summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore19
-rw-r--r--Documentation/ABI/stable/sysfs-devices-node7
-rw-r--r--Documentation/ABI/testing/sysfs-bus-usb2
-rw-r--r--Documentation/DMA-API-HOWTO.txt758
-rw-r--r--Documentation/DMA-API.txt122
-rw-r--r--Documentation/DocBook/mtdnand.tmpl6
-rw-r--r--Documentation/DocBook/tracepoint.tmpl13
-rw-r--r--Documentation/DocBook/v4l/common.xml2
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-parm.xml2
-rw-r--r--Documentation/HOWTO115
-rw-r--r--Documentation/IPMI.txt12
-rw-r--r--Documentation/Makefile4
-rw-r--r--Documentation/PCI/PCI-DMA-mapping.txt766
-rw-r--r--Documentation/RCU/NMI-RCU.txt39
-rw-r--r--Documentation/RCU/checklist.txt7
-rw-r--r--Documentation/RCU/lockdep.txt28
-rw-r--r--Documentation/RCU/whatisRCU.txt6
-rw-r--r--Documentation/SubmitChecklist8
-rw-r--r--Documentation/arm/Samsung-S3C24XX/CPUfreq.txt4
-rw-r--r--Documentation/arm/Samsung/Overview.txt86
-rwxr-xr-xDocumentation/arm/Samsung/clksrc-change-registers.awk167
-rw-r--r--Documentation/block/biodoc.txt4
-rw-r--r--Documentation/cgroups/cgroup_event_listener.c110
-rw-r--r--Documentation/cgroups/cgroups.txt42
-rw-r--r--Documentation/cgroups/cpusets.txt127
-rw-r--r--Documentation/cgroups/memcg_test.txt47
-rw-r--r--Documentation/cgroups/memory.txt82
-rw-r--r--Documentation/circular-buffers.txt234
-rw-r--r--Documentation/connector/cn_test.c1
-rw-r--r--Documentation/console/console.txt2
-rw-r--r--Documentation/cpu-freq/pcc-cpufreq.txt207
-rw-r--r--Documentation/device-mapper/snapshot.txt44
-rw-r--r--Documentation/driver-model/platform.txt2
-rw-r--r--Documentation/eisa.txt2
-rw-r--r--Documentation/email-clients.txt30
-rw-r--r--Documentation/fault-injection/provoke-crashes.txt38
-rw-r--r--Documentation/fb/efifb.txt31
-rw-r--r--Documentation/fb/imacfb.txt31
-rw-r--r--Documentation/feature-removal-schedule.txt45
-rw-r--r--Documentation/filesystems/00-INDEX6
-rw-r--r--Documentation/filesystems/9p.txt18
-rw-r--r--Documentation/filesystems/Locking18
-rw-r--r--Documentation/filesystems/Makefile8
-rw-r--r--Documentation/filesystems/ceph.txt140
-rw-r--r--Documentation/filesystems/dnotify.txt39
-rw-r--r--Documentation/filesystems/dnotify_test.c34
-rw-r--r--Documentation/filesystems/logfs.txt241
-rw-r--r--Documentation/filesystems/nfs/nfs41-server.txt5
-rw-r--r--Documentation/filesystems/proc.txt55
-rw-r--r--Documentation/filesystems/tmpfs.txt6
-rw-r--r--Documentation/gpio.txt64
-rw-r--r--Documentation/hwmon/abituguru2
-rw-r--r--Documentation/hwmon/adt741142
-rw-r--r--Documentation/hwmon/adt747374
-rw-r--r--Documentation/hwmon/asc7621296
-rw-r--r--Documentation/hwmon/it8753
-rw-r--r--Documentation/hwmon/lm9022
-rw-r--r--Documentation/init.txt49
-rw-r--r--Documentation/input/multi-touch-protocol.txt23
-rw-r--r--Documentation/input/rotary-encoder.txt2
-rw-r--r--Documentation/ioctl/ioctl-number.txt1
-rw-r--r--Documentation/kernel-parameters.txt17
-rw-r--r--Documentation/kobject.txt62
-rw-r--r--Documentation/kprobes.txt207
-rw-r--r--Documentation/kvm/api.txt12
-rw-r--r--Documentation/laptops/00-INDEX6
-rw-r--r--Documentation/laptops/Makefile8
-rw-r--r--Documentation/laptops/dslm.c166
-rw-r--r--Documentation/laptops/laptop-mode.txt170
-rw-r--r--Documentation/memory-barriers.txt20
-rw-r--r--Documentation/networking/Makefile2
-rw-r--r--Documentation/networking/skfp.txt2
-rw-r--r--Documentation/networking/stmmac.txt143
-rw-r--r--Documentation/networking/timestamping.txt76
-rw-r--r--Documentation/networking/timestamping/Makefile11
-rw-r--r--Documentation/networking/timestamping/timestamping.c12
-rw-r--r--Documentation/pnp.txt13
-rw-r--r--Documentation/power/runtime_pm.txt95
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt54
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/i2c.txt30
-rw-r--r--Documentation/s390/kvm.txt2
-rw-r--r--Documentation/scsi/ChangeLog.lpfc10
-rw-r--r--Documentation/serial/tty.txt4
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt2
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt16
-rw-r--r--Documentation/spi/spidev_test.c2
-rw-r--r--Documentation/stable_kernel_rules.txt9
-rw-r--r--Documentation/sysctl/vm.txt5
-rw-r--r--Documentation/timers/00-INDEX2
-rw-r--r--Documentation/timers/Makefile8
-rw-r--r--Documentation/timers/hpet.txt273
-rw-r--r--Documentation/timers/hpet_example.c269
-rw-r--r--Documentation/trace/ftrace.txt2
-rw-r--r--Documentation/vm/00-INDEX16
-rw-r--r--Documentation/vm/Makefile2
-rw-r--r--Documentation/vm/hugepage-mmap.c91
-rw-r--r--Documentation/vm/hugepage-shm.c98
-rw-r--r--Documentation/vm/hugetlbpage.txt169
-rw-r--r--Documentation/vm/map_hugetlb.c6
-rw-r--r--Documentation/vm/slub.txt1
-rw-r--r--Documentation/volatile-considered-harmful.txt6
-rw-r--r--Documentation/voyager.txt95
-rw-r--r--Documentation/watchdog/src/watchdog-simple.c3
-rw-r--r--Documentation/watchdog/src/watchdog-test.c8
-rw-r--r--Documentation/watchdog/watchdog-api.txt5
-rw-r--r--MAINTAINERS237
-rw-r--r--Makefile6
-rw-r--r--arch/Kconfig13
-rw-r--r--arch/alpha/Kconfig4
-rw-r--r--arch/alpha/boot/bootp.c1
-rw-r--r--arch/alpha/boot/bootpz.c1
-rw-r--r--arch/alpha/boot/main.c1
-rw-r--r--arch/alpha/boot/misc.c1
-rw-r--r--arch/alpha/include/asm/core_marvel.h1
-rw-r--r--arch/alpha/include/asm/core_mcpcia.h1
-rw-r--r--arch/alpha/include/asm/core_titan.h1
-rw-r--r--arch/alpha/include/asm/core_tsunami.h1
-rw-r--r--arch/alpha/include/asm/dma-mapping.h80
-rw-r--r--arch/alpha/include/asm/pci.h139
-rw-r--r--arch/alpha/include/asm/ptrace.h1
-rw-r--r--arch/alpha/kernel/irq.c1
-rw-r--r--arch/alpha/kernel/osf_sys.c5
-rw-r--r--arch/alpha/kernel/pci-noop.c102
-rw-r--r--arch/alpha/kernel/pci-sysfs.c1
-rw-r--r--arch/alpha/kernel/pci_iommu.c203
-rw-r--r--arch/alpha/kernel/process.c2
-rw-r--r--arch/alpha/kernel/ptrace.c60
-rw-r--r--arch/alpha/kernel/smc37c669.c1
-rw-r--r--arch/alpha/kernel/smc37c93x.c1
-rw-r--r--arch/alpha/kernel/srm_env.c1
-rw-r--r--arch/alpha/kernel/sys_dp264.c2
-rw-r--r--arch/alpha/kernel/sys_titan.c2
-rw-r--r--arch/alpha/kernel/traps.c10
-rw-r--r--arch/alpha/mm/init.c1
-rw-r--r--arch/arm/Kconfig156
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/Makefile16
-rw-r--r--arch/arm/boot/bootp/init.S2
-rw-r--r--arch/arm/boot/compressed/decompress.c1
-rw-r--r--arch/arm/boot/compressed/head.S54
-rw-r--r--arch/arm/boot/compressed/misc.c1
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in3
-rw-r--r--arch/arm/common/clkdev.c3
-rw-r--r--arch/arm/common/it8152.c28
-rw-r--r--arch/arm/common/locomo.c372
-rw-r--r--arch/arm/common/sa1111.c112
-rw-r--r--arch/arm/common/scoop.c2
-rw-r--r--arch/arm/configs/ap4evb_defconfig779
-rw-r--r--arch/arm/configs/bcmring_defconfig126
-rw-r--r--arch/arm/configs/cm_t35_defconfig2
-rw-r--r--arch/arm/configs/g3evm_defconfig774
-rw-r--r--arch/arm/configs/g4evm_defconfig779
-rw-r--r--arch/arm/configs/imote2_defconfig2077
-rw-r--r--arch/arm/configs/kirkwood_defconfig126
-rw-r--r--arch/arm/configs/mini2440_defconfig6
-rw-r--r--arch/arm/configs/mmp2_defconfig1194
-rw-r--r--arch/arm/configs/mv78xx0_defconfig1
-rw-r--r--arch/arm/configs/mx1ads_defconfig742
-rw-r--r--arch/arm/configs/mx27_defconfig2
-rw-r--r--arch/arm/configs/mx51_defconfig1286
-rw-r--r--arch/arm/configs/n770_defconfig1
-rw-r--r--arch/arm/configs/n8x0_defconfig161
-rw-r--r--arch/arm/configs/nuc950_defconfig53
-rw-r--r--arch/arm/configs/omap3_beagle_defconfig1
-rw-r--r--arch/arm/configs/omap3_defconfig2
-rw-r--r--arch/arm/configs/omap3_evm_defconfig1
-rw-r--r--arch/arm/configs/omap3_touchbook_defconfig2
-rw-r--r--arch/arm/configs/omap_3430sdp_defconfig1
-rw-r--r--arch/arm/configs/omap_3630sdp_defconfig2
-rw-r--r--arch/arm/configs/omap_h2_1610_defconfig1
-rw-r--r--arch/arm/configs/omap_zoom2_defconfig3
-rw-r--r--arch/arm/configs/omap_zoom3_defconfig4
-rw-r--r--arch/arm/configs/orion5x_defconfig101
-rw-r--r--arch/arm/configs/pxa168_defconfig229
-rw-r--r--arch/arm/configs/raumfeld_defconfig1898
-rw-r--r--arch/arm/configs/rx51_defconfig4
-rw-r--r--arch/arm/configs/s3c2410_defconfig6
-rw-r--r--arch/arm/configs/s3c6400_defconfig360
-rw-r--r--arch/arm/configs/s5p6440_defconfig969
-rw-r--r--arch/arm/configs/s5p6442_defconfig883
-rw-r--r--arch/arm/configs/s5pc110_defconfig894
-rw-r--r--arch/arm/configs/s5pv210_defconfig894
-rw-r--r--arch/arm/include/asm/assembler.h12
-rw-r--r--arch/arm/include/asm/cacheflush.h38
-rw-r--r--arch/arm/include/asm/clkdev.h1
-rw-r--r--arch/arm/include/asm/dma-mapping.h8
-rw-r--r--arch/arm/include/asm/elf.h1
-rw-r--r--arch/arm/include/asm/entry-macro-vic2.S57
-rw-r--r--arch/arm/include/asm/futex.h16
-rw-r--r--arch/arm/include/asm/hardware/it8152.h12
-rw-r--r--arch/arm/include/asm/hardware/locomo.h4
-rw-r--r--arch/arm/include/asm/hardware/sa1111.h4
-rw-r--r--arch/arm/include/asm/highmem.h15
-rw-r--r--arch/arm/include/asm/irq.h1
-rw-r--r--arch/arm/include/asm/kmap_types.h1
-rw-r--r--arch/arm/include/asm/outercache.h75
-rw-r--r--arch/arm/include/asm/pci.h11
-rw-r--r--arch/arm/include/asm/pgtable-nommu.h1
-rw-r--r--arch/arm/include/asm/ptrace.h2
-rw-r--r--arch/arm/include/asm/system.h16
-rw-r--r--arch/arm/include/asm/uaccess.h40
-rw-r--r--arch/arm/include/asm/ucontext.h23
-rw-r--r--arch/arm/include/asm/unistd.h3
-rw-r--r--arch/arm/include/asm/user.h12
-rw-r--r--arch/arm/kernel/calls.S4
-rw-r--r--arch/arm/kernel/entry-armv.S10
-rw-r--r--arch/arm/kernel/entry-header.S2
-rw-r--r--arch/arm/kernel/ftrace.c8
-rw-r--r--arch/arm/kernel/irq.c1
-rw-r--r--arch/arm/kernel/kgdb.c13
-rw-r--r--arch/arm/kernel/kprobes.c11
-rw-r--r--arch/arm/kernel/module.c2
-rw-r--r--arch/arm/kernel/perf_event.c9
-rw-r--r--arch/arm/kernel/process.c9
-rw-r--r--arch/arm/kernel/ptrace.c60
-rw-r--r--arch/arm/kernel/ptrace.h14
-rw-r--r--arch/arm/kernel/signal.c93
-rw-r--r--arch/arm/kernel/smp.c4
-rw-r--r--arch/arm/kernel/sys_arm.c131
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c3
-rw-r--r--arch/arm/kernel/unwind.c4
-rw-r--r--arch/arm/lib/backtrace.S4
-rw-r--r--arch/arm/lib/clear_user.S4
-rw-r--r--arch/arm/lib/copy_from_user.S4
-rw-r--r--arch/arm/lib/copy_to_user.S4
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S4
-rw-r--r--arch/arm/lib/getuser.S4
-rw-r--r--arch/arm/lib/memmove.S4
-rw-r--r--arch/arm/lib/putuser.S4
-rw-r--r--arch/arm/lib/strncpy_from_user.S4
-rw-r--r--arch/arm/lib/strnlen_user.S4
-rw-r--r--arch/arm/lib/uaccess.S8
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c1
-rw-r--r--arch/arm/mach-aaec2000/core.c1
-rw-r--r--arch/arm/mach-at91/Makefile4
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c20
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c11
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c10
-rw-r--r--arch/arm/mach-at91/include/mach/at91_mci.h2
-rw-r--r--arch/arm/mach-at91/pm_slowclock.S16
-rw-r--r--arch/arm/mach-bcmring/dma.c14
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c1
-rw-r--r--arch/arm/mach-davinci/dm365.c1
-rw-r--r--arch/arm/mach-davinci/dma.c4
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h8
-rw-r--r--arch/arm/mach-davinci/include/mach/i2c.h2
-rw-r--r--arch/arm/mach-davinci/time.c6
-rw-r--r--arch/arm/mach-dove/common.c8
-rw-r--r--arch/arm/mach-ep93xx/gpio.c6
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ts72xx.h2
-rw-r--r--arch/arm/mach-ep93xx/micro9.c2
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c21
-rw-r--r--arch/arm/mach-h720x/common.c1
-rw-r--r--arch/arm/mach-integrator/cpu.c1
-rw-r--r--arch/arm/mach-integrator/impd1.c1
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c2
-rw-r--r--arch/arm/mach-integrator/pci_v3.c1
-rw-r--r--arch/arm/mach-iop13xx/pci.c1
-rw-r--r--arch/arm/mach-iop32x/glantank.c1
-rw-r--r--arch/arm/mach-iop32x/iq31244.c1
-rw-r--r--arch/arm/mach-iop32x/iq80321.c1
-rw-r--r--arch/arm/mach-iop32x/n2100.c1
-rw-r--r--arch/arm/mach-iop33x/iq80331.c1
-rw-r--r--arch/arm/mach-iop33x/iq80332.c1
-rw-r--r--arch/arm/mach-ixp2000/enp2611.c1
-rw-r--r--arch/arm/mach-ixp2000/ixdp2400.c1
-rw-r--r--arch/arm/mach-ixp2000/ixdp2800.c1
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c1
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c1
-rw-r--r--arch/arm/mach-ixp2000/pci.c1
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ixp23xx/pci.c1
-rw-r--r--arch/arm/mach-ixp4xx/avila-setup.c1
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c26
-rw-r--r--arch/arm/mach-ixp4xx/coyote-setup.c1
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-setup.c1
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-setup.c1
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/hardware.h5
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c1
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_npe.c1
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-setup.c1
-rw-r--r--arch/arm/mach-kirkwood/Kconfig23
-rw-r--r--arch/arm/mach-kirkwood/Makefile4
-rw-r--r--arch/arm/mach-kirkwood/common.c8
-rw-r--r--arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c4
-rw-r--r--arch/arm/mach-kirkwood/netspace_v2-setup.c59
-rw-r--r--arch/arm/mach-kirkwood/openrd-setup.c118
-rw-r--r--arch/arm/mach-kirkwood/openrd_base-setup.c96
-rw-r--r--arch/arm/mach-kirkwood/pcie.c1
-rw-r--r--arch/arm/mach-kirkwood/sheevaplug-setup.c50
-rw-r--r--arch/arm/mach-lh7a40x/clcd.c1
-rw-r--r--arch/arm/mach-mmp/Kconfig35
-rw-r--r--arch/arm/mach-mmp/Makefile10
-rw-r--r--arch/arm/mach-mmp/avengers_lite.c51
-rw-r--r--arch/arm/mach-mmp/common.h4
-rw-r--r--arch/arm/mach-mmp/flint.c123
-rw-r--r--arch/arm/mach-mmp/include/mach/cputype.h9
-rw-r--r--arch/arm/mach-mmp/include/mach/devices.h12
-rw-r--r--arch/arm/mach-mmp/include/mach/entry-macro.S7
-rw-r--r--arch/arm/mach-mmp/include/mach/irqs.h115
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-mmp2.h240
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa168.h4
-rw-r--r--arch/arm/mach-mmp/include/mach/mmp2.h60
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apbc.h41
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-icu.h42
-rw-r--r--arch/arm/mach-mmp/include/mach/uncompress.h16
-rw-r--r--arch/arm/mach-mmp/irq-mmp2.c154
-rw-r--r--arch/arm/mach-mmp/irq-pxa168.c (renamed from arch/arm/mach-mmp/irq.c)0
-rw-r--r--arch/arm/mach-mmp/jasper.c80
-rw-r--r--arch/arm/mach-mmp/mmp2.c123
-rw-r--r--arch/arm/mach-mmp/time.c26
-rw-r--r--arch/arm/mach-mv78xx0/Kconfig6
-rw-r--r--arch/arm/mach-mv78xx0/Makefile3
-rw-r--r--arch/arm/mach-mv78xx0/buffalo-wxl-setup.c155
-rw-r--r--arch/arm/mach-mv78xx0/mpp.c96
-rw-r--r--arch/arm/mach-mv78xx0/mpp.h347
-rw-r--r--arch/arm/mach-mx1/Makefile5
-rw-r--r--arch/arm/mach-mx1/mach-mx1ads.c165
-rw-r--r--arch/arm/mach-mx1/mach-scb9328.c158
-rw-r--r--arch/arm/mach-mx1/mx1ads.c165
-rw-r--r--arch/arm/mach-mx1/scb9328.c158
-rw-r--r--arch/arm/mach-mx2/Kconfig10
-rw-r--r--arch/arm/mach-mx2/Makefile23
-rw-r--r--arch/arm/mach-mx2/clock_imx21.c236
-rw-r--r--arch/arm/mach-mx2/clock_imx27.c33
-rw-r--r--arch/arm/mach-mx2/cpu_imx27.c3
-rw-r--r--arch/arm/mach-mx2/crm_regs.h258
-rw-r--r--arch/arm/mach-mx2/devices.c640
-rw-r--r--arch/arm/mach-mx2/devices.h13
-rw-r--r--arch/arm/mach-mx2/eukrea_cpuimx27.c234
-rw-r--r--arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c2
-rw-r--r--arch/arm/mach-mx2/generic.c97
-rw-r--r--arch/arm/mach-mx2/mach-cpuimx27.c235
-rw-r--r--arch/arm/mach-mx2/mach-imx27lite.c95
-rw-r--r--arch/arm/mach-mx2/mach-mx21ads.c294
-rw-r--r--arch/arm/mach-mx2/mach-mx27_3ds.c95
-rw-r--r--arch/arm/mach-mx2/mach-mx27ads.c345
-rw-r--r--arch/arm/mach-mx2/mach-mxt_td60.c295
-rw-r--r--arch/arm/mach-mx2/mach-pca100.c395
-rw-r--r--arch/arm/mach-mx2/mach-pcm038.c358
-rw-r--r--arch/arm/mach-mx2/mm-imx21.c83
-rw-r--r--arch/arm/mach-mx2/mm-imx27.c83
-rw-r--r--arch/arm/mach-mx2/mx21ads.c294
-rw-r--r--arch/arm/mach-mx2/mx27ads.c345
-rw-r--r--arch/arm/mach-mx2/mx27lite.c95
-rw-r--r--arch/arm/mach-mx2/mx27pdk.c95
-rw-r--r--arch/arm/mach-mx2/mxt_td60.c295
-rw-r--r--arch/arm/mach-mx2/pca100.c244
-rw-r--r--arch/arm/mach-mx2/pcm038.c338
-rw-r--r--arch/arm/mach-mx2/pcm970-baseboard.c6
-rw-r--r--arch/arm/mach-mx2/serial.c48
-rw-r--r--arch/arm/mach-mx25/Kconfig1
-rw-r--r--arch/arm/mach-mx25/Makefile2
-rw-r--r--arch/arm/mach-mx25/clock.c14
-rw-r--r--arch/arm/mach-mx25/devices.c62
-rw-r--r--arch/arm/mach-mx25/devices.h3
-rw-r--r--arch/arm/mach-mx25/mach-mx25pdk.c174
-rw-r--r--arch/arm/mach-mx25/mx25pdk.c111
-rw-r--r--arch/arm/mach-mx3/Kconfig12
-rw-r--r--arch/arm/mach-mx3/Makefile32
-rw-r--r--arch/arm/mach-mx3/armadillo5x0.c416
-rw-r--r--arch/arm/mach-mx3/clock-imx31.c630
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c5
-rw-r--r--arch/arm/mach-mx3/clock.c630
-rw-r--r--arch/arm/mach-mx3/cpu.c2
-rw-r--r--arch/arm/mach-mx3/crm_regs.h2
-rw-r--r--arch/arm/mach-mx3/devices.c19
-rw-r--r--arch/arm/mach-mx3/devices.h3
-rw-r--r--arch/arm/mach-mx3/iomux-imx31.c181
-rw-r--r--arch/arm/mach-mx3/iomux.c181
-rw-r--r--arch/arm/mach-mx3/kzmarm11.c268
-rw-r--r--arch/arm/mach-mx3/mach-armadillo5x0.c582
-rw-r--r--arch/arm/mach-mx3/mach-kzm_arm11_01.c273
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c344
-rw-r--r--arch/arm/mach-mx3/mach-mx31ads.c559
-rw-r--r--arch/arm/mach-mx3/mach-mx31lilly.c206
-rw-r--r--arch/arm/mach-mx3/mach-mx31lite.c297
-rw-r--r--arch/arm/mach-mx3/mach-mx31moboard.c552
-rw-r--r--arch/arm/mach-mx3/mach-mx35pdk.c116
-rw-r--r--arch/arm/mach-mx3/mach-pcm037.c693
-rw-r--r--arch/arm/mach-mx3/mach-pcm037_eet.c (renamed from arch/arm/mach-mx3/pcm037_eet.c)0
-rw-r--r--arch/arm/mach-mx3/mach-pcm043.c413
-rw-r--r--arch/arm/mach-mx3/mach-qong.c283
-rw-r--r--arch/arm/mach-mx3/mx31ads.c555
-rw-r--r--arch/arm/mach-mx3/mx31lilly.c206
-rw-r--r--arch/arm/mach-mx3/mx31lite-db.c32
-rw-r--r--arch/arm/mach-mx3/mx31lite.c297
-rw-r--r--arch/arm/mach-mx3/mx31moboard-devboard.c33
-rw-r--r--arch/arm/mach-mx3/mx31moboard-marxbot.c40
-rw-r--r--arch/arm/mach-mx3/mx31moboard-smartbot.c162
-rw-r--r--arch/arm/mach-mx3/mx31moboard.c580
-rw-r--r--arch/arm/mach-mx3/mx31pdk.c266
-rw-r--r--arch/arm/mach-mx3/mx35pdk.c116
-rw-r--r--arch/arm/mach-mx3/pcm037.c646
-rw-r--r--arch/arm/mach-mx3/pcm043.c259
-rw-r--r--arch/arm/mach-mx3/qong.c285
-rw-r--r--arch/arm/mach-mx5/Kconfig18
-rw-r--r--arch/arm/mach-mx5/Makefile9
-rw-r--r--arch/arm/mach-mx5/Makefile.boot3
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c98
-rw-r--r--arch/arm/mach-mx5/clock-mx51.c825
-rw-r--r--arch/arm/mach-mx5/cpu.c100
-rw-r--r--arch/arm/mach-mx5/crm_regs.h583
-rw-r--r--arch/arm/mach-mx5/devices.c96
-rw-r--r--arch/arm/mach-mx5/devices.h4
-rw-r--r--arch/arm/mach-mx5/mm.c83
-rw-r--r--arch/arm/mach-mxc91231/magx-zn5.c2
-rw-r--r--arch/arm/mach-netx/fb.c1
-rw-r--r--arch/arm/mach-netx/xc.c1
-rw-r--r--arch/arm/mach-nomadik/board-nhk8815.c2
-rw-r--r--arch/arm/mach-nomadik/gpio.c1
-rw-r--r--arch/arm/mach-ns9xxx/plat-serial8250.c1
-rw-r--r--arch/arm/mach-ns9xxx/processor-ns9360.c1
-rw-r--r--arch/arm/mach-omap1/mcbsp.c1
-rw-r--r--arch/arm/mach-omap1/timer32k.c15
-rw-r--r--arch/arm/mach-omap2/Kconfig6
-rw-r--r--arch/arm/mach-omap2/Makefile3
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c2
-rw-r--r--[-rwxr-xr-x]arch/arm/mach-omap2/board-3630sdp.c3
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c26
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c6
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c2
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c41
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c64
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c116
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c12
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c12
-rw-r--r--arch/arm/mach-omap2/board-overo.c2
-rw-r--r--arch/arm/mach-omap2/board-sdp-flash.c8
-rw-r--r--arch/arm/mach-omap2/board-zoom-debugboard.c2
-rw-r--r--[-rwxr-xr-x]arch/arm/mach-omap2/board-zoom-peripherals.c1
-rw-r--r--arch/arm/mach-omap2/board-zoom3.c2
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c1
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c1
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c8
-rw-r--r--arch/arm/mach-omap2/clockdomain.c6
-rw-r--r--arch/arm/mach-omap2/devices.c2
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c3
-rw-r--r--arch/arm/mach-omap2/include/mach/entry-macro.S2
-rw-r--r--arch/arm/mach-omap2/io.c21
-rw-r--r--arch/arm/mach-omap2/iommu2.c1
-rw-r--r--arch/arm/mach-omap2/mailbox.c12
-rw-r--r--arch/arm/mach-omap2/mcbsp.c1
-rw-r--r--arch/arm/mach-omap2/mux.c1
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S6
-rw-r--r--arch/arm/mach-omap2/omap44xx-smc.S32
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c3
-rw-r--r--arch/arm/mach-omap2/pm-debug.c1
-rw-r--r--arch/arm/mach-omap2/pm34xx.c1
-rw-r--r--arch/arm/mach-omap2/powerdomain.c2
-rw-r--r--arch/arm/mach-omap2/prcm.c8
-rw-r--r--arch/arm/mach-omap2/serial.c46
-rw-r--r--arch/arm/mach-omap2/usb-ehci.c6
-rw-r--r--arch/arm/mach-orion5x/Kconfig7
-rw-r--r--arch/arm/mach-orion5x/Makefile1
-rw-r--r--arch/arm/mach-orion5x/common.c4
-rw-r--r--arch/arm/mach-orion5x/d2net-setup.c45
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c36
-rw-r--r--arch/arm/mach-orion5x/ls_hgl-setup.c276
-rw-r--r--arch/arm/mach-orion5x/lsmini-setup.c8
-rw-r--r--arch/arm/mach-orion5x/pci.c1
-rw-r--r--arch/arm/mach-orion5x/wrt350n-v2-setup.c2
-rw-r--r--arch/arm/mach-pnx4008/dma.c1
-rw-r--r--arch/arm/mach-pnx4008/pm.c1
-rw-r--r--arch/arm/mach-pxa/Kconfig46
-rw-r--r--arch/arm/mach-pxa/Makefile5
-rw-r--r--arch/arm/mach-pxa/am300epd.c2
-rw-r--r--arch/arm/mach-pxa/balloon3.c33
-rw-r--r--arch/arm/mach-pxa/capc7117.c158
-rw-r--r--arch/arm/mach-pxa/cm-x255.c21
-rw-r--r--arch/arm/mach-pxa/cm-x270.c83
-rw-r--r--arch/arm/mach-pxa/cm-x2xx-pci.c2
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c3
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa3xx.c1
-rw-r--r--arch/arm/mach-pxa/e740.c6
-rw-r--r--arch/arm/mach-pxa/e750.c6
-rw-r--r--arch/arm/mach-pxa/e800.c9
-rw-r--r--arch/arm/mach-pxa/em-x270.c21
-rw-r--r--arch/arm/mach-pxa/icontrol.c202
-rw-r--r--arch/arm/mach-pxa/idp.c20
-rw-r--r--arch/arm/mach-pxa/imote2.c7
-rw-r--r--arch/arm/mach-pxa/include/mach/balloon3.h10
-rw-r--r--arch/arm/mach-pxa/include/mach/hardware.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h153
-rw-r--r--arch/arm/mach-pxa/include/mach/lpd270.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/lubbock.h11
-rw-r--r--arch/arm/mach-pxa/include/mach/mainstone.h17
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa25x.h32
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa27x.h27
-rw-r--r--arch/arm/mach-pxa/include/mach/mxm8x10.h21
-rw-r--r--arch/arm/mach-pxa/include/mach/pcm027.h7
-rw-r--r--arch/arm/mach-pxa/include/mach/ssp.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/uncompress.h46
-rw-r--r--arch/arm/mach-pxa/include/mach/zeus.h3
-rw-r--r--arch/arm/mach-pxa/lpd270.c6
-rw-r--r--arch/arm/mach-pxa/lubbock.c35
-rw-r--r--arch/arm/mach-pxa/magician.c21
-rw-r--r--arch/arm/mach-pxa/mainstone.c27
-rw-r--r--arch/arm/mach-pxa/mioa701.c25
-rw-r--r--arch/arm/mach-pxa/mxm8x10.c474
-rw-r--r--arch/arm/mach-pxa/palmld.c21
-rw-r--r--arch/arm/mach-pxa/palmt5.c21
-rw-r--r--arch/arm/mach-pxa/palmtc.c21
-rw-r--r--arch/arm/mach-pxa/palmte2.c21
-rw-r--r--arch/arm/mach-pxa/palmtreo.c20
-rw-r--r--arch/arm/mach-pxa/palmtx.c21
-rw-r--r--arch/arm/mach-pxa/palmz72.c22
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c9
-rw-r--r--arch/arm/mach-pxa/pm.c1
-rw-r--r--arch/arm/mach-pxa/poodle.c28
-rw-r--r--arch/arm/mach-pxa/pxa27x.c19
-rw-r--r--arch/arm/mach-pxa/raumfeld.c1106
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c2
-rw-r--r--arch/arm/mach-pxa/spitz.c20
-rw-r--r--arch/arm/mach-pxa/ssp.c5
-rw-r--r--arch/arm/mach-pxa/stargate2.c5
-rw-r--r--arch/arm/mach-pxa/time.c10
-rw-r--r--arch/arm/mach-pxa/tosa.c117
-rw-r--r--arch/arm/mach-pxa/trizeps4.c27
-rw-r--r--arch/arm/mach-pxa/viper.c9
-rw-r--r--arch/arm/mach-pxa/zeus.c91
-rw-r--r--arch/arm/mach-realview/core.c3
-rw-r--r--arch/arm/mach-rpc/dma.c1
-rw-r--r--arch/arm/mach-rpc/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-s3c2410/dma.c2
-rw-r--r--arch/arm/mach-s3c2410/h1940-bluetooth.c2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-core.h34
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-track.h33
-rw-r--r--arch/arm/mach-s3c2410/include/mach/pm-core.h64
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpio.h10
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h32
-rw-r--r--arch/arm/mach-s3c2410/include/mach/spi-gpio.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/timex.h24
-rw-r--r--arch/arm/mach-s3c2410/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c7
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-tct_hammer.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c2
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c4
-rw-r--r--arch/arm/mach-s3c2412/clock.c52
-rw-r--r--arch/arm/mach-s3c2412/dma.c2
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c2
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c3
-rw-r--r--arch/arm/mach-s3c2412/mach-vstms.c2
-rw-r--r--arch/arm/mach-s3c2440/Kconfig74
-rw-r--r--arch/arm/mach-s3c2440/Makefile11
-rw-r--r--arch/arm/mach-s3c2440/clock.c6
-rw-r--r--arch/arm/mach-s3c2440/dma.c2
-rw-r--r--arch/arm/mach-s3c2440/dsc.c2
-rw-r--r--arch/arm/mach-s3c2440/include/mach/gta02.h (renamed from arch/arm/mach-s3c2442/include/mach/gta02.h)0
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-at2440evb.c7
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c647
-rw-r--r--arch/arm/mach-s3c2440/mach-mini2440.c8
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c4
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c4
-rw-r--r--arch/arm/mach-s3c2440/s3c2440-cpufreq.c (renamed from arch/arm/plat-s3c24xx/s3c2440-cpufreq.c)0
-rw-r--r--arch/arm/mach-s3c2440/s3c2440-pll-12000000.c97
-rw-r--r--arch/arm/mach-s3c2440/s3c2440-pll-16934400.c127
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c2
-rw-r--r--arch/arm/mach-s3c2440/s3c2442.c165
-rw-r--r--arch/arm/mach-s3c2440/s3c244x-clock.c138
-rw-r--r--arch/arm/mach-s3c2440/s3c244x-irq.c (renamed from arch/arm/plat-s3c24xx/s3c244x-irq.c)0
-rw-r--r--arch/arm/mach-s3c2440/s3c244x.c195
-rw-r--r--arch/arm/mach-s3c2442/Kconfig37
-rw-r--r--arch/arm/mach-s3c2442/Makefile18
-rw-r--r--arch/arm/mach-s3c2442/clock.c151
-rw-r--r--arch/arm/mach-s3c2442/mach-gta02.c648
-rw-r--r--arch/arm/mach-s3c2442/s3c2442.c34
-rw-r--r--arch/arm/mach-s3c2443/Kconfig1
-rw-r--r--arch/arm/mach-s3c2443/clock.c842
-rw-r--r--arch/arm/mach-s3c2443/dma.c2
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c10
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/io.h18
-rw-r--r--arch/arm/mach-s3c6400/Kconfig30
-rw-r--r--arch/arm/mach-s3c6400/Makefile23
-rw-r--r--arch/arm/mach-s3c6400/include/mach/debug-macro.S39
-rw-r--r--arch/arm/mach-s3c6400/include/mach/dma.h70
-rw-r--r--arch/arm/mach-s3c6400/include/mach/entry-macro.S44
-rw-r--r--arch/arm/mach-s3c6400/include/mach/gpio-core.h21
-rw-r--r--arch/arm/mach-s3c6400/include/mach/gpio.h96
-rw-r--r--arch/arm/mach-s3c6400/include/mach/irqs.h16
-rw-r--r--arch/arm/mach-s3c6400/include/mach/map.h89
-rw-r--r--arch/arm/mach-s3c6400/include/mach/regs-clock.h16
-rw-r--r--arch/arm/mach-s3c6400/include/mach/tick.h29
-rw-r--r--arch/arm/mach-s3c6400/mach-smdk6400.c96
-rw-r--r--arch/arm/mach-s3c6400/s3c6400.c92
-rw-r--r--arch/arm/mach-s3c6400/setup-sdhci.c63
-rw-r--r--arch/arm/mach-s3c6410/Kconfig109
-rw-r--r--arch/arm/mach-s3c6410/Makefile26
-rw-r--r--arch/arm/mach-s3c6410/cpu.c105
-rw-r--r--arch/arm/mach-s3c6410/mach-anw6410.c245
-rw-r--r--arch/arm/mach-s3c6410/mach-hmt.c276
-rw-r--r--arch/arm/mach-s3c6410/mach-ncp.c107
-rw-r--r--arch/arm/mach-s3c6410/mach-smdk6410.c457
-rw-r--r--arch/arm/mach-s3c6410/setup-sdhci.c68
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig180
-rw-r--r--arch/arm/mach-s3c64xx/Makefile62
-rw-r--r--arch/arm/mach-s3c64xx/Makefile.boot (renamed from arch/arm/mach-s3c6400/Makefile.boot)0
-rw-r--r--arch/arm/mach-s3c64xx/clock.c809
-rw-r--r--arch/arm/mach-s3c64xx/cpu.c167
-rw-r--r--arch/arm/mach-s3c64xx/cpufreq.c (renamed from arch/arm/plat-s3c64xx/cpufreq.c)0
-rw-r--r--arch/arm/mach-s3c64xx/dev-adc.c46
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c335
-rw-r--r--arch/arm/mach-s3c64xx/dev-rtc.c43
-rw-r--r--arch/arm/mach-s3c64xx/dev-spi.c182
-rw-r--r--arch/arm/mach-s3c64xx/dev-uart.c147
-rw-r--r--arch/arm/mach-s3c64xx/dma.c750
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c288
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/debug-macro.S39
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h127
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/entry-macro.S18
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h48
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h60
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h53
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h49
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h44
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h71
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h42
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h74
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h40
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h36
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h54
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h70
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h69
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h46
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio.h100
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/hardware.h (renamed from arch/arm/mach-s3c6400/include/mach/hardware.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/io.h18
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/irqs.h216
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/map.h107
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/memory.h (renamed from arch/arm/mach-s3c6400/include/mach/memory.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pll.h (renamed from arch/arm/plat-s3c64xx/include/plat/pll.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pm-core.h98
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pwm-clock.h (renamed from arch/arm/mach-s3c6400/include/mach/pwm-clock.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-clock.h156
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-fb.h (renamed from arch/arm/mach-s3c6400/include/mach/regs-fb.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h (renamed from arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-gpio.h (renamed from arch/arm/plat-s3c64xx/include/plat/regs-gpio.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-irq.h (renamed from arch/arm/mach-s3c6400/include/mach/regs-irq.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-modem.h (renamed from arch/arm/plat-s3c64xx/include/plat/regs-modem.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-srom.h59
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-sys.h (renamed from arch/arm/plat-s3c64xx/include/plat/regs-sys.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h (renamed from arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/s3c6400.h36
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/s3c6410.h29
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/spi-clocks.h18
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/system.h (renamed from arch/arm/mach-s3c6400/include/mach/system.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/tick.h29
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/timex.h24
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/uncompress.h (renamed from arch/arm/mach-s3c6400/include/mach/uncompress.h)0
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-s3c64xx/irq-eint.c213
-rw-r--r--arch/arm/mach-s3c64xx/irq-pm.c111
-rw-r--r--arch/arm/mach-s3c64xx/irq.c69
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c245
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c276
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c107
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c96
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c668
-rw-r--r--arch/arm/mach-s3c64xx/pm.c173
-rw-r--r--arch/arm/mach-s3c64xx/s3c6400.c89
-rw-r--r--arch/arm/mach-s3c64xx/s3c6410.c91
-rw-r--r--arch/arm/mach-s3c64xx/setup-fb-24bpp.c (renamed from arch/arm/plat-s3c64xx/setup-fb-24bpp.c)0
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c0.c31
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c1.c31
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci-gpio.c (renamed from arch/arm/plat-s3c64xx/setup-sdhci-gpio.c)0
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci.c72
-rw-r--r--arch/arm/mach-s3c64xx/sleep.S144
-rw-r--r--arch/arm/mach-s5p6440/Kconfig21
-rw-r--r--arch/arm/mach-s5p6440/Makefile19
-rw-r--r--arch/arm/mach-s5p6440/Makefile.boot2
-rw-r--r--arch/arm/mach-s5p6440/clock.c698
-rw-r--r--arch/arm/mach-s5p6440/cpu.c114
-rw-r--r--arch/arm/mach-s5p6440/gpio.c322
-rw-r--r--arch/arm/mach-s5p6440/include/mach/debug-macro.S37
-rw-r--r--arch/arm/mach-s5p6440/include/mach/entry-macro.S16
-rw-r--r--arch/arm/mach-s5p6440/include/mach/gpio.h80
-rw-r--r--arch/arm/mach-s5p6440/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-s5p6440/include/mach/io.h18
-rw-r--r--arch/arm/mach-s5p6440/include/mach/irqs.h111
-rw-r--r--arch/arm/mach-s5p6440/include/mach/map.h68
-rw-r--r--arch/arm/mach-s5p6440/include/mach/memory.h19
-rw-r--r--arch/arm/mach-s5p6440/include/mach/pwm-clock.h62
-rw-r--r--arch/arm/mach-s5p6440/include/mach/regs-clock.h130
-rw-r--r--arch/arm/mach-s5p6440/include/mach/regs-gpio.h54
-rw-r--r--arch/arm/mach-s5p6440/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s5p6440/include/mach/system.h26
-rw-r--r--arch/arm/mach-s5p6440/include/mach/tick.h24
-rw-r--r--arch/arm/mach-s5p6440/include/mach/timex.h24
-rw-r--r--arch/arm/mach-s5p6440/include/mach/uncompress.h24
-rw-r--r--arch/arm/mach-s5p6440/include/mach/vmalloc.h17
-rw-r--r--arch/arm/mach-s5p6440/init.c52
-rw-r--r--arch/arm/mach-s5p6440/mach-smdk6440.c111
-rw-r--r--arch/arm/mach-s5p6442/Kconfig24
-rw-r--r--arch/arm/mach-s5p6442/Makefile19
-rw-r--r--arch/arm/mach-s5p6442/Makefile.boot2
-rw-r--r--arch/arm/mach-s5p6442/clock.c396
-rw-r--r--arch/arm/mach-s5p6442/cpu.c121
-rw-r--r--arch/arm/mach-s5p6442/include/mach/debug-macro.S36
-rw-r--r--arch/arm/mach-s5p6442/include/mach/entry-macro.S48
-rw-r--r--arch/arm/mach-s5p6442/include/mach/gpio.h123
-rw-r--r--arch/arm/mach-s5p6442/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-s5p6442/include/mach/io.h17
-rw-r--r--arch/arm/mach-s5p6442/include/mach/irqs.h86
-rw-r--r--arch/arm/mach-s5p6442/include/mach/map.h58
-rw-r--r--arch/arm/mach-s5p6442/include/mach/memory.h19
-rw-r--r--arch/arm/mach-s5p6442/include/mach/pwm-clock.h69
-rw-r--r--arch/arm/mach-s5p6442/include/mach/regs-clock.h103
-rw-r--r--arch/arm/mach-s5p6442/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s5p6442/include/mach/system.h26
-rw-r--r--arch/arm/mach-s5p6442/include/mach/tick.h26
-rw-r--r--arch/arm/mach-s5p6442/include/mach/timex.h24
-rw-r--r--arch/arm/mach-s5p6442/include/mach/uncompress.h24
-rw-r--r--arch/arm/mach-s5p6442/include/mach/vmalloc.h17
-rw-r--r--arch/arm/mach-s5p6442/init.c44
-rw-r--r--arch/arm/mach-s5p6442/mach-smdk6442.c91
-rw-r--r--arch/arm/mach-s5pc100/include/mach/gpio-core.h21
-rw-r--r--arch/arm/mach-s5pc100/include/mach/io.h18
-rw-r--r--arch/arm/mach-s5pc100/include/mach/tick.h2
-rw-r--r--arch/arm/mach-s5pc100/include/mach/timex.h24
-rw-r--r--arch/arm/mach-s5pc100/include/mach/vmalloc.h17
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci.c4
-rw-r--r--arch/arm/mach-s5pv210/Kconfig40
-rw-r--r--arch/arm/mach-s5pv210/Makefile20
-rw-r--r--arch/arm/mach-s5pv210/Makefile.boot2
-rw-r--r--arch/arm/mach-s5pv210/clock.c454
-rw-r--r--arch/arm/mach-s5pv210/cpu.c126
-rw-r--r--arch/arm/mach-s5pv210/include/mach/debug-macro.S42
-rw-r--r--arch/arm/mach-s5pv210/include/mach/entry-macro.S54
-rw-r--r--arch/arm/mach-s5pv210/include/mach/gpio.h129
-rw-r--r--arch/arm/mach-s5pv210/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-s5pv210/include/mach/io.h26
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h146
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h65
-rw-r--r--arch/arm/mach-s5pv210/include/mach/memory.h23
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pwm-clock.h69
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h169
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s5pv210/include/mach/system.h26
-rw-r--r--arch/arm/mach-s5pv210/include/mach/tick.h26
-rw-r--r--arch/arm/mach-s5pv210/include/mach/timex.h29
-rw-r--r--arch/arm/mach-s5pv210/include/mach/uncompress.h24
-rw-r--r--arch/arm/mach-s5pv210/include/mach/vmalloc.h22
-rw-r--r--arch/arm/mach-s5pv210/init.c44
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c98
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c98
-rw-r--r--arch/arm/mach-sa1100/badge4.c5
-rw-r--r--arch/arm/mach-sa1100/collie.c4
-rw-r--r--arch/arm/mach-sa1100/include/mach/collie.h7
-rw-r--r--arch/arm/mach-sa1100/include/mach/irqs.h91
-rw-r--r--arch/arm/mach-sa1100/jornada720.c5
-rw-r--r--arch/arm/mach-sa1100/jornada720_ssp.c3
-rw-r--r--arch/arm/mach-sa1100/neponset.c6
-rw-r--r--arch/arm/mach-sa1100/time.c8
-rw-r--r--arch/arm/mach-shmobile/Kconfig84
-rw-r--r--arch/arm/mach-shmobile/Makefile22
-rw-r--r--arch/arm/mach-shmobile/Makefile.boot9
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c333
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c333
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c268
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c103
-rw-r--r--arch/arm/mach-shmobile/console.c31
-rw-r--r--arch/arm/mach-shmobile/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h23
-rw-r--r--arch/arm/mach-shmobile/include/mach/dma.h1
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro.S39
-rw-r--r--arch/arm/mach-shmobile/include/mach/gpio.h48
-rw-r--r--arch/arm/mach-shmobile/include/mach/hardware.h7
-rw-r--r--arch/arm/mach-shmobile/include/mach/io.h9
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h10
-rw-r--r--arch/arm/mach-shmobile/include/mach/memory.h7
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7367.h332
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h434
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7377.h360
-rw-r--r--arch/arm/mach-shmobile/include/mach/system.h14
-rw-r--r--arch/arm/mach-shmobile/include/mach/timex.h6
-rw-r--r--arch/arm/mach-shmobile/include/mach/uncompress.h21
-rw-r--r--arch/arm/mach-shmobile/include/mach/vmalloc.h6
-rw-r--r--arch/arm/mach-shmobile/intc-sh7367.c270
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c369
-rw-r--r--arch/arm/mach-shmobile/intc-sh7377.c352
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7367.c1801
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7372.c1637
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7377.c1767
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c198
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c199
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c215
-rw-r--r--arch/arm/mach-shmobile/timer.c46
-rw-r--r--arch/arm/mach-u300/core.c4
-rw-r--r--arch/arm/mach-u300/dummyspichip.c1
-rw-r--r--arch/arm/mach-u300/include/mach/debug-macro.S2
-rw-r--r--arch/arm/mach-u300/mmc.c1
-rw-r--r--arch/arm/mach-ux500/include/mach/hardware.h8
-rw-r--r--arch/arm/mach-versatile/core.c1
-rw-r--r--arch/arm/mach-versatile/pci.c1
-rw-r--r--arch/arm/mach-w90x900/cpu.h1
-rw-r--r--arch/arm/mach-w90x900/dev.c43
-rw-r--r--arch/arm/mach-w90x900/include/mach/fb.h83
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-ldm.h253
-rw-r--r--arch/arm/mach-w90x900/mach-nuc950evb.c47
-rw-r--r--arch/arm/mach-w90x900/nuc950.c4
-rw-r--r--arch/arm/mm/Kconfig13
-rw-r--r--arch/arm/mm/alignment.c24
-rw-r--r--arch/arm/mm/cache-l2x0.c10
-rw-r--r--arch/arm/mm/copypage-v6.c9
-rw-r--r--arch/arm/mm/dma-mapping.c7
-rw-r--r--arch/arm/mm/fault-armv.c1
-rw-r--r--arch/arm/mm/flush.c25
-rw-r--r--arch/arm/mm/highmem.c87
-rw-r--r--arch/arm/mm/init.c1
-rw-r--r--arch/arm/mm/mmu.c14
-rw-r--r--arch/arm/mm/pgd.c1
-rw-r--r--arch/arm/mm/proc-sa1100.S2
-rw-r--r--arch/arm/nwfpe/entry.S8
-rw-r--r--arch/arm/plat-mxc/Kconfig30
-rw-r--r--arch/arm/plat-mxc/Makefile8
-rw-r--r--arch/arm/plat-mxc/audmux-v1.c14
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c10
-rw-r--r--arch/arm/plat-mxc/clock.c1
-rw-r--r--arch/arm/plat-mxc/dma-mx1-mx2.c207
-rw-r--r--arch/arm/plat-mxc/ehci.c122
-rw-r--r--arch/arm/plat-mxc/gpio.c30
-rw-r--r--arch/arm/plat-mxc/include/mach/board-kzmarm11.h18
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31_3ds.h59
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31ads.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31moboard.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31pdk.h59
-rw-r--r--arch/arm/plat-mxc/include/mach/clock.h7
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S12
-rw-r--r--arch/arm/plat-mxc/include/mach/entry-macro.S34
-rw-r--r--arch/arm/plat-mxc/include/mach/hardware.h9
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx1.h313
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx21.h210
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx25.h24
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx27.h372
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx2x.h425
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx3.h76
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx35.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx51.h326
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-v1.h103
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-v3.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux.h128
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h20
-rw-r--r--arch/arm/plat-mxc/include/mach/memory.h54
-rw-r--r--arch/arm/plat-mxc/include/mach/mtd-xip.h34
-rw-r--r--arch/arm/plat-mxc/include/mach/mx1.h395
-rw-r--r--arch/arm/plat-mxc/include/mach/mx21.h13
-rw-r--r--arch/arm/plat-mxc/include/mach/mx25.h36
-rw-r--r--arch/arm/plat-mxc/include/mach/mx27.h32
-rw-r--r--arch/arm/plat-mxc/include/mach/mx2x.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h33
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h13
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3x.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/mx51.h445
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h20
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc91231.h58
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_ehci.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/ssi.h18
-rw-r--r--arch/arm/plat-mxc/include/mach/timex.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/uncompress.h7
-rw-r--r--arch/arm/plat-mxc/iomux-mx1-mx2.c157
-rw-r--r--arch/arm/plat-mxc/iomux-v1.c238
-rw-r--r--arch/arm/plat-mxc/pwm.c1
-rw-r--r--arch/arm/plat-mxc/time.c41
-rw-r--r--arch/arm/plat-mxc/tzic.c172
-rw-r--r--arch/arm/plat-nomadik/timer.c9
-rw-r--r--arch/arm/plat-omap/common.c22
-rw-r--r--arch/arm/plat-omap/devices.c1
-rw-r--r--arch/arm/plat-omap/dma.c10
-rw-r--r--arch/arm/plat-omap/gpio.c16
-rw-r--r--arch/arm/plat-omap/include/plat/blizzard.h2
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h8
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h2
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h2
-rw-r--r--arch/arm/plat-omap/include/plat/nand.h7
-rw-r--r--arch/arm/plat-omap/include/plat/omap44xx.h2
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h2
-rw-r--r--arch/arm/plat-omap/include/plat/prcm.h2
-rw-r--r--arch/arm/plat-omap/include/plat/system.h6
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h4
-rw-r--r--arch/arm/plat-omap/iommu-debug.c1
-rw-r--r--arch/arm/plat-omap/iommu.c1
-rw-r--r--arch/arm/plat-omap/iovmm.c1
-rw-r--r--arch/arm/plat-omap/mailbox.c1
-rw-r--r--arch/arm/plat-omap/mcbsp.c13
-rw-r--r--arch/arm/plat-omap/omap_device.c1
-rw-r--r--arch/arm/plat-pxa/dma.c1
-rw-r--r--arch/arm/plat-pxa/pwm.c1
-rw-r--r--arch/arm/plat-s3c/Kconfig215
-rw-r--r--arch/arm/plat-s3c/Makefile45
-rw-r--r--arch/arm/plat-s3c/clock.c366
-rw-r--r--arch/arm/plat-s3c/dev-fb.c73
-rw-r--r--arch/arm/plat-s3c/dev-i2c0.c71
-rw-r--r--arch/arm/plat-s3c/dev-i2c1.c68
-rw-r--r--arch/arm/plat-s3c/dev-nand.c129
-rw-r--r--arch/arm/plat-s3c/dev-usb-hsotg.c41
-rw-r--r--arch/arm/plat-s3c/dev-usb.c50
-rw-r--r--arch/arm/plat-s3c/dma.c86
-rw-r--r--arch/arm/plat-s3c/gpio-config.c166
-rw-r--r--arch/arm/plat-s3c/gpio.c156
-rw-r--r--arch/arm/plat-s3c/include/mach/io.h18
-rw-r--r--arch/arm/plat-s3c/include/mach/timex.h26
-rw-r--r--arch/arm/plat-s3c/include/mach/vmalloc.h20
-rw-r--r--arch/arm/plat-s3c/include/plat/adc.h35
-rw-r--r--arch/arm/plat-s3c/include/plat/audio-simtec.h37
-rw-r--r--arch/arm/plat-s3c/include/plat/audio.h17
-rw-r--r--arch/arm/plat-s3c/include/plat/clock.h89
-rw-r--r--arch/arm/plat-s3c/include/plat/cpu-freq.h145
-rw-r--r--arch/arm/plat-s3c/include/plat/cpu.h81
-rw-r--r--arch/arm/plat-s3c/include/plat/debug-macro.S75
-rw-r--r--arch/arm/plat-s3c/include/plat/devs.h67
-rw-r--r--arch/arm/plat-s3c/include/plat/dma.h127
-rw-r--r--arch/arm/plat-s3c/include/plat/fb.h80
-rw-r--r--arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h176
-rw-r--r--arch/arm/plat-s3c/include/plat/gpio-core.h107
-rw-r--r--arch/arm/plat-s3c/include/plat/nand.h67
-rw-r--r--arch/arm/plat-s3c/include/plat/pm.h189
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-adc.h60
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-fb-v4.h235
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-fb.h366
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-serial.h251
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h50
-rw-r--r--arch/arm/plat-s3c/include/plat/sdhci.h226
-rw-r--r--arch/arm/plat-s3c/include/plat/udc-hs.h29
-rw-r--r--arch/arm/plat-s3c/include/plat/uncompress.h186
-rw-r--r--arch/arm/plat-s3c/include/plat/usb-control.h41
-rw-r--r--arch/arm/plat-s3c/pm-check.c242
-rw-r--r--arch/arm/plat-s3c/pm-gpio.c380
-rw-r--r--arch/arm/plat-s3c/pm.c378
-rw-r--r--arch/arm/plat-s3c/pwm-clock.c463
-rw-r--r--arch/arm/plat-s3c/pwm.c410
-rw-r--r--arch/arm/plat-s3c/time.c285
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig60
-rw-r--r--arch/arm/plat-s3c24xx/Makefile8
-rw-r--r--arch/arm/plat-s3c24xx/adc.c435
-rw-r--r--arch/arm/plat-s3c24xx/clock-dclk.c22
-rw-r--r--arch/arm/plat-s3c24xx/cpu-freq.c1
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c4
-rw-r--r--arch/arm/plat-s3c24xx/devs.c60
-rw-r--r--arch/arm/plat-s3c24xx/dma.c2
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c2
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/audio-simtec.h37
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h2
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/dma-plat.h84
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/mci.h9
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pm-core.h64
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2440.h17
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2442.h17
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c244x.h37
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-iotiming.c1
-rw-r--r--arch/arm/plat-s3c24xx/s3c2412-iotiming.c1
-rw-r--r--arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c97
-rw-r--r--arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c127
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x-clock.c136
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x.c196
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x.h25
-rw-r--r--arch/arm/plat-s3c64xx/Kconfig71
-rw-r--r--arch/arm/plat-s3c64xx/Makefile44
-rw-r--r--arch/arm/plat-s3c64xx/clock.c300
-rw-r--r--arch/arm/plat-s3c64xx/cpu.c156
-rw-r--r--arch/arm/plat-s3c64xx/dev-audio.c167
-rw-r--r--arch/arm/plat-s3c64xx/dev-uart.c176
-rw-r--r--arch/arm/plat-s3c64xx/dma.c750
-rw-r--r--arch/arm/plat-s3c64xx/gpiolib.c446
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/dma-plat.h70
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h48
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h60
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h53
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h49
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h44
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h71
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h42
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h74
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h40
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h36
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h54
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h70
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h69
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h46
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/irqs.h210
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/pm-core.h98
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/regs-clock.h225
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/s3c6400.h36
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/s3c6410.h29
-rw-r--r--arch/arm/plat-s3c64xx/irq-eint.c213
-rw-r--r--arch/arm/plat-s3c64xx/irq-pm.c111
-rw-r--r--arch/arm/plat-s3c64xx/irq.c256
-rw-r--r--arch/arm/plat-s3c64xx/pm.c173
-rw-r--r--arch/arm/plat-s3c64xx/s3c6400-clock.c758
-rw-r--r--arch/arm/plat-s3c64xx/s3c6400-init.c29
-rw-r--r--arch/arm/plat-s3c64xx/setup-i2c0.c31
-rw-r--r--arch/arm/plat-s3c64xx/setup-i2c1.c31
-rw-r--r--arch/arm/plat-s3c64xx/sleep.S144
-rw-r--r--arch/arm/plat-s5p/Kconfig25
-rw-r--r--arch/arm/plat-s5p/Makefile19
-rw-r--r--arch/arm/plat-s5p/clock.c149
-rw-r--r--arch/arm/plat-s5p/cpu.c113
-rw-r--r--arch/arm/plat-s5p/dev-uart.c139
-rw-r--r--arch/arm/plat-s5p/include/plat/irqs.h90
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h34
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h83
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h40
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p6440.h37
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p6442.h33
-rw-r--r--arch/arm/plat-s5p/include/plat/s5pv210.h33
-rw-r--r--arch/arm/plat-s5p/irq.c72
-rw-r--r--arch/arm/plat-s5p/setup-i2c0.c25
-rw-r--r--arch/arm/plat-s5pc1xx/Kconfig3
-rw-r--r--arch/arm/plat-s5pc1xx/clock.c31
-rw-r--r--arch/arm/plat-s5pc1xx/dev-uart.c29
-rw-r--r--arch/arm/plat-s5pc1xx/gpio-config.c2
-rw-r--r--arch/arm/plat-s5pc1xx/gpiolib.c2
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/irqs.h19
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/regs-clock.h119
-rw-r--r--arch/arm/plat-s5pc1xx/irq.c202
-rw-r--r--arch/arm/plat-s5pc1xx/s5pc100-clock.c770
-rw-r--r--arch/arm/plat-samsung/Kconfig229
-rw-r--r--arch/arm/plat-samsung/Makefile45
-rw-r--r--arch/arm/plat-samsung/adc.c475
-rw-r--r--arch/arm/plat-samsung/clock-clksrc.c212
-rw-r--r--arch/arm/plat-samsung/clock.c409
-rw-r--r--arch/arm/plat-samsung/dev-fb.c74
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c (renamed from arch/arm/plat-s3c/dev-hsmmc.c)0
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c (renamed from arch/arm/plat-s3c/dev-hsmmc1.c)0
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c (renamed from arch/arm/plat-s3c/dev-hsmmc2.c)0
-rw-r--r--arch/arm/plat-samsung/dev-i2c0.c72
-rw-r--r--arch/arm/plat-samsung/dev-i2c1.c69
-rw-r--r--arch/arm/plat-samsung/dev-nand.c130
-rw-r--r--arch/arm/plat-samsung/dev-uart.c44
-rw-r--r--arch/arm/plat-samsung/dev-usb-hsotg.c48
-rw-r--r--arch/arm/plat-samsung/dev-usb.c70
-rw-r--r--arch/arm/plat-samsung/dma.c84
-rw-r--r--arch/arm/plat-samsung/gpio-config.c166
-rw-r--r--arch/arm/plat-samsung/gpio.c156
-rw-r--r--arch/arm/plat-samsung/gpiolib.c199
-rw-r--r--arch/arm/plat-samsung/include/plat/adc.h35
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h25
-rw-r--r--arch/arm/plat-samsung/include/plat/clock-clksrc.h83
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h115
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu-freq.h145
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h84
-rw-r--r--arch/arm/plat-samsung/include/plat/debug-macro.S87
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h74
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-core.h (renamed from arch/arm/plat-s3c/include/plat/dma-core.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-s3c24xx.h84
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h127
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h80
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h176
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h (renamed from arch/arm/plat-s3c/include/plat/gpio-cfg.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h137
-rw-r--r--arch/arm/plat-samsung/include/plat/hwmon.h (renamed from arch/arm/plat-s3c/include/plat/hwmon.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/iic-core.h (renamed from arch/arm/plat-s3c/include/plat/iic-core.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h (renamed from arch/arm/plat-s3c/include/plat/iic.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/irq-uart.h20
-rw-r--r--arch/arm/plat-samsung/include/plat/irq-vic-timer.h13
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h (renamed from arch/arm/plat-s3c/include/plat/map-base.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/nand.h67
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h189
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-ac97.h (renamed from arch/arm/plat-s3c/include/plat/regs-ac97.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-adc.h64
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb-v4.h235
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb.h366
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-iic.h (renamed from arch/arm/plat-s3c/include/plat/regs-iic.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-irqtype.h (renamed from arch/arm/plat-s3c/include/plat/regs-irqtype.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-nand.h (renamed from arch/arm/plat-s3c/include/plat/regs-nand.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-rtc.h (renamed from arch/arm/plat-s3c/include/plat/regs-rtc.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h (renamed from arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-sdhci.h (renamed from arch/arm/plat-s3c/include/plat/regs-sdhci.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h281
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-timer.h (renamed from arch/arm/plat-s3c/include/plat/regs-timer.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h50
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h (renamed from arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-watchdog.h (renamed from arch/arm/plat-s3c/include/plat/regs-watchdog.h)0
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h67
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h221
-rw-r--r--arch/arm/plat-samsung/include/plat/udc-hs.h29
-rw-r--r--arch/arm/plat-samsung/include/plat/uncompress.h184
-rw-r--r--arch/arm/plat-samsung/include/plat/usb-control.h43
-rw-r--r--arch/arm/plat-samsung/include/plat/watchdog-reset.h (renamed from arch/arm/plat-s3c/include/plat/watchdog-reset.h)0
-rw-r--r--arch/arm/plat-samsung/init.c (renamed from arch/arm/plat-s3c/init.c)0
-rw-r--r--arch/arm/plat-samsung/irq-uart.c143
-rw-r--r--arch/arm/plat-samsung/irq-vic-timer.c86
-rw-r--r--arch/arm/plat-samsung/pm-check.c243
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c380
-rw-r--r--arch/arm/plat-samsung/pm.c378
-rw-r--r--arch/arm/plat-samsung/pwm-clock.c455
-rw-r--r--arch/arm/plat-samsung/pwm.c446
-rw-r--r--arch/arm/plat-samsung/time.c285
-rw-r--r--arch/arm/plat-stmp3xxx/dma.c1
-rw-r--r--arch/arm/tools/mach-types75
-rw-r--r--arch/arm/vfp/vfpmodule.c33
-rw-r--r--arch/avr32/include/asm/ptrace.h2
-rw-r--r--arch/avr32/kernel/process.c1
-rw-r--r--arch/avr32/kernel/ptrace.c53
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c1
-rw-r--r--arch/avr32/mach-at32ap/extint.c1
-rw-r--r--arch/avr32/mach-at32ap/hsmc.c1
-rw-r--r--arch/avr32/mm/dma-coherent.c1
-rw-r--r--arch/avr32/mm/init.c1
-rw-r--r--arch/avr32/mm/ioremap.c1
-rw-r--r--arch/blackfin/Kconfig81
-rw-r--r--arch/blackfin/Kconfig.debug12
-rw-r--r--arch/blackfin/Makefile7
-rw-r--r--arch/blackfin/boot/Makefile23
-rw-r--r--arch/blackfin/configs/BF518F-EZBRD_defconfig270
-rw-r--r--arch/blackfin/configs/BF526-EZBRD_defconfig336
-rw-r--r--arch/blackfin/configs/BF527-EZKIT-V2_defconfig1811
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig344
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig250
-rw-r--r--arch/blackfin/configs/BF533-STAMP_defconfig295
-rw-r--r--arch/blackfin/configs/BF537-STAMP_defconfig332
-rw-r--r--arch/blackfin/configs/BF538-EZKIT_defconfig291
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig108
-rw-r--r--arch/blackfin/configs/BF561-ACVILON_defconfig15
-rw-r--r--arch/blackfin/configs/BF561-EZKIT_defconfig82
-rw-r--r--arch/blackfin/configs/H8606_defconfig7
-rw-r--r--arch/blackfin/configs/PNAV-10_defconfig295
-rw-r--r--arch/blackfin/configs/TCM-BF518_defconfig1375
-rw-r--r--arch/blackfin/include/asm/bfin-lq035q1.h12
-rw-r--r--arch/blackfin/include/asm/bfin_can.h725
-rw-r--r--arch/blackfin/include/asm/bfin_sport.h227
-rw-r--r--arch/blackfin/include/asm/bfin_watchdog.h30
-rw-r--r--arch/blackfin/include/asm/bitops.h74
-rw-r--r--arch/blackfin/include/asm/context.S22
-rw-r--r--arch/blackfin/include/asm/cpu.h2
-rw-r--r--arch/blackfin/include/asm/def_LPBlackfin.h58
-rw-r--r--arch/blackfin/include/asm/delay.h16
-rw-r--r--arch/blackfin/include/asm/dma-mapping.h51
-rw-r--r--arch/blackfin/include/asm/dma.h4
-rw-r--r--arch/blackfin/include/asm/dpmc.h4
-rw-r--r--arch/blackfin/include/asm/elf.h8
-rw-r--r--arch/blackfin/include/asm/ftrace.h53
-rw-r--r--arch/blackfin/include/asm/gpio.h17
-rw-r--r--arch/blackfin/include/asm/irq.h7
-rw-r--r--arch/blackfin/include/asm/mmu_context.h16
-rw-r--r--arch/blackfin/include/asm/nand.h4
-rw-r--r--arch/blackfin/include/asm/nmi.h12
-rw-r--r--arch/blackfin/include/asm/page.h3
-rw-r--r--arch/blackfin/include/asm/ptrace.h25
-rw-r--r--arch/blackfin/include/asm/sections.h3
-rw-r--r--arch/blackfin/include/asm/smp.h15
-rw-r--r--arch/blackfin/include/asm/syscall.h96
-rw-r--r--arch/blackfin/include/asm/thread_info.h25
-rw-r--r--arch/blackfin/include/asm/time.h13
-rw-r--r--arch/blackfin/kernel/Makefile1
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c10
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c20
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbinit.c9
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c54
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinit.c9
-rw-r--r--arch/blackfin/kernel/dma-mapping.c2
-rw-r--r--arch/blackfin/kernel/entry.S8
-rw-r--r--arch/blackfin/kernel/ftrace-entry.S23
-rw-r--r--arch/blackfin/kernel/ftrace.c6
-rw-r--r--arch/blackfin/kernel/init_task.c2
-rw-r--r--arch/blackfin/kernel/ipipe.c1
-rw-r--r--arch/blackfin/kernel/kgdb.c10
-rw-r--r--arch/blackfin/kernel/nmi.c299
-rw-r--r--arch/blackfin/kernel/process.c8
-rw-r--r--arch/blackfin/kernel/ptrace.c360
-rw-r--r--arch/blackfin/kernel/setup.c34
-rw-r--r--arch/blackfin/kernel/signal.c24
-rw-r--r--arch/blackfin/kernel/time-ts.c205
-rw-r--r--arch/blackfin/kernel/traps.c32
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S70
-rw-r--r--arch/blackfin/mach-bf518/boards/Kconfig5
-rw-r--r--arch/blackfin/mach-bf518/boards/Makefile1
-rw-r--r--arch/blackfin/mach-bf518/boards/ezbrd.c178
-rw-r--r--arch/blackfin/mach-bf518/boards/tcm-bf518.c753
-rw-r--r--arch/blackfin/mach-bf518/include/mach/irq.h12
-rw-r--r--arch/blackfin/mach-bf518/include/mach/mem_map.h2
-rw-r--r--arch/blackfin/mach-bf527/boards/Kconfig5
-rw-r--r--arch/blackfin/mach-bf527/boards/Makefile1
-rw-r--r--arch/blackfin/mach-bf527/boards/cm_bf527.c245
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c199
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c431
-rw-r--r--arch/blackfin/mach-bf527/include/mach/irq.h12
-rw-r--r--arch/blackfin/mach-bf533/boards/H8606.c66
-rw-r--r--arch/blackfin/mach-bf533/boards/blackstamp.c134
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c138
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c102
-rw-r--r--arch/blackfin/mach-bf533/boards/ip0x.c63
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c174
-rw-r--r--arch/blackfin/mach-bf533/include/mach/irq.h3
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537e.c116
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537u.c187
-rw-r--r--arch/blackfin/mach-bf537/boards/minotaur.c183
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c169
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c684
-rw-r--r--arch/blackfin/mach-bf537/boards/tcm_bf537.c187
-rw-r--r--arch/blackfin/mach-bf537/include/mach/irq.h12
-rw-r--r--arch/blackfin/mach-bf538/boards/ezkit.c346
-rw-r--r--arch/blackfin/mach-bf538/include/mach/irq.h3
-rw-r--r--arch/blackfin/mach-bf548/boards/cm_bf548.c399
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c443
-rw-r--r--arch/blackfin/mach-bf548/include/mach/irq.h3
-rw-r--r--arch/blackfin/mach-bf561/Makefile1
-rw-r--r--arch/blackfin/mach-bf561/boards/acvilon.c2
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c66
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c70
-rw-r--r--arch/blackfin/mach-bf561/boards/tepla.c68
-rw-r--r--arch/blackfin/mach-bf561/hotplug.c32
-rw-r--r--arch/blackfin/mach-bf561/include/mach/irq.h3
-rw-r--r--arch/blackfin/mach-bf561/include/mach/smp.h2
-rw-r--r--arch/blackfin/mach-bf561/secondary.S50
-rw-r--r--arch/blackfin/mach-bf561/smp.c44
-rw-r--r--arch/blackfin/mach-common/cpufreq.c168
-rw-r--r--arch/blackfin/mach-common/entry.S81
-rw-r--r--arch/blackfin/mach-common/head.S16
-rw-r--r--arch/blackfin/mach-common/interrupt.S35
-rw-r--r--arch/blackfin/mach-common/ints-priority.c208
-rw-r--r--arch/blackfin/mach-common/pm.c1
-rw-r--r--arch/blackfin/mach-common/smp.c88
-rw-r--r--arch/blackfin/mm/init.c1
-rw-r--r--arch/blackfin/mm/isram-driver.c7
-rw-r--r--arch/blackfin/mm/sram-alloc.c28
-rw-r--r--arch/cris/Kconfig6
-rw-r--r--arch/cris/arch-v10/drivers/i2c.c1
-rw-r--r--arch/cris/arch-v10/drivers/sync_serial.c1
-rw-r--r--arch/cris/arch-v10/kernel/entry.S2
-rw-r--r--arch/cris/arch-v10/kernel/process.c2
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c51
-rw-r--r--arch/cris/arch-v10/lib/old_checksum.c2
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c2
-rw-r--r--arch/cris/arch-v32/drivers/i2c.c1
-rw-r--r--arch/cris/arch-v32/drivers/pci/bios.c2
-rw-r--r--arch/cris/arch-v32/drivers/pci/dma.c1
-rw-r--r--arch/cris/arch-v32/drivers/sync_serial.c1
-rw-r--r--arch/cris/arch-v32/kernel/entry.S2
-rw-r--r--arch/cris/arch-v32/kernel/process.c2
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c109
-rw-r--r--arch/cris/arch-v32/kernel/signal.c1
-rw-r--r--arch/cris/arch-v32/mach-fs/arbiter.c2
-rw-r--r--arch/cris/arch-v32/mm/tlb.c2
-rw-r--r--arch/cris/include/arch-v32/arch/ptrace.h1
-rw-r--r--arch/cris/include/asm/pci.h8
-rw-r--r--arch/cris/include/asm/unistd.h2
-rw-r--r--arch/cris/kernel/irq.c1
-rw-r--r--arch/cris/kernel/module.c1
-rw-r--r--arch/cris/kernel/profile.c1
-rw-r--r--arch/cris/kernel/sys_cris.c96
-rw-r--r--arch/cris/kernel/time.c68
-rw-r--r--arch/cris/mm/init.c1
-rw-r--r--arch/frv/include/asm/dma-mapping.h41
-rw-r--r--arch/frv/include/asm/pci.h45
-rw-r--r--arch/frv/include/asm/ptrace.h2
-rw-r--r--arch/frv/include/asm/segment.h6
-rw-r--r--arch/frv/include/asm/uaccess.h2
-rw-r--r--arch/frv/include/asm/unistd.h1
-rw-r--r--arch/frv/kernel/irq.c1
-rw-r--r--arch/frv/kernel/sys_frv.c89
-rw-r--r--arch/frv/kernel/sysctl.c1
-rw-r--r--arch/frv/mb93090-mb00/pci-dma-nommu.c30
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c31
-rw-r--r--arch/frv/mb93090-mb00/pci-frv.c6
-rw-r--r--arch/frv/mb93090-mb00/pci-irq.c1
-rw-r--r--arch/frv/mb93090-mb00/pci-vdk.c1
-rw-r--r--arch/frv/mm/dma-alloc.c1
-rw-r--r--arch/frv/mm/init.c1
-rw-r--r--arch/frv/mm/pgalloc.c2
-rw-r--r--arch/h8300/include/asm/io.h2
-rw-r--r--arch/h8300/include/asm/ptrace.h2
-rw-r--r--arch/h8300/include/asm/unistd.h3
-rw-r--r--arch/h8300/kernel/process.c2
-rw-r--r--arch/h8300/kernel/ptrace.c82
-rw-r--r--arch/h8300/kernel/sys_h8300.c138
-rw-r--r--arch/h8300/kernel/syscalls.S4
-rw-r--r--arch/h8300/mm/init.c2
-rw-r--r--arch/h8300/mm/kmap.c1
-rw-r--r--arch/h8300/mm/memory.c1
-rw-r--r--arch/h8300/platform/h8300h/ptrace_h8300h.c6
-rw-r--r--arch/h8300/platform/h8s/ptrace_h8s.c4
-rw-r--r--arch/ia64/Kconfig3
-rw-r--r--arch/ia64/include/asm/compat.h3
-rw-r--r--arch/ia64/include/asm/dmi.h1
-rw-r--r--arch/ia64/include/asm/elf.h48
-rw-r--r--arch/ia64/include/asm/pci.h14
-rw-r--r--arch/ia64/include/asm/ptrace.h4
-rw-r--r--arch/ia64/kernel/Makefile2
-rw-r--r--arch/ia64/kernel/acpi-ext.c1
-rw-r--r--arch/ia64/kernel/acpi.c4
-rw-r--r--arch/ia64/kernel/cpufreq/acpi-cpufreq.c1
-rw-r--r--arch/ia64/kernel/efi.c1
-rw-r--r--arch/ia64/kernel/elfcore.c80
-rw-r--r--arch/ia64/kernel/iosapic.c1
-rw-r--r--arch/ia64/kernel/irq_ia64.c1
-rw-r--r--arch/ia64/kernel/mca.c1
-rw-r--r--arch/ia64/kernel/mca_drv.c1
-rw-r--r--arch/ia64/kernel/pci-swiotlb.c1
-rw-r--r--arch/ia64/kernel/perfmon.c2
-rw-r--r--arch/ia64/kernel/process.c2
-rw-r--r--arch/ia64/kernel/ptrace.c1
-rw-r--r--arch/ia64/kernel/topology.c3
-rw-r--r--arch/ia64/kernel/uncached.c2
-rw-r--r--arch/ia64/kvm/Kconfig1
-rw-r--r--arch/ia64/kvm/kvm-ia64.c61
-rw-r--r--arch/ia64/kvm/kvm_fw.c28
-rw-r--r--arch/ia64/kvm/mmio.c4
-rw-r--r--arch/ia64/kvm/vcpu.c4
-rw-r--r--arch/ia64/mm/discontig.c1
-rw-r--r--arch/ia64/mm/hugetlbpage.c1
-rw-r--r--arch/ia64/mm/init.c2
-rw-r--r--arch/ia64/mm/tlb.c1
-rw-r--r--arch/ia64/sn/kernel/bte.c1
-rw-r--r--arch/ia64/sn/kernel/io_acpi_init.c1
-rw-r--r--arch/ia64/sn/kernel/io_common.c1
-rw-r--r--arch/ia64/sn/kernel/io_init.c1
-rw-r--r--arch/ia64/sn/kernel/irq.c1
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c1
-rw-r--r--arch/ia64/sn/kernel/setup.c2
-rw-r--r--arch/ia64/sn/pci/pci_dma.c1
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c1
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c1
-rw-r--r--arch/ia64/sn/pci/tioce_provider.c1
-rw-r--r--arch/ia64/xen/grant-table.c1
-rw-r--r--arch/m32r/include/asm/ptrace.h2
-rw-r--r--arch/m32r/include/asm/unistd.h1
-rw-r--r--arch/m32r/kernel/process.c2
-rw-r--r--arch/m32r/kernel/ptrace.c97
-rw-r--r--arch/m32r/kernel/sys_m32r.c92
-rw-r--r--arch/m32r/mm/init.c1
-rw-r--r--arch/m68k/atari/atakeyb.c2
-rw-r--r--arch/m68k/bvme6000/rtc.c1
-rw-r--r--arch/m68k/include/asm/atomic_mm.h8
-rw-r--r--arch/m68k/include/asm/fbio.h2
-rw-r--r--arch/m68k/include/asm/io_no.h2
-rw-r--r--arch/m68k/include/asm/mcfuart.h5
-rw-r--r--arch/m68k/include/asm/ptrace.h8
-rw-r--r--arch/m68k/include/asm/sigcontext.h4
-rw-r--r--arch/m68k/include/asm/unistd.h3
-rw-r--r--arch/m68k/kernel/dma.c1
-rw-r--r--arch/m68k/kernel/entry.S4
-rw-r--r--arch/m68k/kernel/process.c2
-rw-r--r--arch/m68k/kernel/sys_m68k.c131
-rw-r--r--arch/m68k/mac/misc.c1
-rw-r--r--arch/m68k/mm/init.c1
-rw-r--r--arch/m68k/mm/memory.c2
-rw-r--r--arch/m68k/mm/motorola.c1
-rw-r--r--arch/m68k/mvme16x/rtc.c1
-rw-r--r--arch/m68k/sun3/sun3dvma.c1
-rw-r--r--arch/m68k/sun3x/dvma.c1
-rw-r--r--arch/m68knommu/Makefile2
-rw-r--r--arch/m68knommu/kernel/dma.c1
-rw-r--r--arch/m68knommu/kernel/entry.S2
-rw-r--r--arch/m68knommu/kernel/process.c2
-rw-r--r--arch/m68knommu/kernel/ptrace.c74
-rw-r--r--arch/m68knommu/kernel/sys_m68k.c136
-rw-r--r--arch/m68knommu/kernel/syscalltable.S4
-rw-r--r--arch/m68knommu/mm/init.c2
-rw-r--r--arch/m68knommu/mm/kmap.c1
-rw-r--r--arch/m68knommu/mm/memory.c1
-rw-r--r--arch/m68knommu/platform/68360/ints.c1
-rw-r--r--arch/microblaze/Kconfig67
-rw-r--r--arch/microblaze/Makefile5
-rw-r--r--arch/microblaze/boot/Makefile6
-rw-r--r--arch/microblaze/include/asm/device.h4
-rw-r--r--arch/microblaze/include/asm/dma-mapping.h154
-rw-r--r--arch/microblaze/include/asm/futex.h2
-rw-r--r--arch/microblaze/include/asm/io.h36
-rw-r--r--arch/microblaze/include/asm/irq.h37
-rw-r--r--arch/microblaze/include/asm/page.h12
-rw-r--r--arch/microblaze/include/asm/pci-bridge.h195
-rw-r--r--arch/microblaze/include/asm/pci.h178
-rw-r--r--arch/microblaze/include/asm/pgalloc.h2
-rw-r--r--arch/microblaze/include/asm/pgtable.h40
-rw-r--r--arch/microblaze/include/asm/processor.h1
-rw-r--r--arch/microblaze/include/asm/prom.h15
-rw-r--r--arch/microblaze/include/asm/segment.h49
-rw-r--r--arch/microblaze/include/asm/system.h3
-rw-r--r--arch/microblaze/include/asm/thread_info.h5
-rw-r--r--arch/microblaze/include/asm/tlbflush.h5
-rw-r--r--arch/microblaze/include/asm/uaccess.h447
-rw-r--r--arch/microblaze/kernel/Makefile2
-rw-r--r--arch/microblaze/kernel/asm-offsets.c1
-rw-r--r--arch/microblaze/kernel/cpu/cache.c211
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c1
-rw-r--r--arch/microblaze/kernel/dma.c157
-rw-r--r--arch/microblaze/kernel/entry.S116
-rw-r--r--arch/microblaze/kernel/ftrace.c12
-rw-r--r--arch/microblaze/kernel/head.S21
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S112
-rw-r--r--arch/microblaze/kernel/irq.c15
-rw-r--r--arch/microblaze/kernel/misc.S15
-rw-r--r--arch/microblaze/kernel/module.c1
-rw-r--r--arch/microblaze/kernel/of_platform.c1
-rw-r--r--arch/microblaze/kernel/process.c10
-rw-r--r--arch/microblaze/kernel/ptrace.c65
-rw-r--r--arch/microblaze/kernel/setup.c69
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c1
-rw-r--r--arch/microblaze/kernel/traps.c6
-rw-r--r--arch/microblaze/lib/Makefile3
-rw-r--r--arch/microblaze/lib/fastcopy.S6
-rw-r--r--arch/microblaze/lib/memcpy.c2
-rw-r--r--arch/microblaze/lib/memset.c15
-rw-r--r--arch/microblaze/lib/uaccess.c48
-rw-r--r--arch/microblaze/lib/uaccess_old.S45
-rw-r--r--arch/microblaze/mm/Makefile2
-rw-r--r--arch/microblaze/mm/consistent.c247
-rw-r--r--arch/microblaze/mm/fault.c24
-rw-r--r--arch/microblaze/mm/init.c45
-rw-r--r--arch/microblaze/mm/pgtable.c4
-rw-r--r--arch/microblaze/pci/Makefile6
-rw-r--r--arch/microblaze/pci/indirect_pci.c163
-rw-r--r--arch/microblaze/pci/iomap.c39
-rw-r--r--arch/microblaze/pci/pci-common.c1643
-rw-r--r--arch/microblaze/pci/pci_32.c431
-rw-r--r--arch/microblaze/pci/xilinx_pci.c168
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/mips/alchemy/devboards/db1200/setup.c40
-rw-r--r--arch/mips/ar7/platform.c3
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c231
-rw-r--r--arch/mips/bcm63xx/cpu.c5
-rw-r--r--arch/mips/bcm63xx/dev-uart.c66
-rw-r--r--arch/mips/bcm63xx/gpio.c4
-rw-r--r--arch/mips/cavium-octeon/setup.c82
-rw-r--r--arch/mips/cavium-octeon/smp.c8
-rw-r--r--arch/mips/configs/bigsur_defconfig680
-rw-r--r--arch/mips/include/asm/abi.h6
-rw-r--r--arch/mips/include/asm/compat.h3
-rw-r--r--arch/mips/include/asm/elf.h5
-rw-r--r--arch/mips/include/asm/fpu_emulator.h6
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h15
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h6
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h4
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h2
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h2
-rw-r--r--arch/mips/include/asm/mach-sibyte/war.h6
-rw-r--r--arch/mips/include/asm/mmu.h5
-rw-r--r--arch/mips/include/asm/mmu_context.h2
-rw-r--r--arch/mips/include/asm/page.h6
-rw-r--r--arch/mips/include/asm/pci.h22
-rw-r--r--arch/mips/include/asm/processor.h11
-rw-r--r--arch/mips/include/asm/stackframe.h19
-rw-r--r--arch/mips/include/asm/uasm.h2
-rw-r--r--arch/mips/include/asm/unistd.h2
-rw-r--r--arch/mips/include/asm/vdso.h29
-rw-r--r--arch/mips/jazz/jazzdma.c1
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/cpufreq/loongson2_clock.c4
-rw-r--r--arch/mips/kernel/irq.c1
-rw-r--r--arch/mips/kernel/linux32.c18
-rw-r--r--arch/mips/kernel/process.c8
-rw-r--r--arch/mips/kernel/ptrace.c30
-rw-r--r--arch/mips/kernel/rtlx.c1
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/signal-common.h5
-rw-r--r--arch/mips/kernel/signal.c86
-rw-r--r--arch/mips/kernel/signal32.c55
-rw-r--r--arch/mips/kernel/signal_n32.c26
-rw-r--r--arch/mips/kernel/smtc.c3
-rw-r--r--arch/mips/kernel/syscall.c138
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/mips/kernel/vdso.c112
-rw-r--r--arch/mips/lib/delay.c4
-rw-r--r--arch/mips/lib/libgcc.h3
-rw-r--r--arch/mips/mipssim/sim_int.c1
-rw-r--r--arch/mips/mm/cache.c2
-rw-r--r--arch/mips/mm/dma-default.c1
-rw-r--r--arch/mips/mm/hugetlbpage.c1
-rw-r--r--arch/mips/mm/init.c1
-rw-r--r--arch/mips/mm/ioremap.c1
-rw-r--r--arch/mips/mm/tlbex.c22
-rw-r--r--arch/mips/mm/uasm.c23
-rw-r--r--arch/mips/mti-malta/malta-int.c1
-rw-r--r--arch/mips/nxp/pnx833x/common/reset.c1
-rw-r--r--arch/mips/nxp/pnx8550/common/int.c1
-rw-r--r--arch/mips/nxp/pnx8550/common/proc.c1
-rw-r--r--arch/mips/nxp/pnx8550/common/reset.c1
-rw-r--r--arch/mips/pci/ops-loongson2.c10
-rw-r--r--arch/mips/pci/ops-titan-ht.c1
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_prom.c1
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht.c1
-rw-r--r--arch/mips/pmc-sierra/yosemite/irq.c1
-rw-r--r--arch/mips/powertv/asic/asic_devices.c1
-rw-r--r--arch/mips/powertv/asic/asic_int.c1
-rw-r--r--arch/mips/rb532/irq.c1
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c1
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c1
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c1
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c1
-rw-r--r--arch/mips/sibyte/sb1250/irq.c1
-rw-r--r--arch/mips/sibyte/sb1250/setup.c15
-rw-r--r--arch/mips/txx9/generic/7segled.c5
-rw-r--r--arch/mips/txx9/generic/pci.c1
-rw-r--r--arch/mips/txx9/generic/setup.c2
-rw-r--r--arch/mips/txx9/generic/spi_eeprom.c1
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c1
-rw-r--r--arch/mn10300/include/asm/dma-mapping.h65
-rw-r--r--arch/mn10300/include/asm/ptrace.h2
-rw-r--r--arch/mn10300/include/asm/unistd.h2
-rw-r--r--arch/mn10300/kernel/entry.S2
-rw-r--r--arch/mn10300/kernel/process.c2
-rw-r--r--arch/mn10300/kernel/setup.c1
-rw-r--r--arch/mn10300/kernel/sys_mn10300.c106
-rw-r--r--arch/mn10300/mm/dma-alloc.c1
-rw-r--r--arch/mn10300/mm/init.c2
-rw-r--r--arch/mn10300/mm/pgtable.c2
-rw-r--r--arch/mn10300/unit-asb2305/pci-irq.c1
-rw-r--r--arch/parisc/Kconfig3
-rw-r--r--arch/parisc/Kconfig.debug14
-rw-r--r--arch/parisc/hpux/fs.c2
-rw-r--r--arch/parisc/include/asm/compat.h3
-rw-r--r--arch/parisc/include/asm/param.h23
-rw-r--r--arch/parisc/include/asm/pci.h14
-rw-r--r--arch/parisc/include/asm/ptrace.h5
-rw-r--r--arch/parisc/include/asm/system.h2
-rw-r--r--arch/parisc/include/asm/uaccess.h27
-rw-r--r--arch/parisc/include/asm/unistd.h4
-rw-r--r--arch/parisc/kernel/cache.c4
-rw-r--r--arch/parisc/kernel/module.c1
-rw-r--r--arch/parisc/kernel/pci-dma.c2
-rw-r--r--arch/parisc/kernel/pci.c1
-rw-r--r--arch/parisc/kernel/process.c1
-rw-r--r--arch/parisc/kernel/signal32.c1
-rw-r--r--arch/parisc/kernel/smp.c1
-rw-r--r--arch/parisc/kernel/sys_parisc.c15
-rw-r--r--arch/parisc/kernel/syscall_table.S4
-rw-r--r--arch/parisc/kernel/time.c29
-rw-r--r--arch/parisc/kernel/unaligned.c14
-rw-r--r--arch/parisc/lib/memcpy.c3
-rw-r--r--arch/parisc/mm/init.c1
-rw-r--r--arch/powerpc/Kconfig16
-rw-r--r--arch/powerpc/boot/dts/gef_ppc9a.dts4
-rw-r--r--arch/powerpc/boot/dts/gef_sbc310.dts4
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts4
-rw-r--r--arch/powerpc/boot/dts/kmeter1.dts2
-rw-r--r--arch/powerpc/configs/52xx/cm5200_defconfig24
-rw-r--r--arch/powerpc/configs/52xx/lite5200b_defconfig28
-rw-r--r--arch/powerpc/configs/52xx/motionpro_defconfig25
-rw-r--r--arch/powerpc/configs/52xx/pcm030_defconfig27
-rw-r--r--arch/powerpc/configs/52xx/tqm5200_defconfig28
-rw-r--r--arch/powerpc/configs/83xx/asp8347_defconfig44
-rw-r--r--arch/powerpc/configs/83xx/kmeter1_defconfig28
-rw-r--r--arch/powerpc/configs/83xx/mpc8313_rdb_defconfig49
-rw-r--r--arch/powerpc/configs/83xx/mpc8315_rdb_defconfig50
-rw-r--r--arch/powerpc/configs/83xx/mpc832x_mds_defconfig45
-rw-r--r--arch/powerpc/configs/83xx/mpc832x_rdb_defconfig49
-rw-r--r--arch/powerpc/configs/83xx/mpc834x_itx_defconfig44
-rw-r--r--arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig43
-rw-r--r--arch/powerpc/configs/83xx/mpc834x_mds_defconfig46
-rw-r--r--arch/powerpc/configs/83xx/mpc836x_mds_defconfig45
-rw-r--r--arch/powerpc/configs/83xx/mpc836x_rdk_defconfig44
-rw-r--r--arch/powerpc/configs/83xx/mpc837x_mds_defconfig46
-rw-r--r--arch/powerpc/configs/83xx/mpc837x_rdb_defconfig51
-rw-r--r--arch/powerpc/configs/83xx/sbc834x_defconfig44
-rw-r--r--arch/powerpc/configs/85xx/ksi8560_defconfig23
-rw-r--r--arch/powerpc/configs/85xx/mpc8540_ads_defconfig25
-rw-r--r--arch/powerpc/configs/85xx/mpc8560_ads_defconfig34
-rw-r--r--arch/powerpc/configs/85xx/mpc85xx_cds_defconfig31
-rw-r--r--arch/powerpc/configs/85xx/sbc8548_defconfig31
-rw-r--r--arch/powerpc/configs/85xx/sbc8560_defconfig25
-rw-r--r--arch/powerpc/configs/85xx/socrates_defconfig51
-rw-r--r--arch/powerpc/configs/85xx/stx_gp3_defconfig51
-rw-r--r--arch/powerpc/configs/85xx/tqm8540_defconfig48
-rw-r--r--arch/powerpc/configs/85xx/tqm8541_defconfig54
-rw-r--r--arch/powerpc/configs/85xx/tqm8548_defconfig47
-rw-r--r--arch/powerpc/configs/85xx/tqm8555_defconfig54
-rw-r--r--arch/powerpc/configs/85xx/tqm8560_defconfig54
-rw-r--r--arch/powerpc/configs/85xx/xes_mpc85xx_defconfig59
-rw-r--r--arch/powerpc/configs/86xx/gef_ppc9a_defconfig102
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc310_defconfig53
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc610_defconfig96
-rw-r--r--arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig34
-rw-r--r--arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig48
-rw-r--r--arch/powerpc/configs/86xx/sbc8641d_defconfig40
-rw-r--r--arch/powerpc/configs/adder875_defconfig18
-rw-r--r--arch/powerpc/configs/c2k_defconfig55
-rw-r--r--arch/powerpc/configs/ep8248e_defconfig20
-rw-r--r--arch/powerpc/configs/ep88xc_defconfig17
-rw-r--r--arch/powerpc/configs/linkstation_defconfig48
-rw-r--r--arch/powerpc/configs/mgcoge_defconfig31
-rw-r--r--arch/powerpc/configs/mgsuvd_defconfig19
-rw-r--r--arch/powerpc/configs/mpc5200_defconfig134
-rw-r--r--arch/powerpc/configs/mpc7448_hpc2_defconfig26
-rw-r--r--arch/powerpc/configs/mpc8272_ads_defconfig23
-rw-r--r--arch/powerpc/configs/mpc83xx_defconfig124
-rw-r--r--arch/powerpc/configs/mpc85xx_defconfig62
-rw-r--r--arch/powerpc/configs/mpc85xx_smp_defconfig64
-rw-r--r--arch/powerpc/configs/mpc866_ads_defconfig20
-rw-r--r--arch/powerpc/configs/mpc86xx_defconfig57
-rw-r--r--arch/powerpc/configs/mpc885_ads_defconfig20
-rw-r--r--arch/powerpc/configs/pq2fads_defconfig22
-rw-r--r--arch/powerpc/configs/prpmc2800_defconfig52
-rw-r--r--arch/powerpc/configs/ps3_defconfig189
-rw-r--r--arch/powerpc/configs/storcenter_defconfig33
-rw-r--r--arch/powerpc/include/asm/asm-compat.h2
-rw-r--r--arch/powerpc/include/asm/compat.h3
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h3
-rw-r--r--arch/powerpc/include/asm/kvm_asm.h6
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h11
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64_asm.h18
-rw-r--r--arch/powerpc/include/asm/kvm_e500.h3
-rw-r--r--arch/powerpc/include/asm/kvm_host.h23
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h83
-rw-r--r--arch/powerpc/include/asm/paca.h23
-rw-r--r--arch/powerpc/include/asm/page.h15
-rw-r--r--arch/powerpc/include/asm/pci.h32
-rw-r--r--arch/powerpc/include/asm/perf_event.h109
-rw-r--r--arch/powerpc/include/asm/perf_event_fsl_emb.h50
-rw-r--r--arch/powerpc/include/asm/perf_event_server.h110
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h6
-rw-r--r--arch/powerpc/include/asm/ptrace.h7
-rw-r--r--arch/powerpc/include/asm/reg.h4
-rw-r--r--arch/powerpc/include/asm/reg_booke.h4
-rw-r--r--arch/powerpc/include/asm/reg_fsl_emb.h2
-rw-r--r--arch/powerpc/include/asm/syscall.h6
-rw-r--r--arch/powerpc/include/asm/syscalls.h4
-rw-r--r--arch/powerpc/include/asm/systbl.h2
-rw-r--r--arch/powerpc/include/asm/unistd.h2
-rw-r--r--arch/powerpc/kernel/Makefile7
-rw-r--r--arch/powerpc/kernel/asm-offsets.c33
-rw-r--r--arch/powerpc/kernel/cacheinfo.c3
-rw-r--r--arch/powerpc/kernel/cputable.c2
-rw-r--r--arch/powerpc/kernel/dma.c1
-rw-r--r--arch/powerpc/kernel/e500-pmu.c129
-rw-r--r--arch/powerpc/kernel/head_64.S17
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S7
-rw-r--r--arch/powerpc/kernel/ibmebus.c1
-rw-r--r--arch/powerpc/kernel/iommu.c7
-rw-r--r--arch/powerpc/kernel/kprobes.c1
-rw-r--r--arch/powerpc/kernel/legacy_serial.c2
-rw-r--r--arch/powerpc/kernel/lparcfg.c1
-rw-r--r--arch/powerpc/kernel/misc.S26
-rw-r--r--arch/powerpc/kernel/of_platform.c1
-rw-r--r--arch/powerpc/kernel/paca.c93
-rw-r--r--arch/powerpc/kernel/pci-common.c16
-rw-r--r--arch/powerpc/kernel/pci_32.c1
-rw-r--r--arch/powerpc/kernel/pci_dn.c1
-rw-r--r--arch/powerpc/kernel/perf_event.c29
-rw-r--r--arch/powerpc/kernel/perf_event_fsl_emb.c654
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c1
-rw-r--r--arch/powerpc/kernel/proc_powerpc.c1
-rw-r--r--arch/powerpc/kernel/prom.c3
-rw-r--r--arch/powerpc/kernel/prom_init.c3
-rw-r--r--arch/powerpc/kernel/ptrace.c12
-rw-r--r--arch/powerpc/kernel/rtas.c1
-rw-r--r--arch/powerpc/kernel/rtas_flash.c1
-rw-r--r--arch/powerpc/kernel/rtasd.c1
-rw-r--r--arch/powerpc/kernel/setup-common.c3
-rw-r--r--arch/powerpc/kernel/setup_32.c6
-rw-r--r--arch/powerpc/kernel/setup_64.c18
-rw-r--r--arch/powerpc/kernel/smp-tbsync.c1
-rw-r--r--arch/powerpc/kernel/softemu8xx.c1
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c1
-rw-r--r--arch/powerpc/kernel/syscalls.c164
-rw-r--r--arch/powerpc/kernel/traps.c1
-rw-r--r--arch/powerpc/kernel/vio.c1
-rw-r--r--arch/powerpc/kvm/44x.c1
-rw-r--r--arch/powerpc/kvm/44x_emulate.c25
-rw-r--r--arch/powerpc/kvm/44x_tlb.c20
-rw-r--r--arch/powerpc/kvm/Kconfig1
-rw-r--r--arch/powerpc/kvm/book3s.c315
-rw-r--r--arch/powerpc/kvm/book3s_64_emulate.c77
-rw-r--r--arch/powerpc/kvm/book3s_64_exports.c8
-rw-r--r--arch/powerpc/kvm/book3s_64_interrupts.S336
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu.c10
-rw-r--r--arch/powerpc/kvm/book3s_64_rmhandlers.S119
-rw-r--r--arch/powerpc/kvm/book3s_64_slb.S160
-rw-r--r--arch/powerpc/kvm/booke.c88
-rw-r--r--arch/powerpc/kvm/booke_emulate.c107
-rw-r--r--arch/powerpc/kvm/e500.c7
-rw-r--r--arch/powerpc/kvm/e500_emulate.c93
-rw-r--r--arch/powerpc/kvm/e500_tlb.c11
-rw-r--r--arch/powerpc/kvm/emulate.c118
-rw-r--r--arch/powerpc/kvm/powerpc.c41
-rw-r--r--arch/powerpc/lib/devres.c1
-rw-r--r--arch/powerpc/mm/dma-noncoherent.c1
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c9
-rw-r--r--arch/powerpc/mm/hugetlbpage.c1
-rw-r--r--arch/powerpc/mm/init_32.c3
-rw-r--r--arch/powerpc/mm/init_64.c1
-rw-r--r--arch/powerpc/mm/mem.c7
-rw-r--r--arch/powerpc/mm/mmu_context_hash64.c1
-rw-r--r--arch/powerpc/mm/mmu_context_nohash.c1
-rw-r--r--arch/powerpc/mm/numa.c23
-rw-r--r--arch/powerpc/mm/pgtable.c1
-rw-r--r--arch/powerpc/mm/pgtable_32.c1
-rw-r--r--arch/powerpc/mm/pgtable_64.c1
-rw-r--r--arch/powerpc/mm/subpage-prot.c1
-rw-r--r--arch/powerpc/oprofile/cell/spu_task_sync.c1
-rw-r--r--arch/powerpc/oprofile/cell/vma_map.c1
-rw-r--r--arch/powerpc/platforms/44x/warp.c1
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpio.c1
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c9
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c2
-rw-r--r--arch/powerpc/platforms/82xx/ep8248e.c1
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c11
-rw-r--r--arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c1
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig4
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c34
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig16
-rw-r--r--arch/powerpc/platforms/86xx/gef_gpio.c11
-rw-r--r--arch/powerpc/platforms/86xx/gef_pic.c20
-rw-r--r--arch/powerpc/platforms/86xx/gef_ppc9a.c12
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc310.c12
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c12
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c1
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype10
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c1
-rw-r--r--arch/powerpc/platforms/cell/celleb_pci.c1
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_pciex.c1
-rw-r--r--arch/powerpc/platforms/cell/iommu.c1
-rw-r--r--arch/powerpc/platforms/cell/ras.c1
-rw-r--r--arch/powerpc/platforms/cell/setup.c1
-rw-r--r--arch/powerpc/platforms/cell/spider-pci.c1
-rw-r--r--arch/powerpc/platforms/cell/spu_manage.c1
-rw-r--r--arch/powerpc/platforms/cell/spu_priv1_mmio.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/lscsa_alloc.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c1
-rw-r--r--arch/powerpc/platforms/chrp/nvram.c1
-rw-r--r--arch/powerpc/platforms/chrp/setup.c1
-rw-r--r--arch/powerpc/platforms/iseries/exception.S25
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c1
-rw-r--r--arch/powerpc/platforms/iseries/mf.c1
-rw-r--r--arch/powerpc/platforms/iseries/pci.c1
-rw-r--r--arch/powerpc/platforms/iseries/vio.c2
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c1
-rw-r--r--arch/powerpc/platforms/maple/setup.c1
-rw-r--r--arch/powerpc/platforms/pasemi/dma_lib.c1
-rw-r--r--arch/powerpc/platforms/pasemi/gpio_mdio.c1
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c1
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c1
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c1
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c1
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c1
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c1
-rw-r--r--arch/powerpc/platforms/powermac/setup.c1
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c1
-rw-r--r--arch/powerpc/platforms/ps3/mm.c1
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c1
-rw-r--r--arch/powerpc/platforms/ps3/spu.c1
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c1
-rw-r--r--arch/powerpc/platforms/pseries/cmm.c1
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c1
-rw-r--r--arch/powerpc/platforms/pseries/dtl.c1
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c1
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c1
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c42
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c7
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c1
-rw-r--r--arch/powerpc/platforms/pseries/offline_states.h23
-rw-r--r--arch/powerpc/platforms/pseries/phyp_dump.c1
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h4
-rw-r--r--arch/powerpc/platforms/pseries/ras.c1
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c1
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c1
-rw-r--r--arch/powerpc/platforms/pseries/setup.c1
-rw-r--r--arch/powerpc/platforms/pseries/xics.c7
-rw-r--r--arch/powerpc/sysdev/cpm1.c15
-rw-r--r--arch/powerpc/sysdev/cpm2.c11
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.h2
-rw-r--r--arch/powerpc/sysdev/cpm_common.c1
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c2
-rw-r--r--arch/powerpc/sysdev/fsl_gtm.c1
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c1
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c1
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c1
-rw-r--r--arch/powerpc/sysdev/mpc8xxx_gpio.c1
-rw-r--r--arch/powerpc/sysdev/mpic.c1
-rw-r--r--arch/powerpc/sysdev/msi_bitmap.c1
-rw-r--r--arch/powerpc/sysdev/of_rtc.c1
-rw-r--r--arch/powerpc/sysdev/pmi.c1
-rw-r--r--arch/powerpc/sysdev/ppc4xx_gpio.c1
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c1
-rw-r--r--arch/powerpc/sysdev/qe_lib/gpio.c1
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c10
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc.c1
-rw-r--r--arch/powerpc/sysdev/simple_gpio.c1
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c1
-rw-r--r--arch/s390/appldata/appldata_mem.c1
-rw-r--r--arch/s390/appldata/appldata_net_sum.c1
-rw-r--r--arch/s390/boot/compressed/misc.c8
-rw-r--r--arch/s390/crypto/prng.c1
-rw-r--r--arch/s390/crypto/sha_common.c2
-rw-r--r--arch/s390/defconfig40
-rw-r--r--arch/s390/hypfs/hypfs_diag.c1
-rw-r--r--arch/s390/hypfs/inode.c2
-rw-r--r--arch/s390/include/asm/cio.h2
-rw-r--r--arch/s390/include/asm/compat.h3
-rw-r--r--arch/s390/include/asm/pgtable.h6
-rw-r--r--arch/s390/include/asm/ptrace.h3
-rw-r--r--arch/s390/include/asm/qdio.h7
-rw-r--r--arch/s390/include/asm/system.h9
-rw-r--r--arch/s390/include/asm/unistd.h1
-rw-r--r--arch/s390/include/asm/vdso.h1
-rw-r--r--arch/s390/kernel/asm-offsets.c1
-rw-r--r--arch/s390/kernel/compat_linux.c2
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/early.c3
-rw-r--r--arch/s390/kernel/entry.S8
-rw-r--r--arch/s390/kernel/entry.h10
-rw-r--r--arch/s390/kernel/entry64.S8
-rw-r--r--arch/s390/kernel/head.S3
-rw-r--r--arch/s390/kernel/head64.S2
-rw-r--r--arch/s390/kernel/ipl.c1
-rw-r--r--arch/s390/kernel/kprobes.c1
-rw-r--r--arch/s390/kernel/process.c2
-rw-r--r--arch/s390/kernel/sclp.S2
-rw-r--r--arch/s390/kernel/setup.c5
-rw-r--r--arch/s390/kernel/smp.c19
-rw-r--r--arch/s390/kernel/swsusp_asm64.S3
-rw-r--r--arch/s390/kernel/sys_s390.c43
-rw-r--r--arch/s390/kernel/syscalls.S6
-rw-r--r--arch/s390/kernel/sysinfo.c1
-rw-r--r--arch/s390/kernel/time.c61
-rw-r--r--arch/s390/kernel/topology.c3
-rw-r--r--arch/s390/kernel/vdso32/clock_gettime.S12
-rw-r--r--arch/s390/kernel/vdso32/gettimeofday.S6
-rw-r--r--arch/s390/kernel/vdso64/clock_gettime.S4
-rw-r--r--arch/s390/kernel/vdso64/gettimeofday.S2
-rw-r--r--arch/s390/kvm/interrupt.c1
-rw-r--r--arch/s390/kvm/kvm-s390.c26
-rw-r--r--arch/s390/kvm/kvm-s390.h10
-rw-r--r--arch/s390/kvm/priv.c1
-rw-r--r--arch/s390/kvm/sigp.c1
-rw-r--r--arch/s390/lib/Makefile3
-rw-r--r--arch/s390/mm/cmm.c3
-rw-r--r--arch/s390/mm/init.c1
-rw-r--r--arch/s390/mm/maccess.c26
-rw-r--r--arch/s390/mm/page-states.c1
-rw-r--r--arch/s390/mm/pgtable.c2
-rw-r--r--arch/s390/mm/vmem.c12
-rw-r--r--arch/score/include/asm/ptrace.h3
-rw-r--r--arch/score/kernel/sys_score.c1
-rw-r--r--arch/score/mm/init.c1
-rw-r--r--arch/sh/Kconfig3
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c2
-rw-r--r--arch/sh/boards/mach-migor/setup.c16
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c8
-rw-r--r--arch/sh/boot/compressed/cache.c2
-rw-r--r--arch/sh/configs/ecovec24_defconfig236
-rw-r--r--arch/sh/drivers/dma/dma-api.c1
-rw-r--r--arch/sh/drivers/dma/dmabrg.c1
-rw-r--r--arch/sh/drivers/heartbeat.c1
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c1
-rw-r--r--arch/sh/drivers/push-switch.c1
-rw-r--r--arch/sh/include/asm/cacheflush.h4
-rw-r--r--arch/sh/include/asm/dma-register.h51
-rw-r--r--arch/sh/include/asm/dma-sh.h88
-rw-r--r--arch/sh/include/asm/dmaengine.h93
-rw-r--r--arch/sh/include/asm/elf.h6
-rw-r--r--arch/sh/include/asm/io.h23
-rw-r--r--arch/sh/include/asm/mmu.h38
-rw-r--r--arch/sh/include/asm/pci.h19
-rw-r--r--arch/sh/include/asm/ptrace.h2
-rw-r--r--arch/sh/include/asm/siu.h2
-rw-r--r--arch/sh/include/asm/syscalls.h5
-rw-r--r--arch/sh/include/asm/topology.h2
-rw-r--r--arch/sh/include/asm/unistd_32.h2
-rw-r--r--arch/sh/include/asm/unistd_64.h2
-rw-r--r--arch/sh/include/cpu-sh3/cpu/dma-register.h41
-rw-r--r--arch/sh/include/cpu-sh3/cpu/dma.h27
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma-register.h112
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma-sh4a.h62
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma.h36
-rw-r--r--arch/sh/include/cpu-sh4/cpu/mmu_context.h4
-rw-r--r--arch/sh/include/cpu-sh4/cpu/watchdog.h6
-rw-r--r--arch/sh/include/mach-migor/mach/migor.h1
-rw-r--r--arch/sh/kernel/cpu/clock.c2
-rw-r--r--arch/sh/kernel/cpu/fpu.c1
-rw-r--r--arch/sh/kernel/cpu/hwblk.c1
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c190
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c186
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c134
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c134
-rw-r--r--arch/sh/kernel/cpufreq.c4
-rw-r--r--arch/sh/kernel/dwarf.c5
-rw-r--r--arch/sh/kernel/hw_breakpoint.c30
-rw-r--r--arch/sh/kernel/idle.c2
-rw-r--r--arch/sh/kernel/kprobes.c1
-rw-r--r--arch/sh/kernel/perf_event.c22
-rw-r--r--arch/sh/kernel/process.c1
-rw-r--r--arch/sh/kernel/process_32.c1
-rw-r--r--arch/sh/kernel/process_64.c8
-rw-r--r--arch/sh/kernel/ptrace_32.c1
-rw-r--r--arch/sh/kernel/return_address.c3
-rw-r--r--arch/sh/kernel/setup.c3
-rw-r--r--arch/sh/kernel/smp.c1
-rw-r--r--arch/sh/kernel/sys_sh.c115
-rw-r--r--arch/sh/kernel/time.c6
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall.c1
-rw-r--r--arch/sh/lib/libgcc.h3
-rw-r--r--arch/sh/mm/consistent.c1
-rw-r--r--arch/sh/mm/hugetlbpage.c1
-rw-r--r--arch/sh/mm/init.c1
-rw-r--r--arch/sh/mm/ioremap.c71
-rw-r--r--arch/sh/mm/ioremap_fixed.c12
-rw-r--r--arch/sh/mm/numa.c3
-rw-r--r--arch/sh/mm/pgtable.c1
-rw-r--r--arch/sh/mm/pmb.c417
-rw-r--r--arch/sh/mm/tlb-pteaex.c30
-rw-r--r--arch/sh/mm/tlb-sh3.c19
-rw-r--r--arch/sh/mm/tlb-sh4.c28
-rw-r--r--arch/sh/mm/tlb-urb.c22
-rw-r--r--arch/sh/mm/tlbflush_32.c19
-rw-r--r--arch/sh/mm/uncached.c9
-rw-r--r--arch/sparc/Kconfig6
-rw-r--r--arch/sparc/Kconfig.debug5
-rw-r--r--arch/sparc/configs/sparc64_defconfig28
-rw-r--r--arch/sparc/include/asm/compat.h3
-rw-r--r--arch/sparc/include/asm/cpudata_64.h2
-rw-r--r--arch/sparc/include/asm/dma-mapping.h14
-rw-r--r--arch/sparc/include/asm/fbio.h2
-rw-r--r--arch/sparc/include/asm/irqflags_64.h23
-rw-r--r--arch/sparc/include/asm/pci_32.h14
-rw-r--r--arch/sparc/include/asm/pci_64.h14
-rw-r--r--arch/sparc/include/asm/stat.h4
-rw-r--r--arch/sparc/include/asm/thread_info_64.h2
-rw-r--r--arch/sparc/include/asm/unistd.h4
-rw-r--r--arch/sparc/kernel/Makefile10
-rw-r--r--arch/sparc/kernel/central.c1
-rw-r--r--arch/sparc/kernel/cpumap.c1
-rw-r--r--arch/sparc/kernel/ftrace.c60
-rw-r--r--arch/sparc/kernel/helpers.S75
-rw-r--r--arch/sparc/kernel/hvapi.c1
-rw-r--r--arch/sparc/kernel/iommu.c11
-rw-r--r--arch/sparc/kernel/ioport.c11
-rw-r--r--arch/sparc/kernel/irq_64.c31
-rw-r--r--arch/sparc/kernel/kgdb_64.c3
-rw-r--r--arch/sparc/kernel/kprobes.c1
-rw-r--r--arch/sparc/kernel/kstack.h19
-rw-r--r--arch/sparc/kernel/led.c1
-rw-r--r--arch/sparc/kernel/leon_kernel.c1
-rw-r--r--arch/sparc/kernel/leon_smp.c1
-rw-r--r--arch/sparc/kernel/module.c2
-rw-r--r--arch/sparc/kernel/nmi.c10
-rw-r--r--arch/sparc/kernel/of_device_common.c1
-rw-r--r--arch/sparc/kernel/pci_common.c11
-rw-r--r--arch/sparc/kernel/pci_msi.c1
-rw-r--r--arch/sparc/kernel/pcr.c3
-rw-r--r--arch/sparc/kernel/perf_event.c6
-rw-r--r--arch/sparc/kernel/process_32.c2
-rw-r--r--arch/sparc/kernel/ptrace_32.c4
-rw-r--r--arch/sparc/kernel/ptrace_64.c4
-rw-r--r--arch/sparc/kernel/rtrap_64.S12
-rw-r--r--arch/sparc/kernel/setup_64.c1
-rw-r--r--arch/sparc/kernel/smp_64.c12
-rw-r--r--arch/sparc/kernel/sun4c_irq.c1
-rw-r--r--arch/sparc/kernel/sun4m_irq.c1
-rw-r--r--arch/sparc/kernel/sys_sparc32.c2
-rw-r--r--arch/sparc/kernel/sys_sparc_32.c113
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c13
-rw-r--r--arch/sparc/kernel/sysfs.c4
-rw-r--r--arch/sparc/kernel/systbls.h5
-rw-r--r--arch/sparc/kernel/systbls_64.S6
-rw-r--r--arch/sparc/kernel/time_64.c4
-rw-r--r--arch/sparc/kernel/traps_64.c27
-rw-r--r--arch/sparc/kernel/unaligned_64.c6
-rw-r--r--arch/sparc/kernel/us2e_cpufreq.c8
-rw-r--r--arch/sparc/kernel/us3_cpufreq.c8
-rw-r--r--arch/sparc/kernel/vio.c1
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S5
-rw-r--r--arch/sparc/lib/mcount.S159
-rw-r--r--arch/sparc/mm/hugetlbpage.c1
-rw-r--r--arch/sparc/mm/init_32.c1
-rw-r--r--arch/sparc/mm/init_64.c4
-rw-r--r--arch/sparc/mm/srmmu.c2
-rw-r--r--arch/sparc/mm/sun4c.c1
-rw-r--r--arch/sparc/mm/tsb.c1
-rw-r--r--arch/um/.gitignore3
-rw-r--r--arch/um/drivers/line.c5
-rw-r--r--arch/um/drivers/net_kern.c1
-rw-r--r--arch/um/drivers/port_kern.c1
-rw-r--r--arch/um/drivers/ubd_kern.c1
-rw-r--r--arch/um/include/asm/dma-mapping.h8
-rw-r--r--arch/um/include/asm/ptrace-generic.h2
-rw-r--r--arch/um/kernel/exec.c1
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/mem.c2
-rw-r--r--arch/um/kernel/process.c2
-rw-r--r--arch/um/kernel/ptrace.c70
-rw-r--r--arch/um/kernel/reboot.c1
-rw-r--r--arch/um/kernel/skas/mmu.c1
-rw-r--r--arch/um/kernel/syscall.c45
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/asm/elf.h43
-rw-r--r--arch/um/sys-i386/elfcore.c83
-rw-r--r--arch/um/sys-i386/ldt.c1
-rw-r--r--arch/um/sys-i386/shared/sysdep/syscalls.h2
-rw-r--r--arch/um/sys-i386/sys_call_table.S2
-rw-r--r--arch/um/sys-i386/syscalls.c137
-rw-r--r--arch/um/sys-x86_64/syscall_table.c5
-rw-r--r--arch/um/sys-x86_64/syscalls.c14
-rw-r--r--arch/x86/Kconfig27
-rw-r--r--arch/x86/crypto/fpu.c1
-rw-r--r--arch/x86/crypto/twofish-i586-asm_32.S10
-rw-r--r--arch/x86/crypto/twofish-x86_64-asm_64.S20
-rw-r--r--arch/x86/ia32/ia32_aout.c1
-rw-r--r--arch/x86/ia32/ia32entry.S8
-rw-r--r--arch/x86/ia32/sys_ia32.c77
-rw-r--r--arch/x86/include/asm/Kbuild1
-rw-r--r--arch/x86/include/asm/alternative.h4
-rw-r--r--arch/x86/include/asm/amd_iommu_types.h3
-rw-r--r--arch/x86/include/asm/apb_timer.h70
-rw-r--r--arch/x86/include/asm/compat.h3
-rw-r--r--arch/x86/include/asm/fixmap.h6
-rw-r--r--arch/x86/include/asm/hw_breakpoint.h1
-rw-r--r--arch/x86/include/asm/hw_irq.h8
-rw-r--r--arch/x86/include/asm/hyperv.h186
-rw-r--r--arch/x86/include/asm/i8259.h19
-rw-r--r--arch/x86/include/asm/io_apic.h7
-rw-r--r--arch/x86/include/asm/irq.h1
-rw-r--r--arch/x86/include/asm/kprobes.h31
-rw-r--r--arch/x86/include/asm/kvm_emulate.h17
-rw-r--r--arch/x86/include/asm/kvm_host.h60
-rw-r--r--arch/x86/include/asm/kvm_para.h1
-rw-r--r--arch/x86/include/asm/lguest_hcall.h29
-rw-r--r--arch/x86/include/asm/mrst.h19
-rw-r--r--arch/x86/include/asm/msr-index.h2
-rw-r--r--arch/x86/include/asm/numaq.h1
-rw-r--r--arch/x86/include/asm/olpc.h20
-rw-r--r--arch/x86/include/asm/pci.h37
-rw-r--r--arch/x86/include/asm/pci_x86.h22
-rw-r--r--arch/x86/include/asm/perf_event.h16
-rw-r--r--arch/x86/include/asm/pgtable_32.h1
-rw-r--r--arch/x86/include/asm/ptrace.h7
-rw-r--r--arch/x86/include/asm/setup.h2
-rw-r--r--arch/x86/include/asm/svm.h2
-rw-r--r--arch/x86/include/asm/sys_ia32.h11
-rw-r--r--arch/x86/include/asm/syscalls.h15
-rw-r--r--arch/x86/include/asm/unistd_32.h4
-rw-r--r--arch/x86/include/asm/unistd_64.h3
-rw-r--r--arch/x86/include/asm/visws/cobalt.h2
-rw-r--r--arch/x86/include/asm/vmx.h5
-rw-r--r--arch/x86/include/asm/x86_init.h15
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/acpi/boot.c105
-rw-r--r--arch/x86/kernel/alternative.c61
-rw-r--r--arch/x86/kernel/amd_iommu.c22
-rw-r--r--arch/x86/kernel/amd_iommu_init.c50
-rw-r--r--arch/x86/kernel/apb_timer.c785
-rw-r--r--arch/x86/kernel/aperture_64.c16
-rw-r--r--arch/x86/kernel/apic/apic.c10
-rw-r--r--arch/x86/kernel/apic/apic_flat_64.c2
-rw-r--r--arch/x86/kernel/apic/es7000_32.c1
-rw-r--r--arch/x86/kernel/apic/io_apic.c95
-rw-r--r--arch/x86/kernel/apic/nmi.c3
-rw-r--r--arch/x86/kernel/apic/numaq_32.c1
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c5
-rw-r--r--arch/x86/kernel/bootflag.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Kconfig14
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Makefile1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/elanfreq.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/gx-suspmod.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longrun.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/p4-clockmod.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c621
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k6.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-lib.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-smi.c1
-rw-r--r--arch/x86/kernel/cpu/intel.c24
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-inject.c1
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c17
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c3
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel.c5
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c1
-rw-r--r--arch/x86/kernel/cpu/mtrr/if.c1
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c1
-rw-r--r--arch/x86/kernel/cpu/perf_event.c269
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd.c142
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c97
-rw-r--r--arch/x86/kernel/cpu/perf_event_p6.c18
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c2
-rw-r--r--arch/x86/kernel/cpu/vmware.c2
-rw-r--r--arch/x86/kernel/cpuid.c1
-rw-r--r--arch/x86/kernel/crash.c6
-rw-r--r--arch/x86/kernel/crash_dump_32.c1
-rw-r--r--arch/x86/kernel/dumpstack.h24
-rw-r--r--arch/x86/kernel/dumpstack_64.c14
-rw-r--r--arch/x86/kernel/e820.c24
-rw-r--r--arch/x86/kernel/head32.c4
-rw-r--r--arch/x86/kernel/head64.c3
-rw-r--r--arch/x86/kernel/head_64.S2
-rw-r--r--arch/x86/kernel/hpet.c10
-rw-r--r--arch/x86/kernel/hw_breakpoint.c12
-rw-r--r--arch/x86/kernel/i387.c1
-rw-r--r--arch/x86/kernel/i8259.c65
-rw-r--r--arch/x86/kernel/irqinit.c32
-rw-r--r--arch/x86/kernel/k8.c16
-rw-r--r--arch/x86/kernel/kdebugfs.c1
-rw-r--r--arch/x86/kernel/kgdb.c2
-rw-r--r--arch/x86/kernel/kprobes.c609
-rw-r--r--arch/x86/kernel/ldt.c1
-rw-r--r--arch/x86/kernel/machine_kexec_64.c1
-rw-r--r--arch/x86/kernel/mca_32.c1
-rw-r--r--arch/x86/kernel/module.c1
-rw-r--r--arch/x86/kernel/mpparse.c4
-rw-r--r--arch/x86/kernel/mrst.c216
-rw-r--r--arch/x86/kernel/msr.c1
-rw-r--r--arch/x86/kernel/olpc.c10
-rw-r--r--arch/x86/kernel/pci-calgary_64.c2
-rw-r--r--arch/x86/kernel/pci-dma.c3
-rw-r--r--arch/x86/kernel/pci-gart_64.c6
-rw-r--r--arch/x86/kernel/pci-nommu.c1
-rw-r--r--arch/x86/kernel/process.c34
-rw-r--r--arch/x86/kernel/process_64.c4
-rw-r--r--arch/x86/kernel/ptrace.c3
-rw-r--r--arch/x86/kernel/setup.c25
-rw-r--r--arch/x86/kernel/smp.c1
-rw-r--r--arch/x86/kernel/smpboot.c16
-rw-r--r--arch/x86/kernel/sys_i386_32.c185
-rw-r--r--arch/x86/kernel/sys_x86_64.c12
-rw-r--r--arch/x86/kernel/syscall_table_32.S4
-rw-r--r--arch/x86/kernel/tlb_uv.c1
-rw-r--r--arch/x86/kernel/tsc.c2
-rw-r--r--arch/x86/kernel/uv_irq.c1
-rw-r--r--arch/x86/kernel/uv_time.c1
-rw-r--r--arch/x86/kernel/visws_quirks.c21
-rw-r--r--arch/x86/kernel/vmi_32.c1
-rw-r--r--arch/x86/kernel/vmiclock_32.c2
-rw-r--r--arch/x86/kernel/vmlinux.lds.S2
-rw-r--r--arch/x86/kernel/vsyscall_64.c3
-rw-r--r--arch/x86/kernel/x86_init.c8
-rw-r--r--arch/x86/kvm/Kconfig1
-rw-r--r--arch/x86/kvm/emulate.c440
-rw-r--r--arch/x86/kvm/i8254.c24
-rw-r--r--arch/x86/kvm/i8254.h2
-rw-r--r--arch/x86/kvm/i8259.c47
-rw-r--r--arch/x86/kvm/irq.h3
-rw-r--r--arch/x86/kvm/kvm_cache_regs.h31
-rw-r--r--arch/x86/kvm/lapic.c32
-rw-r--r--arch/x86/kvm/lapic.h8
-rw-r--r--arch/x86/kvm/mmu.c149
-rw-r--r--arch/x86/kvm/mmu.h35
-rw-r--r--arch/x86/kvm/paging_tmpl.h13
-rw-r--r--arch/x86/kvm/svm.c263
-rw-r--r--arch/x86/kvm/trace.h59
-rw-r--r--arch/x86/kvm/vmx.c421
-rw-r--r--arch/x86/kvm/x86.c1141
-rw-r--r--arch/x86/kvm/x86.h30
-rw-r--r--arch/x86/lguest/boot.c61
-rw-r--r--arch/x86/lguest/i386_head.S2
-rw-r--r--arch/x86/mm/hugetlbpage.c1
-rw-r--r--arch/x86/mm/init.c33
-rw-r--r--arch/x86/mm/init_32.c2
-rw-r--r--arch/x86/mm/init_64.c1
-rw-r--r--arch/x86/mm/kmmio.c1
-rw-r--r--arch/x86/mm/mmio-mod.c1
-rw-r--r--arch/x86/mm/pageattr.c27
-rw-r--r--arch/x86/mm/pat.c2
-rw-r--r--arch/x86/mm/pgtable.c1
-rw-r--r--arch/x86/mm/pgtable_32.c1
-rw-r--r--arch/x86/oprofile/op_model_amd.c23
-rw-r--r--arch/x86/oprofile/op_model_ppro.c6
-rw-r--r--arch/x86/pci/Makefile2
-rw-r--r--arch/x86/pci/acpi.c88
-rw-r--r--arch/x86/pci/common.c7
-rw-r--r--arch/x86/pci/i386.c8
-rw-r--r--arch/x86/pci/init.c8
-rw-r--r--arch/x86/pci/irq.c17
-rw-r--r--arch/x86/pci/legacy.c24
-rw-r--r--arch/x86/pci/mmconfig-shared.c1
-rw-r--r--arch/x86/pci/mrst.c262
-rw-r--r--arch/x86/pci/numaq_32.c6
-rw-r--r--arch/x86/pci/olpc.c3
-rw-r--r--arch/x86/pci/pcbios.c1
-rw-r--r--arch/x86/pci/visws.c6
-rw-r--r--arch/x86/power/hibernate_32.c1
-rw-r--r--arch/x86/power/hibernate_64.c1
-rw-r--r--arch/x86/power/hibernate_asm_32.S15
-rw-r--r--arch/x86/vdso/vma.c1
-rw-r--r--arch/x86/xen/debugfs.c1
-rw-r--r--arch/x86/xen/enlighten.c1
-rw-r--r--arch/x86/xen/mmu.c1
-rw-r--r--arch/x86/xen/smp.c3
-rw-r--r--arch/x86/xen/spinlock.c1
-rw-r--r--arch/x86/xen/time.c1
-rw-r--r--arch/xtensa/include/asm/pci.h8
-rw-r--r--arch/xtensa/include/asm/ptrace.h1
-rw-r--r--arch/xtensa/kernel/entry.S4
-rw-r--r--arch/xtensa/kernel/pci-dma.c1
-rw-r--r--arch/xtensa/kernel/process.c2
-rw-r--r--arch/xtensa/kernel/ptrace.c56
-rw-r--r--arch/xtensa/mm/init.c2
-rw-r--r--arch/xtensa/platforms/iss/console.c1
-rw-r--r--block/Kconfig3
-rw-r--r--block/Kconfig.iosched2
-rw-r--r--block/blk-barrier.c1
-rw-r--r--block/blk-cgroup.c54
-rw-r--r--block/blk-cgroup.h10
-rw-r--r--block/blk-integrity.c3
-rw-r--r--block/blk-ioc.c1
-rw-r--r--block/blk-settings.c12
-rw-r--r--block/blk-sysfs.c28
-rw-r--r--block/blk-tag.c1
-rw-r--r--block/blk-timeout.c12
-rw-r--r--block/bsg.c3
-rw-r--r--block/cfq-iosched.c42
-rw-r--r--block/compat_ioctl.c1
-rw-r--r--block/elevator.c4
-rw-r--r--block/ioctl.c1
-rw-r--r--block/noop-iosched.c1
-rw-r--r--crypto/Kconfig4
-rw-r--r--crypto/ahash.c1
-rw-r--r--crypto/algapi.c1
-rw-r--r--crypto/algboss.c1
-rw-r--r--crypto/async_tx/async_pq.c1
-rw-r--r--crypto/async_tx/raid6test.c1
-rw-r--r--crypto/authenc.c43
-rw-r--r--crypto/hmac.c1
-rw-r--r--crypto/md5.c1
-rw-r--r--crypto/rng.c1
-rw-r--r--crypto/seqiv.c1
-rw-r--r--crypto/tcrypt.c2
-rw-r--r--crypto/xor.c1
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/Makefile4
-rw-r--r--drivers/acpi/ac.c1
-rw-r--r--drivers/acpi/acpi_memhotplug.c1
-rw-r--r--drivers/acpi/acpi_pad.c1
-rw-r--r--drivers/acpi/acpica/evgpe.c19
-rw-r--r--drivers/acpi/acpica/exmutex.c3
-rw-r--r--drivers/acpi/acpica/exprep.c17
-rw-r--r--drivers/acpi/battery.c93
-rw-r--r--drivers/acpi/bus.c11
-rw-r--r--drivers/acpi/button.c1
-rw-r--r--drivers/acpi/container.c1
-rw-r--r--drivers/acpi/debug.c1
-rw-r--r--drivers/acpi/dock.c10
-rw-r--r--drivers/acpi/ec.c69
-rw-r--r--drivers/acpi/event.c1
-rw-r--r--drivers/acpi/glue.c1
-rw-r--r--drivers/acpi/internal.h2
-rw-r--r--drivers/acpi/numa.c6
-rw-r--r--drivers/acpi/osl.c23
-rw-r--r--drivers/acpi/pci_irq.c1
-rw-r--r--drivers/acpi/pci_link.c1
-rw-r--r--drivers/acpi/pci_root.c1
-rw-r--r--drivers/acpi/pci_slot.c1
-rw-r--r--drivers/acpi/power.c1
-rw-r--r--drivers/acpi/power_meter.c1
-rw-r--r--drivers/acpi/proc.c2
-rw-r--r--drivers/acpi/processor_core.c1117
-rw-r--r--drivers/acpi/processor_driver.c979
-rw-r--r--drivers/acpi/processor_idle.c1
-rw-r--r--drivers/acpi/processor_pdc.c209
-rw-r--r--drivers/acpi/processor_perflib.c1
-rw-r--r--drivers/acpi/processor_throttling.c4
-rw-r--r--drivers/acpi/sbs.c6
-rw-r--r--drivers/acpi/sbshc.c1
-rw-r--r--drivers/acpi/scan.c51
-rw-r--r--drivers/acpi/sleep.c19
-rw-r--r--drivers/acpi/system.c3
-rw-r--r--drivers/acpi/thermal.c37
-rw-r--r--drivers/acpi/utils.c46
-rw-r--r--drivers/acpi/video.c105
-rw-r--r--drivers/ata/ahci.c67
-rw-r--r--drivers/ata/ata_piix.c1
-rw-r--r--drivers/ata/libata-acpi.c1
-rw-r--r--drivers/ata/libata-core.c80
-rw-r--r--drivers/ata/libata-eh.c5
-rw-r--r--drivers/ata/libata-pmp.c1
-rw-r--r--drivers/ata/libata-scsi.c1
-rw-r--r--drivers/ata/libata-sff.c48
-rw-r--r--drivers/ata/pata_acpi.c3
-rw-r--r--drivers/ata/pata_at32.c1
-rw-r--r--drivers/ata/pata_at91.c1
-rw-r--r--drivers/ata/pata_atp867x.c1
-rw-r--r--drivers/ata/pata_cmd640.c1
-rw-r--r--drivers/ata/pata_hpt3x3.c2
-rw-r--r--drivers/ata/pata_icside.c1
-rw-r--r--drivers/ata/pata_it821x.c1
-rw-r--r--drivers/ata/pata_macio.c1
-rw-r--r--drivers/ata/pata_mpc52xx.c2
-rw-r--r--drivers/ata/pata_octeon_cf.c1
-rw-r--r--drivers/ata/pata_pcmcia.c7
-rw-r--r--drivers/ata/pata_rb532_cf.c1
-rw-r--r--drivers/ata/pata_rdc.c1
-rw-r--r--drivers/ata/pata_via.c6
-rw-r--r--drivers/ata/pdc_adma.c1
-rw-r--r--drivers/ata/sata_fsl.c1
-rw-r--r--drivers/ata/sata_inic162x.c1
-rw-r--r--drivers/ata/sata_mv.c1
-rw-r--r--drivers/ata/sata_nv.c1
-rw-r--r--drivers/ata/sata_promise.c1
-rw-r--r--drivers/ata/sata_qstor.c1
-rw-r--r--drivers/ata/sata_sil24.c1
-rw-r--r--drivers/ata/sata_sx4.c1
-rw-r--r--drivers/ata/sata_uli.c1
-rw-r--r--drivers/atm/adummy.c1
-rw-r--r--drivers/atm/ambassador.c1
-rw-r--r--drivers/atm/atmtcp.c1
-rw-r--r--drivers/atm/eni.c1
-rw-r--r--drivers/atm/firestream.c1
-rw-r--r--drivers/atm/he.c1
-rw-r--r--drivers/atm/horizon.c1
-rw-r--r--drivers/atm/idt77105.c1
-rw-r--r--drivers/atm/idt77252.c1
-rw-r--r--drivers/atm/iphase.c1
-rw-r--r--drivers/atm/lanai.c8
-rw-r--r--drivers/atm/nicstar.c1
-rw-r--r--drivers/atm/solos-pci.c1
-rw-r--r--drivers/atm/suni.c1
-rw-r--r--drivers/atm/uPD98402.c1
-rw-r--r--drivers/atm/zatm.c1
-rw-r--r--drivers/auxdisplay/cfag12864b.c1
-rw-r--r--drivers/auxdisplay/cfag12864bfb.c3
-rw-r--r--drivers/base/Kconfig51
-rw-r--r--drivers/base/attribute_container.c1
-rw-r--r--drivers/base/bus.c27
-rw-r--r--drivers/base/class.c18
-rw-r--r--drivers/base/core.c52
-rw-r--r--drivers/base/cpu.c106
-rw-r--r--drivers/base/dd.c38
-rw-r--r--drivers/base/devres.c1
-rw-r--r--drivers/base/devtmpfs.c14
-rw-r--r--drivers/base/dma-coherent.c1
-rw-r--r--drivers/base/dma-mapping.c1
-rw-r--r--drivers/base/driver.c1
-rw-r--r--drivers/base/firmware_class.c14
-rw-r--r--drivers/base/memory.c38
-rw-r--r--drivers/base/module.c1
-rw-r--r--drivers/base/node.c89
-rw-r--r--drivers/base/platform.c109
-rw-r--r--drivers/base/power/Makefile1
-rw-r--r--drivers/base/power/generic_ops.c233
-rw-r--r--drivers/base/power/main.c51
-rw-r--r--drivers/base/sys.c18
-rw-r--r--drivers/block/DAC960.c1
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/block/aoe/aoeblk.c1
-rw-r--r--drivers/block/aoe/aoechr.c1
-rw-r--r--drivers/block/aoe/aoecmd.c1
-rw-r--r--drivers/block/aoe/aoedev.c1
-rw-r--r--drivers/block/aoe/aoenet.c1
-rw-r--r--drivers/block/brd.c2
-rw-r--r--drivers/block/cciss.c1
-rw-r--r--drivers/block/drbd/drbd_actlog.c19
-rw-r--r--drivers/block/drbd/drbd_bitmap.c11
-rw-r--r--drivers/block/drbd/drbd_int.h16
-rw-r--r--drivers/block/drbd/drbd_main.c21
-rw-r--r--drivers/block/drbd/drbd_nl.c44
-rw-r--r--drivers/block/drbd/drbd_proc.c1
-rw-r--r--drivers/block/drbd/drbd_receiver.c37
-rw-r--r--drivers/block/drbd/drbd_req.h2
-rw-r--r--drivers/block/drbd/drbd_worker.c18
-rw-r--r--drivers/block/floppy.c1493
-rw-r--r--drivers/block/hd.c1
-rw-r--r--drivers/block/loop.c3
-rw-r--r--drivers/block/mg_disk.c1
-rw-r--r--drivers/block/nbd.c1
-rw-r--r--drivers/block/osdblk.c13
-rw-r--r--drivers/block/paride/pcd.c4
-rw-r--r--drivers/block/paride/pd.c1
-rw-r--r--drivers/block/paride/pf.c4
-rw-r--r--drivers/block/paride/pt.c4
-rw-r--r--drivers/block/pktcdvd.c32
-rw-r--r--drivers/block/ps3disk.c1
-rw-r--r--drivers/block/ps3vram.c1
-rw-r--r--drivers/block/swim.c1
-rw-r--r--drivers/block/ub.c1
-rw-r--r--drivers/block/umem.c2
-rw-r--r--drivers/block/virtio_blk.c6
-rw-r--r--drivers/block/xd.c1
-rw-r--r--drivers/block/xen-blkfront.c1
-rw-r--r--drivers/block/z2ram.c1
-rw-r--r--drivers/bluetooth/btmrvl_debugfs.c1
-rw-r--r--drivers/bluetooth/btmrvl_drv.h1
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c1
-rw-r--r--drivers/char/ChangeLog775
-rw-r--r--drivers/char/agp/Kconfig2
-rw-r--r--drivers/char/agp/amd-k7-agp.c2
-rw-r--r--drivers/char/agp/backend.c1
-rw-r--r--drivers/char/agp/compat_ioctl.c1
-rw-r--r--drivers/char/agp/generic.c1
-rw-r--r--drivers/char/agp/hp-agp.c1
-rw-r--r--drivers/char/agp/intel-agp.c40
-rw-r--r--drivers/char/agp/nvidia-agp.c1
-rw-r--r--drivers/char/agp/sgi-agp.c1
-rw-r--r--drivers/char/agp/uninorth-agp.c1
-rw-r--r--drivers/char/amiserial.c4
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/bfin_jtag_comm.c1
-rw-r--r--drivers/char/briq_panel.c1
-rw-r--r--drivers/char/bsr.c1
-rw-r--r--drivers/char/cyclades.c1
-rw-r--r--drivers/char/dsp56k.c1
-rw-r--r--drivers/char/epca.c1
-rw-r--r--drivers/char/generic_serial.c1
-rw-r--r--drivers/char/hpet.c5
-rw-r--r--drivers/char/hvc_console.c28
-rw-r--r--drivers/char/hvc_iseries.c2
-rw-r--r--drivers/char/hvc_iucv.c7
-rw-r--r--drivers/char/hvcs.c1
-rw-r--r--drivers/char/hw_random/intel-rng.c1
-rw-r--r--drivers/char/hw_random/n2-drv.c2
-rw-r--r--drivers/char/hw_random/octeon-rng.c1
-rw-r--r--drivers/char/hw_random/tx4939-rng.c1
-rw-r--r--drivers/char/ip2/i2hw.h2
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c10
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c71
-rw-r--r--drivers/char/isicom.c10
-rw-r--r--drivers/char/istallion.c2
-rw-r--r--drivers/char/mbcs.c1
-rw-r--r--drivers/char/mem.c197
-rw-r--r--drivers/char/misc.c2
-rw-r--r--drivers/char/mmtimer.c3
-rw-r--r--drivers/char/moxa.c1
-rw-r--r--drivers/char/mxser.c11
-rw-r--r--drivers/char/n_tty.c17
-rw-r--r--drivers/char/nozomi.c1
-rw-r--r--drivers/char/nvram.c1
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c8
-rw-r--r--drivers/char/pcmcia/ipwireless/network.c1
-rw-r--r--drivers/char/ppdev.c1
-rw-r--r--drivers/char/ps3flash.c1
-rw-r--r--drivers/char/pty.c3
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/raw.c2
-rw-r--r--drivers/char/rio/rioinit.c1
-rw-r--r--drivers/char/rio/riointr.c1
-rw-r--r--drivers/char/rio/rioparam.c1
-rw-r--r--drivers/char/rio/rioroute.c1
-rw-r--r--drivers/char/rio/riotty.c1
-rw-r--r--drivers/char/riscom8.c1
-rw-r--r--drivers/char/serial167.c3
-rw-r--r--drivers/char/snsc_event.c1
-rw-r--r--drivers/char/sonypi.c1
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/stallion.c7
-rw-r--r--drivers/char/sysrq.c1
-rw-r--r--drivers/char/tpm/tpm.c1
-rw-r--r--drivers/char/tpm/tpm_bios.c1
-rw-r--r--drivers/char/tpm/tpm_nsc.c1
-rw-r--r--drivers/char/tpm/tpm_tis.c1
-rw-r--r--drivers/char/tty_audit.c2
-rw-r--r--drivers/char/tty_buffer.c4
-rw-r--r--drivers/char/tty_io.c4
-rw-r--r--drivers/char/tty_port.c2
-rw-r--r--drivers/char/viotape.c1
-rw-r--r--drivers/char/virtio_console.c110
-rw-r--r--drivers/char/vme_scc.c1
-rw-r--r--drivers/char/vt.c6
-rw-r--r--drivers/char/vt_ioctl.c39
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c1
-rw-r--r--drivers/clocksource/Kconfig9
-rw-r--r--drivers/clocksource/sh_cmt.c1
-rw-r--r--drivers/clocksource/sh_mtu2.c1
-rw-r--r--drivers/clocksource/sh_tmu.c1
-rw-r--r--drivers/connector/cn_proc.c1
-rw-r--r--drivers/connector/connector.c1
-rw-r--r--drivers/cpufreq/cpufreq.c21
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c8
-rw-r--r--drivers/cpufreq/cpufreq_stats.c1
-rw-r--r--drivers/cpuidle/governors/menu.c2
-rw-r--r--drivers/cpuidle/sysfs.c9
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.c1
-rw-r--r--drivers/crypto/hifn_795x.c2
-rw-r--r--drivers/crypto/ixp4xx_crypto.c1
-rw-r--r--drivers/crypto/mv_cesa.c1
-rw-r--r--drivers/crypto/padlock-aes.c1
-rw-r--r--drivers/crypto/talitos.c1
-rw-r--r--drivers/dca/dca-core.c1
-rw-r--r--drivers/dca/dca-sysfs.c1
-rw-r--r--drivers/dma/at_hdmac.c1
-rw-r--r--drivers/dma/coh901318_lli.c1
-rw-r--r--drivers/dma/coh901318_lli.h2
-rw-r--r--drivers/dma/dmaengine.c1
-rw-r--r--drivers/dma/dmatest.c1
-rw-r--r--drivers/dma/fsldma.c1
-rw-r--r--drivers/dma/ioat/dma.c5
-rw-r--r--drivers/dma/ioat/dma.h2
-rw-r--r--drivers/dma/ioat/dma_v2.c1
-rw-r--r--drivers/dma/ioat/dma_v3.c1
-rw-r--r--drivers/dma/ioat/pci.c1
-rw-r--r--drivers/dma/iop-adma.c1
-rw-r--r--drivers/dma/iovlock.c1
-rw-r--r--drivers/dma/mpc512x_dma.c1
-rw-r--r--drivers/dma/mv_xor.c1
-rw-r--r--drivers/dma/ppc4xx/adma.c1
-rw-r--r--drivers/dma/shdma.c501
-rw-r--r--drivers/dma/shdma.h26
-rw-r--r--drivers/edac/amd76x_edac.c1
-rw-r--r--drivers/edac/cpc925_edac.c1
-rw-r--r--drivers/edac/e752x_edac.c118
-rw-r--r--drivers/edac/e7xxx_edac.c1
-rw-r--r--drivers/edac/edac_device_sysfs.c7
-rw-r--r--drivers/edac/edac_mc_sysfs.c5
-rw-r--r--drivers/edac/edac_mce_amd.c12
-rw-r--r--drivers/edac/edac_pci_sysfs.c5
-rw-r--r--drivers/edac/i3000_edac.c1
-rw-r--r--drivers/edac/i3200_edac.c1
-rw-r--r--drivers/edac/i5100_edac.c1
-rw-r--r--drivers/edac/i82443bxgx_edac.c1
-rw-r--r--drivers/edac/i82860_edac.c1
-rw-r--r--drivers/edac/i82875p_edac.c1
-rw-r--r--drivers/edac/i82975x_edac.c1
-rw-r--r--drivers/edac/mpc85xx_edac.c165
-rw-r--r--drivers/edac/mpc85xx_edac.h3
-rw-r--r--drivers/edac/mv64x60_edac.c2
-rw-r--r--drivers/edac/pasemi_edac.c1
-rw-r--r--drivers/edac/r82600_edac.c1
-rw-r--r--drivers/edac/x38_edac.c1
-rw-r--r--drivers/eisa/eisa-bus.c240
-rw-r--r--drivers/firewire/core-cdev.c24
-rw-r--r--drivers/firewire/core-device.c109
-rw-r--r--drivers/firewire/core-iso.c20
-rw-r--r--drivers/firewire/net.c1
-rw-r--r--drivers/firewire/ohci.c29
-rw-r--r--drivers/firmware/dcdbas.c1
-rw-r--r--drivers/firmware/dell_rbu.c1
-rw-r--r--drivers/firmware/dmi-id.c1
-rw-r--r--drivers/firmware/dmi_scan.c1
-rw-r--r--drivers/firmware/edd.c2
-rw-r--r--drivers/firmware/efivars.c3
-rw-r--r--drivers/firmware/iscsi_ibft.c2
-rw-r--r--drivers/firmware/iscsi_ibft_find.c12
-rw-r--r--drivers/firmware/memmap.c60
-rw-r--r--drivers/gpio/Kconfig57
-rw-r--r--drivers/gpio/Makefile6
-rw-r--r--drivers/gpio/adp5520-gpio.c1
-rw-r--r--drivers/gpio/adp5588-gpio.c1
-rw-r--r--drivers/gpio/bt8xxgpio.c1
-rw-r--r--drivers/gpio/cs5535-gpio.c4
-rw-r--r--drivers/gpio/gpiolib.c70
-rw-r--r--drivers/gpio/it8761e_gpio.c231
-rw-r--r--drivers/gpio/langwell_gpio.c1
-rw-r--r--drivers/gpio/max7300.c95
-rw-r--r--drivers/gpio/max7301.c294
-rw-r--r--drivers/gpio/max730x.c249
-rw-r--r--drivers/gpio/mc33880.c1
-rw-r--r--drivers/gpio/mcp23s08.c1
-rw-r--r--drivers/gpio/pca953x.c262
-rw-r--r--drivers/gpio/pl061.c17
-rw-r--r--drivers/gpio/sch_gpio.c295
-rw-r--r--drivers/gpio/timbgpio.c44
-rw-r--r--drivers/gpio/twl4030-gpio.c1
-rw-r--r--drivers/gpio/wm831x-gpio.c46
-rw-r--r--drivers/gpio/wm8350-gpiolib.c182
-rw-r--r--drivers/gpio/wm8994-gpio.c205
-rw-r--r--drivers/gpio/xilinx_gpio.c1
-rw-r--r--drivers/gpu/drm/drm_agpsupport.c1
-rw-r--r--drivers/gpu/drm/drm_bufs.c1
-rw-r--r--drivers/gpu/drm/drm_crtc.c1
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c1
-rw-r--r--drivers/gpu/drm/drm_debugfs.c1
-rw-r--r--drivers/gpu/drm/drm_dp_i2c_helper.c1
-rw-r--r--drivers/gpu/drm/drm_drv.c1
-rw-r--r--drivers/gpu/drm/drm_edid.c12
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c3
-rw-r--r--drivers/gpu/drm/drm_fops.c17
-rw-r--r--drivers/gpu/drm/drm_hashtab.c1
-rw-r--r--drivers/gpu/drm/drm_irq.c2
-rw-r--r--drivers/gpu/drm/drm_pci.c1
-rw-r--r--drivers/gpu/drm/drm_proc.c1
-rw-r--r--drivers/gpu/drm/drm_scatter.c1
-rw-r--r--drivers/gpu/drm/drm_stub.c5
-rw-r--r--drivers/gpu/drm/drm_sysfs.c19
-rw-r--r--drivers/gpu/drm/drm_vm.c1
-rw-r--r--drivers/gpu/drm/i810/i810_dma.c1
-rw-r--r--drivers/gpu/drm/i830/i830_dma.c1
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c3
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c61
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c15
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h18
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c315
-rw-r--r--drivers/gpu/drm/i915/i915_gem_debug.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c39
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c17
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c54
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h27
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c5
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c69
-rw-r--r--drivers/gpu/drm/i915/intel_display.c124
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c257
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h18
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c93
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c3
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c87
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c1
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c134
-rw-r--r--drivers/gpu/drm/i915/intel_modes.c23
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c19
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c732
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c96
-rw-r--r--drivers/gpu/drm/nouveau/Makefile4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_backlight.c12
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c157
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c67
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_debugfs.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h46
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c55
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_grctx.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c610
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c124
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sgdma.c19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c20
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c6
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fbcon.c6
-rw-r--r--drivers/gpu/drm/nouveau/nv40_fifo.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv40_graph.c21
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c26
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fb.c32
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fbcon.c15
-rw-r--r--drivers/gpu/drm/nouveau/nv50_gpio.c76
-rw-r--r--drivers/gpu/drm/nouveau/nv50_graph.c29
-rw-r--r--drivers/gpu/drm/nouveau/nv50_grctx.c32
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c16
-rw-r--r--drivers/gpu/drm/nouveau/nv50_sor.c25
-rw-r--r--drivers/gpu/drm/r128/r128_cce.c1
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/atom.c105
-rw-r--r--drivers/gpu/drm/radeon/atom.h8
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c100
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c6
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c12
-rw-r--r--drivers/gpu/drm/radeon/r100.c47
-rw-r--r--drivers/gpu/drm/radeon/r100_track.h1
-rw-r--r--drivers/gpu/drm/radeon/r200.c1
-rw-r--r--drivers/gpu/drm/radeon/r300.c27
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c2
-rw-r--r--drivers/gpu/drm/radeon/r420.c9
-rw-r--r--drivers/gpu/drm/radeon/r520.c9
-rw-r--r--drivers/gpu/drm/radeon/r600.c31
-rw-r--r--drivers/gpu/drm/radeon/r600_audio.c54
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_shaders.c35
-rw-r--r--drivers/gpu/drm/radeon/r600_cp.c3
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c70
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c200
-rw-r--r--drivers/gpu/drm/radeon/r600_reg.h10
-rw-r--r--drivers/gpu/drm/radeon/r600d.h49
-rw-r--r--drivers/gpu/drm/radeon/radeon.h66
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c772
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h545
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c468
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c27
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c17
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c17
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c11
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c291
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c76
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c156
-rw-r--r--drivers/gpu/drm/radeon/radeon_family.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c153
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c58
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_tv.c29
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c46
-rw-r--r--drivers/gpu/drm/radeon/radeon_reg.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_state.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c1
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r3002
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r4202
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r60075
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/rs6002
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/rv5153
-rw-r--r--drivers/gpu/drm/radeon/rs400.c8
-rw-r--r--drivers/gpu/drm/radeon/rs600.c35
-rw-r--r--drivers/gpu/drm/radeon/rs600d.h53
-rw-r--r--drivers/gpu/drm/radeon/rs690.c122
-rw-r--r--drivers/gpu/drm/radeon/rs690d.h3
-rw-r--r--drivers/gpu/drm/radeon/rv515.c46
-rw-r--r--drivers/gpu/drm/radeon/rv770.c32
-rw-r--r--drivers/gpu/drm/ttm/ttm_agp_backend.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_memory.c21
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c24
-rw-r--r--drivers/gpu/drm/via/via_dmablit.c1
-rw-r--r--drivers/gpu/drm/via/via_irq.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/Kconfig2
-rw-r--r--drivers/gpu/vga/vgaarb.c1
-rw-r--r--drivers/hid/hid-3m-pct.c1
-rw-r--r--drivers/hid/hid-a4tech.c1
-rw-r--r--drivers/hid/hid-apple.c1
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-debug.c7
-rw-r--r--drivers/hid/hid-drff.c1
-rw-r--r--drivers/hid/hid-gaff.c1
-rw-r--r--drivers/hid/hid-gyration.c5
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-input.c24
-rw-r--r--drivers/hid/hid-lg2ff.c1
-rw-r--r--drivers/hid/hid-magicmouse.c8
-rw-r--r--drivers/hid/hid-mosart.c1
-rw-r--r--drivers/hid/hid-ntrig.c12
-rw-r--r--drivers/hid/hid-pl.c1
-rw-r--r--drivers/hid/hid-quanta.c1
-rw-r--r--drivers/hid/hid-sjoy.c1
-rw-r--r--drivers/hid/hid-sony.c1
-rw-r--r--drivers/hid/hid-stantum.c1
-rw-r--r--drivers/hid/hid-tmff.c3
-rw-r--r--drivers/hid/hid-wacom.c1
-rw-r--r--drivers/hid/hid-zpff.c1
-rw-r--r--drivers/hid/hidraw.c1
-rw-r--r--drivers/hid/usbhid/hid-pidff.c1
-rw-r--r--drivers/hid/usbhid/hid-quirks.c3
-rw-r--r--drivers/hwmon/Kconfig45
-rw-r--r--drivers/hwmon/Makefile3
-rw-r--r--drivers/hwmon/ad7414.c1
-rw-r--r--drivers/hwmon/ad7418.c1
-rw-r--r--drivers/hwmon/adcxx.c16
-rw-r--r--drivers/hwmon/adt7411.c367
-rw-r--r--drivers/hwmon/adt7462.c1
-rw-r--r--drivers/hwmon/adt7470.c1
-rw-r--r--drivers/hwmon/adt7473.c1180
-rw-r--r--drivers/hwmon/applesmc.c18
-rw-r--r--drivers/hwmon/asc7621.c1255
-rw-r--r--drivers/hwmon/asus_atk0110.c5
-rw-r--r--drivers/hwmon/atxp1.c1
-rw-r--r--drivers/hwmon/coretemp.c4
-rw-r--r--drivers/hwmon/f75375s.c1
-rw-r--r--drivers/hwmon/fschmd.c15
-rw-r--r--drivers/hwmon/g760a.c2
-rw-r--r--drivers/hwmon/hp_accel.c4
-rw-r--r--drivers/hwmon/i5k_amb.c1
-rw-r--r--drivers/hwmon/ibmaem.c1
-rw-r--r--drivers/hwmon/ibmpex.c1
-rw-r--r--drivers/hwmon/it87.c965
-rw-r--r--drivers/hwmon/lm70.c1
-rw-r--r--drivers/hwmon/lm73.c1
-rw-r--r--drivers/hwmon/lm90.c89
-rw-r--r--drivers/hwmon/max1111.c1
-rw-r--r--drivers/hwmon/mc13783-adc.c1
-rw-r--r--drivers/hwmon/sht15.c14
-rw-r--r--drivers/hwmon/tmp401.c7
-rw-r--r--drivers/hwmon/tmp421.c24
-rw-r--r--drivers/hwmon/vt8231.c3
-rw-r--r--drivers/hwmon/w83793.c482
-rw-r--r--drivers/hwmon/wm831x-hwmon.c1
-rw-r--r--drivers/i2c/Kconfig9
-rw-r--r--drivers/i2c/Makefile2
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c10
-rw-r--r--drivers/i2c/algos/i2c-algo-pcf.c3
-rw-r--r--drivers/i2c/busses/Kconfig26
-rw-r--r--drivers/i2c/busses/Makefile2
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c1
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c1
-rw-r--r--drivers/i2c/busses/i2c-davinci.c1
-rw-r--r--drivers/i2c/busses/i2c-designware.c5
-rw-r--r--drivers/i2c/busses/i2c-elektor.c1
-rw-r--r--drivers/i2c/busses/i2c-gpio.c1
-rw-r--r--drivers/i2c/busses/i2c-highlander.c1
-rw-r--r--drivers/i2c/busses/i2c-i801.c6
-rw-r--r--drivers/i2c/busses/i2c-imx.c8
-rw-r--r--drivers/i2c/busses/i2c-isch.c68
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c1
-rw-r--r--drivers/i2c/busses/i2c-mpc.c195
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c1
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c1
-rw-r--r--drivers/i2c/busses/i2c-nomadik.c960
-rw-r--r--drivers/i2c/busses/i2c-ocores.c1
-rw-r--r--drivers/i2c/busses/i2c-octeon.c1
-rw-r--r--drivers/i2c/busses/i2c-omap.c47
-rw-r--r--drivers/i2c/busses/i2c-parport.c1
-rw-r--r--drivers/i2c/busses/i2c-pasemi.c1
-rw-r--r--drivers/i2c/busses/i2c-pnx.c10
-rw-r--r--drivers/i2c/busses/i2c-powermac.c25
-rw-r--r--drivers/i2c/busses/i2c-pxa.c3
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c1
-rw-r--r--drivers/i2c/busses/i2c-scmi.c32
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c1
-rw-r--r--drivers/i2c/busses/i2c-simtec.c1
-rw-r--r--drivers/i2c/busses/i2c-stu300.c3
-rw-r--r--drivers/i2c/busses/i2c-tiny-usb.c1
-rw-r--r--drivers/i2c/busses/i2c-versatile.c1
-rw-r--r--drivers/i2c/busses/i2c-xiic.c826
-rw-r--r--drivers/i2c/busses/scx200_acb.c1
-rw-r--r--drivers/i2c/chips/Kconfig19
-rw-r--r--drivers/i2c/chips/Makefile18
-rw-r--r--drivers/i2c/chips/tsl2550.c473
-rw-r--r--drivers/i2c/i2c-boardinfo.c1
-rw-r--r--drivers/i2c/i2c-smbus.c6
-rw-r--r--drivers/ide/hpt366.c1
-rw-r--r--drivers/ide/ide-acpi.c1
-rw-r--r--drivers/ide/ide-atapi.c3
-rw-r--r--drivers/ide/ide-cd_ioctl.c1
-rw-r--r--drivers/ide/ide-cs.c4
-rw-r--r--drivers/ide/ide-devsets.c1
-rw-r--r--drivers/ide/ide-disk_proc.c1
-rw-r--r--drivers/ide/ide-dma.c2
-rw-r--r--drivers/ide/ide-floppy.c1
-rw-r--r--drivers/ide/ide-gd.c1
-rw-r--r--drivers/ide/ide-io.c2
-rw-r--r--drivers/ide/ide-ioctls.c1
-rw-r--r--drivers/ide/ide-park.c1
-rw-r--r--drivers/ide/ide-pm.c1
-rw-r--r--drivers/ide/ide-probe.c12
-rw-r--r--drivers/ide/ide-proc.c1
-rw-r--r--drivers/ide/ide-taskfile.c6
-rw-r--r--drivers/ide/ide.c1
-rw-r--r--drivers/ide/it821x.c1
-rw-r--r--drivers/ide/pmac.c1
-rw-r--r--drivers/ide/rapide.c1
-rw-r--r--drivers/ide/sc1200.c1
-rw-r--r--drivers/ide/via82cxxx.c58
-rw-r--r--drivers/idle/i7300_idle.c1
-rw-r--r--drivers/ieee1394/dma.c1
-rw-r--r--drivers/ieee1394/nodemgr.c5
-rw-r--r--drivers/ieee1394/pcilynx.c2
-rw-r--r--drivers/ieee1394/sbp2.c1
-rw-r--r--drivers/infiniband/core/addr.c1
-rw-r--r--drivers/infiniband/core/cm.c5
-rw-r--r--drivers/infiniband/core/cma.c2
-rw-r--r--drivers/infiniband/core/iwcm.c1
-rw-r--r--drivers/infiniband/core/mad.c25
-rw-r--r--drivers/infiniband/core/mad_rmpp.c2
-rw-r--r--drivers/infiniband/core/multicast.c1
-rw-r--r--drivers/infiniband/core/sysfs.c3
-rw-r--r--drivers/infiniband/core/ucm.c14
-rw-r--r--drivers/infiniband/core/ucma.c1
-rw-r--r--drivers/infiniband/core/umem.c1
-rw-r--r--drivers/infiniband/core/user_mad.c10
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c1
-rw-r--r--drivers/infiniband/core/uverbs_main.c10
-rw-r--r--drivers/infiniband/hw/amso1100/c2.c1
-rw-r--r--drivers/infiniband/hw/amso1100/c2_alloc.c1
-rw-r--r--drivers/infiniband/hw/amso1100/c2_cm.c2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_cq.c2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_mm.c2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_pd.c1
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c1
-rw-r--r--drivers/infiniband/hw/amso1100/c2_qp.c1
-rw-r--r--drivers/infiniband/hw/amso1100/c2_rnic.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_dbg.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.c2
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_ev.c2
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_mem.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_av.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_pd.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qes.h4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_uverbs.c2
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_cq.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_dma.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mmap.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mr.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_sdma.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_srq.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_pages.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs_mcast.c1
-rw-r--r--drivers/infiniband/hw/mlx4/ah.c2
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c1
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c1
-rw-r--r--drivers/infiniband/hw/mlx4/main.c1
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c4
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c1
-rw-r--r--drivers/infiniband/hw/mlx4/srq.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mcg.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c1
-rw-r--r--drivers/infiniband/hw/nes/nes.c1
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c1
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c9
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h1
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c31
-rw-r--r--drivers/infiniband/hw/nes/nes_utils.c1
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c11
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c11
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c10
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c1
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c3
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c1
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/input/ff-core.c1
-rw-r--r--drivers/input/ff-memless.c1
-rw-r--r--drivers/input/gameport/lightning.c1
-rw-r--r--drivers/input/input-polldev.c1
-rw-r--r--drivers/input/input.c46
-rw-r--r--drivers/input/joystick/db9.c1
-rw-r--r--drivers/input/joystick/gamecon.c3
-rw-r--r--drivers/input/joystick/turbografx.c1
-rw-r--r--drivers/input/keyboard/adp5520-keys.c1
-rw-r--r--drivers/input/keyboard/adp5588-keys.c1
-rw-r--r--drivers/input/keyboard/bf54x-keys.c3
-rw-r--r--drivers/input/keyboard/davinci_keyscan.c1
-rw-r--r--drivers/input/keyboard/ep93xx_keypad.c1
-rw-r--r--drivers/input/keyboard/gpio_keys.c1
-rw-r--r--drivers/input/keyboard/imx_keypad.c1
-rw-r--r--drivers/input/keyboard/jornada680_kbd.c1
-rw-r--r--drivers/input/keyboard/jornada720_kbd.c1
-rw-r--r--drivers/input/keyboard/lm8323.c1
-rw-r--r--drivers/input/keyboard/locomokbd.c32
-rw-r--r--drivers/input/keyboard/matrix_keypad.c5
-rw-r--r--drivers/input/keyboard/max7359_keypad.c1
-rw-r--r--drivers/input/keyboard/omap-keypad.c1
-rw-r--r--drivers/input/keyboard/opencores-kbd.c1
-rw-r--r--drivers/input/keyboard/pxa27x_keypad.c1
-rw-r--r--drivers/input/keyboard/pxa930_rotary.c1
-rw-r--r--drivers/input/keyboard/sh_keysc.c1
-rw-r--r--drivers/input/keyboard/tosakbd.c1
-rw-r--r--drivers/input/keyboard/twl4030_keypad.c1
-rw-r--r--drivers/input/keyboard/w90p910_keypad.c1
-rw-r--r--drivers/input/misc/88pm860x_onkey.c156
-rw-r--r--drivers/input/misc/Kconfig21
-rw-r--r--drivers/input/misc/Makefile2
-rw-r--r--drivers/input/misc/ati_remote2.c15
-rw-r--r--drivers/input/misc/bfin_rotary.c1
-rw-r--r--drivers/input/misc/cobalt_btns.c1
-rw-r--r--drivers/input/misc/dm355evm_keys.c1
-rw-r--r--drivers/input/misc/pcap_keys.c1
-rw-r--r--drivers/input/misc/pcf50633-input.c1
-rw-r--r--drivers/input/misc/rotary_encoder.c1
-rw-r--r--drivers/input/misc/sgi_btns.c1
-rw-r--r--drivers/input/misc/sparcspkr.c1
-rw-r--r--drivers/input/misc/twl4030-vibra.c298
-rw-r--r--drivers/input/misc/winbond-cir.c13
-rw-r--r--drivers/input/misc/wistron_btns.c1
-rw-r--r--drivers/input/misc/wm831x-on.c10
-rw-r--r--drivers/input/misc/yealink.h2
-rw-r--r--drivers/input/mouse/alps.c51
-rw-r--r--drivers/input/mouse/appletouch.c6
-rw-r--r--drivers/input/mouse/bcm5974.c1
-rw-r--r--drivers/input/mouse/elantech.c1
-rw-r--r--drivers/input/mouse/hgpk.c1
-rw-r--r--drivers/input/mouse/lifebook.c1
-rw-r--r--drivers/input/mouse/pxa930_trkball.c1
-rw-r--r--drivers/input/mouse/sentelic.c1
-rw-r--r--drivers/input/mouse/synaptics.c1
-rw-r--r--drivers/input/mouse/synaptics_i2c.c1
-rw-r--r--drivers/input/mouse/touchkit_ps2.c1
-rw-r--r--drivers/input/mouse/trackpoint.c1
-rw-r--r--drivers/input/mousedev.c6
-rw-r--r--drivers/input/serio/altera_ps2.c1
-rw-r--r--drivers/input/serio/at32psif.c1
-rw-r--r--drivers/input/serio/ct82c710.c1
-rw-r--r--drivers/input/serio/gscps2.c1
-rw-r--r--drivers/input/serio/hil_mlc.c1
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h10
-rw-r--r--drivers/input/serio/i8042.c29
-rw-r--r--drivers/input/serio/libps2.c1
-rw-r--r--drivers/input/serio/parkbd.c1
-rw-r--r--drivers/input/serio/pcips2.c1
-rw-r--r--drivers/input/serio/q40kbd.c1
-rw-r--r--drivers/input/serio/rpckbd.c1
-rw-r--r--drivers/input/serio/serio_raw.c11
-rw-r--r--drivers/input/serio/xilinx_ps2.c1
-rw-r--r--drivers/input/sparse-keymap.c59
-rw-r--r--drivers/input/tablet/aiptek.c2
-rw-r--r--drivers/input/tablet/wacom_sys.c16
-rw-r--r--drivers/input/tablet/wacom_wac.c2
-rw-r--r--drivers/input/tablet/wacom_wac.h1
-rw-r--r--drivers/input/touchscreen/88pm860x-ts.c237
-rw-r--r--drivers/input/touchscreen/Kconfig21
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ad7877.c2
-rw-r--r--drivers/input/touchscreen/ads7846.c20
-rw-r--r--drivers/input/touchscreen/atmel-wm97xx.c1
-rw-r--r--drivers/input/touchscreen/da9034-ts.c1
-rw-r--r--drivers/input/touchscreen/eeti_ts.c1
-rw-r--r--drivers/input/touchscreen/jornada720_ts.c1
-rw-r--r--drivers/input/touchscreen/mc13783_ts.c5
-rw-r--r--drivers/input/touchscreen/mcs5000_ts.c1
-rw-r--r--drivers/input/touchscreen/migor_ts.c1
-rw-r--r--drivers/input/touchscreen/pcap_ts.c1
-rw-r--r--drivers/input/touchscreen/s3c2410_ts.c1
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c1
-rw-r--r--drivers/input/touchscreen/w90p910_ts.c1
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c1
-rw-r--r--drivers/input/xen-kbdfront.c1
-rw-r--r--drivers/isdn/act2000/module.c1
-rw-r--r--drivers/isdn/capi/capifs.c1
-rw-r--r--drivers/isdn/capi/capilib.c1
-rw-r--r--drivers/isdn/capi/capiutil.c1
-rw-r--r--drivers/isdn/capi/kcapi.c1
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c1
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c5
-rw-r--r--drivers/isdn/gigaset/capi.c47
-rw-r--r--drivers/isdn/gigaset/common.c7
-rw-r--r--drivers/isdn/gigaset/dummyll.c14
-rw-r--r--drivers/isdn/gigaset/ev-layer.c12
-rw-r--r--drivers/isdn/gigaset/gigaset.h10
-rw-r--r--drivers/isdn/gigaset/i4l.c28
-rw-r--r--drivers/isdn/gigaset/interface.c2
-rw-r--r--drivers/isdn/gigaset/proc.c1
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c2
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c4
-rw-r--r--drivers/isdn/hardware/avm/b1.c1
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c1
-rw-r--r--drivers/isdn/hardware/avm/c4.c1
-rw-r--r--drivers/isdn/hardware/avm/t1isa.c1
-rw-r--r--drivers/isdn/hardware/eicon/capimain.c1
-rw-r--r--drivers/isdn/hardware/eicon/message.c35
-rw-r--r--drivers/isdn/hardware/mISDN/avmfritz.c1
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c7
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c1
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c1
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNinfineon.c1
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNipac.c1
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNisar.c5
-rw-r--r--drivers/isdn/hardware/mISDN/netjet.c1
-rw-r--r--drivers/isdn/hardware/mISDN/speedfax.c1
-rw-r--r--drivers/isdn/hardware/mISDN/w6692.c1
-rw-r--r--drivers/isdn/hisax/amd7930_fn.c1
-rw-r--r--drivers/isdn/hisax/avm_pci.c1
-rw-r--r--drivers/isdn/hisax/avma1_cs.c12
-rw-r--r--drivers/isdn/hisax/callc.c1
-rw-r--r--drivers/isdn/hisax/config.c1
-rw-r--r--drivers/isdn/hisax/elsa.c1
-rw-r--r--drivers/isdn/hisax/elsa_cs.c12
-rw-r--r--drivers/isdn/hisax/elsa_ser.c1
-rw-r--r--drivers/isdn/hisax/fsm.c1
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c1
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c1
-rw-r--r--drivers/isdn/hisax/hfc_2bs0.c1
-rw-r--r--drivers/isdn/hisax/hfc_sx.c1
-rw-r--r--drivers/isdn/hisax/hfc_usb.c1
-rw-r--r--drivers/isdn/hisax/hisax_isac.c1
-rw-r--r--drivers/isdn/hisax/hscx.c1
-rw-r--r--drivers/isdn/hisax/icc.c1
-rw-r--r--drivers/isdn/hisax/ipacx.c1
-rw-r--r--drivers/isdn/hisax/isac.c1
-rw-r--r--drivers/isdn/hisax/isar.c1
-rw-r--r--drivers/isdn/hisax/isdnl1.c1
-rw-r--r--drivers/isdn/hisax/isdnl2.c1
-rw-r--r--drivers/isdn/hisax/isdnl3.c1
-rw-r--r--drivers/isdn/hisax/jade.c1
-rw-r--r--drivers/isdn/hisax/l3dss1.c1
-rw-r--r--drivers/isdn/hisax/l3ni1.c1
-rw-r--r--drivers/isdn/hisax/netjet.c1
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c12
-rw-r--r--drivers/isdn/hisax/st5481_b.c2
-rw-r--r--drivers/isdn/hisax/st5481_d.c2
-rw-r--r--drivers/isdn/hisax/tei.c1
-rw-r--r--drivers/isdn/hisax/teles_cs.c12
-rw-r--r--drivers/isdn/hisax/w6692.c1
-rw-r--r--drivers/isdn/hysdn/hycapi.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_boot.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c1
-rw-r--r--drivers/isdn/i4l/isdn_audio.c1
-rw-r--r--drivers/isdn/i4l/isdn_common.c3
-rw-r--r--drivers/isdn/i4l/isdn_net.c1
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c1
-rw-r--r--drivers/isdn/i4l/isdn_tty.c1
-rw-r--r--drivers/isdn/i4l/isdn_x25iface.c1
-rw-r--r--drivers/isdn/icn/icn.c1
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c1
-rw-r--r--drivers/isdn/mISDN/clock.c1
-rw-r--r--drivers/isdn/mISDN/core.c1
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c1
-rw-r--r--drivers/isdn/mISDN/dsp_core.c5
-rw-r--r--drivers/isdn/mISDN/dsp_pipeline.c1
-rw-r--r--drivers/isdn/mISDN/dsp_tones.c1
-rw-r--r--drivers/isdn/mISDN/hwchannel.c1
-rw-r--r--drivers/isdn/mISDN/l1oip_core.c5
-rw-r--r--drivers/isdn/mISDN/layer1.c1
-rw-r--r--drivers/isdn/mISDN/layer2.c1
-rw-r--r--drivers/isdn/mISDN/socket.c1
-rw-r--r--drivers/isdn/mISDN/stack.c1
-rw-r--r--drivers/isdn/mISDN/tei.c1
-rw-r--r--drivers/isdn/mISDN/timerdev.c1
-rw-r--r--drivers/isdn/pcbit/callbacks.c1
-rw-r--r--drivers/isdn/pcbit/edss1.c1
-rw-r--r--drivers/isdn/sc/hardware.h2
-rw-r--r--drivers/isdn/sc/init.c1
-rw-r--r--drivers/leds/Kconfig87
-rw-r--r--drivers/leds/Makefile2
-rw-r--r--drivers/leds/dell-led.c201
-rw-r--r--drivers/leds/led-class.c42
-rw-r--r--drivers/leds/led-triggers.c1
-rw-r--r--drivers/leds/leds-88pm860x.c326
-rw-r--r--drivers/leds/leds-adp5520.c1
-rw-r--r--drivers/leds/leds-atmel-pwm.c1
-rw-r--r--drivers/leds/leds-bd2802.c1
-rw-r--r--drivers/leds/leds-da903x.c1
-rw-r--r--drivers/leds/leds-dac124s085.c1
-rw-r--r--drivers/leds/leds-gpio.c4
-rw-r--r--drivers/leds/leds-lp3944.c1
-rw-r--r--drivers/leds/leds-lt3593.c1
-rw-r--r--drivers/leds/leds-pca9532.c1
-rw-r--r--drivers/leds/leds-pca955x.c1
-rw-r--r--drivers/leds/leds-pwm.c1
-rw-r--r--drivers/leds/leds-regulator.c1
-rw-r--r--drivers/leds/leds-s3c24xx.c1
-rw-r--r--drivers/leds/leds-ss4200.c2
-rw-r--r--drivers/leds/leds-sunfire.c1
-rw-r--r--drivers/leds/leds-wm831x-status.c1
-rw-r--r--drivers/leds/leds-wm8350.c1
-rw-r--r--drivers/leds/ledtrig-backlight.c1
-rw-r--r--drivers/leds/ledtrig-gpio.c1
-rw-r--r--drivers/leds/ledtrig-heartbeat.c1
-rw-r--r--drivers/leds/ledtrig-timer.c1
-rw-r--r--drivers/lguest/core.c1
-rw-r--r--drivers/lguest/lg.h1
-rw-r--r--drivers/lguest/lguest_device.c5
-rw-r--r--drivers/lguest/lguest_user.c1
-rw-r--r--drivers/lguest/page_tables.c1
-rw-r--r--drivers/lguest/x86/core.c12
-rw-r--r--drivers/macintosh/mac_hid.c1
-rw-r--r--drivers/macintosh/rack-meter.c1
-rw-r--r--drivers/macintosh/smu.c1
-rw-r--r--drivers/macintosh/therm_pm72.c31
-rw-r--r--drivers/macintosh/therm_pm72.h2
-rw-r--r--drivers/macintosh/therm_windtunnel.c1
-rw-r--r--drivers/macintosh/via-pmu-backlight.c7
-rw-r--r--drivers/macintosh/via-pmu68k.c1
-rw-r--r--drivers/macintosh/windfarm_core.c3
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c1
-rw-r--r--drivers/md/dm-crypt.c3
-rw-r--r--drivers/md/dm-delay.c8
-rw-r--r--drivers/md/dm-ioctl.c24
-rw-r--r--drivers/md/dm-linear.c3
-rw-r--r--drivers/md/dm-log-userspace-base.c1
-rw-r--r--drivers/md/dm-log-userspace-transfer.c1
-rw-r--r--drivers/md/dm-log.c3
-rw-r--r--drivers/md/dm-mpath.c111
-rw-r--r--drivers/md/dm-raid1.c53
-rw-r--r--drivers/md/dm-region-hash.c1
-rw-r--r--drivers/md/dm-service-time.c2
-rw-r--r--drivers/md/dm-snap.c34
-rw-r--r--drivers/md/dm-stripe.c3
-rw-r--r--drivers/md/dm-sysfs.c2
-rw-r--r--drivers/md/dm-table.c12
-rw-r--r--drivers/md/dm-target.c1
-rw-r--r--drivers/md/dm-uevent.c7
-rw-r--r--drivers/md/dm.c25
-rw-r--r--drivers/md/dm.h4
-rw-r--r--drivers/md/faulty.c1
-rw-r--r--drivers/md/linear.c13
-rw-r--r--drivers/md/md.c5
-rw-r--r--drivers/md/multipath.c21
-rw-r--r--drivers/md/raid0.c14
-rw-r--r--drivers/md/raid1.c29
-rw-r--r--drivers/md/raid10.c29
-rw-r--r--drivers/md/raid5.c53
-rw-r--r--drivers/md/raid6algos.c1
-rw-r--r--drivers/media/IR/ir-keytable.c5
-rw-r--r--drivers/media/IR/ir-sysfs.c1
-rw-r--r--drivers/media/common/tuners/max2165.c1
-rw-r--r--drivers/media/common/tuners/mc44s803.c1
-rw-r--r--drivers/media/common/tuners/mt2060.c1
-rw-r--r--drivers/media/common/tuners/mt20xx.c1
-rw-r--r--drivers/media/common/tuners/mt2131.c1
-rw-r--r--drivers/media/common/tuners/mt2266.c1
-rw-r--r--drivers/media/common/tuners/tda827x.c1
-rw-r--r--drivers/media/common/tuners/tda8290.c1
-rw-r--r--drivers/media/common/tuners/tda9887.c1
-rw-r--r--drivers/media/common/tuners/tea5761.c1
-rw-r--r--drivers/media/common/tuners/tea5767.c1
-rw-r--r--drivers/media/common/tuners/tuner-i2c.h1
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c1
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c1
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c1
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h9
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c1
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c4
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c1
-rw-r--r--drivers/media/dvb/firewire/firedtv-rc.c1
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c1
-rw-r--r--drivers/media/dvb/frontends/dib0070.c1
-rw-r--r--drivers/media/dvb/frontends/dib0090.c1
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c1
-rw-r--r--drivers/media/dvb/frontends/dib7000m.c1
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c1
-rw-r--r--drivers/media/dvb/frontends/dib8000.c1
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c1
-rw-r--r--drivers/media/dvb/frontends/itd1000.c1
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.c1
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.c1
-rw-r--r--drivers/media/dvb/frontends/mb86a16.c1
-rw-r--r--drivers/media/dvb/frontends/s921_module.c1
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c1
-rw-r--r--drivers/media/dvb/frontends/stb6000.c1
-rw-r--r--drivers/media/dvb/frontends/stb6100.c1
-rw-r--r--drivers/media/dvb/frontends/stv090x.c1
-rw-r--r--drivers/media/dvb/frontends/stv6110.c1
-rw-r--r--drivers/media/dvb/frontends/stv6110x.c1
-rw-r--r--drivers/media/dvb/frontends/tda665x.c1
-rw-r--r--drivers/media/dvb/frontends/tda8261.c1
-rw-r--r--drivers/media/dvb/frontends/tda826x.c1
-rw-r--r--drivers/media/dvb/frontends/tua6100.c1
-rw-r--r--drivers/media/dvb/frontends/zl10036.c1
-rw-r--r--drivers/media/dvb/mantis/hopper_cards.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_ca.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_cards.c1
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c1
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c1
-rw-r--r--drivers/media/dvb/pt1/pt1.c1
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c1
-rw-r--r--drivers/media/dvb/siano/smsdvb.c1
-rw-r--r--drivers/media/dvb/siano/smssdio.c1
-rw-r--r--drivers/media/dvb/siano/smsusb.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c1
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c1
-rw-r--r--drivers/media/radio/radio-maestro.c1
-rw-r--r--drivers/media/radio/radio-maxiradio.c1
-rw-r--r--drivers/media/radio/radio-si4713.c1
-rw-r--r--drivers/media/radio/radio-tea5764.c1
-rw-r--r--drivers/media/radio/radio-timb.c1
-rw-r--r--drivers/media/radio/saa7706h.c1
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c1
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c1
-rw-r--r--drivers/media/radio/si4713-i2c.c1
-rw-r--r--drivers/media/radio/tef6862.c1
-rw-r--r--drivers/media/video/adv7170.c1
-rw-r--r--drivers/media/video/adv7175.c1
-rw-r--r--drivers/media/video/adv7180.c1
-rw-r--r--drivers/media/video/adv7343.c1
-rw-r--r--drivers/media/video/au0828/au0828-core.c1
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c1
-rw-r--r--drivers/media/video/au0828/au0828-video.c1
-rw-r--r--drivers/media/video/bt819.c1
-rw-r--r--drivers/media/video/bt856.c1
-rw-r--r--drivers/media/video/bt866.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-gpio.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c1
-rw-r--r--drivers/media/video/cafe_ccic.c1
-rw-r--r--drivers/media/video/cpia_pp.c1
-rw-r--r--drivers/media/video/cs5345.c1
-rw-r--r--drivers/media/video/cs53l32a.c1
-rw-r--r--drivers/media/video/cx18/cx18-alsa-main.c1
-rw-r--r--drivers/media/video/cx18/cx18-controls.c1
-rw-r--r--drivers/media/video/cx18/cx18-driver.h1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-vbi.c1
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c1
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c1
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c1
-rw-r--r--drivers/media/video/cx88/cx88-cards.c1
-rw-r--r--drivers/media/video/cx88/cx88-dsp.c1
-rw-r--r--drivers/media/video/cx88/cx88-input.c1
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c1
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c1
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.c1
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c1
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c1
-rw-r--r--drivers/media/video/davinci/vpif_capture.c1
-rw-r--r--drivers/media/video/davinci/vpif_display.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-vbi.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c1
-rw-r--r--drivers/media/video/gspca/gspca.h1
-rw-r--r--drivers/media/video/gspca/jeilinj.c1
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c1
-rw-r--r--drivers/media/video/gspca/ov519.c2
-rw-r--r--drivers/media/video/gspca/sn9c20x.c1
-rw-r--r--drivers/media/video/gspca/sonixj.c1
-rw-r--r--drivers/media/video/gspca/sq905.c1
-rw-r--r--drivers/media/video/gspca/sq905c.c1
-rw-r--r--drivers/media/video/gspca/zc3xx.c1
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h1
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c1
-rw-r--r--drivers/media/video/ks0127.c1
-rw-r--r--drivers/media/video/m52790.c1
-rw-r--r--drivers/media/video/meye.c1
-rw-r--r--drivers/media/video/msp3400-kthreads.c1
-rw-r--r--drivers/media/video/mt9v011.c1
-rw-r--r--drivers/media/video/mx1_camera.c1
-rw-r--r--drivers/media/video/omap24xxcam.c3
-rw-r--r--drivers/media/video/ov7670.c1
-rw-r--r--drivers/media/video/pms.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-eeprom.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c8
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c1
-rw-r--r--drivers/media/video/pwc/philips.txt2
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c1
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c1
-rw-r--r--drivers/media/video/pwc/pwc.h1
-rw-r--r--drivers/media/video/pxa_camera.c1
-rw-r--r--drivers/media/video/s2255drv.c1
-rw-r--r--drivers/media/video/saa5246a.c1
-rw-r--r--drivers/media/video/saa5249.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c1
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c1
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c2
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c1
-rw-r--r--drivers/media/video/saa717x.c1
-rw-r--r--drivers/media/video/saa7185.c1
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c1
-rw-r--r--drivers/media/video/sn9c102/sn9c102_sensor.h2
-rw-r--r--drivers/media/video/soc_camera.c1
-rw-r--r--drivers/media/video/tda9840.c1
-rw-r--r--drivers/media/video/tea6415c.c1
-rw-r--r--drivers/media/video/tea6420.c3
-rw-r--r--drivers/media/video/ths7303.c1
-rw-r--r--drivers/media/video/tlg2300/pd-alsa.c2
-rw-r--r--drivers/media/video/tlg2300/pd-dvb.c1
-rw-r--r--drivers/media/video/tlg2300/pd-video.c1
-rw-r--r--drivers/media/video/tlv320aic23b.c1
-rw-r--r--drivers/media/video/tvp514x.c1
-rw-r--r--drivers/media/video/tvp5150.c1
-rw-r--r--drivers/media/video/tvp7002.c1
-rw-r--r--drivers/media/video/upd64031a.c1
-rw-r--r--drivers/media/video/upd64083.c1
-rw-r--r--drivers/media/video/usbvideo/konicawc.c1
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c1
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c1
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c1
-rw-r--r--drivers/media/video/uvc/uvc_driver.c1
-rw-r--r--drivers/media/video/uvc/uvc_status.c1
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c1
-rw-r--r--drivers/media/video/uvc/uvc_video.c1
-rw-r--r--drivers/media/video/v4l2-ioctl.c1
-rw-r--r--drivers/media/video/videobuf-dma-contig.c1
-rw-r--r--drivers/media/video/videobuf-dvb.c1
-rw-r--r--drivers/media/video/vino.c1
-rw-r--r--drivers/media/video/vp27smpx.c1
-rw-r--r--drivers/media/video/vpx3220.c1
-rw-r--r--drivers/media/video/w9966.c1
-rw-r--r--drivers/media/video/wm8739.c1
-rw-r--r--drivers/media/video/wm8775.c1
-rw-r--r--drivers/media/video/zoran/zoran_card.c1
-rw-r--r--drivers/memstick/core/memstick.c1
-rw-r--r--drivers/memstick/core/mspro_block.c1
-rw-r--r--drivers/memstick/host/jmb38x_ms.c1
-rw-r--r--drivers/message/fusion/mptfc.c1
-rw-r--r--drivers/message/fusion/mptlan.c1
-rw-r--r--drivers/message/fusion/mptsas.c1
-rw-r--r--drivers/message/fusion/mptscsih.c1
-rw-r--r--drivers/message/fusion/mptspi.c1
-rw-r--r--drivers/message/i2o/i2o_block.c1
-rw-r--r--drivers/message/i2o/i2o_config.c1
-rw-r--r--drivers/message/i2o/i2o_proc.c1
-rw-r--r--drivers/message/i2o/iop.c3
-rw-r--r--drivers/message/i2o/pci.c1
-rw-r--r--drivers/mfd/88pm8607.c302
-rw-r--r--drivers/mfd/88pm860x-core.c740
-rw-r--r--drivers/mfd/88pm860x-i2c.c237
-rw-r--r--drivers/mfd/Kconfig75
-rw-r--r--drivers/mfd/Makefile8
-rw-r--r--drivers/mfd/ab3100-core.c55
-rw-r--r--drivers/mfd/ab3100-otp.c14
-rw-r--r--drivers/mfd/ab4500-core.c1
-rw-r--r--drivers/mfd/adp5520.c1
-rw-r--r--drivers/mfd/asic3.c1
-rw-r--r--drivers/mfd/da903x.c1
-rw-r--r--drivers/mfd/ezx-pcap.c1
-rw-r--r--drivers/mfd/htc-egpio.c3
-rw-r--r--drivers/mfd/htc-i2cpld.c711
-rw-r--r--drivers/mfd/htc-pasic3.c1
-rw-r--r--drivers/mfd/lpc_sch.c133
-rw-r--r--drivers/mfd/max8925-core.c656
-rw-r--r--drivers/mfd/max8925-i2c.c212
-rw-r--r--drivers/mfd/mc13783-core.c74
-rw-r--r--drivers/mfd/mcp-sa11x0.c1
-rw-r--r--drivers/mfd/menelaus.c1
-rw-r--r--drivers/mfd/mfd-core.c6
-rw-r--r--drivers/mfd/pcf50633-adc.c1
-rw-r--r--drivers/mfd/pcf50633-core.c1
-rw-r--r--drivers/mfd/sh_mobile_sdhi.c7
-rw-r--r--drivers/mfd/sm501.c12
-rw-r--r--drivers/mfd/t7l66xb.c5
-rw-r--r--drivers/mfd/tc6387xb.c1
-rw-r--r--drivers/mfd/tc6393xb.c3
-rw-r--r--drivers/mfd/timberdale.c1
-rw-r--r--drivers/mfd/twl-core.c41
-rw-r--r--drivers/mfd/twl4030-codec.c1
-rw-r--r--drivers/mfd/twl4030-irq.c1
-rw-r--r--drivers/mfd/twl4030-power.c52
-rw-r--r--drivers/mfd/ucb1400_core.c1
-rw-r--r--drivers/mfd/ucb1x00-core.c1
-rw-r--r--drivers/mfd/wm831x-core.c52
-rw-r--r--drivers/mfd/wm8350-core.c36
-rw-r--r--drivers/mfd/wm8350-i2c.c1
-rw-r--r--drivers/mfd/wm8350-irq.c155
-rw-r--r--drivers/mfd/wm8400-core.c1
-rw-r--r--drivers/mfd/wm8994-core.c538
-rw-r--r--drivers/misc/Kconfig35
-rw-r--r--drivers/misc/Makefile2
-rw-r--r--drivers/misc/atmel-ssc.c1
-rw-r--r--drivers/misc/atmel_pwm.c1
-rw-r--r--drivers/misc/atmel_tclib.c1
-rw-r--r--drivers/misc/c2port/core.c5
-rw-r--r--drivers/misc/cb710/core.c2
-rw-r--r--drivers/misc/cb710/debug.c1
-rw-r--r--drivers/misc/cs5535-mfgpt.c1
-rw-r--r--drivers/misc/ds1682.c1
-rw-r--r--drivers/misc/eeprom/at24.c1
-rw-r--r--drivers/misc/eeprom/at25.c1
-rw-r--r--drivers/misc/enclosure.c1
-rw-r--r--drivers/misc/ep93xx_pwm.c1
-rw-r--r--drivers/misc/hpilo.c1
-rw-r--r--drivers/misc/ibmasm/command.c1
-rw-r--r--drivers/misc/ibmasm/event.c1
-rw-r--r--drivers/misc/ibmasm/ibmasmfs.c1
-rw-r--r--drivers/misc/ibmasm/module.c1
-rw-r--r--drivers/misc/ics932s401.c1
-rw-r--r--drivers/misc/ioc4.c1
-rw-r--r--drivers/misc/iwmc3200top/debugfs.c1
-rw-r--r--drivers/misc/iwmc3200top/fw-download.c1
-rw-r--r--drivers/misc/iwmc3200top/log.c1
-rw-r--r--drivers/misc/iwmc3200top/main.c3
-rw-r--r--drivers/misc/kgdbts.c6
-rw-r--r--drivers/misc/lkdtm.c473
-rw-r--r--drivers/misc/phantom.c14
-rw-r--r--drivers/misc/sgi-gru/grutables.h15
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c1
-rw-r--r--drivers/misc/sgi-xp/xpc_partition.c1
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c1
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c1
-rw-r--r--drivers/misc/sgi-xp/xpnet.c3
-rw-r--r--drivers/misc/tifm_core.c1
-rw-r--r--drivers/misc/tsl2550.c473
-rw-r--r--drivers/misc/vmware_balloon.c832
-rw-r--r--drivers/mmc/card/block.c1
-rw-r--r--drivers/mmc/card/mmc_test.c1
-rw-r--r--drivers/mmc/card/queue.c1
-rw-r--r--drivers/mmc/card/sdio_uart.c4
-rw-r--r--drivers/mmc/core/bus.c1
-rw-r--r--drivers/mmc/core/core.c13
-rw-r--r--drivers/mmc/core/debugfs.c1
-rw-r--r--drivers/mmc/core/host.c1
-rw-r--r--drivers/mmc/core/mmc.c4
-rw-r--r--drivers/mmc/core/mmc_ops.c1
-rw-r--r--drivers/mmc/core/sd.c1
-rw-r--r--drivers/mmc/core/sdio.c64
-rw-r--r--drivers/mmc/core/sdio_bus.c1
-rw-r--r--drivers/mmc/core/sdio_cis.c1
-rw-r--r--drivers/mmc/core/sdio_io.c56
-rw-r--r--drivers/mmc/core/sdio_ops.c36
-rw-r--r--drivers/mmc/core/sdio_ops.h1
-rw-r--r--drivers/mmc/host/Kconfig15
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/at91_mci.c225
-rw-r--r--drivers/mmc/host/atmel-mci.c1
-rw-r--r--drivers/mmc/host/au1xmmc.c1
-rw-r--r--drivers/mmc/host/bfin_sdh.c11
-rw-r--r--drivers/mmc/host/cb710-mmc.c1
-rw-r--r--drivers/mmc/host/davinci_mmc.c45
-rw-r--r--drivers/mmc/host/mmc_spi.c1
-rw-r--r--drivers/mmc/host/msm_sdcc.c5
-rw-r--r--drivers/mmc/host/mxcmmc.c4
-rw-r--r--drivers/mmc/host/of_mmc_spi.c1
-rw-r--r--drivers/mmc/host/omap.c1
-rw-r--r--drivers/mmc/host/omap_hsmmc.c9
-rw-r--r--drivers/mmc/host/pxamci.c1
-rw-r--r--drivers/mmc/host/ricoh_mmc.c262
-rw-r--r--drivers/mmc/host/s3cmci.c4
-rw-r--r--drivers/mmc/host/sdhci-pci.c25
-rw-r--r--drivers/mmc/host/sdhci-s3c.c1
-rw-r--r--drivers/mmc/host/sdhci.c77
-rw-r--r--drivers/mmc/host/tmio_mmc.c13
-rw-r--r--drivers/mmc/host/tmio_mmc.h6
-rw-r--r--drivers/mmc/host/wbsd.c1
-rw-r--r--drivers/mtd/Makefile2
-rw-r--r--[-rwxr-xr-x]drivers/mtd/chips/cfi_util.c0
-rw-r--r--drivers/mtd/chips/jedec_probe.c2
-rw-r--r--drivers/mtd/devices/block2mtd.c1
-rw-r--r--drivers/mtd/devices/m25p80.c1
-rw-r--r--drivers/mtd/devices/sst25l.c1
-rw-r--r--[-rwxr-xr-x]drivers/mtd/inftlcore.c0
-rw-r--r--drivers/mtd/internal.h17
-rw-r--r--drivers/mtd/lpddr/lpddr_cmds.c1
-rw-r--r--drivers/mtd/maps/amd76xrom.c1
-rw-r--r--drivers/mtd/maps/bfin-async-flash.c1
-rw-r--r--drivers/mtd/maps/ck804xrom.c1
-rw-r--r--drivers/mtd/maps/esb2rom.c1
-rw-r--r--drivers/mtd/maps/gpio-addr-flash.c1
-rw-r--r--drivers/mtd/maps/ichxrom.c1
-rw-r--r--drivers/mtd/maps/intel_vr_nor.c1
-rw-r--r--drivers/mtd/maps/octagon-5066.c1
-rw-r--r--drivers/mtd/maps/omap_nor.c0
-rw-r--r--drivers/mtd/maps/physmap_of.c1
-rw-r--r--drivers/mtd/maps/pismo.c3
-rw-r--r--drivers/mtd/maps/plat-ram.c2
-rw-r--r--drivers/mtd/maps/pmcmsp-flash.c1
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c1
-rw-r--r--drivers/mtd/maps/sbc_gxx.c1
-rw-r--r--drivers/mtd/maps/sun_uflash.c1
-rw-r--r--drivers/mtd/maps/vmax301.c1
-rw-r--r--drivers/mtd/maps/vmu-flash.c1
-rw-r--r--drivers/mtd/mtdbdi.c43
-rw-r--r--drivers/mtd/mtdcore.c80
-rw-r--r--drivers/mtd/mtdsuper.c2
-rw-r--r--drivers/mtd/nand/Kconfig4
-rw-r--r--drivers/mtd/nand/bcm_umi_nand.c5
-rw-r--r--drivers/mtd/nand/cafe_nand.c1
-rw-r--r--drivers/mtd/nand/cmx270_nand.c1
-rw-r--r--drivers/mtd/nand/davinci_nand.c1
-rw-r--r--drivers/mtd/nand/diskonchip.c1
-rw-r--r--drivers/mtd/nand/fsl_upm.c1
-rw-r--r--drivers/mtd/nand/mxc_nand.c2
-rw-r--r--drivers/mtd/nand/ndfc.c1
-rw-r--r--drivers/mtd/nand/nomadik_nand.c1
-rw-r--r--drivers/mtd/nand/omap2.c1
-rw-r--r--drivers/mtd/nand/orion_nand.c8
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c1
-rw-r--r--drivers/mtd/nand/sh_flctl.c1
-rw-r--r--drivers/mtd/nand/tmio_nand.c1
-rw-r--r--drivers/mtd/ofpart.c1
-rw-r--r--drivers/mtd/onenand/omap2.c1
-rw-r--r--drivers/mtd/onenand/onenand_base.c1
-rw-r--r--drivers/mtd/onenand/onenand_sim.c1
-rw-r--r--drivers/mtd/tests/mtd_nandecctest.c1
-rw-r--r--drivers/mtd/tests/mtd_oobtest.c1
-rw-r--r--drivers/mtd/tests/mtd_pagetest.c1
-rw-r--r--drivers/mtd/tests/mtd_readtest.c1
-rw-r--r--drivers/mtd/tests/mtd_speedtest.c1
-rw-r--r--drivers/mtd/tests/mtd_stresstest.c1
-rw-r--r--drivers/mtd/tests/mtd_subpagetest.c1
-rw-r--r--drivers/mtd/tests/mtd_torturetest.c1
-rw-r--r--drivers/mtd/ubi/build.c137
-rw-r--r--drivers/mtd/ubi/cdev.c1
-rw-r--r--drivers/mtd/ubi/debug.h4
-rw-r--r--drivers/mtd/ubi/gluebi.c1
-rw-r--r--drivers/mtd/ubi/io.c121
-rw-r--r--drivers/mtd/ubi/kapi.c1
-rw-r--r--drivers/mtd/ubi/scan.c12
-rw-r--r--drivers/mtd/ubi/ubi.h1
-rw-r--r--drivers/mtd/ubi/vmt.c1
-rw-r--r--drivers/mtd/ubi/vtbl.c1
-rw-r--r--drivers/mtd/ubi/wl.c17
-rw-r--r--drivers/net/3c501.c1
-rw-r--r--drivers/net/3c505.c2
-rw-r--r--drivers/net/3c507.c1
-rw-r--r--drivers/net/3c509.c1
-rw-r--r--drivers/net/3c515.c1
-rw-r--r--drivers/net/3c523.c1
-rw-r--r--drivers/net/3c59x.c2
-rw-r--r--drivers/net/7990.c1
-rw-r--r--drivers/net/8139cp.c1
-rw-r--r--drivers/net/8139too.c3
-rw-r--r--drivers/net/82596.c2
-rw-r--r--drivers/net/Kconfig27
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/a2065.c1
-rw-r--r--drivers/net/acenic.c1
-rw-r--r--drivers/net/amd8111e.c1
-rw-r--r--drivers/net/appletalk/cops.c1
-rw-r--r--drivers/net/appletalk/ipddp.c1
-rw-r--r--drivers/net/appletalk/ltpc.c2
-rw-r--r--drivers/net/arcnet/arc-rawmode.c1
-rw-r--r--drivers/net/arcnet/arc-rimi.c1
-rw-r--r--drivers/net/arcnet/capmode.c1
-rw-r--r--drivers/net/arcnet/com20020-isa.c1
-rw-r--r--drivers/net/arcnet/com20020-pci.c1
-rw-r--r--drivers/net/arcnet/com20020.c1
-rw-r--r--drivers/net/arcnet/com90io.c1
-rw-r--r--drivers/net/arcnet/com90xx.c1
-rw-r--r--drivers/net/arcnet/rfc1051.c1
-rw-r--r--drivers/net/arcnet/rfc1201.c1
-rw-r--r--drivers/net/ariadne.c1
-rw-r--r--drivers/net/arm/at91_ether.c1
-rw-r--r--drivers/net/arm/ep93xx_eth.c1
-rw-r--r--drivers/net/arm/etherh.c1
-rw-r--r--drivers/net/arm/ixp4xx_eth.c1
-rw-r--r--drivers/net/arm/ks8695net.c27
-rw-r--r--drivers/net/arm/w90p910_ether.c1
-rw-r--r--drivers/net/at1700.c1
-rw-r--r--drivers/net/atarilance.c1
-rw-r--r--drivers/net/atl1c/atl1c_ethtool.c1
-rw-r--r--drivers/net/atl1e/atl1e_ethtool.c1
-rw-r--r--drivers/net/atlx/atl1.c2
-rw-r--r--drivers/net/atlx/atl2.c1
-rw-r--r--drivers/net/atlx/atl2.h2
-rw-r--r--drivers/net/atp.c1
-rw-r--r--drivers/net/ax88796.c1
-rw-r--r--drivers/net/b44.c1
-rw-r--r--drivers/net/bcm63xx_enet.c1
-rw-r--r--drivers/net/benet/be.h6
-rw-r--r--drivers/net/benet/be_cmds.c12
-rw-r--r--drivers/net/benet/be_ethtool.c2
-rw-r--r--drivers/net/benet/be_hw.h5
-rw-r--r--drivers/net/benet/be_main.c46
-rw-r--r--drivers/net/bmac.c1
-rw-r--r--drivers/net/bnx2.c62
-rw-r--r--drivers/net/bnx2x_main.c10
-rw-r--r--drivers/net/bonding/bond_main.c66
-rw-r--r--drivers/net/bonding/bond_sysfs.c5
-rw-r--r--drivers/net/can/bfin_can.c100
-rw-r--r--drivers/net/can/dev.c1
-rw-r--r--drivers/net/can/mcp251x.c1
-rw-r--r--drivers/net/can/sja1000/ems_pci.c1
-rw-r--r--drivers/net/can/sja1000/plx_pci.c1
-rw-r--r--drivers/net/can/usb/ems_usb.c12
-rw-r--r--drivers/net/can/vcan.c1
-rw-r--r--drivers/net/cassini.c2
-rw-r--r--drivers/net/chelsio/common.h1
-rw-r--r--drivers/net/chelsio/pm3393.c1
-rw-r--r--drivers/net/chelsio/sge.c3
-rw-r--r--drivers/net/cnic.c10
-rw-r--r--drivers/net/cpmac.c14
-rw-r--r--drivers/net/cris/eth_v10.c1
-rw-r--r--drivers/net/cs89x0.c4
-rw-r--r--drivers/net/cxgb3/ael1002.c2
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c4
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c1
-rw-r--r--drivers/net/cxgb3/l2t.c1
-rw-r--r--drivers/net/cxgb3/sge.c5
-rw-r--r--drivers/net/cxgb4/Makefile7
-rw-r--r--drivers/net/cxgb4/cxgb4.h741
-rw-r--r--drivers/net/cxgb4/cxgb4_main.c3388
-rw-r--r--drivers/net/cxgb4/cxgb4_uld.h239
-rw-r--r--drivers/net/cxgb4/l2t.c624
-rw-r--r--drivers/net/cxgb4/l2t.h110
-rw-r--r--drivers/net/cxgb4/sge.c2431
-rw-r--r--drivers/net/cxgb4/t4_hw.c3131
-rw-r--r--drivers/net/cxgb4/t4_hw.h100
-rw-r--r--drivers/net/cxgb4/t4_msg.h664
-rw-r--r--drivers/net/cxgb4/t4_regs.h878
-rw-r--r--drivers/net/cxgb4/t4fw_api.h1580
-rw-r--r--drivers/net/davinci_emac.c76
-rw-r--r--drivers/net/dm9000.c1
-rw-r--r--drivers/net/e100.c12
-rw-r--r--drivers/net/e1000/e1000.h1
-rw-r--r--drivers/net/e1000/e1000_main.c9
-rw-r--r--drivers/net/e1000e/82571.c22
-rw-r--r--drivers/net/e1000e/defines.h2
-rw-r--r--drivers/net/e1000e/e1000.h6
-rw-r--r--drivers/net/e1000e/ethtool.c1
-rw-r--r--drivers/net/e1000e/ich8lan.c10
-rw-r--r--drivers/net/e1000e/lib.c2
-rw-r--r--drivers/net/e1000e/netdev.c84
-rw-r--r--drivers/net/eepro.c1
-rw-r--r--drivers/net/eexpress.c1
-rw-r--r--drivers/net/ehea/ehea_main.c1
-rw-r--r--drivers/net/ehea/ehea_qmr.c1
-rw-r--r--drivers/net/enc28j60.c1
-rw-r--r--drivers/net/enic/vnic_dev.c1
-rw-r--r--drivers/net/enic/vnic_rq.c1
-rw-r--r--drivers/net/enic/vnic_wq.c1
-rw-r--r--drivers/net/epic100.c1
-rw-r--r--drivers/net/eql.c1
-rw-r--r--drivers/net/eth16i.c1
-rw-r--r--drivers/net/ethoc.c1
-rw-r--r--drivers/net/fealnx.c1
-rw-r--r--drivers/net/fec_mpc52xx.c1
-rw-r--r--drivers/net/fec_mpc52xx_phy.c1
-rw-r--r--drivers/net/forcedeth.c3
-rw-r--r--drivers/net/fs_enet/mac-fcc.c2
-rw-r--r--drivers/net/fs_enet/mac-fec.c2
-rw-r--r--drivers/net/fs_enet/mac-scc.c1
-rw-r--r--drivers/net/fsl_pq_mdio.c20
-rw-r--r--drivers/net/gianfar.c46
-rw-r--r--drivers/net/gianfar.h6
-rw-r--r--drivers/net/gianfar_ethtool.c1
-rw-r--r--drivers/net/gianfar_sysfs.c1
-rw-r--r--drivers/net/greth.c1
-rw-r--r--drivers/net/hamachi.c1
-rw-r--r--drivers/net/hamradio/6pack.c1
-rw-r--r--drivers/net/hamradio/bpqether.c1
-rw-r--r--drivers/net/hamradio/dmascc.c1
-rw-r--r--drivers/net/hamradio/hdlcdrv.c1
-rw-r--r--drivers/net/hamradio/mkiss.c1
-rw-r--r--drivers/net/hamradio/scc.c1
-rw-r--r--drivers/net/hp100.c1
-rw-r--r--drivers/net/hplance.c1
-rw-r--r--drivers/net/hydra.c1
-rw-r--r--drivers/net/ibm_newemac/core.c1
-rw-r--r--drivers/net/ibm_newemac/core.h1
-rw-r--r--drivers/net/ibm_newemac/mal.c1
-rw-r--r--drivers/net/ibm_newemac/rgmii.c1
-rw-r--r--drivers/net/ibm_newemac/zmii.c1
-rw-r--r--drivers/net/ibmlana.c1
-rw-r--r--drivers/net/ibmveth.c3
-rw-r--r--drivers/net/igb/e1000_82575.c2
-rw-r--r--drivers/net/igb/e1000_hw.h1
-rw-r--r--drivers/net/igb/e1000_mac.c6
-rw-r--r--drivers/net/igb/igb.h1
-rw-r--r--drivers/net/igb/igb_ethtool.c2
-rw-r--r--drivers/net/igb/igb_main.c27
-rw-r--r--drivers/net/igbvf/igbvf.h1
-rw-r--r--drivers/net/igbvf/netdev.c12
-rw-r--r--drivers/net/ioc3-eth.c1
-rw-r--r--drivers/net/ipg.c1
-rw-r--r--drivers/net/irda/ali-ircc.c2
-rw-r--r--drivers/net/irda/bfin_sir.h1
-rw-r--r--drivers/net/irda/irda-usb.c4
-rw-r--r--drivers/net/irda/irtty-sir.c1
-rw-r--r--drivers/net/irda/nsc-ircc.c2
-rw-r--r--drivers/net/irda/pxaficp_ir.c1
-rw-r--r--drivers/net/irda/sa1100_ir.c2
-rw-r--r--drivers/net/irda/sh_sir.c1
-rw-r--r--drivers/net/irda/sir_dev.c1
-rw-r--r--drivers/net/irda/smsc-ircc2.c2
-rw-r--r--drivers/net/irda/via-ircc.c2
-rw-r--r--drivers/net/irda/w83977af_ir.c38
-rw-r--r--drivers/net/iseries_veth.c5
-rw-r--r--drivers/net/ixgbe/ixgbe.h7
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c112
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c22
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c40
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c70
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h4
-rw-r--r--drivers/net/ixgbevf/ethtool.c43
-rw-r--r--drivers/net/ixgbevf/ixgbevf_main.c80
-rw-r--r--drivers/net/ixgbevf/vf.h6
-rw-r--r--drivers/net/ixp2000/ixpdev.c1
-rw-r--r--drivers/net/jazzsonic.c3
-rw-r--r--drivers/net/jme.c36
-rw-r--r--drivers/net/jme.h2
-rw-r--r--drivers/net/ks8851.c15
-rw-r--r--drivers/net/ks8851_mll.c1
-rw-r--r--drivers/net/ksz884x.c11
-rw-r--r--drivers/net/lasi_82596.c1
-rw-r--r--drivers/net/lib82596.c2
-rw-r--r--drivers/net/ll_temac_main.c1
-rw-r--r--drivers/net/ll_temac_mdio.c1
-rw-r--r--drivers/net/mac8390.c1
-rw-r--r--drivers/net/mac89x0.c2
-rw-r--r--drivers/net/mace.c1
-rw-r--r--drivers/net/macmace.c1
-rw-r--r--drivers/net/macsonic.c3
-rw-r--r--drivers/net/macvtap.c1
-rw-r--r--drivers/net/mlx4/cmd.c1
-rw-r--r--drivers/net/mlx4/cq.c1
-rw-r--r--drivers/net/mlx4/en_main.c1
-rw-r--r--drivers/net/mlx4/en_netdev.c1
-rw-r--r--drivers/net/mlx4/en_resources.c1
-rw-r--r--drivers/net/mlx4/en_rx.c1
-rw-r--r--drivers/net/mlx4/en_tx.c1
-rw-r--r--drivers/net/mlx4/eq.c1
-rw-r--r--drivers/net/mlx4/icm.c1
-rw-r--r--drivers/net/mlx4/intf.c2
-rw-r--r--drivers/net/mlx4/main.c2
-rw-r--r--drivers/net/mlx4/mcg.c1
-rw-r--r--drivers/net/mlx4/mr.c1
-rw-r--r--drivers/net/mlx4/profile.c2
-rw-r--r--drivers/net/mlx4/qp.c1
-rw-r--r--drivers/net/mlx4/srq.c1
-rw-r--r--drivers/net/mv643xx_eth.c1
-rw-r--r--drivers/net/mvme147.c2
-rw-r--r--drivers/net/myri10ge/myri10ge.c4
-rw-r--r--drivers/net/myri_sbus.c2
-rw-r--r--drivers/net/ne.c2
-rw-r--r--drivers/net/ne2.c1
-rw-r--r--drivers/net/netconsole.c1
-rw-r--r--drivers/net/netxen/netxen_nic.h4
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c14
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c1
-rw-r--r--drivers/net/netxen/netxen_nic_init.c3
-rw-r--r--drivers/net/netxen/netxen_nic_main.c50
-rw-r--r--drivers/net/ni5010.c1
-rw-r--r--drivers/net/ni52.c1
-rw-r--r--drivers/net/niu.c1
-rw-r--r--drivers/net/ns83820.c1
-rw-r--r--drivers/net/octeon/octeon_mgmt.c1
-rw-r--r--drivers/net/pasemi_mac.c1
-rw-r--r--drivers/net/pcmcia/3c574_cs.c7
-rw-r--r--drivers/net/pcmcia/axnet_cs.c1
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c4
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c56
-rw-r--r--drivers/net/phy/cicada.c1
-rw-r--r--drivers/net/phy/davicom.c1
-rw-r--r--drivers/net/phy/et1011c.c1
-rw-r--r--drivers/net/phy/fixed.c1
-rw-r--r--drivers/net/phy/icplus.c1
-rw-r--r--drivers/net/phy/lxt.c1
-rw-r--r--drivers/net/phy/marvell.c1
-rw-r--r--drivers/net/phy/mdio-bitbang.c1
-rw-r--r--drivers/net/phy/mdio-octeon.c1
-rw-r--r--drivers/net/phy/phy.c1
-rw-r--r--drivers/net/phy/qsemi.c1
-rw-r--r--drivers/net/plip.c1
-rw-r--r--drivers/net/ppp_async.c1
-rw-r--r--drivers/net/ppp_generic.c1
-rw-r--r--drivers/net/ppp_synctty.c1
-rw-r--r--drivers/net/pppol2tp.c6
-rw-r--r--drivers/net/pppox.c1
-rw-r--r--drivers/net/ps3_gelic_net.c1
-rw-r--r--drivers/net/ps3_gelic_wireless.c1
-rw-r--r--drivers/net/qlcnic/qlcnic.h13
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c17
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c34
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c157
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c6
-rw-r--r--drivers/net/qlge/qlge_dbg.c2
-rw-r--r--drivers/net/qlge/qlge_ethtool.c3
-rw-r--r--drivers/net/qlge/qlge_main.c2
-rw-r--r--drivers/net/r6040.c12
-rw-r--r--drivers/net/r8169.c90
-rw-r--r--drivers/net/rionet.c1
-rw-r--r--drivers/net/rrunner.c1
-rw-r--r--drivers/net/s2io.c11
-rw-r--r--drivers/net/sb1000.c2
-rw-r--r--drivers/net/seeq8005.c1
-rw-r--r--drivers/net/sfc/efx.c5
-rw-r--r--drivers/net/sfc/falcon.c5
-rw-r--r--drivers/net/sfc/falcon_boards.c13
-rw-r--r--drivers/net/sfc/mcdi_phy.c1
-rw-r--r--drivers/net/sfc/mtd.c1
-rw-r--r--drivers/net/sfc/nic.h2
-rw-r--r--drivers/net/sfc/qt202x_phy.c1
-rw-r--r--drivers/net/sfc/regs.h2
-rw-r--r--drivers/net/sfc/rx.c1
-rw-r--r--drivers/net/sfc/selftest.c1
-rw-r--r--drivers/net/sfc/siena.c14
-rw-r--r--drivers/net/sfc/tenxpress.c1
-rw-r--r--drivers/net/sfc/tx.c1
-rw-r--r--drivers/net/sgiseeq.c5
-rw-r--r--drivers/net/sh_eth.c1
-rw-r--r--drivers/net/sis190.c1
-rw-r--r--drivers/net/skfp/ess.c2
-rw-r--r--drivers/net/skfp/skfddi.c2
-rw-r--r--drivers/net/skge.c1
-rw-r--r--drivers/net/sky2.c3
-rw-r--r--drivers/net/slhc.c1
-rw-r--r--drivers/net/slip.c1
-rw-r--r--drivers/net/smc911x.c1
-rw-r--r--drivers/net/smc9194.c1
-rw-r--r--drivers/net/smc91x.c1
-rw-r--r--drivers/net/smc91x.h42
-rw-r--r--drivers/net/smsc911x.c1
-rw-r--r--drivers/net/smsc9420.c3
-rw-r--r--drivers/net/sni_82596.c1
-rw-r--r--drivers/net/spider_net.c6
-rw-r--r--drivers/net/stmmac/Kconfig1
-rw-r--r--drivers/net/stmmac/dwmac100.c1
-rw-r--r--drivers/net/stmmac/dwmac1000_core.c1
-rw-r--r--drivers/net/stmmac/stmmac_main.c11
-rw-r--r--drivers/net/stmmac/stmmac_mdio.c1
-rw-r--r--drivers/net/sun3_82586.c1
-rw-r--r--drivers/net/sun3lance.c1
-rw-r--r--drivers/net/sunbmac.c2
-rw-r--r--drivers/net/sundance.c1
-rw-r--r--drivers/net/sungem.c4
-rw-r--r--drivers/net/sunlance.c2
-rw-r--r--drivers/net/tehuti.c2
-rw-r--r--drivers/net/tehuti.h1
-rw-r--r--drivers/net/tg3.c5
-rw-r--r--drivers/net/tokenring/3c359.c1
-rw-r--r--drivers/net/tokenring/lanstreamer.c1
-rw-r--r--drivers/net/tokenring/madgemc.c1
-rw-r--r--drivers/net/tokenring/smctr.c1
-rw-r--r--drivers/net/tokenring/tms380tr.c5
-rw-r--r--drivers/net/tsi108_eth.c2
-rw-r--r--drivers/net/tulip/de2104x.c1
-rw-r--r--drivers/net/tulip/de4x5.c2
-rw-r--r--drivers/net/tulip/dmfe.c1
-rw-r--r--drivers/net/tulip/eeprom.c55
-rw-r--r--drivers/net/tulip/tulip_core.c1
-rw-r--r--drivers/net/tulip/uli526x.c9
-rw-r--r--drivers/net/tulip/winbond-840.c1
-rw-r--r--drivers/net/tun.c6
-rw-r--r--drivers/net/typhoon.c13
-rw-r--r--drivers/net/ucc_geth.c2
-rw-r--r--drivers/net/ucc_geth_ethtool.c1
-rw-r--r--drivers/net/usb/Kconfig30
-rw-r--r--drivers/net/usb/Makefile3
-rw-r--r--drivers/net/usb/asix.c31
-rw-r--r--drivers/net/usb/catc.c2
-rw-r--r--drivers/net/usb/cdc-phonet.c1
-rw-r--r--drivers/net/usb/cdc_eem.c1
-rw-r--r--drivers/net/usb/cdc_ether.c1
-rw-r--r--drivers/net/usb/dm9601.c1
-rw-r--r--drivers/net/usb/gl620a.c1
-rw-r--r--drivers/net/usb/hso.c3
-rw-r--r--drivers/net/usb/int51x1.c1
-rw-r--r--drivers/net/usb/ipheth.c569
-rw-r--r--drivers/net/usb/kaweth.c1
-rw-r--r--drivers/net/usb/mcs7830.c1
-rw-r--r--drivers/net/usb/net1080.c1
-rw-r--r--drivers/net/usb/pegasus.h6
-rw-r--r--drivers/net/usb/rndis_host.c1
-rw-r--r--drivers/net/usb/sierra_net.c1001
-rw-r--r--drivers/net/usb/smsc75xx.c1289
-rw-r--r--drivers/net/usb/smsc75xx.h421
-rw-r--r--drivers/net/usb/smsc95xx.c34
-rw-r--r--drivers/net/usb/usbnet.c1
-rw-r--r--drivers/net/veth.c1
-rw-r--r--drivers/net/via-rhine.c1
-rw-r--r--drivers/net/via-velocity.c2
-rw-r--r--drivers/net/virtio_net.c3
-rw-r--r--drivers/net/vxge/vxge-config.c1
-rw-r--r--drivers/net/vxge/vxge-config.h1
-rw-r--r--drivers/net/vxge/vxge-ethtool.c1
-rw-r--r--drivers/net/vxge/vxge-main.c1
-rw-r--r--drivers/net/wan/cosa.c10
-rw-r--r--drivers/net/wan/dscc4.c1
-rw-r--r--drivers/net/wan/farsync.c1
-rw-r--r--drivers/net/wan/hd64570.c1
-rw-r--r--drivers/net/wan/hd64572.c1
-rw-r--r--drivers/net/wan/hdlc_cisco.c9
-rw-r--r--drivers/net/wan/hdlc_ppp.c6
-rw-r--r--drivers/net/wan/hdlc_raw.c1
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c2
-rw-r--r--drivers/net/wan/hdlc_x25.c6
-rw-r--r--drivers/net/wan/hostess_sv11.c1
-rw-r--r--drivers/net/wan/ixp4xx_hss.c1
-rw-r--r--drivers/net/wan/lapbether.c1
-rw-r--r--drivers/net/wan/lmc/lmc_media.c1
-rw-r--r--drivers/net/wan/lmc/lmc_proto.c1
-rw-r--r--drivers/net/wan/pc300_drv.c1
-rw-r--r--drivers/net/wan/sbni.c1
-rw-r--r--drivers/net/wan/sealevel.c1
-rw-r--r--drivers/net/wan/x25_asy.c1
-rw-r--r--drivers/net/wan/z85230.c1
-rw-r--r--drivers/net/wimax/i2400m/control.c1
-rw-r--r--drivers/net/wimax/i2400m/driver.c1
-rw-r--r--drivers/net/wimax/i2400m/fw.c3
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h2
-rw-r--r--drivers/net/wimax/i2400m/netdev.c1
-rw-r--r--drivers/net/wimax/i2400m/op-rfkill.c1
-rw-r--r--drivers/net/wimax/i2400m/rx.c1
-rw-r--r--drivers/net/wimax/i2400m/sdio-rx.c1
-rw-r--r--drivers/net/wimax/i2400m/sdio.c5
-rw-r--r--drivers/net/wimax/i2400m/tx.c1
-rw-r--r--drivers/net/wimax/i2400m/usb-fw.c1
-rw-r--r--drivers/net/wimax/i2400m/usb-notif.c1
-rw-r--r--drivers/net/wimax/i2400m/usb-rx.c1
-rw-r--r--drivers/net/wimax/i2400m/usb.c5
-rw-r--r--drivers/net/wireless/adm8211.c1
-rw-r--r--drivers/net/wireless/airo.c3
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h1
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c15
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c175
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c42
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c25
-rw-r--r--drivers/net/wireless/ath/regd.c1
-rw-r--r--drivers/net/wireless/b43/dma.c1
-rw-r--r--drivers/net/wireless/b43/lo.c1
-rw-r--r--drivers/net/wireless/b43/main.c1
-rw-r--r--drivers/net/wireless/b43/pcmcia.c1
-rw-r--r--drivers/net/wireless/b43/phy_a.c2
-rw-r--r--drivers/net/wireless/b43/phy_g.c1
-rw-r--r--drivers/net/wireless/b43/phy_lp.c2
-rw-r--r--drivers/net/wireless/b43/phy_n.c1
-rw-r--r--drivers/net/wireless/b43/pio.c1
-rw-r--r--drivers/net/wireless/b43/sdio.c1
-rw-r--r--drivers/net/wireless/b43legacy/dma.c1
-rw-r--r--drivers/net/wireless/b43legacy/main.c1
-rw-r--r--drivers/net/wireless/b43legacy/phy.c1
-rw-r--r--drivers/net/wireless/b43legacy/pio.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c1
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c20
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_geo.c1
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c37
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_wx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c173
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c81
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c110
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c5
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/eeprom.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/lmac.h2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/netdev.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/tx.c1
-rw-r--r--drivers/net/wireless/libertas/assoc.c1
-rw-r--r--drivers/net/wireless/libertas/cfg.c9
-rw-r--r--drivers/net/wireless/libertas/cmd.c1
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c1
-rw-r--r--drivers/net/wireless/libertas/debugfs.c1
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/if_cs.c1
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c1
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1
-rw-r--r--drivers/net/wireless/libertas/if_usb.c1
-rw-r--r--drivers/net/wireless/libertas/main.c1
-rw-r--r--drivers/net/wireless/libertas/rx.c1
-rw-r--r--drivers/net/wireless/libertas/scan.c1
-rw-r--r--drivers/net/wireless/libertas/wext.c1
-rw-r--r--drivers/net/wireless/libertas_tf/cmd.c2
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c1
-rw-r--r--drivers/net/wireless/libertas_tf/main.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c1
-rw-r--r--drivers/net/wireless/mwl8k.c2
-rw-r--r--drivers/net/wireless/orinoco/fw.c1
-rw-r--r--drivers/net/wireless/orinoco/main.c1
-rw-r--r--drivers/net/wireless/orinoco/scan.c1
-rw-r--r--drivers/net/wireless/orinoco/wext.c1
-rw-r--r--drivers/net/wireless/p54/eeprom.c1
-rw-r--r--drivers/net/wireless/p54/fwio.c1
-rw-r--r--drivers/net/wireless/p54/main.c1
-rw-r--r--drivers/net/wireless/p54/p54pci.c1
-rw-r--r--drivers/net/wireless/p54/p54spi.c1
-rw-r--r--drivers/net/wireless/p54/p54usb.c2
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.h1
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c1
-rw-r--r--drivers/net/wireless/ray_cs.c1
-rw-r--r--drivers/net/wireless/rndis_wlan.c67
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c9
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_debugfs.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c1
-rw-r--r--drivers/net/wireless/zd1201.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c13
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_uw2453.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c1
-rw-r--r--drivers/net/xen-netfront.c1
-rw-r--r--drivers/net/xilinx_emaclite.c1
-rw-r--r--drivers/net/xtsonic.c3
-rw-r--r--drivers/net/yellowfin.c1
-rw-r--r--drivers/net/znet.c1
-rw-r--r--drivers/nubus/nubus.c1
-rw-r--r--drivers/of/base.c1
-rw-r--r--drivers/of/fdt.c7
-rw-r--r--drivers/of/gpio.c1
-rw-r--r--drivers/of/of_mdio.c2
-rw-r--r--drivers/oprofile/buffer_sync.c1
-rw-r--r--drivers/parisc/asp.c1
-rw-r--r--drivers/parisc/ccio-rm-dma.c1
-rw-r--r--drivers/parisc/eisa_enumerator.c2
-rw-r--r--drivers/parisc/gsc.c1
-rw-r--r--drivers/parisc/pdc_stable.c2
-rw-r--r--drivers/parisc/superio.c2
-rw-r--r--drivers/parport/ChangeLog583
-rw-r--r--drivers/parport/daisy.c1
-rw-r--r--drivers/parport/parport_ax88796.c1
-rw-r--r--drivers/parport/parport_ip32.c1
-rw-r--r--drivers/parport/parport_serial.c1
-rw-r--r--drivers/parport/probe.c1
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/access.c1
-rw-r--r--drivers/pci/bus.c5
-rw-r--r--drivers/pci/dmar.c1
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c1
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c20
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c1
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c1
-rw-r--r--drivers/pci/hotplug/fakephp.c3
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c1
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c1
-rw-r--r--drivers/pci/hotplug/pciehp_core.c1
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c1
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c6
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c3
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c4
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c1
-rw-r--r--drivers/pci/hotplug/shpchp_core.c1
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c1
-rw-r--r--drivers/pci/htirq.c1
-rw-r--r--drivers/pci/intr_remapping.c1
-rw-r--r--drivers/pci/ioapic.c10
-rw-r--r--drivers/pci/iov.c1
-rw-r--r--drivers/pci/msi.c1
-rw-r--r--drivers/pci/pci-sysfs.c6
-rw-r--r--drivers/pci/pci.c131
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c1
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c11
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c1
-rw-r--r--drivers/pci/pcie/pme/pcie_pme.c1
-rw-r--r--drivers/pci/pcie/portdrv_pci.c1
-rw-r--r--drivers/pci/probe.c30
-rw-r--r--drivers/pci/proc.c1
-rw-r--r--drivers/pci/quirks.c114
-rw-r--r--drivers/pci/search.c1
-rw-r--r--drivers/pci/setup-res.c14
-rw-r--r--drivers/pci/slot.c3
-rw-r--r--drivers/pcmcia/at91_cf.c3
-rw-r--r--drivers/pcmcia/au1000_generic.c14
-rw-r--r--drivers/pcmcia/bcm63xx_pcmcia.c1
-rw-r--r--drivers/pcmcia/bfin_cf_pcmcia.c13
-rw-r--r--drivers/pcmcia/cistpl.c9
-rw-r--r--drivers/pcmcia/cs.c124
-rw-r--r--drivers/pcmcia/db1xxx_ss.c32
-rw-r--r--drivers/pcmcia/ds.c93
-rw-r--r--drivers/pcmcia/electra_cf.c1
-rw-r--r--drivers/pcmcia/i82092.c17
-rw-r--r--drivers/pcmcia/i82365.c12
-rw-r--r--drivers/pcmcia/i82365.h1
-rw-r--r--drivers/pcmcia/m32r_cfc.c12
-rw-r--r--drivers/pcmcia/m32r_pcc.c13
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c18
-rw-r--r--drivers/pcmcia/omap_cf.c13
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c1
-rw-r--r--drivers/pcmcia/pcmcia_resource.c47
-rw-r--r--drivers/pcmcia/pd6729.c82
-rw-r--r--drivers/pcmcia/pxa2xx_base.c9
-rw-r--r--drivers/pcmcia/rsrc_mgr.c1
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c66
-rw-r--r--drivers/pcmcia/sa1100_generic.c14
-rw-r--r--drivers/pcmcia/sa1111_generic.c38
-rw-r--r--drivers/pcmcia/sa11xx_base.c1
-rw-r--r--drivers/pcmcia/socket_sysfs.c1
-rw-r--r--drivers/pcmcia/tcic.c13
-rw-r--r--drivers/pcmcia/ti113x.h37
-rw-r--r--drivers/pcmcia/vrc4171_card.c18
-rw-r--r--drivers/pcmcia/xxs1500_ss.c1
-rw-r--r--drivers/pcmcia/yenta_socket.c64
-rw-r--r--drivers/platform/x86/Kconfig12
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c8
-rw-r--r--drivers/platform/x86/asus-laptop.c20
-rw-r--r--drivers/platform/x86/asus_acpi.c8
-rw-r--r--drivers/platform/x86/classmate-laptop.c13
-rw-r--r--drivers/platform/x86/compal-laptop.c11
-rw-r--r--drivers/platform/x86/dell-laptop.c14
-rw-r--r--drivers/platform/x86/dell-wmi.c20
-rw-r--r--drivers/platform/x86/eeepc-laptop.c12
-rw-r--r--drivers/platform/x86/eeepc-wmi.c413
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c15
-rw-r--r--drivers/platform/x86/hp-wmi.c20
-rw-r--r--drivers/platform/x86/intel_menlow.c2
-rw-r--r--drivers/platform/x86/msi-laptop.c367
-rw-r--r--drivers/platform/x86/msi-wmi.c16
-rw-r--r--drivers/platform/x86/panasonic-laptop.c44
-rw-r--r--drivers/platform/x86/sony-laptop.c100
-rw-r--r--drivers/platform/x86/tc1100-wmi.c1
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c17
-rw-r--r--drivers/platform/x86/topstar-laptop.c14
-rw-r--r--drivers/platform/x86/toshiba_acpi.c28
-rw-r--r--drivers/platform/x86/wmi.c1
-rw-r--r--drivers/pnp/base.h3
-rw-r--r--drivers/pnp/interface.c7
-rw-r--r--drivers/pnp/isapnp/core.c1
-rw-r--r--drivers/pnp/manager.c1
-rw-r--r--drivers/pnp/pnpacpi/core.c1
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c84
-rw-r--r--drivers/pnp/pnpbios/bioscalls.c1
-rw-r--r--drivers/pnp/pnpbios/rsparser.c1
-rw-r--r--drivers/pnp/resource.c28
-rw-r--r--drivers/pnp/support.c4
-rw-r--r--drivers/power/Kconfig7
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/bq27x00_battery.c1
-rw-r--r--drivers/power/da9030_battery.c1
-rw-r--r--drivers/power/ds2760_battery.c1
-rw-r--r--drivers/power/ds2782_battery.c1
-rw-r--r--drivers/power/max17040_battery.c1
-rw-r--r--drivers/power/max8925_power.c535
-rw-r--r--drivers/power/pcf50633-charger.c1
-rw-r--r--drivers/power/pmu_battery.c1
-rw-r--r--drivers/power/power_supply_leds.c1
-rw-r--r--drivers/power/power_supply_sysfs.c2
-rw-r--r--drivers/power/wm831x_backup.c1
-rw-r--r--drivers/power/wm831x_power.c1
-rw-r--r--drivers/power/wm8350_power.c26
-rw-r--r--drivers/power/wm97xx_battery.c1
-rw-r--r--drivers/pps/Kconfig2
-rw-r--r--drivers/pps/Makefile1
-rw-r--r--drivers/pps/clients/Kconfig25
-rw-r--r--drivers/pps/clients/Makefile10
-rw-r--r--drivers/pps/clients/pps-ktimer.c123
-rw-r--r--drivers/pps/clients/pps-ldisc.c154
-rw-r--r--drivers/pps/kapi.c1
-rw-r--r--drivers/ps3/ps3-lpm.c1
-rw-r--r--drivers/ps3/ps3-vuart.c1
-rw-r--r--drivers/ps3/ps3av.c1
-rw-r--r--drivers/regulator/88pm8607.c318
-rw-r--r--drivers/regulator/Kconfig8
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/core.c2
-rw-r--r--drivers/regulator/fixed.c1
-rw-r--r--drivers/regulator/lp3971.c11
-rw-r--r--drivers/regulator/max1586.c3
-rw-r--r--drivers/regulator/max8649.c4
-rw-r--r--drivers/regulator/max8660.c3
-rw-r--r--drivers/regulator/max8925-regulator.c308
-rw-r--r--drivers/regulator/mc13783-regulator.c4
-rw-r--r--drivers/regulator/tps65023-regulator.c1
-rw-r--r--drivers/regulator/tps6507x-regulator.c1
-rw-r--r--drivers/regulator/userspace-consumer.c1
-rw-r--r--drivers/regulator/virtual.c1
-rw-r--r--drivers/regulator/wm831x-dcdc.c1
-rw-r--r--drivers/regulator/wm831x-isink.c1
-rw-r--r--drivers/regulator/wm831x-ldo.c1
-rw-r--r--drivers/regulator/wm8350-regulator.c2
-rw-r--r--drivers/regulator/wm8994-regulator.c1
-rw-r--r--drivers/rtc/Kconfig10
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/class.c2
-rw-r--r--drivers/rtc/hctosys.c59
-rw-r--r--drivers/rtc/rtc-at32ap700x.c1
-rw-r--r--drivers/rtc/rtc-at91sam9.c3
-rw-r--r--drivers/rtc/rtc-bfin.c1
-rw-r--r--drivers/rtc/rtc-bq4802.c1
-rw-r--r--drivers/rtc/rtc-coh901331.c6
-rw-r--r--drivers/rtc/rtc-ds1216.c1
-rw-r--r--drivers/rtc/rtc-ds1286.c1
-rw-r--r--drivers/rtc/rtc-ds1305.c1
-rw-r--r--drivers/rtc/rtc-ds1374.c1
-rw-r--r--drivers/rtc/rtc-ds1390.c1
-rw-r--r--drivers/rtc/rtc-ds1511.c1
-rw-r--r--drivers/rtc/rtc-ds1553.c1
-rw-r--r--drivers/rtc/rtc-ds1742.c2
-rw-r--r--drivers/rtc/rtc-ep93xx.c72
-rw-r--r--drivers/rtc/rtc-fm3130.c1
-rw-r--r--drivers/rtc/rtc-m48t35.c1
-rw-r--r--drivers/rtc/rtc-m48t59.c1
-rw-r--r--drivers/rtc/rtc-max8925.c315
-rw-r--r--drivers/rtc/rtc-mc13783.c230
-rw-r--r--drivers/rtc/rtc-mpc5121.c1
-rw-r--r--drivers/rtc/rtc-msm6242.c1
-rw-r--r--drivers/rtc/rtc-mv.c1
-rw-r--r--drivers/rtc/rtc-mxc.c32
-rw-r--r--drivers/rtc/rtc-nuc900.c1
-rw-r--r--drivers/rtc/rtc-pcap.c1
-rw-r--r--drivers/rtc/rtc-pcf2123.c3
-rw-r--r--drivers/rtc/rtc-pcf50633.c1
-rw-r--r--drivers/rtc/rtc-pcf8563.c1
-rw-r--r--drivers/rtc/rtc-pl030.c1
-rw-r--r--drivers/rtc/rtc-pl031.c1
-rw-r--r--drivers/rtc/rtc-pxa.c1
-rw-r--r--drivers/rtc/rtc-rp5c01.c1
-rw-r--r--drivers/rtc/rtc-rs5c348.c1
-rw-r--r--drivers/rtc/rtc-rs5c372.c1
-rw-r--r--drivers/rtc/rtc-rx8025.c1
-rw-r--r--drivers/rtc/rtc-s3c.c1
-rw-r--r--drivers/rtc/rtc-sh.c1
-rw-r--r--drivers/rtc/rtc-stk17ta8.c1
-rw-r--r--drivers/rtc/rtc-stmp3xxx.c1
-rw-r--r--drivers/rtc/rtc-sysfs.c5
-rw-r--r--drivers/rtc/rtc-twl.c4
-rw-r--r--drivers/rtc/rtc-tx4939.c1
-rw-r--r--drivers/rtc/rtc-v3020.c1
-rw-r--r--drivers/rtc/rtc-wm831x.c1
-rw-r--r--drivers/rtc/rtc-wm8350.c11
-rw-r--r--drivers/s390/block/dasd.c39
-rw-r--r--drivers/s390/block/dasd_3990_erp.c19
-rw-r--r--drivers/s390/block/dasd_alias.c1
-rw-r--r--drivers/s390/block/dasd_devmap.c14
-rw-r--r--drivers/s390/block/dasd_diag.c6
-rw-r--r--drivers/s390/block/dasd_eckd.c31
-rw-r--r--drivers/s390/block/dasd_eer.c1
-rw-r--r--drivers/s390/block/dasd_fba.c10
-rw-r--r--drivers/s390/block/dasd_genhd.c3
-rw-r--r--drivers/s390/block/dasd_int.h7
-rw-r--r--drivers/s390/block/dasd_ioctl.c7
-rw-r--r--drivers/s390/block/dasd_proc.c1
-rw-r--r--drivers/s390/block/xpram.c2
-rw-r--r--drivers/s390/char/con3270.c1
-rw-r--r--drivers/s390/char/fs3270.c1
-rw-r--r--drivers/s390/char/keyboard.c1
-rw-r--r--drivers/s390/char/monreader.c1
-rw-r--r--drivers/s390/char/monwriter.c1
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/sclp.c2
-rw-r--r--drivers/s390/char/sclp_async.c2
-rw-r--r--drivers/s390/char/sclp_cmd.c7
-rw-r--r--drivers/s390/char/sclp_con.c1
-rw-r--r--drivers/s390/char/sclp_tty.c2
-rw-r--r--drivers/s390/char/sclp_vt220.c1
-rw-r--r--drivers/s390/char/tape_34xx.c1
-rw-r--r--drivers/s390/char/tape_3590.c1
-rw-r--r--drivers/s390/char/tape_class.c2
-rw-r--r--drivers/s390/char/tape_core.c1
-rw-r--r--drivers/s390/char/vmcp.c1
-rw-r--r--drivers/s390/char/vmlogrdr.c1
-rw-r--r--drivers/s390/char/vmur.c1
-rw-r--r--drivers/s390/char/vmwatchdog.c1
-rw-r--r--drivers/s390/char/zcore.c38
-rw-r--r--drivers/s390/cio/blacklist.c1
-rw-r--r--drivers/s390/cio/chp.c1
-rw-r--r--drivers/s390/cio/chsc.c29
-rw-r--r--drivers/s390/cio/chsc_sch.c3
-rw-r--r--drivers/s390/cio/cio.c18
-rw-r--r--drivers/s390/cio/css.c16
-rw-r--r--drivers/s390/cio/device.c5
-rw-r--r--drivers/s390/cio/device_fsm.c2
-rw-r--r--drivers/s390/cio/qdio_debug.c1
-rw-r--r--drivers/s390/cio/qdio_main.c4
-rw-r--r--drivers/s390/cio/qdio_thinint.c1
-rw-r--r--drivers/s390/crypto/ap_bus.c1
-rw-r--r--drivers/s390/crypto/zcrypt_api.c1
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c1
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c1
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.c1
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c1
-rw-r--r--drivers/s390/kvm/kvm_virtio.c1
-rw-r--r--drivers/s390/net/Kconfig10
-rw-r--r--drivers/s390/net/Makefile1
-rw-r--r--drivers/s390/net/ctcm_dbug.c1
-rw-r--r--drivers/s390/net/ctcm_sysfs.c1
-rw-r--r--drivers/s390/net/fsm.c1
-rw-r--r--drivers/s390/net/lcs.c1
-rw-r--r--drivers/s390/net/qeth_core.h3
-rw-r--r--drivers/s390/net/qeth_core_main.c9
-rw-r--r--drivers/s390/net/qeth_core_sys.c3
-rw-r--r--drivers/s390/net/qeth_l2_main.c17
-rw-r--r--drivers/s390/net/qeth_l3_main.c83
-rw-r--r--drivers/s390/net/qeth_l3_sys.c2
-rw-r--r--drivers/s390/net/smsgiucv.c16
-rw-r--r--drivers/s390/net/smsgiucv.h8
-rw-r--r--drivers/s390/net/smsgiucv_app.c212
-rw-r--r--drivers/s390/scsi/zfcp_aux.c1
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c1
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c1
-rw-r--r--drivers/s390/scsi/zfcp_fc.c1
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c7
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c3
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c1
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c1
-rw-r--r--drivers/sbus/char/bbc_envctrl.c1
-rw-r--r--drivers/sbus/char/display7seg.c1
-rw-r--r--drivers/sbus/char/envctrl.c1
-rw-r--r--drivers/sbus/char/flash.c1
-rw-r--r--drivers/sbus/char/jsflash.c1
-rw-r--r--drivers/scsi/3w-9xxx.c1
-rw-r--r--drivers/scsi/3w-sas.c1
-rw-r--r--drivers/scsi/3w-xxxx.c1
-rw-r--r--drivers/scsi/53c700.c1
-rw-r--r--drivers/scsi/BusLogic.c1
-rw-r--r--drivers/scsi/Kconfig6
-rw-r--r--drivers/scsi/NCR_D700.c1
-rw-r--r--drivers/scsi/NCR_Q720.c1
-rw-r--r--drivers/scsi/a100u2w.c3
-rw-r--r--drivers/scsi/a2091.c1
-rw-r--r--drivers/scsi/a3000.c1
-rw-r--r--drivers/scsi/a4000t.c1
-rw-r--r--drivers/scsi/aacraid/rx.c1
-rw-r--r--drivers/scsi/aacraid/sa.c1
-rw-r--r--drivers/scsi/advansys.c8
-rw-r--r--drivers/scsi/aha152x.c1
-rw-r--r--drivers/scsi/aha1542.c1
-rw-r--r--drivers/scsi/aha1740.c1
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_hwi.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_scb.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sds.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_seq.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_tmf.c1
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c1
-rw-r--r--drivers/scsi/atari_NCR5380.c1
-rw-r--r--drivers/scsi/atp870u.c1
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c7
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c4
-rw-r--r--drivers/scsi/be2iscsi/be_main.c202
-rw-r--r--drivers/scsi/be2iscsi/be_main.h11
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c15
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h8
-rw-r--r--drivers/scsi/bfa/Makefile8
-rw-r--r--drivers/scsi/bfa/bfa_core.c19
-rw-r--r--drivers/scsi/bfa/bfa_fcport.c1709
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c63
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c75
-rw-r--r--drivers/scsi/bfa/bfa_fcs_port.c11
-rw-r--r--drivers/scsi/bfa/bfa_fcs_uf.c8
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c13
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c9
-rw-r--r--drivers/scsi/bfa/bfa_intr.c111
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c762
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h57
-rw-r--r--drivers/scsi/bfa/bfa_ioc_cb.c274
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c423
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.c24
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.h3
-rw-r--r--drivers/scsi/bfa/bfa_ioim.c22
-rw-r--r--drivers/scsi/bfa/bfa_itnim.c30
-rw-r--r--drivers/scsi/bfa/bfa_lps.c134
-rw-r--r--drivers/scsi/bfa/bfa_module.c4
-rw-r--r--drivers/scsi/bfa/bfa_modules_priv.h2
-rw-r--r--drivers/scsi/bfa/bfa_port_priv.h57
-rw-r--r--drivers/scsi/bfa/bfa_priv.h2
-rw-r--r--drivers/scsi/bfa/bfa_rport.c26
-rw-r--r--drivers/scsi/bfa/bfa_trcmod_priv.h62
-rw-r--r--drivers/scsi/bfa/bfa_tskim.c14
-rw-r--r--drivers/scsi/bfa/bfad.c209
-rw-r--r--drivers/scsi/bfa/bfad_attr.c77
-rw-r--r--drivers/scsi/bfa/bfad_attr.h9
-rw-r--r--drivers/scsi/bfa/bfad_drv.h35
-rw-r--r--drivers/scsi/bfa/bfad_im.c54
-rw-r--r--drivers/scsi/bfa/bfad_im.h5
-rw-r--r--drivers/scsi/bfa/bfad_intr.c11
-rw-r--r--drivers/scsi/bfa/fabric.c59
-rw-r--r--drivers/scsi/bfa/fcbuild.h6
-rw-r--r--drivers/scsi/bfa/fcpim.c51
-rw-r--r--drivers/scsi/bfa/fcs_fabric.h2
-rw-r--r--drivers/scsi/bfa/fcs_fcpim.h5
-rw-r--r--drivers/scsi/bfa/fcs_lport.h7
-rw-r--r--drivers/scsi/bfa/fcs_port.h3
-rw-r--r--drivers/scsi/bfa/fcs_rport.h3
-rw-r--r--drivers/scsi/bfa/fcs_uf.h3
-rw-r--r--drivers/scsi/bfa/fcs_vport.h8
-rw-r--r--drivers/scsi/bfa/fdmi.c79
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen.h50
-rw-r--r--drivers/scsi/bfa/include/bfa.h22
-rw-r--r--drivers/scsi/bfa/include/bfa_svc.h101
-rw-r--r--drivers/scsi/bfa/include/bfa_timer.h2
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi.h4
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_cbreg.h16
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ctreg.h26
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ioc.h2
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_lps.h8
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_pport.h172
-rw-r--r--drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h4
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_log.h2
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_plog.h9
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_sm.h8
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_aen.h10
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_auth.h22
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_cee.h14
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_driver.h3
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ethport.h1
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_fcport.h94
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_im_common.h32
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_im_team.h72
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ioc.h3
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h12
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_lport.h4
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_mfg.h111
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_port.h19
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pport.h151
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_status.h17
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h1
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs.h5
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h8
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_hal.h6
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_linux.h16
-rw-r--r--drivers/scsi/bfa/include/protocol/fc.h5
-rw-r--r--drivers/scsi/bfa/include/protocol/pcifw.h75
-rw-r--r--drivers/scsi/bfa/loop.c2
-rw-r--r--drivers/scsi/bfa/lport_api.c5
-rw-r--r--drivers/scsi/bfa/ms.c29
-rw-r--r--drivers/scsi/bfa/ns.c36
-rw-r--r--drivers/scsi/bfa/rport.c92
-rw-r--r--drivers/scsi/bfa/rport_api.c2
-rw-r--r--drivers/scsi/bfa/rport_ftrs.c12
-rw-r--r--drivers/scsi/bfa/scn.c10
-rw-r--r--drivers/scsi/bfa/vport.c86
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h2
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c1
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c13
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c16
-rw-r--r--drivers/scsi/bvme6000_scsi.c1
-rw-r--r--drivers/scsi/ch.c1
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c1
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.h1
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c3
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c1
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.c1
-rw-r--r--drivers/scsi/dc395x.c1
-rw-r--r--drivers/scsi/device_handler/scsi_dh.c1
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c1
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c7
-rw-r--r--drivers/scsi/device_handler/scsi_dh_hp_sw.c1
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c1
-rw-r--r--drivers/scsi/dpt_i2o.c15
-rw-r--r--drivers/scsi/eata.c1
-rw-r--r--drivers/scsi/eata_pio.c1
-rw-r--r--drivers/scsi/fcoe/fcoe.c1
-rw-r--r--drivers/scsi/fcoe/libfcoe.c1
-rw-r--r--drivers/scsi/fd_mcs.c1
-rw-r--r--drivers/scsi/fdomain.c1
-rw-r--r--drivers/scsi/fnic/fnic_fcs.c1
-rw-r--r--drivers/scsi/fnic/fnic_main.c1
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c1
-rw-r--r--drivers/scsi/fnic/vnic_dev.c1
-rw-r--r--drivers/scsi/fnic/vnic_rq.c1
-rw-r--r--drivers/scsi/fnic/vnic_wq.c1
-rw-r--r--drivers/scsi/gdth.c1
-rw-r--r--drivers/scsi/gdth_proc.c1
-rw-r--r--drivers/scsi/gvp11.c1
-rw-r--r--drivers/scsi/hosts.c1
-rw-r--r--drivers/scsi/hpsa.c330
-rw-r--r--drivers/scsi/hpsa.h7
-rw-r--r--drivers/scsi/hpsa_cmd.h20
-rw-r--r--drivers/scsi/hptiop.c1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c28
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c49
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.h1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvstgt.c1
-rw-r--r--drivers/scsi/ibmvscsi/iseries_vscsi.c6
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c14
-rw-r--r--drivers/scsi/imm.c1
-rw-r--r--drivers/scsi/initio.c2
-rw-r--r--drivers/scsi/ipr.c1757
-rw-r--r--drivers/scsi/ipr.h467
-rw-r--r--drivers/scsi/iscsi_tcp.c5
-rw-r--r--drivers/scsi/jazz_esp.c1
-rw-r--r--drivers/scsi/lasi700.c1
-rw-r--r--drivers/scsi/libfc/fc_disc.c1
-rw-r--r--drivers/scsi/libfc/fc_exch.c2
-rw-r--r--drivers/scsi/libfc/fc_fcp.c5
-rw-r--r--drivers/scsi/libfc/fc_frame.c1
-rw-r--r--drivers/scsi/libfc/fc_lport.c1
-rw-r--r--drivers/scsi/libfc/fc_rport.c1
-rw-r--r--drivers/scsi/libiscsi.c29
-rw-r--r--drivers/scsi/libiscsi_tcp.c1
-rw-r--r--drivers/scsi/libsas/sas_ata.c1
-rw-r--r--drivers/scsi/libsas/sas_discover.c1
-rw-r--r--drivers/scsi/libsas/sas_expander.c1
-rw-r--r--drivers/scsi/libsas/sas_host_smp.c1
-rw-r--r--drivers/scsi/libsas/sas_init.c1
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c1
-rw-r--r--drivers/scsi/libsrp.c1
-rw-r--r--drivers/scsi/lpfc/lpfc.h10
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c337
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.h12
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h7
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c1
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c147
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c528
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c278
-rw-r--r--drivers/scsi/lpfc/lpfc_logmsg.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c1
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c1
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c54
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c414
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h38
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c8
-rw-r--r--drivers/scsi/mac_esp.c1
-rw-r--r--drivers/scsi/megaraid.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c1
-rw-r--r--drivers/scsi/mesh.c1
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c1
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c1
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c1
-rw-r--r--drivers/scsi/mvme16x_scsi.c1
-rw-r--r--drivers/scsi/mvsas/mv_sas.h1
-rw-r--r--drivers/scsi/ncr53c8xx.c1
-rw-r--r--drivers/scsi/nsp32.c1
-rw-r--r--drivers/scsi/osd/osd_initiator.c6
-rw-r--r--drivers/scsi/osd/osd_uld.c1
-rw-r--r--drivers/scsi/osst.c1
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c1
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h2
-rw-r--r--drivers/scsi/pm8001/pm8001_ctl.c1
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c3
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c1
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c3
-rw-r--r--drivers/scsi/pmcraid.c1
-rw-r--r--drivers/scsi/pmcraid.h2
-rw-r--r--drivers/scsi/ppa.c1
-rw-r--r--drivers/scsi/ps3rom.c1
-rw-r--r--drivers/scsi/qla1280.c162
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h18
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c38
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c9
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c1
-rw-r--r--drivers/scsi/qlogicpti.c4
-rw-r--r--drivers/scsi/raid_class.c2
-rw-r--r--drivers/scsi/scsi_debug.c1
-rw-r--r--drivers/scsi/scsi_devinfo.c1
-rw-r--r--drivers/scsi/scsi_error.c1
-rw-r--r--drivers/scsi/scsi_netlink.c1
-rw-r--r--drivers/scsi/scsi_proc.c2
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/scsi_sysfs.c1
-rw-r--r--drivers/scsi/scsi_tgt_if.c1
-rw-r--r--drivers/scsi/scsi_tgt_lib.c1
-rw-r--r--drivers/scsi/scsi_transport_fc.c29
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c1
-rw-r--r--drivers/scsi/scsi_transport_spi.c1
-rw-r--r--drivers/scsi/scsicam.c1
-rw-r--r--drivers/scsi/sd.c9
-rw-r--r--drivers/scsi/ses.c5
-rw-r--r--drivers/scsi/sg.c1
-rw-r--r--drivers/scsi/sgiwd93.c2
-rw-r--r--drivers/scsi/sim710.c1
-rw-r--r--drivers/scsi/sni_53c710.c3
-rw-r--r--drivers/scsi/sr.c1
-rw-r--r--drivers/scsi/sr_ioctl.c1
-rw-r--r--drivers/scsi/sr_vendor.c1
-rw-r--r--drivers/scsi/st.c1
-rw-r--r--drivers/scsi/stex.c1
-rw-r--r--drivers/scsi/sun3_NCR5380.c1
-rw-r--r--drivers/scsi/sun3x_esp.c1
-rw-r--r--drivers/scsi/sun_esp.c1
-rw-r--r--drivers/scsi/tmscsim.c1
-rw-r--r--drivers/scsi/u14-34f.c1
-rw-r--r--drivers/scsi/vmw_pvscsi.c1
-rw-r--r--drivers/scsi/wd7000.c3
-rw-r--r--drivers/scsi/zorro7xx.c1
-rw-r--r--drivers/serial/68328serial.c1
-rw-r--r--drivers/serial/8250.c17
-rw-r--r--drivers/serial/8250_gsc.c1
-rw-r--r--drivers/serial/8250_hp300.c1
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/Kconfig35
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/amba-pl010.c16
-rw-r--r--drivers/serial/amba-pl011.c1
-rw-r--r--drivers/serial/bfin_5xx.c1
-rw-r--r--drivers/serial/bfin_sport_uart.c1
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c1
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c5
-rw-r--r--drivers/serial/imx.c3
-rw-r--r--drivers/serial/ioc3_serial.c1
-rw-r--r--drivers/serial/ioc4_serial.c1
-rw-r--r--drivers/serial/jsm/jsm_driver.c1
-rw-r--r--drivers/serial/jsm/jsm_tty.c1
-rw-r--r--drivers/serial/max3100.c1
-rw-r--r--drivers/serial/mcf.c6
-rw-r--r--drivers/serial/mpc52xx_uart.c33
-rw-r--r--drivers/serial/mpsc.c1
-rw-r--r--drivers/serial/mux.c1
-rw-r--r--drivers/serial/of_serial.c1
-rw-r--r--drivers/serial/pmac_zilog.c5
-rw-r--r--drivers/serial/pxa.c1
-rw-r--r--drivers/serial/s3c2412.c1
-rw-r--r--drivers/serial/s5pv210.c154
-rw-r--r--drivers/serial/samsung.c8
-rw-r--r--drivers/serial/samsung.h19
-rw-r--r--drivers/serial/serial_cs.c10
-rw-r--r--drivers/serial/serial_ks8695.c1
-rw-r--r--drivers/serial/sh-sci.c612
-rw-r--r--drivers/serial/sh-sci.h43
-rw-r--r--drivers/serial/sunsab.c2
-rw-r--r--drivers/serial/sunsu.c5
-rw-r--r--drivers/serial/timbuart.c1
-rw-r--r--drivers/serial/uartlite.c10
-rw-r--r--drivers/serial/ucc_uart.c1
-rw-r--r--drivers/sh/intc.c42
-rw-r--r--drivers/sn/ioc3.c1
-rw-r--r--drivers/spi/amba-pl022.c1
-rw-r--r--drivers/spi/atmel_spi.c1
-rw-r--r--drivers/spi/au1550_spi.c1
-rw-r--r--drivers/spi/davinci_spi.c1
-rw-r--r--drivers/spi/dw_spi.c1
-rw-r--r--drivers/spi/dw_spi_mmio.c1
-rw-r--r--drivers/spi/dw_spi_pci.c1
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c1
-rw-r--r--drivers/spi/mpc52xx_spi.c1
-rw-r--r--drivers/spi/omap2_mcspi.c24
-rw-r--r--drivers/spi/omap_spi_100k.c1
-rw-r--r--drivers/spi/omap_uwire.c1
-rw-r--r--drivers/spi/pxa2xx_spi.c1
-rw-r--r--drivers/spi/spi.c9
-rw-r--r--drivers/spi/spi_bfin5xx.c1
-rw-r--r--drivers/spi/spi_bitbang.c1
-rw-r--r--drivers/spi/spi_imx.c1
-rw-r--r--drivers/spi/spi_mpc8xxx.c1
-rw-r--r--drivers/spi/spi_nuc900.c1
-rw-r--r--drivers/spi/spi_ppc4xx.c1
-rw-r--r--drivers/spi/spi_s3c24xx.c3
-rw-r--r--drivers/spi/tle62x0.c1
-rw-r--r--drivers/spi/xilinx_spi_of.c1
-rw-r--r--drivers/ssb/driver_gige.c1
-rw-r--r--drivers/ssb/driver_pcicore.c29
-rw-r--r--drivers/ssb/main.c1
-rw-r--r--drivers/ssb/pci.c1
-rw-r--r--drivers/ssb/pcihost_wrapper.c1
-rw-r--r--drivers/ssb/sprom.c1
-rw-r--r--drivers/staging/Kconfig14
-rw-r--r--drivers/staging/Makefile8
-rw-r--r--drivers/staging/altpciechdma/Kconfig10
-rw-r--r--drivers/staging/altpciechdma/Makefile2
-rw-r--r--drivers/staging/altpciechdma/TODO15
-rw-r--r--drivers/staging/altpciechdma/altpciechdma.c1182
-rw-r--r--drivers/staging/arlan/Makefile2
-rw-r--r--drivers/staging/arlan/arlan.h136
-rw-r--r--drivers/staging/asus_oled/asus_oled.c34
-rw-r--r--drivers/staging/b3dfg/Kconfig10
-rw-r--r--drivers/staging/b3dfg/Makefile1
-rw-r--r--drivers/staging/b3dfg/TODO4
-rw-r--r--drivers/staging/b3dfg/b3dfg.c1100
-rw-r--r--drivers/staging/batman-adv/Kconfig6
-rw-r--r--drivers/staging/batman-adv/Makefile2
-rw-r--r--drivers/staging/batman-adv/README84
-rw-r--r--drivers/staging/batman-adv/TODO24
-rw-r--r--drivers/staging/batman-adv/aggregation.c13
-rw-r--r--drivers/staging/batman-adv/bitarray.c15
-rw-r--r--drivers/staging/batman-adv/compat.h75
-rw-r--r--drivers/staging/batman-adv/device.c54
-rw-r--r--drivers/staging/batman-adv/hard-interface.c209
-rw-r--r--drivers/staging/batman-adv/hard-interface.h4
-rw-r--r--drivers/staging/batman-adv/hash.c23
-rw-r--r--drivers/staging/batman-adv/hash.h5
-rw-r--r--drivers/staging/batman-adv/log.c179
-rw-r--r--drivers/staging/batman-adv/log.h32
-rw-r--r--drivers/staging/batman-adv/main.c55
-rw-r--r--drivers/staging/batman-adv/main.h47
-rw-r--r--drivers/staging/batman-adv/originator.c252
-rw-r--r--drivers/staging/batman-adv/originator.h31
-rw-r--r--drivers/staging/batman-adv/packet.h2
-rw-r--r--drivers/staging/batman-adv/proc.c508
-rw-r--r--drivers/staging/batman-adv/proc.h13
-rw-r--r--drivers/staging/batman-adv/routing.c1304
-rw-r--r--drivers/staging/batman-adv/routing.h21
-rw-r--r--drivers/staging/batman-adv/send.c172
-rw-r--r--drivers/staging/batman-adv/send.h5
-rw-r--r--drivers/staging/batman-adv/soft-interface.c97
-rw-r--r--drivers/staging/batman-adv/soft-interface.h3
-rw-r--r--drivers/staging/batman-adv/translation-table.c94
-rw-r--r--drivers/staging/batman-adv/translation-table.h1
-rw-r--r--drivers/staging/batman-adv/types.h14
-rw-r--r--drivers/staging/batman-adv/vis.c201
-rw-r--r--drivers/staging/batman-adv/vis.h13
-rw-r--r--drivers/staging/comedi/comedi_compat32.c1
-rw-r--r--drivers/staging/comedi/comedi_fops.c12
-rw-r--r--drivers/staging/comedi/drivers.c30
-rw-r--r--drivers/staging/comedi/drivers/8255.c1
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c7
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_eeprom.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c12
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c121
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c6
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c7
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c66
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c21
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c4
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c123
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c46
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c17
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c57
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c1
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c28
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c12
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidio.c6
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c8
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdda.c8
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c3
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c3
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c5
-rw-r--r--drivers/staging/comedi/drivers/das16.c1
-rw-r--r--drivers/staging/comedi/drivers/das1800.c1
-rw-r--r--drivers/staging/comedi/drivers/das6402.c2
-rw-r--r--drivers/staging/comedi/drivers/das800.c6
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c5
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c33
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c89
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c1
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c2
-rw-r--r--drivers/staging/comedi/drivers/fl512.c72
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c3
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c50
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c73
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c33
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c34
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c25
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c277
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c83
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c29
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c26
-rw-r--r--drivers/staging/comedi/drivers/pcl725.c6
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c6
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c17
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c67
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c40
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c85
-rw-r--r--drivers/staging/comedi/drivers/pcm3730.c6
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c22
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c3
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c1
-rw-r--r--drivers/staging/comedi/drivers/poc.c14
-rw-r--r--drivers/staging/comedi/drivers/rti800.c61
-rw-r--r--drivers/staging/comedi/drivers/rti802.c8
-rw-r--r--drivers/staging/comedi/drivers/s626.c2
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c3
-rw-r--r--drivers/staging/comedi/drivers/ssv_dnp.c6
-rw-r--r--drivers/staging/comedi/drivers/unioxx5.c1
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c5
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c5
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c2
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c1
-rw-r--r--drivers/staging/comedi/kcomedilib/ksyms.c1
-rw-r--r--drivers/staging/crystalhd/Kconfig6
-rw-r--r--drivers/staging/crystalhd/Makefile6
-rw-r--r--drivers/staging/crystalhd/TODO16
-rw-r--r--drivers/staging/crystalhd/bc_dts_defs.h498
-rw-r--r--drivers/staging/crystalhd/bc_dts_glob_lnx.h299
-rw-r--r--drivers/staging/crystalhd/bc_dts_types.h121
-rw-r--r--drivers/staging/crystalhd/bcm_70012_regs.h757
-rw-r--r--drivers/staging/crystalhd/crystalhd_cmds.c1058
-rw-r--r--drivers/staging/crystalhd/crystalhd_cmds.h88
-rw-r--r--drivers/staging/crystalhd/crystalhd_fw_if.h369
-rw-r--r--drivers/staging/crystalhd/crystalhd_hw.c2396
-rw-r--r--drivers/staging/crystalhd/crystalhd_hw.h398
-rw-r--r--drivers/staging/crystalhd/crystalhd_lnx.c766
-rw-r--r--drivers/staging/crystalhd/crystalhd_lnx.h96
-rw-r--r--drivers/staging/crystalhd/crystalhd_misc.c1032
-rw-r--r--drivers/staging/crystalhd/crystalhd_misc.h229
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c1
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c1
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c5
-rw-r--r--drivers/staging/cx25821/cx25821-core.c1
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c4
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.c1
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c1
-rw-r--r--drivers/staging/cx25821/cx25821-video.c5
-rw-r--r--drivers/staging/dream/camera/Kconfig2
-rw-r--r--drivers/staging/dream/camera/Makefile1
-rw-r--r--drivers/staging/dream/camera/msm_camera.c70
-rw-r--r--drivers/staging/dream/camera/msm_v4l2.c1
-rw-r--r--drivers/staging/dream/camera/msm_vfe7x.c4
-rw-r--r--drivers/staging/dream/camera/msm_vfe8x.c1
-rw-r--r--drivers/staging/dream/camera/mt9d112.c1
-rw-r--r--drivers/staging/dream/camera/mt9p012_fox.c1
-rw-r--r--drivers/staging/dream/camera/mt9t013.c1
-rw-r--r--drivers/staging/dream/camera/s5k3e2fx.c31
-rw-r--r--drivers/staging/dream/gpio_axis.c1
-rw-r--r--drivers/staging/dream/gpio_event.c1
-rw-r--r--drivers/staging/dream/gpio_input.c1
-rw-r--r--drivers/staging/dream/gpio_matrix.c1
-rw-r--r--drivers/staging/dream/include/linux/android_pmem.h80
-rw-r--r--drivers/staging/dream/include/linux/gpio_event.h154
-rw-r--r--drivers/staging/dream/include/linux/msm_adsp.h84
-rw-r--r--drivers/staging/dream/include/linux/msm_audio.h115
-rw-r--r--drivers/staging/dream/include/linux/msm_rpcrouter.h47
-rw-r--r--drivers/staging/dream/include/linux/wakelock.h91
-rw-r--r--drivers/staging/dream/include/mach/camera.h279
-rw-r--r--drivers/staging/dream/include/mach/msm_adsp.h112
-rw-r--r--drivers/staging/dream/include/mach/msm_rpcrouter.h179
-rw-r--r--drivers/staging/dream/include/mach/msm_smd.h107
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h94
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h70
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h914
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h318
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h256
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h85
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h176
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h127
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h376
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h177
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h82
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h80
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h235
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h107
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h212
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h910
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h290
-rw-r--r--drivers/staging/dream/include/media/msm_camera.h388
-rw-r--r--drivers/staging/dream/pmem.c27
-rw-r--r--drivers/staging/dream/qdsp5/Makefile1
-rw-r--r--drivers/staging/dream/qdsp5/adsp.c1
-rw-r--r--drivers/staging/dream/qdsp5/adsp_driver.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_aac.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_amrnb.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_evrc.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_in.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_mp3.c4
-rw-r--r--drivers/staging/dream/qdsp5/audio_out.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_qcelp.c1
-rw-r--r--drivers/staging/dream/qdsp5/audmgr.c1
-rw-r--r--drivers/staging/dream/smd/Makefile1
-rw-r--r--drivers/staging/dream/smd/smd_rpcrouter.c3
-rw-r--r--drivers/staging/dream/smd/smd_rpcrouter_device.c1
-rw-r--r--drivers/staging/dream/smd/smd_rpcrouter_servers.c1
-rw-r--r--drivers/staging/dream/synaptics_i2c_rmi.c1
-rw-r--r--drivers/staging/dt3155/Kconfig4
-rw-r--r--drivers/staging/dt3155/Makefile6
-rw-r--r--drivers/staging/dt3155/TODO10
-rw-r--r--drivers/staging/dt3155/allocator.README98
-rw-r--r--drivers/staging/dt3155/allocator.c296
-rw-r--r--drivers/staging/dt3155/allocator.h28
-rw-r--r--drivers/staging/dt3155/dt3155.h171
-rw-r--r--drivers/staging/dt3155/dt3155.sysvinit60
-rw-r--r--drivers/staging/dt3155/dt3155_drv.c1087
-rw-r--r--drivers/staging/dt3155/dt3155_drv.h45
-rw-r--r--drivers/staging/dt3155/dt3155_io.c175
-rw-r--r--drivers/staging/dt3155/dt3155_io.h358
-rw-r--r--drivers/staging/dt3155/dt3155_isr.c516
-rw-r--r--drivers/staging/dt3155/dt3155_isr.h77
-rw-r--r--drivers/staging/et131x/et1310_address_map.h617
-rw-r--r--drivers/staging/et131x/et1310_eeprom.c42
-rw-r--r--drivers/staging/et131x/et1310_eeprom.h103
-rw-r--r--drivers/staging/et131x/et1310_jagcore.h94
-rw-r--r--drivers/staging/et131x/et1310_mac.c105
-rw-r--r--drivers/staging/et131x/et1310_mac.h93
-rw-r--r--drivers/staging/et131x/et1310_phy.c8
-rw-r--r--drivers/staging/et131x/et1310_phy.h34
-rw-r--r--drivers/staging/et131x/et1310_pm.c7
-rw-r--r--drivers/staging/et131x/et1310_pm.h85
-rw-r--r--drivers/staging/et131x/et1310_rx.c301
-rw-r--r--drivers/staging/et131x/et1310_rx.h253
-rw-r--r--drivers/staging/et131x/et1310_tx.c10
-rw-r--r--drivers/staging/et131x/et1310_tx.h14
-rw-r--r--drivers/staging/et131x/et131x.h153
-rw-r--r--drivers/staging/et131x/et131x_adapter.h43
-rw-r--r--drivers/staging/et131x/et131x_config.h67
-rw-r--r--drivers/staging/et131x/et131x_initpci.c13
-rw-r--r--drivers/staging/et131x/et131x_initpci.h73
-rw-r--r--drivers/staging/et131x/et131x_isr.c35
-rw-r--r--drivers/staging/et131x/et131x_isr.h65
-rw-r--r--drivers/staging/et131x/et131x_netdev.c64
-rw-r--r--drivers/staging/et131x/et131x_netdev.h64
-rw-r--r--drivers/staging/et131x/et131x_version.h9
-rw-r--r--drivers/staging/frontier/alphatrack.c2
-rw-r--r--drivers/staging/frontier/tranzport.c2
-rw-r--r--drivers/staging/go7007/go7007-driver.c3
-rw-r--r--drivers/staging/go7007/go7007-fw.c1
-rw-r--r--drivers/staging/go7007/go7007-usb.c4
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c1
-rw-r--r--drivers/staging/go7007/s2250-board.c3
-rw-r--r--drivers/staging/go7007/s2250-loader.c5
-rw-r--r--drivers/staging/go7007/saa7134-go7007.c1
-rw-r--r--drivers/staging/go7007/snd-go7007.c1
-rw-r--r--drivers/staging/go7007/wis-ov7640.c2
-rw-r--r--drivers/staging/go7007/wis-saa7113.c3
-rw-r--r--drivers/staging/go7007/wis-saa7115.c3
-rw-r--r--drivers/staging/go7007/wis-sony-tuner.c3
-rw-r--r--drivers/staging/go7007/wis-tw2804.c3
-rw-r--r--drivers/staging/go7007/wis-tw9903.c3
-rw-r--r--drivers/staging/go7007/wis-uda1342.c2
-rw-r--r--drivers/staging/hv/Channel.c4
-rw-r--r--drivers/staging/hv/ChannelMgmt.c1
-rw-r--r--drivers/staging/hv/Connection.c1
-rw-r--r--drivers/staging/hv/Hv.c208
-rw-r--r--drivers/staging/hv/Hv.h10
-rw-r--r--drivers/staging/hv/NetVsc.c1
-rw-r--r--drivers/staging/hv/NetVscApi.h4
-rw-r--r--drivers/staging/hv/RingBuffer.c153
-rw-r--r--drivers/staging/hv/RndisFilter.c12
-rw-r--r--drivers/staging/hv/StorVsc.c4
-rw-r--r--drivers/staging/hv/StorVscApi.h5
-rw-r--r--drivers/staging/hv/VersionInfo.h22
-rw-r--r--drivers/staging/hv/Vmbus.c7
-rw-r--r--drivers/staging/hv/blkvsc_drv.c11
-rw-r--r--drivers/staging/hv/netvsc_drv.c33
-rw-r--r--drivers/staging/hv/osd.c1
-rw-r--r--drivers/staging/hv/storvsc_drv.c228
-rw-r--r--drivers/staging/hv/vmbus.h12
-rw-r--r--drivers/staging/hv/vmbus_drv.c69
-rw-r--r--drivers/staging/iio/accel/kxsd9.c1
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c3
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c4
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c1
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c1
-rw-r--r--drivers/staging/iio/adc/max1363_core.c3
-rw-r--r--drivers/staging/iio/adc/max1363_ring.c1
-rw-r--r--drivers/staging/iio/industrialio-core.c39
-rw-r--r--drivers/staging/iio/industrialio-ring.c1
-rw-r--r--drivers/staging/iio/industrialio-trigger.c1
-rw-r--r--drivers/staging/iio/light/tsl2563.c3
-rw-r--r--drivers/staging/iio/ring_generic.h3
-rw-r--r--drivers/staging/iio/ring_sw.c6
-rw-r--r--drivers/staging/iio/trigger/iio-trig-gpio.c1
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c1
-rw-r--r--drivers/staging/iio/trigger_consumer.h4
-rw-r--r--drivers/staging/line6/capture.c2
-rw-r--r--drivers/staging/line6/driver.c3
-rw-r--r--drivers/staging/line6/dumprequest.c3
-rw-r--r--drivers/staging/line6/midi.c1
-rw-r--r--drivers/staging/line6/pcm.c2
-rw-r--r--drivers/staging/line6/playback.c2
-rw-r--r--drivers/staging/line6/pod.c2
-rw-r--r--drivers/staging/line6/variax.c4
-rw-r--r--drivers/staging/mimio/Kconfig10
-rw-r--r--drivers/staging/mimio/Makefile1
-rw-r--r--drivers/staging/mimio/mimio.c914
-rw-r--r--drivers/staging/netwave/netwave_cs.c1
-rw-r--r--drivers/staging/octeon/ethernet-mem.c1
-rw-r--r--drivers/staging/octeon/ethernet.c1
-rw-r--r--drivers/staging/otus/80211core/cagg.c18
-rw-r--r--drivers/staging/otus/80211core/ccmd.c2
-rw-r--r--drivers/staging/otus/80211core/cfunc.c2
-rw-r--r--drivers/staging/otus/80211core/cmm.c4
-rw-r--r--drivers/staging/otus/80211core/cmmsta.c7
-rw-r--r--drivers/staging/otus/80211core/cpsmgr.c2
-rw-r--r--drivers/staging/otus/80211core/cscanmgr.c2
-rw-r--r--drivers/staging/otus/80211core/ctkip.c5
-rw-r--r--drivers/staging/otus/80211core/ctxrx.c8
-rw-r--r--drivers/staging/otus/80211core/ledmgr.c1
-rw-r--r--drivers/staging/otus/80211core/pub_zfi.h1
-rw-r--r--drivers/staging/otus/Kconfig2
-rw-r--r--drivers/staging/otus/apdbg.c53
-rw-r--r--drivers/staging/otus/hal/hpmain.c4
-rw-r--r--drivers/staging/otus/hal/hpreg.c133
-rw-r--r--drivers/staging/otus/hal/hprw.c1
-rw-r--r--drivers/staging/otus/ioctl.c17
-rw-r--r--drivers/staging/otus/usbdrv.c5
-rw-r--r--drivers/staging/otus/usbdrv.h1
-rw-r--r--drivers/staging/otus/wrap_mem.c1
-rw-r--r--drivers/staging/otus/wrap_pkt.c11
-rw-r--r--drivers/staging/otus/wrap_usb.c1
-rw-r--r--drivers/staging/otus/wwrap.c1
-rw-r--r--drivers/staging/otus/zdusb.c3
-rw-r--r--drivers/staging/p9auth/Kconfig9
-rw-r--r--drivers/staging/p9auth/Makefile1
-rw-r--r--drivers/staging/p9auth/p9auth.c408
-rw-r--r--drivers/staging/panel/panel.c1
-rw-r--r--drivers/staging/phison/phison.c2
-rw-r--r--drivers/staging/poch/poch.c1
-rw-r--r--drivers/staging/pohmelfs/config.c1
-rw-r--r--drivers/staging/pohmelfs/dir.c1
-rw-r--r--drivers/staging/pohmelfs/inode.c30
-rw-r--r--drivers/staging/pohmelfs/lock.c1
-rw-r--r--drivers/staging/pohmelfs/net.c1
-rw-r--r--drivers/staging/pohmelfs/netfs.h3
-rw-r--r--drivers/staging/pohmelfs/path_entry.c1
-rw-r--r--drivers/staging/quatech_usb2/quatech_usb2.c2
-rw-r--r--drivers/staging/ramzswap/Kconfig2
-rw-r--r--drivers/staging/ramzswap/ramzswap.txt6
-rw-r--r--drivers/staging/ramzswap/ramzswap_drv.c145
-rw-r--r--drivers/staging/ramzswap/ramzswap_drv.h67
-rw-r--r--drivers/staging/ramzswap/ramzswap_ioctl.h7
-rw-r--r--drivers/staging/ramzswap/xvmalloc.c4
-rw-r--r--drivers/staging/ramzswap/xvmalloc.h2
-rw-r--r--drivers/staging/ramzswap/xvmalloc_int.h4
-rw-r--r--drivers/staging/rar/Kconfig17
-rw-r--r--drivers/staging/rar/Makefile2
-rw-r--r--drivers/staging/rar/rar_driver.c444
-rw-r--r--drivers/staging/rar/rar_driver.h99
-rw-r--r--drivers/staging/rar_register/Kconfig30
-rw-r--r--drivers/staging/rar_register/Makefile2
-rw-r--r--drivers/staging/rar_register/rar_register.c615
-rw-r--r--drivers/staging/rar_register/rar_register.h84
-rw-r--r--drivers/staging/rt2860/Kconfig2
-rw-r--r--drivers/staging/rt2860/common/firmware.h558
-rw-r--r--drivers/staging/rt2860/common/firmware_3070.h517
-rw-r--r--drivers/staging/rt2860/common/rtmp_mcu.c167
-rw-r--r--drivers/staging/rt2860/pci_main_dev.c1
-rw-r--r--drivers/staging/rt2860/rt_linux.c14
-rw-r--r--drivers/staging/rt2860/rt_linux.h4
-rw-r--r--drivers/staging/rt2860/rt_main_dev.c2
-rw-r--r--drivers/staging/rt2860/rtmp.h7
-rw-r--r--drivers/staging/rt2860/sta/connect.c4
-rw-r--r--drivers/staging/rt2860/sta_ioctl.c5
-rw-r--r--drivers/staging/rt2860/usb_main_dev.c7
-rw-r--r--drivers/staging/rt2870/Kconfig2
-rw-r--r--drivers/staging/rt2870/common/rtusb_io.c10
-rw-r--r--drivers/staging/rt3070/firmware.h558
-rw-r--r--drivers/staging/rt3070/md4.h8
-rw-r--r--drivers/staging/rt3090/firmware.h517
-rw-r--r--drivers/staging/rtl8187se/Kconfig1
-rw-r--r--drivers/staging/rtl8187se/Makefile1
-rw-r--r--drivers/staging/rtl8187se/TODO1
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211.h5
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c21
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c20
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c48
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c3
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c3
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c6
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c7
-rw-r--r--drivers/staging/rtl8187se/r8180.h4
-rw-r--r--drivers/staging/rtl8187se/r8180_93cx6.c146
-rw-r--r--drivers/staging/rtl8187se/r8180_93cx6.h17
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c503
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.c67
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225z2.c232
-rw-r--r--drivers/staging/rtl8187se/r8185b_init.c986
-rw-r--r--drivers/staging/rtl8192e/Makefile9
-rw-r--r--drivers/staging/rtl8192e/dot11d.h138
-rw-r--r--drivers/staging/rtl8192e/ieee80211.h3
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211.h160
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c2
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c37
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c29
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c148
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c247
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c26
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c80
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c7
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c6
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h4
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c65
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c7
-rw-r--r--drivers/staging/rtl8192e/r8180_93cx6.c63
-rw-r--r--drivers/staging/rtl8192e/r8180_93cx6.h33
-rw-r--r--drivers/staging/rtl8192e/r8190_rtl8256.c360
-rw-r--r--drivers/staging/rtl8192e/r8190_rtl8256.h49
-rw-r--r--drivers/staging/rtl8192e/r8192E.h23
-rw-r--r--drivers/staging/rtl8192e/r8192E_core.c774
-rw-r--r--drivers/staging/rtl8192e/r8192E_dm.c40
-rw-r--r--drivers/staging/rtl8192e/r8192E_hw.h8
-rw-r--r--drivers/staging/rtl8192e/r8192E_wx.c212
-rw-r--r--drivers/staging/rtl8192e/r8192E_wx.h1
-rw-r--r--drivers/staging/rtl8192e/r819xE_cmdpkt.c2
-rw-r--r--drivers/staging/rtl8192e/r819xE_firmware.c85
-rw-r--r--drivers/staging/rtl8192e/r819xE_phy.c2
-rw-r--r--drivers/staging/rtl8192e/r819xE_phy.h194
-rw-r--r--drivers/staging/rtl8192e/r819xE_phyreg.h1117
-rw-r--r--drivers/staging/rtl8192su/Kconfig3
-rw-r--r--drivers/staging/rtl8192su/TODO1
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211.h5
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c19
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c21
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c20
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_module.c2
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c48
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c7
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c4
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c7
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c21
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c2
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c7
-rw-r--r--drivers/staging/rtl8192su/r8192SU_HWImg.c4276
-rw-r--r--drivers/staging/rtl8192su/r8192SU_HWImg.h2
-rw-r--r--drivers/staging/rtl8192su/r8192S_firmware.c126
-rw-r--r--drivers/staging/rtl8192su/r8192S_firmware.h7
-rw-r--r--drivers/staging/rtl8192su/r8192S_phy.c16
-rw-r--r--drivers/staging/rtl8192su/r8192U.h1
-rw-r--r--drivers/staging/rtl8192su/r8192U_core.c187
-rw-r--r--drivers/staging/rtl8192su/r8192U_dm.c2
-rw-r--r--drivers/staging/rtl8192u/Kconfig3
-rw-r--r--drivers/staging/rtl8192u/Makefile2
-rw-r--r--drivers/staging/rtl8192u/ieee80211.h3
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211.h4
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c21
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c20
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_module.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c48
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c3
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c4
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c7
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c6
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c4
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c7
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c9
-rw-r--r--drivers/staging/samsung-laptop/samsung-laptop.c16
-rw-r--r--drivers/staging/sep/sep_driver.c29
-rw-r--r--drivers/staging/serqt_usb2/serqt_usb2.c4
-rw-r--r--drivers/staging/slicoss/slic.h9
-rw-r--r--drivers/staging/slicoss/slicoss.c116
-rw-r--r--drivers/staging/sm7xx/Kconfig7
-rw-r--r--drivers/staging/sm7xx/TODO1
-rw-r--r--drivers/staging/sm7xx/smtc2d.c979
-rw-r--r--drivers/staging/sm7xx/smtc2d.h530
-rw-r--r--drivers/staging/sm7xx/smtcfb.c132
-rw-r--r--drivers/staging/strip/strip.c1
-rw-r--r--drivers/staging/udlfb/Kconfig14
-rw-r--r--drivers/staging/udlfb/udlfb.c1994
-rw-r--r--drivers/staging/udlfb/udlfb.h281
-rw-r--r--drivers/staging/usbip/Kconfig7
-rw-r--r--drivers/staging/usbip/Makefile2
-rw-r--r--drivers/staging/usbip/stub_dev.c2
-rw-r--r--drivers/staging/usbip/stub_main.c1
-rw-r--r--drivers/staging/usbip/stub_rx.c2
-rw-r--r--drivers/staging/usbip/stub_tx.c2
-rw-r--r--drivers/staging/usbip/usbip_common.c91
-rw-r--r--drivers/staging/usbip/usbip_common.h8
-rw-r--r--drivers/staging/usbip/usbip_event.c3
-rw-r--r--drivers/staging/usbip/vhci_hcd.c1
-rw-r--r--drivers/staging/usbip/vhci_rx.c2
-rw-r--r--drivers/staging/usbip/vhci_tx.c2
-rw-r--r--drivers/staging/vme/Kconfig2
-rw-r--r--drivers/staging/vme/Makefile1
-rw-r--r--drivers/staging/vme/TODO28
-rw-r--r--drivers/staging/vme/boards/Kconfig9
-rw-r--r--drivers/staging/vme/boards/Makefile5
-rw-r--r--drivers/staging/vme/boards/vme_vmivme7805.c124
-rw-r--r--drivers/staging/vme/boards/vme_vmivme7805.h37
-rw-r--r--drivers/staging/vme/bridges/Kconfig2
-rw-r--r--drivers/staging/vme/bridges/vme_ca91cx42.c1593
-rw-r--r--drivers/staging/vme/bridges/vme_ca91cx42.h136
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.c1010
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.h16
-rw-r--r--drivers/staging/vme/devices/vme_user.c66
-rw-r--r--drivers/staging/vme/vme.c249
-rw-r--r--drivers/staging/vme/vme.h33
-rw-r--r--drivers/staging/vme/vme_api.txt27
-rw-r--r--drivers/staging/vme/vme_bridge.h107
-rw-r--r--drivers/staging/vt6655/card.c6
-rw-r--r--drivers/staging/vt6655/device_main.c6
-rw-r--r--drivers/staging/vt6655/iwctl.c2
-rw-r--r--drivers/staging/winbond/core.h2
-rw-r--r--drivers/staging/winbond/localpara.h34
-rw-r--r--drivers/staging/winbond/mds_f.h3
-rw-r--r--drivers/staging/winbond/mds_s.h28
-rw-r--r--drivers/staging/winbond/mlme_s.h8
-rw-r--r--drivers/staging/winbond/mto.h5
-rw-r--r--drivers/staging/winbond/reg.c10
-rw-r--r--drivers/staging/winbond/scan_s.h1
-rw-r--r--drivers/staging/winbond/sme_api.h4
-rw-r--r--drivers/staging/winbond/wb35reg.c1
-rw-r--r--drivers/staging/winbond/wb35reg_f.h2
-rw-r--r--drivers/staging/winbond/wb35rx.c1
-rw-r--r--drivers/staging/winbond/wb35tx.c1
-rw-r--r--drivers/staging/winbond/wbusb.c24
-rw-r--r--drivers/staging/wlags49_h2/wl_cs.c1
-rw-r--r--drivers/staging/wlags49_h2/wl_main.c2
-rw-r--r--drivers/staging/wlags49_h2/wl_netdev.c3
-rw-r--r--drivers/staging/wlags49_h2/wl_pci.c2
-rw-r--r--drivers/staging/wlags49_h2/wl_priv.c1
-rw-r--r--drivers/staging/wlags49_h2/wl_profile.c76
-rw-r--r--drivers/staging/wlags49_h2/wl_util.c49
-rw-r--r--drivers/staging/wlags49_h2/wl_util.h2
-rw-r--r--drivers/staging/wlan-ng/Kconfig4
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h180
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c42
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c16
-rw-r--r--drivers/staging/wlan-ng/p80211conv.h4
-rw-r--r--drivers/staging/wlan-ng/p80211metadef.h18
-rw-r--r--drivers/staging/wlan-ng/p80211mgmt.h42
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c7
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.h44
-rw-r--r--drivers/staging/wlan-ng/p80211req.c3
-rw-r--r--drivers/staging/wlan-ng/p80211req.h2
-rw-r--r--drivers/staging/wlan-ng/p80211types.h18
-rw-r--r--drivers/staging/wlan-ng/p80211wep.c1
-rw-r--r--drivers/staging/wlan-ng/p80211wext.c84
-rw-r--r--drivers/staging/wlan-ng/prism2fw.c70
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.c31
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h48
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c11
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c20
-rw-r--r--drivers/staging/wlan-ng/prism2usb.c6
-rw-r--r--drivers/tc/tc.c1
-rw-r--r--drivers/thermal/thermal_sys.c4
-rw-r--r--drivers/uio/Kconfig24
-rw-r--r--drivers/uio/Makefile2
-rw-r--r--drivers/uio/uio.c5
-rw-r--r--drivers/uio/uio_aec.c1
-rw-r--r--drivers/uio/uio_cif.c1
-rw-r--r--drivers/uio/uio_netx.c173
-rw-r--r--drivers/uio/uio_pci_generic.c1
-rw-r--r--drivers/uio/uio_pdrv.c1
-rw-r--r--drivers/uio/uio_pdrv_genirq.c1
-rw-r--r--drivers/uio/uio_sercos3.c1
-rw-r--r--drivers/uio/uio_smx.c140
-rw-r--r--drivers/usb/atm/speedtch.c1
-rw-r--r--drivers/usb/atm/ueagle-atm.c1
-rw-r--r--drivers/usb/c67x00/c67x00-drv.c1
-rw-r--r--drivers/usb/c67x00/c67x00-sched.c1
-rw-r--r--drivers/usb/class/cdc-acm.c5
-rw-r--r--drivers/usb/class/cdc-wdm.c134
-rw-r--r--drivers/usb/class/usbtmc.c1
-rw-r--r--drivers/usb/core/Kconfig2
-rw-r--r--drivers/usb/core/devices.c71
-rw-r--r--drivers/usb/core/devio.c17
-rw-r--r--drivers/usb/core/driver.c54
-rw-r--r--drivers/usb/core/endpoint.c1
-rw-r--r--drivers/usb/core/file.c1
-rw-r--r--drivers/usb/core/generic.c2
-rw-r--r--drivers/usb/core/inode.c4
-rw-r--r--drivers/usb/core/urb.c1
-rw-r--r--drivers/usb/core/usb.c20
-rw-r--r--drivers/usb/gadget/Kconfig2
-rw-r--r--drivers/usb/gadget/at91_udc.c9
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c1
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c1
-rw-r--r--drivers/usb/gadget/config.c1
-rw-r--r--drivers/usb/gadget/epautoconf.c2
-rw-r--r--drivers/usb/gadget/f_acm.c1
-rw-r--r--drivers/usb/gadget/f_audio.c1
-rw-r--r--drivers/usb/gadget/f_ecm.c1
-rw-r--r--drivers/usb/gadget/f_eem.c1
-rw-r--r--drivers/usb/gadget/f_loopback.c1
-rw-r--r--drivers/usb/gadget/f_mass_storage.c3
-rw-r--r--drivers/usb/gadget/f_obex.c1
-rw-r--r--drivers/usb/gadget/f_phonet.c1
-rw-r--r--drivers/usb/gadget/f_rndis.c1
-rw-r--r--drivers/usb/gadget/f_serial.c1
-rw-r--r--drivers/usb/gadget/f_sourcesink.c1
-rw-r--r--drivers/usb/gadget/f_subset.c1
-rw-r--r--drivers/usb/gadget/fsl_mx3_udc.c31
-rw-r--r--drivers/usb/gadget/gadget_chips.h8
-rw-r--r--drivers/usb/gadget/gmidi.c1
-rw-r--r--drivers/usb/gadget/goku_udc.c2
-rw-r--r--drivers/usb/gadget/imx_udc.c1
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c1
-rw-r--r--drivers/usb/gadget/m66592-udc.c1
-rw-r--r--drivers/usb/gadget/multi.c2
-rw-r--r--drivers/usb/gadget/pxa25x_udc.c4
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c1
-rw-r--r--drivers/usb/gadget/r8a66597-udc.c1
-rw-r--r--drivers/usb/gadget/rndis.c1
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c10
-rw-r--r--drivers/usb/gadget/u_audio.c1
-rw-r--r--drivers/usb/gadget/u_ether.c1
-rw-r--r--drivers/usb/gadget/u_serial.c1
-rw-r--r--drivers/usb/gadget/zero.c1
-rw-r--r--drivers/usb/host/Makefile4
-rw-r--r--drivers/usb/host/ehci-hcd.c5
-rw-r--r--drivers/usb/host/ehci-hub.c2
-rw-r--r--drivers/usb/host/ehci-mem.c2
-rw-r--r--drivers/usb/host/ehci-mxc.c1
-rw-r--r--drivers/usb/host/ehci-omap.c7
-rw-r--r--drivers/usb/host/ehci-sched.c68
-rw-r--r--drivers/usb/host/ehci.h10
-rw-r--r--drivers/usb/host/fhci-hcd.c1
-rw-r--r--drivers/usb/host/fhci-mem.c1
-rw-r--r--drivers/usb/host/fhci-q.c1
-rw-r--r--drivers/usb/host/fhci-tds.c1
-rw-r--r--drivers/usb/host/hwa-hc.c1
-rw-r--r--drivers/usb/host/imx21-hcd.c1
-rw-r--r--drivers/usb/host/isp116x-hcd.c1
-rw-r--r--drivers/usb/host/ohci-at91.c2
-rw-r--r--drivers/usb/host/ohci-da8xx.c2
-rw-r--r--drivers/usb/host/ohci-hub.c2
-rw-r--r--drivers/usb/host/ohci-q.c1
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c6
-rw-r--r--drivers/usb/host/r8a66597-hcd.c17
-rw-r--r--drivers/usb/host/sl811-hcd.c6
-rw-r--r--drivers/usb/host/uhci-debug.c1
-rw-r--r--drivers/usb/host/whci/asl.c1
-rw-r--r--drivers/usb/host/whci/debug.c1
-rw-r--r--drivers/usb/host/whci/init.c1
-rw-r--r--drivers/usb/host/whci/pzl.c1
-rw-r--r--drivers/usb/host/whci/qset.c1
-rw-r--r--drivers/usb/host/xhci-hcd.c1916
-rw-r--r--drivers/usb/host/xhci-mem.c75
-rw-r--r--drivers/usb/host/xhci-ring.c1
-rw-r--r--drivers/usb/host/xhci.c1918
-rw-r--r--drivers/usb/host/xhci.h4
-rw-r--r--drivers/usb/misc/appledisplay.c8
-rw-r--r--drivers/usb/misc/cypress_cy7c63.c1
-rw-r--r--drivers/usb/misc/cytherm.c1
-rw-r--r--drivers/usb/misc/isight_firmware.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.c1
-rw-r--r--drivers/usb/misc/trancevibrator.c1
-rw-r--r--drivers/usb/misc/usbsevseg.c15
-rw-r--r--drivers/usb/misc/uss720.c1
-rw-r--r--drivers/usb/mon/mon_bin.c1
-rw-r--r--drivers/usb/mon/mon_main.c1
-rw-r--r--drivers/usb/mon/mon_stat.c1
-rw-r--r--drivers/usb/mon/mon_text.c1
-rw-r--r--drivers/usb/musb/Kconfig2
-rw-r--r--drivers/usb/musb/Makefile2
-rw-r--r--drivers/usb/musb/blackfin.c9
-rw-r--r--drivers/usb/musb/cppi_dma.c1
-rw-r--r--drivers/usb/musb/davinci.c5
-rw-r--r--drivers/usb/musb/musb_core.c90
-rw-r--r--drivers/usb/musb/musb_core.h6
-rw-r--r--drivers/usb/musb/musb_gadget.c1
-rw-r--r--drivers/usb/musb/musb_host.c3
-rw-r--r--drivers/usb/musb/musb_regs.h30
-rw-r--r--drivers/usb/musb/musb_virthub.c1
-rw-r--r--drivers/usb/musb/musbhsdma.c1
-rw-r--r--drivers/usb/musb/omap2430.c4
-rw-r--r--drivers/usb/musb/tusb6010.c13
-rw-r--r--drivers/usb/musb/tusb6010_omap.c23
-rw-r--r--drivers/usb/otg/gpio_vbus.c1
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c1
-rw-r--r--drivers/usb/otg/twl4030-usb.c1
-rw-r--r--drivers/usb/otg/ulpi.c1
-rw-r--r--drivers/usb/serial/Kconfig4
-rw-r--r--drivers/usb/serial/aircable.c1
-rw-r--r--drivers/usb/serial/ark3116.c1
-rw-r--r--drivers/usb/serial/bus.c1
-rw-r--r--drivers/usb/serial/ch341.c1
-rw-r--r--drivers/usb/serial/console.c1
-rw-r--r--drivers/usb/serial/cp210x.c5
-rw-r--r--drivers/usb/serial/cypress_m8.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c7
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h7
-rw-r--r--drivers/usb/serial/generic.c49
-rw-r--r--drivers/usb/serial/navman.c1
-rw-r--r--drivers/usb/serial/opticon.c3
-rw-r--r--drivers/usb/serial/option.c64
-rw-r--r--drivers/usb/serial/pl2303.c2
-rw-r--r--drivers/usb/serial/pl2303.h5
-rw-r--r--drivers/usb/serial/qcaux.c10
-rw-r--r--drivers/usb/serial/qcserial.c29
-rw-r--r--drivers/usb/serial/safe_serial.c2
-rw-r--r--drivers/usb/serial/sierra.c2
-rw-r--r--drivers/usb/serial/symbolserial.c3
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c26
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.h3
-rw-r--r--drivers/usb/serial/usb_debug.c1
-rw-r--r--drivers/usb/storage/alauda.c1
-rw-r--r--drivers/usb/storage/karma.c1
-rw-r--r--drivers/usb/storage/option_ms.c1
-rw-r--r--drivers/usb/storage/scsiglue.c1
-rw-r--r--drivers/usb/storage/sierra_ms.c1
-rw-r--r--drivers/usb/storage/transport.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h23
-rw-r--r--drivers/usb/wusbcore/cbaf.c1
-rw-r--r--drivers/usb/wusbcore/crypto.c1
-rw-r--r--drivers/usb/wusbcore/devconnect.c3
-rw-r--r--drivers/usb/wusbcore/mmc.c1
-rw-r--r--drivers/usb/wusbcore/rh.c1
-rw-r--r--drivers/usb/wusbcore/security.c1
-rw-r--r--drivers/usb/wusbcore/wa-hc.c1
-rw-r--r--drivers/usb/wusbcore/wa-nep.c1
-rw-r--r--drivers/usb/wusbcore/wa-rpipe.c1
-rw-r--r--drivers/usb/wusbcore/wa-xfer.c1
-rw-r--r--drivers/usb/wusbcore/wusbhc.h2
-rw-r--r--drivers/uwb/address.c1
-rw-r--r--drivers/uwb/allocator.c1
-rw-r--r--drivers/uwb/beacon.c1
-rw-r--r--drivers/uwb/driver.c5
-rw-r--r--drivers/uwb/drp-ie.c1
-rw-r--r--drivers/uwb/drp.c1
-rw-r--r--drivers/uwb/est.c1
-rw-r--r--drivers/uwb/hwa-rc.c3
-rw-r--r--drivers/uwb/i1480/dfu/mac.c1
-rw-r--r--drivers/uwb/i1480/dfu/usb.c13
-rw-r--r--drivers/uwb/i1480/i1480-est.c4
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/lc.c1
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/netdev.c1
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/rx.c1
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/tx.c1
-rw-r--r--drivers/uwb/ie.c1
-rw-r--r--drivers/uwb/lc-dev.c1
-rw-r--r--drivers/uwb/lc-rc.c1
-rw-r--r--drivers/uwb/neh.c1
-rw-r--r--drivers/uwb/reset.c1
-rw-r--r--drivers/uwb/rsv.c1
-rw-r--r--drivers/uwb/scan.c1
-rw-r--r--drivers/uwb/umc-bus.c4
-rw-r--r--drivers/uwb/umc-dev.c1
-rw-r--r--drivers/uwb/uwb-internal.h4
-rw-r--r--drivers/uwb/uwbd.c3
-rw-r--r--drivers/uwb/whc-rc.c1
-rw-r--r--drivers/uwb/whci.c1
-rw-r--r--drivers/uwb/wlp/eda.c1
-rw-r--r--drivers/uwb/wlp/messages.c107
-rw-r--r--drivers/uwb/wlp/sysfs.c3
-rw-r--r--drivers/uwb/wlp/txrx.c1
-rw-r--r--drivers/uwb/wlp/wlp-lc.c1
-rw-r--r--drivers/uwb/wlp/wss-lc.c1
-rw-r--r--drivers/vhost/net.c11
-rw-r--r--drivers/vhost/vhost.c23
-rw-r--r--drivers/video/68328fb.c3
-rw-r--r--drivers/video/Kconfig41
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/acornfb.c4
-rw-r--r--drivers/video/amba-clcd.c31
-rw-r--r--drivers/video/amifb.c1
-rw-r--r--drivers/video/arcfb.c3
-rw-r--r--drivers/video/asiliantfb.c5
-rw-r--r--drivers/video/atafb.c1
-rw-r--r--drivers/video/atmel_lcdfb.c9
-rw-r--r--drivers/video/aty/aty128fb.c8
-rw-r--r--drivers/video/aty/atyfb_base.c7
-rw-r--r--drivers/video/aty/mach64_cursor.c1
-rw-r--r--drivers/video/aty/radeon_backlight.c8
-rw-r--r--drivers/video/aty/radeon_monitor.c3
-rw-r--r--drivers/video/au1100fb.c1
-rw-r--r--drivers/video/au1200fb.c1
-rw-r--r--drivers/video/backlight/88pm860x_bl.c307
-rw-r--r--drivers/video/backlight/Kconfig20
-rw-r--r--drivers/video/backlight/Makefile3
-rw-r--r--drivers/video/backlight/adp5520_bl.c12
-rw-r--r--drivers/video/backlight/adx_bl.c11
-rw-r--r--drivers/video/backlight/atmel-pwm-bl.c9
-rw-r--r--drivers/video/backlight/backlight.c11
-rw-r--r--drivers/video/backlight/corgi_lcd.c9
-rw-r--r--drivers/video/backlight/cr_bllcd.c9
-rw-r--r--drivers/video/backlight/da903x_bl.c8
-rw-r--r--drivers/video/backlight/generic_bl.c8
-rw-r--r--drivers/video/backlight/hp680_bl.c8
-rw-r--r--drivers/video/backlight/ili9320.c1
-rw-r--r--drivers/video/backlight/jornada720_bl.c7
-rw-r--r--drivers/video/backlight/kb3886_bl.c8
-rw-r--r--drivers/video/backlight/l4f00242t03.c258
-rw-r--r--drivers/video/backlight/lcd.c1
-rw-r--r--drivers/video/backlight/lms283gf05.c1
-rw-r--r--drivers/video/backlight/locomolcd.c8
-rw-r--r--drivers/video/backlight/ltv350qv.c1
-rw-r--r--drivers/video/backlight/max8925_bl.c203
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c55
-rw-r--r--drivers/video/backlight/omap1_bl.c8
-rw-r--r--drivers/video/backlight/platform_lcd.c1
-rw-r--r--drivers/video/backlight/progear_bl.c23
-rw-r--r--drivers/video/backlight/pwm_bl.c9
-rw-r--r--drivers/video/backlight/tdo24m.c1
-rw-r--r--drivers/video/backlight/tosa_bl.c9
-rw-r--r--drivers/video/backlight/tosa_lcd.c1
-rw-r--r--drivers/video/backlight/wm831x_bl.c8
-rw-r--r--drivers/video/bf54x-lq043fb.c49
-rw-r--r--drivers/video/bfin-lq035q1-fb.c2
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c49
-rw-r--r--drivers/video/broadsheetfb.c738
-rw-r--r--drivers/video/bw2.c1
-rw-r--r--drivers/video/carminefb.c1
-rw-r--r--drivers/video/cfbcopyarea.c1
-rw-r--r--drivers/video/cg14.c1
-rw-r--r--drivers/video/cg3.c1
-rw-r--r--drivers/video/cg6.c1
-rw-r--r--drivers/video/chipsfb.c1
-rw-r--r--drivers/video/cirrusfb.c1
-rw-r--r--drivers/video/cobalt_lcdfb.c2
-rw-r--r--drivers/video/console/Kconfig1
-rw-r--r--drivers/video/console/bitblit.c1
-rw-r--r--drivers/video/console/fbcon_ccw.c1
-rw-r--r--drivers/video/console/fbcon_cw.c1
-rw-r--r--drivers/video/console/fbcon_rotate.c1
-rw-r--r--drivers/video/console/fbcon_ud.c1
-rw-r--r--drivers/video/console/mdacon.c1
-rw-r--r--drivers/video/console/vgacon.c2
-rw-r--r--drivers/video/da8xx-fb.c1
-rw-r--r--drivers/video/display/display-sysfs.c1
-rw-r--r--drivers/video/dnfb.c1
-rw-r--r--drivers/video/efifb.c5
-rw-r--r--drivers/video/ep93xx-fb.c1
-rw-r--r--drivers/video/epson1355fb.c3
-rw-r--r--drivers/video/fb_ddc.c1
-rw-r--r--drivers/video/fb_defio.c1
-rw-r--r--drivers/video/fbcvt.c1
-rw-r--r--drivers/video/fbmon.c1
-rw-r--r--drivers/video/fbsysfs.c1
-rw-r--r--drivers/video/ffb.c1
-rw-r--r--drivers/video/fsl-diu-fb.c1
-rw-r--r--drivers/video/g364fb.c1
-rw-r--r--drivers/video/gbefb.c3
-rw-r--r--drivers/video/geode/gx1fb_core.c1
-rw-r--r--drivers/video/geode/gxfb_core.c1
-rw-r--r--drivers/video/geode/lxfb.h2
-rw-r--r--drivers/video/geode/lxfb_core.c1
-rw-r--r--drivers/video/geode/lxfb_ops.c10
-rw-r--r--drivers/video/hecubafb.c1
-rw-r--r--drivers/video/hgafb.c3
-rw-r--r--drivers/video/hitfb.c3
-rw-r--r--drivers/video/hpfb.c1
-rw-r--r--drivers/video/i810/i810-i2c.c1
-rw-r--r--drivers/video/imsttfb.c1
-rw-r--r--drivers/video/intelfb/intelfbhw.c1
-rw-r--r--drivers/video/leo.c1
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c1
-rw-r--r--drivers/video/matrox/matroxfb_base.c1
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c1
-rw-r--r--drivers/video/matrox/matroxfb_maven.c1
-rw-r--r--drivers/video/maxinefb.c1
-rw-r--r--drivers/video/mb862xx/mb862xxfb.c13
-rw-r--r--drivers/video/mb862xx/mb862xxfb_accel.c6
-rw-r--r--drivers/video/mbx/mbxdebugfs.c1
-rw-r--r--drivers/video/mbx/mbxfb.c2
-rw-r--r--drivers/video/metronomefb.c1
-rw-r--r--drivers/video/modedb.c9
-rw-r--r--drivers/video/msm/mddi.c1
-rw-r--r--drivers/video/msm/mddi_client_dummy.c1
-rw-r--r--drivers/video/msm/mddi_client_nt35399.c1
-rw-r--r--drivers/video/msm/mddi_client_toshiba.c1
-rw-r--r--drivers/video/msm/mdp.c1
-rw-r--r--drivers/video/msm/msm_fb.c1
-rw-r--r--drivers/video/nuc900fb.c779
-rw-r--r--drivers/video/nuc900fb.h55
-rw-r--r--drivers/video/nvidia/nv_backlight.c7
-rw-r--r--drivers/video/nvidia/nv_i2c.c1
-rw-r--r--drivers/video/nvidia/nv_of.c1
-rw-r--r--drivers/video/nvidia/nv_setup.c1
-rw-r--r--drivers/video/offb.c1
-rw-r--r--drivers/video/omap/dispc.c1
-rw-r--r--drivers/video/omap/lcd_mipid.c1
-rw-r--r--drivers/video/omap/lcdc.c3
-rw-r--r--drivers/video/omap/omapfb_main.c1
-rw-r--r--drivers/video/omap2/displays/panel-generic.c22
-rw-r--r--drivers/video/omap2/displays/panel-taal.c16
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c1
-rw-r--r--drivers/video/omap2/dss/dss.c3
-rw-r--r--drivers/video/omap2/dss/manager.c3
-rw-r--r--drivers/video/omap2/dss/overlay.c3
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c1
-rw-r--r--drivers/video/omap2/vram.c12
-rw-r--r--drivers/video/output.c1
-rw-r--r--drivers/video/p9100.c1
-rw-r--r--drivers/video/platinumfb.c1
-rw-r--r--drivers/video/pm2fb.c2
-rw-r--r--drivers/video/pmag-aa-fb.c1
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c1
-rw-r--r--drivers/video/pnx4008/sdum.c2
-rw-r--r--drivers/video/pxa168fb.c2
-rw-r--r--drivers/video/q40fb.c3
-rw-r--r--drivers/video/riva/fbdev.c7
-rw-r--r--drivers/video/s1d13xxxfb.c5
-rw-r--r--drivers/video/s3c-fb.c2
-rw-r--r--drivers/video/s3c2410fb.c4
-rw-r--r--drivers/video/s3fb.c1
-rw-r--r--drivers/video/sa1100fb.c2
-rw-r--r--drivers/video/savage/savagefb-i2c.c1
-rw-r--r--drivers/video/sgivwfb.c2
-rw-r--r--drivers/video/sh7760fb.c1
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c3
-rw-r--r--drivers/video/sis/sis_main.c3
-rw-r--r--drivers/video/sm501fb.c2
-rw-r--r--drivers/video/sstfb.c3
-rw-r--r--drivers/video/sunxvr1000.c227
-rw-r--r--drivers/video/sunxvr2500.c1
-rw-r--r--drivers/video/sunxvr500.c25
-rw-r--r--drivers/video/svgalib.c1
-rw-r--r--drivers/video/syscopyarea.c1
-rw-r--r--drivers/video/tcx.c1
-rw-r--r--drivers/video/tgafb.c1
-rw-r--r--drivers/video/tridentfb.c1
-rw-r--r--drivers/video/uvesafb.c1
-rw-r--r--drivers/video/vermilion/vermilion.c1
-rw-r--r--drivers/video/vesafb.c25
-rw-r--r--drivers/video/vfb.c3
-rw-r--r--drivers/video/vga16fb.c3
-rw-r--r--drivers/video/via/Makefile2
-rw-r--r--drivers/video/via/chip.h11
-rw-r--r--drivers/video/via/dvi.c233
-rw-r--r--drivers/video/via/dvi.h7
-rw-r--r--drivers/video/via/global.c5
-rw-r--r--drivers/video/via/global.h3
-rw-r--r--drivers/video/via/hw.c330
-rw-r--r--drivers/video/via/hw.h17
-rw-r--r--drivers/video/via/iface.c78
-rw-r--r--drivers/video/via/iface.h38
-rw-r--r--drivers/video/via/lcd.c640
-rw-r--r--drivers/video/via/share.h56
-rw-r--r--drivers/video/via/via_utility.c12
-rw-r--r--drivers/video/via/via_utility.h1
-rw-r--r--drivers/video/via/viafbdev.c519
-rw-r--r--drivers/video/via/viafbdev.h6
-rw-r--r--drivers/video/via/viamode.c180
-rw-r--r--drivers/video/via/viamode.h8
-rw-r--r--drivers/video/vt8623fb.c1
-rw-r--r--drivers/video/w100fb.c3
-rw-r--r--drivers/video/xen-fbfront.c1
-rw-r--r--drivers/video/xilinxfb.c1
-rw-r--r--drivers/virtio/virtio_balloon.c4
-rw-r--r--drivers/virtio/virtio_pci.c2
-rw-r--r--drivers/virtio/virtio_ring.c1
-rw-r--r--drivers/vlynq/vlynq.c1
-rw-r--r--drivers/w1/masters/ds1wm.c1
-rw-r--r--drivers/w1/masters/ds2482.c2
-rw-r--r--drivers/w1/masters/ds2490.c1
-rw-r--r--drivers/w1/masters/mxc_w1.c5
-rw-r--r--drivers/w1/masters/omap_hdq.c6
-rw-r--r--drivers/w1/masters/w1-gpio.c1
-rw-r--r--drivers/w1/slaves/w1_ds2433.c1
-rw-r--r--drivers/w1/slaves/w1_ds2760.c1
-rw-r--r--drivers/w1/slaves/w1_therm.c5
-rw-r--r--drivers/w1/w1.c4
-rw-r--r--drivers/w1/w1_int.c1
-rw-r--r--drivers/w1/w1_netlink.c1
-rw-r--r--drivers/watchdog/Kconfig27
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/acquirewdt.c2
-rw-r--r--drivers/watchdog/advantechwdt.c2
-rw-r--r--drivers/watchdog/adx_wdt.c3
-rw-r--r--drivers/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/watchdog/alim7101_wdt.c2
-rw-r--r--drivers/watchdog/ar7_wdt.c2
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c3
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c2
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c2
-rw-r--r--drivers/watchdog/bfin_wdt.c56
-rw-r--r--drivers/watchdog/booke_wdt.c2
-rw-r--r--drivers/watchdog/coh901327_wdt.c2
-rw-r--r--drivers/watchdog/cpu5wdt.c2
-rw-r--r--drivers/watchdog/cpwd.c3
-rw-r--r--drivers/watchdog/davinci_wdt.c3
-rw-r--r--drivers/watchdog/ep93xx_wdt.c2
-rw-r--r--drivers/watchdog/eurotechwdt.c2
-rw-r--r--drivers/watchdog/gef_wdt.c16
-rw-r--r--drivers/watchdog/geodewdt.c2
-rw-r--r--drivers/watchdog/hpwdt.c5
-rw-r--r--drivers/watchdog/i6300esb.c101
-rw-r--r--drivers/watchdog/iTCO_wdt.c120
-rw-r--r--drivers/watchdog/ib700wdt.c2
-rw-r--r--drivers/watchdog/ibmasr.c1
-rw-r--r--drivers/watchdog/indydog.c2
-rw-r--r--drivers/watchdog/it8712f_wdt.c2
-rw-r--r--drivers/watchdog/it87_wdt.c2
-rw-r--r--drivers/watchdog/ixp2000_wdt.c2
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c2
-rw-r--r--drivers/watchdog/ks8695_wdt.c2
-rw-r--r--drivers/watchdog/machzwd.c2
-rw-r--r--drivers/watchdog/max63xx_wdt.c403
-rw-r--r--drivers/watchdog/mixcomwd.c2
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c2
-rw-r--r--drivers/watchdog/mpcore_wdt.c3
-rw-r--r--drivers/watchdog/mv64x60_wdt.c2
-rw-r--r--drivers/watchdog/nuc900_wdt.c1
-rw-r--r--drivers/watchdog/omap_wdt.c1
-rw-r--r--drivers/watchdog/pc87413_wdt.c2
-rw-r--r--drivers/watchdog/pcwd.c2
-rw-r--r--drivers/watchdog/pcwd_pci.c2
-rw-r--r--drivers/watchdog/pcwd_usb.c2
-rw-r--r--drivers/watchdog/pnx4008_wdt.c1
-rw-r--r--drivers/watchdog/pnx833x_wdt.c2
-rw-r--r--drivers/watchdog/rc32434_wdt.c2
-rw-r--r--drivers/watchdog/rdc321x_wdt.c2
-rw-r--r--drivers/watchdog/riowd.c3
-rw-r--r--drivers/watchdog/s3c2410_wdt.c1
-rw-r--r--drivers/watchdog/sb_wdog.c4
-rw-r--r--drivers/watchdog/sbc_fitpc2_wdt.c16
-rw-r--r--drivers/watchdog/sch311x_wdt.c2
-rw-r--r--drivers/watchdog/stmp3xxx_wdt.c2
-rw-r--r--drivers/watchdog/ts72xx_wdt.c521
-rw-r--r--drivers/watchdog/twl4030_wdt.c1
-rw-r--r--drivers/watchdog/txx9wdt.c25
-rw-r--r--drivers/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/watchdog/wdrtas.c2
-rw-r--r--drivers/watchdog/wdt.c2
-rw-r--r--drivers/watchdog/wdt_pci.c2
-rw-r--r--drivers/watchdog/wm831x_wdt.c2
-rw-r--r--drivers/watchdog/wm8350_wdt.c2
-rw-r--r--drivers/xen/Kconfig12
-rw-r--r--drivers/xen/balloon.c1
-rw-r--r--drivers/xen/events.c1
-rw-r--r--drivers/xen/evtchn.c1
-rw-r--r--drivers/xen/grant-table.c1
-rw-r--r--drivers/xen/manage.c1
-rw-r--r--drivers/xen/sys-hypervisor.c3
-rw-r--r--drivers/xen/xenbus/xenbus_client.c1
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c1
-rw-r--r--drivers/xen/xencomm.c2
-rw-r--r--drivers/xen/xenfs/xenbus.c1
-rw-r--r--drivers/zorro/zorro.ids2
-rw-r--r--firmware/bnx2x-e1-5.2.7.0.fw.ihex10178
-rw-r--r--firmware/bnx2x-e1h-5.2.7.0.fw.ihex12847
-rw-r--r--fs/9p/cache.c1
-rw-r--r--fs/9p/fid.c15
-rw-r--r--fs/9p/v9fs.c34
-rw-r--r--fs/9p/v9fs.h26
-rw-r--r--fs/9p/vfs_dentry.c1
-rw-r--r--fs/9p/vfs_dir.c16
-rw-r--r--fs/9p/vfs_file.c8
-rw-r--r--fs/9p/vfs_inode.c58
-rw-r--r--fs/9p/vfs_super.c5
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/Makefile2
-rw-r--r--fs/adfs/adfs.h2
-rw-r--r--fs/adfs/inode.c5
-rw-r--r--fs/adfs/super.c1
-rw-r--r--fs/affs/affs.h3
-rw-r--r--fs/affs/bitmap.c3
-rw-r--r--fs/affs/inode.c3
-rw-r--r--fs/affs/super.c1
-rw-r--r--fs/afs/cache.c1
-rw-r--r--fs/afs/cmservice.c1
-rw-r--r--fs/afs/dir.c1
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/afs/fsclient.c1
-rw-r--r--fs/afs/inode.c1
-rw-r--r--fs/afs/internal.h3
-rw-r--r--fs/afs/mntpt.c26
-rw-r--r--fs/afs/rxrpc.c1
-rw-r--r--fs/afs/security.c5
-rw-r--r--fs/afs/super.c2
-rw-r--r--fs/afs/vlclient.c1
-rw-r--r--fs/afs/vlocation.c1
-rw-r--r--fs/afs/vnode.c1
-rw-r--r--fs/afs/volume.c7
-rw-r--r--fs/afs/write.c21
-rw-r--r--fs/anon_inodes.c2
-rw-r--r--fs/attr.c13
-rw-r--r--fs/autofs/root.c1
-rw-r--r--fs/autofs4/dev-ioctl.c1
-rw-r--r--fs/autofs4/root.c1
-rw-r--r--fs/befs/datastream.c1
-rw-r--r--fs/bfs/inode.c5
-rw-r--r--fs/binfmt_aout.c54
-rw-r--r--fs/binfmt_elf.c151
-rw-r--r--fs/binfmt_elf_fdpic.c190
-rw-r--r--fs/binfmt_em86.c1
-rw-r--r--fs/binfmt_flat.c4
-rw-r--r--fs/binfmt_script.c1
-rw-r--r--fs/bio-integrity.c1
-rw-r--r--fs/bio.c11
-rw-r--r--fs/block_dev.c22
-rw-r--r--fs/btrfs/acl.c1
-rw-r--r--fs/btrfs/async-thread.c1
-rw-r--r--fs/btrfs/btrfs_inode.h5
-rw-r--r--fs/btrfs/compression.c23
-rw-r--r--fs/btrfs/ctree.c5
-rw-r--r--fs/btrfs/ctree.h17
-rw-r--r--fs/btrfs/delayed-ref.c1
-rw-r--r--fs/btrfs/disk-io.c44
-rw-r--r--fs/btrfs/export.c4
-rw-r--r--fs/btrfs/extent-tree.c55
-rw-r--r--fs/btrfs/extent_io.c99
-rw-r--r--fs/btrfs/extent_io.h10
-rw-r--r--fs/btrfs/extent_map.c3
-rw-r--r--fs/btrfs/file-item.c1
-rw-r--r--fs/btrfs/file.c24
-rw-r--r--fs/btrfs/free-space-cache.c5
-rw-r--r--fs/btrfs/inode.c203
-rw-r--r--fs/btrfs/ioctl.c710
-rw-r--r--fs/btrfs/ioctl.h111
-rw-r--r--fs/btrfs/locking.c1
-rw-r--r--fs/btrfs/ordered-data.c48
-rw-r--r--fs/btrfs/ordered-data.h9
-rw-r--r--fs/btrfs/ref-cache.c1
-rw-r--r--fs/btrfs/ref-cache.h2
-rw-r--r--fs/btrfs/relocation.c9
-rw-r--r--fs/btrfs/super.c259
-rw-r--r--fs/btrfs/sysfs.c4
-rw-r--r--fs/btrfs/transaction.c120
-rw-r--r--fs/btrfs/tree-log.c3
-rw-r--r--fs/btrfs/volumes.c56
-rw-r--r--fs/buffer.c15
-rw-r--r--fs/cachefiles/interface.c1
-rw-r--r--fs/cachefiles/namei.c1
-rw-r--r--fs/cachefiles/rdwr.c1
-rw-r--r--fs/cachefiles/xattr.c1
-rw-r--r--fs/ceph/Kconfig27
-rw-r--r--fs/ceph/Makefile39
-rw-r--r--fs/ceph/README20
-rw-r--r--fs/ceph/addr.c1193
-rw-r--r--fs/ceph/armor.c99
-rw-r--r--fs/ceph/auth.c258
-rw-r--r--fs/ceph/auth.h84
-rw-r--r--fs/ceph/auth_none.c122
-rw-r--r--fs/ceph/auth_none.h28
-rw-r--r--fs/ceph/auth_x.c680
-rw-r--r--fs/ceph/auth_x.h49
-rw-r--r--fs/ceph/auth_x_protocol.h90
-rw-r--r--fs/ceph/buffer.c81
-rw-r--r--fs/ceph/buffer.h39
-rw-r--r--fs/ceph/caps.c2955
-rw-r--r--fs/ceph/ceph_debug.h37
-rw-r--r--fs/ceph/ceph_frag.c21
-rw-r--r--fs/ceph/ceph_frag.h109
-rw-r--r--fs/ceph/ceph_fs.c74
-rw-r--r--fs/ceph/ceph_fs.h650
-rw-r--r--fs/ceph/ceph_hash.c118
-rw-r--r--fs/ceph/ceph_hash.h13
-rw-r--r--fs/ceph/ceph_strings.c176
-rw-r--r--fs/ceph/crush/crush.c151
-rw-r--r--fs/ceph/crush/crush.h180
-rw-r--r--fs/ceph/crush/hash.c149
-rw-r--r--fs/ceph/crush/hash.h17
-rw-r--r--fs/ceph/crush/mapper.c596
-rw-r--r--fs/ceph/crush/mapper.h20
-rw-r--r--fs/ceph/crypto.c409
-rw-r--r--fs/ceph/crypto.h48
-rw-r--r--fs/ceph/debugfs.c484
-rw-r--r--fs/ceph/decode.h194
-rw-r--r--fs/ceph/dir.c1224
-rw-r--r--fs/ceph/export.c224
-rw-r--r--fs/ceph/file.c938
-rw-r--r--fs/ceph/inode.c1774
-rw-r--r--fs/ceph/ioctl.c160
-rw-r--r--fs/ceph/ioctl.h40
-rw-r--r--fs/ceph/mds_client.c3043
-rw-r--r--fs/ceph/mds_client.h335
-rw-r--r--fs/ceph/mdsmap.c174
-rw-r--r--fs/ceph/mdsmap.h54
-rw-r--r--fs/ceph/messenger.c2249
-rw-r--r--fs/ceph/messenger.h255
-rw-r--r--fs/ceph/mon_client.c835
-rw-r--r--fs/ceph/mon_client.h119
-rw-r--r--fs/ceph/msgpool.c186
-rw-r--r--fs/ceph/msgpool.h27
-rw-r--r--fs/ceph/msgr.h158
-rw-r--r--fs/ceph/osd_client.c1550
-rw-r--r--fs/ceph/osd_client.h166
-rw-r--r--fs/ceph/osdmap.c1062
-rw-r--r--fs/ceph/osdmap.h126
-rw-r--r--fs/ceph/pagelist.c55
-rw-r--r--fs/ceph/pagelist.h54
-rw-r--r--fs/ceph/rados.h376
-rw-r--r--fs/ceph/snap.c907
-rw-r--r--fs/ceph/super.c1031
-rw-r--r--fs/ceph/super.h901
-rw-r--r--fs/ceph/types.h29
-rw-r--r--fs/ceph/xattr.c845
-rw-r--r--fs/cifs/asn1.c2
-rw-r--r--fs/cifs/cifs_dfs_ref.c3
-rw-r--r--fs/cifs/cifs_fs_sb.h3
-rw-r--r--fs/cifs/cifs_spnego.c1
-rw-r--r--fs/cifs/cifs_unicode.c1
-rw-r--r--fs/cifs/cifsacl.c1
-rw-r--r--fs/cifs/cifsencrypt.c1
-rw-r--r--fs/cifs/cifsfs.c14
-rw-r--r--fs/cifs/cifsfs.h3
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/cifsproto.h6
-rw-r--r--fs/cifs/cifssmb.c172
-rw-r--r--fs/cifs/connect.c1
-rw-r--r--fs/cifs/dir.c2
-rw-r--r--fs/cifs/dns_resolve.c1
-rw-r--r--fs/cifs/file.c36
-rw-r--r--fs/cifs/inode.c298
-rw-r--r--fs/cifs/link.c1
-rw-r--r--fs/cifs/readdir.c1
-rw-r--r--fs/cifs/sess.c1
-rw-r--r--fs/cifs/smbencrypt.c1
-rw-r--r--fs/cifs/transport.c1
-rw-r--r--fs/cifs/xattr.c1
-rw-r--r--fs/coda/dir.c1
-rw-r--r--fs/coda/file.c1
-rw-r--r--fs/coda/inode.c9
-rw-r--r--fs/coda/upcall.c1
-rw-r--r--fs/compat.c19
-rw-r--r--fs/compat_binfmt_elf.c2
-rw-r--r--fs/compat_ioctl.c9
-rw-r--r--fs/configfs/inode.c1
-rw-r--r--fs/configfs/mount.c1
-rw-r--r--fs/configfs/symlink.c1
-rw-r--r--fs/debugfs/inode.c1
-rw-r--r--fs/devpts/inode.c1
-rw-r--r--fs/dlm/config.c1
-rw-r--r--fs/dlm/debug_fs.c1
-rw-r--r--fs/dlm/lock.c1
-rw-r--r--fs/dlm/lockspace.c2
-rw-r--r--fs/dlm/lowcomms.c1
-rw-r--r--fs/dlm/member.c2
-rw-r--r--fs/dlm/netlink.c1
-rw-r--r--fs/dlm/plock.c1
-rw-r--r--fs/dlm/user.c1
-rw-r--r--fs/ecryptfs/crypto.c38
-rw-r--r--fs/ecryptfs/dentry.c1
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h15
-rw-r--r--fs/ecryptfs/file.c1
-rw-r--r--fs/ecryptfs/inode.c130
-rw-r--r--fs/ecryptfs/keystore.c1
-rw-r--r--fs/ecryptfs/kthread.c1
-rw-r--r--fs/ecryptfs/main.c11
-rw-r--r--fs/ecryptfs/messaging.c1
-rw-r--r--fs/ecryptfs/miscdev.c1
-rw-r--r--fs/ecryptfs/mmap.c39
-rw-r--r--fs/ecryptfs/super.c3
-rw-r--r--fs/eventfd.c1
-rw-r--r--fs/exec.c50
-rw-r--r--fs/exofs/exofs.h4
-rw-r--r--fs/exofs/inode.c5
-rw-r--r--fs/exofs/ios.c1
-rw-r--r--fs/exofs/super.c9
-rw-r--r--fs/ext2/balloc.c13
-rw-r--r--fs/ext2/ext2.h2
-rw-r--r--fs/ext2/file.c5
-rw-r--r--fs/ext2/ialloc.c14
-rw-r--r--fs/ext2/inode.c18
-rw-r--r--fs/ext2/namei.c51
-rw-r--r--fs/ext2/super.c2
-rw-r--r--fs/ext2/symlink.c2
-rw-r--r--fs/ext2/xattr.c10
-rw-r--r--fs/ext2/xattr_security.c1
-rw-r--r--fs/ext3/balloc.c12
-rw-r--r--fs/ext3/file.c7
-rw-r--r--fs/ext3/ialloc.c20
-rw-r--r--fs/ext3/inode.c47
-rw-r--r--fs/ext3/namei.c24
-rw-r--r--fs/ext3/super.c248
-rw-r--r--fs/ext3/symlink.c2
-rw-r--r--fs/ext3/xattr.c22
-rw-r--r--fs/ext3/xattr_security.c1
-rw-r--r--fs/ext4/balloc.c35
-rw-r--r--fs/ext4/block_validity.c5
-rw-r--r--fs/ext4/dir.c14
-rw-r--r--fs/ext4/ext4.h108
-rw-r--r--fs/ext4/ext4_jbd2.c4
-rw-r--r--fs/ext4/ext4_jbd2.h24
-rw-r--r--fs/ext4/extents.c261
-rw-r--r--fs/ext4/file.c7
-rw-r--r--fs/ext4/fsync.c2
-rw-r--r--fs/ext4/ialloc.c52
-rw-r--r--fs/ext4/inode.c500
-rw-r--r--fs/ext4/ioctl.c12
-rw-r--r--fs/ext4/mballoc.c99
-rw-r--r--fs/ext4/mballoc.h9
-rw-r--r--fs/ext4/migrate.c36
-rw-r--r--fs/ext4/move_extent.c37
-rw-r--r--fs/ext4/namei.c86
-rw-r--r--fs/ext4/resize.c102
-rw-r--r--fs/ext4/super.c390
-rw-r--r--fs/ext4/xattr.c64
-rw-r--r--fs/ext4/xattr_security.c1
-rw-r--r--fs/fat/cache.c1
-rw-r--r--fs/fat/inode.c11
-rw-r--r--fs/fat/namei_vfat.c33
-rw-r--r--fs/fcntl.c2
-rw-r--r--fs/fifo.c1
-rw-r--r--fs/file.c2
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/filesystems.c2
-rw-r--r--fs/freevxfs/vxfs_subr.c1
-rw-r--r--fs/fs-writeback.c156
-rw-r--r--fs/fscache/Kconfig1
-rw-r--r--fs/fscache/object-list.c1
-rw-r--r--fs/fscache/object.c6
-rw-r--r--fs/fscache/operation.c5
-rw-r--r--fs/fscache/page.c2
-rw-r--r--fs/fscache/stats.c4
-rw-r--r--fs/fuse/cuse.c1
-rw-r--r--fs/fuse/inode.c2
-rw-r--r--fs/generic_acl.c1
-rw-r--r--fs/gfs2/Kconfig1
-rw-r--r--fs/gfs2/bmap.c1
-rw-r--r--fs/gfs2/dentry.c1
-rw-r--r--fs/gfs2/export.c1
-rw-r--r--fs/gfs2/file.c2
-rw-r--r--fs/gfs2/glops.c1
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/lock_dlm.c1
-rw-r--r--fs/gfs2/log.c3
-rw-r--r--fs/gfs2/ops_fstype.c2
-rw-r--r--fs/gfs2/quota.c9
-rw-r--r--fs/gfs2/quota.h2
-rw-r--r--fs/gfs2/rgrp.h2
-rw-r--r--fs/gfs2/super.c7
-rw-r--r--fs/gfs2/sys.c7
-rw-r--r--fs/gfs2/util.c1
-rw-r--r--fs/hfs/bnode.c1
-rw-r--r--fs/hfs/btree.c1
-rw-r--r--fs/hfs/hfs_fs.h2
-rw-r--r--fs/hfs/inode.c2
-rw-r--r--fs/hfs/mdb.c1
-rw-r--r--fs/hfs/super.c1
-rw-r--r--fs/hfsplus/options.c1
-rw-r--r--fs/hfsplus/super.c3
-rw-r--r--fs/hostfs/hostfs_kern.c1
-rw-r--r--fs/hpfs/buffer.c1
-rw-r--r--fs/hpfs/dir.c1
-rw-r--r--fs/hpfs/inode.c1
-rw-r--r--fs/hpfs/super.c1
-rw-r--r--fs/inode.c4
-rw-r--r--fs/ioctl.c92
-rw-r--r--fs/ioprio.c1
-rw-r--r--fs/isofs/dir.c1
-rw-r--r--fs/isofs/namei.c1
-rw-r--r--fs/jbd/commit.c11
-rw-r--r--fs/jbd/recovery.c1
-rw-r--r--fs/jbd/transaction.c45
-rw-r--r--fs/jbd2/checkpoint.c1
-rw-r--r--fs/jbd2/commit.c13
-rw-r--r--fs/jbd2/journal.c132
-rw-r--r--fs/jbd2/recovery.c1
-rw-r--r--fs/jbd2/transaction.c43
-rw-r--r--fs/jffs2/compr_lzo.c1
-rw-r--r--fs/jffs2/compr_zlib.c1
-rw-r--r--fs/jffs2/debug.c1
-rw-r--r--fs/jffs2/file.c1
-rw-r--r--fs/jffs2/nodelist.c1
-rw-r--r--fs/jffs2/nodemgmt.c1
-rw-r--r--fs/jffs2/readinode.c2
-rw-r--r--fs/jffs2/symlink.c1
-rw-r--r--fs/jffs2/write.c1
-rw-r--r--fs/jfs/acl.c27
-rw-r--r--fs/jfs/file.c31
-rw-r--r--fs/jfs/inode.c16
-rw-r--r--fs/jfs/jfs_acl.h7
-rw-r--r--fs/jfs/jfs_dmap.c17
-rw-r--r--fs/jfs/jfs_dmap.h6
-rw-r--r--fs/jfs/jfs_dtree.c29
-rw-r--r--fs/jfs/jfs_extent.c16
-rw-r--r--fs/jfs/jfs_imap.c1
-rw-r--r--fs/jfs/jfs_inode.c8
-rw-r--r--fs/jfs/jfs_inode.h4
-rw-r--r--fs/jfs/jfs_logmgr.c1
-rw-r--r--fs/jfs/jfs_metapage.c1
-rw-r--r--fs/jfs/jfs_unicode.h1
-rw-r--r--fs/jfs/jfs_xtree.c21
-rw-r--r--fs/jfs/namei.c27
-rw-r--r--fs/jfs/resize.c6
-rw-r--r--fs/jfs/super.c7
-rw-r--r--fs/jfs/symlink.c14
-rw-r--r--fs/jfs/xattr.c18
-rw-r--r--fs/libfs.c1
-rw-r--r--fs/lockd/clntlock.c1
-rw-r--r--fs/lockd/clntproc.c1
-rw-r--r--fs/lockd/host.c2
-rw-r--r--fs/lockd/mon.c13
-rw-r--r--fs/lockd/svc.c3
-rw-r--r--fs/lockd/svc4proc.c1
-rw-r--r--fs/lockd/svclock.c1
-rw-r--r--fs/lockd/svcproc.c1
-rw-r--r--fs/lockd/svcsubs.c1
-rw-r--r--fs/locks.c2
-rw-r--r--fs/logfs/Kconfig17
-rw-r--r--fs/logfs/Makefile13
-rw-r--r--fs/logfs/compr.c95
-rw-r--r--fs/logfs/dev_bdev.c333
-rw-r--r--fs/logfs/dev_mtd.c254
-rw-r--r--fs/logfs/dir.c827
-rw-r--r--fs/logfs/file.c263
-rw-r--r--fs/logfs/gc.c739
-rw-r--r--fs/logfs/inode.c418
-rw-r--r--fs/logfs/journal.c898
-rw-r--r--fs/logfs/logfs.h736
-rw-r--r--fs/logfs/logfs_abi.h629
-rw-r--r--fs/logfs/readwrite.c2267
-rw-r--r--fs/logfs/segment.c930
-rw-r--r--fs/logfs/super.c657
-rw-r--r--fs/minix/inode.c8
-rw-r--r--fs/minix/itree_v1.c1
-rw-r--r--fs/mpage.c3
-rw-r--r--fs/namei.c535
-rw-r--r--fs/ncpfs/dir.c1
-rw-r--r--fs/ncpfs/file.c1
-rw-r--r--fs/ncpfs/inode.c8
-rw-r--r--fs/ncpfs/ioctl.c1
-rw-r--r--fs/ncpfs/mmap.c2
-rw-r--r--fs/ncpfs/sock.c1
-rw-r--r--fs/ncpfs/symlink.c1
-rw-r--r--fs/nfs/cache_lib.c1
-rw-r--r--fs/nfs/callback.c2
-rw-r--r--fs/nfs/callback.h8
-rw-r--r--fs/nfs/callback_proc.c166
-rw-r--r--fs/nfs/callback_xdr.c107
-rw-r--r--fs/nfs/client.c54
-rw-r--r--fs/nfs/delegation.c1
-rw-r--r--fs/nfs/delegation.h6
-rw-r--r--fs/nfs/dir.c10
-rw-r--r--fs/nfs/direct.c1
-rw-r--r--fs/nfs/dns_resolve.c19
-rw-r--r--fs/nfs/file.c35
-rw-r--r--fs/nfs/fscache.c1
-rw-r--r--fs/nfs/inode.c105
-rw-r--r--fs/nfs/internal.h2
-rw-r--r--fs/nfs/namespace.c1
-rw-r--r--fs/nfs/nfs2xdr.c1
-rw-r--r--fs/nfs/nfs3acl.c1
-rw-r--r--fs/nfs/nfs3proc.c10
-rw-r--r--fs/nfs/nfs3xdr.c1
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4namespace.c1
-rw-r--r--fs/nfs/nfs4proc.c117
-rw-r--r--fs/nfs/nfs4renewd.c24
-rw-r--r--fs/nfs/nfs4state.c118
-rw-r--r--fs/nfs/nfs4xdr.c13
-rw-r--r--fs/nfs/pagelist.c23
-rw-r--r--fs/nfs/proc.c42
-rw-r--r--fs/nfs/super.c29
-rw-r--r--fs/nfs/symlink.c3
-rw-r--r--fs/nfs/write.c312
-rw-r--r--fs/nfs_common/nfsacl.c1
-rw-r--r--fs/nfsd/export.c1
-rw-r--r--fs/nfsd/nfs2acl.c1
-rw-r--r--fs/nfsd/nfs3acl.c1
-rw-r--r--fs/nfsd/nfs4acl.c1
-rw-r--r--fs/nfsd/nfs4callback.c6
-rw-r--r--fs/nfsd/nfs4idmap.c1
-rw-r--r--fs/nfsd/nfs4proc.c1
-rw-r--r--fs/nfsd/nfs4recover.c5
-rw-r--r--fs/nfsd/nfs4state.c7
-rw-r--r--fs/nfsd/nfs4xdr.c13
-rw-r--r--fs/nfsd/nfscache.c2
-rw-r--r--fs/nfsd/nfsctl.c25
-rw-r--r--fs/nfsd/vfs.c158
-rw-r--r--fs/nilfs2/alloc.c3
-rw-r--r--fs/nilfs2/alloc.h2
-rw-r--r--fs/nilfs2/btnode.c1
-rw-r--r--fs/nilfs2/btree.c2
-rw-r--r--fs/nilfs2/dat.c2
-rw-r--r--fs/nilfs2/dir.c2
-rw-r--r--fs/nilfs2/gcinode.c5
-rw-r--r--fs/nilfs2/inode.c1
-rw-r--r--fs/nilfs2/ioctl.c3
-rw-r--r--fs/nilfs2/mdt.c1
-rw-r--r--fs/nilfs2/page.c5
-rw-r--r--fs/nilfs2/recovery.c1
-rw-r--r--fs/nilfs2/segbuf.c19
-rw-r--r--fs/nilfs2/segment.c24
-rw-r--r--fs/nilfs2/segment.h4
-rw-r--r--fs/nilfs2/sufile.c2
-rw-r--r--fs/nilfs2/super.c4
-rw-r--r--fs/nilfs2/the_nilfs.c2
-rw-r--r--fs/nilfs2/the_nilfs.h1
-rw-r--r--fs/notify/fsnotify.c1
-rw-r--r--fs/notify/inode_mark.c1
-rw-r--r--fs/notify/inotify/Kconfig1
-rw-r--r--fs/ntfs/ChangeLog1702
-rw-r--r--fs/ntfs/aops.c1
-rw-r--r--fs/ntfs/attrib.c1
-rw-r--r--fs/ntfs/compress.c1
-rw-r--r--fs/ntfs/dir.c3
-rw-r--r--fs/ntfs/file.c3
-rw-r--r--fs/ntfs/index.c2
-rw-r--r--fs/ntfs/inode.c2
-rw-r--r--fs/ntfs/inode.h4
-rw-r--r--fs/ntfs/mft.c1
-rw-r--r--fs/ntfs/namei.c1
-rw-r--r--fs/ntfs/super.c33
-rw-r--r--fs/ocfs2/acl.c78
-rw-r--r--fs/ocfs2/alloc.c13
-rw-r--r--fs/ocfs2/aops.c11
-rw-r--r--fs/ocfs2/buffer_head_io.c1
-rw-r--r--fs/ocfs2/cluster/heartbeat.c1
-rw-r--r--fs/ocfs2/cluster/masklog.c2
-rw-r--r--fs/ocfs2/cluster/nodemanager.c1
-rw-r--r--fs/ocfs2/cluster/quorum.c1
-rw-r--r--fs/ocfs2/cluster/tcp.c4
-rw-r--r--fs/ocfs2/dir.c37
-rw-r--r--fs/ocfs2/dlm/dlmast.c1
-rw-r--r--fs/ocfs2/dlm/dlmconvert.c1
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c4
-rw-r--r--fs/ocfs2/dlm/dlmthread.c1
-rw-r--r--fs/ocfs2/dlm/dlmunlock.c1
-rw-r--r--fs/ocfs2/dlmglue.c2
-rw-r--r--fs/ocfs2/extent_map.c3
-rw-r--r--fs/ocfs2/file.c20
-rw-r--r--fs/ocfs2/heartbeat.c1
-rw-r--r--fs/ocfs2/inode.c22
-rw-r--r--fs/ocfs2/localalloc.c10
-rw-r--r--fs/ocfs2/locks.c2
-rw-r--r--fs/ocfs2/mmap.c1
-rw-r--r--fs/ocfs2/namei.c80
-rw-r--r--fs/ocfs2/ocfs2.h14
-rw-r--r--fs/ocfs2/quota_global.c8
-rw-r--r--fs/ocfs2/quota_local.c3
-rw-r--r--fs/ocfs2/refcounttree.c4
-rw-r--r--fs/ocfs2/stack_o2cb.c1
-rw-r--r--fs/ocfs2/stack_user.c1
-rw-r--r--fs/ocfs2/suballoc.c129
-rw-r--r--fs/ocfs2/suballoc.h5
-rw-r--r--fs/ocfs2/sysfile.c1
-rw-r--r--fs/ocfs2/xattr.c12
-rw-r--r--fs/omfs/inode.c11
-rw-r--r--fs/open.c7
-rw-r--r--fs/partitions/check.c1
-rw-r--r--fs/partitions/efi.c1
-rw-r--r--fs/partitions/msdos.c85
-rw-r--r--fs/proc/array.c5
-rw-r--r--fs/proc/base.c8
-rw-r--r--fs/proc/generic.c34
-rw-r--r--fs/proc/inode.c1
-rw-r--r--fs/proc/kcore.c3
-rw-r--r--fs/proc/nommu.c1
-rw-r--r--fs/proc/proc_devtree.c1
-rw-r--r--fs/proc/proc_net.c1
-rw-r--r--fs/proc/stat.c1
-rw-r--r--fs/proc/task_mmu.c128
-rw-r--r--fs/proc/task_nommu.c1
-rw-r--r--fs/proc/vmcore.c1
-rw-r--r--fs/qnx4/inode.c3
-rw-r--r--fs/quota/Kconfig13
-rw-r--r--fs/quota/Makefile2
-rw-r--r--fs/quota/compat.c118
-rw-r--r--fs/quota/dquot.c440
-rw-r--r--fs/quota/netlink.c96
-rw-r--r--fs/quota/quota.c735
-rw-r--r--fs/ramfs/file-nommu.c1
-rw-r--r--fs/ramfs/inode.c1
-rw-r--r--fs/read_write.c2
-rw-r--r--fs/reiserfs/bitmap.c12
-rw-r--r--fs/reiserfs/dir.c3
-rw-r--r--fs/reiserfs/file.c2
-rw-r--r--fs/reiserfs/fix_node.c1
-rw-r--r--fs/reiserfs/inode.c25
-rw-r--r--fs/reiserfs/journal.c16
-rw-r--r--fs/reiserfs/namei.c24
-rw-r--r--fs/reiserfs/stree.c20
-rw-r--r--fs/reiserfs/super.c26
-rw-r--r--fs/reiserfs/xattr.c24
-rw-r--r--fs/reiserfs/xattr_acl.c1
-rw-r--r--fs/reiserfs/xattr_security.c3
-rw-r--r--fs/select.c19
-rw-r--r--fs/seq_file.c4
-rw-r--r--fs/signalfd.c1
-rw-r--r--fs/smbfs/file.c1
-rw-r--r--fs/smbfs/inode.c8
-rw-r--r--fs/smbfs/smbiod.c1
-rw-r--r--fs/smbfs/symlink.c1
-rw-r--r--fs/splice.c1
-rw-r--r--fs/squashfs/Makefile2
-rw-r--r--fs/squashfs/block.c81
-rw-r--r--fs/squashfs/cache.c1
-rw-r--r--fs/squashfs/decompressor.c68
-rw-r--r--fs/squashfs/decompressor.h55
-rw-r--r--fs/squashfs/dir.c1
-rw-r--r--fs/squashfs/export.c1
-rw-r--r--fs/squashfs/file.c1
-rw-r--r--fs/squashfs/fragment.c1
-rw-r--r--fs/squashfs/id.c1
-rw-r--r--fs/squashfs/inode.c1
-rw-r--r--fs/squashfs/namei.c1
-rw-r--r--fs/squashfs/squashfs.h8
-rw-r--r--fs/squashfs/squashfs_fs.h6
-rw-r--r--fs/squashfs/squashfs_fs_sb.h40
-rw-r--r--fs/squashfs/super.c53
-rw-r--r--fs/squashfs/symlink.c2
-rw-r--r--fs/squashfs/zlib_wrapper.c152
-rw-r--r--fs/super.c9
-rw-r--r--fs/sync.c18
-rw-r--r--fs/sysfs/bin.c50
-rw-r--r--fs/sysfs/dir.c132
-rw-r--r--fs/sysfs/file.c47
-rw-r--r--fs/sysfs/inode.c14
-rw-r--r--fs/sysfs/mount.c5
-rw-r--r--fs/sysfs/symlink.c39
-rw-r--r--fs/sysfs/sysfs.h17
-rw-r--r--fs/sysv/inode.c10
-rw-r--r--fs/sysv/sysv.h2
-rw-r--r--fs/timerfd.c1
-rw-r--r--fs/ubifs/commit.c1
-rw-r--r--fs/ubifs/debug.c1
-rw-r--r--fs/ubifs/dir.c2
-rw-r--r--fs/ubifs/file.c9
-rw-r--r--fs/ubifs/gc.c1
-rw-r--r--fs/ubifs/io.c1
-rw-r--r--fs/ubifs/lpt.c1
-rw-r--r--fs/ubifs/lpt_commit.c1
-rw-r--r--fs/ubifs/recovery.c1
-rw-r--r--fs/ubifs/sb.c1
-rw-r--r--fs/ubifs/super.c2
-rw-r--r--fs/ubifs/tnc.c1
-rw-r--r--fs/ubifs/ubifs.h1
-rw-r--r--fs/ubifs/xattr.c1
-rw-r--r--fs/udf/balloc.c94
-rw-r--r--fs/udf/file.c28
-rw-r--r--fs/udf/ialloc.c14
-rw-r--r--fs/udf/inode.c48
-rw-r--r--fs/udf/namei.c26
-rw-r--r--fs/udf/partition.c1
-rw-r--r--fs/udf/symlink.c1
-rw-r--r--fs/udf/udfdecl.h5
-rw-r--r--fs/udf/unicode.c1
-rw-r--r--fs/ufs/balloc.c24
-rw-r--r--fs/ufs/file.c3
-rw-r--r--fs/ufs/ialloc.c11
-rw-r--r--fs/ufs/inode.c9
-rw-r--r--fs/ufs/namei.c18
-rw-r--r--fs/ufs/super.c9
-rw-r--r--fs/ufs/truncate.c10
-rw-r--r--fs/ufs/ufs.h2
-rw-r--r--fs/ufs/ufs_fs.h15
-rw-r--r--fs/xattr_acl.c2
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/linux-2.6/kmem.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_acl.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c229
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c83
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c20
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c854
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c796
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h29
-rw-r--r--fs/xfs/linux-2.6/xfs_quotaops.c19
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c126
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h7
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.c16
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h22
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c3
-rw-r--r--fs/xfs/xfs_ag.h1
-rw-r--r--fs/xfs/xfs_bmap.c220
-rw-r--r--fs/xfs/xfs_dfrag.c22
-rw-r--r--fs/xfs/xfs_fs.h3
-rw-r--r--fs/xfs/xfs_iget.c19
-rw-r--r--fs/xfs/xfs_inode.c68
-rw-r--r--fs/xfs/xfs_inode.h3
-rw-r--r--fs/xfs/xfs_inode_item.c18
-rw-r--r--fs/xfs/xfs_itable.c2
-rw-r--r--fs/xfs/xfs_log.c144
-rw-r--r--fs/xfs/xfs_log.h16
-rw-r--r--fs/xfs/xfs_mount.c69
-rw-r--r--fs/xfs/xfs_mount.h3
-rw-r--r--fs/xfs/xfs_trans.c2
-rw-r--r--fs/xfs/xfs_trans.h2
-rw-r--r--fs/xfs/xfs_trans_buf.c216
-rw-r--r--fs/xfs/xfs_vnodeops.c107
-rw-r--r--fs/xfs/xfs_vnodeops.h15
-rw-r--r--include/acpi/acpi_drivers.h2
-rw-r--r--include/acpi/processor.h10
-rw-r--r--include/asm-generic/gpio.h26
-rw-r--r--include/asm-generic/pci-dma-compat.h15
-rw-r--r--include/drm/drmP.h35
-rw-r--r--include/drm/drm_mem_util.h65
-rw-r--r--include/drm/drm_pciids.h2
-rw-r--r--include/drm/ttm/ttm_bo_driver.h1
-rw-r--r--include/linux/acct.h3
-rw-r--r--include/linux/amba/bus.h3
-rw-r--r--include/linux/amba/clcd.h33
-rw-r--r--include/linux/amba/pl061.h2
-rw-r--r--include/linux/ata.h4
-rw-r--r--include/linux/backing-dev.h2
-rw-r--r--include/linux/backlight.h11
-rw-r--r--include/linux/binfmts.h1
-rw-r--r--include/linux/bitops.h3
-rw-r--r--include/linux/blkdev.h35
-rw-r--r--include/linux/btree-128.h109
-rw-r--r--include/linux/btree-type.h147
-rw-r--r--include/linux/btree.h243
-rw-r--r--include/linux/cgroup.h53
-rw-r--r--include/linux/circ_buf.h4
-rw-r--r--include/linux/clockchips.h2
-rw-r--r--include/linux/coda_psdev.h3
-rw-r--r--include/linux/compat.h3
-rw-r--r--include/linux/coredump.h45
-rw-r--r--include/linux/cpumask.h8
-rw-r--r--include/linux/cred.h2
-rw-r--r--include/linux/decompress/mm.h14
-rw-r--r--include/linux/delayacct.h1
-rw-r--r--include/linux/device-mapper.h5
-rw-r--r--include/linux/device.h40
-rw-r--r--include/linux/dm-io.h4
-rw-r--r--include/linux/dm-ioctl.h9
-rw-r--r--include/linux/dm9000.h2
-rw-r--r--include/linux/dma-mapping.h24
-rw-r--r--include/linux/drbd.h2
-rw-r--r--include/linux/drbd_nl.h3
-rw-r--r--include/linux/elf.h28
-rw-r--r--include/linux/elfcore.h17
-rw-r--r--include/linux/ethtool.h24
-rw-r--r--include/linux/exportfs.h5
-rw-r--r--include/linux/ext3_fs.h35
-rw-r--r--include/linux/ext3_fs_i.h2
-rw-r--r--include/linux/fault-inject.h5
-rw-r--r--include/linux/firewire-cdev.h78
-rw-r--r--include/linux/firewire-constants.h29
-rw-r--r--include/linux/firmware-map.h6
-rw-r--r--include/linux/freezer.h7
-rw-r--r--include/linux/fs.h31
-rw-r--r--include/linux/fscache-cache.h2
-rw-r--r--include/linux/fsnotify.h1
-rw-r--r--include/linux/ftrace_event.h23
-rw-r--r--include/linux/gameport.h1
-rw-r--r--include/linux/genhd.h2
-rw-r--r--include/linux/gfp.h12
-rw-r--r--include/linux/hil.h16
-rw-r--r--include/linux/htcpld.h24
-rw-r--r--include/linux/hw_breakpoint.h8
-rw-r--r--include/linux/i2c-algo-bit.h2
-rw-r--r--include/linux/i2c-xiic.h43
-rw-r--r--include/linux/i2c/pca953x.h11
-rw-r--r--include/linux/i2c/twl.h28
-rw-r--r--include/linux/i2o.h1
-rw-r--r--include/linux/ide.h1
-rw-r--r--include/linux/if_tunnel.h1
-rw-r--r--include/linux/init_task.h8
-rw-r--r--include/linux/input.h20
-rw-r--r--include/linux/input/matrix_keypad.h2
-rw-r--r--include/linux/io-mapping.h1
-rw-r--r--include/linux/iocontext.h2
-rw-r--r--include/linux/ioport.h20
-rw-r--r--include/linux/ipc_namespace.h5
-rw-r--r--include/linux/ipmi_smi.h1
-rw-r--r--include/linux/iscsi_ibft.h8
-rw-r--r--include/linux/jbd.h12
-rw-r--r--include/linux/jbd2.h23
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/kfifo.h5
-rw-r--r--include/linux/kmod.h1
-rw-r--r--include/linux/kobject.h14
-rw-r--r--include/linux/kprobes.h44
-rw-r--r--include/linux/kvm.h10
-rw-r--r--include/linux/kvm_host.h78
-rw-r--r--include/linux/lcm.h8
-rw-r--r--include/linux/libata.h1
-rw-r--r--include/linux/list.h6
-rw-r--r--include/linux/lockdep.h4
-rw-r--r--include/linux/lru_cache.h2
-rw-r--r--include/linux/memcontrol.h6
-rw-r--r--include/linux/memory.h2
-rw-r--r--include/linux/mfd/88pm8607.h217
-rw-r--r--include/linux/mfd/88pm860x.h375
-rw-r--r--include/linux/mfd/ab3100.h3
-rw-r--r--include/linux/mfd/max8925.h253
-rw-r--r--include/linux/mfd/mc13783.h26
-rw-r--r--include/linux/mfd/tmio.h3
-rw-r--r--include/linux/mfd/ucb1x00.h1
-rw-r--r--include/linux/mfd/wm831x/core.h6
-rw-r--r--include/linux/mfd/wm831x/gpio.h4
-rw-r--r--include/linux/mfd/wm8350/core.h49
-rw-r--r--include/linux/mfd/wm8350/gpio.h1
-rw-r--r--include/linux/mfd/wm8350/rtc.h1
-rw-r--r--include/linux/mfd/wm8994/core.h54
-rw-r--r--include/linux/mfd/wm8994/gpio.h72
-rw-r--r--include/linux/mfd/wm8994/pdata.h97
-rw-r--r--include/linux/mfd/wm8994/registers.h4292
-rw-r--r--include/linux/mm.h116
-rw-r--r--include/linux/mm_types.h43
-rw-r--r--include/linux/mmc/card.h7
-rw-r--r--include/linux/mmc/host.h5
-rw-r--r--include/linux/mmc/mmc.h1
-rw-r--r--include/linux/mmc/pm.h30
-rw-r--r--include/linux/mmc/sdio.h2
-rw-r--r--include/linux/mmc/sdio_func.h5
-rw-r--r--include/linux/mmzone.h9
-rw-r--r--include/linux/module.h26
-rw-r--r--include/linux/msdos_fs.h3
-rw-r--r--include/linux/ncp_fs_sb.h2
-rw-r--r--include/linux/netdevice.h8
-rw-r--r--include/linux/netfilter/nfnetlink.h2
-rw-r--r--include/linux/netfilter_ipv6.h1
-rw-r--r--include/linux/netlink.h2
-rw-r--r--include/linux/nfs_fs.h15
-rw-r--r--include/linux/nfs_fs_sb.h3
-rw-r--r--include/linux/nodemask.h13
-rw-r--r--include/linux/of.h2
-rw-r--r--include/linux/page_cgroup.h8
-rw-r--r--include/linux/pci-dma.h11
-rw-r--r--include/linux/pci.h5
-rw-r--r--include/linux/pci_regs.h1
-rw-r--r--include/linux/percpu.h31
-rw-r--r--include/linux/perf_event.h95
-rw-r--r--include/linux/platform_device.h9
-rw-r--r--include/linux/pm.h51
-rw-r--r--include/linux/pm_runtime.h6
-rw-r--r--include/linux/poison.h9
-rw-r--r--include/linux/poll.h2
-rw-r--r--include/linux/power_supply.h1
-rw-r--r--include/linux/ptrace.h5
-rw-r--r--include/linux/quota.h33
-rw-r--r--include/linux/quotaops.h304
-rw-r--r--include/linux/radix-tree.h7
-rw-r--r--include/linux/rbtree.h8
-rw-r--r--include/linux/rcupdate.h115
-rw-r--r--include/linux/reboot.h1
-rw-r--r--include/linux/regulator/consumer.h8
-rw-r--r--include/linux/reiserfs_fs.h2
-rw-r--r--include/linux/reiserfs_xattr.h5
-rw-r--r--include/linux/rfkill.h2
-rw-r--r--include/linux/rmap.h38
-rw-r--r--include/linux/rtc.h6
-rw-r--r--include/linux/rtmutex.h2
-rw-r--r--include/linux/rwlock.h20
-rw-r--r--include/linux/sched.h66
-rw-r--r--include/linux/security.h2
-rw-r--r--include/linux/serial_core.h11
-rw-r--r--include/linux/serial_sci.h10
-rw-r--r--include/linux/signal.h2
-rw-r--r--include/linux/skbuff.h6
-rw-r--r--include/linux/slab.h6
-rw-r--r--include/linux/slub_def.h27
-rw-r--r--include/linux/smb_fs_sb.h3
-rw-r--r--include/linux/smp.h2
-rw-r--r--include/linux/snmp.h2
-rw-r--r--include/linux/socket.h1
-rw-r--r--include/linux/spi/ads7846.h3
-rw-r--r--include/linux/spi/l4f00242t03.h31
-rw-r--r--include/linux/spi/max7301.h18
-rw-r--r--include/linux/spi/spi.h1
-rw-r--r--include/linux/spinlock.h13
-rw-r--r--include/linux/sunrpc/bc_xprt.h20
-rw-r--r--include/linux/swap.h9
-rw-r--r--include/linux/syscalls.h35
-rw-r--r--include/linux/sysdev.h21
-rw-r--r--include/linux/sysfs.h61
-rw-r--r--include/linux/taskstats_kern.h8
-rw-r--r--include/linux/tracepoint.h2
-rw-r--r--include/linux/tty.h11
-rw-r--r--include/linux/tty_ldisc.h8
-rw-r--r--include/linux/usb.h42
-rw-r--r--include/linux/usb/audio.h2
-rw-r--r--include/linux/usb/gadget.h2
-rw-r--r--include/linux/virtio.h1
-rw-r--r--include/linux/virtio_9p.h13
-rw-r--r--include/linux/virtio_console.h23
-rw-r--r--include/linux/vt.h3
-rw-r--r--include/linux/wimax/debug.h1
-rw-r--r--include/linux/writeback.h3
-rw-r--r--include/math-emu/op-common.h2
-rw-r--r--include/media/davinci/vpfe_capture.h2
-rw-r--r--include/net/9p/client.h20
-rw-r--r--include/net/ax25.h1
-rw-r--r--include/net/bluetooth/bluetooth.h2
-rw-r--r--include/net/fib_rules.h1
-rw-r--r--include/net/ip6_route.h18
-rw-r--r--include/net/ip6_tunnel.h1
-rw-r--r--include/net/ipx.h1
-rw-r--r--include/net/irda/irttp.h2
-rw-r--r--include/net/iucv/iucv.h1
-rw-r--r--include/net/mac80211.h3
-rw-r--r--include/net/net_namespace.h5
-rw-r--r--include/net/netfilter/nf_conntrack_extend.h2
-rw-r--r--include/net/netlabel.h1
-rw-r--r--include/net/netlink.h6
-rw-r--r--include/net/netrom.h1
-rw-r--r--include/net/sctp/command.h1
-rw-r--r--include/net/sctp/sctp.h1
-rw-r--r--include/net/sock.h18
-rw-r--r--include/net/tcp.h2
-rw-r--r--include/net/x25.h5
-rw-r--r--include/net/xfrm.h4
-rw-r--r--include/pcmcia/ds.h7
-rw-r--r--include/pcmcia/ss.h14
-rw-r--r--include/scsi/libiscsi.h3
-rw-r--r--include/scsi/libsas.h1
-rw-r--r--include/scsi/sg.h3
-rw-r--r--include/sound/ak4113.h2
-rw-r--r--include/sound/asound.h2
-rw-r--r--include/sound/soc-dai.h18
-rw-r--r--include/sound/soc.h1
-rw-r--r--include/trace/events/block.h164
-rw-r--r--include/trace/events/ext4.h101
-rw-r--r--include/trace/events/jbd2.h28
-rw-r--r--include/trace/events/kvm.h41
-rw-r--r--include/trace/ftrace.h48
-rw-r--r--include/trace/syscall.h8
-rw-r--r--include/video/broadsheetfb.h23
-rw-r--r--include/xen/xenbus.h1
-rw-r--r--init/Kconfig1
-rw-r--r--init/do_mounts.c1
-rw-r--r--init/do_mounts_rd.c1
-rw-r--r--init/initramfs.c15
-rw-r--r--init/main.c11
-rw-r--r--ipc/Makefile2
-rw-r--r--ipc/compat.c1
-rw-r--r--ipc/mqueue.c3
-rw-r--r--ipc/msg.c1
-rw-r--r--ipc/shm.c3
-rw-r--r--ipc/syscall.c99
-rw-r--r--kernel/Makefile3
-rw-r--r--kernel/acct.c10
-rw-r--r--kernel/async.c1
-rw-r--r--kernel/audit.c3
-rw-r--r--kernel/audit_tree.c1
-rw-r--r--kernel/audit_watch.c1
-rw-r--r--kernel/auditfilter.c1
-rw-r--r--kernel/auditsc.c3
-rw-r--r--kernel/cgroup.c694
-rw-r--r--kernel/cgroup_freezer.c10
-rw-r--r--kernel/compat.c1
-rw-r--r--kernel/cpu.c3
-rw-r--r--kernel/cpuset.c106
-rw-r--r--kernel/cred.c11
-rw-r--r--kernel/early_res.c6
-rw-r--r--kernel/elfcore.c28
-rw-r--r--kernel/exit.c8
-rw-r--r--kernel/fork.c69
-rw-r--r--kernel/hw_breakpoint.c11
-rw-r--r--kernel/irq/chip.c37
-rw-r--r--kernel/irq/devres.c4
-rw-r--r--kernel/irq/manage.c32
-rw-r--r--kernel/irq/numa_migrate.c1
-rw-r--r--kernel/irq/proc.c1
-rw-r--r--kernel/kallsyms.c1
-rw-r--r--kernel/kgdb.c205
-rw-r--r--kernel/kprobes.c648
-rw-r--r--kernel/ksysfs.c2
-rw-r--r--kernel/kthread.c2
-rw-r--r--kernel/latencytop.c1
-rw-r--r--kernel/lockdep.c32
-rw-r--r--kernel/module.c142
-rw-r--r--kernel/nsproxy.c14
-rw-r--r--kernel/padata.c9
-rw-r--r--kernel/panic.c46
-rw-r--r--kernel/params.c12
-rw-r--r--kernel/perf_event.c152
-rw-r--r--kernel/pid.c6
-rw-r--r--kernel/pid_namespace.c8
-rw-r--r--kernel/posix-cpu-timers.c46
-rw-r--r--kernel/power/hibernate.c10
-rw-r--r--kernel/power/hibernate_nvs.c1
-rw-r--r--kernel/power/process.c5
-rw-r--r--kernel/power/snapshot.c1
-rw-r--r--kernel/power/suspend.c4
-rw-r--r--kernel/power/swap.c1
-rw-r--r--kernel/power/user.c2
-rw-r--r--kernel/printk.c3
-rw-r--r--kernel/rcupdate.c30
-rw-r--r--kernel/rcutree.h21
-rw-r--r--kernel/rcutree_plugin.h8
-rw-r--r--kernel/relay.c5
-rw-r--r--kernel/res_counter.c1
-rw-r--r--kernel/resource.c44
-rw-r--r--kernel/sched.c27
-rw-r--r--kernel/sched_cpupri.c5
-rw-r--r--kernel/sched_debug.c4
-rw-r--r--kernel/sched_fair.c2
-rw-r--r--kernel/sched_rt.c12
-rw-r--r--kernel/signal.c2
-rw-r--r--kernel/slow-work.c2
-rw-r--r--kernel/slow-work.h8
-rw-r--r--kernel/smp.c1
-rw-r--r--kernel/softlockup.c4
-rw-r--r--kernel/srcu.c1
-rw-r--r--kernel/sys.c71
-rw-r--r--kernel/sys_ni.c1
-rw-r--r--kernel/sysctl.c49
-rw-r--r--kernel/sysctl_binary.c1
-rw-r--r--kernel/taskstats.c1
-rw-r--r--kernel/time.c1
-rw-r--r--kernel/time/clocksource.c4
-rw-r--r--kernel/time/tick-oneshot.c52
-rw-r--r--kernel/time/timecompare.c1
-rw-r--r--kernel/time/timekeeping.c3
-rw-r--r--kernel/time/timer_list.c3
-rw-r--r--kernel/timer.c2
-rw-r--r--kernel/trace/Makefile2
-rw-r--r--kernel/trace/blktrace.c1
-rw-r--r--kernel/trace/ftrace.c31
-rw-r--r--kernel/trace/power-traces.c1
-rw-r--r--kernel/trace/ring_buffer.c39
-rw-r--r--kernel/trace/trace.c51
-rw-r--r--kernel/trace/trace.h5
-rw-r--r--kernel/trace/trace_clock.c5
-rw-r--r--kernel/trace/trace_event_perf.c175
-rw-r--r--kernel/trace/trace_event_profile.c164
-rw-r--r--kernel/trace/trace_events.c3
-rw-r--r--kernel/trace/trace_events_filter.c1
-rw-r--r--kernel/trace/trace_functions_graph.c28
-rw-r--r--kernel/trace/trace_kprobe.c29
-rw-r--r--kernel/trace/trace_ksym.c1
-rw-r--r--kernel/trace/trace_mmiotrace.c1
-rw-r--r--kernel/trace/trace_selftest.c1
-rw-r--r--kernel/trace/trace_stat.c1
-rw-r--r--kernel/trace/trace_syscalls.c73
-rw-r--r--kernel/trace/trace_workqueue.c1
-rw-r--r--kernel/tsacct.c1
-rw-r--r--lib/Kconfig3
-rw-r--r--lib/Kconfig.debug18
-rw-r--r--lib/Makefile3
-rw-r--r--lib/bitmap.c19
-rw-r--r--lib/btree.c797
-rw-r--r--lib/cpumask.c1
-rw-r--r--lib/crc32.c31
-rw-r--r--lib/debugobjects.c1
-rw-r--r--lib/decompress_unlzo.c22
-rw-r--r--lib/devres.c1
-rw-r--r--lib/dma-debug.c2
-rw-r--r--lib/dynamic_debug.c1
-rw-r--r--lib/flex_array.c2
-rw-r--r--lib/genalloc.c1
-rw-r--r--lib/inflate.c1
-rw-r--r--lib/kasprintf.c1
-rw-r--r--lib/kobject.c6
-rw-r--r--lib/kobject_uevent.c3
-rw-r--r--lib/kref.c1
-rw-r--r--lib/lcm.c15
-rw-r--r--lib/list_sort.c263
-rw-r--r--lib/radix-tree.c13
-rw-r--r--lib/ratelimit.c11
-rw-r--r--lib/rwsem-spinlock.c14
-rw-r--r--lib/scatterlist.c1
-rw-r--r--lib/show_mem.c14
-rw-r--r--lib/string.c40
-rw-r--r--lib/swiotlb.c1
-rw-r--r--lib/textsearch.c1
-rw-r--r--lib/vsprintf.c85
-rw-r--r--lib/zlib_inflate/inffast.c72
-rw-r--r--mm/Makefile6
-rw-r--r--mm/backing-dev.c37
-rw-r--r--mm/bootmem.c31
-rw-r--r--mm/bounce.c1
-rw-r--r--mm/fadvise.c10
-rw-r--r--mm/failslab.c19
-rw-r--r--mm/filemap.c4
-rw-r--r--mm/filemap_xip.c3
-rw-r--r--mm/fremap.c2
-rw-r--r--mm/highmem.c2
-rw-r--r--mm/hugetlb.c7
-rw-r--r--mm/kmemleak.c1
-rw-r--r--mm/ksm.c26
-rw-r--r--mm/memcontrol.c1416
-rw-r--r--mm/memory-failure.c6
-rw-r--r--mm/memory.c167
-rw-r--r--mm/memory_hotplug.c10
-rw-r--r--mm/mempolicy.c165
-rw-r--r--mm/migrate.c5
-rw-r--r--mm/mincore.c2
-rw-r--r--mm/mlock.c12
-rw-r--r--mm/mmap.c262
-rw-r--r--mm/mmu_context.c1
-rw-r--r--mm/mmu_notifier.c1
-rw-r--r--mm/mprotect.c1
-rw-r--r--mm/mremap.c10
-rw-r--r--mm/nommu.c35
-rw-r--r--mm/oom_kill.c15
-rw-r--r--mm/page_alloc.c138
-rw-r--r--mm/page_cgroup.c42
-rw-r--r--mm/page_io.c1
-rw-r--r--mm/pagewalk.c47
-rw-r--r--mm/percpu.c26
-rw-r--r--mm/percpu_up.c30
-rw-r--r--mm/quicklist.c1
-rw-r--r--mm/readahead.c7
-rw-r--r--mm/rmap.c211
-rw-r--r--mm/slab.c26
-rw-r--r--mm/slub.c346
-rw-r--r--mm/sparse-vmemmap.c1
-rw-r--r--mm/sparse.c1
-rw-r--r--mm/swap.c3
-rw-r--r--mm/swap_state.c1
-rw-r--r--mm/swapfile.c71
-rw-r--r--mm/truncate.c1
-rw-r--r--mm/util.c21
-rw-r--r--mm/vmscan.c156
-rw-r--r--mm/vmstat.c3
-rw-r--r--net/802/garp.c1
-rw-r--r--net/802/p8022.c1
-rw-r--r--net/802/p8023.c1
-rw-r--r--net/802/psnap.c1
-rw-r--r--net/802/stp.c1
-rw-r--r--net/802/tr.c1
-rw-r--r--net/8021q/vlan.c3
-rw-r--r--net/8021q/vlan_core.c4
-rw-r--r--net/8021q/vlan_dev.c72
-rw-r--r--net/9p/client.c134
-rw-r--r--net/9p/protocol.c75
-rw-r--r--net/9p/protocol.h6
-rw-r--r--net/9p/trans_fd.c1
-rw-r--r--net/9p/trans_rdma.c1
-rw-r--r--net/9p/trans_virtio.c143
-rw-r--r--net/9p/util.c1
-rw-r--r--net/appletalk/aarp.c1
-rw-r--r--net/appletalk/ddp.c1
-rw-r--r--net/atm/addr.c1
-rw-r--r--net/atm/atm_sysfs.c1
-rw-r--r--net/atm/br2684.c1
-rw-r--r--net/atm/clip.c1
-rw-r--r--net/atm/common.c1
-rw-r--r--net/atm/lec.c1
-rw-r--r--net/atm/mpc.c1
-rw-r--r--net/atm/mpoa_caches.c1
-rw-r--r--net/atm/mpoa_proc.c1
-rw-r--r--net/atm/pppoatm.c1
-rw-r--r--net/atm/proc.c1
-rw-r--r--net/atm/raw.c1
-rw-r--r--net/atm/resources.c1
-rw-r--r--net/atm/signaling.c1
-rw-r--r--net/ax25/af_ax25.c1
-rw-r--r--net/ax25/ax25_dev.c1
-rw-r--r--net/ax25/ax25_ds_subr.c1
-rw-r--r--net/ax25/ax25_iface.c1
-rw-r--r--net/ax25/ax25_in.c1
-rw-r--r--net/ax25/ax25_ip.c1
-rw-r--r--net/ax25/ax25_out.c1
-rw-r--r--net/ax25/ax25_route.c1
-rw-r--r--net/ax25/ax25_subr.c1
-rw-r--r--net/ax25/ax25_uid.c1
-rw-r--r--net/ax25/sysctl_net_ax25.c1
-rw-r--r--net/bluetooth/af_bluetooth.c1
-rw-r--r--net/bluetooth/bnep/core.c1
-rw-r--r--net/bluetooth/bnep/netdev.c1
-rw-r--r--net/bluetooth/bnep/sock.c2
-rw-r--r--net/bluetooth/cmtp/sock.c2
-rw-r--r--net/bluetooth/hci_sysfs.c45
-rw-r--r--net/bluetooth/hidp/sock.c2
-rw-r--r--net/bluetooth/l2cap.c54
-rw-r--r--net/bluetooth/rfcomm/core.c40
-rw-r--r--net/bluetooth/rfcomm/sock.c39
-rw-r--r--net/bluetooth/sco.c39
-rw-r--r--net/bridge/Kconfig1
-rw-r--r--net/bridge/br_device.c2
-rw-r--r--net/bridge/br_fdb.c1
-rw-r--r--net/bridge/br_forward.c19
-rw-r--r--net/bridge/br_if.c1
-rw-r--r--net/bridge/br_input.c5
-rw-r--r--net/bridge/br_ioctl.c1
-rw-r--r--net/bridge/br_multicast.c47
-rw-r--r--net/bridge/br_netfilter.c1
-rw-r--r--net/bridge/br_netlink.c1
-rw-r--r--net/bridge/br_private.h12
-rw-r--r--net/bridge/br_stp_bpdu.c1
-rw-r--r--net/bridge/br_sysfs_if.c2
-rw-r--r--net/bridge/netfilter/ebt_ulog.c1
-rw-r--r--net/bridge/netfilter/ebtables.c1
-rw-r--r--net/can/bcm.c4
-rw-r--r--net/can/raw.c3
-rw-r--r--net/compat.c1
-rw-r--r--net/core/datagram.c1
-rw-r--r--net/core/dev.c17
-rw-r--r--net/core/dev_mcast.c5
-rw-r--r--net/core/drop_monitor.c1
-rw-r--r--net/core/dst.c1
-rw-r--r--net/core/ethtool.c104
-rw-r--r--net/core/fib_rules.c1
-rw-r--r--net/core/filter.c1
-rw-r--r--net/core/gen_estimator.c1
-rw-r--r--net/core/iovec.c1
-rw-r--r--net/core/link_watch.c1
-rw-r--r--net/core/neighbour.c3
-rw-r--r--net/core/net-sysfs.c1
-rw-r--r--net/core/net-traces.c1
-rw-r--r--net/core/netpoll.c12
-rw-r--r--net/core/rtnetlink.c5
-rw-r--r--net/core/scm.c1
-rw-r--r--net/core/sock.c19
-rw-r--r--net/core/sysctl_net_core.c1
-rw-r--r--net/dcb/dcbnl.c1
-rw-r--r--net/dccp/ccid.c2
-rw-r--r--net/dccp/ccids/ccid2.c1
-rw-r--r--net/dccp/feat.c1
-rw-r--r--net/dccp/input.c1
-rw-r--r--net/dccp/ipv4.c9
-rw-r--r--net/dccp/ipv6.c9
-rw-r--r--net/dccp/minisocks.c3
-rw-r--r--net/dccp/output.c1
-rw-r--r--net/dccp/probe.c1
-rw-r--r--net/dccp/proto.c17
-rw-r--r--net/decnet/dn_dev.c1
-rw-r--r--net/decnet/dn_fib.c1
-rw-r--r--net/decnet/dn_neigh.c1
-rw-r--r--net/decnet/dn_nsp_in.c1
-rw-r--r--net/decnet/dn_nsp_out.c1
-rw-r--r--net/decnet/dn_route.c1
-rw-r--r--net/decnet/dn_table.c1
-rw-r--r--net/decnet/netfilter/dn_rtmsg.c1
-rw-r--r--net/dsa/dsa.c1
-rw-r--r--net/dsa/tag_dsa.c1
-rw-r--r--net/dsa/tag_edsa.c1
-rw-r--r--net/dsa/tag_trailer.c1
-rw-r--r--net/econet/af_econet.c1
-rw-r--r--net/ethernet/pe2.c1
-rw-r--r--net/ieee802154/af_ieee802154.c7
-rw-r--r--net/ieee802154/dgram.c1
-rw-r--r--net/ieee802154/netlink.c1
-rw-r--r--net/ieee802154/nl-mac.c1
-rw-r--r--net/ieee802154/nl-phy.c1
-rw-r--r--net/ieee802154/raw.c1
-rw-r--r--net/ieee802154/wpan-class.c1
-rw-r--r--net/ipv4/af_inet.c6
-rw-r--r--net/ipv4/ah4.c1
-rw-r--r--net/ipv4/arp.c1
-rw-r--r--net/ipv4/cipso_ipv4.c1
-rw-r--r--net/ipv4/devinet.c3
-rw-r--r--net/ipv4/fib_frontend.c1
-rw-r--r--net/ipv4/fib_hash.c1
-rw-r--r--net/ipv4/fib_semantics.c1
-rw-r--r--net/ipv4/fib_trie.c9
-rw-r--r--net/ipv4/icmp.c1
-rw-r--r--net/ipv4/igmp.c1
-rw-r--r--net/ipv4/inet_diag.c1
-rw-r--r--net/ipv4/inet_fragment.c1
-rw-r--r--net/ipv4/inet_timewait_sock.c1
-rw-r--r--net/ipv4/ip_forward.c1
-rw-r--r--net/ipv4/ip_fragment.c1
-rw-r--r--net/ipv4/ip_gre.c12
-rw-r--r--net/ipv4/ip_input.c1
-rw-r--r--net/ipv4/ip_options.c1
-rw-r--r--net/ipv4/ip_output.c3
-rw-r--r--net/ipv4/ip_sockglue.c1
-rw-r--r--net/ipv4/ipconfig.c58
-rw-r--r--net/ipv4/ipip.c1
-rw-r--r--net/ipv4/ipmr.c15
-rw-r--r--net/ipv4/netfilter.c1
-rw-r--r--net/ipv4/netfilter/arptable_filter.c1
-rw-r--r--net/ipv4/netfilter/ip_queue.c1
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c1
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c1
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c1
-rw-r--r--net/ipv4/netfilter/iptable_filter.c1
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c1
-rw-r--r--net/ipv4/netfilter/iptable_raw.c1
-rw-r--r--net/ipv4/netfilter/iptable_security.c1
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c1
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c1
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c1
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c1
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c1
-rw-r--r--net/ipv4/proc.c2
-rw-r--r--net/ipv4/raw.c1
-rw-r--r--net/ipv4/route.c105
-rw-r--r--net/ipv4/sysctl_net_ipv4.c1
-rw-r--r--net/ipv4/tcp.c67
-rw-r--r--net/ipv4/tcp_cong.c1
-rw-r--r--net/ipv4/tcp_input.c4
-rw-r--r--net/ipv4/tcp_ipv4.c21
-rw-r--r--net/ipv4/tcp_minisocks.c3
-rw-r--r--net/ipv4/tcp_output.c19
-rw-r--r--net/ipv4/tcp_probe.c1
-rw-r--r--net/ipv4/tcp_timer.c3
-rw-r--r--net/ipv4/tunnel4.c1
-rw-r--r--net/ipv4/udp.c11
-rw-r--r--net/ipv4/xfrm4_input.c1
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c1
-rw-r--r--net/ipv4/xfrm4_policy.c5
-rw-r--r--net/ipv6/addrconf.c107
-rw-r--r--net/ipv6/addrlabel.c1
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/ah6.c1
-rw-r--r--net/ipv6/anycast.c1
-rw-r--r--net/ipv6/datagram.c1
-rw-r--r--net/ipv6/exthdrs.c1
-rw-r--r--net/ipv6/fib6_rules.c11
-rw-r--r--net/ipv6/icmp.c1
-rw-r--r--net/ipv6/inet6_connection_sock.c1
-rw-r--r--net/ipv6/ip6_fib.c1
-rw-r--r--net/ipv6/ip6_flowlabel.c1
-rw-r--r--net/ipv6/ip6_input.c1
-rw-r--r--net/ipv6/ip6_output.c5
-rw-r--r--net/ipv6/ip6_tunnel.c1
-rw-r--r--net/ipv6/ip6mr.c15
-rw-r--r--net/ipv6/ipv6_sockglue.c1
-rw-r--r--net/ipv6/mcast.c1
-rw-r--r--net/ipv6/ndisc.c1
-rw-r--r--net/ipv6/netfilter/ip6_queue.c1
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c1
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c1
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c1
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c3
-rw-r--r--net/ipv6/netfilter/ip6table_security.c1
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c1
-rw-r--r--net/ipv6/raw.c1
-rw-r--r--net/ipv6/reassembly.c1
-rw-r--r--net/ipv6/route.c29
-rw-r--r--net/ipv6/sit.c1
-rw-r--r--net/ipv6/sysctl_net_ipv6.c1
-rw-r--r--net/ipv6/tcp_ipv6.c10
-rw-r--r--net/ipv6/tunnel6.c1
-rw-r--r--net/ipv6/udp.c33
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c1
-rw-r--r--net/ipv6/xfrm6_policy.c5
-rw-r--r--net/ipv6/xfrm6_tunnel.c1
-rw-r--r--net/ipx/af_ipx.c1
-rw-r--r--net/ipx/ipx_route.c1
-rw-r--r--net/irda/af_irda.c1
-rw-r--r--net/irda/discovery.c1
-rw-r--r--net/irda/ircomm/ircomm_core.c1
-rw-r--r--net/irda/ircomm/ircomm_lmp.c1
-rw-r--r--net/irda/ircomm/ircomm_param.c1
-rw-r--r--net/irda/ircomm/ircomm_tty.c1
-rw-r--r--net/irda/irda_device.c1
-rw-r--r--net/irda/iriap.c1
-rw-r--r--net/irda/iriap_event.c2
-rw-r--r--net/irda/irias_object.c1
-rw-r--r--net/irda/irlan/irlan_client.c1
-rw-r--r--net/irda/irlan/irlan_common.c1
-rw-r--r--net/irda/irlan/irlan_provider.c1
-rw-r--r--net/irda/irlap_event.c1
-rw-r--r--net/irda/irlap_frame.c1
-rw-r--r--net/irda/irnet/irnet_irda.c1
-rw-r--r--net/irda/irnet/irnet_ppp.c1
-rw-r--r--net/irda/irnetlink.c1
-rw-r--r--net/irda/irqueue.c1
-rw-r--r--net/irda/irttp.c1
-rw-r--r--net/key/af_key.c9
-rw-r--r--net/lapb/lapb_iface.c1
-rw-r--r--net/lapb/lapb_in.c1
-rw-r--r--net/lapb/lapb_out.c1
-rw-r--r--net/lapb/lapb_subr.c1
-rw-r--r--net/llc/af_llc.c1
-rw-r--r--net/llc/llc_c_ac.c3
-rw-r--r--net/llc/llc_conn.c4
-rw-r--r--net/llc/llc_if.c1
-rw-r--r--net/llc/llc_input.c1
-rw-r--r--net/llc/llc_sap.c1
-rw-r--r--net/llc/llc_station.c1
-rw-r--r--net/mac80211/agg-rx.c1
-rw-r--r--net/mac80211/agg-tx.c2
-rw-r--r--net/mac80211/cfg.c1
-rw-r--r--net/mac80211/debugfs_key.c1
-rw-r--r--net/mac80211/debugfs_netdev.c11
-rw-r--r--net/mac80211/ibss.c1
-rw-r--r--net/mac80211/iface.c1
-rw-r--r--net/mac80211/key.c1
-rw-r--r--net/mac80211/led.c1
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mesh.c4
-rw-r--r--net/mac80211/mesh_hwmp.c5
-rw-r--r--net/mac80211/mesh_pathtbl.c1
-rw-r--r--net/mac80211/mesh_plink.c3
-rw-r--r--net/mac80211/mlme.c35
-rw-r--r--net/mac80211/rate.c1
-rw-r--r--net/mac80211/rate.h5
-rw-r--r--net/mac80211/rc80211_minstrel.c1
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c1
-rw-r--r--net/mac80211/rc80211_pid_algo.c1
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c1
-rw-r--r--net/mac80211/rx.c6
-rw-r--r--net/mac80211/scan.c1
-rw-r--r--net/mac80211/sta_info.c21
-rw-r--r--net/mac80211/tx.c6
-rw-r--r--net/mac80211/util.c18
-rw-r--r--net/mac80211/wep.c1
-rw-r--r--net/mac80211/work.c1
-rw-r--r--net/mac80211/wpa.c2
-rw-r--r--net/netfilter/core.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_app.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_dh.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_est.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_ftp.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_lblc.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_lblcr.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_proto.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_sh.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_wrr.c1
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c1
-rw-r--r--net/netfilter/nf_conntrack_acct.c1
-rw-r--r--net/netfilter/nf_conntrack_amanda.c1
-rw-r--r--net/netfilter/nf_conntrack_ecache.c1
-rw-r--r--net/netfilter/nf_conntrack_ftp.c1
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c1
-rw-r--r--net/netfilter/nf_conntrack_helper.c1
-rw-r--r--net/netfilter/nf_conntrack_irc.c1
-rw-r--r--net/netfilter/nf_conntrack_netlink.c5
-rw-r--r--net/netfilter/nf_conntrack_proto.c1
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c1
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c1
-rw-r--r--net/netfilter/nf_conntrack_sane.c1
-rw-r--r--net/netfilter/nf_conntrack_sip.c4
-rw-r--r--net/netfilter/nf_conntrack_standalone.c1
-rw-r--r--net/netfilter/nf_queue.c1
-rw-r--r--net/netfilter/nfnetlink.c4
-rw-r--r--net/netfilter/nfnetlink_log.c1
-rw-r--r--net/netfilter/nfnetlink_queue.c1
-rw-r--r--net/netfilter/x_tables.c1
-rw-r--r--net/netfilter/xt_CT.c1
-rw-r--r--net/netfilter/xt_LED.c1
-rw-r--r--net/netfilter/xt_RATEEST.c1
-rw-r--r--net/netfilter/xt_TCPMSS.c1
-rw-r--r--net/netfilter/xt_connlimit.c1
-rw-r--r--net/netfilter/xt_dccp.c1
-rw-r--r--net/netfilter/xt_hashlimit.c6
-rw-r--r--net/netfilter/xt_limit.c1
-rw-r--r--net/netfilter/xt_quota.c1
-rw-r--r--net/netfilter/xt_recent.c3
-rw-r--r--net/netfilter/xt_statistic.c1
-rw-r--r--net/netfilter/xt_string.c1
-rw-r--r--net/netlabel/netlabel_cipso_v4.c1
-rw-r--r--net/netlabel/netlabel_domainhash.c29
-rw-r--r--net/netlabel/netlabel_kapi.c1
-rw-r--r--net/netlabel/netlabel_mgmt.c1
-rw-r--r--net/netlabel/netlabel_unlabeled.c67
-rw-r--r--net/netlabel/netlabel_user.c1
-rw-r--r--net/netlink/af_netlink.c20
-rw-r--r--net/netlink/genetlink.c1
-rw-r--r--net/netrom/af_netrom.c1
-rw-r--r--net/netrom/nr_dev.c1
-rw-r--r--net/netrom/nr_in.c1
-rw-r--r--net/netrom/nr_loopback.c1
-rw-r--r--net/netrom/nr_out.c1
-rw-r--r--net/netrom/nr_route.c1
-rw-r--r--net/netrom/nr_subr.c1
-rw-r--r--net/packet/af_packet.c9
-rw-r--r--net/phonet/af_phonet.c1
-rw-r--r--net/phonet/datagram.c1
-rw-r--r--net/phonet/pep.c1
-rw-r--r--net/phonet/pn_dev.c4
-rw-r--r--net/phonet/pn_netlink.c4
-rw-r--r--net/phonet/socket.c1
-rw-r--r--net/rds/af_rds.c1
-rw-r--r--net/rds/cong.c1
-rw-r--r--net/rds/connection.c1
-rw-r--r--net/rds/ib.c1
-rw-r--r--net/rds/ib_cm.c1
-rw-r--r--net/rds/ib_rdma.c1
-rw-r--r--net/rds/ib_recv.c1
-rw-r--r--net/rds/info.c1
-rw-r--r--net/rds/iw.c1
-rw-r--r--net/rds/iw_cm.c1
-rw-r--r--net/rds/iw_rdma.c1
-rw-r--r--net/rds/iw_recv.c1
-rw-r--r--net/rds/loop.c1
-rw-r--r--net/rds/message.c1
-rw-r--r--net/rds/page.c1
-rw-r--r--net/rds/rdma.c1
-rw-r--r--net/rds/rdma_transport.c2
-rw-r--r--net/rds/recv.c1
-rw-r--r--net/rds/send.c1
-rw-r--r--net/rds/tcp.c1
-rw-r--r--net/rds/tcp_listen.c1
-rw-r--r--net/rds/tcp_recv.c1
-rw-r--r--net/rfkill/core.c1
-rw-r--r--net/rfkill/input.c8
-rw-r--r--net/rose/af_rose.c1
-rw-r--r--net/rose/rose_dev.c1
-rw-r--r--net/rose/rose_link.c1
-rw-r--r--net/rose/rose_loopback.c1
-rw-r--r--net/rose/rose_out.c1
-rw-r--r--net/rose/rose_route.c1
-rw-r--r--net/rose/rose_subr.c1
-rw-r--r--net/rxrpc/af_rxrpc.c1
-rw-r--r--net/rxrpc/ar-accept.c7
-rw-r--r--net/rxrpc/ar-ack.c1
-rw-r--r--net/rxrpc/ar-call.c1
-rw-r--r--net/rxrpc/ar-connection.c1
-rw-r--r--net/rxrpc/ar-input.c1
-rw-r--r--net/rxrpc/ar-key.c1
-rw-r--r--net/rxrpc/ar-local.c1
-rw-r--r--net/rxrpc/ar-output.c1
-rw-r--r--net/rxrpc/ar-peer.c1
-rw-r--r--net/rxrpc/ar-transport.c1
-rw-r--r--net/rxrpc/rxkad.c1
-rw-r--r--net/sched/Kconfig5
-rw-r--r--net/sched/act_api.c1
-rw-r--r--net/sched/act_ipt.c1
-rw-r--r--net/sched/act_mirred.c1
-rw-r--r--net/sched/act_pedit.c1
-rw-r--r--net/sched/act_police.c1
-rw-r--r--net/sched/act_simple.c1
-rw-r--r--net/sched/cls_api.c1
-rw-r--r--net/sched/cls_basic.c1
-rw-r--r--net/sched/cls_cgroup.c37
-rw-r--r--net/sched/cls_flow.c1
-rw-r--r--net/sched/cls_fw.c1
-rw-r--r--net/sched/cls_route.c1
-rw-r--r--net/sched/cls_tcindex.c1
-rw-r--r--net/sched/cls_u32.c1
-rw-r--r--net/sched/em_meta.c1
-rw-r--r--net/sched/em_nbyte.c1
-rw-r--r--net/sched/em_text.c1
-rw-r--r--net/sched/ematch.c1
-rw-r--r--net/sched/sch_api.c1
-rw-r--r--net/sched/sch_atm.c1
-rw-r--r--net/sched/sch_cbq.c1
-rw-r--r--net/sched/sch_drr.c1
-rw-r--r--net/sched/sch_dsmark.c1
-rw-r--r--net/sched/sch_fifo.c1
-rw-r--r--net/sched/sch_generic.c1
-rw-r--r--net/sched/sch_gred.c1
-rw-r--r--net/sched/sch_htb.c1
-rw-r--r--net/sched/sch_mq.c1
-rw-r--r--net/sched/sch_multiq.c1
-rw-r--r--net/sched/sch_netem.c1
-rw-r--r--net/sched/sch_prio.c1
-rw-r--r--net/sched/sch_sfq.c1
-rw-r--r--net/sched/sch_teql.c1
-rw-r--r--net/sctp/associola.c6
-rw-r--r--net/sctp/auth.c1
-rw-r--r--net/sctp/bind_addr.c1
-rw-r--r--net/sctp/chunk.c1
-rw-r--r--net/sctp/endpointola.c1
-rw-r--r--net/sctp/input.c43
-rw-r--r--net/sctp/inqueue.c1
-rw-r--r--net/sctp/ipv6.c1
-rw-r--r--net/sctp/output.c1
-rw-r--r--net/sctp/outqueue.c1
-rw-r--r--net/sctp/primitive.c1
-rw-r--r--net/sctp/protocol.c1
-rw-r--r--net/sctp/sm_make_chunk.c33
-rw-r--r--net/sctp/sm_sideeffect.c29
-rw-r--r--net/sctp/sm_statefuns.c9
-rw-r--r--net/sctp/socket.c18
-rw-r--r--net/sctp/ssnmap.c1
-rw-r--r--net/sctp/transport.c1
-rw-r--r--net/sctp/tsnmap.c1
-rw-r--r--net/sctp/ulpevent.c1
-rw-r--r--net/sctp/ulpqueue.c1
-rw-r--r--net/socket.c5
-rw-r--r--net/sunrpc/addr.c9
-rw-r--r--net/sunrpc/auth.c2
-rw-r--r--net/sunrpc/auth_generic.c1
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c16
-rw-r--r--net/sunrpc/auth_gss/gss_generic_token.c1
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c1
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seal.c1
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seqnum.c1
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_unseal.c1
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c1
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_seal.c1
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c1
-rw-r--r--net/sunrpc/auth_unix.c1
-rw-r--r--net/sunrpc/backchannel_rqst.c1
-rw-r--r--net/sunrpc/bc_svc.c15
-rw-r--r--net/sunrpc/clnt.c1
-rw-r--r--net/sunrpc/rpc_pipe.c2
-rw-r--r--net/sunrpc/rpcb_clnt.c1
-rw-r--r--net/sunrpc/socklib.c1
-rw-r--r--net/sunrpc/stats.c1
-rw-r--r--net/sunrpc/svc.c7
-rw-r--r--net/sunrpc/svc_xprt.c28
-rw-r--r--net/sunrpc/svcauth_unix.c50
-rw-r--r--net/sunrpc/svcsock.c3
-rw-r--r--net/sunrpc/xdr.c1
-rw-r--r--net/sunrpc/xprt.c22
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma.c1
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c6
-rw-r--r--net/sunrpc/xprtrdma/transport.c8
-rw-r--r--net/sunrpc/xprtrdma/verbs.c1
-rw-r--r--net/sunrpc/xprtsock.c29
-rw-r--r--net/tipc/bearer.c37
-rw-r--r--net/tipc/bearer.h2
-rw-r--r--net/tipc/core.h1
-rw-r--r--net/tipc/eth_media.c1
-rw-r--r--net/tipc/link.c9
-rw-r--r--net/tipc/net.c25
-rw-r--r--net/tipc/ref.c26
-rw-r--r--net/tipc/socket.c8
-rw-r--r--net/tipc/subscr.c57
-rw-r--r--net/tipc/subscr.h2
-rw-r--r--net/unix/garbage.c1
-rw-r--r--net/unix/sysctl_net_unix.c1
-rw-r--r--net/wimax/op-msg.c1
-rw-r--r--net/wimax/stack.c1
-rw-r--r--net/wireless/core.c1
-rw-r--r--net/wireless/debugfs.c1
-rw-r--r--net/wireless/ibss.c1
-rw-r--r--net/wireless/mlme.c1
-rw-r--r--net/wireless/nl80211.c1
-rw-r--r--net/wireless/reg.c13
-rw-r--r--net/wireless/scan.c1
-rw-r--r--net/wireless/sme.c1
-rw-r--r--net/wireless/util.c1
-rw-r--r--net/wireless/wext-compat.c1
-rw-r--r--net/wireless/wext-core.c1
-rw-r--r--net/wireless/wext-priv.c1
-rw-r--r--net/wireless/wext-sme.c1
-rw-r--r--net/x25/af_x25.c69
-rw-r--r--net/x25/x25_dev.c3
-rw-r--r--net/x25/x25_facilities.c27
-rw-r--r--net/x25/x25_forward.c1
-rw-r--r--net/x25/x25_in.c16
-rw-r--r--net/x25/x25_link.c1
-rw-r--r--net/x25/x25_out.c1
-rw-r--r--net/x25/x25_route.c1
-rw-r--r--net/x25/x25_subr.c1
-rw-r--r--net/xfrm/xfrm_ipcomp.c2
-rw-r--r--net/xfrm/xfrm_output.c1
-rw-r--r--net/xfrm/xfrm_policy.c7
-rw-r--r--net/xfrm/xfrm_state.c1
-rw-r--r--net/xfrm/xfrm_sysctl.c1
-rw-r--r--samples/hw_breakpoint/data_breakpoint.c6
-rw-r--r--samples/kobject/kobject-example.c4
-rw-r--r--samples/kobject/kset-example.c7
-rwxr-xr-xscripts/checkpatch.pl78
-rwxr-xr-xscripts/get_maintainer.pl185
-rw-r--r--scripts/gfp-translate2
-rwxr-xr-xscripts/kernel-doc5
-rw-r--r--security/device_cgroup.c1
-rw-r--r--security/inode.c4
-rw-r--r--security/integrity/ima/ima_api.c1
-rw-r--r--security/integrity/ima/ima_audit.c1
-rw-r--r--security/integrity/ima/ima_crypto.c1
-rw-r--r--security/integrity/ima/ima_fs.c1
-rw-r--r--security/integrity/ima/ima_iint.c1
-rw-r--r--security/integrity/ima/ima_init.c1
-rw-r--r--security/integrity/ima/ima_main.c1
-rw-r--r--security/integrity/ima/ima_policy.c1
-rw-r--r--security/integrity/ima/ima_queue.c1
-rw-r--r--security/keys/keyring.c2
-rw-r--r--security/keys/proc.c1
-rw-r--r--security/keys/process_keys.c1
-rw-r--r--security/keys/request_key.c22
-rw-r--r--security/lsm_audit.c1
-rw-r--r--security/selinux/avc.c6
-rw-r--r--security/selinux/netif.c1
-rw-r--r--security/selinux/netlabel.c1
-rw-r--r--security/selinux/netlink.c1
-rw-r--r--security/selinux/netnode.c1
-rw-r--r--security/selinux/netport.c1
-rw-r--r--security/selinux/ss/avtab.h2
-rw-r--r--security/selinux/ss/symtab.c1
-rw-r--r--security/selinux/xfrm.c1
-rw-r--r--security/smack/smack_access.c1
-rw-r--r--security/smack/smack_lsm.c1
-rw-r--r--security/smack/smackfs.c1
-rw-r--r--security/tomoyo/common.c2
-rw-r--r--security/tomoyo/domain.c1
-rw-r--r--security/tomoyo/file.c1
-rw-r--r--security/tomoyo/gc.c1
-rw-r--r--security/tomoyo/realpath.c1
-rw-r--r--sound/aoa/codecs/onyx.c1
-rw-r--r--sound/aoa/codecs/tas.c1
-rw-r--r--sound/aoa/codecs/toonie.c1
-rw-r--r--sound/aoa/core/gpio-pmf.c1
-rw-r--r--sound/aoa/fabrics/layout.c1
-rw-r--r--sound/aoa/soundbus/i2sbus/control.c1
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c1
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c1
-rw-r--r--sound/arm/aaci.c7
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c68
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c2
-rw-r--r--sound/core/control_compat.c1
-rw-r--r--sound/core/hrtimer.c1
-rw-r--r--sound/core/info.c1
-rw-r--r--sound/core/jack.c1
-rw-r--r--sound/core/misc.c1
-rw-r--r--sound/core/oss/route.c1
-rw-r--r--sound/core/pcm_compat.c1
-rw-r--r--sound/core/pcm_lib.c6
-rw-r--r--sound/core/pcm_memory.c1
-rw-r--r--sound/core/seq/oss/seq_oss_init.c1
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c1
-rw-r--r--sound/core/seq/oss/seq_oss_readq.c1
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c1
-rw-r--r--sound/core/seq/oss/seq_oss_timer.c1
-rw-r--r--sound/core/seq/oss/seq_oss_writeq.c1
-rw-r--r--sound/core/seq/seq_compat.c1
-rw-r--r--sound/core/seq/seq_system.c1
-rw-r--r--sound/core/timer.c2
-rw-r--r--sound/drivers/ml403-ac97cr.c1
-rw-r--r--sound/drivers/mtpav.c1
-rw-r--r--sound/drivers/mts64.c1
-rw-r--r--sound/drivers/opl3/opl3_oss.c1
-rw-r--r--sound/drivers/opl3/opl3_synth.c1
-rw-r--r--sound/drivers/opl4/opl4_lib.c1
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c1
-rw-r--r--sound/drivers/portman2x4.c1
-rw-r--r--sound/drivers/vx/vx_hwdep.c1
-rw-r--r--sound/i2c/other/ak4113.c2
-rw-r--r--sound/i2c/other/tea575x-tuner.c1
-rw-r--r--sound/isa/cmi8330.c1
-rw-r--r--sound/isa/cs423x/cs4236.c1
-rw-r--r--sound/isa/es18xx.c1
-rw-r--r--sound/isa/gus/interwave.c1
-rw-r--r--sound/isa/msnd/msnd_midi.c1
-rw-r--r--sound/isa/opl3sa2.c1
-rw-r--r--sound/isa/opti9xx/miro.c3
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c122
-rw-r--r--sound/isa/sb/emu8000_pcm.c1
-rw-r--r--sound/isa/sb/jazz16.c1
-rw-r--r--sound/isa/sb/sb16.c1
-rw-r--r--sound/isa/sb/sb8.c1
-rw-r--r--sound/isa/wavefront/wavefront.c1
-rw-r--r--sound/isa/wavefront/wavefront_fx.c1
-rw-r--r--sound/isa/wavefront/wavefront_synth.c1
-rw-r--r--sound/mips/hal2.c1
-rw-r--r--sound/mips/sgio2audio.c2
-rw-r--r--sound/oss/ad1848.c1
-rw-r--r--sound/oss/coproc.h2
-rw-r--r--sound/oss/dmabuf.c1
-rw-r--r--sound/oss/kahlua.c1
-rw-r--r--sound/oss/mpu401.c1
-rw-r--r--sound/oss/msnd.c1
-rw-r--r--sound/oss/msnd_pinnacle.c2
-rw-r--r--sound/oss/opl3.c1
-rw-r--r--sound/oss/sb_card.c1
-rw-r--r--sound/oss/sb_common.c1
-rw-r--r--sound/oss/sb_midi.c1
-rw-r--r--sound/oss/sb_mixer.c2
-rw-r--r--sound/oss/sequencer.c2
-rw-r--r--sound/oss/soundcard.c1
-rw-r--r--sound/oss/uart401.c1
-rw-r--r--sound/oss/v_midi.c1
-rw-r--r--sound/oss/v_midi.h5
-rw-r--r--sound/oss/vidc.c5
-rw-r--r--sound/oss/vwsnd.c1
-rw-r--r--sound/oss/waveartist.c1
-rw-r--r--sound/pci/ac97/ac97_patch.c2
-rw-r--r--sound/pci/ac97/ac97_proc.c1
-rw-r--r--sound/pci/als4000.c1
-rw-r--r--sound/pci/aw2/aw2-saa7146.c1
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c1
-rw-r--r--sound/pci/ca0106/ca0106_proc.c1
-rw-r--r--sound/pci/cmipci.c14
-rw-r--r--sound/pci/cs5530.c1
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c1
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c1
-rw-r--r--sound/pci/ctxfi/ctatc.c1
-rw-r--r--sound/pci/ctxfi/ctpcm.c1
-rw-r--r--sound/pci/echoaudio/darla20.c2
-rw-r--r--sound/pci/echoaudio/darla24.c2
-rw-r--r--sound/pci/echoaudio/echo3g.c2
-rw-r--r--sound/pci/echoaudio/echoaudio.c5
-rw-r--r--sound/pci/echoaudio/gina20.c2
-rw-r--r--sound/pci/echoaudio/gina24.c2
-rw-r--r--sound/pci/echoaudio/indigo.c2
-rw-r--r--sound/pci/echoaudio/indigodj.c2
-rw-r--r--sound/pci/echoaudio/indigodjx.c2
-rw-r--r--sound/pci/echoaudio/indigoio.c2
-rw-r--r--sound/pci/echoaudio/indigoiox.c2
-rw-r--r--sound/pci/echoaudio/layla20.c2
-rw-r--r--sound/pci/echoaudio/layla24.c2
-rw-r--r--sound/pci/echoaudio/mia.c2
-rw-r--r--sound/pci/echoaudio/mona.c2
-rw-r--r--sound/pci/emu10k1/memory.c1
-rw-r--r--sound/pci/hda/Kconfig2
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/hda_beep.c1
-rw-r--r--sound/pci/hda/hda_codec.c73
-rw-r--r--sound/pci/hda/hda_eld.c7
-rw-r--r--sound/pci/hda/hda_intel.c23
-rw-r--r--sound/pci/hda/patch_analog.c17
-rw-r--r--sound/pci/hda/patch_conexant.c15
-rw-r--r--sound/pci/hda/patch_hdmi.c849
-rw-r--r--sound/pci/hda/patch_intelhdmi.c821
-rw-r--r--sound/pci/hda/patch_nvhdmi.c278
-rw-r--r--sound/pci/hda/patch_realtek.c358
-rw-r--r--sound/pci/hda/patch_sigmatel.c6
-rw-r--r--sound/pci/hda/patch_via.c41
-rw-r--r--sound/pci/ice1712/ak4xxx.c1
-rw-r--r--sound/pci/ice1712/amp.c1
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c1
-rw-r--r--sound/pci/ice1712/wtm.c1
-rw-r--r--sound/pci/lx6464es/lx6464es.c1
-rw-r--r--sound/pci/maestro3.c9
-rw-r--r--sound/pci/mixart/mixart.c25
-rw-r--r--sound/pci/mixart/mixart_hwdep.c1
-rw-r--r--sound/pci/oxygen/oxygen_lib.c1
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c2
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/pci/rme32.c2
-rw-r--r--sound/pci/rme96.c1
-rw-r--r--sound/pci/rme9652/hdsp.c1
-rw-r--r--sound/pci/rme9652/hdspm.c2
-rw-r--r--sound/pci/rme9652/rme9652.c1
-rw-r--r--sound/pci/sis7019.c1
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c1
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c1
-rw-r--r--sound/pcmcia/vx/vxpocket.c1
-rw-r--r--sound/ppc/burgundy.c1
-rw-r--r--sound/ppc/keywest.c1
-rw-r--r--sound/ppc/snd_ps3.c2
-rw-r--r--sound/sh/sh_dac_audio.c1
-rw-r--r--sound/soc/atmel/atmel-pcm.c2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c6
-rw-r--r--sound/soc/au1x/psc-ac97.c1
-rw-r--r--sound/soc/au1x/psc-i2s.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c1
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c2
-rw-r--r--sound/soc/codecs/ac97.c16
-rw-r--r--sound/soc/codecs/ad1836.c1
-rw-r--r--sound/soc/codecs/ad1938.c1
-rw-r--r--sound/soc/codecs/ad1980.c1
-rw-r--r--sound/soc/codecs/ad73311.c1
-rw-r--r--sound/soc/codecs/ads117x.c1
-rw-r--r--sound/soc/codecs/ak4104.c7
-rw-r--r--sound/soc/codecs/ak4535.c1
-rw-r--r--sound/soc/codecs/ak4642.c1
-rw-r--r--sound/soc/codecs/ak4671.c1
-rw-r--r--sound/soc/codecs/cs4270.c1
-rw-r--r--sound/soc/codecs/cx20442.c1
-rw-r--r--sound/soc/codecs/da7210.c1
-rw-r--r--sound/soc/codecs/pcm3008.c1
-rw-r--r--sound/soc/codecs/ssm2602.c1
-rw-r--r--sound/soc/codecs/stac9766.c1
-rw-r--r--sound/soc/codecs/tlv320aic23.c1
-rw-r--r--sound/soc/codecs/tlv320aic26.c1
-rw-r--r--sound/soc/codecs/tlv320aic3x.c1
-rw-r--r--sound/soc/codecs/tlv320dac33.c11
-rw-r--r--sound/soc/codecs/tpa6130a2.c1
-rw-r--r--sound/soc/codecs/twl4030.c1
-rw-r--r--sound/soc/codecs/uda134x.c1
-rw-r--r--sound/soc/codecs/uda1380.c2
-rw-r--r--sound/soc/codecs/wm2000.c2
-rw-r--r--sound/soc/codecs/wm8350.c9
-rw-r--r--sound/soc/codecs/wm8400.c1
-rw-r--r--sound/soc/codecs/wm8510.c1
-rw-r--r--sound/soc/codecs/wm8523.c1
-rw-r--r--sound/soc/codecs/wm8580.c1
-rw-r--r--sound/soc/codecs/wm8711.c1
-rw-r--r--sound/soc/codecs/wm8727.c1
-rw-r--r--sound/soc/codecs/wm8728.c1
-rw-r--r--sound/soc/codecs/wm8731.c1
-rw-r--r--sound/soc/codecs/wm8750.c1
-rw-r--r--sound/soc/codecs/wm8753.c1
-rw-r--r--sound/soc/codecs/wm8776.c1
-rw-r--r--sound/soc/codecs/wm8900.c1
-rw-r--r--sound/soc/codecs/wm8903.c1
-rw-r--r--sound/soc/codecs/wm8904.c1
-rw-r--r--sound/soc/codecs/wm8940.c1
-rw-r--r--sound/soc/codecs/wm8955.c1
-rw-r--r--sound/soc/codecs/wm8960.c1
-rw-r--r--sound/soc/codecs/wm8961.c1
-rw-r--r--sound/soc/codecs/wm8971.c1
-rw-r--r--sound/soc/codecs/wm8974.c1
-rw-r--r--sound/soc/codecs/wm8978.c1
-rw-r--r--sound/soc/codecs/wm8988.c1
-rw-r--r--sound/soc/codecs/wm8990.c3
-rw-r--r--sound/soc/codecs/wm8993.c1
-rw-r--r--sound/soc/codecs/wm8994.c59
-rw-r--r--sound/soc/codecs/wm9081.c1
-rw-r--r--sound/soc/codecs/wm9705.c1
-rw-r--r--sound/soc/codecs/wm9712.c1
-rw-r--r--sound/soc/codecs/wm9713.c1
-rw-r--r--sound/soc/codecs/wm_hubs.c83
-rw-r--r--sound/soc/codecs/wm_hubs.h1
-rw-r--r--sound/soc/davinci/davinci-i2s.c4
-rw-r--r--sound/soc/davinci/davinci-mcasp.c4
-rw-r--r--sound/soc/davinci/davinci-pcm.c4
-rw-r--r--sound/soc/fsl/fsl_dma.c1
-rw-r--r--sound/soc/fsl/fsl_ssi.c1
-rw-r--r--sound/soc/fsl/mpc5200_dma.c1
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c1
-rw-r--r--sound/soc/fsl/soc-of-simple.c1
-rw-r--r--sound/soc/imx/Kconfig2
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c24
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c56
-rw-r--r--sound/soc/imx/imx-ssi.c11
-rw-r--r--sound/soc/omap/mcpdm.c1
-rw-r--r--sound/soc/omap/omap-mcbsp.c4
-rw-r--r--sound/soc/omap/omap-mcpdm.c3
-rw-r--r--sound/soc/omap/omap-pcm.c22
-rw-r--r--sound/soc/pxa/pxa-ssp.c117
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c17
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c7
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c4
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.c21
-rw-r--r--sound/soc/s3c24xx/s3c-dma.c4
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c13
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.c7
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c19
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c4
-rw-r--r--sound/soc/s6000/s6000-i2s.c4
-rw-r--r--sound/soc/s6000/s6000-pcm.c40
-rw-r--r--sound/soc/sh/Kconfig1
-rw-r--r--sound/soc/sh/dma-sh7760.c1
-rw-r--r--sound/soc/sh/fsi.c1
-rw-r--r--sound/soc/sh/siu.h2
-rw-r--r--sound/soc/sh/siu_dai.c1
-rw-r--r--sound/soc/sh/siu_pcm.c3
-rw-r--r--sound/soc/soc-core.c18
-rw-r--r--sound/soc/soc-dapm.c1
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c1
-rw-r--r--sound/soc/txx9/txx9aclc.c1
-rw-r--r--sound/sound_firmware.c1
-rw-r--r--sound/sparc/cs4231.c1
-rw-r--r--sound/sparc/dbri.c1
-rw-r--r--sound/synth/emux/emux_proc.c1
-rw-r--r--sound/usb/Kconfig6
-rw-r--r--sound/usb/caiaq/audio.c1
-rw-r--r--sound/usb/caiaq/device.c1
-rw-r--r--sound/usb/caiaq/midi.c1
-rw-r--r--sound/usb/caiaq/midi.h2
-rw-r--r--sound/usb/ua101.c100
-rw-r--r--sound/usb/usbaudio.c57
-rw-r--r--sound/usb/usbaudio.h3
-rw-r--r--sound/usb/usbmidi.c24
-rw-r--r--sound/usb/usbquirks.h30
-rw-r--r--sound/usb/usx2y/us122l.c1
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c1
-rw-r--r--sound/usb/usx2y/usb_stream.c1
-rw-r--r--sound/usb/usx2y/usbusx2y.c1
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c1
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c1
-rw-r--r--tools/perf/Documentation/Makefile4
-rw-r--r--tools/perf/Documentation/perf-lock.txt29
-rw-r--r--tools/perf/Documentation/perf-probe.txt58
-rw-r--r--tools/perf/Makefile24
-rw-r--r--tools/perf/builtin-annotate.c6
-rw-r--r--tools/perf/builtin-diff.c13
-rw-r--r--tools/perf/builtin-lock.c148
-rw-r--r--tools/perf/builtin-probe.c37
-rw-r--r--tools/perf/builtin-record.c13
-rw-r--r--tools/perf/builtin-report.c112
-rw-r--r--tools/perf/builtin-stat.c10
-rw-r--r--tools/perf/builtin-top.c22
-rw-r--r--tools/perf/builtin-trace.c4
-rw-r--r--tools/perf/command-list.txt1
-rw-r--r--tools/perf/perf-archive.sh3
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/perf.h4
-rw-r--r--tools/perf/util/cpumap.c59
-rw-r--r--tools/perf/util/cpumap.h7
-rw-r--r--tools/perf/util/event.h9
-rw-r--r--tools/perf/util/hist.c52
-rw-r--r--tools/perf/util/hist.h12
-rw-r--r--tools/perf/util/probe-event.c59
-rw-r--r--tools/perf/util/probe-finder.c1004
-rw-r--r--tools/perf/util/probe-finder.h52
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c17
-rw-r--r--tools/perf/util/session.c1
-rw-r--r--tools/perf/util/session.h1
-rw-r--r--tools/perf/util/string.c55
-rw-r--r--tools/perf/util/string.h1
-rw-r--r--tools/perf/util/symbol.c18
-rw-r--r--tools/perf/util/symbol.h3
-rw-r--r--tools/perf/util/thread.c41
-rw-r--r--tools/perf/util/thread.h3
-rw-r--r--virt/kvm/Kconfig3
-rw-r--r--virt/kvm/assigned-dev.c13
-rw-r--r--virt/kvm/coalesced_mmio.c44
-rw-r--r--virt/kvm/coalesced_mmio.h15
-rw-r--r--virt/kvm/eventfd.c22
-rw-r--r--virt/kvm/ioapic.c39
-rw-r--r--virt/kvm/ioapic.h2
-rw-r--r--virt/kvm/iommu.c36
-rw-r--r--virt/kvm/irq_comm.c1
-rw-r--r--virt/kvm/kvm_main.c411
7774 files changed, 264339 insertions, 129756 deletions
diff --git a/.gitignore b/.gitignore
index de6344e1570..a2939fc10b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,13 +34,18 @@ modules.builtin
#
# Top-level generic files
#
-tags
-TAGS
-vmlinux
-vmlinuz
-System.map
-Module.markers
-Module.symvers
+/tags
+/TAGS
+/linux
+/vmlinux
+/vmlinuz
+/System.map
+/Module.markers
+/Module.symvers
+
+#
+# git files that we don't want to ignore even it they are dot-files
+#
!.gitignore
!.mailmap
diff --git a/Documentation/ABI/stable/sysfs-devices-node b/Documentation/ABI/stable/sysfs-devices-node
new file mode 100644
index 00000000000..49b82cad700
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-devices-node
@@ -0,0 +1,7 @@
+What: /sys/devices/system/node/nodeX
+Date: October 2002
+Contact: Linux Memory Management list <linux-mm@kvack.org>
+Description:
+ When CONFIG_NUMA is enabled, this is a directory containing
+ information on node X such as what CPUs are local to the
+ node.
diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb
index a986e9bbba3..bcebb9eaedc 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -160,7 +160,7 @@ Description:
match the driver to the device. For example:
# echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id
-What: /sys/bus/usb/device/.../avoid_reset
+What: /sys/bus/usb/device/.../avoid_reset_quirk
Date: December 2009
Contact: Oliver Neukum <oliver@neukum.org>
Description:
diff --git a/Documentation/DMA-API-HOWTO.txt b/Documentation/DMA-API-HOWTO.txt
new file mode 100644
index 00000000000..52618ab069a
--- /dev/null
+++ b/Documentation/DMA-API-HOWTO.txt
@@ -0,0 +1,758 @@
+ Dynamic DMA mapping Guide
+ =========================
+
+ David S. Miller <davem@redhat.com>
+ Richard Henderson <rth@cygnus.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+This is a guide to device driver writers on how to use the DMA API
+with example pseudo-code. For a concise description of the API, see
+DMA-API.txt.
+
+Most of the 64bit platforms have special hardware that translates bus
+addresses (DMA addresses) into physical addresses. This is similar to
+how page tables and/or a TLB translates virtual addresses to physical
+addresses on a CPU. This is needed so that e.g. PCI devices can
+access with a Single Address Cycle (32bit DMA address) any page in the
+64bit physical address space. Previously in Linux those 64bit
+platforms had to set artificial limits on the maximum RAM size in the
+system, so that the virt_to_bus() static scheme works (the DMA address
+translation tables were simply filled on bootup to map each bus
+address to the physical page __pa(bus_to_virt())).
+
+So that Linux can use the dynamic DMA mapping, it needs some help from the
+drivers, namely it has to take into account that DMA addresses should be
+mapped only for the time they are actually used and unmapped after the DMA
+transfer.
+
+The following API will work of course even on platforms where no such
+hardware exists.
+
+Note that the DMA API works with any bus independent of the underlying
+microprocessor architecture. You should use the DMA API rather than
+the bus specific DMA API (e.g. pci_dma_*).
+
+First of all, you should make sure
+
+#include <linux/dma-mapping.h>
+
+is in your driver. This file will obtain for you the definition of the
+dma_addr_t (which can hold any valid DMA address for the platform)
+type which should be used everywhere you hold a DMA (bus) address
+returned from the DMA mapping functions.
+
+ What memory is DMA'able?
+
+The first piece of information you must know is what kernel memory can
+be used with the DMA mapping facilities. There has been an unwritten
+set of rules regarding this, and this text is an attempt to finally
+write them down.
+
+If you acquired your memory via the page allocator
+(i.e. __get_free_page*()) or the generic memory allocators
+(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
+that memory using the addresses returned from those routines.
+
+This means specifically that you may _not_ use the memory/addresses
+returned from vmalloc() for DMA. It is possible to DMA to the
+_underlying_ memory mapped into a vmalloc() area, but this requires
+walking page tables to get the physical addresses, and then
+translating each of those pages back to a kernel address using
+something like __va(). [ EDIT: Update this when we integrate
+Gerd Knorr's generic code which does this. ]
+
+This rule also means that you may use neither kernel image addresses
+(items in data/text/bss segments), nor module image addresses, nor
+stack addresses for DMA. These could all be mapped somewhere entirely
+different than the rest of physical memory. Even if those classes of
+memory could physically work with DMA, you'd need to ensure the I/O
+buffers were cacheline-aligned. Without that, you'd see cacheline
+sharing problems (data corruption) on CPUs with DMA-incoherent caches.
+(The CPU could write to one word, DMA would write to a different one
+in the same cache line, and one of them could be overwritten.)
+
+Also, this means that you cannot take the return of a kmap()
+call and DMA to/from that. This is similar to vmalloc().
+
+What about block I/O and networking buffers? The block I/O and
+networking subsystems make sure that the buffers they use are valid
+for you to DMA from/to.
+
+ DMA addressing limitations
+
+Does your device have any DMA addressing limitations? For example, is
+your device only capable of driving the low order 24-bits of address?
+If so, you need to inform the kernel of this fact.
+
+By default, the kernel assumes that your device can address the full
+32-bits. For a 64-bit capable device, this needs to be increased.
+And for a device with limitations, as discussed in the previous
+paragraph, it needs to be decreased.
+
+Special note about PCI: PCI-X specification requires PCI-X devices to
+support 64-bit addressing (DAC) for all transactions. And at least
+one platform (SGI SN2) requires 64-bit consistent allocations to
+operate correctly when the IO bus is in PCI-X mode.
+
+For correct operation, you must interrogate the kernel in your device
+probe routine to see if the DMA controller on the machine can properly
+support the DMA addressing limitation your device has. It is good
+style to do this even if your device holds the default setting,
+because this shows that you did think about these issues wrt. your
+device.
+
+The query is performed via a call to dma_set_mask():
+
+ int dma_set_mask(struct device *dev, u64 mask);
+
+The query for consistent allocations is performed via a call to
+dma_set_coherent_mask():
+
+ int dma_set_coherent_mask(struct device *dev, u64 mask);
+
+Here, dev is a pointer to the device struct of your device, and mask
+is a bit mask describing which bits of an address your device
+supports. It returns zero if your card can perform DMA properly on
+the machine given the address mask you provided. In general, the
+device struct of your device is embedded in the bus specific device
+struct of your device. For example, a pointer to the device struct of
+your PCI device is pdev->dev (pdev is a pointer to the PCI device
+struct of your device).
+
+If it returns non-zero, your device cannot perform DMA properly on
+this platform, and attempting to do so will result in undefined
+behavior. You must either use a different mask, or not use DMA.
+
+This means that in the failure case, you have three options:
+
+1) Use another DMA mask, if possible (see below).
+2) Use some non-DMA mode for data transfer, if possible.
+3) Ignore this device and do not initialize it.
+
+It is recommended that your driver print a kernel KERN_WARNING message
+when you end up performing either #2 or #3. In this manner, if a user
+of your driver reports that performance is bad or that the device is not
+even detected, you can ask them for the kernel messages to find out
+exactly why.
+
+The standard 32-bit addressing device would do something like this:
+
+ if (dma_set_mask(dev, DMA_BIT_MASK(32))) {
+ printk(KERN_WARNING
+ "mydev: No suitable DMA available.\n");
+ goto ignore_this_device;
+ }
+
+Another common scenario is a 64-bit capable device. The approach here
+is to try for 64-bit addressing, but back down to a 32-bit mask that
+should not fail. The kernel may fail the 64-bit mask not because the
+platform is not capable of 64-bit addressing. Rather, it may fail in
+this case simply because 32-bit addressing is done more efficiently
+than 64-bit addressing. For example, Sparc64 PCI SAC addressing is
+more efficient than DAC addressing.
+
+Here is how you would handle a 64-bit capable device which can drive
+all 64-bits when accessing streaming DMA:
+
+ int using_dac;
+
+ if (!dma_set_mask(dev, DMA_BIT_MASK(64))) {
+ using_dac = 1;
+ } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) {
+ using_dac = 0;
+ } else {
+ printk(KERN_WARNING
+ "mydev: No suitable DMA available.\n");
+ goto ignore_this_device;
+ }
+
+If a card is capable of using 64-bit consistent allocations as well,
+the case would look like this:
+
+ int using_dac, consistent_using_dac;
+
+ if (!dma_set_mask(dev, DMA_BIT_MASK(64))) {
+ using_dac = 1;
+ consistent_using_dac = 1;
+ dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
+ } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) {
+ using_dac = 0;
+ consistent_using_dac = 0;
+ dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+ } else {
+ printk(KERN_WARNING
+ "mydev: No suitable DMA available.\n");
+ goto ignore_this_device;
+ }
+
+dma_set_coherent_mask() will always be able to set the same or a
+smaller mask as dma_set_mask(). However for the rare case that a
+device driver only uses consistent allocations, one would have to
+check the return value from dma_set_coherent_mask().
+
+Finally, if your device can only drive the low 24-bits of
+address you might do something like:
+
+ if (dma_set_mask(dev, DMA_BIT_MASK(24))) {
+ printk(KERN_WARNING
+ "mydev: 24-bit DMA addressing not available.\n");
+ goto ignore_this_device;
+ }
+
+When dma_set_mask() is successful, and returns zero, the kernel saves
+away this mask you have provided. The kernel will use this
+information later when you make DMA mappings.
+
+There is a case which we are aware of at this time, which is worth
+mentioning in this documentation. If your device supports multiple
+functions (for example a sound card provides playback and record
+functions) and the various different functions have _different_
+DMA addressing limitations, you may wish to probe each mask and
+only provide the functionality which the machine can handle. It
+is important that the last call to dma_set_mask() be for the
+most specific mask.
+
+Here is pseudo-code showing how this might be done:
+
+ #define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32)
+ #define RECORD_ADDRESS_BITS DMA_BIT_MASK(24)
+
+ struct my_sound_card *card;
+ struct device *dev;
+
+ ...
+ if (!dma_set_mask(dev, PLAYBACK_ADDRESS_BITS)) {
+ card->playback_enabled = 1;
+ } else {
+ card->playback_enabled = 0;
+ printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n",
+ card->name);
+ }
+ if (!dma_set_mask(dev, RECORD_ADDRESS_BITS)) {
+ card->record_enabled = 1;
+ } else {
+ card->record_enabled = 0;
+ printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n",
+ card->name);
+ }
+
+A sound card was used as an example here because this genre of PCI
+devices seems to be littered with ISA chips given a PCI front end,
+and thus retaining the 16MB DMA addressing limitations of ISA.
+
+ Types of DMA mappings
+
+There are two types of DMA mappings:
+
+- Consistent DMA mappings which are usually mapped at driver
+ initialization, unmapped at the end and for which the hardware should
+ guarantee that the device and the CPU can access the data
+ in parallel and will see updates made by each other without any
+ explicit software flushing.
+
+ Think of "consistent" as "synchronous" or "coherent".
+
+ The current default is to return consistent memory in the low 32
+ bits of the bus space. However, for future compatibility you should
+ set the consistent mask even if this default is fine for your
+ driver.
+
+ Good examples of what to use consistent mappings for are:
+
+ - Network card DMA ring descriptors.
+ - SCSI adapter mailbox command data structures.
+ - Device firmware microcode executed out of
+ main memory.
+
+ The invariant these examples all require is that any CPU store
+ to memory is immediately visible to the device, and vice
+ versa. Consistent mappings guarantee this.
+
+ IMPORTANT: Consistent DMA memory does not preclude the usage of
+ proper memory barriers. The CPU may reorder stores to
+ consistent memory just as it may normal memory. Example:
+ if it is important for the device to see the first word
+ of a descriptor updated before the second, you must do
+ something like:
+
+ desc->word0 = address;
+ wmb();
+ desc->word1 = DESC_VALID;
+
+ in order to get correct behavior on all platforms.
+
+ Also, on some platforms your driver may need to flush CPU write
+ buffers in much the same way as it needs to flush write buffers
+ found in PCI bridges (such as by reading a register's value
+ after writing it).
+
+- Streaming DMA mappings which are usually mapped for one DMA
+ transfer, unmapped right after it (unless you use dma_sync_* below)
+ and for which hardware can optimize for sequential accesses.
+
+ This of "streaming" as "asynchronous" or "outside the coherency
+ domain".
+
+ Good examples of what to use streaming mappings for are:
+
+ - Networking buffers transmitted/received by a device.
+ - Filesystem buffers written/read by a SCSI device.
+
+ The interfaces for using this type of mapping were designed in
+ such a way that an implementation can make whatever performance
+ optimizations the hardware allows. To this end, when using
+ such mappings you must be explicit about what you want to happen.
+
+Neither type of DMA mapping has alignment restrictions that come from
+the underlying bus, although some devices may have such restrictions.
+Also, systems with caches that aren't DMA-coherent will work better
+when the underlying buffers don't share cache lines with other data.
+
+
+ Using Consistent DMA mappings.
+
+To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
+you should do:
+
+ dma_addr_t dma_handle;
+
+ cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, gfp);
+
+where device is a struct device *. This may be called in interrupt
+context with the GFP_ATOMIC flag.
+
+Size is the length of the region you want to allocate, in bytes.
+
+This routine will allocate RAM for that region, so it acts similarly to
+__get_free_pages (but takes size instead of a page order). If your
+driver needs regions sized smaller than a page, you may prefer using
+the dma_pool interface, described below.
+
+The consistent DMA mapping interfaces, for non-NULL dev, will by
+default return a DMA address which is 32-bit addressable. Even if the
+device indicates (via DMA mask) that it may address the upper 32-bits,
+consistent allocation will only return > 32-bit addresses for DMA if
+the consistent DMA mask has been explicitly changed via
+dma_set_coherent_mask(). This is true of the dma_pool interface as
+well.
+
+dma_alloc_coherent returns two values: the virtual address which you
+can use to access it from the CPU and dma_handle which you pass to the
+card.
+
+The cpu return address and the DMA bus master address are both
+guaranteed to be aligned to the smallest PAGE_SIZE order which
+is greater than or equal to the requested size. This invariant
+exists (for example) to guarantee that if you allocate a chunk
+which is smaller than or equal to 64 kilobytes, the extent of the
+buffer you receive will not cross a 64K boundary.
+
+To unmap and free such a DMA region, you call:
+
+ dma_free_coherent(dev, size, cpu_addr, dma_handle);
+
+where dev, size are the same as in the above call and cpu_addr and
+dma_handle are the values dma_alloc_coherent returned to you.
+This function may not be called in interrupt context.
+
+If your driver needs lots of smaller memory regions, you can write
+custom code to subdivide pages returned by dma_alloc_coherent,
+or you can use the dma_pool API to do that. A dma_pool is like
+a kmem_cache, but it uses dma_alloc_coherent not __get_free_pages.
+Also, it understands common hardware constraints for alignment,
+like queue heads needing to be aligned on N byte boundaries.
+
+Create a dma_pool like this:
+
+ struct dma_pool *pool;
+
+ pool = dma_pool_create(name, dev, size, align, alloc);
+
+The "name" is for diagnostics (like a kmem_cache name); dev and size
+are as above. The device's hardware alignment requirement for this
+type of data is "align" (which is expressed in bytes, and must be a
+power of two). If your device has no boundary crossing restrictions,
+pass 0 for alloc; passing 4096 says memory allocated from this pool
+must not cross 4KByte boundaries (but at that time it may be better to
+go for dma_alloc_coherent directly instead).
+
+Allocate memory from a dma pool like this:
+
+ cpu_addr = dma_pool_alloc(pool, flags, &dma_handle);
+
+flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
+holding SMP locks), SLAB_ATOMIC otherwise. Like dma_alloc_coherent,
+this returns two values, cpu_addr and dma_handle.
+
+Free memory that was allocated from a dma_pool like this:
+
+ dma_pool_free(pool, cpu_addr, dma_handle);
+
+where pool is what you passed to dma_pool_alloc, and cpu_addr and
+dma_handle are the values dma_pool_alloc returned. This function
+may be called in interrupt context.
+
+Destroy a dma_pool by calling:
+
+ dma_pool_destroy(pool);
+
+Make sure you've called dma_pool_free for all memory allocated
+from a pool before you destroy the pool. This function may not
+be called in interrupt context.
+
+ DMA Direction
+
+The interfaces described in subsequent portions of this document
+take a DMA direction argument, which is an integer and takes on
+one of the following values:
+
+ DMA_BIDIRECTIONAL
+ DMA_TO_DEVICE
+ DMA_FROM_DEVICE
+ DMA_NONE
+
+One should provide the exact DMA direction if you know it.
+
+DMA_TO_DEVICE means "from main memory to the device"
+DMA_FROM_DEVICE means "from the device to main memory"
+It is the direction in which the data moves during the DMA
+transfer.
+
+You are _strongly_ encouraged to specify this as precisely
+as you possibly can.
+
+If you absolutely cannot know the direction of the DMA transfer,
+specify DMA_BIDIRECTIONAL. It means that the DMA can go in
+either direction. The platform guarantees that you may legally
+specify this, and that it will work, but this may be at the
+cost of performance for example.
+
+The value DMA_NONE is to be used for debugging. One can
+hold this in a data structure before you come to know the
+precise direction, and this will help catch cases where your
+direction tracking logic has failed to set things up properly.
+
+Another advantage of specifying this value precisely (outside of
+potential platform-specific optimizations of such) is for debugging.
+Some platforms actually have a write permission boolean which DMA
+mappings can be marked with, much like page protections in the user
+program address space. Such platforms can and do report errors in the
+kernel logs when the DMA controller hardware detects violation of the
+permission setting.
+
+Only streaming mappings specify a direction, consistent mappings
+implicitly have a direction attribute setting of
+DMA_BIDIRECTIONAL.
+
+The SCSI subsystem tells you the direction to use in the
+'sc_data_direction' member of the SCSI command your driver is
+working on.
+
+For Networking drivers, it's a rather simple affair. For transmit
+packets, map/unmap them with the DMA_TO_DEVICE direction
+specifier. For receive packets, just the opposite, map/unmap them
+with the DMA_FROM_DEVICE direction specifier.
+
+ Using Streaming DMA mappings
+
+The streaming DMA mapping routines can be called from interrupt
+context. There are two versions of each map/unmap, one which will
+map/unmap a single memory region, and one which will map/unmap a
+scatterlist.
+
+To map a single region, you do:
+
+ struct device *dev = &my_dev->dev;
+ dma_addr_t dma_handle;
+ void *addr = buffer->ptr;
+ size_t size = buffer->len;
+
+ dma_handle = dma_map_single(dev, addr, size, direction);
+
+and to unmap it:
+
+ dma_unmap_single(dev, dma_handle, size, direction);
+
+You should call dma_unmap_single when the DMA activity is finished, e.g.
+from the interrupt which told you that the DMA transfer is done.
+
+Using cpu pointers like this for single mappings has a disadvantage,
+you cannot reference HIGHMEM memory in this way. Thus, there is a
+map/unmap interface pair akin to dma_{map,unmap}_single. These
+interfaces deal with page/offset pairs instead of cpu pointers.
+Specifically:
+
+ struct device *dev = &my_dev->dev;
+ dma_addr_t dma_handle;
+ struct page *page = buffer->page;
+ unsigned long offset = buffer->offset;
+ size_t size = buffer->len;
+
+ dma_handle = dma_map_page(dev, page, offset, size, direction);
+
+ ...
+
+ dma_unmap_page(dev, dma_handle, size, direction);
+
+Here, "offset" means byte offset within the given page.
+
+With scatterlists, you map a region gathered from several regions by:
+
+ int i, count = dma_map_sg(dev, sglist, nents, direction);
+ struct scatterlist *sg;
+
+ for_each_sg(sglist, sg, count, i) {
+ hw_address[i] = sg_dma_address(sg);
+ hw_len[i] = sg_dma_len(sg);
+ }
+
+where nents is the number of entries in the sglist.
+
+The implementation is free to merge several consecutive sglist entries
+into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
+consecutive sglist entries can be merged into one provided the first one
+ends and the second one starts on a page boundary - in fact this is a huge
+advantage for cards which either cannot do scatter-gather or have very
+limited number of scatter-gather entries) and returns the actual number
+of sg entries it mapped them to. On failure 0 is returned.
+
+Then you should loop count times (note: this can be less than nents times)
+and use sg_dma_address() and sg_dma_len() macros where you previously
+accessed sg->address and sg->length as shown above.
+
+To unmap a scatterlist, just call:
+
+ dma_unmap_sg(dev, sglist, nents, direction);
+
+Again, make sure DMA activity has already finished.
+
+PLEASE NOTE: The 'nents' argument to the dma_unmap_sg call must be
+ the _same_ one you passed into the dma_map_sg call,
+ it should _NOT_ be the 'count' value _returned_ from the
+ dma_map_sg call.
+
+Every dma_map_{single,sg} call should have its dma_unmap_{single,sg}
+counterpart, because the bus address space is a shared resource (although
+in some ports the mapping is per each BUS so less devices contend for the
+same bus address space) and you could render the machine unusable by eating
+all bus addresses.
+
+If you need to use the same streaming DMA region multiple times and touch
+the data in between the DMA transfers, the buffer needs to be synced
+properly in order for the cpu and device to see the most uptodate and
+correct copy of the DMA buffer.
+
+So, firstly, just map it with dma_map_{single,sg}, and after each DMA
+transfer call either:
+
+ dma_sync_single_for_cpu(dev, dma_handle, size, direction);
+
+or:
+
+ dma_sync_sg_for_cpu(dev, sglist, nents, direction);
+
+as appropriate.
+
+Then, if you wish to let the device get at the DMA area again,
+finish accessing the data with the cpu, and then before actually
+giving the buffer to the hardware call either:
+
+ dma_sync_single_for_device(dev, dma_handle, size, direction);
+
+or:
+
+ dma_sync_sg_for_device(dev, sglist, nents, direction);
+
+as appropriate.
+
+After the last DMA transfer call one of the DMA unmap routines
+dma_unmap_{single,sg}. If you don't touch the data from the first dma_map_*
+call till dma_unmap_*, then you don't have to call the dma_sync_*
+routines at all.
+
+Here is pseudo code which shows a situation in which you would need
+to use the dma_sync_*() interfaces.
+
+ my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
+ {
+ dma_addr_t mapping;
+
+ mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE);
+
+ cp->rx_buf = buffer;
+ cp->rx_len = len;
+ cp->rx_dma = mapping;
+
+ give_rx_buf_to_card(cp);
+ }
+
+ ...
+
+ my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs)
+ {
+ struct my_card *cp = devid;
+
+ ...
+ if (read_card_status(cp) == RX_BUF_TRANSFERRED) {
+ struct my_card_header *hp;
+
+ /* Examine the header to see if we wish
+ * to accept the data. But synchronize
+ * the DMA transfer with the CPU first
+ * so that we see updated contents.
+ */
+ dma_sync_single_for_cpu(&cp->dev, cp->rx_dma,
+ cp->rx_len,
+ DMA_FROM_DEVICE);
+
+ /* Now it is safe to examine the buffer. */
+ hp = (struct my_card_header *) cp->rx_buf;
+ if (header_is_ok(hp)) {
+ dma_unmap_single(&cp->dev, cp->rx_dma, cp->rx_len,
+ DMA_FROM_DEVICE);
+ pass_to_upper_layers(cp->rx_buf);
+ make_and_setup_new_rx_buf(cp);
+ } else {
+ /* Just sync the buffer and give it back
+ * to the card.
+ */
+ dma_sync_single_for_device(&cp->dev,
+ cp->rx_dma,
+ cp->rx_len,
+ DMA_FROM_DEVICE);
+ give_rx_buf_to_card(cp);
+ }
+ }
+ }
+
+Drivers converted fully to this interface should not use virt_to_bus any
+longer, nor should they use bus_to_virt. Some drivers have to be changed a
+little bit, because there is no longer an equivalent to bus_to_virt in the
+dynamic DMA mapping scheme - you have to always store the DMA addresses
+returned by the dma_alloc_coherent, dma_pool_alloc, and dma_map_single
+calls (dma_map_sg stores them in the scatterlist itself if the platform
+supports dynamic DMA mapping in hardware) in your driver structures and/or
+in the card registers.
+
+All drivers should be using these interfaces with no exceptions. It
+is planned to completely remove virt_to_bus() and bus_to_virt() as
+they are entirely deprecated. Some ports already do not provide these
+as it is impossible to correctly support them.
+
+ Optimizing Unmap State Space Consumption
+
+On many platforms, dma_unmap_{single,page}() is simply a nop.
+Therefore, keeping track of the mapping address and length is a waste
+of space. Instead of filling your drivers up with ifdefs and the like
+to "work around" this (which would defeat the whole purpose of a
+portable API) the following facilities are provided.
+
+Actually, instead of describing the macros one by one, we'll
+transform some example code.
+
+1) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures.
+ Example, before:
+
+ struct ring_state {
+ struct sk_buff *skb;
+ dma_addr_t mapping;
+ __u32 len;
+ };
+
+ after:
+
+ struct ring_state {
+ struct sk_buff *skb;
+ DEFINE_DMA_UNMAP_ADDR(mapping);
+ DEFINE_DMA_UNMAP_LEN(len);
+ };
+
+2) Use dma_unmap_{addr,len}_set to set these values.
+ Example, before:
+
+ ringp->mapping = FOO;
+ ringp->len = BAR;
+
+ after:
+
+ dma_unmap_addr_set(ringp, mapping, FOO);
+ dma_unmap_len_set(ringp, len, BAR);
+
+3) Use dma_unmap_{addr,len} to access these values.
+ Example, before:
+
+ dma_unmap_single(dev, ringp->mapping, ringp->len,
+ DMA_FROM_DEVICE);
+
+ after:
+
+ dma_unmap_single(dev,
+ dma_unmap_addr(ringp, mapping),
+ dma_unmap_len(ringp, len),
+ DMA_FROM_DEVICE);
+
+It really should be self-explanatory. We treat the ADDR and LEN
+separately, because it is possible for an implementation to only
+need the address in order to perform the unmap operation.
+
+ Platform Issues
+
+If you are just writing drivers for Linux and do not maintain
+an architecture port for the kernel, you can safely skip down
+to "Closing".
+
+1) Struct scatterlist requirements.
+
+ Struct scatterlist must contain, at a minimum, the following
+ members:
+
+ struct page *page;
+ unsigned int offset;
+ unsigned int length;
+
+ The base address is specified by a "page+offset" pair.
+
+ Previous versions of struct scatterlist contained a "void *address"
+ field that was sometimes used instead of page+offset. As of Linux
+ 2.5., page+offset is always used, and the "address" field has been
+ deleted.
+
+2) More to come...
+
+ Handling Errors
+
+DMA address space is limited on some architectures and an allocation
+failure can be determined by:
+
+- checking if dma_alloc_coherent returns NULL or dma_map_sg returns 0
+
+- checking the returned dma_addr_t of dma_map_single and dma_map_page
+ by using dma_mapping_error():
+
+ dma_addr_t dma_handle;
+
+ dma_handle = dma_map_single(dev, addr, size, direction);
+ if (dma_mapping_error(dev, dma_handle)) {
+ /*
+ * reduce current DMA mapping usage,
+ * delay and try again later or
+ * reset driver.
+ */
+ }
+
+ Closing
+
+This document, and the API itself, would not be in it's current
+form without the feedback and suggestions from numerous individuals.
+We would like to specifically mention, in no particular order, the
+following people:
+
+ Russell King <rmk@arm.linux.org.uk>
+ Leo Dagum <dagum@barrel.engr.sgi.com>
+ Ralf Baechle <ralf@oss.sgi.com>
+ Grant Grundler <grundler@cup.hp.com>
+ Jay Estabrook <Jay.Estabrook@compaq.com>
+ Thomas Sailer <sailer@ife.ee.ethz.ch>
+ Andrea Arcangeli <andrea@suse.de>
+ Jens Axboe <jens.axboe@oracle.com>
+ David Mosberger-Tang <davidm@hpl.hp.com>
diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 5aceb88b3f8..05e2ae23686 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -4,20 +4,18 @@
James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
This document describes the DMA API. For a more gentle introduction
-phrased in terms of the pci_ equivalents (and actual examples) see
-Documentation/PCI/PCI-DMA-mapping.txt.
+of the API (and actual examples) see
+Documentation/DMA-API-HOWTO.txt.
-This API is split into two pieces. Part I describes the API and the
-corresponding pci_ API. Part II describes the extensions to the API
-for supporting non-consistent memory machines. Unless you know that
-your driver absolutely has to support non-consistent platforms (this
-is usually only legacy platforms) you should only use the API
-described in part I.
+This API is split into two pieces. Part I describes the API. Part II
+describes the extensions to the API for supporting non-consistent
+memory machines. Unless you know that your driver absolutely has to
+support non-consistent platforms (this is usually only legacy
+platforms) you should only use the API described in part I.
-Part I - pci_ and dma_ Equivalent API
+Part I - dma_ API
-------------------------------------
-To get the pci_ API, you must #include <linux/pci.h>
To get the dma_ API, you must #include <linux/dma-mapping.h>
@@ -27,9 +25,6 @@ Part Ia - Using large dma-coherent buffers
void *
dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
-void *
-pci_alloc_consistent(struct pci_dev *dev, size_t size,
- dma_addr_t *dma_handle)
Consistent memory is memory for which a write by either the device or
the processor can immediately be read by the processor or device
@@ -53,15 +48,11 @@ The simplest way to do that is to use the dma_pool calls (see below).
The flag parameter (dma_alloc_coherent only) allows the caller to
specify the GFP_ flags (see kmalloc) for the allocation (the
implementation may choose to ignore flags that affect the location of
-the returned memory, like GFP_DMA). For pci_alloc_consistent, you
-must assume GFP_ATOMIC behaviour.
+the returned memory, like GFP_DMA).
void
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_handle)
-void
-pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
Free the region of consistent memory you previously allocated. dev,
size and dma_handle must all be the same as those passed into the
@@ -89,10 +80,6 @@ for alignment, like queue heads needing to be aligned on N-byte boundaries.
dma_pool_create(const char *name, struct device *dev,
size_t size, size_t align, size_t alloc);
- struct pci_pool *
- pci_pool_create(const char *name, struct pci_device *dev,
- size_t size, size_t align, size_t alloc);
-
The pool create() routines initialize a pool of dma-coherent buffers
for use with a given device. It must be called in a context which
can sleep.
@@ -108,9 +95,6 @@ from this pool must not cross 4KByte boundaries.
void *dma_pool_alloc(struct dma_pool *pool, gfp_t gfp_flags,
dma_addr_t *dma_handle);
- void *pci_pool_alloc(struct pci_pool *pool, gfp_t gfp_flags,
- dma_addr_t *dma_handle);
-
This allocates memory from the pool; the returned memory will meet the size
and alignment requirements specified at creation time. Pass GFP_ATOMIC to
prevent blocking, or if it's permitted (not in_interrupt, not holding SMP locks),
@@ -122,9 +106,6 @@ pool's device.
void dma_pool_free(struct dma_pool *pool, void *vaddr,
dma_addr_t addr);
- void pci_pool_free(struct pci_pool *pool, void *vaddr,
- dma_addr_t addr);
-
This puts memory back into the pool. The pool is what was passed to
the pool allocation routine; the cpu (vaddr) and dma addresses are what
were returned when that routine allocated the memory being freed.
@@ -132,8 +113,6 @@ were returned when that routine allocated the memory being freed.
void dma_pool_destroy(struct dma_pool *pool);
- void pci_pool_destroy(struct pci_pool *pool);
-
The pool destroy() routines free the resources of the pool. They must be
called in a context which can sleep. Make sure you've freed all allocated
memory back to the pool before you destroy it.
@@ -144,8 +123,6 @@ Part Ic - DMA addressing limitations
int
dma_supported(struct device *dev, u64 mask)
-int
-pci_dma_supported(struct pci_dev *hwdev, u64 mask)
Checks to see if the device can support DMA to the memory described by
mask.
@@ -159,8 +136,14 @@ driver writers.
int
dma_set_mask(struct device *dev, u64 mask)
+
+Checks to see if the mask is possible and updates the device
+parameters if it is.
+
+Returns: 0 if successful and a negative error if not.
+
int
-pci_set_dma_mask(struct pci_device *dev, u64 mask)
+dma_set_coherent_mask(struct device *dev, u64 mask)
Checks to see if the mask is possible and updates the device
parameters if it is.
@@ -187,9 +170,6 @@ Part Id - Streaming DMA mappings
dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)
-dma_addr_t
-pci_map_single(struct pci_dev *hwdev, void *cpu_addr, size_t size,
- int direction)
Maps a piece of processor virtual memory so it can be accessed by the
device and returns the physical handle of the memory.
@@ -198,14 +178,10 @@ The direction for both api's may be converted freely by casting.
However the dma_ API uses a strongly typed enumerator for its
direction:
-DMA_NONE = PCI_DMA_NONE no direction (used for
- debugging)
-DMA_TO_DEVICE = PCI_DMA_TODEVICE data is going from the
- memory to the device
-DMA_FROM_DEVICE = PCI_DMA_FROMDEVICE data is coming from
- the device to the
- memory
-DMA_BIDIRECTIONAL = PCI_DMA_BIDIRECTIONAL direction isn't known
+DMA_NONE no direction (used for debugging)
+DMA_TO_DEVICE data is going from the memory to the device
+DMA_FROM_DEVICE data is coming from the device to the memory
+DMA_BIDIRECTIONAL direction isn't known
Notes: Not all memory regions in a machine can be mapped by this
API. Further, regions that appear to be physically contiguous in
@@ -268,9 +244,6 @@ cache lines are updated with data that the device may have changed).
void
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
-void
-pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
- size_t size, int direction)
Unmaps the region previously mapped. All the parameters passed in
must be identical to those passed in (and returned) by the mapping
@@ -280,15 +253,9 @@ dma_addr_t
dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction direction)
-dma_addr_t
-pci_map_page(struct pci_dev *hwdev, struct page *page,
- unsigned long offset, size_t size, int direction)
void
dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
enum dma_data_direction direction)
-void
-pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
- size_t size, int direction)
API for mapping and unmapping for pages. All the notes and warnings
for the other mapping APIs apply here. Also, although the <offset>
@@ -299,9 +266,6 @@ cache width is.
int
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-int
-pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr)
-
In some circumstances dma_map_single and dma_map_page will fail to create
a mapping. A driver can check for these errors by testing the returned
dma address with dma_mapping_error(). A non-zero return value means the mapping
@@ -311,9 +275,6 @@ reduce current DMA mapping usage or delay and try again later).
int
dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction direction)
- int
- pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
- int nents, int direction)
Returns: the number of physical segments mapped (this may be shorter
than <nents> passed in if some elements of the scatter/gather list are
@@ -353,9 +314,6 @@ accessed sg->address and sg->length as shown above.
void
dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction direction)
- void
- pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
- int nents, int direction)
Unmap the previously mapped scatter/gather list. All the parameters
must be the same as those and passed in to the scatter/gather mapping
@@ -365,21 +323,23 @@ Note: <nents> must be the number you passed in, *not* the number of
physical entries returned.
void
-dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
void
-pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle,
- size_t size, int direction)
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
void
-dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
void
-pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
- int nelems, int direction)
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
-Synchronise a single contiguous or scatter/gather mapping. All the
-parameters must be the same as those passed into the single mapping
-API.
+Synchronise a single contiguous or scatter/gather mapping for the cpu
+and device. With the sync_sg API, all the parameters must be the same
+as those passed into the single mapping API. With the sync_single API,
+you can use dma_handle and size parameters that aren't identical to
+those passed into the single mapping API to do a partial sync.
Notes: You must do this:
@@ -461,9 +421,9 @@ void whizco_dma_map_sg_attrs(struct device *dev, dma_addr_t dma_addr,
Part II - Advanced dma_ usage
-----------------------------
-Warning: These pieces of the DMA API have no PCI equivalent. They
-should also not be used in the majority of cases, since they cater for
-unlikely corner cases that don't belong in usual drivers.
+Warning: These pieces of the DMA API should not be used in the
+majority of cases, since they cater for unlikely corner cases that
+don't belong in usual drivers.
If you don't understand how cache line coherency works between a
processor and an I/O device, you should not be using this part of the
@@ -514,16 +474,6 @@ into the width returned by this call. It will also always be a power
of two for easy alignment.
void
-dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-
-Does a partial sync, starting at offset and continuing for size. You
-must be careful to observe the cache alignment and width when doing
-anything like this. You must also be extra careful about accessing
-memory you intend to sync partially.
-
-void
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
index 5e7d84b4850..133cd6c3f3c 100644
--- a/Documentation/DocBook/mtdnand.tmpl
+++ b/Documentation/DocBook/mtdnand.tmpl
@@ -488,7 +488,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip)
The ECC bytes must be placed immidiately after the data
bytes in order to make the syndrome generator work. This
is contrary to the usual layout used by software ECC. The
- seperation of data and out of band area is not longer
+ separation of data and out of band area is not longer
possible. The nand driver code handles this layout and
the remaining free bytes in the oob area are managed by
the autoplacement code. Provide a matching oob-layout
@@ -560,7 +560,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip)
bad blocks. They have factory marked good blocks. The marker pattern
is erased when the block is erased to be reused. So in case of
powerloss before writing the pattern back to the chip this block
- would be lost and added to the bad blocks. Therefor we scan the
+ would be lost and added to the bad blocks. Therefore we scan the
chip(s) when we detect them the first time for good blocks and
store this information in a bad block table before erasing any
of the blocks.
@@ -1094,7 +1094,7 @@ in this page</entry>
manufacturers specifications. This applies similar to the spare area.
</para>
<para>
- Therefor NAND aware filesystems must either write in page size chunks
+ Therefore NAND aware filesystems must either write in page size chunks
or hold a writebuffer to collect smaller writes until they sum up to
pagesize. Available NAND aware filesystems: JFFS2, YAFFS.
</para>
diff --git a/Documentation/DocBook/tracepoint.tmpl b/Documentation/DocBook/tracepoint.tmpl
index 8bca1d5cec0..e8473eae2a2 100644
--- a/Documentation/DocBook/tracepoint.tmpl
+++ b/Documentation/DocBook/tracepoint.tmpl
@@ -16,6 +16,15 @@
</address>
</affiliation>
</author>
+ <author>
+ <firstname>William</firstname>
+ <surname>Cohen</surname>
+ <affiliation>
+ <address>
+ <email>wcohen@redhat.com</email>
+ </address>
+ </affiliation>
+ </author>
</authorgroup>
<legalnotice>
@@ -91,4 +100,8 @@
!Iinclude/trace/events/signal.h
</chapter>
+ <chapter id="block">
+ <title>Block IO</title>
+!Iinclude/trace/events/block.h
+ </chapter>
</book>
diff --git a/Documentation/DocBook/v4l/common.xml b/Documentation/DocBook/v4l/common.xml
index c65f0ac9b6e..cea23e1c4fc 100644
--- a/Documentation/DocBook/v4l/common.xml
+++ b/Documentation/DocBook/v4l/common.xml
@@ -1170,7 +1170,7 @@ frames per second. If less than this number of frames is to be
captured or output, applications can request frame skipping or
duplicating on the driver side. This is especially useful when using
the &func-read; or &func-write;, which are not augmented by timestamps
-or sequence counters, and to avoid unneccessary data copying.</para>
+or sequence counters, and to avoid unnecessary data copying.</para>
<para>Finally these ioctls can be used to determine the number of
buffers used internally by a driver in read/write mode. For
diff --git a/Documentation/DocBook/v4l/vidioc-g-parm.xml b/Documentation/DocBook/v4l/vidioc-g-parm.xml
index 78332d365ce..392aa9e5571 100644
--- a/Documentation/DocBook/v4l/vidioc-g-parm.xml
+++ b/Documentation/DocBook/v4l/vidioc-g-parm.xml
@@ -55,7 +55,7 @@ captured or output, applications can request frame skipping or
duplicating on the driver side. This is especially useful when using
the <function>read()</function> or <function>write()</function>, which
are not augmented by timestamps or sequence counters, and to avoid
-unneccessary data copying.</para>
+unnecessary data copying.</para>
<para>Further these ioctls can be used to determine the number of
buffers used internally by a driver in read/write mode. For
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index 8495fc97039..40ada93b820 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -221,8 +221,8 @@ branches. These different branches are:
- main 2.6.x kernel tree
- 2.6.x.y -stable kernel tree
- 2.6.x -git kernel patches
- - 2.6.x -mm kernel patches
- subsystem specific kernel trees and patches
+ - the 2.6.x -next kernel tree for integration tests
2.6.x kernel tree
-----------------
@@ -232,9 +232,9 @@ process is as follows:
- As soon as a new kernel is released a two weeks window is open,
during this period of time maintainers can submit big diffs to
Linus, usually the patches that have already been included in the
- -mm kernel for a few weeks. The preferred way to submit big changes
+ -next kernel for a few weeks. The preferred way to submit big changes
is using git (the kernel's source management tool, more information
- can be found at http://git.or.cz/) but plain patches are also just
+ can be found at http://git-scm.com/) but plain patches are also just
fine.
- After two weeks a -rc1 kernel is released it is now possible to push
only patches that do not include new features that could affect the
@@ -293,84 +293,43 @@ daily and represent the current state of Linus' tree. They are more
experimental than -rc kernels since they are generated automatically
without even a cursory glance to see if they are sane.
-2.6.x -mm kernel patches
-------------------------
-These are experimental kernel patches released by Andrew Morton. Andrew
-takes all of the different subsystem kernel trees and patches and mushes
-them together, along with a lot of patches that have been plucked from
-the linux-kernel mailing list. This tree serves as a proving ground for
-new features and patches. Once a patch has proved its worth in -mm for
-a while Andrew or the subsystem maintainer pushes it on to Linus for
-inclusion in mainline.
-
-It is heavily encouraged that all new patches get tested in the -mm tree
-before they are sent to Linus for inclusion in the main kernel tree. Code
-which does not make an appearance in -mm before the opening of the merge
-window will prove hard to merge into the mainline.
-
-These kernels are not appropriate for use on systems that are supposed
-to be stable and they are more risky to run than any of the other
-branches.
-
-If you wish to help out with the kernel development process, please test
-and use these kernel releases and provide feedback to the linux-kernel
-mailing list if you have any problems, and if everything works properly.
-
-In addition to all the other experimental patches, these kernels usually
-also contain any changes in the mainline -git kernels available at the
-time of release.
-
-The -mm kernels are not released on a fixed schedule, but usually a few
--mm kernels are released in between each -rc kernel (1 to 3 is common).
-
Subsystem Specific kernel trees and patches
-------------------------------------------
-A number of the different kernel subsystem developers expose their
-development trees so that others can see what is happening in the
-different areas of the kernel. These trees are pulled into the -mm
-kernel releases as described above.
-
-Here is a list of some of the different kernel trees available:
- git trees:
- - Kbuild development tree, Sam Ravnborg <sam@ravnborg.org>
- git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
-
- - ACPI development tree, Len Brown <len.brown@intel.com>
- git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
-
- - Block development tree, Jens Axboe <jens.axboe@oracle.com>
- git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
-
- - DRM development tree, Dave Airlie <airlied@linux.ie>
- git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
-
- - ia64 development tree, Tony Luck <tony.luck@intel.com>
- git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
-
- - infiniband, Roland Dreier <rolandd@cisco.com>
- git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
-
- - libata, Jeff Garzik <jgarzik@pobox.com>
- git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
-
- - network drivers, Jeff Garzik <jgarzik@pobox.com>
- git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
-
- - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
- git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
-
- - SCSI, James Bottomley <James.Bottomley@hansenpartnership.com>
- git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
-
- - x86, Ingo Molnar <mingo@elte.hu>
- git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
-
- quilt trees:
- - USB, Driver Core, and I2C, Greg Kroah-Hartman <gregkh@suse.de>
- kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+The maintainers of the various kernel subsystems --- and also many
+kernel subsystem developers --- expose their current state of
+development in source repositories. That way, others can see what is
+happening in the different areas of the kernel. In areas where
+development is rapid, a developer may be asked to base his submissions
+onto such a subsystem kernel tree so that conflicts between the
+submission and other already ongoing work are avoided.
+
+Most of these repositories are git trees, but there are also other SCMs
+in use, or patch queues being published as quilt series. Addresses of
+these subsystem repositories are listed in the MAINTAINERS file. Many
+of them can be browsed at http://git.kernel.org/.
+
+Before a proposed patch is committed to such a subsystem tree, it is
+subject to review which primarily happens on mailing lists (see the
+respective section below). For several kernel subsystems, this review
+process is tracked with the tool patchwork. Patchwork offers a web
+interface which shows patch postings, any comments on a patch or
+revisions to it, and maintainers can mark patches as under review,
+accepted, or rejected. Most of these patchwork sites are listed at
+http://patchwork.kernel.org/ or http://patchwork.ozlabs.org/.
+
+2.6.x -next kernel tree for integration tests
+---------------------------------------------
+Before updates from subsystem trees are merged into the mainline 2.6.x
+tree, they need to be integration-tested. For this purpose, a special
+testing repository exists into which virtually all subsystem trees are
+pulled on an almost daily basis:
+ http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
+ http://linux.f-seidel.de/linux-next/pmwiki/
+
+This way, the -next kernel gives a summary outlook onto what will be
+expected to go into the mainline kernel at the next merge period.
+Adventurous testers are very welcome to runtime-test the -next kernel.
- Other kernel trees can be found listed at http://git.kernel.org/ and in
- the MAINTAINERS file.
Bug Reporting
-------------
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index bc38283379f..69dd29ed824 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -365,6 +365,7 @@ You can change this at module load time (for a module) with:
regshifts=<shift1>,<shift2>,...
slave_addrs=<addr1>,<addr2>,...
force_kipmid=<enable1>,<enable2>,...
+ kipmid_max_busy_us=<ustime1>,<ustime2>,...
unload_when_empty=[0|1]
Each of these except si_trydefaults is a list, the first item for the
@@ -433,6 +434,7 @@ kernel command line as:
ipmi_si.regshifts=<shift1>,<shift2>,...
ipmi_si.slave_addrs=<addr1>,<addr2>,...
ipmi_si.force_kipmid=<enable1>,<enable2>,...
+ ipmi_si.kipmid_max_busy_us=<ustime1>,<ustime2>,...
It works the same as the module parameters of the same names.
@@ -450,6 +452,16 @@ force this thread on or off. If you force it off and don't have
interrupts, the driver will run VERY slowly. Don't blame me,
these interfaces suck.
+Unfortunately, this thread can use a lot of CPU depending on the
+interface's performance. This can waste a lot of CPU and cause
+various issues with detecting idle CPU and using extra power. To
+avoid this, the kipmid_max_busy_us sets the maximum amount of time, in
+microseconds, that kipmid will spin before sleeping for a tick. This
+value sets a balance between performance and CPU waste and needs to be
+tuned to your needs. Maybe, someday, auto-tuning will be added, but
+that's not a simple thing and even the auto-tuning would need to be
+tuned to the user's desired performance.
+
The driver supports a hot add and remove of interfaces. This way,
interfaces can be added or removed after the kernel is up and running.
This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 94b94573353..6fc7ea1d1f9 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,3 @@
obj-m := DocBook/ accounting/ auxdisplay/ connector/ \
- filesystems/configfs/ ia64/ networking/ \
- pcmcia/ spi/ video4linux/ vm/ watchdog/src/
+ filesystems/ filesystems/configfs/ ia64/ laptops/ networking/ \
+ pcmcia/ spi/ timers/ video4linux/ vm/ watchdog/src/
diff --git a/Documentation/PCI/PCI-DMA-mapping.txt b/Documentation/PCI/PCI-DMA-mapping.txt
deleted file mode 100644
index ecad88d9fe5..00000000000
--- a/Documentation/PCI/PCI-DMA-mapping.txt
+++ /dev/null
@@ -1,766 +0,0 @@
- Dynamic DMA mapping
- ===================
-
- David S. Miller <davem@redhat.com>
- Richard Henderson <rth@cygnus.com>
- Jakub Jelinek <jakub@redhat.com>
-
-This document describes the DMA mapping system in terms of the pci_
-API. For a similar API that works for generic devices, see
-DMA-API.txt.
-
-Most of the 64bit platforms have special hardware that translates bus
-addresses (DMA addresses) into physical addresses. This is similar to
-how page tables and/or a TLB translates virtual addresses to physical
-addresses on a CPU. This is needed so that e.g. PCI devices can
-access with a Single Address Cycle (32bit DMA address) any page in the
-64bit physical address space. Previously in Linux those 64bit
-platforms had to set artificial limits on the maximum RAM size in the
-system, so that the virt_to_bus() static scheme works (the DMA address
-translation tables were simply filled on bootup to map each bus
-address to the physical page __pa(bus_to_virt())).
-
-So that Linux can use the dynamic DMA mapping, it needs some help from the
-drivers, namely it has to take into account that DMA addresses should be
-mapped only for the time they are actually used and unmapped after the DMA
-transfer.
-
-The following API will work of course even on platforms where no such
-hardware exists, see e.g. arch/x86/include/asm/pci.h for how it is implemented on
-top of the virt_to_bus interface.
-
-First of all, you should make sure
-
-#include <linux/pci.h>
-
-is in your driver. This file will obtain for you the definition of the
-dma_addr_t (which can hold any valid DMA address for the platform)
-type which should be used everywhere you hold a DMA (bus) address
-returned from the DMA mapping functions.
-
- What memory is DMA'able?
-
-The first piece of information you must know is what kernel memory can
-be used with the DMA mapping facilities. There has been an unwritten
-set of rules regarding this, and this text is an attempt to finally
-write them down.
-
-If you acquired your memory via the page allocator
-(i.e. __get_free_page*()) or the generic memory allocators
-(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from
-that memory using the addresses returned from those routines.
-
-This means specifically that you may _not_ use the memory/addresses
-returned from vmalloc() for DMA. It is possible to DMA to the
-_underlying_ memory mapped into a vmalloc() area, but this requires
-walking page tables to get the physical addresses, and then
-translating each of those pages back to a kernel address using
-something like __va(). [ EDIT: Update this when we integrate
-Gerd Knorr's generic code which does this. ]
-
-This rule also means that you may use neither kernel image addresses
-(items in data/text/bss segments), nor module image addresses, nor
-stack addresses for DMA. These could all be mapped somewhere entirely
-different than the rest of physical memory. Even if those classes of
-memory could physically work with DMA, you'd need to ensure the I/O
-buffers were cacheline-aligned. Without that, you'd see cacheline
-sharing problems (data corruption) on CPUs with DMA-incoherent caches.
-(The CPU could write to one word, DMA would write to a different one
-in the same cache line, and one of them could be overwritten.)
-
-Also, this means that you cannot take the return of a kmap()
-call and DMA to/from that. This is similar to vmalloc().
-
-What about block I/O and networking buffers? The block I/O and
-networking subsystems make sure that the buffers they use are valid
-for you to DMA from/to.
-
- DMA addressing limitations
-
-Does your device have any DMA addressing limitations? For example, is
-your device only capable of driving the low order 24-bits of address
-on the PCI bus for SAC DMA transfers? If so, you need to inform the
-PCI layer of this fact.
-
-By default, the kernel assumes that your device can address the full
-32-bits in a SAC cycle. For a 64-bit DAC capable device, this needs
-to be increased. And for a device with limitations, as discussed in
-the previous paragraph, it needs to be decreased.
-
-pci_alloc_consistent() by default will return 32-bit DMA addresses.
-PCI-X specification requires PCI-X devices to support 64-bit
-addressing (DAC) for all transactions. And at least one platform (SGI
-SN2) requires 64-bit consistent allocations to operate correctly when
-the IO bus is in PCI-X mode. Therefore, like with pci_set_dma_mask(),
-it's good practice to call pci_set_consistent_dma_mask() to set the
-appropriate mask even if your device only supports 32-bit DMA
-(default) and especially if it's a PCI-X device.
-
-For correct operation, you must interrogate the PCI layer in your
-device probe routine to see if the PCI controller on the machine can
-properly support the DMA addressing limitation your device has. It is
-good style to do this even if your device holds the default setting,
-because this shows that you did think about these issues wrt. your
-device.
-
-The query is performed via a call to pci_set_dma_mask():
-
- int pci_set_dma_mask(struct pci_dev *pdev, u64 device_mask);
-
-The query for consistent allocations is performed via a call to
-pci_set_consistent_dma_mask():
-
- int pci_set_consistent_dma_mask(struct pci_dev *pdev, u64 device_mask);
-
-Here, pdev is a pointer to the PCI device struct of your device, and
-device_mask is a bit mask describing which bits of a PCI address your
-device supports. It returns zero if your card can perform DMA
-properly on the machine given the address mask you provided.
-
-If it returns non-zero, your device cannot perform DMA properly on
-this platform, and attempting to do so will result in undefined
-behavior. You must either use a different mask, or not use DMA.
-
-This means that in the failure case, you have three options:
-
-1) Use another DMA mask, if possible (see below).
-2) Use some non-DMA mode for data transfer, if possible.
-3) Ignore this device and do not initialize it.
-
-It is recommended that your driver print a kernel KERN_WARNING message
-when you end up performing either #2 or #3. In this manner, if a user
-of your driver reports that performance is bad or that the device is not
-even detected, you can ask them for the kernel messages to find out
-exactly why.
-
-The standard 32-bit addressing PCI device would do something like
-this:
-
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- printk(KERN_WARNING
- "mydev: No suitable DMA available.\n");
- goto ignore_this_device;
- }
-
-Another common scenario is a 64-bit capable device. The approach
-here is to try for 64-bit DAC addressing, but back down to a
-32-bit mask should that fail. The PCI platform code may fail the
-64-bit mask not because the platform is not capable of 64-bit
-addressing. Rather, it may fail in this case simply because
-32-bit SAC addressing is done more efficiently than DAC addressing.
-Sparc64 is one platform which behaves in this way.
-
-Here is how you would handle a 64-bit capable device which can drive
-all 64-bits when accessing streaming DMA:
-
- int using_dac;
-
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
- using_dac = 1;
- } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- using_dac = 0;
- } else {
- printk(KERN_WARNING
- "mydev: No suitable DMA available.\n");
- goto ignore_this_device;
- }
-
-If a card is capable of using 64-bit consistent allocations as well,
-the case would look like this:
-
- int using_dac, consistent_using_dac;
-
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
- using_dac = 1;
- consistent_using_dac = 1;
- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
- } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- using_dac = 0;
- consistent_using_dac = 0;
- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
- } else {
- printk(KERN_WARNING
- "mydev: No suitable DMA available.\n");
- goto ignore_this_device;
- }
-
-pci_set_consistent_dma_mask() will always be able to set the same or a
-smaller mask as pci_set_dma_mask(). However for the rare case that a
-device driver only uses consistent allocations, one would have to
-check the return value from pci_set_consistent_dma_mask().
-
-Finally, if your device can only drive the low 24-bits of
-address during PCI bus mastering you might do something like:
-
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(24))) {
- printk(KERN_WARNING
- "mydev: 24-bit DMA addressing not available.\n");
- goto ignore_this_device;
- }
-
-When pci_set_dma_mask() is successful, and returns zero, the PCI layer
-saves away this mask you have provided. The PCI layer will use this
-information later when you make DMA mappings.
-
-There is a case which we are aware of at this time, which is worth
-mentioning in this documentation. If your device supports multiple
-functions (for example a sound card provides playback and record
-functions) and the various different functions have _different_
-DMA addressing limitations, you may wish to probe each mask and
-only provide the functionality which the machine can handle. It
-is important that the last call to pci_set_dma_mask() be for the
-most specific mask.
-
-Here is pseudo-code showing how this might be done:
-
- #define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32)
- #define RECORD_ADDRESS_BITS DMA_BIT_MASK(24)
-
- struct my_sound_card *card;
- struct pci_dev *pdev;
-
- ...
- if (!pci_set_dma_mask(pdev, PLAYBACK_ADDRESS_BITS)) {
- card->playback_enabled = 1;
- } else {
- card->playback_enabled = 0;
- printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n",
- card->name);
- }
- if (!pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) {
- card->record_enabled = 1;
- } else {
- card->record_enabled = 0;
- printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n",
- card->name);
- }
-
-A sound card was used as an example here because this genre of PCI
-devices seems to be littered with ISA chips given a PCI front end,
-and thus retaining the 16MB DMA addressing limitations of ISA.
-
- Types of DMA mappings
-
-There are two types of DMA mappings:
-
-- Consistent DMA mappings which are usually mapped at driver
- initialization, unmapped at the end and for which the hardware should
- guarantee that the device and the CPU can access the data
- in parallel and will see updates made by each other without any
- explicit software flushing.
-
- Think of "consistent" as "synchronous" or "coherent".
-
- The current default is to return consistent memory in the low 32
- bits of the PCI bus space. However, for future compatibility you
- should set the consistent mask even if this default is fine for your
- driver.
-
- Good examples of what to use consistent mappings for are:
-
- - Network card DMA ring descriptors.
- - SCSI adapter mailbox command data structures.
- - Device firmware microcode executed out of
- main memory.
-
- The invariant these examples all require is that any CPU store
- to memory is immediately visible to the device, and vice
- versa. Consistent mappings guarantee this.
-
- IMPORTANT: Consistent DMA memory does not preclude the usage of
- proper memory barriers. The CPU may reorder stores to
- consistent memory just as it may normal memory. Example:
- if it is important for the device to see the first word
- of a descriptor updated before the second, you must do
- something like:
-
- desc->word0 = address;
- wmb();
- desc->word1 = DESC_VALID;
-
- in order to get correct behavior on all platforms.
-
- Also, on some platforms your driver may need to flush CPU write
- buffers in much the same way as it needs to flush write buffers
- found in PCI bridges (such as by reading a register's value
- after writing it).
-
-- Streaming DMA mappings which are usually mapped for one DMA transfer,
- unmapped right after it (unless you use pci_dma_sync_* below) and for which
- hardware can optimize for sequential accesses.
-
- This of "streaming" as "asynchronous" or "outside the coherency
- domain".
-
- Good examples of what to use streaming mappings for are:
-
- - Networking buffers transmitted/received by a device.
- - Filesystem buffers written/read by a SCSI device.
-
- The interfaces for using this type of mapping were designed in
- such a way that an implementation can make whatever performance
- optimizations the hardware allows. To this end, when using
- such mappings you must be explicit about what you want to happen.
-
-Neither type of DMA mapping has alignment restrictions that come
-from PCI, although some devices may have such restrictions.
-Also, systems with caches that aren't DMA-coherent will work better
-when the underlying buffers don't share cache lines with other data.
-
-
- Using Consistent DMA mappings.
-
-To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
-you should do:
-
- dma_addr_t dma_handle;
-
- cpu_addr = pci_alloc_consistent(pdev, size, &dma_handle);
-
-where pdev is a struct pci_dev *. This may be called in interrupt context.
-You should use dma_alloc_coherent (see DMA-API.txt) for buses
-where devices don't have struct pci_dev (like ISA, EISA).
-
-This argument is needed because the DMA translations may be bus
-specific (and often is private to the bus which the device is attached
-to).
-
-Size is the length of the region you want to allocate, in bytes.
-
-This routine will allocate RAM for that region, so it acts similarly to
-__get_free_pages (but takes size instead of a page order). If your
-driver needs regions sized smaller than a page, you may prefer using
-the pci_pool interface, described below.
-
-The consistent DMA mapping interfaces, for non-NULL pdev, will by
-default return a DMA address which is SAC (Single Address Cycle)
-addressable. Even if the device indicates (via PCI dma mask) that it
-may address the upper 32-bits and thus perform DAC cycles, consistent
-allocation will only return > 32-bit PCI addresses for DMA if the
-consistent dma mask has been explicitly changed via
-pci_set_consistent_dma_mask(). This is true of the pci_pool interface
-as well.
-
-pci_alloc_consistent returns two values: the virtual address which you
-can use to access it from the CPU and dma_handle which you pass to the
-card.
-
-The cpu return address and the DMA bus master address are both
-guaranteed to be aligned to the smallest PAGE_SIZE order which
-is greater than or equal to the requested size. This invariant
-exists (for example) to guarantee that if you allocate a chunk
-which is smaller than or equal to 64 kilobytes, the extent of the
-buffer you receive will not cross a 64K boundary.
-
-To unmap and free such a DMA region, you call:
-
- pci_free_consistent(pdev, size, cpu_addr, dma_handle);
-
-where pdev, size are the same as in the above call and cpu_addr and
-dma_handle are the values pci_alloc_consistent returned to you.
-This function may not be called in interrupt context.
-
-If your driver needs lots of smaller memory regions, you can write
-custom code to subdivide pages returned by pci_alloc_consistent,
-or you can use the pci_pool API to do that. A pci_pool is like
-a kmem_cache, but it uses pci_alloc_consistent not __get_free_pages.
-Also, it understands common hardware constraints for alignment,
-like queue heads needing to be aligned on N byte boundaries.
-
-Create a pci_pool like this:
-
- struct pci_pool *pool;
-
- pool = pci_pool_create(name, pdev, size, align, alloc);
-
-The "name" is for diagnostics (like a kmem_cache name); pdev and size
-are as above. The device's hardware alignment requirement for this
-type of data is "align" (which is expressed in bytes, and must be a
-power of two). If your device has no boundary crossing restrictions,
-pass 0 for alloc; passing 4096 says memory allocated from this pool
-must not cross 4KByte boundaries (but at that time it may be better to
-go for pci_alloc_consistent directly instead).
-
-Allocate memory from a pci pool like this:
-
- cpu_addr = pci_pool_alloc(pool, flags, &dma_handle);
-
-flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
-holding SMP locks), SLAB_ATOMIC otherwise. Like pci_alloc_consistent,
-this returns two values, cpu_addr and dma_handle.
-
-Free memory that was allocated from a pci_pool like this:
-
- pci_pool_free(pool, cpu_addr, dma_handle);
-
-where pool is what you passed to pci_pool_alloc, and cpu_addr and
-dma_handle are the values pci_pool_alloc returned. This function
-may be called in interrupt context.
-
-Destroy a pci_pool by calling:
-
- pci_pool_destroy(pool);
-
-Make sure you've called pci_pool_free for all memory allocated
-from a pool before you destroy the pool. This function may not
-be called in interrupt context.
-
- DMA Direction
-
-The interfaces described in subsequent portions of this document
-take a DMA direction argument, which is an integer and takes on
-one of the following values:
-
- PCI_DMA_BIDIRECTIONAL
- PCI_DMA_TODEVICE
- PCI_DMA_FROMDEVICE
- PCI_DMA_NONE
-
-One should provide the exact DMA direction if you know it.
-
-PCI_DMA_TODEVICE means "from main memory to the PCI device"
-PCI_DMA_FROMDEVICE means "from the PCI device to main memory"
-It is the direction in which the data moves during the DMA
-transfer.
-
-You are _strongly_ encouraged to specify this as precisely
-as you possibly can.
-
-If you absolutely cannot know the direction of the DMA transfer,
-specify PCI_DMA_BIDIRECTIONAL. It means that the DMA can go in
-either direction. The platform guarantees that you may legally
-specify this, and that it will work, but this may be at the
-cost of performance for example.
-
-The value PCI_DMA_NONE is to be used for debugging. One can
-hold this in a data structure before you come to know the
-precise direction, and this will help catch cases where your
-direction tracking logic has failed to set things up properly.
-
-Another advantage of specifying this value precisely (outside of
-potential platform-specific optimizations of such) is for debugging.
-Some platforms actually have a write permission boolean which DMA
-mappings can be marked with, much like page protections in the user
-program address space. Such platforms can and do report errors in the
-kernel logs when the PCI controller hardware detects violation of the
-permission setting.
-
-Only streaming mappings specify a direction, consistent mappings
-implicitly have a direction attribute setting of
-PCI_DMA_BIDIRECTIONAL.
-
-The SCSI subsystem tells you the direction to use in the
-'sc_data_direction' member of the SCSI command your driver is
-working on.
-
-For Networking drivers, it's a rather simple affair. For transmit
-packets, map/unmap them with the PCI_DMA_TODEVICE direction
-specifier. For receive packets, just the opposite, map/unmap them
-with the PCI_DMA_FROMDEVICE direction specifier.
-
- Using Streaming DMA mappings
-
-The streaming DMA mapping routines can be called from interrupt
-context. There are two versions of each map/unmap, one which will
-map/unmap a single memory region, and one which will map/unmap a
-scatterlist.
-
-To map a single region, you do:
-
- struct pci_dev *pdev = mydev->pdev;
- dma_addr_t dma_handle;
- void *addr = buffer->ptr;
- size_t size = buffer->len;
-
- dma_handle = pci_map_single(pdev, addr, size, direction);
-
-and to unmap it:
-
- pci_unmap_single(pdev, dma_handle, size, direction);
-
-You should call pci_unmap_single when the DMA activity is finished, e.g.
-from the interrupt which told you that the DMA transfer is done.
-
-Using cpu pointers like this for single mappings has a disadvantage,
-you cannot reference HIGHMEM memory in this way. Thus, there is a
-map/unmap interface pair akin to pci_{map,unmap}_single. These
-interfaces deal with page/offset pairs instead of cpu pointers.
-Specifically:
-
- struct pci_dev *pdev = mydev->pdev;
- dma_addr_t dma_handle;
- struct page *page = buffer->page;
- unsigned long offset = buffer->offset;
- size_t size = buffer->len;
-
- dma_handle = pci_map_page(pdev, page, offset, size, direction);
-
- ...
-
- pci_unmap_page(pdev, dma_handle, size, direction);
-
-Here, "offset" means byte offset within the given page.
-
-With scatterlists, you map a region gathered from several regions by:
-
- int i, count = pci_map_sg(pdev, sglist, nents, direction);
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, count, i) {
- hw_address[i] = sg_dma_address(sg);
- hw_len[i] = sg_dma_len(sg);
- }
-
-where nents is the number of entries in the sglist.
-
-The implementation is free to merge several consecutive sglist entries
-into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
-consecutive sglist entries can be merged into one provided the first one
-ends and the second one starts on a page boundary - in fact this is a huge
-advantage for cards which either cannot do scatter-gather or have very
-limited number of scatter-gather entries) and returns the actual number
-of sg entries it mapped them to. On failure 0 is returned.
-
-Then you should loop count times (note: this can be less than nents times)
-and use sg_dma_address() and sg_dma_len() macros where you previously
-accessed sg->address and sg->length as shown above.
-
-To unmap a scatterlist, just call:
-
- pci_unmap_sg(pdev, sglist, nents, direction);
-
-Again, make sure DMA activity has already finished.
-
-PLEASE NOTE: The 'nents' argument to the pci_unmap_sg call must be
- the _same_ one you passed into the pci_map_sg call,
- it should _NOT_ be the 'count' value _returned_ from the
- pci_map_sg call.
-
-Every pci_map_{single,sg} call should have its pci_unmap_{single,sg}
-counterpart, because the bus address space is a shared resource (although
-in some ports the mapping is per each BUS so less devices contend for the
-same bus address space) and you could render the machine unusable by eating
-all bus addresses.
-
-If you need to use the same streaming DMA region multiple times and touch
-the data in between the DMA transfers, the buffer needs to be synced
-properly in order for the cpu and device to see the most uptodate and
-correct copy of the DMA buffer.
-
-So, firstly, just map it with pci_map_{single,sg}, and after each DMA
-transfer call either:
-
- pci_dma_sync_single_for_cpu(pdev, dma_handle, size, direction);
-
-or:
-
- pci_dma_sync_sg_for_cpu(pdev, sglist, nents, direction);
-
-as appropriate.
-
-Then, if you wish to let the device get at the DMA area again,
-finish accessing the data with the cpu, and then before actually
-giving the buffer to the hardware call either:
-
- pci_dma_sync_single_for_device(pdev, dma_handle, size, direction);
-
-or:
-
- pci_dma_sync_sg_for_device(dev, sglist, nents, direction);
-
-as appropriate.
-
-After the last DMA transfer call one of the DMA unmap routines
-pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_*
-call till pci_unmap_*, then you don't have to call the pci_dma_sync_*
-routines at all.
-
-Here is pseudo code which shows a situation in which you would need
-to use the pci_dma_sync_*() interfaces.
-
- my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
- {
- dma_addr_t mapping;
-
- mapping = pci_map_single(cp->pdev, buffer, len, PCI_DMA_FROMDEVICE);
-
- cp->rx_buf = buffer;
- cp->rx_len = len;
- cp->rx_dma = mapping;
-
- give_rx_buf_to_card(cp);
- }
-
- ...
-
- my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs)
- {
- struct my_card *cp = devid;
-
- ...
- if (read_card_status(cp) == RX_BUF_TRANSFERRED) {
- struct my_card_header *hp;
-
- /* Examine the header to see if we wish
- * to accept the data. But synchronize
- * the DMA transfer with the CPU first
- * so that we see updated contents.
- */
- pci_dma_sync_single_for_cpu(cp->pdev, cp->rx_dma,
- cp->rx_len,
- PCI_DMA_FROMDEVICE);
-
- /* Now it is safe to examine the buffer. */
- hp = (struct my_card_header *) cp->rx_buf;
- if (header_is_ok(hp)) {
- pci_unmap_single(cp->pdev, cp->rx_dma, cp->rx_len,
- PCI_DMA_FROMDEVICE);
- pass_to_upper_layers(cp->rx_buf);
- make_and_setup_new_rx_buf(cp);
- } else {
- /* Just sync the buffer and give it back
- * to the card.
- */
- pci_dma_sync_single_for_device(cp->pdev,
- cp->rx_dma,
- cp->rx_len,
- PCI_DMA_FROMDEVICE);
- give_rx_buf_to_card(cp);
- }
- }
- }
-
-Drivers converted fully to this interface should not use virt_to_bus any
-longer, nor should they use bus_to_virt. Some drivers have to be changed a
-little bit, because there is no longer an equivalent to bus_to_virt in the
-dynamic DMA mapping scheme - you have to always store the DMA addresses
-returned by the pci_alloc_consistent, pci_pool_alloc, and pci_map_single
-calls (pci_map_sg stores them in the scatterlist itself if the platform
-supports dynamic DMA mapping in hardware) in your driver structures and/or
-in the card registers.
-
-All PCI drivers should be using these interfaces with no exceptions.
-It is planned to completely remove virt_to_bus() and bus_to_virt() as
-they are entirely deprecated. Some ports already do not provide these
-as it is impossible to correctly support them.
-
- Optimizing Unmap State Space Consumption
-
-On many platforms, pci_unmap_{single,page}() is simply a nop.
-Therefore, keeping track of the mapping address and length is a waste
-of space. Instead of filling your drivers up with ifdefs and the like
-to "work around" this (which would defeat the whole purpose of a
-portable API) the following facilities are provided.
-
-Actually, instead of describing the macros one by one, we'll
-transform some example code.
-
-1) Use DECLARE_PCI_UNMAP_{ADDR,LEN} in state saving structures.
- Example, before:
-
- struct ring_state {
- struct sk_buff *skb;
- dma_addr_t mapping;
- __u32 len;
- };
-
- after:
-
- struct ring_state {
- struct sk_buff *skb;
- DECLARE_PCI_UNMAP_ADDR(mapping)
- DECLARE_PCI_UNMAP_LEN(len)
- };
-
- NOTE: DO NOT put a semicolon at the end of the DECLARE_*()
- macro.
-
-2) Use pci_unmap_{addr,len}_set to set these values.
- Example, before:
-
- ringp->mapping = FOO;
- ringp->len = BAR;
-
- after:
-
- pci_unmap_addr_set(ringp, mapping, FOO);
- pci_unmap_len_set(ringp, len, BAR);
-
-3) Use pci_unmap_{addr,len} to access these values.
- Example, before:
-
- pci_unmap_single(pdev, ringp->mapping, ringp->len,
- PCI_DMA_FROMDEVICE);
-
- after:
-
- pci_unmap_single(pdev,
- pci_unmap_addr(ringp, mapping),
- pci_unmap_len(ringp, len),
- PCI_DMA_FROMDEVICE);
-
-It really should be self-explanatory. We treat the ADDR and LEN
-separately, because it is possible for an implementation to only
-need the address in order to perform the unmap operation.
-
- Platform Issues
-
-If you are just writing drivers for Linux and do not maintain
-an architecture port for the kernel, you can safely skip down
-to "Closing".
-
-1) Struct scatterlist requirements.
-
- Struct scatterlist must contain, at a minimum, the following
- members:
-
- struct page *page;
- unsigned int offset;
- unsigned int length;
-
- The base address is specified by a "page+offset" pair.
-
- Previous versions of struct scatterlist contained a "void *address"
- field that was sometimes used instead of page+offset. As of Linux
- 2.5., page+offset is always used, and the "address" field has been
- deleted.
-
-2) More to come...
-
- Handling Errors
-
-DMA address space is limited on some architectures and an allocation
-failure can be determined by:
-
-- checking if pci_alloc_consistent returns NULL or pci_map_sg returns 0
-
-- checking the returned dma_addr_t of pci_map_single and pci_map_page
- by using pci_dma_mapping_error():
-
- dma_addr_t dma_handle;
-
- dma_handle = pci_map_single(pdev, addr, size, direction);
- if (pci_dma_mapping_error(pdev, dma_handle)) {
- /*
- * reduce current DMA mapping usage,
- * delay and try again later or
- * reset driver.
- */
- }
-
- Closing
-
-This document, and the API itself, would not be in it's current
-form without the feedback and suggestions from numerous individuals.
-We would like to specifically mention, in no particular order, the
-following people:
-
- Russell King <rmk@arm.linux.org.uk>
- Leo Dagum <dagum@barrel.engr.sgi.com>
- Ralf Baechle <ralf@oss.sgi.com>
- Grant Grundler <grundler@cup.hp.com>
- Jay Estabrook <Jay.Estabrook@compaq.com>
- Thomas Sailer <sailer@ife.ee.ethz.ch>
- Andrea Arcangeli <andrea@suse.de>
- Jens Axboe <jens.axboe@oracle.com>
- David Mosberger-Tang <davidm@hpl.hp.com>
diff --git a/Documentation/RCU/NMI-RCU.txt b/Documentation/RCU/NMI-RCU.txt
index a6d32e65d22..a8536cb8809 100644
--- a/Documentation/RCU/NMI-RCU.txt
+++ b/Documentation/RCU/NMI-RCU.txt
@@ -34,7 +34,7 @@ NMI handler.
cpu = smp_processor_id();
++nmi_count(cpu);
- if (!rcu_dereference(nmi_callback)(regs, cpu))
+ if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
default_do_nmi(regs);
nmi_exit();
@@ -47,12 +47,13 @@ function pointer. If this handler returns zero, do_nmi() invokes the
default_do_nmi() function to handle a machine-specific NMI. Finally,
preemption is restored.
-Strictly speaking, rcu_dereference() is not needed, since this code runs
-only on i386, which does not need rcu_dereference() anyway. However,
-it is a good documentation aid, particularly for anyone attempting to
-do something similar on Alpha.
+In theory, rcu_dereference_sched() is not needed, since this code runs
+only on i386, which in theory does not need rcu_dereference_sched()
+anyway. However, in practice it is a good documentation aid, particularly
+for anyone attempting to do something similar on Alpha or on systems
+with aggressive optimizing compilers.
-Quick Quiz: Why might the rcu_dereference() be necessary on Alpha,
+Quick Quiz: Why might the rcu_dereference_sched() be necessary on Alpha,
given that the code referenced by the pointer is read-only?
@@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI entry and exit, respectively.
Answer to Quick Quiz
- Why might the rcu_dereference() be necessary on Alpha, given
+ Why might the rcu_dereference_sched() be necessary on Alpha, given
that the code referenced by the pointer is read-only?
Answer: The caller to set_nmi_callback() might well have
- initialized some data that is to be used by the
- new NMI handler. In this case, the rcu_dereference()
- would be needed, because otherwise a CPU that received
- an NMI just after the new handler was set might see
- the pointer to the new NMI handler, but the old
- pre-initialized version of the handler's data.
-
- More important, the rcu_dereference() makes it clear
- to someone reading the code that the pointer is being
- protected by RCU.
+ initialized some data that is to be used by the new NMI
+ handler. In this case, the rcu_dereference_sched() would
+ be needed, because otherwise a CPU that received an NMI
+ just after the new handler was set might see the pointer
+ to the new NMI handler, but the old pre-initialized
+ version of the handler's data.
+
+ This same sad story can happen on other CPUs when using
+ a compiler with aggressive pointer-value speculation
+ optimizations.
+
+ More important, the rcu_dereference_sched() makes it
+ clear to someone reading the code that the pointer is
+ being protected by RCU-sched.
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
index cbc180f9019..790d1a81237 100644
--- a/Documentation/RCU/checklist.txt
+++ b/Documentation/RCU/checklist.txt
@@ -260,7 +260,8 @@ over a rather long period of time, but improvements are always welcome!
The reason that it is permissible to use RCU list-traversal
primitives when the update-side lock is held is that doing so
can be quite helpful in reducing code bloat when common code is
- shared between readers and updaters.
+ shared between readers and updaters. Additional primitives
+ are provided for this case, as discussed in lockdep.txt.
10. Conversely, if you are in an RCU read-side critical section,
and you don't hold the appropriate update-side lock, you -must-
@@ -344,8 +345,8 @@ over a rather long period of time, but improvements are always welcome!
requiring SRCU's read-side deadlock immunity or low read-side
realtime latency.
- Note that, rcu_assign_pointer() and rcu_dereference() relate to
- SRCU just as they do to other forms of RCU.
+ Note that, rcu_assign_pointer() relates to SRCU just as they do
+ to other forms of RCU.
15. The whole point of call_rcu(), synchronize_rcu(), and friends
is to wait until all pre-existing readers have finished before
diff --git a/Documentation/RCU/lockdep.txt b/Documentation/RCU/lockdep.txt
index fe24b58627b..d7a49b2f699 100644
--- a/Documentation/RCU/lockdep.txt
+++ b/Documentation/RCU/lockdep.txt
@@ -32,9 +32,20 @@ checking of rcu_dereference() primitives:
srcu_dereference(p, sp):
Check for SRCU read-side critical section.
rcu_dereference_check(p, c):
- Use explicit check expression "c".
+ Use explicit check expression "c". This is useful in
+ code that is invoked by both readers and updaters.
rcu_dereference_raw(p)
Don't check. (Use sparingly, if at all.)
+ rcu_dereference_protected(p, c):
+ Use explicit check expression "c", and omit all barriers
+ and compiler constraints. This is useful when the data
+ structure cannot change, for example, in code that is
+ invoked only by updaters.
+ rcu_access_pointer(p):
+ Return the value of the pointer and omit all barriers,
+ but retain the compiler constraints that prevent duplicating
+ or coalescsing. This is useful when when testing the
+ value of the pointer itself, for example, against NULL.
The rcu_dereference_check() check expression can be any boolean
expression, but would normally include one of the rcu_read_lock_held()
@@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla
RCU read-side critical sections, in case (2) the ->file_lock prevents
any change from taking place, and finally, in case (3) the current task
is the only task accessing the file_struct, again preventing any change
-from taking place.
+from taking place. If the above statement was invoked only from updater
+code, it could instead be written as follows:
+
+ file = rcu_dereference_protected(fdt->fd[fd],
+ lockdep_is_held(&files->file_lock) ||
+ atomic_read(&files->count) == 1);
+
+This would verify cases #2 and #3 above, and furthermore lockdep would
+complain if this was used in an RCU read-side critical section unless one
+of these two cases held. Because rcu_dereference_protected() omits all
+barriers and compiler constraints, it generates better code than do the
+other flavors of rcu_dereference(). On the other hand, it is illegal
+to use rcu_dereference_protected() if either the RCU-protected pointer
+or the RCU-protected data that it points to can change concurrently.
There are currently only "universal" versions of the rcu_assign_pointer()
and RCU list-/tree-traversal primitives, which do not (yet) check for
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 1dc00ee9716..cfaac34c455 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -840,6 +840,12 @@ SRCU: Initialization/cleanup
init_srcu_struct
cleanup_srcu_struct
+All: lockdep-checked RCU-protected pointer access
+
+ rcu_dereference_check
+ rcu_dereference_protected
+ rcu_access_pointer
+
See the comment headers in the source code (or the docbook generated
from them) for more information.
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
index 1053a56be3b..8916ca48bc9 100644
--- a/Documentation/SubmitChecklist
+++ b/Documentation/SubmitChecklist
@@ -9,10 +9,14 @@ Documentation/SubmittingPatches and elsewhere regarding submitting Linux
kernel patches.
-1: Builds cleanly with applicable or modified CONFIG options =y, =m, and
+1: If you use a facility then #include the file that defines/declares
+ that facility. Don't depend on other header files pulling in ones
+ that you use.
+
+2: Builds cleanly with applicable or modified CONFIG options =y, =m, and
=n. No gcc warnings/errors, no linker warnings/errors.
-2: Passes allnoconfig, allmodconfig
+2b: Passes allnoconfig, allmodconfig
3: Builds on multiple CPU architectures by using local cross-compile tools
or some other build farm.
diff --git a/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt b/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt
index 76b3a11e90b..fa968aa99d6 100644
--- a/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt
+++ b/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt
@@ -14,8 +14,8 @@ Introduction
how the clocks are arranged. The first implementation used as single
PLL to feed the ARM, memory and peripherals via a series of dividers
and muxes and this is the implementation that is documented here. A
- newer version where there is a seperate PLL and clock divider for the
- ARM core is available as a seperate driver.
+ newer version where there is a separate PLL and clock divider for the
+ ARM core is available as a separate driver.
Layout
diff --git a/Documentation/arm/Samsung/Overview.txt b/Documentation/arm/Samsung/Overview.txt
new file mode 100644
index 00000000000..7cced1fea9c
--- /dev/null
+++ b/Documentation/arm/Samsung/Overview.txt
@@ -0,0 +1,86 @@
+ Samsung ARM Linux Overview
+ ==========================
+
+Introduction
+------------
+
+ The Samsung range of ARM SoCs spans many similar devices, from the initial
+ ARM9 through to the newest ARM cores. This document shows an overview of
+ the current kernel support, how to use it and where to find the code
+ that supports this.
+
+ The currently supported SoCs are:
+
+ - S3C24XX: See Documentation/arm/Samsung-S3C24XX/Overview.txt for full list
+ - S3C64XX: S3C6400 and S3C6410
+ - S5PC6440
+
+ S5PC100 and S5PC110 support is currently being merged
+
+
+S3C24XX Systems
+---------------
+
+ There is still documentation in Documnetation/arm/Samsung-S3C24XX/ which
+ deals with the architecture and drivers specific to these devices.
+
+ See Documentation/arm/Samsung-S3C24XX/Overview.txt for more information
+ on the implementation details and specific support.
+
+
+Configuration
+-------------
+
+ A number of configurations are supplied, as there is no current way of
+ unifying all the SoCs into one kernel.
+
+ s5p6440_defconfig - S5P6440 specific default configuration
+ s5pc100_defconfig - S5PC100 specific default configuration
+
+
+Layout
+------
+
+ The directory layout is currently being restructured, and consists of
+ several platform directories and then the machine specific directories
+ of the CPUs being built for.
+
+ plat-samsung provides the base for all the implementations, and is the
+ last in the line of include directories that are processed for the build
+ specific information. It contains the base clock, GPIO and device definitions
+ to get the system running.
+
+ plat-s3c is the s3c24xx/s3c64xx platform directory, although it is currently
+ involved in other builds this will be phased out once the relevant code is
+ moved elsewhere.
+
+ plat-s3c24xx is for s3c24xx specific builds, see the S3C24XX docs.
+
+ plat-s3c64xx is for the s3c64xx specific bits, see the S3C24XX docs.
+
+ plat-s5p is for s5p specific builds, more to be added.
+
+
+ [ to finish ]
+
+
+Port Contributors
+-----------------
+
+ Ben Dooks (BJD)
+ Vincent Sanders
+ Herbert Potzl
+ Arnaud Patard (RTP)
+ Roc Wu
+ Klaus Fetscher
+ Dimitry Andric
+ Shannon Holland
+ Guillaume Gourat (NexVision)
+ Christer Weinigel (wingel) (Acer N30)
+ Lucas Correia Villa Real (S3C2400 port)
+
+
+Document Author
+---------------
+
+Copyright 2009-2010 Ben Dooks <ben-linux@fluff.org>
diff --git a/Documentation/arm/Samsung/clksrc-change-registers.awk b/Documentation/arm/Samsung/clksrc-change-registers.awk
new file mode 100755
index 00000000000..0c50220851f
--- /dev/null
+++ b/Documentation/arm/Samsung/clksrc-change-registers.awk
@@ -0,0 +1,167 @@
+#!/usr/bin/awk -f
+#
+# Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+#
+# Released under GPLv2
+
+# example usage
+# ./clksrc-change-registers.awk arch/arm/plat-s5pc1xx/include/plat/regs-clock.h < src > dst
+
+function extract_value(s)
+{
+ eqat = index(s, "=")
+ comat = index(s, ",")
+ return substr(s, eqat+2, (comat-eqat)-2)
+}
+
+function remove_brackets(b)
+{
+ return substr(b, 2, length(b)-2)
+}
+
+function splitdefine(l, p)
+{
+ r = split(l, tp)
+
+ p[0] = tp[2]
+ p[1] = remove_brackets(tp[3])
+}
+
+function find_length(f)
+{
+ if (0)
+ printf "find_length " f "\n" > "/dev/stderr"
+
+ if (f ~ /0x1/)
+ return 1
+ else if (f ~ /0x3/)
+ return 2
+ else if (f ~ /0x7/)
+ return 3
+ else if (f ~ /0xf/)
+ return 4
+
+ printf "unknown legnth " f "\n" > "/dev/stderr"
+ exit
+}
+
+function find_shift(s)
+{
+ id = index(s, "<")
+ if (id <= 0) {
+ printf "cannot find shift " s "\n" > "/dev/stderr"
+ exit
+ }
+
+ return substr(s, id+2)
+}
+
+
+BEGIN {
+ if (ARGC < 2) {
+ print "too few arguments" > "/dev/stderr"
+ exit
+ }
+
+# read the header file and find the mask values that we will need
+# to replace and create an associative array of values
+
+ while (getline line < ARGV[1] > 0) {
+ if (line ~ /\#define.*_MASK/ &&
+ !(line ~ /S5PC100_EPLL_MASK/) &&
+ !(line ~ /USB_SIG_MASK/)) {
+ splitdefine(line, fields)
+ name = fields[0]
+ if (0)
+ printf "MASK " line "\n" > "/dev/stderr"
+ dmask[name,0] = find_length(fields[1])
+ dmask[name,1] = find_shift(fields[1])
+ if (0)
+ printf "=> '" name "' LENGTH=" dmask[name,0] " SHIFT=" dmask[name,1] "\n" > "/dev/stderr"
+ } else {
+ }
+ }
+
+ delete ARGV[1]
+}
+
+/clksrc_clk.*=.*{/ {
+ shift=""
+ mask=""
+ divshift=""
+ reg_div=""
+ reg_src=""
+ indent=1
+
+ print $0
+
+ for(; indent >= 1;) {
+ if ((getline line) <= 0) {
+ printf "unexpected end of file" > "/dev/stderr"
+ exit 1;
+ }
+
+ if (line ~ /\.shift/) {
+ shift = extract_value(line)
+ } else if (line ~ /\.mask/) {
+ mask = extract_value(line)
+ } else if (line ~ /\.reg_divider/) {
+ reg_div = extract_value(line)
+ } else if (line ~ /\.reg_source/) {
+ reg_src = extract_value(line)
+ } else if (line ~ /\.divider_shift/) {
+ divshift = extract_value(line)
+ } else if (line ~ /{/) {
+ indent++
+ print line
+ } else if (line ~ /}/) {
+ indent--
+
+ if (indent == 0) {
+ if (0) {
+ printf "shift '" shift "' ='" dmask[shift,0] "'\n" > "/dev/stderr"
+ printf "mask '" mask "'\n" > "/dev/stderr"
+ printf "dshft '" divshift "'\n" > "/dev/stderr"
+ printf "rdiv '" reg_div "'\n" > "/dev/stderr"
+ printf "rsrc '" reg_src "'\n" > "/dev/stderr"
+ }
+
+ generated = mask
+ sub(reg_src, reg_div, generated)
+
+ if (0) {
+ printf "/* rsrc " reg_src " */\n"
+ printf "/* rdiv " reg_div " */\n"
+ printf "/* shift " shift " */\n"
+ printf "/* mask " mask " */\n"
+ printf "/* generated " generated " */\n"
+ }
+
+ if (reg_div != "") {
+ printf "\t.reg_div = { "
+ printf ".reg = " reg_div ", "
+ printf ".shift = " dmask[generated,1] ", "
+ printf ".size = " dmask[generated,0] ", "
+ printf "},\n"
+ }
+
+ printf "\t.reg_src = { "
+ printf ".reg = " reg_src ", "
+ printf ".shift = " dmask[mask,1] ", "
+ printf ".size = " dmask[mask,0] ", "
+
+ printf "},\n"
+
+ }
+
+ print line
+ } else {
+ print line
+ }
+
+ if (0)
+ printf indent ":" line "\n" > "/dev/stderr"
+ }
+}
+
+// && ! /clksrc_clk.*=.*{/ { print $0 }
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index 6fab97ea7e6..508b5b2b028 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -1162,8 +1162,8 @@ where a driver received a request ala this before:
As mentioned, there is no virtual mapping of a bio. For DMA, this is
not a problem as the driver probably never will need a virtual mapping.
-Instead it needs a bus mapping (pci_map_page for a single segment or
-use blk_rq_map_sg for scatter gather) to be able to ship it to the driver. For
+Instead it needs a bus mapping (dma_map_page for a single segment or
+use dma_map_sg for scatter gather) to be able to ship it to the driver. For
PIO drivers (or drivers that need to revert to PIO transfer once in a
while (IDE for example)), where the CPU is doing the actual data
transfer a virtual mapping is needed. If the driver supports highmem I/O,
diff --git a/Documentation/cgroups/cgroup_event_listener.c b/Documentation/cgroups/cgroup_event_listener.c
new file mode 100644
index 00000000000..8c2bfc4a635
--- /dev/null
+++ b/Documentation/cgroups/cgroup_event_listener.c
@@ -0,0 +1,110 @@
+/*
+ * cgroup_event_listener.c - Simple listener of cgroup events
+ *
+ * Copyright (C) Kirill A. Shutemov <kirill@shutemov.name>
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/eventfd.h>
+
+#define USAGE_STR "Usage: cgroup_event_listener <path-to-control-file> <args>\n"
+
+int main(int argc, char **argv)
+{
+ int efd = -1;
+ int cfd = -1;
+ int event_control = -1;
+ char event_control_path[PATH_MAX];
+ char line[LINE_MAX];
+ int ret;
+
+ if (argc != 3) {
+ fputs(USAGE_STR, stderr);
+ return 1;
+ }
+
+ cfd = open(argv[1], O_RDONLY);
+ if (cfd == -1) {
+ fprintf(stderr, "Cannot open %s: %s\n", argv[1],
+ strerror(errno));
+ goto out;
+ }
+
+ ret = snprintf(event_control_path, PATH_MAX, "%s/cgroup.event_control",
+ dirname(argv[1]));
+ if (ret >= PATH_MAX) {
+ fputs("Path to cgroup.event_control is too long\n", stderr);
+ goto out;
+ }
+
+ event_control = open(event_control_path, O_WRONLY);
+ if (event_control == -1) {
+ fprintf(stderr, "Cannot open %s: %s\n", event_control_path,
+ strerror(errno));
+ goto out;
+ }
+
+ efd = eventfd(0, 0);
+ if (efd == -1) {
+ perror("eventfd() failed");
+ goto out;
+ }
+
+ ret = snprintf(line, LINE_MAX, "%d %d %s", efd, cfd, argv[2]);
+ if (ret >= LINE_MAX) {
+ fputs("Arguments string is too long\n", stderr);
+ goto out;
+ }
+
+ ret = write(event_control, line, strlen(line) + 1);
+ if (ret == -1) {
+ perror("Cannot write to cgroup.event_control");
+ goto out;
+ }
+
+ while (1) {
+ uint64_t result;
+
+ ret = read(efd, &result, sizeof(result));
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+ perror("Cannot read from eventfd");
+ break;
+ }
+ assert(ret == sizeof(result));
+
+ ret = access(event_control_path, W_OK);
+ if ((ret == -1) && (errno == ENOENT)) {
+ puts("The cgroup seems to have removed.");
+ ret = 0;
+ break;
+ }
+
+ if (ret == -1) {
+ perror("cgroup.event_control "
+ "is not accessable any more");
+ break;
+ }
+
+ printf("%s %s: crossed\n", argv[1], argv[2]);
+ }
+
+out:
+ if (efd >= 0)
+ close(efd);
+ if (event_control >= 0)
+ close(event_control);
+ if (cfd >= 0)
+ close(cfd);
+
+ return (ret != 0);
+}
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
index 0b33bfe7dde..a1ca5924faf 100644
--- a/Documentation/cgroups/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
@@ -22,6 +22,8 @@ CONTENTS:
2. Usage Examples and Syntax
2.1 Basic Usage
2.2 Attaching processes
+ 2.3 Mounting hierarchies by name
+ 2.4 Notification API
3. Kernel API
3.1 Overview
3.2 Synchronization
@@ -233,8 +235,7 @@ containing the following files describing that cgroup:
- cgroup.procs: list of tgids in the cgroup. This list is not
guaranteed to be sorted or free of duplicate tgids, and userspace
should sort/uniquify the list if this property is required.
- Writing a tgid into this file moves all threads with that tgid into
- this cgroup.
+ This is a read-only file, for now.
- notify_on_release flag: run the release agent on exit?
- release_agent: the path to use for release notifications (this file
exists in the top cgroup only)
@@ -434,6 +435,25 @@ you give a subsystem a name.
The name of the subsystem appears as part of the hierarchy description
in /proc/mounts and /proc/<pid>/cgroups.
+2.4 Notification API
+--------------------
+
+There is mechanism which allows to get notifications about changing
+status of a cgroup.
+
+To register new notification handler you need:
+ - create a file descriptor for event notification using eventfd(2);
+ - open a control file to be monitored (e.g. memory.usage_in_bytes);
+ - write "<event_fd> <control_fd> <args>" to cgroup.event_control.
+ Interpretation of args is defined by control file implementation;
+
+eventfd will be woken up by control file implementation or when the
+cgroup is removed.
+
+To unregister notification handler just close eventfd.
+
+NOTE: Support of notifications should be implemented for the control
+file. See documentation for the subsystem.
3. Kernel API
=============
@@ -488,6 +508,11 @@ Each subsystem should:
- add an entry in linux/cgroup_subsys.h
- define a cgroup_subsys object called <name>_subsys
+If a subsystem can be compiled as a module, it should also have in its
+module initcall a call to cgroup_load_subsys(), and in its exitcall a
+call to cgroup_unload_subsys(). It should also set its_subsys.module =
+THIS_MODULE in its .c file.
+
Each subsystem may export the following methods. The only mandatory
methods are create/destroy. Any others that are null are presumed to
be successful no-ops.
@@ -536,10 +561,21 @@ returns an error, this will abort the attach operation. If a NULL
task is passed, then a successful result indicates that *any*
unspecified task can be moved into the cgroup. Note that this isn't
called on a fork. If this method returns 0 (success) then this should
-remain valid while the caller holds cgroup_mutex. If threadgroup is
+remain valid while the caller holds cgroup_mutex and it is ensured that either
+attach() or cancel_attach() will be called in future. If threadgroup is
true, then a successful result indicates that all threads in the given
thread's threadgroup can be moved together.
+void cancel_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
+ struct task_struct *task, bool threadgroup)
+(cgroup_mutex held by caller)
+
+Called when a task attach operation has failed after can_attach() has succeeded.
+A subsystem whose can_attach() has some side-effects should provide this
+function, so that the subsytem can implement a rollback. If not, not necessary.
+This will be called only about subsystems whose can_attach() operation have
+succeeded.
+
void attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
struct cgroup *old_cgrp, struct task_struct *task,
bool threadgroup)
diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpusets.txt
index 1d7e9784439..4160df82b3f 100644
--- a/Documentation/cgroups/cpusets.txt
+++ b/Documentation/cgroups/cpusets.txt
@@ -168,20 +168,20 @@ Each cpuset is represented by a directory in the cgroup file system
containing (on top of the standard cgroup files) the following
files describing that cpuset:
- - cpus: list of CPUs in that cpuset
- - mems: list of Memory Nodes in that cpuset
- - memory_migrate flag: if set, move pages to cpusets nodes
- - cpu_exclusive flag: is cpu placement exclusive?
- - mem_exclusive flag: is memory placement exclusive?
- - mem_hardwall flag: is memory allocation hardwalled
- - memory_pressure: measure of how much paging pressure in cpuset
- - memory_spread_page flag: if set, spread page cache evenly on allowed nodes
- - memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes
- - sched_load_balance flag: if set, load balance within CPUs on that cpuset
- - sched_relax_domain_level: the searching range when migrating tasks
+ - cpuset.cpus: list of CPUs in that cpuset
+ - cpuset.mems: list of Memory Nodes in that cpuset
+ - cpuset.memory_migrate flag: if set, move pages to cpusets nodes
+ - cpuset.cpu_exclusive flag: is cpu placement exclusive?
+ - cpuset.mem_exclusive flag: is memory placement exclusive?
+ - cpuset.mem_hardwall flag: is memory allocation hardwalled
+ - cpuset.memory_pressure: measure of how much paging pressure in cpuset
+ - cpuset.memory_spread_page flag: if set, spread page cache evenly on allowed nodes
+ - cpuset.memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes
+ - cpuset.sched_load_balance flag: if set, load balance within CPUs on that cpuset
+ - cpuset.sched_relax_domain_level: the searching range when migrating tasks
In addition, the root cpuset only has the following file:
- - memory_pressure_enabled flag: compute memory_pressure?
+ - cpuset.memory_pressure_enabled flag: compute memory_pressure?
New cpusets are created using the mkdir system call or shell
command. The properties of a cpuset, such as its flags, allowed
@@ -229,7 +229,7 @@ If a cpuset is cpu or mem exclusive, no other cpuset, other than
a direct ancestor or descendant, may share any of the same CPUs or
Memory Nodes.
-A cpuset that is mem_exclusive *or* mem_hardwall is "hardwalled",
+A cpuset that is cpuset.mem_exclusive *or* cpuset.mem_hardwall is "hardwalled",
i.e. it restricts kernel allocations for page, buffer and other data
commonly shared by the kernel across multiple users. All cpusets,
whether hardwalled or not, restrict allocations of memory for user
@@ -304,15 +304,15 @@ times 1000.
---------------------------
There are two boolean flag files per cpuset that control where the
kernel allocates pages for the file system buffers and related in
-kernel data structures. They are called 'memory_spread_page' and
-'memory_spread_slab'.
+kernel data structures. They are called 'cpuset.memory_spread_page' and
+'cpuset.memory_spread_slab'.
-If the per-cpuset boolean flag file 'memory_spread_page' is set, then
+If the per-cpuset boolean flag file 'cpuset.memory_spread_page' is set, then
the kernel will spread the file system buffers (page cache) evenly
over all the nodes that the faulting task is allowed to use, instead
of preferring to put those pages on the node where the task is running.
-If the per-cpuset boolean flag file 'memory_spread_slab' is set,
+If the per-cpuset boolean flag file 'cpuset.memory_spread_slab' is set,
then the kernel will spread some file system related slab caches,
such as for inodes and dentries evenly over all the nodes that the
faulting task is allowed to use, instead of preferring to put those
@@ -337,21 +337,21 @@ their containing tasks memory spread settings. If memory spreading
is turned off, then the currently specified NUMA mempolicy once again
applies to memory page allocations.
-Both 'memory_spread_page' and 'memory_spread_slab' are boolean flag
+Both 'cpuset.memory_spread_page' and 'cpuset.memory_spread_slab' are boolean flag
files. By default they contain "0", meaning that the feature is off
for that cpuset. If a "1" is written to that file, then that turns
the named feature on.
The implementation is simple.
-Setting the flag 'memory_spread_page' turns on a per-process flag
+Setting the flag 'cpuset.memory_spread_page' turns on a per-process flag
PF_SPREAD_PAGE for each task that is in that cpuset or subsequently
joins that cpuset. The page allocation calls for the page cache
is modified to perform an inline check for this PF_SPREAD_PAGE task
flag, and if set, a call to a new routine cpuset_mem_spread_node()
returns the node to prefer for the allocation.
-Similarly, setting 'memory_spread_slab' turns on the flag
+Similarly, setting 'cpuset.memory_spread_slab' turns on the flag
PF_SPREAD_SLAB, and appropriately marked slab caches will allocate
pages from the node returned by cpuset_mem_spread_node().
@@ -404,24 +404,24 @@ the following two situations:
system overhead on those CPUs, including avoiding task load
balancing if that is not needed.
-When the per-cpuset flag "sched_load_balance" is enabled (the default
-setting), it requests that all the CPUs in that cpusets allowed 'cpus'
+When the per-cpuset flag "cpuset.sched_load_balance" is enabled (the default
+setting), it requests that all the CPUs in that cpusets allowed 'cpuset.cpus'
be contained in a single sched domain, ensuring that load balancing
can move a task (not otherwised pinned, as by sched_setaffinity)
from any CPU in that cpuset to any other.
-When the per-cpuset flag "sched_load_balance" is disabled, then the
+When the per-cpuset flag "cpuset.sched_load_balance" is disabled, then the
scheduler will avoid load balancing across the CPUs in that cpuset,
--except-- in so far as is necessary because some overlapping cpuset
has "sched_load_balance" enabled.
-So, for example, if the top cpuset has the flag "sched_load_balance"
+So, for example, if the top cpuset has the flag "cpuset.sched_load_balance"
enabled, then the scheduler will have one sched domain covering all
-CPUs, and the setting of the "sched_load_balance" flag in any other
+CPUs, and the setting of the "cpuset.sched_load_balance" flag in any other
cpusets won't matter, as we're already fully load balancing.
Therefore in the above two situations, the top cpuset flag
-"sched_load_balance" should be disabled, and only some of the smaller,
+"cpuset.sched_load_balance" should be disabled, and only some of the smaller,
child cpusets have this flag enabled.
When doing this, you don't usually want to leave any unpinned tasks in
@@ -433,7 +433,7 @@ scheduler might not consider the possibility of load balancing that
task to that underused CPU.
Of course, tasks pinned to a particular CPU can be left in a cpuset
-that disables "sched_load_balance" as those tasks aren't going anywhere
+that disables "cpuset.sched_load_balance" as those tasks aren't going anywhere
else anyway.
There is an impedance mismatch here, between cpusets and sched domains.
@@ -443,19 +443,19 @@ overlap and each CPU is in at most one sched domain.
It is necessary for sched domains to be flat because load balancing
across partially overlapping sets of CPUs would risk unstable dynamics
that would be beyond our understanding. So if each of two partially
-overlapping cpusets enables the flag 'sched_load_balance', then we
+overlapping cpusets enables the flag 'cpuset.sched_load_balance', then we
form a single sched domain that is a superset of both. We won't move
a task to a CPU outside it cpuset, but the scheduler load balancing
code might waste some compute cycles considering that possibility.
This mismatch is why there is not a simple one-to-one relation
-between which cpusets have the flag "sched_load_balance" enabled,
+between which cpusets have the flag "cpuset.sched_load_balance" enabled,
and the sched domain configuration. If a cpuset enables the flag, it
will get balancing across all its CPUs, but if it disables the flag,
it will only be assured of no load balancing if no other overlapping
cpuset enables the flag.
-If two cpusets have partially overlapping 'cpus' allowed, and only
+If two cpusets have partially overlapping 'cpuset.cpus' allowed, and only
one of them has this flag enabled, then the other may find its
tasks only partially load balanced, just on the overlapping CPUs.
This is just the general case of the top_cpuset example given a few
@@ -468,23 +468,23 @@ load balancing to the other CPUs.
1.7.1 sched_load_balance implementation details.
------------------------------------------------
-The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary
+The per-cpuset flag 'cpuset.sched_load_balance' defaults to enabled (contrary
to most cpuset flags.) When enabled for a cpuset, the kernel will
ensure that it can load balance across all the CPUs in that cpuset
(makes sure that all the CPUs in the cpus_allowed of that cpuset are
in the same sched domain.)
-If two overlapping cpusets both have 'sched_load_balance' enabled,
+If two overlapping cpusets both have 'cpuset.sched_load_balance' enabled,
then they will be (must be) both in the same sched domain.
-If, as is the default, the top cpuset has 'sched_load_balance' enabled,
+If, as is the default, the top cpuset has 'cpuset.sched_load_balance' enabled,
then by the above that means there is a single sched domain covering
the whole system, regardless of any other cpuset settings.
The kernel commits to user space that it will avoid load balancing
where it can. It will pick as fine a granularity partition of sched
domains as it can while still providing load balancing for any set
-of CPUs allowed to a cpuset having 'sched_load_balance' enabled.
+of CPUs allowed to a cpuset having 'cpuset.sched_load_balance' enabled.
The internal kernel cpuset to scheduler interface passes from the
cpuset code to the scheduler code a partition of the load balanced
@@ -495,9 +495,9 @@ all the CPUs that must be load balanced.
The cpuset code builds a new such partition and passes it to the
scheduler sched domain setup code, to have the sched domains rebuilt
as necessary, whenever:
- - the 'sched_load_balance' flag of a cpuset with non-empty CPUs changes,
+ - the 'cpuset.sched_load_balance' flag of a cpuset with non-empty CPUs changes,
- or CPUs come or go from a cpuset with this flag enabled,
- - or 'sched_relax_domain_level' value of a cpuset with non-empty CPUs
+ - or 'cpuset.sched_relax_domain_level' value of a cpuset with non-empty CPUs
and with this flag enabled changes,
- or a cpuset with non-empty CPUs and with this flag enabled is removed,
- or a cpu is offlined/onlined.
@@ -542,7 +542,7 @@ As the result, task B on CPU X need to wait task A or wait load balance
on the next tick. For some applications in special situation, waiting
1 tick may be too long.
-The 'sched_relax_domain_level' file allows you to request changing
+The 'cpuset.sched_relax_domain_level' file allows you to request changing
this searching range as you like. This file takes int value which
indicates size of searching range in levels ideally as follows,
otherwise initial value -1 that indicates the cpuset has no request.
@@ -559,8 +559,8 @@ The system default is architecture dependent. The system default
can be changed using the relax_domain_level= boot parameter.
This file is per-cpuset and affect the sched domain where the cpuset
-belongs to. Therefore if the flag 'sched_load_balance' of a cpuset
-is disabled, then 'sched_relax_domain_level' have no effect since
+belongs to. Therefore if the flag 'cpuset.sched_load_balance' of a cpuset
+is disabled, then 'cpuset.sched_relax_domain_level' have no effect since
there is no sched domain belonging the cpuset.
If multiple cpusets are overlapping and hence they form a single sched
@@ -607,9 +607,9 @@ from one cpuset to another, then the kernel will adjust the tasks
memory placement, as above, the next time that the kernel attempts
to allocate a page of memory for that task.
-If a cpuset has its 'cpus' modified, then each task in that cpuset
+If a cpuset has its 'cpuset.cpus' modified, then each task in that cpuset
will have its allowed CPU placement changed immediately. Similarly,
-if a tasks pid is written to another cpusets 'tasks' file, then its
+if a tasks pid is written to another cpusets 'cpuset.tasks' file, then its
allowed CPU placement is changed immediately. If such a task had been
bound to some subset of its cpuset using the sched_setaffinity() call,
the task will be allowed to run on any CPU allowed in its new cpuset,
@@ -622,8 +622,8 @@ and the processor placement is updated immediately.
Normally, once a page is allocated (given a physical page
of main memory) then that page stays on whatever node it
was allocated, so long as it remains allocated, even if the
-cpusets memory placement policy 'mems' subsequently changes.
-If the cpuset flag file 'memory_migrate' is set true, then when
+cpusets memory placement policy 'cpuset.mems' subsequently changes.
+If the cpuset flag file 'cpuset.memory_migrate' is set true, then when
tasks are attached to that cpuset, any pages that task had
allocated to it on nodes in its previous cpuset are migrated
to the tasks new cpuset. The relative placement of the page within
@@ -631,12 +631,12 @@ the cpuset is preserved during these migration operations if possible.
For example if the page was on the second valid node of the prior cpuset
then the page will be placed on the second valid node of the new cpuset.
-Also if 'memory_migrate' is set true, then if that cpusets
-'mems' file is modified, pages allocated to tasks in that
-cpuset, that were on nodes in the previous setting of 'mems',
+Also if 'cpuset.memory_migrate' is set true, then if that cpusets
+'cpuset.mems' file is modified, pages allocated to tasks in that
+cpuset, that were on nodes in the previous setting of 'cpuset.mems',
will be moved to nodes in the new setting of 'mems.'
Pages that were not in the tasks prior cpuset, or in the cpusets
-prior 'mems' setting, will not be moved.
+prior 'cpuset.mems' setting, will not be moved.
There is an exception to the above. If hotplug functionality is used
to remove all the CPUs that are currently assigned to a cpuset,
@@ -678,8 +678,8 @@ and then start a subshell 'sh' in that cpuset:
cd /dev/cpuset
mkdir Charlie
cd Charlie
- /bin/echo 2-3 > cpus
- /bin/echo 1 > mems
+ /bin/echo 2-3 > cpuset.cpus
+ /bin/echo 1 > cpuset.mems
/bin/echo $$ > tasks
sh
# The subshell 'sh' is now running in cpuset Charlie
@@ -725,10 +725,13 @@ Now you want to do something with this cpuset.
In this directory you can find several files:
# ls
-cpu_exclusive memory_migrate mems tasks
-cpus memory_pressure notify_on_release
-mem_exclusive memory_spread_page sched_load_balance
-mem_hardwall memory_spread_slab sched_relax_domain_level
+cpuset.cpu_exclusive cpuset.memory_spread_slab
+cpuset.cpus cpuset.mems
+cpuset.mem_exclusive cpuset.sched_load_balance
+cpuset.mem_hardwall cpuset.sched_relax_domain_level
+cpuset.memory_migrate notify_on_release
+cpuset.memory_pressure tasks
+cpuset.memory_spread_page
Reading them will give you information about the state of this cpuset:
the CPUs and Memory Nodes it can use, the processes that are using
@@ -736,13 +739,13 @@ it, its properties. By writing to these files you can manipulate
the cpuset.
Set some flags:
-# /bin/echo 1 > cpu_exclusive
+# /bin/echo 1 > cpuset.cpu_exclusive
Add some cpus:
-# /bin/echo 0-7 > cpus
+# /bin/echo 0-7 > cpuset.cpus
Add some mems:
-# /bin/echo 0-7 > mems
+# /bin/echo 0-7 > cpuset.mems
Now attach your shell to this cpuset:
# /bin/echo $$ > tasks
@@ -774,28 +777,28 @@ echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent
This is the syntax to use when writing in the cpus or mems files
in cpuset directories:
-# /bin/echo 1-4 > cpus -> set cpus list to cpus 1,2,3,4
-# /bin/echo 1,2,3,4 > cpus -> set cpus list to cpus 1,2,3,4
+# /bin/echo 1-4 > cpuset.cpus -> set cpus list to cpus 1,2,3,4
+# /bin/echo 1,2,3,4 > cpuset.cpus -> set cpus list to cpus 1,2,3,4
To add a CPU to a cpuset, write the new list of CPUs including the
CPU to be added. To add 6 to the above cpuset:
-# /bin/echo 1-4,6 > cpus -> set cpus list to cpus 1,2,3,4,6
+# /bin/echo 1-4,6 > cpuset.cpus -> set cpus list to cpus 1,2,3,4,6
Similarly to remove a CPU from a cpuset, write the new list of CPUs
without the CPU to be removed.
To remove all the CPUs:
-# /bin/echo "" > cpus -> clear cpus list
+# /bin/echo "" > cpuset.cpus -> clear cpus list
2.3 Setting flags
-----------------
The syntax is very simple:
-# /bin/echo 1 > cpu_exclusive -> set flag 'cpu_exclusive'
-# /bin/echo 0 > cpu_exclusive -> unset flag 'cpu_exclusive'
+# /bin/echo 1 > cpuset.cpu_exclusive -> set flag 'cpuset.cpu_exclusive'
+# /bin/echo 0 > cpuset.cpu_exclusive -> unset flag 'cpuset.cpu_exclusive'
2.4 Attaching processes
-----------------------
diff --git a/Documentation/cgroups/memcg_test.txt b/Documentation/cgroups/memcg_test.txt
index 72db89ed060..f7f68b2ac19 100644
--- a/Documentation/cgroups/memcg_test.txt
+++ b/Documentation/cgroups/memcg_test.txt
@@ -1,6 +1,6 @@
Memory Resource Controller(Memcg) Implementation Memo.
-Last Updated: 2009/1/20
-Base Kernel Version: based on 2.6.29-rc2.
+Last Updated: 2010/2
+Base Kernel Version: based on 2.6.33-rc7-mm(candidate for 34).
Because VM is getting complex (one of reasons is memcg...), memcg's behavior
is complex. This is a document for memcg's internal behavior.
@@ -337,7 +337,7 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y.
race and lock dependency with other cgroup subsystems.
example)
- # mount -t cgroup none /cgroup -t cpuset,memory,cpu,devices
+ # mount -t cgroup none /cgroup -o cpuset,memory,cpu,devices
and do task move, mkdir, rmdir etc...under this.
@@ -348,7 +348,7 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y.
For example, test like following is good.
(Shell-A)
- # mount -t cgroup none /cgroup -t memory
+ # mount -t cgroup none /cgroup -o memory
# mkdir /cgroup/test
# echo 40M > /cgroup/test/memory.limit_in_bytes
# echo 0 > /cgroup/test/tasks
@@ -378,3 +378,42 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y.
#echo 50M > memory.limit_in_bytes
#echo 50M > memory.memsw.limit_in_bytes
run 51M of malloc
+
+ 9.9 Move charges at task migration
+ Charges associated with a task can be moved along with task migration.
+
+ (Shell-A)
+ #mkdir /cgroup/A
+ #echo $$ >/cgroup/A/tasks
+ run some programs which uses some amount of memory in /cgroup/A.
+
+ (Shell-B)
+ #mkdir /cgroup/B
+ #echo 1 >/cgroup/B/memory.move_charge_at_immigrate
+ #echo "pid of the program running in group A" >/cgroup/B/tasks
+
+ You can see charges have been moved by reading *.usage_in_bytes or
+ memory.stat of both A and B.
+ See 8.2 of Documentation/cgroups/memory.txt to see what value should be
+ written to move_charge_at_immigrate.
+
+ 9.10 Memory thresholds
+ Memory controler implements memory thresholds using cgroups notification
+ API. You can use Documentation/cgroups/cgroup_event_listener.c to test
+ it.
+
+ (Shell-A) Create cgroup and run event listener
+ # mkdir /cgroup/A
+ # ./cgroup_event_listener /cgroup/A/memory.usage_in_bytes 5M
+
+ (Shell-B) Add task to cgroup and try to allocate and free memory
+ # echo $$ >/cgroup/A/tasks
+ # a="$(dd if=/dev/zero bs=1M count=10)"
+ # a=
+
+ You will see message from cgroup_event_listener every time you cross
+ the thresholds.
+
+ Use /cgroup/A/memory.memsw.usage_in_bytes to test memsw thresholds.
+
+ It's good idea to test root cgroup as well.
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index b871f2552b4..3a6aecd078b 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -182,6 +182,8 @@ list.
NOTE: Reclaim does not work for the root cgroup, since we cannot set any
limits on the root cgroup.
+Note2: When panic_on_oom is set to "2", the whole system will panic.
+
2. Locking
The memory controller uses the following hierarchy
@@ -262,10 +264,12 @@ some of the pages cached in the cgroup (page cache pages).
4.2 Task migration
When a task migrates from one cgroup to another, it's charge is not
-carried forward. The pages allocated from the original cgroup still
+carried forward by default. The pages allocated from the original cgroup still
remain charged to it, the charge is dropped when the page is freed or
reclaimed.
+Note: You can move charges of a task along with task migration. See 8.
+
4.3 Removing a cgroup
A cgroup can be removed by rmdir, but as discussed in sections 4.1 and 4.2, a
@@ -336,7 +340,7 @@ Note:
5.3 swappiness
Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
- Following cgroups' swapiness can't be changed.
+ Following cgroups' swappiness can't be changed.
- root cgroup (uses /proc/sys/vm/swappiness).
- a cgroup which uses hierarchy and it has child cgroup.
- a cgroup which uses hierarchy and not the root of hierarchy.
@@ -377,7 +381,8 @@ The feature can be disabled by
NOTE1: Enabling/disabling will fail if the cgroup already has other
cgroups created below it.
-NOTE2: This feature can be enabled/disabled per subtree.
+NOTE2: When panic_on_oom is set to "2", the whole system will panic in
+case of an oom event in any cgroup.
7. Soft limits
@@ -414,7 +419,76 @@ NOTE1: Soft limits take effect over a long period of time, since they involve
NOTE2: It is recommended to set the soft limit always below the hard limit,
otherwise the hard limit will take precedence.
-8. TODO
+8. Move charges at task migration
+
+Users can move charges associated with a task along with task migration, that
+is, uncharge task's pages from the old cgroup and charge them to the new cgroup.
+This feature is not supported in !CONFIG_MMU environments because of lack of
+page tables.
+
+8.1 Interface
+
+This feature is disabled by default. It can be enabled(and disabled again) by
+writing to memory.move_charge_at_immigrate of the destination cgroup.
+
+If you want to enable it:
+
+# echo (some positive value) > memory.move_charge_at_immigrate
+
+Note: Each bits of move_charge_at_immigrate has its own meaning about what type
+ of charges should be moved. See 8.2 for details.
+Note: Charges are moved only when you move mm->owner, IOW, a leader of a thread
+ group.
+Note: If we cannot find enough space for the task in the destination cgroup, we
+ try to make space by reclaiming memory. Task migration may fail if we
+ cannot make enough space.
+Note: It can take several seconds if you move charges in giga bytes order.
+
+And if you want disable it again:
+
+# echo 0 > memory.move_charge_at_immigrate
+
+8.2 Type of charges which can be move
+
+Each bits of move_charge_at_immigrate has its own meaning about what type of
+charges should be moved.
+
+ bit | what type of charges would be moved ?
+ -----+------------------------------------------------------------------------
+ 0 | A charge of an anonymous page(or swap of it) used by the target task.
+ | Those pages and swaps must be used only by the target task. You must
+ | enable Swap Extension(see 2.4) to enable move of swap charges.
+
+Note: Those pages and swaps must be charged to the old cgroup.
+Note: More type of pages(e.g. file cache, shmem,) will be supported by other
+ bits in future.
+
+8.3 TODO
+
+- Add support for other types of pages(e.g. file cache, shmem, etc.).
+- Implement madvise(2) to let users decide the vma to be moved or not to be
+ moved.
+- All of moving charge operations are done under cgroup_mutex. It's not good
+ behavior to hold the mutex too long, so we may need some trick.
+
+9. Memory thresholds
+
+Memory controler implements memory thresholds using cgroups notification
+API (see cgroups.txt). It allows to register multiple memory and memsw
+thresholds and gets notifications when it crosses.
+
+To register a threshold application need:
+ - create an eventfd using eventfd(2);
+ - open memory.usage_in_bytes or memory.memsw.usage_in_bytes;
+ - write string like "<event_fd> <memory.usage_in_bytes> <threshold>" to
+ cgroup.event_control.
+
+Application will be notified through eventfd when memory usage crosses
+threshold in any direction.
+
+It's applicable for root and non-root cgroup.
+
+10. TODO
1. Add support for accounting huge pages (as a separate controller)
2. Make per-cgroup scanner reclaim not-shared pages first
diff --git a/Documentation/circular-buffers.txt b/Documentation/circular-buffers.txt
new file mode 100644
index 00000000000..8117e5bf606
--- /dev/null
+++ b/Documentation/circular-buffers.txt
@@ -0,0 +1,234 @@
+ ================
+ CIRCULAR BUFFERS
+ ================
+
+By: David Howells <dhowells@redhat.com>
+ Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+
+
+Linux provides a number of features that can be used to implement circular
+buffering. There are two sets of such features:
+
+ (1) Convenience functions for determining information about power-of-2 sized
+ buffers.
+
+ (2) Memory barriers for when the producer and the consumer of objects in the
+ buffer don't want to share a lock.
+
+To use these facilities, as discussed below, there needs to be just one
+producer and just one consumer. It is possible to handle multiple producers by
+serialising them, and to handle multiple consumers by serialising them.
+
+
+Contents:
+
+ (*) What is a circular buffer?
+
+ (*) Measuring power-of-2 buffers.
+
+ (*) Using memory barriers with circular buffers.
+ - The producer.
+ - The consumer.
+
+
+==========================
+WHAT IS A CIRCULAR BUFFER?
+==========================
+
+First of all, what is a circular buffer? A circular buffer is a buffer of
+fixed, finite size into which there are two indices:
+
+ (1) A 'head' index - the point at which the producer inserts items into the
+ buffer.
+
+ (2) A 'tail' index - the point at which the consumer finds the next item in
+ the buffer.
+
+Typically when the tail pointer is equal to the head pointer, the buffer is
+empty; and the buffer is full when the head pointer is one less than the tail
+pointer.
+
+The head index is incremented when items are added, and the tail index when
+items are removed. The tail index should never jump the head index, and both
+indices should be wrapped to 0 when they reach the end of the buffer, thus
+allowing an infinite amount of data to flow through the buffer.
+
+Typically, items will all be of the same unit size, but this isn't strictly
+required to use the techniques below. The indices can be increased by more
+than 1 if multiple items or variable-sized items are to be included in the
+buffer, provided that neither index overtakes the other. The implementer must
+be careful, however, as a region more than one unit in size may wrap the end of
+the buffer and be broken into two segments.
+
+
+============================
+MEASURING POWER-OF-2 BUFFERS
+============================
+
+Calculation of the occupancy or the remaining capacity of an arbitrarily sized
+circular buffer would normally be a slow operation, requiring the use of a
+modulus (divide) instruction. However, if the buffer is of a power-of-2 size,
+then a much quicker bitwise-AND instruction can be used instead.
+
+Linux provides a set of macros for handling power-of-2 circular buffers. These
+can be made use of by:
+
+ #include <linux/circ_buf.h>
+
+The macros are:
+
+ (*) Measure the remaining capacity of a buffer:
+
+ CIRC_SPACE(head_index, tail_index, buffer_size);
+
+ This returns the amount of space left in the buffer[1] into which items
+ can be inserted.
+
+
+ (*) Measure the maximum consecutive immediate space in a buffer:
+
+ CIRC_SPACE_TO_END(head_index, tail_index, buffer_size);
+
+ This returns the amount of consecutive space left in the buffer[1] into
+ which items can be immediately inserted without having to wrap back to the
+ beginning of the buffer.
+
+
+ (*) Measure the occupancy of a buffer:
+
+ CIRC_CNT(head_index, tail_index, buffer_size);
+
+ This returns the number of items currently occupying a buffer[2].
+
+
+ (*) Measure the non-wrapping occupancy of a buffer:
+
+ CIRC_CNT_TO_END(head_index, tail_index, buffer_size);
+
+ This returns the number of consecutive items[2] that can be extracted from
+ the buffer without having to wrap back to the beginning of the buffer.
+
+
+Each of these macros will nominally return a value between 0 and buffer_size-1,
+however:
+
+ [1] CIRC_SPACE*() are intended to be used in the producer. To the producer
+ they will return a lower bound as the producer controls the head index,
+ but the consumer may still be depleting the buffer on another CPU and
+ moving the tail index.
+
+ To the consumer it will show an upper bound as the producer may be busy
+ depleting the space.
+
+ [2] CIRC_CNT*() are intended to be used in the consumer. To the consumer they
+ will return a lower bound as the consumer controls the tail index, but the
+ producer may still be filling the buffer on another CPU and moving the
+ head index.
+
+ To the producer it will show an upper bound as the consumer may be busy
+ emptying the buffer.
+
+ [3] To a third party, the order in which the writes to the indices by the
+ producer and consumer become visible cannot be guaranteed as they are
+ independent and may be made on different CPUs - so the result in such a
+ situation will merely be a guess, and may even be negative.
+
+
+===========================================
+USING MEMORY BARRIERS WITH CIRCULAR BUFFERS
+===========================================
+
+By using memory barriers in conjunction with circular buffers, you can avoid
+the need to:
+
+ (1) use a single lock to govern access to both ends of the buffer, thus
+ allowing the buffer to be filled and emptied at the same time; and
+
+ (2) use atomic counter operations.
+
+There are two sides to this: the producer that fills the buffer, and the
+consumer that empties it. Only one thing should be filling a buffer at any one
+time, and only one thing should be emptying a buffer at any one time, but the
+two sides can operate simultaneously.
+
+
+THE PRODUCER
+------------
+
+The producer will look something like this:
+
+ spin_lock(&producer_lock);
+
+ unsigned long head = buffer->head;
+ unsigned long tail = ACCESS_ONCE(buffer->tail);
+
+ if (CIRC_SPACE(head, tail, buffer->size) >= 1) {
+ /* insert one item into the buffer */
+ struct item *item = buffer[head];
+
+ produce_item(item);
+
+ smp_wmb(); /* commit the item before incrementing the head */
+
+ buffer->head = (head + 1) & (buffer->size - 1);
+
+ /* wake_up() will make sure that the head is committed before
+ * waking anyone up */
+ wake_up(consumer);
+ }
+
+ spin_unlock(&producer_lock);
+
+This will instruct the CPU that the contents of the new item must be written
+before the head index makes it available to the consumer and then instructs the
+CPU that the revised head index must be written before the consumer is woken.
+
+Note that wake_up() doesn't have to be the exact mechanism used, but whatever
+is used must guarantee a (write) memory barrier between the update of the head
+index and the change of state of the consumer, if a change of state occurs.
+
+
+THE CONSUMER
+------------
+
+The consumer will look something like this:
+
+ spin_lock(&consumer_lock);
+
+ unsigned long head = ACCESS_ONCE(buffer->head);
+ unsigned long tail = buffer->tail;
+
+ if (CIRC_CNT(head, tail, buffer->size) >= 1) {
+ /* read index before reading contents at that index */
+ smp_read_barrier_depends();
+
+ /* extract one item from the buffer */
+ struct item *item = buffer[tail];
+
+ consume_item(item);
+
+ smp_mb(); /* finish reading descriptor before incrementing tail */
+
+ buffer->tail = (tail + 1) & (buffer->size - 1);
+ }
+
+ spin_unlock(&consumer_lock);
+
+This will instruct the CPU to make sure the index is up to date before reading
+the new item, and then it shall make sure the CPU has finished reading the item
+before it writes the new tail pointer, which will erase the item.
+
+
+Note the use of ACCESS_ONCE() in both algorithms to read the opposition index.
+This prevents the compiler from discarding and reloading its cached value -
+which some compilers will do across smp_read_barrier_depends(). This isn't
+strictly needed if you can be sure that the opposition index will _only_ be
+used the once.
+
+
+===============
+FURTHER READING
+===============
+
+See also Documentation/memory-barriers.txt for a description of Linux's memory
+barrier facilities.
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
index b07add3467f..7764594778d 100644
--- a/Documentation/connector/cn_test.c
+++ b/Documentation/connector/cn_test.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/connector.h>
diff --git a/Documentation/console/console.txt b/Documentation/console/console.txt
index 877a1b26cc3..926cf1b5e63 100644
--- a/Documentation/console/console.txt
+++ b/Documentation/console/console.txt
@@ -74,7 +74,7 @@ driver takes over the consoles vacated by the driver. Binding, on the other
hand, will bind the driver to the consoles that are currently occupied by a
system driver.
-NOTE1: Binding and binding must be selected in Kconfig. It's under:
+NOTE1: Binding and unbinding must be selected in Kconfig. It's under:
Device Drivers -> Character devices -> Support for binding and unbinding
console drivers
diff --git a/Documentation/cpu-freq/pcc-cpufreq.txt b/Documentation/cpu-freq/pcc-cpufreq.txt
new file mode 100644
index 00000000000..9e3c3b33514
--- /dev/null
+++ b/Documentation/cpu-freq/pcc-cpufreq.txt
@@ -0,0 +1,207 @@
+/*
+ * pcc-cpufreq.txt - PCC interface documentation
+ *
+ * Copyright (C) 2009 Red Hat, Matthew Garrett <mjg@redhat.com>
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ * Nagananda Chumbalkar <nagananda.chumbalkar@hp.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, GOOD TITLE or NON
+ * INFRINGEMENT. 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+
+ Processor Clocking Control Driver
+ ---------------------------------
+
+Contents:
+---------
+1. Introduction
+1.1 PCC interface
+1.1.1 Get Average Frequency
+1.1.2 Set Desired Frequency
+1.2 Platforms affected
+2. Driver and /sys details
+2.1 scaling_available_frequencies
+2.2 cpuinfo_transition_latency
+2.3 cpuinfo_cur_freq
+2.4 related_cpus
+3. Caveats
+
+1. Introduction:
+----------------
+Processor Clocking Control (PCC) is an interface between the platform
+firmware and OSPM. It is a mechanism for coordinating processor
+performance (ie: frequency) between the platform firmware and the OS.
+
+The PCC driver (pcc-cpufreq) allows OSPM to take advantage of the PCC
+interface.
+
+OS utilizes the PCC interface to inform platform firmware what frequency the
+OS wants for a logical processor. The platform firmware attempts to achieve
+the requested frequency. If the request for the target frequency could not be
+satisfied by platform firmware, then it usually means that power budget
+conditions are in place, and "power capping" is taking place.
+
+1.1 PCC interface:
+------------------
+The complete PCC specification is available here:
+http://www.acpica.org/download/Processor-Clocking-Control-v1p0.pdf
+
+PCC relies on a shared memory region that provides a channel for communication
+between the OS and platform firmware. PCC also implements a "doorbell" that
+is used by the OS to inform the platform firmware that a command has been
+sent.
+
+The ACPI PCCH() method is used to discover the location of the PCC shared
+memory region. The shared memory region header contains the "command" and
+"status" interface. PCCH() also contains details on how to access the platform
+doorbell.
+
+The following commands are supported by the PCC interface:
+* Get Average Frequency
+* Set Desired Frequency
+
+The ACPI PCCP() method is implemented for each logical processor and is
+used to discover the offsets for the input and output buffers in the shared
+memory region.
+
+When PCC mode is enabled, the platform will not expose processor performance
+or throttle states (_PSS, _TSS and related ACPI objects) to OSPM. Therefore,
+the native P-state driver (such as acpi-cpufreq for Intel, powernow-k8 for
+AMD) will not load.
+
+However, OSPM remains in control of policy. The governor (eg: "ondemand")
+computes the required performance for each processor based on server workload.
+The PCC driver fills in the command interface, and the input buffer and
+communicates the request to the platform firmware. The platform firmware is
+responsible for delivering the requested performance.
+
+Each PCC command is "global" in scope and can affect all the logical CPUs in
+the system. Therefore, PCC is capable of performing "group" updates. With PCC
+the OS is capable of getting/setting the frequency of all the logical CPUs in
+the system with a single call to the BIOS.
+
+1.1.1 Get Average Frequency:
+----------------------------
+This command is used by the OSPM to query the running frequency of the
+processor since the last time this command was completed. The output buffer
+indicates the average unhalted frequency of the logical processor expressed as
+a percentage of the nominal (ie: maximum) CPU frequency. The output buffer
+also signifies if the CPU frequency is limited by a power budget condition.
+
+1.1.2 Set Desired Frequency:
+----------------------------
+This command is used by the OSPM to communicate to the platform firmware the
+desired frequency for a logical processor. The output buffer is currently
+ignored by OSPM. The next invocation of "Get Average Frequency" will inform
+OSPM if the desired frequency was achieved or not.
+
+1.2 Platforms affected:
+-----------------------
+The PCC driver will load on any system where the platform firmware:
+* supports the PCC interface, and the associated PCCH() and PCCP() methods
+* assumes responsibility for managing the hardware clocking controls in order
+to deliver the requested processor performance
+
+Currently, certain HP ProLiant platforms implement the PCC interface. On those
+platforms PCC is the "default" choice.
+
+However, it is possible to disable this interface via a BIOS setting. In
+such an instance, as is also the case on platforms where the PCC interface
+is not implemented, the PCC driver will fail to load silently.
+
+2. Driver and /sys details:
+---------------------------
+When the driver loads, it merely prints the lowest and the highest CPU
+frequencies supported by the platform firmware.
+
+The PCC driver loads with a message such as:
+pcc-cpufreq: (v1.00.00) driver loaded with frequency limits: 1600 MHz, 2933
+MHz
+
+This means that the OPSM can request the CPU to run at any frequency in
+between the limits (1600 MHz, and 2933 MHz) specified in the message.
+
+Internally, there is no need for the driver to convert the "target" frequency
+to a corresponding P-state.
+
+The VERSION number for the driver will be of the format v.xy.ab.
+eg: 1.00.02
+ ----- --
+ | |
+ | -- this will increase with bug fixes/enhancements to the driver
+ |-- this is the version of the PCC specification the driver adheres to
+
+
+The following is a brief discussion on some of the fields exported via the
+/sys filesystem and how their values are affected by the PCC driver:
+
+2.1 scaling_available_frequencies:
+----------------------------------
+scaling_available_frequencies is not created in /sys. No intermediate
+frequencies need to be listed because the BIOS will try to achieve any
+frequency, within limits, requested by the governor. A frequency does not have
+to be strictly associated with a P-state.
+
+2.2 cpuinfo_transition_latency:
+-------------------------------
+The cpuinfo_transition_latency field is 0. The PCC specification does
+not include a field to expose this value currently.
+
+2.3 cpuinfo_cur_freq:
+---------------------
+A) Often cpuinfo_cur_freq will show a value different than what is declared
+in the scaling_available_frequencies or scaling_cur_freq, or scaling_max_freq.
+This is due to "turbo boost" available on recent Intel processors. If certain
+conditions are met the BIOS can achieve a slightly higher speed than requested
+by OSPM. An example:
+
+scaling_cur_freq : 2933000
+cpuinfo_cur_freq : 3196000
+
+B) There is a round-off error associated with the cpuinfo_cur_freq value.
+Since the driver obtains the current frequency as a "percentage" (%) of the
+nominal frequency from the BIOS, sometimes, the values displayed by
+scaling_cur_freq and cpuinfo_cur_freq may not match. An example:
+
+scaling_cur_freq : 1600000
+cpuinfo_cur_freq : 1583000
+
+In this example, the nominal frequency is 2933 MHz. The driver obtains the
+current frequency, cpuinfo_cur_freq, as 54% of the nominal frequency:
+
+ 54% of 2933 MHz = 1583 MHz
+
+Nominal frequency is the maximum frequency of the processor, and it usually
+corresponds to the frequency of the P0 P-state.
+
+2.4 related_cpus:
+-----------------
+The related_cpus field is identical to affected_cpus.
+
+affected_cpus : 4
+related_cpus : 4
+
+Currently, the PCC driver does not evaluate _PSD. The platforms that support
+PCC do not implement SW_ALL. So OSPM doesn't need to perform any coordination
+to ensure that the same frequency is requested of all dependent CPUs.
+
+3. Caveats:
+-----------
+The "cpufreq_stats" module in its present form cannot be loaded and
+expected to work with the PCC driver. Since the "cpufreq_stats" module
+provides information wrt each P-state, it is not applicable to the PCC driver.
diff --git a/Documentation/device-mapper/snapshot.txt b/Documentation/device-mapper/snapshot.txt
index e3a77b21513..0d5bc46dc16 100644
--- a/Documentation/device-mapper/snapshot.txt
+++ b/Documentation/device-mapper/snapshot.txt
@@ -122,3 +122,47 @@ volumeGroup-base: 0 2097152 snapshot-merge 254:11 254:12 P 16
brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
brw------- 1 root root 254, 12 29 ago 18:16 /dev/mapper/volumeGroup-base-cow
brw------- 1 root root 254, 10 29 ago 18:16 /dev/mapper/volumeGroup-base
+
+
+How to determine when a merging is complete
+===========================================
+The snapshot-merge and snapshot status lines end with:
+ <sectors_allocated>/<total_sectors> <metadata_sectors>
+
+Both <sectors_allocated> and <total_sectors> include both data and metadata.
+During merging, the number of sectors allocated gets smaller and
+smaller. Merging has finished when the number of sectors holding data
+is zero, in other words <sectors_allocated> == <metadata_sectors>.
+
+Here is a practical example (using a hybrid of lvm and dmsetup commands):
+
+# lvs
+ LV VG Attr LSize Origin Snap% Move Log Copy% Convert
+ base volumeGroup owi-a- 4.00g
+ snap volumeGroup swi-a- 1.00g base 18.97
+
+# dmsetup status volumeGroup-snap
+0 8388608 snapshot 397896/2097152 1560
+ ^^^^ metadata sectors
+
+# lvconvert --merge -b volumeGroup/snap
+ Merging of volume snap started.
+
+# lvs volumeGroup/snap
+ LV VG Attr LSize Origin Snap% Move Log Copy% Convert
+ base volumeGroup Owi-a- 4.00g 17.23
+
+# dmsetup status volumeGroup-base
+0 8388608 snapshot-merge 281688/2097152 1104
+
+# dmsetup status volumeGroup-base
+0 8388608 snapshot-merge 180480/2097152 712
+
+# dmsetup status volumeGroup-base
+0 8388608 snapshot-merge 16/2097152 16
+
+Merging has finished.
+
+# lvs
+ LV VG Attr LSize Origin Snap% Move Log Copy% Convert
+ base volumeGroup owi-a- 4.00g
diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.txt
index 2e2c2ea90ce..41f41632ee5 100644
--- a/Documentation/driver-model/platform.txt
+++ b/Documentation/driver-model/platform.txt
@@ -192,7 +192,7 @@ command line. This will execute all matching early_param() callbacks.
User specified early platform devices will be registered at this point.
For the early serial console case the user can specify port on the
kernel command line as "earlyprintk=serial.0" where "earlyprintk" is
-the class string, "serial" is the name of the platfrom driver and
+the class string, "serial" is the name of the platform driver and
0 is the platform device id. If the id is -1 then the dot and the
id can be omitted.
diff --git a/Documentation/eisa.txt b/Documentation/eisa.txt
index 60e361ba08c..f297fc1202a 100644
--- a/Documentation/eisa.txt
+++ b/Documentation/eisa.txt
@@ -171,7 +171,7 @@ device.
virtual_root.force_probe :
Force the probing code to probe EISA slots even when it cannot find an
-EISA compliant mainboard (nothing appears on slot 0). Defaultd to 0
+EISA compliant mainboard (nothing appears on slot 0). Defaults to 0
(don't force), and set to 1 (force probing) when either
CONFIG_ALPHA_JENSEN or CONFIG_EISA_VLB_PRIMING are set.
diff --git a/Documentation/email-clients.txt b/Documentation/email-clients.txt
index a618efab7b1..945ff3fda43 100644
--- a/Documentation/email-clients.txt
+++ b/Documentation/email-clients.txt
@@ -216,26 +216,14 @@ Works. Use "Insert file..." or external editor.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Gmail (Web GUI)
-If you just have to use Gmail to send patches, it CAN be made to work. It
-requires a bit of external help, though.
-
-The first problem is that Gmail converts tabs to spaces. This will
-totally break your patches. To prevent this, you have to use a different
-editor. There is a firefox extension called "ViewSourceWith"
-(https://addons.mozilla.org/en-US/firefox/addon/394) which allows you to
-edit any text box in the editor of your choice. Configure it to launch
-your favorite editor. When you want to send a patch, use this technique.
-Once you have crafted your messsage + patch, save and exit the editor,
-which should reload the Gmail edit box. GMAIL WILL PRESERVE THE TABS.
-Hoorah. Apparently you can cut-n-paste literal tabs, but Gmail will
-convert those to spaces upon sending!
-
-The second problem is that Gmail converts tabs to spaces on replies. If
-you reply to a patch, don't expect to be able to apply it as a patch.
-
-The last problem is that Gmail will base64-encode any message that has a
-non-ASCII character. That includes things like European names. Be aware.
-
-Gmail is not convenient for lkml patches, but CAN be made to work.
+Does not work for sending patches.
+
+Gmail web client converts tabs to spaces automatically.
+
+At the same time it wraps lines every 78 chars with CRLF style line breaks
+although tab2space problem can be solved with external editor.
+
+Another problem is that Gmail will base64-encode any message that has a
+non-ASCII character. That includes things like European names.
###
diff --git a/Documentation/fault-injection/provoke-crashes.txt b/Documentation/fault-injection/provoke-crashes.txt
new file mode 100644
index 00000000000..7a9d3d81525
--- /dev/null
+++ b/Documentation/fault-injection/provoke-crashes.txt
@@ -0,0 +1,38 @@
+The lkdtm module provides an interface to crash or injure the kernel at
+predefined crashpoints to evaluate the reliability of crash dumps obtained
+using different dumping solutions. The module uses KPROBEs to instrument
+crashing points, but can also crash the kernel directly without KRPOBE
+support.
+
+
+You can provide the way either through module arguments when inserting
+the module, or through a debugfs interface.
+
+Usage: insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
+ [cpoint_count={>0}]
+
+ recur_count : Recursion level for the stack overflow test. Default is 10.
+
+ cpoint_name : Crash point where the kernel is to be crashed. It can be
+ one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
+ FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
+ IDE_CORE_CP, DIRECT
+
+ cpoint_type : Indicates the action to be taken on hitting the crash point.
+ It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW,
+ CORRUPT_STACK, UNALIGNED_LOAD_STORE_WRITE, OVERWRITE_ALLOCATION,
+ WRITE_AFTER_FREE,
+
+ cpoint_count : Indicates the number of times the crash point is to be hit
+ to trigger an action. The default is 10.
+
+You can also induce failures by mounting debugfs and writing the type to
+<mountpoint>/provoke-crash/<crashpoint>. E.g.,
+
+ mount -t debugfs debugfs /mnt
+ echo EXCEPTION > /mnt/provoke-crash/INT_HARDWARE_ENTRY
+
+
+A special file is `DIRECT' which will induce the crash directly without
+KPROBE instrumentation. This mode is the only one available when the module
+is built on a kernel without KPROBEs support.
diff --git a/Documentation/fb/efifb.txt b/Documentation/fb/efifb.txt
new file mode 100644
index 00000000000..a59916c29b3
--- /dev/null
+++ b/Documentation/fb/efifb.txt
@@ -0,0 +1,31 @@
+
+What is efifb?
+===============
+
+This is a generic EFI platform driver for Intel based Apple computers.
+efifb is only for EFI booted Intel Macs.
+
+Supported Hardware
+==================
+
+iMac 17"/20"
+Macbook
+Macbook Pro 15"/17"
+MacMini
+
+How to use it?
+==============
+
+efifb does not have any kind of autodetection of your machine.
+You have to add the following kernel parameters in your elilo.conf:
+ Macbook :
+ video=efifb:macbook
+ MacMini :
+ video=efifb:mini
+ Macbook Pro 15", iMac 17" :
+ video=efifb:i17
+ Macbook Pro 17", iMac 20" :
+ video=efifb:i20
+
+--
+Edgar Hucek <gimli@dark-green.com>
diff --git a/Documentation/fb/imacfb.txt b/Documentation/fb/imacfb.txt
deleted file mode 100644
index 316ec9bb7de..00000000000
--- a/Documentation/fb/imacfb.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-
-What is imacfb?
-===============
-
-This is a generic EFI platform driver for Intel based Apple computers.
-Imacfb is only for EFI booted Intel Macs.
-
-Supported Hardware
-==================
-
-iMac 17"/20"
-Macbook
-Macbook Pro 15"/17"
-MacMini
-
-How to use it?
-==============
-
-Imacfb does not have any kind of autodetection of your machine.
-You have to add the following kernel parameters in your elilo.conf:
- Macbook :
- video=imacfb:macbook
- MacMini :
- video=imacfb:mini
- Macbook Pro 15", iMac 17" :
- video=imacfb:i17
- Macbook Pro 17", iMac 20" :
- video=imacfb:i20
-
---
-Edgar Hucek <gimli@dark-green.com>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 03497909539..ed511af0f79 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -449,12 +449,6 @@ Who: Alok N Kataria <akataria@vmware.com>
----------------------------
-What: adt7473 hardware monitoring driver
-When: February 2010
-Why: Obsoleted by the adt7475 driver.
-Who: Jean Delvare <khali@linux-fr.org>
-
----------------------------
What: Support for lcd_switch and display_get in asus-laptop driver
When: March 2010
Why: These two features use non-standard interfaces. There are the
@@ -556,3 +550,42 @@ Why: udev fully replaces this special file system that only contains CAPI
NCCI TTY device nodes. User space (pppdcapiplugin) works without
noticing the difference.
Who: Jan Kiszka <jan.kiszka@web.de>
+
+----------------------------
+
+What: KVM memory aliases support
+When: July 2010
+Why: Memory aliasing support is used for speeding up guest vga access
+ through the vga windows.
+
+ Modern userspace no longer uses this feature, so it's just bitrotted
+ code and can be removed with no impact.
+Who: Avi Kivity <avi@redhat.com>
+
+----------------------------
+
+What: KVM kernel-allocated memory slots
+When: July 2010
+Why: Since 2.6.25, kvm supports user-allocated memory slots, which are
+ much more flexible than kernel-allocated slots. All current userspace
+ supports the newer interface and this code can be removed with no
+ impact.
+Who: Avi Kivity <avi@redhat.com>
+
+----------------------------
+
+What: KVM paravirt mmu host support
+When: January 2011
+Why: The paravirt mmu host support is slower than non-paravirt mmu, both
+ on newer and older hardware. It is already not exposed to the guest,
+ and kept only for live migration purposes.
+Who: Avi Kivity <avi@redhat.com>
+
+----------------------------
+
+What: "acpi=ht" boot option
+When: 2.6.35
+Why: Useful in 2003, implementation is a hack.
+ Generally invoked by accident today.
+ Seen as doing more harm than good.
+Who: Len Brown <len.brown@intel.com>
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index 875d49696b6..4303614b5ad 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -16,6 +16,8 @@ befs.txt
- information about the BeOS filesystem for Linux.
bfs.txt
- info for the SCO UnixWare Boot Filesystem (BFS).
+ceph.txt
+ - info for the Ceph Distributed File System
cifs.txt
- description of the CIFS filesystem.
coda.txt
@@ -32,6 +34,8 @@ dlmfs.txt
- info on the userspace interface to the OCFS2 DLM.
dnotify.txt
- info about directory notification in Linux.
+dnotify_test.c
+ - example program for dnotify
ecryptfs.txt
- docs on eCryptfs: stacked cryptographic filesystem for Linux.
exofs.txt
@@ -62,6 +66,8 @@ jfs.txt
- info and mount options for the JFS filesystem.
locks.txt
- info on file locking implementations, flock() vs. fcntl(), etc.
+logfs.txt
+ - info on the LogFS flash filesystem.
mandatory-locking.txt
- info on the Linux implementation of Sys V mandatory file locking.
ncpfs.txt
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt
index 57e0b80a527..c0236e753bc 100644
--- a/Documentation/filesystems/9p.txt
+++ b/Documentation/filesystems/9p.txt
@@ -37,6 +37,15 @@ For Plan 9 From User Space applications (http://swtch.com/plan9)
mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER
+For server running on QEMU host with virtio transport:
+
+ mount -t 9p -o trans=virtio <mount_tag> /mnt/9
+
+where mount_tag is the tag associated by the server to each of the exported
+mount points. Each 9P export is seen by the client as a virtio device with an
+associated "mount_tag" property. Available mount tags can be
+seen by reading /sys/bus/virtio/drivers/9pnet_virtio/virtio<n>/mount_tag files.
+
OPTIONS
=======
@@ -47,7 +56,7 @@ OPTIONS
fd - used passed file descriptors for connection
(see rfdno and wfdno)
virtio - connect to the next virtio channel available
- (from lguest or KVM with trans_virtio module)
+ (from QEMU with trans_virtio module)
rdma - connect to a specified RDMA channel
uname=name user name to attempt mount as on the remote server. The
@@ -85,7 +94,12 @@ OPTIONS
port=n port to connect to on the remote server
- noextend force legacy mode (no 9p2000.u semantics)
+ noextend force legacy mode (no 9p2000.u or 9p2000.L semantics)
+
+ version=name Select 9P protocol version. Valid options are:
+ 9p2000 - Legacy mode (same as noextend)
+ 9p2000.u - Use 9P2000.u protocol
+ 9p2000.L - Use 9P2000.L protocol
dfltuid attempt to mount as a particular uid
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 18b9d0ca063..06bbbed7120 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -460,13 +460,6 @@ in sys_read() and friends.
--------------------------- dquot_operations -------------------------------
prototypes:
- int (*initialize) (struct inode *, int);
- int (*drop) (struct inode *);
- int (*alloc_space) (struct inode *, qsize_t, int);
- int (*alloc_inode) (const struct inode *, unsigned long);
- int (*free_space) (struct inode *, qsize_t);
- int (*free_inode) (const struct inode *, unsigned long);
- int (*transfer) (struct inode *, struct iattr *);
int (*write_dquot) (struct dquot *);
int (*acquire_dquot) (struct dquot *);
int (*release_dquot) (struct dquot *);
@@ -479,13 +472,6 @@ a proper locking wrt the filesystem and call the generic quota operations.
What filesystem should expect from the generic quota functions:
FS recursion Held locks when called
-initialize: yes maybe dqonoff_sem
-drop: yes -
-alloc_space: ->mark_dirty() -
-alloc_inode: ->mark_dirty() -
-free_space: ->mark_dirty() -
-free_inode: ->mark_dirty() -
-transfer: yes -
write_dquot: yes dqonoff_sem or dqptr_sem
acquire_dquot: yes dqonoff_sem or dqptr_sem
release_dquot: yes dqonoff_sem or dqptr_sem
@@ -495,10 +481,6 @@ write_info: yes dqonoff_sem
FS recursion means calling ->quota_read() and ->quota_write() from superblock
operations.
-->alloc_space(), ->alloc_inode(), ->free_space(), ->free_inode() are called
-only directly by the filesystem and do not call any fs functions only
-the ->mark_dirty() operation.
-
More details about quota locking can be found in fs/dquot.c.
--------------------------- vm_operations_struct -----------------------------
diff --git a/Documentation/filesystems/Makefile b/Documentation/filesystems/Makefile
new file mode 100644
index 00000000000..a5dd114da14
--- /dev/null
+++ b/Documentation/filesystems/Makefile
@@ -0,0 +1,8 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+# List of programs to build
+hostprogs-y := dnotify_test
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff --git a/Documentation/filesystems/ceph.txt b/Documentation/filesystems/ceph.txt
new file mode 100644
index 00000000000..0660c9f5dee
--- /dev/null
+++ b/Documentation/filesystems/ceph.txt
@@ -0,0 +1,140 @@
+Ceph Distributed File System
+============================
+
+Ceph is a distributed network file system designed to provide good
+performance, reliability, and scalability.
+
+Basic features include:
+
+ * POSIX semantics
+ * Seamless scaling from 1 to many thousands of nodes
+ * High availability and reliability. No single point of failure.
+ * N-way replication of data across storage nodes
+ * Fast recovery from node failures
+ * Automatic rebalancing of data on node addition/removal
+ * Easy deployment: most FS components are userspace daemons
+
+Also,
+ * Flexible snapshots (on any directory)
+ * Recursive accounting (nested files, directories, bytes)
+
+In contrast to cluster filesystems like GFS, OCFS2, and GPFS that rely
+on symmetric access by all clients to shared block devices, Ceph
+separates data and metadata management into independent server
+clusters, similar to Lustre. Unlike Lustre, however, metadata and
+storage nodes run entirely as user space daemons. Storage nodes
+utilize btrfs to store data objects, leveraging its advanced features
+(checksumming, metadata replication, etc.). File data is striped
+across storage nodes in large chunks to distribute workload and
+facilitate high throughputs. When storage nodes fail, data is
+re-replicated in a distributed fashion by the storage nodes themselves
+(with some minimal coordination from a cluster monitor), making the
+system extremely efficient and scalable.
+
+Metadata servers effectively form a large, consistent, distributed
+in-memory cache above the file namespace that is extremely scalable,
+dynamically redistributes metadata in response to workload changes,
+and can tolerate arbitrary (well, non-Byzantine) node failures. The
+metadata server takes a somewhat unconventional approach to metadata
+storage to significantly improve performance for common workloads. In
+particular, inodes with only a single link are embedded in
+directories, allowing entire directories of dentries and inodes to be
+loaded into its cache with a single I/O operation. The contents of
+extremely large directories can be fragmented and managed by
+independent metadata servers, allowing scalable concurrent access.
+
+The system offers automatic data rebalancing/migration when scaling
+from a small cluster of just a few nodes to many hundreds, without
+requiring an administrator carve the data set into static volumes or
+go through the tedious process of migrating data between servers.
+When the file system approaches full, new nodes can be easily added
+and things will "just work."
+
+Ceph includes flexible snapshot mechanism that allows a user to create
+a snapshot on any subdirectory (and its nested contents) in the
+system. Snapshot creation and deletion are as simple as 'mkdir
+.snap/foo' and 'rmdir .snap/foo'.
+
+Ceph also provides some recursive accounting on directories for nested
+files and bytes. That is, a 'getfattr -d foo' on any directory in the
+system will reveal the total number of nested regular files and
+subdirectories, and a summation of all nested file sizes. This makes
+the identification of large disk space consumers relatively quick, as
+no 'du' or similar recursive scan of the file system is required.
+
+
+Mount Syntax
+============
+
+The basic mount syntax is:
+
+ # mount -t ceph monip[:port][,monip2[:port]...]:/[subdir] mnt
+
+You only need to specify a single monitor, as the client will get the
+full list when it connects. (However, if the monitor you specify
+happens to be down, the mount won't succeed.) The port can be left
+off if the monitor is using the default. So if the monitor is at
+1.2.3.4,
+
+ # mount -t ceph 1.2.3.4:/ /mnt/ceph
+
+is sufficient. If /sbin/mount.ceph is installed, a hostname can be
+used instead of an IP address.
+
+
+
+Mount Options
+=============
+
+ ip=A.B.C.D[:N]
+ Specify the IP and/or port the client should bind to locally.
+ There is normally not much reason to do this. If the IP is not
+ specified, the client's IP address is determined by looking at the
+ address it's connection to the monitor originates from.
+
+ wsize=X
+ Specify the maximum write size in bytes. By default there is no
+ maximum. Ceph will normally size writes based on the file stripe
+ size.
+
+ rsize=X
+ Specify the maximum readahead.
+
+ mount_timeout=X
+ Specify the timeout value for mount (in seconds), in the case
+ of a non-responsive Ceph file system. The default is 30
+ seconds.
+
+ rbytes
+ When stat() is called on a directory, set st_size to 'rbytes',
+ the summation of file sizes over all files nested beneath that
+ directory. This is the default.
+
+ norbytes
+ When stat() is called on a directory, set st_size to the
+ number of entries in that directory.
+
+ nocrc
+ Disable CRC32C calculation for data writes. If set, the storage node
+ must rely on TCP's error correction to detect data corruption
+ in the data payload.
+
+ noasyncreaddir
+ Disable client's use its local cache to satisfy readdir
+ requests. (This does not change correctness; the client uses
+ cached metadata only when a lease or capability ensures it is
+ valid.)
+
+
+More Information
+================
+
+For more information on Ceph, see the home page at
+ http://ceph.newdream.net/
+
+The Linux kernel client source tree is available at
+ git://ceph.newdream.net/git/ceph-client.git
+ git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
+
+and the source for the full system is at
+ git://ceph.newdream.net/git/ceph.git
diff --git a/Documentation/filesystems/dnotify.txt b/Documentation/filesystems/dnotify.txt
index 9f5d338ddbb..6baf88f4685 100644
--- a/Documentation/filesystems/dnotify.txt
+++ b/Documentation/filesystems/dnotify.txt
@@ -62,38 +62,9 @@ disabled, fcntl(fd, F_NOTIFY, ...) will return -EINVAL.
Example
-------
+See Documentation/filesystems/dnotify_test.c for an example.
- #define _GNU_SOURCE /* needed to get the defines */
- #include <fcntl.h> /* in glibc 2.2 this has the needed
- values defined */
- #include <signal.h>
- #include <stdio.h>
- #include <unistd.h>
-
- static volatile int event_fd;
-
- static void handler(int sig, siginfo_t *si, void *data)
- {
- event_fd = si->si_fd;
- }
-
- int main(void)
- {
- struct sigaction act;
- int fd;
-
- act.sa_sigaction = handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
- sigaction(SIGRTMIN + 1, &act, NULL);
-
- fd = open(".", O_RDONLY);
- fcntl(fd, F_SETSIG, SIGRTMIN + 1);
- fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
- /* we will now be notified if any of the files
- in "." is modified or new files are created */
- while (1) {
- pause();
- printf("Got event on fd=%d\n", event_fd);
- }
- }
+NOTE
+----
+Beginning with Linux 2.6.13, dnotify has been replaced by inotify.
+See Documentation/filesystems/inotify.txt for more information on it.
diff --git a/Documentation/filesystems/dnotify_test.c b/Documentation/filesystems/dnotify_test.c
new file mode 100644
index 00000000000..8b37b4a1e18
--- /dev/null
+++ b/Documentation/filesystems/dnotify_test.c
@@ -0,0 +1,34 @@
+#define _GNU_SOURCE /* needed to get the defines */
+#include <fcntl.h> /* in glibc 2.2 this has the needed
+ values defined */
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static volatile int event_fd;
+
+static void handler(int sig, siginfo_t *si, void *data)
+{
+ event_fd = si->si_fd;
+}
+
+int main(void)
+{
+ struct sigaction act;
+ int fd;
+
+ act.sa_sigaction = handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO;
+ sigaction(SIGRTMIN + 1, &act, NULL);
+
+ fd = open(".", O_RDONLY);
+ fcntl(fd, F_SETSIG, SIGRTMIN + 1);
+ fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
+ /* we will now be notified if any of the files
+ in "." is modified or new files are created */
+ while (1) {
+ pause();
+ printf("Got event on fd=%d\n", event_fd);
+ }
+}
diff --git a/Documentation/filesystems/logfs.txt b/Documentation/filesystems/logfs.txt
new file mode 100644
index 00000000000..e64c94ba401
--- /dev/null
+++ b/Documentation/filesystems/logfs.txt
@@ -0,0 +1,241 @@
+
+The LogFS Flash Filesystem
+==========================
+
+Specification
+=============
+
+Superblocks
+-----------
+
+Two superblocks exist at the beginning and end of the filesystem.
+Each superblock is 256 Bytes large, with another 3840 Bytes reserved
+for future purposes, making a total of 4096 Bytes.
+
+Superblock locations may differ for MTD and block devices. On MTD the
+first non-bad block contains a superblock in the first 4096 Bytes and
+the last non-bad block contains a superblock in the last 4096 Bytes.
+On block devices, the first 4096 Bytes of the device contain the first
+superblock and the last aligned 4096 Byte-block contains the second
+superblock.
+
+For the most part, the superblocks can be considered read-only. They
+are written only to correct errors detected within the superblocks,
+move the journal and change the filesystem parameters through tunefs.
+As a result, the superblock does not contain any fields that require
+constant updates, like the amount of free space, etc.
+
+Segments
+--------
+
+The space in the device is split up into equal-sized segments.
+Segments are the primary write unit of LogFS. Within each segments,
+writes happen from front (low addresses) to back (high addresses. If
+only a partial segment has been written, the segment number, the
+current position within and optionally a write buffer are stored in
+the journal.
+
+Segments are erased as a whole. Therefore Garbage Collection may be
+required to completely free a segment before doing so.
+
+Journal
+--------
+
+The journal contains all global information about the filesystem that
+is subject to frequent change. At mount time, it has to be scanned
+for the most recent commit entry, which contains a list of pointers to
+all currently valid entries.
+
+Object Store
+------------
+
+All space except for the superblocks and journal is part of the object
+store. Each segment contains a segment header and a number of
+objects, each consisting of the object header and the payload.
+Objects are either inodes, directory entries (dentries), file data
+blocks or indirect blocks.
+
+Levels
+------
+
+Garbage collection (GC) may fail if all data is written
+indiscriminately. One requirement of GC is that data is seperated
+roughly according to the distance between the tree root and the data.
+Effectively that means all file data is on level 0, indirect blocks
+are on levels 1, 2, 3 4 or 5 for 1x, 2x, 3x, 4x or 5x indirect blocks,
+respectively. Inode file data is on level 6 for the inodes and 7-11
+for indirect blocks.
+
+Each segment contains objects of a single level only. As a result,
+each level requires its own seperate segment to be open for writing.
+
+Inode File
+----------
+
+All inodes are stored in a special file, the inode file. Single
+exception is the inode file's inode (master inode) which for obvious
+reasons is stored in the journal instead. Instead of data blocks, the
+leaf nodes of the inode files are inodes.
+
+Aliases
+-------
+
+Writes in LogFS are done by means of a wandering tree. A naïve
+implementation would require that for each write or a block, all
+parent blocks are written as well, since the block pointers have
+changed. Such an implementation would not be very efficient.
+
+In LogFS, the block pointer changes are cached in the journal by means
+of alias entries. Each alias consists of its logical address - inode
+number, block index, level and child number (index into block) - and
+the changed data. Any 8-byte word can be changes in this manner.
+
+Currently aliases are used for block pointers, file size, file used
+bytes and the height of an inodes indirect tree.
+
+Segment Aliases
+---------------
+
+Related to regular aliases, these are used to handle bad blocks.
+Initially, bad blocks are handled by moving the affected segment
+content to a spare segment and noting this move in the journal with a
+segment alias, a simple (to, from) tupel. GC will later empty this
+segment and the alias can be removed again. This is used on MTD only.
+
+Vim
+---
+
+By cleverly predicting the life time of data, it is possible to
+seperate long-living data from short-living data and thereby reduce
+the GC overhead later. Each type of distinc life expectency (vim) can
+have a seperate segment open for writing. Each (level, vim) tupel can
+be open just once. If an open segment with unknown vim is encountered
+at mount time, it is closed and ignored henceforth.
+
+Indirect Tree
+-------------
+
+Inodes in LogFS are similar to FFS-style filesystems with direct and
+indirect block pointers. One difference is that LogFS uses a single
+indirect pointer that can be either a 1x, 2x, etc. indirect pointer.
+A height field in the inode defines the height of the indirect tree
+and thereby the indirection of the pointer.
+
+Another difference is the addressing of indirect blocks. In LogFS,
+the first 16 pointers in the first indirect block are left empty,
+corresponding to the 16 direct pointers in the inode. In ext2 (maybe
+others as well) the first pointer in the first indirect block
+corresponds to logical block 12, skipping the 12 direct pointers.
+So where ext2 is using arithmetic to better utilize space, LogFS keeps
+arithmetic simple and uses compression to save space.
+
+Compression
+-----------
+
+Both file data and metadata can be compressed. Compression for file
+data can be enabled with chattr +c and disabled with chattr -c. Doing
+so has no effect on existing data, but new data will be stored
+accordingly. New inodes will inherit the compression flag of the
+parent directory.
+
+Metadata is always compressed. However, the space accounting ignores
+this and charges for the uncompressed size. Failing to do so could
+result in GC failures when, after moving some data, indirect blocks
+compress worse than previously. Even on a 100% full medium, GC may
+not consume any extra space, so the compression gains are lost space
+to the user.
+
+However, they are not lost space to the filesystem internals. By
+cheating the user for those bytes, the filesystem gained some slack
+space and GC will run less often and faster.
+
+Garbage Collection and Wear Leveling
+------------------------------------
+
+Garbage collection is invoked whenever the number of free segments
+falls below a threshold. The best (known) candidate is picked based
+on the least amount of valid data contained in the segment. All
+remaining valid data is copied elsewhere, thereby invalidating it.
+
+The GC code also checks for aliases and writes then back if their
+number gets too large.
+
+Wear leveling is done by occasionally picking a suboptimal segment for
+garbage collection. If a stale segments erase count is significantly
+lower than the active segments' erase counts, it will be picked. Wear
+leveling is rate limited, so it will never monopolize the device for
+more than one segment worth at a time.
+
+Values for "occasionally", "significantly lower" are compile time
+constants.
+
+Hashed directories
+------------------
+
+To satisfy efficient lookup(), directory entries are hashed and
+located based on the hash. In order to both support large directories
+and not be overly inefficient for small directories, several hash
+tables of increasing size are used. For each table, the hash value
+modulo the table size gives the table index.
+
+Tables sizes are chosen to limit the number of indirect blocks with a
+fully populated table to 0, 1, 2 or 3 respectively. So the first
+table contains 16 entries, the second 512-16, etc.
+
+The last table is special in several ways. First its size depends on
+the effective 32bit limit on telldir/seekdir cookies. Since logfs
+uses the upper half of the address space for indirect blocks, the size
+is limited to 2^31. Secondly the table contains hash buckets with 16
+entries each.
+
+Using single-entry buckets would result in birthday "attacks". At
+just 2^16 used entries, hash collisions would be likely (P >= 0.5).
+My math skills are insufficient to do the combinatorics for the 17x
+collisions necessary to overflow a bucket, but testing showed that in
+10,000 runs the lowest directory fill before a bucket overflow was
+188,057,130 entries with an average of 315,149,915 entries. So for
+directory sizes of up to a million, bucket overflows should be
+virtually impossible under normal circumstances.
+
+With carefully chosen filenames, it is obviously possible to cause an
+overflow with just 21 entries (4 higher tables + 16 entries + 1). So
+there may be a security concern if a malicious user has write access
+to a directory.
+
+Open For Discussion
+===================
+
+Device Address Space
+--------------------
+
+A device address space is used for caching. Both block devices and
+MTD provide functions to either read a single page or write a segment.
+Partial segments may be written for data integrity, but where possible
+complete segments are written for performance on simple block device
+flash media.
+
+Meta Inodes
+-----------
+
+Inodes are stored in the inode file, which is just a regular file for
+most purposes. At umount time, however, the inode file needs to
+remain open until all dirty inodes are written. So
+generic_shutdown_super() may not close this inode, but shouldn't
+complain about remaining inodes due to the inode file either. Same
+goes for mapping inode of the device address space.
+
+Currently logfs uses a hack that essentially copies part of fs/inode.c
+code over. A general solution would be preferred.
+
+Indirect block mapping
+----------------------
+
+With compression, the block device (or mapping inode) cannot be used
+to cache indirect blocks. Some other place is required. Currently
+logfs uses the top half of each inode's address space. The low 8TB
+(on 32bit) are filled with file data, the high 8TB are used for
+indirect blocks.
+
+One problem is that 16TB files created on 64bit systems actually have
+data in the top 8TB. But files >16TB would cause problems anyway, so
+only the limit has changed.
diff --git a/Documentation/filesystems/nfs/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt
index 1bd0d0c0517..6a53a84afc7 100644
--- a/Documentation/filesystems/nfs/nfs41-server.txt
+++ b/Documentation/filesystems/nfs/nfs41-server.txt
@@ -17,8 +17,7 @@ kernels must turn 4.1 on or off *before* turning support for version 4
on or off; rpc.nfsd does this correctly.)
The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based
-on the latest NFSv4.1 Internet Draft:
-http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29
+on RFC 5661.
From the many new features in NFSv4.1 the current implementation
focuses on the mandatory-to-implement NFSv4.1 Sessions, providing
@@ -44,7 +43,7 @@ interoperability problems with future clients. Known issues:
trunking, but this is a mandatory feature, and its use is
recommended to clients in a number of places. (E.g. to ensure
timely renewal in case an existing connection's retry timeouts
- have gotten too long; see section 8.3 of the draft.)
+ have gotten too long; see section 8.3 of the RFC.)
Therefore, lack of this feature may cause future clients to
fail.
- Incomplete backchannel support: incomplete backchannel gss
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 0d07513a67a..a4f30faa4f1 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -164,6 +164,7 @@ read the file /proc/PID/status:
VmExe: 68 kB
VmLib: 1412 kB
VmPTE: 20 kb
+ VmSwap: 0 kB
Threads: 1
SigQ: 0/28578
SigPnd: 0000000000000000
@@ -188,7 +189,13 @@ memory usage. Its seven fields are explained in Table 1-3. The stat file
contains details information about the process itself. Its fields are
explained in Table 1-4.
-Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
+(for SMP CONFIG users)
+For making accounting scalable, RSS related information are handled in
+asynchronous manner and the vaule may not be very precise. To see a precise
+snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table.
+It's slow but very precise.
+
+Table 1-2: Contents of the status files (as of 2.6.30-rc7)
..............................................................................
Field Content
Name filename of the executable
@@ -213,6 +220,7 @@ Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
VmExe size of text segment
VmLib size of shared library code
VmPTE size of page table entries
+ VmSwap size of swap usage (the number of referred swapents)
Threads number of threads
SigQ number of signals queued/max. number for queue
SigPnd bitmap of pending signals for the thread
@@ -430,6 +438,7 @@ Table 1-5: Kernel info in /proc
modules List of loaded modules
mounts Mounted filesystems
net Networking info (see text)
+ pagetypeinfo Additional page allocator information (see text) (2.5)
partitions Table of partitions known to the system
pci Deprecated info of PCI bus (new way -> /proc/bus/pci/,
decoupled by lspci (2.4)
@@ -584,7 +593,7 @@ Node 0, zone DMA 0 4 5 4 4 3 ...
Node 0, zone Normal 1 0 0 1 101 8 ...
Node 0, zone HighMem 2 0 0 1 1 0 ...
-Memory fragmentation is a problem under some workloads, and buddyinfo is a
+External fragmentation is a problem under some workloads, and buddyinfo is a
useful tool for helping diagnose these problems. Buddyinfo will give you a
clue as to how big an area you can safely allocate, or why a previous
allocation failed.
@@ -594,6 +603,48 @@ available. In this case, there are 0 chunks of 2^0*PAGE_SIZE available in
ZONE_DMA, 4 chunks of 2^1*PAGE_SIZE in ZONE_DMA, 101 chunks of 2^4*PAGE_SIZE
available in ZONE_NORMAL, etc...
+More information relevant to external fragmentation can be found in
+pagetypeinfo.
+
+> cat /proc/pagetypeinfo
+Page block order: 9
+Pages per block: 512
+
+Free pages count per migrate type at order 0 1 2 3 4 5 6 7 8 9 10
+Node 0, zone DMA, type Unmovable 0 0 0 1 1 1 1 1 1 1 0
+Node 0, zone DMA, type Reclaimable 0 0 0 0 0 0 0 0 0 0 0
+Node 0, zone DMA, type Movable 1 1 2 1 2 1 1 0 1 0 2
+Node 0, zone DMA, type Reserve 0 0 0 0 0 0 0 0 0 1 0
+Node 0, zone DMA, type Isolate 0 0 0 0 0 0 0 0 0 0 0
+Node 0, zone DMA32, type Unmovable 103 54 77 1 1 1 11 8 7 1 9
+Node 0, zone DMA32, type Reclaimable 0 0 2 1 0 0 0 0 1 0 0
+Node 0, zone DMA32, type Movable 169 152 113 91 77 54 39 13 6 1 452
+Node 0, zone DMA32, type Reserve 1 2 2 2 2 0 1 1 1 1 0
+Node 0, zone DMA32, type Isolate 0 0 0 0 0 0 0 0 0 0 0
+
+Number of blocks type Unmovable Reclaimable Movable Reserve Isolate
+Node 0, zone DMA 2 0 5 1 0
+Node 0, zone DMA32 41 6 967 2 0
+
+Fragmentation avoidance in the kernel works by grouping pages of different
+migrate types into the same contiguous regions of memory called page blocks.
+A page block is typically the size of the default hugepage size e.g. 2MB on
+X86-64. By keeping pages grouped based on their ability to move, the kernel
+can reclaim pages within a page block to satisfy a high-order allocation.
+
+The pagetypinfo begins with information on the size of a page block. It
+then gives the same type of information as buddyinfo except broken down
+by migrate-type and finishes with details on how many page blocks of each
+type exist.
+
+If min_free_kbytes has been tuned correctly (recommendations made by hugeadm
+from libhugetlbfs http://sourceforge.net/projects/libhugetlbfs/), one can
+make an estimate of the likely number of huge pages that can be allocated
+at a given point in time. All the "Movable" blocks should be allocatable
+unless memory has been mlock()'d. Some of the Reclaimable blocks should
+also be allocatable although a lot of filesystem metadata may have to be
+reclaimed to achieve this.
+
..............................................................................
meminfo:
diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt
index 3015da0c6b2..fe09a2cb185 100644
--- a/Documentation/filesystems/tmpfs.txt
+++ b/Documentation/filesystems/tmpfs.txt
@@ -82,11 +82,13 @@ tmpfs has a mount option to set the NUMA memory allocation policy for
all files in that instance (if CONFIG_NUMA is enabled) - which can be
adjusted on the fly via 'mount -o remount ...'
-mpol=default prefers to allocate memory from the local node
+mpol=default use the process allocation policy
+ (see set_mempolicy(2))
mpol=prefer:Node prefers to allocate memory from the given Node
mpol=bind:NodeList allocates memory only from nodes in NodeList
mpol=interleave prefers to allocate from each node in turn
mpol=interleave:NodeList allocates from each node of NodeList in turn
+mpol=local prefers to allocate memory from the local node
NodeList format is a comma-separated list of decimal numbers and ranges,
a range being two hyphen-separated decimal numbers, the smallest and
@@ -134,3 +136,5 @@ Author:
Christoph Rohland <cr@sap.com>, 1.12.01
Updated:
Hugh Dickins, 4 June 2007
+Updated:
+ KOSAKI Motohiro, 16 Mar 2010
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index 1866c27eec6..c2c6e9b39bb 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -253,6 +253,70 @@ pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
Also note that it's your responsibility to have stopped using a GPIO
before you free it.
+Considering in most cases GPIOs are actually configured right after they
+are claimed, three additional calls are defined:
+
+ /* request a single GPIO, with initial configuration specified by
+ * 'flags', identical to gpio_request() wrt other arguments and
+ * return value
+ */
+ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
+
+ /* request multiple GPIOs in a single call
+ */
+ int gpio_request_array(struct gpio *array, size_t num);
+
+ /* release multiple GPIOs in a single call
+ */
+ void gpio_free_array(struct gpio *array, size_t num);
+
+where 'flags' is currently defined to specify the following properties:
+
+ * GPIOF_DIR_IN - to configure direction as input
+ * GPIOF_DIR_OUT - to configure direction as output
+
+ * GPIOF_INIT_LOW - as output, set initial level to LOW
+ * GPIOF_INIT_HIGH - as output, set initial level to HIGH
+
+since GPIOF_INIT_* are only valid when configured as output, so group valid
+combinations as:
+
+ * GPIOF_IN - configure as input
+ * GPIOF_OUT_INIT_LOW - configured as output, initial level LOW
+ * GPIOF_OUT_INIT_HIGH - configured as output, initial level HIGH
+
+In the future, these flags can be extended to support more properties such
+as open-drain status.
+
+Further more, to ease the claim/release of multiple GPIOs, 'struct gpio' is
+introduced to encapsulate all three fields as:
+
+ struct gpio {
+ unsigned gpio;
+ unsigned long flags;
+ const char *label;
+ };
+
+A typical example of usage:
+
+ static struct gpio leds_gpios[] = {
+ { 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* default to ON */
+ { 33, GPIOF_OUT_INIT_LOW, "Green LED" }, /* default to OFF */
+ { 34, GPIOF_OUT_INIT_LOW, "Red LED" }, /* default to OFF */
+ { 35, GPIOF_OUT_INIT_LOW, "Blue LED" }, /* default to OFF */
+ { ... },
+ };
+
+ err = gpio_request_one(31, GPIOF_IN, "Reset Button");
+ if (err)
+ ...
+
+ err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
+ if (err)
+ ...
+
+ gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
+
GPIOs mapped to IRQs
--------------------
diff --git a/Documentation/hwmon/abituguru b/Documentation/hwmon/abituguru
index 87ffa0f5ec7..5eb3b9d5f0d 100644
--- a/Documentation/hwmon/abituguru
+++ b/Documentation/hwmon/abituguru
@@ -30,7 +30,7 @@ Supported chips:
bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1
You may also need to specify the fan_sensors option for these boards
fan_sensors=5
- 2) There is a seperate abituguru3 driver for these motherboards,
+ 2) There is a separate abituguru3 driver for these motherboards,
the abituguru (without the 3 !) driver will not work on these
motherboards (and visa versa)!
diff --git a/Documentation/hwmon/adt7411 b/Documentation/hwmon/adt7411
new file mode 100644
index 00000000000..1632960f974
--- /dev/null
+++ b/Documentation/hwmon/adt7411
@@ -0,0 +1,42 @@
+Kernel driver adt7411
+=====================
+
+Supported chips:
+ * Analog Devices ADT7411
+ Prefix: 'adt7411'
+ Addresses scanned: 0x48, 0x4a, 0x4b
+ Datasheet: Publicly available at the Analog Devices website
+
+Author: Wolfram Sang (based on adt7470 by Darrick J. Wong)
+
+Description
+-----------
+
+This driver implements support for the Analog Devices ADT7411 chip. There may
+be other chips that implement this interface.
+
+The ADT7411 can use an I2C/SMBus compatible 2-wire interface or an
+SPI-compatible 4-wire interface. It provides a 10-bit analog to digital
+converter which measures 1 temperature, vdd and 8 input voltages. It has an
+internal temperature sensor, but an external one can also be connected (one
+loses 2 inputs then). There are high- and low-limit registers for all inputs.
+
+Check the datasheet for details.
+
+sysfs-Interface
+---------------
+
+in0_input - vdd voltage input
+in[1-8]_input - analog 1-8 input
+temp1_input - temperature input
+
+Besides standard interfaces, this driver adds (0 = off, 1 = on):
+
+ adc_ref_vdd - Use vdd as reference instead of 2.25 V
+ fast_sampling - Sample at 22.5 kHz instead of 1.4 kHz, but drop filters
+ no_average - Turn off averaging over 16 samples
+
+Notes
+-----
+
+SPI, external temperature sensor and limit registers are not supported yet.
diff --git a/Documentation/hwmon/adt7473 b/Documentation/hwmon/adt7473
deleted file mode 100644
index 446612bd1fb..00000000000
--- a/Documentation/hwmon/adt7473
+++ /dev/null
@@ -1,74 +0,0 @@
-Kernel driver adt7473
-======================
-
-Supported chips:
- * Analog Devices ADT7473
- Prefix: 'adt7473'
- Addresses scanned: I2C 0x2C, 0x2D, 0x2E
- Datasheet: Publicly available at the Analog Devices website
-
-Author: Darrick J. Wong
-
-This driver is depreacted, please use the adt7475 driver instead.
-
-Description
------------
-
-This driver implements support for the Analog Devices ADT7473 chip family.
-
-The ADT7473 uses the 2-wire interface compatible with the SMBUS 2.0
-specification. Using an analog to digital converter it measures three (3)
-temperatures and two (2) voltages. It has four (4) 16-bit counters for
-measuring fan speed. There are three (3) PWM outputs that can be used
-to control fan speed.
-
-A sophisticated control system for the PWM outputs is designed into the
-ADT7473 that allows fan speed to be adjusted automatically based on any of the
-three temperature sensors. Each PWM output is individually adjustable and
-programmable. Once configured, the ADT7473 will adjust the PWM outputs in
-response to the measured temperatures without further host intervention.
-This feature can also be disabled for manual control of the PWM's.
-
-Each of the measured inputs (voltage, temperature, fan speed) has
-corresponding high/low limit values. The ADT7473 will signal an ALARM if
-any measured value exceeds either limit.
-
-The ADT7473 samples all inputs continuously. The driver will not read
-the registers more often than once every other second. Further,
-configuration data is only read once per minute.
-
-Special Features
-----------------
-
-The ADT7473 have a 10-bit ADC and can therefore measure temperatures
-with 0.25 degC resolution. Temperature readings can be configured either
-for twos complement format or "Offset 64" format, wherein 63 is subtracted
-from the raw value to get the temperature value.
-
-The Analog Devices datasheet is very detailed and describes a procedure for
-determining an optimal configuration for the automatic PWM control.
-
-Configuration Notes
--------------------
-
-Besides standard interfaces driver adds the following:
-
-* PWM Control
-
-* pwm#_auto_point1_pwm and temp#_auto_point1_temp and
-* pwm#_auto_point2_pwm and temp#_auto_point2_temp -
-
-point1: Set the pwm speed at a lower temperature bound.
-point2: Set the pwm speed at a higher temperature bound.
-
-The ADT7473 will scale the pwm between the lower and higher pwm speed when
-the temperature is between the two temperature boundaries. PWM values range
-from 0 (off) to 255 (full speed). Fan speed will be set to maximum when the
-temperature sensor associated with the PWM control exceeds temp#_max.
-
-Notes
------
-
-The NVIDIA binary driver presents an ADT7473 chip via an on-card i2c bus.
-Unfortunately, they fail to set the i2c adapter class, so this driver may
-fail to find the chip until the nvidia driver is patched.
diff --git a/Documentation/hwmon/asc7621 b/Documentation/hwmon/asc7621
new file mode 100644
index 00000000000..7287be7e1f2
--- /dev/null
+++ b/Documentation/hwmon/asc7621
@@ -0,0 +1,296 @@
+Kernel driver asc7621
+==================
+
+Supported chips:
+ Andigilog aSC7621 and aSC7621a
+ Prefix: 'asc7621'
+ Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+ Datasheet: http://www.fairview5.com/linux/asc7621/asc7621.pdf
+
+Author:
+ George Joseph
+
+Description provided by Dave Pivin @ Andigilog:
+
+Andigilog has both the PECI and pre-PECI versions of the Heceta-6, as
+Intel calls them. Heceta-6e has high frequency PWM and Heceta-6p has
+added PECI and a 4th thermal zone. The Andigilog aSC7611 is the
+Heceta-6e part and aSC7621 is the Heceta-6p part. They are both in
+volume production, shipping to Intel and their subs.
+
+We have enhanced both parts relative to the governing Intel
+specification. First enhancement is temperature reading resolution. We
+have used registers below 20h for vendor-specific functions in addition
+to those in the Intel-specified vendor range.
+
+Our conversion process produces a result that is reported as two bytes.
+The fan speed control uses this finer value to produce a "step-less" fan
+PWM output. These two bytes are "read-locked" to guarantee that once a
+high or low byte is read, the other byte is locked-in until after the
+next read of any register. So to get an atomic reading, read high or low
+byte, then the very next read should be the opposite byte. Our data
+sheet says 10-bits of resolution, although you may find the lower bits
+are active, they are not necessarily reliable or useful externally. We
+chose not to mask them.
+
+We employ significant filtering that is user tunable as described in the
+data sheet. Our temperature reports and fan PWM outputs are very smooth
+when compared to the competition, in addition to the higher resolution
+temperature reports. The smoother PWM output does not require user
+intervention.
+
+We offer GPIO features on the former VID pins. These are open-drain
+outputs or inputs and may be used as general purpose I/O or as alarm
+outputs that are based on temperature limits. These are in 19h and 1Ah.
+
+We offer flexible mapping of temperature readings to thermal zones. Any
+temperature may be mapped to any zone, which has a default assignment
+that follows Intel's specs.
+
+Since there is a fan to zone assignment that allows for the "hotter" of
+a set of zones to control the PWM of an individual fan, but there is no
+indication to the user, we have added an indicator that shows which zone
+is currently controlling the PWM for a given fan. This is in register
+00h.
+
+Both remote diode temperature readings may be given an offset value such
+that the reported reading as well as the temperature used to determine
+PWM may be offset for system calibration purposes.
+
+PECI Extended configuration allows for having more than two domains per
+PECI address and also provides an enabling function for each PECI
+address. One could use our flexible zone assignment to have a zone
+assigned to up to 4 PECI addresses. This is not possible in the default
+Intel configuration. This would be useful in multi-CPU systems with
+individual fans on each that would benefit from individual fan control.
+This is in register 0Eh.
+
+The tachometer measurement system is flexible and able to adapt to many
+fan types. We can also support pulse-stretched PWM so that 3-wire fans
+may be used. These characteristics are in registers 04h to 07h.
+
+Finally, we have added a tach disable function that turns off the tach
+measurement system for individual tachs in order to save power. That is
+in register 75h.
+
+--
+aSC7621 Product Description
+
+The aSC7621 has a two wire digital interface compatible with SMBus 2.0.
+Using a 10-bit ADC, the aSC7621 measures the temperature of two remote diode
+connected transistors as well as its own die. Support for Platform
+Environmental Control Interface (PECI) is included.
+
+Using temperature information from these four zones, an automatic fan speed
+control algorithm is employed to minimize acoustic impact while achieving
+recommended CPU temperature under varying operational loads.
+
+To set fan speed, the aSC7621 has three independent pulse width modulation
+(PWM) outputs that are controlled by one, or a combination of three,
+temperature zones. Both high- and low-frequency PWM ranges are supported.
+
+The aSC7621 also includes a digital filter that can be invoked to smooth
+temperature readings for better control of fan speed and minimum acoustic
+impact.
+
+The aSC7621 has tachometer inputs to measure fan speed on up to four fans.
+Limit and status registers for all measured values are included to alert
+the system host that any measurements are outside of programmed limits
+via status registers.
+
+System voltages of VCCP, 2.5V, 3.3V, 5.0V, and 12V motherboard power are
+monitored efficiently with internal scaling resistors.
+
+Features
+- Supports PECI interface and monitors internal and remote thermal diodes
+- 2-wire, SMBus 2.0 compliant, serial interface
+- 10-bit ADC
+- Monitors VCCP, 2.5V, 3.3V, 5.0V, and 12V motherboard/processor supplies
+- Programmable autonomous fan control based on temperature readings
+- Noise filtering of temperature reading for fan speed control
+- 0.25C digital temperature sensor resolution
+- 3 PWM fan speed control outputs for 2-, 3- or 4-wire fans and up to 4 fan
+ tachometer inputs
+- Enhanced measured temperature to Temperature Zone assignment.
+- Provides high and low PWM frequency ranges
+- 3 GPIO pins for custom use
+- 24-Lead QSOP package
+
+Configuration Notes
+===================
+
+Except where noted below, the sysfs entries created by this driver follow
+the standards defined in "sysfs-interface".
+
+temp1_source
+ 0 (default) peci_legacy = 0, Remote 1 Temperature
+ peci_legacy = 1, PECI Processor Temperature 0
+ 1 Remote 1 Temperature
+ 2 Remote 2 Temperature
+ 3 Internal Temperature
+ 4 PECI Processor Temperature 0
+ 5 PECI Processor Temperature 1
+ 6 PECI Processor Temperature 2
+ 7 PECI Processor Temperature 3
+
+temp2_source
+ 0 (default) Internal Temperature
+ 1 Remote 1 Temperature
+ 2 Remote 2 Temperature
+ 3 Internal Temperature
+ 4 PECI Processor Temperature 0
+ 5 PECI Processor Temperature 1
+ 6 PECI Processor Temperature 2
+ 7 PECI Processor Temperature 3
+
+temp3_source
+ 0 (default) Remote 2 Temperature
+ 1 Remote 1 Temperature
+ 2 Remote 2 Temperature
+ 3 Internal Temperature
+ 4 PECI Processor Temperature 0
+ 5 PECI Processor Temperature 1
+ 6 PECI Processor Temperature 2
+ 7 PECI Processor Temperature 3
+
+temp4_source
+ 0 (default) peci_legacy = 0, PECI Processor Temperature 0
+ peci_legacy = 1, Remote 1 Temperature
+ 1 Remote 1 Temperature
+ 2 Remote 2 Temperature
+ 3 Internal Temperature
+ 4 PECI Processor Temperature 0
+ 5 PECI Processor Temperature 1
+ 6 PECI Processor Temperature 2
+ 7 PECI Processor Temperature 3
+
+temp[1-4]_smoothing_enable
+temp[1-4]_smoothing_time
+ Smooths spikes in temp readings caused by noise.
+ Valid values in milliseconds are:
+ 35000
+ 17600
+ 11800
+ 7000
+ 4400
+ 3000
+ 1600
+ 800
+
+temp[1-4]_crit
+ When the corresponding zone temperature reaches this value,
+ ALL pwm outputs will got to 100%.
+
+temp[5-8]_input
+temp[5-8]_enable
+ The aSC7621 can also read temperatures provided by the processor
+ via the PECI bus. Usually these are "core" temps and are relative
+ to the point where the automatic thermal control circuit starts
+ throttling. This means that these are usually negative numbers.
+
+pwm[1-3]_enable
+ 0 Fan off.
+ 1 Fan on manual control.
+ 2 Fan on automatic control and will run at the minimum pwm
+ if the temperature for the zone is below the minimum.
+ 3 Fan on automatic control but will be off if the temperature
+ for the zone is below the minimum.
+ 4-254 Ignored.
+ 255 Fan on full.
+
+pwm[1-3]_auto_channels
+ Bitmap as described in sysctl-interface with the following
+ exceptions...
+ Only the following combination of zones (and their corresponding masks)
+ are valid:
+ 1
+ 2
+ 3
+ 2,3
+ 1,2,3
+ 4
+ 1,2,3,4
+
+ Special values:
+ 0 Disabled.
+ 16 Fan on manual control.
+ 31 Fan on full.
+
+
+pwm[1-3]_invert
+ When set, inverts the meaning of pwm[1-3].
+ i.e. when pwm = 0, the fan will be on full and
+ when pwm = 255 the fan will be off.
+
+pwm[1-3]_freq
+ PWM frequency in Hz
+ Valid values in Hz are:
+
+ 10
+ 15
+ 23
+ 30 (default)
+ 38
+ 47
+ 62
+ 94
+ 23000
+ 24000
+ 25000
+ 26000
+ 27000
+ 28000
+ 29000
+ 30000
+
+ Setting any other value will be ignored.
+
+peci_enable
+ Enables or disables PECI
+
+peci_avg
+ Input filter average time.
+
+ 0 0 Sec. (no Smoothing) (default)
+ 1 0.25 Sec.
+ 2 0.5 Sec.
+ 3 1.0 Sec.
+ 4 2.0 Sec.
+ 5 4.0 Sec.
+ 6 8.0 Sec.
+ 7 0.0 Sec.
+
+peci_legacy
+
+ 0 Standard Mode (default)
+ Remote Diode 1 reading is associated with
+ Temperature Zone 1, PECI is associated with
+ Zone 4
+
+ 1 Legacy Mode
+ PECI is associated with Temperature Zone 1,
+ Remote Diode 1 is associated with Zone 4
+
+peci_diode
+ Diode filter
+
+ 0 0.25 Sec.
+ 1 1.1 Sec.
+ 2 2.4 Sec. (default)
+ 3 3.4 Sec.
+ 4 5.0 Sec.
+ 5 6.8 Sec.
+ 6 10.2 Sec.
+ 7 16.4 Sec.
+
+peci_4domain
+ Four domain enable
+
+ 0 1 or 2 Domains for enabled processors (default)
+ 1 3 or 4 Domains for enabled processors
+
+peci_domain
+ Domain
+
+ 0 Processor contains a single domain (0) (default)
+ 1 Processor contains two domains (0,1)
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index f9ba96c0ac4..8d08bf0d38e 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -5,31 +5,23 @@ Supported chips:
* IT8705F
Prefix: 'it87'
Addresses scanned: from Super I/O config space (8 I/O ports)
- Datasheet: Publicly available at the ITE website
- http://www.ite.com.tw/product_info/file/pc/IT8705F_V.0.4.1.pdf
+ Datasheet: Once publicly available at the ITE website, but no longer
* IT8712F
Prefix: 'it8712'
Addresses scanned: from Super I/O config space (8 I/O ports)
- Datasheet: Publicly available at the ITE website
- http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.1.pdf
- http://www.ite.com.tw/product_info/file/pc/Errata%20V0.1%20for%20IT8712F%20V0.9.1.pdf
- http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.3.pdf
+ Datasheet: Once publicly available at the ITE website, but no longer
* IT8716F/IT8726F
Prefix: 'it8716'
Addresses scanned: from Super I/O config space (8 I/O ports)
- Datasheet: Publicly available at the ITE website
- http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP
- http://www.ite.com.tw/product_info/file/pc/IT8726F_V0.3.pdf
+ Datasheet: Once publicly available at the ITE website, but no longer
* IT8718F
Prefix: 'it8718'
Addresses scanned: from Super I/O config space (8 I/O ports)
- Datasheet: Publicly available at the ITE website
- http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip
- http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip
+ Datasheet: Once publicly available at the ITE website, but no longer
* IT8720F
Prefix: 'it8720'
Addresses scanned: from Super I/O config space (8 I/O ports)
- Datasheet: Not yet publicly available.
+ Datasheet: Not publicly available
* SiS950 [clone of IT8705F]
Prefix: 'it87'
Addresses scanned: from Super I/O config space (8 I/O ports)
@@ -136,6 +128,10 @@ registers are read whenever any data is read (unless it is less than 1.5
seconds since the last update). This means that you can easily miss
once-only alarms.
+Out-of-limit readings can also result in beeping, if the chip is properly
+wired and configured. Beeping can be enabled or disabled per sensor type
+(temperatures, voltages and fans.)
+
The IT87xx only updates its values each 1.5 seconds; reading it more often
will do no harm, but will return 'old' values.
@@ -150,11 +146,38 @@ Fan speed control
-----------------
The fan speed control features are limited to manual PWM mode. Automatic
-"Smart Guardian" mode control handling is not implemented. However
-if you want to go for "manual mode" just write 1 to pwmN_enable.
+"Smart Guardian" mode control handling is only implemented for older chips
+(see below.) However if you want to go for "manual mode" just write 1 to
+pwmN_enable.
If you are only able to control the fan speed with very small PWM values,
try lowering the PWM base frequency (pwm1_freq). Depending on the fan,
it may give you a somewhat greater control range. The same frequency is
used to drive all fan outputs, which is why pwm2_freq and pwm3_freq are
read-only.
+
+
+Automatic fan speed control (old interface)
+-------------------------------------------
+
+The driver supports the old interface to automatic fan speed control
+which is implemented by IT8705F chips up to revision F and IT8712F
+chips up to revision G.
+
+This interface implements 4 temperature vs. PWM output trip points.
+The PWM output of trip point 4 is always the maximum value (fan running
+at full speed) while the PWM output of the other 3 trip points can be
+freely chosen. The temperature of all 4 trip points can be freely chosen.
+Additionally, trip point 1 has an hysteresis temperature attached, to
+prevent fast switching between fan on and off.
+
+The chip automatically computes the PWM output value based on the input
+temperature, based on this simple rule: if the temperature value is
+between trip point N and trip point N+1 then the PWM output value is
+the one of trip point N. The automatic control mode is less flexible
+than the manual control mode, but it reacts faster, is more robust and
+doesn't use CPU cycles.
+
+Trip points must be set properly before switching to automatic fan speed
+control mode. The driver will perform basic integrity checks before
+actually switching to automatic control mode.
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90
index 93d8e3d5515..6a03dd4bcc9 100644
--- a/Documentation/hwmon/lm90
+++ b/Documentation/hwmon/lm90
@@ -84,6 +84,10 @@ Supported chips:
Addresses scanned: I2C 0x4c
Datasheet: Publicly available at the Maxim website
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500
+ * Winbond/Nuvoton W83L771AWG/ASG
+ Prefix: 'w83l771'
+ Addresses scanned: I2C 0x4c
+ Datasheet: Not publicly available, can be requested from Nuvoton
Author: Jean Delvare <khali@linux-fr.org>
@@ -147,6 +151,12 @@ MAX6680 and MAX6681:
* Selectable address
* Remote sensor type selection
+W83L771AWG/ASG
+ * The AWG and ASG variants only differ in package format.
+ * Filter and alert configuration register at 0xBF
+ * Diode ideality factor configuration (remote sensor) at 0xE3
+ * Moving average (depending on conversion rate)
+
All temperature values are given in degrees Celsius. Resolution
is 1.0 degree for the local temperature, 0.125 degree for the remote
temperature, except for the MAX6657, MAX6658 and MAX6659 which have a
@@ -163,6 +173,18 @@ The lm90 driver will not update its values more frequently than every
other second; reading them more often will do no harm, but will return
'old' values.
+SMBus Alert Support
+-------------------
+
+This driver has basic support for SMBus alert. When an alert is received,
+the status register is read and the faulty temperature channel is logged.
+
+The Analog Devices chips (ADM1032 and ADT7461) do not implement the SMBus
+alert protocol properly so additional care is needed: the ALERT output is
+disabled when an alert is received, and is re-enabled only when the alarm
+is gone. Otherwise the chip would block alerts from other chips in the bus
+as long as the alarm is active.
+
PEC Support
-----------
diff --git a/Documentation/init.txt b/Documentation/init.txt
new file mode 100644
index 00000000000..535ad5e82b9
--- /dev/null
+++ b/Documentation/init.txt
@@ -0,0 +1,49 @@
+Explaining the dreaded "No init found." boot hang message
+=========================================================
+
+OK, so you've got this pretty unintuitive message (currently located
+in init/main.c) and are wondering what the H*** went wrong.
+Some high-level reasons for failure (listed roughly in order of execution)
+to load the init binary are:
+A) Unable to mount root FS
+B) init binary doesn't exist on rootfs
+C) broken console device
+D) binary exists but dependencies not available
+E) binary cannot be loaded
+
+Detailed explanations:
+0) Set "debug" kernel parameter (in bootloader config file or CONFIG_CMDLINE)
+ to get more detailed kernel messages.
+A) make sure you have the correct root FS type
+ (and root= kernel parameter points to the correct partition),
+ required drivers such as storage hardware (such as SCSI or USB!)
+ and filesystem (ext3, jffs2 etc.) are builtin (alternatively as modules,
+ to be pre-loaded by an initrd)
+C) Possibly a conflict in console= setup --> initial console unavailable.
+ E.g. some serial consoles are unreliable due to serial IRQ issues (e.g.
+ missing interrupt-based configuration).
+ Try using a different console= device or e.g. netconsole= .
+D) e.g. required library dependencies of the init binary such as
+ /lib/ld-linux.so.2 missing or broken. Use readelf -d <INIT>|grep NEEDED
+ to find out which libraries are required.
+E) make sure the binary's architecture matches your hardware.
+ E.g. i386 vs. x86_64 mismatch, or trying to load x86 on ARM hardware.
+ In case you tried loading a non-binary file here (shell script?),
+ you should make sure that the script specifies an interpreter in its shebang
+ header line (#!/...) that is fully working (including its library
+ dependencies). And before tackling scripts, better first test a simple
+ non-script binary such as /bin/sh and confirm its successful execution.
+ To find out more, add code to init/main.c to display kernel_execve()s
+ return values.
+
+Please extend this explanation whenever you find new failure causes
+(after all loading the init binary is a CRITICAL and hard transition step
+which needs to be made as painless as possible), then submit patch to LKML.
+Further TODOs:
+- Implement the various run_init_process() invocations via a struct array
+ which can then store the kernel_execve() result value and on failure
+ log it all by iterating over _all_ results (very important usability fix).
+- try to make the implementation itself more helpful in general,
+ e.g. by providing additional error messages at affected places.
+
+Andreas Mohr <andi at lisas period de>
diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt
index 8490480ce43..c0fc1c75fd8 100644
--- a/Documentation/input/multi-touch-protocol.txt
+++ b/Documentation/input/multi-touch-protocol.txt
@@ -68,6 +68,22 @@ like:
SYN_MT_REPORT
SYN_REPORT
+Here is the sequence after lifting one of the fingers:
+
+ ABS_MT_POSITION_X
+ ABS_MT_POSITION_Y
+ SYN_MT_REPORT
+ SYN_REPORT
+
+And here is the sequence after lifting the remaining finger:
+
+ SYN_MT_REPORT
+ SYN_REPORT
+
+If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
+ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
+last SYN_REPORT will be dropped by the input core, resulting in no
+zero-finger event reaching userland.
Event Semantics
---------------
@@ -217,11 +233,6 @@ where examples can be found.
difference between the contact position and the approaching tool position
could be used to derive tilt.
[2] The list can of course be extended.
-[3] The multi-touch X driver is currently in the prototyping stage. At the
-time of writing (April 2009), the MT protocol is not yet merged, and the
-prototype implements finger matching, basic mouse support and two-finger
-scrolling. The project aims at improving the quality of current multi-touch
-functionality available in the Synaptics X driver, and in addition
-implement more advanced gestures.
+[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
[4] See the section on event computation.
[5] See the section on finger tracking.
diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt
index 3a6aec40c0b..8b4129de1d2 100644
--- a/Documentation/input/rotary-encoder.txt
+++ b/Documentation/input/rotary-encoder.txt
@@ -75,7 +75,7 @@ and the number of steps or will clamp at the maximum and zero depending on
the configuration.
Because GPIO to IRQ mapping is platform specific, this information must
-be given in seperately to the driver. See the example below.
+be given in separately to the driver. See the example below.
---------<snip>---------
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 35c9b51d20e..dd5806f4fcc 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -291,6 +291,7 @@ Code Seq#(hex) Include File Comments
0x92 00-0F drivers/usb/mon/mon_bin.c
0x93 60-7F linux/auto_fs.h
0x94 all fs/btrfs/ioctl.h
+0x97 00-7F fs/ceph/ioctl.h Ceph file system
0x99 00-0F 537-Addinboard driver
<mailto:buk@buks.ipn.de>
0xA0 all linux/sdp/sdp.h Industrial Device Project
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index d80930d58da..839b21b0699 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -200,10 +200,6 @@ and is between 256 and 4096 characters. It is defined in the file
acpi_display_output=video
See above.
- acpi_early_pdc_eval [HW,ACPI] Evaluate processor _PDC methods
- early. Needed on some platforms to properly
- initialize the EC.
-
acpi_irq_balance [HW,ACPI]
ACPI will balance active IRQs
default in APIC mode
@@ -324,11 +320,6 @@ and is between 256 and 4096 characters. It is defined in the file
amd_iommu= [HW,X86-84]
Pass parameters to the AMD IOMMU driver in the system.
Possible values are:
- isolate - enable device isolation (each device, as far
- as possible, will get its own protection
- domain) [default]
- share - put every device behind one IOMMU into the
- same protection domain
fullflush - enable flushing of IO/TLB entries when
they are unmapped. Otherwise they are
flushed before they will be reused, which
@@ -1203,7 +1194,7 @@ and is between 256 and 4096 characters. It is defined in the file
libata.force= [LIBATA] Force configurations. The format is comma
separated list of "[ID:]VAL" where ID is
- PORT[:DEVICE]. PORT and DEVICE are decimal numbers
+ PORT[.DEVICE]. PORT and DEVICE are decimal numbers
matching port, link or device. Basically, it matches
the ATA ID string printed on console by libata. If
the whole ID part is omitted, the last PORT and DEVICE
@@ -2834,6 +2825,12 @@ and is between 256 and 4096 characters. It is defined in the file
default x2apic cluster mode on platforms
supporting x2apic.
+ x86_mrst_timer= [X86-32,APBT]
+ Choose timer option for x86 Moorestown MID platform.
+ Two valid options are apbt timer only and lapic timer
+ plus one apbt timer for broadcast timer.
+ x86_mrst_timer=apbt_only | lapic_and_apbt
+
xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks.
xd_geo= See header of drivers/block/xd.c.
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt
index c79ab996dad..3ab2472509c 100644
--- a/Documentation/kobject.txt
+++ b/Documentation/kobject.txt
@@ -59,37 +59,56 @@ nice to have in other objects. The C language does not allow for the
direct expression of inheritance, so other techniques - such as structure
embedding - must be used.
-So, for example, the UIO code has a structure that defines the memory
-region associated with a uio device:
+(As an aside, for those familiar with the kernel linked list implementation,
+this is analogous as to how "list_head" structs are rarely useful on
+their own, but are invariably found embedded in the larger objects of
+interest.)
-struct uio_mem {
+So, for example, the UIO code in drivers/uio/uio.c has a structure that
+defines the memory region associated with a uio device:
+
+ struct uio_map {
struct kobject kobj;
- unsigned long addr;
- unsigned long size;
- int memtype;
- void __iomem *internal_addr;
-};
+ struct uio_mem *mem;
+ };
-If you have a struct uio_mem structure, finding its embedded kobject is
+If you have a struct uio_map structure, finding its embedded kobject is
just a matter of using the kobj member. Code that works with kobjects will
often have the opposite problem, however: given a struct kobject pointer,
what is the pointer to the containing structure? You must avoid tricks
(such as assuming that the kobject is at the beginning of the structure)
and, instead, use the container_of() macro, found in <linux/kernel.h>:
- container_of(pointer, type, member)
+ container_of(pointer, type, member)
+
+where:
+
+ * "pointer" is the pointer to the embedded kobject,
+ * "type" is the type of the containing structure, and
+ * "member" is the name of the structure field to which "pointer" points.
+
+The return value from container_of() is a pointer to the corresponding
+container type. So, for example, a pointer "kp" to a struct kobject
+embedded *within* a struct uio_map could be converted to a pointer to the
+*containing* uio_map structure with:
+
+ struct uio_map *u_map = container_of(kp, struct uio_map, kobj);
+
+For convenience, programmers often define a simple macro for "back-casting"
+kobject pointers to the containing type. Exactly this happens in the
+earlier drivers/uio/uio.c, as you can see here:
+
+ struct uio_map {
+ struct kobject kobj;
+ struct uio_mem *mem;
+ };
-where pointer is the pointer to the embedded kobject, type is the type of
-the containing structure, and member is the name of the structure field to
-which pointer points. The return value from container_of() is a pointer to
-the given type. So, for example, a pointer "kp" to a struct kobject
-embedded within a struct uio_mem could be converted to a pointer to the
-containing uio_mem structure with:
+ #define to_map(map) container_of(map, struct uio_map, kobj)
- struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj);
+where the macro argument "map" is a pointer to the struct kobject in
+question. That macro is subsequently invoked with:
-Programmers often define a simple macro for "back-casting" kobject pointers
-to the containing type.
+ struct uio_map *map = to_map(kobj);
Initialization of kobjects
@@ -266,7 +285,7 @@ kobj_type:
struct kobj_type {
void (*release)(struct kobject *);
- struct sysfs_ops *sysfs_ops;
+ const struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
};
@@ -387,4 +406,5 @@ called, and the objects in the former circle release each other.
Example code to copy from
For a more complete example of using ksets and kobjects properly, see the
-sample/kobject/kset-example.c code.
+example programs samples/kobject/{kobject-example.c,kset-example.c},
+which will be built as loadable modules if you select CONFIG_SAMPLE_KOBJECT.
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 053037a1fe6..2f9115c0ae6 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -1,6 +1,7 @@
Title : Kernel Probes (Kprobes)
Authors : Jim Keniston <jkenisto@us.ibm.com>
- : Prasanna S Panchamukhi <prasanna@in.ibm.com>
+ : Prasanna S Panchamukhi <prasanna.panchamukhi@gmail.com>
+ : Masami Hiramatsu <mhiramat@redhat.com>
CONTENTS
@@ -15,6 +16,7 @@ CONTENTS
9. Jprobes Example
10. Kretprobes Example
Appendix A: The kprobes debugfs interface
+Appendix B: The kprobes sysctl interface
1. Concepts: Kprobes, Jprobes, Return Probes
@@ -42,13 +44,13 @@ registration/unregistration of a group of *probes. These functions
can speed up unregistration process when you have to unregister
a lot of probes at once.
-The next three subsections explain how the different types of
-probes work. They explain certain things that you'll need to
-know in order to make the best use of Kprobes -- e.g., the
-difference between a pre_handler and a post_handler, and how
-to use the maxactive and nmissed fields of a kretprobe. But
-if you're in a hurry to start using Kprobes, you can skip ahead
-to section 2.
+The next four subsections explain how the different types of
+probes work and how jump optimization works. They explain certain
+things that you'll need to know in order to make the best use of
+Kprobes -- e.g., the difference between a pre_handler and
+a post_handler, and how to use the maxactive and nmissed fields of
+a kretprobe. But if you're in a hurry to start using Kprobes, you
+can skip ahead to section 2.
1.1 How Does a Kprobe Work?
@@ -161,13 +163,125 @@ In case probed function is entered but there is no kretprobe_instance
object available, then in addition to incrementing the nmissed count,
the user entry_handler invocation is also skipped.
+1.4 How Does Jump Optimization Work?
+
+If you configured your kernel with CONFIG_OPTPROBES=y (currently
+this option is supported on x86/x86-64, non-preemptive kernel) and
+the "debug.kprobes_optimization" kernel parameter is set to 1 (see
+sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
+instruction instead of a breakpoint instruction at each probepoint.
+
+1.4.1 Init a Kprobe
+
+When a probe is registered, before attempting this optimization,
+Kprobes inserts an ordinary, breakpoint-based kprobe at the specified
+address. So, even if it's not possible to optimize this particular
+probepoint, there'll be a probe there.
+
+1.4.2 Safety Check
+
+Before optimizing a probe, Kprobes performs the following safety checks:
+
+- Kprobes verifies that the region that will be replaced by the jump
+instruction (the "optimized region") lies entirely within one function.
+(A jump instruction is multiple bytes, and so may overlay multiple
+instructions.)
+
+- Kprobes analyzes the entire function and verifies that there is no
+jump into the optimized region. Specifically:
+ - the function contains no indirect jump;
+ - the function contains no instruction that causes an exception (since
+ the fixup code triggered by the exception could jump back into the
+ optimized region -- Kprobes checks the exception tables to verify this);
+ and
+ - there is no near jump to the optimized region (other than to the first
+ byte).
+
+- For each instruction in the optimized region, Kprobes verifies that
+the instruction can be executed out of line.
+
+1.4.3 Preparing Detour Buffer
+
+Next, Kprobes prepares a "detour" buffer, which contains the following
+instruction sequence:
+- code to push the CPU's registers (emulating a breakpoint trap)
+- a call to the trampoline code which calls user's probe handlers.
+- code to restore registers
+- the instructions from the optimized region
+- a jump back to the original execution path.
+
+1.4.4 Pre-optimization
+
+After preparing the detour buffer, Kprobes verifies that none of the
+following situations exist:
+- The probe has either a break_handler (i.e., it's a jprobe) or a
+post_handler.
+- Other instructions in the optimized region are probed.
+- The probe is disabled.
+In any of the above cases, Kprobes won't start optimizing the probe.
+Since these are temporary situations, Kprobes tries to start
+optimizing it again if the situation is changed.
+
+If the kprobe can be optimized, Kprobes enqueues the kprobe to an
+optimizing list, and kicks the kprobe-optimizer workqueue to optimize
+it. If the to-be-optimized probepoint is hit before being optimized,
+Kprobes returns control to the original instruction path by setting
+the CPU's instruction pointer to the copied code in the detour buffer
+-- thus at least avoiding the single-step.
+
+1.4.5 Optimization
+
+The Kprobe-optimizer doesn't insert the jump instruction immediately;
+rather, it calls synchronize_sched() for safety first, because it's
+possible for a CPU to be interrupted in the middle of executing the
+optimized region(*). As you know, synchronize_sched() can ensure
+that all interruptions that were active when synchronize_sched()
+was called are done, but only if CONFIG_PREEMPT=n. So, this version
+of kprobe optimization supports only kernels with CONFIG_PREEMPT=n.(**)
+
+After that, the Kprobe-optimizer calls stop_machine() to replace
+the optimized region with a jump instruction to the detour buffer,
+using text_poke_smp().
+
+1.4.6 Unoptimization
+
+When an optimized kprobe is unregistered, disabled, or blocked by
+another kprobe, it will be unoptimized. If this happens before
+the optimization is complete, the kprobe is just dequeued from the
+optimized list. If the optimization has been done, the jump is
+replaced with the original code (except for an int3 breakpoint in
+the first byte) by using text_poke_smp().
+
+(*)Please imagine that the 2nd instruction is interrupted and then
+the optimizer replaces the 2nd instruction with the jump *address*
+while the interrupt handler is running. When the interrupt
+returns to original address, there is no valid instruction,
+and it causes an unexpected result.
+
+(**)This optimization-safety checking may be replaced with the
+stop-machine method that ksplice uses for supporting a CONFIG_PREEMPT=y
+kernel.
+
+NOTE for geeks:
+The jump optimization changes the kprobe's pre_handler behavior.
+Without optimization, the pre_handler can change the kernel's execution
+path by changing regs->ip and returning 1. However, when the probe
+is optimized, that modification is ignored. Thus, if you want to
+tweak the kernel's execution path, you need to suppress optimization,
+using one of the following techniques:
+- Specify an empty function for the kprobe's post_handler or break_handler.
+ or
+- Config CONFIG_OPTPROBES=n.
+ or
+- Execute 'sysctl -w debug.kprobes_optimization=n'
+
2. Architectures Supported
Kprobes, jprobes, and return probes are implemented on the following
architectures:
-- i386
-- x86_64 (AMD-64, EM64T)
+- i386 (Supports jump optimization)
+- x86_64 (AMD-64, EM64T) (Supports jump optimization)
- ppc64
- ia64 (Does not support probes on instruction slot1.)
- sparc64 (Return probes not yet implemented.)
@@ -193,6 +307,10 @@ it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
so you can use "objdump -d -l vmlinux" to see the source-to-object
code mapping.
+If you want to reduce probing overhead, set "Kprobes jump optimization
+support" (CONFIG_OPTPROBES) to "y". You can find this option under the
+"Kprobes" line.
+
4. API Reference
The Kprobes API includes a "register" function and an "unregister"
@@ -389,7 +507,10 @@ the probe which has been registered.
Kprobes allows multiple probes at the same address. Currently,
however, there cannot be multiple jprobes on the same function at
-the same time.
+the same time. Also, a probepoint for which there is a jprobe or
+a post_handler cannot be optimized. So if you install a jprobe,
+or a kprobe with a post_handler, at an optimized probepoint, the
+probepoint will be unoptimized automatically.
In general, you can install a probe anywhere in the kernel.
In particular, you can probe interrupt handlers. Known exceptions
@@ -453,6 +574,38 @@ reason, Kprobes doesn't support return probes (or kprobes or jprobes)
on the x86_64 version of __switch_to(); the registration functions
return -EINVAL.
+On x86/x86-64, since the Jump Optimization of Kprobes modifies
+instructions widely, there are some limitations to optimization. To
+explain it, we introduce some terminology. Imagine a 3-instruction
+sequence consisting of a two 2-byte instructions and one 3-byte
+instruction.
+
+ IA
+ |
+[-2][-1][0][1][2][3][4][5][6][7]
+ [ins1][ins2][ ins3 ]
+ [<- DCR ->]
+ [<- JTPR ->]
+
+ins1: 1st Instruction
+ins2: 2nd Instruction
+ins3: 3rd Instruction
+IA: Insertion Address
+JTPR: Jump Target Prohibition Region
+DCR: Detoured Code Region
+
+The instructions in DCR are copied to the out-of-line buffer
+of the kprobe, because the bytes in DCR are replaced by
+a 5-byte jump instruction. So there are several limitations.
+
+a) The instructions in DCR must be relocatable.
+b) The instructions in DCR must not include a call instruction.
+c) JTPR must not be targeted by any jump or call instruction.
+d) DCR must not straddle the border betweeen functions.
+
+Anyway, these limitations are checked by the in-kernel instruction
+decoder, so you don't need to worry about that.
+
6. Probe Overhead
On a typical CPU in use in 2005, a kprobe hit takes 0.5 to 1.0
@@ -476,6 +629,19 @@ k = 0.49 usec; j = 0.76; r = 0.80; kr = 0.82; jr = 1.07
ppc64: POWER5 (gr), 1656 MHz (SMT disabled, 1 virtual CPU per physical CPU)
k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99
+6.1 Optimized Probe Overhead
+
+Typically, an optimized kprobe hit takes 0.07 to 0.1 microseconds to
+process. Here are sample overhead figures (in usec) for x86 architectures.
+k = unoptimized kprobe, b = boosted (single-step skipped), o = optimized kprobe,
+r = unoptimized kretprobe, rb = boosted kretprobe, ro = optimized kretprobe.
+
+i386: Intel(R) Xeon(R) E5410, 2.33GHz, 4656.90 bogomips
+k = 0.80 usec; b = 0.33; o = 0.05; r = 1.10; rb = 0.61; ro = 0.33
+
+x86-64: Intel(R) Xeon(R) E5410, 2.33GHz, 4656.90 bogomips
+k = 0.99 usec; b = 0.43; o = 0.06; r = 1.24; rb = 0.68; ro = 0.30
+
7. TODO
a. SystemTap (http://sourceware.org/systemtap): Provides a simplified
@@ -523,7 +689,8 @@ is also specified. Following columns show probe status. If the probe is on
a virtual address that is no longer valid (module init sections, module
virtual addresses that correspond to modules that've been unloaded),
such probes are marked with [GONE]. If the probe is temporarily disabled,
-such probes are marked with [DISABLED].
+such probes are marked with [DISABLED]. If the probe is optimized, it is
+marked with [OPTIMIZED].
/sys/kernel/debug/kprobes/enabled: Turn kprobes ON/OFF forcibly.
@@ -533,3 +700,19 @@ registered probes will be disarmed, till such time a "1" is echoed to this
file. Note that this knob just disarms and arms all kprobes and doesn't
change each probe's disabling state. This means that disabled kprobes (marked
[DISABLED]) will be not enabled if you turn ON all kprobes by this knob.
+
+
+Appendix B: The kprobes sysctl interface
+
+/proc/sys/debug/kprobes-optimization: Turn kprobes optimization ON/OFF.
+
+When CONFIG_OPTPROBES=y, this sysctl interface appears and it provides
+a knob to globally and forcibly turn jump optimization (see section
+1.4) ON or OFF. By default, jump optimization is allowed (ON).
+If you echo "0" to this file or set "debug.kprobes_optimization" to
+0 via sysctl, all optimized probes will be unoptimized, and any new
+probes registered after that will not be optimized. Note that this
+knob *changes* the optimized state. This means that optimized probes
+(marked [OPTIMIZED]) will be unoptimized ([OPTIMIZED] tag will be
+removed). If the knob is turned on, they will be optimized again.
+
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index 2811e452f75..c6416a39816 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -23,12 +23,12 @@ of a virtual machine. The ioctls belong to three classes
Only run vcpu ioctls from the same thread that was used to create the
vcpu.
-2. File descritpors
+2. File descriptors
The kvm API is centered around file descriptors. An initial
open("/dev/kvm") obtains a handle to the kvm subsystem; this handle
can be used to issue system ioctls. A KVM_CREATE_VM ioctl on this
-handle will create a VM file descripror which can be used to issue VM
+handle will create a VM file descriptor which can be used to issue VM
ioctls. A KVM_CREATE_VCPU ioctl on a VM fd will create a virtual cpu
and return a file descriptor pointing to it. Finally, ioctls on a vcpu
fd can be used to control the vcpu, including the important task of
@@ -643,7 +643,7 @@ Type: vm ioctl
Parameters: struct kvm_clock_data (in)
Returns: 0 on success, -1 on error
-Sets the current timestamp of kvmclock to the valued specific in its parameter.
+Sets the current timestamp of kvmclock to the value specified in its parameter.
In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
such as migration.
@@ -795,11 +795,11 @@ Unused.
__u64 data_offset; /* relative to kvm_run start */
} io;
-If exit_reason is KVM_EXIT_IO_IN or KVM_EXIT_IO_OUT, then the vcpu has
+If exit_reason is KVM_EXIT_IO, then the vcpu has
executed a port I/O instruction which could not be satisfied by kvm.
data_offset describes where the data is located (KVM_EXIT_IO_OUT) or
where kvm expects application code to place the data for the next
-KVM_RUN invocation (KVM_EXIT_IO_IN). Data format is a patcked array.
+KVM_RUN invocation (KVM_EXIT_IO_IN). Data format is a packed array.
struct {
struct kvm_debug_exit_arch arch;
@@ -815,7 +815,7 @@ Unused.
__u8 is_write;
} mmio;
-If exit_reason is KVM_EXIT_MMIO or KVM_EXIT_IO_OUT, then the vcpu has
+If exit_reason is KVM_EXIT_MMIO, then the vcpu has
executed a memory-mapped I/O instruction which could not be satisfied
by kvm. The 'data' member contains the written data if 'is_write' is
true, and should be filled by application code otherwise.
diff --git a/Documentation/laptops/00-INDEX b/Documentation/laptops/00-INDEX
index ee5692b26dd..fa688538e75 100644
--- a/Documentation/laptops/00-INDEX
+++ b/Documentation/laptops/00-INDEX
@@ -2,6 +2,12 @@
- This file
acer-wmi.txt
- information on the Acer Laptop WMI Extras driver.
+asus-laptop.txt
+ - information on the Asus Laptop Extras driver.
+disk-shock-protection.txt
+ - information on hard disk shock protection.
+dslm.c
+ - Simple Disk Sleep Monitor program
laptop-mode.txt
- how to conserve battery power using laptop-mode.
sony-laptop.txt
diff --git a/Documentation/laptops/Makefile b/Documentation/laptops/Makefile
new file mode 100644
index 00000000000..5cb144af3c0
--- /dev/null
+++ b/Documentation/laptops/Makefile
@@ -0,0 +1,8 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+# List of programs to build
+hostprogs-y := dslm
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff --git a/Documentation/laptops/dslm.c b/Documentation/laptops/dslm.c
new file mode 100644
index 00000000000..72ff290c5fc
--- /dev/null
+++ b/Documentation/laptops/dslm.c
@@ -0,0 +1,166 @@
+/*
+ * dslm.c
+ * Simple Disk Sleep Monitor
+ * by Bartek Kania
+ * Licenced under the GPL
+ */
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <linux/hdreg.h>
+
+#ifdef DEBUG
+#define D(x) x
+#else
+#define D(x)
+#endif
+
+int endit = 0;
+
+/* Check if the disk is in powersave-mode
+ * Most of the code is stolen from hdparm.
+ * 1 = active, 0 = standby/sleep, -1 = unknown */
+static int check_powermode(int fd)
+{
+ unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
+ int state;
+
+ if (ioctl(fd, HDIO_DRIVE_CMD, &args)
+ && (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
+ && ioctl(fd, HDIO_DRIVE_CMD, &args)) {
+ if (errno != EIO || args[0] != 0 || args[1] != 0) {
+ state = -1; /* "unknown"; */
+ } else
+ state = 0; /* "sleeping"; */
+ } else {
+ state = (args[2] == 255) ? 1 : 0;
+ }
+ D(printf(" drive state is: %d\n", state));
+
+ return state;
+}
+
+static char *state_name(int i)
+{
+ if (i == -1) return "unknown";
+ if (i == 0) return "sleeping";
+ if (i == 1) return "active";
+
+ return "internal error";
+}
+
+static char *myctime(time_t time)
+{
+ char *ts = ctime(&time);
+ ts[strlen(ts) - 1] = 0;
+
+ return ts;
+}
+
+static void measure(int fd)
+{
+ time_t start_time;
+ int last_state;
+ time_t last_time;
+ int curr_state;
+ time_t curr_time = 0;
+ time_t time_diff;
+ time_t active_time = 0;
+ time_t sleep_time = 0;
+ time_t unknown_time = 0;
+ time_t total_time = 0;
+ int changes = 0;
+ float tmp;
+
+ printf("Starting measurements\n");
+
+ last_state = check_powermode(fd);
+ start_time = last_time = time(0);
+ printf(" System is in state %s\n\n", state_name(last_state));
+
+ while(!endit) {
+ sleep(1);
+ curr_state = check_powermode(fd);
+
+ if (curr_state != last_state || endit) {
+ changes++;
+ curr_time = time(0);
+ time_diff = curr_time - last_time;
+
+ if (last_state == 1) active_time += time_diff;
+ else if (last_state == 0) sleep_time += time_diff;
+ else unknown_time += time_diff;
+
+ last_state = curr_state;
+ last_time = curr_time;
+
+ printf("%s: State-change to %s\n", myctime(curr_time),
+ state_name(curr_state));
+ }
+ }
+ changes--; /* Compensate for SIGINT */
+
+ total_time = time(0) - start_time;
+ printf("\nTotal running time: %lus\n", curr_time - start_time);
+ printf(" State changed %d times\n", changes);
+
+ tmp = (float)sleep_time / (float)total_time * 100;
+ printf(" Time in sleep state: %lus (%.2f%%)\n", sleep_time, tmp);
+ tmp = (float)active_time / (float)total_time * 100;
+ printf(" Time in active state: %lus (%.2f%%)\n", active_time, tmp);
+ tmp = (float)unknown_time / (float)total_time * 100;
+ printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
+}
+
+static void ender(int s)
+{
+ endit = 1;
+}
+
+static void usage(void)
+{
+ puts("usage: dslm [-w <time>] <disk>");
+ exit(0);
+}
+
+int main(int argc, char **argv)
+{
+ int fd;
+ char *disk = 0;
+ int settle_time = 60;
+
+ /* Parse the simple command-line */
+ if (argc == 2)
+ disk = argv[1];
+ else if (argc == 4) {
+ settle_time = atoi(argv[2]);
+ disk = argv[3];
+ } else
+ usage();
+
+ if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
+ printf("Can't open %s, because: %s\n", disk, strerror(errno));
+ exit(-1);
+ }
+
+ if (settle_time) {
+ printf("Waiting %d seconds for the system to settle down to "
+ "'normal'\n", settle_time);
+ sleep(settle_time);
+ } else
+ puts("Not waiting for system to settle down");
+
+ signal(SIGINT, ender);
+
+ measure(fd);
+
+ close(fd);
+
+ return 0;
+}
diff --git a/Documentation/laptops/laptop-mode.txt b/Documentation/laptops/laptop-mode.txt
index eeedee11c8c..2c3c3509302 100644
--- a/Documentation/laptops/laptop-mode.txt
+++ b/Documentation/laptops/laptop-mode.txt
@@ -779,172 +779,4 @@ Monitoring tool
---------------
Bartek Kania submitted this, it can be used to measure how much time your disk
-spends spun up/down.
-
----------------------------dslm.c BEGIN-----------------------------------------
-/*
- * Simple Disk Sleep Monitor
- * by Bartek Kania
- * Licenced under the GPL
- */
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <linux/hdreg.h>
-
-#ifdef DEBUG
-#define D(x) x
-#else
-#define D(x)
-#endif
-
-int endit = 0;
-
-/* Check if the disk is in powersave-mode
- * Most of the code is stolen from hdparm.
- * 1 = active, 0 = standby/sleep, -1 = unknown */
-int check_powermode(int fd)
-{
- unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
- int state;
-
- if (ioctl(fd, HDIO_DRIVE_CMD, &args)
- && (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
- && ioctl(fd, HDIO_DRIVE_CMD, &args)) {
- if (errno != EIO || args[0] != 0 || args[1] != 0) {
- state = -1; /* "unknown"; */
- } else
- state = 0; /* "sleeping"; */
- } else {
- state = (args[2] == 255) ? 1 : 0;
- }
- D(printf(" drive state is: %d\n", state));
-
- return state;
-}
-
-char *state_name(int i)
-{
- if (i == -1) return "unknown";
- if (i == 0) return "sleeping";
- if (i == 1) return "active";
-
- return "internal error";
-}
-
-char *myctime(time_t time)
-{
- char *ts = ctime(&time);
- ts[strlen(ts) - 1] = 0;
-
- return ts;
-}
-
-void measure(int fd)
-{
- time_t start_time;
- int last_state;
- time_t last_time;
- int curr_state;
- time_t curr_time = 0;
- time_t time_diff;
- time_t active_time = 0;
- time_t sleep_time = 0;
- time_t unknown_time = 0;
- time_t total_time = 0;
- int changes = 0;
- float tmp;
-
- printf("Starting measurements\n");
-
- last_state = check_powermode(fd);
- start_time = last_time = time(0);
- printf(" System is in state %s\n\n", state_name(last_state));
-
- while(!endit) {
- sleep(1);
- curr_state = check_powermode(fd);
-
- if (curr_state != last_state || endit) {
- changes++;
- curr_time = time(0);
- time_diff = curr_time - last_time;
-
- if (last_state == 1) active_time += time_diff;
- else if (last_state == 0) sleep_time += time_diff;
- else unknown_time += time_diff;
-
- last_state = curr_state;
- last_time = curr_time;
-
- printf("%s: State-change to %s\n", myctime(curr_time),
- state_name(curr_state));
- }
- }
- changes--; /* Compensate for SIGINT */
-
- total_time = time(0) - start_time;
- printf("\nTotal running time: %lus\n", curr_time - start_time);
- printf(" State changed %d times\n", changes);
-
- tmp = (float)sleep_time / (float)total_time * 100;
- printf(" Time in sleep state: %lus (%.2f%%)\n", sleep_time, tmp);
- tmp = (float)active_time / (float)total_time * 100;
- printf(" Time in active state: %lus (%.2f%%)\n", active_time, tmp);
- tmp = (float)unknown_time / (float)total_time * 100;
- printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
-}
-
-void ender(int s)
-{
- endit = 1;
-}
-
-void usage()
-{
- puts("usage: dslm [-w <time>] <disk>");
- exit(0);
-}
-
-int main(int argc, char **argv)
-{
- int fd;
- char *disk = 0;
- int settle_time = 60;
-
- /* Parse the simple command-line */
- if (argc == 2)
- disk = argv[1];
- else if (argc == 4) {
- settle_time = atoi(argv[2]);
- disk = argv[3];
- } else
- usage();
-
- if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
- printf("Can't open %s, because: %s\n", disk, strerror(errno));
- exit(-1);
- }
-
- if (settle_time) {
- printf("Waiting %d seconds for the system to settle down to "
- "'normal'\n", settle_time);
- sleep(settle_time);
- } else
- puts("Not waiting for system to settle down");
-
- signal(SIGINT, ender);
-
- measure(fd);
-
- close(fd);
-
- return 0;
-}
----------------------------dslm.c END-------------------------------------------
+spends spun up/down. See Documentation/laptops/dslm.c
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 7f5809eddee..631ad2f1b22 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -3,6 +3,7 @@
============================
By: David Howells <dhowells@redhat.com>
+ Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Contents:
@@ -60,6 +61,10 @@ Contents:
- And then there's the Alpha.
+ (*) Example uses.
+
+ - Circular buffers.
+
(*) References.
@@ -2226,6 +2231,21 @@ The Alpha defines the Linux kernel's memory barrier model.
See the subsection on "Cache Coherency" above.
+============
+EXAMPLE USES
+============
+
+CIRCULAR BUFFERS
+----------------
+
+Memory barriers can be used to implement circular buffering without the need
+of a lock to serialise the producer with the consumer. See:
+
+ Documentation/circular-buffers.txt
+
+for details.
+
+
==========
REFERENCES
==========
diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile
index 6d8af1ac56c..5aba7a33aee 100644
--- a/Documentation/networking/Makefile
+++ b/Documentation/networking/Makefile
@@ -6,3 +6,5 @@ hostprogs-y := ifenslave
# Tell kbuild to always build the programs
always := $(hostprogs-y)
+
+obj-m := timestamping/
diff --git a/Documentation/networking/skfp.txt b/Documentation/networking/skfp.txt
index abfddf81e34..203ec66c9fb 100644
--- a/Documentation/networking/skfp.txt
+++ b/Documentation/networking/skfp.txt
@@ -68,7 +68,7 @@ Compaq adapters (not tested):
=======================
From v2.01 on, the driver is integrated in the linux kernel sources.
-Therefor, the installation is the same as for any other adapter
+Therefore, the installation is the same as for any other adapter
supported by the kernel.
Refer to the manual of your distribution about the installation
of network adapters.
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
new file mode 100644
index 00000000000..7ee770b5ef5
--- /dev/null
+++ b/Documentation/networking/stmmac.txt
@@ -0,0 +1,143 @@
+ STMicroelectronics 10/100/1000 Synopsys Ethernet driver
+
+Copyright (C) 2007-2010 STMicroelectronics Ltd
+Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+
+This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers
+(Synopsys IP blocks); it has been fully tested on STLinux platforms.
+
+Currently this network device driver is for all STM embedded MAC/GMAC
+(7xxx SoCs).
+
+DWC Ether MAC 10/100/1000 Universal version 3.41a and DWC Ether MAC 10/100
+Universal version 4.0 have been used for developing the first code
+implementation.
+
+Please, for more information also visit: www.stlinux.com
+
+1) Kernel Configuration
+The kernel configuration option is STMMAC_ETH:
+ Device Drivers ---> Network device support ---> Ethernet (1000 Mbit) --->
+ STMicroelectronics 10/100/1000 Ethernet driver (STMMAC_ETH)
+
+2) Driver parameters list:
+ debug: message level (0: no output, 16: all);
+ phyaddr: to manually provide the physical address to the PHY device;
+ dma_rxsize: DMA rx ring size;
+ dma_txsize: DMA tx ring size;
+ buf_sz: DMA buffer size;
+ tc: control the HW FIFO threshold;
+ tx_coe: Enable/Disable Tx Checksum Offload engine;
+ watchdog: transmit timeout (in milliseconds);
+ flow_ctrl: Flow control ability [on/off];
+ pause: Flow Control Pause Time;
+ tmrate: timer period (only if timer optimisation is configured).
+
+3) Command line options
+Driver parameters can be also passed in command line by using:
+ stmmaceth=dma_rxsize:128,dma_txsize:512
+
+4) Driver information and notes
+
+4.1) Transmit process
+The xmit method is invoked when the kernel needs to transmit a packet; it sets
+the descriptors in the ring and informs the DMA engine that there is a packet
+ready to be transmitted.
+Once the controller has finished transmitting the packet, an interrupt is
+triggered; So the driver will be able to release the socket buffers.
+By default, the driver sets the NETIF_F_SG bit in the features field of the
+net_device structure enabling the scatter/gather feature.
+
+4.2) Receive process
+When one or more packets are received, an interrupt happens. The interrupts
+are not queued so the driver has to scan all the descriptors in the ring during
+the receive process.
+This is based on NAPI so the interrupt handler signals only if there is work to be
+done, and it exits.
+Then the poll method will be scheduled at some future point.
+The incoming packets are stored, by the DMA, in a list of pre-allocated socket
+buffers in order to avoid the memcpy (Zero-copy).
+
+4.3) Timer-Driver Interrupt
+Instead of having the device that asynchronously notifies the frame receptions, the
+driver configures a timer to generate an interrupt at regular intervals.
+Based on the granularity of the timer, the frames that are received by the device
+will experience different levels of latency. Some NICs have dedicated timer
+device to perform this task. STMMAC can use either the RTC device or the TMU
+channel 2 on STLinux platforms.
+The timers frequency can be passed to the driver as parameter; when change it,
+take care of both hardware capability and network stability/performance impact.
+Several performance tests on STM platforms showed this optimisation allows to spare
+the CPU while having the maximum throughput.
+
+4.4) WOL
+Wake up on Lan feature through Magic Frame is only supported for the GMAC
+core.
+
+4.5) DMA descriptors
+Driver handles both normal and enhanced descriptors. The latter has been only
+tested on DWC Ether MAC 10/100/1000 Universal version 3.41a.
+
+4.6) Ethtool support
+Ethtool is supported. Driver statistics and internal errors can be taken using:
+ethtool -S ethX command. It is possible to dump registers etc.
+
+4.7) Jumbo and Segmentation Offloading
+Jumbo frames are supported and tested for the GMAC.
+The GSO has been also added but it's performed in software.
+LRO is not supported.
+
+4.8) Physical
+The driver is compatible with PAL to work with PHY and GPHY devices.
+
+4.9) Platform information
+Several information came from the platform; please refer to the
+driver's Header file in include/linux directory.
+
+struct plat_stmmacenet_data {
+ int bus_id;
+ int pbl;
+ int has_gmac;
+ void (*fix_mac_speed)(void *priv, unsigned int speed);
+ void (*bus_setup)(unsigned long ioaddr);
+#ifdef CONFIG_STM_DRIVERS
+ struct stm_pad_config *pad_config;
+#endif
+ void *bsp_priv;
+};
+
+Where:
+- pbl (Programmable Burst Length) is maximum number of
+ beats to be transferred in one DMA transaction.
+ GMAC also enables the 4xPBL by default.
+- fix_mac_speed and bus_setup are used to configure internal target
+ registers (on STM platforms);
+- has_gmac: GMAC core is on board (get it at run-time in the next step);
+- bus_id: bus identifier.
+
+struct plat_stmmacphy_data {
+ int bus_id;
+ int phy_addr;
+ unsigned int phy_mask;
+ int interface;
+ int (*phy_reset)(void *priv);
+ void *priv;
+};
+
+Where:
+- bus_id: bus identifier;
+- phy_addr: physical address used for the attached phy device;
+ set it to -1 to get it at run-time;
+- interface: physical MII interface mode;
+- phy_reset: hook to reset HW function.
+
+TODO:
+- Continue to make the driver more generic and suitable for other Synopsys
+ Ethernet controllers used on other architectures (i.e. ARM).
+- 10G controllers are not supported.
+- MAC uses Normal descriptors and GMAC uses enhanced ones.
+ This is a limit that should be reviewed. MAC could want to
+ use the enhanced structure.
+- Checksumming: Rx/Tx csum is done in HW in case of GMAC only.
+- Review the timer optimisation code to use an embedded device that seems to be
+ available in new chip generations.
diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt
index 0e58b453917..e8c8f4f06c6 100644
--- a/Documentation/networking/timestamping.txt
+++ b/Documentation/networking/timestamping.txt
@@ -41,11 +41,12 @@ SOF_TIMESTAMPING_SOFTWARE: return system time stamp generated in
SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
following control message:
- struct scm_timestamping {
- struct timespec systime;
- struct timespec hwtimetrans;
- struct timespec hwtimeraw;
- };
+
+struct scm_timestamping {
+ struct timespec systime;
+ struct timespec hwtimetrans;
+ struct timespec hwtimeraw;
+};
recvmsg() can be used to get this control message for regular incoming
packets. For send time stamps the outgoing packet is looped back to
@@ -87,12 +88,13 @@ by the network device and will be empty without that support.
SIOCSHWTSTAMP:
Hardware time stamping must also be initialized for each device driver
-that is expected to do hardware time stamping. The parameter is:
+that is expected to do hardware time stamping. The parameter is defined in
+/include/linux/net_tstamp.h as:
struct hwtstamp_config {
- int flags; /* no flags defined right now, must be zero */
- int tx_type; /* HWTSTAMP_TX_* */
- int rx_filter; /* HWTSTAMP_FILTER_* */
+ int flags; /* no flags defined right now, must be zero */
+ int tx_type; /* HWTSTAMP_TX_* */
+ int rx_filter; /* HWTSTAMP_FILTER_* */
};
Desired behavior is passed into the kernel and to a specific device by
@@ -139,42 +141,56 @@ enum {
/* time stamp any incoming packet */
HWTSTAMP_FILTER_ALL,
- /* return value: time stamp all packets requested plus some others */
- HWTSTAMP_FILTER_SOME,
+ /* return value: time stamp all packets requested plus some others */
+ HWTSTAMP_FILTER_SOME,
/* PTP v1, UDP, any kind of event packet */
HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
- ...
+ /* for the complete list of values, please check
+ * the include file /include/linux/net_tstamp.h
+ */
};
DEVICE IMPLEMENTATION
A driver which supports hardware time stamping must support the
-SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
-in the skb with skb_hwtstamp_set().
+SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
+the actual values as described in the section on SIOCSHWTSTAMP.
+
+Time stamps for received packets must be stored in the skb. To get a pointer
+to the shared time stamp structure of the skb call skb_hwtstamps(). Then
+set the time stamps in the structure:
+
+struct skb_shared_hwtstamps {
+ /* hardware time stamp transformed into duration
+ * since arbitrary point in time
+ */
+ ktime_t hwtstamp;
+ ktime_t syststamp; /* hwtstamp transformed to system time base */
+};
Time stamps for outgoing packets are to be generated as follows:
-- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
- returns non-zero. If yes, then the driver is expected
- to do hardware time stamping.
+- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
+ If yes, then the driver is expected to do hardware time stamping.
- If this is possible for the skb and requested, then declare
- that the driver is doing the time stamping by calling
- skb_hwtstamp_tx_in_progress(). A driver not supporting
- hardware time stamping doesn't do that. A driver must never
- touch sk_buff::tstamp! It is used to store how time stamping
- for an outgoing packets is to be done.
+ that the driver is doing the time stamping by setting the field
+ skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
+ to the associated skb for the next step and not free the skb. A driver
+ not supporting hardware time stamping doesn't do that. A driver must
+ never touch sk_buff::tstamp! It is used to store software generated
+ time stamps by the network subsystem.
- As soon as the driver has sent the packet and/or obtained a
hardware time stamp for it, it passes the time stamp back by
calling skb_hwtstamp_tx() with the original skb, the raw
- hardware time stamp and a handle to the device (necessary
- to convert the hardware time stamp to system time). If obtaining
- the hardware time stamp somehow fails, then the driver should
- not fall back to software time stamping. The rationale is that
- this would occur at a later time in the processing pipeline
- than other software time stamping and therefore could lead
- to unexpected deltas between time stamps.
-- If the driver did not call skb_hwtstamp_tx_in_progress(), then
+ hardware time stamp. skb_hwtstamp_tx() clones the original skb and
+ adds the timestamps, therefore the original skb has to be freed now.
+ If obtaining the hardware time stamp somehow fails, then the driver
+ should not fall back to software time stamping. The rationale is that
+ this would occur at a later time in the processing pipeline than other
+ software time stamping and therefore could lead to unexpected deltas
+ between time stamps.
+- If the driver did not call set skb_tx(skb)->in_progress, then
dev_hard_start_xmit() checks whether software time stamping
is wanted as fallback and potentially generates the time stamp.
diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile
index 2a1489fdc03..e79973443e9 100644
--- a/Documentation/networking/timestamping/Makefile
+++ b/Documentation/networking/timestamping/Makefile
@@ -1,6 +1,13 @@
-CPPFLAGS = -I../../../include
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
-timestamping: timestamping.c
+# List of programs to build
+hostprogs-y := timestamping
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
+
+HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
clean:
rm -f timestamping
diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
index a7936fe8444..8ba82bfe6a3 100644
--- a/Documentation/networking/timestamping/timestamping.c
+++ b/Documentation/networking/timestamping/timestamping.c
@@ -41,9 +41,9 @@
#include <arpa/inet.h>
#include <net/if.h>
-#include "asm/types.h"
-#include "linux/net_tstamp.h"
-#include "linux/errqueue.h"
+#include <asm/types.h>
+#include <linux/net_tstamp.h>
+#include <linux/errqueue.h>
#ifndef SO_TIMESTAMPING
# define SO_TIMESTAMPING 37
@@ -164,7 +164,7 @@ static void printpacket(struct msghdr *msg, int res,
gettimeofday(&now, 0);
- printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n",
+ printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n",
(long)now.tv_sec, (long)now.tv_usec,
(recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
res,
@@ -173,7 +173,7 @@ static void printpacket(struct msghdr *msg, int res,
for (cmsg = CMSG_FIRSTHDR(msg);
cmsg;
cmsg = CMSG_NXTHDR(msg, cmsg)) {
- printf(" cmsg len %d: ", cmsg->cmsg_len);
+ printf(" cmsg len %zu: ", cmsg->cmsg_len);
switch (cmsg->cmsg_level) {
case SOL_SOCKET:
printf("SOL_SOCKET ");
@@ -370,7 +370,7 @@ int main(int argc, char **argv)
}
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (socket < 0)
+ if (sock < 0)
bail("socket");
memset(&device, 0, sizeof(device));
diff --git a/Documentation/pnp.txt b/Documentation/pnp.txt
index a327db67782..763e4659bf1 100644
--- a/Documentation/pnp.txt
+++ b/Documentation/pnp.txt
@@ -57,7 +57,7 @@ PC standard floppy disk controller
# cat resources
DISABLED
-- Notice the string "DISABLED". THis means the device is not active.
+- Notice the string "DISABLED". This means the device is not active.
3.) check the device's possible configurations (optional)
# cat options
@@ -139,7 +139,7 @@ Plug and Play but it is planned to be in the near future.
Requirements for a Linux PnP protocol:
1.) the protocol must use EISA IDs
-2.) the protocol must inform the PnP Layer of a devices current configuration
+2.) the protocol must inform the PnP Layer of a device's current configuration
- the ability to set resources is optional but preferred.
The following are PnP protocol related functions:
@@ -158,7 +158,7 @@ pnp_remove_device
- automatically will free mem used by the device and related structures
pnp_add_id
-- adds a EISA ID to the list of supported IDs for the specified device
+- adds an EISA ID to the list of supported IDs for the specified device
For more information consult the source of a protocol such as
/drivers/pnp/pnpbios/core.c.
@@ -167,7 +167,7 @@ For more information consult the source of a protocol such as
Linux Plug and Play Drivers
---------------------------
- This section contains information for linux PnP driver developers.
+ This section contains information for Linux PnP driver developers.
The New Way
...........
@@ -235,11 +235,10 @@ static int __init serial8250_pnp_init(void)
The Old Way
...........
-a series of compatibility functions have been created to make it easy to convert
-
+A series of compatibility functions have been created to make it easy to convert
ISAPNP drivers. They should serve as a temporary solution only.
-they are as follows:
+They are as follows:
struct pnp_card *pnp_find_card(unsigned short vendor,
unsigned short device,
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 356fd86f4ea..55b859b3bc7 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -224,6 +224,12 @@ defined in include/linux/pm.h:
RPM_SUSPENDED, which means that each device is initially regarded by the
PM core as 'suspended', regardless of its real hardware status
+ unsigned int runtime_auto;
+ - if set, indicates that the user space has allowed the device driver to
+ power manage the device at run time via the /sys/devices/.../power/control
+ interface; it may only be modified with the help of the pm_runtime_allow()
+ and pm_runtime_forbid() helper functions
+
All of the above fields are members of the 'power' member of 'struct device'.
4. Run-time PM Device Helper Functions
@@ -250,7 +256,7 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
to suspend the device again in future
int pm_runtime_resume(struct device *dev);
- - execute the subsystem-leve resume callback for the device; returns 0 on
+ - execute the subsystem-level resume callback for the device; returns 0 on
success, 1 if the device's run-time PM status was already 'active' or
error code on failure, where -EAGAIN means it may be safe to attempt to
resume the device again in future, but 'power.runtime_error' should be
@@ -329,6 +335,20 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
'power.runtime_error' is set or 'power.disable_depth' is greater than
zero)
+ bool pm_runtime_suspended(struct device *dev);
+ - return true if the device's runtime PM status is 'suspended', or false
+ otherwise
+
+ void pm_runtime_allow(struct device *dev);
+ - set the power.runtime_auto flag for the device and decrease its usage
+ counter (used by the /sys/devices/.../power/control interface to
+ effectively allow the device to be power managed at run time)
+
+ void pm_runtime_forbid(struct device *dev);
+ - unset the power.runtime_auto flag for the device and increase its usage
+ counter (used by the /sys/devices/.../power/control interface to
+ effectively prevent the device from being power managed at run time)
+
It is safe to execute the following helper functions from interrupt context:
pm_request_idle()
@@ -382,6 +402,18 @@ may be desirable to suspend the device as soon as ->probe() or ->remove() has
finished, so the PM core uses pm_runtime_idle_sync() to invoke the
subsystem-level idle callback for the device at that time.
+The user space can effectively disallow the driver of the device to power manage
+it at run time by changing the value of its /sys/devices/.../power/control
+attribute to "on", which causes pm_runtime_forbid() to be called. In principle,
+this mechanism may also be used by the driver to effectively turn off the
+run-time power management of the device until the user space turns it on.
+Namely, during the initialization the driver can make sure that the run-time PM
+status of the device is 'active' and call pm_runtime_forbid(). It should be
+noted, however, that if the user space has already intentionally changed the
+value of /sys/devices/.../power/control to "auto" to allow the driver to power
+manage the device at run time, the driver may confuse it by using
+pm_runtime_forbid() this way.
+
6. Run-time PM and System Sleep
Run-time PM and system sleep (i.e., system suspend and hibernation, also known
@@ -431,3 +463,64 @@ The PM core always increments the run-time usage counter before calling the
->prepare() callback and decrements it after calling the ->complete() callback.
Hence disabling run-time PM temporarily like this will not cause any run-time
suspend callbacks to be lost.
+
+7. Generic subsystem callbacks
+
+Subsystems may wish to conserve code space by using the set of generic power
+management callbacks provided by the PM core, defined in
+driver/base/power/generic_ops.c:
+
+ int pm_generic_runtime_idle(struct device *dev);
+ - invoke the ->runtime_idle() callback provided by the driver of this
+ device, if defined, and call pm_runtime_suspend() for this device if the
+ return value is 0 or the callback is not defined
+
+ int pm_generic_runtime_suspend(struct device *dev);
+ - invoke the ->runtime_suspend() callback provided by the driver of this
+ device and return its result, or return -EINVAL if not defined
+
+ int pm_generic_runtime_resume(struct device *dev);
+ - invoke the ->runtime_resume() callback provided by the driver of this
+ device and return its result, or return -EINVAL if not defined
+
+ int pm_generic_suspend(struct device *dev);
+ - if the device has not been suspended at run time, invoke the ->suspend()
+ callback provided by its driver and return its result, or return 0 if not
+ defined
+
+ int pm_generic_resume(struct device *dev);
+ - invoke the ->resume() callback provided by the driver of this device and,
+ if successful, change the device's runtime PM status to 'active'
+
+ int pm_generic_freeze(struct device *dev);
+ - if the device has not been suspended at run time, invoke the ->freeze()
+ callback provided by its driver and return its result, or return 0 if not
+ defined
+
+ int pm_generic_thaw(struct device *dev);
+ - if the device has not been suspended at run time, invoke the ->thaw()
+ callback provided by its driver and return its result, or return 0 if not
+ defined
+
+ int pm_generic_poweroff(struct device *dev);
+ - if the device has not been suspended at run time, invoke the ->poweroff()
+ callback provided by its driver and return its result, or return 0 if not
+ defined
+
+ int pm_generic_restore(struct device *dev);
+ - invoke the ->restore() callback provided by the driver of this device and,
+ if successful, change the device's runtime PM status to 'active'
+
+These functions can be assigned to the ->runtime_idle(), ->runtime_suspend(),
+->runtime_resume(), ->suspend(), ->resume(), ->freeze(), ->thaw(), ->poweroff(),
+or ->restore() callback pointers in the subsystem-level dev_pm_ops structures.
+
+If a subsystem wishes to use all of them at the same time, it can simply assign
+the GENERIC_SUBSYS_PM_OPS macro, defined in include/linux/pm.h, to its
+dev_pm_ops structure pointer.
+
+Device drivers that wish to use the same function as a system suspend, freeze,
+poweroff and run-time suspend callback, and similarly for system resume, thaw,
+restore, and run-time resume, can achieve this with the help of the
+UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its
+last argument to NULL).
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
index 6e37be1eeb2..4f8930263dd 100644
--- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
@@ -21,6 +21,15 @@ Required properties:
- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the
threads.
+Optional properties:
+- fsl,firmware-phandle:
+ Usage: required only if there is no fsl,qe-firmware child node
+ Value type: <phandle>
+ Definition: Points to a firmware node (see "QE Firmware Node" below)
+ that contains the firmware that should be uploaded for this QE.
+ The compatible property for the firmware node should say,
+ "fsl,qe-firmware".
+
Recommended properties
- brg-frequency : the internal clock source frequency for baud-rate
generators in Hz.
@@ -59,3 +68,48 @@ Example:
reg = <0 c000>;
};
};
+
+* QE Firmware Node
+
+This node defines a firmware binary that is embedded in the device tree, for
+the purpose of passing the firmware from bootloader to the kernel, or from
+the hypervisor to the guest.
+
+The firmware node itself contains the firmware binary contents, a compatible
+property, and any firmware-specific properties. The node should be placed
+inside a QE node that needs it. Doing so eliminates the need for a
+fsl,firmware-phandle property. Other QE nodes that need the same firmware
+should define an fsl,firmware-phandle property that points to the firmware node
+in the first QE node.
+
+The fsl,firmware property can be specified in the DTS (possibly using incbin)
+or can be inserted by the boot loader at boot time.
+
+Required properties:
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: A standard property. Specify a string that indicates what
+ kind of firmware it is. For QE, this should be "fsl,qe-firmware".
+
+ - fsl,firmware
+ Usage: required
+ Value type: <prop-encoded-array>, encoded as an array of bytes
+ Definition: A standard property. This property contains the firmware
+ binary "blob".
+
+Example:
+ qe1@e0080000 {
+ compatible = "fsl,qe";
+ qe_firmware:qe-firmware {
+ compatible = "fsl,qe-firmware";
+ fsl,firmware = [0x70 0xcd 0x00 0x00 0x01 0x46 0x45 ...];
+ };
+ ...
+ };
+
+ qe2@e0090000 {
+ compatible = "fsl,qe";
+ fsl,firmware-phandle = <&qe_firmware>;
+ ...
+ };
diff --git a/Documentation/powerpc/dts-bindings/fsl/i2c.txt b/Documentation/powerpc/dts-bindings/fsl/i2c.txt
index b6d2e21474f..50da2031058 100644
--- a/Documentation/powerpc/dts-bindings/fsl/i2c.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/i2c.txt
@@ -2,15 +2,14 @@
Required properties :
- - device_type : Should be "i2c"
- reg : Offset and length of the register set for the device
+ - compatible : should be "fsl,CHIP-i2c" where CHIP is the name of a
+ compatible processor, e.g. mpc8313, mpc8543, mpc8544, mpc5121,
+ mpc5200 or mpc5200b. For the mpc5121, an additional node
+ "fsl,mpc5121-i2c-ctrl" is required as shown in the example below.
Recommended properties :
- - compatible : compatibility list with 2 entries, the first should
- be "fsl,CHIP-i2c" where CHIP is the name of a compatible processor,
- e.g. mpc8313, mpc8543, mpc8544, mpc5200 or mpc5200b. The second one
- should be "fsl-i2c".
- interrupts : <a b> where a is the interrupt number and b is a
field that represents an encoding of the sense and level
information for the interrupt. This should be encoded based on
@@ -24,25 +23,40 @@ Recommended properties :
Examples :
+ /* MPC5121 based board */
+ i2c@1740 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5121-i2c", "fsl-i2c";
+ reg = <0x1740 0x20>;
+ interrupts = <11 0x8>;
+ interrupt-parent = <&ipic>;
+ clock-frequency = <100000>;
+ };
+
+ i2ccontrol@1760 {
+ compatible = "fsl,mpc5121-i2c-ctrl";
+ reg = <0x1760 0x8>;
+ };
+
+ /* MPC5200B based board */
i2c@3d00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
- cell-index = <0>;
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
interrupt-parent = <&mpc5200_pic>;
fsl,preserve-clocking;
};
+ /* MPC8544 base board */
i2c@3100 {
#address-cells = <1>;
#size-cells = <0>;
- cell-index = <1>;
compatible = "fsl,mpc8544-i2c", "fsl-i2c";
reg = <0x3100 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
clock-frequency = <400000>;
};
-
diff --git a/Documentation/s390/kvm.txt b/Documentation/s390/kvm.txt
index 6f5ceb0f09f..85f3280d7ef 100644
--- a/Documentation/s390/kvm.txt
+++ b/Documentation/s390/kvm.txt
@@ -102,7 +102,7 @@ args: unsigned long
see also: include/linux/kvm.h
This ioctl stores the state of the cpu at the guest real address given as
argument, unless one of the following values defined in include/linux/kvm.h
-is given as arguement:
+is given as argument:
KVM_S390_STORE_STATUS_NOADDR - the CPU stores its status to the save area in
absolute lowcore as defined by the principles of operation
KVM_S390_STORE_STATUS_PREFIXED - the CPU stores its status to the save area in
diff --git a/Documentation/scsi/ChangeLog.lpfc b/Documentation/scsi/ChangeLog.lpfc
index ff19a52fe00..2ffc1148eb9 100644
--- a/Documentation/scsi/ChangeLog.lpfc
+++ b/Documentation/scsi/ChangeLog.lpfc
@@ -989,8 +989,8 @@ Changes from 20040709 to 20040716
* Remove redundant port_cmp != 2 check in if
(!port_cmp) { .... if (port_cmp != 2).... }
* Clock changes: removed struct clk_data and timerList.
- * Clock changes: seperate nodev_tmo and els_retry_delay into 2
- seperate timers and convert to 1 argument changed
+ * Clock changes: separate nodev_tmo and els_retry_delay into 2
+ separate timers and convert to 1 argument changed
LPFC_NODE_FARP_PEND_t to struct lpfc_node_farp_pend convert
ipfarp_tmo to 1 argument convert target struct tmofunc and
rtplunfunc to 1 argument * cr_count, cr_delay and
@@ -1514,7 +1514,7 @@ Changes from 20040402 to 20040409
* Remove unused elxclock declaration in elx_sli.h.
* Since everywhere IOCB_ENTRY is used, the return value is cast,
move the cast into the macro.
- * Split ioctls out into seperate files
+ * Split ioctls out into separate files
Changes from 20040326 to 20040402
@@ -1534,7 +1534,7 @@ Changes from 20040326 to 20040402
* Unused variable cleanup
* Use Linux list macros for DMABUF_t
* Break up ioctls into 3 sections, dfc, util, hbaapi
- rearranged code so this could be easily seperated into a
+ rearranged code so this could be easily separated into a
differnet module later All 3 are currently turned on by
defines in lpfc_ioctl.c LPFC_DFC_IOCTL, LPFC_UTIL_IOCTL,
LPFC_HBAAPI_IOCTL
@@ -1551,7 +1551,7 @@ Changes from 20040326 to 20040402
started by lpfc_online(). lpfc_offline() only stopped
els_timeout routine. It now stops all timeout routines
associated with that hba.
- * Replace seperate next and prev pointers in struct
+ * Replace separate next and prev pointers in struct
lpfc_bindlist with list_head type. In elxHBA_t, replace
fc_nlpbind_start and _end with fc_nlpbind_list and use
list_head macros to access it.
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt
index 5e5349a4fcd..7c900507279 100644
--- a/Documentation/serial/tty.txt
+++ b/Documentation/serial/tty.txt
@@ -105,6 +105,10 @@ write_wakeup() - May be called at any point between open and close.
is permitted to call the driver write method from
this function. In such a situation defer it.
+dcd_change() - Report to the tty line the current DCD pin status
+ changes and the relative timestamp. The timestamp
+ can be NULL.
+
Driver Access
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 33df82e3a39..bfcbbf88c44 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -1812,7 +1812,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-ua101
----------------
- Module for the Edirol UA-101 audio/MIDI interface.
+ Module for the Edirol UA-101/UA-1000 audio/MIDI interfaces.
This module supports multiple devices, autoprobe and hotplugging.
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index f4dd3bf99d1..98d14cb8a85 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -119,10 +119,18 @@ the codec slots 0 and 1 no matter what the hardware reports.
Interrupt Handling
~~~~~~~~~~~~~~~~~~
-In rare but some cases, the interrupt isn't properly handled as
-default. You would notice this by the DMA transfer error reported by
-ALSA PCM core, for example. Using MSI might help in such a case.
-Pass `enable_msi=1` option for enabling MSI.
+HD-audio driver uses MSI as default (if available) since 2.6.33
+kernel as MSI works better on some machines, and in general, it's
+better for performance. However, Nvidia controllers showed bad
+regressions with MSI (especially in a combination with AMD chipset),
+thus we disabled MSI for them.
+
+There seem also still other devices that don't work with MSI. If you
+see a regression wrt the sound quality (stuttering, etc) or a lock-up
+in the recent kernel, try to pass `enable_msi=0` option to disable
+MSI. If it works, you can add the known bad device to the blacklist
+defined in hda_intel.c. In such a case, please report and give the
+patch back to the upstream developer.
HD-AUDIO CODEC
diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c
index 10abd3773e4..16feda90146 100644
--- a/Documentation/spi/spidev_test.c
+++ b/Documentation/spi/spidev_test.c
@@ -58,7 +58,7 @@ static void transfer(int fd)
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
- if (ret == 1)
+ if (ret < 1)
pabort("can't send spi message");
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt
index 5effa5bd993..e213f45cf9d 100644
--- a/Documentation/stable_kernel_rules.txt
+++ b/Documentation/stable_kernel_rules.txt
@@ -18,16 +18,15 @@ Rules on what kind of patches are accepted, and which ones are not, into the
- It cannot contain any "trivial" fixes in it (spelling changes,
whitespace cleanups, etc).
- It must follow the Documentation/SubmittingPatches rules.
- - It or an equivalent fix must already exist in Linus' tree. Quote the
- respective commit ID in Linus' tree in your patch submission to -stable.
+ - It or an equivalent fix must already exist in Linus' tree (upstream).
Procedure for submitting patches to the -stable tree:
- Send the patch, after verifying that it follows the above rules, to
- stable@kernel.org.
- - To have the patch automatically included in the stable tree, add the
- the tag
+ stable@kernel.org. You must note the upstream commit ID in the changelog
+ of your submission.
+ - To have the patch automatically included in the stable tree, add the tag
Cc: stable@kernel.org
in the sign-off area. Once the patch is merged it will be applied to
the stable tree without anything else needing to be done by the author
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index fc5790d36cd..6c7d18c53f8 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -573,11 +573,14 @@ Because other nodes' memory may be free. This means system total status
may be not fatal yet.
If this is set to 2, the kernel panics compulsorily even on the
-above-mentioned.
+above-mentioned. Even oom happens under memory cgroup, the whole
+system panics.
The default value is 0.
1 and 2 are for failover of clustering. Please select either
according to your policy of failover.
+panic_on_oom=2+kdump gives you very strong tool to investigate
+why oom happens. You can get snapshot.
=============================================================
diff --git a/Documentation/timers/00-INDEX b/Documentation/timers/00-INDEX
index 397dc35e132..a9248da5cdb 100644
--- a/Documentation/timers/00-INDEX
+++ b/Documentation/timers/00-INDEX
@@ -4,6 +4,8 @@ highres.txt
- High resolution timers and dynamic ticks design notes
hpet.txt
- High Precision Event Timer Driver for Linux
+hpet_example.c
+ - sample hpet timer test program
hrtimers.txt
- subsystem for high-resolution kernel timers
timer_stats.txt
diff --git a/Documentation/timers/Makefile b/Documentation/timers/Makefile
new file mode 100644
index 00000000000..c85625f4ab2
--- /dev/null
+++ b/Documentation/timers/Makefile
@@ -0,0 +1,8 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+# List of programs to build
+hostprogs-y := hpet_example
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff --git a/Documentation/timers/hpet.txt b/Documentation/timers/hpet.txt
index 16d25e6b5a0..767392ffd31 100644
--- a/Documentation/timers/hpet.txt
+++ b/Documentation/timers/hpet.txt
@@ -26,274 +26,5 @@ initialization. An example of this initialization can be found in
arch/x86/kernel/hpet.c.
The driver provides a userspace API which resembles the API found in the
-RTC driver framework. An example user space program is provided below.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <memory.h>
-#include <malloc.h>
-#include <time.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <linux/hpet.h>
-
-
-extern void hpet_open_close(int, const char **);
-extern void hpet_info(int, const char **);
-extern void hpet_poll(int, const char **);
-extern void hpet_fasync(int, const char **);
-extern void hpet_read(int, const char **);
-
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-
-struct hpet_command {
- char *command;
- void (*func)(int argc, const char ** argv);
-} hpet_command[] = {
- {
- "open-close",
- hpet_open_close
- },
- {
- "info",
- hpet_info
- },
- {
- "poll",
- hpet_poll
- },
- {
- "fasync",
- hpet_fasync
- },
-};
-
-int
-main(int argc, const char ** argv)
-{
- int i;
-
- argc--;
- argv++;
-
- if (!argc) {
- fprintf(stderr, "-hpet: requires command\n");
- return -1;
- }
-
-
- for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
- if (!strcmp(argv[0], hpet_command[i].command)) {
- argc--;
- argv++;
- fprintf(stderr, "-hpet: executing %s\n",
- hpet_command[i].command);
- hpet_command[i].func(argc, argv);
- return 0;
- }
-
- fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
-
- return -1;
-}
-
-void
-hpet_open_close(int argc, const char **argv)
-{
- int fd;
-
- if (argc != 1) {
- fprintf(stderr, "hpet_open_close: device-name\n");
- return;
- }
-
- fd = open(argv[0], O_RDONLY);
- if (fd < 0)
- fprintf(stderr, "hpet_open_close: open failed\n");
- else
- close(fd);
-
- return;
-}
-
-void
-hpet_info(int argc, const char **argv)
-{
-}
-
-void
-hpet_poll(int argc, const char **argv)
-{
- unsigned long freq;
- int iterations, i, fd;
- struct pollfd pfd;
- struct hpet_info info;
- struct timeval stv, etv;
- struct timezone tz;
- long usec;
-
- if (argc != 3) {
- fprintf(stderr, "hpet_poll: device-name freq iterations\n");
- return;
- }
-
- freq = atoi(argv[1]);
- iterations = atoi(argv[2]);
-
- fd = open(argv[0], O_RDONLY);
-
- if (fd < 0) {
- fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
- return;
- }
-
- if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
- fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
- goto out;
- }
-
- if (ioctl(fd, HPET_INFO, &info) < 0) {
- fprintf(stderr, "hpet_poll: failed to get info\n");
- goto out;
- }
-
- fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
-
- if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
- fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
- goto out;
- }
-
- if (ioctl(fd, HPET_IE_ON, 0) < 0) {
- fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
- goto out;
- }
-
- pfd.fd = fd;
- pfd.events = POLLIN;
-
- for (i = 0; i < iterations; i++) {
- pfd.revents = 0;
- gettimeofday(&stv, &tz);
- if (poll(&pfd, 1, -1) < 0)
- fprintf(stderr, "hpet_poll: poll failed\n");
- else {
- long data;
-
- gettimeofday(&etv, &tz);
- usec = stv.tv_sec * 1000000 + stv.tv_usec;
- usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
-
- fprintf(stderr,
- "hpet_poll: expired time = 0x%lx\n", usec);
-
- fprintf(stderr, "hpet_poll: revents = 0x%x\n",
- pfd.revents);
-
- if (read(fd, &data, sizeof(data)) != sizeof(data)) {
- fprintf(stderr, "hpet_poll: read failed\n");
- }
- else
- fprintf(stderr, "hpet_poll: data 0x%lx\n",
- data);
- }
- }
-
-out:
- close(fd);
- return;
-}
-
-static int hpet_sigio_count;
-
-static void
-hpet_sigio(int val)
-{
- fprintf(stderr, "hpet_sigio: called\n");
- hpet_sigio_count++;
-}
-
-void
-hpet_fasync(int argc, const char **argv)
-{
- unsigned long freq;
- int iterations, i, fd, value;
- sig_t oldsig;
- struct hpet_info info;
-
- hpet_sigio_count = 0;
- fd = -1;
-
- if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
- fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
- return;
- }
-
- if (argc != 3) {
- fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
- goto out;
- }
-
- fd = open(argv[0], O_RDONLY);
-
- if (fd < 0) {
- fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
- return;
- }
-
-
- if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
- ((value = fcntl(fd, F_GETFL)) == 1) ||
- (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
- fprintf(stderr, "hpet_fasync: fcntl failed\n");
- goto out;
- }
-
- freq = atoi(argv[1]);
- iterations = atoi(argv[2]);
-
- if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
- fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
- goto out;
- }
-
- if (ioctl(fd, HPET_INFO, &info) < 0) {
- fprintf(stderr, "hpet_fasync: failed to get info\n");
- goto out;
- }
-
- fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
-
- if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
- fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
- goto out;
- }
-
- if (ioctl(fd, HPET_IE_ON, 0) < 0) {
- fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
- goto out;
- }
-
- for (i = 0; i < iterations; i++) {
- (void) pause();
- fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
- }
-
-out:
- signal(SIGIO, oldsig);
-
- if (fd >= 0)
- close(fd);
-
- return;
-}
+RTC driver framework. An example user space program is provided in
+file:Documentation/timers/hpet_example.c
diff --git a/Documentation/timers/hpet_example.c b/Documentation/timers/hpet_example.c
new file mode 100644
index 00000000000..f9ce2d9fdfd
--- /dev/null
+++ b/Documentation/timers/hpet_example.c
@@ -0,0 +1,269 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <memory.h>
+#include <malloc.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <linux/hpet.h>
+
+
+extern void hpet_open_close(int, const char **);
+extern void hpet_info(int, const char **);
+extern void hpet_poll(int, const char **);
+extern void hpet_fasync(int, const char **);
+extern void hpet_read(int, const char **);
+
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+
+struct hpet_command {
+ char *command;
+ void (*func)(int argc, const char ** argv);
+} hpet_command[] = {
+ {
+ "open-close",
+ hpet_open_close
+ },
+ {
+ "info",
+ hpet_info
+ },
+ {
+ "poll",
+ hpet_poll
+ },
+ {
+ "fasync",
+ hpet_fasync
+ },
+};
+
+int
+main(int argc, const char ** argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ if (!argc) {
+ fprintf(stderr, "-hpet: requires command\n");
+ return -1;
+ }
+
+
+ for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
+ if (!strcmp(argv[0], hpet_command[i].command)) {
+ argc--;
+ argv++;
+ fprintf(stderr, "-hpet: executing %s\n",
+ hpet_command[i].command);
+ hpet_command[i].func(argc, argv);
+ return 0;
+ }
+
+ fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
+
+ return -1;
+}
+
+void
+hpet_open_close(int argc, const char **argv)
+{
+ int fd;
+
+ if (argc != 1) {
+ fprintf(stderr, "hpet_open_close: device-name\n");
+ return;
+ }
+
+ fd = open(argv[0], O_RDONLY);
+ if (fd < 0)
+ fprintf(stderr, "hpet_open_close: open failed\n");
+ else
+ close(fd);
+
+ return;
+}
+
+void
+hpet_info(int argc, const char **argv)
+{
+}
+
+void
+hpet_poll(int argc, const char **argv)
+{
+ unsigned long freq;
+ int iterations, i, fd;
+ struct pollfd pfd;
+ struct hpet_info info;
+ struct timeval stv, etv;
+ struct timezone tz;
+ long usec;
+
+ if (argc != 3) {
+ fprintf(stderr, "hpet_poll: device-name freq iterations\n");
+ return;
+ }
+
+ freq = atoi(argv[1]);
+ iterations = atoi(argv[2]);
+
+ fd = open(argv[0], O_RDONLY);
+
+ if (fd < 0) {
+ fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
+ return;
+ }
+
+ if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
+ fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
+ goto out;
+ }
+
+ if (ioctl(fd, HPET_INFO, &info) < 0) {
+ fprintf(stderr, "hpet_poll: failed to get info\n");
+ goto out;
+ }
+
+ fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
+
+ if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
+ fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
+ goto out;
+ }
+
+ if (ioctl(fd, HPET_IE_ON, 0) < 0) {
+ fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
+ goto out;
+ }
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ for (i = 0; i < iterations; i++) {
+ pfd.revents = 0;
+ gettimeofday(&stv, &tz);
+ if (poll(&pfd, 1, -1) < 0)
+ fprintf(stderr, "hpet_poll: poll failed\n");
+ else {
+ long data;
+
+ gettimeofday(&etv, &tz);
+ usec = stv.tv_sec * 1000000 + stv.tv_usec;
+ usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
+
+ fprintf(stderr,
+ "hpet_poll: expired time = 0x%lx\n", usec);
+
+ fprintf(stderr, "hpet_poll: revents = 0x%x\n",
+ pfd.revents);
+
+ if (read(fd, &data, sizeof(data)) != sizeof(data)) {
+ fprintf(stderr, "hpet_poll: read failed\n");
+ }
+ else
+ fprintf(stderr, "hpet_poll: data 0x%lx\n",
+ data);
+ }
+ }
+
+out:
+ close(fd);
+ return;
+}
+
+static int hpet_sigio_count;
+
+static void
+hpet_sigio(int val)
+{
+ fprintf(stderr, "hpet_sigio: called\n");
+ hpet_sigio_count++;
+}
+
+void
+hpet_fasync(int argc, const char **argv)
+{
+ unsigned long freq;
+ int iterations, i, fd, value;
+ sig_t oldsig;
+ struct hpet_info info;
+
+ hpet_sigio_count = 0;
+ fd = -1;
+
+ if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
+ fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
+ return;
+ }
+
+ if (argc != 3) {
+ fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
+ goto out;
+ }
+
+ fd = open(argv[0], O_RDONLY);
+
+ if (fd < 0) {
+ fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
+ return;
+ }
+
+
+ if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
+ ((value = fcntl(fd, F_GETFL)) == 1) ||
+ (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
+ fprintf(stderr, "hpet_fasync: fcntl failed\n");
+ goto out;
+ }
+
+ freq = atoi(argv[1]);
+ iterations = atoi(argv[2]);
+
+ if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
+ fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
+ goto out;
+ }
+
+ if (ioctl(fd, HPET_INFO, &info) < 0) {
+ fprintf(stderr, "hpet_fasync: failed to get info\n");
+ goto out;
+ }
+
+ fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
+
+ if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
+ fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
+ goto out;
+ }
+
+ if (ioctl(fd, HPET_IE_ON, 0) < 0) {
+ fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
+ goto out;
+ }
+
+ for (i = 0; i < iterations; i++) {
+ (void) pause();
+ fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
+ }
+
+out:
+ signal(SIGIO, oldsig);
+
+ if (fd >= 0)
+ close(fd);
+
+ return;
+}
diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt
index bab3040da54..03485bfbd79 100644
--- a/Documentation/trace/ftrace.txt
+++ b/Documentation/trace/ftrace.txt
@@ -1588,7 +1588,7 @@ module author does not need to worry about it.
When tracing is enabled, kstop_machine is called to prevent
races with the CPUS executing code being modified (which can
-cause the CPU to do undesireable things), and the nops are
+cause the CPU to do undesirable things), and the nops are
patched back to calls. But this time, they do not call mcount
(which is just a function stub). They now call into the ftrace
infrastructure.
diff --git a/Documentation/vm/00-INDEX b/Documentation/vm/00-INDEX
index e57d6a9dd32..dca82d7c83d 100644
--- a/Documentation/vm/00-INDEX
+++ b/Documentation/vm/00-INDEX
@@ -4,23 +4,35 @@ active_mm.txt
- An explanation from Linus about tsk->active_mm vs tsk->mm.
balance
- various information on memory balancing.
+hugepage-mmap.c
+ - Example app using huge page memory with the mmap system call.
+hugepage-shm.c
+ - Example app using huge page memory with Sys V shared memory system calls.
hugetlbpage.txt
- a brief summary of hugetlbpage support in the Linux kernel.
+hwpoison.txt
+ - explains what hwpoison is
ksm.txt
- how to use the Kernel Samepage Merging feature.
locking
- info on how locking and synchronization is done in the Linux vm code.
+map_hugetlb.c
+ - an example program that uses the MAP_HUGETLB mmap flag.
numa
- information about NUMA specific code in the Linux vm.
numa_memory_policy.txt
- documentation of concepts and APIs of the 2.6 memory policy support.
overcommit-accounting
- description of the Linux kernels overcommit handling modes.
+page-types.c
+ - Tool for querying page flags
page_migration
- description of page migration in NUMA systems.
+pagemap.txt
+ - pagemap, from the userspace perspective
slabinfo.c
- source code for a tool to get reports about slabs.
slub.txt
- a short users guide for SLUB.
-map_hugetlb.c
- - an example program that uses the MAP_HUGETLB mmap flag.
+unevictable-lru.txt
+ - Unevictable LRU infrastructure
diff --git a/Documentation/vm/Makefile b/Documentation/vm/Makefile
index 5bd269b3731..9dcff328b96 100644
--- a/Documentation/vm/Makefile
+++ b/Documentation/vm/Makefile
@@ -2,7 +2,7 @@
obj- := dummy.o
# List of programs to build
-hostprogs-y := slabinfo page-types
+hostprogs-y := slabinfo page-types hugepage-mmap hugepage-shm map_hugetlb
# Tell kbuild to always build the programs
always := $(hostprogs-y)
diff --git a/Documentation/vm/hugepage-mmap.c b/Documentation/vm/hugepage-mmap.c
new file mode 100644
index 00000000000..db0dd9a33d5
--- /dev/null
+++ b/Documentation/vm/hugepage-mmap.c
@@ -0,0 +1,91 @@
+/*
+ * hugepage-mmap:
+ *
+ * Example of using huge page memory in a user application using the mmap
+ * system call. Before running this application, make sure that the
+ * administrator has mounted the hugetlbfs filesystem (on some directory
+ * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
+ * example, the app is requesting memory of size 256MB that is backed by
+ * huge pages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages. That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required. If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define FILE_NAME "/mnt/hugepagefile"
+#define LENGTH (256UL*1024*1024)
+#define PROTECTION (PROT_READ | PROT_WRITE)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define FLAGS (MAP_SHARED | MAP_FIXED)
+#else
+#define ADDR (void *)(0x0UL)
+#define FLAGS (MAP_SHARED)
+#endif
+
+static void check_bytes(char *addr)
+{
+ printf("First hex is %x\n", *((unsigned int *)addr));
+}
+
+static void write_bytes(char *addr)
+{
+ unsigned long i;
+
+ for (i = 0; i < LENGTH; i++)
+ *(addr + i) = (char)i;
+}
+
+static void read_bytes(char *addr)
+{
+ unsigned long i;
+
+ check_bytes(addr);
+ for (i = 0; i < LENGTH; i++)
+ if (*(addr + i) != (char)i) {
+ printf("Mismatch at %lu\n", i);
+ break;
+ }
+}
+
+int main(void)
+{
+ void *addr;
+ int fd;
+
+ fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
+ if (fd < 0) {
+ perror("Open failed");
+ exit(1);
+ }
+
+ addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
+ if (addr == MAP_FAILED) {
+ perror("mmap");
+ unlink(FILE_NAME);
+ exit(1);
+ }
+
+ printf("Returned address is %p\n", addr);
+ check_bytes(addr);
+ write_bytes(addr);
+ read_bytes(addr);
+
+ munmap(addr, LENGTH);
+ close(fd);
+ unlink(FILE_NAME);
+
+ return 0;
+}
diff --git a/Documentation/vm/hugepage-shm.c b/Documentation/vm/hugepage-shm.c
new file mode 100644
index 00000000000..07956d8592c
--- /dev/null
+++ b/Documentation/vm/hugepage-shm.c
@@ -0,0 +1,98 @@
+/*
+ * hugepage-shm:
+ *
+ * Example of using huge page memory in a user application using Sys V shared
+ * memory system calls. In this example the app is requesting 256MB of
+ * memory that is backed by huge pages. The application uses the flag
+ * SHM_HUGETLB in the shmget system call to inform the kernel that it is
+ * requesting huge pages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages. That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required. If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ *
+ * Note: The default shared memory limit is quite low on many kernels,
+ * you may need to increase it via:
+ *
+ * echo 268435456 > /proc/sys/kernel/shmmax
+ *
+ * This will increase the maximum size per shared memory segment to 256MB.
+ * The other limit that you will hit eventually is shmall which is the
+ * total amount of shared memory in pages. To set it to 16GB on a system
+ * with a 4kB pagesize do:
+ *
+ * echo 4194304 > /proc/sys/kernel/shmall
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/mman.h>
+
+#ifndef SHM_HUGETLB
+#define SHM_HUGETLB 04000
+#endif
+
+#define LENGTH (256UL*1024*1024)
+
+#define dprintf(x) printf(x)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define SHMAT_FLAGS (SHM_RND)
+#else
+#define ADDR (void *)(0x0UL)
+#define SHMAT_FLAGS (0)
+#endif
+
+int main(void)
+{
+ int shmid;
+ unsigned long i;
+ char *shmaddr;
+
+ if ((shmid = shmget(2, LENGTH,
+ SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
+ perror("shmget");
+ exit(1);
+ }
+ printf("shmid: 0x%x\n", shmid);
+
+ shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
+ if (shmaddr == (char *)-1) {
+ perror("Shared memory attach failure");
+ shmctl(shmid, IPC_RMID, NULL);
+ exit(2);
+ }
+ printf("shmaddr: %p\n", shmaddr);
+
+ dprintf("Starting the writes:\n");
+ for (i = 0; i < LENGTH; i++) {
+ shmaddr[i] = (char)(i);
+ if (!(i % (1024 * 1024)))
+ dprintf(".");
+ }
+ dprintf("\n");
+
+ dprintf("Starting the Check...");
+ for (i = 0; i < LENGTH; i++)
+ if (shmaddr[i] != (char)i)
+ printf("\nIndex %lu mismatched\n", i);
+ dprintf("Done.\n");
+
+ if (shmdt((const void *)shmaddr) != 0) {
+ perror("Detach failure");
+ shmctl(shmid, IPC_RMID, NULL);
+ exit(3);
+ }
+
+ shmctl(shmid, IPC_RMID, NULL);
+
+ return 0;
+}
diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt
index bc31636973e..457634c1e03 100644
--- a/Documentation/vm/hugetlbpage.txt
+++ b/Documentation/vm/hugetlbpage.txt
@@ -299,176 +299,11 @@ map_hugetlb.c.
*******************************************************************
/*
- * Example of using huge page memory in a user application using Sys V shared
- * memory system calls. In this example the app is requesting 256MB of
- * memory that is backed by huge pages. The application uses the flag
- * SHM_HUGETLB in the shmget system call to inform the kernel that it is
- * requesting huge pages.
- *
- * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages. That means that if one requires a fixed address, a huge page
- * aligned address starting with 0x800000... will be required. If a fixed
- * address is not required, the kernel will select an address in the proper
- * range.
- * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
- *
- * Note: The default shared memory limit is quite low on many kernels,
- * you may need to increase it via:
- *
- * echo 268435456 > /proc/sys/kernel/shmmax
- *
- * This will increase the maximum size per shared memory segment to 256MB.
- * The other limit that you will hit eventually is shmall which is the
- * total amount of shared memory in pages. To set it to 16GB on a system
- * with a 4kB pagesize do:
- *
- * echo 4194304 > /proc/sys/kernel/shmall
+ * hugepage-shm: see Documentation/vm/hugepage-shm.c
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/mman.h>
-
-#ifndef SHM_HUGETLB
-#define SHM_HUGETLB 04000
-#endif
-
-#define LENGTH (256UL*1024*1024)
-
-#define dprintf(x) printf(x)
-
-#define ADDR (void *)(0x0UL) /* let kernel choose address */
-#define SHMAT_FLAGS (0)
-
-int main(void)
-{
- int shmid;
- unsigned long i;
- char *shmaddr;
-
- if ((shmid = shmget(2, LENGTH,
- SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
- perror("shmget");
- exit(1);
- }
- printf("shmid: 0x%x\n", shmid);
-
- shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
- if (shmaddr == (char *)-1) {
- perror("Shared memory attach failure");
- shmctl(shmid, IPC_RMID, NULL);
- exit(2);
- }
- printf("shmaddr: %p\n", shmaddr);
-
- dprintf("Starting the writes:\n");
- for (i = 0; i < LENGTH; i++) {
- shmaddr[i] = (char)(i);
- if (!(i % (1024 * 1024)))
- dprintf(".");
- }
- dprintf("\n");
-
- dprintf("Starting the Check...");
- for (i = 0; i < LENGTH; i++)
- if (shmaddr[i] != (char)i)
- printf("\nIndex %lu mismatched\n", i);
- dprintf("Done.\n");
-
- if (shmdt((const void *)shmaddr) != 0) {
- perror("Detach failure");
- shmctl(shmid, IPC_RMID, NULL);
- exit(3);
- }
-
- shmctl(shmid, IPC_RMID, NULL);
-
- return 0;
-}
*******************************************************************
/*
- * Example of using huge page memory in a user application using the mmap
- * system call. Before running this application, make sure that the
- * administrator has mounted the hugetlbfs filesystem (on some directory
- * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
- * example, the app is requesting memory of size 256MB that is backed by
- * huge pages.
- *
- * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages. That means that if one requires a fixed address, a huge page
- * aligned address starting with 0x800000... will be required. If a fixed
- * address is not required, the kernel will select an address in the proper
- * range.
- * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ * hugepage-mmap: see Documentation/vm/hugepage-mmap.c
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-#define FILE_NAME "/mnt/hugepagefile"
-#define LENGTH (256UL*1024*1024)
-#define PROTECTION (PROT_READ | PROT_WRITE)
-
-#define ADDR (void *)(0x0UL) /* let kernel choose address */
-#define FLAGS (MAP_SHARED)
-
-void check_bytes(char *addr)
-{
- printf("First hex is %x\n", *((unsigned int *)addr));
-}
-
-void write_bytes(char *addr)
-{
- unsigned long i;
-
- for (i = 0; i < LENGTH; i++)
- *(addr + i) = (char)i;
-}
-
-void read_bytes(char *addr)
-{
- unsigned long i;
-
- check_bytes(addr);
- for (i = 0; i < LENGTH; i++)
- if (*(addr + i) != (char)i) {
- printf("Mismatch at %lu\n", i);
- break;
- }
-}
-
-int main(void)
-{
- void *addr;
- int fd;
-
- fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
- if (fd < 0) {
- perror("Open failed");
- exit(1);
- }
-
- addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- unlink(FILE_NAME);
- exit(1);
- }
-
- printf("Returned address is %p\n", addr);
- check_bytes(addr);
- write_bytes(addr);
- read_bytes(addr);
-
- munmap(addr, LENGTH);
- close(fd);
- unlink(FILE_NAME);
-
- return 0;
-}
diff --git a/Documentation/vm/map_hugetlb.c b/Documentation/vm/map_hugetlb.c
index e2bdae37f49..9969c7d9f98 100644
--- a/Documentation/vm/map_hugetlb.c
+++ b/Documentation/vm/map_hugetlb.c
@@ -31,12 +31,12 @@
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
#endif
-void check_bytes(char *addr)
+static void check_bytes(char *addr)
{
printf("First hex is %x\n", *((unsigned int *)addr));
}
-void write_bytes(char *addr)
+static void write_bytes(char *addr)
{
unsigned long i;
@@ -44,7 +44,7 @@ void write_bytes(char *addr)
*(addr + i) = (char)i;
}
-void read_bytes(char *addr)
+static void read_bytes(char *addr)
{
unsigned long i;
diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt
index b37300edf27..07375e73981 100644
--- a/Documentation/vm/slub.txt
+++ b/Documentation/vm/slub.txt
@@ -41,6 +41,7 @@ Possible debug options are
P Poisoning (object and padding)
U User tracking (free and alloc)
T Trace (please only use on single slabs)
+ A Toggle failslab filter mark for the cache
O Switch debugging off for caches that would have
caused higher minimum slab orders
- Switch all debugging off (useful if the kernel is
diff --git a/Documentation/volatile-considered-harmful.txt b/Documentation/volatile-considered-harmful.txt
index 991c26a6ef6..db0cb228d64 100644
--- a/Documentation/volatile-considered-harmful.txt
+++ b/Documentation/volatile-considered-harmful.txt
@@ -63,9 +63,9 @@ way to perform a busy wait is:
cpu_relax();
The cpu_relax() call can lower CPU power consumption or yield to a
-hyperthreaded twin processor; it also happens to serve as a memory barrier,
-so, once again, volatile is unnecessary. Of course, busy-waiting is
-generally an anti-social act to begin with.
+hyperthreaded twin processor; it also happens to serve as a compiler
+barrier, so, once again, volatile is unnecessary. Of course, busy-
+waiting is generally an anti-social act to begin with.
There are still a few rare situations where volatile makes sense in the
kernel:
diff --git a/Documentation/voyager.txt b/Documentation/voyager.txt
deleted file mode 100644
index 2749af552cd..00000000000
--- a/Documentation/voyager.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-Running Linux on the Voyager Architecture
-=========================================
-
-For full details and current project status, see
-
-http://www.hansenpartnership.com/voyager
-
-The voyager architecture was designed by NCR in the mid 80s to be a
-fully SMP capable RAS computing architecture built around intel's 486
-chip set. The voyager came in three levels of architectural
-sophistication: 3,4 and 5 --- 1 and 2 never made it out of prototype.
-The linux patches support only the Level 5 voyager architecture (any
-machine class 3435 and above).
-
-The Voyager Architecture
-------------------------
-
-Voyager machines consist of a Baseboard with a 386 diagnostic
-processor, a Power Supply Interface (PSI) a Primary and possibly
-Secondary Microchannel bus and between 2 and 20 voyager slots. The
-voyager slots can be populated with memory and cpu cards (up to 4GB
-memory and from 1 486 to 32 Pentium Pro processors). Internally, the
-voyager has a dual arbitrated system bus and a configuration and test
-bus (CAT). The voyager bus speed is 40MHz. Therefore (since all
-voyager cards are dual ported for each system bus) the maximum
-transfer rate is 320Mb/s but only if you have your slot configuration
-tuned (only memory cards can communicate with both busses at once, CPU
-cards utilise them one at a time).
-
-Voyager SMP
------------
-
-Since voyager was the first intel based SMP system, it is slightly
-more primitive than the Intel IO-APIC approach to SMP. Voyager allows
-arbitrary interrupt routing (including processor affinity routing) of
-all 16 PC type interrupts. However it does this by using a modified
-5259 master/slave chip set instead of an APIC bus. Additionally,
-voyager supports Cross Processor Interrupts (CPI) equivalent to the
-APIC IPIs. There are two routed voyager interrupt lines provided to
-each slot.
-
-Processor Cards
----------------
-
-These come in single, dyadic and quad configurations (the quads are
-problematic--see later). The maximum configuration is 8 quad cards
-for 32 way SMP.
-
-Quad Processors
----------------
-
-Because voyager only supplies two interrupt lines to each Processor
-card, the Quad processors have to be configured (and Bootstrapped) in
-as a pair of Master/Slave processors.
-
-In fact, most Quad cards only accept one VIC interrupt line, so they
-have one interrupt handling processor (called the VIC extended
-processor) and three non-interrupt handling processors.
-
-Current Status
---------------
-
-The System will boot on Mono, Dyad and Quad cards. There was
-originally a Quad boot problem which has been fixed by proper gdt
-alignment in the initial boot loader. If you still cannot get your
-voyager system to boot, email me at:
-
-<J.E.J.Bottomley@HansenPartnership.com>
-
-
-The Quad cards now support using the separate Quad CPI vectors instead
-of going through the VIC mailbox system.
-
-The Level 4 architecture (3430 and 3360 Machines) should also work
-fine.
-
-Dump Switch
------------
-
-The voyager dump switch sends out a broadcast NMI which the voyager
-code intercepts and does a task dump.
-
-Power Switch
-------------
-
-The front panel power switch is intercepted by the kernel and should
-cause a system shutdown and power off.
-
-A Note About Mixed CPU Systems
-------------------------------
-
-Linux isn't designed to handle mixed CPU systems very well. In order
-to get everything going you *must* make sure that your lowest
-capability CPU is used for booting. Also, mixing CPU classes
-(e.g. 486 and 586) is really not going to work very well at all.
diff --git a/Documentation/watchdog/src/watchdog-simple.c b/Documentation/watchdog/src/watchdog-simple.c
index 4cf72f3fa8e..ba45803a221 100644
--- a/Documentation/watchdog/src/watchdog-simple.c
+++ b/Documentation/watchdog/src/watchdog-simple.c
@@ -17,9 +17,6 @@ int main(void)
ret = -1;
break;
}
- ret = fsync(fd);
- if (ret)
- break;
sleep(10);
}
close(fd);
diff --git a/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c
index a750532ffcf..63fdc34ceb9 100644
--- a/Documentation/watchdog/src/watchdog-test.c
+++ b/Documentation/watchdog/src/watchdog-test.c
@@ -31,6 +31,8 @@ static void keep_alive(void)
*/
int main(int argc, char *argv[])
{
+ int flags;
+
fd = open("/dev/watchdog", O_WRONLY);
if (fd == -1) {
@@ -41,12 +43,14 @@ int main(int argc, char *argv[])
if (argc > 1) {
if (!strncasecmp(argv[1], "-d", 2)) {
- ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);
+ flags = WDIOS_DISABLECARD;
+ ioctl(fd, WDIOC_SETOPTIONS, &flags);
fprintf(stderr, "Watchdog card disabled.\n");
fflush(stderr);
exit(0);
} else if (!strncasecmp(argv[1], "-e", 2)) {
- ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
+ flags = WDIOS_ENABLECARD;
+ ioctl(fd, WDIOC_SETOPTIONS, &flags);
fprintf(stderr, "Watchdog card enabled.\n");
fflush(stderr);
exit(0);
diff --git a/Documentation/watchdog/watchdog-api.txt b/Documentation/watchdog/watchdog-api.txt
index 4cc4ba9d715..eb7132ed8bb 100644
--- a/Documentation/watchdog/watchdog-api.txt
+++ b/Documentation/watchdog/watchdog-api.txt
@@ -222,11 +222,10 @@ returned value is the temperature in degrees fahrenheit.
ioctl(fd, WDIOC_GETTEMP, &temperature);
Finally the SETOPTIONS ioctl can be used to control some aspects of
-the cards operation; right now the pcwd driver is the only one
-supporting this ioctl.
+the cards operation.
int options = 0;
- ioctl(fd, WDIOC_SETOPTIONS, options);
+ ioctl(fd, WDIOC_SETOPTIONS, &options);
The following options are available:
diff --git a/MAINTAINERS b/MAINTAINERS
index c6591bca646..d5b0b1b6dc5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -71,6 +71,7 @@ Descriptions of section entries:
M: Mail patches to: FullName <address@domain>
L: Mailing list that is relevant to this area
W: Web-page with status/info
+ Q: Patchwork web based patch tracking system site
T: SCM tree type and location. Type is one of: git, hg, quilt, stgit.
S: Status, one of the following:
Supported: Someone is actually paid to look after this.
@@ -182,6 +183,7 @@ M: Ron Minnich <rminnich@sandia.gov>
M: Latchesar Ionkov <lucho@ionkov.net>
L: v9fs-developer@lists.sourceforge.net
W: http://swik.net/v9fs
+Q: http://patchwork.kernel.org/project/v9fs-devel/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git
S: Maintained
F: Documentation/filesystems/9p.txt
@@ -238,6 +240,7 @@ ACPI
M: Len Brown <lenb@kernel.org>
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
+Q: http://patchwork.kernel.org/project/linux-acpi/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
S: Supported
F: drivers/acpi/
@@ -428,7 +431,6 @@ P: Jordan Crouse
L: linux-geode@lists.infradead.org (moderated for non-subscribers)
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
S: Supported
-F: arch/x86/kernel/geode_32.c
F: drivers/char/hw_random/geode-rng.c
F: drivers/crypto/geode*
F: drivers/video/geode/
@@ -483,8 +485,8 @@ S: Maintained
F: drivers/input/mouse/bcm5974.c
APPLE SMC DRIVER
-M: Nicolas Boichat <nicolas@boichat.ch>
-L: mactel-linux-devel@lists.sourceforge.net
+M: Henrik Rydberg <rydberg@euromail.se>
+L: lm-sensors@lm-sensors.org
S: Maintained
F: drivers/hwmon/applesmc.c
@@ -664,6 +666,12 @@ T: git://git.pengutronix.de/git/imx/linux-2.6.git
F: arch/arm/mach-mx*/
F: arch/arm/plat-mxc/
+ARM/FREESCALE IMX51
+M: Amit Kucheria <amit.kucheria@canonical.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-mx5/
+
ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -789,12 +797,12 @@ M: Michael Petchkovsky <mkpetch@internode.on.net>
S: Maintained
ARM/NOMADIK ARCHITECTURE
-M: Alessandro Rubini <rubini@unipv.it>
-M: STEricsson <STEricsson_nomadik_linux@list.st.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: arch/arm/mach-nomadik/
-F: arch/arm/plat-nomadik/
+M: Alessandro Rubini <rubini@unipv.it>
+M: STEricsson <STEricsson_nomadik_linux@list.st.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-nomadik/
+F: arch/arm/plat-nomadik/
ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
M: Nelson Castillo <arhuaco@freaks-unidos.net>
@@ -937,6 +945,16 @@ W: http://www.fluff.org/ben/linux/
S: Maintained
F: arch/arm/mach-s3c6410/
+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
+S: Supported
+F: arch/arm/mach-shmobile/
+F: drivers/sh/
+
ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -953,6 +971,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.mcuos.com
S: Maintained
+ARM/U300 MACHINE SUPPORT
+M: Linus Walleij <linus.walleij@stericsson.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Supported
+F: arch/arm/mach-u300/
+F: drivers/i2c/busses/i2c-stu300.c
+F: drivers/rtc/rtc-coh901331.c
+F: drivers/watchdog/coh901327_wdt.c
+F: drivers/dma/coh901318*
+
ARM/U8500 ARM ARCHITECTURE
M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -966,6 +994,13 @@ W: http://www.arm.linux.org.uk/
S: Maintained
F: arch/arm/vfp/
+ASC7621 HARDWARE MONITOR DRIVER
+M: George Joseph <george.joseph@fairview5.com>
+L: lm-sensors@lm-sensors.org
+S: Maintained
+F: Documentation/hwmon/asc7621
+F: drivers/hwmon/asc7621.c
+
ASUS ACPI EXTRAS DRIVER
M: Corentin Chary <corentincj@iksaif.net>
M: Karol Kozimor <sziwan@users.sourceforge.net>
@@ -1226,6 +1261,13 @@ W: http://blackfin.uclinux.org
S: Supported
F: drivers/rtc/rtc-bfin.c
+BLACKFIN SDH DRIVER
+M: Cliff Cai <cliff.cai@analog.com>
+L: uclinux-dist-devel@blackfin.uclinux.org
+W: http://blackfin.uclinux.org
+S: Supported
+F: drivers/mmc/host/bfin_sdh.c
+
BLACKFIN SERIAL DRIVER
M: Sonic Zhang <sonic.zhang@analog.com>
L: uclinux-dist-devel@blackfin.uclinux.org
@@ -1332,6 +1374,7 @@ BTRFS FILE SYSTEM
M: Chris Mason <chris.mason@oracle.com>
L: linux-btrfs@vger.kernel.org
W: http://btrfs.wiki.kernel.org/
+Q: http://patchwork.kernel.org/project/linux-btrfs/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
S: Maintained
F: Documentation/filesystems/btrfs.txt
@@ -1372,20 +1415,30 @@ F: arch/x86/include/asm/calgary.h
F: arch/x86/include/asm/tce.h
CAN NETWORK LAYER
-M: Urs Thuermann <urs.thuermann@volkswagen.de>
+M: Oliver Hartkopp <socketcan@hartkopp.net>
M: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
-L: socketcan-core@lists.berlios.de (subscribers-only)
+M: Urs Thuermann <urs.thuermann@volkswagen.de>
+L: socketcan-core@lists.berlios.de
+L: netdev@vger.kernel.org
W: http://developer.berlios.de/projects/socketcan/
S: Maintained
-F: drivers/net/can/
-F: include/linux/can/
+F: net/can/
F: include/linux/can.h
+F: include/linux/can/core.h
+F: include/linux/can/bcm.h
+F: include/linux/can/raw.h
CAN NETWORK DRIVERS
M: Wolfgang Grandegger <wg@grandegger.com>
-L: socketcan-core@lists.berlios.de (subscribers-only)
+L: socketcan-core@lists.berlios.de
+L: netdev@vger.kernel.org
W: http://developer.berlios.de/projects/socketcan/
S: Maintained
+F: drivers/net/can/
+F: include/linux/can/dev.h
+F: include/linux/can/error.h
+F: include/linux/can/netlink.h
+F: include/linux/can/platform/
CELL BROADBAND ENGINE ARCHITECTURE
M: Arnd Bergmann <arnd@arndb.de>
@@ -1398,6 +1451,15 @@ F: arch/powerpc/include/asm/spu*.h
F: arch/powerpc/oprofile/*cell*
F: arch/powerpc/platforms/cell/
+CEPH DISTRIBUTED FILE SYSTEM CLIENT
+M: Sage Weil <sage@newdream.net>
+L: ceph-devel@vger.kernel.org
+W: http://ceph.newdream.net/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
+S: Supported
+F: Documentation/filesystems/ceph.txt
+F: fs/ceph
+
CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM:
M: David Vrabel <david.vrabel@csr.com>
L: linux-usb@vger.kernel.org
@@ -1496,6 +1558,7 @@ M: Steve French <sfrench@samba.org>
L: linux-cifs-client@lists.samba.org (moderated for non-subscribers)
L: samba-technical@lists.samba.org (moderated for non-subscribers)
W: http://linux-cifs.samba.org/
+Q: http://patchwork.ozlabs.org/project/linux-cifs-client/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
S: Supported
F: Documentation/filesystems/cifs.txt
@@ -1782,6 +1845,7 @@ DEVICE-MAPPER (LVM)
P: Alasdair Kergon
L: dm-devel@redhat.com
W: http://sources.redhat.com/dm
+Q: http://patchwork.kernel.org/project/dm-devel/list/
S: Maintained
F: Documentation/device-mapper/
F: drivers/md/dm*
@@ -1872,17 +1936,17 @@ F: drivers/scsi/dpt*
F: drivers/scsi/dpt/
DRBD DRIVER
-P: Philipp Reisner
-P: Lars Ellenberg
-M: drbd-dev@lists.linbit.com
-L: drbd-user@lists.linbit.com
-W: http://www.drbd.org
-T: git git://git.drbd.org/linux-2.6-drbd.git drbd
-T: git git://git.drbd.org/drbd-8.3.git
-S: Supported
-F: drivers/block/drbd/
-F: lib/lru_cache.c
-F: Documentation/blockdev/drbd/
+P: Philipp Reisner
+P: Lars Ellenberg
+M: drbd-dev@lists.linbit.com
+L: drbd-user@lists.linbit.com
+W: http://www.drbd.org
+T: git git://git.drbd.org/linux-2.6-drbd.git drbd
+T: git git://git.drbd.org/drbd-8.3.git
+S: Supported
+F: drivers/block/drbd/
+F: lib/lru_cache.c
+F: Documentation/blockdev/drbd/
DRIVER CORE, KOBJECTS, AND SYSFS
M: Greg Kroah-Hartman <gregkh@suse.de>
@@ -1896,7 +1960,7 @@ F: lib/kobj*
DRM DRIVERS
M: David Airlie <airlied@linux.ie>
-L: dri-devel@lists.sourceforge.net
+L: dri-devel@lists.freedesktop.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git
S: Maintained
F: drivers/gpu/drm/
@@ -2095,6 +2159,7 @@ F: drivers/net/eexpress.*
ETHERNET BRIDGE
M: Stephen Hemminger <shemminger@linux-foundation.org>
L: bridge@lists.linux-foundation.org
+L: netdev@vger.kernel.org
W: http://www.linux-foundation.org/en/Net:Bridge
S: Maintained
F: include/linux/netfilter_bridge/
@@ -2126,6 +2191,7 @@ M: "Theodore Ts'o" <tytso@mit.edu>
M: Andreas Dilger <adilger@sun.com>
L: linux-ext4@vger.kernel.org
W: http://ext4.wiki.kernel.org
+Q: http://patchwork.ozlabs.org/project/linux-ext4/list/
S: Maintained
F: Documentation/filesystems/ext4.txt
F: fs/ext4/
@@ -2418,12 +2484,6 @@ L: linuxppc-dev@ozlabs.org
S: Odd Fixes
F: drivers/char/hvc_*
-VIRTIO CONSOLE DRIVER
-M: Amit Shah <amit.shah@redhat.com>
-L: virtualization@lists.linux-foundation.org
-S: Maintained
-F: drivers/char/virtio_console.c
-
iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER
M: Peter Jones <pjones@redhat.com>
M: Konrad Rzeszutek Wilk <konrad@kernel.org>
@@ -2502,13 +2562,6 @@ L: linux-parisc@vger.kernel.org
S: Maintained
F: sound/parisc/harmony.*
-HAYES ESP SERIAL DRIVER
-M: "Andrew J. Robinson" <arobinso@nyx.net>
-W: http://www.nyx.net/~arobinso
-S: Maintained
-F: Documentation/serial/hayes-esp.txt
-F: drivers/char/esp.c
-
HEWLETT-PACKARD SMART2 RAID DRIVER
M: Chirag Kantharia <chirag.kantharia@hp.com>
L: iss_storagedev@hp.com
@@ -2717,6 +2770,7 @@ F: drivers/scsi/ips.*
IDE SUBSYSTEM
M: "David S. Miller" <davem@davemloft.net>
L: linux-ide@vger.kernel.org
+Q: http://patchwork.ozlabs.org/project/linux-ide/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git
S: Maintained
F: Documentation/ide/
@@ -2771,6 +2825,7 @@ M: Sean Hefty <sean.hefty@intel.com>
M: Hal Rosenstock <hal.rosenstock@gmail.com>
L: linux-rdma@vger.kernel.org
W: http://www.openib.org/
+Q: http://patchwork.kernel.org/project/linux-rdma/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git
S: Supported
F: Documentation/infiniband/
@@ -2790,12 +2845,13 @@ INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS
M: Dmitry Torokhov <dmitry.torokhov@gmail.com>
M: Dmitry Torokhov <dtor@mail.ru>
L: linux-input@vger.kernel.org
+Q: http://patchwork.kernel.org/project/linux-input/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git
S: Maintained
F: drivers/input/
INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
-M: Sylvain Meyer <sylvain.meyer@worldonline.fr>
+M: Maik Broemme <mbroemme@plusserver.de>
L: linux-fbdev@vger.kernel.org
S: Maintained
F: Documentation/fb/intelfb.txt
@@ -3031,6 +3087,7 @@ F: include/scsi/*iscsi*
ISDN SUBSYSTEM
M: Karsten Keil <isdn@linux-pingi.de>
L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
+L: netdev@vger.kernel.org
W: http://www.isdn4linux.de
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kkeil/isdn-2.6.git
S: Maintained
@@ -3046,6 +3103,13 @@ W: http://www.melware.de
S: Maintained
F: drivers/isdn/hardware/eicon/
+IT87 HARDWARE MONITORING DRIVER
+M: Jean Delvare <khali@linux-fr.org>
+L: lm-sensors@lm-sensors.org
+S: Maintained
+F: Documentation/hwmon/it87
+F: drivers/hwmon/it87.c
+
IVTV VIDEO4LINUX DRIVER
M: Andy Walls <awalls@radix.net>
L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
@@ -3099,6 +3163,7 @@ F: drivers/hwmon/k8temp.c
KCONFIG
M: Roman Zippel <zippel@linux-m68k.org>
L: linux-kbuild@vger.kernel.org
+Q: http://patchwork.kernel.org/project/linux-kbuild/list/
S: Maintained
F: Documentation/kbuild/kconfig-language.txt
F: scripts/kconfig/
@@ -3173,7 +3238,7 @@ F: arch/x86/include/asm/svm.h
F: arch/x86/kvm/svm.c
KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
-M: Hollis Blanchard <hollisb@us.ibm.com>
+M: Alexander Graf <agraf@suse.de>
L: kvm-ppc@vger.kernel.org
W: http://kvm.qumranet.com
S: Supported
@@ -3209,6 +3274,16 @@ S: Maintained
F: include/linux/kexec.h
F: kernel/kexec.c
+KEYS/KEYRINGS:
+M: David Howells <dhowells@redhat.com>
+L: keyrings@linux-nfs.org
+S: Maintained
+F: Documentation/keys.txt
+F: include/linux/key.h
+F: include/linux/key-type.h
+F: include/keys/
+F: security/keys/
+
KGDB
M: Jason Wessel <jason.wessel@windriver.com>
L: kgdb-bugreport@lists.sourceforge.net
@@ -3312,6 +3387,7 @@ M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
M: Paul Mackerras <paulus@samba.org>
W: http://www.penguinppc.org/
L: linuxppc-dev@ozlabs.org
+Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
S: Supported
F: Documentation/powerpc/
@@ -3432,6 +3508,13 @@ S: Maintained
F: Documentation/ldm.txt
F: fs/partitions/ldm.*
+LogFS
+M: Joern Engel <joern@logfs.org>
+L: logfs@logfs.org
+W: logfs.org
+S: Maintained
+F: fs/logfs/
+
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
M: Eric Moore <Eric.Moore@lsi.com>
M: support@lsi.com
@@ -3450,8 +3533,8 @@ F: drivers/scsi/sym53c8xx_2/
LTP (Linux Test Project)
M: Rishikesh K Rajak <risrajak@linux.vnet.ibm.com>
M: Garrett Cooper <yanegomi@gmail.com>
-M: Mike Frysinger <vapier@gentoo.org>
-M: Subrata Modak <subrata@linux.vnet.ibm.com>
+M: Mike Frysinger <vapier@gentoo.org>
+M: Subrata Modak <subrata@linux.vnet.ibm.com>
L: ltp-list@lists.sourceforge.net (subscribers-only)
W: http://ltp.sourceforge.net/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/ltp.git
@@ -3568,6 +3651,7 @@ M: Mauro Carvalho Chehab <mchehab@infradead.org>
P: LinuxTV.org Project
L: linux-media@vger.kernel.org
W: http://linuxtv.org
+Q: http://patchwork.kernel.org/project/linux-media/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
F: Documentation/dvb/
@@ -3595,7 +3679,7 @@ F: mm/
MEMORY RESOURCE CONTROLLER
M: Balbir Singh <balbir@linux.vnet.ibm.com>
-M: Pavel Emelyanov <xemul@openvz.org>
+M: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
M: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
L: linux-mm@kvack.org
S: Maintained
@@ -3603,8 +3687,9 @@ F: mm/memcontrol.c
MEMORY TECHNOLOGY DEVICES (MTD)
M: David Woodhouse <dwmw2@infradead.org>
-W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org
+W: http://www.linux-mtd.infradead.org/
+Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
T: git git://git.infradead.org/mtd-2.6.git
S: Maintained
F: drivers/mtd/
@@ -3864,6 +3949,7 @@ S: Maintained
NETWORKING [WIRELESS]
M: "John W. Linville" <linville@tuxdriver.com>
L: linux-wireless@vger.kernel.org
+Q: http://patchwork.kernel.org/project/linux-wireless/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
S: Maintained
F: net/mac80211/
@@ -3956,6 +4042,7 @@ M: Tony Lindgren <tony@atomide.com>
L: linux-omap@vger.kernel.org
W: http://www.muru.com/linux/omap/
W: http://linux.omap.com/
+Q: http://patchwork.kernel.org/project/linux-omap/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
S: Maintained
F: arch/arm/*omap*/
@@ -4182,6 +4269,7 @@ M: Helge Deller <deller@gmx.de>
M: "James E.J. Bottomley" <jejb@parisc-linux.org>
L: linux-parisc@vger.kernel.org
W: http://www.parisc-linux.org/
+Q: http://patchwork.kernel.org/project/linux-parisc/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
S: Maintained
F: arch/parisc/
@@ -4224,6 +4312,7 @@ F: Documentation/powerpc/eeh-pci-error-recovery.txt
PCI SUBSYSTEM
M: Jesse Barnes <jbarnes@virtuousgeek.org>
L: linux-pci@vger.kernel.org
+Q: http://patchwork.kernel.org/project/linux-pci/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
S: Supported
F: Documentation/PCI/
@@ -4262,10 +4351,13 @@ PERFORMANCE EVENTS SUBSYSTEM
M: Peter Zijlstra <a.p.zijlstra@chello.nl>
M: Paul Mackerras <paulus@samba.org>
M: Ingo Molnar <mingo@elte.hu>
+M: Arnaldo Carvalho de Melo <acme@redhat.com>
S: Supported
F: kernel/perf_event.c
F: include/linux/perf_event.h
-F: arch/*/*/kernel/perf_event.c
+F: arch/*/kernel/perf_event.c
+F: arch/*/kernel/*/perf_event.c
+F: arch/*/kernel/*/*/perf_event.c
F: arch/*/include/asm/perf_event.h
F: arch/*/lib/perf_event.c
F: arch/*/kernel/perf_callchain.c
@@ -4390,17 +4482,17 @@ S: Maintained
F: drivers/ata/sata_promise.*
PS3 NETWORK SUPPORT
-M: Geoff Levand <geoffrey.levand@am.sony.com>
+M: Geoff Levand <geoff@infradead.org>
L: netdev@vger.kernel.org
L: cbe-oss-dev@ozlabs.org
-S: Supported
+S: Maintained
F: drivers/net/ps3_gelic_net.*
PS3 PLATFORM SUPPORT
-M: Geoff Levand <geoffrey.levand@am.sony.com>
+M: Geoff Levand <geoff@infradead.org>
L: linuxppc-dev@ozlabs.org
L: cbe-oss-dev@ozlabs.org
-S: Supported
+S: Maintained
F: arch/powerpc/boot/ps3*
F: arch/powerpc/include/asm/lv1call.h
F: arch/powerpc/include/asm/ps3*.h
@@ -4462,6 +4554,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
S: Maintained
+MMP2 SUPPORT (aka ARMADA610)
+M: Haojian Zhuang <haojian.zhuang@marvell.com>
+M: Eric Miao <eric.y.miao@gmail.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
+S: Maintained
+
PXA MMCI DRIVER
S: Orphan
@@ -4599,6 +4698,7 @@ F: include/linux/rtc.h
REAL TIME CLOCK (RTC) SUBSYSTEM
M: Alessandro Zummo <a.zummo@towertech.it>
L: rtc-linux@googlegroups.com
+Q: http://patchwork.ozlabs.org/project/rtc-linux/list/
S: Maintained
F: Documentation/rtc.txt
F: drivers/rtc/
@@ -4691,12 +4791,11 @@ F: drivers/s390/crypto/
S390 ZFCP DRIVER
M: Christof Schmitt <christof.schmitt@de.ibm.com>
-M: Martin Peschke <mp3@de.ibm.com>
+M: Swen Schillig <swen@vnet.ibm.com>
M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
-F: Documentation/s390/zfcpdump.txt
F: drivers/s390/scsi/zfcp_*
S390 IUCV NETWORK LAYER
@@ -4966,6 +5065,7 @@ F: drivers/*/*/*s3c2410*
TI DAVINCI MACHINE SUPPORT
P: Kevin Hilman
M: davinci-linux-open-source@linux.davincidsp.com
+Q: http://patchwork.kernel.org/project/linux-davinci/list/
S: Supported
F: arch/arm/mach-davinci
@@ -5131,11 +5231,27 @@ F: include/sound/soc*
SPARC + UltraSPARC (sparc/sparc64)
M: "David S. Miller" <davem@davemloft.net>
L: sparclinux@vger.kernel.org
+Q: http://patchwork.ozlabs.org/project/sparclinux/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
S: Maintained
F: arch/sparc/
+SPARC SERIAL DRIVERS
+M: "David S. Miller" <davem@davemloft.net>
+L: sparclinux@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
+S: Maintained
+F: drivers/serial/suncore.c
+F: drivers/serial/suncore.h
+F: drivers/serial/sunhv.c
+F: drivers/serial/sunsab.c
+F: drivers/serial/sunsab.h
+F: drivers/serial/sunsu.c
+F: drivers/serial/sunzilog.c
+F: drivers/serial/sunzilog.h
+
SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
M: Roger Wolff <R.E.Wolff@BitWizard.nl>
S: Supported
@@ -5146,6 +5262,7 @@ SPI SUBSYSTEM
M: David Brownell <dbrownell@users.sourceforge.net>
M: Grant Likely <grant.likely@secretlab.ca>
L: spi-devel-general@lists.sourceforge.net
+Q: http://patchwork.kernel.org/project/spi-devel-general/list/
S: Maintained
F: Documentation/spi/
F: drivers/spi/
@@ -5201,7 +5318,7 @@ F: drivers/net/starfire*
STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
S: Orphan
-F: drivers/net/wireless/strip.c
+F: drivers/staging/strip/strip.c
F: include/linux/if_strip.h
STRADIS MPEG-2 DECODER DRIVER
@@ -5222,6 +5339,7 @@ SUPERH
M: Paul Mundt <lethal@linux-sh.org>
L: linux-sh@vger.kernel.org
W: http://www.linux-sh.org
+Q: http://patchwork.kernel.org/project/linux-sh/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git
S: Supported
F: Documentation/sh/
@@ -5319,7 +5437,6 @@ S: Maintained
F: sound/soc/codecs/twl4030*
TIPC NETWORK LAYER
-M: Per Liden <per.liden@ericsson.com>
M: Jon Maloy <jon.maloy@ericsson.com>
M: Allan Stephens <allan.stephens@windriver.com>
L: tipc-discussion@lists.sourceforge.net
@@ -5857,6 +5974,13 @@ S: Maintained
F: Documentation/filesystems/vfat.txt
F: fs/fat/
+VIRTIO CONSOLE DRIVER
+M: Amit Shah <amit.shah@redhat.com>
+L: virtualization@lists.linux-foundation.org
+S: Maintained
+F: drivers/char/virtio_console.c
+F: include/linux/virtio_console.h
+
VIRTIO HOST (VHOST)
M: "Michael S. Tsirkin" <mst@redhat.com>
L: kvm@vger.kernel.org
@@ -5989,7 +6113,7 @@ L: linux-wireless@vger.kernel.org
W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
S: Maintained
F: Documentation/networking/wavelan.txt
-F: drivers/net/wireless/wavelan*
+F: drivers/staging/wavelan/
WD7000 SCSI DRIVER
M: Miroslav Zagorac <zaga@fly.cc.fer.hr>
@@ -6097,7 +6221,7 @@ F: arch/x86/
X86 PLATFORM DRIVERS
M: Matthew Garrett <mjg@redhat.com>
L: platform-driver-x86@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
S: Maintained
F: drivers/platform/x86
@@ -6185,6 +6309,7 @@ F: drivers/serial/zs.*
THE REST
M: Linus Torvalds <torvalds@linux-foundation.org>
L: linux-kernel@vger.kernel.org
+Q: http://patchwork.kernel.org/project/LKML/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
S: Buried alive in reporters
F: *
diff --git a/Makefile b/Makefile
index 1b24895212d..5f05f8cbeda 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 6
-SUBLEVEL = 33
-EXTRAVERSION =
-NAME = Man-Eating Seals of Antiquity
+SUBLEVEL = 34
+EXTRAVERSION = -rc6
+NAME = Sheep on Meth
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
diff --git a/arch/Kconfig b/arch/Kconfig
index 215e46073c4..e5eb1337a53 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -41,6 +41,17 @@ config KPROBES
for kernel debugging, non-intrusive instrumentation and testing.
If in doubt, say "N".
+config OPTPROBES
+ bool "Kprobes jump optimization support (EXPERIMENTAL)"
+ default y
+ depends on KPROBES
+ depends on !PREEMPT
+ depends on HAVE_OPTPROBES
+ select KALLSYMS_ALL
+ help
+ This option will allow kprobes to optimize breakpoint to
+ a jump for reducing its overhead.
+
config HAVE_EFFICIENT_UNALIGNED_ACCESS
bool
help
@@ -83,6 +94,8 @@ config HAVE_KPROBES
config HAVE_KRETPROBES
bool
+config HAVE_OPTPROBES
+ bool
#
# An arch should select this if it provides all these things:
#
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index bd7261ea8f9..75291fdd379 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -10,6 +10,7 @@ config ALPHA
select HAVE_OPROFILE
select HAVE_SYSCALL_WRAPPERS
select HAVE_PERF_EVENTS
+ select HAVE_DMA_ATTRS
help
The Alpha is a 64-bit general-purpose processor designed and
marketed by the Digital Equipment Corporation of blessed memory,
@@ -58,6 +59,9 @@ config ZONE_DMA
bool
default y
+config NEED_DMA_MAP_STATE
+ def_bool y
+
config GENERIC_ISA_DMA
bool
default y
diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c
index 3c8d1b25c66..be61670d409 100644
--- a/arch/alpha/boot/bootp.c
+++ b/arch/alpha/boot/bootp.c
@@ -8,6 +8,7 @@
* based significantly on the arch/alpha/boot/main.c of Linus Torvalds
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <generated/utsrelease.h>
#include <linux/mm.h>
diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c
index ade3f129dc2..c98865f2142 100644
--- a/arch/alpha/boot/bootpz.c
+++ b/arch/alpha/boot/bootpz.c
@@ -10,6 +10,7 @@
* and the decompression code from MILO.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <generated/utsrelease.h>
#include <linux/mm.h>
diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c
index 644b7db5543..ded57d9a80e 100644
--- a/arch/alpha/boot/main.c
+++ b/arch/alpha/boot/main.c
@@ -6,6 +6,7 @@
* This file is the bootloader for the Linux/AXP kernel
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <generated/utsrelease.h>
#include <linux/mm.h>
diff --git a/arch/alpha/boot/misc.c b/arch/alpha/boot/misc.c
index 3047a1b3a51..3ff9a957a25 100644
--- a/arch/alpha/boot/misc.c
+++ b/arch/alpha/boot/misc.c
@@ -19,6 +19,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
diff --git a/arch/alpha/include/asm/core_marvel.h b/arch/alpha/include/asm/core_marvel.h
index 30d55fe7aaf..dad300fa14c 100644
--- a/arch/alpha/include/asm/core_marvel.h
+++ b/arch/alpha/include/asm/core_marvel.h
@@ -12,7 +12,6 @@
#define __ALPHA_MARVEL__H__
#include <linux/types.h>
-#include <linux/pci.h>
#include <linux/spinlock.h>
#include <asm/compiler.h>
diff --git a/arch/alpha/include/asm/core_mcpcia.h b/arch/alpha/include/asm/core_mcpcia.h
index acf55b48347..21ac53383b3 100644
--- a/arch/alpha/include/asm/core_mcpcia.h
+++ b/arch/alpha/include/asm/core_mcpcia.h
@@ -6,7 +6,6 @@
#define MCPCIA_ONE_HAE_WINDOW 1
#include <linux/types.h>
-#include <linux/pci.h>
#include <asm/compiler.h>
/*
diff --git a/arch/alpha/include/asm/core_titan.h b/arch/alpha/include/asm/core_titan.h
index a17f6f33b68..8cf79d1219e 100644
--- a/arch/alpha/include/asm/core_titan.h
+++ b/arch/alpha/include/asm/core_titan.h
@@ -2,7 +2,6 @@
#define __ALPHA_TITAN__H__
#include <linux/types.h>
-#include <linux/pci.h>
#include <asm/compiler.h>
/*
diff --git a/arch/alpha/include/asm/core_tsunami.h b/arch/alpha/include/asm/core_tsunami.h
index 58d4fe48742..8e39ecf0941 100644
--- a/arch/alpha/include/asm/core_tsunami.h
+++ b/arch/alpha/include/asm/core_tsunami.h
@@ -2,7 +2,6 @@
#define __ALPHA_TSUNAMI__H__
#include <linux/types.h>
-#include <linux/pci.h>
#include <asm/compiler.h>
/*
diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h
index 04eb5681448..1bce8169733 100644
--- a/arch/alpha/include/asm/dma-mapping.h
+++ b/arch/alpha/include/asm/dma-mapping.h
@@ -1,71 +1,49 @@
#ifndef _ALPHA_DMA_MAPPING_H
#define _ALPHA_DMA_MAPPING_H
+#include <linux/dma-attrs.h>
-#ifdef CONFIG_PCI
+extern struct dma_map_ops *dma_ops;
-#include <linux/pci.h>
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+ return dma_ops;
+}
-#define dma_map_single(dev, va, size, dir) \
- pci_map_single(alpha_gendev_to_pci(dev), va, size, dir)
-#define dma_unmap_single(dev, addr, size, dir) \
- pci_unmap_single(alpha_gendev_to_pci(dev), addr, size, dir)
-#define dma_alloc_coherent(dev, size, addr, gfp) \
- __pci_alloc_consistent(alpha_gendev_to_pci(dev), size, addr, gfp)
-#define dma_free_coherent(dev, size, va, addr) \
- pci_free_consistent(alpha_gendev_to_pci(dev), size, va, addr)
-#define dma_map_page(dev, page, off, size, dir) \
- pci_map_page(alpha_gendev_to_pci(dev), page, off, size, dir)
-#define dma_unmap_page(dev, addr, size, dir) \
- pci_unmap_page(alpha_gendev_to_pci(dev), addr, size, dir)
-#define dma_map_sg(dev, sg, nents, dir) \
- pci_map_sg(alpha_gendev_to_pci(dev), sg, nents, dir)
-#define dma_unmap_sg(dev, sg, nents, dir) \
- pci_unmap_sg(alpha_gendev_to_pci(dev), sg, nents, dir)
-#define dma_supported(dev, mask) \
- pci_dma_supported(alpha_gendev_to_pci(dev), mask)
-#define dma_mapping_error(dev, addr) \
- pci_dma_mapping_error(alpha_gendev_to_pci(dev), addr)
+#include <asm-generic/dma-mapping-common.h>
-#else /* no PCI - no IOMMU. */
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ return get_dma_ops(dev)->alloc_coherent(dev, size, dma_handle, gfp);
+}
-#include <asm/io.h> /* for virt_to_phys() */
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ get_dma_ops(dev)->free_coherent(dev, size, vaddr, dma_handle);
+}
-struct scatterlist;
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp);
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction);
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return get_dma_ops(dev)->mapping_error(dev, dma_addr);
+}
-#define dma_free_coherent(dev, size, va, addr) \
- free_pages((unsigned long)va, get_order(size))
-#define dma_supported(dev, mask) (mask < 0x00ffffffUL ? 0 : 1)
-#define dma_map_single(dev, va, size, dir) virt_to_phys(va)
-#define dma_map_page(dev, page, off, size, dir) (page_to_pa(page) + off)
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ return get_dma_ops(dev)->dma_supported(dev, mask);
+}
-#define dma_unmap_single(dev, addr, size, dir) ((void)0)
-#define dma_unmap_page(dev, addr, size, dir) ((void)0)
-#define dma_unmap_sg(dev, sg, nents, dir) ((void)0)
-
-#define dma_mapping_error(dev, addr) (0)
-
-#endif /* !CONFIG_PCI */
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+ return get_dma_ops(dev)->set_dma_mask(dev, mask);
+}
#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)
#define dma_is_consistent(d, h) (1)
-int dma_set_mask(struct device *dev, u64 mask);
-
-#define dma_sync_single_for_cpu(dev, addr, size, dir) ((void)0)
-#define dma_sync_single_for_device(dev, addr, size, dir) ((void)0)
-#define dma_sync_single_range(dev, addr, off, size, dir) ((void)0)
-#define dma_sync_sg_for_cpu(dev, sg, nents, dir) ((void)0)
-#define dma_sync_sg_for_device(dev, sg, nents, dir) ((void)0)
#define dma_cache_sync(dev, va, size, dir) ((void)0)
-#define dma_sync_single_range_for_cpu(dev, addr, offset, size, dir) ((void)0)
-#define dma_sync_single_range_for_device(dev, addr, offset, size, dir) ((void)0)
-
#define dma_get_cache_alignment() L1_CACHE_BYTES
#endif /* _ALPHA_DMA_MAPPING_H */
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index dd8dcabf160..28d0497fd3c 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -70,142 +70,11 @@ extern inline void pcibios_penalize_isa_irq(int irq, int active)
decisions. */
#define PCI_DMA_BUS_IS_PHYS 0
-/* Allocate and map kernel buffer using consistent mode DMA for PCI
- device. Returns non-NULL cpu-view pointer to the buffer if
- successful and sets *DMA_ADDRP to the pci side dma address as well,
- else DMA_ADDRP is undefined. */
-
-extern void *__pci_alloc_consistent(struct pci_dev *, size_t,
- dma_addr_t *, gfp_t);
-static inline void *
-pci_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma)
-{
- return __pci_alloc_consistent(dev, size, dma, GFP_ATOMIC);
-}
-
-/* Free and unmap a consistent DMA buffer. CPU_ADDR and DMA_ADDR must
- be values that were returned from pci_alloc_consistent. SIZE must
- be the same as what as passed into pci_alloc_consistent.
- References to the memory and mappings associated with CPU_ADDR or
- DMA_ADDR past this call are illegal. */
-
-extern void pci_free_consistent(struct pci_dev *, size_t, void *, dma_addr_t);
-
-/* Map a single buffer of the indicate size for PCI DMA in streaming mode.
- The 32-bit PCI bus mastering address to use is returned. Once the device
- is given the dma address, the device owns this memory until either
- pci_unmap_single or pci_dma_sync_single_for_cpu is performed. */
-
-extern dma_addr_t pci_map_single(struct pci_dev *, void *, size_t, int);
-
-/* Likewise, but for a page instead of an address. */
-extern dma_addr_t pci_map_page(struct pci_dev *, struct page *,
- unsigned long, size_t, int);
-
-/* Test for pci_map_single or pci_map_page having generated an error. */
-
-static inline int
-pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr)
-{
- return dma_addr == 0;
-}
-
-/* Unmap a single streaming mode DMA translation. The DMA_ADDR and
- SIZE must match what was provided for in a previous pci_map_single
- call. All other usages are undefined. After this call, reads by
- the cpu to the buffer are guaranteed to see whatever the device
- wrote there. */
-
-extern void pci_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
-extern void pci_unmap_page(struct pci_dev *, dma_addr_t, size_t, int);
-
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
-/* Map a set of buffers described by scatterlist in streaming mode for
- PCI DMA. This is the scatter-gather version of the above
- pci_map_single interface. Here the scatter gather list elements
- are each tagged with the appropriate PCI dma address and length.
- They are obtained via sg_dma_{address,length}(SG).
-
- NOTE: An implementation may be able to use a smaller number of DMA
- address/length pairs than there are SG table elements. (for
- example via virtual mapping capabilities) The routine returns the
- number of addr/length pairs actually used, at most nents.
-
- Device ownership issues as mentioned above for pci_map_single are
- the same here. */
-
-extern int pci_map_sg(struct pci_dev *, struct scatterlist *, int, int);
-
-/* Unmap a set of streaming mode DMA translations. Again, cpu read
- rules concerning calls here are the same as for pci_unmap_single()
- above. */
-
-extern void pci_unmap_sg(struct pci_dev *, struct scatterlist *, int, int);
-
-/* Make physical memory consistent for a single streaming mode DMA
- translation after a transfer and device currently has ownership
- of the buffer.
-
- If you perform a pci_map_single() but wish to interrogate the
- buffer using the cpu, yet do not wish to teardown the PCI dma
- mapping, you must call this function before doing so. At the next
- point you give the PCI dma address back to the card, you must first
- perform a pci_dma_sync_for_device, and then the device again owns
- the buffer. */
-
-static inline void
-pci_dma_sync_single_for_cpu(struct pci_dev *dev, dma_addr_t dma_addr,
- long size, int direction)
-{
- /* Nothing to do. */
-}
-
-static inline void
-pci_dma_sync_single_for_device(struct pci_dev *dev, dma_addr_t dma_addr,
- size_t size, int direction)
-{
- /* Nothing to do. */
-}
-
-/* Make physical memory consistent for a set of streaming mode DMA
- translations after a transfer. The same as pci_dma_sync_single_*
- but for a scatter-gather list, same rules and usage. */
-
-static inline void
-pci_dma_sync_sg_for_cpu(struct pci_dev *dev, struct scatterlist *sg,
- int nents, int direction)
-{
- /* Nothing to do. */
-}
-
-static inline void
-pci_dma_sync_sg_for_device(struct pci_dev *dev, struct scatterlist *sg,
- int nents, int direction)
-{
- /* Nothing to do. */
-}
-
-/* Return whether the given PCI device DMA address mask can
- be supported properly. For example, if your device can
- only drive the low 24-bits during PCI bus mastering, then
- you would pass 0x00ffffff as the mask to this function. */
+#ifdef CONFIG_PCI
-extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
+/* implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>
-#ifdef CONFIG_PCI
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
enum pci_dma_burst_strategy *strat,
unsigned long *strategy_parameter)
@@ -244,8 +113,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
return hose->need_domain_info;
}
-struct pci_dev *alpha_gendev_to_pci(struct device *dev);
-
#endif /* __KERNEL__ */
/* Values for the `which' argument to sys_pciconfig_iobase. */
diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h
index 32c7a5cddd5..65cf3e28e2f 100644
--- a/arch/alpha/include/asm/ptrace.h
+++ b/arch/alpha/include/asm/ptrace.h
@@ -68,6 +68,7 @@ struct switch_stack {
#ifdef __KERNEL__
+#define arch_has_single_step() (1)
#define user_mode(regs) (((regs)->ps & 8) != 0)
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 5f2cf23c464..7f912ba3d9a 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -18,7 +18,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/irq.h>
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 62619f25132..de9d3971780 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -20,7 +20,6 @@
#include <linux/syscalls.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/utsname.h>
#include <linux/time.h>
@@ -37,6 +36,7 @@
#include <linux/uio.h>
#include <linux/vfs.h>
#include <linux/rcupdate.h>
+#include <linux/slab.h>
#include <asm/fpu.h>
#include <asm/io.h>
@@ -361,7 +361,7 @@ osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags)
SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
int, flag, void __user *, data)
{
- int retval = -EINVAL;
+ int retval;
char *name;
name = getname(path);
@@ -379,6 +379,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
retval = osf_procfs_mount(name, data, flag);
break;
default:
+ retval = -EINVAL;
printk("osf_mount(%ld, %x)\n", typenr, flag);
}
putname(name);
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index c19a376520f..246100ef07c 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -7,6 +7,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/gfp.h>
#include <linux/capability.h>
#include <linux/mm.h>
#include <linux/errno.h>
@@ -106,58 +107,8 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
return -ENODEV;
}
-/* Stubs for the routines in pci_iommu.c: */
-
-void *
-__pci_alloc_consistent(struct pci_dev *pdev, size_t size,
- dma_addr_t *dma_addrp, gfp_t gfp)
-{
- return NULL;
-}
-
-void
-pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
- dma_addr_t dma_addr)
-{
-}
-
-dma_addr_t
-pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size,
- int direction)
-{
- return (dma_addr_t) 0;
-}
-
-void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
- int direction)
-{
-}
-
-int
-pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
- int direction)
-{
- return 0;
-}
-
-void
-pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
- int direction)
-{
-}
-
-int
-pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
-{
- return 0;
-}
-
-/* Generic DMA mapping functions: */
-
-void *
-dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
+static void *alpha_noop_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
@@ -171,11 +122,22 @@ dma_alloc_coherent(struct device *dev, size_t size,
return ret;
}
-EXPORT_SYMBOL(dma_alloc_coherent);
+static void alpha_noop_free_coherent(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_addr)
+{
+ free_pages((unsigned long)cpu_addr, get_order(size));
+}
+
+static dma_addr_t alpha_noop_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ return page_to_pa(page) + offset;
+}
-int
-dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
- enum dma_data_direction direction)
+static int alpha_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
int i;
struct scatterlist *sg;
@@ -192,19 +154,37 @@ dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
+static int alpha_noop_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static int alpha_noop_supported(struct device *dev, u64 mask)
+{
+ return mask < 0x00ffffffUL ? 0 : 1;
+}
-int
-dma_set_mask(struct device *dev, u64 mask)
+static int alpha_noop_set_mask(struct device *dev, u64 mask)
{
if (!dev->dma_mask || !dma_supported(dev, mask))
return -EIO;
*dev->dma_mask = mask;
-
return 0;
}
-EXPORT_SYMBOL(dma_set_mask);
+
+struct dma_map_ops alpha_noop_ops = {
+ .alloc_coherent = alpha_noop_alloc_coherent,
+ .free_coherent = alpha_noop_free_coherent,
+ .map_page = alpha_noop_map_page,
+ .map_sg = alpha_noop_map_sg,
+ .mapping_error = alpha_noop_mapping_error,
+ .dma_supported = alpha_noop_supported,
+ .set_dma_mask = alpha_noop_set_mask,
+};
+
+struct dma_map_ops *dma_ops = &alpha_noop_ops;
+EXPORT_SYMBOL(dma_ops);
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
{
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 6ea822e7f72..d979e7c7bc4 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -10,6 +10,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/pci.h>
static int hose_mmap_page_range(struct pci_controller *hose,
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 8449504f5e0..d1dbd9acd1d 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -5,7 +5,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/pci.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/bootmem.h>
#include <linux/scatterlist.h>
#include <linux/log2.h>
@@ -216,10 +216,30 @@ iommu_arena_free(struct pci_iommu_arena *arena, long ofs, long n)
for (i = 0; i < n; ++i)
p[i] = 0;
}
-
-/* True if the machine supports DAC addressing, and DEV can
- make use of it given MASK. */
-static int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
+
+/*
+ * True if the machine supports DAC addressing, and DEV can
+ * make use of it given MASK.
+ */
+static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
+{
+ dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
+ int ok = 1;
+
+ /* If this is not set, the machine doesn't support DAC at all. */
+ if (dac_offset == 0)
+ ok = 0;
+
+ /* The device has to be able to address our DAC bit. */
+ if ((dac_offset & dev->dma_mask) != dac_offset)
+ ok = 0;
+
+ /* If both conditions above are met, we are fine. */
+ DBGA("pci_dac_dma_supported %s from %p\n",
+ ok ? "yes" : "no", __builtin_return_address(0));
+
+ return ok;
+}
/* Map a single buffer of the indicated size for PCI DMA in streaming
mode. The 32-bit PCI bus mastering address to use is returned.
@@ -301,23 +321,36 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
return ret;
}
-dma_addr_t
-pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
+/* Helper for generic DMA-mapping functions. */
+static struct pci_dev *alpha_gendev_to_pci(struct device *dev)
{
- int dac_allowed;
+ if (dev && dev->bus == &pci_bus_type)
+ return to_pci_dev(dev);
- if (dir == PCI_DMA_NONE)
- BUG();
+ /* Assume that non-PCI devices asking for DMA are either ISA or EISA,
+ BUG() otherwise. */
+ BUG_ON(!isa_bridge);
- dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
- return pci_map_single_1(pdev, cpu_addr, size, dac_allowed);
+ /* Assume non-busmaster ISA DMA when dma_mask is not set (the ISA
+ bridge is bus master then). */
+ if (!dev || !dev->dma_mask || !*dev->dma_mask)
+ return isa_bridge;
+
+ /* For EISA bus masters, return isa_bridge (it might have smaller
+ dma_mask due to wiring limitations). */
+ if (*dev->dma_mask >= isa_bridge->dma_mask)
+ return isa_bridge;
+
+ /* This assumes ISA bus master with dma_mask 0xffffff. */
+ return NULL;
}
-EXPORT_SYMBOL(pci_map_single);
-dma_addr_t
-pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset,
- size_t size, int dir)
+static dma_addr_t alpha_pci_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
int dac_allowed;
if (dir == PCI_DMA_NONE)
@@ -327,7 +360,6 @@ pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset,
return pci_map_single_1(pdev, (char *)page_address(page) + offset,
size, dac_allowed);
}
-EXPORT_SYMBOL(pci_map_page);
/* Unmap a single streaming mode DMA translation. The DMA_ADDR and
SIZE must match what was provided for in a previous pci_map_single
@@ -335,16 +367,17 @@ EXPORT_SYMBOL(pci_map_page);
the cpu to the buffer are guaranteed to see whatever the device
wrote there. */
-void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
- int direction)
+static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
unsigned long flags;
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
struct pci_iommu_arena *arena;
long dma_ofs, npages;
- if (direction == PCI_DMA_NONE)
+ if (dir == PCI_DMA_NONE)
BUG();
if (dma_addr >= __direct_map_base
@@ -393,25 +426,16 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n",
dma_addr, size, npages, __builtin_return_address(0));
}
-EXPORT_SYMBOL(pci_unmap_single);
-
-void
-pci_unmap_page(struct pci_dev *pdev, dma_addr_t dma_addr,
- size_t size, int direction)
-{
- pci_unmap_single(pdev, dma_addr, size, direction);
-}
-EXPORT_SYMBOL(pci_unmap_page);
/* Allocate and map kernel buffer using consistent mode DMA for PCI
device. Returns non-NULL cpu-view pointer to the buffer if
successful and sets *DMA_ADDRP to the pci side dma address as well,
else DMA_ADDRP is undefined. */
-void *
-__pci_alloc_consistent(struct pci_dev *pdev, size_t size,
- dma_addr_t *dma_addrp, gfp_t gfp)
+static void *alpha_pci_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_addrp, gfp_t gfp)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
void *cpu_addr;
long order = get_order(size);
@@ -439,13 +463,12 @@ try_again:
gfp |= GFP_DMA;
goto try_again;
}
-
+
DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n",
size, cpu_addr, *dma_addrp, __builtin_return_address(0));
return cpu_addr;
}
-EXPORT_SYMBOL(__pci_alloc_consistent);
/* Free and unmap a consistent DMA buffer. CPU_ADDR and DMA_ADDR must
be values that were returned from pci_alloc_consistent. SIZE must
@@ -453,17 +476,16 @@ EXPORT_SYMBOL(__pci_alloc_consistent);
References to the memory and mappings associated with CPU_ADDR or
DMA_ADDR past this call are illegal. */
-void
-pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
- dma_addr_t dma_addr)
+static void alpha_pci_free_coherent(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_addr)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
free_pages((unsigned long)cpu_addr, get_order(size));
DBGA2("pci_free_consistent: [%llx,%zx] from %p\n",
dma_addr, size, __builtin_return_address(0));
}
-EXPORT_SYMBOL(pci_free_consistent);
/* Classify the elements of the scatterlist. Write dma_address
of each element with:
@@ -626,23 +648,21 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
return 1;
}
-int
-pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
- int direction)
+static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
struct scatterlist *start, *end, *out;
struct pci_controller *hose;
struct pci_iommu_arena *arena;
dma_addr_t max_dma;
int dac_allowed;
- struct device *dev;
- if (direction == PCI_DMA_NONE)
+ if (dir == PCI_DMA_NONE)
BUG();
- dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
-
- dev = pdev ? &pdev->dev : NULL;
+ dac_allowed = dev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
/* Fast path single entry scatterlists. */
if (nents == 1) {
@@ -699,19 +719,19 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
/* Some allocation failed while mapping the scatterlist
entries. Unmap them now. */
if (out > start)
- pci_unmap_sg(pdev, start, out - start, direction);
+ pci_unmap_sg(pdev, start, out - start, dir);
return 0;
}
-EXPORT_SYMBOL(pci_map_sg);
/* Unmap a set of streaming mode DMA translations. Again, cpu read
rules concerning calls here are the same as for pci_unmap_single()
above. */
-void
-pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
- int direction)
+static void alpha_pci_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
unsigned long flags;
struct pci_controller *hose;
struct pci_iommu_arena *arena;
@@ -719,7 +739,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
dma_addr_t max_dma;
dma_addr_t fbeg, fend;
- if (direction == PCI_DMA_NONE)
+ if (dir == PCI_DMA_NONE)
BUG();
if (! alpha_mv.mv_pci_tbi)
@@ -783,15 +803,13 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
DBGA("pci_unmap_sg: %ld entries\n", nents - (end - sg));
}
-EXPORT_SYMBOL(pci_unmap_sg);
-
/* Return whether the given PCI device DMA address mask can be
supported properly. */
-int
-pci_dma_supported(struct pci_dev *pdev, u64 mask)
+static int alpha_pci_supported(struct device *dev, u64 mask)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
struct pci_controller *hose;
struct pci_iommu_arena *arena;
@@ -818,7 +836,6 @@ pci_dma_supported(struct pci_dev *pdev, u64 mask)
return 0;
}
-EXPORT_SYMBOL(pci_dma_supported);
/*
@@ -918,66 +935,32 @@ iommu_unbind(struct pci_iommu_arena *arena, long pg_start, long pg_count)
return 0;
}
-/* True if the machine supports DAC addressing, and DEV can
- make use of it given MASK. */
-
-static int
-pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
-{
- dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
- int ok = 1;
-
- /* If this is not set, the machine doesn't support DAC at all. */
- if (dac_offset == 0)
- ok = 0;
-
- /* The device has to be able to address our DAC bit. */
- if ((dac_offset & dev->dma_mask) != dac_offset)
- ok = 0;
-
- /* If both conditions above are met, we are fine. */
- DBGA("pci_dac_dma_supported %s from %p\n",
- ok ? "yes" : "no", __builtin_return_address(0));
-
- return ok;
-}
-
-/* Helper for generic DMA-mapping functions. */
-
-struct pci_dev *
-alpha_gendev_to_pci(struct device *dev)
+static int alpha_pci_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
- if (dev && dev->bus == &pci_bus_type)
- return to_pci_dev(dev);
-
- /* Assume that non-PCI devices asking for DMA are either ISA or EISA,
- BUG() otherwise. */
- BUG_ON(!isa_bridge);
-
- /* Assume non-busmaster ISA DMA when dma_mask is not set (the ISA
- bridge is bus master then). */
- if (!dev || !dev->dma_mask || !*dev->dma_mask)
- return isa_bridge;
-
- /* For EISA bus masters, return isa_bridge (it might have smaller
- dma_mask due to wiring limitations). */
- if (*dev->dma_mask >= isa_bridge->dma_mask)
- return isa_bridge;
-
- /* This assumes ISA bus master with dma_mask 0xffffff. */
- return NULL;
+ return dma_addr == 0;
}
-EXPORT_SYMBOL(alpha_gendev_to_pci);
-int
-dma_set_mask(struct device *dev, u64 mask)
+static int alpha_pci_set_mask(struct device *dev, u64 mask)
{
if (!dev->dma_mask ||
!pci_dma_supported(alpha_gendev_to_pci(dev), mask))
return -EIO;
*dev->dma_mask = mask;
-
return 0;
}
-EXPORT_SYMBOL(dma_set_mask);
+
+struct dma_map_ops alpha_pci_ops = {
+ .alloc_coherent = alpha_pci_alloc_coherent,
+ .free_coherent = alpha_pci_free_coherent,
+ .map_page = alpha_pci_map_page,
+ .unmap_page = alpha_pci_unmap_page,
+ .map_sg = alpha_pci_map_sg,
+ .unmap_sg = alpha_pci_unmap_sg,
+ .mapping_error = alpha_pci_mapping_error,
+ .dma_supported = alpha_pci_supported,
+ .set_dma_mask = alpha_pci_set_mask,
+};
+
+struct dma_map_ops *dma_ops = &alpha_pci_ops;
+EXPORT_SYMBOL(dma_ops);
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 289039bb6bb..395a464353b 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -17,7 +17,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/time.h>
#include <linux/major.h>
@@ -28,6 +27,7 @@
#include <linux/reboot.h>
#include <linux/tty.h>
#include <linux/console.h>
+#include <linux/slab.h>
#include <asm/reg.h>
#include <asm/uaccess.h>
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index e072041d19f..baa903602f6 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -11,7 +11,6 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
-#include <linux/slab.h>
#include <linux/security.h>
#include <linux/signal.h>
@@ -249,6 +248,17 @@ ptrace_cancel_bpt(struct task_struct * child)
return (nsaved != 0);
}
+void user_enable_single_step(struct task_struct *child)
+{
+ /* Mark single stepping. */
+ task_thread_info(child)->bpt_nsaved = -1;
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+ ptrace_cancel_bpt(child);
+}
+
/*
* Called by kernel/ptrace.c when detaching..
*
@@ -256,7 +266,7 @@ ptrace_cancel_bpt(struct task_struct * child)
*/
void ptrace_disable(struct task_struct *child)
{
- ptrace_cancel_bpt(child);
+ user_disable_single_step(child);
}
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -295,52 +305,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data));
ret = put_reg(child, addr, data);
break;
-
- case PTRACE_SYSCALL:
- /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: /* restart after signal. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- /* make sure single-step breakpoint is gone. */
- ptrace_cancel_bpt(child);
- wake_up_process(child);
- ret = 0;
- break;
-
- /*
- * Make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL:
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE)
- break;
- child->exit_code = SIGKILL;
- /* make sure single-step breakpoint is gone. */
- ptrace_cancel_bpt(child);
- wake_up_process(child);
- break;
-
- case PTRACE_SINGLESTEP: /* execute single instruction. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- /* Mark single stepping. */
- task_thread_info(child)->bpt_nsaved = -1;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- wake_up_process(child);
- /* give it a chance to run. */
- ret = 0;
- break;
-
default:
ret = ptrace_request(child, request, addr, data);
break;
diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
index bca5bda90cd..0435921d41c 100644
--- a/arch/alpha/kernel/smc37c669.c
+++ b/arch/alpha/kernel/smc37c669.c
@@ -3,7 +3,6 @@
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/arch/alpha/kernel/smc37c93x.c b/arch/alpha/kernel/smc37c93x.c
index 2636cc028d0..3e6a2893af9 100644
--- a/arch/alpha/kernel/smc37c93x.c
+++ b/arch/alpha/kernel/smc37c93x.c
@@ -4,7 +4,6 @@
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c
index dbbf04f9230..4afc1a1e2e5 100644
--- a/arch/alpha/kernel/srm_env.c
+++ b/arch/alpha/kernel/srm_env.c
@@ -30,6 +30,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index d64e1e497e7..4026502ab70 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -224,7 +224,7 @@ static void
dp264_device_interrupt(unsigned long vector)
{
#if 1
- printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
+ printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n");
#else
unsigned long pld;
unsigned int i;
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 288053342c8..9008d0f20c5 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -171,7 +171,7 @@ titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
static void
titan_device_interrupt(unsigned long vector)
{
- printk("titan_device_interrupt: NOT IMPLEMENTED YET!! \n");
+ printk("titan_device_interrupt: NOT IMPLEMENTED YET!!\n");
}
static void
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 6ee7655b756..b14f015008a 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kallsyms.h>
+#include <linux/ratelimit.h>
#include <asm/gentrap.h>
#include <asm/uaccess.h>
@@ -771,8 +772,7 @@ asmlinkage void
do_entUnaUser(void __user * va, unsigned long opcode,
unsigned long reg, struct pt_regs *regs)
{
- static int cnt = 0;
- static unsigned long last_time;
+ static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
unsigned long tmp1, tmp2, tmp3, tmp4;
unsigned long fake_reg, *reg_addr = &fake_reg;
@@ -783,15 +783,11 @@ do_entUnaUser(void __user * va, unsigned long opcode,
with the unaliged access. */
if (!test_thread_flag (TIF_UAC_NOPRINT)) {
- if (cnt >= 5 && time_after(jiffies, last_time + 5 * HZ)) {
- cnt = 0;
- }
- if (++cnt < 5) {
+ if (__ratelimit(&ratelimit)) {
printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
current->comm, task_pid_nr(current),
regs->pc - 4, va, opcode, reg);
}
- last_time = jiffies;
}
if (test_thread_flag (TIF_UAC_SIGBUS))
goto give_sigbus;
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index a0902c20d67..86425ab53bf 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/bootmem.h> /* max_low_pfn */
#include <linux/vmalloc.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3b181284970..92622eb5cc0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -155,6 +155,9 @@ config ARCH_MAY_HAVE_PC_FDC
config ZONE_DMA
bool
+config NEED_DMA_MAP_STATE
+ def_bool y
+
config GENERIC_ISA_DMA
bool
@@ -215,6 +218,10 @@ config MMU
Select if you want MMU-based virtualised addressing space
support by paged memory management. If unsure, say 'Y'.
+#
+# The "ARM system type" choice list is ordered alphabetically by option
+# text. Please add new entries in the option alphabetic order.
+#
choice
prompt "ARM system type"
default ARCH_VERSATILE
@@ -246,6 +253,7 @@ config ARCH_REALVIEW
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
+ select GPIO_PL061 if GPIOLIB
help
This enables support for ARM Ltd RealView boards.
@@ -271,6 +279,18 @@ config ARCH_AT91
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
+config ARCH_BCMRING
+ bool "Broadcom BCMRING"
+ depends on MMU
+ select CPU_V6
+ select ARM_AMBA
+ select COMMON_CLKDEV
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ help
+ Support for Broadcom's BCMRing platform.
+
config ARCH_CLPS711X
bool "Cirrus Logic CLPS711x/EP721x-based"
select CPU_ARM720T
@@ -321,10 +341,9 @@ config ARCH_MXC
bool "Freescale MXC/iMX-based"
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
- select ARCH_MTD_XIP
- select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
+ select COMMON_CLKDEV
help
Support for Freescale MXC/iMX-based family of processors
@@ -357,20 +376,6 @@ config ARCH_H720X
help
This enables support for systems based on the Hynix HMS720x
-config ARCH_NOMADIK
- bool "STMicroelectronics Nomadik"
- select ARM_AMBA
- select ARM_VIC
- select CPU_ARM926T
- select HAVE_CLK
- select COMMON_CLKDEV
- select GENERIC_TIME
- select GENERIC_CLOCKEVENTS
- select GENERIC_GPIO
- select ARCH_REQUIRE_GPIOLIB
- help
- Support for the Nomadik platform by ST-Ericsson
-
config ARCH_IOP13XX
bool "IOP13xx-based"
depends on MMU
@@ -508,7 +513,7 @@ config ARCH_ORION5X
Orion-2 (5281), Orion-1-90 (6183).
config ARCH_MMP
- bool "Marvell PXA168/910"
+ bool "Marvell PXA168/910/MMP2"
depends on MMU
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
@@ -519,7 +524,7 @@ config ARCH_MMP
select TICK_ONESHOT
select PLAT_PXA
help
- Support for Marvell's PXA168/910 processor line.
+ Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
config ARCH_KS8695
bool "Micrel/Kendin KS8695"
@@ -605,6 +610,11 @@ config ARCH_MSM
interface to the ARM9 modem processor which runs the baseband stack
and controls some vital subsystems (clock and power control, etc).
+config ARCH_SHMOBILE
+ bool "Renesas SH-Mobile"
+ help
+ Support for Renesas's SH-Mobile ARM platforms
+
config ARCH_RPC
bool "RiscPC"
select ARCH_ACORN
@@ -648,12 +658,43 @@ config ARCH_S3C2410
config ARCH_S3C64XX
bool "Samsung S3C64XX"
+ select PLAT_SAMSUNG
+ select CPU_V6
select GENERIC_GPIO
+ select ARM_VIC
select HAVE_CLK
+ select NO_IOPORT
select ARCH_HAS_CPUFREQ
+ select ARCH_REQUIRE_GPIOLIB
+ select SAMSUNG_CLKSRC
+ select SAMSUNG_IRQ_VIC_TIMER
+ select SAMSUNG_IRQ_UART
+ select S3C_GPIO_TRACK
+ select S3C_GPIO_PULL_UPDOWN
+ select S3C_GPIO_CFG_S3C24XX
+ select S3C_GPIO_CFG_S3C64XX
+ select S3C_DEV_NAND
+ select USB_ARCH_HAS_OHCI
+ select SAMSUNG_GPIOLIB_4BIT
help
Samsung S3C64XX series based systems
+config ARCH_S5P6440
+ bool "Samsung S5P6440"
+ select CPU_V6
+ select GENERIC_GPIO
+ select HAVE_CLK
+ help
+ Samsung S5P6440 CPU based systems
+
+config ARCH_S5P6442
+ bool "Samsung S5P6442"
+ select CPU_V6
+ select GENERIC_GPIO
+ select HAVE_CLK
+ help
+ Samsung S5P6442 CPU based systems
+
config ARCH_S5PC1XX
bool "Samsung S5PC1XX"
select GENERIC_GPIO
@@ -663,6 +704,15 @@ config ARCH_S5PC1XX
help
Samsung S5PC1XX series based systems
+config ARCH_S5PV210
+ bool "Samsung S5PV210/S5PC110"
+ select CPU_V7
+ select GENERIC_GPIO
+ select HAVE_CLK
+ select ARM_L1_CACHE_SHIFT_6
+ help
+ Samsung S5PV210/S5PC110 series based systems
+
config ARCH_SHARK
bool "Shark"
select CPU_SA110
@@ -700,6 +750,30 @@ config ARCH_U300
help
Support for ST-Ericsson U300 series mobile platforms.
+config ARCH_U8500
+ bool "ST-Ericsson U8500 Series"
+ select CPU_V7
+ select ARM_AMBA
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select COMMON_CLKDEV
+ help
+ Support for ST-Ericsson's Ux500 architecture
+
+config ARCH_NOMADIK
+ bool "STMicroelectronics Nomadik"
+ select ARM_AMBA
+ select ARM_VIC
+ select CPU_ARM926T
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for the Nomadik platform by ST-Ericsson
+
config ARCH_DAVINCI
bool "TI DaVinci"
select CPU_ARM926T
@@ -728,30 +802,13 @@ config ARCH_OMAP
help
Support for TI's OMAP platform (OMAP1 and OMAP2).
-config ARCH_BCMRING
- bool "Broadcom BCMRING"
- depends on MMU
- select CPU_V6
- select ARM_AMBA
- select COMMON_CLKDEV
- select GENERIC_TIME
- select GENERIC_CLOCKEVENTS
- select ARCH_WANT_OPTIONAL_GPIOLIB
- help
- Support for Broadcom's BCMRing platform.
-
-config ARCH_U8500
- bool "ST-Ericsson U8500 Series"
- select CPU_V7
- select ARM_AMBA
- select GENERIC_TIME
- select GENERIC_CLOCKEVENTS
- select COMMON_CLKDEV
- help
- Support for ST-Ericsson's Ux500 architecture
-
endchoice
+#
+# This is sorted alphabetically by mach-* pathname. However, plat-*
+# Kconfigs may be included either alphabetically (according to the
+# plat- suffix) or along side the corresponding mach-* source.
+#
source "arch/arm/mach-aaec2000/Kconfig"
source "arch/arm/mach-at91/Kconfig"
@@ -828,8 +885,7 @@ source "arch/arm/mach-sa1100/Kconfig"
source "arch/arm/plat-samsung/Kconfig"
source "arch/arm/plat-s3c24xx/Kconfig"
-source "arch/arm/plat-s3c64xx/Kconfig"
-source "arch/arm/plat-s3c/Kconfig"
+source "arch/arm/plat-s5p/Kconfig"
source "arch/arm/plat-s5pc1xx/Kconfig"
if ARCH_S3C2410
@@ -837,21 +893,27 @@ source "arch/arm/mach-s3c2400/Kconfig"
source "arch/arm/mach-s3c2410/Kconfig"
source "arch/arm/mach-s3c2412/Kconfig"
source "arch/arm/mach-s3c2440/Kconfig"
-source "arch/arm/mach-s3c2442/Kconfig"
source "arch/arm/mach-s3c2443/Kconfig"
endif
if ARCH_S3C64XX
-source "arch/arm/mach-s3c6400/Kconfig"
-source "arch/arm/mach-s3c6410/Kconfig"
+source "arch/arm/mach-s3c64xx/Kconfig"
endif
-source "arch/arm/plat-stmp3xxx/Kconfig"
+source "arch/arm/mach-s5p6440/Kconfig"
+
+source "arch/arm/mach-s5p6442/Kconfig"
if ARCH_S5PC1XX
source "arch/arm/mach-s5pc100/Kconfig"
endif
+source "arch/arm/mach-s5pv210/Kconfig"
+
+source "arch/arm/mach-shmobile/Kconfig"
+
+source "arch/arm/plat-stmp3xxx/Kconfig"
+
source "arch/arm/mach-u300/Kconfig"
source "arch/arm/mach-ux500/Kconfig"
@@ -1117,7 +1179,7 @@ source kernel/Kconfig.preempt
config HZ
int
default 128 if ARCH_L7200
- default 200 if ARCH_EBSA110 || ARCH_S3C2410
+ 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
default 100
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 5cb9326df7a..91344af75f3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -117,7 +117,7 @@ config DEBUG_CLPS711X_UART2
cause the debug messages to appear on the first serial port.
config DEBUG_S3C_UART
- depends on PLAT_S3C
+ depends on PLAT_SAMSUNG
int "S3C UART to use for low-level debug"
default "0"
help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 81f54ca3078..ed820e737a8 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -146,6 +146,7 @@ machine-$(CONFIG_ARCH_MX1) := mx1
machine-$(CONFIG_ARCH_MX2) := mx2
machine-$(CONFIG_ARCH_MX25) := mx25
machine-$(CONFIG_ARCH_MX3) := mx3
+machine-$(CONFIG_ARCH_MX5) := mx5
machine-$(CONFIG_ARCH_MXC91231) := mxc91231
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
@@ -159,12 +160,16 @@ machine-$(CONFIG_ARCH_PNX4008) := pnx4008
machine-$(CONFIG_ARCH_PXA) := pxa
machine-$(CONFIG_ARCH_REALVIEW) := realview
machine-$(CONFIG_ARCH_RPC) := rpc
-machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
+machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2443
machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
-machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410
+machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
+machine-$(CONFIG_ARCH_S5P6440) := s5p6440
+machine-$(CONFIG_ARCH_S5P6442) := s5p6442
machine-$(CONFIG_ARCH_S5PC1XX) := s5pc100
+machine-$(CONFIG_ARCH_S5PV210) := s5pv210
machine-$(CONFIG_ARCH_SA1100) := sa1100
machine-$(CONFIG_ARCH_SHARK) := shark
+machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
machine-$(CONFIG_ARCH_STMP378X) := stmp378x
machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
machine-$(CONFIG_ARCH_U300) := u300
@@ -178,14 +183,15 @@ machine-$(CONFIG_FOOTBRIDGE) := footbridge
# by CONFIG_* macro name.
plat-$(CONFIG_ARCH_MXC) := mxc
plat-$(CONFIG_ARCH_OMAP) := omap
+plat-$(CONFIG_ARCH_S3C64XX) := samsung
plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
plat-$(CONFIG_PLAT_IOP) := iop
plat-$(CONFIG_PLAT_NOMADIK) := nomadik
plat-$(CONFIG_PLAT_ORION) := orion
plat-$(CONFIG_PLAT_PXA) := pxa
-plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c samsung
-plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c samsung
-plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx s3c samsung
+plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung
+plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx samsung
+plat-$(CONFIG_PLAT_S5P) := s5p samsung
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S
index df7bc7068d0..8b0de41c3dc 100644
--- a/arch/arm/boot/bootp/init.S
+++ b/arch/arm/boot/bootp/init.S
@@ -49,7 +49,7 @@ _start: add lr, pc, #-0x8 @ lr = current load addr
/*
* find the end of the tag list, and then add an INITRD tag on the end.
* If there is already an INITRD tag, then we ignore it; the last INITRD
- * tag takes precidence.
+ * tag takes precedence.
*/
taglist: ldr r10, [r9, #0] @ tag length
teq r10, #0 @ last tag (zero length)?
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
index 0da382f3315..9c097073ce4 100644
--- a/arch/arm/boot/compressed/decompress.c
+++ b/arch/arm/boot/compressed/decompress.c
@@ -11,6 +11,7 @@ extern unsigned long free_mem_end_ptr;
extern void error(char *);
#define STATIC static
+#define STATIC_RW_DATA /* non-static please */
#define ARCH_HAS_DECOMP_WDOG
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 99b75aa1c2e..6ab6b337a91 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -170,9 +170,9 @@ not_angel:
.text
adr r0, LC0
- ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} )
- THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, ip} )
- THUMB( ldr sp, [r0, #28] )
+ ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
+ THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} )
+ THUMB( ldr sp, [r0, #32] )
subs r0, r0, r1 @ calculate the delta offset
@ if delta is zero, we are
@@ -182,12 +182,13 @@ not_angel:
/*
* We're running at a different address. We need to fix
* up various pointers:
- * r5 - zImage base address
- * r6 - GOT start
+ * r5 - zImage base address (_start)
+ * r6 - size of decompressed image
+ * r11 - GOT start
* ip - GOT end
*/
add r5, r5, r0
- add r6, r6, r0
+ add r11, r11, r0
add ip, ip, r0
#ifndef CONFIG_ZBOOT_ROM
@@ -205,10 +206,10 @@ not_angel:
/*
* Relocate all entries in the GOT table.
*/
-1: ldr r1, [r6, #0] @ relocate entries in the GOT
+1: ldr r1, [r11, #0] @ relocate entries in the GOT
add r1, r1, r0 @ table. This fixes up the
- str r1, [r6], #4 @ C references.
- cmp r6, ip
+ str r1, [r11], #4 @ C references.
+ cmp r11, ip
blo 1b
#else
@@ -216,12 +217,12 @@ not_angel:
* Relocate entries in the GOT table. We only relocate
* the entries that are outside the (relocated) BSS region.
*/
-1: ldr r1, [r6, #0] @ relocate entries in the GOT
+1: ldr r1, [r11, #0] @ relocate entries in the GOT
cmp r1, r2 @ entry < bss_start ||
cmphs r3, r1 @ _end < entry
addlo r1, r1, r0 @ table. This fixes up the
- str r1, [r6], #4 @ C references.
- cmp r6, ip
+ str r1, [r11], #4 @ C references.
+ cmp r11, ip
blo 1b
#endif
@@ -247,6 +248,7 @@ not_relocated: mov r0, #0
* Check to see if we will overwrite ourselves.
* r4 = final kernel address
* r5 = start of this image
+ * r6 = size of decompressed image
* r2 = end of malloc space (and therefore this image)
* We basically want:
* r4 >= r2 -> OK
@@ -254,8 +256,7 @@ not_relocated: mov r0, #0
*/
cmp r4, r2
bhs wont_overwrite
- sub r3, sp, r5 @ > compressed kernel size
- add r0, r4, r3, lsl #2 @ allow for 4x expansion
+ add r0, r4, r6
cmp r0, r5
bls wont_overwrite
@@ -271,7 +272,6 @@ not_relocated: mov r0, #0
* r1-r3 = unused
* r4 = kernel execution address
* r5 = decompressed kernel start
- * r6 = processor ID
* r7 = architecture ID
* r8 = atags pointer
* r9-r12,r14 = corrupted
@@ -312,7 +312,8 @@ LC0: .word LC0 @ r1
.word _end @ r3
.word zreladdr @ r4
.word _start @ r5
- .word _got_start @ r6
+ .word _image_size @ r6
+ .word _got_start @ r11
.word _got_end @ ip
.word user_stack+4096 @ sp
LC1: .word reloc_end - reloc_start
@@ -336,7 +337,6 @@ params: ldr r0, =params_phys
*
* On entry,
* r4 = kernel execution address
- * r6 = processor ID
* r7 = architecture number
* r8 = atags pointer
* r9 = run-time address of "start" (???)
@@ -542,7 +542,6 @@ __common_mmu_cache_on:
* r1-r3 = unused
* r4 = kernel execution address
* r5 = decompressed kernel start
- * r6 = processor ID
* r7 = architecture ID
* r8 = atags pointer
* r9-r12,r14 = corrupted
@@ -581,19 +580,19 @@ call_kernel: bl cache_clean_flush
* r1 = corrupted
* r2 = corrupted
* r3 = block offset
- * r6 = corrupted
+ * r9 = corrupted
* r12 = corrupted
*/
call_cache_fn: adr r12, proc_types
#ifdef CONFIG_CPU_CP15
- mrc p15, 0, r6, c0, c0 @ get processor ID
+ mrc p15, 0, r9, c0, c0 @ get processor ID
#else
- ldr r6, =CONFIG_PROCESSOR_ID
+ ldr r9, =CONFIG_PROCESSOR_ID
#endif
1: ldr r1, [r12, #0] @ get value
ldr r2, [r12, #4] @ get mask
- eor r1, r1, r6 @ (real ^ match)
+ eor r1, r1, r9 @ (real ^ match)
tst r1, r2 @ & mask
ARM( addeq pc, r12, r3 ) @ call cache function
THUMB( addeq r12, r3 )
@@ -743,7 +742,7 @@ proc_types:
.word 0x000f0000
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
- W(b) __armv4_mmu_cache_flush
+ W(b) __armv5tej_mmu_cache_flush
.word 0x0007b000 @ ARMv6
.word 0x000ff000
@@ -778,8 +777,7 @@ proc_types:
* Turn off the Cache and MMU. ARMv3 does not support
* reading the control register, but ARMv4 does.
*
- * On entry, r6 = processor ID
- * On exit, r0, r1, r2, r3, r12 corrupted
+ * On exit, r0, r1, r2, r3, r9, r12 corrupted
* This routine must preserve: r4, r6, r7
*/
.align 5
@@ -852,10 +850,8 @@ __armv3_mmu_cache_off:
/*
* Clean and flush the cache to maintain consistency.
*
- * On entry,
- * r6 = processor ID
* On exit,
- * r1, r2, r3, r11, r12 corrupted
+ * r1, r2, r3, r9, r11, r12 corrupted
* This routine must preserve:
* r0, r4, r5, r6, r7
*/
@@ -967,7 +963,7 @@ __armv4_mmu_cache_flush:
mov r2, #64*1024 @ default: 32K dcache size (*2)
mov r11, #32 @ default: 32 byte line size
mrc p15, 0, r3, c0, c0, 1 @ read cache type
- teq r3, r6 @ cache ID register present?
+ teq r3, r9 @ cache ID register present?
beq no_cache_id
mov r1, r3, lsr #18
and r1, r1, #7
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index d32bc71c1f7..d2b2ef41cd4 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -33,6 +33,7 @@ unsigned int __machine_arch_type;
#else
static void putstr(const char *ptr);
+extern void error(char *x);
#include <mach/uncompress.h>
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
index 7ca9ecff652..d08168941bd 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.in
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -43,6 +43,9 @@ SECTIONS
_etext = .;
+ /* Assume size of decompressed image is 4x the compressed image */
+ _image_size = (_etext - _text) * 4;
+
_got_start = .;
.got : { *(.got) }
_got_end = .;
diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c
index 446b696196e..dba4c1da63e 100644
--- a/arch/arm/common/clkdev.c
+++ b/arch/arm/common/clkdev.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
@@ -32,7 +33,7 @@ static DEFINE_MUTEX(clocks_mutex);
* If an entry has a device ID, it must match
* If an entry has a connection ID, it must match
* Then we take the most specific entry - with the following
- * order of precidence: dev+con > dev only > con only.
+ * order of precedence: dev+con > dev only > con only.
*/
static struct clk *clk_find(const char *dev_id, const char *con_id)
{
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index 2793447621c..7974baacafc 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -21,7 +21,6 @@
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/irq.h>
@@ -272,33 +271,6 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
}
-/*
- * We override these so we properly do dmabounce otherwise drivers
- * are able to set the dma_mask to 0xffffffff and we can no longer
- * trap bounces. :(
- *
- * We just return true on everyhing except for < 64MB in which case
- * we will fail miseralby and die since we can't handle that case.
- */
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- dev_dbg(&dev->dev, "%s: %llx\n", __func__, mask);
- if (mask >= PHYS_OFFSET + SZ_64M - 1)
- return 0;
-
- return -EIO;
-}
-
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- dev_dbg(&dev->dev, "%s: %llx\n", __func__, mask);
- if (mask >= PHYS_OFFSET + SZ_64M - 1)
- return 0;
-
- return -EIO;
-}
-
int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
{
it8152_io.start = IT8152_IO_BASE + 0x12000;
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index bd36c778c81..9dff07c80dd 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -32,6 +32,12 @@
#include <asm/hardware/locomo.h>
+/* LoCoMo Interrupts */
+#define IRQ_LOCOMO_KEY (0)
+#define IRQ_LOCOMO_GPIO (1)
+#define IRQ_LOCOMO_LT (2)
+#define IRQ_LOCOMO_SPI (3)
+
/* M62332 output channel selection */
#define M62332_EVR_CH 1 /* M62332 volume channel number */
/* 0 : CH.1 , 1 : CH. 2 */
@@ -58,6 +64,7 @@ struct locomo {
struct device *dev;
unsigned long phys;
unsigned int irq;
+ int irq_base;
spinlock_t lock;
void __iomem *base;
#ifdef CONFIG_PM
@@ -81,9 +88,7 @@ struct locomo_dev_info {
static struct locomo_dev_info locomo_devices[] = {
{
.devid = LOCOMO_DEVID_KEYBOARD,
- .irq = {
- IRQ_LOCOMO_KEY,
- },
+ .irq = { IRQ_LOCOMO_KEY },
.name = "locomo-keyboard",
.offset = LOCOMO_KEYBOARD,
.length = 16,
@@ -133,53 +138,20 @@ static struct locomo_dev_info locomo_devices[] = {
},
};
-
-/** LoCoMo interrupt handling stuff.
- * NOTE: LoCoMo has a 1 to many mapping on all of its IRQs.
- * that is, there is only one real hardware interrupt
- * we determine which interrupt it is by reading some IO memory.
- * We have two levels of expansion, first in the handler for the
- * hardware interrupt we generate an interrupt
- * IRQ_LOCOMO_*_BASE and those handlers generate more interrupts
- *
- * hardware irq reads LOCOMO_ICR & 0x0f00
- * IRQ_LOCOMO_KEY_BASE
- * IRQ_LOCOMO_GPIO_BASE
- * IRQ_LOCOMO_LT_BASE
- * IRQ_LOCOMO_SPI_BASE
- * IRQ_LOCOMO_KEY_BASE reads LOCOMO_KIC & 0x0001
- * IRQ_LOCOMO_KEY
- * IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff
- * IRQ_LOCOMO_GPIO[0-15]
- * IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001
- * IRQ_LOCOMO_LT
- * IRQ_LOCOMO_SPI_BASE reads LOCOMO_SPIIR & 0x000F
- * IRQ_LOCOMO_SPI_RFR
- * IRQ_LOCOMO_SPI_RFW
- * IRQ_LOCOMO_SPI_OVRN
- * IRQ_LOCOMO_SPI_TEND
- */
-
-#define LOCOMO_IRQ_START (IRQ_LOCOMO_KEY_BASE)
-#define LOCOMO_IRQ_KEY_START (IRQ_LOCOMO_KEY)
-#define LOCOMO_IRQ_GPIO_START (IRQ_LOCOMO_GPIO0)
-#define LOCOMO_IRQ_LT_START (IRQ_LOCOMO_LT)
-#define LOCOMO_IRQ_SPI_START (IRQ_LOCOMO_SPI_RFR)
-
static void locomo_handler(unsigned int irq, struct irq_desc *desc)
{
+ struct locomo *lchip = get_irq_chip_data(irq);
int req, i;
- void __iomem *mapbase = get_irq_chip_data(irq);
/* Acknowledge the parent IRQ */
desc->chip->ack(irq);
/* check why this interrupt was generated */
- req = locomo_readl(mapbase + LOCOMO_ICR) & 0x0f00;
+ req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
if (req) {
/* generate the next interrupt(s) */
- irq = LOCOMO_IRQ_START;
+ irq = lchip->irq_base;
for (i = 0; i <= 3; i++, irq++) {
if (req & (0x0100 << i)) {
generic_handle_irq(irq);
@@ -195,20 +167,20 @@ static void locomo_ack_irq(unsigned int irq)
static void locomo_mask_irq(unsigned int irq)
{
- void __iomem *mapbase = get_irq_chip_data(irq);
+ struct locomo *lchip = get_irq_chip_data(irq);
unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_ICR);
- r &= ~(0x0010 << (irq - LOCOMO_IRQ_START));
- locomo_writel(r, mapbase + LOCOMO_ICR);
+ r = locomo_readl(lchip->base + LOCOMO_ICR);
+ r &= ~(0x0010 << (irq - lchip->irq_base));
+ locomo_writel(r, lchip->base + LOCOMO_ICR);
}
static void locomo_unmask_irq(unsigned int irq)
{
- void __iomem *mapbase = get_irq_chip_data(irq);
+ struct locomo *lchip = get_irq_chip_data(irq);
unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_ICR);
- r |= (0x0010 << (irq - LOCOMO_IRQ_START));
- locomo_writel(r, mapbase + LOCOMO_ICR);
+ r = locomo_readl(lchip->base + LOCOMO_ICR);
+ r |= (0x0010 << (irq - lchip->irq_base));
+ locomo_writel(r, lchip->base + LOCOMO_ICR);
}
static struct irq_chip locomo_chip = {
@@ -218,297 +190,22 @@ static struct irq_chip locomo_chip = {
.unmask = locomo_unmask_irq,
};
-static void locomo_key_handler(unsigned int irq, struct irq_desc *desc)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
-
- if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
- generic_handle_irq(LOCOMO_IRQ_KEY_START);
- }
-}
-
-static void locomo_key_ack_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
- r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START));
- locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-}
-
-static void locomo_key_mask_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
- r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START));
- locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-}
-
-static void locomo_key_unmask_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
- r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START));
- locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC);
-}
-
-static struct irq_chip locomo_key_chip = {
- .name = "LOCOMO-key",
- .ack = locomo_key_ack_irq,
- .mask = locomo_key_mask_irq,
- .unmask = locomo_key_unmask_irq,
-};
-
-static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc)
-{
- int req, i;
- void __iomem *mapbase = get_irq_chip_data(irq);
-
- req = locomo_readl(mapbase + LOCOMO_GIR) &
- locomo_readl(mapbase + LOCOMO_GPD) &
- 0xffff;
-
- if (req) {
- irq = LOCOMO_IRQ_GPIO_START;
- for (i = 0; i <= 15; i++, irq++) {
- if (req & (0x0001 << i)) {
- generic_handle_irq(irq);
- }
- }
- }
-}
-
-static void locomo_gpio_ack_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_GWE);
- r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
- locomo_writel(r, mapbase + LOCOMO_GWE);
-
- r = locomo_readl(mapbase + LOCOMO_GIS);
- r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
- locomo_writel(r, mapbase + LOCOMO_GIS);
-
- r = locomo_readl(mapbase + LOCOMO_GWE);
- r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
- locomo_writel(r, mapbase + LOCOMO_GWE);
-}
-
-static void locomo_gpio_mask_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_GIE);
- r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
- locomo_writel(r, mapbase + LOCOMO_GIE);
-}
-
-static void locomo_gpio_unmask_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_GIE);
- r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));
- locomo_writel(r, mapbase + LOCOMO_GIE);
-}
-
-static int GPIO_IRQ_rising_edge;
-static int GPIO_IRQ_falling_edge;
-
-static int locomo_gpio_type(unsigned int irq, unsigned int type)
-{
- unsigned int mask;
- void __iomem *mapbase = get_irq_chip_data(irq);
-
- mask = 1 << (irq - LOCOMO_IRQ_GPIO_START);
-
- if (type == IRQ_TYPE_PROBE) {
- if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
- return 0;
- type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
- }
-
- if (type & IRQ_TYPE_EDGE_RISING)
- GPIO_IRQ_rising_edge |= mask;
- else
- GPIO_IRQ_rising_edge &= ~mask;
- if (type & IRQ_TYPE_EDGE_FALLING)
- GPIO_IRQ_falling_edge |= mask;
- else
- GPIO_IRQ_falling_edge &= ~mask;
- locomo_writel(GPIO_IRQ_rising_edge, mapbase + LOCOMO_GRIE);
- locomo_writel(GPIO_IRQ_falling_edge, mapbase + LOCOMO_GFIE);
-
- return 0;
-}
-
-static struct irq_chip locomo_gpio_chip = {
- .name = "LOCOMO-gpio",
- .ack = locomo_gpio_ack_irq,
- .mask = locomo_gpio_mask_irq,
- .unmask = locomo_gpio_unmask_irq,
- .set_type = locomo_gpio_type,
-};
-
-static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
-
- if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
- generic_handle_irq(LOCOMO_IRQ_LT_START);
- }
-}
-
-static void locomo_lt_ack_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_LTINT);
- r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START));
- locomo_writel(r, mapbase + LOCOMO_LTINT);
-}
-
-static void locomo_lt_mask_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_LTINT);
- r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START));
- locomo_writel(r, mapbase + LOCOMO_LTINT);
-}
-
-static void locomo_lt_unmask_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_LTINT);
- r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START));
- locomo_writel(r, mapbase + LOCOMO_LTINT);
-}
-
-static struct irq_chip locomo_lt_chip = {
- .name = "LOCOMO-lt",
- .ack = locomo_lt_ack_irq,
- .mask = locomo_lt_mask_irq,
- .unmask = locomo_lt_unmask_irq,
-};
-
-static void locomo_spi_handler(unsigned int irq, struct irq_desc *desc)
-{
- int req, i;
- void __iomem *mapbase = get_irq_chip_data(irq);
-
- req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F;
- if (req) {
- irq = LOCOMO_IRQ_SPI_START;
-
- for (i = 0; i <= 3; i++, irq++) {
- if (req & (0x0001 << i)) {
- generic_handle_irq(irq);
- }
- }
- }
-}
-
-static void locomo_spi_ack_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
- r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
- locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
-
- r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
- r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
- locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS);
-
- r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
- r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
- locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE);
-}
-
-static void locomo_spi_mask_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
- r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));
- locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
-}
-
-static void locomo_spi_unmask_irq(unsigned int irq)
-{
- void __iomem *mapbase = get_irq_chip_data(irq);
- unsigned int r;
- r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
- r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));
- locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE);
-}
-
-static struct irq_chip locomo_spi_chip = {
- .name = "LOCOMO-spi",
- .ack = locomo_spi_ack_irq,
- .mask = locomo_spi_mask_irq,
- .unmask = locomo_spi_unmask_irq,
-};
-
static void locomo_setup_irq(struct locomo *lchip)
{
- int irq;
- void __iomem *irqbase = lchip->base;
+ int irq = lchip->irq_base;
/*
* Install handler for IRQ_LOCOMO_HW.
*/
set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
- set_irq_chip_data(lchip->irq, irqbase);
+ set_irq_chip_data(lchip->irq, lchip);
set_irq_chained_handler(lchip->irq, locomo_handler);
- /* Install handlers for IRQ_LOCOMO_*_BASE */
- set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip);
- set_irq_chip_data(IRQ_LOCOMO_KEY_BASE, irqbase);
- set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler);
-
- set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip);
- set_irq_chip_data(IRQ_LOCOMO_GPIO_BASE, irqbase);
- set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler);
-
- set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip);
- set_irq_chip_data(IRQ_LOCOMO_LT_BASE, irqbase);
- set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler);
-
- set_irq_chip(IRQ_LOCOMO_SPI_BASE, &locomo_chip);
- set_irq_chip_data(IRQ_LOCOMO_SPI_BASE, irqbase);
- set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler);
-
- /* install handlers for IRQ_LOCOMO_KEY_BASE generated interrupts */
- set_irq_chip(LOCOMO_IRQ_KEY_START, &locomo_key_chip);
- set_irq_chip_data(LOCOMO_IRQ_KEY_START, irqbase);
- set_irq_handler(LOCOMO_IRQ_KEY_START, handle_edge_irq);
- set_irq_flags(LOCOMO_IRQ_KEY_START, IRQF_VALID | IRQF_PROBE);
-
- /* install handlers for IRQ_LOCOMO_GPIO_BASE generated interrupts */
- for (irq = LOCOMO_IRQ_GPIO_START; irq < LOCOMO_IRQ_GPIO_START + 16; irq++) {
- set_irq_chip(irq, &locomo_gpio_chip);
- set_irq_chip_data(irq, irqbase);
- set_irq_handler(irq, handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- }
-
- /* install handlers for IRQ_LOCOMO_LT_BASE generated interrupts */
- set_irq_chip(LOCOMO_IRQ_LT_START, &locomo_lt_chip);
- set_irq_chip_data(LOCOMO_IRQ_LT_START, irqbase);
- set_irq_handler(LOCOMO_IRQ_LT_START, handle_edge_irq);
- set_irq_flags(LOCOMO_IRQ_LT_START, IRQF_VALID | IRQF_PROBE);
-
- /* install handlers for IRQ_LOCOMO_SPI_BASE generated interrupts */
- for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 4; irq++) {
- set_irq_chip(irq, &locomo_spi_chip);
- set_irq_chip_data(irq, irqbase);
- set_irq_handler(irq, handle_edge_irq);
+ /* Install handlers for IRQ_LOCOMO_* */
+ for ( ; irq <= lchip->irq_base + 3; irq++) {
+ set_irq_chip(irq, &locomo_chip);
+ set_irq_chip_data(irq, lchip);
+ set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
@@ -555,7 +252,8 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
dev->mapbase = 0;
dev->length = info->length;
- memmove(dev->irq, info->irq, sizeof(dev->irq));
+ dev->irq[0] = (lchip->irq_base == NO_IRQ) ?
+ NO_IRQ : lchip->irq_base + info->irq[0];
ret = device_register(&dev->dev);
if (ret) {
@@ -592,7 +290,7 @@ static int locomo_suspend(struct platform_device *dev, pm_message_t state)
save->LCM_GPO = locomo_readl(lchip->base + LOCOMO_GPO); /* GPIO */
locomo_writel(0x00, lchip->base + LOCOMO_GPO);
save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT); /* SPI */
- locomo_writel(0x40, lchip->base + LOCOMO_SPICT);
+ locomo_writel(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
save->LCM_GPE = locomo_readl(lchip->base + LOCOMO_GPE); /* GPIO */
locomo_writel(0x00, lchip->base + LOCOMO_GPE);
save->LCM_ASD = locomo_readl(lchip->base + LOCOMO_ASD); /* ADSTART */
@@ -672,6 +370,7 @@ static int locomo_resume(struct platform_device *dev)
static int
__locomo_probe(struct device *me, struct resource *mem, int irq)
{
+ struct locomo_platform_data *pdata = me->platform_data;
struct locomo *lchip;
unsigned long r;
int i, ret = -ENODEV;
@@ -687,6 +386,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
lchip->phys = mem->start;
lchip->irq = irq;
+ lchip->irq_base = (pdata) ? pdata->irq_base : NO_IRQ;
/*
* Map the whole region. This also maps the
@@ -718,7 +418,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
/* Longtime timer */
locomo_writel(0, lchip->base + LOCOMO_LTINT);
/* SPI */
- locomo_writel(0, lchip->base + LOCOMO_SPIIE);
+ locomo_writel(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE);
locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD);
r = locomo_readl(lchip->base + LOCOMO_ASD);
@@ -753,7 +453,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
* The interrupt controller must be initialised before any
* other device to ensure that the interrupts are available.
*/
- if (lchip->irq != NO_IRQ)
+ if (lchip->irq != NO_IRQ && lchip->irq_base != NO_IRQ)
locomo_setup_irq(lchip);
for (i = 0; i < ARRAY_SIZE(locomo_devices); i++)
@@ -1007,7 +707,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
- return;
+ goto out;
}
/* Send Sub address (LSB is channel select) */
@@ -1035,7 +735,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
- return;
+ goto out;
}
/* Send DAC data */
@@ -1060,9 +760,9 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
- return;
}
+out:
/* stop */
r = locomo_readl(mapbase + LOCOMO_DAC);
r &= ~(LOCOMO_DAC_SCLOEB);
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 8ba7044c554..a52a27c1d9b 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -35,6 +35,58 @@
#include <asm/hardware/sa1111.h>
+/* SA1111 IRQs */
+#define IRQ_GPAIN0 (0)
+#define IRQ_GPAIN1 (1)
+#define IRQ_GPAIN2 (2)
+#define IRQ_GPAIN3 (3)
+#define IRQ_GPBIN0 (4)
+#define IRQ_GPBIN1 (5)
+#define IRQ_GPBIN2 (6)
+#define IRQ_GPBIN3 (7)
+#define IRQ_GPBIN4 (8)
+#define IRQ_GPBIN5 (9)
+#define IRQ_GPCIN0 (10)
+#define IRQ_GPCIN1 (11)
+#define IRQ_GPCIN2 (12)
+#define IRQ_GPCIN3 (13)
+#define IRQ_GPCIN4 (14)
+#define IRQ_GPCIN5 (15)
+#define IRQ_GPCIN6 (16)
+#define IRQ_GPCIN7 (17)
+#define IRQ_MSTXINT (18)
+#define IRQ_MSRXINT (19)
+#define IRQ_MSSTOPERRINT (20)
+#define IRQ_TPTXINT (21)
+#define IRQ_TPRXINT (22)
+#define IRQ_TPSTOPERRINT (23)
+#define SSPXMTINT (24)
+#define SSPRCVINT (25)
+#define SSPROR (26)
+#define AUDXMTDMADONEA (32)
+#define AUDRCVDMADONEA (33)
+#define AUDXMTDMADONEB (34)
+#define AUDRCVDMADONEB (35)
+#define AUDTFSR (36)
+#define AUDRFSR (37)
+#define AUDTUR (38)
+#define AUDROR (39)
+#define AUDDTS (40)
+#define AUDRDD (41)
+#define AUDSTO (42)
+#define IRQ_USBPWR (43)
+#define IRQ_HCIM (44)
+#define IRQ_HCIBUFFACC (45)
+#define IRQ_HCIRMTWKP (46)
+#define IRQ_NHCIMFCIR (47)
+#define IRQ_USB_PORT_RESUME (48)
+#define IRQ_S0_READY_NINT (49)
+#define IRQ_S1_READY_NINT (50)
+#define IRQ_S0_CD_VALID (51)
+#define IRQ_S1_CD_VALID (52)
+#define IRQ_S0_BVD1_STSCHG (53)
+#define IRQ_S1_BVD1_STSCHG (54)
+
extern void __init sa1110_mb_enable(void);
/*
@@ -49,6 +101,7 @@ struct sa1111 {
struct clk *clk;
unsigned long phys;
int irq;
+ int irq_base; /* base for cascaded on-chip IRQs */
spinlock_t lock;
void __iomem *base;
#ifdef CONFIG_PM
@@ -152,36 +205,37 @@ static void
sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
{
unsigned int stat0, stat1, i;
- void __iomem *base = get_irq_data(irq);
+ struct sa1111 *sachip = get_irq_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
- stat0 = sa1111_readl(base + SA1111_INTSTATCLR0);
- stat1 = sa1111_readl(base + SA1111_INTSTATCLR1);
+ stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
+ stat1 = sa1111_readl(mapbase + SA1111_INTSTATCLR1);
- sa1111_writel(stat0, base + SA1111_INTSTATCLR0);
+ sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
desc->chip->ack(irq);
- sa1111_writel(stat1, base + SA1111_INTSTATCLR1);
+ sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
if (stat0 == 0 && stat1 == 0) {
do_bad_IRQ(irq, desc);
return;
}
- for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
+ for (i = 0; stat0; i++, stat0 >>= 1)
if (stat0 & 1)
- handle_edge_irq(i, irq_desc + i);
+ generic_handle_irq(i + sachip->irq_base);
- for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
+ for (i = 32; stat1; i++, stat1 >>= 1)
if (stat1 & 1)
- handle_edge_irq(i, irq_desc + i);
+ generic_handle_irq(i + sachip->irq_base);
/* For level-based interrupts */
desc->chip->unmask(irq);
}
-#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START))
-#define SA1111_IRQMASK_HI(x) (1 << (x - IRQ_SA1111_START - 32))
+#define SA1111_IRQMASK_LO(x) (1 << (x - sachip->irq_base))
+#define SA1111_IRQMASK_HI(x) (1 << (x - sachip->irq_base - 32))
static void sa1111_ack_irq(unsigned int irq)
{
@@ -189,7 +243,8 @@ static void sa1111_ack_irq(unsigned int irq)
static void sa1111_mask_lowirq(unsigned int irq)
{
- void __iomem *mapbase = get_irq_chip_data(irq);
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned long ie0;
ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
@@ -199,7 +254,8 @@ static void sa1111_mask_lowirq(unsigned int irq)
static void sa1111_unmask_lowirq(unsigned int irq)
{
- void __iomem *mapbase = get_irq_chip_data(irq);
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned long ie0;
ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
@@ -216,8 +272,9 @@ static void sa1111_unmask_lowirq(unsigned int irq)
*/
static int sa1111_retrigger_lowirq(unsigned int irq)
{
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned int mask = SA1111_IRQMASK_LO(irq);
- void __iomem *mapbase = get_irq_chip_data(irq);
unsigned long ip0;
int i;
@@ -237,8 +294,9 @@ static int sa1111_retrigger_lowirq(unsigned int irq)
static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
{
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned int mask = SA1111_IRQMASK_LO(irq);
- void __iomem *mapbase = get_irq_chip_data(irq);
unsigned long ip0;
if (flags == IRQ_TYPE_PROBE)
@@ -260,8 +318,9 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
{
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned int mask = SA1111_IRQMASK_LO(irq);
- void __iomem *mapbase = get_irq_chip_data(irq);
unsigned long we0;
we0 = sa1111_readl(mapbase + SA1111_WAKEEN0);
@@ -286,7 +345,8 @@ static struct irq_chip sa1111_low_chip = {
static void sa1111_mask_highirq(unsigned int irq)
{
- void __iomem *mapbase = get_irq_chip_data(irq);
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned long ie1;
ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
@@ -296,7 +356,8 @@ static void sa1111_mask_highirq(unsigned int irq)
static void sa1111_unmask_highirq(unsigned int irq)
{
- void __iomem *mapbase = get_irq_chip_data(irq);
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned long ie1;
ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
@@ -313,8 +374,9 @@ static void sa1111_unmask_highirq(unsigned int irq)
*/
static int sa1111_retrigger_highirq(unsigned int irq)
{
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned int mask = SA1111_IRQMASK_HI(irq);
- void __iomem *mapbase = get_irq_chip_data(irq);
unsigned long ip1;
int i;
@@ -334,8 +396,9 @@ static int sa1111_retrigger_highirq(unsigned int irq)
static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
{
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned int mask = SA1111_IRQMASK_HI(irq);
- void __iomem *mapbase = get_irq_chip_data(irq);
unsigned long ip1;
if (flags == IRQ_TYPE_PROBE)
@@ -357,8 +420,9 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
{
+ struct sa1111 *sachip = get_irq_chip_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
unsigned int mask = SA1111_IRQMASK_HI(irq);
- void __iomem *mapbase = get_irq_chip_data(irq);
unsigned long we1;
we1 = sa1111_readl(mapbase + SA1111_WAKEEN1);
@@ -412,14 +476,14 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
set_irq_chip(irq, &sa1111_low_chip);
- set_irq_chip_data(irq, irqbase);
+ set_irq_chip_data(irq, sachip);
set_irq_handler(irq, handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
set_irq_chip(irq, &sa1111_high_chip);
- set_irq_chip_data(irq, irqbase);
+ set_irq_chip_data(irq, sachip);
set_irq_handler(irq, handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
@@ -428,7 +492,7 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
* Register SA1111 interrupt
*/
set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
- set_irq_data(sachip->irq, irqbase);
+ set_irq_data(sachip->irq, sachip);
set_irq_chained_handler(sachip->irq, sa1111_irq_handler);
}
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 37bda5f3dde..9012004321d 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -140,6 +140,7 @@ EXPORT_SYMBOL(reset_scoop);
EXPORT_SYMBOL(read_scoop_reg);
EXPORT_SYMBOL(write_scoop_reg);
+#ifdef CONFIG_PM
static void check_scoop_reg(struct scoop_dev *sdev)
{
unsigned short mcr;
@@ -149,7 +150,6 @@ static void check_scoop_reg(struct scoop_dev *sdev)
iowrite16(0x0101, sdev->base + SCOOP_MCR);
}
-#ifdef CONFIG_PM
static int scoop_suspend(struct platform_device *dev, pm_message_t state)
{
struct scoop_dev *sdev = platform_get_drvdata(dev);
diff --git a/arch/arm/configs/ap4evb_defconfig b/arch/arm/configs/ap4evb_defconfig
new file mode 100644
index 00000000000..e14229be767
--- /dev/null
+++ b/arch/arm/configs/ap4evb_defconfig
@@ -0,0 +1,779 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc7
+# Mon Feb 8 12:25:36 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=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_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_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_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 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
+
+#
+# Kernel Performance Events And Counters
+#
+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_AT91 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_NOMADIK 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_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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 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
+
+#
+# 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_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_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_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_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_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_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_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 is not set
+# CONFIG_MFD_SM501 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_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_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/bcmring_defconfig b/arch/arm/configs/bcmring_defconfig
index 1e12167c89b..6ac6693299b 100644
--- a/arch/arm/configs/bcmring_defconfig
+++ b/arch/arm/configs/bcmring_defconfig
@@ -1,13 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc3
-# Fri Jul 17 12:07:28 2009
+# Linux kernel version: 2.6.34-rc2
+# Mon Mar 29 12:01:41 2010
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
+CONFIG_HAVE_PROC_CPU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,6 +18,7 @@ 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"
@@ -32,6 +33,12 @@ CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
+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
@@ -43,21 +50,22 @@ 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=17
-# CONFIG_GROUP_SCHED is not set
-# 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 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
@@ -75,19 +83,21 @@ CONFIG_FUTEX=y
# CONFIG_EVENTFD is not set
CONFIG_SHMEM=y
# CONFIG_AIO is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_COUNTERS=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_SLUB_DEBUG is not set
-# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_COMPAT_BRK is not set
# 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
@@ -115,24 +125,53 @@ 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_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=y
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_EBSA110 is not set
@@ -149,6 +188,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
# 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
@@ -157,19 +197,26 @@ CONFIG_DEFAULT_IOSCHED="noop"
# 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 is not set
# CONFIG_ARCH_OMAP is not set
-CONFIG_ARCH_BCMRING=y
# CONFIG_ARCH_FPGA11107 is not set
CONFIG_ARCH_BCM11107=y
@@ -185,7 +232,7 @@ CONFIG_CPU_V6=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v6=y
CONFIG_CPU_ABRT_EV6=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_V6=y
CONFIG_CPU_CACHE_V6=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
@@ -201,6 +248,8 @@ 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
@@ -222,6 +271,8 @@ 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
@@ -229,6 +280,7 @@ CONFIG_AEABI=y
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_HIGHMEM is not set
+CONFIG_HW_PERF_EVENTS=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -240,8 +292,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_ALIGNMENT_TRAP=y
CONFIG_UACCESS_WITH_MEMCPY=y
@@ -335,9 +386,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -433,6 +484,10 @@ CONFIG_MTD_NAND_BCM_UMI_HWCS=y
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 is not set
# CONFIG_CDROM_PKTCDVD is not set
@@ -444,6 +499,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -452,6 +508,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_MD is not set
# CONFIG_NETDEVICES is not set
# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
#
# Input device support
@@ -459,6 +516,7 @@ CONFIG_HAVE_IDE=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
@@ -508,6 +566,7 @@ CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_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=y
@@ -519,13 +578,17 @@ CONFIG_LEGACY_PTY_COUNT=64
# 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_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB 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_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -541,6 +604,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
#
@@ -566,14 +630,17 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY 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_REGULATOR is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -589,9 +656,12 @@ CONFIG_FS_POSIX_ACL=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 is not set
# 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
@@ -647,6 +717,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -657,7 +728,6 @@ CONFIG_JFFS2_RTIME=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 is not set
#
@@ -675,11 +745,12 @@ CONFIG_MSDOS_PARTITION=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=y
# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_MEMORY_INIT is not set
CONFIG_FRAME_POINTER=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -693,6 +764,7 @@ CONFIG_TRACING_SUPPORT=y
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_ARM_UNWIND is not set
# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
#
# Security options
@@ -700,7 +772,11 @@ CONFIG_HAVE_ARCH_KGDB=y
# 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 is not set
# CONFIG_BINARY_PRINTF is not set
diff --git a/arch/arm/configs/cm_t35_defconfig b/arch/arm/configs/cm_t35_defconfig
index 893cd267e07..032b49bad91 100644
--- a/arch/arm/configs/cm_t35_defconfig
+++ b/arch/arm/configs/cm_t35_defconfig
@@ -358,7 +358,7 @@ 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_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
diff --git a/arch/arm/configs/g3evm_defconfig b/arch/arm/configs/g3evm_defconfig
new file mode 100644
index 00000000000..3c19031961d
--- /dev/null
+++ b/arch/arm/configs/g3evm_defconfig
@@ -0,0 +1,774 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc7
+# Mon Feb 8 12:20:01 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=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_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_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_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 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
+
+#
+# Kernel Performance Events And Counters
+#
+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_AT91 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_NOMADIK 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_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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 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
+
+#
+# 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_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_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_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_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_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_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_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 is not set
+# CONFIG_MFD_SM501 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_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_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/g4evm_defconfig b/arch/arm/configs/g4evm_defconfig
new file mode 100644
index 00000000000..8ee79a53713
--- /dev/null
+++ b/arch/arm/configs/g4evm_defconfig
@@ -0,0 +1,779 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc7
+# Mon Feb 8 12:21:35 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=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_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_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_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 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
+
+#
+# Kernel Performance Events And Counters
+#
+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_AT91 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_NOMADIK 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_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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 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
+
+#
+# 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_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_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_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_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_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_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_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 is not set
+# CONFIG_MFD_SM501 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_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_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/imote2_defconfig b/arch/arm/configs/imote2_defconfig
new file mode 100644
index 00000000000..95d2becfc66
--- /dev/null
+++ b/arch/arm/configs/imote2_defconfig
@@ -0,0 +1,2077 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc8
+# Sat Feb 13 21:48:53 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=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_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=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 is not set
+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=y
+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_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+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=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# 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=y
+CONFIG_RD_LZMA=y
+# 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=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
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+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_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG 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 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_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# 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_AT91 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_NOMADIK 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_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_MSM 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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+
+#
+# Intel/Marvell Dev Platforms (sorted by hardware release time)
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_ZYLONITE300 is not set
+# CONFIG_MACH_ZYLONITE320 is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+
+#
+# Third Party Dev Platforms (sorted by vendor name)
+#
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_MACH_ARCOM_ZEUS is not set
+# CONFIG_MACH_BALLOON3 is not set
+# CONFIG_MACH_CSB726 is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_EXEDA is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_ARCH_GUMSTIX is not set
+CONFIG_MACH_INTELMOTE2=y
+# CONFIG_MACH_STARGATE2 is not set
+# CONFIG_MACH_XCEP is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_COLIBRI300 is not set
+# CONFIG_MACH_COLIBRI320 is not set
+
+#
+# End-user Products (sorted by vendor name)
+#
+# CONFIG_MACH_H4700 is not set
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_HIMALAYA is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_PXA_EZX is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+CONFIG_PXA27x=y
+CONFIG_PXA_SSP=y
+CONFIG_PXA_HAVE_BOARD_IRQS=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=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_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=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=999999
+# 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=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=3 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE 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=m
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=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=m
+# 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=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+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=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_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=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+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=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# 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
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CT_PROTO_DCCP is not set
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_UDPLITE=m
+CONFIG_NF_NAT_PROTO_SCTP=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+# CONFIG_BRIDGE_NF_EBTABLES 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_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# 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=y
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+# 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=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+# CONFIG_BT_HCIUART_BCSP is not set
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+# CONFIG_BT_ATH3K 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
+
+#
+# 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=m
+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=m
+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_HAVE_MTD_OTP=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=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# 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 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_OTP=y
+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
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PXA2XX=y
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# 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 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=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_DRBD is not set
+CONFIG_BLK_DEV_NBD=m
+# 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_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# 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
+#
+
+#
+# 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_IEEE802154_DRIVERS=y
+# CONFIG_IEEE802154_FAKEHARD is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# 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 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 is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+CONFIG_KEYBOARD_PXA27x=y
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+CONFIG_TOUCHSCREEN_DA9034=y
+# CONFIG_TOUCHSCREEN_DYNAPRO 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 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=y
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER 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_MAX3100 is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=8
+# 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=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+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_PXA=y
+# CONFIG_I2C_PXA_SLAVE 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
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# 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=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PXA2XX=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 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=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# 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:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_DA9030 is not set
+# CONFIG_BATTERY_MAX17040 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 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_TPS65010 is not set
+# CONFIG_TWL4030_CORE 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_PMIC_DA903X=y
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+CONFIG_REGULATOR_DA903X=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+CONFIG_MEDIA_TUNER_CUSTOMISE=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+CONFIG_MEDIA_TUNER_MAX2165=m
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_SG=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 is not set
+CONFIG_VIDEO_IR_I2C=y
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI 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_SOC_CAMERA=y
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+CONFIG_SOC_CAMERA_MT9M111=y
+# CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9T112 is not set
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_RJ54N1 is not set
+# CONFIG_SOC_CAMERA_TW9910 is not set
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+# CONFIG_SOC_CAMERA_OV772X is not set
+# CONFIG_SOC_CAMERA_OV9640 is not set
+CONFIG_VIDEO_PXA27x=y
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_I2C_SI4713 is not set
+# CONFIG_RADIO_SI4713 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_RADIO_SI470X is not set
+# CONFIG_USB_MR800 is not set
+CONFIG_RADIO_TEA5764=y
+CONFIG_RADIO_TEA5764_XTAL=y
+# CONFIG_RADIO_TEF6862 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=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_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_OVERLAY=y
+# CONFIG_FB_PXA_SMARTPANEL is not set
+CONFIG_FB_PXA_PARAMETERS=y
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 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
+# CONFIG_BACKLIGHT_DA903X 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=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER 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_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 is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_PXA2XX_LIB=y
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+# CONFIG_SND_PXA2XX_SOC_IMOTE2 is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+# CONFIG_HID_PID 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_APPLE=m
+# CONFIG_HID_WACOM is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# 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 is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND 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
+# 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_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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_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_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_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_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+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=y
+CONFIG_USB_PXA27X=y
+# 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 is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE 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 is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=m
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_SPI=y
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_LP3944=y
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DA903X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_REGULATOR is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# 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 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
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# 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_RTC_DRV_SA1100 is not set
+# CONFIG_RTC_DRV_PXA 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=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+# 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=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+CONFIG_REISERFS_FS=m
+# 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=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_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=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+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_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=m
+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=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# 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=m
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# 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=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=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=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# 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 is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# 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 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 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_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCKDEP=y
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_LOCKDEP is not set
+CONFIG_TRACE_IRQFLAGS=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# 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_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_DYNAMIC_DEBUG 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=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_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# 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=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# 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=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# 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=m
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
index 5fc44c94b0a..4611d3ce451 100644
--- a/arch/arm/configs/kirkwood_defconfig
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc6
-# Sat Nov 7 20:31:18 2009
+# Linux kernel version: 2.6.33-rc6
+# Thu Feb 4 23:08:54 2010
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -32,6 +32,12 @@ 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=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
@@ -45,6 +51,7 @@ CONFIG_SYSVIPC_SYSCTL=y
#
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
@@ -127,14 +134,41 @@ CONFIG_LBDAF=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
# 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 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
#
@@ -163,6 +197,7 @@ CONFIG_MMU=y
# 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=y
# CONFIG_ARCH_LOKI is not set
# CONFIG_ARCH_MV78XX0 is not set
@@ -185,6 +220,7 @@ CONFIG_ARCH_KIRKWOOD=y
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
#
# Marvell Kirkwood Implementations
@@ -195,7 +231,11 @@ CONFIG_MACH_RD88F6281=y
CONFIG_MACH_MV88F6281GTW_GE=y
CONFIG_MACH_SHEEVAPLUG=y
CONFIG_MACH_TS219=y
+CONFIG_MACH_TS41X=y
+CONFIG_MACH_OPENRD=y
CONFIG_MACH_OPENRD_BASE=y
+CONFIG_MACH_OPENRD_CLIENT=y
+CONFIG_MACH_NETSPACE_V2=y
CONFIG_PLAT_ORION=y
#
@@ -262,12 +302,10 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
# 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_ALIGNMENT_TRAP=y
@@ -398,15 +436,18 @@ CONFIG_NET_PKTGEN=m
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
CONFIG_CFG80211=y
# CONFIG_NL80211_TESTMODE is not set
# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
# CONFIG_CFG80211_REG_DEBUG is not set
CONFIG_CFG80211_DEFAULT_PS=y
-CONFIG_CFG80211_DEFAULT_PS_VALUE=1
# CONFIG_CFG80211_DEBUGFS is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
-CONFIG_WIRELESS_EXT=y
+CONFIG_CFG80211_WEXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
CONFIG_LIB80211=y
# CONFIG_LIB80211_DEBUG is not set
@@ -556,6 +597,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
@@ -606,7 +651,9 @@ CONFIG_SCSI_LOWLEVEL=y
# 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
@@ -642,6 +689,7 @@ CONFIG_SCSI_LOWLEVEL=y
# 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_DH is not set
@@ -696,15 +744,16 @@ CONFIG_SATA_MV=y
# 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_PDC2027X 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_SCH is not set
@@ -720,7 +769,7 @@ CONFIG_SATA_MV=y
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -828,13 +877,6 @@ CONFIG_MV643XX_ETH=y
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-CONFIG_LIBERTAS=y
-# CONFIG_LIBERTAS_USB is not set
-CONFIG_LIBERTAS_SDIO=y
-# CONFIG_LIBERTAS_SPI is not set
-# CONFIG_LIBERTAS_DEBUG is not set
# CONFIG_LIBERTAS_THINFIRM is not set
# CONFIG_ATMEL is not set
# CONFIG_AT76C50X_USB is not set
@@ -846,19 +888,24 @@ CONFIG_LIBERTAS_SDIO=y
# CONFIG_ADM8211 is not set
# CONFIG_MAC80211_HWSIM is not set
# CONFIG_MWL8K is not set
-# CONFIG_P54_COMMON is not set
# CONFIG_ATH_COMMON is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
# CONFIG_IPW2100 is not set
# CONFIG_IPW2200 is not set
# CONFIG_IWLWIFI is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_B43 is not set
-# CONFIG_B43LEGACY is not set
-# CONFIG_ZD1211RW is not set
-# CONFIG_RT2X00 is not set
+# CONFIG_IWM is not set
+CONFIG_LIBERTAS=y
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=y
+# CONFIG_LIBERTAS_SPI is not set
+# CONFIG_LIBERTAS_DEBUG is not set
# CONFIG_HERMES is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
# CONFIG_WL12XX is not set
-# CONFIG_IWM is not set
+# CONFIG_ZD1211RW is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -881,6 +928,7 @@ CONFIG_LIBERTAS_SDIO=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
@@ -890,6 +938,7 @@ CONFIG_LIBERTAS_SDIO=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
@@ -933,6 +982,7 @@ CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_GAMEPORT is not set
#
@@ -1019,11 +1069,6 @@ CONFIG_I2C_MV64XXX=y
# 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
@@ -1032,7 +1077,6 @@ CONFIG_I2C_MV64XXX=y
#
# Miscellaneous I2C Chip support
#
-# CONFIG_DS1682 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1048,6 +1092,8 @@ CONFIG_SPI_MASTER=y
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_GPIO is not set
CONFIG_SPI_ORION=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
#
# SPI Protocol Masters
@@ -1074,10 +1120,12 @@ CONFIG_GPIO_SYSFS=y
# 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:
#
+# CONFIG_GPIO_CS5535 is not set
# CONFIG_GPIO_BT8XX is not set
# CONFIG_GPIO_LANGWELL is not set
@@ -1116,6 +1164,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
@@ -1123,6 +1172,8 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_AB4500_CORE is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1305,6 +1356,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# 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_UWB is not set
CONFIG_MMC=y
@@ -1344,6 +1396,7 @@ CONFIG_LEDS_GPIO_PLATFORM=y
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_DAC124S085 is not set
# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
#
# LED Triggers
@@ -1388,6 +1441,7 @@ CONFIG_RTC_INTF_DEV=y
# 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=y
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
@@ -1417,7 +1471,9 @@ CONFIG_RTC_DRV_S35390A=y
# 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
#
@@ -1684,7 +1740,9 @@ CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
#
# Security options
@@ -1692,7 +1750,11 @@ CONFIG_DEBUG_LL=y
# 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
#
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
index d2a90eb844a..ff44bd1615c 100644
--- a/arch/arm/configs/mini2440_defconfig
+++ b/arch/arm/configs/mini2440_defconfig
@@ -184,7 +184,7 @@ CONFIG_S3C24XX_PWM=y
CONFIG_S3C24XX_GPIO_EXTRA=0
CONFIG_S3C2410_DMA=y
# CONFIG_S3C2410_DMA_DEBUG is not set
-CONFIG_S3C24XX_ADC=y
+CONFIG_S3C_ADC=y
CONFIG_PLAT_S3C=y
CONFIG_CPU_LLSERIAL_S3C2440_ONLY=y
CONFIG_CPU_LLSERIAL_S3C2440=y
@@ -199,8 +199,8 @@ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
#
# Power management
#
-# CONFIG_S3C2410_PM_DEBUG is not set
-# CONFIG_S3C2410_PM_CHECK is not set
+# CONFIG_SAMSUNG_PM_DEBUG is not set
+# CONFIG_SAMSUNG_PM_CHECK is not set
CONFIG_S3C_LOWLEVEL_UART_PORT=0
CONFIG_S3C_GPIO_SPACE=0
diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig
new file mode 100644
index 00000000000..03f76cfc941
--- /dev/null
+++ b/arch/arm/configs/mmp2_defconfig
@@ -0,0 +1,1194 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc2
+# Tue Jan 5 13:55:22 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=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_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_SWAP=y
+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_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# 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_NET_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+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
+
+#
+# Kernel Performance Events And Counters
+#
+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_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=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_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 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_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_NOMADIK 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=y
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM 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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_MACH_TAVOREVB is not set
+
+#
+# Marvell PXA168/910/MMP2 Implmentations
+#
+# CONFIG_MACH_ASPENITE is not set
+# CONFIG_MACH_ZYLONITE2 is not set
+# CONFIG_MACH_TTC_DKB is not set
+CONFIG_MACH_FLINT=y
+CONFIG_CPU_MMP2=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+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_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 is not set
+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=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=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="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M user_debug=255"
+# 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_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# 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_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 is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# 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 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_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=""
+# CONFIG_DEVTMPFS is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+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=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=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+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 is not set
+# CONFIG_MTD_JEDECPROBE 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_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_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_PXA3xx is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_ONENAND=y
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+CONFIG_MTD_ONENAND_GENERIC=y
+# CONFIG_MTD_ONENAND_OTP is not set
+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
+# CONFIG_MTD_ONENAND_SIM 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_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 is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# 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_HOSTAP 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 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_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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=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_PXA=y
+# CONFIG_I2C_PXA_SLAVE 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
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# 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
+
+#
+# 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:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# 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_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE 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_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+CONFIG_MFD_88PM8607=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_MAX8660=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+CONFIG_REGULATOR_88PM8607=y
+# 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=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM 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_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=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 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_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 is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_EXT4_USE_FOR_EXT23=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 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=y
+# 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_CRAMFS=y
+# 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=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_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 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 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_DEBUG_SLAB 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 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=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=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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
+# 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_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_WORKQUEUE=y
+# 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=y
+# 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=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=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 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_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# 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_ZLIB_DEFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 6afa2c108ea..da4710dd1da 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -176,6 +176,7 @@ CONFIG_ARCH_MV78XX0=y
#
CONFIG_MACH_DB78X00_BP=y
CONFIG_MACH_RD78X00_MASA=y
+CONFIG_MACH_TERASTATION_WXL=y
CONFIG_PLAT_ORION=y
#
diff --git a/arch/arm/configs/mx1ads_defconfig b/arch/arm/configs/mx1ads_defconfig
deleted file mode 100644
index 3cabbb6d927..00000000000
--- a/arch/arm/configs/mx1ads_defconfig
+++ /dev/null
@@ -1,742 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 02:15:46 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_EMBEDDED=y
-# CONFIG_KALLSYMS is not set
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=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_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# 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
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-CONFIG_ARCH_IMX=y
-# CONFIG_ARCH_H720X is not set
-
-#
-# IMX Implementations
-#
-CONFIG_ARCH_MX1ADS=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4T=y
-CONFIG_CPU_CACHE_V4WT=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_THUMB is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-
-#
-# Bus support
-#
-CONFIG_ISA=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_PREEMPT=y
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySMX0,57600n8 ip=bootp root=/dev/nfs"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-CONFIG_FPE_NWFPE_XP=y
-CONFIG_FPE_FASTFPE=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM 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
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG 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
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE 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_RAM is not set
-CONFIG_MTD_ROM=y
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS 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_BLKMTD 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
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# 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 is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-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_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# 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_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP 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
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_SMC91X is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# 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_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN 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
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-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_NVRAM is not set
-CONFIG_RTC=m
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_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_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_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# 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_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=y
-# 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=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=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
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-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
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-
-#
-# 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 is not set
-# 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 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_TEST is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=y
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/mx27_defconfig b/arch/arm/configs/mx27_defconfig
index edfdd6faf80..b4c1366e9e0 100644
--- a/arch/arm/configs/mx27_defconfig
+++ b/arch/arm/configs/mx27_defconfig
@@ -200,7 +200,7 @@ CONFIG_MACH_MX27ADS=y
CONFIG_MACH_PCM038=y
CONFIG_MACH_PCM970_BASEBOARD=y
CONFIG_MACH_MX27_3DS=y
-CONFIG_MACH_MX27LITE=y
+CONFIG_MACH_IMX27LITE=y
CONFIG_MXC_IRQ_PRIOR=y
CONFIG_MXC_PWM=y
diff --git a/arch/arm/configs/mx51_defconfig b/arch/arm/configs/mx51_defconfig
new file mode 100644
index 00000000000..c88e9527a8e
--- /dev/null
+++ b/arch/arm/configs/mx51_defconfig
@@ -0,0 +1,1286 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc6
+# Tue Feb 2 15:20:48 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=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_ARCH_MTD_XIP=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 is not set
+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=y
+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_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=18
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD 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
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+# 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_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_BLOCK=y
+# CONFIG_LBDAF 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_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=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_AT91 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=y
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK 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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM 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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MXC91231 is not set
+CONFIG_ARCH_MX5=y
+CONFIG_ARCH_MX51=y
+
+#
+# MX5 platforms:
+#
+CONFIG_MACH_MX51_BABBAGE=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_TZIC=y
+# CONFIG_MXC_PWM is not set
+CONFIG_ARCH_MXC_IOMUX_V3=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_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_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=y
+# 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=32768
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.0.101:/shared/nfs ip=dhcp"
+# 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=y
+
+#
+# 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=m
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_PM_TEST_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+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=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 is not set
+# 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 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=""
+# CONFIG_STANDALONE is not set
+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_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD 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=65536
+# 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 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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 is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# 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=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+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 is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM 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=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_FIXED_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X 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_FEC=y
+# CONFIG_FEC2 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=y
+CONFIG_INPUT_FF_MEMLESS=m
+# 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=y
+CONFIG_INPUT_EVBUG=m
+
+#
+# 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_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 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_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C 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_SERPORT=m
+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=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_HELPER_AUTO is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# 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_IMX is not set
+# 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
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# 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
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# 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:
+#
+# 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 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_TPS65010 is not set
+# CONFIG_TWL4030_CORE 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_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 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=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+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=m
+# CONFIG_MMC_SDHCI_PLTFM is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_MXC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS 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=y
+# 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_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_MXC 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=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=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_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_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=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=m
+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 is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_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_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_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="cp437"
+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=y
+CONFIG_NLS_ISO8859_1=m
+# 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=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# 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=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 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_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 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_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_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 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=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+# 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_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_WORKQUEUE=y
+# 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=y
+# 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=m
+# 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 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=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 is not set
+
+#
+# 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_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/n770_defconfig b/arch/arm/configs/n770_defconfig
index 75cae18fbcb..de0c28aa43e 100644
--- a/arch/arm/configs/n770_defconfig
+++ b/arch/arm/configs/n770_defconfig
@@ -308,6 +308,7 @@ CONFIG_PM_SLEEP=y
CONFIG_SUSPEND_UP_POSSIBLE=y
CONFIG_SUSPEND=y
# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
#
# Networking
diff --git a/arch/arm/configs/n8x0_defconfig b/arch/arm/configs/n8x0_defconfig
index e6f667c5e58..9405e32783d 100644
--- a/arch/arm/configs/n8x0_defconfig
+++ b/arch/arm/configs/n8x0_defconfig
@@ -191,6 +191,7 @@ CONFIG_ARCH_OMAP=y
#
CONFIG_ARCH_OMAP_OTG=y
# CONFIG_ARCH_OMAP1 is not set
+CONFIG_ARCH_OMAP2PLUS=y
CONFIG_ARCH_OMAP2=y
# CONFIG_ARCH_OMAP3 is not set
# CONFIG_ARCH_OMAP4 is not set
@@ -198,8 +199,6 @@ CONFIG_ARCH_OMAP2=y
#
# OMAP Feature Selections
#
-# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
-# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
CONFIG_OMAP_RESET_CLOCKS=y
# CONFIG_OMAP_MUX is not set
# CONFIG_OMAP_MCBSP is not set
@@ -208,15 +207,13 @@ CONFIG_OMAP_MBOX_FWK=y
CONFIG_OMAP_32K_TIMER=y
CONFIG_OMAP_32K_TIMER_HZ=128
CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_LL_DEBUG_UART1 is not set
-# CONFIG_OMAP_LL_DEBUG_UART2 is not set
-CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
# CONFIG_MACH_OMAP_GENERIC is not set
#
# OMAP Core Type
#
-CONFIG_ARCH_OMAP24XX=y
CONFIG_ARCH_OMAP2420=y
# CONFIG_ARCH_OMAP2430 is not set
@@ -227,6 +224,9 @@ CONFIG_MACH_OMAP2_TUSB6010=y
# CONFIG_MACH_OMAP_H4 is not set
# CONFIG_MACH_OMAP_APOLLON is not set
# CONFIG_MACH_OMAP_2430SDP is not set
+CONFIG_MACH_NOKIA_N800=y
+CONFIG_MACH_NOKIA_N810=y
+CONFIG_MACH_NOKIA_N810_WIMAX=y
CONFIG_MACH_NOKIA_N8X0=y
#
@@ -303,7 +303,7 @@ CONFIG_ALIGNMENT_TRAP=y
CONFIG_ZBOOT_ROM_TEXT=0x10C08000
CONFIG_ZBOOT_ROM_BSS=0x10200000
# CONFIG_ZBOOT_ROM is not set
-CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS2,115200n8"
+CONFIG_CMDLINE="root=/dev/mmcblk0p2 console=ttyS2,115200n8 debug earlyprintk rootwait"
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set
@@ -337,7 +337,14 @@ CONFIG_HAVE_AOUT=y
#
# Power management options
#
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -617,7 +624,55 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# 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_OMAP=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_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# 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=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
@@ -673,15 +728,44 @@ CONFIG_SSB_POSSIBLE=y
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+CONFIG_MENELAUS=y
+# CONFIG_TWL4030_CORE 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_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_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
# CONFIG_MEDIA_SUPPORT is not set
#
@@ -718,7 +802,10 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_DEVICEFS=y
CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
# CONFIG_USB_MON is not set
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set
@@ -737,9 +824,10 @@ CONFIG_USB_DEVICE_CLASS=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_TUSB6010=y
# CONFIG_USB_MUSB_HOST is not set
-CONFIG_USB_MUSB_PERIPHERAL=y
-# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
# CONFIG_MUSB_PIO_ONLY is not set
# CONFIG_USB_INVENTRA_DMA is not set
# CONFIG_USB_TI_CPPI_DMA is not set
@@ -824,44 +912,77 @@ CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_ZERO is not set
# CONFIG_USB_AUDIO is not set
CONFIG_USB_ETH=y
-# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_ETH_EEM=y
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
# CONFIG_USB_G_SERIAL is not set
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
+# 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_ISP1301_OMAP is not set
+# CONFIG_USB_ULPI is not set
CONFIG_NOP_USB_XCEIV=y
-# CONFIG_MMC 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_OMAP=y
+# CONFIG_MMC_SPI is not set
# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY 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_REGULATOR 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_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_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
@@ -886,8 +1007,11 @@ CONFIG_INOTIFY_USER=y
#
# DOS/FAT/NT Filesystems
#
+CONFIG_FAT_FS=y
# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_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
#
@@ -934,7 +1058,6 @@ CONFIG_JFFS2_CMODE_PRIORITY=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 is not set
# CONFIG_NFSD is not set
diff --git a/arch/arm/configs/nuc950_defconfig b/arch/arm/configs/nuc950_defconfig
index 97300ec478d..51cc2a260cb 100644
--- a/arch/arm/configs/nuc950_defconfig
+++ b/arch/arm/configs/nuc950_defconfig
@@ -590,8 +590,40 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT 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=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_NUC900=y
+CONFIG_GPM1040A0_320X240=y
+CONFIG_FB_NUC900_DEBUG=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
@@ -603,6 +635,25 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_SUPPORT=y
diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig
index c7999f5b1c9..5a9e95fa728 100644
--- a/arch/arm/configs/omap3_beagle_defconfig
+++ b/arch/arm/configs/omap3_beagle_defconfig
@@ -324,6 +324,7 @@ CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig
index 714835e5ebe..d6ad9217732 100644
--- a/arch/arm/configs/omap3_defconfig
+++ b/arch/arm/configs/omap3_defconfig
@@ -450,7 +450,7 @@ CONFIG_SUSPEND=y
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig
index e2ad859fbec..a6dd6d1af80 100644
--- a/arch/arm/configs/omap3_evm_defconfig
+++ b/arch/arm/configs/omap3_evm_defconfig
@@ -340,6 +340,7 @@ CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
diff --git a/arch/arm/configs/omap3_touchbook_defconfig b/arch/arm/configs/omap3_touchbook_defconfig
index 74fe6be9c5e..968fbaa8f04 100644
--- a/arch/arm/configs/omap3_touchbook_defconfig
+++ b/arch/arm/configs/omap3_touchbook_defconfig
@@ -368,7 +368,7 @@ CONFIG_SUSPEND=y
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig
index bb2917e5cb4..ddde429a7d9 100644
--- a/arch/arm/configs/omap_3430sdp_defconfig
+++ b/arch/arm/configs/omap_3430sdp_defconfig
@@ -363,6 +363,7 @@ CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
diff --git a/arch/arm/configs/omap_3630sdp_defconfig b/arch/arm/configs/omap_3630sdp_defconfig
index d25c3d4424c..609f348b105 100644
--- a/arch/arm/configs/omap_3630sdp_defconfig
+++ b/arch/arm/configs/omap_3630sdp_defconfig
@@ -361,7 +361,7 @@ CONFIG_SUSPEND=y
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
index 523189586a4..91ef2ed0f80 100644
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ b/arch/arm/configs/omap_h2_1610_defconfig
@@ -331,6 +331,7 @@ CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
#
diff --git a/arch/arm/configs/omap_zoom2_defconfig b/arch/arm/configs/omap_zoom2_defconfig
index a82e81332a0..881faea03d7 100644
--- a/arch/arm/configs/omap_zoom2_defconfig
+++ b/arch/arm/configs/omap_zoom2_defconfig
@@ -343,6 +343,7 @@ CONFIG_SUSPEND=y
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -660,7 +661,7 @@ CONFIG_DEVKMEM=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/arm/configs/omap_zoom3_defconfig b/arch/arm/configs/omap_zoom3_defconfig
index ff8ac3dcc31..5e55b550a40 100644
--- a/arch/arm/configs/omap_zoom3_defconfig
+++ b/arch/arm/configs/omap_zoom3_defconfig
@@ -361,7 +361,7 @@ CONFIG_SUSPEND=y
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -680,7 +680,7 @@ CONFIG_DEVKMEM=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 85b05d3e279..ee1ebd8dfa8 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.32-rc6
-# Sat Nov 7 20:52:21 2009
+# Linux kernel version: 2.6.33-rc6
+# Thu Feb 4 23:30:00 2010
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -32,6 +32,12 @@ 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=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
@@ -45,6 +51,7 @@ CONFIG_SYSVIPC_SYSCTL=y
#
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
@@ -122,14 +129,41 @@ CONFIG_LBDAF=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
# 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 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
#
@@ -158,6 +192,7 @@ CONFIG_MMU=y
# 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
@@ -180,6 +215,7 @@ CONFIG_ARCH_ORION5X=y
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
#
# Orion Implementations
@@ -192,6 +228,7 @@ CONFIG_MACH_TS209=y
CONFIG_MACH_TERASTATION_PRO2=y
CONFIG_MACH_LINKSTATION_PRO=y
CONFIG_MACH_LINKSTATION_MINI=y
+CONFIG_MACH_LINKSTATION_LS_HGL=y
CONFIG_MACH_TS409=y
CONFIG_MACH_WRT350N_V2=y
CONFIG_MACH_TS78XX=y
@@ -268,12 +305,10 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
# 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_LEDS=y
@@ -412,10 +447,6 @@ CONFIG_NET_PKTGEN=m
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
-CONFIG_CFG80211_DEFAULT_PS_VALUE=0
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
#
@@ -554,6 +585,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
@@ -562,6 +597,7 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MG_DISK 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
@@ -569,6 +605,7 @@ CONFIG_MISC_DEVICES=y
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
# CONFIG_C2PORT is not set
#
@@ -621,7 +658,9 @@ CONFIG_SCSI_LOWLEVEL=y
# 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
@@ -657,6 +696,7 @@ CONFIG_SCSI_LOWLEVEL=y
# 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_DH is not set
@@ -711,15 +751,16 @@ CONFIG_SATA_MV=y
# 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_PDC2027X 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
@@ -736,7 +777,7 @@ CONFIG_SATA_MV=y
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -842,8 +883,10 @@ CONFIG_MV643XX_ETH=y
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
CONFIG_WLAN=y
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -866,6 +909,7 @@ CONFIG_WLAN=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
@@ -875,6 +919,7 @@ CONFIG_WLAN=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
@@ -993,11 +1038,6 @@ CONFIG_I2C_MV64XXX=y
# 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
@@ -1006,7 +1046,6 @@ CONFIG_I2C_MV64XXX=y
#
# Miscellaneous I2C Chip support
#
-# CONFIG_DS1682 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1033,10 +1072,12 @@ CONFIG_GPIO_SYSFS=y
# 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:
#
+# CONFIG_GPIO_CS5535 is not set
# CONFIG_GPIO_BT8XX is not set
# CONFIG_GPIO_LANGWELL is not set
@@ -1079,6 +1120,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM73 is not set
CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_LM77 is not set
# CONFIG_SENSORS_LM78 is not set
@@ -1104,6 +1146,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1118,6 +1161,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -1140,11 +1184,13 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1316,6 +1362,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# 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_UWB is not set
# CONFIG_MMC is not set
@@ -1332,6 +1379,7 @@ CONFIG_LEDS_GPIO_PLATFORM=y
# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
#
# LED Triggers
@@ -1377,6 +1425,7 @@ CONFIG_RTC_DRV_PCF8563=y
# CONFIG_RTC_DRV_PCF8583 is not set
CONFIG_RTC_DRV_M41T80=y
# CONFIG_RTC_DRV_M41T80_WDT is not set
+# CONFIG_RTC_DRV_BQ32K is not set
CONFIG_RTC_DRV_S35390A=y
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
@@ -1398,7 +1447,9 @@ CONFIG_RTC_DRV_S35390A=y
CONFIG_RTC_DRV_M48T86=y
# 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
#
@@ -1686,7 +1737,9 @@ CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
#
# Security options
@@ -1694,7 +1747,11 @@ CONFIG_DEBUG_LL=y
# 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
#
diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig
index 791b8c39aef..113511f91eb 100644
--- a/arch/arm/configs/pxa168_defconfig
+++ b/arch/arm/configs/pxa168_defconfig
@@ -1,15 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc3
-# Fri Mar 20 13:43:13 2009
+# Linux kernel version: 2.6.33-rc3
+# Tue Jan 12 08:57:10 2010
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,13 +16,12 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=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
@@ -35,6 +32,12 @@ 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=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
@@ -46,11 +49,13 @@ 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=14
# CONFIG_GROUP_SCHED is not set
@@ -64,10 +69,10 @@ CONFIG_NAMESPACES=y
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_NET_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_BLK_DEV_INITRD is not set
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
@@ -78,17 +83,20 @@ 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
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -98,6 +106,11 @@ 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
@@ -109,8 +122,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -118,31 +130,62 @@ CONFIG_BLOCK=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
# 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 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_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_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
@@ -150,26 +193,30 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# 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_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_LOKI is not set
# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
# CONFIG_ARCH_ORION5X is not set
+CONFIG_ARCH_MMP=y
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
-CONFIG_ARCH_MMP=y
+# CONFIG_ARCH_MSM 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_S5PC1XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
# CONFIG_MACH_TAVOREVB is not set
#
@@ -177,6 +224,7 @@ CONFIG_ARCH_MMP=y
#
CONFIG_MACH_ASPENITE=y
CONFIG_MACH_ZYLONITE2=y
+CONFIG_MACH_AVENGERS_LITE=y
# CONFIG_MACH_TTC_DKB is not set
CONFIG_CPU_PXA168=y
CONFIG_PLAT_PXA=y
@@ -187,7 +235,7 @@ CONFIG_PLAT_PXA=y
CONFIG_CPU_MOHAWK=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_LEGACY=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V4WBI=y
@@ -201,7 +249,7 @@ 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_OUTER_CACHE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_IWMMXT=y
CONFIG_COMMON_CLKDEV=y
@@ -223,13 +271,15 @@ 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=y
-CONFIG_ARCH_FLATMEM_HAS_HOLES=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
@@ -237,12 +287,14 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=999999
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=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
@@ -288,7 +340,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -330,6 +381,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -343,6 +395,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -355,13 +409,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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_LIB80211 is not set
-# CONFIG_MAC80211 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
@@ -374,6 +428,7 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
@@ -412,8 +467,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
CONFIG_SMC91X=y
# 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
@@ -422,15 +479,12 @@ CONFIG_SMC91X=y
# 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
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN=y
+# CONFIG_HOSTAP is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -442,6 +496,7 @@ CONFIG_SMC91X=y
# 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
@@ -449,6 +504,7 @@ CONFIG_SMC91X=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
@@ -510,6 +566,11 @@ CONFIG_UNIX98_PTYS=y
# 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
@@ -530,11 +591,14 @@ CONFIG_GPIOLIB=y
#
# 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_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -555,22 +619,8 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_T7L66XB is not set
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB 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 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -595,13 +645,17 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY 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_REGULATOR is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
@@ -613,10 +667,13 @@ CONFIG_RTC_LIB=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=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
@@ -627,6 +684,11 @@ CONFIG_INOTIFY_USER=y
CONFIG_GENERIC_ACL=y
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -673,6 +735,7 @@ 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
@@ -681,7 +744,6 @@ CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -706,6 +768,7 @@ 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
@@ -714,11 +777,15 @@ CONFIG_DEBUG_KERNEL=y
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_DEBUG_SLAB 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
@@ -738,28 +805,33 @@ 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
-
-#
-# Tracers
-#
+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_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING 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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -768,7 +840,9 @@ CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
#
# Security options
@@ -776,13 +850,16 @@ CONFIG_DEBUG_LL=y
# 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_AEAD2=y
@@ -791,10 +868,12 @@ 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_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -822,11 +901,13 @@ CONFIG_CRYPTO_CBC=y
#
# 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=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -863,6 +944,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -870,6 +952,7 @@ CONFIG_CRYPTO_DES=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
@@ -884,7 +967,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig
new file mode 100644
index 00000000000..acb1a8f30e3
--- /dev/null
+++ b/arch/arm/configs/raumfeld_defconfig
@@ -0,0 +1,1898 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc5
+# Sun Nov 1 21:57:32 2009
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=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_ARCH_HAS_CPUFREQ=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=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 is not set
+# CONFIG_SWAP is not set
+# 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_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=17
+# CONFIG_GROUP_SCHED is not set
+# 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_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+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
+
+#
+# Kernel Performance Events And Counters
+#
+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_SLOW_WORK=y
+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 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 is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+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_AT91 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_NOMADIK 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_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_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_MSM 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_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+
+#
+# Supported PXA3xx Processor Variants
+#
+CONFIG_CPU_PXA300=y
+# CONFIG_CPU_PXA310 is not set
+CONFIG_CPU_PXA320=y
+# CONFIG_CPU_PXA930 is not set
+# CONFIG_CPU_PXA935 is not set
+# CONFIG_CPU_PXA950 is not set
+
+#
+# Intel/Marvell Dev Platforms (sorted by hardware release time)
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+
+#
+# Third Party Dev Platforms (sorted by vendor name)
+#
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_MACH_BALLOON3 is not set
+# CONFIG_MACH_CSB726 is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_EXEDA is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
+# CONFIG_MACH_STARGATE2 is not set
+# CONFIG_MACH_XCEP is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_COLIBRI300 is not set
+# CONFIG_MACH_COLIBRI320 is not set
+
+#
+# End-user Products (sorted by vendor name)
+#
+# CONFIG_MACH_H4700 is not set
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_HIMALAYA is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_PXA_EZX is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_ARCH_PXA_PALM is not set
+CONFIG_MACH_RAUMFELD_RC=y
+CONFIG_MACH_RAUMFELD_CONNECTOR=y
+CONFIG_MACH_RAUMFELD_PROTO=y
+CONFIG_MACH_RAUMFELD_SPEAKER=y
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+CONFIG_PXA3xx=y
+CONFIG_PXA_SSP=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSC3=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_IO_36=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_XSC3L2=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_IWMMXT=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 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=4096
+# 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_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="console=ttyS0,115200 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+
+#
+# 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_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=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 is not set
+# 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=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=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_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=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+CONFIG_CFG80211_REG_DEBUG=y
+CONFIG_CFG80211_DEFAULT_PS=y
+CONFIG_CFG80211_DEFAULT_PS_VALUE=1
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUG_MENU 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=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS 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=y
+CONFIG_NFTL_RW=y
+# 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 is not set
+# CONFIG_MTD_JEDECPROBE 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_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_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=y
+
+#
+# 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_H1900 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_SHARPSL is not set
+CONFIG_MTD_NAND_PXA3xx=y
+# CONFIG_MTD_NAND_PXA3xx_BUILTIN 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_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG 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
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB 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_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_ISL29003=y
+CONFIG_TI_DAC7512=y
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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 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=y
+# 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 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 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_DM9000 is not set
+# CONFIG_ENC28J60 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 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_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=y
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_SPI is not set
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_IWM 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=y
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=y
+# CONFIG_USB_NET_CDC_EEM is not set
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC95XX is not set
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+CONFIG_USB_NET_MCS7830=y
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_USB_NET_INT51X1 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 is not set
+CONFIG_INPUT_POLLDEV=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_EVDEV=y
+# 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=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_PXA27x is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+CONFIG_TOUCHSCREEN_EETI=m
+# 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 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=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW 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_MAX3100 is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+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_PXA=y
+# CONFIG_I2C_PXA_SLAVE 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
+
+#
+# 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_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=y
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+# CONFIG_SPI_PXA2XX is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_W1=m
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+CONFIG_W1_MASTER_GPIO=m
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2431 is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+CONFIG_W1_SLAVE_DS2760=m
+# CONFIG_W1_SLAVE_BQ27000 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+CONFIG_PDA_POWER=y
+# CONFIG_APM_POWER is not set
+CONFIG_BATTERY_DS2760=m
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX 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_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A 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_LM70 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_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 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_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 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_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 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_LIS3_SPI=y
+# 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 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_TPS65010 is not set
+# CONFIG_TWL4030_CORE 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_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+CONFIG_REGULATOR_MAX8660=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X 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=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_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
+# CONFIG_FB_PXA_PARAMETERS is not set
+CONFIG_PXA3XX_GCU=y
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 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 is not set
+CONFIG_BACKLIGHT_PWM=y
+
+#
+# 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 is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_RAUMFELD_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 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_PXA2XX_LIB=y
+# CONFIG_SND_PXA2XX_AC97 is not set
+CONFIG_SND_SPI=y
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+CONFIG_SND_PXA_SOC_SSP=y
+CONFIG_SND_SOC_RAUMFELD=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AK4104=y
+CONFIG_SND_SOC_CS4270=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# 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_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=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_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# 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 is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+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_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
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# 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 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=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+# 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_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_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS 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_PXA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_PWM is not set
+# CONFIG_LEDS_BD2802 is not set
+CONFIG_LEDS_LT3593=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+# 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=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 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_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
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# 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_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SA1100 is not set
+CONFIG_RTC_DRV_PXA=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 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=y
+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_FS_XIP=y
+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_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=y
+CONFIG_FSCACHE_STATS=y
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+CONFIG_CACHEFILES=y
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM 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 is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG 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=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFS_FSCACHE=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# 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=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_PRINTK_TIME=y
+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=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_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=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=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_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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC 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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=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_WORKQUEUE=y
+# 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=y
+# 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=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 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=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_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig
index 193bd334fbb..473f9e13f08 100644
--- a/arch/arm/configs/rx51_defconfig
+++ b/arch/arm/configs/rx51_defconfig
@@ -59,8 +59,6 @@ CONFIG_FAIR_GROUP_SCHED=y
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
# 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=y
@@ -322,6 +320,7 @@ CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -479,7 +478,6 @@ CONFIG_BT_HIDP=m
# CONFIG_BT_HCIBFUSB is not set
# CONFIG_BT_HCIVHCI is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
CONFIG_CFG80211=y
# CONFIG_CFG80211_REG_DEBUG is not set
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 2f10dae0279..8e94c3caeb8 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -187,7 +187,7 @@ CONFIG_S3C24XX_GPIO_EXTRA128=y
CONFIG_PM_SIMTEC=y
CONFIG_S3C2410_DMA=y
# CONFIG_S3C2410_DMA_DEBUG is not set
-CONFIG_S3C24XX_ADC=y
+CONFIG_S3C_ADC=y
CONFIG_MACH_SMDK=y
CONFIG_PLAT_S3C=y
CONFIG_CPU_LLSERIAL_S3C2410=y
@@ -203,8 +203,8 @@ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
#
# Power management
#
-# CONFIG_S3C2410_PM_DEBUG is not set
-# CONFIG_S3C2410_PM_CHECK is not set
+# CONFIG_SAMSUNG_PM_DEBUG is not set
+# CONFIG_SAMSUNG_PM_CHECK is not set
CONFIG_S3C_LOWLEVEL_UART_PORT=0
CONFIG_S3C_GPIO_SPACE=0
CONFIG_S3C_DEV_HSMMC=y
diff --git a/arch/arm/configs/s3c6400_defconfig b/arch/arm/configs/s3c6400_defconfig
index f56e50fab79..5e7d4c1b8fc 100644
--- a/arch/arm/configs/s3c6400_defconfig
+++ b/arch/arm/configs/s3c6400_defconfig
@@ -1,14 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc3
-# Mon Nov 3 10:10:30 2008
+# Linux kernel version: 2.6.33-rc4
+# Tue Jan 19 13:12:40 2010
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
-# CONFIG_GENERIC_TIME is not set
-# CONFIG_GENERIC_CLOCKEVENTS is not set
-CONFIG_MMU=y
CONFIG_NO_IOPORT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
@@ -18,13 +15,13 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_HAS_CPUFREQ=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=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
@@ -34,13 +31,30 @@ 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_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_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 is not set
CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -50,8 +64,13 @@ CONFIG_NAMESPACES=y
# 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
@@ -62,32 +81,38 @@ 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
+
+#
+# Kernel Performance Events And Counters
+#
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_MARKERS 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_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
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
@@ -95,11 +120,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_LSF=y
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -107,33 +129,62 @@ CONFIG_LSF=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+# 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_CLPS7500 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_IMX is not set
+# CONFIG_ARCH_NOMADIK is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
@@ -141,35 +192,62 @@ CONFIG_CLASSIC_RCU=y
# 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_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_LOKI is not set
# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC 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_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
CONFIG_ARCH_S3C64XX=y
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5PC1XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+# CONFIG_S3C_ADC is not set
+CONFIG_S3C_DEV_HSMMC=y
+CONFIG_S3C_DEV_HSMMC1=y
+CONFIG_S3C_DEV_I2C1=y
+CONFIG_S3C_DEV_FB=y
+CONFIG_S3C_DEV_USB_HOST=y
+CONFIG_S3C_DEV_USB_HSOTG=y
+CONFIG_S3C_DEV_NAND=y
CONFIG_PLAT_S3C64XX=y
CONFIG_CPU_S3C6400_INIT=y
CONFIG_CPU_S3C6400_CLOCK=y
+# CONFIG_S3C64XX_DMA is not set
CONFIG_S3C64XX_SETUP_I2C0=y
CONFIG_S3C64XX_SETUP_I2C1=y
+CONFIG_S3C64XX_SETUP_FB_24BPP=y
+CONFIG_S3C64XX_SETUP_SDHCI_GPIO=y
CONFIG_PLAT_S3C=y
#
# Boot options
#
CONFIG_S3C_BOOT_ERROR_RESET=y
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
#
# Power management
@@ -177,17 +255,16 @@ CONFIG_S3C_BOOT_ERROR_RESET=y
CONFIG_S3C_LOWLEVEL_UART_PORT=0
CONFIG_S3C_GPIO_SPACE=0
CONFIG_S3C_GPIO_TRACK=y
-CONFIG_S3C_GPIO_PULL_UPDOWN=y
-CONFIG_S3C_GPIO_CFG_S3C24XX=y
-CONFIG_S3C_GPIO_CFG_S3C64XX=y
-CONFIG_S3C_DEV_HSMMC=y
-CONFIG_S3C_DEV_HSMMC1=y
-CONFIG_S3C_DEV_I2C1=y
+# CONFIG_MACH_SMDK6400 is not set
CONFIG_CPU_S3C6410=y
CONFIG_S3C6410_SETUP_SDHCI=y
+# CONFIG_MACH_ANW6410 is not set
CONFIG_MACH_SMDK6410=y
CONFIG_SMDK6410_SD_CH0=y
# CONFIG_SMDK6410_SD_CH1 is not set
+# CONFIG_SMDK6410_WM1190_EV1 is not set
+# CONFIG_MACH_NCP is not set
+# CONFIG_MACH_HMT is not set
#
# Processor Type
@@ -196,7 +273,7 @@ CONFIG_CPU_V6=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v6=y
CONFIG_CPU_ABRT_EV6=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_V6=y
CONFIG_CPU_CACHE_V6=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
@@ -212,8 +289,10 @@ 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_OUTER_CACHE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_411920 is not set
CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
#
# Bus support
@@ -229,13 +308,15 @@ 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=y
-CONFIG_ARCH_FLATMEM_HAS_HOLES=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
@@ -243,26 +324,28 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+CONFIG_SPLIT_PTLOCK_CPUS=999999
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=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=0
CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CMDLINE="console=ttySAC0,115200 root=/dev/ram init=/bin/bash initrd=0x51000000,4M"
+CONFIG_CMDLINE="console=ttySAC0,115200 root=/dev/ram init=/linuxrc initrd=0x51000000,6M ramdisk_size=6144"
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set
#
# CPU Power Management
#
+# CONFIG_CPU_FREQ is not set
# CONFIG_CPU_IDLE is not set
#
@@ -300,6 +383,7 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=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
@@ -314,14 +398,32 @@ 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_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_MG_DISK is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -334,6 +436,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_SCSI_NETLINK is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
+# CONFIG_PHONE is not set
#
# Input device support
@@ -341,6 +444,7 @@ CONFIG_HAVE_IDE=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
@@ -357,27 +461,33 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_GPIO 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_GPIO is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD 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_SENTELIC 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_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
@@ -390,6 +500,7 @@ 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
#
@@ -423,16 +534,18 @@ CONFIG_SERIAL_S3C6400=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
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=y
-# CONFIG_NVRAM is not set
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -443,6 +556,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# 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_S3C2410=y
@@ -463,32 +577,33 @@ CONFIG_I2C_S3C2410=y
#
# Miscellaneous I2C Chip support
#
-# CONFIG_DS1682 is not set
-CONFIG_EEPROM_AT24=y
-# CONFIG_EEPROM_LEGACY 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_TPS65010 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
+
+#
+# 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:
+#
+
+#
# I2C GPIO expanders:
#
# 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:
@@ -497,10 +612,19 @@ CONFIG_GPIOLIB=y
#
# 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_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
@@ -509,17 +633,21 @@ CONFIG_HWMON=y
# 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_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A 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_LM73 is not set
# CONFIG_SENSORS_LM75 is not set
# CONFIG_SENSORS_LM77 is not set
# CONFIG_SENSORS_LM78 is not set
@@ -530,16 +658,24 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 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_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 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_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
@@ -549,15 +685,14 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
@@ -568,28 +703,22 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_ASIC3 is not set
# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE 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_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -612,17 +741,15 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-CONFIG_HID_DEBUG=y
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
#
# Special HID drivers
#
-# CONFIG_HID_COMPAT 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_OHCI=y
# CONFIG_USB_ARCH_HAS_EHCI is not set
# CONFIG_USB is not set
@@ -631,9 +758,13 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
CONFIG_MMC=y
CONFIG_MMC_DEBUG=y
CONFIG_MMC_UNSAFE_RESUME=y
@@ -650,22 +781,24 @@ CONFIG_SDIO_UART=y
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PLTFM is not set
CONFIG_MMC_SDHCI_S3C=y
+# CONFIG_MMC_SDHCI_S3C_DMA is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY 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
#
-# Voltage and Current regulators
+# TI VLYNQ
#
-# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
@@ -674,6 +807,7 @@ 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=y
CONFIG_EXT3_FS_SECURITY=y
@@ -683,9 +817,12 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
# 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=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -696,6 +833,11 @@ CONFIG_INOTIFY_USER=y
CONFIG_GENERIC_ACL=y
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -719,10 +861,7 @@ CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -731,12 +870,17 @@ CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_CRAMFS=y
+# 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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
@@ -755,6 +899,7 @@ 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
@@ -763,12 +908,16 @@ CONFIG_DEBUG_KERNEL=y
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_KMEMLEAK is not set
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
# CONFIG_RT_MUTEX_TESTER is not set
@@ -787,34 +936,43 @@ CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=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_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE 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=y
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
CONFIG_DEBUG_S3C_UART=0
#
@@ -823,13 +981,19 @@ CONFIG_DEBUG_S3C_UART=0
# 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 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
@@ -838,6 +1002,10 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=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_DMA=y
diff --git a/arch/arm/configs/s5p6440_defconfig b/arch/arm/configs/s5p6440_defconfig
new file mode 100644
index 00000000000..279a15e5311
--- /dev/null
+++ b/arch/arm/configs/s5p6440_defconfig
@@ -0,0 +1,969 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc2
+# Sat Jan 9 16:33:55 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_NO_IOPORT=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_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_SWAP=y
+# CONFIG_SYSVIPC is not set
+# 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 is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# 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_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_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=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
+
+#
+# Kernel Performance Events And Counters
+#
+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_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 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_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_NOMADIK 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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM 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=y
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+CONFIG_PLAT_S3C=y
+
+#
+# Boot options
+#
+CONFIG_S3C_BOOT_ERROR_RESET=y
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+
+#
+# Power management
+#
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+CONFIG_PLAT_S5P=y
+CONFIG_CPU_S5P6440_INIT=y
+CONFIG_CPU_S5P6440_CLOCK=y
+CONFIG_CPU_S5P6440=y
+CONFIG_MACH_SMDK6440=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+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_ERRATA_411920 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+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=200
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=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=999999
+# 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=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+# 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_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# 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 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 is not set
+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_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_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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 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=y
+# 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_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# 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_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=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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_XTKBD 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_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT 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=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_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_W90X900 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=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+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_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_S5P6440=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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=y
+# CONFIG_HW_RANDOM_TIMERIOMEM 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:
+#
+
+#
+# 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 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 is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# 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=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=y
+CONFIG_EXT3_FS_SECURITY=y
+# 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=y
+# 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=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 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=y
+# 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_CRAMFS=y
+# 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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_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=y
+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
+
+#
+# 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=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_KMEMLEAK is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+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_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# 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=y
+# 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_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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+CONFIG_DEBUG_S3C_UART=1
+
+#
+# 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_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# 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_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/s5p6442_defconfig b/arch/arm/configs/s5p6442_defconfig
new file mode 100644
index 00000000000..74e20bfc048
--- /dev/null
+++ b/arch/arm/configs/s5p6442_defconfig
@@ -0,0 +1,883 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc4
+# Mon Jan 25 08:50:28 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_NO_IOPORT=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_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_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_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 is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# 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_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=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
+
+#
+# Kernel Performance Events And Counters
+#
+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_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 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_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_NOMADIK 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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM 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=y
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIOLIB_4BIT=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+# CONFIG_S3C_ADC is not set
+
+#
+# Power management
+#
+CONFIG_PLAT_S3C=y
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+CONFIG_PLAT_S5P=y
+CONFIG_CPU_S5P6442=y
+CONFIG_MACH_SMDK6442=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+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_ERRATA_411920 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+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=200
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=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=999999
+# 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=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+# 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_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# 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 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 is not set
+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_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_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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 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=y
+# 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_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# 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_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=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_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_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=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=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+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_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS=3
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_S5PV210=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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=y
+# CONFIG_HW_RANDOM_TIMERIOMEM 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:
+#
+
+#
+# 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 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 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=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP 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=y
+# 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=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 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=y
+# 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_CRAMFS=y
+# 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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_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=y
+# CONFIG_MINIX_SUBPARTITION is not set
+CONFIG_SOLARIS_X86_PARTITION=y
+# 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=y
+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
+
+#
+# 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=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_KMEMLEAK is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+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_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# 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_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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# 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_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_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=y
+# CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+CONFIG_DEBUG_S3C_UART=1
+
+#
+# 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=y
+# 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_DMA=y
diff --git a/arch/arm/configs/s5pc110_defconfig b/arch/arm/configs/s5pc110_defconfig
new file mode 100644
index 00000000000..6ea636131ac
--- /dev/null
+++ b/arch/arm/configs/s5pc110_defconfig
@@ -0,0 +1,894 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc4
+# Wed Feb 24 15:36:54 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_NO_IOPORT=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_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=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=y
+# CONFIG_SYSVIPC is not set
+# 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 is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# 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_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=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
+
+#
+# Kernel Performance Events And Counters
+#
+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_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 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_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_NOMADIK 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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM 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=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIOLIB_4BIT=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+# CONFIG_S3C_ADC is not set
+
+#
+# Power management
+#
+CONFIG_PLAT_S5P=y
+CONFIG_CPU_S5PV210=y
+# CONFIG_MACH_SMDKV210 is not set
+CONFIG_MACH_SMDKC110=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=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=200
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# 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=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+# 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_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# 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 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_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_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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 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=y
+# 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_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# 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_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=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_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_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=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=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+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_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS_4=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_S5PV210=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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=y
+# CONFIG_HW_RANDOM_TIMERIOMEM 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:
+#
+
+#
+# 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 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 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=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP 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=y
+# 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=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 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=y
+# 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_CRAMFS=y
+# 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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_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=y
+# CONFIG_MINIX_SUBPARTITION is not set
+CONFIG_SOLARIS_X86_PARTITION=y
+# 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=y
+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
+
+#
+# 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=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_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+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_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# 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=y
+# 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_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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# 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
+CONFIG_DEBUG_S3C_UART=1
+
+#
+# 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=y
+# 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_DMA=y
diff --git a/arch/arm/configs/s5pv210_defconfig b/arch/arm/configs/s5pv210_defconfig
new file mode 100644
index 00000000000..3f7d47491b5
--- /dev/null
+++ b/arch/arm/configs/s5pv210_defconfig
@@ -0,0 +1,894 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc4
+# Wed Feb 24 15:36:16 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_NO_IOPORT=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_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=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=y
+# CONFIG_SYSVIPC is not set
+# 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 is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# 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_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=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
+
+#
+# Kernel Performance Events And Counters
+#
+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_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 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_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_NOMADIK 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_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM 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=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_PLAT_SAMSUNG=y
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIOLIB_4BIT=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+# CONFIG_S3C_ADC is not set
+
+#
+# Power management
+#
+CONFIG_PLAT_S5P=y
+CONFIG_CPU_S5PV210=y
+CONFIG_MACH_SMDKV210=y
+# CONFIG_MACH_SMDKC110 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_ARM_L1_CACHE_SHIFT=6
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=200
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# 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=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+# 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_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# 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 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_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_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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 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=y
+# 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_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# 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_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=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_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_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=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=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+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_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS_4=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_S5PV210=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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=y
+# CONFIG_HW_RANDOM_TIMERIOMEM 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:
+#
+
+#
+# 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 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 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=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP 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=y
+# 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=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 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=y
+# 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_CRAMFS=y
+# 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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_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=y
+# CONFIG_MINIX_SUBPARTITION is not set
+CONFIG_SOLARIS_X86_PARTITION=y
+# 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=y
+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
+
+#
+# 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=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_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+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_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# 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=y
+# 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_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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# 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
+CONFIG_DEBUG_S3C_UART=1
+
+#
+# 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=y
+# 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_DMA=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 00f46d9ce29..6e8f05c8a1c 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -149,10 +149,10 @@
#define USER(x...) \
9999: x; \
- .section __ex_table,"a"; \
+ .pushsection __ex_table,"a"; \
.align 3; \
.long 9999b,9001f; \
- .previous
+ .popsection
/*
* SMP data memory barrier
@@ -193,10 +193,10 @@
.error "Unsupported inc macro argument"
.endif
- .section __ex_table,"a"
+ .pushsection __ex_table,"a"
.align 3
.long 9999b, \abort
- .previous
+ .popsection
.endm
.macro usracc, instr, reg, ptr, inc, cond, rept, abort
@@ -234,10 +234,10 @@
.error "Unsupported inc macro argument"
.endif
- .section __ex_table,"a"
+ .pushsection __ex_table,"a"
.align 3
.long 9999b, \abort
- .previous
+ .popsection
.endr
.endm
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 72da7e045c6..0d08d4170b6 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -15,6 +15,7 @@
#include <asm/glue.h>
#include <asm/shmparam.h>
#include <asm/cachetype.h>
+#include <asm/outercache.h>
#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
@@ -219,12 +220,6 @@ struct cpu_cache_fns {
void (*dma_flush_range)(const void *, const void *);
};
-struct outer_cache_fns {
- void (*inv_range)(unsigned long, unsigned long);
- void (*clean_range)(unsigned long, unsigned long);
- void (*flush_range)(unsigned long, unsigned long);
-};
-
/*
* Select the calling method
*/
@@ -281,37 +276,6 @@ extern void dmac_flush_range(const void *, const void *);
#endif
-#ifdef CONFIG_OUTER_CACHE
-
-extern struct outer_cache_fns outer_cache;
-
-static inline void outer_inv_range(unsigned long start, unsigned long end)
-{
- if (outer_cache.inv_range)
- outer_cache.inv_range(start, end);
-}
-static inline void outer_clean_range(unsigned long start, unsigned long end)
-{
- if (outer_cache.clean_range)
- outer_cache.clean_range(start, end);
-}
-static inline void outer_flush_range(unsigned long start, unsigned long end)
-{
- if (outer_cache.flush_range)
- outer_cache.flush_range(start, end);
-}
-
-#else
-
-static inline void outer_inv_range(unsigned long start, unsigned long end)
-{ }
-static inline void outer_clean_range(unsigned long start, unsigned long end)
-{ }
-static inline void outer_flush_range(unsigned long start, unsigned long end)
-{ }
-
-#endif
-
/*
* Copy user data from/to a page which is mapped into a different
* processes address space. Really, we want to allow our "user
diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h
index 7a0690da5e6..b56c1389b6f 100644
--- a/arch/arm/include/asm/clkdev.h
+++ b/arch/arm/include/asm/clkdev.h
@@ -13,6 +13,7 @@
#define __ASM_CLKDEV_H
struct clk;
+struct device;
struct clk_lookup {
struct list_head node;
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 256ee1c9f51..69ce0727edb 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -128,6 +128,14 @@ static inline int dma_supported(struct device *dev, u64 mask)
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
{
+#ifdef CONFIG_DMABOUNCE
+ if (dev->archdata.dmabounce) {
+ if (dma_mask >= ISA_DMA_THRESHOLD)
+ return 0;
+ else
+ return -EIO;
+ }
+#endif
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index a399bb5730f..bff056489cc 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -98,6 +98,7 @@ extern int elf_check_arch(const struct elf32_hdr *);
extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
+struct task_struct;
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
#define ELF_CORE_COPY_TASK_REGS dump_task_regs
diff --git a/arch/arm/include/asm/entry-macro-vic2.S b/arch/arm/include/asm/entry-macro-vic2.S
new file mode 100644
index 00000000000..3ceb85e4385
--- /dev/null
+++ b/arch/arm/include/asm/entry-macro-vic2.S
@@ -0,0 +1,57 @@
+/* arch/arm/include/asm/entry-macro-vic2.S
+ *
+ * Originally arch/arm/mach-s3c6400/include/mach/entry-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Low-level IRQ helper macros for a device with two VICs
+ *
+ * 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.
+*/
+
+/* This should be included from <mach/entry-macro.S> with the necessary
+ * defines for virtual addresses and IRQ bases for the two vics.
+ *
+ * The code needs the following defined:
+ * IRQ_VIC0_BASE IRQ number of VIC0's first IRQ
+ * IRQ_VIC1_BASE IRQ number of VIC1's first IRQ
+ * VA_VIC0 Virtual address of VIC0
+ * VA_VIC1 Virtual address of VIC1
+ *
+ * Note, code assumes VIC0's virtual address is an ARM immediate constant
+ * away from VIC1.
+*/
+
+#include <asm/hardware/vic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =VA_VIC0
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ @ check the vic0
+ mov \irqnr, #IRQ_VIC0_BASE + 31
+ ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
+ teq \irqstat, #0
+
+ @ otherwise try vic1
+ addeq \tmp, \base, #(VA_VIC1 - VA_VIC0)
+ addeq \irqnr, \irqnr, #(IRQ_VIC1_BASE - IRQ_VIC0_BASE)
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index bfcc15929a7..540a044153a 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -21,14 +21,14 @@
"2: strt %0, [%2]\n" \
" mov %0, #0\n" \
"3:\n" \
- " .section __ex_table,\"a\"\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 4f, 2b, 4f\n" \
- " .previous\n" \
- " .section .fixup,\"ax\"\n" \
+ " .popsection\n" \
+ " .pushsection .fixup,\"ax\"\n" \
"4: mov %0, %4\n" \
" b 3b\n" \
- " .previous" \
+ " .popsection" \
: "=&r" (ret), "=&r" (oldval) \
: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
: "cc", "memory")
@@ -102,14 +102,14 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
" it eq @ explicit IT needed for the 2b label\n"
"2: streqt %2, [%3]\n"
"3:\n"
- " .section __ex_table,\"a\"\n"
+ " .pushsection __ex_table,\"a\"\n"
" .align 3\n"
" .long 1b, 4f, 2b, 4f\n"
- " .previous\n"
- " .section .fixup,\"ax\"\n"
+ " .popsection\n"
+ " .pushsection .fixup,\"ax\"\n"
"4: mov %0, %4\n"
" b 3b\n"
- " .previous"
+ " .popsection"
: "=&r" (val)
: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
: "cc", "memory");
diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h
index 74b5fff7f57..6700c7fc7eb 100644
--- a/arch/arm/include/asm/hardware/it8152.h
+++ b/arch/arm/include/asm/hardware/it8152.h
@@ -75,6 +75,18 @@ extern unsigned long it8152_base_address;
IT8152_PD_IRQ(1) USB (USBR)
IT8152_PD_IRQ(0) Audio controller (ACR)
*/
+#define IT8152_IRQ(x) (IRQ_BOARD_END + (x))
+
+/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
+#define IT8152_LD_IRQ_COUNT 9
+#define IT8152_LP_IRQ_COUNT 16
+#define IT8152_PD_IRQ_COUNT 15
+
+/* Priorities: */
+#define IT8152_PD_IRQ(i) IT8152_IRQ(i)
+#define IT8152_LP_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT)
+#define IT8152_LD_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT + IT8152_LP_IRQ_COUNT)
+
/* frequently used interrupts */
#define IT8152_PCISERR IT8152_PD_IRQ(14)
#define IT8152_H2PTADR IT8152_PD_IRQ(13)
diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h
index 954b1be991b..74e51d6bd93 100644
--- a/arch/arm/include/asm/hardware/locomo.h
+++ b/arch/arm/include/asm/hardware/locomo.h
@@ -214,4 +214,8 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
/* Frontlight control */
void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf);
+struct locomo_platform_data {
+ int irq_base; /* IRQ base for cascaded on-chip IRQs */
+};
+
#endif
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index 5da2595759e..92ed254c175 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -578,4 +578,8 @@ void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int
void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
+struct sa1111_platform_data {
+ int irq_base; /* base for cascaded on-chip IRQs */
+};
+
#endif /* _ASM_ARCH_SA1111 */
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 7f36d00600b..feb988a7ec3 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -11,7 +11,11 @@
#define kmap_prot PAGE_KERNEL
-#define flush_cache_kmaps() flush_cache_all()
+#define flush_cache_kmaps() \
+ do { \
+ if (cache_is_vivt()) \
+ flush_cache_all(); \
+ } while (0)
extern pte_t *pkmap_page_table;
@@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page);
extern void *kmap_high_get(struct page *page);
extern void kunmap_high(struct page *page);
+extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
+extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
+
+/*
+ * The following functions are already defined by <linux/highmem.h>
+ * when CONFIG_HIGHMEM is not set.
+ */
+#ifdef CONFIG_HIGHMEM
extern void *kmap(struct page *page);
extern void kunmap(struct page *page);
extern void *kmap_atomic(struct page *page, enum km_type type);
extern void kunmap_atomic(void *kvaddr, enum km_type type);
extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
extern struct page *kmap_atomic_to_page(const void *ptr);
+#endif
#endif
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 328f14a8b79..237282f7c76 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -17,6 +17,7 @@
#ifndef __ASSEMBLY__
struct irqaction;
+struct pt_regs;
extern void migrate_irqs(void);
extern void asm_do_IRQ(unsigned int, struct pt_regs *);
diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h
index c019949a518..c4b2ea3fbe4 100644
--- a/arch/arm/include/asm/kmap_types.h
+++ b/arch/arm/include/asm/kmap_types.h
@@ -18,6 +18,7 @@ enum km_type {
KM_IRQ1,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
+ KM_L1_CACHE,
KM_L2_CACHE,
KM_TYPE_NR
};
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
new file mode 100644
index 00000000000..25f76bae57a
--- /dev/null
+++ b/arch/arm/include/asm/outercache.h
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/include/asm/outercache.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 __ASM_OUTERCACHE_H
+#define __ASM_OUTERCACHE_H
+
+struct outer_cache_fns {
+ void (*inv_range)(unsigned long, unsigned long);
+ void (*clean_range)(unsigned long, unsigned long);
+ void (*flush_range)(unsigned long, unsigned long);
+#ifdef CONFIG_OUTER_CACHE_SYNC
+ void (*sync)(void);
+#endif
+};
+
+#ifdef CONFIG_OUTER_CACHE
+
+extern struct outer_cache_fns outer_cache;
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{
+ if (outer_cache.inv_range)
+ outer_cache.inv_range(start, end);
+}
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{
+ if (outer_cache.clean_range)
+ outer_cache.clean_range(start, end);
+}
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{
+ if (outer_cache.flush_range)
+ outer_cache.flush_range(start, end);
+}
+
+#else
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{ }
+
+#endif
+
+#ifdef CONFIG_OUTER_CACHE_SYNC
+static inline void outer_sync(void)
+{
+ if (outer_cache.sync)
+ outer_cache.sync();
+}
+#else
+static inline void outer_sync(void)
+{ }
+#endif
+
+#endif /* __ASM_OUTERCACHE_H */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 226cddd2fb6..47980118d0a 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -30,17 +30,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
*/
#define PCI_DMA_BUS_IS_PHYS (1)
-/*
- * Whether pci_unmap_{single,page} is a nop depends upon the
- * configuration.
- */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
-
#ifdef CONFIG_PCI
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
enum pci_dma_burst_strategy *strat,
diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
index 013cfcdc483..ffc0e85775b 100644
--- a/arch/arm/include/asm/pgtable-nommu.h
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -67,6 +67,7 @@ static inline int pte_file(pte_t pte) { return 0; }
*/
#define pgprot_noncached(prot) __pgprot(0)
#define pgprot_writecombine(prot) __pgprot(0)
+#define pgprot_dmacoherent(prot) __pgprot(0)
/*
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index eec6e897ceb..9dcb11e5902 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -128,6 +128,8 @@ struct pt_regs {
#ifdef __KERNEL__
+#define arch_has_single_step() (1)
+
#define user_mode(regs) \
(((regs)->ARM_cpsr & 0xf) == 0)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index ca88e6a8470..4ace45ec3ef 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -60,6 +60,8 @@
#include <linux/linkage.h>
#include <linux/irqflags.h>
+#include <asm/outercache.h>
+
#define __exception __attribute__((section(".exception.text")))
struct thread_info;
@@ -137,10 +139,12 @@ extern unsigned int user_debug;
#define dmb() __asm__ __volatile__ ("" : : : "memory")
#endif
-#if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
-#define mb() dmb()
+#ifdef CONFIG_ARCH_HAS_BARRIERS
+#include <mach/barriers.h>
+#elif __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
+#define mb() do { dsb(); outer_sync(); } while (0)
#define rmb() dmb()
-#define wmb() dmb()
+#define wmb() mb()
#else
#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
@@ -152,9 +156,9 @@ extern unsigned int user_debug;
#define smp_rmb() barrier()
#define smp_wmb() barrier()
#else
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
+#define smp_mb() dmb()
+#define smp_rmb() dmb()
+#define smp_wmb() dmb()
#endif
#define read_barrier_depends() do { } while(0)
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 1d6bd40a432..33e4a48fe10 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -229,16 +229,16 @@ do { \
__asm__ __volatile__( \
"1: ldrbt %1,[%2]\n" \
"2:\n" \
- " .section .fixup,\"ax\"\n" \
+ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"3: mov %0, %3\n" \
" mov %1, #0\n" \
" b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 3b\n" \
- " .previous" \
+ " .popsection" \
: "+r" (err), "=&r" (x) \
: "r" (addr), "i" (-EFAULT) \
: "cc")
@@ -265,16 +265,16 @@ do { \
__asm__ __volatile__( \
"1: ldrt %1,[%2]\n" \
"2:\n" \
- " .section .fixup,\"ax\"\n" \
+ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"3: mov %0, %3\n" \
" mov %1, #0\n" \
" b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 3b\n" \
- " .previous" \
+ " .popsection" \
: "+r" (err), "=&r" (x) \
: "r" (addr), "i" (-EFAULT) \
: "cc")
@@ -310,15 +310,15 @@ do { \
__asm__ __volatile__( \
"1: strbt %1,[%2]\n" \
"2:\n" \
- " .section .fixup,\"ax\"\n" \
+ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"3: mov %0, %3\n" \
" b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 3b\n" \
- " .previous" \
+ " .popsection" \
: "+r" (err) \
: "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
: "cc")
@@ -343,15 +343,15 @@ do { \
__asm__ __volatile__( \
"1: strt %1,[%2]\n" \
"2:\n" \
- " .section .fixup,\"ax\"\n" \
+ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"3: mov %0, %3\n" \
" b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 3b\n" \
- " .previous" \
+ " .popsection" \
: "+r" (err) \
: "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
: "cc")
@@ -371,16 +371,16 @@ do { \
THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \
THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \
"3:\n" \
- " .section .fixup,\"ax\"\n" \
+ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"4: mov %0, %3\n" \
" b 3b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 4b\n" \
" .long 2b, 4b\n" \
- " .previous" \
+ " .popsection" \
: "+r" (err), "+r" (__pu_addr) \
: "r" (x), "i" (-EFAULT) \
: "cc")
diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h
index bf65e9f4525..47f023aa849 100644
--- a/arch/arm/include/asm/ucontext.h
+++ b/arch/arm/include/asm/ucontext.h
@@ -59,23 +59,22 @@ struct iwmmxt_sigframe {
#endif /* CONFIG_IWMMXT */
#ifdef CONFIG_VFP
-#if __LINUX_ARM_ARCH__ < 6
-/* For ARM pre-v6, we use fstmiax and fldmiax. This adds one extra
- * word after the registers, and a word of padding at the end for
- * alignment. */
#define VFP_MAGIC 0x56465001
-#define VFP_STORAGE_SIZE 152
-#else
-#define VFP_MAGIC 0x56465002
-#define VFP_STORAGE_SIZE 144
-#endif
struct vfp_sigframe
{
unsigned long magic;
unsigned long size;
- union vfp_state storage;
-};
+ struct user_vfp ufp;
+ struct user_vfp_exc ufp_exc;
+} __attribute__((__aligned__(8)));
+
+/*
+ * 8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc,
+ * 4 bytes padding.
+ */
+#define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe)
+
#endif /* CONFIG_VFP */
/*
@@ -91,7 +90,7 @@ struct aux_sigframe {
#ifdef CONFIG_IWMMXT
struct iwmmxt_sigframe iwmmxt;
#endif
-#if 0 && defined CONFIG_VFP /* Not yet saved. */
+#ifdef CONFIG_VFP
struct vfp_sigframe vfp;
#endif
/* Something that isn't a valid magic number for any coprocessor. */
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index cf9cdaa2d4d..dd2bf53000f 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -443,9 +443,12 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_UTIME
diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h
index df95e050f9d..05ac4b06876 100644
--- a/arch/arm/include/asm/user.h
+++ b/arch/arm/include/asm/user.h
@@ -83,11 +83,21 @@ struct user{
/*
* User specific VFP registers. If only VFPv2 is present, registers 16 to 31
- * are ignored by the ptrace system call.
+ * are ignored by the ptrace system call and the signal handler.
*/
struct user_vfp {
unsigned long long fpregs[32];
unsigned long fpscr;
};
+/*
+ * VFP exception registers exposed to user space during signal delivery.
+ * Fields not relavant to the current VFP architecture are ignored.
+ */
+struct user_vfp_exc {
+ unsigned long fpexc;
+ unsigned long fpinst;
+ unsigned long fpinst2;
+};
+
#endif /* _ARM_USER_H */
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 9314a2d681f..37ae301cc47 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -91,7 +91,7 @@
CALL(sys_settimeofday)
/* 80 */ CALL(sys_getgroups16)
CALL(sys_setgroups16)
- CALL(OBSOLETE(old_select)) /* used by libc4 */
+ CALL(OBSOLETE(sys_old_select)) /* used by libc4 */
CALL(sys_symlink)
CALL(sys_ni_syscall) /* was sys_lstat */
/* 85 */ CALL(sys_readlink)
@@ -99,7 +99,7 @@
CALL(sys_swapon)
CALL(sys_reboot)
CALL(OBSOLETE(sys_old_readdir)) /* used by libc4 */
-/* 90 */ CALL(OBSOLETE(old_mmap)) /* used by libc4 */
+/* 90 */ CALL(OBSOLETE(sys_old_mmap)) /* used by libc4 */
CALL(sys_munmap)
CALL(sys_truncate)
CALL(sys_ftruncate)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 6c5cf369183..e6a0fb0f392 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -523,16 +523,16 @@ ENDPROC(__und_usr)
/*
* The out of line fixup for the ldrt above.
*/
- .section .fixup, "ax"
+ .pushsection .fixup, "ax"
4: mov pc, r9
- .previous
- .section __ex_table,"a"
+ .popsection
+ .pushsection __ex_table,"a"
.long 1b, 4b
#if __LINUX_ARM_ARCH__ >= 7
.long 2b, 4b
.long 3b, 4b
#endif
- .previous
+ .popsection
/*
* Check whether the instruction is a co-processor instruction.
@@ -679,7 +679,7 @@ do_fpe:
.data
ENTRY(fp_enter)
.word no_fp
- .previous
+ .text
ENTRY(no_fp)
mov pc, lr
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 7e9ed1eea40..d93f976fb38 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -102,6 +102,8 @@
.else
ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
.endif
+ mov r0, r0 @ ARMv5T and earlier require a nop
+ @ after ldm {}^
add sp, sp, #S_FRAME_SIZE - S_PC
movs pc, lr @ return & move spsr_svc into cpsr
.endm
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index c6384276622..0298286ad4a 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -62,15 +62,15 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code,
" movne %0, #2 \n"
"3:\n"
- ".section .fixup, \"ax\"\n"
+ ".pushsection .fixup, \"ax\"\n"
"4: mov %0, #1 \n"
" b 3b \n"
- ".previous\n"
+ ".popsection\n"
- ".section __ex_table, \"a\"\n"
+ ".pushsection __ex_table, \"a\"\n"
" .long 1b, 4b \n"
" .long 2b, 4b \n"
- ".previous\n"
+ ".popsection\n"
: "=r"(err), "=r"(replaced)
: "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced)
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b7cb45bb91e..3b3d2c80509 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -27,7 +27,6 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/smp.h>
#include <linux/init.h>
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index ba8ccfede96..a5b846b9895 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -9,6 +9,7 @@
* Authors: George Davis <davis_g@mvista.com>
* Deepak Saxena <dsaxena@plexity.net>
*/
+#include <linux/irq.h>
#include <linux/kgdb.h>
#include <asm/traps.h>
@@ -158,6 +159,18 @@ static struct undef_hook kgdb_compiled_brkpt_hook = {
.fn = kgdb_compiled_brk_fn
};
+static void kgdb_call_nmi_hook(void *ignored)
+{
+ kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+ local_irq_enable();
+ smp_call_function(kgdb_call_nmi_hook, NULL, 0);
+ local_irq_disable();
+}
+
/**
* kgdb_arch_init - Perform any architecture specific initalization.
*
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 60c62c377fa..2ba7deb3072 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/stop_machine.h>
#include <linux/stringify.h>
#include <asm/traps.h>
@@ -393,6 +394,14 @@ void __kprobes jprobe_return(void)
/*
* Setup an empty pt_regs. Fill SP and PC fields as
* they're needed by longjmp_break_handler.
+ *
+ * We allocate some slack between the original SP and start of
+ * our fabricated regs. To be precise we want to have worst case
+ * covered which is STMFD with all 16 regs so we allocate 2 *
+ * sizeof(struct_pt_regs)).
+ *
+ * This is to prevent any simulated instruction from writing
+ * over the regs when they are accessing the stack.
*/
"sub sp, %0, %1 \n\t"
"ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t"
@@ -410,7 +419,7 @@ void __kprobes jprobe_return(void)
"ldmia sp, {r0 - pc} \n\t"
:
: "r" (kcb->jprobe_saved_regs.ARM_sp),
- "I" (sizeof(struct pt_regs)),
+ "I" (sizeof(struct pt_regs) * 2),
"J" (offsetof(struct pt_regs, ARM_sp)),
"J" (offsetof(struct pt_regs, ARM_pc)),
"J" (offsetof(struct pt_regs, ARM_cpsr))
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index f28c5e9c51e..c628bdf6c43 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -16,9 +16,9 @@
#include <linux/mm.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/string.h>
+#include <linux/gfp.h>
#include <asm/pgtable.h>
#include <asm/sections.h>
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index c54ceb3d1f9..9e70f2053f9 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -332,7 +332,8 @@ armpmu_reserve_hardware(void)
for (i = 0; i < pmu_irqs->num_irqs; ++i) {
err = request_irq(pmu_irqs->irqs[i], armpmu->handle_irq,
- IRQF_DISABLED, "armpmu", NULL);
+ IRQF_DISABLED | IRQF_NOBALANCING,
+ "armpmu", NULL);
if (err) {
pr_warning("unable to request IRQ%d for ARM "
"perf counters\n", pmu_irqs->irqs[i]);
@@ -965,7 +966,7 @@ armv6pmu_handle_irq(int irq_num,
*/
armv6_pmcr_write(pmcr);
- data.addr = 0;
+ perf_sample_data_init(&data, 0);
cpuc = &__get_cpu_var(cpu_hw_events);
for (idx = 0; idx <= armpmu->num_events; ++idx) {
@@ -1624,7 +1625,7 @@ enum armv7_counters {
/*
* EVTSEL: Event selection reg
*/
-#define ARMV7_EVTSEL_MASK 0x7f /* Mask for writable bits */
+#define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */
/*
* SELECT: Counter selection reg
@@ -1945,7 +1946,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
*/
regs = get_irq_regs();
- data.addr = 0;
+ perf_sample_data_init(&data, 0);
cpuc = &__get_cpu_var(cpu_hw_events);
for (idx = 0; idx <= armpmu->num_events; ++idx) {
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index ba2adefa53f..acf5e6fdb6d 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/delay.h>
#include <linux/reboot.h>
@@ -356,7 +355,7 @@ EXPORT_SYMBOL(dump_fpu);
* the thread function, and r3 points to the exit function.
*/
extern void kernel_thread_helper(void);
-asm( ".section .text\n"
+asm( ".pushsection .text\n"
" .align\n"
" .type kernel_thread_helper, #function\n"
"kernel_thread_helper:\n"
@@ -364,11 +363,11 @@ asm( ".section .text\n"
" mov lr, r3\n"
" mov pc, r2\n"
" .size kernel_thread_helper, . - kernel_thread_helper\n"
-" .previous");
+" .popsection");
#ifdef CONFIG_ARM_UNWIND
extern void kernel_thread_exit(long code);
-asm( ".section .text\n"
+asm( ".pushsection .text\n"
" .align\n"
" .type kernel_thread_exit, #function\n"
"kernel_thread_exit:\n"
@@ -378,7 +377,7 @@ asm( ".section .text\n"
" nop\n"
" .fnend\n"
" .size kernel_thread_exit, . - kernel_thread_exit\n"
-" .previous");
+" .popsection");
#else
#define kernel_thread_exit do_exit
#endif
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 08f899fb76a..3f562a7c0a9 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -452,12 +452,23 @@ void ptrace_cancel_bpt(struct task_struct *child)
clear_breakpoint(child, &child->thread.debug.bp[i]);
}
+void user_disable_single_step(struct task_struct *task)
+{
+ task->ptrace &= ~PT_SINGLESTEP;
+ ptrace_cancel_bpt(task);
+}
+
+void user_enable_single_step(struct task_struct *task)
+{
+ task->ptrace |= PT_SINGLESTEP;
+}
+
/*
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
{
- single_step_disable(child);
+ user_disable_single_step(child);
}
/*
@@ -753,53 +764,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_write_user(child, addr, data);
break;
- /*
- * continue/restart and stop at next (return from) syscall
- */
- case PTRACE_SYSCALL:
- case PTRACE_CONT:
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- single_step_disable(child);
- wake_up_process(child);
- ret = 0;
- break;
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL:
- single_step_disable(child);
- if (child->exit_state != EXIT_ZOMBIE) {
- child->exit_code = SIGKILL;
- wake_up_process(child);
- }
- ret = 0;
- break;
-
- /*
- * execute single instruction.
- */
- case PTRACE_SINGLESTEP:
- ret = -EIO;
- if (!valid_signal(data))
- break;
- single_step_enable(child);
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- break;
-
case PTRACE_GETREGS:
ret = ptrace_getregs(child, (void __user *)data);
break;
diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h
index def3b6184a7..3926605b82e 100644
--- a/arch/arm/kernel/ptrace.h
+++ b/arch/arm/kernel/ptrace.h
@@ -14,20 +14,6 @@ extern void ptrace_set_bpt(struct task_struct *);
extern void ptrace_break(struct task_struct *, struct pt_regs *);
/*
- * make sure single-step breakpoint is gone.
- */
-static inline void single_step_disable(struct task_struct *task)
-{
- task->ptrace &= ~PT_SINGLESTEP;
- ptrace_cancel_bpt(task);
-}
-
-static inline void single_step_enable(struct task_struct *task)
-{
- task->ptrace |= PT_SINGLESTEP;
-}
-
-/*
* Send SIGTRAP if we're single-stepping
*/
static inline void single_step_trap(struct task_struct *task)
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index e7714f367eb..907d5a620bc 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -18,6 +18,7 @@
#include <asm/cacheflush.h>
#include <asm/ucontext.h>
#include <asm/unistd.h>
+#include <asm/vfp.h>
#include "ptrace.h"
#include "signal.h"
@@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
#endif
+#ifdef CONFIG_VFP
+
+static int preserve_vfp_context(struct vfp_sigframe __user *frame)
+{
+ struct thread_info *thread = current_thread_info();
+ struct vfp_hard_struct *h = &thread->vfpstate.hard;
+ const unsigned long magic = VFP_MAGIC;
+ const unsigned long size = VFP_STORAGE_SIZE;
+ int err = 0;
+
+ vfp_sync_hwstate(thread);
+ __put_user_error(magic, &frame->magic, err);
+ __put_user_error(size, &frame->size, err);
+
+ /*
+ * Copy the floating point registers. There can be unused
+ * registers see asm/hwcap.h for details.
+ */
+ err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
+ sizeof(h->fpregs));
+ /*
+ * Copy the status and control register.
+ */
+ __put_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+ /*
+ * Copy the exception registers.
+ */
+ __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
+ __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+ __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+ return err ? -EFAULT : 0;
+}
+
+static int restore_vfp_context(struct vfp_sigframe __user *frame)
+{
+ struct thread_info *thread = current_thread_info();
+ struct vfp_hard_struct *h = &thread->vfpstate.hard;
+ unsigned long magic;
+ unsigned long size;
+ unsigned long fpexc;
+ int err = 0;
+
+ __get_user_error(magic, &frame->magic, err);
+ __get_user_error(size, &frame->size, err);
+
+ if (err)
+ return -EFAULT;
+ if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
+ return -EINVAL;
+
+ /*
+ * Copy the floating point registers. There can be unused
+ * registers see asm/hwcap.h for details.
+ */
+ err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
+ sizeof(h->fpregs));
+ /*
+ * Copy the status and control register.
+ */
+ __get_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+ /*
+ * Sanitise and restore the exception registers.
+ */
+ __get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
+ /* Ensure the VFP is enabled. */
+ fpexc |= FPEXC_EN;
+ /* Ensure FPINST2 is invalid and the exception flag is cleared. */
+ fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
+ h->fpexc = fpexc;
+
+ __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+ __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+ if (!err)
+ vfp_flush_hwstate(thread);
+
+ return err ? -EFAULT : 0;
+}
+
+#endif
+
/*
* Do a signal return; undo the signal stack. These are aligned to 64-bit.
*/
@@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
err |= restore_iwmmxt_context(&aux->iwmmxt);
#endif
#ifdef CONFIG_VFP
-// if (err == 0)
-// err |= vfp_restore_state(&sf->aux.vfp);
+ if (err == 0)
+ err |= restore_vfp_context(&aux->vfp);
#endif
return err;
@@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
err |= preserve_iwmmxt_context(&aux->iwmmxt);
#endif
#ifdef CONFIG_VFP
-// if (err == 0)
-// err |= vfp_save_state(&sf->aux.vfp);
+ if (err == 0)
+ err |= preserve_vfp_context(&aux->vfp);
#endif
__put_user_error(0, &aux->end_magic, err);
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 57162af53dc..577543f3857 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -99,6 +99,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
flush_pmd_entry(pmd);
+ outer_clean_range(__pa(pmd), __pa(pmd + 1));
/*
* We need to tell the secondary core where to find
@@ -106,7 +107,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
*/
secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
secondary_data.pgdir = virt_to_phys(pgd);
- wmb();
+ __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
+ outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
/*
* Now bring the CPU into our world.
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index ae4027bd01b..c23501842b9 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/sem.h>
#include <linux/msg.h>
@@ -27,135 +26,7 @@
#include <linux/file.h>
#include <linux/ipc.h>
#include <linux/uaccess.h>
-
-struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
-{
- int error = -EFAULT;
- struct mmap_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
-
- error = -EINVAL;
- if (a.offset & ~PAGE_MASK)
- goto out;
-
- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-out:
- return error;
-}
-
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls.
- */
-
-struct sel_arg_struct {
- unsigned long n;
- fd_set __user *inp, *outp, *exp;
- struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
- struct sel_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
- /* sys_select() does the appropriate kernel locking */
- return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc(uint call, int first, int second, int third,
- void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
- (const struct timespec __user *)fifth);
-
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void __user * __user *) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd(first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
- if (copy_from_user(&tmp,(struct ipc_kludge __user *)ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
-
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat(first, (char __user *)ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user(raddr, (ulong __user *)third);
- }
- case 1: /* Of course, we don't support iBCS2! */
- return -EINVAL;
- }
- case SHMDT:
- return sys_shmdt ((char __user *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -ENOSYS;
- }
-}
-#endif
+#include <linux/slab.h>
/* Fork a new task - this creates a new program thread.
* This is called indirectly via a small wrapper
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index d59a0cd537f..33ff678e32f 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -346,9 +346,6 @@ asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops,
return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
}
-extern asmlinkage int sys_ipc(uint call, int first, int second, int third,
- void __user *ptr, long fifth);
-
asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
void __user *ptr, long fifth)
{
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 786ac2b6914..50292cd9c12 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -359,7 +359,9 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
frame.fp = regs->ARM_fp;
frame.sp = regs->ARM_sp;
frame.lr = regs->ARM_lr;
- frame.pc = regs->ARM_pc;
+ /* PC might be corrupted, use LR in that case. */
+ frame.pc = kernel_text_address(regs->ARM_pc)
+ ? regs->ARM_pc : regs->ARM_lr;
} else if (tsk == current) {
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_sp;
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index aaf7220d9e3..a673297b0cf 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -110,13 +110,13 @@ no_frame: ldmfd sp!, {r4 - r8, pc}
ENDPROC(__backtrace)
ENDPROC(c_backtrace)
- .section __ex_table,"a"
+ .pushsection __ex_table,"a"
.align 3
.long 1001b, 1006b
.long 1002b, 1006b
.long 1003b, 1006b
.long 1004b, 1006b
- .previous
+ .popsection
#define instr r4
#define reg r5
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index 1279abd8b88..5e3f99620c0 100644
--- a/arch/arm/lib/clear_user.S
+++ b/arch/arm/lib/clear_user.S
@@ -46,8 +46,8 @@ USER( strnebt r2, [r0])
ldmfd sp!, {r1, pc}
ENDPROC(__clear_user)
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 0
9001: ldmfd sp!, {r0, pc}
- .previous
+ .popsection
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index e4fe124aced..66a477a3e3c 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -90,7 +90,7 @@ ENTRY(__copy_from_user)
ENDPROC(__copy_from_user)
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 0
copy_abort_preamble
ldmfd sp!, {r1, r2}
@@ -100,5 +100,5 @@ ENDPROC(__copy_from_user)
bl __memzero
ldr r0, [sp], #4
copy_abort_end
- .previous
+ .popsection
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 1a71e158444..027b69bdbad 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -94,12 +94,12 @@ WEAK(__copy_to_user)
ENDPROC(__copy_to_user)
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 0
copy_abort_preamble
ldmfd sp!, {r1, r2, r3}
sub r0, r0, r1
rsb r0, r0, r2
copy_abort_end
- .previous
+ .popsection
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index fd0e9dcd9fd..59ff6fdc1e6 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -68,7 +68,7 @@
* so properly, we would have to add in whatever registers were loaded before
* the fault, which, with the current asm above is not predictable.
*/
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 4
9001: mov r4, #-EFAULT
ldr r5, [fp, #4] @ *err_ptr
@@ -80,4 +80,4 @@
strneb r0, [r1], #1
bne 9002b
load_regs
- .previous
+ .popsection
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index a1814d92712..b1631a7dbe7 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -64,9 +64,9 @@ __get_user_bad:
mov pc, lr
ENDPROC(__get_user_bad)
-.section __ex_table, "a"
+.pushsection __ex_table, "a"
.long 1b, __get_user_bad
.long 2b, __get_user_bad
.long 3b, __get_user_bad
.long 4b, __get_user_bad
-.previous
+.popsection
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index 5025c863713..938fc14f962 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -74,7 +74,7 @@ ENTRY(memmove)
rsb ip, ip, #32
addne pc, pc, ip @ C is always clear here
b 7f
-6: nop
+6: W(nop)
W(ldr) r3, [r1, #-4]!
W(ldr) r4, [r1, #-4]!
W(ldr) r5, [r1, #-4]!
@@ -85,7 +85,7 @@ ENTRY(memmove)
add pc, pc, ip
nop
- nop
+ W(nop)
W(str) r3, [r0, #-4]!
W(str) r4, [r0, #-4]!
W(str) r5, [r0, #-4]!
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 02fedbf07c0..5a01a23c6c0 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -81,11 +81,11 @@ __put_user_bad:
mov pc, lr
ENDPROC(__put_user_bad)
-.section __ex_table, "a"
+.pushsection __ex_table, "a"
.long 1b, __put_user_bad
.long 2b, __put_user_bad
.long 3b, __put_user_bad
.long 4b, __put_user_bad
.long 5b, __put_user_bad
.long 6b, __put_user_bad
-.previous
+.popsection
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S
index 1c9814f346c..f202d7bd164 100644
--- a/arch/arm/lib/strncpy_from_user.S
+++ b/arch/arm/lib/strncpy_from_user.S
@@ -33,11 +33,11 @@ ENTRY(__strncpy_from_user)
mov pc, lr
ENDPROC(__strncpy_from_user)
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 0
9001: mov r3, #0
strb r3, [r0, #0] @ null terminate
mov r0, #-EFAULT
mov pc, lr
- .previous
+ .popsection
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S
index 7855b290665..0ecbb459c4f 100644
--- a/arch/arm/lib/strnlen_user.S
+++ b/arch/arm/lib/strnlen_user.S
@@ -33,8 +33,8 @@ ENTRY(__strnlen_user)
mov pc, lr
ENDPROC(__strnlen_user)
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 0
9001: mov r0, #0
mov pc, lr
- .previous
+ .popsection
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index ffdd27498ce..fee9f6f88ad 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -279,10 +279,10 @@ USER( strgtbt r3, [r0], #1) @ May fault
b .Lc2u_finished
ENDPROC(__copy_to_user)
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 0
9001: ldmfd sp!, {r0, r4 - r7, pc}
- .previous
+ .popsection
/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
* Purpose : copy a block from user memory to kernel memory
@@ -545,7 +545,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
b .Lcfu_finished
ENDPROC(__copy_from_user)
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 0
/*
* We took an exception. r0 contains a pointer to
@@ -559,5 +559,5 @@ ENDPROC(__copy_from_user)
blne __memzero
mov r0, r4
ldmfd sp!, {r4 - r7, pc}
- .previous
+ .popsection
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index 6b967ffb655..e2d2f2cd0c4 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -16,6 +16,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/hardirq.h> /* for in_atomic() */
+#include <linux/gfp.h>
#include <asm/current.h>
#include <asm/page.h>
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index b5c5fc6ba3a..3ef68330452 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -20,6 +20,7 @@
#include <linux/timex.h>
#include <linux/signal.h>
#include <linux/clk.h>
+#include <linux/gfp.h>
#include <mach/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 027dd570dcc..d4004557532 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_d
obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
- obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index 309f3511aa2..2500f41d8d2 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -58,6 +58,12 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
{
u32 sr = at91_sys_read(AT91_ST_SR) & irqmask;
+ /*
+ * irqs should be disabled here, but as the irq is shared they are only
+ * guaranteed to be off if the timer irq is registered first.
+ */
+ WARN_ON_ONCE(!irqs_disabled());
+
/* simulate "oneshot" timer with alarm */
if (sr & AT91_ST_ALMS) {
clkevt.event_handler(&clkevt);
@@ -132,24 +138,11 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
static int
clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
{
- unsigned long flags;
u32 alm;
int status = 0;
BUG_ON(delta < 2);
- /* Use "raw" primitives so we behave correctly on RT kernels. */
- raw_local_irq_save(flags);
-
- /*
- * According to Thomas Gleixner irqs are already disabled here. Simply
- * removing raw_local_irq_save above (and the matching
- * raw_local_irq_restore) was not accepted. See
- * http://thread.gmane.org/gmane.linux.ports.arm.kernel/41174
- * So for now (2008-11-20) just warn once if irqs were not disabled ...
- */
- WARN_ON_ONCE(!raw_irqs_disabled_flags(flags));
-
/* The alarm IRQ uses absolute time (now+delta), not the relative
* time (delta) in our calling convention. Like all clockevents
* using such "match" hardware, we have a race to defend against.
@@ -169,7 +162,6 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
alm += delta;
at91_sys_write(AT91_ST_RTAR, alm);
- raw_local_irq_restore(flags);
return status;
}
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 4bd56aee437..608a63240b6 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -62,16 +62,12 @@ static struct clocksource pit_clk = {
static void
pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
- unsigned long flags;
-
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
- /* update clocksource counter, then enable the IRQ */
- raw_local_irq_save(flags);
+ /* update clocksource counter */
pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
| AT91_PIT_PITIEN);
- raw_local_irq_restore(flags);
break;
case CLOCK_EVT_MODE_ONESHOT:
BUG();
@@ -100,6 +96,11 @@ static struct clock_event_device pit_clkevt = {
*/
static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
{
+ /*
+ * irqs should be disabled here, but as the irq is shared they are only
+ * guaranteed to be off if the timer irq is registered first.
+ */
+ WARN_ON_ONCE(!irqs_disabled());
/* The PIT interrupt may be disabled, and is shared */
if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC)
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index 29cf8317748..c11fd47aec5 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -271,10 +271,12 @@ static void __init ek_add_device_buttons(void) {}
static struct i2c_board_info __initdata ek_i2c_devices[] = {
- {
- I2C_BOARD_INFO("24c512", 0x50),
- I2C_BOARD_INFO("wm8731", 0x1b),
- },
+ {
+ I2C_BOARD_INFO("24c512", 0x50)
+ },
+ {
+ I2C_BOARD_INFO("wm8731", 0x1b)
+ },
};
diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h
index 550d503a1bc..57f8ee15494 100644
--- a/arch/arm/mach-at91/include/mach/at91_mci.h
+++ b/arch/arm/mach-at91/include/mach/at91_mci.h
@@ -77,7 +77,7 @@
#define AT91_MCI_BLKR 0x18 /* Block Register */
#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */
-#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block lenght */
+#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block length */
#define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */
#define AT91_MCR_RDR 0x30 /* Receive Data Register */
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index 987fab3d846..9c5b48e68a7 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -175,8 +175,6 @@ ENTRY(at91_slow_clock)
orr r3, r3, #(1 << 29) /* bit 29 always set */
str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
- wait_pllalock
-
/* Save PLLB setting and disable it */
ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
str r3, .saved_pllbr
@@ -184,8 +182,6 @@ ENTRY(at91_slow_clock)
mov r3, #AT91_PMC_PLLCOUNT
str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
- wait_pllblock
-
/* Turn off the main oscillator */
ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
bic r3, r3, #AT91_PMC_MOSCEN
@@ -205,13 +201,25 @@ ENTRY(at91_slow_clock)
ldr r3, .saved_pllbr
str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+ tst r3, #(AT91_PMC_MUL & 0xff0000)
+ bne 1f
+ tst r3, #(AT91_PMC_MUL & ~0xff0000)
+ beq 2f
+1:
wait_pllblock
+2:
/* Restore PLLA setting */
ldr r3, .saved_pllar
str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+ tst r3, #(AT91_PMC_MUL & 0xff0000)
+ bne 3f
+ tst r3, #(AT91_PMC_MUL & ~0xff0000)
+ beq 4f
+3:
wait_pllalock
+4:
#ifdef SLOWDOWN_MASTER_CLOCK
/*
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c
index 7b20fccb9d4..29c0a911df2 100644
--- a/arch/arm/mach-bcmring/dma.c
+++ b/arch/arm/mach-bcmring/dma.c
@@ -28,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <mach/timer.h>
@@ -2220,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_ring);
int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
int dirtied /* non-zero if any of the pages were modified */
) {
+
+ int rc = 0;
int regionIdx;
int segmentIdx;
DMA_Region_t *region;
DMA_Segment_t *segment;
+ down(&memMap->lock);
+
for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
region = &memMap->region[regionIdx];
@@ -2238,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
printk(KERN_ERR
"%s: vmalloc'd pages are not yet supported\n",
__func__);
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
case DMA_MEM_TYPE_KMALLOC:
@@ -2275,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
printk(KERN_ERR
"%s: Unsupported memory type: %d\n",
__func__, region->memType);
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
}
@@ -2313,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
memMap->numRegionsUsed = 0;
memMap->inUse = 0;
+out:
up(&memMap->lock);
- return 0;
+ return rc;
}
EXPORT_SYMBOL(dma_unmap);
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index d15beceb632..df4ab210586 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -22,6 +22,7 @@
#include <linux/leds.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
#include <linux/mtd/nand.h>
#include <linux/input.h>
#include <linux/spi/spi.h>
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 27772e18e45..0d6ee583f65 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -758,7 +758,6 @@ static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
[IRQ_MMCINT] = 7,
[IRQ_DM365_MMCINT1] = 7,
[IRQ_DM365_PWMINT3] = 7,
- [IRQ_DDRINT] = 4,
[IRQ_AEMIFINT] = 2,
[IRQ_DM365_SDIOINT1] = 2,
[IRQ_TINT0_TINT12] = 7,
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 15dd886df04..53137387aee 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/edma.h>
@@ -1266,7 +1267,8 @@ int edma_start(unsigned channel)
/* EDMA channel with event association */
pr_debug("EDMA: ER%d %08x\n", j,
edma_shadow0_read_array(ctlr, SH_ER, j));
- /* Clear any pending error */
+ /* Clear any pending event or error */
+ edma_write_array(ctlr, EDMA_ECR, j, mask);
edma_write_array(ctlr, EDMA_EMCR, j, mask);
/* Clear any SER */
edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index cc9be7fee62..03acfd39042 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -3,7 +3,7 @@
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
- * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * 2007, 2009-2010 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
@@ -13,7 +13,9 @@
#include <video/da8xx-fb.h>
+#include <linux/platform_device.h>
#include <linux/davinci_emac.h>
+
#include <mach/serial.h>
#include <mach/edma.h>
#include <mach/i2c.h>
@@ -144,6 +146,10 @@ extern const short da850_mmcsd0_pins[];
extern const short da850_nand_pins[];
extern const short da850_nor_pins[];
+#ifdef CONFIG_DAVINCI_MUX
int da8xx_pinmux_setup(const short pins[]);
+#else
+static inline int da8xx_pinmux_setup(const short pins[]) { return 0; }
+#endif
#endif /* __ASM_ARCH_DAVINCI_DA8XX_H */
diff --git a/arch/arm/mach-davinci/include/mach/i2c.h b/arch/arm/mach-davinci/include/mach/i2c.h
index 39fdceac841..2312d197dfb 100644
--- a/arch/arm/mach-davinci/include/mach/i2c.h
+++ b/arch/arm/mach-davinci/include/mach/i2c.h
@@ -1,5 +1,5 @@
/*
- * DaVinci I2C controller platfrom_device info
+ * DaVinci I2C controller platform_device info
*
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
*
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 42d985beece..9e0b106b4f5 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -253,8 +253,6 @@ static void __init timer_init(void)
irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq;
setup_irq(irq, &t->irqaction);
}
-
- timer32_config(&timers[i]);
}
}
@@ -331,6 +329,7 @@ static void __init davinci_timer_init(void)
unsigned int clocksource_id;
static char err[] __initdata = KERN_ERR
"%s: can't register clocksource!\n";
+ int i;
clockevent_id = soc_info->timer_info->clockevent_id;
clocksource_id = soc_info->timer_info->clocksource_id;
@@ -389,6 +388,9 @@ static void __init davinci_timer_init(void)
clockevent_davinci.cpumask = cpumask_of(0);
clockevents_register_device(&clockevent_davinci);
+
+ for (i=0; i< ARRAY_SIZE(timers); i++)
+ timer32_config(&timers[i]);
}
struct sys_timer davinci_timer = {
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index 806972a68c8..5da2cf402c8 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -605,7 +605,7 @@ static struct platform_device dove_xor00_channel = {
.dev = {
.dma_mask = &dove_xor0_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&dove_xor00_data,
+ .platform_data = &dove_xor00_data,
},
};
@@ -631,7 +631,7 @@ static struct platform_device dove_xor01_channel = {
.dev = {
.dma_mask = &dove_xor0_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&dove_xor01_data,
+ .platform_data = &dove_xor01_data,
},
};
@@ -704,7 +704,7 @@ static struct platform_device dove_xor10_channel = {
.dev = {
.dma_mask = &dove_xor1_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&dove_xor10_data,
+ .platform_data = &dove_xor10_data,
},
};
@@ -730,7 +730,7 @@ static struct platform_device dove_xor11_channel = {
.dev = {
.dma_mask = &dove_xor1_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&dove_xor11_data,
+ .platform_data = &dove_xor11_data,
},
};
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index cc377ae8c42..cf547ad7ebd 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -25,7 +25,7 @@
#include <mach/hardware.h>
/*************************************************************************
- * GPIO handling for EP93xx
+ * Interrupt handling for EP93xx on-chip GPIOs
*************************************************************************/
static unsigned char gpio_int_unmasked[3];
static unsigned char gpio_int_enabled[3];
@@ -40,7 +40,7 @@ static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
-void ep93xx_gpio_update_int_params(unsigned port)
+static void ep93xx_gpio_update_int_params(unsigned port)
{
BUG_ON(port > 2);
@@ -56,7 +56,7 @@ void ep93xx_gpio_update_int_params(unsigned port)
EP93XX_GPIO_REG(int_en_register_offset[port]));
}
-void ep93xx_gpio_int_mask(unsigned line)
+static inline void ep93xx_gpio_int_mask(unsigned line)
{
gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
}
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
index 3bd934e9a7f..93107d88ff3 100644
--- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -65,6 +65,8 @@
#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
#define TS72XX_RTC_DATA_SIZE 0x00001000
+#define TS72XX_WDT_CONTROL_PHYS_BASE 0x23800000
+#define TS72XX_WDT_FEED_PHYS_BASE 0x23c00000
#ifndef __ASSEMBLY__
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index f3757a1c5a1..c33360e8286 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -28,7 +28,7 @@
*
* Micro9-High has up to 64MB of 32-bit flash on CS1
* Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1
- * Micro9-Lite uses a seperate MTD map driver for flash support
+ * 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;
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 259f7822ba5..fac1ec7a60f 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -166,6 +166,26 @@ static struct platform_device ts72xx_rtc_device = {
.num_resources = 0,
};
+static struct resource ts72xx_wdt_resources[] = {
+ {
+ .start = TS72XX_WDT_CONTROL_PHYS_BASE,
+ .end = TS72XX_WDT_CONTROL_PHYS_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = TS72XX_WDT_FEED_PHYS_BASE,
+ .end = TS72XX_WDT_FEED_PHYS_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ts72xx_wdt_device = {
+ .name = "ts72xx-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ts72xx_wdt_resources),
+ .resource = ts72xx_wdt_resources,
+};
+
static struct ep93xx_eth_data ts72xx_eth_data = {
.phy_id = 1,
};
@@ -175,6 +195,7 @@ static void __init ts72xx_init_machine(void)
ep93xx_init_devices();
ts72xx_register_flash();
platform_device_register(&ts72xx_rtc_device);
+ platform_device_register(&ts72xx_wdt_device);
ep93xx_register_eth(&ts72xx_eth_data, 1);
}
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index 7a261482821..bdb3f670680 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -14,7 +14,6 @@
*/
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/mman.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
index 44d4c2e8207..f77f2025504 100644
--- a/arch/arm/mach-integrator/cpu.c
+++ b/arch/arm/mach-integrator/cpu.c
@@ -13,7 +13,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/cpufreq.h>
-#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 0058c937719..41b10725cef 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -21,6 +21,7 @@
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 66ef86d6d9e..15e6cc5a352 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -13,7 +13,6 @@
#include <linux/list.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sysdev.h>
#include <linux/amba/bus.h>
@@ -21,6 +20,7 @@
#include <linux/amba/clcd.h>
#include <linux/amba/mmci.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 148d25fc636..ffbd349363a 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -22,7 +22,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 4873f26a42e..6d5a90813d3 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -18,6 +18,7 @@
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
index 93370a46b62..10384fc37cb 100644
--- a/arch/arm/mach-iop32x/glantank.c
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -19,7 +19,6 @@
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/mtd/physmap.h>
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
index a7a08dda7f3..d6ac85ff109 100644
--- a/arch/arm/mach-iop32x/iq31244.c
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -21,7 +21,6 @@
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/mtd/physmap.h>
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
index 0200f80c1e1..c6a0e4ee9d9 100644
--- a/arch/arm/mach-iop32x/iq80321.c
+++ b/arch/arm/mach-iop32x/iq80321.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/mtd/physmap.h>
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index 2a5c637639b..5d99039286e 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -23,7 +23,6 @@
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/mtd/physmap.h>
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c
index 394e95a30b7..c6ff5523b38 100644
--- a/arch/arm/mach-iop33x/iq80331.c
+++ b/arch/arm/mach-iop33x/iq80331.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/mtd/physmap.h>
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c
index a40badf126c..fbf55140939 100644
--- a/arch/arm/mach-iop33x/iq80332.c
+++ b/arch/arm/mach-iop33x/iq80332.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/mtd/physmap.h>
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index c84dfac1388..1a557e0d055 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -26,7 +26,6 @@
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/serial.h>
#include <linux/tty.h>
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
index 4467c4224d7..55e5c69352a 100644
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -23,7 +23,6 @@
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index 94f68ba9ea5..237b61a85e9 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -23,7 +23,6 @@
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 30451300751..91fffb9b208 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -23,7 +23,6 @@
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 4a12327a09a..0369ec4242a 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -23,7 +23,6 @@
#include <linux/bitops.h>
#include <linux/pci.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/serial.h>
#include <linux/tty.h>
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 60e9fd08ab8..90771cad06f 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -22,7 +22,6 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
diff --git a/arch/arm/mach-ixp23xx/include/mach/memory.h b/arch/arm/mach-ixp23xx/include/mach/memory.h
index 94a3a86cfeb..6ef65d813f1 100644
--- a/arch/arm/mach-ixp23xx/include/mach/memory.h
+++ b/arch/arm/mach-ixp23xx/include/mach/memory.h
@@ -19,7 +19,7 @@
*/
#define PHYS_OFFSET (0x00000000)
-#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0))
+#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)
#define __phys_to_bus(x) ((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
#define __bus_to_phys(x) ((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index 59022becb13..4b0e598a91c 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -23,7 +23,6 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c
index 6e558a76457..d8bc86d76f1 100644
--- a/arch/arm/mach-ixp4xx/avila-setup.c
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
@@ -17,7 +17,6 @@
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
-#include <linux/slab.h>
#include <linux/i2c-gpio.h>
#include <asm/types.h>
#include <asm/setup.h>
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index c4a01594c76..e3181534c7f 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -502,32 +502,6 @@ struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
}
-/*
- * We override these so we properly do dmabounce otherwise drivers
- * are able to set the dma_mask to 0xffffffff and we can no longer
- * trap bounces. :(
- *
- * We just return true on everyhing except for < 64MB in which case
- * we will fail miseralby and die since we can't handle that case.
- */
-int
-pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (mask >= SZ_64M - 1 )
- return 0;
-
- return -EIO;
-}
-
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (mask >= SZ_64M - 1 )
- return 0;
-
- return -EIO;
-}
-
EXPORT_SYMBOL(ixp4xx_pci_read);
EXPORT_SYMBOL(ixp4xx_pci_write);
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 25bf5ad770e..31a47f6a893 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -14,7 +14,6 @@
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
-#include <linux/slab.h>
#include <asm/types.h>
#include <asm/setup.h>
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
index 59b73a0ddfa..2583b2a1317 100644
--- a/arch/arm/mach-ixp4xx/gateway7001-setup.c
+++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c
@@ -17,7 +17,6 @@
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
-#include <linux/slab.h>
#include <asm/types.h>
#include <asm/setup.h>
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
index 0bc7185cb6f..c67586b7940 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -27,7 +27,6 @@
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
-#include <linux/slab.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h
index f9d1c43e4a5..f91ca6d4fbe 100644
--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h
+++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h
@@ -26,11 +26,6 @@
#define PCIBIOS_MAX_MEM 0x4BFFFFFF
#endif
-/*
- * We override the standard dma-mask routines for bouncing.
- */
-#define HAVE_ARCH_PCI_SET_DMA_MASK
-
#define pcibios_assign_all_busses() 1
/* Register locations and bits */
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index bbb76898884..827cbc4402f 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -14,7 +14,6 @@
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
-#include <linux/slab.h>
#include <linux/i2c-gpio.h>
#include <linux/io.h>
#include <linux/mtd/mtd.h>
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
index e8bb2577816..a17ed79207a 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c
+++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
@@ -20,7 +20,6 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <mach/npe.h>
#define DEBUG_MSG 0
diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c
index 7ea782021d1..4dd74863daa 100644
--- a/arch/arm/mach-ixp4xx/wg302v2-setup.c
+++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c
@@ -18,7 +18,6 @@
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
-#include <linux/slab.h>
#include <asm/types.h>
#include <asm/setup.h>
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index f6c6196a51f..17879a876be 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -32,6 +32,12 @@ config MACH_SHEEVAPLUG
Say 'Y' here if you want your kernel to support the
Marvell SheevaPlug Reference Board.
+config MACH_ESATA_SHEEVAPLUG
+ bool "Marvell eSATA SheevaPlug Reference Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell eSATA SheevaPlug Reference Board.
+
config MACH_TS219
bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS"
help
@@ -46,18 +52,35 @@ config MACH_TS41X
QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
devices.
+config MACH_OPENRD
+ bool
+
config MACH_OPENRD_BASE
bool "Marvell OpenRD Base Board"
+ select MACH_OPENRD
help
Say 'Y' here if you want your kernel to support the
Marvell OpenRD Base Board.
+config MACH_OPENRD_CLIENT
+ bool "Marvell OpenRD Client Board"
+ select MACH_OPENRD
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell OpenRD Client Board.
+
config MACH_NETSPACE_V2
bool "LaCie Network Space v2 NAS Board"
help
Say 'Y' here if you want your kernel to support the
LaCie Network Space v2 NAS.
+config MACH_INETSPACE_V2
+ bool "LaCie Internet Space v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie Internet Space v2 NAS.
+
endmenu
endif
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index d4d7f53b0fb..a5530e36ba3 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -5,9 +5,11 @@ obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o
obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o
obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o
obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
+obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o
obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o
obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o
-obj-$(CONFIG_MACH_OPENRD_BASE) += openrd_base-setup.o
+obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o
obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o
+obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 242dd077534..f759ca24392 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -656,7 +656,7 @@ static struct platform_device kirkwood_xor00_channel = {
.dev = {
.dma_mask = &kirkwood_xor_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&kirkwood_xor00_data,
+ .platform_data = &kirkwood_xor00_data,
},
};
@@ -682,7 +682,7 @@ static struct platform_device kirkwood_xor01_channel = {
.dev = {
.dma_mask = &kirkwood_xor_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&kirkwood_xor01_data,
+ .platform_data = &kirkwood_xor01_data,
},
};
@@ -755,7 +755,7 @@ static struct platform_device kirkwood_xor10_channel = {
.dev = {
.dma_mask = &kirkwood_xor_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&kirkwood_xor10_data,
+ .platform_data = &kirkwood_xor10_data,
},
};
@@ -781,7 +781,7 @@ static struct platform_device kirkwood_xor11_channel = {
.dev = {
.dma_mask = &kirkwood_xor_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&kirkwood_xor11_data,
+ .platform_data = &kirkwood_xor11_data,
},
};
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
index 0358f45766c..5e6f711b1c6 100644
--- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -74,9 +74,9 @@ static struct gpio_keys_button mv88f6281gtw_ge_button_pins[] = {
.desc = "SWR Button",
.active_low = 1,
}, {
- .code = KEY_F1,
+ .code = KEY_WPS_BUTTON,
.gpio = 46,
- .desc = "WPS Button(F1)",
+ .desc = "WPS Button",
.active_low = 1,
},
};
diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c
index 9a064065beb..3ae158d7268 100644
--- a/arch/arm/mach-kirkwood/netspace_v2-setup.c
+++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c
@@ -182,8 +182,14 @@ static struct platform_device netspace_v2_gpio_buttons = {
static struct gpio_led netspace_v2_gpio_led_pins[] = {
{
- .name = "ns_v2:red:fail",
- .gpio = NETSPACE_V2_GPIO_RED_LED,
+ .name = "ns_v2:blue:sata",
+ .default_trigger = "default-on",
+ .gpio = NETSPACE_V2_GPIO_BLUE_LED_CMD,
+ .active_low = 1,
+ },
+ {
+ .name = "ns_v2:red:fail",
+ .gpio = NETSPACE_V2_GPIO_RED_LED,
},
};
@@ -202,30 +208,19 @@ static struct platform_device netspace_v2_gpio_leds = {
static void __init netspace_v2_gpio_leds_init(void)
{
- platform_device_register(&netspace_v2_gpio_leds);
+ int err;
- /*
- * Configure the front blue LED to blink in relation with the SATA
- * activity.
- */
- if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_SLOW,
- "SATA blue LED slow") != 0)
- return;
- if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_SLOW, 0) != 0)
- goto err_free_1;
- if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_CMD,
- "SATA blue LED command") != 0)
- goto err_free_1;
- if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_CMD, 0) != 0)
- goto err_free_2;
-
- return;
-
-err_free_2:
- gpio_free(NETSPACE_V2_GPIO_BLUE_LED_CMD);
-err_free_1:
- gpio_free(NETSPACE_V2_GPIO_BLUE_LED_SLOW);
- pr_err("netspace_v2: failed to configure SATA blue LED\n");
+ /* Configure register slow_led to allow SATA activity LED blinking */
+ err = gpio_request(NETSPACE_V2_GPIO_BLUE_LED_SLOW, "blue LED slow");
+ if (err == 0) {
+ err = gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_SLOW, 0);
+ if (err)
+ gpio_free(NETSPACE_V2_GPIO_BLUE_LED_SLOW);
+ }
+ if (err)
+ pr_err("netspace_v2: failed to configure blue LED slow GPIO\n");
+
+ platform_device_register(&netspace_v2_gpio_leds);
}
/*****************************************************************************
@@ -314,6 +309,7 @@ static void __init netspace_v2_init(void)
pr_err("netspace_v2: failed to configure power-off GPIO\n");
}
+#ifdef CONFIG_MACH_NETSPACE_V2
MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
.phys_io = KIRKWOOD_REGS_PHYS_BASE,
.io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
@@ -323,3 +319,16 @@ MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
.init_irq = kirkwood_init_irq,
.timer = &netspace_v2_timer,
MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_INETSPACE_V2
+MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2")
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = netspace_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &netspace_v2_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
new file mode 100644
index 00000000000..ad3f1ec3379
--- /dev/null
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/mach-kirkwood/openrd-setup.c
+ *
+ * Marvell OpenRD (Base|Client) Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition openrd_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data openrd_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data openrd_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(24),
+};
+
+static struct mv_sata_platform_data openrd_sata_data = {
+ .n_ports = 2,
+};
+
+static struct mvsdio_platform_data openrd_mvsdio_data = {
+ .gpio_card_detect = 29, /* MPP29 used as SD card detect */
+};
+
+static unsigned int openrd_mpp_config[] __initdata = {
+ MPP29_GPIO,
+ 0
+};
+
+static void __init openrd_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(openrd_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_nand_init(ARRAY_AND_SIZE(openrd_nand_parts), 25);
+
+ kirkwood_ehci_init();
+
+ kirkwood_ge00_init(&openrd_ge00_data);
+ if (machine_is_openrd_client())
+ kirkwood_ge01_init(&openrd_ge01_data);
+ kirkwood_sata_init(&openrd_sata_data);
+ kirkwood_sdio_init(&openrd_mvsdio_data);
+
+ kirkwood_i2c_init();
+}
+
+static int __init openrd_pci_init(void)
+{
+ if (machine_is_openrd_base() || machine_is_openrd_client())
+ kirkwood_pcie_init();
+
+ return 0;
+}
+subsys_initcall(openrd_pci_init);
+
+#ifdef CONFIG_MACH_OPENRD_BASE
+MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
+ /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = openrd_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_OPENRD_CLIENT
+MACHINE_START(OPENRD_CLIENT, "Marvell OpenRD Client Board")
+ /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = openrd_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-kirkwood/openrd_base-setup.c b/arch/arm/mach-kirkwood/openrd_base-setup.c
deleted file mode 100644
index 77617c72229..00000000000
--- a/arch/arm/mach-kirkwood/openrd_base-setup.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/openrd_base-setup.c
- *
- * Marvell OpenRD Base Board Setup
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/partitions.h>
-#include <linux/ata_platform.h>
-#include <linux/mv643xx_eth.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
-#include <plat/mvsdio.h>
-#include "common.h"
-#include "mpp.h"
-
-static struct mtd_partition openrd_base_nand_parts[] = {
- {
- .name = "u-boot",
- .offset = 0,
- .size = SZ_1M
- }, {
- .name = "uImage",
- .offset = MTDPART_OFS_NXTBLK,
- .size = SZ_4M
- }, {
- .name = "root",
- .offset = MTDPART_OFS_NXTBLK,
- .size = MTDPART_SIZ_FULL
- },
-};
-
-static struct mv643xx_eth_platform_data openrd_base_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
-static struct mv_sata_platform_data openrd_base_sata_data = {
- .n_ports = 2,
-};
-
-static struct mvsdio_platform_data openrd_base_mvsdio_data = {
- .gpio_card_detect = 29, /* MPP29 used as SD card detect */
-};
-
-static unsigned int openrd_base_mpp_config[] __initdata = {
- MPP29_GPIO,
- 0
-};
-
-static void __init openrd_base_init(void)
-{
- /*
- * Basic setup. Needs to be called early.
- */
- kirkwood_init();
- kirkwood_mpp_conf(openrd_base_mpp_config);
-
- kirkwood_uart0_init();
- kirkwood_nand_init(ARRAY_AND_SIZE(openrd_base_nand_parts), 25);
-
- kirkwood_ehci_init();
-
- kirkwood_ge00_init(&openrd_base_ge00_data);
- kirkwood_sata_init(&openrd_base_sata_data);
- kirkwood_sdio_init(&openrd_base_mvsdio_data);
-
- kirkwood_i2c_init();
-}
-
-static int __init openrd_base_pci_init(void)
-{
- if (machine_is_openrd_base())
- kirkwood_pcie_init();
-
- return 0;
- }
-subsys_initcall(openrd_base_pci_init);
-
-
-MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
- /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
- .phys_io = KIRKWOOD_REGS_PHYS_BASE,
- .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
- .boot_params = 0x00000100,
- .init_machine = openrd_base_init,
- .map_io = kirkwood_map_io,
- .init_irq = kirkwood_init_irq,
- .timer = &kirkwood_timer,
-MACHINE_END
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index a604b2a701a..dee1eff50d3 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/mbus.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c
index c7319eeac8b..a00879d34d5 100644
--- a/arch/arm/mach-kirkwood/sheevaplug-setup.c
+++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
#include <linux/mtd/partitions.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
@@ -42,10 +43,19 @@ static struct mv643xx_eth_platform_data sheevaplug_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
};
+static struct mv_sata_platform_data sheeva_esata_sata_data = {
+ .n_ports = 2,
+};
+
static struct mvsdio_platform_data sheevaplug_mvsdio_data = {
/* unfortunately the CD signal has not been connected */
};
+static struct mvsdio_platform_data sheeva_esata_mvsdio_data = {
+ .gpio_write_protect = 44, /* MPP44 used as SD write protect */
+ .gpio_card_detect = 47, /* MPP47 used as SD card detect */
+};
+
static struct gpio_led sheevaplug_led_pins[] = {
{
.name = "plug:green:health",
@@ -74,13 +84,26 @@ static unsigned int sheevaplug_mpp_config[] __initdata = {
0
};
+static unsigned int sheeva_esata_mpp_config[] __initdata = {
+ MPP29_GPIO, /* USB Power Enable */
+ MPP44_GPIO, /* SD Write Protect */
+ MPP47_GPIO, /* SD Card Detect */
+ MPP49_GPIO, /* LED Green */
+ 0
+};
+
static void __init sheevaplug_init(void)
{
/*
* Basic setup. Needs to be called early.
*/
kirkwood_init();
- kirkwood_mpp_conf(sheevaplug_mpp_config);
+
+ /* setup gpio pin select */
+ if (machine_is_sheeva_esata())
+ kirkwood_mpp_conf(sheeva_esata_mpp_config);
+ else
+ kirkwood_mpp_conf(sheevaplug_mpp_config);
kirkwood_uart0_init();
kirkwood_nand_init(ARRAY_AND_SIZE(sheevaplug_nand_parts), 25);
@@ -91,11 +114,21 @@ static void __init sheevaplug_init(void)
kirkwood_ehci_init();
kirkwood_ge00_init(&sheevaplug_ge00_data);
- kirkwood_sdio_init(&sheevaplug_mvsdio_data);
+
+ /* honor lower power consumption for plugs with out eSATA */
+ if (machine_is_sheeva_esata())
+ kirkwood_sata_init(&sheeva_esata_sata_data);
+
+ /* enable sd wp and sd cd on plugs with esata */
+ if (machine_is_sheeva_esata())
+ kirkwood_sdio_init(&sheeva_esata_mvsdio_data);
+ else
+ kirkwood_sdio_init(&sheevaplug_mvsdio_data);
platform_device_register(&sheevaplug_leds);
}
+#ifdef CONFIG_MACH_SHEEVAPLUG
MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")
/* Maintainer: shadi Ammouri <shadi@marvell.com> */
.phys_io = KIRKWOOD_REGS_PHYS_BASE,
@@ -106,3 +139,16 @@ MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")
.init_irq = kirkwood_init_irq,
.timer = &kirkwood_timer,
MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_ESATA_SHEEVAPLUG
+MACHINE_START(ESATA_SHEEVAPLUG, "Marvell eSATA SheevaPlug Reference Board")
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = sheevaplug_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-lh7a40x/clcd.c b/arch/arm/mach-lh7a40x/clcd.c
index c472b9e8b37..7fe4fd347c8 100644
--- a/arch/arm/mach-lh7a40x/clcd.c
+++ b/arch/arm/mach-lh7a40x/clcd.c
@@ -10,6 +10,7 @@
*/
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/sysdev.h>
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index c6a564fc4a7..6ab843eaa35 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -1,6 +1,6 @@
if ARCH_MMP
-menu "Marvell PXA168/910 Implmentations"
+menu "Marvell PXA168/910/MMP2 Implmentations"
config MACH_ASPENITE
bool "Marvell's PXA168 Aspenite Development Board"
@@ -16,6 +16,13 @@ config MACH_ZYLONITE2
Say 'Y' here if you want to support the Marvell PXA168-based
Zylonite2 Development Board.
+config MACH_AVENGERS_LITE
+ bool "Marvell's PXA168 Avengers Lite Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Avengers Lite Development Board.
+
config MACH_TAVOREVB
bool "Marvell's PXA910 TavorEVB Development Board"
select CPU_PXA910
@@ -30,6 +37,26 @@ config MACH_TTC_DKB
Say 'Y' here if you want to support the Marvell PXA910-based
TTC_DKB Development Board.
+config MACH_FLINT
+ bool "Marvell's Flint Development Platform"
+ select CPU_MMP2
+ help
+ Say 'Y' here if you want to support the Marvell MMP2-based
+ Flint Development Platform.
+ MMP2-based board can't be co-existed with PXA168-based &
+ PXA910-based development board. Since MMP2 is compatible to
+ ARMv6 architecture.
+
+config MACH_MARVELL_JASPER
+ bool "Marvell's Jasper Development Platform"
+ select CPU_MMP2
+ help
+ Say 'Y' here if you want to support the Marvell MMP2-base
+ Jasper Development Platform.
+ MMP2-based board can't be co-existed with PXA168-based &
+ PXA910-based development board. Since MMP2 is compatible to
+ ARMv6 architecture.
+
endmenu
config CPU_PXA168
@@ -44,4 +71,10 @@ config CPU_PXA910
help
Select code specific to PXA910
+config CPU_MMP2
+ bool
+ select CPU_V6
+ select CPU_32v6K
+ help
+ Select code specific to MMP2. MMP2 is ARMv6 compatible.
endif
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 6883e658488..8b66d06739c 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -2,14 +2,18 @@
# Makefile for Marvell's PXA168 processors line
#
-obj-y += common.o clock.o devices.o irq.o time.o
+obj-y += common.o clock.o devices.o time.o
# SoC support
-obj-$(CONFIG_CPU_PXA168) += pxa168.o
-obj-$(CONFIG_CPU_PXA910) += pxa910.o
+obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o
+obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o
+obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o
# board support
obj-$(CONFIG_MACH_ASPENITE) += aspenite.o
obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o
+obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o
obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o
+obj-$(CONFIG_MACH_FLINT) += flint.o
+obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
new file mode 100644
index 00000000000..8c3fa5d14f4
--- /dev/null
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/arm/mach-mmp/avengers_lite.c
+ *
+ * Support for the Marvell PXA168-based Avengers lite Development Platform.
+ *
+ * Copyright (C) 2009-2010 Marvell International 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
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/irqs.h>
+
+
+#include "common.h"
+#include <linux/delay.h>
+
+/* Avengers lite MFP configurations */
+static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
+ /* DEBUG_UART */
+ GPIO88_UART2_TXD,
+ GPIO89_UART2_RXD,
+};
+
+static void __init avengers_lite_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F));
+
+ /* on-chip devices */
+ pxa168_add_uart(2);
+}
+
+MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
+ .phys_io = APB_PHYS_BASE,
+ .boot_params = 0x00000100,
+ .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = avengers_lite_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index c33fbbc4941..b4a0ba05a0f 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -3,11 +3,15 @@
struct sys_timer;
extern void timer_init(int irq);
+extern void mmp2_clear_pmic_int(void);
extern struct sys_timer pxa168_timer;
extern struct sys_timer pxa910_timer;
+extern struct sys_timer mmp2_timer;
extern void __init pxa168_init_irq(void);
extern void __init pxa910_init_irq(void);
+extern void __init mmp2_init_icu(void);
+extern void __init mmp2_init_irq(void);
extern void __init icu_init_irq(void);
extern void __init pxa_map_io(void);
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
new file mode 100644
index 00000000000..4ec7709a346
--- /dev/null
+++ b/arch/arm/mach-mmp/flint.c
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/arm/mach-mmp/flint.c
+ *
+ * Support for the Marvell Flint Development Platform.
+ *
+ * Copyright (C) 2009 Marvell International 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
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-mmp2.h>
+#include <mach/mmp2.h>
+
+#include "common.h"
+
+static unsigned long flint_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO45_UART1_RXD,
+ GPIO46_UART1_TXD,
+
+ /* UART2 */
+ GPIO47_UART2_RXD,
+ GPIO48_UART2_TXD,
+
+ /* SMC */
+ GPIO151_SMC_SCLK,
+ GPIO145_SMC_nCS0,
+ GPIO146_SMC_nCS1,
+ GPIO152_SMC_BE0,
+ GPIO153_SMC_BE1,
+ GPIO154_SMC_IRQ,
+ GPIO113_SMC_RDY,
+
+ /*Ethernet*/
+ GPIO155_GPIO155,
+
+ /* DFI */
+ GPIO168_DFI_D0,
+ GPIO167_DFI_D1,
+ GPIO166_DFI_D2,
+ GPIO165_DFI_D3,
+ GPIO107_DFI_D4,
+ GPIO106_DFI_D5,
+ GPIO105_DFI_D6,
+ GPIO104_DFI_D7,
+ GPIO111_DFI_D8,
+ GPIO164_DFI_D9,
+ GPIO163_DFI_D10,
+ GPIO162_DFI_D11,
+ GPIO161_DFI_D12,
+ GPIO110_DFI_D13,
+ GPIO109_DFI_D14,
+ GPIO108_DFI_D15,
+ GPIO143_ND_nCS0,
+ GPIO144_ND_nCS1,
+ GPIO147_ND_nWE,
+ GPIO148_ND_nRE,
+ GPIO150_ND_ALE,
+ GPIO149_ND_CLE,
+ GPIO112_ND_RDY0,
+ GPIO160_ND_RDY1,
+};
+
+static struct smc91x_platdata flint_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = SMC_CS1_PHYS_BASE + 0x300,
+ .end = SMC_CS1_PHYS_BASE + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(155),
+ .end = gpio_to_irq(155),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &flint_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static void __init flint_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(flint_pin_config));
+
+ /* on-chip devices */
+ mmp2_add_uart(1);
+ mmp2_add_uart(2);
+
+ /* off-chip devices */
+ platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(FLINT, "Flint Development Platform")
+ .phys_io = APB_PHYS_BASE,
+ .boot_params = 0x00000100,
+ .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = mmp2_init_irq,
+ .timer = &mmp2_timer,
+ .init_machine = flint_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h
index 25e797b0908..83b18721d93 100644
--- a/arch/arm/mach-mmp/include/mach/cputype.h
+++ b/arch/arm/mach-mmp/include/mach/cputype.h
@@ -8,6 +8,7 @@
*
* PXA168 A0 0x41159263 0x56158400 0x00A0A333
* PXA910 Y0 0x41159262 0x56158000 0x00F0C910
+ * MMP2 Z0 0x560f5811
*/
#ifdef CONFIG_CPU_PXA168
@@ -24,7 +25,15 @@
# define __cpu_is_pxa910(id) (0)
#endif
+#ifdef CONFIG_CPU_MMP2
+# define __cpu_is_mmp2(id) \
+ ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x58; })
+#else
+# define __cpu_is_mmp2(id) (0)
+#endif
+
#define cpu_is_pxa168() ({ __cpu_is_pxa168(read_cpuid_id()); })
#define cpu_is_pxa910() ({ __cpu_is_pxa910(read_cpuid_id()); })
+#define cpu_is_mmp2() ({ __cpu_is_mmp2(read_cpuid_id()); })
#endif /* __ASM_MACH_CPUTYPE_H */
diff --git a/arch/arm/mach-mmp/include/mach/devices.h b/arch/arm/mach-mmp/include/mach/devices.h
index 24585397217..1fa0a492454 100644
--- a/arch/arm/mach-mmp/include/mach/devices.h
+++ b/arch/arm/mach-mmp/include/mach/devices.h
@@ -34,4 +34,16 @@ struct pxa_device_desc pxa910_device_##_name __initdata = { \
.size = _size, \
.dma = { _dma }, \
};
+
+#define MMP2_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \
+struct pxa_device_desc mmp2_device_##_name __initdata = { \
+ .dev_name = "mmp2-" #_name, \
+ .drv_name = _drv, \
+ .id = _id, \
+ .irq = IRQ_MMP2_##_irq, \
+ .start = _start, \
+ .size = _size, \
+ .dma = { _dma }, \
+}
+
extern int pxa_register_device(struct pxa_device_desc *, void *, size_t);
diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S
index 6d3cd35478b..c42d9d4e892 100644
--- a/arch/arm/mach-mmp/include/mach/entry-macro.S
+++ b/arch/arm/mach-mmp/include/mach/entry-macro.S
@@ -15,7 +15,12 @@
.endm
.macro get_irqnr_preamble, base, tmp
- ldr \base, =ICU_AP_IRQ_SEL_INT_NUM
+ mrc p15, 0, \tmp, c0, c0, 0 @ CPUID
+ and \tmp, \tmp, #0xff00
+ cmp \tmp, #0x5800
+ ldr \base, =ICU_VIRT_BASE
+ addne \base, \base, #0x10c @ PJ1 AP INT SEL register
+ addeq \base, \base, #0x104 @ PJ4 IRQ SEL register
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
index d68871b0f28..02701196ea0 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -113,10 +113,119 @@
#define IRQ_PXA910_AP_PMU 60
#define IRQ_PXA910_SM_INT 63 /* from PinMux */
-#define IRQ_GPIO_START 64
-#define IRQ_GPIO_NUM 128
+/*
+ * Interrupt numbers for MMP2
+ */
+#define IRQ_MMP2_NONE (-1)
+#define IRQ_MMP2_SSP1 0
+#define IRQ_MMP2_SSP2 1
+#define IRQ_MMP2_SSPA1 2
+#define IRQ_MMP2_SSPA2 3
+#define IRQ_MMP2_PMIC_MUX 4 /* PMIC & Charger */
+#define IRQ_MMP2_RTC_MUX 5
+#define IRQ_MMP2_TWSI1 7
+#define IRQ_MMP2_GPU 8
+#define IRQ_MMP2_KEYPAD 9
+#define IRQ_MMP2_ROTARY 10
+#define IRQ_MMP2_TRACKBALL 11
+#define IRQ_MMP2_ONEWIRE 12
+#define IRQ_MMP2_TIMER1 13
+#define IRQ_MMP2_TIMER2 14
+#define IRQ_MMP2_TIMER3 15
+#define IRQ_MMP2_RIPC 16
+#define IRQ_MMP2_TWSI_MUX 17 /* TWSI2 ~ TWSI6 */
+#define IRQ_MMP2_HDMI 19
+#define IRQ_MMP2_SSP3 20
+#define IRQ_MMP2_SSP4 21
+#define IRQ_MMP2_USB_HS1 22
+#define IRQ_MMP2_USB_HS2 23
+#define IRQ_MMP2_UART3 24
+#define IRQ_MMP2_UART1 27
+#define IRQ_MMP2_UART2 28
+#define IRQ_MMP2_MIPI_DSI 29
+#define IRQ_MMP2_CI2 30
+#define IRQ_MMP2_PMU_TIMER1 31
+#define IRQ_MMP2_PMU_TIMER2 32
+#define IRQ_MMP2_PMU_TIMER3 33
+#define IRQ_MMP2_USB_FS 34
+#define IRQ_MMP2_MISC_MUX 35
+#define IRQ_MMP2_WDT1 36
+#define IRQ_MMP2_NAND_DMA 37
+#define IRQ_MMP2_USIM 38
+#define IRQ_MMP2_MMC 39
+#define IRQ_MMP2_WTM 40
+#define IRQ_MMP2_LCD 41
+#define IRQ_MMP2_CI 42
+#define IRQ_MMP2_IRE 43
+#define IRQ_MMP2_USB_OTG 44
+#define IRQ_MMP2_NAND 45
+#define IRQ_MMP2_UART4 46
+#define IRQ_MMP2_DMA_FIQ 47
+#define IRQ_MMP2_DMA_RIQ 48
+#define IRQ_MMP2_GPIO 49
+#define IRQ_MMP2_SSP_MUX 51
+#define IRQ_MMP2_MMC2 52
+#define IRQ_MMP2_MMC3 53
+#define IRQ_MMP2_MMC4 54
+#define IRQ_MMP2_MIPI_HSI 55
+#define IRQ_MMP2_MSP 58
+#define IRQ_MMP2_MIPI_SLIM_DMA 59
+#define IRQ_MMP2_PJ4_FREQ_CHG 60
+#define IRQ_MMP2_MIPI_SLIM 62
+#define IRQ_MMP2_SM 63
+
+#define IRQ_MMP2_MUX_BASE 64
+
+/* secondary interrupt of INT #4 */
+#define IRQ_MMP2_PMIC_BASE (IRQ_MMP2_MUX_BASE)
+#define IRQ_MMP2_CHARGER (IRQ_MMP2_PMIC_BASE + 0)
+#define IRQ_MMP2_PMIC (IRQ_MMP2_PMIC_BASE + 1)
+
+/* secondary interrupt of INT #5 */
+#define IRQ_MMP2_RTC_BASE (IRQ_MMP2_PMIC_BASE + 2)
+#define IRQ_MMP2_RTC_ALARM (IRQ_MMP2_RTC_BASE + 0)
+#define IRQ_MMP2_RTC (IRQ_MMP2_RTC_BASE + 1)
+
+/* secondary interrupt of INT #17 */
+#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_RTC_BASE + 2)
+#define IRQ_MMP2_TWSI2 (IRQ_MMP2_TWSI_BASE + 0)
+#define IRQ_MMP2_TWSI3 (IRQ_MMP2_TWSI_BASE + 1)
+#define IRQ_MMP2_TWSI4 (IRQ_MMP2_TWSI_BASE + 2)
+#define IRQ_MMP2_TWSI5 (IRQ_MMP2_TWSI_BASE + 3)
+#define IRQ_MMP2_TWSI6 (IRQ_MMP2_TWSI_BASE + 4)
+
+/* secondary interrupt of INT #35 */
+#define IRQ_MMP2_MISC_BASE (IRQ_MMP2_TWSI_BASE + 5)
+#define IRQ_MMP2_PERF (IRQ_MMP2_MISC_BASE + 0)
+#define IRQ_MMP2_L2_PA_ECC (IRQ_MMP2_MISC_BASE + 1)
+#define IRQ_MMP2_L2_ECC (IRQ_MMP2_MISC_BASE + 2)
+#define IRQ_MMP2_L2_UECC (IRQ_MMP2_MISC_BASE + 3)
+#define IRQ_MMP2_DDR (IRQ_MMP2_MISC_BASE + 4)
+#define IRQ_MMP2_FAB0_TIMEOUT (IRQ_MMP2_MISC_BASE + 5)
+#define IRQ_MMP2_FAB1_TIMEOUT (IRQ_MMP2_MISC_BASE + 6)
+#define IRQ_MMP2_FAB2_TIMEOUT (IRQ_MMP2_MISC_BASE + 7)
+#define IRQ_MMP2_THERMAL (IRQ_MMP2_MISC_BASE + 9)
+#define IRQ_MMP2_MAIN_PMU (IRQ_MMP2_MISC_BASE + 10)
+#define IRQ_MMP2_WDT2 (IRQ_MMP2_MISC_BASE + 11)
+#define IRQ_MMP2_CORESIGHT (IRQ_MMP2_MISC_BASE + 12)
+#define IRQ_MMP2_COMMTX (IRQ_MMP2_MISC_BASE + 13)
+#define IRQ_MMP2_COMMRX (IRQ_MMP2_MISC_BASE + 14)
+
+/* secondary interrupt of INT #51 */
+#define IRQ_MMP2_SSP_BASE (IRQ_MMP2_MISC_BASE + 15)
+#define IRQ_MMP2_SSP1_SRDY (IRQ_MMP2_SSP_BASE + 0)
+#define IRQ_MMP2_SSP3_SRDY (IRQ_MMP2_SSP_BASE + 1)
+
+#define IRQ_MMP2_MUX_END (IRQ_MMP2_SSP_BASE + 2)
+
+#define IRQ_GPIO_START 128
+#define IRQ_GPIO_NUM 192
#define IRQ_GPIO(x) (IRQ_GPIO_START + (x))
-#define NR_IRQS (IRQ_GPIO_START + IRQ_GPIO_NUM)
+/* Board IRQ - 64 by default, increase if not enough */
+#define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM)
+#define IRQ_BOARD_END (IRQ_BOARD_START + 64)
+
+#define NR_IRQS (IRQ_BOARD_END)
#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
new file mode 100644
index 00000000000..9f9f8143e27
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
@@ -0,0 +1,240 @@
+#ifndef __ASM_MACH_MFP_MMP2_H
+#define __ASM_MACH_MFP_MMP2_H
+
+#include <mach/mfp.h>
+
+#define MFP_DRIVE_VERY_SLOW (0x0 << 13)
+#define MFP_DRIVE_SLOW (0x2 << 13)
+#define MFP_DRIVE_MEDIUM (0x4 << 13)
+#define MFP_DRIVE_FAST (0x8 << 13)
+
+/* GPIO */
+
+/* DFI */
+#define GPIO108_DFI_D15 MFP_CFG(GPIO108, AF0)
+#define GPIO109_DFI_D14 MFP_CFG(GPIO109, AF0)
+#define GPIO110_DFI_D13 MFP_CFG(GPIO110, AF0)
+#define GPIO161_DFI_D12 MFP_CFG(GPIO161, AF0)
+#define GPIO162_DFI_D11 MFP_CFG(GPIO162, AF0)
+#define GPIO163_DFI_D10 MFP_CFG(GPIO163, AF0)
+#define GPIO164_DFI_D9 MFP_CFG(GPIO164, AF0)
+#define GPIO111_DFI_D8 MFP_CFG(GPIO111, AF0)
+#define GPIO104_DFI_D7 MFP_CFG(GPIO104, AF0)
+#define GPIO105_DFI_D6 MFP_CFG(GPIO105, AF0)
+#define GPIO106_DFI_D5 MFP_CFG(GPIO106, AF0)
+#define GPIO107_DFI_D4 MFP_CFG(GPIO107, AF0)
+#define GPIO165_DFI_D3 MFP_CFG(GPIO165, AF0)
+#define GPIO166_DFI_D2 MFP_CFG(GPIO166, AF0)
+#define GPIO167_DFI_D1 MFP_CFG(GPIO167, AF0)
+#define GPIO168_DFI_D0 MFP_CFG(GPIO168, AF0)
+#define GPIO143_ND_nCS0 MFP_CFG(GPIO143, AF0)
+#define GPIO144_ND_nCS1 MFP_CFG(GPIO144, AF0)
+#define GPIO147_ND_nWE MFP_CFG(GPIO147, AF0)
+#define GPIO148_ND_nRE MFP_CFG(GPIO148, AF0)
+#define GPIO150_ND_ALE MFP_CFG(GPIO150, AF0)
+#define GPIO149_ND_CLE MFP_CFG(GPIO149, AF0)
+#define GPIO112_ND_RDY0 MFP_CFG(GPIO112, AF0)
+#define GPIO160_ND_RDY1 MFP_CFG(GPIO160, AF0)
+
+/* Static Memory Controller */
+#define GPIO145_SMC_nCS0 MFP_CFG(GPIO145, AF0)
+#define GPIO146_SMC_nCS1 MFP_CFG(GPIO146, AF0)
+#define GPIO152_SMC_BE0 MFP_CFG(GPIO152, AF0)
+#define GPIO153_SMC_BE1 MFP_CFG(GPIO153, AF0)
+#define GPIO154_SMC_IRQ MFP_CFG(GPIO154, AF0)
+#define GPIO113_SMC_RDY MFP_CFG(GPIO113, AF0)
+#define GPIO151_SMC_SCLK MFP_CFG(GPIO151, AF0)
+
+/* Ethernet */
+#define GPIO155_SM_ADVMUX MFP_CFG(GPIO155, AF2)
+#define GPIO155_GPIO155 MFP_CFG(GPIO155, AF1)
+
+/* UART1 */
+#define GPIO45_UART1_RXD MFP_CFG(GPIO45, AF1)
+#define GPIO46_UART1_TXD MFP_CFG(GPIO46, AF1)
+#define GPIO29_UART1_RXD MFP_CFG(GPIO29, AF1)
+#define GPIO30_UART1_TXD MFP_CFG(GPIO30, AF1)
+#define GPIO31_UART1_CTS MFP_CFG(GPIO31, AF1)
+#define GPIO32_UART1_RTS MFP_CFG(GPIO32, AF1)
+
+/* UART2 */
+#define GPIO47_UART2_RXD MFP_CFG(GPIO47, AF1)
+#define GPIO48_UART2_TXD MFP_CFG(GPIO48, AF1)
+#define GPIO49_UART2_CTS MFP_CFG(GPIO49, AF1)
+#define GPIO50_UART2_RTS MFP_CFG(GPIO50, AF1)
+
+/* UART3 */
+#define GPIO51_UART3_RXD MFP_CFG(GPIO51, AF1)
+#define GPIO52_UART3_TXD MFP_CFG(GPIO52, AF1)
+#define GPIO53_UART3_CTS MFP_CFG(GPIO53, AF1)
+#define GPIO54_UART3_RTS MFP_CFG(GPIO54, AF1)
+
+/* MMC1 */
+#define GPIO124_MMC1_DAT7 MFP_CFG_DRV(GPIO124, AF1, FAST)
+#define GPIO125_MMC1_DAT6 MFP_CFG_DRV(GPIO125, AF1, FAST)
+#define GPIO129_MMC1_DAT5 MFP_CFG_DRV(GPIO129, AF1, FAST)
+#define GPIO130_MMC1_DAT4 MFP_CFG_DRV(GPIO130, AF1, FAST)
+#define GPIO131_MMC1_DAT3 MFP_CFG_DRV(GPIO131, AF1, FAST)
+#define GPIO132_MMC1_DAT2 MFP_CFG_DRV(GPIO132, AF1, FAST)
+#define GPIO133_MMC1_DAT1 MFP_CFG_DRV(GPIO133, AF1, FAST)
+#define GPIO134_MMC1_DAT0 MFP_CFG_DRV(GPIO134, AF1, FAST)
+#define GPIO136_MMC1_CMD MFP_CFG_DRV(GPIO136, AF1, FAST)
+#define GPIO139_MMC1_CLK MFP_CFG_DRV(GPIO139, AF1, FAST)
+#define GPIO140_MMC1_CD MFP_CFG_DRV(GPIO140, AF1, FAST)
+#define GPIO141_MMC1_WP MFP_CFG_DRV(GPIO141, AF1, FAST)
+
+/*MMC2*/
+#define GPIO37_MMC2_DAT3 MFP_CFG_DRV(GPIO37, AF1, FAST)
+#define GPIO38_MMC2_DAT2 MFP_CFG_DRV(GPIO38, AF1, FAST)
+#define GPIO39_MMC2_DAT1 MFP_CFG_DRV(GPIO39, AF1, FAST)
+#define GPIO40_MMC2_DAT0 MFP_CFG_DRV(GPIO40, AF1, FAST)
+#define GPIO41_MMC2_CMD MFP_CFG_DRV(GPIO41, AF1, FAST)
+#define GPIO42_MMC2_CLK MFP_CFG_DRV(GPIO42, AF1, FAST)
+
+/*MMC3*/
+#define GPIO165_MMC3_DAT7 MFP_CFG_DRV(GPIO165, AF2, FAST)
+#define GPIO162_MMC3_DAT6 MFP_CFG_DRV(GPIO162, AF2, FAST)
+#define GPIO166_MMC3_DAT5 MFP_CFG_DRV(GPIO166, AF2, FAST)
+#define GPIO163_MMC3_DAT4 MFP_CFG_DRV(GPIO163, AF2, FAST)
+#define GPIO167_MMC3_DAT3 MFP_CFG_DRV(GPIO167, AF2, FAST)
+#define GPIO164_MMC3_DAT2 MFP_CFG_DRV(GPIO164, AF2, FAST)
+#define GPIO168_MMC3_DAT1 MFP_CFG_DRV(GPIO168, AF2, FAST)
+#define GPIO111_MMC3_DAT0 MFP_CFG_DRV(GPIO111, AF2, FAST)
+#define GPIO112_MMC3_CMD MFP_CFG_DRV(GPIO112, AF2, FAST)
+#define GPIO151_MMC3_CLK MFP_CFG_DRV(GPIO151, AF2, FAST)
+
+/* LCD */
+#define GPIO74_LCD_FCLK MFP_CFG_DRV(GPIO74, AF1, FAST)
+#define GPIO75_LCD_LCLK MFP_CFG_DRV(GPIO75, AF1, FAST)
+#define GPIO76_LCD_PCLK MFP_CFG_DRV(GPIO76, AF1, FAST)
+#define GPIO77_LCD_DENA MFP_CFG_DRV(GPIO77, AF1, FAST)
+#define GPIO78_LCD_DD0 MFP_CFG_DRV(GPIO78, AF1, FAST)
+#define GPIO79_LCD_DD1 MFP_CFG_DRV(GPIO79, AF1, FAST)
+#define GPIO80_LCD_DD2 MFP_CFG_DRV(GPIO80, AF1, FAST)
+#define GPIO81_LCD_DD3 MFP_CFG_DRV(GPIO81, AF1, FAST)
+#define GPIO82_LCD_DD4 MFP_CFG_DRV(GPIO82, AF1, FAST)
+#define GPIO83_LCD_DD5 MFP_CFG_DRV(GPIO83, AF1, FAST)
+#define GPIO84_LCD_DD6 MFP_CFG_DRV(GPIO84, AF1, FAST)
+#define GPIO85_LCD_DD7 MFP_CFG_DRV(GPIO85, AF1, FAST)
+#define GPIO86_LCD_DD8 MFP_CFG_DRV(GPIO86, AF1, FAST)
+#define GPIO87_LCD_DD9 MFP_CFG_DRV(GPIO87, AF1, FAST)
+#define GPIO88_LCD_DD10 MFP_CFG_DRV(GPIO88, AF1, FAST)
+#define GPIO89_LCD_DD11 MFP_CFG_DRV(GPIO89, AF1, FAST)
+#define GPIO90_LCD_DD12 MFP_CFG_DRV(GPIO90, AF1, FAST)
+#define GPIO91_LCD_DD13 MFP_CFG_DRV(GPIO91, AF1, FAST)
+#define GPIO92_LCD_DD14 MFP_CFG_DRV(GPIO92, AF1, FAST)
+#define GPIO93_LCD_DD15 MFP_CFG_DRV(GPIO93, AF1, FAST)
+#define GPIO94_LCD_DD16 MFP_CFG_DRV(GPIO94, AF1, FAST)
+#define GPIO95_LCD_DD17 MFP_CFG_DRV(GPIO95, AF1, FAST)
+#define GPIO96_LCD_DD18 MFP_CFG_DRV(GPIO96, AF1, FAST)
+#define GPIO97_LCD_DD19 MFP_CFG_DRV(GPIO97, AF1, FAST)
+#define GPIO98_LCD_DD20 MFP_CFG_DRV(GPIO98, AF1, FAST)
+#define GPIO99_LCD_DD21 MFP_CFG_DRV(GPIO99, AF1, FAST)
+#define GPIO100_LCD_DD22 MFP_CFG_DRV(GPIO100, AF1, FAST)
+#define GPIO101_LCD_DD23 MFP_CFG_DRV(GPIO101, AF1, FAST)
+#define GPIO94_SPI_DCLK MFP_CFG_DRV(GPIO94, AF3, FAST)
+#define GPIO95_SPI_CS0 MFP_CFG_DRV(GPIO95, AF3, FAST)
+#define GPIO96_SPI_DIN MFP_CFG_DRV(GPIO96, AF3, FAST)
+#define GPIO97_SPI_DOUT MFP_CFG_DRV(GPIO97, AF3, FAST)
+#define GPIO98_LCD_RST MFP_CFG_DRV(GPIO98, AF0, FAST)
+
+#define GPIO114_MN_CLK_OUT MFP_CFG_DRV(GPIO114, AF1, FAST)
+
+/*LCD TV path*/
+#define GPIO124_LCD_DD24 MFP_CFG_DRV(GPIO124, AF2, FAST)
+#define GPIO125_LCD_DD25 MFP_CFG_DRV(GPIO125, AF2, FAST)
+#define GPIO126_LCD_DD33 MFP_CFG_DRV(GPIO126, AF2, FAST)
+#define GPIO127_LCD_DD26 MFP_CFG_DRV(GPIO127, AF2, FAST)
+#define GPIO128_LCD_DD27 MFP_CFG_DRV(GPIO128, AF2, FAST)
+#define GPIO129_LCD_DD28 MFP_CFG_DRV(GPIO129, AF2, FAST)
+#define GPIO130_LCD_DD29 MFP_CFG_DRV(GPIO130, AF2, FAST)
+#define GPIO135_LCD_DD30 MFP_CFG_DRV(GPIO135, AF2, FAST)
+#define GPIO137_LCD_DD31 MFP_CFG_DRV(GPIO137, AF2, FAST)
+#define GPIO138_LCD_DD32 MFP_CFG_DRV(GPIO138, AF2, FAST)
+#define GPIO140_LCD_DD34 MFP_CFG_DRV(GPIO140, AF2, FAST)
+#define GPIO141_LCD_DD35 MFP_CFG_DRV(GPIO141, AF2, FAST)
+
+/* I2C */
+#define GPIO43_TWSI2_SCL MFP_CFG_DRV(GPIO43, AF1, SLOW)
+#define GPIO44_TWSI2_SDA MFP_CFG_DRV(GPIO44, AF1, SLOW)
+#define GPIO71_TWSI3_SCL MFP_CFG_DRV(GPIO71, AF1, SLOW)
+#define GPIO72_TWSI3_SDA MFP_CFG_DRV(GPIO72, AF1, SLOW)
+#define GPIO99_TWSI5_SCL MFP_CFG_DRV(GPIO99, AF4, SLOW)
+#define GPIO100_TWSI5_SDA MFP_CFG_DRV(GPIO100, AF4, SLOW)
+#define GPIO97_TWSI6_SCL MFP_CFG_DRV(GPIO97, AF2, SLOW)
+#define GPIO98_TWSI6_SDA MFP_CFG_DRV(GPIO98, AF2, SLOW)
+
+/* SSPA1 */
+#define GPIO24_I2S_SYSCLK MFP_CFG(GPIO24, AF1)
+#define GPIO25_I2S_BITCLK MFP_CFG(GPIO25, AF1)
+#define GPIO26_I2S_SYNC MFP_CFG(GPIO26, AF1)
+#define GPIO27_I2S_DATA_OUT MFP_CFG(GPIO27, AF1)
+#define GPIO28_I2S_SDATA_IN MFP_CFG(GPIO28, AF1)
+#define GPIO114_I2S_MCLK MFP_CFG(GPIO114, AF1)
+
+/* SSPA2 */
+#define GPIO33_SSPA2_CLK MFP_CFG(GPIO33, AF1)
+#define GPIO34_SSPA2_FRM MFP_CFG(GPIO34, AF1)
+#define GPIO35_SSPA2_TXD MFP_CFG(GPIO35, AF1)
+#define GPIO36_SSPA2_RXD MFP_CFG(GPIO36, AF1)
+
+/* Keypad */
+#define GPIO00_KP_MKIN0 MFP_CFG(GPIO0, AF1)
+#define GPIO01_KP_MKOUT0 MFP_CFG(GPIO1, AF1)
+#define GPIO02_KP_MKIN1 MFP_CFG(GPIO2, AF1)
+#define GPIO03_KP_MKOUT1 MFP_CFG(GPIO3, AF1)
+#define GPIO04_KP_MKIN2 MFP_CFG(GPIO4, AF1)
+#define GPIO05_KP_MKOUT2 MFP_CFG(GPIO5, AF1)
+#define GPIO06_KP_MKIN3 MFP_CFG(GPIO6, AF1)
+#define GPIO07_KP_MKOUT3 MFP_CFG(GPIO7, AF1)
+#define GPIO08_KP_MKIN4 MFP_CFG(GPIO8, AF1)
+#define GPIO09_KP_MKOUT4 MFP_CFG(GPIO9, AF1)
+#define GPIO10_KP_MKIN5 MFP_CFG(GPIO10, AF1)
+#define GPIO11_KP_MKOUT5 MFP_CFG(GPIO11, AF1)
+#define GPIO12_KP_MKIN6 MFP_CFG(GPIO12, AF1)
+#define GPIO13_KP_MKOUT6 MFP_CFG(GPIO13, AF1)
+#define GPIO14_KP_MKIN7 MFP_CFG(GPIO14, AF1)
+#define GPIO15_KP_MKOUT7 MFP_CFG(GPIO15, AF1)
+#define GPIO16_KP_DKIN0 MFP_CFG(GPIO16, AF1)
+#define GPIO17_KP_DKIN1 MFP_CFG(GPIO17, AF1)
+#define GPIO18_KP_DKIN2 MFP_CFG(GPIO18, AF1)
+#define GPIO19_KP_DKIN3 MFP_CFG(GPIO19, AF1)
+#define GPIO20_KP_DKIN4 MFP_CFG(GPIO20, AF1)
+#define GPIO21_KP_DKIN5 MFP_CFG(GPIO21, AF1)
+#define GPIO22_KP_DKIN6 MFP_CFG(GPIO22, AF1)
+#define GPIO23_KP_DKIN7 MFP_CFG(GPIO23, AF1)
+
+/* CAMERA */
+#define GPIO59_CCIC_IN7 MFP_CFG_DRV(GPIO59, AF1, FAST)
+#define GPIO60_CCIC_IN6 MFP_CFG_DRV(GPIO60, AF1, FAST)
+#define GPIO61_CCIC_IN5 MFP_CFG_DRV(GPIO61, AF1, FAST)
+#define GPIO62_CCIC_IN4 MFP_CFG_DRV(GPIO62, AF1, FAST)
+#define GPIO63_CCIC_IN3 MFP_CFG_DRV(GPIO63, AF1, FAST)
+#define GPIO64_CCIC_IN2 MFP_CFG_DRV(GPIO64, AF1, FAST)
+#define GPIO65_CCIC_IN1 MFP_CFG_DRV(GPIO65, AF1, FAST)
+#define GPIO66_CCIC_IN0 MFP_CFG_DRV(GPIO66, AF1, FAST)
+#define GPIO67_CAM_HSYNC MFP_CFG_DRV(GPIO67, AF1, FAST)
+#define GPIO68_CAM_VSYNC MFP_CFG_DRV(GPIO68, AF1, FAST)
+#define GPIO69_CAM_MCLK MFP_CFG_DRV(GPIO69, AF1, FAST)
+#define GPIO70_CAM_PCLK MFP_CFG_DRV(GPIO70, AF1, FAST)
+
+/* Wifi */
+#define GPIO45_GPIO45 MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO46 MFP_CFG(GPIO46, AF0)
+#define GPIO21_GPIO21 MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO22 MFP_CFG(GPIO22, AF0)
+#define GPIO55_GPIO55 MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO56 MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO57 MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO58 MFP_CFG(GPIO58, AF0)
+
+/* Codec*/
+#define GPIO23_GPIO23 MFP_CFG(GPIO23, AF0)
+
+#define GPIO101_GPIO101 MFP_CFG(GPIO101, AF0)
+
+/* PMIC */
+#define PMIC_PMIC_INT MFP_CFG(PMIC_INT, AF0)
+
+#endif /* __ASM_MACH_MFP_MMP2_H */
+
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
index 3b216bf41e7..ded43c455ec 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -193,7 +193,9 @@
#define GPIO32_CF_nCD1 MFP_CFG(GPIO32, AF3)
#define GPIO33_CF_nCD2 MFP_CFG(GPIO33, AF3)
-/* UART1 */
+/* UART */
+#define GPIO88_UART2_TXD MFP_CFG(GPIO88, AF2)
+#define GPIO89_UART2_RXD MFP_CFG(GPIO89, AF2)
#define GPIO107_UART1_TXD MFP_CFG_DRV(GPIO107, AF1, FAST)
#define GPIO107_UART1_RXD MFP_CFG_DRV(GPIO107, AF2, FAST)
#define GPIO108_UART1_RXD MFP_CFG_DRV(GPIO108, AF1, FAST)
diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h
new file mode 100644
index 00000000000..459f3be9cfb
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mmp2.h
@@ -0,0 +1,60 @@
+#ifndef __ASM_MACH_MMP2_H
+#define __ASM_MACH_MMP2_H
+
+#include <linux/i2c.h>
+#include <mach/devices.h>
+#include <plat/i2c.h>
+
+extern struct pxa_device_desc mmp2_device_uart1;
+extern struct pxa_device_desc mmp2_device_uart2;
+extern struct pxa_device_desc mmp2_device_uart3;
+extern struct pxa_device_desc mmp2_device_uart4;
+extern struct pxa_device_desc mmp2_device_twsi1;
+extern struct pxa_device_desc mmp2_device_twsi2;
+extern struct pxa_device_desc mmp2_device_twsi3;
+extern struct pxa_device_desc mmp2_device_twsi4;
+extern struct pxa_device_desc mmp2_device_twsi5;
+extern struct pxa_device_desc mmp2_device_twsi6;
+
+static inline int mmp2_add_uart(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &mmp2_device_uart1; break;
+ case 2: d = &mmp2_device_uart2; break;
+ case 3: d = &mmp2_device_uart3; break;
+ case 4: d = &mmp2_device_uart4; break;
+ default:
+ return -EINVAL;
+ }
+
+ return pxa_register_device(d, NULL, 0);
+}
+
+static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data,
+ struct i2c_board_info *info, unsigned size)
+{
+ struct pxa_device_desc *d = NULL;
+ int ret;
+
+ switch (id) {
+ case 0: d = &mmp2_device_twsi1; break;
+ case 1: d = &mmp2_device_twsi2; break;
+ case 2: d = &mmp2_device_twsi3; break;
+ case 3: d = &mmp2_device_twsi4; break;
+ case 4: d = &mmp2_device_twsi5; break;
+ case 5: d = &mmp2_device_twsi6; break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = i2c_register_board_info(id, info, size);
+ if (ret)
+ return ret;
+
+ return pxa_register_device(d, data, sizeof(*data));
+}
+
+#endif /* __ASM_MACH_MMP2_H */
+
diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h
index 98ccbee4bd0..712af03fd1a 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apbc.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h
@@ -69,6 +69,47 @@
#define APBC_PXA910_ASFAR APBC_REG(0x050)
#define APBC_PXA910_ASSAR APBC_REG(0x054)
+/*
+ * APB Clock register offsets for MMP2
+ */
+#define APBC_MMP2_RTC APBC_REG(0x000)
+#define APBC_MMP2_TWSI1 APBC_REG(0x004)
+#define APBC_MMP2_TWSI2 APBC_REG(0x008)
+#define APBC_MMP2_TWSI3 APBC_REG(0x00c)
+#define APBC_MMP2_TWSI4 APBC_REG(0x010)
+#define APBC_MMP2_ONEWIRE APBC_REG(0x014)
+#define APBC_MMP2_KPC APBC_REG(0x018)
+#define APBC_MMP2_TB_ROTARY APBC_REG(0x01c)
+#define APBC_MMP2_SW_JTAG APBC_REG(0x020)
+#define APBC_MMP2_TIMERS APBC_REG(0x024)
+#define APBC_MMP2_UART1 APBC_REG(0x02c)
+#define APBC_MMP2_UART2 APBC_REG(0x030)
+#define APBC_MMP2_UART3 APBC_REG(0x034)
+#define APBC_MMP2_GPIO APBC_REG(0x038)
+#define APBC_MMP2_PWM0 APBC_REG(0x03c)
+#define APBC_MMP2_PWM1 APBC_REG(0x040)
+#define APBC_MMP2_PWM2 APBC_REG(0x044)
+#define APBC_MMP2_PWM3 APBC_REG(0x048)
+#define APBC_MMP2_SSP0 APBC_REG(0x04c)
+#define APBC_MMP2_SSP1 APBC_REG(0x050)
+#define APBC_MMP2_SSP2 APBC_REG(0x054)
+#define APBC_MMP2_SSP3 APBC_REG(0x058)
+#define APBC_MMP2_SSP4 APBC_REG(0x05c)
+#define APBC_MMP2_SSP5 APBC_REG(0x060)
+#define APBC_MMP2_AIB APBC_REG(0x064)
+#define APBC_MMP2_ASFAR APBC_REG(0x068)
+#define APBC_MMP2_ASSAR APBC_REG(0x06c)
+#define APBC_MMP2_USIM APBC_REG(0x070)
+#define APBC_MMP2_MPMU APBC_REG(0x074)
+#define APBC_MMP2_IPC APBC_REG(0x078)
+#define APBC_MMP2_TWSI5 APBC_REG(0x07c)
+#define APBC_MMP2_TWSI6 APBC_REG(0x080)
+#define APBC_MMP2_TWSI_INTSTS APBC_REG(0x084)
+#define APBC_MMP2_UART4 APBC_REG(0x088)
+#define APBC_MMP2_RIPC APBC_REG(0x08c)
+#define APBC_MMP2_THSENS1 APBC_REG(0x090) /* Thermal Sensor */
+#define APBC_MMP2_THSENS_INTSTS APBC_REG(0x0a4)
+
/* Common APB clock register bit definitions */
#define APBC_APBCLK (1 << 0) /* APB Bus Clock Enable */
#define APBC_FNCLK (1 << 1) /* Functional Clock Enable */
diff --git a/arch/arm/mach-mmp/include/mach/regs-icu.h b/arch/arm/mach-mmp/include/mach/regs-icu.h
index e5f08723e0c..f882d91894b 100644
--- a/arch/arm/mach-mmp/include/mach/regs-icu.h
+++ b/arch/arm/mach-mmp/include/mach/regs-icu.h
@@ -17,10 +17,12 @@
#define ICU_REG(x) (ICU_VIRT_BASE + (x))
#define ICU_INT_CONF(n) ICU_REG((n) << 2)
+#define ICU_INT_CONF_MASK (0xf)
+
+/************ PXA168/PXA910 (MMP) *********************/
#define ICU_INT_CONF_AP_INT (1 << 6)
#define ICU_INT_CONF_CP_INT (1 << 5)
#define ICU_INT_CONF_IRQ (1 << 4)
-#define ICU_INT_CONF_MASK (0xf)
#define ICU_AP_FIQ_SEL_INT_NUM ICU_REG(0x108) /* AP FIQ Selected Interrupt */
#define ICU_AP_IRQ_SEL_INT_NUM ICU_REG(0x10C) /* AP IRQ Selected Interrupt */
@@ -28,4 +30,42 @@
#define ICU_INT_STATUS_0 ICU_REG(0x128) /* Interrupt Stuats 0 */
#define ICU_INT_STATUS_1 ICU_REG(0x12C) /* Interrupt Status 1 */
+/************************** MMP2 ***********************/
+
+/*
+ * IRQ0/FIQ0 is routed to SP IRQ/FIQ.
+ * IRQ1 is routed to PJ4 IRQ, and IRQ2 is routes to PJ4 FIQ.
+ */
+#define ICU_INT_ROUTE_SP_IRQ (1 << 4)
+#define ICU_INT_ROUTE_PJ4_IRQ (1 << 5)
+#define ICU_INT_ROUTE_PJ4_FIQ (1 << 6)
+
+#define MMP2_ICU_PJ4_IRQ_STATUS0 ICU_REG(0x138)
+#define MMP2_ICU_PJ4_IRQ_STATUS1 ICU_REG(0x13c)
+#define MMP2_ICU_PJ4_FIQ_STATUS0 ICU_REG(0x140)
+#define MMP2_ICU_PJ4_FIQ_STATUS1 ICU_REG(0x144)
+
+#define MMP2_ICU_INT4_STATUS ICU_REG(0x150)
+#define MMP2_ICU_INT5_STATUS ICU_REG(0x154)
+#define MMP2_ICU_INT17_STATUS ICU_REG(0x158)
+#define MMP2_ICU_INT35_STATUS ICU_REG(0x15c)
+#define MMP2_ICU_INT51_STATUS ICU_REG(0x160)
+
+#define MMP2_ICU_INT4_MASK ICU_REG(0x168)
+#define MMP2_ICU_INT5_MASK ICU_REG(0x16C)
+#define MMP2_ICU_INT17_MASK ICU_REG(0x170)
+#define MMP2_ICU_INT35_MASK ICU_REG(0x174)
+#define MMP2_ICU_INT51_MASK ICU_REG(0x178)
+
+#define MMP2_ICU_SP_IRQ_SEL ICU_REG(0x100)
+#define MMP2_ICU_PJ4_IRQ_SEL ICU_REG(0x104)
+#define MMP2_ICU_PJ4_FIQ_SEL ICU_REG(0x108)
+
+#define MMP2_ICU_INVERT ICU_REG(0x164)
+
+#define MMP2_ICU_INV_PMIC (1 << 0)
+#define MMP2_ICU_INV_PERF (1 << 1)
+#define MMP2_ICU_INV_COMMTX (1 << 2)
+#define MMP2_ICU_INV_COMMRX (1 << 3)
+
#endif /* __ASM_MACH_ICU_H */
diff --git a/arch/arm/mach-mmp/include/mach/uncompress.h b/arch/arm/mach-mmp/include/mach/uncompress.h
index c93d5fa5865..85bd8a2d84b 100644
--- a/arch/arm/mach-mmp/include/mach/uncompress.h
+++ b/arch/arm/mach-mmp/include/mach/uncompress.h
@@ -8,15 +8,16 @@
#include <linux/serial_reg.h>
#include <mach/addr-map.h>
+#include <asm/mach-types.h>
#define UART1_BASE (APB_PHYS_BASE + 0x36000)
#define UART2_BASE (APB_PHYS_BASE + 0x17000)
#define UART3_BASE (APB_PHYS_BASE + 0x18000)
+static volatile unsigned long *UART;
+
static inline void putc(char c)
{
- volatile unsigned long *UART = (unsigned long *)UART2_BASE;
-
/* UART enabled? */
if (!(UART[UART_IER] & UART_IER_UUE))
return;
@@ -34,8 +35,17 @@ static inline void flush(void)
{
}
+static inline void arch_decomp_setup(void)
+{
+ /* default to UART2 */
+ UART = (unsigned long *)UART2_BASE;
+
+ if (machine_is_avengers_lite())
+ UART = (unsigned long *)UART3_BASE;
+}
+
/*
* nothing to do
*/
-#define arch_decomp_setup()
+
#define arch_decomp_wdog()
diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c
new file mode 100644
index 00000000000..cb18221c0af
--- /dev/null
+++ b/arch/arm/mach-mmp/irq-mmp2.c
@@ -0,0 +1,154 @@
+/*
+ * linux/arch/arm/mach-mmp/irq-mmp2.c
+ *
+ * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ * Copyright: Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/regs-icu.h>
+
+#include "common.h"
+
+static void icu_mask_irq(unsigned int irq)
+{
+ uint32_t r = __raw_readl(ICU_INT_CONF(irq));
+
+ r &= ~ICU_INT_ROUTE_PJ4_IRQ;
+ __raw_writel(r, ICU_INT_CONF(irq));
+}
+
+static void icu_unmask_irq(unsigned int irq)
+{
+ uint32_t r = __raw_readl(ICU_INT_CONF(irq));
+
+ r |= ICU_INT_ROUTE_PJ4_IRQ;
+ __raw_writel(r, ICU_INT_CONF(irq));
+}
+
+static struct irq_chip icu_irq_chip = {
+ .name = "icu_irq",
+ .mask = icu_mask_irq,
+ .mask_ack = icu_mask_irq,
+ .unmask = icu_unmask_irq,
+};
+
+static void pmic_irq_ack(unsigned int irq)
+{
+ if (irq == IRQ_MMP2_PMIC)
+ mmp2_clear_pmic_int();
+}
+
+#define SECOND_IRQ_MASK(_name_, irq_base, prefix) \
+static void _name_##_mask_irq(unsigned int irq) \
+{ \
+ uint32_t r; \
+ r = __raw_readl(prefix##_MASK) | (1 << (irq - irq_base)); \
+ __raw_writel(r, prefix##_MASK); \
+}
+
+#define SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \
+static void _name_##_unmask_irq(unsigned int irq) \
+{ \
+ uint32_t r; \
+ r = __raw_readl(prefix##_MASK) & ~(1 << (irq - irq_base)); \
+ __raw_writel(r, prefix##_MASK); \
+}
+
+#define SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \
+static void _name_##_irq_demux(unsigned int irq, struct irq_desc *desc) \
+{ \
+ unsigned long status, mask, n; \
+ mask = __raw_readl(prefix##_MASK); \
+ while (1) { \
+ status = __raw_readl(prefix##_STATUS) & ~mask; \
+ if (status == 0) \
+ break; \
+ n = find_first_bit(&status, BITS_PER_LONG); \
+ while (n < BITS_PER_LONG) { \
+ generic_handle_irq(irq_base + n); \
+ n = find_next_bit(&status, BITS_PER_LONG, n+1); \
+ } \
+ } \
+}
+
+#define SECOND_IRQ_CHIP(_name_, irq_base, prefix) \
+SECOND_IRQ_MASK(_name_, irq_base, prefix) \
+SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \
+SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \
+static struct irq_chip _name_##_irq_chip = { \
+ .name = #_name_, \
+ .mask = _name_##_mask_irq, \
+ .unmask = _name_##_unmask_irq, \
+}
+
+SECOND_IRQ_CHIP(pmic, IRQ_MMP2_PMIC_BASE, MMP2_ICU_INT4);
+SECOND_IRQ_CHIP(rtc, IRQ_MMP2_RTC_BASE, MMP2_ICU_INT5);
+SECOND_IRQ_CHIP(twsi, IRQ_MMP2_TWSI_BASE, MMP2_ICU_INT17);
+SECOND_IRQ_CHIP(misc, IRQ_MMP2_MISC_BASE, MMP2_ICU_INT35);
+SECOND_IRQ_CHIP(ssp, IRQ_MMP2_SSP_BASE, MMP2_ICU_INT51);
+
+static void init_mux_irq(struct irq_chip *chip, int start, int num)
+{
+ int irq;
+
+ for (irq = start; num > 0; irq++, num--) {
+ /* mask and clear the IRQ */
+ chip->mask(irq);
+ if (chip->ack)
+ chip->ack(irq);
+
+ set_irq_chip(irq, chip);
+ set_irq_flags(irq, IRQF_VALID);
+ set_irq_handler(irq, handle_level_irq);
+ }
+}
+
+void __init mmp2_init_icu(void)
+{
+ int irq;
+
+ for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) {
+ icu_mask_irq(irq);
+ set_irq_chip(irq, &icu_irq_chip);
+ set_irq_flags(irq, IRQF_VALID);
+
+ switch (irq) {
+ case IRQ_MMP2_PMIC_MUX:
+ case IRQ_MMP2_RTC_MUX:
+ case IRQ_MMP2_TWSI_MUX:
+ case IRQ_MMP2_MISC_MUX:
+ case IRQ_MMP2_SSP_MUX:
+ break;
+ default:
+ set_irq_handler(irq, handle_level_irq);
+ break;
+ }
+ }
+
+ /* NOTE: IRQ_MMP2_PMIC requires the PMIC MFPR register
+ * to be written to clear the interrupt
+ */
+ pmic_irq_chip.ack = pmic_irq_ack;
+
+ init_mux_irq(&pmic_irq_chip, IRQ_MMP2_PMIC_BASE, 2);
+ init_mux_irq(&rtc_irq_chip, IRQ_MMP2_RTC_BASE, 2);
+ init_mux_irq(&twsi_irq_chip, IRQ_MMP2_TWSI_BASE, 5);
+ init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15);
+ init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2);
+
+ set_irq_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux);
+ set_irq_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux);
+ set_irq_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux);
+ set_irq_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux);
+ set_irq_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux);
+}
diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq-pxa168.c
index 52ff2f065eb..52ff2f065eb 100644
--- a/arch/arm/mach-mmp/irq.c
+++ b/arch/arm/mach-mmp/irq-pxa168.c
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
new file mode 100644
index 00000000000..cfd4d66ef80
--- /dev/null
+++ b/arch/arm/mach-mmp/jasper.c
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/arm/mach-mmp/jasper.c
+ *
+ * Support for the Marvell Jasper Development Platform.
+ *
+ * Copyright (C) 2009-2010 Marvell International 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
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-mmp2.h>
+#include <mach/mmp2.h>
+
+#include "common.h"
+
+static unsigned long jasper_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO29_UART1_RXD,
+ GPIO30_UART1_TXD,
+
+ /* UART3 */
+ GPIO51_UART3_RXD,
+ GPIO52_UART3_TXD,
+
+ /* DFI */
+ GPIO168_DFI_D0,
+ GPIO167_DFI_D1,
+ GPIO166_DFI_D2,
+ GPIO165_DFI_D3,
+ GPIO107_DFI_D4,
+ GPIO106_DFI_D5,
+ GPIO105_DFI_D6,
+ GPIO104_DFI_D7,
+ GPIO111_DFI_D8,
+ GPIO164_DFI_D9,
+ GPIO163_DFI_D10,
+ GPIO162_DFI_D11,
+ GPIO161_DFI_D12,
+ GPIO110_DFI_D13,
+ GPIO109_DFI_D14,
+ GPIO108_DFI_D15,
+ GPIO143_ND_nCS0,
+ GPIO144_ND_nCS1,
+ GPIO147_ND_nWE,
+ GPIO148_ND_nRE,
+ GPIO150_ND_ALE,
+ GPIO149_ND_CLE,
+ GPIO112_ND_RDY0,
+ GPIO160_ND_RDY1,
+};
+
+static void __init jasper_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(jasper_pin_config));
+
+ /* on-chip devices */
+ mmp2_add_uart(1);
+ mmp2_add_uart(3);
+}
+
+MACHINE_START(MARVELL_JASPER, "Jasper Development Platform")
+ .phys_io = APB_PHYS_BASE,
+ .boot_params = 0x00000100,
+ .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = mmp2_init_irq,
+ .timer = &mmp2_timer,
+ .init_machine = jasper_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
new file mode 100644
index 00000000000..72eb9daeea9
--- /dev/null
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/arm/mach-mmp/mmp2.c
+ *
+ * code name MMP2
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/addr-map.h>
+#include <mach/regs-apbc.h>
+#include <mach/regs-apmu.h>
+#include <mach/cputype.h>
+#include <mach/irqs.h>
+#include <mach/mfp.h>
+#include <mach/gpio.h>
+#include <mach/devices.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
+
+#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c)
+
+static struct mfp_addr_map mmp2_addr_map[] __initdata = {
+ MFP_ADDR(PMIC_INT, 0x2c4),
+
+ MFP_ADDR_END,
+};
+
+void mmp2_clear_pmic_int(void)
+{
+ unsigned long mfpr_pmic, data;
+
+ mfpr_pmic = APB_VIRT_BASE + 0x1e000 + 0x2c4;
+ data = __raw_readl(mfpr_pmic);
+ __raw_writel(data | (1 << 6), mfpr_pmic);
+ __raw_writel(data, mfpr_pmic);
+}
+
+static void __init mmp2_init_gpio(void)
+{
+ int i;
+
+ /* enable GPIO clock */
+ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_MMP2_GPIO);
+
+ /* unmask GPIO edge detection for all 6 banks -- APMASKx */
+ for (i = 0; i < 6; i++)
+ __raw_writel(0xffffffff, APMASK(i));
+
+ pxa_init_gpio(IRQ_MMP2_GPIO, 0, 167, NULL);
+}
+
+void __init mmp2_init_irq(void)
+{
+ mmp2_init_icu();
+ mmp2_init_gpio();
+}
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, MMP2_UART1, 1, 26000000);
+static APBC_CLK(uart2, MMP2_UART2, 1, 26000000);
+static APBC_CLK(uart3, MMP2_UART3, 1, 26000000);
+static APBC_CLK(uart4, MMP2_UART4, 1, 26000000);
+static APBC_CLK(twsi1, MMP2_TWSI1, 0, 26000000);
+static APBC_CLK(twsi2, MMP2_TWSI2, 0, 26000000);
+static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000);
+static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000);
+static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000);
+static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000);
+static APBC_CLK(rtc, MMP2_RTC, 0, 32768);
+
+static APMU_CLK(nand, NAND, 0xbf, 100000000);
+
+static struct clk_lookup mmp2_clkregs[] = {
+ INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL),
+ INIT_CLKREG(&clk_uart4, "pxa2xx-uart.3", NULL),
+ INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_twsi2, "pxa2xx-i2c.1", NULL),
+ INIT_CLKREG(&clk_twsi3, "pxa2xx-i2c.2", NULL),
+ INIT_CLKREG(&clk_twsi4, "pxa2xx-i2c.3", NULL),
+ INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL),
+ INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL),
+ INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+};
+
+static int __init mmp2_init(void)
+{
+ if (cpu_is_mmp2()) {
+ mfp_init_base(MFPR_VIRT_BASE);
+ mfp_init_addr(mmp2_addr_map);
+ clks_register(ARRAY_AND_SIZE(mmp2_clkregs));
+ }
+
+ return 0;
+}
+postcore_initcall(mmp2_init);
+
+/* on-chip devices */
+MMP2_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4030000, 0x30, 4, 5);
+MMP2_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4017000, 0x30, 20, 21);
+MMP2_DEVICE(uart3, "pxa2xx-uart", 2, UART3, 0xd4018000, 0x30, 22, 23);
+MMP2_DEVICE(uart4, "pxa2xx-uart", 3, UART4, 0xd4016000, 0x30, 18, 19);
+MMP2_DEVICE(twsi1, "pxa2xx-i2c", 0, TWSI1, 0xd4011000, 0x70);
+MMP2_DEVICE(twsi2, "pxa2xx-i2c", 1, TWSI2, 0xd4031000, 0x70);
+MMP2_DEVICE(twsi3, "pxa2xx-i2c", 2, TWSI3, 0xd4032000, 0x70);
+MMP2_DEVICE(twsi4, "pxa2xx-i2c", 3, TWSI4, 0xd4033000, 0x70);
+MMP2_DEVICE(twsi5, "pxa2xx-i2c", 4, TWSI5, 0xd4033800, 0x70);
+MMP2_DEVICE(twsi6, "pxa2xx-i2c", 5, TWSI6, 0xd4034000, 0x70);
+MMP2_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x100, 28, 29);
+
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index a8400bb891e..cf75694e968 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -30,7 +30,10 @@
#include <mach/addr-map.h>
#include <mach/regs-timers.h>
+#include <mach/regs-apbc.h>
#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <asm/mach/time.h>
#include "clock.h"
@@ -158,7 +161,7 @@ static void __init timer_config(void)
__raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */
- ccr &= TMR_CCR_CS_0(0x3);
+ ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3);
__raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR);
/* free-running mode */
@@ -197,3 +200,24 @@ void __init timer_init(int irq)
clocksource_register(&cksrc);
clockevents_register_device(&ckevt);
}
+
+static void __init mmp2_timer_init(void)
+{
+ unsigned long clk_rst;
+
+ __raw_writel(APBC_APBCLK | APBC_RST, APBC_MMP2_TIMERS);
+
+ /*
+ * enable bus/functional clock, enable 6.5MHz (divider 4),
+ * release reset
+ */
+ clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
+ __raw_writel(clk_rst, APBC_MMP2_TIMERS);
+
+ timer_init(IRQ_MMP2_TIMER1);
+}
+
+struct sys_timer mmp2_timer = {
+ .init = mmp2_timer_init,
+};
+
diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig
index 6fbe68fe441..f2d309d0619 100644
--- a/arch/arm/mach-mv78xx0/Kconfig
+++ b/arch/arm/mach-mv78xx0/Kconfig
@@ -14,6 +14,12 @@ config MACH_RD78X00_MASA
Say 'Y' here if you want your kernel to support the
Marvell RD-78x00-mASA Reference Design.
+config MACH_TERASTATION_WXL
+ bool "Buffalo WLX (Terastation Duo) NAS"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo WXL Nas.
+
endmenu
endif
diff --git a/arch/arm/mach-mv78xx0/Makefile b/arch/arm/mach-mv78xx0/Makefile
index da628b7f3bb..67a13f9bfe6 100644
--- a/arch/arm/mach-mv78xx0/Makefile
+++ b/arch/arm/mach-mv78xx0/Makefile
@@ -1,3 +1,4 @@
-obj-y += common.o addr-map.o irq.o pcie.o
+obj-y += common.o addr-map.o mpp.o irq.o pcie.o
obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o
obj-$(CONFIG_MACH_RD78X00_MASA) += rd78x00-masa-setup.o
+obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o
diff --git a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
new file mode 100644
index 00000000000..61e5e583603
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
@@ -0,0 +1,155 @@
+/*
+ * arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
+ *
+ * Buffalo WXL (Terastation Duo) Setup routines
+ *
+ * sebastien requiem <sebastien@requiem.fr>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <linux/i2c.h>
+#include <mach/mv78xx0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+#include "mpp.h"
+
+
+/* This arch has 2 Giga Ethernet */
+
+static struct mv643xx_eth_platform_data db78x00_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+
+/* 2 SATA controller supporting HotPlug */
+
+static struct mv_sata_platform_data db78x00_sata_data = {
+ .n_ports = 2,
+};
+
+static struct i2c_board_info __initdata db78x00_i2c_rtc = {
+ I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+
+static unsigned int wxl_mpp_config[] __initdata = {
+ MPP0_GE1_TXCLK,
+ MPP1_GE1_TXCTL,
+ MPP2_GE1_RXCTL,
+ MPP3_GE1_RXCLK,
+ MPP4_GE1_TXD0,
+ MPP5_GE1_TXD1,
+ MPP6_GE1_TXD2,
+ MPP7_GE1_TXD3,
+ MPP8_GE1_RXD0,
+ MPP9_GE1_RXD1,
+ MPP10_GE1_RXD2,
+ MPP11_GE1_RXD3,
+ MPP12_GPIO,
+ MPP13_SYSRST_OUTn,
+ MPP14_SATA1_ACTn,
+ MPP15_SATA0_ACTn,
+ MPP16_GPIO,
+ MPP17_GPIO,
+ MPP18_GPIO,
+ MPP19_GPIO,
+ MPP20_GPIO,
+ MPP21_GPIO,
+ MPP22_GPIO,
+ MPP23_GPIO,
+ MPP24_UA2_TXD,
+ MPP25_UA2_RXD,
+ MPP26_UA2_CTSn,
+ MPP27_UA2_RTSn,
+ MPP28_GPIO,
+ MPP29_SYSRST_OUTn,
+ MPP30_GPIO,
+ MPP31_GPIO,
+ MPP32_GPIO,
+ MPP33_GPIO,
+ MPP34_GPIO,
+ MPP35_GPIO,
+ MPP36_GPIO,
+ MPP37_GPIO,
+ MPP38_GPIO,
+ MPP39_GPIO,
+ MPP40_UNUSED,
+ MPP41_UNUSED,
+ MPP42_UNUSED,
+ MPP43_UNUSED,
+ MPP44_UNUSED,
+ MPP45_UNUSED,
+ MPP46_UNUSED,
+ MPP47_UNUSED,
+ MPP48_SATA1_ACTn,
+ MPP49_SATA0_ACTn,
+ 0
+};
+
+
+static void __init wxl_init(void)
+{
+ /*
+ * Basic MV78xx0 setup. Needs to be called early.
+ */
+ mv78xx0_init();
+ mv78xx0_mpp_conf(wxl_mpp_config);
+
+ /*
+ * Partition on-chip peripherals between the two CPU cores.
+ */
+ mv78xx0_ehci0_init();
+ mv78xx0_ehci1_init();
+ mv78xx0_ehci2_init();
+ mv78xx0_ge00_init(&db78x00_ge00_data);
+ mv78xx0_ge01_init(&db78x00_ge01_data);
+ mv78xx0_sata_init(&db78x00_sata_data);
+ mv78xx0_uart0_init();
+ mv78xx0_uart1_init();
+ mv78xx0_uart2_init();
+ mv78xx0_uart3_init();
+ mv78xx0_i2c_init();
+ i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
+}
+
+static int __init wxl_pci_init(void)
+{
+ if (machine_is_terastation_wxl()) {
+ /*
+ * Assign the x16 PCIe slot on the board to CPU core
+ * #0, and let CPU core #1 have the four x1 slots.
+ */
+ if (mv78xx0_core_index() == 0)
+ mv78xx0_pcie_init(0, 1);
+ else
+ mv78xx0_pcie_init(1, 0);
+ }
+
+ return 0;
+}
+subsys_initcall(wxl_pci_init);
+
+MACHINE_START(TERASTATION_WXL, "Buffalo Nas WXL")
+ /* Maintainer: Sebastien Requiem <sebastien@requiem.fr> */
+ .phys_io = MV78XX0_REGS_PHYS_BASE,
+ .io_pg_offst = ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = wxl_init,
+ .map_io = mv78xx0_map_io,
+ .init_irq = mv78xx0_init_irq,
+ .timer = &mv78xx0_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c
new file mode 100644
index 00000000000..354ac514eb8
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/mpp.c
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-mv78x00/mpp.c
+ *
+ * MPP functions for Marvell MV78x00 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include "common.h"
+#include "mpp.h"
+
+static unsigned int __init mv78xx0_variant(void)
+{
+ u32 dev, rev;
+
+ mv78xx0_pcie_id(&dev, &rev);
+
+ if (dev == MV78100_DEV_ID && rev >= MV78100_REV_A0)
+ return MPP_78100_A0_MASK;
+
+ printk(KERN_ERR "MPP setup: unknown mv78x00 variant "
+ "(dev %#x rev %#x)\n", dev, rev);
+ return 0;
+}
+
+#define MPP_CTRL(i) (DEV_BUS_VIRT_BASE + (i) * 4)
+#define MPP_NR_REGS (1 + MPP_MAX/8)
+
+void __init mv78xx0_mpp_conf(unsigned int *mpp_list)
+{
+ u32 mpp_ctrl[MPP_NR_REGS];
+ unsigned int variant_mask;
+ int i;
+
+ variant_mask = mv78xx0_variant();
+ if (!variant_mask)
+ return;
+
+ /* Initialize gpiolib. */
+ orion_gpio_init();
+
+ printk(KERN_DEBUG "initial MPP regs:");
+ for (i = 0; i < MPP_NR_REGS; i++) {
+ mpp_ctrl[i] = readl(MPP_CTRL(i));
+ printk(" %08x", mpp_ctrl[i]);
+ }
+ printk("\n");
+
+ while (*mpp_list) {
+ unsigned int num = MPP_NUM(*mpp_list);
+ unsigned int sel = MPP_SEL(*mpp_list);
+ int shift, gpio_mode;
+
+ if (num > MPP_MAX) {
+ printk(KERN_ERR "mv78xx0_mpp_conf: invalid MPP "
+ "number (%u)\n", num);
+ continue;
+ }
+ if (!(*mpp_list & variant_mask)) {
+ printk(KERN_WARNING
+ "mv78xx0_mpp_conf: requested MPP%u config "
+ "unavailable on this hardware\n", num);
+ continue;
+ }
+
+ shift = (num & 7) << 2;
+ mpp_ctrl[num / 8] &= ~(0xf << shift);
+ mpp_ctrl[num / 8] |= sel << shift;
+
+ gpio_mode = 0;
+ if (*mpp_list & MPP_INPUT_MASK)
+ gpio_mode |= GPIO_INPUT_OK;
+ if (*mpp_list & MPP_OUTPUT_MASK)
+ gpio_mode |= GPIO_OUTPUT_OK;
+ if (sel != 0)
+ gpio_mode = 0;
+ orion_gpio_set_valid(num, gpio_mode);
+
+ mpp_list++;
+ }
+
+ printk(KERN_DEBUG " final MPP regs:");
+ for (i = 0; i < MPP_NR_REGS; i++) {
+ writel(mpp_ctrl[i], MPP_CTRL(i));
+ printk(" %08x", mpp_ctrl[i]);
+ }
+ printk("\n");
+}
diff --git a/arch/arm/mach-mv78xx0/mpp.h b/arch/arm/mach-mv78xx0/mpp.h
new file mode 100644
index 00000000000..80840b781ea
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/mpp.h
@@ -0,0 +1,347 @@
+/*
+ * linux/arch/arm/mach-mv78xx0/mpp.h -- Multi Purpose Pins
+ *
+ *
+ * sebastien requiem <sebastien@requiem.fr>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MV78X00_MPP_H
+#define __MV78X00_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _78100_A0) (\
+ /* MPP number */ ((_num) & 0xff) | \
+ /* MPP select value */ (((_sel) & 0xf) << 8) | \
+ /* may be input signal */ ((!!(_in)) << 12) | \
+ /* may be output signal */ ((!!(_out)) << 13) | \
+ /* available on A0 */ ((!!(_78100_A0)) << 14))
+
+#define MPP_NUM(x) ((x) & 0xff)
+#define MPP_SEL(x) (((x) >> 8) & 0xf)
+
+ /* num sel i o 78100_A0 */
+
+#define MPP_INPUT_MASK MPP(0, 0x0, 1, 0, 0)
+#define MPP_OUTPUT_MASK MPP(0, 0x0, 0, 1, 0)
+
+#define MPP_78100_A0_MASK MPP(0, 0x0, 0, 0, 1)
+
+#define MPP0_GPIO MPP(0, 0x0, 1, 1, 1)
+#define MPP0_GE0_COL MPP(0, 0x1, 1, 0, 1)
+#define MPP0_GE1_TXCLK MPP(0, 0x2, 0, 1, 1)
+#define MPP0_UNUSED MPP(0, 0x3, 0, 0, 1)
+
+#define MPP1_GPIO MPP(1, 0x0, 1, 1, 1)
+#define MPP1_GE0_RXERR MPP(1, 0x1, 1, 0, 1)
+#define MPP1_GE1_TXCTL MPP(1, 0x2, 0, 1, 1)
+#define MPP1_UNUSED MPP(1, 0x3, 0, 0, 1)
+
+#define MPP2_GPIO MPP(2, 0x0, 1, 1, 1)
+#define MPP2_GE0_CRS MPP(2, 0x1, 1, 0, 1)
+#define MPP2_GE1_RXCTL MPP(2, 0x2, 1, 0, 1)
+#define MPP2_UNUSED MPP(2, 0x3, 0, 0, 1)
+
+#define MPP3_GPIO MPP(3, 0x0, 1, 1, 1)
+#define MPP3_GE0_TXERR MPP(3, 0x1, 0, 1, 1)
+#define MPP3_GE1_RXCLK MPP(3, 0x2, 1, 0, 1)
+#define MPP3_UNUSED MPP(3, 0x3, 0, 0, 1)
+
+#define MPP4_GPIO MPP(4, 0x0, 1, 1, 1)
+#define MPP4_GE0_TXD4 MPP(4, 0x1, 0, 1, 1)
+#define MPP4_GE1_TXD0 MPP(4, 0x2, 0, 1, 1)
+#define MPP4_UNUSED MPP(4, 0x3, 0, 0, 1)
+
+#define MPP5_GPIO MPP(5, 0x0, 1, 1, 1)
+#define MPP5_GE0_TXD5 MPP(5, 0x1, 0, 1, 1)
+#define MPP5_GE1_TXD1 MPP(5, 0x2, 0, 1, 1)
+#define MPP5_UNUSED MPP(5, 0x3, 0, 0, 1)
+
+#define MPP6_GPIO MPP(6, 0x0, 1, 1, 1)
+#define MPP6_GE0_TXD6 MPP(6, 0x1, 0, 1, 1)
+#define MPP6_GE1_TXD2 MPP(6, 0x2, 0, 1, 1)
+#define MPP6_UNUSED MPP(6, 0x3, 0, 0, 1)
+
+#define MPP7_GPIO MPP(7, 0x0, 1, 1, 1)
+#define MPP7_GE0_TXD7 MPP(7, 0x1, 0, 1, 1)
+#define MPP7_GE1_TXD3 MPP(7, 0x2, 0, 1, 1)
+#define MPP7_UNUSED MPP(7, 0x3, 0, 0, 1)
+
+#define MPP8_GPIO MPP(8, 0x0, 1, 1, 1)
+#define MPP8_GE0_RXD4 MPP(8, 0x1, 1, 0, 1)
+#define MPP8_GE1_RXD0 MPP(8, 0x2, 1, 0, 1)
+#define MPP8_UNUSED MPP(8, 0x3, 0, 0, 1)
+
+#define MPP9_GPIO MPP(9, 0x0, 1, 1, 1)
+#define MPP9_GE0_RXD5 MPP(9, 0x1, 1, 0, 1)
+#define MPP9_GE1_RXD1 MPP(9, 0x2, 1, 0, 1)
+#define MPP9_UNUSED MPP(9, 0x3, 0, 0, 1)
+
+#define MPP10_GPIO MPP(10, 0x0, 1, 1, 1)
+#define MPP10_GE0_RXD6 MPP(10, 0x1, 1, 0, 1)
+#define MPP10_GE1_RXD2 MPP(10, 0x2, 1, 0, 1)
+#define MPP10_UNUSED MPP(10, 0x3, 0, 0, 1)
+
+#define MPP11_GPIO MPP(11, 0x0, 1, 1, 1)
+#define MPP11_GE0_RXD7 MPP(11, 0x1, 1, 0, 1)
+#define MPP11_GE1_RXD3 MPP(11, 0x2, 1, 0, 1)
+#define MPP11_UNUSED MPP(11, 0x3, 0, 0, 1)
+
+#define MPP12_GPIO MPP(12, 0x0, 1, 1, 1)
+#define MPP12_M_BB MPP(12, 0x3, 1, 0, 1)
+#define MPP12_UA0_CTSn MPP(12, 0x4, 1, 0, 1)
+#define MPP12_NAND_FLASH_REn0 MPP(12, 0x5, 0, 1, 1)
+#define MPP12_TDM0_SCSn MPP(12, 0X6, 0, 1, 1)
+#define MPP12_UNUSED MPP(12, 0x1, 0, 0, 1)
+
+#define MPP13_GPIO MPP(13, 0x0, 1, 1, 1)
+#define MPP13_SYSRST_OUTn MPP(13, 0x3, 0, 1, 1)
+#define MPP13_UA0_RTSn MPP(13, 0x4, 0, 1, 1)
+#define MPP13_NAN_FLASH_WEn0 MPP(13, 0x5, 0, 1, 1)
+#define MPP13_TDM_SCLK MPP(13, 0x6, 0, 1, 1)
+#define MPP13_UNUSED MPP(13, 0x1, 0, 0, 1)
+
+#define MPP14_GPIO MPP(14, 0x0, 1, 1, 1)
+#define MPP14_SATA1_ACTn MPP(14, 0x3, 0, 1, 1)
+#define MPP14_UA1_CTSn MPP(14, 0x4, 1, 0, 1)
+#define MPP14_NAND_FLASH_REn1 MPP(14, 0x5, 0, 1, 1)
+#define MPP14_TDM_SMOSI MPP(14, 0x6, 0, 1, 1)
+#define MPP14_UNUSED MPP(14, 0x1, 0, 0, 1)
+
+#define MPP15_GPIO MPP(15, 0x0, 1, 1, 1)
+#define MPP15_SATA0_ACTn MPP(15, 0x3, 0, 1, 1)
+#define MPP15_UA1_RTSn MPP(15, 0x4, 0, 1, 1)
+#define MPP15_NAND_FLASH_WEn1 MPP(15, 0x5, 0, 1, 1)
+#define MPP15_TDM_SMISO MPP(15, 0x6, 1, 0, 1)
+#define MPP15_UNUSED MPP(15, 0x1, 0, 0, 1)
+
+#define MPP16_GPIO MPP(16, 0x0, 1, 1, 1)
+#define MPP16_SATA1_PRESENTn MPP(16, 0x3, 0, 1, 1)
+#define MPP16_UA2_TXD MPP(16, 0x4, 0, 1, 1)
+#define MPP16_NAND_FLASH_REn3 MPP(16, 0x5, 0, 1, 1)
+#define MPP16_TDM_INTn MPP(16, 0x6, 1, 0, 1)
+#define MPP16_UNUSED MPP(16, 0x1, 0, 0, 1)
+
+
+#define MPP17_GPIO MPP(17, 0x0, 1, 1, 1)
+#define MPP17_SATA0_PRESENTn MPP(17, 0x3, 0, 1, 1)
+#define MPP17_UA2_RXD MPP(17, 0x4, 1, 0, 1)
+#define MPP17_NAND_FLASH_WEn3 MPP(17, 0x5, 0, 1, 1)
+#define MPP17_TDM_RSTn MPP(17, 0x6, 0, 1, 1)
+#define MPP17_UNUSED MPP(17, 0x1, 0, 0, 1)
+
+
+#define MPP18_GPIO MPP(18, 0x0, 1, 1, 1)
+#define MPP18_UA0_CTSn MPP(18, 0x4, 1, 0, 1)
+#define MPP18_BOOT_FLASH_REn MPP(18, 0x5, 0, 1, 1)
+#define MPP18_UNUSED MPP(18, 0x1, 0, 0, 1)
+
+
+
+#define MPP19_GPIO MPP(19, 0x0, 1, 1, 1)
+#define MPP19_UA0_CTSn MPP(19, 0x4, 0, 1, 1)
+#define MPP19_BOOT_FLASH_WEn MPP(19, 0x5, 0, 1, 1)
+#define MPP19_UNUSED MPP(19, 0x1, 0, 0, 1)
+
+
+#define MPP20_GPIO MPP(20, 0x0, 1, 1, 1)
+#define MPP20_UA1_CTSs MPP(20, 0x4, 1, 0, 1)
+#define MPP20_TDM_PCLK MPP(20, 0x6, 1, 1, 0)
+#define MPP20_UNUSED MPP(20, 0x1, 0, 0, 1)
+
+
+
+#define MPP21_GPIO MPP(21, 0x0, 1, 1, 1)
+#define MPP21_UA1_CTSs MPP(21, 0x4, 0, 1, 1)
+#define MPP21_TDM_FSYNC MPP(21, 0x6, 1, 1, 0)
+#define MPP21_UNUSED MPP(21, 0x1, 0, 0, 1)
+
+
+
+#define MPP22_GPIO MPP(22, 0x0, 1, 1, 1)
+#define MPP22_UA3_TDX MPP(22, 0x4, 0, 1, 1)
+#define MPP22_NAND_FLASH_REn2 MPP(22, 0x5, 0, 1, 1)
+#define MPP22_TDM_DRX MPP(22, 0x6, 1, 0, 1)
+#define MPP22_UNUSED MPP(22, 0x1, 0, 0, 1)
+
+
+
+#define MPP23_GPIO MPP(23, 0x0, 1, 1, 1)
+#define MPP23_UA3_RDX MPP(23, 0x4, 1, 0, 1)
+#define MPP23_NAND_FLASH_WEn2 MPP(23, 0x5, 0, 1, 1)
+#define MPP23_TDM_DTX MPP(23, 0x6, 0, 1, 1)
+#define MPP23_UNUSED MPP(23, 0x1, 0, 0, 1)
+
+
+#define MPP24_GPIO MPP(24, 0x0, 1, 1, 1)
+#define MPP24_UA2_TXD MPP(24, 0x4, 0, 1, 1)
+#define MPP24_TDM_INTn MPP(24, 0x6, 1, 0, 1)
+#define MPP24_UNUSED MPP(24, 0x1, 0, 0, 1)
+
+
+#define MPP25_GPIO MPP(25, 0x0, 1, 1, 1)
+#define MPP25_UA2_RXD MPP(25, 0x4, 1, 0, 1)
+#define MPP25_TDM_RSTn MPP(25, 0x6, 0, 1, 1)
+#define MPP25_UNUSED MPP(25, 0x1, 0, 0, 1)
+
+
+#define MPP26_GPIO MPP(26, 0x0, 1, 1, 1)
+#define MPP26_UA2_CTSn MPP(26, 0x4, 1, 0, 1)
+#define MPP26_TDM_PCLK MPP(26, 0x6, 1, 1, 1)
+#define MPP26_UNUSED MPP(26, 0x1, 0, 0, 1)
+
+
+#define MPP27_GPIO MPP(27, 0x0, 1, 1, 1)
+#define MPP27_UA2_RTSn MPP(27, 0x4, 0, 1, 1)
+#define MPP27_TDM_FSYNC MPP(27, 0x6, 1, 1, 1)
+#define MPP27_UNUSED MPP(27, 0x1, 0, 0, 1)
+
+
+#define MPP28_GPIO MPP(28, 0x0, 1, 1, 1)
+#define MPP28_UA3_TXD MPP(28, 0x4, 0, 1, 1)
+#define MPP28_TDM_DRX MPP(28, 0x6, 1, 0, 1)
+#define MPP28_UNUSED MPP(28, 0x1, 0, 0, 1)
+
+#define MPP29_GPIO MPP(29, 0x0, 1, 1, 1)
+#define MPP29_UA3_RXD MPP(29, 0x4, 1, 0, 1)
+#define MPP29_SYSRST_OUTn MPP(29, 0x5, 0, 1, 1)
+#define MPP29_TDM_DTX MPP(29, 0x6, 0, 1, 1)
+#define MPP29_UNUSED MPP(29, 0x1, 0, 0, 1)
+
+#define MPP30_GPIO MPP(30, 0x0, 1, 1, 1)
+#define MPP30_UA3_CTSn MPP(30, 0x4, 1, 0, 1)
+#define MPP30_UNUSED MPP(30, 0x1, 0, 0, 1)
+
+#define MPP31_GPIO MPP(31, 0x0, 1, 1, 1)
+#define MPP31_UA3_RTSn MPP(31, 0x4, 0, 1, 1)
+#define MPP31_TDM1_SCSn MPP(31, 0x6, 0, 1, 1)
+#define MPP31_UNUSED MPP(31, 0x1, 0, 0, 1)
+
+
+#define MPP32_GPIO MPP(32, 0x1, 1, 1, 1)
+#define MPP32_UA3_TDX MPP(32, 0x4, 0, 1, 1)
+#define MPP32_SYSRST_OUTn MPP(32, 0x5, 0, 1, 1)
+#define MPP32_TDM0_RXQ MPP(32, 0x6, 0, 1, 1)
+#define MPP32_UNUSED MPP(32, 0x3, 0, 0, 1)
+
+
+#define MPP33_GPIO MPP(33, 0x1, 1, 1, 1)
+#define MPP33_UA3_RDX MPP(33, 0x4, 1, 0, 1)
+#define MPP33_TDM0_TXQ MPP(33, 0x6, 0, 1, 1)
+#define MPP33_UNUSED MPP(33, 0x3, 0, 0, 1)
+
+
+
+#define MPP34_GPIO MPP(34, 0x1, 1, 1, 1)
+#define MPP34_UA2_TDX MPP(34, 0x4, 0, 1, 1)
+#define MPP34_TDM1_RXQ MPP(34, 0x6, 0, 1, 1)
+#define MPP34_UNUSED MPP(34, 0x3, 0, 0, 1)
+
+
+
+#define MPP35_GPIO MPP(35, 0x1, 1, 1, 1)
+#define MPP35_UA2_RDX MPP(35, 0x4, 1, 0, 1)
+#define MPP35_TDM1_TXQ MPP(35, 0x6, 0, 1, 1)
+#define MPP35_UNUSED MPP(35, 0x3, 0, 0, 1)
+
+#define MPP36_GPIO MPP(36, 0x1, 1, 1, 1)
+#define MPP36_UA0_CTSn MPP(36, 0x2, 1, 0, 1)
+#define MPP36_UA2_TDX MPP(36, 0x4, 0, 1, 1)
+#define MPP36_TDM0_SCSn MPP(36, 0x6, 0, 1, 1)
+#define MPP36_UNUSED MPP(36, 0x3, 0, 0, 1)
+
+
+#define MPP37_GPIO MPP(37, 0x1, 1, 1, 1)
+#define MPP37_UA0_RTSn MPP(37, 0x2, 0, 1, 1)
+#define MPP37_UA2_RXD MPP(37, 0x4, 1, 0, 1)
+#define MPP37_SYSRST_OUTn MPP(37, 0x5, 0, 1, 1)
+#define MPP37_TDM_SCLK MPP(37, 0x6, 0, 1, 1)
+#define MPP37_UNUSED MPP(37, 0x3, 0, 0, 1)
+
+
+
+
+#define MPP38_GPIO MPP(38, 0x1, 1, 1, 1)
+#define MPP38_UA1_CTSn MPP(38, 0x2, 1, 0, 1)
+#define MPP38_UA3_TXD MPP(38, 0x4, 0, 1, 1)
+#define MPP38_SYSRST_OUTn MPP(38, 0x5, 0, 1, 1)
+#define MPP38_TDM_SMOSI MPP(38, 0x6, 0, 1, 1)
+#define MPP38_UNUSED MPP(38, 0x3, 0, 0, 1)
+
+
+
+
+#define MPP39_GPIO MPP(39, 0x1, 1, 1, 1)
+#define MPP39_UA1_RTSn MPP(39, 0x2, 0, 1, 1)
+#define MPP39_UA3_RXD MPP(39, 0x4, 1, 0, 1)
+#define MPP39_SYSRST_OUTn MPP(39, 0x5, 0, 1, 1)
+#define MPP39_TDM_SMISO MPP(39, 0x6, 1, 0, 1)
+#define MPP39_UNUSED MPP(39, 0x3, 0, 0, 1)
+
+
+
+#define MPP40_GPIO MPP(40, 0x1, 1, 1, 1)
+#define MPP40_TDM_INTn MPP(40, 0x6, 1, 0, 1)
+#define MPP40_UNUSED MPP(40, 0x0, 0, 0, 1)
+
+
+
+#define MPP41_GPIO MPP(41, 0x1, 1, 1, 1)
+#define MPP41_TDM_RSTn MPP(41, 0x6, 0, 1, 1)
+#define MPP41_UNUSED MPP(41, 0x0, 0, 0, 1)
+
+
+
+#define MPP42_GPIO MPP(42, 0x1, 1, 1, 1)
+#define MPP42_TDM_PCLK MPP(42, 0x6, 1, 1, 1)
+#define MPP42_UNUSED MPP(42, 0x0, 0, 0, 1)
+
+
+
+#define MPP43_GPIO MPP(43, 0x1, 1, 1, 1)
+#define MPP43_TDM_FSYNC MPP(43, 0x6, 1, 1, 1)
+#define MPP43_UNUSED MPP(43, 0x0, 0, 0, 1)
+
+
+
+#define MPP44_GPIO MPP(44, 0x1, 1, 1, 1)
+#define MPP44_TDM_DRX MPP(44, 0x6, 1, 0, 1)
+#define MPP44_UNUSED MPP(44, 0x0, 0, 0, 1)
+
+
+
+#define MPP45_GPIO MPP(45, 0x1, 1, 1, 1)
+#define MPP45_SATA0_ACTn MPP(45, 0x3, 0, 1, 1)
+#define MPP45_TDM_DRX MPP(45, 0x6, 0, 1, 1)
+#define MPP45_UNUSED MPP(45, 0x0, 0, 0, 1)
+
+
+#define MPP46_GPIO MPP(46, 0x1, 1, 1, 1)
+#define MPP46_TDM_SCSn MPP(46, 0x6, 0, 1, 1)
+#define MPP46_UNUSED MPP(46, 0x0, 0, 0, 1)
+
+
+#define MPP47_GPIO MPP(47, 0x1, 1, 1, 1)
+#define MPP47_UNUSED MPP(47, 0x0, 0, 0, 1)
+
+
+
+#define MPP48_GPIO MPP(48, 0x1, 1, 1, 1)
+#define MPP48_SATA1_ACTn MPP(48, 0x3, 0, 1, 1)
+#define MPP48_UNUSED MPP(48, 0x2, 0, 0, 1)
+
+
+
+#define MPP49_GPIO MPP(49, 0x1, 1, 1, 1)
+#define MPP49_SATA0_ACTn MPP(49, 0x3, 0, 1, 1)
+#define MPP49_M_BB MPP(49, 0x4, 1, 0, 1)
+#define MPP49_UNUSED MPP(49, 0x2, 0, 0, 1)
+
+
+#define MPP_MAX 49
+
+void mv78xx0_mpp_conf(unsigned int *mpp_list);
+
+#endif
diff --git a/arch/arm/mach-mx1/Makefile b/arch/arm/mach-mx1/Makefile
index 7f86fe073ec..fc2ddf82441 100644
--- a/arch/arm/mach-mx1/Makefile
+++ b/arch/arm/mach-mx1/Makefile
@@ -4,11 +4,12 @@
# 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) += mx1ads.o
-obj-$(CONFIG_MACH_SCB9328) += scb9328.o \ No newline at end of file
+obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o
+obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
diff --git a/arch/arm/mach-mx1/mach-mx1ads.c b/arch/arm/mach-mx1/mach-mx1ads.c
new file mode 100644
index 00000000000..51f3cfd83db
--- /dev/null
+++ b/arch/arm/mach-mx1/mach-mx1ads.c
@@ -0,0 +1,165 @@
+/*
+ * arch/arm/mach-imx/mach-mx1ads.c
+ *
+ * Initially based on:
+ * linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c
+ * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ *
+ * 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 kind, whether express or implied.
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#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.h"
+
+static int mx1ads_pins[] = {
+ /* UART1 */
+ PC9_PF_UART1_CTS,
+ PC10_PF_UART1_RTS,
+ PC11_PF_UART1_TXD,
+ PC12_PF_UART1_RXD,
+ /* UART2 */
+ PB28_PF_UART2_CTS,
+ PB29_PF_UART2_RTS,
+ PB30_PF_UART2_TXD,
+ PB31_PF_UART2_RXD,
+ /* I2C */
+ PA15_PF_I2C_SDA,
+ PA16_PF_I2C_SCL,
+ /* SPI */
+ PC13_PF_SPI1_SPI_RDY,
+ PC14_PF_SPI1_SCLK,
+ PC15_PF_SPI1_SS,
+ PC16_PF_SPI1_MISO,
+ PC17_PF_SPI1_MOSI,
+};
+
+/*
+ * UARTs platform data
+ */
+
+static struct imxuart_platform_data uart_pdata[] = {
+ {
+ .flags = IMXUART_HAVE_RTSCTS,
+ }, {
+ .flags = IMXUART_HAVE_RTSCTS,
+ },
+};
+
+/*
+ * Physmap flash
+ */
+
+static struct physmap_flash_data mx1ads_flash_data = {
+ .width = 4, /* bankwidth in bytes */
+};
+
+static struct resource flash_resource = {
+ .start = IMX_CS0_PHYS,
+ .end = IMX_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+/*
+ * I2C
+ */
+static struct pcf857x_platform_data pcf857x_data[] = {
+ {
+ .gpio_base = 4 * 32,
+ }, {
+ .gpio_base = 4 * 32 + 16,
+ }
+};
+
+static struct imxi2c_platform_data mx1ads_i2c_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mx1ads_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8575", 0x22),
+ .platform_data = &pcf857x_data[0],
+ }, {
+ I2C_BOARD_INFO("pcf8575", 0x24),
+ .platform_data = &pcf857x_data[1],
+ },
+};
+
+/*
+ * Board init
+ */
+static void __init mx1ads_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mx1ads_pins,
+ ARRAY_SIZE(mx1ads_pins), "mx1ads");
+
+ /* UART */
+ mxc_register_device(&imx_uart1_device, &uart_pdata[0]);
+ mxc_register_device(&imx_uart2_device, &uart_pdata[1]);
+
+ /* Physmap flash */
+ mxc_register_device(&flash_device, &mx1ads_flash_data);
+
+ /* I2C */
+ i2c_register_board_info(0, mx1ads_i2c_devices,
+ ARRAY_SIZE(mx1ads_i2c_devices));
+
+ mxc_register_device(&imx_i2c_device, &mx1ads_i2c_data);
+}
+
+static void __init mx1ads_timer_init(void)
+{
+ mx1_clocks_init(32000);
+}
+
+struct sys_timer mx1ads_timer = {
+ .init = mx1ads_timer_init,
+};
+
+MACHINE_START(MX1ADS, "Freescale MX1ADS")
+ /* Maintainer: Sascha Hauer, Pengutronix */
+ .phys_io = IMX_IO_PHYS,
+ .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
+ .boot_params = MX1_PHYS_OFFSET + 0x100,
+ .map_io = mx1_map_io,
+ .init_irq = mx1_init_irq,
+ .timer = &mx1ads_timer,
+ .init_machine = mx1ads_init,
+MACHINE_END
+
+MACHINE_START(MXLADS, "Freescale MXLADS")
+ .phys_io = IMX_IO_PHYS,
+ .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
+ .boot_params = MX1_PHYS_OFFSET + 0x100,
+ .map_io = mx1_map_io,
+ .init_irq = mx1_init_irq,
+ .timer = &mx1ads_timer,
+ .init_machine = mx1ads_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx1/mach-scb9328.c b/arch/arm/mach-mx1/mach-scb9328.c
new file mode 100644
index 00000000000..7587a7a1246
--- /dev/null
+++ b/arch/arm/mach-mx1/mach-scb9328.c
@@ -0,0 +1,158 @@
+/*
+ * linux/arch/arm/mach-mx1/mach-scb9328.c
+ *
+ * Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
+ * Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/interrupt.h>
+#include <linux/dm9000.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx1.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,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data scb_flash_data = {
+ .width = 2,
+};
+
+static struct platform_device scb_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &scb_flash_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+/*
+ * scb9328 has a DM9000 network controller
+ * connected to CS5, with 16 bit data path
+ * and interrupt connected to GPIO 3
+ */
+
+/*
+ * internal datapath is fixed 16 bit
+ */
+static struct dm9000_plat_data dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+/*
+ * the DM9000 drivers wants two defined address spaces
+ * to gain access to address latch registers and the data path.
+ */
+static struct resource dm9000x_resources[] = {
+ {
+ .name = "address area",
+ .start = IMX_CS5_PHYS,
+ .end = IMX_CS5_PHYS + 1,
+ .flags = IORESOURCE_MEM, /* address access */
+ }, {
+ .name = "data area",
+ .start = IMX_CS5_PHYS + 4,
+ .end = IMX_CS5_PHYS + 5,
+ .flags = IORESOURCE_MEM, /* data access */
+ }, {
+ .start = IRQ_GPIOC(3),
+ .end = IRQ_GPIOC(3),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct platform_device dm9000x_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9000x_resources),
+ .resource = dm9000x_resources,
+ .dev = {
+ .platform_data = &dm9000_platdata,
+ }
+};
+
+static int mxc_uart1_pins[] = {
+ PC9_PF_UART1_CTS,
+ PC10_PF_UART1_RTS,
+ PC11_PF_UART1_TXD,
+ PC12_PF_UART1_RXD,
+};
+
+static int uart1_mxc_init(struct platform_device *pdev)
+{
+ return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
+ ARRAY_SIZE(mxc_uart1_pins), "UART1");
+}
+
+static int 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 = {
+ .init = uart1_mxc_init,
+ .exit = uart1_mxc_exit,
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &scb_flash_device,
+ &dm9000x_device,
+};
+
+/*
+ * scb9328_init - Init the CPU card itself
+ */
+static void __init scb9328_init(void)
+{
+ mxc_register_device(&imx_uart1_device, &uart_pdata);
+
+ printk(KERN_INFO"Scb9328: Adding devices\n");
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init scb9328_timer_init(void)
+{
+ mx1_clocks_init(32000);
+}
+
+static struct sys_timer scb9328_timer = {
+ .init = scb9328_timer_init,
+};
+
+MACHINE_START(SCB9328, "Synertronixx scb9328")
+ /* Sascha Hauer */
+ .phys_io = 0x00200000,
+ .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
+ .boot_params = 0x08000100,
+ .map_io = mx1_map_io,
+ .init_irq = mx1_init_irq,
+ .timer = &scb9328_timer,
+ .init_machine = scb9328_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx1/mx1ads.c b/arch/arm/mach-mx1/mx1ads.c
deleted file mode 100644
index 30f04e56faf..00000000000
--- a/arch/arm/mach-mx1/mx1ads.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * arch/arm/mach-imx/mx1ads.c
- *
- * Initially based on:
- * linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c
- * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
- *
- * 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 kind, whether express or implied.
- */
-
-#include <linux/i2c.h>
-#include <linux/i2c/pcf857x.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.h>
-#include <mach/irqs.h>
-
-#include "devices.h"
-
-static int mx1ads_pins[] = {
- /* UART1 */
- PC9_PF_UART1_CTS,
- PC10_PF_UART1_RTS,
- PC11_PF_UART1_TXD,
- PC12_PF_UART1_RXD,
- /* UART2 */
- PB28_PF_UART2_CTS,
- PB29_PF_UART2_RTS,
- PB30_PF_UART2_TXD,
- PB31_PF_UART2_RXD,
- /* I2C */
- PA15_PF_I2C_SDA,
- PA16_PF_I2C_SCL,
- /* SPI */
- PC13_PF_SPI1_SPI_RDY,
- PC14_PF_SPI1_SCLK,
- PC15_PF_SPI1_SS,
- PC16_PF_SPI1_MISO,
- PC17_PF_SPI1_MOSI,
-};
-
-/*
- * UARTs platform data
- */
-
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- },
-};
-
-/*
- * Physmap flash
- */
-
-static struct physmap_flash_data mx1ads_flash_data = {
- .width = 4, /* bankwidth in bytes */
-};
-
-static struct resource flash_resource = {
- .start = IMX_CS0_PHYS,
- .end = IMX_CS0_PHYS + SZ_32M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device flash_device = {
- .name = "physmap-flash",
- .id = 0,
- .resource = &flash_resource,
- .num_resources = 1,
-};
-
-/*
- * I2C
- */
-static struct pcf857x_platform_data pcf857x_data[] = {
- {
- .gpio_base = 4 * 32,
- }, {
- .gpio_base = 4 * 32 + 16,
- }
-};
-
-static struct imxi2c_platform_data mx1ads_i2c_data = {
- .bitrate = 100000,
-};
-
-static struct i2c_board_info mx1ads_i2c_devices[] = {
- {
- I2C_BOARD_INFO("pcf8575", 0x22),
- .platform_data = &pcf857x_data[0],
- }, {
- I2C_BOARD_INFO("pcf8575", 0x24),
- .platform_data = &pcf857x_data[1],
- },
-};
-
-/*
- * Board init
- */
-static void __init mx1ads_init(void)
-{
- mxc_gpio_setup_multiple_pins(mx1ads_pins,
- ARRAY_SIZE(mx1ads_pins), "mx1ads");
-
- /* UART */
- mxc_register_device(&imx_uart1_device, &uart_pdata[0]);
- mxc_register_device(&imx_uart2_device, &uart_pdata[1]);
-
- /* Physmap flash */
- mxc_register_device(&flash_device, &mx1ads_flash_data);
-
- /* I2C */
- i2c_register_board_info(0, mx1ads_i2c_devices,
- ARRAY_SIZE(mx1ads_i2c_devices));
-
- mxc_register_device(&imx_i2c_device, &mx1ads_i2c_data);
-}
-
-static void __init mx1ads_timer_init(void)
-{
- mx1_clocks_init(32000);
-}
-
-struct sys_timer mx1ads_timer = {
- .init = mx1ads_timer_init,
-};
-
-MACHINE_START(MX1ADS, "Freescale MX1ADS")
- /* Maintainer: Sascha Hauer, Pengutronix */
- .phys_io = IMX_IO_PHYS,
- .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx1_map_io,
- .init_irq = mx1_init_irq,
- .timer = &mx1ads_timer,
- .init_machine = mx1ads_init,
-MACHINE_END
-
-MACHINE_START(MXLADS, "Freescale MXLADS")
- .phys_io = IMX_IO_PHYS,
- .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx1_map_io,
- .init_irq = mx1_init_irq,
- .timer = &mx1ads_timer,
- .init_machine = mx1ads_init,
-MACHINE_END
diff --git a/arch/arm/mach-mx1/scb9328.c b/arch/arm/mach-mx1/scb9328.c
deleted file mode 100644
index 325d98df605..00000000000
--- a/arch/arm/mach-mx1/scb9328.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * linux/arch/arm/mach-mx1/scb9328.c
- *
- * Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
- * Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/interrupt.h>
-#include <linux/dm9000.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.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,
- .flags = IORESOURCE_MEM,
-};
-
-static struct physmap_flash_data scb_flash_data = {
- .width = 2,
-};
-
-static struct platform_device scb_flash_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &scb_flash_data,
- },
- .resource = &flash_resource,
- .num_resources = 1,
-};
-
-/*
- * scb9328 has a DM9000 network controller
- * connected to CS5, with 16 bit data path
- * and interrupt connected to GPIO 3
- */
-
-/*
- * internal datapath is fixed 16 bit
- */
-static struct dm9000_plat_data dm9000_platdata = {
- .flags = DM9000_PLATF_16BITONLY,
-};
-
-/*
- * the DM9000 drivers wants two defined address spaces
- * to gain access to address latch registers and the data path.
- */
-static struct resource dm9000x_resources[] = {
- {
- .name = "address area",
- .start = IMX_CS5_PHYS,
- .end = IMX_CS5_PHYS + 1,
- .flags = IORESOURCE_MEM, /* address access */
- }, {
- .name = "data area",
- .start = IMX_CS5_PHYS + 4,
- .end = IMX_CS5_PHYS + 5,
- .flags = IORESOURCE_MEM, /* data access */
- }, {
- .start = IRQ_GPIOC(3),
- .end = IRQ_GPIOC(3),
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
- },
-};
-
-static struct platform_device dm9000x_device = {
- .name = "dm9000",
- .id = 0,
- .num_resources = ARRAY_SIZE(dm9000x_resources),
- .resource = dm9000x_resources,
- .dev = {
- .platform_data = &dm9000_platdata,
- }
-};
-
-static int mxc_uart1_pins[] = {
- PC9_PF_UART1_CTS,
- PC10_PF_UART1_RTS,
- PC11_PF_UART1_TXD,
- PC12_PF_UART1_RXD,
-};
-
-static int uart1_mxc_init(struct platform_device *pdev)
-{
- return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
- ARRAY_SIZE(mxc_uart1_pins), "UART1");
-}
-
-static int 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 = {
- .init = uart1_mxc_init,
- .exit = uart1_mxc_exit,
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *devices[] __initdata = {
- &scb_flash_device,
- &dm9000x_device,
-};
-
-/*
- * scb9328_init - Init the CPU card itself
- */
-static void __init scb9328_init(void)
-{
- mxc_register_device(&imx_uart1_device, &uart_pdata);
-
- printk(KERN_INFO"Scb9328: Adding devices\n");
- platform_add_devices(devices, ARRAY_SIZE(devices));
-}
-
-static void __init scb9328_timer_init(void)
-{
- mx1_clocks_init(32000);
-}
-
-static struct sys_timer scb9328_timer = {
- .init = scb9328_timer_init,
-};
-
-MACHINE_START(SCB9328, "Synertronixx scb9328")
- /* Sascha Hauer */
- .phys_io = 0x00200000,
- .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
- .boot_params = 0x08000100,
- .map_io = mx1_map_io,
- .init_irq = mx1_init_irq,
- .timer = &scb9328_timer,
- .init_machine = scb9328_init,
-MACHINE_END
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig
index b96c6a38936..742fd4e6dcb 100644
--- a/arch/arm/mach-mx2/Kconfig
+++ b/arch/arm/mach-mx2/Kconfig
@@ -37,6 +37,7 @@ config MACH_MX27ADS
config MACH_PCM038
bool "Phytec phyCORE-i.MX27 CPU module (pcm038)"
depends on MACH_MX27
+ select MXC_ULPI if USB_ULPI
help
Include support for phyCORE-i.MX27 (aka pcm038) platform. This
includes specific configurations for the module and its peripherals.
@@ -55,7 +56,7 @@ config MACH_PCM970_BASEBOARD
endchoice
-config MACH_EUKREA_CPUIMX27
+config MACH_CPUIMX27
bool "Eukrea CPUIMX27 module"
depends on MACH_MX27
help
@@ -64,14 +65,14 @@ config MACH_EUKREA_CPUIMX27
config MACH_EUKREA_CPUIMX27_USESDHC2
bool "CPUIMX27 integrates SDHC2 module"
- depends on MACH_EUKREA_CPUIMX27
+ depends on MACH_CPUIMX27
help
This adds support for the internal SDHC2 used on CPUIMX27 used
for wifi or eMMC.
choice
prompt "Baseboard"
- depends on MACH_EUKREA_CPUIMX27
+ depends on MACH_CPUIMX27
default MACH_EUKREA_MBIMX27_BASEBOARD
config MACH_EUKREA_MBIMX27_BASEBOARD
@@ -90,7 +91,7 @@ config MACH_MX27_3DS
Include support for MX27PDK platform. This includes specific
configurations for the board and its peripherals.
-config MACH_MX27LITE
+config MACH_IMX27LITE
bool "LogicPD MX27 LITEKIT platform"
depends on MACH_MX27
help
@@ -100,6 +101,7 @@ config MACH_MX27LITE
config MACH_PCA100
bool "Phytec phyCARD-s (pca100)"
depends on MACH_MX27
+ select MXC_ULPI if USB_ULPI
help
Include support for phyCARD-s (aka pca100) platform. This
includes specific configurations for the module and its peripherals.
diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile
index 52aca0aaf9b..e3254faac82 100644
--- a/arch/arm/mach-mx2/Makefile
+++ b/arch/arm/mach-mx2/Makefile
@@ -4,21 +4,20 @@
# Object file lists.
-obj-y := generic.o devices.o serial.o
+obj-y := devices.o serial.o
-obj-$(CONFIG_MACH_MX21) += clock_imx21.o
+obj-$(CONFIG_MACH_MX21) += clock_imx21.o mm-imx21.o
obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
-obj-$(CONFIG_MACH_MX27) += clock_imx27.o
+obj-$(CONFIG_MACH_MX27) += clock_imx27.o mm-imx27.o
-obj-$(CONFIG_MACH_MX21ADS) += mx21ads.o
-obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o
-obj-$(CONFIG_MACH_PCM038) += pcm038.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
-obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o
-obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o
-obj-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27.o
+obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
+obj-$(CONFIG_MACH_IMX27LITE) += mach-imx27lite.o
+obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
-obj-$(CONFIG_MACH_PCA100) += pca100.o
-obj-$(CONFIG_MACH_MXT_TD60) += mxt_td60.o
-
+obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
+obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c
index e82b489d121..bb419ef4d13 100644
--- a/arch/arm/mach-mx2/clock_imx21.c
+++ b/arch/arm/mach-mx2/clock_imx21.c
@@ -23,11 +23,242 @@
#include <linux/module.h>
#include <mach/clock.h>
+#include <mach/hardware.h>
#include <mach/common.h>
#include <asm/clkdev.h>
#include <asm/div64.h>
-#include "crm_regs.h"
+#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
+
+/* Register offsets */
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
+#define CCM_PCDR0 IO_ADDR_CCM(0x18)
+#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0 IO_ADDR_CCM(0x20)
+#define CCM_PCCR1 IO_ADDR_CCM(0x24)
+#define CCM_CCSR IO_ADDR_CCM(0x28)
+#define CCM_PMCTL IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
+
+#define CCM_CSCR_PRESC_OFFSET 29
+#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
+
+#define CCM_CSCR_USB_OFFSET 26
+#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
+#define CCM_CSCR_SD_OFFSET 24
+#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
+#define CCM_CSCR_SPLLRES (1 << 22)
+#define CCM_CSCR_MPLLRES (1 << 21)
+#define CCM_CSCR_SSI2_OFFSET 20
+#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
+#define CCM_CSCR_SSI1_OFFSET 19
+#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
+#define CCM_CSCR_FIR_OFFSET 18
+#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
+#define CCM_CSCR_SP (1 << 17)
+#define CCM_CSCR_MCU (1 << 16)
+#define CCM_CSCR_BCLK_OFFSET 10
+#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
+#define CCM_CSCR_IPDIV_OFFSET 9
+#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
+
+#define CCM_CSCR_OSC26MDIV (1 << 4)
+#define CCM_CSCR_OSC26M (1 << 3)
+#define CCM_CSCR_FPM (1 << 2)
+#define CCM_CSCR_SPEN (1 << 1)
+#define CCM_CSCR_MPEN 1
+
+#define CCM_MPCTL0_CPLM (1 << 31)
+#define CCM_MPCTL0_PD_OFFSET 26
+#define CCM_MPCTL0_PD_MASK (0xf << 26)
+#define CCM_MPCTL0_MFD_OFFSET 16
+#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
+#define CCM_MPCTL0_MFI_OFFSET 10
+#define CCM_MPCTL0_MFI_MASK (0xf << 10)
+#define CCM_MPCTL0_MFN_OFFSET 0
+#define CCM_MPCTL0_MFN_MASK 0x3ff
+
+#define CCM_MPCTL1_LF (1 << 15)
+#define CCM_MPCTL1_BRMO (1 << 6)
+
+#define CCM_SPCTL0_CPLM (1 << 31)
+#define CCM_SPCTL0_PD_OFFSET 26
+#define CCM_SPCTL0_PD_MASK (0xf << 26)
+#define CCM_SPCTL0_MFD_OFFSET 16
+#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
+#define CCM_SPCTL0_MFI_OFFSET 10
+#define CCM_SPCTL0_MFI_MASK (0xf << 10)
+#define CCM_SPCTL0_MFN_OFFSET 0
+#define CCM_SPCTL0_MFN_MASK 0x3ff
+
+#define CCM_SPCTL1_LF (1 << 15)
+#define CCM_SPCTL1_BRMO (1 << 6)
+
+#define CCM_OSC26MCTL_PEAK_OFFSET 16
+#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
+#define CCM_OSC26MCTL_AGC_OFFSET 8
+#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
+#define CCM_OSC26MCTL_ANATEST_OFFSET 0
+#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
+
+#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
+#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
+#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
+#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
+#define CCM_PCDR0_NFCDIV_OFFSET 12
+#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
+#define CCM_PCDR0_48MDIV_OFFSET 5
+#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
+#define CCM_PCDR0_FIRIDIV_OFFSET 0
+#define CCM_PCDR0_FIRIDIV_MASK 0x1f
+#define CCM_PCDR1_PERDIV4_OFFSET 24
+#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
+#define CCM_PCDR1_PERDIV3_OFFSET 16
+#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
+#define CCM_PCDR1_PERDIV2_OFFSET 8
+#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
+#define CCM_PCDR1_PERDIV1_OFFSET 0
+#define CCM_PCDR1_PERDIV1_MASK 0x3f
+
+#define CCM_PCCR_HCLK_CSI_OFFSET 31
+#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_DMA_OFFSET 30
+#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_BROM_OFFSET 28
+#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_EMMA_OFFSET 27
+#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_LCDC_OFFSET 26
+#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
+#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
+#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_BMI_OFFSET 23
+#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
+#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
+#define CCM_PCCR_PERCLK4_OFFSET 22
+#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
+#define CCM_PCCR_SLCDC_OFFSET 21
+#define CCM_PCCR_SLCDC_REG CCM_PCCR0
+#define CCM_PCCR_FIRI_BAUD_OFFSET 20
+#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
+#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_NFC_OFFSET 19
+#define CCM_PCCR_NFC_REG CCM_PCCR0
+#define CCM_PCCR_LCDC_OFFSET 18
+#define CCM_PCCR_LCDC_REG CCM_PCCR0
+#define CCM_PCCR_SSI1_BAUD_OFFSET 17
+#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_SSI2_BAUD_OFFSET 16
+#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_EMMA_OFFSET 15
+#define CCM_PCCR_EMMA_REG CCM_PCCR0
+#define CCM_PCCR_USBOTG_OFFSET 14
+#define CCM_PCCR_USBOTG_REG CCM_PCCR0
+#define CCM_PCCR_DMA_OFFSET 13
+#define CCM_PCCR_DMA_REG CCM_PCCR0
+#define CCM_PCCR_I2C1_OFFSET 12
+#define CCM_PCCR_I2C1_REG CCM_PCCR0
+#define CCM_PCCR_GPIO_OFFSET 11
+#define CCM_PCCR_GPIO_REG CCM_PCCR0
+#define CCM_PCCR_SDHC2_OFFSET 10
+#define CCM_PCCR_SDHC2_REG CCM_PCCR0
+#define CCM_PCCR_SDHC1_OFFSET 9
+#define CCM_PCCR_SDHC1_REG CCM_PCCR0
+#define CCM_PCCR_FIRI_OFFSET 8
+#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
+#define CCM_PCCR_FIRI_REG CCM_PCCR0
+#define CCM_PCCR_SSI2_IPG_OFFSET 7
+#define CCM_PCCR_SSI2_REG CCM_PCCR0
+#define CCM_PCCR_SSI1_IPG_OFFSET 6
+#define CCM_PCCR_SSI1_REG CCM_PCCR0
+#define CCM_PCCR_CSPI2_OFFSET 5
+#define CCM_PCCR_CSPI2_REG CCM_PCCR0
+#define CCM_PCCR_CSPI1_OFFSET 4
+#define CCM_PCCR_CSPI1_REG CCM_PCCR0
+#define CCM_PCCR_UART4_OFFSET 3
+#define CCM_PCCR_UART4_REG CCM_PCCR0
+#define CCM_PCCR_UART3_OFFSET 2
+#define CCM_PCCR_UART3_REG CCM_PCCR0
+#define CCM_PCCR_UART2_OFFSET 1
+#define CCM_PCCR_UART2_REG CCM_PCCR0
+#define CCM_PCCR_UART1_OFFSET 0
+#define CCM_PCCR_UART1_REG CCM_PCCR0
+
+#define CCM_PCCR_OWIRE_OFFSET 31
+#define CCM_PCCR_OWIRE_REG CCM_PCCR1
+#define CCM_PCCR_KPP_OFFSET 30
+#define CCM_PCCR_KPP_REG CCM_PCCR1
+#define CCM_PCCR_RTC_OFFSET 29
+#define CCM_PCCR_RTC_REG CCM_PCCR1
+#define CCM_PCCR_PWM_OFFSET 28
+#define CCM_PCCR_PWM_REG CCM_PCCR1
+#define CCM_PCCR_GPT3_OFFSET 27
+#define CCM_PCCR_GPT3_REG CCM_PCCR1
+#define CCM_PCCR_GPT2_OFFSET 26
+#define CCM_PCCR_GPT2_REG CCM_PCCR1
+#define CCM_PCCR_GPT1_OFFSET 25
+#define CCM_PCCR_GPT1_REG CCM_PCCR1
+#define CCM_PCCR_WDT_OFFSET 24
+#define CCM_PCCR_WDT_REG CCM_PCCR1
+#define CCM_PCCR_CSPI3_OFFSET 23
+#define CCM_PCCR_CSPI3_REG CCM_PCCR1
+
+#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
+#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
+#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
+#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
+#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
+#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
+#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
+#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
+#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
+#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
+#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
+#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
+#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
+#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
+#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
+#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
+#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
+#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
+#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
+#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
+#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
+#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
+#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
+#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
+#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
+#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
+#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
+#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
+#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
+#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
+#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
+#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
+#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
+#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
+#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
+#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
+#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
+
+#define CCM_CCSR_32KSR (1 << 15)
+
+#define CCM_CCSR_CLKMODE1 (1 << 9)
+#define CCM_CCSR_CLKMODE0 (1 << 8)
+
+#define CCM_CCSR_CLKOSEL_OFFSET 0
+#define CCM_CCSR_CLKOSEL_MASK 0x1f
+
+#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
+#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
static int _clk_enable(struct clk *clk)
{
@@ -1002,6 +1233,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
clk_enable(&uart_clk[0]);
#endif
- mxc_timer_init(&gpt_clk[0], IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1);
+ mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
+ MX21_INT_GPT1);
return 0;
}
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c
index 18c53a6487f..0f0823c8b17 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-mx2/clock_imx27.c
@@ -29,21 +29,23 @@
#include <mach/common.h>
#include <mach/hardware.h>
+#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
+
/* Register offsets */
-#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0)
-#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4)
-#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8)
-#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC)
-#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10)
-#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14)
-#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18)
-#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c)
-#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20)
-#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24)
-#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28)
-#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c)
-#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
-#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
+#define CCM_PCDR0 IO_ADDR_CCM(0x18)
+#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0 IO_ADDR_CCM(0x20)
+#define CCM_PCCR1 IO_ADDR_CCM(0x24)
+#define CCM_CCSR IO_ADDR_CCM(0x28)
+#define CCM_PMCTL IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
#define CCM_CSCR_UPDATE_DIS (1 << 31)
#define CCM_CSCR_SSI2 (1 << 23)
@@ -753,7 +755,8 @@ int __init mx27_clocks_init(unsigned long fref)
clk_enable(&uart1_clk);
#endif
- mxc_timer_init(&gpt1_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1);
+ mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
+ MX27_INT_GPT1);
return 0;
}
diff --git a/arch/arm/mach-mx2/cpu_imx27.c b/arch/arm/mach-mx2/cpu_imx27.c
index d9e3bf9644c..d8d3b2d84dc 100644
--- a/arch/arm/mach-mx2/cpu_imx27.c
+++ b/arch/arm/mach-mx2/cpu_imx27.c
@@ -39,7 +39,8 @@ static void query_silicon_parameter(void)
* the silicon revision very early we read it here to
* avoid any further hooks
*/
- val = __raw_readl(IO_ADDRESS(SYSCTRL_BASE_ADDR) + SYS_CHIP_ID);
+ val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR
+ + SYS_CHIP_ID));
cpu_silicon_rev = (int)(val >> 28);
cpu_partnumber = (int)((val >> 12) & 0xFFFF);
diff --git a/arch/arm/mach-mx2/crm_regs.h b/arch/arm/mach-mx2/crm_regs.h
deleted file mode 100644
index 749de76b3f9..00000000000
--- a/arch/arm/mach-mx2/crm_regs.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright 2004-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.
- */
-
-#ifndef __ARCH_ARM_MACH_MX2_CRM_REGS_H__
-#define __ARCH_ARM_MACH_MX2_CRM_REGS_H__
-
-#include <mach/hardware.h>
-
-/* Register offsets */
-#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0)
-#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4)
-#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8)
-#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC)
-#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10)
-#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14)
-#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18)
-#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c)
-#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20)
-#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24)
-#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28)
-#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c)
-#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
-#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
-
-#define CCM_CSCR_PRESC_OFFSET 29
-#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
-
-#define CCM_CSCR_USB_OFFSET 26
-#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
-#define CCM_CSCR_SD_OFFSET 24
-#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
-#define CCM_CSCR_SPLLRES (1 << 22)
-#define CCM_CSCR_MPLLRES (1 << 21)
-#define CCM_CSCR_SSI2_OFFSET 20
-#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
-#define CCM_CSCR_SSI1_OFFSET 19
-#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
-#define CCM_CSCR_FIR_OFFSET 18
-#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
-#define CCM_CSCR_SP (1 << 17)
-#define CCM_CSCR_MCU (1 << 16)
-#define CCM_CSCR_BCLK_OFFSET 10
-#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
-#define CCM_CSCR_IPDIV_OFFSET 9
-#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
-
-#define CCM_CSCR_OSC26MDIV (1 << 4)
-#define CCM_CSCR_OSC26M (1 << 3)
-#define CCM_CSCR_FPM (1 << 2)
-#define CCM_CSCR_SPEN (1 << 1)
-#define CCM_CSCR_MPEN 1
-
-
-
-#define CCM_MPCTL0_CPLM (1 << 31)
-#define CCM_MPCTL0_PD_OFFSET 26
-#define CCM_MPCTL0_PD_MASK (0xf << 26)
-#define CCM_MPCTL0_MFD_OFFSET 16
-#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
-#define CCM_MPCTL0_MFI_OFFSET 10
-#define CCM_MPCTL0_MFI_MASK (0xf << 10)
-#define CCM_MPCTL0_MFN_OFFSET 0
-#define CCM_MPCTL0_MFN_MASK 0x3ff
-
-#define CCM_MPCTL1_LF (1 << 15)
-#define CCM_MPCTL1_BRMO (1 << 6)
-
-#define CCM_SPCTL0_CPLM (1 << 31)
-#define CCM_SPCTL0_PD_OFFSET 26
-#define CCM_SPCTL0_PD_MASK (0xf << 26)
-#define CCM_SPCTL0_MFD_OFFSET 16
-#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
-#define CCM_SPCTL0_MFI_OFFSET 10
-#define CCM_SPCTL0_MFI_MASK (0xf << 10)
-#define CCM_SPCTL0_MFN_OFFSET 0
-#define CCM_SPCTL0_MFN_MASK 0x3ff
-
-#define CCM_SPCTL1_LF (1 << 15)
-#define CCM_SPCTL1_BRMO (1 << 6)
-
-#define CCM_OSC26MCTL_PEAK_OFFSET 16
-#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
-#define CCM_OSC26MCTL_AGC_OFFSET 8
-#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
-#define CCM_OSC26MCTL_ANATEST_OFFSET 0
-#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
-
-#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
-#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
-#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
-#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
-#define CCM_PCDR0_NFCDIV_OFFSET 12
-#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
-#define CCM_PCDR0_48MDIV_OFFSET 5
-#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
-#define CCM_PCDR0_FIRIDIV_OFFSET 0
-#define CCM_PCDR0_FIRIDIV_MASK 0x1f
-#define CCM_PCDR1_PERDIV4_OFFSET 24
-#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
-#define CCM_PCDR1_PERDIV3_OFFSET 16
-#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
-#define CCM_PCDR1_PERDIV2_OFFSET 8
-#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
-#define CCM_PCDR1_PERDIV1_OFFSET 0
-#define CCM_PCDR1_PERDIV1_MASK 0x3f
-
-#define CCM_PCCR_HCLK_CSI_OFFSET 31
-#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_DMA_OFFSET 30
-#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_BROM_OFFSET 28
-#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_EMMA_OFFSET 27
-#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_LCDC_OFFSET 26
-#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
-#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
-#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_BMI_OFFSET 23
-#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
-#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
-#define CCM_PCCR_PERCLK4_OFFSET 22
-#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
-#define CCM_PCCR_SLCDC_OFFSET 21
-#define CCM_PCCR_SLCDC_REG CCM_PCCR0
-#define CCM_PCCR_FIRI_BAUD_OFFSET 20
-#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
-#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
-#define CCM_PCCR_NFC_OFFSET 19
-#define CCM_PCCR_NFC_REG CCM_PCCR0
-#define CCM_PCCR_LCDC_OFFSET 18
-#define CCM_PCCR_LCDC_REG CCM_PCCR0
-#define CCM_PCCR_SSI1_BAUD_OFFSET 17
-#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
-#define CCM_PCCR_SSI2_BAUD_OFFSET 16
-#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
-#define CCM_PCCR_EMMA_OFFSET 15
-#define CCM_PCCR_EMMA_REG CCM_PCCR0
-#define CCM_PCCR_USBOTG_OFFSET 14
-#define CCM_PCCR_USBOTG_REG CCM_PCCR0
-#define CCM_PCCR_DMA_OFFSET 13
-#define CCM_PCCR_DMA_REG CCM_PCCR0
-#define CCM_PCCR_I2C1_OFFSET 12
-#define CCM_PCCR_I2C1_REG CCM_PCCR0
-#define CCM_PCCR_GPIO_OFFSET 11
-#define CCM_PCCR_GPIO_REG CCM_PCCR0
-#define CCM_PCCR_SDHC2_OFFSET 10
-#define CCM_PCCR_SDHC2_REG CCM_PCCR0
-#define CCM_PCCR_SDHC1_OFFSET 9
-#define CCM_PCCR_SDHC1_REG CCM_PCCR0
-#define CCM_PCCR_FIRI_OFFSET 8
-#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
-#define CCM_PCCR_FIRI_REG CCM_PCCR0
-#define CCM_PCCR_SSI2_IPG_OFFSET 7
-#define CCM_PCCR_SSI2_REG CCM_PCCR0
-#define CCM_PCCR_SSI1_IPG_OFFSET 6
-#define CCM_PCCR_SSI1_REG CCM_PCCR0
-#define CCM_PCCR_CSPI2_OFFSET 5
-#define CCM_PCCR_CSPI2_REG CCM_PCCR0
-#define CCM_PCCR_CSPI1_OFFSET 4
-#define CCM_PCCR_CSPI1_REG CCM_PCCR0
-#define CCM_PCCR_UART4_OFFSET 3
-#define CCM_PCCR_UART4_REG CCM_PCCR0
-#define CCM_PCCR_UART3_OFFSET 2
-#define CCM_PCCR_UART3_REG CCM_PCCR0
-#define CCM_PCCR_UART2_OFFSET 1
-#define CCM_PCCR_UART2_REG CCM_PCCR0
-#define CCM_PCCR_UART1_OFFSET 0
-#define CCM_PCCR_UART1_REG CCM_PCCR0
-
-#define CCM_PCCR_OWIRE_OFFSET 31
-#define CCM_PCCR_OWIRE_REG CCM_PCCR1
-#define CCM_PCCR_KPP_OFFSET 30
-#define CCM_PCCR_KPP_REG CCM_PCCR1
-#define CCM_PCCR_RTC_OFFSET 29
-#define CCM_PCCR_RTC_REG CCM_PCCR1
-#define CCM_PCCR_PWM_OFFSET 28
-#define CCM_PCCR_PWM_REG CCM_PCCR1
-#define CCM_PCCR_GPT3_OFFSET 27
-#define CCM_PCCR_GPT3_REG CCM_PCCR1
-#define CCM_PCCR_GPT2_OFFSET 26
-#define CCM_PCCR_GPT2_REG CCM_PCCR1
-#define CCM_PCCR_GPT1_OFFSET 25
-#define CCM_PCCR_GPT1_REG CCM_PCCR1
-#define CCM_PCCR_WDT_OFFSET 24
-#define CCM_PCCR_WDT_REG CCM_PCCR1
-#define CCM_PCCR_CSPI3_OFFSET 23
-#define CCM_PCCR_CSPI3_REG CCM_PCCR1
-
-#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
-#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
-#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
-#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
-#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
-#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
-#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
-#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
-#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
-#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
-#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
-#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
-#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
-#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
-#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
-#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
-#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
-#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
-#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
-#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
-#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
-#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
-#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
-#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
-#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
-#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
-#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
-#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
-#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
-#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
-#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
-#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
-#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
-#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
-#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
-#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
-#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
-
-
-#define CCM_CCSR_32KSR (1 << 15)
-
-#define CCM_CCSR_CLKMODE1 (1 << 9)
-#define CCM_CCSR_CLKMODE0 (1 << 8)
-
-#define CCM_CCSR_CLKOSEL_OFFSET 0
-#define CCM_CCSR_CLKOSEL_MASK 0x1f
-
-#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
-#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
-
-#endif /* __ARCH_ARM_MACH_MX2_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c
index 3956d82b7c4..b91e412f7b3 100644
--- a/arch/arm/mach-mx2/devices.c
+++ b/arch/arm/mach-mx2/devices.c
@@ -47,65 +47,31 @@
* - i.MX21: 2 channel
* - i.MX27: 3 channel
*/
-static struct resource mxc_spi_resources0[] = {
- {
- .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_resources1[] = {
- {
- .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,
- },
-};
-
-#ifdef CONFIG_MACH_MX27
-static struct resource mxc_spi_resources2[] = {
- {
- .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,
- },
-};
-#endif
-
-struct platform_device mxc_spi_device0 = {
- .name = "spi_imx",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_spi_resources0),
- .resource = mxc_spi_resources0,
-};
+#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, \
+ }
-struct platform_device mxc_spi_device1 = {
- .name = "spi_imx",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxc_spi_resources1),
- .resource = mxc_spi_resources1,
-};
+DEFINE_IMX_SPI_DEVICE(0, MX2x_CSPI1_BASE_ADDR, MX2x_INT_CSPI1);
+DEFINE_IMX_SPI_DEVICE(1, MX2x_CSPI2_BASE_ADDR, MX2x_INT_CSPI2);
#ifdef CONFIG_MACH_MX27
-struct platform_device mxc_spi_device2 = {
- .name = "spi_imx",
- .id = 2,
- .num_resources = ARRAY_SIZE(mxc_spi_resources2),
- .resource = mxc_spi_resources2,
-};
+DEFINE_IMX_SPI_DEVICE(2, MX27_CSPI3_BASE_ADDR, MX27_INT_CSPI3);
#endif
/*
@@ -113,104 +79,34 @@ struct platform_device mxc_spi_device2 = {
* - i.MX21: 3 timers
* - i.MX27: 6 timers
*/
-
-/* We use gpt0 as system timer, so do not add a device for this one */
-
-static struct resource timer1_resources[] = {
- {
- .start = GPT2_BASE_ADDR,
- .end = GPT2_BASE_ADDR + 0x17,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_GPT2,
- .end = MXC_INT_GPT2,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_gpt1 = {
- .name = "imx_gpt",
- .id = 1,
- .num_resources = ARRAY_SIZE(timer1_resources),
- .resource = timer1_resources,
-};
-
-static struct resource timer2_resources[] = {
- {
- .start = GPT3_BASE_ADDR,
- .end = GPT3_BASE_ADDR + 0x17,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_GPT3,
- .end = MXC_INT_GPT3,
- .flags = IORESOURCE_IRQ,
+#define DEFINE_IMX_GPT_DEVICE(n, baseaddr, irq) \
+ static struct resource timer ## n ##_resources[] = { \
+ { \
+ .start = baseaddr, \
+ .end = baseaddr + SZ_4K - 1, \
+ .flags = IORESOURCE_MEM, \
+ }, { \
+ .start = irq, \
+ .end = irq, \
+ .flags = IORESOURCE_IRQ, \
+ } \
+ }; \
+ \
+ struct platform_device mxc_gpt ## n = { \
+ .name = "imx_gpt", \
+ .id = n, \
+ .num_resources = ARRAY_SIZE(timer ## n ## _resources), \
+ .resource = timer ## n ## _resources, \
}
-};
-struct platform_device mxc_gpt2 = {
- .name = "imx_gpt",
- .id = 2,
- .num_resources = ARRAY_SIZE(timer2_resources),
- .resource = timer2_resources,
-};
+/* We use gpt1 as system timer, so do not add a device for this one */
+DEFINE_IMX_GPT_DEVICE(1, MX2x_GPT2_BASE_ADDR, MX2x_INT_GPT2);
+DEFINE_IMX_GPT_DEVICE(2, MX2x_GPT3_BASE_ADDR, MX2x_INT_GPT3);
#ifdef CONFIG_MACH_MX27
-static struct resource timer3_resources[] = {
- {
- .start = GPT4_BASE_ADDR,
- .end = GPT4_BASE_ADDR + 0x17,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_GPT4,
- .end = MXC_INT_GPT4,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_gpt3 = {
- .name = "imx_gpt",
- .id = 3,
- .num_resources = ARRAY_SIZE(timer3_resources),
- .resource = timer3_resources,
-};
-
-static struct resource timer4_resources[] = {
- {
- .start = GPT5_BASE_ADDR,
- .end = GPT5_BASE_ADDR + 0x17,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_GPT5,
- .end = MXC_INT_GPT5,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_gpt4 = {
- .name = "imx_gpt",
- .id = 4,
- .num_resources = ARRAY_SIZE(timer4_resources),
- .resource = timer4_resources,
-};
-
-static struct resource timer5_resources[] = {
- {
- .start = GPT6_BASE_ADDR,
- .end = GPT6_BASE_ADDR + 0x17,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_GPT6,
- .end = MXC_INT_GPT6,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_gpt5 = {
- .name = "imx_gpt",
- .id = 5,
- .num_resources = ARRAY_SIZE(timer5_resources),
- .resource = timer5_resources,
-};
+DEFINE_IMX_GPT_DEVICE(3, MX27_GPT4_BASE_ADDR, MX27_INT_GPT4);
+DEFINE_IMX_GPT_DEVICE(4, MX27_GPT5_BASE_ADDR, MX27_INT_GPT5);
+DEFINE_IMX_GPT_DEVICE(5, MX27_GPT6_BASE_ADDR, MX27_INT_GPT6);
#endif
/*
@@ -221,9 +117,9 @@ struct platform_device mxc_gpt5 = {
*/
static struct resource mxc_wdt_resources[] = {
{
- .start = WDOG_BASE_ADDR,
- .end = WDOG_BASE_ADDR + 0x30,
- .flags = IORESOURCE_MEM,
+ .start = MX2x_WDOG_BASE_ADDR,
+ .end = MX2x_WDOG_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
},
};
@@ -236,8 +132,8 @@ struct platform_device mxc_wdt = {
static struct resource mxc_w1_master_resources[] = {
{
- .start = OWIRE_BASE_ADDR,
- .end = OWIRE_BASE_ADDR + SZ_4K - 1,
+ .start = MX2x_OWIRE_BASE_ADDR,
+ .end = MX2x_OWIRE_BASE_ADDR + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
@@ -249,24 +145,33 @@ struct platform_device mxc_w1_master_device = {
.resource = mxc_w1_master_resources,
};
-static struct resource mxc_nand_resources[] = {
- {
- .start = NFC_BASE_ADDR,
- .end = NFC_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_NANDFC,
- .end = MXC_INT_NANDFC,
- .flags = IORESOURCE_IRQ,
- },
-};
+#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, \
+ }
-struct platform_device mxc_nand_device = {
- .name = "mxc_nand",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_nand_resources),
- .resource = mxc_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:
@@ -276,12 +181,12 @@ struct platform_device mxc_nand_device = {
*/
static struct resource mxc_fb[] = {
{
- .start = LCDC_BASE_ADDR,
- .end = LCDC_BASE_ADDR + 0xFFF,
+ .start = MX2x_LCDC_BASE_ADDR,
+ .end = MX2x_LCDC_BASE_ADDR + SZ_4K - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_LCDC,
- .end = MXC_INT_LCDC,
+ .start = MX2x_INT_LCDC,
+ .end = MX2x_INT_LCDC,
.flags = IORESOURCE_IRQ,
}
};
@@ -300,13 +205,13 @@ struct platform_device mxc_fb_device = {
#ifdef CONFIG_MACH_MX27
static struct resource mxc_fec_resources[] = {
{
- .start = FEC_BASE_ADDR,
- .end = FEC_BASE_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
+ .start = MX27_FEC_BASE_ADDR,
+ .end = MX27_FEC_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_FEC,
- .end = MXC_INT_FEC,
- .flags = IORESOURCE_IRQ,
+ .start = MX27_INT_FEC,
+ .end = MX27_INT_FEC,
+ .flags = IORESOURCE_IRQ,
},
};
@@ -318,55 +223,41 @@ struct platform_device mxc_fec_device = {
};
#endif
-static struct resource mxc_i2c_1_resources[] = {
- {
- .start = I2C_BASE_ADDR,
- .end = I2C_BASE_ADDR + 0x0fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_I2C,
- .end = MXC_INT_I2C,
- .flags = IORESOURCE_IRQ,
+#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, \
}
-};
-struct platform_device mxc_i2c_device0 = {
- .name = "imx-i2c",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
- .resource = mxc_i2c_1_resources,
-};
+DEFINE_IMX_I2C_DEVICE(0, MX2x_I2C_BASE_ADDR, MX2x_INT_I2C);
#ifdef CONFIG_MACH_MX27
-static struct resource mxc_i2c_2_resources[] = {
- {
- .start = I2C2_BASE_ADDR,
- .end = I2C2_BASE_ADDR + 0x0fff,
- .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_i2c_2_resources),
- .resource = mxc_i2c_2_resources,
-};
+DEFINE_IMX_I2C_DEVICE(1, MX27_I2C2_BASE_ADDR, MX27_INT_I2C2);
#endif
static struct resource mxc_pwm_resources[] = {
{
- .start = PWM_BASE_ADDR,
- .end = PWM_BASE_ADDR + 0x0fff,
- .flags = IORESOURCE_MEM,
+ .start = MX2x_PWM_BASE_ADDR,
+ .end = MX2x_PWM_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_PWM,
- .end = MXC_INT_PWM,
- .flags = IORESOURCE_IRQ,
+ .start = MX2x_INT_PWM,
+ .end = MX2x_INT_PWM,
+ .flags = IORESOURCE_IRQ,
}
};
@@ -377,77 +268,49 @@ struct platform_device mxc_pwm_device = {
.resource = mxc_pwm_resources,
};
-/*
- * Resource definition for the MXC SDHC
- */
-static struct resource mxc_sdhc1_resources[] = {
- {
- .start = SDHC1_BASE_ADDR,
- .end = SDHC1_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_SDHC1,
- .end = MXC_INT_SDHC1,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = DMA_REQ_SDHC1,
- .end = DMA_REQ_SDHC1,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static u64 mxc_sdhc1_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device mxc_sdhc_device0 = {
- .name = "mxc-mmc",
- .id = 0,
- .dev = {
- .dma_mask = &mxc_sdhc1_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .num_resources = ARRAY_SIZE(mxc_sdhc1_resources),
- .resource = mxc_sdhc1_resources,
-};
-
-static struct resource mxc_sdhc2_resources[] = {
- {
- .start = SDHC2_BASE_ADDR,
- .end = SDHC2_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_SDHC2,
- .end = MXC_INT_SDHC2,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = DMA_REQ_SDHC2,
- .end = DMA_REQ_SDHC2,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static u64 mxc_sdhc2_dmamask = DMA_BIT_MASK(32);
+#define DEFINE_MXC_MMC_DEVICE(n, baseaddr, irq, dmareq) \
+ static struct resource mxc_sdhc_resources ## n[] = { \
+ { \
+ .start = baseaddr, \
+ .end = baseaddr + SZ_4K - 1, \
+ .flags = IORESOURCE_MEM, \
+ }, { \
+ .start = irq, \
+ .end = irq, \
+ .flags = IORESOURCE_IRQ, \
+ }, { \
+ .start = dmareq, \
+ .end = dmareq, \
+ .flags = IORESOURCE_DMA, \
+ }, \
+ }; \
+ \
+ static u64 mxc_sdhc ## n ## _dmamask = DMA_BIT_MASK(32); \
+ \
+ struct platform_device mxc_sdhc_device ## n = { \
+ .name = "mxc-mmc", \
+ .id = n, \
+ .dev = { \
+ .dma_mask = &mxc_sdhc ## n ## _dmamask, \
+ .coherent_dma_mask = DMA_BIT_MASK(32), \
+ }, \
+ .num_resources = ARRAY_SIZE(mxc_sdhc_resources ## n), \
+ .resource = mxc_sdhc_resources ## n, \
+ }
-struct platform_device mxc_sdhc_device1 = {
- .name = "mxc-mmc",
- .id = 1,
- .dev = {
- .dma_mask = &mxc_sdhc2_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .num_resources = ARRAY_SIZE(mxc_sdhc2_resources),
- .resource = mxc_sdhc2_resources,
-};
+DEFINE_MXC_MMC_DEVICE(0, MX2x_SDHC1_BASE_ADDR, MX2x_INT_SDHC1, MX2x_DMA_REQ_SDHC1);
+DEFINE_MXC_MMC_DEVICE(1, MX2x_SDHC2_BASE_ADDR, MX2x_INT_SDHC2, MX2x_DMA_REQ_SDHC2);
#ifdef CONFIG_MACH_MX27
static struct resource otg_resources[] = {
{
- .start = OTG_BASE_ADDR,
- .end = OTG_BASE_ADDR + 0x1ff,
- .flags = IORESOURCE_MEM,
+ .start = MX27_USBOTG_BASE_ADDR,
+ .end = MX27_USBOTG_BASE_ADDR + 0x1ff,
+ .flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_USB3,
- .end = MXC_INT_USB3,
- .flags = IORESOURCE_IRQ,
+ .start = MX27_INT_USB3,
+ .end = MX27_INT_USB3,
+ .flags = IORESOURCE_IRQ,
},
};
@@ -483,12 +346,12 @@ static u64 usbh1_dmamask = DMA_BIT_MASK(32);
static struct resource mxc_usbh1_resources[] = {
{
- .start = OTG_BASE_ADDR + 0x200,
- .end = OTG_BASE_ADDR + 0x3ff,
+ .start = MX27_USBOTG_BASE_ADDR + 0x200,
+ .end = MX27_USBOTG_BASE_ADDR + 0x3ff,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_USB1,
- .end = MXC_INT_USB1,
+ .start = MX27_INT_USB1,
+ .end = MX27_INT_USB1,
.flags = IORESOURCE_IRQ,
},
};
@@ -509,12 +372,12 @@ static u64 usbh2_dmamask = DMA_BIT_MASK(32);
static struct resource mxc_usbh2_resources[] = {
{
- .start = OTG_BASE_ADDR + 0x400,
- .end = OTG_BASE_ADDR + 0x5ff,
+ .start = MX27_USBOTG_BASE_ADDR + 0x400,
+ .end = MX27_USBOTG_BASE_ADDR + 0x5ff,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_USB2,
- .end = MXC_INT_USB2,
+ .start = MX27_INT_USB2,
+ .end = MX27_INT_USB2,
.flags = IORESOURCE_IRQ,
},
};
@@ -531,129 +394,102 @@ struct platform_device mxc_usbh2 = {
};
#endif
-static struct resource imx_ssi_resources0[] = {
- {
- .start = SSI1_BASE_ADDR,
- .end = SSI1_BASE_ADDR + 0x6F,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_SSI1,
- .end = MXC_INT_SSI1,
- .flags = IORESOURCE_IRQ,
- }, {
- .name = "tx0",
- .start = DMA_REQ_SSI1_TX0,
- .end = DMA_REQ_SSI1_TX0,
- .flags = IORESOURCE_DMA,
- }, {
- .name = "rx0",
- .start = DMA_REQ_SSI1_RX0,
- .end = DMA_REQ_SSI1_RX0,
- .flags = IORESOURCE_DMA,
- }, {
- .name = "tx1",
- .start = DMA_REQ_SSI1_TX1,
- .end = DMA_REQ_SSI1_TX1,
- .flags = IORESOURCE_DMA,
- }, {
- .name = "rx1",
- .start = DMA_REQ_SSI1_RX1,
- .end = DMA_REQ_SSI1_RX1,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static struct resource imx_ssi_resources1[] = {
- {
- .start = SSI2_BASE_ADDR,
- .end = SSI2_BASE_ADDR + 0x6F,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_SSI2,
- .end = MXC_INT_SSI2,
- .flags = IORESOURCE_IRQ,
- }, {
- .name = "tx0",
- .start = DMA_REQ_SSI2_TX0,
- .end = DMA_REQ_SSI2_TX0,
- .flags = IORESOURCE_DMA,
- }, {
- .name = "rx0",
- .start = DMA_REQ_SSI2_RX0,
- .end = DMA_REQ_SSI2_RX0,
- .flags = IORESOURCE_DMA,
- }, {
- .name = "tx1",
- .start = DMA_REQ_SSI2_TX1,
- .end = DMA_REQ_SSI2_TX1,
- .flags = IORESOURCE_DMA,
- }, {
- .name = "rx1",
- .start = DMA_REQ_SSI2_RX1,
- .end = DMA_REQ_SSI2_RX1,
- .flags = IORESOURCE_DMA,
- },
-};
+#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix) \
+ { \
+ .name = _name, \
+ .start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
+ .end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \
+ .flags = IORESOURCE_DMA, \
+ }
-struct platform_device imx_ssi_device0 = {
- .name = "imx-ssi",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_ssi_resources0),
- .resource = imx_ssi_resources0,
-};
+#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq) \
+ static struct resource imx_ssi_resources ## n[] = { \
+ { \
+ .start = MX2x_SSI ## ssin ## _BASE_ADDR, \
+ .end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f, \
+ .flags = IORESOURCE_MEM, \
+ }, { \
+ .start = MX2x_INT_SSI1, \
+ .end = MX2x_INT_SSI1, \
+ .flags = IORESOURCE_IRQ, \
+ }, \
+ DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0), \
+ DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0), \
+ DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1), \
+ DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1), \
+ }; \
+ \
+ struct platform_device imx_ssi_device ## n = { \
+ .name = "imx-ssi", \
+ .id = n, \
+ .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \
+ .resource = imx_ssi_resources ## n, \
+ }
-struct platform_device imx_ssi_device1 = {
- .name = "imx-ssi",
- .id = 1,
- .num_resources = ARRAY_SIZE(imx_ssi_resources1),
- .resource = imx_ssi_resources1,
-};
+DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
+DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
/* GPIO port description */
-static struct mxc_gpio_port imx_gpio_ports[] = {
- {
- .chip.label = "gpio-0",
- .irq = MXC_INT_GPIO,
- .base = IO_ADDRESS(GPIO_BASE_ADDR),
- .virtual_irq_start = MXC_GPIO_IRQ_START,
- }, {
- .chip.label = "gpio-1",
- .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
- .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
- }, {
- .chip.label = "gpio-2",
- .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
- .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
- }, {
- .chip.label = "gpio-3",
- .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
- .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
- }, {
- .chip.label = "gpio-4",
- .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
- .virtual_irq_start = MXC_GPIO_IRQ_START + 128,
- }, {
- .chip.label = "gpio-5",
- .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
- .virtual_irq_start = MXC_GPIO_IRQ_START + 160,
+#define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq) \
+ { \
+ .chip.label = "gpio-" #n, \
+ .irq = _irq, \
+ .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \
+ n * 0x100), \
+ .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
}
-};
+
+#define DEFINE_MXC_GPIO_PORT(SOC, n) \
+ { \
+ .chip.label = "gpio-" #n, \
+ .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \
+ n * 0x100), \
+ .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
+ }
+
+#define DEFINE_MXC_GPIO_PORTS(SOC, pfx) \
+ static struct mxc_gpio_port pfx ## _gpio_ports[] = { \
+ DEFINE_MXC_GPIO_PORT_IRQ(SOC, 0, SOC ## _INT_GPIO), \
+ DEFINE_MXC_GPIO_PORT(SOC, 1), \
+ DEFINE_MXC_GPIO_PORT(SOC, 2), \
+ DEFINE_MXC_GPIO_PORT(SOC, 3), \
+ DEFINE_MXC_GPIO_PORT(SOC, 4), \
+ DEFINE_MXC_GPIO_PORT(SOC, 5), \
+ }
+
+#ifdef CONFIG_MACH_MX21
+DEFINE_MXC_GPIO_PORTS(MX21, imx21);
+#endif
+
+#ifdef CONFIG_MACH_MX27
+DEFINE_MXC_GPIO_PORTS(MX27, imx27);
+#endif
int __init mxc_register_gpios(void)
{
- return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
+#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;
}
#ifdef CONFIG_MACH_MX21
static struct resource mx21_usbhc_resources[] = {
{
- .start = USBOTG_BASE_ADDR,
- .end = USBOTG_BASE_ADDR + 0x1FFF,
+ .start = MX21_BASE_ADDR,
+ .end = MX21_BASE_ADDR + 0x1FFF,
.flags = IORESOURCE_MEM,
},
{
- .start = MXC_INT_USBHOST,
- .end = MXC_INT_USBHOST,
+ .start = MX21_INT_USBHOST,
+ .end = MX21_INT_USBHOST,
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h
index f12694b0736..84ed5138017 100644
--- a/arch/arm/mach-mx2/devices.h
+++ b/arch/arm/mach-mx2/devices.h
@@ -1,8 +1,10 @@
extern struct platform_device mxc_gpt1;
extern struct platform_device mxc_gpt2;
+#ifdef CONFIG_MACH_MX27
extern struct platform_device mxc_gpt3;
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;
@@ -11,12 +13,19 @@ 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;
-extern struct platform_device mxc_nand_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;
@@ -25,7 +34,9 @@ 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;
diff --git a/arch/arm/mach-mx2/eukrea_cpuimx27.c b/arch/arm/mach-mx2/eukrea_cpuimx27.c
deleted file mode 100644
index 7b187606682..00000000000
--- a/arch/arm/mach-mx2/eukrea_cpuimx27.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2009 Eric Benard - eric@eukrea.com
- *
- * Based on pcm038.c which is :
- * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
- * 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/i2c.h>
-#include <linux/io.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/mtd/physmap.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.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_cpuimx27.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-#include <mach/iomux.h>
-#include <mach/imx-uart.h>
-#include <mach/mxc_nand.h>
-
-#include "devices.h"
-
-static int eukrea_cpuimx27_pins[] = {
- /* UART1 */
- PE12_PF_UART1_TXD,
- PE13_PF_UART1_RXD,
- PE14_PF_UART1_CTS,
- PE15_PF_UART1_RTS,
- /* UART4 */
- PB26_AF_UART4_RTS,
- PB28_AF_UART4_TXD,
- PB29_AF_UART4_CTS,
- PB31_AF_UART4_RXD,
- /* FEC */
- PD0_AIN_FEC_TXD0,
- PD1_AIN_FEC_TXD1,
- PD2_AIN_FEC_TXD2,
- PD3_AIN_FEC_TXD3,
- PD4_AOUT_FEC_RX_ER,
- PD5_AOUT_FEC_RXD1,
- PD6_AOUT_FEC_RXD2,
- PD7_AOUT_FEC_RXD3,
- PD8_AF_FEC_MDIO,
- PD9_AIN_FEC_MDC,
- PD10_AOUT_FEC_CRS,
- PD11_AOUT_FEC_TX_CLK,
- PD12_AOUT_FEC_RXD0,
- PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_RX_CLK,
- PD15_AOUT_FEC_COL,
- PD16_AIN_FEC_TX_ER,
- PF23_AIN_FEC_TX_EN,
- /* I2C1 */
- PD17_PF_I2C_DATA,
- PD18_PF_I2C_CLK,
- /* SDHC2 */
- PB4_PF_SD2_D0,
- PB5_PF_SD2_D1,
- PB6_PF_SD2_D2,
- PB7_PF_SD2_D3,
- PB8_PF_SD2_CMD,
- PB9_PF_SD2_CLK,
-#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,
-#endif
-};
-
-static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
- .width = 2,
-};
-
-static struct resource eukrea_cpuimx27_flash_resource = {
- .start = 0xc0000000,
- .end = 0xc3ffffff,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &eukrea_cpuimx27_flash_data,
- },
- .num_resources = 1,
- .resource = &eukrea_cpuimx27_flash_resource,
-};
-
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- },
-};
-
-static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
- &eukrea_cpuimx27_nor_mtd_device,
- &mxc_fec_device,
-};
-
-static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = {
- .bitrate = 100000,
-};
-
-static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
- {
- I2C_BOARD_INFO("pcf8563", 0x51),
- },
-};
-
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
-static struct plat_serial8250_port serial_platform_data[] = {
- {
- .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x200000),
- .irq = IRQ_GPIOB(23),
- .uartclk = 14745600,
- .regshift = 1,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
- }, {
- .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x400000),
- .irq = IRQ_GPIOB(22),
- .uartclk = 14745600,
- .regshift = 1,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
- }, {
- .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x800000),
- .irq = IRQ_GPIOB(27),
- .uartclk = 14745600,
- .regshift = 1,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
- }, {
- .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x1000000),
- .irq = IRQ_GPIOB(30),
- .uartclk = 14745600,
- .regshift = 1,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
- }, {
- }
-};
-
-static struct platform_device serial_device = {
- .name = "serial8250",
- .id = 0,
- .dev = {
- .platform_data = serial_platform_data,
- },
-};
-#endif
-
-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]);
-
- mxc_register_device(&mxc_nand_device, &eukrea_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);
-
- 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);
- /* in which case UART4 is also used for Bluetooth */
- mxc_register_device(&mxc_uart_device3, &uart_pdata[1]);
-#endif
-
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
- platform_device_register(&serial_device);
-#endif
-
-#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
- eukrea_mbimx27_baseboard_init();
-#endif
-}
-
-static void __init eukrea_cpuimx27_timer_init(void)
-{
- mx27_clocks_init(26000000);
-}
-
-static struct sys_timer eukrea_cpuimx27_timer = {
- .init = eukrea_cpuimx27_timer_init,
-};
-
-MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
- .phys_io = AIPI_BASE_ADDR,
- .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx27_map_io,
- .init_irq = mx27_init_irq,
- .init_machine = eukrea_cpuimx27_init,
- .timer = &eukrea_cpuimx27_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
index 7382b6d27ee..f3b169d5245 100644
--- a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
+++ b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
@@ -28,7 +28,7 @@
#include <asm/mach/arch.h>
#include <mach/common.h>
-#include <mach/iomux.h>
+#include <mach/iomux-mx27.h>
#include <mach/imxfb.h>
#include <mach/hardware.h>
#include <mach/mmc.h>
diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c
deleted file mode 100644
index ae8f759134d..00000000000
--- a/arch/arm/mach-mx2/generic.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * generic.c
- *
- * 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/mm.h>
-#include <linux/init.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <asm/pgtable.h>
-#include <asm/mach/map.h>
-
-/* MX27 memory map definition */
-static struct map_desc mxc_io_desc[] __initdata = {
- /*
- * this fixed mapping covers:
- * - AIPI1
- * - AIPI2
- * - AITC
- * - ROM Patch
- * - and some reserved space
- */
- {
- .virtual = AIPI_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPI_BASE_ADDR),
- .length = AIPI_SIZE,
- .type = MT_DEVICE
- },
- /*
- * this fixed mapping covers:
- * - CSI
- * - ATA
- */
- {
- .virtual = SAHB1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(SAHB1_BASE_ADDR),
- .length = SAHB1_SIZE,
- .type = MT_DEVICE
- },
- /*
- * this fixed mapping covers:
- * - EMI
- */
- {
- .virtual = X_MEMC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR),
- .length = X_MEMC_SIZE,
- .type = MT_DEVICE
- }
-};
-
-/*
- * Initialize the memory map. It is called during the
- * system startup to create static physical to virtual
- * memory map for the IO modules.
- */
-void __init mx21_map_io(void)
-{
- mxc_set_cpu_type(MXC_CPU_MX21);
- mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
-
- iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
-}
-
-void __init mx27_map_io(void)
-{
- mxc_set_cpu_type(MXC_CPU_MX27);
- mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
-
- iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
-}
-
-void __init mx27_init_irq(void)
-{
- mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
-}
-
-void __init mx21_init_irq(void)
-{
- mx27_init_irq();
-}
-
diff --git a/arch/arm/mach-mx2/mach-cpuimx27.c b/arch/arm/mach-mx2/mach-cpuimx27.c
new file mode 100644
index 00000000000..1f616dcaabc
--- /dev/null
+++ b/arch/arm/mach-mx2/mach-cpuimx27.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2009 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm038.c which is :
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * 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/i2c.h>
+#include <linux/io.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.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_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 "devices.h"
+
+static int eukrea_cpuimx27_pins[] = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* UART4 */
+ PB26_AF_UART4_RTS,
+ PB28_AF_UART4_TXD,
+ PB29_AF_UART4_CTS,
+ PB31_AF_UART4_RXD,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* I2C1 */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ /* SDHC2 */
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+#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,
+#endif
+};
+
+static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
+ .width = 2,
+};
+
+static struct resource eukrea_cpuimx27_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc3ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &eukrea_cpuimx27_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &eukrea_cpuimx27_flash_resource,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+ {
+ .flags = IMXUART_HAVE_RTSCTS,
+ }, {
+ .flags = IMXUART_HAVE_RTSCTS,
+ },
+};
+
+static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &eukrea_cpuimx27_nor_mtd_device,
+ &mxc_fec_device,
+};
+
+static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x200000),
+ .irq = IRQ_GPIOB(23),
+ .uartclk = 14745600,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x400000),
+ .irq = IRQ_GPIOB(22),
+ .uartclk = 14745600,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x800000),
+ .irq = IRQ_GPIOB(27),
+ .uartclk = 14745600,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x1000000),
+ .irq = IRQ_GPIOB(30),
+ .uartclk = 14745600,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ }
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+#endif
+
+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]);
+
+ mxc_register_device(&imx27_nand_device,
+ &eukrea_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);
+
+ 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);
+ /* in which case UART4 is also used for Bluetooth */
+ mxc_register_device(&mxc_uart_device3, &uart_pdata[1]);
+#endif
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+ platform_device_register(&serial_device);
+#endif
+
+#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
+ eukrea_mbimx27_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx27_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer eukrea_cpuimx27_timer = {
+ .init = eukrea_cpuimx27_timer_init,
+};
+
+MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
+ .phys_io = MX27_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mx27_init_irq,
+ .init_machine = eukrea_cpuimx27_init,
+ .timer = &eukrea_cpuimx27_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx2/mach-imx27lite.c b/arch/arm/mach-mx2/mach-imx27lite.c
new file mode 100644
index 00000000000..b5710bf18b9
--- /dev/null
+++ b/arch/arm/mach-mx2/mach-imx27lite.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ * Copyright 2009 Daniel Schaeffer (daniel.schaeffer@timesys.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/platform_device.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#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.h"
+
+static unsigned int mx27lite_pins[] = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &mxc_fec_device,
+};
+
+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);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx27lite_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mx27lite_timer = {
+ .init = mx27lite_timer_init,
+};
+
+MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
+ .phys_io = MX27_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mx27_init_irq,
+ .init_machine = mx27lite_init,
+ .timer = &mx27lite_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx2/mach-mx21ads.c b/arch/arm/mach-mx2/mach-mx21ads.c
new file mode 100644
index 00000000000..113e58d7cb4
--- /dev/null
+++ b/arch/arm/mach-mx2/mach-mx21ads.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2006-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 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/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#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.h"
+
+static unsigned int mx21ads_pins[] = {
+
+ /* CS8900A */
+ (GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
+
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+
+ /* UART3 (IrDA) - only TXD and RXD */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+
+ /* UART4 */
+ PB26_AF_UART4_RTS,
+ PB28_AF_UART4_TXD,
+ PB29_AF_UART4_CTS,
+ PB31_AF_UART4_RXD,
+
+ /* LCDC */
+ 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,
+ PA24_PF_REV, /* Sharp panel dedicated signal */
+ PA25_PF_CLS, /* Sharp panel dedicated signal */
+ PA26_PF_PS, /* Sharp panel dedicated signal */
+ PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
+
+ /* MMC/SDHC */
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+
+ /* NFC */
+ PF0_PF_NRFB,
+ PF1_PF_NFCE,
+ PF2_PF_NFWP,
+ PF3_PF_NFCLE,
+ PF4_PF_NFALE,
+ PF5_PF_NFRE,
+ PF6_PF_NFWE,
+ PF7_PF_NFIO0,
+ PF8_PF_NFIO1,
+ PF9_PF_NFIO2,
+ PF10_PF_NFIO3,
+ PF11_PF_NFIO4,
+ PF12_PF_NFIO5,
+ PF13_PF_NFIO6,
+ PF14_PF_NFIO7,
+};
+
+/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */
+static struct physmap_flash_data mx21ads_flash_data = {
+ .width = 4,
+};
+
+static struct resource mx21ads_flash_resource = {
+ .start = MX21_CS0_BASE_ADDR,
+ .end = MX21_CS0_BASE_ADDR + 0x02000000 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mx21ads_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx21ads_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mx21ads_flash_resource,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct imxuart_platform_data uart_norts_pdata = {
+};
+
+
+static int mx21ads_fb_init(struct platform_device *pdev)
+{
+ u16 tmp;
+
+ tmp = __raw_readw(MX21ADS_IO_REG);
+ tmp |= MX21ADS_IO_LCDON;
+ __raw_writew(tmp, MX21ADS_IO_REG);
+ return 0;
+}
+
+static void mx21ads_fb_exit(struct platform_device *pdev)
+{
+ u16 tmp;
+
+ tmp = __raw_readw(MX21ADS_IO_REG);
+ tmp &= ~MX21ADS_IO_LCDON;
+ __raw_writew(tmp, MX21ADS_IO_REG);
+}
+
+/*
+ * Connected is a portrait Sharp-QVGA display
+ * of type: LQ035Q7DB02
+ */
+static struct imx_fb_videomode mx21ads_modes[] = {
+ {
+ .mode = {
+ .name = "Sharp-LQ035Q7",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 188679, /* in ps (5.3MHz) */
+ .hsync_len = 2,
+ .left_margin = 6,
+ .right_margin = 16,
+ .vsync_len = 1,
+ .upper_margin = 8,
+ .lower_margin = 10,
+ },
+ .pcr = 0xfb108bc7,
+ .bpp = 16,
+ },
+};
+
+static struct imx_fb_platform_data mx21ads_fb_data = {
+ .mode = mx21ads_modes,
+ .num_modes = ARRAY_SIZE(mx21ads_modes),
+
+ .pwmr = 0x00a903ff,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020008,
+
+ .init = mx21ads_fb_init,
+ .exit = mx21ads_fb_exit,
+};
+
+static int mx21ads_sdhc_get_ro(struct device *dev)
+{
+ return (__raw_readw(MX21ADS_IO_REG) & MX21ADS_IO_SD_WP) ? 1 : 0;
+}
+
+static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = request_irq(IRQ_GPIOD(25), detect_irq,
+ IRQF_TRIGGER_FALLING, "mmc-detect", data);
+ if (ret)
+ goto out;
+ return 0;
+out:
+ return ret;
+}
+
+static void mx21ads_sdhc_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOD(25), data);
+}
+
+static struct imxmmc_platform_data mx21ads_sdhc_pdata = {
+ .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
+ .get_ro = mx21ads_sdhc_get_ro,
+ .init = mx21ads_sdhc_init,
+ .exit = mx21ads_sdhc_exit,
+};
+
+static struct mxc_nand_platform_data mx21ads_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct map_desc mx21ads_io_desc[] __initdata = {
+ /*
+ * Memory-mapped I/O on MX21ADS Base board:
+ * - CS8900A Ethernet controller
+ * - ST16C2552CJ UART
+ * - CPU and Base board version
+ * - Base board I/O register
+ */
+ {
+ .virtual = MX21ADS_MMIO_BASE_ADDR,
+ .pfn = __phys_to_pfn(MX21_CS1_BASE_ADDR),
+ .length = MX21ADS_MMIO_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init mx21ads_map_io(void)
+{
+ mx21_map_io();
+ iotable_init(mx21ads_io_desc, ARRAY_SIZE(mx21ads_io_desc));
+}
+
+static struct platform_device *platform_devices[] __initdata = {
+ &mx21ads_nor_mtd_device,
+};
+
+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);
+ 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);
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx21ads_timer_init(void)
+{
+ mx21_clocks_init(32768, 26000000);
+}
+
+static struct sys_timer mx21ads_timer = {
+ .init = mx21ads_timer_init,
+};
+
+MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = MX21_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX21_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX21_PHYS_OFFSET + 0x100,
+ .map_io = mx21ads_map_io,
+ .init_irq = mx21_init_irq,
+ .init_machine = mx21ads_board_init,
+ .timer = &mx21ads_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx2/mach-mx27_3ds.c b/arch/arm/mach-mx2/mach-mx27_3ds.c
new file mode 100644
index 00000000000..b2f4e0db3fb
--- /dev/null
+++ b/arch/arm/mach-mx2/mach-mx27_3ds.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.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/platform_device.h>
+#include <linux/gpio.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.h"
+
+static unsigned int mx27pdk_pins[] = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &mxc_fec_device,
+};
+
+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);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx27pdk_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mx27pdk_timer = {
+ .init = mx27pdk_timer_init,
+};
+
+MACHINE_START(MX27_3DS, "Freescale MX27PDK")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = MX27_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mx27_init_irq,
+ .init_machine = mx27pdk_init,
+ .timer = &mx27pdk_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx2/mach-mx27ads.c b/arch/arm/mach-mx2/mach-mx27ads.c
new file mode 100644
index 00000000000..6ce323669e5
--- /dev/null
+++ b/arch/arm/mach-mx2/mach-mx27ads.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2006-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 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/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#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.h"
+
+static unsigned int mx27ads_pins[] = {
+ /* UART0 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* UART1 */
+ PE3_PF_UART2_CTS,
+ PE4_PF_UART2_RTS,
+ PE6_PF_UART2_TXD,
+ PE7_PF_UART2_RXD,
+ /* UART2 */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+ PE10_PF_UART3_CTS,
+ PE11_PF_UART3_RTS,
+ /* UART3 */
+ PB26_AF_UART4_RTS,
+ PB28_AF_UART4_TXD,
+ PB29_AF_UART4_CTS,
+ PB31_AF_UART4_RXD,
+ /* UART4 */
+ PB18_AF_UART5_TXD,
+ PB19_AF_UART5_RXD,
+ PB20_AF_UART5_CTS,
+ PB21_AF_UART5_RTS,
+ /* UART5 */
+ PB10_AF_UART6_TXD,
+ PB12_AF_UART6_CTS,
+ PB11_AF_UART6_RXD,
+ PB13_AF_UART6_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* I2C2 */
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* FB */
+ 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,
+ PA24_PF_REV,
+ PA25_PF_CLS,
+ PA26_PF_PS,
+ PA27_PF_SPL_SPR,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
+ /* OWIRE */
+ PE16_AF_OWIRE,
+ /* SDHC1*/
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ /* SDHC2*/
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+};
+
+static struct mxc_nand_platform_data mx27ads_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+/* ADS's NOR flash */
+static struct physmap_flash_data mx27ads_flash_data = {
+ .width = 2,
+};
+
+static struct resource mx27ads_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc0000000 + 0x02000000 - 1,
+ .flags = IORESOURCE_MEM,
+
+};
+
+static struct platform_device mx27ads_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx27ads_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mx27ads_flash_resource,
+};
+
+static struct imxi2c_platform_data mx27ads_i2c_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mx27ads_i2c_devices[] = {
+};
+
+void lcd_power(int on)
+{
+ if (on)
+ __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
+ else
+ __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
+}
+
+static struct imx_fb_videomode mx27ads_modes[] = {
+ {
+ .mode = {
+ .name = "Sharp-LQ035Q7",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 188679, /* in ps (5.3MHz) */
+ .hsync_len = 1,
+ .left_margin = 9,
+ .right_margin = 16,
+ .vsync_len = 1,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ },
+ .bpp = 16,
+ .pcr = 0xFB008BC0,
+ },
+};
+
+static struct imx_fb_platform_data mx27ads_fb_data = {
+ .mode = mx27ads_modes,
+ .num_modes = ARRAY_SIZE(mx27ads_modes),
+
+ /*
+ * - HSYNC active high
+ * - VSYNC active high
+ * - clk notenabled while idle
+ * - clock inverted
+ * - data not inverted
+ * - data enable low active
+ * - enable sharp mode
+ */
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+
+ .lcd_power = lcd_power,
+};
+
+static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING,
+ "sdhc1-card-detect", data);
+}
+
+static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING,
+ "sdhc2-card-detect", data);
+}
+
+static void mx27ads_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOE(21), data);
+}
+
+static void mx27ads_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOB(7), data);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+ .init = mx27ads_sdhc1_init,
+ .exit = mx27ads_sdhc1_exit,
+};
+
+static struct imxmmc_platform_data sdhc2_pdata = {
+ .init = mx27ads_sdhc2_init,
+ .exit = mx27ads_sdhc2_exit,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &mx27ads_nor_mtd_device,
+ &mxc_fec_device,
+ &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 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);
+
+ /* 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);
+ 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);
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx27ads_timer_init(void)
+{
+ unsigned long fref = 26000000;
+
+ if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
+ fref = 27000000;
+
+ mx27_clocks_init(fref);
+}
+
+static struct sys_timer mx27ads_timer = {
+ .init = mx27ads_timer_init,
+};
+
+static struct map_desc mx27ads_io_desc[] __initdata = {
+ {
+ .virtual = PBC_BASE_ADDRESS,
+ .pfn = __phys_to_pfn(MX27_CS4_BASE_ADDR),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init mx27ads_map_io(void)
+{
+ mx27_map_io();
+ iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
+}
+
+MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = MX27_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27ads_map_io,
+ .init_irq = mx27_init_irq,
+ .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-mx2/mach-mxt_td60.c
new file mode 100644
index 00000000000..bc385599267
--- /dev/null
+++ b/arch/arm/mach-mx2/mach-mxt_td60.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2006-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 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/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#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.h"
+
+static unsigned int mxt_td60_pins[] __initdata = {
+ /* UART0 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* UART1 */
+ PE3_PF_UART2_CTS,
+ PE4_PF_UART2_RTS,
+ PE6_PF_UART2_TXD,
+ PE7_PF_UART2_RXD,
+ /* UART2 */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+ PE10_PF_UART3_CTS,
+ PE11_PF_UART3_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* I2C1 */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ /* I2C2 */
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* FB */
+ 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,
+ PA25_PF_CLS,
+ PA27_PF_SPL_SPR,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
+ /* OWIRE */
+ PE16_AF_OWIRE,
+ /* SDHC1*/
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ PF8_AF_ATA_IORDY,
+ /* SDHC2*/
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+};
+
+static struct mxc_nand_platform_data mxt_td60_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct imxi2c_platform_data mxt_td60_i2c_data = {
+ .bitrate = 100000,
+};
+
+/* PCA9557 */
+static int mxt_td60_pca9557_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ static int mxt_td60_gpio_value[] = {
+ -1, -1, -1, -1, -1, -1, -1, 1
+ };
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp");
+ if (mxt_td60_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ mxt_td60_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data mxt_td60_pca9557_pdata = {
+ .gpio_base = 240, /* place PCA9557 after all MX27 gpio pins */
+ .invert = 0, /* Do not invert */
+ .setup = mxt_td60_pca9557_setup,
+};
+
+static struct i2c_board_info mxt_td60_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pca9557", 0x18),
+ .platform_data = &mxt_td60_pca9557_pdata,
+ },
+};
+
+static struct imxi2c_platform_data mxt_td60_i2c2_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mxt_td60_i2c2_devices[] = {
+};
+
+static struct imx_fb_videomode mxt_td60_modes[] = {
+ {
+ .mode = {
+ .name = "Chimei LW700AT9003",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = 30303,
+ .hsync_len = 64,
+ .left_margin = 0x67,
+ .right_margin = 0x68,
+ .vsync_len = 16,
+ .upper_margin = 0x0f,
+ .lower_margin = 0x0f,
+ },
+ .bpp = 16,
+ .pcr = 0xFA208B83,
+ },
+};
+
+static struct imx_fb_platform_data mxt_td60_fb_data = {
+ .mode = mxt_td60_modes,
+ .num_modes = ARRAY_SIZE(mxt_td60_modes),
+
+ /*
+ * - HSYNC active high
+ * - VSYNC active high
+ * - clk notenabled while idle
+ * - clock inverted
+ * - data not inverted
+ * - data enable low active
+ * - enable sharp mode
+ */
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+};
+
+static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING,
+ "sdhc1-card-detect", data);
+}
+
+static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOF(8), data);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+ .init = mxt_td60_sdhc1_init,
+ .exit = mxt_td60_sdhc1_exit,
+};
+
+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 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);
+
+ i2c_register_board_info(0, mxt_td60_i2c_devices,
+ ARRAY_SIZE(mxt_td60_i2c_devices));
+
+ 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);
+ mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
+ mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mxt_td60_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mxt_td60_timer = {
+ .init = mxt_td60_timer_init,
+};
+
+MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
+ /* maintainer: Maxtrack Industrial */
+ .phys_io = MX27_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mx27_init_irq,
+ .init_machine = mxt_td60_board_init,
+ .timer = &mxt_td60_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx2/mach-pca100.c b/arch/arm/mach-mx2/mach-pca100.c
new file mode 100644
index 00000000000..778fff23091
--- /dev/null
+++ b/arch/arm/mach-mx2/mach-pca100.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2009 Sascha Hauer (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/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#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>
+#include <mach/irqs.h>
+#include <mach/mmc.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
+#include "devices.h"
+
+#define OTG_PHY_CS_GPIO (GPIO_PORTB + 23)
+#define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24)
+
+static int pca100_pins[] = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* SDHC */
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* SSI1 */
+ PC20_PF_SSI1_FS,
+ PC21_PF_SSI1_RXD,
+ PC22_PF_SSI1_TXD,
+ PC23_PF_SSI1_CLK,
+ /* onboard I2C */
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* external I2C */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ /* SPI1 */
+ PD25_PF_CSPI1_RDY,
+ PD29_PF_CSPI1_SCLK,
+ PD30_PF_CSPI1_MISO,
+ PD31_PF_CSPI1_MOSI,
+ /* OTG */
+ OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+ 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 */
+ USBH2_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+ 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 imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct mxc_nand_platform_data pca100_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &mxc_w1_master_device,
+ &mxc_fec_device,
+};
+
+static struct imxi2c_platform_data pca100_i2c_1_data = {
+ .bitrate = 100000,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pca100_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+ .type = "pcf8563"
+ }, {
+ I2C_BOARD_INFO("lm75", 0x4a),
+ .type = "lm75"
+ }
+};
+
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+static struct spi_eeprom at25320 = {
+ .name = "at25320an",
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info pca100_spi_board_info[] __initdata = {
+ {
+ .modalias = "at25",
+ .max_speed_hz = 30000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &at25320,
+ },
+};
+
+static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27};
+
+static struct spi_imx_master pca100_spi_0_data = {
+ .chipselect = pca100_spi_cs,
+ .num_chipselect = ARRAY_SIZE(pca100_spi_cs),
+};
+#endif
+
+static void pca100_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+ mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT);
+ gpio_set_value(GPIO_PORTC + 20, 1);
+ udelay(2);
+ gpio_set_value(GPIO_PORTC + 20, 0);
+ mxc_gpio_mode(PC20_PF_SSI1_FS);
+ msleep(2);
+}
+
+static void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
+{
+ mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT); /* FS */
+ gpio_set_value(GPIO_PORTC + 20, 0);
+ mxc_gpio_mode(GPIO_PORTC | 22 | GPIO_GPIO | GPIO_OUT); /* TX */
+ gpio_set_value(GPIO_PORTC + 22, 0);
+ mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_OUT); /* reset */
+ gpio_set_value(GPIO_PORTC + 28, 0);
+ udelay(10);
+ gpio_set_value(GPIO_PORTC + 28, 1);
+ mxc_gpio_mode(PC20_PF_SSI1_FS);
+ mxc_gpio_mode(PC22_PF_SSI1_TXD);
+ msleep(2);
+}
+
+static struct imx_ssi_platform_data pca100_ssi_pdata = {
+ .ac97_reset = pca100_ac97_cold_reset,
+ .ac97_warm_reset = pca100_ac97_warm_reset,
+ .flags = IMX_SSI_USE_AC97,
+};
+
+static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = request_irq(IRQ_GPIOC(29), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "imx-mmc-detect", data);
+ if (ret)
+ printk(KERN_ERR
+ "pca100: Failed to reuest irq for sd/mmc detection\n");
+
+ return ret;
+}
+
+static void pca100_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOC(29), data);
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+ .init = pca100_sdhc2_init,
+ .exit = pca100_sdhc2_exit,
+};
+
+static int otg_phy_init(struct platform_device *pdev)
+{
+ gpio_set_value(OTG_PHY_CS_GPIO, 0);
+ return 0;
+}
+
+static struct mxc_usbh_platform_data otg_pdata = {
+ .init = otg_phy_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static int usbh2_phy_init(struct platform_device *pdev)
+{
+ gpio_set_value(USBH2_PHY_CS_GPIO, 0);
+ return 0;
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+ .init = usbh2_phy_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+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 pca100_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=", pca100_otg_mode);
+
+static void __init pca100_init(void)
+{
+ int ret;
+
+ /* SSI unit */
+ mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+ MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+ MXC_AUDMUX_V1_PCR_TFCSEL(3) |
+ MXC_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
+ MXC_AUDMUX_V1_PCR_RXDSEL(3));
+ mxc_audmux_v1_configure_port(3,
+ MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+ MXC_AUDMUX_V1_PCR_TFCSEL(0) |
+ MXC_AUDMUX_V1_PCR_TFSDIR |
+ MXC_AUDMUX_V1_PCR_RXDSEL(0));
+
+ ret = mxc_gpio_setup_multiple_pins(pca100_pins,
+ ARRAY_SIZE(pca100_pins), "PCA100");
+ if (ret)
+ printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
+
+ mxc_register_device(&imx_ssi_device0, &pca100_ssi_pdata);
+
+ mxc_register_device(&mxc_uart_device0, &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);
+
+ /* 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);
+
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+ spi_register_board_info(pca100_spi_board_info,
+ ARRAY_SIZE(pca100_spi_board_info));
+ mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data);
+#endif
+
+ gpio_request(OTG_PHY_CS_GPIO, "usb-otg-cs");
+ gpio_direction_output(OTG_PHY_CS_GPIO, 1);
+ gpio_request(USBH2_PHY_CS_GPIO, "usb-host2-cs");
+ gpio_direction_output(USBH2_PHY_CS_GPIO, 1);
+
+#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) {
+ gpio_set_value(OTG_PHY_CS_GPIO, 0);
+ mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+ }
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init pca100_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer pca100_timer = {
+ .init = pca100_timer_init,
+};
+
+MACHINE_START(PCA100, "phyCARD-i.MX27")
+ .phys_io = MX27_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mx27_init_irq,
+ .init_machine = pca100_init,
+ .timer = &pca100_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx2/mach-pcm038.c b/arch/arm/mach-mx2/mach-pcm038.c
new file mode 100644
index 00000000000..035fbe046ec
--- /dev/null
+++ b/arch/arm/mach-mx2/mach-pcm038.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * 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/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/io.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#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.h"
+
+static int pcm038_pins[] = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* UART2 */
+ PE3_PF_UART2_CTS,
+ PE4_PF_UART2_RTS,
+ PE6_PF_UART2_TXD,
+ PE7_PF_UART2_RXD,
+ /* UART3 */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+ PE10_PF_UART3_CTS,
+ PE11_PF_UART3_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* I2C2 */
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* SPI1 */
+ PD25_PF_CSPI1_RDY,
+ PD29_PF_CSPI1_SCLK,
+ PD30_PF_CSPI1_MISO,
+ PD31_PF_CSPI1_MOSI,
+ /* SSI1 */
+ PC20_PF_SSI1_FS,
+ PC21_PF_SSI1_RXD,
+ PC22_PF_SSI1_TXD,
+ PC23_PF_SSI1_CLK,
+ /* SSI4 */
+ PC16_PF_SSI4_FS,
+ PC17_PF_SSI4_RXD,
+ PC18_PF_SSI4_TXD,
+ PC19_PF_SSI4_CLK,
+ /* USB host */
+ 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,
+};
+
+/*
+ * Phytec's PCM038 comes with 2MiB battery buffered SRAM,
+ * 16 bit width
+ */
+
+static struct platdata_mtd_ram pcm038_sram_data = {
+ .bankwidth = 2,
+};
+
+static struct resource pcm038_sram_resource = {
+ .start = MX27_CS1_BASE_ADDR,
+ .end = MX27_CS1_BASE_ADDR + 512 * 1024 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm038_sram_mtd_device = {
+ .name = "mtd-ram",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm038_sram_data,
+ },
+ .num_resources = 1,
+ .resource = &pcm038_sram_resource,
+};
+
+/*
+ * Phytec's phyCORE-i.MX27 comes with 32MiB flash,
+ * 16 bit width
+ */
+static struct physmap_flash_data pcm038_flash_data = {
+ .width = 2,
+};
+
+static struct resource pcm038_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm038_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm038_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &pcm038_flash_resource,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+ {
+ .flags = IMXUART_HAVE_RTSCTS,
+ }, {
+ .flags = IMXUART_HAVE_RTSCTS,
+ }, {
+ .flags = IMXUART_HAVE_RTSCTS,
+ },
+};
+
+static struct mxc_nand_platform_data pcm038_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &pcm038_nor_mtd_device,
+ &mxc_w1_master_device,
+ &mxc_fec_device,
+ &pcm038_sram_mtd_device,
+};
+
+/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
+ * setup other stuffs to access the sram. */
+static void __init pcm038_init_sram(void)
+{
+ mx27_setup_weimcs(1, 0x0000d843, 0x22252521, 0x22220a00);
+}
+
+static struct imxi2c_platform_data pcm038_i2c_1_data = {
+ .bitrate = 100000,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm038_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }, {
+ I2C_BOARD_INFO("lm75", 0x4a),
+ }
+};
+
+static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
+
+static struct spi_imx_master pcm038_spi_0_data = {
+ .chipselect = pcm038_spi_cs,
+ .num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
+};
+
+static struct regulator_consumer_supply sdhc1_consumers[] = {
+ {
+ .dev = &mxc_sdhc_device1.dev,
+ .supply = "sdhc_vcc",
+ },
+};
+
+static struct regulator_init_data sdhc1_data = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3400000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
+ .consumer_supplies = sdhc1_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+ {
+ .dev = NULL,
+ .supply = "imx_cam_vcc",
+ },
+};
+
+static struct regulator_init_data cam_data = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3400000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+ .consumer_supplies = cam_consumers,
+};
+
+struct mc13783_regulator_init_data pcm038_regulators[] = {
+ {
+ .id = MC13783_REGU_VCAM,
+ .init_data = &cam_data,
+ }, {
+ .id = MC13783_REGU_VMMC1,
+ .init_data = &sdhc1_data,
+ },
+};
+
+static struct mc13783_platform_data pcm038_pmic = {
+ .regulators = pcm038_regulators,
+ .num_regulators = ARRAY_SIZE(pcm038_regulators),
+ .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
+ MC13783_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info pcm038_spi_board_info[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .irq = IRQ_GPIOB(23),
+ .max_speed_hz = 300000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &pcm038_pmic,
+ .mode = SPI_CS_HIGH,
+ }
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static void __init pcm038_init(void)
+{
+ mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
+ "PCM038");
+
+ 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]);
+
+ mxc_gpio_mode(PE16_AF_OWIRE);
+ mxc_register_device(&imx27_nand_device, &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);
+
+ /* PE18 for user-LED D40 */
+ mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
+
+ mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+
+ /* MC13783 IRQ */
+ mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
+
+ mxc_register_device(&mxc_spi_device0, &pcm038_spi_0_data);
+ spi_register_board_info(pcm038_spi_board_info,
+ ARRAY_SIZE(pcm038_spi_board_info));
+
+ mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+#ifdef CONFIG_MACH_PCM970_BASEBOARD
+ pcm970_baseboard_init();
+#endif
+}
+
+static void __init pcm038_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer pcm038_timer = {
+ .init = pcm038_timer_init,
+};
+
+MACHINE_START(PCM038, "phyCORE-i.MX27")
+ .phys_io = MX27_AIPI_BASE_ADDR,
+ .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mx27_init_irq,
+ .init_machine = pcm038_init,
+ .timer = &pcm038_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx2/mm-imx21.c b/arch/arm/mach-mx2/mm-imx21.c
new file mode 100644
index 00000000000..64134314d01
--- /dev/null
+++ b/arch/arm/mach-mx2/mm-imx21.c
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-mx2/mm-imx21.c
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+/* MX21 memory map definition */
+static struct map_desc imx21_io_desc[] __initdata = {
+ /*
+ * this fixed mapping covers:
+ * - AIPI1
+ * - AIPI2
+ * - AITC
+ * - ROM Patch
+ * - and some reserved space
+ */
+ {
+ .virtual = MX21_AIPI_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX21_AIPI_BASE_ADDR),
+ .length = MX21_AIPI_SIZE,
+ .type = MT_DEVICE
+ },
+ /*
+ * this fixed mapping covers:
+ * - CSI
+ * - ATA
+ */
+ {
+ .virtual = MX21_SAHB1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX21_SAHB1_BASE_ADDR),
+ .length = MX21_SAHB1_SIZE,
+ .type = MT_DEVICE
+ },
+ /*
+ * this fixed mapping covers:
+ * - EMI
+ */
+ {
+ .virtual = MX21_X_MEMC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX21_X_MEMC_BASE_ADDR),
+ .length = MX21_X_MEMC_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+/*
+ * Initialize the memory map. It is called during the
+ * system startup to create static physical to virtual
+ * memory map for the IO modules.
+ */
+void __init mx21_map_io(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX21);
+ mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
+
+ iotable_init(imx21_io_desc, ARRAY_SIZE(imx21_io_desc));
+}
+
+void __init mx21_init_irq(void)
+{
+ mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
+}
diff --git a/arch/arm/mach-mx2/mm-imx27.c b/arch/arm/mach-mx2/mm-imx27.c
new file mode 100644
index 00000000000..3366ed44cfd
--- /dev/null
+++ b/arch/arm/mach-mx2/mm-imx27.c
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-mx2/mm-imx27.c
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+/* MX27 memory map definition */
+static struct map_desc imx27_io_desc[] __initdata = {
+ /*
+ * this fixed mapping covers:
+ * - AIPI1
+ * - AIPI2
+ * - AITC
+ * - ROM Patch
+ * - and some reserved space
+ */
+ {
+ .virtual = MX27_AIPI_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX27_AIPI_BASE_ADDR),
+ .length = MX27_AIPI_SIZE,
+ .type = MT_DEVICE
+ },
+ /*
+ * this fixed mapping covers:
+ * - CSI
+ * - ATA
+ */
+ {
+ .virtual = MX27_SAHB1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX27_SAHB1_BASE_ADDR),
+ .length = MX27_SAHB1_SIZE,
+ .type = MT_DEVICE
+ },
+ /*
+ * this fixed mapping covers:
+ * - EMI
+ */
+ {
+ .virtual = MX27_X_MEMC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX27_X_MEMC_BASE_ADDR),
+ .length = MX27_X_MEMC_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+/*
+ * Initialize the memory map. It is called during the
+ * system startup to create static physical to virtual
+ * memory map for the IO modules.
+ */
+void __init mx27_map_io(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX27);
+ mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
+
+ iotable_init(imx27_io_desc, ARRAY_SIZE(imx27_io_desc));
+}
+
+void __init mx27_init_irq(void)
+{
+ mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
+}
diff --git a/arch/arm/mach-mx2/mx21ads.c b/arch/arm/mach-mx2/mx21ads.c
deleted file mode 100644
index cf5f77cbc2f..00000000000
--- a/arch/arm/mach-mx2/mx21ads.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright (C) 2002 Shane Nay (shane@minirl.com)
- * Copyright 2006-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 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/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/physmap.h>
-#include <linux/gpio.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#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.h>
-#include <mach/mxc_nand.h>
-#include <mach/mmc.h>
-#include <mach/board-mx21ads.h>
-
-#include "devices.h"
-
-static unsigned int mx21ads_pins[] = {
-
- /* CS8900A */
- (GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
-
- /* UART1 */
- PE12_PF_UART1_TXD,
- PE13_PF_UART1_RXD,
- PE14_PF_UART1_CTS,
- PE15_PF_UART1_RTS,
-
- /* UART3 (IrDA) - only TXD and RXD */
- PE8_PF_UART3_TXD,
- PE9_PF_UART3_RXD,
-
- /* UART4 */
- PB26_AF_UART4_RTS,
- PB28_AF_UART4_TXD,
- PB29_AF_UART4_CTS,
- PB31_AF_UART4_RXD,
-
- /* LCDC */
- 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,
- PA24_PF_REV, /* Sharp panel dedicated signal */
- PA25_PF_CLS, /* Sharp panel dedicated signal */
- PA26_PF_PS, /* Sharp panel dedicated signal */
- PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */
- PA28_PF_HSYNC,
- PA29_PF_VSYNC,
- PA30_PF_CONTRAST,
- PA31_PF_OE_ACD,
-
- /* MMC/SDHC */
- PE18_PF_SD1_D0,
- PE19_PF_SD1_D1,
- PE20_PF_SD1_D2,
- PE21_PF_SD1_D3,
- PE22_PF_SD1_CMD,
- PE23_PF_SD1_CLK,
-
- /* NFC */
- PF0_PF_NRFB,
- PF1_PF_NFCE,
- PF2_PF_NFWP,
- PF3_PF_NFCLE,
- PF4_PF_NFALE,
- PF5_PF_NFRE,
- PF6_PF_NFWE,
- PF7_PF_NFIO0,
- PF8_PF_NFIO1,
- PF9_PF_NFIO2,
- PF10_PF_NFIO3,
- PF11_PF_NFIO4,
- PF12_PF_NFIO5,
- PF13_PF_NFIO6,
- PF14_PF_NFIO7,
-};
-
-/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */
-static struct physmap_flash_data mx21ads_flash_data = {
- .width = 4,
-};
-
-static struct resource mx21ads_flash_resource = {
- .start = CS0_BASE_ADDR,
- .end = CS0_BASE_ADDR + 0x02000000 - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device mx21ads_nor_mtd_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &mx21ads_flash_data,
- },
- .num_resources = 1,
- .resource = &mx21ads_flash_resource,
-};
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct imxuart_platform_data uart_norts_pdata = {
-};
-
-
-static int mx21ads_fb_init(struct platform_device *pdev)
-{
- u16 tmp;
-
- tmp = __raw_readw(MX21ADS_IO_REG);
- tmp |= MX21ADS_IO_LCDON;
- __raw_writew(tmp, MX21ADS_IO_REG);
- return 0;
-}
-
-static void mx21ads_fb_exit(struct platform_device *pdev)
-{
- u16 tmp;
-
- tmp = __raw_readw(MX21ADS_IO_REG);
- tmp &= ~MX21ADS_IO_LCDON;
- __raw_writew(tmp, MX21ADS_IO_REG);
-}
-
-/*
- * Connected is a portrait Sharp-QVGA display
- * of type: LQ035Q7DB02
- */
-static struct imx_fb_videomode mx21ads_modes[] = {
- {
- .mode = {
- .name = "Sharp-LQ035Q7",
- .refresh = 60,
- .xres = 240,
- .yres = 320,
- .pixclock = 188679, /* in ps (5.3MHz) */
- .hsync_len = 2,
- .left_margin = 6,
- .right_margin = 16,
- .vsync_len = 1,
- .upper_margin = 8,
- .lower_margin = 10,
- },
- .pcr = 0xfb108bc7,
- .bpp = 16,
- },
-};
-
-static struct imx_fb_platform_data mx21ads_fb_data = {
- .mode = mx21ads_modes,
- .num_modes = ARRAY_SIZE(mx21ads_modes),
-
- .pwmr = 0x00a903ff,
- .lscr1 = 0x00120300,
- .dmacr = 0x00020008,
-
- .init = mx21ads_fb_init,
- .exit = mx21ads_fb_exit,
-};
-
-static int mx21ads_sdhc_get_ro(struct device *dev)
-{
- return (__raw_readw(MX21ADS_IO_REG) & MX21ADS_IO_SD_WP) ? 1 : 0;
-}
-
-static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
- void *data)
-{
- int ret;
-
- ret = request_irq(IRQ_GPIOD(25), detect_irq,
- IRQF_TRIGGER_FALLING, "mmc-detect", data);
- if (ret)
- goto out;
- return 0;
-out:
- return ret;
-}
-
-static void mx21ads_sdhc_exit(struct device *dev, void *data)
-{
- free_irq(IRQ_GPIOD(25), data);
-}
-
-static struct imxmmc_platform_data mx21ads_sdhc_pdata = {
- .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
- .get_ro = mx21ads_sdhc_get_ro,
- .init = mx21ads_sdhc_init,
- .exit = mx21ads_sdhc_exit,
-};
-
-static struct mxc_nand_platform_data mx21ads_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-static struct map_desc mx21ads_io_desc[] __initdata = {
- /*
- * Memory-mapped I/O on MX21ADS Base board:
- * - CS8900A Ethernet controller
- * - ST16C2552CJ UART
- * - CPU and Base board version
- * - Base board I/O register
- */
- {
- .virtual = MX21ADS_MMIO_BASE_ADDR,
- .pfn = __phys_to_pfn(CS1_BASE_ADDR),
- .length = MX21ADS_MMIO_SIZE,
- .type = MT_DEVICE,
- },
-};
-
-static void __init mx21ads_map_io(void)
-{
- mx21_map_io();
- iotable_init(mx21ads_io_desc, ARRAY_SIZE(mx21ads_io_desc));
-}
-
-static struct platform_device *platform_devices[] __initdata = {
- &mx21ads_nor_mtd_device,
-};
-
-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);
- mxc_register_device(&mxc_fb_device, &mx21ads_fb_data);
- mxc_register_device(&mxc_sdhc_device0, &mx21ads_sdhc_pdata);
- mxc_register_device(&mxc_nand_device, &mx21ads_nand_board_info);
-
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mx21ads_timer_init(void)
-{
- mx21_clocks_init(32768, 26000000);
-}
-
-static struct sys_timer mx21ads_timer = {
- .init = mx21ads_timer_init,
-};
-
-MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
- /* maintainer: Freescale Semiconductor, Inc. */
- .phys_io = AIPI_BASE_ADDR,
- .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx21ads_map_io,
- .init_irq = mx21_init_irq,
- .init_machine = mx21ads_board_init,
- .timer = &mx21ads_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c
deleted file mode 100644
index 83e412b713e..00000000000
--- a/arch/arm/mach-mx2/mx27ads.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright (C) 2002 Shane Nay (shane@minirl.com)
- * Copyright 2006-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 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/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <mach/gpio.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.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.h"
-
-static unsigned int mx27ads_pins[] = {
- /* UART0 */
- PE12_PF_UART1_TXD,
- PE13_PF_UART1_RXD,
- PE14_PF_UART1_CTS,
- PE15_PF_UART1_RTS,
- /* UART1 */
- PE3_PF_UART2_CTS,
- PE4_PF_UART2_RTS,
- PE6_PF_UART2_TXD,
- PE7_PF_UART2_RXD,
- /* UART2 */
- PE8_PF_UART3_TXD,
- PE9_PF_UART3_RXD,
- PE10_PF_UART3_CTS,
- PE11_PF_UART3_RTS,
- /* UART3 */
- PB26_AF_UART4_RTS,
- PB28_AF_UART4_TXD,
- PB29_AF_UART4_CTS,
- PB31_AF_UART4_RXD,
- /* UART4 */
- PB18_AF_UART5_TXD,
- PB19_AF_UART5_RXD,
- PB20_AF_UART5_CTS,
- PB21_AF_UART5_RTS,
- /* UART5 */
- PB10_AF_UART6_TXD,
- PB12_AF_UART6_CTS,
- PB11_AF_UART6_RXD,
- PB13_AF_UART6_RTS,
- /* FEC */
- PD0_AIN_FEC_TXD0,
- PD1_AIN_FEC_TXD1,
- PD2_AIN_FEC_TXD2,
- PD3_AIN_FEC_TXD3,
- PD4_AOUT_FEC_RX_ER,
- PD5_AOUT_FEC_RXD1,
- PD6_AOUT_FEC_RXD2,
- PD7_AOUT_FEC_RXD3,
- PD8_AF_FEC_MDIO,
- PD9_AIN_FEC_MDC,
- PD10_AOUT_FEC_CRS,
- PD11_AOUT_FEC_TX_CLK,
- PD12_AOUT_FEC_RXD0,
- PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_RX_CLK,
- PD15_AOUT_FEC_COL,
- PD16_AIN_FEC_TX_ER,
- PF23_AIN_FEC_TX_EN,
- /* I2C2 */
- PC5_PF_I2C2_SDA,
- PC6_PF_I2C2_SCL,
- /* FB */
- 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,
- PA24_PF_REV,
- PA25_PF_CLS,
- PA26_PF_PS,
- PA27_PF_SPL_SPR,
- PA28_PF_HSYNC,
- PA29_PF_VSYNC,
- PA30_PF_CONTRAST,
- PA31_PF_OE_ACD,
- /* OWIRE */
- PE16_AF_OWIRE,
- /* SDHC1*/
- PE18_PF_SD1_D0,
- PE19_PF_SD1_D1,
- PE20_PF_SD1_D2,
- PE21_PF_SD1_D3,
- PE22_PF_SD1_CMD,
- PE23_PF_SD1_CLK,
- /* SDHC2*/
- PB4_PF_SD2_D0,
- PB5_PF_SD2_D1,
- PB6_PF_SD2_D2,
- PB7_PF_SD2_D3,
- PB8_PF_SD2_CMD,
- PB9_PF_SD2_CLK,
-};
-
-static struct mxc_nand_platform_data mx27ads_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-/* ADS's NOR flash */
-static struct physmap_flash_data mx27ads_flash_data = {
- .width = 2,
-};
-
-static struct resource mx27ads_flash_resource = {
- .start = 0xc0000000,
- .end = 0xc0000000 + 0x02000000 - 1,
- .flags = IORESOURCE_MEM,
-
-};
-
-static struct platform_device mx27ads_nor_mtd_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &mx27ads_flash_data,
- },
- .num_resources = 1,
- .resource = &mx27ads_flash_resource,
-};
-
-static struct imxi2c_platform_data mx27ads_i2c_data = {
- .bitrate = 100000,
-};
-
-static struct i2c_board_info mx27ads_i2c_devices[] = {
-};
-
-void lcd_power(int on)
-{
- if (on)
- __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
- else
- __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
-}
-
-static struct imx_fb_videomode mx27ads_modes[] = {
- {
- .mode = {
- .name = "Sharp-LQ035Q7",
- .refresh = 60,
- .xres = 240,
- .yres = 320,
- .pixclock = 188679, /* in ps (5.3MHz) */
- .hsync_len = 1,
- .left_margin = 9,
- .right_margin = 16,
- .vsync_len = 1,
- .upper_margin = 7,
- .lower_margin = 9,
- },
- .bpp = 16,
- .pcr = 0xFB008BC0,
- },
-};
-
-static struct imx_fb_platform_data mx27ads_fb_data = {
- .mode = mx27ads_modes,
- .num_modes = ARRAY_SIZE(mx27ads_modes),
-
- /*
- * - HSYNC active high
- * - VSYNC active high
- * - clk notenabled while idle
- * - clock inverted
- * - data not inverted
- * - data enable low active
- * - enable sharp mode
- */
- .pwmr = 0x00A903FF,
- .lscr1 = 0x00120300,
- .dmacr = 0x00020010,
-
- .lcd_power = lcd_power,
-};
-
-static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
- void *data)
-{
- return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING,
- "sdhc1-card-detect", data);
-}
-
-static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
- void *data)
-{
- return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING,
- "sdhc2-card-detect", data);
-}
-
-static void mx27ads_sdhc1_exit(struct device *dev, void *data)
-{
- free_irq(IRQ_GPIOE(21), data);
-}
-
-static void mx27ads_sdhc2_exit(struct device *dev, void *data)
-{
- free_irq(IRQ_GPIOB(7), data);
-}
-
-static struct imxmmc_platform_data sdhc1_pdata = {
- .init = mx27ads_sdhc1_init,
- .exit = mx27ads_sdhc1_exit,
-};
-
-static struct imxmmc_platform_data sdhc2_pdata = {
- .init = mx27ads_sdhc2_init,
- .exit = mx27ads_sdhc2_exit,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
- &mx27ads_nor_mtd_device,
- &mxc_fec_device,
- &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 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(&mxc_nand_device, &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);
- 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);
-
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mx27ads_timer_init(void)
-{
- unsigned long fref = 26000000;
-
- if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
- fref = 27000000;
-
- mx27_clocks_init(fref);
-}
-
-static struct sys_timer mx27ads_timer = {
- .init = mx27ads_timer_init,
-};
-
-static struct map_desc mx27ads_io_desc[] __initdata = {
- {
- .virtual = PBC_BASE_ADDRESS,
- .pfn = __phys_to_pfn(CS4_BASE_ADDR),
- .length = SZ_1M,
- .type = MT_DEVICE,
- },
-};
-
-static void __init mx27ads_map_io(void)
-{
- mx27_map_io();
- iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
-}
-
-MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
- /* maintainer: Freescale Semiconductor, Inc. */
- .phys_io = AIPI_BASE_ADDR,
- .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx27ads_map_io,
- .init_irq = mx27_init_irq,
- .init_machine = mx27ads_board_init,
- .timer = &mx27ads_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-mx2/mx27lite.c b/arch/arm/mach-mx2/mx27lite.c
deleted file mode 100644
index 82ea227ea0c..00000000000
--- a/arch/arm/mach-mx2/mx27lite.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
- * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
- * Copyright 2009 Daniel Schaeffer (daniel.schaeffer@timesys.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/platform_device.h>
-#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.h>
-#include <mach/board-mx27lite.h>
-
-#include "devices.h"
-
-static unsigned int mx27lite_pins[] = {
- /* UART1 */
- PE12_PF_UART1_TXD,
- PE13_PF_UART1_RXD,
- PE14_PF_UART1_CTS,
- PE15_PF_UART1_RTS,
- /* FEC */
- PD0_AIN_FEC_TXD0,
- PD1_AIN_FEC_TXD1,
- PD2_AIN_FEC_TXD2,
- PD3_AIN_FEC_TXD3,
- PD4_AOUT_FEC_RX_ER,
- PD5_AOUT_FEC_RXD1,
- PD6_AOUT_FEC_RXD2,
- PD7_AOUT_FEC_RXD3,
- PD8_AF_FEC_MDIO,
- PD9_AIN_FEC_MDC,
- PD10_AOUT_FEC_CRS,
- PD11_AOUT_FEC_TX_CLK,
- PD12_AOUT_FEC_RXD0,
- PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_RX_CLK,
- PD15_AOUT_FEC_COL,
- PD16_AIN_FEC_TX_ER,
- PF23_AIN_FEC_TX_EN,
-};
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_fec_device,
-};
-
-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);
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mx27lite_timer_init(void)
-{
- mx27_clocks_init(26000000);
-}
-
-static struct sys_timer mx27lite_timer = {
- .init = mx27lite_timer_init,
-};
-
-MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
- .phys_io = AIPI_BASE_ADDR,
- .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx27_map_io,
- .init_irq = mx27_init_irq,
- .init_machine = mx27lite_init,
- .timer = &mx27lite_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27pdk.c b/arch/arm/mach-mx2/mx27pdk.c
deleted file mode 100644
index 6761d1b79e4..00000000000
--- a/arch/arm/mach-mx2/mx27pdk.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * Author: Fabio Estevam <fabio.estevam@freescale.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/platform_device.h>
-#include <linux/gpio.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.h>
-#include <mach/board-mx27pdk.h>
-
-#include "devices.h"
-
-static unsigned int mx27pdk_pins[] = {
- /* UART1 */
- PE12_PF_UART1_TXD,
- PE13_PF_UART1_RXD,
- PE14_PF_UART1_CTS,
- PE15_PF_UART1_RTS,
- /* FEC */
- PD0_AIN_FEC_TXD0,
- PD1_AIN_FEC_TXD1,
- PD2_AIN_FEC_TXD2,
- PD3_AIN_FEC_TXD3,
- PD4_AOUT_FEC_RX_ER,
- PD5_AOUT_FEC_RXD1,
- PD6_AOUT_FEC_RXD2,
- PD7_AOUT_FEC_RXD3,
- PD8_AF_FEC_MDIO,
- PD9_AIN_FEC_MDC,
- PD10_AOUT_FEC_CRS,
- PD11_AOUT_FEC_TX_CLK,
- PD12_AOUT_FEC_RXD0,
- PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_RX_CLK,
- PD15_AOUT_FEC_COL,
- PD16_AIN_FEC_TX_ER,
- PF23_AIN_FEC_TX_EN,
-};
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_fec_device,
-};
-
-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);
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mx27pdk_timer_init(void)
-{
- mx27_clocks_init(26000000);
-}
-
-static struct sys_timer mx27pdk_timer = {
- .init = mx27pdk_timer_init,
-};
-
-MACHINE_START(MX27_3DS, "Freescale MX27PDK")
- /* maintainer: Freescale Semiconductor, Inc. */
- .phys_io = AIPI_BASE_ADDR,
- .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx27_map_io,
- .init_irq = mx27_init_irq,
- .init_machine = mx27pdk_init,
- .timer = &mx27pdk_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx2/mxt_td60.c b/arch/arm/mach-mx2/mxt_td60.c
deleted file mode 100644
index 8bcc1a5b882..00000000000
--- a/arch/arm/mach-mx2/mxt_td60.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright (C) 2002 Shane Nay (shane@minirl.com)
- * Copyright 2006-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 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/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <linux/gpio.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux.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.h"
-
-static unsigned int mxt_td60_pins[] __initdata = {
- /* UART0 */
- PE12_PF_UART1_TXD,
- PE13_PF_UART1_RXD,
- PE14_PF_UART1_CTS,
- PE15_PF_UART1_RTS,
- /* UART1 */
- PE3_PF_UART2_CTS,
- PE4_PF_UART2_RTS,
- PE6_PF_UART2_TXD,
- PE7_PF_UART2_RXD,
- /* UART2 */
- PE8_PF_UART3_TXD,
- PE9_PF_UART3_RXD,
- PE10_PF_UART3_CTS,
- PE11_PF_UART3_RTS,
- /* FEC */
- PD0_AIN_FEC_TXD0,
- PD1_AIN_FEC_TXD1,
- PD2_AIN_FEC_TXD2,
- PD3_AIN_FEC_TXD3,
- PD4_AOUT_FEC_RX_ER,
- PD5_AOUT_FEC_RXD1,
- PD6_AOUT_FEC_RXD2,
- PD7_AOUT_FEC_RXD3,
- PD8_AF_FEC_MDIO,
- PD9_AIN_FEC_MDC,
- PD10_AOUT_FEC_CRS,
- PD11_AOUT_FEC_TX_CLK,
- PD12_AOUT_FEC_RXD0,
- PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_RX_CLK,
- PD15_AOUT_FEC_COL,
- PD16_AIN_FEC_TX_ER,
- PF23_AIN_FEC_TX_EN,
- /* I2C1 */
- PD17_PF_I2C_DATA,
- PD18_PF_I2C_CLK,
- /* I2C2 */
- PC5_PF_I2C2_SDA,
- PC6_PF_I2C2_SCL,
- /* FB */
- 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,
- PA25_PF_CLS,
- PA27_PF_SPL_SPR,
- PA28_PF_HSYNC,
- PA29_PF_VSYNC,
- PA30_PF_CONTRAST,
- PA31_PF_OE_ACD,
- /* OWIRE */
- PE16_AF_OWIRE,
- /* SDHC1*/
- PE18_PF_SD1_D0,
- PE19_PF_SD1_D1,
- PE20_PF_SD1_D2,
- PE21_PF_SD1_D3,
- PE22_PF_SD1_CMD,
- PE23_PF_SD1_CLK,
- PF8_AF_ATA_IORDY,
- /* SDHC2*/
- PB4_PF_SD2_D0,
- PB5_PF_SD2_D1,
- PB6_PF_SD2_D2,
- PB7_PF_SD2_D3,
- PB8_PF_SD2_CMD,
- PB9_PF_SD2_CLK,
-};
-
-static struct mxc_nand_platform_data mxt_td60_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-static struct imxi2c_platform_data mxt_td60_i2c_data = {
- .bitrate = 100000,
-};
-
-/* PCA9557 */
-static int mxt_td60_pca9557_setup(struct i2c_client *client,
- unsigned gpio_base, unsigned ngpio,
- void *context)
-{
- static int mxt_td60_gpio_value[] = {
- -1, -1, -1, -1, -1, -1, -1, 1
- };
- int n;
-
- for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) {
- gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp");
- if (mxt_td60_gpio_value[n] < 0)
- gpio_direction_input(gpio_base + n);
- else
- gpio_direction_output(gpio_base + n,
- mxt_td60_gpio_value[n]);
- gpio_export(gpio_base + n, 0);
- }
-
- return 0;
-}
-
-static struct pca953x_platform_data mxt_td60_pca9557_pdata = {
- .gpio_base = 240, /* place PCA9557 after all MX27 gpio pins */
- .invert = 0, /* Do not invert */
- .setup = mxt_td60_pca9557_setup,
-};
-
-static struct i2c_board_info mxt_td60_i2c_devices[] = {
- {
- I2C_BOARD_INFO("pca9557", 0x18),
- .platform_data = &mxt_td60_pca9557_pdata,
- },
-};
-
-static struct imxi2c_platform_data mxt_td60_i2c2_data = {
- .bitrate = 100000,
-};
-
-static struct i2c_board_info mxt_td60_i2c2_devices[] = {
-};
-
-static struct imx_fb_videomode mxt_td60_modes[] = {
- {
- .mode = {
- .name = "Chimei LW700AT9003",
- .refresh = 60,
- .xres = 800,
- .yres = 480,
- .pixclock = 30303,
- .hsync_len = 64,
- .left_margin = 0x67,
- .right_margin = 0x68,
- .vsync_len = 16,
- .upper_margin = 0x0f,
- .lower_margin = 0x0f,
- },
- .bpp = 16,
- .pcr = 0xFA208B83,
- },
-};
-
-static struct imx_fb_platform_data mxt_td60_fb_data = {
- .mode = mxt_td60_modes,
- .num_modes = ARRAY_SIZE(mxt_td60_modes),
-
- /*
- * - HSYNC active high
- * - VSYNC active high
- * - clk notenabled while idle
- * - clock inverted
- * - data not inverted
- * - data enable low active
- * - enable sharp mode
- */
- .pwmr = 0x00A903FF,
- .lscr1 = 0x00120300,
- .dmacr = 0x00020010,
-};
-
-static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
- void *data)
-{
- return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING,
- "sdhc1-card-detect", data);
-}
-
-static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
-{
- free_irq(IRQ_GPIOF(8), data);
-}
-
-static struct imxmmc_platform_data sdhc1_pdata = {
- .init = mxt_td60_sdhc1_init,
- .exit = mxt_td60_sdhc1_exit,
-};
-
-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 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(&mxc_nand_device, &mxt_td60_nand_board_info);
-
- i2c_register_board_info(0, mxt_td60_i2c_devices,
- ARRAY_SIZE(mxt_td60_i2c_devices));
-
- 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);
- mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
- mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
-
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init mxt_td60_timer_init(void)
-{
- mx27_clocks_init(26000000);
-}
-
-static struct sys_timer mxt_td60_timer = {
- .init = mxt_td60_timer_init,
-};
-
-MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
- /* maintainer: Maxtrack Industrial */
- .phys_io = AIPI_BASE_ADDR,
- .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx27_map_io,
- .init_irq = mx27_init_irq,
- .init_machine = mxt_td60_board_init,
- .timer = &mxt_td60_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-mx2/pca100.c b/arch/arm/mach-mx2/pca100.c
deleted file mode 100644
index aea3d340d2e..00000000000
--- a/arch/arm/mach-mx2/pca100.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
- * Copyright (C) 2009 Sascha Hauer (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/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-#include <linux/dma-mapping.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/eeprom.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux.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/mxc_nand.h>
-#include <mach/irqs.h>
-#include <mach/mmc.h>
-
-#include "devices.h"
-
-static int pca100_pins[] = {
- /* UART1 */
- PE12_PF_UART1_TXD,
- PE13_PF_UART1_RXD,
- PE14_PF_UART1_CTS,
- PE15_PF_UART1_RTS,
- /* SDHC */
- PB4_PF_SD2_D0,
- PB5_PF_SD2_D1,
- PB6_PF_SD2_D2,
- PB7_PF_SD2_D3,
- PB8_PF_SD2_CMD,
- PB9_PF_SD2_CLK,
- /* FEC */
- PD0_AIN_FEC_TXD0,
- PD1_AIN_FEC_TXD1,
- PD2_AIN_FEC_TXD2,
- PD3_AIN_FEC_TXD3,
- PD4_AOUT_FEC_RX_ER,
- PD5_AOUT_FEC_RXD1,
- PD6_AOUT_FEC_RXD2,
- PD7_AOUT_FEC_RXD3,
- PD8_AF_FEC_MDIO,
- PD9_AIN_FEC_MDC,
- PD10_AOUT_FEC_CRS,
- PD11_AOUT_FEC_TX_CLK,
- PD12_AOUT_FEC_RXD0,
- PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_RX_CLK,
- PD15_AOUT_FEC_COL,
- PD16_AIN_FEC_TX_ER,
- PF23_AIN_FEC_TX_EN,
- /* SSI1 */
- PC20_PF_SSI1_FS,
- PC21_PF_SSI1_RXD,
- PC22_PF_SSI1_TXD,
- PC23_PF_SSI1_CLK,
- /* onboard I2C */
- PC5_PF_I2C2_SDA,
- PC6_PF_I2C2_SCL,
- /* external I2C */
- PD17_PF_I2C_DATA,
- PD18_PF_I2C_CLK,
- /* SPI1 */
- PD25_PF_CSPI1_RDY,
- PD29_PF_CSPI1_SCLK,
- PD30_PF_CSPI1_MISO,
- PD31_PF_CSPI1_MOSI,
-};
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct mxc_nand_platform_data pca100_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
- &mxc_w1_master_device,
- &mxc_fec_device,
-};
-
-static struct imxi2c_platform_data pca100_i2c_1_data = {
- .bitrate = 100000,
-};
-
-static struct at24_platform_data board_eeprom = {
- .byte_len = 4096,
- .page_size = 32,
- .flags = AT24_FLAG_ADDR16,
-};
-
-static struct i2c_board_info pca100_i2c_devices[] = {
- {
- I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
- .platform_data = &board_eeprom,
- }, {
- I2C_BOARD_INFO("rtc-pcf8563", 0x51),
- .type = "pcf8563"
- }, {
- I2C_BOARD_INFO("lm75", 0x4a),
- .type = "lm75"
- }
-};
-
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-static struct spi_eeprom at25320 = {
- .name = "at25320an",
- .byte_len = 4096,
- .page_size = 32,
- .flags = EE_ADDR2,
-};
-
-static struct spi_board_info pca100_spi_board_info[] __initdata = {
- {
- .modalias = "at25",
- .max_speed_hz = 30000,
- .bus_num = 0,
- .chip_select = 1,
- .platform_data = &at25320,
- },
-};
-
-static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27};
-
-static struct spi_imx_master pca100_spi_0_data = {
- .chipselect = pca100_spi_cs,
- .num_chipselect = ARRAY_SIZE(pca100_spi_cs),
-};
-#endif
-
-static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
- void *data)
-{
- int ret;
-
- ret = request_irq(IRQ_GPIOC(29), detect_irq,
- IRQF_DISABLED | IRQF_TRIGGER_FALLING,
- "imx-mmc-detect", data);
- if (ret)
- printk(KERN_ERR
- "pca100: Failed to reuest irq for sd/mmc detection\n");
-
- return ret;
-}
-
-static void pca100_sdhc2_exit(struct device *dev, void *data)
-{
- free_irq(IRQ_GPIOC(29), data);
-}
-
-static struct imxmmc_platform_data sdhc_pdata = {
- .init = pca100_sdhc2_init,
- .exit = pca100_sdhc2_exit,
-};
-
-static void __init pca100_init(void)
-{
- int ret;
-
- ret = mxc_gpio_setup_multiple_pins(pca100_pins,
- ARRAY_SIZE(pca100_pins), "PCA100");
- if (ret)
- printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
-
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
- mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN);
- mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
-
- mxc_register_device(&mxc_nand_device, &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);
-
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
- spi_register_board_info(pca100_spi_board_info,
- ARRAY_SIZE(pca100_spi_board_info));
- mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data);
-#endif
-
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
-
-static void __init pca100_timer_init(void)
-{
- mx27_clocks_init(26000000);
-}
-
-static struct sys_timer pca100_timer = {
- .init = pca100_timer_init,
-};
-
-MACHINE_START(PCA100, "phyCARD-i.MX27")
- .phys_io = AIPI_BASE_ADDR,
- .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx27_map_io,
- .init_irq = mx27_init_irq,
- .init_machine = pca100_init,
- .timer = &pca100_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c
deleted file mode 100644
index 906d59b0a7a..00000000000
--- a/arch/arm/mach-mx2/pcm038.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
- * 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/i2c.h>
-#include <linux/i2c/at24.h>
-#include <linux/io.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/mtd/physmap.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/spi/spi.h>
-#include <linux/irq.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-
-#include <mach/board-pcm038.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/i2c.h>
-#include <mach/iomux.h>
-#include <mach/imx-uart.h>
-#include <mach/mxc_nand.h>
-#include <mach/spi.h>
-
-#include "devices.h"
-
-static int pcm038_pins[] = {
- /* UART1 */
- PE12_PF_UART1_TXD,
- PE13_PF_UART1_RXD,
- PE14_PF_UART1_CTS,
- PE15_PF_UART1_RTS,
- /* UART2 */
- PE3_PF_UART2_CTS,
- PE4_PF_UART2_RTS,
- PE6_PF_UART2_TXD,
- PE7_PF_UART2_RXD,
- /* UART3 */
- PE8_PF_UART3_TXD,
- PE9_PF_UART3_RXD,
- PE10_PF_UART3_CTS,
- PE11_PF_UART3_RTS,
- /* FEC */
- PD0_AIN_FEC_TXD0,
- PD1_AIN_FEC_TXD1,
- PD2_AIN_FEC_TXD2,
- PD3_AIN_FEC_TXD3,
- PD4_AOUT_FEC_RX_ER,
- PD5_AOUT_FEC_RXD1,
- PD6_AOUT_FEC_RXD2,
- PD7_AOUT_FEC_RXD3,
- PD8_AF_FEC_MDIO,
- PD9_AIN_FEC_MDC,
- PD10_AOUT_FEC_CRS,
- PD11_AOUT_FEC_TX_CLK,
- PD12_AOUT_FEC_RXD0,
- PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_RX_CLK,
- PD15_AOUT_FEC_COL,
- PD16_AIN_FEC_TX_ER,
- PF23_AIN_FEC_TX_EN,
- /* I2C2 */
- PC5_PF_I2C2_SDA,
- PC6_PF_I2C2_SCL,
- /* SPI1 */
- PD25_PF_CSPI1_RDY,
- PD29_PF_CSPI1_SCLK,
- PD30_PF_CSPI1_MISO,
- PD31_PF_CSPI1_MOSI,
- /* SSI1 */
- PC20_PF_SSI1_FS,
- PC21_PF_SSI1_RXD,
- PC22_PF_SSI1_TXD,
- PC23_PF_SSI1_CLK,
- /* SSI4 */
- PC16_PF_SSI4_FS,
- PC17_PF_SSI4_RXD,
- PC18_PF_SSI4_TXD,
- PC19_PF_SSI4_CLK,
-};
-
-/*
- * Phytec's PCM038 comes with 2MiB battery buffered SRAM,
- * 16 bit width
- */
-
-static struct platdata_mtd_ram pcm038_sram_data = {
- .bankwidth = 2,
-};
-
-static struct resource pcm038_sram_resource = {
- .start = CS1_BASE_ADDR,
- .end = CS1_BASE_ADDR + 512 * 1024 - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device pcm038_sram_mtd_device = {
- .name = "mtd-ram",
- .id = 0,
- .dev = {
- .platform_data = &pcm038_sram_data,
- },
- .num_resources = 1,
- .resource = &pcm038_sram_resource,
-};
-
-/*
- * Phytec's phyCORE-i.MX27 comes with 32MiB flash,
- * 16 bit width
- */
-static struct physmap_flash_data pcm038_flash_data = {
- .width = 2,
-};
-
-static struct resource pcm038_flash_resource = {
- .start = 0xc0000000,
- .end = 0xc1ffffff,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device pcm038_nor_mtd_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &pcm038_flash_data,
- },
- .num_resources = 1,
- .resource = &pcm038_flash_resource,
-};
-
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- },
-};
-
-static struct mxc_nand_platform_data pcm038_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-static struct platform_device *platform_devices[] __initdata = {
- &pcm038_nor_mtd_device,
- &mxc_w1_master_device,
- &mxc_fec_device,
- &pcm038_sram_mtd_device,
-};
-
-/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
- * setup other stuffs to access the sram. */
-static void __init pcm038_init_sram(void)
-{
- __raw_writel(0x0000d843, CSCR_U(1));
- __raw_writel(0x22252521, CSCR_L(1));
- __raw_writel(0x22220a00, CSCR_A(1));
-}
-
-static struct imxi2c_platform_data pcm038_i2c_1_data = {
- .bitrate = 100000,
-};
-
-static struct at24_platform_data board_eeprom = {
- .byte_len = 4096,
- .page_size = 32,
- .flags = AT24_FLAG_ADDR16,
-};
-
-static struct i2c_board_info pcm038_i2c_devices[] = {
- {
- I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
- .platform_data = &board_eeprom,
- }, {
- I2C_BOARD_INFO("pcf8563", 0x51),
- }, {
- I2C_BOARD_INFO("lm75", 0x4a),
- }
-};
-
-static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
-
-static struct spi_imx_master pcm038_spi_0_data = {
- .chipselect = pcm038_spi_cs,
- .num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
-};
-
-static struct regulator_consumer_supply sdhc1_consumers[] = {
- {
- .dev = &mxc_sdhc_device1.dev,
- .supply = "sdhc_vcc",
- },
-};
-
-static struct regulator_init_data sdhc1_data = {
- .constraints = {
- .min_uV = 3000000,
- .max_uV = 3400000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
- .valid_modes_mask = REGULATOR_MODE_NORMAL |
- REGULATOR_MODE_FAST,
- .always_on = 0,
- .boot_on = 0,
- },
- .num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
- .consumer_supplies = sdhc1_consumers,
-};
-
-static struct regulator_consumer_supply cam_consumers[] = {
- {
- .dev = NULL,
- .supply = "imx_cam_vcc",
- },
-};
-
-static struct regulator_init_data cam_data = {
- .constraints = {
- .min_uV = 3000000,
- .max_uV = 3400000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
- .valid_modes_mask = REGULATOR_MODE_NORMAL |
- REGULATOR_MODE_FAST,
- .always_on = 0,
- .boot_on = 0,
- },
- .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
- .consumer_supplies = cam_consumers,
-};
-
-struct mc13783_regulator_init_data pcm038_regulators[] = {
- {
- .id = MC13783_REGU_VCAM,
- .init_data = &cam_data,
- }, {
- .id = MC13783_REGU_VMMC1,
- .init_data = &sdhc1_data,
- },
-};
-
-static struct mc13783_platform_data pcm038_pmic = {
- .regulators = pcm038_regulators,
- .num_regulators = ARRAY_SIZE(pcm038_regulators),
- .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
- MC13783_USE_TOUCHSCREEN,
-};
-
-static struct spi_board_info pcm038_spi_board_info[] __initdata = {
- {
- .modalias = "mc13783",
- .irq = IRQ_GPIOB(23),
- .max_speed_hz = 300000,
- .bus_num = 0,
- .chip_select = 0,
- .platform_data = &pcm038_pmic,
- .mode = SPI_CS_HIGH,
- }
-};
-
-static void __init pcm038_init(void)
-{
- mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
- "PCM038");
-
- 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]);
-
- mxc_gpio_mode(PE16_AF_OWIRE);
- mxc_register_device(&mxc_nand_device, &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);
-
- /* PE18 for user-LED D40 */
- mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
-
- mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
-
- /* MC13783 IRQ */
- mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
-
- mxc_register_device(&mxc_spi_device0, &pcm038_spi_0_data);
- spi_register_board_info(pcm038_spi_board_info,
- ARRAY_SIZE(pcm038_spi_board_info));
-
- platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-
-#ifdef CONFIG_MACH_PCM970_BASEBOARD
- pcm970_baseboard_init();
-#endif
-}
-
-static void __init pcm038_timer_init(void)
-{
- mx27_clocks_init(26000000);
-}
-
-static struct sys_timer pcm038_timer = {
- .init = pcm038_timer_init,
-};
-
-MACHINE_START(PCM038, "phyCORE-i.MX27")
- .phys_io = AIPI_BASE_ADDR,
- .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx27_map_io,
- .init_irq = mx27_init_irq,
- .init_machine = pcm038_init,
- .timer = &pcm038_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c
index 3cb7f457e5d..4aafd5b8b85 100644
--- a/arch/arm/mach-mx2/pcm970-baseboard.c
+++ b/arch/arm/mach-mx2/pcm970-baseboard.c
@@ -24,7 +24,7 @@
#include <asm/mach/arch.h>
#include <mach/common.h>
-#include <mach/iomux.h>
+#include <mach/iomux-mx27.h>
#include <mach/imxfb.h>
#include <mach/hardware.h>
#include <mach/mmc.h>
@@ -190,8 +190,8 @@ static struct imx_fb_platform_data pcm038_fb_data = {
static struct resource pcm970_sja1000_resources[] = {
{
- .start = CS4_BASE_ADDR,
- .end = CS4_BASE_ADDR + 0x100 - 1,
+ .start = MX27_CS4_BASE_ADDR,
+ .end = MX27_CS4_BASE_ADDR + 0x100 - 1,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_GPIOE(19),
diff --git a/arch/arm/mach-mx2/serial.c b/arch/arm/mach-mx2/serial.c
index 40a485cdc10..1c0c835b225 100644
--- a/arch/arm/mach-mx2/serial.c
+++ b/arch/arm/mach-mx2/serial.c
@@ -26,12 +26,12 @@
static struct resource uart0[] = {
{
- .start = UART1_BASE_ADDR,
- .end = UART1_BASE_ADDR + 0x0B5,
+ .start = MX2x_UART1_BASE_ADDR,
+ .end = MX2x_UART1_BASE_ADDR + 0x0B5,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_UART1,
- .end = MXC_INT_UART1,
+ .start = MX2x_INT_UART1,
+ .end = MX2x_INT_UART1,
.flags = IORESOURCE_IRQ,
},
};
@@ -45,12 +45,12 @@ struct platform_device mxc_uart_device0 = {
static struct resource uart1[] = {
{
- .start = UART2_BASE_ADDR,
- .end = UART2_BASE_ADDR + 0x0B5,
+ .start = MX2x_UART2_BASE_ADDR,
+ .end = MX2x_UART2_BASE_ADDR + 0x0B5,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_UART2,
- .end = MXC_INT_UART2,
+ .start = MX2x_INT_UART2,
+ .end = MX2x_INT_UART2,
.flags = IORESOURCE_IRQ,
},
};
@@ -64,12 +64,12 @@ struct platform_device mxc_uart_device1 = {
static struct resource uart2[] = {
{
- .start = UART3_BASE_ADDR,
- .end = UART3_BASE_ADDR + 0x0B5,
+ .start = MX2x_UART3_BASE_ADDR,
+ .end = MX2x_UART3_BASE_ADDR + 0x0B5,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_UART3,
- .end = MXC_INT_UART3,
+ .start = MX2x_INT_UART3,
+ .end = MX2x_INT_UART3,
.flags = IORESOURCE_IRQ,
},
};
@@ -83,12 +83,12 @@ struct platform_device mxc_uart_device2 = {
static struct resource uart3[] = {
{
- .start = UART4_BASE_ADDR,
- .end = UART4_BASE_ADDR + 0x0B5,
+ .start = MX2x_UART4_BASE_ADDR,
+ .end = MX2x_UART4_BASE_ADDR + 0x0B5,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_UART4,
- .end = MXC_INT_UART4,
+ .start = MX2x_INT_UART4,
+ .end = MX2x_INT_UART4,
.flags = IORESOURCE_IRQ,
},
};
@@ -103,12 +103,12 @@ struct platform_device mxc_uart_device3 = {
#ifdef CONFIG_MACH_MX27
static struct resource uart4[] = {
{
- .start = UART5_BASE_ADDR,
- .end = UART5_BASE_ADDR + 0x0B5,
+ .start = MX27_UART5_BASE_ADDR,
+ .end = MX27_UART5_BASE_ADDR + 0x0B5,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_UART5,
- .end = MXC_INT_UART5,
+ .start = MX27_INT_UART5,
+ .end = MX27_INT_UART5,
.flags = IORESOURCE_IRQ,
},
};
@@ -122,12 +122,12 @@ struct platform_device mxc_uart_device4 = {
static struct resource uart5[] = {
{
- .start = UART6_BASE_ADDR,
- .end = UART6_BASE_ADDR + 0x0B5,
+ .start = MX27_UART6_BASE_ADDR,
+ .end = MX27_UART6_BASE_ADDR + 0x0B5,
.flags = IORESOURCE_MEM,
}, {
- .start = MXC_INT_UART6,
- .end = MXC_INT_UART6,
+ .start = MX27_INT_UART6,
+ .end = MX27_INT_UART6,
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
index cc28f56eae8..54d217314ee 100644
--- a/arch/arm/mach-mx25/Kconfig
+++ b/arch/arm/mach-mx25/Kconfig
@@ -3,7 +3,6 @@ if ARCH_MX25
comment "MX25 platforms:"
config MACH_MX25_3DS
- select ARCH_MXC_IOMUX_V3
bool "Support MX25PDK (3DS) Platform"
endif
diff --git a/arch/arm/mach-mx25/Makefile b/arch/arm/mach-mx25/Makefile
index fe23836a9f3..10cebc5ced8 100644
--- a/arch/arm/mach-mx25/Makefile
+++ b/arch/arm/mach-mx25/Makefile
@@ -1,3 +1,3 @@
obj-y := mm.o devices.o
obj-$(CONFIG_ARCH_MX25) += clock.o
-obj-$(CONFIG_MACH_MX25_3DS) += mx25pdk.o
+obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25pdk.o
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c
index 37e1359ad0c..155014993b1 100644
--- a/arch/arm/mach-mx25/clock.c
+++ b/arch/arm/mach-mx25/clock.c
@@ -124,6 +124,11 @@ static unsigned long get_rate_gpt(struct clk *clk)
return get_rate_per(5);
}
+static unsigned long get_rate_lcdc(struct clk *clk)
+{
+ return get_rate_per(7);
+}
+
static unsigned long get_rate_otg(struct clk *clk)
{
return 48000000; /* FIXME */
@@ -167,6 +172,8 @@ 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(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);
@@ -182,6 +189,8 @@ DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
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 _REGISTER_CLOCK(d, n, c) \
{ \
@@ -214,6 +223,8 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
_REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
+ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
};
int __init mx25_clocks_init(void)
@@ -228,6 +239,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);
+
mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
return 0;
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
index 9fdeea1c083..3f4b8a0b5fa 100644
--- a/arch/arm/mach-mx25/devices.c
+++ b/arch/arm/mach-mx25/devices.c
@@ -438,3 +438,65 @@ struct platform_device mx25_fec_device = {
.num_resources = ARRAY_SIZE(mx25_fec_resources),
.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,
+ .end = MX25_DRYICE_BASE_ADDR + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX25_INT_DRYICE,
+ .flags = IORESOURCE_IRQ
+ },
+};
+
+struct platform_device mx25_rtc_device = {
+ .name = "imxdi_rtc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mx25_rtc_resources),
+ .resource = mx25_rtc_resources,
+};
+
+static struct resource mx25_fb_resources[] = {
+ {
+ .start = MX25_LCDC_BASE_ADDR,
+ .end = MX25_LCDC_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX25_INT_LCDC,
+ .end = MX25_INT_LCDC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mx25_fb_device = {
+ .name = "imx-fb",
+ .id = 0,
+ .resource = mx25_fb_resources,
+ .num_resources = ARRAY_SIZE(mx25_fb_resources),
+ .dev = {
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h
index fe5420fcd11..39560e13bc0 100644
--- a/arch/arm/mach-mx25/devices.h
+++ b/arch/arm/mach-mx25/devices.h
@@ -18,3 +18,6 @@ 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;
diff --git a/arch/arm/mach-mx25/mach-mx25pdk.c b/arch/arm/mach-mx25/mach-mx25pdk.c
new file mode 100644
index 00000000000..83d74109e7d
--- /dev/null
+++ b/arch/arm/mach-mx25/mach-mx25pdk.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2009 Sascha Hauer, <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/delay.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/fec.h>
+#include <linux/platform_device.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/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 = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct pad_desc mx25pdk_pads[] = {
+ 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,
+ MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */
+ MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */
+
+ /* 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,
+};
+
+static struct fec_platform_data mx25_fec_pdata = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+#define FEC_ENABLE_GPIO 35
+#define FEC_RESET_B_GPIO 104
+
+static void __init mx25pdk_fec_reset(void)
+{
+ gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable");
+ gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset");
+
+ gpio_direction_output(FEC_ENABLE_GPIO, 0); /* drop PHY power */
+ gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */
+ udelay(2);
+
+ /* turn on PHY power and lift reset */
+ gpio_set_value(FEC_ENABLE_GPIO, 1);
+ gpio_set_value(FEC_RESET_B_GPIO, 1);
+}
+
+static struct mxc_nand_platform_data mx25pdk_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static struct imx_fb_videomode mx25pdk_modes[] = {
+ {
+ .mode = {
+ .name = "CRT-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39683,
+ .left_margin = 45,
+ .right_margin = 114,
+ .upper_margin = 33,
+ .lower_margin = 11,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ },
+ .bpp = 16,
+ .pcr = 0xFA208B80,
+ },
+};
+
+static struct imx_fb_platform_data mx25pdk_fb_pdata = {
+ .mode = mx25pdk_modes,
+ .num_modes = ARRAY_SIZE(mx25pdk_modes),
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+};
+
+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);
+ mxc_register_device(&mxc_usbh2, NULL);
+ mxc_register_device(&mxc_nand_device, &mx25pdk_nand_board_info);
+ mxc_register_device(&mx25_rtc_device, NULL);
+ mxc_register_device(&mx25_fb_device, &mx25pdk_fb_pdata);
+
+ mx25pdk_fec_reset();
+ mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
+}
+
+static void __init mx25pdk_timer_init(void)
+{
+ mx25_clocks_init();
+}
+
+static struct sys_timer mx25pdk_timer = {
+ .init = mx25pdk_timer_init,
+};
+
+MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .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 = mx25pdk_init,
+ .timer = &mx25pdk_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx25/mx25pdk.c b/arch/arm/mach-mx25/mx25pdk.c
deleted file mode 100644
index 6f06089246e..00000000000
--- a/arch/arm/mach-mx25/mx25pdk.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2009 Sascha Hauer, <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/delay.h>
-#include <linux/clk.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/fec.h>
-#include <linux/platform_device.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/imx-uart.h>
-#include <mach/mx25.h>
-#include <mach/mxc_nand.h>
-#include "devices.h"
-#include <mach/iomux.h>
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct pad_desc mx25pdk_pads[] = {
- 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,
- MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */
- MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */
-};
-
-static struct fec_platform_data mx25_fec_pdata = {
- .phy = PHY_INTERFACE_MODE_RMII,
-};
-
-#define FEC_ENABLE_GPIO 35
-#define FEC_RESET_B_GPIO 104
-
-static void __init mx25pdk_fec_reset(void)
-{
- gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable");
- gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset");
-
- gpio_direction_output(FEC_ENABLE_GPIO, 0); /* drop PHY power */
- gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */
- udelay(2);
-
- /* turn on PHY power and lift reset */
- gpio_set_value(FEC_ENABLE_GPIO, 1);
- gpio_set_value(FEC_RESET_B_GPIO, 1);
-}
-
-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);
- mxc_register_device(&mxc_usbh2, NULL);
-
- mx25pdk_fec_reset();
- mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
-}
-
-static void __init mx25pdk_timer_init(void)
-{
- mx25_clocks_init();
-}
-
-static struct sys_timer mx25pdk_timer = {
- .init = mx25pdk_timer_init,
-};
-
-MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
- /* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = MX25_AIPS1_BASE_ADDR,
- .io_pg_offst = ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx25_map_io,
- .init_irq = mx25_init_irq,
- .init_machine = mx25pdk_init,
- .timer = &mx25pdk_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index 28294416b0a..170f68e46dd 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -34,6 +34,7 @@ config MACH_MX31ADS_WM1133_EV1
config MACH_PCM037
bool "Support Phytec pcm037 (i.MX31) platforms"
select ARCH_MX31
+ select MXC_ULPI if USB_ULPI
help
Include support for Phytec pcm037 platform. This includes
specific configurations for the board and its peripherals.
@@ -61,6 +62,15 @@ config MACH_MX31_3DS
Include support for MX31PDK (3DS) platform. This includes specific
configurations for the board and its peripherals.
+config MACH_MX31_3DS_MXC_NAND_USE_BBT
+ bool "Make the MXC NAND driver use the in flash Bad Block Table"
+ depends on MACH_MX31_3DS
+ depends on MTD_NAND_MXC
+ help
+ Enable this if you want that the MXC NAND driver uses the in flash
+ Bad Block Table to know what blocks are bad instead of scanning the
+ entire flash looking for bad block markers.
+
config MACH_MX31MOBOARD
bool "Support mx31moboard platforms (EPFL Mobots group)"
select ARCH_MX31
@@ -86,6 +96,7 @@ config MACH_QONG
config MACH_PCM043
bool "Support Phytec pcm043 (i.MX35) platforms"
select ARCH_MX35
+ select MXC_ULPI if USB_ULPI
help
Include support for Phytec pcm043 platform. This includes
specific configurations for the board and its peripherals.
@@ -93,6 +104,7 @@ config MACH_PCM043
config MACH_ARMADILLO5X0
bool "Support Atmark Armadillo-500 Development Base Board"
select ARCH_MX31
+ select MXC_ULPI if USB_ULPI
help
Include support for Atmark Armadillo-500 platform. This includes
specific configurations for the board and its peripherals.
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index 93c7b296be6..5d650fda5d5 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -5,18 +5,22 @@
# Object file lists.
obj-y := mm.o devices.o cpu.o
-obj-$(CONFIG_ARCH_MX31) += clock.o iomux.o
+CFLAGS_mm.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
+CFLAGS_devices.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
+CFLAGS_cpu.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
+obj-$(CONFIG_ARCH_MX31) += clock-imx31.o iomux-imx31.o
obj-$(CONFIG_ARCH_MX35) += clock-imx35.o
-obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o
-obj-$(CONFIG_MACH_MX31LILLY) += mx31lilly.o mx31lilly-db.o
-obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o mx31lite-db.o
-obj-$(CONFIG_MACH_PCM037) += pcm037.o
-obj-$(CONFIG_MACH_PCM037_EET) += pcm037_eet.o
-obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o
-obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \
- mx31moboard-marxbot.o
-obj-$(CONFIG_MACH_QONG) += qong.o
-obj-$(CONFIG_MACH_PCM043) += pcm043.o
-obj-$(CONFIG_MACH_ARMADILLO5X0) += armadillo5x0.o
-obj-$(CONFIG_MACH_MX35_3DS) += mx35pdk.o
-obj-$(CONFIG_MACH_KZM_ARM11_01) += kzmarm11.o
+obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o
+obj-$(CONFIG_MACH_MX31LILLY) += mach-mx31lilly.o mx31lilly-db.o
+obj-$(CONFIG_MACH_MX31LITE) += mach-mx31lite.o mx31lite-db.o
+obj-$(CONFIG_MACH_PCM037) += mach-pcm037.o
+obj-$(CONFIG_MACH_PCM037_EET) += mach-pcm037_eet.o
+obj-$(CONFIG_MACH_MX31_3DS) += mach-mx31_3ds.o
+CFLAGS_mach-mx31_3ds.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS
+obj-$(CONFIG_MACH_MX31MOBOARD) += mach-mx31moboard.o mx31moboard-devboard.o \
+ mx31moboard-marxbot.o mx31moboard-smartbot.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_KZM_ARM11_01) += mach-kzm_arm11_01.o
diff --git a/arch/arm/mach-mx3/armadillo5x0.c b/arch/arm/mach-mx3/armadillo5x0.c
deleted file mode 100644
index 54aab401dbd..00000000000
--- a/arch/arm/mach-mx3/armadillo5x0.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * armadillo5x0.c
- *
- * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- * updates in http://alberdroid.blogspot.com/
- *
- * Based on Atmark Techno, Inc. armadillo 500 BSP 2008
- * Based on mx31ads.c and pcm037.c Great Work!
- *
- * This program is free software; 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/clk.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/smsc911x.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
-#include <linux/io.h>
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
-#include <linux/i2c.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/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 "devices.h"
-#include "crm_regs.h"
-
-static int armadillo5x0_pins[] = {
- /* UART1 */
- MX31_PIN_CTS1__CTS1,
- MX31_PIN_RTS1__RTS1,
- MX31_PIN_TXD1__TXD1,
- MX31_PIN_RXD1__RXD1,
- /* UART2 */
- MX31_PIN_CTS2__CTS2,
- MX31_PIN_RTS2__RTS2,
- MX31_PIN_TXD2__TXD2,
- MX31_PIN_RXD2__RXD2,
- /* LAN9118_IRQ */
- IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO),
- /* SDHC1 */
- MX31_PIN_SD1_DATA3__SD1_DATA3,
- MX31_PIN_SD1_DATA2__SD1_DATA2,
- MX31_PIN_SD1_DATA1__SD1_DATA1,
- MX31_PIN_SD1_DATA0__SD1_DATA0,
- MX31_PIN_SD1_CLK__SD1_CLK,
- MX31_PIN_SD1_CMD__SD1_CMD,
- /* Framebuffer */
- MX31_PIN_LD0__LD0,
- MX31_PIN_LD1__LD1,
- MX31_PIN_LD2__LD2,
- MX31_PIN_LD3__LD3,
- MX31_PIN_LD4__LD4,
- MX31_PIN_LD5__LD5,
- MX31_PIN_LD6__LD6,
- MX31_PIN_LD7__LD7,
- MX31_PIN_LD8__LD8,
- MX31_PIN_LD9__LD9,
- MX31_PIN_LD10__LD10,
- MX31_PIN_LD11__LD11,
- MX31_PIN_LD12__LD12,
- MX31_PIN_LD13__LD13,
- MX31_PIN_LD14__LD14,
- MX31_PIN_LD15__LD15,
- MX31_PIN_LD16__LD16,
- MX31_PIN_LD17__LD17,
- MX31_PIN_VSYNC3__VSYNC3,
- MX31_PIN_HSYNC__HSYNC,
- MX31_PIN_FPSHIFT__FPSHIFT,
- MX31_PIN_DRDY0__DRDY0,
- IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/
- /* I2C2 */
- MX31_PIN_CSPI2_MOSI__SCL,
- MX31_PIN_CSPI2_MISO__SDA,
-};
-
-/* RTC over I2C*/
-#define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4)
-
-static struct i2c_board_info armadillo5x0_i2c_rtc = {
- I2C_BOARD_INFO("s35390a", 0x30),
-};
-
-/* GPIO BUTTONS */
-static struct gpio_keys_button armadillo5x0_buttons[] = {
- {
- .code = KEY_ENTER, /*28*/
- .gpio = IOMUX_TO_GPIO(MX31_PIN_SCLK0),
- .active_low = 1,
- .desc = "menu",
- .wakeup = 1,
- }, {
- .code = KEY_BACK, /*158*/
- .gpio = IOMUX_TO_GPIO(MX31_PIN_SRST0),
- .active_low = 1,
- .desc = "back",
- .wakeup = 1,
- }
-};
-
-static struct gpio_keys_platform_data armadillo5x0_button_data = {
- .buttons = armadillo5x0_buttons,
- .nbuttons = ARRAY_SIZE(armadillo5x0_buttons),
-};
-
-static struct platform_device armadillo5x0_button_device = {
- .name = "gpio-keys",
- .id = -1,
- .num_resources = 0,
- .dev = {
- .platform_data = &armadillo5x0_button_data,
- }
-};
-
-/*
- * NAND Flash
- */
-static struct mxc_nand_platform_data armadillo5x0_nand_flash_pdata = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-/*
- * MTD NOR Flash
- */
-static struct mtd_partition armadillo5x0_nor_flash_partitions[] = {
- {
- .name = "nor.bootloader",
- .offset = 0x00000000,
- .size = 4*32*1024,
- }, {
- .name = "nor.kernel",
- .offset = MTDPART_OFS_APPEND,
- .size = 16*128*1024,
- }, {
- .name = "nor.userland",
- .offset = MTDPART_OFS_APPEND,
- .size = 110*128*1024,
- }, {
- .name = "nor.config",
- .offset = MTDPART_OFS_APPEND,
- .size = 1*128*1024,
- },
-};
-
-static struct physmap_flash_data armadillo5x0_nor_flash_pdata = {
- .width = 2,
- .parts = armadillo5x0_nor_flash_partitions,
- .nr_parts = ARRAY_SIZE(armadillo5x0_nor_flash_partitions),
-};
-
-static struct resource armadillo5x0_nor_flash_resource = {
- .flags = IORESOURCE_MEM,
- .start = CS0_BASE_ADDR,
- .end = CS0_BASE_ADDR + SZ_64M - 1,
-};
-
-static struct platform_device armadillo5x0_nor_flash = {
- .name = "physmap-flash",
- .id = -1,
- .num_resources = 1,
- .resource = &armadillo5x0_nor_flash_resource,
-};
-
-/*
- * FB support
- */
-static const struct fb_videomode fb_modedb[] = {
- { /* 640x480 @ 60 Hz */
- .name = "CRT-VGA",
- .refresh = 60,
- .xres = 640,
- .yres = 480,
- .pixclock = 39721,
- .left_margin = 35,
- .right_margin = 115,
- .upper_margin = 43,
- .lower_margin = 1,
- .hsync_len = 10,
- .vsync_len = 1,
- .sync = FB_SYNC_OE_ACT_HIGH,
- .vmode = FB_VMODE_NONINTERLACED,
- .flag = 0,
- }, {/* 800x600 @ 56 Hz */
- .name = "CRT-SVGA",
- .refresh = 56,
- .xres = 800,
- .yres = 600,
- .pixclock = 30000,
- .left_margin = 30,
- .right_margin = 108,
- .upper_margin = 13,
- .lower_margin = 10,
- .hsync_len = 10,
- .vsync_len = 1,
- .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT |
- FB_SYNC_VERT_HIGH_ACT,
- .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 = "CRT-VGA",
- .mode = fb_modedb,
- .num_modes = ARRAY_SIZE(fb_modedb),
-};
-
-/*
- * SDHC 1
- * MMC support
- */
-static int armadillo5x0_sdhc1_get_ro(struct device *dev)
-{
- return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
-}
-
-static int armadillo5x0_sdhc1_init(struct device *dev,
- irq_handler_t detect_irq, void *data)
-{
- int ret;
- int gpio_det, gpio_wp;
-
- gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK);
- gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B);
-
- ret = gpio_request(gpio_det, "sdhc-card-detect");
- if (ret)
- return ret;
-
- gpio_direction_input(gpio_det);
-
- ret = gpio_request(gpio_wp, "sdhc-write-protect");
- if (ret)
- goto err_gpio_free;
-
- gpio_direction_input(gpio_wp);
-
- /* When supported the trigger type have to be BOTH */
- ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq,
- IRQF_DISABLED | IRQF_TRIGGER_FALLING,
- "sdhc-detect", data);
-
- if (ret)
- goto err_gpio_free_2;
-
- return 0;
-
-err_gpio_free_2:
- gpio_free(gpio_wp);
-
-err_gpio_free:
- gpio_free(gpio_det);
-
- return ret;
-
-}
-
-static void armadillo5x0_sdhc1_exit(struct device *dev, void *data)
-{
- free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data);
- gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK));
- gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
-}
-
-static struct imxmmc_platform_data sdhc_pdata = {
- .get_ro = armadillo5x0_sdhc1_get_ro,
- .init = armadillo5x0_sdhc1_init,
- .exit = armadillo5x0_sdhc1_exit,
-};
-
-/*
- * SMSC 9118
- * Network support
- */
-static struct resource armadillo5x0_smc911x_resources[] = {
- {
- .start = CS3_BASE_ADDR,
- .end = CS3_BASE_ADDR + SZ_32M - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
- .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
- },
-};
-
-static struct smsc911x_platform_config smsc911x_info = {
- .flags = SMSC911X_USE_16BIT,
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
- .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
-};
-
-static struct platform_device armadillo5x0_smc911x_device = {
- .name = "smsc911x",
- .id = -1,
- .num_resources = ARRAY_SIZE(armadillo5x0_smc911x_resources),
- .resource = armadillo5x0_smc911x_resources,
- .dev = {
- .platform_data = &smsc911x_info,
- },
-};
-
-/* UART device data */
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *devices[] __initdata = {
- &armadillo5x0_smc911x_device,
- &mxc_i2c_device1,
- &armadillo5x0_button_device,
-};
-
-/*
- * Perform board specific initializations
- */
-static void __init armadillo5x0_init(void)
-{
- mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
- ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
-
- platform_add_devices(devices, ARRAY_SIZE(devices));
-
- /* Register UART */
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
-
- /* SMSC9118 IRQ pin */
- gpio_direction_input(MX31_PIN_GPIO1_0);
-
- /* Register SDHC */
- mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
-
- /* Register FB */
- mxc_register_device(&mx3_ipu, &mx3_ipu_data);
- mxc_register_device(&mx3_fb, &mx3fb_pdata);
-
- /* Register NOR Flash */
- mxc_register_device(&armadillo5x0_nor_flash,
- &armadillo5x0_nor_flash_pdata);
-
- /* Register NAND Flash */
- mxc_register_device(&mxc_nand_device, &armadillo5x0_nand_flash_pdata);
-
- /* 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);
-
- /* RTC */
- /* Get RTC IRQ and register the chip */
- if (gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc") == 0) {
- if (gpio_direction_input(ARMADILLO5X0_RTC_GPIO) == 0)
- armadillo5x0_i2c_rtc.irq = gpio_to_irq(ARMADILLO5X0_RTC_GPIO);
- else
- gpio_free(ARMADILLO5X0_RTC_GPIO);
- }
- if (armadillo5x0_i2c_rtc.irq == 0)
- pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
- i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
-}
-
-static void __init armadillo5x0_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-static struct sys_timer armadillo5x0_timer = {
- .init = armadillo5x0_timer_init,
-};
-
-MACHINE_START(ARMADILLO5X0, "Armadillo-500")
- /* Maintainer: Alberto Panizzo */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x00000100,
- .map_io = mx31_map_io,
- .init_irq = mx31_init_irq,
- .timer = &armadillo5x0_timer,
- .init_machine = armadillo5x0_init,
-MACHINE_END
diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c
new file mode 100644
index 00000000000..9a9eb6de612
--- /dev/null
+++ b/arch/arm/mach-mx3/clock-imx31.c
@@ -0,0 +1,630 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <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/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/mx31.h>
+#include <mach/common.h>
+
+#include "crm_regs.h"
+
+#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
+
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ if (div >= 512) {
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 64) {
+ min_pre = (div - 1) / 64 + 1;
+ old_err = 8;
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = (div + *pre - 1) / *pre;
+ } else if (div <= 8) {
+ *pre = div;
+ *post = 1;
+ } else {
+ *pre = 1;
+ *post = div;
+ }
+}
+
+static struct clk mcu_pll_clk;
+static struct clk serial_pll_clk;
+static struct clk ipg_clk;
+static struct clk ckih_clk;
+
+static int cgr_enable(struct clk *clk)
+{
+ u32 reg;
+
+ if (!clk->enable_reg)
+ return 0;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 3 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void cgr_disable(struct clk *clk)
+{
+ u32 reg;
+
+ if (!clk->enable_reg)
+ return;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(3 << clk->enable_shift);
+
+ /* special case for EMI clock */
+ if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
+ reg |= (1 << clk->enable_shift);
+
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static unsigned long pll_ref_get_rate(void)
+{
+ unsigned long ccmr;
+ unsigned int prcs;
+
+ ccmr = __raw_readl(MXC_CCM_CCMR);
+ prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
+ if (prcs == 0x1)
+ return CKIL_CLK_FREQ * 1024;
+ else
+ return clk_get_rate(&ckih_clk);
+}
+
+static unsigned long usb_pll_get_rate(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(MXC_CCM_UPCTL);
+
+ return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static unsigned long serial_pll_get_rate(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(MXC_CCM_SRPCTL);
+
+ return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static unsigned long mcu_pll_get_rate(struct clk *clk)
+{
+ unsigned long reg, ccmr;
+
+ ccmr = __raw_readl(MXC_CCM_CCMR);
+
+ if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
+ return clk_get_rate(&ckih_clk);
+
+ reg = __raw_readl(MXC_CCM_MPCTL);
+
+ return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static int usb_pll_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg |= MXC_CCM_CCMR_UPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+
+ /* No lock bit on MX31, so using max time from spec */
+ udelay(80);
+
+ return 0;
+}
+
+static void usb_pll_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg &= ~MXC_CCM_CCMR_UPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+}
+
+static int serial_pll_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg |= MXC_CCM_CCMR_SPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+
+ /* No lock bit on MX31, so using max time from spec */
+ udelay(80);
+
+ return 0;
+}
+
+static void serial_pll_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg &= ~MXC_CCM_CCMR_SPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+}
+
+#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
+#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
+#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
+
+static unsigned long mcu_main_get_rate(struct clk *clk)
+{
+ u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+
+ if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
+ return clk_get_rate(&serial_pll_clk);
+ else
+ return clk_get_rate(&mcu_pll_clk);
+}
+
+static unsigned long ahb_get_rate(struct clk *clk)
+{
+ unsigned long max_pdf;
+
+ max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
+ MXC_CCM_PDR0_MAX_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (max_pdf + 1);
+}
+
+static unsigned long ipg_get_rate(struct clk *clk)
+{
+ unsigned long ipg_pdf;
+
+ ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
+ MXC_CCM_PDR0_IPG_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (ipg_pdf + 1);
+}
+
+static unsigned long nfc_get_rate(struct clk *clk)
+{
+ unsigned long nfc_pdf;
+
+ nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
+ MXC_CCM_PDR0_NFC_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (nfc_pdf + 1);
+}
+
+static unsigned long hsp_get_rate(struct clk *clk)
+{
+ unsigned long hsp_pdf;
+
+ hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
+ MXC_CCM_PDR0_HSP_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (hsp_pdf + 1);
+}
+
+static unsigned long usb_get_rate(struct clk *clk)
+{
+ unsigned long usb_pdf, usb_prepdf;
+
+ usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
+ MXC_CCM_PDR1_USB_PODF_OFFSET);
+ usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
+ MXC_CCM_PDR1_USB_PRDF_OFFSET);
+ return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
+}
+
+static unsigned long csi_get_rate(struct clk *clk)
+{
+ u32 reg, pre, post;
+
+ reg = __raw_readl(MXC_CCM_PDR0);
+ pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
+ MXC_CCM_PDR0_CSI_PRDF_OFFSET;
+ pre++;
+ post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
+ MXC_CCM_PDR0_CSI_PODF_OFFSET;
+ post++;
+ return clk_get_rate(clk->parent) / (pre * post);
+}
+
+static unsigned long csi_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post, parent = clk_get_rate(clk->parent);
+ u32 div = parent / rate;
+
+ if (parent % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent / (pre * post);
+}
+
+static int csi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
+
+ div = parent / rate;
+
+ if ((parent / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set CSI clock divider */
+ reg = __raw_readl(MXC_CCM_PDR0) &
+ ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
+ reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
+ __raw_writel(reg, MXC_CCM_PDR0);
+
+ return 0;
+}
+
+static unsigned long ssi1_get_rate(struct clk *clk)
+{
+ unsigned long ssi1_pdf, ssi1_prepdf;
+
+ ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
+ MXC_CCM_PDR1_SSI1_PODF_OFFSET);
+ ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
+ MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
+}
+
+static unsigned long ssi2_get_rate(struct clk *clk)
+{
+ unsigned long ssi2_pdf, ssi2_prepdf;
+
+ ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
+ MXC_CCM_PDR1_SSI2_PODF_OFFSET);
+ ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
+ MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
+}
+
+static unsigned long firi_get_rate(struct clk *clk)
+{
+ unsigned long firi_pdf, firi_prepdf;
+
+ firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
+ MXC_CCM_PDR1_FIRI_PODF_OFFSET);
+ firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
+ MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
+}
+
+static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent = clk_get_rate(clk->parent);
+ u32 div = parent / rate;
+
+ if (parent % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent / (pre * post);
+
+}
+
+static int firi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
+
+ div = parent / rate;
+
+ if ((parent / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set FIRI clock divider */
+ reg = __raw_readl(MXC_CCM_PDR1) &
+ ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
+ reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
+ reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_PDR1);
+
+ return 0;
+}
+
+static unsigned long mbx_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static unsigned long mstick1_get_rate(struct clk *clk)
+{
+ unsigned long msti_pdf;
+
+ msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
+ MXC_CCM_PDR2_MST1_PDF_OFFSET);
+ return clk_get_rate(clk->parent) / (msti_pdf + 1);
+}
+
+static unsigned long mstick2_get_rate(struct clk *clk)
+{
+ unsigned long msti_pdf;
+
+ msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
+ MXC_CCM_PDR2_MST2_PDF_OFFSET);
+ return clk_get_rate(clk->parent) / (msti_pdf + 1);
+}
+
+static unsigned long ckih_rate;
+
+static unsigned long clk_ckih_get_rate(struct clk *clk)
+{
+ return ckih_rate;
+}
+
+static unsigned long clk_ckil_get_rate(struct clk *clk)
+{
+ return CKIL_CLK_FREQ;
+}
+
+static struct clk ckih_clk = {
+ .get_rate = clk_ckih_get_rate,
+};
+
+static struct clk mcu_pll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = mcu_pll_get_rate,
+};
+
+static struct clk mcu_main_clk = {
+ .parent = &mcu_pll_clk,
+ .get_rate = mcu_main_get_rate,
+};
+
+static struct clk serial_pll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = serial_pll_get_rate,
+ .enable = serial_pll_enable,
+ .disable = serial_pll_disable,
+};
+
+static struct clk usb_pll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = usb_pll_get_rate,
+ .enable = usb_pll_enable,
+ .disable = usb_pll_disable,
+};
+
+static struct clk ahb_clk = {
+ .parent = &mcu_main_clk,
+ .get_rate = ahb_get_rate,
+};
+
+#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .enable = cgr_enable, \
+ .disable = cgr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
+
+#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = getsetround##_get_rate, \
+ .set_rate = getsetround##_set_rate, \
+ .round_rate = getsetround##_round_rate, \
+ .enable = cgr_enable, \
+ .disable = cgr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
+
+DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
+
+DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk);
+DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk);
+DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk);
+
+DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
+DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk);
+DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk);
+
+DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk);
+DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk);
+
+DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "emi", emi_clk)
+ _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+ _REGISTER_CLOCK(NULL, "epit", epit1_clk)
+ _REGISTER_CLOCK(NULL, "epit", epit2_clk)
+ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+ _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
+ _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
+ _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
+ _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
+ _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK(NULL, "firi", firi_clk)
+ _REGISTER_CLOCK(NULL, "ata", ata_clk)
+ _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+ _REGISTER_CLOCK(NULL, "rng", rng_clk)
+ _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1)
+ _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
+ _REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
+ _REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
+ _REGISTER_CLOCK(NULL, "scc", scc_clk)
+ _REGISTER_CLOCK(NULL, "iim", iim_clk)
+ _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
+ _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
+};
+
+int __init mx31_clocks_init(unsigned long fref)
+{
+ u32 reg;
+
+ ckih_rate = fref;
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ /* change the csi_clk parent if necessary */
+ reg = __raw_readl(MXC_CCM_CCMR);
+ if (!(reg & MXC_CCM_CCMR_CSCS))
+ if (clk_set_parent(&csi_clk, &usb_pll_clk))
+ pr_err("%s: error changing csi_clk parent\n", __func__);
+
+
+ /* Turn off all possible clocks */
+ __raw_writel((3 << 4), MXC_CCM_CGR0);
+ __raw_writel(0, MXC_CCM_CGR1);
+ __raw_writel((3 << 8) | (3 << 14) | (3 << 16)|
+ 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
+ MX32, but still required to be set */
+ MXC_CCM_CGR2);
+
+ /*
+ * Before turning off usb_pll make sure ipg_per_clk is generated
+ * by ipg_clk and not usb_pll.
+ */
+ __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR);
+
+ usb_pll_disable(&usb_pll_clk);
+
+ pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
+
+ clk_enable(&gpt_clk);
+ clk_enable(&emi_clk);
+ clk_enable(&iim_clk);
+
+ clk_enable(&serial_pll_clk);
+
+ mx31_read_cpu_rev();
+
+ if (mx31_revision() >= MX31_CHIP_REV_2_0) {
+ reg = __raw_readl(MXC_CCM_PMCR1);
+ /* No PLL restart on DVFS switch; enable auto EMI handshake */
+ reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
+ __raw_writel(reg, MXC_CCM_PMCR1);
+ }
+
+ mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
+ MX31_INT_GPT);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index f3f41fa4f21..9f3e943e223 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -28,7 +28,7 @@
#include <mach/hardware.h>
#include <mach/common.h>
-#define CCM_BASE IO_ADDRESS(CCM_BASE_ADDR)
+#define CCM_BASE MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)
#define CCM_CCMR 0x00
#define CCM_PDR0 0x04
@@ -502,7 +502,8 @@ int __init mx35_clocks_init()
__raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2);
__raw_writel(0, CCM_BASE + CCM_CGR3);
- mxc_timer_init(&gpt_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT);
+ mxc_timer_init(&gpt_clk,
+ MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
return 0;
}
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c
deleted file mode 100644
index b5c39a016db..00000000000
--- a/arch/arm/mach-mx3/clock.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2008 by Sascha Hauer <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/spinlock.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <asm/clkdev.h>
-#include <asm/div64.h>
-
-#include <mach/clock.h>
-#include <mach/hardware.h>
-#include <mach/mx31.h>
-#include <mach/common.h>
-
-#include "crm_regs.h"
-
-#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
-
-static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
-{
- u32 min_pre, temp_pre, old_err, err;
-
- if (div >= 512) {
- *pre = 8;
- *post = 64;
- } else if (div >= 64) {
- min_pre = (div - 1) / 64 + 1;
- old_err = 8;
- for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
- err = div % temp_pre;
- if (err == 0) {
- *pre = temp_pre;
- break;
- }
- err = temp_pre - err;
- if (err < old_err) {
- old_err = err;
- *pre = temp_pre;
- }
- }
- *post = (div + *pre - 1) / *pre;
- } else if (div <= 8) {
- *pre = div;
- *post = 1;
- } else {
- *pre = 1;
- *post = div;
- }
-}
-
-static struct clk mcu_pll_clk;
-static struct clk serial_pll_clk;
-static struct clk ipg_clk;
-static struct clk ckih_clk;
-
-static int cgr_enable(struct clk *clk)
-{
- u32 reg;
-
- if (!clk->enable_reg)
- return 0;
-
- reg = __raw_readl(clk->enable_reg);
- reg |= 3 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
-
- return 0;
-}
-
-static void cgr_disable(struct clk *clk)
-{
- u32 reg;
-
- if (!clk->enable_reg)
- return;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(3 << clk->enable_shift);
-
- /* special case for EMI clock */
- if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
- reg |= (1 << clk->enable_shift);
-
- __raw_writel(reg, clk->enable_reg);
-}
-
-static unsigned long pll_ref_get_rate(void)
-{
- unsigned long ccmr;
- unsigned int prcs;
-
- ccmr = __raw_readl(MXC_CCM_CCMR);
- prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
- if (prcs == 0x1)
- return CKIL_CLK_FREQ * 1024;
- else
- return clk_get_rate(&ckih_clk);
-}
-
-static unsigned long usb_pll_get_rate(struct clk *clk)
-{
- unsigned long reg;
-
- reg = __raw_readl(MXC_CCM_UPCTL);
-
- return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static unsigned long serial_pll_get_rate(struct clk *clk)
-{
- unsigned long reg;
-
- reg = __raw_readl(MXC_CCM_SRPCTL);
-
- return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static unsigned long mcu_pll_get_rate(struct clk *clk)
-{
- unsigned long reg, ccmr;
-
- ccmr = __raw_readl(MXC_CCM_CCMR);
-
- if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
- return clk_get_rate(&ckih_clk);
-
- reg = __raw_readl(MXC_CCM_MPCTL);
-
- return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static int usb_pll_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCMR);
- reg |= MXC_CCM_CCMR_UPE;
- __raw_writel(reg, MXC_CCM_CCMR);
-
- /* No lock bit on MX31, so using max time from spec */
- udelay(80);
-
- return 0;
-}
-
-static void usb_pll_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCMR);
- reg &= ~MXC_CCM_CCMR_UPE;
- __raw_writel(reg, MXC_CCM_CCMR);
-}
-
-static int serial_pll_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCMR);
- reg |= MXC_CCM_CCMR_SPE;
- __raw_writel(reg, MXC_CCM_CCMR);
-
- /* No lock bit on MX31, so using max time from spec */
- udelay(80);
-
- return 0;
-}
-
-static void serial_pll_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCMR);
- reg &= ~MXC_CCM_CCMR_SPE;
- __raw_writel(reg, MXC_CCM_CCMR);
-}
-
-#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
-#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
-#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
-
-static unsigned long mcu_main_get_rate(struct clk *clk)
-{
- u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
-
- if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
- return clk_get_rate(&serial_pll_clk);
- else
- return clk_get_rate(&mcu_pll_clk);
-}
-
-static unsigned long ahb_get_rate(struct clk *clk)
-{
- unsigned long max_pdf;
-
- max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
- MXC_CCM_PDR0_MAX_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (max_pdf + 1);
-}
-
-static unsigned long ipg_get_rate(struct clk *clk)
-{
- unsigned long ipg_pdf;
-
- ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
- MXC_CCM_PDR0_IPG_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ipg_pdf + 1);
-}
-
-static unsigned long nfc_get_rate(struct clk *clk)
-{
- unsigned long nfc_pdf;
-
- nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
- MXC_CCM_PDR0_NFC_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (nfc_pdf + 1);
-}
-
-static unsigned long hsp_get_rate(struct clk *clk)
-{
- unsigned long hsp_pdf;
-
- hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
- MXC_CCM_PDR0_HSP_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (hsp_pdf + 1);
-}
-
-static unsigned long usb_get_rate(struct clk *clk)
-{
- unsigned long usb_pdf, usb_prepdf;
-
- usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
- MXC_CCM_PDR1_USB_PODF_OFFSET);
- usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
- MXC_CCM_PDR1_USB_PRDF_OFFSET);
- return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
-}
-
-static unsigned long csi_get_rate(struct clk *clk)
-{
- u32 reg, pre, post;
-
- reg = __raw_readl(MXC_CCM_PDR0);
- pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
- MXC_CCM_PDR0_CSI_PRDF_OFFSET;
- pre++;
- post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
- MXC_CCM_PDR0_CSI_PODF_OFFSET;
- post++;
- return clk_get_rate(clk->parent) / (pre * post);
-}
-
-static unsigned long csi_round_rate(struct clk *clk, unsigned long rate)
-{
- u32 pre, post, parent = clk_get_rate(clk->parent);
- u32 div = parent / rate;
-
- if (parent % rate)
- div++;
-
- __calc_pre_post_dividers(div, &pre, &post);
-
- return parent / (pre * post);
-}
-
-static int csi_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
-
- div = parent / rate;
-
- if ((parent / div) != rate)
- return -EINVAL;
-
- __calc_pre_post_dividers(div, &pre, &post);
-
- /* Set CSI clock divider */
- reg = __raw_readl(MXC_CCM_PDR0) &
- ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
- reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
- reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
- __raw_writel(reg, MXC_CCM_PDR0);
-
- return 0;
-}
-
-static unsigned long ssi1_get_rate(struct clk *clk)
-{
- unsigned long ssi1_pdf, ssi1_prepdf;
-
- ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
- MXC_CCM_PDR1_SSI1_PODF_OFFSET);
- ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
- MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
-}
-
-static unsigned long ssi2_get_rate(struct clk *clk)
-{
- unsigned long ssi2_pdf, ssi2_prepdf;
-
- ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
- MXC_CCM_PDR1_SSI2_PODF_OFFSET);
- ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
- MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
-}
-
-static unsigned long firi_get_rate(struct clk *clk)
-{
- unsigned long firi_pdf, firi_prepdf;
-
- firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
- MXC_CCM_PDR1_FIRI_PODF_OFFSET);
- firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
- MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
-}
-
-static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
-{
- u32 pre, post;
- u32 parent = clk_get_rate(clk->parent);
- u32 div = parent / rate;
-
- if (parent % rate)
- div++;
-
- __calc_pre_post_dividers(div, &pre, &post);
-
- return parent / (pre * post);
-
-}
-
-static int firi_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
-
- div = parent / rate;
-
- if ((parent / div) != rate)
- return -EINVAL;
-
- __calc_pre_post_dividers(div, &pre, &post);
-
- /* Set FIRI clock divider */
- reg = __raw_readl(MXC_CCM_PDR1) &
- ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
- reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
- reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
- __raw_writel(reg, MXC_CCM_PDR1);
-
- return 0;
-}
-
-static unsigned long mbx_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 2;
-}
-
-static unsigned long mstick1_get_rate(struct clk *clk)
-{
- unsigned long msti_pdf;
-
- msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
- MXC_CCM_PDR2_MST1_PDF_OFFSET);
- return clk_get_rate(clk->parent) / (msti_pdf + 1);
-}
-
-static unsigned long mstick2_get_rate(struct clk *clk)
-{
- unsigned long msti_pdf;
-
- msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
- MXC_CCM_PDR2_MST2_PDF_OFFSET);
- return clk_get_rate(clk->parent) / (msti_pdf + 1);
-}
-
-static unsigned long ckih_rate;
-
-static unsigned long clk_ckih_get_rate(struct clk *clk)
-{
- return ckih_rate;
-}
-
-static unsigned long clk_ckil_get_rate(struct clk *clk)
-{
- return CKIL_CLK_FREQ;
-}
-
-static struct clk ckih_clk = {
- .get_rate = clk_ckih_get_rate,
-};
-
-static struct clk mcu_pll_clk = {
- .parent = &ckih_clk,
- .get_rate = mcu_pll_get_rate,
-};
-
-static struct clk mcu_main_clk = {
- .parent = &mcu_pll_clk,
- .get_rate = mcu_main_get_rate,
-};
-
-static struct clk serial_pll_clk = {
- .parent = &ckih_clk,
- .get_rate = serial_pll_get_rate,
- .enable = serial_pll_enable,
- .disable = serial_pll_disable,
-};
-
-static struct clk usb_pll_clk = {
- .parent = &ckih_clk,
- .get_rate = usb_pll_get_rate,
- .enable = usb_pll_enable,
- .disable = usb_pll_disable,
-};
-
-static struct clk ahb_clk = {
- .parent = &mcu_main_clk,
- .get_rate = ahb_get_rate,
-};
-
-#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = gr, \
- .enable = cgr_enable, \
- .disable = cgr_disable, \
- .secondary = s, \
- .parent = p, \
- }
-
-#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = getsetround##_get_rate, \
- .set_rate = getsetround##_set_rate, \
- .round_rate = getsetround##_round_rate, \
- .enable = cgr_enable, \
- .disable = cgr_disable, \
- .secondary = s, \
- .parent = p, \
- }
-
-DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
-
-DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk);
-DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk);
-DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk);
-
-DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
-DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
-DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
-DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk);
-DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk);
-
-DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk);
-DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk);
-
-DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk);
-DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-
-static struct clk_lookup lookups[] = {
- _REGISTER_CLOCK(NULL, "emi", emi_clk)
- _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
- _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
- _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
- _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
- _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
- _REGISTER_CLOCK(NULL, "epit", epit1_clk)
- _REGISTER_CLOCK(NULL, "epit", epit2_clk)
- _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
- _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
- _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
- _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
- _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
- _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
- _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
- _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
- _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
- _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
- _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
- _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
- _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
- _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
- _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
- _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
- _REGISTER_CLOCK(NULL, "firi", firi_clk)
- _REGISTER_CLOCK(NULL, "ata", ata_clk)
- _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
- _REGISTER_CLOCK(NULL, "rng", rng_clk)
- _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1)
- _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
- _REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
- _REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
- _REGISTER_CLOCK(NULL, "scc", scc_clk)
- _REGISTER_CLOCK(NULL, "iim", iim_clk)
- _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
- _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
- _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
-};
-
-int __init mx31_clocks_init(unsigned long fref)
-{
- u32 reg;
-
- ckih_rate = fref;
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- /* change the csi_clk parent if necessary */
- reg = __raw_readl(MXC_CCM_CCMR);
- if (!(reg & MXC_CCM_CCMR_CSCS))
- if (clk_set_parent(&csi_clk, &usb_pll_clk))
- pr_err("%s: error changing csi_clk parent\n", __func__);
-
-
- /* Turn off all possible clocks */
- __raw_writel((3 << 4), MXC_CCM_CGR0);
- __raw_writel(0, MXC_CCM_CGR1);
- __raw_writel((3 << 8) | (3 << 14) | (3 << 16)|
- 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
- MX32, but still required to be set */
- MXC_CCM_CGR2);
-
- /*
- * Before turning off usb_pll make sure ipg_per_clk is generated
- * by ipg_clk and not usb_pll.
- */
- __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR);
-
- usb_pll_disable(&usb_pll_clk);
-
- pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
-
- clk_enable(&gpt_clk);
- clk_enable(&emi_clk);
- clk_enable(&iim_clk);
-
- clk_enable(&serial_pll_clk);
-
- mx31_read_cpu_rev();
-
- if (mx31_revision() >= CHIP_REV_2_0) {
- reg = __raw_readl(MXC_CCM_PMCR1);
- /* No PLL restart on DVFS switch; enable auto EMI handshake */
- reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
- __raw_writel(reg, MXC_CCM_PMCR1);
- }
-
- mxc_timer_init(&ipg_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT);
-
- return 0;
-}
-
diff --git a/arch/arm/mach-mx3/cpu.c b/arch/arm/mach-mx3/cpu.c
index db828809c67..861afe0fe3a 100644
--- a/arch/arm/mach-mx3/cpu.c
+++ b/arch/arm/mach-mx3/cpu.c
@@ -41,7 +41,7 @@ void __init mx31_read_cpu_rev(void)
u32 i, srev;
/* read SREV register from IIM module */
- srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR) + MXC_IIMSREV);
+ srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR + MXC_IIMSREV));
for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
if (srev == mx31_cpu_type[i].srev) {
diff --git a/arch/arm/mach-mx3/crm_regs.h b/arch/arm/mach-mx3/crm_regs.h
index adfa3627ad8..37a8a07beda 100644
--- a/arch/arm/mach-mx3/crm_regs.h
+++ b/arch/arm/mach-mx3/crm_regs.h
@@ -24,7 +24,7 @@
#define CKIH_CLK_FREQ_27MHZ 27000000
#define CKIL_CLK_FREQ 32768
-#define MXC_CCM_BASE IO_ADDRESS(CCM_BASE_ADDR)
+#define MXC_CCM_BASE MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR)
/* Register addresses */
#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00)
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index 6adb586515e..f8911154a9f 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = {
.resource = imx_ssi_resources1,
};
-static int mx3_devices_init(void)
+static struct resource imx_wdt_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device imx_wdt_device0 = {
+ .name = "imx-wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(imx_wdt_resources),
+ .resource = imx_wdt_resources,
+};
+
+static int __init mx3_devices_init(void)
{
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);
}
if (cpu_is_mx35()) {
@@ -597,6 +612,8 @@ static int mx3_devices_init(void)
imx_ssi_resources0[1].end = MX35_INT_SSI1;
imx_ssi_resources1[1].start = MX35_INT_SSI2;
imx_ssi_resources1[1].end = MX35_INT_SSI2;
+ imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
+ imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
}
return 0;
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index 42cf175eac6..4f77eb50127 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -25,4 +25,5 @@ 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;
+extern struct platform_device imx_wdt_device0;
diff --git a/arch/arm/mach-mx3/iomux-imx31.c b/arch/arm/mach-mx3/iomux-imx31.c
new file mode 100644
index 00000000000..a1d7fa5123d
--- /dev/null
+++ b/arch/arm/mach-mx3/iomux-imx31.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
+ *
+ * This program is free software; 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/spinlock.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/iomux-mx3.h>
+
+/*
+ * IOMUX register (base) addresses
+ */
+#define IOMUX_BASE MX31_IO_ADDRESS(MX31_IOMUXC_BASE_ADDR)
+#define IOMUXINT_OBS1 (IOMUX_BASE + 0x000)
+#define IOMUXINT_OBS2 (IOMUX_BASE + 0x004)
+#define IOMUXGPR (IOMUX_BASE + 0x008)
+#define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C)
+#define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154)
+
+static DEFINE_SPINLOCK(gpio_mux_lock);
+
+#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
+
+unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
+/*
+ * set the mode for a IOMUX pin.
+ */
+int mxc_iomux_mode(unsigned int pin_mode)
+{
+ u32 field, l, mode, ret = 0;
+ void __iomem *reg;
+
+ reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK);
+ field = pin_mode & 0x3;
+ mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
+
+ spin_lock(&gpio_mux_lock);
+
+ l = __raw_readl(reg);
+ l &= ~(0xff << (field * 8));
+ l |= mode << (field * 8);
+ __raw_writel(l, reg);
+
+ spin_unlock(&gpio_mux_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_mode);
+
+/*
+ * This function configures the pad value for a IOMUX pin.
+ */
+void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
+{
+ u32 field, l;
+ void __iomem *reg;
+
+ pin &= IOMUX_PADNUM_MASK;
+ reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
+ field = (pin + 2) % 3;
+
+ pr_debug("%s: reg offset = 0x%x, field = %d\n",
+ __func__, (pin + 2) / 3, field);
+
+ spin_lock(&gpio_mux_lock);
+
+ l = __raw_readl(reg);
+ l &= ~(0x1ff << (field * 10));
+ l |= config << (field * 10);
+ __raw_writel(l, reg);
+
+ spin_unlock(&gpio_mux_lock);
+}
+EXPORT_SYMBOL(mxc_iomux_set_pad);
+
+/*
+ * allocs a single pin:
+ * - reserves the pin so that it is not claimed by another driver
+ * - setups the iomux according to the configuration
+ */
+int mxc_iomux_alloc_pin(const unsigned int pin, const char *label)
+{
+ unsigned pad = pin & IOMUX_PADNUM_MASK;
+
+ if (pad >= (PIN_MAX + 1)) {
+ printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
+ pad, label ? label : "?");
+ return -EINVAL;
+ }
+
+ if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
+ printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
+ pad, label ? label : "?");
+ return -EBUSY;
+ }
+ mxc_iomux_mode(pin);
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_alloc_pin);
+
+int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+ const char *label)
+{
+ unsigned int *p = pin_list;
+ int i;
+ int ret = -EINVAL;
+
+ for (i = 0; i < count; i++) {
+ ret = mxc_iomux_alloc_pin(*p, label);
+ if (ret)
+ goto setup_error;
+ p++;
+ }
+ return 0;
+
+setup_error:
+ mxc_iomux_release_multiple_pins(pin_list, i);
+ return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
+
+void mxc_iomux_release_pin(const unsigned int pin)
+{
+ unsigned pad = pin & IOMUX_PADNUM_MASK;
+
+ if (pad < (PIN_MAX + 1))
+ clear_bit(pad, mxc_pin_alloc_map);
+}
+EXPORT_SYMBOL(mxc_iomux_release_pin);
+
+void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
+{
+ unsigned int *p = pin_list;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ mxc_iomux_release_pin(*p);
+ p++;
+ }
+}
+EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
+
+/*
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ */
+void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
+{
+ u32 l;
+
+ spin_lock(&gpio_mux_lock);
+ l = __raw_readl(IOMUXGPR);
+ if (en)
+ l |= gp;
+ else
+ l &= ~gp;
+
+ __raw_writel(l, IOMUXGPR);
+ spin_unlock(&gpio_mux_lock);
+}
+EXPORT_SYMBOL(mxc_iomux_set_gpr);
diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c
deleted file mode 100644
index c66ccbcdc11..00000000000
--- a/arch/arm/mach-mx3/iomux.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
- * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
- *
- * This program is free software; 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/spinlock.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <mach/iomux-mx3.h>
-
-/*
- * IOMUX register (base) addresses
- */
-#define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR)
-#define IOMUXINT_OBS1 (IOMUX_BASE + 0x000)
-#define IOMUXINT_OBS2 (IOMUX_BASE + 0x004)
-#define IOMUXGPR (IOMUX_BASE + 0x008)
-#define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C)
-#define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154)
-
-static DEFINE_SPINLOCK(gpio_mux_lock);
-
-#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
-
-unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
-/*
- * set the mode for a IOMUX pin.
- */
-int mxc_iomux_mode(unsigned int pin_mode)
-{
- u32 field, l, mode, ret = 0;
- void __iomem *reg;
-
- reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK);
- field = pin_mode & 0x3;
- mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
-
- spin_lock(&gpio_mux_lock);
-
- l = __raw_readl(reg);
- l &= ~(0xff << (field * 8));
- l |= mode << (field * 8);
- __raw_writel(l, reg);
-
- spin_unlock(&gpio_mux_lock);
-
- return ret;
-}
-EXPORT_SYMBOL(mxc_iomux_mode);
-
-/*
- * This function configures the pad value for a IOMUX pin.
- */
-void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
-{
- u32 field, l;
- void __iomem *reg;
-
- pin &= IOMUX_PADNUM_MASK;
- reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
- field = (pin + 2) % 3;
-
- pr_debug("%s: reg offset = 0x%x, field = %d\n",
- __func__, (pin + 2) / 3, field);
-
- spin_lock(&gpio_mux_lock);
-
- l = __raw_readl(reg);
- l &= ~(0x1ff << (field * 10));
- l |= config << (field * 10);
- __raw_writel(l, reg);
-
- spin_unlock(&gpio_mux_lock);
-}
-EXPORT_SYMBOL(mxc_iomux_set_pad);
-
-/*
- * allocs a single pin:
- * - reserves the pin so that it is not claimed by another driver
- * - setups the iomux according to the configuration
- */
-int mxc_iomux_alloc_pin(const unsigned int pin, const char *label)
-{
- unsigned pad = pin & IOMUX_PADNUM_MASK;
-
- if (pad >= (PIN_MAX + 1)) {
- printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
- pad, label ? label : "?");
- return -EINVAL;
- }
-
- if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
- printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
- pad, label ? label : "?");
- return -EBUSY;
- }
- mxc_iomux_mode(pin);
-
- return 0;
-}
-EXPORT_SYMBOL(mxc_iomux_alloc_pin);
-
-int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
- const char *label)
-{
- unsigned int *p = pin_list;
- int i;
- int ret = -EINVAL;
-
- for (i = 0; i < count; i++) {
- ret = mxc_iomux_alloc_pin(*p, label);
- if (ret)
- goto setup_error;
- p++;
- }
- return 0;
-
-setup_error:
- mxc_iomux_release_multiple_pins(pin_list, i);
- return ret;
-}
-EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
-
-void mxc_iomux_release_pin(const unsigned int pin)
-{
- unsigned pad = pin & IOMUX_PADNUM_MASK;
-
- if (pad < (PIN_MAX + 1))
- clear_bit(pad, mxc_pin_alloc_map);
-}
-EXPORT_SYMBOL(mxc_iomux_release_pin);
-
-void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
-{
- unsigned int *p = pin_list;
- int i;
-
- for (i = 0; i < count; i++) {
- mxc_iomux_release_pin(*p);
- p++;
- }
-}
-EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
-
-/*
- * This function enables/disables the general purpose function for a particular
- * signal.
- */
-void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
-{
- u32 l;
-
- spin_lock(&gpio_mux_lock);
- l = __raw_readl(IOMUXGPR);
- if (en)
- l |= gp;
- else
- l &= ~gp;
-
- __raw_writel(l, IOMUXGPR);
- spin_unlock(&gpio_mux_lock);
-}
-EXPORT_SYMBOL(mxc_iomux_set_gpr);
diff --git a/arch/arm/mach-mx3/kzmarm11.c b/arch/arm/mach-mx3/kzmarm11.c
deleted file mode 100644
index 6fa99ce3008..00000000000
--- a/arch/arm/mach-mx3/kzmarm11.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * KZM-ARM11-01 support
- * Copyright (C) 2009 Yoichi Yuasa <yuasa@linux-mips.org>
- *
- * based on code for MX31ADS,
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright (C) 2002 Shane Nay (shane@minirl.com)
- * 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 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/gpio.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
-#include <linux/smsc911x.h>
-#include <linux/types.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-#include <asm/setup.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#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.h"
-
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
-/*
- * KZM-ARM11-01 has an external UART on FPGA
- */
-static struct plat_serial8250_port serial_platform_data[] = {
- {
- .membase = IO_ADDRESS(KZM_ARM11_16550),
- .mapbase = KZM_ARM11_16550,
- .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
- .irqflags = IRQ_TYPE_EDGE_RISING,
- .uartclk = 14745600,
- .regshift = 0,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
- UPF_BUGGY_UART,
- },
- {},
-};
-
-static struct resource serial8250_resources[] = {
- {
- .start = KZM_ARM11_16550,
- .end = KZM_ARM11_16550 + 0x10,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
- .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device serial_device = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = serial_platform_data,
- },
- .num_resources = ARRAY_SIZE(serial8250_resources),
- .resource = serial8250_resources,
-};
-
-static int __init kzm_init_ext_uart(void)
-{
- u8 tmp;
-
- /*
- * GPIO 1-1: external UART interrupt line
- */
- mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO));
- gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int");
- gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
-
- /*
- * Unmask UART interrupt
- */
- tmp = __raw_readb(IO_ADDRESS(KZM_ARM11_CTL1));
- tmp |= 0x2;
- __raw_writeb(tmp, IO_ADDRESS(KZM_ARM11_CTL1));
-
- return platform_device_register(&serial_device);
-}
-#else
-static inline int kzm_init_ext_uart(void)
-{
- return 0;
-}
-#endif
-
-/*
- * SMSC LAN9118
- */
-#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
-static struct smsc911x_platform_config kzm_smsc9118_config = {
- .phy_interface = PHY_INTERFACE_MODE_MII,
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
- .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
- .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
-};
-
-static struct resource kzm_smsc9118_resources[] = {
- {
- .start = CS5_BASE_ADDR,
- .end = CS5_BASE_ADDR + SZ_128K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
- .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
- },
-};
-
-static struct platform_device kzm_smsc9118_device = {
- .name = "smsc911x",
- .id = -1,
- .num_resources = ARRAY_SIZE(kzm_smsc9118_resources),
- .resource = kzm_smsc9118_resources,
- .dev = {
- .platform_data = &kzm_smsc9118_config,
- },
-};
-
-static int __init kzm_init_smsc9118(void)
-{
- /*
- * GPIO 1-2: SMSC9118 interrupt line
- */
- mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO));
- gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int");
- gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2));
-
- return platform_device_register(&kzm_smsc9118_device);
-}
-#else
-static inline int kzm_init_smsc9118(void)
-{
- return 0;
-}
-#endif
-
-#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
- .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);
-}
-#else
-static inline void kzm_init_imx_uart(void)
-{
-}
-#endif
-
-static int kzm_pins[] __initdata = {
- MX31_PIN_CTS1__CTS1,
- MX31_PIN_RTS1__RTS1,
- MX31_PIN_TXD1__TXD1,
- MX31_PIN_RXD1__RXD1,
- MX31_PIN_DCD_DCE1__DCD_DCE1,
- MX31_PIN_RI_DCE1__RI_DCE1,
- MX31_PIN_DSR_DCE1__DSR_DCE1,
- MX31_PIN_DTR_DCE1__DTR_DCE1,
- MX31_PIN_CTS2__CTS2,
- MX31_PIN_RTS2__RTS2,
- MX31_PIN_TXD2__TXD2,
- MX31_PIN_RXD2__RXD2,
- MX31_PIN_DCD_DTE1__DCD_DTE2,
- MX31_PIN_RI_DTE1__RI_DTE2,
- MX31_PIN_DSR_DTE1__DSR_DTE2,
- MX31_PIN_DTR_DTE1__DTR_DTE2,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init kzm_board_init(void)
-{
- mxc_iomux_setup_multiple_pins(kzm_pins,
- ARRAY_SIZE(kzm_pins), "kzm");
- kzm_init_ext_uart();
- kzm_init_smsc9118();
- kzm_init_imx_uart();
-
- pr_info("Clock input source is 26MHz\n");
-}
-
-/*
- * This structure defines static mappings for the kzm-arm11-01 board.
- */
-static struct map_desc kzm_io_desc[] __initdata = {
- {
- .virtual = CS4_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(CS4_BASE_ADDR),
- .length = CS4_SIZE,
- .type = MT_DEVICE
- },
- {
- .virtual = CS5_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(CS5_BASE_ADDR),
- .length = CS5_SIZE,
- .type = MT_DEVICE
- },
-};
-
-/*
- * Set up static virtual mappings.
- */
-static void __init kzm_map_io(void)
-{
- mx31_map_io();
- iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc));
-}
-
-static void __init kzm_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-static struct sys_timer kzm_timer = {
- .init = kzm_timer_init,
-};
-
-/*
- * The following uses standard kernel macros define in arch.h in order to
- * initialize __mach_desc_KZM_ARM11_01 data structure.
- */
-MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = kzm_map_io,
- .init_irq = mx31_init_irq,
- .init_machine = kzm_board_init,
- .timer = &kzm_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c
new file mode 100644
index 00000000000..5f72ec91af2
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-armadillo5x0.c
@@ -0,0 +1,582 @@
+/*
+ * armadillo5x0.c
+ *
+ * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * updates in http://alberdroid.blogspot.com/
+ *
+ * Based on Atmark Techno, Inc. armadillo 500 BSP 2008
+ * Based on mx31ads.c and pcm037.c Great Work!
+ *
+ * This program is free software; 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/clk.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.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/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.h"
+#include "crm_regs.h"
+
+static int armadillo5x0_pins[] = {
+ /* UART1 */
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ /* UART2 */
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ /* LAN9118_IRQ */
+ IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO),
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+ /* Framebuffer */
+ MX31_PIN_LD0__LD0,
+ MX31_PIN_LD1__LD1,
+ MX31_PIN_LD2__LD2,
+ MX31_PIN_LD3__LD3,
+ MX31_PIN_LD4__LD4,
+ MX31_PIN_LD5__LD5,
+ MX31_PIN_LD6__LD6,
+ MX31_PIN_LD7__LD7,
+ MX31_PIN_LD8__LD8,
+ MX31_PIN_LD9__LD9,
+ MX31_PIN_LD10__LD10,
+ MX31_PIN_LD11__LD11,
+ MX31_PIN_LD12__LD12,
+ MX31_PIN_LD13__LD13,
+ MX31_PIN_LD14__LD14,
+ MX31_PIN_LD15__LD15,
+ MX31_PIN_LD16__LD16,
+ MX31_PIN_LD17__LD17,
+ MX31_PIN_VSYNC3__VSYNC3,
+ MX31_PIN_HSYNC__HSYNC,
+ MX31_PIN_FPSHIFT__FPSHIFT,
+ MX31_PIN_DRDY0__DRDY0,
+ IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/
+ /* I2C2 */
+ MX31_PIN_CSPI2_MOSI__SCL,
+ MX31_PIN_CSPI2_MISO__SDA,
+ /* OTG */
+ MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+ MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+ MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+ MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+ MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+ MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+ MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+ MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+ MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+ MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+ MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+ MX31_PIN_USBOTG_STP__USBOTG_STP,
+ /* USB host 2 */
+ IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
+};
+
+/* USB */
+#if defined(CONFIG_USB_ULPI)
+
+#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4)
+#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbotg_init(struct platform_device *pdev)
+{
+ 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);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+ /* Chip already enabled by hardware */
+ /* OTG phy reset*/
+ err = gpio_request(OTG_RESET, "USB-OTG-RESET");
+ if (err) {
+ pr_err("Failed to request the usb otg reset gpio\n");
+ return err;
+ }
+
+ err = gpio_direction_output(OTG_RESET, 1/*HIGH*/);
+ if (err) {
+ pr_err("Failed to reset the usb otg phy\n");
+ goto otg_free_reset;
+ }
+
+ gpio_set_value(OTG_RESET, 0/*LOW*/);
+ mdelay(5);
+ gpio_set_value(OTG_RESET, 1/*HIGH*/);
+
+ return 0;
+
+otg_free_reset:
+ gpio_free(OTG_RESET);
+ return err;
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+ int err;
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+
+ /* Enable the chip */
+ err = gpio_request(USBH2_CS, "USB-H2-CS");
+ if (err) {
+ pr_err("Failed to request the usb host 2 CS gpio\n");
+ return err;
+ }
+
+ err = gpio_direction_output(USBH2_CS, 0/*Enabled*/);
+ if (err) {
+ pr_err("Failed to drive the usb host 2 CS gpio\n");
+ goto h2_free_cs;
+ }
+
+ /* H2 phy reset*/
+ err = gpio_request(USBH2_RESET, "USB-H2-RESET");
+ if (err) {
+ pr_err("Failed to request the usb host 2 reset gpio\n");
+ goto h2_free_cs;
+ }
+
+ err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/);
+ if (err) {
+ pr_err("Failed to reset the usb host 2 phy\n");
+ goto h2_free_reset;
+ }
+
+ gpio_set_value(USBH2_RESET, 0/*LOW*/);
+ mdelay(5);
+ gpio_set_value(USBH2_RESET, 1/*HIGH*/);
+
+ return 0;
+
+h2_free_reset:
+ gpio_free(USBH2_RESET);
+h2_free_cs:
+ gpio_free(USBH2_CS);
+ return err;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata = {
+ .init = usbotg_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+ .init = usbh2_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+#endif /* CONFIG_USB_ULPI */
+
+/* RTC over I2C*/
+#define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4)
+
+static struct i2c_board_info armadillo5x0_i2c_rtc = {
+ I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+/* GPIO BUTTONS */
+static struct gpio_keys_button armadillo5x0_buttons[] = {
+ {
+ .code = KEY_ENTER, /*28*/
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SCLK0),
+ .active_low = 1,
+ .desc = "menu",
+ .wakeup = 1,
+ }, {
+ .code = KEY_BACK, /*158*/
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SRST0),
+ .active_low = 1,
+ .desc = "back",
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data armadillo5x0_button_data = {
+ .buttons = armadillo5x0_buttons,
+ .nbuttons = ARRAY_SIZE(armadillo5x0_buttons),
+};
+
+static struct platform_device armadillo5x0_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &armadillo5x0_button_data,
+ }
+};
+
+/*
+ * NAND Flash
+ */
+static struct mxc_nand_platform_data armadillo5x0_nand_flash_pdata = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+/*
+ * MTD NOR Flash
+ */
+static struct mtd_partition armadillo5x0_nor_flash_partitions[] = {
+ {
+ .name = "nor.bootloader",
+ .offset = 0x00000000,
+ .size = 4*32*1024,
+ }, {
+ .name = "nor.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 16*128*1024,
+ }, {
+ .name = "nor.userland",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 110*128*1024,
+ }, {
+ .name = "nor.config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1*128*1024,
+ },
+};
+
+static struct physmap_flash_data armadillo5x0_nor_flash_pdata = {
+ .width = 2,
+ .parts = armadillo5x0_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(armadillo5x0_nor_flash_partitions),
+};
+
+static struct resource armadillo5x0_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = MX31_CS0_BASE_ADDR,
+ .end = MX31_CS0_BASE_ADDR + SZ_64M - 1,
+};
+
+static struct platform_device armadillo5x0_nor_flash = {
+ .name = "physmap-flash",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &armadillo5x0_nor_flash_resource,
+};
+
+/*
+ * FB support
+ */
+static const struct fb_videomode fb_modedb[] = {
+ { /* 640x480 @ 60 Hz */
+ .name = "CRT-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 35,
+ .right_margin = 115,
+ .upper_margin = 43,
+ .lower_margin = 1,
+ .hsync_len = 10,
+ .vsync_len = 1,
+ .sync = FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {/* 800x600 @ 56 Hz */
+ .name = "CRT-SVGA",
+ .refresh = 56,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000,
+ .left_margin = 30,
+ .right_margin = 108,
+ .upper_margin = 13,
+ .lower_margin = 10,
+ .hsync_len = 10,
+ .vsync_len = 1,
+ .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT,
+ .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 = "CRT-VGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+/*
+ * SDHC 1
+ * MMC support
+ */
+static int armadillo5x0_sdhc1_get_ro(struct device *dev)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
+}
+
+static int armadillo5x0_sdhc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+ int gpio_det, gpio_wp;
+
+ gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK);
+ gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B);
+
+ ret = gpio_request(gpio_det, "sdhc-card-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(gpio_det);
+
+ ret = gpio_request(gpio_wp, "sdhc-write-protect");
+ if (ret)
+ goto err_gpio_free;
+
+ gpio_direction_input(gpio_wp);
+
+ /* When supported the trigger type have to be BOTH */
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "sdhc-detect", data);
+
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+ gpio_free(gpio_wp);
+
+err_gpio_free:
+ gpio_free(gpio_det);
+
+ return ret;
+
+}
+
+static void armadillo5x0_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data);
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK));
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+ .get_ro = armadillo5x0_sdhc1_get_ro,
+ .init = armadillo5x0_sdhc1_init,
+ .exit = armadillo5x0_sdhc1_exit,
+};
+
+/*
+ * SMSC 9118
+ * Network support
+ */
+static struct resource armadillo5x0_smc911x_resources[] = {
+ {
+ .start = MX31_CS3_BASE_ADDR,
+ .end = MX31_CS3_BASE_ADDR + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_16BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device armadillo5x0_smc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(armadillo5x0_smc911x_resources),
+ .resource = armadillo5x0_smc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_info,
+ },
+};
+
+/* UART device data */
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &armadillo5x0_smc911x_device,
+ &mxc_i2c_device1,
+ &armadillo5x0_button_device,
+};
+
+/*
+ * Perform board specific initializations
+ */
+static void __init armadillo5x0_init(void)
+{
+ mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
+ ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ /* Register UART */
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ mxc_register_device(&mxc_uart_device1, &uart_pdata);
+
+ /* SMSC9118 IRQ pin */
+ gpio_direction_input(MX31_PIN_GPIO1_0);
+
+ /* Register SDHC */
+ mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
+
+ /* Register FB */
+ mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+ mxc_register_device(&mx3_fb, &mx3fb_pdata);
+
+ /* Register NOR Flash */
+ mxc_register_device(&armadillo5x0_nor_flash,
+ &armadillo5x0_nor_flash_pdata);
+
+ /* Register NAND Flash */
+ mxc_register_device(&mxc_nand_device, &armadillo5x0_nand_flash_pdata);
+
+ /* 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);
+
+ /* RTC */
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(ARMADILLO5X0_RTC_GPIO) == 0)
+ armadillo5x0_i2c_rtc.irq = gpio_to_irq(ARMADILLO5X0_RTC_GPIO);
+ else
+ gpio_free(ARMADILLO5X0_RTC_GPIO);
+ }
+ if (armadillo5x0_i2c_rtc.irq == 0)
+ pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
+ i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
+
+ /* USB */
+#if defined(CONFIG_USB_ULPI)
+ usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+ usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+ mxc_register_device(&mxc_otg_host, &usbotg_pdata);
+ mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
+}
+
+static void __init armadillo5x0_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer armadillo5x0_timer = {
+ .init = armadillo5x0_timer_init,
+};
+
+MACHINE_START(ARMADILLO5X0, "Armadillo-500")
+ /* Maintainer: Alberto Panizzo */
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_irq = mx31_init_irq,
+ .timer = &armadillo5x0_timer,
+ .init_machine = armadillo5x0_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mach-kzm_arm11_01.c b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
new file mode 100644
index 00000000000..f085d5d1a6d
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
@@ -0,0 +1,273 @@
+/*
+ * KZM-ARM11-01 support
+ * Copyright (C) 2009 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * based on code for MX31ADS,
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * 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 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/gpio.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/smsc911x.h>
+#include <linux/types.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#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.h"
+
+#define KZM_ARM11_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX31_CS4) ?: \
+ IMX_IO_ADDRESS(x, MX31_CS5) ?: \
+ MX31_IO_ADDRESS(x))
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+/*
+ * KZM-ARM11-01 has an external UART on FPGA
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = KZM_ARM11_IO_ADDRESS(KZM_ARM11_16550),
+ .mapbase = KZM_ARM11_16550,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+ .irqflags = IRQ_TYPE_EDGE_RISING,
+ .uartclk = 14745600,
+ .regshift = 0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_BUGGY_UART,
+ },
+ {},
+};
+
+static struct resource serial8250_resources[] = {
+ {
+ .start = KZM_ARM11_16550,
+ .end = KZM_ARM11_16550 + 0x10,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(serial8250_resources),
+ .resource = serial8250_resources,
+};
+
+static int __init kzm_init_ext_uart(void)
+{
+ u8 tmp;
+
+ /*
+ * GPIO 1-1: external UART interrupt line
+ */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO));
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int");
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
+
+ /*
+ * Unmask UART interrupt
+ */
+ tmp = __raw_readb(KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1));
+ tmp |= 0x2;
+ __raw_writeb(tmp, KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1));
+
+ return platform_device_register(&serial_device);
+}
+#else
+static inline int kzm_init_ext_uart(void)
+{
+ return 0;
+}
+#endif
+
+/*
+ * SMSC LAN9118
+ */
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct smsc911x_platform_config kzm_smsc9118_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct resource kzm_smsc9118_resources[] = {
+ {
+ .start = MX31_CS5_BASE_ADDR,
+ .end = MX31_CS5_BASE_ADDR + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct platform_device kzm_smsc9118_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(kzm_smsc9118_resources),
+ .resource = kzm_smsc9118_resources,
+ .dev = {
+ .platform_data = &kzm_smsc9118_config,
+ },
+};
+
+static int __init kzm_init_smsc9118(void)
+{
+ /*
+ * GPIO 1-2: SMSC9118 interrupt line
+ */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO));
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int");
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2));
+
+ return platform_device_register(&kzm_smsc9118_device);
+}
+#else
+static inline int kzm_init_smsc9118(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+ .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);
+}
+#else
+static inline void kzm_init_imx_uart(void)
+{
+}
+#endif
+
+static int kzm_pins[] __initdata = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ MX31_PIN_DCD_DCE1__DCD_DCE1,
+ MX31_PIN_RI_DCE1__RI_DCE1,
+ MX31_PIN_DSR_DCE1__DSR_DCE1,
+ MX31_PIN_DTR_DCE1__DTR_DCE1,
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ MX31_PIN_DCD_DTE1__DCD_DTE2,
+ MX31_PIN_RI_DTE1__RI_DTE2,
+ MX31_PIN_DSR_DTE1__DSR_DTE2,
+ MX31_PIN_DTR_DTE1__DTR_DTE2,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init kzm_board_init(void)
+{
+ mxc_iomux_setup_multiple_pins(kzm_pins,
+ ARRAY_SIZE(kzm_pins), "kzm");
+ kzm_init_ext_uart();
+ kzm_init_smsc9118();
+ kzm_init_imx_uart();
+
+ pr_info("Clock input source is 26MHz\n");
+}
+
+/*
+ * This structure defines static mappings for the kzm-arm11-01 board.
+ */
+static struct map_desc kzm_io_desc[] __initdata = {
+ {
+ .virtual = MX31_CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+ .length = MX31_CS4_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .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 kzm_map_io(void)
+{
+ mx31_map_io();
+ iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc));
+}
+
+static void __init kzm_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer kzm_timer = {
+ .init = kzm_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_KZM_ARM11_01 data structure.
+ */
+MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = kzm_map_io,
+ .init_irq = mx31_init_irq,
+ .init_machine = kzm_board_init,
+ .timer = &kzm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
new file mode 100644
index 00000000000..f54af1e29ca
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -0,0 +1,344 @@
+/*
+ * 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 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/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>
+#include <linux/regulator/machine.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/board-mx31_3ds.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/mxc_nand.h>
+#include <mach/spi.h>
+#include "devices.h"
+
+/*!
+ * @file mx31_3ds.c
+ *
+ * @brief This file contains the board-specific initialization routines.
+ *
+ * @ingroup System
+ */
+
+static int mx31_3ds_pins[] = {
+ /* UART1 */
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
+ /* SPI 1 */
+ MX31_PIN_CSPI2_SCLK__SCLK,
+ MX31_PIN_CSPI2_MOSI__MOSI,
+ MX31_PIN_CSPI2_MISO__MISO,
+ MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI2_SS0__SS0,
+ MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
+ /* MC13783 IRQ */
+ IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
+};
+
+/* Regulators */
+static struct regulator_init_data pwgtx_init = {
+ .constraints = {
+ .boot_on = 1,
+ .always_on = 1,
+ },
+};
+
+static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
+ {
+ .id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */
+ .init_data = &pwgtx_init,
+ }, {
+ .id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */
+ .init_data = &pwgtx_init,
+ },
+};
+
+/* MC13783 */
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+ .regulators = mx31_3ds_regulators,
+ .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+ .flags = MC13783_USE_REGULATOR,
+};
+
+/* SPI */
+static int spi1_internal_chipselect[] = {
+ MXC_SPI_CS(0),
+ MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi1_pdata = {
+ .chipselect = spi1_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
+};
+
+static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 1, /* SS2 */
+ .platform_data = &mc13783_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ .mode = SPI_CS_HIGH,
+ },
+};
+
+/*
+ * NAND Flash
+ */
+static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
+ .width = 1,
+ .hw_ecc = 1,
+#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
+ .flash_bbt = 1,
+#endif
+};
+
+static struct imxuart_platform_data uart_pdata = {
+ .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));
+}
+
+/*!
+ * Board specific initialization.
+ */
+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);
+
+ mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+ spi_register_board_info(mx31_3ds_spi_devs,
+ ARRAY_SIZE(mx31_3ds_spi_devs));
+
+ if (!mx31_3ds_init_expio())
+ platform_device_register(&smsc911x_device);
+}
+
+static void __init mx31_3ds_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31_3ds_timer = {
+ .init = mx31_3ds_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_MX31_3DS data structure.
+ */
+MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_3ds_map_io,
+ .init_irq = mx31_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mx31_3ds_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mach-mx31ads.c b/arch/arm/mach-mx3/mach-mx31ads.c
new file mode 100644
index 00000000000..b3d1a1895c2
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-mx31ads.c
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * 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 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/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/irq.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/board-mx31ads.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+#include <linux/mfd/wm8350/audio.h>
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
+#include "devices.h"
+
+/*!
+ * @file mx31ads.c
+ *
+ * @brief This file contains the board-specific initialization routines.
+ *
+ * @ingroup System
+ */
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+/*!
+ * The serial port definition structure.
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
+ .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA),
+ .irq = EXPIO_INT_XUART_INTA,
+ .uartclk = 14745600,
+ .regshift = 0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+ }, {
+ .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
+ .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB),
+ .irq = EXPIO_INT_XUART_INTB,
+ .uartclk = 14745600,
+ .regshift = 0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+ },
+ {},
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static int __init mxc_init_extuart(void)
+{
+ return platform_device_register(&serial_device);
+}
+#else
+static inline int mxc_init_extuart(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static unsigned int uart_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1
+};
+
+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);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* !SERIAL_IMX */
+
+static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 imr_val;
+ u32 int_valid;
+ u32 expio_irq;
+
+ imr_val = __raw_readw(PBC_INTMASK_SET_REG);
+ int_valid = __raw_readw(PBC_INTSTATUS_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(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* mask the interrupt */
+ __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
+ __raw_readw(PBC_INTMASK_CLEAR_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(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* clear the interrupt status */
+ __raw_writew(1 << expio, PBC_INTSTATUS_REG);
+}
+
+/*
+ * 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(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* unmask the interrupt */
+ __raw_writew(1 << expio, PBC_INTMASK_SET_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+ .name = "EXPIO(CPLD)",
+ .ack = expio_ack_irq,
+ .mask = expio_mask_irq,
+ .unmask = expio_unmask_irq,
+};
+
+static void __init mx31ads_init_expio(void)
+{
+ int i;
+
+ printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio");
+
+ /* disable the interrupt and clear the status */
+ __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
+ __raw_writew(0xFFFF, PBC_INTSTATUS_REG);
+ for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+ i++) {
+ set_irq_chip(i, &expio_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
+ set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
+}
+
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+/* This section defines setup for the Wolfson Microelectronics
+ * 1133-EV1 PMU/audio board. When other PMU boards are supported the
+ * regulator definitions may be shared with them, but for now they can
+ * only be used with this board so would generate warnings about
+ * unused statics and some of the configuration is specific to this
+ * module.
+ */
+
+/* CPU */
+static struct regulator_consumer_supply sw1a_consumers[] = {
+ {
+ .supply = "cpu_vcc",
+ }
+};
+
+static struct regulator_init_data sw1a_data = {
+ .constraints = {
+ .name = "SW1A",
+ .min_uV = 1275000,
+ .max_uV = 1600000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .state_mem = {
+ .uV = 1400000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1a_consumers),
+ .consumer_supplies = sw1a_consumers,
+};
+
+/* System IO - High */
+static struct regulator_init_data viohi_data = {
+ .constraints = {
+ .name = "VIOHO",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .state_mem = {
+ .uV = 2800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* System IO - Low */
+static struct regulator_init_data violo_data = {
+ .constraints = {
+ .name = "VIOLO",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* DDR RAM */
+static struct regulator_init_data sw2a_data = {
+ .constraints = {
+ .name = "SW2A",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .state_disk = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 0,
+ },
+ .always_on = 1,
+ .boot_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ },
+};
+
+static struct regulator_init_data ldo1_data = {
+ .constraints = {
+ .name = "VCAM/VMMC1/VMMC2",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_consumer_supply ldo2_consumers[] = {
+ { .supply = "AVDD", .dev_name = "1-001a" },
+ { .supply = "HPVDD", .dev_name = "1-001a" },
+};
+
+/* CODEC and SIM */
+static struct regulator_init_data ldo2_data = {
+ .constraints = {
+ .name = "VESIM/VSIM/AVDD",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
+ .consumer_supplies = ldo2_consumers,
+};
+
+/* General */
+static struct regulator_init_data vdig_data = {
+ .constraints = {
+ .name = "VDIG",
+ .min_uV = 1500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* Tranceivers */
+static struct regulator_init_data ldo4_data = {
+ .constraints = {
+ .name = "VRF1/CVDD_2.775",
+ .min_uV = 2500000,
+ .max_uV = 2500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct wm8350_led_platform_data wm8350_led_data = {
+ .name = "wm8350:white",
+ .default_trigger = "heartbeat",
+ .max_uA = 27899,
+};
+
+static struct wm8350_audio_platform_data imx32ads_wm8350_setup = {
+ .vmid_discharge_msecs = 1000,
+ .drain_msecs = 30,
+ .cap_discharge_msecs = 700,
+ .vmid_charge_msecs = 700,
+ .vmid_s_curve = WM8350_S_CURVE_SLOW,
+ .dis_out4 = WM8350_DISCHARGE_SLOW,
+ .dis_out3 = WM8350_DISCHARGE_SLOW,
+ .dis_out2 = WM8350_DISCHARGE_SLOW,
+ .dis_out1 = WM8350_DISCHARGE_SLOW,
+ .vroi_out4 = WM8350_TIE_OFF_500R,
+ .vroi_out3 = WM8350_TIE_OFF_500R,
+ .vroi_out2 = WM8350_TIE_OFF_500R,
+ .vroi_out1 = WM8350_TIE_OFF_500R,
+ .vroi_enable = 0,
+ .codec_current_on = WM8350_CODEC_ISEL_1_0,
+ .codec_current_standby = WM8350_CODEC_ISEL_0_5,
+ .codec_current_charge = WM8350_CODEC_ISEL_1_5,
+};
+
+static int mx31_wm8350_init(struct wm8350 *wm8350)
+{
+ wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_ON);
+
+ wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_ON);
+
+ wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data);
+
+ /* LEDs */
+ wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1,
+ WM8350_DC5_ERRACT_SHUTDOWN_CONV);
+ wm8350_isink_set_flash(wm8350, WM8350_ISINK_A,
+ WM8350_ISINK_FLASH_DISABLE,
+ WM8350_ISINK_FLASH_TRIG_BIT,
+ WM8350_ISINK_FLASH_DUR_32MS,
+ WM8350_ISINK_FLASH_ON_INSTANT,
+ WM8350_ISINK_FLASH_OFF_INSTANT,
+ WM8350_ISINK_FLASH_MODE_EN);
+ wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5,
+ WM8350_ISINK_MODE_BOOST,
+ WM8350_ISINK_ILIM_NORMAL,
+ WM8350_DC5_RMP_20V,
+ WM8350_DC5_FBSRC_ISINKA);
+ wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A,
+ &wm8350_led_data);
+
+ wm8350->codec.platform_data = &imx32ads_wm8350_setup;
+
+ regulator_has_full_constraints();
+
+ return 0;
+}
+
+static struct wm8350_platform_data __initdata mx31_wm8350_pdata = {
+ .init = mx31_wm8350_init,
+ .irq_base = MXC_BOARD_IRQ_START + MXC_MAX_EXP_IO_LINES,
+};
+#endif
+
+#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE)
+static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = {
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+ {
+ I2C_BOARD_INFO("wm8350", 0x1a),
+ .platform_data = &mx31_wm8350_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ },
+#endif
+};
+
+static void mxc_init_i2c(void)
+{
+ i2c_register_board_info(1, mx31ads_i2c1_devices,
+ ARRAY_SIZE(mx31ads_i2c1_devices));
+
+ 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);
+}
+#else
+static void mxc_init_i2c(void)
+{
+}
+#endif
+
+static unsigned int ssi_pins[] = {
+ MX31_PIN_SFS5__SFS5,
+ MX31_PIN_SCK5__SCK5,
+ MX31_PIN_SRXD5__SRXD5,
+ MX31_PIN_STXD5__STXD5,
+};
+
+static void mxc_init_audio(void)
+{
+ mxc_register_device(&imx_ssi_device0, NULL);
+ mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
+}
+
+/*!
+ * This structure defines static mappings for the i.MX31ADS board.
+ */
+static struct map_desc mx31ads_io_desc[] __initdata = {
+ {
+ .virtual = MX31_CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+ .length = MX31_CS4_SIZE / 2,
+ .type = MT_DEVICE
+ },
+};
+
+/*!
+ * Set up static virtual mappings.
+ */
+static void __init mx31ads_map_io(void)
+{
+ mx31_map_io();
+ iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
+}
+
+static void __init mx31ads_init_irq(void)
+{
+ mx31_init_irq();
+ mx31ads_init_expio();
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_init_extuart();
+ mxc_init_imx_uart();
+ mxc_init_i2c();
+ mxc_init_audio();
+}
+
+static void __init mx31ads_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31ads_timer = {
+ .init = mx31ads_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_MX31ADS data structure.
+ */
+MACHINE_START(MX31ADS, "Freescale MX31ADS")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31ads_map_io,
+ .init_irq = mx31ads_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mx31ads_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mach-mx31lilly.c b/arch/arm/mach-mx3/mach-mx31lilly.c
new file mode 100644
index 00000000000..80847b04c06
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-mx31lilly.c
@@ -0,0 +1,206 @@
+/*
+ * LILLY-1131 module support
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * based on code for other MX31 boards,
+ *
+ * Copyright 2005-2007 Freescale Semiconductor
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; 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/clk.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/smsc911x.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/mc13783.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lilly.h>
+#include <mach/spi.h>
+
+#include "devices.h"
+
+/*
+ * This file contains module-specific initialization routines for LILLY-1131.
+ * Initialization of peripherals found on the baseboard is implemented in the
+ * appropriate baseboard support code.
+ */
+
+/* SMSC ethernet support */
+
+static struct resource smsc91x_resources[] = {
+ {
+ .start = MX31_CS4_BASE_ADDR,
+ .end = MX31_CS4_BASE_ADDR + 0xffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+ }
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT |
+ SMSC911X_SAVE_MAC_ADDRESS |
+ SMSC911X_FORCE_INTERNAL_PHY,
+};
+
+static struct platform_device smsc91x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc91x_resources),
+ .resource = smsc91x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ }
+};
+
+/* NOR flash */
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+};
+
+static struct resource nor_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device physmap_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .resource = &nor_flash_resource,
+ .num_resources = 1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &smsc91x_device,
+ &physmap_flash_device,
+};
+
+/* SPI */
+
+static int spi_internal_chipselect[] = {
+ MXC_SPI_CS(0),
+ MXC_SPI_CS(1),
+ MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi0_pdata = {
+ .chipselect = spi_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct spi_imx_master spi1_pdata = {
+ .chipselect = spi_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+ .flags = MC13783_USE_RTC | MC13783_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info mc13783_dev __initdata = {
+ .modalias = "mc13783",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = &mc13783_pdata,
+};
+
+static int mx31lilly_baseboard;
+core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
+
+static void __init mx31lilly_board_init(void)
+{
+ switch (mx31lilly_baseboard) {
+ case MX31LILLY_NOBOARD:
+ break;
+ case MX31LILLY_DB:
+ mx31lilly_db_init();
+ break;
+ default:
+ printk(KERN_ERR "Illegal mx31lilly_baseboard type %d\n",
+ mx31lilly_baseboard);
+ }
+
+ mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS");
+
+ /* SPI */
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2");
+
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0");
+ 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);
+ spi_register_board_info(&mc13783_dev, 1);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mx31lilly_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31lilly_timer = {
+ .init = mx31lilly_timer_init,
+};
+
+MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_irq = mx31_init_irq,
+ .init_machine = mx31lilly_board_init,
+ .timer = &mx31lilly_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx3/mach-mx31lite.c b/arch/arm/mach-mx3/mach-mx31lite.c
new file mode 100644
index 00000000000..2b6d1140087
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-mx31lite.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Daniel Mack <daniel@caiaq.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#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.h"
+
+/*
+ * This file contains the module-specific initialization routines.
+ */
+
+static unsigned int mx31lite_pins[] = {
+ /* LAN9117 IRQ pin */
+ IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO),
+ /* SPI 1 */
+ MX31_PIN_CSPI2_SCLK__SCLK,
+ MX31_PIN_CSPI2_MOSI__MOSI,
+ MX31_PIN_CSPI2_MISO__MISO,
+ MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI2_SS0__SS0,
+ MX31_PIN_CSPI2_SS1__SS1,
+ MX31_PIN_CSPI2_SS2__SS2,
+};
+
+static struct mxc_nand_platform_data mx31lite_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+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,
+};
+
+static struct resource smsc911x_resources[] = {
+ {
+ .start = MX31_CS4_BASE_ADDR,
+ .end = MX31_CS4_BASE_ADDR + 0x100,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(MX31_PIN_SFS6),
+ .end = IOMUX_TO_IRQ(MX31_PIN_SFS6),
+ .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,
+ },
+};
+
+/*
+ * SPI
+ *
+ * The MC13783 is the only hard-wired SPI device on the module.
+ */
+
+static int spi_internal_chipselect[] = {
+ MXC_SPI_CS(0),
+};
+
+static struct spi_imx_master spi1_pdata = {
+ .chipselect = spi_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+ .flags = MC13783_USE_RTC |
+ MC13783_USE_REGULATOR,
+};
+
+static struct spi_board_info mc13783_spi_dev __initdata = {
+ .modalias = "mc13783",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = &mc13783_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+};
+
+/*
+ * USB
+ */
+
+#if defined(CONFIG_USB_ULPI)
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbh2_init(struct platform_device *pdev)
+{
+ int pins[] = {
+ MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+ MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+ MX31_PIN_USBH2_CLK__USBH2_CLK,
+ MX31_PIN_USBH2_DIR__USBH2_DIR,
+ MX31_PIN_USBH2_NXT__USBH2_NXT,
+ MX31_PIN_USBH2_STP__USBH2_STP,
+ };
+
+ mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2");
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+ /* chip select */
+ mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO),
+ "USBH2_CS");
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS");
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0);
+
+ return 0;
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+ .init = usbh2_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED,
+};
+#endif
+
+/*
+ * NOR flash
+ */
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+};
+
+static struct resource nor_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device physmap_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .resource = &nor_flash_resource,
+ .num_resources = 1,
+};
+
+
+
+/*
+ * This structure defines the MX31 memory map.
+ */
+static struct map_desc mx31lite_io_desc[] __initdata = {
+ {
+ .virtual = MX31_CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+ .length = MX31_CS4_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+void __init mx31lite_map_io(void)
+{
+ mx31_map_io();
+ iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc));
+}
+
+static int mx31lite_baseboard;
+core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444);
+
+static void __init mxc_board_init(void)
+{
+ int ret;
+
+ switch (mx31lite_baseboard) {
+ case MX31LITE_NOBOARD:
+ break;
+ case MX31LITE_DB:
+ mx31lite_db_init();
+ break;
+ default:
+ printk(KERN_ERR "Illegal mx31lite_baseboard type %d\n",
+ mx31lite_baseboard);
+ }
+
+ mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins),
+ "mx31lite");
+
+ /* NOR and NAND flash */
+ platform_device_register(&physmap_flash_device);
+ mxc_register_device(&mxc_nand_device, &mx31lite_nand_board_info);
+
+ mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+ spi_register_board_info(&mc13783_spi_dev, 1);
+
+#if defined(CONFIG_USB_ULPI)
+ /* USB */
+ 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
+
+ /* SMSC9117 IRQ pin */
+ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq");
+ if (ret)
+ pr_warning("could not get LAN irq gpio\n");
+ else {
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+ platform_device_register(&smsc911x_device);
+ }
+}
+
+static void __init mx31lite_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+struct sys_timer mx31lite_timer = {
+ .init = mx31lite_timer_init,
+};
+
+MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31lite_map_io,
+ .init_irq = mx31_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mx31lite_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c
new file mode 100644
index 00000000000..fccb9207b78
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-mx31moboard.c
@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 2008 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; 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/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/gfp.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/memory.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
+
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#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.h"
+
+static unsigned int moboard_pins[] = {
+ /* UART0 */
+ MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
+ MX31_PIN_CTS1__GPIO2_7,
+ /* UART4 */
+ MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
+ MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
+ /* I2C0 */
+ MX31_PIN_I2C_DAT__I2C1_SDA, MX31_PIN_I2C_CLK__I2C1_SCL,
+ /* I2C1 */
+ MX31_PIN_DCD_DTE1__I2C2_SDA, MX31_PIN_RI_DTE1__I2C2_SCL,
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA3__SD1_DATA3, MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD,
+ MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27,
+ /* USB reset */
+ MX31_PIN_GPIO1_0__GPIO1_0,
+ /* USB OTG */
+ MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+ MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+ MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+ MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+ MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+ MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+ MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+ MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+ MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+ MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
+ MX31_PIN_USB_OC__GPIO1_30,
+ /* USB H2 */
+ MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+ MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+ MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3,
+ MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5,
+ MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7,
+ MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR,
+ MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP,
+ MX31_PIN_SCK6__GPIO1_25,
+ /* LEDs */
+ MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
+ MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
+ /* SPI1 */
+ MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO,
+ MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2,
+ /* Atlas IRQ */
+ MX31_PIN_GPIO1_3__GPIO1_3,
+ /* SPI2 */
+ MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO,
+ MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI2_SS1__CSPI3_SS1,
+};
+
+static struct physmap_flash_data mx31moboard_flash_data = {
+ .width = 2,
+};
+
+static struct resource mx31moboard_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mx31moboard_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx31moboard_flash_data,
+ },
+ .resource = &mx31moboard_flash_resource,
+ .num_resources = 1,
+};
+
+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;
+}
+
+static struct imxuart_platform_data uart0_pdata = {
+ .init = moboard_uart0_init,
+};
+
+static struct imxuart_platform_data uart4_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct imxi2c_platform_data moboard_i2c0_pdata = {
+ .bitrate = 400000,
+};
+
+static struct imxi2c_platform_data moboard_i2c1_pdata = {
+ .bitrate = 100000,
+};
+
+static int moboard_spi1_cs[] = {
+ MXC_SPI_CS(0),
+ MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master moboard_spi1_master = {
+ .chipselect = moboard_spi1_cs,
+ .num_chipselect = ARRAY_SIZE(moboard_spi1_cs),
+};
+
+static struct regulator_consumer_supply sdhc_consumers[] = {
+ {
+ .dev = &mxcsdhc_device0.dev,
+ .supply = "sdhc0_vcc",
+ },
+ {
+ .dev = &mxcsdhc_device1.dev,
+ .supply = "sdhc1_vcc",
+ },
+};
+
+static struct regulator_init_data sdhc_vreg_data = {
+ .constraints = {
+ .min_uV = 2700000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdhc_consumers),
+ .consumer_supplies = sdhc_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+ {
+ .dev = &mx3_camera.dev,
+ .supply = "cam_vcc",
+ },
+};
+
+static struct regulator_init_data cam_vreg_data = {
+ .constraints = {
+ .min_uV = 2700000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+ .consumer_supplies = cam_consumers,
+};
+
+static struct mc13783_regulator_init_data moboard_regulators[] = {
+ {
+ .id = MC13783_REGU_VMMC1,
+ .init_data = &sdhc_vreg_data,
+ },
+ {
+ .id = MC13783_REGU_VCAM,
+ .init_data = &cam_vreg_data,
+ },
+};
+
+static struct mc13783_platform_data moboard_pmic = {
+ .regulators = moboard_regulators,
+ .num_regulators = ARRAY_SIZE(moboard_regulators),
+ .flags = MC13783_USE_REGULATOR | MC13783_USE_RTC |
+ MC13783_USE_ADC,
+};
+
+static struct spi_board_info moboard_spi_board_info[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ .max_speed_hz = 300000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = &moboard_pmic,
+ .mode = SPI_CS_HIGH,
+ },
+};
+
+static int moboard_spi2_cs[] = {
+ MXC_SPI_CS(1),
+};
+
+static struct spi_imx_master moboard_spi2_master = {
+ .chipselect = moboard_spi2_cs,
+ .num_chipselect = ARRAY_SIZE(moboard_spi2_cs),
+};
+
+#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
+#define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1)
+
+static int moboard_sdhc1_get_ro(struct device *dev)
+{
+ return !gpio_get_value(SDHC1_WP);
+}
+
+static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request(SDHC1_CD, "sdhc-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(SDHC1_CD);
+
+ ret = gpio_request(SDHC1_WP, "sdhc-wp");
+ if (ret)
+ goto err_gpio_free;
+ gpio_direction_input(SDHC1_WP);
+
+ ret = request_irq(gpio_to_irq(SDHC1_CD), detect_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "sdhc1-card-detect", data);
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+ gpio_free(SDHC1_WP);
+err_gpio_free:
+ gpio_free(SDHC1_CD);
+
+ return ret;
+}
+
+static void moboard_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(SDHC1_CD), data);
+ gpio_free(SDHC1_WP);
+ gpio_free(SDHC1_CD);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+ .get_ro = moboard_sdhc1_get_ro,
+ .init = moboard_sdhc1_init,
+ .exit = moboard_sdhc1_exit,
+};
+
+/*
+ * this pin is dedicated for all mx31moboard systems, so we do it here
+ */
+#define USB_RESET_B IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
+
+static void usb_xcvr_reset(void)
+{
+ gpio_request(USB_RESET_B, "usb-reset");
+ gpio_direction_output(USB_RESET_B, 0);
+ mdelay(1);
+ gpio_set_value(USB_RESET_B, 1);
+}
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
+
+static void moboard_usbotg_init(void)
+{
+ 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);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+ gpio_request(OTG_EN_B, "usb-udc-en");
+ gpio_direction_output(OTG_EN_B, 0);
+}
+
+static struct fsl_usb2_platform_data usb_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+#if defined(CONFIG_USB_ULPI)
+
+#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
+
+static int moboard_usbh2_hw_init(struct platform_device *pdev)
+{
+ int ret;
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+ ret = gpio_request(USBH2_EN_B, "usbh2-en");
+ if (ret)
+ return ret;
+ gpio_direction_output(USBH2_EN_B, 0);
+
+ return 0;
+}
+
+static int moboard_usbh2_hw_exit(struct platform_device *pdev)
+{
+ gpio_free(USBH2_EN_B);
+ return 0;
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+ .init = moboard_usbh2_hw_init,
+ .exit = moboard_usbh2_hw_exit,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED,
+};
+
+static int __init moboard_usbh2_init(void)
+{
+ usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+ return mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+}
+#else
+static inline int moboard_usbh2_init(void) { return 0; }
+#endif
+
+
+static struct gpio_led mx31moboard_leds[] = {
+ {
+ .name = "coreboard-led-0:red:running",
+ .default_trigger = "heartbeat",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SVEN0),
+ }, {
+ .name = "coreboard-led-1:red",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_STX0),
+ }, {
+ .name = "coreboard-led-2:red",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SRX0),
+ }, {
+ .name = "coreboard-led-3:red",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SIMPD0),
+ },
+};
+
+static struct gpio_led_platform_data mx31moboard_led_pdata = {
+ .num_leds = ARRAY_SIZE(mx31moboard_leds),
+ .leds = mx31moboard_leds,
+};
+
+static struct platform_device mx31moboard_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mx31moboard_led_pdata,
+ },
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mx31moboard_flash,
+ &mx31moboard_leds_device,
+};
+
+static struct mx3_camera_pdata camera_pdata = {
+ .dma_dev = &mx3_ipu.dev,
+ .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+ .mclk_10khz = 4800,
+};
+
+#define CAMERA_BUF_SIZE (4*1024*1024)
+
+static int __init mx31moboard_cam_alloc_dma(const size_t buf_size)
+{
+ dma_addr_t dma_handle;
+ void *buf;
+ int dma;
+
+ if (buf_size < 2 * 1024 * 1024)
+ return -EINVAL;
+
+ buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
+ if (!buf) {
+ pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ memset(buf, 0, buf_size);
+
+ dma = dma_declare_coherent_memory(&mx3_camera.dev,
+ dma_handle, dma_handle, buf_size,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+ /* The way we call dma_declare_coherent_memory only a malloc can fail */
+ return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
+}
+
+static int mx31moboard_baseboard;
+core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
+ "moboard");
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ mxc_register_device(&mxc_uart_device0, &uart0_pdata);
+
+ mxc_register_device(&mxc_uart_device4, &uart4_pdata);
+
+ mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
+ mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
+
+ mxc_register_device(&mxc_spi_device1, &moboard_spi1_master);
+ mxc_register_device(&mxc_spi_device2, &moboard_spi2_master);
+
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq");
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
+ spi_register_board_info(moboard_spi_board_info,
+ ARRAY_SIZE(moboard_spi_board_info));
+
+ mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
+
+ mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+ if (!mx31moboard_cam_alloc_dma(CAMERA_BUF_SIZE))
+ mxc_register_device(&mx3_camera, &camera_pdata);
+
+ usb_xcvr_reset();
+
+ moboard_usbotg_init();
+ mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+ moboard_usbh2_init();
+
+ switch (mx31moboard_baseboard) {
+ case MX31NOBOARD:
+ break;
+ case MX31DEVBOARD:
+ mx31moboard_devboard_init();
+ break;
+ case MX31MARXBOT:
+ mx31moboard_marxbot_init();
+ break;
+ case MX31SMARTBOT:
+ mx31moboard_smartbot_init();
+ break;
+ default:
+ printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n",
+ mx31moboard_baseboard);
+ }
+}
+
+static void __init mx31moboard_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+struct sys_timer mx31moboard_timer = {
+ .init = mx31moboard_timer_init,
+};
+
+MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
+ /* Maintainer: Valentin Longchamp, EPFL Mobots group */
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_irq = mx31_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mx31moboard_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx3/mach-mx35pdk.c b/arch/arm/mach-mx3/mach-mx35pdk.c
new file mode 100644
index 00000000000..bcac84d4dca
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-mx35pdk.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.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/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/memory.h>
+#include <linux/gpio.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/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx35.h>
+
+#include "devices.h"
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mxc_fec_device,
+};
+
+static struct pad_desc mx35pdk_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,
+ /* USBOTG */
+ MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
+ MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+};
+
+/* OTG config */
+static struct fsl_usb2_platform_data usb_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
+
+ mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+}
+
+static void __init mx35pdk_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+struct sys_timer mx35pdk_timer = {
+ .init = mx35pdk_timer_init,
+};
+
+MACHINE_START(MX35_3DS, "Freescale MX35PDK")
+ /* Maintainer: Freescale Semiconductor, Inc */
+ .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 = &mx35pdk_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c
new file mode 100644
index 00000000000..2df1ec55a97
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-pcm037.c
@@ -0,0 +1,693 @@
+/*
+ * 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
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
+#include <linux/fsl_devices.h>
+#include <linux/can/platform/sja1000.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/gfp.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/mach-types.h>
+#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.h"
+#include "pcm037.h"
+
+static enum pcm037_board_variant pcm037_instance = PCM037_PCM970;
+
+static int __init pcm037_variant_setup(char *str)
+{
+ if (!strcmp("eet", str))
+ pcm037_instance = PCM037_EET;
+ else if (strcmp("pcm970", str))
+ pr_warning("Unknown pcm037 baseboard variant %s\n", str);
+
+ return 1;
+}
+
+/* Supported values: "pcm970" (default) and "eet" */
+__setup("pcm037_variant=", pcm037_variant_setup);
+
+enum pcm037_board_variant pcm037_variant(void)
+{
+ return pcm037_instance;
+}
+
+/* UART1 with RTS/CTS handshake signals */
+static unsigned int pcm037_uart1_handshake_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+};
+
+/* UART1 without RTS/CTS handshake signals */
+static unsigned int pcm037_uart1_pins[] = {
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+};
+
+static unsigned int pcm037_pins[] = {
+ /* I2C */
+ MX31_PIN_CSPI2_MOSI__SCL,
+ MX31_PIN_CSPI2_MISO__SDA,
+ MX31_PIN_CSPI2_SS2__I2C3_SDA,
+ MX31_PIN_CSPI2_SCLK__I2C3_SCL,
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+ IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO), /* card detect */
+ IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), /* write protect */
+ /* SPI1 */
+ MX31_PIN_CSPI1_MOSI__MOSI,
+ MX31_PIN_CSPI1_MISO__MISO,
+ MX31_PIN_CSPI1_SCLK__SCLK,
+ MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI1_SS0__SS0,
+ MX31_PIN_CSPI1_SS1__SS1,
+ MX31_PIN_CSPI1_SS2__SS2,
+ /* UART2 */
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ /* UART3 */
+ MX31_PIN_CSPI3_MOSI__RXD3,
+ MX31_PIN_CSPI3_MISO__TXD3,
+ MX31_PIN_CSPI3_SCLK__RTS3,
+ MX31_PIN_CSPI3_SPI_RDY__CTS3,
+ /* LAN9217 irq pin */
+ IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
+ /* Onewire */
+ MX31_PIN_BATT_LINE__OWIRE,
+ /* Framebuffer */
+ MX31_PIN_LD0__LD0,
+ MX31_PIN_LD1__LD1,
+ MX31_PIN_LD2__LD2,
+ MX31_PIN_LD3__LD3,
+ MX31_PIN_LD4__LD4,
+ MX31_PIN_LD5__LD5,
+ MX31_PIN_LD6__LD6,
+ MX31_PIN_LD7__LD7,
+ MX31_PIN_LD8__LD8,
+ MX31_PIN_LD9__LD9,
+ MX31_PIN_LD10__LD10,
+ MX31_PIN_LD11__LD11,
+ MX31_PIN_LD12__LD12,
+ MX31_PIN_LD13__LD13,
+ MX31_PIN_LD14__LD14,
+ MX31_PIN_LD15__LD15,
+ MX31_PIN_LD16__LD16,
+ MX31_PIN_LD17__LD17,
+ MX31_PIN_VSYNC3__VSYNC3,
+ MX31_PIN_HSYNC__HSYNC,
+ MX31_PIN_FPSHIFT__FPSHIFT,
+ MX31_PIN_DRDY0__DRDY0,
+ MX31_PIN_D3_REV__D3_REV,
+ MX31_PIN_CONTRAST__CONTRAST,
+ MX31_PIN_D3_SPL__D3_SPL,
+ MX31_PIN_D3_CLS__D3_CLS,
+ MX31_PIN_LCS0__GPI03_23,
+ /* CSI */
+ IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO),
+ MX31_PIN_CSI_D6__CSI_D6,
+ MX31_PIN_CSI_D7__CSI_D7,
+ MX31_PIN_CSI_D8__CSI_D8,
+ MX31_PIN_CSI_D9__CSI_D9,
+ MX31_PIN_CSI_D10__CSI_D10,
+ MX31_PIN_CSI_D11__CSI_D11,
+ MX31_PIN_CSI_D12__CSI_D12,
+ MX31_PIN_CSI_D13__CSI_D13,
+ MX31_PIN_CSI_D14__CSI_D14,
+ MX31_PIN_CSI_D15__CSI_D15,
+ MX31_PIN_CSI_HSYNC__CSI_HSYNC,
+ MX31_PIN_CSI_MCLK__CSI_MCLK,
+ MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
+ MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+ /* GPIO */
+ IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO),
+ /* OTG */
+ MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+ MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+ MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+ MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+ MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+ MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+ MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+ MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+ MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+ MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+ MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+ MX31_PIN_USBOTG_STP__USBOTG_STP,
+ /* USB host 2 */
+ IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
+};
+
+static struct physmap_flash_data pcm037_flash_data = {
+ .width = 2,
+};
+
+static struct resource pcm037_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm037_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm037_flash_data,
+ },
+ .resource = &pcm037_flash_resource,
+ .num_resources = 1,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct resource smsc911x_resources[] = {
+ {
+ .start = MX31_CS1_BASE_ADDR + 0x300,
+ .end = MX31_CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY |
+ SMSC911X_SAVE_MAC_ADDRESS,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device pcm037_eth = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_info,
+ },
+};
+
+static struct platdata_mtd_ram pcm038_sram_data = {
+ .bankwidth = 2,
+};
+
+static struct resource pcm038_sram_resource = {
+ .start = MX31_CS4_BASE_ADDR,
+ .end = MX31_CS4_BASE_ADDR + 512 * 1024 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm037_sram_device = {
+ .name = "mtd-ram",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm038_sram_data,
+ },
+ .num_resources = 1,
+ .resource = &pcm038_sram_resource,
+};
+
+static struct mxc_nand_platform_data pcm037_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct imxi2c_platform_data pcm037_i2c_1_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data pcm037_i2c_2_data = {
+ .bitrate = 20000,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static int pcm037_camera_power(struct device *dev, int on)
+{
+ /* disable or enable the camera in X7 or X8 PCM970 connector */
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on);
+ return 0;
+}
+
+static struct i2c_board_info pcm037_i2c_camera[] = {
+ {
+ I2C_BOARD_INFO("mt9t031", 0x5d),
+ }, {
+ I2C_BOARD_INFO("mt9v022", 0x48),
+ },
+};
+
+static struct soc_camera_link iclink_mt9v022 = {
+ .bus_id = 0, /* Must match with the camera ID */
+ .board_info = &pcm037_i2c_camera[1],
+ .i2c_adapter_id = 2,
+ .module_name = "mt9v022",
+};
+
+static struct soc_camera_link iclink_mt9t031 = {
+ .bus_id = 0, /* Must match with the camera ID */
+ .power = pcm037_camera_power,
+ .board_info = &pcm037_i2c_camera[0],
+ .i2c_adapter_id = 2,
+ .module_name = "mt9t031",
+};
+
+static struct i2c_board_info pcm037_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }
+};
+
+static struct platform_device pcm037_mt9t031 = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &iclink_mt9t031,
+ },
+};
+
+static struct platform_device pcm037_mt9v022 = {
+ .name = "soc-camera-pdrv",
+ .id = 1,
+ .dev = {
+ .platform_data = &iclink_mt9v022,
+ },
+};
+
+/* Not connected by default */
+#ifdef PCM970_SDHC_RW_SWITCH
+static int pcm970_sdhc1_get_ro(struct device *dev)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+}
+#endif
+
+#define SDHC1_GPIO_WP IOMUX_TO_GPIO(MX31_PIN_SFS6)
+#define SDHC1_GPIO_DET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+
+static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request(SDHC1_GPIO_DET, "sdhc-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(SDHC1_GPIO_DET);
+
+#ifdef PCM970_SDHC_RW_SWITCH
+ ret = gpio_request(SDHC1_GPIO_WP, "sdhc-wp");
+ if (ret)
+ goto err_gpio_free;
+ gpio_direction_input(SDHC1_GPIO_WP);
+#endif
+
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "sdhc-detect", data);
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+#ifdef PCM970_SDHC_RW_SWITCH
+ gpio_free(SDHC1_GPIO_WP);
+err_gpio_free:
+#endif
+ gpio_free(SDHC1_GPIO_DET);
+
+ return ret;
+}
+
+static void pcm970_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), data);
+ gpio_free(SDHC1_GPIO_DET);
+ gpio_free(SDHC1_GPIO_WP);
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+#ifdef PCM970_SDHC_RW_SWITCH
+ .get_ro = pcm970_sdhc1_get_ro,
+#endif
+ .init = pcm970_sdhc1_init,
+ .exit = pcm970_sdhc1_exit,
+};
+
+struct mx3_camera_pdata camera_pdata = {
+ .dma_dev = &mx3_ipu.dev,
+ .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+ .mclk_10khz = 2000,
+};
+
+static int __init pcm037_camera_alloc_dma(const size_t buf_size)
+{
+ dma_addr_t dma_handle;
+ void *buf;
+ int dma;
+
+ if (buf_size < 2 * 1024 * 1024)
+ return -EINVAL;
+
+ buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
+ if (!buf) {
+ pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ memset(buf, 0, buf_size);
+
+ dma = dma_declare_coherent_memory(&mx3_camera.dev,
+ dma_handle, dma_handle, buf_size,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+ /* The way we call dma_declare_coherent_memory only a malloc can fail */
+ return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
+}
+
+static struct platform_device *devices[] __initdata = {
+ &pcm037_flash,
+ &pcm037_sram_device,
+ &pcm037_mt9t031,
+ &pcm037_mt9v022,
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static const struct fb_videomode fb_modedb[] = {
+ {
+ /* 240x320 @ 60 Hz Sharp */
+ .name = "Sharp-LQ035Q7DH06-QVGA",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
+ FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 240x320 @ 60 Hz */
+ .name = "TX090",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 38255,
+ .left_margin = 144,
+ .right_margin = 0,
+ .upper_margin = 7,
+ .lower_margin = 40,
+ .hsync_len = 96,
+ .vsync_len = 1,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 240x320 @ 60 Hz */
+ .name = "CMEL-OLED",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static struct mx3fb_platform_data mx3fb_pdata = {
+ .dma_dev = &mx3_ipu.dev,
+ .name = "Sharp-LQ035Q7DH06-QVGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static struct resource pcm970_sja1000_resources[] = {
+ {
+ .start = MX31_CS5_BASE_ADDR,
+ .end = MX31_CS5_BASE_ADDR + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
+ .end = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+struct sja1000_platform_data pcm970_sja1000_platform_data = {
+ .clock = 16000000 / 2,
+ .ocr = 0x40 | 0x18,
+ .cdr = 0x40,
+};
+
+static struct platform_device pcm970_sja1000 = {
+ .name = "sja1000_platform",
+ .dev = {
+ .platform_data = &pcm970_sja1000_platform_data,
+ },
+ .resource = pcm970_sja1000_resources,
+ .num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
+};
+
+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,
+};
+
+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 pcm037_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=", pcm037_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ int ret;
+ u32 tmp;
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, 1);
+
+ mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins),
+ "pcm037");
+
+#define H2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS \
+ | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, H2_PAD_CFG); /* USBH2_DATA0 */
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, H2_PAD_CFG); /* USBH2_DATA1 */
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, H2_PAD_CFG); /* USBH2_DATA2 */
+ mxc_iomux_set_pad(MX31_PIN_STXD6, H2_PAD_CFG); /* USBH2_DATA3 */
+ mxc_iomux_set_pad(MX31_PIN_SFS3, H2_PAD_CFG); /* USBH2_DATA4 */
+ mxc_iomux_set_pad(MX31_PIN_SCK3, H2_PAD_CFG); /* USBH2_DATA5 */
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, H2_PAD_CFG); /* USBH2_DATA6 */
+ mxc_iomux_set_pad(MX31_PIN_STXD3, H2_PAD_CFG); /* USBH2_DATA7 */
+
+ if (pcm037_variant() == PCM037_EET)
+ mxc_iomux_setup_multiple_pins(pcm037_uart1_pins,
+ ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1");
+ else
+ mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins,
+ ARRAY_SIZE(pcm037_uart1_handshake_pins),
+ "pcm037_uart1");
+
+ 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);
+
+ mxc_register_device(&mxc_w1_master_device, NULL);
+
+ /* LAN9217 IRQ pin */
+ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq");
+ if (ret)
+ pr_warning("could not get LAN irq gpio\n");
+ else {
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1));
+ platform_device_register(&pcm037_eth);
+ }
+
+
+ /* I2C adapters and devices */
+ 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);
+
+ mxc_register_device(&mxc_nand_device, &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);
+
+ /* CSI */
+ /* Camera power: default - off */
+ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "mt9t031-power");
+ if (!ret)
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1);
+ else
+ iclink_mt9t031.power = NULL;
+
+ if (!pcm037_camera_alloc_dma(4 * 1024 * 1024))
+ mxc_register_device(&mx3_camera, &camera_pdata);
+
+ platform_device_register(&pcm970_sja1000);
+
+#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);
+
+}
+
+static void __init pcm037_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+struct sys_timer pcm037_timer = {
+ .init = pcm037_timer_init,
+};
+
+MACHINE_START(PCM037, "Phytec Phycore pcm037")
+ /* Maintainer: Pengutronix */
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_irq = mx31_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &pcm037_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/pcm037_eet.c b/arch/arm/mach-mx3/mach-pcm037_eet.c
index 8d386000fc4..8d386000fc4 100644
--- a/arch/arm/mach-mx3/pcm037_eet.c
+++ b/arch/arm/mach-mx3/mach-pcm037_eet.c
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
new file mode 100644
index 00000000000..1bf1ec2eef5
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -0,0 +1,413 @@
+/*
+ * 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/mtd/plat-ram.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/smc911x.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.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/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.h"
+
+static const struct fb_videomode fb_modedb[] = {
+ {
+ /* 240x320 @ 60 Hz */
+ .name = "Sharp-LQ035Q7",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 240x320 @ 60 Hz */
+ .name = "TX090",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 38255,
+ .left_margin = 144,
+ .right_margin = 0,
+ .upper_margin = 7,
+ .lower_margin = 40,
+ .hsync_len = 96,
+ .vsync_len = 1,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+ .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 = "Sharp-LQ035Q7",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static struct physmap_flash_data pcm043_flash_data = {
+ .width = 2,
+};
+
+static struct resource pcm043_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm043_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm043_flash_data,
+ },
+ .resource = &pcm043_flash_resource,
+ .num_resources = 1,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
+static struct imxi2c_platform_data pcm043_i2c_1_data = {
+ .bitrate = 50000,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm043_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }
+};
+#endif
+
+static struct platform_device *devices[] __initdata = {
+ &pcm043_flash,
+ &mxc_fec_device,
+};
+
+static struct pad_desc pcm043_pads[] = {
+ /* UART1 */
+ MX35_PAD_CTS1__UART1_CTS,
+ MX35_PAD_RTS1__UART1_RTS,
+ MX35_PAD_TXD1__UART1_TXD_MUX,
+ MX35_PAD_RXD1__UART1_RXD_MUX,
+ /* UART2 */
+ MX35_PAD_CTS2__UART2_CTS,
+ MX35_PAD_RTS2__UART2_RTS,
+ MX35_PAD_TXD2__UART2_TXD_MUX,
+ MX35_PAD_RXD2__UART2_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,
+ /* Display */
+ 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_CONTRAST__IPU_DISPB_CONTR,
+ MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
+ MX35_PAD_D3_REV__IPU_DISPB_D3_REV,
+ MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS,
+ /* gpio */
+ MX35_PAD_ATA_CS0__GPIO2_6,
+ /* USB host */
+ MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
+ MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
+ /* SSI */
+ 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 AC97_GPIO_TXFS (1 * 32 + 31)
+#define AC97_GPIO_TXD (1 * 32 + 28)
+#define AC97_GPIO_RESET (1 * 32 + 0)
+
+static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+ struct pad_desc txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+ struct pad_desc txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
+ int ret;
+
+ ret = gpio_request(AC97_GPIO_TXFS, "SSI");
+ if (ret) {
+ printk("failed to get GPIO_TXFS: %d\n", ret);
+ return;
+ }
+
+ mxc_iomux_v3_setup_pad(&txfs_gpio);
+
+ /* warm reset */
+ gpio_direction_output(AC97_GPIO_TXFS, 1);
+ udelay(2);
+ gpio_set_value(AC97_GPIO_TXFS, 0);
+
+ gpio_free(AC97_GPIO_TXFS);
+ mxc_iomux_v3_setup_pad(&txfs);
+}
+
+static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
+{
+ struct pad_desc txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+ struct pad_desc txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
+ struct pad_desc txd_gpio = MX35_PAD_STXD4__GPIO2_28;
+ struct pad_desc txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD;
+ struct pad_desc reset_gpio = MX35_PAD_SD2_CMD__GPIO2_0;
+ int ret;
+
+ ret = gpio_request(AC97_GPIO_TXFS, "SSI");
+ if (ret)
+ goto err1;
+
+ ret = gpio_request(AC97_GPIO_TXD, "SSI");
+ if (ret)
+ goto err2;
+
+ ret = gpio_request(AC97_GPIO_RESET, "SSI");
+ if (ret)
+ goto err3;
+
+ mxc_iomux_v3_setup_pad(&txfs_gpio);
+ mxc_iomux_v3_setup_pad(&txd_gpio);
+ mxc_iomux_v3_setup_pad(&reset_gpio);
+
+ gpio_direction_output(AC97_GPIO_TXFS, 0);
+ gpio_direction_output(AC97_GPIO_TXD, 0);
+
+ /* cold reset */
+ gpio_direction_output(AC97_GPIO_RESET, 0);
+ udelay(10);
+ gpio_direction_output(AC97_GPIO_RESET, 1);
+
+ mxc_iomux_v3_setup_pad(&txd);
+ mxc_iomux_v3_setup_pad(&txfs);
+
+ gpio_free(AC97_GPIO_RESET);
+err3:
+ gpio_free(AC97_GPIO_TXD);
+err2:
+ gpio_free(AC97_GPIO_TXFS);
+err1:
+ if (ret)
+ printk("%s failed with %d\n", __func__, ret);
+ mdelay(1);
+}
+
+static struct imx_ssi_platform_data pcm043_ssi_pdata = {
+ .ac97_reset = pcm043_ac97_cold_reset,
+ .ac97_warm_reset = pcm043_ac97_warm_reset,
+ .flags = IMX_SSI_USE_AC97,
+};
+
+static struct mxc_nand_platform_data pcm037_nand_board_info = {
+ .width = 1,
+ .hw_ecc = 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 pcm043_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=", pcm043_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
+
+ mxc_audmux_v2_configure_port(3,
+ MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+ MXC_AUDMUX_V2_PTCR_TFSEL(0) |
+ MXC_AUDMUX_V2_PTCR_TFSDIR,
+ MXC_AUDMUX_V2_PDCR_RXDSEL(0));
+
+ mxc_audmux_v2_configure_port(0,
+ MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+ MXC_AUDMUX_V2_PTCR_TCSEL(3) |
+ MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
+ MXC_AUDMUX_V2_PDCR_RXDSEL(3));
+
+ 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);
+ mxc_register_device(&imx_ssi_device0, &pcm043_ssi_pdata);
+
+ mxc_register_device(&mxc_uart_device1, &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);
+#endif
+
+ mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+ mxc_register_device(&mx3_fb, &mx3fb_pdata);
+
+#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);
+
+}
+
+static void __init pcm043_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+struct sys_timer pcm043_timer = {
+ .init = pcm043_timer_init,
+};
+
+MACHINE_START(PCM043, "Phytec Phycore pcm043")
+ /* Maintainer: Pengutronix */
+ .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 = &pcm043_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx3/mach-qong.c b/arch/arm/mach-mx3/mach-qong.c
new file mode 100644
index 00000000000..e5b5b8323a1
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-qong.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 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 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/kernel.h>
+#include <linux/memory.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#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.h"
+
+/* FPGA defines */
+#define QONG_FPGA_VERSION(major, minor, rev) \
+ (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF))
+
+#define QONG_FPGA_BASEADDR MX31_CS1_BASE_ADDR
+#define QONG_FPGA_PERIPH_SIZE (1 << 24)
+
+#define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR
+#define QONG_FPGA_CTRL_SIZE 0x10
+/* FPGA control registers */
+#define QONG_FPGA_CTRL_VERSION 0x00
+
+#define QONG_DNET_ID 1
+#define QONG_DNET_BASEADDR \
+ (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE)
+#define QONG_DNET_SIZE 0x00001000
+
+#define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1)
+
+/*
+ * This file contains the board-specific initialization routines.
+ */
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int uart_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1
+};
+
+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);
+}
+
+static struct resource dnet_resources[] = {
+ {
+ .name = "dnet-memory",
+ .start = QONG_DNET_BASEADDR,
+ .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = QONG_FPGA_IRQ,
+ .end = QONG_FPGA_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dnet_device = {
+ .name = "dnet",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dnet_resources),
+ .resource = dnet_resources,
+};
+
+static int __init qong_init_dnet(void)
+{
+ int ret;
+
+ ret = platform_device_register(&dnet_device);
+ return ret;
+}
+
+/* MTD NOR flash */
+
+static struct physmap_flash_data qong_flash_data = {
+ .width = 2,
+};
+
+static struct resource qong_flash_resource = {
+ .start = MX31_CS0_BASE_ADDR,
+ .end = MX31_CS0_BASE_ADDR + QONG_NOR_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &qong_flash_data,
+ },
+ .resource = &qong_flash_resource,
+ .num_resources = 1,
+};
+
+static void qong_init_nor_mtd(void)
+{
+ (void)platform_device_register(&qong_nor_mtd_device);
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
+ else
+ writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int qong_nand_device_ready(struct mtd_info *mtd)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+}
+
+static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ if (chip >= 0)
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+ else
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
+}
+
+static struct platform_nand_data qong_nand_data = {
+ .chip = {
+ .chip_delay = 20,
+ .options = 0,
+ },
+ .ctrl = {
+ .cmd_ctrl = qong_nand_cmd_ctrl,
+ .dev_ready = qong_nand_device_ready,
+ .select_chip = qong_nand_select_chip,
+ }
+};
+
+static struct resource qong_nand_resource = {
+ .start = MX31_CS3_BASE_ADDR,
+ .end = MX31_CS3_BASE_ADDR + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nand_device = {
+ .name = "gen_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &qong_nand_data,
+ },
+ .num_resources = 1,
+ .resource = &qong_nand_resource,
+};
+
+static void __init qong_init_nand_mtd(void)
+{
+ /* init CS */
+ mx31_setup_weimcs(3, 0x00004f00, 0x20013b31, 0x00020800);
+ mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true);
+
+ /* enable pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable"))
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+
+ /* ready/busy pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy"))
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+
+ /* write protect pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp"))
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B));
+
+ platform_device_register(&qong_nand_device);
+}
+
+static void __init qong_init_fpga(void)
+{
+ void __iomem *regs;
+ u32 fpga_ver;
+
+ regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE);
+ if (!regs) {
+ printk(KERN_ERR "%s: failed to map registers, aborting.\n",
+ __func__);
+ return;
+ }
+
+ fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION);
+ iounmap(regs);
+ printk(KERN_INFO "Qong FPGA version %d.%d.%d\n",
+ (fpga_ver & 0xF000) >> 12,
+ (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF);
+ if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) {
+ printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based "
+ "devices won't be registered!\n");
+ return;
+ }
+
+ /* register FPGA-based devices */
+ qong_init_nand_mtd();
+ qong_init_dnet();
+}
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_init_imx_uart();
+ qong_init_nor_mtd();
+ qong_init_fpga();
+}
+
+static void __init qong_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer qong_timer = {
+ .init = qong_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_QONG data structure.
+ */
+
+MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
+ /* Maintainer: DENX Software Engineering GmbH */
+ .phys_io = MX31_AIPS1_BASE_ADDR,
+ .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_irq = mx31_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &qong_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
deleted file mode 100644
index 938c549767d..00000000000
--- a/arch/arm/mach-mx3/mx31ads.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright (C) 2002 Shane Nay (shane@minirl.com)
- * 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 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/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/irq.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/board-mx31ads.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-
-#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
-#include <linux/mfd/wm8350/audio.h>
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/pmic.h>
-#endif
-
-#include "devices.h"
-
-/*!
- * @file mx31ads.c
- *
- * @brief This file contains the board-specific initialization routines.
- *
- * @ingroup System
- */
-
-#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
-/*!
- * The serial port definition structure.
- */
-static struct plat_serial8250_port serial_platform_data[] = {
- {
- .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
- .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTA),
- .irq = EXPIO_INT_XUART_INTA,
- .uartclk = 14745600,
- .regshift = 0,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
- }, {
- .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
- .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTB),
- .irq = EXPIO_INT_XUART_INTB,
- .uartclk = 14745600,
- .regshift = 0,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
- },
- {},
-};
-
-static struct platform_device serial_device = {
- .name = "serial8250",
- .id = 0,
- .dev = {
- .platform_data = serial_platform_data,
- },
-};
-
-static int __init mxc_init_extuart(void)
-{
- return platform_device_register(&serial_device);
-}
-#else
-static inline int mxc_init_extuart(void)
-{
- return 0;
-}
-#endif
-
-#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static unsigned int uart_pins[] = {
- MX31_PIN_CTS1__CTS1,
- MX31_PIN_RTS1__RTS1,
- MX31_PIN_TXD1__TXD1,
- MX31_PIN_RXD1__RXD1
-};
-
-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);
-}
-#else /* !SERIAL_IMX */
-static inline void mxc_init_imx_uart(void)
-{
-}
-#endif /* !SERIAL_IMX */
-
-static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
-{
- u32 imr_val;
- u32 int_valid;
- u32 expio_irq;
-
- imr_val = __raw_readw(PBC_INTMASK_SET_REG);
- int_valid = __raw_readw(PBC_INTSTATUS_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(u32 irq)
-{
- u32 expio = MXC_IRQ_TO_EXPIO(irq);
- /* mask the interrupt */
- __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
- __raw_readw(PBC_INTMASK_CLEAR_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(u32 irq)
-{
- u32 expio = MXC_IRQ_TO_EXPIO(irq);
- /* clear the interrupt status */
- __raw_writew(1 << expio, PBC_INTSTATUS_REG);
-}
-
-/*
- * 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(u32 irq)
-{
- u32 expio = MXC_IRQ_TO_EXPIO(irq);
- /* unmask the interrupt */
- __raw_writew(1 << expio, PBC_INTMASK_SET_REG);
-}
-
-static struct irq_chip expio_irq_chip = {
- .name = "EXPIO(CPLD)",
- .ack = expio_ack_irq,
- .mask = expio_mask_irq,
- .unmask = expio_unmask_irq,
-};
-
-static void __init mx31ads_init_expio(void)
-{
- int i;
-
- printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
-
- /*
- * Configure INT line as GPIO input
- */
- mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio");
-
- /* disable the interrupt and clear the status */
- __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
- __raw_writew(0xFFFF, PBC_INTSTATUS_REG);
- for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
- i++) {
- set_irq_chip(i, &expio_irq_chip);
- set_irq_handler(i, handle_level_irq);
- set_irq_flags(i, IRQF_VALID);
- }
- set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
- set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
-}
-
-#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
-/* This section defines setup for the Wolfson Microelectronics
- * 1133-EV1 PMU/audio board. When other PMU boards are supported the
- * regulator definitions may be shared with them, but for now they can
- * only be used with this board so would generate warnings about
- * unused statics and some of the configuration is specific to this
- * module.
- */
-
-/* CPU */
-static struct regulator_consumer_supply sw1a_consumers[] = {
- {
- .supply = "cpu_vcc",
- }
-};
-
-static struct regulator_init_data sw1a_data = {
- .constraints = {
- .name = "SW1A",
- .min_uV = 1275000,
- .max_uV = 1600000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_MODE,
- .valid_modes_mask = REGULATOR_MODE_NORMAL |
- REGULATOR_MODE_FAST,
- .state_mem = {
- .uV = 1400000,
- .mode = REGULATOR_MODE_NORMAL,
- .enabled = 1,
- },
- .initial_state = PM_SUSPEND_MEM,
- .always_on = 1,
- .boot_on = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(sw1a_consumers),
- .consumer_supplies = sw1a_consumers,
-};
-
-/* System IO - High */
-static struct regulator_init_data viohi_data = {
- .constraints = {
- .name = "VIOHO",
- .min_uV = 2800000,
- .max_uV = 2800000,
- .state_mem = {
- .uV = 2800000,
- .mode = REGULATOR_MODE_NORMAL,
- .enabled = 1,
- },
- .initial_state = PM_SUSPEND_MEM,
- .always_on = 1,
- .boot_on = 1,
- },
-};
-
-/* System IO - Low */
-static struct regulator_init_data violo_data = {
- .constraints = {
- .name = "VIOLO",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .state_mem = {
- .uV = 1800000,
- .mode = REGULATOR_MODE_NORMAL,
- .enabled = 1,
- },
- .initial_state = PM_SUSPEND_MEM,
- .always_on = 1,
- .boot_on = 1,
- },
-};
-
-/* DDR RAM */
-static struct regulator_init_data sw2a_data = {
- .constraints = {
- .name = "SW2A",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .state_mem = {
- .uV = 1800000,
- .mode = REGULATOR_MODE_NORMAL,
- .enabled = 1,
- },
- .state_disk = {
- .mode = REGULATOR_MODE_NORMAL,
- .enabled = 0,
- },
- .always_on = 1,
- .boot_on = 1,
- .initial_state = PM_SUSPEND_MEM,
- },
-};
-
-static struct regulator_init_data ldo1_data = {
- .constraints = {
- .name = "VCAM/VMMC1/VMMC2",
- .min_uV = 2800000,
- .max_uV = 2800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- .apply_uV = 1,
- },
-};
-
-static struct regulator_consumer_supply ldo2_consumers[] = {
- {
- .supply = "AVDD",
- },
- {
- .supply = "HPVDD",
- },
-};
-
-/* CODEC and SIM */
-static struct regulator_init_data ldo2_data = {
- .constraints = {
- .name = "VESIM/VSIM/AVDD",
- .min_uV = 3300000,
- .max_uV = 3300000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_STATUS,
- .apply_uV = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
- .consumer_supplies = ldo2_consumers,
-};
-
-/* General */
-static struct regulator_init_data vdig_data = {
- .constraints = {
- .name = "VDIG",
- .min_uV = 1500000,
- .max_uV = 1500000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .apply_uV = 1,
- .always_on = 1,
- .boot_on = 1,
- },
-};
-
-/* Tranceivers */
-static struct regulator_init_data ldo4_data = {
- .constraints = {
- .name = "VRF1/CVDD_2.775",
- .min_uV = 2500000,
- .max_uV = 2500000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .apply_uV = 1,
- .always_on = 1,
- .boot_on = 1,
- },
-};
-
-static struct wm8350_led_platform_data wm8350_led_data = {
- .name = "wm8350:white",
- .default_trigger = "heartbeat",
- .max_uA = 27899,
-};
-
-static struct wm8350_audio_platform_data imx32ads_wm8350_setup = {
- .vmid_discharge_msecs = 1000,
- .drain_msecs = 30,
- .cap_discharge_msecs = 700,
- .vmid_charge_msecs = 700,
- .vmid_s_curve = WM8350_S_CURVE_SLOW,
- .dis_out4 = WM8350_DISCHARGE_SLOW,
- .dis_out3 = WM8350_DISCHARGE_SLOW,
- .dis_out2 = WM8350_DISCHARGE_SLOW,
- .dis_out1 = WM8350_DISCHARGE_SLOW,
- .vroi_out4 = WM8350_TIE_OFF_500R,
- .vroi_out3 = WM8350_TIE_OFF_500R,
- .vroi_out2 = WM8350_TIE_OFF_500R,
- .vroi_out1 = WM8350_TIE_OFF_500R,
- .vroi_enable = 0,
- .codec_current_on = WM8350_CODEC_ISEL_1_0,
- .codec_current_standby = WM8350_CODEC_ISEL_0_5,
- .codec_current_charge = WM8350_CODEC_ISEL_1_5,
-};
-
-static int mx31_wm8350_init(struct wm8350 *wm8350)
-{
- int i;
-
- wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN,
- WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW,
- WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
- WM8350_GPIO_DEBOUNCE_ON);
-
- wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN,
- WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH,
- WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
- WM8350_GPIO_DEBOUNCE_ON);
-
- wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
- WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
- WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
- WM8350_GPIO_DEBOUNCE_OFF);
-
- wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN,
- WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH,
- WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
- WM8350_GPIO_DEBOUNCE_OFF);
-
- wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT,
- WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH,
- WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
- WM8350_GPIO_DEBOUNCE_OFF);
-
- wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT,
- WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
- WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
- WM8350_GPIO_DEBOUNCE_OFF);
-
- wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT,
- WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
- WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
- WM8350_GPIO_DEBOUNCE_OFF);
-
- /* Fix up for our own supplies. */
- for (i = 0; i < ARRAY_SIZE(ldo2_consumers); i++)
- ldo2_consumers[i].dev = wm8350->dev;
-
- wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data);
- wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data);
- wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data);
- wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data);
- wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data);
- wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data);
- wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data);
- wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data);
-
- /* LEDs */
- wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1,
- WM8350_DC5_ERRACT_SHUTDOWN_CONV);
- wm8350_isink_set_flash(wm8350, WM8350_ISINK_A,
- WM8350_ISINK_FLASH_DISABLE,
- WM8350_ISINK_FLASH_TRIG_BIT,
- WM8350_ISINK_FLASH_DUR_32MS,
- WM8350_ISINK_FLASH_ON_INSTANT,
- WM8350_ISINK_FLASH_OFF_INSTANT,
- WM8350_ISINK_FLASH_MODE_EN);
- wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5,
- WM8350_ISINK_MODE_BOOST,
- WM8350_ISINK_ILIM_NORMAL,
- WM8350_DC5_RMP_20V,
- WM8350_DC5_FBSRC_ISINKA);
- wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A,
- &wm8350_led_data);
-
- wm8350->codec.platform_data = &imx32ads_wm8350_setup;
-
- regulator_has_full_constraints();
-
- return 0;
-}
-
-static struct wm8350_platform_data __initdata mx31_wm8350_pdata = {
- .init = mx31_wm8350_init,
- .irq_base = MXC_BOARD_IRQ_START + MXC_MAX_EXP_IO_LINES,
-};
-#endif
-
-#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE)
-static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = {
-#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
- {
- I2C_BOARD_INFO("wm8350", 0x1a),
- .platform_data = &mx31_wm8350_pdata,
- .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
- },
-#endif
-};
-
-static void mxc_init_i2c(void)
-{
- i2c_register_board_info(1, mx31ads_i2c1_devices,
- ARRAY_SIZE(mx31ads_i2c1_devices));
-
- 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);
-}
-#else
-static void mxc_init_i2c(void)
-{
-}
-#endif
-
-/*!
- * This structure defines static mappings for the i.MX31ADS board.
- */
-static struct map_desc mx31ads_io_desc[] __initdata = {
- {
- .virtual = CS4_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(CS4_BASE_ADDR),
- .length = CS4_SIZE / 2,
- .type = MT_DEVICE
- },
-};
-
-/*!
- * Set up static virtual mappings.
- */
-static void __init mx31ads_map_io(void)
-{
- mx31_map_io();
- iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
-}
-
-static void __init mx31ads_init_irq(void)
-{
- mx31_init_irq();
- mx31ads_init_expio();
-}
-
-/*!
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
- mxc_init_extuart();
- mxc_init_imx_uart();
- mxc_init_i2c();
-}
-
-static void __init mx31ads_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-static struct sys_timer mx31ads_timer = {
- .init = mx31ads_timer_init,
-};
-
-/*
- * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31ADS data structure.
- */
-MACHINE_START(MX31ADS, "Freescale MX31ADS")
- /* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31ads_map_io,
- .init_irq = mx31ads_init_irq,
- .init_machine = mxc_board_init,
- .timer = &mx31ads_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31lilly.c b/arch/arm/mach-mx3/mx31lilly.c
deleted file mode 100644
index 9ce029f554b..00000000000
--- a/arch/arm/mach-mx3/mx31lilly.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * LILLY-1131 module support
- *
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- * based on code for other MX31 boards,
- *
- * Copyright 2005-2007 Freescale Semiconductor
- * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
- *
- * This program is free software; 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/clk.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/smsc911x.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/spi.h>
-#include <linux/mfd/mc13783.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31lilly.h>
-#include <mach/spi.h>
-
-#include "devices.h"
-
-/*
- * This file contains module-specific initialization routines for LILLY-1131.
- * Initialization of peripherals found on the baseboard is implemented in the
- * appropriate baseboard support code.
- */
-
-/* SMSC ethernet support */
-
-static struct resource smsc91x_resources[] = {
- {
- .start = CS4_BASE_ADDR,
- .end = CS4_BASE_ADDR + 0xffff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
- .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
- .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
- }
-};
-
-static struct smsc911x_platform_config smsc911x_config = {
- .phy_interface = PHY_INTERFACE_MODE_MII,
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
- .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
- .flags = SMSC911X_USE_32BIT |
- SMSC911X_SAVE_MAC_ADDRESS |
- SMSC911X_FORCE_INTERNAL_PHY,
-};
-
-static struct platform_device smsc91x_device = {
- .name = "smsc911x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smsc91x_resources),
- .resource = smsc91x_resources,
- .dev = {
- .platform_data = &smsc911x_config,
- }
-};
-
-/* NOR flash */
-static struct physmap_flash_data nor_flash_data = {
- .width = 2,
-};
-
-static struct resource nor_flash_resource = {
- .start = 0xa0000000,
- .end = 0xa1ffffff,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device physmap_flash_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &nor_flash_data,
- },
- .resource = &nor_flash_resource,
- .num_resources = 1,
-};
-
-static struct platform_device *devices[] __initdata = {
- &smsc91x_device,
- &physmap_flash_device,
-};
-
-/* SPI */
-
-static int spi_internal_chipselect[] = {
- MXC_SPI_CS(0),
- MXC_SPI_CS(1),
- MXC_SPI_CS(2),
-};
-
-static struct spi_imx_master spi0_pdata = {
- .chipselect = spi_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static struct spi_imx_master spi1_pdata = {
- .chipselect = spi_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static struct mc13783_platform_data mc13783_pdata __initdata = {
- .flags = MC13783_USE_RTC | MC13783_USE_TOUCHSCREEN,
-};
-
-static struct spi_board_info mc13783_dev __initdata = {
- .modalias = "mc13783",
- .max_speed_hz = 1000000,
- .bus_num = 1,
- .chip_select = 0,
- .platform_data = &mc13783_pdata,
-};
-
-static int mx31lilly_baseboard;
-core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
-
-static void __init mx31lilly_board_init(void)
-{
- switch (mx31lilly_baseboard) {
- case MX31LILLY_NOBOARD:
- break;
- case MX31LILLY_DB:
- mx31lilly_db_init();
- break;
- default:
- printk(KERN_ERR "Illegal mx31lilly_baseboard type %d\n",
- mx31lilly_baseboard);
- }
-
- mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS");
-
- /* SPI */
- mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2");
-
- mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY");
- mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0");
- 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);
- spi_register_board_info(&mc13783_dev, 1);
-
- platform_add_devices(devices, ARRAY_SIZE(devices));
-}
-
-static void __init mx31lilly_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-static struct sys_timer mx31lilly_timer = {
- .init = mx31lilly_timer_init,
-};
-
-MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31_map_io,
- .init_irq = mx31_init_irq,
- .init_machine = mx31lilly_board_init,
- .timer = &mx31lilly_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c
index 694611d6b05..093c595ca58 100644
--- a/arch/arm/mach-mx3/mx31lite-db.c
+++ b/arch/arm/mach-mx3/mx31lite-db.c
@@ -28,7 +28,6 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/gpio.h>
-#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
@@ -67,6 +66,13 @@ static unsigned int litekit_db_board_pins[] __initdata = {
MX31_PIN_CSPI1_SS0__SS0,
MX31_PIN_CSPI1_SS1__SS1,
MX31_PIN_CSPI1_SS2__SS2,
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
};
/* UART */
@@ -79,11 +85,11 @@ static struct imxuart_platform_data uart_pdata __initdata = {
static int gpio_det, gpio_wp;
#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
- PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+ PAD_CTL_ODE_CMOS)
static int mxc_mmc1_get_ro(struct device *dev)
{
- return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_6));
}
static int mxc_mmc1_init(struct device *dev,
@@ -94,12 +100,17 @@ static int mxc_mmc1_init(struct device *dev,
gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1);
gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6);
- mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA1,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA2,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA3,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_CMD,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG);
ret = gpio_request(gpio_det, "MMC detect");
if (ret)
@@ -113,7 +124,7 @@ static int mxc_mmc1_init(struct device *dev,
gpio_direction_input(gpio_wp);
ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq,
- IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"MMC detect", data);
if (ret)
goto exit_free_wp;
@@ -133,7 +144,7 @@ static void mxc_mmc1_exit(struct device *dev, void *data)
{
gpio_free(gpio_det);
gpio_free(gpio_wp);
- free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data);
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), data);
}
static struct imxmmc_platform_data mmc_pdata = {
@@ -194,5 +205,6 @@ void __init mx31lite_db_init(void)
mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
mxc_register_device(&mxc_spi_device0, &spi0_pdata);
platform_device_register(&litekit_led_device);
+ mxc_register_device(&imx_wdt_device0, NULL);
}
diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c
deleted file mode 100644
index 789b20d1730..00000000000
--- a/arch/arm/mach-mx3/mx31lite.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright (C) 2002 Shane Nay (shane@minirl.com)
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2009 Daniel Mack <daniel@caiaq.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/memory.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/smsc911x.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/spi/spi.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/ulpi.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-#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.h"
-
-/*
- * This file contains the module-specific initialization routines.
- */
-
-static unsigned int mx31lite_pins[] = {
- /* LAN9117 IRQ pin */
- IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO),
- /* SPI 1 */
- MX31_PIN_CSPI2_SCLK__SCLK,
- MX31_PIN_CSPI2_MOSI__MOSI,
- MX31_PIN_CSPI2_MISO__MISO,
- MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
- MX31_PIN_CSPI2_SS0__SS0,
- MX31_PIN_CSPI2_SS1__SS1,
- MX31_PIN_CSPI2_SS2__SS2,
-};
-
-static struct mxc_nand_platform_data mx31lite_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-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,
-};
-
-static struct resource smsc911x_resources[] = {
- {
- .start = CS4_BASE_ADDR,
- .end = CS4_BASE_ADDR + 0x100,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IOMUX_TO_IRQ(MX31_PIN_SFS6),
- .end = IOMUX_TO_IRQ(MX31_PIN_SFS6),
- .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,
- },
-};
-
-/*
- * SPI
- *
- * The MC13783 is the only hard-wired SPI device on the module.
- */
-
-static int spi_internal_chipselect[] = {
- MXC_SPI_CS(0),
-};
-
-static struct spi_imx_master spi1_pdata = {
- .chipselect = spi_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static struct mc13783_platform_data mc13783_pdata __initdata = {
- .flags = MC13783_USE_RTC |
- MC13783_USE_REGULATOR,
-};
-
-static struct spi_board_info mc13783_spi_dev __initdata = {
- .modalias = "mc13783",
- .max_speed_hz = 1000000,
- .bus_num = 1,
- .chip_select = 0,
- .platform_data = &mc13783_pdata,
- .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
-};
-
-/*
- * USB
- */
-
-#if defined(CONFIG_USB_ULPI)
-#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
- PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
-
-static int usbh2_init(struct platform_device *pdev)
-{
- int pins[] = {
- MX31_PIN_USBH2_DATA0__USBH2_DATA0,
- MX31_PIN_USBH2_DATA1__USBH2_DATA1,
- MX31_PIN_USBH2_CLK__USBH2_CLK,
- MX31_PIN_USBH2_DIR__USBH2_DIR,
- MX31_PIN_USBH2_NXT__USBH2_NXT,
- MX31_PIN_USBH2_STP__USBH2_STP,
- };
-
- mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2");
-
- mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
-
- mxc_iomux_set_gpr(MUX_PGP_UH2, true);
-
- /* chip select */
- mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO),
- "USBH2_CS");
- gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS");
- gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0);
-
- return 0;
-}
-
-static struct mxc_usbh_platform_data usbh2_pdata = {
- .init = usbh2_init,
- .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
- .flags = MXC_EHCI_POWER_PINS_ENABLED,
-};
-#endif
-
-/*
- * NOR flash
- */
-
-static struct physmap_flash_data nor_flash_data = {
- .width = 2,
-};
-
-static struct resource nor_flash_resource = {
- .start = 0xa0000000,
- .end = 0xa1ffffff,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device physmap_flash_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &nor_flash_data,
- },
- .resource = &nor_flash_resource,
- .num_resources = 1,
-};
-
-
-
-/*
- * This structure defines the MX31 memory map.
- */
-static struct map_desc mx31lite_io_desc[] __initdata = {
- {
- .virtual = CS4_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(CS4_BASE_ADDR),
- .length = CS4_SIZE,
- .type = MT_DEVICE
- }
-};
-
-/*
- * Set up static virtual mappings.
- */
-void __init mx31lite_map_io(void)
-{
- mx31_map_io();
- iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc));
-}
-
-static int mx31lite_baseboard;
-core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444);
-
-static void __init mxc_board_init(void)
-{
- int ret;
-
- switch (mx31lite_baseboard) {
- case MX31LITE_NOBOARD:
- break;
- case MX31LITE_DB:
- mx31lite_db_init();
- break;
- default:
- printk(KERN_ERR "Illegal mx31lite_baseboard type %d\n",
- mx31lite_baseboard);
- }
-
- mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins),
- "mx31lite");
-
- /* NOR and NAND flash */
- platform_device_register(&physmap_flash_device);
- mxc_register_device(&mxc_nand_device, &mx31lite_nand_board_info);
-
- mxc_register_device(&mxc_spi_device1, &spi1_pdata);
- spi_register_board_info(&mc13783_spi_dev, 1);
-
-#if defined(CONFIG_USB_ULPI)
- /* USB */
- 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
-
- /* SMSC9117 IRQ pin */
- ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq");
- if (ret)
- pr_warning("could not get LAN irq gpio\n");
- else {
- gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6));
- platform_device_register(&smsc911x_device);
- }
-}
-
-static void __init mx31lite_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-struct sys_timer mx31lite_timer = {
- .init = mx31lite_timer_init,
-};
-
-MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")
- /* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31lite_map_io,
- .init_irq = mx31_init_irq,
- .init_machine = mxc_board_init,
- .timer = &mx31lite_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c
index 438428eaf76..11b906ce7ea 100644
--- a/arch/arm/mach-mx3/mx31moboard-devboard.c
+++ b/arch/arm/mach-mx3/mx31moboard-devboard.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/usb/otg.h>
@@ -49,6 +50,9 @@ static unsigned int devboard_pins[] = {
MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
+ /* SEL */
+ MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+ MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
};
static struct imxuart_platform_data uart_pdata = {
@@ -108,6 +112,33 @@ static struct imxmmc_platform_data sdhc2_pdata = {
.exit = devboard_sdhc2_exit,
};
+#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void devboard_init_sel_gpios(void)
+{
+ if (!gpio_request(SEL0, "sel0")) {
+ gpio_direction_input(SEL0);
+ gpio_export(SEL0, true);
+ }
+
+ if (!gpio_request(SEL1, "sel1")) {
+ gpio_direction_input(SEL1);
+ gpio_export(SEL1, true);
+ }
+
+ if (!gpio_request(SEL2, "sel2")) {
+ gpio_direction_input(SEL2);
+ gpio_export(SEL2, true);
+ }
+
+ if (!gpio_request(SEL3, "sel3")) {
+ gpio_direction_input(SEL3);
+ gpio_export(SEL3, true);
+ }
+}
#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
@@ -196,5 +227,7 @@ void __init mx31moboard_devboard_init(void)
mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
+ devboard_init_sel_gpios();
+
devboard_usbh1_init();
}
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c
index 1f44b9ccbb0..ffb105e14d8 100644
--- a/arch/arm/mach-mx3/mx31moboard-marxbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/types.h>
@@ -66,6 +67,9 @@ static unsigned int marxbot_pins[] = {
MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
+ /* SEL */
+ MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+ MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
};
#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
@@ -127,12 +131,12 @@ static struct imxmmc_platform_data sdhc2_pdata = {
static void dspics_resets_init(void)
{
if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
- gpio_direction_output(TRSLAT_RST_B, 1);
+ gpio_direction_output(TRSLAT_RST_B, 0);
gpio_export(TRSLAT_RST_B, false);
}
if (!gpio_request(DSPICS_RST_B, "dspics-rst")) {
- gpio_direction_output(DSPICS_RST_B, 1);
+ gpio_direction_output(DSPICS_RST_B, 0);
gpio_export(DSPICS_RST_B, false);
}
}
@@ -200,7 +204,7 @@ static int __init marxbot_cam_init(void)
int ret = gpio_request(CAM_CHOICE, "cam-choice");
if (ret)
return ret;
- gpio_direction_output(CAM_CHOICE, 1);
+ gpio_direction_output(CAM_CHOICE, 0);
ret = gpio_request(BASECAM_RST_B, "basecam-reset");
if (ret)
@@ -223,6 +227,34 @@ static int __init marxbot_cam_init(void)
return 0;
}
+#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void marxbot_init_sel_gpios(void)
+{
+ if (!gpio_request(SEL0, "sel0")) {
+ gpio_direction_input(SEL0);
+ gpio_export(SEL0, true);
+ }
+
+ if (!gpio_request(SEL1, "sel1")) {
+ gpio_direction_input(SEL1);
+ gpio_export(SEL1, true);
+ }
+
+ if (!gpio_request(SEL2, "sel2")) {
+ gpio_direction_input(SEL2);
+ gpio_export(SEL2, true);
+ }
+
+ if (!gpio_request(SEL3, "sel3")) {
+ gpio_direction_input(SEL3);
+ gpio_export(SEL3, true);
+ }
+}
+
#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
@@ -307,6 +339,8 @@ void __init mx31moboard_marxbot_init(void)
mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins),
"marxbot");
+ marxbot_init_sel_gpios();
+
dspics_resets_init();
mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c
new file mode 100644
index 00000000000..52a69fc8b14
--- /dev/null
+++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; 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/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#include <media/soc_camera.h>
+
+#include "devices.h"
+
+static unsigned int smartbot_pins[] = {
+ /* UART1 */
+ MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
+ /* CSI */
+ MX31_PIN_CSI_D4__CSI_D4, MX31_PIN_CSI_D5__CSI_D5,
+ MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7,
+ MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9,
+ MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11,
+ MX31_PIN_CSI_D12__CSI_D12, MX31_PIN_CSI_D13__CSI_D13,
+ MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15,
+ MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK,
+ MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+ MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
+ /* ENABLES */
+ MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+ MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+#define CAM_POWER IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
+#define CAM_RST_B IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
+
+static int smartbot_cam_power(struct device *dev, int on)
+{
+ gpio_set_value(CAM_POWER, !on);
+ return 0;
+}
+
+static int smartbot_cam_reset(struct device *dev)
+{
+ gpio_set_value(CAM_RST_B, 0);
+ udelay(100);
+ gpio_set_value(CAM_RST_B, 1);
+ return 0;
+}
+
+static struct i2c_board_info smartbot_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("mt9t031", 0x5d),
+ },
+};
+
+static struct soc_camera_link base_iclink = {
+ .bus_id = 0, /* Must match with the camera ID */
+ .power = smartbot_cam_power,
+ .reset = smartbot_cam_reset,
+ .board_info = &smartbot_i2c_devices[0],
+ .i2c_adapter_id = 0,
+ .module_name = "mt9t031",
+};
+
+static struct platform_device smartbot_camera[] = {
+ {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &base_iclink,
+ },
+ },
+};
+
+static struct platform_device *smartbot_cameras[] __initdata = {
+ &smartbot_camera[0],
+};
+
+static int __init smartbot_cam_init(void)
+{
+ int ret = gpio_request(CAM_RST_B, "cam-reset");
+ if (ret)
+ return ret;
+ gpio_direction_output(CAM_RST_B, 1);
+ ret = gpio_request(CAM_POWER, "cam-standby");
+ if (ret)
+ return ret;
+ gpio_direction_output(CAM_POWER, 0);
+
+ return 0;
+}
+
+#define POWER_EN IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define DSPIC_RST_B IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void smartbot_resets_init(void)
+{
+ if (!gpio_request(POWER_EN, "power-enable")) {
+ gpio_direction_output(POWER_EN, 0);
+ gpio_export(POWER_EN, false);
+ }
+
+ if (!gpio_request(DSPIC_RST_B, "dspic-rst")) {
+ gpio_direction_output(DSPIC_RST_B, 0);
+ gpio_export(DSPIC_RST_B, false);
+ }
+
+ if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
+ gpio_direction_output(TRSLAT_RST_B, 0);
+ gpio_export(TRSLAT_RST_B, false);
+ }
+
+ if (!gpio_request(SEL3, "sel3")) {
+ gpio_direction_input(SEL3);
+ gpio_export(SEL3, true);
+ }
+}
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_smartbot_init(void)
+{
+ printk(KERN_INFO "Initializing mx31smartbot peripherals\n");
+
+ mxc_iomux_setup_multiple_pins(smartbot_pins, ARRAY_SIZE(smartbot_pins),
+ "smartbot");
+
+ mxc_register_device(&mxc_uart_device1, &uart_pdata);
+
+ smartbot_resets_init();
+
+ smartbot_cam_init();
+ platform_add_devices(smartbot_cameras, ARRAY_SIZE(smartbot_cameras));
+}
diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c
deleted file mode 100644
index cfd605d078e..00000000000
--- a/arch/arm/mach-mx3/mx31moboard.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Copyright (C) 2008 Valentin Longchamp, EPFL Mobots group
- *
- * This program is free software; 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/dma-mapping.h>
-#include <linux/fsl_devices.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/leds.h>
-#include <linux/memory.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/partitions.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/spi/spi.h>
-#include <linux/types.h>
-
-#include <linux/usb/otg.h>
-#include <linux/usb/ulpi.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#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.h"
-
-static unsigned int moboard_pins[] = {
- /* UART0 */
- MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
- MX31_PIN_CTS1__GPIO2_7,
- /* UART4 */
- MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
- MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
- /* I2C0 */
- MX31_PIN_I2C_DAT__I2C1_SDA, MX31_PIN_I2C_CLK__I2C1_SCL,
- /* I2C1 */
- MX31_PIN_DCD_DTE1__I2C2_SDA, MX31_PIN_RI_DTE1__I2C2_SCL,
- /* SDHC1 */
- MX31_PIN_SD1_DATA3__SD1_DATA3, MX31_PIN_SD1_DATA2__SD1_DATA2,
- MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0,
- MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD,
- MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27,
- /* USB reset */
- MX31_PIN_GPIO1_0__GPIO1_0,
- /* USB OTG */
- MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
- MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
- MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
- MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
- MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
- MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
- MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
- MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
- MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
- MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
- MX31_PIN_USB_OC__GPIO1_30,
- /* USB H2 */
- MX31_PIN_USBH2_DATA0__USBH2_DATA0,
- MX31_PIN_USBH2_DATA1__USBH2_DATA1,
- MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3,
- MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5,
- MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7,
- MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR,
- MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP,
- MX31_PIN_SCK6__GPIO1_25,
- /* LEDs */
- MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
- MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
- /* SEL */
- MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
- MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
- /* SPI1 */
- MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO,
- MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
- MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2,
- /* Atlas IRQ */
- MX31_PIN_GPIO1_3__GPIO1_3,
- /* SPI2 */
- MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO,
- MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY,
- MX31_PIN_CSPI2_SS1__CSPI3_SS1,
-};
-
-static struct physmap_flash_data mx31moboard_flash_data = {
- .width = 2,
-};
-
-static struct resource mx31moboard_flash_resource = {
- .start = 0xa0000000,
- .end = 0xa1ffffff,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device mx31moboard_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &mx31moboard_flash_data,
- },
- .resource = &mx31moboard_flash_resource,
- .num_resources = 1,
-};
-
-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;
-}
-
-static struct imxuart_platform_data uart0_pdata = {
- .init = moboard_uart0_init,
-};
-
-static struct imxuart_platform_data uart4_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct imxi2c_platform_data moboard_i2c0_pdata = {
- .bitrate = 400000,
-};
-
-static struct imxi2c_platform_data moboard_i2c1_pdata = {
- .bitrate = 100000,
-};
-
-static int moboard_spi1_cs[] = {
- MXC_SPI_CS(0),
- MXC_SPI_CS(2),
-};
-
-static struct spi_imx_master moboard_spi1_master = {
- .chipselect = moboard_spi1_cs,
- .num_chipselect = ARRAY_SIZE(moboard_spi1_cs),
-};
-
-static struct regulator_consumer_supply sdhc_consumers[] = {
- {
- .dev = &mxcsdhc_device0.dev,
- .supply = "sdhc0_vcc",
- },
- {
- .dev = &mxcsdhc_device1.dev,
- .supply = "sdhc1_vcc",
- },
-};
-
-static struct regulator_init_data sdhc_vreg_data = {
- .constraints = {
- .min_uV = 2700000,
- .max_uV = 3000000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
- .valid_modes_mask = REGULATOR_MODE_NORMAL |
- REGULATOR_MODE_FAST,
- .always_on = 0,
- .boot_on = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(sdhc_consumers),
- .consumer_supplies = sdhc_consumers,
-};
-
-static struct regulator_consumer_supply cam_consumers[] = {
- {
- .dev = &mx3_camera.dev,
- .supply = "cam_vcc",
- },
-};
-
-static struct regulator_init_data cam_vreg_data = {
- .constraints = {
- .min_uV = 2700000,
- .max_uV = 3000000,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
- REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
- .valid_modes_mask = REGULATOR_MODE_NORMAL |
- REGULATOR_MODE_FAST,
- .always_on = 0,
- .boot_on = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
- .consumer_supplies = cam_consumers,
-};
-
-static struct mc13783_regulator_init_data moboard_regulators[] = {
- {
- .id = MC13783_REGU_VMMC1,
- .init_data = &sdhc_vreg_data,
- },
- {
- .id = MC13783_REGU_VCAM,
- .init_data = &cam_vreg_data,
- },
-};
-
-static struct mc13783_platform_data moboard_pmic = {
- .regulators = moboard_regulators,
- .num_regulators = ARRAY_SIZE(moboard_regulators),
- .flags = MC13783_USE_REGULATOR | MC13783_USE_RTC |
- MC13783_USE_ADC,
-};
-
-static struct spi_board_info moboard_spi_board_info[] __initdata = {
- {
- .modalias = "mc13783",
- .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
- .max_speed_hz = 300000,
- .bus_num = 1,
- .chip_select = 0,
- .platform_data = &moboard_pmic,
- .mode = SPI_CS_HIGH,
- },
-};
-
-static int moboard_spi2_cs[] = {
- MXC_SPI_CS(1),
-};
-
-static struct spi_imx_master moboard_spi2_master = {
- .chipselect = moboard_spi2_cs,
- .num_chipselect = ARRAY_SIZE(moboard_spi2_cs),
-};
-
-#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
-#define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1)
-
-static int moboard_sdhc1_get_ro(struct device *dev)
-{
- return !gpio_get_value(SDHC1_WP);
-}
-
-static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
- void *data)
-{
- int ret;
-
- ret = gpio_request(SDHC1_CD, "sdhc-detect");
- if (ret)
- return ret;
-
- gpio_direction_input(SDHC1_CD);
-
- ret = gpio_request(SDHC1_WP, "sdhc-wp");
- if (ret)
- goto err_gpio_free;
- gpio_direction_input(SDHC1_WP);
-
- ret = request_irq(gpio_to_irq(SDHC1_CD), detect_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- "sdhc1-card-detect", data);
- if (ret)
- goto err_gpio_free_2;
-
- return 0;
-
-err_gpio_free_2:
- gpio_free(SDHC1_WP);
-err_gpio_free:
- gpio_free(SDHC1_CD);
-
- return ret;
-}
-
-static void moboard_sdhc1_exit(struct device *dev, void *data)
-{
- free_irq(gpio_to_irq(SDHC1_CD), data);
- gpio_free(SDHC1_WP);
- gpio_free(SDHC1_CD);
-}
-
-static struct imxmmc_platform_data sdhc1_pdata = {
- .get_ro = moboard_sdhc1_get_ro,
- .init = moboard_sdhc1_init,
- .exit = moboard_sdhc1_exit,
-};
-
-/*
- * this pin is dedicated for all mx31moboard systems, so we do it here
- */
-#define USB_RESET_B IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
-
-static void usb_xcvr_reset(void)
-{
- gpio_request(USB_RESET_B, "usb-reset");
- gpio_direction_output(USB_RESET_B, 0);
- mdelay(1);
- gpio_set_value(USB_RESET_B, 1);
-}
-
-#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
- PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
-
-#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
-
-static void moboard_usbotg_init(void)
-{
- 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);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
-
- gpio_request(OTG_EN_B, "usb-udc-en");
- gpio_direction_output(OTG_EN_B, 0);
-}
-
-static struct fsl_usb2_platform_data usb_pdata = {
- .operating_mode = FSL_USB2_DR_DEVICE,
- .phy_mode = FSL_USB2_PHY_ULPI,
-};
-
-#if defined(CONFIG_USB_ULPI)
-
-#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
-
-static int moboard_usbh2_hw_init(struct platform_device *pdev)
-{
- int ret = gpio_request(USBH2_EN_B, "usbh2-en");
- if (ret)
- return ret;
-
- mxc_iomux_set_gpr(MUX_PGP_UH2, true);
-
- mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
- mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
-
- gpio_direction_output(USBH2_EN_B, 0);
-
- return 0;
-}
-
-static int moboard_usbh2_hw_exit(struct platform_device *pdev)
-{
- gpio_free(USBH2_EN_B);
- return 0;
-}
-
-static struct mxc_usbh_platform_data usbh2_pdata = {
- .init = moboard_usbh2_hw_init,
- .exit = moboard_usbh2_hw_exit,
- .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
- .flags = MXC_EHCI_POWER_PINS_ENABLED,
-};
-
-static int __init moboard_usbh2_init(void)
-{
- usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
-
- return mxc_register_device(&mxc_usbh2, &usbh2_pdata);
-}
-#else
-static inline int moboard_usbh2_init(void) { return 0; }
-#endif
-
-
-static struct gpio_led mx31moboard_leds[] = {
- {
- .name = "coreboard-led-0:red:running",
- .default_trigger = "heartbeat",
- .gpio = IOMUX_TO_GPIO(MX31_PIN_SVEN0),
- }, {
- .name = "coreboard-led-1:red",
- .gpio = IOMUX_TO_GPIO(MX31_PIN_STX0),
- }, {
- .name = "coreboard-led-2:red",
- .gpio = IOMUX_TO_GPIO(MX31_PIN_SRX0),
- }, {
- .name = "coreboard-led-3:red",
- .gpio = IOMUX_TO_GPIO(MX31_PIN_SIMPD0),
- },
-};
-
-static struct gpio_led_platform_data mx31moboard_led_pdata = {
- .num_leds = ARRAY_SIZE(mx31moboard_leds),
- .leds = mx31moboard_leds,
-};
-
-static struct platform_device mx31moboard_leds_device = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &mx31moboard_led_pdata,
- },
-};
-
-#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
-#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
-#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
-#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
-
-static void mx31moboard_init_sel_gpios(void)
-{
- if (!gpio_request(SEL0, "sel0")) {
- gpio_direction_input(SEL0);
- gpio_export(SEL0, true);
- }
-
- if (!gpio_request(SEL1, "sel1")) {
- gpio_direction_input(SEL1);
- gpio_export(SEL1, true);
- }
-
- if (!gpio_request(SEL2, "sel2")) {
- gpio_direction_input(SEL2);
- gpio_export(SEL2, true);
- }
-
- if (!gpio_request(SEL3, "sel3")) {
- gpio_direction_input(SEL3);
- gpio_export(SEL3, true);
- }
-}
-
-static struct ipu_platform_data mx3_ipu_data = {
- .irq_base = MXC_IPU_IRQ_START,
-};
-
-static struct platform_device *devices[] __initdata = {
- &mx31moboard_flash,
- &mx31moboard_leds_device,
-};
-
-static struct mx3_camera_pdata camera_pdata = {
- .dma_dev = &mx3_ipu.dev,
- .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
- .mclk_10khz = 4800,
-};
-
-#define CAMERA_BUF_SIZE (4*1024*1024)
-
-static int __init mx31moboard_cam_alloc_dma(const size_t buf_size)
-{
- dma_addr_t dma_handle;
- void *buf;
- int dma;
-
- if (buf_size < 2 * 1024 * 1024)
- return -EINVAL;
-
- buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
- if (!buf) {
- pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
- return -ENOMEM;
- }
-
- memset(buf, 0, buf_size);
-
- dma = dma_declare_coherent_memory(&mx3_camera.dev,
- dma_handle, dma_handle, buf_size,
- DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
-
- /* The way we call dma_declare_coherent_memory only a malloc can fail */
- return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
-}
-
-static int mx31moboard_baseboard;
-core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
- mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
- "moboard");
-
- platform_add_devices(devices, ARRAY_SIZE(devices));
-
- mxc_register_device(&mxc_uart_device0, &uart0_pdata);
-
- mxc_register_device(&mxc_uart_device4, &uart4_pdata);
-
- mx31moboard_init_sel_gpios();
-
- mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
- mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
-
- mxc_register_device(&mxc_spi_device1, &moboard_spi1_master);
- mxc_register_device(&mxc_spi_device2, &moboard_spi2_master);
-
- gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq");
- gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
- spi_register_board_info(moboard_spi_board_info,
- ARRAY_SIZE(moboard_spi_board_info));
-
- mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
-
- mxc_register_device(&mx3_ipu, &mx3_ipu_data);
- if (!mx31moboard_cam_alloc_dma(CAMERA_BUF_SIZE))
- mxc_register_device(&mx3_camera, &camera_pdata);
-
- usb_xcvr_reset();
-
- moboard_usbotg_init();
- mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
- moboard_usbh2_init();
-
- switch (mx31moboard_baseboard) {
- case MX31NOBOARD:
- break;
- case MX31DEVBOARD:
- mx31moboard_devboard_init();
- break;
- case MX31MARXBOT:
- mx31moboard_marxbot_init();
- break;
- default:
- printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n",
- mx31moboard_baseboard);
- }
-}
-
-static void __init mx31moboard_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-struct sys_timer mx31moboard_timer = {
- .init = mx31moboard_timer_init,
-};
-
-MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
- /* Maintainer: Valentin Longchamp, EPFL Mobots group */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31_map_io,
- .init_irq = mx31_init_irq,
- .init_machine = mxc_board_init,
- .timer = &mx31moboard_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c
deleted file mode 100644
index 18715f1aa7e..00000000000
--- a/arch/arm/mach-mx3/mx31pdk.c
+++ /dev/null
@@ -1,266 +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 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/clk.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/smsc911x.h>
-#include <linux/platform_device.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/board-mx31pdk.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-#include "devices.h"
-
-/*!
- * @file mx31pdk.c
- *
- * @brief This file contains the board-specific initialization routines.
- *
- * @ingroup System
- */
-
-static int mx31pdk_pins[] = {
- /* UART1 */
- MX31_PIN_CTS1__CTS1,
- MX31_PIN_RTS1__RTS1,
- MX31_PIN_TXD1__TXD1,
- MX31_PIN_RXD1__RXD1,
- IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
-};
-
-static struct imxuart_platform_data uart_pdata = {
- .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 mx31pdk_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 mx31pdk_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.MX31PDK 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, mx31pdk_expio_irq_handler);
-
- return 0;
-}
-
-/*
- * This structure defines the MX31 memory map.
- */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
- {
- .virtual = CS5_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(CS5_BASE_ADDR),
- .length = CS5_SIZE,
- .type = MT_DEVICE,
- },
-};
-
-/*
- * Set up static virtual mappings.
- */
-static void __init mx31pdk_map_io(void)
-{
- mx31_map_io();
- iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
-}
-
-/*!
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
- mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins),
- "mx31pdk");
-
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
- if (!mx31pdk_init_expio())
- platform_device_register(&smsc911x_device);
-}
-
-static void __init mx31pdk_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-static struct sys_timer mx31pdk_timer = {
- .init = mx31pdk_timer_init,
-};
-
-/*
- * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31PDK data structure.
- */
-MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
- /* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31pdk_map_io,
- .init_irq = mx31_init_irq,
- .init_machine = mxc_board_init,
- .timer = &mx31pdk_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx3/mx35pdk.c b/arch/arm/mach-mx3/mx35pdk.c
deleted file mode 100644
index 0bbc65ea23c..00000000000
--- a/arch/arm/mach-mx3/mx35pdk.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * Author: Fabio Estevam <fabio.estevam@freescale.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/types.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/memory.h>
-#include <linux/gpio.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/hardware.h>
-#include <mach/common.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx35.h>
-
-#include "devices.h"
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *devices[] __initdata = {
- &mxc_fec_device,
-};
-
-static struct pad_desc mx35pdk_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,
- /* USBOTG */
- MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
- MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
-};
-
-/* OTG config */
-static struct fsl_usb2_platform_data usb_pdata = {
- .operating_mode = FSL_USB2_DR_DEVICE,
- .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
- mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
-
- platform_add_devices(devices, ARRAY_SIZE(devices));
-
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
- mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
-}
-
-static void __init mx35pdk_timer_init(void)
-{
- mx35_clocks_init();
-}
-
-struct sys_timer mx35pdk_timer = {
- .init = mx35pdk_timer_init,
-};
-
-MACHINE_START(MX35_3DS, "Freescale MX35PDK")
- /* Maintainer: Freescale Semiconductor, Inc */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx35_map_io,
- .init_irq = mx35_init_irq,
- .init_machine = mxc_board_init,
- .timer = &mx35pdk_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
deleted file mode 100644
index 5be396917c9..00000000000
--- a/arch/arm/mach-mx3/pcm037.c
+++ /dev/null
@@ -1,646 +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
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/plat-ram.h>
-#include <linux/memory.h>
-#include <linux/gpio.h>
-#include <linux/smsc911x.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-#include <linux/delay.h>
-#include <linux/spi/spi.h>
-#include <linux/irq.h>
-#include <linux/fsl_devices.h>
-#include <linux/can/platform/sja1000.h>
-
-#include <media/soc_camera.h>
-
-#include <asm/mach-types.h>
-#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 "devices.h"
-#include "pcm037.h"
-
-static enum pcm037_board_variant pcm037_instance = PCM037_PCM970;
-
-static int __init pcm037_variant_setup(char *str)
-{
- if (!strcmp("eet", str))
- pcm037_instance = PCM037_EET;
- else if (strcmp("pcm970", str))
- pr_warning("Unknown pcm037 baseboard variant %s\n", str);
-
- return 1;
-}
-
-/* Supported values: "pcm970" (default) and "eet" */
-__setup("pcm037_variant=", pcm037_variant_setup);
-
-enum pcm037_board_variant pcm037_variant(void)
-{
- return pcm037_instance;
-}
-
-/* UART1 with RTS/CTS handshake signals */
-static unsigned int pcm037_uart1_handshake_pins[] = {
- MX31_PIN_CTS1__CTS1,
- MX31_PIN_RTS1__RTS1,
- MX31_PIN_TXD1__TXD1,
- MX31_PIN_RXD1__RXD1,
-};
-
-/* UART1 without RTS/CTS handshake signals */
-static unsigned int pcm037_uart1_pins[] = {
- MX31_PIN_TXD1__TXD1,
- MX31_PIN_RXD1__RXD1,
-};
-
-static unsigned int pcm037_pins[] = {
- /* I2C */
- MX31_PIN_CSPI2_MOSI__SCL,
- MX31_PIN_CSPI2_MISO__SDA,
- MX31_PIN_CSPI2_SS2__I2C3_SDA,
- MX31_PIN_CSPI2_SCLK__I2C3_SCL,
- /* SDHC1 */
- MX31_PIN_SD1_DATA3__SD1_DATA3,
- MX31_PIN_SD1_DATA2__SD1_DATA2,
- MX31_PIN_SD1_DATA1__SD1_DATA1,
- MX31_PIN_SD1_DATA0__SD1_DATA0,
- MX31_PIN_SD1_CLK__SD1_CLK,
- MX31_PIN_SD1_CMD__SD1_CMD,
- IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO), /* card detect */
- IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), /* write protect */
- /* SPI1 */
- MX31_PIN_CSPI1_MOSI__MOSI,
- MX31_PIN_CSPI1_MISO__MISO,
- MX31_PIN_CSPI1_SCLK__SCLK,
- MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
- MX31_PIN_CSPI1_SS0__SS0,
- MX31_PIN_CSPI1_SS1__SS1,
- MX31_PIN_CSPI1_SS2__SS2,
- /* UART2 */
- MX31_PIN_TXD2__TXD2,
- MX31_PIN_RXD2__RXD2,
- MX31_PIN_CTS2__CTS2,
- MX31_PIN_RTS2__RTS2,
- /* UART3 */
- MX31_PIN_CSPI3_MOSI__RXD3,
- MX31_PIN_CSPI3_MISO__TXD3,
- MX31_PIN_CSPI3_SCLK__RTS3,
- MX31_PIN_CSPI3_SPI_RDY__CTS3,
- /* LAN9217 irq pin */
- IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
- /* Onewire */
- MX31_PIN_BATT_LINE__OWIRE,
- /* Framebuffer */
- MX31_PIN_LD0__LD0,
- MX31_PIN_LD1__LD1,
- MX31_PIN_LD2__LD2,
- MX31_PIN_LD3__LD3,
- MX31_PIN_LD4__LD4,
- MX31_PIN_LD5__LD5,
- MX31_PIN_LD6__LD6,
- MX31_PIN_LD7__LD7,
- MX31_PIN_LD8__LD8,
- MX31_PIN_LD9__LD9,
- MX31_PIN_LD10__LD10,
- MX31_PIN_LD11__LD11,
- MX31_PIN_LD12__LD12,
- MX31_PIN_LD13__LD13,
- MX31_PIN_LD14__LD14,
- MX31_PIN_LD15__LD15,
- MX31_PIN_LD16__LD16,
- MX31_PIN_LD17__LD17,
- MX31_PIN_VSYNC3__VSYNC3,
- MX31_PIN_HSYNC__HSYNC,
- MX31_PIN_FPSHIFT__FPSHIFT,
- MX31_PIN_DRDY0__DRDY0,
- MX31_PIN_D3_REV__D3_REV,
- MX31_PIN_CONTRAST__CONTRAST,
- MX31_PIN_D3_SPL__D3_SPL,
- MX31_PIN_D3_CLS__D3_CLS,
- MX31_PIN_LCS0__GPI03_23,
- /* CSI */
- IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO),
- MX31_PIN_CSI_D6__CSI_D6,
- MX31_PIN_CSI_D7__CSI_D7,
- MX31_PIN_CSI_D8__CSI_D8,
- MX31_PIN_CSI_D9__CSI_D9,
- MX31_PIN_CSI_D10__CSI_D10,
- MX31_PIN_CSI_D11__CSI_D11,
- MX31_PIN_CSI_D12__CSI_D12,
- MX31_PIN_CSI_D13__CSI_D13,
- MX31_PIN_CSI_D14__CSI_D14,
- MX31_PIN_CSI_D15__CSI_D15,
- MX31_PIN_CSI_HSYNC__CSI_HSYNC,
- MX31_PIN_CSI_MCLK__CSI_MCLK,
- MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
- MX31_PIN_CSI_VSYNC__CSI_VSYNC,
- /* GPIO */
- IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO),
-};
-
-static struct physmap_flash_data pcm037_flash_data = {
- .width = 2,
-};
-
-static struct resource pcm037_flash_resource = {
- .start = 0xa0000000,
- .end = 0xa1ffffff,
- .flags = IORESOURCE_MEM,
-};
-
-static int usbotg_pins[] = {
- MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
- MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
- MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
- MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
- MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
- MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
- MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
- MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
- MX31_PIN_USBOTG_CLK__USBOTG_CLK,
- MX31_PIN_USBOTG_DIR__USBOTG_DIR,
- MX31_PIN_USBOTG_NXT__USBOTG_NXT,
- MX31_PIN_USBOTG_STP__USBOTG_STP,
-};
-
-/* USB OTG HS port */
-static int __init gpio_usbotg_hs_activate(void)
-{
- int ret = mxc_iomux_setup_multiple_pins(usbotg_pins,
- ARRAY_SIZE(usbotg_pins), "usbotg");
-
- if (ret < 0) {
- printk(KERN_ERR "Cannot set up OTG pins\n");
- return ret;
- }
-
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
- mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
-
- return 0;
-}
-
-/* OTG config */
-static struct fsl_usb2_platform_data usb_pdata = {
- .operating_mode = FSL_USB2_DR_DEVICE,
- .phy_mode = FSL_USB2_PHY_ULPI,
-};
-
-static struct platform_device pcm037_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &pcm037_flash_data,
- },
- .resource = &pcm037_flash_resource,
- .num_resources = 1,
-};
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct resource smsc911x_resources[] = {
- {
- .start = CS1_BASE_ADDR + 0x300,
- .end = CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
- .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
- },
-};
-
-static struct smsc911x_platform_config smsc911x_info = {
- .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY |
- SMSC911X_SAVE_MAC_ADDRESS,
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
- .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
- .phy_interface = PHY_INTERFACE_MODE_MII,
-};
-
-static struct platform_device pcm037_eth = {
- .name = "smsc911x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smsc911x_resources),
- .resource = smsc911x_resources,
- .dev = {
- .platform_data = &smsc911x_info,
- },
-};
-
-static struct platdata_mtd_ram pcm038_sram_data = {
- .bankwidth = 2,
-};
-
-static struct resource pcm038_sram_resource = {
- .start = CS4_BASE_ADDR,
- .end = CS4_BASE_ADDR + 512 * 1024 - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device pcm037_sram_device = {
- .name = "mtd-ram",
- .id = 0,
- .dev = {
- .platform_data = &pcm038_sram_data,
- },
- .num_resources = 1,
- .resource = &pcm038_sram_resource,
-};
-
-static struct mxc_nand_platform_data pcm037_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-static struct imxi2c_platform_data pcm037_i2c_1_data = {
- .bitrate = 100000,
-};
-
-static struct imxi2c_platform_data pcm037_i2c_2_data = {
- .bitrate = 20000,
-};
-
-static struct at24_platform_data board_eeprom = {
- .byte_len = 4096,
- .page_size = 32,
- .flags = AT24_FLAG_ADDR16,
-};
-
-static int pcm037_camera_power(struct device *dev, int on)
-{
- /* disable or enable the camera in X7 or X8 PCM970 connector */
- gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on);
- return 0;
-}
-
-static struct i2c_board_info pcm037_i2c_camera[] = {
- {
- I2C_BOARD_INFO("mt9t031", 0x5d),
- }, {
- I2C_BOARD_INFO("mt9v022", 0x48),
- },
-};
-
-static struct soc_camera_link iclink_mt9v022 = {
- .bus_id = 0, /* Must match with the camera ID */
- .board_info = &pcm037_i2c_camera[1],
- .i2c_adapter_id = 2,
- .module_name = "mt9v022",
-};
-
-static struct soc_camera_link iclink_mt9t031 = {
- .bus_id = 0, /* Must match with the camera ID */
- .power = pcm037_camera_power,
- .board_info = &pcm037_i2c_camera[0],
- .i2c_adapter_id = 2,
- .module_name = "mt9t031",
-};
-
-static struct i2c_board_info pcm037_i2c_devices[] = {
- {
- I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
- .platform_data = &board_eeprom,
- }, {
- I2C_BOARD_INFO("pcf8563", 0x51),
- }
-};
-
-static struct platform_device pcm037_mt9t031 = {
- .name = "soc-camera-pdrv",
- .id = 0,
- .dev = {
- .platform_data = &iclink_mt9t031,
- },
-};
-
-static struct platform_device pcm037_mt9v022 = {
- .name = "soc-camera-pdrv",
- .id = 1,
- .dev = {
- .platform_data = &iclink_mt9v022,
- },
-};
-
-/* Not connected by default */
-#ifdef PCM970_SDHC_RW_SWITCH
-static int pcm970_sdhc1_get_ro(struct device *dev)
-{
- return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_SFS6));
-}
-#endif
-
-#define SDHC1_GPIO_WP IOMUX_TO_GPIO(MX31_PIN_SFS6)
-#define SDHC1_GPIO_DET IOMUX_TO_GPIO(MX31_PIN_SCK6)
-
-static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
- void *data)
-{
- int ret;
-
- ret = gpio_request(SDHC1_GPIO_DET, "sdhc-detect");
- if (ret)
- return ret;
-
- gpio_direction_input(SDHC1_GPIO_DET);
-
-#ifdef PCM970_SDHC_RW_SWITCH
- ret = gpio_request(SDHC1_GPIO_WP, "sdhc-wp");
- if (ret)
- goto err_gpio_free;
- gpio_direction_input(SDHC1_GPIO_WP);
-#endif
-
- ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), detect_irq,
- IRQF_DISABLED | IRQF_TRIGGER_FALLING,
- "sdhc-detect", data);
- if (ret)
- goto err_gpio_free_2;
-
- return 0;
-
-err_gpio_free_2:
-#ifdef PCM970_SDHC_RW_SWITCH
- gpio_free(SDHC1_GPIO_WP);
-err_gpio_free:
-#endif
- gpio_free(SDHC1_GPIO_DET);
-
- return ret;
-}
-
-static void pcm970_sdhc1_exit(struct device *dev, void *data)
-{
- free_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), data);
- gpio_free(SDHC1_GPIO_DET);
- gpio_free(SDHC1_GPIO_WP);
-}
-
-static struct imxmmc_platform_data sdhc_pdata = {
-#ifdef PCM970_SDHC_RW_SWITCH
- .get_ro = pcm970_sdhc1_get_ro,
-#endif
- .init = pcm970_sdhc1_init,
- .exit = pcm970_sdhc1_exit,
-};
-
-struct mx3_camera_pdata camera_pdata = {
- .dma_dev = &mx3_ipu.dev,
- .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
- .mclk_10khz = 2000,
-};
-
-static int __init pcm037_camera_alloc_dma(const size_t buf_size)
-{
- dma_addr_t dma_handle;
- void *buf;
- int dma;
-
- if (buf_size < 2 * 1024 * 1024)
- return -EINVAL;
-
- buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL);
- if (!buf) {
- pr_err("%s: cannot allocate camera buffer-memory\n", __func__);
- return -ENOMEM;
- }
-
- memset(buf, 0, buf_size);
-
- dma = dma_declare_coherent_memory(&mx3_camera.dev,
- dma_handle, dma_handle, buf_size,
- DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
-
- /* The way we call dma_declare_coherent_memory only a malloc can fail */
- return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM;
-}
-
-static struct platform_device *devices[] __initdata = {
- &pcm037_flash,
- &pcm037_sram_device,
- &pcm037_mt9t031,
- &pcm037_mt9v022,
-};
-
-static struct ipu_platform_data mx3_ipu_data = {
- .irq_base = MXC_IPU_IRQ_START,
-};
-
-static const struct fb_videomode fb_modedb[] = {
- {
- /* 240x320 @ 60 Hz Sharp */
- .name = "Sharp-LQ035Q7DH06-QVGA",
- .refresh = 60,
- .xres = 240,
- .yres = 320,
- .pixclock = 185925,
- .left_margin = 9,
- .right_margin = 16,
- .upper_margin = 7,
- .lower_margin = 9,
- .hsync_len = 1,
- .vsync_len = 1,
- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
- FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
- .vmode = FB_VMODE_NONINTERLACED,
- .flag = 0,
- }, {
- /* 240x320 @ 60 Hz */
- .name = "TX090",
- .refresh = 60,
- .xres = 240,
- .yres = 320,
- .pixclock = 38255,
- .left_margin = 144,
- .right_margin = 0,
- .upper_margin = 7,
- .lower_margin = 40,
- .hsync_len = 96,
- .vsync_len = 1,
- .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
- .vmode = FB_VMODE_NONINTERLACED,
- .flag = 0,
- }, {
- /* 240x320 @ 60 Hz */
- .name = "CMEL-OLED",
- .refresh = 60,
- .xres = 240,
- .yres = 320,
- .pixclock = 185925,
- .left_margin = 9,
- .right_margin = 16,
- .upper_margin = 7,
- .lower_margin = 9,
- .hsync_len = 1,
- .vsync_len = 1,
- .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
- .vmode = FB_VMODE_NONINTERLACED,
- .flag = 0,
- },
-};
-
-static struct mx3fb_platform_data mx3fb_pdata = {
- .dma_dev = &mx3_ipu.dev,
- .name = "Sharp-LQ035Q7DH06-QVGA",
- .mode = fb_modedb,
- .num_modes = ARRAY_SIZE(fb_modedb),
-};
-
-static struct resource pcm970_sja1000_resources[] = {
- {
- .start = CS5_BASE_ADDR,
- .end = CS5_BASE_ADDR + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
- .end = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
- },
-};
-
-struct sja1000_platform_data pcm970_sja1000_platform_data = {
- .clock = 16000000 / 2,
- .ocr = 0x40 | 0x18,
- .cdr = 0x40,
-};
-
-static struct platform_device pcm970_sja1000 = {
- .name = "sja1000_platform",
- .dev = {
- .platform_data = &pcm970_sja1000_platform_data,
- },
- .resource = pcm970_sja1000_resources,
- .num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
-};
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
- int ret;
-
- mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins),
- "pcm037");
-
- if (pcm037_variant() == PCM037_EET)
- mxc_iomux_setup_multiple_pins(pcm037_uart1_pins,
- ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1");
- else
- mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins,
- ARRAY_SIZE(pcm037_uart1_handshake_pins),
- "pcm037_uart1");
-
- 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);
-
- mxc_register_device(&mxc_w1_master_device, NULL);
-
- /* LAN9217 IRQ pin */
- ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq");
- if (ret)
- pr_warning("could not get LAN irq gpio\n");
- else {
- gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1));
- platform_device_register(&pcm037_eth);
- }
-
-
- /* I2C adapters and devices */
- 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);
-
- mxc_register_device(&mxc_nand_device, &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);
- if (!gpio_usbotg_hs_activate())
- mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
-
- /* CSI */
- /* Camera power: default - off */
- ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "mt9t031-power");
- if (!ret)
- gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1);
- else
- iclink_mt9t031.power = NULL;
-
- if (!pcm037_camera_alloc_dma(4 * 1024 * 1024))
- mxc_register_device(&mx3_camera, &camera_pdata);
-
- platform_device_register(&pcm970_sja1000);
-}
-
-static void __init pcm037_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-struct sys_timer pcm037_timer = {
- .init = pcm037_timer_init,
-};
-
-MACHINE_START(PCM037, "Phytec Phycore pcm037")
- /* Maintainer: Pengutronix */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31_map_io,
- .init_irq = mx31_init_irq,
- .init_machine = mxc_board_init,
- .timer = &pcm037_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx3/pcm043.c b/arch/arm/mach-mx3/pcm043.c
deleted file mode 100644
index e3aa829be58..00000000000
--- a/arch/arm/mach-mx3/pcm043.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * 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/mtd/plat-ram.h>
-#include <linux/memory.h>
-#include <linux/gpio.h>
-#include <linux/smc911x.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-
-#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 "devices.h"
-
-static const struct fb_videomode fb_modedb[] = {
- {
- /* 240x320 @ 60 Hz */
- .name = "Sharp-LQ035Q7",
- .refresh = 60,
- .xres = 240,
- .yres = 320,
- .pixclock = 185925,
- .left_margin = 9,
- .right_margin = 16,
- .upper_margin = 7,
- .lower_margin = 9,
- .hsync_len = 1,
- .vsync_len = 1,
- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
- .vmode = FB_VMODE_NONINTERLACED,
- .flag = 0,
- }, {
- /* 240x320 @ 60 Hz */
- .name = "TX090",
- .refresh = 60,
- .xres = 240,
- .yres = 320,
- .pixclock = 38255,
- .left_margin = 144,
- .right_margin = 0,
- .upper_margin = 7,
- .lower_margin = 40,
- .hsync_len = 96,
- .vsync_len = 1,
- .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
- .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 = "Sharp-LQ035Q7",
- .mode = fb_modedb,
- .num_modes = ARRAY_SIZE(fb_modedb),
-};
-
-static struct physmap_flash_data pcm043_flash_data = {
- .width = 2,
-};
-
-static struct resource pcm043_flash_resource = {
- .start = 0xa0000000,
- .end = 0xa1ffffff,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device pcm043_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &pcm043_flash_data,
- },
- .resource = &pcm043_flash_resource,
- .num_resources = 1,
-};
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
-static struct imxi2c_platform_data pcm043_i2c_1_data = {
- .bitrate = 50000,
-};
-
-static struct at24_platform_data board_eeprom = {
- .byte_len = 4096,
- .page_size = 32,
- .flags = AT24_FLAG_ADDR16,
-};
-
-static struct i2c_board_info pcm043_i2c_devices[] = {
- {
- I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
- .platform_data = &board_eeprom,
- }, {
- I2C_BOARD_INFO("pcf8563", 0x51),
- }
-};
-#endif
-
-static struct platform_device *devices[] __initdata = {
- &pcm043_flash,
- &mxc_fec_device,
-};
-
-static struct pad_desc pcm043_pads[] = {
- /* UART1 */
- MX35_PAD_CTS1__UART1_CTS,
- MX35_PAD_RTS1__UART1_RTS,
- MX35_PAD_TXD1__UART1_TXD_MUX,
- MX35_PAD_RXD1__UART1_RXD_MUX,
- /* UART2 */
- MX35_PAD_CTS2__UART2_CTS,
- MX35_PAD_RTS2__UART2_RTS,
- MX35_PAD_TXD2__UART2_TXD_MUX,
- MX35_PAD_RXD2__UART2_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,
- /* Display */
- 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_CONTRAST__IPU_DISPB_CONTR,
- MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
- MX35_PAD_D3_REV__IPU_DISPB_D3_REV,
- MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS,
- /* gpio */
- MX35_PAD_ATA_CS0__GPIO2_6,
-};
-
-static struct mxc_nand_platform_data pcm037_nand_board_info = {
- .width = 1,
- .hw_ecc = 1,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
- mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
-
- 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);
-
- mxc_register_device(&mxc_uart_device1, &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);
-#endif
-
- mxc_register_device(&mx3_ipu, &mx3_ipu_data);
- mxc_register_device(&mx3_fb, &mx3fb_pdata);
-}
-
-static void __init pcm043_timer_init(void)
-{
- mx35_clocks_init();
-}
-
-struct sys_timer pcm043_timer = {
- .init = pcm043_timer_init,
-};
-
-MACHINE_START(PCM043, "Phytec Phycore pcm043")
- /* Maintainer: Pengutronix */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx35_map_io,
- .init_irq = mx35_init_irq,
- .init_machine = mxc_board_init,
- .timer = &pcm043_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-mx3/qong.c b/arch/arm/mach-mx3/qong.c
deleted file mode 100644
index 044511f1b9a..00000000000
--- a/arch/arm/mach-mx3/qong.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 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 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/kernel.h>
-#include <linux/memory.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/nand.h>
-#include <linux/gpio.h>
-
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-#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.h"
-
-/* FPGA defines */
-#define QONG_FPGA_VERSION(major, minor, rev) \
- (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF))
-
-#define QONG_FPGA_BASEADDR CS1_BASE_ADDR
-#define QONG_FPGA_PERIPH_SIZE (1 << 24)
-
-#define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR
-#define QONG_FPGA_CTRL_SIZE 0x10
-/* FPGA control registers */
-#define QONG_FPGA_CTRL_VERSION 0x00
-
-#define QONG_DNET_ID 1
-#define QONG_DNET_BASEADDR \
- (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE)
-#define QONG_DNET_SIZE 0x00001000
-
-#define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1)
-
-/*
- * This file contains the board-specific initialization routines.
- */
-
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
-};
-
-static int uart_pins[] = {
- MX31_PIN_CTS1__CTS1,
- MX31_PIN_RTS1__RTS1,
- MX31_PIN_TXD1__TXD1,
- MX31_PIN_RXD1__RXD1
-};
-
-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);
-}
-
-static struct resource dnet_resources[] = {
- {
- .name = "dnet-memory",
- .start = QONG_DNET_BASEADDR,
- .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = QONG_FPGA_IRQ,
- .end = QONG_FPGA_IRQ,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device dnet_device = {
- .name = "dnet",
- .id = -1,
- .num_resources = ARRAY_SIZE(dnet_resources),
- .resource = dnet_resources,
-};
-
-static int __init qong_init_dnet(void)
-{
- int ret;
-
- ret = platform_device_register(&dnet_device);
- return ret;
-}
-
-/* MTD NOR flash */
-
-static struct physmap_flash_data qong_flash_data = {
- .width = 2,
-};
-
-static struct resource qong_flash_resource = {
- .start = CS0_BASE_ADDR,
- .end = CS0_BASE_ADDR + QONG_NOR_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device qong_nor_mtd_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &qong_flash_data,
- },
- .resource = &qong_flash_resource,
- .num_resources = 1,
-};
-
-static void qong_init_nor_mtd(void)
-{
- (void)platform_device_register(&qong_nor_mtd_device);
-}
-
-/*
- * Hardware specific access to control-lines
- */
-static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
-{
- struct nand_chip *nand_chip = mtd->priv;
-
- if (cmd == NAND_CMD_NONE)
- return;
-
- if (ctrl & NAND_CLE)
- writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
- else
- writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
-}
-
-/*
- * Read the Device Ready pin.
- */
-static int qong_nand_device_ready(struct mtd_info *mtd)
-{
- return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
-}
-
-static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
-{
- if (chip >= 0)
- gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
- else
- gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
-}
-
-static struct platform_nand_data qong_nand_data = {
- .chip = {
- .chip_delay = 20,
- .options = 0,
- },
- .ctrl = {
- .cmd_ctrl = qong_nand_cmd_ctrl,
- .dev_ready = qong_nand_device_ready,
- .select_chip = qong_nand_select_chip,
- }
-};
-
-static struct resource qong_nand_resource = {
- .start = CS3_BASE_ADDR,
- .end = CS3_BASE_ADDR + SZ_32M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device qong_nand_device = {
- .name = "gen_nand",
- .id = -1,
- .dev = {
- .platform_data = &qong_nand_data,
- },
- .num_resources = 1,
- .resource = &qong_nand_resource,
-};
-
-static void __init qong_init_nand_mtd(void)
-{
- /* init CS */
- __raw_writel(0x00004f00, CSCR_U(3));
- __raw_writel(0x20013b31, CSCR_L(3));
- __raw_writel(0x00020800, CSCR_A(3));
- mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true);
-
- /* enable pin */
- mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO));
- if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable"))
- gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
-
- /* ready/busy pin */
- mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO));
- if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy"))
- gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB));
-
- /* write protect pin */
- mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO));
- if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp"))
- gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B));
-
- platform_device_register(&qong_nand_device);
-}
-
-static void __init qong_init_fpga(void)
-{
- void __iomem *regs;
- u32 fpga_ver;
-
- regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE);
- if (!regs) {
- printk(KERN_ERR "%s: failed to map registers, aborting.\n",
- __func__);
- return;
- }
-
- fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION);
- iounmap(regs);
- printk(KERN_INFO "Qong FPGA version %d.%d.%d\n",
- (fpga_ver & 0xF000) >> 12,
- (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF);
- if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) {
- printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based "
- "devices won't be registered!\n");
- return;
- }
-
- /* register FPGA-based devices */
- qong_init_nand_mtd();
- qong_init_dnet();
-}
-
-/*
- * Board specific initialization.
- */
-static void __init mxc_board_init(void)
-{
- mxc_init_imx_uart();
- qong_init_nor_mtd();
- qong_init_fpga();
-}
-
-static void __init qong_timer_init(void)
-{
- mx31_clocks_init(26000000);
-}
-
-static struct sys_timer qong_timer = {
- .init = qong_timer_init,
-};
-
-/*
- * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_QONG data structure.
- */
-
-MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
- /* Maintainer: DENX Software Engineering GmbH */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31_map_io,
- .init_irq = mx31_init_irq,
- .init_machine = mxc_board_init,
- .timer = &qong_timer,
-MACHINE_END
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
new file mode 100644
index 00000000000..1576d51e676
--- /dev/null
+++ b/arch/arm/mach-mx5/Kconfig
@@ -0,0 +1,18 @@
+if ARCH_MX5
+
+config ARCH_MX51
+ bool
+ default y
+ select MXC_TZIC
+ select ARCH_MXC_IOMUX_V3
+
+comment "MX5 platforms:"
+
+config MACH_MX51_BABBAGE
+ bool "Support MX51 BABBAGE platforms"
+ help
+ Include support for MX51 Babbage platform, also known as MX51EVK in
+ u-boot. This includes specific configurations for the board and its
+ peripherals.
+
+endif
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
new file mode 100644
index 00000000000..bf23f869ef5
--- /dev/null
+++ b/arch/arm/mach-mx5/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+obj-y := cpu.o mm.o clock-mx51.o devices.o
+
+obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
+
diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot
new file mode 100644
index 00000000000..9939a19d99a
--- /dev/null
+++ b/arch/arm/mach-mx5/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x90008000
+params_phys-y := 0x90000100
+initrd_phys-y := 0x90800000
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
new file mode 100644
index 00000000000..ee67a71db80
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.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/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx51.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices.h"
+
+static struct platform_device *devices[] __initdata = {
+ &mxc_fec_device,
+};
+
+static struct pad_desc mx51babbage_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+
+ /* UART2 */
+ MX51_PAD_UART2_RXD__UART2_RXD,
+ MX51_PAD_UART2_TXD__UART2_TXD,
+
+ /* UART3 */
+ MX51_PAD_EIM_D25__UART3_RXD,
+ MX51_PAD_EIM_D26__UART3_TXD,
+ MX51_PAD_EIM_D27__UART3_RTS,
+ MX51_PAD_EIM_D24__UART3_CTS,
+};
+
+/* Serial ports */
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ mxc_register_device(&mxc_uart_device1, &uart_pdata);
+ mxc_register_device(&mxc_uart_device2, &uart_pdata);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* SERIAL_IMX */
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
+ ARRAY_SIZE(mx51babbage_pads));
+ mxc_init_imx_uart();
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mx51_babbage_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx51_babbage_timer_init,
+};
+
+MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
+ /* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */
+ .phys_io = MX51_AIPS1_BASE_ADDR,
+ .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_irq = mx51_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
new file mode 100644
index 00000000000..8f85f73b83a
--- /dev/null
+++ b/arch/arm/mach-mx5/clock-mx51.c
@@ -0,0 +1,825 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.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/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "crm_regs.h"
+
+/* External clock values passed-in by the board code */
+static unsigned long external_high_reference, external_low_reference;
+static unsigned long oscillator_reference, ckih2_reference;
+
+static struct clk osc_clk;
+static struct clk pll1_main_clk;
+static struct clk pll1_sw_clk;
+static struct clk pll2_sw_clk;
+static struct clk pll3_sw_clk;
+static struct clk lp_apm_clk;
+static struct clk periph_apm_clk;
+static struct clk ahb_clk;
+static struct clk ipg_clk;
+
+#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
+
+static int _clk_ccgr_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_ccgr_disable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+
+}
+
+static void _clk_ccgr_disable_inwait(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else
+ BUG();
+
+ return -EINVAL;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_main_clk)
+ return MX51_DPLL1_BASE;
+ else if (pll == &pll2_sw_clk)
+ return MX51_DPLL2_BASE;
+ else if (pll == &pll3_sw_clk)
+ return MX51_DPLL3_BASE;
+ else
+ BUG();
+
+ return NULL;
+}
+
+static unsigned long clk_pll_get_rate(struct clk *clk)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ void __iomem *pllbase;
+ s64 temp;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ pllbase = _get_pll_base(clk);
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ if (pll_hfsm == 0) {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+ } else {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * parent_rate;
+ if (dbl != 0)
+ ref_clk *= 2;
+
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ return temp;
+}
+
+static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ void __iomem *pllbase;
+
+ long mfi, pdf, mfn, mfd = 999999;
+ s64 temp64;
+ unsigned long quad_parent_rate;
+ unsigned long pll_hfsm, dp_ctl;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ pllbase = _get_pll_base(clk);
+
+ quad_parent_rate = 4 * parent_rate;
+ pdf = mfi = -1;
+ while (++pdf < 16 && mfi < 5)
+ mfi = rate * (pdf+1) / quad_parent_rate;
+ if (mfi > 15)
+ return -EINVAL;
+ pdf--;
+
+ temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
+ do_div(temp64, quad_parent_rate/1000000);
+ mfn = (long)temp64;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ /* use dpdck0_2 */
+ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ if (pll_hfsm == 0) {
+ reg = mfi << 4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+ } else {
+ reg = mfi << 4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+
+ return 0;
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+ u32 reg;
+ void __iomem *pllbase;
+ int i = 0;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+ /* Wait for lock */
+ do {
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ if (reg & MXC_PLL_DP_CTL_LRF)
+ break;
+
+ udelay(1);
+ } while (++i < MAX_DPLL_WAIT_TRIES);
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ pr_err("MX5: pll locking failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+ u32 reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, step;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ /* When switching from pll_main_clk to a bypass clock, first select a
+ * multiplexed clock in 'step_sel', then shift the glitchless mux
+ * 'pll1_sw_clk_sel'.
+ *
+ * When switching back, do it in reverse order
+ */
+ if (parent == &pll1_main_clk) {
+ /* Switch to pll1_main_clk */
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* step_clk mux switched to lp_apm, to save power. */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+ reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
+ MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ } else {
+ if (parent == &lp_apm_clk) {
+ step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
+ } else if (parent == &pll2_sw_clk) {
+ step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
+ } else if (parent == &pll3_sw_clk) {
+ step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED;
+ } else
+ return -EINVAL;
+
+ reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+ reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* Switch to step_clk */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (clk->parent == &pll2_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+ } else if (clk->parent == &pll3_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+ } else
+ div = 1;
+ return parent_rate / div;
+}
+
+static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll2_sw_clk)
+ reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+ else
+ reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (parent == &osc_clk)
+ reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static unsigned long clk_arm_get_rate(struct clk *clk)
+{
+ u32 cacrr, div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ cacrr = __raw_readl(MXC_CCM_CACRR);
+ div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+
+ return parent_rate / div;
+}
+
+static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ int i = 0;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
+
+ reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ /* Wait for lock */
+ do {
+ reg = __raw_readl(MXC_CCM_CDHIPR);
+ if (!(reg & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY))
+ break;
+
+ udelay(1);
+ } while (++i < MAX_DPLL_WAIT_TRIES);
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ pr_err("MX5: Set parent for periph_apm clock failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+
+ if (parent == &pll2_sw_clk)
+ reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ else if (parent == &periph_apm_clk)
+ reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ return 0;
+}
+
+static struct clk main_bus_clk = {
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_main_bus_set_parent,
+};
+
+static unsigned long clk_ahb_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+ return parent_rate / div;
+}
+
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ unsigned long parent_rate;
+ int i = 0;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* Wait for lock */
+ do {
+ reg = __raw_readl(MXC_CCM_CDHIPR);
+ if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY))
+ break;
+
+ udelay(1);
+ } while (++i < MAX_DPLL_WAIT_TRIES);
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ pr_err("MX5: clk_ahb_set_rate failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static unsigned long _clk_ahb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return parent_rate / div;
+}
+
+
+static int _clk_max_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_enable(clk);
+
+ /* Handshake with MAX when LPM is entered. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_max_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_disable_inwait(clk);
+
+ /* No Handshake with MAX when LPM is entered as its disabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static unsigned long clk_ipg_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+
+ return parent_rate / div;
+}
+
+static unsigned long clk_ipg_per_get_rate(struct clk *clk)
+{
+ u32 reg, prediv1, prediv2, podf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+ /* the main_bus_clk is the one before the DVFS engine */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
+ prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
+ return parent_rate / (prediv1 * prediv2 * podf);
+ } else if (clk->parent == &ipg_clk)
+ return parent_rate;
+ else
+ BUG();
+}
+
+static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+
+ reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+
+ if (parent == &ipg_clk)
+ reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ else if (parent == &lp_apm_clk)
+ reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ else if (parent != &main_bus_clk)
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static unsigned long clk_uart_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+
+ return parent_rate / (prediv * podf);
+}
+
+static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+ return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+ return ckih2_reference;
+}
+
+/* External high frequency clock */
+static struct clk ckih_clk = {
+ .get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+ .get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+ .get_rate = get_oscillator_reference_clock_rate,
+};
+
+/* External low frequency (32kHz) clock */
+static struct clk ckil_clk = {
+ .get_rate = get_low_reference_clock_rate,
+};
+
+static struct clk pll1_main_clk = {
+ .parent = &osc_clk,
+ .get_rate = clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+/* Clock tree block diagram (WIP):
+ * CCM: Clock Controller Module
+ *
+ * PLL output -> |
+ * | CCM Switcher -> CCM_CLK_ROOT_GEN ->
+ * PLL bypass -> |
+ *
+ */
+
+/* PLL1 SW supplies to ARM core */
+static struct clk pll1_sw_clk = {
+ .parent = &pll1_main_clk,
+ .set_parent = _clk_pll1_sw_set_parent,
+ .get_rate = clk_pll1_sw_get_rate,
+};
+
+/* PLL2 SW supplies to AXI/AHB/IP buses */
+static struct clk pll2_sw_clk = {
+ .parent = &osc_clk,
+ .get_rate = clk_pll_get_rate,
+ .set_rate = _clk_pll_set_rate,
+ .set_parent = _clk_pll2_sw_set_parent,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
+static struct clk pll3_sw_clk = {
+ .parent = &osc_clk,
+ .set_rate = _clk_pll_set_rate,
+ .get_rate = clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+/* Low-power Audio Playback Mode clock */
+static struct clk lp_apm_clk = {
+ .parent = &osc_clk,
+ .set_parent = _clk_lp_apm_set_parent,
+};
+
+static struct clk periph_apm_clk = {
+ .parent = &pll1_sw_clk,
+ .set_parent = _clk_periph_apm_set_parent,
+};
+
+static struct clk cpu_clk = {
+ .parent = &pll1_sw_clk,
+ .get_rate = clk_arm_get_rate,
+};
+
+static struct clk ahb_clk = {
+ .parent = &main_bus_clk,
+ .get_rate = clk_ahb_get_rate,
+ .set_rate = _clk_ahb_set_rate,
+ .round_rate = _clk_ahb_round_rate,
+};
+
+/* Main IP interface clock for access to registers */
+static struct clk ipg_clk = {
+ .parent = &ahb_clk,
+ .get_rate = clk_ipg_get_rate,
+};
+
+static struct clk ipg_perclk = {
+ .parent = &lp_apm_clk,
+ .get_rate = clk_ipg_per_get_rate,
+ .set_parent = _clk_ipg_per_set_parent,
+};
+
+static struct clk uart_root_clk = {
+ .parent = &pll2_sw_clk,
+ .get_rate = clk_uart_get_rate,
+ .set_parent = _clk_uart_set_parent,
+};
+
+static struct clk ahb_max_clk = {
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+};
+
+static struct clk aips_tz1_clk = {
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk aips_tz2_clk = {
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk gpt_32k_clk = {
+ .id = 0,
+ .parent = &ckil_clk,
+};
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .set_rate = sr, \
+ .enable = _clk_ccgr_enable, \
+ .disable = _clk_ccgr_disable, \
+ .parent = p, \
+ .secondary = s, \
+ }
+
+/* DEFINE_CLOCK(name, id, enable_reg, enable_shift,
+ get_rate, set_rate, parent, secondary); */
+
+/* Shared peripheral bus arbiter */
+DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+
+/* UART */
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
+ NULL, NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
+ NULL, NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
+ NULL, NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
+ NULL, NULL, &ipg_clk, &aips_tz1_clk);
+DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
+ NULL, NULL, &ipg_clk, &aips_tz1_clk);
+DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
+ NULL, NULL, &ipg_clk, &spba_clk);
+
+/* GPT */
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_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);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+};
+
+static void clk_tree_init(void)
+{
+ u32 reg;
+
+ ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+
+ /*
+ * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+ * 8MHz, its derived from lp_apm.
+ *
+ * FIXME: Verify if true for all boards
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
+ reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+}
+
+int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2)
+{
+ int i;
+
+ external_low_reference = ckil;
+ external_high_reference = ckih1;
+ ckih2_reference = ckih2;
+ oscillator_reference = osc;
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
+
+ clk_tree_init();
+
+ clk_enable(&cpu_clk);
+ clk_enable(&main_bus_clk);
+
+ /* System timer */
+ mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
+ MX51_MXC_INT_GPT);
+ return 0;
+}
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
new file mode 100644
index 00000000000..2d37785e385
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu.c
@@ -0,0 +1,100 @@
+/*
+ * 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
+ *
+ * This file contains the CPU initialization code.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+static int cpu_silicon_rev = -1;
+
+#define SI_REV 0x48
+
+static void query_silicon_parameter(void)
+{
+ void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE);
+ u32 rev;
+
+ if (!rom) {
+ cpu_silicon_rev = -EINVAL;
+ return;
+ }
+
+ rev = readl(rom + SI_REV);
+ switch (rev) {
+ case 0x1:
+ cpu_silicon_rev = MX51_CHIP_REV_1_0;
+ break;
+ case 0x2:
+ cpu_silicon_rev = MX51_CHIP_REV_1_1;
+ break;
+ case 0x10:
+ cpu_silicon_rev = MX51_CHIP_REV_2_0;
+ break;
+ case 0x20:
+ cpu_silicon_rev = MX51_CHIP_REV_3_0;
+ break;
+ default:
+ cpu_silicon_rev = 0;
+ }
+
+ iounmap(rom);
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx51
+ */
+int mx51_revision(void)
+{
+ if (!cpu_is_mx51())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ query_silicon_parameter();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx51_revision);
+
+static int __init post_cpu_init(void)
+{
+ unsigned int reg;
+ void __iomem *base;
+
+ if (!cpu_is_mx51())
+ return 0;
+
+ base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
+ __raw_writel(0x0, base + 0x40);
+ __raw_writel(0x0, base + 0x44);
+ __raw_writel(0x0, base + 0x48);
+ __raw_writel(0x0, base + 0x4C);
+ reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+ __raw_writel(reg, base + 0x50);
+
+ base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
+ __raw_writel(0x0, base + 0x40);
+ __raw_writel(0x0, base + 0x44);
+ __raw_writel(0x0, base + 0x48);
+ __raw_writel(0x0, base + 0x4C);
+ reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+ __raw_writel(reg, base + 0x50);
+
+ return 0;
+}
+
+postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
new file mode 100644
index 00000000000..c776b9af062
--- /dev/null
+++ b/arch/arm/mach-mx5/crm_regs.h
@@ -0,0 +1,583 @@
+/*
+ * 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 __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+
+#define MX51_CCM_BASE MX51_IO_ADDRESS(MX51_CCM_BASE_ADDR)
+#define MX51_DPLL1_BASE MX51_IO_ADDRESS(MX51_PLL1_BASE_ADDR)
+#define MX51_DPLL2_BASE MX51_IO_ADDRESS(MX51_PLL2_BASE_ADDR)
+#define MX51_DPLL3_BASE MX51_IO_ADDRESS(MX51_PLL3_BASE_ADDR)
+#define MX51_CORTEXA8_BASE MX51_IO_ADDRESS(MX51_ARM_BASE_ADDR)
+#define MX51_GPC_BASE MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR)
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL 0x00
+#define MXC_PLL_DP_CONFIG 0x04
+#define MXC_PLL_DP_OP 0x08
+#define MXC_PLL_DP_MFD 0x0C
+#define MXC_PLL_DP_MFN 0x10
+#define MXC_PLL_DP_MFNMINUS 0x14
+#define MXC_PLL_DP_MFNPLUS 0x18
+#define MXC_PLL_DP_HFS_OP 0x1C
+#define MXC_PLL_DP_HFS_MFD 0x20
+#define MXC_PLL_DP_HFS_MFN 0x24
+#define MXC_PLL_DP_MFN_TOGC 0x28
+#define MXC_PLL_DP_DESTAT 0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
+#define MXC_PLL_DP_CTL_ADE 0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
+#define MXC_PLL_DP_CTL_HFSM 0x80
+#define MXC_PLL_DP_CTL_PRE 0x40
+#define MXC_PLL_DP_CTL_UPEN 0x20
+#define MXC_PLL_DP_CTL_RST 0x10
+#define MXC_PLL_DP_CTL_RCP 0x8
+#define MXC_PLL_DP_CTL_PLM 0x4
+#define MXC_PLL_DP_CTL_BRM0 0x2
+#define MXC_PLL_DP_CTL_LRF 0x1
+
+#define MXC_PLL_DP_CONFIG_BIST 0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
+#define MXC_PLL_DP_CONFIG_AREN 0x2
+#define MXC_PLL_DP_CONFIG_LDREQ 0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET 4
+#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET 0
+#define MXC_PLL_DP_OP_PDF_MASK 0xF
+
+#define MXC_PLL_DP_MFD_OFFSET 0
+#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET 0x0
+#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR (MX51_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR (MX51_CCM_BASE + 0x04)
+#define MXC_CCM_CSR (MX51_CCM_BASE + 0x08)
+#define MXC_CCM_CCSR (MX51_CCM_BASE + 0x0C)
+#define MXC_CCM_CACRR (MX51_CCM_BASE + 0x10)
+#define MXC_CCM_CBCDR (MX51_CCM_BASE + 0x14)
+#define MXC_CCM_CBCMR (MX51_CCM_BASE + 0x18)
+#define MXC_CCM_CSCMR1 (MX51_CCM_BASE + 0x1C)
+#define MXC_CCM_CSCMR2 (MX51_CCM_BASE + 0x20)
+#define MXC_CCM_CSCDR1 (MX51_CCM_BASE + 0x24)
+#define MXC_CCM_CS1CDR (MX51_CCM_BASE + 0x28)
+#define MXC_CCM_CS2CDR (MX51_CCM_BASE + 0x2C)
+#define MXC_CCM_CDCDR (MX51_CCM_BASE + 0x30)
+#define MXC_CCM_CHSCDR (MX51_CCM_BASE + 0x34)
+#define MXC_CCM_CSCDR2 (MX51_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR3 (MX51_CCM_BASE + 0x3C)
+#define MXC_CCM_CSCDR4 (MX51_CCM_BASE + 0x40)
+#define MXC_CCM_CWDR (MX51_CCM_BASE + 0x44)
+#define MXC_CCM_CDHIPR (MX51_CCM_BASE + 0x48)
+#define MXC_CCM_CDCR (MX51_CCM_BASE + 0x4C)
+#define MXC_CCM_CTOR (MX51_CCM_BASE + 0x50)
+#define MXC_CCM_CLPCR (MX51_CCM_BASE + 0x54)
+#define MXC_CCM_CISR (MX51_CCM_BASE + 0x58)
+#define MXC_CCM_CIMR (MX51_CCM_BASE + 0x5C)
+#define MXC_CCM_CCOSR (MX51_CCM_BASE + 0x60)
+#define MXC_CCM_CGPR (MX51_CCM_BASE + 0x64)
+#define MXC_CCM_CCGR0 (MX51_CCM_BASE + 0x68)
+#define MXC_CCM_CCGR1 (MX51_CCM_BASE + 0x6C)
+#define MXC_CCM_CCGR2 (MX51_CCM_BASE + 0x70)
+#define MXC_CCM_CCGR3 (MX51_CCM_BASE + 0x74)
+#define MXC_CCM_CCGR4 (MX51_CCM_BASE + 0x78)
+#define MXC_CCM_CCGR5 (MX51_CCM_BASE + 0x7C)
+#define MXC_CCM_CCGR6 (MX51_CCM_BASE + 0x80)
+#define MXC_CCM_CMEOR (MX51_CCM_BASE + 0x84)
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_COSC_EN (1 << 12)
+#define MXC_CCM_CCR_FPM_MULT_MASK (1 << 11)
+#define MXC_CCM_CCR_CAMP2_EN (1 << 10)
+#define MXC_CCM_CCR_CAMP1_EN (1 << 9)
+#define MXC_CCM_CCR_FPM_EN (1 << 8)
+#define MXC_CCM_CCR_OSCNT_OFFSET (0)
+#define MXC_CCM_CCR_OSCNT_MASK (0xFF)
+
+/* Define the bits in register CCDR */
+#define MXC_CCM_CCDR_HSC_HS_MASK (0x1 << 18)
+#define MXC_CCM_CCDR_IPU_HS_MASK (0x1 << 17)
+#define MXC_CCM_CCDR_EMI_HS_MASK (0x1 << 16)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSR_READY (1 << 5)
+#define MXC_CCM_CSR_LVS_VALUE (1 << 4)
+#define MXC_CCM_CSR_CAMP2_READY (1 << 3)
+#define MXC_CCM_CSR_CAMP1_READY (1 << 2)
+#define MXC_CCM_CSR_FPM_READY (1 << 1)
+#define MXC_CCM_CSR_REF_EN_B (1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 9)
+#define MXC_CCM_CCSR_STEP_SEL_OFFSET (7)
+#define MXC_CCM_CCSR_STEP_SEL_MASK (0x3 << 7)
+#define MXC_CCM_CCSR_STEP_SEL_LP_APM 0
+#define MXC_CCM_CCSR_STEP_SEL_PLL1_BYPASS 1 /* Only when JTAG connected? */
+#define MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED 2
+#define MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED 3
+#define MXC_CCM_CCSR_PLL2_PODF_OFFSET (5)
+#define MXC_CCM_CCSR_PLL2_PODF_MASK (0x3 << 5)
+#define MXC_CCM_CCSR_PLL3_PODF_OFFSET (3)
+#define MXC_CCM_CCSR_PLL3_PODF_MASK (0x3 << 3)
+#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2) /* 0: pll1_main_clk,
+ 1: step_clk */
+#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1)
+#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0)
+
+/* Define the bits in register CACRR */
+#define MXC_CCM_CACRR_ARM_PODF_OFFSET (0)
+#define MXC_CCM_CACRR_ARM_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR */
+#define MXC_CCM_CBCDR_EMI_CLK_SEL (0x1 << 26)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL (0x1 << 25)
+#define MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET (30)
+#define MXC_CCM_CBCDR_DDR_HF_SEL (0x1 << 30)
+#define MXC_CCM_CBCDR_DDR_PODF_OFFSET (27)
+#define MXC_CCM_CBCDR_DDR_PODF_MASK (0x7 << 27)
+#define MXC_CCM_CBCDR_EMI_PODF_OFFSET (22)
+#define MXC_CCM_CBCDR_EMI_PODF_MASK (0x7 << 22)
+#define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET (19)
+#define MXC_CCM_CBCDR_AXI_B_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CBCDR_AXI_A_PODF_OFFSET (16)
+#define MXC_CCM_CBCDR_AXI_A_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CBCDR_NFC_PODF_OFFSET (13)
+#define MXC_CCM_CBCDR_NFC_PODF_MASK (0x7 << 13)
+#define MXC_CCM_CBCDR_AHB_PODF_OFFSET (10)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10)
+#define MXC_CCM_CBCDR_IPG_PODF_OFFSET (8)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET (6)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_MASK (0x3 << 6)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET (3)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_MASK (0x7 << 3)
+#define MXC_CCM_CBCDR_PERCLK_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR_PERCLK_PODF_MASK (0x7)
+
+/* Define the bits in register CBCMR */
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK (0x3 << 6)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30)
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK (0x3 << 28)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET (26)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL (0x1 << 26)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET (24)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK (0x3 << 24)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET (22)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK (0x3 << 22)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL (0x1 << 19)
+#define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 18)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL (0x1 << 11)
+#define MXC_CCM_CSCMR1_VPU_RCLK_SEL (0x1 << 10)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CSCMR1_TVE_CLK_SEL (0x1 << 7)
+#define MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL (0x1 << 6)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL (0x1)
+
+/* Define the bits in register CSCMR2 */
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(n) (26+n*3)
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_MASK(n) (0x7 << (26+n*3))
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET (24)
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK (0x3 << 24)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET (22)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK (0x3 << 22)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET (18)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_MASK (0x3 << 18)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CSCMR2_SLIMBUS_COM (0x1 << 9)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK (0x7 << 6)
+#define MXC_CCM_CSCMR2_SPDIF1_COM (1 << 5)
+#define MXC_CCM_CSCMR2_SPDIF0_COM (1 << 4)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET (0)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK (0x3)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK (0x3 << 14)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET (8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK (0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK (0x3 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET (3)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK (0x7 << 3)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x7)
+
+/* Define the bits in register CS1CDR and CS2CDR */
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F)
+
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CDCDR */
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET (28)
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_MASK (0x7 << 28)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x3F << 19)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CDCDR_DI_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CDCDR_DI_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET (3)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_MASK (0x7 << 3)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET (0)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_MASK (0x7)
+
+/* Define the bits in register CHSCCDR */
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET (12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_MASK (0x7 << 12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_MASK (0x3F << 6)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET (3)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_MASK (0x7)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK (0x3F << 19)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_MASK (0x3F)
+
+/* Define the bits in register CSCDR3 */
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CSCDR4 */
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
+#define MXC_CCM_CDHIPR_DDR_HF_CLK_SEL_BUSY (1 << 8)
+#define MXC_CCM_CDHIPR_DDR_PODF_BUSY (1 << 7)
+#define MXC_CCM_CDHIPR_EMI_CLK_SEL_BUSY (1 << 6)
+#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5)
+#define MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY (1 << 4)
+#define MXC_CCM_CDHIPR_AHB_PODF_BUSY (1 << 3)
+#define MXC_CCM_CDHIPR_EMI_PODF_BUSY (1 << 2)
+#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY (1 << 1)
+#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0)
+
+/* Define the bits in register CDCR */
+#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3)
+
+/* Define the bits in register CLPCR */
+#define MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS (0x1 << 23)
+#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS (0x1 << 22)
+#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21)
+#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 20)
+#define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS (0x1 << 19)
+#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18)
+#define MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS (0x1 << 17)
+#define MXC_CCM_CLPCR_BYPASS_RNGC_LPM_HS (0x1 << 16)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN (0x1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9)
+#define MXC_CCM_CLPCR_VSTBY (0x1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define MXC_CCM_CLPCR_SBYOS (0x1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3)
+#define MXC_CCM_CLPCR_LPM_OFFSET (0)
+#define MXC_CCM_CLPCR_LPM_MASK (0x3)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED (0x1 << 25)
+#define MXC_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
+#define MXC_CCM_CISR_AHB_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CISR_EMI_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CISR_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CISR_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CISR_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CISR_COSC_READY (0x1 << 6)
+#define MXC_CCM_CISR_CKIH2_READY (0x1 << 5)
+#define MXC_CCM_CISR_CKIH_READY (0x1 << 4)
+#define MXC_CCM_CISR_FPM_READY (0x1 << 3)
+#define MXC_CCM_CISR_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CISR_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CISR_LRF_PLL1 (0x1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 25)
+#define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
+#define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CIMR_MASK_COSC_READY (0x1 << 5)
+#define MXC_CCM_CIMR_MASK_CKIH_READY (0x1 << 4)
+#define MXC_CCM_CIMR_MASK_FPM_READY (0x1 << 3)
+#define MXC_CCM_CIMR_MASK_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CIMR_MASK_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CIMR_MASK_LRF_PLL1 (0x1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (0x1 << 24)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_EN (0x1 << 7)
+#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET (4)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET (0)
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK (0xF)
+
+/* Define the bits in registers CGPR */
+#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (0x1 << 4)
+#define MXC_CCM_CGPR_FPM_SEL (0x1 << 3)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET (0)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK (0x7)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGRx_CG_MASK 0x3
+#define MXC_CCM_CCGRx_MOD_OFF 0x0
+#define MXC_CCM_CCGRx_MOD_ON 0x3
+#define MXC_CCM_CCGRx_MOD_IDLE 0x1
+
+#define MXC_CCM_CCGRx_CG15_MASK (0x3 << 30)
+#define MXC_CCM_CCGRx_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGRx_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGRx_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGRx_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGRx_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGRx_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGRx_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGRx_CG5_MASK (0x3 << 10)
+#define MXC_CCM_CCGRx_CG4_MASK (0x3 << 8)
+#define MXC_CCM_CCGRx_CG3_MASK (0x3 << 6)
+#define MXC_CCM_CCGRx_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGRx_CG1_MASK (0x3 << 2)
+#define MXC_CCM_CCGRx_CG0_MASK (0x3 << 0)
+
+#define MXC_CCM_CCGRx_CG15_OFFSET 30
+#define MXC_CCM_CCGRx_CG14_OFFSET 28
+#define MXC_CCM_CCGRx_CG13_OFFSET 26
+#define MXC_CCM_CCGRx_CG12_OFFSET 24
+#define MXC_CCM_CCGRx_CG11_OFFSET 22
+#define MXC_CCM_CCGRx_CG10_OFFSET 20
+#define MXC_CCM_CCGRx_CG9_OFFSET 18
+#define MXC_CCM_CCGRx_CG8_OFFSET 16
+#define MXC_CCM_CCGRx_CG7_OFFSET 14
+#define MXC_CCM_CCGRx_CG6_OFFSET 12
+#define MXC_CCM_CCGRx_CG5_OFFSET 10
+#define MXC_CCM_CCGRx_CG4_OFFSET 8
+#define MXC_CCM_CCGRx_CG3_OFFSET 6
+#define MXC_CCM_CCGRx_CG2_OFFSET 4
+#define MXC_CCM_CCGRx_CG1_OFFSET 2
+#define MXC_CCM_CCGRx_CG0_OFFSET 0
+
+#define MXC_DPTC_LP_BASE (MX51_GPC_BASE + 0x80)
+#define MXC_DPTC_GP_BASE (MX51_GPC_BASE + 0x100)
+#define MXC_DVFS_CORE_BASE (MX51_GPC_BASE + 0x180)
+#define MXC_DPTC_PER_BASE (MX51_GPC_BASE + 0x1C0)
+#define MXC_PGC_IPU_BASE (MX51_GPC_BASE + 0x220)
+#define MXC_PGC_VPU_BASE (MX51_GPC_BASE + 0x240)
+#define MXC_PGC_GPU_BASE (MX51_GPC_BASE + 0x260)
+#define MXC_SRPG_NEON_BASE (MX51_GPC_BASE + 0x280)
+#define MXC_SRPG_ARM_BASE (MX51_GPC_BASE + 0x2A0)
+#define MXC_SRPG_EMPGC0_BASE (MX51_GPC_BASE + 0x2C0)
+#define MXC_SRPG_EMPGC1_BASE (MX51_GPC_BASE + 0x2D0)
+#define MXC_SRPG_MEGAMIX_BASE (MX51_GPC_BASE + 0x2E0)
+#define MXC_SRPG_EMI_BASE (MX51_GPC_BASE + 0x300)
+
+/* CORTEXA8 platform */
+#define MXC_CORTEXA8_PLAT_PVID (MX51_CORTEXA8_BASE + 0x0)
+#define MXC_CORTEXA8_PLAT_GPC (MX51_CORTEXA8_BASE + 0x4)
+#define MXC_CORTEXA8_PLAT_PIC (MX51_CORTEXA8_BASE + 0x8)
+#define MXC_CORTEXA8_PLAT_LPC (MX51_CORTEXA8_BASE + 0xC)
+#define MXC_CORTEXA8_PLAT_NEON_LPC (MX51_CORTEXA8_BASE + 0x10)
+#define MXC_CORTEXA8_PLAT_ICGC (MX51_CORTEXA8_BASE + 0x14)
+#define MXC_CORTEXA8_PLAT_AMC (MX51_CORTEXA8_BASE + 0x18)
+#define MXC_CORTEXA8_PLAT_NMC (MX51_CORTEXA8_BASE + 0x20)
+#define MXC_CORTEXA8_PLAT_NMS (MX51_CORTEXA8_BASE + 0x24)
+
+/* DVFS CORE */
+#define MXC_DVFSTHRS (MXC_DVFS_CORE_BASE + 0x00)
+#define MXC_DVFSCOUN (MXC_DVFS_CORE_BASE + 0x04)
+#define MXC_DVFSSIG1 (MXC_DVFS_CORE_BASE + 0x08)
+#define MXC_DVFSSIG0 (MXC_DVFS_CORE_BASE + 0x0C)
+#define MXC_DVFSGPC0 (MXC_DVFS_CORE_BASE + 0x10)
+#define MXC_DVFSGPC1 (MXC_DVFS_CORE_BASE + 0x14)
+#define MXC_DVFSGPBT (MXC_DVFS_CORE_BASE + 0x18)
+#define MXC_DVFSEMAC (MXC_DVFS_CORE_BASE + 0x1C)
+#define MXC_DVFSCNTR (MXC_DVFS_CORE_BASE + 0x20)
+#define MXC_DVFSLTR0_0 (MXC_DVFS_CORE_BASE + 0x24)
+#define MXC_DVFSLTR0_1 (MXC_DVFS_CORE_BASE + 0x28)
+#define MXC_DVFSLTR1_0 (MXC_DVFS_CORE_BASE + 0x2C)
+#define MXC_DVFSLTR1_1 (MXC_DVFS_CORE_BASE + 0x30)
+#define MXC_DVFSPT0 (MXC_DVFS_CORE_BASE + 0x34)
+#define MXC_DVFSPT1 (MXC_DVFS_CORE_BASE + 0x38)
+#define MXC_DVFSPT2 (MXC_DVFS_CORE_BASE + 0x3C)
+#define MXC_DVFSPT3 (MXC_DVFS_CORE_BASE + 0x40)
+
+/* GPC */
+#define MXC_GPC_CNTR (MX51_GPC_BASE + 0x0)
+#define MXC_GPC_PGR (MX51_GPC_BASE + 0x4)
+#define MXC_GPC_VCR (MX51_GPC_BASE + 0x8)
+#define MXC_GPC_ALL_PU (MX51_GPC_BASE + 0xC)
+#define MXC_GPC_NEON (MX51_GPC_BASE + 0x10)
+#define MXC_GPC_PGR_ARMPG_OFFSET 8
+#define MXC_GPC_PGR_ARMPG_MASK (3 << 8)
+
+/* PGC */
+#define MXC_PGC_IPU_PGCR (MXC_PGC_IPU_BASE + 0x0)
+#define MXC_PGC_IPU_PGSR (MXC_PGC_IPU_BASE + 0xC)
+#define MXC_PGC_VPU_PGCR (MXC_PGC_VPU_BASE + 0x0)
+#define MXC_PGC_VPU_PGSR (MXC_PGC_VPU_BASE + 0xC)
+#define MXC_PGC_GPU_PGCR (MXC_PGC_GPU_BASE + 0x0)
+#define MXC_PGC_GPU_PGSR (MXC_PGC_GPU_BASE + 0xC)
+
+#define MXC_PGCR_PCR 1
+#define MXC_SRPGCR_PCR 1
+#define MXC_EMPGCR_PCR 1
+#define MXC_PGSR_PSR 1
+
+
+#define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0)
+#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1)
+
+/* SRPG */
+#define MXC_SRPG_NEON_SRPGCR (MXC_SRPG_NEON_BASE + 0x0)
+#define MXC_SRPG_NEON_PUPSCR (MXC_SRPG_NEON_BASE + 0x4)
+#define MXC_SRPG_NEON_PDNSCR (MXC_SRPG_NEON_BASE + 0x8)
+
+#define MXC_SRPG_ARM_SRPGCR (MXC_SRPG_ARM_BASE + 0x0)
+#define MXC_SRPG_ARM_PUPSCR (MXC_SRPG_ARM_BASE + 0x4)
+#define MXC_SRPG_ARM_PDNSCR (MXC_SRPG_ARM_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC0_SRPGCR (MXC_SRPG_EMPGC0_BASE + 0x0)
+#define MXC_SRPG_EMPGC0_PUPSCR (MXC_SRPG_EMPGC0_BASE + 0x4)
+#define MXC_SRPG_EMPGC0_PDNSCR (MXC_SRPG_EMPGC0_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC1_SRPGCR (MXC_SRPG_EMPGC1_BASE + 0x0)
+#define MXC_SRPG_EMPGC1_PUPSCR (MXC_SRPG_EMPGC1_BASE + 0x4)
+#define MXC_SRPG_EMPGC1_PDNSCR (MXC_SRPG_EMPGC1_BASE + 0x8)
+
+#define MXC_SRPG_MEGAMIX_SRPGCR (MXC_SRPG_MEGAMIX_BASE + 0x0)
+#define MXC_SRPG_MEGAMIX_PUPSCR (MXC_SRPG_MEGAMIX_BASE + 0x4)
+#define MXC_SRPG_MEGAMIX_PDNSCR (MXC_SRPG_MEGAMIX_BASE + 0x8)
+
+#define MXC_SRPGC_EMI_SRPGCR (MXC_SRPGC_EMI_BASE + 0x0)
+#define MXC_SRPGC_EMI_PUPSCR (MXC_SRPGC_EMI_BASE + 0x4)
+#define MXC_SRPGC_EMI_PDNSCR (MXC_SRPGC_EMI_BASE + 0x8)
+
+#endif /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
new file mode 100644
index 00000000000..d6fd3961ade
--- /dev/null
+++ b/arch/arm/mach-mx5/devices.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.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/platform_device.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+
+static struct resource uart0[] = {
+ {
+ .start = MX51_UART1_BASE_ADDR,
+ .end = MX51_UART1_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX51_MXC_INT_UART1,
+ .end = MX51_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 = MX51_UART2_BASE_ADDR,
+ .end = MX51_UART2_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX51_MXC_INT_UART2,
+ .end = MX51_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 = MX51_UART3_BASE_ADDR,
+ .end = MX51_UART3_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX51_MXC_INT_UART3,
+ .end = MX51_MXC_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 mxc_fec_resources[] = {
+ {
+ .start = MX51_MXC_FEC_BASE_ADDR,
+ .end = MX51_MXC_FEC_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX51_MXC_INT_FEC,
+ .end = MX51_MXC_INT_FEC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_fec_device = {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_fec_resources),
+ .resource = mxc_fec_resources,
+};
+
+/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */
+int __init mxc_register_gpios(void)
+{
+ return 0;
+}
diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
new file mode 100644
index 00000000000..f339ab8c19b
--- /dev/null
+++ b/arch/arm/mach-mx5/devices.h
@@ -0,0 +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_fec_device;
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
new file mode 100644
index 00000000000..b7677ef80cc
--- /dev/null
+++ b/arch/arm/mach-mx5/mm.c
@@ -0,0 +1,83 @@
+/*
+ * 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
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-v3.h>
+
+/*
+ * Define the MX51 memory map.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+ {
+ .virtual = MX51_IRAM_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX51_IRAM_BASE_ADDR),
+ .length = MX51_IRAM_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = MX51_DEBUG_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
+ .length = MX51_DEBUG_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = MX51_AIPS1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
+ .length = MX51_AIPS1_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = MX51_SPBA0_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX51_SPBA0_BASE_ADDR),
+ .length = MX51_SPBA0_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = MX51_AIPS2_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
+ .length = MX51_AIPS2_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx51_map_io(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX51);
+ mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
+ iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
+
+void __init mx51_init_irq(void)
+{
+ unsigned long tzic_addr;
+ void __iomem *tzic_virt;
+
+ if (mx51_revision() < MX51_CHIP_REV_2_0)
+ tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
+ else
+ tzic_addr = MX51_TZIC_BASE_ADDR;
+
+ tzic_virt = ioremap(tzic_addr, SZ_16K);
+ if (!tzic_virt)
+ panic("unable to map TZIC interrupt controller\n");
+
+ tzic_init_irq(tzic_virt);
+}
diff --git a/arch/arm/mach-mxc91231/magx-zn5.c b/arch/arm/mach-mxc91231/magx-zn5.c
index 7dbe4ca12ef..69816ba8293 100644
--- a/arch/arm/mach-mxc91231/magx-zn5.c
+++ b/arch/arm/mach-mxc91231/magx-zn5.c
@@ -55,7 +55,7 @@ struct sys_timer zn5_timer = {
MACHINE_START(MAGX_ZN5, "Motorola Zn5")
.phys_io = MXC91231_AIPS1_BASE_ADDR,
.io_pg_offst = ((MXC91231_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = MXC91231_PHYS_OFFSET + 0x100,
.map_io = mxc91231_map_io,
.init_irq = mxc91231_init_irq,
.timer = &zn5_timer,
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c
index 1d844e228ea..5b84bcd3027 100644
--- a/arch/arm/mach-netx/fb.c
+++ b/arch/arm/mach-netx/fb.c
@@ -23,6 +23,7 @@
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/err.h>
+#include <linux/gfp.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c
index 181a78ba816..f009b54e8d2 100644
--- a/arch/arm/mach-netx/xc.c
+++ b/arch/arm/mach-netx/xc.c
@@ -21,6 +21,7 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index 9438bf6613a..ab3712c86d2 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -38,7 +38,7 @@
#define SRC_CR_INIT_MASK 0x00007fff
#define SRC_CR_INIT_VAL 0x2aaa8000
-/* These adresses span 16MB, so use three individual pages */
+/* These addresses span 16MB, so use three individual pages */
static struct resource nhk8815_nand_resources[] = {
{
.name = "nand_addr",
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c
index 9a09b2791e0..66b1c91ccc7 100644
--- a/arch/arm/mach-nomadik/gpio.c
+++ b/arch/arm/mach-nomadik/gpio.c
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
diff --git a/arch/arm/mach-ns9xxx/plat-serial8250.c b/arch/arm/mach-ns9xxx/plat-serial8250.c
index 795b15e8982..463e92465fd 100644
--- a/arch/arm/mach-ns9xxx/plat-serial8250.c
+++ b/arch/arm/mach-ns9xxx/plat-serial8250.c
@@ -10,6 +10,7 @@
*/
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
+#include <linux/slab.h>
#include <mach/regs-board-a9m9750dev.h>
#include <mach/board.h>
diff --git a/arch/arm/mach-ns9xxx/processor-ns9360.c b/arch/arm/mach-ns9xxx/processor-ns9360.c
index abee8338735..aed1999d24f 100644
--- a/arch/arm/mach-ns9xxx/processor-ns9360.c
+++ b/arch/arm/mach-ns9xxx/processor-ns9360.c
@@ -10,7 +10,6 @@
*/
#include <linux/io.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <asm/page.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index f9a5cf750b5..e9bdff192f8 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <mach/irqs.h>
#include <plat/dma.h>
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 9ad118563f7..20cfbcc6c60 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -68,12 +68,6 @@ struct sys_timer omap_timer;
* ---------------------------------------------------------------------------
*/
-#if defined(CONFIG_ARCH_OMAP16XX)
-#define TIMER_32K_SYNCHRONIZED 0xfffbc410
-#else
-#error OMAP 32KHz timer does not currently work on 15XX!
-#endif
-
/* 16xx specific defines */
#define OMAP1_32K_TIMER_BASE 0xfffb9000
#define OMAP1_32K_TIMER_CR 0x08
@@ -150,15 +144,6 @@ static struct clock_event_device clockevent_32k_timer = {
.set_mode = omap_32k_timer_set_mode,
};
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
- return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = &clockevent_32k_timer;
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index a8a3d1e23e2..2455dcc744a 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -59,8 +59,10 @@ config MACH_OMAP3_BEAGLE
select OMAP_PACKAGE_CBB
config MACH_DEVKIT8000
- bool "DEVKIT8000 board"
- depends on ARCH_OMAP3
+ bool "DEVKIT8000 board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CUS
+ select OMAP_MUX
config MACH_OMAP_LDP
bool "OMAP3 LDP board"
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 2069fb33baa..4b9fc57770d 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -22,6 +22,9 @@ 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_ARCH_OMAP4) += omap44xx-smc.o
+
+AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a
# Functions loaded to SRAM
obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index a101029ceb6..5822bcf7b15 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -648,7 +648,7 @@ static void enable_board_wakeup_source(void)
OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
}
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 4386d2b4a78..504d2bd222f 100755..100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -54,7 +54,7 @@ static void enable_board_wakeup_source(void)
OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
}
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -96,6 +96,7 @@ static struct omap_board_mux board_mux[] __initdata = {
static void __init omap_sdp_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+ omap_serial_init();
zoom_peripherals_init();
board_smc91x_init();
enable_board_wakeup_source();
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 180ac112e52..b88f28c5814 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -50,33 +50,9 @@ static struct omap_board_config_kernel sdp4430_config[] __initdata = {
};
#ifdef CONFIG_CACHE_L2X0
-noinline void omap_smc1(u32 fn, u32 arg)
-{
- register u32 r12 asm("r12") = fn;
- register u32 r0 asm("r0") = arg;
-
- /* This is common routine cache secure monitor API used to
- * modify the PL310 secure registers.
- * r0 contains the value to be modified and "r12" contains
- * the monitor API number. It uses few CPU registers
- * internally and hence they need be backed up including
- * link register "lr".
- * Explicitly save r11 and r12 the compiler generated code
- * won't save it.
- */
- asm volatile(
- "stmfd r13!, {r11,r12}\n"
- "dsb\n"
- "smc\n"
- "ldmfd r13!, {r11,r12}\n"
- : "+r" (r0), "+r" (r12)
- :
- : "r4", "r5", "r10", "lr", "cc");
-}
-EXPORT_SYMBOL(omap_smc1);
-
static int __init omap_l2_cache_init(void)
{
+ extern void omap_smc1(u32 fn, u32 arg);
void __iomem *l2cache_base;
/* To avoid code running on other OMAPs in
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 70c18614773..c1c4389fbd8 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -273,7 +273,7 @@ static void __init am3517_evm_init_irq(void)
omap_gpio_init();
}
-static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
@@ -294,9 +294,9 @@ static struct omap_board_mux board_mux[] __initdata = {
static void __init am3517_evm_init(void)
{
- am3517_evm_i2c_init();
-
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ am3517_evm_i2c_init();
platform_add_devices(am3517_evm_devices,
ARRAY_SIZE(am3517_evm_devices));
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index afa77caaff4..2de4f79f03a 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -612,7 +612,7 @@ static struct omap2_hsmmc_info mmc[] = {
{} /* Terminator */
};
-static struct ehci_hcd_omap_platform_data ehci_pdata = {
+static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 371019054b4..47e3af2166d 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -50,7 +50,6 @@
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
-#include <linux/usb/otg.h>
#include <linux/dm9000.h>
#include <linux/interrupt.h>
@@ -269,20 +268,6 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
devkit8000_vmmc1_supply.dev = mmc[0].dev;
devkit8000_vsim_supply.dev = mmc[0].dev;
- /* REVISIT: need ehci-omap hooks for external VBUS
- * power switch and overcurrent detect
- */
-
- gpio_request(gpio + 1, "EHCI_nOC");
- gpio_direction_input(gpio + 1);
-
- /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
- gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
-
- /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
- gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
-
return 0;
}
@@ -303,7 +288,7 @@ static struct regulator_consumer_supply devkit8000_vpll2_supplies[] = {
.dev = &devkit8000_lcd_device.dev,
},
{
- .supply = "vdss_dsi",
+ .supply = "vdds_dsi",
.dev = &devkit8000_dss_device.dev,
}
};
@@ -636,20 +621,24 @@ static struct omap_musb_board_data musb_board_data = {
.power = 100,
};
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
- .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+ .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.phy_reset = true,
.reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = 147,
+ .reset_gpio_port[1] = -EINVAL,
.reset_gpio_port[2] = -EINVAL
};
static void __init devkit8000_init(void)
{
+ omap_serial_init();
+
+ omap_dm9000_init();
+
devkit8000_i2c_init();
platform_add_devices(devkit8000_devices,
ARRAY_SIZE(devkit8000_devices));
@@ -659,25 +648,15 @@ static void __init devkit8000_init(void)
spi_register_board_info(devkit8000_spi_board_info,
ARRAY_SIZE(devkit8000_spi_board_info));
- omap_serial_init();
-
- omap_dm9000_init();
-
devkit8000_ads7846_init();
- omap_mux_init_gpio(170, OMAP_PIN_INPUT);
-
- gpio_request(170, "DVI_nPD");
- /* REVISIT leave DVI powered down until it's needed ... */
- gpio_direction_output(170, true);
-
usb_musb_init(&musb_board_data);
usb_ehci_init(&ehci_pdata);
devkit8000_flash_init();
/* Ensure SDRC pins are mux'd for self-refresh */
- omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT);
- omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
}
static void __init devkit8000_map_io(void)
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 9958987a3d0..d55c57b761a 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -16,7 +16,6 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/gpio.h>
-#include <linux/leds.h>
#include <linux/interrupt.h>
#include <linux/regulator/machine.h>
@@ -39,8 +38,8 @@
#define IGEP2_SMSC911X_CS 5
#define IGEP2_SMSC911X_GPIO 176
#define IGEP2_GPIO_USBH_NRESET 24
-#define IGEP2_GPIO_LED0_RED 26
-#define IGEP2_GPIO_LED0_GREEN 27
+#define IGEP2_GPIO_LED0_GREEN 26
+#define IGEP2_GPIO_LED0_RED 27
#define IGEP2_GPIO_LED1_RED 28
#define IGEP2_GPIO_DVI_PUP 170
#define IGEP2_GPIO_WIFI_NPD 94
@@ -355,34 +354,50 @@ static void __init igep2_display_init(void)
gpio_direction_output(IGEP2_GPIO_DVI_PUP, 1))
pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
}
-#ifdef CONFIG_LEDS_TRIGGERS
-static struct gpio_led gpio_leds[] = {
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep2_gpio_leds[] = {
{
- .name = "GPIO_LED1_RED",
+ .name = "led0:red",
+ .gpio = IGEP2_GPIO_LED0_RED,
+ },
+ {
+ .name = "led0:green",
.default_trigger = "heartbeat",
+ .gpio = IGEP2_GPIO_LED0_GREEN,
+ },
+ {
+ .name = "led1:red",
.gpio = IGEP2_GPIO_LED1_RED,
},
};
-static struct gpio_led_platform_data gpio_leds_info = {
- .leds = gpio_leds,
- .num_leds = ARRAY_SIZE(gpio_leds),
+static struct gpio_led_platform_data igep2_led_pdata = {
+ .leds = igep2_gpio_leds,
+ .num_leds = ARRAY_SIZE(igep2_gpio_leds),
};
-static struct platform_device leds_gpio = {
+static struct platform_device igep2_led_device = {
.name = "leds-gpio",
.id = -1,
.dev = {
- .platform_data = &gpio_leds_info,
+ .platform_data = &igep2_led_pdata,
},
};
+
+static void __init igep2_init_led(void)
+{
+ platform_device_register(&igep2_led_device);
+}
+
+#else
+static inline void igep2_init_led(void) {}
#endif
static struct platform_device *igep2_devices[] __initdata = {
&igep2_dss_device,
-#ifdef CONFIG_LEDS_TRIGGERS
- &leds_gpio,
-#endif
};
static void __init igep2_init_irq(void)
@@ -442,14 +457,14 @@ static struct omap_musb_board_data musb_board_data = {
.power = 100,
};
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
- .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
- .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+ .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+ .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.phy_reset = true,
- .reset_gpio_port[0] = -EINVAL,
- .reset_gpio_port[1] = IGEP2_GPIO_USBH_NRESET,
+ .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
+ .reset_gpio_port[1] = -EINVAL,
.reset_gpio_port[2] = -EINVAL,
};
@@ -471,31 +486,34 @@ static void __init igep2_init(void)
usb_ehci_init(&ehci_pdata);
igep2_flash_init();
+ igep2_init_led();
igep2_display_init();
igep2_init_smsc911x();
/* GPIO userspace leds */
- if ((gpio_request(IGEP2_GPIO_LED0_RED, "GPIO_LED0_RED") == 0) &&
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+ if ((gpio_request(IGEP2_GPIO_LED0_RED, "led0:red") == 0) &&
(gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
gpio_export(IGEP2_GPIO_LED0_RED, 0);
gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
} else
pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
- if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "GPIO_LED0_GREEN") == 0) &&
+ if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "led0:green") == 0) &&
(gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
} else
pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
-#ifndef CONFIG_LEDS_TRIGGERS
- if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_LED1_RED") == 0) &&
+
+ if ((gpio_request(IGEP2_GPIO_LED1_RED, "led1:red") == 0) &&
(gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
gpio_export(IGEP2_GPIO_LED1_RED, 0);
gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
} else
pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
#endif
+
/* GPIO W-LAN + Bluetooth combo module */
if ((gpio_request(IGEP2_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
(gpio_direction_output(IGEP2_GPIO_WIFI_NPD, 1) == 0)) {
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 4cab0522d7c..3ccc34ebdcc 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -37,6 +37,103 @@ static int slot1_cover_open;
static int slot2_cover_open;
static struct device *mmc_device;
+#define TUSB6010_ASYNC_CS 1
+#define TUSB6010_SYNC_CS 4
+#define TUSB6010_GPIO_INT 58
+#define TUSB6010_GPIO_ENABLE 0
+#define TUSB6010_DMACHAN 0x3f
+
+#if defined(CONFIG_USB_TUSB6010) || \
+ defined(CONFIG_USB_TUSB6010_MODULE)
+/*
+ * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
+ * 1.5 V voltage regulators of PM companion chip. Companion chip will then
+ * provide then PGOOD signal to TUSB6010 which will release it from reset.
+ */
+static int tusb_set_power(int state)
+{
+ int i, retval = 0;
+
+ if (state) {
+ gpio_set_value(TUSB6010_GPIO_ENABLE, 1);
+ msleep(1);
+
+ /* Wait until TUSB6010 pulls INT pin down */
+ i = 100;
+ while (i && gpio_get_value(TUSB6010_GPIO_INT)) {
+ msleep(1);
+ i--;
+ }
+
+ if (!i) {
+ printk(KERN_ERR "tusb: powerup failed\n");
+ retval = -ENODEV;
+ }
+ } else {
+ gpio_set_value(TUSB6010_GPIO_ENABLE, 0);
+ msleep(10);
+ }
+
+ return retval;
+}
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .num_eps = 16,
+ .ram_bits = 12,
+};
+
+static struct musb_hdrc_platform_data tusb_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+ .mode = MUSB_PERIPHERAL,
+#else /* defined(CONFIG_USB_MUSB_HOST) */
+ .mode = MUSB_HOST,
+#endif
+ .set_power = tusb_set_power,
+ .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */
+ .power = 100, /* Max 100 mA VBUS for host mode */
+ .config = &musb_config,
+};
+
+static void __init n8x0_usb_init(void)
+{
+ int ret = 0;
+ static char announce[] __initdata = KERN_INFO "TUSB 6010\n";
+
+ /* PM companion chip power control pin */
+ ret = gpio_request(TUSB6010_GPIO_ENABLE, "TUSB6010 enable");
+ if (ret != 0) {
+ printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
+ TUSB6010_GPIO_ENABLE);
+ return;
+ }
+ gpio_direction_output(TUSB6010_GPIO_ENABLE, 0);
+
+ tusb_set_power(0);
+
+ ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
+ TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
+ TUSB6010_GPIO_INT, TUSB6010_DMACHAN);
+ if (ret != 0)
+ goto err;
+
+ printk(announce);
+
+ return;
+
+err:
+ gpio_free(TUSB6010_GPIO_ENABLE);
+}
+#else
+
+static void __init n8x0_usb_init(void) {}
+
+#endif /*CONFIG_USB_TUSB6010 */
+
+
static struct omap2_mcspi_device_config p54spi_mcspi_config = {
.turbo_mode = 0,
.single_channel = 1,
@@ -119,7 +216,7 @@ static void __init n8x0_onenand_init(void) {}
*/
#define N8X0_SLOT_SWITCH_GPIO 96
#define N810_EMMC_VSD_GPIO 23
-#define NN810_EMMC_VIO_GPIO 9
+#define N810_EMMC_VIO_GPIO 9
static int n8x0_mmc_switch_slot(struct device *dev, int slot)
{
@@ -207,10 +304,10 @@ static void n810_set_power_emmc(struct device *dev,
if (power_on) {
gpio_set_value(N810_EMMC_VSD_GPIO, 1);
msleep(1);
- gpio_set_value(NN810_EMMC_VIO_GPIO, 1);
+ gpio_set_value(N810_EMMC_VIO_GPIO, 1);
msleep(1);
} else {
- gpio_set_value(NN810_EMMC_VIO_GPIO, 0);
+ gpio_set_value(N810_EMMC_VIO_GPIO, 0);
msleep(50);
gpio_set_value(N810_EMMC_VSD_GPIO, 0);
msleep(50);
@@ -371,7 +468,7 @@ static void n8x0_mmc_cleanup(struct device *dev)
if (machine_is_nokia_n810()) {
gpio_free(N810_EMMC_VSD_GPIO);
- gpio_free(NN810_EMMC_VIO_GPIO);
+ gpio_free(N810_EMMC_VIO_GPIO);
}
}
@@ -432,7 +529,7 @@ void __init n8x0_mmc_init(void)
err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch");
if (err)
- return err;
+ return;
gpio_direction_output(N8X0_SLOT_SWITCH_GPIO, 0);
@@ -440,17 +537,17 @@ void __init n8x0_mmc_init(void)
err = gpio_request(N810_EMMC_VSD_GPIO, "MMC slot 2 Vddf");
if (err) {
gpio_free(N8X0_SLOT_SWITCH_GPIO);
- return err;
+ return;
}
gpio_direction_output(N810_EMMC_VSD_GPIO, 0);
- err = gpio_request(NN810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
+ err = gpio_request(N810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
if (err) {
gpio_free(N8X0_SLOT_SWITCH_GPIO);
gpio_free(N810_EMMC_VSD_GPIO);
- return err;
+ return;
}
- gpio_direction_output(NN810_EMMC_VIO_GPIO, 0);
+ gpio_direction_output(N810_EMMC_VIO_GPIO, 0);
}
mmc_data[0] = &mmc1_data;
@@ -562,6 +659,7 @@ static void __init n8x0_init_machine(void)
n8x0_menelaus_init();
n8x0_onenand_init();
n8x0_mmc_init();
+ n8x0_usb_init();
}
MACHINE_START(NOKIA_N800, "Nokia N800")
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 6eb77e1f7c8..962d377970e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -410,7 +410,7 @@ static void __init omap3beagle_flash_init(void)
}
}
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index d6bc88c426b..017bb2f4f7d 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -635,7 +635,7 @@ static struct platform_device *omap3_evm_devices[] __initdata = {
&omap3_evm_dss_device,
};
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 4827f4658df..395d049bf01 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -459,12 +459,20 @@ static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = {
},
};
+static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("bq27500", 0x55),
+ .flags = I2C_CLIENT_WAKE,
+ },
+};
+
static int __init omap3pandora_i2c_init(void)
{
omap_register_i2c_bus(1, 2600, omap3pandora_i2c_boardinfo,
ARRAY_SIZE(omap3pandora_i2c_boardinfo));
/* i2c2 pins are not connected */
- omap_register_i2c_bus(3, 100, NULL, 0);
+ omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo,
+ ARRAY_SIZE(omap3pandora_i2c3_boardinfo));
return 0;
}
@@ -537,7 +545,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
&pandora_dss_device,
};
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 3943d0f8322..2504d41f923 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -493,7 +493,7 @@ static void __init omap3touchbook_flash_init(void)
}
}
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -518,14 +518,14 @@ static void omap3_touchbook_poweroff(void)
gpio_direction_output(TB_KILL_POWER_GPIO, 0);
}
-static void __init early_touchbook_revision(char **p)
+static int __init early_touchbook_revision(char *p)
{
- if (!*p)
- return;
+ if (!p)
+ return 0;
- strict_strtoul(*p, 10, &touchbook_revision);
+ return strict_strtoul(p, 10, &touchbook_revision);
}
-__early_param("tbr=", early_touchbook_revision);
+early_param("tbr", early_touchbook_revision);
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_ULPI,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 50872a42bec..8848c7c5ce4 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -394,7 +394,7 @@ static struct platform_device *overo_devices[] __initdata = {
&overo_lcd_device,
};
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
diff --git a/arch/arm/mach-omap2/board-sdp-flash.c b/arch/arm/mach-omap2/board-sdp-flash.c
index b1b88deec7f..2d026328e38 100644
--- a/arch/arm/mach-omap2/board-sdp-flash.c
+++ b/arch/arm/mach-omap2/board-sdp-flash.c
@@ -253,20 +253,20 @@ void __init sdp_flash_init(struct flash_partitions sdp_partition_info[])
}
if (norcs > GPMC_CS_NUM)
- printk(KERN_INFO "OneNAND: Unable to find configuration "
- " in GPMC\n ");
+ printk(KERN_INFO "NOR: Unable to find configuration "
+ "in GPMC\n");
else
board_nor_init(sdp_partition_info[0], norcs);
if (onenandcs > GPMC_CS_NUM)
printk(KERN_INFO "OneNAND: Unable to find configuration "
- " in GPMC\n ");
+ "in GPMC\n");
else
board_onenand_init(sdp_partition_info[1], onenandcs);
if (nandcs > GPMC_CS_NUM)
printk(KERN_INFO "NAND: Unable to find configuration "
- " in GPMC\n ");
+ "in GPMC\n");
else
board_nand_init(sdp_partition_info[2], nandcs);
}
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
index bb4018b6064..e15d2e87cfc 100644
--- a/arch/arm/mach-omap2/board-zoom-debugboard.c
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -96,7 +96,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
static struct platform_device zoom_debugboard_serial_device = {
.name = "serial8250",
- .id = 3,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index ca95d8d6413..6b3984964cc 100755..100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -280,7 +280,6 @@ static void enable_board_wakeup_source(void)
void __init zoom_peripherals_init(void)
{
omap_i2c_init();
- omap_serial_init();
usb_musb_init(&musb_board_data);
enable_board_wakeup_source();
}
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index d3e3cd5170d..cd3e40cf3ac 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -52,7 +52,7 @@ static struct omap_board_mux board_mux[] __initdata = {
#define board_mux NULL
#endif
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index 3b1eac4d539..e60ca4e47bb 100644
--- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -31,6 +31,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/cpufreq.h>
+#include <linux/slab.h>
#include <plat/clock.h>
#include <plat/sram.h>
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index fc55ab4c32e..1820a556361 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1841,6 +1841,7 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "aes_ick", &aes_ick, CK_242X),
CLK(NULL, "pka_ick", &pka_ick, CK_242X),
CLK(NULL, "usb_fck", &usb_fck, CK_242X),
+ CLK("musb_hdrc", "fck", &osc_ck, CK_242X),
};
/*
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 5a974dcbcec..52638df1545 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -895,7 +895,7 @@ static struct clk dpll4_m4x2_ck = {
.ops = &clkops_omap2_dflt_wait,
.parent = &dpll4_m4_ck,
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
- .enable_bit = OMAP3430_PWRDN_CAM_SHIFT,
+ .enable_bit = OMAP3430_PWRDN_DSS1_SHIFT,
.flags = INVERT_ENABLE,
.clkdm_name = "dpll4_clkdm",
.recalc = &omap3_clkoutx2_recalc,
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 28b107967c8..a5c0c9c8e49 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -2671,10 +2671,10 @@ static struct omap_clk omap44xx_clks[] = {
CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_443X),
CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_443X),
CLK("omap-mcbsp.4", "ick", &dummy_ck, CK_443X),
- CLK("omap-mcspi.1", "ick", &dummy_ck, CK_443X),
- CLK("omap-mcspi.2", "ick", &dummy_ck, CK_443X),
- CLK("omap-mcspi.3", "ick", &dummy_ck, CK_443X),
- CLK("omap-mcspi.4", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.1", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_443X),
CLK(NULL, "uart1_ick", &dummy_ck, CK_443X),
CLK(NULL, "uart2_ick", &dummy_ck, CK_443X),
CLK(NULL, "uart3_ick", &dummy_ck, CK_443X),
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index b87ad66f083..6e568ec995e 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -240,7 +240,7 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
bits = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
else
bits = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
- } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+ } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
if (enable)
bits = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
else
@@ -812,7 +812,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
- } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+ } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
__ffs(clkdm->clktrctrl_mask));
@@ -856,7 +856,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
- } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+ } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
__ffs(clkdm->clktrctrl_mask));
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 7e7acc19bed..beac46c48c5 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -764,7 +764,7 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
if (!cpu_is_omap44xx())
return;
base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET;
- irq = OMAP44XX_IRQ_MMC4;
+ irq = OMAP44XX_IRQ_MMC5;
break;
default:
continue;
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 64d74f05abb..e57fb29ff85 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -39,6 +39,9 @@ static int omap2_nand_gpmc_retime(void)
struct gpmc_timings t;
int err;
+ if (!gpmc_nand_data->gpmc_t)
+ return 0;
+
memset(&t, 0, sizeof(t));
t.sync_clk = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->sync_clk);
t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on);
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S
index ff25c7e4e60..50fd7491664 100644
--- a/arch/arm/mach-omap2/include/mach/entry-macro.S
+++ b/arch/arm/mach-omap2/include/mach/entry-macro.S
@@ -52,7 +52,7 @@ omap_irq_base: .word 0
mrc p15, 0, \tmp, c0, c0, 0 @ get processor revision
and \tmp, \tmp, #0x000f0000 @ only check architecture
- cmp \tmp, #0x00060000 @ is v6?
+ cmp \tmp, #0x00070000 @ is v6?
beq 2400f @ found v6 so it's omap24xx
mrc p15, 0, \tmp, c0, c0, 0 @ get processor revision
and \tmp, \tmp, #0x000000f0 @ check cortex 8 or 9
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 402e8f0d0f2..87f676acf61 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -237,7 +237,7 @@ static void __init _omap2_map_common_io(void)
}
#ifdef CONFIG_ARCH_OMAP2420
-void __init omap242x_map_common_io()
+void __init omap242x_map_common_io(void)
{
iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
@@ -246,7 +246,7 @@ void __init omap242x_map_common_io()
#endif
#ifdef CONFIG_ARCH_OMAP2430
-void __init omap243x_map_common_io()
+void __init omap243x_map_common_io(void)
{
iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
@@ -255,7 +255,7 @@ void __init omap243x_map_common_io()
#endif
#ifdef CONFIG_ARCH_OMAP3
-void __init omap34xx_map_common_io()
+void __init omap34xx_map_common_io(void)
{
iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
_omap2_map_common_io();
@@ -263,7 +263,7 @@ void __init omap34xx_map_common_io()
#endif
#ifdef CONFIG_ARCH_OMAP4
-void __init omap44xx_map_common_io()
+void __init omap44xx_map_common_io(void)
{
iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
_omap2_map_common_io();
@@ -309,7 +309,6 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
{
pwrdm_init(powerdomains_omap);
clkdm_init(clockdomains_omap, clkdm_autodeps);
-#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
if (cpu_is_omap242x())
omap2420_hwmod_init();
else if (cpu_is_omap243x())
@@ -319,7 +318,6 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
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);
-#endif
if (cpu_is_omap2420())
omap2420_clk_init();
@@ -333,11 +331,12 @@ 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_ARCH_OMAP4
- omap_hwmod_late_init();
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */
+ omap_hwmod_late_init();
omap_pm_if_init();
- omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
- _omap2_init_reprogram_sdrc();
-#endif
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+ omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
+ _omap2_init_reprogram_sdrc();
+ }
gpmc_init();
}
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index 6f4b7cc8f4d..4f63dc6859a 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/stringify.h>
#include <plat/iommu.h>
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index 52a981cb8fd..318f3638653 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -430,19 +430,19 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
if (unlikely(!res)) {
dev_err(&pdev->dev, "invalid irq resource\n");
ret = -ENODEV;
- goto err_iva1;
+ omap_mbox_unregister(&mbox_dsp_info);
+ goto err_dsp;
}
mbox_iva_info.irq = res->start;
ret = omap_mbox_register(&pdev->dev, &mbox_iva_info);
- if (ret)
- goto err_iva1;
+ if (ret) {
+ omap_mbox_unregister(&mbox_dsp_info);
+ goto err_dsp;
+ }
}
#endif
return 0;
-err_iva1:
- omap_mbox_unregister(&mbox_dsp_info);
-
err_dsp:
iounmap(mbox_base);
return ret;
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index be8fce395a5..2f3cad6f940 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <mach/irqs.h>
#include <plat/dma.h>
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index b4ca84ee0a9..8b3d26935a3 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/ctype.h>
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index aa3f65c2ac9..ef0e7a00dd6 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -33,7 +33,7 @@
ENTRY(omap_secondary_startup)
hold: ldr r12,=0x103
dsb
- smc @ read from AuxCoreBoot0
+ smc #0 @ read from AuxCoreBoot0
mov r0, r0, lsr #9
mrc p15, 0, r4, c0, c0, 5
and r4, r4, #0x0f
@@ -52,7 +52,7 @@ ENTRY(omap_modify_auxcoreboot0)
stmfd sp!, {r1-r12, lr}
ldr r12, =0x104
dsb
- smc
+ smc #0
ldmfd sp!, {r1-r12, pc}
END(omap_modify_auxcoreboot0)
@@ -60,6 +60,6 @@ ENTRY(omap_auxcoreboot_addr)
stmfd sp!, {r2-r12, lr}
ldr r12, =0x105
dsb
- smc
+ smc #0
ldmfd sp!, {r2-r12, pc}
END(omap_auxcoreboot_addr)
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S
new file mode 100644
index 00000000000..f61c7771ca4
--- /dev/null
+++ b/arch/arm/mach-omap2/omap44xx-smc.S
@@ -0,0 +1,32 @@
+/*
+ * OMAP44xx secure APIs file.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@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/linkage.h>
+
+/*
+ * This is common routine to manage secure monitor API
+ * used to modify the PL310 secure registers.
+ * 'r0' contains the value to be modified and 'r12' contains
+ * the monitor API number. It uses few CPU registers
+ * internally and hence they need be backed up including
+ * link register "lr".
+ * Function signature : void omap_smc1(u32 fn, u32 arg)
+ */
+
+ENTRY(omap_smc1)
+ stmfd sp!, {r2-r12, lr}
+ mov r12, r0
+ mov r0, r1
+ dsb
+ smc #0
+ ldmfd sp!, {r2-r12, pc}
+END(omap_smc1)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index c6649472ce0..e436dcb1979 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1511,6 +1511,9 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
c = oh->slaves[oh->_mpu_port_index]->_clk;
}
+ if (!c->clkdm)
+ return NULL;
+
return c->clkdm->pwrdm.ptr;
}
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index c18f7f2f19b..6cac9817c24 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <plat/clock.h>
#include <plat/board.h>
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fee2efb172e..ea0000bc535 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -27,6 +27,7 @@
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <plat/sram.h>
#include <plat/clockdomain.h>
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 9a0fb385622..ebfce7d1a5d 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -222,7 +222,7 @@ void pwrdm_init(struct powerdomain **pwrdm_list)
{
struct powerdomain **p = NULL;
- if (cpu_is_omap24xx() | cpu_is_omap34xx()) {
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL;
pwrstst_reg_offs = OMAP2_PM_PWSTST;
} else if (cpu_is_omap44xx()) {
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 81872aacb80..07a60f1204c 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -123,7 +123,7 @@ struct omap3_prcm_regs prcm_context;
u32 omap_prcm_get_reset_sources(void)
{
/* XXX This presumably needs modification for 34XX */
- if (cpu_is_omap24xx() | cpu_is_omap34xx())
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
if (cpu_is_omap44xx())
return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
@@ -133,7 +133,7 @@ u32 omap_prcm_get_reset_sources(void)
EXPORT_SYMBOL(omap_prcm_get_reset_sources);
/* Resets clock rates and reboots the system. Only called from system.h */
-void omap_prcm_arch_reset(char mode)
+void omap_prcm_arch_reset(char mode, const char *cmd)
{
s16 prcm_offs = 0;
@@ -145,7 +145,7 @@ void omap_prcm_arch_reset(char mode)
u32 l;
prcm_offs = OMAP3430_GR_MOD;
- l = ('B' << 24) | ('M' << 16) | mode;
+ l = ('B' << 24) | ('M' << 16) | (cmd ? (u8)*cmd : 0);
/* Reserve the first word in scratchpad for communicating
* with the boot ROM. A pointer to a data structure
* describing the boot process can be stored there,
@@ -157,7 +157,7 @@ void omap_prcm_arch_reset(char mode)
else
WARN_ON(1);
- if (cpu_is_omap24xx() | cpu_is_omap34xx())
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs,
OMAP2_RM_RSTCTRL);
if (cpu_is_omap44xx())
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index b79bc8926cc..3771254dfa8 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -115,7 +115,6 @@ static struct plat_serial8250_port serial_platform_data2[] = {
}
};
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
static struct plat_serial8250_port serial_platform_data3[] = {
{
.irq = 70,
@@ -128,23 +127,12 @@ static struct plat_serial8250_port serial_platform_data3[] = {
}
};
-static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
-{
- serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
-}
-#else
-static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
-{
-}
-#endif
-
void __init omap2_set_globals_uart(struct omap_globals *omap2_globals)
{
serial_platform_data0[0].mapbase = omap2_globals->uart1_phys;
serial_platform_data1[0].mapbase = omap2_globals->uart2_phys;
serial_platform_data2[0].mapbase = omap2_globals->uart3_phys;
- if (cpu_is_omap3630() || cpu_is_omap44xx())
- omap2_set_globals_uart4(omap2_globals);
+ serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
}
static inline unsigned int __serial_read_reg(struct uart_port *up,
@@ -550,7 +538,7 @@ static ssize_t sleep_timeout_store(struct device *dev,
unsigned int value;
if (sscanf(buf, "%u", &value) != 1) {
- printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
+ dev_err(dev, "sleep_timeout_store: Invalid value\n");
return -EINVAL;
}
@@ -644,42 +632,53 @@ static void serial_out_override(struct uart_port *up, int offset, int value)
}
void __init omap_serial_early_init(void)
{
- int i;
+ int i, nr_ports;
char name[16];
+ if (!(cpu_is_omap3630() || cpu_is_omap4430()))
+ nr_ports = 3;
+ else
+ nr_ports = ARRAY_SIZE(omap_uart);
+
/*
* 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.
*/
- for (i = 0; i < ARRAY_SIZE(omap_uart); i++) {
+ for (i = 0; i < nr_ports; i++) {
struct omap_uart_state *uart = &omap_uart[i];
struct platform_device *pdev = &uart->pdev;
struct device *dev = &pdev->dev;
struct plat_serial8250_port *p = dev->platform_data;
+ /* Don't map zero-based physical address */
+ if (p->mapbase == 0) {
+ dev_warn(dev, "no physical address for uart#%d,"
+ " so skipping early_init...\n", i);
+ continue;
+ }
/*
* Module 4KB + L4 interconnect 4KB
* Static mapping, never released
*/
p->membase = ioremap(p->mapbase, SZ_8K);
if (!p->membase) {
- printk(KERN_ERR "ioremap failed for uart%i\n", i + 1);
+ dev_err(dev, "ioremap failed for uart%i\n", i + 1);
continue;
}
- sprintf(name, "uart%d_ick", i+1);
+ sprintf(name, "uart%d_ick", i + 1);
uart->ick = clk_get(NULL, name);
if (IS_ERR(uart->ick)) {
- printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
+ dev_err(dev, "Could not get uart%d_ick\n", i + 1);
uart->ick = NULL;
}
sprintf(name, "uart%d_fck", i+1);
uart->fck = clk_get(NULL, name);
if (IS_ERR(uart->fck)) {
- printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
+ dev_err(dev, "Could not get uart%d_fck\n", i + 1);
uart->fck = NULL;
}
@@ -722,6 +721,13 @@ void __init omap_serial_init_port(int port)
pdev = &uart->pdev;
dev = &pdev->dev;
+ /* Don't proceed if there's no clocks available */
+ if (unlikely(!uart->ick || !uart->fck)) {
+ WARN(1, "%s: can't init uart%d, no clocks available\n",
+ kobject_name(&dev->kobj), port);
+ return;
+ }
+
omap_uart_enable_clocks(uart);
omap_uart_reset(uart);
diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c
index f1df873d59d..ee9f548d5d8 100644
--- a/arch/arm/mach-omap2/usb-ehci.c
+++ b/arch/arm/mach-omap2/usb-ehci.c
@@ -70,7 +70,7 @@ static struct platform_device ehci_device = {
/*
* setup_ehci_io_mux - initialize IO pad mux for USBHOST
*/
-static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode)
+static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode)
{
switch (port_mode[0]) {
case EHCI_HCD_OMAP_MODE_PHY:
@@ -213,7 +213,7 @@ static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode)
return;
}
-void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
+void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
{
platform_device_add_data(&ehci_device, pdata, sizeof(*pdata));
@@ -229,7 +229,7 @@ void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
#else
-void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
+void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
{
}
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index c3d513cad5a..905719a677a 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -57,6 +57,13 @@ config MACH_LINKSTATION_MINI
Say 'Y' here if you want your kernel to support the
Buffalo Linkstation Mini platform.
+config MACH_LINKSTATION_LS_HGL
+ bool "Buffalo Linkstation LS-HGL"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Linkstation LS-HGL platform.
+
config MACH_TS409
bool "QNAP TS-409"
help
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index 89772fcd65c..eb6eabcb41e 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
obj-$(CONFIG_MACH_TERASTATION_PRO2) += terastation_pro2-setup.o
obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o
obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_LS_HGL) += ls_hgl-setup.o
obj-$(CONFIG_MACH_DNS323) += dns323-setup.o
obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o
obj-$(CONFIG_MACH_TS409) += ts409-setup.o tsx09-common.o
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index f87fa125380..8dc2c76d226 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -488,7 +488,7 @@ static struct platform_device orion5x_xor0_channel = {
.dev = {
.dma_mask = &orion5x_xor_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&orion5x_xor0_data,
+ .platform_data = &orion5x_xor0_data,
},
};
@@ -514,7 +514,7 @@ static struct platform_device orion5x_xor1_channel = {
.dev = {
.dma_mask = &orion5x_xor_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
- .platform_data = (void *)&orion5x_xor1_data,
+ .platform_data = &orion5x_xor1_data,
},
};
diff --git a/arch/arm/mach-orion5x/d2net-setup.c b/arch/arm/mach-orion5x/d2net-setup.c
index 9d4bf763f25..7130904ad99 100644
--- a/arch/arm/mach-orion5x/d2net-setup.c
+++ b/arch/arm/mach-orion5x/d2net-setup.c
@@ -149,10 +149,7 @@ static void __init d2net_sata_power_init(void)
/*
* The blue front LED is wired to the CPLD and can blink in relation with the
- * SATA activity. This feature is disabled to make this LED compatible with
- * the leds-gpio driver: MPP14 and MPP15 are configured to act like output
- * GPIO's and have to stay in an active state. This is needed to set the blue
- * LED in a "fix on" state regardless of the SATA activity.
+ * SATA activity.
*
* The following array detail the different LED registers and the combination
* of their possible values:
@@ -171,12 +168,11 @@ static void __init d2net_sata_power_init(void)
#define D2NET_GPIO_RED_LED 6
#define D2NET_GPIO_BLUE_LED_BLINK_CTRL 16
#define D2NET_GPIO_BLUE_LED_OFF 23
-#define D2NET_GPIO_SATA0_ACT 14
-#define D2NET_GPIO_SATA1_ACT 15
static struct gpio_led d2net_leds[] = {
{
- .name = "d2net:blue:power",
+ .name = "d2net:blue:sata",
+ .default_trigger = "default-on",
.gpio = D2NET_GPIO_BLUE_LED_OFF,
.active_low = 1,
},
@@ -201,25 +197,22 @@ static struct platform_device d2net_gpio_leds = {
static void __init d2net_gpio_leds_init(void)
{
+ int err;
+
/* Configure GPIO over MPP max number. */
orion_gpio_set_valid(D2NET_GPIO_BLUE_LED_OFF, 1);
- if (gpio_request(D2NET_GPIO_SATA0_ACT, "LED SATA0 activity") != 0)
- return;
- if (gpio_direction_output(D2NET_GPIO_SATA0_ACT, 1) != 0)
- goto err_free_1;
- if (gpio_request(D2NET_GPIO_SATA1_ACT, "LED SATA1 activity") != 0)
- goto err_free_1;
- if (gpio_direction_output(D2NET_GPIO_SATA1_ACT, 1) != 0)
- goto err_free_2;
- platform_device_register(&d2net_gpio_leds);
- return;
+ /* Configure register blink_ctrl to allow SATA activity LED blinking. */
+ err = gpio_request(D2NET_GPIO_BLUE_LED_BLINK_CTRL, "blue LED blink");
+ if (err == 0) {
+ err = gpio_direction_output(D2NET_GPIO_BLUE_LED_BLINK_CTRL, 1);
+ if (err)
+ gpio_free(D2NET_GPIO_BLUE_LED_BLINK_CTRL);
+ }
+ if (err)
+ pr_err("d2net: failed to configure blue LED blink GPIO\n");
-err_free_2:
- gpio_free(D2NET_GPIO_SATA1_ACT);
-err_free_1:
- gpio_free(D2NET_GPIO_SATA0_ACT);
- return;
+ platform_device_register(&d2net_gpio_leds);
}
/****************************************************************************
@@ -289,8 +282,8 @@ static struct orion5x_mpp_mode d2net_mpp_modes[] __initdata = {
{ 11, MPP_UNUSED },
{ 12, MPP_GPIO }, /* SATA 1 power */
{ 13, MPP_UNUSED },
- { 14, MPP_GPIO }, /* SATA 0 active */
- { 15, MPP_GPIO }, /* SATA 1 active */
+ { 14, MPP_SATA_LED }, /* SATA 0 active */
+ { 15, MPP_SATA_LED }, /* SATA 1 active */
{ 16, MPP_GPIO }, /* Blue front LED blink control */
{ 17, MPP_UNUSED },
{ 18, MPP_GPIO }, /* Front button (0 = Released, 1 = Pushed ) */
@@ -301,6 +294,8 @@ static struct orion5x_mpp_mode d2net_mpp_modes[] __initdata = {
/* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */
};
+#define D2NET_GPIO_INHIBIT_POWER_OFF 24
+
static void __init d2net_init(void)
{
/*
@@ -333,6 +328,8 @@ static void __init d2net_init(void)
i2c_register_board_info(0, d2net_i2c_devices,
ARRAY_SIZE(d2net_i2c_devices));
+
+ orion_gpio_set_valid(D2NET_GPIO_INHIBIT_POWER_OFF, 1);
}
/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index 8f159db4d08..421b82f7c63 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -34,7 +34,8 @@
#define DNS323_GPIO_LED_RIGHT_AMBER 1
#define DNS323_GPIO_LED_LEFT_AMBER 2
#define DNS323_GPIO_SYSTEM_UP 3
-#define DNS323_GPIO_LED_POWER 5
+#define DNS323_GPIO_LED_POWER1 4
+#define DNS323_GPIO_LED_POWER2 5
#define DNS323_GPIO_OVERTEMP 6
#define DNS323_GPIO_RTC 7
#define DNS323_GPIO_POWER_OFF 8
@@ -237,11 +238,31 @@ error_fail:
* GPIO LEDs (simple - doesn't use hardware blinking support)
*/
+#define ORION_BLINK_HALF_PERIOD 100 /* ms */
+
+static int dns323_gpio_blink_set(unsigned gpio,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ static int value = 0;
+
+ if (!*delay_on && !*delay_off)
+ *delay_on = *delay_off = ORION_BLINK_HALF_PERIOD;
+
+ if (ORION_BLINK_HALF_PERIOD == *delay_on
+ && ORION_BLINK_HALF_PERIOD == *delay_off) {
+ value = !value;
+ orion_gpio_set_blink(gpio, value);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static struct gpio_led dns323_leds[] = {
{
.name = "power:blue",
- .gpio = DNS323_GPIO_LED_POWER,
- .default_state = LEDS_GPIO_DEFSTATE_ON,
+ .gpio = DNS323_GPIO_LED_POWER2,
+ .default_trigger = "timer",
}, {
.name = "right:amber",
.gpio = DNS323_GPIO_LED_RIGHT_AMBER,
@@ -256,6 +277,7 @@ static struct gpio_led dns323_leds[] = {
static struct gpio_led_platform_data dns323_led_data = {
.num_leds = ARRAY_SIZE(dns323_leds),
.leds = dns323_leds,
+ .gpio_blink_set = dns323_gpio_blink_set,
};
static struct platform_device dns323_gpio_leds = {
@@ -412,6 +434,14 @@ static void __init dns323_init(void)
orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE);
platform_device_register(&dns323_nor_flash);
+ /* The 5181 power LED is active low and requires
+ * DNS323_GPIO_LED_POWER1 to also be low.
+ */
+ if (dns323_dev_id() == MV88F5181_DEV_ID) {
+ dns323_leds[0].active_low = 1;
+ gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
+ }
+
platform_device_register(&dns323_gpio_leds);
platform_device_register(&dns323_button_device);
diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c
new file mode 100644
index 00000000000..8e569be6e2c
--- /dev/null
+++ b/arch/arm/mach-orion5x/ls_hgl-setup.c
@@ -0,0 +1,276 @@
+/*
+ * arch/arm/mach-orion5x/ls_hgl-setup.c
+ *
+ * Maintainer: Zhu Qingsen <zhuqs@cn.fujitsu.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/system.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * Linkstation LS-HGL Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define LS_HGL_NOR_BOOT_BASE 0xf4000000
+#define LS_HGL_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data ls_hgl_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource ls_hgl_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = LS_HGL_NOR_BOOT_BASE,
+ .end = LS_HGL_NOR_BOOT_BASE + LS_HGL_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device ls_hgl_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ls_hgl_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ls_hgl_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data ls_hgl_eth_data = {
+ .phy_addr = 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+static struct i2c_board_info __initdata ls_hgl_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+#define LS_HGL_GPIO_LED_ALARM 2
+#define LS_HGL_GPIO_LED_INFO 3
+#define LS_HGL_GPIO_LED_FUNC 17
+#define LS_HGL_GPIO_LED_PWR 0
+
+
+static struct gpio_led ls_hgl_led_pins[] = {
+ {
+ .name = "alarm:red",
+ .gpio = LS_HGL_GPIO_LED_ALARM,
+ .active_low = 1,
+ }, {
+ .name = "info:amber",
+ .gpio = LS_HGL_GPIO_LED_INFO,
+ .active_low = 1,
+ }, {
+ .name = "func:blue:top",
+ .gpio = LS_HGL_GPIO_LED_FUNC,
+ .active_low = 1,
+ }, {
+ .name = "power:blue:bottom",
+ .gpio = LS_HGL_GPIO_LED_PWR,
+ },
+};
+
+static struct gpio_led_platform_data ls_hgl_led_data = {
+ .leds = ls_hgl_led_pins,
+ .num_leds = ARRAY_SIZE(ls_hgl_led_pins),
+};
+
+static struct platform_device ls_hgl_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &ls_hgl_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ ****************************************************************************/
+#define LS_HGL_GPIO_KEY_FUNC 15
+#define LS_HGL_GPIO_KEY_POWER 8
+#define LS_HGL_GPIO_KEY_AUTOPOWER 10
+
+#define LS_HGL_SW_POWER 0x00
+#define LS_HGL_SW_AUTOPOWER 0x01
+
+static struct gpio_keys_button ls_hgl_buttons[] = {
+ {
+ .code = KEY_OPTION,
+ .gpio = LS_HGL_GPIO_KEY_FUNC,
+ .desc = "Function Button",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LS_HGL_SW_POWER,
+ .gpio = LS_HGL_GPIO_KEY_POWER,
+ .desc = "Power-on Switch",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LS_HGL_SW_AUTOPOWER,
+ .gpio = LS_HGL_GPIO_KEY_AUTOPOWER,
+ .desc = "Power-auto Switch",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data ls_hgl_button_data = {
+ .buttons = ls_hgl_buttons,
+ .nbuttons = ARRAY_SIZE(ls_hgl_buttons),
+};
+
+static struct platform_device ls_hgl_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ls_hgl_button_data,
+ },
+};
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data ls_hgl_sata_data = {
+ .n_ports = 2,
+};
+
+
+/*****************************************************************************
+ * Linkstation LS-HGL specific power off method: reboot
+ ****************************************************************************/
+/*
+ * On the Linkstation LS-HGL, the shutdown process is following:
+ * - Userland monitors key events until the power switch goes to off position
+ * - The board reboots
+ * - U-boot starts and goes into an idle mode waiting for the user
+ * to move the switch to ON position
+ */
+
+static void ls_hgl_power_off(void)
+{
+ arm_machine_restart('h', NULL);
+}
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+#define LS_HGL_GPIO_USB_POWER 9
+#define LS_HGL_GPIO_AUTO_POWER 10
+#define LS_HGL_GPIO_POWER 8
+
+#define LS_HGL_GPIO_HDD_POWER 1
+
+static struct orion5x_mpp_mode ls_hgl_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* LED_PWR */
+ { 1, MPP_GPIO }, /* HDD_PWR */
+ { 2, MPP_GPIO }, /* LED_ALARM */
+ { 3, MPP_GPIO }, /* LED_INFO */
+ { 4, MPP_UNUSED },
+ { 5, MPP_UNUSED },
+ { 6, MPP_GPIO }, /* FAN_LCK */
+ { 7, MPP_GPIO }, /* INIT */
+ { 8, MPP_GPIO }, /* POWER */
+ { 9, MPP_GPIO }, /* USB_PWR */
+ { 10, MPP_GPIO }, /* AUTO_POWER */
+ { 11, MPP_UNUSED }, /* LED_ETH (dummy) */
+ { 12, MPP_UNUSED },
+ { 13, MPP_UNUSED },
+ { 14, MPP_UNUSED },
+ { 15, MPP_GPIO }, /* FUNC */
+ { 16, MPP_UNUSED },
+ { 17, MPP_GPIO }, /* LED_FUNC */
+ { 18, MPP_UNUSED },
+ { 19, MPP_UNUSED },
+ { -1 },
+};
+
+static void __init ls_hgl_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(ls_hgl_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&ls_hgl_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&ls_hgl_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(LS_HGL_NOR_BOOT_BASE,
+ LS_HGL_NOR_BOOT_SIZE);
+ platform_device_register(&ls_hgl_nor_flash);
+
+ platform_device_register(&ls_hgl_button_device);
+
+ platform_device_register(&ls_hgl_leds);
+
+ i2c_register_board_info(0, &ls_hgl_i2c_rtc, 1);
+
+ /* enable USB power */
+ gpio_set_value(LS_HGL_GPIO_USB_POWER, 1);
+
+ /* register power-off method */
+ pm_power_off = ls_hgl_power_off;
+
+ pr_info("%s: finished\n", __func__);
+}
+
+MACHINE_START(LINKSTATION_LS_HGL, "Buffalo Linkstation LS-HGL")
+ /* Maintainer: Zhu Qingsen <zhuqs@cn.fujistu.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = ls_hgl_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
index c9bf6b81a80..c704f056de1 100644
--- a/arch/arm/mach-orion5x/lsmini-setup.c
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/pci.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/leds.h>
@@ -19,12 +18,13 @@
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/ata_platform.h>
-#include <asm/mach-types.h>
#include <linux/gpio.h>
+#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/system.h>
+#include <mach/orion5x.h>
#include "common.h"
#include "mpp.h"
-#include "include/mach/system.h"
/*****************************************************************************
* Linkstation Mini Info
@@ -186,7 +186,7 @@ static struct mv_sata_platform_data lsmini_sata_data = {
static void lsmini_power_off(void)
{
- arch_reset(0, NULL);
+ arm_machine_restart('h', NULL);
}
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index bdf96eb523b..e8706f15a67 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/mbus.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
index cb0feca193d..f9f222ebb7e 100644
--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -77,7 +77,7 @@ static struct gpio_keys_button wrt350n_v2_buttons[] = {
.desc = "Reset Button",
.active_low = 1,
}, {
- .code = KEY_WLAN,
+ .code = KEY_WPS_BUTTON,
.gpio = 2,
.desc = "WPS Button",
.active_low = 1,
diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c
index 425f7188505..7fa4bf2e212 100644
--- a/arch/arm/mach-pnx4008/dma.c
+++ b/arch/arm/mach-pnx4008/dma.c
@@ -22,6 +22,7 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
index 1f0585329be..ee3c29c57ae 100644
--- a/arch/arm/mach-pnx4008/pm.c
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/cacheflush.h>
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index dee92182749..5b6ee46fa7f 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -115,6 +115,11 @@ config MACH_CM_X300
select CPU_PXA310
select HAVE_PWM
+config MACH_CAPC7117
+ bool "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM"
+ select CPU_PXA320
+ select PXA3xx
+
config ARCH_GUMSTIX
bool "Gumstix XScale 255 boards"
select PXA25x
@@ -267,7 +272,6 @@ config MACH_H5000
config MACH_HIMALAYA
bool "HTC Himalaya Support"
select CPU_PXA26x
- select FB_W100
config MACH_MAGICIAN
bool "Enable HTC Magician Support"
@@ -417,6 +421,24 @@ config MACH_TREO680
Say Y here if you intend to run this kernel on Palm Treo 680
smartphone.
+config MACH_RAUMFELD_RC
+ bool "Raumfeld Controller"
+ select PXA3xx
+ select CPU_PXA300
+ select HAVE_PWM
+
+config MACH_RAUMFELD_CONNECTOR
+ bool "Raumfeld Connector"
+ select PXA3xx
+ select CPU_PXA300
+ select PXA_SSP
+
+config MACH_RAUMFELD_SPEAKER
+ bool "Raumfeld Speaker"
+ select PXA3xx
+ select CPU_PXA300
+ select PXA_SSP
+
config PXA_SHARPSL
bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
select SHARP_SCOOP
@@ -431,10 +453,18 @@ config PXA_SHARPSL
config SHARPSL_PM
bool
select APM_EMULATION
+ select SHARPSL_PM_MAX1111
+
+config SHARPSL_PM_MAX1111
+ bool
+ depends on !CORGI_SSP_DEPRECATED
+ select HWMON
+ select SENSORS_MAX1111
config CORGI_SSP_DEPRECATED
bool
select PXA_SSP
+ select PXA_SSP_LEGACY
help
This option will include corgi_ssp.c and corgi_lcd.c
that corgi_ts.c and other legacy drivers (corgi_bl.c
@@ -446,6 +476,7 @@ config MACH_POODLE
select PXA25x
select SHARP_LOCOMO
select PXA_SSP
+ select PXA_HAVE_BOARD_IRQS
config MACH_CORGI
bool "Enable Sharp SL-C700 (Corgi) Support"
@@ -492,6 +523,11 @@ config MACH_TOSA
select PXA25x
select PXA_HAVE_BOARD_IRQS
+config MACH_ICONTROL
+ bool "TMT iControl/SafeTCam based on the MXM-8x10 CoM"
+ select CPU_PXA320
+ select PXA3xx
+
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
select PXA25x
@@ -517,7 +553,6 @@ config MACH_E740
bool "Toshiba e740"
default y
depends on ARCH_PXA_ESERIES
- select FB_W100
help
Say Y here if you intend to run this kernel on a Toshiba
e740 family PDA.
@@ -526,7 +561,6 @@ config MACH_E750
bool "Toshiba e750"
default y
depends on ARCH_PXA_ESERIES
- select FB_W100
help
Say Y here if you intend to run this kernel on a Toshiba
e750 family PDA.
@@ -543,7 +577,6 @@ config MACH_E800
bool "Toshiba e800"
default y
depends on ARCH_PXA_ESERIES
- select FB_W100
help
Say Y here if you intend to run this kernel on a Toshiba
e800 family PDA.
@@ -629,6 +662,11 @@ config PXA_SSP
help
Enable support for PXA2xx SSP ports
+config PXA_SSP_LEGACY
+ bool
+ help
+ Support of legacy SSP API
+
config TOSA_BT
tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
depends on MACH_TOSA
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index f64afda7e6f..86bc87b7f2d 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx-pci.o
endif
obj-$(CONFIG_MACH_EM_X270) += em-x270.o
obj-$(CONFIG_MACH_CM_X300) += cm-x300.o
+obj-$(CONFIG_MACH_CAPC7117) += capc7117.o mxm8x10.o
obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
obj-$(CONFIG_GUMSTIX_AM200EPD) += am200epd.o
obj-$(CONFIG_GUMSTIX_AM300EPD) += am300epd.o
@@ -82,6 +83,7 @@ obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o sharpsl_pm.o spitz_pm.o
obj-$(CONFIG_CORGI_SSP_DEPRECATED) += corgi_ssp.o corgi_lcd.o
obj-$(CONFIG_MACH_POODLE) += poodle.o
obj-$(CONFIG_MACH_TOSA) += tosa.o
+obj-$(CONFIG_MACH_ICONTROL) += icontrol.o mxm8x10.o
obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o
obj-$(CONFIG_MACH_E330) += e330.o
obj-$(CONFIG_MACH_E350) += e350.o
@@ -89,6 +91,9 @@ obj-$(CONFIG_MACH_E740) += e740.o
obj-$(CONFIG_MACH_E750) += e750.o
obj-$(CONFIG_MACH_E400) += e400.o
obj-$(CONFIG_MACH_E800) += e800.o
+obj-$(CONFIG_MACH_RAUMFELD_RC) += raumfeld.o
+obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR) += raumfeld.o
+obj-$(CONFIG_MACH_RAUMFELD_SPEAKER) += raumfeld.o
# Support for blinky lights
led-y := leds.o
diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c
index 4bd10a17332..993d75e6639 100644
--- a/arch/arm/mach-pxa/am300epd.c
+++ b/arch/arm/mach-pxa/am300epd.c
@@ -288,7 +288,7 @@ int __init am300_init(void)
}
module_param(panel_type, uint, 0);
-MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97");
+MODULE_PARM_DESC(panel_type, "Select the panel type: 37, 6, 97");
MODULE_DESCRIPTION("board driver for am300 epd kit");
MODULE_AUTHOR("Jaya Kumar");
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index b8cd07ca938..f3b5ace815e 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -132,6 +132,14 @@ static void __init balloon3_init_irq(void)
"enabled\n", __func__, BALLOON3_AUX_NIRQ);
}
+static unsigned long balloon3_ac97_pin_config[] = {
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO113_AC97_nRESET,
+};
+
static void balloon3_backlight_power(int on)
{
pr_debug("%s: power is %s\n", __func__, on ? "on" : "off");
@@ -140,26 +148,7 @@ static void balloon3_backlight_power(int on)
static unsigned long balloon3_lcd_pin_config[] = {
/* LCD - 16bpp Active TFT */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
GPIO99_GPIO, /* Backlight */
};
@@ -311,8 +300,10 @@ static void __init balloon3_init(void)
pxa_set_stuart_info(NULL);
pxa_set_i2c_info(NULL);
- if (balloon3_has(BALLOON3_FEATURE_AUDIO))
+ if (balloon3_has(BALLOON3_FEATURE_AUDIO)) {
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config));
pxa_set_ac97_info(NULL);
+ }
if (balloon3_has(BALLOON3_FEATURE_TOPPOLY)) {
pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config));
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
new file mode 100644
index 00000000000..aae544631a8
--- /dev/null
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -0,0 +1,158 @@
+/*
+ * linux/arch/arm/mach-pxa/capc7117.c
+ *
+ * Support for the Embedian CAPC-7117 Evaluation Kit
+ * based on the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2009 Embedian Inc.
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2007-09-04: eric miao <eric.y.miao@gmail.com>
+ * rewrite to align with latest kernel
+ *
+ * 2010-01-09: Edwin Peer <epeer@tmtservices.co.za>
+ * Hennie van der Merwe <hvdmerwe@tmtservices.co.za>
+ * rework for upstream merge
+ *
+ * This program is free software; you can 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/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/serial_8250.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa320.h>
+#include <mach/mxm8x10.h>
+
+#include "generic.h"
+
+/* IDE (PATA) Support */
+static struct pata_platform_info pata_platform_data = {
+ .ioport_shift = 1
+};
+
+static struct resource capc7117_ide_resources[] = {
+ [0] = {
+ .start = 0x11000020,
+ .end = 0x1100003f,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = 0x1100001c,
+ .end = 0x1100001c,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)),
+ .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING
+ }
+};
+
+static struct platform_device capc7117_ide_device = {
+ .name = "pata_platform",
+ .num_resources = ARRAY_SIZE(capc7117_ide_resources),
+ .resource = capc7117_ide_resources,
+ .dev = {
+ .platform_data = &pata_platform_data,
+ .coherent_dma_mask = ~0 /* grumble */
+ }
+};
+
+static void __init capc7117_ide_init(void)
+{
+ platform_device_register(&capc7117_ide_device);
+}
+
+/* TI16C752 UART support */
+#define TI16C752_FLAGS (UPF_BOOT_AUTOCONF | \
+ UPF_IOREMAP | \
+ UPF_BUGGY_UART | \
+ UPF_SKIP_TEST)
+#define TI16C752_UARTCLK (22118400)
+static struct plat_serial8250_port ti16c752_platform_data[] = {
+ [0] = {
+ .mapbase = 0x14000000,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO78)),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .flags = TI16C752_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = TI16C752_UARTCLK
+ },
+ [1] = {
+ .mapbase = 0x14000040,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO79)),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .flags = TI16C752_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = TI16C752_UARTCLK
+ },
+ [2] = {
+ .mapbase = 0x14000080,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO80)),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .flags = TI16C752_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = TI16C752_UARTCLK
+ },
+ [3] = {
+ .mapbase = 0x140000c0,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO81)),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .flags = TI16C752_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = TI16C752_UARTCLK
+ },
+ [4] = {
+ /* end of array */
+ }
+};
+
+static struct platform_device ti16c752_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = ti16c752_platform_data
+ }
+};
+
+static void __init capc7117_uarts_init(void)
+{
+ platform_device_register(&ti16c752_device);
+}
+
+static void __init capc7117_init(void)
+{
+ /* Init CoM */
+ mxm_8x10_barebones_init();
+
+ /* Init evaluation board peripherals */
+ mxm_8x10_ac97_init();
+ mxm_8x10_usb_host_init();
+ mxm_8x10_mmc_init();
+
+ capc7117_uarts_init();
+ capc7117_ide_init();
+}
+
+MACHINE_START(CAPC7117,
+ "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM")
+ .phys_io = 0x40000000,
+ .boot_params = 0xa0000100,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = capc7117_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c
index 253fd76142d..f1a7703d771 100644
--- a/arch/arm/mach-pxa/cm-x255.c
+++ b/arch/arm/mach-pxa/cm-x255.c
@@ -50,26 +50,7 @@ static unsigned long cmx255_pin_config[] = {
GPIO47_STUART_TXD,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* SSP1 */
GPIO23_SSP1_SCLK,
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index eea78b6c2bc..a9926bb7592 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -71,26 +71,7 @@ static unsigned long cmx270_pin_config[] = {
GPIO111_MMC_DAT_3,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* I2C */
GPIO117_I2C_SCL,
@@ -195,33 +176,57 @@ static struct resource cmx270_2700G_resource[] = {
},
};
-static unsigned long save_lcd_regs[10];
+static unsigned long cmx270_marathon_on[] = {
+ GPIO58_GPIO,
+ GPIO59_GPIO,
+ GPIO60_GPIO,
+ GPIO61_GPIO,
+ GPIO62_GPIO,
+ GPIO63_GPIO,
+ GPIO64_GPIO,
+ GPIO65_GPIO,
+ GPIO66_GPIO,
+ GPIO67_GPIO,
+ GPIO68_GPIO,
+ GPIO69_GPIO,
+ GPIO70_GPIO,
+ GPIO71_GPIO,
+ GPIO72_GPIO,
+ GPIO73_GPIO,
+ GPIO74_GPIO,
+ GPIO75_GPIO,
+ GPIO76_GPIO,
+ GPIO77_GPIO,
+};
+
+static unsigned long cmx270_marathon_off[] = {
+ GPIOxx_LCD_TFT_16BPP,
+};
static int cmx270_marathon_probe(struct fb_info *fb)
{
- /* save PXA-270 pin settings before enabling 2700G */
- save_lcd_regs[0] = GPDR1;
- save_lcd_regs[1] = GPDR2;
- save_lcd_regs[2] = GAFR1_U;
- save_lcd_regs[3] = GAFR2_L;
- save_lcd_regs[4] = GAFR2_U;
-
- /* Disable PXA-270 on-chip controller driving pins */
- GPDR1 &= ~(0xfc000000);
- GPDR2 &= ~(0x00c03fff);
- GAFR1_U &= ~(0xfff00000);
- GAFR2_L &= ~(0x0fffffff);
- GAFR2_U &= ~(0x0000f000);
+ int gpio, err;
+
+ for (gpio = 58; gpio <= 77; gpio++) {
+ err = gpio_request(gpio, "LCD");
+ if (err)
+ return err;
+ gpio_direction_input(gpio);
+ }
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_on));
return 0;
}
static int cmx270_marathon_remove(struct fb_info *fb)
{
- GPDR1 = save_lcd_regs[0];
- GPDR2 = save_lcd_regs[1];
- GAFR1_U = save_lcd_regs[2];
- GAFR2_L = save_lcd_regs[3];
- GAFR2_U = save_lcd_regs[4];
+ int gpio;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_off));
+
+ for (gpio = 58; gpio <= 77; gpio++)
+ gpio_free(gpio);
+
return 0;
}
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c
index 7873fa3d8fa..161fc2d6120 100644
--- a/arch/arm/mach-pxa/cm-x2xx-pci.c
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.c
@@ -59,7 +59,7 @@ void __init cmx2xx_pci_adjust_zones(int node, unsigned long *zone_size,
static void cmx2xx_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
{
/* clear our parent irq */
- GEDR(cmx2xx_it8152_irq_gpio) = GPIO_bit(cmx2xx_it8152_irq_gpio);
+ desc->chip->ack(irq);
it8152_irq_demux(irq, desc);
}
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index a5ee70735e0..9347254f8bc 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <mach/hardware.h>
@@ -204,7 +203,7 @@ void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
ssp_machinfo = machinfo;
}
-static int __init corgi_ssp_probe(struct platform_device *dev)
+static int __devinit corgi_ssp_probe(struct platform_device *dev)
{
int ret;
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
index 149cdd9aee4..27fa329d9a8 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
@@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
+#include <linux/slab.h>
#include <mach/pxa3xx-regs.h>
diff --git a/arch/arm/mach-pxa/e740.c b/arch/arm/mach-pxa/e740.c
index 94b23a9e387..d578021d1a1 100644
--- a/arch/arm/mach-pxa/e740.c
+++ b/arch/arm/mach-pxa/e740.c
@@ -134,6 +134,12 @@ static unsigned long e740_pin_config[] __initdata = {
/* IrDA */
GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
/* Audio power control */
GPIO16_GPIO, /* AC97 codec AVDD2 supply (analogue power) */
GPIO40_GPIO, /* Mic amp power */
diff --git a/arch/arm/mach-pxa/e750.c b/arch/arm/mach-pxa/e750.c
index 5eccbce73a3..af83caa52dd 100644
--- a/arch/arm/mach-pxa/e750.c
+++ b/arch/arm/mach-pxa/e750.c
@@ -132,6 +132,12 @@ static unsigned long e750_pin_config[] __initdata = {
/* IrDA */
GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
/* Audio power control */
GPIO4_GPIO, /* Headphone amp power */
GPIO7_GPIO, /* Speaker amp power */
diff --git a/arch/arm/mach-pxa/e800.c b/arch/arm/mach-pxa/e800.c
index aad129bed19..8ea97bf53fe 100644
--- a/arch/arm/mach-pxa/e800.c
+++ b/arch/arm/mach-pxa/e800.c
@@ -35,6 +35,14 @@
/* ------------------------ e800 LCD definitions ------------------------- */
+static unsigned long e800_pin_config[] __initdata = {
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+};
+
static struct w100_gen_regs e800_lcd_regs = {
.lcd_format = 0x00008003,
.lcdd_cntl1 = 0x02a00000,
@@ -195,6 +203,7 @@ static struct platform_device *devices[] __initdata = {
static void __init e800_init(void)
{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(e800_pin_config));
pxa_set_ffuart_info(NULL);
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index c8a01bc85fd..aab04f33e49 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -109,26 +109,7 @@ static unsigned long common_pin_config[] = {
GPIO111_MMC_DAT_3,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* QCI */
GPIO84_CIF_FV,
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
new file mode 100644
index 00000000000..771137fc1a8
--- /dev/null
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -0,0 +1,202 @@
+/*
+ * linux/arch/arm/mach-pxa/icontrol.c
+ *
+ * Support for the iControl and SafeTcam platforms from TMT Services
+ * using the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2010-01-21 Hennie van der Merve <hvdmerwe@tmtservies.co.za>
+ *
+ * This program is free software; you can 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/irq.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa320.h>
+#include <mach/mxm8x10.h>
+
+#include <linux/spi/spi.h>
+#include <mach/pxa2xx_spi.h>
+#include <linux/can/platform/mcp251x.h>
+
+#include "generic.h"
+
+#define ICONTROL_MCP251x_nCS1 (15)
+#define ICONTROL_MCP251x_nCS2 (16)
+#define ICONTROL_MCP251x_nCS3 (17)
+#define ICONTROL_MCP251x_nCS4 (24)
+
+#define ICONTROL_MCP251x_nIRQ1 (74)
+#define ICONTROL_MCP251x_nIRQ2 (75)
+#define ICONTROL_MCP251x_nIRQ3 (76)
+#define ICONTROL_MCP251x_nIRQ4 (77)
+
+static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
+ .tx_threshold = 8,
+ .rx_threshold = 128,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = ICONTROL_MCP251x_nCS1
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
+ .tx_threshold = 8,
+ .rx_threshold = 128,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = ICONTROL_MCP251x_nCS2
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
+ .tx_threshold = 8,
+ .rx_threshold = 128,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = ICONTROL_MCP251x_nCS3
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
+ .tx_threshold = 8,
+ .rx_threshold = 128,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = ICONTROL_MCP251x_nCS4
+};
+
+static struct mcp251x_platform_data mcp251x_info = {
+ .oscillator_frequency = 16E6,
+ .model = CAN_MCP251X_MCP2515,
+ .board_specific_setup = NULL,
+ .power_enable = NULL,
+ .transceiver_enable = NULL
+};
+
+static struct spi_board_info mcp251x_board_info[] = {
+ {
+ .modalias = "mcp251x",
+ .max_speed_hz = 6500000,
+ .bus_num = 3,
+ .chip_select = 0,
+ .platform_data = &mcp251x_info,
+ .controller_data = &mcp251x_chip_info1,
+ .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ1)
+ },
+ {
+ .modalias = "mcp251x",
+ .max_speed_hz = 6500000,
+ .bus_num = 3,
+ .chip_select = 1,
+ .platform_data = &mcp251x_info,
+ .controller_data = &mcp251x_chip_info2,
+ .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ2)
+ },
+ {
+ .modalias = "mcp251x",
+ .max_speed_hz = 6500000,
+ .bus_num = 4,
+ .chip_select = 0,
+ .platform_data = &mcp251x_info,
+ .controller_data = &mcp251x_chip_info3,
+ .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ3)
+ },
+ {
+ .modalias = "mcp251x",
+ .max_speed_hz = 6500000,
+ .bus_num = 4,
+ .chip_select = 1,
+ .platform_data = &mcp251x_info,
+ .controller_data = &mcp251x_chip_info4,
+ .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ4)
+ }
+};
+
+static struct pxa2xx_spi_master pxa_ssp3_spi_master_info = {
+ .clock_enable = CKEN_SSP3,
+ .num_chipselect = 2,
+ .enable_dma = 1
+};
+
+static struct pxa2xx_spi_master pxa_ssp4_spi_master_info = {
+ .clock_enable = CKEN_SSP4,
+ .num_chipselect = 2,
+ .enable_dma = 1
+};
+
+struct platform_device pxa_spi_ssp3 = {
+ .name = "pxa2xx-spi",
+ .id = 3,
+ .dev = {
+ .platform_data = &pxa_ssp3_spi_master_info,
+ }
+};
+
+struct platform_device pxa_spi_ssp4 = {
+ .name = "pxa2xx-spi",
+ .id = 4,
+ .dev = {
+ .platform_data = &pxa_ssp4_spi_master_info,
+ }
+};
+
+static struct platform_device *icontrol_spi_devices[] __initdata = {
+ &pxa_spi_ssp3,
+ &pxa_spi_ssp4,
+};
+
+static mfp_cfg_t mfp_can_cfg[] __initdata = {
+ /* CAN CS lines */
+ GPIO15_GPIO,
+ GPIO16_GPIO,
+ GPIO17_GPIO,
+ GPIO24_GPIO,
+
+ /* SPI (SSP3) lines */
+ GPIO89_SSP3_SCLK,
+ GPIO91_SSP3_TXD,
+ GPIO92_SSP3_RXD,
+
+ /* SPI (SSP4) lines */
+ GPIO93_SSP4_SCLK,
+ GPIO95_SSP4_TXD,
+ GPIO96_SSP4_RXD,
+
+ /* CAN nIRQ lines */
+ GPIO74_GPIO | MFP_LPM_EDGE_RISE,
+ GPIO75_GPIO | MFP_LPM_EDGE_RISE,
+ GPIO76_GPIO | MFP_LPM_EDGE_RISE,
+ GPIO77_GPIO | MFP_LPM_EDGE_RISE
+};
+
+static void __init icontrol_can_init(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
+ platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
+ spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
+}
+
+static void __init icontrol_init(void)
+{
+ mxm_8x10_barebones_init();
+ mxm_8x10_usb_host_init();
+ mxm_8x10_mmc_init();
+
+ icontrol_can_init();
+}
+
+MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
+ .phys_io = 0x40000000,
+ .boot_params = 0xa0000100,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = icontrol_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 5c9e11d74f4..bc78c4dc0c6 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -47,25 +47,7 @@
static unsigned long idp_pin_config[] __initdata = {
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
+ GPIOxx_LCD_DSTN_16BPP,
/* BTUART */
GPIO42_BTUART_RXD,
diff --git a/arch/arm/mach-pxa/imote2.c b/arch/arm/mach-pxa/imote2.c
index 5b0862df61a..5161dca8ccc 100644
--- a/arch/arm/mach-pxa/imote2.c
+++ b/arch/arm/mach-pxa/imote2.c
@@ -64,7 +64,6 @@ static unsigned long imote2_pin_config[] __initdata = {
GPIO116_GPIO, /* CC_CCA */
GPIO0_GPIO, /* CC_FIFOP */
GPIO16_GPIO, /* CCSFD */
- GPIO39_GPIO, /* CSn */
GPIO115_GPIO, /* Power enable */
/* I2C */
@@ -72,7 +71,7 @@ static unsigned long imote2_pin_config[] __initdata = {
GPIO118_I2C_SDA,
/* SSP 3 - 802.15.4 radio */
- GPIO39_GPIO, /* Chip Select */
+ GPIO39_GPIO, /* Chip Select */
GPIO34_SSP3_SCLK,
GPIO35_SSP3_TXD,
GPIO41_SSP3_RXD,
@@ -560,10 +559,6 @@ static void __init imote2_init(void)
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
- /* SPI chip select directions - all other directions should
- * be handled by drivers.*/
- gpio_direction_output(37, 0);
-
platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h
index bfec09b1814..1a741065045 100644
--- a/arch/arm/mach-pxa/include/mach/balloon3.h
+++ b/arch/arm/mach-pxa/include/mach/balloon3.h
@@ -129,6 +129,16 @@ enum balloon3_features {
#define CPLD_AROUTING_LOONR2INT_BIT 6
#define CPLD_AROUTING_LOONR2EXT_BIT 7
+/* Balloon3 Interrupts */
+#define BALLOON3_IRQ(x) (IRQ_BOARD_START + (x))
+
+#define BALLOON3_BP_CF_NRDY_IRQ BALLOON3_IRQ(0)
+#define BALLOON3_BP_NSTSCHG_IRQ BALLOON3_IRQ(1)
+
+#define BALLOON3_AUX_NIRQ IRQ_GPIO(BALLOON3_GPIO_AUX_NIRQ)
+#define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
+#define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD)
+
extern int balloon3_has(enum balloon3_features feature);
#endif
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index e741bf1bfb2..7515757d691 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -314,7 +314,6 @@ extern unsigned long get_clock_tick_rate(void);
#define PCIBIOS_MIN_IO 0
#define PCIBIOS_MIN_MEM 0
#define pcibios_assign_all_busses() 1
-#define HAVE_ARCH_PCI_SET_DMA_MASK 1
#endif
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 3677a9af9c8..ffc8314520f 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -135,82 +135,6 @@
#define IRQ_BOARD_END (IRQ_BOARD_START + 16)
#endif
-#define IRQ_SA1111_START (IRQ_BOARD_END)
-#define IRQ_GPAIN0 (IRQ_BOARD_END + 0)
-#define IRQ_GPAIN1 (IRQ_BOARD_END + 1)
-#define IRQ_GPAIN2 (IRQ_BOARD_END + 2)
-#define IRQ_GPAIN3 (IRQ_BOARD_END + 3)
-#define IRQ_GPBIN0 (IRQ_BOARD_END + 4)
-#define IRQ_GPBIN1 (IRQ_BOARD_END + 5)
-#define IRQ_GPBIN2 (IRQ_BOARD_END + 6)
-#define IRQ_GPBIN3 (IRQ_BOARD_END + 7)
-#define IRQ_GPBIN4 (IRQ_BOARD_END + 8)
-#define IRQ_GPBIN5 (IRQ_BOARD_END + 9)
-#define IRQ_GPCIN0 (IRQ_BOARD_END + 10)
-#define IRQ_GPCIN1 (IRQ_BOARD_END + 11)
-#define IRQ_GPCIN2 (IRQ_BOARD_END + 12)
-#define IRQ_GPCIN3 (IRQ_BOARD_END + 13)
-#define IRQ_GPCIN4 (IRQ_BOARD_END + 14)
-#define IRQ_GPCIN5 (IRQ_BOARD_END + 15)
-#define IRQ_GPCIN6 (IRQ_BOARD_END + 16)
-#define IRQ_GPCIN7 (IRQ_BOARD_END + 17)
-#define IRQ_MSTXINT (IRQ_BOARD_END + 18)
-#define IRQ_MSRXINT (IRQ_BOARD_END + 19)
-#define IRQ_MSSTOPERRINT (IRQ_BOARD_END + 20)
-#define IRQ_TPTXINT (IRQ_BOARD_END + 21)
-#define IRQ_TPRXINT (IRQ_BOARD_END + 22)
-#define IRQ_TPSTOPERRINT (IRQ_BOARD_END + 23)
-#define SSPXMTINT (IRQ_BOARD_END + 24)
-#define SSPRCVINT (IRQ_BOARD_END + 25)
-#define SSPROR (IRQ_BOARD_END + 26)
-#define AUDXMTDMADONEA (IRQ_BOARD_END + 32)
-#define AUDRCVDMADONEA (IRQ_BOARD_END + 33)
-#define AUDXMTDMADONEB (IRQ_BOARD_END + 34)
-#define AUDRCVDMADONEB (IRQ_BOARD_END + 35)
-#define AUDTFSR (IRQ_BOARD_END + 36)
-#define AUDRFSR (IRQ_BOARD_END + 37)
-#define AUDTUR (IRQ_BOARD_END + 38)
-#define AUDROR (IRQ_BOARD_END + 39)
-#define AUDDTS (IRQ_BOARD_END + 40)
-#define AUDRDD (IRQ_BOARD_END + 41)
-#define AUDSTO (IRQ_BOARD_END + 42)
-#define IRQ_USBPWR (IRQ_BOARD_END + 43)
-#define IRQ_HCIM (IRQ_BOARD_END + 44)
-#define IRQ_HCIBUFFACC (IRQ_BOARD_END + 45)
-#define IRQ_HCIRMTWKP (IRQ_BOARD_END + 46)
-#define IRQ_NHCIMFCIR (IRQ_BOARD_END + 47)
-#define IRQ_USB_PORT_RESUME (IRQ_BOARD_END + 48)
-#define IRQ_S0_READY_NINT (IRQ_BOARD_END + 49)
-#define IRQ_S1_READY_NINT (IRQ_BOARD_END + 50)
-#define IRQ_S0_CD_VALID (IRQ_BOARD_END + 51)
-#define IRQ_S1_CD_VALID (IRQ_BOARD_END + 52)
-#define IRQ_S0_BVD1_STSCHG (IRQ_BOARD_END + 53)
-#define IRQ_S1_BVD1_STSCHG (IRQ_BOARD_END + 54)
-
-#define IRQ_LOCOMO_START (IRQ_BOARD_END)
-#define IRQ_LOCOMO_KEY (IRQ_BOARD_END + 0)
-#define IRQ_LOCOMO_GPIO0 (IRQ_BOARD_END + 1)
-#define IRQ_LOCOMO_GPIO1 (IRQ_BOARD_END + 2)
-#define IRQ_LOCOMO_GPIO2 (IRQ_BOARD_END + 3)
-#define IRQ_LOCOMO_GPIO3 (IRQ_BOARD_END + 4)
-#define IRQ_LOCOMO_GPIO4 (IRQ_BOARD_END + 5)
-#define IRQ_LOCOMO_GPIO5 (IRQ_BOARD_END + 6)
-#define IRQ_LOCOMO_GPIO6 (IRQ_BOARD_END + 7)
-#define IRQ_LOCOMO_GPIO7 (IRQ_BOARD_END + 8)
-#define IRQ_LOCOMO_GPIO8 (IRQ_BOARD_END + 9)
-#define IRQ_LOCOMO_GPIO9 (IRQ_BOARD_END + 10)
-#define IRQ_LOCOMO_GPIO10 (IRQ_BOARD_END + 11)
-#define IRQ_LOCOMO_GPIO11 (IRQ_BOARD_END + 12)
-#define IRQ_LOCOMO_GPIO12 (IRQ_BOARD_END + 13)
-#define IRQ_LOCOMO_GPIO13 (IRQ_BOARD_END + 14)
-#define IRQ_LOCOMO_GPIO14 (IRQ_BOARD_END + 15)
-#define IRQ_LOCOMO_GPIO15 (IRQ_BOARD_END + 16)
-#define IRQ_LOCOMO_LT (IRQ_BOARD_END + 17)
-#define IRQ_LOCOMO_SPI_RFR (IRQ_BOARD_END + 18)
-#define IRQ_LOCOMO_SPI_RFW (IRQ_BOARD_END + 19)
-#define IRQ_LOCOMO_SPI_OVRN (IRQ_BOARD_END + 20)
-#define IRQ_LOCOMO_SPI_TEND (IRQ_BOARD_END + 21)
-
/*
* Figure out the MAX IRQ number.
*
@@ -219,89 +143,16 @@
* Otherwise, we have the standard IRQs only.
*/
#ifdef CONFIG_SA1111
-#define NR_IRQS (IRQ_S1_BVD1_STSCHG + 1)
-#elif defined(CONFIG_SHARP_LOCOMO)
-#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
+#define NR_IRQS (IRQ_BOARD_END + 55)
#elif defined(CONFIG_PXA_HAVE_BOARD_IRQS)
#define NR_IRQS (IRQ_BOARD_END)
#else
#define NR_IRQS (IRQ_BOARD_START)
#endif
-/*
- * Board specific IRQs. Define them here.
- * Do not surround them with ifdefs.
- */
-#define LUBBOCK_IRQ(x) (IRQ_BOARD_START + (x))
-#define LUBBOCK_SD_IRQ LUBBOCK_IRQ(0)
-#define LUBBOCK_SA1111_IRQ LUBBOCK_IRQ(1)
-#define LUBBOCK_USB_IRQ LUBBOCK_IRQ(2) /* usb connect */
-#define LUBBOCK_ETH_IRQ LUBBOCK_IRQ(3)
-#define LUBBOCK_UCB1400_IRQ LUBBOCK_IRQ(4)
-#define LUBBOCK_BB_IRQ LUBBOCK_IRQ(5)
-#define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */
-#define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6)
-
-#define LPD270_IRQ(x) (IRQ_BOARD_START + (x))
-#define LPD270_USBC_IRQ LPD270_IRQ(2)
-#define LPD270_ETHERNET_IRQ LPD270_IRQ(3)
-#define LPD270_AC97_IRQ LPD270_IRQ(4)
-
-#define MAINSTONE_IRQ(x) (IRQ_BOARD_START + (x))
-#define MAINSTONE_MMC_IRQ MAINSTONE_IRQ(0)
-#define MAINSTONE_USIM_IRQ MAINSTONE_IRQ(1)
-#define MAINSTONE_USBC_IRQ MAINSTONE_IRQ(2)
-#define MAINSTONE_ETHERNET_IRQ MAINSTONE_IRQ(3)
-#define MAINSTONE_AC97_IRQ MAINSTONE_IRQ(4)
-#define MAINSTONE_PEN_IRQ MAINSTONE_IRQ(5)
-#define MAINSTONE_MSINS_IRQ MAINSTONE_IRQ(6)
-#define MAINSTONE_EXBRD_IRQ MAINSTONE_IRQ(7)
-#define MAINSTONE_S0_CD_IRQ MAINSTONE_IRQ(9)
-#define MAINSTONE_S0_STSCHG_IRQ MAINSTONE_IRQ(10)
-#define MAINSTONE_S0_IRQ MAINSTONE_IRQ(11)
-#define MAINSTONE_S1_CD_IRQ MAINSTONE_IRQ(13)
-#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14)
-#define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15)
-
-/* Balloon3 Interrupts */
-#define BALLOON3_IRQ(x) (IRQ_BOARD_START + (x))
-
-#define BALLOON3_BP_CF_NRDY_IRQ BALLOON3_IRQ(0)
-#define BALLOON3_BP_NSTSCHG_IRQ BALLOON3_IRQ(1)
-
-#define BALLOON3_AUX_NIRQ IRQ_GPIO(BALLOON3_GPIO_AUX_NIRQ)
-#define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
-#define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD)
-
-/* LoCoMo Interrupts (CONFIG_SHARP_LOCOMO) */
-#define IRQ_LOCOMO_KEY_BASE (IRQ_BOARD_START + 0)
-#define IRQ_LOCOMO_GPIO_BASE (IRQ_BOARD_START + 1)
-#define IRQ_LOCOMO_LT_BASE (IRQ_BOARD_START + 2)
-#define IRQ_LOCOMO_SPI_BASE (IRQ_BOARD_START + 3)
-
-/* phyCORE-PXA270 (PCM027) Interrupts */
-#define PCM027_IRQ(x) (IRQ_BOARD_START + (x))
-#define PCM027_BTDET_IRQ PCM027_IRQ(0)
-#define PCM027_FF_RI_IRQ PCM027_IRQ(1)
-#define PCM027_MMCDET_IRQ PCM027_IRQ(2)
-#define PCM027_PM_5V_IRQ PCM027_IRQ(3)
-
-/* ITE8152 irqs */
/* add IT8152 IRQs beyond BOARD_END */
#ifdef CONFIG_PCI_HOST_ITE8152
-#define IT8152_IRQ(x) (IRQ_BOARD_END + (x))
-
-/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
-#define IT8152_LD_IRQ_COUNT 9
-#define IT8152_LP_IRQ_COUNT 16
-#define IT8152_PD_IRQ_COUNT 15
-
-/* Priorities: */
-#define IT8152_PD_IRQ(i) IT8152_IRQ(i)
-#define IT8152_LP_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT)
-#define IT8152_LD_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT + IT8152_LP_IRQ_COUNT)
-
-#define IT8152_LAST_IRQ IT8152_LD_IRQ(IT8152_LD_IRQ_COUNT - 1)
+#define IT8152_LAST_IRQ (IRQ_BOARD_END + 40)
#if NR_IRQS < (IT8152_LAST_IRQ+1)
#undef NR_IRQS
diff --git a/arch/arm/mach-pxa/include/mach/lpd270.h b/arch/arm/mach-pxa/include/mach/lpd270.h
index f89fb715266..0e6440c8168 100644
--- a/arch/arm/mach-pxa/include/mach/lpd270.h
+++ b/arch/arm/mach-pxa/include/mach/lpd270.h
@@ -34,5 +34,9 @@
#define LPD270_INT_ETHERNET (1 << 3) /* Ethernet controller IRQ */
#define LPD270_INT_USBC (1 << 2) /* USB client cable detection IRQ */
+#define LPD270_IRQ(x) (IRQ_BOARD_START + (x))
+#define LPD270_USBC_IRQ LPD270_IRQ(2)
+#define LPD270_ETHERNET_IRQ LPD270_IRQ(3)
+#define LPD270_AC97_IRQ LPD270_IRQ(4)
#endif
diff --git a/arch/arm/mach-pxa/include/mach/lubbock.h b/arch/arm/mach-pxa/include/mach/lubbock.h
index 751b74811d0..a0d4247f08f 100644
--- a/arch/arm/mach-pxa/include/mach/lubbock.h
+++ b/arch/arm/mach-pxa/include/mach/lubbock.h
@@ -34,6 +34,17 @@
#define LUB_IRQ_SET_CLR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x0d0)
#define LUB_GP __LUB_REG(LUBBOCK_FPGA_PHYS + 0x100)
+/* Board specific IRQs */
+#define LUBBOCK_IRQ(x) (IRQ_BOARD_START + (x))
+#define LUBBOCK_SD_IRQ LUBBOCK_IRQ(0)
+#define LUBBOCK_SA1111_IRQ LUBBOCK_IRQ(1)
+#define LUBBOCK_USB_IRQ LUBBOCK_IRQ(2) /* usb connect */
+#define LUBBOCK_ETH_IRQ LUBBOCK_IRQ(3)
+#define LUBBOCK_UCB1400_IRQ LUBBOCK_IRQ(4)
+#define LUBBOCK_BB_IRQ LUBBOCK_IRQ(5)
+#define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */
+#define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6)
+
#ifndef __ASSEMBLY__
extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set);
#endif
diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h
index 3461c4302ff..86e623abd64 100644
--- a/arch/arm/mach-pxa/include/mach/mainstone.h
+++ b/arch/arm/mach-pxa/include/mach/mainstone.h
@@ -117,4 +117,21 @@
#define MST_PCMCIA_PWR_VCC_33 0x8 /* voltage VCC = 3.3V */
#define MST_PCMCIA_PWR_VCC_50 0x4 /* voltage VCC = 5.0V */
+/* board specific IRQs */
+#define MAINSTONE_IRQ(x) (IRQ_BOARD_START + (x))
+#define MAINSTONE_MMC_IRQ MAINSTONE_IRQ(0)
+#define MAINSTONE_USIM_IRQ MAINSTONE_IRQ(1)
+#define MAINSTONE_USBC_IRQ MAINSTONE_IRQ(2)
+#define MAINSTONE_ETHERNET_IRQ MAINSTONE_IRQ(3)
+#define MAINSTONE_AC97_IRQ MAINSTONE_IRQ(4)
+#define MAINSTONE_PEN_IRQ MAINSTONE_IRQ(5)
+#define MAINSTONE_MSINS_IRQ MAINSTONE_IRQ(6)
+#define MAINSTONE_EXBRD_IRQ MAINSTONE_IRQ(7)
+#define MAINSTONE_S0_CD_IRQ MAINSTONE_IRQ(9)
+#define MAINSTONE_S0_STSCHG_IRQ MAINSTONE_IRQ(10)
+#define MAINSTONE_S0_IRQ MAINSTONE_IRQ(11)
+#define MAINSTONE_S1_CD_IRQ MAINSTONE_IRQ(13)
+#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14)
+#define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15)
+
#endif
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
index 9c787855cf2..cafadc33dfd 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
@@ -190,4 +190,36 @@
#define GPIO89_AC97_nRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
#endif /* CONFIG_CPU_PXA26x */
+/* commonly used pin configurations */
+#define GPIOxx_LCD_16BPP \
+ GPIO58_LCD_LDD_0, \
+ GPIO59_LCD_LDD_1, \
+ GPIO60_LCD_LDD_2, \
+ GPIO61_LCD_LDD_3, \
+ GPIO62_LCD_LDD_4, \
+ GPIO63_LCD_LDD_5, \
+ GPIO64_LCD_LDD_6, \
+ GPIO65_LCD_LDD_7, \
+ GPIO66_LCD_LDD_8, \
+ GPIO67_LCD_LDD_9, \
+ GPIO68_LCD_LDD_10, \
+ GPIO69_LCD_LDD_11, \
+ GPIO70_LCD_LDD_12, \
+ GPIO71_LCD_LDD_13, \
+ GPIO72_LCD_LDD_14, \
+ GPIO73_LCD_LDD_15
+
+#define GPIOxx_LCD_DSTN_16BPP \
+ GPIOxx_LCD_16BPP, \
+ GPIO74_LCD_FCLK, \
+ GPIO75_LCD_LCLK, \
+ GPIO76_LCD_PCLK
+
+#define GPIOxx_LCD_TFT_16BPP \
+ GPIOxx_LCD_16BPP, \
+ GPIO74_LCD_FCLK, \
+ GPIO75_LCD_LCLK, \
+ GPIO76_LCD_PCLK, \
+ GPIO77_LCD_BIAS
+
#endif /* __ASM_ARCH_MFP_PXA25X_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
index 6543c05f47e..ec0f0b0b674 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
@@ -434,5 +434,32 @@
#define GPIO112_nMSINS MFP_CFG_IN(GPIO112, AF2)
#define GPIO32_MSSCLK MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
+/* commonly used pin configurations */
+#define GPIOxx_LCD_16BPP \
+ GPIO58_LCD_LDD_0, \
+ GPIO59_LCD_LDD_1, \
+ GPIO60_LCD_LDD_2, \
+ GPIO61_LCD_LDD_3, \
+ GPIO62_LCD_LDD_4, \
+ GPIO63_LCD_LDD_5, \
+ GPIO64_LCD_LDD_6, \
+ GPIO65_LCD_LDD_7, \
+ GPIO66_LCD_LDD_8, \
+ GPIO67_LCD_LDD_9, \
+ GPIO68_LCD_LDD_10, \
+ GPIO69_LCD_LDD_11, \
+ GPIO70_LCD_LDD_12, \
+ GPIO71_LCD_LDD_13, \
+ GPIO72_LCD_LDD_14, \
+ GPIO73_LCD_LDD_15
+
+#define GPIOxx_LCD_TFT_16BPP \
+ GPIOxx_LCD_16BPP, \
+ GPIO74_LCD_FCLK, \
+ GPIO75_LCD_LCLK, \
+ GPIO76_LCD_PCLK, \
+ GPIO77_LCD_BIAS
+
+
extern int keypad_set_wake(unsigned int on);
#endif /* __ASM_ARCH_MFP_PXA27X_H */
diff --git a/arch/arm/mach-pxa/include/mach/mxm8x10.h b/arch/arm/mach-pxa/include/mach/mxm8x10.h
new file mode 100644
index 00000000000..ffa15665a41
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mxm8x10.h
@@ -0,0 +1,21 @@
+#ifndef __MACH_MXM_8X10_H
+#define __MACH_MXM_8X10_H
+
+#define MXM_8X10_ETH_PHYS 0x13000000
+
+#if defined(CONFIG_MMC)
+
+#define MXM_8X10_SD_nCD (72)
+#define MXM_8X10_SD_WP (84)
+
+extern void mxm_8x10_mmc_init(void);
+#else
+static inline void mxm_8x10_mmc_init(void) {}
+#endif
+
+extern void mxm_8x10_usb_host_init(void);
+extern void mxm_8x10_ac97_init(void);
+
+extern void mxm_8x10_barebones_init(void);
+
+#endif /* __MACH_MXM_8X10_H */
diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h
index 4dcd2e8baa6..04083263167 100644
--- a/arch/arm/mach-pxa/include/mach/pcm027.h
+++ b/arch/arm/mach-pxa/include/mach/pcm027.h
@@ -23,6 +23,13 @@
* Definitions of CPU card resources only
*/
+/* phyCORE-PXA270 (PCM027) Interrupts */
+#define PCM027_IRQ(x) (IRQ_BOARD_START + (x))
+#define PCM027_BTDET_IRQ PCM027_IRQ(0)
+#define PCM027_FF_RI_IRQ PCM027_IRQ(1)
+#define PCM027_MMCDET_IRQ PCM027_IRQ(2)
+#define PCM027_PM_5V_IRQ PCM027_IRQ(3)
+
/* I2C RTC */
#define PCM027_RTC_IRQ_GPIO 0
#define PCM027_RTC_IRQ IRQ_GPIO(PCM027_RTC_IRQ_GPIO)
diff --git a/arch/arm/mach-pxa/include/mach/ssp.h b/arch/arm/mach-pxa/include/mach/ssp.h
index cb5cb766f0f..be1be5b6db5 100644
--- a/arch/arm/mach-pxa/include/mach/ssp.h
+++ b/arch/arm/mach-pxa/include/mach/ssp.h
@@ -46,6 +46,7 @@ struct ssp_device {
int drcmr_tx;
};
+#ifdef CONFIG_PXA_SSP_LEGACY
/*
* SSP initialisation flags
*/
@@ -78,6 +79,7 @@ void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp);
int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags);
int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
void ssp_exit(struct ssp_dev *dev);
+#endif /* CONFIG_PXA_SSP_LEGACY */
/**
* ssp_write_reg - Write to a SSP register
diff --git a/arch/arm/mach-pxa/include/mach/uncompress.h b/arch/arm/mach-pxa/include/mach/uncompress.h
index 237734b5b1b..759b851ec98 100644
--- a/arch/arm/mach-pxa/include/mach/uncompress.h
+++ b/arch/arm/mach-pxa/include/mach/uncompress.h
@@ -10,20 +10,41 @@
*/
#include <linux/serial_reg.h>
-#include <mach/regs-uart.h>
#include <asm/mach-types.h>
-#define __REG(x) ((volatile unsigned long *)x)
+#define FFUART_BASE (0x40100000)
+#define BTUART_BASE (0x40200000)
+#define STUART_BASE (0x40700000)
-static volatile unsigned long *UART = FFUART;
+static unsigned long uart_base;
+static unsigned int uart_shift;
+static unsigned int uart_is_pxa;
+
+static inline unsigned char uart_read(int offset)
+{
+ return *(volatile unsigned char *)(uart_base + (offset << uart_shift));
+}
+
+static inline void uart_write(unsigned char val, int offset)
+{
+ *(volatile unsigned char *)(uart_base + (offset << uart_shift)) = val;
+}
+
+static inline int uart_is_enabled(void)
+{
+ /* assume enabled by default for non-PXA uarts */
+ return uart_is_pxa ? uart_read(UART_IER) & UART_IER_UUE : 1;
+}
static inline void putc(char c)
{
- if (!(UART[UART_IER] & IER_UUE))
+ if (!uart_is_enabled())
return;
- while (!(UART[UART_LSR] & LSR_TDRQ))
+
+ while (!(uart_read(UART_LSR) & UART_LSR_THRE))
barrier();
- UART[UART_TX] = c;
+
+ uart_write(c, UART_TX);
}
/*
@@ -35,10 +56,21 @@ static inline void flush(void)
static inline void arch_decomp_setup(void)
{
+ /* initialize to default */
+ uart_base = FFUART_BASE;
+ uart_shift = 2;
+ uart_is_pxa = 1;
+
if (machine_is_littleton() || machine_is_intelmote2()
|| machine_is_csb726() || machine_is_stargate2()
|| machine_is_cm_x300() || machine_is_balloon3())
- UART = STUART;
+ uart_base = STUART_BASE;
+
+ if (machine_is_arcom_zeus()) {
+ uart_base = 0x10000000; /* nCS4 */
+ uart_shift = 1;
+ uart_is_pxa = 0;
+ }
}
/*
diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/include/mach/zeus.h
index c387046d2f2..6e119976003 100644
--- a/arch/arm/mach-pxa/include/mach/zeus.h
+++ b/arch/arm/mach-pxa/include/mach/zeus.h
@@ -58,6 +58,8 @@
#define ZEUS_EXT1_GPIO(x) (ZEUS_EXT1_GPIO_BASE + (x))
#define ZEUS_USER_GPIO(x) (ZEUS_USER_GPIO_BASE + (x))
+#define ZEUS_CAN_SHDN_GPIO ZEUS_EXT1_GPIO(2)
+
/*
* CPLD registers:
* Only 4 registers, but spreaded over a 32MB address space.
@@ -68,7 +70,6 @@
#define ZEUS_CPLD_VERSION (ZEUS_CPLD + 0x0000)
#define ZEUS_CPLD_ISA_IRQ (ZEUS_CPLD + 0x1000)
#define ZEUS_CPLD_CONTROL (ZEUS_CPLD + 0x2000)
-#define ZEUS_CPLD_EXTWDOG (ZEUS_CPLD + 0x3000)
/* CPLD register bits */
#define ZEUS_CPLD_CONTROL_CF_RST 0x01
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 1373c22dbb8..d279507fc74 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -83,6 +83,10 @@ static unsigned long lpd270_pin_config[] __initdata = {
GPIO89_USBH1_PEN,
/* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
GPIO45_AC97_SYSCLK,
GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
@@ -121,7 +125,7 @@ static void lpd270_irq_handler(unsigned int irq, struct irq_desc *desc)
pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled;
do {
- GEDR(0) = GPIO_bit(0); /* clear useless edge notification */
+ desc->chip->ack(irq); /* clear useless edge notification */
if (likely(pending)) {
irq = LPD270_IRQ(0) + __ffs(pending);
generic_handle_irq(irq);
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 98ee7e59029..63d65a2a038 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -66,26 +66,14 @@ static unsigned long lubbock_pin_config[] __initdata = {
GPIO25_SSP1_TXD,
GPIO26_SSP1_RXD,
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
/* LCD - 16bpp DSTN */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
+ GPIOxx_LCD_DSTN_16BPP,
/* BTUART */
GPIO42_BTUART_RXD,
@@ -158,7 +146,7 @@ static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc)
{
unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
do {
- GEDR(0) = GPIO_bit(0); /* clear our parent irq */
+ desc->chip->ack(irq); /* clear our parent irq */
if (likely(pending)) {
irq = LUBBOCK_IRQ(0) + __ffs(pending);
generic_handle_irq(irq);
@@ -240,11 +228,18 @@ static struct resource sa1111_resources[] = {
},
};
+static struct sa1111_platform_data sa1111_info = {
+ .irq_base = IRQ_BOARD_END,
+};
+
static struct platform_device sa1111_device = {
.name = "sa1111",
.id = -1,
.num_resources = ARRAY_SIZE(sa1111_resources),
.resource = sa1111_resources,
+ .dev = {
+ .platform_data = &sa1111_info,
+ },
};
/* ADS7846 is connected through SSP ... and if your board has J5 populated,
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 189f330719a..e81dd0c8e40 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -88,26 +88,7 @@ static unsigned long magician_pin_config[] __initdata = {
GPIO112_MMC_CMD,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* QCI */
GPIO12_CIF_DD_7,
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 851ee0fc32e..5543c64da9e 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -60,26 +60,7 @@ static unsigned long mainstone_pin_config[] = {
GPIO15_nCS_1,
/* LCD - 16bpp Active TFT */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
GPIO16_PWM0_OUT, /* Backlight */
/* MMC */
@@ -107,6 +88,10 @@ static unsigned long mainstone_pin_config[] = {
GPIO57_nIOIS16,
/* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
GPIO45_AC97_SYSCLK,
/* Keypad */
@@ -162,7 +147,7 @@ static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc)
{
unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
do {
- GEDR(0) = GPIO_bit(0); /* clear useless edge notification */
+ desc->chip->ack(irq); /* clear useless edge notification */
if (likely(pending)) {
irq = MAINSTONE_IRQ(0) + __ffs(pending);
generic_handle_irq(irq);
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 2466a44d8fd..7a50ed8fce9 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -38,6 +38,7 @@
#include <linux/mtd/physmap.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/regulator/max1586.h>
+#include <linux/slab.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -86,25 +87,7 @@ static unsigned long mioa701_pin_config[] = {
MIO_CFG_OUT(GPIO22_USB_ENABLE, AF0, DRIVE_LOW),
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
+ GPIOxx_LCD_TFT_16BPP,
/* QCI */
GPIO12_CIF_DD_7,
@@ -155,6 +138,10 @@ static unsigned long mioa701_pin_config[] = {
GPIO41_FFUART_RTS,
/* Sound */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
GPIO89_AC97_SYSCLK,
MIO_CFG_IN(GPIO12_HPJACK_INSERT, AF0),
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
new file mode 100644
index 00000000000..8c9c6f0d56b
--- /dev/null
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -0,0 +1,474 @@
+/*
+ * linux/arch/arm/mach-pxa/mxm8x10.c
+ *
+ * Support for the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2006 Marvell International Ltd.
+ * Copyright (C) 2009 Embedian Inc.
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2007-09-04: eric miao <eric.y.miao@gmail.com>
+ * rewrite to align with latest kernel
+ *
+ * 2010-01-09: Edwin Peer <epeer@tmtservices.co.za>
+ * Hennie van der Merwe <hvdmerwe@tmtservices.co.za>
+ * rework for upstream merge
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_8250.h>
+#include <linux/dm9000.h>
+#include <linux/gpio.h>
+
+#include <plat/i2c.h>
+#include <plat/pxa3xx_nand.h>
+
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxa320.h>
+
+#include <mach/mxm8x10.h>
+
+#include "devices.h"
+#include "generic.h"
+
+/* GPIO pin definition
+
+External device stuff - Leave unconfigured for now...
+---------------------
+GPIO0 - DREQ (External DMA Request)
+GPIO3 - nGCS2 (External Chip Select) Where is nGCS0; nGCS1; nGCS4; nGCS5 ?
+GPIO4 - nGCS3
+GPIO15 - EXT_GPIO1
+GPIO16 - EXT_GPIO2
+GPIO17 - EXT_GPIO3
+GPIO24 - EXT_GPIO4
+GPIO25 - EXT_GPIO5
+GPIO26 - EXT_GPIO6
+GPIO27 - EXT_GPIO7
+GPIO28 - EXT_GPIO8
+GPIO29 - EXT_GPIO9
+GPIO30 - EXT_GPIO10
+GPIO31 - EXT_GPIO11
+GPIO57 - EXT_GPIO12
+GPIO74 - EXT_IRQ1
+GPIO75 - EXT_IRQ2
+GPIO76 - EXT_IRQ3
+GPIO77 - EXT_IRQ4
+GPIO78 - EXT_IRQ5
+GPIO79 - EXT_IRQ6
+GPIO80 - EXT_IRQ7
+GPIO81 - EXT_IRQ8
+GPIO87 - VCCIO_PWREN (External Device PWREN)
+
+Dallas 1-Wire - Leave unconfigured for now...
+-------------
+GPIO0_2 - DS - 1Wire
+
+Ethernet
+--------
+GPIO1 - DM9000 PWR
+GPIO9 - DM9K_nIRQ
+GPIO36 - DM9K_RESET
+
+Keypad - Leave unconfigured by for now...
+------
+GPIO1_2 - KP_DKIN0
+GPIO5_2 - KP_MKOUT7
+GPIO82 - KP_DKIN1
+GPIO85 - KP_DKIN2
+GPIO86 - KP_DKIN3
+GPIO113 - KP_MKIN0
+GPIO114 - KP_MKIN1
+GPIO115 - KP_MKIN2
+GPIO116 - KP_MKIN3
+GPIO117 - KP_MKIN4
+GPIO118 - KP_MKIN5
+GPIO119 - KP_MKIN6
+GPIO120 - KP_MKIN7
+GPIO121 - KP_MKOUT0
+GPIO122 - KP_MKOUT1
+GPIO122 - KP_MKOUT2
+GPIO123 - KP_MKOUT3
+GPIO124 - KP_MKOUT4
+GPIO125 - KP_MKOUT5
+GPIO127 - KP_MKOUT6
+
+Data Bus - Leave unconfigured for now...
+--------
+GPIO2 - nWait (Data Bus)
+
+USB Device
+----------
+GPIO4_2 - USBD_PULLUP
+GPIO10 - UTM_CLK (USB Device UTM Clk)
+GPIO49 - USB 2.0 Device UTM_DATA0
+GPIO50 - USB 2.0 Device UTM_DATA1
+GPIO51 - USB 2.0 Device UTM_DATA2
+GPIO52 - USB 2.0 Device UTM_DATA3
+GPIO53 - USB 2.0 Device UTM_DATA4
+GPIO54 - USB 2.0 Device UTM_DATA5
+GPIO55 - USB 2.0 Device UTM_DATA6
+GPIO56 - USB 2.0 Device UTM_DATA7
+GPIO58 - UTM_RXVALID (USB 2.0 Device)
+GPIO59 - UTM_RXACTIVE (USB 2.0 Device)
+GPIO60 - UTM_RXERROR
+GPIO61 - UTM_OPMODE0
+GPIO62 - UTM_OPMODE1
+GPIO71 - USBD_INT (USB Device?)
+GPIO73 - UTM_TXREADY (USB 2.0 Device)
+GPIO83 - UTM_TXVALID (USB 2.0 Device)
+GPIO98 - UTM_RESET (USB 2.0 device)
+GPIO99 - UTM_XCVR_SELECT
+GPIO100 - UTM_TERM_SELECT
+GPIO101 - UTM_SUSPENDM_X
+GPIO102 - UTM_LINESTATE0
+GPIO103 - UTM_LINESTATE1
+
+Card-Bus Interface - Leave unconfigured for now...
+------------------
+GPIO5 - nPIOR (I/O space output enable)
+GPIO6 - nPIOW (I/O space write enable)
+GPIO7 - nIOS16 (Input from I/O space telling size of data bus)
+GPIO8 - nPWAIT (Input for inserting wait states)
+
+LCD
+---
+GPIO6_2 - LDD0
+GPIO7_2 - LDD1
+GPIO8_2 - LDD2
+GPIO9_2 - LDD3
+GPIO11_2 - LDD5
+GPIO12_2 - LDD6
+GPIO13_2 - LDD7
+GPIO14_2 - VSYNC
+GPIO15_2 - HSYNC
+GPIO16_2 - VCLK
+GPIO17_2 - HCLK
+GPIO18_2 - VDEN
+GPIO63 - LDD8 (CPU LCD)
+GPIO64 - LDD9 (CPU LCD)
+GPIO65 - LDD10 (CPU LCD)
+GPIO66 - LDD11 (CPU LCD)
+GPIO67 - LDD12 (CPU LCD)
+GPIO68 - LDD13 (CPU LCD)
+GPIO69 - LDD14 (CPU LCD)
+GPIO70 - LDD15 (CPU LCD)
+GPIO88 - VCCLCD_PWREN (LCD Panel PWREN)
+GPIO97 - BACKLIGHT_EN
+GPIO104 - LCD_PWREN
+
+PWM - Leave unconfigured for now...
+---
+GPIO11 - PWM0
+GPIO12 - PWM1
+GPIO13 - PWM2
+GPIO14 - PWM3
+
+SD-CARD
+-------
+GPIO18 - SDDATA0
+GPIO19 - SDDATA1
+GPIO20 - SDDATA2
+GPIO21 - SDDATA3
+GPIO22 - SDCLK
+GPIO23 - SDCMD
+GPIO72 - SD_WP
+GPIO84 - SD_nIRQ_CD (SD-Card)
+
+I2C
+---
+GPIO32 - I2CSCL
+GPIO33 - I2CSDA
+
+AC97
+----
+GPIO35 - AC97_SDATA_IN
+GPIO37 - AC97_SDATA_OUT
+GPIO38 - AC97_SYNC
+GPIO39 - AC97_BITCLK
+GPIO40 - AC97_nRESET
+
+UART1
+-----
+GPIO41 - UART_RXD1
+GPIO42 - UART_TXD1
+GPIO43 - UART_CTS1
+GPIO44 - UART_DCD1
+GPIO45 - UART_DSR1
+GPIO46 - UART_nRI1
+GPIO47 - UART_DTR1
+GPIO48 - UART_RTS1
+
+UART2
+-----
+GPIO109 - RTS2
+GPIO110 - RXD2
+GPIO111 - TXD2
+GPIO112 - nCTS2
+
+UART3
+-----
+GPIO105 - nCTS3
+GPIO106 - nRTS3
+GPIO107 - TXD3
+GPIO108 - RXD3
+
+SSP3 - Leave unconfigured for now...
+----
+GPIO89 - SSP3_CLK
+GPIO90 - SSP3_SFRM
+GPIO91 - SSP3_TXD
+GPIO92 - SSP3_RXD
+
+SSP4
+GPIO93 - SSP4_CLK
+GPIO94 - SSP4_SFRM
+GPIO95 - SSP4_TXD
+GPIO96 - SSP4_RXD
+*/
+
+static mfp_cfg_t mfp_cfg[] __initdata = {
+ /* USB */
+ GPIO10_UTM_CLK,
+ GPIO49_U2D_PHYDATA_0,
+ GPIO50_U2D_PHYDATA_1,
+ GPIO51_U2D_PHYDATA_2,
+ GPIO52_U2D_PHYDATA_3,
+ GPIO53_U2D_PHYDATA_4,
+ GPIO54_U2D_PHYDATA_5,
+ GPIO55_U2D_PHYDATA_6,
+ GPIO56_U2D_PHYDATA_7,
+ GPIO58_UTM_RXVALID,
+ GPIO59_UTM_RXACTIVE,
+ GPIO60_U2D_RXERROR,
+ GPIO61_U2D_OPMODE0,
+ GPIO62_U2D_OPMODE1,
+ GPIO71_GPIO, /* USBD_INT */
+ GPIO73_UTM_TXREADY,
+ GPIO83_U2D_TXVALID,
+ GPIO98_U2D_RESET,
+ GPIO99_U2D_XCVR_SEL,
+ GPIO100_U2D_TERM_SEL,
+ GPIO101_U2D_SUSPEND,
+ GPIO102_UTM_LINESTATE_0,
+ GPIO103_UTM_LINESTATE_1,
+ GPIO4_2_GPIO | MFP_PULL_HIGH, /* UTM_PULLUP */
+
+ /* DM9000 */
+ GPIO1_GPIO,
+ GPIO9_GPIO,
+ GPIO36_GPIO,
+
+ /* AC97 */
+ GPIO35_AC97_SDATA_IN_0,
+ GPIO37_AC97_SDATA_OUT,
+ GPIO38_AC97_SYNC,
+ GPIO39_AC97_BITCLK,
+ GPIO40_AC97_nACRESET,
+
+ /* UARTS */
+ GPIO41_UART1_RXD,
+ GPIO42_UART1_TXD,
+ GPIO43_UART1_CTS,
+ GPIO44_UART1_DCD,
+ GPIO45_UART1_DSR,
+ GPIO46_UART1_RI,
+ GPIO47_UART1_DTR,
+ GPIO48_UART1_RTS,
+
+ GPIO109_UART2_RTS,
+ GPIO110_UART2_RXD,
+ GPIO111_UART2_TXD,
+ GPIO112_UART2_CTS,
+
+ GPIO105_UART3_CTS,
+ GPIO106_UART3_RTS,
+ GPIO107_UART3_TXD,
+ GPIO108_UART3_RXD,
+
+ GPIO78_GPIO,
+ GPIO79_GPIO,
+ GPIO80_GPIO,
+ GPIO81_GPIO,
+
+ /* I2C */
+ GPIO32_I2C_SCL,
+ GPIO33_I2C_SDA,
+
+ /* MMC */
+ GPIO18_MMC1_DAT0,
+ GPIO19_MMC1_DAT1,
+ GPIO20_MMC1_DAT2,
+ GPIO21_MMC1_DAT3,
+ GPIO22_MMC1_CLK,
+ GPIO23_MMC1_CMD,
+ GPIO72_GPIO | MFP_PULL_HIGH, /* Card Detect */
+ GPIO84_GPIO | MFP_PULL_LOW, /* Write Protect */
+
+ /* IRQ */
+ GPIO74_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ1 */
+ GPIO75_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ2 */
+ GPIO76_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ3 */
+ GPIO77_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ4 */
+ GPIO78_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ5 */
+ GPIO79_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ6 */
+ GPIO80_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ7 */
+ GPIO81_GPIO | MFP_LPM_EDGE_RISE /* EXT_IRQ8 */
+};
+
+/* MMC/MCI Support */
+#if defined(CONFIG_MMC)
+static struct pxamci_platform_data mxm_8x10_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .detect_delay = 1,
+ .gpio_card_detect = MXM_8X10_SD_nCD,
+ .gpio_card_ro = MXM_8X10_SD_WP,
+ .gpio_power = -1
+};
+
+void __init mxm_8x10_mmc_init(void)
+{
+ pxa_set_mci_info(&mxm_8x10_mci_platform_data);
+}
+#endif
+
+/* USB Open Host Controler Interface */
+static struct pxaohci_platform_data mxm_8x10_ohci_platform_data = {
+ .port_mode = PMM_NPS_MODE,
+ .flags = ENABLE_PORT_ALL
+};
+
+void __init mxm_8x10_usb_host_init(void)
+{
+ pxa_set_ohci_info(&mxm_8x10_ohci_platform_data);
+}
+
+/* AC97 Sound Support */
+static struct platform_device mxm_8x10_ac97_device = {
+ .name = "pxa2xx-ac97"
+};
+
+void __init mxm_8x10_ac97_init(void)
+{
+ platform_device_register(&mxm_8x10_ac97_device);
+}
+
+/* NAND flash Support */
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#define NAND_BLOCK_SIZE SZ_128K
+#define NB(x) (NAND_BLOCK_SIZE * (x))
+static struct mtd_partition mxm_8x10_nand_partitions[] = {
+ [0] = {
+ .name = "boot",
+ .size = NB(0x002),
+ .offset = NB(0x000),
+ .mask_flags = MTD_WRITEABLE
+ },
+ [1] = {
+ .name = "kernel",
+ .size = NB(0x010),
+ .offset = NB(0x002),
+ .mask_flags = MTD_WRITEABLE
+ },
+ [2] = {
+ .name = "root",
+ .size = NB(0x36c),
+ .offset = NB(0x012)
+ },
+ [3] = {
+ .name = "bbt",
+ .size = NB(0x082),
+ .offset = NB(0x37e),
+ .mask_flags = MTD_WRITEABLE
+ }
+};
+
+static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
+ .enable_arbiter = 1,
+ .keep_config = 1,
+ .parts = mxm_8x10_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions)
+};
+
+static void __init mxm_8x10_nand_init(void)
+{
+ pxa3xx_set_nand_info(&mxm_8x10_nand_info);
+}
+#else
+static inline void mxm_8x10_nand_init(void) {}
+#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+
+/* Ethernet support: Davicom DM9000 */
+static struct resource dm9k_resources[] = {
+ [0] = {
+ .start = MXM_8X10_ETH_PHYS + 0x300,
+ .end = MXM_8X10_ETH_PHYS + 0x300,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = MXM_8X10_ETH_PHYS + 0x308,
+ .end = MXM_8X10_ETH_PHYS + 0x308,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)),
+ .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE
+ }
+};
+
+static struct dm9000_plat_data dm9k_plat_data = {
+ .flags = DM9000_PLATF_16BITONLY
+};
+
+static struct platform_device dm9k_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9k_resources),
+ .resource = dm9k_resources,
+ .dev = {
+ .platform_data = &dm9k_plat_data
+ }
+};
+
+static void __init mxm_8x10_ethernet_init(void)
+{
+ platform_device_register(&dm9k_device);
+}
+
+/* PXA UARTs */
+static void __init mxm_8x10_uarts_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+}
+
+/* I2C and Real Time Clock */
+static struct i2c_board_info __initdata mxm_8x10_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68)
+ }
+};
+
+static void __init mxm_8x10_i2c_init(void)
+{
+ i2c_register_board_info(0, mxm_8x10_i2c_devices,
+ ARRAY_SIZE(mxm_8x10_i2c_devices));
+ pxa_set_i2c_info(NULL);
+}
+
+void __init mxm_8x10_barebones_init(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));
+
+ mxm_8x10_uarts_init();
+ mxm_8x10_nand_init();
+ mxm_8x10_i2c_init();
+ mxm_8x10_ethernet_init();
+}
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index e100af78b16..f70c75b3876 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -83,26 +83,7 @@ static unsigned long palmld_pin_config[] __initdata = {
GPIO105_KP_MKOUT_2,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* PWM */
GPIO16_PWM0_OUT,
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 8fe3ec27568..d902a813aae 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -87,26 +87,7 @@ static unsigned long palmt5_pin_config[] __initdata = {
GPIO105_KP_MKOUT_2,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* PWM */
GPIO16_PWM0_OUT,
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index b992f07ece2..717d7a63867 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -84,26 +84,7 @@ static unsigned long palmtc_pin_config[] __initdata = {
GPIO36_GPIO, /* pullup */
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* MATRIX KEYPAD */
GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 0 */
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index dc728d6ab94..3d284ff1a64 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -73,26 +73,7 @@ static unsigned long palmte2_pin_config[] __initdata = {
GPIO47_FICP_TXD,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* GPIO KEYS */
GPIO5_GPIO, /* notes */
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index b433bb49671..d8b4469607a 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -99,25 +99,7 @@ static unsigned long treo_pin_config[] __initdata = {
GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH, /* Hotsync button */
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
+ GPIOxx_LCD_TFT_16BPP,
/* Quick Capture Interface */
GPIO84_CIF_FV,
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index b37a025c0b7..007b58c11f8 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -110,26 +110,7 @@ static unsigned long palmtx_pin_config[] __initdata = {
GPIO105_KP_MKOUT_2,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* FFUART */
GPIO34_FFUART_RXD,
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index 1c5d68a9451..3a7925ca394 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -95,26 +95,8 @@ static unsigned long palmz72_pin_config[] __initdata = {
GPIO105_KP_MKOUT_2,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
+
GPIO20_GPIO, /* bl power */
GPIO21_GPIO, /* LCD border switch */
GPIO22_GPIO, /* LCD border color */
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index d5255ae74fe..9d0ecea1760 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -58,6 +58,12 @@ static unsigned long pcm990_pin_config[] __initdata = {
/* I2C */
GPIO117_I2C_SCL,
GPIO118_I2C_SDA,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
};
/*
@@ -259,8 +265,7 @@ static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
do {
- GEDR(PCM990_CTRL_INT_IRQ_GPIO) =
- GPIO_bit(PCM990_CTRL_INT_IRQ_GPIO);
+ desc->chip->ack(irq); /* clear our parent IRQ */
if (likely(pending)) {
irq = PCM027_IRQ(0) + __ffs(pending);
generic_handle_irq(irq);
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 7693355ee63..166c15f6291 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/suspend.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <mach/pm.h>
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index c2b938a4d5c..d58a52415d7 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -91,26 +91,7 @@ static unsigned long poodle_pin_config[] __initdata = {
GPIO35_FFUART_CTS,
/* LCD */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* PC Card */
GPIO48_nPOE,
@@ -193,11 +174,18 @@ static struct resource locomo_resources[] = {
},
};
+static struct locomo_platform_data locomo_info = {
+ .irq_base = IRQ_BOARD_START,
+};
+
struct platform_device poodle_locomo_device = {
.name = "locomo",
.id = 0,
.num_resources = ARRAY_SIZE(locomo_resources),
.resource = locomo_resources,
+ .dev = {
+ .platform_data = &locomo_info,
+ },
};
EXPORT_SYMBOL(poodle_locomo_device);
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index d783123e2d4..0af36177ff0 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -40,6 +40,25 @@ void pxa27x_clear_otgph(void)
}
EXPORT_SYMBOL(pxa27x_clear_otgph);
+static unsigned long ac97_reset_config[] = {
+ GPIO95_AC97_nRESET,
+ GPIO95_GPIO,
+ GPIO113_AC97_nRESET,
+ GPIO113_GPIO,
+};
+
+void pxa27x_assert_ac97reset(int reset_gpio, int on)
+{
+ if (reset_gpio == 113)
+ pxa2xx_mfp_config(on ? &ac97_reset_config[0] :
+ &ac97_reset_config[1], 1);
+
+ if (reset_gpio == 95)
+ pxa2xx_mfp_config(on ? &ac97_reset_config[2] :
+ &ac97_reset_config[3], 1);
+}
+EXPORT_SYMBOL_GPL(pxa27x_assert_ac97reset);
+
/* Crystal clock: 13MHz */
#define BASE_CLK 13000000
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
new file mode 100644
index 00000000000..44bb675e47f
--- /dev/null
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -0,0 +1,1106 @@
+/*
+ * arch/arm/mach-pxa/raumfeld.c
+ *
+ * Support for the following Raumfeld devices:
+ *
+ * * Controller
+ * * Connector
+ * * Speaker S/M
+ *
+ * See http://www.raumfeld.com for details.
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.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/init.h>
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/input.h>
+#include <linux/rotary_encoder.h>
+#include <linux/gpio_keys.h>
+#include <linux/input/eeti_ts.h>
+#include <linux/leds.h>
+#include <linux/w1-gpio.h>
+#include <linux/sched.h>
+#include <linux/pwm_backlight.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/lis3lv02d.h>
+#include <linux/pda_power.h>
+#include <linux/power_supply.h>
+#include <linux/regulator/max8660.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa3xx.h>
+#include <mach/mfp-pxa300.h>
+#include <mach/ohci.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <plat/i2c.h>
+#include <plat/pxa3xx_nand.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+/* common GPIO definitions */
+
+/* inputs */
+#define GPIO_ON_OFF (14)
+#define GPIO_VOLENC_A (19)
+#define GPIO_VOLENC_B (20)
+#define GPIO_CHARGE_DONE (23)
+#define GPIO_CHARGE_IND (27)
+#define GPIO_TOUCH_IRQ (32)
+#define GPIO_ETH_IRQ (40)
+#define GPIO_SPI_MISO (98)
+#define GPIO_ACCEL_IRQ (104)
+#define GPIO_RESCUE_BOOT (115)
+#define GPIO_DOCK_DETECT (116)
+#define GPIO_KEY1 (117)
+#define GPIO_KEY2 (118)
+#define GPIO_KEY3 (119)
+#define GPIO_CHARGE_USB_OK (112)
+#define GPIO_CHARGE_DC_OK (101)
+#define GPIO_CHARGE_USB_SUSP (102)
+
+/* outputs */
+#define GPIO_SHUTDOWN_SUPPLY (16)
+#define GPIO_SHUTDOWN_BATT (18)
+#define GPIO_CHRG_PEN2 (31)
+#define GPIO_TFT_VA_EN (33)
+#define GPIO_SPDIF_CS (34)
+#define GPIO_LED2 (35)
+#define GPIO_LED1 (36)
+#define GPIO_SPDIF_RESET (38)
+#define GPIO_SPI_CLK (95)
+#define GPIO_MCLK_DAC_CS (96)
+#define GPIO_SPI_MOSI (97)
+#define GPIO_W1_PULLUP_ENABLE (105)
+#define GPIO_DISPLAY_ENABLE (106)
+#define GPIO_MCLK_RESET (111)
+#define GPIO_W2W_RESET (113)
+#define GPIO_W2W_PDN (114)
+#define GPIO_CODEC_RESET (120)
+#define GPIO_AUDIO_VA_ENABLE (124)
+#define GPIO_ACCEL_CS (125)
+#define GPIO_ONE_WIRE (126)
+
+/*
+ * GPIO configurations
+ */
+static mfp_cfg_t raumfeld_controller_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO77_UART1_RXD,
+ GPIO78_UART1_TXD,
+ GPIO79_UART1_CTS,
+ GPIO81_UART1_DSR,
+ GPIO83_UART1_DTR,
+ GPIO84_UART1_RTS,
+
+ /* UART3 */
+ GPIO110_UART3_RXD,
+
+ /* USB Host */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+
+ /* I2C */
+ GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+ GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+ /* SPI */
+ GPIO34_GPIO, /* SPDIF_CS */
+ GPIO96_GPIO, /* MCLK_CS */
+ GPIO125_GPIO, /* ACCEL_CS */
+
+ /* MMC */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD,
+
+ /* One-wire */
+ GPIO126_GPIO | MFP_LPM_FLOAT,
+ GPIO105_GPIO | MFP_PULL_LOW | MFP_LPM_PULL_LOW,
+
+ /* CHRG_USB_OK */
+ GPIO101_GPIO | MFP_PULL_HIGH,
+ /* CHRG_USB_OK */
+ GPIO112_GPIO | MFP_PULL_HIGH,
+ /* CHRG_USB_SUSP */
+ GPIO102_GPIO,
+ /* DISPLAY_ENABLE */
+ GPIO106_GPIO,
+ /* DOCK_DETECT */
+ GPIO116_GPIO | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+ /* LCD */
+ GPIO54_LCD_LDD_0,
+ GPIO55_LCD_LDD_1,
+ GPIO56_LCD_LDD_2,
+ GPIO57_LCD_LDD_3,
+ GPIO58_LCD_LDD_4,
+ GPIO59_LCD_LDD_5,
+ GPIO60_LCD_LDD_6,
+ GPIO61_LCD_LDD_7,
+ GPIO62_LCD_LDD_8,
+ GPIO63_LCD_LDD_9,
+ GPIO64_LCD_LDD_10,
+ GPIO65_LCD_LDD_11,
+ GPIO66_LCD_LDD_12,
+ GPIO67_LCD_LDD_13,
+ GPIO68_LCD_LDD_14,
+ GPIO69_LCD_LDD_15,
+ GPIO70_LCD_LDD_16,
+ GPIO71_LCD_LDD_17,
+ GPIO72_LCD_FCLK,
+ GPIO73_LCD_LCLK,
+ GPIO74_LCD_PCLK,
+ GPIO75_LCD_BIAS,
+};
+
+static mfp_cfg_t raumfeld_connector_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO77_UART1_RXD,
+ GPIO78_UART1_TXD,
+ GPIO79_UART1_CTS,
+ GPIO81_UART1_DSR,
+ GPIO83_UART1_DTR,
+ GPIO84_UART1_RTS,
+
+ /* UART3 */
+ GPIO110_UART3_RXD,
+
+ /* USB Host */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+
+ /* I2C */
+ GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+ GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+ /* SPI */
+ GPIO34_GPIO, /* SPDIF_CS */
+ GPIO96_GPIO, /* MCLK_CS */
+ GPIO125_GPIO, /* ACCEL_CS */
+
+ /* MMC */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD,
+
+ /* Ethernet */
+ GPIO1_nCS2, /* CS */
+ GPIO40_GPIO | MFP_PULL_HIGH, /* IRQ */
+
+ /* SSP for I2S */
+ GPIO85_SSP1_SCLK,
+ GPIO89_SSP1_EXTCLK,
+ GPIO86_SSP1_FRM,
+ GPIO87_SSP1_TXD,
+ GPIO88_SSP1_RXD,
+ GPIO90_SSP1_SYSCLK,
+
+ /* SSP2 for S/PDIF */
+ GPIO25_SSP2_SCLK,
+ GPIO26_SSP2_FRM,
+ GPIO27_SSP2_TXD,
+ GPIO29_SSP2_EXTCLK,
+
+ /* LEDs */
+ GPIO35_GPIO | MFP_LPM_PULL_LOW,
+ GPIO36_GPIO | MFP_LPM_DRIVE_HIGH,
+};
+
+static mfp_cfg_t raumfeld_speaker_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO77_UART1_RXD,
+ GPIO78_UART1_TXD,
+ GPIO79_UART1_CTS,
+ GPIO81_UART1_DSR,
+ GPIO83_UART1_DTR,
+ GPIO84_UART1_RTS,
+
+ /* UART3 */
+ GPIO110_UART3_RXD,
+
+ /* USB Host */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+
+ /* I2C */
+ GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+ GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+ /* SPI */
+ GPIO34_GPIO, /* SPDIF_CS */
+ GPIO96_GPIO, /* MCLK_CS */
+ GPIO125_GPIO, /* ACCEL_CS */
+
+ /* MMC */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD,
+
+ /* Ethernet */
+ GPIO1_nCS2, /* CS */
+ GPIO40_GPIO | MFP_PULL_HIGH, /* IRQ */
+
+ /* SSP for I2S */
+ GPIO85_SSP1_SCLK,
+ GPIO89_SSP1_EXTCLK,
+ GPIO86_SSP1_FRM,
+ GPIO87_SSP1_TXD,
+ GPIO88_SSP1_RXD,
+ GPIO90_SSP1_SYSCLK,
+
+ /* LEDs */
+ GPIO35_GPIO | MFP_LPM_PULL_LOW,
+ GPIO36_GPIO | MFP_LPM_DRIVE_HIGH,
+};
+
+/*
+ * SMSC LAN9220 Ethernet
+ */
+
+static struct resource smc91x_resources[] = {
+ {
+ .start = PXA3xx_CS2_PHYS,
+ .end = PXA3xx_CS2_PHYS + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = gpio_to_irq(GPIO_ETH_IRQ),
+ .end = gpio_to_irq(GPIO_ETH_IRQ),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+ }
+};
+
+static struct smsc911x_platform_config raumfeld_smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &raumfeld_smsc911x_config,
+ }
+};
+
+/**
+ * NAND
+ */
+
+static struct mtd_partition raumfeld_nand_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0,
+ .size = 0xa0000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "BootloaderEnvironment",
+ .offset = 0xa0000,
+ .size = 0x20000,
+ },
+ {
+ .name = "BootloaderSplashScreen",
+ .offset = 0xc0000,
+ .size = 0x60000,
+ },
+ {
+ .name = "UBI",
+ .offset = 0x120000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
+ .enable_arbiter = 1,
+ .keep_config = 1,
+ .parts = raumfeld_nand_partitions,
+ .nr_parts = ARRAY_SIZE(raumfeld_nand_partitions),
+};
+
+/**
+ * USB (OHCI) support
+ */
+
+static struct pxaohci_platform_data raumfeld_ohci_info = {
+ .port_mode = PMM_GLOBAL_MODE,
+ .flags = ENABLE_PORT1,
+};
+
+/**
+ * Rotary encoder input device
+ */
+
+static struct rotary_encoder_platform_data raumfeld_rotary_encoder_info = {
+ .steps = 24,
+ .axis = REL_X,
+ .relative_axis = 1,
+ .gpio_a = GPIO_VOLENC_A,
+ .gpio_b = GPIO_VOLENC_B,
+ .inverted_a = 1,
+ .inverted_b = 0,
+};
+
+static struct platform_device rotary_encoder_device = {
+ .name = "rotary-encoder",
+ .id = 0,
+ .dev = {
+ .platform_data = &raumfeld_rotary_encoder_info,
+ }
+};
+
+/**
+ * GPIO buttons
+ */
+
+static struct gpio_keys_button gpio_keys_button[] = {
+ {
+ .code = KEY_F1,
+ .type = EV_KEY,
+ .gpio = GPIO_KEY1,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "Button 1",
+ },
+ {
+ .code = KEY_F2,
+ .type = EV_KEY,
+ .gpio = GPIO_KEY2,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "Button 2",
+ },
+ {
+ .code = KEY_F3,
+ .type = EV_KEY,
+ .gpio = GPIO_KEY3,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "Button 3",
+ },
+ {
+ .code = KEY_F4,
+ .type = EV_KEY,
+ .gpio = GPIO_RESCUE_BOOT,
+ .active_low = 0,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "rescue boot button",
+ },
+ {
+ .code = KEY_F5,
+ .type = EV_KEY,
+ .gpio = GPIO_DOCK_DETECT,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "dock detect",
+ },
+ {
+ .code = KEY_F6,
+ .type = EV_KEY,
+ .gpio = GPIO_ON_OFF,
+ .active_low = 0,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "on_off button",
+ },
+};
+
+static struct gpio_keys_platform_data gpio_keys_platform_data = {
+ .buttons = gpio_keys_button,
+ .nbuttons = ARRAY_SIZE(gpio_keys_button),
+ .rep = 0,
+};
+
+static struct platform_device raumfeld_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_keys_platform_data,
+ }
+};
+
+/**
+ * GPIO LEDs
+ */
+
+static struct gpio_led raumfeld_leds[] = {
+ {
+ .name = "raumfeld:1",
+ .gpio = GPIO_LED1,
+ .active_low = 1,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "raumfeld:2",
+ .gpio = GPIO_LED2,
+ .active_low = 0,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ }
+};
+
+static struct gpio_led_platform_data raumfeld_led_platform_data = {
+ .leds = raumfeld_leds,
+ .num_leds = ARRAY_SIZE(raumfeld_leds),
+};
+
+static struct platform_device raumfeld_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &raumfeld_led_platform_data,
+ },
+};
+
+/**
+ * One-wire (W1 bus) support
+ */
+
+static void w1_enable_external_pullup(int enable)
+{
+ gpio_set_value(GPIO_W1_PULLUP_ENABLE, enable);
+ msleep(100);
+}
+
+static struct w1_gpio_platform_data w1_gpio_platform_data = {
+ .pin = GPIO_ONE_WIRE,
+ .is_open_drain = 0,
+ .enable_external_pullup = w1_enable_external_pullup,
+};
+
+struct platform_device raumfeld_w1_gpio_device = {
+ .name = "w1-gpio",
+ .dev = {
+ .platform_data = &w1_gpio_platform_data
+ }
+};
+
+static void __init raumfeld_w1_init(void)
+{
+ int ret = gpio_request(GPIO_W1_PULLUP_ENABLE,
+ "W1 external pullup enable");
+
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_W1_PULLUP_ENABLE\n");
+ else
+ gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0);
+
+ platform_device_register(&raumfeld_w1_gpio_device);
+}
+
+/**
+ * Framebuffer device
+ */
+
+/* PWM controlled backlight */
+static struct platform_pwm_backlight_data raumfeld_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 100,
+ .dft_brightness = 100,
+ /* 10000 ns = 10 ms ^= 100 kHz */
+ .pwm_period_ns = 10000,
+};
+
+static struct platform_device raumfeld_pwm_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &raumfeld_pwm_backlight_data,
+ }
+};
+
+/* LT3593 controlled backlight */
+static struct gpio_led raumfeld_lt3593_led = {
+ .name = "backlight",
+ .gpio = mfp_to_gpio(MFP_PIN_GPIO17),
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+};
+
+static struct gpio_led_platform_data raumfeld_lt3593_platform_data = {
+ .leds = &raumfeld_lt3593_led,
+ .num_leds = 1,
+};
+
+static struct platform_device raumfeld_lt3593_device = {
+ .name = "leds-lt3593",
+ .id = -1,
+ .dev = {
+ .platform_data = &raumfeld_lt3593_platform_data,
+ },
+};
+
+static struct pxafb_mode_info sharp_lq043t3dx02_mode = {
+ .pixclock = 111000,
+ .xres = 480,
+ .yres = 272,
+ .bpp = 16,
+ .hsync_len = 4,
+ .left_margin = 2,
+ .right_margin = 1,
+ .vsync_len = 1,
+ .upper_margin = 3,
+ .lower_margin = 1,
+ .sync = 0,
+};
+
+static struct pxafb_mach_info raumfeld_sharp_lcd_info = {
+ .modes = &sharp_lq043t3dx02_mode,
+ .num_modes = 1,
+ .video_mem_size = 0x400000,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static void __init raumfeld_lcd_init(void)
+{
+ int ret;
+
+ set_pxa_fb_info(&raumfeld_sharp_lcd_info);
+
+ /* Earlier devices had the backlight regulator controlled
+ * via PWM, later versions use another controller for that */
+ if ((system_rev & 0xff) < 2) {
+ mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT;
+ pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1);
+ platform_device_register(&raumfeld_pwm_backlight_device);
+ } else
+ platform_device_register(&raumfeld_lt3593_device);
+
+ ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_TFT_VA_EN\n");
+ else
+ gpio_direction_output(GPIO_TFT_VA_EN, 1);
+
+ ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n");
+ else
+ gpio_direction_output(GPIO_DISPLAY_ENABLE, 1);
+}
+
+/**
+ * SPI devices
+ */
+
+struct spi_gpio_platform_data raumfeld_spi_platform_data = {
+ .sck = GPIO_SPI_CLK,
+ .mosi = GPIO_SPI_MOSI,
+ .miso = GPIO_SPI_MISO,
+ .num_chipselect = 3,
+};
+
+static struct platform_device raumfeld_spi_device = {
+ .name = "spi_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &raumfeld_spi_platform_data,
+ }
+};
+
+static struct lis3lv02d_platform_data lis3_pdata = {
+ .click_flags = LIS3_CLICK_SINGLE_X |
+ LIS3_CLICK_SINGLE_Y |
+ LIS3_CLICK_SINGLE_Z,
+ .irq_cfg = LIS3_IRQ1_CLICK | LIS3_IRQ2_CLICK,
+ .wakeup_flags = LIS3_WAKEUP_X_LO | LIS3_WAKEUP_X_HI |
+ LIS3_WAKEUP_Y_LO | LIS3_WAKEUP_Y_HI |
+ LIS3_WAKEUP_Z_LO | LIS3_WAKEUP_Z_HI,
+ .wakeup_thresh = 10,
+ .click_thresh_x = 10,
+ .click_thresh_y = 10,
+ .click_thresh_z = 10,
+};
+
+#define SPI_AK4104 \
+{ \
+ .modalias = "ak4104", \
+ .max_speed_hz = 10000, \
+ .bus_num = 0, \
+ .chip_select = 0, \
+ .controller_data = (void *) GPIO_SPDIF_CS, \
+}
+
+#define SPI_LIS3 \
+{ \
+ .modalias = "lis3lv02d_spi", \
+ .max_speed_hz = 1000000, \
+ .bus_num = 0, \
+ .chip_select = 1, \
+ .controller_data = (void *) GPIO_ACCEL_CS, \
+ .platform_data = &lis3_pdata, \
+ .irq = gpio_to_irq(GPIO_ACCEL_IRQ), \
+}
+
+#define SPI_DAC7512 \
+{ \
+ .modalias = "dac7512", \
+ .max_speed_hz = 1000000, \
+ .bus_num = 0, \
+ .chip_select = 2, \
+ .controller_data = (void *) GPIO_MCLK_DAC_CS, \
+}
+
+static struct spi_board_info connector_spi_devices[] __initdata = {
+ SPI_AK4104,
+ SPI_DAC7512,
+};
+
+static struct spi_board_info speaker_spi_devices[] __initdata = {
+ SPI_DAC7512,
+};
+
+static struct spi_board_info controller_spi_devices[] __initdata = {
+ SPI_LIS3,
+};
+
+/**
+ * MMC for Marvell Libertas 8688 via SDIO
+ */
+
+static int raumfeld_mci_init(struct device *dev, irq_handler_t isr, void *data)
+{
+ gpio_set_value(GPIO_W2W_RESET, 1);
+ gpio_set_value(GPIO_W2W_PDN, 1);
+
+ return 0;
+}
+
+static void raumfeld_mci_exit(struct device *dev, void *data)
+{
+ gpio_set_value(GPIO_W2W_RESET, 0);
+ gpio_set_value(GPIO_W2W_PDN, 0);
+}
+
+static struct pxamci_platform_data raumfeld_mci_platform_data = {
+ .init = raumfeld_mci_init,
+ .exit = raumfeld_mci_exit,
+ .detect_delay = 20,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+/*
+ * External power / charge logic
+ */
+
+static int power_supply_init(struct device *dev)
+{
+ return 0;
+}
+
+static void power_supply_exit(struct device *dev)
+{
+}
+
+static int raumfeld_is_ac_online(void)
+{
+ return !gpio_get_value(GPIO_CHARGE_DC_OK);
+}
+
+static int raumfeld_is_usb_online(void)
+{
+ return 0;
+}
+
+static char *raumfeld_power_supplicants[] = { "ds2760-battery.0" };
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = raumfeld_is_ac_online,
+ .is_usb_online = raumfeld_is_usb_online,
+ .exit = power_supply_exit,
+ .supplied_to = raumfeld_power_supplicants,
+ .num_supplicants = ARRAY_SIZE(raumfeld_power_supplicants)
+};
+
+static struct resource power_supply_resources[] = {
+ {
+ .name = "ac",
+ .flags = IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+ .start = GPIO_CHARGE_DC_OK,
+ .end = GPIO_CHARGE_DC_OK,
+ },
+};
+
+static irqreturn_t charge_done_irq(int irq, void *dev_id)
+{
+ struct power_supply *psy;
+
+ psy = power_supply_get_by_name("ds2760-battery.0");
+
+ if (psy)
+ power_supply_set_battery_charged(psy);
+
+ return IRQ_HANDLED;
+}
+
+static struct platform_device raumfeld_power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &power_supply_info,
+ },
+ .resource = power_supply_resources,
+ .num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+static void __init raumfeld_power_init(void)
+{
+ int ret;
+
+ /* Set PEN2 high to enable maximum charge current */
+ ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_CHRG_PEN2\n");
+ else
+ gpio_direction_output(GPIO_CHRG_PEN2, 1);
+
+ ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_CHARGE_DC_OK\n");
+
+ ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_CHARGE_USB_SUSP\n");
+ else
+ gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0);
+
+ power_supply_resources[0].start = gpio_to_irq(GPIO_CHARGE_DC_OK);
+ power_supply_resources[0].end = gpio_to_irq(GPIO_CHARGE_DC_OK);
+
+ ret = request_irq(gpio_to_irq(GPIO_CHARGE_DONE),
+ &charge_done_irq, IORESOURCE_IRQ_LOWEDGE,
+ "charge_done", NULL);
+
+ if (ret < 0)
+ printk(KERN_ERR "%s: unable to register irq %d\n", __func__,
+ GPIO_CHARGE_DONE);
+ else
+ platform_device_register(&raumfeld_power_supply);
+}
+
+/* Fixed regulator for AUDIO_VA, 0-0048 maps to the cs4270 codec device */
+
+static struct regulator_consumer_supply audio_va_consumer_supply =
+ REGULATOR_SUPPLY("va", "0-0048");
+
+struct regulator_init_data audio_va_initdata = {
+ .consumer_supplies = &audio_va_consumer_supply,
+ .num_consumer_supplies = 1,
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct fixed_voltage_config audio_va_config = {
+ .supply_name = "audio_va",
+ .microvolts = 5000000,
+ .gpio = GPIO_AUDIO_VA_ENABLE,
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &audio_va_initdata,
+};
+
+static struct platform_device audio_va_device = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &audio_va_config,
+ },
+};
+
+/* Dummy supplies for Codec's VD/VLC */
+
+static struct regulator_consumer_supply audio_dummy_supplies[] = {
+ REGULATOR_SUPPLY("vd", "0-0048"),
+ REGULATOR_SUPPLY("vlc", "0-0048"),
+};
+
+struct regulator_init_data audio_dummy_initdata = {
+ .consumer_supplies = audio_dummy_supplies,
+ .num_consumer_supplies = ARRAY_SIZE(audio_dummy_supplies),
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct fixed_voltage_config audio_dummy_config = {
+ .supply_name = "audio_vd",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &audio_dummy_initdata,
+};
+
+static struct platform_device audio_supply_dummy_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &audio_dummy_config,
+ },
+};
+
+static struct platform_device *audio_regulator_devices[] = {
+ &audio_va_device,
+ &audio_supply_dummy_device,
+};
+
+/**
+ * Regulator support via MAX8660
+ */
+
+static struct regulator_consumer_supply vcc_mmc_supply =
+ REGULATOR_SUPPLY("vmmc", "pxa2xx-mci.0");
+
+static struct regulator_init_data vcc_mmc_init_data = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ },
+ .consumer_supplies = &vcc_mmc_supply,
+ .num_consumer_supplies = 1,
+};
+
+struct max8660_subdev_data max8660_v6_subdev_data = {
+ .id = MAX8660_V6,
+ .name = "vmmc",
+ .platform_data = &vcc_mmc_init_data,
+};
+
+static struct max8660_platform_data max8660_pdata = {
+ .subdevs = &max8660_v6_subdev_data,
+ .num_subdevs = 1,
+};
+
+/**
+ * I2C devices
+ */
+
+static struct i2c_board_info raumfeld_pwri2c_board_info = {
+ .type = "max8660",
+ .addr = 0x34,
+ .platform_data = &max8660_pdata,
+};
+
+static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = {
+ .type = "cs4270",
+ .addr = 0x48,
+};
+
+static struct eeti_ts_platform_data eeti_ts_pdata = {
+ .irq_active_high = 1,
+};
+
+static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = {
+ .type = "eeti_ts",
+ .addr = 0x0a,
+ .irq = gpio_to_irq(GPIO_TOUCH_IRQ),
+ .platform_data = &eeti_ts_pdata,
+};
+
+static struct platform_device *raumfeld_common_devices[] = {
+ &raumfeld_gpio_keys_device,
+ &raumfeld_led_device,
+ &raumfeld_spi_device,
+};
+
+static void __init raumfeld_audio_init(void)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset");
+ if (ret < 0)
+ pr_warning("unable to request GPIO_CODEC_RESET\n");
+ else
+ gpio_direction_output(GPIO_CODEC_RESET, 1);
+
+ ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset");
+ if (ret < 0)
+ pr_warning("unable to request GPIO_SPDIF_RESET\n");
+ else
+ gpio_direction_output(GPIO_SPDIF_RESET, 1);
+
+ ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset");
+ if (ret < 0)
+ pr_warning("unable to request GPIO_MCLK_RESET\n");
+ else
+ gpio_direction_output(GPIO_MCLK_RESET, 1);
+
+ platform_add_devices(ARRAY_AND_SIZE(audio_regulator_devices));
+}
+
+static void __init raumfeld_common_init(void)
+{
+ int ret;
+
+ /* The on/off button polarity has changed after revision 1 */
+ if ((system_rev & 0xff) > 1) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(gpio_keys_button); i++)
+ if (!strcmp(gpio_keys_button[i].desc, "on/off button"))
+ gpio_keys_button[i].active_low = 1;
+ }
+
+ enable_irq_wake(IRQ_WAKEUP0);
+
+ pxa3xx_set_nand_info(&raumfeld_nand_info);
+ pxa3xx_set_i2c_power_info(NULL);
+ pxa_set_ohci_info(&raumfeld_ohci_info);
+ pxa_set_mci_info(&raumfeld_mci_platform_data);
+ pxa_set_i2c_info(NULL);
+ pxa_set_ffuart_info(NULL);
+
+ ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_W2W_RESET\n");
+ else
+ gpio_direction_output(GPIO_W2W_RESET, 0);
+
+ ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_W2W_PDN\n");
+ else
+ gpio_direction_output(GPIO_W2W_PDN, 0);
+
+ /* this can be used to switch off the device */
+ ret = gpio_request(GPIO_SHUTDOWN_SUPPLY,
+ "supply shutdown");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n");
+ else
+ gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0);
+
+ platform_add_devices(ARRAY_AND_SIZE(raumfeld_common_devices));
+ i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1);
+}
+
+static void __init raumfeld_controller_init(void)
+{
+ int ret;
+
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_controller_pin_config));
+ platform_device_register(&rotary_encoder_device);
+ spi_register_board_info(ARRAY_AND_SIZE(controller_spi_devices));
+ i2c_register_board_info(0, &raumfeld_controller_i2c_board_info, 1);
+
+ ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_SHUTDOWN_BATT\n");
+ else
+ gpio_direction_output(GPIO_SHUTDOWN_BATT, 0);
+
+ raumfeld_common_init();
+ raumfeld_power_init();
+ raumfeld_lcd_init();
+ raumfeld_w1_init();
+}
+
+static void __init raumfeld_connector_init(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_connector_pin_config));
+ spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices));
+ i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1);
+
+ platform_device_register(&smc91x_device);
+
+ raumfeld_audio_init();
+ raumfeld_common_init();
+}
+
+static void __init raumfeld_speaker_init(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_speaker_pin_config));
+ spi_register_board_info(ARRAY_AND_SIZE(speaker_spi_devices));
+ i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1);
+
+ platform_device_register(&smc91x_device);
+ platform_device_register(&rotary_encoder_device);
+
+ raumfeld_audio_init();
+ raumfeld_common_init();
+}
+
+/* physical memory regions */
+#define RAUMFELD_SDRAM_BASE 0xa0000000 /* SDRAM region */
+
+#ifdef CONFIG_MACH_RAUMFELD_RC
+MACHINE_START(RAUMFELD_RC, "Raumfeld Controller")
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = RAUMFELD_SDRAM_BASE + 0x100,
+ .init_machine = raumfeld_controller_init,
+ .map_io = pxa_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_RAUMFELD_CONNECTOR
+MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = RAUMFELD_SDRAM_BASE + 0x100,
+ .init_machine = raumfeld_connector_init,
+ .map_io = pxa_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_RAUMFELD_SPEAKER
+MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = RAUMFELD_SDRAM_BASE + 0x100,
+ .init_machine = raumfeld_speaker_init,
+ .map_io = pxa_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 67229a1ef55..463d874bb86 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -900,7 +900,7 @@ static struct platform_suspend_ops sharpsl_pm_ops = {
};
#endif
-static int __init sharpsl_pm_probe(struct platform_device *pdev)
+static int __devinit sharpsl_pm_probe(struct platform_device *pdev)
{
int ret;
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 28352c0b8c3..19b5109d980 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -56,25 +56,7 @@ static unsigned long spitz_pin_config[] __initdata = {
GPIO80_nCS_4, /* SCOOP #1 */
/* LCD - 16bpp Active TFT */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
+ GPIOxx_LCD_TFT_16BPP,
/* PC Card */
GPIO48_nPOE,
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 9ebe658590f..a81d6dbf662 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -35,6 +35,8 @@
#include <mach/ssp.h>
#include <mach/regs-ssp.h>
+#ifdef CONFIG_PXA_SSP_LEGACY
+
#define TIMEOUT 100000
static irqreturn_t ssp_interrupt(int irq, void *dev_id)
@@ -303,6 +305,7 @@ void ssp_exit(struct ssp_dev *dev)
clk_disable(ssp->clk);
ssp_free(ssp);
}
+#endif /* CONFIG_PXA_SSP_LEGACY */
static DEFINE_MUTEX(ssp_lock);
static LIST_HEAD(ssp_list);
@@ -488,6 +491,7 @@ static void __exit pxa_ssp_exit(void)
arch_initcall(pxa_ssp_init);
module_exit(pxa_ssp_exit);
+#ifdef CONFIG_PXA_SSP_LEGACY
EXPORT_SYMBOL(ssp_write_word);
EXPORT_SYMBOL(ssp_read_word);
EXPORT_SYMBOL(ssp_flush);
@@ -498,6 +502,7 @@ EXPORT_SYMBOL(ssp_restore_state);
EXPORT_SYMBOL(ssp_init);
EXPORT_SYMBOL(ssp_exit);
EXPORT_SYMBOL(ssp_config);
+#endif
MODULE_DESCRIPTION("PXA SSP driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index a98a434f011..2041eb1d90b 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -764,11 +764,6 @@ static void __init stargate2_init(void)
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
- /* spi chip selects */
- gpio_direction_output(37, 0);
- gpio_direction_output(24, 0);
- gpio_direction_output(39, 0);
-
platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 750c448db67..293e40aeaf2 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -76,14 +76,12 @@ pxa_ost0_interrupt(int irq, void *dev_id)
static int
pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
{
- unsigned long flags, next, oscr;
+ unsigned long next, oscr;
- raw_local_irq_save(flags);
OIER |= OIER_E0;
next = OSCR + delta;
OSMR0 = next;
oscr = OSCR;
- raw_local_irq_restore(flags);
return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
}
@@ -91,23 +89,17 @@ pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
static void
pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
- unsigned long irqflags;
-
switch (mode) {
case CLOCK_EVT_MODE_ONESHOT:
- raw_local_irq_save(irqflags);
OIER &= ~OIER_E0;
OSSR = OSSR_M0;
- raw_local_irq_restore(irqflags);
break;
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
/* initializing, released, or preparing for suspend */
- raw_local_irq_save(irqflags);
OIER &= ~OIER_E0;
OSSR = OSSR_M0;
- raw_local_irq_restore(irqflags);
break;
case CLOCK_EVT_MODE_RESUME:
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index c854c168a45..ad552791c4c 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -32,6 +32,7 @@
#include <linux/gpio.h>
#include <linux/pda_power.h>
#include <linux/spi/spi.h>
+#include <linux/input/matrix_keypad.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -131,24 +132,24 @@ static unsigned long tosa_pin_config[] = {
GPIO45_BTUART_RTS,
/* Keybd */
- GPIO58_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO59_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO60_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO61_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO62_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO63_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO64_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO65_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO66_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO67_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO68_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO69_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO70_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO71_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO72_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO73_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO74_GPIO | MFP_LPM_DRIVE_LOW,
- GPIO75_GPIO | MFP_LPM_DRIVE_LOW,
+ GPIO58_GPIO | MFP_LPM_DRIVE_LOW, /* Column 0 */
+ GPIO59_GPIO | MFP_LPM_DRIVE_LOW, /* Column 1 */
+ GPIO60_GPIO | MFP_LPM_DRIVE_LOW, /* Column 2 */
+ GPIO61_GPIO | MFP_LPM_DRIVE_LOW, /* Column 3 */
+ GPIO62_GPIO | MFP_LPM_DRIVE_LOW, /* Column 4 */
+ GPIO63_GPIO | MFP_LPM_DRIVE_LOW, /* Column 5 */
+ GPIO64_GPIO | MFP_LPM_DRIVE_LOW, /* Column 6 */
+ GPIO65_GPIO | MFP_LPM_DRIVE_LOW, /* Column 7 */
+ GPIO66_GPIO | MFP_LPM_DRIVE_LOW, /* Column 8 */
+ GPIO67_GPIO | MFP_LPM_DRIVE_LOW, /* Column 9 */
+ GPIO68_GPIO | MFP_LPM_DRIVE_LOW, /* Column 10 */
+ GPIO69_GPIO | MFP_LPM_DRIVE_LOW, /* Row 0 */
+ GPIO70_GPIO | MFP_LPM_DRIVE_LOW, /* Row 1 */
+ GPIO71_GPIO | MFP_LPM_DRIVE_LOW, /* Row 2 */
+ GPIO72_GPIO | MFP_LPM_DRIVE_LOW, /* Row 3 */
+ GPIO73_GPIO | MFP_LPM_DRIVE_LOW, /* Row 4 */
+ GPIO74_GPIO | MFP_LPM_DRIVE_LOW, /* Row 5 */
+ GPIO75_GPIO | MFP_LPM_DRIVE_LOW, /* Row 6 */
/* SPI */
GPIO81_SSP2_CLK_OUT,
@@ -411,9 +412,87 @@ static struct platform_device tosa_power_device = {
/*
* Tosa Keyboard
*/
+static const uint32_t tosakbd_keymap[] = {
+ KEY(0, 2, KEY_W),
+ KEY(0, 6, KEY_K),
+ KEY(0, 7, KEY_BACKSPACE),
+ KEY(0, 8, KEY_P),
+ KEY(1, 1, KEY_Q),
+ KEY(1, 2, KEY_E),
+ KEY(1, 3, KEY_T),
+ KEY(1, 4, KEY_Y),
+ KEY(1, 6, KEY_O),
+ KEY(1, 7, KEY_I),
+ KEY(1, 8, KEY_COMMA),
+ KEY(2, 1, KEY_A),
+ KEY(2, 2, KEY_D),
+ KEY(2, 3, KEY_G),
+ KEY(2, 4, KEY_U),
+ KEY(2, 6, KEY_L),
+ KEY(2, 7, KEY_ENTER),
+ KEY(2, 8, KEY_DOT),
+ KEY(3, 1, KEY_Z),
+ KEY(3, 2, KEY_C),
+ KEY(3, 3, KEY_V),
+ KEY(3, 4, KEY_J),
+ KEY(3, 5, TOSA_KEY_ADDRESSBOOK),
+ KEY(3, 6, TOSA_KEY_CANCEL),
+ KEY(3, 7, TOSA_KEY_CENTER),
+ KEY(3, 8, TOSA_KEY_OK),
+ KEY(3, 9, KEY_LEFTSHIFT),
+ KEY(4, 1, KEY_S),
+ KEY(4, 2, KEY_R),
+ KEY(4, 3, KEY_B),
+ KEY(4, 4, KEY_N),
+ KEY(4, 5, TOSA_KEY_CALENDAR),
+ KEY(4, 6, TOSA_KEY_HOMEPAGE),
+ KEY(4, 7, KEY_LEFTCTRL),
+ KEY(4, 8, TOSA_KEY_LIGHT),
+ KEY(4, 10, KEY_RIGHTSHIFT),
+ KEY(5, 1, KEY_TAB),
+ KEY(5, 2, KEY_SLASH),
+ KEY(5, 3, KEY_H),
+ KEY(5, 4, KEY_M),
+ KEY(5, 5, TOSA_KEY_MENU),
+ KEY(5, 7, KEY_UP),
+ KEY(5, 11, TOSA_KEY_FN),
+ KEY(6, 1, KEY_X),
+ KEY(6, 2, KEY_F),
+ KEY(6, 3, KEY_SPACE),
+ KEY(6, 4, KEY_APOSTROPHE),
+ KEY(6, 5, TOSA_KEY_MAIL),
+ KEY(6, 6, KEY_LEFT),
+ KEY(6, 7, KEY_DOWN),
+ KEY(6, 8, KEY_RIGHT),
+};
+
+static struct matrix_keymap_data tosakbd_keymap_data = {
+ .keymap = tosakbd_keymap,
+ .keymap_size = ARRAY_SIZE(tosakbd_keymap),
+};
+
+static const int tosakbd_col_gpios[] =
+ { 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68 };
+static const int tosakbd_row_gpios[] =
+ { 69, 70, 71, 72, 73, 74, 75 };
+
+static struct matrix_keypad_platform_data tosakbd_pdata = {
+ .keymap_data = &tosakbd_keymap_data,
+ .row_gpios = tosakbd_row_gpios,
+ .col_gpios = tosakbd_col_gpios,
+ .num_row_gpios = ARRAY_SIZE(tosakbd_row_gpios),
+ .num_col_gpios = ARRAY_SIZE(tosakbd_col_gpios),
+ .col_scan_delay_us = 10,
+ .debounce_ms = 10,
+ .wakeup = 1,
+};
+
static struct platform_device tosakbd_device = {
- .name = "tosa-keyboard",
+ .name = "matrix-keypad",
.id = -1,
+ .dev = {
+ .platform_data = &tosakbd_pdata,
+ },
};
static struct gpio_keys_button tosa_gpio_keys[] = {
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 0aa858ebc57..797f2544d0c 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -72,27 +72,14 @@ static unsigned long trizeps4_pin_config[] __initdata = {
GPIO79_nCS_3, /* Logic CS */
GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, /* Logic irq */
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
/* LCD - 16bpp Active TFT */
- GPIO58_LCD_LDD_0,
- GPIO59_LCD_LDD_1,
- GPIO60_LCD_LDD_2,
- GPIO61_LCD_LDD_3,
- GPIO62_LCD_LDD_4,
- GPIO63_LCD_LDD_5,
- GPIO64_LCD_LDD_6,
- GPIO65_LCD_LDD_7,
- GPIO66_LCD_LDD_8,
- GPIO67_LCD_LDD_9,
- GPIO68_LCD_LDD_10,
- GPIO69_LCD_LDD_11,
- GPIO70_LCD_LDD_12,
- GPIO71_LCD_LDD_13,
- GPIO72_LCD_LDD_14,
- GPIO73_LCD_LDD_15,
- GPIO74_LCD_FCLK,
- GPIO75_LCD_LCLK,
- GPIO76_LCD_PCLK,
- GPIO77_LCD_BIAS,
+ GPIOxx_LCD_TFT_16BPP,
/* UART */
GPIO9_FFUART_CTS,
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 89f258c9e12..9e0c5c3988a 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -27,6 +27,7 @@
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/major.h>
#include <linux/module.h>
@@ -281,7 +282,7 @@ static void viper_irq_handler(unsigned int irq, struct irq_desc *desc)
do {
/* we're in a chained irq handler,
* so ack the interrupt by hand */
- GEDR(VIPER_CPLD_GPIO) = GPIO_bit(VIPER_CPLD_GPIO);
+ desc->chip->ack(irq);
if (likely(pending)) {
irq = viper_bit_to_irq(__ffs(pending));
@@ -711,6 +712,12 @@ static mfp_cfg_t viper_pin_config[] __initdata = {
GPIO80_nCS_4,
GPIO33_nCS_5,
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
/* FP Backlight */
GPIO9_GPIO, /* VIPER_BCKLIGHT_EN_GPIO */
GPIO10_GPIO, /* VIPER_LCD_EN_GPIO */
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 75f2a37f945..39896d88358 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <linux/apm-emulation.h>
+#include <linux/can/platform/mcp251x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -387,11 +388,47 @@ static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = {
.enable_dma = 1,
};
-static struct platform_device pxa2xx_spi_ssp3_device = {
- .name = "pxa2xx-spi",
- .id = 3,
- .dev = {
- .platform_data = &pxa2xx_spi_ssp3_master_info,
+/* CAN bus on SPI */
+static int zeus_mcp2515_setup(struct spi_device *sdev)
+{
+ int err;
+
+ err = gpio_request(ZEUS_CAN_SHDN_GPIO, "CAN shutdown");
+ if (err)
+ return err;
+
+ err = gpio_direction_output(ZEUS_CAN_SHDN_GPIO, 1);
+ if (err) {
+ gpio_free(ZEUS_CAN_SHDN_GPIO);
+ return err;
+ }
+
+ return 0;
+}
+
+static int zeus_mcp2515_transceiver_enable(int enable)
+{
+ gpio_set_value(ZEUS_CAN_SHDN_GPIO, !enable);
+ return 0;
+}
+
+static struct mcp251x_platform_data zeus_mcp2515_pdata = {
+ .oscillator_frequency = 16*1000*1000,
+ .model = CAN_MCP251X_MCP2515,
+ .board_specific_setup = zeus_mcp2515_setup,
+ .transceiver_enable = zeus_mcp2515_transceiver_enable,
+ .power_enable = zeus_mcp2515_transceiver_enable,
+};
+
+static struct spi_board_info zeus_spi_board_info[] = {
+ [0] = {
+ .modalias = "mcp251x",
+ .platform_data = &zeus_mcp2515_pdata,
+ .irq = gpio_to_irq(ZEUS_CAN_GPIO),
+ .max_speed_hz = 1*1000*1000,
+ .bus_num = 3,
+ .mode = SPI_MODE_0,
+ .chip_select = 0,
},
};
@@ -457,15 +494,28 @@ static struct platform_device zeus_pcmcia_device = {
},
};
+static struct resource zeus_max6369_resource = {
+ .start = ZEUS_CPLD_EXTWDOG_PHYS,
+ .end = ZEUS_CPLD_EXTWDOG_PHYS,
+ .flags = IORESOURCE_MEM,
+};
+
+struct platform_device zeus_max6369_device = {
+ .name = "max6369_wdt",
+ .id = -1,
+ .resource = &zeus_max6369_resource,
+ .num_resources = 1,
+};
+
static struct platform_device *zeus_devices[] __initdata = {
&zeus_serial_device,
&zeus_mtd_devices[0],
&zeus_dm9k0_device,
&zeus_dm9k1_device,
&zeus_sram_device,
- &pxa2xx_spi_ssp3_device,
&zeus_leds_device,
&zeus_pcmcia_device,
+ &zeus_max6369_device,
};
/* AC'97 */
@@ -509,7 +559,9 @@ static void zeus_ohci_exit(struct device *dev)
static struct pxaohci_platform_data zeus_ohci_platform_data = {
.port_mode = PMM_NPS_MODE,
- .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+ /* Clear Power Control Polarity Low and set Power Sense
+ * Polarity Low. Supply power to USB ports. */
+ .flags = ENABLE_PORT_ALL | POWER_SENSE_LOW,
.init = zeus_ohci_init,
.exit = zeus_ohci_exit,
};
@@ -621,11 +673,15 @@ static struct pxa2xx_udc_mach_info zeus_udc_info = {
.udc_command = zeus_udc_command,
};
+#ifdef CONFIG_PM
static void zeus_power_off(void)
{
local_irq_disable();
pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP);
}
+#else
+#define zeus_power_off NULL
+#endif
#ifdef CONFIG_APM_EMULATION
static void zeus_get_power_status(struct apm_power_info *info)
@@ -706,6 +762,12 @@ static struct i2c_board_info __initdata zeus_i2c_devices[] = {
};
static mfp_cfg_t zeus_pin_config[] __initdata = {
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
GPIO15_nCS_1,
GPIO78_nCS_2,
GPIO80_nCS_4,
@@ -731,6 +793,11 @@ static mfp_cfg_t zeus_pin_config[] __initdata = {
GPIO104_CIF_DD_2,
GPIO105_CIF_DD_1,
+ GPIO81_SSP3_TXD,
+ GPIO82_SSP3_RXD,
+ GPIO83_SSP3_SFRM,
+ GPIO84_SSP3_SCLK,
+
GPIO48_nPOE,
GPIO49_nPWE,
GPIO50_nPIOR,
@@ -785,6 +852,8 @@ static void __init zeus_init(void)
pxa_set_ac97_info(&zeus_ac97_info);
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(zeus_i2c_devices));
+ pxa2xx_set_spi_info(3, &pxa2xx_spi_ssp3_master_info);
+ spi_register_board_info(zeus_spi_board_info, ARRAY_SIZE(zeus_spi_board_info));
}
static struct map_desc zeus_io_desc[] __initdata = {
@@ -807,12 +876,6 @@ static struct map_desc zeus_io_desc[] __initdata = {
.type = MT_DEVICE,
},
{
- .virtual = ZEUS_CPLD_EXTWDOG,
- .pfn = __phys_to_pfn(ZEUS_CPLD_EXTWDOG_PHYS),
- .length = 0x1000,
- .type = MT_DEVICE,
- },
- {
.virtual = ZEUS_PC104IO,
.pfn = __phys_to_pfn(ZEUS_PC104IO_PHYS),
.length = 0x00800000,
@@ -837,7 +900,7 @@ static void __init zeus_map_io(void)
PCFR = PCFR_OPDE | PCFR_DC_EN | PCFR_FS | PCFR_FP;
}
-MACHINE_START(ARCOM_ZEUS, "Arcom ZEUS")
+MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS")
/* Maintainer: Marc Zyngier <maz@misterjones.org> */
.phys_io = 0x40000000,
.io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc),
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 90bd4ef71b2..d5a95738f85 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -31,6 +31,7 @@
#include <linux/smsc911x.h>
#include <linux/ata_platform.h>
#include <linux/amba/mmci.h>
+#include <linux/gfp.h>
#include <asm/clkdev.h>
#include <asm/system.h>
@@ -253,7 +254,7 @@ static unsigned int realview_mmc_status(struct device *dev)
else
mask = 2;
- return readl(REALVIEW_SYSMCI) & mask;
+ return !(readl(REALVIEW_SYSMCI) & mask);
}
struct mmci_platform_data realview_mmc0_plat_data = {
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
index c47d974d52b..85883b2e0e4 100644
--- a/arch/arm/mach-rpc/dma.c
+++ b/arch/arm/mach-rpc/dma.c
@@ -9,7 +9,6 @@
*
* DMA functions specific to RiscPC architecture
*/
-#include <linux/slab.h>
#include <linux/mman.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-rpc/include/mach/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h
index d5862368c4f..8c9e2c7161c 100644
--- a/arch/arm/mach-rpc/include/mach/uncompress.h
+++ b/arch/arm/mach-rpc/include/mach/uncompress.h
@@ -109,8 +109,6 @@ static inline void flush(void)
{
}
-static void error(char *x);
-
/*
* Setup for decompression
*/
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 63b753f56c6..0d8e043804c 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -21,7 +21,7 @@
#include <mach/dma.h>
#include <plat/cpu.h>
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c
index b7d1f8d27bc..a3f3c7b1ca3 100644
--- a/arch/arm/mach-s3c2410/h1940-bluetooth.c
+++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c
@@ -56,7 +56,7 @@ static const struct rfkill_ops h1940bt_rfkill_ops = {
.set_block = h1940bt_set_block,
};
-static int __init h1940bt_probe(struct platform_device *pdev)
+static int __devinit h1940bt_probe(struct platform_device *pdev)
{
struct rfkill *rfk;
int ret = 0;
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-core.h b/arch/arm/mach-s3c2410/include/mach/gpio-core.h
deleted file mode 100644
index f8b879a7973..00000000000
--- a/arch/arm/mach-s3c2410/include/mach/gpio-core.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* arch/arm/mach-s3c24100/include/mach/gpio-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C2410 - GPIO core support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_CORE_H
-#define __ASM_ARCH_GPIO_CORE_H __FILE__
-
-#include <plat/gpio-core.h>
-#include <mach/regs-gpio.h>
-
-extern struct s3c_gpio_chip s3c24xx_gpios[];
-
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
-{
- struct s3c_gpio_chip *chip;
-
- if (pin > S3C2410_GPG(10))
- return NULL;
-
- chip = &s3c24xx_gpios[pin/32];
- return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL;
-}
-
-#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
new file mode 100644
index 00000000000..acb25910380
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
@@ -0,0 +1,33 @@
+/* arch/arm/mach-s3c24100/include/mach/gpio-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C2410 - GPIO core support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_CORE_H
+#define __ASM_ARCH_GPIO_CORE_H __FILE__
+
+#include <mach/regs-gpio.h>
+
+extern struct s3c_gpio_chip s3c24xx_gpios[];
+
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip;
+
+ if (pin > S3C2410_GPG(10))
+ return NULL;
+
+ chip = &s3c24xx_gpios[pin/32];
+ return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL;
+}
+
+#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/pm-core.h b/arch/arm/mach-s3c2410/include/mach/pm-core.h
new file mode 100644
index 00000000000..70a83b209e2
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/pm-core.h
@@ -0,0 +1,64 @@
+/* linux/arch/arm/mach-s3c2410/include/pm-core.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ unsigned long tmp = __raw_readl(S3C2410_CLKCON);
+
+ /* re-start uart clocks */
+ tmp |= S3C2410_CLKCON_UART0;
+ tmp |= S3C2410_CLKCON_UART1;
+ tmp |= S3C2410_CLKCON_UART2;
+
+ __raw_writel(tmp, S3C2410_CLKCON);
+ udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
+ __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
+
+ /* ack any outstanding external interrupts before we go to sleep */
+
+ __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
+ __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
+ __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
+
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+ __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
+}
+
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+ unsigned long mask);
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+ S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n",
+ __raw_readl(S3C2410_SRCPND),
+ __raw_readl(S3C2410_EINTPEND));
+
+ s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
+ s3c_irqwake_intmask);
+
+ s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
+ s3c_irqwake_eintmask);
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+}
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index ebc85c6dadb..fd672f330bf 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -406,31 +406,31 @@
#define S3C2443_GPE5_SD1_CLK (0x02 << 10)
#define S3C2400_GPE5_EINT5 (0x02 << 10)
#define S3C2400_GPE5_TCLK1 (0x03 << 10)
+#define S3C2443_GPE5_AC_BITCLK (0x03 << 10)
#define S3C2410_GPE6_SDCMD (0x02 << 12)
#define S3C2443_GPE6_SD1_CMD (0x02 << 12)
-#define S3C2443_GPE6_AC_BITCLK (0x03 << 12)
+#define S3C2443_GPE6_AC_SDI (0x03 << 12)
#define S3C2400_GPE6_EINT6 (0x02 << 12)
#define S3C2410_GPE7_SDDAT0 (0x02 << 14)
#define S3C2443_GPE5_SD1_DAT0 (0x02 << 14)
-#define S3C2443_GPE7_AC_SDI (0x03 << 14)
+#define S3C2443_GPE7_AC_SDO (0x03 << 14)
#define S3C2400_GPE7_EINT7 (0x02 << 14)
#define S3C2410_GPE8_SDDAT1 (0x02 << 16)
#define S3C2443_GPE8_SD1_DAT1 (0x02 << 16)
-#define S3C2443_GPE8_AC_SDO (0x03 << 16)
+#define S3C2443_GPE8_AC_SYNC (0x03 << 16)
#define S3C2400_GPE8_nXDACK0 (0x02 << 16)
#define S3C2410_GPE9_SDDAT2 (0x02 << 18)
#define S3C2443_GPE9_SD1_DAT2 (0x02 << 18)
-#define S3C2443_GPE9_AC_SYNC (0x03 << 18)
+#define S3C2443_GPE9_AC_nRESET (0x03 << 18)
#define S3C2400_GPE9_nXDACK1 (0x02 << 18)
#define S3C2400_GPE9_nXBACK (0x03 << 18)
#define S3C2410_GPE10_SDDAT3 (0x02 << 20)
#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
-#define S3C2443_GPE10_AC_nRESET (0x03 << 20)
#define S3C2400_GPE10_nXDREQ0 (0x02 << 20)
#define S3C2410_GPE11_SPIMISO0 (0x02 << 22)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
index 6026d091a2f..d87ebe0cb62 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -42,23 +42,14 @@
#define S3C2443_PLLCON_OFF (1<<24)
-#define S3C2443_CLKSRC_I2S_EXT (1<<14)
-#define S3C2443_CLKSRC_I2S_EPLLDIV (0<<14)
-#define S3C2443_CLKSRC_I2S_EPLLREF (2<<14)
-#define S3C2443_CLKSRC_I2S_EPLLREF3 (3<<14)
-#define S3C2443_CLKSRC_I2S_MASK (3<<14)
-
#define S3C2443_CLKSRC_EPLLREF_XTAL (2<<7)
#define S3C2443_CLKSRC_EPLLREF_EXTCLK (3<<7)
#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<7)
#define S3C2443_CLKSRC_EPLLREF_MPLLREF2 (1<<7)
#define S3C2443_CLKSRC_EPLLREF_MASK (3<<7)
-#define S3C2443_CLKSRC_ESYSCLK_EPLL (1<<6)
-#define S3C2443_CLKSRC_MSYSCLK_MPLL (1<<4)
#define S3C2443_CLKSRC_EXTCLK_DIV (1<<3)
-#define S3C2443_CLKDIV0_DVS (1<<13)
#define S3C2443_CLKDIV0_HALF_HCLK (1<<3)
#define S3C2443_CLKDIV0_HALF_PCLK (1<<2)
@@ -81,28 +72,7 @@
#define S3C2443_CLKDIV0_ARMDIV_12 (13<<9)
#define S3C2443_CLKDIV0_ARMDIV_16 (15<<9)
-/* S3C2443_CLKDIV1 */
-
-#define S3C2443_CLKDIV1_CAMDIV_MASK (15<<26)
-#define S3C2443_CLKDIV1_CAMDIV_SHIFT (26)
-
-#define S3C2443_CLKDIV1_HSSPIDIV_MASK (3<<24)
-#define S3C2443_CLKDIV1_HSSPIDIV_SHIFT (24)
-
-#define S3C2443_CLKDIV1_DISPDIV_MASK (0xff<<16)
-#define S3C2443_CLKDIV1_DISPDIV_SHIFT (16)
-
-#define S3C2443_CLKDIV1_I2SDIV_MASK (15<<12)
-#define S3C2443_CLKDIV1_I2SDIV_SHIFT (12)
-
-#define S3C2443_CLKDIV1_UARTDIV_MASK (15<<8)
-#define S3C2443_CLKDIV1_UARTDIV_SHIFT (8)
-
-#define S3C2443_CLKDIV1_HSMMCDIV_MASK (3<<6)
-#define S3C2443_CLKDIV1_HSMMCDIV_SHIFT (6)
-
-#define S3C2443_CLKDIV1_USBHOSTDIV_MASK (3<<4)
-#define S3C2443_CLKDIV1_USBHOSTDIV_SHIFT (4)
+/* S3C2443_CLKDIV1 removed, only used in clock.c code */
#define S3C2443_CLKCON_NAND
diff --git a/arch/arm/mach-s3c2410/include/mach/spi-gpio.h b/arch/arm/mach-s3c2410/include/mach/spi-gpio.h
index 980a099e209..dcef2287cb3 100644
--- a/arch/arm/mach-s3c2410/include/mach/spi-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/spi-gpio.h
@@ -3,7 +3,7 @@
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
- * S3C2410 - SPI Controller platfrom_device info
+ * S3C2410 - SPI Controller 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
diff --git a/arch/arm/mach-s3c2410/include/mach/timex.h b/arch/arm/mach-s3c2410/include/mach/timex.h
new file mode 100644
index 00000000000..fe9ca1ffd51
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/timex.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/vmalloc.h b/arch/arm/mach-s3c2410/include/mach/vmalloc.h
new file mode 100644
index 00000000000..315b0078a34
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/* arch/arm/mach-s3c2410/include/mach/vmalloc.h
+ *
+ * from arch/arm/mach-iop3xx/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 06a84adfb13..7047317ed7f 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -153,7 +153,7 @@ static struct platform_device *amlm5900_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_wdt,
&s3c_device_i2c0,
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_rtc,
&s3c_device_usbgadget,
&s3c_device_sdi,
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 97162fdd059..02b1b6220cb 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -584,7 +584,7 @@ static struct s3c_hwmon_pdata bast_hwmon_info = {
// cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
static struct platform_device *bast_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 1e34abe1a19..fbedd076094 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -196,7 +196,7 @@ static struct platform_device h1940_device_bluetooth = {
.id = -1,
};
-static struct s3c24xx_mci_pdata h1940_mmc_cfg = {
+static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
.gpio_detect = S3C2410_GPF(5),
.gpio_wprotect = S3C2410_GPH(8),
.set_power = NULL,
@@ -272,7 +272,7 @@ static struct platform_device h1940_lcd_powerdev = {
static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_ts,
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
@@ -311,12 +311,11 @@ static void __init h1940_init(void)
u32 tmp;
s3c24xx_fb_set_platdata(&h1940_fb_info);
+ s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
s3c24xx_udc_set_platdata(&h1940_udc_cfg);
s3c24xx_ts_set_platdata(&h1940_ts_cfg);
s3c_i2c0_set_platdata(NULL);
- s3c_device_sdi.dev.platform_data = &h1940_mmc_cfg;
-
/* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 0405712c226..684710f8814 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -322,7 +322,7 @@ static struct platform_device *n30_devices[] __initdata = {
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_usbgadget,
&n30_button_device,
&n30_blue_led,
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index f6c7261a4a1..d8c7f2efc1a 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -92,7 +92,7 @@ static struct platform_device otom_device_nor = {
/* Standard OTOM devices */
static struct platform_device *otom11_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index ab092bcda39..92a4ec375d8 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -246,7 +246,7 @@ static struct platform_device qt2410_spi = {
/* Board devices */
static struct platform_device *qt2410_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index c49126ccb1d..45222304220 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -87,7 +87,7 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = {
};
static struct platform_device *smdk2410_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c
index 8fdb0430bd4..929164a8e9b 100644
--- a/arch/arm/mach-s3c2410/mach-tct_hammer.c
+++ b/arch/arm/mach-s3c2410/mach-tct_hammer.c
@@ -129,7 +129,7 @@ static struct platform_device *tct_hammer_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_wdt,
&s3c_device_i2c0,
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_rtc,
&s3c_device_usbgadget,
&s3c_device_sdi,
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 0d61fb57717..9051f0d3112 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -334,7 +334,7 @@ static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
/* devices for this board */
static struct platform_device *vr1000_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index 6b9d0d83a6f..29bd3d987be 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -91,7 +91,7 @@ static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
}
}
-static struct s3c2410_hcd_info usb_simtec_info = {
+static struct s3c2410_hcd_info usb_simtec_info __initdata = {
.port[0] = {
.flags = S3C_HCDFLG_USED
},
@@ -127,6 +127,6 @@ int usb_simtec_init(void)
gpio_direction_output(S3C2410_GPB(4), 1);
gpio_direction_input(S3C2410_GPG(10));
- s3c_device_usb.dev.platform_data = &usb_simtec_info;
+ s3c_ohci_set_platdata(&usb_simtec_info);
return 0;
}
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index a037df5e1c2..0c0505b025c 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -124,7 +124,9 @@ static struct clk clk_usysclk = {
.name = "usysclk",
.id = -1,
.parent = &clk_xtal,
- .set_parent = s3c2412_setparent_usysclk,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2412_setparent_usysclk,
+ },
};
static struct clk clk_mrefclk = {
@@ -199,10 +201,12 @@ static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
static struct clk clk_usbsrc = {
.name = "usbsrc",
.id = -1,
- .get_rate = s3c2412_getrate_usbsrc,
- .set_rate = s3c2412_setrate_usbsrc,
- .round_rate = s3c2412_roundrate_usbsrc,
- .set_parent = s3c2412_setparent_usbsrc,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2412_getrate_usbsrc,
+ .set_rate = s3c2412_setrate_usbsrc,
+ .round_rate = s3c2412_roundrate_usbsrc,
+ .set_parent = s3c2412_setparent_usbsrc,
+ },
};
static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
@@ -225,7 +229,9 @@ static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
static struct clk clk_msysclk = {
.name = "msysclk",
.id = -1,
- .set_parent = s3c2412_setparent_msysclk,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2412_setparent_msysclk,
+ },
};
static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent)
@@ -264,7 +270,9 @@ static struct clk clk_armclk = {
.name = "armclk",
.id = -1,
.parent = &clk_msysclk,
- .set_parent = s3c2412_setparent_armclk,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2412_setparent_armclk,
+ },
};
/* these next clocks have an divider immediately after them,
@@ -337,10 +345,12 @@ static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
static struct clk clk_uart = {
.name = "uartclk",
.id = -1,
- .get_rate = s3c2412_getrate_uart,
- .set_rate = s3c2412_setrate_uart,
- .set_parent = s3c2412_setparent_uart,
- .round_rate = s3c2412_roundrate_clksrc,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2412_getrate_uart,
+ .set_rate = s3c2412_setrate_uart,
+ .set_parent = s3c2412_setparent_uart,
+ .round_rate = s3c2412_roundrate_clksrc,
+ },
};
static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
@@ -388,10 +398,12 @@ static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
static struct clk clk_i2s = {
.name = "i2sclk",
.id = -1,
- .get_rate = s3c2412_getrate_i2s,
- .set_rate = s3c2412_setrate_i2s,
- .set_parent = s3c2412_setparent_i2s,
- .round_rate = s3c2412_roundrate_clksrc,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2412_getrate_i2s,
+ .set_rate = s3c2412_setrate_i2s,
+ .set_parent = s3c2412_setparent_i2s,
+ .round_rate = s3c2412_roundrate_clksrc,
+ },
};
static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
@@ -438,10 +450,12 @@ static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
static struct clk clk_cam = {
.name = "camif-upll", /* same as 2440 name */
.id = -1,
- .get_rate = s3c2412_getrate_cam,
- .set_rate = s3c2412_setrate_cam,
- .set_parent = s3c2412_setparent_cam,
- .round_rate = s3c2412_roundrate_clksrc,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2412_getrate_cam,
+ .set_rate = s3c2412_setrate_cam,
+ .set_parent = s3c2412_setparent_cam,
+ .round_rate = s3c2412_roundrate_clksrc,
+ },
};
/* standard clock definitions */
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index f8d16fc10bc..e880524904e 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -20,7 +20,7 @@
#include <mach/dma.h>
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
#include <plat/cpu.h>
#include <plat/regs-serial.h>
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index c9fa3fca486..14f4798291a 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -468,7 +468,7 @@ static struct i2c_board_info jive_i2c_devs[] __initdata = {
/* The platform devices being used. */
static struct platform_device *jive_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_rtc,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 9a5e4341972..0392065af1a 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -104,8 +104,7 @@ static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = {
static struct platform_device *smdk2413_devices[] __initdata = {
- &s3c_device_usb,
- //&s3c_device_lcd,
+ &s3c_device_ohci,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
index a6ba591b26b..3ca9265b699 100644
--- a/arch/arm/mach-s3c2412/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -121,7 +121,7 @@ static struct s3c2410_platform_nand __initdata vstms_nand_info = {
};
static struct platform_device *vstms_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 80879358eb2..7f465265cf0 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -15,14 +15,67 @@ config CPU_S3C2440
help
Support for S3C2440 Samsung Mobile CPU based systems.
+config CPU_S3C2442
+ bool
+ depends on ARCH_S3C2410
+ select CPU_ARM920T
+ select S3C2410_CLOCK
+ select S3C2410_GPIO
+ select S3C2410_PM if PM
+ select CPU_S3C244X
+ select CPU_LLSERIAL_S3C2440
+ help
+ Support for S3C2442 Samsung Mobile CPU based systems.
+
+config CPU_S3C244X
+ bool
+ depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
+ help
+ Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
+
+
+
+config S3C2440_CPUFREQ
+ bool "S3C2440/S3C2442 CPU Frequency scaling support"
+ depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
+ select S3C2410_CPUFREQ_UTILS
+ default y
+ help
+ CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
+
+config S3C2440_XTAL_12000000
+ bool
+ help
+ Indicate that the build needs to support 12MHz system
+ crystal.
+
+config S3C2440_XTAL_16934400
+ bool
+ help
+ Indicate that the build needs to support 16.9344MHz system
+ crystal.
+
+config S3C2440_PLL_12000000
+ bool
+ depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
+ default y if CPU_FREQ_S3C24XX_PLL
+ help
+ PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
+
+config S3C2440_PLL_16934400
+ bool
+ depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
+ default y if CPU_FREQ_S3C24XX_PLL
+ help
+ PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
+
config S3C2440_DMA
bool
depends on ARCH_S3C2410 && CPU_S3C24405B
help
Support for S3C2440 specific DMA code5A
-
-menu "S3C2440 Machines"
+menu "S3C2440 and S3C2442 Machines"
config MACH_ANUBIS
bool "Simtec Electronics ANUBIS"
@@ -37,6 +90,18 @@ config MACH_ANUBIS
Say Y here if you are using the Simtec Electronics ANUBIS
development system
+config MACH_NEO1973_GTA02
+ bool "Openmoko GTA02 / Freerunner phone"
+ select CPU_S3C2442
+ select MFD_PCF50633
+ select PCF50633_GPIO
+ select I2C
+ select POWER_SUPPLY
+ select MACH_NEO1973
+ select S3C2410_PWM
+ help
+ Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
+
config MACH_OSIRIS
bool "Simtec IM2440D20 (OSIRIS) module"
select CPU_S3C2440
@@ -94,11 +159,14 @@ config MACH_NEXCODER_2440
config SMDK2440_CPU2440
bool "SMDK2440 with S3C2440 CPU module"
- depends on ARCH_S3C2440
default y if ARCH_S3C2440
select S3C2440_XTAL_16934400
select CPU_S3C2440
+config SMDK2440_CPU2442
+ bool "SMDM2440 with S3C2442 CPU module"
+ select CPU_S3C2442
+
config MACH_AT2440EVB
bool "Avantech AT2440EVB development board"
select CPU_S3C2440
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
index 5f322453188..c85ba32d895 100644
--- a/arch/arm/mach-s3c2440/Makefile
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -10,10 +10,20 @@ obj-n :=
obj- :=
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o
+obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
+
obj-$(CONFIG_CPU_S3C2440) += irq.o
obj-$(CONFIG_CPU_S3C2440) += clock.o
obj-$(CONFIG_S3C2440_DMA) += dma.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o
+obj-$(CONFIG_S3C2440_CPUFREQ) += s3c2440-cpufreq.o
+
+obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o
+obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o
+
# Machine support
obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
@@ -23,6 +33,7 @@ obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
+obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
# extra machine support
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index d1c29b2537c..3dc2426e234 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -98,8 +98,10 @@ static struct clk s3c2440_clk_cam = {
static struct clk s3c2440_clk_cam_upll = {
.name = "camif-upll",
.id = -1,
- .set_rate = s3c2440_camif_upll_setrate,
- .round_rate = s3c2440_camif_upll_round,
+ .ops = &(struct clk_ops) {
+ .set_rate = s3c2440_camif_upll_setrate,
+ .round_rate = s3c2440_camif_upll_round,
+ },
};
static struct clk s3c2440_clk_ac97 = {
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
index e08e081430f..3b0529f54e9 100644
--- a/arch/arm/mach-s3c2440/dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -20,7 +20,7 @@
#include <mach/map.h>
#include <mach/dma.h>
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
#include <plat/cpu.h>
#include <plat/regs-serial.h>
diff --git a/arch/arm/mach-s3c2440/dsc.c b/arch/arm/mach-s3c2440/dsc.c
index 55404427277..9ea66e31f62 100644
--- a/arch/arm/mach-s3c2440/dsc.c
+++ b/arch/arm/mach-s3c2440/dsc.c
@@ -28,7 +28,7 @@
#include <mach/regs-dsc.h>
#include <plat/cpu.h>
-#include <plat/s3c2440.h>
+#include <plat/s3c244x.h>
int s3c2440_set_dsc(unsigned int pin, unsigned int value)
{
diff --git a/arch/arm/mach-s3c2442/include/mach/gta02.h b/arch/arm/mach-s3c2440/include/mach/gta02.h
index 953331d8d56..953331d8d56 100644
--- a/arch/arm/mach-s3c2442/include/mach/gta02.h
+++ b/arch/arm/mach-s3c2440/include/mach/gta02.h
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index 62a4c3eba97..b73f78a9da5 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -409,7 +409,7 @@ static struct platform_device anubis_device_sm501 = {
/* Standard Anubis devices */
static struct platform_device *anubis_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_wdt,
&s3c_device_adc,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
index aa69290e04c..84725791e6b 100644
--- a/arch/arm/mach-s3c2440/mach-at2440evb.c
+++ b/arch/arm/mach-s3c2440/mach-at2440evb.c
@@ -165,7 +165,7 @@ static struct platform_device at2440evb_device_eth = {
},
};
-static struct s3c24xx_mci_pdata at2440evb_mci_pdata = {
+static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = {
.gpio_detect = S3C2410_GPG(10),
};
@@ -203,7 +203,7 @@ static struct s3c2410fb_mach_info at2440evb_fb_info __initdata = {
};
static struct platform_device *at2440evb_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_wdt,
&s3c_device_adc,
&s3c_device_i2c0,
@@ -216,8 +216,6 @@ static struct platform_device *at2440evb_devices[] __initdata = {
static void __init at2440evb_map_io(void)
{
- s3c_device_sdi.dev.platform_data = &at2440evb_mci_pdata;
-
s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
s3c24xx_init_clocks(16934400);
s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
@@ -226,6 +224,7 @@ static void __init at2440evb_map_io(void)
static void __init at2440evb_init(void)
{
s3c24xx_fb_set_platdata(&at2440evb_fb_info);
+ s3c24xx_mci_set_platdata(&at2440evb_mci_pdata);
s3c_nand_set_platdata(&at2440evb_nand_info);
s3c_i2c0_set_platdata(NULL);
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
new file mode 100644
index 00000000000..45799c608d8
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -0,0 +1,647 @@
+/*
+ * linux/arch/arm/mach-s3c2442/mach-gta02.c
+ *
+ * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
+ *
+ * Copyright (C) 2006-2009 by Openmoko, Inc.
+ * Authors: Harald Welte <laforge@openmoko.org>
+ * Andy Green <andy@openmoko.org>
+ * Werner Almesberger <werner@openmoko.org>
+ * 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
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mmc/host.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/mbc.h>
+#include <linux/mfd/pcf50633/adc.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/pmic.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/fb.h>
+
+#include <mach/spi.h>
+#include <mach/spi-gpio.h>
+#include <plat/usb-control.h>
+#include <mach/regs-mem.h>
+#include <mach/hardware.h>
+
+#include <mach/gta02.h>
+
+#include <plat/regs-serial.h>
+#include <plat/nand.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/udc.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+static struct pcf50633 *gta02_pcf;
+
+/*
+ * This gets called every 1ms when we paniced.
+ */
+
+static long gta02_panic_blink(long count)
+{
+ long delay = 0;
+ static long last_blink;
+ static char led;
+
+ /* Fast blink: 200ms period. */
+ if (count - last_blink < 100)
+ return 0;
+
+ led ^= 1;
+ gpio_direction_output(GTA02_GPIO_AUX_LED, led);
+
+ last_blink = count;
+
+ return delay;
+}
+
+
+static struct map_desc gta02_iodesc[] __initdata = {
+ {
+ .virtual = 0xe0000000,
+ .pfn = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ },
+};
+
+#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg gta02_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+#ifdef CONFIG_CHARGER_PCF50633
+/*
+ * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
+ * We use this to recognize that we can pull 1A from the USB socket.
+ *
+ * These constants are the measured pcf50633 ADC levels with the 1A
+ * charger / 48K resistor, and with no pulldown resistor.
+ */
+
+#define ADC_NOM_CHG_DETECT_1A 6
+#define ADC_NOM_CHG_DETECT_USB 43
+
+static void
+gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
+{
+ int ma;
+
+ /* Interpret charger type */
+ if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
+
+ /*
+ * Sanity - stop GPO driving out now that we have a 1A charger
+ * GPO controls USB Host power generation on GTA02
+ */
+ pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
+
+ ma = 1000;
+ } else
+ ma = 100;
+
+ pcf50633_mbc_usb_curlim_set(pcf, ma);
+}
+
+static struct delayed_work gta02_charger_work;
+static int gta02_usb_vbus_draw;
+
+static void gta02_charger_worker(struct work_struct *work)
+{
+ if (gta02_usb_vbus_draw) {
+ pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
+ return;
+ }
+
+#ifdef CONFIG_PCF50633_ADC
+ pcf50633_adc_async_read(gta02_pcf,
+ PCF50633_ADCC1_MUX_ADCIN1,
+ PCF50633_ADCC1_AVERAGE_16,
+ gta02_configure_pmu_for_charger,
+ NULL);
+#else
+ /*
+ * If the PCF50633 ADC is disabled we fallback to a
+ * 100mA limit for safety.
+ */
+ pcf50633_mbc_usb_curlim_set(pcf, 100);
+#endif
+}
+
+#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
+
+static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
+{
+ if (irq == PCF50633_IRQ_USBINS) {
+ schedule_delayed_work(&gta02_charger_work,
+ GTA02_CHARGER_CONFIGURE_TIMEOUT);
+
+ return;
+ }
+
+ if (irq == PCF50633_IRQ_USBREM) {
+ cancel_delayed_work_sync(&gta02_charger_work);
+ gta02_usb_vbus_draw = 0;
+ }
+}
+
+static void gta02_udc_vbus_draw(unsigned int ma)
+{
+ if (!gta02_pcf)
+ return;
+
+ gta02_usb_vbus_draw = ma;
+
+ schedule_delayed_work(&gta02_charger_work,
+ GTA02_CHARGER_CONFIGURE_TIMEOUT);
+}
+#else /* !CONFIG_CHARGER_PCF50633 */
+#define gta02_pmu_event_callback NULL
+#define gta02_udc_vbus_draw NULL
+#endif
+
+/*
+ * This is called when pc50633 is probed, unfortunately quite late in the
+ * day since it is an I2C bus device. Here we can belatedly define some
+ * platform devices with the advantage that we can mark the pcf50633 as the
+ * parent. This makes them get suspended and resumed with their parent
+ * the pcf50633 still around.
+ */
+
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
+
+
+static char *gta02_batteries[] = {
+ "battery",
+};
+
+struct pcf50633_platform_data gta02_pcf_pdata = {
+ .resumers = {
+ [0] = PCF50633_INT1_USBINS |
+ PCF50633_INT1_USBREM |
+ PCF50633_INT1_ALARM,
+ [1] = PCF50633_INT2_ONKEYF,
+ [2] = PCF50633_INT3_ONKEY1S,
+ [3] = PCF50633_INT4_LOWSYS |
+ PCF50633_INT4_LOWBAT |
+ PCF50633_INT4_HIGHTMP,
+ },
+
+ .batteries = gta02_batteries,
+ .num_batteries = ARRAY_SIZE(gta02_batteries),
+
+ .charger_reference_current_ma = 1000,
+
+ .reg_init_data = {
+ [PCF50633_REGULATOR_AUTO] = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .always_on = 1,
+ .apply_uV = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ },
+ [PCF50633_REGULATOR_DOWN1] = {
+ .constraints = {
+ .min_uV = 1300000,
+ .max_uV = 1600000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .always_on = 1,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_DOWN2] = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ },
+ [PCF50633_REGULATOR_HCLDO] = {
+ .constraints = {
+ .min_uV = 2000000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO1] = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .state_mem = {
+ .enabled = 0,
+ },
+ },
+ },
+ [PCF50633_REGULATOR_LDO2] = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO3] = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO4] = {
+ .constraints = {
+ .min_uV = 3200000,
+ .max_uV = 3200000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO5] = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ },
+ [PCF50633_REGULATOR_LDO6] = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ },
+ },
+ [PCF50633_REGULATOR_MEMLDO] = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ },
+
+ },
+ .probe_done = gta02_pmu_attach_child_devices,
+ .mbc_event_callback = gta02_pmu_event_callback,
+};
+
+
+/* NOR Flash. */
+
+#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */
+#define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */
+
+static struct physmap_flash_data gta02_nor_flash_data = {
+ .width = 2,
+};
+
+static struct resource gta02_nor_flash_resource = {
+ .start = GTA02_FLASH_BASE,
+ .end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device gta02_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &gta02_nor_flash_data,
+ },
+ .resource = &gta02_nor_flash_resource,
+ .num_resources = 1,
+};
+
+
+struct platform_device s3c24xx_pwm_device = {
+ .name = "s3c24xx_pwm",
+ .num_resources = 0,
+};
+
+static struct i2c_board_info gta02_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf50633", 0x73),
+ .irq = GTA02_IRQ_PCF50633,
+ .platform_data = &gta02_pcf_pdata,
+ },
+ {
+ I2C_BOARD_INFO("wm8753", 0x1a),
+ },
+};
+
+static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
+ [0] = {
+ /*
+ * This name is also hard-coded in the boot loaders, so
+ * changing it would would require all users to upgrade
+ * their boot loaders, some of which are stored in a NOR
+ * that is considered to be immutable.
+ */
+ .name = "neo1973-nand",
+ .nr_chips = 1,
+ .flash_bbt = 1,
+ },
+};
+
+/*
+ * Choose a set of timings derived from S3C@2442B MCP54
+ * data sheet (K5D2G13ACM-D075 MCP Memory).
+ */
+
+static struct s3c2410_platform_nand __initdata gta02_nand_info = {
+ .tacls = 0,
+ .twrph0 = 25,
+ .twrph1 = 15,
+ .nr_sets = ARRAY_SIZE(gta02_nand_sets),
+ .sets = gta02_nand_sets,
+};
+
+
+static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd)
+{
+ switch (cmd) {
+ case S3C2410_UDC_P_ENABLE:
+ pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__);
+ gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
+ break;
+ case S3C2410_UDC_P_DISABLE:
+ pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__);
+ gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0);
+ break;
+ case S3C2410_UDC_P_RESET:
+ pr_debug("%s S3C2410_UDC_P_RESET\n", __func__);
+ /* FIXME: Do something here. */
+ }
+}
+
+/* Get PMU to set USB current limit accordingly. */
+static struct s3c2410_udc_mach_info gta02_udc_cfg = {
+ .vbus_draw = gta02_udc_vbus_draw,
+ .udc_command = gta02_udc_command,
+
+};
+
+
+
+static void gta02_bl_set_intensity(int intensity)
+{
+ struct pcf50633 *pcf = gta02_pcf;
+ int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
+
+ /* We map 8-bit intensity to 6-bit intensity in hardware. */
+ intensity >>= 2;
+
+ /*
+ * This can happen during, eg, print of panic on blanked console,
+ * but we can't service i2c without interrupts active, so abort.
+ */
+ if (in_atomic()) {
+ printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n");
+ return;
+ }
+
+ old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
+ if (intensity == old_intensity)
+ return;
+
+ /* We can't do this anywhere else. */
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5);
+
+ if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3))
+ old_intensity = 0;
+
+ /*
+ * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
+ * if seen, you have to re-enable the LED unit.
+ */
+ if (!intensity || !old_intensity)
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0);
+
+ /* Illegal to set LEDOUT to 0. */
+ if (!intensity)
+ pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
+ else
+ pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
+ intensity);
+
+ if (intensity)
+ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2);
+
+}
+
+static struct generic_bl_info gta02_bl_info = {
+ .name = "gta02-bl",
+ .max_intensity = 0xff,
+ .default_intensity = 0xff,
+ .set_bl_intensity = gta02_bl_set_intensity,
+};
+
+static struct platform_device gta02_bl_dev = {
+ .name = "generic-bl",
+ .id = 1,
+ .dev = {
+ .platform_data = &gta02_bl_info,
+ },
+};
+
+
+
+/* USB */
+static struct s3c2410_hcd_info gta02_usb_info __initdata = {
+ .port[0] = {
+ .flags = S3C_HCDFLG_USED,
+ },
+ .port[1] = {
+ .flags = 0,
+ },
+};
+
+
+static void __init gta02_map_io(void)
+{
+ s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
+}
+
+
+/* These are the guys that don't need to be children of PMU. */
+
+static struct platform_device *gta02_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_wdt,
+ &s3c_device_sdi,
+ &s3c_device_usbgadget,
+ &s3c_device_nand,
+ &gta02_nor_flash,
+ &s3c24xx_pwm_device,
+ &s3c_device_iis,
+ &s3c_device_i2c0,
+};
+
+/* These guys DO need to be children of PMU. */
+
+static struct platform_device *gta02_devices_pmu_children[] = {
+ &gta02_bl_dev,
+};
+
+
+/*
+ * This is called when pc50633 is probed, quite late in the day since it is an
+ * I2C bus device. Here we can define platform devices with the advantage that
+ * we can mark the pcf50633 as the parent. This makes them get suspended and
+ * resumed with their parent the pcf50633 still around. All devices whose
+ * operation depends on something from pcf50633 must have this relationship
+ * made explicit like this, or suspend and resume will become an unreliable
+ * hellworld.
+ */
+
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
+{
+ int n;
+
+ /* Grab a copy of the now probed PMU pointer. */
+ gta02_pcf = pcf;
+
+ for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
+ gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
+
+ platform_add_devices(gta02_devices_pmu_children,
+ ARRAY_SIZE(gta02_devices_pmu_children));
+}
+
+static void gta02_poweroff(void)
+{
+ pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
+}
+
+static void __init gta02_machine_init(void)
+{
+ /* Set the panic callback to make AUX LED blink at ~5Hz. */
+ panic_blink = gta02_panic_blink;
+
+ s3c_pm_init();
+
+#ifdef CONFIG_CHARGER_PCF50633
+ INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
+#endif
+
+ s3c24xx_udc_set_platdata(&gta02_udc_cfg);
+ s3c_ohci_set_platdata(&gta02_usb_info);
+ s3c_nand_set_platdata(&gta02_nand_info);
+ s3c_i2c0_set_platdata(NULL);
+
+ i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
+
+ platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
+ pm_power_off = gta02_poweroff;
+}
+
+
+MACHINE_START(NEO1973_GTA02, "GTA02")
+ /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
+ .phys_io = S3C2410_PA_UART,
+ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = gta02_map_io,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = gta02_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
index 2068e9096a4..571b17683d9 100644
--- a/arch/arm/mach-s3c2440/mach-mini2440.c
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -506,9 +506,8 @@ static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
};
static struct platform_device *mini2440_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_wdt,
-/* &s3c_device_adc,*/ /* ADC doesn't like living with touchscreen ! */
&s3c_device_i2c0,
&s3c_device_rtc,
&s3c_device_usbgadget,
@@ -522,8 +521,6 @@ static struct platform_device *mini2440_devices[] __initdata = {
&s3c_device_sdi,
&s3c_device_iis,
&mini2440_audio,
-/* &s3c_device_timer[0],*/ /* buzzer pwm, no API for it */
- /* remaining devices are optional */
};
static void __init mini2440_map_io(void)
@@ -531,8 +528,6 @@ static void __init mini2440_map_io(void)
s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
-
- s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
}
/*
@@ -678,6 +673,7 @@ static void __init mini2440_init(void)
}
s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
+ s3c24xx_mci_set_platdata(&mini2440_mmc_cfg);
s3c_nand_set_platdata(&mini2440_nand_info);
s3c_i2c0_set_platdata(NULL);
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index d43edede590..342041593f2 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -41,7 +41,7 @@
#include <plat/iic.h>
#include <plat/s3c2410.h>
-#include <plat/s3c2440.h>
+#include <plat/s3c244x.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -106,7 +106,7 @@ static struct platform_device nexcoder_device_nor = {
/* Standard Nexcoder devices */
static struct platform_device *nexcoder_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index a952a13afb1..1e836e506f8 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -176,7 +176,7 @@ static struct s3c2410_platform_nand __initdata rx3715_nand_info = {
};
static struct platform_device *rx3715_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index ec13e748ccc..3ac3d636d61 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -40,7 +40,7 @@
#include <plat/iic.h>
#include <plat/s3c2410.h>
-#include <plat/s3c2440.h>
+#include <plat/s3c244x.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -150,7 +150,7 @@ static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
};
static struct platform_device *smdk2440_devices[] __initdata = {
- &s3c_device_usb,
+ &s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
diff --git a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c
index 976002fb1b8..976002fb1b8 100644
--- a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
+++ b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c
diff --git a/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c b/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
new file mode 100644
index 00000000000..f105d5e8c47
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
@@ -0,0 +1,97 @@
+/* arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
+ *
+ * Copyright (c) 2006-2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ * Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
+ { .frequency = 75000000, .index = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */
+ { .frequency = 80000000, .index = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */
+ { .frequency = 90000000, .index = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */
+ { .frequency = 100000000, .index = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */
+ { .frequency = 110000000, .index = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */
+ { .frequency = 120000000, .index = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */
+ { .frequency = 150000000, .index = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */
+ { .frequency = 160000000, .index = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */
+ { .frequency = 170000000, .index = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */
+ { .frequency = 180000000, .index = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */
+ { .frequency = 190000000, .index = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */
+ { .frequency = 200000000, .index = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */
+ { .frequency = 210000000, .index = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */
+ { .frequency = 220000000, .index = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */
+ { .frequency = 230000000, .index = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */
+ { .frequency = 240000000, .index = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */
+ { .frequency = 300000000, .index = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */
+ { .frequency = 310000000, .index = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */
+ { .frequency = 320000000, .index = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */
+ { .frequency = 330000000, .index = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */
+ { .frequency = 340000000, .index = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */
+ { .frequency = 350000000, .index = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */
+ { .frequency = 360000000, .index = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */
+ { .frequency = 370000000, .index = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */
+ { .frequency = 380000000, .index = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */
+ { .frequency = 390000000, .index = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */
+ { .frequency = 400000000, .index = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */
+};
+
+static int s3c2440_plls12_add(struct sys_device *dev)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ if (IS_ERR(xtal_clk))
+ return PTR_ERR(xtal_clk);
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ if (xtal == 12000000) {
+ printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
+ return s3c_plltab_register(s3c2440_plls_12,
+ ARRAY_SIZE(s3c2440_plls_12));
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_plls12_drv = {
+ .add = s3c2440_plls12_add,
+};
+
+static int __init s3c2440_pll_12mhz(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv);
+
+}
+
+arch_initcall(s3c2440_pll_12mhz);
+
+static struct sysdev_driver s3c2442_plls12_drv = {
+ .add = s3c2440_plls12_add,
+};
+
+static int __init s3c2442_pll_12mhz(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv);
+
+}
+
+arch_initcall(s3c2442_pll_12mhz);
diff --git a/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c b/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
new file mode 100644
index 00000000000..c8a8f90ef38
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
@@ -0,0 +1,127 @@
+/* arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
+ *
+ * Copyright (c) 2006-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ * Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
+ { .frequency = 78019200, .index = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */
+ { .frequency = 84067200, .index = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */
+ { .frequency = 90115200, .index = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */
+ { .frequency = 96163200, .index = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */
+ { .frequency = 102135600, .index = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */
+ { .frequency = 108259200, .index = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */
+ { .frequency = 114307200, .index = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */
+ { .frequency = 120234240, .index = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */
+ { .frequency = 126161280, .index = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */
+ { .frequency = 132088320, .index = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */
+ { .frequency = 138015360, .index = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */
+ { .frequency = 144789120, .index = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */
+ { .frequency = 150100363, .index = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */
+ { .frequency = 156038400, .index = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */
+ { .frequency = 162086400, .index = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */
+ { .frequency = 168134400, .index = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */
+ { .frequency = 174048000, .index = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */
+ { .frequency = 180230400, .index = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */
+ { .frequency = 186278400, .index = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */
+ { .frequency = 192326400, .index = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */
+ { .frequency = 198132480, .index = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */
+ { .frequency = 204271200, .index = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */
+ { .frequency = 210268800, .index = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */
+ { .frequency = 216518400, .index = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */
+ { .frequency = 222264000, .index = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */
+ { .frequency = 228614400, .index = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */
+ { .frequency = 234259200, .index = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */
+ { .frequency = 240468480, .index = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */
+ { .frequency = 246960000, .index = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */
+ { .frequency = 252322560, .index = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */
+ { .frequency = 258249600, .index = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */
+ { .frequency = 264176640, .index = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */
+ { .frequency = 270950400, .index = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */
+ { .frequency = 276030720, .index = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */
+ { .frequency = 282240000, .index = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */
+ { .frequency = 289578240, .index = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */
+ { .frequency = 294235200, .index = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */
+ { .frequency = 300200727, .index = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */
+ { .frequency = 306358690, .index = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */
+ { .frequency = 312076800, .index = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */
+ { .frequency = 318366720, .index = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */
+ { .frequency = 324172800, .index = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */
+ { .frequency = 330220800, .index = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */
+ { .frequency = 336268800, .index = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */
+ { .frequency = 342074880, .index = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */
+ { .frequency = 348096000, .index = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */
+ { .frequency = 355622400, .index = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */
+ { .frequency = 360460800, .index = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */
+ { .frequency = 366206400, .index = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */
+ { .frequency = 372556800, .index = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */
+ { .frequency = 378201600, .index = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */
+ { .frequency = 384652800, .index = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */
+ { .frequency = 391608000, .index = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */
+ { .frequency = 396264960, .index = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */
+ { .frequency = 402192000, .index = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */
+};
+
+static int s3c2440_plls169344_add(struct sys_device *dev)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ if (IS_ERR(xtal_clk))
+ return PTR_ERR(xtal_clk);
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ if (xtal == 169344000) {
+ printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
+ return s3c_plltab_register(s3c2440_plls_169344,
+ ARRAY_SIZE(s3c2440_plls_169344));
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_plls169344_drv = {
+ .add = s3c2440_plls169344_add,
+};
+
+static int __init s3c2440_pll_16934400(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass,
+ &s3c2440_plls169344_drv);
+
+}
+
+arch_initcall(s3c2440_pll_16934400);
+
+static struct sysdev_driver s3c2442_plls169344_drv = {
+ .add = s3c2440_plls169344_add,
+};
+
+static int __init s3c2442_pll_16934400(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass,
+ &s3c2442_plls169344_drv);
+
+}
+
+arch_initcall(s3c2442_pll_16934400);
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index ac1f7ea5f40..2b68f7ea45a 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -29,9 +29,9 @@
#include <mach/hardware.h>
#include <asm/irq.h>
-#include <plat/s3c2440.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/s3c244x.h>
static struct sys_device s3c2440_sysdev = {
.cls = &s3c2440_sysclass,
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c
new file mode 100644
index 00000000000..188ad1e57dc
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c2442.c
@@ -0,0 +1,165 @@
+/* linux/arch/arm/mach-s3c2442/s3c2442.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2442 core and lock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* S3C2442 extended clock support */
+
+static unsigned long s3c2442_camif_upll_round(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ int div;
+
+ if (rate > parent_rate)
+ return parent_rate;
+
+ div = parent_rate / rate;
+
+ if (div == 3)
+ return parent_rate / 3;
+
+ /* note, we remove the +/- 1 calculations for the divisor */
+
+ div /= 2;
+
+ if (div < 1)
+ div = 1;
+ else if (div > 16)
+ div = 16;
+
+ return parent_rate / (div * 2);
+}
+
+static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+
+ rate = s3c2442_camif_upll_round(clk, rate);
+
+ camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
+
+ if (rate == parent_rate) {
+ camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
+ } else if ((parent_rate / rate) == 3) {
+ camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+ camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
+ } else {
+ camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
+ camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+ camdivn |= (((parent_rate / rate) / 2) - 1);
+ }
+
+ __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+ return 0;
+}
+
+/* Extra S3C2442 clocks */
+
+static struct clk s3c2442_clk_cam = {
+ .name = "camif",
+ .id = -1,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2442_clk_cam_upll = {
+ .name = "camif-upll",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .set_rate = s3c2442_camif_upll_setrate,
+ .round_rate = s3c2442_camif_upll_round,
+ },
+};
+
+static int s3c2442_clk_add(struct sys_device *sysdev)
+{
+ struct clk *clock_upll;
+ struct clk *clock_h;
+ struct clk *clock_p;
+
+ clock_p = clk_get(NULL, "pclk");
+ clock_h = clk_get(NULL, "hclk");
+ clock_upll = clk_get(NULL, "upll");
+
+ if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+ printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
+ return -EINVAL;
+ }
+
+ s3c2442_clk_cam.parent = clock_h;
+ s3c2442_clk_cam_upll.parent = clock_upll;
+
+ s3c24xx_register_clock(&s3c2442_clk_cam);
+ s3c24xx_register_clock(&s3c2442_clk_cam_upll);
+
+ clk_disable(&s3c2442_clk_cam);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2442_clk_driver = {
+ .add = s3c2442_clk_add,
+};
+
+static __init int s3c2442_clk_init(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
+
+
+static struct sys_device s3c2442_sysdev = {
+ .cls = &s3c2442_sysclass,
+};
+
+int __init s3c2442_init(void)
+{
+ printk("S3C2442: Initialising architecture\n");
+
+ return sysdev_register(&s3c2442_sysdev);
+}
diff --git a/arch/arm/mach-s3c2440/s3c244x-clock.c b/arch/arm/mach-s3c2440/s3c244x-clock.c
new file mode 100644
index 00000000000..f8d96130d1d
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c244x-clock.c
@@ -0,0 +1,138 @@
+/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
+ *
+ * Copyright (c) 2004-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 Common clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+ unsigned long camdivn;
+ unsigned long dvs;
+
+ if (parent == &clk_f)
+ dvs = 0;
+ else if (parent == &clk_h)
+ dvs = S3C2440_CAMDIVN_DVSEN;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ camdivn = __raw_readl(S3C2440_CAMDIVN);
+ camdivn &= ~S3C2440_CAMDIVN_DVSEN;
+ camdivn |= dvs;
+ __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+ return 0;
+}
+
+static struct clk clk_arm = {
+ .name = "armclk",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2440_setparent_armclk,
+ },
+};
+
+static int s3c244x_clk_add(struct sys_device *sysdev)
+{
+ unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+ unsigned long clkdivn;
+ struct clk *clock_upll;
+ int ret;
+
+ printk("S3C244X: Clock Support, DVS %s\n",
+ (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+ clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
+
+ ret = s3c24xx_register_clock(&clk_arm);
+ if (ret < 0) {
+ printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
+ return ret;
+ }
+
+ clock_upll = clk_get(NULL, "upll");
+ if (IS_ERR(clock_upll)) {
+ printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
+ return -ENOENT;
+ }
+
+ /* check rate of UPLL, and if it is near 96MHz, then change
+ * to using half the UPLL rate for the system */
+
+ if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+ clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
+
+ spin_lock(&clocks_lock);
+
+ clkdivn = __raw_readl(S3C2410_CLKDIVN);
+ clkdivn |= S3C2440_CLKDIVN_UCLK;
+ __raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+ spin_unlock(&clocks_lock);
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_clk_driver = {
+ .add = s3c244x_clk_add,
+};
+
+static int s3c2440_clk_init(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
+}
+
+arch_initcall(s3c2440_clk_init);
+
+static struct sysdev_driver s3c2442_clk_driver = {
+ .add = s3c244x_clk_add,
+};
+
+static int s3c2442_clk_init(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/plat-s3c24xx/s3c244x-irq.c b/arch/arm/mach-s3c2440/s3c244x-irq.c
index a75c0c2431e..a75c0c2431e 100644
--- a/arch/arm/plat-s3c24xx/s3c244x-irq.c
+++ b/arch/arm/mach-s3c2440/s3c244x-irq.c
diff --git a/arch/arm/mach-s3c2440/s3c244x.c b/arch/arm/mach-s3c2440/s3c244x.c
new file mode 100644
index 00000000000..5e4a97e7653
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c244x.c
@@ -0,0 +1,195 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-dsc.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/pll.h>
+
+static struct map_desc s3c244x_iodesc[] __initdata = {
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+ IODESC_ENT(WATCHDOG),
+};
+
+/* uart initialisation */
+
+void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+void __init s3c244x_map_io(void)
+{
+ /* register our io-tables */
+
+ iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
+
+ /* rename any peripherals used differing from the s3c2410 */
+
+ s3c_device_sdi.name = "s3c2440-sdi";
+ s3c_device_i2c0.name = "s3c2440-i2c";
+ s3c_device_nand.name = "s3c2440-nand";
+ s3c_device_ts.name = "s3c2440-ts";
+ s3c_device_usbgadget.name = "s3c2440-usbgadget";
+}
+
+void __init_or_cpufreq s3c244x_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long clkdiv;
+ unsigned long camdiv;
+ unsigned long xtal;
+ unsigned long hclk, fclk, pclk;
+ int hdiv = 1;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
+
+ clkdiv = __raw_readl(S3C2410_CLKDIVN);
+ camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+ /* work out clock scalings */
+
+ switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
+ case S3C2440_CLKDIVN_HDIVN_1:
+ hdiv = 1;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_2:
+ hdiv = 2;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_4_8:
+ hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_3_6:
+ hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
+ break;
+ }
+
+ hclk = fclk / hdiv;
+ pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
+
+ /* print brief summary of clocks, etc */
+
+ printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+ print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+ s3c24xx_setup_clocks(fclk, hclk, pclk);
+}
+
+void __init s3c244x_init_clocks(int xtal)
+{
+ /* initialise the clocks here, to allow other things like the
+ * console to use them, and to add new ones after the initialisation
+ */
+
+ s3c24xx_register_baseclocks(xtal);
+ s3c244x_setup_clocks();
+ s3c2410_baseclk_add();
+}
+
+#ifdef CONFIG_PM
+
+static struct sleep_save s3c244x_sleep[] = {
+ SAVE_ITEM(S3C2440_DSC0),
+ SAVE_ITEM(S3C2440_DSC1),
+ SAVE_ITEM(S3C2440_GPJDAT),
+ SAVE_ITEM(S3C2440_GPJCON),
+ SAVE_ITEM(S3C2440_GPJUP)
+};
+
+static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
+{
+ s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+ return 0;
+}
+
+static int s3c244x_resume(struct sys_device *dev)
+{
+ s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+ return 0;
+}
+
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume NULL
+#endif
+
+/* Since the S3C2442 and S3C2440 share items, put both sysclasses here */
+
+struct sysdev_class s3c2440_sysclass = {
+ .name = "s3c2440-core",
+ .suspend = s3c244x_suspend,
+ .resume = s3c244x_resume
+};
+
+struct sysdev_class s3c2442_sysclass = {
+ .name = "s3c2442-core",
+ .suspend = s3c244x_suspend,
+ .resume = s3c244x_resume
+};
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2440 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2440_core_init(void)
+{
+ return sysdev_class_register(&s3c2440_sysclass);
+}
+
+core_initcall(s3c2440_core_init);
+
+static int __init s3c2442_core_init(void)
+{
+ return sysdev_class_register(&s3c2442_sysclass);
+}
+
+core_initcall(s3c2442_core_init);
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig
deleted file mode 100644
index 8d3811852fc..00000000000
--- a/arch/arm/mach-s3c2442/Kconfig
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-config CPU_S3C2442
- bool
- depends on ARCH_S3C2410
- select CPU_ARM920T
- select S3C2410_CLOCK
- select S3C2410_GPIO
- select S3C2410_PM if PM
- select CPU_S3C244X
- select CPU_LLSERIAL_S3C2440
- help
- Support for S3C2442 Samsung Mobile CPU based systems.
-
-
-menu "S3C2442 Machines"
-
-config SMDK2440_CPU2442
- bool "SMDM2440 with S3C2442 CPU module"
- depends on ARCH_S3C2440
- select CPU_S3C2442
-
-config MACH_NEO1973_GTA02
- bool "Openmoko GTA02 / Freerunner phone"
- select CPU_S3C2442
- select MFD_PCF50633
- select PCF50633_GPIO
- select I2C
- select POWER_SUPPLY
- select MACH_NEO1973
- select S3C2410_PWM
- help
- Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
-
-endmenu
diff --git a/arch/arm/mach-s3c2442/Makefile b/arch/arm/mach-s3c2442/Makefile
deleted file mode 100644
index 2a19113a576..00000000000
--- a/arch/arm/mach-s3c2442/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-# arch/arm/mach-s3c2442/Makefile
-#
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-
-obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
-obj-$(CONFIG_CPU_S3C2442) += clock.o
-
-obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
-
-# Machine support
-
diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c
deleted file mode 100644
index ea1aa1f5157..00000000000
--- a/arch/arm/mach-s3c2442/clock.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/* linux/arch/arm/mach-s3c2442/clock.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2442 Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-/* S3C2442 extended clock support */
-
-static unsigned long s3c2442_camif_upll_round(struct clk *clk,
- unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- int div;
-
- if (rate > parent_rate)
- return parent_rate;
-
- div = parent_rate / rate;
-
- if (div == 3)
- return parent_rate / 3;
-
- /* note, we remove the +/- 1 calculations for the divisor */
-
- div /= 2;
-
- if (div < 1)
- div = 1;
- else if (div > 16)
- div = 16;
-
- return parent_rate / (div * 2);
-}
-
-static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-
- rate = s3c2442_camif_upll_round(clk, rate);
-
- camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
-
- if (rate == parent_rate) {
- camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
- } else if ((parent_rate / rate) == 3) {
- camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
- camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
- } else {
- camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
- camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
- camdivn |= (((parent_rate / rate) / 2) - 1);
- }
-
- __raw_writel(camdivn, S3C2440_CAMDIVN);
-
- return 0;
-}
-
-/* Extra S3C2442 clocks */
-
-static struct clk s3c2442_clk_cam = {
- .name = "camif",
- .id = -1,
- .enable = s3c2410_clkcon_enable,
- .ctrlbit = S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2442_clk_cam_upll = {
- .name = "camif-upll",
- .id = -1,
- .set_rate = s3c2442_camif_upll_setrate,
- .round_rate = s3c2442_camif_upll_round,
-};
-
-static int s3c2442_clk_add(struct sys_device *sysdev)
-{
- struct clk *clock_upll;
- struct clk *clock_h;
- struct clk *clock_p;
-
- clock_p = clk_get(NULL, "pclk");
- clock_h = clk_get(NULL, "hclk");
- clock_upll = clk_get(NULL, "upll");
-
- if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
- printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
- return -EINVAL;
- }
-
- s3c2442_clk_cam.parent = clock_h;
- s3c2442_clk_cam_upll.parent = clock_upll;
-
- s3c24xx_register_clock(&s3c2442_clk_cam);
- s3c24xx_register_clock(&s3c2442_clk_cam_upll);
-
- clk_disable(&s3c2442_clk_cam);
-
- return 0;
-}
-
-static struct sysdev_driver s3c2442_clk_driver = {
- .add = s3c2442_clk_add,
-};
-
-static __init int s3c2442_clk_init(void)
-{
- return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
-}
-
-arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c2442/mach-gta02.c b/arch/arm/mach-s3c2442/mach-gta02.c
deleted file mode 100644
index 0b4a3a03071..00000000000
--- a/arch/arm/mach-s3c2442/mach-gta02.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * linux/arch/arm/mach-s3c2442/mach-gta02.c
- *
- * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
- *
- * Copyright (C) 2006-2009 by Openmoko, Inc.
- * Authors: Harald Welte <laforge@openmoko.org>
- * Andy Green <andy@openmoko.org>
- * Werner Almesberger <werner@openmoko.org>
- * 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
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/spi/spi.h>
-
-#include <linux/mmc/host.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/io.h>
-
-#include <linux/i2c.h>
-#include <linux/backlight.h>
-#include <linux/regulator/machine.h>
-
-#include <linux/mfd/pcf50633/core.h>
-#include <linux/mfd/pcf50633/mbc.h>
-#include <linux/mfd/pcf50633/adc.h>
-#include <linux/mfd/pcf50633/gpio.h>
-#include <linux/mfd/pcf50633/pmic.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-gpioj.h>
-#include <mach/fb.h>
-
-#include <mach/spi.h>
-#include <mach/spi-gpio.h>
-#include <plat/usb-control.h>
-#include <mach/regs-mem.h>
-#include <mach/hardware.h>
-
-#include <mach/gta02.h>
-
-#include <plat/regs-serial.h>
-#include <plat/nand.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/udc.h>
-#include <plat/gpio-cfg.h>
-#include <plat/iic.h>
-
-static struct pcf50633 *gta02_pcf;
-
-/*
- * This gets called every 1ms when we paniced.
- */
-
-static long gta02_panic_blink(long count)
-{
- long delay = 0;
- static long last_blink;
- static char led;
-
- /* Fast blink: 200ms period. */
- if (count - last_blink < 100)
- return 0;
-
- led ^= 1;
- gpio_direction_output(GTA02_GPIO_AUX_LED, led);
-
- last_blink = count;
-
- return delay;
-}
-
-
-static struct map_desc gta02_iodesc[] __initdata = {
- {
- .virtual = 0xe0000000,
- .pfn = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
- .length = SZ_1M,
- .type = MT_DEVICE
- },
-};
-
-#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
-#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
-#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
-
-static struct s3c2410_uartcfg gta02_uartcfgs[] = {
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [2] = {
- .hwport = 2,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
-};
-
-#ifdef CONFIG_CHARGER_PCF50633
-/*
- * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
- * We use this to recognize that we can pull 1A from the USB socket.
- *
- * These constants are the measured pcf50633 ADC levels with the 1A
- * charger / 48K resistor, and with no pulldown resistor.
- */
-
-#define ADC_NOM_CHG_DETECT_1A 6
-#define ADC_NOM_CHG_DETECT_USB 43
-
-static void
-gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
-{
- int ma;
-
- /* Interpret charger type */
- if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
-
- /*
- * Sanity - stop GPO driving out now that we have a 1A charger
- * GPO controls USB Host power generation on GTA02
- */
- pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
-
- ma = 1000;
- } else
- ma = 100;
-
- pcf50633_mbc_usb_curlim_set(pcf, ma);
-}
-
-static struct delayed_work gta02_charger_work;
-static int gta02_usb_vbus_draw;
-
-static void gta02_charger_worker(struct work_struct *work)
-{
- if (gta02_usb_vbus_draw) {
- pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
- return;
- }
-
-#ifdef CONFIG_PCF50633_ADC
- pcf50633_adc_async_read(gta02_pcf,
- PCF50633_ADCC1_MUX_ADCIN1,
- PCF50633_ADCC1_AVERAGE_16,
- gta02_configure_pmu_for_charger,
- NULL);
-#else
- /*
- * If the PCF50633 ADC is disabled we fallback to a
- * 100mA limit for safety.
- */
- pcf50633_mbc_usb_curlim_set(pcf, 100);
-#endif
-}
-
-#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
-
-static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
-{
- if (irq == PCF50633_IRQ_USBINS) {
- schedule_delayed_work(&gta02_charger_work,
- GTA02_CHARGER_CONFIGURE_TIMEOUT);
-
- return;
- }
-
- if (irq == PCF50633_IRQ_USBREM) {
- cancel_delayed_work_sync(&gta02_charger_work);
- gta02_usb_vbus_draw = 0;
- }
-}
-
-static void gta02_udc_vbus_draw(unsigned int ma)
-{
- if (!gta02_pcf)
- return;
-
- gta02_usb_vbus_draw = ma;
-
- schedule_delayed_work(&gta02_charger_work,
- GTA02_CHARGER_CONFIGURE_TIMEOUT);
-}
-#else /* !CONFIG_CHARGER_PCF50633 */
-#define gta02_pmu_event_callback NULL
-#define gta02_udc_vbus_draw NULL
-#endif
-
-/*
- * This is called when pc50633 is probed, unfortunately quite late in the
- * day since it is an I2C bus device. Here we can belatedly define some
- * platform devices with the advantage that we can mark the pcf50633 as the
- * parent. This makes them get suspended and resumed with their parent
- * the pcf50633 still around.
- */
-
-static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
-
-
-static char *gta02_batteries[] = {
- "battery",
-};
-
-struct pcf50633_platform_data gta02_pcf_pdata = {
- .resumers = {
- [0] = PCF50633_INT1_USBINS |
- PCF50633_INT1_USBREM |
- PCF50633_INT1_ALARM,
- [1] = PCF50633_INT2_ONKEYF,
- [2] = PCF50633_INT3_ONKEY1S,
- [3] = PCF50633_INT4_LOWSYS |
- PCF50633_INT4_LOWBAT |
- PCF50633_INT4_HIGHTMP,
- },
-
- .batteries = gta02_batteries,
- .num_batteries = ARRAY_SIZE(gta02_batteries),
-
- .charger_reference_current_ma = 1000,
-
- .reg_init_data = {
- [PCF50633_REGULATOR_AUTO] = {
- .constraints = {
- .min_uV = 3300000,
- .max_uV = 3300000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .always_on = 1,
- .apply_uV = 1,
- .state_mem = {
- .enabled = 1,
- },
- },
- },
- [PCF50633_REGULATOR_DOWN1] = {
- .constraints = {
- .min_uV = 1300000,
- .max_uV = 1600000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .always_on = 1,
- .apply_uV = 1,
- },
- },
- [PCF50633_REGULATOR_DOWN2] = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .apply_uV = 1,
- .always_on = 1,
- .state_mem = {
- .enabled = 1,
- },
- },
- },
- [PCF50633_REGULATOR_HCLDO] = {
- .constraints = {
- .min_uV = 2000000,
- .max_uV = 3300000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- .always_on = 1,
- },
- },
- [PCF50633_REGULATOR_LDO1] = {
- .constraints = {
- .min_uV = 3300000,
- .max_uV = 3300000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .apply_uV = 1,
- .state_mem = {
- .enabled = 0,
- },
- },
- },
- [PCF50633_REGULATOR_LDO2] = {
- .constraints = {
- .min_uV = 3300000,
- .max_uV = 3300000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .apply_uV = 1,
- },
- },
- [PCF50633_REGULATOR_LDO3] = {
- .constraints = {
- .min_uV = 3000000,
- .max_uV = 3000000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .apply_uV = 1,
- },
- },
- [PCF50633_REGULATOR_LDO4] = {
- .constraints = {
- .min_uV = 3200000,
- .max_uV = 3200000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .apply_uV = 1,
- },
- },
- [PCF50633_REGULATOR_LDO5] = {
- .constraints = {
- .min_uV = 3000000,
- .max_uV = 3000000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .apply_uV = 1,
- .state_mem = {
- .enabled = 1,
- },
- },
- },
- [PCF50633_REGULATOR_LDO6] = {
- .constraints = {
- .min_uV = 3000000,
- .max_uV = 3000000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- },
- },
- [PCF50633_REGULATOR_MEMLDO] = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 1800000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL,
- .state_mem = {
- .enabled = 1,
- },
- },
- },
-
- },
- .probe_done = gta02_pmu_attach_child_devices,
- .mbc_event_callback = gta02_pmu_event_callback,
-};
-
-
-/* NOR Flash. */
-
-#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */
-#define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */
-
-static struct physmap_flash_data gta02_nor_flash_data = {
- .width = 2,
-};
-
-static struct resource gta02_nor_flash_resource = {
- .start = GTA02_FLASH_BASE,
- .end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device gta02_nor_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &gta02_nor_flash_data,
- },
- .resource = &gta02_nor_flash_resource,
- .num_resources = 1,
-};
-
-
-struct platform_device s3c24xx_pwm_device = {
- .name = "s3c24xx_pwm",
- .num_resources = 0,
-};
-
-static struct i2c_board_info gta02_i2c_devs[] __initdata = {
- {
- I2C_BOARD_INFO("pcf50633", 0x73),
- .irq = GTA02_IRQ_PCF50633,
- .platform_data = &gta02_pcf_pdata,
- },
- {
- I2C_BOARD_INFO("wm8753", 0x1a),
- },
-};
-
-static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
- [0] = {
- /*
- * This name is also hard-coded in the boot loaders, so
- * changing it would would require all users to upgrade
- * their boot loaders, some of which are stored in a NOR
- * that is considered to be immutable.
- */
- .name = "neo1973-nand",
- .nr_chips = 1,
- .flash_bbt = 1,
- },
-};
-
-/*
- * Choose a set of timings derived from S3C@2442B MCP54
- * data sheet (K5D2G13ACM-D075 MCP Memory).
- */
-
-static struct s3c2410_platform_nand __initdata gta02_nand_info = {
- .tacls = 0,
- .twrph0 = 25,
- .twrph1 = 15,
- .nr_sets = ARRAY_SIZE(gta02_nand_sets),
- .sets = gta02_nand_sets,
-};
-
-
-static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd)
-{
- switch (cmd) {
- case S3C2410_UDC_P_ENABLE:
- pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__);
- gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
- break;
- case S3C2410_UDC_P_DISABLE:
- pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__);
- gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0);
- break;
- case S3C2410_UDC_P_RESET:
- pr_debug("%s S3C2410_UDC_P_RESET\n", __func__);
- /* FIXME: Do something here. */
- }
-}
-
-/* Get PMU to set USB current limit accordingly. */
-static struct s3c2410_udc_mach_info gta02_udc_cfg = {
- .vbus_draw = gta02_udc_vbus_draw,
- .udc_command = gta02_udc_command,
-
-};
-
-
-
-static void gta02_bl_set_intensity(int intensity)
-{
- struct pcf50633 *pcf = gta02_pcf;
- int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
-
- /* We map 8-bit intensity to 6-bit intensity in hardware. */
- intensity >>= 2;
-
- /*
- * This can happen during, eg, print of panic on blanked console,
- * but we can't service i2c without interrupts active, so abort.
- */
- if (in_atomic()) {
- printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n");
- return;
- }
-
- old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
- if (intensity == old_intensity)
- return;
-
- /* We can't do this anywhere else. */
- pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5);
-
- if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3))
- old_intensity = 0;
-
- /*
- * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
- * if seen, you have to re-enable the LED unit.
- */
- if (!intensity || !old_intensity)
- pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0);
-
- /* Illegal to set LEDOUT to 0. */
- if (!intensity)
- pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
- else
- pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
- intensity);
-
- if (intensity)
- pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2);
-
-}
-
-static struct generic_bl_info gta02_bl_info = {
- .name = "gta02-bl",
- .max_intensity = 0xff,
- .default_intensity = 0xff,
- .set_bl_intensity = gta02_bl_set_intensity,
-};
-
-static struct platform_device gta02_bl_dev = {
- .name = "generic-bl",
- .id = 1,
- .dev = {
- .platform_data = &gta02_bl_info,
- },
-};
-
-
-
-/* USB */
-static struct s3c2410_hcd_info gta02_usb_info = {
- .port[0] = {
- .flags = S3C_HCDFLG_USED,
- },
- .port[1] = {
- .flags = 0,
- },
-};
-
-
-static void __init gta02_map_io(void)
-{
- s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
- s3c24xx_init_clocks(12000000);
- s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
-}
-
-
-/* These are the guys that don't need to be children of PMU. */
-
-static struct platform_device *gta02_devices[] __initdata = {
- &s3c_device_usb,
- &s3c_device_wdt,
- &s3c_device_sdi,
- &s3c_device_usbgadget,
- &s3c_device_nand,
- &gta02_nor_flash,
- &s3c24xx_pwm_device,
- &s3c_device_iis,
- &s3c_device_i2c0,
-};
-
-/* These guys DO need to be children of PMU. */
-
-static struct platform_device *gta02_devices_pmu_children[] = {
- &gta02_bl_dev,
-};
-
-
-/*
- * This is called when pc50633 is probed, quite late in the day since it is an
- * I2C bus device. Here we can define platform devices with the advantage that
- * we can mark the pcf50633 as the parent. This makes them get suspended and
- * resumed with their parent the pcf50633 still around. All devices whose
- * operation depends on something from pcf50633 must have this relationship
- * made explicit like this, or suspend and resume will become an unreliable
- * hellworld.
- */
-
-static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
-{
- int n;
-
- /* Grab a copy of the now probed PMU pointer. */
- gta02_pcf = pcf;
-
- for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
- gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
-
- platform_add_devices(gta02_devices_pmu_children,
- ARRAY_SIZE(gta02_devices_pmu_children));
-}
-
-static void gta02_poweroff(void)
-{
- pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
-}
-
-static void __init gta02_machine_init(void)
-{
- /* Set the panic callback to make AUX LED blink at ~5Hz. */
- panic_blink = gta02_panic_blink;
-
- s3c_pm_init();
-
-#ifdef CONFIG_CHARGER_PCF50633
- INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
-#endif
-
- s3c_device_usb.dev.platform_data = &gta02_usb_info;
-
- s3c24xx_udc_set_platdata(&gta02_udc_cfg);
- s3c_nand_set_platdata(&gta02_nand_info);
- s3c_i2c0_set_platdata(NULL);
-
- i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
-
- platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
- pm_power_off = gta02_poweroff;
-}
-
-
-MACHINE_START(NEO1973_GTA02, "GTA02")
- /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
- .phys_io = S3C2410_PA_UART,
- .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
- .boot_params = S3C2410_SDRAM_PA + 0x100,
- .map_io = gta02_map_io,
- .init_irq = s3c24xx_init_irq,
- .init_machine = gta02_machine_init,
- .timer = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2442/s3c2442.c b/arch/arm/mach-s3c2442/s3c2442.c
deleted file mode 100644
index 4663bdc7fff..00000000000
--- a/arch/arm/mach-s3c2442/s3c2442.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* linux/arch/arm/mach-s3c2442/s3c2442.c
- *
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2442 Mobile CPU support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/sysdev.h>
-
-#include <plat/s3c2442.h>
-#include <plat/cpu.h>
-
-static struct sys_device s3c2442_sysdev = {
- .cls = &s3c2442_sysclass,
-};
-
-int __init s3c2442_init(void)
-{
- printk("S3C2442: Initialising architecture\n");
-
- return sysdev_register(&s3c2442_sysdev);
-}
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index 4314c442490..698140af247 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -7,6 +7,7 @@ config CPU_S3C2443
depends on ARCH_S3C2410
select S3C2443_DMA if S3C2410_DMA
select CPU_LLSERIAL_S3C2440
+ select SAMSUNG_CLKSRC
help
Support for the S3C2443 SoC from the S3C24XX line
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 2785d69c95b..62cd4eaee01 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/mach-s3c2443/clock.c
*
- * Copyright (c) 2007 Simtec Electronics
+ * Copyright (c) 2007, 2010 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2443 Clock control support
@@ -42,6 +42,7 @@
#include <plat/s3c2443.h>
#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
#include <plat/cpu.h>
/* We currently have to assume that the system is running
@@ -53,141 +54,69 @@
* set the correct muxing at initialisation
*/
-static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
-{
- unsigned int clocks = clk->ctrlbit;
- unsigned long clkcon;
-
- clkcon = __raw_readl(S3C2443_HCLKCON);
-
- if (enable)
- clkcon |= clocks;
- else
- clkcon &= ~clocks;
-
- __raw_writel(clkcon, S3C2443_HCLKCON);
-
- return 0;
-}
-
-static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
{
- unsigned int clocks = clk->ctrlbit;
- unsigned long clkcon;
-
- clkcon = __raw_readl(S3C2443_PCLKCON);
+ u32 ctrlbit = clk->ctrlbit;
+ u32 con = __raw_readl(reg);
if (enable)
- clkcon |= clocks;
+ con |= ctrlbit;
else
- clkcon &= ~clocks;
-
- __raw_writel(clkcon, S3C2443_PCLKCON);
+ con &= ~ctrlbit;
+ __raw_writel(con, reg);
return 0;
}
-static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
-{
- unsigned int clocks = clk->ctrlbit;
- unsigned long clkcon;
-
- clkcon = __raw_readl(S3C2443_SCLKCON);
-
- if (enable)
- clkcon |= clocks;
- else
- clkcon &= ~clocks;
-
- __raw_writel(clkcon, S3C2443_SCLKCON);
-
- return 0;
-}
-
-static unsigned long s3c2443_roundrate_clksrc(struct clk *clk,
- unsigned long rate,
- unsigned int max)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- int div;
-
- if (rate > parent_rate)
- return parent_rate;
-
- /* note, we remove the +/- 1 calculations as they cancel out */
-
- div = (rate / parent_rate);
-
- if (div < 1)
- div = 1;
- else if (div > max)
- div = max;
-
- return parent_rate / div;
-}
-
-static unsigned long s3c2443_roundrate_clksrc4(struct clk *clk,
- unsigned long rate)
+static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
{
- return s3c2443_roundrate_clksrc(clk, rate, 4);
+ return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
}
-static unsigned long s3c2443_roundrate_clksrc16(struct clk *clk,
- unsigned long rate)
+static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
{
- return s3c2443_roundrate_clksrc(clk, rate, 16);
+ return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
}
-static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk,
- unsigned long rate)
+static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
{
- return s3c2443_roundrate_clksrc(clk, rate, 256);
+ return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
}
/* clock selections */
+/* mpllref is a direct descendant of clk_xtal by default, but it is not
+ * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+ * such directly equating the two source clocks is impossible.
+ */
static struct clk clk_mpllref = {
.name = "mpllref",
.parent = &clk_xtal,
.id = -1,
};
-#if 0
-static struct clk clk_mpll = {
- .name = "mpll",
- .parent = &clk_mpllref,
- .id = -1,
-};
-#endif
-
static struct clk clk_i2s_ext = {
.name = "i2s-ext",
.id = -1,
};
-static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent)
-{
- unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
-
- clksrc &= ~S3C2443_CLKSRC_EPLLREF_MASK;
-
- if (parent == &clk_xtal)
- clksrc |= S3C2443_CLKSRC_EPLLREF_XTAL;
- else if (parent == &clk_ext)
- clksrc |= S3C2443_CLKSRC_EPLLREF_EXTCLK;
- else if (parent != &clk_mpllref)
- return -EINVAL;
-
- __raw_writel(clksrc, S3C2443_CLKSRC);
- clk->parent = parent;
-
- return 0;
-}
+static struct clk *clk_epllref_sources[] = {
+ [0] = &clk_mpllref,
+ [1] = &clk_mpllref,
+ [2] = &clk_xtal,
+ [3] = &clk_ext,
+};
-static struct clk clk_epllref = {
- .name = "epllref",
- .id = -1,
- .set_parent = s3c2443_setparent_epllref,
+static struct clksrc_clk clk_epllref = {
+ .clk = {
+ .name = "epllref",
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_epllref_sources,
+ .nr_sources = ARRAY_SIZE(clk_epllref_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
};
static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
@@ -205,34 +134,29 @@ static struct clk clk_mdivclk = {
.name = "mdivclk",
.parent = &clk_mpllref,
.id = -1,
- .get_rate = s3c2443_getrate_mdivclk,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2443_getrate_mdivclk,
+ },
};
-static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
-{
- unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
-
- clksrc &= ~(S3C2443_CLKSRC_MSYSCLK_MPLL |
- S3C2443_CLKSRC_EXTCLK_DIV);
-
- if (parent == &clk_mpll)
- clksrc |= S3C2443_CLKSRC_MSYSCLK_MPLL;
- else if (parent == &clk_mdivclk)
- clksrc |= S3C2443_CLKSRC_EXTCLK_DIV;
- else if (parent != &clk_mpllref)
- return -EINVAL;
-
- __raw_writel(clksrc, S3C2443_CLKSRC);
- clk->parent = parent;
-
- return 0;
-}
+static struct clk *clk_msysclk_sources[] = {
+ [0] = &clk_mpllref,
+ [1] = &clk_mpll,
+ [2] = &clk_mdivclk,
+ [3] = &clk_mpllref,
+};
-static struct clk clk_msysclk = {
- .name = "msysclk",
- .parent = &clk_xtal,
- .id = -1,
- .set_parent = s3c2443_setparent_msysclk,
+static struct clksrc_clk clk_msysclk = {
+ .clk = {
+ .name = "msysclk",
+ .parent = &clk_xtal,
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_msysclk_sources,
+ .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
};
/* armdiv
@@ -241,152 +165,159 @@ static struct clk clk_msysclk = {
* divider values applied to it to then be fed into armclk.
*/
-static struct clk clk_armdiv = {
- .name = "armdiv",
- .id = -1,
- .parent = &clk_msysclk,
-};
+/* armdiv divisor table */
-/* armclk
- *
- * this is the clock fed into the ARM core itself, either from
- * armdiv or from hclk.
- */
+static unsigned int armdiv[16] = {
+ [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
+ [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
+ [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3,
+ [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4,
+ [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6,
+ [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8,
+ [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12,
+ [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16,
+};
-static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent)
+static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
{
- unsigned long clkdiv0;
-
- clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-
- if (parent == &clk_armdiv)
- clkdiv0 &= ~S3C2443_CLKDIV0_DVS;
- else if (parent == &clk_h)
- clkdiv0 |= S3C2443_CLKDIV0_DVS;
- else
- return -EINVAL;
+ clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
- __raw_writel(clkdiv0, S3C2443_CLKDIV0);
- return 0;
+ return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
}
-static struct clk clk_arm = {
- .name = "armclk",
- .id = -1,
- .set_parent = s3c2443_setparent_armclk,
-};
+static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ unsigned long calc;
+ unsigned best = 256; /* bigger than any value */
+ unsigned div;
+ int ptr;
-/* esysclk
- *
- * this is sourced from either the EPLL or the EPLLref clock
-*/
+ for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
+ div = armdiv[ptr];
+ calc = parent / div;
+ if (calc <= rate && div < best)
+ best = div;
+ }
-static int s3c2443_setparent_esysclk(struct clk *clk, struct clk *parent)
+ return parent / best;
+}
+
+static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
{
- unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+ unsigned long parent = clk_get_rate(clk->parent);
+ unsigned long calc;
+ unsigned div;
+ unsigned best = 256; /* bigger than any value */
+ int ptr;
+ int val = -1;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
+ div = armdiv[ptr];
+ calc = parent / div;
+ if (calc <= rate && div < best) {
+ best = div;
+ val = ptr;
+ }
+ }
- if (parent == &clk_epll)
- clksrc |= S3C2443_CLKSRC_ESYSCLK_EPLL;
- else if (parent == &clk_epllref)
- clksrc &= ~S3C2443_CLKSRC_ESYSCLK_EPLL;
- else
- return -EINVAL;
+ if (val >= 0) {
+ unsigned long clkcon0;
- __raw_writel(clksrc, S3C2443_CLKSRC);
- clk->parent = parent;
+ clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+ clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+ clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+ __raw_writel(clkcon0, S3C2443_CLKDIV0);
+ }
- return 0;
+ return (val == -1) ? -EINVAL : 0;
}
-static struct clk clk_esysclk = {
- .name = "esysclk",
- .parent = &clk_epll,
+static struct clk clk_armdiv = {
+ .name = "armdiv",
.id = -1,
- .set_parent = s3c2443_setparent_esysclk,
+ .parent = &clk_msysclk.clk,
+ .ops = &(struct clk_ops) {
+ .round_rate = s3c2443_armclk_roundrate,
+ .set_rate = s3c2443_armclk_setrate,
+ },
};
-/* uartclk
+/* armclk
*
- * UART baud-rate clock sourced from esysclk via a divisor
-*/
-
-static unsigned long s3c2443_getrate_uart(struct clk *clk)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
- div &= S3C2443_CLKDIV1_UARTDIV_MASK;
- div >>= S3C2443_CLKDIV1_UARTDIV_SHIFT;
+ * this is the clock fed into the ARM core itself, from armdiv or from hclk.
+ */
- return parent_rate / (div + 1);
-}
+static struct clk *clk_arm_sources[] = {
+ [0] = &clk_armdiv,
+ [1] = &clk_h,
+};
+static struct clksrc_clk clk_arm = {
+ .clk = {
+ .name = "armclk",
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_arm_sources,
+ .nr_sources = ARRAY_SIZE(clk_arm_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
+};
-static int s3c2443_setrate_uart(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
- rate = s3c2443_roundrate_clksrc16(clk, rate);
- rate = parent_rate / rate;
+static struct clk *clk_sysclk_sources[] = {
+ [0] = &clk_epllref.clk,
+ [1] = &clk_epll,
+};
- clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
- clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
+static struct clksrc_clk clk_esysclk = {
+ .clk = {
+ .name = "esysclk",
+ .parent = &clk_epll,
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_sysclk_sources,
+ .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
+};
- __raw_writel(clkdivn, S3C2443_CLKDIV1);
- return 0;
-}
+/* uartclk
+ *
+ * UART baud-rate clock sourced from esysclk via a divisor
+*/
-static struct clk clk_uart = {
- .name = "uartclk",
- .id = -1,
- .parent = &clk_esysclk,
- .get_rate = s3c2443_getrate_uart,
- .set_rate = s3c2443_setrate_uart,
- .round_rate = s3c2443_roundrate_clksrc16,
+static struct clksrc_clk clk_uart = {
+ .clk = {
+ .name = "uartclk",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
};
+
/* hsspi
*
* high-speed spi clock, sourced from esysclk
*/
-static unsigned long s3c2443_getrate_hsspi(struct clk *clk)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
- div &= S3C2443_CLKDIV1_HSSPIDIV_MASK;
- div >>= S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
-
- return parent_rate / (div + 1);
-}
-
-
-static int s3c2443_setrate_hsspi(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
- rate = s3c2443_roundrate_clksrc4(clk, rate);
- rate = parent_rate / rate;
-
- clkdivn &= ~S3C2443_CLKDIV1_HSSPIDIV_MASK;
- clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
-
- __raw_writel(clkdivn, S3C2443_CLKDIV1);
- return 0;
-}
-
-static struct clk clk_hsspi = {
- .name = "hsspi",
- .id = -1,
- .parent = &clk_esysclk,
- .ctrlbit = S3C2443_SCLKCON_HSSPICLK,
- .enable = s3c2443_clkcon_enable_s,
- .get_rate = s3c2443_getrate_hsspi,
- .set_rate = s3c2443_setrate_hsspi,
- .round_rate = s3c2443_roundrate_clksrc4,
+static struct clksrc_clk clk_hsspi = {
+ .clk = {
+ .name = "hsspi",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_HSSPICLK,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
};
/* usbhost
@@ -394,41 +325,15 @@ static struct clk clk_hsspi = {
* usb host bus-clock, usually 48MHz to provide USB bus clock timing
*/
-static unsigned long s3c2443_getrate_usbhost(struct clk *clk)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
- div &= S3C2443_CLKDIV1_USBHOSTDIV_MASK;
- div >>= S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
-
- return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
- rate = s3c2443_roundrate_clksrc4(clk, rate);
- rate = parent_rate / rate;
-
- clkdivn &= ~S3C2443_CLKDIV1_USBHOSTDIV_MASK;
- clkdivn |= (rate - 1) << S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
-
- __raw_writel(clkdivn, S3C2443_CLKDIV1);
- return 0;
-}
-
-static struct clk clk_usb_bus_host = {
- .name = "usb-bus-host-parent",
- .id = -1,
- .parent = &clk_esysclk,
- .ctrlbit = S3C2443_SCLKCON_USBHOST,
- .enable = s3c2443_clkcon_enable_s,
- .get_rate = s3c2443_getrate_usbhost,
- .set_rate = s3c2443_setrate_usbhost,
- .round_rate = s3c2443_roundrate_clksrc4,
+static struct clksrc_clk clk_usb_bus_host = {
+ .clk = {
+ .name = "usb-bus-host-parent",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_USBHOST,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
};
/* clk_hsmcc_div
@@ -438,39 +343,13 @@ static struct clk clk_usb_bus_host = {
* be fed to the hsmmc block
*/
-static unsigned long s3c2443_getrate_hsmmc_div(struct clk *clk)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
- div &= S3C2443_CLKDIV1_HSMMCDIV_MASK;
- div >>= S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
-
- return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_hsmmc_div(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
- rate = s3c2443_roundrate_clksrc4(clk, rate);
- rate = parent_rate / rate;
-
- clkdivn &= ~S3C2443_CLKDIV1_HSMMCDIV_MASK;
- clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
-
- __raw_writel(clkdivn, S3C2443_CLKDIV1);
- return 0;
-}
-
-static struct clk clk_hsmmc_div = {
- .name = "hsmmc-div",
- .id = -1,
- .parent = &clk_esysclk,
- .get_rate = s3c2443_getrate_hsmmc_div,
- .set_rate = s3c2443_setrate_hsmmc_div,
- .round_rate = s3c2443_roundrate_clksrc4,
+static struct clksrc_clk clk_hsmmc_div = {
+ .clk = {
+ .name = "hsmmc-div",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
};
static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
@@ -503,82 +382,55 @@ static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
static struct clk clk_hsmmc = {
.name = "hsmmc-if",
.id = -1,
- .parent = &clk_hsmmc_div,
+ .parent = &clk_hsmmc_div.clk,
.enable = s3c2443_enable_hsmmc,
- .set_parent = s3c2443_setparent_hsmmc,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2443_setparent_hsmmc,
+ },
};
/* i2s_eplldiv
*
- * this clock is the output from the i2s divisor of esysclk
+ * This clock is the output from the I2S divisor of ESYSCLK, and is seperate
+ * from the mux that comes after it (cannot merge into one single clock)
*/
-static unsigned long s3c2443_getrate_i2s_eplldiv(struct clk *clk)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
- div &= S3C2443_CLKDIV1_I2SDIV_MASK;
- div >>= S3C2443_CLKDIV1_I2SDIV_SHIFT;
-
- return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_i2s_eplldiv(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
- rate = s3c2443_roundrate_clksrc16(clk, rate);
- rate = parent_rate / rate;
-
- clkdivn &= ~S3C2443_CLKDIV1_I2SDIV_MASK;
- clkdivn |= (rate - 1) << S3C2443_CLKDIV1_I2SDIV_SHIFT;
-
- __raw_writel(clkdivn, S3C2443_CLKDIV1);
- return 0;
-}
-
-static struct clk clk_i2s_eplldiv = {
- .name = "i2s-eplldiv",
- .id = -1,
- .parent = &clk_esysclk,
- .get_rate = s3c2443_getrate_i2s_eplldiv,
- .set_rate = s3c2443_setrate_i2s_eplldiv,
- .round_rate = s3c2443_roundrate_clksrc16,
+static struct clksrc_clk clk_i2s_eplldiv = {
+ .clk = {
+ .name = "i2s-eplldiv",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
};
/* i2s-ref
*
* i2s bus reference clock, selectable from external, esysclk or epllref
+ *
+ * Note, this used to be two clocks, but was compressed into one.
*/
-static int s3c2443_setparent_i2s(struct clk *clk, struct clk *parent)
-{
- unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
-
- clksrc &= ~S3C2443_CLKSRC_I2S_MASK;
-
- if (parent == &clk_epllref)
- clksrc |= S3C2443_CLKSRC_I2S_EPLLREF;
- else if (parent == &clk_i2s_ext)
- clksrc |= S3C2443_CLKSRC_I2S_EXT;
- else if (parent != &clk_i2s_eplldiv)
- return -EINVAL;
-
- clk->parent = parent;
- __raw_writel(clksrc, S3C2443_CLKSRC);
-
- return 0;
-}
+struct clk *clk_i2s_srclist[] = {
+ [0] = &clk_i2s_eplldiv.clk,
+ [1] = &clk_i2s_ext,
+ [2] = &clk_epllref.clk,
+ [3] = &clk_epllref.clk,
+};
-static struct clk clk_i2s = {
- .name = "i2s-if",
- .id = -1,
- .parent = &clk_i2s_eplldiv,
- .ctrlbit = S3C2443_SCLKCON_I2SCLK,
- .enable = s3c2443_clkcon_enable_s,
- .set_parent = s3c2443_setparent_i2s,
+static struct clksrc_clk clk_i2s = {
+ .clk = {
+ .name = "i2s-if",
+ .id = -1,
+ .ctrlbit = S3C2443_SCLKCON_I2SCLK,
+ .enable = s3c2443_clkcon_enable_s,
+
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_i2s_srclist,
+ .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
};
/* cam-if
@@ -586,41 +438,15 @@ static struct clk clk_i2s = {
* camera interface bus-clock, divided down from esysclk
*/
-static unsigned long s3c2443_getrate_cam(struct clk *clk)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
- div &= S3C2443_CLKDIV1_CAMDIV_MASK;
- div >>= S3C2443_CLKDIV1_CAMDIV_SHIFT;
-
- return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_cam(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long clkdiv1 = __raw_readl(S3C2443_CLKDIV1);
-
- rate = s3c2443_roundrate_clksrc16(clk, rate);
- rate = parent_rate / rate;
-
- clkdiv1 &= ~S3C2443_CLKDIV1_CAMDIV_MASK;
- clkdiv1 |= (rate - 1) << S3C2443_CLKDIV1_CAMDIV_SHIFT;
-
- __raw_writel(clkdiv1, S3C2443_CLKDIV1);
- return 0;
-}
-
-static struct clk clk_cam = {
- .name = "camif-upll", /* same as 2440 name */
- .id = -1,
- .parent = &clk_esysclk,
- .ctrlbit = S3C2443_SCLKCON_CAMCLK,
- .enable = s3c2443_clkcon_enable_s,
- .get_rate = s3c2443_getrate_cam,
- .set_rate = s3c2443_setrate_cam,
- .round_rate = s3c2443_roundrate_clksrc16,
+static struct clksrc_clk clk_cam = {
+ .clk = {
+ .name = "camif-upll", /* same as 2440 name */
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_CAMCLK,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
};
/* display-if
@@ -628,41 +454,15 @@ static struct clk clk_cam = {
* display interface clock, divided from esysclk
*/
-static unsigned long s3c2443_getrate_display(struct clk *clk)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long div = __raw_readl(S3C2443_CLKDIV1);
-
- div &= S3C2443_CLKDIV1_DISPDIV_MASK;
- div >>= S3C2443_CLKDIV1_DISPDIV_SHIFT;
-
- return parent_rate / (div + 1);
-}
-
-static int s3c2443_setrate_display(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
-
- rate = s3c2443_roundrate_clksrc256(clk, rate);
- rate = parent_rate / rate;
-
- clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
- clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
-
- __raw_writel(clkdivn, S3C2443_CLKDIV1);
- return 0;
-}
-
-static struct clk clk_display = {
- .name = "display-if",
- .id = -1,
- .parent = &clk_esysclk,
- .ctrlbit = S3C2443_SCLKCON_DISPCLK,
- .enable = s3c2443_clkcon_enable_s,
- .get_rate = s3c2443_getrate_display,
- .set_rate = s3c2443_setrate_display,
- .round_rate = s3c2443_roundrate_clksrc256,
+static struct clksrc_clk clk_display = {
+ .clk = {
+ .name = "display-if",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_DISPCLK,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
};
/* prediv
@@ -684,8 +484,10 @@ static unsigned long s3c2443_prediv_getrate(struct clk *clk)
static struct clk clk_prediv = {
.name = "prediv",
.id = -1,
- .parent = &clk_msysclk,
- .get_rate = s3c2443_prediv_getrate,
+ .parent = &clk_msysclk.clk,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2443_prediv_getrate,
+ },
};
/* standard clock definitions */
@@ -857,7 +659,7 @@ static struct clk init_clocks[] = {
}, {
.name = "usb-bus-host",
.id = -1,
- .parent = &clk_usb_bus_host,
+ .parent = &clk_usb_bus_host.clk,
}, {
.name = "ac97",
.id = -1,
@@ -868,103 +670,26 @@ static struct clk init_clocks[] = {
/* clocks to add where we need to check their parentage */
-/* s3c2443_clk_initparents
- *
- * Initialise the parents for the clocks that we get at start-time
-*/
-
-static int __init clk_init_set_parent(struct clk *clk, struct clk *parent)
-{
- printk(KERN_DEBUG "clock %s: parent %s\n", clk->name, parent->name);
- return clk_set_parent(clk, parent);
-}
-
-static void __init s3c2443_clk_initparents(void)
-{
- unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
- struct clk *parent;
-
- switch (clksrc & S3C2443_CLKSRC_EPLLREF_MASK) {
- case S3C2443_CLKSRC_EPLLREF_EXTCLK:
- parent = &clk_ext;
- break;
-
- case S3C2443_CLKSRC_EPLLREF_XTAL:
- default:
- parent = &clk_xtal;
- break;
-
- case S3C2443_CLKSRC_EPLLREF_MPLLREF:
- case S3C2443_CLKSRC_EPLLREF_MPLLREF2:
- parent = &clk_mpllref;
- break;
- }
-
- clk_init_set_parent(&clk_epllref, parent);
-
- switch (clksrc & S3C2443_CLKSRC_I2S_MASK) {
- case S3C2443_CLKSRC_I2S_EXT:
- parent = &clk_i2s_ext;
- break;
-
- case S3C2443_CLKSRC_I2S_EPLLDIV:
- default:
- parent = &clk_i2s_eplldiv;
- break;
-
- case S3C2443_CLKSRC_I2S_EPLLREF:
- case S3C2443_CLKSRC_I2S_EPLLREF3:
- parent = &clk_epllref;
- }
-
- clk_init_set_parent(&clk_i2s, &clk_epllref);
-
- /* esysclk source */
-
- parent = (clksrc & S3C2443_CLKSRC_ESYSCLK_EPLL) ?
- &clk_epll : &clk_epllref;
-
- clk_init_set_parent(&clk_esysclk, parent);
-
- /* msysclk source */
-
- if (clksrc & S3C2443_CLKSRC_MSYSCLK_MPLL) {
- parent = &clk_mpll;
- } else {
- parent = (clksrc & S3C2443_CLKSRC_EXTCLK_DIV) ?
- &clk_mdivclk : &clk_mpllref;
- }
-
- clk_init_set_parent(&clk_msysclk, parent);
-
- /* arm */
-
- if (__raw_readl(S3C2443_CLKDIV0) & S3C2443_CLKDIV0_DVS)
- parent = &clk_h;
- else
- parent = &clk_armdiv;
-
- clk_init_set_parent(&clk_arm, parent);
-}
-
-/* armdiv divisor table */
-
-static unsigned int armdiv[16] = {
- [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
- [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
- [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3,
- [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4,
- [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6,
- [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8,
- [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12,
- [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16,
+static struct clksrc_clk __initdata *init_list[] = {
+ &clk_epllref, /* should be first */
+ &clk_esysclk,
+ &clk_msysclk,
+ &clk_arm,
+ &clk_i2s_eplldiv,
+ &clk_i2s,
+ &clk_cam,
+ &clk_uart,
+ &clk_display,
+ &clk_hsmmc_div,
+ &clk_usb_bus_host,
};
-static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
+static void __init s3c2443_clk_initparents(void)
{
- clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+ int ptr;
- return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+ for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++)
+ s3c_set_clksrc(init_list[ptr], true);
}
static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
@@ -976,15 +701,12 @@ static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
/* clocks to add straight away */
-static struct clk *clks[] __initdata = {
- &clk_ext,
- &clk_epll,
+static struct clksrc_clk *clksrcs[] __initdata = {
&clk_usb_bus_host,
- &clk_usb_bus,
- &clk_esysclk,
&clk_epllref,
- &clk_mpllref,
+ &clk_esysclk,
&clk_msysclk,
+ &clk_arm,
&clk_uart,
&clk_display,
&clk_cam,
@@ -992,9 +714,15 @@ static struct clk *clks[] __initdata = {
&clk_i2s,
&clk_hsspi,
&clk_hsmmc_div,
+};
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_epll,
+ &clk_usb_bus,
+ &clk_mpllref,
&clk_hsmmc,
&clk_armdiv,
- &clk_arm,
&clk_prediv,
};
@@ -1014,7 +742,7 @@ void __init_or_cpufreq s3c2443_setup_clocks(void)
clk_put(xtal_clk);
pll = s3c2443_get_mpll(mpllcon, xtal);
- clk_msysclk.rate = pll;
+ clk_msysclk.clk.rate = pll;
fclk = pll / s3c2443_fclk_div(clkdiv0);
hclk = s3c2443_prediv_getrate(&clk_prediv);
@@ -1056,15 +784,18 @@ void __init s3c2443_init_clocks(int xtal)
}
}
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_register_clksrc(clksrcs[ptr], 1);
+
clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
- clk_epll.parent = &clk_epllref;
- clk_usb_bus.parent = &clk_usb_bus_host;
+ clk_epll.parent = &clk_epllref.clk;
+ clk_usb_bus.parent = &clk_usb_bus_host.clk;
/* ensure usb bus clock is within correct rate of 48MHz */
- if (clk_get_rate(&clk_usb_bus_host) != (48 * 1000 * 1000)) {
+ if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
- clk_set_rate(&clk_usb_bus_host, 48*1000*1000);
+ clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
}
printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
@@ -1074,14 +805,7 @@ void __init s3c2443_init_clocks(int xtal)
/* register clocks from clock array */
- clkp = init_clocks;
- for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
- }
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
/* We must be careful disabling the clocks we are not intending to
* be using at boot time, as subsystems such as the LCD which do
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
index 397f3b5c0b4..3f658685ec1 100644
--- a/arch/arm/mach-s3c2443/dma.c
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -20,7 +20,7 @@
#include <mach/dma.h>
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
#include <plat/cpu.h>
#include <plat/regs-serial.h>
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
index 039a4624310..e2e362bda9b 100644
--- a/arch/arm/mach-s3c2443/mach-smdk2443.c
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -40,7 +40,7 @@
#include <plat/iic.h>
#include <plat/s3c2410.h>
-#include <plat/s3c2440.h>
+#include <plat/s3c2443.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -106,6 +106,9 @@ static struct platform_device *smdk2443_devices[] __initdata = {
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_hsmmc0,
+#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
+ &s3c_device_ac97,
+#endif
};
static void __init smdk2443_map_io(void)
@@ -118,6 +121,11 @@ static void __init smdk2443_map_io(void)
static void __init smdk2443_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
+
+#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
+ s3c24xx_ac97_setup_gpio(S3C24XX_AC97_GPE0);
+#endif
+
platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices));
smdk_machine_init();
}
diff --git a/arch/arm/mach-s3c24a0/include/mach/io.h b/arch/arm/mach-s3c24a0/include/mach/io.h
new file mode 100644
index 00000000000..4326c30fabc
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/io.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c24a0/include/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S3C24A0
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s3c6400/Kconfig b/arch/arm/mach-s3c6400/Kconfig
deleted file mode 100644
index a250bf68709..00000000000
--- a/arch/arm/mach-s3c6400/Kconfig
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2008 Openmoko, Inc.
-# Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
-#
-# Licensed under GPLv2
-
-# Configuration options for the S3C6410 CPU
-
-config CPU_S3C6400
- bool
- select CPU_S3C6400_INIT
- select CPU_S3C6400_CLOCK
- help
- Enable S3C6400 CPU support
-
-config S3C6400_SETUP_SDHCI
- bool
- help
- Internal configuration for default SDHCI
- setup for S3C6400.
-
-# S36400 Macchine support
-
-config MACH_SMDK6400
- bool "SMDK6400"
- select CPU_S3C6400
- select S3C_DEV_HSMMC
- select S3C_DEV_NAND
- select S3C6400_SETUP_SDHCI
- help
- Machine support for the Samsung SMDK6400
diff --git a/arch/arm/mach-s3c6400/Makefile b/arch/arm/mach-s3c6400/Makefile
deleted file mode 100644
index df1ce4aa03e..00000000000
--- a/arch/arm/mach-s3c6400/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-# arch/arm/mach-s3c6400/Makefile
-#
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-
-# Core support for S3C6400 system
-
-obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
-
-# setup support
-
-obj-$(CONFIG_S3C6400_SETUP_SDHCI) += setup-sdhci.o
-
-# Machine support
-
-obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
diff --git a/arch/arm/mach-s3c6400/include/mach/debug-macro.S b/arch/arm/mach-s3c6400/include/mach/debug-macro.S
deleted file mode 100644
index 5c88875d6a3..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/debug-macro.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* pull in the relevant register and map files. */
-
-#include <mach/map.h>
-#include <plat/regs-serial.h>
-
- /* note, for the boot process to work we have to keep the UART
- * virtual address aligned to an 1MiB boundary for the L1
- * mapping the head code makes. We keep the UART virtual address
- * aligned and add in the offset when we load the value here.
- */
-
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- ldreq \rx, = S3C_PA_UART
- ldrne \rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
-#if CONFIG_DEBUG_S3C_UART != 0
- add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
-#endif
- .endm
-
-/* include the reset of the code which will do the work, we're only
- * compiling for a single cpu processor type so the default of s3c2440
- * will be fine with us.
- */
-
-#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s3c6400/include/mach/dma.h b/arch/arm/mach-s3c6400/include/mach/dma.h
deleted file mode 100644
index 6723860748b..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/dma.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/dma.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C6400 - DMA support
- */
-
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H __FILE__
-
-#define S3C_DMA_CHANNELS (16)
-
-/* see mach-s3c2410/dma.h for notes on dma channel numbers */
-
-/* Note, for the S3C64XX architecture we keep the DMACH_
- * defines in the order they are allocated to [S]DMA0/[S]DMA1
- * so that is easy to do DHACH_ -> DMA controller conversion
- */
-enum dma_ch {
- /* DMA0/SDMA0 */
- DMACH_UART0 = 0,
- DMACH_UART0_SRC2,
- DMACH_UART1,
- DMACH_UART1_SRC2,
- DMACH_UART2,
- DMACH_UART2_SRC2,
- DMACH_UART3,
- DMACH_UART3_SRC2,
- DMACH_PCM0_TX,
- DMACH_PCM0_RX,
- DMACH_I2S0_OUT,
- DMACH_I2S0_IN,
- DMACH_SPI0_TX,
- DMACH_SPI0_RX,
- DMACH_HSI_I2SV40_TX,
- DMACH_HSI_I2SV40_RX,
-
- /* DMA1/SDMA1 */
- DMACH_PCM1_TX = 16,
- DMACH_PCM1_RX,
- DMACH_I2S1_OUT,
- DMACH_I2S1_IN,
- DMACH_SPI1_TX,
- DMACH_SPI1_RX,
- DMACH_AC97_PCMOUT,
- DMACH_AC97_PCMIN,
- DMACH_AC97_MICIN,
- DMACH_PWM,
- DMACH_IRDA,
- DMACH_EXTERNAL,
- DMACH_RES1,
- DMACH_RES2,
- DMACH_SECURITY_RX, /* SDMA1 only */
- DMACH_SECURITY_TX, /* SDMA1 only */
- DMACH_MAX /* the end */
-};
-
-static __inline__ bool s3c_dma_has_circular(void)
-{
- return true;
-}
-
-#define S3C2410_DMAF_CIRCULAR (1 << 0)
-
-#include <plat/dma.h>
-
-#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/entry-macro.S b/arch/arm/mach-s3c6400/include/mach/entry-macro.S
deleted file mode 100644
index fbd90d2cf35..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/entry-macro.S
+++ /dev/null
@@ -1,44 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/entry-macro.S
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Low-level IRQ helper macros for the Samsung S3C64XX series
- *
- * 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 <asm/hardware/vic.h>
-#include <mach/map.h>
-#include <plat/irqs.h>
-
- .macro disable_fiq
- .endm
-
- .macro get_irqnr_preamble, base, tmp
- ldr \base, =S3C_VA_VIC0
- .endm
-
- .macro arch_ret_to_user, tmp1, tmp2
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-
- @ check the vic0
- mov \irqnr, # S3C_IRQ_OFFSET + 31
- ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
- teq \irqstat, #0
-
- @ otherwise try vic1
- addeq \tmp, \base, #(S3C_VA_VIC1 - S3C_VA_VIC0)
- addeq \irqnr, \irqnr, #32
- ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
- teqeq \irqstat, #0
-
- clzne \irqstat, \irqstat
- subne \irqnr, \irqnr, \irqstat
- .endm
diff --git a/arch/arm/mach-s3c6400/include/mach/gpio-core.h b/arch/arm/mach-s3c6400/include/mach/gpio-core.h
deleted file mode 100644
index d89aae68b0a..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/gpio-core.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/gpio-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX - GPIO core support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_CORE_H
-#define __ASM_ARCH_GPIO_CORE_H __FILE__
-
-/* currently we just include the platform support */
-#include <plat/gpio-core.h>
-
-#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/gpio.h b/arch/arm/mach-s3c6400/include/mach/gpio.h
deleted file mode 100644
index e8e35e8fe73..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/gpio.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* arch/arm/mach-s3c6400/include/mach/gpio.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C6400 - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#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
-
-/* GPIO bank sizes */
-#define S3C64XX_GPIO_A_NR (8)
-#define S3C64XX_GPIO_B_NR (7)
-#define S3C64XX_GPIO_C_NR (8)
-#define S3C64XX_GPIO_D_NR (5)
-#define S3C64XX_GPIO_E_NR (5)
-#define S3C64XX_GPIO_F_NR (16)
-#define S3C64XX_GPIO_G_NR (7)
-#define S3C64XX_GPIO_H_NR (10)
-#define S3C64XX_GPIO_I_NR (16)
-#define S3C64XX_GPIO_J_NR (12)
-#define S3C64XX_GPIO_K_NR (16)
-#define S3C64XX_GPIO_L_NR (15)
-#define S3C64XX_GPIO_M_NR (6)
-#define S3C64XX_GPIO_N_NR (16)
-#define S3C64XX_GPIO_O_NR (16)
-#define S3C64XX_GPIO_P_NR (15)
-#define S3C64XX_GPIO_Q_NR (9)
-
-/* GPIO bank numbes */
-
-/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
- * space for debugging purposes so that any accidental
- * change from one gpio bank to another can be caught.
-*/
-
-#define S3C64XX_GPIO_NEXT(__gpio) \
- ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
-
-enum s3c_gpio_number {
- S3C64XX_GPIO_A_START = 0,
- S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),
- S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),
- S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),
- S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),
- S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),
- S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),
- S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),
- S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),
- S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),
- S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),
- S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),
- S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),
- S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),
- S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),
- S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),
- S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),
-};
-
-/* S3C64XX GPIO number definitions. */
-
-#define S3C64XX_GPA(_nr) (S3C64XX_GPIO_A_START + (_nr))
-#define S3C64XX_GPB(_nr) (S3C64XX_GPIO_B_START + (_nr))
-#define S3C64XX_GPC(_nr) (S3C64XX_GPIO_C_START + (_nr))
-#define S3C64XX_GPD(_nr) (S3C64XX_GPIO_D_START + (_nr))
-#define S3C64XX_GPE(_nr) (S3C64XX_GPIO_E_START + (_nr))
-#define S3C64XX_GPF(_nr) (S3C64XX_GPIO_F_START + (_nr))
-#define S3C64XX_GPG(_nr) (S3C64XX_GPIO_G_START + (_nr))
-#define S3C64XX_GPH(_nr) (S3C64XX_GPIO_H_START + (_nr))
-#define S3C64XX_GPI(_nr) (S3C64XX_GPIO_I_START + (_nr))
-#define S3C64XX_GPJ(_nr) (S3C64XX_GPIO_J_START + (_nr))
-#define S3C64XX_GPK(_nr) (S3C64XX_GPIO_K_START + (_nr))
-#define S3C64XX_GPL(_nr) (S3C64XX_GPIO_L_START + (_nr))
-#define S3C64XX_GPM(_nr) (S3C64XX_GPIO_M_START + (_nr))
-#define S3C64XX_GPN(_nr) (S3C64XX_GPIO_N_START + (_nr))
-#define S3C64XX_GPO(_nr) (S3C64XX_GPIO_O_START + (_nr))
-#define S3C64XX_GPP(_nr) (S3C64XX_GPIO_P_START + (_nr))
-#define S3C64XX_GPQ(_nr) (S3C64XX_GPIO_Q_START + (_nr))
-
-/* the end of the S3C64XX specific gpios */
-#define S3C64XX_GPIO_END (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
-#define S3C_GPIO_END S3C64XX_GPIO_END
-
-/* define the number of gpios we need to the one after the GPQ() range */
-#define ARCH_NR_GPIOS (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
-
-#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-s3c6400/include/mach/irqs.h b/arch/arm/mach-s3c6400/include/mach/irqs.h
deleted file mode 100644
index 4c97f9a4370..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/irqs.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/irqs.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C6400 - IRQ definitions
- */
-
-#ifndef __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H __FILE__
-
-#include <plat/irqs.h>
-
-#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h
deleted file mode 100644
index 106ee13581e..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/map.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/map.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MAP_H
-#define __ASM_ARCH_MAP_H __FILE__
-
-#include <plat/map-base.h>
-
-/* HSMMC units */
-#define S3C64XX_PA_HSMMC(x) (0x7C200000 + ((x) * 0x100000))
-#define S3C64XX_PA_HSMMC0 S3C64XX_PA_HSMMC(0)
-#define S3C64XX_PA_HSMMC1 S3C64XX_PA_HSMMC(1)
-#define S3C64XX_PA_HSMMC2 S3C64XX_PA_HSMMC(2)
-
-#define S3C_PA_UART (0x7F005000)
-#define S3C_PA_UART0 (S3C_PA_UART + 0x00)
-#define S3C_PA_UART1 (S3C_PA_UART + 0x400)
-#define S3C_PA_UART2 (S3C_PA_UART + 0x800)
-#define S3C_PA_UART3 (S3C_PA_UART + 0xC00)
-#define S3C_UART_OFFSET (0x400)
-
-/* See notes on UART VA mapping in debug-macro.S */
-#define S3C_VA_UARTx(x) (S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET))
-
-#define S3C_VA_UART0 S3C_VA_UARTx(0)
-#define S3C_VA_UART1 S3C_VA_UARTx(1)
-#define S3C_VA_UART2 S3C_VA_UARTx(2)
-#define S3C_VA_UART3 S3C_VA_UARTx(3)
-
-#define S3C64XX_PA_NAND (0x70200000)
-#define S3C64XX_PA_FB (0x77100000)
-#define S3C64XX_PA_USB_HSOTG (0x7C000000)
-#define S3C64XX_PA_WATCHDOG (0x7E004000)
-#define S3C64XX_PA_SYSCON (0x7E00F000)
-#define S3C64XX_PA_AC97 (0x7F001000)
-#define S3C64XX_PA_IIS0 (0x7F002000)
-#define S3C64XX_PA_IIS1 (0x7F003000)
-#define S3C64XX_PA_TIMER (0x7F006000)
-#define S3C64XX_PA_IIC0 (0x7F004000)
-#define S3C64XX_PA_PCM0 (0x7F009000)
-#define S3C64XX_PA_PCM1 (0x7F00A000)
-#define S3C64XX_PA_IISV4 (0x7F00D000)
-#define S3C64XX_PA_IIC1 (0x7F00F000)
-
-#define S3C64XX_PA_GPIO (0x7F008000)
-#define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000)
-#define S3C64XX_SZ_GPIO SZ_4K
-
-#define S3C64XX_PA_SDRAM (0x50000000)
-#define S3C64XX_PA_VIC0 (0x71200000)
-#define S3C64XX_PA_VIC1 (0x71300000)
-
-#define S3C64XX_PA_MODEM (0x74108000)
-#define S3C64XX_VA_MODEM S3C_ADDR_CPU(0x00100000)
-
-#define S3C64XX_PA_USBHOST (0x74300000)
-
-#define S3C64XX_PA_USB_HSPHY (0x7C100000)
-#define S3C64XX_VA_USB_HSPHY S3C_ADDR_CPU(0x00200000)
-
-/* place VICs close together */
-#define S3C_VA_VIC0 (S3C_VA_IRQ + 0x00)
-#define S3C_VA_VIC1 (S3C_VA_IRQ + 0x10000)
-
-/* compatibiltiy defines. */
-#define S3C_PA_TIMER S3C64XX_PA_TIMER
-#define S3C_PA_HSMMC0 S3C64XX_PA_HSMMC0
-#define S3C_PA_HSMMC1 S3C64XX_PA_HSMMC1
-#define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2
-#define S3C_PA_IIC S3C64XX_PA_IIC0
-#define S3C_PA_IIC1 S3C64XX_PA_IIC1
-#define S3C_PA_NAND S3C64XX_PA_NAND
-#define S3C_PA_FB S3C64XX_PA_FB
-#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
-#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
-#define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY
-
-#endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/regs-clock.h b/arch/arm/mach-s3c6400/include/mach/regs-clock.h
deleted file mode 100644
index a6c7f4eb3a1..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/regs-clock.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/regs-clock.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - clock register compatibility with s3c24xx
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <plat/regs-clock.h>
-
diff --git a/arch/arm/mach-s3c6400/include/mach/tick.h b/arch/arm/mach-s3c6400/include/mach/tick.h
deleted file mode 100644
index d9c0dc7014e..00000000000
--- a/arch/arm/mach-s3c6400/include/mach/tick.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/tick.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - Timer tick support definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TICK_H
-#define __ASM_ARCH_TICK_H __FILE__
-
-/* note, the timer interrutps turn up in 2 places, the vic and then
- * the timer block. We take the VIC as the base at the moment.
- */
-static inline u32 s3c24xx_ostimer_pending(void)
-{
- u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS);
- return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0));
-}
-
-#define TICK_MAX (0xffffffff)
-
-#endif /* __ASM_ARCH_6400_TICK_H */
diff --git a/arch/arm/mach-s3c6400/mach-smdk6400.c b/arch/arm/mach-s3c6400/mach-smdk6400.c
deleted file mode 100644
index ab19285389a..00000000000
--- a/arch/arm/mach-s3c6400/mach-smdk6400.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/mach-smdk6400.c
- *
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/regs-serial.h>
-
-#include <plat/s3c6400.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/iic.h>
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk6400_uartcfgs[] __initdata = {
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = 0x3c5,
- .ulcon = 0x03,
- .ufcon = 0x51,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = 0x3c5,
- .ulcon = 0x03,
- .ufcon = 0x51,
- },
-};
-
-static struct map_desc smdk6400_iodesc[] = {};
-
-static void __init smdk6400_map_io(void)
-{
- s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
- s3c24xx_init_clocks(12000000);
- s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
-}
-
-static struct platform_device *smdk6400_devices[] __initdata = {
- &s3c_device_hsmmc1,
- &s3c_device_i2c0,
-};
-
-static struct i2c_board_info i2c_devs[] __initdata = {
- { I2C_BOARD_INFO("wm8753", 0x1A), },
- { I2C_BOARD_INFO("24c08", 0x50), },
-};
-
-static void __init smdk6400_machine_init(void)
-{
- i2c_register_board_info(0, i2c_devs, ARRAY_SIZE(i2c_devs));
- platform_add_devices(smdk6400_devices, ARRAY_SIZE(smdk6400_devices));
-}
-
-MACHINE_START(SMDK6400, "SMDK6400")
- /* Maintainer: Ben Dooks <ben@fluff.org> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
- .boot_params = S3C64XX_PA_SDRAM + 0x100,
-
- .init_irq = s3c6400_init_irq,
- .map_io = smdk6400_map_io,
- .init_machine = smdk6400_machine_init,
- .timer = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c6400/s3c6400.c b/arch/arm/mach-s3c6400/s3c6400.c
deleted file mode 100644
index d876ee50367..00000000000
--- a/arch/arm/mach-s3c6400/s3c6400.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/cpu.c
- *
- * Copyright 2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/sdhci.h>
-#include <plat/iic-core.h>
-#include <plat/s3c6400.h>
-
-void __init s3c6400_map_io(void)
-{
- /* setup SDHCI */
-
- s3c6400_default_sdhci0();
- s3c6400_default_sdhci1();
- s3c6400_default_sdhci2();
-
- /* the i2c devices are directly compatible with s3c2440 */
- s3c_i2c0_setname("s3c2440-i2c");
-
- s3c_device_nand.name = "s3c6400-nand";
-}
-
-void __init s3c6400_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
- s3c24xx_register_baseclocks(xtal);
- s3c64xx_register_clocks();
- s3c6400_register_clocks(S3C6400_CLKDIV0_ARM_MASK);
- s3c6400_setup_clocks();
-}
-
-void __init s3c6400_init_irq(void)
-{
- /* VIC0 does not have IRQS 5..7,
- * VIC1 is fully populated. */
- s3c64xx_init_irq(~0 & ~(0xf << 5), ~0);
-}
-
-struct sysdev_class s3c6400_sysclass = {
- .name = "s3c6400-core",
-};
-
-static struct sys_device s3c6400_sysdev = {
- .cls = &s3c6400_sysclass,
-};
-
-static int __init s3c6400_core_init(void)
-{
- return sysdev_class_register(&s3c6400_sysclass);
-}
-
-core_initcall(s3c6400_core_init);
-
-int __init s3c6400_init(void)
-{
- printk("S3C6400: Initialising architecture\n");
-
- return sysdev_register(&s3c6400_sysdev);
-}
diff --git a/arch/arm/mach-s3c6400/setup-sdhci.c b/arch/arm/mach-s3c6400/setup-sdhci.c
deleted file mode 100644
index 1039937403b..00000000000
--- a/arch/arm/mach-s3c6400/setup-sdhci.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/setup-sdhci.c
- *
- * Copyright 2008 Simtec Electronics
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
-
-/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
-
-char *s3c6400_hsmmc_clksrcs[4] = {
- [0] = "hsmmc",
- [1] = "hsmmc",
- [2] = "mmc_bus",
- /* [3] = "48m", - note not successfully used yet */
-};
-
-void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
- void __iomem *r,
- struct mmc_ios *ios,
- struct mmc_card *card)
-{
- u32 ctrl2, ctrl3;
-
- ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
- ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
- ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
- S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
- S3C_SDHCI_CTRL2_ENFBCLKRX |
- S3C_SDHCI_CTRL2_DFCNT_NONE |
- S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
- if (ios->clock < 25 * 1000000)
- ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
- S3C_SDHCI_CTRL3_FCSEL2 |
- S3C_SDHCI_CTRL3_FCSEL1 |
- S3C_SDHCI_CTRL3_FCSEL0);
- else
- ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
- printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
- writel(ctrl2, r + S3C_SDHCI_CONTROL2);
- writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
-
diff --git a/arch/arm/mach-s3c6410/Kconfig b/arch/arm/mach-s3c6410/Kconfig
deleted file mode 100644
index 162f4561f80..00000000000
--- a/arch/arm/mach-s3c6410/Kconfig
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-# Configuration options for the S3C6410 CPU
-
-config CPU_S3C6410
- bool
- select CPU_S3C6400_INIT
- select CPU_S3C6400_CLOCK
- help
- Enable S3C6410 CPU support
-
-config S3C6410_SETUP_SDHCI
- bool
- select S3C64XX_SETUP_SDHCI_GPIO
- help
- Internal helper functions for S3C6410 based SDHCI systems
-
-config MACH_ANW6410
- bool "A&W6410"
- select CPU_S3C6410
- select S3C_DEV_FB
- select S3C64XX_SETUP_FB_24BPP
- help
- Machine support for the A&W6410
-
-config MACH_SMDK6410
- bool "SMDK6410"
- select CPU_S3C6410
- select S3C_DEV_HSMMC
- select S3C_DEV_HSMMC1
- select S3C_DEV_I2C1
- select S3C_DEV_FB
- select S3C_DEV_USB_HOST
- select S3C_DEV_USB_HSOTG
- select S3C6410_SETUP_SDHCI
- select S3C64XX_SETUP_I2C1
- select S3C64XX_SETUP_FB_24BPP
- help
- Machine support for the Samsung SMDK6410
-
-# At least some of the SMDK6410s were shipped with the card detect
-# for the MMC/SD slots connected to the same input. This means that
-# either the boards need to be altered to have channel0 to an alternate
-# configuration or that only one slot can be used.
-
-choice
- prompt "SMDK6410 MMC/SD slot setup"
- depends on MACH_SMDK6410
-
-config SMDK6410_SD_CH0
- bool "Use channel 0 only"
- depends on MACH_SMDK6410
- help
- Select CON7 (channel 0) as the MMC/SD slot, as
- at least some SMDK6410 boards come with the
- resistors fitted so that the card detects for
- channels 0 and 1 are the same.
-
-config SMDK6410_SD_CH1
- bool "Use channel 1 only"
- depends on MACH_SMDK6410
- help
- Select CON6 (channel 1) as the MMC/SD slot, as
- at least some SMDK6410 boards come with the
- resistors fitted so that the card detects for
- channels 0 and 1 are the same.
-
-endchoice
-
-config SMDK6410_WM1190_EV1
- bool "Support Wolfson Microelectronics 1190-EV1 PMIC card"
- depends on MACH_SMDK6410
- select REGULATOR
- select REGULATOR_WM8350
- select S3C24XX_GPIO_EXTRA64
- select MFD_WM8350_I2C
- select MFD_WM8350_CONFIG_MODE_0
- select MFD_WM8350_CONFIG_MODE_3
- select MFD_WM8352_CONFIG_MODE_0
- help
- The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
- and audio daughtercard for the Samsung SMDK6410 reference
- platform. Enabling this option will build support for this
- module into the kernel. The presence of the module will be
- detected at runtime so the the resulting kernel can be used
- with or without the 1190-EV1 fitted.
-
-config MACH_NCP
- bool "NCP"
- select CPU_S3C6410
- select S3C_DEV_I2C1
- select S3C_DEV_HSMMC1
- select S3C64XX_SETUP_I2C1
- help
- Machine support for the Samsung NCP
-
-config MACH_HMT
- bool "Airgoo HMT"
- select CPU_S3C6410
- select S3C_DEV_FB
- select S3C_DEV_NAND
- select S3C_DEV_USB_HOST
- select S3C64XX_SETUP_FB_24BPP
- select HAVE_PWM
- help
- Machine support for the Airgoo HMT
diff --git a/arch/arm/mach-s3c6410/Makefile b/arch/arm/mach-s3c6410/Makefile
deleted file mode 100644
index 3e48c3dbf97..00000000000
--- a/arch/arm/mach-s3c6410/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# arch/arm/plat-s3c6410/Makefile
-#
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-
-# Core support for S3C6410 system
-
-obj-$(CONFIG_CPU_S3C6410) += cpu.o
-
-# Helper and device support
-
-obj-$(CONFIG_S3C6410_SETUP_SDHCI) += setup-sdhci.o
-
-# machine support
-
-obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
-obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
-obj-$(CONFIG_MACH_NCP) += mach-ncp.o
-obj-$(CONFIG_MACH_HMT) += mach-hmt.o
diff --git a/arch/arm/mach-s3c6410/cpu.c b/arch/arm/mach-s3c6410/cpu.c
deleted file mode 100644
index 522c0869195..00000000000
--- a/arch/arm/mach-s3c6410/cpu.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/cpu.c
- *
- * Copyright 2008 Simtec Electronics
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/sdhci.h>
-#include <plat/iic-core.h>
-#include <plat/s3c6400.h>
-#include <plat/s3c6410.h>
-
-/* Initial IO mappings */
-
-static struct map_desc s3c6410_iodesc[] __initdata = {
-};
-
-/* s3c6410_map_io
- *
- * register the standard cpu IO areas
-*/
-
-void __init s3c6410_map_io(void)
-{
- iotable_init(s3c6410_iodesc, ARRAY_SIZE(s3c6410_iodesc));
-
- /* initialise device information early */
- s3c6410_default_sdhci0();
- s3c6410_default_sdhci1();
- s3c6410_default_sdhci2();
-
- /* the i2c devices are directly compatible with s3c2440 */
- s3c_i2c0_setname("s3c2440-i2c");
- s3c_i2c1_setname("s3c2440-i2c");
-
- s3c_device_nand.name = "s3c6400-nand";
-}
-
-void __init s3c6410_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
- s3c24xx_register_baseclocks(xtal);
- s3c64xx_register_clocks();
- s3c6400_register_clocks(S3C6410_CLKDIV0_ARM_MASK);
- s3c6400_setup_clocks();
-}
-
-void __init s3c6410_init_irq(void)
-{
- /* VIC0 is missing IRQ7, VIC1 is fully populated. */
- s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
-}
-
-struct sysdev_class s3c6410_sysclass = {
- .name = "s3c6410-core",
-};
-
-static struct sys_device s3c6410_sysdev = {
- .cls = &s3c6410_sysclass,
-};
-
-static int __init s3c6410_core_init(void)
-{
- return sysdev_class_register(&s3c6410_sysclass);
-}
-
-core_initcall(s3c6410_core_init);
-
-int __init s3c6410_init(void)
-{
- printk("S3C6410: Initialising architecture\n");
-
- return sysdev_register(&s3c6410_sysdev);
-}
diff --git a/arch/arm/mach-s3c6410/mach-anw6410.c b/arch/arm/mach-s3c6410/mach-anw6410.c
deleted file mode 100644
index 661cca63de2..00000000000
--- a/arch/arm/mach-s3c6410/mach-anw6410.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/mach-anw6410.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- * Copyright 2009 Kwangwoo Lee
- * Kwangwoo Lee <kwangwoo.lee@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/dm9000.h>
-
-#include <video/platform_lcd.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-#include <plat/fb.h>
-
-#include <plat/s3c6410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/regs-gpio.h>
-#include <plat/regs-modem.h>
-
-/* DM9000 */
-#define ANW6410_PA_DM9000 (0x18000000)
-
-/* A hardware buffer to control external devices is mapped at 0x30000000.
- * It can not be read. So current status must be kept in anw6410_extdev_status.
- */
-#define ANW6410_VA_EXTDEV S3C_ADDR(0x02000000)
-#define ANW6410_PA_EXTDEV (0x30000000)
-
-#define ANW6410_EN_DM9000 (1<<11)
-#define ANW6410_EN_LCD (1<<14)
-
-static __u32 anw6410_extdev_status;
-
-static struct s3c2410_uartcfg anw6410_uartcfgs[] __initdata = {
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = 0x3c5,
- .ulcon = 0x03,
- .ufcon = 0x51,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = 0x3c5,
- .ulcon = 0x03,
- .ufcon = 0x51,
- },
-};
-
-/* framebuffer and LCD setup. */
-static void __init anw6410_lcd_mode_set(void)
-{
- u32 tmp;
-
- /* set the LCD type */
- tmp = __raw_readl(S3C64XX_SPCON);
- tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
- tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
- __raw_writel(tmp, S3C64XX_SPCON);
-
- /* remove the LCD bypass */
- tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
- tmp &= ~MIFPCON_LCD_BYPASS;
- __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
-}
-
-/* GPF1 = LCD panel power
- * GPF4 = LCD backlight control
- */
-static void anw6410_lcd_power_set(struct plat_lcd_data *pd,
- unsigned int power)
-{
- if (power) {
- anw6410_extdev_status |= (ANW6410_EN_LCD << 16);
- __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
-
- gpio_direction_output(S3C64XX_GPF(1), 1);
- gpio_direction_output(S3C64XX_GPF(4), 1);
- } else {
- anw6410_extdev_status &= ~(ANW6410_EN_LCD << 16);
- __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
-
- gpio_direction_output(S3C64XX_GPF(1), 0);
- gpio_direction_output(S3C64XX_GPF(4), 0);
- }
-}
-
-static struct plat_lcd_data anw6410_lcd_power_data = {
- .set_power = anw6410_lcd_power_set,
-};
-
-static struct platform_device anw6410_lcd_powerdev = {
- .name = "platform-lcd",
- .dev.parent = &s3c_device_fb.dev,
- .dev.platform_data = &anw6410_lcd_power_data,
-};
-
-static struct s3c_fb_pd_win anw6410_fb_win0 = {
- /* this is to ensure we use win0 */
- .win_mode = {
- .pixclock = 41094,
- .left_margin = 8,
- .right_margin = 13,
- .upper_margin = 7,
- .lower_margin = 5,
- .hsync_len = 3,
- .vsync_len = 1,
- .xres = 800,
- .yres = 480,
- },
- .max_bpp = 32,
- .default_bpp = 16,
-};
-
-/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
-static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = {
- .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
- .win[0] = &anw6410_fb_win0,
- .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
- .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-};
-
-/* DM9000AEP 10/100 ethernet controller */
-static void __init anw6410_dm9000_enable(void)
-{
- anw6410_extdev_status |= (ANW6410_EN_DM9000 << 16);
- __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
-}
-
-static struct resource anw6410_dm9000_resource[] = {
- [0] = {
- .start = ANW6410_PA_DM9000,
- .end = ANW6410_PA_DM9000 + 3,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = ANW6410_PA_DM9000 + 4,
- .end = ANW6410_PA_DM9000 + 4 + 500,
- .flags = IORESOURCE_MEM,
- },
- [2] = {
- .start = IRQ_EINT(15),
- .end = IRQ_EINT(15),
- .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
- },
-};
-
-static struct dm9000_plat_data anw6410_dm9000_pdata = {
- .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
- /* dev_addr can be set to provide hwaddr. */
-};
-
-static struct platform_device anw6410_device_eth = {
- .name = "dm9000",
- .id = -1,
- .num_resources = ARRAY_SIZE(anw6410_dm9000_resource),
- .resource = anw6410_dm9000_resource,
- .dev = {
- .platform_data = &anw6410_dm9000_pdata,
- },
-};
-
-static struct map_desc anw6410_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)ANW6410_VA_EXTDEV,
- .pfn = __phys_to_pfn(ANW6410_PA_EXTDEV),
- .length = SZ_64K,
- .type = MT_DEVICE,
- },
-};
-
-static struct platform_device *anw6410_devices[] __initdata = {
- &s3c_device_fb,
- &anw6410_lcd_powerdev,
- &anw6410_device_eth,
-};
-
-static void __init anw6410_map_io(void)
-{
- s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
- s3c24xx_init_clocks(12000000);
- s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
-
- anw6410_lcd_mode_set();
-}
-
-static void __init anw6410_machine_init(void)
-{
- s3c_fb_set_platdata(&anw6410_lcd_pdata);
-
- gpio_request(S3C64XX_GPF(1), "panel power");
- gpio_request(S3C64XX_GPF(4), "LCD backlight");
-
- anw6410_dm9000_enable();
-
- platform_add_devices(anw6410_devices, ARRAY_SIZE(anw6410_devices));
-}
-
-MACHINE_START(ANW6410, "A&W6410")
- /* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
- .boot_params = S3C64XX_PA_SDRAM + 0x100,
-
- .init_irq = s3c6410_init_irq,
- .map_io = anw6410_map_io,
- .init_machine = anw6410_machine_init,
- .timer = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c6410/mach-hmt.c b/arch/arm/mach-s3c6410/mach-hmt.c
deleted file mode 100644
index 7619456f2ae..00000000000
--- a/arch/arm/mach-s3c6410/mach-hmt.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/* mach-hmt.c - Platform code for Airgoo HMT
- *
- * Copyright 2009 Peter Korsgaard <jacmet@sunsite.dk>
- *
- * This program is free software; you can 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/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/leds.h>
-#include <linux/pwm_backlight.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-#include <plat/fb.h>
-#include <plat/nand.h>
-
-#include <plat/s3c6410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
-#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
-
-static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [2] = {
- .hwport = 2,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
-};
-
-static int hmt_bl_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable");
- if (!ret)
- ret = gpio_direction_output(S3C64XX_GPB(4), 0);
-
- return ret;
-}
-
-static int hmt_bl_notify(struct device *dev, int brightness)
-{
- /*
- * translate from CIELUV/CIELAB L*->brightness, E.G. from
- * perceived luminance to light output. Assumes range 0..25600
- */
- if (brightness < 0x800) {
- /* Y = Yn * L / 903.3 */
- brightness = (100*256 * brightness + 231245/2) / 231245;
- } else {
- /* Y = Yn * ((L + 16) / 116 )^3 */
- int t = (brightness*4 + 16*1024 + 58)/116;
- brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000);
- }
-
- gpio_set_value(S3C64XX_GPB(4), brightness);
-
- return brightness;
-}
-
-static void hmt_bl_exit(struct device *dev)
-{
- gpio_free(S3C64XX_GPB(4));
-}
-
-static struct platform_pwm_backlight_data hmt_backlight_data = {
- .pwm_id = 1,
- .max_brightness = 100 * 256,
- .dft_brightness = 40 * 256,
- .pwm_period_ns = 1000000000 / (100 * 256 * 20),
- .init = hmt_bl_init,
- .notify = hmt_bl_notify,
- .exit = hmt_bl_exit,
-
-};
-
-static struct platform_device hmt_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[1].dev,
- .platform_data = &hmt_backlight_data,
- },
-};
-
-static struct s3c_fb_pd_win hmt_fb_win0 = {
- .win_mode = {
- .pixclock = 41094,
- .left_margin = 8,
- .right_margin = 13,
- .upper_margin = 7,
- .lower_margin = 5,
- .hsync_len = 3,
- .vsync_len = 1,
- .xres = 800,
- .yres = 480,
- },
- .max_bpp = 32,
- .default_bpp = 16,
-};
-
-/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
-static struct s3c_fb_platdata hmt_lcd_pdata __initdata = {
- .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
- .win[0] = &hmt_fb_win0,
- .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
- .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-};
-
-static struct mtd_partition hmt_nand_part[] = {
- [0] = {
- .name = "uboot",
- .size = SZ_512K,
- .offset = 0,
- },
- [1] = {
- .name = "uboot-env1",
- .size = SZ_256K,
- .offset = SZ_512K,
- },
- [2] = {
- .name = "uboot-env2",
- .size = SZ_256K,
- .offset = SZ_512K + SZ_256K,
- },
- [3] = {
- .name = "kernel",
- .size = SZ_2M,
- .offset = SZ_1M,
- },
- [4] = {
- .name = "rootfs",
- .size = MTDPART_SIZ_FULL,
- .offset = SZ_1M + SZ_2M,
- },
-};
-
-static struct s3c2410_nand_set hmt_nand_sets[] = {
- [0] = {
- .name = "nand",
- .nr_chips = 1,
- .nr_partitions = ARRAY_SIZE(hmt_nand_part),
- .partitions = hmt_nand_part,
- },
-};
-
-static struct s3c2410_platform_nand hmt_nand_info = {
- .tacls = 25,
- .twrph0 = 55,
- .twrph1 = 40,
- .nr_sets = ARRAY_SIZE(hmt_nand_sets),
- .sets = hmt_nand_sets,
-};
-
-static struct gpio_led hmt_leds[] = {
- { /* left function keys */
- .name = "left:blue",
- .gpio = S3C64XX_GPO(12),
- .default_trigger = "default-on",
- },
- { /* right function keys - red */
- .name = "right:red",
- .gpio = S3C64XX_GPO(13),
- },
- { /* right function keys - green */
- .name = "right:green",
- .gpio = S3C64XX_GPO(14),
- },
- { /* right function keys - blue */
- .name = "right:blue",
- .gpio = S3C64XX_GPO(15),
- .default_trigger = "default-on",
- },
-};
-
-static struct gpio_led_platform_data hmt_led_data = {
- .num_leds = ARRAY_SIZE(hmt_leds),
- .leds = hmt_leds,
-};
-
-static struct platform_device hmt_leds_device = {
- .name = "leds-gpio",
- .id = -1,
- .dev.platform_data = &hmt_led_data,
-};
-
-static struct map_desc hmt_iodesc[] = {};
-
-static struct platform_device *hmt_devices[] __initdata = {
- &s3c_device_i2c0,
- &s3c_device_nand,
- &s3c_device_fb,
- &s3c_device_usb,
- &s3c_device_timer[1],
- &hmt_backlight_device,
- &hmt_leds_device,
-};
-
-static void __init hmt_map_io(void)
-{
- s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
- s3c24xx_init_clocks(12000000);
- s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
-}
-
-static void __init hmt_machine_init(void)
-{
- s3c_i2c0_set_platdata(NULL);
- s3c_fb_set_platdata(&hmt_lcd_pdata);
- s3c_nand_set_platdata(&hmt_nand_info);
-
- gpio_request(S3C64XX_GPC(7), "usb power");
- gpio_direction_output(S3C64XX_GPC(7), 0);
- gpio_request(S3C64XX_GPM(0), "usb power");
- gpio_direction_output(S3C64XX_GPM(0), 1);
- gpio_request(S3C64XX_GPK(7), "usb power");
- gpio_direction_output(S3C64XX_GPK(7), 1);
- gpio_request(S3C64XX_GPF(13), "usb power");
- gpio_direction_output(S3C64XX_GPF(13), 1);
-
- platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
-}
-
-MACHINE_START(HMT, "Airgoo-HMT")
- /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
- .boot_params = S3C64XX_PA_SDRAM + 0x100,
- .init_irq = s3c6410_init_irq,
- .map_io = hmt_map_io,
- .init_machine = hmt_machine_init,
- .timer = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c6410/mach-ncp.c b/arch/arm/mach-s3c6410/mach-ncp.c
deleted file mode 100644
index 55e9bbfaf68..00000000000
--- a/arch/arm/mach-s3c6410/mach-ncp.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * linux/arch/arm/mach-s3c6410/mach-ncp.c
- *
- * Copyright (C) 2008-2009 Samsung Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-
-#include <video/platform_lcd.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-#include <plat/fb.h>
-
-#include <plat/s3c6410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg ncp_uartcfgs[] __initdata = {
- /* REVISIT: NCP uses only serial 1, 2 */
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [2] = {
- .hwport = 2,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
-};
-
-static struct platform_device *ncp_devices[] __initdata = {
- &s3c_device_hsmmc1,
- &s3c_device_i2c0,
-};
-
-static struct map_desc ncp_iodesc[] __initdata = {};
-
-static void __init ncp_map_io(void)
-{
- s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
- s3c24xx_init_clocks(12000000);
- s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
-}
-
-static void __init ncp_machine_init(void)
-{
- s3c_i2c0_set_platdata(NULL);
-
- platform_add_devices(ncp_devices, ARRAY_SIZE(ncp_devices));
-}
-
-MACHINE_START(NCP, "NCP")
- /* Maintainer: Samsung Electronics */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
- .boot_params = S3C64XX_PA_SDRAM + 0x100,
- .init_irq = s3c6410_init_irq,
- .map_io = ncp_map_io,
- .init_machine = ncp_machine_init,
- .timer = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c
deleted file mode 100644
index 8969fe73b83..00000000000
--- a/arch/arm/mach-s3c6410/mach-smdk6410.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/mach-smdk6410.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/smsc911x.h>
-#include <linux/regulator/fixed.h>
-
-#ifdef CONFIG_SMDK6410_WM1190_EV1
-#include <linux/mfd/wm8350/core.h>
-#include <linux/mfd/wm8350/pmic.h>
-#endif
-
-#include <video/platform_lcd.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/regs-modem.h>
-#include <plat/regs-gpio.h>
-#include <plat/regs-sys.h>
-#include <plat/iic.h>
-#include <plat/fb.h>
-#include <plat/gpio-cfg.h>
-
-#include <plat/s3c6410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = {
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [2] = {
- .hwport = 2,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
- [3] = {
- .hwport = 3,
- .flags = 0,
- .ucon = UCON,
- .ulcon = ULCON,
- .ufcon = UFCON,
- },
-};
-
-/* framebuffer and LCD setup. */
-
-/* GPF15 = LCD backlight control
- * GPF13 => Panel power
- * GPN5 = LCD nRESET signal
- * PWM_TOUT1 => backlight brightness
- */
-
-static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
- unsigned int power)
-{
- if (power) {
- gpio_direction_output(S3C64XX_GPF(13), 1);
- gpio_direction_output(S3C64XX_GPF(15), 1);
-
- /* fire nRESET on power up */
- gpio_direction_output(S3C64XX_GPN(5), 0);
- msleep(10);
- gpio_direction_output(S3C64XX_GPN(5), 1);
- msleep(1);
- } else {
- gpio_direction_output(S3C64XX_GPF(15), 0);
- gpio_direction_output(S3C64XX_GPF(13), 0);
- }
-}
-
-static struct plat_lcd_data smdk6410_lcd_power_data = {
- .set_power = smdk6410_lcd_power_set,
-};
-
-static struct platform_device smdk6410_lcd_powerdev = {
- .name = "platform-lcd",
- .dev.parent = &s3c_device_fb.dev,
- .dev.platform_data = &smdk6410_lcd_power_data,
-};
-
-static struct s3c_fb_pd_win smdk6410_fb_win0 = {
- /* this is to ensure we use win0 */
- .win_mode = {
- .pixclock = 41094,
- .left_margin = 8,
- .right_margin = 13,
- .upper_margin = 7,
- .lower_margin = 5,
- .hsync_len = 3,
- .vsync_len = 1,
- .xres = 800,
- .yres = 480,
- },
- .max_bpp = 32,
- .default_bpp = 16,
-};
-
-/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
-static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = {
- .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
- .win[0] = &smdk6410_fb_win0,
- .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
- .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-};
-
-static struct resource smdk6410_smsc911x_resources[] = {
- [0] = {
- .start = 0x18000000,
- .end = 0x18000000 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = S3C_EINT(10),
- .end = S3C_EINT(10),
- .flags = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_LOW,
- },
-};
-
-static struct smsc911x_platform_config smdk6410_smsc911x_pdata = {
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
- .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
- .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
- .phy_interface = PHY_INTERFACE_MODE_MII,
-};
-
-
-static struct platform_device smdk6410_smsc911x = {
- .name = "smsc911x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smdk6410_smsc911x_resources),
- .resource = &smdk6410_smsc911x_resources[0],
- .dev = {
- .platform_data = &smdk6410_smsc911x_pdata,
- },
-};
-
-#ifdef CONFIG_REGULATOR
-static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
- {
- /* WM8580 */
- .supply = "PVDD",
- .dev_name = "0-001b",
- },
- {
- /* WM8580 */
- .supply = "AVDD",
- .dev_name = "0-001b",
- },
-};
-
-static struct regulator_init_data smdk6410_b_pwr_5v_data = {
- .constraints = {
- .always_on = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(smdk6410_b_pwr_5v_consumers),
- .consumer_supplies = smdk6410_b_pwr_5v_consumers,
-};
-
-static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = {
- .supply_name = "B_PWR_5V",
- .microvolts = 5000000,
- .init_data = &smdk6410_b_pwr_5v_data,
- .gpio = -EINVAL,
-};
-
-static struct platform_device smdk6410_b_pwr_5v = {
- .name = "reg-fixed-voltage",
- .id = -1,
- .dev = {
- .platform_data = &smdk6410_b_pwr_5v_pdata,
- },
-};
-#endif
-
-static struct map_desc smdk6410_iodesc[] = {};
-
-static struct platform_device *smdk6410_devices[] __initdata = {
-#ifdef CONFIG_SMDK6410_SD_CH0
- &s3c_device_hsmmc0,
-#endif
-#ifdef CONFIG_SMDK6410_SD_CH1
- &s3c_device_hsmmc1,
-#endif
- &s3c_device_i2c0,
- &s3c_device_i2c1,
- &s3c_device_fb,
- &s3c_device_usb,
- &s3c_device_usb_hsotg,
-
-#ifdef CONFIG_REGULATOR
- &smdk6410_b_pwr_5v,
-#endif
- &smdk6410_lcd_powerdev,
-
- &smdk6410_smsc911x,
-};
-
-#ifdef CONFIG_SMDK6410_WM1190_EV1
-/* S3C64xx internal logic & PLL */
-static struct regulator_init_data wm8350_dcdc1_data = {
- .constraints = {
- .name = "PVDD_INT/PVDD_PLL",
- .min_uV = 1200000,
- .max_uV = 1200000,
- .always_on = 1,
- .apply_uV = 1,
- },
-};
-
-/* Memory */
-static struct regulator_init_data wm8350_dcdc3_data = {
- .constraints = {
- .name = "PVDD_MEM",
- .min_uV = 1800000,
- .max_uV = 1800000,
- .always_on = 1,
- .state_mem = {
- .uV = 1800000,
- .mode = REGULATOR_MODE_NORMAL,
- .enabled = 1,
- },
- .initial_state = PM_SUSPEND_MEM,
- },
-};
-
-/* USB, EXT, PCM, ADC/DAC, USB, MMC */
-static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
- {
- /* WM8580 */
- .supply = "DVDD",
- .dev_name = "0-001b",
- },
-};
-
-static struct regulator_init_data wm8350_dcdc4_data = {
- .constraints = {
- .name = "PVDD_HI/PVDD_EXT/PVDD_SYS/PVCCM2MTV",
- .min_uV = 3000000,
- .max_uV = 3000000,
- .always_on = 1,
- },
- .num_consumer_supplies = ARRAY_SIZE(wm8350_dcdc4_consumers),
- .consumer_supplies = wm8350_dcdc4_consumers,
-};
-
-/* ARM core */
-static struct regulator_consumer_supply dcdc6_consumers[] = {
- {
- .supply = "vddarm",
- }
-};
-
-static struct regulator_init_data wm8350_dcdc6_data = {
- .constraints = {
- .name = "PVDD_ARM",
- .min_uV = 1000000,
- .max_uV = 1300000,
- .always_on = 1,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
- },
- .num_consumer_supplies = ARRAY_SIZE(dcdc6_consumers),
- .consumer_supplies = dcdc6_consumers,
-};
-
-/* Alive */
-static struct regulator_init_data wm8350_ldo1_data = {
- .constraints = {
- .name = "PVDD_ALIVE",
- .min_uV = 1200000,
- .max_uV = 1200000,
- .always_on = 1,
- .apply_uV = 1,
- },
-};
-
-/* OTG */
-static struct regulator_init_data wm8350_ldo2_data = {
- .constraints = {
- .name = "PVDD_OTG",
- .min_uV = 3300000,
- .max_uV = 3300000,
- .always_on = 1,
- },
-};
-
-/* LCD */
-static struct regulator_init_data wm8350_ldo3_data = {
- .constraints = {
- .name = "PVDD_LCD",
- .min_uV = 3000000,
- .max_uV = 3000000,
- .always_on = 1,
- },
-};
-
-/* OTGi/1190-EV1 HPVDD & AVDD */
-static struct regulator_init_data wm8350_ldo4_data = {
- .constraints = {
- .name = "PVDD_OTGI/HPVDD/AVDD",
- .min_uV = 1200000,
- .max_uV = 1200000,
- .apply_uV = 1,
- .always_on = 1,
- },
-};
-
-static struct {
- int regulator;
- struct regulator_init_data *initdata;
-} wm1190_regulators[] = {
- { WM8350_DCDC_1, &wm8350_dcdc1_data },
- { WM8350_DCDC_3, &wm8350_dcdc3_data },
- { WM8350_DCDC_4, &wm8350_dcdc4_data },
- { WM8350_DCDC_6, &wm8350_dcdc6_data },
- { WM8350_LDO_1, &wm8350_ldo1_data },
- { WM8350_LDO_2, &wm8350_ldo2_data },
- { WM8350_LDO_3, &wm8350_ldo3_data },
- { WM8350_LDO_4, &wm8350_ldo4_data },
-};
-
-static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
-{
- int i;
-
- /* Configure the IRQ line */
- s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
-
- /* Instantiate the regulators */
- for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
- wm8350_register_regulator(wm8350,
- wm1190_regulators[i].regulator,
- wm1190_regulators[i].initdata);
-
- return 0;
-}
-
-static struct wm8350_platform_data __initdata smdk6410_wm8350_pdata = {
- .init = smdk6410_wm8350_init,
- .irq_high = 1,
-};
-#endif
-
-static struct i2c_board_info i2c_devs0[] __initdata = {
- { I2C_BOARD_INFO("24c08", 0x50), },
- { I2C_BOARD_INFO("wm8580", 0x1b), },
-
-#ifdef CONFIG_SMDK6410_WM1190_EV1
- { I2C_BOARD_INFO("wm8350", 0x1a),
- .platform_data = &smdk6410_wm8350_pdata,
- .irq = S3C_EINT(12),
- },
-#endif
-};
-
-static struct i2c_board_info i2c_devs1[] __initdata = {
- { I2C_BOARD_INFO("24c128", 0x57), }, /* Samsung S524AD0XD1 */
-};
-
-static void __init smdk6410_map_io(void)
-{
- u32 tmp;
-
- s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
- s3c24xx_init_clocks(12000000);
- s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
-
- /* set the LCD type */
-
- tmp = __raw_readl(S3C64XX_SPCON);
- tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
- tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
- __raw_writel(tmp, S3C64XX_SPCON);
-
- /* remove the lcd bypass */
- tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
- tmp &= ~MIFPCON_LCD_BYPASS;
- __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
-}
-
-static void __init smdk6410_machine_init(void)
-{
- s3c_i2c0_set_platdata(NULL);
- s3c_i2c1_set_platdata(NULL);
- s3c_fb_set_platdata(&smdk6410_lcd_pdata);
-
- gpio_request(S3C64XX_GPN(5), "LCD power");
- gpio_request(S3C64XX_GPF(13), "LCD power");
- gpio_request(S3C64XX_GPF(15), "LCD power");
-
- i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
- i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
-
- platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
-}
-
-MACHINE_START(SMDK6410, "SMDK6410")
- /* Maintainer: Ben Dooks <ben@fluff.org> */
- .phys_io = S3C_PA_UART & 0xfff00000,
- .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
- .boot_params = S3C64XX_PA_SDRAM + 0x100,
-
- .init_irq = s3c6410_init_irq,
- .map_io = smdk6410_map_io,
- .init_machine = smdk6410_machine_init,
- .timer = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c6410/setup-sdhci.c b/arch/arm/mach-s3c6410/setup-sdhci.c
deleted file mode 100644
index 816d2d9f9ef..00000000000
--- a/arch/arm/mach-s3c6410/setup-sdhci.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* linux/arch/arm/mach-s3c6410/setup-sdhci.c
- *
- * Copyright 2008 Simtec Electronics
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
-
-/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
-
-char *s3c6410_hsmmc_clksrcs[4] = {
- [0] = "hsmmc",
- [1] = "hsmmc",
- [2] = "mmc_bus",
- /* [3] = "48m", - note not successfully used yet */
-};
-
-
-void s3c6410_setup_sdhci0_cfg_card(struct platform_device *dev,
- void __iomem *r,
- struct mmc_ios *ios,
- struct mmc_card *card)
-{
- u32 ctrl2, ctrl3;
-
- /* don't need to alter anything acording to card-type */
-
- writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
-
- ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
- ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
- ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
- S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
- S3C_SDHCI_CTRL2_ENFBCLKRX |
- S3C_SDHCI_CTRL2_DFCNT_NONE |
- S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
- if (ios->clock < 25 * 1000000)
- ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
- S3C_SDHCI_CTRL3_FCSEL2 |
- S3C_SDHCI_CTRL3_FCSEL1 |
- S3C_SDHCI_CTRL3_FCSEL0);
- else
- ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
- printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
- writel(ctrl2, r + S3C_SDHCI_CONTROL2);
- writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
-
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
new file mode 100644
index 00000000000..959df3840de
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -0,0 +1,180 @@
+# Copyright 2008 Openmoko, Inc.
+# Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
+#
+# Licensed under GPLv2
+
+# temporary until we can eliminate all drivers using it.
+config PLAT_S3C64XX
+ bool
+ depends on ARCH_S3C64XX
+ default y
+ help
+ Base platform code for any Samsung S3C64XX device
+
+
+# Configuration options for the S3C6410 CPU
+
+config CPU_S3C6400
+ bool
+ help
+ Enable S3C6400 CPU support
+
+config CPU_S3C6410
+ bool
+ help
+ Enable S3C6410 CPU support
+
+config S3C64XX_DMA
+ bool "S3C64XX DMA"
+ select S3C_DMA
+
+config S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_SDHCI_GPIO
+ bool
+ help
+ Internal configuration for default SDHCI setup for S3C6400 and
+ S3C6410 SoCs.
+
+# platform specific device setup
+
+config S3C64XX_SETUP_I2C0
+ bool
+ default y
+ help
+ Common setup code for i2c bus 0.
+
+ Note, currently since i2c0 is always compiled, this setup helper
+ is always compiled with it.
+
+config S3C64XX_SETUP_I2C1
+ bool
+ help
+ Common setup code for i2c bus 1.
+
+config S3C64XX_SETUP_FB_24BPP
+ bool
+ help
+ Common setup code for S3C64XX with an 24bpp RGB display helper.
+
+config S3C64XX_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for S3C64XX SDHCI GPIO configurations
+
+# S36400 Macchine support
+
+config MACH_SMDK6400
+ bool "SMDK6400"
+ select CPU_S3C6400
+ select S3C_DEV_HSMMC
+ select S3C_DEV_NAND
+ select S3C64XX_SETUP_SDHCI
+ help
+ Machine support for the Samsung SMDK6400
+
+# S3C6410 machine support
+
+config MACH_ANW6410
+ bool "A&W6410"
+ select CPU_S3C6410
+ select S3C_DEV_FB
+ select S3C64XX_SETUP_FB_24BPP
+ help
+ Machine support for the A&W6410
+
+config MACH_SMDK6410
+ bool "SMDK6410"
+ select CPU_S3C6410
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_I2C1
+ select S3C_DEV_FB
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_I2C1
+ select S3C64XX_SETUP_FB_24BPP
+ help
+ Machine support for the Samsung SMDK6410
+
+# At least some of the SMDK6410s were shipped with the card detect
+# for the MMC/SD slots connected to the same input. This means that
+# either the boards need to be altered to have channel0 to an alternate
+# configuration or that only one slot can be used.
+
+choice
+ prompt "SMDK6410 MMC/SD slot setup"
+ depends on MACH_SMDK6410
+
+config SMDK6410_SD_CH0
+ bool "Use channel 0 only"
+ depends on MACH_SMDK6410
+ help
+ Select CON7 (channel 0) as the MMC/SD slot, as
+ at least some SMDK6410 boards come with the
+ resistors fitted so that the card detects for
+ channels 0 and 1 are the same.
+
+config SMDK6410_SD_CH1
+ bool "Use channel 1 only"
+ depends on MACH_SMDK6410
+ help
+ Select CON6 (channel 1) as the MMC/SD slot, as
+ at least some SMDK6410 boards come with the
+ resistors fitted so that the card detects for
+ channels 0 and 1 are the same.
+
+endchoice
+
+config SMDK6410_WM1190_EV1
+ bool "Support Wolfson Microelectronics 1190-EV1 PMIC card"
+ depends on MACH_SMDK6410
+ select REGULATOR
+ select REGULATOR_WM8350
+ select S3C24XX_GPIO_EXTRA64
+ select MFD_WM8350_I2C
+ select MFD_WM8350_CONFIG_MODE_0
+ select MFD_WM8350_CONFIG_MODE_3
+ select MFD_WM8352_CONFIG_MODE_0
+ help
+ The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
+ and audio daughtercard for the Samsung SMDK6410 reference
+ platform. Enabling this option will build support for this
+ module into the kernel. The presence of the module will be
+ detected at runtime so the the resulting kernel can be used
+ with or without the 1190-EV1 fitted.
+
+config SMDK6410_WM1192_EV1
+ bool "Support Wolfson Microelectronics 1192-EV1 PMIC card"
+ depends on MACH_SMDK6410
+ select REGULATOR
+ select REGULATOR_WM831X
+ select S3C24XX_GPIO_EXTRA64
+ select MFD_WM831X
+ help
+ The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
+ daughtercard for the Samsung SMDK6410 reference platform.
+ Enabling this option will build support for this module into
+ the kernel. The presence of the daughtercard will be
+ detected at runtime so the the resulting kernel can be used
+ with or without the 1192-EV1 fitted.
+
+config MACH_NCP
+ bool "NCP"
+ select CPU_S3C6410
+ select S3C_DEV_I2C1
+ select S3C_DEV_HSMMC1
+ select S3C64XX_SETUP_I2C1
+ help
+ Machine support for the Samsung NCP
+
+config MACH_HMT
+ bool "Airgoo HMT"
+ select CPU_S3C6410
+ select S3C_DEV_FB
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select S3C64XX_SETUP_FB_24BPP
+ select HAVE_PWM
+ help
+ Machine support for the Airgoo HMT
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
new file mode 100644
index 00000000000..3758e15086b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -0,0 +1,62 @@
+# arch/arm/mach-s3c64xx/Makefile
+#
+# Copyright 2008 Openmoko, Inc.
+# Copyright 2008 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core files
+obj-y += cpu.o
+obj-y += clock.o
+obj-y += gpiolib.o
+
+# Core support for S3C6400 system
+
+obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
+obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
+
+obj-y += irq.o
+obj-y += irq-eint.o
+
+# CPU frequency scaling
+
+obj-$(CONFIG_CPU_FREQ_S3C64XX) += cpufreq.o
+
+# DMA support
+
+obj-$(CONFIG_S3C64XX_DMA) += dma.o
+
+# Device setup
+
+obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
+obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.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
+
+# PM
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += sleep.o
+obj-$(CONFIG_PM) += irq-pm.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
+obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
+obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
+obj-$(CONFIG_MACH_NCP) += mach-ncp.o
+obj-$(CONFIG_MACH_HMT) += mach-hmt.o
+
+# device support
+
+obj-y += dev-uart.o
+obj-y += dev-rtc.o
+obj-y += dev-audio.o
+obj-$(CONFIG_S3C_ADC) += dev-adc.o
+obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
diff --git a/arch/arm/mach-s3c6400/Makefile.boot b/arch/arm/mach-s3c64xx/Makefile.boot
index ba41fdc0a58..ba41fdc0a58 100644
--- a/arch/arm/mach-s3c6400/Makefile.boot
+++ b/arch/arm/mach-s3c64xx/Makefile.boot
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
new file mode 100644
index 00000000000..2ac2e7d73e5
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -0,0 +1,809 @@
+/* linux/arch/arm/plat-s3c64xx/clock.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX Base clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-sys.h>
+#include <mach/regs-clock.h>
+#include <mach/pll.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+
+/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
+ * ext_xtal_mux for want of an actual name from the manual.
+*/
+
+static struct clk clk_ext_xtal_mux = {
+ .name = "ext_xtal",
+ .id = -1,
+};
+
+#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_mpll clk_ext_xtal_mux
+#define clk_fin_epll clk_ext_xtal_mux
+
+#define clk_fout_mpll clk_mpll
+#define clk_fout_epll clk_epll
+
+struct clk clk_h2 = {
+ .name = "hclk2",
+ .id = -1,
+ .rate = 0,
+};
+
+struct clk clk_27m = {
+ .name = "clk_27m",
+ .id = -1,
+ .rate = 27000000,
+};
+
+static int clk_48m_ctrl(struct clk *clk, int enable)
+{
+ unsigned long flags;
+ u32 val;
+
+ /* can't rely on clock lock, this register has other usages */
+ local_irq_save(flags);
+
+ val = __raw_readl(S3C64XX_OTHERS);
+ if (enable)
+ val |= S3C64XX_OTHERS_USBMASK;
+ else
+ val &= ~S3C64XX_OTHERS_USBMASK;
+
+ __raw_writel(val, S3C64XX_OTHERS);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+struct clk clk_48m = {
+ .name = "clk_48m",
+ .id = -1,
+ .rate = 48000000,
+ .enable = clk_48m_ctrl,
+};
+
+static int inline s3c64xx_gate(void __iomem *reg,
+ struct clk *clk,
+ int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ u32 con;
+
+ con = __raw_readl(reg);
+
+ if (enable)
+ con |= ctrlbit;
+ else
+ con &= ~ctrlbit;
+
+ __raw_writel(con, reg);
+ return 0;
+}
+
+static int s3c64xx_pclk_ctrl(struct clk *clk, int enable)
+{
+ return s3c64xx_gate(S3C_PCLK_GATE, clk, enable);
+}
+
+static int s3c64xx_hclk_ctrl(struct clk *clk, int enable)
+{
+ return s3c64xx_gate(S3C_HCLK_GATE, clk, enable);
+}
+
+int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
+{
+ return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
+}
+
+static struct clk init_clocks_disable[] = {
+ {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_h,
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_TSADC,
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_IIC,
+ }, {
+ .name = "iis",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_IIS0,
+ }, {
+ .name = "iis",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_IIS1,
+ }, {
+#ifdef CONFIG_CPU_S3C6410
+ .name = "iis",
+ .id = -1, /* There's only one IISv4 port */
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C6410_CLKCON_PCLK_IIS2,
+ }, {
+#endif
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_SPI0,
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_SPI1,
+ }, {
+ .name = "spi_48m",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_SPI0_48,
+ }, {
+ .name = "spi_48m",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_SPI1_48,
+ }, {
+ .name = "48m",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC0_48,
+ }, {
+ .name = "48m",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC1_48,
+ }, {
+ .name = "48m",
+ .id = 2,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC2_48,
+ }, {
+ .name = "dma0",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_DMA0,
+ }, {
+ .name = "dma1",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_DMA1,
+ },
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_LCD,
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_GPIO,
+ }, {
+ .name = "usb-host",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_UHOST,
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_PWM,
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_UART0,
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_UART1,
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_UART2,
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_UART3,
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_RTC,
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = S3C_CLKCON_PCLK_WDT,
+ }, {
+ .name = "ac97",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = S3C_CLKCON_PCLK_AC97,
+ }
+};
+
+
+static struct clk clk_fout_apll = {
+ .name = "fout_apll",
+ .id = -1,
+};
+
+static struct clk *clk_src_apll_list[] = {
+ [0] = &clk_fin_apll,
+ [1] = &clk_fout_apll,
+};
+
+static struct clksrc_sources clk_src_apll = {
+ .sources = clk_src_apll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_apll_list),
+};
+
+static struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 0, .size = 1 },
+ .sources = &clk_src_apll,
+};
+
+static struct clk *clk_src_epll_list[] = {
+ [0] = &clk_fin_epll,
+ [1] = &clk_fout_epll,
+};
+
+static struct clksrc_sources clk_src_epll = {
+ .sources = clk_src_epll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_epll_list),
+};
+
+static struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 2, .size = 1 },
+ .sources = &clk_src_epll,
+};
+
+static struct clk *clk_src_mpll_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &clk_fout_mpll,
+};
+
+static struct clksrc_sources clk_src_mpll = {
+ .sources = clk_src_mpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 1, .size = 1 },
+ .sources = &clk_src_mpll,
+};
+
+static unsigned int armclk_mask;
+
+static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 clkdiv;
+
+ /* divisor mask starts at bit0, so no need to shift */
+ clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask;
+
+ return rate / (clkdiv + 1);
+}
+
+static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ u32 div;
+
+ if (parent < rate)
+ return parent;
+
+ div = (parent / rate) - 1;
+ if (div > armclk_mask)
+ div = armclk_mask;
+
+ return parent / (div + 1);
+}
+
+static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ u32 div;
+ u32 val;
+
+ if (rate < parent / (armclk_mask + 1))
+ return -EINVAL;
+
+ rate = clk_round_rate(clk, rate);
+ div = clk_get_rate(clk->parent) / rate;
+
+ val = __raw_readl(S3C_CLK_DIV0);
+ val &= ~armclk_mask;
+ val |= (div - 1);
+ __raw_writel(val, S3C_CLK_DIV0);
+
+ return 0;
+
+}
+
+static struct clk clk_arm = {
+ .name = "armclk",
+ .id = -1,
+ .parent = &clk_mout_apll.clk,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c64xx_clk_arm_get_rate,
+ .set_rate = s3c64xx_clk_arm_set_rate,
+ .round_rate = s3c64xx_clk_arm_round_rate,
+ },
+};
+
+static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+
+ printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+ if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK)
+ rate /= 2;
+
+ return rate;
+}
+
+static struct clk_ops clk_dout_ops = {
+ .get_rate = s3c64xx_clk_doutmpll_get_rate,
+};
+
+static struct clk clk_dout_mpll = {
+ .name = "dout_mpll",
+ .id = -1,
+ .parent = &clk_mout_mpll.clk,
+ .ops = &clk_dout_ops,
+};
+
+static struct clk *clkset_spi_mmc_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ &clk_fin_epll,
+ &clk_27m,
+};
+
+static struct clksrc_sources clkset_spi_mmc = {
+ .sources = clkset_spi_mmc_list,
+ .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list),
+};
+
+static struct clk *clkset_irda_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ NULL,
+ &clk_27m,
+};
+
+static struct clksrc_sources clkset_irda = {
+ .sources = clkset_irda_list,
+ .nr_sources = ARRAY_SIZE(clkset_irda_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ NULL,
+ NULL
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_uhost_list[] = {
+ &clk_48m,
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ &clk_fin_epll,
+};
+
+static struct clksrc_sources clkset_uhost = {
+ .sources = clkset_uhost_list,
+ .nr_sources = ARRAY_SIZE(clkset_uhost_list),
+};
+
+/* The peripheral clocks are all controlled via clocksource followed
+ * by an optional divider and gate stage. We currently roll this into
+ * one clock which hides the intermediate clock from the mux.
+ *
+ * Note, the JPEG clock can only be an even divider...
+ *
+ * The scaler and LCD clocks depend on the S3C64XX version, and also
+ * have a common parent divisor so are not included here.
+ */
+
+/* clocks that feed other parts of the clock source tree */
+
+static struct clk clk_iis_cd0 = {
+ .name = "iis_cdclk0",
+ .id = -1,
+};
+
+static struct clk clk_iis_cd1 = {
+ .name = "iis_cdclk1",
+ .id = -1,
+};
+
+static struct clk clk_pcm_cd = {
+ .name = "pcm_cdclk",
+ .id = -1,
+};
+
+static struct clk *clkset_audio0_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_dout_mpll,
+ [2] = &clk_fin_epll,
+ [3] = &clk_iis_cd0,
+ [4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio0 = {
+ .sources = clkset_audio0_list,
+ .nr_sources = ARRAY_SIZE(clkset_audio0_list),
+};
+
+static struct clk *clkset_audio1_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_dout_mpll,
+ [2] = &clk_fin_epll,
+ [3] = &clk_iis_cd1,
+ [4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio1 = {
+ .sources = clkset_audio1_list,
+ .nr_sources = ARRAY_SIZE(clkset_audio1_list),
+};
+
+static struct clk *clkset_camif_list[] = {
+ &clk_h2,
+};
+
+static struct clksrc_sources clkset_camif = {
+ .sources = clkset_camif_list,
+ .nr_sources = ARRAY_SIZE(clkset_camif_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 0,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC0,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 1,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC1,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 2,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC2,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "usb-bus-host",
+ .id = -1,
+ .ctrlbit = S3C_CLKCON_SCLK_UHOST,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 5, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 },
+ .sources = &clkset_uhost,
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = S3C_CLKCON_SCLK_UART,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
+ .sources = &clkset_uart,
+ }, {
+/* Where does UCLK0 come from? */
+ .clk = {
+ .name = "spi-bus",
+ .id = 0,
+ .ctrlbit = S3C_CLKCON_SCLK_SPI0,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "spi-bus",
+ .id = 1,
+ .ctrlbit = S3C_CLKCON_SCLK_SPI1,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "audio-bus",
+ .id = 0,
+ .ctrlbit = S3C_CLKCON_SCLK_AUDIO0,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 7, .size = 3 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4 },
+ .sources = &clkset_audio0,
+ }, {
+ .clk = {
+ .name = "audio-bus",
+ .id = 1,
+ .ctrlbit = S3C_CLKCON_SCLK_AUDIO1,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4 },
+ .sources = &clkset_audio1,
+ }, {
+ .clk = {
+ .name = "irda-bus",
+ .id = 0,
+ .ctrlbit = S3C_CLKCON_SCLK_IRDA,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 24, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4 },
+ .sources = &clkset_irda,
+ }, {
+ .clk = {
+ .name = "camera",
+ .id = -1,
+ .ctrlbit = S3C_CLKCON_SCLK_CAM,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_div = { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4 },
+ .reg_src = { .reg = NULL, .shift = 0, .size = 0 },
+ .sources = &clkset_camif,
+ },
+};
+
+/* Clock initialisation code */
+
+static struct clksrc_clk *init_parents[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_mout_mpll,
+};
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+void __init_or_cpufreq s3c6400_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long hclk2;
+ unsigned long pclk;
+ unsigned long epll;
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned int ptr;
+ u32 clkdiv0;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ clkdiv0 = __raw_readl(S3C_CLK_DIV0);
+ printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0);
+
+ xtal_clk = clk_get(NULL, "xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+ /* For now assume the mux always selects the crystal */
+ clk_ext_xtal_mux.parent = xtal_clk;
+
+ epll = s3c6400_get_epll(xtal);
+ mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
+ apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
+
+ fclk = mpll;
+
+ printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
+ apll, mpll, epll);
+
+ hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
+ hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
+ pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
+
+ printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n",
+ hclk2, hclk, pclk);
+
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_fout_apll.rate = apll;
+
+ clk_h2.rate = hclk2;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+ clk_f.rate = fclk;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+ s3c_set_clksrc(init_parents[ptr], true);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks1[] __initdata = {
+ &clk_ext_xtal_mux,
+ &clk_iis_cd0,
+ &clk_iis_cd1,
+ &clk_pcm_cd,
+ &clk_mout_epll.clk,
+ &clk_mout_mpll.clk,
+ &clk_dout_mpll,
+ &clk_arm,
+};
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_epll,
+ &clk_27m,
+ &clk_48m,
+ &clk_h2,
+};
+
+/**
+ * s3c64xx_register_clocks - register clocks for s3c6400 and s3c6410
+ * @xtal: The rate for the clock crystal feeding the PLLs.
+ * @armclk_divlimit: Divisor mask for ARMCLK.
+ *
+ * Register the clocks for the S3C6400 and S3C6410 SoC range, such
+ * as ARMCLK as well as the necessary parent clocks.
+ *
+ * This call does not setup the clocks, which is left to the
+ * s3c6400_setup_clocks() call which may be needed by the cpufreq
+ * or resume code to re-set the clocks if the bootloader has changed
+ * them.
+ */
+void __init s3c64xx_register_clocks(unsigned long xtal,
+ unsigned armclk_divlimit)
+{
+ struct clk *clkp;
+ int ret;
+ int ptr;
+
+ armclk_mask = armclk_divlimit;
+
+ s3c24xx_register_baseclocks(xtal);
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ clkp = init_clocks_disable;
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+
+ (clkp->enable)(clkp, 0);
+ }
+
+ s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s3c64xx/cpu.c b/arch/arm/mach-s3c64xx/cpu.c
new file mode 100644
index 00000000000..374e45e566b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/cpu.c
@@ -0,0 +1,167 @@
+/* linux/arch/arm/plat-s3c64xx/cpu.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU Support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/regs-serial.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+#include <mach/s3c6400.h>
+#include <mach/s3c6410.h>
+
+/* table of supported CPUs */
+
+static const char name_s3c6400[] = "S3C6400";
+static const char name_s3c6410[] = "S3C6410";
+
+static struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = 0x36400000,
+ .idmask = 0xfffff000,
+ .map_io = s3c6400_map_io,
+ .init_clocks = s3c6400_init_clocks,
+ .init_uarts = s3c6400_init_uarts,
+ .init = s3c6400_init,
+ .name = name_s3c6400,
+ }, {
+ .idcode = 0x36410100,
+ .idmask = 0xffffff00,
+ .map_io = s3c6410_map_io,
+ .init_clocks = s3c6410_init_clocks,
+ .init_uarts = s3c6410_init_uarts,
+ .init = s3c6410_init,
+ .name = name_s3c6410,
+ },
+};
+
+/* minimal IO mapping */
+
+/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */
+#define UART_OFFS (S3C_PA_UART & 0xfffff)
+
+static struct map_desc s3c_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_MEM,
+ .pfn = __phys_to_pfn(S3C64XX_PA_SROM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS),
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S3C64XX_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S3C64XX_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_TIMER,
+ .pfn = __phys_to_pfn(S3C_PA_TIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C64XX_VA_GPIO,
+ .pfn = __phys_to_pfn(S3C64XX_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C64XX_VA_MODEM,
+ .pfn = __phys_to_pfn(S3C64XX_PA_MODEM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_WATCHDOG,
+ .pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_USB_HSPHY,
+ .pfn = __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
+ .length = SZ_1K,
+ .type = MT_DEVICE,
+ },
+};
+
+
+struct sysdev_class s3c64xx_sysclass = {
+ .name = "s3c64xx-core",
+};
+
+static struct sys_device s3c64xx_sysdev = {
+ .cls = &s3c64xx_sysclass,
+};
+
+/* uart registration process */
+
+void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
+}
+
+/* read cpu identification code */
+
+void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
+{
+ unsigned long idcode;
+
+ /* initialise the io descriptors we need for initialisation */
+ iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
+ iotable_init(mach_desc, size);
+
+ idcode = __raw_readl(S3C_VA_SYS + 0x118);
+ if (!idcode) {
+ /* S3C6400 has the ID register in a different place,
+ * and needs a write before it can be read. */
+
+ __raw_writel(0x0, S3C_VA_SYS + 0xA1C);
+ idcode = __raw_readl(S3C_VA_SYS + 0xA1C);
+ }
+
+ s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+}
+
+static __init int s3c64xx_sysdev_init(void)
+{
+ sysdev_class_register(&s3c64xx_sysclass);
+ return sysdev_register(&s3c64xx_sysdev);
+}
+
+core_initcall(s3c64xx_sysdev_init);
diff --git a/arch/arm/plat-s3c64xx/cpufreq.c b/arch/arm/mach-s3c64xx/cpufreq.c
index 74c0e8347de..74c0e8347de 100644
--- a/arch/arm/plat-s3c64xx/cpufreq.c
+++ b/arch/arm/mach-s3c64xx/cpufreq.c
diff --git a/arch/arm/mach-s3c64xx/dev-adc.c b/arch/arm/mach-s3c64xx/dev-adc.c
new file mode 100644
index 00000000000..fafef9b6bcf
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-adc.c
@@ -0,0 +1,46 @@
+/* linux/arch/arm/plat-s3c64xx/dev-adc.c
+ *
+ * Copyright 2010 Maurus Cuelenaere
+ *
+ * S3C64xx series device definition for ADC device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/adc.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_adc_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_ADC,
+ .end = S3C64XX_PA_ADC + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC,
+ .end = IRQ_TC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_ADC,
+ .end = IRQ_ADC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_adc = {
+ .name = "s3c64xx-adc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_adc_resource),
+ .resource = s3c_adc_resource,
+};
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
new file mode 100644
index 00000000000..c3e9e73bd0f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -0,0 +1,335 @@
+/* linux/arch/arm/plat-s3c/dev-audio.c
+ *
+ * Copyright 2009 Wolfson Microelectronics
+ * Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/gpio.h>
+
+#include <plat/devs.h>
+#include <plat/audio.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/gpio-bank-c.h>
+#include <mach/gpio-bank-d.h>
+#include <mach/gpio-bank-e.h>
+#include <mach/gpio-bank-h.h>
+
+static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
+ s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI);
+ s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0);
+ break;
+ case 1:
+ s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK);
+ s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI);
+ s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0);
+ default:
+ printk(KERN_DEBUG "Invalid I2S Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0);
+ s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1);
+ s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2);
+ s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI);
+
+ return 0;
+}
+
+static struct resource s3c64xx_iis0_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_IIS0,
+ .end = S3C64XX_PA_IIS0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S0_OUT,
+ .end = DMACH_I2S0_OUT,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S0_IN,
+ .end = DMACH_I2S0_IN,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata s3c_i2s0_pdata = {
+ .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_iis0 = {
+ .name = "s3c64xx-iis",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
+ .resource = s3c64xx_iis0_resource,
+ .dev = {
+ .platform_data = &s3c_i2s0_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iis0);
+
+static struct resource s3c64xx_iis1_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_IIS1,
+ .end = S3C64XX_PA_IIS1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S1_OUT,
+ .end = DMACH_I2S1_OUT,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S1_IN,
+ .end = DMACH_I2S1_IN,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata s3c_i2s1_pdata = {
+ .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_iis1 = {
+ .name = "s3c64xx-iis",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
+ .resource = s3c64xx_iis1_resource,
+ .dev = {
+ .platform_data = &s3c_i2s1_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iis1);
+
+static struct resource s3c64xx_iisv4_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_IISV4,
+ .end = S3C64XX_PA_IISV4 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_HSI_I2SV40_TX,
+ .end = DMACH_HSI_I2SV40_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_HSI_I2SV40_RX,
+ .end = DMACH_HSI_I2SV40_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata s3c_i2sv4_pdata = {
+ .cfg_gpio = s3c64xx_i2sv4_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_iisv4 = {
+ .name = "s3c64xx-iis-v4",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
+ .resource = s3c64xx_iisv4_resource,
+ .dev = {
+ .platform_data = &s3c_i2sv4_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iisv4);
+
+
+/* PCM Controller platform_devices */
+
+static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
+ s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
+ s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
+ break;
+ case 1:
+ s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
+ s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
+ s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
+ break;
+ default:
+ printk(KERN_DEBUG "Invalid PCM Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct resource s3c64xx_pcm0_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_PCM0,
+ .end = S3C64XX_PA_PCM0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM0_TX,
+ .end = DMACH_PCM0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM0_RX,
+ .end = DMACH_PCM0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata s3c_pcm0_pdata = {
+ .cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm0 = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_pcm0_resource),
+ .resource = s3c64xx_pcm0_resource,
+ .dev = {
+ .platform_data = &s3c_pcm0_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm0);
+
+static struct resource s3c64xx_pcm1_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_PCM1,
+ .end = S3C64XX_PA_PCM1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM1_TX,
+ .end = DMACH_PCM1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM1_RX,
+ .end = DMACH_PCM1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata s3c_pcm1_pdata = {
+ .cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm1 = {
+ .name = "samsung-pcm",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_pcm1_resource),
+ .resource = s3c64xx_pcm1_resource,
+ .dev = {
+ .platform_data = &s3c_pcm1_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm1);
+
+/* AC97 Controller platform devices */
+
+static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_AC97_BITCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_AC97_nRESET);
+ s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_AC97_SYNC);
+ s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_AC97_SDI);
+ s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_AC97_SDO);
+
+ return 0;
+}
+
+static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_AC97_BITCLK);
+ s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_AC97_nRESET);
+ s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_AC97_SYNC);
+ s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_AC97_SDI);
+ s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_AC97_SDO);
+
+ return 0;
+}
+
+static struct resource s3c64xx_ac97_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_AC97,
+ .end = S3C64XX_PA_AC97 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_AC97_PCMOUT,
+ .end = DMACH_AC97_PCMOUT,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_AC97_PCMIN,
+ .end = DMACH_AC97_PCMIN,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DMACH_AC97_MICIN,
+ .end = DMACH_AC97_MICIN,
+ .flags = IORESOURCE_DMA,
+ },
+ [4] = {
+ .start = IRQ_AC97,
+ .end = IRQ_AC97,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata;
+
+static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c64xx_device_ac97 = {
+ .name = "s3c-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource),
+ .resource = s3c64xx_ac97_resource,
+ .dev = {
+ .platform_data = &s3c_ac97_pdata,
+ .dma_mask = &s3c64xx_ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_ac97);
+
+void __init s3c64xx_ac97_setup_gpio(int num)
+{
+ if (num == S3C64XX_AC97_GPD)
+ s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
+ else
+ s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
+}
diff --git a/arch/arm/mach-s3c64xx/dev-rtc.c b/arch/arm/mach-s3c64xx/dev-rtc.c
new file mode 100644
index 00000000000..b9e7a05f012
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-rtc.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s3c64xx/dev-rtc.c
+ *
+ * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+static struct resource s3c_rtc_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_RTC,
+ .end = S3C64XX_PA_RTC + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_RTC_ALARM,
+ .end = IRQ_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_RTC_TIC,
+ .end = IRQ_RTC_TIC,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+struct platform_device s3c_device_rtc = {
+ .name = "s3c64xx-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_rtc_resource),
+ .resource = s3c_rtc_resource,
+};
+EXPORT_SYMBOL(s3c_device_rtc);
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c
new file mode 100644
index 00000000000..29c32d08851
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-spi.c
@@ -0,0 +1,182 @@
+/* linux/arch/arm/plat-s3c64xx/dev-spi.c
+ *
+ * Copyright (C) 2009 Samsung Electronics Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/gpio-bank-c.h>
+#include <mach/spi-clocks.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irqs.h>
+
+static char *spi_src_clks[] = {
+ [S3C64XX_SPI_SRCCLK_PCLK] = "pclk",
+ [S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus",
+ [S3C64XX_SPI_SRCCLK_48M] = "spi_48m",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the GPC-3,7.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(S3C64XX_GPC(0), S3C64XX_GPC0_SPI_MISO0);
+ s3c_gpio_cfgpin(S3C64XX_GPC(1), S3C64XX_GPC1_SPI_CLKO);
+ s3c_gpio_cfgpin(S3C64XX_GPC(2), S3C64XX_GPC2_SPI_MOSIO);
+ s3c_gpio_setpull(S3C64XX_GPC(0), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C64XX_GPC(1), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C64XX_GPC(2), S3C_GPIO_PULL_UP);
+ break;
+
+ case 1:
+ s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_SPI_MISO1);
+ s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_SPI_CLK1);
+ s3c_gpio_cfgpin(S3C64XX_GPC(6), S3C64XX_GPC6_SPI_MOSI1);
+ s3c_gpio_setpull(S3C64XX_GPC(4), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C64XX_GPC(5), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C64XX_GPC(6), S3C_GPIO_PULL_UP);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct resource s3c64xx_spi0_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_SPI0,
+ .end = S3C64XX_PA_SPI0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI0_TX,
+ .end = DMACH_SPI0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI0_RX,
+ .end = DMACH_SPI0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI0,
+ .end = IRQ_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
+ .cfg_gpio = s3c64xx_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 13,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c64xx_device_spi0 = {
+ .name = "s3c64xx-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
+ .resource = s3c64xx_spi0_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c64xx_spi0_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_spi0);
+
+static struct resource s3c64xx_spi1_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_SPI1,
+ .end = S3C64XX_PA_SPI1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI1_TX,
+ .end = DMACH_SPI1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI1_RX,
+ .end = DMACH_SPI1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI1,
+ .end = IRQ_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
+ .cfg_gpio = s3c64xx_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 13,
+};
+
+struct platform_device s3c64xx_device_spi1 = {
+ .name = "s3c64xx-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
+ .resource = s3c64xx_spi1_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c64xx_spi1_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_spi1);
+
+void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
+{
+ struct s3c64xx_spi_info *pd;
+
+ /* Reject invalid configuration */
+ if (!num_cs || src_clk_nr < 0
+ || src_clk_nr > S3C64XX_SPI_SRCCLK_48M) {
+ printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ switch (cntrlr) {
+ case 0:
+ pd = &s3c64xx_spi0_pdata;
+ break;
+ case 1:
+ pd = &s3c64xx_spi1_pdata;
+ break;
+ default:
+ printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
+ __func__, cntrlr);
+ return;
+ }
+
+ pd->num_cs = num_cs;
+ pd->src_clk_nr = src_clk_nr;
+ pd->src_clk_name = spi_src_clks[src_clk_nr];
+}
diff --git a/arch/arm/mach-s3c64xx/dev-uart.c b/arch/arm/mach-s3c64xx/dev-uart.c
new file mode 100644
index 00000000000..f797f748b99
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-uart.c
@@ -0,0 +1,147 @@
+/* linux/arch/arm/plat-s3c64xx/dev-uart.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX UART resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+/* Serial port registrations */
+
+/* 64xx uarts are closer together */
+
+static struct resource s3c64xx_uart0_resource[] = {
+ [0] = {
+ .start = S3C_PA_UART0,
+ .end = S3C_PA_UART0 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX0,
+ .end = IRQ_S3CUART_RX0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S3CUART_TX0,
+ .end = IRQ_S3CUART_TX0,
+ .flags = IORESOURCE_IRQ,
+
+ },
+ [3] = {
+ .start = IRQ_S3CUART_ERR0,
+ .end = IRQ_S3CUART_ERR0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s3c64xx_uart1_resource[] = {
+ [0] = {
+ .start = S3C_PA_UART1,
+ .end = S3C_PA_UART1 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX1,
+ .end = IRQ_S3CUART_RX1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S3CUART_TX1,
+ .end = IRQ_S3CUART_TX1,
+ .flags = IORESOURCE_IRQ,
+
+ },
+ [3] = {
+ .start = IRQ_S3CUART_ERR1,
+ .end = IRQ_S3CUART_ERR1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource s3c6xx_uart2_resource[] = {
+ [0] = {
+ .start = S3C_PA_UART2,
+ .end = S3C_PA_UART2 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX2,
+ .end = IRQ_S3CUART_RX2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S3CUART_TX2,
+ .end = IRQ_S3CUART_TX2,
+ .flags = IORESOURCE_IRQ,
+
+ },
+ [3] = {
+ .start = IRQ_S3CUART_ERR2,
+ .end = IRQ_S3CUART_ERR2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource s3c64xx_uart3_resource[] = {
+ [0] = {
+ .start = S3C_PA_UART3,
+ .end = S3C_PA_UART3 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX3,
+ .end = IRQ_S3CUART_RX3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S3CUART_TX3,
+ .end = IRQ_S3CUART_TX3,
+ .flags = IORESOURCE_IRQ,
+
+ },
+ [3] = {
+ .start = IRQ_S3CUART_ERR3,
+ .end = IRQ_S3CUART_ERR3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s3c64xx_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart0_resource),
+ },
+ [1] = {
+ .resources = s3c64xx_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart1_resource),
+ },
+ [2] = {
+ .resources = s3c6xx_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s3c6xx_uart2_resource),
+ },
+ [3] = {
+ .resources = s3c64xx_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart3_resource),
+ },
+};
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c
new file mode 100644
index 00000000000..33ccf7bf766
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dma.c
@@ -0,0 +1,750 @@
+/* linux/arch/arm/plat-s3c64xx/dma.c
+ *
+ * Copyright 2009 Openmoko, Inc.
+ * Copyright 2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX DMA core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/dmapool.h>
+#include <linux/sysdev.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <mach/regs-sys.h>
+
+#include <asm/hardware/pl080.h>
+
+/* dma channel state information */
+
+struct s3c64xx_dmac {
+ struct sys_device sysdev;
+ struct clk *clk;
+ void __iomem *regs;
+ struct s3c2410_dma_chan *channels;
+ enum dma_ch chanbase;
+};
+
+/* pool to provide LLI buffers */
+static struct dma_pool *dma_pool;
+
+/* Debug configuration and code */
+
+static unsigned char debug_show_buffs = 0;
+
+static void dbg_showchan(struct s3c2410_dma_chan *chan)
+{
+ pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
+ chan->number,
+ readl(chan->regs + PL080_CH_SRC_ADDR),
+ readl(chan->regs + PL080_CH_DST_ADDR),
+ readl(chan->regs + PL080_CH_LLI),
+ readl(chan->regs + PL080_CH_CONTROL),
+ readl(chan->regs + PL080S_CH_CONTROL2),
+ readl(chan->regs + PL080S_CH_CONFIG));
+}
+
+static void show_lli(struct pl080s_lli *lli)
+{
+ pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
+ lli, lli->src_addr, lli->dst_addr, lli->next_lli,
+ lli->control0, lli->control1);
+}
+
+static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
+{
+ struct s3c64xx_dma_buff *ptr;
+ struct s3c64xx_dma_buff *end;
+
+ pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
+ chan->number, chan->next, chan->curr, chan->end);
+
+ ptr = chan->next;
+ end = chan->end;
+
+ if (debug_show_buffs) {
+ for (; ptr != NULL; ptr = ptr->next) {
+ pr_debug("DMA%d: %08x ",
+ chan->number, ptr->lli_dma);
+ show_lli(ptr->lli);
+ }
+ }
+}
+
+/* End of Debug */
+
+static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
+{
+ struct s3c2410_dma_chan *chan;
+ unsigned int start, offs;
+
+ start = 0;
+
+ if (channel >= DMACH_PCM1_TX)
+ start = 8;
+
+ for (offs = 0; offs < 8; offs++) {
+ chan = &s3c2410_chans[start + offs];
+ if (!chan->in_use)
+ goto found;
+ }
+
+ return NULL;
+
+found:
+ s3c_dma_chan_map[channel] = chan;
+ return chan;
+}
+
+int s3c2410_dma_config(unsigned int channel, int xferunit)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ switch (xferunit) {
+ case 1:
+ chan->hw_width = 0;
+ break;
+ case 2:
+ chan->hw_width = 1;
+ break;
+ case 4:
+ chan->hw_width = 2;
+ break;
+ default:
+ printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
+ struct pl080s_lli *lli,
+ dma_addr_t data, int size)
+{
+ dma_addr_t src, dst;
+ u32 control0, control1;
+
+ switch (chan->source) {
+ case S3C2410_DMASRC_HW:
+ src = chan->dev_addr;
+ dst = data;
+ control0 = PL080_CONTROL_SRC_AHB2;
+ control0 |= PL080_CONTROL_DST_INCR;
+ break;
+
+ case S3C2410_DMASRC_MEM:
+ src = data;
+ dst = chan->dev_addr;
+ control0 = PL080_CONTROL_DST_AHB2;
+ control0 |= PL080_CONTROL_SRC_INCR;
+ break;
+ default:
+ BUG();
+ }
+
+ /* note, we do not currently setup any of the burst controls */
+
+ control1 = size >> chan->hw_width; /* size in no of xfers */
+ control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */
+ control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */
+ control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
+ control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
+
+ lli->src_addr = src;
+ lli->dst_addr = dst;
+ lli->next_lli = 0;
+ lli->control0 = control0;
+ lli->control1 = control1;
+}
+
+static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
+ struct pl080s_lli *lli)
+{
+ void __iomem *regs = chan->regs;
+
+ pr_debug("%s: LLI %p => regs\n", __func__, lli);
+ show_lli(lli);
+
+ writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
+ writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
+ writel(lli->next_lli, regs + PL080_CH_LLI);
+ writel(lli->control0, regs + PL080_CH_CONTROL);
+ writel(lli->control1, regs + PL080S_CH_CONTROL2);
+}
+
+static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
+{
+ struct s3c64xx_dmac *dmac = chan->dmac;
+ u32 config;
+ u32 bit = chan->bit;
+
+ dbg_showchan(chan);
+
+ pr_debug("%s: clearing interrupts\n", __func__);
+
+ /* clear interrupts */
+ writel(bit, dmac->regs + PL080_TC_CLEAR);
+ writel(bit, dmac->regs + PL080_ERR_CLEAR);
+
+ pr_debug("%s: starting channel\n", __func__);
+
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ config |= PL080_CONFIG_ENABLE;
+
+ pr_debug("%s: writing config %08x\n", __func__, config);
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ return 0;
+}
+
+static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
+{
+ u32 config;
+ int timeout;
+
+ pr_debug("%s: stopping channel\n", __func__);
+
+ dbg_showchan(chan);
+
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ config |= PL080_CONFIG_HALT;
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ timeout = 1000;
+ do {
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
+ if (config & PL080_CONFIG_ACTIVE)
+ udelay(10);
+ else
+ break;
+ } while (--timeout > 0);
+
+ if (config & PL080_CONFIG_ACTIVE) {
+ printk(KERN_ERR "%s: channel still active\n", __func__);
+ return -EFAULT;
+ }
+
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ config &= ~PL080_CONFIG_ENABLE;
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ return 0;
+}
+
+static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
+ struct s3c64xx_dma_buff *buf,
+ enum s3c2410_dma_buffresult result)
+{
+ if (chan->callback_fn != NULL)
+ (chan->callback_fn)(chan, buf->pw, 0, result);
+}
+
+static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
+{
+ dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
+ kfree(buff);
+}
+
+static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
+{
+ struct s3c64xx_dma_buff *buff, *next;
+ u32 config;
+
+ dbg_showchan(chan);
+
+ pr_debug("%s: flushing channel\n", __func__);
+
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ config &= ~PL080_CONFIG_ENABLE;
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ /* dump all the buffers associated with this channel */
+
+ for (buff = chan->curr; buff != NULL; buff = next) {
+ next = buff->next;
+ pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
+
+ s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
+ s3c64xx_dma_freebuff(buff);
+ }
+
+ chan->curr = chan->next = chan->end = NULL;
+
+ return 0;
+}
+
+int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ WARN_ON(!chan);
+ if (!chan)
+ return -EINVAL;
+
+ switch (op) {
+ case S3C2410_DMAOP_START:
+ return s3c64xx_dma_start(chan);
+
+ case S3C2410_DMAOP_STOP:
+ return s3c64xx_dma_stop(chan);
+
+ case S3C2410_DMAOP_FLUSH:
+ return s3c64xx_dma_flush(chan);
+
+ /* belive PAUSE/RESUME are no-ops */
+ case S3C2410_DMAOP_PAUSE:
+ case S3C2410_DMAOP_RESUME:
+ case S3C2410_DMAOP_STARTED:
+ case S3C2410_DMAOP_TIMEOUT:
+ return 0;
+ }
+
+ return -ENOENT;
+}
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+/* s3c2410_dma_enque
+ *
+ */
+
+int s3c2410_dma_enqueue(unsigned int channel, void *id,
+ dma_addr_t data, int size)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ struct s3c64xx_dma_buff *next;
+ struct s3c64xx_dma_buff *buff;
+ struct pl080s_lli *lli;
+ unsigned long flags;
+ int ret;
+
+ WARN_ON(!chan);
+ if (!chan)
+ return -EINVAL;
+
+ buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
+ if (!buff) {
+ printk(KERN_ERR "%s: no memory for buffer\n", __func__);
+ return -ENOMEM;
+ }
+
+ lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
+ if (!lli) {
+ printk(KERN_ERR "%s: no memory for lli\n", __func__);
+ ret = -ENOMEM;
+ goto err_buff;
+ }
+
+ pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
+ __func__, buff, data, lli, (u32)buff->lli_dma, size);
+
+ buff->lli = lli;
+ buff->pw = id;
+
+ s3c64xx_dma_fill_lli(chan, lli, data, size);
+
+ local_irq_save(flags);
+
+ if ((next = chan->next) != NULL) {
+ struct s3c64xx_dma_buff *end = chan->end;
+ struct pl080s_lli *endlli = end->lli;
+
+ pr_debug("enquing onto channel\n");
+
+ end->next = buff;
+ endlli->next_lli = buff->lli_dma;
+
+ if (chan->flags & S3C2410_DMAF_CIRCULAR) {
+ struct s3c64xx_dma_buff *curr = chan->curr;
+ lli->next_lli = curr->lli_dma;
+ }
+
+ if (next == chan->curr) {
+ writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
+ chan->next = buff;
+ }
+
+ show_lli(endlli);
+ chan->end = buff;
+ } else {
+ pr_debug("enquing onto empty channel\n");
+
+ chan->curr = buff;
+ chan->next = buff;
+ chan->end = buff;
+
+ s3c64xx_lli_to_regs(chan, lli);
+ }
+
+ local_irq_restore(flags);
+
+ show_lli(lli);
+
+ dbg_showchan(chan);
+ dbg_showbuffs(chan);
+ return 0;
+
+err_buff:
+ kfree(buff);
+ return ret;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+
+int s3c2410_dma_devconfig(int channel,
+ enum s3c2410_dmasrc source,
+ unsigned long devaddr)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ u32 peripheral;
+ u32 config = 0;
+
+ pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
+ __func__, channel, source, devaddr, chan);
+
+ WARN_ON(!chan);
+ if (!chan)
+ return -EINVAL;
+
+ peripheral = (chan->peripheral & 0xf);
+ chan->source = source;
+ chan->dev_addr = devaddr;
+
+ pr_debug("%s: peripheral %d\n", __func__, peripheral);
+
+ switch (source) {
+ case S3C2410_DMASRC_HW:
+ config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
+ config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
+ break;
+ case S3C2410_DMASRC_MEM:
+ config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
+ config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
+ break;
+ default:
+ printk(KERN_ERR "%s: bad source\n", __func__);
+ return -EINVAL;
+ }
+
+ /* allow TC and ERR interrupts */
+ config |= PL080_CONFIG_TC_IRQ_MASK;
+ config |= PL080_CONFIG_ERR_IRQ_MASK;
+
+ pr_debug("%s: config %08x\n", __func__, config);
+
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+
+int s3c2410_dma_getposition(unsigned int channel,
+ dma_addr_t *src, dma_addr_t *dst)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ WARN_ON(!chan);
+ if (!chan)
+ return -EINVAL;
+
+ if (src != NULL)
+ *src = readl(chan->regs + PL080_CH_SRC_ADDR);
+
+ if (dst != NULL)
+ *dst = readl(chan->regs + PL080_CH_DST_ADDR);
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+/* s3c2410_request_dma
+ *
+ * get control of an dma channel
+*/
+
+int s3c2410_dma_request(unsigned int channel,
+ struct s3c2410_dma_client *client,
+ void *dev)
+{
+ struct s3c2410_dma_chan *chan;
+ unsigned long flags;
+
+ pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
+ channel, client->name, dev);
+
+ local_irq_save(flags);
+
+ chan = s3c64xx_dma_map_channel(channel);
+ if (chan == NULL) {
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+
+ dbg_showchan(chan);
+
+ chan->client = client;
+ chan->in_use = 1;
+ chan->peripheral = channel;
+
+ local_irq_restore(flags);
+
+ /* need to setup */
+
+ pr_debug("%s: channel initialised, %p\n", __func__, chan);
+
+ return chan->number | DMACH_LOW_LEVEL;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+/* s3c2410_dma_free
+ *
+ * release the given channel back to the system, will stop and flush
+ * any outstanding transfers, and ensure the channel is ready for the
+ * next claimant.
+ *
+ * Note, although a warning is currently printed if the freeing client
+ * info is not the same as the registrant's client info, the free is still
+ * allowed to go through.
+*/
+
+int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ unsigned long flags;
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ if (chan->client != client) {
+ printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
+ channel, chan->client, client);
+ }
+
+ /* sort out stopping and freeing the channel */
+
+
+ chan->client = NULL;
+ chan->in_use = 0;
+
+ if (!(channel & DMACH_LOW_LEVEL))
+ s3c_dma_chan_map[channel] = NULL;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
+{
+ struct s3c64xx_dmac *dmac = pw;
+ struct s3c2410_dma_chan *chan;
+ enum s3c2410_dma_buffresult res;
+ u32 tcstat, errstat;
+ u32 bit;
+ int offs;
+
+ tcstat = readl(dmac->regs + PL080_TC_STATUS);
+ errstat = readl(dmac->regs + PL080_ERR_STATUS);
+
+ for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
+ struct s3c64xx_dma_buff *buff;
+
+ if (!(errstat & bit) && !(tcstat & bit))
+ continue;
+
+ chan = dmac->channels + offs;
+ res = S3C2410_RES_ERR;
+
+ if (tcstat & bit) {
+ writel(bit, dmac->regs + PL080_TC_CLEAR);
+ res = S3C2410_RES_OK;
+ }
+
+ if (errstat & bit)
+ writel(bit, dmac->regs + PL080_ERR_CLEAR);
+
+ /* 'next' points to the buffer that is next to the
+ * currently active buffer.
+ * For CIRCULAR queues, 'next' will be same as 'curr'
+ * when 'end' is the active buffer.
+ */
+ buff = chan->curr;
+ while (buff && buff != chan->next
+ && buff->next != chan->next)
+ buff = buff->next;
+
+ if (!buff)
+ BUG();
+
+ if (buff == chan->next)
+ buff = chan->end;
+
+ s3c64xx_dma_bufffdone(chan, buff, res);
+
+ /* Free the node and update curr, if non-circular queue */
+ if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
+ chan->curr = buff->next;
+ s3c64xx_dma_freebuff(buff);
+ }
+
+ /* Update 'next' */
+ buff = chan->next;
+ if (chan->next == chan->end) {
+ chan->next = chan->curr;
+ if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
+ chan->end = NULL;
+ } else {
+ chan->next = buff->next;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct sysdev_class dma_sysclass = {
+ .name = "s3c64xx-dma",
+};
+
+static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
+ int irq, unsigned int base)
+{
+ struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
+ struct s3c64xx_dmac *dmac;
+ char clkname[16];
+ void __iomem *regs;
+ void __iomem *regptr;
+ int err, ch;
+
+ dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
+ if (!dmac) {
+ printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
+ return -ENOMEM;
+ }
+
+ dmac->sysdev.id = chno / 8;
+ dmac->sysdev.cls = &dma_sysclass;
+
+ err = sysdev_register(&dmac->sysdev);
+ if (err) {
+ printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
+ goto err_alloc;
+ }
+
+ regs = ioremap(base, 0x200);
+ if (!regs) {
+ printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
+ err = -ENXIO;
+ goto err_dev;
+ }
+
+ snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);
+
+ dmac->clk = clk_get(NULL, clkname);
+ if (IS_ERR(dmac->clk)) {
+ printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
+ err = PTR_ERR(dmac->clk);
+ goto err_map;
+ }
+
+ clk_enable(dmac->clk);
+
+ dmac->regs = regs;
+ dmac->chanbase = chbase;
+ dmac->channels = chptr;
+
+ err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
+ if (err < 0) {
+ printk(KERN_ERR "%s: failed to get irq\n", __func__);
+ goto err_clk;
+ }
+
+ regptr = regs + PL080_Cx_BASE(0);
+
+ for (ch = 0; ch < 8; ch++, chno++, chptr++) {
+ printk(KERN_INFO "%s: registering DMA %d (%p)\n",
+ __func__, chno, regptr);
+
+ chptr->bit = 1 << ch;
+ chptr->number = chno;
+ chptr->dmac = dmac;
+ chptr->regs = regptr;
+ regptr += PL008_Cx_STRIDE;
+ }
+
+ /* for the moment, permanently enable the controller */
+ writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
+
+ printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs);
+
+ return 0;
+
+err_clk:
+ clk_disable(dmac->clk);
+ clk_put(dmac->clk);
+err_map:
+ iounmap(regs);
+err_dev:
+ sysdev_unregister(&dmac->sysdev);
+err_alloc:
+ kfree(dmac);
+ return err;
+}
+
+static int __init s3c64xx_dma_init(void)
+{
+ int ret;
+
+ printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
+
+ dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
+ if (!dma_pool) {
+ printk(KERN_ERR "%s: failed to create pool\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = sysdev_class_register(&dma_sysclass);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to create sysclass\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Set all DMA configuration to be DMA, not SDMA */
+ writel(0xffffff, S3C_SYSREG(0x110));
+
+ /* Register standard DMA controlers */
+ s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
+ s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
+
+ return 0;
+}
+
+arch_initcall(s3c64xx_dma_init);
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
new file mode 100644
index 00000000000..66e6794481d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -0,0 +1,288 @@
+/* arch/arm/plat-s3c64xx/gpiolib.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <mach/regs-gpio.h>
+
+/* GPIO bank summary:
+ *
+ * Bank GPIOs Style SlpCon ExtInt Group
+ * A 8 4Bit Yes 1
+ * B 7 4Bit Yes 1
+ * C 8 4Bit Yes 2
+ * D 5 4Bit Yes 3
+ * E 5 4Bit Yes None
+ * F 16 2Bit Yes 4 [1]
+ * G 7 4Bit Yes 5
+ * H 10 4Bit[2] Yes 6
+ * I 16 2Bit Yes None
+ * J 12 2Bit Yes None
+ * K 16 4Bit[2] No None
+ * L 15 4Bit[2] No None
+ * M 6 4Bit No IRQ_EINT
+ * N 16 2Bit No IRQ_EINT
+ * O 16 2Bit Yes 7
+ * P 15 2Bit Yes 8
+ * Q 9 2Bit Yes 9
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
+ .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
+ .cfg_eint = 7,
+ .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
+ .cfg_eint = 3,
+ .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
+{
+ return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
+}
+
+static struct s3c_gpio_chip gpio_4bit[] = {
+ {
+ .base = S3C64XX_GPA_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPA(0),
+ .ngpio = S3C64XX_GPIO_A_NR,
+ .label = "GPA",
+ },
+ }, {
+ .base = S3C64XX_GPB_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPB(0),
+ .ngpio = S3C64XX_GPIO_B_NR,
+ .label = "GPB",
+ },
+ }, {
+ .base = S3C64XX_GPC_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPC(0),
+ .ngpio = S3C64XX_GPIO_C_NR,
+ .label = "GPC",
+ },
+ }, {
+ .base = S3C64XX_GPD_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPD(0),
+ .ngpio = S3C64XX_GPIO_D_NR,
+ .label = "GPD",
+ },
+ }, {
+ .base = S3C64XX_GPE_BASE,
+ .config = &gpio_4bit_cfg_noint,
+ .chip = {
+ .base = S3C64XX_GPE(0),
+ .ngpio = S3C64XX_GPIO_E_NR,
+ .label = "GPE",
+ },
+ }, {
+ .base = S3C64XX_GPG_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPG(0),
+ .ngpio = S3C64XX_GPIO_G_NR,
+ .label = "GPG",
+ },
+ }, {
+ .base = S3C64XX_GPM_BASE,
+ .config = &gpio_4bit_cfg_eint0011,
+ .chip = {
+ .base = S3C64XX_GPM(0),
+ .ngpio = S3C64XX_GPIO_M_NR,
+ .label = "GPM",
+ .to_irq = s3c64xx_gpio2int_gpm,
+ },
+ },
+};
+
+int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
+{
+ return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
+}
+
+static struct s3c_gpio_chip gpio_4bit2[] = {
+ {
+ .base = S3C64XX_GPH_BASE + 0x4,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPH(0),
+ .ngpio = S3C64XX_GPIO_H_NR,
+ .label = "GPH",
+ },
+ }, {
+ .base = S3C64XX_GPK_BASE + 0x4,
+ .config = &gpio_4bit_cfg_noint,
+ .chip = {
+ .base = S3C64XX_GPK(0),
+ .ngpio = S3C64XX_GPIO_K_NR,
+ .label = "GPK",
+ },
+ }, {
+ .base = S3C64XX_GPL_BASE + 0x4,
+ .config = &gpio_4bit_cfg_eint0011,
+ .chip = {
+ .base = S3C64XX_GPL(0),
+ .ngpio = S3C64XX_GPIO_L_NR,
+ .label = "GPL",
+ .to_irq = s3c64xx_gpio2int_gpl,
+ },
+ },
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
+ .cfg_eint = 2,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
+ .cfg_eint = 3,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
+{
+ return IRQ_EINT(0) + pin;
+}
+
+static struct s3c_gpio_chip gpio_2bit[] = {
+ {
+ .base = S3C64XX_GPF_BASE,
+ .config = &gpio_2bit_cfg_eint11,
+ .chip = {
+ .base = S3C64XX_GPF(0),
+ .ngpio = S3C64XX_GPIO_F_NR,
+ .label = "GPF",
+ },
+ }, {
+ .base = S3C64XX_GPI_BASE,
+ .config = &gpio_2bit_cfg_noint,
+ .chip = {
+ .base = S3C64XX_GPI(0),
+ .ngpio = S3C64XX_GPIO_I_NR,
+ .label = "GPI",
+ },
+ }, {
+ .base = S3C64XX_GPJ_BASE,
+ .config = &gpio_2bit_cfg_noint,
+ .chip = {
+ .base = S3C64XX_GPJ(0),
+ .ngpio = S3C64XX_GPIO_J_NR,
+ .label = "GPJ",
+ },
+ }, {
+ .base = S3C64XX_GPN_BASE,
+ .config = &gpio_2bit_cfg_eint10,
+ .chip = {
+ .base = S3C64XX_GPN(0),
+ .ngpio = S3C64XX_GPIO_N_NR,
+ .label = "GPN",
+ .to_irq = s3c64xx_gpio2int_gpn,
+ },
+ }, {
+ .base = S3C64XX_GPO_BASE,
+ .config = &gpio_2bit_cfg_eint11,
+ .chip = {
+ .base = S3C64XX_GPO(0),
+ .ngpio = S3C64XX_GPIO_O_NR,
+ .label = "GPO",
+ },
+ }, {
+ .base = S3C64XX_GPP_BASE,
+ .config = &gpio_2bit_cfg_eint11,
+ .chip = {
+ .base = S3C64XX_GPP(0),
+ .ngpio = S3C64XX_GPIO_P_NR,
+ .label = "GPP",
+ },
+ }, {
+ .base = S3C64XX_GPQ_BASE,
+ .config = &gpio_2bit_cfg_eint11,
+ .chip = {
+ .base = S3C64XX_GPQ(0),
+ .ngpio = S3C64XX_GPIO_Q_NR,
+ .label = "GPQ",
+ },
+ },
+};
+
+static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
+{
+ chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
+}
+
+static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
+ int nr_chips,
+ void (*fn)(struct s3c_gpio_chip *))
+{
+ for (; nr_chips > 0; nr_chips--, chips++) {
+ if (fn)
+ (fn)(chips);
+ s3c_gpiolib_add(chips);
+ }
+}
+
+static __init int s3c64xx_gpiolib_init(void)
+{
+ s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
+ samsung_gpiolib_add_4bit);
+
+ s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
+ samsung_gpiolib_add_4bit2);
+
+ s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
+ s3c64xx_gpiolib_add_2bit);
+
+ return 0;
+}
+
+core_initcall(s3c64xx_gpiolib_init);
diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
new file mode 100644
index 00000000000..f9ab5d26052
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
@@ -0,0 +1,39 @@
+/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+ /* note, for the boot process to work we have to keep the UART
+ * virtual address aligned to an 1MiB boundary for the L1
+ * mapping the head code makes. We keep the UART virtual address
+ * aligned and add in the offset when we load the value here.
+ */
+
+ .macro addruart, rx, rtmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1
+ ldreq \rx, = S3C_PA_UART
+ ldrne \rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
new file mode 100644
index 00000000000..0a5d9268a23
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -0,0 +1,127 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/dma.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - DMA support
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H __FILE__
+
+#define S3C_DMA_CHANNELS (16)
+
+/* see mach-s3c2410/dma.h for notes on dma channel numbers */
+
+/* Note, for the S3C64XX architecture we keep the DMACH_
+ * defines in the order they are allocated to [S]DMA0/[S]DMA1
+ * so that is easy to do DHACH_ -> DMA controller conversion
+ */
+enum dma_ch {
+ /* DMA0/SDMA0 */
+ DMACH_UART0 = 0,
+ DMACH_UART0_SRC2,
+ DMACH_UART1,
+ DMACH_UART1_SRC2,
+ DMACH_UART2,
+ DMACH_UART2_SRC2,
+ DMACH_UART3,
+ DMACH_UART3_SRC2,
+ DMACH_PCM0_TX,
+ DMACH_PCM0_RX,
+ DMACH_I2S0_OUT,
+ DMACH_I2S0_IN,
+ DMACH_SPI0_TX,
+ DMACH_SPI0_RX,
+ DMACH_HSI_I2SV40_TX,
+ DMACH_HSI_I2SV40_RX,
+
+ /* DMA1/SDMA1 */
+ DMACH_PCM1_TX = 16,
+ DMACH_PCM1_RX,
+ DMACH_I2S1_OUT,
+ DMACH_I2S1_IN,
+ DMACH_SPI1_TX,
+ DMACH_SPI1_RX,
+ DMACH_AC97_PCMOUT,
+ DMACH_AC97_PCMIN,
+ DMACH_AC97_MICIN,
+ DMACH_PWM,
+ DMACH_IRDA,
+ DMACH_EXTERNAL,
+ DMACH_RES1,
+ DMACH_RES2,
+ DMACH_SECURITY_RX, /* SDMA1 only */
+ DMACH_SECURITY_TX, /* SDMA1 only */
+ DMACH_MAX /* the end */
+};
+
+static __inline__ bool s3c_dma_has_circular(void)
+{
+ return true;
+}
+
+#define S3C2410_DMAF_CIRCULAR (1 << 0)
+
+#include <plat/dma.h>
+
+#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
+
+struct s3c64xx_dma_buff;
+
+/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
+ * @next: Pointer to next buffer in queue or ring.
+ * @pw: Client provided identifier
+ * @lli: Pointer to hardware descriptor this buffer is associated with.
+ * @lli_dma: Hardare address of the descriptor.
+ */
+struct s3c64xx_dma_buff {
+ struct s3c64xx_dma_buff *next;
+
+ void *pw;
+ struct pl080s_lli *lli;
+ dma_addr_t lli_dma;
+};
+
+struct s3c64xx_dmac;
+
+struct s3c2410_dma_chan {
+ unsigned char number; /* number of this dma channel */
+ unsigned char in_use; /* channel allocated */
+ unsigned char bit; /* bit for enable/disable/etc */
+ unsigned char hw_width;
+ unsigned char peripheral;
+
+ unsigned int flags;
+ enum s3c2410_dmasrc source;
+
+
+ dma_addr_t dev_addr;
+
+ struct s3c2410_dma_client *client;
+ struct s3c64xx_dmac *dmac; /* pointer to controller */
+
+ void __iomem *regs;
+
+ /* cdriver callbacks */
+ s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
+ s3c2410_dma_opfn_t op_fn; /* channel op callback */
+
+ /* buffer list and information */
+ struct s3c64xx_dma_buff *curr; /* current dma buffer */
+ struct s3c64xx_dma_buff *next; /* next buffer to load */
+ struct s3c64xx_dma_buff *end; /* end of queue */
+
+ /* note, when channel is running in circular mode, curr is the
+ * first buffer enqueued, end is the last and curr is where the
+ * last buffer-done event is set-at. The buffers are not freed
+ * and the last buffer hardware descriptor points back to the
+ * first.
+ */
+};
+
+#include <plat/dma-core.h>
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/entry-macro.S b/arch/arm/mach-s3c64xx/include/mach/entry-macro.S
new file mode 100644
index 00000000000..dd362604dcc
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/entry-macro.S
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c6400/include/mach/entry-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Low-level IRQ helper macros for the Samsung S3C64XX series
+ *
+ * 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/map.h>
+#include <mach/irqs.h>
+
+#include <asm/entry-macro-vic2.S>
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h
new file mode 100644
index 00000000000..34212e1a7e8
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h
@@ -0,0 +1,48 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank A register and configuration 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.
+*/
+
+#define S3C64XX_GPACON (S3C64XX_GPA_BASE + 0x00)
+#define S3C64XX_GPADAT (S3C64XX_GPA_BASE + 0x04)
+#define S3C64XX_GPAPUD (S3C64XX_GPA_BASE + 0x08)
+#define S3C64XX_GPACONSLP (S3C64XX_GPA_BASE + 0x0c)
+#define S3C64XX_GPAPUDSLP (S3C64XX_GPA_BASE + 0x10)
+
+#define S3C64XX_GPA_CONMASK(__gpio) (0xf << ((__gpio) * 4))
+#define S3C64XX_GPA_INPUT(__gpio) (0x0 << ((__gpio) * 4))
+#define S3C64XX_GPA_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPA0_UART_RXD0 (0x02 << 0)
+#define S3C64XX_GPA0_EINT_G1_0 (0x07 << 0)
+
+#define S3C64XX_GPA1_UART_TXD0 (0x02 << 4)
+#define S3C64XX_GPA1_EINT_G1_1 (0x07 << 4)
+
+#define S3C64XX_GPA2_UART_nCTS0 (0x02 << 8)
+#define S3C64XX_GPA2_EINT_G1_2 (0x07 << 8)
+
+#define S3C64XX_GPA3_UART_nRTS0 (0x02 << 12)
+#define S3C64XX_GPA3_EINT_G1_3 (0x07 << 12)
+
+#define S3C64XX_GPA4_UART_RXD1 (0x02 << 16)
+#define S3C64XX_GPA4_EINT_G1_4 (0x07 << 16)
+
+#define S3C64XX_GPA5_UART_TXD1 (0x02 << 20)
+#define S3C64XX_GPA5_EINT_G1_5 (0x07 << 20)
+
+#define S3C64XX_GPA6_UART_nCTS1 (0x02 << 24)
+#define S3C64XX_GPA6_EINT_G1_6 (0x07 << 24)
+
+#define S3C64XX_GPA7_UART_nRTS1 (0x02 << 28)
+#define S3C64XX_GPA7_EINT_G1_7 (0x07 << 28)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h
new file mode 100644
index 00000000000..7232c037e64
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h
@@ -0,0 +1,60 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank B register and configuration 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.
+*/
+
+#define S3C64XX_GPBCON (S3C64XX_GPB_BASE + 0x00)
+#define S3C64XX_GPBDAT (S3C64XX_GPB_BASE + 0x04)
+#define S3C64XX_GPBPUD (S3C64XX_GPB_BASE + 0x08)
+#define S3C64XX_GPBCONSLP (S3C64XX_GPB_BASE + 0x0c)
+#define S3C64XX_GPBPUDSLP (S3C64XX_GPB_BASE + 0x10)
+
+#define S3C64XX_GPB_CONMASK(__gpio) (0xf << ((__gpio) * 4))
+#define S3C64XX_GPB_INPUT(__gpio) (0x0 << ((__gpio) * 4))
+#define S3C64XX_GPB_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPB0_UART_RXD2 (0x02 << 0)
+#define S3C64XX_GPB0_EXTDMA_REQ (0x03 << 0)
+#define S3C64XX_GPB0_IrDA_RXD (0x04 << 0)
+#define S3C64XX_GPB0_ADDR_CF0 (0x05 << 0)
+#define S3C64XX_GPB0_EINT_G1_8 (0x07 << 0)
+
+#define S3C64XX_GPB1_UART_TXD2 (0x02 << 4)
+#define S3C64XX_GPB1_EXTDMA_ACK (0x03 << 4)
+#define S3C64XX_GPB1_IrDA_TXD (0x04 << 4)
+#define S3C64XX_GPB1_ADDR_CF1 (0x05 << 4)
+#define S3C64XX_GPB1_EINT_G1_9 (0x07 << 4)
+
+#define S3C64XX_GPB2_UART_RXD3 (0x02 << 8)
+#define S3C64XX_GPB2_IrDA_RXD (0x03 << 8)
+#define S3C64XX_GPB2_EXTDMA_REQ (0x04 << 8)
+#define S3C64XX_GPB2_ADDR_CF2 (0x05 << 8)
+#define S3C64XX_GPB2_I2C_SCL1 (0x06 << 8)
+#define S3C64XX_GPB2_EINT_G1_10 (0x07 << 8)
+
+#define S3C64XX_GPB3_UART_TXD3 (0x02 << 12)
+#define S3C64XX_GPB3_IrDA_TXD (0x03 << 12)
+#define S3C64XX_GPB3_EXTDMA_ACK (0x04 << 12)
+#define S3C64XX_GPB3_I2C_SDA1 (0x06 << 12)
+#define S3C64XX_GPB3_EINT_G1_11 (0x07 << 12)
+
+#define S3C64XX_GPB4_IrDA_SDBW (0x02 << 16)
+#define S3C64XX_GPB4_CAM_FIELD (0x03 << 16)
+#define S3C64XX_GPB4_CF_DATA_DIR (0x04 << 16)
+#define S3C64XX_GPB4_EINT_G1_12 (0x07 << 16)
+
+#define S3C64XX_GPB5_I2C_SCL0 (0x02 << 20)
+#define S3C64XX_GPB5_EINT_G1_13 (0x07 << 20)
+
+#define S3C64XX_GPB6_I2C_SDA0 (0x02 << 24)
+#define S3C64XX_GPB6_EINT_G1_14 (0x07 << 24)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h
new file mode 100644
index 00000000000..db189ab1639
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h
@@ -0,0 +1,53 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank C register and configuration 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.
+*/
+
+#define S3C64XX_GPCCON (S3C64XX_GPC_BASE + 0x00)
+#define S3C64XX_GPCDAT (S3C64XX_GPC_BASE + 0x04)
+#define S3C64XX_GPCPUD (S3C64XX_GPC_BASE + 0x08)
+#define S3C64XX_GPCCONSLP (S3C64XX_GPC_BASE + 0x0c)
+#define S3C64XX_GPCPUDSLP (S3C64XX_GPC_BASE + 0x10)
+
+#define S3C64XX_GPC_CONMASK(__gpio) (0xf << ((__gpio) * 4))
+#define S3C64XX_GPC_INPUT(__gpio) (0x0 << ((__gpio) * 4))
+#define S3C64XX_GPC_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPC0_SPI_MISO0 (0x02 << 0)
+#define S3C64XX_GPC0_EINT_G2_0 (0x07 << 0)
+
+#define S3C64XX_GPC1_SPI_CLKO (0x02 << 4)
+#define S3C64XX_GPC1_EINT_G2_1 (0x07 << 4)
+
+#define S3C64XX_GPC2_SPI_MOSIO (0x02 << 8)
+#define S3C64XX_GPC2_EINT_G2_2 (0x07 << 8)
+
+#define S3C64XX_GPC3_SPI_nCSO (0x02 << 12)
+#define S3C64XX_GPC3_EINT_G2_3 (0x07 << 12)
+
+#define S3C64XX_GPC4_SPI_MISO1 (0x02 << 16)
+#define S3C64XX_GPC4_MMC2_CMD (0x03 << 16)
+#define S3C64XX_GPC4_I2S_V40_DO0 (0x05 << 16)
+#define S3C64XX_GPC4_EINT_G2_4 (0x07 << 16)
+
+#define S3C64XX_GPC5_SPI_CLK1 (0x02 << 20)
+#define S3C64XX_GPC5_MMC2_CLK (0x03 << 20)
+#define S3C64XX_GPC5_I2S_V40_DO1 (0x05 << 20)
+#define S3C64XX_GPC5_EINT_G2_5 (0x07 << 20)
+
+#define S3C64XX_GPC6_SPI_MOSI1 (0x02 << 24)
+#define S3C64XX_GPC6_EINT_G2_6 (0x07 << 24)
+
+#define S3C64XX_GPC7_SPI_nCS1 (0x02 << 28)
+#define S3C64XX_GPC7_I2S_V40_DO2 (0x05 << 28)
+#define S3C64XX_GPC7_EINT_G2_7 (0x07 << 28)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h
new file mode 100644
index 00000000000..1a01cee7aca
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h
@@ -0,0 +1,49 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank D register and configuration 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.
+*/
+
+#define S3C64XX_GPDCON (S3C64XX_GPD_BASE + 0x00)
+#define S3C64XX_GPDDAT (S3C64XX_GPD_BASE + 0x04)
+#define S3C64XX_GPDPUD (S3C64XX_GPD_BASE + 0x08)
+#define S3C64XX_GPDCONSLP (S3C64XX_GPD_BASE + 0x0c)
+#define S3C64XX_GPDPUDSLP (S3C64XX_GPD_BASE + 0x10)
+
+#define S3C64XX_GPD_CONMASK(__gpio) (0xf << ((__gpio) * 4))
+#define S3C64XX_GPD_INPUT(__gpio) (0x0 << ((__gpio) * 4))
+#define S3C64XX_GPD_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPD0_PCM0_SCLK (0x02 << 0)
+#define S3C64XX_GPD0_I2S0_CLK (0x03 << 0)
+#define S3C64XX_GPD0_AC97_BITCLK (0x04 << 0)
+#define S3C64XX_GPD0_EINT_G3_0 (0x07 << 0)
+
+#define S3C64XX_GPD1_PCM0_EXTCLK (0x02 << 4)
+#define S3C64XX_GPD1_I2S0_CDCLK (0x03 << 4)
+#define S3C64XX_GPD1_AC97_nRESET (0x04 << 4)
+#define S3C64XX_GPD1_EINT_G3_1 (0x07 << 4)
+
+#define S3C64XX_GPD2_PCM0_FSYNC (0x02 << 8)
+#define S3C64XX_GPD2_I2S0_LRCLK (0x03 << 8)
+#define S3C64XX_GPD2_AC97_SYNC (0x04 << 8)
+#define S3C64XX_GPD2_EINT_G3_2 (0x07 << 8)
+
+#define S3C64XX_GPD3_PCM0_SIN (0x02 << 12)
+#define S3C64XX_GPD3_I2S0_DI (0x03 << 12)
+#define S3C64XX_GPD3_AC97_SDI (0x04 << 12)
+#define S3C64XX_GPD3_EINT_G3_3 (0x07 << 12)
+
+#define S3C64XX_GPD4_PCM0_SOUT (0x02 << 16)
+#define S3C64XX_GPD4_I2S0_D0 (0x03 << 16)
+#define S3C64XX_GPD4_AC97_SDO (0x04 << 16)
+#define S3C64XX_GPD4_EINT_G3_4 (0x07 << 16)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h
new file mode 100644
index 00000000000..f057adb627d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h
@@ -0,0 +1,44 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank E register and configuration 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.
+*/
+
+#define S3C64XX_GPECON (S3C64XX_GPE_BASE + 0x00)
+#define S3C64XX_GPEDAT (S3C64XX_GPE_BASE + 0x04)
+#define S3C64XX_GPEPUD (S3C64XX_GPE_BASE + 0x08)
+#define S3C64XX_GPECONSLP (S3C64XX_GPE_BASE + 0x0c)
+#define S3C64XX_GPEPUDSLP (S3C64XX_GPE_BASE + 0x10)
+
+#define S3C64XX_GPE_CONMASK(__gpio) (0xf << ((__gpio) * 4))
+#define S3C64XX_GPE_INPUT(__gpio) (0x0 << ((__gpio) * 4))
+#define S3C64XX_GPE_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPE0_PCM1_SCLK (0x02 << 0)
+#define S3C64XX_GPE0_I2S1_CLK (0x03 << 0)
+#define S3C64XX_GPE0_AC97_BITCLK (0x04 << 0)
+
+#define S3C64XX_GPE1_PCM1_EXTCLK (0x02 << 4)
+#define S3C64XX_GPE1_I2S1_CDCLK (0x03 << 4)
+#define S3C64XX_GPE1_AC97_nRESET (0x04 << 4)
+
+#define S3C64XX_GPE2_PCM1_FSYNC (0x02 << 8)
+#define S3C64XX_GPE2_I2S1_LRCLK (0x03 << 8)
+#define S3C64XX_GPE2_AC97_SYNC (0x04 << 8)
+
+#define S3C64XX_GPE3_PCM1_SIN (0x02 << 12)
+#define S3C64XX_GPE3_I2S1_DI (0x03 << 12)
+#define S3C64XX_GPE3_AC97_SDI (0x04 << 12)
+
+#define S3C64XX_GPE4_PCM1_SOUT (0x02 << 16)
+#define S3C64XX_GPE4_I2S1_D0 (0x03 << 16)
+#define S3C64XX_GPE4_AC97_SDO (0x04 << 16)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h
new file mode 100644
index 00000000000..62ab8f5e783
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h
@@ -0,0 +1,71 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank F register and configuration 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.
+*/
+
+#define S3C64XX_GPFCON (S3C64XX_GPF_BASE + 0x00)
+#define S3C64XX_GPFDAT (S3C64XX_GPF_BASE + 0x04)
+#define S3C64XX_GPFPUD (S3C64XX_GPF_BASE + 0x08)
+#define S3C64XX_GPFCONSLP (S3C64XX_GPF_BASE + 0x0c)
+#define S3C64XX_GPFPUDSLP (S3C64XX_GPF_BASE + 0x10)
+
+#define S3C64XX_GPF_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPF_INPUT(__gpio) (0x0 << ((__gpio) * 2))
+#define S3C64XX_GPF_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPF0_CAMIF_CLK (0x02 << 0)
+#define S3C64XX_GPF0_EINT_G4_0 (0x03 << 0)
+
+#define S3C64XX_GPF1_CAMIF_HREF (0x02 << 2)
+#define S3C64XX_GPF1_EINT_G4_1 (0x03 << 2)
+
+#define S3C64XX_GPF2_CAMIF_PCLK (0x02 << 4)
+#define S3C64XX_GPF2_EINT_G4_2 (0x03 << 4)
+
+#define S3C64XX_GPF3_CAMIF_nRST (0x02 << 6)
+#define S3C64XX_GPF3_EINT_G4_3 (0x03 << 6)
+
+#define S3C64XX_GPF4_CAMIF_VSYNC (0x02 << 8)
+#define S3C64XX_GPF4_EINT_G4_4 (0x03 << 8)
+
+#define S3C64XX_GPF5_CAMIF_YDATA0 (0x02 << 10)
+#define S3C64XX_GPF5_EINT_G4_5 (0x03 << 10)
+
+#define S3C64XX_GPF6_CAMIF_YDATA1 (0x02 << 12)
+#define S3C64XX_GPF6_EINT_G4_6 (0x03 << 12)
+
+#define S3C64XX_GPF7_CAMIF_YDATA2 (0x02 << 14)
+#define S3C64XX_GPF7_EINT_G4_7 (0x03 << 14)
+
+#define S3C64XX_GPF8_CAMIF_YDATA3 (0x02 << 16)
+#define S3C64XX_GPF8_EINT_G4_8 (0x03 << 16)
+
+#define S3C64XX_GPF9_CAMIF_YDATA4 (0x02 << 18)
+#define S3C64XX_GPF9_EINT_G4_9 (0x03 << 18)
+
+#define S3C64XX_GPF10_CAMIF_YDATA5 (0x02 << 20)
+#define S3C64XX_GPF10_EINT_G4_10 (0x03 << 20)
+
+#define S3C64XX_GPF11_CAMIF_YDATA6 (0x02 << 22)
+#define S3C64XX_GPF11_EINT_G4_11 (0x03 << 22)
+
+#define S3C64XX_GPF12_CAMIF_YDATA7 (0x02 << 24)
+#define S3C64XX_GPF12_EINT_G4_12 (0x03 << 24)
+
+#define S3C64XX_GPF13_PWM_ECLK (0x02 << 26)
+#define S3C64XX_GPF13_EINT_G4_13 (0x03 << 26)
+
+#define S3C64XX_GPF14_PWM_TOUT0 (0x02 << 28)
+#define S3C64XX_GPF14_CLKOUT0 (0x03 << 28)
+
+#define S3C64XX_GPF15_PWM_TOUT1 (0x02 << 30)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h
new file mode 100644
index 00000000000..b94954af159
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank G register and configuration 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.
+*/
+
+#define S3C64XX_GPGCON (S3C64XX_GPG_BASE + 0x00)
+#define S3C64XX_GPGDAT (S3C64XX_GPG_BASE + 0x04)
+#define S3C64XX_GPGPUD (S3C64XX_GPG_BASE + 0x08)
+#define S3C64XX_GPGCONSLP (S3C64XX_GPG_BASE + 0x0c)
+#define S3C64XX_GPGPUDSLP (S3C64XX_GPG_BASE + 0x10)
+
+#define S3C64XX_GPG_CONMASK(__gpio) (0xf << ((__gpio) * 4))
+#define S3C64XX_GPG_INPUT(__gpio) (0x0 << ((__gpio) * 4))
+#define S3C64XX_GPG_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPG0_MMC0_CLK (0x02 << 0)
+#define S3C64XX_GPG0_EINT_G5_0 (0x07 << 0)
+
+#define S3C64XX_GPG1_MMC0_CMD (0x02 << 4)
+#define S3C64XX_GPG1_EINT_G5_1 (0x07 << 4)
+
+#define S3C64XX_GPG2_MMC0_DATA0 (0x02 << 8)
+#define S3C64XX_GPG2_EINT_G5_2 (0x07 << 8)
+
+#define S3C64XX_GPG3_MMC0_DATA1 (0x02 << 12)
+#define S3C64XX_GPG3_EINT_G5_3 (0x07 << 12)
+
+#define S3C64XX_GPG4_MMC0_DATA2 (0x02 << 16)
+#define S3C64XX_GPG4_EINT_G5_4 (0x07 << 16)
+
+#define S3C64XX_GPG5_MMC0_DATA3 (0x02 << 20)
+#define S3C64XX_GPG5_EINT_G5_5 (0x07 << 20)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h
new file mode 100644
index 00000000000..5d75aaad865
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h
@@ -0,0 +1,74 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank H register and configuration 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.
+*/
+
+#define S3C64XX_GPHCON0 (S3C64XX_GPH_BASE + 0x00)
+#define S3C64XX_GPHCON1 (S3C64XX_GPH_BASE + 0x04)
+#define S3C64XX_GPHDAT (S3C64XX_GPH_BASE + 0x08)
+#define S3C64XX_GPHPUD (S3C64XX_GPH_BASE + 0x0c)
+#define S3C64XX_GPHCONSLP (S3C64XX_GPH_BASE + 0x10)
+#define S3C64XX_GPHPUDSLP (S3C64XX_GPH_BASE + 0x14)
+
+#define S3C64XX_GPH_CONMASK(__gpio) (0xf << ((__gpio) * 4))
+#define S3C64XX_GPH_INPUT(__gpio) (0x0 << ((__gpio) * 4))
+#define S3C64XX_GPH_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
+
+#define S3C64XX_GPH0_MMC1_CLK (0x02 << 0)
+#define S3C64XX_GPH0_KP_COL0 (0x04 << 0)
+#define S3C64XX_GPH0_EINT_G6_0 (0x07 << 0)
+
+#define S3C64XX_GPH1_MMC1_CMD (0x02 << 4)
+#define S3C64XX_GPH1_KP_COL1 (0x04 << 4)
+#define S3C64XX_GPH1_EINT_G6_1 (0x07 << 4)
+
+#define S3C64XX_GPH2_MMC1_DATA0 (0x02 << 8)
+#define S3C64XX_GPH2_KP_COL2 (0x04 << 8)
+#define S3C64XX_GPH2_EINT_G6_2 (0x07 << 8)
+
+#define S3C64XX_GPH3_MMC1_DATA1 (0x02 << 12)
+#define S3C64XX_GPH3_KP_COL3 (0x04 << 12)
+#define S3C64XX_GPH3_EINT_G6_3 (0x07 << 12)
+
+#define S3C64XX_GPH4_MMC1_DATA2 (0x02 << 16)
+#define S3C64XX_GPH4_KP_COL4 (0x04 << 16)
+#define S3C64XX_GPH4_EINT_G6_4 (0x07 << 16)
+
+#define S3C64XX_GPH5_MMC1_DATA3 (0x02 << 20)
+#define S3C64XX_GPH5_KP_COL5 (0x04 << 20)
+#define S3C64XX_GPH5_EINT_G6_5 (0x07 << 20)
+
+#define S3C64XX_GPH6_MMC1_DATA4 (0x02 << 24)
+#define S3C64XX_GPH6_MMC2_DATA0 (0x03 << 24)
+#define S3C64XX_GPH6_KP_COL6 (0x04 << 24)
+#define S3C64XX_GPH6_I2S_V40_BCLK (0x05 << 24)
+#define S3C64XX_GPH6_ADDR_CF0 (0x06 << 24)
+#define S3C64XX_GPH6_EINT_G6_6 (0x07 << 24)
+
+#define S3C64XX_GPH7_MMC1_DATA5 (0x02 << 28)
+#define S3C64XX_GPH7_MMC2_DATA1 (0x03 << 28)
+#define S3C64XX_GPH7_KP_COL7 (0x04 << 28)
+#define S3C64XX_GPH7_I2S_V40_CDCLK (0x05 << 28)
+#define S3C64XX_GPH7_ADDR_CF1 (0x06 << 28)
+#define S3C64XX_GPH7_EINT_G6_7 (0x07 << 28)
+
+#define S3C64XX_GPH8_MMC1_DATA6 (0x02 << 0)
+#define S3C64XX_GPH8_MMC2_DATA2 (0x03 << 0)
+#define S3C64XX_GPH8_I2S_V40_LRCLK (0x05 << 0)
+#define S3C64XX_GPH8_ADDR_CF2 (0x06 << 0)
+#define S3C64XX_GPH8_EINT_G6_8 (0x07 << 0)
+
+#define S3C64XX_GPH9_OUTPUT (0x01 << 4)
+#define S3C64XX_GPH9_MMC1_DATA7 (0x02 << 4)
+#define S3C64XX_GPH9_MMC2_DATA3 (0x03 << 4)
+#define S3C64XX_GPH9_I2S_V40_DI (0x05 << 4)
+#define S3C64XX_GPH9_EINT_G6_9 (0x07 << 4)
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h
new file mode 100644
index 00000000000..4ceaa6098bc
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h
@@ -0,0 +1,40 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank I register and configuration 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.
+*/
+
+#define S3C64XX_GPICON (S3C64XX_GPI_BASE + 0x00)
+#define S3C64XX_GPIDAT (S3C64XX_GPI_BASE + 0x04)
+#define S3C64XX_GPIPUD (S3C64XX_GPI_BASE + 0x08)
+#define S3C64XX_GPICONSLP (S3C64XX_GPI_BASE + 0x0c)
+#define S3C64XX_GPIPUDSLP (S3C64XX_GPI_BASE + 0x10)
+
+#define S3C64XX_GPI_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPI_INPUT(__gpio) (0x0 << ((__gpio) * 2))
+#define S3C64XX_GPI_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPI0_VD0 (0x02 << 0)
+#define S3C64XX_GPI1_VD1 (0x02 << 2)
+#define S3C64XX_GPI2_VD2 (0x02 << 4)
+#define S3C64XX_GPI3_VD3 (0x02 << 6)
+#define S3C64XX_GPI4_VD4 (0x02 << 8)
+#define S3C64XX_GPI5_VD5 (0x02 << 10)
+#define S3C64XX_GPI6_VD6 (0x02 << 12)
+#define S3C64XX_GPI7_VD7 (0x02 << 14)
+#define S3C64XX_GPI8_VD8 (0x02 << 16)
+#define S3C64XX_GPI9_VD9 (0x02 << 18)
+#define S3C64XX_GPI10_VD10 (0x02 << 20)
+#define S3C64XX_GPI11_VD11 (0x02 << 22)
+#define S3C64XX_GPI12_VD12 (0x02 << 24)
+#define S3C64XX_GPI13_VD13 (0x02 << 26)
+#define S3C64XX_GPI14_VD14 (0x02 << 28)
+#define S3C64XX_GPI15_VD15 (0x02 << 30)
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h
new file mode 100644
index 00000000000..6f25cd079a4
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank J register and configuration 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.
+*/
+
+#define S3C64XX_GPJCON (S3C64XX_GPJ_BASE + 0x00)
+#define S3C64XX_GPJDAT (S3C64XX_GPJ_BASE + 0x04)
+#define S3C64XX_GPJPUD (S3C64XX_GPJ_BASE + 0x08)
+#define S3C64XX_GPJCONSLP (S3C64XX_GPJ_BASE + 0x0c)
+#define S3C64XX_GPJPUDSLP (S3C64XX_GPJ_BASE + 0x10)
+
+#define S3C64XX_GPJ_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPJ_INPUT(__gpio) (0x0 << ((__gpio) * 2))
+#define S3C64XX_GPJ_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPJ0_VD16 (0x02 << 0)
+#define S3C64XX_GPJ1_VD17 (0x02 << 2)
+#define S3C64XX_GPJ2_VD18 (0x02 << 4)
+#define S3C64XX_GPJ3_VD19 (0x02 << 6)
+#define S3C64XX_GPJ4_VD20 (0x02 << 8)
+#define S3C64XX_GPJ5_VD21 (0x02 << 10)
+#define S3C64XX_GPJ6_VD22 (0x02 << 12)
+#define S3C64XX_GPJ7_VD23 (0x02 << 14)
+#define S3C64XX_GPJ8_LCD_HSYNC (0x02 << 16)
+#define S3C64XX_GPJ9_LCD_VSYNC (0x02 << 18)
+#define S3C64XX_GPJ10_LCD_VDEN (0x02 << 20)
+#define S3C64XX_GPJ11_LCD_VCLK (0x02 << 22)
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h
new file mode 100644
index 00000000000..d0aeda1cd9d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank N register and configuration 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.
+*/
+
+#define S3C64XX_GPNCON (S3C64XX_GPN_BASE + 0x00)
+#define S3C64XX_GPNDAT (S3C64XX_GPN_BASE + 0x04)
+#define S3C64XX_GPNPUD (S3C64XX_GPN_BASE + 0x08)
+
+#define S3C64XX_GPN_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPN_INPUT(__gpio) (0x0 << ((__gpio) * 2))
+#define S3C64XX_GPN_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPN0_EINT0 (0x02 << 0)
+#define S3C64XX_GPN0_KP_ROW0 (0x03 << 0)
+
+#define S3C64XX_GPN1_EINT1 (0x02 << 2)
+#define S3C64XX_GPN1_KP_ROW1 (0x03 << 2)
+
+#define S3C64XX_GPN2_EINT2 (0x02 << 4)
+#define S3C64XX_GPN2_KP_ROW2 (0x03 << 4)
+
+#define S3C64XX_GPN3_EINT3 (0x02 << 6)
+#define S3C64XX_GPN3_KP_ROW3 (0x03 << 6)
+
+#define S3C64XX_GPN4_EINT4 (0x02 << 8)
+#define S3C64XX_GPN4_KP_ROW4 (0x03 << 8)
+
+#define S3C64XX_GPN5_EINT5 (0x02 << 10)
+#define S3C64XX_GPN5_KP_ROW5 (0x03 << 10)
+
+#define S3C64XX_GPN6_EINT6 (0x02 << 12)
+#define S3C64XX_GPN6_KP_ROW6 (0x03 << 12)
+
+#define S3C64XX_GPN7_EINT7 (0x02 << 14)
+#define S3C64XX_GPN7_KP_ROW7 (0x03 << 14)
+
+#define S3C64XX_GPN8_EINT8 (0x02 << 16)
+#define S3C64XX_GPN9_EINT9 (0x02 << 18)
+#define S3C64XX_GPN10_EINT10 (0x02 << 20)
+#define S3C64XX_GPN11_EINT11 (0x02 << 22)
+#define S3C64XX_GPN12_EINT12 (0x02 << 24)
+#define S3C64XX_GPN13_EINT13 (0x02 << 26)
+#define S3C64XX_GPN14_EINT14 (0x02 << 28)
+#define S3C64XX_GPN15_EINT15 (0x02 << 30)
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h
new file mode 100644
index 00000000000..21868fa102d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h
@@ -0,0 +1,70 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank O register and configuration 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.
+*/
+
+#define S3C64XX_GPOCON (S3C64XX_GPO_BASE + 0x00)
+#define S3C64XX_GPODAT (S3C64XX_GPO_BASE + 0x04)
+#define S3C64XX_GPOPUD (S3C64XX_GPO_BASE + 0x08)
+#define S3C64XX_GPOCONSLP (S3C64XX_GPO_BASE + 0x0c)
+#define S3C64XX_GPOPUDSLP (S3C64XX_GPO_BASE + 0x10)
+
+#define S3C64XX_GPO_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPO_INPUT(__gpio) (0x0 << ((__gpio) * 2))
+#define S3C64XX_GPO_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPO0_MEM0_nCS2 (0x02 << 0)
+#define S3C64XX_GPO0_EINT_G7_0 (0x03 << 0)
+
+#define S3C64XX_GPO1_MEM0_nCS3 (0x02 << 2)
+#define S3C64XX_GPO1_EINT_G7_1 (0x03 << 2)
+
+#define S3C64XX_GPO2_MEM0_nCS4 (0x02 << 4)
+#define S3C64XX_GPO2_EINT_G7_2 (0x03 << 4)
+
+#define S3C64XX_GPO3_MEM0_nCS5 (0x02 << 6)
+#define S3C64XX_GPO3_EINT_G7_3 (0x03 << 6)
+
+#define S3C64XX_GPO4_EINT_G7_4 (0x03 << 8)
+
+#define S3C64XX_GPO5_EINT_G7_5 (0x03 << 10)
+
+#define S3C64XX_GPO6_MEM0_ADDR6 (0x02 << 12)
+#define S3C64XX_GPO6_EINT_G7_6 (0x03 << 12)
+
+#define S3C64XX_GPO7_MEM0_ADDR7 (0x02 << 14)
+#define S3C64XX_GPO7_EINT_G7_7 (0x03 << 14)
+
+#define S3C64XX_GPO8_MEM0_ADDR8 (0x02 << 16)
+#define S3C64XX_GPO8_EINT_G7_8 (0x03 << 16)
+
+#define S3C64XX_GPO9_MEM0_ADDR9 (0x02 << 18)
+#define S3C64XX_GPO9_EINT_G7_9 (0x03 << 18)
+
+#define S3C64XX_GPO10_MEM0_ADDR10 (0x02 << 20)
+#define S3C64XX_GPO10_EINT_G7_10 (0x03 << 20)
+
+#define S3C64XX_GPO11_MEM0_ADDR11 (0x02 << 22)
+#define S3C64XX_GPO11_EINT_G7_11 (0x03 << 22)
+
+#define S3C64XX_GPO12_MEM0_ADDR12 (0x02 << 24)
+#define S3C64XX_GPO12_EINT_G7_12 (0x03 << 24)
+
+#define S3C64XX_GPO13_MEM0_ADDR13 (0x02 << 26)
+#define S3C64XX_GPO13_EINT_G7_13 (0x03 << 26)
+
+#define S3C64XX_GPO14_MEM0_ADDR14 (0x02 << 28)
+#define S3C64XX_GPO14_EINT_G7_14 (0x03 << 28)
+
+#define S3C64XX_GPO15_MEM0_ADDR15 (0x02 << 30)
+#define S3C64XX_GPO15_EINT_G7_15 (0x03 << 30)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h
new file mode 100644
index 00000000000..46bcfb63b8d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank P register and configuration 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.
+*/
+
+#define S3C64XX_GPPCON (S3C64XX_GPP_BASE + 0x00)
+#define S3C64XX_GPPDAT (S3C64XX_GPP_BASE + 0x04)
+#define S3C64XX_GPPPUD (S3C64XX_GPP_BASE + 0x08)
+#define S3C64XX_GPPCONSLP (S3C64XX_GPP_BASE + 0x0c)
+#define S3C64XX_GPPPUDSLP (S3C64XX_GPP_BASE + 0x10)
+
+#define S3C64XX_GPP_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPP_INPUT(__gpio) (0x0 << ((__gpio) * 2))
+#define S3C64XX_GPP_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPP0_MEM0_ADDRV (0x02 << 0)
+#define S3C64XX_GPP0_EINT_G8_0 (0x03 << 0)
+
+#define S3C64XX_GPP1_MEM0_SMCLK (0x02 << 2)
+#define S3C64XX_GPP1_EINT_G8_1 (0x03 << 2)
+
+#define S3C64XX_GPP2_MEM0_nWAIT (0x02 << 4)
+#define S3C64XX_GPP2_EINT_G8_2 (0x03 << 4)
+
+#define S3C64XX_GPP3_MEM0_RDY0_ALE (0x02 << 6)
+#define S3C64XX_GPP3_EINT_G8_3 (0x03 << 6)
+
+#define S3C64XX_GPP4_MEM0_RDY1_CLE (0x02 << 8)
+#define S3C64XX_GPP4_EINT_G8_4 (0x03 << 8)
+
+#define S3C64XX_GPP5_MEM0_INTsm0_FWE (0x02 << 10)
+#define S3C64XX_GPP5_EINT_G8_5 (0x03 << 10)
+
+#define S3C64XX_GPP6_MEM0_(null) (0x02 << 12)
+#define S3C64XX_GPP6_EINT_G8_6 (0x03 << 12)
+
+#define S3C64XX_GPP7_MEM0_INTsm1_FRE (0x02 << 14)
+#define S3C64XX_GPP7_EINT_G8_7 (0x03 << 14)
+
+#define S3C64XX_GPP8_MEM0_RPn_RnB (0x02 << 16)
+#define S3C64XX_GPP8_EINT_G8_8 (0x03 << 16)
+
+#define S3C64XX_GPP9_MEM0_ATA_RESET (0x02 << 18)
+#define S3C64XX_GPP9_EINT_G8_9 (0x03 << 18)
+
+#define S3C64XX_GPP10_MEM0_ATA_INPACK (0x02 << 20)
+#define S3C64XX_GPP10_EINT_G8_10 (0x03 << 20)
+
+#define S3C64XX_GPP11_MEM0_ATA_REG (0x02 << 22)
+#define S3C64XX_GPP11_EINT_G8_11 (0x03 << 22)
+
+#define S3C64XX_GPP12_MEM0_ATA_WE (0x02 << 24)
+#define S3C64XX_GPP12_EINT_G8_12 (0x03 << 24)
+
+#define S3C64XX_GPP13_MEM0_ATA_OE (0x02 << 26)
+#define S3C64XX_GPP13_EINT_G8_13 (0x03 << 26)
+
+#define S3C64XX_GPP14_MEM0_ATA_CD (0x02 << 28)
+#define S3C64XX_GPP14_EINT_G8_14 (0x03 << 28)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h
new file mode 100644
index 00000000000..1712223487b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h
@@ -0,0 +1,46 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * GPIO Bank Q register and configuration 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.
+*/
+
+#define S3C64XX_GPQCON (S3C64XX_GPQ_BASE + 0x00)
+#define S3C64XX_GPQDAT (S3C64XX_GPQ_BASE + 0x04)
+#define S3C64XX_GPQPUD (S3C64XX_GPQ_BASE + 0x08)
+#define S3C64XX_GPQCONSLP (S3C64XX_GPQ_BASE + 0x0c)
+#define S3C64XX_GPQPUDSLP (S3C64XX_GPQ_BASE + 0x10)
+
+#define S3C64XX_GPQ_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPQ_INPUT(__gpio) (0x0 << ((__gpio) * 2))
+#define S3C64XX_GPQ_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+#define S3C64XX_GPQ0_MEM0_ADDR18_RAS (0x02 << 0)
+#define S3C64XX_GPQ0_EINT_G9_0 (0x03 << 0)
+
+#define S3C64XX_GPQ1_MEM0_ADDR19_CAS (0x02 << 2)
+#define S3C64XX_GPQ1_EINT_G9_1 (0x03 << 2)
+
+#define S3C64XX_GPQ2_EINT_G9_2 (0x03 << 4)
+
+#define S3C64XX_GPQ3_EINT_G9_3 (0x03 << 6)
+
+#define S3C64XX_GPQ4_EINT_G9_4 (0x03 << 8)
+
+#define S3C64XX_GPQ5_EINT_G9_5 (0x03 << 10)
+
+#define S3C64XX_GPQ6_EINT_G9_6 (0x03 << 12)
+
+#define S3C64XX_GPQ7_MEM0_ADDR17_WENDMC (0x02 << 14)
+#define S3C64XX_GPQ7_EINT_G9_7 (0x03 << 14)
+
+#define S3C64XX_GPQ8_MEM0_ADDR16_APDMC (0x02 << 16)
+#define S3C64XX_GPQ8_EINT_G9_8 (0x03 << 16)
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio.h b/arch/arm/mach-s3c64xx/include/mach/gpio.h
new file mode 100644
index 00000000000..0d46e994048
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio.h
@@ -0,0 +1,100 @@
+/* arch/arm/mach-s3c6400/include/mach/gpio.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#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
+
+/* GPIO bank sizes */
+#define S3C64XX_GPIO_A_NR (8)
+#define S3C64XX_GPIO_B_NR (7)
+#define S3C64XX_GPIO_C_NR (8)
+#define S3C64XX_GPIO_D_NR (5)
+#define S3C64XX_GPIO_E_NR (5)
+#define S3C64XX_GPIO_F_NR (16)
+#define S3C64XX_GPIO_G_NR (7)
+#define S3C64XX_GPIO_H_NR (10)
+#define S3C64XX_GPIO_I_NR (16)
+#define S3C64XX_GPIO_J_NR (12)
+#define S3C64XX_GPIO_K_NR (16)
+#define S3C64XX_GPIO_L_NR (15)
+#define S3C64XX_GPIO_M_NR (6)
+#define S3C64XX_GPIO_N_NR (16)
+#define S3C64XX_GPIO_O_NR (16)
+#define S3C64XX_GPIO_P_NR (15)
+#define S3C64XX_GPIO_Q_NR (9)
+
+/* GPIO bank numbes */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S3C64XX_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s3c_gpio_number {
+ S3C64XX_GPIO_A_START = 0,
+ S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),
+ S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),
+ S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),
+ S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),
+ S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),
+ S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),
+ S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),
+ S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),
+ S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),
+ S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),
+ S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),
+ S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),
+ S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),
+ S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),
+ S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),
+ S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),
+};
+
+/* S3C64XX GPIO number definitions. */
+
+#define S3C64XX_GPA(_nr) (S3C64XX_GPIO_A_START + (_nr))
+#define S3C64XX_GPB(_nr) (S3C64XX_GPIO_B_START + (_nr))
+#define S3C64XX_GPC(_nr) (S3C64XX_GPIO_C_START + (_nr))
+#define S3C64XX_GPD(_nr) (S3C64XX_GPIO_D_START + (_nr))
+#define S3C64XX_GPE(_nr) (S3C64XX_GPIO_E_START + (_nr))
+#define S3C64XX_GPF(_nr) (S3C64XX_GPIO_F_START + (_nr))
+#define S3C64XX_GPG(_nr) (S3C64XX_GPIO_G_START + (_nr))
+#define S3C64XX_GPH(_nr) (S3C64XX_GPIO_H_START + (_nr))
+#define S3C64XX_GPI(_nr) (S3C64XX_GPIO_I_START + (_nr))
+#define S3C64XX_GPJ(_nr) (S3C64XX_GPIO_J_START + (_nr))
+#define S3C64XX_GPK(_nr) (S3C64XX_GPIO_K_START + (_nr))
+#define S3C64XX_GPL(_nr) (S3C64XX_GPIO_L_START + (_nr))
+#define S3C64XX_GPM(_nr) (S3C64XX_GPIO_M_START + (_nr))
+#define S3C64XX_GPN(_nr) (S3C64XX_GPIO_N_START + (_nr))
+#define S3C64XX_GPO(_nr) (S3C64XX_GPIO_O_START + (_nr))
+#define S3C64XX_GPP(_nr) (S3C64XX_GPIO_P_START + (_nr))
+#define S3C64XX_GPQ(_nr) (S3C64XX_GPIO_Q_START + (_nr))
+
+/* the end of the S3C64XX specific gpios */
+#define S3C64XX_GPIO_END (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
+#define S3C_GPIO_END S3C64XX_GPIO_END
+
+/* define the number of gpios we need to the one after the GPQ() range */
+#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
+
+#define BOARD_NR_GPIOS 16
+
+#define ARCH_NR_GPIOS (GPIO_BOARD_START + BOARD_NR_GPIOS)
+
+#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-s3c6400/include/mach/hardware.h b/arch/arm/mach-s3c64xx/include/mach/hardware.h
index 862d033e57a..862d033e57a 100644
--- a/arch/arm/mach-s3c6400/include/mach/hardware.h
+++ b/arch/arm/mach-s3c64xx/include/mach/hardware.h
diff --git a/arch/arm/mach-s3c64xx/include/mach/io.h b/arch/arm/mach-s3c64xx/include/mach/io.h
new file mode 100644
index 00000000000..de5716dbbd6
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/io.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c64xxinclude/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S3C64XX based
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h
new file mode 100644
index 00000000000..e9ab4ac0b9a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h
@@ -0,0 +1,216 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/irqs.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - IRQ support
+ */
+
+#ifndef __ASM_MACH_S3C64XX_IRQS_H
+#define __ASM_MACH_S3C64XX_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S3C_IRQ_OFFSET (32)
+
+#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET)
+
+#define IRQ_VIC0_BASE S3C_IRQ(0)
+#define IRQ_VIC1_BASE S3C_IRQ(32)
+
+/* UART interrupts, each UART has 4 intterupts per channel so
+ * use the space between the ISA and S3C main interrupts. Note, these
+ * are not in the same order as the S3C24XX series! */
+
+#define IRQ_S3CUART_BASE0 (16)
+#define IRQ_S3CUART_BASE1 (20)
+#define IRQ_S3CUART_BASE2 (24)
+#define IRQ_S3CUART_BASE3 (28)
+
+#define UART_IRQ_RXD (0)
+#define UART_IRQ_ERR (1)
+#define UART_IRQ_TXD (2)
+#define UART_IRQ_MODEM (3)
+
+#define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
+
+/* VIC based IRQs */
+
+#define S3C64XX_IRQ_VIC0(x) (IRQ_VIC0_BASE + (x))
+#define S3C64XX_IRQ_VIC1(x) (IRQ_VIC1_BASE + (x))
+
+/* VIC0 */
+
+#define IRQ_EINT0_3 S3C64XX_IRQ_VIC0(0)
+#define IRQ_EINT4_11 S3C64XX_IRQ_VIC0(1)
+#define IRQ_RTC_TIC S3C64XX_IRQ_VIC0(2)
+#define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3)
+#define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4)
+#define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIC1 S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6)
+#define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6)
+#define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7)
+#define IRQ_S3C6410_G3D S3C64XX_IRQ_VIC0(8)
+#define IRQ_S3C6400_CAMIF_WE_P S3C64XX_IRQ_VIC0(8)
+#define IRQ_POST0 S3C64XX_IRQ_VIC0(9)
+#define IRQ_ROTATOR S3C64XX_IRQ_VIC0(10)
+#define IRQ_2D S3C64XX_IRQ_VIC0(11)
+#define IRQ_TVENC S3C64XX_IRQ_VIC0(12)
+#define IRQ_SCALER S3C64XX_IRQ_VIC0(13)
+#define IRQ_BATF S3C64XX_IRQ_VIC0(14)
+#define IRQ_JPEG S3C64XX_IRQ_VIC0(15)
+#define IRQ_MFC S3C64XX_IRQ_VIC0(16)
+#define IRQ_SDMA0 S3C64XX_IRQ_VIC0(17)
+#define IRQ_SDMA1 S3C64XX_IRQ_VIC0(18)
+#define IRQ_ARM_DMAERR S3C64XX_IRQ_VIC0(19)
+#define IRQ_ARM_DMA S3C64XX_IRQ_VIC0(20)
+#define IRQ_ARM_DMAS S3C64XX_IRQ_VIC0(21)
+#define IRQ_KEYPAD S3C64XX_IRQ_VIC0(22)
+#define IRQ_TIMER0_VIC S3C64XX_IRQ_VIC0(23)
+#define IRQ_TIMER1_VIC S3C64XX_IRQ_VIC0(24)
+#define IRQ_TIMER2_VIC S3C64XX_IRQ_VIC0(25)
+#define IRQ_WDT S3C64XX_IRQ_VIC0(26)
+#define IRQ_TIMER3_VIC S3C64XX_IRQ_VIC0(27)
+#define IRQ_TIMER4_VIC S3C64XX_IRQ_VIC0(28)
+#define IRQ_LCD_FIFO S3C64XX_IRQ_VIC0(29)
+#define IRQ_LCD_VSYNC S3C64XX_IRQ_VIC0(30)
+#define IRQ_LCD_SYSTEM S3C64XX_IRQ_VIC0(31)
+
+/* VIC1 */
+
+#define IRQ_EINT12_19 S3C64XX_IRQ_VIC1(0)
+#define IRQ_EINT20_27 S3C64XX_IRQ_VIC1(1)
+#define IRQ_PCM0 S3C64XX_IRQ_VIC1(2)
+#define IRQ_PCM1 S3C64XX_IRQ_VIC1(3)
+#define IRQ_AC97 S3C64XX_IRQ_VIC1(4)
+#define IRQ_UART0 S3C64XX_IRQ_VIC1(5)
+#define IRQ_UART1 S3C64XX_IRQ_VIC1(6)
+#define IRQ_UART2 S3C64XX_IRQ_VIC1(7)
+#define IRQ_UART3 S3C64XX_IRQ_VIC1(8)
+#define IRQ_DMA0 S3C64XX_IRQ_VIC1(9)
+#define IRQ_DMA1 S3C64XX_IRQ_VIC1(10)
+#define IRQ_ONENAND0 S3C64XX_IRQ_VIC1(11)
+#define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12)
+#define IRQ_NFC S3C64XX_IRQ_VIC1(13)
+#define IRQ_CFCON S3C64XX_IRQ_VIC1(14)
+#define IRQ_USBH S3C64XX_IRQ_VIC1(15)
+#define IRQ_SPI0 S3C64XX_IRQ_VIC1(16)
+#define IRQ_SPI1 S3C64XX_IRQ_VIC1(17)
+#define IRQ_IIC S3C64XX_IRQ_VIC1(18)
+#define IRQ_HSItx S3C64XX_IRQ_VIC1(19)
+#define IRQ_HSIrx S3C64XX_IRQ_VIC1(20)
+#define IRQ_RESERVED S3C64XX_IRQ_VIC1(21)
+#define IRQ_MSM S3C64XX_IRQ_VIC1(22)
+#define IRQ_HOSTIF S3C64XX_IRQ_VIC1(23)
+#define IRQ_HSMMC0 S3C64XX_IRQ_VIC1(24)
+#define IRQ_HSMMC1 S3C64XX_IRQ_VIC1(25)
+#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */
+#define IRQ_OTG S3C64XX_IRQ_VIC1(26)
+#define IRQ_IRDA S3C64XX_IRQ_VIC1(27)
+#define IRQ_RTC_ALARM S3C64XX_IRQ_VIC1(28)
+#define IRQ_SEC S3C64XX_IRQ_VIC1(29)
+#define IRQ_PENDN S3C64XX_IRQ_VIC1(30)
+#define IRQ_TC IRQ_PENDN
+#define IRQ_ADC S3C64XX_IRQ_VIC1(31)
+
+#define S3C64XX_TIMER_IRQ(x) S3C_IRQ(64 + (x))
+
+#define IRQ_TIMER0 S3C64XX_TIMER_IRQ(0)
+#define IRQ_TIMER1 S3C64XX_TIMER_IRQ(1)
+#define IRQ_TIMER2 S3C64XX_TIMER_IRQ(2)
+#define IRQ_TIMER3 S3C64XX_TIMER_IRQ(3)
+#define IRQ_TIMER4 S3C64XX_TIMER_IRQ(4)
+
+/* compatibility for device defines */
+
+#define IRQ_IIC1 IRQ_S3C6410_IIC1
+
+/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
+ * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
+ * which we place after the pair of VICs. */
+
+#define S3C_IRQ_EINT_BASE S3C_IRQ(64+5)
+
+#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
+#define IRQ_EINT(x) S3C_EINT(x)
+#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0))
+
+/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
+ * that they are sourced from the GPIO pins but with a different scheme for
+ * priority and source indication.
+ *
+ * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
+ * interrupts, but for historical reasons they are kept apart from these
+ * next interrupts.
+ *
+ * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
+ * machine specific support files.
+ */
+
+#define IRQ_EINT_GROUP1_NR (15)
+#define IRQ_EINT_GROUP2_NR (8)
+#define IRQ_EINT_GROUP3_NR (5)
+#define IRQ_EINT_GROUP4_NR (14)
+#define IRQ_EINT_GROUP5_NR (7)
+#define IRQ_EINT_GROUP6_NR (10)
+#define IRQ_EINT_GROUP7_NR (16)
+#define IRQ_EINT_GROUP8_NR (15)
+#define IRQ_EINT_GROUP9_NR (9)
+
+#define IRQ_EINT_GROUP_BASE S3C_EINT(28)
+#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0x00)
+#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
+#define IRQ_EINT_GROUP3_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
+#define IRQ_EINT_GROUP4_BASE (IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
+#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
+#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
+#define IRQ_EINT_GROUP7_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
+#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
+#define IRQ_EINT_GROUP9_BASE (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
+
+#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##_BASE + (no))
+
+/* Define a group of interrupts for board-specific use (eg, for MFD
+ * interrupt controllers). */
+#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+#define IRQ_BOARD_NR 64
+#elif defined(CONFIG_SMDK6410_WM1192_EV1)
+#define IRQ_BOARD_NR 64
+#else
+#define IRQ_BOARD_NR 16
+#endif
+
+#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS (IRQ_BOARD_END + 1)
+
+#endif /* __ASM_MACH_S3C64XX_IRQS_H */
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
new file mode 100644
index 00000000000..801c1c0f3a9
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -0,0 +1,107 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/map.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+
+/*
+ * Post-mux Chip Select Regions Xm0CSn_
+ * These may be used by SROM, NAND or CF depending on settings
+ */
+
+#define S3C64XX_PA_XM0CSN0 (0x10000000)
+#define S3C64XX_PA_XM0CSN1 (0x18000000)
+#define S3C64XX_PA_XM0CSN2 (0x20000000)
+#define S3C64XX_PA_XM0CSN3 (0x28000000)
+#define S3C64XX_PA_XM0CSN4 (0x30000000)
+#define S3C64XX_PA_XM0CSN5 (0x38000000)
+
+/* HSMMC units */
+#define S3C64XX_PA_HSMMC(x) (0x7C200000 + ((x) * 0x100000))
+#define S3C64XX_PA_HSMMC0 S3C64XX_PA_HSMMC(0)
+#define S3C64XX_PA_HSMMC1 S3C64XX_PA_HSMMC(1)
+#define S3C64XX_PA_HSMMC2 S3C64XX_PA_HSMMC(2)
+
+#define S3C_PA_UART (0x7F005000)
+#define S3C_PA_UART0 (S3C_PA_UART + 0x00)
+#define S3C_PA_UART1 (S3C_PA_UART + 0x400)
+#define S3C_PA_UART2 (S3C_PA_UART + 0x800)
+#define S3C_PA_UART3 (S3C_PA_UART + 0xC00)
+#define S3C_UART_OFFSET (0x400)
+
+/* See notes on UART VA mapping in debug-macro.S */
+#define S3C_VA_UARTx(x) (S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET))
+
+#define S3C_VA_UART0 S3C_VA_UARTx(0)
+#define S3C_VA_UART1 S3C_VA_UARTx(1)
+#define S3C_VA_UART2 S3C_VA_UARTx(2)
+#define S3C_VA_UART3 S3C_VA_UARTx(3)
+
+#define S3C64XX_PA_SROM (0x70000000)
+
+#define S3C64XX_PA_NAND (0x70200000)
+#define S3C64XX_PA_FB (0x77100000)
+#define S3C64XX_PA_USB_HSOTG (0x7C000000)
+#define S3C64XX_PA_WATCHDOG (0x7E004000)
+#define S3C64XX_PA_RTC (0x7E005000)
+#define S3C64XX_PA_ADC (0x7E00B000)
+#define S3C64XX_PA_SYSCON (0x7E00F000)
+#define S3C64XX_PA_AC97 (0x7F001000)
+#define S3C64XX_PA_IIS0 (0x7F002000)
+#define S3C64XX_PA_IIS1 (0x7F003000)
+#define S3C64XX_PA_TIMER (0x7F006000)
+#define S3C64XX_PA_IIC0 (0x7F004000)
+#define S3C64XX_PA_SPI0 (0x7F00B000)
+#define S3C64XX_PA_SPI1 (0x7F00C000)
+#define S3C64XX_PA_PCM0 (0x7F009000)
+#define S3C64XX_PA_PCM1 (0x7F00A000)
+#define S3C64XX_PA_IISV4 (0x7F00D000)
+#define S3C64XX_PA_IIC1 (0x7F00F000)
+
+#define S3C64XX_PA_GPIO (0x7F008000)
+#define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000)
+#define S3C64XX_SZ_GPIO SZ_4K
+
+#define S3C64XX_PA_SDRAM (0x50000000)
+#define S3C64XX_PA_VIC0 (0x71200000)
+#define S3C64XX_PA_VIC1 (0x71300000)
+
+#define S3C64XX_PA_MODEM (0x74108000)
+#define S3C64XX_VA_MODEM S3C_ADDR_CPU(0x00100000)
+
+#define S3C64XX_PA_USBHOST (0x74300000)
+
+#define S3C64XX_PA_USB_HSPHY (0x7C100000)
+#define S3C64XX_VA_USB_HSPHY S3C_ADDR_CPU(0x00200000)
+
+/* place VICs close together */
+#define VA_VIC0 (S3C_VA_IRQ + 0x00)
+#define VA_VIC1 (S3C_VA_IRQ + 0x10000)
+
+/* compatibiltiy defines. */
+#define S3C_PA_TIMER S3C64XX_PA_TIMER
+#define S3C_PA_HSMMC0 S3C64XX_PA_HSMMC0
+#define S3C_PA_HSMMC1 S3C64XX_PA_HSMMC1
+#define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2
+#define S3C_PA_IIC S3C64XX_PA_IIC0
+#define S3C_PA_IIC1 S3C64XX_PA_IIC1
+#define S3C_PA_NAND S3C64XX_PA_NAND
+#define S3C_PA_FB S3C64XX_PA_FB
+#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
+#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
+#define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY
+
+#endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/memory.h b/arch/arm/mach-s3c64xx/include/mach/memory.h
index a3ac84a6548..a3ac84a6548 100644
--- a/arch/arm/mach-s3c6400/include/mach/memory.h
+++ b/arch/arm/mach-s3c64xx/include/mach/memory.h
diff --git a/arch/arm/plat-s3c64xx/include/plat/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h
index 90bbd72fdc4..90bbd72fdc4 100644
--- a/arch/arm/plat-s3c64xx/include/plat/pll.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pll.h
diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
new file mode 100644
index 00000000000..1e9f20f0bb7
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -0,0 +1,98 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - PM core support for arch/arm/plat-s3c/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/regs-gpio.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ u32 tmp = __raw_readl(S3C_PCLK_GATE);
+
+ /* As a note, since the S3C64XX UARTs generally have multiple
+ * clock sources, we simply enable PCLK at the moment and hope
+ * that the resume settings for the UART are suitable for the
+ * use with PCLK.
+ */
+
+ tmp |= S3C_CLKCON_PCLK_UART0;
+ tmp |= S3C_CLKCON_PCLK_UART1;
+ tmp |= S3C_CLKCON_PCLK_UART2;
+ tmp |= S3C_CLKCON_PCLK_UART3;
+
+ __raw_writel(tmp, S3C_PCLK_GATE);
+ udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ /* VIC should have already been taken care of */
+
+ /* clear any pending EINT0 interrupts */
+ __raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+}
+
+/* make these defines, we currently do not have any need to change
+ * the IRQ wake controls depending on the CPU we are running on */
+
+#define s3c_irqwake_eintallow ((1 << 28) - 1)
+#define s3c_irqwake_intallow (0)
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+ u32 ucon = __raw_readl(regs + S3C2410_UCON);
+ u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
+ u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
+ u32 new_ucon;
+ u32 delta;
+
+ /* S3C64XX UART blocks only support level interrupts, so ensure that
+ * when we restore unused UART blocks we force the level interrupt
+ * settigs. */
+ save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
+
+ /* We have a constraint on changing the clock type of the UART
+ * between UCLKx and PCLK, so ensure that when we restore UCON
+ * that the CLK field is correctly modified if the bootloader
+ * has changed anything.
+ */
+ if (ucon_clk != save_clk) {
+ new_ucon = save->ucon;
+ delta = ucon_clk ^ save_clk;
+
+ /* change from UCLKx => wrong PCLK,
+ * either UCLK can be tested for by a bit-test
+ * with UCLK0 */
+ if (ucon_clk & S3C6400_UCON_UCLK0 &&
+ !(save_clk & S3C6400_UCON_UCLK0) &&
+ delta & S3C6400_UCON_PCLK2) {
+ new_ucon &= ~S3C6400_UCON_UCLK0;
+ } else if (delta == S3C6400_UCON_PCLK2) {
+ /* as an precaution, don't change from
+ * PCLK2 => PCLK or vice-versa */
+ new_ucon ^= S3C6400_UCON_PCLK2;
+ }
+
+ S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
+ ucon, new_ucon, save->ucon);
+ save->ucon = new_ucon;
+ }
+}
diff --git a/arch/arm/mach-s3c6400/include/mach/pwm-clock.h b/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
index b25bedee0d5..b25bedee0d5 100644
--- a/arch/arm/mach-s3c6400/include/mach/pwm-clock.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
new file mode 100644
index 00000000000..3ef62741e5d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
@@ -0,0 +1,156 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-clock.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_REGS_CLOCK_H
+#define __PLAT_REGS_CLOCK_H __FILE__
+
+#define S3C_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S3C_APLL_LOCK S3C_CLKREG(0x00)
+#define S3C_MPLL_LOCK S3C_CLKREG(0x04)
+#define S3C_EPLL_LOCK S3C_CLKREG(0x08)
+#define S3C_APLL_CON S3C_CLKREG(0x0C)
+#define S3C_MPLL_CON S3C_CLKREG(0x10)
+#define S3C_EPLL_CON0 S3C_CLKREG(0x14)
+#define S3C_EPLL_CON1 S3C_CLKREG(0x18)
+#define S3C_CLK_SRC S3C_CLKREG(0x1C)
+#define S3C_CLK_DIV0 S3C_CLKREG(0x20)
+#define S3C_CLK_DIV1 S3C_CLKREG(0x24)
+#define S3C_CLK_DIV2 S3C_CLKREG(0x28)
+#define S3C_CLK_OUT S3C_CLKREG(0x2C)
+#define S3C_HCLK_GATE S3C_CLKREG(0x30)
+#define S3C_PCLK_GATE S3C_CLKREG(0x34)
+#define S3C_SCLK_GATE S3C_CLKREG(0x38)
+#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
+
+/* CLKDIV0 */
+#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
+#define S3C6400_CLKDIV0_PCLK_SHIFT (12)
+#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9)
+#define S3C6400_CLKDIV0_HCLK2_SHIFT (9)
+#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8)
+#define S3C6400_CLKDIV0_HCLK_SHIFT (8)
+#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4)
+#define S3C6400_CLKDIV0_MPLL_SHIFT (4)
+
+#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0)
+#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0)
+#define S3C6400_CLKDIV0_ARM_SHIFT (0)
+
+/* HCLK GATE Registers */
+#define S3C_CLKCON_HCLK_3DSE (1<<31)
+#define S3C_CLKCON_HCLK_UHOST (1<<29)
+#define S3C_CLKCON_HCLK_SECUR (1<<28)
+#define S3C_CLKCON_HCLK_SDMA1 (1<<27)
+#define S3C_CLKCON_HCLK_SDMA0 (1<<26)
+#define S3C_CLKCON_HCLK_IROM (1<<25)
+#define S3C_CLKCON_HCLK_DDR1 (1<<24)
+#define S3C_CLKCON_HCLK_DDR0 (1<<23)
+#define S3C_CLKCON_HCLK_MEM1 (1<<22)
+#define S3C_CLKCON_HCLK_MEM0 (1<<21)
+#define S3C_CLKCON_HCLK_USB (1<<20)
+#define S3C_CLKCON_HCLK_HSMMC2 (1<<19)
+#define S3C_CLKCON_HCLK_HSMMC1 (1<<18)
+#define S3C_CLKCON_HCLK_HSMMC0 (1<<17)
+#define S3C_CLKCON_HCLK_MDP (1<<16)
+#define S3C_CLKCON_HCLK_DHOST (1<<15)
+#define S3C_CLKCON_HCLK_IHOST (1<<14)
+#define S3C_CLKCON_HCLK_DMA1 (1<<13)
+#define S3C_CLKCON_HCLK_DMA0 (1<<12)
+#define S3C_CLKCON_HCLK_JPEG (1<<11)
+#define S3C_CLKCON_HCLK_CAMIF (1<<10)
+#define S3C_CLKCON_HCLK_SCALER (1<<9)
+#define S3C_CLKCON_HCLK_2D (1<<8)
+#define S3C_CLKCON_HCLK_TV (1<<7)
+#define S3C_CLKCON_HCLK_POST0 (1<<5)
+#define S3C_CLKCON_HCLK_ROT (1<<4)
+#define S3C_CLKCON_HCLK_LCD (1<<3)
+#define S3C_CLKCON_HCLK_TZIC (1<<2)
+#define S3C_CLKCON_HCLK_INTC (1<<1)
+#define S3C_CLKCON_HCLK_MFC (1<<0)
+
+/* PCLK GATE Registers */
+#define S3C6410_CLKCON_PCLK_I2C1 (1<<27)
+#define S3C6410_CLKCON_PCLK_IIS2 (1<<26)
+#define S3C_CLKCON_PCLK_SKEY (1<<24)
+#define S3C_CLKCON_PCLK_CHIPID (1<<23)
+#define S3C_CLKCON_PCLK_SPI1 (1<<22)
+#define S3C_CLKCON_PCLK_SPI0 (1<<21)
+#define S3C_CLKCON_PCLK_HSIRX (1<<20)
+#define S3C_CLKCON_PCLK_HSITX (1<<19)
+#define S3C_CLKCON_PCLK_GPIO (1<<18)
+#define S3C_CLKCON_PCLK_IIC (1<<17)
+#define S3C_CLKCON_PCLK_IIS1 (1<<16)
+#define S3C_CLKCON_PCLK_IIS0 (1<<15)
+#define S3C_CLKCON_PCLK_AC97 (1<<14)
+#define S3C_CLKCON_PCLK_TZPC (1<<13)
+#define S3C_CLKCON_PCLK_TSADC (1<<12)
+#define S3C_CLKCON_PCLK_KEYPAD (1<<11)
+#define S3C_CLKCON_PCLK_IRDA (1<<10)
+#define S3C_CLKCON_PCLK_PCM1 (1<<9)
+#define S3C_CLKCON_PCLK_PCM0 (1<<8)
+#define S3C_CLKCON_PCLK_PWM (1<<7)
+#define S3C_CLKCON_PCLK_RTC (1<<6)
+#define S3C_CLKCON_PCLK_WDT (1<<5)
+#define S3C_CLKCON_PCLK_UART3 (1<<4)
+#define S3C_CLKCON_PCLK_UART2 (1<<3)
+#define S3C_CLKCON_PCLK_UART1 (1<<2)
+#define S3C_CLKCON_PCLK_UART0 (1<<1)
+#define S3C_CLKCON_PCLK_MFC (1<<0)
+
+/* SCLK GATE Registers */
+#define S3C_CLKCON_SCLK_UHOST (1<<30)
+#define S3C_CLKCON_SCLK_MMC2_48 (1<<29)
+#define S3C_CLKCON_SCLK_MMC1_48 (1<<28)
+#define S3C_CLKCON_SCLK_MMC0_48 (1<<27)
+#define S3C_CLKCON_SCLK_MMC2 (1<<26)
+#define S3C_CLKCON_SCLK_MMC1 (1<<25)
+#define S3C_CLKCON_SCLK_MMC0 (1<<24)
+#define S3C_CLKCON_SCLK_SPI1_48 (1<<23)
+#define S3C_CLKCON_SCLK_SPI0_48 (1<<22)
+#define S3C_CLKCON_SCLK_SPI1 (1<<21)
+#define S3C_CLKCON_SCLK_SPI0 (1<<20)
+#define S3C_CLKCON_SCLK_DAC27 (1<<19)
+#define S3C_CLKCON_SCLK_TV27 (1<<18)
+#define S3C_CLKCON_SCLK_SCALER27 (1<<17)
+#define S3C_CLKCON_SCLK_SCALER (1<<16)
+#define S3C_CLKCON_SCLK_LCD27 (1<<15)
+#define S3C_CLKCON_SCLK_LCD (1<<14)
+#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13)
+#define S3C6410_CLKCON_FIMC (1<<13)
+#define S3C_CLKCON_SCLK_POST0_27 (1<<12)
+#define S3C6400_CLKCON_SCLK_POST1 (1<<11)
+#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11)
+#define S3C_CLKCON_SCLK_POST0 (1<<10)
+#define S3C_CLKCON_SCLK_AUDIO1 (1<<9)
+#define S3C_CLKCON_SCLK_AUDIO0 (1<<8)
+#define S3C_CLKCON_SCLK_SECUR (1<<7)
+#define S3C_CLKCON_SCLK_IRDA (1<<6)
+#define S3C_CLKCON_SCLK_UART (1<<5)
+#define S3C_CLKCON_SCLK_ONENAND (1<<4)
+#define S3C_CLKCON_SCLK_MFC (1<<3)
+#define S3C_CLKCON_SCLK_CAM (1<<2)
+#define S3C_CLKCON_SCLK_JPEG (1<<1)
+
+/* CLKSRC */
+
+#define S3C6400_CLKSRC_APLL_MOUT (1 << 0)
+#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1)
+#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2)
+#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0)
+#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1)
+#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
+#define S3C6400_CLKSRC_MFC (1 << 4)
+
+#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/regs-fb.h b/arch/arm/mach-s3c64xx/include/mach/regs-fb.h
index f56611526c6..f56611526c6 100644
--- a/arch/arm/mach-s3c6400/include/mach/regs-fb.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-fb.h
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h b/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h
index 82342f6fd27..82342f6fd27 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h
index 81f7f6e6832..81f7f6e6832 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h
diff --git a/arch/arm/mach-s3c6400/include/mach/regs-irq.h b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h
index bcce68a0bb7..bcce68a0bb7 100644
--- a/arch/arm/mach-s3c6400/include/mach/regs-irq.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-modem.h b/arch/arm/mach-s3c64xx/include/mach/regs-modem.h
index 49f7759dedf..49f7759dedf 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-modem.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-modem.h
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-srom.h b/arch/arm/mach-s3c64xx/include/mach/regs-srom.h
new file mode 100644
index 00000000000..756731b3629
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-srom.h
@@ -0,0 +1,59 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-srom.h
+ *
+ * Copyright 2009 Andy Green <andy@warmcat.com>
+ *
+ * S3C64XX SROM definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_REGS_SROM_H
+#define __PLAT_REGS_SROM_H __FILE__
+
+#define S3C64XX_SROMREG(x) (S3C_VA_MEM + (x))
+
+#define S3C64XX_SROM_BW S3C64XX_SROMREG(0)
+#define S3C64XX_SROM_BC0 S3C64XX_SROMREG(4)
+#define S3C64XX_SROM_BC1 S3C64XX_SROMREG(8)
+#define S3C64XX_SROM_BC2 S3C64XX_SROMREG(0xc)
+#define S3C64XX_SROM_BC3 S3C64XX_SROMREG(0x10)
+#define S3C64XX_SROM_BC4 S3C64XX_SROMREG(0x14)
+#define S3C64XX_SROM_BC5 S3C64XX_SROMREG(0x18)
+
+/*
+ * one register BW holds 5 x 4-bit packed settings for NCS0 - NCS4
+ */
+
+#define S3C64XX_SROM_BW__DATAWIDTH__SHIFT 0
+#define S3C64XX_SROM_BW__WAITENABLE__SHIFT 2
+#define S3C64XX_SROM_BW__BYTEENABLE__SHIFT 3
+#define S3C64XX_SROM_BW__CS_MASK 0xf
+
+#define S3C64XX_SROM_BW__NCS0__SHIFT 0
+#define S3C64XX_SROM_BW__NCS1__SHIFT 4
+#define S3C64XX_SROM_BW__NCS2__SHIFT 8
+#define S3C64XX_SROM_BW__NCS3__SHIFT 0xc
+#define S3C64XX_SROM_BW__NCS4__SHIFT 0x10
+
+/*
+ * applies to same to BCS0 - BCS4
+ */
+
+#define S3C64XX_SROM_BCX__PMC__SHIFT 0
+#define S3C64XX_SROM_BCX__PMC__MASK 3
+#define S3C64XX_SROM_BCX__TACP__SHIFT 4
+#define S3C64XX_SROM_BCX__TACP__MASK 0xf
+#define S3C64XX_SROM_BCX__TCAH__SHIFT 8
+#define S3C64XX_SROM_BCX__TCAH__MASK 0xf
+#define S3C64XX_SROM_BCX__TCOH__SHIFT 12
+#define S3C64XX_SROM_BCX__TCOH__MASK 0xf
+#define S3C64XX_SROM_BCX__TACC__SHIFT 16
+#define S3C64XX_SROM_BCX__TACC__MASK 0x1f
+#define S3C64XX_SROM_BCX__TCOS__SHIFT 24
+#define S3C64XX_SROM_BCX__TCOS__MASK 0xf
+#define S3C64XX_SROM_BCX__TACS__SHIFT 28
+#define S3C64XX_SROM_BCX__TACS__MASK 0xf
+
+#endif /* _PLAT_REGS_SROM_H */
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-sys.h b/arch/arm/mach-s3c64xx/include/mach/regs-sys.h
index 69b78d9f83b..69b78d9f83b 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-sys.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-sys.h
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h b/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h
index 270d96ac970..270d96ac970 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h
diff --git a/arch/arm/mach-s3c64xx/include/mach/s3c6400.h b/arch/arm/mach-s3c64xx/include/mach/s3c6400.h
new file mode 100644
index 00000000000..f86958d0535
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/s3c6400.h
@@ -0,0 +1,36 @@
+/* arch/arm/mach-s3c64xx/include/macht/s3c6400.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Header file for s3c6400 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S3C6400 related SoCs */
+
+extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c6400_setup_clocks(void);
+
+extern void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
+
+#ifdef CONFIG_CPU_S3C6400
+
+extern int s3c6400_init(void);
+extern void s3c6400_init_irq(void);
+extern void s3c6400_map_io(void);
+extern void s3c6400_init_clocks(int xtal);
+
+#define s3c6400_init_uarts s3c6400_common_init_uarts
+
+#else
+#define s3c6400_init_clocks NULL
+#define s3c6400_init_uarts NULL
+#define s3c6400_map_io NULL
+#define s3c6400_init NULL
+#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/s3c6410.h b/arch/arm/mach-s3c64xx/include/mach/s3c6410.h
new file mode 100644
index 00000000000..24f1141ffcb
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/s3c6410.h
@@ -0,0 +1,29 @@
+/* arch/arm/mach-s3c64xx/include/mach/s3c6410.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Header file for s3c6410 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifdef CONFIG_CPU_S3C6410
+
+extern int s3c6410_init(void);
+extern void s3c6410_init_irq(void);
+extern void s3c6410_map_io(void);
+extern void s3c6410_init_clocks(int xtal);
+
+#define s3c6410_init_uarts s3c6400_common_init_uarts
+
+#else
+#define s3c6410_init_clocks NULL
+#define s3c6410_init_uarts NULL
+#define s3c6410_map_io NULL
+#define s3c6410_init NULL
+#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h b/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h
new file mode 100644
index 00000000000..9d0c43b4b68
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h
+ *
+ * Copyright (C) 2009 Samsung Electronics Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __S3C64XX_PLAT_SPI_CLKS_H
+#define __S3C64XX_PLAT_SPI_CLKS_H __FILE__
+
+#define S3C64XX_SPI_SRCCLK_PCLK 0
+#define S3C64XX_SPI_SRCCLK_SPIBUS 1
+#define S3C64XX_SPI_SRCCLK_48M 2
+
+#endif /* __S3C64XX_PLAT_SPI_CLKS_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/system.h b/arch/arm/mach-s3c64xx/include/mach/system.h
index 2e58cb7a714..2e58cb7a714 100644
--- a/arch/arm/mach-s3c6400/include/mach/system.h
+++ b/arch/arm/mach-s3c64xx/include/mach/system.h
diff --git a/arch/arm/mach-s3c64xx/include/mach/tick.h b/arch/arm/mach-s3c64xx/include/mach/tick.h
new file mode 100644
index 00000000000..ebe18a9469b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/tick.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/tick.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+/* note, the timer interrutps turn up in 2 places, the vic and then
+ * the timer block. We take the VIC as the base at the moment.
+ */
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0));
+}
+
+#define TICK_MAX (0xffffffff)
+
+#endif /* __ASM_ARCH_6400_TICK_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/timex.h b/arch/arm/mach-s3c64xx/include/mach/timex.h
new file mode 100644
index 00000000000..fb2e8cd4082
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/timex.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c64xx/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/uncompress.h b/arch/arm/mach-s3c64xx/include/mach/uncompress.h
index c6a82a20bf2..c6a82a20bf2 100644
--- a/arch/arm/mach-s3c6400/include/mach/uncompress.h
+++ b/arch/arm/mach-s3c64xx/include/mach/uncompress.h
diff --git a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
new file mode 100644
index 00000000000..7411ef3711a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/* arch/arm/mach-s3c64xx/include/mach/vmalloc.h
+ *
+ * from arch/arm/mach-iop3xx/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c
new file mode 100644
index 00000000000..5682d6a7f4a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/irq-eint.c
@@ -0,0 +1,213 @@
+/* arch/arm/plat-s3c64xx/irq-eint.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling for IRQ_EINT(x)
+ *
+ * This program is free software; you can 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/sysdev.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <plat/regs-irqtype.h>
+#include <mach/regs-gpio.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#define eint_offset(irq) ((irq) - IRQ_EINT(0))
+#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
+
+static inline void s3c_irq_eint_mask(unsigned int irq)
+{
+ u32 mask;
+
+ mask = __raw_readl(S3C64XX_EINT0MASK);
+ mask |= eint_irq_to_bit(irq);
+ __raw_writel(mask, S3C64XX_EINT0MASK);
+}
+
+static void s3c_irq_eint_unmask(unsigned int irq)
+{
+ u32 mask;
+
+ mask = __raw_readl(S3C64XX_EINT0MASK);
+ mask &= ~eint_irq_to_bit(irq);
+ __raw_writel(mask, S3C64XX_EINT0MASK);
+}
+
+static inline void s3c_irq_eint_ack(unsigned int irq)
+{
+ __raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND);
+}
+
+static void s3c_irq_eint_maskack(unsigned int irq)
+{
+ /* compiler should in-line these */
+ s3c_irq_eint_mask(irq);
+ s3c_irq_eint_ack(irq);
+}
+
+static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
+{
+ int offs = eint_offset(irq);
+ int pin, pin_val;
+ int shift;
+ u32 ctrl, mask;
+ u32 newvalue = 0;
+ void __iomem *reg;
+
+ if (offs > 27)
+ return -EINVAL;
+
+ if (offs <= 15)
+ reg = S3C64XX_EINT0CON0;
+ else
+ reg = S3C64XX_EINT0CON1;
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ printk(KERN_WARNING "No edge setting!\n");
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S3C2410_EXTINT_RISEEDGE;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S3C2410_EXTINT_FALLEDGE;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S3C2410_EXTINT_BOTHEDGE;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S3C2410_EXTINT_LOWLEV;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S3C2410_EXTINT_HILEV;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -1;
+ }
+
+ if (offs <= 15)
+ shift = (offs / 2) * 4;
+ else
+ shift = ((offs - 16) / 2) * 4;
+ mask = 0x7 << shift;
+
+ ctrl = __raw_readl(reg);
+ ctrl &= ~mask;
+ ctrl |= newvalue << shift;
+ __raw_writel(ctrl, reg);
+
+ /* set the GPIO pin appropriately */
+
+ if (offs < 16) {
+ pin = S3C64XX_GPN(offs);
+ pin_val = S3C_GPIO_SFN(2);
+ } else if (offs < 23) {
+ pin = S3C64XX_GPL(offs + 8 - 16);
+ pin_val = S3C_GPIO_SFN(3);
+ } else {
+ pin = S3C64XX_GPM(offs - 23);
+ pin_val = S3C_GPIO_SFN(3);
+ }
+
+ s3c_gpio_cfgpin(pin, pin_val);
+
+ return 0;
+}
+
+static struct irq_chip s3c_irq_eint = {
+ .name = "s3c-eint",
+ .mask = s3c_irq_eint_mask,
+ .unmask = s3c_irq_eint_unmask,
+ .mask_ack = s3c_irq_eint_maskack,
+ .ack = s3c_irq_eint_ack,
+ .set_type = s3c_irq_eint_set_type,
+ .set_wake = s3c_irqext_wake,
+};
+
+/* s3c_irq_demux_eint
+ *
+ * This function demuxes the IRQ from the group0 external interrupts,
+ * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
+ * the specific handlers s3c_irq_demux_eintX_Y.
+ */
+static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
+{
+ u32 status = __raw_readl(S3C64XX_EINT0PEND);
+ u32 mask = __raw_readl(S3C64XX_EINT0MASK);
+ unsigned int irq;
+
+ status &= ~mask;
+ status >>= start;
+ status &= (1 << (end - start + 1)) - 1;
+
+ for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+ if (status & 1)
+ generic_handle_irq(irq);
+
+ status >>= 1;
+ }
+}
+
+static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(0, 3);
+}
+
+static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(4, 11);
+}
+
+static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(12, 19);
+}
+
+static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(20, 27);
+}
+
+static int __init s3c64xx_init_irq_eint(void)
+{
+ int irq;
+
+ for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
+ set_irq_chip(irq, &s3c_irq_eint);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
+ set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
+ set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
+ set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
+
+ return 0;
+}
+
+arch_initcall(s3c64xx_init_irq_eint);
diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c
new file mode 100644
index 00000000000..da1bec64b9d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/irq-pm.c
@@ -0,0 +1,111 @@
+/* arch/arm/plat-s3c64xx/irq-pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling Power Management
+ *
+ * This program is free software; you can 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/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-timer.h>
+#include <mach/regs-gpio.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+/* We handled all the IRQ types in this code, to save having to make several
+ * small files to handle each different type separately. Having the EINT_GRP
+ * code here shouldn't be as much bloat as the IRQ table space needed when
+ * they are enabled. The added benefit is we ensure that these registers are
+ * in the same state as we suspended.
+ */
+
+static struct sleep_save irq_save[] = {
+ SAVE_ITEM(S3C64XX_PRIORITY),
+ SAVE_ITEM(S3C64XX_EINT0CON0),
+ SAVE_ITEM(S3C64XX_EINT0CON1),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON0),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON1),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON2),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON3),
+ SAVE_ITEM(S3C64XX_EINT0MASK),
+ SAVE_ITEM(S3C64XX_TINT_CSTAT),
+};
+
+static struct irq_grp_save {
+ u32 fltcon;
+ u32 con;
+ u32 mask;
+} eint_grp_save[5];
+
+static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: suspending IRQs\n", __func__);
+
+ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+ irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4));
+ grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4));
+ grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4));
+ }
+
+ return 0;
+}
+
+static int s3c64xx_irq_pm_resume(struct sys_device *dev)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: resuming IRQs\n", __func__);
+
+ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+ __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ __raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4));
+ __raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4));
+ __raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4));
+ }
+
+ S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
+ return 0;
+}
+
+static struct sysdev_driver s3c64xx_irq_driver = {
+ .suspend = s3c64xx_irq_pm_suspend,
+ .resume = s3c64xx_irq_pm_resume,
+};
+
+static int __init s3c64xx_irq_pm_init(void)
+{
+ return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver);
+}
+
+arch_initcall(s3c64xx_irq_pm_init);
+
diff --git a/arch/arm/mach-s3c64xx/irq.c b/arch/arm/mach-s3c64xx/irq.c
new file mode 100644
index 00000000000..67a145d440f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/irq.c
@@ -0,0 +1,69 @@
+/* arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling
+ *
+ * This program is free software; you can 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/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <mach/map.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.h>
+#include <plat/cpu.h>
+
+static struct s3c_uart_irq uart_irqs[] = {
+ [0] = {
+ .regs = S3C_VA_UART0,
+ .base_irq = IRQ_S3CUART_BASE0,
+ .parent_irq = IRQ_UART0,
+ },
+ [1] = {
+ .regs = S3C_VA_UART1,
+ .base_irq = IRQ_S3CUART_BASE1,
+ .parent_irq = IRQ_UART1,
+ },
+ [2] = {
+ .regs = S3C_VA_UART2,
+ .base_irq = IRQ_S3CUART_BASE2,
+ .parent_irq = IRQ_UART2,
+ },
+ [3] = {
+ .regs = S3C_VA_UART3,
+ .base_irq = IRQ_S3CUART_BASE3,
+ .parent_irq = IRQ_UART3,
+ },
+};
+
+
+void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
+{
+ printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
+
+ /* initialise the pair of VICs */
+ vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, 0);
+ vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0);
+
+ /* add the timer sub-irqs */
+
+ s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
+ s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
+ s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
+ s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
+ s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
+
+ s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
+}
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
new file mode 100644
index 00000000000..4a0bb243d14
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -0,0 +1,245 @@
+/* linux/arch/arm/mach-s3c64xx/mach-anw6410.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ * Copyright 2009 Kwangwoo Lee
+ * Kwangwoo Lee <kwangwoo.lee@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/dm9000.h>
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
+
+/* DM9000 */
+#define ANW6410_PA_DM9000 (0x18000000)
+
+/* A hardware buffer to control external devices is mapped at 0x30000000.
+ * It can not be read. So current status must be kept in anw6410_extdev_status.
+ */
+#define ANW6410_VA_EXTDEV S3C_ADDR(0x02000000)
+#define ANW6410_PA_EXTDEV (0x30000000)
+
+#define ANW6410_EN_DM9000 (1<<11)
+#define ANW6410_EN_LCD (1<<14)
+
+static __u32 anw6410_extdev_status;
+
+static struct s3c2410_uartcfg anw6410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+};
+
+/* framebuffer and LCD setup. */
+static void __init anw6410_lcd_mode_set(void)
+{
+ u32 tmp;
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/* GPF1 = LCD panel power
+ * GPF4 = LCD backlight control
+ */
+static void anw6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+ anw6410_extdev_status |= (ANW6410_EN_LCD << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+
+ gpio_direction_output(S3C64XX_GPF(1), 1);
+ gpio_direction_output(S3C64XX_GPF(4), 1);
+ } else {
+ anw6410_extdev_status &= ~(ANW6410_EN_LCD << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+
+ gpio_direction_output(S3C64XX_GPF(1), 0);
+ gpio_direction_output(S3C64XX_GPF(4), 0);
+ }
+}
+
+static struct plat_lcd_data anw6410_lcd_power_data = {
+ .set_power = anw6410_lcd_power_set,
+};
+
+static struct platform_device anw6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &anw6410_lcd_power_data,
+};
+
+static struct s3c_fb_pd_win anw6410_fb_win0 = {
+ /* this is to ensure we use win0 */
+ .win_mode = {
+ .pixclock = 41094,
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &anw6410_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+static void __init anw6410_dm9000_enable(void)
+{
+ anw6410_extdev_status |= (ANW6410_EN_DM9000 << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+}
+
+static struct resource anw6410_dm9000_resource[] = {
+ [0] = {
+ .start = ANW6410_PA_DM9000,
+ .end = ANW6410_PA_DM9000 + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ANW6410_PA_DM9000 + 4,
+ .end = ANW6410_PA_DM9000 + 4 + 500,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_EINT(15),
+ .end = IRQ_EINT(15),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+ },
+};
+
+static struct dm9000_plat_data anw6410_dm9000_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+ /* dev_addr can be set to provide hwaddr. */
+};
+
+static struct platform_device anw6410_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(anw6410_dm9000_resource),
+ .resource = anw6410_dm9000_resource,
+ .dev = {
+ .platform_data = &anw6410_dm9000_pdata,
+ },
+};
+
+static struct map_desc anw6410_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)ANW6410_VA_EXTDEV,
+ .pfn = __phys_to_pfn(ANW6410_PA_EXTDEV),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct platform_device *anw6410_devices[] __initdata = {
+ &s3c_device_fb,
+ &anw6410_lcd_powerdev,
+ &anw6410_device_eth,
+};
+
+static void __init anw6410_map_io(void)
+{
+ s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
+
+ anw6410_lcd_mode_set();
+}
+
+static void __init anw6410_machine_init(void)
+{
+ s3c_fb_set_platdata(&anw6410_lcd_pdata);
+
+ gpio_request(S3C64XX_GPF(1), "panel power");
+ gpio_request(S3C64XX_GPF(4), "LCD backlight");
+
+ anw6410_dm9000_enable();
+
+ platform_add_devices(anw6410_devices, ARRAY_SIZE(anw6410_devices));
+}
+
+MACHINE_START(ANW6410, "A&W6410")
+ /* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = anw6410_map_io,
+ .init_machine = anw6410_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
new file mode 100644
index 00000000000..187441a78dd
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -0,0 +1,276 @@
+/* mach-hmt.c - Platform code for Airgoo HMT
+ *
+ * Copyright 2009 Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * This program is free software; you can 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/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/pwm_backlight.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+static int hmt_bl_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable");
+ if (!ret)
+ ret = gpio_direction_output(S3C64XX_GPB(4), 0);
+
+ return ret;
+}
+
+static int hmt_bl_notify(struct device *dev, int brightness)
+{
+ /*
+ * translate from CIELUV/CIELAB L*->brightness, E.G. from
+ * perceived luminance to light output. Assumes range 0..25600
+ */
+ if (brightness < 0x800) {
+ /* Y = Yn * L / 903.3 */
+ brightness = (100*256 * brightness + 231245/2) / 231245;
+ } else {
+ /* Y = Yn * ((L + 16) / 116 )^3 */
+ int t = (brightness*4 + 16*1024 + 58)/116;
+ brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000);
+ }
+
+ gpio_set_value(S3C64XX_GPB(4), brightness);
+
+ return brightness;
+}
+
+static void hmt_bl_exit(struct device *dev)
+{
+ gpio_free(S3C64XX_GPB(4));
+}
+
+static struct platform_pwm_backlight_data hmt_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 100 * 256,
+ .dft_brightness = 40 * 256,
+ .pwm_period_ns = 1000000000 / (100 * 256 * 20),
+ .init = hmt_bl_init,
+ .notify = hmt_bl_notify,
+ .exit = hmt_bl_exit,
+
+};
+
+static struct platform_device hmt_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &s3c_device_timer[1].dev,
+ .platform_data = &hmt_backlight_data,
+ },
+};
+
+static struct s3c_fb_pd_win hmt_fb_win0 = {
+ .win_mode = {
+ .pixclock = 41094,
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata hmt_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &hmt_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct mtd_partition hmt_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_512K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "uboot-env1",
+ .size = SZ_256K,
+ .offset = SZ_512K,
+ },
+ [2] = {
+ .name = "uboot-env2",
+ .size = SZ_256K,
+ .offset = SZ_512K + SZ_256K,
+ },
+ [3] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [4] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set hmt_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(hmt_nand_part),
+ .partitions = hmt_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand hmt_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(hmt_nand_sets),
+ .sets = hmt_nand_sets,
+};
+
+static struct gpio_led hmt_leds[] = {
+ { /* left function keys */
+ .name = "left:blue",
+ .gpio = S3C64XX_GPO(12),
+ .default_trigger = "default-on",
+ },
+ { /* right function keys - red */
+ .name = "right:red",
+ .gpio = S3C64XX_GPO(13),
+ },
+ { /* right function keys - green */
+ .name = "right:green",
+ .gpio = S3C64XX_GPO(14),
+ },
+ { /* right function keys - blue */
+ .name = "right:blue",
+ .gpio = S3C64XX_GPO(15),
+ .default_trigger = "default-on",
+ },
+};
+
+static struct gpio_led_platform_data hmt_led_data = {
+ .num_leds = ARRAY_SIZE(hmt_leds),
+ .leds = hmt_leds,
+};
+
+static struct platform_device hmt_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &hmt_led_data,
+};
+
+static struct map_desc hmt_iodesc[] = {};
+
+static struct platform_device *hmt_devices[] __initdata = {
+ &s3c_device_i2c0,
+ &s3c_device_nand,
+ &s3c_device_fb,
+ &s3c_device_ohci,
+ &s3c_device_timer[1],
+ &hmt_backlight_device,
+ &hmt_leds_device,
+};
+
+static void __init hmt_map_io(void)
+{
+ s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
+}
+
+static void __init hmt_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_fb_set_platdata(&hmt_lcd_pdata);
+ s3c_nand_set_platdata(&hmt_nand_info);
+
+ gpio_request(S3C64XX_GPC(7), "usb power");
+ gpio_direction_output(S3C64XX_GPC(7), 0);
+ gpio_request(S3C64XX_GPM(0), "usb power");
+ gpio_direction_output(S3C64XX_GPM(0), 1);
+ gpio_request(S3C64XX_GPK(7), "usb power");
+ gpio_direction_output(S3C64XX_GPK(7), 1);
+ gpio_request(S3C64XX_GPF(13), "usb power");
+ gpio_direction_output(S3C64XX_GPF(13), 1);
+
+ platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
+}
+
+MACHINE_START(HMT, "Airgoo-HMT")
+ /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = hmt_map_io,
+ .init_machine = hmt_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
new file mode 100644
index 00000000000..bf65747ea68
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -0,0 +1,107 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-ncp.c
+ *
+ * Copyright (C) 2008-2009 Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg ncp_uartcfgs[] __initdata = {
+ /* REVISIT: NCP uses only serial 1, 2 */
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+static struct platform_device *ncp_devices[] __initdata = {
+ &s3c_device_hsmmc1,
+ &s3c_device_i2c0,
+};
+
+static struct map_desc ncp_iodesc[] __initdata = {};
+
+static void __init ncp_map_io(void)
+{
+ s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
+}
+
+static void __init ncp_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+
+ platform_add_devices(ncp_devices, ARRAY_SIZE(ncp_devices));
+}
+
+MACHINE_START(NCP, "NCP")
+ /* Maintainer: Samsung Electronics */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = ncp_map_io,
+ .init_machine = ncp_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
new file mode 100644
index 00000000000..f7b18983950
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -0,0 +1,96 @@
+/* linux/arch/arm/mach-s3c64xx/mach-smdk6400.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+
+#include <mach/s3c6400.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk6400_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+};
+
+static struct map_desc smdk6400_iodesc[] = {};
+
+static void __init smdk6400_map_io(void)
+{
+ s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
+}
+
+static struct platform_device *smdk6400_devices[] __initdata = {
+ &s3c_device_hsmmc1,
+ &s3c_device_i2c0,
+};
+
+static struct i2c_board_info i2c_devs[] __initdata = {
+ { I2C_BOARD_INFO("wm8753", 0x1A), },
+ { I2C_BOARD_INFO("24c08", 0x50), },
+};
+
+static void __init smdk6400_machine_init(void)
+{
+ i2c_register_board_info(0, i2c_devs, ARRAY_SIZE(i2c_devs));
+ platform_add_devices(smdk6400_devices, ARRAY_SIZE(smdk6400_devices));
+}
+
+MACHINE_START(SMDK6400, "SMDK6400")
+ /* Maintainer: Ben Dooks <ben@fluff.org> */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+
+ .init_irq = s3c6400_init_irq,
+ .map_io = smdk6400_map_io,
+ .init_machine = smdk6400_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
new file mode 100644
index 00000000000..2d5afd221d7
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -0,0 +1,668 @@
+/* linux/arch/arm/mach-s3c64xx/mach-smdk6410.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/smsc911x.h>
+#include <linux/regulator/fixed.h>
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#endif
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-modem.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-sys.h>
+#include <mach/regs-srom.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* framebuffer and LCD setup. */
+
+/* GPF15 = LCD backlight control
+ * GPF13 => Panel power
+ * GPN5 = LCD nRESET signal
+ * PWM_TOUT1 => backlight brightness
+ */
+
+static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+ gpio_direction_output(S3C64XX_GPF(13), 1);
+ gpio_direction_output(S3C64XX_GPF(15), 1);
+
+ /* fire nRESET on power up */
+ gpio_direction_output(S3C64XX_GPN(5), 0);
+ msleep(10);
+ gpio_direction_output(S3C64XX_GPN(5), 1);
+ msleep(1);
+ } else {
+ gpio_direction_output(S3C64XX_GPF(15), 0);
+ gpio_direction_output(S3C64XX_GPF(13), 0);
+ }
+}
+
+static struct plat_lcd_data smdk6410_lcd_power_data = {
+ .set_power = smdk6410_lcd_power_set,
+};
+
+static struct platform_device smdk6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smdk6410_lcd_power_data,
+};
+
+static struct s3c_fb_pd_win smdk6410_fb_win0 = {
+ /* this is to ensure we use win0 */
+ .win_mode = {
+ .pixclock = 41094,
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &smdk6410_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/*
+ * Configuring Ethernet on SMDK6410
+ *
+ * Both CS8900A and LAN9115 chips share one chip select mediated by CFG6.
+ * The constant address below corresponds to nCS1
+ *
+ * 1) Set CFGB2 p3 ON others off, no other CFGB selects "ethernet"
+ * 2) CFG6 needs to be switched to "LAN9115" side
+ */
+
+static struct resource smdk6410_smsc911x_resources[] = {
+ [0] = {
+ .start = S3C64XX_PA_XM0CSN1,
+ .end = S3C64XX_PA_XM0CSN1 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S3C_EINT(10),
+ .end = S3C_EINT(10),
+ .flags = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smdk6410_smsc911x_pdata = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+
+static struct platform_device smdk6410_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdk6410_smsc911x_resources),
+ .resource = &smdk6410_smsc911x_resources[0],
+ .dev = {
+ .platform_data = &smdk6410_smsc911x_pdata,
+ },
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
+ {
+ /* WM8580 */
+ .supply = "PVDD",
+ .dev_name = "0-001b",
+ },
+ {
+ /* WM8580 */
+ .supply = "AVDD",
+ .dev_name = "0-001b",
+ },
+};
+
+static struct regulator_init_data smdk6410_b_pwr_5v_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdk6410_b_pwr_5v_consumers),
+ .consumer_supplies = smdk6410_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = {
+ .supply_name = "B_PWR_5V",
+ .microvolts = 5000000,
+ .init_data = &smdk6410_b_pwr_5v_data,
+ .gpio = -EINVAL,
+};
+
+static struct platform_device smdk6410_b_pwr_5v = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &smdk6410_b_pwr_5v_pdata,
+ },
+};
+#endif
+
+static struct map_desc smdk6410_iodesc[] = {};
+
+static struct platform_device *smdk6410_devices[] __initdata = {
+#ifdef CONFIG_SMDK6410_SD_CH0
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_SMDK6410_SD_CH1
+ &s3c_device_hsmmc1,
+#endif
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_fb,
+ &s3c_device_ohci,
+ &s3c_device_usb_hsotg,
+ &s3c64xx_device_iisv4,
+
+#ifdef CONFIG_REGULATOR
+ &smdk6410_b_pwr_5v,
+#endif
+ &smdk6410_lcd_powerdev,
+
+ &smdk6410_smsc911x,
+};
+
+#ifdef CONFIG_REGULATOR
+/* ARM core */
+static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = {
+ {
+ .supply = "vddarm",
+ }
+};
+
+/* VDDARM, BUCK1 on J5 */
+static struct regulator_init_data smdk6410_vddarm = {
+ .constraints = {
+ .name = "PVDD_ARM",
+ .min_uV = 1000000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdk6410_vddarm_consumers),
+ .consumer_supplies = smdk6410_vddarm_consumers,
+};
+
+/* VDD_INT, BUCK2 on J5 */
+static struct regulator_init_data smdk6410_vddint = {
+ .constraints = {
+ .name = "PVDD_INT",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+};
+
+/* VDD_HI, LDO3 on J5 */
+static struct regulator_init_data smdk6410_vddhi = {
+ .constraints = {
+ .name = "PVDD_HI",
+ .always_on = 1,
+ },
+};
+
+/* VDD_PLL, LDO2 on J5 */
+static struct regulator_init_data smdk6410_vddpll = {
+ .constraints = {
+ .name = "PVDD_PLL",
+ .always_on = 1,
+ },
+};
+
+/* VDD_UH_MMC, LDO5 on J5 */
+static struct regulator_init_data smdk6410_vdduh_mmc = {
+ .constraints = {
+ .name = "PVDD_UH/PVDD_MMC",
+ .always_on = 1,
+ },
+};
+
+/* VCCM3BT, LDO8 on J5 */
+static struct regulator_init_data smdk6410_vccmc3bt = {
+ .constraints = {
+ .name = "PVCCM3BT",
+ .always_on = 1,
+ },
+};
+
+/* VCCM2MTV, LDO11 on J5 */
+static struct regulator_init_data smdk6410_vccm2mtv = {
+ .constraints = {
+ .name = "PVCCM2MTV",
+ .always_on = 1,
+ },
+};
+
+/* VDD_LCD, LDO12 on J5 */
+static struct regulator_init_data smdk6410_vddlcd = {
+ .constraints = {
+ .name = "PVDD_LCD",
+ .always_on = 1,
+ },
+};
+
+/* VDD_OTGI, LDO9 on J5 */
+static struct regulator_init_data smdk6410_vddotgi = {
+ .constraints = {
+ .name = "PVDD_OTGI",
+ .always_on = 1,
+ },
+};
+
+/* VDD_OTG, LDO14 on J5 */
+static struct regulator_init_data smdk6410_vddotg = {
+ .constraints = {
+ .name = "PVDD_OTG",
+ .always_on = 1,
+ },
+};
+
+/* VDD_ALIVE, LDO15 on J5 */
+static struct regulator_init_data smdk6410_vddalive = {
+ .constraints = {
+ .name = "PVDD_ALIVE",
+ .always_on = 1,
+ },
+};
+
+/* VDD_AUDIO, VLDO_AUDIO on J5 */
+static struct regulator_init_data smdk6410_vddaudio = {
+ .constraints = {
+ .name = "PVDD_AUDIO",
+ .always_on = 1,
+ },
+};
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+/* S3C64xx internal logic & PLL */
+static struct regulator_init_data wm8350_dcdc1_data = {
+ .constraints = {
+ .name = "PVDD_INT/PVDD_PLL",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .apply_uV = 1,
+ },
+};
+
+/* Memory */
+static struct regulator_init_data wm8350_dcdc3_data = {
+ .constraints = {
+ .name = "PVDD_MEM",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 1,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ },
+};
+
+/* USB, EXT, PCM, ADC/DAC, USB, MMC */
+static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
+ {
+ /* WM8580 */
+ .supply = "DVDD",
+ .dev_name = "0-001b",
+ },
+};
+
+static struct regulator_init_data wm8350_dcdc4_data = {
+ .constraints = {
+ .name = "PVDD_HI/PVDD_EXT/PVDD_SYS/PVCCM2MTV",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8350_dcdc4_consumers),
+ .consumer_supplies = wm8350_dcdc4_consumers,
+};
+
+/* OTGi/1190-EV1 HPVDD & AVDD */
+static struct regulator_init_data wm8350_ldo4_data = {
+ .constraints = {
+ .name = "PVDD_OTGI/HPVDD/AVDD",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct {
+ int regulator;
+ struct regulator_init_data *initdata;
+} wm1190_regulators[] = {
+ { WM8350_DCDC_1, &wm8350_dcdc1_data },
+ { WM8350_DCDC_3, &wm8350_dcdc3_data },
+ { WM8350_DCDC_4, &wm8350_dcdc4_data },
+ { WM8350_DCDC_6, &smdk6410_vddarm },
+ { WM8350_LDO_1, &smdk6410_vddalive },
+ { WM8350_LDO_2, &smdk6410_vddotg },
+ { WM8350_LDO_3, &smdk6410_vddlcd },
+ { WM8350_LDO_4, &wm8350_ldo4_data },
+};
+
+static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
+{
+ int i;
+
+ /* Configure the IRQ line */
+ s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
+ /* Instantiate the regulators */
+ for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
+ wm8350_register_regulator(wm8350,
+ wm1190_regulators[i].regulator,
+ wm1190_regulators[i].initdata);
+
+ return 0;
+}
+
+static struct wm8350_platform_data __initdata smdk6410_wm8350_pdata = {
+ .init = smdk6410_wm8350_init,
+ .irq_high = 1,
+ .irq_base = IRQ_BOARD_START,
+};
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+static struct gpio_led wm1192_pmic_leds[] = {
+ {
+ .name = "PMIC:red:power",
+ .gpio = GPIO_BOARD_START + 3,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+};
+
+static struct gpio_led_platform_data wm1192_pmic_led = {
+ .num_leds = ARRAY_SIZE(wm1192_pmic_leds),
+ .leds = wm1192_pmic_leds,
+};
+
+static struct platform_device wm1192_pmic_led_dev = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wm1192_pmic_led,
+ },
+};
+
+static int wm1192_pre_init(struct wm831x *wm831x)
+{
+ int ret;
+
+ /* Configure the IRQ line */
+ s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
+ ret = platform_device_register(&wm1192_pmic_led_dev);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to add PMIC LED: %d\n", ret);
+
+ return 0;
+}
+
+static struct wm831x_backlight_pdata wm1192_backlight_pdata = {
+ .isink = 1,
+ .max_uA = 27554,
+};
+
+static struct regulator_init_data wm1192_dcdc3 = {
+ .constraints = {
+ .name = "PVDD_MEM/PVDD_GPS",
+ .always_on = 1,
+ },
+};
+
+static struct regulator_consumer_supply wm1192_ldo1_consumers[] = {
+ { .supply = "DVDD", .dev_name = "0-001b", }, /* WM8580 */
+};
+
+static struct regulator_init_data wm1192_ldo1 = {
+ .constraints = {
+ .name = "PVDD_LCD/PVDD_EXT",
+ .always_on = 1,
+ },
+ .consumer_supplies = wm1192_ldo1_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(wm1192_ldo1_consumers),
+};
+
+static struct wm831x_status_pdata wm1192_led7_pdata = {
+ .name = "LED7:green:",
+};
+
+static struct wm831x_status_pdata wm1192_led8_pdata = {
+ .name = "LED8:green:",
+};
+
+static struct wm831x_pdata smdk6410_wm1192_pdata = {
+ .pre_init = wm1192_pre_init,
+ .irq_base = IRQ_BOARD_START,
+
+ .backlight = &wm1192_backlight_pdata,
+ .dcdc = {
+ &smdk6410_vddarm, /* DCDC1 */
+ &smdk6410_vddint, /* DCDC2 */
+ &wm1192_dcdc3,
+ },
+ .gpio_base = GPIO_BOARD_START,
+ .ldo = {
+ &wm1192_ldo1, /* LDO1 */
+ &smdk6410_vdduh_mmc, /* LDO2 */
+ NULL, /* LDO3 NC */
+ &smdk6410_vddotgi, /* LDO4 */
+ &smdk6410_vddotg, /* LDO5 */
+ &smdk6410_vddhi, /* LDO6 */
+ &smdk6410_vddaudio, /* LDO7 */
+ &smdk6410_vccm2mtv, /* LDO8 */
+ &smdk6410_vddpll, /* LDO9 */
+ &smdk6410_vccmc3bt, /* LDO10 */
+ &smdk6410_vddalive, /* LDO11 */
+ },
+ .status = {
+ &wm1192_led7_pdata,
+ &wm1192_led8_pdata,
+ },
+};
+#endif
+
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("24c08", 0x50), },
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+ { I2C_BOARD_INFO("wm8312", 0x34),
+ .platform_data = &smdk6410_wm1192_pdata,
+ .irq = S3C_EINT(12),
+ },
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+ { I2C_BOARD_INFO("wm8350", 0x1a),
+ .platform_data = &smdk6410_wm8350_pdata,
+ .irq = S3C_EINT(12),
+ },
+#endif
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ { I2C_BOARD_INFO("24c128", 0x57), }, /* Samsung S524AD0XD1 */
+};
+
+static void __init smdk6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
+
+ /* set the LCD type */
+
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the lcd bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+static void __init smdk6410_machine_init(void)
+{
+ u32 cs1;
+
+ s3c_i2c0_set_platdata(NULL);
+ s3c_i2c1_set_platdata(NULL);
+ s3c_fb_set_platdata(&smdk6410_lcd_pdata);
+
+ /* configure nCS1 width to 16 bits */
+
+ cs1 = __raw_readl(S3C64XX_SROM_BW) &
+ ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S3C64XX_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S3C64XX_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+
+ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+ (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+ (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+ (0xe << S3C64XX_SROM_BCX__TACC__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+ (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+ gpio_request(S3C64XX_GPN(5), "LCD power");
+ gpio_request(S3C64XX_GPF(13), "LCD power");
+ gpio_request(S3C64XX_GPF(15), "LCD power");
+
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
+}
+
+MACHINE_START(SMDK6410, "SMDK6410")
+ /* Maintainer: Ben Dooks <ben@fluff.org> */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = smdk6410_map_io,
+ .init_machine = smdk6410_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
new file mode 100644
index 00000000000..b8ac4597fad
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -0,0 +1,173 @@
+/* linux/arch/arm/plat-s3c64xx/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU PM support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/pm.h>
+#include <mach/regs-sys.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-syscon-power.h>
+#include <mach/regs-gpio-memport.h>
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+#include <mach/gpio-bank-n.h>
+
+void s3c_pm_debug_smdkled(u32 set, u32 clear)
+{
+ unsigned long flags;
+ u32 reg;
+
+ local_irq_save(flags);
+ reg = __raw_readl(S3C64XX_GPNCON);
+ reg &= ~(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) |
+ S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15));
+ reg |= S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) |
+ S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15);
+ __raw_writel(reg, S3C64XX_GPNCON);
+
+ reg = __raw_readl(S3C64XX_GPNDAT);
+ reg &= ~(clear << 12);
+ reg |= set << 12;
+ __raw_writel(reg, S3C64XX_GPNDAT);
+
+ local_irq_restore(flags);
+}
+#endif
+
+static struct sleep_save core_save[] = {
+ SAVE_ITEM(S3C_APLL_LOCK),
+ SAVE_ITEM(S3C_MPLL_LOCK),
+ SAVE_ITEM(S3C_EPLL_LOCK),
+ SAVE_ITEM(S3C_CLK_SRC),
+ SAVE_ITEM(S3C_CLK_DIV0),
+ SAVE_ITEM(S3C_CLK_DIV1),
+ SAVE_ITEM(S3C_CLK_DIV2),
+ SAVE_ITEM(S3C_CLK_OUT),
+ SAVE_ITEM(S3C_HCLK_GATE),
+ SAVE_ITEM(S3C_PCLK_GATE),
+ SAVE_ITEM(S3C_SCLK_GATE),
+ SAVE_ITEM(S3C_MEM0_GATE),
+
+ SAVE_ITEM(S3C_EPLL_CON1),
+ SAVE_ITEM(S3C_EPLL_CON0),
+
+ SAVE_ITEM(S3C64XX_MEM0DRVCON),
+ SAVE_ITEM(S3C64XX_MEM1DRVCON),
+
+#ifndef CONFIG_CPU_FREQ
+ SAVE_ITEM(S3C_APLL_CON),
+ SAVE_ITEM(S3C_MPLL_CON),
+#endif
+};
+
+static struct sleep_save misc_save[] = {
+ SAVE_ITEM(S3C64XX_AHB_CON0),
+ SAVE_ITEM(S3C64XX_AHB_CON1),
+ SAVE_ITEM(S3C64XX_AHB_CON2),
+
+ SAVE_ITEM(S3C64XX_SPCON),
+
+ SAVE_ITEM(S3C64XX_MEM0CONSTOP),
+ SAVE_ITEM(S3C64XX_MEM1CONSTOP),
+ SAVE_ITEM(S3C64XX_MEM0CONSLP0),
+ SAVE_ITEM(S3C64XX_MEM0CONSLP1),
+ SAVE_ITEM(S3C64XX_MEM1CONSLP),
+};
+
+void s3c_pm_configure_extint(void)
+{
+ __raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK);
+}
+
+void s3c_pm_restore_core(void)
+{
+ __raw_writel(0, S3C64XX_EINT_MASK);
+
+ s3c_pm_debug_smdkled(1 << 2, 0);
+
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+ s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
+}
+
+void s3c_pm_save_core(void)
+{
+ s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
+}
+
+/* since both s3c6400 and s3c6410 share the same sleep pm calls, we
+ * put the per-cpu code in here until any new cpu comes along and changes
+ * this.
+ */
+
+static void s3c64xx_cpu_suspend(void)
+{
+ unsigned long tmp;
+
+ /* set our standby method to sleep */
+
+ tmp = __raw_readl(S3C64XX_PWR_CFG);
+ tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+ tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP;
+ __raw_writel(tmp, S3C64XX_PWR_CFG);
+
+ /* clear any old wakeup */
+
+ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT),
+ S3C64XX_WAKEUP_STAT);
+
+ /* set the LED state to 0110 over sleep */
+ s3c_pm_debug_smdkled(3 << 1, 0xf);
+
+ /* issue the standby signal into the pm unit. Note, we
+ * issue a write-buffer drain just in case */
+
+ tmp = 0;
+
+ asm("b 1f\n\t"
+ ".align 5\n\t"
+ "1:\n\t"
+ "mcr p15, 0, %0, c7, c10, 5\n\t"
+ "mcr p15, 0, %0, c7, c10, 4\n\t"
+ "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
+
+ /* we should never get past here */
+
+ panic("sleep resumed to originator?");
+}
+
+static void s3c64xx_pm_prepare(void)
+{
+ /* store address of resume. */
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
+
+ /* ensure previous wakeup state is cleared before sleeping */
+ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
+}
+
+static int s3c64xx_pm_init(void)
+{
+ pm_cpu_prep = s3c64xx_pm_prepare;
+ pm_cpu_sleep = s3c64xx_cpu_suspend;
+ pm_uart_udivslot = 1;
+ return 0;
+}
+
+arch_initcall(s3c64xx_pm_init);
diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c
new file mode 100644
index 00000000000..707e34e3afd
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/s3c6400.c
@@ -0,0 +1,89 @@
+/* linux/arch/arm/mach-s3c64xx/cpu.c
+ *
+ * Copyright 2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/sdhci.h>
+#include <plat/iic-core.h>
+#include <mach/s3c6400.h>
+
+void __init s3c6400_map_io(void)
+{
+ /* setup SDHCI */
+
+ s3c6400_default_sdhci0();
+ s3c6400_default_sdhci1();
+ s3c6400_default_sdhci2();
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+
+ s3c_device_nand.name = "s3c6400-nand";
+}
+
+void __init s3c6400_init_clocks(int xtal)
+{
+ s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK);
+ s3c6400_setup_clocks();
+}
+
+void __init s3c6400_init_irq(void)
+{
+ /* VIC0 does not have IRQS 5..7,
+ * VIC1 is fully populated. */
+ s3c64xx_init_irq(~0 & ~(0xf << 5), ~0);
+}
+
+struct sysdev_class s3c6400_sysclass = {
+ .name = "s3c6400-core",
+};
+
+static struct sys_device s3c6400_sysdev = {
+ .cls = &s3c6400_sysclass,
+};
+
+static int __init s3c6400_core_init(void)
+{
+ return sysdev_class_register(&s3c6400_sysclass);
+}
+
+core_initcall(s3c6400_core_init);
+
+int __init s3c6400_init(void)
+{
+ printk("S3C6400: Initialising architecture\n");
+
+ return sysdev_register(&s3c6400_sysdev);
+}
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
new file mode 100644
index 00000000000..59635d19466
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-s3c64xx/s3c6410.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/sdhci.h>
+#include <plat/iic-core.h>
+#include <mach/s3c6400.h>
+#include <mach/s3c6410.h>
+
+void __init s3c6410_map_io(void)
+{
+ /* initialise device information early */
+ s3c6410_default_sdhci0();
+ s3c6410_default_sdhci1();
+ s3c6410_default_sdhci2();
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+
+ s3c_device_nand.name = "s3c6400-nand";
+}
+
+void __init s3c6410_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
+ s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK);
+ s3c6400_setup_clocks();
+}
+
+void __init s3c6410_init_irq(void)
+{
+ /* VIC0 is missing IRQ7, VIC1 is fully populated. */
+ s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
+}
+
+struct sysdev_class s3c6410_sysclass = {
+ .name = "s3c6410-core",
+};
+
+static struct sys_device s3c6410_sysdev = {
+ .cls = &s3c6410_sysclass,
+};
+
+static int __init s3c6410_core_init(void)
+{
+ return sysdev_class_register(&s3c6410_sysclass);
+}
+
+core_initcall(s3c6410_core_init);
+
+int __init s3c6410_init(void)
+{
+ printk("S3C6410: Initialising architecture\n");
+
+ return sysdev_register(&s3c6410_sysdev);
+}
diff --git a/arch/arm/plat-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
index 8e28e448dd2..8e28e448dd2 100644
--- a/arch/arm/plat-s3c64xx/setup-fb-24bpp.c
+++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
diff --git a/arch/arm/mach-s3c64xx/setup-i2c0.c b/arch/arm/mach-s3c64xx/setup-i2c0.c
new file mode 100644
index 00000000000..d1b11e6e77e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-i2c0.c
@@ -0,0 +1,31 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c0.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX I2C bus 0 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/gpio.h>
+#include <mach/gpio-bank-b.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgpin(S3C64XX_GPB(5), S3C64XX_GPB5_I2C_SCL0);
+ s3c_gpio_cfgpin(S3C64XX_GPB(6), S3C64XX_GPB6_I2C_SDA0);
+ s3c_gpio_setpull(S3C64XX_GPB(5), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C64XX_GPB(6), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s3c64xx/setup-i2c1.c b/arch/arm/mach-s3c64xx/setup-i2c1.c
new file mode 100644
index 00000000000..2dce57d8c6f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-i2c1.c
@@ -0,0 +1,31 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX I2C bus 1 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/gpio.h>
+#include <mach/gpio-bank-b.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgpin(S3C64XX_GPB(2), S3C64XX_GPB2_I2C_SCL1);
+ s3c_gpio_cfgpin(S3C64XX_GPB(3), S3C64XX_GPB3_I2C_SDA1);
+ s3c_gpio_setpull(S3C64XX_GPB(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C64XX_GPB(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
index a58c0cc7ba5..a58c0cc7ba5 100644
--- a/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci.c b/arch/arm/mach-s3c64xx/setup-sdhci.c
new file mode 100644
index 00000000000..1a942037c4e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-sdhci.c
@@ -0,0 +1,72 @@
+/* linux/arch/arm/mach-s3c64xx/setup-sdhci.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C6400/S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s3c64xx_hsmmc_clksrcs[4] = {
+ [0] = "hsmmc",
+ [1] = "hsmmc",
+ [2] = "mmc_bus",
+ /* [3] = "48m", - note not successfully used yet */
+};
+
+void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card)
+{
+ u32 ctrl2, ctrl3;
+
+ ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+ ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+ ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+ S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+ S3C_SDHCI_CTRL2_ENFBCLKRX |
+ S3C_SDHCI_CTRL2_DFCNT_NONE |
+ S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+ if (ios->clock < 25 * 1000000)
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+ S3C_SDHCI_CTRL3_FCSEL2 |
+ S3C_SDHCI_CTRL3_FCSEL1 |
+ S3C_SDHCI_CTRL3_FCSEL0);
+ else
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+ printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
+ writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+ writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
+
+void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card)
+{
+ writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+
+ s3c6400_setup_sdhci_cfg_card(dev, r, ios, card);
+}
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S
new file mode 100644
index 00000000000..b2ef4431736
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/sleep.S
@@ -0,0 +1,144 @@
+/* linux/arch/arm/plat-s3c64xx/sleep.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU sleep code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/map.h>
+
+#undef S3C64XX_VA_GPIO
+#define S3C64XX_VA_GPIO (0x0)
+
+#include <mach/regs-gpio.h>
+#include <mach/gpio-bank-n.h>
+
+#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
+
+ .text
+
+ /* s3c_cpu_save
+ *
+ * Save enough processor state to allow the restart of the pm.c
+ * code after resume.
+ *
+ * entry:
+ * r0 = pointer to the save block
+ */
+
+ENTRY(s3c_cpu_save)
+ stmfd sp!, { r4 - r12, lr }
+
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
+ mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
+ mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
+ mrc p15, 0, r9, c1, c0, 0 @ Control register
+ mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
+
+ stmia r0, { r4 - r13 } @ Save CP registers and SP
+
+ @@ save our state to ram
+ bl s3c_pm_cb_flushcache
+
+ @@ call final suspend code
+ ldr r0, =pm_cpu_sleep
+ ldr pc, [r0]
+
+ @@ return to the caller, after the MMU is turned on.
+ @@ restore the last bits of the stack and return.
+resume_with_mmu:
+ ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
+
+ .data
+
+ /* the next bit is code, but it requires easy access to the
+ * s3c_sleep_save_phys data before the MMU is switched on, so
+ * we store the code that needs this variable in the .data where
+ * the value can be written to (the .text segment is RO).
+ */
+
+ .global s3c_sleep_save_phys
+s3c_sleep_save_phys:
+ .word 0
+
+ /* Sleep magic, the word before the resume entry point so that the
+ * bootloader can check for a resumeable image. */
+
+ .word 0x2bedf00d
+
+ /* s3c_cpu_reusme
+ *
+ * This is the entry point, stored by whatever method the bootloader
+ * requires to get the kernel runnign again. This code expects to be
+ * entered with no caches live and the MMU disabled. It will then
+ * restore the MMU and other basic CP registers saved and restart
+ * the kernel C code to finish the resume code.
+ */
+
+ENTRY(s3c_cpu_resume)
+ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ ldr r2, =LL_UART /* for debug */
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+ /* Initialise the GPIO state if we are debugging via the SMDK LEDs,
+ * as the uboot version supplied resets these to inputs during the
+ * resume checks.
+ */
+
+ ldr r3, =S3C64XX_PA_GPIO
+ ldr r0, [ r3, #S3C64XX_GPNCON ]
+ bic r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
+ S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
+ orr r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
+ S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
+ str r0, [ r3, #S3C64XX_GPNCON ]
+
+ ldr r0, [ r3, #S3C64XX_GPNDAT ]
+ bic r0, r0, #0xf << 12 @ GPN12..15
+ orr r0, r0, #1 << 15 @ GPN15
+ str r0, [ r3, #S3C64XX_GPNDAT ]
+#endif
+
+ /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
+ * are thoroughly cleaned just in case the bootloader didn't do it
+ * for us. */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ @@mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
+ @@mcr p15, 0, r0, c7, c7, 0 @ Invalidate I + D caches
+
+ ldr r0, s3c_sleep_save_phys
+ ldmia r0, { r4 - r13 }
+
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
+ mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
+ mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
+ mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+
+ mov r0, #0 @ restore copro access controls
+ mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls
+ mcr p15, 0, r0, c7, c5, 4
+
+ ldr r2, =resume_with_mmu
+ mcr p15, 0, r9, c1, c0, 0 /* turn mmu back on */
+ nop
+ mov pc, r2 /* jump back */
+
+ .end
diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig
new file mode 100644
index 00000000000..4c29ff8b07d
--- /dev/null
+++ b/arch/arm/mach-s5p6440/Kconfig
@@ -0,0 +1,21 @@
+# arch/arm/mach-s5p6440/Kconfig
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+if ARCH_S5P6440
+
+config CPU_S5P6440
+ bool
+ help
+ Enable S5P6440 CPU support
+
+config MACH_SMDK6440
+ bool "SMDK6440"
+ select CPU_S5P6440
+ help
+ Machine support for the Samsung SMDK6440
+
+endif
diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile
new file mode 100644
index 00000000000..1ad894b1d3a
--- /dev/null
+++ b/arch/arm/mach-s5p6440/Makefile
@@ -0,0 +1,19 @@
+# arch/arm/mach-s5p6440/Makefile
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core support for S5P6440 system
+
+obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o
diff --git a/arch/arm/mach-s5p6440/Makefile.boot b/arch/arm/mach-s5p6440/Makefile.boot
new file mode 100644
index 00000000000..ff90aa13bd6
--- /dev/null
+++ b/arch/arm/mach-s5p6440/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c
new file mode 100644
index 00000000000..b2672e16e7a
--- /dev/null
+++ b/arch/arm/mach-s5p6440/clock.c
@@ -0,0 +1,698 @@
+/* linux/arch/arm/mach-s5p6440/clock.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p-clock.h>
+#include <plat/pll.h>
+#include <plat/s5p6440.h>
+
+/* APLL Mux output clock */
+static struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static int s5p6440_epll_enable(struct clk *clk, int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
+
+ if (enable)
+ __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
+ else
+ __raw_writel(epll_con, S5P_EPLL_CON);
+
+ return 0;
+}
+
+static unsigned long s5p6440_epll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static u32 epll_div[][5] = {
+ { 36000000, 0, 48, 1, 4 },
+ { 48000000, 0, 32, 1, 3 },
+ { 60000000, 0, 40, 1, 3 },
+ { 72000000, 0, 48, 1, 3 },
+ { 84000000, 0, 28, 1, 2 },
+ { 96000000, 0, 32, 1, 2 },
+ { 32768000, 45264, 43, 1, 4 },
+ { 45158000, 6903, 30, 1, 3 },
+ { 49152000, 50332, 32, 1, 3 },
+ { 67738000, 10398, 45, 1, 3 },
+ { 73728000, 9961, 49, 1, 3 }
+};
+
+static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+
+ if (clk->rate == rate) /* Return if nothing changed */
+ return 0;
+
+ epll_con = __raw_readl(S5P_EPLL_CON);
+ epll_con_k = __raw_readl(S5P_EPLL_CON_K);
+
+ epll_con_k &= ~(PLL90XX_KDIV_MASK);
+ epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+ epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+ (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+ (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(epll_con, S5P_EPLL_CON);
+ __raw_writel(epll_con_k, S5P_EPLL_CON_K);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5p6440_epll_ops = {
+ .get_rate = s5p6440_epll_get_rate,
+ .set_rate = s5p6440_epll_set_rate,
+};
+
+static struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 2, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .sources = &clk_src_mpll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 },
+};
+
+static struct clk clk_h_low = {
+ .name = "hclk_low",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+ .ops = &clk_ops_def_setrate,
+};
+
+static struct clk clk_p_low = {
+ .name = "pclk_low",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+ .ops = &clk_ops_def_setrate,
+};
+
+enum perf_level {
+ L0 = 532*1000,
+ L1 = 266*1000,
+ L2 = 133*1000,
+};
+
+static const u32 clock_table[][3] = {
+ /*{ARM_CLK, DIVarm, DIVhclk}*/
+ {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P_CLKDIV0_HCLK_SHIFT)},
+ {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P_CLKDIV0_HCLK_SHIFT)},
+ {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P_CLKDIV0_HCLK_SHIFT)},
+};
+
+static unsigned long s5p6440_armclk_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 clkdiv;
+
+ /* divisor mask starts at bit0, so no need to shift */
+ clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK;
+
+ return rate / (clkdiv + 1);
+}
+
+static unsigned long s5p6440_armclk_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 iter;
+
+ for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+ if (rate > clock_table[iter][0])
+ return clock_table[iter-1][0];
+ }
+
+ return clock_table[ARRAY_SIZE(clock_table) - 1][0];
+}
+
+static int s5p6440_armclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 round_tmp;
+ u32 iter;
+ u32 clk_div0_tmp;
+ u32 cur_rate = clk->ops->get_rate(clk);
+ unsigned long flags;
+
+ round_tmp = clk->ops->round_rate(clk, rate);
+ if (round_tmp == cur_rate)
+ return 0;
+
+
+ for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+ if (round_tmp == clock_table[iter][0])
+ break;
+ }
+
+ if (iter >= ARRAY_SIZE(clock_table))
+ iter = ARRAY_SIZE(clock_table) - 1;
+
+ local_irq_save(flags);
+ if (cur_rate > round_tmp) {
+ /* Frequency Down */
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+ clk_div0_tmp |= clock_table[iter][1];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+ ~(S5P_CLKDIV0_HCLK_MASK);
+ clk_div0_tmp |= clock_table[iter][2];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+
+ } else {
+ /* Frequency Up */
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+ ~(S5P_CLKDIV0_HCLK_MASK);
+ clk_div0_tmp |= clock_table[iter][2];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+ clk_div0_tmp |= clock_table[iter][1];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+ }
+ local_irq_restore(flags);
+
+ clk->rate = clock_table[iter][0];
+
+ return 0;
+}
+
+static struct clk_ops s5p6440_clkarm_ops = {
+ .get_rate = s5p6440_armclk_get_rate,
+ .set_rate = s5p6440_armclk_set_rate,
+ .round_rate = s5p6440_armclk_round_rate,
+};
+
+static unsigned long s5p6440_clk_doutmpll_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+
+ if (__raw_readl(S5P_CLK_DIV0) & S5P_CLKDIV0_MPLL_MASK)
+ rate /= 2;
+
+ return rate;
+}
+
+static struct clk clk_dout_mpll = {
+ .name = "dout_mpll",
+ .id = -1,
+ .parent = &clk_mout_mpll.clk,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5p6440_clk_doutmpll_get_rate,
+ },
+};
+
+int s5p6440_clk48m_ctrl(struct clk *clk, int enable)
+{
+ unsigned long flags;
+ u32 val;
+
+ /* can't rely on clock lock, this register has other usages */
+ local_irq_save(flags);
+
+ val = __raw_readl(S5P_OTHERS);
+ if (enable)
+ val |= S5P_OTHERS_USB_SIG_MASK;
+ else
+ val &= ~S5P_OTHERS_USB_SIG_MASK;
+
+ __raw_writel(val, S5P_OTHERS);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static int s5p6440_pclk_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLK_GATE_PCLK, clk, enable);
+}
+
+static int s5p6440_hclk0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLK_GATE_HCLK0, clk, enable);
+}
+
+static int s5p6440_hclk1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLK_GATE_HCLK1, clk, enable);
+}
+
+static int s5p6440_sclk_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable);
+}
+
+static int s5p6440_mem_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable);
+}
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_disable[] = {
+ {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s5p6440_mem_ctrl,
+ .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON,
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_TSADC,
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_IIC0,
+ }, {
+ .name = "i2s_v40",
+ .id = 0,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_IIS2,
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_SPI0,
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_SPI1,
+ }, {
+ .name = "sclk_spi_48",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s5p6440_sclk_ctrl,
+ .ctrlbit = S5P_CLKCON_SCLK0_SPI0_48,
+ }, {
+ .name = "sclk_spi_48",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s5p6440_sclk_ctrl,
+ .ctrlbit = S5P_CLKCON_SCLK0_SPI1_48,
+ }, {
+ .name = "mmc_48m",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s5p6440_sclk_ctrl,
+ .ctrlbit = S5P_CLKCON_SCLK0_MMC0_48,
+ }, {
+ .name = "mmc_48m",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s5p6440_sclk_ctrl,
+ .ctrlbit = S5P_CLKCON_SCLK0_MMC1_48,
+ }, {
+ .name = "mmc_48m",
+ .id = 2,
+ .parent = &clk_48m,
+ .enable = s5p6440_sclk_ctrl,
+ .ctrlbit = S5P_CLKCON_SCLK0_MMC2_48,
+ }, {
+ .name = "otg",
+ .id = -1,
+ .parent = &clk_h_low,
+ .enable = s5p6440_hclk0_ctrl,
+ .ctrlbit = S5P_CLKCON_HCLK0_USB
+ }, {
+ .name = "post",
+ .id = -1,
+ .parent = &clk_h_low,
+ .enable = s5p6440_hclk0_ctrl,
+ .ctrlbit = S5P_CLKCON_HCLK0_POST0
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h_low,
+ .enable = s5p6440_hclk1_ctrl,
+ .ctrlbit = S5P_CLKCON_HCLK1_DISPCON,
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_h_low,
+ .enable = s5p6440_hclk0_ctrl,
+ .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0,
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_h_low,
+ .enable = s5p6440_hclk0_ctrl,
+ .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1,
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_h_low,
+ .enable = s5p6440_hclk0_ctrl,
+ .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2,
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_RTC,
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_WDT,
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_PWM,
+ }
+};
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+ {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_GPIO,
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_UART0,
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_UART1,
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_UART2,
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_p_low,
+ .enable = s5p6440_pclk_ctrl,
+ .ctrlbit = S5P_CLKCON_PCLK_UART3,
+ }
+};
+
+static struct clk clk_iis_cd_v40 = {
+ .name = "iis_cdclk_v40",
+ .id = -1,
+};
+
+static struct clk clk_pcm_cd = {
+ .name = "pcm_cdclk",
+ .id = -1,
+};
+
+static struct clk *clkset_spi_mmc_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ &clk_fin_epll,
+};
+
+static struct clksrc_sources clkset_spi_mmc = {
+ .sources = clkset_spi_mmc_list,
+ .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 0,
+ .ctrlbit = S5P_CLKCON_SCLK0_MMC0,
+ .enable = s5p6440_sclk_ctrl,
+ },
+ .sources = &clkset_spi_mmc,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 1,
+ .ctrlbit = S5P_CLKCON_SCLK0_MMC1,
+ .enable = s5p6440_sclk_ctrl,
+ },
+ .sources = &clkset_spi_mmc,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 2,
+ .ctrlbit = S5P_CLKCON_SCLK0_MMC2,
+ .enable = s5p6440_sclk_ctrl,
+ },
+ .sources = &clkset_spi_mmc,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = S5P_CLKCON_SCLK0_UART,
+ .enable = s5p6440_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "spi_epll",
+ .id = 0,
+ .ctrlbit = S5P_CLKCON_SCLK0_SPI0,
+ .enable = s5p6440_sclk_ctrl,
+ },
+ .sources = &clkset_spi_mmc,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "spi_epll",
+ .id = 1,
+ .ctrlbit = S5P_CLKCON_SCLK0_SPI1,
+ .enable = s5p6440_sclk_ctrl,
+ },
+ .sources = &clkset_spi_mmc,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
+ }
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *init_parents[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_mout_mpll,
+};
+
+void __init_or_cpufreq s5p6440_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long hclk_low;
+ unsigned long pclk;
+ unsigned long pclk_low;
+ unsigned long epll;
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned int ptr;
+ u32 clkdiv0;
+ u32 clkdiv3;
+
+ /* Set S5P6440 functions for clk_fout_epll */
+ clk_fout_epll.enable = s5p6440_epll_enable;
+ clk_fout_epll.ops = &s5p6440_epll_ops;
+
+ /* Set S5P6440 functions for arm clock */
+ clk_arm.parent = &clk_mout_apll.clk;
+ clk_arm.ops = &s5p6440_clkarm_ops;
+ clk_48m.enable = s5p6440_clk48m_ctrl;
+
+ clkdiv0 = __raw_readl(S5P_CLK_DIV0);
+ clkdiv3 = __raw_readl(S5P_CLK_DIV3);
+
+ xtal_clk = clk_get(NULL, "ext_xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ epll = s5p_get_pll90xx(xtal, __raw_readl(S5P_EPLL_CON),
+ __raw_readl(S5P_EPLL_CON_K));
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
+ apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502);
+
+ printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
+ " E=%ld.%ldMHz\n",
+ print_mhz(apll), print_mhz(mpll), print_mhz(epll));
+
+ fclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_ARM);
+ hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK);
+ pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK);
+
+ if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) {
+ /* Asynchronous mode */
+ hclk_low = mpll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
+ } else {
+ /* Synchronous mode */
+ hclk_low = apll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
+ }
+
+ pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW);
+
+ printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
+ " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
+ print_mhz(hclk), print_mhz(hclk_low),
+ print_mhz(pclk), print_mhz(pclk_low));
+
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_fout_apll.rate = apll;
+
+ clk_f.rate = fclk;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+ clk_h_low.rate = hclk_low;
+ clk_p_low.rate = pclk_low;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+ s3c_set_clksrc(init_parents[ptr], true);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_mout_epll.clk,
+ &clk_mout_mpll.clk,
+ &clk_dout_mpll,
+ &clk_iis_cd_v40,
+ &clk_pcm_cd,
+ &clk_p_low,
+ &clk_h_low,
+};
+
+void __init s5p6440_register_clocks(void)
+{
+ struct clk *clkp;
+ int ret;
+ int ptr;
+
+ ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+ if (ret > 0)
+ printk(KERN_ERR "Failed to register %u clocks\n", ret);
+
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ clkp = init_clocks_disable;
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ (clkp->enable)(clkp, 0);
+ }
+
+ s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c
new file mode 100644
index 00000000000..1794131aeac
--- /dev/null
+++ b/arch/arm/mach-s5p6440/cpu.c
@@ -0,0 +1,114 @@
+/* linux/arch/arm/mach-s5p6440/cpu.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5p6440.h>
+
+static void s5p6440_idle(void)
+{
+ unsigned long val;
+
+ if (!need_resched()) {
+ val = __raw_readl(S5P_PWR_CFG);
+ val &= ~(0x3<<5);
+ val |= (0x1<<5);
+ __raw_writel(val, S5P_PWR_CFG);
+
+ cpu_do_idle();
+ }
+ local_irq_enable();
+}
+
+/* s5p6440_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5p6440_map_io(void)
+{
+ /* initialize any device information early */
+}
+
+void __init s5p6440_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5p6440_register_clocks();
+ s5p6440_setup_clocks();
+}
+
+void __init s5p6440_init_irq(void)
+{
+ /* S5P6440 supports only 2 VIC */
+ u32 vic[2];
+
+ /*
+ * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
+ * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
+ */
+ vic[0] = 0xff800ae7;
+ vic[1] = 0xffbf23e5;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+static struct sysdev_class s5p6440_sysclass = {
+ .name = "s5p6440-core",
+};
+
+static struct sys_device s5p6440_sysdev = {
+ .cls = &s5p6440_sysclass,
+};
+
+static int __init s5p6440_core_init(void)
+{
+ return sysdev_class_register(&s5p6440_sysclass);
+}
+
+core_initcall(s5p6440_core_init);
+
+int __init s5p6440_init(void)
+{
+ printk(KERN_INFO "S5P6440: Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = s5p6440_idle;
+
+ return sysdev_register(&s5p6440_sysdev);
+}
diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p6440/gpio.c
new file mode 100644
index 00000000000..b0ea741177a
--- /dev/null
+++ b/arch/arm/mach-s5p6440/gpio.c
@@ -0,0 +1,322 @@
+/* arch/arm/mach-s5p6440/gpio.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/regs-gpio.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/* GPIO bank summary:
+*
+* Bank GPIOs Style SlpCon ExtInt Group
+* A 6 4Bit Yes 1
+* B 7 4Bit Yes 1
+* C 8 4Bit Yes 2
+* F 2 2Bit Yes 4 [1]
+* G 7 4Bit Yes 5
+* H 10 4Bit[2] Yes 6
+* I 16 2Bit Yes None
+* J 12 2Bit Yes None
+* N 16 2Bit No IRQ_EINT
+* P 8 2Bit Yes 8
+* R 15 4Bit[2] Yes 8
+*
+* [1] BANKF pins 14,15 do not form part of the external interrupt sources
+* [2] BANK has two control registers, GPxCON0 and GPxCON1
+*/
+
+static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ void __iomem *regcon = base;
+ unsigned long con;
+
+ switch (offset) {
+ case 6:
+ offset += 1;
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ regcon -= 4;
+ break;
+ default:
+ offset -= 7;
+ break;
+ }
+
+ con = __raw_readl(regcon);
+ con &= ~(0xf << con_4bit_shift(offset));
+ __raw_writel(con, regcon);
+
+ return 0;
+}
+
+static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ void __iomem *regcon = base;
+ unsigned long con;
+ unsigned long dat;
+ unsigned con_offset = offset;
+
+ switch (con_offset) {
+ case 6:
+ con_offset += 1;
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ regcon -= 4;
+ break;
+ default:
+ con_offset -= 7;
+ break;
+ }
+
+ con = __raw_readl(regcon);
+ con &= ~(0xf << con_4bit_shift(con_offset));
+ con |= 0x1 << con_4bit_shift(con_offset);
+
+ dat = __raw_readl(base + GPIODAT_OFF);
+ if (value)
+ dat |= 1 << offset;
+ else
+ dat &= ~(1 << offset);
+
+ __raw_writel(con, regcon);
+ __raw_writel(dat, base + GPIODAT_OFF);
+
+ return 0;
+}
+
+int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift;
+ u32 con;
+
+ switch (off) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ shift = (off & 7) * 4;
+ reg -= 4;
+ break;
+ case 6:
+ shift = ((off + 1) & 7) * 4;
+ reg -= 4;
+ default:
+ shift = ((off + 1) & 7) * 4;
+ break;
+ }
+
+ if (s3c_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0xf << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
+ {
+ .cfg_eint = 0,
+ }, {
+ .cfg_eint = 7,
+ }, {
+ .cfg_eint = 3,
+ .set_config = s5p6440_gpio_setcfg_4bit_rbank,
+ }, {
+ .cfg_eint = 0,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ }, {
+ .cfg_eint = 2,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ }, {
+ .cfg_eint = 3,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ },
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
+ {
+ .base = S5P6440_GPA_BASE,
+ .config = &s5p6440_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPA(0),
+ .ngpio = S5P6440_GPIO_A_NR,
+ .label = "GPA",
+ },
+ }, {
+ .base = S5P6440_GPB_BASE,
+ .config = &s5p6440_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPB(0),
+ .ngpio = S5P6440_GPIO_B_NR,
+ .label = "GPB",
+ },
+ }, {
+ .base = S5P6440_GPC_BASE,
+ .config = &s5p6440_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPC(0),
+ .ngpio = S5P6440_GPIO_C_NR,
+ .label = "GPC",
+ },
+ }, {
+ .base = S5P6440_GPG_BASE,
+ .config = &s5p6440_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPG(0),
+ .ngpio = S5P6440_GPIO_G_NR,
+ .label = "GPG",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
+ {
+ .base = S5P6440_GPH_BASE + 0x4,
+ .config = &s5p6440_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPH(0),
+ .ngpio = S5P6440_GPIO_H_NR,
+ .label = "GPH",
+ },
+ },
+};
+
+static struct s3c_gpio_chip gpio_rbank_4bit2[] = {
+ {
+ .base = S5P6440_GPR_BASE + 0x4,
+ .config = &s5p6440_gpio_cfgs[2],
+ .chip = {
+ .base = S5P6440_GPR(0),
+ .ngpio = S5P6440_GPIO_R_NR,
+ .label = "GPR",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
+ {
+ .base = S5P6440_GPF_BASE,
+ .config = &s5p6440_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6440_GPF(0),
+ .ngpio = S5P6440_GPIO_F_NR,
+ .label = "GPF",
+ },
+ }, {
+ .base = S5P6440_GPI_BASE,
+ .config = &s5p6440_gpio_cfgs[3],
+ .chip = {
+ .base = S5P6440_GPI(0),
+ .ngpio = S5P6440_GPIO_I_NR,
+ .label = "GPI",
+ },
+ }, {
+ .base = S5P6440_GPJ_BASE,
+ .config = &s5p6440_gpio_cfgs[3],
+ .chip = {
+ .base = S5P6440_GPJ(0),
+ .ngpio = S5P6440_GPIO_J_NR,
+ .label = "GPJ",
+ },
+ }, {
+ .base = S5P6440_GPN_BASE,
+ .config = &s5p6440_gpio_cfgs[4],
+ .chip = {
+ .base = S5P6440_GPN(0),
+ .ngpio = S5P6440_GPIO_N_NR,
+ .label = "GPN",
+ },
+ }, {
+ .base = S5P6440_GPP_BASE,
+ .config = &s5p6440_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6440_GPP(0),
+ .ngpio = S5P6440_GPIO_P_NR,
+ .label = "GPP",
+ },
+ },
+};
+
+void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chipcfg++) {
+ if (!chipcfg->set_config)
+ chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit;
+ if (!chipcfg->set_pull)
+ chipcfg->set_pull = s3c_gpio_setpull_updown;
+ if (!chipcfg->get_pull)
+ chipcfg->get_pull = s3c_gpio_getpull_updown;
+ }
+}
+
+static void __init s5p6440_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
+ int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chip++) {
+ chip->chip.direction_input = s5p6440_gpiolib_rbank_4bit2_input;
+ chip->chip.direction_output =
+ s5p6440_gpiolib_rbank_4bit2_output;
+ s3c_gpiolib_add(chip);
+ }
+}
+
+static int __init s5p6440_gpiolib_init(void)
+{
+ struct s3c_gpio_chip *chips = s5p6440_gpio_2bit;
+ int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit);
+
+ s5p6440_gpiolib_set_cfg(s5p6440_gpio_cfgs,
+ ARRAY_SIZE(s5p6440_gpio_cfgs));
+
+ for (; nr_chips > 0; nr_chips--, chips++)
+ s3c_gpiolib_add(chips);
+
+ samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit,
+ ARRAY_SIZE(s5p6440_gpio_4bit));
+
+ samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
+ ARRAY_SIZE(s5p6440_gpio_4bit2));
+
+ s5p6440_gpio_add_rbank_4bit2(gpio_rbank_4bit2,
+ ARRAY_SIZE(gpio_rbank_4bit2));
+
+ return 0;
+}
+arch_initcall(s5p6440_gpiolib_init);
diff --git a/arch/arm/mach-s5p6440/include/mach/debug-macro.S b/arch/arm/mach-s5p6440/include/mach/debug-macro.S
new file mode 100644
index 00000000000..1347d7f9907
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/debug-macro.S
@@ -0,0 +1,37 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+ /* note, for the boot process to work we have to keep the UART
+ * virtual address aligned to an 1MiB boundary for the L1
+ * mapping the head code makes. We keep the UART virtual address
+ * aligned and add in the offset when we load the value here.
+ */
+
+ .macro addruart, rx, rtmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1
+ ldreq \rx, = S3C_PA_UART
+ ldrne \rx, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5p6440/include/mach/entry-macro.S b/arch/arm/mach-s5p6440/include/mach/entry-macro.S
new file mode 100644
index 00000000000..e65f1b96726
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/entry-macro.S
@@ -0,0 +1,16 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Low-level IRQ helper macros for the Samsung S5P6440
+ *
+ * This program is free software; you can 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/map.h>
+#include <plat/irqs.h>
+
+#include <asm/entry-macro-vic2.S>
diff --git a/arch/arm/mach-s5p6440/include/mach/gpio.h b/arch/arm/mach-s5p6440/include/mach/gpio.h
new file mode 100644
index 00000000000..21783834f2a
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/gpio.h
@@ -0,0 +1,80 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/gpio.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#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
+
+/* GPIO bank sizes */
+#define S5P6440_GPIO_A_NR (6)
+#define S5P6440_GPIO_B_NR (7)
+#define S5P6440_GPIO_C_NR (8)
+#define S5P6440_GPIO_F_NR (2)
+#define S5P6440_GPIO_G_NR (7)
+#define S5P6440_GPIO_H_NR (10)
+#define S5P6440_GPIO_I_NR (16)
+#define S5P6440_GPIO_J_NR (12)
+#define S5P6440_GPIO_N_NR (16)
+#define S5P6440_GPIO_P_NR (8)
+#define S5P6440_GPIO_R_NR (15)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+#define S5P6440_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+ S5P6440_GPIO_A_START = 0,
+ S5P6440_GPIO_B_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_A),
+ S5P6440_GPIO_C_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_B),
+ S5P6440_GPIO_F_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_C),
+ S5P6440_GPIO_G_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_F),
+ S5P6440_GPIO_H_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_G),
+ S5P6440_GPIO_I_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_H),
+ S5P6440_GPIO_J_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_I),
+ S5P6440_GPIO_N_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_J),
+ S5P6440_GPIO_P_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_N),
+ S5P6440_GPIO_R_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_P),
+};
+
+/* S5P6440 GPIO number definitions. */
+#define S5P6440_GPA(_nr) (S5P6440_GPIO_A_START + (_nr))
+#define S5P6440_GPB(_nr) (S5P6440_GPIO_B_START + (_nr))
+#define S5P6440_GPC(_nr) (S5P6440_GPIO_C_START + (_nr))
+#define S5P6440_GPF(_nr) (S5P6440_GPIO_F_START + (_nr))
+#define S5P6440_GPG(_nr) (S5P6440_GPIO_G_START + (_nr))
+#define S5P6440_GPH(_nr) (S5P6440_GPIO_H_START + (_nr))
+#define S5P6440_GPI(_nr) (S5P6440_GPIO_I_START + (_nr))
+#define S5P6440_GPJ(_nr) (S5P6440_GPIO_J_START + (_nr))
+#define S5P6440_GPN(_nr) (S5P6440_GPIO_N_START + (_nr))
+#define S5P6440_GPP(_nr) (S5P6440_GPIO_P_START + (_nr))
+#define S5P6440_GPR(_nr) (S5P6440_GPIO_R_START + (_nr))
+
+/* the end of the S5P6440 specific gpios */
+#define S5P6440_GPIO_END (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1)
+#define S3C_GPIO_END S5P6440_GPIO_END
+
+/* define the number of gpios we need to the one after the GPR() range */
+#define ARCH_NR_GPIOS (S5P6440_GPR(S5P6440_GPIO_R_NR) + \
+ CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/hardware.h b/arch/arm/mach-s5p6440/include/mach/hardware.h
new file mode 100644
index 00000000000..be8b26e875d
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/hardware.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/hardware.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/io.h b/arch/arm/mach-s5p6440/include/mach/io.h
new file mode 100644
index 00000000000..fa2d69cb1ad
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/io.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s5p6440/include/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S3C64XX based
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s5p6440/include/mach/irqs.h b/arch/arm/mach-s5p6440/include/mach/irqs.h
new file mode 100644
index 00000000000..a4b9b40d18f
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/irqs.h
@@ -0,0 +1,111 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/irqs.h
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_S5P_IRQS_H
+#define __ASM_ARCH_S5P_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* VIC0 */
+
+#define IRQ_EINT0_3 S5P_IRQ_VIC0(0)
+#define IRQ_EINT4_11 S5P_IRQ_VIC0(1)
+#define IRQ_RTC_TIC S5P_IRQ_VIC0(2)
+#define IRQ_IIC1 S5P_IRQ_VIC0(5)
+#define IRQ_I2SV40 S5P_IRQ_VIC0(6)
+#define IRQ_GPS S5P_IRQ_VIC0(7)
+#define IRQ_POST0 S5P_IRQ_VIC0(9)
+#define IRQ_2D S5P_IRQ_VIC0(11)
+#define IRQ_TIMER0_VIC S5P_IRQ_VIC0(23)
+#define IRQ_TIMER1_VIC S5P_IRQ_VIC0(24)
+#define IRQ_TIMER2_VIC S5P_IRQ_VIC0(25)
+#define IRQ_WDT S5P_IRQ_VIC0(26)
+#define IRQ_TIMER3_VIC S5P_IRQ_VIC0(27)
+#define IRQ_TIMER4_VIC S5P_IRQ_VIC0(28)
+#define IRQ_DISPCON0 S5P_IRQ_VIC0(29)
+#define IRQ_DISPCON1 S5P_IRQ_VIC0(30)
+#define IRQ_DISPCON2 S5P_IRQ_VIC0(31)
+
+/* VIC1 */
+
+#define IRQ_EINT12_15 S5P_IRQ_VIC1(0)
+#define IRQ_PCM0 S5P_IRQ_VIC1(2)
+#define IRQ_UART0 S5P_IRQ_VIC1(5)
+#define IRQ_UART1 S5P_IRQ_VIC1(6)
+#define IRQ_UART2 S5P_IRQ_VIC1(7)
+#define IRQ_UART3 S5P_IRQ_VIC1(8)
+#define IRQ_DMA0 S5P_IRQ_VIC1(9)
+#define IRQ_NFC S5P_IRQ_VIC1(13)
+#define IRQ_SPI0 S5P_IRQ_VIC1(16)
+#define IRQ_SPI1 S5P_IRQ_VIC1(17)
+#define IRQ_IIC S5P_IRQ_VIC1(18)
+#define IRQ_DISPCON3 S5P_IRQ_VIC1(19)
+#define IRQ_FIMGVG S5P_IRQ_VIC1(20)
+#define IRQ_EINT_GROUPS S5P_IRQ_VIC1(21)
+#define IRQ_PMUIRQ S5P_IRQ_VIC1(23)
+#define IRQ_HSMMC0 S5P_IRQ_VIC1(24)
+#define IRQ_HSMMC1 S5P_IRQ_VIC1(25)
+#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */
+#define IRQ_OTG S5P_IRQ_VIC1(26)
+#define IRQ_DSI S5P_IRQ_VIC1(27)
+#define IRQ_RTC_ALARM S5P_IRQ_VIC1(28)
+#define IRQ_TSI S5P_IRQ_VIC1(29)
+#define IRQ_PENDN S5P_IRQ_VIC1(30)
+#define IRQ_TC IRQ_PENDN
+#define IRQ_ADC S5P_IRQ_VIC1(31)
+
+/*
+ * Since the IRQ_EINT(x) are a linear mapping on s5p6440 we just defined
+ * them as an IRQ_EINT(x) macro from S5P_IRQ_EINT_BASE which we place
+ * after the pair of VICs.
+ */
+
+#define S5P_IRQ_EINT_BASE (S5P_IRQ_VIC1(31) + 6)
+
+#define S5P_EINT(x) ((x) + S5P_IRQ_EINT_BASE)
+#define IRQ_EINT(x) S5P_EINT(x)
+
+/*
+ * Next the external interrupt groups. These are similar to the IRQ_EINT(x)
+ * that they are sourced from the GPIO pins but with a different scheme for
+ * priority and source indication.
+ *
+ * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
+ * interrupts, but for historical reasons they are kept apart from these
+ * next interrupts.
+ *
+ * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
+ * machine specific support files.
+ */
+
+/* Actually, #6 and #7 are missing in the EINT_GROUP1 */
+#define IRQ_EINT_GROUP1_NR (15)
+#define IRQ_EINT_GROUP2_NR (8)
+#define IRQ_EINT_GROUP5_NR (7)
+#define IRQ_EINT_GROUP6_NR (10)
+/* Actually, #0, #1 and #2 are missing in the EINT_GROUP8 */
+#define IRQ_EINT_GROUP8_NR (11)
+
+#define IRQ_EINT_GROUP_BASE S5P_EINT(16)
+#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0)
+#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
+#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
+#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
+#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
+
+#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x))
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
+
+#endif /* __ASM_ARCH_S5P_IRQS_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h
new file mode 100644
index 00000000000..8924e5a4d6a
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/map.h
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/map.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5P6440_PA_CHIPID (0xE0000000)
+#define S5P_PA_CHIPID S5P6440_PA_CHIPID
+
+#define S5P6440_PA_SYSCON (0xE0100000)
+#define S5P6440_PA_CLK (S5P6440_PA_SYSCON + 0x0)
+#define S5P_PA_SYSCON S5P6440_PA_SYSCON
+
+#define S5P6440_PA_GPIO (0xE0308000)
+#define S5P_PA_GPIO S5P6440_PA_GPIO
+
+#define S5P6440_PA_VIC0 (0xE4000000)
+#define S5P_PA_VIC0 S5P6440_PA_VIC0
+
+#define S5P6440_PA_VIC1 (0xE4100000)
+#define S5P_PA_VIC1 S5P6440_PA_VIC1
+
+#define S5P6440_PA_TIMER (0xEA000000)
+#define S5P_PA_TIMER S5P6440_PA_TIMER
+
+#define S5P6440_PA_RTC (0xEA100000)
+#define S5P_PA_RTC S5P6440_PA_RTC
+
+#define S5P6440_PA_WDT (0xEA200000)
+#define S5P_PA_WDT S5P6440_PA_WDT
+
+#define S5P6440_PA_UART (0xEC000000)
+
+#define S5P_PA_UART0 (S5P6440_PA_UART + 0x0)
+#define S5P_PA_UART1 (S5P6440_PA_UART + 0x400)
+#define S5P_PA_UART2 (S5P6440_PA_UART + 0x800)
+#define S5P_PA_UART3 (S5P6440_PA_UART + 0xC00)
+
+#define S5P_SZ_UART SZ_256
+
+#define S5P6440_PA_IIC0 (0xEC104000)
+
+#define S5P6440_PA_HSOTG (0xED100000)
+
+#define S5P6440_PA_HSMMC0 (0xED800000)
+#define S5P6440_PA_HSMMC1 (0xED900000)
+#define S5P6440_PA_HSMMC2 (0xEDA00000)
+
+#define S5P6440_PA_SDRAM (0x20000000)
+#define S5P_PA_SDRAM S5P6440_PA_SDRAM
+
+/* compatibiltiy defines. */
+#define S3C_PA_UART S5P6440_PA_UART
+#define S3C_PA_IIC S5P6440_PA_IIC0
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/memory.h b/arch/arm/mach-s5p6440/include/mach/memory.h
new file mode 100644
index 00000000000..d62910c71b5
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/memory.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/memory.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET UL(0x20000000)
+#define CONSISTENT_DMA_SIZE SZ_8M
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h b/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
new file mode 100644
index 00000000000..c4bb7c55547
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
@@ -0,0 +1,62 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @cfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return tcfg == S3C2410_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << (1 + tcfg1);
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 0;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div) - 1;
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
diff --git a/arch/arm/mach-s5p6440/include/mach/regs-clock.h b/arch/arm/mach-s5p6440/include/mach/regs-clock.h
new file mode 100644
index 00000000000..c783ecc9f19
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/regs-clock.h
@@ -0,0 +1,130 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S5P_APLL_LOCK S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK S5P_CLKREG(0x04)
+#define S5P_EPLL_LOCK S5P_CLKREG(0x08)
+#define S5P_APLL_CON S5P_CLKREG(0x0C)
+#define S5P_MPLL_CON S5P_CLKREG(0x10)
+#define S5P_EPLL_CON S5P_CLKREG(0x14)
+#define S5P_EPLL_CON_K S5P_CLKREG(0x18)
+#define S5P_CLK_SRC0 S5P_CLKREG(0x1C)
+#define S5P_CLK_DIV0 S5P_CLKREG(0x20)
+#define S5P_CLK_DIV1 S5P_CLKREG(0x24)
+#define S5P_CLK_DIV2 S5P_CLKREG(0x28)
+#define S5P_CLK_OUT S5P_CLKREG(0x2C)
+#define S5P_CLK_GATE_HCLK0 S5P_CLKREG(0x30)
+#define S5P_CLK_GATE_PCLK S5P_CLKREG(0x34)
+#define S5P_CLK_GATE_SCLK0 S5P_CLKREG(0x38)
+#define S5P_CLK_GATE_MEM0 S5P_CLKREG(0x3C)
+#define S5P_CLK_DIV3 S5P_CLKREG(0x40)
+#define S5P_CLK_GATE_HCLK1 S5P_CLKREG(0x44)
+#define S5P_CLK_GATE_SCLK1 S5P_CLKREG(0x48)
+#define S5P_AHB_CON0 S5P_CLKREG(0x100)
+#define S5P_CLK_SRC1 S5P_CLKREG(0x10C)
+#define S5P_SWRESET S5P_CLKREG(0x114)
+#define S5P_SYS_ID S5P_CLKREG(0x118)
+#define S5P_SYS_OTHERS S5P_CLKREG(0x11C)
+#define S5P_MEM_CFG_STAT S5P_CLKREG(0x12C)
+#define S5P_PWR_CFG S5P_CLKREG(0x804)
+#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0x808)
+#define S5P_NORMAL_CFG S5P_CLKREG(0x810)
+#define S5P_STOP_CFG S5P_CLKREG(0x814)
+#define S5P_SLEEP_CFG S5P_CLKREG(0x818)
+#define S5P_OSC_FREQ S5P_CLKREG(0x820)
+#define S5P_OSC_STABLE S5P_CLKREG(0x824)
+#define S5P_PWR_STABLE S5P_CLKREG(0x828)
+#define S5P_MTC_STABLE S5P_CLKREG(0x830)
+#define S5P_OTHERS S5P_CLKREG(0x900)
+#define S5P_RST_STAT S5P_CLKREG(0x904)
+#define S5P_WAKEUP_STAT S5P_CLKREG(0x908)
+#define S5P_SLPEN S5P_CLKREG(0x930)
+#define S5P_INFORM0 S5P_CLKREG(0xA00)
+#define S5P_INFORM1 S5P_CLKREG(0xA04)
+#define S5P_INFORM2 S5P_CLKREG(0xA08)
+#define S5P_INFORM3 S5P_CLKREG(0xA0C)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_PCLK_MASK (0xf << 12)
+#define S5P_CLKDIV0_PCLK_SHIFT (12)
+#define S5P_CLKDIV0_HCLK_MASK (0xf << 8)
+#define S5P_CLKDIV0_HCLK_SHIFT (8)
+#define S5P_CLKDIV0_MPLL_MASK (0x1 << 4)
+#define S5P_CLKDIV0_ARM_MASK (0xf << 0)
+#define S5P_CLKDIV0_ARM_SHIFT (0)
+
+/* CLKDIV3 */
+#define S5P_CLKDIV3_PCLK_LOW_MASK (0xf << 12)
+#define S5P_CLKDIV3_PCLK_LOW_SHIFT (12)
+#define S5P_CLKDIV3_HCLK_LOW_MASK (0xf << 8)
+#define S5P_CLKDIV3_HCLK_LOW_SHIFT (8)
+
+/* HCLK0 GATE Registers */
+#define S5P_CLKCON_HCLK0_USB (1<<20)
+#define S5P_CLKCON_HCLK0_HSMMC2 (1<<19)
+#define S5P_CLKCON_HCLK0_HSMMC1 (1<<18)
+#define S5P_CLKCON_HCLK0_HSMMC0 (1<<17)
+#define S5P_CLKCON_HCLK0_POST0 (1<<5)
+
+/* HCLK1 GATE Registers */
+#define S5P_CLKCON_HCLK1_DISPCON (1<<1)
+
+/* PCLK GATE Registers */
+#define S5P_CLKCON_PCLK_IIS2 (1<<26)
+#define S5P_CLKCON_PCLK_SPI1 (1<<22)
+#define S5P_CLKCON_PCLK_SPI0 (1<<21)
+#define S5P_CLKCON_PCLK_GPIO (1<<18)
+#define S5P_CLKCON_PCLK_IIC0 (1<<17)
+#define S5P_CLKCON_PCLK_TSADC (1<<12)
+#define S5P_CLKCON_PCLK_PWM (1<<7)
+#define S5P_CLKCON_PCLK_RTC (1<<6)
+#define S5P_CLKCON_PCLK_WDT (1<<5)
+#define S5P_CLKCON_PCLK_UART3 (1<<4)
+#define S5P_CLKCON_PCLK_UART2 (1<<3)
+#define S5P_CLKCON_PCLK_UART1 (1<<2)
+#define S5P_CLKCON_PCLK_UART0 (1<<1)
+
+/* SCLK0 GATE Registers */
+#define S5P_CLKCON_SCLK0_MMC2_48 (1<<29)
+#define S5P_CLKCON_SCLK0_MMC1_48 (1<<28)
+#define S5P_CLKCON_SCLK0_MMC0_48 (1<<27)
+#define S5P_CLKCON_SCLK0_MMC2 (1<<26)
+#define S5P_CLKCON_SCLK0_MMC1 (1<<25)
+#define S5P_CLKCON_SCLK0_MMC0 (1<<24)
+#define S5P_CLKCON_SCLK0_SPI1_48 (1<<23)
+#define S5P_CLKCON_SCLK0_SPI0_48 (1<<22)
+#define S5P_CLKCON_SCLK0_SPI1 (1<<21)
+#define S5P_CLKCON_SCLK0_SPI0 (1<<20)
+#define S5P_CLKCON_SCLK0_UART (1<<5)
+
+/* SCLK1 GATE Registers */
+
+/* MEM0 GATE Registers */
+#define S5P_CLKCON_MEM0_HCLK_NFCON (1<<2)
+
+/*OTHERS Resgister */
+#define S5P_OTHERS_USB_SIG_MASK (1<<16)
+#define S5P_OTHERS_HCLK_LOW_SEL_MPLL (1<<6)
+
+/* Compatibility defines */
+#define ARM_CLK_DIV S5P_CLK_DIV0
+#define ARM_DIV_RATIO_SHIFT 0
+#define ARM_DIV_MASK (0xf << ARM_DIV_RATIO_SHIFT)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/regs-gpio.h b/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
new file mode 100644
index 00000000000..82ff753913d
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - GPIO register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+/* Base addresses for each of the banks */
+#define S5P6440_GPA_BASE (S5P_VA_GPIO + 0x0000)
+#define S5P6440_GPB_BASE (S5P_VA_GPIO + 0x0020)
+#define S5P6440_GPC_BASE (S5P_VA_GPIO + 0x0040)
+#define S5P6440_GPF_BASE (S5P_VA_GPIO + 0x00A0)
+#define S5P6440_GPG_BASE (S5P_VA_GPIO + 0x00C0)
+#define S5P6440_GPH_BASE (S5P_VA_GPIO + 0x00E0)
+#define S5P6440_GPI_BASE (S5P_VA_GPIO + 0x0100)
+#define S5P6440_GPJ_BASE (S5P_VA_GPIO + 0x0120)
+#define S5P6440_GPN_BASE (S5P_VA_GPIO + 0x0830)
+#define S5P6440_GPP_BASE (S5P_VA_GPIO + 0x0160)
+#define S5P6440_GPR_BASE (S5P_VA_GPIO + 0x0290)
+#define S5P6440_EINT0CON0 (S5P_VA_GPIO + 0x900)
+#define S5P6440_EINT0FLTCON0 (S5P_VA_GPIO + 0x910)
+#define S5P6440_EINT0FLTCON1 (S5P_VA_GPIO + 0x914)
+#define S5P6440_EINT0MASK (S5P_VA_GPIO + 0x920)
+#define S5P6440_EINT0PEND (S5P_VA_GPIO + 0x924)
+
+/* for LCD */
+#define S5P6440_SPCON_LCD_SEL_RGB (1 << 0)
+#define S5P6440_SPCON_LCD_SEL_MASK (3 << 0)
+
+/* These set of macros are not really useful for the
+ * GPF/GPI/GPJ/GPN/GPP,
+ * useful for others set of GPIO's (4 bit)
+ */
+#define S5P6440_GPIO_CONMASK(__gpio) (0xf << ((__gpio) * 4))
+#define S5P6440_GPIO_INPUT(__gpio) (0x0 << ((__gpio) * 4))
+#define S5P6440_GPIO_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
+
+/* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit)
+ * */
+#define S5P6440_GPIO2_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S5P6440_GPIO2_INPUT(__gpio) (0x0 << ((__gpio) * 2))
+#define S5P6440_GPIO2_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/regs-irq.h b/arch/arm/mach-s5p6440/include/mach/regs-irq.h
new file mode 100644
index 00000000000..a961f4beeb0
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/system.h b/arch/arm/mach-s5p6440/include/mach/system.h
new file mode 100644
index 00000000000..d2dd817da66
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/system.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/system.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+static void arch_idle(void)
+{
+ /* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ /* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/tick.h b/arch/arm/mach-s5p6440/include/mach/tick.h
new file mode 100644
index 00000000000..2f25c7f0797
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/tick.h
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/tick.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX (0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/timex.h b/arch/arm/mach-s5p6440/include/mach/timex.h
new file mode 100644
index 00000000000..fb2e8cd4082
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/timex.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c64xx/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/uncompress.h b/arch/arm/mach-s5p6440/include/mach/uncompress.h
new file mode 100644
index 00000000000..7c1f600d65c
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/uncompress.h
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5p6440/include/mach/uncompress.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/vmalloc.h b/arch/arm/mach-s5p6440/include/mach/vmalloc.h
new file mode 100644
index 00000000000..16df257b1dc
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/vmalloc.h
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5p6440/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.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.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5p6440/init.c b/arch/arm/mach-s5p6440/init.c
new file mode 100644
index 00000000000..a1f3727e402
--- /dev/null
+++ b/arch/arm/mach-s5p6440/init.c
@@ -0,0 +1,52 @@
+/* linux/arch/arm/mach-s5p6440/init.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6440 - Init support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5p6440.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5p6440_serial_clocks[] = {
+ [0] = {
+ .name = "pclk_low",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "uclk1",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+};
+
+/* uart registration process */
+void __init s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ struct s3c2410_uartcfg *tcfg = cfg;
+ u32 ucnt;
+
+ for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+ if (!tcfg->clocks) {
+ tcfg->clocks = s5p6440_serial_clocks;
+ tcfg->clocks_size = ARRAY_SIZE(s5p6440_serial_clocks);
+ }
+ }
+
+ s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-s5p6440/mach-smdk6440.c b/arch/arm/mach-s5p6440/mach-smdk6440.c
new file mode 100644
index 00000000000..3ae88f2c7c7
--- /dev/null
+++ b/arch/arm/mach-s5p6440/mach-smdk6440.c
@@ -0,0 +1,111 @@
+/* linux/arch/arm/mach-s5p6440/mach-smdk6440.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+
+#include <plat/s5p6440.h>
+#include <plat/clock.h>
+#include <mach/regs-clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+
+#define S5P6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define S5P6440_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define S5P6440_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S3C2440_UFCON_TXTRIG16 | \
+ S3C2410_UFCON_RXTRIG8)
+
+static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = S5P6440_UCON_DEFAULT,
+ .ulcon = S5P6440_ULCON_DEFAULT,
+ .ufcon = S5P6440_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = S5P6440_UCON_DEFAULT,
+ .ulcon = S5P6440_ULCON_DEFAULT,
+ .ufcon = S5P6440_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = S5P6440_UCON_DEFAULT,
+ .ulcon = S5P6440_ULCON_DEFAULT,
+ .ufcon = S5P6440_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = S5P6440_UCON_DEFAULT,
+ .ulcon = S5P6440_ULCON_DEFAULT,
+ .ufcon = S5P6440_UFCON_DEFAULT,
+ },
+};
+
+static struct platform_device *smdk6440_devices[] __initdata = {
+};
+
+static void __init smdk6440_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_SYS_ID);
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
+}
+
+static void __init smdk6440_machine_init(void)
+{
+ platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
+}
+
+MACHINE_START(SMDK6440, "SMDK6440")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S5P_PA_SDRAM + 0x100,
+
+ .init_irq = s5p6440_init_irq,
+ .map_io = smdk6440_map_io,
+ .init_machine = smdk6440_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5p6442/Kconfig b/arch/arm/mach-s5p6442/Kconfig
new file mode 100644
index 00000000000..4f3f6de6a01
--- /dev/null
+++ b/arch/arm/mach-s5p6442/Kconfig
@@ -0,0 +1,24 @@
+# arch/arm/mach-s5p6442/Kconfig
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+# Configuration options for the S5P6442
+
+if ARCH_S5P6442
+
+config CPU_S5P6442
+ bool
+ select PLAT_S5P
+ help
+ Enable S5P6442 CPU support
+
+config MACH_SMDK6442
+ bool "SMDK6442"
+ select CPU_S5P6442
+ help
+ Machine support for Samsung SMDK6442
+
+endif
diff --git a/arch/arm/mach-s5p6442/Makefile b/arch/arm/mach-s5p6442/Makefile
new file mode 100644
index 00000000000..dde39a6ce6b
--- /dev/null
+++ b/arch/arm/mach-s5p6442/Makefile
@@ -0,0 +1,19 @@
+# arch/arm/mach-s5p6442/Makefile
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core support for S5P6442 system
+
+obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDK6442) += mach-smdk6442.o
diff --git a/arch/arm/mach-s5p6442/Makefile.boot b/arch/arm/mach-s5p6442/Makefile.boot
new file mode 100644
index 00000000000..ff90aa13bd6
--- /dev/null
+++ b/arch/arm/mach-s5p6442/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
diff --git a/arch/arm/mach-s5p6442/clock.c b/arch/arm/mach-s5p6442/clock.c
new file mode 100644
index 00000000000..3aadbf42c11
--- /dev/null
+++ b/arch/arm/mach-s5p6442/clock.c
@@ -0,0 +1,396 @@
+/* linux/arch/arm/mach-s5p6442/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6442.h>
+
+static struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .sources = &clk_src_mpll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+/* Possible clock sources for ARM Mux */
+static struct clk *clk_src_arm_list[] = {
+ [1] = &clk_mout_apll.clk,
+ [2] = &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clk_src_arm = {
+ .sources = clk_src_arm_list,
+ .nr_sources = ARRAY_SIZE(clk_src_arm_list),
+};
+
+static struct clksrc_clk clk_mout_arm = {
+ .clk = {
+ .name = "mout_arm",
+ .id = -1,
+ },
+ .sources = &clk_src_arm,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 16, .size = 3 },
+};
+
+static struct clk clk_dout_a2m = {
+ .name = "dout_a2m",
+ .id = -1,
+ .parent = &clk_mout_apll.clk,
+};
+
+/* Possible clock sources for D0 Mux */
+static struct clk *clk_src_d0_list[] = {
+ [1] = &clk_mout_mpll.clk,
+ [2] = &clk_dout_a2m,
+};
+
+static struct clksrc_sources clk_src_d0 = {
+ .sources = clk_src_d0_list,
+ .nr_sources = ARRAY_SIZE(clk_src_d0_list),
+};
+
+static struct clksrc_clk clk_mout_d0 = {
+ .clk = {
+ .name = "mout_d0",
+ .id = -1,
+ },
+ .sources = &clk_src_d0,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 20, .size = 3 },
+};
+
+static struct clk clk_dout_apll = {
+ .name = "dout_apll",
+ .id = -1,
+ .parent = &clk_mout_arm.clk,
+};
+
+/* Possible clock sources for D0SYNC Mux */
+static struct clk *clk_src_d0sync_list[] = {
+ [1] = &clk_mout_d0.clk,
+ [2] = &clk_dout_apll,
+};
+
+static struct clksrc_sources clk_src_d0sync = {
+ .sources = clk_src_d0sync_list,
+ .nr_sources = ARRAY_SIZE(clk_src_d0sync_list),
+};
+
+static struct clksrc_clk clk_mout_d0sync = {
+ .clk = {
+ .name = "mout_d0sync",
+ .id = -1,
+ },
+ .sources = &clk_src_d0sync,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 },
+};
+
+/* Possible clock sources for D1 Mux */
+static struct clk *clk_src_d1_list[] = {
+ [1] = &clk_mout_mpll.clk,
+ [2] = &clk_dout_a2m,
+};
+
+static struct clksrc_sources clk_src_d1 = {
+ .sources = clk_src_d1_list,
+ .nr_sources = ARRAY_SIZE(clk_src_d1_list),
+};
+
+static struct clksrc_clk clk_mout_d1 = {
+ .clk = {
+ .name = "mout_d1",
+ .id = -1,
+ },
+ .sources = &clk_src_d1,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 24, .size = 3 },
+};
+
+/* Possible clock sources for D1SYNC Mux */
+static struct clk *clk_src_d1sync_list[] = {
+ [1] = &clk_mout_d1.clk,
+ [2] = &clk_dout_apll,
+};
+
+static struct clksrc_sources clk_src_d1sync = {
+ .sources = clk_src_d1sync_list,
+ .nr_sources = ARRAY_SIZE(clk_src_d1sync_list),
+};
+
+static struct clksrc_clk clk_mout_d1sync = {
+ .clk = {
+ .name = "mout_d1sync",
+ .id = -1,
+ },
+ .sources = &clk_src_d1sync,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 },
+};
+
+static struct clk clk_hclkd0 = {
+ .name = "hclkd0",
+ .id = -1,
+ .parent = &clk_mout_d0sync.clk,
+};
+
+static struct clk clk_hclkd1 = {
+ .name = "hclkd1",
+ .id = -1,
+ .parent = &clk_mout_d1sync.clk,
+};
+
+static struct clk clk_pclkd0 = {
+ .name = "pclkd0",
+ .id = -1,
+ .parent = &clk_hclkd0,
+};
+
+static struct clk clk_pclkd1 = {
+ .name = "pclkd1",
+ .id = -1,
+ .parent = &clk_hclkd1,
+};
+
+int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
+}
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "dout_a2m",
+ .id = -1,
+ .parent = &clk_mout_apll.clk,
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
+ }, {
+ .clk = {
+ .name = "dout_apll",
+ .id = -1,
+ .parent = &clk_mout_arm.clk,
+ },
+ .sources = &clk_src_arm,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT0, .shift = 16, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
+ }, {
+ .clk = {
+ .name = "hclkd1",
+ .id = -1,
+ .parent = &clk_mout_d1sync.clk,
+ },
+ .sources = &clk_src_d1sync,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "hclkd0",
+ .id = -1,
+ .parent = &clk_mout_d0sync.clk,
+ },
+ .sources = &clk_src_d0sync,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "pclkd0",
+ .id = -1,
+ .parent = &clk_hclkd0,
+ },
+ .sources = &clk_src_d0sync,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 28, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
+ }, {
+ .clk = {
+ .name = "pclkd1",
+ .id = -1,
+ .parent = &clk_hclkd1,
+ },
+ .sources = &clk_src_d1sync,
+ .reg_src = { .reg = S5P_CLK_MUX_STAT1, .shift = 24, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
+ }
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *init_parents[] = {
+ &clk_mout_apll,
+ &clk_mout_mpll,
+ &clk_mout_epll,
+ &clk_mout_arm,
+ &clk_mout_d0,
+ &clk_mout_d0sync,
+ &clk_mout_d1,
+ &clk_mout_d1sync,
+};
+
+void __init_or_cpufreq s5p6442_setup_clocks(void)
+{
+ struct clk *pclkd0_clk;
+ struct clk *pclkd1_clk;
+
+ unsigned long xtal;
+ unsigned long arm;
+ unsigned long hclkd0 = 0;
+ unsigned long hclkd1 = 0;
+ unsigned long pclkd0 = 0;
+ unsigned long pclkd1 = 0;
+
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned int ptr;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ xtal = clk_get_rate(&clk_xtal);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+ apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
+ epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
+
+ printk(KERN_INFO "S5P6440: PLL settings, A=%ld, M=%ld, E=%ld",
+ apll, mpll, epll);
+
+ clk_fout_apll.rate = apll;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+ s3c_set_clksrc(init_parents[ptr], true);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+
+ arm = clk_get_rate(&clk_dout_apll);
+ hclkd0 = clk_get_rate(&clk_hclkd0);
+ hclkd1 = clk_get_rate(&clk_hclkd1);
+
+ pclkd0_clk = clk_get(NULL, "pclkd0");
+ BUG_ON(IS_ERR(pclkd0_clk));
+
+ pclkd0 = clk_get_rate(pclkd0_clk);
+ clk_put(pclkd0_clk);
+
+ pclkd1_clk = clk_get(NULL, "pclkd1");
+ BUG_ON(IS_ERR(pclkd1_clk));
+
+ pclkd1 = clk_get_rate(pclkd1_clk);
+ clk_put(pclkd1_clk);
+
+ printk(KERN_INFO "S5P6442: HCLKD0=%ld, HCLKD1=%ld, PCLKD0=%ld, PCLKD1=%ld\n",
+ hclkd0, hclkd1, pclkd0, pclkd1);
+
+ /* For backward compatibility */
+ clk_f.rate = arm;
+ clk_h.rate = hclkd1;
+ clk_p.rate = pclkd1;
+
+ clk_pclkd0.rate = pclkd0;
+ clk_pclkd1.rate = pclkd1;
+}
+
+static struct clk init_clocks[] = {
+ {
+ .name = "systimer",
+ .id = -1,
+ .parent = &clk_pclkd1,
+ .enable = s5p6442_clk_ip3_ctrl,
+ .ctrlbit = (1<<16),
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_pclkd1,
+ .enable = s5p6442_clk_ip3_ctrl,
+ .ctrlbit = (1<<17),
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_pclkd1,
+ .enable = s5p6442_clk_ip3_ctrl,
+ .ctrlbit = (1<<18),
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_pclkd1,
+ .enable = s5p6442_clk_ip3_ctrl,
+ .ctrlbit = (1<<19),
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_pclkd1,
+ .enable = s5p6442_clk_ip3_ctrl,
+ .ctrlbit = (1<<23),
+ },
+};
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_epll,
+ &clk_mout_apll.clk,
+ &clk_mout_mpll.clk,
+ &clk_mout_epll.clk,
+ &clk_mout_d0.clk,
+ &clk_mout_d0sync.clk,
+ &clk_mout_d1.clk,
+ &clk_mout_d1sync.clk,
+ &clk_hclkd0,
+ &clk_pclkd0,
+ &clk_hclkd1,
+ &clk_pclkd1,
+};
+
+void __init s5p6442_register_clocks(void)
+{
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c
new file mode 100644
index 00000000000..bc2524df89b
--- /dev/null
+++ b/arch/arm/mach-s5p6442/cpu.c
@@ -0,0 +1,121 @@
+/* linux/arch/arm/mach-s5p6442/cpu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5p6442.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5p6442_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SYSTIMER,
+ .pfn = __phys_to_pfn(S5P6442_PA_SYSTIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC2,
+ .pfn = __phys_to_pfn(S5P6442_PA_VIC2),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }
+};
+
+static void s5p6442_idle(void)
+{
+ if (!need_resched())
+ cpu_do_idle();
+
+ local_irq_enable();
+}
+
+/* s5p6442_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5p6442_map_io(void)
+{
+ iotable_init(s5p6442_iodesc, ARRAY_SIZE(s5p6442_iodesc));
+}
+
+void __init s5p6442_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5p6442_register_clocks();
+ s5p6442_setup_clocks();
+}
+
+void __init s5p6442_init_irq(void)
+{
+ /* S5P6442 supports 3 VIC */
+ u32 vic[3];
+
+ /* VIC0, VIC1, and VIC2: some interrupt reserved */
+ vic[0] = 0x7fefffff;
+ vic[1] = 0X7f389c81;
+ vic[2] = 0X1bbbcfff;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+static struct sysdev_class s5p6442_sysclass = {
+ .name = "s5p6442-core",
+};
+
+static struct sys_device s5p6442_sysdev = {
+ .cls = &s5p6442_sysclass,
+};
+
+static int __init s5p6442_core_init(void)
+{
+ return sysdev_class_register(&s5p6442_sysclass);
+}
+
+core_initcall(s5p6442_core_init);
+
+int __init s5p6442_init(void)
+{
+ printk(KERN_INFO "S5P6442: Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = s5p6442_idle;
+
+ return sysdev_register(&s5p6442_sysdev);
+}
diff --git a/arch/arm/mach-s5p6442/include/mach/debug-macro.S b/arch/arm/mach-s5p6442/include/mach/debug-macro.S
new file mode 100644
index 00000000000..bb6536147ff
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/debug-macro.S
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+ .macro addruart, rx, rtmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1
+ ldreq \rx, = S3C_PA_UART
+ ldrne \rx, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+#define fifo_full fifo_full_s5pv210
+#define fifo_level fifo_level_s5pv210
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5p6442/include/mach/entry-macro.S b/arch/arm/mach-s5p6442/include/mach/entry-macro.S
new file mode 100644
index 00000000000..6d574edbf1a
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/entry-macro.S
@@ -0,0 +1,48 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Low-level IRQ helper macros for the Samsung S5P6442
+ *
+ * This program is free software; you can 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/hardware/vic.h>
+#include <mach/map.h>
+#include <plat/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =VA_VIC0
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ @ check the vic0
+ mov \irqnr, # S5P_IRQ_OFFSET + 31
+ ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
+ teq \irqstat, #0
+
+ @ otherwise try vic1
+ addeq \tmp, \base, #(VA_VIC1 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ @ otherwise try vic2
+ addeq \tmp, \base, #(VA_VIC2 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/mach-s5p6442/include/mach/gpio.h b/arch/arm/mach-s5p6442/include/mach/gpio.h
new file mode 100644
index 00000000000..b8715df2fda
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/gpio.h
@@ -0,0 +1,123 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/gpio.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#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
+
+/* GPIO bank sizes */
+#define S5P6442_GPIO_A0_NR (8)
+#define S5P6442_GPIO_A1_NR (2)
+#define S5P6442_GPIO_B_NR (4)
+#define S5P6442_GPIO_C0_NR (5)
+#define S5P6442_GPIO_C1_NR (5)
+#define S5P6442_GPIO_D0_NR (2)
+#define S5P6442_GPIO_D1_NR (6)
+#define S5P6442_GPIO_E0_NR (8)
+#define S5P6442_GPIO_E1_NR (5)
+#define S5P6442_GPIO_F0_NR (8)
+#define S5P6442_GPIO_F1_NR (8)
+#define S5P6442_GPIO_F2_NR (8)
+#define S5P6442_GPIO_F3_NR (6)
+#define S5P6442_GPIO_G0_NR (7)
+#define S5P6442_GPIO_G1_NR (7)
+#define S5P6442_GPIO_G2_NR (7)
+#define S5P6442_GPIO_H0_NR (8)
+#define S5P6442_GPIO_H1_NR (8)
+#define S5P6442_GPIO_H2_NR (8)
+#define S5P6442_GPIO_H3_NR (8)
+#define S5P6442_GPIO_J0_NR (8)
+#define S5P6442_GPIO_J1_NR (6)
+#define S5P6442_GPIO_J2_NR (8)
+#define S5P6442_GPIO_J3_NR (8)
+#define S5P6442_GPIO_J4_NR (5)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5P6442_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+ S5P6442_GPIO_A0_START = 0,
+ S5P6442_GPIO_A1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_A0),
+ S5P6442_GPIO_B_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_A1),
+ S5P6442_GPIO_C0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_B),
+ S5P6442_GPIO_C1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_C0),
+ S5P6442_GPIO_D0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_C1),
+ S5P6442_GPIO_D1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_D0),
+ S5P6442_GPIO_E0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_D1),
+ S5P6442_GPIO_E1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_E0),
+ S5P6442_GPIO_F0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_E1),
+ S5P6442_GPIO_F1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_F0),
+ S5P6442_GPIO_F2_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_F1),
+ S5P6442_GPIO_F3_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_F2),
+ S5P6442_GPIO_G0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_F3),
+ S5P6442_GPIO_G1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_G0),
+ S5P6442_GPIO_G2_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_G1),
+ S5P6442_GPIO_H0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_G2),
+ S5P6442_GPIO_H1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_H0),
+ S5P6442_GPIO_H2_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_H1),
+ S5P6442_GPIO_H3_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_H2),
+ S5P6442_GPIO_J0_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_H3),
+ S5P6442_GPIO_J1_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_J0),
+ S5P6442_GPIO_J2_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_J1),
+ S5P6442_GPIO_J3_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_J2),
+ S5P6442_GPIO_J4_START = S5P6442_GPIO_NEXT(S5P6442_GPIO_J3),
+};
+
+/* S5P6442 GPIO number definitions. */
+#define S5P6442_GPA0(_nr) (S5P6442_GPIO_A0_START + (_nr))
+#define S5P6442_GPA1(_nr) (S5P6442_GPIO_A1_START + (_nr))
+#define S5P6442_GPB(_nr) (S5P6442_GPIO_B_START + (_nr))
+#define S5P6442_GPC0(_nr) (S5P6442_GPIO_C0_START + (_nr))
+#define S5P6442_GPC1(_nr) (S5P6442_GPIO_C1_START + (_nr))
+#define S5P6442_GPD0(_nr) (S5P6442_GPIO_D0_START + (_nr))
+#define S5P6442_GPD1(_nr) (S5P6442_GPIO_D1_START + (_nr))
+#define S5P6442_GPE0(_nr) (S5P6442_GPIO_E0_START + (_nr))
+#define S5P6442_GPE1(_nr) (S5P6442_GPIO_E1_START + (_nr))
+#define S5P6442_GPF0(_nr) (S5P6442_GPIO_F0_START + (_nr))
+#define S5P6442_GPF1(_nr) (S5P6442_GPIO_F1_START + (_nr))
+#define S5P6442_GPF2(_nr) (S5P6442_GPIO_F2_START + (_nr))
+#define S5P6442_GPF3(_nr) (S5P6442_GPIO_F3_START + (_nr))
+#define S5P6442_GPG0(_nr) (S5P6442_GPIO_G0_START + (_nr))
+#define S5P6442_GPG1(_nr) (S5P6442_GPIO_G1_START + (_nr))
+#define S5P6442_GPG2(_nr) (S5P6442_GPIO_G2_START + (_nr))
+#define S5P6442_GPH0(_nr) (S5P6442_GPIO_H0_START + (_nr))
+#define S5P6442_GPH1(_nr) (S5P6442_GPIO_H1_START + (_nr))
+#define S5P6442_GPH2(_nr) (S5P6442_GPIO_H2_START + (_nr))
+#define S5P6442_GPH3(_nr) (S5P6442_GPIO_H3_START + (_nr))
+#define S5P6442_GPJ0(_nr) (S5P6442_GPIO_J0_START + (_nr))
+#define S5P6442_GPJ1(_nr) (S5P6442_GPIO_J1_START + (_nr))
+#define S5P6442_GPJ2(_nr) (S5P6442_GPIO_J2_START + (_nr))
+#define S5P6442_GPJ3(_nr) (S5P6442_GPIO_J3_START + (_nr))
+#define S5P6442_GPJ4(_nr) (S5P6442_GPIO_J4_START + (_nr))
+
+/* the end of the S5P6442 specific gpios */
+#define S5P6442_GPIO_END (S5P6442_GPJ4(S5P6442_GPIO_J4_NR) + 1)
+#define S3C_GPIO_END S5P6442_GPIO_END
+
+/* define the number of gpios we need to the one after the GPJ4() range */
+#define ARCH_NR_GPIOS (S5P6442_GPJ4(S5P6442_GPIO_J4_NR) + \
+ CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/hardware.h b/arch/arm/mach-s5p6442/include/mach/hardware.h
new file mode 100644
index 00000000000..8cd7b67b49d
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/hardware.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/hardware.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/io.h b/arch/arm/mach-s5p6442/include/mach/io.h
new file mode 100644
index 00000000000..5d2195ad0b6
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/io.h
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5p6442/include/mach/io.h
+ *
+ * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S5P6442
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s5p6442/include/mach/irqs.h b/arch/arm/mach-s5p6442/include/mach/irqs.h
new file mode 100644
index 00000000000..da665809f6e
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/irqs.h
@@ -0,0 +1,86 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/irqs.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* VIC0 */
+#define IRQ_EINT16_31 S5P_IRQ_VIC0(16)
+#define IRQ_BATF S5P_IRQ_VIC0(17)
+#define IRQ_MDMA S5P_IRQ_VIC0(18)
+#define IRQ_PDMA S5P_IRQ_VIC0(19)
+#define IRQ_TIMER0_VIC S5P_IRQ_VIC0(21)
+#define IRQ_TIMER1_VIC S5P_IRQ_VIC0(22)
+#define IRQ_TIMER2_VIC S5P_IRQ_VIC0(23)
+#define IRQ_TIMER3_VIC S5P_IRQ_VIC0(24)
+#define IRQ_TIMER4_VIC S5P_IRQ_VIC0(25)
+#define IRQ_SYSTIMER S5P_IRQ_VIC0(26)
+#define IRQ_WDT S5P_IRQ_VIC0(27)
+#define IRQ_RTC_ALARM S5P_IRQ_VIC0(28)
+#define IRQ_RTC_TIC S5P_IRQ_VIC0(29)
+#define IRQ_GPIOINT S5P_IRQ_VIC0(30)
+
+/* VIC1 */
+#define IRQ_nPMUIRQ S5P_IRQ_VIC1(0)
+#define IRQ_ONENAND S5P_IRQ_VIC1(7)
+#define IRQ_UART0 S5P_IRQ_VIC1(10)
+#define IRQ_UART1 S5P_IRQ_VIC1(11)
+#define IRQ_UART2 S5P_IRQ_VIC1(12)
+#define IRQ_SPI0 S5P_IRQ_VIC1(15)
+#define IRQ_IIC S5P_IRQ_VIC1(19)
+#define IRQ_IIC1 S5P_IRQ_VIC1(20)
+#define IRQ_IIC2 S5P_IRQ_VIC1(21)
+#define IRQ_OTG S5P_IRQ_VIC1(24)
+#define IRQ_MSM S5P_IRQ_VIC1(25)
+#define IRQ_HSMMC0 S5P_IRQ_VIC1(26)
+#define IRQ_HSMMC1 S5P_IRQ_VIC1(27)
+#define IRQ_HSMMC2 S5P_IRQ_VIC1(28)
+#define IRQ_COMMRX S5P_IRQ_VIC1(29)
+#define IRQ_COMMTX S5P_IRQ_VIC1(30)
+
+/* VIC2 */
+#define IRQ_LCD0 S5P_IRQ_VIC2(0)
+#define IRQ_LCD1 S5P_IRQ_VIC2(1)
+#define IRQ_LCD2 S5P_IRQ_VIC2(2)
+#define IRQ_LCD3 S5P_IRQ_VIC2(3)
+#define IRQ_ROTATOR S5P_IRQ_VIC2(4)
+#define IRQ_FIMC0 S5P_IRQ_VIC2(5)
+#define IRQ_FIMC1 S5P_IRQ_VIC2(6)
+#define IRQ_FIMC2 S5P_IRQ_VIC2(7)
+#define IRQ_JPEG S5P_IRQ_VIC2(8)
+#define IRQ_3D S5P_IRQ_VIC2(10)
+#define IRQ_Mixer S5P_IRQ_VIC2(11)
+#define IRQ_MFC S5P_IRQ_VIC2(14)
+#define IRQ_TVENC S5P_IRQ_VIC2(15)
+#define IRQ_I2S0 S5P_IRQ_VIC2(16)
+#define IRQ_I2S1 S5P_IRQ_VIC2(17)
+#define IRQ_RP S5P_IRQ_VIC2(19)
+#define IRQ_PCM0 S5P_IRQ_VIC2(20)
+#define IRQ_PCM1 S5P_IRQ_VIC2(21)
+#define IRQ_ADC S5P_IRQ_VIC2(23)
+#define IRQ_PENDN S5P_IRQ_VIC2(24)
+#define IRQ_KEYPAD S5P_IRQ_VIC2(25)
+#define IRQ_SSS_INT S5P_IRQ_VIC2(27)
+#define IRQ_SSS_HASH S5P_IRQ_VIC2(28)
+#define IRQ_VIC_END S5P_IRQ_VIC2(31)
+
+#define S5P_IRQ_EINT_BASE (IRQ_VIC_END + 1)
+
+#define IRQ_EINT(x) ((x) < 16 ? S5P_IRQ_VIC0(x) : \
+ (S5P_IRQ_EINT_BASE + (x)-16))
+/* Set the default NR_IRQS */
+
+#define NR_IRQS (IRQ_EINT(31) + 1)
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h
new file mode 100644
index 00000000000..685277d792f
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/map.h
@@ -0,0 +1,58 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/map.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5P6442_PA_CHIPID (0xE0000000)
+#define S5P_PA_CHIPID S5P6442_PA_CHIPID
+
+#define S5P6442_PA_SYSCON (0xE0100000)
+#define S5P_PA_SYSCON S5P6442_PA_SYSCON
+
+#define S5P6442_PA_GPIO (0xE0200000)
+#define S5P_PA_GPIO S5P6442_PA_GPIO
+
+#define S5P6442_PA_VIC0 (0xE4000000)
+#define S5P_PA_VIC0 S5P6442_PA_VIC0
+
+#define S5P6442_PA_VIC1 (0xE4100000)
+#define S5P_PA_VIC1 S5P6442_PA_VIC1
+
+#define S5P6442_PA_VIC2 (0xE4200000)
+#define S5P_PA_VIC2 S5P6442_PA_VIC2
+
+#define S5P6442_PA_TIMER (0xEA000000)
+#define S5P_PA_TIMER S5P6442_PA_TIMER
+
+#define S5P6442_PA_SYSTIMER (0xEA100000)
+
+#define S5P6442_PA_UART (0xEC000000)
+
+#define S5P_PA_UART0 (S5P6442_PA_UART + 0x0)
+#define S5P_PA_UART1 (S5P6442_PA_UART + 0x400)
+#define S5P_PA_UART2 (S5P6442_PA_UART + 0x800)
+#define S5P_SZ_UART SZ_256
+
+#define S5P6442_PA_IIC0 (0xEC100000)
+
+#define S5P6442_PA_SDRAM (0x20000000)
+#define S5P_PA_SDRAM S5P6442_PA_SDRAM
+
+/* compatibiltiy defines. */
+#define S3C_PA_UART S5P6442_PA_UART
+#define S3C_PA_IIC S5P6442_PA_IIC0
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/memory.h b/arch/arm/mach-s5p6442/include/mach/memory.h
new file mode 100644
index 00000000000..9ddd877ba2e
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/memory.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/memory.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET UL(0x20000000)
+#define CONSISTENT_DMA_SIZE SZ_8M
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/pwm-clock.h b/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
new file mode 100644
index 00000000000..15e8525da0f
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ *
+ * S5P6442 - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @cfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return tcfg == S3C2410_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << (1 + tcfg1);
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 0;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div) - 1;
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+
+#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/regs-clock.h b/arch/arm/mach-s5p6442/include/mach/regs-clock.h
new file mode 100644
index 00000000000..d8360b5d4ec
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/regs-clock.h
@@ -0,0 +1,103 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S5P_APLL_LOCK S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK S5P_CLKREG(0x08)
+#define S5P_EPLL_LOCK S5P_CLKREG(0x10)
+#define S5P_VPLL_LOCK S5P_CLKREG(0x20)
+
+#define S5P_APLL_CON S5P_CLKREG(0x100)
+#define S5P_MPLL_CON S5P_CLKREG(0x108)
+#define S5P_EPLL_CON S5P_CLKREG(0x110)
+#define S5P_VPLL_CON S5P_CLKREG(0x120)
+
+#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
+#define S5P_CLK_SRC1 S5P_CLKREG(0x204)
+#define S5P_CLK_SRC2 S5P_CLKREG(0x208)
+#define S5P_CLK_SRC3 S5P_CLKREG(0x20C)
+#define S5P_CLK_SRC4 S5P_CLKREG(0x210)
+#define S5P_CLK_SRC5 S5P_CLKREG(0x214)
+#define S5P_CLK_SRC6 S5P_CLKREG(0x218)
+
+#define S5P_CLK_SRC_MASK0 S5P_CLKREG(0x280)
+#define S5P_CLK_SRC_MASK1 S5P_CLKREG(0x284)
+
+#define S5P_CLK_DIV0 S5P_CLKREG(0x300)
+#define S5P_CLK_DIV1 S5P_CLKREG(0x304)
+#define S5P_CLK_DIV2 S5P_CLKREG(0x308)
+#define S5P_CLK_DIV3 S5P_CLKREG(0x30C)
+#define S5P_CLK_DIV4 S5P_CLKREG(0x310)
+#define S5P_CLK_DIV5 S5P_CLKREG(0x314)
+#define S5P_CLK_DIV6 S5P_CLKREG(0x318)
+
+#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C)
+
+/* CLK_OUT */
+#define S5P_CLK_OUT_SHIFT (12)
+#define S5P_CLK_OUT_MASK (0x1F << S5P_CLK_OUT_SHIFT)
+#define S5P_CLK_OUT S5P_CLKREG(0x500)
+
+#define S5P_CLK_DIV_STAT0 S5P_CLKREG(0x1000)
+#define S5P_CLK_DIV_STAT1 S5P_CLKREG(0x1004)
+
+#define S5P_CLK_MUX_STAT0 S5P_CLKREG(0x1100)
+#define S5P_CLK_MUX_STAT1 S5P_CLKREG(0x1104)
+
+#define S5P_MDNIE_SEL S5P_CLKREG(0x7008)
+
+/* Register Bit definition */
+#define S5P_EPLL_EN (1<<31)
+#define S5P_EPLL_MASK 0xffffffff
+#define S5P_EPLLVAL(_m, _p, _s) ((_m) << 16 | ((_p) << 8) | ((_s)))
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_APLL_SHIFT (0)
+#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
+#define S5P_CLKDIV0_A2M_SHIFT (4)
+#define S5P_CLKDIV0_A2M_MASK (0x7 << S5P_CLKDIV0_A2M_SHIFT)
+#define S5P_CLKDIV0_D0CLK_SHIFT (16)
+#define S5P_CLKDIV0_D0CLK_MASK (0xF << S5P_CLKDIV0_D0CLK_SHIFT)
+#define S5P_CLKDIV0_P0CLK_SHIFT (20)
+#define S5P_CLKDIV0_P0CLK_MASK (0x7 << S5P_CLKDIV0_P0CLK_SHIFT)
+#define S5P_CLKDIV0_D1CLK_SHIFT (24)
+#define S5P_CLKDIV0_D1CLK_MASK (0xF << S5P_CLKDIV0_D1CLK_SHIFT)
+#define S5P_CLKDIV0_P1CLK_SHIFT (28)
+#define S5P_CLKDIV0_P1CLK_MASK (0x7 << S5P_CLKDIV0_P1CLK_SHIFT)
+
+/* Clock MUX status Registers */
+#define S5P_CLK_MUX_STAT0_APLL_SHIFT (0)
+#define S5P_CLK_MUX_STAT0_APLL_MASK (0x7 << S5P_CLK_MUX_STAT0_APLL_SHIFT)
+#define S5P_CLK_MUX_STAT0_MPLL_SHIFT (4)
+#define S5P_CLK_MUX_STAT0_MPLL_MASK (0x7 << S5P_CLK_MUX_STAT0_MPLL_SHIFT)
+#define S5P_CLK_MUX_STAT0_EPLL_SHIFT (8)
+#define S5P_CLK_MUX_STAT0_EPLL_MASK (0x7 << S5P_CLK_MUX_STAT0_EPLL_SHIFT)
+#define S5P_CLK_MUX_STAT0_VPLL_SHIFT (12)
+#define S5P_CLK_MUX_STAT0_VPLL_MASK (0x7 << S5P_CLK_MUX_STAT0_VPLL_SHIFT)
+#define S5P_CLK_MUX_STAT0_MUXARM_SHIFT (16)
+#define S5P_CLK_MUX_STAT0_MUXARM_MASK (0x7 << S5P_CLK_MUX_STAT0_MUXARM_SHIFT)
+#define S5P_CLK_MUX_STAT0_MUXD0_SHIFT (20)
+#define S5P_CLK_MUX_STAT0_MUXD0_MASK (0x7 << S5P_CLK_MUX_STAT0_MUXD0_SHIFT)
+#define S5P_CLK_MUX_STAT0_MUXD1_SHIFT (24)
+#define S5P_CLK_MUX_STAT0_MUXD1_MASK (0x7 << S5P_CLK_MUX_STAT0_MUXD1_SHIFT)
+#define S5P_CLK_MUX_STAT1_D1SYNC_SHIFT (24)
+#define S5P_CLK_MUX_STAT1_D1SYNC_MASK (0x7 << S5P_CLK_MUX_STAT1_D1SYNC_SHIFT)
+#define S5P_CLK_MUX_STAT1_D0SYNC_SHIFT (28)
+#define S5P_CLK_MUX_STAT1_D0SYNC_MASK (0x7 << S5P_CLK_MUX_STAT1_D0SYNC_SHIFT)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/regs-irq.h b/arch/arm/mach-s5p6442/include/mach/regs-irq.h
new file mode 100644
index 00000000000..73782b52a83
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/system.h b/arch/arm/mach-s5p6442/include/mach/system.h
new file mode 100644
index 00000000000..8bcd8ed0c3c
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/system.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/system.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+static void arch_idle(void)
+{
+ /* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ /* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/tick.h b/arch/arm/mach-s5p6442/include/mach/tick.h
new file mode 100644
index 00000000000..e1d4cabf829
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/tick.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/tick.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/tick.h
+ *
+ * S5P6442 - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX (0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/timex.h b/arch/arm/mach-s5p6442/include/mach/timex.h
new file mode 100644
index 00000000000..ff8f2fcadeb
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/timex.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s5p6442/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S5P6442 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/uncompress.h b/arch/arm/mach-s5p6442/include/mach/uncompress.h
new file mode 100644
index 00000000000..5ac7cbeeb98
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/uncompress.h
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/uncompress.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P6442 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/vmalloc.h b/arch/arm/mach-s5p6442/include/mach/vmalloc.h
new file mode 100644
index 00000000000..be3333688c2
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/vmalloc.h
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5p6442/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.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.
+ *
+ * S5P6442 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5p6442/init.c b/arch/arm/mach-s5p6442/init.c
new file mode 100644
index 00000000000..1874bdb71e1
--- /dev/null
+++ b/arch/arm/mach-s5p6442/init.c
@@ -0,0 +1,44 @@
+/* linux/arch/arm/mach-s5p6442/s5p6442-init.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5p6442.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5p6442_serial_clocks[] = {
+ [0] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+};
+
+/* uart registration process */
+void __init s5p6442_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ struct s3c2410_uartcfg *tcfg = cfg;
+ u32 ucnt;
+
+ for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+ if (!tcfg->clocks) {
+ tcfg->clocks = s5p6442_serial_clocks;
+ tcfg->clocks_size = ARRAY_SIZE(s5p6442_serial_clocks);
+ }
+ }
+
+ s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c
new file mode 100644
index 00000000000..0d63371ce07
--- /dev/null
+++ b/arch/arm/mach-s5p6442/mach-smdk6442.c
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-s5p6442/mach-smdk6442.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5p6442.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define S5P6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define S5P6442_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define S5P6442_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = S5P6442_UCON_DEFAULT,
+ .ulcon = S5P6442_ULCON_DEFAULT,
+ .ufcon = S5P6442_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = S5P6442_UCON_DEFAULT,
+ .ulcon = S5P6442_ULCON_DEFAULT,
+ .ufcon = S5P6442_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = S5P6442_UCON_DEFAULT,
+ .ulcon = S5P6442_ULCON_DEFAULT,
+ .ufcon = S5P6442_UFCON_DEFAULT,
+ },
+};
+
+static struct platform_device *smdk6442_devices[] __initdata = {
+};
+
+static void __init smdk6442_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk6442_uartcfgs, ARRAY_SIZE(smdk6442_uartcfgs));
+}
+
+static void __init smdk6442_machine_init(void)
+{
+ platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices));
+}
+
+MACHINE_START(SMDK6442, "SMDK6442")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5p6442_init_irq,
+ .map_io = smdk6442_map_io,
+ .init_machine = smdk6442_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio-core.h b/arch/arm/mach-s5pc100/include/mach/gpio-core.h
deleted file mode 100644
index ad28d8ec8a7..00000000000
--- a/arch/arm/mach-s5pc100/include/mach/gpio-core.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* arch/arm/mach-s5pc100/include/mach/gpio-core.h
- *
- * Copyright 2009 Samsung Electronics Co.
- * Byungho Min <bhmin@samsung.com>
- *
- * S5PC100 - GPIO core support
- *
- * Based on mach-s3c6400/include/mach/gpio-core.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_CORE_H
-#define __ASM_ARCH_GPIO_CORE_H __FILE__
-
-/* currently we just include the platform support */
-#include <plat/gpio-core.h>
-
-#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/io.h b/arch/arm/mach-s5pc100/include/mach/io.h
new file mode 100644
index 00000000000..819acf5eaf8
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/io.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s5pc100/include/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S5PC100 systems
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s5pc100/include/mach/tick.h b/arch/arm/mach-s5pc100/include/mach/tick.h
index d3de0f3591a..f338c9eec71 100644
--- a/arch/arm/mach-s5pc100/include/mach/tick.h
+++ b/arch/arm/mach-s5pc100/include/mach/tick.h
@@ -21,7 +21,7 @@
static inline u32 s3c24xx_ostimer_pending(void)
{
u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS);
- return pend & 1 << (IRQ_TIMER4 - S5PC1XX_IRQ_VIC0(0));
+ return pend & 1 << (IRQ_TIMER4_VIC - S5PC1XX_IRQ_VIC0(0));
}
#define TICK_MAX (0xffffffff)
diff --git a/arch/arm/mach-s5pc100/include/mach/timex.h b/arch/arm/mach-s5pc100/include/mach/timex.h
new file mode 100644
index 00000000000..47ffb17aff9
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/timex.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s5pc100/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/vmalloc.h b/arch/arm/mach-s5pc100/include/mach/vmalloc.h
new file mode 100644
index 00000000000..be9df79903e
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/vmalloc.h
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5pc100/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.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.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (0xe0000000UL)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pc100/setup-sdhci.c b/arch/arm/mach-s5pc100/setup-sdhci.c
index 4385986a3da..ea7ff19adb9 100644
--- a/arch/arm/mach-s5pc100/setup-sdhci.c
+++ b/arch/arm/mach-s5pc100/setup-sdhci.c
@@ -28,8 +28,8 @@
char *s5pc100_hsmmc_clksrcs[4] = {
[0] = "hsmmc",
[1] = "hsmmc",
- /* [2] = "mmc_bus", not yet succesfuuly used yet */
- /* [3] = "48m", - note not succesfully used yet */
+ /* [2] = "mmc_bus", not yet successfully used yet */
+ /* [3] = "48m", - note not successfully used yet */
};
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
new file mode 100644
index 00000000000..af33a1a89b7
--- /dev/null
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -0,0 +1,40 @@
+# arch/arm/mach-s5pv210/Kconfig
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+# Configuration options for the S5PV210/S5PC110
+
+if ARCH_S5PV210
+
+config CPU_S5PV210
+ bool
+ select PLAT_S5P
+ help
+ Enable S5PV210 CPU support
+
+choice
+ prompt "Select machine type"
+ depends on ARCH_S5PV210
+ default MACH_SMDKV210
+
+config MACH_SMDKV210
+ bool "SMDKV210"
+ select CPU_S5PV210
+ select ARCH_SPARSEMEM_ENABLE
+ help
+ Machine support for Samsung SMDKV210
+
+config MACH_SMDKC110
+ bool "SMDKC110"
+ select CPU_S5PV210
+ select ARCH_SPARSEMEM_ENABLE
+ help
+ Machine support for Samsung SMDKC110
+ S5PC110(MCP) is one of package option of S5PV210
+
+endchoice
+
+endif
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
new file mode 100644
index 00000000000..8ebf51c52a0
--- /dev/null
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -0,0 +1,20 @@
+# arch/arm/mach-s5pv210/Makefile
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core support for S5PV210 system
+
+obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o
+obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o
diff --git a/arch/arm/mach-s5pv210/Makefile.boot b/arch/arm/mach-s5pv210/Makefile.boot
new file mode 100644
index 00000000000..ff90aa13bd6
--- /dev/null
+++ b/arch/arm/mach-s5pv210/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
new file mode 100644
index 00000000000..ccccae26235
--- /dev/null
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -0,0 +1,454 @@
+/* linux/arch/arm/mach-s5pv210/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5pv210.h>
+
+static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
+}
+
+static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
+}
+
+static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
+}
+
+static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
+}
+
+static struct clk clk_h200 = {
+ .name = "hclk200",
+ .id = -1,
+};
+
+static struct clk clk_h100 = {
+ .name = "hclk100",
+ .id = -1,
+};
+
+static struct clk clk_h166 = {
+ .name = "hclk166",
+ .id = -1,
+};
+
+static struct clk clk_h133 = {
+ .name = "hclk133",
+ .id = -1,
+};
+
+static struct clk clk_p100 = {
+ .name = "pclk100",
+ .id = -1,
+};
+
+static struct clk clk_p83 = {
+ .name = "pclk83",
+ .id = -1,
+};
+
+static struct clk clk_p66 = {
+ .name = "pclk66",
+ .id = -1,
+};
+
+static struct clk *sys_clks[] = {
+ &clk_h200,
+ &clk_h100,
+ &clk_h166,
+ &clk_h133,
+ &clk_p100,
+ &clk_p83,
+ &clk_p66
+};
+
+static struct clk init_clocks_disable[] = {
+ {
+ .name = "rot",
+ .id = -1,
+ .parent = &clk_h166,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1<<29),
+ }, {
+ .name = "otg",
+ .id = -1,
+ .parent = &clk_h133,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<16),
+ }, {
+ .name = "usb-host",
+ .id = -1,
+ .parent = &clk_h133,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<17),
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h166,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<0),
+ }, {
+ .name = "cfcon",
+ .id = 0,
+ .parent = &clk_h133,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<25),
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_h133,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1<<16),
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_h133,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1<<17),
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_h133,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1<<18),
+ }, {
+ .name = "hsmmc",
+ .id = 3,
+ .parent = &clk_h133,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1<<19),
+ }, {
+ .name = "systimer",
+ .id = -1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<16),
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<22),
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<15),
+ }, {
+ .name = "i2c",
+ .id = 0,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<7),
+ }, {
+ .name = "i2c",
+ .id = 1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<8),
+ }, {
+ .name = "i2c",
+ .id = 2,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<9),
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<12),
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<13),
+ }, {
+ .name = "spi",
+ .id = 2,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<14),
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<23),
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<24),
+ }, {
+ .name = "keypad",
+ .id = -1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<21),
+ }, {
+ .name = "i2s_v50",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<4),
+ }, {
+ .name = "i2s_v32",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<4),
+ }, {
+ .name = "i2s_v32",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<4),
+ }
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<7),
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<8),
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<9),
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_p66,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<10),
+ },
+};
+
+static struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .sources = &clk_src_mpll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_uart_list[] = {
+ [6] = &clk_mout_mpll.clk,
+ [7] = &clk_mout_epll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = (1<<17),
+ .enable = s5pv210_clk_ip3_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+ }
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *init_parents[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_mout_mpll,
+};
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+void __init_or_cpufreq s5pv210_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+ unsigned long armclk;
+ unsigned long hclk200;
+ unsigned long hclk166;
+ unsigned long hclk133;
+ unsigned long pclk100;
+ unsigned long pclk83;
+ unsigned long pclk66;
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned int ptr;
+ u32 clkdiv0, clkdiv1;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ clkdiv0 = __raw_readl(S5P_CLK_DIV0);
+ clkdiv1 = __raw_readl(S5P_CLK_DIV1);
+
+ printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
+ __func__, clkdiv0, clkdiv1);
+
+ xtal_clk = clk_get(NULL, "xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+ apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
+ epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
+
+ printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld",
+ apll, mpll, epll);
+
+ armclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_APLL);
+ if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX200_MASK)
+ hclk200 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
+ else
+ hclk200 = armclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
+
+ if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX166_MASK) {
+ hclk166 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
+ hclk166 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
+ } else
+ hclk166 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
+
+ if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX133_MASK) {
+ hclk133 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
+ hclk133 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
+ } else
+ hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
+
+ pclk100 = hclk200 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100);
+ pclk83 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83);
+ pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66);
+
+ printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \
+ HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
+ armclk, hclk200, hclk166, hclk133, pclk100, pclk83, pclk66);
+
+ clk_fout_apll.rate = apll;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+
+ clk_f.rate = armclk;
+ clk_h.rate = hclk133;
+ clk_p.rate = pclk66;
+ clk_p66.rate = pclk66;
+ clk_p83.rate = pclk83;
+ clk_h133.rate = hclk133;
+ clk_h166.rate = hclk166;
+ clk_h200.rate = hclk200;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+ s3c_set_clksrc(init_parents[ptr], true);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+ &clk_mout_epll.clk,
+ &clk_mout_mpll.clk,
+};
+
+void __init s5pv210_register_clocks(void)
+{
+ struct clk *clkp;
+ int ret;
+ int ptr;
+
+ ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+ if (ret > 0)
+ printk(KERN_ERR "Failed to register %u clocks\n", ret);
+
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ ret = s3c24xx_register_clocks(sys_clks, ARRAY_SIZE(sys_clks));
+ if (ret > 0)
+ printk(KERN_ERR "Failed to register system clocks\n");
+
+ clkp = init_clocks_disable;
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ (clkp->enable)(clkp, 0);
+ }
+
+ s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
new file mode 100644
index 00000000000..0e0f8fde2aa
--- /dev/null
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -0,0 +1,126 @@
+/* linux/arch/arm/mach-s5pv210/cpu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5pv210.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5pv210_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SYSTIMER,
+ .pfn = __phys_to_pfn(S5PV210_PA_SYSTIMER),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC2,
+ .pfn = __phys_to_pfn(S5PV210_PA_VIC2),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC3,
+ .pfn = __phys_to_pfn(S5PV210_PA_VIC3),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SROMC,
+ .pfn = __phys_to_pfn(S5PV210_PA_SROMC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }
+};
+
+static void s5pv210_idle(void)
+{
+ if (!need_resched())
+ cpu_do_idle();
+
+ local_irq_enable();
+}
+
+/* s5pv210_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5pv210_map_io(void)
+{
+ iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc));
+}
+
+void __init s5pv210_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5pv210_register_clocks();
+ s5pv210_setup_clocks();
+}
+
+void __init s5pv210_init_irq(void)
+{
+ u32 vic[4]; /* S5PV210 supports 4 VIC */
+
+ /* All the VICs are fully populated. */
+ vic[0] = ~0;
+ vic[1] = ~0;
+ vic[2] = ~0;
+ vic[3] = ~0;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+static struct sysdev_class s5pv210_sysclass = {
+ .name = "s5pv210-core",
+};
+
+static struct sys_device s5pv210_sysdev = {
+ .cls = &s5pv210_sysclass,
+};
+
+static int __init s5pv210_core_init(void)
+{
+ return sysdev_class_register(&s5pv210_sysclass);
+}
+
+core_initcall(s5pv210_core_init);
+
+int __init s5pv210_init(void)
+{
+ printk(KERN_INFO "S5PV210: Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = s5pv210_idle;
+
+ return sysdev_register(&s5pv210_sysdev);
+}
diff --git a/arch/arm/mach-s5pv210/include/mach/debug-macro.S b/arch/arm/mach-s5pv210/include/mach/debug-macro.S
new file mode 100644
index 00000000000..7872f5c3dfc
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/debug-macro.S
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+ /* note, for the boot process to work we have to keep the UART
+ * virtual address aligned to an 1MiB boundary for the L1
+ * mapping the head code makes. We keep the UART virtual address
+ * aligned and add in the offset when we load the value here.
+ */
+
+ .macro addruart, rx, tmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1
+ ldreq \rx, = S3C_PA_UART
+ ldrne \rx, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+#define fifo_full fifo_full_s5pv210
+#define fifo_level fifo_level_s5pv210
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5pv210/include/mach/entry-macro.S b/arch/arm/mach-s5pv210/include/mach/entry-macro.S
new file mode 100644
index 00000000000..3aa41ac59f0
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/entry-macro.S
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Low-level IRQ helper macros for the Samsung S5PV210
+ *
+ * This program is free software; you can 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/hardware/vic.h>
+#include <mach/map.h>
+#include <plat/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =VA_VIC0
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ @ check the vic0
+ mov \irqnr, # S5P_IRQ_OFFSET + 31
+ ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
+ teq \irqstat, #0
+
+ @ otherwise try vic1
+ addeq \tmp, \base, #(VA_VIC1 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ @ otherwise try vic2
+ addeq \tmp, \base, #(VA_VIC2 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ @ otherwise try vic3
+ addeq \tmp, \base, #(VA_VIC3 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/mach-s5pv210/include/mach/gpio.h b/arch/arm/mach-s5pv210/include/mach/gpio.h
new file mode 100644
index 00000000000..533b020e21e
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/gpio.h
@@ -0,0 +1,129 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/gpio.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#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
+
+/* GPIO bank sizes */
+#define S5PV210_GPIO_A0_NR (8)
+#define S5PV210_GPIO_A1_NR (4)
+#define S5PV210_GPIO_B_NR (8)
+#define S5PV210_GPIO_C0_NR (5)
+#define S5PV210_GPIO_C1_NR (5)
+#define S5PV210_GPIO_D0_NR (4)
+#define S5PV210_GPIO_D1_NR (6)
+#define S5PV210_GPIO_E0_NR (8)
+#define S5PV210_GPIO_E1_NR (5)
+#define S5PV210_GPIO_F0_NR (8)
+#define S5PV210_GPIO_F1_NR (8)
+#define S5PV210_GPIO_F2_NR (8)
+#define S5PV210_GPIO_F3_NR (6)
+#define S5PV210_GPIO_G0_NR (7)
+#define S5PV210_GPIO_G1_NR (7)
+#define S5PV210_GPIO_G2_NR (7)
+#define S5PV210_GPIO_G3_NR (7)
+#define S5PV210_GPIO_H0_NR (8)
+#define S5PV210_GPIO_H1_NR (8)
+#define S5PV210_GPIO_H2_NR (8)
+#define S5PV210_GPIO_H3_NR (8)
+#define S5PV210_GPIO_I_NR (7)
+#define S5PV210_GPIO_J0_NR (8)
+#define S5PV210_GPIO_J1_NR (6)
+#define S5PV210_GPIO_J2_NR (8)
+#define S5PV210_GPIO_J3_NR (8)
+#define S5PV210_GPIO_J4_NR (5)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5PV210_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+ S5PV210_GPIO_A0_START = 0,
+ S5PV210_GPIO_A1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_A0),
+ S5PV210_GPIO_B_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_A1),
+ S5PV210_GPIO_C0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_B),
+ S5PV210_GPIO_C1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_C0),
+ S5PV210_GPIO_D0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_C1),
+ S5PV210_GPIO_D1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_D0),
+ S5PV210_GPIO_E0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_D1),
+ S5PV210_GPIO_E1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_E0),
+ S5PV210_GPIO_F0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_E1),
+ S5PV210_GPIO_F1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_F0),
+ S5PV210_GPIO_F2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_F1),
+ S5PV210_GPIO_F3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_F2),
+ S5PV210_GPIO_G0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_F3),
+ S5PV210_GPIO_G1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_G0),
+ S5PV210_GPIO_G2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_G1),
+ S5PV210_GPIO_G3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_G2),
+ S5PV210_GPIO_H0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_G3),
+ S5PV210_GPIO_H1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_H0),
+ S5PV210_GPIO_H2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_H1),
+ S5PV210_GPIO_H3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_H2),
+ S5PV210_GPIO_I_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_H3),
+ S5PV210_GPIO_J0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_I),
+ S5PV210_GPIO_J1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J0),
+ S5PV210_GPIO_J2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J1),
+ S5PV210_GPIO_J3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J2),
+ S5PV210_GPIO_J4_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J3),
+};
+
+/* S5PV210 GPIO number definitions */
+#define S5PV210_GPA0(_nr) (S5PV210_GPIO_A0_START + (_nr))
+#define S5PV210_GPA1(_nr) (S5PV210_GPIO_A1_START + (_nr))
+#define S5PV210_GPB(_nr) (S5PV210_GPIO_B_START + (_nr))
+#define S5PV210_GPC0(_nr) (S5PV210_GPIO_C0_START + (_nr))
+#define S5PV210_GPC1(_nr) (S5PV210_GPIO_C1_START + (_nr))
+#define S5PV210_GPD0(_nr) (S5PV210_GPIO_D0_START + (_nr))
+#define S5PV210_GPD1(_nr) (S5PV210_GPIO_D1_START + (_nr))
+#define S5PV210_GPE0(_nr) (S5PV210_GPIO_E0_START + (_nr))
+#define S5PV210_GPE1(_nr) (S5PV210_GPIO_E1_START + (_nr))
+#define S5PV210_GPF0(_nr) (S5PV210_GPIO_F0_START + (_nr))
+#define S5PV210_GPF1(_nr) (S5PV210_GPIO_F1_START + (_nr))
+#define S5PV210_GPF2(_nr) (S5PV210_GPIO_F2_START + (_nr))
+#define S5PV210_GPF3(_nr) (S5PV210_GPIO_F3_START + (_nr))
+#define S5PV210_GPG0(_nr) (S5PV210_GPIO_G0_START + (_nr))
+#define S5PV210_GPG1(_nr) (S5PV210_GPIO_G1_START + (_nr))
+#define S5PV210_GPG2(_nr) (S5PV210_GPIO_G2_START + (_nr))
+#define S5PV210_GPG3(_nr) (S5PV210_GPIO_G3_START + (_nr))
+#define S5PV210_GPH0(_nr) (S5PV210_GPIO_H0_START + (_nr))
+#define S5PV210_GPH1(_nr) (S5PV210_GPIO_H1_START + (_nr))
+#define S5PV210_GPH2(_nr) (S5PV210_GPIO_H2_START + (_nr))
+#define S5PV210_GPH3(_nr) (S5PV210_GPIO_H3_START + (_nr))
+#define S5PV210_GPI(_nr) (S5PV210_GPIO_I_START + (_nr))
+#define S5PV210_GPJ0(_nr) (S5PV210_GPIO_J0_START + (_nr))
+#define S5PV210_GPJ1(_nr) (S5PV210_GPIO_J1_START + (_nr))
+#define S5PV210_GPJ2(_nr) (S5PV210_GPIO_J2_START + (_nr))
+#define S5PV210_GPJ3(_nr) (S5PV210_GPIO_J3_START + (_nr))
+#define S5PV210_GPJ4(_nr) (S5PV210_GPIO_J4_START + (_nr))
+
+/* the end of the S5PV210 specific gpios */
+#define S5PV210_GPIO_END (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + 1)
+#define S3C_GPIO_END S5PV210_GPIO_END
+
+/* define the number of gpios we need to the one after the GPJ4() range */
+#define ARCH_NR_GPIOS (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + \
+ CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/hardware.h b/arch/arm/mach-s5pv210/include/mach/hardware.h
new file mode 100644
index 00000000000..fada7a392d0
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/hardware.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/hardware.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/io.h b/arch/arm/mach-s5pv210/include/mach/io.h
new file mode 100644
index 00000000000..5ab9d560bc8
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/io.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/io.h
+ *
+ * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/io.h
+ *
+ * Default IO routines for S5PV210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H __FILE__
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
new file mode 100644
index 00000000000..62c5175ef29
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -0,0 +1,146 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/irqs.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* VIC0: System, DMA, Timer */
+
+#define IRQ_EINT0 S5P_IRQ_VIC0(0)
+#define IRQ_EINT1 S5P_IRQ_VIC0(1)
+#define IRQ_EINT2 S5P_IRQ_VIC0(2)
+#define IRQ_EINT3 S5P_IRQ_VIC0(3)
+#define IRQ_EINT4 S5P_IRQ_VIC0(4)
+#define IRQ_EINT5 S5P_IRQ_VIC0(5)
+#define IRQ_EINT6 S5P_IRQ_VIC0(6)
+#define IRQ_EINT7 S5P_IRQ_VIC0(7)
+#define IRQ_EINT8 S5P_IRQ_VIC0(8)
+#define IRQ_EINT9 S5P_IRQ_VIC0(9)
+#define IRQ_EINT10 S5P_IRQ_VIC0(10)
+#define IRQ_EINT11 S5P_IRQ_VIC0(11)
+#define IRQ_EINT12 S5P_IRQ_VIC0(12)
+#define IRQ_EINT13 S5P_IRQ_VIC0(13)
+#define IRQ_EINT14 S5P_IRQ_VIC0(14)
+#define IRQ_EINT15 S5P_IRQ_VIC0(15)
+#define IRQ_EINT16_31 S5P_IRQ_VIC0(16)
+#define IRQ_BATF S5P_IRQ_VIC0(17)
+#define IRQ_MDMA S5P_IRQ_VIC0(18)
+#define IRQ_PDMA0 S5P_IRQ_VIC0(19)
+#define IRQ_PDMA1 S5P_IRQ_VIC0(20)
+#define IRQ_TIMER0_VIC S5P_IRQ_VIC0(21)
+#define IRQ_TIMER1_VIC S5P_IRQ_VIC0(22)
+#define IRQ_TIMER2_VIC S5P_IRQ_VIC0(23)
+#define IRQ_TIMER3_VIC S5P_IRQ_VIC0(24)
+#define IRQ_TIMER4_VIC S5P_IRQ_VIC0(25)
+#define IRQ_SYSTIMER S5P_IRQ_VIC0(26)
+#define IRQ_WDT S5P_IRQ_VIC0(27)
+#define IRQ_RTC_ALARM S5P_IRQ_VIC0(28)
+#define IRQ_RTC_TIC S5P_IRQ_VIC0(29)
+#define IRQ_GPIOINT S5P_IRQ_VIC0(30)
+#define IRQ_FIMC3 S5P_IRQ_VIC0(31)
+
+/* VIC1: ARM, Power, Memory, Connectivity, Storage */
+
+#define IRQ_CORTEX0 S5P_IRQ_VIC1(0)
+#define IRQ_CORTEX1 S5P_IRQ_VIC1(1)
+#define IRQ_CORTEX2 S5P_IRQ_VIC1(2)
+#define IRQ_CORTEX3 S5P_IRQ_VIC1(3)
+#define IRQ_CORTEX4 S5P_IRQ_VIC1(4)
+#define IRQ_IEMAPC S5P_IRQ_VIC1(5)
+#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_UART0 S5P_IRQ_VIC1(10)
+#define IRQ_UART1 S5P_IRQ_VIC1(11)
+#define IRQ_UART2 S5P_IRQ_VIC1(12)
+#define IRQ_UART3 S5P_IRQ_VIC1(13)
+#define IRQ_IIC S5P_IRQ_VIC1(14)
+#define IRQ_SPI0 S5P_IRQ_VIC1(15)
+#define IRQ_SPI1 S5P_IRQ_VIC1(16)
+#define IRQ_SPI2 S5P_IRQ_VIC1(17)
+#define IRQ_IRDA S5P_IRQ_VIC1(18)
+#define IRQ_CAN0 S5P_IRQ_VIC1(19)
+#define IRQ_CAN1 S5P_IRQ_VIC1(20)
+#define IRQ_HSIRX S5P_IRQ_VIC1(21)
+#define IRQ_HSITX S5P_IRQ_VIC1(22)
+#define IRQ_UHOST S5P_IRQ_VIC1(23)
+#define IRQ_OTG S5P_IRQ_VIC1(24)
+#define IRQ_MSM S5P_IRQ_VIC1(25)
+#define IRQ_HSMMC0 S5P_IRQ_VIC1(26)
+#define IRQ_HSMMC1 S5P_IRQ_VIC1(27)
+#define IRQ_HSMMC2 S5P_IRQ_VIC1(28)
+#define IRQ_MIPICSI S5P_IRQ_VIC1(29)
+#define IRQ_MIPIDSI S5P_IRQ_VIC1(30)
+#define IRQ_ONENAND_AUDI S5P_IRQ_VIC1(31)
+
+/* VIC2: Multimedia, Audio, Security */
+
+#define IRQ_LCD0 S5P_IRQ_VIC2(0)
+#define IRQ_LCD1 S5P_IRQ_VIC2(1)
+#define IRQ_LCD2 S5P_IRQ_VIC2(2)
+#define IRQ_LCD3 S5P_IRQ_VIC2(3)
+#define IRQ_ROTATOR S5P_IRQ_VIC2(4)
+#define IRQ_FIMC0 S5P_IRQ_VIC2(5)
+#define IRQ_FIMC1 S5P_IRQ_VIC2(6)
+#define IRQ_FIMC2 S5P_IRQ_VIC2(7)
+#define IRQ_JPEG S5P_IRQ_VIC2(8)
+#define IRQ_2D S5P_IRQ_VIC2(9)
+#define IRQ_3D S5P_IRQ_VIC2(10)
+#define IRQ_MIXER S5P_IRQ_VIC2(11)
+#define IRQ_HDMI S5P_IRQ_VIC2(12)
+#define IRQ_IIC1 S5P_IRQ_VIC2(13)
+#define IRQ_MFC S5P_IRQ_VIC2(14)
+#define IRQ_TVENC S5P_IRQ_VIC2(15)
+#define IRQ_I2S0 S5P_IRQ_VIC2(16)
+#define IRQ_I2S1 S5P_IRQ_VIC2(17)
+#define IRQ_I2S2 S5P_IRQ_VIC2(18)
+#define IRQ_AC97 S5P_IRQ_VIC2(19)
+#define IRQ_PCM0 S5P_IRQ_VIC2(20)
+#define IRQ_PCM1 S5P_IRQ_VIC2(21)
+#define IRQ_SPDIF S5P_IRQ_VIC2(22)
+#define IRQ_ADC S5P_IRQ_VIC2(23)
+#define IRQ_PENDN S5P_IRQ_VIC2(24)
+#define IRQ_TC IRQ_PENDN
+#define IRQ_KEYPAD S5P_IRQ_VIC2(25)
+#define IRQ_CG S5P_IRQ_VIC2(26)
+#define IRQ_SEC S5P_IRQ_VIC2(27)
+#define IRQ_SECRX S5P_IRQ_VIC2(28)
+#define IRQ_SECTX S5P_IRQ_VIC2(29)
+#define IRQ_SDMIRQ S5P_IRQ_VIC2(30)
+#define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
+
+/* VIC3: Etc */
+
+#define IRQ_IPC S5P_IRQ_VIC3(0)
+#define IRQ_HOSTIF S5P_IRQ_VIC3(1)
+#define IRQ_MMC3 S5P_IRQ_VIC3(2)
+#define IRQ_CEC S5P_IRQ_VIC3(3)
+#define IRQ_TSI S5P_IRQ_VIC3(4)
+#define IRQ_MDNIE0 S5P_IRQ_VIC3(5)
+#define IRQ_MDNIE1 S5P_IRQ_VIC3(6)
+#define IRQ_MDNIE2 S5P_IRQ_VIC3(7)
+#define IRQ_MDNIE3 S5P_IRQ_VIC3(8)
+#define IRQ_VIC_END S5P_IRQ_VIC3(31)
+
+#define S5P_IRQ_EINT_BASE (IRQ_VIC_END + 1)
+
+#define S5P_EINT(x) ((x) + S5P_IRQ_EINT_BASE)
+#define IRQ_EINT(x) S5P_EINT(x)
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS (IRQ_EINT(31) + 1)
+
+#endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
new file mode 100644
index 00000000000..c22694c8231
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -0,0 +1,65 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/map.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5PV210_PA_CHIPID (0xE0000000)
+#define S5P_PA_CHIPID S5PV210_PA_CHIPID
+
+#define S5PV210_PA_SYSCON (0xE0100000)
+#define S5P_PA_SYSCON S5PV210_PA_SYSCON
+
+#define S5PV210_PA_GPIO (0xE0200000)
+#define S5P_PA_GPIO S5PV210_PA_GPIO
+
+#define S5PV210_PA_IIC0 (0xE1800000)
+
+#define S5PV210_PA_TIMER (0xE2500000)
+#define S5P_PA_TIMER S5PV210_PA_TIMER
+
+#define S5PV210_PA_SYSTIMER (0xE2600000)
+
+#define S5PV210_PA_UART (0xE2900000)
+
+#define S5P_PA_UART0 (S5PV210_PA_UART + 0x0)
+#define S5P_PA_UART1 (S5PV210_PA_UART + 0x400)
+#define S5P_PA_UART2 (S5PV210_PA_UART + 0x800)
+#define S5P_PA_UART3 (S5PV210_PA_UART + 0xC00)
+
+#define S5P_SZ_UART SZ_256
+
+#define S5PV210_PA_SROMC (0xE8000000)
+
+#define S5PV210_PA_VIC0 (0xF2000000)
+#define S5P_PA_VIC0 S5PV210_PA_VIC0
+
+#define S5PV210_PA_VIC1 (0xF2100000)
+#define S5P_PA_VIC1 S5PV210_PA_VIC1
+
+#define S5PV210_PA_VIC2 (0xF2200000)
+#define S5P_PA_VIC2 S5PV210_PA_VIC2
+
+#define S5PV210_PA_VIC3 (0xF2300000)
+#define S5P_PA_VIC3 S5PV210_PA_VIC3
+
+#define S5PV210_PA_SDRAM (0x20000000)
+#define S5P_PA_SDRAM S5PV210_PA_SDRAM
+
+/* compatibiltiy defines. */
+#define S3C_PA_UART S5PV210_PA_UART
+#define S3C_PA_IIC S5PV210_PA_IIC0
+
+#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
new file mode 100644
index 00000000000..379117e2760
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/memory.h
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/memory.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#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
+#define SECTION_SIZE_BITS 28
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
new file mode 100644
index 00000000000..69027fea987
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ *
+ * S5PV210 - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @cfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return tcfg == S3C2410_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << (1 + tcfg1);
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 0;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div) - 1;
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+
+#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
new file mode 100644
index 00000000000..e56e0e4673e
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -0,0 +1,169 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S5P_APLL_LOCK S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK S5P_CLKREG(0x08)
+#define S5P_EPLL_LOCK S5P_CLKREG(0x10)
+#define S5P_VPLL_LOCK S5P_CLKREG(0x20)
+
+#define S5P_APLL_CON S5P_CLKREG(0x100)
+#define S5P_MPLL_CON S5P_CLKREG(0x108)
+#define S5P_EPLL_CON S5P_CLKREG(0x110)
+#define S5P_VPLL_CON S5P_CLKREG(0x120)
+
+#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
+#define S5P_CLK_SRC1 S5P_CLKREG(0x204)
+#define S5P_CLK_SRC2 S5P_CLKREG(0x208)
+#define S5P_CLK_SRC3 S5P_CLKREG(0x20C)
+#define S5P_CLK_SRC4 S5P_CLKREG(0x210)
+#define S5P_CLK_SRC5 S5P_CLKREG(0x214)
+#define S5P_CLK_SRC6 S5P_CLKREG(0x218)
+
+#define S5P_CLK_SRC_MASK0 S5P_CLKREG(0x280)
+#define S5P_CLK_SRC_MASK1 S5P_CLKREG(0x284)
+
+#define S5P_CLK_DIV0 S5P_CLKREG(0x300)
+#define S5P_CLK_DIV1 S5P_CLKREG(0x304)
+#define S5P_CLK_DIV2 S5P_CLKREG(0x308)
+#define S5P_CLK_DIV3 S5P_CLKREG(0x30C)
+#define S5P_CLK_DIV4 S5P_CLKREG(0x310)
+#define S5P_CLK_DIV5 S5P_CLKREG(0x314)
+#define S5P_CLK_DIV6 S5P_CLKREG(0x318)
+#define S5P_CLK_DIV7 S5P_CLKREG(0x31C)
+
+#define S5P_CLKGATE_MAIN0 S5P_CLKREG(0x400)
+#define S5P_CLKGATE_MAIN1 S5P_CLKREG(0x404)
+#define S5P_CLKGATE_MAIN2 S5P_CLKREG(0x408)
+
+#define S5P_CLKGATE_PERI0 S5P_CLKREG(0x420)
+#define S5P_CLKGATE_PERI1 S5P_CLKREG(0x424)
+
+#define S5P_CLKGATE_SCLK0 S5P_CLKREG(0x440)
+#define S5P_CLKGATE_SCLK1 S5P_CLKREG(0x444)
+#define S5P_CLKGATE_IP0 S5P_CLKREG(0x460)
+#define S5P_CLKGATE_IP1 S5P_CLKREG(0x464)
+#define S5P_CLKGATE_IP2 S5P_CLKREG(0x468)
+#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C)
+#define S5P_CLKGATE_IP4 S5P_CLKREG(0x470)
+
+#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x480)
+#define S5P_CLKGATE_BUS0 S5P_CLKREG(0x484)
+#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488)
+#define S5P_CLK_OUT S5P_CLKREG(0x500)
+
+/* CLKSRC0 */
+#define S5P_CLKSRC0_MUX200_MASK (0x1<<16)
+#define S5P_CLKSRC0_MUX166_MASK (0x1<<20)
+#define S5P_CLKSRC0_MUX133_MASK (0x1<<24)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_APLL_SHIFT (0)
+#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
+#define S5P_CLKDIV0_A2M_SHIFT (4)
+#define S5P_CLKDIV0_A2M_MASK (0x7 << S5P_CLKDIV0_A2M_SHIFT)
+#define S5P_CLKDIV0_HCLK200_SHIFT (8)
+#define S5P_CLKDIV0_HCLK200_MASK (0x7 << S5P_CLKDIV0_HCLK200_SHIFT)
+#define S5P_CLKDIV0_PCLK100_SHIFT (12)
+#define S5P_CLKDIV0_PCLK100_MASK (0x7 << S5P_CLKDIV0_PCLK100_SHIFT)
+#define S5P_CLKDIV0_HCLK166_SHIFT (16)
+#define S5P_CLKDIV0_HCLK166_MASK (0xF << S5P_CLKDIV0_HCLK166_SHIFT)
+#define S5P_CLKDIV0_PCLK83_SHIFT (20)
+#define S5P_CLKDIV0_PCLK83_MASK (0x7 << S5P_CLKDIV0_PCLK83_SHIFT)
+#define S5P_CLKDIV0_HCLK133_SHIFT (24)
+#define S5P_CLKDIV0_HCLK133_MASK (0xF << S5P_CLKDIV0_HCLK133_SHIFT)
+#define S5P_CLKDIV0_PCLK66_SHIFT (28)
+#define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
+
+/* Registers related to power management */
+#define S5P_PWR_CFG S5P_CLKREG(0xC000)
+#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004)
+#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008)
+#define S5P_PWR_MODE S5P_CLKREG(0xC00C)
+#define S5P_NORMAL_CFG S5P_CLKREG(0xC010)
+#define S5P_IDLE_CFG S5P_CLKREG(0xC020)
+#define S5P_STOP_CFG S5P_CLKREG(0xC030)
+#define S5P_STOP_MEM_CFG S5P_CLKREG(0xC034)
+#define S5P_SLEEP_CFG S5P_CLKREG(0xC040)
+
+#define S5P_OSC_FREQ S5P_CLKREG(0xC100)
+#define S5P_OSC_STABLE S5P_CLKREG(0xC104)
+#define S5P_PWR_STABLE S5P_CLKREG(0xC108)
+#define S5P_MTC_STABLE S5P_CLKREG(0xC110)
+#define S5P_CLAMP_STABLE S5P_CLKREG(0xC114)
+
+#define S5P_WAKEUP_STAT S5P_CLKREG(0xC200)
+#define S5P_BLK_PWR_STAT S5P_CLKREG(0xC204)
+
+#define S5P_OTHERS S5P_CLKREG(0xE000)
+#define S5P_OM_STAT S5P_CLKREG(0xE100)
+#define S5P_USB_PHY_CONTROL S5P_CLKREG(0xE80C)
+#define S5P_DAC_CONTROL S5P_CLKREG(0xE810)
+
+#define S5P_INFORM0 S5P_CLKREG(0xF000)
+#define S5P_INFORM1 S5P_CLKREG(0xF004)
+#define S5P_INFORM2 S5P_CLKREG(0xF008)
+#define S5P_INFORM3 S5P_CLKREG(0xF00C)
+#define S5P_INFORM4 S5P_CLKREG(0xF010)
+#define S5P_INFORM5 S5P_CLKREG(0xF014)
+#define S5P_INFORM6 S5P_CLKREG(0xF018)
+#define S5P_INFORM7 S5P_CLKREG(0xF01C)
+
+#define S5P_RST_STAT S5P_CLKREG(0xA000)
+#define S5P_OSC_CON S5P_CLKREG(0x8000)
+#define S5P_MIPI_PHY_CON0 S5P_CLKREG(0x7200)
+#define S5P_MIPI_PHY_CON1 S5P_CLKREG(0x7204)
+#define S5P_MIPI_CONTROL S5P_CLKREG(0xE814)
+
+#define S5P_IDLE_CFG_TL_MASK (3 << 30)
+#define S5P_IDLE_CFG_TM_MASK (3 << 28)
+#define S5P_IDLE_CFG_TL_ON (2 << 30)
+#define S5P_IDLE_CFG_TM_ON (2 << 28)
+#define S5P_IDLE_CFG_DIDLE (1 << 0)
+
+#define S5P_CFG_WFI_CLEAN (~(3 << 8))
+#define S5P_CFG_WFI_IDLE (1 << 8)
+#define S5P_CFG_WFI_STOP (2 << 8)
+#define S5P_CFG_WFI_SLEEP (3 << 8)
+
+#define S5P_OTHER_SYS_INT 24
+#define S5P_OTHER_STA_TYPE 23
+#define S5P_OTHER_SYSC_INTOFF (1 << 0)
+#define STA_TYPE_EXPON 0
+#define STA_TYPE_SFR 1
+
+#define S5P_PWR_STA_EXP_SCALE 0
+#define S5P_PWR_STA_CNT 4
+
+#define S5P_PWR_STABLE_COUNT 85500
+
+#define S5P_SLEEP_CFG_OSC_EN (1 << 0)
+#define S5P_SLEEP_CFG_USBOSC_EN (1 << 1)
+
+/* OTHERS Resgister */
+#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
+#define S5P_OTHERS_MIPI_DPHY_EN (1 << 28)
+
+/* MIPI */
+#define S5P_MIPI_DPHY_EN (3)
+
+/* S5P_DAC_CONTROL */
+#define S5P_DAC_ENABLE (1)
+#define S5P_DAC_DISABLE (0)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-irq.h b/arch/arm/mach-s5pv210/include/mach/regs-irq.h
new file mode 100644
index 00000000000..5c3b104a7c8
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/system.h b/arch/arm/mach-s5pv210/include/mach/system.h
new file mode 100644
index 00000000000..1ca04d5025b
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/system.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/system.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+static void arch_idle(void)
+{
+ /* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ /* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/tick.h b/arch/arm/mach-s5pv210/include/mach/tick.h
new file mode 100644
index 00000000000..7993b3603cc
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/tick.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/tick.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/tick.h
+ *
+ * S5PV210 - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX (0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/timex.h b/arch/arm/mach-s5pv210/include/mach/timex.h
new file mode 100644
index 00000000000..73dc85496a8
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/timex.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/timex.h
+ *
+ * S5PV210 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H __FILE__
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/uncompress.h b/arch/arm/mach-s5pv210/include/mach/uncompress.h
new file mode 100644
index 00000000000..08ff2fda1fb
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/uncompress.h
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/uncompress.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/vmalloc.h b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
new file mode 100644
index 00000000000..58f515e0747
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/vmalloc.h
+ *
+ * S5PV210 vmalloc definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H __FILE__
+
+#define VMALLOC_END (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pv210/init.c b/arch/arm/mach-s5pv210/init.c
new file mode 100644
index 00000000000..4865ae2c475
--- /dev/null
+++ b/arch/arm/mach-s5pv210/init.c
@@ -0,0 +1,44 @@
+/* linux/arch/arm/mach-s5pv210/init.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5pv210.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
+ [0] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+};
+
+/* uart registration process */
+void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ struct s3c2410_uartcfg *tcfg = cfg;
+ u32 ucnt;
+
+ for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+ if (!tcfg->clocks) {
+ tcfg->clocks = s5pv210_serial_clocks;
+ tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
+ }
+ }
+
+ s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
new file mode 100644
index 00000000000..ab4869df30c
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -0,0 +1,98 @@
+/* linux/arch/arm/mach-s5pv210/mach-smdkc110.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define S5PV210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+};
+
+static struct platform_device *smdkc110_devices[] __initdata = {
+};
+
+static void __init smdkc110_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+}
+
+static void __init smdkc110_machine_init(void)
+{
+ platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));
+}
+
+MACHINE_START(SMDKC110, "SMDKC110")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv210_init_irq,
+ .map_io = smdkc110_map_io,
+ .init_machine = smdkc110_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
new file mode 100644
index 00000000000..a2788325320
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -0,0 +1,98 @@
+/* linux/arch/arm/mach-s5pv210/mach-smdkv210.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define S5PV210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = S5PV210_UCON_DEFAULT,
+ .ulcon = S5PV210_ULCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT,
+ },
+};
+
+static struct platform_device *smdkv210_devices[] __initdata = {
+};
+
+static void __init smdkv210_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+}
+
+static void __init smdkv210_machine_init(void)
+{
+ platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
+}
+
+MACHINE_START(SMDKV210, "SMDKV210")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .phys_io = S3C_PA_UART & 0xfff00000,
+ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv210_init_irq,
+ .map_io = smdkv210_map_io,
+ .init_machine = smdkv210_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index 051ec0f0023..259cb2c15ff 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -51,6 +51,10 @@ static struct resource sa1111_resources[] = {
},
};
+static struct sa1111_platform_data sa1111_info = {
+ .irq_base = IRQ_BOARD_END,
+};
+
static u64 sa1111_dmamask = 0xffffffffUL;
static struct platform_device sa1111_device = {
@@ -59,6 +63,7 @@ static struct platform_device sa1111_device = {
.dev = {
.dma_mask = &sa1111_dmamask,
.coherent_dma_mask = 0xffffffff,
+ .platform_data = &sa1111_info,
},
.num_resources = ARRAY_SIZE(sa1111_resources),
.resource = sa1111_resources,
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 9982c5c28ed..5d5f330c5d9 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -234,6 +234,10 @@ static struct resource locomo_resources[] = {
},
};
+static struct locomo_platform_data locomo_info = {
+ .irq_base = IRQ_BOARD_START,
+};
+
struct platform_device collie_locomo_device = {
.name = "locomo",
.id = 0,
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
index 71a0b3fdcc8..52acda7061b 100644
--- a/arch/arm/mach-sa1100/include/mach/collie.h
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -72,13 +72,6 @@
#define COLLIE_IRQ_GPIO_GA_INT IRQ_GPIO25
#define COLLIE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO26
-#define COLLIE_LCM_IRQ_GPIO_RTS IRQ_LOCOMO_GPIO0
-#define COLLIE_LCM_IRQ_GPIO_CTS IRQ_LOCOMO_GPIO1
-#define COLLIE_LCM_IRQ_GPIO_DSR IRQ_LOCOMO_GPIO2
-#define COLLIE_LCM_IRQ_GPIO_DTR IRQ_LOCOMO_GPIO3
-#define COLLIE_LCM_IRQ_GPIO_nSD_DETECT IRQ_LOCOMO_GPIO13
-#define COLLIE_LCM_IRQ_GPIO_nSD_WP IRQ_LOCOMO_GPIO14
-
/* GPIO's on the TC35143AF (Toshiba Analog Frontend) */
#define COLLIE_TC35143_GPIO_BASE (GPIO_MAX + 13)
#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index ae81f80b0cf..8c8845b5ae5 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -68,93 +68,17 @@
#define IRQ_BOARD_START 49
#define IRQ_BOARD_END 65
-#define IRQ_SA1111_START (IRQ_BOARD_END)
-#define IRQ_GPAIN0 (IRQ_BOARD_END + 0)
-#define IRQ_GPAIN1 (IRQ_BOARD_END + 1)
-#define IRQ_GPAIN2 (IRQ_BOARD_END + 2)
-#define IRQ_GPAIN3 (IRQ_BOARD_END + 3)
-#define IRQ_GPBIN0 (IRQ_BOARD_END + 4)
-#define IRQ_GPBIN1 (IRQ_BOARD_END + 5)
-#define IRQ_GPBIN2 (IRQ_BOARD_END + 6)
-#define IRQ_GPBIN3 (IRQ_BOARD_END + 7)
-#define IRQ_GPBIN4 (IRQ_BOARD_END + 8)
-#define IRQ_GPBIN5 (IRQ_BOARD_END + 9)
-#define IRQ_GPCIN0 (IRQ_BOARD_END + 10)
-#define IRQ_GPCIN1 (IRQ_BOARD_END + 11)
-#define IRQ_GPCIN2 (IRQ_BOARD_END + 12)
-#define IRQ_GPCIN3 (IRQ_BOARD_END + 13)
-#define IRQ_GPCIN4 (IRQ_BOARD_END + 14)
-#define IRQ_GPCIN5 (IRQ_BOARD_END + 15)
-#define IRQ_GPCIN6 (IRQ_BOARD_END + 16)
-#define IRQ_GPCIN7 (IRQ_BOARD_END + 17)
-#define IRQ_MSTXINT (IRQ_BOARD_END + 18)
-#define IRQ_MSRXINT (IRQ_BOARD_END + 19)
-#define IRQ_MSSTOPERRINT (IRQ_BOARD_END + 20)
-#define IRQ_TPTXINT (IRQ_BOARD_END + 21)
-#define IRQ_TPRXINT (IRQ_BOARD_END + 22)
-#define IRQ_TPSTOPERRINT (IRQ_BOARD_END + 23)
-#define SSPXMTINT (IRQ_BOARD_END + 24)
-#define SSPRCVINT (IRQ_BOARD_END + 25)
-#define SSPROR (IRQ_BOARD_END + 26)
-#define AUDXMTDMADONEA (IRQ_BOARD_END + 32)
-#define AUDRCVDMADONEA (IRQ_BOARD_END + 33)
-#define AUDXMTDMADONEB (IRQ_BOARD_END + 34)
-#define AUDRCVDMADONEB (IRQ_BOARD_END + 35)
-#define AUDTFSR (IRQ_BOARD_END + 36)
-#define AUDRFSR (IRQ_BOARD_END + 37)
-#define AUDTUR (IRQ_BOARD_END + 38)
-#define AUDROR (IRQ_BOARD_END + 39)
-#define AUDDTS (IRQ_BOARD_END + 40)
-#define AUDRDD (IRQ_BOARD_END + 41)
-#define AUDSTO (IRQ_BOARD_END + 42)
-#define IRQ_USBPWR (IRQ_BOARD_END + 43)
-#define IRQ_HCIM (IRQ_BOARD_END + 44)
-#define IRQ_HCIBUFFACC (IRQ_BOARD_END + 45)
-#define IRQ_HCIRMTWKP (IRQ_BOARD_END + 46)
-#define IRQ_NHCIMFCIR (IRQ_BOARD_END + 47)
-#define IRQ_USB_PORT_RESUME (IRQ_BOARD_END + 48)
-#define IRQ_S0_READY_NINT (IRQ_BOARD_END + 49)
-#define IRQ_S1_READY_NINT (IRQ_BOARD_END + 50)
-#define IRQ_S0_CD_VALID (IRQ_BOARD_END + 51)
-#define IRQ_S1_CD_VALID (IRQ_BOARD_END + 52)
-#define IRQ_S0_BVD1_STSCHG (IRQ_BOARD_END + 53)
-#define IRQ_S1_BVD1_STSCHG (IRQ_BOARD_END + 54)
-
-#define IRQ_LOCOMO_START (IRQ_BOARD_END)
-#define IRQ_LOCOMO_KEY (IRQ_BOARD_END + 0)
-#define IRQ_LOCOMO_GPIO0 (IRQ_BOARD_END + 1)
-#define IRQ_LOCOMO_GPIO1 (IRQ_BOARD_END + 2)
-#define IRQ_LOCOMO_GPIO2 (IRQ_BOARD_END + 3)
-#define IRQ_LOCOMO_GPIO3 (IRQ_BOARD_END + 4)
-#define IRQ_LOCOMO_GPIO4 (IRQ_BOARD_END + 5)
-#define IRQ_LOCOMO_GPIO5 (IRQ_BOARD_END + 6)
-#define IRQ_LOCOMO_GPIO6 (IRQ_BOARD_END + 7)
-#define IRQ_LOCOMO_GPIO7 (IRQ_BOARD_END + 8)
-#define IRQ_LOCOMO_GPIO8 (IRQ_BOARD_END + 9)
-#define IRQ_LOCOMO_GPIO9 (IRQ_BOARD_END + 10)
-#define IRQ_LOCOMO_GPIO10 (IRQ_BOARD_END + 11)
-#define IRQ_LOCOMO_GPIO11 (IRQ_BOARD_END + 12)
-#define IRQ_LOCOMO_GPIO12 (IRQ_BOARD_END + 13)
-#define IRQ_LOCOMO_GPIO13 (IRQ_BOARD_END + 14)
-#define IRQ_LOCOMO_GPIO14 (IRQ_BOARD_END + 15)
-#define IRQ_LOCOMO_GPIO15 (IRQ_BOARD_END + 16)
-#define IRQ_LOCOMO_LT (IRQ_BOARD_END + 17)
-#define IRQ_LOCOMO_SPI_RFR (IRQ_BOARD_END + 18)
-#define IRQ_LOCOMO_SPI_RFW (IRQ_BOARD_END + 19)
-#define IRQ_LOCOMO_SPI_REND (IRQ_BOARD_END + 20)
-#define IRQ_LOCOMO_SPI_TEND (IRQ_BOARD_END + 21)
-
/*
* Figure out the MAX IRQ number.
*
* If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
- * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1
+ * If we have an LoCoMo, the max IRQ is IRQ_BOARD_START + 4
* Otherwise, we have the standard IRQs only.
*/
#ifdef CONFIG_SA1111
-#define NR_IRQS (IRQ_S1_BVD1_STSCHG + 1)
-#elif defined(CONFIG_SHARP_LOCOMO)
-#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
+#define NR_IRQS (IRQ_BOARD_END + 55)
+#elif defined(CONFIG_SHARPSL_LOCOMO)
+#define NR_IRQS (IRQ_BOARD_START + 4)
#else
#define NR_IRQS (IRQ_BOARD_START)
#endif
@@ -166,10 +90,3 @@
#define IRQ_NEPONSET_SMC9196 (IRQ_BOARD_START + 0)
#define IRQ_NEPONSET_USAR (IRQ_BOARD_START + 1)
#define IRQ_NEPONSET_SA1111 (IRQ_BOARD_START + 2)
-
-/* LoCoMo Interrupts (CONFIG_SHARP_LOCOMO) */
-#define IRQ_LOCOMO_KEY_BASE (IRQ_BOARD_START + 0)
-#define IRQ_LOCOMO_GPIO_BASE (IRQ_BOARD_START + 1)
-#define IRQ_LOCOMO_LT_BASE (IRQ_BOARD_START + 2)
-#define IRQ_LOCOMO_SPI_BASE (IRQ_BOARD_START + 3)
-
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 13ebd2d99bf..d3ec620618f 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -208,6 +208,10 @@ static struct resource sa1111_resources[] = {
},
};
+static struct sa1111_platform_data sa1111_info = {
+ .irq_base = IRQ_BOARD_END,
+};
+
static u64 sa1111_dmamask = 0xffffffffUL;
static struct platform_device sa1111_device = {
@@ -216,6 +220,7 @@ static struct platform_device sa1111_device = {
.dev = {
.dma_mask = &sa1111_dmamask,
.coherent_dma_mask = 0xffffffff,
+ .platform_data = &sa1111_info,
},
.num_resources = ARRAY_SIZE(sa1111_resources),
.resource = sa1111_resources,
diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c
index 506a5e5a9ad..9d490c66891 100644
--- a/arch/arm/mach-sa1100/jornada720_ssp.c
+++ b/arch/arm/mach-sa1100/jornada720_ssp.c
@@ -18,7 +18,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/jornada720.h>
@@ -130,7 +129,7 @@ void jornada_ssp_end(void)
};
EXPORT_SYMBOL(jornada_ssp_end);
-static int __init jornada_ssp_probe(struct platform_device *dev)
+static int __devinit jornada_ssp_probe(struct platform_device *dev)
{
int ret;
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 6ccd175bc4c..c601a75a333 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -8,7 +8,6 @@
#include <linux/ioport.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -241,6 +240,10 @@ static struct resource sa1111_resources[] = {
},
};
+static struct sa1111_platform_data sa1111_info = {
+ .irq_base = IRQ_BOARD_END,
+};
+
static u64 sa1111_dmamask = 0xffffffffUL;
static struct platform_device sa1111_device = {
@@ -249,6 +252,7 @@ static struct platform_device sa1111_device = {
.dev = {
.dma_mask = &sa1111_dmamask,
.coherent_dma_mask = 0xffffffff,
+ .platform_data = &sa1111_info,
},
.num_resources = ARRAY_SIZE(sa1111_resources),
.resource = sa1111_resources,
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index b9cbb56d6e9..74b6e0e570b 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -35,14 +35,12 @@ static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id)
static int
sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
{
- unsigned long flags, next, oscr;
+ unsigned long next, oscr;
- raw_local_irq_save(flags);
OIER |= OIER_E0;
next = OSCR + delta;
OSMR0 = next;
oscr = OSCR;
- raw_local_irq_restore(flags);
return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
}
@@ -50,16 +48,12 @@ sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
static void
sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)
{
- unsigned long flags;
-
switch (mode) {
case CLOCK_EVT_MODE_ONESHOT:
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
- raw_local_irq_save(flags);
OIER &= ~OIER_E0;
OSSR = OSSR_M0;
- raw_local_irq_restore(flags);
break;
case CLOCK_EVT_MODE_RESUME:
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
new file mode 100644
index 00000000000..aeceb9b92ae
--- /dev/null
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -0,0 +1,84 @@
+if ARCH_SHMOBILE
+
+comment "SH-Mobile System Type"
+
+config ARCH_SH7367
+ bool "SH-Mobile G3 (SH7367)"
+ select CPU_V6
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+
+config ARCH_SH7377
+ bool "SH-Mobile G4 (SH7377)"
+ select CPU_V7
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+
+config ARCH_SH7372
+ bool "SH-Mobile AP4 (SH7372)"
+ select CPU_V7
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+
+comment "SH-Mobile Board Type"
+
+config MACH_G3EVM
+ bool "G3EVM board"
+ depends on ARCH_SH7367
+ select ARCH_REQUIRE_GPIOLIB
+
+config MACH_G4EVM
+ bool "G4EVM board"
+ depends on ARCH_SH7377
+ select ARCH_REQUIRE_GPIOLIB
+
+config MACH_AP4EVB
+ bool "AP4EVB board"
+ depends on ARCH_SH7372
+ select ARCH_REQUIRE_GPIOLIB
+
+comment "SH-Mobile System Configuration"
+
+menu "Memory configuration"
+
+config MEMORY_START
+ hex "Physical memory start address"
+ default "0x50000000" if MACH_G3EVM
+ default "0x40000000" if MACH_G4EVM
+ default "0x40000000" if MACH_AP4EVB
+ default "0x00000000"
+ ---help---
+ Tweak this only when porting to a new machine which does not
+ already have a defconfig. Changing it from the known correct
+ value on any of the known systems will only lead to disaster.
+
+config MEMORY_SIZE
+ hex "Physical memory size"
+ default "0x08000000" if MACH_G3EVM
+ default "0x08000000" if MACH_G4EVM
+ default "0x10000000" if MACH_AP4EVB
+ default "0x04000000"
+ help
+ This sets the default memory size assumed by your kernel. It can
+ be overridden as normal by the 'mem=' argument on the kernel command
+ line.
+
+endmenu
+
+menu "Timer and clock configuration"
+
+config SH_TIMER_CMT
+ bool "CMT timer driver"
+ default y
+ help
+ This enables build of the CMT timer driver.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
new file mode 100644
index 00000000000..6d385d371c3
--- /dev/null
+++ b/arch/arm/mach-shmobile/Makefile
@@ -0,0 +1,22 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common objects
+obj-y := timer.o console.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
+
+# Pinmux setup
+pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o
+pfc-$(CONFIG_ARCH_SH7377) := pfc-sh7377.o
+pfc-$(CONFIG_ARCH_SH7372) := pfc-sh7372.o
+obj-$(CONFIG_GENERIC_GPIO) += $(pfc-y)
+
+# Board objects
+obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o
+obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o
+obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o
diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot
new file mode 100644
index 00000000000..1c08ee9de86
--- /dev/null
+++ b/arch/arm/mach-shmobile/Makefile.boot
@@ -0,0 +1,9 @@
+__ZRELADDR := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_MEMORY_START) + 0x8000]')
+
+ zreladdr-y := $(__ZRELADDR)
+
+# Unsupported legacy stuff
+#
+#params_phys-y (Instead: Pass atags pointer in r2)
+#initrd_phys-y (Instead: Use compiled-in initramfs)
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
new file mode 100644
index 00000000000..1c2ec96ce26
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -0,0 +1,333 @@
+/*
+ * AP4EVB board support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <mach/common.h>
+#include <mach/sh7372.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+/*
+ * Address Interface BusWidth note
+ * ------------------------------------------------------------------
+ * 0x0000_0000 NOR Flash ROM (MCP) 16bit SW7 : bit1 = ON
+ * 0x0800_0000 user area -
+ * 0x1000_0000 NOR Flash ROM (MCP) 16bit SW7 : bit1 = OFF
+ * 0x1400_0000 Ether (LAN9220) 16bit
+ * 0x1600_0000 user area - cannot use with NAND
+ * 0x1800_0000 user area -
+ * 0x1A00_0000 -
+ * 0x4000_0000 LPDDR2-SDRAM (POP) 32bit
+ */
+
+/*
+ * NOR Flash ROM
+ *
+ * SW1 | SW2 | SW7 | NOR Flash ROM
+ * bit1 | bit1 bit2 | bit1 | Memory allocation
+ * ------+------------+------+------------------
+ * OFF | ON OFF | ON | Area 0
+ * OFF | ON OFF | OFF | Area 4
+ */
+
+/*
+ * NAND Flash ROM
+ *
+ * SW1 | SW2 | SW7 | NAND Flash ROM
+ * bit1 | bit1 bit2 | bit2 | Memory allocation
+ * ------+------------+------+------------------
+ * OFF | ON OFF | ON | FCE 0
+ * OFF | ON OFF | OFF | FCE 1
+ */
+
+/*
+ * SMSC 9220
+ *
+ * SW1 SMSC 9220
+ * -----------------------
+ * ON access disable
+ * OFF access enable
+ */
+
+/*
+ * KEYSC
+ *
+ * SW43 KEYSC
+ * -------------------------
+ * ON enable
+ * OFF disable
+ */
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "kernel_ro",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+/* SMSC 9220 */
+static struct resource smc911x_resources[] = {
+ {
+ .start = 0x14000000,
+ .end = 0x16000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 6,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_16BIT | SMSC911X_SAVE_MAC_ADDRESS,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device smc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc911x_resources),
+ .resource = smc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_info,
+ },
+};
+
+/* KEYSC (Needs SW43 set to ON) */
+static struct sh_keysc_info keysc_info = {
+ .mode = SH_KEYSC_MODE_1,
+ .scan_timing = 3,
+ .delay = 2500,
+ .keycodes = {
+ KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
+ KEY_5, KEY_6, KEY_7, KEY_8, KEY_9,
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
+ KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
+ KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b0063,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 79,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* "keysc0" clock */
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_info,
+ },
+};
+
+/* SDHI0 */
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0xe6850000,
+ .end = 0xe68501ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 96,
+ .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 platform_device *ap4evb_devices[] __initdata = {
+ &nor_flash_device,
+ &smc911x_device,
+ &keysc_device,
+ &sdhi0_device,
+};
+
+static struct map_desc ap4evb_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init ap4evb_map_io(void)
+{
+ iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc));
+
+ /* setup early devices, clocks and console here as well */
+ sh7372_add_early_devices();
+ sh7367_clock_init(); /* use g3 clocks for now */
+ shmobile_setup_console();
+}
+
+static void __init ap4evb_init(void)
+{
+ sh7372_pinmux_init();
+
+ /* enable SCIFA0 */
+ gpio_request(GPIO_FN_SCIFA0_TXD, NULL);
+ gpio_request(GPIO_FN_SCIFA0_RXD, NULL);
+
+ /* enable SMSC911X */
+ gpio_request(GPIO_FN_CS5A, NULL);
+ gpio_request(GPIO_FN_IRQ6_39, NULL);
+
+ /* enable LED 1 - 4 */
+ gpio_request(GPIO_PORT185, NULL);
+ gpio_request(GPIO_PORT186, NULL);
+ gpio_request(GPIO_PORT187, NULL);
+ gpio_request(GPIO_PORT188, NULL);
+ gpio_direction_output(GPIO_PORT185, 1);
+ gpio_direction_output(GPIO_PORT186, 1);
+ gpio_direction_output(GPIO_PORT187, 1);
+ gpio_direction_output(GPIO_PORT188, 1);
+ gpio_export(GPIO_PORT185, 0);
+ gpio_export(GPIO_PORT186, 0);
+ gpio_export(GPIO_PORT187, 0);
+ gpio_export(GPIO_PORT188, 0);
+
+ /* enable Debug switch (S6) */
+ gpio_request(GPIO_PORT32, NULL);
+ gpio_request(GPIO_PORT33, NULL);
+ gpio_request(GPIO_PORT34, NULL);
+ gpio_request(GPIO_PORT35, NULL);
+ gpio_direction_input(GPIO_PORT32);
+ gpio_direction_input(GPIO_PORT33);
+ gpio_direction_input(GPIO_PORT34);
+ gpio_direction_input(GPIO_PORT35);
+ gpio_export(GPIO_PORT32, 0);
+ gpio_export(GPIO_PORT33, 0);
+ gpio_export(GPIO_PORT34, 0);
+ gpio_export(GPIO_PORT35, 0);
+
+ /* enable KEYSC */
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT4, NULL);
+ gpio_request(GPIO_FN_KEYIN0_136, NULL);
+ gpio_request(GPIO_FN_KEYIN1_135, NULL);
+ gpio_request(GPIO_FN_KEYIN2_134, NULL);
+ gpio_request(GPIO_FN_KEYIN3_133, NULL);
+ gpio_request(GPIO_FN_KEYIN4, NULL);
+
+ /* SDHI0 */
+ gpio_request(GPIO_FN_SDHICD0, NULL);
+ gpio_request(GPIO_FN_SDHIWP0, NULL);
+ gpio_request(GPIO_FN_SDHICMD0, NULL);
+ gpio_request(GPIO_FN_SDHICLK0, NULL);
+ gpio_request(GPIO_FN_SDHID0_3, NULL);
+ gpio_request(GPIO_FN_SDHID0_2, NULL);
+ gpio_request(GPIO_FN_SDHID0_1, NULL);
+ gpio_request(GPIO_FN_SDHID0_0, NULL);
+
+ sh7372_add_standard_devices();
+
+ platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
+}
+
+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,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
new file mode 100644
index 00000000000..9247503296c
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -0,0 +1,333 @@
+/*
+ * G3EVM board support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/sh_flctl.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <mach/sh7367.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "kernel_ro",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+/* USBHS */
+void usb_host_port_power(int port, int power)
+{
+ if (!power) /* only power-on supported for now */
+ return;
+
+ /* set VBOUT/PWEN and EXTLP0 in DVSTCTR */
+ __raw_writew(__raw_readw(0xe6890008) | 0x600, 0xe6890008);
+}
+
+static struct r8a66597_platdata usb_host_data = {
+ .on_chip = 1,
+ .port_power = usb_host_port_power,
+};
+
+static struct resource usb_host_resources[] = {
+ [0] = {
+ .name = "USBHS",
+ .start = 0xe6890000,
+ .end = 0xe68900e5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 65,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &usb_host_data,
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(usb_host_resources),
+ .resource = usb_host_resources,
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+ .mode = SH_KEYSC_MODE_5,
+ .scan_timing = 3,
+ .delay = 100,
+ .keycodes = {
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
+ KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N,
+ KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
+ KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP,
+ KEY_WAKEUP, KEY_COFFEE, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
+ KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 79,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_info,
+ },
+};
+
+static struct mtd_partition nand_partition_info[] = {
+ {
+ .name = "system",
+ .offset = 0,
+ .size = 64 * 1024 * 1024,
+ },
+ {
+ .name = "userdata",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 128 * 1024 * 1024,
+ },
+ {
+ .name = "cache",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 64 * 1024 * 1024,
+ },
+};
+
+static struct resource nand_flash_resources[] = {
+ [0] = {
+ .start = 0xe6a30000,
+ .end = 0xe6a3009b,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct sh_flctl_platform_data nand_flash_data = {
+ .parts = nand_partition_info,
+ .nr_parts = ARRAY_SIZE(nand_partition_info),
+ .flcmncr_val = QTSEL_E | FCKSEL_E | TYPESEL_SET | NANWF_E
+ | SHBUSSEL | SEL_16BIT,
+};
+
+static struct platform_device nand_flash_device = {
+ .name = "sh_flctl",
+ .resource = nand_flash_resources,
+ .num_resources = ARRAY_SIZE(nand_flash_resources),
+ .dev = {
+ .platform_data = &nand_flash_data,
+ },
+};
+
+static struct platform_device *g3evm_devices[] __initdata = {
+ &nor_flash_device,
+ &usb_host_device,
+ &keysc_device,
+ &nand_flash_device,
+};
+
+static struct map_desc g3evm_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init g3evm_map_io(void)
+{
+ iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc));
+
+ /* setup early devices, clocks and console here as well */
+ sh7367_add_early_devices();
+ sh7367_clock_init();
+ shmobile_setup_console();
+}
+
+static void __init g3evm_init(void)
+{
+ sh7367_pinmux_init();
+
+ /* Lit DS4 LED */
+ gpio_request(GPIO_PORT22, NULL);
+ gpio_direction_output(GPIO_PORT22, 1);
+ gpio_export(GPIO_PORT22, 0);
+
+ /* Lit DS8 LED */
+ gpio_request(GPIO_PORT23, NULL);
+ gpio_direction_output(GPIO_PORT23, 1);
+ gpio_export(GPIO_PORT23, 0);
+
+ /* Lit DS3 LED */
+ gpio_request(GPIO_PORT24, NULL);
+ gpio_direction_output(GPIO_PORT24, 1);
+ gpio_export(GPIO_PORT24, 0);
+
+ /* SCIFA1 */
+ gpio_request(GPIO_FN_SCIFA1_TXD, NULL);
+ gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
+ gpio_request(GPIO_FN_SCIFA1_CTS, NULL);
+ gpio_request(GPIO_FN_SCIFA1_RTS, NULL);
+
+ /* USBHS */
+ gpio_request(GPIO_FN_VBUS0, NULL);
+ gpio_request(GPIO_FN_PWEN, NULL);
+ gpio_request(GPIO_FN_OVCN, NULL);
+ gpio_request(GPIO_FN_OVCN2, NULL);
+ 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 */
+ __raw_writew(0x6010, 0xe60581c6); /* CGPOSR */
+ __raw_writew(0x8a0a, 0xe605810c); /* USBCR2 */
+
+ /* KEYSC @ CN7 */
+ gpio_request(GPIO_FN_PORT42_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_PORT43_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_PORT44_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_PORT45_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_PORT46_KEYOUT4, NULL);
+ gpio_request(GPIO_FN_PORT47_KEYOUT5, NULL);
+ gpio_request(GPIO_FN_PORT48_KEYIN0_PU, NULL);
+ gpio_request(GPIO_FN_PORT49_KEYIN1_PU, NULL);
+ gpio_request(GPIO_FN_PORT50_KEYIN2_PU, NULL);
+ gpio_request(GPIO_FN_PORT55_KEYIN3_PU, NULL);
+ gpio_request(GPIO_FN_PORT56_KEYIN4_PU, NULL);
+ gpio_request(GPIO_FN_PORT57_KEYIN5_PU, NULL);
+ gpio_request(GPIO_FN_PORT58_KEYIN6_PU, NULL);
+
+ /* FLCTL */
+ gpio_request(GPIO_FN_FCE0, NULL);
+ gpio_request(GPIO_FN_D0_ED0_NAF0, NULL);
+ gpio_request(GPIO_FN_D1_ED1_NAF1, NULL);
+ gpio_request(GPIO_FN_D2_ED2_NAF2, NULL);
+ gpio_request(GPIO_FN_D3_ED3_NAF3, NULL);
+ gpio_request(GPIO_FN_D4_ED4_NAF4, NULL);
+ gpio_request(GPIO_FN_D5_ED5_NAF5, NULL);
+ gpio_request(GPIO_FN_D6_ED6_NAF6, NULL);
+ gpio_request(GPIO_FN_D7_ED7_NAF7, NULL);
+ gpio_request(GPIO_FN_D8_ED8_NAF8, NULL);
+ gpio_request(GPIO_FN_D9_ED9_NAF9, NULL);
+ gpio_request(GPIO_FN_D10_ED10_NAF10, NULL);
+ gpio_request(GPIO_FN_D11_ED11_NAF11, NULL);
+ gpio_request(GPIO_FN_D12_ED12_NAF12, NULL);
+ gpio_request(GPIO_FN_D13_ED13_NAF13, NULL);
+ gpio_request(GPIO_FN_D14_ED14_NAF14, NULL);
+ gpio_request(GPIO_FN_D15_ED15_NAF15, NULL);
+ gpio_request(GPIO_FN_WE0_XWR0_FWE, NULL);
+ gpio_request(GPIO_FN_FRB, NULL);
+ /* FOE, FCDE, FSC on dedicated pins */
+ __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048);
+
+ sh7367_add_standard_devices();
+
+ platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices));
+}
+
+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,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
new file mode 100644
index 00000000000..10673a90be5
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -0,0 +1,268 @@
+/*
+ * G4EVM board support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.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>
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "kernel_ro",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+/* USBHS */
+void usb_host_port_power(int port, int power)
+{
+ if (!power) /* only power-on supported for now */
+ return;
+
+ /* set VBOUT/PWEN and EXTLP0 in DVSTCTR */
+ __raw_writew(__raw_readw(0xe6890008) | 0x600, 0xe6890008);
+}
+
+static struct r8a66597_platdata usb_host_data = {
+ .on_chip = 1,
+ .port_power = usb_host_port_power,
+};
+
+static struct resource usb_host_resources[] = {
+ [0] = {
+ .name = "USBHS",
+ .start = 0xe6890000,
+ .end = 0xe68900e5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 65,
+ .end = 65,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &usb_host_data,
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(usb_host_resources),
+ .resource = usb_host_resources,
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+ .mode = SH_KEYSC_MODE_5,
+ .scan_timing = 3,
+ .delay = 100,
+ .keycodes = {
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F,
+ KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
+ KEY_M, KEY_N, KEY_U, KEY_P, KEY_Q, KEY_R,
+ KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X,
+ KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE,
+ KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
+ KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 79,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* keysc0 clock */
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_info,
+ },
+};
+
+static struct platform_device *g4evm_devices[] __initdata = {
+ &nor_flash_device,
+ &usb_host_device,
+ &keysc_device,
+};
+
+static struct map_desc g4evm_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init g4evm_map_io(void)
+{
+ iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
+
+ /* setup early devices, clocks and console here as well */
+ sh7377_add_early_devices();
+ sh7367_clock_init(); /* use g3 clocks for now */
+ shmobile_setup_console();
+}
+
+static void __init g4evm_init(void)
+{
+ sh7377_pinmux_init();
+
+ /* Lit DS14 LED */
+ gpio_request(GPIO_PORT109, NULL);
+ gpio_direction_output(GPIO_PORT109, 1);
+ gpio_export(GPIO_PORT109, 1);
+
+ /* Lit DS15 LED */
+ gpio_request(GPIO_PORT110, NULL);
+ gpio_direction_output(GPIO_PORT110, 1);
+ gpio_export(GPIO_PORT110, 1);
+
+ /* Lit DS16 LED */
+ gpio_request(GPIO_PORT112, NULL);
+ gpio_direction_output(GPIO_PORT112, 1);
+ gpio_export(GPIO_PORT112, 1);
+
+ /* Lit DS17 LED */
+ gpio_request(GPIO_PORT113, NULL);
+ gpio_direction_output(GPIO_PORT113, 1);
+ gpio_export(GPIO_PORT113, 1);
+
+ /* USBHS */
+ gpio_request(GPIO_FN_VBUS_0, NULL);
+ gpio_request(GPIO_FN_PWEN, NULL);
+ gpio_request(GPIO_FN_OVCN, NULL);
+ gpio_request(GPIO_FN_OVCN2, NULL);
+ 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 */
+ __raw_writew(0x6010, 0xe60581c6); /* CGPOSR */
+ __raw_writew(0x8a0a, 0xe605810c); /* USBCR2 */
+
+ /* KEYSC @ CN31 */
+ gpio_request(GPIO_FN_PORT60_KEYOUT5, NULL);
+ gpio_request(GPIO_FN_PORT61_KEYOUT4, NULL);
+ gpio_request(GPIO_FN_PORT62_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_PORT63_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_PORT64_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_PORT65_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_PORT66_KEYIN0_PU, NULL);
+ gpio_request(GPIO_FN_PORT67_KEYIN1_PU, NULL);
+ gpio_request(GPIO_FN_PORT68_KEYIN2_PU, NULL);
+ gpio_request(GPIO_FN_PORT69_KEYIN3_PU, NULL);
+ gpio_request(GPIO_FN_PORT70_KEYIN4_PU, NULL);
+ gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL);
+ gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL);
+
+ sh7377_add_standard_devices();
+
+ platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
+}
+
+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,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
new file mode 100644
index 00000000000..bb940c6e4e6
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -0,0 +1,103 @@
+/*
+ * Preliminary clock framework support for sh7367
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+
+struct clk {
+ const char *name;
+ unsigned long rate;
+};
+
+#include <asm/clkdev.h>
+
+int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+EXPORT_SYMBOL(__clk_get);
+
+void __clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(__clk_put);
+
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk ? clk->rate : 0;
+}
+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,
+};
+
+/* a static rclk for now - enough to get sh_cmt working */
+static struct clk r_clk = {
+ .name = "r_clk",
+ .rate = 32768,
+};
+
+/* a static usb0 for now - enough to get r8a66597 working */
+static struct clk usb0_clk = {
+ .name = "usb0",
+};
+
+/* a static keysc0 clk for now - enough to get sh_keysc working */
+static struct clk keysc0_clk = {
+ .name = "keysc0",
+};
+
+static struct clk_lookup lookups[] = {
+ {
+ .clk = &peripheral_clk,
+ }, {
+ .clk = &r_clk,
+ }, {
+ .clk = &usb0_clk,
+ }, {
+ .clk = &keysc0_clk,
+ }
+};
+
+void __init sh7367_clock_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ lookups[i].con_id = lookups[i].clk->name;
+ clkdev_add(&lookups[i]);
+ }
+}
diff --git a/arch/arm/mach-shmobile/console.c b/arch/arm/mach-shmobile/console.c
new file mode 100644
index 00000000000..9411a5bf4fd
--- /dev/null
+++ b/arch/arm/mach-shmobile/console.c
@@ -0,0 +1,31 @@
+/*
+ * SH-Mobile Console
+ *
+ * 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/platform_device.h>
+#include <mach/common.h>
+#include <asm/mach/map.h>
+
+void __init shmobile_setup_console(void)
+{
+ parse_early_param();
+
+ /* Let earlyprintk output early console messages */
+ early_platform_driver_probe("earlyprintk", 1, 1);
+}
diff --git a/arch/arm/mach-shmobile/include/mach/clkdev.h b/arch/arm/mach-shmobile/include/mach/clkdev.h
new file mode 100644
index 00000000000..36d0163a857
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+int __clk_get(struct clk *clk);
+void __clk_put(struct clk *clk);
+
+#endif /* __ASM_MACH_CLKDEV_H */
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
new file mode 100644
index 00000000000..57903605cc5
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -0,0 +1,23 @@
+#ifndef __ARCH_MACH_COMMON_H
+#define __ARCH_MACH_COMMON_H
+
+extern struct sys_timer shmobile_timer;
+extern void shmobile_setup_console(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 void sh7377_init_irq(void);
+extern void sh7377_add_early_devices(void);
+extern void sh7377_add_standard_devices(void);
+extern void sh7377_pinmux_init(void);
+
+extern void sh7372_init_irq(void);
+extern void sh7372_add_early_devices(void);
+extern void sh7372_add_standard_devices(void);
+extern void sh7372_pinmux_init(void);
+
+#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/dma.h b/arch/arm/mach-shmobile/include/mach/dma.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/dma.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S
new file mode 100644
index 00000000000..a285d13c741
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =INTFLGA
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base]
+ cmp \irqnr, #0
+ beq 1000f
+ /* intevt to irq number */
+ lsr \irqnr, \irqnr, #0x5
+ subs \irqnr, \irqnr, #16
+
+1000:
+ .endm
diff --git a/arch/arm/mach-shmobile/include/mach/gpio.h b/arch/arm/mach-shmobile/include/mach/gpio.h
new file mode 100644
index 00000000000..5bc6bd444d7
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/gpio.h
@@ -0,0 +1,48 @@
+/*
+ * Generic GPIO API and pinmux table support
+ *
+ * Copyright (c) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#define ARCH_NR_GPIOS 1024
+#include <linux/sh_pfc.h>
+
+#ifdef CONFIG_GPIOLIB
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-shmobile/include/mach/hardware.h b/arch/arm/mach-shmobile/include/mach/hardware.h
new file mode 100644
index 00000000000..3f0ef194603
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/hardware.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_HARDWARE_H
+#define __ASM_MACH_HARDWARE_H
+
+/* INTFLGA register - used by low level interrupt code in entry-macro.S */
+#define INTFLGA 0xe6980018
+
+#endif /* __ASM_MACH_HARDWARE_H */
diff --git a/arch/arm/mach-shmobile/include/mach/io.h b/arch/arm/mach-shmobile/include/mach/io.h
new file mode 100644
index 00000000000..7339fe46cb7
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/io.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_IO_H
+#define __ASM_MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) ((void __iomem *)(a))
+#define __mem_pci(a) (a)
+
+#endif /* __ASM_MACH_IO_H */
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
new file mode 100644
index 00000000000..5179b72e1ee
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+#define NR_IRQS 512
+#define NR_IRQS_LEGACY 8
+
+#define evt2irq(evt) (((evt) >> 5) - 16)
+#define irq2evt(irq) (((irq) + 16) << 5)
+
+#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
new file mode 100644
index 00000000000..e188183f4dc
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/memory.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_MEMORY_H
+#define __ASM_MACH_MEMORY_H
+
+#define PHYS_OFFSET UL(CONFIG_MEMORY_START)
+#define MEM_SIZE UL(CONFIG_MEMORY_SIZE)
+
+#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7367.h b/arch/arm/mach-shmobile/include/mach/sh7367.h
new file mode 100644
index 00000000000..52d0de686f6
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/sh7367.h
@@ -0,0 +1,332 @@
+#ifndef __ASM_SH7367_H__
+#define __ASM_SH7367_H__
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* 49-1 -> 49-6 (GPIO) */
+ GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+ GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+ GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+ GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+ GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+ GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+ GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+ GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+ GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+ GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+ GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+ GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+ GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+ GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+ GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+ GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+ GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+ GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+ GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+ GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+ GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+ GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+ GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+ GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
+
+ GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
+ GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
+
+ GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+ GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+ GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+ GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+ GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+ GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+ GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+ GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
+
+ GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
+ GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
+
+ GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
+ GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
+
+ GPIO_PORT190, GPIO_PORT191, GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
+ GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
+
+ GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
+ GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
+
+ GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
+ GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
+
+ GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
+ GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
+
+ GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
+ GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
+
+ GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
+ GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
+
+ GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
+ GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
+
+ GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
+ GPIO_PORT265, GPIO_PORT266, GPIO_PORT267, GPIO_PORT268, GPIO_PORT269,
+
+ GPIO_PORT270, GPIO_PORT271, GPIO_PORT272,
+
+ /* Special Pull-up / Pull-down Functions */
+ GPIO_FN_PORT48_KEYIN0_PU, GPIO_FN_PORT49_KEYIN1_PU,
+ GPIO_FN_PORT50_KEYIN2_PU, GPIO_FN_PORT55_KEYIN3_PU,
+ GPIO_FN_PORT56_KEYIN4_PU, GPIO_FN_PORT57_KEYIN5_PU,
+ GPIO_FN_PORT58_KEYIN6_PU,
+
+ /* 49-1 (FN) */
+ GPIO_FN_VBUS0, GPIO_FN_CPORT0, GPIO_FN_CPORT1, GPIO_FN_CPORT2,
+ GPIO_FN_CPORT3, GPIO_FN_CPORT4, GPIO_FN_CPORT5, GPIO_FN_CPORT6,
+ GPIO_FN_CPORT7, GPIO_FN_CPORT8, GPIO_FN_CPORT9, GPIO_FN_CPORT10,
+ GPIO_FN_CPORT11, GPIO_FN_SIN2, GPIO_FN_CPORT12, GPIO_FN_XCTS2,
+ GPIO_FN_CPORT13, GPIO_FN_RFSPO4, GPIO_FN_CPORT14, GPIO_FN_RFSPO5,
+ GPIO_FN_CPORT15, GPIO_FN_CPORT16, GPIO_FN_CPORT17, GPIO_FN_SOUT2,
+ GPIO_FN_CPORT18, GPIO_FN_XRTS2, GPIO_FN_CPORT19, GPIO_FN_CPORT20,
+ GPIO_FN_RFSPO6, GPIO_FN_CPORT21, GPIO_FN_STATUS0, GPIO_FN_CPORT22,
+ GPIO_FN_STATUS1, GPIO_FN_CPORT23, GPIO_FN_STATUS2, GPIO_FN_RFSPO7,
+ GPIO_FN_MPORT0, GPIO_FN_MPORT1, GPIO_FN_B_SYNLD1, GPIO_FN_B_SYNLD2,
+ GPIO_FN_XMAINPS, GPIO_FN_XDIVPS, GPIO_FN_XIDRST, GPIO_FN_IDCLK,
+ GPIO_FN_IDIO, GPIO_FN_SOUT1, GPIO_FN_SCIFA4_TXD,
+ GPIO_FN_M02_BERDAT, GPIO_FN_SIN1, GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
+ GPIO_FN_XRTS1, GPIO_FN_SCIFA4_RTS, GPIO_FN_M03_BERCLK,
+ GPIO_FN_XCTS1, GPIO_FN_SCIFA4_CTS,
+
+ /* 49-2 (FN) */
+ GPIO_FN_HSU_IQ_AGC6, GPIO_FN_MFG2_IN2, GPIO_FN_MSIOF2_MCK0,
+ GPIO_FN_HSU_IQ_AGC5, GPIO_FN_MFG2_IN1, GPIO_FN_MSIOF2_MCK1,
+ GPIO_FN_HSU_IQ_AGC4, GPIO_FN_MSIOF2_RSYNC,
+ GPIO_FN_HSU_IQ_AGC3, GPIO_FN_MFG2_OUT1, GPIO_FN_MSIOF2_RSCK,
+ GPIO_FN_HSU_IQ_AGC2, GPIO_FN_PORT42_KEYOUT0,
+ GPIO_FN_HSU_IQ_AGC1, GPIO_FN_PORT43_KEYOUT1,
+ GPIO_FN_HSU_IQ_AGC0, GPIO_FN_PORT44_KEYOUT2,
+ GPIO_FN_HSU_IQ_AGC_ST, GPIO_FN_PORT45_KEYOUT3,
+ GPIO_FN_HSU_IQ_PDO, GPIO_FN_PORT46_KEYOUT4,
+ GPIO_FN_HSU_IQ_PYO, GPIO_FN_PORT47_KEYOUT5,
+ GPIO_FN_HSU_EN_TXMUX_G3MO, GPIO_FN_PORT48_KEYIN0,
+ GPIO_FN_HSU_I_TXMUX_G3MO, GPIO_FN_PORT49_KEYIN1,
+ GPIO_FN_HSU_Q_TXMUX_G3MO, GPIO_FN_PORT50_KEYIN2,
+ GPIO_FN_HSU_SYO, GPIO_FN_PORT51_MSIOF2_TSYNC,
+ GPIO_FN_HSU_SDO, GPIO_FN_PORT52_MSIOF2_TSCK,
+ GPIO_FN_HSU_TGTTI_G3MO, GPIO_FN_PORT53_MSIOF2_TXD,
+ GPIO_FN_B_TIME_STAMP, GPIO_FN_PORT54_MSIOF2_RXD,
+ GPIO_FN_HSU_SDI, GPIO_FN_PORT55_KEYIN3,
+ GPIO_FN_HSU_SCO, GPIO_FN_PORT56_KEYIN4,
+ GPIO_FN_HSU_DREQ, GPIO_FN_PORT57_KEYIN5,
+ GPIO_FN_HSU_DACK, GPIO_FN_PORT58_KEYIN6,
+ GPIO_FN_HSU_CLK61M, GPIO_FN_PORT59_MSIOF2_SS1,
+ GPIO_FN_HSU_XRST, GPIO_FN_PORT60_MSIOF2_SS2,
+ GPIO_FN_PCMCLKO, GPIO_FN_SYNC8KO, GPIO_FN_DNPCM_A, GPIO_FN_UPPCM_A,
+ GPIO_FN_XTALB1L,
+ GPIO_FN_GPS_AGC1, GPIO_FN_SCIFA0_RTS,
+ GPIO_FN_GPS_AGC2, GPIO_FN_SCIFA0_SCK,
+ GPIO_FN_GPS_AGC3, GPIO_FN_SCIFA0_TXD,
+ GPIO_FN_GPS_AGC4, GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_GPS_PWRD, GPIO_FN_SCIFA0_CTS,
+ GPIO_FN_GPS_IM, GPIO_FN_GPS_IS, GPIO_FN_GPS_QM, GPIO_FN_GPS_QS,
+ GPIO_FN_SIUBOMC, GPIO_FN_TPU2TO0,
+ GPIO_FN_SIUCKB, GPIO_FN_TPU2TO1,
+ GPIO_FN_SIUBOLR, GPIO_FN_BBIF2_TSYNC, GPIO_FN_TPU2TO2,
+ GPIO_FN_SIUBOBT, GPIO_FN_BBIF2_TSCK, GPIO_FN_TPU2TO3,
+ GPIO_FN_SIUBOSLD, GPIO_FN_BBIF2_TXD, GPIO_FN_TPU3TO0,
+ GPIO_FN_SIUBILR, GPIO_FN_TPU3TO1,
+ GPIO_FN_SIUBIBT, GPIO_FN_TPU3TO2,
+ GPIO_FN_SIUBISLD, GPIO_FN_TPU3TO3,
+ GPIO_FN_NMI, GPIO_FN_TPU4TO0,
+ GPIO_FN_DNPCM_M, GPIO_FN_TPU4TO1, GPIO_FN_TPU4TO2, GPIO_FN_TPU4TO3,
+ GPIO_FN_IRQ_TMPB,
+ GPIO_FN_PWEN, GPIO_FN_MFG1_OUT1,
+ GPIO_FN_OVCN, GPIO_FN_MFG1_IN1,
+ GPIO_FN_OVCN2, GPIO_FN_MFG1_IN2,
+
+ /* 49-3 (FN) */
+ GPIO_FN_RFSPO1, GPIO_FN_RFSPO2, GPIO_FN_RFSPO3, GPIO_FN_PORT93_VIO_CKO2,
+ GPIO_FN_USBTERM, GPIO_FN_EXTLP, GPIO_FN_IDIN,
+ GPIO_FN_SCIFA5_CTS, GPIO_FN_MFG0_IN1,
+ GPIO_FN_SCIFA5_RTS, GPIO_FN_MFG0_IN2,
+ GPIO_FN_SCIFA5_RXD,
+ GPIO_FN_SCIFA5_TXD,
+ GPIO_FN_SCIFA5_SCK, GPIO_FN_MFG0_OUT1,
+ GPIO_FN_A0_EA0, GPIO_FN_BS,
+ GPIO_FN_A14_EA14, GPIO_FN_PORT102_KEYOUT0,
+ GPIO_FN_A15_EA15, GPIO_FN_PORT103_KEYOUT1, GPIO_FN_DV_CLKOL,
+ GPIO_FN_A16_EA16, GPIO_FN_PORT104_KEYOUT2,
+ GPIO_FN_DV_VSYNCL, GPIO_FN_MSIOF0_SS1,
+ GPIO_FN_A17_EA17, GPIO_FN_PORT105_KEYOUT3,
+ GPIO_FN_DV_HSYNCL, GPIO_FN_MSIOF0_TSYNC,
+ GPIO_FN_A18_EA18, GPIO_FN_PORT106_KEYOUT4,
+ GPIO_FN_DV_DL0, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_A19_EA19, GPIO_FN_PORT107_KEYOUT5,
+ GPIO_FN_DV_DL1, GPIO_FN_MSIOF0_TXD,
+ GPIO_FN_A20_EA20, GPIO_FN_PORT108_KEYIN0,
+ GPIO_FN_DV_DL2, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_A21_EA21, GPIO_FN_PORT109_KEYIN1,
+ GPIO_FN_DV_DL3, GPIO_FN_MSIOF0_RSYNC,
+ GPIO_FN_A22_EA22, GPIO_FN_PORT110_KEYIN2,
+ GPIO_FN_DV_DL4, GPIO_FN_MSIOF0_MCK0,
+ GPIO_FN_A23_EA23, GPIO_FN_PORT111_KEYIN3,
+ GPIO_FN_DV_DL5, GPIO_FN_MSIOF0_MCK1,
+ GPIO_FN_A24_EA24, GPIO_FN_PORT112_KEYIN4,
+ GPIO_FN_DV_DL6, GPIO_FN_MSIOF0_RXD,
+ GPIO_FN_A25_EA25, GPIO_FN_PORT113_KEYIN5,
+ GPIO_FN_DV_DL7, GPIO_FN_MSIOF0_SS2,
+ GPIO_FN_A26, GPIO_FN_PORT113_KEYIN6, GPIO_FN_DV_CLKIL,
+ GPIO_FN_D0_ED0_NAF0, GPIO_FN_D1_ED1_NAF1, GPIO_FN_D2_ED2_NAF2,
+ GPIO_FN_D3_ED3_NAF3, GPIO_FN_D4_ED4_NAF4, GPIO_FN_D5_ED5_NAF5,
+ GPIO_FN_D6_ED6_NAF6, GPIO_FN_D7_ED7_NAF7, GPIO_FN_D8_ED8_NAF8,
+ GPIO_FN_D9_ED9_NAF9, GPIO_FN_D10_ED10_NAF10, GPIO_FN_D11_ED11_NAF11,
+ GPIO_FN_D12_ED12_NAF12, GPIO_FN_D13_ED13_NAF13,
+ GPIO_FN_D14_ED14_NAF14, GPIO_FN_D15_ED15_NAF15,
+ GPIO_FN_CS4, GPIO_FN_CS5A, GPIO_FN_CS5B, GPIO_FN_FCE1,
+ GPIO_FN_CS6B, GPIO_FN_XCS2, GPIO_FN_FCE0, GPIO_FN_CS6A,
+ GPIO_FN_DACK0, GPIO_FN_WAIT, GPIO_FN_DREQ0, GPIO_FN_RD_XRD,
+ GPIO_FN_A27, GPIO_FN_RDWR_XWE, GPIO_FN_WE0_XWR0_FWE,
+ GPIO_FN_WE1_XWR1, GPIO_FN_FRB, GPIO_FN_CKO,
+ GPIO_FN_NBRSTOUT, GPIO_FN_NBRST,
+
+ /* 49-4 (FN) */
+ GPIO_FN_RFSPO0, GPIO_FN_PORT146_VIO_CKO2, GPIO_FN_TSTMD,
+ GPIO_FN_VIO_VD, GPIO_FN_VIO_HD,
+ GPIO_FN_VIO_D0, GPIO_FN_VIO_D1, GPIO_FN_VIO_D2,
+ GPIO_FN_VIO_D3, GPIO_FN_VIO_D4, GPIO_FN_VIO_D5,
+ GPIO_FN_VIO_D6, GPIO_FN_VIO_D7, GPIO_FN_VIO_D8,
+ GPIO_FN_VIO_D9, GPIO_FN_VIO_D10, GPIO_FN_VIO_D11,
+ GPIO_FN_VIO_D12, GPIO_FN_VIO_D13, GPIO_FN_VIO_D14,
+ GPIO_FN_VIO_D15, GPIO_FN_VIO_CLK, GPIO_FN_VIO_FIELD,
+ GPIO_FN_VIO_CKO,
+ GPIO_FN_MFG3_IN1, GPIO_FN_MFG3_IN2,
+ GPIO_FN_M9_SLCD_A01, GPIO_FN_MFG3_OUT1, GPIO_FN_TPU0TO0,
+ GPIO_FN_M10_SLCD_CK1, GPIO_FN_MFG4_IN1, GPIO_FN_TPU0TO1,
+ GPIO_FN_M11_SLCD_SO1, GPIO_FN_MFG4_IN2, GPIO_FN_TPU0TO2,
+ GPIO_FN_M12_SLCD_CE1, GPIO_FN_MFG4_OUT1, GPIO_FN_TPU0TO3,
+ GPIO_FN_LCDD0, GPIO_FN_PORT175_KEYOUT0, GPIO_FN_DV_D0,
+ GPIO_FN_SIUCKA, GPIO_FN_MFG0_OUT2,
+ GPIO_FN_LCDD1, GPIO_FN_PORT176_KEYOUT1, GPIO_FN_DV_D1,
+ GPIO_FN_SIUAOLR, GPIO_FN_BBIF2_TSYNC1,
+ GPIO_FN_LCDD2, GPIO_FN_PORT177_KEYOUT2, GPIO_FN_DV_D2,
+ GPIO_FN_SIUAOBT, GPIO_FN_BBIF2_TSCK1,
+ GPIO_FN_LCDD3, GPIO_FN_PORT178_KEYOUT3, GPIO_FN_DV_D3,
+ GPIO_FN_SIUAOSLD, GPIO_FN_BBIF2_TXD1,
+ GPIO_FN_LCDD4, GPIO_FN_PORT179_KEYOUT4, GPIO_FN_DV_D4,
+ GPIO_FN_SIUAISPD, GPIO_FN_MFG1_OUT2,
+ GPIO_FN_LCDD5, GPIO_FN_PORT180_KEYOUT5, GPIO_FN_DV_D5,
+ GPIO_FN_SIUAILR, GPIO_FN_MFG2_OUT2,
+ GPIO_FN_LCDD6, GPIO_FN_DV_D6,
+ GPIO_FN_SIUAIBT, GPIO_FN_MFG3_OUT2, GPIO_FN_XWR2,
+ GPIO_FN_LCDD7, GPIO_FN_DV_D7,
+ GPIO_FN_SIUAISLD, GPIO_FN_MFG4_OUT2, GPIO_FN_XWR3,
+ GPIO_FN_LCDD8, GPIO_FN_DV_D8, GPIO_FN_D16, GPIO_FN_ED16,
+ GPIO_FN_LCDD9, GPIO_FN_DV_D9, GPIO_FN_D17, GPIO_FN_ED17,
+ GPIO_FN_LCDD10, GPIO_FN_DV_D10, GPIO_FN_D18, GPIO_FN_ED18,
+ GPIO_FN_LCDD11, GPIO_FN_DV_D11, GPIO_FN_D19, GPIO_FN_ED19,
+ GPIO_FN_LCDD12, GPIO_FN_DV_D12, GPIO_FN_D20, GPIO_FN_ED20,
+ GPIO_FN_LCDD13, GPIO_FN_DV_D13, GPIO_FN_D21, GPIO_FN_ED21,
+ GPIO_FN_LCDD14, GPIO_FN_DV_D14, GPIO_FN_D22, GPIO_FN_ED22,
+ GPIO_FN_LCDD15, GPIO_FN_DV_D15, GPIO_FN_D23, GPIO_FN_ED23,
+ GPIO_FN_LCDD16, GPIO_FN_DV_HSYNC, GPIO_FN_D24, GPIO_FN_ED24,
+ GPIO_FN_LCDD17, GPIO_FN_DV_VSYNC, GPIO_FN_D25, GPIO_FN_ED25,
+ GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_MSIOF0L_TSCK,
+ GPIO_FN_D26, GPIO_FN_ED26,
+ GPIO_FN_LCDD19, GPIO_FN_MSIOF0L_TSYNC,
+ GPIO_FN_D27, GPIO_FN_ED27,
+ GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0,
+ GPIO_FN_D28, GPIO_FN_ED28,
+ GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1,
+ GPIO_FN_D29, GPIO_FN_ED29,
+ GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_SS1,
+ GPIO_FN_D30, GPIO_FN_ED30,
+ GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_SS2,
+ GPIO_FN_D31, GPIO_FN_ED31,
+ GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_DV_CKO, GPIO_FN_SIUAOSPD,
+ GPIO_FN_LCDRD, GPIO_FN_DACK2, GPIO_FN_MSIOF0L_RSYNC,
+
+
+ /* 49-5 (FN) */
+ GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDCS2, GPIO_FN_DACK3,
+ GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_RSCK,
+ GPIO_FN_LCDCSYN, GPIO_FN_LCDCSYN2, GPIO_FN_DV_CKI,
+ GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_MSIOF0L_RXD,
+ GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_MSIOF0L_TXD,
+ GPIO_FN_VIO_DR0, GPIO_FN_VIO_DR1, GPIO_FN_VIO_DR2, GPIO_FN_VIO_DR3,
+ GPIO_FN_VIO_DR4, GPIO_FN_VIO_DR5, GPIO_FN_VIO_DR6, GPIO_FN_VIO_DR7,
+ GPIO_FN_VIO_VDR, GPIO_FN_VIO_HDR,
+ GPIO_FN_VIO_CLKR, GPIO_FN_VIO_CKOR,
+ GPIO_FN_SCIFA1_TXD, GPIO_FN_GPS_PGFA0,
+ GPIO_FN_SCIFA1_SCK, GPIO_FN_GPS_PGFA1,
+ GPIO_FN_SCIFA1_RTS, GPIO_FN_GPS_EPPSINMON,
+ GPIO_FN_SCIFA1_RXD, GPIO_FN_SCIFA1_CTS,
+ GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA1_TXD2, GPIO_FN_GPS_TXD,
+ GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA1_CTS2, GPIO_FN_I2C_SDA2,
+ GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA1_SCK2,
+ GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA1_RXD2, GPIO_FN_GPS_RXD,
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA1_RTS2,
+ GPIO_FN_MSIOF1_RSYNC, GPIO_FN_I2C_SCL2,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1,
+ GPIO_FN_MSIOF1_SS1, GPIO_FN_EDBGREQ3,
+ GPIO_FN_MSIOF1_SS2,
+ GPIO_FN_PORT236_IROUT, GPIO_FN_IRDA_OUT,
+ GPIO_FN_IRDA_IN, GPIO_FN_IRDA_FIRSEL,
+ GPIO_FN_TPU1TO0, GPIO_FN_TS_SPSYNC3,
+ GPIO_FN_TPU1TO1, GPIO_FN_TS_SDAT3,
+ GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT241_MSIOF2_SS1,
+ GPIO_FN_TPU1TO3, GPIO_FN_PORT242_MSIOF2_TSCK,
+ GPIO_FN_M13_BSW, GPIO_FN_PORT243_MSIOF2_TSYNC,
+ GPIO_FN_M14_GSW, GPIO_FN_PORT244_MSIOF2_TXD,
+ GPIO_FN_PORT245_IROUT, GPIO_FN_M15_RSW,
+ GPIO_FN_SOUT3, GPIO_FN_SCIFA2_TXD1,
+ GPIO_FN_SIN3, GPIO_FN_SCIFA2_RXD1,
+ GPIO_FN_XRTS3, GPIO_FN_SCIFA2_RTS1, GPIO_FN_PORT248_MSIOF2_SS2,
+ GPIO_FN_XCTS3, GPIO_FN_SCIFA2_CTS1, GPIO_FN_PORT249_MSIOF2_RXD,
+ GPIO_FN_DINT, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
+ GPIO_FN_SDHICLK0, GPIO_FN_TCK2,
+ GPIO_FN_SDHICD0,
+ GPIO_FN_SDHID0_0, GPIO_FN_TMS2,
+ GPIO_FN_SDHID0_1, GPIO_FN_TDO2,
+ GPIO_FN_SDHID0_2, GPIO_FN_TDI2,
+ GPIO_FN_SDHID0_3, GPIO_FN_RTCK2,
+
+ /* 49-6 (FN) */
+ GPIO_FN_SDHICMD0, GPIO_FN_TRST2,
+ GPIO_FN_SDHIWP0, GPIO_FN_EDBGREQ2,
+ GPIO_FN_SDHICLK1, GPIO_FN_TCK3,
+ GPIO_FN_SDHID1_0, GPIO_FN_M11_SLCD_SO2,
+ GPIO_FN_TS_SPSYNC2, GPIO_FN_TMS3,
+ GPIO_FN_SDHID1_1, GPIO_FN_M9_SLCD_AO2,
+ GPIO_FN_TS_SDAT2, GPIO_FN_TDO3,
+ GPIO_FN_SDHID1_2, GPIO_FN_M10_SLCD_CK2,
+ GPIO_FN_TS_SDEN2, GPIO_FN_TDI3,
+ GPIO_FN_SDHID1_3, GPIO_FN_M12_SLCD_CE2,
+ GPIO_FN_TS_SCK2, GPIO_FN_RTCK3,
+ GPIO_FN_SDHICMD1, GPIO_FN_TRST3,
+ GPIO_FN_SDHICLK2, GPIO_FN_SCIFB_SCK,
+ GPIO_FN_SDHID2_0, GPIO_FN_SCIFB_TXD,
+ GPIO_FN_SDHID2_1, GPIO_FN_SCIFB_CTS,
+ GPIO_FN_SDHID2_2, GPIO_FN_SCIFB_RXD,
+ GPIO_FN_SDHID2_3, GPIO_FN_SCIFB_RTS,
+ GPIO_FN_SDHICMD2,
+ GPIO_FN_RESETOUTS,
+ GPIO_FN_DIVLOCK,
+};
+
+#endif /* __ASM_SH7367_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
new file mode 100644
index 00000000000..dc34f00c56b
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.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.
+ */
+
+#ifndef __ASM_SH7372_H__
+#define __ASM_SH7372_H__
+
+/*
+ * Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* PORT */
+ GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+ GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+ GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+ GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+ GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+ GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+ GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+ GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+ GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+ GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+ GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+ GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+ GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+ GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+ GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+ GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+ GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+ GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+ GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+ GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+ GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+ GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+ GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+ GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
+
+ GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
+ GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
+
+ GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+ GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+ GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+ GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+ GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+ GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+ GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+ GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
+
+ GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
+ GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
+
+ GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
+ GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
+
+ GPIO_PORT190,
+
+ /* IRQ */
+ GPIO_FN_IRQ0_6, /* PORT 6 */
+ GPIO_FN_IRQ0_162, /* PORT 162 */
+ GPIO_FN_IRQ1, /* PORT 12 */
+ GPIO_FN_IRQ2_4, /* PORT 4 */
+ GPIO_FN_IRQ2_5, /* PORT 5 */
+ GPIO_FN_IRQ3_8, /* PORT 8 */
+ GPIO_FN_IRQ3_16, /* PORT 16 */
+ GPIO_FN_IRQ4_17, /* PORT 17 */
+ GPIO_FN_IRQ4_163, /* PORT 163 */
+ GPIO_FN_IRQ5, /* PORT 18 */
+ GPIO_FN_IRQ6_39, /* PORT 39 */
+ GPIO_FN_IRQ6_164, /* PORT 164 */
+ GPIO_FN_IRQ7_40, /* PORT 40 */
+ GPIO_FN_IRQ7_167, /* PORT 167 */
+ GPIO_FN_IRQ8_41, /* PORT 41 */
+ GPIO_FN_IRQ8_168, /* PORT 168 */
+ GPIO_FN_IRQ9_42, /* PORT 42 */
+ GPIO_FN_IRQ9_169, /* PORT 169 */
+ GPIO_FN_IRQ10, /* PORT 65 */
+ GPIO_FN_IRQ11, /* PORT 67 */
+ GPIO_FN_IRQ12_80, /* PORT 80 */
+ GPIO_FN_IRQ12_137, /* PORT 137 */
+ GPIO_FN_IRQ13_81, /* PORT 81 */
+ GPIO_FN_IRQ13_145, /* PORT 145 */
+ GPIO_FN_IRQ14_82, /* PORT 82 */
+ GPIO_FN_IRQ14_146, /* PORT 146 */
+ GPIO_FN_IRQ15_83, /* PORT 83 */
+ GPIO_FN_IRQ15_147, /* PORT 147 */
+ GPIO_FN_IRQ16_84, /* PORT 84 */
+ GPIO_FN_IRQ16_170, /* PORT 170 */
+ GPIO_FN_IRQ17, /* PORT 85 */
+ GPIO_FN_IRQ18, /* PORT 86 */
+ GPIO_FN_IRQ19, /* PORT 87 */
+ GPIO_FN_IRQ20, /* PORT 92 */
+ GPIO_FN_IRQ21, /* PORT 93 */
+ GPIO_FN_IRQ22, /* PORT 94 */
+ GPIO_FN_IRQ23, /* PORT 95 */
+ GPIO_FN_IRQ24, /* PORT 112 */
+ GPIO_FN_IRQ25, /* PORT 119 */
+ GPIO_FN_IRQ26_121, /* PORT 121 */
+ GPIO_FN_IRQ26_172, /* PORT 172 */
+ GPIO_FN_IRQ27_122, /* PORT 122 */
+ GPIO_FN_IRQ27_180, /* PORT 180 */
+ GPIO_FN_IRQ28_123, /* PORT 123 */
+ GPIO_FN_IRQ28_181, /* PORT 181 */
+ GPIO_FN_IRQ29_129, /* PORT 129 */
+ GPIO_FN_IRQ29_182, /* PORT 182 */
+ GPIO_FN_IRQ30_130, /* PORT 130 */
+ GPIO_FN_IRQ30_183, /* PORT 183 */
+ GPIO_FN_IRQ31_138, /* PORT 138 */
+ GPIO_FN_IRQ31_184, /* PORT 184 */
+
+ /*
+ * MSIOF0 (PORT 36, 37, 38, 39
+ * 40, 41, 42, 43, 44, 45)
+ */
+ GPIO_FN_MSIOF0_TSYNC, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_MSIOF0_RXD, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_MSIOF0_RSYNC, GPIO_FN_MSIOF0_MCK0,
+ GPIO_FN_MSIOF0_MCK1, GPIO_FN_MSIOF0_SS1,
+ GPIO_FN_MSIOF0_SS2, GPIO_FN_MSIOF0_TXD,
+
+ /*
+ * MSIOF1 (PORT 39, 40, 41, 42, 43, 44
+ * 84, 85, 86, 87, 88, 89, 90, 91, 92, 93)
+ */
+ GPIO_FN_MSIOF1_TSCK_39, GPIO_FN_MSIOF1_TSYNC_40,
+ GPIO_FN_MSIOF1_TSCK_88, GPIO_FN_MSIOF1_TSYNC_89,
+ GPIO_FN_MSIOF1_TXD_41, GPIO_FN_MSIOF1_RXD_42,
+ GPIO_FN_MSIOF1_TXD_90, GPIO_FN_MSIOF1_RXD_91,
+ GPIO_FN_MSIOF1_SS1_43, GPIO_FN_MSIOF1_SS2_44,
+ GPIO_FN_MSIOF1_SS1_92, GPIO_FN_MSIOF1_SS2_93,
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_MSIOF1_RSYNC,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1,
+
+ /*
+ * MSIOF2 (PORT 134, 135, 136, 137, 138, 139
+ * 148, 149, 150, 151)
+ */
+ GPIO_FN_MSIOF2_RSCK, GPIO_FN_MSIOF2_RSYNC,
+ GPIO_FN_MSIOF2_MCK0, GPIO_FN_MSIOF2_MCK1,
+ GPIO_FN_MSIOF2_SS1, GPIO_FN_MSIOF2_SS2,
+ GPIO_FN_MSIOF2_TSYNC, GPIO_FN_MSIOF2_TSCK,
+ GPIO_FN_MSIOF2_RXD, GPIO_FN_MSIOF2_TXD,
+
+ /* MSIOF3 (PORT 76, 77, 78, 79, 80, 81, 82, 83) */
+ GPIO_FN_BBIF1_RXD, GPIO_FN_BBIF1_TSYNC,
+ GPIO_FN_BBIF1_TSCK, GPIO_FN_BBIF1_TXD,
+ GPIO_FN_BBIF1_RSCK, GPIO_FN_BBIF1_RSYNC,
+ GPIO_FN_BBIF1_FLOW, GPIO_FN_BB_RX_FLOW_N,
+
+ /* MSIOF4 (PORT 0, 1, 2, 3) */
+ GPIO_FN_BBIF2_TSCK1, GPIO_FN_BBIF2_TSYNC1,
+ GPIO_FN_BBIF2_TXD1, GPIO_FN_BBIF2_RXD,
+
+ /* FSI (PORT 4, 5, 6, 7, 8, 9, 10, 11, 15) */
+ GPIO_FN_FSIACK, GPIO_FN_FSIBCK,
+ GPIO_FN_FSIAILR, GPIO_FN_FSIAIBT,
+ GPIO_FN_FSIAISLD, GPIO_FN_FSIAOMC,
+ GPIO_FN_FSIAOLR, GPIO_FN_FSIAOBT,
+ GPIO_FN_FSIAOSLD, GPIO_FN_FSIASPDIF_11,
+ GPIO_FN_FSIASPDIF_15,
+
+ /* FMSI (PORT 12, 13, 14, 15, 16, 17, 18, 65) */
+ GPIO_FN_FMSOCK, GPIO_FN_FMSOOLR,
+ GPIO_FN_FMSIOLR, GPIO_FN_FMSOOBT,
+ GPIO_FN_FMSIOBT, GPIO_FN_FMSOSLD,
+ GPIO_FN_FMSOILR, GPIO_FN_FMSIILR,
+ GPIO_FN_FMSOIBT, GPIO_FN_FMSIIBT,
+ GPIO_FN_FMSISLD, GPIO_FN_FMSICK,
+
+ /* SCIFA0 (PORT 152, 153, 156, 157, 158) */
+ GPIO_FN_SCIFA0_TXD, GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_SCIFA0_SCK, GPIO_FN_SCIFA0_RTS,
+ GPIO_FN_SCIFA0_CTS,
+
+ /* SCIFA1 (PORT 154, 155, 159, 160, 161) */
+ GPIO_FN_SCIFA1_TXD, GPIO_FN_SCIFA1_RXD,
+ GPIO_FN_SCIFA1_SCK, GPIO_FN_SCIFA1_RTS,
+ GPIO_FN_SCIFA1_CTS,
+
+ /* SCIFA2 (PORT 94, 95, 96, 97, 98) */
+ GPIO_FN_SCIFA2_CTS1, GPIO_FN_SCIFA2_RTS1,
+ GPIO_FN_SCIFA2_TXD1, GPIO_FN_SCIFA2_RXD1,
+ GPIO_FN_SCIFA2_SCK1,
+
+ /* SCIFA3 (PORT 43, 44,
+ 140, 141, 142, 143, 144) */
+ GPIO_FN_SCIFA3_CTS_43, GPIO_FN_SCIFA3_CTS_140,
+ GPIO_FN_SCIFA3_RTS_44, GPIO_FN_SCIFA3_RTS_141,
+ GPIO_FN_SCIFA3_SCK, GPIO_FN_SCIFA3_TXD,
+ GPIO_FN_SCIFA3_RXD,
+
+ /* SCIFA4 (PORT 5, 6) */
+ GPIO_FN_SCIFA4_RXD, GPIO_FN_SCIFA4_TXD,
+
+ /* SCIFA5 (PORT 8, 12) */
+ GPIO_FN_SCIFA5_RXD, GPIO_FN_SCIFA5_TXD,
+
+ /* SCIFB (PORT 162, 163, 164, 165, 166) */
+ GPIO_FN_SCIFB_SCK, GPIO_FN_SCIFB_RTS,
+ GPIO_FN_SCIFB_CTS, GPIO_FN_SCIFB_TXD,
+ GPIO_FN_SCIFB_RXD,
+
+ /*
+ * CEU (PORT 16, 17,
+ * 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ * 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ * 120)
+ */
+ GPIO_FN_VIO_HD, GPIO_FN_VIO_CKO1, GPIO_FN_VIO_CKO2,
+ GPIO_FN_VIO_VD, GPIO_FN_VIO_CLK, GPIO_FN_VIO_FIELD,
+ GPIO_FN_VIO_CKO,
+ GPIO_FN_VIO_D0, GPIO_FN_VIO_D1, GPIO_FN_VIO_D2,
+ GPIO_FN_VIO_D3, GPIO_FN_VIO_D4, GPIO_FN_VIO_D5,
+ GPIO_FN_VIO_D6, GPIO_FN_VIO_D7, GPIO_FN_VIO_D8,
+ GPIO_FN_VIO_D9, GPIO_FN_VIO_D10, GPIO_FN_VIO_D11,
+ GPIO_FN_VIO_D12, GPIO_FN_VIO_D13, GPIO_FN_VIO_D14,
+ GPIO_FN_VIO_D15,
+
+ /* USB0 (PORT 113, 114, 115, 116, 117, 167) */
+ GPIO_FN_IDIN_0, GPIO_FN_EXTLP_0,
+ GPIO_FN_OVCN2_0, GPIO_FN_PWEN_0,
+ GPIO_FN_OVCN_0, GPIO_FN_VBUS0_0,
+
+ /* USB1 (PORT 18, 113, 114, 115, 116, 117, 138, 162, 168) */
+ GPIO_FN_IDIN_1_18, GPIO_FN_IDIN_1_113,
+ GPIO_FN_PWEN_1_115, GPIO_FN_PWEN_1_138,
+ GPIO_FN_OVCN_1_114, GPIO_FN_OVCN_1_162,
+ GPIO_FN_EXTLP_1, GPIO_FN_OVCN2_1,
+ GPIO_FN_VBUS0_1,
+
+ /* GPIO (PORT 41, 42, 43, 44) */
+ GPIO_FN_GPI0, GPIO_FN_GPI1, GPIO_FN_GPO0, GPIO_FN_GPO1,
+
+ /*
+ * BSC (PORT 19,
+ * 20, 21, 22, 25, 26, 27, 28, 29,
+ * 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ * 40, 41, 42, 43, 44, 45,
+ * 62, 63, 64, 65, 66, 67,
+ * 71, 72, 74, 75)
+ */
+ GPIO_FN_BS, GPIO_FN_WE1,
+ GPIO_FN_CKO, GPIO_FN_WAIT, GPIO_FN_RDWR,
+
+ GPIO_FN_A0, GPIO_FN_A1, GPIO_FN_A2, GPIO_FN_A3,
+ GPIO_FN_A6, GPIO_FN_A7, GPIO_FN_A8, GPIO_FN_A9,
+ GPIO_FN_A10, GPIO_FN_A11, GPIO_FN_A12, GPIO_FN_A13,
+ GPIO_FN_A14, GPIO_FN_A15, GPIO_FN_A16, GPIO_FN_A17,
+ GPIO_FN_A18, GPIO_FN_A19, GPIO_FN_A20, GPIO_FN_A21,
+ GPIO_FN_A22, GPIO_FN_A23, GPIO_FN_A24, GPIO_FN_A25,
+ GPIO_FN_A26,
+
+ GPIO_FN_CS0, GPIO_FN_CS2, GPIO_FN_CS4,
+ GPIO_FN_CS5A, GPIO_FN_CS5B, GPIO_FN_CS6A,
+
+ /*
+ * BSC/FLCTL (PORT 23, 24,
+ * 46, 47, 48, 49,
+ * 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ * 60, 61, 69, 70)
+ */
+ GPIO_FN_RD_FSC, GPIO_FN_WE0_FWE,
+ GPIO_FN_A4_FOE, GPIO_FN_A5_FCDE,
+ GPIO_FN_D0_NAF0, GPIO_FN_D1_NAF1, GPIO_FN_D2_NAF2,
+ GPIO_FN_D3_NAF3, GPIO_FN_D4_NAF4, GPIO_FN_D5_NAF5,
+ GPIO_FN_D6_NAF6, GPIO_FN_D7_NAF7, GPIO_FN_D8_NAF8,
+ GPIO_FN_D9_NAF9, GPIO_FN_D10_NAF10, GPIO_FN_D11_NAF11,
+ GPIO_FN_D12_NAF12, GPIO_FN_D13_NAF13, GPIO_FN_D14_NAF14,
+ GPIO_FN_D15_NAF15,
+
+ /*
+ * MMCIF(1) (PORT 84, 85, 86, 87, 88, 89,
+ * 90, 91, 92, 99)
+ */
+ GPIO_FN_MMCD0_0, GPIO_FN_MMCD0_1, GPIO_FN_MMCD0_2,
+ GPIO_FN_MMCD0_3, GPIO_FN_MMCD0_4, GPIO_FN_MMCD0_5,
+ GPIO_FN_MMCD0_6, GPIO_FN_MMCD0_7,
+ GPIO_FN_MMCCMD0, GPIO_FN_MMCCLK0,
+
+ /* MMCIF(2) (PORT 54, 55, 56, 57, 58, 59, 60, 61, 66, 67) */
+ GPIO_FN_MMCD1_0, GPIO_FN_MMCD1_1, GPIO_FN_MMCD1_2,
+ GPIO_FN_MMCD1_3, GPIO_FN_MMCD1_4, GPIO_FN_MMCD1_5,
+ GPIO_FN_MMCD1_6, GPIO_FN_MMCD1_7,
+ GPIO_FN_MMCCLK1, GPIO_FN_MMCCMD1,
+
+ /* SPU2 (PORT 65) */
+ GPIO_FN_VINT_I,
+
+ /* FLCTL (PORT 66, 68, 73) */
+ GPIO_FN_FCE1, GPIO_FN_FCE0, GPIO_FN_FRB,
+
+ /* HSI (PORT 76, 77, 78, 79, 80, 81, 82, 83) */
+ GPIO_FN_GP_RX_FLAG, GPIO_FN_GP_RX_DATA, GPIO_FN_GP_TX_READY,
+ GPIO_FN_GP_RX_WAKE, GPIO_FN_MP_TX_FLAG, GPIO_FN_MP_TX_DATA,
+ GPIO_FN_MP_RX_READY, GPIO_FN_MP_TX_WAKE,
+
+ /*
+ * MFI (PORT 76, 77, 78, 79,
+ * 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ * 90, 91, 92, 93, 94, 95, 96, 97, 98, 99)
+ */
+ GPIO_FN_MFIv6, /* see MSEL4CR 6 */
+ GPIO_FN_MFIv4, /* see MSEL4CR 6 */
+
+ GPIO_FN_MEMC_CS0, GPIO_FN_MEMC_BUSCLK_MEMC_A0,
+ GPIO_FN_MEMC_CS1_MEMC_A1, GPIO_FN_MEMC_ADV_MEMC_DREQ0,
+ GPIO_FN_MEMC_WAIT_MEMC_DREQ1, GPIO_FN_MEMC_NOE,
+ GPIO_FN_MEMC_NWE, GPIO_FN_MEMC_INT,
+
+ GPIO_FN_MEMC_AD0, GPIO_FN_MEMC_AD1, GPIO_FN_MEMC_AD2,
+ GPIO_FN_MEMC_AD3, GPIO_FN_MEMC_AD4, GPIO_FN_MEMC_AD5,
+ GPIO_FN_MEMC_AD6, GPIO_FN_MEMC_AD7, GPIO_FN_MEMC_AD8,
+ GPIO_FN_MEMC_AD9, GPIO_FN_MEMC_AD10, GPIO_FN_MEMC_AD11,
+ GPIO_FN_MEMC_AD12, GPIO_FN_MEMC_AD13, GPIO_FN_MEMC_AD14,
+ GPIO_FN_MEMC_AD15,
+
+ /* SIM (PORT 94, 95, 98) */
+ GPIO_FN_SIM_RST, GPIO_FN_SIM_CLK, GPIO_FN_SIM_D,
+
+ /* TPU (PORT 93, 99, 112, 160, 161) */
+ GPIO_FN_TPU0TO0, GPIO_FN_TPU0TO1,
+ GPIO_FN_TPU0TO2_93, GPIO_FN_TPU0TO2_99,
+ GPIO_FN_TPU0TO3,
+
+ /* I2C2 (PORT 110, 111) */
+ GPIO_FN_I2C_SCL2, GPIO_FN_I2C_SDA2,
+
+ /* I2C3(1) (PORT 114, 115) */
+ GPIO_FN_I2C_SCL3, GPIO_FN_I2C_SDA3,
+
+ /* I2C3(2) (PORT 137, 145) */
+ GPIO_FN_I2C_SCL3S, GPIO_FN_I2C_SDA3S,
+
+ /* I2C4(2) (PORT 116, 117) */
+ GPIO_FN_I2C_SCL4, GPIO_FN_I2C_SDA4,
+
+ /* I2C4(2) (PORT 146, 147) */
+ GPIO_FN_I2C_SCL4S, GPIO_FN_I2C_SDA4S,
+
+ /*
+ * KEYSC (PORT 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ * 130, 131, 132, 133, 134, 135, 136)
+ */
+ GPIO_FN_KEYOUT0, GPIO_FN_KEYIN0_121, GPIO_FN_KEYIN0_136,
+ GPIO_FN_KEYOUT1, GPIO_FN_KEYIN1_122, GPIO_FN_KEYIN1_135,
+ GPIO_FN_KEYOUT2, GPIO_FN_KEYIN2_123, GPIO_FN_KEYIN2_134,
+ GPIO_FN_KEYOUT3, GPIO_FN_KEYIN3_124, GPIO_FN_KEYIN3_133,
+ GPIO_FN_KEYOUT4, GPIO_FN_KEYIN4,
+ GPIO_FN_KEYOUT5, GPIO_FN_KEYIN5,
+ GPIO_FN_KEYOUT6, GPIO_FN_KEYIN6,
+ GPIO_FN_KEYOUT7, GPIO_FN_KEYIN7,
+
+ /*
+ * LCDC (PORT 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ * 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+ * 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ * 150, 151)
+ */
+ GPIO_FN_LCDC0_SELECT, /* LCDC 0 */
+ GPIO_FN_LCDC1_SELECT, /* LCDC 1 */
+ GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDVSYN,
+ GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_LCDRD,
+ GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_LCDLCLK,
+ GPIO_FN_LCDDON,
+
+ GPIO_FN_LCDD0, GPIO_FN_LCDD1, GPIO_FN_LCDD2, GPIO_FN_LCDD3,
+ GPIO_FN_LCDD4, GPIO_FN_LCDD5, GPIO_FN_LCDD6, GPIO_FN_LCDD7,
+ GPIO_FN_LCDD8, GPIO_FN_LCDD9, GPIO_FN_LCDD10, GPIO_FN_LCDD11,
+ GPIO_FN_LCDD12, GPIO_FN_LCDD13, GPIO_FN_LCDD14, GPIO_FN_LCDD15,
+ GPIO_FN_LCDD16, GPIO_FN_LCDD17, GPIO_FN_LCDD18, GPIO_FN_LCDD19,
+ GPIO_FN_LCDD20, GPIO_FN_LCDD21, GPIO_FN_LCDD22, GPIO_FN_LCDD23,
+
+ /* IRDA (PORT 139, 140, 141, 142) */
+ GPIO_FN_IRDA_OUT, GPIO_FN_IRDA_IN, GPIO_FN_IRDA_FIRSEL,
+ GPIO_FN_IROUT_139, GPIO_FN_IROUT_140,
+
+ /* TSIF1 (PORT 156, 157, 158, 159) */
+ GPIO_FN_TS0_1SELECT, /* TSIF0 - 1 select */
+ GPIO_FN_TS0_2SELECT, /* TSIF0 - 2 select */
+ GPIO_FN_TS1_1SELECT, /* TSIF1 - 1 select */
+ GPIO_FN_TS1_2SELECT, /* TSIF1 - 2 select */
+
+ GPIO_FN_TS_SPSYNC1, GPIO_FN_TS_SDAT1,
+ GPIO_FN_TS_SDEN1, GPIO_FN_TS_SCK1,
+
+ /* TSIF2 (PORT 137, 145, 146, 147) */
+ GPIO_FN_TS_SPSYNC2, GPIO_FN_TS_SDAT2,
+ GPIO_FN_TS_SDEN2, GPIO_FN_TS_SCK2,
+
+ /* HDMI (PORT 169, 170) */
+ GPIO_FN_HDMI_HPD, GPIO_FN_HDMI_CEC,
+
+ /* SDHI0 (PORT 171, 172, 173, 174, 175, 176, 177, 178) */
+ GPIO_FN_SDHICLK0, GPIO_FN_SDHICD0,
+ GPIO_FN_SDHICMD0, GPIO_FN_SDHIWP0,
+ GPIO_FN_SDHID0_0, GPIO_FN_SDHID0_1,
+ GPIO_FN_SDHID0_2, GPIO_FN_SDHID0_3,
+
+ /* SDHI1 (PORT 179, 180, 181, 182, 183, 184) */
+ GPIO_FN_SDHICLK1, GPIO_FN_SDHICMD1, GPIO_FN_SDHID1_0,
+ GPIO_FN_SDHID1_1, GPIO_FN_SDHID1_2, GPIO_FN_SDHID1_3,
+
+ /* SDHI2 (PORT 185, 186, 187, 188, 189, 190) */
+ GPIO_FN_SDHICLK2, GPIO_FN_SDHICMD2, GPIO_FN_SDHID2_0,
+ GPIO_FN_SDHID2_1, GPIO_FN_SDHID2_2, GPIO_FN_SDHID2_3,
+
+ /* SDENC see MSEL4CR 19 */
+ GPIO_FN_SDENC_CPG,
+ GPIO_FN_SDENC_DV_CLKI,
+};
+
+#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7377.h b/arch/arm/mach-shmobile/include/mach/sh7377.h
new file mode 100644
index 00000000000..f580e227dd1
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/sh7377.h
@@ -0,0 +1,360 @@
+#ifndef __ASM_SH7377_H__
+#define __ASM_SH7377_H__
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* 55-1 -> 55-5 (GPIO) */
+ GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+ GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+ GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+ GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+ GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+ GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+ GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+ GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+ GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+ GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+ GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+ GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+ GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+ GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+ GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+ GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+ GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+ GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+ GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+ GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+ GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+ GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+ GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+ GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118,
+
+ GPIO_PORT128, GPIO_PORT129,
+
+ GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+ GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+ GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+ GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+ GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+ GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+ GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+
+ GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
+ GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
+
+ GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
+ GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
+
+ GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
+ GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
+
+ GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
+ GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
+
+ GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
+ GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
+
+ GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
+ GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
+
+ GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
+ GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
+
+ GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
+
+ /* Special Pull-up / Pull-down Functions */
+ GPIO_FN_PORT66_KEYIN0_PU, GPIO_FN_PORT67_KEYIN1_PU,
+ GPIO_FN_PORT68_KEYIN2_PU, GPIO_FN_PORT69_KEYIN3_PU,
+ GPIO_FN_PORT70_KEYIN4_PU, GPIO_FN_PORT71_KEYIN5_PU,
+ GPIO_FN_PORT72_KEYIN6_PU,
+
+ /* 55-1 (FN) */
+ GPIO_FN_VBUS_0,
+ GPIO_FN_CPORT0,
+ GPIO_FN_CPORT1,
+ GPIO_FN_CPORT2,
+ GPIO_FN_CPORT3,
+ GPIO_FN_CPORT4,
+ GPIO_FN_CPORT5,
+ GPIO_FN_CPORT6,
+ GPIO_FN_CPORT7,
+ GPIO_FN_CPORT8,
+ GPIO_FN_CPORT9,
+ GPIO_FN_CPORT10,
+ GPIO_FN_CPORT11, GPIO_FN_SIN2,
+ GPIO_FN_CPORT12, GPIO_FN_XCTS2,
+ GPIO_FN_CPORT13, GPIO_FN_RFSPO4,
+ GPIO_FN_CPORT14, GPIO_FN_RFSPO5,
+ GPIO_FN_CPORT15, GPIO_FN_SCIFA0_SCK, GPIO_FN_GPS_AGC2,
+ GPIO_FN_CPORT16, GPIO_FN_SCIFA0_TXD, GPIO_FN_GPS_AGC3,
+ GPIO_FN_CPORT17_IC_OE, GPIO_FN_SOUT2,
+ GPIO_FN_CPORT18, GPIO_FN_XRTS2, GPIO_FN_PORT19_VIO_CKO2,
+ GPIO_FN_CPORT19_MPORT1,
+ GPIO_FN_CPORT20, GPIO_FN_RFSPO6,
+ GPIO_FN_CPORT21, GPIO_FN_STATUS0,
+ GPIO_FN_CPORT22, GPIO_FN_STATUS1,
+ GPIO_FN_CPORT23, GPIO_FN_STATUS2, GPIO_FN_RFSPO7,
+ GPIO_FN_B_SYNLD1,
+ GPIO_FN_B_SYNLD2, GPIO_FN_SYSENMSK,
+ GPIO_FN_XMAINPS,
+ GPIO_FN_XDIVPS,
+ GPIO_FN_XIDRST,
+ GPIO_FN_IDCLK, GPIO_FN_IC_DP,
+ GPIO_FN_IDIO, GPIO_FN_IC_DM,
+ GPIO_FN_SOUT1, GPIO_FN_SCIFA4_TXD, GPIO_FN_M02_BERDAT,
+ GPIO_FN_SIN1, GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
+ GPIO_FN_XRTS1, GPIO_FN_SCIFA4_RTS, GPIO_FN_M03_BERCLK,
+ GPIO_FN_XCTS1, GPIO_FN_SCIFA4_CTS,
+ GPIO_FN_PCMCLKO,
+ GPIO_FN_SYNC8KO,
+
+ /* 55-2 (FN) */
+ GPIO_FN_DNPCM_A,
+ GPIO_FN_UPPCM_A,
+ GPIO_FN_VACK,
+ GPIO_FN_XTALB1L,
+ GPIO_FN_GPS_AGC1, GPIO_FN_SCIFA0_RTS,
+ GPIO_FN_GPS_AGC4, GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_GPS_PWRDOWN, GPIO_FN_SCIFA0_CTS,
+ GPIO_FN_GPS_IM,
+ GPIO_FN_GPS_IS,
+ GPIO_FN_GPS_QM,
+ GPIO_FN_GPS_QS,
+ GPIO_FN_FMSOCK, GPIO_FN_PORT49_IRDA_OUT, GPIO_FN_PORT49_IROUT,
+ GPIO_FN_FMSOOLR, GPIO_FN_BBIF2_TSYNC2, GPIO_FN_TPU2TO2, GPIO_FN_IPORT3,
+ GPIO_FN_FMSIOLR,
+ GPIO_FN_FMSOOBT, GPIO_FN_BBIF2_TSCK2, GPIO_FN_TPU2TO3, GPIO_FN_OPORT1,
+ GPIO_FN_FMSIOBT,
+ GPIO_FN_FMSOSLD, GPIO_FN_BBIF2_TXD2, GPIO_FN_OPORT2,
+ GPIO_FN_FMSOILR, GPIO_FN_PORT53_IRDA_IN, GPIO_FN_TPU3TO3,
+ GPIO_FN_OPORT3, GPIO_FN_FMSIILR,
+ GPIO_FN_FMSOIBT, GPIO_FN_PORT54_IRDA_FIRSEL, GPIO_FN_TPU3TO2,
+ GPIO_FN_FMSIIBT,
+ GPIO_FN_FMSISLD, GPIO_FN_MFG0_OUT1, GPIO_FN_TPU0TO0,
+ GPIO_FN_A0_EA0, GPIO_FN_BS,
+ GPIO_FN_A12_EA12, GPIO_FN_PORT58_VIO_CKOR, GPIO_FN_TPU4TO2,
+ GPIO_FN_A13_EA13, GPIO_FN_PORT59_IROUT, GPIO_FN_MFG0_OUT2,
+ GPIO_FN_TPU0TO1,
+ GPIO_FN_A14_EA14, GPIO_FN_PORT60_KEYOUT5,
+ GPIO_FN_A15_EA15, GPIO_FN_PORT61_KEYOUT4,
+ GPIO_FN_A16_EA16, GPIO_FN_PORT62_KEYOUT3, GPIO_FN_MSIOF0_SS1,
+ GPIO_FN_A17_EA17, GPIO_FN_PORT63_KEYOUT2, GPIO_FN_MSIOF0_TSYNC,
+ GPIO_FN_A18_EA18, GPIO_FN_PORT64_KEYOUT1, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_A19_EA19, GPIO_FN_PORT65_KEYOUT0, GPIO_FN_MSIOF0_TXD,
+ GPIO_FN_A20_EA20, GPIO_FN_PORT66_KEYIN0, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_A21_EA21, GPIO_FN_PORT67_KEYIN1, GPIO_FN_MSIOF0_RSYNC,
+ GPIO_FN_A22_EA22, GPIO_FN_PORT68_KEYIN2, GPIO_FN_MSIOF0_MCK0,
+ GPIO_FN_A23_EA23, GPIO_FN_PORT69_KEYIN3, GPIO_FN_MSIOF0_MCK1,
+ GPIO_FN_A24_EA24, GPIO_FN_PORT70_KEYIN4, GPIO_FN_MSIOF0_RXD,
+ GPIO_FN_A25_EA25, GPIO_FN_PORT71_KEYIN5, GPIO_FN_MSIOF0_SS2,
+ GPIO_FN_A26, GPIO_FN_PORT72_KEYIN6,
+ GPIO_FN_D0_ED0_NAF0,
+ GPIO_FN_D1_ED1_NAF1,
+ GPIO_FN_D2_ED2_NAF2,
+ GPIO_FN_D3_ED3_NAF3,
+ GPIO_FN_D4_ED4_NAF4,
+ GPIO_FN_D5_ED5_NAF5,
+ GPIO_FN_D6_ED6_NAF6,
+ GPIO_FN_D7_ED7_NAF7,
+ GPIO_FN_D8_ED8_NAF8,
+ GPIO_FN_D9_ED9_NAF9,
+ GPIO_FN_D10_ED10_NAF10,
+ GPIO_FN_D11_ED11_NAF11,
+ GPIO_FN_D12_ED12_NAF12,
+ GPIO_FN_D13_ED13_NAF13,
+ GPIO_FN_D14_ED14_NAF14,
+ GPIO_FN_D15_ED15_NAF15,
+ GPIO_FN_CS4,
+ GPIO_FN_CS5A, GPIO_FN_FMSICK,
+ GPIO_FN_CS5B, GPIO_FN_FCE1,
+
+ /* 55-3 (FN) */
+ GPIO_FN_CS6B, GPIO_FN_XCS2, GPIO_FN_CS6A, GPIO_FN_DACK0,
+ GPIO_FN_FCE0,
+ GPIO_FN_WAIT, GPIO_FN_DREQ0,
+ GPIO_FN_RD_XRD,
+ GPIO_FN_WE0_XWR0_FWE,
+ GPIO_FN_WE1_XWR1,
+ GPIO_FN_FRB,
+ GPIO_FN_CKO,
+ GPIO_FN_NBRSTOUT,
+ GPIO_FN_NBRST,
+ GPIO_FN_GPS_EPPSIN,
+ GPIO_FN_LATCHPULSE,
+ GPIO_FN_LTESIGNAL,
+ GPIO_FN_LEGACYSTATE,
+ GPIO_FN_TCKON,
+ GPIO_FN_VIO_VD, GPIO_FN_PORT128_KEYOUT0, GPIO_FN_IPORT0,
+ GPIO_FN_VIO_HD, GPIO_FN_PORT129_KEYOUT1, GPIO_FN_IPORT1,
+ GPIO_FN_VIO_D0, GPIO_FN_PORT130_KEYOUT2, GPIO_FN_PORT130_MSIOF2_RXD,
+ GPIO_FN_VIO_D1, GPIO_FN_PORT131_KEYOUT3, GPIO_FN_PORT131_MSIOF2_SS1,
+ GPIO_FN_VIO_D2, GPIO_FN_PORT132_KEYOUT4, GPIO_FN_PORT132_MSIOF2_SS2,
+ GPIO_FN_VIO_D3, GPIO_FN_PORT133_KEYOUT5, GPIO_FN_PORT133_MSIOF2_TSYNC,
+ GPIO_FN_VIO_D4, GPIO_FN_PORT134_KEYIN0, GPIO_FN_PORT134_MSIOF2_TXD,
+ GPIO_FN_VIO_D5, GPIO_FN_PORT135_KEYIN1, GPIO_FN_PORT135_MSIOF2_TSCK,
+ GPIO_FN_VIO_D6, GPIO_FN_PORT136_KEYIN2,
+ GPIO_FN_VIO_D7, GPIO_FN_PORT137_KEYIN3,
+ GPIO_FN_VIO_D8, GPIO_FN_M9_SLCD_A01, GPIO_FN_PORT138_FSIAOMC,
+ GPIO_FN_VIO_D9, GPIO_FN_M10_SLCD_CK1, GPIO_FN_PORT139_FSIAOLR,
+ GPIO_FN_VIO_D10, GPIO_FN_M11_SLCD_SO1, GPIO_FN_TPU0TO2,
+ GPIO_FN_PORT140_FSIAOBT,
+ GPIO_FN_VIO_D11, GPIO_FN_M12_SLCD_CE1, GPIO_FN_TPU0TO3,
+ GPIO_FN_PORT141_FSIAOSLD,
+ GPIO_FN_VIO_D12, GPIO_FN_M13_BSW, GPIO_FN_PORT142_FSIACK,
+ GPIO_FN_VIO_D13, GPIO_FN_M14_GSW, GPIO_FN_PORT143_FSIAILR,
+ GPIO_FN_VIO_D14, GPIO_FN_M15_RSW, GPIO_FN_PORT144_FSIAIBT,
+ GPIO_FN_VIO_D15, GPIO_FN_TPU1TO3, GPIO_FN_PORT145_FSIAISLD,
+ GPIO_FN_VIO_CLK, GPIO_FN_PORT146_KEYIN4, GPIO_FN_IPORT2,
+ GPIO_FN_VIO_FIELD, GPIO_FN_PORT147_KEYIN5,
+ GPIO_FN_VIO_CKO, GPIO_FN_PORT148_KEYIN6,
+ GPIO_FN_A27, GPIO_FN_RDWR_XWE, GPIO_FN_MFG0_IN1,
+ GPIO_FN_MFG0_IN2,
+ GPIO_FN_TS_SPSYNC3, GPIO_FN_MSIOF2_RSCK,
+ GPIO_FN_TS_SDAT3, GPIO_FN_MSIOF2_RSYNC,
+ GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT153_MSIOF2_SS1,
+ GPIO_FN_SOUT3, GPIO_FN_SCIFA2_TXD1, GPIO_FN_MSIOF2_MCK0,
+ GPIO_FN_SIN3, GPIO_FN_SCIFA2_RXD1, GPIO_FN_MSIOF2_MCK1,
+ GPIO_FN_XRTS3, GPIO_FN_SCIFA2_RTS1, GPIO_FN_PORT156_MSIOF2_SS2,
+ GPIO_FN_XCTS3, GPIO_FN_SCIFA2_CTS1, GPIO_FN_PORT157_MSIOF2_RXD,
+
+ /* 55-4 (FN) */
+ GPIO_FN_DINT, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
+ GPIO_FN_PORT159_SCIFB_SCK, GPIO_FN_PORT159_SCIFA5_SCK, GPIO_FN_NMI,
+ GPIO_FN_PORT160_SCIFB_TXD, GPIO_FN_PORT160_SCIFA5_TXD, GPIO_FN_SOUT0,
+ GPIO_FN_PORT161_SCIFB_CTS, GPIO_FN_PORT161_SCIFA5_CTS, GPIO_FN_XCTS0,
+ GPIO_FN_MFG3_IN2,
+ GPIO_FN_PORT162_SCIFB_RXD, GPIO_FN_PORT162_SCIFA5_RXD, GPIO_FN_SIN0,
+ GPIO_FN_MFG3_IN1,
+ GPIO_FN_PORT163_SCIFB_RTS, GPIO_FN_PORT163_SCIFA5_RTS, GPIO_FN_XRTS0,
+ GPIO_FN_MFG3_OUT1,
+ GPIO_FN_TPU3TO0,
+ GPIO_FN_LCDD0, GPIO_FN_PORT192_KEYOUT0, GPIO_FN_EXT_CKI,
+ GPIO_FN_LCDD1, GPIO_FN_PORT193_KEYOUT1, GPIO_FN_PORT193_SCIFA5_CTS,
+ GPIO_FN_BBIF2_TSYNC1,
+ GPIO_FN_LCDD2, GPIO_FN_PORT194_KEYOUT2, GPIO_FN_PORT194_SCIFA5_RTS,
+ GPIO_FN_BBIF2_TSCK1,
+ GPIO_FN_LCDD3, GPIO_FN_PORT195_KEYOUT3, GPIO_FN_PORT195_SCIFA5_RXD,
+ GPIO_FN_BBIF2_TXD1,
+ GPIO_FN_LCDD4, GPIO_FN_PORT196_KEYOUT4, GPIO_FN_PORT196_SCIFA5_TXD,
+ GPIO_FN_LCDD5, GPIO_FN_PORT197_KEYOUT5, GPIO_FN_PORT197_SCIFA5_SCK,
+ GPIO_FN_MFG2_OUT2, GPIO_FN_TPU2TO1,
+ GPIO_FN_LCDD6, GPIO_FN_XWR2,
+ GPIO_FN_LCDD7, GPIO_FN_TPU4TO1, GPIO_FN_MFG4_OUT2, GPIO_FN_XWR3,
+ GPIO_FN_LCDD8, GPIO_FN_PORT200_KEYIN0, GPIO_FN_VIO_DR0, GPIO_FN_D16,
+ GPIO_FN_ED16,
+ GPIO_FN_LCDD9, GPIO_FN_PORT201_KEYIN1, GPIO_FN_VIO_DR1, GPIO_FN_D17,
+ GPIO_FN_ED17,
+ GPIO_FN_LCDD10, GPIO_FN_PORT202_KEYIN2, GPIO_FN_VIO_DR2, GPIO_FN_D18,
+ GPIO_FN_ED18,
+ GPIO_FN_LCDD11, GPIO_FN_PORT203_KEYIN3, GPIO_FN_VIO_DR3, GPIO_FN_D19,
+ GPIO_FN_ED19,
+ GPIO_FN_LCDD12, GPIO_FN_PORT204_KEYIN4, GPIO_FN_VIO_DR4, GPIO_FN_D20,
+ GPIO_FN_ED20,
+ GPIO_FN_LCDD13, GPIO_FN_PORT205_KEYIN5, GPIO_FN_VIO_DR5, GPIO_FN_D21,
+ GPIO_FN_ED21,
+ GPIO_FN_LCDD14, GPIO_FN_PORT206_KEYIN6, GPIO_FN_VIO_DR6, GPIO_FN_D22,
+ GPIO_FN_ED22,
+ GPIO_FN_LCDD15, GPIO_FN_PORT207_MSIOF0L_SS1, GPIO_FN_PORT207_KEYOUT0,
+ GPIO_FN_VIO_DR7,
+ GPIO_FN_D23, GPIO_FN_ED23,
+ GPIO_FN_LCDD16, GPIO_FN_PORT208_MSIOF0L_SS2, GPIO_FN_PORT208_KEYOUT1,
+ GPIO_FN_VIO_VDR,
+ GPIO_FN_D24, GPIO_FN_ED24,
+ GPIO_FN_LCDD17, GPIO_FN_PORT209_KEYOUT2, GPIO_FN_VIO_HDR, GPIO_FN_D25,
+ GPIO_FN_ED25,
+ GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_PORT210_MSIOF0L_SS1, GPIO_FN_D26,
+ GPIO_FN_ED26,
+ GPIO_FN_LCDD19, GPIO_FN_PORT211_MSIOF0L_SS2, GPIO_FN_D27, GPIO_FN_ED27,
+ GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0, GPIO_FN_D28,
+ GPIO_FN_ED28,
+ GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1, GPIO_FN_D29,
+ GPIO_FN_ED29,
+ GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_RSCK, GPIO_FN_D30,
+ GPIO_FN_ED30,
+ GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_RSYNC, GPIO_FN_D31,
+ GPIO_FN_ED31,
+ GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_PORT216_KEYOUT3,
+ GPIO_FN_VIO_CLKR,
+ GPIO_FN_LCDRD, GPIO_FN_DACK2, GPIO_FN_MSIOF0L_TSYNC,
+ GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDCS2, GPIO_FN_DACK3,
+ GPIO_FN_PORT218_VIO_CKOR, GPIO_FN_PORT218_KEYOUT4,
+ GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_TSCK,
+ GPIO_FN_LCDVSYN, GPIO_FN_LCDVSYN2, GPIO_FN_PORT220_KEYOUT5,
+ GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_PWEN, GPIO_FN_MSIOF0L_RXD,
+ GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_OVCN,
+ GPIO_FN_MSIOF0L_TXD,
+ GPIO_FN_SCIFA1_TXD, GPIO_FN_OVCN2,
+ GPIO_FN_EXTLP, GPIO_FN_SCIFA1_SCK, GPIO_FN_USBTERM,
+ GPIO_FN_PORT226_VIO_CKO2,
+ GPIO_FN_SCIFA1_RTS, GPIO_FN_IDIN,
+ GPIO_FN_SCIFA1_RXD,
+ GPIO_FN_SCIFA1_CTS, GPIO_FN_MFG1_IN1,
+ GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA2_TXD2, GPIO_FN_PORT230_FSIAOMC,
+ GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA2_CTS2, GPIO_FN_PORT231_FSIAOLR,
+ GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA2_SCK2, GPIO_FN_PORT232_FSIAOBT,
+ GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA2_RXD2, GPIO_FN_GPS_VCOTRIG,
+ GPIO_FN_PORT233_FSIACK,
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA2_RTS2, GPIO_FN_PORT234_FSIAOSLD,
+ GPIO_FN_MSIOF1_RSYNC, GPIO_FN_OPORT0, GPIO_FN_MFG1_IN2,
+ GPIO_FN_PORT235_FSIAILR,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_I2C_SDA2, GPIO_FN_PORT236_FSIAIBT,
+ GPIO_FN_MSIOF1_MCK1, GPIO_FN_I2C_SCL2, GPIO_FN_PORT237_FSIAISLD,
+ GPIO_FN_MSIOF1_SS1, GPIO_FN_EDBGREQ3,
+
+ /* 55-5 (FN) */
+ GPIO_FN_MSIOF1_SS2,
+ GPIO_FN_SCIFA6_TXD,
+ GPIO_FN_PORT241_IRDA_OUT, GPIO_FN_PORT241_IROUT, GPIO_FN_MFG4_OUT1,
+ GPIO_FN_TPU4TO0,
+ GPIO_FN_PORT242_IRDA_IN, GPIO_FN_MFG4_IN2,
+ GPIO_FN_PORT243_IRDA_FIRSEL, GPIO_FN_PORT243_VIO_CKO2,
+ GPIO_FN_PORT244_SCIFA5_CTS, GPIO_FN_MFG2_IN1, GPIO_FN_PORT244_SCIFB_CTS,
+ GPIO_FN_PORT244_MSIOF2_RXD,
+ GPIO_FN_PORT245_SCIFA5_RTS, GPIO_FN_MFG2_IN2, GPIO_FN_PORT245_SCIFB_RTS,
+ GPIO_FN_PORT245_MSIOF2_TXD,
+ GPIO_FN_PORT246_SCIFA5_RXD, GPIO_FN_MFG1_OUT1,
+ GPIO_FN_PORT246_SCIFB_RXD, GPIO_FN_TPU1TO0,
+ GPIO_FN_PORT247_SCIFA5_TXD, GPIO_FN_MFG3_OUT2,
+ GPIO_FN_PORT247_SCIFB_TXD, GPIO_FN_TPU3TO1,
+ GPIO_FN_PORT248_SCIFA5_SCK, GPIO_FN_MFG2_OUT1,
+ GPIO_FN_PORT248_SCIFB_SCK, GPIO_FN_TPU2TO0,
+ GPIO_FN_PORT248_MSIOF2_TSCK,
+ GPIO_FN_PORT249_IROUT, GPIO_FN_MFG4_IN1, GPIO_FN_PORT249_MSIOF2_TSYNC,
+ GPIO_FN_SDHICLK0, GPIO_FN_TCK2_SWCLK_MC0,
+ GPIO_FN_SDHICD0,
+ GPIO_FN_SDHID0_0, GPIO_FN_TMS2_SWDIO_MC0,
+ GPIO_FN_SDHID0_1, GPIO_FN_TDO2_SWO0_MC0,
+ GPIO_FN_SDHID0_2, GPIO_FN_TDI2,
+ GPIO_FN_SDHID0_3, GPIO_FN_RTCK2_SWO1_MC0,
+ GPIO_FN_SDHICMD0, GPIO_FN_TRST2,
+ GPIO_FN_SDHIWP0, GPIO_FN_EDBGREQ2,
+ GPIO_FN_SDHICLK1, GPIO_FN_TCK3_SWCLK_MC1,
+ GPIO_FN_SDHID1_0, GPIO_FN_M11_SLCD_SO2, GPIO_FN_TS_SPSYNC2,
+ GPIO_FN_TMS3_SWDIO_MC1,
+ GPIO_FN_SDHID1_1, GPIO_FN_M9_SLCD_A02, GPIO_FN_TS_SDAT2,
+ GPIO_FN_TDO3_SWO0_MC1,
+ GPIO_FN_SDHID1_2, GPIO_FN_M10_SLCD_CK2, GPIO_FN_TS_SDEN2, GPIO_FN_TDI3,
+ GPIO_FN_SDHID1_3, GPIO_FN_M12_SLCD_CE2, GPIO_FN_TS_SCK2,
+ GPIO_FN_RTCK3_SWO1_MC1,
+ GPIO_FN_SDHICMD1, GPIO_FN_TRST3,
+ GPIO_FN_RESETOUTS,
+};
+
+#endif /* __ASM_SH7377_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/system.h b/arch/arm/mach-shmobile/include/mach/system.h
new file mode 100644
index 00000000000..76a687eeaa2
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/system.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ cpu_reset(0);
+}
+
+#endif
diff --git a/arch/arm/mach-shmobile/include/mach/timex.h b/arch/arm/mach-shmobile/include/mach/timex.h
new file mode 100644
index 00000000000..ae0d8d825c2
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/timex.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_MACH_TIMEX_H
+#define __ASM_MACH_TIMEX_H
+
+#define CLOCK_TICK_RATE 1193180 /* unused i8253 PIT value */
+
+#endif /* __ASM_MACH_TIMEX_H */
diff --git a/arch/arm/mach-shmobile/include/mach/uncompress.h b/arch/arm/mach-shmobile/include/mach/uncompress.h
new file mode 100644
index 00000000000..0bd7556b138
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/uncompress.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_MACH_UNCOMPRESS_H
+#define __ASM_MACH_UNCOMPRESS_H
+
+/*
+ * This does not append a newline
+ */
+static void putc(int c)
+{
+}
+
+static inline void flush(void)
+{
+}
+
+static void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog()
+
+#endif /* __ASM_MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h
new file mode 100644
index 00000000000..fb3c4f1ab25
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_MACH_VMALLOC_H
+#define __ASM_MACH_VMALLOC_H
+
+#define VMALLOC_END (PAGE_OFFSET + 0x24000000)
+
+#endif /* __ASM_MACH_VMALLOC_H */
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c
new file mode 100644
index 00000000000..5ff70cadfc3
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh7367.c
@@ -0,0 +1,270 @@
+/*
+ * sh7367 processor support - INTC hardware block
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+ UNUSED_INTCA = 0,
+ ENABLED,
+ DISABLED,
+
+ /* interrupt sources INTCA */
+ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+ IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+ DIRC,
+ CRYPT1_ERR, CRYPT2_STD,
+ IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+ ARM11_IRQPMU, ARM11_COMMTX, ARM11_COMMRX,
+ ETM11_ACQCMP, ETM11_FULL,
+ MFI_MFIM, MFI_MFIS,
+ BBIF1, BBIF2,
+ USBDMAC_USHDMI,
+ USBHS_USHI0, USBHS_USHI1,
+ CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+ KEYSC_KEY,
+ SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+ MSIOF2, MSIOF1,
+ SCIFA4, SCIFA5, SCIFB,
+ FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+ SDHI0,
+ SDHI1,
+ MSU_MSU, MSU_MSU2,
+ IREM,
+ SIU,
+ SPU,
+ IRDA,
+ TPU0, TPU1, TPU2, TPU3, TPU4,
+ LCRC,
+ PINT1, PINT2,
+ TTI20,
+ MISTY,
+ DDM,
+ SDHI2,
+ RWDT0, RWDT1,
+ DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
+ DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
+ DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+ DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+
+ /* interrupt groups INTCA */
+ DMAC_1, DMAC_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2,
+ ETM11, ARM11, USBHS, FLCTL, IIC1
+};
+
+static struct intc_vect intca_vectors[] = {
+ INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+ INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+ INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+ INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+ INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+ INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+ INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+ INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+ INTC_VECT(DIRC, 0x0560),
+ INTC_VECT(CRYPT1_ERR, 0x05e0),
+ INTC_VECT(CRYPT2_STD, 0x0700),
+ INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+ INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+ INTC_VECT(ARM11_IRQPMU, 0x0800), INTC_VECT(ARM11_COMMTX, 0x0840),
+ INTC_VECT(ARM11_COMMRX, 0x0860),
+ INTC_VECT(ETM11_ACQCMP, 0x0880), INTC_VECT(ETM11_FULL, 0x08a0),
+ INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+ INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+ INTC_VECT(USBDMAC_USHDMI, 0x0a00),
+ INTC_VECT(USBHS_USHI0, 0x0a20), INTC_VECT(USBHS_USHI1, 0x0a40),
+ INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+ INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+ INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+ INTC_VECT(KEYSC_KEY, 0x0be0),
+ INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+ INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+ INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+ INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+ INTC_VECT(SCIFB, 0x0d60),
+ INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+ INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+ INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+ INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+ INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+ INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
+ INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
+ INTC_VECT(IREM, 0x0f60),
+ INTC_VECT(SIU, 0x0fa0),
+ INTC_VECT(SPU, 0x0fc0),
+ INTC_VECT(IRDA, 0x0480),
+ INTC_VECT(TPU0, 0x04a0), INTC_VECT(TPU1, 0x04c0),
+ INTC_VECT(TPU2, 0x04e0), INTC_VECT(TPU3, 0x0500),
+ INTC_VECT(TPU4, 0x0520),
+ INTC_VECT(LCRC, 0x0540),
+ INTC_VECT(PINT1, 0x1000), INTC_VECT(PINT2, 0x1020),
+ INTC_VECT(TTI20, 0x1100),
+ INTC_VECT(MISTY, 0x1120),
+ INTC_VECT(DDM, 0x1140),
+ INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
+ INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
+ INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
+ INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
+ INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
+ INTC_VECT(DMAC_2_DEI4, 0x2080), INTC_VECT(DMAC_2_DEI5, 0x20a0),
+ INTC_VECT(DMAC_2_DADERR, 0x20c0),
+ INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+ INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+ INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+ INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+ INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+ INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+ INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+ INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+ INTC_GROUP(DMAC_1, DMAC_1_DEI0,
+ DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3),
+ INTC_GROUP(DMAC_2, DMAC_2_DEI4,
+ DMAC_2_DEI5, DMAC_2_DADERR),
+ INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+ DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+ INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+ DMAC2_2_DEI5, DMAC2_2_DADERR),
+ INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+ DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+ INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+ DMAC3_2_DEI5, DMAC3_2_DADERR),
+ INTC_GROUP(ETM11, ETM11_ACQCMP, ETM11_FULL),
+ INTC_GROUP(ARM11, ARM11_IRQPMU, ARM11_COMMTX, ARM11_COMMTX),
+ INTC_GROUP(USBHS, USBHS_USHI0, USBHS_USHI1),
+ INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+ FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+ INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+};
+
+static struct intc_mask_reg intca_mask_registers[] = {
+ { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+ { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+ ARM11_IRQPMU, 0, ARM11_COMMTX, ARM11_COMMRX } },
+ { 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+ { CRYPT1_ERR, CRYPT2_STD, DIRC, 0,
+ DMAC_1_DEI3, DMAC_1_DEI2, DMAC_1_DEI1, DMAC_1_DEI0 } },
+ { 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+ { PINT1, PINT2, 0, 0,
+ BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+ { 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+ { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+ DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+ { 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+ { DDM, 0, 0, 0,
+ 0, 0, ETM11_FULL, ETM11_ACQCMP } },
+ { 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+ { KEYSC_KEY, DMAC_2_DADERR, DMAC_2_DEI5, DMAC_2_DEI4,
+ SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+ { 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+ { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+ 0, 0, MSIOF2, 0 } },
+ { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+ { DISABLED, DISABLED, ENABLED, ENABLED,
+ FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+ { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+ { DISABLED, DISABLED, ENABLED, ENABLED,
+ TTI20, USBDMAC_USHDMI, SPU, SIU } },
+ { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+ CMT2, USBHS_USHI1, USBHS_USHI0, 0 } },
+ { 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+ { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+ 0, 0, 0, 0 } },
+ { 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+ { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+ LCRC, MSU_MSU2, IREM, MSU_MSU } },
+ { 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+ { 0, 0, TPU0, TPU1,
+ TPU2, TPU3, TPU4, 0 } },
+ { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+ { DISABLED, DISABLED, ENABLED, ENABLED,
+ MISTY, CMT3, RWDT1, RWDT0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] = {
+ { 0xe6900010, 0, 32, 4, /* INTPRI00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900014, 0, 32, 4, /* INTPRI10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+
+ { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
+ { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, ETM11, BBIF1, BBIF2 } },
+ { 0xe6940008, 0, 16, 4, /* IPRCA */ { CRYPT1_ERR, CRYPT2_STD,
+ CMT1_CMT11, ARM11 } },
+ { 0xe694000c, 0, 16, 4, /* IPRDA */ { PINT1, PINT2,
+ CMT1_CMT12, TPU4 } },
+ { 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC_1, MFI_MFIS,
+ MFI_MFIM, USBHS } },
+ { 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC_2,
+ 0, CMT1_CMT10 } },
+ { 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+ SCIFA2, SCIFA3 } },
+ { 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBDMAC_USHDMI,
+ FLCTL, SDHI0 } },
+ { 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, MSU_MSU, IIC1 } },
+ { 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2, SIU, TTI20 } },
+ { 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IREM, SDHI1 } },
+ { 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, TPU1, TPU2, TPU3 } },
+ { 0xe6940030, 0, 16, 4, /* IPRMA */ { MISTY, CMT3, RWDT1, RWDT0 } },
+ { 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, SPU, DDM } },
+ { 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+ { 0xe6900000, 16, 2, /* ICR1A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900004, 16, 2, /* ICR2A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+ { 0xe6900020, 0, 8, /* INTREQ00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900024, 0, 8, /* INTREQ10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+};
+
+static struct intc_desc intca_desc __initdata = {
+ .name = "sh7367-intca",
+ .force_enable = ENABLED,
+ .force_disable = DISABLED,
+ .hw = INTC_HW_DESC(intca_vectors, intca_groups,
+ intca_mask_registers, intca_prio_registers,
+ intca_sense_registers, intca_ack_registers),
+};
+
+void __init sh7367_init_irq(void)
+{
+ /* INTCA */
+ register_intc_controller(&intca_desc);
+}
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
new file mode 100644
index 00000000000..3ce9d9bd589
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -0,0 +1,369 @@
+/*
+ * sh7372 processor support - INTC hardware block
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+ UNUSED_INTCA = 0,
+ ENABLED,
+ DISABLED,
+
+ /* interrupt sources INTCA */
+ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+ IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+ IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A,
+ IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A,
+ DIRC,
+ CRYPT_STD,
+ IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+ AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX,
+ MFI_MFIM, MFI_MFIS,
+ BBIF1, BBIF2,
+ USBHSDMAC0_USHDMI,
+ _3DG_SGX540,
+ CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+ KEYSC_KEY,
+ SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+ MSIOF2, MSIOF1,
+ SCIFA4, SCIFA5, SCIFB,
+ FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+ SDHI0,
+ SDHI1,
+ IRREM,
+ IRDA,
+ TPU0,
+ TTI20,
+ DDM,
+ SDHI2,
+ RWDT0,
+ DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3,
+ DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR,
+ DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+ DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+ SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
+ HDMI,
+ SPU2_SPU0, SPU2_SPU1,
+ FSI, FMSI,
+ MIPI_HSI,
+ IPMMU_IPMMUD,
+ CEC_1, CEC_2,
+ AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ, AP_ARM_DMAIRQ, AP_ARM_DMASIRQ,
+ MFIS2,
+ CPORTR2S,
+ CMT14, CMT15,
+ MMC_MMC_ERR, MMC_MMC_NOR,
+ IIC4_ALI4, IIC4_TACKI4, IIC4_WAITI4, IIC4_DTEI4,
+ IIC3_ALI3, IIC3_TACKI3, IIC3_WAITI3, IIC3_DTEI3,
+ USB0_USB0I1, USB0_USB0I0,
+ USB1_USB1I1, USB1_USB1I0,
+ USBHSDMAC1_USHDMI,
+
+ /* interrupt groups INTCA */
+ DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
+ AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1
+};
+
+static struct intc_vect intca_vectors[] __initdata = {
+ INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+ INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+ INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+ INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+ INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+ INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+ INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+ INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+ INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
+ INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
+ INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0),
+ INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
+ INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
+ INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
+ INTC_VECT(IRQ28A, 0x3380), INTC_VECT(IRQ29A, 0x33a0),
+ INTC_VECT(IRQ30A, 0x33c0), INTC_VECT(IRQ31A, 0x33e0),
+ INTC_VECT(DIRC, 0x0560),
+ INTC_VECT(CRYPT_STD, 0x0700),
+ INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+ INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+ INTC_VECT(AP_ARM_IRQPMU, 0x0800), INTC_VECT(AP_ARM_COMMTX, 0x0840),
+ INTC_VECT(AP_ARM_COMMRX, 0x0860),
+ INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+ INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+ INTC_VECT(USBHSDMAC0_USHDMI, 0x0a00),
+ INTC_VECT(_3DG_SGX540, 0x0a60),
+ INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+ INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+ INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+ INTC_VECT(KEYSC_KEY, 0x0be0),
+ INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+ INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+ INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+ INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+ INTC_VECT(SCIFB, 0x0d60),
+ INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+ INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+ INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+ INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+ INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+ INTC_VECT(SDHI1, 0x0ec0),
+ INTC_VECT(IRREM, 0x0f60),
+ INTC_VECT(IRDA, 0x0480),
+ INTC_VECT(TPU0, 0x04a0),
+ INTC_VECT(TTI20, 0x1100),
+ INTC_VECT(DDM, 0x1140),
+ INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
+ INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
+ INTC_VECT(RWDT0, 0x1280),
+ INTC_VECT(DMAC1_1_DEI0, 0x2000), INTC_VECT(DMAC1_1_DEI1, 0x2020),
+ INTC_VECT(DMAC1_1_DEI2, 0x2040), INTC_VECT(DMAC1_1_DEI3, 0x2060),
+ INTC_VECT(DMAC1_2_DEI4, 0x2080), INTC_VECT(DMAC1_2_DEI5, 0x20a0),
+ INTC_VECT(DMAC1_2_DADERR, 0x20c0),
+ INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+ INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+ INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+ INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+ INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+ INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+ INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+ INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+ INTC_VECT(SHWYSTAT_RT, 0x1300), INTC_VECT(SHWYSTAT_HS, 0x1320),
+ INTC_VECT(SHWYSTAT_COM, 0x1340),
+ INTC_VECT(HDMI, 0x17e0),
+ INTC_VECT(SPU2_SPU0, 0x1800), INTC_VECT(SPU2_SPU1, 0x1820),
+ INTC_VECT(FSI, 0x1840),
+ INTC_VECT(FMSI, 0x1860),
+ INTC_VECT(MIPI_HSI, 0x18e0),
+ INTC_VECT(IPMMU_IPMMUD, 0x1920),
+ INTC_VECT(CEC_1, 0x1940), INTC_VECT(CEC_2, 0x1960),
+ INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
+ INTC_VECT(AP_ARM_DMAEXTERRIRQ, 0x19a0),
+ INTC_VECT(AP_ARM_DMAIRQ, 0x19c0),
+ INTC_VECT(AP_ARM_DMASIRQ, 0x19e0),
+ INTC_VECT(MFIS2, 0x1a00),
+ INTC_VECT(CPORTR2S, 0x1a20),
+ INTC_VECT(CMT14, 0x1a40), INTC_VECT(CMT15, 0x1a60),
+ INTC_VECT(MMC_MMC_ERR, 0x1ac0), INTC_VECT(MMC_MMC_NOR, 0x1ae0),
+ INTC_VECT(IIC4_ALI4, 0x1b00), INTC_VECT(IIC4_TACKI4, 0x1b20),
+ INTC_VECT(IIC4_WAITI4, 0x1b40), INTC_VECT(IIC4_DTEI4, 0x1b60),
+ INTC_VECT(IIC3_ALI3, 0x1b80), INTC_VECT(IIC3_TACKI3, 0x1ba0),
+ INTC_VECT(IIC3_WAITI3, 0x1bc0), INTC_VECT(IIC3_DTEI3, 0x1be0),
+ INTC_VECT(USB0_USB0I1, 0x1c80), INTC_VECT(USB0_USB0I0, 0x1ca0),
+ INTC_VECT(USB1_USB1I1, 0x1cc0), INTC_VECT(USB1_USB1I0, 0x1ce0),
+ INTC_VECT(USBHSDMAC1_USHDMI, 0x1d00),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+ INTC_GROUP(DMAC1_1, DMAC1_1_DEI0,
+ DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3),
+ INTC_GROUP(DMAC1_2, DMAC1_2_DEI4,
+ DMAC1_2_DEI5, DMAC1_2_DADERR),
+ INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+ DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+ INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+ DMAC2_2_DEI5, DMAC2_2_DADERR),
+ INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+ DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+ INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+ DMAC3_2_DEI5, DMAC3_2_DADERR),
+ INTC_GROUP(AP_ARM1, AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX),
+ INTC_GROUP(AP_ARM2, AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+ AP_ARM_DMAIRQ, AP_ARM_DMASIRQ),
+ INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
+ INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+ FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+ INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+ INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
+};
+
+static struct intc_mask_reg intca_mask_registers[] __initdata = {
+ { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900048, 0xe6900068, 8, /* INTMSK20A / INTMSKCLR20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690004c, 0xe690006c, 8, /* INTMSK30A / INTMSKCLR30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+ { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+ { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+ AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
+ { 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+ { 0, CRYPT_STD, DIRC, 0,
+ DMAC1_1_DEI3, DMAC1_1_DEI2, DMAC1_1_DEI1, DMAC1_1_DEI0 } },
+ { 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+ { 0, 0, 0, 0,
+ BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+ { 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+ { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+ DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+ { 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+ { DDM, 0, 0, 0,
+ 0, 0, 0, 0 } },
+ { 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+ { KEYSC_KEY, DMAC1_2_DADERR, DMAC1_2_DEI5, DMAC1_2_DEI4,
+ SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+ { 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+ { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+ 0, 0, MSIOF2, 0 } },
+ { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+ { DISABLED, DISABLED, ENABLED, ENABLED,
+ FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+ { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+ { 0, DISABLED, ENABLED, ENABLED,
+ TTI20, USBHSDMAC0_USHDMI, 0, 0 } },
+ { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+ CMT2, 0, 0, _3DG_SGX540 } },
+ { 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+ { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+ 0, 0, 0, 0 } },
+ { 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+ { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+ 0, 0, IRREM, 0 } },
+ { 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+ { 0, 0, TPU0, 0,
+ 0, 0, 0, 0 } },
+ { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+ { DISABLED, DISABLED, ENABLED, ENABLED,
+ 0, CMT3, 0, RWDT0 } },
+ { 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
+ { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
+ 0, 0, 0, 0 } },
+ { 0xe6950090, 0xe69500d0, 8, /* IMR4A3 / IMCR4A3 */
+ { 0, 0, 0, 0,
+ 0, 0, 0, HDMI } },
+ { 0xe6950094, 0xe69500d4, 8, /* IMR5A3 / IMCR5A3 */
+ { SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
+ 0, 0, 0, MIPI_HSI } },
+ { 0xe6950098, 0xe69500d8, 8, /* IMR6A3 / IMCR6A3 */
+ { 0, IPMMU_IPMMUD, CEC_1, CEC_2,
+ AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+ AP_ARM_DMAIRQ, AP_ARM_DMASIRQ } },
+ { 0xe695009c, 0xe69500dc, 8, /* IMR7A3 / IMCR7A3 */
+ { MFIS2, CPORTR2S, CMT14, CMT15,
+ 0, 0, MMC_MMC_ERR, MMC_MMC_NOR } },
+ { 0xe69500a0, 0xe69500e0, 8, /* IMR8A3 / IMCR8A3 */
+ { IIC4_ALI4, IIC4_TACKI4, IIC4_WAITI4, IIC4_DTEI4,
+ IIC3_ALI3, IIC3_TACKI3, IIC3_WAITI3, IIC3_DTEI3 } },
+ { 0xe69500a4, 0xe69500e4, 8, /* IMR9A3 / IMCR9A3 */
+ { 0, 0, 0, 0,
+ USB0_USB0I1, USB0_USB0I0, USB1_USB1I1, USB1_USB1I0 } },
+ { 0xe69500a8, 0xe69500e8, 8, /* IMR10A3 / IMCR10A3 */
+ { USBHSDMAC1_USHDMI, 0, 0, 0,
+ 0, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] __initdata = {
+ { 0xe6900010, 0, 32, 4, /* INTPRI00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900014, 0, 32, 4, /* INTPRI10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900018, 0, 32, 4, /* INTPRI20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690001c, 0, 32, 4, /* INTPRI30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+ { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, 0 } },
+ { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
+ { 0xe6940008, 0, 16, 4, /* IPRCA */ { 0, CRYPT_STD,
+ CMT1_CMT11, AP_ARM1 } },
+ { 0xe694000c, 0, 16, 4, /* IPRDA */ { 0, 0,
+ CMT1_CMT12, 0 } },
+ { 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC1_1, MFI_MFIS,
+ MFI_MFIM, 0 } },
+ { 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC1_2,
+ _3DG_SGX540, CMT1_CMT10 } },
+ { 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+ SCIFA2, SCIFA3 } },
+ { 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBHSDMAC0_USHDMI,
+ FLCTL, SDHI0 } },
+ { 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4,
+ 0/* MSU */, IIC1 } },
+ { 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2,
+ 0/* MSUG */, TTI20 } },
+ { 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IRREM, SDHI1 } },
+ { 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, 0, 0, 0 } },
+ { 0xe6940030, 0, 16, 4, /* IPRMA */ { 0, CMT3, 0, RWDT0 } },
+ { 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, DDM } },
+ { 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
+ { 0xe6950000, 0, 16, 4, /* IPRAA3 */ { SHWYSTAT, 0, 0, 0 } },
+ { 0xe6950024, 0, 16, 4, /* IPRJA3 */ { 0, 0, 0, HDMI } },
+ { 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
+ { 0xe695002c, 0, 16, 4, /* IPRLA3 */ { 0, 0, 0, MIPI_HSI } },
+ { 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU_IPMMUD, 0,
+ CEC_1, CEC_2 } },
+ { 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,
+ MMC_MMC_ERR, MMC_MMC_NOR } },
+ { 0xe6940040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4,
+ IIC4_WAITI4, IIC4_DTEI4 } },
+ { 0xe6940044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3,
+ IIC3_WAITI3, IIC3_DTEI3 } },
+ { 0xe6940048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/,
+ 0/*TXI*/, 0/*TEI*/} },
+ { 0xe694004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0,
+ USB1_USB1I1, USB1_USB1I0 } },
+ { 0xe6940050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+ { 0xe6900000, 32, 4, /* ICR1A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900004, 32, 4, /* ICR2A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900008, 32, 4, /* ICR3A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690000c, 32, 4, /* ICR4A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+ { 0xe6900020, 0, 8, /* INTREQ00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900024, 0, 8, /* INTREQ10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900028, 0, 8, /* INTREQ20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690002c, 0, 8, /* INTREQ30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_desc intca_desc __initdata = {
+ .name = "sh7372-intca",
+ .force_enable = ENABLED,
+ .force_disable = DISABLED,
+ .hw = INTC_HW_DESC(intca_vectors, intca_groups,
+ intca_mask_registers, intca_prio_registers,
+ intca_sense_registers, intca_ack_registers),
+};
+
+void __init sh7372_init_irq(void)
+{
+ register_intc_controller(&intca_desc);
+}
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c
new file mode 100644
index 00000000000..5c781e2d189
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh7377.c
@@ -0,0 +1,352 @@
+/*
+ * sh7377 processor support - INTC hardware block
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+ UNUSED_INTCA = 0,
+ ENABLED,
+ DISABLED,
+
+ /* interrupt sources INTCA */
+ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+ IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+ IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A,
+ IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A,
+ DIRC,
+ _2DG,
+ CRYPT_STD,
+ IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+ AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX,
+ MFI_MFIM, MFI_MFIS,
+ BBIF1, BBIF2,
+ USBDMAC_USHDMI,
+ USBHS_USHI0, USBHS_USHI1,
+ _3DG_SGX540,
+ CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+ KEYSC_KEY,
+ SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+ MSIOF2, MSIOF1,
+ SCIFA4, SCIFA5, SCIFB,
+ FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+ SDHI0,
+ SDHI1,
+ MSU_MSU, MSU_MSU2,
+ IRREM,
+ MSUG,
+ IRDA,
+ TPU0, TPU1, TPU2, TPU3, TPU4,
+ LCRC,
+ PINTCA_PINT1, PINTCA_PINT2,
+ TTI20,
+ MISTY,
+ DDM,
+ RWDT0, RWDT1,
+ DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
+ DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
+ DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+ DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+ SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
+ ICUSB_ICUSB0, ICUSB_ICUSB1,
+ ICUDMC_ICUDMC1, ICUDMC_ICUDMC2,
+ SPU2_SPU0, SPU2_SPU1,
+ FSI,
+ FMSI,
+ SCUV,
+ IPMMU_IPMMUB,
+ AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ, AP_ARM_DMAIRQ, AP_ARM_DMASIRQ,
+ MFIS2,
+ CPORTR2S,
+ CMT14, CMT15,
+ SCIFA6,
+
+ /* interrupt groups INTCA */
+ DMAC_1, DMAC_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
+ AP_ARM1, AP_ARM2, USBHS, SPU2, FLCTL, IIC1,
+ ICUSB, ICUDMC
+};
+
+static struct intc_vect intca_vectors[] = {
+ INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+ INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+ INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+ INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+ INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+ INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+ INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+ INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+ INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
+ INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
+ INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0),
+ INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
+ INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
+ INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
+ INTC_VECT(IRQ28A, 0x3380), INTC_VECT(IRQ29A, 0x33a0),
+ INTC_VECT(IRQ30A, 0x33c0), INTC_VECT(IRQ31A, 0x33e0),
+ INTC_VECT(DIRC, 0x0560),
+ INTC_VECT(_2DG, 0x05e0),
+ INTC_VECT(CRYPT_STD, 0x0700),
+ INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+ INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+ INTC_VECT(AP_ARM_IRQPMU, 0x0800), INTC_VECT(AP_ARM_COMMTX, 0x0840),
+ INTC_VECT(AP_ARM_COMMRX, 0x0860),
+ INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+ INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+ INTC_VECT(USBDMAC_USHDMI, 0x0a00),
+ INTC_VECT(USBHS_USHI0, 0x0a20), INTC_VECT(USBHS_USHI1, 0x0a40),
+ INTC_VECT(_3DG_SGX540, 0x0a60),
+ INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+ INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+ INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+ INTC_VECT(KEYSC_KEY, 0x0be0),
+ INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+ INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+ INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+ INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+ INTC_VECT(SCIFB, 0x0d60),
+ INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+ INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+ INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+ INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+ INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+ INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
+ INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
+ INTC_VECT(IRREM, 0x0f60),
+ INTC_VECT(MSUG, 0x0fa0),
+ INTC_VECT(IRDA, 0x0480),
+ INTC_VECT(TPU0, 0x04a0), INTC_VECT(TPU1, 0x04c0),
+ INTC_VECT(TPU2, 0x04e0), INTC_VECT(TPU3, 0x0500),
+ INTC_VECT(TPU4, 0x0520),
+ INTC_VECT(LCRC, 0x0540),
+ INTC_VECT(PINTCA_PINT1, 0x1000), INTC_VECT(PINTCA_PINT2, 0x1020),
+ INTC_VECT(TTI20, 0x1100),
+ INTC_VECT(MISTY, 0x1120),
+ INTC_VECT(DDM, 0x1140),
+ INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
+ INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
+ INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
+ INTC_VECT(DMAC_2_DEI4, 0x2080), INTC_VECT(DMAC_2_DEI5, 0x20a0),
+ INTC_VECT(DMAC_2_DADERR, 0x20c0),
+ INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+ INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+ INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+ INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+ INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+ INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+ INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+ INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+ INTC_VECT(SHWYSTAT_RT, 0x1300), INTC_VECT(SHWYSTAT_HS, 0x1d20),
+ INTC_VECT(SHWYSTAT_COM, 0x1340),
+ INTC_VECT(ICUSB_ICUSB0, 0x1700), INTC_VECT(ICUSB_ICUSB1, 0x1720),
+ INTC_VECT(ICUDMC_ICUDMC1, 0x1780), INTC_VECT(ICUDMC_ICUDMC2, 0x17a0),
+ INTC_VECT(SPU2_SPU0, 0x1800), INTC_VECT(SPU2_SPU1, 0x1820),
+ INTC_VECT(FSI, 0x1840),
+ INTC_VECT(FMSI, 0x1860),
+ INTC_VECT(SCUV, 0x1880),
+ INTC_VECT(IPMMU_IPMMUB, 0x1900),
+ INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
+ INTC_VECT(AP_ARM_DMAEXTERRIRQ, 0x19a0),
+ INTC_VECT(AP_ARM_DMAIRQ, 0x19c0),
+ INTC_VECT(AP_ARM_DMASIRQ, 0x19e0),
+ INTC_VECT(MFIS2, 0x1a00),
+ INTC_VECT(CPORTR2S, 0x1a20),
+ INTC_VECT(CMT14, 0x1a40), INTC_VECT(CMT15, 0x1a60),
+ INTC_VECT(SCIFA6, 0x1a80),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+ INTC_GROUP(DMAC_1, DMAC_1_DEI0,
+ DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3),
+ INTC_GROUP(DMAC_2, DMAC_2_DEI4,
+ DMAC_2_DEI5, DMAC_2_DADERR),
+ INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+ DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+ INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+ DMAC2_2_DEI5, DMAC2_2_DADERR),
+ INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+ DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+ INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+ DMAC3_2_DEI5, DMAC3_2_DADERR),
+ INTC_GROUP(AP_ARM1, AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMTX),
+ INTC_GROUP(USBHS, USBHS_USHI0, USBHS_USHI1),
+ INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
+ INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+ FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+ INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+ INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
+ INTC_GROUP(ICUSB, ICUSB_ICUSB0, ICUSB_ICUSB1),
+ INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2),
+};
+
+static struct intc_mask_reg intca_mask_registers[] = {
+ { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900048, 0xe6900068, 8, /* INTMSK20A / INTMSKCLR20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690004c, 0xe690006c, 8, /* INTMSK30A / INTMSKCLR30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+ { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+ { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+ AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
+ { 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+ { _2DG, CRYPT_STD, DIRC, 0,
+ DMAC_1_DEI3, DMAC_1_DEI2, DMAC_1_DEI1, DMAC_1_DEI0 } },
+ { 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+ { PINTCA_PINT1, PINTCA_PINT2, 0, 0,
+ BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+ { 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+ { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+ DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+ { 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+ { DDM, 0, 0, 0,
+ 0, 0, 0, 0 } },
+ { 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+ { KEYSC_KEY, DMAC_2_DADERR, DMAC_2_DEI5, DMAC_2_DEI4,
+ SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+ { 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+ { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+ 0, 0, MSIOF2, 0 } },
+ { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+ { DISABLED, DISABLED, ENABLED, ENABLED,
+ FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+ { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+ { DISABLED, DISABLED, ENABLED, ENABLED,
+ TTI20, USBDMAC_USHDMI, 0, MSUG } },
+ { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+ CMT2, USBHS_USHI1, USBHS_USHI0, _3DG_SGX540 } },
+ { 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+ { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+ 0, 0, 0, 0 } },
+ { 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+ { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+ LCRC, MSU_MSU2, IRREM, MSU_MSU } },
+ { 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+ { 0, 0, TPU0, TPU1,
+ TPU2, TPU3, TPU4, 0 } },
+ { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+ { 0, 0, 0, 0,
+ MISTY, CMT3, RWDT1, RWDT0 } },
+ { 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
+ { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
+ 0, 0, 0, 0 } },
+ { 0xe6950090, 0xe69500d0, 8, /* IMR4A3 / IMCR4A3 */
+ { ICUSB_ICUSB0, ICUSB_ICUSB1, 0, 0,
+ ICUDMC_ICUDMC1, ICUDMC_ICUDMC2, 0, 0 } },
+ { 0xe6950094, 0xe69500d4, 8, /* IMR5A3 / IMCR5A3 */
+ { SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
+ SCUV, 0, 0, 0 } },
+ { 0xe6950098, 0xe69500d8, 8, /* IMR6A3 / IMCR6A3 */
+ { IPMMU_IPMMUB, 0, 0, 0,
+ AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+ AP_ARM_DMAIRQ, AP_ARM_DMASIRQ } },
+ { 0xe695009c, 0xe69500dc, 8, /* IMR7A3 / IMCR7A3 */
+ { MFIS2, CPORTR2S, CMT14, CMT15,
+ SCIFA6, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] = {
+ { 0xe6900010, 0, 32, 4, /* INTPRI00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900014, 0, 32, 4, /* INTPRI10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900018, 0, 32, 4, /* INTPRI10A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690001c, 0, 32, 4, /* INTPRI30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+ { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
+ { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
+ { 0xe6940008, 0, 16, 4, /* IPRCA */ { _2DG, CRYPT_STD,
+ CMT1_CMT11, AP_ARM1 } },
+ { 0xe694000c, 0, 16, 4, /* IPRDA */ { PINTCA_PINT1, PINTCA_PINT2,
+ CMT1_CMT12, TPU4 } },
+ { 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC_1, MFI_MFIS,
+ MFI_MFIM, USBHS } },
+ { 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC_2,
+ _3DG_SGX540, CMT1_CMT10 } },
+ { 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+ SCIFA2, SCIFA3 } },
+ { 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBDMAC_USHDMI,
+ FLCTL, SDHI0 } },
+ { 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, MSU_MSU, IIC1 } },
+ { 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2, MSUG, TTI20 } },
+ { 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IRREM, SDHI1 } },
+ { 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, TPU1, TPU2, TPU3 } },
+ { 0xe6940030, 0, 16, 4, /* IPRMA */ { MISTY, CMT3, RWDT1, RWDT0 } },
+ { 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, DDM } },
+ { 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, 0 } },
+ { 0xe6950000, 0, 16, 4, /* IPRAA3 */ { SHWYSTAT, 0, 0, 0 } },
+ { 0xe6950020, 0, 16, 4, /* IPRIA3 */ { ICUSB, 0, 0, 0 } },
+ { 0xe6950024, 0, 16, 4, /* IPRJA3 */ { ICUDMC, 0, 0, 0 } },
+ { 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
+ { 0xe695002c, 0, 16, 4, /* IPRLA3 */ { SCUV, 0, 0, 0 } },
+ { 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU_IPMMUB, 0, 0, 0 } },
+ { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
+ { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
+ CMT14, CMT15 } },
+ { 0xe694003c, 0, 16, 4, /* IPRPA3 */ { SCIFA6, 0, 0, 0 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+ { 0xe6900000, 16, 2, /* ICR1A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900004, 16, 2, /* ICR2A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900008, 16, 2, /* ICR3A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690000c, 16, 2, /* ICR4A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+ { 0xe6900020, 0, 8, /* INTREQ00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900024, 0, 8, /* INTREQ10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900028, 0, 8, /* INTREQ20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690002c, 0, 8, /* INTREQ30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_desc intca_desc __initdata = {
+ .name = "sh7377-intca",
+ .force_enable = ENABLED,
+ .force_disable = DISABLED,
+ .hw = INTC_HW_DESC(intca_vectors, intca_groups,
+ intca_mask_registers, intca_prio_registers,
+ intca_sense_registers, intca_ack_registers),
+};
+
+void __init sh7377_init_irq(void)
+{
+ register_intc_controller(&intca_desc);
+}
diff --git a/arch/arm/mach-shmobile/pfc-sh7367.c b/arch/arm/mach-shmobile/pfc-sh7367.c
new file mode 100644
index 00000000000..128555e76e4
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-sh7367.c
@@ -0,0 +1,1801 @@
+/*
+ * sh7367 processor support - PFC hardware block
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7367.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx) \
+ _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
+ _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
+ _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
+ _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
+ _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _90(fn, pfx, sfx) \
+ _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
+ _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
+ _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
+ _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx), \
+ _10(fn, pfx##9, sfx)
+
+#define _273(fn, pfx, sfx) \
+ _10(fn, pfx, sfx), _90(fn, pfx, sfx), \
+ _10(fn, pfx##10, sfx), _90(fn, pfx##1, sfx), \
+ _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx), \
+ _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx), \
+ _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx), \
+ _10(fn, pfx##26, sfx), _1(fn, pfx##270, sfx), \
+ _1(fn, pfx##271, sfx), _1(fn, pfx##272, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_273(str) _273(_PORT, PORT, str)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PORT_273(DATA), /* PORT0_DATA -> PORT272_DATA */
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PORT_273(IN), /* PORT0_IN -> PORT272_IN */
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_273(IN_PU), /* PORT0_IN_PU -> PORT272_IN_PU */
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_273(IN_PD), /* PORT0_IN_PD -> PORT272_IN_PD */
+ PINMUX_INPUT_PULLDOWN_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PORT_273(OUT), /* PORT0_OUT -> PORT272_OUT */
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_273(FN_IN), /* PORT0_FN_IN -> PORT272_FN_IN */
+ PORT_273(FN_OUT), /* PORT0_FN_OUT -> PORT272_FN_OUT */
+ PORT_273(FN0), /* PORT0_FN0 -> PORT272_FN0 */
+ PORT_273(FN1), /* PORT0_FN1 -> PORT272_FN1 */
+ PORT_273(FN2), /* PORT0_FN2 -> PORT272_FN2 */
+ PORT_273(FN3), /* PORT0_FN3 -> PORT272_FN3 */
+ PORT_273(FN4), /* PORT0_FN4 -> PORT272_FN4 */
+ PORT_273(FN5), /* PORT0_FN5 -> PORT272_FN5 */
+ PORT_273(FN6), /* PORT0_FN6 -> PORT272_FN6 */
+ PORT_273(FN7), /* PORT0_FN7 -> PORT272_FN7 */
+
+ MSELBCR_MSEL2_1, MSELBCR_MSEL2_0,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ /* Special Pull-up / Pull-down Functions */
+ PORT48_KEYIN0_PU_MARK, PORT49_KEYIN1_PU_MARK,
+ PORT50_KEYIN2_PU_MARK, PORT55_KEYIN3_PU_MARK,
+ PORT56_KEYIN4_PU_MARK, PORT57_KEYIN5_PU_MARK,
+ PORT58_KEYIN6_PU_MARK,
+
+ /* 49-1 */
+ VBUS0_MARK, CPORT0_MARK, CPORT1_MARK, CPORT2_MARK,
+ CPORT3_MARK, CPORT4_MARK, CPORT5_MARK, CPORT6_MARK,
+ CPORT7_MARK, CPORT8_MARK, CPORT9_MARK, CPORT10_MARK,
+ CPORT11_MARK, SIN2_MARK, CPORT12_MARK, XCTS2_MARK,
+ CPORT13_MARK, RFSPO4_MARK, CPORT14_MARK, RFSPO5_MARK,
+ CPORT15_MARK, CPORT16_MARK, CPORT17_MARK, SOUT2_MARK,
+ CPORT18_MARK, XRTS2_MARK, CPORT19_MARK, CPORT20_MARK,
+ RFSPO6_MARK, CPORT21_MARK, STATUS0_MARK, CPORT22_MARK,
+ STATUS1_MARK, CPORT23_MARK, STATUS2_MARK, RFSPO7_MARK,
+ MPORT0_MARK, MPORT1_MARK, B_SYNLD1_MARK, B_SYNLD2_MARK,
+ XMAINPS_MARK, XDIVPS_MARK, XIDRST_MARK, IDCLK_MARK,
+ IDIO_MARK, SOUT1_MARK, SCIFA4_TXD_MARK,
+ M02_BERDAT_MARK, SIN1_MARK, SCIFA4_RXD_MARK, XWUP_MARK,
+ XRTS1_MARK, SCIFA4_RTS_MARK, M03_BERCLK_MARK,
+ XCTS1_MARK, SCIFA4_CTS_MARK,
+
+ /* 49-2 */
+ HSU_IQ_AGC6_MARK, MFG2_IN2_MARK, MSIOF2_MCK0_MARK,
+ HSU_IQ_AGC5_MARK, MFG2_IN1_MARK, MSIOF2_MCK1_MARK,
+ HSU_IQ_AGC4_MARK, MSIOF2_RSYNC_MARK,
+ HSU_IQ_AGC3_MARK, MFG2_OUT1_MARK, MSIOF2_RSCK_MARK,
+ HSU_IQ_AGC2_MARK, PORT42_KEYOUT0_MARK,
+ HSU_IQ_AGC1_MARK, PORT43_KEYOUT1_MARK,
+ HSU_IQ_AGC0_MARK, PORT44_KEYOUT2_MARK,
+ HSU_IQ_AGC_ST_MARK, PORT45_KEYOUT3_MARK,
+ HSU_IQ_PDO_MARK, PORT46_KEYOUT4_MARK,
+ HSU_IQ_PYO_MARK, PORT47_KEYOUT5_MARK,
+ HSU_EN_TXMUX_G3MO_MARK, PORT48_KEYIN0_MARK,
+ HSU_I_TXMUX_G3MO_MARK, PORT49_KEYIN1_MARK,
+ HSU_Q_TXMUX_G3MO_MARK, PORT50_KEYIN2_MARK,
+ HSU_SYO_MARK, PORT51_MSIOF2_TSYNC_MARK,
+ HSU_SDO_MARK, PORT52_MSIOF2_TSCK_MARK,
+ HSU_TGTTI_G3MO_MARK, PORT53_MSIOF2_TXD_MARK,
+ B_TIME_STAMP_MARK, PORT54_MSIOF2_RXD_MARK,
+ HSU_SDI_MARK, PORT55_KEYIN3_MARK,
+ HSU_SCO_MARK, PORT56_KEYIN4_MARK,
+ HSU_DREQ_MARK, PORT57_KEYIN5_MARK,
+ HSU_DACK_MARK, PORT58_KEYIN6_MARK,
+ HSU_CLK61M_MARK, PORT59_MSIOF2_SS1_MARK,
+ HSU_XRST_MARK, PORT60_MSIOF2_SS2_MARK,
+ PCMCLKO_MARK, SYNC8KO_MARK, DNPCM_A_MARK, UPPCM_A_MARK,
+ XTALB1L_MARK,
+ GPS_AGC1_MARK, SCIFA0_RTS_MARK,
+ GPS_AGC2_MARK, SCIFA0_SCK_MARK,
+ GPS_AGC3_MARK, SCIFA0_TXD_MARK,
+ GPS_AGC4_MARK, SCIFA0_RXD_MARK,
+ GPS_PWRD_MARK, SCIFA0_CTS_MARK,
+ GPS_IM_MARK, GPS_IS_MARK, GPS_QM_MARK, GPS_QS_MARK,
+ SIUBOMC_MARK, TPU2TO0_MARK,
+ SIUCKB_MARK, TPU2TO1_MARK,
+ SIUBOLR_MARK, BBIF2_TSYNC_MARK, TPU2TO2_MARK,
+ SIUBOBT_MARK, BBIF2_TSCK_MARK, TPU2TO3_MARK,
+ SIUBOSLD_MARK, BBIF2_TXD_MARK, TPU3TO0_MARK,
+ SIUBILR_MARK, TPU3TO1_MARK,
+ SIUBIBT_MARK, TPU3TO2_MARK,
+ SIUBISLD_MARK, TPU3TO3_MARK,
+ NMI_MARK, TPU4TO0_MARK,
+ DNPCM_M_MARK, TPU4TO1_MARK, TPU4TO2_MARK, TPU4TO3_MARK,
+ IRQ_TMPB_MARK,
+ PWEN_MARK, MFG1_OUT1_MARK,
+ OVCN_MARK, MFG1_IN1_MARK,
+ OVCN2_MARK, MFG1_IN2_MARK,
+
+ /* 49-3 */
+ RFSPO1_MARK, RFSPO2_MARK, RFSPO3_MARK, PORT93_VIO_CKO2_MARK,
+ USBTERM_MARK, EXTLP_MARK, IDIN_MARK,
+ SCIFA5_CTS_MARK, MFG0_IN1_MARK,
+ SCIFA5_RTS_MARK, MFG0_IN2_MARK,
+ SCIFA5_RXD_MARK,
+ SCIFA5_TXD_MARK,
+ SCIFA5_SCK_MARK, MFG0_OUT1_MARK,
+ A0_EA0_MARK, BS_MARK,
+ A14_EA14_MARK, PORT102_KEYOUT0_MARK,
+ A15_EA15_MARK, PORT103_KEYOUT1_MARK, DV_CLKOL_MARK,
+ A16_EA16_MARK, PORT104_KEYOUT2_MARK,
+ DV_VSYNCL_MARK, MSIOF0_SS1_MARK,
+ A17_EA17_MARK, PORT105_KEYOUT3_MARK,
+ DV_HSYNCL_MARK, MSIOF0_TSYNC_MARK,
+ A18_EA18_MARK, PORT106_KEYOUT4_MARK,
+ DV_DL0_MARK, MSIOF0_TSCK_MARK,
+ A19_EA19_MARK, PORT107_KEYOUT5_MARK,
+ DV_DL1_MARK, MSIOF0_TXD_MARK,
+ A20_EA20_MARK, PORT108_KEYIN0_MARK,
+ DV_DL2_MARK, MSIOF0_RSCK_MARK,
+ A21_EA21_MARK, PORT109_KEYIN1_MARK,
+ DV_DL3_MARK, MSIOF0_RSYNC_MARK,
+ A22_EA22_MARK, PORT110_KEYIN2_MARK,
+ DV_DL4_MARK, MSIOF0_MCK0_MARK,
+ A23_EA23_MARK, PORT111_KEYIN3_MARK,
+ DV_DL5_MARK, MSIOF0_MCK1_MARK,
+ A24_EA24_MARK, PORT112_KEYIN4_MARK,
+ DV_DL6_MARK, MSIOF0_RXD_MARK,
+ A25_EA25_MARK, PORT113_KEYIN5_MARK,
+ DV_DL7_MARK, MSIOF0_SS2_MARK,
+ A26_MARK, PORT113_KEYIN6_MARK, DV_CLKIL_MARK,
+ D0_ED0_NAF0_MARK, D1_ED1_NAF1_MARK, D2_ED2_NAF2_MARK,
+ D3_ED3_NAF3_MARK, D4_ED4_NAF4_MARK, D5_ED5_NAF5_MARK,
+ D6_ED6_NAF6_MARK, D7_ED7_NAF7_MARK, D8_ED8_NAF8_MARK,
+ D9_ED9_NAF9_MARK, D10_ED10_NAF10_MARK, D11_ED11_NAF11_MARK,
+ D12_ED12_NAF12_MARK, D13_ED13_NAF13_MARK,
+ D14_ED14_NAF14_MARK, D15_ED15_NAF15_MARK,
+ CS4_MARK, CS5A_MARK, CS5B_MARK, FCE1_MARK,
+ CS6B_MARK, XCS2_MARK, FCE0_MARK, CS6A_MARK,
+ DACK0_MARK, WAIT_MARK, DREQ0_MARK, RD_XRD_MARK,
+ A27_MARK, RDWR_XWE_MARK, WE0_XWR0_FWE_MARK,
+ WE1_XWR1_MARK, FRB_MARK, CKO_MARK,
+ NBRSTOUT_MARK, NBRST_MARK,
+
+ /* 49-4 */
+ RFSPO0_MARK, PORT146_VIO_CKO2_MARK, TSTMD_MARK,
+ VIO_VD_MARK, VIO_HD_MARK,
+ VIO_D0_MARK, VIO_D1_MARK, VIO_D2_MARK,
+ VIO_D3_MARK, VIO_D4_MARK, VIO_D5_MARK,
+ VIO_D6_MARK, VIO_D7_MARK, VIO_D8_MARK,
+ VIO_D9_MARK, VIO_D10_MARK, VIO_D11_MARK,
+ VIO_D12_MARK, VIO_D13_MARK, VIO_D14_MARK,
+ VIO_D15_MARK, VIO_CLK_MARK, VIO_FIELD_MARK,
+ VIO_CKO_MARK,
+ MFG3_IN1_MARK, MFG3_IN2_MARK,
+ M9_SLCD_A01_MARK, MFG3_OUT1_MARK, TPU0TO0_MARK,
+ M10_SLCD_CK1_MARK, MFG4_IN1_MARK, TPU0TO1_MARK,
+ M11_SLCD_SO1_MARK, MFG4_IN2_MARK, TPU0TO2_MARK,
+ M12_SLCD_CE1_MARK, MFG4_OUT1_MARK, TPU0TO3_MARK,
+ LCDD0_MARK, PORT175_KEYOUT0_MARK, DV_D0_MARK,
+ SIUCKA_MARK, MFG0_OUT2_MARK,
+ LCDD1_MARK, PORT176_KEYOUT1_MARK, DV_D1_MARK,
+ SIUAOLR_MARK, BBIF2_TSYNC1_MARK,
+ LCDD2_MARK, PORT177_KEYOUT2_MARK, DV_D2_MARK,
+ SIUAOBT_MARK, BBIF2_TSCK1_MARK,
+ LCDD3_MARK, PORT178_KEYOUT3_MARK, DV_D3_MARK,
+ SIUAOSLD_MARK, BBIF2_TXD1_MARK,
+ LCDD4_MARK, PORT179_KEYOUT4_MARK, DV_D4_MARK,
+ SIUAISPD_MARK, MFG1_OUT2_MARK,
+ LCDD5_MARK, PORT180_KEYOUT5_MARK, DV_D5_MARK,
+ SIUAILR_MARK, MFG2_OUT2_MARK,
+ LCDD6_MARK, DV_D6_MARK,
+ SIUAIBT_MARK, MFG3_OUT2_MARK, XWR2_MARK,
+ LCDD7_MARK, DV_D7_MARK,
+ SIUAISLD_MARK, MFG4_OUT2_MARK, XWR3_MARK,
+ LCDD8_MARK, DV_D8_MARK, D16_MARK, ED16_MARK,
+ LCDD9_MARK, DV_D9_MARK, D17_MARK, ED17_MARK,
+ LCDD10_MARK, DV_D10_MARK, D18_MARK, ED18_MARK,
+ LCDD11_MARK, DV_D11_MARK, D19_MARK, ED19_MARK,
+ LCDD12_MARK, DV_D12_MARK, D20_MARK, ED20_MARK,
+ LCDD13_MARK, DV_D13_MARK, D21_MARK, ED21_MARK,
+ LCDD14_MARK, DV_D14_MARK, D22_MARK, ED22_MARK,
+ LCDD15_MARK, DV_D15_MARK, D23_MARK, ED23_MARK,
+ LCDD16_MARK, DV_HSYNC_MARK, D24_MARK, ED24_MARK,
+ LCDD17_MARK, DV_VSYNC_MARK, D25_MARK, ED25_MARK,
+ LCDD18_MARK, DREQ2_MARK, MSIOF0L_TSCK_MARK,
+ D26_MARK, ED26_MARK,
+ LCDD19_MARK, MSIOF0L_TSYNC_MARK,
+ D27_MARK, ED27_MARK,
+ LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK,
+ D28_MARK, ED28_MARK,
+ LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK,
+ D29_MARK, ED29_MARK,
+ LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_SS1_MARK,
+ D30_MARK, ED30_MARK,
+ LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_SS2_MARK,
+ D31_MARK, ED31_MARK,
+ LCDDCK_MARK, LCDWR_MARK, DV_CKO_MARK, SIUAOSPD_MARK,
+ LCDRD_MARK, DACK2_MARK, MSIOF0L_RSYNC_MARK,
+
+ /* 49-5 */
+ LCDHSYN_MARK, LCDCS_MARK, LCDCS2_MARK, DACK3_MARK,
+ LCDDISP_MARK, LCDRS_MARK, DREQ3_MARK, MSIOF0L_RSCK_MARK,
+ LCDCSYN_MARK, LCDCSYN2_MARK, DV_CKI_MARK,
+ LCDLCLK_MARK, DREQ1_MARK, MSIOF0L_RXD_MARK,
+ LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, MSIOF0L_TXD_MARK,
+ VIO_DR0_MARK, VIO_DR1_MARK, VIO_DR2_MARK, VIO_DR3_MARK,
+ VIO_DR4_MARK, VIO_DR5_MARK, VIO_DR6_MARK, VIO_DR7_MARK,
+ VIO_VDR_MARK, VIO_HDR_MARK,
+ VIO_CLKR_MARK, VIO_CKOR_MARK,
+ SCIFA1_TXD_MARK, GPS_PGFA0_MARK,
+ SCIFA1_SCK_MARK, GPS_PGFA1_MARK,
+ SCIFA1_RTS_MARK, GPS_EPPSINMON_MARK,
+ SCIFA1_RXD_MARK, SCIFA1_CTS_MARK,
+ MSIOF1_TXD_MARK, SCIFA1_TXD2_MARK, GPS_TXD_MARK,
+ MSIOF1_TSYNC_MARK, SCIFA1_CTS2_MARK, I2C_SDA2_MARK,
+ MSIOF1_TSCK_MARK, SCIFA1_SCK2_MARK,
+ MSIOF1_RXD_MARK, SCIFA1_RXD2_MARK, GPS_RXD_MARK,
+ MSIOF1_RSCK_MARK, SCIFA1_RTS2_MARK,
+ MSIOF1_RSYNC_MARK, I2C_SCL2_MARK,
+ MSIOF1_MCK0_MARK, MSIOF1_MCK1_MARK,
+ MSIOF1_SS1_MARK, EDBGREQ3_MARK,
+ MSIOF1_SS2_MARK,
+ PORT236_IROUT_MARK, IRDA_OUT_MARK,
+ IRDA_IN_MARK, IRDA_FIRSEL_MARK,
+ TPU1TO0_MARK, TS_SPSYNC3_MARK,
+ TPU1TO1_MARK, TS_SDAT3_MARK,
+ TPU1TO2_MARK, TS_SDEN3_MARK, PORT241_MSIOF2_SS1_MARK,
+ TPU1TO3_MARK, PORT242_MSIOF2_TSCK_MARK,
+ M13_BSW_MARK, PORT243_MSIOF2_TSYNC_MARK,
+ M14_GSW_MARK, PORT244_MSIOF2_TXD_MARK,
+ PORT245_IROUT_MARK, M15_RSW_MARK,
+ SOUT3_MARK, SCIFA2_TXD1_MARK,
+ SIN3_MARK, SCIFA2_RXD1_MARK,
+ XRTS3_MARK, SCIFA2_RTS1_MARK, PORT248_MSIOF2_SS2_MARK,
+ XCTS3_MARK, SCIFA2_CTS1_MARK, PORT249_MSIOF2_RXD_MARK,
+ DINT_MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
+ SDHICLK0_MARK, TCK2_MARK,
+ SDHICD0_MARK,
+ SDHID0_0_MARK, TMS2_MARK,
+ SDHID0_1_MARK, TDO2_MARK,
+ SDHID0_2_MARK, TDI2_MARK,
+ SDHID0_3_MARK, RTCK2_MARK,
+
+ /* 49-6 */
+ SDHICMD0_MARK, TRST2_MARK,
+ SDHIWP0_MARK, EDBGREQ2_MARK,
+ SDHICLK1_MARK, TCK3_MARK,
+ SDHID1_0_MARK, M11_SLCD_SO2_MARK,
+ TS_SPSYNC2_MARK, TMS3_MARK,
+ SDHID1_1_MARK, M9_SLCD_AO2_MARK,
+ TS_SDAT2_MARK, TDO3_MARK,
+ SDHID1_2_MARK, M10_SLCD_CK2_MARK,
+ TS_SDEN2_MARK, TDI3_MARK,
+ SDHID1_3_MARK, M12_SLCD_CE2_MARK,
+ TS_SCK2_MARK, RTCK3_MARK,
+ SDHICMD1_MARK, TRST3_MARK,
+ SDHICLK2_MARK, SCIFB_SCK_MARK,
+ SDHID2_0_MARK, SCIFB_TXD_MARK,
+ SDHID2_1_MARK, SCIFB_CTS_MARK,
+ SDHID2_2_MARK, SCIFB_RXD_MARK,
+ SDHID2_3_MARK, SCIFB_RTS_MARK,
+ SDHICMD2_MARK,
+ RESETOUTS_MARK,
+ DIVLOCK_MARK,
+ PINMUX_MARK_END,
+};
+
+#define PORT_DATA_I(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+
+static pinmux_enum_t pinmux_data[] = {
+
+ /* specify valid pin states for each pin in GPIO mode */
+
+ /* 49-1 (GPIO) */
+ PORT_DATA_I_PD(0),
+ PORT_DATA_I_PU(1), PORT_DATA_I_PU(2), PORT_DATA_I_PU(3),
+ PORT_DATA_I_PU(4), PORT_DATA_I_PU(5), PORT_DATA_I_PU(6),
+ PORT_DATA_I_PU(7), PORT_DATA_I_PU(8), PORT_DATA_I_PU(9),
+ PORT_DATA_I_PU(10), PORT_DATA_I_PU(11), PORT_DATA_I_PU(12),
+ PORT_DATA_I_PU(13),
+ PORT_DATA_IO_PU_PD(14), PORT_DATA_IO_PU_PD(15),
+ PORT_DATA_O(16), PORT_DATA_O(17), PORT_DATA_O(18), PORT_DATA_O(19),
+ PORT_DATA_O(20), PORT_DATA_O(21), PORT_DATA_O(22), PORT_DATA_O(23),
+ PORT_DATA_O(24), PORT_DATA_O(25), PORT_DATA_O(26),
+ PORT_DATA_I_PD(27), PORT_DATA_I_PD(28),
+ PORT_DATA_O(29), PORT_DATA_O(30), PORT_DATA_O(31), PORT_DATA_O(32),
+ PORT_DATA_IO_PU(33),
+ PORT_DATA_O(34),
+ PORT_DATA_I_PU(35),
+ PORT_DATA_O(36),
+ PORT_DATA_I_PU_PD(37),
+
+ /* 49-2 (GPIO) */
+ PORT_DATA_IO_PU_PD(38),
+ PORT_DATA_IO_PD(39), PORT_DATA_IO_PD(40), PORT_DATA_IO_PD(41),
+ PORT_DATA_O(42), PORT_DATA_O(43), PORT_DATA_O(44), PORT_DATA_O(45),
+ PORT_DATA_O(46), PORT_DATA_O(47),
+ PORT_DATA_I_PU_PD(48), PORT_DATA_I_PU_PD(49), PORT_DATA_I_PU_PD(50),
+ PORT_DATA_IO_PD(51), PORT_DATA_IO_PD(52),
+ PORT_DATA_O(53),
+ PORT_DATA_IO_PD(54),
+ PORT_DATA_I_PU_PD(55),
+ PORT_DATA_IO_PU_PD(56),
+ PORT_DATA_I_PU_PD(57),
+ PORT_DATA_IO_PU_PD(58),
+ PORT_DATA_O(59), PORT_DATA_O(60), PORT_DATA_O(61), PORT_DATA_O(62),
+ PORT_DATA_O(63),
+ PORT_DATA_I_PU(64),
+ PORT_DATA_O(65), PORT_DATA_O(66), PORT_DATA_O(67), PORT_DATA_O(68),
+ PORT_DATA_IO_PD(69), PORT_DATA_IO_PD(70),
+ PORT_DATA_I_PD(71), PORT_DATA_I_PD(72), PORT_DATA_I_PD(73),
+ PORT_DATA_I_PD(74),
+ PORT_DATA_IO_PU_PD(75), PORT_DATA_IO_PU_PD(76),
+ PORT_DATA_IO_PD(77), PORT_DATA_IO_PD(78),
+ PORT_DATA_O(79),
+ PORT_DATA_IO_PD(80), PORT_DATA_IO_PD(81), PORT_DATA_IO_PD(82),
+ PORT_DATA_IO_PU_PD(83), PORT_DATA_IO_PU_PD(84),
+ PORT_DATA_IO_PU_PD(85), PORT_DATA_IO_PU_PD(86),
+ PORT_DATA_I_PD(87),
+ PORT_DATA_IO_PU_PD(88),
+ PORT_DATA_I_PU_PD(89), PORT_DATA_I_PU_PD(90),
+
+ /* 49-3 (GPIO) */
+ PORT_DATA_O(91), PORT_DATA_O(92), PORT_DATA_O(93), PORT_DATA_O(94),
+ PORT_DATA_I_PU_PD(95),
+ PORT_DATA_IO_PU_PD(96), PORT_DATA_IO_PU_PD(97), PORT_DATA_IO_PU_PD(98),
+ PORT_DATA_IO_PU_PD(99), PORT_DATA_IO_PU_PD(100),
+ PORT_DATA_IO(101), PORT_DATA_IO(102), PORT_DATA_IO(103),
+ PORT_DATA_IO_PD(104), PORT_DATA_IO_PD(105), PORT_DATA_IO_PD(106),
+ PORT_DATA_IO_PD(107),
+ PORT_DATA_IO_PU_PD(108), PORT_DATA_IO_PU_PD(109),
+ PORT_DATA_IO_PU_PD(110), PORT_DATA_IO_PU_PD(111),
+ PORT_DATA_IO_PU_PD(112), PORT_DATA_IO_PU_PD(113),
+ PORT_DATA_IO_PU_PD(114),
+ PORT_DATA_IO_PU(115), PORT_DATA_IO_PU(116), PORT_DATA_IO_PU(117),
+ PORT_DATA_IO_PU(118), PORT_DATA_IO_PU(119), PORT_DATA_IO_PU(120),
+ PORT_DATA_IO_PU(121), PORT_DATA_IO_PU(122), PORT_DATA_IO_PU(123),
+ PORT_DATA_IO_PU(124), PORT_DATA_IO_PU(125), PORT_DATA_IO_PU(126),
+ PORT_DATA_IO_PU(127), PORT_DATA_IO_PU(128), PORT_DATA_IO_PU(129),
+ PORT_DATA_IO_PU(130),
+ PORT_DATA_O(131), PORT_DATA_O(132), PORT_DATA_O(133),
+ PORT_DATA_IO_PU(134),
+ PORT_DATA_O(135), PORT_DATA_O(136),
+ PORT_DATA_I_PU_PD(137),
+ PORT_DATA_IO(138),
+ PORT_DATA_IO_PU_PD(139),
+ PORT_DATA_IO(140), PORT_DATA_IO(141),
+ PORT_DATA_I_PU(142),
+ PORT_DATA_O(143), PORT_DATA_O(144),
+ PORT_DATA_I_PU(145),
+
+ /* 49-4 (GPIO) */
+ PORT_DATA_O(146),
+ PORT_DATA_I_PU_PD(147),
+ PORT_DATA_I_PD(148), PORT_DATA_I_PD(149),
+ PORT_DATA_IO_PD(150), PORT_DATA_IO_PD(151), PORT_DATA_IO_PD(152),
+ PORT_DATA_IO_PD(153), PORT_DATA_IO_PD(154), PORT_DATA_IO_PD(155),
+ PORT_DATA_IO_PD(156), PORT_DATA_IO_PD(157), PORT_DATA_IO_PD(158),
+ PORT_DATA_IO_PD(159), PORT_DATA_IO_PD(160), PORT_DATA_IO_PD(161),
+ PORT_DATA_IO_PD(162), PORT_DATA_IO_PD(163), PORT_DATA_IO_PD(164),
+ PORT_DATA_IO_PD(165), PORT_DATA_IO_PD(166),
+ PORT_DATA_IO_PU_PD(167),
+ PORT_DATA_O(168),
+ PORT_DATA_I_PD(169), PORT_DATA_I_PD(170),
+ PORT_DATA_O(171),
+ PORT_DATA_IO_PD(172), PORT_DATA_IO_PD(173),
+ PORT_DATA_O(174),
+ PORT_DATA_IO_PD(175), PORT_DATA_IO_PD(176), PORT_DATA_IO_PD(177),
+ PORT_DATA_IO_PD(178), PORT_DATA_IO_PD(179), PORT_DATA_IO_PD(180),
+ PORT_DATA_IO_PD(181), PORT_DATA_IO_PD(182), PORT_DATA_IO_PD(183),
+ PORT_DATA_IO_PD(184), PORT_DATA_IO_PD(185), PORT_DATA_IO_PD(186),
+ PORT_DATA_IO_PD(187), PORT_DATA_IO_PD(188), PORT_DATA_IO_PD(189),
+ PORT_DATA_IO_PD(190), PORT_DATA_IO_PD(191), PORT_DATA_IO_PD(192),
+ PORT_DATA_IO_PD(193), PORT_DATA_IO_PD(194), PORT_DATA_IO_PD(195),
+ PORT_DATA_IO_PD(196), PORT_DATA_IO_PD(197), PORT_DATA_IO_PD(198),
+ PORT_DATA_O(199),
+ PORT_DATA_IO_PD(200),
+
+ /* 49-5 (GPIO) */
+ PORT_DATA_O(201),
+ PORT_DATA_IO_PD(202), PORT_DATA_IO_PD(203),
+ PORT_DATA_I(204),
+ PORT_DATA_O(205),
+ PORT_DATA_IO_PD(206), PORT_DATA_IO_PD(207), PORT_DATA_IO_PD(208),
+ PORT_DATA_IO_PD(209), PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
+ PORT_DATA_IO_PD(212), PORT_DATA_IO_PD(213), PORT_DATA_IO_PD(214),
+ PORT_DATA_IO_PD(215), PORT_DATA_IO_PD(216),
+ PORT_DATA_O(217),
+ PORT_DATA_I_PU_PD(218), PORT_DATA_I_PU_PD(219),
+ PORT_DATA_O(220), PORT_DATA_O(221), PORT_DATA_O(222),
+ PORT_DATA_I_PD(223),
+ PORT_DATA_I_PU_PD(224),
+ PORT_DATA_O(225),
+ PORT_DATA_IO_PD(226),
+ PORT_DATA_IO_PU_PD(227),
+ PORT_DATA_I_PD(228),
+ PORT_DATA_IO_PD(229), PORT_DATA_IO_PD(230),
+ PORT_DATA_I_PU_PD(231), PORT_DATA_I_PU_PD(232),
+ PORT_DATA_IO_PU_PD(233), PORT_DATA_IO_PU_PD(234),
+ PORT_DATA_I_PU_PD(235),
+ PORT_DATA_O(236),
+ PORT_DATA_I_PD(237),
+ PORT_DATA_IO_PU_PD(238), PORT_DATA_IO_PU_PD(239),
+ PORT_DATA_IO_PD(240), PORT_DATA_IO_PD(241),
+ PORT_DATA_IO_PD(242), PORT_DATA_IO_PD(243),
+ PORT_DATA_O(244),
+ PORT_DATA_IO_PU_PD(245),
+ PORT_DATA_O(246),
+ PORT_DATA_I_PD(247),
+ PORT_DATA_IO_PU_PD(248),
+ PORT_DATA_I_PU_PD(249),
+ PORT_DATA_IO_PD(250), PORT_DATA_IO_PD(251),
+ PORT_DATA_IO_PU_PD(252), PORT_DATA_IO_PU_PD(253),
+ PORT_DATA_IO_PU_PD(254), PORT_DATA_IO_PU_PD(255),
+ PORT_DATA_IO_PU_PD(256),
+
+ /* 49-6 (GPIO) */
+ PORT_DATA_IO_PU_PD(257), PORT_DATA_IO_PU_PD(258),
+ PORT_DATA_IO_PD(259),
+ PORT_DATA_IO_PU(260), PORT_DATA_IO_PU(261), PORT_DATA_IO_PU(262),
+ PORT_DATA_IO_PU(263), PORT_DATA_IO_PU(264),
+ PORT_DATA_O(265),
+ PORT_DATA_IO_PU(266), PORT_DATA_IO_PU(267), PORT_DATA_IO_PU(268),
+ PORT_DATA_IO_PU(269), PORT_DATA_IO_PU(270),
+ PORT_DATA_O(271),
+ PORT_DATA_I_PD(272),
+
+ /* Special Pull-up / Pull-down Functions */
+ PINMUX_DATA(PORT48_KEYIN0_PU_MARK, MSELBCR_MSEL2_1,
+ PORT48_FN2, PORT48_IN_PU),
+ PINMUX_DATA(PORT49_KEYIN1_PU_MARK, MSELBCR_MSEL2_1,
+ PORT49_FN2, PORT49_IN_PU),
+ PINMUX_DATA(PORT50_KEYIN2_PU_MARK, MSELBCR_MSEL2_1,
+ PORT50_FN2, PORT50_IN_PU),
+ PINMUX_DATA(PORT55_KEYIN3_PU_MARK, MSELBCR_MSEL2_1,
+ PORT55_FN2, PORT55_IN_PU),
+ PINMUX_DATA(PORT56_KEYIN4_PU_MARK, MSELBCR_MSEL2_1,
+ PORT56_FN2, PORT56_IN_PU),
+ PINMUX_DATA(PORT57_KEYIN5_PU_MARK, MSELBCR_MSEL2_1,
+ PORT57_FN2, PORT57_IN_PU),
+ PINMUX_DATA(PORT58_KEYIN6_PU_MARK, MSELBCR_MSEL2_1,
+ PORT58_FN2, PORT58_IN_PU),
+
+ /* 49-1 (FN) */
+ PINMUX_DATA(VBUS0_MARK, PORT0_FN1),
+ PINMUX_DATA(CPORT0_MARK, PORT1_FN1),
+ PINMUX_DATA(CPORT1_MARK, PORT2_FN1),
+ PINMUX_DATA(CPORT2_MARK, PORT3_FN1),
+ PINMUX_DATA(CPORT3_MARK, PORT4_FN1),
+ PINMUX_DATA(CPORT4_MARK, PORT5_FN1),
+ PINMUX_DATA(CPORT5_MARK, PORT6_FN1),
+ PINMUX_DATA(CPORT6_MARK, PORT7_FN1),
+ PINMUX_DATA(CPORT7_MARK, PORT8_FN1),
+ PINMUX_DATA(CPORT8_MARK, PORT9_FN1),
+ PINMUX_DATA(CPORT9_MARK, PORT10_FN1),
+ PINMUX_DATA(CPORT10_MARK, PORT11_FN1),
+ PINMUX_DATA(CPORT11_MARK, PORT12_FN1),
+ PINMUX_DATA(SIN2_MARK, PORT12_FN2),
+ PINMUX_DATA(CPORT12_MARK, PORT13_FN1),
+ PINMUX_DATA(XCTS2_MARK, PORT13_FN2),
+ PINMUX_DATA(CPORT13_MARK, PORT14_FN1),
+ PINMUX_DATA(RFSPO4_MARK, PORT14_FN2),
+ PINMUX_DATA(CPORT14_MARK, PORT15_FN1),
+ PINMUX_DATA(RFSPO5_MARK, PORT15_FN2),
+ PINMUX_DATA(CPORT15_MARK, PORT16_FN1),
+ PINMUX_DATA(CPORT16_MARK, PORT17_FN1),
+ PINMUX_DATA(CPORT17_MARK, PORT18_FN1),
+ PINMUX_DATA(SOUT2_MARK, PORT18_FN2),
+ PINMUX_DATA(CPORT18_MARK, PORT19_FN1),
+ PINMUX_DATA(XRTS2_MARK, PORT19_FN1),
+ PINMUX_DATA(CPORT19_MARK, PORT20_FN1),
+ PINMUX_DATA(CPORT20_MARK, PORT21_FN1),
+ PINMUX_DATA(RFSPO6_MARK, PORT21_FN2),
+ PINMUX_DATA(CPORT21_MARK, PORT22_FN1),
+ PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
+ PINMUX_DATA(CPORT22_MARK, PORT23_FN1),
+ PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
+ PINMUX_DATA(CPORT23_MARK, PORT24_FN1),
+ PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
+ PINMUX_DATA(RFSPO7_MARK, PORT24_FN3),
+ PINMUX_DATA(MPORT0_MARK, PORT25_FN1),
+ PINMUX_DATA(MPORT1_MARK, PORT26_FN1),
+ PINMUX_DATA(B_SYNLD1_MARK, PORT27_FN1),
+ PINMUX_DATA(B_SYNLD2_MARK, PORT28_FN1),
+ PINMUX_DATA(XMAINPS_MARK, PORT29_FN1),
+ PINMUX_DATA(XDIVPS_MARK, PORT30_FN1),
+ PINMUX_DATA(XIDRST_MARK, PORT31_FN1),
+ PINMUX_DATA(IDCLK_MARK, PORT32_FN1),
+ PINMUX_DATA(IDIO_MARK, PORT33_FN1),
+ PINMUX_DATA(SOUT1_MARK, PORT34_FN1),
+ PINMUX_DATA(SCIFA4_TXD_MARK, PORT34_FN2),
+ PINMUX_DATA(M02_BERDAT_MARK, PORT34_FN3),
+ PINMUX_DATA(SIN1_MARK, PORT35_FN1),
+ PINMUX_DATA(SCIFA4_RXD_MARK, PORT35_FN2),
+ PINMUX_DATA(XWUP_MARK, PORT35_FN3),
+ PINMUX_DATA(XRTS1_MARK, PORT36_FN1),
+ PINMUX_DATA(SCIFA4_RTS_MARK, PORT36_FN2),
+ PINMUX_DATA(M03_BERCLK_MARK, PORT36_FN3),
+ PINMUX_DATA(XCTS1_MARK, PORT37_FN1),
+ PINMUX_DATA(SCIFA4_CTS_MARK, PORT37_FN2),
+
+ /* 49-2 (FN) */
+ PINMUX_DATA(HSU_IQ_AGC6_MARK, PORT38_FN1),
+ PINMUX_DATA(MFG2_IN2_MARK, PORT38_FN2),
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT38_FN3),
+ PINMUX_DATA(HSU_IQ_AGC5_MARK, PORT39_FN1),
+ PINMUX_DATA(MFG2_IN1_MARK, PORT39_FN2),
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT39_FN3),
+ PINMUX_DATA(HSU_IQ_AGC4_MARK, PORT40_FN1),
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT40_FN3),
+ PINMUX_DATA(HSU_IQ_AGC3_MARK, PORT41_FN1),
+ PINMUX_DATA(MFG2_OUT1_MARK, PORT41_FN2),
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT41_FN3),
+ PINMUX_DATA(HSU_IQ_AGC2_MARK, PORT42_FN1),
+ PINMUX_DATA(PORT42_KEYOUT0_MARK, MSELBCR_MSEL2_1, PORT42_FN2),
+ PINMUX_DATA(HSU_IQ_AGC1_MARK, PORT43_FN1),
+ PINMUX_DATA(PORT43_KEYOUT1_MARK, MSELBCR_MSEL2_1, PORT43_FN2),
+ PINMUX_DATA(HSU_IQ_AGC0_MARK, PORT44_FN1),
+ PINMUX_DATA(PORT44_KEYOUT2_MARK, MSELBCR_MSEL2_1, PORT44_FN2),
+ PINMUX_DATA(HSU_IQ_AGC_ST_MARK, PORT45_FN1),
+ PINMUX_DATA(PORT45_KEYOUT3_MARK, MSELBCR_MSEL2_1, PORT45_FN2),
+ PINMUX_DATA(HSU_IQ_PDO_MARK, PORT46_FN1),
+ PINMUX_DATA(PORT46_KEYOUT4_MARK, MSELBCR_MSEL2_1, PORT46_FN2),
+ PINMUX_DATA(HSU_IQ_PYO_MARK, PORT47_FN1),
+ PINMUX_DATA(PORT47_KEYOUT5_MARK, MSELBCR_MSEL2_1, PORT47_FN2),
+ PINMUX_DATA(HSU_EN_TXMUX_G3MO_MARK, PORT48_FN1),
+ PINMUX_DATA(PORT48_KEYIN0_MARK, MSELBCR_MSEL2_1, PORT48_FN2),
+ PINMUX_DATA(HSU_I_TXMUX_G3MO_MARK, PORT49_FN1),
+ PINMUX_DATA(PORT49_KEYIN1_MARK, MSELBCR_MSEL2_1, PORT49_FN2),
+ PINMUX_DATA(HSU_Q_TXMUX_G3MO_MARK, PORT50_FN1),
+ PINMUX_DATA(PORT50_KEYIN2_MARK, MSELBCR_MSEL2_1, PORT50_FN2),
+ PINMUX_DATA(HSU_SYO_MARK, PORT51_FN1),
+ PINMUX_DATA(PORT51_MSIOF2_TSYNC_MARK, PORT51_FN2),
+ PINMUX_DATA(HSU_SDO_MARK, PORT52_FN1),
+ PINMUX_DATA(PORT52_MSIOF2_TSCK_MARK, PORT52_FN2),
+ PINMUX_DATA(HSU_TGTTI_G3MO_MARK, PORT53_FN1),
+ PINMUX_DATA(PORT53_MSIOF2_TXD_MARK, PORT53_FN2),
+ PINMUX_DATA(B_TIME_STAMP_MARK, PORT54_FN1),
+ PINMUX_DATA(PORT54_MSIOF2_RXD_MARK, PORT54_FN2),
+ PINMUX_DATA(HSU_SDI_MARK, PORT55_FN1),
+ PINMUX_DATA(PORT55_KEYIN3_MARK, MSELBCR_MSEL2_1, PORT55_FN2),
+ PINMUX_DATA(HSU_SCO_MARK, PORT56_FN1),
+ PINMUX_DATA(PORT56_KEYIN4_MARK, MSELBCR_MSEL2_1, PORT56_FN2),
+ PINMUX_DATA(HSU_DREQ_MARK, PORT57_FN1),
+ PINMUX_DATA(PORT57_KEYIN5_MARK, MSELBCR_MSEL2_1, PORT57_FN2),
+ PINMUX_DATA(HSU_DACK_MARK, PORT58_FN1),
+ PINMUX_DATA(PORT58_KEYIN6_MARK, MSELBCR_MSEL2_1, PORT58_FN2),
+ PINMUX_DATA(HSU_CLK61M_MARK, PORT59_FN1),
+ PINMUX_DATA(PORT59_MSIOF2_SS1_MARK, PORT59_FN2),
+ PINMUX_DATA(HSU_XRST_MARK, PORT60_FN1),
+ PINMUX_DATA(PORT60_MSIOF2_SS2_MARK, PORT60_FN2),
+ PINMUX_DATA(PCMCLKO_MARK, PORT61_FN1),
+ PINMUX_DATA(SYNC8KO_MARK, PORT62_FN1),
+ PINMUX_DATA(DNPCM_A_MARK, PORT63_FN1),
+ PINMUX_DATA(UPPCM_A_MARK, PORT64_FN1),
+ PINMUX_DATA(XTALB1L_MARK, PORT65_FN1),
+ PINMUX_DATA(GPS_AGC1_MARK, PORT66_FN1),
+ PINMUX_DATA(SCIFA0_RTS_MARK, PORT66_FN2),
+ PINMUX_DATA(GPS_AGC2_MARK, PORT67_FN1),
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT67_FN2),
+ PINMUX_DATA(GPS_AGC3_MARK, PORT68_FN1),
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT68_FN2),
+ PINMUX_DATA(GPS_AGC4_MARK, PORT69_FN1),
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT69_FN2),
+ PINMUX_DATA(GPS_PWRD_MARK, PORT70_FN1),
+ PINMUX_DATA(SCIFA0_CTS_MARK, PORT70_FN2),
+ PINMUX_DATA(GPS_IM_MARK, PORT71_FN1),
+ PINMUX_DATA(GPS_IS_MARK, PORT72_FN1),
+ PINMUX_DATA(GPS_QM_MARK, PORT73_FN1),
+ PINMUX_DATA(GPS_QS_MARK, PORT74_FN1),
+ PINMUX_DATA(SIUBOMC_MARK, PORT75_FN1),
+ PINMUX_DATA(TPU2TO0_MARK, PORT75_FN3),
+ PINMUX_DATA(SIUCKB_MARK, PORT76_FN1),
+ PINMUX_DATA(TPU2TO1_MARK, PORT76_FN3),
+ PINMUX_DATA(SIUBOLR_MARK, PORT77_FN1),
+ PINMUX_DATA(BBIF2_TSYNC_MARK, PORT77_FN2),
+ PINMUX_DATA(TPU2TO2_MARK, PORT77_FN3),
+ PINMUX_DATA(SIUBOBT_MARK, PORT78_FN1),
+ PINMUX_DATA(BBIF2_TSCK_MARK, PORT78_FN2),
+ PINMUX_DATA(TPU2TO3_MARK, PORT78_FN3),
+ PINMUX_DATA(SIUBOSLD_MARK, PORT79_FN1),
+ PINMUX_DATA(BBIF2_TXD_MARK, PORT79_FN2),
+ PINMUX_DATA(TPU3TO0_MARK, PORT79_FN3),
+ PINMUX_DATA(SIUBILR_MARK, PORT80_FN1),
+ PINMUX_DATA(TPU3TO1_MARK, PORT80_FN3),
+ PINMUX_DATA(SIUBIBT_MARK, PORT81_FN1),
+ PINMUX_DATA(TPU3TO2_MARK, PORT81_FN3),
+ PINMUX_DATA(SIUBISLD_MARK, PORT82_FN1),
+ PINMUX_DATA(TPU3TO3_MARK, PORT82_FN3),
+ PINMUX_DATA(NMI_MARK, PORT83_FN1),
+ PINMUX_DATA(TPU4TO0_MARK, PORT83_FN3),
+ PINMUX_DATA(DNPCM_M_MARK, PORT84_FN1),
+ PINMUX_DATA(TPU4TO1_MARK, PORT84_FN3),
+ PINMUX_DATA(TPU4TO2_MARK, PORT85_FN3),
+ PINMUX_DATA(TPU4TO3_MARK, PORT86_FN3),
+ PINMUX_DATA(IRQ_TMPB_MARK, PORT87_FN1),
+ PINMUX_DATA(PWEN_MARK, PORT88_FN1),
+ PINMUX_DATA(MFG1_OUT1_MARK, PORT88_FN2),
+ PINMUX_DATA(OVCN_MARK, PORT89_FN1),
+ PINMUX_DATA(MFG1_IN1_MARK, PORT89_FN2),
+ PINMUX_DATA(OVCN2_MARK, PORT90_FN1),
+ PINMUX_DATA(MFG1_IN2_MARK, PORT90_FN2),
+
+ /* 49-3 (FN) */
+ PINMUX_DATA(RFSPO1_MARK, PORT91_FN1),
+ PINMUX_DATA(RFSPO2_MARK, PORT92_FN1),
+ PINMUX_DATA(RFSPO3_MARK, PORT93_FN1),
+ PINMUX_DATA(PORT93_VIO_CKO2_MARK, PORT93_FN2),
+ PINMUX_DATA(USBTERM_MARK, PORT94_FN1),
+ PINMUX_DATA(EXTLP_MARK, PORT94_FN2),
+ PINMUX_DATA(IDIN_MARK, PORT95_FN1),
+ PINMUX_DATA(SCIFA5_CTS_MARK, PORT96_FN1),
+ PINMUX_DATA(MFG0_IN1_MARK, PORT96_FN2),
+ PINMUX_DATA(SCIFA5_RTS_MARK, PORT97_FN1),
+ PINMUX_DATA(MFG0_IN2_MARK, PORT97_FN2),
+ PINMUX_DATA(SCIFA5_RXD_MARK, PORT98_FN1),
+ PINMUX_DATA(SCIFA5_TXD_MARK, PORT99_FN1),
+ PINMUX_DATA(SCIFA5_SCK_MARK, PORT100_FN1),
+ PINMUX_DATA(MFG0_OUT1_MARK, PORT100_FN2),
+ PINMUX_DATA(A0_EA0_MARK, PORT101_FN1),
+ PINMUX_DATA(BS_MARK, PORT101_FN2),
+ PINMUX_DATA(A14_EA14_MARK, PORT102_FN1),
+ PINMUX_DATA(PORT102_KEYOUT0_MARK, MSELBCR_MSEL2_0, PORT102_FN2),
+ PINMUX_DATA(A15_EA15_MARK, PORT103_FN1),
+ PINMUX_DATA(PORT103_KEYOUT1_MARK, MSELBCR_MSEL2_0, PORT103_FN2),
+ PINMUX_DATA(DV_CLKOL_MARK, PORT103_FN3),
+ PINMUX_DATA(A16_EA16_MARK, PORT104_FN1),
+ PINMUX_DATA(PORT104_KEYOUT2_MARK, MSELBCR_MSEL2_0, PORT104_FN2),
+ PINMUX_DATA(DV_VSYNCL_MARK, PORT104_FN3),
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT104_FN4),
+ PINMUX_DATA(A17_EA17_MARK, PORT105_FN1),
+ PINMUX_DATA(PORT105_KEYOUT3_MARK, MSELBCR_MSEL2_0, PORT105_FN2),
+ PINMUX_DATA(DV_HSYNCL_MARK, PORT105_FN3),
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT105_FN4),
+ PINMUX_DATA(A18_EA18_MARK, PORT106_FN1),
+ PINMUX_DATA(PORT106_KEYOUT4_MARK, MSELBCR_MSEL2_0, PORT106_FN2),
+ PINMUX_DATA(DV_DL0_MARK, PORT106_FN3),
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT106_FN4),
+ PINMUX_DATA(A19_EA19_MARK, PORT107_FN1),
+ PINMUX_DATA(PORT107_KEYOUT5_MARK, MSELBCR_MSEL2_0, PORT107_FN2),
+ PINMUX_DATA(DV_DL1_MARK, PORT107_FN3),
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT107_FN4),
+ PINMUX_DATA(A20_EA20_MARK, PORT108_FN1),
+ PINMUX_DATA(PORT108_KEYIN0_MARK, MSELBCR_MSEL2_0, PORT108_FN2),
+ PINMUX_DATA(DV_DL2_MARK, PORT108_FN3),
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT108_FN4),
+ PINMUX_DATA(A21_EA21_MARK, PORT109_FN1),
+ PINMUX_DATA(PORT109_KEYIN1_MARK, MSELBCR_MSEL2_0, PORT109_FN2),
+ PINMUX_DATA(DV_DL3_MARK, PORT109_FN3),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT109_FN4),
+ PINMUX_DATA(A22_EA22_MARK, PORT110_FN1),
+ PINMUX_DATA(PORT110_KEYIN2_MARK, MSELBCR_MSEL2_0, PORT110_FN2),
+ PINMUX_DATA(DV_DL4_MARK, PORT110_FN3),
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT110_FN4),
+ PINMUX_DATA(A23_EA23_MARK, PORT111_FN1),
+ PINMUX_DATA(PORT111_KEYIN3_MARK, MSELBCR_MSEL2_0, PORT111_FN2),
+ PINMUX_DATA(DV_DL5_MARK, PORT111_FN3),
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT111_FN4),
+ PINMUX_DATA(A24_EA24_MARK, PORT112_FN1),
+ PINMUX_DATA(PORT112_KEYIN4_MARK, MSELBCR_MSEL2_0, PORT112_FN2),
+ PINMUX_DATA(DV_DL6_MARK, PORT112_FN3),
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT112_FN4),
+ PINMUX_DATA(A25_EA25_MARK, PORT113_FN1),
+ PINMUX_DATA(PORT113_KEYIN5_MARK, MSELBCR_MSEL2_0, PORT113_FN2),
+ PINMUX_DATA(DV_DL7_MARK, PORT113_FN3),
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT113_FN4),
+ PINMUX_DATA(A26_MARK, PORT114_FN1),
+ PINMUX_DATA(PORT113_KEYIN6_MARK, MSELBCR_MSEL2_0, PORT114_FN2),
+ PINMUX_DATA(DV_CLKIL_MARK, PORT114_FN3),
+ PINMUX_DATA(D0_ED0_NAF0_MARK, PORT115_FN1),
+ PINMUX_DATA(D1_ED1_NAF1_MARK, PORT116_FN1),
+ PINMUX_DATA(D2_ED2_NAF2_MARK, PORT117_FN1),
+ PINMUX_DATA(D3_ED3_NAF3_MARK, PORT118_FN1),
+ PINMUX_DATA(D4_ED4_NAF4_MARK, PORT119_FN1),
+ PINMUX_DATA(D5_ED5_NAF5_MARK, PORT120_FN1),
+ PINMUX_DATA(D6_ED6_NAF6_MARK, PORT121_FN1),
+ PINMUX_DATA(D7_ED7_NAF7_MARK, PORT122_FN1),
+ PINMUX_DATA(D8_ED8_NAF8_MARK, PORT123_FN1),
+ PINMUX_DATA(D9_ED9_NAF9_MARK, PORT124_FN1),
+ PINMUX_DATA(D10_ED10_NAF10_MARK, PORT125_FN1),
+ PINMUX_DATA(D11_ED11_NAF11_MARK, PORT126_FN1),
+ PINMUX_DATA(D12_ED12_NAF12_MARK, PORT127_FN1),
+ PINMUX_DATA(D13_ED13_NAF13_MARK, PORT128_FN1),
+ PINMUX_DATA(D14_ED14_NAF14_MARK, PORT129_FN1),
+ PINMUX_DATA(D15_ED15_NAF15_MARK, PORT130_FN1),
+ PINMUX_DATA(CS4_MARK, PORT131_FN1),
+ PINMUX_DATA(CS5A_MARK, PORT132_FN1),
+ PINMUX_DATA(CS5B_MARK, PORT133_FN1),
+ PINMUX_DATA(FCE1_MARK, PORT133_FN2),
+ PINMUX_DATA(CS6B_MARK, PORT134_FN1),
+ PINMUX_DATA(XCS2_MARK, PORT134_FN2),
+ PINMUX_DATA(FCE0_MARK, PORT135_FN1),
+ PINMUX_DATA(CS6A_MARK, PORT136_FN1),
+ PINMUX_DATA(DACK0_MARK, PORT136_FN2),
+ PINMUX_DATA(WAIT_MARK, PORT137_FN1),
+ PINMUX_DATA(DREQ0_MARK, PORT137_FN2),
+ PINMUX_DATA(RD_XRD_MARK, PORT138_FN1),
+ PINMUX_DATA(A27_MARK, PORT139_FN1),
+ PINMUX_DATA(RDWR_XWE_MARK, PORT139_FN2),
+ PINMUX_DATA(WE0_XWR0_FWE_MARK, PORT140_FN1),
+ PINMUX_DATA(WE1_XWR1_MARK, PORT141_FN1),
+ PINMUX_DATA(FRB_MARK, PORT142_FN1),
+ PINMUX_DATA(CKO_MARK, PORT143_FN1),
+ PINMUX_DATA(NBRSTOUT_MARK, PORT144_FN1),
+ PINMUX_DATA(NBRST_MARK, PORT145_FN1),
+
+ /* 49-4 (FN) */
+ PINMUX_DATA(RFSPO0_MARK, PORT146_FN1),
+ PINMUX_DATA(PORT146_VIO_CKO2_MARK, PORT146_FN2),
+ PINMUX_DATA(TSTMD_MARK, PORT147_FN1),
+ PINMUX_DATA(VIO_VD_MARK, PORT148_FN1),
+ PINMUX_DATA(VIO_HD_MARK, PORT149_FN1),
+ PINMUX_DATA(VIO_D0_MARK, PORT150_FN1),
+ PINMUX_DATA(VIO_D1_MARK, PORT151_FN1),
+ PINMUX_DATA(VIO_D2_MARK, PORT152_FN1),
+ PINMUX_DATA(VIO_D3_MARK, PORT153_FN1),
+ PINMUX_DATA(VIO_D4_MARK, PORT154_FN1),
+ PINMUX_DATA(VIO_D5_MARK, PORT155_FN1),
+ PINMUX_DATA(VIO_D6_MARK, PORT156_FN1),
+ PINMUX_DATA(VIO_D7_MARK, PORT157_FN1),
+ PINMUX_DATA(VIO_D8_MARK, PORT158_FN1),
+ PINMUX_DATA(VIO_D9_MARK, PORT159_FN1),
+ PINMUX_DATA(VIO_D10_MARK, PORT160_FN1),
+ PINMUX_DATA(VIO_D11_MARK, PORT161_FN1),
+ PINMUX_DATA(VIO_D12_MARK, PORT162_FN1),
+ PINMUX_DATA(VIO_D13_MARK, PORT163_FN1),
+ PINMUX_DATA(VIO_D14_MARK, PORT164_FN1),
+ PINMUX_DATA(VIO_D15_MARK, PORT165_FN1),
+ PINMUX_DATA(VIO_CLK_MARK, PORT166_FN1),
+ PINMUX_DATA(VIO_FIELD_MARK, PORT167_FN1),
+ PINMUX_DATA(VIO_CKO_MARK, PORT168_FN1),
+ PINMUX_DATA(MFG3_IN1_MARK, PORT169_FN2),
+ PINMUX_DATA(MFG3_IN2_MARK, PORT170_FN2),
+ PINMUX_DATA(M9_SLCD_A01_MARK, PORT171_FN1),
+ PINMUX_DATA(MFG3_OUT1_MARK, PORT171_FN2),
+ PINMUX_DATA(TPU0TO0_MARK, PORT171_FN3),
+ PINMUX_DATA(M10_SLCD_CK1_MARK, PORT172_FN1),
+ PINMUX_DATA(MFG4_IN1_MARK, PORT172_FN2),
+ PINMUX_DATA(TPU0TO1_MARK, PORT172_FN3),
+ PINMUX_DATA(M11_SLCD_SO1_MARK, PORT173_FN1),
+ PINMUX_DATA(MFG4_IN2_MARK, PORT173_FN2),
+ PINMUX_DATA(TPU0TO2_MARK, PORT173_FN3),
+ PINMUX_DATA(M12_SLCD_CE1_MARK, PORT174_FN1),
+ PINMUX_DATA(MFG4_OUT1_MARK, PORT174_FN2),
+ PINMUX_DATA(TPU0TO3_MARK, PORT174_FN3),
+ PINMUX_DATA(LCDD0_MARK, PORT175_FN1),
+ PINMUX_DATA(PORT175_KEYOUT0_MARK, PORT175_FN2),
+ PINMUX_DATA(DV_D0_MARK, PORT175_FN3),
+ PINMUX_DATA(SIUCKA_MARK, PORT175_FN4),
+ PINMUX_DATA(MFG0_OUT2_MARK, PORT175_FN5),
+ PINMUX_DATA(LCDD1_MARK, PORT176_FN1),
+ PINMUX_DATA(PORT176_KEYOUT1_MARK, PORT176_FN2),
+ PINMUX_DATA(DV_D1_MARK, PORT176_FN3),
+ PINMUX_DATA(SIUAOLR_MARK, PORT176_FN4),
+ PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT176_FN5),
+ PINMUX_DATA(LCDD2_MARK, PORT177_FN1),
+ PINMUX_DATA(PORT177_KEYOUT2_MARK, PORT177_FN2),
+ PINMUX_DATA(DV_D2_MARK, PORT177_FN3),
+ PINMUX_DATA(SIUAOBT_MARK, PORT177_FN4),
+ PINMUX_DATA(BBIF2_TSCK1_MARK, PORT177_FN5),
+ PINMUX_DATA(LCDD3_MARK, PORT178_FN1),
+ PINMUX_DATA(PORT178_KEYOUT3_MARK, PORT178_FN2),
+ PINMUX_DATA(DV_D3_MARK, PORT178_FN3),
+ PINMUX_DATA(SIUAOSLD_MARK, PORT178_FN4),
+ PINMUX_DATA(BBIF2_TXD1_MARK, PORT178_FN5),
+ PINMUX_DATA(LCDD4_MARK, PORT179_FN1),
+ PINMUX_DATA(PORT179_KEYOUT4_MARK, PORT179_FN2),
+ PINMUX_DATA(DV_D4_MARK, PORT179_FN3),
+ PINMUX_DATA(SIUAISPD_MARK, PORT179_FN4),
+ PINMUX_DATA(MFG1_OUT2_MARK, PORT179_FN5),
+ PINMUX_DATA(LCDD5_MARK, PORT180_FN1),
+ PINMUX_DATA(PORT180_KEYOUT5_MARK, PORT180_FN2),
+ PINMUX_DATA(DV_D5_MARK, PORT180_FN3),
+ PINMUX_DATA(SIUAILR_MARK, PORT180_FN4),
+ PINMUX_DATA(MFG2_OUT2_MARK, PORT180_FN5),
+ PINMUX_DATA(LCDD6_MARK, PORT181_FN1),
+ PINMUX_DATA(DV_D6_MARK, PORT181_FN3),
+ PINMUX_DATA(SIUAIBT_MARK, PORT181_FN4),
+ PINMUX_DATA(MFG3_OUT2_MARK, PORT181_FN5),
+ PINMUX_DATA(XWR2_MARK, PORT181_FN7),
+ PINMUX_DATA(LCDD7_MARK, PORT182_FN1),
+ PINMUX_DATA(DV_D7_MARK, PORT182_FN3),
+ PINMUX_DATA(SIUAISLD_MARK, PORT182_FN4),
+ PINMUX_DATA(MFG4_OUT2_MARK, PORT182_FN5),
+ PINMUX_DATA(XWR3_MARK, PORT182_FN7),
+ PINMUX_DATA(LCDD8_MARK, PORT183_FN1),
+ PINMUX_DATA(DV_D8_MARK, PORT183_FN3),
+ PINMUX_DATA(D16_MARK, PORT183_FN6),
+ PINMUX_DATA(ED16_MARK, PORT183_FN7),
+ PINMUX_DATA(LCDD9_MARK, PORT184_FN1),
+ PINMUX_DATA(DV_D9_MARK, PORT184_FN3),
+ PINMUX_DATA(D17_MARK, PORT184_FN6),
+ PINMUX_DATA(ED17_MARK, PORT184_FN7),
+ PINMUX_DATA(LCDD10_MARK, PORT185_FN1),
+ PINMUX_DATA(DV_D10_MARK, PORT185_FN3),
+ PINMUX_DATA(D18_MARK, PORT185_FN6),
+ PINMUX_DATA(ED18_MARK, PORT185_FN7),
+ PINMUX_DATA(LCDD11_MARK, PORT186_FN1),
+ PINMUX_DATA(DV_D11_MARK, PORT186_FN3),
+ PINMUX_DATA(D19_MARK, PORT186_FN6),
+ PINMUX_DATA(ED19_MARK, PORT186_FN7),
+ PINMUX_DATA(LCDD12_MARK, PORT187_FN1),
+ PINMUX_DATA(DV_D12_MARK, PORT187_FN3),
+ PINMUX_DATA(D20_MARK, PORT187_FN6),
+ PINMUX_DATA(ED20_MARK, PORT187_FN7),
+ PINMUX_DATA(LCDD13_MARK, PORT188_FN1),
+ PINMUX_DATA(DV_D13_MARK, PORT188_FN3),
+ PINMUX_DATA(D21_MARK, PORT188_FN6),
+ PINMUX_DATA(ED21_MARK, PORT188_FN7),
+ PINMUX_DATA(LCDD14_MARK, PORT189_FN1),
+ PINMUX_DATA(DV_D14_MARK, PORT189_FN3),
+ PINMUX_DATA(D22_MARK, PORT189_FN6),
+ PINMUX_DATA(ED22_MARK, PORT189_FN7),
+ PINMUX_DATA(LCDD15_MARK, PORT190_FN1),
+ PINMUX_DATA(DV_D15_MARK, PORT190_FN3),
+ PINMUX_DATA(D23_MARK, PORT190_FN6),
+ PINMUX_DATA(ED23_MARK, PORT190_FN7),
+ PINMUX_DATA(LCDD16_MARK, PORT191_FN1),
+ PINMUX_DATA(DV_HSYNC_MARK, PORT191_FN3),
+ PINMUX_DATA(D24_MARK, PORT191_FN6),
+ PINMUX_DATA(ED24_MARK, PORT191_FN7),
+ PINMUX_DATA(LCDD17_MARK, PORT192_FN1),
+ PINMUX_DATA(DV_VSYNC_MARK, PORT192_FN3),
+ PINMUX_DATA(D25_MARK, PORT192_FN6),
+ PINMUX_DATA(ED25_MARK, PORT192_FN7),
+ PINMUX_DATA(LCDD18_MARK, PORT193_FN1),
+ PINMUX_DATA(DREQ2_MARK, PORT193_FN2),
+ PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT193_FN5),
+ PINMUX_DATA(D26_MARK, PORT193_FN6),
+ PINMUX_DATA(ED26_MARK, PORT193_FN7),
+ PINMUX_DATA(LCDD19_MARK, PORT194_FN1),
+ PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT194_FN5),
+ PINMUX_DATA(D27_MARK, PORT194_FN6),
+ PINMUX_DATA(ED27_MARK, PORT194_FN7),
+ PINMUX_DATA(LCDD20_MARK, PORT195_FN1),
+ PINMUX_DATA(TS_SPSYNC1_MARK, PORT195_FN2),
+ PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT195_FN5),
+ PINMUX_DATA(D28_MARK, PORT195_FN6),
+ PINMUX_DATA(ED28_MARK, PORT195_FN7),
+ PINMUX_DATA(LCDD21_MARK, PORT196_FN1),
+ PINMUX_DATA(TS_SDAT1_MARK, PORT196_FN2),
+ PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT196_FN5),
+ PINMUX_DATA(D29_MARK, PORT196_FN6),
+ PINMUX_DATA(ED29_MARK, PORT196_FN7),
+ PINMUX_DATA(LCDD22_MARK, PORT197_FN1),
+ PINMUX_DATA(TS_SDEN1_MARK, PORT197_FN2),
+ PINMUX_DATA(MSIOF0L_SS1_MARK, PORT197_FN5),
+ PINMUX_DATA(D30_MARK, PORT197_FN6),
+ PINMUX_DATA(ED30_MARK, PORT197_FN7),
+ PINMUX_DATA(LCDD23_MARK, PORT198_FN1),
+ PINMUX_DATA(TS_SCK1_MARK, PORT198_FN2),
+ PINMUX_DATA(MSIOF0L_SS2_MARK, PORT198_FN5),
+ PINMUX_DATA(D31_MARK, PORT198_FN6),
+ PINMUX_DATA(ED31_MARK, PORT198_FN7),
+ PINMUX_DATA(LCDDCK_MARK, PORT199_FN1),
+ PINMUX_DATA(LCDWR_MARK, PORT199_FN2),
+ PINMUX_DATA(DV_CKO_MARK, PORT199_FN3),
+ PINMUX_DATA(SIUAOSPD_MARK, PORT199_FN4),
+ PINMUX_DATA(LCDRD_MARK, PORT200_FN1),
+ PINMUX_DATA(DACK2_MARK, PORT200_FN2),
+ PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT200_FN5),
+
+ /* 49-5 (FN) */
+ PINMUX_DATA(LCDHSYN_MARK, PORT201_FN1),
+ PINMUX_DATA(LCDCS_MARK, PORT201_FN2),
+ PINMUX_DATA(LCDCS2_MARK, PORT201_FN3),
+ PINMUX_DATA(DACK3_MARK, PORT201_FN4),
+ PINMUX_DATA(LCDDISP_MARK, PORT202_FN1),
+ PINMUX_DATA(LCDRS_MARK, PORT202_FN2),
+ PINMUX_DATA(DREQ3_MARK, PORT202_FN4),
+ PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT202_FN5),
+ PINMUX_DATA(LCDCSYN_MARK, PORT203_FN1),
+ PINMUX_DATA(LCDCSYN2_MARK, PORT203_FN2),
+ PINMUX_DATA(DV_CKI_MARK, PORT203_FN3),
+ PINMUX_DATA(LCDLCLK_MARK, PORT204_FN1),
+ PINMUX_DATA(DREQ1_MARK, PORT204_FN3),
+ PINMUX_DATA(MSIOF0L_RXD_MARK, PORT204_FN5),
+ PINMUX_DATA(LCDDON_MARK, PORT205_FN1),
+ PINMUX_DATA(LCDDON2_MARK, PORT205_FN2),
+ PINMUX_DATA(DACK1_MARK, PORT205_FN3),
+ PINMUX_DATA(MSIOF0L_TXD_MARK, PORT205_FN5),
+ PINMUX_DATA(VIO_DR0_MARK, PORT206_FN1),
+ PINMUX_DATA(VIO_DR1_MARK, PORT207_FN1),
+ PINMUX_DATA(VIO_DR2_MARK, PORT208_FN1),
+ PINMUX_DATA(VIO_DR3_MARK, PORT209_FN1),
+ PINMUX_DATA(VIO_DR4_MARK, PORT210_FN1),
+ PINMUX_DATA(VIO_DR5_MARK, PORT211_FN1),
+ PINMUX_DATA(VIO_DR6_MARK, PORT212_FN1),
+ PINMUX_DATA(VIO_DR7_MARK, PORT213_FN1),
+ PINMUX_DATA(VIO_VDR_MARK, PORT214_FN1),
+ PINMUX_DATA(VIO_HDR_MARK, PORT215_FN1),
+ PINMUX_DATA(VIO_CLKR_MARK, PORT216_FN1),
+ PINMUX_DATA(VIO_CKOR_MARK, PORT217_FN1),
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT220_FN2),
+ PINMUX_DATA(GPS_PGFA0_MARK, PORT220_FN3),
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT221_FN2),
+ PINMUX_DATA(GPS_PGFA1_MARK, PORT221_FN3),
+ PINMUX_DATA(SCIFA1_RTS_MARK, PORT222_FN2),
+ PINMUX_DATA(GPS_EPPSINMON_MARK, PORT222_FN3),
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT223_FN2),
+ PINMUX_DATA(SCIFA1_CTS_MARK, PORT224_FN2),
+ PINMUX_DATA(MSIOF1_TXD_MARK, PORT225_FN1),
+ PINMUX_DATA(SCIFA1_TXD2_MARK, PORT225_FN2),
+ PINMUX_DATA(GPS_TXD_MARK, PORT225_FN3),
+ PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT226_FN1),
+ PINMUX_DATA(SCIFA1_CTS2_MARK, PORT226_FN2),
+ PINMUX_DATA(I2C_SDA2_MARK, PORT226_FN3),
+ PINMUX_DATA(MSIOF1_TSCK_MARK, PORT227_FN1),
+ PINMUX_DATA(SCIFA1_SCK2_MARK, PORT227_FN2),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PORT228_FN1),
+ PINMUX_DATA(SCIFA1_RXD2_MARK, PORT228_FN2),
+ PINMUX_DATA(GPS_RXD_MARK, PORT228_FN3),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT229_FN1),
+ PINMUX_DATA(SCIFA1_RTS2_MARK, PORT229_FN2),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT230_FN1),
+ PINMUX_DATA(I2C_SCL2_MARK, PORT230_FN3),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT231_FN1),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT232_FN1),
+ PINMUX_DATA(MSIOF1_SS1_MARK, PORT233_FN1),
+ PINMUX_DATA(EDBGREQ3_MARK, PORT233_FN2),
+ PINMUX_DATA(MSIOF1_SS2_MARK, PORT234_FN1),
+ PINMUX_DATA(PORT236_IROUT_MARK, PORT236_FN1),
+ PINMUX_DATA(IRDA_OUT_MARK, PORT236_FN2),
+ PINMUX_DATA(IRDA_IN_MARK, PORT237_FN2),
+ PINMUX_DATA(IRDA_FIRSEL_MARK, PORT238_FN1),
+ PINMUX_DATA(TPU1TO0_MARK, PORT239_FN3),
+ PINMUX_DATA(TS_SPSYNC3_MARK, PORT239_FN4),
+ PINMUX_DATA(TPU1TO1_MARK, PORT240_FN3),
+ PINMUX_DATA(TS_SDAT3_MARK, PORT240_FN4),
+ PINMUX_DATA(TPU1TO2_MARK, PORT241_FN3),
+ PINMUX_DATA(TS_SDEN3_MARK, PORT241_FN4),
+ PINMUX_DATA(PORT241_MSIOF2_SS1_MARK, PORT241_FN5),
+ PINMUX_DATA(TPU1TO3_MARK, PORT242_FN3),
+ PINMUX_DATA(PORT242_MSIOF2_TSCK_MARK, PORT242_FN5),
+ PINMUX_DATA(M13_BSW_MARK, PORT243_FN2),
+ PINMUX_DATA(PORT243_MSIOF2_TSYNC_MARK, PORT243_FN5),
+ PINMUX_DATA(M14_GSW_MARK, PORT244_FN2),
+ PINMUX_DATA(PORT244_MSIOF2_TXD_MARK, PORT244_FN5),
+ PINMUX_DATA(PORT245_IROUT_MARK, PORT245_FN1),
+ PINMUX_DATA(M15_RSW_MARK, PORT245_FN2),
+ PINMUX_DATA(SOUT3_MARK, PORT246_FN1),
+ PINMUX_DATA(SCIFA2_TXD1_MARK, PORT246_FN2),
+ PINMUX_DATA(SIN3_MARK, PORT247_FN1),
+ PINMUX_DATA(SCIFA2_RXD1_MARK, PORT247_FN2),
+ PINMUX_DATA(XRTS3_MARK, PORT248_FN1),
+ PINMUX_DATA(SCIFA2_RTS1_MARK, PORT248_FN2),
+ PINMUX_DATA(PORT248_MSIOF2_SS2_MARK, PORT248_FN5),
+ PINMUX_DATA(XCTS3_MARK, PORT249_FN1),
+ PINMUX_DATA(SCIFA2_CTS1_MARK, PORT249_FN2),
+ PINMUX_DATA(PORT249_MSIOF2_RXD_MARK, PORT249_FN5),
+ PINMUX_DATA(DINT_MARK, PORT250_FN1),
+ PINMUX_DATA(SCIFA2_SCK1_MARK, PORT250_FN2),
+ PINMUX_DATA(TS_SCK3_MARK, PORT250_FN4),
+ PINMUX_DATA(SDHICLK0_MARK, PORT251_FN1),
+ PINMUX_DATA(TCK2_MARK, PORT251_FN2),
+ PINMUX_DATA(SDHICD0_MARK, PORT252_FN1),
+ PINMUX_DATA(SDHID0_0_MARK, PORT253_FN1),
+ PINMUX_DATA(TMS2_MARK, PORT253_FN2),
+ PINMUX_DATA(SDHID0_1_MARK, PORT254_FN1),
+ PINMUX_DATA(TDO2_MARK, PORT254_FN2),
+ PINMUX_DATA(SDHID0_2_MARK, PORT255_FN1),
+ PINMUX_DATA(TDI2_MARK, PORT255_FN2),
+ PINMUX_DATA(SDHID0_3_MARK, PORT256_FN1),
+ PINMUX_DATA(RTCK2_MARK, PORT256_FN2),
+
+ /* 49-6 (FN) */
+ PINMUX_DATA(SDHICMD0_MARK, PORT257_FN1),
+ PINMUX_DATA(TRST2_MARK, PORT257_FN2),
+ PINMUX_DATA(SDHIWP0_MARK, PORT258_FN1),
+ PINMUX_DATA(EDBGREQ2_MARK, PORT258_FN2),
+ PINMUX_DATA(SDHICLK1_MARK, PORT259_FN1),
+ PINMUX_DATA(TCK3_MARK, PORT259_FN4),
+ PINMUX_DATA(SDHID1_0_MARK, PORT260_FN1),
+ PINMUX_DATA(M11_SLCD_SO2_MARK, PORT260_FN2),
+ PINMUX_DATA(TS_SPSYNC2_MARK, PORT260_FN3),
+ PINMUX_DATA(TMS3_MARK, PORT260_FN4),
+ PINMUX_DATA(SDHID1_1_MARK, PORT261_FN1),
+ PINMUX_DATA(M9_SLCD_AO2_MARK, PORT261_FN2),
+ PINMUX_DATA(TS_SDAT2_MARK, PORT261_FN3),
+ PINMUX_DATA(TDO3_MARK, PORT261_FN4),
+ PINMUX_DATA(SDHID1_2_MARK, PORT262_FN1),
+ PINMUX_DATA(M10_SLCD_CK2_MARK, PORT262_FN2),
+ PINMUX_DATA(TS_SDEN2_MARK, PORT262_FN3),
+ PINMUX_DATA(TDI3_MARK, PORT262_FN4),
+ PINMUX_DATA(SDHID1_3_MARK, PORT263_FN1),
+ PINMUX_DATA(M12_SLCD_CE2_MARK, PORT263_FN2),
+ PINMUX_DATA(TS_SCK2_MARK, PORT263_FN3),
+ PINMUX_DATA(RTCK3_MARK, PORT263_FN4),
+ PINMUX_DATA(SDHICMD1_MARK, PORT264_FN1),
+ PINMUX_DATA(TRST3_MARK, PORT264_FN4),
+ PINMUX_DATA(SDHICLK2_MARK, PORT265_FN1),
+ PINMUX_DATA(SCIFB_SCK_MARK, PORT265_FN2),
+ PINMUX_DATA(SDHID2_0_MARK, PORT266_FN1),
+ PINMUX_DATA(SCIFB_TXD_MARK, PORT266_FN2),
+ PINMUX_DATA(SDHID2_1_MARK, PORT267_FN1),
+ PINMUX_DATA(SCIFB_CTS_MARK, PORT267_FN2),
+ PINMUX_DATA(SDHID2_2_MARK, PORT268_FN1),
+ PINMUX_DATA(SCIFB_RXD_MARK, PORT268_FN2),
+ PINMUX_DATA(SDHID2_3_MARK, PORT269_FN1),
+ PINMUX_DATA(SCIFB_RTS_MARK, PORT269_FN2),
+ PINMUX_DATA(SDHICMD2_MARK, PORT270_FN1),
+ PINMUX_DATA(RESETOUTS_MARK, PORT271_FN1),
+ PINMUX_DATA(DIVLOCK_MARK, PORT272_FN1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_273() _273(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* 49-1 -> 49-6 (GPIO) */
+ GPIO_PORT_273(),
+
+ /* Special Pull-up / Pull-down Functions */
+ GPIO_FN(PORT48_KEYIN0_PU), GPIO_FN(PORT49_KEYIN1_PU),
+ GPIO_FN(PORT50_KEYIN2_PU), GPIO_FN(PORT55_KEYIN3_PU),
+ GPIO_FN(PORT56_KEYIN4_PU), GPIO_FN(PORT57_KEYIN5_PU),
+ GPIO_FN(PORT58_KEYIN6_PU),
+
+ /* 49-1 (FN) */
+ GPIO_FN(VBUS0), GPIO_FN(CPORT0), GPIO_FN(CPORT1), GPIO_FN(CPORT2),
+ GPIO_FN(CPORT3), GPIO_FN(CPORT4), GPIO_FN(CPORT5), GPIO_FN(CPORT6),
+ GPIO_FN(CPORT7), GPIO_FN(CPORT8), GPIO_FN(CPORT9), GPIO_FN(CPORT10),
+ GPIO_FN(CPORT11), GPIO_FN(SIN2), GPIO_FN(CPORT12), GPIO_FN(XCTS2),
+ GPIO_FN(CPORT13), GPIO_FN(RFSPO4), GPIO_FN(CPORT14), GPIO_FN(RFSPO5),
+ GPIO_FN(CPORT15), GPIO_FN(CPORT16), GPIO_FN(CPORT17), GPIO_FN(SOUT2),
+ GPIO_FN(CPORT18), GPIO_FN(XRTS2), GPIO_FN(CPORT19), GPIO_FN(CPORT20),
+ GPIO_FN(RFSPO6), GPIO_FN(CPORT21), GPIO_FN(STATUS0), GPIO_FN(CPORT22),
+ GPIO_FN(STATUS1), GPIO_FN(CPORT23), GPIO_FN(STATUS2), GPIO_FN(RFSPO7),
+ GPIO_FN(MPORT0), GPIO_FN(MPORT1), GPIO_FN(B_SYNLD1), GPIO_FN(B_SYNLD2),
+ GPIO_FN(XMAINPS), GPIO_FN(XDIVPS), GPIO_FN(XIDRST), GPIO_FN(IDCLK),
+ GPIO_FN(IDIO), GPIO_FN(SOUT1), GPIO_FN(SCIFA4_TXD),
+ GPIO_FN(M02_BERDAT), GPIO_FN(SIN1), GPIO_FN(SCIFA4_RXD), GPIO_FN(XWUP),
+ GPIO_FN(XRTS1), GPIO_FN(SCIFA4_RTS), GPIO_FN(M03_BERCLK),
+ GPIO_FN(XCTS1), GPIO_FN(SCIFA4_CTS),
+
+ /* 49-2 (FN) */
+ GPIO_FN(HSU_IQ_AGC6), GPIO_FN(MFG2_IN2), GPIO_FN(MSIOF2_MCK0),
+ GPIO_FN(HSU_IQ_AGC5), GPIO_FN(MFG2_IN1), GPIO_FN(MSIOF2_MCK1),
+ GPIO_FN(HSU_IQ_AGC4), GPIO_FN(MSIOF2_RSYNC),
+ GPIO_FN(HSU_IQ_AGC3), GPIO_FN(MFG2_OUT1), GPIO_FN(MSIOF2_RSCK),
+ GPIO_FN(HSU_IQ_AGC2), GPIO_FN(PORT42_KEYOUT0),
+ GPIO_FN(HSU_IQ_AGC1), GPIO_FN(PORT43_KEYOUT1),
+ GPIO_FN(HSU_IQ_AGC0), GPIO_FN(PORT44_KEYOUT2),
+ GPIO_FN(HSU_IQ_AGC_ST), GPIO_FN(PORT45_KEYOUT3),
+ GPIO_FN(HSU_IQ_PDO), GPIO_FN(PORT46_KEYOUT4),
+ GPIO_FN(HSU_IQ_PYO), GPIO_FN(PORT47_KEYOUT5),
+ GPIO_FN(HSU_EN_TXMUX_G3MO), GPIO_FN(PORT48_KEYIN0),
+ GPIO_FN(HSU_I_TXMUX_G3MO), GPIO_FN(PORT49_KEYIN1),
+ GPIO_FN(HSU_Q_TXMUX_G3MO), GPIO_FN(PORT50_KEYIN2),
+ GPIO_FN(HSU_SYO), GPIO_FN(PORT51_MSIOF2_TSYNC),
+ GPIO_FN(HSU_SDO), GPIO_FN(PORT52_MSIOF2_TSCK),
+ GPIO_FN(HSU_TGTTI_G3MO), GPIO_FN(PORT53_MSIOF2_TXD),
+ GPIO_FN(B_TIME_STAMP), GPIO_FN(PORT54_MSIOF2_RXD),
+ GPIO_FN(HSU_SDI), GPIO_FN(PORT55_KEYIN3),
+ GPIO_FN(HSU_SCO), GPIO_FN(PORT56_KEYIN4),
+ GPIO_FN(HSU_DREQ), GPIO_FN(PORT57_KEYIN5),
+ GPIO_FN(HSU_DACK), GPIO_FN(PORT58_KEYIN6),
+ GPIO_FN(HSU_CLK61M), GPIO_FN(PORT59_MSIOF2_SS1),
+ GPIO_FN(HSU_XRST), GPIO_FN(PORT60_MSIOF2_SS2),
+ GPIO_FN(PCMCLKO), GPIO_FN(SYNC8KO), GPIO_FN(DNPCM_A), GPIO_FN(UPPCM_A),
+ GPIO_FN(XTALB1L),
+ GPIO_FN(GPS_AGC1), GPIO_FN(SCIFA0_RTS),
+ GPIO_FN(GPS_AGC2), GPIO_FN(SCIFA0_SCK),
+ GPIO_FN(GPS_AGC3), GPIO_FN(SCIFA0_TXD),
+ GPIO_FN(GPS_AGC4), GPIO_FN(SCIFA0_RXD),
+ GPIO_FN(GPS_PWRD), GPIO_FN(SCIFA0_CTS),
+ GPIO_FN(GPS_IM), GPIO_FN(GPS_IS), GPIO_FN(GPS_QM), GPIO_FN(GPS_QS),
+ GPIO_FN(SIUBOMC), GPIO_FN(TPU2TO0),
+ GPIO_FN(SIUCKB), GPIO_FN(TPU2TO1),
+ GPIO_FN(SIUBOLR), GPIO_FN(BBIF2_TSYNC), GPIO_FN(TPU2TO2),
+ GPIO_FN(SIUBOBT), GPIO_FN(BBIF2_TSCK), GPIO_FN(TPU2TO3),
+ GPIO_FN(SIUBOSLD), GPIO_FN(BBIF2_TXD), GPIO_FN(TPU3TO0),
+ GPIO_FN(SIUBILR), GPIO_FN(TPU3TO1),
+ GPIO_FN(SIUBIBT), GPIO_FN(TPU3TO2),
+ GPIO_FN(SIUBISLD), GPIO_FN(TPU3TO3),
+ GPIO_FN(NMI), GPIO_FN(TPU4TO0),
+ GPIO_FN(DNPCM_M), GPIO_FN(TPU4TO1), GPIO_FN(TPU4TO2), GPIO_FN(TPU4TO3),
+ GPIO_FN(IRQ_TMPB),
+ GPIO_FN(PWEN), GPIO_FN(MFG1_OUT1),
+ GPIO_FN(OVCN), GPIO_FN(MFG1_IN1),
+ GPIO_FN(OVCN2), GPIO_FN(MFG1_IN2),
+
+ /* 49-3 (FN) */
+ GPIO_FN(RFSPO1), GPIO_FN(RFSPO2), GPIO_FN(RFSPO3),
+ GPIO_FN(PORT93_VIO_CKO2),
+ GPIO_FN(USBTERM), GPIO_FN(EXTLP), GPIO_FN(IDIN),
+ GPIO_FN(SCIFA5_CTS), GPIO_FN(MFG0_IN1),
+ GPIO_FN(SCIFA5_RTS), GPIO_FN(MFG0_IN2),
+ GPIO_FN(SCIFA5_RXD),
+ GPIO_FN(SCIFA5_TXD),
+ GPIO_FN(SCIFA5_SCK), GPIO_FN(MFG0_OUT1),
+ GPIO_FN(A0_EA0), GPIO_FN(BS),
+ GPIO_FN(A14_EA14), GPIO_FN(PORT102_KEYOUT0),
+ GPIO_FN(A15_EA15), GPIO_FN(PORT103_KEYOUT1), GPIO_FN(DV_CLKOL),
+ GPIO_FN(A16_EA16), GPIO_FN(PORT104_KEYOUT2),
+ GPIO_FN(DV_VSYNCL), GPIO_FN(MSIOF0_SS1),
+ GPIO_FN(A17_EA17), GPIO_FN(PORT105_KEYOUT3),
+ GPIO_FN(DV_HSYNCL), GPIO_FN(MSIOF0_TSYNC),
+ GPIO_FN(A18_EA18), GPIO_FN(PORT106_KEYOUT4),
+ GPIO_FN(DV_DL0), GPIO_FN(MSIOF0_TSCK),
+ GPIO_FN(A19_EA19), GPIO_FN(PORT107_KEYOUT5),
+ GPIO_FN(DV_DL1), GPIO_FN(MSIOF0_TXD),
+ GPIO_FN(A20_EA20), GPIO_FN(PORT108_KEYIN0),
+ GPIO_FN(DV_DL2), GPIO_FN(MSIOF0_RSCK),
+ GPIO_FN(A21_EA21), GPIO_FN(PORT109_KEYIN1),
+ GPIO_FN(DV_DL3), GPIO_FN(MSIOF0_RSYNC),
+ GPIO_FN(A22_EA22), GPIO_FN(PORT110_KEYIN2),
+ GPIO_FN(DV_DL4), GPIO_FN(MSIOF0_MCK0),
+ GPIO_FN(A23_EA23), GPIO_FN(PORT111_KEYIN3),
+ GPIO_FN(DV_DL5), GPIO_FN(MSIOF0_MCK1),
+ GPIO_FN(A24_EA24), GPIO_FN(PORT112_KEYIN4),
+ GPIO_FN(DV_DL6), GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(A25_EA25), GPIO_FN(PORT113_KEYIN5),
+ GPIO_FN(DV_DL7), GPIO_FN(MSIOF0_SS2),
+ GPIO_FN(A26), GPIO_FN(PORT113_KEYIN6), GPIO_FN(DV_CLKIL),
+ GPIO_FN(D0_ED0_NAF0), GPIO_FN(D1_ED1_NAF1), GPIO_FN(D2_ED2_NAF2),
+ GPIO_FN(D3_ED3_NAF3), GPIO_FN(D4_ED4_NAF4), GPIO_FN(D5_ED5_NAF5),
+ GPIO_FN(D6_ED6_NAF6), GPIO_FN(D7_ED7_NAF7), GPIO_FN(D8_ED8_NAF8),
+ GPIO_FN(D9_ED9_NAF9), GPIO_FN(D10_ED10_NAF10), GPIO_FN(D11_ED11_NAF11),
+ GPIO_FN(D12_ED12_NAF12), GPIO_FN(D13_ED13_NAF13),
+ GPIO_FN(D14_ED14_NAF14), GPIO_FN(D15_ED15_NAF15),
+ GPIO_FN(CS4), GPIO_FN(CS5A), GPIO_FN(CS5B), GPIO_FN(FCE1),
+ GPIO_FN(CS6B), GPIO_FN(XCS2), GPIO_FN(FCE0), GPIO_FN(CS6A),
+ GPIO_FN(DACK0), GPIO_FN(WAIT), GPIO_FN(DREQ0), GPIO_FN(RD_XRD),
+ GPIO_FN(A27), GPIO_FN(RDWR_XWE), GPIO_FN(WE0_XWR0_FWE),
+ GPIO_FN(WE1_XWR1), GPIO_FN(FRB), GPIO_FN(CKO),
+ GPIO_FN(NBRSTOUT), GPIO_FN(NBRST),
+
+ /* 49-4 (FN) */
+ GPIO_FN(RFSPO0), GPIO_FN(PORT146_VIO_CKO2), GPIO_FN(TSTMD),
+ GPIO_FN(VIO_VD), GPIO_FN(VIO_HD),
+ GPIO_FN(VIO_D0), GPIO_FN(VIO_D1), GPIO_FN(VIO_D2),
+ GPIO_FN(VIO_D3), GPIO_FN(VIO_D4), GPIO_FN(VIO_D5),
+ GPIO_FN(VIO_D6), GPIO_FN(VIO_D7), GPIO_FN(VIO_D8),
+ GPIO_FN(VIO_D9), GPIO_FN(VIO_D10), GPIO_FN(VIO_D11),
+ GPIO_FN(VIO_D12), GPIO_FN(VIO_D13), GPIO_FN(VIO_D14),
+ GPIO_FN(VIO_D15), GPIO_FN(VIO_CLK), GPIO_FN(VIO_FIELD),
+ GPIO_FN(VIO_CKO),
+ GPIO_FN(MFG3_IN1), GPIO_FN(MFG3_IN2),
+ GPIO_FN(M9_SLCD_A01), GPIO_FN(MFG3_OUT1), GPIO_FN(TPU0TO0),
+ GPIO_FN(M10_SLCD_CK1), GPIO_FN(MFG4_IN1), GPIO_FN(TPU0TO1),
+ GPIO_FN(M11_SLCD_SO1), GPIO_FN(MFG4_IN2), GPIO_FN(TPU0TO2),
+ GPIO_FN(M12_SLCD_CE1), GPIO_FN(MFG4_OUT1), GPIO_FN(TPU0TO3),
+ GPIO_FN(LCDD0), GPIO_FN(PORT175_KEYOUT0), GPIO_FN(DV_D0),
+ GPIO_FN(SIUCKA), GPIO_FN(MFG0_OUT2),
+ GPIO_FN(LCDD1), GPIO_FN(PORT176_KEYOUT1), GPIO_FN(DV_D1),
+ GPIO_FN(SIUAOLR), GPIO_FN(BBIF2_TSYNC1),
+ GPIO_FN(LCDD2), GPIO_FN(PORT177_KEYOUT2), GPIO_FN(DV_D2),
+ GPIO_FN(SIUAOBT), GPIO_FN(BBIF2_TSCK1),
+ GPIO_FN(LCDD3), GPIO_FN(PORT178_KEYOUT3), GPIO_FN(DV_D3),
+ GPIO_FN(SIUAOSLD), GPIO_FN(BBIF2_TXD1),
+ GPIO_FN(LCDD4), GPIO_FN(PORT179_KEYOUT4), GPIO_FN(DV_D4),
+ GPIO_FN(SIUAISPD), GPIO_FN(MFG1_OUT2),
+ GPIO_FN(LCDD5), GPIO_FN(PORT180_KEYOUT5), GPIO_FN(DV_D5),
+ GPIO_FN(SIUAILR), GPIO_FN(MFG2_OUT2),
+ GPIO_FN(LCDD6), GPIO_FN(DV_D6),
+ GPIO_FN(SIUAIBT), GPIO_FN(MFG3_OUT2), GPIO_FN(XWR2),
+ GPIO_FN(LCDD7), GPIO_FN(DV_D7),
+ GPIO_FN(SIUAISLD), GPIO_FN(MFG4_OUT2), GPIO_FN(XWR3),
+ GPIO_FN(LCDD8), GPIO_FN(DV_D8), GPIO_FN(D16), GPIO_FN(ED16),
+ GPIO_FN(LCDD9), GPIO_FN(DV_D9), GPIO_FN(D17), GPIO_FN(ED17),
+ GPIO_FN(LCDD10), GPIO_FN(DV_D10), GPIO_FN(D18), GPIO_FN(ED18),
+ GPIO_FN(LCDD11), GPIO_FN(DV_D11), GPIO_FN(D19), GPIO_FN(ED19),
+ GPIO_FN(LCDD12), GPIO_FN(DV_D12), GPIO_FN(D20), GPIO_FN(ED20),
+ GPIO_FN(LCDD13), GPIO_FN(DV_D13), GPIO_FN(D21), GPIO_FN(ED21),
+ GPIO_FN(LCDD14), GPIO_FN(DV_D14), GPIO_FN(D22), GPIO_FN(ED22),
+ GPIO_FN(LCDD15), GPIO_FN(DV_D15), GPIO_FN(D23), GPIO_FN(ED23),
+ GPIO_FN(LCDD16), GPIO_FN(DV_HSYNC), GPIO_FN(D24), GPIO_FN(ED24),
+ GPIO_FN(LCDD17), GPIO_FN(DV_VSYNC), GPIO_FN(D25), GPIO_FN(ED25),
+ GPIO_FN(LCDD18), GPIO_FN(DREQ2), GPIO_FN(MSIOF0L_TSCK),
+ GPIO_FN(D26), GPIO_FN(ED26),
+ GPIO_FN(LCDD19), GPIO_FN(MSIOF0L_TSYNC),
+ GPIO_FN(D27), GPIO_FN(ED27),
+ GPIO_FN(LCDD20), GPIO_FN(TS_SPSYNC1), GPIO_FN(MSIOF0L_MCK0),
+ GPIO_FN(D28), GPIO_FN(ED28),
+ GPIO_FN(LCDD21), GPIO_FN(TS_SDAT1), GPIO_FN(MSIOF0L_MCK1),
+ GPIO_FN(D29), GPIO_FN(ED29),
+ GPIO_FN(LCDD22), GPIO_FN(TS_SDEN1), GPIO_FN(MSIOF0L_SS1),
+ GPIO_FN(D30), GPIO_FN(ED30),
+ GPIO_FN(LCDD23), GPIO_FN(TS_SCK1), GPIO_FN(MSIOF0L_SS2),
+ GPIO_FN(D31), GPIO_FN(ED31),
+ GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(DV_CKO), GPIO_FN(SIUAOSPD),
+ GPIO_FN(LCDRD), GPIO_FN(DACK2), GPIO_FN(MSIOF0L_RSYNC),
+
+ /* 49-5 (FN) */
+ GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDCS2), GPIO_FN(DACK3),
+ GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(DREQ3), GPIO_FN(MSIOF0L_RSCK),
+ GPIO_FN(LCDCSYN), GPIO_FN(LCDCSYN2), GPIO_FN(DV_CKI),
+ GPIO_FN(LCDLCLK), GPIO_FN(DREQ1), GPIO_FN(MSIOF0L_RXD),
+ GPIO_FN(LCDDON), GPIO_FN(LCDDON2), GPIO_FN(DACK1), GPIO_FN(MSIOF0L_TXD),
+ GPIO_FN(VIO_DR0), GPIO_FN(VIO_DR1), GPIO_FN(VIO_DR2), GPIO_FN(VIO_DR3),
+ GPIO_FN(VIO_DR4), GPIO_FN(VIO_DR5), GPIO_FN(VIO_DR6), GPIO_FN(VIO_DR7),
+ GPIO_FN(VIO_VDR), GPIO_FN(VIO_HDR),
+ GPIO_FN(VIO_CLKR), GPIO_FN(VIO_CKOR),
+ GPIO_FN(SCIFA1_TXD), GPIO_FN(GPS_PGFA0),
+ GPIO_FN(SCIFA1_SCK), GPIO_FN(GPS_PGFA1),
+ GPIO_FN(SCIFA1_RTS), GPIO_FN(GPS_EPPSINMON),
+ GPIO_FN(SCIFA1_RXD), GPIO_FN(SCIFA1_CTS),
+ GPIO_FN(MSIOF1_TXD), GPIO_FN(SCIFA1_TXD2), GPIO_FN(GPS_TXD),
+ GPIO_FN(MSIOF1_TSYNC), GPIO_FN(SCIFA1_CTS2), GPIO_FN(I2C_SDA2),
+ GPIO_FN(MSIOF1_TSCK), GPIO_FN(SCIFA1_SCK2),
+ GPIO_FN(MSIOF1_RXD), GPIO_FN(SCIFA1_RXD2), GPIO_FN(GPS_RXD),
+ GPIO_FN(MSIOF1_RSCK), GPIO_FN(SCIFA1_RTS2),
+ GPIO_FN(MSIOF1_RSYNC), GPIO_FN(I2C_SCL2),
+ GPIO_FN(MSIOF1_MCK0), GPIO_FN(MSIOF1_MCK1),
+ GPIO_FN(MSIOF1_SS1), GPIO_FN(EDBGREQ3),
+ GPIO_FN(MSIOF1_SS2),
+ GPIO_FN(PORT236_IROUT), GPIO_FN(IRDA_OUT),
+ GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL),
+ GPIO_FN(TPU1TO0), GPIO_FN(TS_SPSYNC3),
+ GPIO_FN(TPU1TO1), GPIO_FN(TS_SDAT3),
+ GPIO_FN(TPU1TO2), GPIO_FN(TS_SDEN3), GPIO_FN(PORT241_MSIOF2_SS1),
+ GPIO_FN(TPU1TO3), GPIO_FN(PORT242_MSIOF2_TSCK),
+ GPIO_FN(M13_BSW), GPIO_FN(PORT243_MSIOF2_TSYNC),
+ GPIO_FN(M14_GSW), GPIO_FN(PORT244_MSIOF2_TXD),
+ GPIO_FN(PORT245_IROUT), GPIO_FN(M15_RSW),
+ GPIO_FN(SOUT3), GPIO_FN(SCIFA2_TXD1),
+ GPIO_FN(SIN3), GPIO_FN(SCIFA2_RXD1),
+ GPIO_FN(XRTS3), GPIO_FN(SCIFA2_RTS1), GPIO_FN(PORT248_MSIOF2_SS2),
+ GPIO_FN(XCTS3), GPIO_FN(SCIFA2_CTS1), GPIO_FN(PORT249_MSIOF2_RXD),
+ GPIO_FN(DINT), GPIO_FN(SCIFA2_SCK1), GPIO_FN(TS_SCK3),
+ GPIO_FN(SDHICLK0), GPIO_FN(TCK2),
+ GPIO_FN(SDHICD0),
+ GPIO_FN(SDHID0_0), GPIO_FN(TMS2),
+ GPIO_FN(SDHID0_1), GPIO_FN(TDO2),
+ GPIO_FN(SDHID0_2), GPIO_FN(TDI2),
+ GPIO_FN(SDHID0_3), GPIO_FN(RTCK2),
+
+ /* 49-6 (FN) */
+ GPIO_FN(SDHICMD0), GPIO_FN(TRST2),
+ GPIO_FN(SDHIWP0), GPIO_FN(EDBGREQ2),
+ GPIO_FN(SDHICLK1), GPIO_FN(TCK3),
+ GPIO_FN(SDHID1_0), GPIO_FN(M11_SLCD_SO2),
+ GPIO_FN(TS_SPSYNC2), GPIO_FN(TMS3),
+ GPIO_FN(SDHID1_1), GPIO_FN(M9_SLCD_AO2),
+ GPIO_FN(TS_SDAT2), GPIO_FN(TDO3),
+ GPIO_FN(SDHID1_2), GPIO_FN(M10_SLCD_CK2),
+ GPIO_FN(TS_SDEN2), GPIO_FN(TDI3),
+ GPIO_FN(SDHID1_3), GPIO_FN(M12_SLCD_CE2),
+ GPIO_FN(TS_SCK2), GPIO_FN(RTCK3),
+ GPIO_FN(SDHICMD1), GPIO_FN(TRST3),
+ GPIO_FN(SDHICLK2), GPIO_FN(SCIFB_SCK),
+ GPIO_FN(SDHID2_0), GPIO_FN(SCIFB_TXD),
+ GPIO_FN(SDHID2_1), GPIO_FN(SCIFB_CTS),
+ GPIO_FN(SDHID2_2), GPIO_FN(SCIFB_RXD),
+ GPIO_FN(SDHID2_3), GPIO_FN(SCIFB_RTS),
+ GPIO_FN(SDHICMD2),
+ GPIO_FN(RESETOUTS),
+ GPIO_FN(DIVLOCK),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out) \
+ 0, (out), (in), 0, \
+ 0, 0, 0, 0, \
+ 0, 0, (in_pd), 0, \
+ 0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg) \
+ { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU, PORT##nr##_OUT), \
+ PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
+ PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7 } \
+ }
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ PORTCR(0, 0xe6050000), /* PORT0CR */
+ PORTCR(1, 0xe6050001), /* PORT1CR */
+ PORTCR(2, 0xe6050002), /* PORT2CR */
+ PORTCR(3, 0xe6050003), /* PORT3CR */
+ PORTCR(4, 0xe6050004), /* PORT4CR */
+ PORTCR(5, 0xe6050005), /* PORT5CR */
+ PORTCR(6, 0xe6050006), /* PORT6CR */
+ PORTCR(7, 0xe6050007), /* PORT7CR */
+ PORTCR(8, 0xe6050008), /* PORT8CR */
+ PORTCR(9, 0xe6050009), /* PORT9CR */
+
+ PORTCR(10, 0xe605000a), /* PORT10CR */
+ PORTCR(11, 0xe605000b), /* PORT11CR */
+ PORTCR(12, 0xe605000c), /* PORT12CR */
+ PORTCR(13, 0xe605000d), /* PORT13CR */
+ PORTCR(14, 0xe605000e), /* PORT14CR */
+ PORTCR(15, 0xe605000f), /* PORT15CR */
+ PORTCR(16, 0xe6050010), /* PORT16CR */
+ PORTCR(17, 0xe6050011), /* PORT17CR */
+ PORTCR(18, 0xe6050012), /* PORT18CR */
+ PORTCR(19, 0xe6050013), /* PORT19CR */
+
+ PORTCR(20, 0xe6050014), /* PORT20CR */
+ PORTCR(21, 0xe6050015), /* PORT21CR */
+ PORTCR(22, 0xe6050016), /* PORT22CR */
+ PORTCR(23, 0xe6050017), /* PORT23CR */
+ PORTCR(24, 0xe6050018), /* PORT24CR */
+ PORTCR(25, 0xe6050019), /* PORT25CR */
+ PORTCR(26, 0xe605001a), /* PORT26CR */
+ PORTCR(27, 0xe605001b), /* PORT27CR */
+ PORTCR(28, 0xe605001c), /* PORT28CR */
+ PORTCR(29, 0xe605001d), /* PORT29CR */
+
+ PORTCR(30, 0xe605001e), /* PORT30CR */
+ PORTCR(31, 0xe605001f), /* PORT31CR */
+ PORTCR(32, 0xe6050020), /* PORT32CR */
+ PORTCR(33, 0xe6050021), /* PORT33CR */
+ PORTCR(34, 0xe6050022), /* PORT34CR */
+ PORTCR(35, 0xe6050023), /* PORT35CR */
+ PORTCR(36, 0xe6050024), /* PORT36CR */
+ PORTCR(37, 0xe6050025), /* PORT37CR */
+ PORTCR(38, 0xe6050026), /* PORT38CR */
+ PORTCR(39, 0xe6050027), /* PORT39CR */
+
+ PORTCR(40, 0xe6050028), /* PORT40CR */
+ PORTCR(41, 0xe6050029), /* PORT41CR */
+ PORTCR(42, 0xe605002a), /* PORT42CR */
+ PORTCR(43, 0xe605002b), /* PORT43CR */
+ PORTCR(44, 0xe605002c), /* PORT44CR */
+ PORTCR(45, 0xe605002d), /* PORT45CR */
+ PORTCR(46, 0xe605002e), /* PORT46CR */
+ PORTCR(47, 0xe605002f), /* PORT47CR */
+ PORTCR(48, 0xe6050030), /* PORT48CR */
+ PORTCR(49, 0xe6050031), /* PORT49CR */
+
+ PORTCR(50, 0xe6050032), /* PORT50CR */
+ PORTCR(51, 0xe6050033), /* PORT51CR */
+ PORTCR(52, 0xe6050034), /* PORT52CR */
+ PORTCR(53, 0xe6050035), /* PORT53CR */
+ PORTCR(54, 0xe6050036), /* PORT54CR */
+ PORTCR(55, 0xe6050037), /* PORT55CR */
+ PORTCR(56, 0xe6050038), /* PORT56CR */
+ PORTCR(57, 0xe6050039), /* PORT57CR */
+ PORTCR(58, 0xe605003a), /* PORT58CR */
+ PORTCR(59, 0xe605003b), /* PORT59CR */
+
+ PORTCR(60, 0xe605003c), /* PORT60CR */
+ PORTCR(61, 0xe605003d), /* PORT61CR */
+ PORTCR(62, 0xe605003e), /* PORT62CR */
+ PORTCR(63, 0xe605003f), /* PORT63CR */
+ PORTCR(64, 0xe6050040), /* PORT64CR */
+ PORTCR(65, 0xe6050041), /* PORT65CR */
+ PORTCR(66, 0xe6050042), /* PORT66CR */
+ PORTCR(67, 0xe6050043), /* PORT67CR */
+ PORTCR(68, 0xe6050044), /* PORT68CR */
+ PORTCR(69, 0xe6050045), /* PORT69CR */
+
+ PORTCR(70, 0xe6050046), /* PORT70CR */
+ PORTCR(71, 0xe6050047), /* PORT71CR */
+ PORTCR(72, 0xe6050048), /* PORT72CR */
+ PORTCR(73, 0xe6050049), /* PORT73CR */
+ PORTCR(74, 0xe605004a), /* PORT74CR */
+ PORTCR(75, 0xe605004b), /* PORT75CR */
+ PORTCR(76, 0xe605004c), /* PORT76CR */
+ PORTCR(77, 0xe605004d), /* PORT77CR */
+ PORTCR(78, 0xe605004e), /* PORT78CR */
+ PORTCR(79, 0xe605004f), /* PORT79CR */
+
+ PORTCR(80, 0xe6050050), /* PORT80CR */
+ PORTCR(81, 0xe6050051), /* PORT81CR */
+ PORTCR(82, 0xe6050052), /* PORT82CR */
+ PORTCR(83, 0xe6050053), /* PORT83CR */
+ PORTCR(84, 0xe6050054), /* PORT84CR */
+ PORTCR(85, 0xe6050055), /* PORT85CR */
+ PORTCR(86, 0xe6050056), /* PORT86CR */
+ PORTCR(87, 0xe6050057), /* PORT87CR */
+ PORTCR(88, 0xe6051058), /* PORT88CR */
+ PORTCR(89, 0xe6051059), /* PORT89CR */
+
+ PORTCR(90, 0xe605105a), /* PORT90CR */
+ PORTCR(91, 0xe605105b), /* PORT91CR */
+ PORTCR(92, 0xe605105c), /* PORT92CR */
+ PORTCR(93, 0xe605105d), /* PORT93CR */
+ PORTCR(94, 0xe605105e), /* PORT94CR */
+ PORTCR(95, 0xe605105f), /* PORT95CR */
+ PORTCR(96, 0xe6051060), /* PORT96CR */
+ PORTCR(97, 0xe6051061), /* PORT97CR */
+ PORTCR(98, 0xe6051062), /* PORT98CR */
+ PORTCR(99, 0xe6051063), /* PORT99CR */
+
+ PORTCR(100, 0xe6051064), /* PORT100CR */
+ PORTCR(101, 0xe6051065), /* PORT101CR */
+ PORTCR(102, 0xe6051066), /* PORT102CR */
+ PORTCR(103, 0xe6051067), /* PORT103CR */
+ PORTCR(104, 0xe6051068), /* PORT104CR */
+ PORTCR(105, 0xe6051069), /* PORT105CR */
+ PORTCR(106, 0xe605106a), /* PORT106CR */
+ PORTCR(107, 0xe605106b), /* PORT107CR */
+ PORTCR(108, 0xe605106c), /* PORT108CR */
+ PORTCR(109, 0xe605106d), /* PORT109CR */
+
+ PORTCR(110, 0xe605106e), /* PORT110CR */
+ PORTCR(111, 0xe605106f), /* PORT111CR */
+ PORTCR(112, 0xe6051070), /* PORT112CR */
+ PORTCR(113, 0xe6051071), /* PORT113CR */
+ PORTCR(114, 0xe6051072), /* PORT114CR */
+ PORTCR(115, 0xe6051073), /* PORT115CR */
+ PORTCR(116, 0xe6051074), /* PORT116CR */
+ PORTCR(117, 0xe6051075), /* PORT117CR */
+ PORTCR(118, 0xe6051076), /* PORT118CR */
+ PORTCR(119, 0xe6051077), /* PORT119CR */
+
+ PORTCR(120, 0xe6051078), /* PORT120CR */
+ PORTCR(121, 0xe6051079), /* PORT121CR */
+ PORTCR(122, 0xe605107a), /* PORT122CR */
+ PORTCR(123, 0xe605107b), /* PORT123CR */
+ PORTCR(124, 0xe605107c), /* PORT124CR */
+ PORTCR(125, 0xe605107d), /* PORT125CR */
+ PORTCR(126, 0xe605107e), /* PORT126CR */
+ PORTCR(127, 0xe605107f), /* PORT127CR */
+ PORTCR(128, 0xe6051080), /* PORT128CR */
+ PORTCR(129, 0xe6051081), /* PORT129CR */
+
+ PORTCR(130, 0xe6051082), /* PORT130CR */
+ PORTCR(131, 0xe6051083), /* PORT131CR */
+ PORTCR(132, 0xe6051084), /* PORT132CR */
+ PORTCR(133, 0xe6051085), /* PORT133CR */
+ PORTCR(134, 0xe6051086), /* PORT134CR */
+ PORTCR(135, 0xe6051087), /* PORT135CR */
+ PORTCR(136, 0xe6051088), /* PORT136CR */
+ PORTCR(137, 0xe6051089), /* PORT137CR */
+ PORTCR(138, 0xe605108a), /* PORT138CR */
+ PORTCR(139, 0xe605108b), /* PORT139CR */
+
+ PORTCR(140, 0xe605108c), /* PORT140CR */
+ PORTCR(141, 0xe605108d), /* PORT141CR */
+ PORTCR(142, 0xe605108e), /* PORT142CR */
+ PORTCR(143, 0xe605108f), /* PORT143CR */
+ PORTCR(144, 0xe6051090), /* PORT144CR */
+ PORTCR(145, 0xe6051091), /* PORT145CR */
+ PORTCR(146, 0xe6051092), /* PORT146CR */
+ PORTCR(147, 0xe6051093), /* PORT147CR */
+ PORTCR(148, 0xe6051094), /* PORT148CR */
+ PORTCR(149, 0xe6051095), /* PORT149CR */
+
+ PORTCR(150, 0xe6051096), /* PORT150CR */
+ PORTCR(151, 0xe6051097), /* PORT151CR */
+ PORTCR(152, 0xe6051098), /* PORT152CR */
+ PORTCR(153, 0xe6051099), /* PORT153CR */
+ PORTCR(154, 0xe605109a), /* PORT154CR */
+ PORTCR(155, 0xe605109b), /* PORT155CR */
+ PORTCR(156, 0xe605109c), /* PORT156CR */
+ PORTCR(157, 0xe605109d), /* PORT157CR */
+ PORTCR(158, 0xe605109e), /* PORT158CR */
+ PORTCR(159, 0xe605109f), /* PORT159CR */
+
+ PORTCR(160, 0xe60510a0), /* PORT160CR */
+ PORTCR(161, 0xe60510a1), /* PORT161CR */
+ PORTCR(162, 0xe60510a2), /* PORT162CR */
+ PORTCR(163, 0xe60510a3), /* PORT163CR */
+ PORTCR(164, 0xe60510a4), /* PORT164CR */
+ PORTCR(165, 0xe60510a5), /* PORT165CR */
+ PORTCR(166, 0xe60510a6), /* PORT166CR */
+ PORTCR(167, 0xe60510a7), /* PORT167CR */
+ PORTCR(168, 0xe60510a8), /* PORT168CR */
+ PORTCR(169, 0xe60510a9), /* PORT169CR */
+
+ PORTCR(170, 0xe60510aa), /* PORT170CR */
+ PORTCR(171, 0xe60510ab), /* PORT171CR */
+ PORTCR(172, 0xe60510ac), /* PORT172CR */
+ PORTCR(173, 0xe60510ad), /* PORT173CR */
+ PORTCR(174, 0xe60510ae), /* PORT174CR */
+ PORTCR(175, 0xe60520af), /* PORT175CR */
+ PORTCR(176, 0xe60520b0), /* PORT176CR */
+ PORTCR(177, 0xe60520b1), /* PORT177CR */
+ PORTCR(178, 0xe60520b2), /* PORT178CR */
+ PORTCR(179, 0xe60520b3), /* PORT179CR */
+
+ PORTCR(180, 0xe60520b4), /* PORT180CR */
+ PORTCR(181, 0xe60520b5), /* PORT181CR */
+ PORTCR(182, 0xe60520b6), /* PORT182CR */
+ PORTCR(183, 0xe60520b7), /* PORT183CR */
+ PORTCR(184, 0xe60520b8), /* PORT184CR */
+ PORTCR(185, 0xe60520b9), /* PORT185CR */
+ PORTCR(186, 0xe60520ba), /* PORT186CR */
+ PORTCR(187, 0xe60520bb), /* PORT187CR */
+ PORTCR(188, 0xe60520bc), /* PORT188CR */
+ PORTCR(189, 0xe60520bd), /* PORT189CR */
+
+ PORTCR(190, 0xe60520be), /* PORT190CR */
+ PORTCR(191, 0xe60520bf), /* PORT191CR */
+ PORTCR(192, 0xe60520c0), /* PORT192CR */
+ PORTCR(193, 0xe60520c1), /* PORT193CR */
+ PORTCR(194, 0xe60520c2), /* PORT194CR */
+ PORTCR(195, 0xe60520c3), /* PORT195CR */
+ PORTCR(196, 0xe60520c4), /* PORT196CR */
+ PORTCR(197, 0xe60520c5), /* PORT197CR */
+ PORTCR(198, 0xe60520c6), /* PORT198CR */
+ PORTCR(199, 0xe60520c7), /* PORT199CR */
+
+ PORTCR(200, 0xe60520c8), /* PORT200CR */
+ PORTCR(201, 0xe60520c9), /* PORT201CR */
+ PORTCR(202, 0xe60520ca), /* PORT202CR */
+ PORTCR(203, 0xe60520cb), /* PORT203CR */
+ PORTCR(204, 0xe60520cc), /* PORT204CR */
+ PORTCR(205, 0xe60520cd), /* PORT205CR */
+ PORTCR(206, 0xe60520ce), /* PORT206CR */
+ PORTCR(207, 0xe60520cf), /* PORT207CR */
+ PORTCR(208, 0xe60520d0), /* PORT208CR */
+ PORTCR(209, 0xe60520d1), /* PORT209CR */
+
+ PORTCR(210, 0xe60520d2), /* PORT210CR */
+ PORTCR(211, 0xe60520d3), /* PORT211CR */
+ PORTCR(212, 0xe60520d4), /* PORT212CR */
+ PORTCR(213, 0xe60520d5), /* PORT213CR */
+ PORTCR(214, 0xe60520d6), /* PORT214CR */
+ PORTCR(215, 0xe60520d7), /* PORT215CR */
+ PORTCR(216, 0xe60520d8), /* PORT216CR */
+ PORTCR(217, 0xe60520d9), /* PORT217CR */
+ PORTCR(218, 0xe60520da), /* PORT218CR */
+ PORTCR(219, 0xe60520db), /* PORT219CR */
+
+ PORTCR(220, 0xe60520dc), /* PORT220CR */
+ PORTCR(221, 0xe60520dd), /* PORT221CR */
+ PORTCR(222, 0xe60520de), /* PORT222CR */
+ PORTCR(223, 0xe60520df), /* PORT223CR */
+ PORTCR(224, 0xe60520e0), /* PORT224CR */
+ PORTCR(225, 0xe60520e1), /* PORT225CR */
+ PORTCR(226, 0xe60520e2), /* PORT226CR */
+ PORTCR(227, 0xe60520e3), /* PORT227CR */
+ PORTCR(228, 0xe60520e4), /* PORT228CR */
+ PORTCR(229, 0xe60520e5), /* PORT229CR */
+
+ PORTCR(230, 0xe60520e6), /* PORT230CR */
+ PORTCR(231, 0xe60520e7), /* PORT231CR */
+ PORTCR(232, 0xe60520e8), /* PORT232CR */
+ PORTCR(233, 0xe60520e9), /* PORT233CR */
+ PORTCR(234, 0xe60520ea), /* PORT234CR */
+ PORTCR(235, 0xe60520eb), /* PORT235CR */
+ PORTCR(236, 0xe60530ec), /* PORT236CR */
+ PORTCR(237, 0xe60530ed), /* PORT237CR */
+ PORTCR(238, 0xe60530ee), /* PORT238CR */
+ PORTCR(239, 0xe60530ef), /* PORT239CR */
+
+ PORTCR(240, 0xe60530f0), /* PORT240CR */
+ PORTCR(241, 0xe60530f1), /* PORT241CR */
+ PORTCR(242, 0xe60530f2), /* PORT242CR */
+ PORTCR(243, 0xe60530f3), /* PORT243CR */
+ PORTCR(244, 0xe60530f4), /* PORT244CR */
+ PORTCR(245, 0xe60530f5), /* PORT245CR */
+ PORTCR(246, 0xe60530f6), /* PORT246CR */
+ PORTCR(247, 0xe60530f7), /* PORT247CR */
+ PORTCR(248, 0xe60530f8), /* PORT248CR */
+ PORTCR(249, 0xe60530f9), /* PORT249CR */
+
+ PORTCR(250, 0xe60530fa), /* PORT250CR */
+ PORTCR(251, 0xe60530fb), /* PORT251CR */
+ PORTCR(252, 0xe60530fc), /* PORT252CR */
+ PORTCR(253, 0xe60530fd), /* PORT253CR */
+ PORTCR(254, 0xe60530fe), /* PORT254CR */
+ PORTCR(255, 0xe60530ff), /* PORT255CR */
+ PORTCR(256, 0xe6053100), /* PORT256CR */
+ PORTCR(257, 0xe6053101), /* PORT257CR */
+ PORTCR(258, 0xe6053102), /* PORT258CR */
+ PORTCR(259, 0xe6053103), /* PORT259CR */
+
+ PORTCR(260, 0xe6053104), /* PORT260CR */
+ PORTCR(261, 0xe6053105), /* PORT261CR */
+ PORTCR(262, 0xe6053106), /* PORT262CR */
+ PORTCR(263, 0xe6053107), /* PORT263CR */
+ PORTCR(264, 0xe6053108), /* PORT264CR */
+ PORTCR(265, 0xe6053109), /* PORT265CR */
+ PORTCR(266, 0xe605310a), /* PORT266CR */
+ PORTCR(267, 0xe605310b), /* PORT267CR */
+ PORTCR(268, 0xe605310c), /* PORT268CR */
+ PORTCR(269, 0xe605310d), /* PORT269CR */
+
+ PORTCR(270, 0xe605310e), /* PORT270CR */
+ PORTCR(271, 0xe605310f), /* PORT271CR */
+ PORTCR(272, 0xe6053110), /* PORT272CR */
+
+ { PINMUX_CFG_REG("MSELBCR", 0xe6058024, 32, 1) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSELBCR_MSEL2_0, MSELBCR_MSEL2_1,
+ 0, 0,
+ 0, 0 }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
+ PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+ PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+ PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+ PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+ PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+ PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+ PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+ PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL063_032DR", 0xe6054004, 32) {
+ PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+ PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+ PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+ PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+ PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
+ PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+ PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+ PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL095_064DR", 0xe6054008, 32) {
+ PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+ PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+ PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+ PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+ PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+ PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+ PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+ PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD127_096DR", 0xe6055004, 32) {
+ PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA,
+ PORT123_DATA, PORT122_DATA, PORT121_DATA, PORT120_DATA,
+ PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+ PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+ PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+ PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+ PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+ PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD159_128DR", 0xe6055008, 32) {
+ PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+ PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+ PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+ PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+ PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+ PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+ PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+ PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR191_160DR", 0xe6056000, 32) {
+ PORT191_DATA, PORT190_DATA, PORT189_DATA, PORT188_DATA,
+ PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA,
+ PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA,
+ PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA,
+ PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA,
+ PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA,
+ PORT167_DATA, PORT166_DATA, PORT165_DATA, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR223_192DR", 0xe6056004, 32) {
+ PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
+ PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
+ PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
+ PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
+ PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
+ PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
+ PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
+ PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU255_224DR", 0xe6057000, 32) {
+ PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
+ PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
+ PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
+ PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
+ PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
+ PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
+ PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
+ PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU287_256DR", 0xe6057004, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT272_DATA,
+ PORT271_DATA, PORT270_DATA, PORT269_DATA, PORT268_DATA,
+ PORT267_DATA, PORT266_DATA, PORT265_DATA, PORT264_DATA,
+ PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
+ PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7367_pinmux_info = {
+ .name = "sh7367_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PORT0,
+ .last_gpio = GPIO_FN_DIVLOCK,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7367_pinmux_init(void)
+{
+ register_pinmux(&sh7367_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c
new file mode 100644
index 00000000000..9557d0964d7
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-sh7372.c
@@ -0,0 +1,1637 @@
+/*
+ * sh7372 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010 Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on
+ * sh7367 processor support - PFC hardware block
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7372.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx) \
+ _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
+ _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
+ _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
+ _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
+ _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _80(fn, pfx, sfx) \
+ _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
+ _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
+ _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
+ _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx)
+
+#define _190(fn, pfx, sfx) \
+ _10(fn, pfx, sfx), _80(fn, pfx, sfx), _10(fn, pfx##9, sfx), \
+ _10(fn, pfx##10, sfx), _80(fn, pfx##1, sfx), _1(fn, pfx##190, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_ALL(str) _190(_PORT, PORT, str)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ /* PORT0_DATA -> PORT190_DATA */
+ PINMUX_DATA_BEGIN,
+ PORT_ALL(DATA),
+ PINMUX_DATA_END,
+
+ /* PORT0_IN -> PORT190_IN */
+ PINMUX_INPUT_BEGIN,
+ PORT_ALL(IN),
+ PINMUX_INPUT_END,
+
+ /* PORT0_IN_PU -> PORT190_IN_PU */
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_ALL(IN_PU),
+ PINMUX_INPUT_PULLUP_END,
+
+ /* PORT0_IN_PD -> PORT190_IN_PD */
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_ALL(IN_PD),
+ PINMUX_INPUT_PULLDOWN_END,
+
+ /* PORT0_OUT -> PORT190_OUT */
+ PINMUX_OUTPUT_BEGIN,
+ PORT_ALL(OUT),
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT190_FN_IN */
+ PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT190_FN_OUT */
+ PORT_ALL(FN0), /* PORT0_FN0 -> PORT190_FN0 */
+ PORT_ALL(FN1), /* PORT0_FN1 -> PORT190_FN1 */
+ PORT_ALL(FN2), /* PORT0_FN2 -> PORT190_FN2 */
+ PORT_ALL(FN3), /* PORT0_FN3 -> PORT190_FN3 */
+ PORT_ALL(FN4), /* PORT0_FN4 -> PORT190_FN4 */
+ PORT_ALL(FN5), /* PORT0_FN5 -> PORT190_FN5 */
+ PORT_ALL(FN6), /* PORT0_FN6 -> PORT190_FN6 */
+ PORT_ALL(FN7), /* PORT0_FN7 -> PORT190_FN7 */
+
+ MSEL1CR_31_0, MSEL1CR_31_1,
+ MSEL1CR_30_0, MSEL1CR_30_1,
+ MSEL1CR_29_0, MSEL1CR_29_1,
+ MSEL1CR_28_0, MSEL1CR_28_1,
+ MSEL1CR_27_0, MSEL1CR_27_1,
+ MSEL1CR_26_0, MSEL1CR_26_1,
+ MSEL1CR_16_0, MSEL1CR_16_1,
+ MSEL1CR_15_0, MSEL1CR_15_1,
+ MSEL1CR_14_0, MSEL1CR_14_1,
+ MSEL1CR_13_0, MSEL1CR_13_1,
+ MSEL1CR_12_0, MSEL1CR_12_1,
+ MSEL1CR_9_0, MSEL1CR_9_1,
+ MSEL1CR_8_0, MSEL1CR_8_1,
+ MSEL1CR_7_0, MSEL1CR_7_1,
+ MSEL1CR_6_0, MSEL1CR_6_1,
+ MSEL1CR_4_0, MSEL1CR_4_1,
+ MSEL1CR_3_0, MSEL1CR_3_1,
+ MSEL1CR_2_0, MSEL1CR_2_1,
+ MSEL1CR_0_0, MSEL1CR_0_1,
+
+ MSEL3CR_27_0, MSEL3CR_27_1,
+ MSEL3CR_26_0, MSEL3CR_26_1,
+ MSEL3CR_21_0, MSEL3CR_21_1,
+ MSEL3CR_20_0, MSEL3CR_20_1,
+ MSEL3CR_15_0, MSEL3CR_15_1,
+ MSEL3CR_9_0, MSEL3CR_9_1,
+ MSEL3CR_6_0, MSEL3CR_6_1,
+
+ MSEL4CR_19_0, MSEL4CR_19_1,
+ MSEL4CR_18_0, MSEL4CR_18_1,
+ MSEL4CR_17_0, MSEL4CR_17_1,
+ MSEL4CR_16_0, MSEL4CR_16_1,
+ MSEL4CR_15_0, MSEL4CR_15_1,
+ MSEL4CR_14_0, MSEL4CR_14_1,
+ MSEL4CR_10_0, MSEL4CR_10_1,
+ MSEL4CR_6_0, MSEL4CR_6_1,
+ MSEL4CR_4_0, MSEL4CR_4_1,
+ MSEL4CR_1_0, MSEL4CR_1_1,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+
+ /* IRQ */
+ IRQ0_6_MARK, IRQ0_162_MARK, IRQ1_MARK, IRQ2_4_MARK,
+ IRQ2_5_MARK, IRQ3_8_MARK, IRQ3_16_MARK, IRQ4_17_MARK,
+ IRQ4_163_MARK, IRQ5_MARK, IRQ6_39_MARK, IRQ6_164_MARK,
+ IRQ7_40_MARK, IRQ7_167_MARK, IRQ8_41_MARK, IRQ8_168_MARK,
+ IRQ9_42_MARK, IRQ9_169_MARK, IRQ10_MARK, IRQ11_MARK,
+ IRQ12_80_MARK, IRQ12_137_MARK, IRQ13_81_MARK, IRQ13_145_MARK,
+ IRQ14_82_MARK, IRQ14_146_MARK, IRQ15_83_MARK, IRQ15_147_MARK,
+ IRQ16_84_MARK, IRQ16_170_MARK, IRQ17_MARK, IRQ18_MARK,
+ IRQ19_MARK, IRQ20_MARK, IRQ21_MARK, IRQ22_MARK,
+ IRQ23_MARK, IRQ24_MARK, IRQ25_MARK, IRQ26_121_MARK,
+ IRQ26_172_MARK, IRQ27_122_MARK, IRQ27_180_MARK, IRQ28_123_MARK,
+ IRQ28_181_MARK, IRQ29_129_MARK, IRQ29_182_MARK, IRQ30_130_MARK,
+ IRQ30_183_MARK, IRQ31_138_MARK, IRQ31_184_MARK,
+
+ /* MSIOF0 */
+ MSIOF0_TSYNC_MARK, MSIOF0_TSCK_MARK, MSIOF0_RXD_MARK,
+ MSIOF0_RSCK_MARK, MSIOF0_RSYNC_MARK, MSIOF0_MCK0_MARK,
+ MSIOF0_MCK1_MARK, MSIOF0_SS1_MARK, MSIOF0_SS2_MARK,
+ MSIOF0_TXD_MARK,
+
+ /* MSIOF1 */
+ MSIOF1_TSCK_39_MARK, MSIOF1_TSYNC_40_MARK,
+ MSIOF1_TSCK_88_MARK, MSIOF1_TSYNC_89_MARK,
+ MSIOF1_TXD_41_MARK, MSIOF1_RXD_42_MARK,
+ MSIOF1_TXD_90_MARK, MSIOF1_RXD_91_MARK,
+ MSIOF1_SS1_43_MARK, MSIOF1_SS2_44_MARK,
+ MSIOF1_SS1_92_MARK, MSIOF1_SS2_93_MARK,
+ MSIOF1_RSCK_MARK, MSIOF1_RSYNC_MARK,
+ MSIOF1_MCK0_MARK, MSIOF1_MCK1_MARK,
+
+ /* MSIOF2 */
+ MSIOF2_RSCK_MARK, MSIOF2_RSYNC_MARK, MSIOF2_MCK0_MARK,
+ MSIOF2_MCK1_MARK, MSIOF2_SS1_MARK, MSIOF2_SS2_MARK,
+ MSIOF2_TSYNC_MARK, MSIOF2_TSCK_MARK, MSIOF2_RXD_MARK,
+ MSIOF2_TXD_MARK,
+
+ /* MSIOF3 */
+ BBIF1_RXD_MARK, BBIF1_TSYNC_MARK, BBIF1_TSCK_MARK,
+ BBIF1_TXD_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK,
+ BBIF1_FLOW_MARK, BB_RX_FLOW_N_MARK,
+
+ /* MSIOF4 */
+ BBIF2_TSCK1_MARK, BBIF2_TSYNC1_MARK,
+ BBIF2_TXD1_MARK, BBIF2_RXD_MARK,
+
+ /* FSI */
+ FSIACK_MARK, FSIBCK_MARK, FSIAILR_MARK, FSIAIBT_MARK,
+ FSIAISLD_MARK, FSIAOMC_MARK, FSIAOLR_MARK, FSIAOBT_MARK,
+ FSIAOSLD_MARK, FSIASPDIF_11_MARK, FSIASPDIF_15_MARK,
+
+ /* FMSI */
+ FMSOCK_MARK, FMSOOLR_MARK, FMSIOLR_MARK, FMSOOBT_MARK,
+ FMSIOBT_MARK, FMSOSLD_MARK, FMSOILR_MARK, FMSIILR_MARK,
+ FMSOIBT_MARK, FMSIIBT_MARK, FMSISLD_MARK, FMSICK_MARK,
+
+ /* SCIFA0 */
+ SCIFA0_TXD_MARK, SCIFA0_RXD_MARK, SCIFA0_SCK_MARK,
+ SCIFA0_RTS_MARK, SCIFA0_CTS_MARK,
+
+ /* SCIFA1 */
+ SCIFA1_TXD_MARK, SCIFA1_RXD_MARK, SCIFA1_SCK_MARK,
+ SCIFA1_RTS_MARK, SCIFA1_CTS_MARK,
+
+ /* SCIFA2 */
+ SCIFA2_CTS1_MARK, SCIFA2_RTS1_MARK, SCIFA2_TXD1_MARK,
+ SCIFA2_RXD1_MARK, SCIFA2_SCK1_MARK,
+
+ /* SCIFA3 */
+ SCIFA3_CTS_43_MARK, SCIFA3_CTS_140_MARK, SCIFA3_RTS_44_MARK,
+ SCIFA3_RTS_141_MARK, SCIFA3_SCK_MARK, SCIFA3_TXD_MARK,
+ SCIFA3_RXD_MARK,
+
+ /* SCIFA4 */
+ SCIFA4_RXD_MARK, SCIFA4_TXD_MARK,
+
+ /* SCIFA5 */
+ SCIFA5_RXD_MARK, SCIFA5_TXD_MARK,
+
+ /* SCIFB */
+ SCIFB_SCK_MARK, SCIFB_RTS_MARK, SCIFB_CTS_MARK,
+ SCIFB_TXD_MARK, SCIFB_RXD_MARK,
+
+ /* CEU */
+ VIO_HD_MARK, VIO_CKO1_MARK, VIO_CKO2_MARK, VIO_VD_MARK,
+ VIO_CLK_MARK, VIO_FIELD_MARK, VIO_CKO_MARK,
+ VIO_D0_MARK, VIO_D1_MARK, VIO_D2_MARK, VIO_D3_MARK,
+ VIO_D4_MARK, VIO_D5_MARK, VIO_D6_MARK, VIO_D7_MARK,
+ VIO_D8_MARK, VIO_D9_MARK, VIO_D10_MARK, VIO_D11_MARK,
+ VIO_D12_MARK, VIO_D13_MARK, VIO_D14_MARK, VIO_D15_MARK,
+
+ /* USB0 */
+ IDIN_0_MARK, EXTLP_0_MARK, OVCN2_0_MARK, PWEN_0_MARK,
+ OVCN_0_MARK, VBUS0_0_MARK,
+
+ /* USB1 */
+ IDIN_1_18_MARK, IDIN_1_113_MARK,
+ PWEN_1_115_MARK, PWEN_1_138_MARK,
+ OVCN_1_114_MARK, OVCN_1_162_MARK,
+ EXTLP_1_MARK, OVCN2_1_MARK,
+ VBUS0_1_MARK,
+
+ /* GPIO */
+ GPI0_MARK, GPI1_MARK, GPO0_MARK, GPO1_MARK,
+
+ /* BSC */
+ BS_MARK, WE1_MARK,
+ CKO_MARK, WAIT_MARK, RDWR_MARK,
+
+ A0_MARK, A1_MARK, A2_MARK, A3_MARK,
+ A6_MARK, A7_MARK, A8_MARK, A9_MARK,
+ A10_MARK, A11_MARK, A12_MARK, A13_MARK,
+ A14_MARK, A15_MARK, A16_MARK, A17_MARK,
+ A18_MARK, A19_MARK, A20_MARK, A21_MARK,
+ A22_MARK, A23_MARK, A24_MARK, A25_MARK,
+ A26_MARK,
+
+ CS0_MARK, CS2_MARK, CS4_MARK,
+ CS5A_MARK, CS5B_MARK, CS6A_MARK,
+
+ /* BSC/FLCTL */
+ RD_FSC_MARK, WE0_FWE_MARK, A4_FOE_MARK, A5_FCDE_MARK,
+ D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK,
+ D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK,
+ D8_NAF8_MARK, D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK,
+ D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, D15_NAF15_MARK,
+
+ /* MMCIF(1) */
+ MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK,
+ MMCD0_4_MARK, MMCD0_5_MARK, MMCD0_6_MARK, MMCD0_7_MARK,
+ MMCCMD0_MARK, MMCCLK0_MARK,
+
+ /* MMCIF(2) */
+ MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK,
+ MMCD1_4_MARK, MMCD1_5_MARK, MMCD1_6_MARK, MMCD1_7_MARK,
+ MMCCLK1_MARK, MMCCMD1_MARK,
+
+ /* SPU2 */
+ VINT_I_MARK,
+
+ /* FLCTL */
+ FCE1_MARK, FCE0_MARK, FRB_MARK,
+
+ /* HSI */
+ GP_RX_FLAG_MARK, GP_RX_DATA_MARK, GP_TX_READY_MARK,
+ GP_RX_WAKE_MARK, MP_TX_FLAG_MARK, MP_TX_DATA_MARK,
+ MP_RX_READY_MARK, MP_TX_WAKE_MARK,
+
+ /* MFI */
+ MFIv6_MARK,
+ MFIv4_MARK,
+
+ MEMC_CS0_MARK, MEMC_BUSCLK_MEMC_A0_MARK,
+ MEMC_CS1_MEMC_A1_MARK, MEMC_ADV_MEMC_DREQ0_MARK,
+ MEMC_WAIT_MEMC_DREQ1_MARK, MEMC_NOE_MARK,
+ MEMC_NWE_MARK, MEMC_INT_MARK,
+
+ MEMC_AD0_MARK, MEMC_AD1_MARK, MEMC_AD2_MARK,
+ MEMC_AD3_MARK, MEMC_AD4_MARK, MEMC_AD5_MARK,
+ MEMC_AD6_MARK, MEMC_AD7_MARK, MEMC_AD8_MARK,
+ MEMC_AD9_MARK, MEMC_AD10_MARK, MEMC_AD11_MARK,
+ MEMC_AD12_MARK, MEMC_AD13_MARK, MEMC_AD14_MARK,
+ MEMC_AD15_MARK,
+
+ /* SIM */
+ SIM_RST_MARK, SIM_CLK_MARK, SIM_D_MARK,
+
+ /* TPU */
+ TPU0TO0_MARK, TPU0TO1_MARK,
+ TPU0TO2_93_MARK, TPU0TO2_99_MARK,
+ TPU0TO3_MARK,
+
+ /* I2C2 */
+ I2C_SCL2_MARK, I2C_SDA2_MARK,
+
+ /* I2C3(1) */
+ I2C_SCL3_MARK, I2C_SDA3_MARK,
+
+ /* I2C3(2) */
+ I2C_SCL3S_MARK, I2C_SDA3S_MARK,
+
+ /* I2C4(2) */
+ I2C_SCL4_MARK, I2C_SDA4_MARK,
+
+ /* I2C4(2) */
+ I2C_SCL4S_MARK, I2C_SDA4S_MARK,
+
+ /* KEYSC */
+ KEYOUT0_MARK, KEYIN0_121_MARK, KEYIN0_136_MARK,
+ KEYOUT1_MARK, KEYIN1_122_MARK, KEYIN1_135_MARK,
+ KEYOUT2_MARK, KEYIN2_123_MARK, KEYIN2_134_MARK,
+ KEYOUT3_MARK, KEYIN3_124_MARK, KEYIN3_133_MARK,
+ KEYOUT4_MARK, KEYIN4_MARK,
+ KEYOUT5_MARK, KEYIN5_MARK,
+ KEYOUT6_MARK, KEYIN6_MARK,
+ KEYOUT7_MARK, KEYIN7_MARK,
+
+ /* LCDC */
+ LCDC0_SELECT_MARK,
+ LCDC1_SELECT_MARK,
+ LCDHSYN_MARK, LCDCS_MARK, LCDVSYN_MARK, LCDDCK_MARK,
+ LCDWR_MARK, LCDRD_MARK, LCDDISP_MARK, LCDRS_MARK,
+ LCDLCLK_MARK, LCDDON_MARK,
+
+ LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK,
+ LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK,
+ LCDD8_MARK, LCDD9_MARK, LCDD10_MARK, LCDD11_MARK,
+ LCDD12_MARK, LCDD13_MARK, LCDD14_MARK, LCDD15_MARK,
+ LCDD16_MARK, LCDD17_MARK, LCDD18_MARK, LCDD19_MARK,
+ LCDD20_MARK, LCDD21_MARK, LCDD22_MARK, LCDD23_MARK,
+
+ /* IRDA */
+ IRDA_OUT_MARK, IRDA_IN_MARK, IRDA_FIRSEL_MARK,
+ IROUT_139_MARK, IROUT_140_MARK,
+
+ /* TSIF1 */
+ TS0_1SELECT_MARK,
+ TS0_2SELECT_MARK,
+ TS1_1SELECT_MARK,
+ TS1_2SELECT_MARK,
+
+ TS_SPSYNC1_MARK, TS_SDAT1_MARK,
+ TS_SDEN1_MARK, TS_SCK1_MARK,
+
+ /* TSIF2 */
+ TS_SPSYNC2_MARK, TS_SDAT2_MARK,
+ TS_SDEN2_MARK, TS_SCK2_MARK,
+
+ /* HDMI */
+ HDMI_HPD_MARK, HDMI_CEC_MARK,
+
+ /* SDHI0 */
+ SDHICLK0_MARK, SDHICD0_MARK,
+ SDHICMD0_MARK, SDHIWP0_MARK,
+ SDHID0_0_MARK, SDHID0_1_MARK,
+ SDHID0_2_MARK, SDHID0_3_MARK,
+
+ /* SDHI1 */
+ SDHICLK1_MARK, SDHICMD1_MARK, SDHID1_0_MARK,
+ SDHID1_1_MARK, SDHID1_2_MARK, SDHID1_3_MARK,
+
+ /* SDHI2 */
+ SDHICLK2_MARK, SDHICMD2_MARK, SDHID2_0_MARK,
+ SDHID2_1_MARK, SDHID2_2_MARK, SDHID2_3_MARK,
+
+ /* SDENC */
+ SDENC_CPG_MARK,
+ SDENC_DV_CLKI_MARK,
+
+ PINMUX_MARK_END,
+};
+
+/* PORT_DATA_I_PD(nr) */
+#define _I___D(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+/* PORT_DATA_I_PU(nr) */
+#define _I__U_(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+/* PORT_DATA_I_PU_PD(nr) */
+#define _I__UD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+/* PORT_DATA_O(nr) */
+#define __O___(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
+
+/* PORT_DATA_IO(nr) */
+#define _IO___(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN)
+
+/* PORT_DATA_IO_PD(nr) */
+#define _IO__D(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+/* PORT_DATA_IO_PU(nr) */
+#define _IO_U_(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+/* PORT_DATA_IO_PU_PD(nr) */
+#define _IO_UD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+
+static pinmux_enum_t pinmux_data[] = {
+
+ /* specify valid pin states for each pin in GPIO mode */
+
+ _IO__D(0), _IO__D(1), __O___(2), _I___D(3), _I___D(4),
+ _I___D(5), _IO_UD(6), _I___D(7), _IO__D(8), __O___(9),
+
+ __O___(10), __O___(11), _IO_UD(12), _IO__D(13), _IO__D(14),
+ __O___(15), _IO__D(16), _IO__D(17), _I___D(18), _IO___(19),
+
+ _IO___(20), _IO___(21), _IO___(22), _IO___(23), _IO___(24),
+ _IO___(25), _IO___(26), _IO___(27), _IO___(28), _IO___(29),
+
+ _IO___(30), _IO___(31), _IO___(32), _IO___(33), _IO___(34),
+ _IO___(35), _IO___(36), _IO___(37), _IO___(38), _IO___(39),
+
+ _IO___(40), _IO___(41), _IO___(42), _IO___(43), _IO___(44),
+ _IO___(45), _IO_U_(46), _IO_U_(47), _IO_U_(48), _IO_U_(49),
+
+ _IO_U_(50), _IO_U_(51), _IO_U_(52), _IO_U_(53), _IO_U_(54),
+ _IO_U_(55), _IO_U_(56), _IO_U_(57), _IO_U_(58), _IO_U_(59),
+
+ _IO_U_(60), _IO_U_(61), _IO___(62), __O___(63), __O___(64),
+ _IO_U_(65), __O___(66), _IO_U_(67), __O___(68), _IO___(69), /*66?*/
+
+ _IO___(70), _IO___(71), __O___(72), _I__U_(73), _I__UD(74),
+ _IO_UD(75), _IO_UD(76), _IO_UD(77), _IO_UD(78), _IO_UD(79),
+
+ _IO_UD(80), _IO_UD(81), _IO_UD(82), _IO_UD(83), _IO_UD(84),
+ _IO_UD(85), _IO_UD(86), _IO_UD(87), _IO_UD(88), _IO_UD(89),
+
+ _IO_UD(90), _IO_UD(91), _IO_UD(92), _IO_UD(93), _IO_UD(94),
+ _IO_UD(95), _IO_U_(96), _IO_UD(97), _IO_UD(98), __O___(99), /*99?*/
+
+ _IO__D(100), _IO__D(101), _IO__D(102), _IO__D(103), _IO__D(104),
+ _IO__D(105), _IO_U_(106), _IO_U_(107), _IO_U_(108), _IO_U_(109),
+
+ _IO_U_(110), _IO_U_(111), _IO__D(112), _IO__D(113), _IO_U_(114),
+ _IO_U_(115), _IO_U_(116), _IO_U_(117), _IO_U_(118), _IO_U_(119),
+
+ _IO_U_(120), _IO__D(121), _IO__D(122), _IO__D(123), _IO__D(124),
+ _IO__D(125), _IO__D(126), _IO__D(127), _IO__D(128), _IO_UD(129),
+
+ _IO_UD(130), _IO_UD(131), _IO_UD(132), _IO_UD(133), _IO_UD(134),
+ _IO_UD(135), _IO__D(136), _IO__D(137), _IO__D(138), _IO__D(139),
+
+ _IO__D(140), _IO__D(141), _IO__D(142), _IO_UD(143), _IO__D(144),
+ _IO__D(145), _IO__D(146), _IO__D(147), _IO__D(148), _IO__D(149),
+
+ _IO__D(150), _IO__D(151), _IO_UD(152), _I___D(153), _IO_UD(154),
+ _I___D(155), _IO__D(156), _IO__D(157), _I___D(158), _IO__D(159),
+
+ __O___(160), _IO__D(161), _IO__D(162), _IO__D(163), _I___D(164),
+ _IO__D(165), _I___D(166), _I___D(167), _I___D(168), _I___D(169),
+
+ _I___D(170), __O___(171), _IO_UD(172), _IO_UD(173), _IO_UD(174),
+ _IO_UD(175), _IO_UD(176), _IO_UD(177), _IO_UD(178), __O___(179),
+
+ _IO_UD(180), _IO_UD(181), _IO_UD(182), _IO_UD(183), _IO_UD(184),
+ __O___(185), _IO_UD(186), _IO_UD(187), _IO_UD(188), _IO_UD(189),
+
+ _IO_UD(190),
+
+ /* IRQ */
+ PINMUX_DATA(IRQ0_6_MARK, PORT6_FN0, MSEL1CR_0_0),
+ PINMUX_DATA(IRQ0_162_MARK, PORT162_FN0, MSEL1CR_0_1),
+ PINMUX_DATA(IRQ1_MARK, PORT12_FN0),
+ PINMUX_DATA(IRQ2_4_MARK, PORT4_FN0, MSEL1CR_2_0),
+ PINMUX_DATA(IRQ2_5_MARK, PORT5_FN0, MSEL1CR_2_1),
+ PINMUX_DATA(IRQ3_8_MARK, PORT8_FN0, MSEL1CR_3_0),
+ PINMUX_DATA(IRQ3_16_MARK, PORT16_FN0, MSEL1CR_3_1),
+ PINMUX_DATA(IRQ4_17_MARK, PORT17_FN0, MSEL1CR_4_0),
+ PINMUX_DATA(IRQ4_163_MARK, PORT163_FN0, MSEL1CR_4_1),
+ PINMUX_DATA(IRQ5_MARK, PORT18_FN0),
+ PINMUX_DATA(IRQ6_39_MARK, PORT39_FN0, MSEL1CR_6_0),
+ PINMUX_DATA(IRQ6_164_MARK, PORT164_FN0, MSEL1CR_6_1),
+ PINMUX_DATA(IRQ7_40_MARK, PORT40_FN0, MSEL1CR_7_1),
+ PINMUX_DATA(IRQ7_167_MARK, PORT167_FN0, MSEL1CR_7_0),
+ PINMUX_DATA(IRQ8_41_MARK, PORT41_FN0, MSEL1CR_8_1),
+ PINMUX_DATA(IRQ8_168_MARK, PORT168_FN0, MSEL1CR_8_0),
+ PINMUX_DATA(IRQ9_42_MARK, PORT42_FN0, MSEL1CR_9_0),
+ PINMUX_DATA(IRQ9_169_MARK, PORT169_FN0, MSEL1CR_9_1),
+ PINMUX_DATA(IRQ10_MARK, PORT65_FN0, MSEL1CR_9_1),
+ PINMUX_DATA(IRQ11_MARK, PORT67_FN0),
+ PINMUX_DATA(IRQ12_80_MARK, PORT80_FN0, MSEL1CR_12_0),
+ PINMUX_DATA(IRQ12_137_MARK, PORT137_FN0, MSEL1CR_12_1),
+ PINMUX_DATA(IRQ13_81_MARK, PORT81_FN0, MSEL1CR_13_0),
+ PINMUX_DATA(IRQ13_145_MARK, PORT145_FN0, MSEL1CR_13_1),
+ PINMUX_DATA(IRQ14_82_MARK, PORT82_FN0, MSEL1CR_14_0),
+ PINMUX_DATA(IRQ14_146_MARK, PORT146_FN0, MSEL1CR_14_1),
+ PINMUX_DATA(IRQ15_83_MARK, PORT83_FN0, MSEL1CR_15_0),
+ PINMUX_DATA(IRQ15_147_MARK, PORT147_FN0, MSEL1CR_15_1),
+ PINMUX_DATA(IRQ16_84_MARK, PORT84_FN0, MSEL1CR_16_0),
+ PINMUX_DATA(IRQ16_170_MARK, PORT170_FN0, MSEL1CR_16_1),
+ PINMUX_DATA(IRQ17_MARK, PORT85_FN0),
+ PINMUX_DATA(IRQ18_MARK, PORT86_FN0),
+ PINMUX_DATA(IRQ19_MARK, PORT87_FN0),
+ PINMUX_DATA(IRQ20_MARK, PORT92_FN0),
+ PINMUX_DATA(IRQ21_MARK, PORT93_FN0),
+ PINMUX_DATA(IRQ22_MARK, PORT94_FN0),
+ PINMUX_DATA(IRQ23_MARK, PORT95_FN0),
+ PINMUX_DATA(IRQ24_MARK, PORT112_FN0),
+ PINMUX_DATA(IRQ25_MARK, PORT119_FN0),
+ PINMUX_DATA(IRQ26_121_MARK, PORT121_FN0, MSEL1CR_26_1),
+ PINMUX_DATA(IRQ26_172_MARK, PORT172_FN0, MSEL1CR_26_0),
+ PINMUX_DATA(IRQ27_122_MARK, PORT122_FN0, MSEL1CR_27_1),
+ PINMUX_DATA(IRQ27_180_MARK, PORT180_FN0, MSEL1CR_27_0),
+ PINMUX_DATA(IRQ28_123_MARK, PORT123_FN0, MSEL1CR_28_1),
+ PINMUX_DATA(IRQ28_181_MARK, PORT181_FN0, MSEL1CR_28_0),
+ PINMUX_DATA(IRQ29_129_MARK, PORT129_FN0, MSEL1CR_29_1),
+ PINMUX_DATA(IRQ29_182_MARK, PORT182_FN0, MSEL1CR_29_0),
+ PINMUX_DATA(IRQ30_130_MARK, PORT130_FN0, MSEL1CR_30_1),
+ PINMUX_DATA(IRQ30_183_MARK, PORT183_FN0, MSEL1CR_30_0),
+ PINMUX_DATA(IRQ31_138_MARK, PORT138_FN0, MSEL1CR_31_1),
+ PINMUX_DATA(IRQ31_184_MARK, PORT184_FN0, MSEL1CR_31_0),
+
+ /* Function 1 */
+ PINMUX_DATA(BBIF2_TSCK1_MARK, PORT0_FN1),
+ PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT1_FN1),
+ PINMUX_DATA(BBIF2_TXD1_MARK, PORT2_FN1),
+ PINMUX_DATA(BBIF2_RXD_MARK, PORT3_FN1),
+ PINMUX_DATA(FSIACK_MARK, PORT4_FN1),
+ PINMUX_DATA(FSIAILR_MARK, PORT5_FN1),
+ PINMUX_DATA(FSIAIBT_MARK, PORT6_FN1),
+ PINMUX_DATA(FSIAISLD_MARK, PORT7_FN1),
+ PINMUX_DATA(FSIAOMC_MARK, PORT8_FN1),
+ PINMUX_DATA(FSIAOLR_MARK, PORT9_FN1),
+ PINMUX_DATA(FSIAOBT_MARK, PORT10_FN1),
+ PINMUX_DATA(FSIAOSLD_MARK, PORT11_FN1),
+ PINMUX_DATA(FMSOCK_MARK, PORT12_FN1),
+ PINMUX_DATA(FMSOOLR_MARK, PORT13_FN1),
+ PINMUX_DATA(FMSOOBT_MARK, PORT14_FN1),
+ PINMUX_DATA(FMSOSLD_MARK, PORT15_FN1),
+ PINMUX_DATA(FMSOILR_MARK, PORT16_FN1),
+ PINMUX_DATA(FMSOIBT_MARK, PORT17_FN1),
+ PINMUX_DATA(FMSISLD_MARK, PORT18_FN1),
+ PINMUX_DATA(A0_MARK, PORT19_FN1),
+ PINMUX_DATA(A1_MARK, PORT20_FN1),
+ PINMUX_DATA(A2_MARK, PORT21_FN1),
+ PINMUX_DATA(A3_MARK, PORT22_FN1),
+ PINMUX_DATA(A4_FOE_MARK, PORT23_FN1),
+ PINMUX_DATA(A5_FCDE_MARK, PORT24_FN1),
+ PINMUX_DATA(A6_MARK, PORT25_FN1),
+ PINMUX_DATA(A7_MARK, PORT26_FN1),
+ PINMUX_DATA(A8_MARK, PORT27_FN1),
+ PINMUX_DATA(A9_MARK, PORT28_FN1),
+ PINMUX_DATA(A10_MARK, PORT29_FN1),
+ PINMUX_DATA(A11_MARK, PORT30_FN1),
+ PINMUX_DATA(A12_MARK, PORT31_FN1),
+ PINMUX_DATA(A13_MARK, PORT32_FN1),
+ PINMUX_DATA(A14_MARK, PORT33_FN1),
+ PINMUX_DATA(A15_MARK, PORT34_FN1),
+ PINMUX_DATA(A16_MARK, PORT35_FN1),
+ PINMUX_DATA(A17_MARK, PORT36_FN1),
+ PINMUX_DATA(A18_MARK, PORT37_FN1),
+ PINMUX_DATA(A19_MARK, PORT38_FN1),
+ PINMUX_DATA(A20_MARK, PORT39_FN1),
+ PINMUX_DATA(A21_MARK, PORT40_FN1),
+ PINMUX_DATA(A22_MARK, PORT41_FN1),
+ PINMUX_DATA(A23_MARK, PORT42_FN1),
+ PINMUX_DATA(A24_MARK, PORT43_FN1),
+ PINMUX_DATA(A25_MARK, PORT44_FN1),
+ PINMUX_DATA(A26_MARK, PORT45_FN1),
+ PINMUX_DATA(D0_NAF0_MARK, PORT46_FN1),
+ PINMUX_DATA(D1_NAF1_MARK, PORT47_FN1),
+ PINMUX_DATA(D2_NAF2_MARK, PORT48_FN1),
+ PINMUX_DATA(D3_NAF3_MARK, PORT49_FN1),
+ PINMUX_DATA(D4_NAF4_MARK, PORT50_FN1),
+ PINMUX_DATA(D5_NAF5_MARK, PORT51_FN1),
+ PINMUX_DATA(D6_NAF6_MARK, PORT52_FN1),
+ PINMUX_DATA(D7_NAF7_MARK, PORT53_FN1),
+ PINMUX_DATA(D8_NAF8_MARK, PORT54_FN1),
+ PINMUX_DATA(D9_NAF9_MARK, PORT55_FN1),
+ PINMUX_DATA(D10_NAF10_MARK, PORT56_FN1),
+ PINMUX_DATA(D11_NAF11_MARK, PORT57_FN1),
+ PINMUX_DATA(D12_NAF12_MARK, PORT58_FN1),
+ PINMUX_DATA(D13_NAF13_MARK, PORT59_FN1),
+ PINMUX_DATA(D14_NAF14_MARK, PORT60_FN1),
+ PINMUX_DATA(D15_NAF15_MARK, PORT61_FN1),
+ PINMUX_DATA(CS0_MARK, PORT62_FN1),
+ PINMUX_DATA(CS2_MARK, PORT63_FN1),
+ PINMUX_DATA(CS4_MARK, PORT64_FN1),
+ PINMUX_DATA(CS5A_MARK, PORT65_FN1),
+ PINMUX_DATA(CS5B_MARK, PORT66_FN1),
+ PINMUX_DATA(CS6A_MARK, PORT67_FN1),
+ PINMUX_DATA(FCE0_MARK, PORT68_FN1),
+ PINMUX_DATA(RD_FSC_MARK, PORT69_FN1),
+ PINMUX_DATA(WE0_FWE_MARK, PORT70_FN1),
+ PINMUX_DATA(WE1_MARK, PORT71_FN1),
+ PINMUX_DATA(CKO_MARK, PORT72_FN1),
+ PINMUX_DATA(FRB_MARK, PORT73_FN1),
+ PINMUX_DATA(WAIT_MARK, PORT74_FN1),
+ PINMUX_DATA(RDWR_MARK, PORT75_FN1),
+ PINMUX_DATA(MEMC_AD0_MARK, PORT76_FN1),
+ PINMUX_DATA(MEMC_AD1_MARK, PORT77_FN1),
+ PINMUX_DATA(MEMC_AD2_MARK, PORT78_FN1),
+ PINMUX_DATA(MEMC_AD3_MARK, PORT79_FN1),
+ PINMUX_DATA(MEMC_AD4_MARK, PORT80_FN1),
+ PINMUX_DATA(MEMC_AD5_MARK, PORT81_FN1),
+ PINMUX_DATA(MEMC_AD6_MARK, PORT82_FN1),
+ PINMUX_DATA(MEMC_AD7_MARK, PORT83_FN1),
+ PINMUX_DATA(MEMC_AD8_MARK, PORT84_FN1),
+ PINMUX_DATA(MEMC_AD9_MARK, PORT85_FN1),
+ PINMUX_DATA(MEMC_AD10_MARK, PORT86_FN1),
+ PINMUX_DATA(MEMC_AD11_MARK, PORT87_FN1),
+ PINMUX_DATA(MEMC_AD12_MARK, PORT88_FN1),
+ PINMUX_DATA(MEMC_AD13_MARK, PORT89_FN1),
+ PINMUX_DATA(MEMC_AD14_MARK, PORT90_FN1),
+ PINMUX_DATA(MEMC_AD15_MARK, PORT91_FN1),
+ PINMUX_DATA(MEMC_CS0_MARK, PORT92_FN1),
+ PINMUX_DATA(MEMC_BUSCLK_MEMC_A0_MARK, PORT93_FN1),
+ PINMUX_DATA(MEMC_CS1_MEMC_A1_MARK, PORT94_FN1),
+ PINMUX_DATA(MEMC_ADV_MEMC_DREQ0_MARK, PORT95_FN1),
+ PINMUX_DATA(MEMC_WAIT_MEMC_DREQ1_MARK, PORT96_FN1),
+ PINMUX_DATA(MEMC_NOE_MARK, PORT97_FN1),
+ PINMUX_DATA(MEMC_NWE_MARK, PORT98_FN1),
+ PINMUX_DATA(MEMC_INT_MARK, PORT99_FN1),
+ PINMUX_DATA(VIO_VD_MARK, PORT100_FN1),
+ PINMUX_DATA(VIO_HD_MARK, PORT101_FN1),
+ PINMUX_DATA(VIO_D0_MARK, PORT102_FN1),
+ PINMUX_DATA(VIO_D1_MARK, PORT103_FN1),
+ PINMUX_DATA(VIO_D2_MARK, PORT104_FN1),
+ PINMUX_DATA(VIO_D3_MARK, PORT105_FN1),
+ PINMUX_DATA(VIO_D4_MARK, PORT106_FN1),
+ PINMUX_DATA(VIO_D5_MARK, PORT107_FN1),
+ PINMUX_DATA(VIO_D6_MARK, PORT108_FN1),
+ PINMUX_DATA(VIO_D7_MARK, PORT109_FN1),
+ PINMUX_DATA(VIO_D8_MARK, PORT110_FN1),
+ PINMUX_DATA(VIO_D9_MARK, PORT111_FN1),
+ PINMUX_DATA(VIO_D10_MARK, PORT112_FN1),
+ PINMUX_DATA(VIO_D11_MARK, PORT113_FN1),
+ PINMUX_DATA(VIO_D12_MARK, PORT114_FN1),
+ PINMUX_DATA(VIO_D13_MARK, PORT115_FN1),
+ PINMUX_DATA(VIO_D14_MARK, PORT116_FN1),
+ PINMUX_DATA(VIO_D15_MARK, PORT117_FN1),
+ PINMUX_DATA(VIO_CLK_MARK, PORT118_FN1),
+ PINMUX_DATA(VIO_FIELD_MARK, PORT119_FN1),
+ PINMUX_DATA(VIO_CKO_MARK, PORT120_FN1),
+ PINMUX_DATA(LCDD0_MARK, PORT121_FN1),
+ PINMUX_DATA(LCDD1_MARK, PORT122_FN1),
+ PINMUX_DATA(LCDD2_MARK, PORT123_FN1),
+ PINMUX_DATA(LCDD3_MARK, PORT124_FN1),
+ PINMUX_DATA(LCDD4_MARK, PORT125_FN1),
+ PINMUX_DATA(LCDD5_MARK, PORT126_FN1),
+ PINMUX_DATA(LCDD6_MARK, PORT127_FN1),
+ PINMUX_DATA(LCDD7_MARK, PORT128_FN1),
+ PINMUX_DATA(LCDD8_MARK, PORT129_FN1),
+ PINMUX_DATA(LCDD9_MARK, PORT130_FN1),
+ PINMUX_DATA(LCDD10_MARK, PORT131_FN1),
+ PINMUX_DATA(LCDD11_MARK, PORT132_FN1),
+ PINMUX_DATA(LCDD12_MARK, PORT133_FN1),
+ PINMUX_DATA(LCDD13_MARK, PORT134_FN1),
+ PINMUX_DATA(LCDD14_MARK, PORT135_FN1),
+ PINMUX_DATA(LCDD15_MARK, PORT136_FN1),
+ PINMUX_DATA(LCDD16_MARK, PORT137_FN1),
+ PINMUX_DATA(LCDD17_MARK, PORT138_FN1),
+ PINMUX_DATA(LCDD18_MARK, PORT139_FN1),
+ PINMUX_DATA(LCDD19_MARK, PORT140_FN1),
+ PINMUX_DATA(LCDD20_MARK, PORT141_FN1),
+ PINMUX_DATA(LCDD21_MARK, PORT142_FN1),
+ PINMUX_DATA(LCDD22_MARK, PORT143_FN1),
+ PINMUX_DATA(LCDD23_MARK, PORT144_FN1),
+ PINMUX_DATA(LCDHSYN_MARK, PORT145_FN1),
+ PINMUX_DATA(LCDVSYN_MARK, PORT146_FN1),
+ PINMUX_DATA(LCDDCK_MARK, PORT147_FN1),
+ PINMUX_DATA(LCDRD_MARK, PORT148_FN1),
+ PINMUX_DATA(LCDDISP_MARK, PORT149_FN1),
+ PINMUX_DATA(LCDLCLK_MARK, PORT150_FN1),
+ PINMUX_DATA(LCDDON_MARK, PORT151_FN1),
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT152_FN1),
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT153_FN1),
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT154_FN1),
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT155_FN1),
+ PINMUX_DATA(TS_SPSYNC1_MARK, PORT156_FN1),
+ PINMUX_DATA(TS_SDAT1_MARK, PORT157_FN1),
+ PINMUX_DATA(TS_SDEN1_MARK, PORT158_FN1),
+ PINMUX_DATA(TS_SCK1_MARK, PORT159_FN1),
+ PINMUX_DATA(TPU0TO0_MARK, PORT160_FN1),
+ PINMUX_DATA(TPU0TO1_MARK, PORT161_FN1),
+ PINMUX_DATA(SCIFB_SCK_MARK, PORT162_FN1),
+ PINMUX_DATA(SCIFB_RTS_MARK, PORT163_FN1),
+ PINMUX_DATA(SCIFB_CTS_MARK, PORT164_FN1),
+ PINMUX_DATA(SCIFB_TXD_MARK, PORT165_FN1),
+ PINMUX_DATA(SCIFB_RXD_MARK, PORT166_FN1),
+ PINMUX_DATA(VBUS0_0_MARK, PORT167_FN1),
+ PINMUX_DATA(VBUS0_1_MARK, PORT168_FN1),
+ PINMUX_DATA(HDMI_HPD_MARK, PORT169_FN1),
+ PINMUX_DATA(HDMI_CEC_MARK, PORT170_FN1),
+ PINMUX_DATA(SDHICLK0_MARK, PORT171_FN1),
+ PINMUX_DATA(SDHICD0_MARK, PORT172_FN1),
+ PINMUX_DATA(SDHID0_0_MARK, PORT173_FN1),
+ PINMUX_DATA(SDHID0_1_MARK, PORT174_FN1),
+ PINMUX_DATA(SDHID0_2_MARK, PORT175_FN1),
+ PINMUX_DATA(SDHID0_3_MARK, PORT176_FN1),
+ PINMUX_DATA(SDHICMD0_MARK, PORT177_FN1),
+ PINMUX_DATA(SDHIWP0_MARK, PORT178_FN1),
+ PINMUX_DATA(SDHICLK1_MARK, PORT179_FN1),
+ PINMUX_DATA(SDHID1_0_MARK, PORT180_FN1),
+ PINMUX_DATA(SDHID1_1_MARK, PORT181_FN1),
+ PINMUX_DATA(SDHID1_2_MARK, PORT182_FN1),
+ PINMUX_DATA(SDHID1_3_MARK, PORT183_FN1),
+ PINMUX_DATA(SDHICMD1_MARK, PORT184_FN1),
+ PINMUX_DATA(SDHICLK2_MARK, PORT185_FN1),
+ PINMUX_DATA(SDHID2_0_MARK, PORT186_FN1),
+ PINMUX_DATA(SDHID2_1_MARK, PORT187_FN1),
+ PINMUX_DATA(SDHID2_2_MARK, PORT188_FN1),
+ PINMUX_DATA(SDHID2_3_MARK, PORT189_FN1),
+ PINMUX_DATA(SDHICMD2_MARK, PORT190_FN1),
+
+ /* Function 2 */
+ PINMUX_DATA(FSIBCK_MARK, PORT4_FN2),
+ PINMUX_DATA(SCIFA4_RXD_MARK, PORT5_FN2),
+ PINMUX_DATA(SCIFA4_TXD_MARK, PORT6_FN2),
+ PINMUX_DATA(SCIFA5_RXD_MARK, PORT8_FN2),
+ PINMUX_DATA(FSIASPDIF_11_MARK, PORT11_FN2),
+ PINMUX_DATA(SCIFA5_TXD_MARK, PORT12_FN2),
+ PINMUX_DATA(FMSIOLR_MARK, PORT13_FN2),
+ PINMUX_DATA(FMSIOBT_MARK, PORT14_FN2),
+ PINMUX_DATA(FSIASPDIF_15_MARK, PORT15_FN2),
+ PINMUX_DATA(FMSIILR_MARK, PORT16_FN2),
+ PINMUX_DATA(FMSIIBT_MARK, PORT17_FN2),
+ PINMUX_DATA(BS_MARK, PORT19_FN2),
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT36_FN2),
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT37_FN2),
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT38_FN2),
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT39_FN2),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT40_FN2),
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT41_FN2),
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT42_FN2),
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT43_FN2),
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT44_FN2),
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT45_FN2),
+ PINMUX_DATA(FMSICK_MARK, PORT65_FN2),
+ PINMUX_DATA(FCE1_MARK, PORT66_FN2),
+ PINMUX_DATA(BBIF1_RXD_MARK, PORT76_FN2),
+ PINMUX_DATA(BBIF1_TSYNC_MARK, PORT77_FN2),
+ PINMUX_DATA(BBIF1_TSCK_MARK, PORT78_FN2),
+ PINMUX_DATA(BBIF1_TXD_MARK, PORT79_FN2),
+ PINMUX_DATA(BBIF1_RSCK_MARK, PORT80_FN2),
+ PINMUX_DATA(BBIF1_RSYNC_MARK, PORT81_FN2),
+ PINMUX_DATA(BBIF1_FLOW_MARK, PORT82_FN2),
+ PINMUX_DATA(BB_RX_FLOW_N_MARK, PORT83_FN2),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT84_FN2),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT85_FN2),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT86_FN2),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT87_FN2),
+ PINMUX_DATA(MSIOF1_TSCK_88_MARK, PORT88_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_TSYNC_89_MARK, PORT89_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_TXD_90_MARK, PORT90_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_RXD_91_MARK, PORT91_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_SS1_92_MARK, PORT92_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_SS2_93_MARK, PORT93_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(SCIFA2_CTS1_MARK, PORT94_FN2),
+ PINMUX_DATA(SCIFA2_RTS1_MARK, PORT95_FN2),
+ PINMUX_DATA(SCIFA2_TXD1_MARK, PORT96_FN2),
+ PINMUX_DATA(SCIFA2_RXD1_MARK, PORT97_FN2),
+ PINMUX_DATA(SCIFA2_SCK1_MARK, PORT98_FN2),
+ PINMUX_DATA(I2C_SCL2_MARK, PORT110_FN2),
+ PINMUX_DATA(I2C_SDA2_MARK, PORT111_FN2),
+ PINMUX_DATA(I2C_SCL3_MARK, PORT114_FN2, MSEL4CR_16_1),
+ PINMUX_DATA(I2C_SDA3_MARK, PORT115_FN2, MSEL4CR_16_1),
+ PINMUX_DATA(I2C_SCL4_MARK, PORT116_FN2, MSEL4CR_17_1),
+ PINMUX_DATA(I2C_SDA4_MARK, PORT117_FN2, MSEL4CR_17_1),
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT134_FN2),
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT135_FN2),
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT136_FN2),
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT137_FN2),
+ PINMUX_DATA(MSIOF2_SS1_MARK, PORT138_FN2),
+ PINMUX_DATA(MSIOF2_SS2_MARK, PORT139_FN2),
+ PINMUX_DATA(SCIFA3_CTS_140_MARK, PORT140_FN2, MSEL3CR_9_1),
+ PINMUX_DATA(SCIFA3_RTS_141_MARK, PORT141_FN2),
+ PINMUX_DATA(SCIFA3_SCK_MARK, PORT142_FN2),
+ PINMUX_DATA(SCIFA3_TXD_MARK, PORT143_FN2),
+ PINMUX_DATA(SCIFA3_RXD_MARK, PORT144_FN2),
+ PINMUX_DATA(MSIOF2_TSYNC_MARK, PORT148_FN2),
+ PINMUX_DATA(MSIOF2_TSCK_MARK, PORT149_FN2),
+ PINMUX_DATA(MSIOF2_RXD_MARK, PORT150_FN2),
+ PINMUX_DATA(MSIOF2_TXD_MARK, PORT151_FN2),
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT156_FN2),
+ PINMUX_DATA(SCIFA0_RTS_MARK, PORT157_FN2),
+ PINMUX_DATA(SCIFA0_CTS_MARK, PORT158_FN2),
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT159_FN2),
+ PINMUX_DATA(SCIFA1_RTS_MARK, PORT160_FN2),
+ PINMUX_DATA(SCIFA1_CTS_MARK, PORT161_FN2),
+
+ /* Function 3 */
+ PINMUX_DATA(VIO_CKO1_MARK, PORT16_FN3),
+ PINMUX_DATA(VIO_CKO2_MARK, PORT17_FN3),
+ PINMUX_DATA(IDIN_1_18_MARK, PORT18_FN3, MSEL4CR_14_1),
+ PINMUX_DATA(MSIOF1_TSCK_39_MARK, PORT39_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_TSYNC_40_MARK, PORT40_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_TXD_41_MARK, PORT41_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_RXD_42_MARK, PORT42_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_SS1_43_MARK, PORT43_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_SS2_44_MARK, PORT44_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MMCD1_0_MARK, PORT54_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_1_MARK, PORT55_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_2_MARK, PORT56_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_3_MARK, PORT57_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_4_MARK, PORT58_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_5_MARK, PORT59_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_6_MARK, PORT60_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_7_MARK, PORT61_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(VINT_I_MARK, PORT65_FN3),
+ PINMUX_DATA(MMCCLK1_MARK, PORT66_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCCMD1_MARK, PORT67_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(TPU0TO2_93_MARK, PORT93_FN3),
+ PINMUX_DATA(TPU0TO2_99_MARK, PORT99_FN3),
+ PINMUX_DATA(TPU0TO3_MARK, PORT112_FN3),
+ PINMUX_DATA(IDIN_0_MARK, PORT113_FN3),
+ PINMUX_DATA(EXTLP_0_MARK, PORT114_FN3),
+ PINMUX_DATA(OVCN2_0_MARK, PORT115_FN3),
+ PINMUX_DATA(PWEN_0_MARK, PORT116_FN3),
+ PINMUX_DATA(OVCN_0_MARK, PORT117_FN3),
+ PINMUX_DATA(KEYOUT7_MARK, PORT121_FN3),
+ PINMUX_DATA(KEYOUT6_MARK, PORT122_FN3),
+ PINMUX_DATA(KEYOUT5_MARK, PORT123_FN3),
+ PINMUX_DATA(KEYOUT4_MARK, PORT124_FN3),
+ PINMUX_DATA(KEYOUT3_MARK, PORT125_FN3),
+ PINMUX_DATA(KEYOUT2_MARK, PORT126_FN3),
+ PINMUX_DATA(KEYOUT1_MARK, PORT127_FN3),
+ PINMUX_DATA(KEYOUT0_MARK, PORT128_FN3),
+ PINMUX_DATA(KEYIN7_MARK, PORT129_FN3),
+ PINMUX_DATA(KEYIN6_MARK, PORT130_FN3),
+ PINMUX_DATA(KEYIN5_MARK, PORT131_FN3),
+ PINMUX_DATA(KEYIN4_MARK, PORT132_FN3),
+ PINMUX_DATA(KEYIN3_133_MARK, PORT133_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(KEYIN2_134_MARK, PORT134_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(KEYIN1_135_MARK, PORT135_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(KEYIN0_136_MARK, PORT136_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(TS_SPSYNC2_MARK, PORT137_FN3),
+ PINMUX_DATA(IROUT_139_MARK, PORT139_FN3),
+ PINMUX_DATA(IRDA_OUT_MARK, PORT140_FN3),
+ PINMUX_DATA(IRDA_IN_MARK, PORT141_FN3),
+ PINMUX_DATA(IRDA_FIRSEL_MARK, PORT142_FN3),
+ PINMUX_DATA(TS_SDAT2_MARK, PORT145_FN3),
+ PINMUX_DATA(TS_SDEN2_MARK, PORT146_FN3),
+ PINMUX_DATA(TS_SCK2_MARK, PORT147_FN3),
+
+ /* Function 4 */
+ PINMUX_DATA(SCIFA3_CTS_43_MARK, PORT43_FN4, MSEL3CR_9_0),
+ PINMUX_DATA(SCIFA3_RTS_44_MARK, PORT44_FN4),
+ PINMUX_DATA(GP_RX_FLAG_MARK, PORT76_FN4),
+ PINMUX_DATA(GP_RX_DATA_MARK, PORT77_FN4),
+ PINMUX_DATA(GP_TX_READY_MARK, PORT78_FN4),
+ PINMUX_DATA(GP_RX_WAKE_MARK, PORT79_FN4),
+ PINMUX_DATA(MP_TX_FLAG_MARK, PORT80_FN4),
+ PINMUX_DATA(MP_TX_DATA_MARK, PORT81_FN4),
+ PINMUX_DATA(MP_RX_READY_MARK, PORT82_FN4),
+ PINMUX_DATA(MP_TX_WAKE_MARK, PORT83_FN4),
+ PINMUX_DATA(MMCD0_0_MARK, PORT84_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_1_MARK, PORT85_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_2_MARK, PORT86_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_3_MARK, PORT87_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_4_MARK, PORT88_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_5_MARK, PORT89_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_6_MARK, PORT90_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_7_MARK, PORT91_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCCMD0_MARK, PORT92_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(SIM_RST_MARK, PORT94_FN4),
+ PINMUX_DATA(SIM_CLK_MARK, PORT95_FN4),
+ PINMUX_DATA(SIM_D_MARK, PORT98_FN4),
+ PINMUX_DATA(MMCCLK0_MARK, PORT99_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(IDIN_1_113_MARK, PORT113_FN4, MSEL4CR_14_0),
+ PINMUX_DATA(OVCN_1_114_MARK, PORT114_FN4, MSEL4CR_14_0),
+ PINMUX_DATA(PWEN_1_115_MARK, PORT115_FN4),
+ PINMUX_DATA(EXTLP_1_MARK, PORT116_FN4),
+ PINMUX_DATA(OVCN2_1_MARK, PORT117_FN4),
+ PINMUX_DATA(KEYIN0_121_MARK, PORT121_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(KEYIN1_122_MARK, PORT122_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(KEYIN2_123_MARK, PORT123_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(KEYIN3_124_MARK, PORT124_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(PWEN_1_138_MARK, PORT138_FN4),
+ PINMUX_DATA(IROUT_140_MARK, PORT140_FN4),
+ PINMUX_DATA(LCDCS_MARK, PORT145_FN4),
+ PINMUX_DATA(LCDWR_MARK, PORT147_FN4),
+ PINMUX_DATA(LCDRS_MARK, PORT149_FN4),
+ PINMUX_DATA(OVCN_1_162_MARK, PORT162_FN4, MSEL4CR_14_1),
+
+ /* Function 5 */
+ PINMUX_DATA(GPI0_MARK, PORT41_FN5),
+ PINMUX_DATA(GPI1_MARK, PORT42_FN5),
+ PINMUX_DATA(GPO0_MARK, PORT43_FN5),
+ PINMUX_DATA(GPO1_MARK, PORT44_FN5),
+ PINMUX_DATA(I2C_SCL3S_MARK, PORT137_FN5, MSEL4CR_16_0),
+ PINMUX_DATA(I2C_SDA3S_MARK, PORT145_FN5, MSEL4CR_16_0),
+ PINMUX_DATA(I2C_SCL4S_MARK, PORT146_FN5, MSEL4CR_17_0),
+ PINMUX_DATA(I2C_SDA4S_MARK, PORT147_FN5, MSEL4CR_17_0),
+
+ /* Function select */
+ PINMUX_DATA(LCDC0_SELECT_MARK, MSEL3CR_6_0),
+ PINMUX_DATA(LCDC1_SELECT_MARK, MSEL3CR_6_1),
+
+ PINMUX_DATA(TS0_1SELECT_MARK, MSEL3CR_21_0, MSEL3CR_20_0),
+ PINMUX_DATA(TS0_2SELECT_MARK, MSEL3CR_21_0, MSEL3CR_20_1),
+ PINMUX_DATA(TS1_1SELECT_MARK, MSEL3CR_27_0, MSEL3CR_26_0),
+ PINMUX_DATA(TS1_2SELECT_MARK, MSEL3CR_27_0, MSEL3CR_26_1),
+
+ PINMUX_DATA(SDENC_CPG_MARK, MSEL4CR_19_0),
+ PINMUX_DATA(SDENC_DV_CLKI_MARK, MSEL4CR_19_1),
+
+ PINMUX_DATA(MFIv6_MARK, MSEL4CR_6_0),
+ PINMUX_DATA(MFIv4_MARK, MSEL4CR_6_1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_ALL() _190(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+
+ /* PORT */
+ GPIO_PORT_ALL(),
+
+ /* IRQ */
+ GPIO_FN(IRQ0_6), GPIO_FN(IRQ0_162), GPIO_FN(IRQ1),
+ GPIO_FN(IRQ2_4), GPIO_FN(IRQ2_5), GPIO_FN(IRQ3_8),
+ GPIO_FN(IRQ3_16), GPIO_FN(IRQ4_17), GPIO_FN(IRQ4_163),
+ GPIO_FN(IRQ5), GPIO_FN(IRQ6_39), GPIO_FN(IRQ6_164),
+ GPIO_FN(IRQ7_40), GPIO_FN(IRQ7_167), GPIO_FN(IRQ8_41),
+ GPIO_FN(IRQ8_168), GPIO_FN(IRQ9_42), GPIO_FN(IRQ9_169),
+ GPIO_FN(IRQ10), GPIO_FN(IRQ11), GPIO_FN(IRQ12_80),
+ GPIO_FN(IRQ12_137), GPIO_FN(IRQ13_81), GPIO_FN(IRQ13_145),
+ GPIO_FN(IRQ14_82), GPIO_FN(IRQ14_146), GPIO_FN(IRQ15_83),
+ GPIO_FN(IRQ15_147), GPIO_FN(IRQ16_84), GPIO_FN(IRQ16_170),
+ GPIO_FN(IRQ17), GPIO_FN(IRQ18), GPIO_FN(IRQ19),
+ GPIO_FN(IRQ20), GPIO_FN(IRQ21), GPIO_FN(IRQ22),
+ GPIO_FN(IRQ23), GPIO_FN(IRQ24), GPIO_FN(IRQ25),
+ GPIO_FN(IRQ26_121), GPIO_FN(IRQ26_172), GPIO_FN(IRQ27_122),
+ GPIO_FN(IRQ27_180), GPIO_FN(IRQ28_123), GPIO_FN(IRQ28_181),
+ GPIO_FN(IRQ29_129), GPIO_FN(IRQ29_182), GPIO_FN(IRQ30_130),
+ GPIO_FN(IRQ30_183), GPIO_FN(IRQ31_138), GPIO_FN(IRQ31_184),
+
+ /* MSIOF0 */
+ GPIO_FN(MSIOF0_TSYNC), GPIO_FN(MSIOF0_TSCK), GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(MSIOF0_RSCK), GPIO_FN(MSIOF0_RSYNC), GPIO_FN(MSIOF0_MCK0),
+ GPIO_FN(MSIOF0_MCK1), GPIO_FN(MSIOF0_SS1), GPIO_FN(MSIOF0_SS2),
+ GPIO_FN(MSIOF0_TXD),
+
+ /* MSIOF1 */
+ GPIO_FN(MSIOF1_TSCK_39), GPIO_FN(MSIOF1_TSCK_88),
+ GPIO_FN(MSIOF1_TSYNC_40), GPIO_FN(MSIOF1_TSYNC_89),
+ GPIO_FN(MSIOF1_TXD_41), GPIO_FN(MSIOF1_TXD_90),
+ GPIO_FN(MSIOF1_RXD_42), GPIO_FN(MSIOF1_RXD_91),
+ GPIO_FN(MSIOF1_SS1_43), GPIO_FN(MSIOF1_SS1_92),
+ GPIO_FN(MSIOF1_SS2_44), GPIO_FN(MSIOF1_SS2_93),
+ GPIO_FN(MSIOF1_RSCK), GPIO_FN(MSIOF1_RSYNC),
+ GPIO_FN(MSIOF1_MCK0), GPIO_FN(MSIOF1_MCK1),
+
+ /* MSIOF2 */
+ GPIO_FN(MSIOF2_RSCK), GPIO_FN(MSIOF2_RSYNC), GPIO_FN(MSIOF2_MCK0),
+ GPIO_FN(MSIOF2_MCK1), GPIO_FN(MSIOF2_SS1), GPIO_FN(MSIOF2_SS2),
+ GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_TSCK), GPIO_FN(MSIOF2_RXD),
+ GPIO_FN(MSIOF2_TXD),
+
+ /* MSIOF3 */
+ GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TSYNC), GPIO_FN(BBIF1_TSCK),
+ GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC),
+ GPIO_FN(BBIF1_FLOW), GPIO_FN(BB_RX_FLOW_N),
+
+ /* MSIOF4 */
+ GPIO_FN(BBIF2_TSCK1), GPIO_FN(BBIF2_TSYNC1),
+ GPIO_FN(BBIF2_TXD1), GPIO_FN(BBIF2_RXD),
+
+ /* FSI */
+ GPIO_FN(FSIACK), GPIO_FN(FSIBCK), GPIO_FN(FSIAILR),
+ GPIO_FN(FSIAIBT), GPIO_FN(FSIAISLD), GPIO_FN(FSIAOMC),
+ GPIO_FN(FSIAOLR), GPIO_FN(FSIAOBT), GPIO_FN(FSIAOSLD),
+ GPIO_FN(FSIASPDIF_11), GPIO_FN(FSIASPDIF_15),
+
+ /* FMSI */
+ GPIO_FN(FMSOCK), GPIO_FN(FMSOOLR), GPIO_FN(FMSIOLR),
+ GPIO_FN(FMSOOBT), GPIO_FN(FMSIOBT), GPIO_FN(FMSOSLD),
+ GPIO_FN(FMSOILR), GPIO_FN(FMSIILR), GPIO_FN(FMSOIBT),
+ GPIO_FN(FMSIIBT), GPIO_FN(FMSISLD), GPIO_FN(FMSICK),
+
+ /* SCIFA0 */
+ GPIO_FN(SCIFA0_TXD), GPIO_FN(SCIFA0_RXD), GPIO_FN(SCIFA0_SCK),
+ GPIO_FN(SCIFA0_RTS), GPIO_FN(SCIFA0_CTS),
+
+ /* SCIFA1 */
+ GPIO_FN(SCIFA1_TXD), GPIO_FN(SCIFA1_RXD), GPIO_FN(SCIFA1_SCK),
+ GPIO_FN(SCIFA1_RTS), GPIO_FN(SCIFA1_CTS),
+
+ /* SCIFA2 */
+ GPIO_FN(SCIFA2_CTS1), GPIO_FN(SCIFA2_RTS1), GPIO_FN(SCIFA2_TXD1),
+ GPIO_FN(SCIFA2_RXD1), GPIO_FN(SCIFA2_SCK1),
+
+ /* SCIFA3 */
+ GPIO_FN(SCIFA3_CTS_43), GPIO_FN(SCIFA3_CTS_140),
+ GPIO_FN(SCIFA3_RTS_44), GPIO_FN(SCIFA3_RTS_141),
+ GPIO_FN(SCIFA3_SCK), GPIO_FN(SCIFA3_TXD),
+ GPIO_FN(SCIFA3_RXD),
+
+ /* SCIFA4 */
+ GPIO_FN(SCIFA4_RXD), GPIO_FN(SCIFA4_TXD),
+
+ /* SCIFA5 */
+ GPIO_FN(SCIFA5_RXD), GPIO_FN(SCIFA5_TXD),
+
+ /* SCIFB */
+ GPIO_FN(SCIFB_SCK), GPIO_FN(SCIFB_RTS), GPIO_FN(SCIFB_CTS),
+ GPIO_FN(SCIFB_TXD), GPIO_FN(SCIFB_RXD),
+
+ /* CEU */
+ GPIO_FN(VIO_HD), GPIO_FN(VIO_CKO1), GPIO_FN(VIO_CKO2),
+ GPIO_FN(VIO_VD), GPIO_FN(VIO_CLK), GPIO_FN(VIO_FIELD),
+ GPIO_FN(VIO_CKO), GPIO_FN(VIO_D0), GPIO_FN(VIO_D1),
+ GPIO_FN(VIO_D2), GPIO_FN(VIO_D3), GPIO_FN(VIO_D4),
+ GPIO_FN(VIO_D5), GPIO_FN(VIO_D6), GPIO_FN(VIO_D7),
+ GPIO_FN(VIO_D8), GPIO_FN(VIO_D9), GPIO_FN(VIO_D10),
+ GPIO_FN(VIO_D11), GPIO_FN(VIO_D12), GPIO_FN(VIO_D13),
+ GPIO_FN(VIO_D14), GPIO_FN(VIO_D15),
+
+ /* USB0 */
+ GPIO_FN(IDIN_0), GPIO_FN(EXTLP_0), GPIO_FN(OVCN2_0),
+ GPIO_FN(PWEN_0), GPIO_FN(OVCN_0), GPIO_FN(VBUS0_0),
+
+ /* USB1 */
+ GPIO_FN(IDIN_1_18), GPIO_FN(IDIN_1_113),
+ GPIO_FN(OVCN_1_114), GPIO_FN(OVCN_1_162),
+ GPIO_FN(PWEN_1_115), GPIO_FN(PWEN_1_138),
+ GPIO_FN(EXTLP_1), GPIO_FN(OVCN2_1),
+ GPIO_FN(VBUS0_1),
+
+ /* GPIO */
+ GPIO_FN(GPI0), GPIO_FN(GPI1), GPIO_FN(GPO0), GPIO_FN(GPO1),
+
+ /* BSC */
+ GPIO_FN(BS), GPIO_FN(WE1), GPIO_FN(CKO),
+ GPIO_FN(WAIT), GPIO_FN(RDWR),
+
+ GPIO_FN(A0), GPIO_FN(A1), GPIO_FN(A2),
+ GPIO_FN(A3), GPIO_FN(A6), GPIO_FN(A7),
+ GPIO_FN(A8), GPIO_FN(A9), GPIO_FN(A10),
+ GPIO_FN(A11), GPIO_FN(A12), GPIO_FN(A13),
+ GPIO_FN(A14), GPIO_FN(A15), GPIO_FN(A16),
+ GPIO_FN(A17), GPIO_FN(A18), GPIO_FN(A19),
+ GPIO_FN(A20), GPIO_FN(A21), GPIO_FN(A22),
+ GPIO_FN(A23), GPIO_FN(A24), GPIO_FN(A25),
+ GPIO_FN(A26),
+
+ GPIO_FN(CS0), GPIO_FN(CS2), GPIO_FN(CS4),
+ GPIO_FN(CS5A), GPIO_FN(CS5B), GPIO_FN(CS6A),
+
+ /* BSC/FLCTL */
+ GPIO_FN(RD_FSC), GPIO_FN(WE0_FWE), GPIO_FN(A4_FOE),
+ GPIO_FN(A5_FCDE), GPIO_FN(D0_NAF0), GPIO_FN(D1_NAF1),
+ GPIO_FN(D2_NAF2), GPIO_FN(D3_NAF3), GPIO_FN(D4_NAF4),
+ GPIO_FN(D5_NAF5), GPIO_FN(D6_NAF6), GPIO_FN(D7_NAF7),
+ GPIO_FN(D8_NAF8), GPIO_FN(D9_NAF9), GPIO_FN(D10_NAF10),
+ GPIO_FN(D11_NAF11), GPIO_FN(D12_NAF12), GPIO_FN(D13_NAF13),
+ GPIO_FN(D14_NAF14), GPIO_FN(D15_NAF15),
+
+ /* MMCIF(1) */
+ GPIO_FN(MMCD0_0), GPIO_FN(MMCD0_1), GPIO_FN(MMCD0_2),
+ GPIO_FN(MMCD0_3), GPIO_FN(MMCD0_4), GPIO_FN(MMCD0_5),
+ GPIO_FN(MMCD0_6), GPIO_FN(MMCD0_7), GPIO_FN(MMCCMD0),
+ GPIO_FN(MMCCLK0),
+
+ /* MMCIF(2) */
+ GPIO_FN(MMCD1_0), GPIO_FN(MMCD1_1), GPIO_FN(MMCD1_2),
+ GPIO_FN(MMCD1_3), GPIO_FN(MMCD1_4), GPIO_FN(MMCD1_5),
+ GPIO_FN(MMCD1_6), GPIO_FN(MMCD1_7), GPIO_FN(MMCCLK1),
+ GPIO_FN(MMCCMD1),
+
+ /* SPU2 */
+ GPIO_FN(VINT_I),
+
+ /* FLCTL */
+ GPIO_FN(FCE1), GPIO_FN(FCE0), GPIO_FN(FRB),
+
+ /* HSI */
+ GPIO_FN(GP_RX_FLAG), GPIO_FN(GP_RX_DATA), GPIO_FN(GP_TX_READY),
+ GPIO_FN(GP_RX_WAKE), GPIO_FN(MP_TX_FLAG), GPIO_FN(MP_TX_DATA),
+ GPIO_FN(MP_RX_READY), GPIO_FN(MP_TX_WAKE),
+
+ /* MFI */
+ GPIO_FN(MFIv6),
+ GPIO_FN(MFIv4),
+
+ GPIO_FN(MEMC_BUSCLK_MEMC_A0), GPIO_FN(MEMC_ADV_MEMC_DREQ0),
+ GPIO_FN(MEMC_WAIT_MEMC_DREQ1), GPIO_FN(MEMC_CS1_MEMC_A1),
+ GPIO_FN(MEMC_CS0), GPIO_FN(MEMC_NOE),
+ GPIO_FN(MEMC_NWE), GPIO_FN(MEMC_INT),
+
+ GPIO_FN(MEMC_AD0), GPIO_FN(MEMC_AD1), GPIO_FN(MEMC_AD2),
+ GPIO_FN(MEMC_AD3), GPIO_FN(MEMC_AD4), GPIO_FN(MEMC_AD5),
+ GPIO_FN(MEMC_AD6), GPIO_FN(MEMC_AD7), GPIO_FN(MEMC_AD8),
+ GPIO_FN(MEMC_AD9), GPIO_FN(MEMC_AD10), GPIO_FN(MEMC_AD11),
+ GPIO_FN(MEMC_AD12), GPIO_FN(MEMC_AD13), GPIO_FN(MEMC_AD14),
+ GPIO_FN(MEMC_AD15),
+
+ /* SIM */
+ GPIO_FN(SIM_RST), GPIO_FN(SIM_CLK), GPIO_FN(SIM_D),
+
+ /* TPU */
+ GPIO_FN(TPU0TO0), GPIO_FN(TPU0TO1), GPIO_FN(TPU0TO2_93),
+ GPIO_FN(TPU0TO2_99), GPIO_FN(TPU0TO3),
+
+ /* I2C2 */
+ GPIO_FN(I2C_SCL2), GPIO_FN(I2C_SDA2),
+
+ /* I2C3(1) */
+ GPIO_FN(I2C_SCL3), GPIO_FN(I2C_SDA3),
+
+ /* I2C3(2) */
+ GPIO_FN(I2C_SCL3S), GPIO_FN(I2C_SDA3S),
+
+ /* I2C4(2) */
+ GPIO_FN(I2C_SCL4), GPIO_FN(I2C_SDA4),
+
+ /* I2C4(2) */
+ GPIO_FN(I2C_SCL4S), GPIO_FN(I2C_SDA4S),
+
+ /* KEYSC */
+ GPIO_FN(KEYOUT0), GPIO_FN(KEYIN0_121), GPIO_FN(KEYIN0_136),
+ GPIO_FN(KEYOUT1), GPIO_FN(KEYIN1_122), GPIO_FN(KEYIN1_135),
+ GPIO_FN(KEYOUT2), GPIO_FN(KEYIN2_123), GPIO_FN(KEYIN2_134),
+ GPIO_FN(KEYOUT3), GPIO_FN(KEYIN3_124), GPIO_FN(KEYIN3_133),
+ GPIO_FN(KEYOUT4), GPIO_FN(KEYIN4), GPIO_FN(KEYOUT5),
+ GPIO_FN(KEYIN5), GPIO_FN(KEYOUT6), GPIO_FN(KEYIN6),
+ GPIO_FN(KEYOUT7), GPIO_FN(KEYIN7),
+
+ /* LCDC */
+ GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDVSYN),
+ GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(LCDRD),
+ GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(LCDLCLK),
+ GPIO_FN(LCDDON),
+
+ GPIO_FN(LCDD0), GPIO_FN(LCDD1), GPIO_FN(LCDD2),
+ GPIO_FN(LCDD3), GPIO_FN(LCDD4), GPIO_FN(LCDD5),
+ GPIO_FN(LCDD6), GPIO_FN(LCDD7), GPIO_FN(LCDD8),
+ GPIO_FN(LCDD9), GPIO_FN(LCDD10), GPIO_FN(LCDD11),
+ GPIO_FN(LCDD12), GPIO_FN(LCDD13), GPIO_FN(LCDD14),
+ GPIO_FN(LCDD15), GPIO_FN(LCDD16), GPIO_FN(LCDD17),
+ GPIO_FN(LCDD18), GPIO_FN(LCDD19), GPIO_FN(LCDD20),
+ GPIO_FN(LCDD21), GPIO_FN(LCDD22), GPIO_FN(LCDD23),
+
+ /* IRDA */
+ GPIO_FN(IRDA_OUT), GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL),
+ GPIO_FN(IROUT_139), GPIO_FN(IROUT_140),
+
+ /* TSIF1 */
+ GPIO_FN(TS0_1SELECT),
+ GPIO_FN(TS0_2SELECT),
+ GPIO_FN(TS1_1SELECT),
+ GPIO_FN(TS1_2SELECT),
+
+ GPIO_FN(TS_SPSYNC1), GPIO_FN(TS_SDAT1),
+ GPIO_FN(TS_SDEN1), GPIO_FN(TS_SCK1),
+
+ /* TSIF2 */
+ GPIO_FN(TS_SPSYNC2), GPIO_FN(TS_SDAT2),
+ GPIO_FN(TS_SDEN2), GPIO_FN(TS_SCK2),
+
+ /* HDMI */
+ GPIO_FN(HDMI_HPD), GPIO_FN(HDMI_CEC),
+
+ /* SDHI0 */
+ GPIO_FN(SDHICLK0), GPIO_FN(SDHICD0), GPIO_FN(SDHICMD0),
+ GPIO_FN(SDHIWP0), GPIO_FN(SDHID0_0), GPIO_FN(SDHID0_1),
+ GPIO_FN(SDHID0_2), GPIO_FN(SDHID0_3),
+
+ /* SDHI1 */
+ GPIO_FN(SDHICLK1), GPIO_FN(SDHICMD1), GPIO_FN(SDHID1_0),
+ GPIO_FN(SDHID1_1), GPIO_FN(SDHID1_2), GPIO_FN(SDHID1_3),
+
+ /* SDHI2 */
+ GPIO_FN(SDHICLK2), GPIO_FN(SDHICMD2), GPIO_FN(SDHID2_0),
+ GPIO_FN(SDHID2_1), GPIO_FN(SDHID2_2), GPIO_FN(SDHID2_3),
+
+ /* SDENC */
+ GPIO_FN(SDENC_CPG),
+ GPIO_FN(SDENC_DV_CLKI),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out) \
+ 0, (out), (in), 0, \
+ 0, 0, 0, 0, \
+ 0, 0, (in_pd), 0, \
+ 0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg) \
+ { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU, PORT##nr##_OUT), \
+ PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
+ PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7 } \
+ }
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ PORTCR(0, 0xE6051000), /* PORT0CR */
+ PORTCR(1, 0xE6051001), /* PORT1CR */
+ PORTCR(2, 0xE6051002), /* PORT2CR */
+ PORTCR(3, 0xE6051003), /* PORT3CR */
+ PORTCR(4, 0xE6051004), /* PORT4CR */
+ PORTCR(5, 0xE6051005), /* PORT5CR */
+ PORTCR(6, 0xE6051006), /* PORT6CR */
+ PORTCR(7, 0xE6051007), /* PORT7CR */
+ PORTCR(8, 0xE6051008), /* PORT8CR */
+ PORTCR(9, 0xE6051009), /* PORT9CR */
+ PORTCR(10, 0xE605100A), /* PORT10CR */
+ PORTCR(11, 0xE605100B), /* PORT11CR */
+ PORTCR(12, 0xE605100C), /* PORT12CR */
+ PORTCR(13, 0xE605100D), /* PORT13CR */
+ PORTCR(14, 0xE605100E), /* PORT14CR */
+ PORTCR(15, 0xE605100F), /* PORT15CR */
+ PORTCR(16, 0xE6051010), /* PORT16CR */
+ PORTCR(17, 0xE6051011), /* PORT17CR */
+ PORTCR(18, 0xE6051012), /* PORT18CR */
+ PORTCR(19, 0xE6051013), /* PORT19CR */
+ PORTCR(20, 0xE6051014), /* PORT20CR */
+ PORTCR(21, 0xE6051015), /* PORT21CR */
+ PORTCR(22, 0xE6051016), /* PORT22CR */
+ PORTCR(23, 0xE6051017), /* PORT23CR */
+ PORTCR(24, 0xE6051018), /* PORT24CR */
+ PORTCR(25, 0xE6051019), /* PORT25CR */
+ PORTCR(26, 0xE605101A), /* PORT26CR */
+ PORTCR(27, 0xE605101B), /* PORT27CR */
+ PORTCR(28, 0xE605101C), /* PORT28CR */
+ PORTCR(29, 0xE605101D), /* PORT29CR */
+ PORTCR(30, 0xE605101E), /* PORT30CR */
+ PORTCR(31, 0xE605101F), /* PORT31CR */
+ PORTCR(32, 0xE6051020), /* PORT32CR */
+ PORTCR(33, 0xE6051021), /* PORT33CR */
+ PORTCR(34, 0xE6051022), /* PORT34CR */
+ PORTCR(35, 0xE6051023), /* PORT35CR */
+ PORTCR(36, 0xE6051024), /* PORT36CR */
+ PORTCR(37, 0xE6051025), /* PORT37CR */
+ PORTCR(38, 0xE6051026), /* PORT38CR */
+ PORTCR(39, 0xE6051027), /* PORT39CR */
+ PORTCR(40, 0xE6051028), /* PORT40CR */
+ PORTCR(41, 0xE6051029), /* PORT41CR */
+ PORTCR(42, 0xE605102A), /* PORT42CR */
+ PORTCR(43, 0xE605102B), /* PORT43CR */
+ PORTCR(44, 0xE605102C), /* PORT44CR */
+ PORTCR(45, 0xE605102D), /* PORT45CR */
+ PORTCR(46, 0xE605202E), /* PORT46CR */
+ PORTCR(47, 0xE605202F), /* PORT47CR */
+ PORTCR(48, 0xE6052030), /* PORT48CR */
+ PORTCR(49, 0xE6052031), /* PORT49CR */
+ PORTCR(50, 0xE6052032), /* PORT50CR */
+ PORTCR(51, 0xE6052033), /* PORT51CR */
+ PORTCR(52, 0xE6052034), /* PORT52CR */
+ PORTCR(53, 0xE6052035), /* PORT53CR */
+ PORTCR(54, 0xE6052036), /* PORT54CR */
+ PORTCR(55, 0xE6052037), /* PORT55CR */
+ PORTCR(56, 0xE6052038), /* PORT56CR */
+ PORTCR(57, 0xE6052039), /* PORT57CR */
+ PORTCR(58, 0xE605203A), /* PORT58CR */
+ PORTCR(59, 0xE605203B), /* PORT59CR */
+ PORTCR(60, 0xE605203C), /* PORT60CR */
+ PORTCR(61, 0xE605203D), /* PORT61CR */
+ PORTCR(62, 0xE605203E), /* PORT62CR */
+ PORTCR(63, 0xE605203F), /* PORT63CR */
+ PORTCR(64, 0xE6052040), /* PORT64CR */
+ PORTCR(65, 0xE6052041), /* PORT65CR */
+ PORTCR(66, 0xE6052042), /* PORT66CR */
+ PORTCR(67, 0xE6052043), /* PORT67CR */
+ PORTCR(68, 0xE6052044), /* PORT68CR */
+ PORTCR(69, 0xE6052045), /* PORT69CR */
+ PORTCR(70, 0xE6052046), /* PORT70CR */
+ PORTCR(71, 0xE6052047), /* PORT71CR */
+ PORTCR(72, 0xE6052048), /* PORT72CR */
+ PORTCR(73, 0xE6052049), /* PORT73CR */
+ PORTCR(74, 0xE605204A), /* PORT74CR */
+ PORTCR(75, 0xE605204B), /* PORT75CR */
+ PORTCR(76, 0xE605004C), /* PORT76CR */
+ PORTCR(77, 0xE605004D), /* PORT77CR */
+ PORTCR(78, 0xE605004E), /* PORT78CR */
+ PORTCR(79, 0xE605004F), /* PORT79CR */
+ PORTCR(80, 0xE6050050), /* PORT80CR */
+ PORTCR(81, 0xE6050051), /* PORT81CR */
+ PORTCR(82, 0xE6050052), /* PORT82CR */
+ PORTCR(83, 0xE6050053), /* PORT83CR */
+ PORTCR(84, 0xE6050054), /* PORT84CR */
+ PORTCR(85, 0xE6050055), /* PORT85CR */
+ PORTCR(86, 0xE6050056), /* PORT86CR */
+ PORTCR(87, 0xE6050057), /* PORT87CR */
+ PORTCR(88, 0xE6050058), /* PORT88CR */
+ PORTCR(89, 0xE6050059), /* PORT89CR */
+ PORTCR(90, 0xE605005A), /* PORT90CR */
+ PORTCR(91, 0xE605005B), /* PORT91CR */
+ PORTCR(92, 0xE605005C), /* PORT92CR */
+ PORTCR(93, 0xE605005D), /* PORT93CR */
+ PORTCR(94, 0xE605005E), /* PORT94CR */
+ PORTCR(95, 0xE605005F), /* PORT95CR */
+ PORTCR(96, 0xE6050060), /* PORT96CR */
+ PORTCR(97, 0xE6050061), /* PORT97CR */
+ PORTCR(98, 0xE6050062), /* PORT98CR */
+ PORTCR(99, 0xE6050063), /* PORT99CR */
+ PORTCR(100, 0xE6053064), /* PORT100CR */
+ PORTCR(101, 0xE6053065), /* PORT101CR */
+ PORTCR(102, 0xE6053066), /* PORT102CR */
+ PORTCR(103, 0xE6053067), /* PORT103CR */
+ PORTCR(104, 0xE6053068), /* PORT104CR */
+ PORTCR(105, 0xE6053069), /* PORT105CR */
+ PORTCR(106, 0xE605306A), /* PORT106CR */
+ PORTCR(107, 0xE605306B), /* PORT107CR */
+ PORTCR(108, 0xE605306C), /* PORT108CR */
+ PORTCR(109, 0xE605306D), /* PORT109CR */
+ PORTCR(110, 0xE605306E), /* PORT110CR */
+ PORTCR(111, 0xE605306F), /* PORT111CR */
+ PORTCR(112, 0xE6053070), /* PORT112CR */
+ PORTCR(113, 0xE6053071), /* PORT113CR */
+ PORTCR(114, 0xE6053072), /* PORT114CR */
+ PORTCR(115, 0xE6053073), /* PORT115CR */
+ PORTCR(116, 0xE6053074), /* PORT116CR */
+ PORTCR(117, 0xE6053075), /* PORT117CR */
+ PORTCR(118, 0xE6053076), /* PORT118CR */
+ PORTCR(119, 0xE6053077), /* PORT119CR */
+ PORTCR(120, 0xE6053078), /* PORT120CR */
+ PORTCR(121, 0xE6050079), /* PORT121CR */
+ PORTCR(122, 0xE605007A), /* PORT122CR */
+ PORTCR(123, 0xE605007B), /* PORT123CR */
+ PORTCR(124, 0xE605007C), /* PORT124CR */
+ PORTCR(125, 0xE605007D), /* PORT125CR */
+ PORTCR(126, 0xE605007E), /* PORT126CR */
+ PORTCR(127, 0xE605007F), /* PORT127CR */
+ PORTCR(128, 0xE6050080), /* PORT128CR */
+ PORTCR(129, 0xE6050081), /* PORT129CR */
+ PORTCR(130, 0xE6050082), /* PORT130CR */
+ PORTCR(131, 0xE6050083), /* PORT131CR */
+ PORTCR(132, 0xE6050084), /* PORT132CR */
+ PORTCR(133, 0xE6050085), /* PORT133CR */
+ PORTCR(134, 0xE6050086), /* PORT134CR */
+ PORTCR(135, 0xE6050087), /* PORT135CR */
+ PORTCR(136, 0xE6050088), /* PORT136CR */
+ PORTCR(137, 0xE6050089), /* PORT137CR */
+ PORTCR(138, 0xE605008A), /* PORT138CR */
+ PORTCR(139, 0xE605008B), /* PORT139CR */
+ PORTCR(140, 0xE605008C), /* PORT140CR */
+ PORTCR(141, 0xE605008D), /* PORT141CR */
+ PORTCR(142, 0xE605008E), /* PORT142CR */
+ PORTCR(143, 0xE605008F), /* PORT143CR */
+ PORTCR(144, 0xE6050090), /* PORT144CR */
+ PORTCR(145, 0xE6050091), /* PORT145CR */
+ PORTCR(146, 0xE6050092), /* PORT146CR */
+ PORTCR(147, 0xE6050093), /* PORT147CR */
+ PORTCR(148, 0xE6050094), /* PORT148CR */
+ PORTCR(149, 0xE6050095), /* PORT149CR */
+ PORTCR(150, 0xE6050096), /* PORT150CR */
+ PORTCR(151, 0xE6050097), /* PORT151CR */
+ PORTCR(152, 0xE6053098), /* PORT152CR */
+ PORTCR(153, 0xE6053099), /* PORT153CR */
+ PORTCR(154, 0xE605309A), /* PORT154CR */
+ PORTCR(155, 0xE605309B), /* PORT155CR */
+ PORTCR(156, 0xE605009C), /* PORT156CR */
+ PORTCR(157, 0xE605009D), /* PORT157CR */
+ PORTCR(158, 0xE605009E), /* PORT158CR */
+ PORTCR(159, 0xE605009F), /* PORT159CR */
+ PORTCR(160, 0xE60500A0), /* PORT160CR */
+ PORTCR(161, 0xE60500A1), /* PORT161CR */
+ PORTCR(162, 0xE60500A2), /* PORT162CR */
+ PORTCR(163, 0xE60500A3), /* PORT163CR */
+ PORTCR(164, 0xE60500A4), /* PORT164CR */
+ PORTCR(165, 0xE60500A5), /* PORT165CR */
+ PORTCR(166, 0xE60500A6), /* PORT166CR */
+ PORTCR(167, 0xE60520A7), /* PORT167CR */
+ PORTCR(168, 0xE60520A8), /* PORT168CR */
+ PORTCR(169, 0xE60520A9), /* PORT169CR */
+ PORTCR(170, 0xE60520AA), /* PORT170CR */
+ PORTCR(171, 0xE60520AB), /* PORT171CR */
+ PORTCR(172, 0xE60520AC), /* PORT172CR */
+ PORTCR(173, 0xE60520AD), /* PORT173CR */
+ PORTCR(174, 0xE60520AE), /* PORT174CR */
+ PORTCR(175, 0xE60520AF), /* PORT175CR */
+ PORTCR(176, 0xE60520B0), /* PORT176CR */
+ PORTCR(177, 0xE60520B1), /* PORT177CR */
+ PORTCR(178, 0xE60520B2), /* PORT178CR */
+ PORTCR(179, 0xE60520B3), /* PORT179CR */
+ PORTCR(180, 0xE60520B4), /* PORT180CR */
+ PORTCR(181, 0xE60520B5), /* PORT181CR */
+ PORTCR(182, 0xE60520B6), /* PORT182CR */
+ PORTCR(183, 0xE60520B7), /* PORT183CR */
+ PORTCR(184, 0xE60520B8), /* PORT184CR */
+ PORTCR(185, 0xE60520B9), /* PORT185CR */
+ PORTCR(186, 0xE60520BA), /* PORT186CR */
+ PORTCR(187, 0xE60520BB), /* PORT187CR */
+ PORTCR(188, 0xE60520BC), /* PORT188CR */
+ PORTCR(189, 0xE60520BD), /* PORT189CR */
+ PORTCR(190, 0xE60520BE), /* PORT190CR */
+
+ { PINMUX_CFG_REG("MSEL1CR", 0xE605800C, 32, 1) {
+ MSEL1CR_31_0, MSEL1CR_31_1,
+ MSEL1CR_30_0, MSEL1CR_30_1,
+ MSEL1CR_29_0, MSEL1CR_29_1,
+ MSEL1CR_28_0, MSEL1CR_28_1,
+ MSEL1CR_27_0, MSEL1CR_27_1,
+ MSEL1CR_26_0, MSEL1CR_26_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ MSEL1CR_16_0, MSEL1CR_16_1,
+ MSEL1CR_15_0, MSEL1CR_15_1,
+ MSEL1CR_14_0, MSEL1CR_14_1,
+ MSEL1CR_13_0, MSEL1CR_13_1,
+ MSEL1CR_12_0, MSEL1CR_12_1,
+ 0, 0, 0, 0,
+ MSEL1CR_9_0, MSEL1CR_9_1,
+ MSEL1CR_8_0, MSEL1CR_8_1,
+ MSEL1CR_7_0, MSEL1CR_7_1,
+ MSEL1CR_6_0, MSEL1CR_6_1,
+ 0, 0,
+ MSEL1CR_4_0, MSEL1CR_4_1,
+ MSEL1CR_3_0, MSEL1CR_3_1,
+ MSEL1CR_2_0, MSEL1CR_2_1,
+ 0, 0,
+ MSEL1CR_0_0, MSEL1CR_0_1,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL3CR", 0xE6058020, 32, 1) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ MSEL3CR_27_0, MSEL3CR_27_1,
+ MSEL3CR_26_0, MSEL3CR_26_1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ MSEL3CR_21_0, MSEL3CR_21_1,
+ MSEL3CR_20_0, MSEL3CR_20_1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ MSEL3CR_15_0, MSEL3CR_15_1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0,
+ MSEL3CR_9_0, MSEL3CR_9_1,
+ 0, 0, 0, 0,
+ MSEL3CR_6_0, MSEL3CR_6_1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL4CR", 0xE6058024, 32, 1) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ MSEL4CR_19_0, MSEL4CR_19_1,
+ MSEL4CR_18_0, MSEL4CR_18_1,
+ MSEL4CR_17_0, MSEL4CR_17_1,
+ MSEL4CR_16_0, MSEL4CR_16_1,
+ MSEL4CR_15_0, MSEL4CR_15_1,
+ MSEL4CR_14_0, MSEL4CR_14_1,
+ 0, 0, 0, 0,
+ 0, 0,
+ MSEL4CR_10_0, MSEL4CR_10_1,
+ 0, 0, 0, 0,
+ 0, 0,
+ MSEL4CR_6_0, MSEL4CR_6_1,
+ 0, 0,
+ MSEL4CR_4_0, MSEL4CR_4_1,
+ 0, 0, 0, 0,
+ MSEL4CR_1_0, MSEL4CR_1_1,
+ 0, 0,
+ }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PORTL095_064DR", 0xE6054008, 32) {
+ PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+ PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+ PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+ PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+ PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_DATA_REG("PORTL127_096DR", 0xE605400C, 32) {
+ PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA,
+ PORT123_DATA, PORT122_DATA, PORT121_DATA, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTL159_128DR", 0xE6054010, 32) {
+ PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+ 0, 0, 0, 0,
+ PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+ PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+ PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+ PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+ PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+ PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTL191_160DR", 0xE6054014, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, PORT166_DATA, PORT165_DATA, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTD031_000DR", 0xE6055000, 32) {
+ PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+ PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+ PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+ PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+ PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+ PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+ PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+ PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTD063_032DR", 0xE6055004, 32) {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, PORT45_DATA, PORT44_DATA,
+ PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+ PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+ PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTR063_032DR", 0xE6056004, 32) {
+ PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+ PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+ PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+ PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+ PORT47_DATA, PORT46_DATA, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_DATA_REG("PORTR095_064DR", 0xE6056008, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+ PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+ PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTR191_160DR", 0xE6056014, 32) {
+ 0, PORT190_DATA, PORT189_DATA, PORT188_DATA,
+ PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA,
+ PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA,
+ PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA,
+ PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA,
+ PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA,
+ PORT167_DATA, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_DATA_REG("PORTU127_096DR", 0xE605700C, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT120_DATA,
+ PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+ PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+ PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+ PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+ PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_DATA_REG("PORTU159_128DR", 0xE6057010, 32) {
+ 0, 0, 0, 0,
+ PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { },
+};
+
+static struct pinmux_info sh7372_pinmux_info = {
+ .name = "sh7372_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PORT0,
+ .last_gpio = GPIO_FN_SDENC_DV_CLKI,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7372_pinmux_init(void)
+{
+ register_pinmux(&sh7372_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/pfc-sh7377.c b/arch/arm/mach-shmobile/pfc-sh7377.c
new file mode 100644
index 00000000000..613e6842ad0
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-sh7377.c
@@ -0,0 +1,1767 @@
+/*
+ * sh7377 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010 NISHIMOTO Hiroki
+ *
+ * This program is free software; 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/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7377.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx) \
+ _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
+ _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
+ _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
+ _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
+ _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _90(fn, pfx, sfx) \
+ _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
+ _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
+ _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
+ _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx), \
+ _10(fn, pfx##9, sfx)
+
+#define _265(fn, pfx, sfx) \
+ _10(fn, pfx, sfx), _90(fn, pfx, sfx), \
+ _10(fn, pfx##10, sfx), \
+ _1(fn, pfx##110, sfx), _1(fn, pfx##111, sfx), \
+ _1(fn, pfx##112, sfx), _1(fn, pfx##113, sfx), \
+ _1(fn, pfx##114, sfx), _1(fn, pfx##115, sfx), \
+ _1(fn, pfx##116, sfx), _1(fn, pfx##117, sfx), \
+ _1(fn, pfx##118, sfx), \
+ _1(fn, pfx##128, sfx), _1(fn, pfx##129, sfx), \
+ _10(fn, pfx##13, sfx), _10(fn, pfx##14, sfx), \
+ _10(fn, pfx##15, sfx), \
+ _1(fn, pfx##160, sfx), _1(fn, pfx##161, sfx), \
+ _1(fn, pfx##162, sfx), _1(fn, pfx##163, sfx), \
+ _1(fn, pfx##164, sfx), \
+ _1(fn, pfx##192, sfx), _1(fn, pfx##193, sfx), \
+ _1(fn, pfx##194, sfx), _1(fn, pfx##195, sfx), \
+ _1(fn, pfx##196, sfx), _1(fn, pfx##197, sfx), \
+ _1(fn, pfx##198, sfx), _1(fn, pfx##199, sfx), \
+ _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx), \
+ _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx), \
+ _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx), \
+ _1(fn, pfx##260, sfx), _1(fn, pfx##261, sfx), \
+ _1(fn, pfx##262, sfx), _1(fn, pfx##263, sfx), \
+ _1(fn, pfx##264, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_265(str) _265(_PORT, PORT, str)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PORT_265(DATA), /* PORT0_DATA -> PORT264_DATA */
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PORT_265(IN), /* PORT0_IN -> PORT264_IN */
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_265(IN_PU), /* PORT0_IN_PU -> PORT264_IN_PU */
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_265(IN_PD), /* PORT0_IN_PD -> PORT264_IN_PD */
+ PINMUX_INPUT_PULLDOWN_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PORT_265(OUT), /* PORT0_OUT -> PORT264_OUT */
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_265(FN_IN), /* PORT0_FN_IN -> PORT264_FN_IN */
+ PORT_265(FN_OUT), /* PORT0_FN_OUT -> PORT264_FN_OUT */
+ PORT_265(FN0), /* PORT0_FN0 -> PORT264_FN0 */
+ PORT_265(FN1), /* PORT0_FN1 -> PORT264_FN1 */
+ PORT_265(FN2), /* PORT0_FN2 -> PORT264_FN2 */
+ PORT_265(FN3), /* PORT0_FN3 -> PORT264_FN3 */
+ PORT_265(FN4), /* PORT0_FN4 -> PORT264_FN4 */
+ PORT_265(FN5), /* PORT0_FN5 -> PORT264_FN5 */
+ PORT_265(FN6), /* PORT0_FN6 -> PORT264_FN6 */
+ PORT_265(FN7), /* PORT0_FN7 -> PORT264_FN7 */
+
+ MSELBCR_MSEL17_1, MSELBCR_MSEL17_0,
+ MSELBCR_MSEL16_1, MSELBCR_MSEL16_0,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ /* Special Pull-up / Pull-down Functions */
+ PORT66_KEYIN0_PU_MARK, PORT67_KEYIN1_PU_MARK,
+ PORT68_KEYIN2_PU_MARK, PORT69_KEYIN3_PU_MARK,
+ PORT70_KEYIN4_PU_MARK, PORT71_KEYIN5_PU_MARK,
+ PORT72_KEYIN6_PU_MARK,
+
+ /* 55-1 */
+ VBUS_0_MARK,
+ CPORT0_MARK,
+ CPORT1_MARK,
+ CPORT2_MARK,
+ CPORT3_MARK,
+ CPORT4_MARK,
+ CPORT5_MARK,
+ CPORT6_MARK,
+ CPORT7_MARK,
+ CPORT8_MARK,
+ CPORT9_MARK,
+ CPORT10_MARK,
+ CPORT11_MARK, SIN2_MARK,
+ CPORT12_MARK, XCTS2_MARK,
+ CPORT13_MARK, RFSPO4_MARK,
+ CPORT14_MARK, RFSPO5_MARK,
+ CPORT15_MARK, SCIFA0_SCK_MARK, GPS_AGC2_MARK,
+ CPORT16_MARK, SCIFA0_TXD_MARK, GPS_AGC3_MARK,
+ CPORT17_IC_OE_MARK, SOUT2_MARK,
+ CPORT18_MARK, XRTS2_MARK, PORT19_VIO_CKO2_MARK,
+ CPORT19_MPORT1_MARK,
+ CPORT20_MARK, RFSPO6_MARK,
+ CPORT21_MARK, STATUS0_MARK,
+ CPORT22_MARK, STATUS1_MARK,
+ CPORT23_MARK, STATUS2_MARK, RFSPO7_MARK,
+ B_SYNLD1_MARK,
+ B_SYNLD2_MARK, SYSENMSK_MARK,
+ XMAINPS_MARK,
+ XDIVPS_MARK,
+ XIDRST_MARK,
+ IDCLK_MARK, IC_DP_MARK,
+ IDIO_MARK, IC_DM_MARK,
+ SOUT1_MARK, SCIFA4_TXD_MARK, M02_BERDAT_MARK,
+ SIN1_MARK, SCIFA4_RXD_MARK, XWUP_MARK,
+ XRTS1_MARK, SCIFA4_RTS_MARK, M03_BERCLK_MARK,
+ XCTS1_MARK, SCIFA4_CTS_MARK,
+ PCMCLKO_MARK,
+ SYNC8KO_MARK,
+
+ /* 55-2 */
+ DNPCM_A_MARK,
+ UPPCM_A_MARK,
+ VACK_MARK,
+ XTALB1L_MARK,
+ GPS_AGC1_MARK, SCIFA0_RTS_MARK,
+ GPS_AGC4_MARK, SCIFA0_RXD_MARK,
+ GPS_PWRDOWN_MARK, SCIFA0_CTS_MARK,
+ GPS_IM_MARK,
+ GPS_IS_MARK,
+ GPS_QM_MARK,
+ GPS_QS_MARK,
+ FMSOCK_MARK, PORT49_IRDA_OUT_MARK, PORT49_IROUT_MARK,
+ FMSOOLR_MARK, BBIF2_TSYNC2_MARK, TPU2TO2_MARK, IPORT3_MARK,
+ FMSIOLR_MARK,
+ FMSOOBT_MARK, BBIF2_TSCK2_MARK, TPU2TO3_MARK, OPORT1_MARK,
+ FMSIOBT_MARK,
+ FMSOSLD_MARK, BBIF2_TXD2_MARK, OPORT2_MARK,
+ FMSOILR_MARK, PORT53_IRDA_IN_MARK, TPU3TO3_MARK, OPORT3_MARK,
+ FMSIILR_MARK,
+ FMSOIBT_MARK, PORT54_IRDA_FIRSEL_MARK, TPU3TO2_MARK, FMSIIBT_MARK,
+ FMSISLD_MARK, MFG0_OUT1_MARK, TPU0TO0_MARK,
+ A0_EA0_MARK, BS_MARK,
+ A12_EA12_MARK, PORT58_VIO_CKOR_MARK, TPU4TO2_MARK,
+ A13_EA13_MARK, PORT59_IROUT_MARK, MFG0_OUT2_MARK, TPU0TO1_MARK,
+ A14_EA14_MARK, PORT60_KEYOUT5_MARK,
+ A15_EA15_MARK, PORT61_KEYOUT4_MARK,
+ A16_EA16_MARK, PORT62_KEYOUT3_MARK, MSIOF0_SS1_MARK,
+ A17_EA17_MARK, PORT63_KEYOUT2_MARK, MSIOF0_TSYNC_MARK,
+ A18_EA18_MARK, PORT64_KEYOUT1_MARK, MSIOF0_TSCK_MARK,
+ A19_EA19_MARK, PORT65_KEYOUT0_MARK, MSIOF0_TXD_MARK,
+ A20_EA20_MARK, PORT66_KEYIN0_MARK, MSIOF0_RSCK_MARK,
+ A21_EA21_MARK, PORT67_KEYIN1_MARK, MSIOF0_RSYNC_MARK,
+ A22_EA22_MARK, PORT68_KEYIN2_MARK, MSIOF0_MCK0_MARK,
+ A23_EA23_MARK, PORT69_KEYIN3_MARK, MSIOF0_MCK1_MARK,
+ A24_EA24_MARK, PORT70_KEYIN4_MARK, MSIOF0_RXD_MARK,
+ A25_EA25_MARK, PORT71_KEYIN5_MARK, MSIOF0_SS2_MARK,
+ A26_MARK, PORT72_KEYIN6_MARK,
+ D0_ED0_NAF0_MARK,
+ D1_ED1_NAF1_MARK,
+ D2_ED2_NAF2_MARK,
+ D3_ED3_NAF3_MARK,
+ D4_ED4_NAF4_MARK,
+ D5_ED5_NAF5_MARK,
+ D6_ED6_NAF6_MARK,
+ D7_ED7_NAF7_MARK,
+ D8_ED8_NAF8_MARK,
+ D9_ED9_NAF9_MARK,
+ D10_ED10_NAF10_MARK,
+ D11_ED11_NAF11_MARK,
+ D12_ED12_NAF12_MARK,
+ D13_ED13_NAF13_MARK,
+ D14_ED14_NAF14_MARK,
+ D15_ED15_NAF15_MARK,
+ CS4_MARK,
+ CS5A_MARK, FMSICK_MARK,
+ CS5B_MARK, FCE1_MARK,
+
+ /* 55-3 */
+ CS6B_MARK, XCS2_MARK, CS6A_MARK, DACK0_MARK,
+ FCE0_MARK,
+ WAIT_MARK, DREQ0_MARK,
+ RD_XRD_MARK,
+ WE0_XWR0_FWE_MARK,
+ WE1_XWR1_MARK,
+ FRB_MARK,
+ CKO_MARK,
+ NBRSTOUT_MARK,
+ NBRST_MARK,
+ GPS_EPPSIN_MARK,
+ LATCHPULSE_MARK,
+ LTESIGNAL_MARK,
+ LEGACYSTATE_MARK,
+ TCKON_MARK,
+ VIO_VD_MARK, PORT128_KEYOUT0_MARK, IPORT0_MARK,
+ VIO_HD_MARK, PORT129_KEYOUT1_MARK, IPORT1_MARK,
+ VIO_D0_MARK, PORT130_KEYOUT2_MARK, PORT130_MSIOF2_RXD_MARK,
+ VIO_D1_MARK, PORT131_KEYOUT3_MARK, PORT131_MSIOF2_SS1_MARK,
+ VIO_D2_MARK, PORT132_KEYOUT4_MARK, PORT132_MSIOF2_SS2_MARK,
+ VIO_D3_MARK, PORT133_KEYOUT5_MARK, PORT133_MSIOF2_TSYNC_MARK,
+ VIO_D4_MARK, PORT134_KEYIN0_MARK, PORT134_MSIOF2_TXD_MARK,
+ VIO_D5_MARK, PORT135_KEYIN1_MARK, PORT135_MSIOF2_TSCK_MARK,
+ VIO_D6_MARK, PORT136_KEYIN2_MARK,
+ VIO_D7_MARK, PORT137_KEYIN3_MARK,
+ VIO_D8_MARK, M9_SLCD_A01_MARK, PORT138_FSIAOMC_MARK,
+ VIO_D9_MARK, M10_SLCD_CK1_MARK, PORT139_FSIAOLR_MARK,
+ VIO_D10_MARK, M11_SLCD_SO1_MARK, TPU0TO2_MARK, PORT140_FSIAOBT_MARK,
+ VIO_D11_MARK, M12_SLCD_CE1_MARK, TPU0TO3_MARK, PORT141_FSIAOSLD_MARK,
+ VIO_D12_MARK, M13_BSW_MARK, PORT142_FSIACK_MARK,
+ VIO_D13_MARK, M14_GSW_MARK, PORT143_FSIAILR_MARK,
+ VIO_D14_MARK, M15_RSW_MARK, PORT144_FSIAIBT_MARK,
+ VIO_D15_MARK, TPU1TO3_MARK, PORT145_FSIAISLD_MARK,
+ VIO_CLK_MARK, PORT146_KEYIN4_MARK, IPORT2_MARK,
+ VIO_FIELD_MARK, PORT147_KEYIN5_MARK,
+ VIO_CKO_MARK, PORT148_KEYIN6_MARK,
+ A27_MARK, RDWR_XWE_MARK, MFG0_IN1_MARK,
+ MFG0_IN2_MARK,
+ TS_SPSYNC3_MARK, MSIOF2_RSCK_MARK,
+ TS_SDAT3_MARK, MSIOF2_RSYNC_MARK,
+ TPU1TO2_MARK, TS_SDEN3_MARK, PORT153_MSIOF2_SS1_MARK,
+ SOUT3_MARK, SCIFA2_TXD1_MARK, MSIOF2_MCK0_MARK,
+ SIN3_MARK, SCIFA2_RXD1_MARK, MSIOF2_MCK1_MARK,
+ XRTS3_MARK, SCIFA2_RTS1_MARK, PORT156_MSIOF2_SS2_MARK,
+ XCTS3_MARK, SCIFA2_CTS1_MARK, PORT157_MSIOF2_RXD_MARK,
+
+ /* 55-4 */
+ DINT_MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
+ PORT159_SCIFB_SCK_MARK, PORT159_SCIFA5_SCK_MARK, NMI_MARK,
+ PORT160_SCIFB_TXD_MARK, PORT160_SCIFA5_TXD_MARK, SOUT0_MARK,
+ PORT161_SCIFB_CTS_MARK, PORT161_SCIFA5_CTS_MARK, XCTS0_MARK,
+ MFG3_IN2_MARK,
+ PORT162_SCIFB_RXD_MARK, PORT162_SCIFA5_RXD_MARK, SIN0_MARK,
+ MFG3_IN1_MARK,
+ PORT163_SCIFB_RTS_MARK, PORT163_SCIFA5_RTS_MARK, XRTS0_MARK,
+ MFG3_OUT1_MARK, TPU3TO0_MARK,
+ LCDD0_MARK, PORT192_KEYOUT0_MARK, EXT_CKI_MARK,
+ LCDD1_MARK, PORT193_KEYOUT1_MARK, PORT193_SCIFA5_CTS_MARK,
+ BBIF2_TSYNC1_MARK,
+ LCDD2_MARK, PORT194_KEYOUT2_MARK, PORT194_SCIFA5_RTS_MARK,
+ BBIF2_TSCK1_MARK,
+ LCDD3_MARK, PORT195_KEYOUT3_MARK, PORT195_SCIFA5_RXD_MARK,
+ BBIF2_TXD1_MARK,
+ LCDD4_MARK, PORT196_KEYOUT4_MARK, PORT196_SCIFA5_TXD_MARK,
+ LCDD5_MARK, PORT197_KEYOUT5_MARK, PORT197_SCIFA5_SCK_MARK,
+ MFG2_OUT2_MARK,
+ TPU2TO1_MARK,
+ LCDD6_MARK, XWR2_MARK,
+ LCDD7_MARK, TPU4TO1_MARK, MFG4_OUT2_MARK, XWR3_MARK,
+ LCDD8_MARK, PORT200_KEYIN0_MARK, VIO_DR0_MARK, D16_MARK, ED16_MARK,
+ LCDD9_MARK, PORT201_KEYIN1_MARK, VIO_DR1_MARK, D17_MARK, ED17_MARK,
+ LCDD10_MARK, PORT202_KEYIN2_MARK, VIO_DR2_MARK, D18_MARK, ED18_MARK,
+ LCDD11_MARK, PORT203_KEYIN3_MARK, VIO_DR3_MARK, D19_MARK, ED19_MARK,
+ LCDD12_MARK, PORT204_KEYIN4_MARK, VIO_DR4_MARK, D20_MARK, ED20_MARK,
+ LCDD13_MARK, PORT205_KEYIN5_MARK, VIO_DR5_MARK, D21_MARK, ED21_MARK,
+ LCDD14_MARK, PORT206_KEYIN6_MARK, VIO_DR6_MARK, D22_MARK, ED22_MARK,
+ LCDD15_MARK, PORT207_MSIOF0L_SS1_MARK, PORT207_KEYOUT0_MARK,
+ VIO_DR7_MARK, D23_MARK, ED23_MARK,
+ LCDD16_MARK, PORT208_MSIOF0L_SS2_MARK, PORT208_KEYOUT1_MARK,
+ VIO_VDR_MARK, D24_MARK, ED24_MARK,
+ LCDD17_MARK, PORT209_KEYOUT2_MARK, VIO_HDR_MARK, D25_MARK, ED25_MARK,
+ LCDD18_MARK, DREQ2_MARK, PORT210_MSIOF0L_SS1_MARK, D26_MARK, ED26_MARK,
+ LCDD19_MARK, PORT211_MSIOF0L_SS2_MARK, D27_MARK, ED27_MARK,
+ LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK, D28_MARK, ED28_MARK,
+ LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK, D29_MARK, ED29_MARK,
+ LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_RSCK_MARK, D30_MARK, ED30_MARK,
+ LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_RSYNC_MARK, D31_MARK, ED31_MARK,
+ LCDDCK_MARK, LCDWR_MARK, PORT216_KEYOUT3_MARK, VIO_CLKR_MARK,
+ LCDRD_MARK, DACK2_MARK, MSIOF0L_TSYNC_MARK,
+ LCDHSYN_MARK, LCDCS_MARK, LCDCS2_MARK, DACK3_MARK,
+ PORT218_VIO_CKOR_MARK, PORT218_KEYOUT4_MARK,
+ LCDDISP_MARK, LCDRS_MARK, DREQ3_MARK, MSIOF0L_TSCK_MARK,
+ LCDVSYN_MARK, LCDVSYN2_MARK, PORT220_KEYOUT5_MARK,
+ LCDLCLK_MARK, DREQ1_MARK, PWEN_MARK, MSIOF0L_RXD_MARK,
+ LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, OVCN_MARK, MSIOF0L_TXD_MARK,
+ SCIFA1_TXD_MARK, OVCN2_MARK,
+ EXTLP_MARK, SCIFA1_SCK_MARK, USBTERM_MARK, PORT226_VIO_CKO2_MARK,
+ SCIFA1_RTS_MARK, IDIN_MARK,
+ SCIFA1_RXD_MARK,
+ SCIFA1_CTS_MARK, MFG1_IN1_MARK,
+ MSIOF1_TXD_MARK, SCIFA2_TXD2_MARK, PORT230_FSIAOMC_MARK,
+ MSIOF1_TSYNC_MARK, SCIFA2_CTS2_MARK, PORT231_FSIAOLR_MARK,
+ MSIOF1_TSCK_MARK, SCIFA2_SCK2_MARK, PORT232_FSIAOBT_MARK,
+ MSIOF1_RXD_MARK, SCIFA2_RXD2_MARK, GPS_VCOTRIG_MARK,
+ PORT233_FSIACK_MARK,
+ MSIOF1_RSCK_MARK, SCIFA2_RTS2_MARK, PORT234_FSIAOSLD_MARK,
+ MSIOF1_RSYNC_MARK, OPORT0_MARK, MFG1_IN2_MARK, PORT235_FSIAILR_MARK,
+ MSIOF1_MCK0_MARK, I2C_SDA2_MARK, PORT236_FSIAIBT_MARK,
+ MSIOF1_MCK1_MARK, I2C_SCL2_MARK, PORT237_FSIAISLD_MARK,
+ MSIOF1_SS1_MARK, EDBGREQ3_MARK,
+
+ /* 55-5 */
+ MSIOF1_SS2_MARK,
+ SCIFA6_TXD_MARK,
+ PORT241_IRDA_OUT_MARK, PORT241_IROUT_MARK, MFG4_OUT1_MARK,
+ TPU4TO0_MARK,
+ PORT242_IRDA_IN_MARK, MFG4_IN2_MARK,
+ PORT243_IRDA_FIRSEL_MARK, PORT243_VIO_CKO2_MARK,
+ PORT244_SCIFA5_CTS_MARK, MFG2_IN1_MARK, PORT244_SCIFB_CTS_MARK,
+ PORT244_MSIOF2_RXD_MARK,
+ PORT245_SCIFA5_RTS_MARK, MFG2_IN2_MARK, PORT245_SCIFB_RTS_MARK,
+ PORT245_MSIOF2_TXD_MARK,
+ PORT246_SCIFA5_RXD_MARK, MFG1_OUT1_MARK, PORT246_SCIFB_RXD_MARK,
+ TPU1TO0_MARK,
+ PORT247_SCIFA5_TXD_MARK, MFG3_OUT2_MARK, PORT247_SCIFB_TXD_MARK,
+ TPU3TO1_MARK,
+ PORT248_SCIFA5_SCK_MARK, MFG2_OUT1_MARK, PORT248_SCIFB_SCK_MARK,
+ TPU2TO0_MARK,
+ PORT248_MSIOF2_TSCK_MARK,
+ PORT249_IROUT_MARK, MFG4_IN1_MARK, PORT249_MSIOF2_TSYNC_MARK,
+ SDHICLK0_MARK, TCK2_SWCLK_MC0_MARK,
+ SDHICD0_MARK,
+ SDHID0_0_MARK, TMS2_SWDIO_MC0_MARK,
+ SDHID0_1_MARK, TDO2_SWO0_MC0_MARK,
+ SDHID0_2_MARK, TDI2_MARK,
+ SDHID0_3_MARK, RTCK2_SWO1_MC0_MARK,
+ SDHICMD0_MARK, TRST2_MARK,
+ SDHIWP0_MARK, EDBGREQ2_MARK,
+ SDHICLK1_MARK, TCK3_SWCLK_MC1_MARK,
+ SDHID1_0_MARK, M11_SLCD_SO2_MARK, TS_SPSYNC2_MARK,
+ TMS3_SWDIO_MC1_MARK,
+ SDHID1_1_MARK, M9_SLCD_A02_MARK, TS_SDAT2_MARK, TDO3_SWO0_MC1_MARK,
+ SDHID1_2_MARK, M10_SLCD_CK2_MARK, TS_SDEN2_MARK, TDI3_MARK,
+ SDHID1_3_MARK, M12_SLCD_CE2_MARK, TS_SCK2_MARK, RTCK3_SWO1_MC1_MARK,
+ SDHICMD1_MARK, TRST3_MARK,
+ RESETOUTS_MARK,
+ PINMUX_MARK_END,
+};
+
+#define PORT_DATA_I(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+static pinmux_enum_t pinmux_data[] = {
+ /* specify valid pin states for each pin in GPIO mode */
+ /* 55-1 (GPIO) */
+ PORT_DATA_I_PD(0), PORT_DATA_I_PU(1),
+ PORT_DATA_I_PU(2), PORT_DATA_I_PU(3),
+ PORT_DATA_I_PU(4), PORT_DATA_I_PU(5),
+ PORT_DATA_I_PU(6), PORT_DATA_I_PU(7),
+ PORT_DATA_I_PU(8), PORT_DATA_I_PU(9),
+ PORT_DATA_I_PU(10), PORT_DATA_I_PU(11),
+ PORT_DATA_IO_PU(12), PORT_DATA_IO_PU(13),
+ PORT_DATA_IO_PU_PD(14), PORT_DATA_IO_PU_PD(15),
+ PORT_DATA_O(16), PORT_DATA_IO(17),
+ PORT_DATA_O(18), PORT_DATA_O(19),
+ PORT_DATA_O(20), PORT_DATA_O(21),
+ PORT_DATA_O(22), PORT_DATA_O(23),
+ PORT_DATA_O(24), PORT_DATA_I_PD(25),
+ PORT_DATA_I_PD(26), PORT_DATA_O(27),
+ PORT_DATA_O(28), PORT_DATA_O(29),
+ PORT_DATA_IO(30), PORT_DATA_IO_PU(31),
+ PORT_DATA_IO_PD(32), PORT_DATA_I_PU(33),
+ PORT_DATA_IO_PD(34), PORT_DATA_I_PU_PD(35),
+ PORT_DATA_O(36), PORT_DATA_IO(37),
+
+ /* 55-2 (GPIO) */
+ PORT_DATA_O(38), PORT_DATA_I_PU(39),
+ PORT_DATA_I_PU_PD(40), PORT_DATA_O(41),
+ PORT_DATA_IO_PD(42), PORT_DATA_IO_PD(43),
+ PORT_DATA_IO_PD(44), PORT_DATA_I_PD(45),
+ PORT_DATA_I_PD(46), PORT_DATA_I_PD(47),
+ PORT_DATA_I_PD(48), PORT_DATA_IO_PU_PD(49),
+ PORT_DATA_IO_PD(50), PORT_DATA_IO_PD(51),
+ PORT_DATA_O(52), PORT_DATA_IO_PU_PD(53),
+ PORT_DATA_IO_PU_PD(54), PORT_DATA_IO_PD(55),
+ PORT_DATA_I_PU_PD(56), PORT_DATA_IO(57),
+ PORT_DATA_IO(58), PORT_DATA_IO(59),
+ PORT_DATA_IO(60), PORT_DATA_IO(61),
+ PORT_DATA_IO_PD(62), PORT_DATA_IO_PD(63),
+ PORT_DATA_IO_PD(64), PORT_DATA_IO_PD(65),
+ PORT_DATA_IO_PU_PD(66), PORT_DATA_IO_PU_PD(67),
+ PORT_DATA_IO_PU_PD(68), PORT_DATA_IO_PU_PD(69),
+ PORT_DATA_IO_PU_PD(70), PORT_DATA_IO_PU_PD(71),
+ PORT_DATA_IO_PU_PD(72), PORT_DATA_I_PU_PD(73),
+ PORT_DATA_IO_PU(74), PORT_DATA_IO_PU(75),
+ PORT_DATA_IO_PU(76), PORT_DATA_IO_PU(77),
+ PORT_DATA_IO_PU(78), PORT_DATA_IO_PU(79),
+ PORT_DATA_IO_PU(80), PORT_DATA_IO_PU(81),
+ PORT_DATA_IO_PU(82), PORT_DATA_IO_PU(83),
+ PORT_DATA_IO_PU(84), PORT_DATA_IO_PU(85),
+ PORT_DATA_IO_PU(86), PORT_DATA_IO_PU(87),
+ PORT_DATA_IO_PU(88), PORT_DATA_IO_PU(89),
+ PORT_DATA_O(90), PORT_DATA_IO_PU(91),
+ PORT_DATA_O(92),
+
+ /* 55-3 (GPIO) */
+ PORT_DATA_IO_PU(93),
+ PORT_DATA_O(94),
+ PORT_DATA_I_PU_PD(95),
+ PORT_DATA_IO(96), PORT_DATA_IO(97),
+ PORT_DATA_IO(98), PORT_DATA_I_PU(99),
+ PORT_DATA_O(100), PORT_DATA_O(101),
+ PORT_DATA_I_PU(102), PORT_DATA_IO_PD(103),
+ PORT_DATA_I_PD(104), PORT_DATA_I_PD(105),
+ PORT_DATA_I_PD(106), PORT_DATA_I_PD(107),
+ PORT_DATA_I_PD(108), PORT_DATA_IO_PD(109),
+ PORT_DATA_IO_PD(110), PORT_DATA_I_PD(111),
+ PORT_DATA_IO_PD(112), PORT_DATA_IO_PD(113),
+ PORT_DATA_IO_PD(114), PORT_DATA_I_PD(115),
+ PORT_DATA_I_PD(116), PORT_DATA_IO_PD(117),
+ PORT_DATA_I_PD(118), PORT_DATA_IO_PD(128),
+ PORT_DATA_IO_PD(129), PORT_DATA_IO_PD(130),
+ PORT_DATA_IO_PD(131), PORT_DATA_IO_PD(132),
+ PORT_DATA_IO_PD(133), PORT_DATA_IO_PU_PD(134),
+ PORT_DATA_IO_PU_PD(135), PORT_DATA_IO_PU_PD(136),
+ PORT_DATA_IO_PU_PD(137), PORT_DATA_IO_PD(138),
+ PORT_DATA_IO_PD(139), PORT_DATA_IO_PD(140),
+ PORT_DATA_IO_PD(141), PORT_DATA_IO_PD(142),
+ PORT_DATA_IO_PD(143), PORT_DATA_IO_PU_PD(144),
+ PORT_DATA_IO_PD(145), PORT_DATA_IO_PU_PD(146),
+ PORT_DATA_IO_PU_PD(147), PORT_DATA_IO_PU_PD(148),
+ PORT_DATA_IO_PU_PD(149), PORT_DATA_I_PD(150),
+ PORT_DATA_IO_PU_PD(151), PORT_DATA_IO_PD(152),
+ PORT_DATA_IO_PD(153), PORT_DATA_IO_PD(154),
+ PORT_DATA_I_PD(155), PORT_DATA_IO_PU_PD(156),
+ PORT_DATA_I_PD(157), PORT_DATA_IO_PD(158),
+
+ /* 55-4 (GPIO) */
+ PORT_DATA_IO_PU_PD(159), PORT_DATA_IO_PU_PD(160),
+ PORT_DATA_I_PU_PD(161), PORT_DATA_I_PU_PD(162),
+ PORT_DATA_IO_PU_PD(163), PORT_DATA_I_PU_PD(164),
+ PORT_DATA_IO_PD(192), PORT_DATA_IO_PD(193),
+ PORT_DATA_IO_PD(194), PORT_DATA_IO_PD(195),
+ PORT_DATA_IO_PD(196), PORT_DATA_IO_PD(197),
+ PORT_DATA_IO_PD(198), PORT_DATA_IO_PD(199),
+ PORT_DATA_IO_PU_PD(200), PORT_DATA_IO_PU_PD(201),
+ PORT_DATA_IO_PU_PD(202), PORT_DATA_IO_PU_PD(203),
+ PORT_DATA_IO_PU_PD(204), PORT_DATA_IO_PU_PD(205),
+ PORT_DATA_IO_PU_PD(206), PORT_DATA_IO_PD(207),
+ PORT_DATA_IO_PD(208), PORT_DATA_IO_PD(209),
+ PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
+ PORT_DATA_IO_PD(212), PORT_DATA_IO_PD(213),
+ PORT_DATA_IO_PD(214), PORT_DATA_IO_PD(215),
+ PORT_DATA_IO_PD(216), PORT_DATA_IO_PD(217),
+ PORT_DATA_O(218), PORT_DATA_IO_PD(219),
+ PORT_DATA_IO_PD(220), PORT_DATA_IO_PD(221),
+ PORT_DATA_IO_PU_PD(222),
+ PORT_DATA_I_PU_PD(223), PORT_DATA_I_PU_PD(224),
+ PORT_DATA_IO_PU_PD(225), PORT_DATA_O(226),
+ PORT_DATA_IO_PU_PD(227), PORT_DATA_I_PD(228),
+ PORT_DATA_I_PD(229), PORT_DATA_IO(230),
+ PORT_DATA_IO_PD(231), PORT_DATA_IO_PU_PD(232),
+ PORT_DATA_I_PD(233), PORT_DATA_IO_PU_PD(234),
+ PORT_DATA_IO_PU_PD(235), PORT_DATA_IO_PU_PD(236),
+ PORT_DATA_IO_PD(237), PORT_DATA_IO_PU_PD(238),
+
+ /* 55-5 (GPIO) */
+ PORT_DATA_IO_PU_PD(239), PORT_DATA_IO_PU_PD(240),
+ PORT_DATA_O(241), PORT_DATA_I_PD(242),
+ PORT_DATA_IO_PU_PD(243), PORT_DATA_IO_PU_PD(244),
+ PORT_DATA_IO_PU_PD(245), PORT_DATA_IO_PU_PD(246),
+ PORT_DATA_IO_PU_PD(247), PORT_DATA_IO_PU_PD(248),
+ PORT_DATA_IO_PU_PD(249), PORT_DATA_IO_PD(250),
+ PORT_DATA_IO_PU_PD(251), PORT_DATA_IO_PU_PD(252),
+ PORT_DATA_IO_PU_PD(253), PORT_DATA_IO_PU_PD(254),
+ PORT_DATA_IO_PU_PD(255), PORT_DATA_IO_PU_PD(256),
+ PORT_DATA_IO_PU_PD(257), PORT_DATA_IO_PD(258),
+ PORT_DATA_IO_PU_PD(259), PORT_DATA_IO_PU_PD(260),
+ PORT_DATA_IO_PU_PD(261), PORT_DATA_IO_PU_PD(262),
+ PORT_DATA_IO_PU_PD(263),
+
+ /* Special Pull-up / Pull-down Functions */
+ PINMUX_DATA(PORT66_KEYIN0_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT66_FN2, PORT66_IN_PU),
+ PINMUX_DATA(PORT67_KEYIN1_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT67_FN2, PORT67_IN_PU),
+ PINMUX_DATA(PORT68_KEYIN2_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT68_FN2, PORT68_IN_PU),
+ PINMUX_DATA(PORT69_KEYIN3_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT69_FN2, PORT69_IN_PU),
+ PINMUX_DATA(PORT70_KEYIN4_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT70_FN2, PORT70_IN_PU),
+ PINMUX_DATA(PORT71_KEYIN5_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT71_FN2, PORT71_IN_PU),
+ PINMUX_DATA(PORT72_KEYIN6_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT72_FN2, PORT72_IN_PU),
+
+
+ /* 55-1 (FN) */
+ PINMUX_DATA(VBUS_0_MARK, PORT0_FN1),
+ PINMUX_DATA(CPORT0_MARK, PORT1_FN1),
+ PINMUX_DATA(CPORT1_MARK, PORT2_FN1),
+ PINMUX_DATA(CPORT2_MARK, PORT3_FN1),
+ PINMUX_DATA(CPORT3_MARK, PORT4_FN1),
+ PINMUX_DATA(CPORT4_MARK, PORT5_FN1),
+ PINMUX_DATA(CPORT5_MARK, PORT6_FN1),
+ PINMUX_DATA(CPORT6_MARK, PORT7_FN1),
+ PINMUX_DATA(CPORT7_MARK, PORT8_FN1),
+ PINMUX_DATA(CPORT8_MARK, PORT9_FN1),
+ PINMUX_DATA(CPORT9_MARK, PORT10_FN1),
+ PINMUX_DATA(CPORT10_MARK, PORT11_FN1),
+ PINMUX_DATA(CPORT11_MARK, PORT12_FN1),
+ PINMUX_DATA(SIN2_MARK, PORT12_FN2),
+ PINMUX_DATA(CPORT12_MARK, PORT13_FN1),
+ PINMUX_DATA(XCTS2_MARK, PORT13_FN2),
+ PINMUX_DATA(CPORT13_MARK, PORT14_FN1),
+ PINMUX_DATA(RFSPO4_MARK, PORT14_FN2),
+ PINMUX_DATA(CPORT14_MARK, PORT15_FN1),
+ PINMUX_DATA(RFSPO5_MARK, PORT15_FN2),
+ PINMUX_DATA(CPORT15_MARK, PORT16_FN1),
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT16_FN2),
+ PINMUX_DATA(GPS_AGC2_MARK, PORT16_FN3),
+ PINMUX_DATA(CPORT16_MARK, PORT17_FN1),
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT17_FN2),
+ PINMUX_DATA(GPS_AGC3_MARK, PORT17_FN3),
+ PINMUX_DATA(CPORT17_IC_OE_MARK, PORT18_FN1),
+ PINMUX_DATA(SOUT2_MARK, PORT18_FN2),
+ PINMUX_DATA(CPORT18_MARK, PORT19_FN1),
+ PINMUX_DATA(XRTS2_MARK, PORT19_FN2),
+ PINMUX_DATA(PORT19_VIO_CKO2_MARK, PORT19_FN3),
+ PINMUX_DATA(CPORT19_MPORT1_MARK, PORT20_FN1),
+ PINMUX_DATA(CPORT20_MARK, PORT21_FN1),
+ PINMUX_DATA(RFSPO6_MARK, PORT21_FN2),
+ PINMUX_DATA(CPORT21_MARK, PORT22_FN1),
+ PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
+ PINMUX_DATA(CPORT22_MARK, PORT23_FN1),
+ PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
+ PINMUX_DATA(CPORT23_MARK, PORT24_FN1),
+ PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
+ PINMUX_DATA(RFSPO7_MARK, PORT24_FN3),
+ PINMUX_DATA(B_SYNLD1_MARK, PORT25_FN1),
+ PINMUX_DATA(B_SYNLD2_MARK, PORT26_FN1),
+ PINMUX_DATA(SYSENMSK_MARK, PORT26_FN2),
+ PINMUX_DATA(XMAINPS_MARK, PORT27_FN1),
+ PINMUX_DATA(XDIVPS_MARK, PORT28_FN1),
+ PINMUX_DATA(XIDRST_MARK, PORT29_FN1),
+ PINMUX_DATA(IDCLK_MARK, PORT30_FN1),
+ PINMUX_DATA(IC_DP_MARK, PORT30_FN2),
+ PINMUX_DATA(IDIO_MARK, PORT31_FN1),
+ PINMUX_DATA(IC_DM_MARK, PORT31_FN2),
+ PINMUX_DATA(SOUT1_MARK, PORT32_FN1),
+ PINMUX_DATA(SCIFA4_TXD_MARK, PORT32_FN2),
+ PINMUX_DATA(M02_BERDAT_MARK, PORT32_FN3),
+ PINMUX_DATA(SIN1_MARK, PORT33_FN1),
+ PINMUX_DATA(SCIFA4_RXD_MARK, PORT33_FN2),
+ PINMUX_DATA(XWUP_MARK, PORT33_FN3),
+ PINMUX_DATA(XRTS1_MARK, PORT34_FN1),
+ PINMUX_DATA(SCIFA4_RTS_MARK, PORT34_FN2),
+ PINMUX_DATA(M03_BERCLK_MARK, PORT34_FN3),
+ PINMUX_DATA(XCTS1_MARK, PORT35_FN1),
+ PINMUX_DATA(SCIFA4_CTS_MARK, PORT35_FN2),
+ PINMUX_DATA(PCMCLKO_MARK, PORT36_FN1),
+ PINMUX_DATA(SYNC8KO_MARK, PORT37_FN1),
+
+ /* 55-2 (FN) */
+ PINMUX_DATA(DNPCM_A_MARK, PORT38_FN1),
+ PINMUX_DATA(UPPCM_A_MARK, PORT39_FN1),
+ PINMUX_DATA(VACK_MARK, PORT40_FN1),
+ PINMUX_DATA(XTALB1L_MARK, PORT41_FN1),
+ PINMUX_DATA(GPS_AGC1_MARK, PORT42_FN1),
+ PINMUX_DATA(SCIFA0_RTS_MARK, PORT42_FN2),
+ PINMUX_DATA(GPS_AGC4_MARK, PORT43_FN1),
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT43_FN2),
+ PINMUX_DATA(GPS_PWRDOWN_MARK, PORT44_FN1),
+ PINMUX_DATA(SCIFA0_CTS_MARK, PORT44_FN2),
+ PINMUX_DATA(GPS_IM_MARK, PORT45_FN1),
+ PINMUX_DATA(GPS_IS_MARK, PORT46_FN1),
+ PINMUX_DATA(GPS_QM_MARK, PORT47_FN1),
+ PINMUX_DATA(GPS_QS_MARK, PORT48_FN1),
+ PINMUX_DATA(FMSOCK_MARK, PORT49_FN1),
+ PINMUX_DATA(PORT49_IRDA_OUT_MARK, PORT49_FN2),
+ PINMUX_DATA(PORT49_IROUT_MARK, PORT49_FN3),
+ PINMUX_DATA(FMSOOLR_MARK, PORT50_FN1),
+ PINMUX_DATA(BBIF2_TSYNC2_MARK, PORT50_FN2),
+ PINMUX_DATA(TPU2TO2_MARK, PORT50_FN3),
+ PINMUX_DATA(IPORT3_MARK, PORT50_FN4),
+ PINMUX_DATA(FMSIOLR_MARK, PORT50_FN5),
+ PINMUX_DATA(FMSOOBT_MARK, PORT51_FN1),
+ PINMUX_DATA(BBIF2_TSCK2_MARK, PORT51_FN2),
+ PINMUX_DATA(TPU2TO3_MARK, PORT51_FN3),
+ PINMUX_DATA(OPORT1_MARK, PORT51_FN4),
+ PINMUX_DATA(FMSIOBT_MARK, PORT51_FN5),
+ PINMUX_DATA(FMSOSLD_MARK, PORT52_FN1),
+ PINMUX_DATA(BBIF2_TXD2_MARK, PORT52_FN2),
+ PINMUX_DATA(OPORT2_MARK, PORT52_FN3),
+ PINMUX_DATA(FMSOILR_MARK, PORT53_FN1),
+ PINMUX_DATA(PORT53_IRDA_IN_MARK, PORT53_FN2),
+ PINMUX_DATA(TPU3TO3_MARK, PORT53_FN3),
+ PINMUX_DATA(OPORT3_MARK, PORT53_FN4),
+ PINMUX_DATA(FMSIILR_MARK, PORT53_FN5),
+ PINMUX_DATA(FMSOIBT_MARK, PORT54_FN1),
+ PINMUX_DATA(PORT54_IRDA_FIRSEL_MARK, PORT54_FN2),
+ PINMUX_DATA(TPU3TO2_MARK, PORT54_FN3),
+ PINMUX_DATA(FMSIIBT_MARK, PORT54_FN4),
+ PINMUX_DATA(FMSISLD_MARK, PORT55_FN1),
+ PINMUX_DATA(MFG0_OUT1_MARK, PORT55_FN2),
+ PINMUX_DATA(TPU0TO0_MARK, PORT55_FN3),
+ PINMUX_DATA(A0_EA0_MARK, PORT57_FN1),
+ PINMUX_DATA(BS_MARK, PORT57_FN2),
+ PINMUX_DATA(A12_EA12_MARK, PORT58_FN1),
+ PINMUX_DATA(PORT58_VIO_CKOR_MARK, PORT58_FN2),
+ PINMUX_DATA(TPU4TO2_MARK, PORT58_FN3),
+ PINMUX_DATA(A13_EA13_MARK, PORT59_FN1),
+ PINMUX_DATA(PORT59_IROUT_MARK, PORT59_FN2),
+ PINMUX_DATA(MFG0_OUT2_MARK, PORT59_FN3),
+ PINMUX_DATA(TPU0TO1_MARK, PORT59_FN4),
+ PINMUX_DATA(A14_EA14_MARK, PORT60_FN1),
+ PINMUX_DATA(PORT60_KEYOUT5_MARK, PORT60_FN2),
+ PINMUX_DATA(A15_EA15_MARK, PORT61_FN1),
+ PINMUX_DATA(PORT61_KEYOUT4_MARK, PORT61_FN2),
+ PINMUX_DATA(A16_EA16_MARK, PORT62_FN1),
+ PINMUX_DATA(PORT62_KEYOUT3_MARK, PORT62_FN2),
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT62_FN3),
+ PINMUX_DATA(A17_EA17_MARK, PORT63_FN1),
+ PINMUX_DATA(PORT63_KEYOUT2_MARK, PORT63_FN2),
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT63_FN3),
+ PINMUX_DATA(A18_EA18_MARK, PORT64_FN1),
+ PINMUX_DATA(PORT64_KEYOUT1_MARK, PORT64_FN2),
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT64_FN3),
+ PINMUX_DATA(A19_EA19_MARK, PORT65_FN1),
+ PINMUX_DATA(PORT65_KEYOUT0_MARK, PORT65_FN2),
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT65_FN3),
+ PINMUX_DATA(A20_EA20_MARK, PORT66_FN1),
+ PINMUX_DATA(PORT66_KEYIN0_MARK, PORT66_FN2),
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT66_FN3),
+ PINMUX_DATA(A21_EA21_MARK, PORT67_FN1),
+ PINMUX_DATA(PORT67_KEYIN1_MARK, PORT67_FN2),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT67_FN3),
+ PINMUX_DATA(A22_EA22_MARK, PORT68_FN1),
+ PINMUX_DATA(PORT68_KEYIN2_MARK, PORT68_FN2),
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT68_FN3),
+ PINMUX_DATA(A23_EA23_MARK, PORT69_FN1),
+ PINMUX_DATA(PORT69_KEYIN3_MARK, PORT69_FN2),
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT69_FN3),
+ PINMUX_DATA(A24_EA24_MARK, PORT70_FN1),
+ PINMUX_DATA(PORT70_KEYIN4_MARK, PORT70_FN2),
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT70_FN3),
+ PINMUX_DATA(A25_EA25_MARK, PORT71_FN1),
+ PINMUX_DATA(PORT71_KEYIN5_MARK, PORT71_FN2),
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT71_FN3),
+ PINMUX_DATA(A26_MARK, PORT72_FN1),
+ PINMUX_DATA(PORT72_KEYIN6_MARK, PORT72_FN2),
+ PINMUX_DATA(D0_ED0_NAF0_MARK, PORT74_FN1),
+ PINMUX_DATA(D1_ED1_NAF1_MARK, PORT75_FN1),
+ PINMUX_DATA(D2_ED2_NAF2_MARK, PORT76_FN1),
+ PINMUX_DATA(D3_ED3_NAF3_MARK, PORT77_FN1),
+ PINMUX_DATA(D4_ED4_NAF4_MARK, PORT78_FN1),
+ PINMUX_DATA(D5_ED5_NAF5_MARK, PORT79_FN1),
+ PINMUX_DATA(D6_ED6_NAF6_MARK, PORT80_FN1),
+ PINMUX_DATA(D7_ED7_NAF7_MARK, PORT81_FN1),
+ PINMUX_DATA(D8_ED8_NAF8_MARK, PORT82_FN1),
+ PINMUX_DATA(D9_ED9_NAF9_MARK, PORT83_FN1),
+ PINMUX_DATA(D10_ED10_NAF10_MARK, PORT84_FN1),
+ PINMUX_DATA(D11_ED11_NAF11_MARK, PORT85_FN1),
+ PINMUX_DATA(D12_ED12_NAF12_MARK, PORT86_FN1),
+ PINMUX_DATA(D13_ED13_NAF13_MARK, PORT87_FN1),
+ PINMUX_DATA(D14_ED14_NAF14_MARK, PORT88_FN1),
+ PINMUX_DATA(D15_ED15_NAF15_MARK, PORT89_FN1),
+ PINMUX_DATA(CS4_MARK, PORT90_FN1),
+ PINMUX_DATA(CS5A_MARK, PORT91_FN1),
+ PINMUX_DATA(FMSICK_MARK, PORT91_FN2),
+ PINMUX_DATA(CS5B_MARK, PORT92_FN1),
+ PINMUX_DATA(FCE1_MARK, PORT92_FN2),
+
+ /* 55-3 (FN) */
+ PINMUX_DATA(CS6B_MARK, PORT93_FN1),
+ PINMUX_DATA(XCS2_MARK, PORT93_FN2),
+ PINMUX_DATA(CS6A_MARK, PORT93_FN3),
+ PINMUX_DATA(DACK0_MARK, PORT93_FN4),
+ PINMUX_DATA(FCE0_MARK, PORT94_FN1),
+ PINMUX_DATA(WAIT_MARK, PORT95_FN1),
+ PINMUX_DATA(DREQ0_MARK, PORT95_FN2),
+ PINMUX_DATA(RD_XRD_MARK, PORT96_FN1),
+ PINMUX_DATA(WE0_XWR0_FWE_MARK, PORT97_FN1),
+ PINMUX_DATA(WE1_XWR1_MARK, PORT98_FN1),
+ PINMUX_DATA(FRB_MARK, PORT99_FN1),
+ PINMUX_DATA(CKO_MARK, PORT100_FN1),
+ PINMUX_DATA(NBRSTOUT_MARK, PORT101_FN1),
+ PINMUX_DATA(NBRST_MARK, PORT102_FN1),
+ PINMUX_DATA(GPS_EPPSIN_MARK, PORT106_FN1),
+ PINMUX_DATA(LATCHPULSE_MARK, PORT110_FN1),
+ PINMUX_DATA(LTESIGNAL_MARK, PORT111_FN1),
+ PINMUX_DATA(LEGACYSTATE_MARK, PORT112_FN1),
+ PINMUX_DATA(TCKON_MARK, PORT118_FN1),
+ PINMUX_DATA(VIO_VD_MARK, PORT128_FN1),
+ PINMUX_DATA(PORT128_KEYOUT0_MARK, PORT128_FN2),
+ PINMUX_DATA(IPORT0_MARK, PORT128_FN3),
+ PINMUX_DATA(VIO_HD_MARK, PORT129_FN1),
+ PINMUX_DATA(PORT129_KEYOUT1_MARK, PORT129_FN2),
+ PINMUX_DATA(IPORT1_MARK, PORT129_FN3),
+ PINMUX_DATA(VIO_D0_MARK, PORT130_FN1),
+ PINMUX_DATA(PORT130_KEYOUT2_MARK, PORT130_FN2),
+ PINMUX_DATA(PORT130_MSIOF2_RXD_MARK, PORT130_FN3),
+ PINMUX_DATA(VIO_D1_MARK, PORT131_FN1),
+ PINMUX_DATA(PORT131_KEYOUT3_MARK, PORT131_FN2),
+ PINMUX_DATA(PORT131_MSIOF2_SS1_MARK, PORT131_FN3),
+ PINMUX_DATA(VIO_D2_MARK, PORT132_FN1),
+ PINMUX_DATA(PORT132_KEYOUT4_MARK, PORT132_FN2),
+ PINMUX_DATA(PORT132_MSIOF2_SS2_MARK, PORT132_FN3),
+ PINMUX_DATA(VIO_D3_MARK, PORT133_FN1),
+ PINMUX_DATA(PORT133_KEYOUT5_MARK, PORT133_FN2),
+ PINMUX_DATA(PORT133_MSIOF2_TSYNC_MARK, PORT133_FN3),
+ PINMUX_DATA(VIO_D4_MARK, PORT134_FN1),
+ PINMUX_DATA(PORT134_KEYIN0_MARK, PORT134_FN2),
+ PINMUX_DATA(PORT134_MSIOF2_TXD_MARK, PORT134_FN3),
+ PINMUX_DATA(VIO_D5_MARK, PORT135_FN1),
+ PINMUX_DATA(PORT135_KEYIN1_MARK, PORT135_FN2),
+ PINMUX_DATA(PORT135_MSIOF2_TSCK_MARK, PORT135_FN3),
+ PINMUX_DATA(VIO_D6_MARK, PORT136_FN1),
+ PINMUX_DATA(PORT136_KEYIN2_MARK, PORT136_FN2),
+ PINMUX_DATA(VIO_D7_MARK, PORT137_FN1),
+ PINMUX_DATA(PORT137_KEYIN3_MARK, PORT137_FN2),
+ PINMUX_DATA(VIO_D8_MARK, PORT138_FN1),
+ PINMUX_DATA(M9_SLCD_A01_MARK, PORT138_FN2),
+ PINMUX_DATA(PORT138_FSIAOMC_MARK, PORT138_FN3),
+ PINMUX_DATA(VIO_D9_MARK, PORT139_FN1),
+ PINMUX_DATA(M10_SLCD_CK1_MARK, PORT139_FN2),
+ PINMUX_DATA(PORT139_FSIAOLR_MARK, PORT139_FN3),
+ PINMUX_DATA(VIO_D10_MARK, PORT140_FN1),
+ PINMUX_DATA(M11_SLCD_SO1_MARK, PORT140_FN2),
+ PINMUX_DATA(TPU0TO2_MARK, PORT140_FN3),
+ PINMUX_DATA(PORT140_FSIAOBT_MARK, PORT140_FN4),
+ PINMUX_DATA(VIO_D11_MARK, PORT141_FN1),
+ PINMUX_DATA(M12_SLCD_CE1_MARK, PORT141_FN2),
+ PINMUX_DATA(TPU0TO3_MARK, PORT141_FN3),
+ PINMUX_DATA(PORT141_FSIAOSLD_MARK, PORT141_FN4),
+ PINMUX_DATA(VIO_D12_MARK, PORT142_FN1),
+ PINMUX_DATA(M13_BSW_MARK, PORT142_FN2),
+ PINMUX_DATA(PORT142_FSIACK_MARK, PORT142_FN3),
+ PINMUX_DATA(VIO_D13_MARK, PORT143_FN1),
+ PINMUX_DATA(M14_GSW_MARK, PORT143_FN2),
+ PINMUX_DATA(PORT143_FSIAILR_MARK, PORT143_FN3),
+ PINMUX_DATA(VIO_D14_MARK, PORT144_FN1),
+ PINMUX_DATA(M15_RSW_MARK, PORT144_FN2),
+ PINMUX_DATA(PORT144_FSIAIBT_MARK, PORT144_FN3),
+ PINMUX_DATA(VIO_D15_MARK, PORT145_FN1),
+ PINMUX_DATA(TPU1TO3_MARK, PORT145_FN2),
+ PINMUX_DATA(PORT145_FSIAISLD_MARK, PORT145_FN3),
+ PINMUX_DATA(VIO_CLK_MARK, PORT146_FN1),
+ PINMUX_DATA(PORT146_KEYIN4_MARK, PORT146_FN2),
+ PINMUX_DATA(IPORT2_MARK, PORT146_FN3),
+ PINMUX_DATA(VIO_FIELD_MARK, PORT147_FN1),
+ PINMUX_DATA(PORT147_KEYIN5_MARK, PORT147_FN2),
+ PINMUX_DATA(VIO_CKO_MARK, PORT148_FN1),
+ PINMUX_DATA(PORT148_KEYIN6_MARK, PORT148_FN2),
+ PINMUX_DATA(A27_MARK, PORT149_FN1),
+ PINMUX_DATA(RDWR_XWE_MARK, PORT149_FN2),
+ PINMUX_DATA(MFG0_IN1_MARK, PORT149_FN3),
+ PINMUX_DATA(MFG0_IN2_MARK, PORT150_FN1),
+ PINMUX_DATA(TS_SPSYNC3_MARK, PORT151_FN1),
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT151_FN2),
+ PINMUX_DATA(TS_SDAT3_MARK, PORT152_FN1),
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT152_FN2),
+ PINMUX_DATA(TPU1TO2_MARK, PORT153_FN1),
+ PINMUX_DATA(TS_SDEN3_MARK, PORT153_FN2),
+ PINMUX_DATA(PORT153_MSIOF2_SS1_MARK, PORT153_FN3),
+ PINMUX_DATA(SOUT3_MARK, PORT154_FN1),
+ PINMUX_DATA(SCIFA2_TXD1_MARK, PORT154_FN2),
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT154_FN3),
+ PINMUX_DATA(SIN3_MARK, PORT155_FN1),
+ PINMUX_DATA(SCIFA2_RXD1_MARK, PORT155_FN2),
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT155_FN3),
+ PINMUX_DATA(XRTS3_MARK, PORT156_FN1),
+ PINMUX_DATA(SCIFA2_RTS1_MARK, PORT156_FN2),
+ PINMUX_DATA(PORT156_MSIOF2_SS2_MARK, PORT156_FN3),
+ PINMUX_DATA(XCTS3_MARK, PORT157_FN1),
+ PINMUX_DATA(SCIFA2_CTS1_MARK, PORT157_FN2),
+ PINMUX_DATA(PORT157_MSIOF2_RXD_MARK, PORT157_FN3),
+
+ /* 55-4 (FN) */
+ PINMUX_DATA(DINT_MARK, PORT158_FN1),
+ PINMUX_DATA(SCIFA2_SCK1_MARK, PORT158_FN2),
+ PINMUX_DATA(TS_SCK3_MARK, PORT158_FN3),
+ PINMUX_DATA(PORT159_SCIFB_SCK_MARK, PORT159_FN1),
+ PINMUX_DATA(PORT159_SCIFA5_SCK_MARK, PORT159_FN2),
+ PINMUX_DATA(NMI_MARK, PORT159_FN3),
+ PINMUX_DATA(PORT160_SCIFB_TXD_MARK, PORT160_FN1),
+ PINMUX_DATA(PORT160_SCIFA5_TXD_MARK, PORT160_FN2),
+ PINMUX_DATA(SOUT0_MARK, PORT160_FN3),
+ PINMUX_DATA(PORT161_SCIFB_CTS_MARK, PORT161_FN1),
+ PINMUX_DATA(PORT161_SCIFA5_CTS_MARK, PORT161_FN2),
+ PINMUX_DATA(XCTS0_MARK, PORT161_FN3),
+ PINMUX_DATA(MFG3_IN2_MARK, PORT161_FN4),
+ PINMUX_DATA(PORT162_SCIFB_RXD_MARK, PORT162_FN1),
+ PINMUX_DATA(PORT162_SCIFA5_RXD_MARK, PORT162_FN2),
+ PINMUX_DATA(SIN0_MARK, PORT162_FN3),
+ PINMUX_DATA(MFG3_IN1_MARK, PORT162_FN4),
+ PINMUX_DATA(PORT163_SCIFB_RTS_MARK, PORT163_FN1),
+ PINMUX_DATA(PORT163_SCIFA5_RTS_MARK, PORT163_FN2),
+ PINMUX_DATA(XRTS0_MARK, PORT163_FN3),
+ PINMUX_DATA(MFG3_OUT1_MARK, PORT163_FN4),
+ PINMUX_DATA(TPU3TO0_MARK, PORT163_FN5),
+ PINMUX_DATA(LCDD0_MARK, PORT192_FN1),
+ PINMUX_DATA(PORT192_KEYOUT0_MARK, PORT192_FN2),
+ PINMUX_DATA(EXT_CKI_MARK, PORT192_FN3),
+ PINMUX_DATA(LCDD1_MARK, PORT193_FN1),
+ PINMUX_DATA(PORT193_KEYOUT1_MARK, PORT193_FN2),
+ PINMUX_DATA(PORT193_SCIFA5_CTS_MARK, PORT193_FN3),
+ PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT193_FN4),
+ PINMUX_DATA(LCDD2_MARK, PORT194_FN1),
+ PINMUX_DATA(PORT194_KEYOUT2_MARK, PORT194_FN2),
+ PINMUX_DATA(PORT194_SCIFA5_RTS_MARK, PORT194_FN3),
+ PINMUX_DATA(BBIF2_TSCK1_MARK, PORT194_FN4),
+ PINMUX_DATA(LCDD3_MARK, PORT195_FN1),
+ PINMUX_DATA(PORT195_KEYOUT3_MARK, PORT195_FN2),
+ PINMUX_DATA(PORT195_SCIFA5_RXD_MARK, PORT195_FN3),
+ PINMUX_DATA(BBIF2_TXD1_MARK, PORT195_FN4),
+ PINMUX_DATA(LCDD4_MARK, PORT196_FN1),
+ PINMUX_DATA(PORT196_KEYOUT4_MARK, PORT196_FN2),
+ PINMUX_DATA(PORT196_SCIFA5_TXD_MARK, PORT196_FN3),
+ PINMUX_DATA(LCDD5_MARK, PORT197_FN1),
+ PINMUX_DATA(PORT197_KEYOUT5_MARK, PORT197_FN2),
+ PINMUX_DATA(PORT197_SCIFA5_SCK_MARK, PORT197_FN3),
+ PINMUX_DATA(MFG2_OUT2_MARK, PORT197_FN4),
+ PINMUX_DATA(LCDD6_MARK, PORT198_FN1),
+ PINMUX_DATA(LCDD7_MARK, PORT199_FN1),
+ PINMUX_DATA(TPU4TO1_MARK, PORT199_FN2),
+ PINMUX_DATA(MFG4_OUT2_MARK, PORT199_FN3),
+ PINMUX_DATA(LCDD8_MARK, PORT200_FN1),
+ PINMUX_DATA(PORT200_KEYIN0_MARK, PORT200_FN2),
+ PINMUX_DATA(VIO_DR0_MARK, PORT200_FN3),
+ PINMUX_DATA(D16_MARK, PORT200_FN4),
+ PINMUX_DATA(LCDD9_MARK, PORT201_FN1),
+ PINMUX_DATA(PORT201_KEYIN1_MARK, PORT201_FN2),
+ PINMUX_DATA(VIO_DR1_MARK, PORT201_FN3),
+ PINMUX_DATA(D17_MARK, PORT201_FN4),
+ PINMUX_DATA(LCDD10_MARK, PORT202_FN1),
+ PINMUX_DATA(PORT202_KEYIN2_MARK, PORT202_FN2),
+ PINMUX_DATA(VIO_DR2_MARK, PORT202_FN3),
+ PINMUX_DATA(D18_MARK, PORT202_FN4),
+ PINMUX_DATA(LCDD11_MARK, PORT203_FN1),
+ PINMUX_DATA(PORT203_KEYIN3_MARK, PORT203_FN2),
+ PINMUX_DATA(VIO_DR3_MARK, PORT203_FN3),
+ PINMUX_DATA(D19_MARK, PORT203_FN4),
+ PINMUX_DATA(LCDD12_MARK, PORT204_FN1),
+ PINMUX_DATA(PORT204_KEYIN4_MARK, PORT204_FN2),
+ PINMUX_DATA(VIO_DR4_MARK, PORT204_FN3),
+ PINMUX_DATA(D20_MARK, PORT204_FN4),
+ PINMUX_DATA(LCDD13_MARK, PORT205_FN1),
+ PINMUX_DATA(PORT205_KEYIN5_MARK, PORT205_FN2),
+ PINMUX_DATA(VIO_DR5_MARK, PORT205_FN3),
+ PINMUX_DATA(D21_MARK, PORT205_FN4),
+ PINMUX_DATA(LCDD14_MARK, PORT206_FN1),
+ PINMUX_DATA(PORT206_KEYIN6_MARK, PORT206_FN2),
+ PINMUX_DATA(VIO_DR6_MARK, PORT206_FN3),
+ PINMUX_DATA(D22_MARK, PORT206_FN4),
+ PINMUX_DATA(LCDD15_MARK, PORT207_FN1),
+ PINMUX_DATA(PORT207_MSIOF0L_SS1_MARK, PORT207_FN2),
+ PINMUX_DATA(PORT207_KEYOUT0_MARK, PORT207_FN3),
+ PINMUX_DATA(VIO_DR7_MARK, PORT207_FN4),
+ PINMUX_DATA(D23_MARK, PORT207_FN5),
+ PINMUX_DATA(LCDD16_MARK, PORT208_FN1),
+ PINMUX_DATA(PORT208_MSIOF0L_SS2_MARK, PORT208_FN2),
+ PINMUX_DATA(PORT208_KEYOUT1_MARK, PORT208_FN3),
+ PINMUX_DATA(VIO_VDR_MARK, PORT208_FN4),
+ PINMUX_DATA(D24_MARK, PORT208_FN5),
+ PINMUX_DATA(LCDD17_MARK, PORT209_FN1),
+ PINMUX_DATA(PORT209_KEYOUT2_MARK, PORT209_FN2),
+ PINMUX_DATA(VIO_HDR_MARK, PORT209_FN3),
+ PINMUX_DATA(D25_MARK, PORT209_FN4),
+ PINMUX_DATA(LCDD18_MARK, PORT210_FN1),
+ PINMUX_DATA(DREQ2_MARK, PORT210_FN2),
+ PINMUX_DATA(PORT210_MSIOF0L_SS1_MARK, PORT210_FN3),
+ PINMUX_DATA(D26_MARK, PORT210_FN4),
+ PINMUX_DATA(LCDD19_MARK, PORT211_FN1),
+ PINMUX_DATA(PORT211_MSIOF0L_SS2_MARK, PORT211_FN2),
+ PINMUX_DATA(D27_MARK, PORT211_FN3),
+ PINMUX_DATA(LCDD20_MARK, PORT212_FN1),
+ PINMUX_DATA(TS_SPSYNC1_MARK, PORT212_FN2),
+ PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT212_FN3),
+ PINMUX_DATA(D28_MARK, PORT212_FN4),
+ PINMUX_DATA(LCDD21_MARK, PORT213_FN1),
+ PINMUX_DATA(TS_SDAT1_MARK, PORT213_FN2),
+ PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT213_FN3),
+ PINMUX_DATA(D29_MARK, PORT213_FN4),
+ PINMUX_DATA(LCDD22_MARK, PORT214_FN1),
+ PINMUX_DATA(TS_SDEN1_MARK, PORT214_FN2),
+ PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT214_FN3),
+ PINMUX_DATA(D30_MARK, PORT214_FN4),
+ PINMUX_DATA(LCDD23_MARK, PORT215_FN1),
+ PINMUX_DATA(TS_SCK1_MARK, PORT215_FN2),
+ PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT215_FN3),
+ PINMUX_DATA(D31_MARK, PORT215_FN4),
+ PINMUX_DATA(LCDDCK_MARK, PORT216_FN1),
+ PINMUX_DATA(LCDWR_MARK, PORT216_FN2),
+ PINMUX_DATA(PORT216_KEYOUT3_MARK, PORT216_FN3),
+ PINMUX_DATA(VIO_CLKR_MARK, PORT216_FN4),
+ PINMUX_DATA(LCDRD_MARK, PORT217_FN1),
+ PINMUX_DATA(DACK2_MARK, PORT217_FN2),
+ PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT217_FN3),
+ PINMUX_DATA(LCDHSYN_MARK, PORT218_FN1),
+ PINMUX_DATA(LCDCS_MARK, PORT218_FN2),
+ PINMUX_DATA(LCDCS2_MARK, PORT218_FN3),
+ PINMUX_DATA(DACK3_MARK, PORT218_FN4),
+ PINMUX_DATA(PORT218_VIO_CKOR_MARK, PORT218_FN5),
+ PINMUX_DATA(PORT218_KEYOUT4_MARK, PORT218_FN6),
+ PINMUX_DATA(LCDDISP_MARK, PORT219_FN1),
+ PINMUX_DATA(LCDRS_MARK, PORT219_FN2),
+ PINMUX_DATA(DREQ3_MARK, PORT219_FN3),
+ PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT219_FN4),
+ PINMUX_DATA(LCDVSYN_MARK, PORT220_FN1),
+ PINMUX_DATA(LCDVSYN2_MARK, PORT220_FN2),
+ PINMUX_DATA(PORT220_KEYOUT5_MARK, PORT220_FN3),
+ PINMUX_DATA(LCDLCLK_MARK, PORT221_FN1),
+ PINMUX_DATA(DREQ1_MARK, PORT221_FN2),
+ PINMUX_DATA(PWEN_MARK, PORT221_FN3),
+ PINMUX_DATA(MSIOF0L_RXD_MARK, PORT221_FN4),
+ PINMUX_DATA(LCDDON_MARK, PORT222_FN1),
+ PINMUX_DATA(LCDDON2_MARK, PORT222_FN2),
+ PINMUX_DATA(DACK1_MARK, PORT222_FN3),
+ PINMUX_DATA(OVCN_MARK, PORT222_FN4),
+ PINMUX_DATA(MSIOF0L_TXD_MARK, PORT222_FN5),
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT225_FN1),
+ PINMUX_DATA(OVCN2_MARK, PORT225_FN2),
+ PINMUX_DATA(EXTLP_MARK, PORT226_FN1),
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT226_FN2),
+ PINMUX_DATA(USBTERM_MARK, PORT226_FN3),
+ PINMUX_DATA(PORT226_VIO_CKO2_MARK, PORT226_FN4),
+ PINMUX_DATA(SCIFA1_RTS_MARK, PORT227_FN1),
+ PINMUX_DATA(IDIN_MARK, PORT227_FN2),
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT228_FN1),
+ PINMUX_DATA(SCIFA1_CTS_MARK, PORT229_FN1),
+ PINMUX_DATA(MFG1_IN1_MARK, PORT229_FN2),
+ PINMUX_DATA(MSIOF1_TXD_MARK, PORT230_FN1),
+ PINMUX_DATA(SCIFA2_TXD2_MARK, PORT230_FN2),
+ PINMUX_DATA(PORT230_FSIAOMC_MARK, PORT230_FN3),
+ PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT231_FN1),
+ PINMUX_DATA(SCIFA2_CTS2_MARK, PORT231_FN2),
+ PINMUX_DATA(PORT231_FSIAOLR_MARK, PORT231_FN3),
+ PINMUX_DATA(MSIOF1_TSCK_MARK, PORT232_FN1),
+ PINMUX_DATA(SCIFA2_SCK2_MARK, PORT232_FN2),
+ PINMUX_DATA(PORT232_FSIAOBT_MARK, PORT232_FN3),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PORT233_FN1),
+ PINMUX_DATA(SCIFA2_RXD2_MARK, PORT233_FN2),
+ PINMUX_DATA(GPS_VCOTRIG_MARK, PORT233_FN3),
+ PINMUX_DATA(PORT233_FSIACK_MARK, PORT233_FN4),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT234_FN1),
+ PINMUX_DATA(SCIFA2_RTS2_MARK, PORT234_FN2),
+ PINMUX_DATA(PORT234_FSIAOSLD_MARK, PORT234_FN3),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT235_FN1),
+ PINMUX_DATA(OPORT0_MARK, PORT235_FN2),
+ PINMUX_DATA(MFG1_IN2_MARK, PORT235_FN3),
+ PINMUX_DATA(PORT235_FSIAILR_MARK, PORT235_FN4),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT236_FN1),
+ PINMUX_DATA(I2C_SDA2_MARK, PORT236_FN2),
+ PINMUX_DATA(PORT236_FSIAIBT_MARK, PORT236_FN3),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT237_FN1),
+ PINMUX_DATA(I2C_SCL2_MARK, PORT237_FN2),
+ PINMUX_DATA(PORT237_FSIAISLD_MARK, PORT237_FN3),
+ PINMUX_DATA(MSIOF1_SS1_MARK, PORT238_FN1),
+ PINMUX_DATA(EDBGREQ3_MARK, PORT238_FN2),
+
+ /* 55-5 (FN) */
+ PINMUX_DATA(MSIOF1_SS2_MARK, PORT239_FN1),
+ PINMUX_DATA(SCIFA6_TXD_MARK, PORT240_FN1),
+ PINMUX_DATA(PORT241_IRDA_OUT_MARK, PORT241_FN1),
+ PINMUX_DATA(PORT241_IROUT_MARK, PORT241_FN2),
+ PINMUX_DATA(MFG4_OUT1_MARK, PORT241_FN3),
+ PINMUX_DATA(TPU4TO0_MARK, PORT241_FN4),
+ PINMUX_DATA(PORT242_IRDA_IN_MARK, PORT242_FN1),
+ PINMUX_DATA(MFG4_IN2_MARK, PORT242_FN2),
+ PINMUX_DATA(PORT243_IRDA_FIRSEL_MARK, PORT243_FN1),
+ PINMUX_DATA(PORT243_VIO_CKO2_MARK, PORT243_FN2),
+ PINMUX_DATA(PORT244_SCIFA5_CTS_MARK, PORT244_FN1),
+ PINMUX_DATA(MFG2_IN1_MARK, PORT244_FN2),
+ PINMUX_DATA(PORT244_SCIFB_CTS_MARK, PORT244_FN3),
+ PINMUX_DATA(PORT245_SCIFA5_RTS_MARK, PORT245_FN1),
+ PINMUX_DATA(MFG2_IN2_MARK, PORT245_FN2),
+ PINMUX_DATA(PORT245_SCIFB_RTS_MARK, PORT245_FN3),
+ PINMUX_DATA(PORT246_SCIFA5_RXD_MARK, PORT246_FN1),
+ PINMUX_DATA(MFG1_OUT1_MARK, PORT246_FN2),
+ PINMUX_DATA(PORT246_SCIFB_RXD_MARK, PORT246_FN3),
+ PINMUX_DATA(TPU1TO0_MARK, PORT246_FN4),
+ PINMUX_DATA(PORT247_SCIFA5_TXD_MARK, PORT247_FN1),
+ PINMUX_DATA(MFG3_OUT2_MARK, PORT247_FN2),
+ PINMUX_DATA(PORT247_SCIFB_TXD_MARK, PORT247_FN3),
+ PINMUX_DATA(TPU3TO1_MARK, PORT247_FN4),
+ PINMUX_DATA(PORT248_SCIFA5_SCK_MARK, PORT248_FN1),
+ PINMUX_DATA(MFG2_OUT1_MARK, PORT248_FN2),
+ PINMUX_DATA(PORT248_SCIFB_SCK_MARK, PORT248_FN3),
+ PINMUX_DATA(TPU2TO0_MARK, PORT248_FN4),
+ PINMUX_DATA(PORT249_IROUT_MARK, PORT249_FN1),
+ PINMUX_DATA(MFG4_IN1_MARK, PORT249_FN2),
+ PINMUX_DATA(SDHICLK0_MARK, PORT250_FN1),
+ PINMUX_DATA(TCK2_SWCLK_MC0_MARK, PORT250_FN2),
+ PINMUX_DATA(SDHICD0_MARK, PORT251_FN1),
+ PINMUX_DATA(SDHID0_0_MARK, PORT252_FN1),
+ PINMUX_DATA(TMS2_SWDIO_MC0_MARK, PORT252_FN2),
+ PINMUX_DATA(SDHID0_1_MARK, PORT253_FN1),
+ PINMUX_DATA(TDO2_SWO0_MC0_MARK, PORT253_FN2),
+ PINMUX_DATA(SDHID0_2_MARK, PORT254_FN1),
+ PINMUX_DATA(TDI2_MARK, PORT254_FN2),
+ PINMUX_DATA(SDHID0_3_MARK, PORT255_FN1),
+ PINMUX_DATA(RTCK2_SWO1_MC0_MARK, PORT255_FN2),
+ PINMUX_DATA(SDHICMD0_MARK, PORT256_FN1),
+ PINMUX_DATA(TRST2_MARK, PORT256_FN2),
+ PINMUX_DATA(SDHIWP0_MARK, PORT257_FN1),
+ PINMUX_DATA(EDBGREQ2_MARK, PORT257_FN2),
+ PINMUX_DATA(SDHICLK1_MARK, PORT258_FN1),
+ PINMUX_DATA(TCK3_SWCLK_MC1_MARK, PORT258_FN2),
+ PINMUX_DATA(SDHID1_0_MARK, PORT259_FN1),
+ PINMUX_DATA(M11_SLCD_SO2_MARK, PORT259_FN2),
+ PINMUX_DATA(TS_SPSYNC2_MARK, PORT259_FN3),
+ PINMUX_DATA(TMS3_SWDIO_MC1_MARK, PORT259_FN4),
+ PINMUX_DATA(SDHID1_1_MARK, PORT260_FN1),
+ PINMUX_DATA(M9_SLCD_A02_MARK, PORT260_FN2),
+ PINMUX_DATA(TS_SDAT2_MARK, PORT260_FN3),
+ PINMUX_DATA(TDO3_SWO0_MC1_MARK, PORT260_FN4),
+ PINMUX_DATA(SDHID1_2_MARK, PORT261_FN1),
+ PINMUX_DATA(M10_SLCD_CK2_MARK, PORT261_FN2),
+ PINMUX_DATA(TS_SDEN2_MARK, PORT261_FN3),
+ PINMUX_DATA(TDI3_MARK, PORT261_FN4),
+ PINMUX_DATA(SDHID1_3_MARK, PORT262_FN1),
+ PINMUX_DATA(M12_SLCD_CE2_MARK, PORT262_FN2),
+ PINMUX_DATA(TS_SCK2_MARK, PORT262_FN3),
+ PINMUX_DATA(RTCK3_SWO1_MC1_MARK, PORT262_FN4),
+ PINMUX_DATA(SDHICMD1_MARK, PORT263_FN1),
+ PINMUX_DATA(TRST3_MARK, PORT263_FN2),
+ PINMUX_DATA(RESETOUTS_MARK, PORT264_FN1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_265() _265(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* 55-1 -> 55-5 (GPIO) */
+ GPIO_PORT_265(),
+
+ /* Special Pull-up / Pull-down Functions */
+ GPIO_FN(PORT66_KEYIN0_PU), GPIO_FN(PORT67_KEYIN1_PU),
+ GPIO_FN(PORT68_KEYIN2_PU), GPIO_FN(PORT69_KEYIN3_PU),
+ GPIO_FN(PORT70_KEYIN4_PU), GPIO_FN(PORT71_KEYIN5_PU),
+ GPIO_FN(PORT72_KEYIN6_PU),
+
+ /* 55-1 (FN) */
+ GPIO_FN(VBUS_0),
+ GPIO_FN(CPORT0),
+ GPIO_FN(CPORT1),
+ GPIO_FN(CPORT2),
+ GPIO_FN(CPORT3),
+ GPIO_FN(CPORT4),
+ GPIO_FN(CPORT5),
+ GPIO_FN(CPORT6),
+ GPIO_FN(CPORT7),
+ GPIO_FN(CPORT8),
+ GPIO_FN(CPORT9),
+ GPIO_FN(CPORT10),
+ GPIO_FN(CPORT11), GPIO_FN(SIN2),
+ GPIO_FN(CPORT12), GPIO_FN(XCTS2),
+ GPIO_FN(CPORT13), GPIO_FN(RFSPO4),
+ GPIO_FN(CPORT14), GPIO_FN(RFSPO5),
+ GPIO_FN(CPORT15), GPIO_FN(SCIFA0_SCK), GPIO_FN(GPS_AGC2),
+ GPIO_FN(CPORT16), GPIO_FN(SCIFA0_TXD), GPIO_FN(GPS_AGC3),
+ GPIO_FN(CPORT17_IC_OE), GPIO_FN(SOUT2),
+ GPIO_FN(CPORT18), GPIO_FN(XRTS2), GPIO_FN(PORT19_VIO_CKO2),
+ GPIO_FN(CPORT19_MPORT1),
+ GPIO_FN(CPORT20), GPIO_FN(RFSPO6),
+ GPIO_FN(CPORT21), GPIO_FN(STATUS0),
+ GPIO_FN(CPORT22), GPIO_FN(STATUS1),
+ GPIO_FN(CPORT23), GPIO_FN(STATUS2), GPIO_FN(RFSPO7),
+ GPIO_FN(B_SYNLD1),
+ GPIO_FN(B_SYNLD2), GPIO_FN(SYSENMSK),
+ GPIO_FN(XMAINPS),
+ GPIO_FN(XDIVPS),
+ GPIO_FN(XIDRST),
+ GPIO_FN(IDCLK), GPIO_FN(IC_DP),
+ GPIO_FN(IDIO), GPIO_FN(IC_DM),
+ GPIO_FN(SOUT1), GPIO_FN(SCIFA4_TXD), GPIO_FN(M02_BERDAT),
+ GPIO_FN(SIN1), GPIO_FN(SCIFA4_RXD), GPIO_FN(XWUP),
+ GPIO_FN(XRTS1), GPIO_FN(SCIFA4_RTS), GPIO_FN(M03_BERCLK),
+ GPIO_FN(XCTS1), GPIO_FN(SCIFA4_CTS),
+ GPIO_FN(PCMCLKO),
+ GPIO_FN(SYNC8KO),
+
+ /* 55-2 (FN) */
+ GPIO_FN(DNPCM_A),
+ GPIO_FN(UPPCM_A),
+ GPIO_FN(VACK),
+ GPIO_FN(XTALB1L),
+ GPIO_FN(GPS_AGC1), GPIO_FN(SCIFA0_RTS),
+ GPIO_FN(GPS_AGC4), GPIO_FN(SCIFA0_RXD),
+ GPIO_FN(GPS_PWRDOWN), GPIO_FN(SCIFA0_CTS),
+ GPIO_FN(GPS_IM),
+ GPIO_FN(GPS_IS),
+ GPIO_FN(GPS_QM),
+ GPIO_FN(GPS_QS),
+ GPIO_FN(FMSOCK), GPIO_FN(PORT49_IRDA_OUT), GPIO_FN(PORT49_IROUT),
+ GPIO_FN(FMSOOLR), GPIO_FN(BBIF2_TSYNC2), GPIO_FN(TPU2TO2),
+ GPIO_FN(IPORT3), GPIO_FN(FMSIOLR),
+ GPIO_FN(FMSOOBT), GPIO_FN(BBIF2_TSCK2), GPIO_FN(TPU2TO3),
+ GPIO_FN(OPORT1), GPIO_FN(FMSIOBT),
+ GPIO_FN(FMSOSLD), GPIO_FN(BBIF2_TXD2), GPIO_FN(OPORT2),
+ GPIO_FN(FMSOILR), GPIO_FN(PORT53_IRDA_IN), GPIO_FN(TPU3TO3),
+ GPIO_FN(OPORT3), GPIO_FN(FMSIILR),
+ GPIO_FN(FMSOIBT), GPIO_FN(PORT54_IRDA_FIRSEL), GPIO_FN(TPU3TO2),
+ GPIO_FN(FMSIIBT),
+ GPIO_FN(FMSISLD), GPIO_FN(MFG0_OUT1), GPIO_FN(TPU0TO0),
+ GPIO_FN(A0_EA0), GPIO_FN(BS),
+ GPIO_FN(A12_EA12), GPIO_FN(PORT58_VIO_CKOR), GPIO_FN(TPU4TO2),
+ GPIO_FN(A13_EA13), GPIO_FN(PORT59_IROUT), GPIO_FN(MFG0_OUT2),
+ GPIO_FN(TPU0TO1),
+ GPIO_FN(A14_EA14), GPIO_FN(PORT60_KEYOUT5),
+ GPIO_FN(A15_EA15), GPIO_FN(PORT61_KEYOUT4),
+ GPIO_FN(A16_EA16), GPIO_FN(PORT62_KEYOUT3), GPIO_FN(MSIOF0_SS1),
+ GPIO_FN(A17_EA17), GPIO_FN(PORT63_KEYOUT2), GPIO_FN(MSIOF0_TSYNC),
+ GPIO_FN(A18_EA18), GPIO_FN(PORT64_KEYOUT1), GPIO_FN(MSIOF0_TSCK),
+ GPIO_FN(A19_EA19), GPIO_FN(PORT65_KEYOUT0), GPIO_FN(MSIOF0_TXD),
+ GPIO_FN(A20_EA20), GPIO_FN(PORT66_KEYIN0), GPIO_FN(MSIOF0_RSCK),
+ GPIO_FN(A21_EA21), GPIO_FN(PORT67_KEYIN1), GPIO_FN(MSIOF0_RSYNC),
+ GPIO_FN(A22_EA22), GPIO_FN(PORT68_KEYIN2), GPIO_FN(MSIOF0_MCK0),
+ GPIO_FN(A23_EA23), GPIO_FN(PORT69_KEYIN3), GPIO_FN(MSIOF0_MCK1),
+ GPIO_FN(A24_EA24), GPIO_FN(PORT70_KEYIN4), GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(A25_EA25), GPIO_FN(PORT71_KEYIN5), GPIO_FN(MSIOF0_SS2),
+ GPIO_FN(A26), GPIO_FN(PORT72_KEYIN6),
+ GPIO_FN(D0_ED0_NAF0),
+ GPIO_FN(D1_ED1_NAF1),
+ GPIO_FN(D2_ED2_NAF2),
+ GPIO_FN(D3_ED3_NAF3),
+ GPIO_FN(D4_ED4_NAF4),
+ GPIO_FN(D5_ED5_NAF5),
+ GPIO_FN(D6_ED6_NAF6),
+ GPIO_FN(D7_ED7_NAF7),
+ GPIO_FN(D8_ED8_NAF8),
+ GPIO_FN(D9_ED9_NAF9),
+ GPIO_FN(D10_ED10_NAF10),
+ GPIO_FN(D11_ED11_NAF11),
+ GPIO_FN(D12_ED12_NAF12),
+ GPIO_FN(D13_ED13_NAF13),
+ GPIO_FN(D14_ED14_NAF14),
+ GPIO_FN(D15_ED15_NAF15),
+ GPIO_FN(CS4),
+ GPIO_FN(CS5A), GPIO_FN(FMSICK),
+
+ /* 55-3 (FN) */
+ GPIO_FN(CS5B), GPIO_FN(FCE1),
+ GPIO_FN(CS6B), GPIO_FN(XCS2), GPIO_FN(CS6A), GPIO_FN(DACK0),
+ GPIO_FN(FCE0),
+ GPIO_FN(WAIT), GPIO_FN(DREQ0),
+ GPIO_FN(RD_XRD),
+ GPIO_FN(WE0_XWR0_FWE),
+ GPIO_FN(WE1_XWR1),
+ GPIO_FN(FRB),
+ GPIO_FN(CKO),
+ GPIO_FN(NBRSTOUT),
+ GPIO_FN(NBRST),
+ GPIO_FN(GPS_EPPSIN),
+ GPIO_FN(LATCHPULSE),
+ GPIO_FN(LTESIGNAL),
+ GPIO_FN(LEGACYSTATE),
+ GPIO_FN(TCKON),
+ GPIO_FN(VIO_VD), GPIO_FN(PORT128_KEYOUT0), GPIO_FN(IPORT0),
+ GPIO_FN(VIO_HD), GPIO_FN(PORT129_KEYOUT1), GPIO_FN(IPORT1),
+ GPIO_FN(VIO_D0), GPIO_FN(PORT130_KEYOUT2), GPIO_FN(PORT130_MSIOF2_RXD),
+ GPIO_FN(VIO_D1), GPIO_FN(PORT131_KEYOUT3), GPIO_FN(PORT131_MSIOF2_SS1),
+ GPIO_FN(VIO_D2), GPIO_FN(PORT132_KEYOUT4), GPIO_FN(PORT132_MSIOF2_SS2),
+ GPIO_FN(VIO_D3), GPIO_FN(PORT133_KEYOUT5),
+ GPIO_FN(PORT133_MSIOF2_TSYNC),
+ GPIO_FN(VIO_D4), GPIO_FN(PORT134_KEYIN0), GPIO_FN(PORT134_MSIOF2_TXD),
+ GPIO_FN(VIO_D5), GPIO_FN(PORT135_KEYIN1), GPIO_FN(PORT135_MSIOF2_TSCK),
+ GPIO_FN(VIO_D6), GPIO_FN(PORT136_KEYIN2),
+ GPIO_FN(VIO_D7), GPIO_FN(PORT137_KEYIN3),
+ GPIO_FN(VIO_D8), GPIO_FN(M9_SLCD_A01), GPIO_FN(PORT138_FSIAOMC),
+ GPIO_FN(VIO_D9), GPIO_FN(M10_SLCD_CK1), GPIO_FN(PORT139_FSIAOLR),
+ GPIO_FN(VIO_D10), GPIO_FN(M11_SLCD_SO1), GPIO_FN(TPU0TO2),
+ GPIO_FN(PORT140_FSIAOBT),
+ GPIO_FN(VIO_D11), GPIO_FN(M12_SLCD_CE1), GPIO_FN(TPU0TO3),
+ GPIO_FN(PORT141_FSIAOSLD),
+ GPIO_FN(VIO_D12), GPIO_FN(M13_BSW), GPIO_FN(PORT142_FSIACK),
+ GPIO_FN(VIO_D13), GPIO_FN(M14_GSW), GPIO_FN(PORT143_FSIAILR),
+ GPIO_FN(VIO_D14), GPIO_FN(M15_RSW), GPIO_FN(PORT144_FSIAIBT),
+ GPIO_FN(VIO_D15), GPIO_FN(TPU1TO3), GPIO_FN(PORT145_FSIAISLD),
+ GPIO_FN(VIO_CLK), GPIO_FN(PORT146_KEYIN4), GPIO_FN(IPORT2),
+ GPIO_FN(VIO_FIELD), GPIO_FN(PORT147_KEYIN5),
+ GPIO_FN(VIO_CKO), GPIO_FN(PORT148_KEYIN6),
+ GPIO_FN(A27), GPIO_FN(RDWR_XWE), GPIO_FN(MFG0_IN1),
+ GPIO_FN(MFG0_IN2),
+ GPIO_FN(TS_SPSYNC3), GPIO_FN(MSIOF2_RSCK),
+ GPIO_FN(TS_SDAT3), GPIO_FN(MSIOF2_RSYNC),
+ GPIO_FN(TPU1TO2), GPIO_FN(TS_SDEN3), GPIO_FN(PORT153_MSIOF2_SS1),
+ GPIO_FN(SOUT3), GPIO_FN(SCIFA2_TXD1), GPIO_FN(MSIOF2_MCK0),
+ GPIO_FN(SIN3), GPIO_FN(SCIFA2_RXD1), GPIO_FN(MSIOF2_MCK1),
+ GPIO_FN(XRTS3), GPIO_FN(SCIFA2_RTS1), GPIO_FN(PORT156_MSIOF2_SS2),
+ GPIO_FN(XCTS3), GPIO_FN(SCIFA2_CTS1), GPIO_FN(PORT157_MSIOF2_RXD),
+
+ /* 55-4 (FN) */
+ GPIO_FN(DINT), GPIO_FN(SCIFA2_SCK1), GPIO_FN(TS_SCK3),
+ GPIO_FN(PORT159_SCIFB_SCK), GPIO_FN(PORT159_SCIFA5_SCK), GPIO_FN(NMI),
+ GPIO_FN(PORT160_SCIFB_TXD), GPIO_FN(PORT160_SCIFA5_TXD), GPIO_FN(SOUT0),
+ GPIO_FN(PORT161_SCIFB_CTS), GPIO_FN(PORT161_SCIFA5_CTS), GPIO_FN(XCTS0),
+ GPIO_FN(MFG3_IN2),
+ GPIO_FN(PORT162_SCIFB_RXD), GPIO_FN(PORT162_SCIFA5_RXD), GPIO_FN(SIN0),
+ GPIO_FN(MFG3_IN1),
+ GPIO_FN(PORT163_SCIFB_RTS), GPIO_FN(PORT163_SCIFA5_RTS), GPIO_FN(XRTS0),
+ GPIO_FN(MFG3_OUT1), GPIO_FN(TPU3TO0),
+ GPIO_FN(LCDD0), GPIO_FN(PORT192_KEYOUT0), GPIO_FN(EXT_CKI),
+ GPIO_FN(LCDD1), GPIO_FN(PORT193_KEYOUT1), GPIO_FN(PORT193_SCIFA5_CTS),
+ GPIO_FN(BBIF2_TSYNC1),
+ GPIO_FN(LCDD2), GPIO_FN(PORT194_KEYOUT2), GPIO_FN(PORT194_SCIFA5_RTS),
+ GPIO_FN(BBIF2_TSCK1),
+ GPIO_FN(LCDD3), GPIO_FN(PORT195_KEYOUT3), GPIO_FN(PORT195_SCIFA5_RXD),
+ GPIO_FN(BBIF2_TXD1),
+ GPIO_FN(LCDD4), GPIO_FN(PORT196_KEYOUT4), GPIO_FN(PORT196_SCIFA5_TXD),
+ GPIO_FN(LCDD5), GPIO_FN(PORT197_KEYOUT5), GPIO_FN(PORT197_SCIFA5_SCK),
+ GPIO_FN(MFG2_OUT2),
+ GPIO_FN(LCDD6),
+ GPIO_FN(LCDD7), GPIO_FN(TPU4TO1), GPIO_FN(MFG4_OUT2),
+ GPIO_FN(LCDD8), GPIO_FN(PORT200_KEYIN0), GPIO_FN(VIO_DR0),
+ GPIO_FN(D16),
+ GPIO_FN(LCDD9), GPIO_FN(PORT201_KEYIN1), GPIO_FN(VIO_DR1),
+ GPIO_FN(D17),
+ GPIO_FN(LCDD10), GPIO_FN(PORT202_KEYIN2), GPIO_FN(VIO_DR2),
+ GPIO_FN(D18),
+ GPIO_FN(LCDD11), GPIO_FN(PORT203_KEYIN3), GPIO_FN(VIO_DR3),
+ GPIO_FN(D19),
+ GPIO_FN(LCDD12), GPIO_FN(PORT204_KEYIN4), GPIO_FN(VIO_DR4),
+ GPIO_FN(D20),
+ GPIO_FN(LCDD13), GPIO_FN(PORT205_KEYIN5), GPIO_FN(VIO_DR5),
+ GPIO_FN(D21),
+ GPIO_FN(LCDD14), GPIO_FN(PORT206_KEYIN6), GPIO_FN(VIO_DR6),
+ GPIO_FN(D22),
+ GPIO_FN(LCDD15), GPIO_FN(PORT207_MSIOF0L_SS1), GPIO_FN(PORT207_KEYOUT0),
+ GPIO_FN(VIO_DR7), GPIO_FN(D23),
+ GPIO_FN(LCDD16), GPIO_FN(PORT208_MSIOF0L_SS2), GPIO_FN(PORT208_KEYOUT1),
+ GPIO_FN(VIO_VDR), GPIO_FN(D24),
+ GPIO_FN(LCDD17), GPIO_FN(PORT209_KEYOUT2), GPIO_FN(VIO_HDR),
+ GPIO_FN(D25),
+ GPIO_FN(LCDD18), GPIO_FN(DREQ2), GPIO_FN(PORT210_MSIOF0L_SS1),
+ GPIO_FN(D26),
+ GPIO_FN(LCDD19), GPIO_FN(PORT211_MSIOF0L_SS2), GPIO_FN(D27),
+ GPIO_FN(LCDD20), GPIO_FN(TS_SPSYNC1), GPIO_FN(MSIOF0L_MCK0),
+ GPIO_FN(D28),
+ GPIO_FN(LCDD21), GPIO_FN(TS_SDAT1), GPIO_FN(MSIOF0L_MCK1),
+ GPIO_FN(D29),
+ GPIO_FN(LCDD22), GPIO_FN(TS_SDEN1), GPIO_FN(MSIOF0L_RSCK),
+ GPIO_FN(D30),
+ GPIO_FN(LCDD23), GPIO_FN(TS_SCK1), GPIO_FN(MSIOF0L_RSYNC),
+ GPIO_FN(D31),
+ GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(PORT216_KEYOUT3),
+ GPIO_FN(VIO_CLKR),
+ GPIO_FN(LCDRD), GPIO_FN(DACK2), GPIO_FN(MSIOF0L_TSYNC),
+ GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDCS2), GPIO_FN(DACK3),
+ GPIO_FN(PORT218_VIO_CKOR), GPIO_FN(PORT218_KEYOUT4),
+ GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(DREQ3), GPIO_FN(MSIOF0L_TSCK),
+ GPIO_FN(LCDVSYN), GPIO_FN(LCDVSYN2), GPIO_FN(PORT220_KEYOUT5),
+ GPIO_FN(LCDLCLK), GPIO_FN(DREQ1), GPIO_FN(PWEN), GPIO_FN(MSIOF0L_RXD),
+ GPIO_FN(LCDDON), GPIO_FN(LCDDON2), GPIO_FN(DACK1), GPIO_FN(OVCN),
+ GPIO_FN(MSIOF0L_TXD),
+ GPIO_FN(SCIFA1_TXD), GPIO_FN(OVCN2),
+ GPIO_FN(EXTLP), GPIO_FN(SCIFA1_SCK), GPIO_FN(USBTERM),
+ GPIO_FN(PORT226_VIO_CKO2),
+ GPIO_FN(SCIFA1_RTS), GPIO_FN(IDIN),
+ GPIO_FN(SCIFA1_RXD),
+ GPIO_FN(SCIFA1_CTS), GPIO_FN(MFG1_IN1),
+ GPIO_FN(MSIOF1_TXD), GPIO_FN(SCIFA2_TXD2), GPIO_FN(PORT230_FSIAOMC),
+ GPIO_FN(MSIOF1_TSYNC), GPIO_FN(SCIFA2_CTS2), GPIO_FN(PORT231_FSIAOLR),
+ GPIO_FN(MSIOF1_TSCK), GPIO_FN(SCIFA2_SCK2), GPIO_FN(PORT232_FSIAOBT),
+ GPIO_FN(MSIOF1_RXD), GPIO_FN(SCIFA2_RXD2), GPIO_FN(GPS_VCOTRIG),
+ GPIO_FN(PORT233_FSIACK),
+ GPIO_FN(MSIOF1_RSCK), GPIO_FN(SCIFA2_RTS2), GPIO_FN(PORT234_FSIAOSLD),
+ GPIO_FN(MSIOF1_RSYNC), GPIO_FN(OPORT0), GPIO_FN(MFG1_IN2),
+ GPIO_FN(PORT235_FSIAILR),
+ GPIO_FN(MSIOF1_MCK0), GPIO_FN(I2C_SDA2), GPIO_FN(PORT236_FSIAIBT),
+ GPIO_FN(MSIOF1_MCK1), GPIO_FN(I2C_SCL2), GPIO_FN(PORT237_FSIAISLD),
+ GPIO_FN(MSIOF1_SS1), GPIO_FN(EDBGREQ3),
+
+ /* 55-5 (FN) */
+ GPIO_FN(MSIOF1_SS2),
+ GPIO_FN(SCIFA6_TXD),
+ GPIO_FN(PORT241_IRDA_OUT), GPIO_FN(PORT241_IROUT), GPIO_FN(MFG4_OUT1),
+ GPIO_FN(TPU4TO0),
+ GPIO_FN(PORT242_IRDA_IN), GPIO_FN(MFG4_IN2),
+ GPIO_FN(PORT243_IRDA_FIRSEL), GPIO_FN(PORT243_VIO_CKO2),
+ GPIO_FN(PORT244_SCIFA5_CTS), GPIO_FN(MFG2_IN1),
+ GPIO_FN(PORT244_SCIFB_CTS),
+ GPIO_FN(PORT245_SCIFA5_RTS), GPIO_FN(MFG2_IN2),
+ GPIO_FN(PORT245_SCIFB_RTS),
+ GPIO_FN(PORT246_SCIFA5_RXD), GPIO_FN(MFG1_OUT1),
+ GPIO_FN(PORT246_SCIFB_RXD), GPIO_FN(TPU1TO0),
+ GPIO_FN(PORT247_SCIFA5_TXD), GPIO_FN(MFG3_OUT2),
+ GPIO_FN(PORT247_SCIFB_TXD), GPIO_FN(TPU3TO1),
+ GPIO_FN(PORT248_SCIFA5_SCK), GPIO_FN(MFG2_OUT1),
+ GPIO_FN(PORT248_SCIFB_SCK), GPIO_FN(TPU2TO0),
+ GPIO_FN(PORT249_IROUT), GPIO_FN(MFG4_IN1),
+ GPIO_FN(SDHICLK0), GPIO_FN(TCK2_SWCLK_MC0),
+ GPIO_FN(SDHICD0),
+ GPIO_FN(SDHID0_0), GPIO_FN(TMS2_SWDIO_MC0),
+ GPIO_FN(SDHID0_1), GPIO_FN(TDO2_SWO0_MC0),
+ GPIO_FN(SDHID0_2), GPIO_FN(TDI2),
+ GPIO_FN(SDHID0_3), GPIO_FN(RTCK2_SWO1_MC0),
+ GPIO_FN(SDHICMD0), GPIO_FN(TRST2),
+ GPIO_FN(SDHIWP0), GPIO_FN(EDBGREQ2),
+ GPIO_FN(SDHICLK1), GPIO_FN(TCK3_SWCLK_MC1),
+ GPIO_FN(SDHID1_0), GPIO_FN(M11_SLCD_SO2), GPIO_FN(TS_SPSYNC2),
+ GPIO_FN(TMS3_SWDIO_MC1),
+ GPIO_FN(SDHID1_1), GPIO_FN(M9_SLCD_A02), GPIO_FN(TS_SDAT2),
+ GPIO_FN(TDO3_SWO0_MC1),
+ GPIO_FN(SDHID1_2), GPIO_FN(M10_SLCD_CK2), GPIO_FN(TS_SDEN2),
+ GPIO_FN(TDI3),
+ GPIO_FN(SDHID1_3), GPIO_FN(M12_SLCD_CE2), GPIO_FN(TS_SCK2),
+ GPIO_FN(RTCK3_SWO1_MC1),
+ GPIO_FN(SDHICMD1), GPIO_FN(TRST3),
+ GPIO_FN(RESETOUTS),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out) \
+ 0, (out), (in), 0, \
+ 0, 0, 0, 0, \
+ 0, 0, (in_pd), 0, \
+ 0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg) \
+ { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU, PORT##nr##_OUT), \
+ PORT##nr##_FN0, PORT##nr##_FN1, \
+ PORT##nr##_FN2, PORT##nr##_FN3, \
+ PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7 } \
+ }
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ PORTCR(0, 0xe6050000), /* PORT0CR */
+ PORTCR(1, 0xe6050001), /* PORT1CR */
+ PORTCR(2, 0xe6050002), /* PORT2CR */
+ PORTCR(3, 0xe6050003), /* PORT3CR */
+ PORTCR(4, 0xe6050004), /* PORT4CR */
+ PORTCR(5, 0xe6050005), /* PORT5CR */
+ PORTCR(6, 0xe6050006), /* PORT6CR */
+ PORTCR(7, 0xe6050007), /* PORT7CR */
+ PORTCR(8, 0xe6050008), /* PORT8CR */
+ PORTCR(9, 0xe6050009), /* PORT9CR */
+
+ PORTCR(10, 0xe605000a), /* PORT10CR */
+ PORTCR(11, 0xe605000b), /* PORT11CR */
+ PORTCR(12, 0xe605000c), /* PORT12CR */
+ PORTCR(13, 0xe605000d), /* PORT13CR */
+ PORTCR(14, 0xe605000e), /* PORT14CR */
+ PORTCR(15, 0xe605000f), /* PORT15CR */
+ PORTCR(16, 0xe6050010), /* PORT16CR */
+ PORTCR(17, 0xe6050011), /* PORT17CR */
+ PORTCR(18, 0xe6050012), /* PORT18CR */
+ PORTCR(19, 0xe6050013), /* PORT19CR */
+
+ PORTCR(20, 0xe6050014), /* PORT20CR */
+ PORTCR(21, 0xe6050015), /* PORT21CR */
+ PORTCR(22, 0xe6050016), /* PORT22CR */
+ PORTCR(23, 0xe6050017), /* PORT23CR */
+ PORTCR(24, 0xe6050018), /* PORT24CR */
+ PORTCR(25, 0xe6050019), /* PORT25CR */
+ PORTCR(26, 0xe605001a), /* PORT26CR */
+ PORTCR(27, 0xe605001b), /* PORT27CR */
+ PORTCR(28, 0xe605001c), /* PORT28CR */
+ PORTCR(29, 0xe605001d), /* PORT29CR */
+
+ PORTCR(30, 0xe605001e), /* PORT30CR */
+ PORTCR(31, 0xe605001f), /* PORT31CR */
+ PORTCR(32, 0xe6050020), /* PORT32CR */
+ PORTCR(33, 0xe6050021), /* PORT33CR */
+ PORTCR(34, 0xe6050022), /* PORT34CR */
+ PORTCR(35, 0xe6050023), /* PORT35CR */
+ PORTCR(36, 0xe6050024), /* PORT36CR */
+ PORTCR(37, 0xe6050025), /* PORT37CR */
+ PORTCR(38, 0xe6050026), /* PORT38CR */
+ PORTCR(39, 0xe6050027), /* PORT39CR */
+
+ PORTCR(40, 0xe6050028), /* PORT40CR */
+ PORTCR(41, 0xe6050029), /* PORT41CR */
+ PORTCR(42, 0xe605002a), /* PORT42CR */
+ PORTCR(43, 0xe605002b), /* PORT43CR */
+ PORTCR(44, 0xe605002c), /* PORT44CR */
+ PORTCR(45, 0xe605002d), /* PORT45CR */
+ PORTCR(46, 0xe605002e), /* PORT46CR */
+ PORTCR(47, 0xe605002f), /* PORT47CR */
+ PORTCR(48, 0xe6050030), /* PORT48CR */
+ PORTCR(49, 0xe6050031), /* PORT49CR */
+
+ PORTCR(50, 0xe6050032), /* PORT50CR */
+ PORTCR(51, 0xe6050033), /* PORT51CR */
+ PORTCR(52, 0xe6050034), /* PORT52CR */
+ PORTCR(53, 0xe6050035), /* PORT53CR */
+ PORTCR(54, 0xe6050036), /* PORT54CR */
+ PORTCR(55, 0xe6050037), /* PORT55CR */
+ PORTCR(56, 0xe6050038), /* PORT56CR */
+ PORTCR(57, 0xe6050039), /* PORT57CR */
+ PORTCR(58, 0xe605003a), /* PORT58CR */
+ PORTCR(59, 0xe605003b), /* PORT59CR */
+
+ PORTCR(60, 0xe605003c), /* PORT60CR */
+ PORTCR(61, 0xe605003d), /* PORT61CR */
+ PORTCR(62, 0xe605003e), /* PORT62CR */
+ PORTCR(63, 0xe605003f), /* PORT63CR */
+ PORTCR(64, 0xe6050040), /* PORT64CR */
+ PORTCR(65, 0xe6050041), /* PORT65CR */
+ PORTCR(66, 0xe6050042), /* PORT66CR */
+ PORTCR(67, 0xe6050043), /* PORT67CR */
+ PORTCR(68, 0xe6050044), /* PORT68CR */
+ PORTCR(69, 0xe6050045), /* PORT69CR */
+
+ PORTCR(70, 0xe6050046), /* PORT70CR */
+ PORTCR(71, 0xe6050047), /* PORT71CR */
+ PORTCR(72, 0xe6050048), /* PORT72CR */
+ PORTCR(73, 0xe6050049), /* PORT73CR */
+ PORTCR(74, 0xe605004a), /* PORT74CR */
+ PORTCR(75, 0xe605004b), /* PORT75CR */
+ PORTCR(76, 0xe605004c), /* PORT76CR */
+ PORTCR(77, 0xe605004d), /* PORT77CR */
+ PORTCR(78, 0xe605004e), /* PORT78CR */
+ PORTCR(79, 0xe605004f), /* PORT79CR */
+
+ PORTCR(80, 0xe6050050), /* PORT80CR */
+ PORTCR(81, 0xe6050051), /* PORT81CR */
+ PORTCR(82, 0xe6050052), /* PORT82CR */
+ PORTCR(83, 0xe6050053), /* PORT83CR */
+ PORTCR(84, 0xe6050054), /* PORT84CR */
+ PORTCR(85, 0xe6050055), /* PORT85CR */
+ PORTCR(86, 0xe6050056), /* PORT86CR */
+ PORTCR(87, 0xe6050057), /* PORT87CR */
+ PORTCR(88, 0xe6050058), /* PORT88CR */
+ PORTCR(89, 0xe6050059), /* PORT89CR */
+
+ PORTCR(90, 0xe605005a), /* PORT90CR */
+ PORTCR(91, 0xe605005b), /* PORT91CR */
+ PORTCR(92, 0xe605005c), /* PORT92CR */
+ PORTCR(93, 0xe605005d), /* PORT93CR */
+ PORTCR(94, 0xe605005e), /* PORT94CR */
+ PORTCR(95, 0xe605005f), /* PORT95CR */
+ PORTCR(96, 0xe6050060), /* PORT96CR */
+ PORTCR(97, 0xe6050061), /* PORT97CR */
+ PORTCR(98, 0xe6050062), /* PORT98CR */
+ PORTCR(99, 0xe6050063), /* PORT99CR */
+
+ PORTCR(100, 0xe6050064), /* PORT100CR */
+ PORTCR(101, 0xe6050065), /* PORT101CR */
+ PORTCR(102, 0xe6050066), /* PORT102CR */
+ PORTCR(103, 0xe6050067), /* PORT103CR */
+ PORTCR(104, 0xe6050068), /* PORT104CR */
+ PORTCR(105, 0xe6050069), /* PORT105CR */
+ PORTCR(106, 0xe605006a), /* PORT106CR */
+ PORTCR(107, 0xe605006b), /* PORT107CR */
+ PORTCR(108, 0xe605006c), /* PORT108CR */
+ PORTCR(109, 0xe605006d), /* PORT109CR */
+
+ PORTCR(110, 0xe605006e), /* PORT110CR */
+ PORTCR(111, 0xe605006f), /* PORT111CR */
+ PORTCR(112, 0xe6050070), /* PORT112CR */
+ PORTCR(113, 0xe6050071), /* PORT113CR */
+ PORTCR(114, 0xe6050072), /* PORT114CR */
+ PORTCR(115, 0xe6050073), /* PORT115CR */
+ PORTCR(116, 0xe6050074), /* PORT116CR */
+ PORTCR(117, 0xe6050075), /* PORT117CR */
+ PORTCR(118, 0xe6050076), /* PORT118CR */
+
+ PORTCR(128, 0xe6051080), /* PORT128CR */
+ PORTCR(129, 0xe6051081), /* PORT129CR */
+
+ PORTCR(130, 0xe6051082), /* PORT130CR */
+ PORTCR(131, 0xe6051083), /* PORT131CR */
+ PORTCR(132, 0xe6051084), /* PORT132CR */
+ PORTCR(133, 0xe6051085), /* PORT133CR */
+ PORTCR(134, 0xe6051086), /* PORT134CR */
+ PORTCR(135, 0xe6051087), /* PORT135CR */
+ PORTCR(136, 0xe6051088), /* PORT136CR */
+ PORTCR(137, 0xe6051089), /* PORT137CR */
+ PORTCR(138, 0xe605108a), /* PORT138CR */
+ PORTCR(139, 0xe605108b), /* PORT139CR */
+
+ PORTCR(140, 0xe605108c), /* PORT140CR */
+ PORTCR(141, 0xe605108d), /* PORT141CR */
+ PORTCR(142, 0xe605108e), /* PORT142CR */
+ PORTCR(143, 0xe605108f), /* PORT143CR */
+ PORTCR(144, 0xe6051090), /* PORT144CR */
+ PORTCR(145, 0xe6051091), /* PORT145CR */
+ PORTCR(146, 0xe6051092), /* PORT146CR */
+ PORTCR(147, 0xe6051093), /* PORT147CR */
+ PORTCR(148, 0xe6051094), /* PORT148CR */
+ PORTCR(149, 0xe6051095), /* PORT149CR */
+
+ PORTCR(150, 0xe6051096), /* PORT150CR */
+ PORTCR(151, 0xe6051097), /* PORT151CR */
+ PORTCR(152, 0xe6051098), /* PORT152CR */
+ PORTCR(153, 0xe6051099), /* PORT153CR */
+ PORTCR(154, 0xe605109a), /* PORT154CR */
+ PORTCR(155, 0xe605109b), /* PORT155CR */
+ PORTCR(156, 0xe605109c), /* PORT156CR */
+ PORTCR(157, 0xe605109d), /* PORT157CR */
+ PORTCR(158, 0xe605109e), /* PORT158CR */
+ PORTCR(159, 0xe605109f), /* PORT159CR */
+
+ PORTCR(160, 0xe60510a0), /* PORT160CR */
+ PORTCR(161, 0xe60510a1), /* PORT161CR */
+ PORTCR(162, 0xe60510a2), /* PORT162CR */
+ PORTCR(163, 0xe60510a3), /* PORT163CR */
+ PORTCR(164, 0xe60510a4), /* PORT164CR */
+
+ PORTCR(192, 0xe60520c0), /* PORT192CR */
+ PORTCR(193, 0xe60520c1), /* PORT193CR */
+ PORTCR(194, 0xe60520c2), /* PORT194CR */
+ PORTCR(195, 0xe60520c3), /* PORT195CR */
+ PORTCR(196, 0xe60520c4), /* PORT196CR */
+ PORTCR(197, 0xe60520c5), /* PORT197CR */
+ PORTCR(198, 0xe60520c6), /* PORT198CR */
+ PORTCR(199, 0xe60520c7), /* PORT199CR */
+
+ PORTCR(200, 0xe60520c8), /* PORT200CR */
+ PORTCR(201, 0xe60520c9), /* PORT201CR */
+ PORTCR(202, 0xe60520ca), /* PORT202CR */
+ PORTCR(203, 0xe60520cb), /* PORT203CR */
+ PORTCR(204, 0xe60520cc), /* PORT204CR */
+ PORTCR(205, 0xe60520cd), /* PORT205CR */
+ PORTCR(206, 0xe60520ce), /* PORT206CR */
+ PORTCR(207, 0xe60520cf), /* PORT207CR */
+ PORTCR(208, 0xe60520d0), /* PORT208CR */
+ PORTCR(209, 0xe60520d1), /* PORT209CR */
+
+ PORTCR(210, 0xe60520d2), /* PORT210CR */
+ PORTCR(211, 0xe60520d3), /* PORT211CR */
+ PORTCR(212, 0xe60520d4), /* PORT212CR */
+ PORTCR(213, 0xe60520d5), /* PORT213CR */
+ PORTCR(214, 0xe60520d6), /* PORT214CR */
+ PORTCR(215, 0xe60520d7), /* PORT215CR */
+ PORTCR(216, 0xe60520d8), /* PORT216CR */
+ PORTCR(217, 0xe60520d9), /* PORT217CR */
+ PORTCR(218, 0xe60520da), /* PORT218CR */
+ PORTCR(219, 0xe60520db), /* PORT219CR */
+
+ PORTCR(220, 0xe60520dc), /* PORT220CR */
+ PORTCR(221, 0xe60520dd), /* PORT221CR */
+ PORTCR(222, 0xe60520de), /* PORT222CR */
+ PORTCR(223, 0xe60520df), /* PORT223CR */
+ PORTCR(224, 0xe60520e0), /* PORT224CR */
+ PORTCR(225, 0xe60520e1), /* PORT225CR */
+ PORTCR(226, 0xe60520e2), /* PORT226CR */
+ PORTCR(227, 0xe60520e3), /* PORT227CR */
+ PORTCR(228, 0xe60520e4), /* PORT228CR */
+ PORTCR(229, 0xe60520e5), /* PORT229CR */
+
+ PORTCR(230, 0xe60520e6), /* PORT230CR */
+ PORTCR(231, 0xe60520e7), /* PORT231CR */
+ PORTCR(232, 0xe60520e8), /* PORT232CR */
+ PORTCR(233, 0xe60520e9), /* PORT233CR */
+ PORTCR(234, 0xe60520ea), /* PORT234CR */
+ PORTCR(235, 0xe60520eb), /* PORT235CR */
+ PORTCR(236, 0xe60520ec), /* PORT236CR */
+ PORTCR(237, 0xe60520ed), /* PORT237CR */
+ PORTCR(238, 0xe60520ee), /* PORT238CR */
+ PORTCR(239, 0xe60520ef), /* PORT239CR */
+
+ PORTCR(240, 0xe60520f0), /* PORT240CR */
+ PORTCR(241, 0xe60520f1), /* PORT241CR */
+ PORTCR(242, 0xe60520f2), /* PORT242CR */
+ PORTCR(243, 0xe60520f3), /* PORT243CR */
+ PORTCR(244, 0xe60520f4), /* PORT244CR */
+ PORTCR(245, 0xe60520f5), /* PORT245CR */
+ PORTCR(246, 0xe60520f6), /* PORT246CR */
+ PORTCR(247, 0xe60520f7), /* PORT247CR */
+ PORTCR(248, 0xe60520f8), /* PORT248CR */
+ PORTCR(249, 0xe60520f9), /* PORT249CR */
+
+ PORTCR(250, 0xe60520fa), /* PORT250CR */
+ PORTCR(251, 0xe60520fb), /* PORT251CR */
+ PORTCR(252, 0xe60520fc), /* PORT252CR */
+ PORTCR(253, 0xe60520fd), /* PORT253CR */
+ PORTCR(254, 0xe60520fe), /* PORT254CR */
+ PORTCR(255, 0xe60520ff), /* PORT255CR */
+ PORTCR(256, 0xe6052100), /* PORT256CR */
+ PORTCR(257, 0xe6052101), /* PORT257CR */
+ PORTCR(258, 0xe6052102), /* PORT258CR */
+ PORTCR(259, 0xe6052103), /* PORT259CR */
+
+ PORTCR(260, 0xe6052104), /* PORT260CR */
+ PORTCR(261, 0xe6052105), /* PORT261CR */
+ PORTCR(262, 0xe6052106), /* PORT262CR */
+ PORTCR(263, 0xe6052107), /* PORT263CR */
+ PORTCR(264, 0xe6052108), /* PORT264CR */
+
+ { PINMUX_CFG_REG("MSELBCR", 0xe6058024, 32, 1) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ MSELBCR_MSEL17_0, MSELBCR_MSEL17_1,
+ MSELBCR_MSEL16_0, MSELBCR_MSEL16_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
+ PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+ PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+ PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+ PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+ PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+ PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+ PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+ PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL063_032DR", 0xe6054004, 32) {
+ PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+ PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+ PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+ PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+ PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
+ PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+ PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+ PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL095_064DR", 0xe6054008, 32) {
+ PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+ PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+ PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+ PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+ PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+ PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+ PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+ PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD127_096DR", 0xe605400C, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+ PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+ PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+ PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+ PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+ PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD159_128DR", 0xe6055000, 32) {
+ PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+ PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+ PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+ PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+ PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+ PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+ PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+ PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR191_160DR", 0xe6055004, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR223_192DR", 0xe6056000, 32) {
+ PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
+ PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
+ PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
+ PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
+ PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
+ PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
+ PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
+ PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU255_224DR", 0xe6056004, 32) {
+ PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
+ PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
+ PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
+ PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
+ PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
+ PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
+ PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
+ PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU287_256DR", 0xe6056008, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT264_DATA,
+ PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
+ PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7377_pinmux_info = {
+ .name = "sh7377_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PORT0,
+ .last_gpio = GPIO_FN_RESETOUTS,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7377_pinmux_init(void)
+{
+ register_pinmux(&sh7377_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
new file mode 100644
index 00000000000..eca90716140
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -0,0 +1,198 @@
+/*
+ * sh7367 processor support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 80, 80, 80, 80 },
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xe6c50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 81, 81, 81, 81 },
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xe6c60000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 82, 82, 82, 82 },
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xe6c70000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 83, 83, 83, 83 },
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xe6c80000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 89, 89, 89, 89 },
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xe6cb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 90, 90, 90, 90 },
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+static struct plat_sci_port scif6_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 91, 91, 91, 91 },
+};
+
+static struct platform_device scif6_device = {
+ .name = "sh-sci",
+ .id = 6,
+ .dev = {
+ .platform_data = &scif6_platform_data,
+ },
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clk = "r_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 72,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt10_device = {
+ .name = "sh_cmt",
+ .id = 10,
+ .dev = {
+ .platform_data = &cmt10_platform_data,
+ },
+ .resource = cmt10_resources,
+ .num_resources = ARRAY_SIZE(cmt10_resources),
+};
+
+static struct platform_device *sh7367_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &cmt10_device,
+};
+
+void __init sh7367_add_standard_devices(void)
+{
+ platform_add_devices(sh7367_early_devices,
+ ARRAY_SIZE(sh7367_early_devices));
+}
+
+#define SYMSTPCR2 0xe6158048
+#define SYMSTPCR2_CMT1 (1 << 29)
+
+void __init sh7367_add_early_devices(void)
+{
+ /* enable clock to CMT1 */
+ __raw_writel(__raw_readl(SYMSTPCR2) & ~SYMSTPCR2_CMT1, SYMSTPCR2);
+
+ early_platform_add_devices(sh7367_early_devices,
+ ARRAY_SIZE(sh7367_early_devices));
+}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
new file mode 100644
index 00000000000..1d1153290f5
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -0,0 +1,199 @@
+/*
+ * sh7372 processor support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 80, 80, 80, 80 },
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xe6c50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 81, 81, 81, 81 },
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xe6c60000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 82, 82, 82, 82 },
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xe6c70000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 83, 83, 83, 83 },
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xe6c80000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 89, 89, 89, 89 },
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xe6cb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 90, 90, 90, 90 },
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+static struct plat_sci_port scif6_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 91, 91, 91, 91 },
+};
+
+static struct platform_device scif6_device = {
+ .name = "sh-sci",
+ .id = 6,
+ .dev = {
+ .platform_data = &scif6_platform_data,
+ },
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clk = "r_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 72,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt10_device = {
+ .name = "sh_cmt",
+ .id = 10,
+ .dev = {
+ .platform_data = &cmt10_platform_data,
+ },
+ .resource = cmt10_resources,
+ .num_resources = ARRAY_SIZE(cmt10_resources),
+};
+
+static struct platform_device *sh7372_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &cmt10_device,
+};
+
+void __init sh7372_add_standard_devices(void)
+{
+ platform_add_devices(sh7372_early_devices,
+ 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
new file mode 100644
index 00000000000..60e37774c35
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -0,0 +1,215 @@
+/*
+ * sh7377 processor support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 80, 80, 80, 80 },
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xe6c50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 81, 81, 81, 81 },
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xe6c60000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 82, 82, 82, 82 },
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xe6c70000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 83, 83, 83, 83 },
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xe6c80000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 89, 89, 89, 89 },
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xe6cb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 90, 90, 90, 90 },
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+static struct plat_sci_port scif6_platform_data = {
+ .mapbase = 0xe6cc0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 196, 196, 196, 196 },
+};
+
+static struct platform_device scif6_device = {
+ .name = "sh-sci",
+ .id = 6,
+ .dev = {
+ .platform_data = &scif6_platform_data,
+ },
+};
+
+static struct plat_sci_port scif7_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 91, 91, 91, 91 },
+};
+
+static struct platform_device scif7_device = {
+ .name = "sh-sci",
+ .id = 7,
+ .dev = {
+ .platform_data = &scif7_platform_data,
+ },
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clk = "r_clk",
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 72,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt10_device = {
+ .name = "sh_cmt",
+ .id = 10,
+ .dev = {
+ .platform_data = &cmt10_platform_data,
+ },
+ .resource = cmt10_resources,
+ .num_resources = ARRAY_SIZE(cmt10_resources),
+};
+
+static struct platform_device *sh7377_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &scif7_device,
+ &cmt10_device,
+};
+
+void __init sh7377_add_standard_devices(void)
+{
+ platform_add_devices(sh7377_early_devices,
+ ARRAY_SIZE(sh7377_early_devices));
+}
+
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR3_CMT1 (1 << 29)
+
+void __init sh7377_add_early_devices(void)
+{
+ /* enable clock to CMT1 */
+ __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
+
+ early_platform_add_devices(sh7377_early_devices,
+ ARRAY_SIZE(sh7377_early_devices));
+}
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
new file mode 100644
index 00000000000..895794b543c
--- /dev/null
+++ b/arch/arm/mach-shmobile/timer.c
@@ -0,0 +1,46 @@
+/*
+ * SH-Mobile Timer
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2002 - 2009 Paul Mundt
+ *
+ * This program is free software; 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/platform_device.h>
+#include <asm/mach/time.h>
+
+static void __init shmobile_late_time_init(void)
+{
+ /*
+ * Make sure all compiled-in early timers register themselves.
+ *
+ * Run probe() for two "earlytimer" devices, these will be the
+ * clockevents and clocksource devices respectively. In the event
+ * that only a clockevents device is available, we -ENODEV on the
+ * clocksource and the jiffies clocksource is used transparently
+ * instead. No error handling is necessary here.
+ */
+ early_platform_driver_register_all("earlytimer");
+ early_platform_driver_probe("earlytimer", 2, 0);
+}
+
+static void __init shmobile_timer_init(void)
+{
+ late_time_init = shmobile_late_time_init;
+}
+
+struct sys_timer shmobile_timer = {
+ .init = shmobile_timer_init,
+};
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 01b50313914..5f34eb674d6 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -358,7 +358,7 @@ static struct resource ave_resources[] = {
/*
* The AVE3e requires two regions of 256MB that it considers
* "invisible". The hardware will not be able to access these
- * adresses, so they should never point to system RAM.
+ * addresses, so they should never point to system RAM.
*/
{
.name = "AVE3e Reserved 0",
@@ -1596,7 +1596,7 @@ static void __init u300_init_check_chip(void)
/*
* Some devices and their resources require reserved physical memory from
* the end of the available RAM. This function traverses the list of devices
- * and assigns actual adresses to these.
+ * and assigns actual addresses to these.
*/
static void __init u300_assign_physmem(void)
{
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c
index 962f9de454d..5f55012b7c9 100644
--- a/arch/arm/mach-u300/dummyspichip.c
+++ b/arch/arm/mach-u300/dummyspichip.c
@@ -15,6 +15,7 @@
#include <linux/mutex.h>
#include <linux/spi/spi.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
/*
* WARNING! Do not include this pl022-specific controller header
* for any generic driver. It is only done in this dummy chip
diff --git a/arch/arm/mach-u300/include/mach/debug-macro.S b/arch/arm/mach-u300/include/mach/debug-macro.S
index ca4a028c266..92c12420256 100644
--- a/arch/arm/mach-u300/include/mach/debug-macro.S
+++ b/arch/arm/mach-u300/include/mach/debug-macro.S
@@ -11,7 +11,7 @@
#include <mach/hardware.h>
.macro addruart, rx, tmp
- /* If we move the adress using MMU, use this. */
+ /* If we move the address using MMU, use this. */
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
ldreq \rx, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
index 109f5a6e71c..77fbb1e0e52 100644
--- a/arch/arm/mach-u300/mmc.c
+++ b/arch/arm/mach-u300/mmc.c
@@ -20,6 +20,7 @@
#include <linux/regulator/machine.h>
#include <linux/gpio.h>
#include <linux/amba/mmci.h>
+#include <linux/slab.h>
#include "mmc.h"
#include "padmux.h"
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
index 6da650202dc..04ea836969b 100644
--- a/arch/arm/mach-ux500/include/mach/hardware.h
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -68,12 +68,12 @@
#define U8500_PKAM_BASE (U8500_PER6_BASE + 0x2000)
#define U8500_CRYPTO0_BASE (U8500_PER6_BASE + 0xa000)
#define U8500_CRYPTO1_BASE (U8500_PER6_BASE + 0xb000)
-#define U8500_CLKRST6_BASE (U8500_PER7_BASE + 0xf000)
+#define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000)
/* per5 base addressess */
#define U8500_USBOTG_BASE (U8500_PER5_BASE + 0x00000)
#define U8500_GPIO5_BASE (U8500_PER5_BASE + 0x1e000)
-#define U8500_CLKRST5_BASE (U8500_PER7_BASE + 0x1f000)
+#define U8500_CLKRST5_BASE (U8500_PER5_BASE + 0x1f000)
/* per4 base addressess */
#define U8500_BACKUPRAM0_BASE (U8500_PER4_BASE + 0x0000)
@@ -95,7 +95,7 @@
#define U8500_UART2_BASE (U8500_PER3_BASE + 0x7000)
#define U8500_SDI5_BASE (U8500_PER3_BASE + 0x8000)
#define U8500_GPIO3_BASE (U8500_PER3_BASE + 0xe000)
-#define U8500_CLKRST3_BASE (U8500_PER7_BASE + 0xf000)
+#define U8500_CLKRST3_BASE (U8500_PER3_BASE + 0xf000)
/* per2 base addressess */
#define U8500_I2C3_BASE (U8500_PER2_BASE + 0x0000)
@@ -123,7 +123,7 @@
#define U8500_SPI3_BASE (U8500_PER1_BASE + 0x9000)
#define U8500_SLIM0_BASE (U8500_PER1_BASE + 0xa000)
#define U8500_GPIO1_BASE (U8500_PER1_BASE + 0xe000)
-#define U8500_CLKRST1_BASE (U8500_PER2_BASE + 0xf000)
+#define U8500_CLKRST1_BASE (U8500_PER1_BASE + 0xf000)
/* ST-Ericsson modified pl022 id */
#define SSP_PER_ID 0x01080022
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 9ddb49b1cb7..3b1a4ee0181 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -32,6 +32,7 @@
#include <linux/clockchips.h>
#include <linux/cnt32_to_63.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <asm/clkdev.h>
#include <asm/system.h>
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
index 7161ba23b58..334f0df4e94 100644
--- a/arch/arm/mach-versatile/pci.c
+++ b/arch/arm/mach-versatile/pci.c
@@ -16,7 +16,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
index 4d58ba164e2..f8730b60bd7 100644
--- a/arch/arm/mach-w90x900/cpu.h
+++ b/arch/arm/mach-w90x900/cpu.h
@@ -57,3 +57,4 @@ extern struct platform_device nuc900_device_fmi;
extern struct platform_device nuc900_device_kpi;
extern struct platform_device nuc900_device_rtc;
extern struct platform_device nuc900_device_ts;
+extern struct platform_device nuc900_device_lcd;
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c
index ec711f4b401..e2958eb567f 100644
--- a/arch/arm/mach-w90x900/dev.c
+++ b/arch/arm/mach-w90x900/dev.c
@@ -18,6 +18,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/mtd.h>
@@ -34,6 +35,7 @@
#include <mach/regs-serial.h>
#include <mach/nuc900_spi.h>
#include <mach/map.h>
+#include <mach/fb.h>
#include "cpu.h"
@@ -380,6 +382,47 @@ struct platform_device nuc900_device_kpi = {
.resource = nuc900_kpi_resource,
};
+#ifdef CONFIG_FB_NUC900
+
+static struct resource nuc900_lcd_resource[] = {
+ [0] = {
+ .start = W90X900_PA_LCD,
+ .end = W90X900_PA_LCD + W90X900_SZ_LCD - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD,
+ .end = IRQ_LCD,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 nuc900_device_lcd_dmamask = -1;
+struct platform_device nuc900_device_lcd = {
+ .name = "nuc900-lcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_lcd_resource),
+ .resource = nuc900_lcd_resource,
+ .dev = {
+ .dma_mask = &nuc900_device_lcd_dmamask,
+ .coherent_dma_mask = -1,
+ }
+};
+
+void nuc900_fb_set_platdata(struct nuc900fb_mach_info *pd)
+{
+ struct nuc900fb_mach_info *npd;
+
+ npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+ if (npd) {
+ memcpy(npd, pd, sizeof(*npd));
+ nuc900_device_lcd.dev.platform_data = npd;
+ } else {
+ printk(KERN_ERR "no memory for LCD platform data\n");
+ }
+}
+#endif
+
/*Here should be your evb resourse,such as LCD*/
static struct platform_device *nuc900_public_dev[] __initdata = {
diff --git a/arch/arm/mach-w90x900/include/mach/fb.h b/arch/arm/mach-w90x900/include/mach/fb.h
new file mode 100644
index 00000000000..cec5ece765e
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/fb.h
@@ -0,0 +1,83 @@
+/* linux/include/asm/arch-nuc900/fb.h
+ *
+ * Copyright (c) 2008 Nuvoton technology 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Changelog:
+ *
+ * 2008/08/26 vincen.zswan modify this file for LCD.
+ */
+
+#ifndef __ASM_ARM_FB_H
+#define __ASM_ARM_FB_H
+
+
+
+/* LCD Controller Hardware Desc */
+struct nuc900fb_hw {
+ unsigned int lcd_dccs;
+ unsigned int lcd_device_ctrl;
+ unsigned int lcd_mpulcd_cmd;
+ unsigned int lcd_int_cs;
+ unsigned int lcd_crtc_size;
+ unsigned int lcd_crtc_dend;
+ unsigned int lcd_crtc_hr;
+ unsigned int lcd_crtc_hsync;
+ unsigned int lcd_crtc_vr;
+ unsigned int lcd_va_baddr0;
+ unsigned int lcd_va_baddr1;
+ unsigned int lcd_va_fbctrl;
+ unsigned int lcd_va_scale;
+ unsigned int lcd_va_test;
+ unsigned int lcd_va_win;
+ unsigned int lcd_va_stuff;
+};
+
+/* LCD Display Description */
+struct nuc900fb_display {
+ /* LCD Image type */
+ unsigned type;
+
+ /* LCD Screen Size */
+ unsigned short width;
+ unsigned short height;
+
+ /* LCD Screen Info */
+ unsigned short xres;
+ unsigned short yres;
+ unsigned short bpp;
+
+ unsigned long pixclock;
+ unsigned short left_margin;
+ unsigned short right_margin;
+ unsigned short hsync_len;
+ unsigned short upper_margin;
+ unsigned short lower_margin;
+ unsigned short vsync_len;
+
+ /* hardware special register value */
+ unsigned int dccs;
+ unsigned int devctl;
+ unsigned int fbctrl;
+ unsigned int scale;
+};
+
+struct nuc900fb_mach_info {
+ struct nuc900fb_display *displays;
+ unsigned num_displays;
+ unsigned default_display;
+ /* GPIO Setting Info */
+ unsigned gpio_dir;
+ unsigned gpio_dir_mask;
+ unsigned gpio_data;
+ unsigned gpio_data_mask;
+};
+
+extern void __init nuc900_fb_set_platdata(struct nuc900fb_mach_info *);
+
+#endif /* __ASM_ARM_FB_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ldm.h b/arch/arm/mach-w90x900/include/mach/regs-ldm.h
new file mode 100644
index 00000000000..e9d480a5b23
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-ldm.h
@@ -0,0 +1,253 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-serial.h
+ *
+ * Copyright (c) 2009 Nuvoton technology 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Description:
+ * Nuvoton Display, LCM Register list
+ * Author: Wang Qiang (rurality.linux@gmail.com) 2009/12/11
+ *
+ */
+
+
+#ifndef __ASM_ARM_W90X900_REGS_LDM_H
+#define __ASM_ARM_W90X900_REGS_LDM_H
+
+#include <mach/map.h>
+
+/* Display Controller Control/Status Register */
+#define REG_LCM_DCCS (0x00)
+
+#define LCM_DCCS_ENG_RST (1 << 0)
+#define LCM_DCCS_VA_EN (1 << 1)
+#define LCM_DCCS_OSD_EN (1 << 2)
+#define LCM_DCCS_DISP_OUT_EN (1 << 3)
+#define LCM_DCCS_DISP_INT_EN (1 << 4)
+#define LCM_DCCS_CMD_ON (1 << 5)
+#define LCM_DCCS_FIELD_INTR (1 << 6)
+#define LCM_DCCS_SINGLE (1 << 7)
+
+enum LCM_DCCS_VA_SRC {
+ LCM_DCCS_VA_SRC_YUV422 = (0 << 8),
+ LCM_DCCS_VA_SRC_YCBCR422 = (1 << 8),
+ LCM_DCCS_VA_SRC_RGB888 = (2 << 8),
+ LCM_DCCS_VA_SRC_RGB666 = (3 << 8),
+ LCM_DCCS_VA_SRC_RGB565 = (4 << 8),
+ LCM_DCCS_VA_SRC_RGB444LOW = (5 << 8),
+ LCM_DCCS_VA_SRC_RGB444HIGH = (7 << 8)
+};
+
+
+/* Display Device Control Register */
+#define REG_LCM_DEV_CTRL (0x04)
+
+enum LCM_DEV_CTRL_SWAP_YCbCr {
+ LCM_DEV_CTRL_SWAP_UYVY = (0 << 1),
+ LCM_DEV_CTRL_SWAP_YUYV = (1 << 1),
+ LCM_DEV_CTRL_SWAP_VYUY = (2 << 1),
+ LCM_DEV_CTRL_SWAP_YVYU = (3 << 1)
+};
+
+enum LCM_DEV_CTRL_RGB_SHIFT {
+ LCM_DEV_CTRL_RGB_SHIFT_NOT = (0 << 3),
+ LCM_DEV_CTRL_RGB_SHIFT_ONECYCLE = (1 << 3),
+ LCM_DEV_CTRL_RGB_SHIFT_TWOCYCLE = (2 << 3),
+ LCM_DEV_CTRL_RGB_SHIFT_NOT_DEF = (3 << 3)
+};
+
+enum LCM_DEV_CTRL_DEVICE {
+ LCM_DEV_CTRL_DEVICE_YUV422 = (0 << 5),
+ LCM_DEV_CTRL_DEVICE_YUV444 = (1 << 5),
+ LCM_DEV_CTRL_DEVICE_UNIPAC = (4 << 5),
+ LCM_DEV_CTRL_DEVICE_SEIKO_EPSON = (5 << 5),
+ LCM_DEV_CTRL_DEVICE_HIGH_COLOR = (6 << 5),
+ LCM_DEV_CTRL_DEVICE_MPU = (7 << 5)
+};
+
+#define LCM_DEV_CTRL_LCD_DDA (8)
+#define LCM_DEV_CTRL_YUV2CCIR (16)
+
+enum LCM_DEV_CTRL_LCD_SEL {
+ LCM_DEV_CTRL_LCD_SEL_RGB_GBR = (0 << 17),
+ LCM_DEV_CTRL_LCD_SEL_BGR_RBG = (1 << 17),
+ LCM_DEV_CTRL_LCD_SEL_GBR_RGB = (2 << 17),
+ LCM_DEV_CTRL_LCD_SEL_RBG_BGR = (3 << 17)
+};
+
+enum LCM_DEV_CTRL_FAL_D {
+ LCM_DEV_CTRL_FAL_D_FALLING = (0 << 19),
+ LCM_DEV_CTRL_FAL_D_RISING = (1 << 19),
+};
+
+enum LCM_DEV_CTRL_H_POL {
+ LCM_DEV_CTRL_H_POL_LOW = (0 << 20),
+ LCM_DEV_CTRL_H_POL_HIGH = (1 << 20),
+};
+
+enum LCM_DEV_CTRL_V_POL {
+ LCM_DEV_CTRL_V_POL_LOW = (0 << 21),
+ LCM_DEV_CTRL_V_POL_HIGH = (1 << 21),
+};
+
+enum LCM_DEV_CTRL_VR_LACE {
+ LCM_DEV_CTRL_VR_LACE_NINTERLACE = (0 << 22),
+ LCM_DEV_CTRL_VR_LACE_INTERLACE = (1 << 22),
+};
+
+enum LCM_DEV_CTRL_LACE {
+ LCM_DEV_CTRL_LACE_NINTERLACE = (0 << 23),
+ LCM_DEV_CTRL_LACE_INTERLACE = (1 << 23),
+};
+
+enum LCM_DEV_CTRL_RGB_SCALE {
+ LCM_DEV_CTRL_RGB_SCALE_4096 = (0 << 24),
+ LCM_DEV_CTRL_RGB_SCALE_65536 = (1 << 24),
+ LCM_DEV_CTRL_RGB_SCALE_262144 = (2 << 24),
+ LCM_DEV_CTRL_RGB_SCALE_16777216 = (3 << 24),
+};
+
+enum LCM_DEV_CTRL_DBWORD {
+ LCM_DEV_CTRL_DBWORD_HALFWORD = (0 << 26),
+ LCM_DEV_CTRL_DBWORD_FULLWORD = (1 << 26),
+};
+
+enum LCM_DEV_CTRL_MPU68 {
+ LCM_DEV_CTRL_MPU68_80_SERIES = (0 << 27),
+ LCM_DEV_CTRL_MPU68_68_SERIES = (1 << 27),
+};
+
+enum LCM_DEV_CTRL_DE_POL {
+ LCM_DEV_CTRL_DE_POL_HIGH = (0 << 28),
+ LCM_DEV_CTRL_DE_POL_LOW = (1 << 28),
+};
+
+#define LCM_DEV_CTRL_CMD16 (29)
+#define LCM_DEV_CTRL_CM16t18 (30)
+#define LCM_DEV_CTRL_CMD_LOW (31)
+
+/* MPU-Interface LCD Write Command */
+#define REG_LCM_MPU_CMD (0x08)
+
+/* Interrupt Control/Status Register */
+#define REG_LCM_INT_CS (0x0c)
+#define LCM_INT_CS_DISP_F_EN (1 << 0)
+#define LCM_INT_CS_UNDERRUN_EN (1 << 1)
+#define LCM_INT_CS_BUS_ERROR_INT (1 << 28)
+#define LCM_INT_CS_UNDERRUN_INT (1 << 29)
+#define LCM_INT_CS_DISP_F_STATUS (1 << 30)
+#define LCM_INT_CS_DISP_F_INT (1 << 31)
+
+/* CRTC Display Size Control Register */
+#define REG_LCM_CRTC_SIZE (0x10)
+#define LCM_CRTC_SIZE_VTTVAL(x) ((x) << 16)
+#define LCM_CRTC_SIZE_HTTVAL(x) ((x) << 0)
+
+/* CRTC Display Enable End */
+#define REG_LCM_CRTC_DEND (0x14)
+#define LCM_CRTC_DEND_VDENDVAL(x) ((x) << 16)
+#define LCM_CRTC_DEND_HDENDVAL(x) ((x) << 0)
+
+/* CRTC Internal Horizontal Retrace Control Register */
+#define REG_LCM_CRTC_HR (0x18)
+#define LCM_CRTC_HR_EVAL(x) ((x) << 16)
+#define LCM_CRTC_HR_SVAL(x) ((x) << 0)
+
+/* CRTC Horizontal Sync Control Register */
+#define REG_LCM_CRTC_HSYNC (0x1C)
+#define LCM_CRTC_HSYNC_SHIFTVAL(x) ((x) << 30)
+#define LCM_CRTC_HSYNC_EVAL(x) ((x) << 16)
+#define LCM_CRTC_HSYNC_SVAL(x) ((x) << 0)
+
+/* CRTC Internal Vertical Retrace Control Register */
+#define REG_LCM_CRTC_VR (0x20)
+#define LCM_CRTC_VR_EVAL(x) ((x) << 16)
+#define LCM_CRTC_VR_SVAL(x) ((x) << 0)
+
+/* Video Stream Frame Buffer-0 Starting Address */
+#define REG_LCM_VA_BADDR0 (0x24)
+
+/* Video Stream Frame Buffer-1 Starting Address */
+#define REG_LCM_VA_BADDR1 (0x28)
+
+/* Video Stream Frame Buffer Control Register */
+#define REG_LCM_VA_FBCTRL (0x2C)
+#define LCM_VA_FBCTRL_IO_REGION_HALF (1 << 28)
+#define LCM_VA_FBCTRL_FIELD_DUAL (1 << 29)
+#define LCM_VA_FBCTRL_START_BUF (1 << 30)
+#define LCM_VA_FBCTRL_DB_EN (1 << 31)
+
+/* Video Stream Scaling Control Register */
+#define REG_LCM_VA_SCALE (0x30)
+#define LCM_VA_SCALE_XCOPY_INTERPOLATION (0 << 15)
+#define LCM_VA_SCALE_XCOPY_DUPLICATION (1 << 15)
+
+/* Image Stream Active Window Coordinates */
+#define REG_LCM_VA_WIN (0x38)
+
+/* Image Stream Stuff Pixel */
+#define REG_LCM_VA_STUFF (0x3C)
+
+/* OSD Window Starting Coordinates */
+#define REG_LCM_OSD_WINS (0x40)
+
+/* OSD Window Ending Coordinates */
+#define REG_LCM_OSD_WINE (0x44)
+
+/* OSD Stream Frame Buffer Starting Address */
+#define REG_LCM_OSD_BADDR (0x48)
+
+/* OSD Stream Frame Buffer Control Register */
+#define REG_LCM_OSD_FBCTRL (0x4c)
+
+/* OSD Overlay Control Register */
+#define REG_LCM_OSD_OVERLAY (0x50)
+
+/* OSD Overlay Color-Key Pattern Register */
+#define REG_LCM_OSD_CKEY (0x54)
+
+/* OSD Overlay Color-Key Mask Register */
+#define REG_LCM_OSD_CMASK (0x58)
+
+/* OSD Window Skip1 Register */
+#define REG_LCM_OSD_SKIP1 (0x5C)
+
+/* OSD Window Skip2 Register */
+#define REG_LCM_OSD_SKIP2 (0x60)
+
+/* OSD horizontal up scaling control register */
+#define REG_LCM_OSD_SCALE (0x64)
+
+/* MPU Vsync control register */
+#define REG_LCM_MPU_VSYNC (0x68)
+
+/* Hardware cursor control Register */
+#define REG_LCM_HC_CTRL (0x6C)
+
+/* Hardware cursot tip point potison on va picture */
+#define REG_LCM_HC_POS (0x70)
+
+/* Hardware Cursor Window Buffer Control Register */
+#define REG_LCM_HC_WBCTRL (0x74)
+
+/* Hardware cursor memory base address register */
+#define REG_LCM_HC_BADDR (0x78)
+
+/* Hardware cursor color ram register mapped to bpp = 0 */
+#define REG_LCM_HC_COLOR0 (0x7C)
+
+/* Hardware cursor color ram register mapped to bpp = 1 */
+#define REG_LCM_HC_COLOR1 (0x80)
+
+/* Hardware cursor color ram register mapped to bpp = 2 */
+#define REG_LCM_HC_COLOR2 (0x84)
+
+/* Hardware cursor color ram register mapped to bpp = 3 */
+#define REG_LCM_HC_COLOR3 (0x88)
+
+#endif /* __ASM_ARM_W90X900_REGS_LDM_H */
diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c
index cef903bcccd..b3edc3cccf5 100644
--- a/arch/arm/mach-w90x900/mach-nuc950evb.c
+++ b/arch/arm/mach-w90x900/mach-nuc950evb.c
@@ -10,6 +10,8 @@
* This program is free software; 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.
+ * history:
+ * Wang Qiang (rurality.linux@gmail.com) add LCD support
*
*/
@@ -18,9 +20,51 @@
#include <asm/mach/map.h>
#include <asm/mach-types.h>
#include <mach/map.h>
+#include <mach/regs-ldm.h>
+#include <mach/fb.h>
#include "nuc950.h"
+#ifdef CONFIG_FB_NUC900
+/* LCD Controller */
+static struct nuc900fb_display __initdata nuc950_lcd_info[] = {
+ /* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
+ [0] = {
+ .type = LCM_DCCS_VA_SRC_RGB565,
+ .width = 320,
+ .height = 240,
+ .xres = 320,
+ .yres = 240,
+ .bpp = 16,
+ .pixclock = 200000,
+ .left_margin = 34,
+ .right_margin = 54,
+ .hsync_len = 10,
+ .upper_margin = 18,
+ .lower_margin = 4,
+ .vsync_len = 1,
+ .dccs = 0x8e00041a,
+ .devctl = 0x060800c0,
+ .fbctrl = 0x00a000a0,
+ .scale = 0x04000400,
+ },
+};
+
+static struct nuc900fb_mach_info nuc950_fb_info __initdata = {
+#if defined(CONFIG_GPM1040A0_320X240)
+ .displays = &nuc950_lcd_info[0],
+#else
+ .displays = nuc950_lcd_info,
+#endif
+ .num_displays = ARRAY_SIZE(nuc950_lcd_info),
+ .default_display = 0,
+ .gpio_dir = 0x00000004,
+ .gpio_dir_mask = 0xFFFFFFFD,
+ .gpio_data = 0x00000004,
+ .gpio_data_mask = 0xFFFFFFFD,
+};
+#endif
+
static void __init nuc950evb_map_io(void)
{
nuc950_map_io();
@@ -30,6 +74,9 @@ static void __init nuc950evb_map_io(void)
static void __init nuc950evb_init(void)
{
nuc950_board_init();
+#ifdef CONFIG_FB_NUC900
+ nuc900_fb_set_platdata(&nuc950_fb_info);
+#endif
}
MACHINE_START(W90P950EVB, "W90P950EVB")
diff --git a/arch/arm/mach-w90x900/nuc950.c b/arch/arm/mach-w90x900/nuc950.c
index 149508116d1..4d1f1ab044c 100644
--- a/arch/arm/mach-w90x900/nuc950.c
+++ b/arch/arm/mach-w90x900/nuc950.c
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
+
#include "cpu.h"
/* define specific CPU platform device */
@@ -25,6 +26,9 @@
static struct platform_device *nuc950_dev[] __initdata = {
&nuc900_device_kpi,
&nuc900_device_fmi,
+#ifdef CONFIG_FB_NUC900
+ &nuc900_device_lcd,
+#endif
};
/* define specific CPU platform io map */
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c4ed9f93f64..5bd7c89a604 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -736,6 +736,12 @@ config NEEDS_SYSCALL_FOR_CMPXCHG
config OUTER_CACHE
bool
+config OUTER_CACHE_SYNC
+ bool
+ help
+ The outer cache has a outer_cache_fns.sync function pointer
+ that can be used to drain the write buffer of the outer cache.
+
config CACHE_FEROCEON_L2
bool "Enable the Feroceon L2 cache controller"
depends on ARCH_KIRKWOOD || ARCH_MV78XX0
@@ -757,6 +763,7 @@ config CACHE_L2X0
REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4
default y
select OUTER_CACHE
+ select OUTER_CACHE_SYNC
help
This option enables the L2x0 PrimeCell.
@@ -781,3 +788,9 @@ config ARM_L1_CACHE_SHIFT
int
default 6 if ARM_L1_CACHE_SHIFT_6
default 5
+
+config ARCH_HAS_BARRIERS
+ bool
+ help
+ This option allows the use of custom mandatory barriers
+ included via the mach/barriers.h file.
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index edddd66faac..a2ab51fa73e 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -166,15 +166,15 @@ union offset_union {
THUMB( "1: "ins" %1, [%2]\n" ) \
THUMB( " add %2, %2, #1\n" ) \
"2:\n" \
- " .section .fixup,\"ax\"\n" \
+ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"3: mov %0, #1\n" \
" b 2b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 3b\n" \
- " .previous\n" \
+ " .popsection\n" \
: "=r" (err), "=&r" (val), "=r" (addr) \
: "0" (err), "2" (addr))
@@ -226,16 +226,16 @@ union offset_union {
" mov %1, %1, "NEXT_BYTE"\n" \
"2: "ins" %1, [%2]\n" \
"3:\n" \
- " .section .fixup,\"ax\"\n" \
+ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"4: mov %0, #1\n" \
" b 3b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 4b\n" \
" .long 2b, 4b\n" \
- " .previous\n" \
+ " .popsection\n" \
: "=r" (err), "=&r" (v), "=&r" (a) \
: "0" (err), "1" (v), "2" (a)); \
if (err) \
@@ -266,18 +266,18 @@ union offset_union {
" mov %1, %1, "NEXT_BYTE"\n" \
"4: "ins" %1, [%2]\n" \
"5:\n" \
- " .section .fixup,\"ax\"\n" \
+ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
"6: mov %0, #1\n" \
" b 5b\n" \
- " .previous\n" \
- " .section __ex_table,\"a\"\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 6b\n" \
" .long 2b, 6b\n" \
" .long 3b, 6b\n" \
" .long 4b, 6b\n" \
- " .previous\n" \
+ " .popsection\n" \
: "=r" (err), "=&r" (v), "=&r" (a) \
: "0" (err), "1" (v), "2" (a)); \
if (err) \
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 07334632d3e..21ad68ba22b 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -93,6 +93,15 @@ static inline void l2x0_flush_line(unsigned long addr)
}
#endif
+static void l2x0_cache_sync(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&l2x0_lock, flags);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
static inline void l2x0_inv_all(void)
{
unsigned long flags;
@@ -225,6 +234,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
outer_cache.inv_range = l2x0_inv_range;
outer_cache.clean_range = l2x0_clean_range;
outer_cache.flush_range = l2x0_flush_range;
+ outer_cache.sync = l2x0_cache_sync;
printk(KERN_INFO "L2X0 cache controller enabled\n");
}
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 8bca4dea6df..f55fa1044f7 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
kfrom = kmap_atomic(from, KM_USER0);
kto = kmap_atomic(to, KM_USER1);
copy_page(kto, kfrom);
-#ifdef CONFIG_HIGHMEM
- /*
- * kmap_atomic() doesn't set the page virtual address, and
- * kunmap_atomic() takes care of cache flushing already.
- */
- if (page_address(to) != NULL)
-#endif
- __cpuc_flush_dcache_area(kto, PAGE_SIZE);
+ __cpuc_flush_dcache_area(kto, PAGE_SIZE);
kunmap_atomic(kto, KM_USER1);
kunmap_atomic(kfrom, KM_USER0);
}
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 0da7eccf774..13fa536d82e 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -11,7 +11,7 @@
*/
#include <linux/module.h>
#include <linux/mm.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/init.h>
@@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
vaddr += offset;
op(vaddr, len, dir);
kunmap_high(page);
+ } else if (cache_is_vipt()) {
+ pte_t saved_pte;
+ vaddr = kmap_high_l1_vipt(page, &saved_pte);
+ op(vaddr + offset, len, dir);
+ kunmap_high_l1_vipt(page, saved_pte);
}
} else {
vaddr = page_address(page) + offset;
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index c9b97e9836a..0d414c28eb2 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -16,6 +16,7 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/pagemap.h>
+#include <linux/gfp.h>
#include <asm/bugs.h>
#include <asm/cacheflush.h>
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index e34f095e209..c6844cb9b50 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -13,6 +13,7 @@
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
+#include <asm/highmem.h>
#include <asm/smp_plat.h>
#include <asm/system.h>
#include <asm/tlbflush.h>
@@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
void __flush_dcache_page(struct address_space *mapping, struct page *page)
{
- void *addr = page_address(page);
-
/*
* Writeback any data associated with the kernel mapping of this
* page. This ensures that data in the physical page is mutually
* coherent with the kernels mapping.
*/
-#ifdef CONFIG_HIGHMEM
- /*
- * kmap_atomic() doesn't set the page virtual address, and
- * kunmap_atomic() takes care of cache flushing already.
- */
- if (addr)
-#endif
- __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ if (!PageHighMem(page)) {
+ __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+ } else {
+ void *addr = kmap_high_get(page);
+ if (addr) {
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_high(page);
+ } else if (cache_is_vipt()) {
+ pte_t saved_pte;
+ addr = kmap_high_l1_vipt(page, &saved_pte);
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_high_l1_vipt(page, saved_pte);
+ }
+ }
/*
* If this is a page cache page, and we have an aliasing VIPT cache,
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 2be1ec7c1b4..77b030f5ec0 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
if (kvaddr >= (void *)FIXADDR_START) {
- __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
+ if (cache_is_vivt())
+ __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
@@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr)
pte = TOP_PTE(vaddr);
return pte_page(*pte);
}
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+
+#include <linux/percpu.h>
+
+/*
+ * The VIVT cache of a highmem page is always flushed before the page
+ * is unmapped. Hence unmapped highmem pages need no cache maintenance
+ * in that case.
+ *
+ * However unmapped pages may still be cached with a VIPT cache, and
+ * it is not possible to perform cache maintenance on them using physical
+ * addresses unfortunately. So we have no choice but to set up a temporary
+ * virtual mapping for that purpose.
+ *
+ * Yet this VIPT cache maintenance may be triggered from DMA support
+ * functions which are possibly called from interrupt context. As we don't
+ * want to keep interrupt disabled all the time when such maintenance is
+ * taking place, we therefore allow for some reentrancy by preserving and
+ * restoring the previous fixmap entry before the interrupted context is
+ * resumed. If the reentrancy depth is 0 then there is no need to restore
+ * the previous fixmap, and leaving the current one in place allow it to
+ * be reused the next time without a TLB flush (common with DMA).
+ */
+
+static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
+
+void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
+{
+ unsigned int idx, cpu = smp_processor_id();
+ int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+ unsigned long vaddr, flags;
+ pte_t pte, *ptep;
+
+ idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ ptep = TOP_PTE(vaddr);
+ pte = mk_pte(page, kmap_prot);
+
+ if (!in_interrupt())
+ preempt_disable();
+
+ raw_local_irq_save(flags);
+ (*depth)++;
+ if (pte_val(*ptep) == pte_val(pte)) {
+ *saved_pte = pte;
+ } else {
+ *saved_pte = *ptep;
+ set_pte_ext(ptep, pte, 0);
+ local_flush_tlb_kernel_page(vaddr);
+ }
+ raw_local_irq_restore(flags);
+
+ return (void *)vaddr;
+}
+
+void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
+{
+ unsigned int idx, cpu = smp_processor_id();
+ int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+ unsigned long vaddr, flags;
+ pte_t pte, *ptep;
+
+ idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ ptep = TOP_PTE(vaddr);
+ pte = mk_pte(page, kmap_prot);
+
+ BUG_ON(pte_val(*ptep) != pte_val(pte));
+ BUG_ON(*depth <= 0);
+
+ raw_local_irq_save(flags);
+ (*depth)--;
+ if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
+ set_pte_ext(ptep, saved_pte, 0);
+ local_flush_tlb_kernel_page(vaddr);
+ }
+ raw_local_irq_restore(flags);
+
+ if (!in_interrupt())
+ preempt_enable();
+}
+
+#endif /* CONFIG_CPU_CACHE_VIPT */
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7829cb5425f..83db12a68d5 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -17,6 +17,7 @@
#include <linux/initrd.h>
#include <linux/sort.h>
#include <linux/highmem.h>
+#include <linux/gfp.h>
#include <asm/mach-types.h>
#include <asm/sections.h>
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9d4da6ac28e..241c24a1c18 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -420,6 +420,10 @@ static void __init build_mem_type_table(void)
user_pgprot |= L_PTE_SHARED;
kern_pgprot |= L_PTE_SHARED;
vecs_pgprot |= L_PTE_SHARED;
+ mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
+ mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
#endif
@@ -1050,10 +1054,12 @@ void setup_mm_for_reboot(char mode)
pgd_t *pgd;
int i;
- if (current->mm && current->mm->pgd)
- pgd = current->mm->pgd;
- else
- pgd = init_mm.pgd;
+ /*
+ * We need to access to user-mode page tables here. For kernel threads
+ * we don't have any user-mode mappings so we use the context that we
+ * "borrowed".
+ */
+ pgd = current->active_mm->pgd;
base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 2690146161b..be5f58e153b 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/highmem.h>
#include <asm/pgalloc.h>
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index ee7700242c1..5c47760c206 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -45,7 +45,7 @@ ENTRY(cpu_sa1100_proc_init)
mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland
mov pc, lr
- .previous
+ .section .text
/*
* cpu_sa1100_proc_fin()
diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S
index 48bca0db460..cafa1835433 100644
--- a/arch/arm/nwfpe/entry.S
+++ b/arch/arm/nwfpe/entry.S
@@ -111,12 +111,12 @@ next:
@ to fault. Emit the appropriate exception gunk to fix things up.
@ ??? For some reason, faults can happen at .Lx2 even with a
@ plain LDR instruction. Weird, but it seems harmless.
- .section .fixup,"ax"
+ .pushsection .fixup,"ax"
.align 2
.Lfix: mov pc, r9 @ let the user eat segfaults
- .previous
+ .popsection
- .section __ex_table,"a"
+ .pushsection __ex_table,"a"
.align 3
.long .Lx1, .Lfix
- .previous
+ .popsection
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 8b0a1ee039f..7f7ad6f289b 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -9,38 +9,43 @@ choice
config ARCH_MX1
bool "MX1-based"
select CPU_ARM920T
- select COMMON_CLKDEV
+ select IMX_HAVE_IOMUX_V1
help
This enables support for systems based on the Freescale i.MX1 family
config ARCH_MX2
bool "MX2-based"
select CPU_ARM926T
- select COMMON_CLKDEV
+ select IMX_HAVE_IOMUX_V1
help
This enables support for systems based on the Freescale i.MX2 family
config ARCH_MX25
bool "MX25-based"
select CPU_ARM926T
- select COMMON_CLKDEV
+ select ARCH_MXC_IOMUX_V3
+ select HAVE_FB_IMX
help
This enables support for systems based on the Freescale i.MX25 family
config ARCH_MX3
bool "MX3-based"
select CPU_V6
- select COMMON_CLKDEV
help
This enables support for systems based on the Freescale i.MX3 family
config ARCH_MXC91231
bool "MXC91231-based"
select CPU_V6
- select COMMON_CLKDEV
help
This enables support for systems based on the Freescale MXC91231 family
+config ARCH_MX5
+ bool "MX5-based"
+ select CPU_V7
+ help
+ This enables support for systems based on the Freescale i.MX51 family
+
endchoice
source "arch/arm/mach-mx1/Kconfig"
@@ -48,12 +53,12 @@ source "arch/arm/mach-mx2/Kconfig"
source "arch/arm/mach-mx3/Kconfig"
source "arch/arm/mach-mx25/Kconfig"
source "arch/arm/mach-mxc91231/Kconfig"
+source "arch/arm/mach-mx5/Kconfig"
endmenu
config MXC_IRQ_PRIOR
bool "Use IRQ priority"
- depends on ARCH_MXC
help
Select this if you want to use prioritized IRQ handling.
This feature prevents higher priority ISR to be interrupted
@@ -62,9 +67,16 @@ config MXC_IRQ_PRIOR
requirements for timing.
Say N here, unless you have a specialized requirement.
+config MXC_TZIC
+ bool "Enable TrustZone Interrupt Controller"
+ depends on ARCH_MX51
+ help
+ This will be automatically selected for all processors
+ containing this interrupt controller.
+ Say N here only if you are really sure.
+
config MXC_PWM
tristate "Enable PWM driver"
- depends on ARCH_MXC
select HAVE_PWM
help
Enable support for the i.MX PWM controller(s).
@@ -74,7 +86,9 @@ config MXC_ULPI
config ARCH_HAS_RNGA
bool
- depends on ARCH_MXC
+
+config IMX_HAVE_IOMUX_V1
+ bool
config ARCH_MXC_IOMUX_V3
bool
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 6cee38df58b..895bc3c5e0c 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -5,8 +5,12 @@
# Common support
obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
-obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
-obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.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
obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
diff --git a/arch/arm/plat-mxc/audmux-v1.c b/arch/arm/plat-mxc/audmux-v1.c
index da6387dcdf2..b62917ca3f9 100644
--- a/arch/arm/plat-mxc/audmux-v1.c
+++ b/arch/arm/plat-mxc/audmux-v1.c
@@ -50,8 +50,18 @@ EXPORT_SYMBOL_GPL(mxc_audmux_v1_configure_port);
static int mxc_audmux_v1_init(void)
{
- if (cpu_is_mx27() || cpu_is_mx21())
- audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR);
+#ifdef CONFIG_MACH_MX21
+ if (cpu_is_mx21())
+ audmux_base = MX21_IO_ADDRESS(MX21_AUDMUX_BASE_ADDR);
+ else
+#endif
+#ifdef CONFIG_MACH_MX27
+ if (cpu_is_mx27())
+ audmux_base = MX27_IO_ADDRESS(MX27_AUDMUX_BASE_ADDR);
+ else
+#endif
+ (void)0;
+
return 0;
}
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index b06954a8443..0c2cc5cd4d8 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <mach/audmux.h>
#include <mach/hardware.h>
@@ -190,7 +191,10 @@ static int mxc_audmux_v2_init(void)
{
int ret;
- if (cpu_is_mx35()) {
+ if (cpu_is_mx31())
+ audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
+
+ else if (cpu_is_mx35()) {
audmux_clk = clk_get(NULL, "audmux");
if (IS_ERR(audmux_clk)) {
ret = PTR_ERR(audmux_clk);
@@ -198,11 +202,9 @@ static int mxc_audmux_v2_init(void)
ret);
return ret;
}
+ audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
}
- if (cpu_is_mx31() || cpu_is_mx35())
- audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR);
-
audmux_debugfs_init();
return 0;
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 9e8fbd57495..323ff8ccc87 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -56,6 +56,7 @@ static void __clk_disable(struct clk *clk)
__clk_disable(clk->parent);
__clk_disable(clk->secondary);
+ WARN_ON(!clk->usecount);
if (!(--clk->usecount) && clk->disable)
clk->disable(clk);
}
diff --git a/arch/arm/plat-mxc/dma-mx1-mx2.c b/arch/arm/plat-mxc/dma-mx1-mx2.c
index 9c1b3f9c4f4..e16014b0d13 100644
--- a/arch/arm/plat-mxc/dma-mx1-mx2.c
+++ b/arch/arm/plat-mxc/dma-mx1-mx2.c
@@ -128,6 +128,18 @@ struct imx_dma_channel {
int hw_chaining;
};
+static void __iomem *imx_dmav1_baseaddr;
+
+static void imx_dmav1_writel(unsigned val, unsigned offset)
+{
+ __raw_writel(val, imx_dmav1_baseaddr + offset);
+}
+
+static unsigned imx_dmav1_readl(unsigned offset)
+{
+ return __raw_readl(imx_dmav1_baseaddr + offset);
+}
+
static struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
static struct clk *dma_clk;
@@ -140,7 +152,6 @@ static int imx_dma_hw_chain(struct imx_dma_channel *imxdma)
return 0;
}
-
/*
* imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
*/
@@ -160,17 +171,17 @@ static inline int imx_dma_sg_next(int channel, struct scatterlist *sg)
imxdma->resbytes -= now;
if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
- __raw_writel(sg->dma_address, DMA_BASE + DMA_DAR(channel));
+ imx_dmav1_writel(sg->dma_address, DMA_DAR(channel));
else
- __raw_writel(sg->dma_address, DMA_BASE + DMA_SAR(channel));
+ imx_dmav1_writel(sg->dma_address, DMA_SAR(channel));
- __raw_writel(now, DMA_BASE + DMA_CNTR(channel));
+ imx_dmav1_writel(now, DMA_CNTR(channel));
pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, "
"size 0x%08x\n", channel,
- __raw_readl(DMA_BASE + DMA_DAR(channel)),
- __raw_readl(DMA_BASE + DMA_SAR(channel)),
- __raw_readl(DMA_BASE + DMA_CNTR(channel)));
+ imx_dmav1_readl(DMA_DAR(channel)),
+ imx_dmav1_readl(DMA_SAR(channel)),
+ imx_dmav1_readl(DMA_CNTR(channel)));
return now;
}
@@ -218,27 +229,26 @@ imx_dma_setup_single(int channel, dma_addr_t dma_address,
channel, __func__, (unsigned int)dma_address,
dma_length, dev_addr);
- __raw_writel(dev_addr, DMA_BASE + DMA_SAR(channel));
- __raw_writel(dma_address, DMA_BASE + DMA_DAR(channel));
- __raw_writel(imxdma->ccr_from_device,
- DMA_BASE + DMA_CCR(channel));
+ imx_dmav1_writel(dev_addr, DMA_SAR(channel));
+ imx_dmav1_writel(dma_address, DMA_DAR(channel));
+ imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
"dev_addr=0x%08x for write\n",
channel, __func__, (unsigned int)dma_address,
dma_length, dev_addr);
- __raw_writel(dma_address, DMA_BASE + DMA_SAR(channel));
- __raw_writel(dev_addr, DMA_BASE + DMA_DAR(channel));
- __raw_writel(imxdma->ccr_to_device,
- DMA_BASE + DMA_CCR(channel));
+ imx_dmav1_writel(dma_address, DMA_SAR(channel));
+ imx_dmav1_writel(dev_addr, DMA_DAR(channel));
+ imx_dmav1_writel(imxdma->ccr_to_device,
+ DMA_CCR(channel));
} else {
printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
channel);
return -EINVAL;
}
- __raw_writel(dma_length, DMA_BASE + DMA_CNTR(channel));
+ imx_dmav1_writel(dma_length, DMA_CNTR(channel));
return 0;
}
@@ -316,17 +326,15 @@ imx_dma_setup_sg(int channel,
"dev_addr=0x%08x for read\n",
channel, __func__, sg, sgcount, dma_length, dev_addr);
- __raw_writel(dev_addr, DMA_BASE + DMA_SAR(channel));
- __raw_writel(imxdma->ccr_from_device,
- DMA_BASE + DMA_CCR(channel));
+ imx_dmav1_writel(dev_addr, DMA_SAR(channel));
+ imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
"dev_addr=0x%08x for write\n",
channel, __func__, sg, sgcount, dma_length, dev_addr);
- __raw_writel(dev_addr, DMA_BASE + DMA_DAR(channel));
- __raw_writel(imxdma->ccr_to_device,
- DMA_BASE + DMA_CCR(channel));
+ imx_dmav1_writel(dev_addr, DMA_DAR(channel));
+ imx_dmav1_writel(imxdma->ccr_to_device, DMA_CCR(channel));
} else {
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
channel);
@@ -360,7 +368,7 @@ imx_dma_config_channel(int channel, unsigned int config_port,
imxdma->ccr_from_device = config_port | (config_mem << 2) | dreq;
imxdma->ccr_to_device = config_mem | (config_port << 2) | dreq;
- __raw_writel(dmareq, DMA_BASE + DMA_RSSR(channel));
+ imx_dmav1_writel(dmareq, DMA_RSSR(channel));
return 0;
}
@@ -368,7 +376,7 @@ EXPORT_SYMBOL(imx_dma_config_channel);
void imx_dma_config_burstlen(int channel, unsigned int burstlen)
{
- __raw_writel(burstlen, DMA_BASE + DMA_BLR(channel));
+ imx_dmav1_writel(burstlen, DMA_BLR(channel));
}
EXPORT_SYMBOL(imx_dma_config_burstlen);
@@ -398,7 +406,7 @@ imx_dma_setup_handlers(int channel,
}
local_irq_save(flags);
- __raw_writel(1 << channel, DMA_BASE + DMA_DISR);
+ imx_dmav1_writel(1 << channel, DMA_DISR);
imxdma->irq_handler = irq_handler;
imxdma->err_handler = err_handler;
imxdma->data = data;
@@ -462,22 +470,21 @@ void imx_dma_enable(int channel)
local_irq_save(flags);
- __raw_writel(1 << channel, DMA_BASE + DMA_DISR);
- __raw_writel(__raw_readl(DMA_BASE + DMA_DIMR) & ~(1 << channel),
- DMA_BASE + DMA_DIMR);
- __raw_writel(__raw_readl(DMA_BASE + DMA_CCR(channel)) | CCR_CEN |
- CCR_ACRPT,
- DMA_BASE + DMA_CCR(channel));
+ imx_dmav1_writel(1 << channel, DMA_DISR);
+ imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) & ~(1 << channel), DMA_DIMR);
+ imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) | CCR_CEN |
+ CCR_ACRPT, DMA_CCR(channel));
#ifdef CONFIG_ARCH_MX2
- if (imxdma->sg && imx_dma_hw_chain(imxdma)) {
+ if ((cpu_is_mx21() || cpu_is_mx27()) &&
+ imxdma->sg && imx_dma_hw_chain(imxdma)) {
imxdma->sg = sg_next(imxdma->sg);
if (imxdma->sg) {
u32 tmp;
imx_dma_sg_next(channel, imxdma->sg);
- tmp = __raw_readl(DMA_BASE + DMA_CCR(channel));
- __raw_writel(tmp | CCR_RPT | CCR_ACRPT,
- DMA_BASE + DMA_CCR(channel));
+ tmp = imx_dmav1_readl(DMA_CCR(channel));
+ imx_dmav1_writel(tmp | CCR_RPT | CCR_ACRPT,
+ DMA_CCR(channel));
}
}
#endif
@@ -502,11 +509,10 @@ void imx_dma_disable(int channel)
del_timer(&imxdma->watchdog);
local_irq_save(flags);
- __raw_writel(__raw_readl(DMA_BASE + DMA_DIMR) | (1 << channel),
- DMA_BASE + DMA_DIMR);
- __raw_writel(__raw_readl(DMA_BASE + DMA_CCR(channel)) & ~CCR_CEN,
- DMA_BASE + DMA_CCR(channel));
- __raw_writel(1 << channel, DMA_BASE + DMA_DISR);
+ imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) | (1 << channel), DMA_DIMR);
+ imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) & ~CCR_CEN,
+ DMA_CCR(channel));
+ imx_dmav1_writel(1 << channel, DMA_DISR);
imxdma->in_use = 0;
local_irq_restore(flags);
}
@@ -517,7 +523,7 @@ static void imx_dma_watchdog(unsigned long chno)
{
struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
- __raw_writel(0, DMA_BASE + DMA_CCR(chno));
+ imx_dmav1_writel(0, DMA_CCR(chno));
imxdma->in_use = 0;
imxdma->sg = NULL;
@@ -533,17 +539,17 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id)
unsigned int err_mask;
int errcode;
- disr = __raw_readl(DMA_BASE + DMA_DISR);
+ disr = imx_dmav1_readl(DMA_DISR);
- err_mask = __raw_readl(DMA_BASE + DMA_DBTOSR) |
- __raw_readl(DMA_BASE + DMA_DRTOSR) |
- __raw_readl(DMA_BASE + DMA_DSESR) |
- __raw_readl(DMA_BASE + DMA_DBOSR);
+ err_mask = imx_dmav1_readl(DMA_DBTOSR) |
+ imx_dmav1_readl(DMA_DRTOSR) |
+ imx_dmav1_readl(DMA_DSESR) |
+ imx_dmav1_readl(DMA_DBOSR);
if (!err_mask)
return IRQ_HANDLED;
- __raw_writel(disr & err_mask, DMA_BASE + DMA_DISR);
+ imx_dmav1_writel(disr & err_mask, DMA_DISR);
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
if (!(err_mask & (1 << i)))
@@ -551,20 +557,20 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id)
imxdma = &imx_dma_channels[i];
errcode = 0;
- if (__raw_readl(DMA_BASE + DMA_DBTOSR) & (1 << i)) {
- __raw_writel(1 << i, DMA_BASE + DMA_DBTOSR);
+ if (imx_dmav1_readl(DMA_DBTOSR) & (1 << i)) {
+ imx_dmav1_writel(1 << i, DMA_DBTOSR);
errcode |= IMX_DMA_ERR_BURST;
}
- if (__raw_readl(DMA_BASE + DMA_DRTOSR) & (1 << i)) {
- __raw_writel(1 << i, DMA_BASE + DMA_DRTOSR);
+ if (imx_dmav1_readl(DMA_DRTOSR) & (1 << i)) {
+ imx_dmav1_writel(1 << i, DMA_DRTOSR);
errcode |= IMX_DMA_ERR_REQUEST;
}
- if (__raw_readl(DMA_BASE + DMA_DSESR) & (1 << i)) {
- __raw_writel(1 << i, DMA_BASE + DMA_DSESR);
+ if (imx_dmav1_readl(DMA_DSESR) & (1 << i)) {
+ imx_dmav1_writel(1 << i, DMA_DSESR);
errcode |= IMX_DMA_ERR_TRANSFER;
}
- if (__raw_readl(DMA_BASE + DMA_DBOSR) & (1 << i)) {
- __raw_writel(1 << i, DMA_BASE + DMA_DBOSR);
+ if (imx_dmav1_readl(DMA_DBOSR) & (1 << i)) {
+ imx_dmav1_writel(1 << i, DMA_DBOSR);
errcode |= IMX_DMA_ERR_BUFFER;
}
if (imxdma->name && imxdma->err_handler) {
@@ -607,7 +613,7 @@ static void dma_irq_handle_channel(int chno)
if (imxdma->sg) {
imx_dma_sg_next(chno, imxdma->sg);
- tmp = __raw_readl(DMA_BASE + DMA_CCR(chno));
+ tmp = imx_dmav1_readl(DMA_CCR(chno));
if (imx_dma_hw_chain(imxdma)) {
/* FIXME: The timeout should probably be
@@ -617,15 +623,13 @@ static void dma_irq_handle_channel(int chno)
jiffies + msecs_to_jiffies(500));
tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT;
- __raw_writel(tmp, DMA_BASE +
- DMA_CCR(chno));
+ imx_dmav1_writel(tmp, DMA_CCR(chno));
} else {
- __raw_writel(tmp & ~CCR_CEN, DMA_BASE +
- DMA_CCR(chno));
+ imx_dmav1_writel(tmp & ~CCR_CEN, DMA_CCR(chno));
tmp |= CCR_CEN;
}
- __raw_writel(tmp, DMA_BASE + DMA_CCR(chno));
+ imx_dmav1_writel(tmp, DMA_CCR(chno));
if (imxdma->prog_handler)
imxdma->prog_handler(chno, imxdma->data,
@@ -640,7 +644,7 @@ static void dma_irq_handle_channel(int chno)
}
}
- __raw_writel(0, DMA_BASE + DMA_CCR(chno));
+ imx_dmav1_writel(0, DMA_CCR(chno));
imxdma->in_use = 0;
if (imxdma->irq_handler)
imxdma->irq_handler(chno, imxdma->data);
@@ -651,15 +655,16 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
int i, disr;
#ifdef CONFIG_ARCH_MX2
- dma_err_handler(irq, dev_id);
+ if (cpu_is_mx21() || cpu_is_mx27())
+ dma_err_handler(irq, dev_id);
#endif
- disr = __raw_readl(DMA_BASE + DMA_DISR);
+ disr = imx_dmav1_readl(DMA_DISR);
pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
disr);
- __raw_writel(disr, DMA_BASE + DMA_DISR);
+ imx_dmav1_writel(disr, DMA_DISR);
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
if (disr & (1 << i))
dma_irq_handle_channel(i);
@@ -699,17 +704,19 @@ int imx_dma_request(int channel, const char *name)
local_irq_restore(flags); /* request_irq() can block */
#ifdef CONFIG_ARCH_MX2
- ret = request_irq(MXC_INT_DMACH0 + channel, dma_irq_handler, 0, "DMA",
- NULL);
- if (ret) {
- imxdma->name = NULL;
- printk(KERN_CRIT "Can't register IRQ %d for DMA channel %d\n",
- MXC_INT_DMACH0 + channel, channel);
- return ret;
+ if (cpu_is_mx21() || cpu_is_mx27()) {
+ ret = request_irq(MX2x_INT_DMACH0 + channel,
+ dma_irq_handler, 0, "DMA", NULL);
+ if (ret) {
+ imxdma->name = NULL;
+ pr_crit("Can't register IRQ %d for DMA channel %d\n",
+ MX2x_INT_DMACH0 + channel, channel);
+ return ret;
+ }
+ init_timer(&imxdma->watchdog);
+ imxdma->watchdog.function = &imx_dma_watchdog;
+ imxdma->watchdog.data = channel;
}
- init_timer(&imxdma->watchdog);
- imxdma->watchdog.function = &imx_dma_watchdog;
- imxdma->watchdog.data = channel;
#endif
return ret;
@@ -738,7 +745,8 @@ void imx_dma_free(int channel)
imxdma->name = NULL;
#ifdef CONFIG_ARCH_MX2
- free_irq(MXC_INT_DMACH0 + channel, NULL);
+ if (cpu_is_mx21() || cpu_is_mx27())
+ free_irq(MX2x_INT_DMACH0 + channel, NULL);
#endif
local_irq_restore(flags);
@@ -796,34 +804,53 @@ static int __init imx_dma_init(void)
int ret = 0;
int i;
+#ifdef CONFIG_ARCH_MX1
+ if (cpu_is_mx1())
+ imx_dmav1_baseaddr = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR);
+ else
+#endif
+#ifdef CONFIG_MACH_MX21
+ if (cpu_is_mx21())
+ imx_dmav1_baseaddr = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR);
+ else
+#endif
+#ifdef CONFIG_MACH_MX27
+ if (cpu_is_mx27())
+ imx_dmav1_baseaddr = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
+ else
+#endif
+ BUG();
+
dma_clk = clk_get(NULL, "dma");
clk_enable(dma_clk);
/* reset DMA module */
- __raw_writel(DCR_DRST, DMA_BASE + DMA_DCR);
+ imx_dmav1_writel(DCR_DRST, DMA_DCR);
#ifdef CONFIG_ARCH_MX1
- ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
- if (ret) {
- printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n");
- return ret;
- }
+ if (cpu_is_mx1()) {
+ ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", NULL);
+ if (ret) {
+ pr_crit("Wow! Can't register IRQ for DMA\n");
+ return ret;
+ }
- ret = request_irq(DMA_ERR, dma_err_handler, 0, "DMA", NULL);
- if (ret) {
- printk(KERN_CRIT "Wow! Can't register ERRIRQ for DMA\n");
- free_irq(DMA_INT, NULL);
- return ret;
+ ret = request_irq(MX1_DMA_ERR, dma_err_handler, 0, "DMA", NULL);
+ if (ret) {
+ pr_crit("Wow! Can't register ERRIRQ for DMA\n");
+ free_irq(MX1_DMA_INT, NULL);
+ return ret;
+ }
}
#endif
/* enable DMA module */
- __raw_writel(DCR_DEN, DMA_BASE + DMA_DCR);
+ imx_dmav1_writel(DCR_DEN, DMA_DCR);
/* clear all interrupts */
- __raw_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_BASE + DMA_DISR);
+ imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DISR);
/* disable interrupts */
- __raw_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_BASE + DMA_DIMR);
+ imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DIMR);
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
imx_dma_channels[i].sg = NULL;
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
index 41599be882e..cb0b6387448 100644
--- a/arch/arm/plat-mxc/ehci.c
+++ b/arch/arm/plat-mxc/ehci.c
@@ -25,25 +25,37 @@
#define USBCTRL_OTGBASE_OFFSET 0x600
#define MX31_OTG_SIC_SHIFT 29
-#define MX31_OTG_SIC_MASK (0xf << MX31_OTG_SIC_SHIFT)
+#define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT)
#define MX31_OTG_PM_BIT (1 << 24)
#define MX31_H2_SIC_SHIFT 21
-#define MX31_H2_SIC_MASK (0xf << MX31_H2_SIC_SHIFT)
+#define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT)
#define MX31_H2_PM_BIT (1 << 16)
#define MX31_H2_DT_BIT (1 << 5)
#define MX31_H1_SIC_SHIFT 13
-#define MX31_H1_SIC_MASK (0xf << MX31_H1_SIC_SHIFT)
+#define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT)
#define MX31_H1_PM_BIT (1 << 8)
#define MX31_H1_DT_BIT (1 << 4)
+#define MX35_OTG_SIC_SHIFT 29
+#define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT)
+#define MX35_OTG_PM_BIT (1 << 24)
+
+#define MX35_H1_SIC_SHIFT 21
+#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
+#define MX35_H1_PM_BIT (1 << 8)
+#define MX35_H1_IPPUE_UP_BIT (1 << 7)
+#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
+#define MX35_H1_TLL_BIT (1 << 5)
+#define MX35_H1_USBTE_BIT (1 << 4)
+
int mxc_set_usbcontrol(int port, unsigned int flags)
{
unsigned int v;
-
+#ifdef CONFIG_ARCH_MX3
if (cpu_is_mx31()) {
- v = readl(IO_ADDRESS(MX31_OTG_BASE_ADDR +
+ v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
switch (port) {
@@ -51,15 +63,15 @@ int mxc_set_usbcontrol(int port, unsigned int flags)
v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK)
<< MX31_OTG_SIC_SHIFT;
- if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX31_OTG_PM_BIT;
break;
case 1: /* H1 port */
- v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT);
+ v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK)
<< MX31_H1_SIC_SHIFT;
- if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
v |= MX31_H1_PM_BIT;
if (!(flags & MXC_EHCI_TTL_ENABLED))
@@ -67,7 +79,7 @@ int mxc_set_usbcontrol(int port, unsigned int flags)
break;
case 2: /* H2 port */
- v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT);
+ v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
v |= (flags & MXC_EHCI_INTERFACE_MASK)
<< MX31_H2_SIC_SHIFT;
if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
@@ -77,13 +89,103 @@ int mxc_set_usbcontrol(int port, unsigned int flags)
v |= MX31_H2_DT_BIT;
break;
+ default:
+ return -EINVAL;
}
- writel(v, IO_ADDRESS(MX31_OTG_BASE_ADDR +
+ writel(v, MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
return 0;
}
+ if (cpu_is_mx35()) {
+ v = readl(MX35_IO_ADDRESS(MX35_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, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
+ USBCTRL_OTGBASE_OFFSET));
+ return 0;
+ }
+#endif /* CONFIG_ARCH_MX3 */
+#ifdef CONFIG_MACH_MX27
+ if (cpu_is_mx27()) {
+ /* On i.MX27 we can use the i.MX31 USBCTRL bits, they
+ * are identical
+ */
+ v = readl(MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
+ USBCTRL_OTGBASE_OFFSET));
+ switch (port) {
+ case 0: /* OTG port */
+ v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK)
+ << MX31_OTG_SIC_SHIFT;
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX31_OTG_PM_BIT;
+ break;
+ case 1: /* H1 port */
+ v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK)
+ << MX31_H1_SIC_SHIFT;
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX31_H1_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX31_H1_DT_BIT;
+
+ break;
+ case 2: /* H2 port */
+ v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK)
+ << MX31_H2_SIC_SHIFT;
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX31_H2_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX31_H2_DT_BIT;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+ writel(v, MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR +
+ USBCTRL_OTGBASE_OFFSET));
+ return 0;
+ }
+#endif /* CONFIG_MACH_MX27 */
printk(KERN_WARNING
"%s() unable to setup USBCONTROL for this CPU\n", __func__);
return -EINVAL;
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index d65ebe303b9..70b23893f09 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -140,16 +140,13 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
val = __raw_readl(reg);
edge = (val >> (bit << 1)) & 3;
val &= ~(0x3 << (bit << 1));
- switch (edge) {
- case GPIO_INT_HIGH_LEV:
+ if (edge == GPIO_INT_HIGH_LEV) {
edge = GPIO_INT_LOW_LEV;
pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
- break;
- case GPIO_INT_LOW_LEV:
+ } else if (edge == GPIO_INT_LOW_LEV) {
edge = GPIO_INT_HIGH_LEV;
pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
- break;
- default:
+ } else {
pr_err("mxc: invalid configuration for GPIO %d: %x\n",
gpio, edge);
return;
@@ -157,25 +154,20 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
__raw_writel(val | (edge << (bit << 1)), reg);
}
-/* handle n interrupts in one status register */
+/* handle 32 interrupts in one status register */
static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
{
- u32 gpio_irq_no;
+ u32 gpio_irq_no_base = port->virtual_irq_start;
- gpio_irq_no = port->virtual_irq_start;
- for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) {
- u32 gpio = irq_to_gpio(gpio_irq_no);
-
- if ((irq_stat & 1) == 0)
- continue;
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
- BUG_ON(!(irq_desc[gpio_irq_no].handle_irq));
+ if (port->both_edges & (1 << irqoffset))
+ mxc_flip_edge(port, irqoffset);
- if (port->both_edges & (1 << (gpio & 31)))
- mxc_flip_edge(port, gpio);
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
- irq_desc[gpio_irq_no].handle_irq(gpio_irq_no,
- &irq_desc[gpio_irq_no]);
+ irq_stat &= ~(1 << irqoffset);
}
}
diff --git a/arch/arm/plat-mxc/include/mach/board-kzmarm11.h b/arch/arm/plat-mxc/include/mach/board-kzmarm11.h
index 05ff2f31ef1..93cc66f104c 100644
--- a/arch/arm/plat-mxc/include/mach/board-kzmarm11.h
+++ b/arch/arm/plat-mxc/include/mach/board-kzmarm11.h
@@ -21,19 +21,19 @@
/*
* KZM-ARM11-01 Board Control Registers on FPGA
*/
-#define KZM_ARM11_CTL1 (CS4_BASE_ADDR + 0x1000)
-#define KZM_ARM11_CTL2 (CS4_BASE_ADDR + 0x1001)
-#define KZM_ARM11_RSW1 (CS4_BASE_ADDR + 0x1002)
-#define KZM_ARM11_BACK_LIGHT (CS4_BASE_ADDR + 0x1004)
-#define KZM_ARM11_FPGA_REV (CS4_BASE_ADDR + 0x1008)
-#define KZM_ARM11_7SEG_LED (CS4_BASE_ADDR + 0x1010)
-#define KZM_ARM11_LEDS (CS4_BASE_ADDR + 0x1020)
-#define KZM_ARM11_DIPSW2 (CS4_BASE_ADDR + 0x1003)
+#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 (CS4_BASE_ADDR + 0x1050)
+#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-mx31_3ds.h b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
new file mode 100644
index 00000000000..da92933a233
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
@@ -0,0 +1,59 @@
+/*
+ * 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
index 2cbfa35e82f..095a199591c 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
@@ -14,7 +14,7 @@
#include <mach/hardware.h>
/* Base address of PBC controller */
-#define PBC_BASE_ADDRESS IO_ADDRESS(CS4_BASE_ADDR)
+#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
/* Offsets for the PBC Controller register */
/* PBC Board status register offset */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
index d5be6b5a6ac..fc5fec9b55f 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
@@ -25,6 +25,7 @@ enum mx31moboard_boards {
MX31NOBOARD = 0,
MX31DEVBOARD = 1,
MX31MARXBOT = 2,
+ MX31SMARTBOT = 3,
};
/*
@@ -34,6 +35,7 @@ enum mx31moboard_boards {
extern void mx31moboard_devboard_init(void);
extern void mx31moboard_marxbot_init(void);
+extern void mx31moboard_smartbot_init(void);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
deleted file mode 100644
index 2bbd6ed17f5..00000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx31pdk.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_MX31PDK_H__
-#define __ASM_ARCH_MXC_BOARD_MX31PDK_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_MX31PDK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index 43a82d0c534..753a5988d85 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -26,13 +26,6 @@
struct module;
struct clk {
-#ifndef CONFIG_COMMON_CLKDEV
- /* As soon as i.MX1 and i.MX31 switched to clkdev, this
- * block can go away */
- struct list_head node;
- struct module *owner;
- const char *name;
-#endif
int id;
/* Source clock this clk depends on */
struct clk *parent;
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 4bf1068ffad..2941472582d 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -20,14 +20,17 @@ extern void mx25_map_io(void);
extern void mx27_map_io(void);
extern void mx31_map_io(void);
extern void mx35_map_io(void);
+extern void mx51_map_io(void);
extern void mxc91231_map_io(void);
extern void mxc_init_irq(void __iomem *);
+extern void tzic_init_irq(void __iomem *);
extern void mx1_init_irq(void);
extern void mx21_init_irq(void);
extern void mx25_init_irq(void);
extern void mx27_init_irq(void);
extern void mx31_init_irq(void);
extern void mx35_init_irq(void);
+extern void mx51_init_irq(void);
extern void mxc91231_init_irq(void);
extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
extern int mx1_clocks_init(unsigned long fref);
@@ -36,6 +39,8 @@ extern int mx25_clocks_init(void);
extern int mx27_clocks_init(unsigned long fref);
extern int mx31_clocks_init(unsigned long fref);
extern int mx35_clocks_init(void);
+extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2);
extern int mxc91231_clocks_init(unsigned long fref);
extern int mxc_register_gpios(void);
extern int mxc_register_device(struct platform_device *pdev, void *data);
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 5a6ae1b9e1e..0b6e11eaeb8 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -10,6 +10,7 @@
* published by the Free Software Foundation.
*
*/
+#define IMX_NEEDS_DEPRECATED_SYMBOLS
#ifdef CONFIG_ARCH_MX1
#include <mach/mx1.h>
@@ -44,13 +45,22 @@
#define UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
#endif
+#ifdef CONFIG_ARCH_MX5
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#include <mach/mx51.h>
+#define UART_PADDR MX51_UART1_BASE_ADDR
+#define UART_VADDR MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR)
+#endif
+
#ifdef CONFIG_ARCH_MXC91231
#ifdef UART_PADDR
#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
#endif
#include <mach/mxc91231.h>
#define UART_PADDR MXC91231_UART2_BASE_ADDR
-#define UART_VADDR MXC91231_AIPS1_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
+#define UART_VADDR MXC91231_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
#endif
.macro addruart, rx, tmp
mrc p15, 0, \rx, c1, c0
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index 7cf290efe76..aeb08697726 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -18,11 +18,16 @@
.endm
.macro get_irqnr_preamble, base, tmp
+#ifndef CONFIG_MXC_TZIC
ldr \base, =avic_base
ldr \base, [\base]
#ifdef CONFIG_MXC_IRQ_PRIOR
ldr r4, [\base, #AVIC_NIMASK]
#endif
+#elif defined CONFIG_MXC_TZIC
+ ldr \base, =tzic_base
+ ldr \base, [\base]
+#endif /* CONFIG_MXC_TZIC */
.endm
.macro arch_ret_to_user, tmp1, tmp2
@@ -32,6 +37,7 @@
@ and returns its number in irqnr
@ and returns if an interrupt occured in irqstat
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+#ifndef CONFIG_MXC_TZIC
@ Load offset & priority of the highest priority
@ interrupt pending from AVIC_NIVECSR
ldr \irqstat, [\base, #0x40]
@@ -45,6 +51,32 @@
strne \tmp, [\base, #AVIC_NIMASK]
streq r4, [\base, #AVIC_NIMASK]
#endif
+#elif defined CONFIG_MXC_TZIC
+ @ Load offset & priority of the highest priority
+ @ interrupt pending.
+ @ 0xD80 is HIPND0 register
+ mov \irqnr, #0
+ mov \irqstat, #0x0D80
+1000:
+ ldr \tmp, [\irqstat, \base]
+ cmp \tmp, #0
+ bne 1001f
+ addeq \irqnr, \irqnr, #32
+ addeq \irqstat, \irqstat, #4
+ cmp \irqnr, #128
+ blo 1000b
+ b 2001f
+1001: mov \irqstat, #1
+1002: tst \tmp, \irqstat
+ bne 2002f
+ movs \tmp, \tmp, lsr #1
+ addne \irqnr, \irqnr, #1
+ bne 1002b
+2001:
+ mov \irqnr, #0
+2002:
+ movs \irqnr, \irqnr
+#endif
.endm
@ irq priority table (not used)
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index 78db75475f6..ebadf4ac43f 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -22,6 +22,15 @@
#include <asm/sizes.h>
+#define IMX_IO_ADDRESS(addr, module) \
+ ((void __force __iomem *) \
+ (((unsigned long)((addr) - (module ## _BASE_ADDR)) < module ## _SIZE) ?\
+ (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0))
+
+#ifdef CONFIG_ARCH_MX5
+#include <mach/mx51.h>
+#endif
+
#ifdef CONFIG_ARCH_MX3
#include <mach/mx3x.h>
#include <mach/mx31.h>
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1.h b/arch/arm/plat-mxc/include/mach/iomux-mx1.h
index bf23305c19c..6b1507cf378 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx1.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx1.h
@@ -1,166 +1,155 @@
/*
-* Copyright (C) 2008 by Sascha Hauer <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.
-*/
+ * Copyright (C) 2008 by Sascha Hauer <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 __MACH_IOMUX_MX1_H__
+#define __MACH_IOMUX_MX1_H__
-#ifndef _MXC_IOMUX_MX1_H
-#define _MXC_IOMUX_MX1_H
+#include <mach/iomux-v1.h>
-#ifndef GPIO_PORTA
-#error Please include mach/iomux.h
-#endif
+#define PA0_AIN_SPI2_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
+#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0)
+#define PA1_AOUT_SPI2_RXD (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 1)
+#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 2)
+#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4)
+#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5)
+#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6)
+#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7)
+#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8)
+#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9)
+#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10)
+#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11)
+#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12)
+#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13)
+#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14)
+#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17)
+#define PA17_AIN_SPI2_SS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
+#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18)
+#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19)
+#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20)
+#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21)
+#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22)
+#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23)
+#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24)
+#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24)
+#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25)
+#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25)
+#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26)
+#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26)
+#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27)
+#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27)
+#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28)
+#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28)
+#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29)
+#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29)
+#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30)
+#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30)
+#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31)
+#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31)
+#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8)
+#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8)
+#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9)
+#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9)
+#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10)
+#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10)
+#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11)
+#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11)
+#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12)
+#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12)
+#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13)
+#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13)
+#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14)
+#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15)
+#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_AF | GPIO_IN | 16)
+#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_AF | GPIO_OUT | 17)
+#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18)
+#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19)
+#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20)
+#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21)
+#define PB22_PF_USBD_RCV (GPIO_PORTB | GPIO_PF | 22)
+#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24)
+#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25)
+#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_PF | GPIO_OUT | 28)
+#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_PF | GPIO_IN | 29)
+#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_PF | GPIO_OUT | 30)
+#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_PF | GPIO_IN | 31)
+#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3)
+#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4)
+#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
+#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_PF | GPIO_OUT | 6)
+#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7)
+#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8)
+#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
+#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_PF | GPIO_IN | 10)
+#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
+#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 12)
+#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13)
+#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14)
+#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15)
+#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16)
+#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17)
+#define PC24_BIN_UART3_RI (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 24)
+#define PC25_BIN_UART3_DSR (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 25)
+#define PC26_AOUT_UART3_DTR (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 26)
+#define PC27_BIN_UART3_DCD (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 27)
+#define PC28_BIN_UART3_CTS (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 28)
+#define PC29_AOUT_UART3_RTS (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 29)
+#define PC30_BIN_UART3_TX (GPIO_PORTC | GPIO_BIN | 30)
+#define PC31_AOUT_UART3_RX (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 31)
+#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 6)
+#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7)
+#define PD7_AF_UART2_DTR (GPIO_PORTD | GPIO_AF | GPIO_IN | 7)
+#define PD7_AIN_SPI2_SCLK (GPIO_PORTD | GPIO_AIN | 7)
+#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8)
+#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_AF | GPIO_OUT | 8)
+#define PD8_AIN_SPI2_SS (GPIO_PORTD | GPIO_AIN | 8)
+#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9)
+#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_AF | GPIO_OUT | 9)
+#define PD9_AOUT_SPI2_RXD (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 9)
+#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_PF | GPIO_OUT | 10)
+#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_AF | GPIO_OUT | 10)
+#define PD10_AIN_SPI2_TXD (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 10)
+#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_PF | GPIO_OUT | 11)
+#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_PF | GPIO_OUT | 12)
+#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 13)
+#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 14)
+#define PD15_PF_LD0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 15)
+#define PD16_PF_LD1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 16)
+#define PD17_PF_LD2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
+#define PD18_PF_LD3 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
+#define PD19_PF_LD4 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
+#define PD20_PF_LD5 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
+#define PD21_PF_LD6 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
+#define PD22_PF_LD7 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
+#define PD23_PF_LD8 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 23)
+#define PD24_PF_LD9 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
+#define PD25_PF_LD10 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
+#define PD26_PF_LD11 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
+#define PD27_PF_LD12 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
+#define PD28_PF_LD13 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
+#define PD29_PF_LD14 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
+#define PD30_PF_LD15 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 30)
+#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31)
+#define PD31_BIN_SPI2_TXD (GPIO_PORTD | GPIO_BIN | 31)
-/* FIXME: This list is not completed. The correct directions are
-* missing on some (many) pins
-*/
-
-
-/* Primary GPIO pin functions */
-
-#define PA0_AIN_SPI2_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
-#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0)
-#define PA1_AOUT_SPI2_RXD (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 1)
-#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1)
-#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 2)
-#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3)
-#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4)
-#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5)
-#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6)
-#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7)
-#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8)
-#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9)
-#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10)
-#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11)
-#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12)
-#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13)
-#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14)
-#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
-#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
-#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17)
-#define PA17_AIN_SPI2_SS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
-#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18)
-#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19)
-#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20)
-#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21)
-#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22)
-#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23)
-#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24)
-#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24)
-#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25)
-#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25)
-#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26)
-#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26)
-#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27)
-#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27)
-#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28)
-#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28)
-#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29)
-#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29)
-#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30)
-#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30)
-#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31)
-#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31)
-#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8)
-#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8)
-#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9)
-#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9)
-#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10)
-#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10)
-#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11)
-#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11)
-#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12)
-#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12)
-#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13)
-#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13)
-#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14)
-#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15)
-#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_AF | GPIO_IN | 16)
-#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_AF | GPIO_OUT | 17)
-#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18)
-#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19)
-#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20)
-#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21)
-#define PB22_PF_USBD_RCV (GPIO_PORTB | GPIO_PF | 22)
-#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23)
-#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24)
-#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25)
-#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26)
-#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27)
-#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_PF | GPIO_OUT | 28)
-#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_PF | GPIO_IN | 29)
-#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_PF | GPIO_OUT | 30)
-#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_PF | GPIO_IN | 31)
-#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3)
-#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4)
-#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
-#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_PF | GPIO_OUT | 6)
-#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7)
-#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8)
-#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
-#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_PF | GPIO_IN | 10)
-#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
-#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 12)
-#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13)
-#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14)
-#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15)
-#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16)
-#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17)
-#define PC24_BIN_UART3_RI (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 24)
-#define PC25_BIN_UART3_DSR (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 25)
-#define PC26_AOUT_UART3_DTR (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 26)
-#define PC27_BIN_UART3_DCD (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 27)
-#define PC28_BIN_UART3_CTS (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 28)
-#define PC29_AOUT_UART3_RTS (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 29)
-#define PC30_BIN_UART3_TX (GPIO_PORTC | GPIO_BIN | 30)
-#define PC31_AOUT_UART3_RX (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 31)
-#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 6)
-#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7)
-#define PD7_AF_UART2_DTR (GPIO_PORTD | GPIO_AF | GPIO_IN | 7)
-#define PD7_AIN_SPI2_SCLK (GPIO_PORTD | GPIO_AIN | 7)
-#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8)
-#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_AF | GPIO_OUT | 8)
-#define PD8_AIN_SPI2_SS (GPIO_PORTD | GPIO_AIN | 8)
-#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9)
-#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_AF | GPIO_OUT | 9)
-#define PD9_AOUT_SPI2_RXD (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 9)
-#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_PF | GPIO_OUT | 10)
-#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_AF | GPIO_OUT | 10)
-#define PD10_AIN_SPI2_TXD (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 10)
-#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_PF | GPIO_OUT | 11)
-#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_PF | GPIO_OUT | 12)
-#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 13)
-#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 14)
-#define PD15_PF_LD0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 15)
-#define PD16_PF_LD1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 16)
-#define PD17_PF_LD2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
-#define PD18_PF_LD3 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
-#define PD19_PF_LD4 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
-#define PD20_PF_LD5 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
-#define PD21_PF_LD6 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
-#define PD22_PF_LD7 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
-#define PD23_PF_LD8 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 23)
-#define PD24_PF_LD9 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
-#define PD25_PF_LD10 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
-#define PD26_PF_LD11 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
-#define PD27_PF_LD12 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
-#define PD28_PF_LD13 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
-#define PD29_PF_LD14 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
-#define PD30_PF_LD15 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 30)
-#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31)
-#define PD31_BIN_SPI2_TXD (GPIO_PORTD | GPIO_BIN | 31)
-
-
-#endif
+#endif /* ifndef __MACH_IOMUX_MX1_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx21.h b/arch/arm/plat-mxc/include/mach/iomux-mx21.h
index 63aaa972e27..1495dfda783 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx21.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx21.h
@@ -1,126 +1,122 @@
/*
-* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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 _MXC_IOMUX_MX21_H
-#define _MXC_IOMUX_MX21_H
-
-#ifndef GPIO_PORTA
-#error Please include mach/iomux.h
-#endif
-
+ * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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 __MACH_IOMUX_MX21_H__
+#define __MACH_IOMUX_MX21_H__
+
+#include <mach/iomux-mx2x.h>
+#include <mach/iomux-v1.h>
/* Primary GPIO pin functions */
-#define PB22_PF_USBH1_BYP (GPIO_PORTB | GPIO_PF | 22)
-#define PB25_PF_USBH1_ON (GPIO_PORTB | GPIO_PF | 25)
-#define PC5_PF_USBOTG_SDA (GPIO_PORTC | GPIO_PF | 5)
-#define PC6_PF_USBOTG_SCL (GPIO_PORTC | GPIO_PF | 6)
-#define PC7_PF_USBOTG_ON (GPIO_PORTC | GPIO_PF | 7)
-#define PC8_PF_USBOTG_FS (GPIO_PORTC | GPIO_PF | 8)
-#define PC9_PF_USBOTG_OE (GPIO_PORTC | GPIO_PF | 9)
-#define PC10_PF_USBOTG_TXDM (GPIO_PORTC | GPIO_PF | 10)
-#define PC11_PF_USBOTG_TXDP (GPIO_PORTC | GPIO_PF | 11)
-#define PC12_PF_USBOTG_RXDM (GPIO_PORTC | GPIO_PF | 12)
-#define PC13_PF_USBOTG_RXDP (GPIO_PORTC | GPIO_PF | 13)
-#define PC16_PF_SAP_FS (GPIO_PORTC | GPIO_PF | 16)
-#define PC17_PF_SAP_RXD (GPIO_PORTC | GPIO_PF | 17)
-#define PC18_PF_SAP_TXD (GPIO_PORTC | GPIO_PF | 18)
-#define PC19_PF_SAP_CLK (GPIO_PORTC | GPIO_PF | 19)
-#define PE0_PF_TEST_WB2 (GPIO_PORTE | GPIO_PF | 0)
-#define PE1_PF_TEST_WB1 (GPIO_PORTE | GPIO_PF | 1)
-#define PE2_PF_TEST_WB0 (GPIO_PORTE | GPIO_PF | 2)
-#define PF1_PF_NFCE (GPIO_PORTF | GPIO_PF | 1)
-#define PF3_PF_NFCLE (GPIO_PORTF | GPIO_PF | 3)
-#define PF7_PF_NFIO0 (GPIO_PORTF | GPIO_PF | 7)
-#define PF8_PF_NFIO1 (GPIO_PORTF | GPIO_PF | 8)
-#define PF9_PF_NFIO2 (GPIO_PORTF | GPIO_PF | 9)
-#define PF10_PF_NFIO3 (GPIO_PORTF | GPIO_PF | 10)
-#define PF11_PF_NFIO4 (GPIO_PORTF | GPIO_PF | 11)
-#define PF12_PF_NFIO5 (GPIO_PORTF | GPIO_PF | 12)
-#define PF13_PF_NFIO6 (GPIO_PORTF | GPIO_PF | 13)
-#define PF14_PF_NFIO7 (GPIO_PORTF | GPIO_PF | 14)
-#define PF16_PF_RES (GPIO_PORTF | GPIO_PF | 16)
+#define PB22_PF_USBH1_BYP (GPIO_PORTB | GPIO_PF | 22)
+#define PB25_PF_USBH1_ON (GPIO_PORTB | GPIO_PF | 25)
+#define PC5_PF_USBOTG_SDA (GPIO_PORTC | GPIO_PF | 5)
+#define PC6_PF_USBOTG_SCL (GPIO_PORTC | GPIO_PF | 6)
+#define PC7_PF_USBOTG_ON (GPIO_PORTC | GPIO_PF | 7)
+#define PC8_PF_USBOTG_FS (GPIO_PORTC | GPIO_PF | 8)
+#define PC9_PF_USBOTG_OE (GPIO_PORTC | GPIO_PF | 9)
+#define PC10_PF_USBOTG_TXDM (GPIO_PORTC | GPIO_PF | 10)
+#define PC11_PF_USBOTG_TXDP (GPIO_PORTC | GPIO_PF | 11)
+#define PC12_PF_USBOTG_RXDM (GPIO_PORTC | GPIO_PF | 12)
+#define PC13_PF_USBOTG_RXDP (GPIO_PORTC | GPIO_PF | 13)
+#define PC16_PF_SAP_FS (GPIO_PORTC | GPIO_PF | 16)
+#define PC17_PF_SAP_RXD (GPIO_PORTC | GPIO_PF | 17)
+#define PC18_PF_SAP_TXD (GPIO_PORTC | GPIO_PF | 18)
+#define PC19_PF_SAP_CLK (GPIO_PORTC | GPIO_PF | 19)
+#define PE0_PF_TEST_WB2 (GPIO_PORTE | GPIO_PF | 0)
+#define PE1_PF_TEST_WB1 (GPIO_PORTE | GPIO_PF | 1)
+#define PE2_PF_TEST_WB0 (GPIO_PORTE | GPIO_PF | 2)
+#define PF1_PF_NFCE (GPIO_PORTF | GPIO_PF | 1)
+#define PF3_PF_NFCLE (GPIO_PORTF | GPIO_PF | 3)
+#define PF7_PF_NFIO0 (GPIO_PORTF | GPIO_PF | 7)
+#define PF8_PF_NFIO1 (GPIO_PORTF | GPIO_PF | 8)
+#define PF9_PF_NFIO2 (GPIO_PORTF | GPIO_PF | 9)
+#define PF10_PF_NFIO3 (GPIO_PORTF | GPIO_PF | 10)
+#define PF11_PF_NFIO4 (GPIO_PORTF | GPIO_PF | 11)
+#define PF12_PF_NFIO5 (GPIO_PORTF | GPIO_PF | 12)
+#define PF13_PF_NFIO6 (GPIO_PORTF | GPIO_PF | 13)
+#define PF14_PF_NFIO7 (GPIO_PORTF | GPIO_PF | 14)
+#define PF16_PF_RES (GPIO_PORTF | GPIO_PF | 16)
/* Alternate GPIO pin functions */
-#define PA5_AF_BMI_CLK_CS (GPIO_PORTA | GPIO_AF | 5)
-#define PA6_AF_BMI_D0 (GPIO_PORTA | GPIO_AF | 6)
-#define PA7_AF_BMI_D1 (GPIO_PORTA | GPIO_AF | 7)
-#define PA8_AF_BMI_D2 (GPIO_PORTA | GPIO_AF | 8)
-#define PA9_AF_BMI_D3 (GPIO_PORTA | GPIO_AF | 9)
-#define PA10_AF_BMI_D4 (GPIO_PORTA | GPIO_AF | 10)
-#define PA11_AF_BMI_D5 (GPIO_PORTA | GPIO_AF | 11)
-#define PA12_AF_BMI_D6 (GPIO_PORTA | GPIO_AF | 12)
-#define PA13_AF_BMI_D7 (GPIO_PORTA | GPIO_AF | 13)
-#define PA14_AF_BMI_D8 (GPIO_PORTA | GPIO_AF | 14)
-#define PA15_AF_BMI_D9 (GPIO_PORTA | GPIO_AF | 15)
-#define PA16_AF_BMI_D10 (GPIO_PORTA | GPIO_AF | 16)
-#define PA17_AF_BMI_D11 (GPIO_PORTA | GPIO_AF | 17)
-#define PA18_AF_BMI_D12 (GPIO_PORTA | GPIO_AF | 18)
-#define PA19_AF_BMI_D13 (GPIO_PORTA | GPIO_AF | 19)
-#define PA20_AF_BMI_D14 (GPIO_PORTA | GPIO_AF | 20)
-#define PA21_AF_BMI_D15 (GPIO_PORTA | GPIO_AF | 21)
-#define PA22_AF_BMI_READ_REQ (GPIO_PORTA | GPIO_AF | 22)
-#define PA23_AF_BMI_WRITE (GPIO_PORTA | GPIO_AF | 23)
-#define PA29_AF_BMI_RX_FULL (GPIO_PORTA | GPIO_AF | 29)
-#define PA30_AF_BMI_READ (GPIO_PORTA | GPIO_AF | 30)
+#define PA5_AF_BMI_CLK_CS (GPIO_PORTA | GPIO_AF | 5)
+#define PA6_AF_BMI_D0 (GPIO_PORTA | GPIO_AF | 6)
+#define PA7_AF_BMI_D1 (GPIO_PORTA | GPIO_AF | 7)
+#define PA8_AF_BMI_D2 (GPIO_PORTA | GPIO_AF | 8)
+#define PA9_AF_BMI_D3 (GPIO_PORTA | GPIO_AF | 9)
+#define PA10_AF_BMI_D4 (GPIO_PORTA | GPIO_AF | 10)
+#define PA11_AF_BMI_D5 (GPIO_PORTA | GPIO_AF | 11)
+#define PA12_AF_BMI_D6 (GPIO_PORTA | GPIO_AF | 12)
+#define PA13_AF_BMI_D7 (GPIO_PORTA | GPIO_AF | 13)
+#define PA14_AF_BMI_D8 (GPIO_PORTA | GPIO_AF | 14)
+#define PA15_AF_BMI_D9 (GPIO_PORTA | GPIO_AF | 15)
+#define PA16_AF_BMI_D10 (GPIO_PORTA | GPIO_AF | 16)
+#define PA17_AF_BMI_D11 (GPIO_PORTA | GPIO_AF | 17)
+#define PA18_AF_BMI_D12 (GPIO_PORTA | GPIO_AF | 18)
+#define PA19_AF_BMI_D13 (GPIO_PORTA | GPIO_AF | 19)
+#define PA20_AF_BMI_D14 (GPIO_PORTA | GPIO_AF | 20)
+#define PA21_AF_BMI_D15 (GPIO_PORTA | GPIO_AF | 21)
+#define PA22_AF_BMI_READ_REQ (GPIO_PORTA | GPIO_AF | 22)
+#define PA23_AF_BMI_WRITE (GPIO_PORTA | GPIO_AF | 23)
+#define PA29_AF_BMI_RX_FULL (GPIO_PORTA | GPIO_AF | 29)
+#define PA30_AF_BMI_READ (GPIO_PORTA | GPIO_AF | 30)
/* AIN GPIO pin functions */
-#define PC14_AIN_SYS_CLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
-#define PD21_AIN_USBH2_FS (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 21)
-#define PD22_AIN_USBH2_OE (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 22)
-#define PD23_AIN_USBH2_TXDM (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 23)
-#define PD24_AIN_USBH2_TXDP (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 24)
-#define PE8_AIN_IR_TXD (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 8)
-#define PF0_AIN_PC_RST (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 0)
-#define PF1_AIN_PC_CE1 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 1)
-#define PF2_AIN_PC_CE2 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 2)
-#define PF3_AIN_PC_POE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 3)
-#define PF4_AIN_PC_OE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 4)
-#define PF5_AIN_PC_RW (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 5)
+#define PC14_AIN_SYS_CLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
+#define PD21_AIN_USBH2_FS (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 21)
+#define PD22_AIN_USBH2_OE (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 22)
+#define PD23_AIN_USBH2_TXDM (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 23)
+#define PD24_AIN_USBH2_TXDP (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 24)
+#define PE8_AIN_IR_TXD (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 8)
+#define PF0_AIN_PC_RST (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 0)
+#define PF1_AIN_PC_CE1 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 1)
+#define PF2_AIN_PC_CE2 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 2)
+#define PF3_AIN_PC_POE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 3)
+#define PF4_AIN_PC_OE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 4)
+#define PF5_AIN_PC_RW (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 5)
/* BIN GPIO pin functions */
-#define PC14_BIN_SYS_CLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
-#define PD27_BIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_BIN | GPIO_OUT | 27)
+#define PC14_BIN_SYS_CLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
+#define PD27_BIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_BIN | GPIO_OUT | 27)
/* CIN GPIO pin functions */
-#define PB26_CIN_USBH1_RXDAT (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 26)
+#define PB26_CIN_USBH1_RXDAT (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 26)
/* AOUT GPIO pin functions */
-#define PA29_AOUT_BMI_WAIT (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 29)
-#define PD19_AOUT_USBH2_RXDM (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 19)
-#define PD20_AOUT_USBH2_RXDP (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 20)
-#define PD25_AOUT_EXT_DMAREQ (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 25)
-#define PD26_AOUT_USBOTG_RXDAT (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 26)
-#define PE9_AOUT_IR_RXD (GPIO_PORTE | GPIO_AOUT | GPIO_IN | 9)
-#define PF6_AOUT_PC_BVD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 6)
-#define PF7_AOUT_PC_BVD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 7)
-#define PF8_AOUT_PC_VS2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 8)
-#define PF9_AOUT_PC_VS1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 9)
-#define PF10_AOUT_PC_WP (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 10)
-#define PF11_AOUT_PC_READY (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 11)
-#define PF12_AOUT_PC_WAIT (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 12)
-#define PF13_AOUT_PC_CD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 13)
-#define PF14_AOUT_PC_CD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 14)
-
-
-#endif
+#define PA29_AOUT_BMI_WAIT (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 29)
+#define PD19_AOUT_USBH2_RXDM (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 19)
+#define PD20_AOUT_USBH2_RXDP (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 20)
+#define PD25_AOUT_EXT_DMAREQ (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 25)
+#define PD26_AOUT_USBOTG_RXDAT (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 26)
+#define PE9_AOUT_IR_RXD (GPIO_PORTE | GPIO_AOUT | GPIO_IN | 9)
+#define PF6_AOUT_PC_BVD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 6)
+#define PF7_AOUT_PC_BVD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 7)
+#define PF8_AOUT_PC_VS2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 8)
+#define PF9_AOUT_PC_VS1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 9)
+#define PF10_AOUT_PC_WP (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 10)
+#define PF11_AOUT_PC_READY (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 11)
+#define PF12_AOUT_PC_WAIT (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 12)
+#define PF13_AOUT_PC_CD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 13)
+#define PF14_AOUT_PC_CD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 14)
+
+#endif /* ifndef __MACH_IOMUX_MX21_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
index 9af494f0ab3..f39220d1b67 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
@@ -7,7 +7,7 @@
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
* and
* arch/arm/plat-mxc/include/mach/iomux-mx35.h
- * Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -16,24 +16,11 @@
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
-#ifndef __IOMUX_MX25_H__
-#define __IOMUX_MX25_H__
+#ifndef __MACH_IOMUX_MX25_H__
+#define __MACH_IOMUX_MX25_H__
#include <mach/iomux-v3.h>
-#ifndef GPIO_PORTA
-#error Please include mach/iomux.h
-#endif
-
-/*
- *
- * @brief MX25 I/O Pin List
- *
- * @ingroup GPIO_MX25
- */
-
-#ifndef __ASSEMBLY__
-
/*
* IOMUX/PAD Bit field definitions
*/
@@ -462,9 +449,11 @@
#define MX25_PAD_GPIO_C__CAN2_TX IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
#define MX25_PAD_GPIO_D__GPIO_D IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_E__LD16 IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_D__CAN2_RX IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP)
#define MX25_PAD_GPIO_E__GPIO_E IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_F__LD17 IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_GPIO_F__GPIO_F IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL)
@@ -513,5 +502,4 @@
#define MX25_PAD_CTL_GRP_DVS_SDHC1 IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CTL_GRP_DVS_LCD IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL)
-#endif // __ASSEMBLY__
-#endif // __IOMUX_MX25_H__
+#endif /* __MACH_IOMUX_MX25_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx27.h b/arch/arm/plat-mxc/include/mach/iomux-mx27.h
index 5ac158b70f6..d9f9a6e32d8 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx27.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx27.h
@@ -1,207 +1,205 @@
/*
-* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
-* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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 _MXC_IOMUX_MX27_H
-#define _MXC_IOMUX_MX27_H
-
-#ifndef GPIO_PORTA
-#error Please include mach/iomux.h
-#endif
-
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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 __MACH_IOMUX_MX27_H__
+#define __MACH_IOMUX_MX27_H__
+
+#include <mach/iomux-mx2x.h>
+#include <mach/iomux-v1.h>
/* Primary GPIO pin functions */
-#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0)
-#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1)
-#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2)
-#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3)
-#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4)
-#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22)
-#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25)
-#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
-#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_PF | GPIO_IN | 6)
-#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7)
-#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8)
-#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
-#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10)
-#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
-#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12)
-#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13)
-#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 16)
-#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 17)
-#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 18)
-#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 19)
-#define PC25_AF_GPT5_TIN (GPIO_PORTC | GPIO_AF | 25)
-#define PC27_AF_GPT4_TIN (GPIO_PORTC | GPIO_AF | 27)
-#define PD0_PF_SD3_CMD (GPIO_PORTD | GPIO_PF | 0)
-#define PD1_PF_SD3_CLK (GPIO_PORTD | GPIO_PF | 1)
-#define PD2_PF_ATA_DATA0 (GPIO_PORTD | GPIO_PF | 2)
-#define PD3_PF_ATA_DATA1 (GPIO_PORTD | GPIO_PF | 3)
-#define PD4_PF_ATA_DATA2 (GPIO_PORTD | GPIO_PF | 4)
-#define PD5_PF_ATA_DATA3 (GPIO_PORTD | GPIO_PF | 5)
-#define PD6_PF_ATA_DATA4 (GPIO_PORTD | GPIO_PF | 6)
-#define PD7_PF_ATA_DATA5 (GPIO_PORTD | GPIO_PF | 7)
-#define PD8_PF_ATA_DATA6 (GPIO_PORTD | GPIO_PF | 8)
-#define PD9_PF_ATA_DATA7 (GPIO_PORTD | GPIO_PF | 9)
-#define PD10_PF_ATA_DATA8 (GPIO_PORTD | GPIO_PF | 10)
-#define PD11_PF_ATA_DATA9 (GPIO_PORTD | GPIO_PF | 11)
-#define PD12_PF_ATA_DATA10 (GPIO_PORTD | GPIO_PF | 12)
-#define PD13_PF_ATA_DATA11 (GPIO_PORTD | GPIO_PF | 13)
-#define PD14_PF_ATA_DATA12 (GPIO_PORTD | GPIO_PF | 14)
-#define PD15_PF_ATA_DATA13 (GPIO_PORTD | GPIO_PF | 15)
-#define PD16_PF_ATA_DATA14 (GPIO_PORTD | GPIO_PF | 16)
-#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0)
-#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1)
-#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2)
-#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24)
-#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25)
-#define PF1_PF_NFCLE (GPIO_PORTF | GPIO_PF | 1)
-#define PF3_PF_NFCE (GPIO_PORTF | GPIO_PF | 3)
-#define PF7_PF_PC_POE (GPIO_PORTF | GPIO_PF | 7)
-#define PF8_PF_PC_RW (GPIO_PORTF | GPIO_PF | 8)
-#define PF9_PF_PC_IOIS16 (GPIO_PORTF | GPIO_PF | 9)
-#define PF10_PF_PC_RST (GPIO_PORTF | GPIO_PF | 10)
-#define PF11_PF_PC_BVD2 (GPIO_PORTF | GPIO_PF | 11)
-#define PF12_PF_PC_BVD1 (GPIO_PORTF | GPIO_PF | 12)
-#define PF13_PF_PC_VS2 (GPIO_PORTF | GPIO_PF | 13)
-#define PF14_PF_PC_VS1 (GPIO_PORTF | GPIO_PF | 14)
-#define PF16_PF_PC_PWRON (GPIO_PORTF | GPIO_PF | 16)
-#define PF17_PF_PC_READY (GPIO_PORTF | GPIO_PF | 17)
-#define PF18_PF_PC_WAIT (GPIO_PORTF | GPIO_PF | 18)
-#define PF19_PF_PC_CD2 (GPIO_PORTF | GPIO_PF | 19)
-#define PF20_PF_PC_CD1 (GPIO_PORTF | GPIO_PF | 20)
-#define PF23_PF_ATA_DATA15 (GPIO_PORTF | GPIO_PF | 23)
+#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0)
+#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2)
+#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4)
+#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22)
+#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25)
+#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
+#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_PF | GPIO_IN | 6)
+#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7)
+#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8)
+#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
+#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10)
+#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
+#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12)
+#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13)
+#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 16)
+#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 17)
+#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 18)
+#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 19)
+#define PD0_PF_SD3_CMD (GPIO_PORTD | GPIO_PF | 0)
+#define PD1_PF_SD3_CLK (GPIO_PORTD | GPIO_PF | 1)
+#define PD2_PF_ATA_DATA0 (GPIO_PORTD | GPIO_PF | 2)
+#define PD3_PF_ATA_DATA1 (GPIO_PORTD | GPIO_PF | 3)
+#define PD4_PF_ATA_DATA2 (GPIO_PORTD | GPIO_PF | 4)
+#define PD5_PF_ATA_DATA3 (GPIO_PORTD | GPIO_PF | 5)
+#define PD6_PF_ATA_DATA4 (GPIO_PORTD | GPIO_PF | 6)
+#define PD7_PF_ATA_DATA5 (GPIO_PORTD | GPIO_PF | 7)
+#define PD8_PF_ATA_DATA6 (GPIO_PORTD | GPIO_PF | 8)
+#define PD9_PF_ATA_DATA7 (GPIO_PORTD | GPIO_PF | 9)
+#define PD10_PF_ATA_DATA8 (GPIO_PORTD | GPIO_PF | 10)
+#define PD11_PF_ATA_DATA9 (GPIO_PORTD | GPIO_PF | 11)
+#define PD12_PF_ATA_DATA10 (GPIO_PORTD | GPIO_PF | 12)
+#define PD13_PF_ATA_DATA11 (GPIO_PORTD | GPIO_PF | 13)
+#define PD14_PF_ATA_DATA12 (GPIO_PORTD | GPIO_PF | 14)
+#define PD15_PF_ATA_DATA13 (GPIO_PORTD | GPIO_PF | 15)
+#define PD16_PF_ATA_DATA14 (GPIO_PORTD | GPIO_PF | 16)
+#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0)
+#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1)
+#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2)
+#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24)
+#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25)
+#define PF1_PF_NFCLE (GPIO_PORTF | GPIO_PF | 1)
+#define PF3_PF_NFCE (GPIO_PORTF | GPIO_PF | 3)
+#define PF7_PF_PC_POE (GPIO_PORTF | GPIO_PF | 7)
+#define PF8_PF_PC_RW (GPIO_PORTF | GPIO_PF | 8)
+#define PF9_PF_PC_IOIS16 (GPIO_PORTF | GPIO_PF | 9)
+#define PF10_PF_PC_RST (GPIO_PORTF | GPIO_PF | 10)
+#define PF11_PF_PC_BVD2 (GPIO_PORTF | GPIO_PF | 11)
+#define PF12_PF_PC_BVD1 (GPIO_PORTF | GPIO_PF | 12)
+#define PF13_PF_PC_VS2 (GPIO_PORTF | GPIO_PF | 13)
+#define PF14_PF_PC_VS1 (GPIO_PORTF | GPIO_PF | 14)
+#define PF16_PF_PC_PWRON (GPIO_PORTF | GPIO_PF | 16)
+#define PF17_PF_PC_READY (GPIO_PORTF | GPIO_PF | 17)
+#define PF18_PF_PC_WAIT (GPIO_PORTF | GPIO_PF | 18)
+#define PF19_PF_PC_CD2 (GPIO_PORTF | GPIO_PF | 19)
+#define PF20_PF_PC_CD1 (GPIO_PORTF | GPIO_PF | 20)
+#define PF23_PF_ATA_DATA15 (GPIO_PORTF | GPIO_PF | 23)
/* Alternate GPIO pin functions */
-#define PB4_AF_MSHC_DATA0 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 4)
-#define PB5_AF_MSHC_DATA1 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 5)
-#define PB6_AF_MSHC_DATA2 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 6)
-#define PB7_AF_MSHC_DATA4 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 7)
-#define PB8_AF_MSHC_BS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 8)
-#define PB9_AF_MSHC_SCLK (GPIO_PORTB | GPIO_AF | GPIO_OUT | 9)
-#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 10)
-#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 11)
-#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 12)
-#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 13)
-#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 18)
-#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 19)
-#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 20)
-#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 21)
-#define PC8_AF_FEC_MDIO (GPIO_PORTC | GPIO_AF | GPIO_IN | 8)
-#define PC24_AF_GPT5_TOUT (GPIO_PORTC | GPIO_AF | 24)
-#define PC26_AF_GPT4_TOUT (GPIO_PORTC | GPIO_AF | 26)
-#define PD1_AF_ETMTRACE_PKT15 (GPIO_PORTD | GPIO_AF | 1)
-#define PD6_AF_ETMTRACE_PKT14 (GPIO_PORTD | GPIO_AF | 6)
-#define PD7_AF_ETMTRACE_PKT13 (GPIO_PORTD | GPIO_AF | 7)
-#define PD9_AF_ETMTRACE_PKT12 (GPIO_PORTD | GPIO_AF | 9)
-#define PD2_AF_SD3_D0 (GPIO_PORTD | GPIO_AF | 2)
-#define PD3_AF_SD3_D1 (GPIO_PORTD | GPIO_AF | 3)
-#define PD4_AF_SD3_D2 (GPIO_PORTD | GPIO_AF | 4)
-#define PD5_AF_SD3_D3 (GPIO_PORTD | GPIO_AF | 5)
-#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_AF | GPIO_IN | 8)
-#define PD10_AF_ETMTRACE_PKT11 (GPIO_PORTD | GPIO_AF | 10)
-#define PD11_AF_ETMTRACE_PKT10 (GPIO_PORTD | GPIO_AF | 11)
-#define PD12_AF_ETMTRACE_PKT9 (GPIO_PORTD | GPIO_AF | 12)
-#define PD13_AF_ETMTRACE_PKT8 (GPIO_PORTD | GPIO_AF | 13)
-#define PD14_AF_ETMTRACE_PKT7 (GPIO_PORTD | GPIO_AF | 14)
-#define PD15_AF_ETMTRACE_PKT6 (GPIO_PORTD | GPIO_AF | 15)
-#define PD16_AF_ETMTRACE_PKT5 (GPIO_PORTD | GPIO_AF | 16)
-#define PF1_AF_ETMTRACE_PKT0 (GPIO_PORTF | GPIO_AF | 1)
-#define PF3_AF_ETMTRACE_PKT2 (GPIO_PORTF | GPIO_AF | 3)
-#define PF5_AF_ETMPIPESTAT11 (GPIO_PORTF | GPIO_AF | 5)
-#define PF7_AF_ATA_BUFFER_EN (GPIO_PORTF | GPIO_AF | 7)
-#define PF8_AF_ATA_IORDY (GPIO_PORTF | GPIO_AF | 8)
-#define PF9_AF_ATA_INTRQ (GPIO_PORTF | GPIO_AF | 9)
-#define PF10_AF_ATA_RESET (GPIO_PORTF | GPIO_AF | 10)
-#define PF11_AF_ATA_DMACK (GPIO_PORTF | GPIO_AF | 11)
-#define PF12_AF_ATA_DMAREQ (GPIO_PORTF | GPIO_AF | 12)
-#define PF13_AF_ATA_DA0 (GPIO_PORTF | GPIO_AF | 13)
-#define PF14_AF_ATA_DA1 (GPIO_PORTF | GPIO_AF | 14)
-#define PF15_AF_ETMTRACE_SYNC (GPIO_PORTF | GPIO_AF | 15)
-#define PF16_AF_ATA_DA2 (GPIO_PORTF | GPIO_AF | 16)
-#define PF17_AF_ATA_CS0 (GPIO_PORTF | GPIO_AF | 17)
-#define PF18_AF_ATA_CS1 (GPIO_PORTF | GPIO_AF | 18)
-#define PF19_AF_ATA_DIOW (GPIO_PORTF | GPIO_AF | 19)
-#define PF20_AF_ATA_DIOR (GPIO_PORTF | GPIO_AF | 20)
-#define PF22_AF_ETMTRACE_CLK (GPIO_PORTF | GPIO_AF | 22)
-#define PF23_AF_ETMTRACE_PKT4 (GPIO_PORTF | GPIO_AF | 23)
+#define PB4_AF_MSHC_DATA0 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 4)
+#define PB5_AF_MSHC_DATA1 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 5)
+#define PB6_AF_MSHC_DATA2 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 6)
+#define PB7_AF_MSHC_DATA4 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 7)
+#define PB8_AF_MSHC_BS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 8)
+#define PB9_AF_MSHC_SCLK (GPIO_PORTB | GPIO_AF | GPIO_OUT | 9)
+#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 10)
+#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 11)
+#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 12)
+#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 13)
+#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 18)
+#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 19)
+#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 20)
+#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 21)
+#define PC8_AF_FEC_MDIO (GPIO_PORTC | GPIO_AF | GPIO_IN | 8)
+#define PC24_AF_GPT5_TOUT (GPIO_PORTC | GPIO_AF | 24)
+#define PC25_AF_GPT5_TIN (GPIO_PORTC | GPIO_AF | 25)
+#define PC26_AF_GPT4_TOUT (GPIO_PORTC | GPIO_AF | 26)
+#define PC27_AF_GPT4_TIN (GPIO_PORTC | GPIO_AF | 27)
+#define PD1_AF_ETMTRACE_PKT15 (GPIO_PORTD | GPIO_AF | 1)
+#define PD6_AF_ETMTRACE_PKT14 (GPIO_PORTD | GPIO_AF | 6)
+#define PD7_AF_ETMTRACE_PKT13 (GPIO_PORTD | GPIO_AF | 7)
+#define PD9_AF_ETMTRACE_PKT12 (GPIO_PORTD | GPIO_AF | 9)
+#define PD2_AF_SD3_D0 (GPIO_PORTD | GPIO_AF | 2)
+#define PD3_AF_SD3_D1 (GPIO_PORTD | GPIO_AF | 3)
+#define PD4_AF_SD3_D2 (GPIO_PORTD | GPIO_AF | 4)
+#define PD5_AF_SD3_D3 (GPIO_PORTD | GPIO_AF | 5)
+#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_AF | GPIO_IN | 8)
+#define PD10_AF_ETMTRACE_PKT11 (GPIO_PORTD | GPIO_AF | 10)
+#define PD11_AF_ETMTRACE_PKT10 (GPIO_PORTD | GPIO_AF | 11)
+#define PD12_AF_ETMTRACE_PKT9 (GPIO_PORTD | GPIO_AF | 12)
+#define PD13_AF_ETMTRACE_PKT8 (GPIO_PORTD | GPIO_AF | 13)
+#define PD14_AF_ETMTRACE_PKT7 (GPIO_PORTD | GPIO_AF | 14)
+#define PD15_AF_ETMTRACE_PKT6 (GPIO_PORTD | GPIO_AF | 15)
+#define PD16_AF_ETMTRACE_PKT5 (GPIO_PORTD | GPIO_AF | 16)
+#define PF1_AF_ETMTRACE_PKT0 (GPIO_PORTF | GPIO_AF | 1)
+#define PF3_AF_ETMTRACE_PKT2 (GPIO_PORTF | GPIO_AF | 3)
+#define PF5_AF_ETMPIPESTAT11 (GPIO_PORTF | GPIO_AF | 5)
+#define PF7_AF_ATA_BUFFER_EN (GPIO_PORTF | GPIO_AF | 7)
+#define PF8_AF_ATA_IORDY (GPIO_PORTF | GPIO_AF | 8)
+#define PF9_AF_ATA_INTRQ (GPIO_PORTF | GPIO_AF | 9)
+#define PF10_AF_ATA_RESET (GPIO_PORTF | GPIO_AF | 10)
+#define PF11_AF_ATA_DMACK (GPIO_PORTF | GPIO_AF | 11)
+#define PF12_AF_ATA_DMAREQ (GPIO_PORTF | GPIO_AF | 12)
+#define PF13_AF_ATA_DA0 (GPIO_PORTF | GPIO_AF | 13)
+#define PF14_AF_ATA_DA1 (GPIO_PORTF | GPIO_AF | 14)
+#define PF15_AF_ETMTRACE_SYNC (GPIO_PORTF | GPIO_AF | 15)
+#define PF16_AF_ATA_DA2 (GPIO_PORTF | GPIO_AF | 16)
+#define PF17_AF_ATA_CS0 (GPIO_PORTF | GPIO_AF | 17)
+#define PF18_AF_ATA_CS1 (GPIO_PORTF | GPIO_AF | 18)
+#define PF19_AF_ATA_DIOW (GPIO_PORTF | GPIO_AF | 19)
+#define PF20_AF_ATA_DIOR (GPIO_PORTF | GPIO_AF | 20)
+#define PF22_AF_ETMTRACE_CLK (GPIO_PORTF | GPIO_AF | 22)
+#define PF23_AF_ETMTRACE_PKT4 (GPIO_PORTF | GPIO_AF | 23)
/* AIN GPIO pin functions */
-#define PC14_AIN_SSI1_MCLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
-#define PC15_AIN_GPT6_TOUT (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 15)
-#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 0)
-#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 1)
-#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 2)
-#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 3)
-#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 9)
-#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 16)
-#define PD27_AIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 27)
-#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 23)
+#define PC14_AIN_SSI1_MCLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
+#define PC15_AIN_GPT6_TOUT (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 15)
+#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 0)
+#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 1)
+#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 2)
+#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 3)
+#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 9)
+#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 16)
+#define PD27_AIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 27)
+#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 23)
/* BIN GPIO pin functions */
-#define PC14_BIN_SSI2_MCLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
+#define PC14_BIN_SSI2_MCLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
/* CIN GPIO pin functions */
-#define PD2_CIN_SLCDC1_DAT0 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 2)
-#define PD3_CIN_SLCDC1_DAT1 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 3)
-#define PD4_CIN_SLCDC1_DAT2 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 4)
-#define PD5_CIN_SLCDC1_DAT3 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 5)
-#define PD6_CIN_SLCDC1_DAT4 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 6)
-#define PD7_CIN_SLCDC1_DAT5 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 7)
-#define PD8_CIN_SLCDC1_DAT6 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 8)
-#define PD9_CIN_SLCDC1_DAT7 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 9)
-#define PD10_CIN_SLCDC1_DAT8 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 10)
-#define PD11_CIN_SLCDC1_DAT9 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 11)
-#define PD12_CIN_SLCDC1_DAT10 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 12)
-#define PD13_CIN_SLCDC1_DAT11 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 13)
-#define PD14_CIN_SLCDC1_DAT12 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 14)
-#define PD15_CIN_SLCDC1_DAT13 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 15)
-#define PD16_CIN_SLCDC1_DAT14 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 16)
-#define PD23_CIN_SLCDC1_DAT15 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 23)
-#define PF27_CIN_EXT_DMA_GRANT (GPIO_PORTF | GPIO_CIN | GPIO_OUT | 27)
+#define PD2_CIN_SLCDC1_DAT0 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 2)
+#define PD3_CIN_SLCDC1_DAT1 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 3)
+#define PD4_CIN_SLCDC1_DAT2 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 4)
+#define PD5_CIN_SLCDC1_DAT3 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 5)
+#define PD6_CIN_SLCDC1_DAT4 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 6)
+#define PD7_CIN_SLCDC1_DAT5 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 7)
+#define PD8_CIN_SLCDC1_DAT6 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 8)
+#define PD9_CIN_SLCDC1_DAT7 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 9)
+#define PD10_CIN_SLCDC1_DAT8 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 10)
+#define PD11_CIN_SLCDC1_DAT9 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 11)
+#define PD12_CIN_SLCDC1_DAT10 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 12)
+#define PD13_CIN_SLCDC1_DAT11 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 13)
+#define PD14_CIN_SLCDC1_DAT12 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 14)
+#define PD15_CIN_SLCDC1_DAT13 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 15)
+#define PD16_CIN_SLCDC1_DAT14 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 16)
+#define PD23_CIN_SLCDC1_DAT15 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 23)
+#define PF27_CIN_EXT_DMA_GRANT (GPIO_PORTF | GPIO_CIN | GPIO_OUT | 27)
/* LCDC_TESTx on PBxx omitted, because it's not clear what they do */
/* AOUT GPIO pin functions */
-#define PC14_AOUT_GPT6_TIN (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 14)
-#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 4)
-#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 5)
-#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 6)
-#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 7)
-#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 10)
-#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 11)
-#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 12)
-#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 13)
-#define PD14_AOUT_FEC_RX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 14)
-#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 15)
-
-#define PC17_BOUT_PC_IOIS16 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 17)
-#define PC18_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 18)
-#define PC19_BOUT_PC_BVD1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 19)
-#define PC28_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 28)
-#define PC29_BOUT_PC_VS1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 29)
-#define PC30_BOUT_PC_READY (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 30)
-#define PC31_BOUT_PC_WAIT (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 31)
-
-
-#endif /* _MXC_GPIO_MX1_MX2_H */
+#define PC14_AOUT_GPT6_TIN (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 14)
+#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 4)
+#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 5)
+#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 6)
+#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 7)
+#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 10)
+#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 11)
+#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 12)
+#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 13)
+#define PD14_AOUT_FEC_RX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 14)
+#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 15)
+
+/* BOUT GPIO pin functions */
+
+#define PC17_BOUT_PC_IOIS16 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 17)
+#define PC18_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 18)
+#define PC19_BOUT_PC_BVD1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 19)
+#define PC28_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 28)
+#define PC29_BOUT_PC_VS1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 29)
+#define PC30_BOUT_PC_READY (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 30)
+#define PC31_BOUT_PC_WAIT (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 31)
+
+#endif /* __MACH_IOMUX_MX27_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
index fb5ae638e79..c4f116d214f 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
@@ -1,237 +1,230 @@
/*
-* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
-* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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 _MXC_IOMUX_MX2x_H
-#define _MXC_IOMUX_MX2x_H
-
-#ifndef GPIO_PORTA
-#error Please include mach/iomux.h
-#endif
-
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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 __MACH_IOMUX_MX2x_H__
+#define __MACH_IOMUX_MX2x_H__
/* Primary GPIO pin functions */
-#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5)
-#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6)
-#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7)
-#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8)
-#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9)
-#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10)
-#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11)
-#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12)
-#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13)
-#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14)
-#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
-#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
-#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17)
-#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18)
-#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19)
-#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20)
-#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21)
-#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22)
-#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23)
-#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24)
-#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25)
-#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26)
-#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27)
-#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28)
-#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29)
-#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30)
-#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31)
-#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4)
-#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5)
-#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6)
-#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7)
-#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8)
-#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9)
-#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 10)
-#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 11)
-#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 12)
-#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 13)
-#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 14)
-#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 15)
-#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 16)
-#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 17)
-#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 18)
-#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 19)
-#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 20)
-#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 21)
-#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23)
-#define PB24_PF_USB_OC (GPIO_PORTB | GPIO_PF | 24)
-#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26)
-#define PB27_PF_USBH1_OE (GPIO_PORTB | GPIO_PF | 27)
-#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28)
-#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29)
-#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30)
-#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31)
-#define PC14_PF_TOUT (GPIO_PORTC | GPIO_PF | 14)
-#define PC15_PF_TIN (GPIO_PORTC | GPIO_PF | 15)
-#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 20)
-#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 21)
-#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 22)
-#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 23)
-#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 24)
-#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 25)
-#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 26)
-#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 27)
-#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 28)
-#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 29)
-#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 30)
-#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
-#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
-#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
-#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | 19)
-#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | 20)
-#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | 21)
-#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | 22)
-#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | 23)
-#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | 24)
-#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
-#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
-#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
-#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
-#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
-#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 30)
-#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 31)
-#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 3)
-#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 4)
-#define PE5_PF_PWMO (GPIO_PORTE | GPIO_PF | 5)
-#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 6)
-#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 7)
-#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 8)
-#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 9)
-#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 10)
-#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 11)
-#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 12)
-#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 13)
-#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 14)
-#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 15)
-#define PE16_PF_RTCK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 16)
-#define PE17_PF_RESET_OUT (GPIO_PORTE | GPIO_PF | 17)
-#define PE18_PF_SD1_D0 (GPIO_PORTE | GPIO_PF | 18)
-#define PE19_PF_SD1_D1 (GPIO_PORTE | GPIO_PF | 19)
-#define PE20_PF_SD1_D2 (GPIO_PORTE | GPIO_PF | 20)
-#define PE21_PF_SD1_D3 (GPIO_PORTE | GPIO_PF | 21)
-#define PE22_PF_SD1_CMD (GPIO_PORTE | GPIO_PF | 22)
-#define PE23_PF_SD1_CLK (GPIO_PORTE | GPIO_PF | 23)
-#define PF0_PF_NRFB (GPIO_PORTF | GPIO_PF | 0)
-#define PF2_PF_NFWP (GPIO_PORTF | GPIO_PF | 2)
-#define PF4_PF_NFALE (GPIO_PORTF | GPIO_PF | 4)
-#define PF5_PF_NFRE (GPIO_PORTF | GPIO_PF | 5)
-#define PF6_PF_NFWE (GPIO_PORTF | GPIO_PF | 6)
-#define PF15_PF_CLKO (GPIO_PORTF | GPIO_PF | 15)
-#define PF21_PF_CS4 (GPIO_PORTF | GPIO_PF | 21)
-#define PF22_PF_CS5 (GPIO_PORTF | GPIO_PF | 22)
+#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5)
+#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6)
+#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7)
+#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8)
+#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9)
+#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10)
+#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11)
+#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12)
+#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13)
+#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14)
+#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17)
+#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18)
+#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19)
+#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20)
+#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21)
+#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22)
+#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23)
+#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24)
+#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25)
+#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26)
+#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27)
+#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28)
+#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29)
+#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30)
+#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31)
+#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4)
+#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5)
+#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6)
+#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7)
+#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8)
+#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9)
+#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 10)
+#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 11)
+#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 12)
+#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 13)
+#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 14)
+#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 15)
+#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 16)
+#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 17)
+#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 18)
+#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 19)
+#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 20)
+#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 21)
+#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USB_OC (GPIO_PORTB | GPIO_PF | 24)
+#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBH1_OE (GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28)
+#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29)
+#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30)
+#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31)
+#define PC14_PF_TOUT (GPIO_PORTC | GPIO_PF | 14)
+#define PC15_PF_TIN (GPIO_PORTC | GPIO_PF | 15)
+#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 20)
+#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 21)
+#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 22)
+#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 23)
+#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 24)
+#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 25)
+#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 26)
+#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 27)
+#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 28)
+#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 29)
+#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 30)
+#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
+#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
+#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
+#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | 19)
+#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | 20)
+#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | 21)
+#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | 22)
+#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | 23)
+#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | 24)
+#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
+#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
+#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
+#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
+#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
+#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 30)
+#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 31)
+#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 3)
+#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 4)
+#define PE5_PF_PWMO (GPIO_PORTE | GPIO_PF | 5)
+#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 6)
+#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 7)
+#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 8)
+#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 9)
+#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 10)
+#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 11)
+#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 12)
+#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 13)
+#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 14)
+#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 15)
+#define PE16_PF_RTCK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 16)
+#define PE17_PF_RESET_OUT (GPIO_PORTE | GPIO_PF | 17)
+#define PE18_PF_SD1_D0 (GPIO_PORTE | GPIO_PF | 18)
+#define PE19_PF_SD1_D1 (GPIO_PORTE | GPIO_PF | 19)
+#define PE20_PF_SD1_D2 (GPIO_PORTE | GPIO_PF | 20)
+#define PE21_PF_SD1_D3 (GPIO_PORTE | GPIO_PF | 21)
+#define PE22_PF_SD1_CMD (GPIO_PORTE | GPIO_PF | 22)
+#define PE23_PF_SD1_CLK (GPIO_PORTE | GPIO_PF | 23)
+#define PF0_PF_NRFB (GPIO_PORTF | GPIO_PF | 0)
+#define PF2_PF_NFWP (GPIO_PORTF | GPIO_PF | 2)
+#define PF4_PF_NFALE (GPIO_PORTF | GPIO_PF | 4)
+#define PF5_PF_NFRE (GPIO_PORTF | GPIO_PF | 5)
+#define PF6_PF_NFWE (GPIO_PORTF | GPIO_PF | 6)
+#define PF15_PF_CLKO (GPIO_PORTF | GPIO_PF | 15)
+#define PF21_PF_CS4 (GPIO_PORTF | GPIO_PF | 21)
+#define PF22_PF_CS5 (GPIO_PORTF | GPIO_PF | 22)
/* Alternate GPIO pin functions */
-#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 26)
-#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 28)
-#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 29)
-#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 31)
-#define PC28_AF_SLCDC2_D0 (GPIO_PORTC | GPIO_AF | 28)
-#define PC29_AF_SLCDC2_RS (GPIO_PORTC | GPIO_AF | 29)
-#define PC30_AF_SLCDC2_CS (GPIO_PORTC | GPIO_AF | 30)
-#define PC31_AF_SLCDC2_CLK (GPIO_PORTC | GPIO_AF | 31)
-#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19)
-#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20)
-#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21)
-#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22)
-#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23)
-#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24)
-#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26)
-#define PE0_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 0)
-#define PE1_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 1)
-#define PE2_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 2)
-#define PE3_AF_KP_COL7 (GPIO_PORTE | GPIO_AF | 3)
-#define PE4_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 4)
-#define PE6_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 6)
-#define PE7_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 7)
-#define PE16_AF_OWIRE (GPIO_PORTE | GPIO_AF | 16)
-#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_AF | GPIO_IN | 18)
-#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_AF | GPIO_OUT | 21)
-#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_AF | GPIO_OUT | 22)
-#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_AF | GPIO_OUT | 23)
+#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 26)
+#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 28)
+#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 29)
+#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 31)
+#define PC28_AF_SLCDC2_D0 (GPIO_PORTC | GPIO_AF | 28)
+#define PC29_AF_SLCDC2_RS (GPIO_PORTC | GPIO_AF | 29)
+#define PC30_AF_SLCDC2_CS (GPIO_PORTC | GPIO_AF | 30)
+#define PC31_AF_SLCDC2_CLK (GPIO_PORTC | GPIO_AF | 31)
+#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19)
+#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20)
+#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21)
+#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22)
+#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23)
+#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24)
+#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26)
+#define PE0_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 0)
+#define PE1_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 1)
+#define PE2_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 2)
+#define PE3_AF_KP_COL7 (GPIO_PORTE | GPIO_AF | 3)
+#define PE4_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 4)
+#define PE6_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 6)
+#define PE7_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 7)
+#define PE16_AF_OWIRE (GPIO_PORTE | GPIO_AF | 16)
+#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_AF | GPIO_IN | 18)
+#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_AF | GPIO_OUT | 21)
+#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_AF | GPIO_OUT | 22)
+#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_AF | GPIO_OUT | 23)
/* AIN GPIO pin functions */
-#define PA6_AIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 6)
-#define PA7_AIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 7)
-#define PA8_AIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 8)
-#define PA0_AIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
-#define PA11_AIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 11)
-#define PA13_AIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 13)
-#define PA15_AIN_SLCDC1_DAT9 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 15)
-#define PA17_AIN_SLCDC1_DAT11 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
-#define PA19_AIN_SLCDC1_DAT13 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 19)
-#define PA21_AIN_SLCDC1_DAT15 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 21)
-#define PA22_AIN_EXT_DMAGRANT (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 22)
-#define PA24_AIN_SLCDC1_D0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 24)
-#define PA25_AIN_SLCDC1_RS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 25)
-#define PA26_AIN_SLCDC1_CS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 26)
-#define PA27_AIN_SLCDC1_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 27)
-#define PB6_AIN_SLCDC1_D0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 6)
-#define PB7_AIN_SLCDC1_RS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 7)
-#define PB8_AIN_SLCDC1_CS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 8)
-#define PB9_AIN_SLCDC1_CLK (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 9)
-#define PB25_AIN_SLCDC1_DAT0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 25)
-#define PB26_AIN_SLCDC1_DAT1 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 26)
-#define PB27_AIN_SLCDC1_DAT2 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 27)
-#define PB28_AIN_SLCDC1_DAT3 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 28)
-#define PB29_AIN_SLCDC1_DAT4 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 29)
-#define PB30_AIN_SLCDC1_DAT5 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 30)
-#define PB31_AIN_SLCDC1_DAT6 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 31)
-#define PC5_AIN_SLCDC1_DAT7 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 5)
-#define PC6_AIN_SLCDC1_DAT8 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 6)
-#define PC7_AIN_SLCDC1_DAT9 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 7)
-#define PC8_AIN_SLCDC1_DAT10 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 8)
-#define PC9_AIN_SLCDC1_DAT11 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 9)
-#define PC10_AIN_SLCDC1_DAT12 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 10)
-#define PC11_AIN_SLCDC1_DAT13 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 11)
-#define PC12_AIN_SLCDC1_DAT14 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 12)
-#define PC13_AIN_SLCDC1_DAT15 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 13)
-#define PE5_AIN_PC_SPKOUT (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 5)
+#define PA6_AIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 6)
+#define PA7_AIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 7)
+#define PA8_AIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 8)
+#define PA0_AIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
+#define PA11_AIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 11)
+#define PA13_AIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 13)
+#define PA15_AIN_SLCDC1_DAT9 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 15)
+#define PA17_AIN_SLCDC1_DAT11 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
+#define PA19_AIN_SLCDC1_DAT13 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 19)
+#define PA21_AIN_SLCDC1_DAT15 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 21)
+#define PA22_AIN_EXT_DMAGRANT (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 22)
+#define PA24_AIN_SLCDC1_D0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 24)
+#define PA25_AIN_SLCDC1_RS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 25)
+#define PA26_AIN_SLCDC1_CS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 26)
+#define PA27_AIN_SLCDC1_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 27)
+#define PB6_AIN_SLCDC1_D0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 6)
+#define PB7_AIN_SLCDC1_RS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 7)
+#define PB8_AIN_SLCDC1_CS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 8)
+#define PB9_AIN_SLCDC1_CLK (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 9)
+#define PB25_AIN_SLCDC1_DAT0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 25)
+#define PB26_AIN_SLCDC1_DAT1 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 26)
+#define PB27_AIN_SLCDC1_DAT2 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 27)
+#define PB28_AIN_SLCDC1_DAT3 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 28)
+#define PB29_AIN_SLCDC1_DAT4 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 29)
+#define PB30_AIN_SLCDC1_DAT5 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 30)
+#define PB31_AIN_SLCDC1_DAT6 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 31)
+#define PC5_AIN_SLCDC1_DAT7 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 5)
+#define PC6_AIN_SLCDC1_DAT8 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 6)
+#define PC7_AIN_SLCDC1_DAT9 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 7)
+#define PC8_AIN_SLCDC1_DAT10 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 8)
+#define PC9_AIN_SLCDC1_DAT11 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 9)
+#define PC10_AIN_SLCDC1_DAT12 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 10)
+#define PC11_AIN_SLCDC1_DAT13 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 11)
+#define PC12_AIN_SLCDC1_DAT14 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 12)
+#define PC13_AIN_SLCDC1_DAT15 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 13)
+#define PE5_AIN_PC_SPKOUT (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 5)
/* BIN GPIO pin functions */
-#define PE5_BIN_TOUT2 (GPIO_PORTE | GPIO_BIN | GPIO_OUT | 5)
+#define PE5_BIN_TOUT2 (GPIO_PORTE | GPIO_BIN | GPIO_OUT | 5)
/* CIN GPIO pin functions */
-#define PA14_CIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 14)
-#define PA15_CIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 15)
-#define PA16_CIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 16)
-#define PA17_CIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 17)
-#define PA18_CIN_SLCDC1_DAT4 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 18)
-#define PA19_CIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 19)
-#define PA20_CIN_SLCDC1_DAT6 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 20)
-#define PA21_CIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 21)
-#define PB30_CIN_UART4_CTS (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 30)
-#define PE5_CIN_TOUT3 (GPIO_PORTE | GPIO_CIN | GPIO_OUT | 5)
+#define PA14_CIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 14)
+#define PA15_CIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 15)
+#define PA16_CIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 16)
+#define PA17_CIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 17)
+#define PA18_CIN_SLCDC1_DAT4 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 18)
+#define PA19_CIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 19)
+#define PA20_CIN_SLCDC1_DAT6 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 20)
+#define PA21_CIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 21)
+#define PB30_CIN_UART4_CTS (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 30)
+#define PE5_CIN_TOUT3 (GPIO_PORTE | GPIO_CIN | GPIO_OUT | 5)
/* AOUT GPIO pin functions */
-#define PB29_AOUT_UART4_RXD (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 29)
-#define PB31_AOUT_UART4_RTS (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 31)
+#define PB29_AOUT_UART4_RXD (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 29)
+#define PB31_AOUT_UART4_RTS (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 31)
#define PC8_AOUT_USBOTG_TXR_INT (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 8)
-#define PC15_AOUT_WKGD (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15)
-#define PF21_AOUT_DTACK (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21)
-
+#define PC15_AOUT_WKGD (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15)
+#define PF21_AOUT_DTACK (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21)
-#endif
+#endif /* ifndef __MACH_IOMUX_MX2x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index e1fc6da1cd1..e51465d7b22 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -16,12 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
-
-#ifndef __MACH_MX31_IOMUX_H__
-#define __MACH_MX31_IOMUX_H__
+#ifndef __MACH_IOMUX_MX3_H__
+#define __MACH_IOMUX_MX3_H__
#include <linux/types.h>
-
/*
* various IOMUX output functions
*/
@@ -34,7 +32,7 @@
#define IOMUX_OCONFIG_ALT4 (5 << 4) /* used as alternate function 4 */
#define IOMUX_OCONFIG_ALT5 (6 << 4) /* used as alternate function 5 */
#define IOMUX_OCONFIG_ALT6 (7 << 4) /* used as alternate function 6 */
-#define IOMUX_ICONFIG_NONE 0 /* not configured for input */
+#define IOMUX_ICONFIG_NONE 0 /* not configured for input */
#define IOMUX_ICONFIG_GPIO 1 /* used as GPIO */
#define IOMUX_ICONFIG_FUNC 2 /* used as function */
#define IOMUX_ICONFIG_ALT1 4 /* used as alternate function 1 */
@@ -167,11 +165,6 @@ int mxc_iomux_mode(unsigned int pin_mode);
MXC_GPIO_IRQ_START)
/*
- * The number of gpio devices among the pads
- */
-#define GPIO_PORT_MAX 3
-
-/*
* This enumeration is constructed based on the Section
* "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated
* value is constructed based on the rules described above.
@@ -633,40 +626,40 @@ enum iomux_pins {
#define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO)
#define MX31_PIN_CSI_D4__GPIO3_4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_GPIO)
#define MX31_PIN_CSI_D5__GPIO3_5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO)
-#define MX31_PIN_USBOTG_DATA0__USBOTG_DATA0 IOMUX_MODE(MX31_PIN_USBOTG_DATA0, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA1__USBOTG_DATA1 IOMUX_MODE(MX31_PIN_USBOTG_DATA1, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA2__USBOTG_DATA2 IOMUX_MODE(MX31_PIN_USBOTG_DATA2, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA3__USBOTG_DATA3 IOMUX_MODE(MX31_PIN_USBOTG_DATA3, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA4__USBOTG_DATA4 IOMUX_MODE(MX31_PIN_USBOTG_DATA4, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA5__USBOTG_DATA5 IOMUX_MODE(MX31_PIN_USBOTG_DATA5, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA6__USBOTG_DATA6 IOMUX_MODE(MX31_PIN_USBOTG_DATA6, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DATA7__USBOTG_DATA7 IOMUX_MODE(MX31_PIN_USBOTG_DATA7, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_CLK__USBOTG_CLK IOMUX_MODE(MX31_PIN_USBOTG_CLK, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_DIR__USBOTG_DIR IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_NXT__USBOTG_NXT IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBOTG_STP__USBOTG_STP IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_CSPI1_MOSI__USBH1_RXDM IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_MISO__USBH1_RXDP IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SS0__USBH1_TXDM IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SS1__USBH1_TXDP IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SS2__USBH1_RCV IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SCLK__USBH1_OEB IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1)
-#define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_USBOTG_DATA0__USBOTG_DATA0 IOMUX_MODE(MX31_PIN_USBOTG_DATA0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA1__USBOTG_DATA1 IOMUX_MODE(MX31_PIN_USBOTG_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA2__USBOTG_DATA2 IOMUX_MODE(MX31_PIN_USBOTG_DATA2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA3__USBOTG_DATA3 IOMUX_MODE(MX31_PIN_USBOTG_DATA3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA4__USBOTG_DATA4 IOMUX_MODE(MX31_PIN_USBOTG_DATA4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA5__USBOTG_DATA5 IOMUX_MODE(MX31_PIN_USBOTG_DATA5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA6__USBOTG_DATA6 IOMUX_MODE(MX31_PIN_USBOTG_DATA6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA7__USBOTG_DATA7 IOMUX_MODE(MX31_PIN_USBOTG_DATA7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_CLK__USBOTG_CLK IOMUX_MODE(MX31_PIN_USBOTG_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DIR__USBOTG_DIR IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_NXT__USBOTG_NXT IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_STP__USBOTG_STP IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_MOSI__USBH1_RXDM IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_MISO__USBH1_RXDP IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS0__USBH1_TXDM IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS1__USBH1_TXDP IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS2__USBH1_RCV IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SCLK__USBH1_OEB IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1)
#define MX31_PIN_SFS6__USBH1_SUSPEND IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_FUNC)
#define MX31_PIN_NFRE_B__GPIO1_11 IOMUX_MODE(MX31_PIN_NFRE_B, IOMUX_CONFIG_GPIO)
#define MX31_PIN_NFALE__GPIO1_12 IOMUX_MODE(MX31_PIN_NFALE, IOMUX_CONFIG_GPIO)
-#define MX31_PIN_USBH2_DATA0__USBH2_DATA0 IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_DATA1__USBH2_DATA1 IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DATA0__USBH2_DATA0 IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DATA1__USBH2_DATA1 IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC)
#define MX31_PIN_STXD3__USBH2_DATA2 IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC)
#define MX31_PIN_SRXD3__USBH2_DATA3 IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC)
#define MX31_PIN_SCK3__USBH2_DATA4 IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC)
#define MX31_PIN_SFS3__USBH2_DATA5 IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC)
#define MX31_PIN_STXD6__USBH2_DATA6 IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC)
#define MX31_PIN_SRXD6__USBH2_DATA7 IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_CLK__USBH2_CLK IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_DIR__USBH2_DIR IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_NXT__USBH2_NXT IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC)
-#define MX31_PIN_USBH2_STP__USBH2_STP IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_CLK__USBH2_CLK IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DIR__USBH2_DIR IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_NXT__USBH2_NXT IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_STP__USBH2_STP IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC)
#define MX31_PIN_SCK6__GPIO1_25 IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO)
#define MX31_PIN_USB_OC__GPIO1_30 IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO)
#define MX31_PIN_I2C_DAT__I2C1_SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
@@ -711,8 +704,8 @@ enum iomux_pins {
#define MX31_PIN_DSR_DCE1__GPIO2_9 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_GPIO)
#define MX31_PIN_RI_DCE1__GPIO2_10 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_GPIO)
#define MX31_PIN_DCD_DCE1__GPIO2_11 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_GPIO)
-#define MX31_PIN_STXD5__GPIO1_21 IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO)
-#define MX31_PIN_SRXD5__GPIO1_22 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_STXD5__GPIO1_21 IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SRXD5__GPIO1_22 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO)
#define MX31_PIN_GPIO1_3__GPIO1_3 IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO)
#define MX31_PIN_CSPI2_SS1__CSPI3_SS1 IOMUX_MODE(MX31_PIN_CSPI2_SS1, IOMUX_CONFIG_ALT1)
#define MX31_PIN_RTS1__GPIO2_6 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO)
@@ -727,13 +720,14 @@ enum iomux_pins {
#define MX31_PIN_SCK5__SCK5 IOMUX_MODE(MX31_PIN_SCK5, IOMUX_CONFIG_FUNC)
#define MX31_PIN_SFS5__SFS5 IOMUX_MODE(MX31_PIN_SFS5, IOMUX_CONFIG_FUNC)
-/*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0
- * cspi1_ss1*/
+/*
+ * XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed with cspi2_ss0,
+ * cspi2_ss1, cspi1_ss0 cspi1_ss1
+ */
/*
* This function configures the pad value for a IOMUX pin.
*/
void mxc_iomux_set_pad(enum iomux_pins, u32);
-#endif
-
+#endif /* ifndef __MACH_IOMUX_MX3_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx35.h b/arch/arm/plat-mxc/include/mach/iomux-mx35.h
index c88d40795f7..2a24bae1b87 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx35.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx35.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
new file mode 100644
index 00000000000..b4f975e6a66
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.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
+ */
+
+#ifndef __MACH_IOMUX_MX51_H__
+#define __MACH_IOMUX_MX51_H__
+
+#include <mach/iomux-v3.h>
+
+/*
+ * various IOMUX alternate output functions (1-7)
+ */
+typedef enum iomux_config {
+ IOMUX_CONFIG_ALT0,
+ IOMUX_CONFIG_ALT1,
+ IOMUX_CONFIG_ALT2,
+ IOMUX_CONFIG_ALT3,
+ IOMUX_CONFIG_ALT4,
+ 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_pin_cfg_t;
+
+/* Pad control groupings */
+#define MX51_UART1_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_HIGH)
+#define MX51_UART2_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_SRE_FAST)
+#define MX51_UART3_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_SRE_FAST)
+
+/*
+ * 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
+ */
+
+/*
+ * 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_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_GPIO_1_25__USBH1_CLK IOMUX_PAD(0x678, 0x278, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_26__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_27__USBH1_STP IOMUX_PAD(0x680, 0x280, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_28__USBH1_NXT IOMUX_PAD(0x684, 0x284, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_11__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_12__USBH1_DATA1 IOMUX_PAD(0x68C, 0x28C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_13__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_14__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_15__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_16__USBH1_DATA5 IOMUX_PAD(0x69C, 0x29C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_17__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_18__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 2, 0x0, 0, NO_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, NO_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)
+
+#endif /* __MACH_IOMUX_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v1.h b/arch/arm/plat-mxc/include/mach/iomux-v1.h
new file mode 100644
index 00000000000..884f5753f27
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-v1.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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 __MACH_IOMUX_V1_H__
+#define __MACH_IOMUX_V1_H__
+
+/*
+* GPIO Module and I/O Multiplexer
+* x = 0..3 for reg_A, reg_B, reg_C, reg_D
+*/
+#define MXC_DDIR(x) (0x00 + ((x) << 8))
+#define MXC_OCR1(x) (0x04 + ((x) << 8))
+#define MXC_OCR2(x) (0x08 + ((x) << 8))
+#define MXC_ICONFA1(x) (0x0c + ((x) << 8))
+#define MXC_ICONFA2(x) (0x10 + ((x) << 8))
+#define MXC_ICONFB1(x) (0x14 + ((x) << 8))
+#define MXC_ICONFB2(x) (0x18 + ((x) << 8))
+#define MXC_DR(x) (0x1c + ((x) << 8))
+#define MXC_GIUS(x) (0x20 + ((x) << 8))
+#define MXC_SSR(x) (0x24 + ((x) << 8))
+#define MXC_ICR1(x) (0x28 + ((x) << 8))
+#define MXC_ICR2(x) (0x2c + ((x) << 8))
+#define MXC_IMR(x) (0x30 + ((x) << 8))
+#define MXC_ISR(x) (0x34 + ((x) << 8))
+#define MXC_GPR(x) (0x38 + ((x) << 8))
+#define MXC_SWR(x) (0x3c + ((x) << 8))
+#define MXC_PUEN(x) (0x40 + ((x) << 8))
+
+#define MX1_NUM_GPIO_PORT 4
+#define MX21_NUM_GPIO_PORT 6
+#define MX27_NUM_GPIO_PORT 6
+
+#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)
+
+#define GPIO_OUT (1 << 8)
+#define GPIO_IN (0 << 8)
+#define GPIO_PUEN (1 << 9)
+
+#define GPIO_PF (1 << 10)
+#define GPIO_AF (1 << 11)
+
+#define GPIO_OCR_SHIFT 12
+#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT)
+#define GPIO_AIN (0 << GPIO_OCR_SHIFT)
+#define GPIO_BIN (1 << GPIO_OCR_SHIFT)
+#define GPIO_CIN (2 << GPIO_OCR_SHIFT)
+#define GPIO_GPIO (3 << GPIO_OCR_SHIFT)
+
+#define GPIO_AOUT_SHIFT 14
+#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT)
+
+#define GPIO_BOUT_SHIFT 16
+#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT)
+
+/* decode irq number to use with IMR(x), ISR(x) and friends */
+#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5)
+
+#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x)
+#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x)
+#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x)
+#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x)
+#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x)
+#define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x)
+
+extern int mxc_gpio_mode(int gpio_mode);
+extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+ const char *label);
+extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count);
+
+#endif /* __MACH_IOMUX_V1_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
index 1deda018489..f2f73d31d5b 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
@@ -81,11 +81,13 @@ struct pad_desc {
#define PAD_CTL_ODE (1 << 3)
-#define PAD_CTL_DSE_STANDARD (0 << 1)
-#define PAD_CTL_DSE_HIGH (1 << 1)
-#define PAD_CTL_DSE_MAX (2 << 1)
+#define PAD_CTL_DSE_LOW (0 << 1)
+#define PAD_CTL_DSE_MED (1 << 1)
+#define PAD_CTL_DSE_HIGH (2 << 1)
+#define PAD_CTL_DSE_MAX (3 << 1)
#define PAD_CTL_SRE_FAST (1 << 0)
+#define PAD_CTL_SRE_SLOW (0 << 0)
/*
* setups a single pad in the iomuxer
diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h
index 011cfcd8b82..3d226d7e7be 100644
--- a/arch/arm/plat-mxc/include/mach/iomux.h
+++ b/arch/arm/plat-mxc/include/mach/iomux.h
@@ -1,102 +1,14 @@
/*
-* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
-* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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 _MXC_IOMUX_H
-#define _MXC_IOMUX_H
-
-/*
-* GPIO Module and I/O Multiplexer
-* x = 0..3 for reg_A, reg_B, reg_C, reg_D
-*/
-#define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR)
-#define MXC_DDIR(x) (0x00 + ((x) << 8))
-#define MXC_OCR1(x) (0x04 + ((x) << 8))
-#define MXC_OCR2(x) (0x08 + ((x) << 8))
-#define MXC_ICONFA1(x) (0x0c + ((x) << 8))
-#define MXC_ICONFA2(x) (0x10 + ((x) << 8))
-#define MXC_ICONFB1(x) (0x14 + ((x) << 8))
-#define MXC_ICONFB2(x) (0x18 + ((x) << 8))
-#define MXC_DR(x) (0x1c + ((x) << 8))
-#define MXC_GIUS(x) (0x20 + ((x) << 8))
-#define MXC_SSR(x) (0x24 + ((x) << 8))
-#define MXC_ICR1(x) (0x28 + ((x) << 8))
-#define MXC_ICR2(x) (0x2c + ((x) << 8))
-#define MXC_IMR(x) (0x30 + ((x) << 8))
-#define MXC_ISR(x) (0x34 + ((x) << 8))
-#define MXC_GPR(x) (0x38 + ((x) << 8))
-#define MXC_SWR(x) (0x3c + ((x) << 8))
-#define MXC_PUEN(x) (0x40 + ((x) << 8))
-
-#ifdef CONFIG_ARCH_MX1
-# define GPIO_PORT_MAX 3
-#endif
-#ifdef CONFIG_ARCH_MX2
-# define GPIO_PORT_MAX 5
-#endif
-#ifdef CONFIG_ARCH_MX25
-# define GPIO_PORT_MAX 3
-#endif
-
-#ifndef GPIO_PORT_MAX
-# error "GPIO config port count unknown!"
-#endif
-
-#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)
-
-#define GPIO_OUT (1 << 8)
-#define GPIO_IN (0 << 8)
-#define GPIO_PUEN (1 << 9)
-
-#define GPIO_PF (1 << 10)
-#define GPIO_AF (1 << 11)
-
-#define GPIO_OCR_SHIFT 12
-#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT)
-#define GPIO_AIN (0 << GPIO_OCR_SHIFT)
-#define GPIO_BIN (1 << GPIO_OCR_SHIFT)
-#define GPIO_CIN (2 << GPIO_OCR_SHIFT)
-#define GPIO_GPIO (3 << GPIO_OCR_SHIFT)
-
-#define GPIO_AOUT_SHIFT 14
-#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT)
-
-#define GPIO_BOUT_SHIFT 16
-#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT)
+ * Copyright (C) 2010 Uwe Kleine-Koenig, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef __MACH_IOMUX_H__
+#define __MACH_IOMUX_H__
+/* This file will go away, please include mach/iomux-mx... directly */
#ifdef CONFIG_ARCH_MX1
#include <mach/iomux-mx1.h>
@@ -110,25 +22,5 @@
#include <mach/iomux-mx27.h>
#endif
#endif
-#ifdef CONFIG_ARCH_MX25
-#include <mach/iomux-mx25.h>
-#endif
-
-/* decode irq number to use with IMR(x), ISR(x) and friends */
-#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5)
-
-#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x)
-#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x)
-#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x)
-#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x)
-#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x)
-#define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x)
-
-
-extern void mxc_gpio_mode(int gpio_mode);
-extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
- const char *label);
-extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count);
-
-#endif
+#endif /* __MACH_IOMUX_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 0cb347645db..86781f7b0c0 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -12,22 +12,29 @@
#define __ASM_ARCH_MXC_IRQS_H__
/*
- * So far all i.MX SoCs have 64 internal interrupts
+ * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
*/
+#ifdef CONFIG_MXC_TZIC
+#define MXC_INTERNAL_IRQS 128
+#else
#define MXC_INTERNAL_IRQS 64
+#endif
#define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS
-#if defined CONFIG_ARCH_MX1
-#define MXC_GPIO_IRQS (32 * 4)
-#elif defined CONFIG_ARCH_MX2
+/* these are ordered by size to support multi-SoC kernels */
+#if defined CONFIG_ARCH_MX2
#define MXC_GPIO_IRQS (32 * 6)
-#elif defined CONFIG_ARCH_MX3
-#define MXC_GPIO_IRQS (32 * 3)
+#elif defined CONFIG_ARCH_MX1
+#define MXC_GPIO_IRQS (32 * 4)
#elif defined CONFIG_ARCH_MX25
#define MXC_GPIO_IRQS (32 * 4)
+#elif defined CONFIG_ARCH_MX5
+#define MXC_GPIO_IRQS (32 * 4)
#elif defined CONFIG_ARCH_MXC91231
#define MXC_GPIO_IRQS (32 * 4)
+#elif defined CONFIG_ARCH_MX3
+#define MXC_GPIO_IRQS (32 * 3)
#endif
/*
@@ -51,6 +58,7 @@
#else
#define MX3_IPU_IRQS 0
#endif
+/* REVISIT: Add IPU irqs on IMX51 */
#define NR_IRQS (MXC_IPU_IRQ_START + MX3_IPU_IRQS)
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index d3afafdcc0e..c4b40c35a6a 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -11,37 +11,45 @@
#ifndef __ASM_ARCH_MXC_MEMORY_H__
#define __ASM_ARCH_MXC_MEMORY_H__
-#if defined CONFIG_ARCH_MX1
-#define PHYS_OFFSET UL(0x08000000)
-#elif defined CONFIG_ARCH_MX2
-#ifdef CONFIG_MACH_MX21
-#define PHYS_OFFSET UL(0xC0000000)
-#endif
-#ifdef CONFIG_MACH_MX27
-#define PHYS_OFFSET UL(0xA0000000)
-#endif
-#elif defined CONFIG_ARCH_MX3
-#define PHYS_OFFSET UL(0x80000000)
-#elif defined CONFIG_ARCH_MX25
-#define PHYS_OFFSET UL(0x80000000)
-#elif defined CONFIG_ARCH_MXC91231
-#define PHYS_OFFSET UL(0x90000000)
+#define MX1_PHYS_OFFSET UL(0x08000000)
+#define MX21_PHYS_OFFSET UL(0xc0000000)
+#define MX25_PHYS_OFFSET UL(0x80000000)
+#define MX27_PHYS_OFFSET UL(0xa0000000)
+#define MX3x_PHYS_OFFSET UL(0x80000000)
+#define MX51_PHYS_OFFSET UL(0x90000000)
+#define MXC91231_PHYS_OFFSET UL(0x90000000)
+
+#if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
+# if defined CONFIG_ARCH_MX1
+# define PHYS_OFFSET MX1_PHYS_OFFSET
+# elif defined CONFIG_MACH_MX21
+# define PHYS_OFFSET MX21_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX25
+# define PHYS_OFFSET MX25_PHYS_OFFSET
+# elif defined CONFIG_MACH_MX27
+# define PHYS_OFFSET MX27_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX3
+# define PHYS_OFFSET MX3x_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MXC91231
+# define PHYS_OFFSET MXC91231_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX5
+# define PHYS_OFFSET MX51_PHYS_OFFSET
+# endif
#endif
-#if defined(CONFIG_MX1_VIDEO)
+#if defined(CONFIG_MX3_VIDEO)
/*
* Increase size of DMA-consistent memory region.
- * This is required for i.MX camera driver to capture at least four VGA frames.
+ * This is required for mx3 camera driver to capture at least two QXGA frames.
*/
-#define CONSISTENT_DMA_SIZE SZ_4M
-#endif /* CONFIG_MX1_VIDEO */
+#define CONSISTENT_DMA_SIZE SZ_8M
-#if defined(CONFIG_MX3_VIDEO)
+#elif defined(CONFIG_MX1_VIDEO)
/*
* Increase size of DMA-consistent memory region.
- * This is required for mx3 camera driver to capture at least two QXGA frames.
+ * This is required for i.MX camera driver to capture at least four VGA frames.
*/
-#define CONSISTENT_DMA_SIZE SZ_8M
-#endif /* CONFIG_MX3_VIDEO */
+#define CONSISTENT_DMA_SIZE SZ_4M
+#endif /* CONFIG_MX1_VIDEO */
#endif /* __ASM_ARCH_MXC_MEMORY_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mtd-xip.h b/arch/arm/plat-mxc/include/mach/mtd-xip.h
deleted file mode 100644
index 1ab1bba5688..00000000000
--- a/arch/arm/plat-mxc/include/mach/mtd-xip.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * MTD primitives for XIP support. Architecture specific functions
- *
- * Do not include this file directly. It's included from linux/mtd/xip.h
- *
- * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com>, Teltonika, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <mach/mxc_timer.h>
-
-#ifndef __ARCH_IMX_MTD_XIP_H__
-#define __ARCH_IMX_MTD_XIP_H__
-
-#ifdef CONFIG_ARCH_MX1
-/* AITC registers */
-#define AITC_BASE IO_ADDRESS(AVIC_BASE_ADDR)
-#define NIPNDH (AITC_BASE + 0x58)
-#define NIPNDL (AITC_BASE + 0x5C)
-#define INTENABLEH (AITC_BASE + 0x10)
-#define INTENABLEL (AITC_BASE + 0x14)
-/* MTD macros */
-#define xip_irqpending() ((__raw_readl(INTENABLEH) & __raw_readl(NIPNDH)) \
- || (__raw_readl(INTENABLEL) & __raw_readl(NIPNDL)))
-#define xip_currtime() (__raw_readl(TIMER_BASE + MXC_TCN))
-#define xip_elapsed_since(x) (signed)((__raw_readl(TIMER_BASE + MXC_TCN) - (x)) / 96)
-#define xip_cpu_idle() asm volatile ("mcr p15, 0, %0, c7, c0, 4" :: "r" (0))
-#endif /* CONFIG_ARCH_MX1 */
-
-#endif /* __ARCH_IMX_MTD_XIP_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx1.h b/arch/arm/plat-mxc/include/mach/mx1.h
index 1b2890a5c45..5eba7e6785d 100644
--- a/arch/arm/plat-mxc/include/mach/mx1.h
+++ b/arch/arm/plat-mxc/include/mach/mx1.h
@@ -9,156 +9,289 @@
* published by the Free Software Foundation.
*/
-#ifndef __ASM_ARCH_MXC_MX1_H__
-#define __ASM_ARCH_MXC_MX1_H__
+#ifndef __MACH_MX1_H__
+#define __MACH_MX1_H__
#include <mach/vmalloc.h>
/*
* Memory map
*/
-#define IMX_IO_PHYS 0x00200000
-#define IMX_IO_SIZE 0x00100000
-#define IMX_IO_BASE VMALLOC_END
+#define MX1_IO_BASE_ADDR 0x00200000
+#define MX1_IO_SIZE SZ_1M
+#define MX1_IO_BASE_ADDR_VIRT VMALLOC_END
-#define IMX_CS0_PHYS 0x10000000
-#define IMX_CS0_SIZE 0x02000000
+#define MX1_CS0_PHYS 0x10000000
+#define MX1_CS0_SIZE 0x02000000
-#define IMX_CS1_PHYS 0x12000000
-#define IMX_CS1_SIZE 0x01000000
+#define MX1_CS1_PHYS 0x12000000
+#define MX1_CS1_SIZE 0x01000000
-#define IMX_CS2_PHYS 0x13000000
-#define IMX_CS2_SIZE 0x01000000
+#define MX1_CS2_PHYS 0x13000000
+#define MX1_CS2_SIZE 0x01000000
-#define IMX_CS3_PHYS 0x14000000
-#define IMX_CS3_SIZE 0x01000000
+#define MX1_CS3_PHYS 0x14000000
+#define MX1_CS3_SIZE 0x01000000
-#define IMX_CS4_PHYS 0x15000000
-#define IMX_CS4_SIZE 0x01000000
+#define MX1_CS4_PHYS 0x15000000
+#define MX1_CS4_SIZE 0x01000000
-#define IMX_CS5_PHYS 0x16000000
-#define IMX_CS5_SIZE 0x01000000
+#define MX1_CS5_PHYS 0x16000000
+#define MX1_CS5_SIZE 0x01000000
/*
* Register BASEs, based on OFFSETs
*/
-#define AIPI1_BASE_ADDR (0x00000 + IMX_IO_PHYS)
-#define WDT_BASE_ADDR (0x01000 + IMX_IO_PHYS)
-#define TIM1_BASE_ADDR (0x02000 + IMX_IO_PHYS)
-#define TIM2_BASE_ADDR (0x03000 + IMX_IO_PHYS)
-#define RTC_BASE_ADDR (0x04000 + IMX_IO_PHYS)
-#define LCDC_BASE_ADDR (0x05000 + IMX_IO_PHYS)
-#define UART1_BASE_ADDR (0x06000 + IMX_IO_PHYS)
-#define UART2_BASE_ADDR (0x07000 + IMX_IO_PHYS)
-#define PWM_BASE_ADDR (0x08000 + IMX_IO_PHYS)
-#define DMA_BASE_ADDR (0x09000 + IMX_IO_PHYS)
-#define AIPI2_BASE_ADDR (0x10000 + IMX_IO_PHYS)
-#define SIM_BASE_ADDR (0x11000 + IMX_IO_PHYS)
-#define USBD_BASE_ADDR (0x12000 + IMX_IO_PHYS)
-#define SPI1_BASE_ADDR (0x13000 + IMX_IO_PHYS)
-#define MMC_BASE_ADDR (0x14000 + IMX_IO_PHYS)
-#define ASP_BASE_ADDR (0x15000 + IMX_IO_PHYS)
-#define BTA_BASE_ADDR (0x16000 + IMX_IO_PHYS)
-#define I2C_BASE_ADDR (0x17000 + IMX_IO_PHYS)
-#define SSI_BASE_ADDR (0x18000 + IMX_IO_PHYS)
-#define SPI2_BASE_ADDR (0x19000 + IMX_IO_PHYS)
-#define MSHC_BASE_ADDR (0x1A000 + IMX_IO_PHYS)
-#define CCM_BASE_ADDR (0x1B000 + IMX_IO_PHYS)
-#define SCM_BASE_ADDR (0x1B804 + IMX_IO_PHYS)
-#define GPIO_BASE_ADDR (0x1C000 + IMX_IO_PHYS)
-#define EIM_BASE_ADDR (0x20000 + IMX_IO_PHYS)
-#define SDRAMC_BASE_ADDR (0x21000 + IMX_IO_PHYS)
-#define MMA_BASE_ADDR (0x22000 + IMX_IO_PHYS)
-#define AVIC_BASE_ADDR (0x23000 + IMX_IO_PHYS)
-#define CSI_BASE_ADDR (0x24000 + IMX_IO_PHYS)
+#define MX1_AIPI1_BASE_ADDR (0x00000 + MX1_IO_BASE_ADDR)
+#define MX1_WDT_BASE_ADDR (0x01000 + MX1_IO_BASE_ADDR)
+#define MX1_TIM1_BASE_ADDR (0x02000 + MX1_IO_BASE_ADDR)
+#define MX1_TIM2_BASE_ADDR (0x03000 + MX1_IO_BASE_ADDR)
+#define MX1_RTC_BASE_ADDR (0x04000 + MX1_IO_BASE_ADDR)
+#define MX1_LCDC_BASE_ADDR (0x05000 + MX1_IO_BASE_ADDR)
+#define MX1_UART1_BASE_ADDR (0x06000 + MX1_IO_BASE_ADDR)
+#define MX1_UART2_BASE_ADDR (0x07000 + MX1_IO_BASE_ADDR)
+#define MX1_PWM_BASE_ADDR (0x08000 + MX1_IO_BASE_ADDR)
+#define MX1_DMA_BASE_ADDR (0x09000 + MX1_IO_BASE_ADDR)
+#define MX1_AIPI2_BASE_ADDR (0x10000 + MX1_IO_BASE_ADDR)
+#define MX1_SIM_BASE_ADDR (0x11000 + MX1_IO_BASE_ADDR)
+#define MX1_USBD_BASE_ADDR (0x12000 + MX1_IO_BASE_ADDR)
+#define MX1_SPI1_BASE_ADDR (0x13000 + MX1_IO_BASE_ADDR)
+#define MX1_MMC_BASE_ADDR (0x14000 + MX1_IO_BASE_ADDR)
+#define MX1_ASP_BASE_ADDR (0x15000 + MX1_IO_BASE_ADDR)
+#define MX1_BTA_BASE_ADDR (0x16000 + MX1_IO_BASE_ADDR)
+#define MX1_I2C_BASE_ADDR (0x17000 + MX1_IO_BASE_ADDR)
+#define MX1_SSI_BASE_ADDR (0x18000 + MX1_IO_BASE_ADDR)
+#define MX1_SPI2_BASE_ADDR (0x19000 + MX1_IO_BASE_ADDR)
+#define MX1_MSHC_BASE_ADDR (0x1A000 + MX1_IO_BASE_ADDR)
+#define MX1_CCM_BASE_ADDR (0x1B000 + MX1_IO_BASE_ADDR)
+#define MX1_SCM_BASE_ADDR (0x1B804 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO_BASE_ADDR (0x1C000 + MX1_IO_BASE_ADDR)
+#define MX1_EIM_BASE_ADDR (0x20000 + MX1_IO_BASE_ADDR)
+#define MX1_SDRAMC_BASE_ADDR (0x21000 + MX1_IO_BASE_ADDR)
+#define MX1_MMA_BASE_ADDR (0x22000 + MX1_IO_BASE_ADDR)
+#define MX1_AVIC_BASE_ADDR (0x23000 + MX1_IO_BASE_ADDR)
+#define MX1_CSI_BASE_ADDR (0x24000 + MX1_IO_BASE_ADDR)
/* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x) ((x) - IMX_IO_PHYS + IMX_IO_BASE)
-
-/* define macros needed for entry-macro.S */
-#define AVIC_IO_ADDRESS(x) IO_ADDRESS(x)
+#define MX1_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX1_IO))
/* fixed interrput numbers */
-#define INT_SOFTINT 0
-#define CSI_INT 6
-#define DSPA_MAC_INT 7
-#define DSPA_INT 8
-#define COMP_INT 9
-#define MSHC_XINT 10
-#define GPIO_INT_PORTA 11
-#define GPIO_INT_PORTB 12
-#define GPIO_INT_PORTC 13
-#define LCDC_INT 14
-#define SIM_INT 15
-#define SIM_DATA_INT 16
-#define RTC_INT 17
-#define RTC_SAMINT 18
-#define UART2_MINT_PFERR 19
-#define UART2_MINT_RTS 20
-#define UART2_MINT_DTR 21
-#define UART2_MINT_UARTC 22
-#define UART2_MINT_TX 23
-#define UART2_MINT_RX 24
-#define UART1_MINT_PFERR 25
-#define UART1_MINT_RTS 26
-#define UART1_MINT_DTR 27
-#define UART1_MINT_UARTC 28
-#define UART1_MINT_TX 29
-#define UART1_MINT_RX 30
-#define VOICE_DAC_INT 31
-#define VOICE_ADC_INT 32
-#define PEN_DATA_INT 33
-#define PWM_INT 34
-#define SDHC_INT 35
-#define I2C_INT 39
-#define CSPI_INT 41
-#define SSI_TX_INT 42
-#define SSI_TX_ERR_INT 43
-#define SSI_RX_INT 44
-#define SSI_RX_ERR_INT 45
-#define TOUCH_INT 46
-#define USBD_INT0 47
-#define USBD_INT1 48
-#define USBD_INT2 49
-#define USBD_INT3 50
-#define USBD_INT4 51
-#define USBD_INT5 52
-#define USBD_INT6 53
-#define BTSYS_INT 55
-#define BTTIM_INT 56
-#define BTWUI_INT 57
-#define TIM2_INT 58
-#define TIM1_INT 59
-#define DMA_ERR 60
-#define DMA_INT 61
-#define GPIO_INT_PORTD 62
-#define WDT_INT 63
+#define MX1_INT_SOFTINT 0
+#define MX1_CSI_INT 6
+#define MX1_DSPA_MAC_INT 7
+#define MX1_DSPA_INT 8
+#define MX1_COMP_INT 9
+#define MX1_MSHC_XINT 10
+#define MX1_GPIO_INT_PORTA 11
+#define MX1_GPIO_INT_PORTB 12
+#define MX1_GPIO_INT_PORTC 13
+#define MX1_LCDC_INT 14
+#define MX1_SIM_INT 15
+#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_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_CSPI_INT 41
+#define MX1_SSI_TX_INT 42
+#define MX1_SSI_TX_ERR_INT 43
+#define MX1_SSI_RX_INT 44
+#define MX1_SSI_RX_ERR_INT 45
+#define MX1_TOUCH_INT 46
+#define MX1_USBD_INT0 47
+#define MX1_USBD_INT1 48
+#define MX1_USBD_INT2 49
+#define MX1_USBD_INT3 50
+#define MX1_USBD_INT4 51
+#define MX1_USBD_INT5 52
+#define MX1_USBD_INT6 53
+#define MX1_BTSYS_INT 55
+#define MX1_BTTIM_INT 56
+#define MX1_BTWUI_INT 57
+#define MX1_TIM2_INT 58
+#define MX1_TIM1_INT 59
+#define MX1_DMA_ERR 60
+#define MX1_DMA_INT 61
+#define MX1_GPIO_INT_PORTD 62
+#define MX1_WDT_INT 63
/* DMA */
-#define DMA_REQ_UART3_T 2
-#define DMA_REQ_UART3_R 3
-#define DMA_REQ_SSI2_T 4
-#define DMA_REQ_SSI2_R 5
-#define DMA_REQ_CSI_STAT 6
-#define DMA_REQ_CSI_R 7
-#define DMA_REQ_MSHC 8
-#define DMA_REQ_DSPA_DCT_DOUT 9
-#define DMA_REQ_DSPA_DCT_DIN 10
-#define DMA_REQ_DSPA_MAC 11
-#define DMA_REQ_EXT 12
-#define DMA_REQ_SDHC 13
-#define DMA_REQ_SPI1_R 14
-#define DMA_REQ_SPI1_T 15
-#define DMA_REQ_SSI_T 16
-#define DMA_REQ_SSI_R 17
-#define DMA_REQ_ASP_DAC 18
-#define DMA_REQ_ASP_ADC 19
-#define DMA_REQ_USP_EP(x) (20 + (x))
-#define DMA_REQ_SPI2_R 26
-#define DMA_REQ_SPI2_T 27
-#define DMA_REQ_UART2_T 28
-#define DMA_REQ_UART2_R 29
-#define DMA_REQ_UART1_T 30
-#define DMA_REQ_UART1_R 31
-
-#endif /* __ASM_ARCH_MXC_MX1_H__ */
+#define MX1_DMA_REQ_UART3_T 2
+#define MX1_DMA_REQ_UART3_R 3
+#define MX1_DMA_REQ_SSI2_T 4
+#define MX1_DMA_REQ_SSI2_R 5
+#define MX1_DMA_REQ_CSI_STAT 6
+#define MX1_DMA_REQ_CSI_R 7
+#define MX1_DMA_REQ_MSHC 8
+#define MX1_DMA_REQ_DSPA_DCT_DOUT 9
+#define MX1_DMA_REQ_DSPA_DCT_DIN 10
+#define MX1_DMA_REQ_DSPA_MAC 11
+#define MX1_DMA_REQ_EXT 12
+#define MX1_DMA_REQ_SDHC 13
+#define MX1_DMA_REQ_SPI1_R 14
+#define MX1_DMA_REQ_SPI1_T 15
+#define MX1_DMA_REQ_SSI_T 16
+#define MX1_DMA_REQ_SSI_R 17
+#define MX1_DMA_REQ_ASP_DAC 18
+#define MX1_DMA_REQ_ASP_ADC 19
+#define MX1_DMA_REQ_USP_EP(x) (20 + (x))
+#define MX1_DMA_REQ_SPI2_R 26
+#define MX1_DMA_REQ_SPI2_T 27
+#define MX1_DMA_REQ_UART2_T 28
+#define MX1_DMA_REQ_UART2_R 29
+#define MX1_DMA_REQ_UART1_T 30
+#define MX1_DMA_REQ_UART1_R 31
+
+/*
+ * This doesn't depend on IMX_NEEDS_DEPRECATED_SYMBOLS
+ * to not break drivers/usb/gadget/imx_udc. Should go
+ * away after this driver uses the new name.
+ */
+#define USBD_INT0 MX1_USBD_INT0
+
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
+/* these should go away */
+#define IMX_IO_PHYS MX1_IO_BASE_ADDR
+#define IMX_IO_SIZE MX1_IO_SIZE
+#define IMX_IO_BASE MX1_IO_BASE_ADDR_VIRT
+#define IMX_CS0_PHYS MX1_CS0_PHYS
+#define IMX_CS0_SIZE MX1_CS0_SIZE
+#define IMX_CS1_PHYS MX1_CS1_PHYS
+#define IMX_CS1_SIZE MX1_CS1_SIZE
+#define IMX_CS2_PHYS MX1_CS2_PHYS
+#define IMX_CS2_SIZE MX1_CS2_SIZE
+#define IMX_CS3_PHYS MX1_CS3_PHYS
+#define IMX_CS3_SIZE MX1_CS3_SIZE
+#define IMX_CS4_PHYS MX1_CS4_PHYS
+#define IMX_CS4_SIZE MX1_CS4_SIZE
+#define IMX_CS5_PHYS MX1_CS5_PHYS
+#define IMX_CS5_SIZE MX1_CS5_SIZE
+#define AIPI1_BASE_ADDR MX1_AIPI1_BASE_ADDR
+#define WDT_BASE_ADDR MX1_WDT_BASE_ADDR
+#define TIM1_BASE_ADDR MX1_TIM1_BASE_ADDR
+#define TIM2_BASE_ADDR MX1_TIM2_BASE_ADDR
+#define RTC_BASE_ADDR MX1_RTC_BASE_ADDR
+#define LCDC_BASE_ADDR MX1_LCDC_BASE_ADDR
+#define UART1_BASE_ADDR MX1_UART1_BASE_ADDR
+#define UART2_BASE_ADDR MX1_UART2_BASE_ADDR
+#define PWM_BASE_ADDR MX1_PWM_BASE_ADDR
+#define DMA_BASE_ADDR MX1_DMA_BASE_ADDR
+#define AIPI2_BASE_ADDR MX1_AIPI2_BASE_ADDR
+#define SIM_BASE_ADDR MX1_SIM_BASE_ADDR
+#define USBD_BASE_ADDR MX1_USBD_BASE_ADDR
+#define SPI1_BASE_ADDR MX1_SPI1_BASE_ADDR
+#define MMC_BASE_ADDR MX1_MMC_BASE_ADDR
+#define ASP_BASE_ADDR MX1_ASP_BASE_ADDR
+#define BTA_BASE_ADDR MX1_BTA_BASE_ADDR
+#define I2C_BASE_ADDR MX1_I2C_BASE_ADDR
+#define SSI_BASE_ADDR MX1_SSI_BASE_ADDR
+#define SPI2_BASE_ADDR MX1_SPI2_BASE_ADDR
+#define MSHC_BASE_ADDR MX1_MSHC_BASE_ADDR
+#define CCM_BASE_ADDR MX1_CCM_BASE_ADDR
+#define SCM_BASE_ADDR MX1_SCM_BASE_ADDR
+#define GPIO_BASE_ADDR MX1_GPIO_BASE_ADDR
+#define EIM_BASE_ADDR MX1_EIM_BASE_ADDR
+#define SDRAMC_BASE_ADDR MX1_SDRAMC_BASE_ADDR
+#define MMA_BASE_ADDR MX1_MMA_BASE_ADDR
+#define AVIC_BASE_ADDR MX1_AVIC_BASE_ADDR
+#define CSI_BASE_ADDR MX1_CSI_BASE_ADDR
+#define IO_ADDRESS(x) MX1_IO_ADDRESS(x)
+#define AVIC_IO_ADDRESS(x) IO_ADDRESS(x)
+#define INT_SOFTINT MX1_INT_SOFTINT
+#define CSI_INT MX1_CSI_INT
+#define DSPA_MAC_INT MX1_DSPA_MAC_INT
+#define DSPA_INT MX1_DSPA_INT
+#define COMP_INT MX1_COMP_INT
+#define MSHC_XINT MX1_MSHC_XINT
+#define GPIO_INT_PORTA MX1_GPIO_INT_PORTA
+#define GPIO_INT_PORTB MX1_GPIO_INT_PORTB
+#define GPIO_INT_PORTC MX1_GPIO_INT_PORTC
+#define LCDC_INT MX1_LCDC_INT
+#define SIM_INT MX1_SIM_INT
+#define SIM_DATA_INT MX1_SIM_DATA_INT
+#define RTC_INT MX1_RTC_INT
+#define RTC_SAMINT MX1_RTC_SAMINT
+#define UART2_MINT_PFERR MX1_UART2_MINT_PFERR
+#define UART2_MINT_RTS MX1_UART2_MINT_RTS
+#define UART2_MINT_DTR MX1_UART2_MINT_DTR
+#define UART2_MINT_UARTC MX1_UART2_MINT_UARTC
+#define UART2_MINT_TX MX1_UART2_MINT_TX
+#define UART2_MINT_RX MX1_UART2_MINT_RX
+#define UART1_MINT_PFERR MX1_UART1_MINT_PFERR
+#define UART1_MINT_RTS MX1_UART1_MINT_RTS
+#define UART1_MINT_DTR MX1_UART1_MINT_DTR
+#define UART1_MINT_UARTC MX1_UART1_MINT_UARTC
+#define UART1_MINT_TX MX1_UART1_MINT_TX
+#define UART1_MINT_RX MX1_UART1_MINT_RX
+#define VOICE_DAC_INT MX1_VOICE_DAC_INT
+#define VOICE_ADC_INT MX1_VOICE_ADC_INT
+#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 CSPI_INT MX1_CSPI_INT
+#define SSI_TX_INT MX1_SSI_TX_INT
+#define SSI_TX_ERR_INT MX1_SSI_TX_ERR_INT
+#define SSI_RX_INT MX1_SSI_RX_INT
+#define SSI_RX_ERR_INT MX1_SSI_RX_ERR_INT
+#define TOUCH_INT MX1_TOUCH_INT
+#define USBD_INT1 MX1_USBD_INT1
+#define USBD_INT2 MX1_USBD_INT2
+#define USBD_INT3 MX1_USBD_INT3
+#define USBD_INT4 MX1_USBD_INT4
+#define USBD_INT5 MX1_USBD_INT5
+#define USBD_INT6 MX1_USBD_INT6
+#define BTSYS_INT MX1_BTSYS_INT
+#define BTTIM_INT MX1_BTTIM_INT
+#define BTWUI_INT MX1_BTWUI_INT
+#define TIM2_INT MX1_TIM2_INT
+#define TIM1_INT MX1_TIM1_INT
+#define DMA_ERR MX1_DMA_ERR
+#define DMA_INT MX1_DMA_INT
+#define GPIO_INT_PORTD MX1_GPIO_INT_PORTD
+#define WDT_INT MX1_WDT_INT
+#define DMA_REQ_UART3_T MX1_DMA_REQ_UART3_T
+#define DMA_REQ_UART3_R MX1_DMA_REQ_UART3_R
+#define DMA_REQ_SSI2_T MX1_DMA_REQ_SSI2_T
+#define DMA_REQ_SSI2_R MX1_DMA_REQ_SSI2_R
+#define DMA_REQ_CSI_STAT MX1_DMA_REQ_CSI_STAT
+#define DMA_REQ_CSI_R MX1_DMA_REQ_CSI_R
+#define DMA_REQ_MSHC MX1_DMA_REQ_MSHC
+#define DMA_REQ_DSPA_DCT_DOUT MX1_DMA_REQ_DSPA_DCT_DOUT
+#define DMA_REQ_DSPA_DCT_DIN MX1_DMA_REQ_DSPA_DCT_DIN
+#define DMA_REQ_DSPA_MAC MX1_DMA_REQ_DSPA_MAC
+#define DMA_REQ_EXT MX1_DMA_REQ_EXT
+#define DMA_REQ_SDHC MX1_DMA_REQ_SDHC
+#define DMA_REQ_SPI1_R MX1_DMA_REQ_SPI1_R
+#define DMA_REQ_SPI1_T MX1_DMA_REQ_SPI1_T
+#define DMA_REQ_SSI_T MX1_DMA_REQ_SSI_T
+#define DMA_REQ_SSI_R MX1_DMA_REQ_SSI_R
+#define DMA_REQ_ASP_DAC MX1_DMA_REQ_ASP_DAC
+#define DMA_REQ_ASP_ADC MX1_DMA_REQ_ASP_ADC
+#define DMA_REQ_USP_EP(x) MX1_DMA_REQ_USP_EP(x)
+#define DMA_REQ_SPI2_R MX1_DMA_REQ_SPI2_R
+#define DMA_REQ_SPI2_T MX1_DMA_REQ_SPI2_T
+#define DMA_REQ_UART2_T MX1_DMA_REQ_UART2_T
+#define DMA_REQ_UART2_R MX1_DMA_REQ_UART2_R
+#define DMA_REQ_UART1_T MX1_DMA_REQ_UART1_T
+#define DMA_REQ_UART1_R MX1_DMA_REQ_UART1_R
+#endif /* ifdef IMX_NEEDS_DEPRECATED_SYMBOLS */
+
+#endif /* ifndef __MACH_MX1_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h
index bb297d8765a..ed98b9c9f38 100644
--- a/arch/arm/plat-mxc/include/mach/mx21.h
+++ b/arch/arm/plat-mxc/include/mach/mx21.h
@@ -22,8 +22,8 @@
* MA 02110-1301, USA.
*/
-#ifndef __ASM_ARCH_MXC_MX21_H__
-#define __ASM_ARCH_MXC_MX21_H__
+#ifndef __MACH_MX21_H__
+#define __MACH_MX21_H__
#define MX21_AIPI_BASE_ADDR 0x10000000
#define MX21_AIPI_BASE_ADDR_VIRT 0xf4000000
@@ -92,6 +92,11 @@
#define MX21_IRAM_BASE_ADDR 0xffffe800 /* internal ram */
+#define MX21_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX21_AIPI) ?: \
+ IMX_IO_ADDRESS(x, MX21_SAHB1) ?: \
+ IMX_IO_ADDRESS(x, MX21_X_MEMC))
+
/* fixed interrupt numbers */
#define MX21_INT_CSPI3 6
#define MX21_INT_GPIO 8
@@ -179,6 +184,7 @@
#define MX21_DMA_REQ_CSI_STAT 30
#define MX21_DMA_REQ_CSI_RX 31
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
/* these should go away */
#define SDRAM_BASE_ADDR MX21_SDRAM_BASE_ADDR
#define CSD1_BASE_ADDR MX21_CSD1_BASE_ADDR
@@ -211,5 +217,6 @@
#define DMA_REQ_FIRI_RX MX21_DMA_REQ_FIRI_RX
#define DMA_REQ_BMI_TX MX21_DMA_REQ_BMI_TX
#define DMA_REQ_BMI_RX MX21_DMA_REQ_BMI_RX
+#endif
-#endif /* __ASM_ARCH_MXC_MX21_H__ */
+#endif /* ifndef __MACH_MX21_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
index 854e2dc5848..4eb6e334bda 100644
--- a/arch/arm/plat-mxc/include/mach/mx25.h
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -22,27 +22,27 @@
#define MX25_GPIO3_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xa4000)
#define MX25_GPIO4_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0x9c000)
-#define MX25_AIPS1_IO_ADDRESS(x) \
- (((x) - MX25_AIPS1_BASE_ADDR) + MX25_AIPS1_BASE_ADDR_VIRT)
-#define MX25_AIPS2_IO_ADDRESS(x) \
- (((x) - MX25_AIPS2_BASE_ADDR) + MX25_AIPS2_BASE_ADDR_VIRT)
-#define MX25_AVIC_IO_ADDRESS(x) \
- (((x) - MX25_AVIC_BASE_ADDR) + MX25_AVIC_BASE_ADDR_VIRT)
+#define MX25_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX25_AIPS1) ?: \
+ IMX_IO_ADDRESS(x, MX25_AIPS2) ?: \
+ IMX_IO_ADDRESS(x, MX25_AVIC))
-#define __in_range(addr, name) ((addr) >= name##_BASE_ADDR && (addr) < name##_BASE_ADDR + name##_SIZE)
-
-#define MX25_IO_ADDRESS(x) \
- (void __force __iomem *) \
- (__in_range(x, MX25_AIPS1) ? MX25_AIPS1_IO_ADDRESS(x) : \
- __in_range(x, MX25_AIPS2) ? MX25_AIPS2_IO_ADDRESS(x) : \
- __in_range(x, MX25_AVIC) ? MX25_AVIC_IO_ADDRESS(x) : \
- 0xDEADBEEF)
-
-#define UART1_BASE_ADDR 0x43f90000
-#define UART2_BASE_ADDR 0x43f94000
+#define MX25_UART1_BASE_ADDR 0x43f90000
+#define MX25_UART2_BASE_ADDR 0x43f94000
#define MX25_FEC_BASE_ADDR 0x50038000
+#define MX25_NFC_BASE_ADDR 0xbb000000
+#define MX25_DRYICE_BASE_ADDR 0x53ffc000
+#define MX25_LCDC_BASE_ADDR 0x53fbc000
+#define MX25_INT_DRYICE 25
#define MX25_INT_FEC 57
+#define MX25_INT_NANDFC 33
+#define MX25_INT_LCDC 39
+
+#if defined(IMX_NEEDS_DEPRECATED_SYMBOLS)
+#define UART1_BASE_ADDR MX25_UART1_BASE_ADDR
+#define UART2_BASE_ADDR MX25_UART2_BASE_ADDR
+#endif
-#endif /* __MACH_MX25_H__ */
+#endif /* ifndef __MACH_MX25_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index e2ae19f5171..bae9cd75bee 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -21,8 +21,12 @@
* MA 02110-1301, USA.
*/
-#ifndef __ASM_ARCH_MXC_MX27_H__
-#define __ASM_ARCH_MXC_MX27_H__
+#ifndef __MACH_MX27_H__
+#define __MACH_MX27_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
#define MX27_AIPI_BASE_ADDR 0x10000000
#define MX27_AIPI_BASE_ADDR_VIRT 0xf4000000
@@ -109,11 +113,31 @@
#define MX27_M3IF_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x3000)
#define MX27_PCMCIA_CTL_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x4000)
+#define MX27_WEIM_CSCRx_BASE_ADDR(cs) (MX27_WEIM_BASE_ADDR + (cs) * 0x10)
+#define MX27_WEIM_CSCRxU(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs))
+#define MX27_WEIM_CSCRxL(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs) + 0x4)
+#define MX27_WEIM_CSCRxA(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs) + 0x8)
+
#define MX27_PCMCIA_MEM_BASE_ADDR 0xdc000000
/* IRAM */
#define MX27_IRAM_BASE_ADDR 0xffff4c00 /* internal ram */
+#define MX27_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX27_AIPI) ?: \
+ IMX_IO_ADDRESS(x, MX27_SAHB1) ?: \
+ IMX_IO_ADDRESS(x, MX27_X_MEMC))
+
+#ifndef __ASSEMBLER__
+static inline void mx27_setup_weimcs(size_t cs,
+ unsigned upper, unsigned lower, unsigned addional)
+{
+ __raw_writel(upper, MX27_IO_ADDRESS(MX27_WEIM_CSCRxU(cs)));
+ __raw_writel(lower, MX27_IO_ADDRESS(MX27_WEIM_CSCRxL(cs)));
+ __raw_writel(addional, MX27_IO_ADDRESS(MX27_WEIM_CSCRxA(cs)));
+}
+#endif
+
/* fixed interrupt numbers */
#define MX27_INT_I2C2 1
#define MX27_INT_GPT6 2
@@ -225,6 +249,7 @@
extern int mx27_revision(void);
#endif
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
/* these should go away */
#define MSHC_BASE_ADDR MX27_MSHC_BASE_ADDR
#define GPT5_BASE_ADDR MX27_GPT5_BASE_ADDR
@@ -292,5 +317,6 @@ extern int mx27_revision(void);
#define DMA_REQ_UART6_RX MX27_DMA_REQ_UART6_RX
#define DMA_REQ_SDHC3 MX27_DMA_REQ_SDHC3
#define DMA_REQ_NFC MX27_DMA_REQ_NFC
+#endif
-#endif /* __ASM_ARCH_MXC_MX27_H__ */
+#endif /* ifndef __MACH_MX27_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx2x.h b/arch/arm/plat-mxc/include/mach/mx2x.h
index f2eaf140ed0..afb895a0b5b 100644
--- a/arch/arm/plat-mxc/include/mach/mx2x.h
+++ b/arch/arm/plat-mxc/include/mach/mx2x.h
@@ -20,8 +20,8 @@
* MA 02110-1301, USA.
*/
-#ifndef __ASM_ARCH_MXC_MX2x_H__
-#define __ASM_ARCH_MXC_MX2x_H__
+#ifndef __MACH_MX2x_H__
+#define __MACH_MX2x_H__
/* The following addresses are common between i.MX21 and i.MX27 */
@@ -176,6 +176,7 @@
#define MX2x_DMA_REQ_CSI_STAT 30
#define MX2x_DMA_REQ_CSI_RX 31
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
/* these should go away */
#define AIPI_BASE_ADDR MX2x_AIPI_BASE_ADDR
#define AIPI_BASE_ADDR_VIRT MX2x_AIPI_BASE_ADDR_VIRT
@@ -287,5 +288,6 @@
#define DMA_REQ_UART1_TX MX2x_DMA_REQ_UART1_TX
#define DMA_REQ_CSI_STAT MX2x_DMA_REQ_CSI_STAT
#define DMA_REQ_CSI_RX MX2x_DMA_REQ_CSI_RX
+#endif
-#endif /* __ASM_ARCH_MXC_MX2x_H__ */
+#endif /* ifndef __MACH_MX2x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index b8b47d139eb..fb90e119c2b 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -1,3 +1,10 @@
+#ifndef __MACH_MX31_H__
+#define __MACH_MX31_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
/*
* IRAM
*/
@@ -107,8 +114,30 @@
#define MX31_EMI_CTL_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x4000)
#define MX31_PCMCIA_CTL_BASE_ADDR MX31_EMI_CTL_BASE_ADDR
+#define MX31_WEIM_CSCRx_BASE_ADDR(cs) (MX31_WEIM_BASE_ADDR + (cs) * 0x10)
+#define MX31_WEIM_CSCRxU(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs))
+#define MX31_WEIM_CSCRxL(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs) + 0x4)
+#define MX31_WEIM_CSCRxA(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs) + 0x8)
+
#define MX31_PCMCIA_MEM_BASE_ADDR 0xbc000000
+#define MX31_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX31_AIPS1) ?: \
+ IMX_IO_ADDRESS(x, MX31_AIPS2) ?: \
+ IMX_IO_ADDRESS(x, MX31_AVIC) ?: \
+ IMX_IO_ADDRESS(x, MX31_X_MEMC) ?: \
+ IMX_IO_ADDRESS(x, MX31_SPBA0))
+
+#ifndef __ASSEMBLER__
+static inline void mx31_setup_weimcs(size_t cs,
+ unsigned upper, unsigned lower, unsigned addional)
+{
+ __raw_writel(upper, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(cs)));
+ __raw_writel(lower, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(cs)));
+ __raw_writel(addional, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(cs)));
+}
+#endif
+
#define MX31_INT_I2C3 3
#define MX31_INT_I2C2 4
#define MX31_INT_MPEG4_ENCODER 5
@@ -186,6 +215,7 @@
#define MX31_SYSTEM_REV_MIN MX31_CHIP_REV_1_0
#define MX31_SYSTEM_REV_NUM 3
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
/* these should go away */
#define ATA_BASE_ADDR MX31_ATA_BASE_ADDR
#define UART4_BASE_ADDR MX31_UART4_BASE_ADDR
@@ -216,3 +246,6 @@
#define MXC_INT_UART5 MX31_INT_UART5
#define MXC_INT_CCM MX31_INT_CCM
#define MXC_INT_PCMCIA MX31_INT_PCMCIA
+#endif
+
+#endif /* ifndef __MACH_MX31_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
index af871bce35b..526a55842ae 100644
--- a/arch/arm/plat-mxc/include/mach/mx35.h
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -1,3 +1,5 @@
+#ifndef __MACH_MX35_H__
+#define __MACH_MX35_H__
/*
* IRAM
*/
@@ -104,6 +106,13 @@
#define MX35_NFC_BASE_ADDR 0xbb000000
#define MX35_PCMCIA_MEM_BASE_ADDR 0xbc000000
+#define MX35_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MX35_AIPS1) ?: \
+ IMX_IO_ADDRESS(x, MX35_AIPS2) ?: \
+ IMX_IO_ADDRESS(x, MX35_AVIC) ?: \
+ IMX_IO_ADDRESS(x, MX35_X_MEMC) ?: \
+ IMX_IO_ADDRESS(x, MX35_SPBA0))
+
/*
* Interrupt numbers
*/
@@ -180,6 +189,7 @@
#define MX35_SYSTEM_REV_MIN MX35_CHIP_REV_1_0
#define MX35_SYSTEM_REV_NUM 3
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
/* these should go away */
#define MXC_FEC_BASE_ADDR MX35_FEC_BASE_ADDR
#define MXC_INT_OWIRE MX35_INT_OWIRE
@@ -195,3 +205,6 @@
#define MXC_INT_MLB MX35_INT_MLB
#define MXC_INT_SPDIF MX35_INT_SPDIF
#define MXC_INT_FEC MX35_INT_FEC
+#endif
+
+#endif /* ifndef __MACH_MX35_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h
index be69272407a..7a356de385f 100644
--- a/arch/arm/plat-mxc/include/mach/mx3x.h
+++ b/arch/arm/plat-mxc/include/mach/mx3x.h
@@ -8,8 +8,8 @@
* published by the Free Software Foundation.
*/
-#ifndef __ASM_ARCH_MXC_MX31_H__
-#define __ASM_ARCH_MXC_MX31_H__
+#ifndef __MACH_MX3x_H__
+#define __MACH_MX3x_H__
/*
* MX31 memory map:
@@ -269,6 +269,7 @@ static inline int mx31_revision(void)
}
#endif
+#ifdef IMX_NEEDS_DEPRECATED_SYMBOLS
/* these should go away */
#define L2CC_BASE_ADDR MX3x_L2CC_BASE_ADDR
#define L2CC_SIZE MX3x_L2CC_SIZE
@@ -401,5 +402,6 @@ static inline int mx31_revision(void)
#define CHIP_REV_3_2 MX3x_CHIP_REV_3_2
#define SYSTEM_REV_MIN MX3x_SYSTEM_REV_MIN
#define SYSTEM_REV_NUM MX3x_SYSTEM_REV_NUM
+#endif
-#endif /* __ASM_ARCH_MXC_MX31_H__ */
+#endif /* ifndef __MACH_MX3x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h
new file mode 100644
index 00000000000..5aad344d565
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx51.h
@@ -0,0 +1,445 @@
+#ifndef __ASM_ARCH_MXC_MX51_H__
+#define __ASM_ARCH_MXC_MX51_H__
+
+/*
+ * MX51 memory map:
+ *
+ *
+ * Virt Phys Size What
+ * ---------------------------------------------------------------------------
+ * FA3E0000 1FFE0000 128K IRAM (SCCv2 RAM)
+ * 30000000 256M GPU
+ * 40000000 512M IPU
+ * FA200000 60000000 1M DEBUG
+ * FB100000 70000000 1M SPBA 0
+ * FB000000 73F00000 1M AIPS 1
+ * FB200000 83F00000 1M AIPS 2
+ * 8FFFC000 16K TZIC (interrupt controller)
+ * 90000000 256M CSD0 SDRAM/DDR
+ * A0000000 256M CSD1 SDRAM/DDR
+ * B0000000 128M CS0 Flash
+ * B8000000 128M CS1 Flash
+ * C0000000 128M CS2 Flash
+ * C8000000 64M CS3 Flash
+ * CC000000 32M CS4 SRAM
+ * CE000000 32M CS5 SRAM
+ * CFFF0000 64K NFC (NAND Flash AXI)
+ *
+ */
+
+/*
+ * IROM
+ */
+#define MX51_IROM_BASE_ADDR 0x0
+#define MX51_IROM_SIZE SZ_64K
+
+/*
+ * IRAM
+ */
+#define MX51_IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */
+#define MX51_IRAM_BASE_ADDR_VIRT 0xFA3E0000
+#define MX51_IRAM_PARTITIONS 16
+#define MX51_IRAM_PARTITIONS_TO1 12
+#define MX51_IRAM_SIZE (MX51_IRAM_PARTITIONS * SZ_8K) /* 128KB */
+
+/*
+ * NFC
+ */
+#define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */
+#define MX51_NFC_AXI_SIZE SZ_64K
+
+/*
+ * Graphics Memory of GPU
+ */
+#define MX51_GPU_BASE_ADDR 0x20000000
+#define MX51_GPU2D_BASE_ADDR 0xD0000000
+
+#define MX51_TZIC_BASE_ADDR_TO1 0x8FFFC000
+#define MX51_TZIC_BASE_ADDR 0xE0000000
+
+#define MX51_DEBUG_BASE_ADDR 0x60000000
+#define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000
+#define MX51_DEBUG_SIZE SZ_1M
+#define MX51_ETB_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00001000)
+#define MX51_ETM_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00002000)
+#define MX51_TPIU_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00003000)
+#define MX51_CTI0_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00004000)
+#define MX51_CTI1_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00005000)
+#define MX51_CTI2_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00006000)
+#define MX51_CTI3_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00007000)
+#define MX51_CORTEX_DBG_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00008000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX51_SPBA0_BASE_ADDR 0x70000000
+#define MX51_SPBA0_BASE_ADDR_VIRT 0xFB100000
+#define MX51_SPBA0_SIZE SZ_1M
+
+#define MX51_MMC_SDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00004000)
+#define MX51_MMC_SDHC2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00008000)
+#define MX51_UART3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0000C000)
+#define MX51_CSPI1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00010000)
+#define MX51_SSI2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00014000)
+#define MX51_MMC_SDHC3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00020000)
+#define MX51_MMC_SDHC4_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00024000)
+#define MX51_SPDIF_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00028000)
+#define MX51_ATA_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00030000)
+#define MX51_SLIM_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00034000)
+#define MX51_HSI2C_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00038000)
+#define MX51_SPBA_CTRL_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0003C000)
+
+/*
+ * defines for SPBA modules
+ */
+#define MX51_SPBA_SDHC1 0x04
+#define MX51_SPBA_SDHC2 0x08
+#define MX51_SPBA_UART3 0x0C
+#define MX51_SPBA_CSPI1 0x10
+#define MX51_SPBA_SSI2 0x14
+#define MX51_SPBA_SDHC3 0x20
+#define MX51_SPBA_SDHC4 0x24
+#define MX51_SPBA_SPDIF 0x28
+#define MX51_SPBA_ATA 0x30
+#define MX51_SPBA_SLIM 0x34
+#define MX51_SPBA_HSI2C 0x38
+#define MX51_SPBA_CTRL 0x3C
+
+/*
+ * AIPS 1
+ */
+#define MX51_AIPS1_BASE_ADDR 0x73F00000
+#define MX51_AIPS1_BASE_ADDR_VIRT 0xFB000000
+#define MX51_AIPS1_SIZE SZ_1M
+
+#define MX51_OTG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00080000)
+#define MX51_GPIO1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00084000)
+#define MX51_GPIO2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00088000)
+#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x0008C000)
+#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00090000)
+#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00094000)
+#define MX51_WDOG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00098000)
+#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x0009C000)
+#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A0000)
+#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A4000)
+#define MX51_IOMUXC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A8000)
+#define MX51_EPIT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000AC000)
+#define MX51_EPIT2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B0000)
+#define MX51_PWM1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B4000)
+#define MX51_PWM2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B8000)
+#define MX51_UART1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000BC000)
+#define MX51_UART2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000C0000)
+#define MX51_SRC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D0000)
+#define MX51_CCM_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D4000)
+#define MX51_GPC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D8000)
+
+/*
+ * Defines for modules using static and dynamic DMA channels
+ */
+#define MX51_MXC_DMA_CHANNEL_IRAM 30
+#define MX51_MXC_DMA_CHANNEL_SPDIF_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MMC2 MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#ifdef CONFIG_SDMA_IRAM
+#define MX51_MXC_DMA_CHANNEL_SSI2_TX (MX51_MXC_DMA_CHANNEL_IRAM + 1)
+#else /*CONFIG_SDMA_IRAM */
+#define MX51_MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#endif /*CONFIG_SDMA_IRAM */
+#define MX51_MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
+
+/*
+ * AIPS 2
+ */
+#define MX51_AIPS2_BASE_ADDR 0x83F00000
+#define MX51_AIPS2_BASE_ADDR_VIRT 0xFB200000
+#define MX51_AIPS2_SIZE SZ_1M
+
+#define MX51_PLL1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00080000)
+#define MX51_PLL2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00084000)
+#define MX51_PLL3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00088000)
+#define MX51_AHBMAX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00094000)
+#define MX51_IIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00098000)
+#define MX51_CSU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x0009C000)
+#define MX51_ARM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A0000)
+#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A4000)
+#define MX51_FIRI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A8000)
+#define MX51_CSPI2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000AC000)
+#define MX51_SDMA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B0000)
+#define MX51_SCC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B4000)
+#define MX51_ROMCP_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B8000)
+#define MX51_RTIC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000BC000)
+#define MX51_CSPI3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C0000)
+#define MX51_I2C2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C4000)
+#define MX51_I2C1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C8000)
+#define MX51_SSI1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000CC000)
+#define MX51_AUDMUX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D0000)
+#define MX51_M4IF_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D8000)
+#define MX51_ESDCTL_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D9000)
+#define MX51_WEIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DA000)
+#define MX51_NFC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DB000)
+#define MX51_EMI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DBF00)
+#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DC000)
+#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E0000)
+#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E4000)
+#define MX51_SSI3BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E8000)
+#define MX51_MXC_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000EC000)
+#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F0000)
+#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F4000)
+#define MX51_SAHARA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F8000)
+
+/*
+ * Memory regions and CS
+ */
+#define MX51_GPU_CTRL_BASE_ADDR 0x30000000
+#define MX51_IPU_CTRL_BASE_ADDR 0x40000000
+#define MX51_CSD0_BASE_ADDR 0x90000000
+#define MX51_CSD1_BASE_ADDR 0xA0000000
+#define MX51_CS0_BASE_ADDR 0xB0000000
+#define MX51_CS1_BASE_ADDR 0xB8000000
+#define MX51_CS2_BASE_ADDR 0xC0000000
+#define MX51_CS3_BASE_ADDR 0xC8000000
+#define MX51_CS4_BASE_ADDR 0xCC000000
+#define MX51_CS5_BASE_ADDR 0xCE000000
+
+/* Does given address belongs to the specified memory region? */
+#define ADDRESS_IN_REGION(addr, start, size) \
+ (((addr) >= (start)) && ((addr) < (start)+(size)))
+
+/* Does given address belongs to the specified named `module'? */
+#define MX51_IS_MODULE(addr, module) \
+ ADDRESS_IN_REGION(addr, MX51_ ## module ## _BASE_ADDR, \
+ MX51_ ## module ## _SIZE)
+/*
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+
+#define MX51_IO_ADDRESS(x) \
+ (void __iomem *) \
+ (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \
+ MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \
+ MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \
+ MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \
+ MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
+ 0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+#define MX51_IRAM_IO_ADDRESS(x) \
+ (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
+
+#define MX51_DEBUG_IO_ADDRESS(x) \
+ (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
+
+#define MX51_SPBA0_IO_ADDRESS(x) \
+ (((x) - MX51_SPBA0_BASE_ADDR) + MX51_SPBA0_BASE_ADDR_VIRT)
+
+#define MX51_AIPS1_IO_ADDRESS(x) \
+ (((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT)
+
+#define MX51_AIPS2_IO_ADDRESS(x) \
+ (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
+
+#define MX51_IS_MEM_DEVICE_NONSHARED(x) 0
+
+/*
+ * DMA request assignments
+ */
+#define MX51_DMA_REQ_SSI3_TX1 47
+#define MX51_DMA_REQ_SSI3_RX1 46
+#define MX51_DMA_REQ_SPDIF 45
+#define MX51_DMA_REQ_UART3_TX 44
+#define MX51_DMA_REQ_UART3_RX 43
+#define MX51_DMA_REQ_SLIM_B_TX 42
+#define MX51_DMA_REQ_SDHC4 41
+#define MX51_DMA_REQ_SDHC3 40
+#define MX51_DMA_REQ_CSPI_TX 39
+#define MX51_DMA_REQ_CSPI_RX 38
+#define MX51_DMA_REQ_SSI3_TX2 37
+#define MX51_DMA_REQ_IPU 36
+#define MX51_DMA_REQ_SSI3_RX2 35
+#define MX51_DMA_REQ_EPIT2 34
+#define MX51_DMA_REQ_CTI2_1 33
+#define MX51_DMA_REQ_EMI_WR 32
+#define MX51_DMA_REQ_CTI2_0 31
+#define MX51_DMA_REQ_EMI_RD 30
+#define MX51_DMA_REQ_SSI1_TX1 29
+#define MX51_DMA_REQ_SSI1_RX1 28
+#define MX51_DMA_REQ_SSI1_TX2 27
+#define MX51_DMA_REQ_SSI1_RX2 26
+#define MX51_DMA_REQ_SSI2_TX1 25
+#define MX51_DMA_REQ_SSI2_RX1 24
+#define MX51_DMA_REQ_SSI2_TX2 23
+#define MX51_DMA_REQ_SSI2_RX2 22
+#define MX51_DMA_REQ_SDHC2 21
+#define MX51_DMA_REQ_SDHC1 20
+#define MX51_DMA_REQ_UART1_TX 19
+#define MX51_DMA_REQ_UART1_RX 18
+#define MX51_DMA_REQ_UART2_TX 17
+#define MX51_DMA_REQ_UART2_RX 16
+#define MX51_DMA_REQ_GPU 15
+#define MX51_DMA_REQ_EXTREQ1 14
+#define MX51_DMA_REQ_FIRI_TX 13
+#define MX51_DMA_REQ_FIRI_RX 12
+#define MX51_DMA_REQ_HS_I2C_RX 11
+#define MX51_DMA_REQ_HS_I2C_TX 10
+#define MX51_DMA_REQ_CSPI2_TX 9
+#define MX51_DMA_REQ_CSPI2_RX 8
+#define MX51_DMA_REQ_CSPI1_TX 7
+#define MX51_DMA_REQ_CSPI1_RX 6
+#define MX51_DMA_REQ_SLIM_B 5
+#define MX51_DMA_REQ_ATA_TX_END 4
+#define MX51_DMA_REQ_ATA_TX 3
+#define MX51_DMA_REQ_ATA_RX 2
+#define MX51_DMA_REQ_GPC 1
+#define MX51_DMA_REQ_VPU 0
+
+/*
+ * Interrupt numbers
+ */
+#define MX51_MXC_INT_BASE 0
+#define MX51_MXC_INT_RESV0 0
+#define MX51_MXC_INT_MMC_SDHC1 1
+#define MX51_MXC_INT_MMC_SDHC2 2
+#define MX51_MXC_INT_MMC_SDHC3 3
+#define MX51_MXC_INT_MMC_SDHC4 4
+#define MX51_MXC_INT_RESV5 5
+#define MX51_MXC_INT_SDMA 6
+#define MX51_MXC_INT_IOMUX 7
+#define MX51_MXC_INT_NFC 8
+#define MX51_MXC_INT_VPU 9
+#define MX51_MXC_INT_IPU_ERR 10
+#define MX51_MXC_INT_IPU_SYN 11
+#define MX51_MXC_INT_GPU 12
+#define MX51_MXC_INT_RESV13 13
+#define MX51_MXC_INT_USB_H1 14
+#define MX51_MXC_INT_EMI 15
+#define MX51_MXC_INT_USB_H2 16
+#define MX51_MXC_INT_USB_H3 17
+#define MX51_MXC_INT_USB_OTG 18
+#define MX51_MXC_INT_SAHARA_H0 19
+#define MX51_MXC_INT_SAHARA_H1 20
+#define MX51_MXC_INT_SCC_SMN 21
+#define MX51_MXC_INT_SCC_STZ 22
+#define MX51_MXC_INT_SCC_SCM 23
+#define MX51_MXC_INT_SRTC_NTZ 24
+#define MX51_MXC_INT_SRTC_TZ 25
+#define MX51_MXC_INT_RTIC 26
+#define MX51_MXC_INT_CSU 27
+#define MX51_MXC_INT_SLIM_B 28
+#define MX51_MXC_INT_SSI1 29
+#define MX51_MXC_INT_SSI2 30
+#define MX51_MXC_INT_UART1 31
+#define MX51_MXC_INT_UART2 32
+#define MX51_MXC_INT_UART3 33
+#define MX51_MXC_INT_RESV34 34
+#define MX51_MXC_INT_RESV35 35
+#define MX51_MXC_INT_CSPI1 36
+#define MX51_MXC_INT_CSPI2 37
+#define MX51_MXC_INT_CSPI 38
+#define MX51_MXC_INT_GPT 39
+#define MX51_MXC_INT_EPIT1 40
+#define MX51_MXC_INT_EPIT2 41
+#define MX51_MXC_INT_GPIO1_INT7 42
+#define MX51_MXC_INT_GPIO1_INT6 43
+#define MX51_MXC_INT_GPIO1_INT5 44
+#define MX51_MXC_INT_GPIO1_INT4 45
+#define MX51_MXC_INT_GPIO1_INT3 46
+#define MX51_MXC_INT_GPIO1_INT2 47
+#define MX51_MXC_INT_GPIO1_INT1 48
+#define MX51_MXC_INT_GPIO1_INT0 49
+#define MX51_MXC_INT_GPIO1_LOW 50
+#define MX51_MXC_INT_GPIO1_HIGH 51
+#define MX51_MXC_INT_GPIO2_LOW 52
+#define MX51_MXC_INT_GPIO2_HIGH 53
+#define MX51_MXC_INT_GPIO3_LOW 54
+#define MX51_MXC_INT_GPIO3_HIGH 55
+#define MX51_MXC_INT_GPIO4_LOW 56
+#define MX51_MXC_INT_GPIO4_HIGH 57
+#define MX51_MXC_INT_WDOG1 58
+#define MX51_MXC_INT_WDOG2 59
+#define MX51_MXC_INT_KPP 60
+#define MX51_MXC_INT_PWM1 61
+#define MX51_MXC_INT_I2C1 62
+#define MX51_MXC_INT_I2C2 63
+#define MX51_MXC_INT_HS_I2C 64
+#define MX51_MXC_INT_RESV65 65
+#define MX51_MXC_INT_RESV66 66
+#define MX51_MXC_INT_SIM_IPB 67
+#define MX51_MXC_INT_SIM_DAT 68
+#define MX51_MXC_INT_IIM 69
+#define MX51_MXC_INT_ATA 70
+#define MX51_MXC_INT_CCM1 71
+#define MX51_MXC_INT_CCM2 72
+#define MX51_MXC_INT_GPC1 73
+#define MX51_MXC_INT_GPC2 74
+#define MX51_MXC_INT_SRC 75
+#define MX51_MXC_INT_NM 76
+#define MX51_MXC_INT_PMU 77
+#define MX51_MXC_INT_CTI_IRQ 78
+#define MX51_MXC_INT_CTI1_TG0 79
+#define MX51_MXC_INT_CTI1_TG1 80
+#define MX51_MXC_INT_MCG_ERR 81
+#define MX51_MXC_INT_MCG_TMR 82
+#define MX51_MXC_INT_MCG_FUNC 83
+#define MX51_MXC_INT_GPU2_IRQ 84
+#define MX51_MXC_INT_GPU2_BUSY 85
+#define MX51_MXC_INT_RESV86 86
+#define MX51_MXC_INT_FEC 87
+#define MX51_MXC_INT_OWIRE 88
+#define MX51_MXC_INT_CTI1_TG2 89
+#define MX51_MXC_INT_SJC 90
+#define MX51_MXC_INT_SPDIF 91
+#define MX51_MXC_INT_TVE 92
+#define MX51_MXC_INT_FIRI 93
+#define MX51_MXC_INT_PWM2 94
+#define MX51_MXC_INT_SLIM_EXP 95
+#define MX51_MXC_INT_SSI3 96
+#define MX51_MXC_INT_EMI_BOOT 97
+#define MX51_MXC_INT_CTI1_TG3 98
+#define MX51_MXC_INT_SMC_RX 99
+#define MX51_MXC_INT_VPU_IDLE 100
+#define MX51_MXC_INT_EMI_NFC 101
+#define MX51_MXC_INT_GPU_IDLE 102
+
+/* silicon revisions specific to i.MX51 */
+#define MX51_CHIP_REV_1_0 0x10
+#define MX51_CHIP_REV_1_1 0x11
+#define MX51_CHIP_REV_1_2 0x12
+#define MX51_CHIP_REV_1_3 0x13
+#define MX51_CHIP_REV_2_0 0x20
+#define MX51_CHIP_REV_2_1 0x21
+#define MX51_CHIP_REV_2_2 0x22
+#define MX51_CHIP_REV_2_3 0x23
+#define MX51_CHIP_REV_3_0 0x30
+#define MX51_CHIP_REV_3_1 0x31
+#define MX51_CHIP_REV_3_2 0x32
+
+/* Mandatory defines used globally */
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+
+extern int mx51_revision(void);
+#endif
+
+#endif /* __ASM_ARCH_MXC_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 51990536b84..a790bf21297 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -30,6 +30,7 @@
#define MXC_CPU_MX27 27
#define MXC_CPU_MX31 31
#define MXC_CPU_MX35 35
+#define MXC_CPU_MX51 51
#define MXC_CPU_MXC91231 91231
#ifndef __ASSEMBLY__
@@ -108,6 +109,18 @@ extern unsigned int __mxc_cpu_type;
# define cpu_is_mx35() (0)
#endif
+#ifdef CONFIG_ARCH_MX5
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX51
+# endif
+# define cpu_is_mx51() (mxc_cpu_type == MXC_CPU_MX51)
+#else
+# define cpu_is_mx51() (0)
+#endif
+
#ifdef CONFIG_ARCH_MXC91231
# ifdef mxc_cpu_type
# undef mxc_cpu_type
@@ -121,9 +134,10 @@ extern unsigned int __mxc_cpu_type;
#endif
#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
-#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10)
-#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4)
-#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8)
+/* These are deprecated, use mx[23][157]_setup_weimcs instead. */
+#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10))
+#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10 + 0x4))
+#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10 + 0x8))
#endif
#define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
diff --git a/arch/arm/plat-mxc/include/mach/mxc91231.h b/arch/arm/plat-mxc/include/mach/mxc91231.h
index 81484d1ef23..5182b986b78 100644
--- a/arch/arm/plat-mxc/include/mach/mxc91231.h
+++ b/arch/arm/plat-mxc/include/mach/mxc91231.h
@@ -184,60 +184,22 @@
#define MXC91231_CS4_BASE_ADDR 0xB4000000
#define MXC91231_CS5_BASE_ADDR 0xB6000000
-/* Is given address belongs to the specified memory region? */
-#define ADDRESS_IN_REGION(addr, start, size) \
- (((addr) >= (start)) && ((addr) < (start)+(size)))
-
-/* Is given address belongs to the specified named `module'? */
-#define MXC91231_IS_MODULE(addr, module) \
- ADDRESS_IN_REGION(addr, MXC91231_ ## module ## _BASE_ADDR, \
- MXC91231_ ## module ## _SIZE)
/*
* This macro defines the physical to virtual address mapping for all the
* peripheral modules. It is used by passing in the physical address as x
* and returning the virtual address. If the physical address is not mapped,
- * it returns 0xDEADBEEF
- */
-
-#define MXC91231_IO_ADDRESS(x) \
- (void __iomem *) \
- (MXC91231_IS_MODULE(x, L2CC) ? MXC91231_L2CC_IO_ADDRESS(x) : \
- MXC91231_IS_MODULE(x, AIPS1) ? MXC91231_AIPS1_IO_ADDRESS(x) : \
- MXC91231_IS_MODULE(x, AIPS2) ? MXC91231_AIPS2_IO_ADDRESS(x) : \
- MXC91231_IS_MODULE(x, SPBA0) ? MXC91231_SPBA0_IO_ADDRESS(x) : \
- MXC91231_IS_MODULE(x, SPBA1) ? MXC91231_SPBA1_IO_ADDRESS(x) : \
- MXC91231_IS_MODULE(x, ROMP) ? MXC91231_ROMP_IO_ADDRESS(x) : \
- MXC91231_IS_MODULE(x, AVIC) ? MXC91231_AVIC_IO_ADDRESS(x) : \
- MXC91231_IS_MODULE(x, X_MEMC) ? MXC91231_X_MEMC_IO_ADDRESS(x) : \
- 0xDEADBEEF)
-
-
-/*
- * define the address mapping macros: in physical address order
+ * it returns 0.
*/
-#define MXC91231_L2CC_IO_ADDRESS(x) \
- (((x) - MXC91231_L2CC_BASE_ADDR) + MXC91231_L2CC_BASE_ADDR_VIRT)
-
-#define MXC91231_AIPS1_IO_ADDRESS(x) \
- (((x) - MXC91231_AIPS1_BASE_ADDR) + MXC91231_AIPS1_BASE_ADDR_VIRT)
-
-#define MXC91231_SPBA0_IO_ADDRESS(x) \
- (((x) - MXC91231_SPBA0_BASE_ADDR) + MXC91231_SPBA0_BASE_ADDR_VIRT)
-
-#define MXC91231_SPBA1_IO_ADDRESS(x) \
- (((x) - MXC91231_SPBA1_BASE_ADDR) + MXC91231_SPBA1_BASE_ADDR_VIRT)
-
-#define MXC91231_AIPS2_IO_ADDRESS(x) \
- (((x) - MXC91231_AIPS2_BASE_ADDR) + MXC91231_AIPS2_BASE_ADDR_VIRT)
-
-#define MXC91231_ROMP_IO_ADDRESS(x) \
- (((x) - MXC91231_ROMP_BASE_ADDR) + MXC91231_ROMP_BASE_ADDR_VIRT)
-
-#define MXC91231_AVIC_IO_ADDRESS(x) \
- (((x) - MXC91231_AVIC_BASE_ADDR) + MXC91231_AVIC_BASE_ADDR_VIRT)
-#define MXC91231_X_MEMC_IO_ADDRESS(x) \
- (((x) - MXC91231_X_MEMC_BASE_ADDR) + MXC91231_X_MEMC_BASE_ADDR_VIRT)
+#define MXC91231_IO_ADDRESS(x) ( \
+ IMX_IO_ADDRESS(x, MXC91231_L2CC) ?: \
+ IMX_IO_ADDRESS(x, MXC91231_X_MEMC) ?: \
+ IMX_IO_ADDRESS(x, MXC91231_ROMP) ?: \
+ IMX_IO_ADDRESS(x, MXC91231_AVIC) ?: \
+ IMX_IO_ADDRESS(x, MXC91231_AIPS1) ?: \
+ IMX_IO_ADDRESS(x, MXC91231_SPBA0) ?: \
+ IMX_IO_ADDRESS(x, MXC91231_SPBA1) ?: \
+ IMX_IO_ADDRESS(x, MXC91231_AIPS2))
/*
* Interrupt numbers
diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
index 8f796239393..4b9b8368c0c 100644
--- a/arch/arm/plat-mxc/include/mach/mxc_ehci.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
@@ -22,6 +22,10 @@
#define MXC_EHCI_POWER_PINS_ENABLED (1 << 5)
#define MXC_EHCI_TTL_ENABLED (1 << 6)
+#define MXC_EHCI_INTERNAL_PHY (1 << 7)
+#define MXC_EHCI_IPPUE_DOWN (1 << 8)
+#define MXC_EHCI_IPPUE_UP (1 << 9)
+
struct mxc_usbh_platform_data {
int (*init)(struct platform_device *pdev);
int (*exit)(struct platform_device *pdev);
diff --git a/arch/arm/plat-mxc/include/mach/ssi.h b/arch/arm/plat-mxc/include/mach/ssi.h
new file mode 100644
index 00000000000..c34ded523f1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/ssi.h
@@ -0,0 +1,18 @@
+#ifndef __MACH_SSI_H
+#define __MACH_SSI_H
+
+struct snd_ac97;
+
+extern unsigned char imx_ssi_fiq_start, imx_ssi_fiq_end;
+extern unsigned long imx_ssi_fiq_base, imx_ssi_fiq_tx_buffer, imx_ssi_fiq_rx_buffer;
+
+struct imx_ssi_platform_data {
+ unsigned int flags;
+#define IMX_SSI_DMA (1 << 0)
+#define IMX_SSI_USE_AC97 (1 << 1)
+ void (*ac97_reset) (struct snd_ac97 *ac97);
+ void (*ac97_warm_reset)(struct snd_ac97 *ac97);
+};
+
+#endif /* __MACH_SSI_H */
+
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/arch/arm/plat-mxc/include/mach/timex.h
index 527a6c24788..024416ed11c 100644
--- a/arch/arm/plat-mxc/include/mach/timex.h
+++ b/arch/arm/plat-mxc/include/mach/timex.h
@@ -28,6 +28,8 @@
#define CLOCK_TICK_RATE 16625000
#elif defined CONFIG_ARCH_MX25
#define CLOCK_TICK_RATE 16000000
+#elif defined CONFIG_ARCH_MX5
+#define CLOCK_TICK_RATE 8000000
#elif defined CONFIG_ARCH_MXC91231
#define CLOCK_TICK_RATE 13000000
#endif
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index d49384cb1e9..b6d3d0fddc4 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -1,8 +1,6 @@
/*
* arch/arm/plat-mxc/include/mach/uncompress.h
*
- *
- *
* Copyright (C) 1999 ARM Limited
* Copyright (C) Shane Nay (shane@minirl.com)
*
@@ -25,7 +23,6 @@
#define __MXC_BOOT_UNCOMPRESS
-#include <mach/hardware.h>
#include <asm/mach-types.h>
static unsigned long uart_base;
@@ -69,6 +66,7 @@ static inline void flush(void)
#define MX2X_UART1_BASE_ADDR 0x1000a000
#define MX3X_UART1_BASE_ADDR 0x43F90000
#define MX3X_UART2_BASE_ADDR 0x43F94000
+#define MX51_UART1_BASE_ADDR 0x73fbc000
static __inline__ void __arch_decomp_setup(unsigned long arch_id)
{
@@ -104,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
case MACH_TYPE_MAGX_ZN5:
uart_base = MX3X_UART2_BASE_ADDR;
break;
+ case MACH_TYPE_MX51_BABBAGE:
+ uart_base = MX51_UART1_BASE_ADDR;
+ break;
default:
break;
}
diff --git a/arch/arm/plat-mxc/iomux-mx1-mx2.c b/arch/arm/plat-mxc/iomux-mx1-mx2.c
deleted file mode 100644
index a37163ce280..00000000000
--- a/arch/arm/plat-mxc/iomux-mx1-mx2.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * arch/arm/mach-mxc/generic.c
- *
- * author: Sascha Hauer
- * Created: april 20th, 2004
- * Copyright: Synertronixx GmbH
- *
- * Common code for i.MX 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
- * 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/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/gpio.h>
-
-#include <mach/hardware.h>
-#include <asm/mach/map.h>
-#include <mach/iomux.h>
-
-void mxc_gpio_mode(int gpio_mode)
-{
- unsigned int pin = gpio_mode & GPIO_PIN_MASK;
- unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
- unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
- unsigned int tmp;
-
- /* Pullup enable */
- tmp = __raw_readl(VA_GPIO_BASE + MXC_PUEN(port));
- if (gpio_mode & GPIO_PUEN)
- tmp |= (1 << pin);
- else
- tmp &= ~(1 << pin);
- __raw_writel(tmp, VA_GPIO_BASE + MXC_PUEN(port));
-
- /* Data direction */
- tmp = __raw_readl(VA_GPIO_BASE + MXC_DDIR(port));
- if (gpio_mode & GPIO_OUT)
- tmp |= 1 << pin;
- else
- tmp &= ~(1 << pin);
- __raw_writel(tmp, VA_GPIO_BASE + MXC_DDIR(port));
-
- /* Primary / alternate function */
- tmp = __raw_readl(VA_GPIO_BASE + MXC_GPR(port));
- if (gpio_mode & GPIO_AF)
- tmp |= (1 << pin);
- else
- tmp &= ~(1 << pin);
- __raw_writel(tmp, VA_GPIO_BASE + MXC_GPR(port));
-
- /* use as gpio? */
- tmp = __raw_readl(VA_GPIO_BASE + MXC_GIUS(port));
- if (gpio_mode & (GPIO_PF | GPIO_AF))
- tmp &= ~(1 << pin);
- else
- tmp |= (1 << pin);
- __raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port));
-
- if (pin < 16) {
- tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port));
- tmp &= ~(3 << (pin * 2));
- tmp |= (ocr << (pin * 2));
- __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port));
-
- tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port));
- tmp &= ~(3 << (pin * 2));
- tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2);
- __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA1(port));
-
- tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB1(port));
- tmp &= ~(3 << (pin * 2));
- tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2);
- __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port));
- } else {
- pin -= 16;
-
- tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port));
- tmp &= ~(3 << (pin * 2));
- tmp |= (ocr << (pin * 2));
- __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port));
-
- tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port));
- tmp &= ~(3 << (pin * 2));
- tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2);
- __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA2(port));
-
- tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB2(port));
- tmp &= ~(3 << (pin * 2));
- tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2);
- __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB2(port));
- }
-}
-EXPORT_SYMBOL(mxc_gpio_mode);
-
-int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
- const char *label)
-{
- const int *p = pin_list;
- int i;
- unsigned gpio;
- unsigned mode;
- int ret = -EINVAL;
-
- for (i = 0; i < count; i++) {
- gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
- mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK);
-
- if (gpio >= (GPIO_PORT_MAX + 1) * 32)
- goto setup_error;
-
- ret = gpio_request(gpio, label);
- if (ret)
- goto setup_error;
-
- mxc_gpio_mode(gpio | mode);
-
- p++;
- }
- return 0;
-
-setup_error:
- mxc_gpio_release_multiple_pins(pin_list, i);
- return ret;
-}
-EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins);
-
-void mxc_gpio_release_multiple_pins(const int *pin_list, int count)
-{
- const int *p = pin_list;
- int i;
-
- for (i = 0; i < count; i++) {
- unsigned gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
- gpio_free(gpio);
- p++;
- }
-
-}
-EXPORT_SYMBOL(mxc_gpio_release_multiple_pins);
-
diff --git a/arch/arm/plat-mxc/iomux-v1.c b/arch/arm/plat-mxc/iomux-v1.c
new file mode 100644
index 00000000000..960a02cbcba
--- /dev/null
+++ b/arch/arm/plat-mxc/iomux-v1.c
@@ -0,0 +1,238 @@
+/*
+ * arch/arm/plat-mxc/iomux-v1.c
+ *
+ * Copyright (C) 2004 Sascha Hauer, Synertronixx GmbH
+ * Copyright (C) 2009 Uwe Kleine-Koenig, Pengutronix
+ *
+ * Common code for i.MX1, i.MX21 and i.MX27
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+#include <mach/iomux-v1.h>
+
+static void __iomem *imx_iomuxv1_baseaddr;
+static unsigned imx_iomuxv1_numports;
+
+static inline unsigned long imx_iomuxv1_readl(unsigned offset)
+{
+ return __raw_readl(imx_iomuxv1_baseaddr + offset);
+}
+
+static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset)
+{
+ __raw_writel(val, imx_iomuxv1_baseaddr + offset);
+}
+
+static inline void imx_iomuxv1_rmwl(unsigned offset,
+ unsigned long mask, unsigned long value)
+{
+ unsigned long reg = imx_iomuxv1_readl(offset);
+
+ reg &= ~mask;
+ reg |= value;
+
+ imx_iomuxv1_writel(reg, offset);
+}
+
+static inline void imx_iomuxv1_set_puen(
+ unsigned int port, unsigned int pin, int on)
+{
+ unsigned long mask = 1 << pin;
+
+ imx_iomuxv1_rmwl(MXC_PUEN(port), mask, on ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_ddir(
+ unsigned int port, unsigned int pin, int out)
+{
+ unsigned long mask = 1 << pin;
+
+ imx_iomuxv1_rmwl(MXC_DDIR(port), mask, out ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_gpr(
+ unsigned int port, unsigned int pin, int af)
+{
+ unsigned long mask = 1 << pin;
+
+ imx_iomuxv1_rmwl(MXC_GPR(port), mask, af ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_gius(
+ unsigned int port, unsigned int pin, int inuse)
+{
+ unsigned long mask = 1 << pin;
+
+ imx_iomuxv1_rmwl(MXC_GIUS(port), mask, inuse ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_ocr(
+ unsigned int port, unsigned int pin, unsigned int ocr)
+{
+ unsigned long shift = (pin & 0xf) << 1;
+ unsigned long mask = 3 << shift;
+ unsigned long value = ocr << shift;
+ unsigned long offset = pin < 16 ? MXC_OCR1(port) : MXC_OCR2(port);
+
+ imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+static inline void imx_iomuxv1_set_iconfa(
+ unsigned int port, unsigned int pin, unsigned int aout)
+{
+ unsigned long shift = (pin & 0xf) << 1;
+ unsigned long mask = 3 << shift;
+ unsigned long value = aout << shift;
+ unsigned long offset = pin < 16 ? MXC_ICONFA1(port) : MXC_ICONFA2(port);
+
+ imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+static inline void imx_iomuxv1_set_iconfb(
+ unsigned int port, unsigned int pin, unsigned int bout)
+{
+ unsigned long shift = (pin & 0xf) << 1;
+ unsigned long mask = 3 << shift;
+ unsigned long value = bout << shift;
+ unsigned long offset = pin < 16 ? MXC_ICONFB1(port) : MXC_ICONFB2(port);
+
+ imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+int mxc_gpio_mode(int gpio_mode)
+{
+ unsigned int pin = gpio_mode & GPIO_PIN_MASK;
+ unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
+ unsigned int aout = (gpio_mode >> GPIO_AOUT_SHIFT) & 3;
+ unsigned int bout = (gpio_mode >> GPIO_BOUT_SHIFT) & 3;
+
+ if (port >= imx_iomuxv1_numports)
+ return -EINVAL;
+
+ /* Pullup enable */
+ imx_iomuxv1_set_puen(port, pin, gpio_mode & GPIO_PUEN);
+
+ /* Data direction */
+ imx_iomuxv1_set_ddir(port, pin, gpio_mode & GPIO_OUT);
+
+ /* Primary / alternate function */
+ imx_iomuxv1_set_gpr(port, pin, gpio_mode & GPIO_AF);
+
+ /* use as gpio? */
+ imx_iomuxv1_set_gius(port, pin, !(gpio_mode & (GPIO_PF | GPIO_AF)));
+
+ imx_iomuxv1_set_ocr(port, pin, ocr);
+
+ imx_iomuxv1_set_iconfa(port, pin, aout);
+
+ imx_iomuxv1_set_iconfb(port, pin, bout);
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_gpio_mode);
+
+static int imx_iomuxv1_setup_multiple(const int *list, unsigned count)
+{
+ size_t i;
+ int ret;
+
+ for (i = 0; i < count; ++i) {
+ ret = mxc_gpio_mode(list[i]);
+
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+ const char *label)
+{
+ size_t i;
+ int ret;
+
+ for (i = 0; i < count; ++i) {
+ unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK);
+
+ ret = gpio_request(gpio, label);
+ if (ret)
+ goto err_gpio_request;
+ }
+
+ ret = imx_iomuxv1_setup_multiple(pin_list, count);
+ if (ret)
+ goto err_setup;
+
+ return 0;
+
+err_setup:
+ BUG_ON(i != count);
+
+err_gpio_request:
+ mxc_gpio_release_multiple_pins(pin_list, i);
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins);
+
+void mxc_gpio_release_multiple_pins(const int *pin_list, int count)
+{
+ size_t i;
+
+ for (i = 0; i < count; ++i) {
+ unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK);
+
+ gpio_free(gpio);
+ }
+}
+EXPORT_SYMBOL(mxc_gpio_release_multiple_pins);
+
+static int imx_iomuxv1_init(void)
+{
+#ifdef CONFIG_ARCH_MX1
+ if (cpu_is_mx1()) {
+ imx_iomuxv1_baseaddr = MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR);
+ imx_iomuxv1_numports = MX1_NUM_GPIO_PORT;
+ } else
+#endif
+#ifdef CONFIG_MACH_MX21
+ if (cpu_is_mx21()) {
+ imx_iomuxv1_baseaddr = MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR);
+ imx_iomuxv1_numports = MX21_NUM_GPIO_PORT;
+ } else
+#endif
+#ifdef CONFIG_MACH_MX27
+ if (cpu_is_mx27()) {
+ imx_iomuxv1_baseaddr = MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR);
+ imx_iomuxv1_numports = MX27_NUM_GPIO_PORT;
+ } else
+#endif
+ return -ENODEV;
+
+ return 0;
+}
+pure_initcall(imx_iomuxv1_init);
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
index 4ff6dfe0428..c36f2630ed9 100644
--- a/arch/arm/plat-mxc/pwm.c
+++ b/arch/arm/plat-mxc/pwm.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 844567ee35f..c1ce51abdba 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -30,9 +30,15 @@
#include <asm/mach/time.h>
#include <mach/common.h>
+/*
+ * There are 2 versions of the timer hardware on Freescale MXC hardware.
+ * Version 1: MX1/MXL, MX21, MX27.
+ * Version 2: MX25, MX31, MX35, MX37, MX51
+ */
+
/* defines common for all i.MX */
#define MXC_TCTL 0x00
-#define MXC_TCTL_TEN (1 << 0)
+#define MXC_TCTL_TEN (1 << 0) /* Enable module */
#define MXC_TPRER 0x04
/* MX1, MX21, MX27 */
@@ -47,8 +53,8 @@
#define MX2_TSTAT_CAPT (1 << 1)
#define MX2_TSTAT_COMP (1 << 0)
-/* MX31, MX35, MX25, MXC91231 */
-#define MX3_TCTL_WAITEN (1 << 3)
+/* MX31, MX35, MX25, MXC91231, MX5 */
+#define MX3_TCTL_WAITEN (1 << 3) /* Wait enable mode */
#define MX3_TCTL_CLK_IPG (1 << 6)
#define MX3_TCTL_FRR (1 << 9)
#define MX3_IR 0x0c
@@ -57,6 +63,9 @@
#define MX3_TCN 0x24
#define MX3_TCMP 0x10
+#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
+#define timer_is_v2() (!timer_is_v1())
+
static struct clock_event_device clockevent_mxc;
static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
@@ -66,7 +75,7 @@ static inline void gpt_irq_disable(void)
{
unsigned int tmp;
- if (cpu_is_mx3() || cpu_is_mx25())
+ if (timer_is_v2())
__raw_writel(0, timer_base + MX3_IR);
else {
tmp = __raw_readl(timer_base + MXC_TCTL);
@@ -76,7 +85,7 @@ static inline void gpt_irq_disable(void)
static inline void gpt_irq_enable(void)
{
- if (cpu_is_mx3() || cpu_is_mx25())
+ if (timer_is_v2())
__raw_writel(1<<0, timer_base + MX3_IR);
else {
__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
@@ -86,11 +95,13 @@ static inline void gpt_irq_enable(void)
static void gpt_irq_acknowledge(void)
{
- if (cpu_is_mx1())
- __raw_writel(0, timer_base + MX1_2_TSTAT);
- if (cpu_is_mx2())
- __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT);
- if (cpu_is_mx3() || cpu_is_mx25())
+ if (timer_is_v1()) {
+ if (cpu_is_mx1())
+ __raw_writel(0, timer_base + MX1_2_TSTAT);
+ else
+ __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
+ timer_base + MX1_2_TSTAT);
+ } else if (timer_is_v2())
__raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT);
}
@@ -117,7 +128,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
{
unsigned int c = clk_get_rate(timer_clk);
- if (cpu_is_mx3() || cpu_is_mx25())
+ if (timer_is_v2())
clocksource_mxc.read = mx3_get_cycles;
clocksource_mxc.mult = clocksource_hz2mult(c,
@@ -180,7 +191,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
if (mode != clockevent_mode) {
/* Set event time into far-far future */
- if (cpu_is_mx3() || cpu_is_mx25())
+ if (timer_is_v2())
__raw_writel(__raw_readl(timer_base + MX3_TCN) - 3,
timer_base + MX3_TCMP);
else
@@ -233,7 +244,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
struct clock_event_device *evt = &clockevent_mxc;
uint32_t tstat;
- if (cpu_is_mx3() || cpu_is_mx25())
+ if (timer_is_v2())
tstat = __raw_readl(timer_base + MX3_TSTAT);
else
tstat = __raw_readl(timer_base + MX1_2_TSTAT);
@@ -264,7 +275,7 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
{
unsigned int c = clk_get_rate(timer_clk);
- if (cpu_is_mx3() || cpu_is_mx25())
+ if (timer_is_v2())
clockevent_mxc.set_next_event = mx3_set_next_event;
clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
@@ -296,7 +307,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
__raw_writel(0, timer_base + MXC_TCTL);
__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
- if (cpu_is_mx3() || cpu_is_mx25())
+ if (timer_is_v2())
tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN;
else
tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
new file mode 100644
index 00000000000..afa6709db0b
--- /dev/null
+++ b/arch/arm/plat-mxc/tzic.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2004-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
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+
+/*
+ *****************************************
+ * TZIC Registers *
+ *****************************************
+ */
+
+#define TZIC_INTCNTL 0x0000 /* Control register */
+#define TZIC_INTTYPE 0x0004 /* Controller Type register */
+#define TZIC_IMPID 0x0008 /* Distributor Implementer Identification */
+#define TZIC_PRIOMASK 0x000C /* Priority Mask Reg */
+#define TZIC_SYNCCTRL 0x0010 /* Synchronizer Control register */
+#define TZIC_DSMINT 0x0014 /* DSM interrupt Holdoffregister */
+#define TZIC_INTSEC0(i) (0x0080 + ((i) << 2)) /* Interrupt Security Reg 0 */
+#define TZIC_ENSET0(i) (0x0100 + ((i) << 2)) /* Enable Set Reg 0 */
+#define TZIC_ENCLEAR0(i) (0x0180 + ((i) << 2)) /* Enable Clear Reg 0 */
+#define TZIC_SRCSET0 0x0200 /* Source Set Register 0 */
+#define TZIC_SRCCLAR0 0x0280 /* Source Clear Register 0 */
+#define TZIC_PRIORITY0 0x0400 /* Priority Register 0 */
+#define TZIC_PND0 0x0D00 /* Pending Register 0 */
+#define TZIC_HIPND0 0x0D80 /* High Priority Pending Register */
+#define TZIC_WAKEUP0(i) (0x0E00 + ((i) << 2)) /* Wakeup Config Register */
+#define TZIC_SWINT 0x0F00 /* Software Interrupt Rigger Register */
+#define TZIC_ID0 0x0FD0 /* Indentification Register 0 */
+
+void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */
+
+/**
+ * tzic_mask_irq() - Disable interrupt number "irq" in the TZIC
+ *
+ * @param irq interrupt source number
+ */
+static void tzic_mask_irq(unsigned int irq)
+{
+ int index, off;
+
+ index = irq >> 5;
+ off = irq & 0x1F;
+ __raw_writel(1 << off, tzic_base + TZIC_ENCLEAR0(index));
+}
+
+/**
+ * tzic_unmask_irq() - Enable interrupt number "irq" in the TZIC
+ *
+ * @param irq interrupt source number
+ */
+static void tzic_unmask_irq(unsigned int irq)
+{
+ int index, off;
+
+ index = irq >> 5;
+ off = irq & 0x1F;
+ __raw_writel(1 << off, tzic_base + TZIC_ENSET0(index));
+}
+
+static unsigned int wakeup_intr[4];
+
+/**
+ * tzic_set_wake_irq() - Set interrupt number "irq" in the TZIC as a wake-up source.
+ *
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * disble as wake-up if equal to zero
+ *
+ * @return This function returns 0 on success.
+ */
+static int tzic_set_wake_irq(unsigned int irq, unsigned int enable)
+{
+ unsigned int index, off;
+
+ index = irq >> 5;
+ off = irq & 0x1F;
+
+ if (index > 3)
+ return -EINVAL;
+
+ if (enable)
+ wakeup_intr[index] |= (1 << off);
+ else
+ wakeup_intr[index] &= ~(1 << off);
+
+ return 0;
+}
+
+static struct irq_chip mxc_tzic_chip = {
+ .name = "MXC_TZIC",
+ .ack = tzic_mask_irq,
+ .mask = tzic_mask_irq,
+ .unmask = tzic_unmask_irq,
+ .set_wake = tzic_set_wake_irq,
+};
+
+/*
+ * This function initializes the TZIC hardware and disables all the
+ * interrupts. It registers the interrupt enable and disable functions
+ * to the kernel for each interrupt source.
+ */
+void __init tzic_init_irq(void __iomem *irqbase)
+{
+ int i;
+
+ tzic_base = irqbase;
+ /* put the TZIC into the reset value with
+ * all interrupts disabled
+ */
+ i = __raw_readl(tzic_base + TZIC_INTCNTL);
+
+ __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL);
+ __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK);
+ __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL);
+
+ for (i = 0; i < 4; i++)
+ __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i));
+
+ /* disable all interrupts */
+ for (i = 0; i < 4; i++)
+ __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i));
+
+ /* all IRQ no FIQ Warning :: No selection */
+
+ for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+ set_irq_chip(i, &mxc_tzic_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
+}
+
+/**
+ * tzic_enable_wake() - enable wakeup interrupt
+ *
+ * @param is_idle 1 if called in idle loop (ENSET0 register);
+ * 0 to be used when called from low power entry
+ * @return 0 if successful; non-zero otherwise
+ */
+int tzic_enable_wake(int is_idle)
+{
+ unsigned int i, v;
+
+ __raw_writel(1, tzic_base + TZIC_DSMINT);
+ if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
+ return -EAGAIN;
+
+ for (i = 0; i < 4; i++) {
+ v = is_idle ? __raw_readl(TZIC_ENSET0(i)) : wakeup_intr[i];
+ __raw_writel(v, TZIC_WAKEUP0(i));
+ }
+
+ return 0;
+}
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index 62f18ad43a2..fa7cb3a57cb 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -49,24 +49,17 @@ static struct clocksource nmdk_clksrc = {
static void nmdk_clkevt_mode(enum clock_event_mode mode,
struct clock_event_device *dev)
{
- unsigned long flags;
-
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
- /* enable interrupts -- and count current value? */
- raw_local_irq_save(flags);
+ /* count current value? */
writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
- raw_local_irq_restore(flags);
break;
case CLOCK_EVT_MODE_ONESHOT:
BUG(); /* Not supported, yet */
/* FALLTHROUGH */
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_UNUSED:
- /* disable irq */
- raw_local_irq_save(flags);
writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
- raw_local_irq_restore(flags);
break;
case CLOCK_EVT_MODE_RESUME:
break;
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 088c1a03b94..f12f0e39ddf 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -44,9 +44,6 @@
#define NO_LENGTH_CHECK 0xffffffff
-unsigned char omap_bootloader_tag[512];
-int omap_bootloader_tag_len;
-
struct omap_board_config_kernel *omap_board_config;
int omap_board_config_size;
@@ -100,10 +97,17 @@ EXPORT_SYMBOL(omap_get_var_config);
#include <linux/clocksource.h>
+/*
+ * offset_32k holds the init time counter value. It is then subtracted
+ * from every counter read to achieve a counter that counts time from the
+ * kernel boot (needed for sched_clock()).
+ */
+static u32 offset_32k __read_mostly;
+
#ifdef CONFIG_ARCH_OMAP16XX
static cycle_t omap16xx_32k_read(struct clocksource *cs)
{
- return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED);
+ return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
}
#else
#define omap16xx_32k_read NULL
@@ -112,7 +116,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
#ifdef CONFIG_ARCH_OMAP2420
static cycle_t omap2420_32k_read(struct clocksource *cs)
{
- return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10);
+ return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
}
#else
#define omap2420_32k_read NULL
@@ -121,7 +125,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
#ifdef CONFIG_ARCH_OMAP2430
static cycle_t omap2430_32k_read(struct clocksource *cs)
{
- return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10);
+ return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
}
#else
#define omap2430_32k_read NULL
@@ -130,7 +134,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
#ifdef CONFIG_ARCH_OMAP3
static cycle_t omap34xx_32k_read(struct clocksource *cs)
{
- return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
+ return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
}
#else
#define omap34xx_32k_read NULL
@@ -139,7 +143,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
#ifdef CONFIG_ARCH_OMAP4
static cycle_t omap44xx_32k_read(struct clocksource *cs)
{
- return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
+ return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
}
#else
#define omap44xx_32k_read NULL
@@ -227,6 +231,8 @@ static int __init omap_init_clocksource_32k(void)
clocksource_32k.mult = clocksource_hz2mult(32768,
clocksource_32k.shift);
+ offset_32k = clocksource_32k.read(&clocksource_32k);
+
if (clocksource_register(&clocksource_32k))
printk(err, clocksource_32k.name);
}
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 4a4cd8774aa..95677d17cd1 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 2ab224c8e16..1d959965ff5 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -29,6 +29,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <mach/hardware.h>
@@ -936,6 +937,15 @@ void omap_start_dma(int lch)
{
u32 l;
+ /*
+ * The CPC/CDAC register needs to be initialized to zero
+ * before starting dma transfer.
+ */
+ if (cpu_is_omap15xx())
+ dma_write(0, CPC(lch));
+ else
+ dma_write(0, CDAC(lch));
+
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch;
char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 337199ed347..45a225d0912 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -798,7 +798,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_INT_EDGE;
l = __raw_readl(reg);
- if (trigger & IRQ_TYPE_EDGE_BOTH)
+ if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
bank->toggle_mask |= 1 << gpio;
if (trigger & IRQ_TYPE_EDGE_RISING)
l |= 1 << gpio;
@@ -812,7 +812,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_CONTROL;
l = __raw_readl(reg);
- if (trigger & IRQ_TYPE_EDGE_BOTH)
+ if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
bank->toggle_mask |= 1 << gpio;
if (trigger & IRQ_TYPE_EDGE_RISING)
l |= 1 << gpio;
@@ -846,7 +846,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
case METHOD_GPIO_7XX:
reg += OMAP7XX_GPIO_INT_CONTROL;
l = __raw_readl(reg);
- if (trigger & IRQ_TYPE_EDGE_BOTH)
+ if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
bank->toggle_mask |= 1 << gpio;
if (trigger & IRQ_TYPE_EDGE_RISING)
l |= 1 << gpio;
@@ -2140,18 +2140,18 @@ void omap2_gpio_resume_after_retention(void)
if (gen) {
u32 old0, old1;
- if (cpu_is_omap24xx() || cpu_is_omap44xx()) {
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
old0 = __raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT0);
old1 = __raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT1);
- __raw_writel(old0 | gen, bank->base +
+ __raw_writel(old0 | gen, bank->base +
OMAP24XX_GPIO_LEVELDETECT0);
- __raw_writel(old1 | gen, bank->base +
+ __raw_writel(old1 | gen, bank->base +
OMAP24XX_GPIO_LEVELDETECT1);
- __raw_writel(old0, bank->base +
+ __raw_writel(old0, bank->base +
OMAP24XX_GPIO_LEVELDETECT0);
- __raw_writel(old1, bank->base +
+ __raw_writel(old1, bank->base +
OMAP24XX_GPIO_LEVELDETECT1);
}
diff --git a/arch/arm/plat-omap/include/plat/blizzard.h b/arch/arm/plat-omap/include/plat/blizzard.h
index 8d160f17137..56e7f2e7d12 100644
--- a/arch/arm/plat-omap/include/plat/blizzard.h
+++ b/arch/arm/plat-omap/include/plat/blizzard.h
@@ -6,7 +6,7 @@ struct blizzard_platform_data {
void (*power_down)(struct device *dev);
unsigned long (*get_clock_rate)(struct device *dev);
- unsigned te_connected : 1;
+ unsigned te_connected:1;
};
#endif
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index ed8786c41df..75141742300 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -167,10 +167,14 @@ IS_OMAP_SUBCLASS(443x, 0x443)
#if defined(MULTI_OMAP2)
# if defined(CONFIG_ARCH_OMAP2)
# undef cpu_is_omap24xx
-# undef cpu_is_omap242x
-# undef cpu_is_omap243x
# define cpu_is_omap24xx() is_omap24xx()
+# endif
+# if defined (CONFIG_ARCH_OMAP2420)
+# undef cpu_is_omap242x
# define cpu_is_omap242x() is_omap242x()
+# endif
+# if defined (CONFIG_ARCH_OMAP2430)
+# undef cpu_is_omap243x
# define cpu_is_omap243x() is_omap243x()
# endif
# if defined(CONFIG_ARCH_OMAP3)
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index b65088a869e..401701977db 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -345,8 +345,6 @@
#define INT_34XX_MMC3_IRQ 94
#define INT_34XX_GPT12_IRQ 95
-#define INT_34XX_BENCH_MPU_EMUL 3
-
#define INT_35XX_HECC0_IRQ 24
#define INT_35XX_HECC1_IRQ 28
#define INT_35XX_EMAC_C0_RXTHRESH_IRQ 67
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index 39748354ce4..7de903d7c1c 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -59,7 +59,7 @@
#define OMAP44XX_MCBSP1_BASE 0x49022000
#define OMAP44XX_MCBSP2_BASE 0x49024000
#define OMAP44XX_MCBSP3_BASE 0x49026000
-#define OMAP44XX_MCBSP4_BASE 0x48074000
+#define OMAP44XX_MCBSP4_BASE 0x48096000
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h
index 6ba88d2630d..f8efd5466b1 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -29,4 +29,11 @@ struct omap_nand_platform_data {
/* size (4 KiB) for IO mapping */
#define NAND_IO_SIZE SZ_4K
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
extern int gpmc_nand_init(struct omap_nand_platform_data *d);
+#else
+static inline int gpmc_nand_init(struct omap_nand_platform_data *d)
+{
+ return 0;
+}
+#endif
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index 2302474a374..b3ef1a7f53c 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -32,7 +32,7 @@
#define OMAP4430_PRM_BASE 0x4a306000
#define OMAP44XX_GPMC_BASE 0x50000000
#define OMAP443X_SCM_BASE 0x4a002000
-#define OMAP443X_CTRL_BASE OMAP443X_SCM_BASE
+#define OMAP443X_CTRL_BASE 0x4a100000
#define OMAP44XX_IC_BASE 0x48200000
#define OMAP44XX_IVA_INTC_BASE 0x40000000
#define IRQ_SIR_IRQ 0x0040
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 440b4164f2f..36d6ea56ab5 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -294,8 +294,8 @@ struct omap_hwmod_class_sysconfig {
u16 rev_offs;
u16 sysc_offs;
u16 syss_offs;
+ u16 sysc_flags;
u8 idlemodes;
- u8 sysc_flags;
u8 clockact;
struct omap_hwmod_sysc_fields *sysc_fields;
};
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
index d6a0e27d5a7..9fbd91419cd 100644
--- a/arch/arm/plat-omap/include/plat/prcm.h
+++ b/arch/arm/plat-omap/include/plat/prcm.h
@@ -24,7 +24,7 @@
#define __ASM_ARM_ARCH_OMAP_PRCM_H
u32 omap_prcm_get_reset_sources(void);
-void omap_prcm_arch_reset(char mode);
+void omap_prcm_arch_reset(char mode, const char *cmd);
int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
const char *name);
diff --git a/arch/arm/plat-omap/include/plat/system.h b/arch/arm/plat-omap/include/plat/system.h
index c58a4ef42a4..d0a119f735b 100644
--- a/arch/arm/plat-omap/include/plat/system.h
+++ b/arch/arm/plat-omap/include/plat/system.h
@@ -22,7 +22,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void omap1_arch_reset(char mode)
+static inline void omap1_arch_reset(char mode, const char *cmd)
{
/*
* Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
@@ -43,9 +43,9 @@ static inline void omap1_arch_reset(char mode)
static inline void arch_reset(char mode, const char *cmd)
{
if (!cpu_class_is_omap2())
- omap1_arch_reset(mode);
+ omap1_arch_reset(mode, cmd);
else
- omap_prcm_arch_reset(mode);
+ omap_prcm_arch_reset(mode, cmd);
}
#endif
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 288e29e1c06..876ca8d5e92 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -46,14 +46,14 @@ struct ehci_hcd_omap_platform_data {
struct omap_musb_board_data {
u8 interface_type;
u8 mode;
- u8 power;
+ u16 power;
};
enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
extern void usb_musb_init(struct omap_musb_board_data *board_data);
-extern void usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata);
+extern void usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata);
#endif
diff --git a/arch/arm/plat-omap/iommu-debug.c b/arch/arm/plat-omap/iommu-debug.c
index afd1c27cff7..e6c0d536899 100644
--- a/arch/arm/plat-omap/iommu-debug.c
+++ b/arch/arm/plat-omap/iommu-debug.c
@@ -13,6 +13,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/debugfs.h>
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index 905ed832df5..0e137663349 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -13,6 +13,7 @@
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/clk.h>
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 936aef1971c..65c6d1ff723 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -11,6 +11,7 @@
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/device.h>
#include <linux/scatterlist.h>
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 4229cec5314..08a2df76628 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <plat/mailbox.h>
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index e47686e0a63..e1d0440fd4a 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -23,6 +23,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <plat/dma.h>
#include <plat/mcbsp.h>
@@ -133,8 +134,7 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
irqst_spcr2);
/* Writing zero to XSYNC_ERR clears the IRQ */
- MCBSP_WRITE(mcbsp_tx, SPCR2,
- MCBSP_READ_CACHE(mcbsp_tx, SPCR2) & ~(XSYNC_ERR));
+ MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
} else {
complete(&mcbsp_tx->tx_irq_completion);
}
@@ -154,8 +154,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
irqst_spcr1);
/* Writing zero to RSYNC_ERR clears the IRQ */
- MCBSP_WRITE(mcbsp_rx, SPCR1,
- MCBSP_READ_CACHE(mcbsp_rx, SPCR1) & ~(RSYNC_ERR));
+ MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
} else {
complete(&mcbsp_rx->tx_irq_completion);
}
@@ -934,8 +933,7 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
/* if frame sync error - clear the error */
if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) {
/* clear error */
- MCBSP_WRITE(mcbsp, SPCR2,
- MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XSYNC_ERR));
+ MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
/* resend */
return -1;
} else {
@@ -975,8 +973,7 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
/* if frame sync error - clear the error */
if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) {
/* clear error */
- MCBSP_WRITE(mcbsp, SPCR1,
- MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RSYNC_ERR));
+ MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
/* resend */
return -1;
} else {
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 59043589484..0f519747951 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -79,6 +79,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/io.h>
diff --git a/arch/arm/plat-pxa/dma.c b/arch/arm/plat-pxa/dma.c
index 2975798d411..742350e0f2a 100644
--- a/arch/arm/plat-pxa/dma.c
+++ b/arch/arm/plat-pxa/dma.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c
index 51dc5c8106c..0732c6c8d51 100644
--- a/arch/arm/plat-pxa/pwm.c
+++ b/arch/arm/plat-pxa/pwm.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
deleted file mode 100644
index 9e9d0286e48..00000000000
--- a/arch/arm/plat-s3c/Kconfig
+++ /dev/null
@@ -1,215 +0,0 @@
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-config PLAT_S3C
- bool
- depends on ARCH_S3C2410 || ARCH_S3C24A0 || ARCH_S3C64XX
- default y
- select NO_IOPORT
- help
- Base platform code for any Samsung S3C device
-
-# low-level serial option nodes
-
-if PLAT_S3C
-
-config CPU_LLSERIAL_S3C2410_ONLY
- bool
- default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440
-
-config CPU_LLSERIAL_S3C2440_ONLY
- bool
- default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410
-
-config CPU_LLSERIAL_S3C2410
- bool
- help
- Selected if there is an S3C2410 (or register compatible) serial
- low-level implementation needed
-
-config CPU_LLSERIAL_S3C2440
- bool
- help
- Selected if there is an S3C2440 (or register compatible) serial
- low-level implementation needed
-
-# boot configurations
-
-comment "Boot options"
-
-config S3C_BOOT_WATCHDOG
- bool "S3C Initialisation watchdog"
- depends on S3C2410_WATCHDOG
- help
- Say y to enable the watchdog during the kernel decompression
- stage. If the kernel fails to uncompress, then the watchdog
- will trigger a reset and the system should restart.
-
-config S3C_BOOT_ERROR_RESET
- bool "S3C Reboot on decompression error"
- help
- Say y here to use the watchdog to reset the system if the
- kernel decompressor detects an error during decompression.
-
-config S3C_BOOT_UART_FORCE_FIFO
- bool "Force UART FIFO on during boot process"
- default y
- help
- Say Y here to force the UART FIFOs on during the kernel
- uncompressor
-
-comment "Power management"
-
-config S3C2410_PM_DEBUG
- bool "S3C2410 PM Suspend debug"
- depends on PM
- help
- Say Y here if you want verbose debugging from the PM Suspend and
- Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
- for more information.
-
-config S3C_PM_DEBUG_LED_SMDK
- bool "SMDK LED suspend/resume debugging"
- depends on PM && (MACH_SMDK6410)
- help
- Say Y here to enable the use of the SMDK LEDs on the baseboard
- for debugging of the state of the suspend and resume process.
-
- Note, this currently only works for S3C64XX based SMDK boards.
-
-config S3C2410_PM_CHECK
- bool "S3C2410 PM Suspend Memory CRC"
- depends on PM && CRC32
- help
- Enable the PM code's memory area checksum over sleep. This option
- will generate CRCs of all blocks of memory, and store them before
- going to sleep. The blocks are then checked on resume for any
- errors.
-
- Note, this can take several seconds depending on memory size
- and CPU speed.
-
- See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-
-config S3C2410_PM_CHECK_CHUNKSIZE
- int "S3C2410 PM Suspend CRC Chunksize (KiB)"
- depends on PM && S3C2410_PM_CHECK
- default 64
- help
- Set the chunksize in Kilobytes of the CRC for checking memory
- corruption over suspend and resume. A smaller value will mean that
- the CRC data block will take more memory, but wil identify any
- faults with better precision.
-
- See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-
-config S3C_LOWLEVEL_UART_PORT
- int "S3C UART to use for low-level messages"
- default 0
- help
- Choice of which UART port to use for the low-level messages,
- such as the `Uncompressing...` at start time. The value of
- this configuration should be between zero and two. The port
- must have been initialised by the boot-loader before use.
-
-# options for gpiolib support
-
-config S3C_GPIO_SPACE
- int "Space between gpio banks"
- default 0
- help
- Add a number of spare GPIO entries between each bank for debugging
- purposes. This allows any problems where an counter overflows from
- one bank to another to be caught, at the expense of using a little
- more memory.
-
-config S3C_GPIO_TRACK
- bool
- help
- Internal configuration option to enable the s3c specific gpio
- chip tracking if the platform requires it.
-
-config S3C_GPIO_PULL_UPDOWN
- bool
- help
- Internal configuration to enable the correct GPIO pull helper
-
-config S3C_GPIO_PULL_DOWN
- bool
- help
- Internal configuration to enable the correct GPIO pull helper
-
-config S3C_GPIO_PULL_UP
- bool
- help
- Internal configuration to enable the correct GPIO pull helper
-
-config S3C_GPIO_CFG_S3C24XX
- bool
- help
- Internal configuration to enable S3C24XX style GPIO configuration
- functions.
-
-config S3C_GPIO_CFG_S3C64XX
- bool
- help
- Internal configuration to enable S3C64XX style GPIO configuration
- functions.
-
-config S5P_GPIO_CFG_S5PC1XX
- bool
- help
- Internal configuration to enable S5PC1XX style GPIO configuration
- functions.
-
-# DMA
-
-config S3C_DMA
- bool
- help
- Internal configuration for S3C DMA core
-
-# device definitions to compile in
-
-config S3C_DEV_HSMMC
- bool
- help
- Compile in platform device definitions for HSMMC code
-
-config S3C_DEV_HSMMC1
- bool
- help
- Compile in platform device definitions for HSMMC channel 1
-
-config S3C_DEV_HSMMC2
- bool
- help
- Compile in platform device definitions for HSMMC channel 2
-
-config S3C_DEV_I2C1
- bool
- help
- Compile in platform device definitions for I2C channel 1
-
-config S3C_DEV_FB
- bool
- help
- Compile in platform device definition for framebuffer
-
-config S3C_DEV_USB_HOST
- bool
- help
- Compile in platform device definition for USB host.
-
-config S3C_DEV_USB_HSOTG
- bool
- help
- Compile in platform device definition for USB high-speed OtG
-
-config S3C_DEV_NAND
- bool
- help
- Compile in platform device definition for NAND controller
-
-endif
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
deleted file mode 100644
index 50444da9842..00000000000
--- a/arch/arm/plat-s3c/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-# arch/arm/plat-s3c/Makefile
-#
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-
-# Core support for all Samsung SoCs
-
-obj-y += init.o
-obj-y += time.o
-obj-y += clock.o
-obj-y += pwm-clock.o
-obj-y += gpio.o
-obj-y += gpio-config.o
-
-# DMA support
-
-obj-$(CONFIG_S3C_DMA) += dma.o
-
-# PM support
-
-obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += pm-gpio.o
-obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o
-
-# PWM support
-
-obj-$(CONFIG_HAVE_PWM) += pwm.o
-
-# devices
-
-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-y += dev-i2c0.o
-obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
-obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
-obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
-obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
-obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o
diff --git a/arch/arm/plat-s3c/clock.c b/arch/arm/plat-s3c/clock.c
deleted file mode 100644
index 619cfa82dca..00000000000
--- a/arch/arm/plat-s3c/clock.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/clock.c
- *
- * Copyright 2004-2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX Core clock control support
- *
- * Based on, and code from linux/arch/arm/mach-versatile/clock.c
- **
- ** Copyright (C) 2004 ARM Limited.
- ** Written by Deep Blue Solutions Limited.
- *
- *
- * This program is free software; 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/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-/* clock information */
-
-static LIST_HEAD(clocks);
-
-/* We originally used an mutex here, but some contexts (see resume)
- * are calling functions such as clk_set_parent() with IRQs disabled
- * causing an BUG to be triggered.
- */
-DEFINE_SPINLOCK(clocks_lock);
-
-/* enable and disable calls for use with the clk struct */
-
-static int clk_null_enable(struct clk *clk, int enable)
-{
- return 0;
-}
-
-/* Clock API calls */
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
- struct clk *p;
- struct clk *clk = ERR_PTR(-ENOENT);
- int idno;
-
- if (dev == NULL || dev->bus != &platform_bus_type)
- idno = -1;
- else
- idno = to_platform_device(dev)->id;
-
- spin_lock(&clocks_lock);
-
- list_for_each_entry(p, &clocks, list) {
- if (p->id == idno &&
- strcmp(id, p->name) == 0 &&
- try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
-
- /* check for the case where a device was supplied, but the
- * clock that was being searched for is not device specific */
-
- if (IS_ERR(clk)) {
- list_for_each_entry(p, &clocks, list) {
- if (p->id == -1 && strcmp(id, p->name) == 0 &&
- try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
- }
-
- spin_unlock(&clocks_lock);
- return clk;
-}
-
-void clk_put(struct clk *clk)
-{
- module_put(clk->owner);
-}
-
-int clk_enable(struct clk *clk)
-{
- if (IS_ERR(clk) || clk == NULL)
- return -EINVAL;
-
- clk_enable(clk->parent);
-
- spin_lock(&clocks_lock);
-
- if ((clk->usage++) == 0)
- (clk->enable)(clk, 1);
-
- spin_unlock(&clocks_lock);
- return 0;
-}
-
-void clk_disable(struct clk *clk)
-{
- if (IS_ERR(clk) || clk == NULL)
- return;
-
- spin_lock(&clocks_lock);
-
- if ((--clk->usage) == 0)
- (clk->enable)(clk, 0);
-
- spin_unlock(&clocks_lock);
- clk_disable(clk->parent);
-}
-
-
-unsigned long clk_get_rate(struct clk *clk)
-{
- if (IS_ERR(clk))
- return 0;
-
- if (clk->rate != 0)
- return clk->rate;
-
- if (clk->get_rate != NULL)
- return (clk->get_rate)(clk);
-
- if (clk->parent != NULL)
- return clk_get_rate(clk->parent);
-
- return clk->rate;
-}
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- if (!IS_ERR(clk) && clk->round_rate)
- return (clk->round_rate)(clk, rate);
-
- return rate;
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- int ret;
-
- if (IS_ERR(clk))
- return -EINVAL;
-
- /* We do not default just do a clk->rate = rate as
- * the clock may have been made this way by choice.
- */
-
- WARN_ON(clk->set_rate == NULL);
-
- if (clk->set_rate == NULL)
- return -EINVAL;
-
- spin_lock(&clocks_lock);
- ret = (clk->set_rate)(clk, rate);
- spin_unlock(&clocks_lock);
-
- return ret;
-}
-
-struct clk *clk_get_parent(struct clk *clk)
-{
- return clk->parent;
-}
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- int ret = 0;
-
- if (IS_ERR(clk))
- return -EINVAL;
-
- spin_lock(&clocks_lock);
-
- if (clk->set_parent)
- ret = (clk->set_parent)(clk, parent);
-
- spin_unlock(&clocks_lock);
-
- return ret;
-}
-
-EXPORT_SYMBOL(clk_get);
-EXPORT_SYMBOL(clk_put);
-EXPORT_SYMBOL(clk_enable);
-EXPORT_SYMBOL(clk_disable);
-EXPORT_SYMBOL(clk_get_rate);
-EXPORT_SYMBOL(clk_round_rate);
-EXPORT_SYMBOL(clk_set_rate);
-EXPORT_SYMBOL(clk_get_parent);
-EXPORT_SYMBOL(clk_set_parent);
-
-/* base clocks */
-
-static int clk_default_setrate(struct clk *clk, unsigned long rate)
-{
- clk->rate = rate;
- return 0;
-}
-
-struct clk clk_xtal = {
- .name = "xtal",
- .id = -1,
- .rate = 0,
- .parent = NULL,
- .ctrlbit = 0,
-};
-
-struct clk clk_ext = {
- .name = "ext",
- .id = -1,
-};
-
-struct clk clk_epll = {
- .name = "epll",
- .id = -1,
-};
-
-struct clk clk_mpll = {
- .name = "mpll",
- .id = -1,
- .set_rate = clk_default_setrate,
-};
-
-struct clk clk_upll = {
- .name = "upll",
- .id = -1,
- .parent = NULL,
- .ctrlbit = 0,
-};
-
-struct clk clk_f = {
- .name = "fclk",
- .id = -1,
- .rate = 0,
- .parent = &clk_mpll,
- .ctrlbit = 0,
- .set_rate = clk_default_setrate,
-};
-
-struct clk clk_h = {
- .name = "hclk",
- .id = -1,
- .rate = 0,
- .parent = NULL,
- .ctrlbit = 0,
- .set_rate = clk_default_setrate,
-};
-
-struct clk clk_p = {
- .name = "pclk",
- .id = -1,
- .rate = 0,
- .parent = NULL,
- .ctrlbit = 0,
- .set_rate = clk_default_setrate,
-};
-
-struct clk clk_usb_bus = {
- .name = "usb-bus",
- .id = -1,
- .rate = 0,
- .parent = &clk_upll,
-};
-
-
-
-struct clk s3c24xx_uclk = {
- .name = "uclk",
- .id = -1,
-};
-
-/* initialise the clock system */
-
-int s3c24xx_register_clock(struct clk *clk)
-{
- if (clk->enable == NULL)
- clk->enable = clk_null_enable;
-
- /* add to the list of available clocks */
-
- /* Quick check to see if this clock has already been registered. */
- BUG_ON(clk->list.prev != clk->list.next);
-
- spin_lock(&clocks_lock);
- list_add(&clk->list, &clocks);
- spin_unlock(&clocks_lock);
-
- return 0;
-}
-
-int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
-{
- int fails = 0;
-
- for (; nr_clks > 0; nr_clks--, clks++) {
- if (s3c24xx_register_clock(*clks) < 0)
- fails++;
- }
-
- return fails;
-}
-
-/* initalise all the clocks */
-
-int __init s3c24xx_register_baseclocks(unsigned long xtal)
-{
- printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");
-
- clk_xtal.rate = xtal;
-
- /* register our clocks */
-
- if (s3c24xx_register_clock(&clk_xtal) < 0)
- printk(KERN_ERR "failed to register master xtal\n");
-
- if (s3c24xx_register_clock(&clk_mpll) < 0)
- printk(KERN_ERR "failed to register mpll clock\n");
-
- if (s3c24xx_register_clock(&clk_upll) < 0)
- printk(KERN_ERR "failed to register upll clock\n");
-
- if (s3c24xx_register_clock(&clk_f) < 0)
- printk(KERN_ERR "failed to register cpu fclk\n");
-
- if (s3c24xx_register_clock(&clk_h) < 0)
- printk(KERN_ERR "failed to register cpu hclk\n");
-
- if (s3c24xx_register_clock(&clk_p) < 0)
- printk(KERN_ERR "failed to register cpu pclk\n");
-
- return 0;
-}
-
diff --git a/arch/arm/plat-s3c/dev-fb.c b/arch/arm/plat-s3c/dev-fb.c
deleted file mode 100644
index a90198fc4b0..00000000000
--- a/arch/arm/plat-s3c/dev-fb.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-fb.c
- *
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for framebuffer device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-#include <mach/regs-fb.h>
-
-#include <plat/fb.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_fb_resource[] = {
- [0] = {
- .start = S3C_PA_FB,
- .end = S3C_PA_FB + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_LCD_VSYNC,
- .end = IRQ_LCD_VSYNC,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = IRQ_LCD_FIFO,
- .end = IRQ_LCD_FIFO,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- .start = IRQ_LCD_SYSTEM,
- .end = IRQ_LCD_SYSTEM,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device s3c_device_fb = {
- .name = "s3c-fb",
- .id = -1,
- .num_resources = ARRAY_SIZE(s3c_fb_resource),
- .resource = s3c_fb_resource,
- .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask,
- .dev.coherent_dma_mask = 0xffffffffUL,
-};
-
-void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
-{
- struct s3c_fb_platdata *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_fb.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-s3c/dev-i2c0.c b/arch/arm/plat-s3c/dev-i2c0.c
deleted file mode 100644
index 4c761529b94..00000000000
--- a/arch/arm/plat-s3c/dev-i2c0.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c0.c
- *
- * Copyright 2008-2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 0
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
- [0] = {
- .start = S3C_PA_IIC,
- .end = S3C_PA_IIC + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_IIC,
- .end = IRQ_IIC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device s3c_device_i2c0 = {
- .name = "s3c2410-i2c",
-#ifdef CONFIG_S3C_DEV_I2C1
- .id = 0,
-#else
- .id = -1,
-#endif
- .num_resources = ARRAY_SIZE(s3c_i2c_resource),
- .resource = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
- .flags = 0,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
-void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
-{
- struct s3c2410_platform_i2c *npd;
-
- if (!pd)
- pd = &default_i2c_data0;
-
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c0_cfg_gpio;
-
- s3c_device_i2c0.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-s3c/dev-i2c1.c b/arch/arm/plat-s3c/dev-i2c1.c
deleted file mode 100644
index d44f7911050..00000000000
--- a/arch/arm/plat-s3c/dev-i2c1.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c1.c
- *
- * Copyright 2008-2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
- [0] = {
- .start = S3C_PA_IIC1,
- .end = S3C_PA_IIC1 + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_IIC1,
- .end = IRQ_IIC1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device s3c_device_i2c1 = {
- .name = "s3c2410-i2c",
- .id = 1,
- .num_resources = ARRAY_SIZE(s3c_i2c_resource),
- .resource = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
- .flags = 0,
- .bus_num = 1,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
-void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
-{
- struct s3c2410_platform_i2c *npd;
-
- if (!pd)
- pd = &default_i2c_data1;
-
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c1_cfg_gpio;
-
- s3c_device_i2c1.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-s3c/dev-nand.c b/arch/arm/plat-s3c/dev-nand.c
deleted file mode 100644
index a52fb6cf618..00000000000
--- a/arch/arm/plat-s3c/dev-nand.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * S3C series device definition for nand device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <mach/map.h>
-#include <plat/devs.h>
-#include <plat/nand.h>
-
-static struct resource s3c_nand_resource[] = {
- [0] = {
- .start = S3C_PA_NAND,
- .end = S3C_PA_NAND + SZ_1M,
- .flags = IORESOURCE_MEM,
- }
-};
-
-struct platform_device s3c_device_nand = {
- .name = "s3c2410-nand",
- .id = -1,
- .num_resources = ARRAY_SIZE(s3c_nand_resource),
- .resource = s3c_nand_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_nand);
-
-/**
- * s3c_nand_copy_set() - copy nand set data
- * @set: The new structure, directly copied from the old.
- *
- * Copy all the fields from the NAND set field from what is probably __initdata
- * to new kernel memory. The code returns 0 if the copy happened correctly or
- * an error code for the calling function to display.
- *
- * Note, we currently do not try and look to see if we've already copied the
- * data in a previous set.
- */
-static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
-{
- void *ptr;
- int size;
-
- size = sizeof(struct mtd_partition) * set->nr_partitions;
- if (size) {
- ptr = kmemdup(set->partitions, size, GFP_KERNEL);
- set->partitions = ptr;
-
- if (!ptr)
- return -ENOMEM;
- }
-
- if (set->nr_map && set->nr_chips) {
- size = sizeof(int) * set->nr_chips;
- ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
- set->nr_map = ptr;
-
- if (!ptr)
- return -ENOMEM;
- }
-
- if (set->ecc_layout) {
- ptr = kmemdup(set->ecc_layout,
- sizeof(struct nand_ecclayout), GFP_KERNEL);
- set->ecc_layout = ptr;
-
- if (!ptr)
- return -ENOMEM;
- }
-
- return 0;
-}
-
-void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
-{
- struct s3c2410_platform_nand *npd;
- int size;
- int ret;
-
- /* note, if we get a failure in allocation, we simply drop out of the
- * function. If there is so little memory available at initialisation
- * time then there is little chance the system is going to run.
- */
-
- npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL);
- if (!npd) {
- printk(KERN_ERR "%s: failed copying platform data\n", __func__);
- return;
- }
-
- /* now see if we need to copy any of the nand set data */
-
- size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
- if (size) {
- struct s3c2410_nand_set *from = npd->sets;
- struct s3c2410_nand_set *to;
- int i;
-
- to = kmemdup(from, size, GFP_KERNEL);
- npd->sets = to; /* set, even if we failed */
-
- if (!to) {
- printk(KERN_ERR "%s: no memory for sets\n", __func__);
- return;
- }
-
- for (i = 0; i < npd->nr_sets; i++) {
- ret = s3c_nand_copy_set(to);
- if (ret) {
- printk(KERN_ERR "%s: failed to copy set %d\n",
- __func__, i);
- return;
- }
- to++;
- }
- }
-
- s3c_device_nand.dev.platform_data = npd;
-}
-
-EXPORT_SYMBOL_GPL(s3c_nand_set_platdata);
diff --git a/arch/arm/plat-s3c/dev-usb-hsotg.c b/arch/arm/plat-s3c/dev-usb-hsotg.c
deleted file mode 100644
index e2f604b51c8..00000000000
--- a/arch/arm/plat-s3c/dev-usb-hsotg.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c
- *
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for USB high-speed UDC/OtG block
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-static struct resource s3c_usb_hsotg_resources[] = {
- [0] = {
- .start = S3C_PA_USB_HSOTG,
- .end = S3C_PA_USB_HSOTG + 0x10000 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_OTG,
- .end = IRQ_OTG,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device s3c_device_usb_hsotg = {
- .name = "s3c-hsotg",
- .id = -1,
- .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources),
- .resource = s3c_usb_hsotg_resources,
-};
diff --git a/arch/arm/plat-s3c/dev-usb.c b/arch/arm/plat-s3c/dev-usb.c
deleted file mode 100644
index 2ee85abed6d..00000000000
--- a/arch/arm/plat-s3c/dev-usb.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-usb.c
- *
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for USB host
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-
-static struct resource s3c_usb_resource[] = {
- [0] = {
- .start = S3C_PA_USBHOST,
- .end = S3C_PA_USBHOST + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_USBH,
- .end = IRQ_USBH,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static u64 s3c_device_usb_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_usb = {
- .name = "s3c2410-ohci",
- .id = -1,
- .num_resources = ARRAY_SIZE(s3c_usb_resource),
- .resource = s3c_usb_resource,
- .dev = {
- .dma_mask = &s3c_device_usb_dmamask,
- .coherent_dma_mask = 0xffffffffUL
- }
-};
-
-EXPORT_SYMBOL(s3c_device_usb);
diff --git a/arch/arm/plat-s3c/dma.c b/arch/arm/plat-s3c/dma.c
deleted file mode 100644
index a995850cd9d..00000000000
--- a/arch/arm/plat-s3c/dma.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* linux/arch/arm/plat-s3c/dma.c
- *
- * Copyright (c) 2003-2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C DMA core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct s3c2410_dma_buf;
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-#include <plat/dma-plat.h>
-
-/* dma channel state information */
-struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
-struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
-
-/* s3c_dma_lookup_channel
- *
- * change the dma channel number given into a real dma channel id
-*/
-
-struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
-{
- if (channel & DMACH_LOW_LEVEL)
- return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
- else
- return s3c_dma_chan_map[channel];
-}
-
-/* do we need to protect the settings of the fields from
- * irq?
-*/
-
-int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
-
- chan->op_fn = rtn;
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_set_opfn);
-
-int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
-
- chan->callback_fn = rtn;
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
-
-int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- chan->flags = flags;
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_setflags);
diff --git a/arch/arm/plat-s3c/gpio-config.c b/arch/arm/plat-s3c/gpio-config.c
deleted file mode 100644
index 456969b6fa0..00000000000
--- a/arch/arm/plat-s3c/gpio-config.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/* linux/arch/arm/plat-s3c/gpio-config.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C series GPIO configuration core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <mach/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
-{
- struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
- unsigned long flags;
- int offset;
- int ret;
-
- if (!chip)
- return -EINVAL;
-
- offset = pin - chip->chip.base;
-
- local_irq_save(flags);
- ret = s3c_gpio_do_setcfg(chip, offset, config);
- local_irq_restore(flags);
-
- return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_cfgpin);
-
-int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
-{
- struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
- unsigned long flags;
- int offset, ret;
-
- if (!chip)
- return -EINVAL;
-
- offset = pin - chip->chip.base;
-
- local_irq_save(flags);
- ret = s3c_gpio_do_setpull(chip, offset, pull);
- local_irq_restore(flags);
-
- return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_setpull);
-
-#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
-int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
- unsigned int off, unsigned int cfg)
-{
- void __iomem *reg = chip->base;
- unsigned int shift = off;
- u32 con;
-
- if (s3c_gpio_is_cfg_special(cfg)) {
- cfg &= 0xf;
-
- /* Map output to 0, and SFN2 to 1 */
- cfg -= 1;
- if (cfg > 1)
- return -EINVAL;
-
- cfg <<= shift;
- }
-
- con = __raw_readl(reg);
- con &= ~(0x1 << shift);
- con |= cfg;
- __raw_writel(con, reg);
-
- return 0;
-}
-
-int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
- unsigned int off, unsigned int cfg)
-{
- void __iomem *reg = chip->base;
- unsigned int shift = off * 2;
- u32 con;
-
- if (s3c_gpio_is_cfg_special(cfg)) {
- cfg &= 0xf;
- if (cfg > 3)
- return -EINVAL;
-
- cfg <<= shift;
- }
-
- con = __raw_readl(reg);
- con &= ~(0x3 << shift);
- con |= cfg;
- __raw_writel(con, reg);
-
- return 0;
-}
-#endif
-
-#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
-int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
- unsigned int off, unsigned int cfg)
-{
- void __iomem *reg = chip->base;
- unsigned int shift = (off & 7) * 4;
- u32 con;
-
- if (off < 8 && chip->chip.ngpio > 8)
- reg -= 4;
-
- if (s3c_gpio_is_cfg_special(cfg)) {
- cfg &= 0xf;
- cfg <<= shift;
- }
-
- con = __raw_readl(reg);
- con &= ~(0xf << shift);
- con |= cfg;
- __raw_writel(con, reg);
-
- return 0;
-}
-#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
-
-#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
-int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
- unsigned int off, s3c_gpio_pull_t pull)
-{
- void __iomem *reg = chip->base + 0x08;
- int shift = off * 2;
- u32 pup;
-
- pup = __raw_readl(reg);
- pup &= ~(3 << shift);
- pup |= pull << shift;
- __raw_writel(pup, reg);
-
- return 0;
-}
-
-s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
- unsigned int off)
-{
- void __iomem *reg = chip->base + 0x08;
- int shift = off * 2;
- u32 pup = __raw_readl(reg);
-
- pup >>= shift;
- pup &= 0x3;
- return (__force s3c_gpio_pull_t)pup;
-}
-#endif
diff --git a/arch/arm/plat-s3c/gpio.c b/arch/arm/plat-s3c/gpio.c
deleted file mode 100644
index 5ff24e0f9f8..00000000000
--- a/arch/arm/plat-s3c/gpio.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* linux/arch/arm/plat-s3c/gpio.c
- *
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C series GPIO core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/gpio-core.h>
-
-#ifdef CONFIG_S3C_GPIO_TRACK
-struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
-
-static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
-{
- unsigned int gpn;
- int i;
-
- gpn = chip->chip.base;
- for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
- BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
- s3c_gpios[gpn] = chip;
- }
-}
-#endif /* CONFIG_S3C_GPIO_TRACK */
-
-/* Default routines for controlling GPIO, based on the original S3C24XX
- * GPIO functions which deal with the case where each gpio bank of the
- * chip is as following:
- *
- * base + 0x00: Control register, 2 bits per gpio
- * gpio n: 2 bits starting at (2*n)
- * 00 = input, 01 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- * bit n: data bit n
-*/
-
-static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
-{
- struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
- void __iomem *base = ourchip->base;
- unsigned long flags;
- unsigned long con;
-
- local_irq_save(flags);
-
- con = __raw_readl(base + 0x00);
- con &= ~(3 << (offset * 2));
-
- __raw_writel(con, base + 0x00);
-
- local_irq_restore(flags);
- return 0;
-}
-
-static int s3c_gpiolib_output(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
- void __iomem *base = ourchip->base;
- unsigned long flags;
- unsigned long dat;
- unsigned long con;
-
- local_irq_save(flags);
-
- dat = __raw_readl(base + 0x04);
- dat &= ~(1 << offset);
- if (value)
- dat |= 1 << offset;
- __raw_writel(dat, base + 0x04);
-
- con = __raw_readl(base + 0x00);
- con &= ~(3 << (offset * 2));
- con |= 1 << (offset * 2);
-
- __raw_writel(con, base + 0x00);
- __raw_writel(dat, base + 0x04);
-
- local_irq_restore(flags);
- return 0;
-}
-
-static void s3c_gpiolib_set(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
- void __iomem *base = ourchip->base;
- unsigned long flags;
- unsigned long dat;
-
- local_irq_save(flags);
-
- dat = __raw_readl(base + 0x04);
- dat &= ~(1 << offset);
- if (value)
- dat |= 1 << offset;
- __raw_writel(dat, base + 0x04);
-
- local_irq_restore(flags);
-}
-
-static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
-{
- struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
- unsigned long val;
-
- val = __raw_readl(ourchip->base + 0x04);
- val >>= offset;
- val &= 1;
-
- return val;
-}
-
-__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
-{
- struct gpio_chip *gc = &chip->chip;
- int ret;
-
- BUG_ON(!chip->base);
- BUG_ON(!gc->label);
- BUG_ON(!gc->ngpio);
-
- if (!gc->direction_input)
- gc->direction_input = s3c_gpiolib_input;
- if (!gc->direction_output)
- gc->direction_output = s3c_gpiolib_output;
- if (!gc->set)
- gc->set = s3c_gpiolib_set;
- if (!gc->get)
- gc->get = s3c_gpiolib_get;
-
-#ifdef CONFIG_PM
- if (chip->pm != NULL) {
- if (!chip->pm->save || !chip->pm->resume)
- printk(KERN_ERR "gpio: %s has missing PM functions\n",
- gc->label);
- } else
- printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
-#endif
-
- /* gpiochip_add() prints own failure message on error. */
- ret = gpiochip_add(gc);
- if (ret >= 0)
- s3c_gpiolib_track(chip);
-}
diff --git a/arch/arm/plat-s3c/include/mach/io.h b/arch/arm/plat-s3c/include/mach/io.h
deleted file mode 100644
index f6a53631b66..00000000000
--- a/arch/arm/plat-s3c/include/mach/io.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* arch/arm/plat-s3c/include/mach/io.h
- *
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben-linux@fluff.org>
- *
- * Default IO routines for plat-s3c based systems, such as S3C24A0
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-/* No current ISA/PCI bus support. */
-#define __io(a) __typesafe_io(a)
-#define __mem_pci(a) (a)
-
-#define IO_SPACE_LIMIT (0xFFFFFFFF)
-
-#endif
diff --git a/arch/arm/plat-s3c/include/mach/timex.h b/arch/arm/plat-s3c/include/mach/timex.h
deleted file mode 100644
index 2a425ed0a7e..00000000000
--- a/arch/arm/plat-s3c/include/mach/timex.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/timex.h
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-
-#define CLOCK_TICK_RATE 12000000
-
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/plat-s3c/include/mach/vmalloc.h b/arch/arm/plat-s3c/include/mach/vmalloc.h
deleted file mode 100644
index 299d95f365c..00000000000
--- a/arch/arm/plat-s3c/include/mach/vmalloc.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* arch/arm/plat-s3c/include/mach/vmalloc.h
- *
- * from arch/arm/mach-iop3xx/include/mach/vmalloc.h
- *
- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
- * http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 vmalloc definition
-*/
-
-#ifndef __ASM_ARCH_VMALLOC_H
-#define __ASM_ARCH_VMALLOC_H
-
-#define VMALLOC_END (0xe0000000UL)
-
-#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/plat-s3c/include/plat/adc.h b/arch/arm/plat-s3c/include/plat/adc.h
deleted file mode 100644
index 5f3b1cd53b9..00000000000
--- a/arch/arm/plat-s3c/include/plat/adc.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/adc.h
- *
- * Copyright (c) 2008 Simtec Electronics
- * http://armlinux.simnte.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX ADC driver information
- *
- * This program is free software; you can 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_H
-#define __ASM_PLAT_ADC_H __FILE__
-
-struct s3c_adc_client;
-
-extern int s3c_adc_start(struct s3c_adc_client *client,
- unsigned int channel, unsigned int nr_samples);
-
-extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
-
-extern struct s3c_adc_client *
- s3c_adc_register(struct platform_device *pdev,
- void (*select)(struct s3c_adc_client *client,
- unsigned selected),
- void (*conv)(struct s3c_adc_client *client,
- unsigned d0, unsigned d1,
- unsigned *samples_left),
- unsigned int is_ts);
-
-extern void s3c_adc_release(struct s3c_adc_client *client);
-
-#endif /* __ASM_PLAT_ADC_H */
diff --git a/arch/arm/plat-s3c/include/plat/audio-simtec.h b/arch/arm/plat-s3c/include/plat/audio-simtec.h
deleted file mode 100644
index 53a93656d5d..00000000000
--- a/arch/arm/plat-s3c/include/plat/audio-simtec.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/audio-simtec.h
- *
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Simtec Audio support.
-*/
-
-/**
- * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
- * @use_mpllin: Select codec clock from MPLLin
- * @output_cdclk: Need to output CDCLK to the codec
- * @have_mic: Set if we have a MIC socket
- * @have_lout: Set if we have a LineOut socket
- * @amp_gpio: GPIO pin to enable the AMP
- * @amp_gain: Option GPIO to control AMP gain
- */
-struct s3c24xx_audio_simtec_pdata {
- unsigned int use_mpllin:1;
- unsigned int output_cdclk:1;
-
- unsigned int have_mic:1;
- unsigned int have_lout:1;
-
- int amp_gpio;
- int amp_gain[2];
-
- void (*startup)(void);
-};
-
-extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
- struct s3c24xx_audio_simtec_pdata *pdata);
diff --git a/arch/arm/plat-s3c/include/plat/audio.h b/arch/arm/plat-s3c/include/plat/audio.h
deleted file mode 100644
index f22d23bb627..00000000000
--- a/arch/arm/plat-s3c/include/plat/audio.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/audio.h
- *
- * Copyright (c) 2009 Samsung Electronics Co. Ltd
- * Author: Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/**
- * struct s3c_audio_pdata - common platform data for audio device drivers
- * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
- */
-struct s3c_audio_pdata {
- int (*cfg_gpio)(struct platform_device *);
-};
diff --git a/arch/arm/plat-s3c/include/plat/clock.h b/arch/arm/plat-s3c/include/plat/clock.h
deleted file mode 100644
index d86af84b5b8..00000000000
--- a/arch/arm/plat-s3c/include/plat/clock.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/clock.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- * http://www.simtec.co.uk/products/SWLINUX/
- * Written by Ben Dooks, <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/spinlock.h>
-
-struct clk {
- struct list_head list;
- struct module *owner;
- struct clk *parent;
- const char *name;
- int id;
- int usage;
- unsigned long rate;
- unsigned long ctrlbit;
-
- int (*enable)(struct clk *, int enable);
- int (*set_rate)(struct clk *c, unsigned long rate);
- unsigned long (*get_rate)(struct clk *c);
- unsigned long (*round_rate)(struct clk *c, unsigned long rate);
- int (*set_parent)(struct clk *c, struct clk *parent);
-};
-
-/* other clocks which may be registered by board support */
-
-extern struct clk s3c24xx_dclk0;
-extern struct clk s3c24xx_dclk1;
-extern struct clk s3c24xx_clkout0;
-extern struct clk s3c24xx_clkout1;
-extern struct clk s3c24xx_uclk;
-
-extern struct clk clk_usb_bus;
-
-/* core clock support */
-
-extern struct clk clk_f;
-extern struct clk clk_h;
-extern struct clk clk_p;
-extern struct clk clk_mpll;
-extern struct clk clk_upll;
-extern struct clk clk_epll;
-extern struct clk clk_xtal;
-extern struct clk clk_ext;
-
-/* S3C64XX specific clocks */
-extern struct clk clk_h2;
-extern struct clk clk_27m;
-extern struct clk clk_48m;
-
-/* exports for arch/arm/mach-s3c2410
- *
- * Please DO NOT use these outside of arch/arm/mach-s3c2410
-*/
-
-extern spinlock_t clocks_lock;
-
-extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
-
-extern int s3c24xx_register_clock(struct clk *clk);
-extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
-
-extern int s3c24xx_register_baseclocks(unsigned long xtal);
-
-extern void s3c64xx_register_clocks(void);
-
-extern void s3c24xx_setup_clocks(unsigned long fclk,
- unsigned long hclk,
- unsigned long pclk);
-
-extern void s3c2410_setup_clocks(void);
-extern void s3c2412_setup_clocks(void);
-extern void s3c244x_setup_clocks(void);
-extern void s3c2443_setup_clocks(void);
-
-/* S3C64XX specific functions and clocks */
-
-extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
-
-/* Init for pwm clock code */
-
-extern void s3c_pwmclk_init(void);
-
diff --git a/arch/arm/plat-s3c/include/plat/cpu-freq.h b/arch/arm/plat-s3c/include/plat/cpu-freq.h
deleted file mode 100644
index 94eb06a2ea5..00000000000
--- a/arch/arm/plat-s3c/include/plat/cpu-freq.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/cpu-freq.h
- *
- * Copyright (c) 2006-2007 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C CPU frequency scaling support - driver and board
- *
- * This program is free software; you can 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/cpufreq.h>
-
-struct s3c_cpufreq_info;
-struct s3c_cpufreq_board;
-struct s3c_iotimings;
-
-/**
- * struct s3c_freq - frequency information (mainly for core drivers)
- * @fclk: The FCLK frequency in Hz.
- * @armclk: The ARMCLK frequency in Hz.
- * @hclk_tns: HCLK cycle time in 10ths of nano-seconds.
- * @hclk: The HCLK frequency in Hz.
- * @pclk: The PCLK frequency in Hz.
- *
- * This contains the frequency information about the current configuration
- * mainly for the core drivers to ensure we do not end up passing about
- * a large number of parameters.
- *
- * The @hclk_tns field is a useful cache for the parts of the drivers that
- * need to calculate IO timings and suchlike.
- */
-struct s3c_freq {
- unsigned long fclk;
- unsigned long armclk;
- unsigned long hclk_tns; /* in 10ths of ns */
- unsigned long hclk;
- unsigned long pclk;
-};
-
-/**
- * struct s3c_cpufreq_freqs - s3c cpufreq notification information.
- * @freqs: The cpufreq setting information.
- * @old: The old clock settings.
- * @new: The new clock settings.
- * @pll_changing: Set if the PLL is changing.
- *
- * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the
- * notification can use this information that is not provided by just
- * having the core frequency alone.
- *
- * The pll_changing flag is used to indicate if the PLL itself is
- * being set during this change. This is important as the clocks
- * will temporarily be set to the XTAL clock during this time, so
- * drivers may want to close down their output during this time.
- *
- * Note, this is not being used by any current drivers and therefore
- * may be removed in the future.
- */
-struct s3c_cpufreq_freqs {
- struct cpufreq_freqs freqs;
- struct s3c_freq old;
- struct s3c_freq new;
-
- unsigned int pll_changing:1;
-};
-
-#define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs)
-
-/**
- * struct s3c_clkdivs - clock divisor information
- * @p_divisor: Divisor from FCLK to PCLK.
- * @h_divisor: Divisor from FCLK to HCLK.
- * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs).
- * @dvs: Non-zero if using DVS mode for ARMCLK.
- *
- * Divisor settings for the core clocks.
- */
-struct s3c_clkdivs {
- int p_divisor;
- int h_divisor;
- int arm_divisor;
- unsigned char dvs;
-};
-
-#define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s))
-
-/**
- * struct s3c_pllval - PLL value entry.
- * @freq: The frequency for this entry in Hz.
- * @pll_reg: The PLL register setting for this PLL value.
- */
-struct s3c_pllval {
- unsigned long freq;
- unsigned long pll_reg;
-};
-
-/**
- * struct s3c_cpufreq_board - per-board cpu frequency informatin
- * @refresh: The SDRAM refresh period in nanoseconds.
- * @auto_io: Set if the IO timing settings should be generated from the
- * initialisation time hardware registers.
- * @need_io: Set if the board has external IO on any of the chipselect
- * lines that will require the hardware timing registers to be
- * updated on a clock change.
- * @max: The maxium frequency limits for the system. Any field that
- * is left at zero will use the CPU's settings.
- *
- * This contains the board specific settings that affect how the CPU
- * drivers chose settings. These include the memory refresh and IO
- * timing information.
- *
- * Registration depends on the driver being used, the ARMCLK only
- * implementation does not currently need this but the older style
- * driver requires this to be available.
- */
-struct s3c_cpufreq_board {
- unsigned int refresh;
- unsigned int auto_io:1; /* automatically init io timings. */
- unsigned int need_io:1; /* set if needs io timing support. */
-
- /* any non-zero field in here is taken as an upper limit. */
- struct s3c_freq max; /* frequency limits */
-};
-
-/* Things depending on frequency scaling. */
-#ifdef CONFIG_CPU_FREQ_S3C
-#define __init_or_cpufreq
-#else
-#define __init_or_cpufreq __init
-#endif
-
-/* Board functions */
-
-#ifdef CONFIG_CPU_FREQ_S3C
-extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board);
-#else
-
-static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
-{
- return 0;
-}
-#endif /* CONFIG_CPU_FREQ_S3C */
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h
deleted file mode 100644
index d1131ca11e9..00000000000
--- a/arch/arm/plat-s3c/include/plat/cpu.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/cpu.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C24XX CPU support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* todo - fix when rmk changes iodescs to use `void __iomem *` */
-
-#ifndef __SAMSUNG_PLAT_CPU_H
-#define __SAMSUNG_PLAT_CPU_H
-
-#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
-
-#ifndef MHZ
-#define MHZ (1000*1000)
-#endif
-
-#define print_mhz(m) ((m) / MHZ), (((m) / 1000) % 1000)
-
-/* forward declaration */
-struct s3c24xx_uart_resources;
-struct platform_device;
-struct s3c2410_uartcfg;
-struct map_desc;
-
-/* per-cpu initialisation function table. */
-
-struct cpu_table {
- unsigned long idcode;
- unsigned long idmask;
- void (*map_io)(void);
- void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
- void (*init_clocks)(int xtal);
- int (*init)(void);
- const char *name;
-};
-
-extern void s3c_init_cpu(unsigned long idcode,
- struct cpu_table *cpus, unsigned int cputab_size);
-
-/* core initialisation functions */
-
-extern void s3c24xx_init_irq(void);
-extern void s3c64xx_init_irq(u32 vic0, u32 vic1);
-
-extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
-extern void s3c64xx_init_io(struct map_desc *mach_desc, int size);
-
-extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c24xx_init_clocks(int xtal);
-
-extern void s3c24xx_init_uartdevs(char *name,
- struct s3c24xx_uart_resources *res,
- struct s3c2410_uartcfg *cfg, int no);
-
-/* timer for 2410/2440 */
-
-struct sys_timer;
-extern struct sys_timer s3c24xx_timer;
-
-/* system device classes */
-
-extern struct sysdev_class s3c2410_sysclass;
-extern struct sysdev_class s3c2410a_sysclass;
-extern struct sysdev_class s3c2412_sysclass;
-extern struct sysdev_class s3c2440_sysclass;
-extern struct sysdev_class s3c2442_sysclass;
-extern struct sysdev_class s3c2443_sysclass;
-extern struct sysdev_class s3c6410_sysclass;
-extern struct sysdev_class s3c64xx_sysclass;
-
-extern void (*s5pc1xx_idle)(void);
-
-#endif
diff --git a/arch/arm/plat-s3c/include/plat/debug-macro.S b/arch/arm/plat-s3c/include/plat/debug-macro.S
deleted file mode 100644
index 3634d4e3708..00000000000
--- a/arch/arm/plat-s3c/include/plat/debug-macro.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/* linux/include/asm-arm/plat-s3c/debug-macro.S
- *
- * Copyright 2005, 2007 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <plat/regs-serial.h>
-
-/* The S3C2440 implementations are used by default as they are the
- * most widely re-used */
-
- .macro fifo_level_s3c2440 rd, rx
- ldr \rd, [ \rx, # S3C2410_UFSTAT ]
- and \rd, \rd, #S3C2440_UFSTAT_TXMASK
- .endm
-
-#ifndef fifo_level
-#define fifo_level fifo_level_s3c2440
-#endif
-
- .macro fifo_full_s3c2440 rd, rx
- ldr \rd, [ \rx, # S3C2410_UFSTAT ]
- tst \rd, #S3C2440_UFSTAT_TXFULL
- .endm
-
-#ifndef fifo_full
-#define fifo_full fifo_full_s3c2440
-#endif
-
- .macro senduart,rd,rx
- strb \rd, [\rx, # S3C2410_UTXH ]
- .endm
-
- .macro busyuart, rd, rx
- ldr \rd, [ \rx, # S3C2410_UFCON ]
- tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled?
- beq 1001f @
- @ FIFO enabled...
-1003:
- fifo_full \rd, \rx
- bne 1003b
- b 1002f
-
-1001:
- @ busy waiting for non fifo
- ldr \rd, [ \rx, # S3C2410_UTRSTAT ]
- tst \rd, #S3C2410_UTRSTAT_TXFE
- beq 1001b
-
-1002: @ exit busyuart
- .endm
-
- .macro waituart,rd,rx
- ldr \rd, [ \rx, # S3C2410_UFCON ]
- tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled?
- beq 1001f @
- @ FIFO enabled...
-1003:
- fifo_level \rd, \rx
- teq \rd, #0
- bne 1003b
- b 1002f
-1001:
- @ idle waiting for non fifo
- ldr \rd, [ \rx, # S3C2410_UTRSTAT ]
- tst \rd, #S3C2410_UTRSTAT_TXFE
- beq 1001b
-
-1002: @ exit busyuart
- .endm
diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h
deleted file mode 100644
index c1c20b02391..00000000000
--- a/arch/arm/plat-s3c/include/plat/devs.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/devs.h
- *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2410 standard platform devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#include <linux/platform_device.h>
-
-struct s3c24xx_uart_resources {
- struct resource *resources;
- unsigned long nr_resources;
-};
-
-extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
-extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
-
-extern struct platform_device *s3c24xx_uart_devs[];
-extern struct platform_device *s3c24xx_uart_src[];
-
-extern struct platform_device s3c_device_timer[];
-
-extern struct platform_device s3c64xx_device_iis0;
-extern struct platform_device s3c64xx_device_iis1;
-extern struct platform_device s3c64xx_device_iisv4;
-
-extern struct platform_device s3c64xx_device_pcm0;
-extern struct platform_device s3c64xx_device_pcm1;
-
-extern struct platform_device s3c_device_ts;
-extern struct platform_device s3c_device_fb;
-extern struct platform_device s3c_device_usb;
-extern struct platform_device s3c_device_lcd;
-extern struct platform_device s3c_device_wdt;
-extern struct platform_device s3c_device_i2c0;
-extern struct platform_device s3c_device_i2c1;
-extern struct platform_device s3c_device_rtc;
-extern struct platform_device s3c_device_adc;
-extern struct platform_device s3c_device_sdi;
-extern struct platform_device s3c_device_iis;
-extern struct platform_device s3c_device_hwmon;
-extern struct platform_device s3c_device_hsmmc0;
-extern struct platform_device s3c_device_hsmmc1;
-extern struct platform_device s3c_device_hsmmc2;
-
-extern struct platform_device s3c_device_spi0;
-extern struct platform_device s3c_device_spi1;
-
-extern struct platform_device s3c_device_hwmon;
-
-extern struct platform_device s3c_device_nand;
-
-extern struct platform_device s3c_device_usbgadget;
-extern struct platform_device s3c_device_usb_hsotg;
-
-/* s3c2440 specific devices */
-
-#ifdef CONFIG_CPU_S3C2440
-
-extern struct platform_device s3c_device_camif;
-extern struct platform_device s3c_device_ac97;
-
-#endif
diff --git a/arch/arm/plat-s3c/include/plat/dma.h b/arch/arm/plat-s3c/include/plat/dma.h
deleted file mode 100644
index e429d10be3a..00000000000
--- a/arch/arm/plat-s3c/include/plat/dma.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/dma.h
- *
- * Copyright (C) 2003-2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-enum s3c2410_dma_buffresult {
- S3C2410_RES_OK,
- S3C2410_RES_ERR,
- S3C2410_RES_ABORT
-};
-
-enum s3c2410_dmasrc {
- S3C2410_DMASRC_HW, /* source is memory */
- S3C2410_DMASRC_MEM /* source is hardware */
-};
-
-/* enum s3c2410_chan_op
- *
- * operation codes passed to the DMA code by the user, and also used
- * to inform the current channel owner of any changes to the system state
-*/
-
-enum s3c2410_chan_op {
- S3C2410_DMAOP_START,
- S3C2410_DMAOP_STOP,
- S3C2410_DMAOP_PAUSE,
- S3C2410_DMAOP_RESUME,
- S3C2410_DMAOP_FLUSH,
- S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */
- S3C2410_DMAOP_STARTED, /* indicate channel started */
-};
-
-struct s3c2410_dma_client {
- char *name;
-};
-
-struct s3c2410_dma_chan;
-
-/* s3c2410_dma_cbfn_t
- *
- * buffer callback routine type
-*/
-
-typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
- void *buf, int size,
- enum s3c2410_dma_buffresult result);
-
-typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
- enum s3c2410_chan_op );
-
-
-
-/* s3c2410_dma_request
- *
- * request a dma channel exclusivley
-*/
-
-extern int s3c2410_dma_request(unsigned int channel,
- struct s3c2410_dma_client *, void *dev);
-
-
-/* s3c2410_dma_ctrl
- *
- * change the state of the dma channel
-*/
-
-extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op);
-
-/* s3c2410_dma_setflags
- *
- * set the channel's flags to a given state
-*/
-
-extern int s3c2410_dma_setflags(unsigned int channel,
- unsigned int flags);
-
-/* s3c2410_dma_free
- *
- * free the dma channel (will also abort any outstanding operations)
-*/
-
-extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *);
-
-/* s3c2410_dma_enqueue
- *
- * place the given buffer onto the queue of operations for the channel.
- * The buffer must be allocated from dma coherent memory, or the Dcache/WB
- * drained before the buffer is given to the DMA system.
-*/
-
-extern int s3c2410_dma_enqueue(unsigned int channel, void *id,
- dma_addr_t data, int size);
-
-/* s3c2410_dma_config
- *
- * configure the dma channel
-*/
-
-extern int s3c2410_dma_config(unsigned int channel, int xferunit);
-
-/* s3c2410_dma_devconfig
- *
- * configure the device we're talking to
-*/
-
-extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
- unsigned long devaddr);
-
-/* s3c2410_dma_getposition
- *
- * get the position that the dma transfer is currently at
-*/
-
-extern int s3c2410_dma_getposition(unsigned int channel,
- dma_addr_t *src, dma_addr_t *dest);
-
-extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn);
-extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn);
-
-
diff --git a/arch/arm/plat-s3c/include/plat/fb.h b/arch/arm/plat-s3c/include/plat/fb.h
deleted file mode 100644
index f8db87930f8..00000000000
--- a/arch/arm/plat-s3c/include/plat/fb.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/fb.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - FB platform data definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_S3C_FB_H
-#define __PLAT_S3C_FB_H __FILE__
-
-/**
- * struct s3c_fb_pd_win - per window setup data
- * @win_mode: The display parameters to initialise (not for window 0)
- * @virtual_x: The virtual X size.
- * @virtual_y: The virtual Y size.
- */
-struct s3c_fb_pd_win {
- struct fb_videomode win_mode;
-
- unsigned short default_bpp;
- unsigned short max_bpp;
- unsigned short virtual_x;
- unsigned short virtual_y;
-};
-
-/**
- * struct s3c_fb_platdata - S3C driver platform specific information
- * @setup_gpio: Setup the external GPIO pins to the right state to transfer
- * the data from the display system to the connected display
- * device.
- * @vidcon0: The base vidcon0 values to control the panel data format.
- * @vidcon1: The base vidcon1 values to control the panel data output.
- * @win: The setup data for each hardware window, or NULL for unused.
- * @display_mode: The LCD output display mode.
- *
- * The platform data supplies the video driver with all the information
- * it requires to work with the display(s) attached to the machine. It
- * controls the initial mode, the number of display windows (0 is always
- * the base framebuffer) that are initialised etc.
- *
- */
-struct s3c_fb_platdata {
- void (*setup_gpio)(void);
-
- struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN];
-
- u32 vidcon0;
- u32 vidcon1;
-};
-
-/**
- * s3c_fb_set_platdata() - Setup the FB device with platform data.
- * @pd: The platform data to set. The data is copied from the passed structure
- * so the machine data can mark the data __initdata so that any unused
- * machines will end up dumping their data at runtime.
- */
-extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
-
-/**
- * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
- *
- * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
- */
-extern void s3c64xx_fb_gpio_setup_24bpp(void);
-
-/**
- * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
- *
- * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
- */
-extern void s5pc100_fb_gpio_setup_24bpp(void);
-
-#endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h
deleted file mode 100644
index 652e2bbdaa2..00000000000
--- a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - GPIO pin configuration helper definitions
- *
- * This program is free software; you can 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 is meant for core cpu support, machine or other driver files
- * should not be including this header.
- */
-
-#ifndef __PLAT_GPIO_CFG_HELPERS_H
-#define __PLAT_GPIO_CFG_HELPERS_H __FILE__
-
-/* As a note, all gpio configuration functions are entered exclusively, either
- * with the relevant lock held or the system prevented from doing anything else
- * by disabling interrupts.
-*/
-
-static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
- unsigned int off, unsigned int config)
-{
- return (chip->config->set_config)(chip, off, config);
-}
-
-static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
- unsigned int off, s3c_gpio_pull_t pull)
-{
- return (chip->config->set_pull)(chip, off, pull);
-}
-
-/**
- * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register
- * has two bits of configuration per gpio, which have the following
- * functions:
- * 00 = input
- * 01 = output
- * 1x = special function
-*/
-extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
- unsigned int off, unsigned int cfg);
-
-/**
- * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register
- * has one bit of configuration for the gpio, where setting the bit
- * means the pin is in special function mode and unset means output.
-*/
-extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
- unsigned int off, unsigned int cfg);
-
-/**
- * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register has 4 bits
- * of control per GPIO, generally in the form of:
- * 0000 = Input
- * 0001 = Output
- * others = Special functions (dependant on bank)
- *
- * Note, since the code to deal with the case where there are two control
- * registers instead of one, we do not have a seperate set of functions for
- * each case.
-*/
-extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
- unsigned int off, unsigned int cfg);
-
-
-/* Pull-{up,down} resistor controls.
- *
- * S3C2410,S3C2440,S3C24A0 = Pull-UP,
- * S3C2412,S3C2413 = Pull-Down
- * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef]
- * S3C2443 = Pull-Both [not same as S3C6400]
- */
-
-/**
- * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @param: pull: The pull mode being requested.
- *
- * This is a helper function for the case where we have GPIOs with one
- * bit configuring the presence of a pull-up resistor.
- */
-extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
- unsigned int off, s3c_gpio_pull_t pull);
-
-/**
- * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none
- * @chip: The gpio chip that is being configured
- * @off: The offset for the GPIO being configured
- * @param: pull: The pull mode being requested
- *
- * This is a helper function for the case where we have GPIOs with one
- * bit configuring the presence of a pull-down resistor.
- */
-extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
- unsigned int off, s3c_gpio_pull_t pull);
-
-/**
- * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @param: pull: The pull mode being requested.
- *
- * This is a helper function for the case where we have GPIOs with two
- * bits configuring the presence of a pull resistor, in the following
- * order:
- * 00 = No pull resistor connected
- * 01 = Pull-up resistor connected
- * 10 = Pull-down resistor connected
- */
-extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
- unsigned int off, s3c_gpio_pull_t pull);
-
-
-/**
- * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none
- * @chip: The gpio chip that the GPIO pin belongs to
- * @off: The offset to the pin to get the configuration of.
- *
- * This helper function reads the state of the pull-{up,down} resistor for the
- * given GPIO in the same case as s3c_gpio_setpull_upown.
-*/
-extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
- unsigned int off);
-
-/**
- * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @param: pull: The pull mode being requested.
- *
- * This is a helper function for the case where we have GPIOs with two
- * bits configuring the presence of a pull resistor, in the following
- * order:
- * 00 = Pull-up resistor connected
- * 10 = Pull-down resistor connected
- * x1 = No pull up resistor
- */
-extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
- unsigned int off, s3c_gpio_pull_t pull);
-
-/**
- * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors
- * @chip: The gpio chip that the GPIO pin belongs to.
- * @off: The offset to the pin to get the configuration of.
- *
- * This helper function reads the state of the pull-{up,down} resistor for the
- * given GPIO in the same case as s3c_gpio_setpull_upown.
-*/
-extern s3c_gpio_pull_t s3c_gpio_getpull_s3c24xx(struct s3c_gpio_chip *chip,
- unsigned int off);
-
-#endif /* __PLAT_GPIO_CFG_HELPERS_H */
-
diff --git a/arch/arm/plat-s3c/include/plat/gpio-core.h b/arch/arm/plat-s3c/include/plat/gpio-core.h
deleted file mode 100644
index 32af612767a..00000000000
--- a/arch/arm/plat-s3c/include/plat/gpio-core.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/gpio-core.h
- *
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - GPIO core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Define the core gpiolib support functions that the s3c platforms may
- * need to extend or change depending on the hardware and the s3c chip
- * selected at build or found at run time.
- *
- * These definitions are not intended for driver inclusion, there is
- * nothing here that should not live outside the platform and core
- * specific code.
-*/
-
-struct s3c_gpio_chip;
-
-/**
- * struct s3c_gpio_pm - power management (suspend/resume) information
- * @save: Routine to save the state of the GPIO block
- * @resume: Routine to resume the GPIO block.
- */
-struct s3c_gpio_pm {
- void (*save)(struct s3c_gpio_chip *chip);
- void (*resume)(struct s3c_gpio_chip *chip);
-};
-
-struct s3c_gpio_cfg;
-
-/**
- * struct s3c_gpio_chip - wrapper for specific implementation of gpio
- * @chip: The chip structure to be exported via gpiolib.
- * @base: The base pointer to the gpio configuration registers.
- * @config: special function and pull-resistor control information.
- * @pm_save: Save information for suspend/resume support.
- *
- * This wrapper provides the necessary information for the Samsung
- * specific gpios being registered with gpiolib.
- */
-struct s3c_gpio_chip {
- struct gpio_chip chip;
- struct s3c_gpio_cfg *config;
- struct s3c_gpio_pm *pm;
- void __iomem *base;
-#ifdef CONFIG_PM
- u32 pm_save[4];
-#endif
-};
-
-static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
-{
- return container_of(gpc, struct s3c_gpio_chip, chip);
-}
-
-/** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip.
- * @chip: The chip to register
- *
- * This is a wrapper to gpiochip_add() that takes our specific gpio chip
- * information and makes the necessary alterations for the platform and
- * notes the information for use with the configuration systems and any
- * other parts of the system.
- */
-extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
-
-/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
- * for use with the configuration calls, and other parts of the s3c gpiolib
- * support code.
- *
- * Not all s3c support code will need this, as some configurations of cpu
- * may only support one or two different configuration options and have an
- * easy gpio to s3c_gpio_chip mapping function. If this is the case, then
- * the machine support file should provide its own s3c_gpiolib_getchip()
- * and any other necessary functions.
- */
-
-#ifdef CONFIG_S3C_GPIO_TRACK
-extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
-
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
-{
- return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
-}
-#else
-/* machine specific code should provide s3c_gpiolib_getchip */
-
-static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
-#endif
-
-#ifdef CONFIG_PM
-extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
-extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
-extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
-#define __gpio_pm(x) x
-#else
-#define s3c_gpio_pm_1bit NULL
-#define s3c_gpio_pm_2bit NULL
-#define s3c_gpio_pm_4bit NULL
-#define __gpio_pm(x) NULL
-
-#endif /* CONFIG_PM */
diff --git a/arch/arm/plat-s3c/include/plat/nand.h b/arch/arm/plat-s3c/include/plat/nand.h
deleted file mode 100644
index 226147b7e02..00000000000
--- a/arch/arm/plat-s3c/include/plat/nand.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/nand.h
- *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - NAND device controller platfrom_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.
-*/
-
-/**
- * struct s3c2410_nand_set - define a set of one or more nand chips
- * @disable_ecc: Entirely disable ECC - Dangerous
- * @flash_bbt: Openmoko u-boot can create a Bad Block Table
- * Setting this flag will allow the kernel to
- * look for it at boot time and also skip the NAND
- * scan.
- * @options: Default value to set into 'struct nand_chip' options.
- * @nr_chips: Number of chips in this set
- * @nr_partitions: Number of partitions pointed to by @partitions
- * @name: Name of set (optional)
- * @nr_map: Map for low-layer logical to physical chip numbers (option)
- * @partitions: The mtd partition list
- *
- * define a set of one or more nand chips registered with an unique mtd. Also
- * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger
- * a warning at boot time.
- */
-struct s3c2410_nand_set {
- unsigned int disable_ecc:1;
- unsigned int flash_bbt:1;
-
- unsigned int options;
- int nr_chips;
- int nr_partitions;
- char *name;
- int *nr_map;
- struct mtd_partition *partitions;
- struct nand_ecclayout *ecc_layout;
-};
-
-struct s3c2410_platform_nand {
- /* timing information for controller, all times in nanoseconds */
-
- int tacls; /* time for active CLE/ALE to nWE/nOE */
- int twrph0; /* active time for nWE/nOE */
- int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */
-
- unsigned int ignore_unset_ecc:1;
-
- int nr_sets;
- struct s3c2410_nand_set *sets;
-
- void (*select_chip)(struct s3c2410_nand_set *,
- int chip);
-};
-
-/**
- * s3c_nand_set_platdata() - register NAND platform data.
- * @nand: The NAND platform data to register with s3c_device_nand.
- *
- * This function copies the given NAND platform data, @nand and registers
- * it with the s3c_device_nand. This allows @nand to be __initdata.
-*/
-extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand);
diff --git a/arch/arm/plat-s3c/include/plat/pm.h b/arch/arm/plat-s3c/include/plat/pm.h
deleted file mode 100644
index 7a797192fcf..00000000000
--- a/arch/arm/plat-s3c/include/plat/pm.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/pm.h
- *
- * Copyright (c) 2004 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Written by Ben Dooks, <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* s3c_pm_init
- *
- * called from board at initialisation time to setup the power
- * management
-*/
-
-#ifdef CONFIG_PM
-
-extern __init int s3c_pm_init(void);
-
-#else
-
-static inline int s3c_pm_init(void)
-{
- return 0;
-}
-#endif
-
-/* configuration for the IRQ mask over sleep */
-extern unsigned long s3c_irqwake_intmask;
-extern unsigned long s3c_irqwake_eintmask;
-
-/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
-extern unsigned long s3c_irqwake_intallow;
-extern unsigned long s3c_irqwake_eintallow;
-
-/* per-cpu sleep functions */
-
-extern void (*pm_cpu_prep)(void);
-extern void (*pm_cpu_sleep)(void);
-
-/* Flags for PM Control */
-
-extern unsigned long s3c_pm_flags;
-
-extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */
-
-/* from sleep.S */
-
-extern int s3c_cpu_save(unsigned long *saveblk);
-extern void s3c_cpu_resume(void);
-
-extern void s3c2410_cpu_suspend(void);
-
-extern unsigned long s3c_sleep_save_phys;
-
-/* sleep save info */
-
-/**
- * struct sleep_save - save information for shared peripherals.
- * @reg: Pointer to the register to save.
- * @val: Holder for the value saved from reg.
- *
- * This describes a list of registers which is used by the pm core and
- * other subsystem to save and restore register values over suspend.
- */
-struct sleep_save {
- void __iomem *reg;
- unsigned long val;
-};
-
-#define SAVE_ITEM(x) \
- { .reg = (x) }
-
-/**
- * struct pm_uart_save - save block for core UART
- * @ulcon: Save value for S3C2410_ULCON
- * @ucon: Save value for S3C2410_UCON
- * @ufcon: Save value for S3C2410_UFCON
- * @umcon: Save value for S3C2410_UMCON
- * @ubrdiv: Save value for S3C2410_UBRDIV
- *
- * Save block for UART registers to be held over sleep and restored if they
- * are needed (say by debug).
-*/
-struct pm_uart_save {
- u32 ulcon;
- u32 ucon;
- u32 ufcon;
- u32 umcon;
- u32 ubrdiv;
- u32 udivslot;
-};
-
-/* helper functions to save/restore lists of registers. */
-
-extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
-extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
-extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
-
-#ifdef CONFIG_PM
-extern int s3c_irqext_wake(unsigned int irqno, unsigned int state);
-extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
-extern int s3c24xx_irq_resume(struct sys_device *dev);
-#else
-#define s3c_irqext_wake NULL
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume NULL
-#endif
-
-/* PM debug functions */
-
-#ifdef CONFIG_S3C2410_PM_DEBUG
-/**
- * s3c_pm_dbg() - low level debug function for use in suspend/resume.
- * @msg: The message to print.
- *
- * This function is used mainly to debug the resume process before the system
- * can rely on printk/console output. It uses the low-level debugging output
- * routine printascii() to do its work.
- */
-extern void s3c_pm_dbg(const char *msg, ...);
-
-#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
-#else
-#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
-#endif
-
-#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
-/**
- * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
- * @set: set bits for the state of the LEDs
- * @clear: clear bits for the state of the LEDs.
- */
-extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
-
-#else
-static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
-#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
-
-/* suspend memory checking */
-
-#ifdef CONFIG_S3C2410_PM_CHECK
-extern void s3c_pm_check_prepare(void);
-extern void s3c_pm_check_restore(void);
-extern void s3c_pm_check_cleanup(void);
-extern void s3c_pm_check_store(void);
-#else
-#define s3c_pm_check_prepare() do { } while(0)
-#define s3c_pm_check_restore() do { } while(0)
-#define s3c_pm_check_cleanup() do { } while(0)
-#define s3c_pm_check_store() do { } while(0)
-#endif
-
-/**
- * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ
- *
- * Setup all the necessary GPIO pins for waking the system on external
- * interrupt.
- */
-extern void s3c_pm_configure_extint(void);
-
-/**
- * s3c_pm_restore_gpios() - restore the state of the gpios after sleep.
- *
- * Restore the state of the GPIO pins after sleep, which may involve ensuring
- * that we do not glitch the state of the pins from that the bootloader's
- * resume code has done.
-*/
-extern void s3c_pm_restore_gpios(void);
-
-/**
- * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
- *
- * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios().
- */
-extern void s3c_pm_save_gpios(void);
-
-/**
- * s3c_pm_cb_flushcache - callback for assembly code
- *
- * Callback to issue flush_cache_all() as this call is
- * not a directly callable object.
- */
-extern void s3c_pm_cb_flushcache(void);
-
-extern void s3c_pm_save_core(void);
-extern void s3c_pm_restore_core(void);
diff --git a/arch/arm/plat-s3c/include/plat/regs-adc.h b/arch/arm/plat-s3c/include/plat/regs-adc.h
deleted file mode 100644
index 4323cccc86c..00000000000
--- a/arch/arm/plat-s3c/include/plat/regs-adc.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-adc.h
- *
- * Copyright (c) 2004 Shannon Holland <holland@loser.net>
- *
- * This program is free software; yosu can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 ADC registers
-*/
-
-#ifndef __ASM_ARCH_REGS_ADC_H
-#define __ASM_ARCH_REGS_ADC_H "regs-adc.h"
-
-#define S3C2410_ADCREG(x) (x)
-
-#define S3C2410_ADCCON S3C2410_ADCREG(0x00)
-#define S3C2410_ADCTSC S3C2410_ADCREG(0x04)
-#define S3C2410_ADCDLY S3C2410_ADCREG(0x08)
-#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C)
-#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
-
-
-/* ADCCON Register Bits */
-#define S3C2410_ADCCON_ECFLG (1<<15)
-#define S3C2410_ADCCON_PRSCEN (1<<14)
-#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
-#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)
-#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)
-#define S3C2410_ADCCON_MUXMASK (0x7<<3)
-#define S3C2410_ADCCON_STDBM (1<<2)
-#define S3C2410_ADCCON_READ_START (1<<1)
-#define S3C2410_ADCCON_ENABLE_START (1<<0)
-#define S3C2410_ADCCON_STARTMASK (0x3<<0)
-
-
-/* ADCTSC Register Bits */
-#define S3C2410_ADCTSC_YM_SEN (1<<7)
-#define S3C2410_ADCTSC_YP_SEN (1<<6)
-#define S3C2410_ADCTSC_XM_SEN (1<<5)
-#define S3C2410_ADCTSC_XP_SEN (1<<4)
-#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)
-#define S3C2410_ADCTSC_AUTO_PST (1<<2)
-#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0)
-
-/* ADCDAT0 Bits */
-#define S3C2410_ADCDAT0_UPDOWN (1<<15)
-#define S3C2410_ADCDAT0_AUTO_PST (1<<14)
-#define S3C2410_ADCDAT0_XY_PST (0x3<<12)
-#define S3C2410_ADCDAT0_XPDATA_MASK (0x03FF)
-
-/* ADCDAT1 Bits */
-#define S3C2410_ADCDAT1_UPDOWN (1<<15)
-#define S3C2410_ADCDAT1_AUTO_PST (1<<14)
-#define S3C2410_ADCDAT1_XY_PST (0x3<<12)
-#define S3C2410_ADCDAT1_YPDATA_MASK (0x03FF)
-
-#endif /* __ASM_ARCH_REGS_ADC_H */
-
-
diff --git a/arch/arm/plat-s3c/include/plat/regs-fb-v4.h b/arch/arm/plat-s3c/include/plat/regs-fb-v4.h
deleted file mode 100644
index a60ed0d06c9..00000000000
--- a/arch/arm/plat-s3c/include/plat/regs-fb-v4.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-fb-v4.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - new-style framebuffer register definitions
- *
- * This is the register set for the new style framebuffer interface
- * found from the S3C2443 onwards and specifically the S3C64XX series
- * S3C6400 and S3C6410.
- *
- * The file contains the cpu specific items which change between whichever
- * architecture is selected. See <plat/regs-fb.h> for the core definitions
- * that are the same.
- *
- * This program is free software; you can 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 the core definitions here, in case we really do need to
- * override them at a later date.
-*/
-
-#include <plat/regs-fb.h>
-
-#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */
-#define VIDCON1_FSTATUS_EVEN (1 << 15)
-
-/* Video timing controls */
-#define VIDTCON0 (0x10)
-#define VIDTCON1 (0x14)
-#define VIDTCON2 (0x18)
-
-/* Window position controls */
-
-#define WINCON(_win) (0x20 + ((_win) * 4))
-
-/* OSD1 and OSD4 do not have register D */
-
-#define VIDOSD_A(_win) (0x40 + ((_win) * 16))
-#define VIDOSD_B(_win) (0x44 + ((_win) * 16))
-#define VIDOSD_C(_win) (0x48 + ((_win) * 16))
-#define VIDOSD_D(_win) (0x4C + ((_win) * 16))
-
-
-#define VIDINTCON0 (0x130)
-
-#define WxKEYCONy(_win, _con) ((0x140 + ((_win) * 8)) + ((_con) * 4))
-
-/* WINCONx */
-
-#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
-#define WINCONx_CSCWIDTH_SHIFT (26)
-#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
-#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
-
-#define WINCONx_ENLOCAL (1 << 22)
-#define WINCONx_BUFSTATUS (1 << 21)
-#define WINCONx_BUFSEL (1 << 20)
-#define WINCONx_BUFAUTOEN (1 << 19)
-#define WINCONx_YCbCr (1 << 13)
-
-#define WINCON1_LOCALSEL_CAMIF (1 << 23)
-
-#define WINCON2_LOCALSEL_CAMIF (1 << 23)
-#define WINCON2_BLD_PIX (1 << 6)
-
-#define WINCON2_ALPHA_SEL (1 << 1)
-#define WINCON2_BPPMODE_MASK (0xf << 2)
-#define WINCON2_BPPMODE_SHIFT (2)
-#define WINCON2_BPPMODE_1BPP (0x0 << 2)
-#define WINCON2_BPPMODE_2BPP (0x1 << 2)
-#define WINCON2_BPPMODE_4BPP (0x2 << 2)
-#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2)
-#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2)
-#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2)
-#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2)
-#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2)
-#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2)
-#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2)
-#define WINCON2_BPPMODE_24BPP_888 (0xb << 2)
-#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2)
-#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2)
-#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2)
-
-#define WINCON3_BLD_PIX (1 << 6)
-
-#define WINCON3_ALPHA_SEL (1 << 1)
-#define WINCON3_BPPMODE_MASK (0xf << 2)
-#define WINCON3_BPPMODE_SHIFT (2)
-#define WINCON3_BPPMODE_1BPP (0x0 << 2)
-#define WINCON3_BPPMODE_2BPP (0x1 << 2)
-#define WINCON3_BPPMODE_4BPP (0x2 << 2)
-#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2)
-#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2)
-#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2)
-#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2)
-#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2)
-#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2)
-#define WINCON3_BPPMODE_24BPP_888 (0xb << 2)
-#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2)
-#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2)
-#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2)
-
-#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
-
-#define DITHMODE (0x170)
-#define WINxMAP(_win) (0x180 + ((_win) * 4))
-
-
-#define DITHMODE_R_POS_MASK (0x3 << 5)
-#define DITHMODE_R_POS_SHIFT (5)
-#define DITHMODE_R_POS_8BIT (0x0 << 5)
-#define DITHMODE_R_POS_6BIT (0x1 << 5)
-#define DITHMODE_R_POS_5BIT (0x2 << 5)
-
-#define DITHMODE_G_POS_MASK (0x3 << 3)
-#define DITHMODE_G_POS_SHIFT (3)
-#define DITHMODE_G_POS_8BIT (0x0 << 3)
-#define DITHMODE_G_POS_6BIT (0x1 << 3)
-#define DITHMODE_G_POS_5BIT (0x2 << 3)
-
-#define DITHMODE_B_POS_MASK (0x3 << 1)
-#define DITHMODE_B_POS_SHIFT (1)
-#define DITHMODE_B_POS_8BIT (0x0 << 1)
-#define DITHMODE_B_POS_6BIT (0x1 << 1)
-#define DITHMODE_B_POS_5BIT (0x2 << 1)
-
-#define DITHMODE_DITH_EN (1 << 0)
-
-#define WPALCON (0x1A0)
-
-/* Palette control */
-/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
- * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
-#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
-#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
-#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
-
-
-/* system specific implementation code for palette sizes, and other
- * information that changes depending on which architecture is being
- * compiled.
-*/
-
-/* return true if window _win has OSD register D */
-#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
-
-static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
-{
- if (win < 2)
- return 256;
- if (win < 4)
- return 16;
- if (win == 4)
- return 4;
-
- BUG(); /* shouldn't get here */
-}
-
-static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
-{
- /* all windows can do 1/2 bpp */
-
- if ((bpp == 25 || bpp == 19) && win == 0)
- return 0; /* win 0 does not have 19 or 25bpp modes */
-
- if (bpp == 4 && win == 4)
- return 0;
-
- if (bpp == 8 && (win >= 3))
- return 0; /* win 3/4 cannot do 8bpp in any mode */
-
- return 1;
-}
-
-static inline int s3c_fb_pal_is16(unsigned int window)
-{
- return window > 1;
-}
-
-struct s3c_fb_palette {
- struct fb_bitfield r;
- struct fb_bitfield g;
- struct fb_bitfield b;
- struct fb_bitfield a;
-};
-
-static inline void s3c_fb_init_palette(unsigned int window,
- struct s3c_fb_palette *palette)
-{
- if (window < 2) {
- /* Windows 0/1 are 8/8/8 or A/8/8/8 */
- palette->r.offset = 16;
- palette->r.length = 8;
- palette->g.offset = 8;
- palette->g.length = 8;
- palette->b.offset = 0;
- palette->b.length = 8;
- } else {
- /* currently we assume RGB 5/6/5 */
- palette->r.offset = 11;
- palette->r.length = 5;
- palette->g.offset = 5;
- palette->g.length = 6;
- palette->b.offset = 0;
- palette->b.length = 5;
- }
-}
-
-/* Notes on per-window bpp settings
- *
- * Value Win0 Win1 Win2 Win3 Win 4
- * 0000 1(P) 1(P) 1(P) 1(P) 1(P)
- * 0001 2(P) 2(P) 2(P) 2(P) 2(P)
- * 0010 4(P) 4(P) 4(P) 4(P) -none-
- * 0011 8(P) 8(P) -none- -none- -none-
- * 0100 -none- 8(A232) 8(A232) -none- -none-
- * 0101 16(565) 16(565) 16(565) 16(565) 16(565)
- * 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555)
- * 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555)
- * 1000 18(666) 18(666) 18(666) 18(666) 18(666)
- * 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665)
- * 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666)
- * 1011 24(888) 24(888) 24(888) 24(888) 24(888)
- * 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887)
- * 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888)
- * 1110 -none- -none- -none- -none- -none-
- * 1111 -none- -none- -none- -none- -none-
-*/
diff --git a/arch/arm/plat-s3c/include/plat/regs-fb.h b/arch/arm/plat-s3c/include/plat/regs-fb.h
deleted file mode 100644
index e9ee599d430..00000000000
--- a/arch/arm/plat-s3c/include/plat/regs-fb.h
+++ /dev/null
@@ -1,366 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-fb.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - new-style framebuffer register definitions
- *
- * This is the register set for the new style framebuffer interface
- * found from the S3C2443 onwards into the S3C2416, S3C2450 and the
- * S3C64XX series such as the S3C6400 and S3C6410.
- *
- * The file does not contain the cpu specific items which are based on
- * whichever architecture is selected, it only contains the core of the
- * register set. See <mach/regs-fb.h> to get the specifics.
- *
- * Note, we changed to using regs-fb.h as it avoids any clashes with
- * the original regs-lcd.h so out of the way of regs-lcd.h as well as
- * indicating the newer block is much more than just an LCD interface.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Please do not include this file directly, use <mach/regs-fb.h> to
- * ensure all the localised SoC support is included as necessary.
-*/
-
-/* VIDCON0 */
-
-#define VIDCON0 (0x00)
-#define VIDCON0_INTERLACE (1 << 29)
-#define VIDCON0_VIDOUT_MASK (0x3 << 26)
-#define VIDCON0_VIDOUT_SHIFT (26)
-#define VIDCON0_VIDOUT_RGB (0x0 << 26)
-#define VIDCON0_VIDOUT_TV (0x1 << 26)
-#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26)
-#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26)
-
-#define VIDCON0_L1_DATA_MASK (0x7 << 23)
-#define VIDCON0_L1_DATA_SHIFT (23)
-#define VIDCON0_L1_DATA_16BPP (0x0 << 23)
-#define VIDCON0_L1_DATA_18BPP16 (0x1 << 23)
-#define VIDCON0_L1_DATA_18BPP9 (0x2 << 23)
-#define VIDCON0_L1_DATA_24BPP (0x3 << 23)
-#define VIDCON0_L1_DATA_18BPP (0x4 << 23)
-#define VIDCON0_L1_DATA_16BPP8 (0x5 << 23)
-
-#define VIDCON0_L0_DATA_MASK (0x7 << 20)
-#define VIDCON0_L0_DATA_SHIFT (20)
-#define VIDCON0_L0_DATA_16BPP (0x0 << 20)
-#define VIDCON0_L0_DATA_18BPP16 (0x1 << 20)
-#define VIDCON0_L0_DATA_18BPP9 (0x2 << 20)
-#define VIDCON0_L0_DATA_24BPP (0x3 << 20)
-#define VIDCON0_L0_DATA_18BPP (0x4 << 20)
-#define VIDCON0_L0_DATA_16BPP8 (0x5 << 20)
-
-#define VIDCON0_PNRMODE_MASK (0x3 << 17)
-#define VIDCON0_PNRMODE_SHIFT (17)
-#define VIDCON0_PNRMODE_RGB (0x0 << 17)
-#define VIDCON0_PNRMODE_BGR (0x1 << 17)
-#define VIDCON0_PNRMODE_SERIAL_RGB (0x2 << 17)
-#define VIDCON0_PNRMODE_SERIAL_BGR (0x3 << 17)
-
-#define VIDCON0_CLKVALUP (1 << 16)
-#define VIDCON0_CLKVAL_F_MASK (0xff << 6)
-#define VIDCON0_CLKVAL_F_SHIFT (6)
-#define VIDCON0_CLKVAL_F_LIMIT (0xff)
-#define VIDCON0_CLKVAL_F(_x) ((_x) << 6)
-#define VIDCON0_VLCKFREE (1 << 5)
-#define VIDCON0_CLKDIR (1 << 4)
-
-#define VIDCON0_CLKSEL_MASK (0x3 << 2)
-#define VIDCON0_CLKSEL_SHIFT (2)
-#define VIDCON0_CLKSEL_HCLK (0x0 << 2)
-#define VIDCON0_CLKSEL_LCD (0x1 << 2)
-#define VIDCON0_CLKSEL_27M (0x3 << 2)
-
-#define VIDCON0_ENVID (1 << 1)
-#define VIDCON0_ENVID_F (1 << 0)
-
-#define VIDCON1 (0x04)
-#define VIDCON1_LINECNT_MASK (0x7ff << 16)
-#define VIDCON1_LINECNT_SHIFT (16)
-#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff)
-#define VIDCON1_VSTATUS_MASK (0x3 << 13)
-#define VIDCON1_VSTATUS_SHIFT (13)
-#define VIDCON1_VSTATUS_VSYNC (0x0 << 13)
-#define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13)
-#define VIDCON1_VSTATUS_ACTIVE (0x2 << 13)
-#define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13)
-
-#define VIDCON1_INV_VCLK (1 << 7)
-#define VIDCON1_INV_HSYNC (1 << 6)
-#define VIDCON1_INV_VSYNC (1 << 5)
-#define VIDCON1_INV_VDEN (1 << 4)
-
-/* VIDCON2 */
-
-#define VIDCON2 (0x08)
-#define VIDCON2_EN601 (1 << 23)
-#define VIDCON2_TVFMTSEL_SW (1 << 14)
-
-#define VIDCON2_TVFMTSEL1_MASK (0x3 << 12)
-#define VIDCON2_TVFMTSEL1_SHIFT (12)
-#define VIDCON2_TVFMTSEL1_RGB (0x0 << 12)
-#define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12)
-#define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12)
-
-#define VIDCON2_ORGYCbCr (1 << 8)
-#define VIDCON2_YUVORDCrCb (1 << 7)
-
-/* VIDTCON0 */
-
-#define VIDTCON0_VBPDE_MASK (0xff << 24)
-#define VIDTCON0_VBPDE_SHIFT (24)
-#define VIDTCON0_VBPDE_LIMIT (0xff)
-#define VIDTCON0_VBPDE(_x) ((_x) << 24)
-
-#define VIDTCON0_VBPD_MASK (0xff << 16)
-#define VIDTCON0_VBPD_SHIFT (16)
-#define VIDTCON0_VBPD_LIMIT (0xff)
-#define VIDTCON0_VBPD(_x) ((_x) << 16)
-
-#define VIDTCON0_VFPD_MASK (0xff << 8)
-#define VIDTCON0_VFPD_SHIFT (8)
-#define VIDTCON0_VFPD_LIMIT (0xff)
-#define VIDTCON0_VFPD(_x) ((_x) << 8)
-
-#define VIDTCON0_VSPW_MASK (0xff << 0)
-#define VIDTCON0_VSPW_SHIFT (0)
-#define VIDTCON0_VSPW_LIMIT (0xff)
-#define VIDTCON0_VSPW(_x) ((_x) << 0)
-
-/* VIDTCON1 */
-
-#define VIDTCON1_VFPDE_MASK (0xff << 24)
-#define VIDTCON1_VFPDE_SHIFT (24)
-#define VIDTCON1_VFPDE_LIMIT (0xff)
-#define VIDTCON1_VFPDE(_x) ((_x) << 24)
-
-#define VIDTCON1_HBPD_MASK (0xff << 16)
-#define VIDTCON1_HBPD_SHIFT (16)
-#define VIDTCON1_HBPD_LIMIT (0xff)
-#define VIDTCON1_HBPD(_x) ((_x) << 16)
-
-#define VIDTCON1_HFPD_MASK (0xff << 8)
-#define VIDTCON1_HFPD_SHIFT (8)
-#define VIDTCON1_HFPD_LIMIT (0xff)
-#define VIDTCON1_HFPD(_x) ((_x) << 8)
-
-#define VIDTCON1_HSPW_MASK (0xff << 0)
-#define VIDTCON1_HSPW_SHIFT (0)
-#define VIDTCON1_HSPW_LIMIT (0xff)
-#define VIDTCON1_HSPW(_x) ((_x) << 0)
-
-#define VIDTCON2 (0x18)
-#define VIDTCON2_LINEVAL_MASK (0x7ff << 11)
-#define VIDTCON2_LINEVAL_SHIFT (11)
-#define VIDTCON2_LINEVAL_LIMIT (0x7ff)
-#define VIDTCON2_LINEVAL(_x) ((_x) << 11)
-
-#define VIDTCON2_HOZVAL_MASK (0x7ff << 0)
-#define VIDTCON2_HOZVAL_SHIFT (0)
-#define VIDTCON2_HOZVAL_LIMIT (0x7ff)
-#define VIDTCON2_HOZVAL(_x) ((_x) << 0)
-
-/* WINCONx */
-
-
-#define WINCONx_BITSWP (1 << 18)
-#define WINCONx_BYTSWP (1 << 17)
-#define WINCONx_HAWSWP (1 << 16)
-#define WINCONx_BURSTLEN_MASK (0x3 << 9)
-#define WINCONx_BURSTLEN_SHIFT (9)
-#define WINCONx_BURSTLEN_16WORD (0x0 << 9)
-#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
-#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
-
-#define WINCONx_ENWIN (1 << 0)
-#define WINCON0_BPPMODE_MASK (0xf << 2)
-#define WINCON0_BPPMODE_SHIFT (2)
-#define WINCON0_BPPMODE_1BPP (0x0 << 2)
-#define WINCON0_BPPMODE_2BPP (0x1 << 2)
-#define WINCON0_BPPMODE_4BPP (0x2 << 2)
-#define WINCON0_BPPMODE_8BPP_PALETTE (0x3 << 2)
-#define WINCON0_BPPMODE_16BPP_565 (0x5 << 2)
-#define WINCON0_BPPMODE_16BPP_1555 (0x7 << 2)
-#define WINCON0_BPPMODE_18BPP_666 (0x8 << 2)
-#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
-
-#define WINCON1_BLD_PIX (1 << 6)
-
-#define WINCON1_ALPHA_SEL (1 << 1)
-#define WINCON1_BPPMODE_MASK (0xf << 2)
-#define WINCON1_BPPMODE_SHIFT (2)
-#define WINCON1_BPPMODE_1BPP (0x0 << 2)
-#define WINCON1_BPPMODE_2BPP (0x1 << 2)
-#define WINCON1_BPPMODE_4BPP (0x2 << 2)
-#define WINCON1_BPPMODE_8BPP_PALETTE (0x3 << 2)
-#define WINCON1_BPPMODE_8BPP_1232 (0x4 << 2)
-#define WINCON1_BPPMODE_16BPP_565 (0x5 << 2)
-#define WINCON1_BPPMODE_16BPP_A1555 (0x6 << 2)
-#define WINCON1_BPPMODE_16BPP_I1555 (0x7 << 2)
-#define WINCON1_BPPMODE_18BPP_666 (0x8 << 2)
-#define WINCON1_BPPMODE_18BPP_A1665 (0x9 << 2)
-#define WINCON1_BPPMODE_19BPP_A1666 (0xa << 2)
-#define WINCON1_BPPMODE_24BPP_888 (0xb << 2)
-#define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2)
-#define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2)
-#define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2)
-
-
-#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11)
-#define VIDOSDxA_TOPLEFT_X_SHIFT (11)
-#define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff)
-#define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11)
-
-#define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0)
-#define VIDOSDxA_TOPLEFT_Y_SHIFT (0)
-#define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff)
-#define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0)
-
-#define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11)
-#define VIDOSDxB_BOTRIGHT_X_SHIFT (11)
-#define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff)
-#define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11)
-
-#define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0)
-#define VIDOSDxB_BOTRIGHT_Y_SHIFT (0)
-#define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff)
-#define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0)
-
-/* For VIDOSD[1..4]C */
-#define VIDISD14C_ALPHA0_R(_x) ((_x) << 20)
-#define VIDISD14C_ALPHA0_G_MASK (0xf << 16)
-#define VIDISD14C_ALPHA0_G_SHIFT (16)
-#define VIDISD14C_ALPHA0_G_LIMIT (0xf)
-#define VIDISD14C_ALPHA0_G(_x) ((_x) << 16)
-#define VIDISD14C_ALPHA0_B_MASK (0xf << 12)
-#define VIDISD14C_ALPHA0_B_SHIFT (12)
-#define VIDISD14C_ALPHA0_B_LIMIT (0xf)
-#define VIDISD14C_ALPHA0_B(_x) ((_x) << 12)
-#define VIDISD14C_ALPHA1_R_MASK (0xf << 8)
-#define VIDISD14C_ALPHA1_R_SHIFT (8)
-#define VIDISD14C_ALPHA1_R_LIMIT (0xf)
-#define VIDISD14C_ALPHA1_R(_x) ((_x) << 8)
-#define VIDISD14C_ALPHA1_G_MASK (0xf << 4)
-#define VIDISD14C_ALPHA1_G_SHIFT (4)
-#define VIDISD14C_ALPHA1_G_LIMIT (0xf)
-#define VIDISD14C_ALPHA1_G(_x) ((_x) << 4)
-#define VIDISD14C_ALPHA1_B_MASK (0xf << 0)
-#define VIDISD14C_ALPHA1_B_SHIFT (0)
-#define VIDISD14C_ALPHA1_B_LIMIT (0xf)
-#define VIDISD14C_ALPHA1_B(_x) ((_x) << 0)
-
-/* Video buffer addresses */
-#define VIDW_BUF_START(_buff) (0xA0 + ((_buff) * 8))
-#define VIDW_BUF_START1(_buff) (0xA4 + ((_buff) * 8))
-#define VIDW_BUF_END(_buff) (0xD0 + ((_buff) * 8))
-#define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8))
-#define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4))
-
-#define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13)
-#define VIDW_BUF_SIZE_OFFSET_SHIFT (13)
-#define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff)
-#define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13)
-
-#define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0)
-#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0)
-#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff)
-#define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0)
-
-/* Interrupt controls and status */
-
-#define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20)
-#define VIDINTCON0_FIFOINTERVAL_SHIFT (20)
-#define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f)
-#define VIDINTCON0_FIFOINTERVAL(_x) ((_x) << 20)
-
-#define VIDINTCON0_INT_SYSMAINCON (1 << 19)
-#define VIDINTCON0_INT_SYSSUBCON (1 << 18)
-#define VIDINTCON0_INT_I80IFDONE (1 << 17)
-
-#define VIDINTCON0_FRAMESEL0_MASK (0x3 << 15)
-#define VIDINTCON0_FRAMESEL0_SHIFT (15)
-#define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15)
-#define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15)
-#define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15)
-#define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15)
-
-#define VIDINTCON0_FRAMESEL1 (1 << 14)
-#define VIDINTCON0_FRAMESEL1_NONE (0x0 << 14)
-#define VIDINTCON0_FRAMESEL1_BACKPORCH (0x1 << 14)
-#define VIDINTCON0_FRAMESEL1_VSYNC (0x2 << 14)
-#define VIDINTCON0_FRAMESEL1_FRONTPORCH (0x3 << 14)
-
-#define VIDINTCON0_INT_FRAME (1 << 12)
-#define VIDINTCON0_FIFIOSEL_MASK (0x7f << 5)
-#define VIDINTCON0_FIFIOSEL_SHIFT (5)
-#define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5)
-
-#define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2)
-#define VIDINTCON0_FIFOLEVEL_SHIFT (2)
-#define VIDINTCON0_FIFOLEVEL_TO25PC (0x0 << 2)
-#define VIDINTCON0_FIFOLEVEL_TO50PC (0x1 << 2)
-#define VIDINTCON0_FIFOLEVEL_TO75PC (0x2 << 2)
-#define VIDINTCON0_FIFOLEVEL_EMPTY (0x3 << 2)
-#define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 2)
-
-#define VIDINTCON0_INT_FIFO_MASK (0x3 << 0)
-#define VIDINTCON0_INT_FIFO_SHIFT (0)
-#define VIDINTCON0_INT_ENABLE (1 << 0)
-
-#define VIDINTCON1 (0x134)
-#define VIDINTCON1_INT_I180 (1 << 2)
-#define VIDINTCON1_INT_FRAME (1 << 1)
-#define VIDINTCON1_INT_FIFO (1 << 0)
-
-/* Window colour-key control registers */
-
-#define WxKEYCON0_KEYBL_EN (1 << 26)
-#define WxKEYCON0_KEYEN_F (1 << 25)
-#define WxKEYCON0_DIRCON (1 << 24)
-#define WxKEYCON0_COMPKEY_MASK (0xffffff << 0)
-#define WxKEYCON0_COMPKEY_SHIFT (0)
-#define WxKEYCON0_COMPKEY_LIMIT (0xffffff)
-#define WxKEYCON0_COMPKEY(_x) ((_x) << 0)
-#define WxKEYCON1_COLVAL_MASK (0xffffff << 0)
-#define WxKEYCON1_COLVAL_SHIFT (0)
-#define WxKEYCON1_COLVAL_LIMIT (0xffffff)
-#define WxKEYCON1_COLVAL(_x) ((_x) << 0)
-
-
-/* Window blanking (MAP) */
-
-#define WINxMAP_MAP (1 << 24)
-#define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0)
-#define WINxMAP_MAP_COLOUR_SHIFT (0)
-#define WINxMAP_MAP_COLOUR_LIMIT (0xffffff)
-#define WINxMAP_MAP_COLOUR(_x) ((_x) << 0)
-
-#define WPALCON_PAL_UPDATE (1 << 9)
-#define WPALCON_W1PAL_MASK (0x7 << 3)
-#define WPALCON_W1PAL_SHIFT (3)
-#define WPALCON_W1PAL_25BPP_A888 (0x0 << 3)
-#define WPALCON_W1PAL_24BPP (0x1 << 3)
-#define WPALCON_W1PAL_19BPP_A666 (0x2 << 3)
-#define WPALCON_W1PAL_18BPP_A665 (0x3 << 3)
-#define WPALCON_W1PAL_18BPP (0x4 << 3)
-#define WPALCON_W1PAL_16BPP_A555 (0x5 << 3)
-#define WPALCON_W1PAL_16BPP_565 (0x6 << 3)
-
-#define WPALCON_W0PAL_MASK (0x7 << 0)
-#define WPALCON_W0PAL_SHIFT (0)
-#define WPALCON_W0PAL_25BPP_A888 (0x0 << 0)
-#define WPALCON_W0PAL_24BPP (0x1 << 0)
-#define WPALCON_W0PAL_19BPP_A666 (0x2 << 0)
-#define WPALCON_W0PAL_18BPP_A665 (0x3 << 0)
-#define WPALCON_W0PAL_18BPP (0x4 << 0)
-#define WPALCON_W0PAL_16BPP_A555 (0x5 << 0)
-#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
-
diff --git a/arch/arm/plat-s3c/include/plat/regs-serial.h b/arch/arm/plat-s3c/include/plat/regs-serial.h
deleted file mode 100644
index 85d8904e7f2..00000000000
--- a/arch/arm/plat-s3c/include/plat/regs-serial.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-serial.h
- *
- * From linux/include/asm-arm/hardware/serial_s3c2410.h
- *
- * Internal header file for Samsung S3C2410 serial ports (UART0-2)
- *
- * Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *
- * Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk)
- *
- * Adapted from:
- *
- * Internal header file for MX1ADS serial ports (UART1 & 2)
- *
- * Copyright (C) 2002 Shane Nay (shane@minirl.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
-*/
-
-#ifndef __ASM_ARM_REGS_SERIAL_H
-#define __ASM_ARM_REGS_SERIAL_H
-
-#define S3C24XX_VA_UART0 (S3C_VA_UART)
-#define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 )
-#define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 )
-#define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 )
-
-#define S3C2410_PA_UART0 (S3C24XX_PA_UART)
-#define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 )
-#define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 )
-#define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 )
-
-#define S3C2410_URXH (0x24)
-#define S3C2410_UTXH (0x20)
-#define S3C2410_ULCON (0x00)
-#define S3C2410_UCON (0x04)
-#define S3C2410_UFCON (0x08)
-#define S3C2410_UMCON (0x0C)
-#define S3C2410_UBRDIV (0x28)
-#define S3C2410_UTRSTAT (0x10)
-#define S3C2410_UERSTAT (0x14)
-#define S3C2410_UFSTAT (0x18)
-#define S3C2410_UMSTAT (0x1C)
-
-#define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3))
-
-#define S3C2410_LCON_CS5 (0x0)
-#define S3C2410_LCON_CS6 (0x1)
-#define S3C2410_LCON_CS7 (0x2)
-#define S3C2410_LCON_CS8 (0x3)
-#define S3C2410_LCON_CSMASK (0x3)
-
-#define S3C2410_LCON_PNONE (0x0)
-#define S3C2410_LCON_PEVEN (0x5 << 3)
-#define S3C2410_LCON_PODD (0x4 << 3)
-#define S3C2410_LCON_PMASK (0x7 << 3)
-
-#define S3C2410_LCON_STOPB (1<<2)
-#define S3C2410_LCON_IRM (1<<6)
-
-#define S3C2440_UCON_CLKMASK (3<<10)
-#define S3C2440_UCON_PCLK (0<<10)
-#define S3C2440_UCON_UCLK (1<<10)
-#define S3C2440_UCON_PCLK2 (2<<10)
-#define S3C2440_UCON_FCLK (3<<10)
-#define S3C2443_UCON_EPLL (3<<10)
-
-#define S3C6400_UCON_CLKMASK (3<<10)
-#define S3C6400_UCON_PCLK (0<<10)
-#define S3C6400_UCON_PCLK2 (2<<10)
-#define S3C6400_UCON_UCLK0 (1<<10)
-#define S3C6400_UCON_UCLK1 (3<<10)
-
-#define S3C2440_UCON2_FCLK_EN (1<<15)
-#define S3C2440_UCON0_DIVMASK (15 << 12)
-#define S3C2440_UCON1_DIVMASK (15 << 12)
-#define S3C2440_UCON2_DIVMASK (7 << 12)
-#define S3C2440_UCON_DIVSHIFT (12)
-
-#define S3C2412_UCON_CLKMASK (3<<10)
-#define S3C2412_UCON_UCLK (1<<10)
-#define S3C2412_UCON_USYSCLK (3<<10)
-#define S3C2412_UCON_PCLK (0<<10)
-#define S3C2412_UCON_PCLK2 (2<<10)
-
-#define S3C2410_UCON_UCLK (1<<10)
-#define S3C2410_UCON_SBREAK (1<<4)
-
-#define S3C2410_UCON_TXILEVEL (1<<9)
-#define S3C2410_UCON_RXILEVEL (1<<8)
-#define S3C2410_UCON_TXIRQMODE (1<<2)
-#define S3C2410_UCON_RXIRQMODE (1<<0)
-#define S3C2410_UCON_RXFIFO_TOI (1<<7)
-#define S3C2443_UCON_RXERR_IRQEN (1<<6)
-#define S3C2443_UCON_LOOPBACK (1<<5)
-
-#define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
- S3C2410_UCON_RXILEVEL | \
- S3C2410_UCON_TXIRQMODE | \
- S3C2410_UCON_RXIRQMODE | \
- S3C2410_UCON_RXFIFO_TOI)
-
-#define S3C2410_UFCON_FIFOMODE (1<<0)
-#define S3C2410_UFCON_TXTRIG0 (0<<6)
-#define S3C2410_UFCON_RXTRIG8 (1<<4)
-#define S3C2410_UFCON_RXTRIG12 (2<<4)
-
-/* S3C2440 FIFO trigger levels */
-#define S3C2440_UFCON_RXTRIG1 (0<<4)
-#define S3C2440_UFCON_RXTRIG8 (1<<4)
-#define S3C2440_UFCON_RXTRIG16 (2<<4)
-#define S3C2440_UFCON_RXTRIG32 (3<<4)
-
-#define S3C2440_UFCON_TXTRIG0 (0<<6)
-#define S3C2440_UFCON_TXTRIG16 (1<<6)
-#define S3C2440_UFCON_TXTRIG32 (2<<6)
-#define S3C2440_UFCON_TXTRIG48 (3<<6)
-
-#define S3C2410_UFCON_RESETBOTH (3<<1)
-#define S3C2410_UFCON_RESETTX (1<<2)
-#define S3C2410_UFCON_RESETRX (1<<1)
-
-#define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
- S3C2410_UFCON_TXTRIG0 | \
- S3C2410_UFCON_RXTRIG8 )
-
-#define S3C2410_UMCOM_AFC (1<<4)
-#define S3C2410_UMCOM_RTS_LOW (1<<0)
-
-#define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */
-#define S3C2412_UMCON_AFC_56 (1<<5)
-#define S3C2412_UMCON_AFC_48 (2<<5)
-#define S3C2412_UMCON_AFC_40 (3<<5)
-#define S3C2412_UMCON_AFC_32 (4<<5)
-#define S3C2412_UMCON_AFC_24 (5<<5)
-#define S3C2412_UMCON_AFC_16 (6<<5)
-#define S3C2412_UMCON_AFC_8 (7<<5)
-
-#define S3C2410_UFSTAT_TXFULL (1<<9)
-#define S3C2410_UFSTAT_RXFULL (1<<8)
-#define S3C2410_UFSTAT_TXMASK (15<<4)
-#define S3C2410_UFSTAT_TXSHIFT (4)
-#define S3C2410_UFSTAT_RXMASK (15<<0)
-#define S3C2410_UFSTAT_RXSHIFT (0)
-
-/* UFSTAT S3C24A0 */
-#define S3C24A0_UFSTAT_TXFULL (1 << 14)
-#define S3C24A0_UFSTAT_RXFULL (1 << 6)
-#define S3C24A0_UFSTAT_TXMASK (63 << 8)
-#define S3C24A0_UFSTAT_TXSHIFT (8)
-#define S3C24A0_UFSTAT_RXMASK (63)
-#define S3C24A0_UFSTAT_RXSHIFT (0)
-
-/* UFSTAT S3C2443 same as S3C2440 */
-#define S3C2440_UFSTAT_TXFULL (1<<14)
-#define S3C2440_UFSTAT_RXFULL (1<<6)
-#define S3C2440_UFSTAT_TXSHIFT (8)
-#define S3C2440_UFSTAT_RXSHIFT (0)
-#define S3C2440_UFSTAT_TXMASK (63<<8)
-#define S3C2440_UFSTAT_RXMASK (63)
-
-#define S3C2410_UTRSTAT_TXE (1<<2)
-#define S3C2410_UTRSTAT_TXFE (1<<1)
-#define S3C2410_UTRSTAT_RXDR (1<<0)
-
-#define S3C2410_UERSTAT_OVERRUN (1<<0)
-#define S3C2410_UERSTAT_FRAME (1<<2)
-#define S3C2410_UERSTAT_BREAK (1<<3)
-#define S3C2443_UERSTAT_PARITY (1<<1)
-
-#define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \
- S3C2410_UERSTAT_FRAME | \
- S3C2410_UERSTAT_BREAK)
-
-#define S3C2410_UMSTAT_CTS (1<<0)
-#define S3C2410_UMSTAT_DeltaCTS (1<<2)
-
-#define S3C2443_DIVSLOT (0x2C)
-
-/* S3C64XX interrupt registers. */
-#define S3C64XX_UINTP 0x30
-#define S3C64XX_UINTSP 0x34
-#define S3C64XX_UINTM 0x38
-
-#ifndef __ASSEMBLY__
-
-/* struct s3c24xx_uart_clksrc
- *
- * this structure defines a named clock source that can be used for the
- * uart, so that the best clock can be selected for the requested baud
- * rate.
- *
- * min_baud and max_baud define the range of baud-rates this clock is
- * acceptable for, if they are both zero, it is assumed any baud rate that
- * can be generated from this clock will be used.
- *
- * divisor gives the divisor from the clock to the one seen by the uart
-*/
-
-struct s3c24xx_uart_clksrc {
- const char *name;
- unsigned int divisor;
- unsigned int min_baud;
- unsigned int max_baud;
-};
-
-/* configuration structure for per-machine configurations for the
- * serial port
- *
- * the pointer is setup by the machine specific initialisation from the
- * arch/arm/mach-s3c2410/ directory.
-*/
-
-struct s3c2410_uartcfg {
- unsigned char hwport; /* hardware port number */
- unsigned char unused;
- unsigned short flags;
- upf_t uart_flags; /* default uart flags */
-
- unsigned long ucon; /* value of ucon for port */
- unsigned long ulcon; /* value of ulcon for port */
- unsigned long ufcon; /* value of ufcon for port */
-
- struct s3c24xx_uart_clksrc *clocks;
- unsigned int clocks_size;
-};
-
-/* s3c24xx_uart_devs
- *
- * this is exported from the core as we cannot use driver_register(),
- * or platform_add_device() before the console_initcall()
-*/
-
-extern struct platform_device *s3c24xx_uart_devs[4];
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASM_ARM_REGS_SERIAL_H */
-
diff --git a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h
deleted file mode 100644
index 36a85f5000c..00000000000
--- a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - USB2.0 Highspeed/OtG device PHY registers
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Note, this is a seperate header file as some of the clock framework
- * needs to touch this if the clk_48m is used as the USB OHCI or other
- * peripheral source.
-*/
-
-#ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H
-#define __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H __FILE__
-
-/* S3C64XX_PA_USB_HSPHY */
-
-#define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY)
-
-#define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00)
-#define SRC_PHYPWR_OTG_DISABLE (1 << 4)
-#define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3)
-#define SRC_PHYPWR_FORCE_SUSPEND (1 << 1)
-
-#define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04)
-#define S3C_PHYCLK_MODE_USB11 (1 << 6)
-#define S3C_PHYCLK_EXT_OSC (1 << 5)
-#define S3C_PHYCLK_CLK_FORCE (1 << 4)
-#define S3C_PHYCLK_ID_PULL (1 << 2)
-#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
-#define S3C_PHYCLK_CLKSEL_SHIFT (0)
-#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
-#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
-#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
-
-#define S3C_RSTCON S3C_HSOTG_PHYREG(0x08)
-#define S3C_RSTCON_PHYCLK (1 << 2)
-#define S3C_RSTCON_HCLK (1 << 2)
-#define S3C_RSTCON_PHY (1 << 0)
-
-#define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20)
-
-#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H */
diff --git a/arch/arm/plat-s3c/include/plat/sdhci.h b/arch/arm/plat-s3c/include/plat/sdhci.h
deleted file mode 100644
index 53198673b6b..00000000000
--- a/arch/arm/plat-s3c/include/plat/sdhci.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/sdhci.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Platform - SDHCI (HSMMC) platform data definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_S3C_SDHCI_H
-#define __PLAT_S3C_SDHCI_H __FILE__
-
-struct platform_device;
-struct mmc_host;
-struct mmc_card;
-struct mmc_ios;
-
-/**
- * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
- * @max_width: The maximum number of data bits supported.
- * @host_caps: Standard MMC host capabilities bit field.
- * @cfg_gpio: Configure the GPIO for a specific card bit-width
- * @cfg_card: Configure the interface for a specific card and speed. This
- * is necessary the controllers and/or GPIO blocks require the
- * changing of driver-strength and other controls dependant on
- * the card and speed of operation.
- *
- * Initialisation data specific to either the machine or the platform
- * for the device driver to use or call-back when configuring gpio or
- * card speed information.
-*/
-struct s3c_sdhci_platdata {
- unsigned int max_width;
- unsigned int host_caps;
-
- char **clocks; /* set of clock sources */
-
- void (*cfg_gpio)(struct platform_device *dev, int width);
- void (*cfg_card)(struct platform_device *dev,
- void __iomem *regbase,
- struct mmc_ios *ios,
- struct mmc_card *card);
-};
-
-/**
- * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
- * @pd: Platform data to register to device.
- *
- * Register the given platform data for use withe S3C SDHCI device.
- * The call will copy the platform data, so the board definitions can
- * make the structure itself __initdata.
- */
-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);
-
-/* Default platform data, exported so that per-cpu initialisation can
- * set the correct one when there are more than one cpu type selected.
-*/
-
-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;
-
-/* Helper function availablity */
-
-extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
-extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
-extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
-extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
-extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
-extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
-
-/* S3C6400 SDHCI setup */
-
-#ifdef CONFIG_S3C6400_SETUP_SDHCI
-extern char *s3c6400_hsmmc_clksrcs[4];
-
-#ifdef CONFIG_S3C_DEV_HSMMC
-extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
- void __iomem *r,
- struct mmc_ios *ios,
- struct mmc_card *card);
-
-static inline void s3c6400_default_sdhci0(void)
-{
- s3c_hsmmc0_def_platdata.clocks = s3c6400_hsmmc_clksrcs;
- s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
- s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
-}
-
-#else
-static inline void s3c6400_default_sdhci0(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC */
-
-#ifdef CONFIG_S3C_DEV_HSMMC1
-static inline void s3c6400_default_sdhci1(void)
-{
- s3c_hsmmc1_def_platdata.clocks = s3c6400_hsmmc_clksrcs;
- s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
- s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
-}
-#else
-static inline void s3c6400_default_sdhci1(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC1 */
-
-#ifdef CONFIG_S3C_DEV_HSMMC2
-static inline void s3c6400_default_sdhci2(void)
-{
- s3c_hsmmc2_def_platdata.clocks = s3c6400_hsmmc_clksrcs;
- s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
- s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
-}
-#else
-static inline void s3c6400_default_sdhci2(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC2 */
-
-#else
-static inline void s3c6400_default_sdhci0(void) { }
-static inline void s3c6400_default_sdhci1(void) { }
-#endif /* CONFIG_S3C6400_SETUP_SDHCI */
-
-/* S3C6410 SDHCI setup */
-
-#ifdef CONFIG_S3C6410_SETUP_SDHCI
-extern char *s3c6410_hsmmc_clksrcs[4];
-
-extern void s3c6410_setup_sdhci0_cfg_card(struct platform_device *dev,
- void __iomem *r,
- struct mmc_ios *ios,
- struct mmc_card *card);
-
-#ifdef CONFIG_S3C_DEV_HSMMC
-static inline void s3c6410_default_sdhci0(void)
-{
- s3c_hsmmc0_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
- s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
- s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s3c6410_default_sdhci0(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC */
-
-#ifdef CONFIG_S3C_DEV_HSMMC1
-static inline void s3c6410_default_sdhci1(void)
-{
- s3c_hsmmc1_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
- s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
- s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s3c6410_default_sdhci1(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC1 */
-
-#ifdef CONFIG_S3C_DEV_HSMMC2
-static inline void s3c6410_default_sdhci2(void)
-{
- s3c_hsmmc2_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
- s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
- s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s3c6410_default_sdhci2(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC2 */
-
-#else
-static inline void s3c6410_default_sdhci0(void) { }
-static inline void s3c6410_default_sdhci1(void) { }
-#endif /* CONFIG_S3C6410_SETUP_SDHCI */
-
-/* S5PC100 SDHCI setup */
-
-#ifdef CONFIG_S5PC100_SETUP_SDHCI
-extern char *s5pc100_hsmmc_clksrcs[4];
-
-extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
- void __iomem *r,
- struct mmc_ios *ios,
- struct mmc_card *card);
-
-#ifdef CONFIG_S3C_DEV_HSMMC
-static inline void s5pc100_default_sdhci0(void)
-{
- s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
- s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
- s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s5pc100_default_sdhci0(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC */
-
-#ifdef CONFIG_S3C_DEV_HSMMC1
-static inline void s5pc100_default_sdhci1(void)
-{
- s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
- s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
- s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s5pc100_default_sdhci1(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC1 */
-
-#ifdef CONFIG_S3C_DEV_HSMMC2
-static inline void s5pc100_default_sdhci2(void)
-{
- s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
- s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
- s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
-}
-#else
-static inline void s5pc100_default_sdhci2(void) { }
-#endif /* CONFIG_S3C_DEV_HSMMC1 */
-
-
-#else
-static inline void s5pc100_default_sdhci0(void) { }
-static inline void s5pc100_default_sdhci1(void) { }
-static inline void s5pc100_default_sdhci2(void) { }
-#endif /* CONFIG_S5PC100_SETUP_SDHCI */
-
-#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-s3c/include/plat/udc-hs.h b/arch/arm/plat-s3c/include/plat/udc-hs.h
deleted file mode 100644
index dd04db04310..00000000000
--- a/arch/arm/plat-s3c/include/plat/udc-hs.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/udc-hs.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C USB2.0 High-speed / OtG platform information
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-enum s3c_hostg_dmamode {
- S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */
- S3C_HSOTG_DMA_ONLY, /* always use DMA */
- S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */
-};
-
-/**
- * struct s3c_hsotg_plat - platform data for high-speed otg/udc
- * @dma: Whether to use DMA or not.
- * @is_osc: The clock source is an oscillator, not a crystal
- */
-struct s3c_hsotg_plat {
- enum s3c_hostg_dmamode dma;
- unsigned int is_osc : 1;
-};
diff --git a/arch/arm/plat-s3c/include/plat/uncompress.h b/arch/arm/plat-s3c/include/plat/uncompress.h
deleted file mode 100644
index dc66a477f62..00000000000
--- a/arch/arm/plat-s3c/include/plat/uncompress.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* linux/include/asm-arm/plat-s3c/uncompress.h
- *
- * Copyright 2003, 2007 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_UNCOMPRESS_H
-#define __ASM_PLAT_UNCOMPRESS_H
-
-typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
-
-/* uart setup */
-
-static unsigned int fifo_mask;
-static unsigned int fifo_max;
-
-/* forward declerations */
-
-static void arch_detect_cpu(void);
-
-/* defines for UART registers */
-
-#include <plat/regs-serial.h>
-#include <plat/regs-watchdog.h>
-
-/* working in physical space... */
-#undef S3C2410_WDOGREG
-#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
-
-/* how many bytes we allow into the FIFO at a time in FIFO mode */
-#define FIFO_MAX (14)
-
-#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
-
-static __inline__ void
-uart_wr(unsigned int reg, unsigned int val)
-{
- volatile unsigned int *ptr;
-
- ptr = (volatile unsigned int *)(reg + uart_base);
- *ptr = val;
-}
-
-static __inline__ unsigned int
-uart_rd(unsigned int reg)
-{
- volatile unsigned int *ptr;
-
- ptr = (volatile unsigned int *)(reg + uart_base);
- return *ptr;
-}
-
-/* we can deal with the case the UARTs are being run
- * in FIFO mode, so that we don't hold up our execution
- * waiting for tx to happen...
-*/
-
-static void putc(int ch)
-{
- if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
- int level;
-
- while (1) {
- level = uart_rd(S3C2410_UFSTAT);
- level &= fifo_mask;
-
- if (level < fifo_max)
- break;
- }
-
- } else {
- /* not using fifos */
-
- while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
- barrier();
- }
-
- /* write byte to transmission register */
- uart_wr(S3C2410_UTXH, ch);
-}
-
-static inline void flush(void)
-{
-}
-
-#define __raw_writel(d, ad) \
- do { \
- *((volatile unsigned int __force *)(ad)) = (d); \
- } while (0)
-
-/* CONFIG_S3C_BOOT_WATCHDOG
- *
- * Simple boot-time watchdog setup, to reboot the system if there is
- * any problem with the boot process
-*/
-
-#ifdef CONFIG_S3C_BOOT_WATCHDOG
-
-#define WDOG_COUNT (0xff00)
-
-static inline void arch_decomp_wdog(void)
-{
- __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
-}
-
-static void arch_decomp_wdog_start(void)
-{
- __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
- __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
- __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
-}
-
-#else
-#define arch_decomp_wdog_start()
-#define arch_decomp_wdog()
-#endif
-
-#ifdef CONFIG_S3C_BOOT_ERROR_RESET
-
-static void arch_decomp_error(const char *x)
-{
- putstr("\n\n");
- putstr(x);
- putstr("\n\n -- System resetting\n");
-
- __raw_writel(0x4000, S3C2410_WTDAT);
- __raw_writel(0x4000, S3C2410_WTCNT);
- __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
-
- while(1);
-}
-
-#define arch_error arch_decomp_error
-#endif
-
-static void error(char *err);
-
-#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
-static inline void arch_enable_uart_fifo(void)
-{
- u32 fifocon = uart_rd(S3C2410_UFCON);
-
- if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
- fifocon |= S3C2410_UFCON_RESETBOTH;
- uart_wr(S3C2410_UFCON, fifocon);
-
- /* wait for fifo reset to complete */
- while (1) {
- fifocon = uart_rd(S3C2410_UFCON);
- if (!(fifocon & S3C2410_UFCON_RESETBOTH))
- break;
- }
- }
-}
-#else
-#define arch_enable_uart_fifo() do { } while(0)
-#endif
-
-
-static void
-arch_decomp_setup(void)
-{
- /* we may need to setup the uart(s) here if we are not running
- * on an BAST... the BAST will have left the uarts configured
- * after calling linux.
- */
-
- arch_detect_cpu();
- arch_decomp_wdog_start();
-
- /* Enable the UART FIFOs if they where not enabled and our
- * configuration says we should turn them on.
- */
-
- arch_enable_uart_fifo();
-}
-
-
-#endif /* __ASM_PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/plat-s3c/include/plat/usb-control.h b/arch/arm/plat-s3c/include/plat/usb-control.h
deleted file mode 100644
index 822c87fe948..00000000000
--- a/arch/arm/plat-s3c/include/plat/usb-control.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/usb-control.h
- *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - USB host port information
- *
- * This program is free software; you can 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_USBCONTROL_H
-#define __ASM_ARCH_USBCONTROL_H
-
-#define S3C_HCDFLG_USED (1)
-
-struct s3c2410_hcd_port {
- unsigned char flags;
- unsigned char power;
- unsigned char oc_status;
- unsigned char oc_changed;
-};
-
-struct s3c2410_hcd_info {
- struct usb_hcd *hcd;
- struct s3c2410_hcd_port port[2];
-
- void (*power_control)(int port, int to);
- void (*enable_oc)(struct s3c2410_hcd_info *, int on);
- void (*report_oc)(struct s3c2410_hcd_info *, int ports);
-};
-
-static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports)
-{
- if (info->report_oc != NULL) {
- (info->report_oc)(info, ports);
- }
-}
-
-#endif /*__ASM_ARCH_USBCONTROL_H */
diff --git a/arch/arm/plat-s3c/pm-check.c b/arch/arm/plat-s3c/pm-check.c
deleted file mode 100644
index 8eb1f439861..00000000000
--- a/arch/arm/plat-s3c/pm-check.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* linux/arch/arm/plat-s3c/pm-check.c
- * originally in linux/arch/arm/plat-s3c24xx/pm.c
- *
- * Copyright (c) 2004-2008 Simtec Electronics
- * http://armlinux.simtec.co.uk
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C Power Mangament - suspend/resume memory corruptiuon check.
- *
- * This program is free software; you can 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/suspend.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-#include <linux/ioport.h>
-
-#include <plat/pm.h>
-
-#if CONFIG_S3C2410_PM_CHECK_CHUNKSIZE < 1
-#error CONFIG_S3C2410_PM_CHECK_CHUNKSIZE must be a positive non-zero value
-#endif
-
-/* suspend checking code...
- *
- * this next area does a set of crc checks over all the installed
- * memory, so the system can verify if the resume was ok.
- *
- * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
- * increasing it will mean that the area corrupted will be less easy to spot,
- * and reducing the size will cause the CRC save area to grow
-*/
-
-#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
-
-static u32 crc_size; /* size needed for the crc block */
-static u32 *crcs; /* allocated over suspend/resume */
-
-typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
-
-/* s3c_pm_run_res
- *
- * go through the given resource list, and look for system ram
-*/
-
-static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
-{
- while (ptr != NULL) {
- if (ptr->child != NULL)
- s3c_pm_run_res(ptr->child, fn, arg);
-
- if ((ptr->flags & IORESOURCE_MEM) &&
- strcmp(ptr->name, "System RAM") == 0) {
- S3C_PMDBG("Found system RAM at %08lx..%08lx\n",
- (unsigned long)ptr->start,
- (unsigned long)ptr->end);
- arg = (fn)(ptr, arg);
- }
-
- ptr = ptr->sibling;
- }
-}
-
-static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg)
-{
- s3c_pm_run_res(&iomem_resource, fn, arg);
-}
-
-static u32 *s3c_pm_countram(struct resource *res, u32 *val)
-{
- u32 size = (u32)(res->end - res->start)+1;
-
- size += CHECK_CHUNKSIZE-1;
- size /= CHECK_CHUNKSIZE;
-
- S3C_PMDBG("Area %08lx..%08lx, %d blocks\n",
- (unsigned long)res->start, (unsigned long)res->end, size);
-
- *val += size * sizeof(u32);
- return val;
-}
-
-/* s3c_pm_prepare_check
- *
- * prepare the necessary information for creating the CRCs. This
- * must be done before the final save, as it will require memory
- * allocating, and thus touching bits of the kernel we do not
- * know about.
-*/
-
-void s3c_pm_check_prepare(void)
-{
- crc_size = 0;
-
- s3c_pm_run_sysram(s3c_pm_countram, &crc_size);
-
- S3C_PMDBG("s3c_pm_prepare_check: %u checks needed\n", crc_size);
-
- crcs = kmalloc(crc_size+4, GFP_KERNEL);
- if (crcs == NULL)
- printk(KERN_ERR "Cannot allocated CRC save area\n");
-}
-
-static u32 *s3c_pm_makecheck(struct resource *res, u32 *val)
-{
- unsigned long addr, left;
-
- for (addr = res->start; addr < res->end;
- addr += CHECK_CHUNKSIZE) {
- left = res->end - addr;
-
- if (left > CHECK_CHUNKSIZE)
- left = CHECK_CHUNKSIZE;
-
- *val = crc32_le(~0, phys_to_virt(addr), left);
- val++;
- }
-
- return val;
-}
-
-/* s3c_pm_check_store
- *
- * compute the CRC values for the memory blocks before the final
- * sleep.
-*/
-
-void s3c_pm_check_store(void)
-{
- if (crcs != NULL)
- s3c_pm_run_sysram(s3c_pm_makecheck, crcs);
-}
-
-/* in_region
- *
- * return TRUE if the area defined by ptr..ptr+size contains the
- * what..what+whatsz
-*/
-
-static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
-{
- if ((what+whatsz) < ptr)
- return 0;
-
- if (what > (ptr+size))
- return 0;
-
- return 1;
-}
-
-/**
- * s3c_pm_runcheck() - helper to check a resource on restore.
- * @res: The resource to check
- * @vak: Pointer to list of CRC32 values to check.
- *
- * Called from the s3c_pm_check_restore() via s3c_pm_run_sysram(), this
- * function runs the given memory resource checking it against the stored
- * CRC to ensure that memory is restored. The function tries to skip as
- * many of the areas used during the suspend process.
- */
-static u32 *s3c_pm_runcheck(struct resource *res, u32 *val)
-{
- void *save_at = phys_to_virt(s3c_sleep_save_phys);
- unsigned long addr;
- unsigned long left;
- void *stkpage;
- void *ptr;
- u32 calc;
-
- stkpage = (void *)((u32)&calc & ~PAGE_MASK);
-
- for (addr = res->start; addr < res->end;
- addr += CHECK_CHUNKSIZE) {
- left = res->end - addr;
-
- if (left > CHECK_CHUNKSIZE)
- left = CHECK_CHUNKSIZE;
-
- ptr = phys_to_virt(addr);
-
- if (in_region(ptr, left, stkpage, 4096)) {
- S3C_PMDBG("skipping %08lx, has stack in\n", addr);
- goto skip_check;
- }
-
- if (in_region(ptr, left, crcs, crc_size)) {
- S3C_PMDBG("skipping %08lx, has crc block in\n", addr);
- goto skip_check;
- }
-
- if (in_region(ptr, left, save_at, 32*4 )) {
- S3C_PMDBG("skipping %08lx, has save block in\n", addr);
- goto skip_check;
- }
-
- /* calculate and check the checksum */
-
- calc = crc32_le(~0, ptr, left);
- if (calc != *val) {
- printk(KERN_ERR "Restore CRC error at "
- "%08lx (%08x vs %08x)\n", addr, calc, *val);
-
- S3C_PMDBG("Restore CRC error at %08lx (%08x vs %08x)\n",
- addr, calc, *val);
- }
-
- skip_check:
- val++;
- }
-
- return val;
-}
-
-/**
- * s3c_pm_check_restore() - memory check called on resume
- *
- * check the CRCs after the restore event and free the memory used
- * to hold them
-*/
-void s3c_pm_check_restore(void)
-{
- if (crcs != NULL)
- s3c_pm_run_sysram(s3c_pm_runcheck, crcs);
-}
-
-/**
- * s3c_pm_check_cleanup() - free memory resources
- *
- * Free the resources that where allocated by the suspend
- * memory check code. We do this separately from the
- * s3c_pm_check_restore() function as we cannot call any
- * functions that might sleep during that resume.
- */
-void s3c_pm_check_cleanup(void)
-{
- kfree(crcs);
- crcs = NULL;
-}
-
diff --git a/arch/arm/plat-s3c/pm-gpio.c b/arch/arm/plat-s3c/pm-gpio.c
deleted file mode 100644
index cfd326a8b69..00000000000
--- a/arch/arm/plat-s3c/pm-gpio.c
+++ /dev/null
@@ -1,380 +0,0 @@
-
-/* linux/arch/arm/plat-s3c/pm-gpio.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C series GPIO PM code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/sysdev.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/gpio-core.h>
-#include <plat/pm.h>
-
-/* PM GPIO helpers */
-
-#define OFFS_CON (0x00)
-#define OFFS_DAT (0x04)
-#define OFFS_UP (0x08)
-
-static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
-{
- chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
- chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
-}
-
-static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
-{
- void __iomem *base = chip->base;
- u32 old_gpcon = __raw_readl(base + OFFS_CON);
- u32 old_gpdat = __raw_readl(base + OFFS_DAT);
- u32 gps_gpcon = chip->pm_save[0];
- u32 gps_gpdat = chip->pm_save[1];
- u32 gpcon;
-
- /* GPACON only has one bit per control / data and no PULLUPs.
- * GPACON[x] = 0 => Output, 1 => SFN */
-
- /* first set all SFN bits to SFN */
-
- gpcon = old_gpcon | gps_gpcon;
- __raw_writel(gpcon, base + OFFS_CON);
-
- /* now set all the other bits */
-
- __raw_writel(gps_gpdat, base + OFFS_DAT);
- __raw_writel(gps_gpcon, base + OFFS_CON);
-
- S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
- chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
-}
-
-struct s3c_gpio_pm s3c_gpio_pm_1bit = {
- .save = s3c_gpio_pm_1bit_save,
- .resume = s3c_gpio_pm_1bit_resume,
-};
-
-static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip)
-{
- chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
- chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
- chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP);
-}
-
-/* Test whether the given masked+shifted bits of an GPIO configuration
- * are one of the SFN (special function) modes. */
-
-static inline int is_sfn(unsigned long con)
-{
- return con >= 2;
-}
-
-/* Test if the given masked+shifted GPIO configuration is an input */
-
-static inline int is_in(unsigned long con)
-{
- return con == 0;
-}
-
-/* Test if the given masked+shifted GPIO configuration is an output */
-
-static inline int is_out(unsigned long con)
-{
- return con == 1;
-}
-
-/**
- * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank
- * @chip: The chip information to resume.
- *
- * Restore one of the GPIO banks that was saved during suspend. This is
- * not as simple as once thought, due to the possibility of glitches
- * from the order that the CON and DAT registers are set in.
- *
- * The three states the pin can be are {IN,OUT,SFN} which gives us 9
- * combinations of changes to check. Three of these, if the pin stays
- * in the same configuration can be discounted. This leaves us with
- * the following:
- *
- * { IN => OUT } Change DAT first
- * { IN => SFN } Change CON first
- * { OUT => SFN } Change CON first, so new data will not glitch
- * { OUT => IN } Change CON first, so new data will not glitch
- * { SFN => IN } Change CON first
- * { SFN => OUT } Change DAT first, so new data will not glitch [1]
- *
- * We do not currently deal with the UP registers as these control
- * weak resistors, so a small delay in change should not need to bring
- * these into the calculations.
- *
- * [1] this assumes that writing to a pin DAT whilst in SFN will set the
- * state for when it is next output.
- */
-static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
-{
- void __iomem *base = chip->base;
- u32 old_gpcon = __raw_readl(base + OFFS_CON);
- u32 old_gpdat = __raw_readl(base + OFFS_DAT);
- u32 gps_gpcon = chip->pm_save[0];
- u32 gps_gpdat = chip->pm_save[1];
- u32 gpcon, old, new, mask;
- u32 change_mask = 0x0;
- int nr;
-
- /* restore GPIO pull-up settings */
- __raw_writel(chip->pm_save[2], base + OFFS_UP);
-
- /* Create a change_mask of all the items that need to have
- * their CON value changed before their DAT value, so that
- * we minimise the work between the two settings.
- */
-
- for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
- old = (old_gpcon & mask) >> nr;
- new = (gps_gpcon & mask) >> nr;
-
- /* If there is no change, then skip */
-
- if (old == new)
- continue;
-
- /* If both are special function, then skip */
-
- if (is_sfn(old) && is_sfn(new))
- continue;
-
- /* Change is IN => OUT, do not change now */
-
- if (is_in(old) && is_out(new))
- continue;
-
- /* Change is SFN => OUT, do not change now */
-
- if (is_sfn(old) && is_out(new))
- continue;
-
- /* We should now be at the case of IN=>SFN,
- * OUT=>SFN, OUT=>IN, SFN=>IN. */
-
- change_mask |= mask;
- }
-
-
- /* Write the new CON settings */
-
- gpcon = old_gpcon & ~change_mask;
- gpcon |= gps_gpcon & change_mask;
-
- __raw_writel(gpcon, base + OFFS_CON);
-
- /* Now change any items that require DAT,CON */
-
- __raw_writel(gps_gpdat, base + OFFS_DAT);
- __raw_writel(gps_gpcon, base + OFFS_CON);
-
- S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
- chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
-}
-
-struct s3c_gpio_pm s3c_gpio_pm_2bit = {
- .save = s3c_gpio_pm_2bit_save,
- .resume = s3c_gpio_pm_2bit_resume,
-};
-
-#ifdef CONFIG_ARCH_S3C64XX
-static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
-{
- chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
- chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
- chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
-
- if (chip->chip.ngpio > 8)
- chip->pm_save[0] = __raw_readl(chip->base - 4);
-}
-
-static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
-{
- u32 old, new, mask;
- u32 change_mask = 0x0;
- int nr;
-
- for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
- old = (old_gpcon & mask) >> nr;
- new = (gps_gpcon & mask) >> nr;
-
- /* If there is no change, then skip */
-
- if (old == new)
- continue;
-
- /* If both are special function, then skip */
-
- if (is_sfn(old) && is_sfn(new))
- continue;
-
- /* Change is IN => OUT, do not change now */
-
- if (is_in(old) && is_out(new))
- continue;
-
- /* Change is SFN => OUT, do not change now */
-
- if (is_sfn(old) && is_out(new))
- continue;
-
- /* We should now be at the case of IN=>SFN,
- * OUT=>SFN, OUT=>IN, SFN=>IN. */
-
- change_mask |= mask;
- }
-
- return change_mask;
-}
-
-static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
-{
- void __iomem *con = chip->base + (index * 4);
- u32 old_gpcon = __raw_readl(con);
- u32 gps_gpcon = chip->pm_save[index + 1];
- u32 gpcon, mask;
-
- mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
-
- gpcon = old_gpcon & ~mask;
- gpcon |= gps_gpcon & mask;
-
- __raw_writel(gpcon, con);
-}
-
-static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
-{
- void __iomem *base = chip->base;
- u32 old_gpcon[2];
- u32 old_gpdat = __raw_readl(base + OFFS_DAT);
- u32 gps_gpdat = chip->pm_save[2];
-
- /* First, modify the CON settings */
-
- old_gpcon[0] = 0;
- old_gpcon[1] = __raw_readl(base + OFFS_CON);
-
- s3c_gpio_pm_4bit_con(chip, 0);
- if (chip->chip.ngpio > 8) {
- old_gpcon[0] = __raw_readl(base - 4);
- s3c_gpio_pm_4bit_con(chip, -1);
- }
-
- /* Now change the configurations that require DAT,CON */
-
- __raw_writel(chip->pm_save[2], base + OFFS_DAT);
- __raw_writel(chip->pm_save[1], base + OFFS_CON);
- if (chip->chip.ngpio > 8)
- __raw_writel(chip->pm_save[0], base - 4);
-
- __raw_writel(chip->pm_save[2], base + OFFS_DAT);
- __raw_writel(chip->pm_save[3], base + OFFS_UP);
-
- if (chip->chip.ngpio > 8) {
- S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
- chip->chip.label, old_gpcon[0], old_gpcon[1],
- __raw_readl(base - 4),
- __raw_readl(base + OFFS_CON),
- old_gpdat, gps_gpdat);
- } else
- S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
- chip->chip.label, old_gpcon[1],
- __raw_readl(base + OFFS_CON),
- old_gpdat, gps_gpdat);
-}
-
-struct s3c_gpio_pm s3c_gpio_pm_4bit = {
- .save = s3c_gpio_pm_4bit_save,
- .resume = s3c_gpio_pm_4bit_resume,
-};
-#endif /* CONFIG_ARCH_S3C64XX */
-
-/**
- * s3c_pm_save_gpio() - save gpio chip data for suspend
- * @ourchip: The chip for suspend.
- */
-static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
-{
- struct s3c_gpio_pm *pm = ourchip->pm;
-
- if (pm == NULL || pm->save == NULL)
- S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
- else
- pm->save(ourchip);
-}
-
-/**
- * s3c_pm_save_gpios() - Save the state of the GPIO banks.
- *
- * For all the GPIO banks, save the state of each one ready for going
- * into a suspend mode.
- */
-void s3c_pm_save_gpios(void)
-{
- struct s3c_gpio_chip *ourchip;
- unsigned int gpio_nr;
-
- for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
- ourchip = s3c_gpiolib_getchip(gpio_nr);
- if (!ourchip)
- continue;
-
- s3c_pm_save_gpio(ourchip);
-
- S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
- ourchip->chip.label,
- ourchip->pm_save[0],
- ourchip->pm_save[1],
- ourchip->pm_save[2],
- ourchip->pm_save[3]);
-
- gpio_nr += ourchip->chip.ngpio;
- gpio_nr += CONFIG_S3C_GPIO_SPACE;
- }
-}
-
-/**
- * s3c_pm_resume_gpio() - restore gpio chip data after suspend
- * @ourchip: The suspended chip.
- */
-static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
-{
- struct s3c_gpio_pm *pm = ourchip->pm;
-
- if (pm == NULL || pm->resume == NULL)
- S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
- else
- pm->resume(ourchip);
-}
-
-void s3c_pm_restore_gpios(void)
-{
- struct s3c_gpio_chip *ourchip;
- unsigned int gpio_nr;
-
- for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
- ourchip = s3c_gpiolib_getchip(gpio_nr);
- if (!ourchip)
- continue;
-
- s3c_pm_resume_gpio(ourchip);
-
- gpio_nr += ourchip->chip.ngpio;
- gpio_nr += CONFIG_S3C_GPIO_SPACE;
- }
-}
diff --git a/arch/arm/plat-s3c/pm.c b/arch/arm/plat-s3c/pm.c
deleted file mode 100644
index 767470601e5..00000000000
--- a/arch/arm/plat-s3c/pm.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/* linux/arch/arm/plat-s3c/pm.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2004-2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C common power management (suspend to ram) support.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/suspend.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <asm/cacheflush.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-irq.h>
-#include <asm/irq.h>
-
-#include <plat/pm.h>
-#include <plat/pm-core.h>
-
-/* for external use */
-
-unsigned long s3c_pm_flags;
-
-/* Debug code:
- *
- * This code supports debug output to the low level UARTs for use on
- * resume before the console layer is available.
-*/
-
-#ifdef CONFIG_S3C2410_PM_DEBUG
-extern void printascii(const char *);
-
-void s3c_pm_dbg(const char *fmt, ...)
-{
- va_list va;
- char buff[256];
-
- va_start(va, fmt);
- vsprintf(buff, fmt, va);
- va_end(va);
-
- printascii(buff);
-}
-
-static inline void s3c_pm_debug_init(void)
-{
- /* restart uart clocks so we can use them to output */
- s3c_pm_debug_init_uart();
-}
-
-#else
-#define s3c_pm_debug_init() do { } while(0)
-
-#endif /* CONFIG_S3C2410_PM_DEBUG */
-
-/* Save the UART configurations if we are configured for debug. */
-
-unsigned char pm_uart_udivslot;
-
-#ifdef CONFIG_S3C2410_PM_DEBUG
-
-struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
-
-static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
-{
- void __iomem *regs = S3C_VA_UARTx(uart);
-
- save->ulcon = __raw_readl(regs + S3C2410_ULCON);
- save->ucon = __raw_readl(regs + S3C2410_UCON);
- save->ufcon = __raw_readl(regs + S3C2410_UFCON);
- save->umcon = __raw_readl(regs + S3C2410_UMCON);
- save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
-
- if (pm_uart_udivslot)
- save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
-
- S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
- uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
-}
-
-static void s3c_pm_save_uarts(void)
-{
- struct pm_uart_save *save = uart_save;
- unsigned int uart;
-
- for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
- s3c_pm_save_uart(uart, save);
-}
-
-static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
-{
- void __iomem *regs = S3C_VA_UARTx(uart);
-
- s3c_pm_arch_update_uart(regs, save);
-
- __raw_writel(save->ulcon, regs + S3C2410_ULCON);
- __raw_writel(save->ucon, regs + S3C2410_UCON);
- __raw_writel(save->ufcon, regs + S3C2410_UFCON);
- __raw_writel(save->umcon, regs + S3C2410_UMCON);
- __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
-
- if (pm_uart_udivslot)
- __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
-}
-
-static void s3c_pm_restore_uarts(void)
-{
- struct pm_uart_save *save = uart_save;
- unsigned int uart;
-
- for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
- s3c_pm_restore_uart(uart, save);
-}
-#else
-static void s3c_pm_save_uarts(void) { }
-static void s3c_pm_restore_uarts(void) { }
-#endif
-
-/* The IRQ ext-int code goes here, it is too small to currently bother
- * with its own file. */
-
-unsigned long s3c_irqwake_intmask = 0xffffffffL;
-unsigned long s3c_irqwake_eintmask = 0xffffffffL;
-
-int s3c_irqext_wake(unsigned int irqno, unsigned int state)
-{
- unsigned long bit = 1L << IRQ_EINT_BIT(irqno);
-
- if (!(s3c_irqwake_eintallow & bit))
- return -ENOENT;
-
- printk(KERN_INFO "wake %s for irq %d\n",
- state ? "enabled" : "disabled", irqno);
-
- if (!state)
- s3c_irqwake_eintmask |= bit;
- else
- s3c_irqwake_eintmask &= ~bit;
-
- return 0;
-}
-
-/* helper functions to save and restore register state */
-
-/**
- * s3c_pm_do_save() - save a set of registers for restoration on resume.
- * @ptr: Pointer to an array of registers.
- * @count: Size of the ptr array.
- *
- * Run through the list of registers given, saving their contents in the
- * array for later restoration when we wakeup.
- */
-void s3c_pm_do_save(struct sleep_save *ptr, int count)
-{
- for (; count > 0; count--, ptr++) {
- ptr->val = __raw_readl(ptr->reg);
- S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
- }
-}
-
-/**
- * s3c_pm_do_restore() - restore register values from the save list.
- * @ptr: Pointer to an array of registers.
- * @count: Size of the ptr array.
- *
- * Restore the register values saved from s3c_pm_do_save().
- *
- * Note, we do not use S3C_PMDBG() in here, as the system may not have
- * restore the UARTs state yet
-*/
-
-void s3c_pm_do_restore(struct sleep_save *ptr, int count)
-{
- for (; count > 0; count--, ptr++) {
- printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
- ptr->reg, ptr->val, __raw_readl(ptr->reg));
-
- __raw_writel(ptr->val, ptr->reg);
- }
-}
-
-/**
- * s3c_pm_do_restore_core() - early restore register values from save list.
- *
- * This is similar to s3c_pm_do_restore() except we try and minimise the
- * side effects of the function in case registers that hardware might need
- * to work has been restored.
- *
- * WARNING: Do not put any debug in here that may effect memory or use
- * peripherals, as things may be changing!
-*/
-
-void s3c_pm_do_restore_core(struct sleep_save *ptr, int count)
-{
- for (; count > 0; count--, ptr++)
- __raw_writel(ptr->val, ptr->reg);
-}
-
-/* s3c2410_pm_show_resume_irqs
- *
- * print any IRQs asserted at resume time (ie, we woke from)
-*/
-static void s3c_pm_show_resume_irqs(int start, unsigned long which,
- unsigned long mask)
-{
- int i;
-
- which &= ~mask;
-
- for (i = 0; i <= 31; i++) {
- if (which & (1L<<i)) {
- S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
- }
- }
-}
-
-
-void (*pm_cpu_prep)(void);
-void (*pm_cpu_sleep)(void);
-
-#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
-
-/* s3c_pm_enter
- *
- * central control for sleep/resume process
-*/
-
-static int s3c_pm_enter(suspend_state_t state)
-{
- static unsigned long regs_save[16];
-
- /* ensure the debug is initialised (if enabled) */
-
- s3c_pm_debug_init();
-
- S3C_PMDBG("%s(%d)\n", __func__, state);
-
- if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
- printk(KERN_ERR "%s: error: no cpu sleep function\n", __func__);
- return -EINVAL;
- }
-
- /* check if we have anything to wake-up with... bad things seem
- * to happen if you suspend with no wakeup (system will often
- * require a full power-cycle)
- */
-
- if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
- !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
- printk(KERN_ERR "%s: No wake-up sources!\n", __func__);
- printk(KERN_ERR "%s: Aborting sleep\n", __func__);
- return -EINVAL;
- }
-
- /* store the physical address of the register recovery block */
-
- s3c_sleep_save_phys = virt_to_phys(regs_save);
-
- S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys);
-
- /* save all necessary core registers not covered by the drivers */
-
- s3c_pm_save_gpios();
- s3c_pm_save_uarts();
- s3c_pm_save_core();
-
- /* set the irq configuration for wake */
-
- s3c_pm_configure_extint();
-
- S3C_PMDBG("sleep: irq wakeup masks: %08lx,%08lx\n",
- s3c_irqwake_intmask, s3c_irqwake_eintmask);
-
- s3c_pm_arch_prepare_irqs();
-
- /* call cpu specific preparation */
-
- pm_cpu_prep();
-
- /* flush cache back to ram */
-
- flush_cache_all();
-
- s3c_pm_check_store();
-
- /* send the cpu to sleep... */
-
- s3c_pm_arch_stop_clocks();
-
- /* s3c_cpu_save will also act as our return point from when
- * we resume as it saves its own register state and restores it
- * during the resume. */
-
- s3c_cpu_save(regs_save);
-
- /* restore the cpu state using the kernel's cpu init code. */
-
- cpu_init();
-
- /* restore the system state */
-
- s3c_pm_restore_core();
- s3c_pm_restore_uarts();
- s3c_pm_restore_gpios();
-
- s3c_pm_debug_init();
-
- /* check what irq (if any) restored the system */
-
- s3c_pm_arch_show_resume_irqs();
-
- S3C_PMDBG("%s: post sleep, preparing to return\n", __func__);
-
- /* LEDs should now be 1110 */
- s3c_pm_debug_smdkled(1 << 1, 0);
-
- s3c_pm_check_restore();
-
- /* ok, let's return from sleep */
-
- S3C_PMDBG("S3C PM Resume (post-restore)\n");
- return 0;
-}
-
-/* callback from assembly code */
-void s3c_pm_cb_flushcache(void)
-{
- flush_cache_all();
-}
-
-static int s3c_pm_prepare(void)
-{
- /* prepare check area if configured */
-
- s3c_pm_check_prepare();
- return 0;
-}
-
-static void s3c_pm_finish(void)
-{
- s3c_pm_check_cleanup();
-}
-
-static struct platform_suspend_ops s3c_pm_ops = {
- .enter = s3c_pm_enter,
- .prepare = s3c_pm_prepare,
- .finish = s3c_pm_finish,
- .valid = suspend_valid_only_mem,
-};
-
-/* s3c_pm_init
- *
- * Attach the power management functions. This should be called
- * from the board specific initialisation if the board supports
- * it.
-*/
-
-int __init s3c_pm_init(void)
-{
- printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
-
- suspend_set_ops(&s3c_pm_ops);
- return 0;
-}
diff --git a/arch/arm/plat-s3c/pwm-clock.c b/arch/arm/plat-s3c/pwm-clock.c
deleted file mode 100644
index a318215ab53..00000000000
--- a/arch/arm/plat-s3c/pwm-clock.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
- *
- * Copyright (c) 2007 Simtec Electronics
- * Copyright (c) 2007, 2008 Ben Dooks
- * Ben Dooks <ben-linux@fluff.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.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/log2.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <asm/irq.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-#include <plat/regs-timer.h>
-#include <mach/pwm-clock.h>
-
-/* Each of the timers 0 through 5 go through the following
- * clock tree, with the inputs depending on the timers.
- *
- * pclk ---- [ prescaler 0 ] -+---> timer 0
- * +---> timer 1
- *
- * pclk ---- [ prescaler 1 ] -+---> timer 2
- * +---> timer 3
- * \---> timer 4
- *
- * Which are fed into the timers as so:
- *
- * prescaled 0 ---- [ div 2,4,8,16 ] ---\
- * [mux] -> timer 0
- * tclk 0 ------------------------------/
- *
- * prescaled 0 ---- [ div 2,4,8,16 ] ---\
- * [mux] -> timer 1
- * tclk 0 ------------------------------/
- *
- *
- * prescaled 1 ---- [ div 2,4,8,16 ] ---\
- * [mux] -> timer 2
- * tclk 1 ------------------------------/
- *
- * prescaled 1 ---- [ div 2,4,8,16 ] ---\
- * [mux] -> timer 3
- * tclk 1 ------------------------------/
- *
- * prescaled 1 ---- [ div 2,4,8, 16 ] --\
- * [mux] -> timer 4
- * tclk 1 ------------------------------/
- *
- * Since the mux and the divider are tied together in the
- * same register space, it is impossible to set the parent
- * and the rate at the same time. To avoid this, we add an
- * intermediate 'prescaled-and-divided' clock to select
- * as the parent for the timer input clock called tdiv.
- *
- * prescaled clk --> pwm-tdiv ---\
- * [ mux ] --> timer X
- * tclk -------------------------/
-*/
-
-static struct clk clk_timer_scaler[];
-
-static unsigned long clk_pwm_scaler_get_rate(struct clk *clk)
-{
- unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
-
- if (clk == &clk_timer_scaler[1]) {
- tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
- tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
- } else {
- tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
- }
-
- return clk_get_rate(clk->parent) / (tcfg0 + 1);
-}
-
-static unsigned long clk_pwm_scaler_round_rate(struct clk *clk,
- unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long divisor = parent_rate / rate;
-
- if (divisor > 256)
- divisor = 256;
- else if (divisor < 2)
- divisor = 2;
-
- return parent_rate / divisor;
-}
-
-static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long round = clk_pwm_scaler_round_rate(clk, rate);
- unsigned long tcfg0;
- unsigned long divisor;
- unsigned long flags;
-
- divisor = clk_get_rate(clk->parent) / round;
- divisor--;
-
- local_irq_save(flags);
- tcfg0 = __raw_readl(S3C2410_TCFG0);
-
- if (clk == &clk_timer_scaler[1]) {
- tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
- tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT;
- } else {
- tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
- tcfg0 |= divisor;
- }
-
- __raw_writel(tcfg0, S3C2410_TCFG0);
- local_irq_restore(flags);
-
- return 0;
-}
-
-static struct clk clk_timer_scaler[] = {
- [0] = {
- .name = "pwm-scaler0",
- .id = -1,
- .get_rate = clk_pwm_scaler_get_rate,
- .set_rate = clk_pwm_scaler_set_rate,
- .round_rate = clk_pwm_scaler_round_rate,
- },
- [1] = {
- .name = "pwm-scaler1",
- .id = -1,
- .get_rate = clk_pwm_scaler_get_rate,
- .set_rate = clk_pwm_scaler_set_rate,
- .round_rate = clk_pwm_scaler_round_rate,
- },
-};
-
-static struct clk clk_timer_tclk[] = {
- [0] = {
- .name = "pwm-tclk0",
- .id = -1,
- },
- [1] = {
- .name = "pwm-tclk1",
- .id = -1,
- },
-};
-
-struct pwm_tdiv_clk {
- struct clk clk;
- unsigned int divisor;
-};
-
-static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
-{
- return container_of(clk, struct pwm_tdiv_clk, clk);
-}
-
-static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
-{
- unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
- unsigned int divisor;
-
- tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
- tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
- if (pwm_cfg_src_is_tclk(tcfg1))
- divisor = to_tdiv(clk)->divisor;
- else
- divisor = tcfg_to_divisor(tcfg1);
-
- return clk_get_rate(clk->parent) / divisor;
-}
-
-static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
- unsigned long rate)
-{
- unsigned long parent_rate;
- unsigned long divisor;
-
- parent_rate = clk_get_rate(clk->parent);
- divisor = parent_rate / rate;
-
- if (divisor <= 1 && pwm_tdiv_has_div1())
- divisor = 1;
- else if (divisor <= 2)
- divisor = 2;
- else if (divisor <= 4)
- divisor = 4;
- else if (divisor <= 8)
- divisor = 8;
- else
- divisor = 16;
-
- return parent_rate / divisor;
-}
-
-static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
-{
- return pwm_tdiv_div_bits(divclk->divisor);
-}
-
-static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
-{
- unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
- unsigned long bits = clk_pwm_tdiv_bits(divclk);
- unsigned long flags;
- unsigned long shift = S3C2410_TCFG1_SHIFT(divclk->clk.id);
-
- local_irq_save(flags);
-
- tcfg1 = __raw_readl(S3C2410_TCFG1);
- tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
- tcfg1 |= bits << shift;
- __raw_writel(tcfg1, S3C2410_TCFG1);
-
- local_irq_restore(flags);
-}
-
-static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
-{
- struct pwm_tdiv_clk *divclk = to_tdiv(clk);
- unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long divisor;
-
- tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
- tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
- rate = clk_round_rate(clk, rate);
- divisor = parent_rate / rate;
-
- if (divisor > 16)
- return -EINVAL;
-
- divclk->divisor = divisor;
-
- /* Update the current MUX settings if we are currently
- * selected as the clock source for this clock. */
-
- if (!pwm_cfg_src_is_tclk(tcfg1))
- clk_pwm_tdiv_update(divclk);
-
- return 0;
-}
-
-static struct pwm_tdiv_clk clk_timer_tdiv[] = {
- [0] = {
- .clk = {
- .name = "pwm-tdiv",
- .parent = &clk_timer_scaler[0],
- .get_rate = clk_pwm_tdiv_get_rate,
- .set_rate = clk_pwm_tdiv_set_rate,
- .round_rate = clk_pwm_tdiv_round_rate,
- },
- },
- [1] = {
- .clk = {
- .name = "pwm-tdiv",
- .parent = &clk_timer_scaler[0],
- .get_rate = clk_pwm_tdiv_get_rate,
- .set_rate = clk_pwm_tdiv_set_rate,
- .round_rate = clk_pwm_tdiv_round_rate,
- }
- },
- [2] = {
- .clk = {
- .name = "pwm-tdiv",
- .parent = &clk_timer_scaler[1],
- .get_rate = clk_pwm_tdiv_get_rate,
- .set_rate = clk_pwm_tdiv_set_rate,
- .round_rate = clk_pwm_tdiv_round_rate,
- },
- },
- [3] = {
- .clk = {
- .name = "pwm-tdiv",
- .parent = &clk_timer_scaler[1],
- .get_rate = clk_pwm_tdiv_get_rate,
- .set_rate = clk_pwm_tdiv_set_rate,
- .round_rate = clk_pwm_tdiv_round_rate,
- },
- },
- [4] = {
- .clk = {
- .name = "pwm-tdiv",
- .parent = &clk_timer_scaler[1],
- .get_rate = clk_pwm_tdiv_get_rate,
- .set_rate = clk_pwm_tdiv_set_rate,
- .round_rate = clk_pwm_tdiv_round_rate,
- },
- },
-};
-
-static int __init clk_pwm_tdiv_register(unsigned int id)
-{
- struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
- unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-
- tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
- tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
- divclk->clk.id = id;
- divclk->divisor = tcfg_to_divisor(tcfg1);
-
- return s3c24xx_register_clock(&divclk->clk);
-}
-
-static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
-{
- return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
-}
-
-static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
-{
- return &clk_timer_tdiv[id].clk;
-}
-
-static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
-{
- unsigned int id = clk->id;
- unsigned long tcfg1;
- unsigned long flags;
- unsigned long bits;
- unsigned long shift = S3C2410_TCFG1_SHIFT(id);
-
- if (parent == s3c24xx_pwmclk_tclk(id))
- bits = S3C_TCFG1_MUX_TCLK << shift;
- else if (parent == s3c24xx_pwmclk_tdiv(id))
- bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
- else
- return -EINVAL;
-
- clk->parent = parent;
-
- local_irq_save(flags);
-
- tcfg1 = __raw_readl(S3C2410_TCFG1);
- tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
- __raw_writel(tcfg1 | bits, S3C2410_TCFG1);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-static struct clk clk_tin[] = {
- [0] = {
- .name = "pwm-tin",
- .id = 0,
- .set_parent = clk_pwm_tin_set_parent,
- },
- [1] = {
- .name = "pwm-tin",
- .id = 1,
- .set_parent = clk_pwm_tin_set_parent,
- },
- [2] = {
- .name = "pwm-tin",
- .id = 2,
- .set_parent = clk_pwm_tin_set_parent,
- },
- [3] = {
- .name = "pwm-tin",
- .id = 3,
- .set_parent = clk_pwm_tin_set_parent,
- },
- [4] = {
- .name = "pwm-tin",
- .id = 4,
- .set_parent = clk_pwm_tin_set_parent,
- },
-};
-
-static __init int clk_pwm_tin_register(struct clk *pwm)
-{
- unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
- unsigned int id = pwm->id;
-
- struct clk *parent;
- int ret;
-
- ret = s3c24xx_register_clock(pwm);
- if (ret < 0)
- return ret;
-
- tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
- tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
- if (pwm_cfg_src_is_tclk(tcfg1))
- parent = s3c24xx_pwmclk_tclk(id);
- else
- parent = s3c24xx_pwmclk_tdiv(id);
-
- return clk_set_parent(pwm, parent);
-}
-
-/**
- * s3c_pwmclk_init() - initialise pwm clocks
- *
- * Initialise and register the clocks which provide the inputs for the
- * pwm timer blocks.
- *
- * Note, this call is required by the time core, so must be called after
- * the base clocks are added and before any of the initcalls are run.
- */
-__init void s3c_pwmclk_init(void)
-{
- struct clk *clk_timers;
- unsigned int clk;
- int ret;
-
- clk_timers = clk_get(NULL, "timers");
- if (IS_ERR(clk_timers)) {
- printk(KERN_ERR "%s: no parent clock\n", __func__);
- return;
- }
-
- for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) {
- clk_timer_scaler[clk].parent = clk_timers;
- ret = s3c24xx_register_clock(&clk_timer_scaler[clk]);
- if (ret < 0) {
- printk(KERN_ERR "error adding pwm scaler%d clock\n", clk);
- return;
- }
- }
-
- for (clk = 0; clk < ARRAY_SIZE(clk_timer_tclk); clk++) {
- ret = s3c24xx_register_clock(&clk_timer_tclk[clk]);
- if (ret < 0) {
- printk(KERN_ERR "error adding pww tclk%d\n", clk);
- return;
- }
- }
-
- for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
- ret = clk_pwm_tdiv_register(clk);
- if (ret < 0) {
- printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
- return;
- }
- }
-
- for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
- ret = clk_pwm_tin_register(&clk_tin[clk]);
- if (ret < 0) {
- printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
- return;
- }
- }
-}
diff --git a/arch/arm/plat-s3c/pwm.c b/arch/arm/plat-s3c/pwm.c
deleted file mode 100644
index ef019f27b67..00000000000
--- a/arch/arm/plat-s3c/pwm.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/* arch/arm/plat-s3c/pwm.c
- *
- * Copyright (c) 2007 Ben Dooks
- * Copyright (c) 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C series PWM device core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-#include <plat/regs-timer.h>
-
-struct pwm_device {
- struct list_head list;
- struct platform_device *pdev;
-
- struct clk *clk_div;
- struct clk *clk;
- const char *label;
-
- unsigned int period_ns;
- unsigned int duty_ns;
-
- unsigned char tcon_base;
- unsigned char running;
- unsigned char use_count;
- unsigned char pwm_id;
-};
-
-#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
-
-static struct clk *clk_scaler[2];
-
-/* Standard setup for a timer block. */
-
-#define TIMER_RESOURCE_SIZE (1)
-
-#define TIMER_RESOURCE(_tmr, _irq) \
- (struct resource [TIMER_RESOURCE_SIZE]) { \
- [0] = { \
- .start = _irq, \
- .end = _irq, \
- .flags = IORESOURCE_IRQ \
- } \
- }
-
-#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
- .name = "s3c24xx-pwm", \
- .id = _tmr_no, \
- .num_resources = TIMER_RESOURCE_SIZE, \
- .resource = TIMER_RESOURCE(_tmr_no, _irq), \
-
-/* since we already have an static mapping for the timer, we do not
- * bother setting any IO resource for the base.
- */
-
-struct platform_device s3c_device_timer[] = {
- [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
- [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
- [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
- [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
- [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
-};
-
-static inline int pwm_is_tdiv(struct pwm_device *pwm)
-{
- return clk_get_parent(pwm->clk) == pwm->clk_div;
-}
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
- int found = 0;
-
- mutex_lock(&pwm_lock);
-
- list_for_each_entry(pwm, &pwm_list, list) {
- if (pwm->pwm_id == pwm_id) {
- found = 1;
- break;
- }
- }
-
- if (found) {
- if (pwm->use_count == 0) {
- pwm->use_count = 1;
- pwm->label = label;
- } else
- pwm = ERR_PTR(-EBUSY);
- } else
- pwm = ERR_PTR(-ENOENT);
-
- mutex_unlock(&pwm_lock);
- return pwm;
-}
-
-EXPORT_SYMBOL(pwm_request);
-
-
-void pwm_free(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
-
- if (pwm->use_count) {
- pwm->use_count--;
- pwm->label = NULL;
- } else
- printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
-
- mutex_unlock(&pwm_lock);
-}
-
-EXPORT_SYMBOL(pwm_free);
-
-#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
-#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
-#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
-#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
-
-int pwm_enable(struct pwm_device *pwm)
-{
- unsigned long flags;
- unsigned long tcon;
-
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
- pwm->running = 1;
- return 0;
-}
-
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
- unsigned long flags;
- unsigned long tcon;
-
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon &= ~pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
- pwm->running = 0;
-}
-
-EXPORT_SYMBOL(pwm_disable);
-
-static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
-{
- unsigned long tin_parent_rate;
- unsigned int div;
-
- tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
- pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
-
- for (div = 2; div <= 16; div *= 2) {
- if ((tin_parent_rate / (div << 16)) < freq)
- return tin_parent_rate / div;
- }
-
- return tin_parent_rate / 16;
-}
-
-#define NS_IN_HZ (1000000000UL)
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- unsigned long tin_rate;
- unsigned long tin_ns;
- unsigned long period;
- unsigned long flags;
- unsigned long tcon;
- unsigned long tcnt;
- long tcmp;
-
- /* We currently avoid using 64bit arithmetic by using the
- * fact that anything faster than 1Hz is easily representable
- * by 32bits. */
-
- if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
- return -ERANGE;
-
- if (duty_ns > period_ns)
- return -EINVAL;
-
- if (period_ns == pwm->period_ns &&
- duty_ns == pwm->duty_ns)
- return 0;
-
- /* The TCMP and TCNT can be read without a lock, they're not
- * shared between the timers. */
-
- tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
- tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
-
- period = NS_IN_HZ / period_ns;
-
- pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
- duty_ns, period_ns, period);
-
- /* Check to see if we are changing the clock rate of the PWM */
-
- if (pwm->period_ns != period_ns) {
- if (pwm_is_tdiv(pwm)) {
- tin_rate = pwm_calc_tin(pwm, period);
- clk_set_rate(pwm->clk_div, tin_rate);
- } else
- tin_rate = clk_get_rate(pwm->clk);
-
- pwm->period_ns = period_ns;
-
- pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
-
- tin_ns = NS_IN_HZ / tin_rate;
- tcnt = period_ns / tin_ns;
- } else
- tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
-
- /* Note, counters count down */
-
- tcmp = duty_ns / tin_ns;
- tcmp = tcnt - tcmp;
- /* the pwm hw only checks the compare register after a decrement,
- so the pin never toggles if tcmp = tcnt */
- if (tcmp == tcnt)
- tcmp--;
-
- pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
-
- if (tcmp < 0)
- tcmp = 0;
-
- /* Update the PWM register block. */
-
- local_irq_save(flags);
-
- __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
- __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_manulupdate(pwm);
- tcon |= pwm_tcon_autoreload(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- tcon &= ~pwm_tcon_manulupdate(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-EXPORT_SYMBOL(pwm_config);
-
-static int pwm_register(struct pwm_device *pwm)
-{
- pwm->duty_ns = -1;
- pwm->period_ns = -1;
-
- mutex_lock(&pwm_lock);
- list_add_tail(&pwm->list, &pwm_list);
- mutex_unlock(&pwm_lock);
-
- return 0;
-}
-
-static int s3c_pwm_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct pwm_device *pwm;
- unsigned long flags;
- unsigned long tcon;
- unsigned int id = pdev->id;
- int ret;
-
- if (id == 4) {
- dev_err(dev, "TIMER4 is currently not supported\n");
- return -ENXIO;
- }
-
- pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (pwm == NULL) {
- dev_err(dev, "failed to allocate pwm_device\n");
- return -ENOMEM;
- }
-
- pwm->pdev = pdev;
- pwm->pwm_id = id;
-
- /* calculate base of control bits in TCON */
- pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
-
- pwm->clk = clk_get(dev, "pwm-tin");
- if (IS_ERR(pwm->clk)) {
- dev_err(dev, "failed to get pwm tin clk\n");
- ret = PTR_ERR(pwm->clk);
- goto err_alloc;
- }
-
- pwm->clk_div = clk_get(dev, "pwm-tdiv");
- if (IS_ERR(pwm->clk_div)) {
- dev_err(dev, "failed to get pwm tdiv clk\n");
- ret = PTR_ERR(pwm->clk_div);
- goto err_clk_tin;
- }
-
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
-
- ret = pwm_register(pwm);
- if (ret) {
- dev_err(dev, "failed to register pwm\n");
- goto err_clk_tdiv;
- }
-
- pwm_dbg(pwm, "config bits %02x\n",
- (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
-
- dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
- clk_get_rate(pwm->clk),
- clk_get_rate(pwm->clk_div),
- pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
-
- platform_set_drvdata(pdev, pwm);
- return 0;
-
- err_clk_tdiv:
- clk_put(pwm->clk_div);
-
- err_clk_tin:
- clk_put(pwm->clk);
-
- err_alloc:
- kfree(pwm);
- return ret;
-}
-
-static int __devexit s3c_pwm_remove(struct platform_device *pdev)
-{
- struct pwm_device *pwm = platform_get_drvdata(pdev);
-
- clk_put(pwm->clk_div);
- clk_put(pwm->clk);
- kfree(pwm);
-
- return 0;
-}
-
-static struct platform_driver s3c_pwm_driver = {
- .driver = {
- .name = "s3c24xx-pwm",
- .owner = THIS_MODULE,
- },
- .probe = s3c_pwm_probe,
- .remove = __devexit_p(s3c_pwm_remove),
-};
-
-static int __init pwm_init(void)
-{
- int ret;
-
- clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
- clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
-
- if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
- printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
- return -EINVAL;
- }
-
- ret = platform_driver_register(&s3c_pwm_driver);
- if (ret)
- printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
-
- return ret;
-}
-
-arch_initcall(pwm_init);
diff --git a/arch/arm/plat-s3c/time.c b/arch/arm/plat-s3c/time.c
deleted file mode 100644
index 3b27b29da47..00000000000
--- a/arch/arm/plat-s3c/time.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/time.c
- *
- * Copyright (C) 2003-2005 Simtec Electronics
- * Ben Dooks, <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-
-#include <asm/system.h>
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#include <asm/irq.h>
-#include <mach/map.h>
-#include <plat/regs-timer.h>
-#include <mach/regs-irq.h>
-#include <asm/mach/time.h>
-#include <mach/tick.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-static unsigned long timer_startval;
-static unsigned long timer_usec_ticks;
-
-#ifndef TICK_MAX
-#define TICK_MAX (0xffff)
-#endif
-
-#define TIMER_USEC_SHIFT 16
-
-/* we use the shifted arithmetic to work out the ratio of timer ticks
- * to usecs, as often the peripheral clock is not a nice even multiple
- * of 1MHz.
- *
- * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
- * for the current HZ value of 200 without producing overflows.
- *
- * Original patch by Dimitry Andric, updated by Ben Dooks
-*/
-
-
-/* timer_mask_usec_ticks
- *
- * given a clock and divisor, make the value to pass into timer_ticks_to_usec
- * to scale the ticks into usecs
-*/
-
-static inline unsigned long
-timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
-{
- unsigned long den = pclk / 1000;
-
- return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
-}
-
-/* timer_ticks_to_usec
- *
- * convert timer ticks to usec.
-*/
-
-static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
-{
- unsigned long res;
-
- res = ticks * timer_usec_ticks;
- res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */
-
- return res >> TIMER_USEC_SHIFT;
-}
-
-/***
- * Returns microsecond since last clock interrupt. Note that interrupts
- * will have been disabled by do_gettimeoffset()
- * IRQs are disabled before entering here from do_gettimeofday()
- */
-
-static unsigned long s3c2410_gettimeoffset (void)
-{
- unsigned long tdone;
- unsigned long tval;
-
- /* work out how many ticks have gone since last timer interrupt */
-
- tval = __raw_readl(S3C2410_TCNTO(4));
- tdone = timer_startval - tval;
-
- /* check to see if there is an interrupt pending */
-
- if (s3c24xx_ostimer_pending()) {
- /* re-read the timer, and try and fix up for the missed
- * interrupt. Note, the interrupt may go off before the
- * timer has re-loaded from wrapping.
- */
-
- tval = __raw_readl(S3C2410_TCNTO(4));
- tdone = timer_startval - tval;
-
- if (tval != 0)
- tdone += timer_startval;
- }
-
- return timer_ticks_to_usec(tdone);
-}
-
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t
-s3c2410_timer_interrupt(int irq, void *dev_id)
-{
- timer_tick();
- return IRQ_HANDLED;
-}
-
-static struct irqaction s3c2410_timer_irq = {
- .name = "S3C2410 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .handler = s3c2410_timer_interrupt,
-};
-
-#define use_tclk1_12() ( \
- machine_is_bast() || \
- machine_is_vr1000() || \
- machine_is_anubis() || \
- machine_is_osiris())
-
-static struct clk *tin;
-static struct clk *tdiv;
-static struct clk *timerclk;
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- *
- * Currently we only use timer4, as it is the only timer which has no
- * other function that can be exploited externally
- */
-static void s3c2410_timer_setup (void)
-{
- unsigned long tcon;
- unsigned long tcnt;
- unsigned long tcfg1;
- unsigned long tcfg0;
-
- tcnt = TICK_MAX; /* default value for tcnt */
-
- /* configure the system for whichever machine is in use */
-
- if (use_tclk1_12()) {
- /* timer is at 12MHz, scaler is 1 */
- timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
- tcnt = 12000000 / HZ;
-
- tcfg1 = __raw_readl(S3C2410_TCFG1);
- tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
- tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
- __raw_writel(tcfg1, S3C2410_TCFG1);
- } else {
- unsigned long pclk;
- struct clk *tscaler;
-
- /* for the h1940 (and others), we use the pclk from the core
- * to generate the timer values. since values around 50 to
- * 70MHz are not values we can directly generate the timer
- * value from, we need to pre-scale and divide before using it.
- *
- * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
- * (8.45 ticks per usec)
- */
-
- pclk = clk_get_rate(timerclk);
-
- /* configure clock tick */
-
- timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
-
- tscaler = clk_get_parent(tdiv);
-
- clk_set_rate(tscaler, pclk / 3);
- clk_set_rate(tdiv, pclk / 6);
- clk_set_parent(tin, tdiv);
-
- tcnt = clk_get_rate(tin) / HZ;
- }
-
- tcon = __raw_readl(S3C2410_TCON);
- tcfg0 = __raw_readl(S3C2410_TCFG0);
- tcfg1 = __raw_readl(S3C2410_TCFG1);
-
- /* timers reload after counting zero, so reduce the count by 1 */
-
- tcnt--;
-
- printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
- tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
-
- /* check to see if timer is within 16bit range... */
- if (tcnt > TICK_MAX) {
- panic("setup_timer: HZ is too small, cannot configure timer!");
- return;
- }
-
- __raw_writel(tcfg1, S3C2410_TCFG1);
- __raw_writel(tcfg0, S3C2410_TCFG0);
-
- timer_startval = tcnt;
- __raw_writel(tcnt, S3C2410_TCNTB(4));
-
- /* ensure timer is stopped... */
-
- tcon &= ~(7<<20);
- tcon |= S3C2410_TCON_T4RELOAD;
- tcon |= S3C2410_TCON_T4MANUALUPD;
-
- __raw_writel(tcon, S3C2410_TCON);
- __raw_writel(tcnt, S3C2410_TCNTB(4));
- __raw_writel(tcnt, S3C2410_TCMPB(4));
-
- /* start the timer running */
- tcon |= S3C2410_TCON_T4START;
- tcon &= ~S3C2410_TCON_T4MANUALUPD;
- __raw_writel(tcon, S3C2410_TCON);
-}
-
-static void __init s3c2410_timer_resources(void)
-{
- struct platform_device tmpdev;
-
- tmpdev.dev.bus = &platform_bus_type;
- tmpdev.id = 4;
-
- timerclk = clk_get(NULL, "timers");
- if (IS_ERR(timerclk))
- panic("failed to get clock for system timer");
-
- clk_enable(timerclk);
-
- if (!use_tclk1_12()) {
- tin = clk_get(&tmpdev.dev, "pwm-tin");
- if (IS_ERR(tin))
- panic("failed to get pwm-tin clock for system timer");
-
- tdiv = clk_get(&tmpdev.dev, "pwm-tdiv");
- if (IS_ERR(tdiv))
- panic("failed to get pwm-tdiv clock for system timer");
- }
-
- clk_enable(tin);
-}
-
-static void __init s3c2410_timer_init(void)
-{
- s3c2410_timer_resources();
- s3c2410_timer_setup();
- setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
-}
-
-struct sys_timer s3c24xx_timer = {
- .init = s3c2410_timer_init,
- .offset = s3c2410_gettimeoffset,
- .resume = s3c2410_timer_setup
-};
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 342647eb91d..6e93ef8f3d4 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -14,58 +14,40 @@ config PLAT_S3C24XX
if PLAT_S3C24XX
-# code that is shared between a number of the s3c24xx implementations
+# low-level serial option nodes
-config S3C2410_CLOCK
+config CPU_LLSERIAL_S3C2410_ONLY
bool
- help
- Clock code for the S3C2410, and similar processors which
- is currently includes the S3C2410, S3C2440, S3C2442.
+ default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440
-config S3C24XX_DCLK
+config CPU_LLSERIAL_S3C2440_ONLY
bool
- help
- Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
+ default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410
-config CPU_S3C244X
+config CPU_LLSERIAL_S3C2410
bool
- depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
- help
- Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
-
-config S3C2440_CPUFREQ
- bool "S3C2440/S3C2442 CPU Frequency scaling support"
- depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
- select S3C2410_CPUFREQ_UTILS
- default y
help
- CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
+ Selected if there is an S3C2410 (or register compatible) serial
+ low-level implementation needed
-config S3C2440_XTAL_12000000
+config CPU_LLSERIAL_S3C2440
bool
help
- Indicate that the build needs to support 12MHz system
- crystal.
+ Selected if there is an S3C2440 (or register compatible) serial
+ low-level implementation needed
-config S3C2440_XTAL_16934400
- bool
- help
- Indicate that the build needs to support 16.9344MHz system
- crystal.
+# code that is shared between a number of the s3c24xx implementations
-config S3C2440_PLL_12000000
+config S3C2410_CLOCK
bool
- depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
- default y if CPU_FREQ_S3C24XX_PLL
help
- PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
+ Clock code for the S3C2410, and similar processors which
+ is currently includes the S3C2410, S3C2440, S3C2442.
-config S3C2440_PLL_16934400
+config S3C24XX_DCLK
bool
- depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
- default y if CPU_FREQ_S3C24XX_PLL
help
- PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
+ Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
config S3C24XX_PWM
bool "PWM device support"
@@ -74,7 +56,6 @@ config S3C24XX_PWM
Support for exporting the PWM timer blocks via the pwm device
system.
-
# gpio configurations
config S3C24XX_GPIO_EXTRA
@@ -117,13 +98,6 @@ config S3C2410_DMA_DEBUG
Enable debugging output for the DMA code. This option sends info
to the kernel log, at priority KERN_DEBUG.
-config S3C24XX_ADC
- bool "ADC common driver support"
- help
- Core support for the ADC block found in the S3C24XX SoC systems
- for drivers such as the touchscreen and hwmon to use to share
- this resource.
-
# SPI default pin configuration code
config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 5dee8c12e8b..c2237c41141 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -25,20 +25,12 @@ obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o
# Architecture dependant builds
-obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
-obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
-obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o
-obj-$(CONFIG_S3C2440_CPUFREQ) += s3c2440-cpufreq.o
-obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o
-obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o
-
obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += irq-pm.o
obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
obj-$(CONFIG_S3C2410_DMA) += dma.o
-obj-$(CONFIG_S3C24XX_ADC) += adc.o
obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o
obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o
diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-s3c24xx/adc.c
deleted file mode 100644
index ce47627f336..00000000000
--- a/arch/arm/plat-s3c24xx/adc.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/* arch/arm/plat-s3c24xx/adc.c
- *
- * Copyright (c) 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C24XX ADC device core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-#include <plat/regs-adc.h>
-#include <plat/adc.h>
-
-/* This driver is designed to control the usage of the ADC block between
- * the touchscreen and any other drivers that may need to use it, such as
- * the hwmon driver.
- *
- * Priority will be given to the touchscreen driver, but as this itself is
- * rate limited it should not starve other requests which are processed in
- * order that they are received.
- *
- * Each user registers to get a client block which uniquely identifies it
- * and stores information such as the necessary functions to callback when
- * action is required.
- */
-
-struct s3c_adc_client {
- struct platform_device *pdev;
- struct list_head pend;
- wait_queue_head_t *wait;
-
- unsigned int nr_samples;
- int result;
- unsigned char is_ts;
- unsigned char channel;
-
- void (*select_cb)(struct s3c_adc_client *c, unsigned selected);
- void (*convert_cb)(struct s3c_adc_client *c,
- unsigned val1, unsigned val2,
- unsigned *samples_left);
-};
-
-struct adc_device {
- struct platform_device *pdev;
- struct platform_device *owner;
- struct clk *clk;
- struct s3c_adc_client *cur;
- struct s3c_adc_client *ts_pend;
- void __iomem *regs;
-
- unsigned int prescale;
-
- int irq;
-};
-
-static struct adc_device *adc_dev;
-
-static LIST_HEAD(adc_pending);
-
-#define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg)
-
-static inline void s3c_adc_convert(struct adc_device *adc)
-{
- unsigned con = readl(adc->regs + S3C2410_ADCCON);
-
- con |= S3C2410_ADCCON_ENABLE_START;
- writel(con, adc->regs + S3C2410_ADCCON);
-}
-
-static inline void s3c_adc_select(struct adc_device *adc,
- struct s3c_adc_client *client)
-{
- unsigned con = readl(adc->regs + S3C2410_ADCCON);
-
- client->select_cb(client, 1);
-
- con &= ~S3C2410_ADCCON_MUXMASK;
- con &= ~S3C2410_ADCCON_STDBM;
- con &= ~S3C2410_ADCCON_STARTMASK;
-
- if (!client->is_ts)
- con |= S3C2410_ADCCON_SELMUX(client->channel);
-
- writel(con, adc->regs + S3C2410_ADCCON);
-}
-
-static void s3c_adc_dbgshow(struct adc_device *adc)
-{
- adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
- readl(adc->regs + S3C2410_ADCCON),
- readl(adc->regs + S3C2410_ADCTSC),
- readl(adc->regs + S3C2410_ADCDLY));
-}
-
-static void s3c_adc_try(struct adc_device *adc)
-{
- struct s3c_adc_client *next = adc->ts_pend;
-
- if (!next && !list_empty(&adc_pending)) {
- next = list_first_entry(&adc_pending,
- struct s3c_adc_client, pend);
- list_del(&next->pend);
- } else
- adc->ts_pend = NULL;
-
- if (next) {
- adc_dbg(adc, "new client is %p\n", next);
- adc->cur = next;
- s3c_adc_select(adc, next);
- s3c_adc_convert(adc);
- s3c_adc_dbgshow(adc);
- }
-}
-
-int s3c_adc_start(struct s3c_adc_client *client,
- unsigned int channel, unsigned int nr_samples)
-{
- struct adc_device *adc = adc_dev;
- unsigned long flags;
-
- if (!adc) {
- printk(KERN_ERR "%s: failed to find adc\n", __func__);
- return -EINVAL;
- }
-
- if (client->is_ts && adc->ts_pend)
- return -EAGAIN;
-
- local_irq_save(flags);
-
- client->channel = channel;
- client->nr_samples = nr_samples;
-
- if (client->is_ts)
- adc->ts_pend = client;
- else
- list_add_tail(&client->pend, &adc_pending);
-
- if (!adc->cur)
- s3c_adc_try(adc);
- local_irq_restore(flags);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(s3c_adc_start);
-
-static void s3c_convert_done(struct s3c_adc_client *client,
- unsigned v, unsigned u, unsigned *left)
-{
- client->result = v;
- wake_up(client->wait);
-}
-
-int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
-{
- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
- int ret;
-
- client->convert_cb = s3c_convert_done;
- client->wait = &wake;
- client->result = -1;
-
- ret = s3c_adc_start(client, ch, 1);
- if (ret < 0)
- goto err;
-
- ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
- if (client->result < 0) {
- ret = -ETIMEDOUT;
- goto err;
- }
-
- client->convert_cb = NULL;
- return client->result;
-
-err:
- return ret;
-}
-EXPORT_SYMBOL_GPL(s3c_adc_read);
-
-static void s3c_adc_default_select(struct s3c_adc_client *client,
- unsigned select)
-{
-}
-
-struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
- void (*select)(struct s3c_adc_client *client,
- unsigned int selected),
- void (*conv)(struct s3c_adc_client *client,
- unsigned d0, unsigned d1,
- unsigned *samples_left),
- unsigned int is_ts)
-{
- struct s3c_adc_client *client;
-
- WARN_ON(!pdev);
-
- if (!select)
- select = s3c_adc_default_select;
-
- if (!pdev)
- return ERR_PTR(-EINVAL);
-
- client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);
- if (!client) {
- dev_err(&pdev->dev, "no memory for adc client\n");
- return ERR_PTR(-ENOMEM);
- }
-
- client->pdev = pdev;
- client->is_ts = is_ts;
- client->select_cb = select;
- client->convert_cb = conv;
-
- return client;
-}
-EXPORT_SYMBOL_GPL(s3c_adc_register);
-
-void s3c_adc_release(struct s3c_adc_client *client)
-{
- /* We should really check that nothing is in progress. */
- if (adc_dev->cur == client)
- adc_dev->cur = NULL;
- if (adc_dev->ts_pend == client)
- adc_dev->ts_pend = NULL;
- else {
- struct list_head *p, *n;
- struct s3c_adc_client *tmp;
-
- list_for_each_safe(p, n, &adc_pending) {
- tmp = list_entry(p, struct s3c_adc_client, pend);
- if (tmp == client)
- list_del(&tmp->pend);
- }
- }
-
- if (adc_dev->cur == NULL)
- s3c_adc_try(adc_dev);
- kfree(client);
-}
-EXPORT_SYMBOL_GPL(s3c_adc_release);
-
-static irqreturn_t s3c_adc_irq(int irq, void *pw)
-{
- struct adc_device *adc = pw;
- struct s3c_adc_client *client = adc->cur;
- unsigned long flags;
- unsigned data0, data1;
-
- if (!client) {
- dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
- return IRQ_HANDLED;
- }
-
- data0 = readl(adc->regs + S3C2410_ADCDAT0);
- data1 = readl(adc->regs + S3C2410_ADCDAT1);
- adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
-
- client->nr_samples--;
-
- if (client->convert_cb)
- (client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff,
- &client->nr_samples);
-
- if (client->nr_samples > 0) {
- /* fire another conversion for this */
-
- client->select_cb(client, 1);
- s3c_adc_convert(adc);
- } else {
- local_irq_save(flags);
- (client->select_cb)(client, 0);
- adc->cur = NULL;
-
- s3c_adc_try(adc);
- local_irq_restore(flags);
- }
-
- return IRQ_HANDLED;
-}
-
-static int s3c_adc_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct adc_device *adc;
- struct resource *regs;
- int ret;
-
- adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
- if (adc == NULL) {
- dev_err(dev, "failed to allocate adc_device\n");
- return -ENOMEM;
- }
-
- adc->pdev = pdev;
- adc->prescale = S3C2410_ADCCON_PRSCVL(49);
-
- adc->irq = platform_get_irq(pdev, 1);
- if (adc->irq <= 0) {
- dev_err(dev, "failed to get adc irq\n");
- ret = -ENOENT;
- goto err_alloc;
- }
-
- ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
- if (ret < 0) {
- dev_err(dev, "failed to attach adc irq\n");
- goto err_alloc;
- }
-
- adc->clk = clk_get(dev, "adc");
- if (IS_ERR(adc->clk)) {
- dev_err(dev, "failed to get adc clock\n");
- ret = PTR_ERR(adc->clk);
- goto err_irq;
- }
-
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
- dev_err(dev, "failed to find registers\n");
- ret = -ENXIO;
- goto err_clk;
- }
-
- adc->regs = ioremap(regs->start, resource_size(regs));
- if (!adc->regs) {
- dev_err(dev, "failed to map registers\n");
- ret = -ENXIO;
- goto err_clk;
- }
-
- clk_enable(adc->clk);
-
- writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
- adc->regs + S3C2410_ADCCON);
-
- dev_info(dev, "attached adc driver\n");
-
- platform_set_drvdata(pdev, adc);
- adc_dev = adc;
-
- return 0;
-
- err_clk:
- clk_put(adc->clk);
-
- err_irq:
- free_irq(adc->irq, adc);
-
- err_alloc:
- kfree(adc);
- return ret;
-}
-
-static int __devexit s3c_adc_remove(struct platform_device *pdev)
-{
- struct adc_device *adc = platform_get_drvdata(pdev);
-
- iounmap(adc->regs);
- free_irq(adc->irq, adc);
- clk_disable(adc->clk);
- clk_put(adc->clk);
- kfree(adc);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct adc_device *adc = platform_get_drvdata(pdev);
- u32 con;
-
- con = readl(adc->regs + S3C2410_ADCCON);
- con |= S3C2410_ADCCON_STDBM;
- writel(con, adc->regs + S3C2410_ADCCON);
-
- clk_disable(adc->clk);
-
- return 0;
-}
-
-static int s3c_adc_resume(struct platform_device *pdev)
-{
- struct adc_device *adc = platform_get_drvdata(pdev);
-
- clk_enable(adc->clk);
-
- writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
- adc->regs + S3C2410_ADCCON);
-
- return 0;
-}
-
-#else
-#define s3c_adc_suspend NULL
-#define s3c_adc_resume NULL
-#endif
-
-static struct platform_driver s3c_adc_driver = {
- .driver = {
- .name = "s3c24xx-adc",
- .owner = THIS_MODULE,
- },
- .probe = s3c_adc_probe,
- .remove = __devexit_p(s3c_adc_remove),
- .suspend = s3c_adc_suspend,
- .resume = s3c_adc_resume,
-};
-
-static int __init adc_init(void)
-{
- int ret;
-
- ret = platform_driver_register(&s3c_adc_driver);
- if (ret)
- printk(KERN_ERR "%s: failed to add adc driver\n", __func__);
-
- return ret;
-}
-
-arch_initcall(adc_init);
diff --git a/arch/arm/plat-s3c24xx/clock-dclk.c b/arch/arm/plat-s3c24xx/clock-dclk.c
index ac061a1bcb3..cf97caafe56 100644
--- a/arch/arm/plat-s3c24xx/clock-dclk.c
+++ b/arch/arm/plat-s3c24xx/clock-dclk.c
@@ -161,14 +161,18 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
/* external clock definitions */
+static struct clk_ops dclk_ops = {
+ .set_parent = s3c24xx_dclk_setparent,
+ .set_rate = s3c24xx_set_dclk_rate,
+ .round_rate = s3c24xx_round_dclk_rate,
+};
+
struct clk s3c24xx_dclk0 = {
.name = "dclk0",
.id = -1,
.ctrlbit = S3C2410_DCLKCON_DCLK0EN,
.enable = s3c24xx_dclk_enable,
- .set_parent = s3c24xx_dclk_setparent,
- .set_rate = s3c24xx_set_dclk_rate,
- .round_rate = s3c24xx_round_dclk_rate,
+ .ops = &dclk_ops,
};
struct clk s3c24xx_dclk1 = {
@@ -176,19 +180,21 @@ struct clk s3c24xx_dclk1 = {
.id = -1,
.ctrlbit = S3C2410_DCLKCON_DCLK1EN,
.enable = s3c24xx_dclk_enable,
- .set_parent = s3c24xx_dclk_setparent,
- .set_rate = s3c24xx_set_dclk_rate,
- .round_rate = s3c24xx_round_dclk_rate,
+ .ops = &dclk_ops,
+};
+
+static struct clk_ops clkout_ops = {
+ .set_parent = s3c24xx_clkout_setparent,
};
struct clk s3c24xx_clkout0 = {
.name = "clkout0",
.id = -1,
- .set_parent = s3c24xx_clkout_setparent,
+ .ops = &clkout_ops,
};
struct clk s3c24xx_clkout1 = {
.name = "clkout1",
.id = -1,
- .set_parent = s3c24xx_clkout_setparent,
+ .ops = &clkout_ops,
};
diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c
index 2d42efb9f4e..1ecc15bfe9d 100644
--- a/arch/arm/plat-s3c24xx/cpu-freq.c
+++ b/arch/arm/plat-s3c24xx/cpu-freq.c
@@ -23,6 +23,7 @@
#include <linux/sysdev.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
+#include <linux/slab.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 4af9dd94879..9ca64df35bf 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -49,9 +49,7 @@
#include <plat/s3c2400.h>
#include <plat/s3c2410.h>
#include <plat/s3c2412.h>
-#include "s3c244x.h"
-#include <plat/s3c2440.h>
-#include <plat/s3c2442.h>
+#include <plat/s3c244x.h>
#include <plat/s3c2443.h>
/* table of supported CPUs */
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 7f686a31e67..9265f09bfa5 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -20,6 +20,7 @@
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -32,6 +33,7 @@
#include <plat/regs-serial.h>
#include <plat/udc.h>
+#include <plat/mci.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -112,34 +114,6 @@ struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
},
};
-/* yart devices */
-
-static struct platform_device s3c24xx_uart_device0 = {
- .id = 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
- .id = 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
- .id = 2,
-};
-
-static struct platform_device s3c24xx_uart_device3 = {
- .id = 3,
-};
-
-struct platform_device *s3c24xx_uart_src[4] = {
- &s3c24xx_uart_device0,
- &s3c24xx_uart_device1,
- &s3c24xx_uart_device2,
- &s3c24xx_uart_device3,
-};
-
-struct platform_device *s3c24xx_uart_devs[4] = {
-};
-
/* LCD Controller */
static struct resource s3c_lcd_resource[] = {
@@ -185,9 +159,27 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
}
/* Touchscreen */
+
+static struct resource s3c_ts_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_ADC,
+ .end = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC,
+ .end = IRQ_TC,
+ .flags = IORESOURCE_IRQ,
+ },
+
+};
+
struct platform_device s3c_device_ts = {
.name = "s3c2410-ts",
.id = -1,
+ .dev.parent = &s3c_device_adc.dev,
+ .num_resources = ARRAY_SIZE(s3c_ts_resource),
+ .resource = s3c_ts_resource,
};
EXPORT_SYMBOL(s3c_device_ts);
@@ -379,6 +371,18 @@ struct platform_device s3c_device_sdi = {
EXPORT_SYMBOL(s3c_device_sdi);
+void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
+{
+ struct s3c24xx_mci_pdata *npd;
+
+ npd = kmemdup(pdata, sizeof(struct s3c24xx_mci_pdata), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory to copy pdata", __func__);
+
+ s3c_device_sdi.dev.platform_data = npd;
+}
+
+
/* SPI (0) */
static struct resource s3c_spi0_resource[] = {
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index f0ea7943ac5..93827b3d4e8 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -33,7 +33,7 @@
#include <mach/dma.h>
#include <mach/map.h>
-#include <plat/dma-plat.h>
+#include <plat/dma-s3c24xx.h>
#include <plat/regs-dma.h>
/* io map for dma */
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index 6d7a961d326..4f0f11a6a67 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -20,7 +20,7 @@
#include <linux/io.h>
#include <linux/gpio.h>
-#include <mach/gpio-core.h>
+#include <plat/gpio-core.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <plat/pm.h>
diff --git a/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h b/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
new file mode 100644
index 00000000000..de5e88fdcb3
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
@@ -0,0 +1,37 @@
+/* arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Simtec Audio support.
+*/
+
+/**
+ * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
+ * @use_mpllin: Select codec clock from MPLLin
+ * @output_cdclk: Need to output CDCLK to the codec
+ * @have_mic: Set if we have a MIC socket
+ * @have_lout: Set if we have a LineOut socket
+ * @amp_gpio: GPIO pin to enable the AMP
+ * @amp_gain: Option GPIO to control AMP gain
+ */
+struct s3c24xx_audio_simtec_pdata {
+ unsigned int use_mpllin:1;
+ unsigned int output_cdclk:1;
+
+ unsigned int have_mic:1;
+ unsigned int have_lout:1;
+
+ int amp_gpio;
+ int amp_gain[2];
+
+ void (*startup)(void);
+};
+
+extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
+ struct s3c24xx_audio_simtec_pdata *pdata);
diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
index 33d421d78ba..d623235ae96 100644
--- a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
+++ b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
@@ -135,7 +135,7 @@ struct s3c_cpufreq_config {
* @locktime_m: The lock-time in uS for the MPLL.
* @locktime_u: The lock-time in uS for the UPLL.
* @locttime_bits: The number of bits each LOCKTIME field.
- * @need_pll: Set if this driver needs to change the PLL values to acheive
+ * @need_pll: Set if this driver needs to change the PLL values to achieve
* any frequency changes. This is really only need by devices like the
* S3C2410 where there is no or limited divider between the PLL and the
* ARMCLK.
diff --git a/arch/arm/plat-s3c24xx/include/plat/dma-plat.h b/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
deleted file mode 100644
index 9565ead1bc9..00000000000
--- a/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
- *
- * Copyright (C) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <plat/dma-core.h>
-
-extern struct sysdev_class dma_sysclass;
-extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
-
-#define DMA_CH_VALID (1<<31)
-#define DMA_CH_NEVER (1<<30)
-
-struct s3c24xx_dma_addr {
- unsigned long from;
- unsigned long to;
-};
-
-/* struct s3c24xx_dma_map
- *
- * this holds the mapping information for the channel selected
- * to be connected to the specified device
-*/
-
-struct s3c24xx_dma_map {
- const char *name;
- struct s3c24xx_dma_addr hw_addr;
-
- unsigned long channels[S3C_DMA_CHANNELS];
- unsigned long channels_rx[S3C_DMA_CHANNELS];
-};
-
-struct s3c24xx_dma_selection {
- struct s3c24xx_dma_map *map;
- unsigned long map_size;
- unsigned long dcon_mask;
-
- void (*select)(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map);
-
- void (*direction)(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map,
- enum s3c2410_dmasrc dir);
-};
-
-extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
-
-/* struct s3c24xx_dma_order_ch
- *
- * channel map for one of the `enum dma_ch` dma channels. the list
- * entry contains a set of low-level channel numbers, orred with
- * DMA_CH_VALID, which are checked in the order in the array.
-*/
-
-struct s3c24xx_dma_order_ch {
- unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */
- unsigned int flags; /* flags */
-};
-
-/* struct s3c24xx_dma_order
- *
- * information provided by either the core or the board to give the
- * dma system a hint on how to allocate channels
-*/
-
-struct s3c24xx_dma_order {
- struct s3c24xx_dma_order_ch channels[DMACH_MAX];
-};
-
-extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
-
-/* DMA init code, called from the cpu support code */
-
-extern int s3c2410_dma_init(void);
-
-extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
- unsigned int stride);
diff --git a/arch/arm/plat-s3c24xx/include/plat/mci.h b/arch/arm/plat-s3c24xx/include/plat/mci.h
index 36aaa10fad0..2ac2b21ec49 100644
--- a/arch/arm/plat-s3c24xx/include/plat/mci.h
+++ b/arch/arm/plat-s3c24xx/include/plat/mci.h
@@ -40,4 +40,13 @@ struct s3c24xx_mci_pdata {
unsigned short vdd);
};
+/**
+ * s3c24xx_mci_set_platdata - set platform data for mmc/sdi device
+ * @pdata: The platform data
+ *
+ * Copy the platform data supplied by @pdata so that this can be marked
+ * __initdata.
+ */
+extern void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata);
+
#endif /* _ARCH_NCI_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/pm-core.h b/arch/arm/plat-s3c24xx/include/plat/pm-core.h
deleted file mode 100644
index fb45dd9adca..00000000000
--- a/arch/arm/plat-s3c24xx/include/plat/pm-core.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/include/plat/pll.h
- *
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-static inline void s3c_pm_debug_init_uart(void)
-{
- unsigned long tmp = __raw_readl(S3C2410_CLKCON);
-
- /* re-start uart clocks */
- tmp |= S3C2410_CLKCON_UART0;
- tmp |= S3C2410_CLKCON_UART1;
- tmp |= S3C2410_CLKCON_UART2;
-
- __raw_writel(tmp, S3C2410_CLKCON);
- udelay(10);
-}
-
-static inline void s3c_pm_arch_prepare_irqs(void)
-{
- __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
- __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
-
- /* ack any outstanding external interrupts before we go to sleep */
-
- __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
- __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
- __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
-
-}
-
-static inline void s3c_pm_arch_stop_clocks(void)
-{
- __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
-}
-
-static void s3c_pm_show_resume_irqs(int start, unsigned long which,
- unsigned long mask);
-
-static inline void s3c_pm_arch_show_resume_irqs(void)
-{
- S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n",
- __raw_readl(S3C2410_SRCPND),
- __raw_readl(S3C2410_EINTPEND));
-
- s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
- s3c_irqwake_intmask);
-
- s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
- s3c_irqwake_eintmask);
-}
-
-static inline void s3c_pm_arch_update_uart(void __iomem *regs,
- struct pm_uart_save *save)
-{
-}
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2440.h b/arch/arm/plat-s3c24xx/include/plat/s3c2440.h
deleted file mode 100644
index 107853bf948..00000000000
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2440.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/s3c2440.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2440 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifdef CONFIG_CPU_S3C2440
-extern int s3c2440_init(void);
-#else
-#define s3c2440_init NULL
-#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2442.h b/arch/arm/plat-s3c24xx/include/plat/s3c2442.h
deleted file mode 100644
index 451a23a2092..00000000000
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2442.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/s3c2442.h
- *
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2442 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifdef CONFIG_CPU_S3C2442
-extern int s3c2442_init(void);
-#else
-#define s3c2442_init NULL
-#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
new file mode 100644
index 00000000000..307248d1ccb
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2440 and S3C2442 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+extern void s3c244x_map_io(void);
+
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c244x_init_clocks(int xtal);
+
+#else
+#define s3c244x_init_clocks NULL
+#define s3c244x_init_uarts NULL
+#define s3c244x_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+extern int s3c2440_init(void);
+#else
+#define s3c2440_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2442
+extern int s3c2442_init(void);
+#else
+#define s3c2442_init NULL
+#endif
diff --git a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
index 963fb0b4379..b1908e56da1 100644
--- a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
+++ b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
@@ -17,6 +17,7 @@
#include <linux/cpufreq.h>
#include <linux/seq_file.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/map.h>
#include <mach/regs-mem.h>
diff --git a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
index 24993dce10b..0b46d3895d6 100644
--- a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
+++ b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
@@ -21,6 +21,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/amba/pl093.h>
diff --git a/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c b/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
deleted file mode 100644
index 49f65032f2c..00000000000
--- a/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
- *
- * Copyright (c) 2006-2007 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- * Vincent Sanders <vince@arm.linux.org.uk>
- *
- * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <plat/cpu.h>
-#include <plat/cpu-freq-core.h>
-
-static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
- { .frequency = 75000000, .index = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */
- { .frequency = 80000000, .index = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */
- { .frequency = 90000000, .index = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */
- { .frequency = 100000000, .index = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */
- { .frequency = 110000000, .index = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */
- { .frequency = 120000000, .index = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */
- { .frequency = 150000000, .index = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */
- { .frequency = 160000000, .index = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */
- { .frequency = 170000000, .index = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */
- { .frequency = 180000000, .index = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */
- { .frequency = 190000000, .index = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */
- { .frequency = 200000000, .index = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */
- { .frequency = 210000000, .index = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */
- { .frequency = 220000000, .index = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */
- { .frequency = 230000000, .index = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */
- { .frequency = 240000000, .index = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */
- { .frequency = 300000000, .index = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */
- { .frequency = 310000000, .index = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */
- { .frequency = 320000000, .index = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */
- { .frequency = 330000000, .index = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */
- { .frequency = 340000000, .index = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */
- { .frequency = 350000000, .index = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */
- { .frequency = 360000000, .index = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */
- { .frequency = 370000000, .index = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */
- { .frequency = 380000000, .index = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */
- { .frequency = 390000000, .index = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */
- { .frequency = 400000000, .index = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */
-};
-
-static int s3c2440_plls12_add(struct sys_device *dev)
-{
- struct clk *xtal_clk;
- unsigned long xtal;
-
- xtal_clk = clk_get(NULL, "xtal");
- if (IS_ERR(xtal_clk))
- return PTR_ERR(xtal_clk);
-
- xtal = clk_get_rate(xtal_clk);
- clk_put(xtal_clk);
-
- if (xtal == 12000000) {
- printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
- return s3c_plltab_register(s3c2440_plls_12,
- ARRAY_SIZE(s3c2440_plls_12));
- }
-
- return 0;
-}
-
-static struct sysdev_driver s3c2440_plls12_drv = {
- .add = s3c2440_plls12_add,
-};
-
-static int __init s3c2440_pll_12mhz(void)
-{
- return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv);
-
-}
-
-arch_initcall(s3c2440_pll_12mhz);
-
-static struct sysdev_driver s3c2442_plls12_drv = {
- .add = s3c2440_plls12_add,
-};
-
-static int __init s3c2442_pll_12mhz(void)
-{
- return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv);
-
-}
-
-arch_initcall(s3c2442_pll_12mhz);
diff --git a/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c b/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
deleted file mode 100644
index 7679af13a94..00000000000
--- a/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
- *
- * Copyright (c) 2006-2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- * Vincent Sanders <vince@arm.linux.org.uk>
- *
- * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <plat/cpu.h>
-#include <plat/cpu-freq-core.h>
-
-static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
- { .frequency = 78019200, .index = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */
- { .frequency = 84067200, .index = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */
- { .frequency = 90115200, .index = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */
- { .frequency = 96163200, .index = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */
- { .frequency = 102135600, .index = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */
- { .frequency = 108259200, .index = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */
- { .frequency = 114307200, .index = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */
- { .frequency = 120234240, .index = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */
- { .frequency = 126161280, .index = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */
- { .frequency = 132088320, .index = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */
- { .frequency = 138015360, .index = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */
- { .frequency = 144789120, .index = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */
- { .frequency = 150100363, .index = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */
- { .frequency = 156038400, .index = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */
- { .frequency = 162086400, .index = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */
- { .frequency = 168134400, .index = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */
- { .frequency = 174048000, .index = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */
- { .frequency = 180230400, .index = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */
- { .frequency = 186278400, .index = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */
- { .frequency = 192326400, .index = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */
- { .frequency = 198132480, .index = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */
- { .frequency = 204271200, .index = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */
- { .frequency = 210268800, .index = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */
- { .frequency = 216518400, .index = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */
- { .frequency = 222264000, .index = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */
- { .frequency = 228614400, .index = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */
- { .frequency = 234259200, .index = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */
- { .frequency = 240468480, .index = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */
- { .frequency = 246960000, .index = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */
- { .frequency = 252322560, .index = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */
- { .frequency = 258249600, .index = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */
- { .frequency = 264176640, .index = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */
- { .frequency = 270950400, .index = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */
- { .frequency = 276030720, .index = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */
- { .frequency = 282240000, .index = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */
- { .frequency = 289578240, .index = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */
- { .frequency = 294235200, .index = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */
- { .frequency = 300200727, .index = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */
- { .frequency = 306358690, .index = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */
- { .frequency = 312076800, .index = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */
- { .frequency = 318366720, .index = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */
- { .frequency = 324172800, .index = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */
- { .frequency = 330220800, .index = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */
- { .frequency = 336268800, .index = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */
- { .frequency = 342074880, .index = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */
- { .frequency = 348096000, .index = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */
- { .frequency = 355622400, .index = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */
- { .frequency = 360460800, .index = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */
- { .frequency = 366206400, .index = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */
- { .frequency = 372556800, .index = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */
- { .frequency = 378201600, .index = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */
- { .frequency = 384652800, .index = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */
- { .frequency = 391608000, .index = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */
- { .frequency = 396264960, .index = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */
- { .frequency = 402192000, .index = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */
-};
-
-static int s3c2440_plls169344_add(struct sys_device *dev)
-{
- struct clk *xtal_clk;
- unsigned long xtal;
-
- xtal_clk = clk_get(NULL, "xtal");
- if (IS_ERR(xtal_clk))
- return PTR_ERR(xtal_clk);
-
- xtal = clk_get_rate(xtal_clk);
- clk_put(xtal_clk);
-
- if (xtal == 169344000) {
- printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
- return s3c_plltab_register(s3c2440_plls_169344,
- ARRAY_SIZE(s3c2440_plls_169344));
- }
-
- return 0;
-}
-
-static struct sysdev_driver s3c2440_plls169344_drv = {
- .add = s3c2440_plls169344_add,
-};
-
-static int __init s3c2440_pll_16934400(void)
-{
- return sysdev_driver_register(&s3c2440_sysclass,
- &s3c2440_plls169344_drv);
-
-}
-
-arch_initcall(s3c2440_pll_16934400);
-
-static struct sysdev_driver s3c2442_plls169344_drv = {
- .add = s3c2440_plls169344_add,
-};
-
-static int __init s3c2442_pll_16934400(void)
-{
- return sysdev_driver_register(&s3c2442_sysclass,
- &s3c2442_plls169344_drv);
-
-}
-
-arch_initcall(s3c2442_pll_16934400);
diff --git a/arch/arm/plat-s3c24xx/s3c244x-clock.c b/arch/arm/plat-s3c24xx/s3c244x-clock.c
deleted file mode 100644
index 79371091aa3..00000000000
--- a/arch/arm/plat-s3c24xx/s3c244x-clock.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
- *
- * Copyright (c) 2004-2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440/S3C2442 Common clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
-{
- unsigned long camdivn;
- unsigned long dvs;
-
- if (parent == &clk_f)
- dvs = 0;
- else if (parent == &clk_h)
- dvs = S3C2440_CAMDIVN_DVSEN;
- else
- return -EINVAL;
-
- clk->parent = parent;
-
- camdivn = __raw_readl(S3C2440_CAMDIVN);
- camdivn &= ~S3C2440_CAMDIVN_DVSEN;
- camdivn |= dvs;
- __raw_writel(camdivn, S3C2440_CAMDIVN);
-
- return 0;
-}
-
-static struct clk clk_arm = {
- .name = "armclk",
- .id = -1,
- .set_parent = s3c2440_setparent_armclk,
-};
-
-static int s3c244x_clk_add(struct sys_device *sysdev)
-{
- unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
- unsigned long clkdivn;
- struct clk *clock_upll;
- int ret;
-
- printk("S3C244X: Clock Support, DVS %s\n",
- (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
-
- clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
-
- ret = s3c24xx_register_clock(&clk_arm);
- if (ret < 0) {
- printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
- return ret;
- }
-
- clock_upll = clk_get(NULL, "upll");
- if (IS_ERR(clock_upll)) {
- printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
- return -ENOENT;
- }
-
- /* check rate of UPLL, and if it is near 96MHz, then change
- * to using half the UPLL rate for the system */
-
- if (clk_get_rate(clock_upll) > (94 * MHZ)) {
- clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
- spin_lock(&clocks_lock);
-
- clkdivn = __raw_readl(S3C2410_CLKDIVN);
- clkdivn |= S3C2440_CLKDIVN_UCLK;
- __raw_writel(clkdivn, S3C2410_CLKDIVN);
-
- spin_unlock(&clocks_lock);
- }
-
- return 0;
-}
-
-static struct sysdev_driver s3c2440_clk_driver = {
- .add = s3c244x_clk_add,
-};
-
-static int s3c2440_clk_init(void)
-{
- return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
-}
-
-arch_initcall(s3c2440_clk_init);
-
-static struct sysdev_driver s3c2442_clk_driver = {
- .add = s3c244x_clk_add,
-};
-
-static int s3c2442_clk_init(void)
-{
- return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
-}
-
-arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
deleted file mode 100644
index 12623a474b5..00000000000
--- a/arch/arm/plat-s3c24xx/s3c244x.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c244x.c
- *
- * Copyright (c) 2004-2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-
-#include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-gpioj.h>
-#include <mach/regs-dsc.h>
-
-#include <plat/s3c2410.h>
-#include <plat/s3c2440.h>
-#include "s3c244x.h"
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/pll.h>
-
-static struct map_desc s3c244x_iodesc[] __initdata = {
- IODESC_ENT(CLKPWR),
- IODESC_ENT(TIMER),
- IODESC_ENT(WATCHDOG),
-};
-
-/* uart initialisation */
-
-void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
- s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
-}
-
-void __init s3c244x_map_io(void)
-{
- /* register our io-tables */
-
- iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
-
- /* rename any peripherals used differing from the s3c2410 */
-
- s3c_device_sdi.name = "s3c2440-sdi";
- s3c_device_i2c0.name = "s3c2440-i2c";
- s3c_device_nand.name = "s3c2440-nand";
- s3c_device_ts.name = "s3c2440-ts";
- s3c_device_usbgadget.name = "s3c2440-usbgadget";
-}
-
-void __init_or_cpufreq s3c244x_setup_clocks(void)
-{
- struct clk *xtal_clk;
- unsigned long clkdiv;
- unsigned long camdiv;
- unsigned long xtal;
- unsigned long hclk, fclk, pclk;
- int hdiv = 1;
-
- xtal_clk = clk_get(NULL, "xtal");
- xtal = clk_get_rate(xtal_clk);
- clk_put(xtal_clk);
-
- fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
-
- clkdiv = __raw_readl(S3C2410_CLKDIVN);
- camdiv = __raw_readl(S3C2440_CAMDIVN);
-
- /* work out clock scalings */
-
- switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
- case S3C2440_CLKDIVN_HDIVN_1:
- hdiv = 1;
- break;
-
- case S3C2440_CLKDIVN_HDIVN_2:
- hdiv = 2;
- break;
-
- case S3C2440_CLKDIVN_HDIVN_4_8:
- hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
- break;
-
- case S3C2440_CLKDIVN_HDIVN_3_6:
- hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
- break;
- }
-
- hclk = fclk / hdiv;
- pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
-
- /* print brief summary of clocks, etc */
-
- printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
- print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
- s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-void __init s3c244x_init_clocks(int xtal)
-{
- /* initialise the clocks here, to allow other things like the
- * console to use them, and to add new ones after the initialisation
- */
-
- s3c24xx_register_baseclocks(xtal);
- s3c244x_setup_clocks();
- s3c2410_baseclk_add();
-}
-
-#ifdef CONFIG_PM
-
-static struct sleep_save s3c244x_sleep[] = {
- SAVE_ITEM(S3C2440_DSC0),
- SAVE_ITEM(S3C2440_DSC1),
- SAVE_ITEM(S3C2440_GPJDAT),
- SAVE_ITEM(S3C2440_GPJCON),
- SAVE_ITEM(S3C2440_GPJUP)
-};
-
-static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
-{
- s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
- return 0;
-}
-
-static int s3c244x_resume(struct sys_device *dev)
-{
- s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
- return 0;
-}
-
-#else
-#define s3c244x_suspend NULL
-#define s3c244x_resume NULL
-#endif
-
-/* Since the S3C2442 and S3C2440 share items, put both sysclasses here */
-
-struct sysdev_class s3c2440_sysclass = {
- .name = "s3c2440-core",
- .suspend = s3c244x_suspend,
- .resume = s3c244x_resume
-};
-
-struct sysdev_class s3c2442_sysclass = {
- .name = "s3c2442-core",
- .suspend = s3c244x_suspend,
- .resume = s3c244x_resume
-};
-
-/* need to register class before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2440 based system)
- * as a driver which may support both 2410 and 2440 may try and use it.
-*/
-
-static int __init s3c2440_core_init(void)
-{
- return sysdev_class_register(&s3c2440_sysclass);
-}
-
-core_initcall(s3c2440_core_init);
-
-static int __init s3c2442_core_init(void)
-{
- return sysdev_class_register(&s3c2442_sysclass);
-}
-
-core_initcall(s3c2442_core_init);
diff --git a/arch/arm/plat-s3c24xx/s3c244x.h b/arch/arm/plat-s3c24xx/s3c244x.h
deleted file mode 100644
index 6aab5eaae2b..00000000000
--- a/arch/arm/plat-s3c24xx/s3c244x.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c244x.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C2440 and S3C2442 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
-
-extern void s3c244x_map_io(void);
-
-extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c244x_init_clocks(int xtal);
-
-#else
-#define s3c244x_init_clocks NULL
-#define s3c244x_init_uarts NULL
-#define s3c244x_map_io NULL
-#endif
diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig
deleted file mode 100644
index e6da87a5885..00000000000
--- a/arch/arm/plat-s3c64xx/Kconfig
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-# Ben Dooks <ben@simtec.co.uk>
-#
-# Licensed under GPLv2
-
-config PLAT_S3C64XX
- bool
- depends on ARCH_S3C64XX
- default y
- select CPU_V6
- select PLAT_S3C
- select ARM_VIC
- select NO_IOPORT
- select ARCH_REQUIRE_GPIOLIB
- select S3C_GPIO_TRACK
- select S3C_GPIO_PULL_UPDOWN
- select S3C_GPIO_CFG_S3C24XX
- select S3C_GPIO_CFG_S3C64XX
- select S3C_DEV_NAND
- select USB_ARCH_HAS_OHCI
- help
- Base platform code for any Samsung S3C64XX device
-
-if PLAT_S3C64XX
-
-# Configuration options shared by all S3C64XX implementations
-
-config CPU_S3C6400_INIT
- bool
- help
- Common initialisation code for the S3C6400 that is shared
- by other CPUs in the series, such as the S3C6410.
-
-config CPU_S3C6400_CLOCK
- bool
- help
- Common clock support code for the S3C6400 that is shared
- by other CPUs in the series, such as the S3C6410.
-
-config S3C64XX_DMA
- bool "S3C64XX DMA"
- select S3C_DMA
-
-# platform specific device setup
-
-config S3C64XX_SETUP_I2C0
- bool
- default y
- help
- Common setup code for i2c bus 0.
-
- Note, currently since i2c0 is always compiled, this setup helper
- is always compiled with it.
-
-config S3C64XX_SETUP_I2C1
- bool
- help
- Common setup code for i2c bus 1.
-
-config S3C64XX_SETUP_FB_24BPP
- bool
- help
- Common setup code for S3C64XX with an 24bpp RGB display helper.
-
-config S3C64XX_SETUP_SDHCI_GPIO
- bool
- help
- Common setup code for S3C64XX SDHCI GPIO configurations
-
-endif
diff --git a/arch/arm/plat-s3c64xx/Makefile b/arch/arm/plat-s3c64xx/Makefile
deleted file mode 100644
index b85b4359e93..00000000000
--- a/arch/arm/plat-s3c64xx/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# arch/arm/plat-s3c64xx/Makefile
-#
-# Copyright 2008 Openmoko, Inc.
-# Copyright 2008 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n := dummy.o
-obj- :=
-
-# Core files
-
-obj-y += dev-uart.o
-obj-y += cpu.o
-obj-y += irq.o
-obj-y += irq-eint.o
-obj-y += clock.o
-obj-y += gpiolib.o
-
-# CPU support
-
-obj-$(CONFIG_CPU_S3C6400_INIT) += s3c6400-init.o
-obj-$(CONFIG_CPU_S3C6400_CLOCK) += s3c6400-clock.o
-obj-$(CONFIG_CPU_FREQ_S3C64XX) += cpufreq.o
-
-# PM support
-
-obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += sleep.o
-obj-$(CONFIG_PM) += irq-pm.o
-
-# DMA support
-
-obj-$(CONFIG_S3C64XX_DMA) += dma.o
-
-# Device setup
-
-obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
-obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
-obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
-obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
-obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o
diff --git a/arch/arm/plat-s3c64xx/clock.c b/arch/arm/plat-s3c64xx/clock.c
deleted file mode 100644
index 7a36e899360..00000000000
--- a/arch/arm/plat-s3c64xx/clock.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/clock.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX Base clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/regs-sys.h>
-#include <plat/regs-clock.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-
-struct clk clk_h2 = {
- .name = "hclk2",
- .id = -1,
- .rate = 0,
-};
-
-struct clk clk_27m = {
- .name = "clk_27m",
- .id = -1,
- .rate = 27000000,
-};
-
-static int clk_48m_ctrl(struct clk *clk, int enable)
-{
- unsigned long flags;
- u32 val;
-
- /* can't rely on clock lock, this register has other usages */
- local_irq_save(flags);
-
- val = __raw_readl(S3C64XX_OTHERS);
- if (enable)
- val |= S3C64XX_OTHERS_USBMASK;
- else
- val &= ~S3C64XX_OTHERS_USBMASK;
-
- __raw_writel(val, S3C64XX_OTHERS);
- local_irq_restore(flags);
-
- return 0;
-}
-
-struct clk clk_48m = {
- .name = "clk_48m",
- .id = -1,
- .rate = 48000000,
- .enable = clk_48m_ctrl,
-};
-
-static int inline s3c64xx_gate(void __iomem *reg,
- struct clk *clk,
- int enable)
-{
- unsigned int ctrlbit = clk->ctrlbit;
- u32 con;
-
- con = __raw_readl(reg);
-
- if (enable)
- con |= ctrlbit;
- else
- con &= ~ctrlbit;
-
- __raw_writel(con, reg);
- return 0;
-}
-
-static int s3c64xx_pclk_ctrl(struct clk *clk, int enable)
-{
- return s3c64xx_gate(S3C_PCLK_GATE, clk, enable);
-}
-
-static int s3c64xx_hclk_ctrl(struct clk *clk, int enable)
-{
- return s3c64xx_gate(S3C_HCLK_GATE, clk, enable);
-}
-
-int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
-{
- return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
-}
-
-static struct clk init_clocks_disable[] = {
- {
- .name = "nand",
- .id = -1,
- .parent = &clk_h,
- }, {
- .name = "adc",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_TSADC,
- }, {
- .name = "i2c",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_IIC,
- }, {
- .name = "iis",
- .id = 0,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_IIS0,
- }, {
- .name = "iis",
- .id = 1,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_IIS1,
- }, {
- .name = "spi",
- .id = 0,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_SPI0,
- }, {
- .name = "spi",
- .id = 1,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_SPI1,
- }, {
- .name = "48m",
- .id = 0,
- .parent = &clk_48m,
- .enable = s3c64xx_sclk_ctrl,
- .ctrlbit = S3C_CLKCON_SCLK_MMC0_48,
- }, {
- .name = "48m",
- .id = 1,
- .parent = &clk_48m,
- .enable = s3c64xx_sclk_ctrl,
- .ctrlbit = S3C_CLKCON_SCLK_MMC1_48,
- }, {
- .name = "48m",
- .id = 2,
- .parent = &clk_48m,
- .enable = s3c64xx_sclk_ctrl,
- .ctrlbit = S3C_CLKCON_SCLK_MMC2_48,
- }, {
- .name = "dma0",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c64xx_hclk_ctrl,
- .ctrlbit = S3C_CLKCON_HCLK_DMA0,
- }, {
- .name = "dma1",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c64xx_hclk_ctrl,
- .ctrlbit = S3C_CLKCON_HCLK_DMA1,
- },
-};
-
-static struct clk init_clocks[] = {
- {
- .name = "lcd",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c64xx_hclk_ctrl,
- .ctrlbit = S3C_CLKCON_HCLK_LCD,
- }, {
- .name = "gpio",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_GPIO,
- }, {
- .name = "usb-host",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c64xx_hclk_ctrl,
- .ctrlbit = S3C_CLKCON_HCLK_UHOST,
- }, {
- .name = "hsmmc",
- .id = 0,
- .parent = &clk_h,
- .enable = s3c64xx_hclk_ctrl,
- .ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
- }, {
- .name = "hsmmc",
- .id = 1,
- .parent = &clk_h,
- .enable = s3c64xx_hclk_ctrl,
- .ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
- }, {
- .name = "hsmmc",
- .id = 2,
- .parent = &clk_h,
- .enable = s3c64xx_hclk_ctrl,
- .ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
- }, {
- .name = "timers",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_PWM,
- }, {
- .name = "uart",
- .id = 0,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_UART0,
- }, {
- .name = "uart",
- .id = 1,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_UART1,
- }, {
- .name = "uart",
- .id = 2,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_UART2,
- }, {
- .name = "uart",
- .id = 3,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_UART3,
- }, {
- .name = "rtc",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c64xx_pclk_ctrl,
- .ctrlbit = S3C_CLKCON_PCLK_RTC,
- }, {
- .name = "watchdog",
- .id = -1,
- .parent = &clk_p,
- .ctrlbit = S3C_CLKCON_PCLK_WDT,
- }, {
- .name = "ac97",
- .id = -1,
- .parent = &clk_p,
- .ctrlbit = S3C_CLKCON_PCLK_AC97,
- }
-};
-
-static struct clk *clks[] __initdata = {
- &clk_ext,
- &clk_epll,
- &clk_27m,
- &clk_48m,
- &clk_h2,
-};
-
-void __init s3c64xx_register_clocks(void)
-{
- struct clk *clkp;
- int ret;
- int ptr;
-
- s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-
- clkp = init_clocks;
- for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
- }
-
- clkp = init_clocks_disable;
- for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
-
- (clkp->enable)(clkp, 0);
- }
-
- s3c_pwmclk_init();
-}
diff --git a/arch/arm/plat-s3c64xx/cpu.c b/arch/arm/plat-s3c64xx/cpu.c
deleted file mode 100644
index 49796d2db86..00000000000
--- a/arch/arm/plat-s3c64xx/cpu.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/cpu.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX CPU Support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <plat/regs-serial.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-
-#include <plat/s3c6400.h>
-#include <plat/s3c6410.h>
-
-/* table of supported CPUs */
-
-static const char name_s3c6400[] = "S3C6400";
-static const char name_s3c6410[] = "S3C6410";
-
-static struct cpu_table cpu_ids[] __initdata = {
- {
- .idcode = 0x36400000,
- .idmask = 0xfffff000,
- .map_io = s3c6400_map_io,
- .init_clocks = s3c6400_init_clocks,
- .init_uarts = s3c6400_init_uarts,
- .init = s3c6400_init,
- .name = name_s3c6400,
- }, {
- .idcode = 0x36410100,
- .idmask = 0xffffff00,
- .map_io = s3c6410_map_io,
- .init_clocks = s3c6410_init_clocks,
- .init_uarts = s3c6410_init_uarts,
- .init = s3c6410_init,
- .name = name_s3c6410,
- },
-};
-
-/* minimal IO mapping */
-
-/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */
-#define UART_OFFS (S3C_PA_UART & 0xfffff)
-
-static struct map_desc s3c_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S3C_VA_SYS,
- .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS),
- .pfn = __phys_to_pfn(S3C_PA_UART),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C_VA_VIC0,
- .pfn = __phys_to_pfn(S3C64XX_PA_VIC0),
- .length = SZ_16K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C_VA_VIC1,
- .pfn = __phys_to_pfn(S3C64XX_PA_VIC1),
- .length = SZ_16K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C_VA_TIMER,
- .pfn = __phys_to_pfn(S3C_PA_TIMER),
- .length = SZ_16K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C64XX_VA_GPIO,
- .pfn = __phys_to_pfn(S3C64XX_PA_GPIO),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C64XX_VA_MODEM,
- .pfn = __phys_to_pfn(S3C64XX_PA_MODEM),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C_VA_WATCHDOG,
- .pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C_VA_USB_HSPHY,
- .pfn = __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
- .length = SZ_1K,
- .type = MT_DEVICE,
- },
-};
-
-
-struct sysdev_class s3c64xx_sysclass = {
- .name = "s3c64xx-core",
-};
-
-static struct sys_device s3c64xx_sysdev = {
- .cls = &s3c64xx_sysclass,
-};
-
-
-/* read cpu identification code */
-
-void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
-{
- unsigned long idcode;
-
- /* initialise the io descriptors we need for initialisation */
- iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
- iotable_init(mach_desc, size);
-
- idcode = __raw_readl(S3C_VA_SYS + 0x118);
- if (!idcode) {
- /* S3C6400 has the ID register in a different place,
- * and needs a write before it can be read. */
-
- __raw_writel(0x0, S3C_VA_SYS + 0xA1C);
- idcode = __raw_readl(S3C_VA_SYS + 0xA1C);
- }
-
- s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
-}
-
-static __init int s3c64xx_sysdev_init(void)
-{
- sysdev_class_register(&s3c64xx_sysclass);
- return sysdev_register(&s3c64xx_sysdev);
-}
-
-core_initcall(s3c64xx_sysdev_init);
diff --git a/arch/arm/plat-s3c64xx/dev-audio.c b/arch/arm/plat-s3c64xx/dev-audio.c
deleted file mode 100644
index a21a88fbb7e..00000000000
--- a/arch/arm/plat-s3c64xx/dev-audio.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-audio.c
- *
- * Copyright 2009 Wolfson Microelectronics
- * Mark Brown <broonie@opensource.wolfsonmicro.com>
- *
-
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-#include <mach/dma.h>
-#include <mach/gpio.h>
-
-#include <plat/devs.h>
-#include <plat/audio.h>
-#include <plat/gpio-bank-d.h>
-#include <plat/gpio-bank-e.h>
-#include <plat/gpio-cfg.h>
-
-static struct resource s3c64xx_iis0_resource[] = {
- [0] = {
- .start = S3C64XX_PA_IIS0,
- .end = S3C64XX_PA_IIS0 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device s3c64xx_device_iis0 = {
- .name = "s3c64xx-iis",
- .id = 0,
- .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
- .resource = s3c64xx_iis0_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iis0);
-
-static struct resource s3c64xx_iis1_resource[] = {
- [0] = {
- .start = S3C64XX_PA_IIS1,
- .end = S3C64XX_PA_IIS1 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device s3c64xx_device_iis1 = {
- .name = "s3c64xx-iis",
- .id = 1,
- .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
- .resource = s3c64xx_iis1_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iis1);
-
-static struct resource s3c64xx_iisv4_resource[] = {
- [0] = {
- .start = S3C64XX_PA_IISV4,
- .end = S3C64XX_PA_IISV4 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-struct platform_device s3c64xx_device_iisv4 = {
- .name = "s3c64xx-iis-v4",
- .id = -1,
- .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
- .resource = s3c64xx_iisv4_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iisv4);
-
-
-/* PCM Controller platform_devices */
-
-static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
-{
- switch (pdev->id) {
- case 0:
- s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK);
- s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
- s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
- s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
- s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
- break;
- case 1:
- s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK);
- s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
- s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
- s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
- s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
- break;
- default:
- printk(KERN_DEBUG "Invalid PCM Controller number!");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct resource s3c64xx_pcm0_resource[] = {
- [0] = {
- .start = S3C64XX_PA_PCM0,
- .end = S3C64XX_PA_PCM0 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_PCM0_TX,
- .end = DMACH_PCM0_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_PCM0_RX,
- .end = DMACH_PCM0_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static struct s3c_audio_pdata s3c_pcm0_pdata = {
- .cfg_gpio = s3c64xx_pcm_cfg_gpio,
-};
-
-struct platform_device s3c64xx_device_pcm0 = {
- .name = "samsung-pcm",
- .id = 0,
- .num_resources = ARRAY_SIZE(s3c64xx_pcm0_resource),
- .resource = s3c64xx_pcm0_resource,
- .dev = {
- .platform_data = &s3c_pcm0_pdata,
- },
-};
-EXPORT_SYMBOL(s3c64xx_device_pcm0);
-
-static struct resource s3c64xx_pcm1_resource[] = {
- [0] = {
- .start = S3C64XX_PA_PCM1,
- .end = S3C64XX_PA_PCM1 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_PCM1_TX,
- .end = DMACH_PCM1_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_PCM1_RX,
- .end = DMACH_PCM1_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static struct s3c_audio_pdata s3c_pcm1_pdata = {
- .cfg_gpio = s3c64xx_pcm_cfg_gpio,
-};
-
-struct platform_device s3c64xx_device_pcm1 = {
- .name = "samsung-pcm",
- .id = 1,
- .num_resources = ARRAY_SIZE(s3c64xx_pcm1_resource),
- .resource = s3c64xx_pcm1_resource,
- .dev = {
- .platform_data = &s3c_pcm1_pdata,
- },
-};
-EXPORT_SYMBOL(s3c64xx_device_pcm1);
diff --git a/arch/arm/plat-s3c64xx/dev-uart.c b/arch/arm/plat-s3c64xx/dev-uart.c
deleted file mode 100644
index 62c11a6fc7b..00000000000
--- a/arch/arm/plat-s3c64xx/dev-uart.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/dev-uart.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * Base S3C64XX UART resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-/* Serial port registrations */
-
-/* 64xx uarts are closer together */
-
-static struct resource s3c64xx_uart0_resource[] = {
- [0] = {
- .start = S3C_PA_UART0,
- .end = S3C_PA_UART0 + 0x100,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX0,
- .end = IRQ_S3CUART_RX0,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = IRQ_S3CUART_TX0,
- .end = IRQ_S3CUART_TX0,
- .flags = IORESOURCE_IRQ,
-
- },
- [3] = {
- .start = IRQ_S3CUART_ERR0,
- .end = IRQ_S3CUART_ERR0,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static struct resource s3c64xx_uart1_resource[] = {
- [0] = {
- .start = S3C_PA_UART1,
- .end = S3C_PA_UART1 + 0x100,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX1,
- .end = IRQ_S3CUART_RX1,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = IRQ_S3CUART_TX1,
- .end = IRQ_S3CUART_TX1,
- .flags = IORESOURCE_IRQ,
-
- },
- [3] = {
- .start = IRQ_S3CUART_ERR1,
- .end = IRQ_S3CUART_ERR1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource s3c6xx_uart2_resource[] = {
- [0] = {
- .start = S3C_PA_UART2,
- .end = S3C_PA_UART2 + 0x100,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX2,
- .end = IRQ_S3CUART_RX2,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = IRQ_S3CUART_TX2,
- .end = IRQ_S3CUART_TX2,
- .flags = IORESOURCE_IRQ,
-
- },
- [3] = {
- .start = IRQ_S3CUART_ERR2,
- .end = IRQ_S3CUART_ERR2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource s3c64xx_uart3_resource[] = {
- [0] = {
- .start = S3C_PA_UART3,
- .end = S3C_PA_UART3 + 0x100,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX3,
- .end = IRQ_S3CUART_RX3,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = IRQ_S3CUART_TX3,
- .end = IRQ_S3CUART_TX3,
- .flags = IORESOURCE_IRQ,
-
- },
- [3] = {
- .start = IRQ_S3CUART_ERR3,
- .end = IRQ_S3CUART_ERR3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-
-struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = {
- [0] = {
- .resources = s3c64xx_uart0_resource,
- .nr_resources = ARRAY_SIZE(s3c64xx_uart0_resource),
- },
- [1] = {
- .resources = s3c64xx_uart1_resource,
- .nr_resources = ARRAY_SIZE(s3c64xx_uart1_resource),
- },
- [2] = {
- .resources = s3c6xx_uart2_resource,
- .nr_resources = ARRAY_SIZE(s3c6xx_uart2_resource),
- },
- [3] = {
- .resources = s3c64xx_uart3_resource,
- .nr_resources = ARRAY_SIZE(s3c64xx_uart3_resource),
- },
-};
-
-/* uart devices */
-
-static struct platform_device s3c24xx_uart_device0 = {
- .id = 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
- .id = 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
- .id = 2,
-};
-
-static struct platform_device s3c24xx_uart_device3 = {
- .id = 3,
-};
-
-struct platform_device *s3c24xx_uart_src[4] = {
- &s3c24xx_uart_device0,
- &s3c24xx_uart_device1,
- &s3c24xx_uart_device2,
- &s3c24xx_uart_device3,
-};
-
-struct platform_device *s3c24xx_uart_devs[4] = {
-};
-
diff --git a/arch/arm/plat-s3c64xx/dma.c b/arch/arm/plat-s3c64xx/dma.c
deleted file mode 100644
index d554b936fcf..00000000000
--- a/arch/arm/plat-s3c64xx/dma.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/dma.c
- *
- * Copyright 2009 Openmoko, Inc.
- * Copyright 2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX DMA core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/dmapool.h>
-#include <linux/sysdev.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/dma.h>
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#include <plat/dma-plat.h>
-#include <plat/regs-sys.h>
-
-#include <asm/hardware/pl080.h>
-
-/* dma channel state information */
-
-struct s3c64xx_dmac {
- struct sys_device sysdev;
- struct clk *clk;
- void __iomem *regs;
- struct s3c2410_dma_chan *channels;
- enum dma_ch chanbase;
-};
-
-/* pool to provide LLI buffers */
-static struct dma_pool *dma_pool;
-
-/* Debug configuration and code */
-
-static unsigned char debug_show_buffs = 0;
-
-static void dbg_showchan(struct s3c2410_dma_chan *chan)
-{
- pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
- chan->number,
- readl(chan->regs + PL080_CH_SRC_ADDR),
- readl(chan->regs + PL080_CH_DST_ADDR),
- readl(chan->regs + PL080_CH_LLI),
- readl(chan->regs + PL080_CH_CONTROL),
- readl(chan->regs + PL080S_CH_CONTROL2),
- readl(chan->regs + PL080S_CH_CONFIG));
-}
-
-static void show_lli(struct pl080s_lli *lli)
-{
- pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
- lli, lli->src_addr, lli->dst_addr, lli->next_lli,
- lli->control0, lli->control1);
-}
-
-static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
-{
- struct s3c64xx_dma_buff *ptr;
- struct s3c64xx_dma_buff *end;
-
- pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
- chan->number, chan->next, chan->curr, chan->end);
-
- ptr = chan->next;
- end = chan->end;
-
- if (debug_show_buffs) {
- for (; ptr != NULL; ptr = ptr->next) {
- pr_debug("DMA%d: %08x ",
- chan->number, ptr->lli_dma);
- show_lli(ptr->lli);
- }
- }
-}
-
-/* End of Debug */
-
-static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
-{
- struct s3c2410_dma_chan *chan;
- unsigned int start, offs;
-
- start = 0;
-
- if (channel >= DMACH_PCM1_TX)
- start = 8;
-
- for (offs = 0; offs < 8; offs++) {
- chan = &s3c2410_chans[start + offs];
- if (!chan->in_use)
- goto found;
- }
-
- return NULL;
-
-found:
- s3c_dma_chan_map[channel] = chan;
- return chan;
-}
-
-int s3c2410_dma_config(unsigned int channel, int xferunit)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- switch (xferunit) {
- case 1:
- chan->hw_width = 0;
- break;
- case 2:
- chan->hw_width = 1;
- break;
- case 4:
- chan->hw_width = 2;
- break;
- default:
- printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
- return -EINVAL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_config);
-
-static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
- struct pl080s_lli *lli,
- dma_addr_t data, int size)
-{
- dma_addr_t src, dst;
- u32 control0, control1;
-
- switch (chan->source) {
- case S3C2410_DMASRC_HW:
- src = chan->dev_addr;
- dst = data;
- control0 = PL080_CONTROL_SRC_AHB2;
- control0 |= PL080_CONTROL_DST_INCR;
- break;
-
- case S3C2410_DMASRC_MEM:
- src = data;
- dst = chan->dev_addr;
- control0 = PL080_CONTROL_DST_AHB2;
- control0 |= PL080_CONTROL_SRC_INCR;
- break;
- default:
- BUG();
- }
-
- /* note, we do not currently setup any of the burst controls */
-
- control1 = size >> chan->hw_width; /* size in no of xfers */
- control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */
- control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */
- control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
- control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
-
- lli->src_addr = src;
- lli->dst_addr = dst;
- lli->next_lli = 0;
- lli->control0 = control0;
- lli->control1 = control1;
-}
-
-static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
- struct pl080s_lli *lli)
-{
- void __iomem *regs = chan->regs;
-
- pr_debug("%s: LLI %p => regs\n", __func__, lli);
- show_lli(lli);
-
- writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
- writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
- writel(lli->next_lli, regs + PL080_CH_LLI);
- writel(lli->control0, regs + PL080_CH_CONTROL);
- writel(lli->control1, regs + PL080S_CH_CONTROL2);
-}
-
-static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
-{
- struct s3c64xx_dmac *dmac = chan->dmac;
- u32 config;
- u32 bit = chan->bit;
-
- dbg_showchan(chan);
-
- pr_debug("%s: clearing interrupts\n", __func__);
-
- /* clear interrupts */
- writel(bit, dmac->regs + PL080_TC_CLEAR);
- writel(bit, dmac->regs + PL080_ERR_CLEAR);
-
- pr_debug("%s: starting channel\n", __func__);
-
- config = readl(chan->regs + PL080S_CH_CONFIG);
- config |= PL080_CONFIG_ENABLE;
-
- pr_debug("%s: writing config %08x\n", __func__, config);
- writel(config, chan->regs + PL080S_CH_CONFIG);
-
- return 0;
-}
-
-static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
-{
- u32 config;
- int timeout;
-
- pr_debug("%s: stopping channel\n", __func__);
-
- dbg_showchan(chan);
-
- config = readl(chan->regs + PL080S_CH_CONFIG);
- config |= PL080_CONFIG_HALT;
- writel(config, chan->regs + PL080S_CH_CONFIG);
-
- timeout = 1000;
- do {
- config = readl(chan->regs + PL080S_CH_CONFIG);
- pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
- if (config & PL080_CONFIG_ACTIVE)
- udelay(10);
- else
- break;
- } while (--timeout > 0);
-
- if (config & PL080_CONFIG_ACTIVE) {
- printk(KERN_ERR "%s: channel still active\n", __func__);
- return -EFAULT;
- }
-
- config = readl(chan->regs + PL080S_CH_CONFIG);
- config &= ~PL080_CONFIG_ENABLE;
- writel(config, chan->regs + PL080S_CH_CONFIG);
-
- return 0;
-}
-
-static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
- struct s3c64xx_dma_buff *buf,
- enum s3c2410_dma_buffresult result)
-{
- if (chan->callback_fn != NULL)
- (chan->callback_fn)(chan, buf->pw, 0, result);
-}
-
-static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
-{
- dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
- kfree(buff);
-}
-
-static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
-{
- struct s3c64xx_dma_buff *buff, *next;
- u32 config;
-
- dbg_showchan(chan);
-
- pr_debug("%s: flushing channel\n", __func__);
-
- config = readl(chan->regs + PL080S_CH_CONFIG);
- config &= ~PL080_CONFIG_ENABLE;
- writel(config, chan->regs + PL080S_CH_CONFIG);
-
- /* dump all the buffers associated with this channel */
-
- for (buff = chan->curr; buff != NULL; buff = next) {
- next = buff->next;
- pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
-
- s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
- s3c64xx_dma_freebuff(buff);
- }
-
- chan->curr = chan->next = chan->end = NULL;
-
- return 0;
-}
-
-int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- WARN_ON(!chan);
- if (!chan)
- return -EINVAL;
-
- switch (op) {
- case S3C2410_DMAOP_START:
- return s3c64xx_dma_start(chan);
-
- case S3C2410_DMAOP_STOP:
- return s3c64xx_dma_stop(chan);
-
- case S3C2410_DMAOP_FLUSH:
- return s3c64xx_dma_flush(chan);
-
- /* belive PAUSE/RESUME are no-ops */
- case S3C2410_DMAOP_PAUSE:
- case S3C2410_DMAOP_RESUME:
- case S3C2410_DMAOP_STARTED:
- case S3C2410_DMAOP_TIMEOUT:
- return 0;
- }
-
- return -ENOENT;
-}
-EXPORT_SYMBOL(s3c2410_dma_ctrl);
-
-/* s3c2410_dma_enque
- *
- */
-
-int s3c2410_dma_enqueue(unsigned int channel, void *id,
- dma_addr_t data, int size)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- struct s3c64xx_dma_buff *next;
- struct s3c64xx_dma_buff *buff;
- struct pl080s_lli *lli;
- unsigned long flags;
- int ret;
-
- WARN_ON(!chan);
- if (!chan)
- return -EINVAL;
-
- buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
- if (!buff) {
- printk(KERN_ERR "%s: no memory for buffer\n", __func__);
- return -ENOMEM;
- }
-
- lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
- if (!lli) {
- printk(KERN_ERR "%s: no memory for lli\n", __func__);
- ret = -ENOMEM;
- goto err_buff;
- }
-
- pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
- __func__, buff, data, lli, (u32)buff->lli_dma, size);
-
- buff->lli = lli;
- buff->pw = id;
-
- s3c64xx_dma_fill_lli(chan, lli, data, size);
-
- local_irq_save(flags);
-
- if ((next = chan->next) != NULL) {
- struct s3c64xx_dma_buff *end = chan->end;
- struct pl080s_lli *endlli = end->lli;
-
- pr_debug("enquing onto channel\n");
-
- end->next = buff;
- endlli->next_lli = buff->lli_dma;
-
- if (chan->flags & S3C2410_DMAF_CIRCULAR) {
- struct s3c64xx_dma_buff *curr = chan->curr;
- lli->next_lli = curr->lli_dma;
- }
-
- if (next == chan->curr) {
- writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
- chan->next = buff;
- }
-
- show_lli(endlli);
- chan->end = buff;
- } else {
- pr_debug("enquing onto empty channel\n");
-
- chan->curr = buff;
- chan->next = buff;
- chan->end = buff;
-
- s3c64xx_lli_to_regs(chan, lli);
- }
-
- local_irq_restore(flags);
-
- show_lli(lli);
-
- dbg_showchan(chan);
- dbg_showbuffs(chan);
- return 0;
-
-err_buff:
- kfree(buff);
- return ret;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
-
-
-int s3c2410_dma_devconfig(int channel,
- enum s3c2410_dmasrc source,
- unsigned long devaddr)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- u32 peripheral;
- u32 config = 0;
-
- pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
- __func__, channel, source, devaddr, chan);
-
- WARN_ON(!chan);
- if (!chan)
- return -EINVAL;
-
- peripheral = (chan->peripheral & 0xf);
- chan->source = source;
- chan->dev_addr = devaddr;
-
- pr_debug("%s: peripheral %d\n", __func__, peripheral);
-
- switch (source) {
- case S3C2410_DMASRC_HW:
- config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
- config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
- break;
- case S3C2410_DMASRC_MEM:
- config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
- config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
- break;
- default:
- printk(KERN_ERR "%s: bad source\n", __func__);
- return -EINVAL;
- }
-
- /* allow TC and ERR interrupts */
- config |= PL080_CONFIG_TC_IRQ_MASK;
- config |= PL080_CONFIG_ERR_IRQ_MASK;
-
- pr_debug("%s: config %08x\n", __func__, config);
-
- writel(config, chan->regs + PL080S_CH_CONFIG);
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_devconfig);
-
-
-int s3c2410_dma_getposition(unsigned int channel,
- dma_addr_t *src, dma_addr_t *dst)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- WARN_ON(!chan);
- if (!chan)
- return -EINVAL;
-
- if (src != NULL)
- *src = readl(chan->regs + PL080_CH_SRC_ADDR);
-
- if (dst != NULL)
- *dst = readl(chan->regs + PL080_CH_DST_ADDR);
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_getposition);
-
-/* s3c2410_request_dma
- *
- * get control of an dma channel
-*/
-
-int s3c2410_dma_request(unsigned int channel,
- struct s3c2410_dma_client *client,
- void *dev)
-{
- struct s3c2410_dma_chan *chan;
- unsigned long flags;
-
- pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
- channel, client->name, dev);
-
- local_irq_save(flags);
-
- chan = s3c64xx_dma_map_channel(channel);
- if (chan == NULL) {
- local_irq_restore(flags);
- return -EBUSY;
- }
-
- dbg_showchan(chan);
-
- chan->client = client;
- chan->in_use = 1;
- chan->peripheral = channel;
-
- local_irq_restore(flags);
-
- /* need to setup */
-
- pr_debug("%s: channel initialised, %p\n", __func__, chan);
-
- return chan->number | DMACH_LOW_LEVEL;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_request);
-
-/* s3c2410_dma_free
- *
- * release the given channel back to the system, will stop and flush
- * any outstanding transfers, and ensure the channel is ready for the
- * next claimant.
- *
- * Note, although a warning is currently printed if the freeing client
- * info is not the same as the registrant's client info, the free is still
- * allowed to go through.
-*/
-
-int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- unsigned long flags;
-
- if (chan == NULL)
- return -EINVAL;
-
- local_irq_save(flags);
-
- if (chan->client != client) {
- printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
- channel, chan->client, client);
- }
-
- /* sort out stopping and freeing the channel */
-
-
- chan->client = NULL;
- chan->in_use = 0;
-
- if (!(channel & DMACH_LOW_LEVEL))
- s3c_dma_chan_map[channel] = NULL;
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_free);
-
-static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
-{
- struct s3c64xx_dmac *dmac = pw;
- struct s3c2410_dma_chan *chan;
- enum s3c2410_dma_buffresult res;
- u32 tcstat, errstat;
- u32 bit;
- int offs;
-
- tcstat = readl(dmac->regs + PL080_TC_STATUS);
- errstat = readl(dmac->regs + PL080_ERR_STATUS);
-
- for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
- struct s3c64xx_dma_buff *buff;
-
- if (!(errstat & bit) && !(tcstat & bit))
- continue;
-
- chan = dmac->channels + offs;
- res = S3C2410_RES_ERR;
-
- if (tcstat & bit) {
- writel(bit, dmac->regs + PL080_TC_CLEAR);
- res = S3C2410_RES_OK;
- }
-
- if (errstat & bit)
- writel(bit, dmac->regs + PL080_ERR_CLEAR);
-
- /* 'next' points to the buffer that is next to the
- * currently active buffer.
- * For CIRCULAR queues, 'next' will be same as 'curr'
- * when 'end' is the active buffer.
- */
- buff = chan->curr;
- while (buff && buff != chan->next
- && buff->next != chan->next)
- buff = buff->next;
-
- if (!buff)
- BUG();
-
- if (buff == chan->next)
- buff = chan->end;
-
- s3c64xx_dma_bufffdone(chan, buff, res);
-
- /* Free the node and update curr, if non-circular queue */
- if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
- chan->curr = buff->next;
- s3c64xx_dma_freebuff(buff);
- }
-
- /* Update 'next' */
- buff = chan->next;
- if (chan->next == chan->end) {
- chan->next = chan->curr;
- if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
- chan->end = NULL;
- } else {
- chan->next = buff->next;
- }
- }
-
- return IRQ_HANDLED;
-}
-
-static struct sysdev_class dma_sysclass = {
- .name = "s3c64xx-dma",
-};
-
-static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
- int irq, unsigned int base)
-{
- struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
- struct s3c64xx_dmac *dmac;
- char clkname[16];
- void __iomem *regs;
- void __iomem *regptr;
- int err, ch;
-
- dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
- if (!dmac) {
- printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
- return -ENOMEM;
- }
-
- dmac->sysdev.id = chno / 8;
- dmac->sysdev.cls = &dma_sysclass;
-
- err = sysdev_register(&dmac->sysdev);
- if (err) {
- printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
- goto err_alloc;
- }
-
- regs = ioremap(base, 0x200);
- if (!regs) {
- printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
- err = -ENXIO;
- goto err_dev;
- }
-
- snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);
-
- dmac->clk = clk_get(NULL, clkname);
- if (IS_ERR(dmac->clk)) {
- printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
- err = PTR_ERR(dmac->clk);
- goto err_map;
- }
-
- clk_enable(dmac->clk);
-
- dmac->regs = regs;
- dmac->chanbase = chbase;
- dmac->channels = chptr;
-
- err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
- if (err < 0) {
- printk(KERN_ERR "%s: failed to get irq\n", __func__);
- goto err_clk;
- }
-
- regptr = regs + PL080_Cx_BASE(0);
-
- for (ch = 0; ch < 8; ch++, chno++, chptr++) {
- printk(KERN_INFO "%s: registering DMA %d (%p)\n",
- __func__, chno, regptr);
-
- chptr->bit = 1 << ch;
- chptr->number = chno;
- chptr->dmac = dmac;
- chptr->regs = regptr;
- regptr += PL008_Cx_STRIDE;
- }
-
- /* for the moment, permanently enable the controller */
- writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
-
- printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs);
-
- return 0;
-
-err_clk:
- clk_disable(dmac->clk);
- clk_put(dmac->clk);
-err_map:
- iounmap(regs);
-err_dev:
- sysdev_unregister(&dmac->sysdev);
-err_alloc:
- kfree(dmac);
- return err;
-}
-
-static int __init s3c64xx_dma_init(void)
-{
- int ret;
-
- printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
-
- dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
- if (!dma_pool) {
- printk(KERN_ERR "%s: failed to create pool\n", __func__);
- return -ENOMEM;
- }
-
- ret = sysdev_class_register(&dma_sysclass);
- if (ret) {
- printk(KERN_ERR "%s: failed to create sysclass\n", __func__);
- return -ENOMEM;
- }
-
- /* Set all DMA configuration to be DMA, not SDMA */
- writel(0xffffff, S3C_SYSREG(0x110));
-
- /* Register standard DMA controlers */
- s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
- s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
-
- return 0;
-}
-
-arch_initcall(s3c64xx_dma_init);
diff --git a/arch/arm/plat-s3c64xx/gpiolib.c b/arch/arm/plat-s3c64xx/gpiolib.c
deleted file mode 100644
index 77856045727..00000000000
--- a/arch/arm/plat-s3c64xx/gpiolib.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* arch/arm/plat-s3c64xx/gpiolib.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX - GPIOlib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <mach/map.h>
-#include <mach/gpio.h>
-#include <mach/gpio-core.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <plat/regs-gpio.h>
-
-/* GPIO bank summary:
- *
- * Bank GPIOs Style SlpCon ExtInt Group
- * A 8 4Bit Yes 1
- * B 7 4Bit Yes 1
- * C 8 4Bit Yes 2
- * D 5 4Bit Yes 3
- * E 5 4Bit Yes None
- * F 16 2Bit Yes 4 [1]
- * G 7 4Bit Yes 5
- * H 10 4Bit[2] Yes 6
- * I 16 2Bit Yes None
- * J 12 2Bit Yes None
- * K 16 4Bit[2] No None
- * L 15 4Bit[2] No None
- * M 6 4Bit No IRQ_EINT
- * N 16 2Bit No IRQ_EINT
- * O 16 2Bit Yes 7
- * P 15 2Bit Yes 8
- * Q 9 2Bit Yes 9
- *
- * [1] BANKF pins 14,15 do not form part of the external interrupt sources
- * [2] BANK has two control registers, GPxCON0 and GPxCON1
- */
-
-#define OFF_GPCON (0x00)
-#define OFF_GPDAT (0x04)
-
-#define con_4bit_shift(__off) ((__off) * 4)
-
-#if 1
-#define gpio_dbg(x...) do { } while(0)
-#else
-#define gpio_dbg(x...) printk(KERN_DEBUG x)
-#endif
-
-/* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where
- * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
- * following example:
- *
- * base + 0x00: Control register, 4 bits per gpio
- * gpio n: 4 bits starting at (4*n)
- * 0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- * bit n: data bit n
- *
- * Note, since the data register is one bit per gpio and is at base + 0x4
- * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
- * the output.
-*/
-
-static int s3c64xx_gpiolib_4bit_input(struct gpio_chip *chip, unsigned offset)
-{
- struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
- void __iomem *base = ourchip->base;
- unsigned long con;
-
- con = __raw_readl(base + OFF_GPCON);
- con &= ~(0xf << con_4bit_shift(offset));
- __raw_writel(con, base + OFF_GPCON);
-
- gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
-
- return 0;
-}
-
-static int s3c64xx_gpiolib_4bit_output(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
- void __iomem *base = ourchip->base;
- unsigned long con;
- unsigned long dat;
-
- con = __raw_readl(base + OFF_GPCON);
- con &= ~(0xf << con_4bit_shift(offset));
- con |= 0x1 << con_4bit_shift(offset);
-
- dat = __raw_readl(base + OFF_GPDAT);
- if (value)
- dat |= 1 << offset;
- else
- dat &= ~(1 << offset);
-
- __raw_writel(dat, base + OFF_GPDAT);
- __raw_writel(con, base + OFF_GPCON);
- __raw_writel(dat, base + OFF_GPDAT);
-
- gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
- return 0;
-}
-
-/* The next set of routines are for the case where the GPIO configuration
- * registers are 4 bits per GPIO but there is more than one register (the
- * bank has more than 8 GPIOs.
- *
- * This case is the similar to the 4 bit case, but the registers are as
- * follows:
- *
- * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
- * gpio n: 4 bits starting at (4*n)
- * 0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
- * gpio n: 4 bits starting at (4*n)
- * 0000 = input, 0001 = output, others mean special-function
- * base + 0x08: Data register, 1 bit per gpio
- * bit n: data bit n
- *
- * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we
- * store the 'base + 0x4' address so that these routines see the data
- * register at ourchip->base + 0x04.
-*/
-
-static int s3c64xx_gpiolib_4bit2_input(struct gpio_chip *chip, unsigned offset)
-{
- struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
- void __iomem *base = ourchip->base;
- void __iomem *regcon = base;
- unsigned long con;
-
- if (offset > 7)
- offset -= 8;
- else
- regcon -= 4;
-
- con = __raw_readl(regcon);
- con &= ~(0xf << con_4bit_shift(offset));
- __raw_writel(con, regcon);
-
- gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
-
- return 0;
-
-}
-
-static int s3c64xx_gpiolib_4bit2_output(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
- void __iomem *base = ourchip->base;
- void __iomem *regcon = base;
- unsigned long con;
- unsigned long dat;
-
- if (offset > 7)
- offset -= 8;
- else
- regcon -= 4;
-
- con = __raw_readl(regcon);
- con &= ~(0xf << con_4bit_shift(offset));
- con |= 0x1 << con_4bit_shift(offset);
-
- dat = __raw_readl(base + OFF_GPDAT);
- if (value)
- dat |= 1 << offset;
- else
- dat &= ~(1 << offset);
-
- __raw_writel(dat, base + OFF_GPDAT);
- __raw_writel(con, regcon);
- __raw_writel(dat, base + OFF_GPDAT);
-
- gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
- return 0;
-}
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
- .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
- .set_pull = s3c_gpio_setpull_updown,
- .get_pull = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
- .cfg_eint = 7,
- .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
- .set_pull = s3c_gpio_setpull_updown,
- .get_pull = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
- .cfg_eint = 3,
- .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
- .set_pull = s3c_gpio_setpull_updown,
- .get_pull = s3c_gpio_getpull_updown,
-};
-
-int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
-{
- return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
-}
-
-static struct s3c_gpio_chip gpio_4bit[] = {
- {
- .base = S3C64XX_GPA_BASE,
- .config = &gpio_4bit_cfg_eint0111,
- .chip = {
- .base = S3C64XX_GPA(0),
- .ngpio = S3C64XX_GPIO_A_NR,
- .label = "GPA",
- },
- }, {
- .base = S3C64XX_GPB_BASE,
- .config = &gpio_4bit_cfg_eint0111,
- .chip = {
- .base = S3C64XX_GPB(0),
- .ngpio = S3C64XX_GPIO_B_NR,
- .label = "GPB",
- },
- }, {
- .base = S3C64XX_GPC_BASE,
- .config = &gpio_4bit_cfg_eint0111,
- .chip = {
- .base = S3C64XX_GPC(0),
- .ngpio = S3C64XX_GPIO_C_NR,
- .label = "GPC",
- },
- }, {
- .base = S3C64XX_GPD_BASE,
- .config = &gpio_4bit_cfg_eint0111,
- .chip = {
- .base = S3C64XX_GPD(0),
- .ngpio = S3C64XX_GPIO_D_NR,
- .label = "GPD",
- },
- }, {
- .base = S3C64XX_GPE_BASE,
- .config = &gpio_4bit_cfg_noint,
- .chip = {
- .base = S3C64XX_GPE(0),
- .ngpio = S3C64XX_GPIO_E_NR,
- .label = "GPE",
- },
- }, {
- .base = S3C64XX_GPG_BASE,
- .config = &gpio_4bit_cfg_eint0111,
- .chip = {
- .base = S3C64XX_GPG(0),
- .ngpio = S3C64XX_GPIO_G_NR,
- .label = "GPG",
- },
- }, {
- .base = S3C64XX_GPM_BASE,
- .config = &gpio_4bit_cfg_eint0011,
- .chip = {
- .base = S3C64XX_GPM(0),
- .ngpio = S3C64XX_GPIO_M_NR,
- .label = "GPM",
- .to_irq = s3c64xx_gpio2int_gpm,
- },
- },
-};
-
-int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
-{
- return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
-}
-
-static struct s3c_gpio_chip gpio_4bit2[] = {
- {
- .base = S3C64XX_GPH_BASE + 0x4,
- .config = &gpio_4bit_cfg_eint0111,
- .chip = {
- .base = S3C64XX_GPH(0),
- .ngpio = S3C64XX_GPIO_H_NR,
- .label = "GPH",
- },
- }, {
- .base = S3C64XX_GPK_BASE + 0x4,
- .config = &gpio_4bit_cfg_noint,
- .chip = {
- .base = S3C64XX_GPK(0),
- .ngpio = S3C64XX_GPIO_K_NR,
- .label = "GPK",
- },
- }, {
- .base = S3C64XX_GPL_BASE + 0x4,
- .config = &gpio_4bit_cfg_eint0011,
- .chip = {
- .base = S3C64XX_GPL(0),
- .ngpio = S3C64XX_GPIO_L_NR,
- .label = "GPL",
- .to_irq = s3c64xx_gpio2int_gpl,
- },
- },
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
- .set_config = s3c_gpio_setcfg_s3c24xx,
- .set_pull = s3c_gpio_setpull_updown,
- .get_pull = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
- .cfg_eint = 2,
- .set_config = s3c_gpio_setcfg_s3c24xx,
- .set_pull = s3c_gpio_setpull_updown,
- .get_pull = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
- .cfg_eint = 3,
- .set_config = s3c_gpio_setcfg_s3c24xx,
- .set_pull = s3c_gpio_setpull_updown,
- .get_pull = s3c_gpio_getpull_updown,
-};
-
-int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
-{
- return IRQ_EINT(0) + pin;
-}
-
-static struct s3c_gpio_chip gpio_2bit[] = {
- {
- .base = S3C64XX_GPF_BASE,
- .config = &gpio_2bit_cfg_eint11,
- .chip = {
- .base = S3C64XX_GPF(0),
- .ngpio = S3C64XX_GPIO_F_NR,
- .label = "GPF",
- },
- }, {
- .base = S3C64XX_GPI_BASE,
- .config = &gpio_2bit_cfg_noint,
- .chip = {
- .base = S3C64XX_GPI(0),
- .ngpio = S3C64XX_GPIO_I_NR,
- .label = "GPI",
- },
- }, {
- .base = S3C64XX_GPJ_BASE,
- .config = &gpio_2bit_cfg_noint,
- .chip = {
- .base = S3C64XX_GPJ(0),
- .ngpio = S3C64XX_GPIO_J_NR,
- .label = "GPJ",
- },
- }, {
- .base = S3C64XX_GPN_BASE,
- .config = &gpio_2bit_cfg_eint10,
- .chip = {
- .base = S3C64XX_GPN(0),
- .ngpio = S3C64XX_GPIO_N_NR,
- .label = "GPN",
- .to_irq = s3c64xx_gpio2int_gpn,
- },
- }, {
- .base = S3C64XX_GPO_BASE,
- .config = &gpio_2bit_cfg_eint11,
- .chip = {
- .base = S3C64XX_GPO(0),
- .ngpio = S3C64XX_GPIO_O_NR,
- .label = "GPO",
- },
- }, {
- .base = S3C64XX_GPP_BASE,
- .config = &gpio_2bit_cfg_eint11,
- .chip = {
- .base = S3C64XX_GPP(0),
- .ngpio = S3C64XX_GPIO_P_NR,
- .label = "GPP",
- },
- }, {
- .base = S3C64XX_GPQ_BASE,
- .config = &gpio_2bit_cfg_eint11,
- .chip = {
- .base = S3C64XX_GPQ(0),
- .ngpio = S3C64XX_GPIO_Q_NR,
- .label = "GPQ",
- },
- },
-};
-
-static __init void s3c64xx_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
-{
- chip->chip.direction_input = s3c64xx_gpiolib_4bit_input;
- chip->chip.direction_output = s3c64xx_gpiolib_4bit_output;
- chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
-}
-
-static __init void s3c64xx_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
-{
- chip->chip.direction_input = s3c64xx_gpiolib_4bit2_input;
- chip->chip.direction_output = s3c64xx_gpiolib_4bit2_output;
- chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
-}
-
-static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
-{
- chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
-}
-
-static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
- int nr_chips,
- void (*fn)(struct s3c_gpio_chip *))
-{
- for (; nr_chips > 0; nr_chips--, chips++) {
- if (fn)
- (fn)(chips);
- s3c_gpiolib_add(chips);
- }
-}
-
-static __init int s3c64xx_gpiolib_init(void)
-{
- s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
- s3c64xx_gpiolib_add_4bit);
-
- s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
- s3c64xx_gpiolib_add_4bit2);
-
- s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
- s3c64xx_gpiolib_add_2bit);
-
- return 0;
-}
-
-core_initcall(s3c64xx_gpiolib_init);
diff --git a/arch/arm/plat-s3c64xx/include/plat/dma-plat.h b/arch/arm/plat-s3c64xx/include/plat/dma-plat.h
deleted file mode 100644
index 8f76a1e474d..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/dma-plat.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/dma-plat.h
- *
- * Copyright 2009 Openmoko, Inc.
- * Copyright 2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX DMA core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
-
-struct s3c64xx_dma_buff;
-
-/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
- * @next: Pointer to next buffer in queue or ring.
- * @pw: Client provided identifier
- * @lli: Pointer to hardware descriptor this buffer is associated with.
- * @lli_dma: Hardare address of the descriptor.
- */
-struct s3c64xx_dma_buff {
- struct s3c64xx_dma_buff *next;
-
- void *pw;
- struct pl080s_lli *lli;
- dma_addr_t lli_dma;
-};
-
-struct s3c64xx_dmac;
-
-struct s3c2410_dma_chan {
- unsigned char number; /* number of this dma channel */
- unsigned char in_use; /* channel allocated */
- unsigned char bit; /* bit for enable/disable/etc */
- unsigned char hw_width;
- unsigned char peripheral;
-
- unsigned int flags;
- enum s3c2410_dmasrc source;
-
-
- dma_addr_t dev_addr;
-
- struct s3c2410_dma_client *client;
- struct s3c64xx_dmac *dmac; /* pointer to controller */
-
- void __iomem *regs;
-
- /* cdriver callbacks */
- s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
- s3c2410_dma_opfn_t op_fn; /* channel op callback */
-
- /* buffer list and information */
- struct s3c64xx_dma_buff *curr; /* current dma buffer */
- struct s3c64xx_dma_buff *next; /* next buffer to load */
- struct s3c64xx_dma_buff *end; /* end of queue */
-
- /* note, when channel is running in circular mode, curr is the
- * first buffer enqueued, end is the last and curr is where the
- * last buffer-done event is set-at. The buffers are not freed
- * and the last buffer hardware descriptor points back to the
- * first.
- */
-};
-
-#include <plat/dma-core.h>
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h
deleted file mode 100644
index 9aa0e427d11..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank A register and configuration 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.
-*/
-
-#define S3C64XX_GPACON (S3C64XX_GPA_BASE + 0x00)
-#define S3C64XX_GPADAT (S3C64XX_GPA_BASE + 0x04)
-#define S3C64XX_GPAPUD (S3C64XX_GPA_BASE + 0x08)
-#define S3C64XX_GPACONSLP (S3C64XX_GPA_BASE + 0x0c)
-#define S3C64XX_GPAPUDSLP (S3C64XX_GPA_BASE + 0x10)
-
-#define S3C64XX_GPA_CONMASK(__gpio) (0xf << ((__gpio) * 4))
-#define S3C64XX_GPA_INPUT(__gpio) (0x0 << ((__gpio) * 4))
-#define S3C64XX_GPA_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPA0_UART_RXD0 (0x02 << 0)
-#define S3C64XX_GPA0_EINT_G1_0 (0x07 << 0)
-
-#define S3C64XX_GPA1_UART_TXD0 (0x02 << 4)
-#define S3C64XX_GPA1_EINT_G1_1 (0x07 << 4)
-
-#define S3C64XX_GPA2_UART_nCTS0 (0x02 << 8)
-#define S3C64XX_GPA2_EINT_G1_2 (0x07 << 8)
-
-#define S3C64XX_GPA3_UART_nRTS0 (0x02 << 12)
-#define S3C64XX_GPA3_EINT_G1_3 (0x07 << 12)
-
-#define S3C64XX_GPA4_UART_RXD1 (0x02 << 16)
-#define S3C64XX_GPA4_EINT_G1_4 (0x07 << 16)
-
-#define S3C64XX_GPA5_UART_TXD1 (0x02 << 20)
-#define S3C64XX_GPA5_EINT_G1_5 (0x07 << 20)
-
-#define S3C64XX_GPA6_UART_nCTS1 (0x02 << 24)
-#define S3C64XX_GPA6_EINT_G1_6 (0x07 << 24)
-
-#define S3C64XX_GPA7_UART_nRTS1 (0x02 << 28)
-#define S3C64XX_GPA7_EINT_G1_7 (0x07 << 28)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h
deleted file mode 100644
index 3933adb4d50..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank B register and configuration 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.
-*/
-
-#define S3C64XX_GPBCON (S3C64XX_GPB_BASE + 0x00)
-#define S3C64XX_GPBDAT (S3C64XX_GPB_BASE + 0x04)
-#define S3C64XX_GPBPUD (S3C64XX_GPB_BASE + 0x08)
-#define S3C64XX_GPBCONSLP (S3C64XX_GPB_BASE + 0x0c)
-#define S3C64XX_GPBPUDSLP (S3C64XX_GPB_BASE + 0x10)
-
-#define S3C64XX_GPB_CONMASK(__gpio) (0xf << ((__gpio) * 4))
-#define S3C64XX_GPB_INPUT(__gpio) (0x0 << ((__gpio) * 4))
-#define S3C64XX_GPB_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPB0_UART_RXD2 (0x02 << 0)
-#define S3C64XX_GPB0_EXTDMA_REQ (0x03 << 0)
-#define S3C64XX_GPB0_IrDA_RXD (0x04 << 0)
-#define S3C64XX_GPB0_ADDR_CF0 (0x05 << 0)
-#define S3C64XX_GPB0_EINT_G1_8 (0x07 << 0)
-
-#define S3C64XX_GPB1_UART_TXD2 (0x02 << 4)
-#define S3C64XX_GPB1_EXTDMA_ACK (0x03 << 4)
-#define S3C64XX_GPB1_IrDA_TXD (0x04 << 4)
-#define S3C64XX_GPB1_ADDR_CF1 (0x05 << 4)
-#define S3C64XX_GPB1_EINT_G1_9 (0x07 << 4)
-
-#define S3C64XX_GPB2_UART_RXD3 (0x02 << 8)
-#define S3C64XX_GPB2_IrDA_RXD (0x03 << 8)
-#define S3C64XX_GPB2_EXTDMA_REQ (0x04 << 8)
-#define S3C64XX_GPB2_ADDR_CF2 (0x05 << 8)
-#define S3C64XX_GPB2_I2C_SCL1 (0x06 << 8)
-#define S3C64XX_GPB2_EINT_G1_10 (0x07 << 8)
-
-#define S3C64XX_GPB3_UART_TXD3 (0x02 << 12)
-#define S3C64XX_GPB3_IrDA_TXD (0x03 << 12)
-#define S3C64XX_GPB3_EXTDMA_ACK (0x04 << 12)
-#define S3C64XX_GPB3_I2C_SDA1 (0x06 << 12)
-#define S3C64XX_GPB3_EINT_G1_11 (0x07 << 12)
-
-#define S3C64XX_GPB4_IrDA_SDBW (0x02 << 16)
-#define S3C64XX_GPB4_CAM_FIELD (0x03 << 16)
-#define S3C64XX_GPB4_CF_DATA_DIR (0x04 << 16)
-#define S3C64XX_GPB4_EINT_G1_12 (0x07 << 16)
-
-#define S3C64XX_GPB5_I2C_SCL0 (0x02 << 20)
-#define S3C64XX_GPB5_EINT_G1_13 (0x07 << 20)
-
-#define S3C64XX_GPB6_I2C_SDA0 (0x02 << 24)
-#define S3C64XX_GPB6_EINT_G1_14 (0x07 << 24)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h
deleted file mode 100644
index e22b49f4f98..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank C register and configuration 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.
-*/
-
-#define S3C64XX_GPCCON (S3C64XX_GPC_BASE + 0x00)
-#define S3C64XX_GPCDAT (S3C64XX_GPC_BASE + 0x04)
-#define S3C64XX_GPCPUD (S3C64XX_GPC_BASE + 0x08)
-#define S3C64XX_GPCCONSLP (S3C64XX_GPC_BASE + 0x0c)
-#define S3C64XX_GPCPUDSLP (S3C64XX_GPC_BASE + 0x10)
-
-#define S3C64XX_GPC_CONMASK(__gpio) (0xf << ((__gpio) * 4))
-#define S3C64XX_GPC_INPUT(__gpio) (0x0 << ((__gpio) * 4))
-#define S3C64XX_GPC_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPC0_SPI_MISO0 (0x02 << 0)
-#define S3C64XX_GPC0_EINT_G2_0 (0x07 << 0)
-
-#define S3C64XX_GPC1_SPI_CLKO (0x02 << 4)
-#define S3C64XX_GPC1_EINT_G2_1 (0x07 << 4)
-
-#define S3C64XX_GPC2_SPI_MOSIO (0x02 << 8)
-#define S3C64XX_GPC2_EINT_G2_2 (0x07 << 8)
-
-#define S3C64XX_GPC3_SPI_nCSO (0x02 << 12)
-#define S3C64XX_GPC3_EINT_G2_3 (0x07 << 12)
-
-#define S3C64XX_GPC4_SPI_MISO1 (0x02 << 16)
-#define S3C64XX_GPC4_MMC2_CMD (0x03 << 16)
-#define S3C64XX_GPC4_I2S_V40_DO0 (0x05 << 16)
-#define S3C64XX_GPC4_EINT_G2_4 (0x07 << 16)
-
-#define S3C64XX_GPC5_SPI_CLK1 (0x02 << 20)
-#define S3C64XX_GPC5_MMC2_CLK (0x03 << 20)
-#define S3C64XX_GPC5_I2S_V40_DO1 (0x05 << 20)
-#define S3C64XX_GPC5_EINT_G2_5 (0x07 << 20)
-
-#define S3C64XX_GPC6_SPI_MOSI1 (0x02 << 24)
-#define S3C64XX_GPC6_EINT_G2_6 (0x07 << 24)
-
-#define S3C64XX_GPC7_SPI_nCS1 (0x02 << 28)
-#define S3C64XX_GPC7_I2S_V40_DO2 (0x05 << 28)
-#define S3C64XX_GPC7_EINT_G2_7 (0x07 << 28)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h
deleted file mode 100644
index 6fe4a49c26f..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank D register and configuration 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.
-*/
-
-#define S3C64XX_GPDCON (S3C64XX_GPD_BASE + 0x00)
-#define S3C64XX_GPDDAT (S3C64XX_GPD_BASE + 0x04)
-#define S3C64XX_GPDPUD (S3C64XX_GPD_BASE + 0x08)
-#define S3C64XX_GPDCONSLP (S3C64XX_GPD_BASE + 0x0c)
-#define S3C64XX_GPDPUDSLP (S3C64XX_GPD_BASE + 0x10)
-
-#define S3C64XX_GPD_CONMASK(__gpio) (0xf << ((__gpio) * 4))
-#define S3C64XX_GPD_INPUT(__gpio) (0x0 << ((__gpio) * 4))
-#define S3C64XX_GPD_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPD0_PCM0_SCLK (0x02 << 0)
-#define S3C64XX_GPD0_I2S0_CLK (0x03 << 0)
-#define S3C64XX_GPD0_AC97_BITCLK (0x04 << 0)
-#define S3C64XX_GPD0_EINT_G3_0 (0x07 << 0)
-
-#define S3C64XX_GPD1_PCM0_EXTCLK (0x02 << 4)
-#define S3C64XX_GPD1_I2S0_CDCLK (0x03 << 4)
-#define S3C64XX_GPD1_AC97_nRESET (0x04 << 4)
-#define S3C64XX_GPD1_EINT_G3_1 (0x07 << 4)
-
-#define S3C64XX_GPD2_PCM0_FSYNC (0x02 << 8)
-#define S3C64XX_GPD2_I2S0_LRCLK (0x03 << 8)
-#define S3C64XX_GPD2_AC97_SYNC (0x04 << 8)
-#define S3C64XX_GPD2_EINT_G3_2 (0x07 << 8)
-
-#define S3C64XX_GPD3_PCM0_SIN (0x02 << 12)
-#define S3C64XX_GPD3_I2S0_DI (0x03 << 12)
-#define S3C64XX_GPD3_AC97_SDI (0x04 << 12)
-#define S3C64XX_GPD3_EINT_G3_3 (0x07 << 12)
-
-#define S3C64XX_GPD4_PCM0_SOUT (0x02 << 16)
-#define S3C64XX_GPD4_I2S0_D0 (0x03 << 16)
-#define S3C64XX_GPD4_AC97_SDO (0x04 << 16)
-#define S3C64XX_GPD4_EINT_G3_4 (0x07 << 16)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h
deleted file mode 100644
index 7fcf3d8e0a4..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank E register and configuration 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.
-*/
-
-#define S3C64XX_GPECON (S3C64XX_GPE_BASE + 0x00)
-#define S3C64XX_GPEDAT (S3C64XX_GPE_BASE + 0x04)
-#define S3C64XX_GPEPUD (S3C64XX_GPE_BASE + 0x08)
-#define S3C64XX_GPECONSLP (S3C64XX_GPE_BASE + 0x0c)
-#define S3C64XX_GPEPUDSLP (S3C64XX_GPE_BASE + 0x10)
-
-#define S3C64XX_GPE_CONMASK(__gpio) (0xf << ((__gpio) * 4))
-#define S3C64XX_GPE_INPUT(__gpio) (0x0 << ((__gpio) * 4))
-#define S3C64XX_GPE_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPE0_PCM1_SCLK (0x02 << 0)
-#define S3C64XX_GPE0_I2S1_CLK (0x03 << 0)
-#define S3C64XX_GPE0_AC97_BITCLK (0x04 << 0)
-
-#define S3C64XX_GPE1_PCM1_EXTCLK (0x02 << 4)
-#define S3C64XX_GPE1_I2S1_CDCLK (0x03 << 4)
-#define S3C64XX_GPE1_AC97_nRESET (0x04 << 4)
-
-#define S3C64XX_GPE2_PCM1_FSYNC (0x02 << 8)
-#define S3C64XX_GPE2_I2S1_LRCLK (0x03 << 8)
-#define S3C64XX_GPE2_AC97_SYNC (0x04 << 8)
-
-#define S3C64XX_GPE3_PCM1_SIN (0x02 << 12)
-#define S3C64XX_GPE3_I2S1_DI (0x03 << 12)
-#define S3C64XX_GPE3_AC97_SDI (0x04 << 12)
-
-#define S3C64XX_GPE4_PCM1_SOUT (0x02 << 16)
-#define S3C64XX_GPE4_I2S1_D0 (0x03 << 16)
-#define S3C64XX_GPE4_AC97_SDO (0x04 << 16)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h
deleted file mode 100644
index f3faff974a1..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank F register and configuration 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.
-*/
-
-#define S3C64XX_GPFCON (S3C64XX_GPF_BASE + 0x00)
-#define S3C64XX_GPFDAT (S3C64XX_GPF_BASE + 0x04)
-#define S3C64XX_GPFPUD (S3C64XX_GPF_BASE + 0x08)
-#define S3C64XX_GPFCONSLP (S3C64XX_GPF_BASE + 0x0c)
-#define S3C64XX_GPFPUDSLP (S3C64XX_GPF_BASE + 0x10)
-
-#define S3C64XX_GPF_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
-#define S3C64XX_GPF_INPUT(__gpio) (0x0 << ((__gpio) * 2))
-#define S3C64XX_GPF_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPF0_CAMIF_CLK (0x02 << 0)
-#define S3C64XX_GPF0_EINT_G4_0 (0x03 << 0)
-
-#define S3C64XX_GPF1_CAMIF_HREF (0x02 << 2)
-#define S3C64XX_GPF1_EINT_G4_1 (0x03 << 2)
-
-#define S3C64XX_GPF2_CAMIF_PCLK (0x02 << 4)
-#define S3C64XX_GPF2_EINT_G4_2 (0x03 << 4)
-
-#define S3C64XX_GPF3_CAMIF_nRST (0x02 << 6)
-#define S3C64XX_GPF3_EINT_G4_3 (0x03 << 6)
-
-#define S3C64XX_GPF4_CAMIF_VSYNC (0x02 << 8)
-#define S3C64XX_GPF4_EINT_G4_4 (0x03 << 8)
-
-#define S3C64XX_GPF5_CAMIF_YDATA0 (0x02 << 10)
-#define S3C64XX_GPF5_EINT_G4_5 (0x03 << 10)
-
-#define S3C64XX_GPF6_CAMIF_YDATA1 (0x02 << 12)
-#define S3C64XX_GPF6_EINT_G4_6 (0x03 << 12)
-
-#define S3C64XX_GPF7_CAMIF_YDATA2 (0x02 << 14)
-#define S3C64XX_GPF7_EINT_G4_7 (0x03 << 14)
-
-#define S3C64XX_GPF8_CAMIF_YDATA3 (0x02 << 16)
-#define S3C64XX_GPF8_EINT_G4_8 (0x03 << 16)
-
-#define S3C64XX_GPF9_CAMIF_YDATA4 (0x02 << 18)
-#define S3C64XX_GPF9_EINT_G4_9 (0x03 << 18)
-
-#define S3C64XX_GPF10_CAMIF_YDATA5 (0x02 << 20)
-#define S3C64XX_GPF10_EINT_G4_10 (0x03 << 20)
-
-#define S3C64XX_GPF11_CAMIF_YDATA6 (0x02 << 22)
-#define S3C64XX_GPF11_EINT_G4_11 (0x03 << 22)
-
-#define S3C64XX_GPF12_CAMIF_YDATA7 (0x02 << 24)
-#define S3C64XX_GPF12_EINT_G4_12 (0x03 << 24)
-
-#define S3C64XX_GPF13_PWM_ECLK (0x02 << 26)
-#define S3C64XX_GPF13_EINT_G4_13 (0x03 << 26)
-
-#define S3C64XX_GPF14_PWM_TOUT0 (0x02 << 28)
-#define S3C64XX_GPF14_CLKOUT0 (0x03 << 28)
-
-#define S3C64XX_GPF15_PWM_TOUT1 (0x02 << 30)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h
deleted file mode 100644
index 35bbd2378e5..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank G register and configuration 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.
-*/
-
-#define S3C64XX_GPGCON (S3C64XX_GPG_BASE + 0x00)
-#define S3C64XX_GPGDAT (S3C64XX_GPG_BASE + 0x04)
-#define S3C64XX_GPGPUD (S3C64XX_GPG_BASE + 0x08)
-#define S3C64XX_GPGCONSLP (S3C64XX_GPG_BASE + 0x0c)
-#define S3C64XX_GPGPUDSLP (S3C64XX_GPG_BASE + 0x10)
-
-#define S3C64XX_GPG_CONMASK(__gpio) (0xf << ((__gpio) * 4))
-#define S3C64XX_GPG_INPUT(__gpio) (0x0 << ((__gpio) * 4))
-#define S3C64XX_GPG_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPG0_MMC0_CLK (0x02 << 0)
-#define S3C64XX_GPG0_EINT_G5_0 (0x07 << 0)
-
-#define S3C64XX_GPG1_MMC0_CMD (0x02 << 4)
-#define S3C64XX_GPG1_EINT_G5_1 (0x07 << 4)
-
-#define S3C64XX_GPG2_MMC0_DATA0 (0x02 << 8)
-#define S3C64XX_GPG2_EINT_G5_2 (0x07 << 8)
-
-#define S3C64XX_GPG3_MMC0_DATA1 (0x02 << 12)
-#define S3C64XX_GPG3_EINT_G5_3 (0x07 << 12)
-
-#define S3C64XX_GPG4_MMC0_DATA2 (0x02 << 16)
-#define S3C64XX_GPG4_EINT_G5_4 (0x07 << 16)
-
-#define S3C64XX_GPG5_MMC0_DATA3 (0x02 << 20)
-#define S3C64XX_GPG5_EINT_G5_5 (0x07 << 20)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h
deleted file mode 100644
index 2ba1767512d..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank H register and configuration 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.
-*/
-
-#define S3C64XX_GPHCON0 (S3C64XX_GPH_BASE + 0x00)
-#define S3C64XX_GPHCON1 (S3C64XX_GPH_BASE + 0x04)
-#define S3C64XX_GPHDAT (S3C64XX_GPH_BASE + 0x08)
-#define S3C64XX_GPHPUD (S3C64XX_GPH_BASE + 0x0c)
-#define S3C64XX_GPHCONSLP (S3C64XX_GPH_BASE + 0x10)
-#define S3C64XX_GPHPUDSLP (S3C64XX_GPH_BASE + 0x14)
-
-#define S3C64XX_GPH_CONMASK(__gpio) (0xf << ((__gpio) * 4))
-#define S3C64XX_GPH_INPUT(__gpio) (0x0 << ((__gpio) * 4))
-#define S3C64XX_GPH_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
-
-#define S3C64XX_GPH0_MMC1_CLK (0x02 << 0)
-#define S3C64XX_GPH0_KP_COL0 (0x04 << 0)
-#define S3C64XX_GPH0_EINT_G6_0 (0x07 << 0)
-
-#define S3C64XX_GPH1_MMC1_CMD (0x02 << 4)
-#define S3C64XX_GPH1_KP_COL1 (0x04 << 4)
-#define S3C64XX_GPH1_EINT_G6_1 (0x07 << 4)
-
-#define S3C64XX_GPH2_MMC1_DATA0 (0x02 << 8)
-#define S3C64XX_GPH2_KP_COL2 (0x04 << 8)
-#define S3C64XX_GPH2_EINT_G6_2 (0x07 << 8)
-
-#define S3C64XX_GPH3_MMC1_DATA1 (0x02 << 12)
-#define S3C64XX_GPH3_KP_COL3 (0x04 << 12)
-#define S3C64XX_GPH3_EINT_G6_3 (0x07 << 12)
-
-#define S3C64XX_GPH4_MMC1_DATA2 (0x02 << 16)
-#define S3C64XX_GPH4_KP_COL4 (0x04 << 16)
-#define S3C64XX_GPH4_EINT_G6_4 (0x07 << 16)
-
-#define S3C64XX_GPH5_MMC1_DATA3 (0x02 << 20)
-#define S3C64XX_GPH5_KP_COL5 (0x04 << 20)
-#define S3C64XX_GPH5_EINT_G6_5 (0x07 << 20)
-
-#define S3C64XX_GPH6_MMC1_DATA4 (0x02 << 24)
-#define S3C64XX_GPH6_MMC2_DATA0 (0x03 << 24)
-#define S3C64XX_GPH6_KP_COL6 (0x04 << 24)
-#define S3C64XX_GPH6_I2S_V40_BCLK (0x05 << 24)
-#define S3C64XX_GPH6_ADDR_CF0 (0x06 << 24)
-#define S3C64XX_GPH6_EINT_G6_6 (0x07 << 24)
-
-#define S3C64XX_GPH7_MMC1_DATA5 (0x02 << 28)
-#define S3C64XX_GPH7_MMC2_DATA1 (0x03 << 28)
-#define S3C64XX_GPH7_KP_COL7 (0x04 << 28)
-#define S3C64XX_GPH7_I2S_V40_CDCLK (0x05 << 28)
-#define S3C64XX_GPH7_ADDR_CF1 (0x06 << 28)
-#define S3C64XX_GPH7_EINT_G6_7 (0x07 << 28)
-
-#define S3C64XX_GPH8_MMC1_DATA6 (0x02 << 0)
-#define S3C64XX_GPH8_MMC2_DATA2 (0x03 << 0)
-#define S3C64XX_GPH8_I2S_V40_LRCLK (0x05 << 0)
-#define S3C64XX_GPH8_ADDR_CF2 (0x06 << 0)
-#define S3C64XX_GPH8_EINT_G6_8 (0x07 << 0)
-
-#define S3C64XX_GPH9_OUTPUT (0x01 << 4)
-#define S3C64XX_GPH9_MMC1_DATA7 (0x02 << 4)
-#define S3C64XX_GPH9_MMC2_DATA3 (0x03 << 4)
-#define S3C64XX_GPH9_I2S_V40_DI (0x05 << 4)
-#define S3C64XX_GPH9_EINT_G6_9 (0x07 << 4)
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h
deleted file mode 100644
index ce9ebe33556..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank I register and configuration 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.
-*/
-
-#define S3C64XX_GPICON (S3C64XX_GPI_BASE + 0x00)
-#define S3C64XX_GPIDAT (S3C64XX_GPI_BASE + 0x04)
-#define S3C64XX_GPIPUD (S3C64XX_GPI_BASE + 0x08)
-#define S3C64XX_GPICONSLP (S3C64XX_GPI_BASE + 0x0c)
-#define S3C64XX_GPIPUDSLP (S3C64XX_GPI_BASE + 0x10)
-
-#define S3C64XX_GPI_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
-#define S3C64XX_GPI_INPUT(__gpio) (0x0 << ((__gpio) * 2))
-#define S3C64XX_GPI_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPI0_VD0 (0x02 << 0)
-#define S3C64XX_GPI1_VD1 (0x02 << 2)
-#define S3C64XX_GPI2_VD2 (0x02 << 4)
-#define S3C64XX_GPI3_VD3 (0x02 << 6)
-#define S3C64XX_GPI4_VD4 (0x02 << 8)
-#define S3C64XX_GPI5_VD5 (0x02 << 10)
-#define S3C64XX_GPI6_VD6 (0x02 << 12)
-#define S3C64XX_GPI7_VD7 (0x02 << 14)
-#define S3C64XX_GPI8_VD8 (0x02 << 16)
-#define S3C64XX_GPI9_VD9 (0x02 << 18)
-#define S3C64XX_GPI10_VD10 (0x02 << 20)
-#define S3C64XX_GPI11_VD11 (0x02 << 22)
-#define S3C64XX_GPI12_VD12 (0x02 << 24)
-#define S3C64XX_GPI13_VD13 (0x02 << 26)
-#define S3C64XX_GPI14_VD14 (0x02 << 28)
-#define S3C64XX_GPI15_VD15 (0x02 << 30)
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h
deleted file mode 100644
index 21a906299d3..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank J register and configuration 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.
-*/
-
-#define S3C64XX_GPJCON (S3C64XX_GPJ_BASE + 0x00)
-#define S3C64XX_GPJDAT (S3C64XX_GPJ_BASE + 0x04)
-#define S3C64XX_GPJPUD (S3C64XX_GPJ_BASE + 0x08)
-#define S3C64XX_GPJCONSLP (S3C64XX_GPJ_BASE + 0x0c)
-#define S3C64XX_GPJPUDSLP (S3C64XX_GPJ_BASE + 0x10)
-
-#define S3C64XX_GPJ_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
-#define S3C64XX_GPJ_INPUT(__gpio) (0x0 << ((__gpio) * 2))
-#define S3C64XX_GPJ_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPJ0_VD16 (0x02 << 0)
-#define S3C64XX_GPJ1_VD17 (0x02 << 2)
-#define S3C64XX_GPJ2_VD18 (0x02 << 4)
-#define S3C64XX_GPJ3_VD19 (0x02 << 6)
-#define S3C64XX_GPJ4_VD20 (0x02 << 8)
-#define S3C64XX_GPJ5_VD21 (0x02 << 10)
-#define S3C64XX_GPJ6_VD22 (0x02 << 12)
-#define S3C64XX_GPJ7_VD23 (0x02 << 14)
-#define S3C64XX_GPJ8_LCD_HSYNC (0x02 << 16)
-#define S3C64XX_GPJ9_LCD_VSYNC (0x02 << 18)
-#define S3C64XX_GPJ10_LCD_VDEN (0x02 << 20)
-#define S3C64XX_GPJ11_LCD_VCLK (0x02 << 22)
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h
deleted file mode 100644
index 569e7612088..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank N register and configuration 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.
-*/
-
-#define S3C64XX_GPNCON (S3C64XX_GPN_BASE + 0x00)
-#define S3C64XX_GPNDAT (S3C64XX_GPN_BASE + 0x04)
-#define S3C64XX_GPNPUD (S3C64XX_GPN_BASE + 0x08)
-
-#define S3C64XX_GPN_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
-#define S3C64XX_GPN_INPUT(__gpio) (0x0 << ((__gpio) * 2))
-#define S3C64XX_GPN_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPN0_EINT0 (0x02 << 0)
-#define S3C64XX_GPN0_KP_ROW0 (0x03 << 0)
-
-#define S3C64XX_GPN1_EINT1 (0x02 << 2)
-#define S3C64XX_GPN1_KP_ROW1 (0x03 << 2)
-
-#define S3C64XX_GPN2_EINT2 (0x02 << 4)
-#define S3C64XX_GPN2_KP_ROW2 (0x03 << 4)
-
-#define S3C64XX_GPN3_EINT3 (0x02 << 6)
-#define S3C64XX_GPN3_KP_ROW3 (0x03 << 6)
-
-#define S3C64XX_GPN4_EINT4 (0x02 << 8)
-#define S3C64XX_GPN4_KP_ROW4 (0x03 << 8)
-
-#define S3C64XX_GPN5_EINT5 (0x02 << 10)
-#define S3C64XX_GPN5_KP_ROW5 (0x03 << 10)
-
-#define S3C64XX_GPN6_EINT6 (0x02 << 12)
-#define S3C64XX_GPN6_KP_ROW6 (0x03 << 12)
-
-#define S3C64XX_GPN7_EINT7 (0x02 << 14)
-#define S3C64XX_GPN7_KP_ROW7 (0x03 << 14)
-
-#define S3C64XX_GPN8_EINT8 (0x02 << 16)
-#define S3C64XX_GPN9_EINT9 (0x02 << 18)
-#define S3C64XX_GPN10_EINT10 (0x02 << 20)
-#define S3C64XX_GPN11_EINT11 (0x02 << 22)
-#define S3C64XX_GPN12_EINT12 (0x02 << 24)
-#define S3C64XX_GPN13_EINT13 (0x02 << 26)
-#define S3C64XX_GPN14_EINT14 (0x02 << 28)
-#define S3C64XX_GPN15_EINT15 (0x02 << 30)
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h
deleted file mode 100644
index b09e12954b5..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank O register and configuration 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.
-*/
-
-#define S3C64XX_GPOCON (S3C64XX_GPO_BASE + 0x00)
-#define S3C64XX_GPODAT (S3C64XX_GPO_BASE + 0x04)
-#define S3C64XX_GPOPUD (S3C64XX_GPO_BASE + 0x08)
-#define S3C64XX_GPOCONSLP (S3C64XX_GPO_BASE + 0x0c)
-#define S3C64XX_GPOPUDSLP (S3C64XX_GPO_BASE + 0x10)
-
-#define S3C64XX_GPO_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
-#define S3C64XX_GPO_INPUT(__gpio) (0x0 << ((__gpio) * 2))
-#define S3C64XX_GPO_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPO0_MEM0_nCS2 (0x02 << 0)
-#define S3C64XX_GPO0_EINT_G7_0 (0x03 << 0)
-
-#define S3C64XX_GPO1_MEM0_nCS3 (0x02 << 2)
-#define S3C64XX_GPO1_EINT_G7_1 (0x03 << 2)
-
-#define S3C64XX_GPO2_MEM0_nCS4 (0x02 << 4)
-#define S3C64XX_GPO2_EINT_G7_2 (0x03 << 4)
-
-#define S3C64XX_GPO3_MEM0_nCS5 (0x02 << 6)
-#define S3C64XX_GPO3_EINT_G7_3 (0x03 << 6)
-
-#define S3C64XX_GPO4_EINT_G7_4 (0x03 << 8)
-
-#define S3C64XX_GPO5_EINT_G7_5 (0x03 << 10)
-
-#define S3C64XX_GPO6_MEM0_ADDR6 (0x02 << 12)
-#define S3C64XX_GPO6_EINT_G7_6 (0x03 << 12)
-
-#define S3C64XX_GPO7_MEM0_ADDR7 (0x02 << 14)
-#define S3C64XX_GPO7_EINT_G7_7 (0x03 << 14)
-
-#define S3C64XX_GPO8_MEM0_ADDR8 (0x02 << 16)
-#define S3C64XX_GPO8_EINT_G7_8 (0x03 << 16)
-
-#define S3C64XX_GPO9_MEM0_ADDR9 (0x02 << 18)
-#define S3C64XX_GPO9_EINT_G7_9 (0x03 << 18)
-
-#define S3C64XX_GPO10_MEM0_ADDR10 (0x02 << 20)
-#define S3C64XX_GPO10_EINT_G7_10 (0x03 << 20)
-
-#define S3C64XX_GPO11_MEM0_ADDR11 (0x02 << 22)
-#define S3C64XX_GPO11_EINT_G7_11 (0x03 << 22)
-
-#define S3C64XX_GPO12_MEM0_ADDR12 (0x02 << 24)
-#define S3C64XX_GPO12_EINT_G7_12 (0x03 << 24)
-
-#define S3C64XX_GPO13_MEM0_ADDR13 (0x02 << 26)
-#define S3C64XX_GPO13_EINT_G7_13 (0x03 << 26)
-
-#define S3C64XX_GPO14_MEM0_ADDR14 (0x02 << 28)
-#define S3C64XX_GPO14_EINT_G7_14 (0x03 << 28)
-
-#define S3C64XX_GPO15_MEM0_ADDR15 (0x02 << 30)
-#define S3C64XX_GPO15_EINT_G7_15 (0x03 << 30)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h
deleted file mode 100644
index 92f00517926..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank P register and configuration 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.
-*/
-
-#define S3C64XX_GPPCON (S3C64XX_GPP_BASE + 0x00)
-#define S3C64XX_GPPDAT (S3C64XX_GPP_BASE + 0x04)
-#define S3C64XX_GPPPUD (S3C64XX_GPP_BASE + 0x08)
-#define S3C64XX_GPPCONSLP (S3C64XX_GPP_BASE + 0x0c)
-#define S3C64XX_GPPPUDSLP (S3C64XX_GPP_BASE + 0x10)
-
-#define S3C64XX_GPP_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
-#define S3C64XX_GPP_INPUT(__gpio) (0x0 << ((__gpio) * 2))
-#define S3C64XX_GPP_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPP0_MEM0_ADDRV (0x02 << 0)
-#define S3C64XX_GPP0_EINT_G8_0 (0x03 << 0)
-
-#define S3C64XX_GPP1_MEM0_SMCLK (0x02 << 2)
-#define S3C64XX_GPP1_EINT_G8_1 (0x03 << 2)
-
-#define S3C64XX_GPP2_MEM0_nWAIT (0x02 << 4)
-#define S3C64XX_GPP2_EINT_G8_2 (0x03 << 4)
-
-#define S3C64XX_GPP3_MEM0_RDY0_ALE (0x02 << 6)
-#define S3C64XX_GPP3_EINT_G8_3 (0x03 << 6)
-
-#define S3C64XX_GPP4_MEM0_RDY1_CLE (0x02 << 8)
-#define S3C64XX_GPP4_EINT_G8_4 (0x03 << 8)
-
-#define S3C64XX_GPP5_MEM0_INTsm0_FWE (0x02 << 10)
-#define S3C64XX_GPP5_EINT_G8_5 (0x03 << 10)
-
-#define S3C64XX_GPP6_MEM0_(null) (0x02 << 12)
-#define S3C64XX_GPP6_EINT_G8_6 (0x03 << 12)
-
-#define S3C64XX_GPP7_MEM0_INTsm1_FRE (0x02 << 14)
-#define S3C64XX_GPP7_EINT_G8_7 (0x03 << 14)
-
-#define S3C64XX_GPP8_MEM0_RPn_RnB (0x02 << 16)
-#define S3C64XX_GPP8_EINT_G8_8 (0x03 << 16)
-
-#define S3C64XX_GPP9_MEM0_ATA_RESET (0x02 << 18)
-#define S3C64XX_GPP9_EINT_G8_9 (0x03 << 18)
-
-#define S3C64XX_GPP10_MEM0_ATA_INPACK (0x02 << 20)
-#define S3C64XX_GPP10_EINT_G8_10 (0x03 << 20)
-
-#define S3C64XX_GPP11_MEM0_ATA_REG (0x02 << 22)
-#define S3C64XX_GPP11_EINT_G8_11 (0x03 << 22)
-
-#define S3C64XX_GPP12_MEM0_ATA_WE (0x02 << 24)
-#define S3C64XX_GPP12_EINT_G8_12 (0x03 << 24)
-
-#define S3C64XX_GPP13_MEM0_ATA_OE (0x02 << 26)
-#define S3C64XX_GPP13_EINT_G8_13 (0x03 << 26)
-
-#define S3C64XX_GPP14_MEM0_ATA_CD (0x02 << 28)
-#define S3C64XX_GPP14_EINT_G8_14 (0x03 << 28)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h b/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h
deleted file mode 100644
index 565e60aaee4..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * GPIO Bank Q register and configuration 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.
-*/
-
-#define S3C64XX_GPQCON (S3C64XX_GPQ_BASE + 0x00)
-#define S3C64XX_GPQDAT (S3C64XX_GPQ_BASE + 0x04)
-#define S3C64XX_GPQPUD (S3C64XX_GPQ_BASE + 0x08)
-#define S3C64XX_GPQCONSLP (S3C64XX_GPQ_BASE + 0x0c)
-#define S3C64XX_GPQPUDSLP (S3C64XX_GPQ_BASE + 0x10)
-
-#define S3C64XX_GPQ_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
-#define S3C64XX_GPQ_INPUT(__gpio) (0x0 << ((__gpio) * 2))
-#define S3C64XX_GPQ_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
-
-#define S3C64XX_GPQ0_MEM0_ADDR18_RAS (0x02 << 0)
-#define S3C64XX_GPQ0_EINT_G9_0 (0x03 << 0)
-
-#define S3C64XX_GPQ1_MEM0_ADDR19_CAS (0x02 << 2)
-#define S3C64XX_GPQ1_EINT_G9_1 (0x03 << 2)
-
-#define S3C64XX_GPQ2_EINT_G9_2 (0x03 << 4)
-
-#define S3C64XX_GPQ3_EINT_G9_3 (0x03 << 6)
-
-#define S3C64XX_GPQ4_EINT_G9_4 (0x03 << 8)
-
-#define S3C64XX_GPQ5_EINT_G9_5 (0x03 << 10)
-
-#define S3C64XX_GPQ6_EINT_G9_6 (0x03 << 12)
-
-#define S3C64XX_GPQ7_MEM0_ADDR17_WENDMC (0x02 << 14)
-#define S3C64XX_GPQ7_EINT_G9_7 (0x03 << 14)
-
-#define S3C64XX_GPQ8_MEM0_ADDR16_APDMC (0x02 << 16)
-#define S3C64XX_GPQ8_EINT_G9_8 (0x03 << 16)
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/irqs.h b/arch/arm/plat-s3c64xx/include/plat/irqs.h
deleted file mode 100644
index 7956fd3bb19..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/irqs.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/mach/irqs.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Common IRQ support
- */
-
-#ifndef __ASM_PLAT_S3C64XX_IRQS_H
-#define __ASM_PLAT_S3C64XX_IRQS_H __FILE__
-
-/* we keep the first set of CPU IRQs out of the range of
- * the ISA space, so that the PC104 has them to itself
- * and we don't end up having to do horrible things to the
- * standard ISA drivers....
- *
- * note, since we're using the VICs, our start must be a
- * mulitple of 32 to allow the common code to work
- */
-
-#define S3C_IRQ_OFFSET (32)
-
-#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET)
-
-#define S3C_VIC0_BASE S3C_IRQ(0)
-#define S3C_VIC1_BASE S3C_IRQ(32)
-
-/* UART interrupts, each UART has 4 intterupts per channel so
- * use the space between the ISA and S3C main interrupts. Note, these
- * are not in the same order as the S3C24XX series! */
-
-#define IRQ_S3CUART_BASE0 (16)
-#define IRQ_S3CUART_BASE1 (20)
-#define IRQ_S3CUART_BASE2 (24)
-#define IRQ_S3CUART_BASE3 (28)
-
-#define UART_IRQ_RXD (0)
-#define UART_IRQ_ERR (1)
-#define UART_IRQ_TXD (2)
-#define UART_IRQ_MODEM (3)
-
-#define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
-
-/* VIC based IRQs */
-
-#define S3C64XX_IRQ_VIC0(x) (S3C_VIC0_BASE + (x))
-#define S3C64XX_IRQ_VIC1(x) (S3C_VIC1_BASE + (x))
-
-/* VIC0 */
-
-#define IRQ_EINT0_3 S3C64XX_IRQ_VIC0(0)
-#define IRQ_EINT4_11 S3C64XX_IRQ_VIC0(1)
-#define IRQ_RTC_TIC S3C64XX_IRQ_VIC0(2)
-#define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3)
-#define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4)
-#define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5)
-#define IRQ_S3C6410_IIC1 S3C64XX_IRQ_VIC0(5)
-#define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6)
-#define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6)
-#define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7)
-#define IRQ_S3C6410_G3D S3C64XX_IRQ_VIC0(8)
-#define IRQ_S3C6400_CAMIF_WE_P S3C64XX_IRQ_VIC0(8)
-#define IRQ_POST0 S3C64XX_IRQ_VIC0(9)
-#define IRQ_ROTATOR S3C64XX_IRQ_VIC0(10)
-#define IRQ_2D S3C64XX_IRQ_VIC0(11)
-#define IRQ_TVENC S3C64XX_IRQ_VIC0(12)
-#define IRQ_SCALER S3C64XX_IRQ_VIC0(13)
-#define IRQ_BATF S3C64XX_IRQ_VIC0(14)
-#define IRQ_JPEG S3C64XX_IRQ_VIC0(15)
-#define IRQ_MFC S3C64XX_IRQ_VIC0(16)
-#define IRQ_SDMA0 S3C64XX_IRQ_VIC0(17)
-#define IRQ_SDMA1 S3C64XX_IRQ_VIC0(18)
-#define IRQ_ARM_DMAERR S3C64XX_IRQ_VIC0(19)
-#define IRQ_ARM_DMA S3C64XX_IRQ_VIC0(20)
-#define IRQ_ARM_DMAS S3C64XX_IRQ_VIC0(21)
-#define IRQ_KEYPAD S3C64XX_IRQ_VIC0(22)
-#define IRQ_TIMER0_VIC S3C64XX_IRQ_VIC0(23)
-#define IRQ_TIMER1_VIC S3C64XX_IRQ_VIC0(24)
-#define IRQ_TIMER2_VIC S3C64XX_IRQ_VIC0(25)
-#define IRQ_WDT S3C64XX_IRQ_VIC0(26)
-#define IRQ_TIMER3_VIC S3C64XX_IRQ_VIC0(27)
-#define IRQ_TIMER4_VIC S3C64XX_IRQ_VIC0(28)
-#define IRQ_LCD_FIFO S3C64XX_IRQ_VIC0(29)
-#define IRQ_LCD_VSYNC S3C64XX_IRQ_VIC0(30)
-#define IRQ_LCD_SYSTEM S3C64XX_IRQ_VIC0(31)
-
-/* VIC1 */
-
-#define IRQ_EINT12_19 S3C64XX_IRQ_VIC1(0)
-#define IRQ_EINT20_27 S3C64XX_IRQ_VIC1(1)
-#define IRQ_PCM0 S3C64XX_IRQ_VIC1(2)
-#define IRQ_PCM1 S3C64XX_IRQ_VIC1(3)
-#define IRQ_AC97 S3C64XX_IRQ_VIC1(4)
-#define IRQ_UART0 S3C64XX_IRQ_VIC1(5)
-#define IRQ_UART1 S3C64XX_IRQ_VIC1(6)
-#define IRQ_UART2 S3C64XX_IRQ_VIC1(7)
-#define IRQ_UART3 S3C64XX_IRQ_VIC1(8)
-#define IRQ_DMA0 S3C64XX_IRQ_VIC1(9)
-#define IRQ_DMA1 S3C64XX_IRQ_VIC1(10)
-#define IRQ_ONENAND0 S3C64XX_IRQ_VIC1(11)
-#define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12)
-#define IRQ_NFC S3C64XX_IRQ_VIC1(13)
-#define IRQ_CFCON S3C64XX_IRQ_VIC1(14)
-#define IRQ_USBH S3C64XX_IRQ_VIC1(15)
-#define IRQ_SPI0 S3C64XX_IRQ_VIC1(16)
-#define IRQ_SPI1 S3C64XX_IRQ_VIC1(17)
-#define IRQ_IIC S3C64XX_IRQ_VIC1(18)
-#define IRQ_HSItx S3C64XX_IRQ_VIC1(19)
-#define IRQ_HSIrx S3C64XX_IRQ_VIC1(20)
-#define IRQ_RESERVED S3C64XX_IRQ_VIC1(21)
-#define IRQ_MSM S3C64XX_IRQ_VIC1(22)
-#define IRQ_HOSTIF S3C64XX_IRQ_VIC1(23)
-#define IRQ_HSMMC0 S3C64XX_IRQ_VIC1(24)
-#define IRQ_HSMMC1 S3C64XX_IRQ_VIC1(25)
-#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */
-#define IRQ_OTG S3C64XX_IRQ_VIC1(26)
-#define IRQ_IRDA S3C64XX_IRQ_VIC1(27)
-#define IRQ_RTC_ALARM S3C64XX_IRQ_VIC1(28)
-#define IRQ_SEC S3C64XX_IRQ_VIC1(29)
-#define IRQ_PENDN S3C64XX_IRQ_VIC1(30)
-#define IRQ_TC IRQ_PENDN
-#define IRQ_ADC S3C64XX_IRQ_VIC1(31)
-
-#define S3C64XX_TIMER_IRQ(x) S3C_IRQ(64 + (x))
-
-#define IRQ_TIMER0 S3C64XX_TIMER_IRQ(0)
-#define IRQ_TIMER1 S3C64XX_TIMER_IRQ(1)
-#define IRQ_TIMER2 S3C64XX_TIMER_IRQ(2)
-#define IRQ_TIMER3 S3C64XX_TIMER_IRQ(3)
-#define IRQ_TIMER4 S3C64XX_TIMER_IRQ(4)
-
-/* compatibility for device defines */
-
-#define IRQ_IIC1 IRQ_S3C6410_IIC1
-
-/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
- * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
- * which we place after the pair of VICs. */
-
-#define S3C_IRQ_EINT_BASE S3C_IRQ(64+5)
-
-#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
-#define IRQ_EINT(x) S3C_EINT(x)
-#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0))
-
-/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
- * that they are sourced from the GPIO pins but with a different scheme for
- * priority and source indication.
- *
- * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
- * interrupts, but for historical reasons they are kept apart from these
- * next interrupts.
- *
- * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
- * machine specific support files.
- */
-
-#define IRQ_EINT_GROUP1_NR (15)
-#define IRQ_EINT_GROUP2_NR (8)
-#define IRQ_EINT_GROUP3_NR (5)
-#define IRQ_EINT_GROUP4_NR (14)
-#define IRQ_EINT_GROUP5_NR (7)
-#define IRQ_EINT_GROUP6_NR (10)
-#define IRQ_EINT_GROUP7_NR (16)
-#define IRQ_EINT_GROUP8_NR (15)
-#define IRQ_EINT_GROUP9_NR (9)
-
-#define IRQ_EINT_GROUP_BASE S3C_EINT(28)
-#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0x00)
-#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
-#define IRQ_EINT_GROUP3_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
-#define IRQ_EINT_GROUP4_BASE (IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
-#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
-#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
-#define IRQ_EINT_GROUP7_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
-#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
-#define IRQ_EINT_GROUP9_BASE (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
-
-#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##_BASE + (no))
-
-/* Define a group of interrupts for board-specific use (eg, for MFD
- * interrupt controllers). */
-#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
-
-#define IRQ_BOARD_NR 16
-
-#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
-
-/* Set the default NR_IRQS */
-
-#define NR_IRQS (IRQ_BOARD_END + 1)
-
-#endif /* __ASM_PLAT_S3C64XX_IRQS_H */
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/pm-core.h b/arch/arm/plat-s3c64xx/include/plat/pm-core.h
deleted file mode 100644
index d347de3ba0d..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/pm-core.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/include/plat/pm-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX - PM core support for arch/arm/plat-s3c/pm.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <plat/regs-gpio.h>
-
-static inline void s3c_pm_debug_init_uart(void)
-{
- u32 tmp = __raw_readl(S3C_PCLK_GATE);
-
- /* As a note, since the S3C64XX UARTs generally have multiple
- * clock sources, we simply enable PCLK at the moment and hope
- * that the resume settings for the UART are suitable for the
- * use with PCLK.
- */
-
- tmp |= S3C_CLKCON_PCLK_UART0;
- tmp |= S3C_CLKCON_PCLK_UART1;
- tmp |= S3C_CLKCON_PCLK_UART2;
- tmp |= S3C_CLKCON_PCLK_UART3;
-
- __raw_writel(tmp, S3C_PCLK_GATE);
- udelay(10);
-}
-
-static inline void s3c_pm_arch_prepare_irqs(void)
-{
- /* VIC should have already been taken care of */
-
- /* clear any pending EINT0 interrupts */
- __raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
-}
-
-static inline void s3c_pm_arch_stop_clocks(void)
-{
-}
-
-static inline void s3c_pm_arch_show_resume_irqs(void)
-{
-}
-
-/* make these defines, we currently do not have any need to change
- * the IRQ wake controls depending on the CPU we are running on */
-
-#define s3c_irqwake_eintallow ((1 << 28) - 1)
-#define s3c_irqwake_intallow (0)
-
-static inline void s3c_pm_arch_update_uart(void __iomem *regs,
- struct pm_uart_save *save)
-{
- u32 ucon = __raw_readl(regs + S3C2410_UCON);
- u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
- u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
- u32 new_ucon;
- u32 delta;
-
- /* S3C64XX UART blocks only support level interrupts, so ensure that
- * when we restore unused UART blocks we force the level interrupt
- * settigs. */
- save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
-
- /* We have a constraint on changing the clock type of the UART
- * between UCLKx and PCLK, so ensure that when we restore UCON
- * that the CLK field is correctly modified if the bootloader
- * has changed anything.
- */
- if (ucon_clk != save_clk) {
- new_ucon = save->ucon;
- delta = ucon_clk ^ save_clk;
-
- /* change from UCLKx => wrong PCLK,
- * either UCLK can be tested for by a bit-test
- * with UCLK0 */
- if (ucon_clk & S3C6400_UCON_UCLK0 &&
- !(save_clk & S3C6400_UCON_UCLK0) &&
- delta & S3C6400_UCON_PCLK2) {
- new_ucon &= ~S3C6400_UCON_UCLK0;
- } else if (delta == S3C6400_UCON_PCLK2) {
- /* as an precaution, don't change from
- * PCLK2 => PCLK or vice-versa */
- new_ucon ^= S3C6400_UCON_PCLK2;
- }
-
- S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
- ucon, new_ucon, save->ucon);
- save->ucon = new_ucon;
- }
-}
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
deleted file mode 100644
index ff46e7fa957..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/regs-clock.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX clock register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_REGS_CLOCK_H
-#define __PLAT_REGS_CLOCK_H __FILE__
-
-#define S3C_CLKREG(x) (S3C_VA_SYS + (x))
-
-#define S3C_APLL_LOCK S3C_CLKREG(0x00)
-#define S3C_MPLL_LOCK S3C_CLKREG(0x04)
-#define S3C_EPLL_LOCK S3C_CLKREG(0x08)
-#define S3C_APLL_CON S3C_CLKREG(0x0C)
-#define S3C_MPLL_CON S3C_CLKREG(0x10)
-#define S3C_EPLL_CON0 S3C_CLKREG(0x14)
-#define S3C_EPLL_CON1 S3C_CLKREG(0x18)
-#define S3C_CLK_SRC S3C_CLKREG(0x1C)
-#define S3C_CLK_DIV0 S3C_CLKREG(0x20)
-#define S3C_CLK_DIV1 S3C_CLKREG(0x24)
-#define S3C_CLK_DIV2 S3C_CLKREG(0x28)
-#define S3C_CLK_OUT S3C_CLKREG(0x2C)
-#define S3C_HCLK_GATE S3C_CLKREG(0x30)
-#define S3C_PCLK_GATE S3C_CLKREG(0x34)
-#define S3C_SCLK_GATE S3C_CLKREG(0x38)
-#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
-
-/* CLKDIV0 */
-#define S3C6400_CLKDIV0_MFC_MASK (0xf << 28)
-#define S3C6400_CLKDIV0_MFC_SHIFT (28)
-#define S3C6400_CLKDIV0_JPEG_MASK (0xf << 24)
-#define S3C6400_CLKDIV0_JPEG_SHIFT (24)
-#define S3C6400_CLKDIV0_CAM_MASK (0xf << 20)
-#define S3C6400_CLKDIV0_CAM_SHIFT (20)
-#define S3C6400_CLKDIV0_SECURITY_MASK (0x3 << 18)
-#define S3C6400_CLKDIV0_SECURITY_SHIFT (18)
-#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
-#define S3C6400_CLKDIV0_PCLK_SHIFT (12)
-#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9)
-#define S3C6400_CLKDIV0_HCLK2_SHIFT (9)
-#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8)
-#define S3C6400_CLKDIV0_HCLK_SHIFT (8)
-#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4)
-#define S3C6400_CLKDIV0_MPLL_SHIFT (4)
-#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0)
-#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0)
-#define S3C6400_CLKDIV0_ARM_SHIFT (0)
-
-/* CLKDIV1 */
-#define S3C6410_CLKDIV1_FIMC_MASK (0xf << 24)
-#define S3C6410_CLKDIV1_FIMC_SHIFT (24)
-#define S3C6400_CLKDIV1_UHOST_MASK (0xf << 20)
-#define S3C6400_CLKDIV1_UHOST_SHIFT (20)
-#define S3C6400_CLKDIV1_SCALER_MASK (0xf << 16)
-#define S3C6400_CLKDIV1_SCALER_SHIFT (16)
-#define S3C6400_CLKDIV1_LCD_MASK (0xf << 12)
-#define S3C6400_CLKDIV1_LCD_SHIFT (12)
-#define S3C6400_CLKDIV1_MMC2_MASK (0xf << 8)
-#define S3C6400_CLKDIV1_MMC2_SHIFT (8)
-#define S3C6400_CLKDIV1_MMC1_MASK (0xf << 4)
-#define S3C6400_CLKDIV1_MMC1_SHIFT (4)
-#define S3C6400_CLKDIV1_MMC0_MASK (0xf << 0)
-#define S3C6400_CLKDIV1_MMC0_SHIFT (0)
-
-/* CLKDIV2 */
-#define S3C6410_CLKDIV2_AUDIO2_MASK (0xf << 24)
-#define S3C6410_CLKDIV2_AUDIO2_SHIFT (24)
-#define S3C6400_CLKDIV2_IRDA_MASK (0xf << 20)
-#define S3C6400_CLKDIV2_IRDA_SHIFT (20)
-#define S3C6400_CLKDIV2_UART_MASK (0xf << 16)
-#define S3C6400_CLKDIV2_UART_SHIFT (16)
-#define S3C6400_CLKDIV2_AUDIO1_MASK (0xf << 12)
-#define S3C6400_CLKDIV2_AUDIO1_SHIFT (12)
-#define S3C6400_CLKDIV2_AUDIO0_MASK (0xf << 8)
-#define S3C6400_CLKDIV2_AUDIO0_SHIFT (8)
-#define S3C6400_CLKDIV2_SPI1_MASK (0xf << 4)
-#define S3C6400_CLKDIV2_SPI1_SHIFT (4)
-#define S3C6400_CLKDIV2_SPI0_MASK (0xf << 0)
-#define S3C6400_CLKDIV2_SPI0_SHIFT (0)
-
-/* HCLK GATE Registers */
-#define S3C_CLKCON_HCLK_3DSE (1<<31)
-#define S3C_CLKCON_HCLK_UHOST (1<<29)
-#define S3C_CLKCON_HCLK_SECUR (1<<28)
-#define S3C_CLKCON_HCLK_SDMA1 (1<<27)
-#define S3C_CLKCON_HCLK_SDMA0 (1<<26)
-#define S3C_CLKCON_HCLK_IROM (1<<25)
-#define S3C_CLKCON_HCLK_DDR1 (1<<24)
-#define S3C_CLKCON_HCLK_DDR0 (1<<23)
-#define S3C_CLKCON_HCLK_MEM1 (1<<22)
-#define S3C_CLKCON_HCLK_MEM0 (1<<21)
-#define S3C_CLKCON_HCLK_USB (1<<20)
-#define S3C_CLKCON_HCLK_HSMMC2 (1<<19)
-#define S3C_CLKCON_HCLK_HSMMC1 (1<<18)
-#define S3C_CLKCON_HCLK_HSMMC0 (1<<17)
-#define S3C_CLKCON_HCLK_MDP (1<<16)
-#define S3C_CLKCON_HCLK_DHOST (1<<15)
-#define S3C_CLKCON_HCLK_IHOST (1<<14)
-#define S3C_CLKCON_HCLK_DMA1 (1<<13)
-#define S3C_CLKCON_HCLK_DMA0 (1<<12)
-#define S3C_CLKCON_HCLK_JPEG (1<<11)
-#define S3C_CLKCON_HCLK_CAMIF (1<<10)
-#define S3C_CLKCON_HCLK_SCALER (1<<9)
-#define S3C_CLKCON_HCLK_2D (1<<8)
-#define S3C_CLKCON_HCLK_TV (1<<7)
-#define S3C_CLKCON_HCLK_POST0 (1<<5)
-#define S3C_CLKCON_HCLK_ROT (1<<4)
-#define S3C_CLKCON_HCLK_LCD (1<<3)
-#define S3C_CLKCON_HCLK_TZIC (1<<2)
-#define S3C_CLKCON_HCLK_INTC (1<<1)
-#define S3C_CLKCON_HCLK_MFC (1<<0)
-
-/* PCLK GATE Registers */
-#define S3C6410_CLKCON_PCLK_I2C1 (1<<27)
-#define S3C6410_CLKCON_PCLK_IIS2 (1<<26)
-#define S3C_CLKCON_PCLK_SKEY (1<<24)
-#define S3C_CLKCON_PCLK_CHIPID (1<<23)
-#define S3C_CLKCON_PCLK_SPI1 (1<<22)
-#define S3C_CLKCON_PCLK_SPI0 (1<<21)
-#define S3C_CLKCON_PCLK_HSIRX (1<<20)
-#define S3C_CLKCON_PCLK_HSITX (1<<19)
-#define S3C_CLKCON_PCLK_GPIO (1<<18)
-#define S3C_CLKCON_PCLK_IIC (1<<17)
-#define S3C_CLKCON_PCLK_IIS1 (1<<16)
-#define S3C_CLKCON_PCLK_IIS0 (1<<15)
-#define S3C_CLKCON_PCLK_AC97 (1<<14)
-#define S3C_CLKCON_PCLK_TZPC (1<<13)
-#define S3C_CLKCON_PCLK_TSADC (1<<12)
-#define S3C_CLKCON_PCLK_KEYPAD (1<<11)
-#define S3C_CLKCON_PCLK_IRDA (1<<10)
-#define S3C_CLKCON_PCLK_PCM1 (1<<9)
-#define S3C_CLKCON_PCLK_PCM0 (1<<8)
-#define S3C_CLKCON_PCLK_PWM (1<<7)
-#define S3C_CLKCON_PCLK_RTC (1<<6)
-#define S3C_CLKCON_PCLK_WDT (1<<5)
-#define S3C_CLKCON_PCLK_UART3 (1<<4)
-#define S3C_CLKCON_PCLK_UART2 (1<<3)
-#define S3C_CLKCON_PCLK_UART1 (1<<2)
-#define S3C_CLKCON_PCLK_UART0 (1<<1)
-#define S3C_CLKCON_PCLK_MFC (1<<0)
-
-/* SCLK GATE Registers */
-#define S3C_CLKCON_SCLK_UHOST (1<<30)
-#define S3C_CLKCON_SCLK_MMC2_48 (1<<29)
-#define S3C_CLKCON_SCLK_MMC1_48 (1<<28)
-#define S3C_CLKCON_SCLK_MMC0_48 (1<<27)
-#define S3C_CLKCON_SCLK_MMC2 (1<<26)
-#define S3C_CLKCON_SCLK_MMC1 (1<<25)
-#define S3C_CLKCON_SCLK_MMC0 (1<<24)
-#define S3C_CLKCON_SCLK_SPI1_48 (1<<23)
-#define S3C_CLKCON_SCLK_SPI0_48 (1<<22)
-#define S3C_CLKCON_SCLK_SPI1 (1<<21)
-#define S3C_CLKCON_SCLK_SPI0 (1<<20)
-#define S3C_CLKCON_SCLK_DAC27 (1<<19)
-#define S3C_CLKCON_SCLK_TV27 (1<<18)
-#define S3C_CLKCON_SCLK_SCALER27 (1<<17)
-#define S3C_CLKCON_SCLK_SCALER (1<<16)
-#define S3C_CLKCON_SCLK_LCD27 (1<<15)
-#define S3C_CLKCON_SCLK_LCD (1<<14)
-#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13)
-#define S3C6410_CLKCON_FIMC (1<<13)
-#define S3C_CLKCON_SCLK_POST0_27 (1<<12)
-#define S3C6400_CLKCON_SCLK_POST1 (1<<11)
-#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11)
-#define S3C_CLKCON_SCLK_POST0 (1<<10)
-#define S3C_CLKCON_SCLK_AUDIO1 (1<<9)
-#define S3C_CLKCON_SCLK_AUDIO0 (1<<8)
-#define S3C_CLKCON_SCLK_SECUR (1<<7)
-#define S3C_CLKCON_SCLK_IRDA (1<<6)
-#define S3C_CLKCON_SCLK_UART (1<<5)
-#define S3C_CLKCON_SCLK_ONENAND (1<<4)
-#define S3C_CLKCON_SCLK_MFC (1<<3)
-#define S3C_CLKCON_SCLK_CAM (1<<2)
-#define S3C_CLKCON_SCLK_JPEG (1<<1)
-
-/* CLKSRC */
-
-#define S3C6400_CLKSRC_APLL_MOUT (1 << 0)
-#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1)
-#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2)
-#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0)
-#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1)
-#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
-#define S3C6400_CLKSRC_MFC (1 << 4)
-
-#define S3C6410_CLKSRC_TV27_MASK (0x1 << 31)
-#define S3C6410_CLKSRC_TV27_SHIFT (31)
-#define S3C6410_CLKSRC_DAC27_MASK (0x1 << 30)
-#define S3C6410_CLKSRC_DAC27_SHIFT (30)
-#define S3C6400_CLKSRC_SCALER_MASK (0x3 << 28)
-#define S3C6400_CLKSRC_SCALER_SHIFT (28)
-#define S3C6400_CLKSRC_LCD_MASK (0x3 << 26)
-#define S3C6400_CLKSRC_LCD_SHIFT (26)
-#define S3C6400_CLKSRC_IRDA_MASK (0x3 << 24)
-#define S3C6400_CLKSRC_IRDA_SHIFT (24)
-#define S3C6400_CLKSRC_MMC2_MASK (0x3 << 22)
-#define S3C6400_CLKSRC_MMC2_SHIFT (22)
-#define S3C6400_CLKSRC_MMC1_MASK (0x3 << 20)
-#define S3C6400_CLKSRC_MMC1_SHIFT (20)
-#define S3C6400_CLKSRC_MMC0_MASK (0x3 << 18)
-#define S3C6400_CLKSRC_MMC0_SHIFT (18)
-#define S3C6400_CLKSRC_SPI1_MASK (0x3 << 16)
-#define S3C6400_CLKSRC_SPI1_SHIFT (16)
-#define S3C6400_CLKSRC_SPI0_MASK (0x3 << 14)
-#define S3C6400_CLKSRC_SPI0_SHIFT (14)
-#define S3C6400_CLKSRC_UART_MASK (0x1 << 13)
-#define S3C6400_CLKSRC_UART_SHIFT (13)
-#define S3C6400_CLKSRC_AUDIO1_MASK (0x7 << 10)
-#define S3C6400_CLKSRC_AUDIO1_SHIFT (10)
-#define S3C6400_CLKSRC_AUDIO0_MASK (0x7 << 7)
-#define S3C6400_CLKSRC_AUDIO0_SHIFT (7)
-#define S3C6400_CLKSRC_UHOST_MASK (0x3 << 5)
-#define S3C6400_CLKSRC_UHOST_SHIFT (5)
-
-
-#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/plat-s3c64xx/include/plat/s3c6400.h b/arch/arm/plat-s3c64xx/include/plat/s3c6400.h
deleted file mode 100644
index 11f2e1e119b..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/s3c6400.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/s3c6400.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * Header file for s3c6400 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Common init code for S3C6400 related SoCs */
-
-extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-extern void s3c6400_register_clocks(unsigned armclk_divlimit);
-extern void s3c6400_setup_clocks(void);
-
-#ifdef CONFIG_CPU_S3C6400
-
-extern int s3c6400_init(void);
-extern void s3c6400_init_irq(void);
-extern void s3c6400_map_io(void);
-extern void s3c6400_init_clocks(int xtal);
-
-#define s3c6400_init_uarts s3c6400_common_init_uarts
-
-#else
-#define s3c6400_init_clocks NULL
-#define s3c6400_init_uarts NULL
-#define s3c6400_map_io NULL
-#define s3c6400_init NULL
-#endif
-
diff --git a/arch/arm/plat-s3c64xx/include/plat/s3c6410.h b/arch/arm/plat-s3c64xx/include/plat/s3c6410.h
deleted file mode 100644
index 50dcdd6f680..00000000000
--- a/arch/arm/plat-s3c64xx/include/plat/s3c6410.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/s3c6410.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * Header file for s3c6410 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifdef CONFIG_CPU_S3C6410
-
-extern int s3c6410_init(void);
-extern void s3c6410_init_irq(void);
-extern void s3c6410_map_io(void);
-extern void s3c6410_init_clocks(int xtal);
-
-#define s3c6410_init_uarts s3c6400_common_init_uarts
-
-#else
-#define s3c6410_init_clocks NULL
-#define s3c6410_init_uarts NULL
-#define s3c6410_map_io NULL
-#define s3c6410_init NULL
-#endif
diff --git a/arch/arm/plat-s3c64xx/irq-eint.c b/arch/arm/plat-s3c64xx/irq-eint.c
deleted file mode 100644
index ebdf183a091..00000000000
--- a/arch/arm/plat-s3c64xx/irq-eint.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* arch/arm/plat-s3c64xx/irq-eint.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Interrupt handling for IRQ_EINT(x)
- *
- * This program is free software; you can 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/sysdev.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <asm/hardware/vic.h>
-
-#include <plat/regs-irqtype.h>
-#include <plat/regs-gpio.h>
-#include <plat/gpio-cfg.h>
-
-#include <mach/map.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-#define eint_offset(irq) ((irq) - IRQ_EINT(0))
-#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
-
-static inline void s3c_irq_eint_mask(unsigned int irq)
-{
- u32 mask;
-
- mask = __raw_readl(S3C64XX_EINT0MASK);
- mask |= eint_irq_to_bit(irq);
- __raw_writel(mask, S3C64XX_EINT0MASK);
-}
-
-static void s3c_irq_eint_unmask(unsigned int irq)
-{
- u32 mask;
-
- mask = __raw_readl(S3C64XX_EINT0MASK);
- mask &= ~eint_irq_to_bit(irq);
- __raw_writel(mask, S3C64XX_EINT0MASK);
-}
-
-static inline void s3c_irq_eint_ack(unsigned int irq)
-{
- __raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND);
-}
-
-static void s3c_irq_eint_maskack(unsigned int irq)
-{
- /* compiler should in-line these */
- s3c_irq_eint_mask(irq);
- s3c_irq_eint_ack(irq);
-}
-
-static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
-{
- int offs = eint_offset(irq);
- int pin, pin_val;
- int shift;
- u32 ctrl, mask;
- u32 newvalue = 0;
- void __iomem *reg;
-
- if (offs > 27)
- return -EINVAL;
-
- if (offs <= 15)
- reg = S3C64XX_EINT0CON0;
- else
- reg = S3C64XX_EINT0CON1;
-
- switch (type) {
- case IRQ_TYPE_NONE:
- printk(KERN_WARNING "No edge setting!\n");
- break;
-
- case IRQ_TYPE_EDGE_RISING:
- newvalue = S3C2410_EXTINT_RISEEDGE;
- break;
-
- case IRQ_TYPE_EDGE_FALLING:
- newvalue = S3C2410_EXTINT_FALLEDGE;
- break;
-
- case IRQ_TYPE_EDGE_BOTH:
- newvalue = S3C2410_EXTINT_BOTHEDGE;
- break;
-
- case IRQ_TYPE_LEVEL_LOW:
- newvalue = S3C2410_EXTINT_LOWLEV;
- break;
-
- case IRQ_TYPE_LEVEL_HIGH:
- newvalue = S3C2410_EXTINT_HILEV;
- break;
-
- default:
- printk(KERN_ERR "No such irq type %d", type);
- return -1;
- }
-
- if (offs <= 15)
- shift = (offs / 2) * 4;
- else
- shift = ((offs - 16) / 2) * 4;
- mask = 0x7 << shift;
-
- ctrl = __raw_readl(reg);
- ctrl &= ~mask;
- ctrl |= newvalue << shift;
- __raw_writel(ctrl, reg);
-
- /* set the GPIO pin appropriately */
-
- if (offs < 16) {
- pin = S3C64XX_GPN(offs);
- pin_val = S3C_GPIO_SFN(2);
- } else if (offs < 23) {
- pin = S3C64XX_GPL(offs + 8 - 16);
- pin_val = S3C_GPIO_SFN(3);
- } else {
- pin = S3C64XX_GPM(offs - 23);
- pin_val = S3C_GPIO_SFN(3);
- }
-
- s3c_gpio_cfgpin(pin, pin_val);
-
- return 0;
-}
-
-static struct irq_chip s3c_irq_eint = {
- .name = "s3c-eint",
- .mask = s3c_irq_eint_mask,
- .unmask = s3c_irq_eint_unmask,
- .mask_ack = s3c_irq_eint_maskack,
- .ack = s3c_irq_eint_ack,
- .set_type = s3c_irq_eint_set_type,
- .set_wake = s3c_irqext_wake,
-};
-
-/* s3c_irq_demux_eint
- *
- * This function demuxes the IRQ from the group0 external interrupts,
- * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
- * the specific handlers s3c_irq_demux_eintX_Y.
- */
-static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
-{
- u32 status = __raw_readl(S3C64XX_EINT0PEND);
- u32 mask = __raw_readl(S3C64XX_EINT0MASK);
- unsigned int irq;
-
- status &= ~mask;
- status >>= start;
- status &= (1 << (end - start + 1)) - 1;
-
- for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
- if (status & 1)
- generic_handle_irq(irq);
-
- status >>= 1;
- }
-}
-
-static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_eint(0, 3);
-}
-
-static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_eint(4, 11);
-}
-
-static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_eint(12, 19);
-}
-
-static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_eint(20, 27);
-}
-
-static int __init s3c64xx_init_irq_eint(void)
-{
- int irq;
-
- for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
- set_irq_chip(irq, &s3c_irq_eint);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
-
- set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
- set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
- set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
- set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
-
- return 0;
-}
-
-arch_initcall(s3c64xx_init_irq_eint);
diff --git a/arch/arm/plat-s3c64xx/irq-pm.c b/arch/arm/plat-s3c64xx/irq-pm.c
deleted file mode 100644
index ca523b5d4c1..00000000000
--- a/arch/arm/plat-s3c64xx/irq-pm.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* arch/arm/plat-s3c64xx/irq-pm.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Interrupt handling Power Management
- *
- * This program is free software; you can 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/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/serial_core.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <mach/map.h>
-
-#include <plat/regs-serial.h>
-#include <plat/regs-timer.h>
-#include <plat/regs-gpio.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-/* We handled all the IRQ types in this code, to save having to make several
- * small files to handle each different type separately. Having the EINT_GRP
- * code here shouldn't be as much bloat as the IRQ table space needed when
- * they are enabled. The added benefit is we ensure that these registers are
- * in the same state as we suspended.
- */
-
-static struct sleep_save irq_save[] = {
- SAVE_ITEM(S3C64XX_PRIORITY),
- SAVE_ITEM(S3C64XX_EINT0CON0),
- SAVE_ITEM(S3C64XX_EINT0CON1),
- SAVE_ITEM(S3C64XX_EINT0FLTCON0),
- SAVE_ITEM(S3C64XX_EINT0FLTCON1),
- SAVE_ITEM(S3C64XX_EINT0FLTCON2),
- SAVE_ITEM(S3C64XX_EINT0FLTCON3),
- SAVE_ITEM(S3C64XX_EINT0MASK),
- SAVE_ITEM(S3C64XX_TINT_CSTAT),
-};
-
-static struct irq_grp_save {
- u32 fltcon;
- u32 con;
- u32 mask;
-} eint_grp_save[5];
-
-static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
-
-static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
-{
- struct irq_grp_save *grp = eint_grp_save;
- int i;
-
- S3C_PMDBG("%s: suspending IRQs\n", __func__);
-
- s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-
- for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
- irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
-
- for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
- grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4));
- grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4));
- grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4));
- }
-
- return 0;
-}
-
-static int s3c64xx_irq_pm_resume(struct sys_device *dev)
-{
- struct irq_grp_save *grp = eint_grp_save;
- int i;
-
- S3C_PMDBG("%s: resuming IRQs\n", __func__);
-
- s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-
- for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
- __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
-
- for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
- __raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4));
- __raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4));
- __raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4));
- }
-
- S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
- return 0;
-}
-
-static struct sysdev_driver s3c64xx_irq_driver = {
- .suspend = s3c64xx_irq_pm_suspend,
- .resume = s3c64xx_irq_pm_resume,
-};
-
-static int __init s3c64xx_irq_pm_init(void)
-{
- return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver);
-}
-
-arch_initcall(s3c64xx_irq_pm_init);
-
diff --git a/arch/arm/plat-s3c64xx/irq.c b/arch/arm/plat-s3c64xx/irq.c
deleted file mode 100644
index 8dc5b6da978..00000000000
--- a/arch/arm/plat-s3c64xx/irq.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* arch/arm/plat-s3c64xx/irq.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Interrupt handling
- *
- * This program is free software; you can 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/serial_core.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <asm/hardware/vic.h>
-
-#include <mach/map.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-timer.h>
-#include <plat/cpu.h>
-
-/* Timer interrupt handling */
-
-static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
-{
- generic_handle_irq(sub_irq);
-}
-
-static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER0);
-}
-
-static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER1);
-}
-
-static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER2);
-}
-
-static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER3);
-}
-
-static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER4);
-}
-
-/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-
-static void s3c_irq_timer_mask(unsigned int irq)
-{
- u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
- reg &= 0x1f; /* mask out pending interrupts */
- reg &= ~(1 << (irq - IRQ_TIMER0));
- __raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_unmask(unsigned int irq)
-{
- u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
- reg &= 0x1f; /* mask out pending interrupts */
- reg |= 1 << (irq - IRQ_TIMER0);
- __raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_ack(unsigned int irq)
-{
- u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
- reg &= 0x1f;
- reg |= (1 << 5) << (irq - IRQ_TIMER0);
- __raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static struct irq_chip s3c_irq_timer = {
- .name = "s3c-timer",
- .mask = s3c_irq_timer_mask,
- .unmask = s3c_irq_timer_unmask,
- .ack = s3c_irq_timer_ack,
-};
-
-struct uart_irq {
- void __iomem *regs;
- unsigned int base_irq;
- unsigned int parent_irq;
-};
-
-/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
- * are consecutive when looking up the interrupt in the demux routines.
- */
-static struct uart_irq uart_irqs[] = {
- [0] = {
- .regs = S3C_VA_UART0,
- .base_irq = IRQ_S3CUART_BASE0,
- .parent_irq = IRQ_UART0,
- },
- [1] = {
- .regs = S3C_VA_UART1,
- .base_irq = IRQ_S3CUART_BASE1,
- .parent_irq = IRQ_UART1,
- },
- [2] = {
- .regs = S3C_VA_UART2,
- .base_irq = IRQ_S3CUART_BASE2,
- .parent_irq = IRQ_UART2,
- },
- [3] = {
- .regs = S3C_VA_UART3,
- .base_irq = IRQ_S3CUART_BASE3,
- .parent_irq = IRQ_UART3,
- },
-};
-
-static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
-{
- struct uart_irq *uirq = get_irq_chip_data(irq);
- return uirq->regs;
-}
-
-static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
-{
- return irq & 3;
-}
-
-/* UART interrupt registers, not worth adding to seperate include header */
-
-static void s3c_irq_uart_mask(unsigned int irq)
-{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
- u32 reg;
-
- reg = __raw_readl(regs + S3C64XX_UINTM);
- reg |= (1 << bit);
- __raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_maskack(unsigned int irq)
-{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
- u32 reg;
-
- reg = __raw_readl(regs + S3C64XX_UINTM);
- reg |= (1 << bit);
- __raw_writel(reg, regs + S3C64XX_UINTM);
- __raw_writel(1 << bit, regs + S3C64XX_UINTP);
-}
-
-static void s3c_irq_uart_unmask(unsigned int irq)
-{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
- u32 reg;
-
- reg = __raw_readl(regs + S3C64XX_UINTM);
- reg &= ~(1 << bit);
- __raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_ack(unsigned int irq)
-{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
-
- __raw_writel(1 << bit, regs + S3C64XX_UINTP);
-}
-
-static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
-{
- struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
- u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
- int base = uirq->base_irq;
-
- if (pend & (1 << 0))
- generic_handle_irq(base);
- if (pend & (1 << 1))
- generic_handle_irq(base + 1);
- if (pend & (1 << 2))
- generic_handle_irq(base + 2);
- if (pend & (1 << 3))
- generic_handle_irq(base + 3);
-}
-
-static struct irq_chip s3c_irq_uart = {
- .name = "s3c-uart",
- .mask = s3c_irq_uart_mask,
- .unmask = s3c_irq_uart_unmask,
- .mask_ack = s3c_irq_uart_maskack,
- .ack = s3c_irq_uart_ack,
-};
-
-static void __init s3c64xx_uart_irq(struct uart_irq *uirq)
-{
- void __iomem *reg_base = uirq->regs;
- unsigned int irq;
- int offs;
-
- /* mask all interrupts at the start. */
- __raw_writel(0xf, reg_base + S3C64XX_UINTM);
-
- for (offs = 0; offs < 3; offs++) {
- irq = uirq->base_irq + offs;
-
- set_irq_chip(irq, &s3c_irq_uart);
- set_irq_chip_data(irq, uirq);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
-
- set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
-}
-
-void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
-{
- int uart, irq;
-
- printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
-
- /* initialise the pair of VICs */
- vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid, 0);
- vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid, 0);
-
- /* add the timer sub-irqs */
-
- set_irq_chained_handler(IRQ_TIMER0_VIC, s3c_irq_demux_timer0);
- set_irq_chained_handler(IRQ_TIMER1_VIC, s3c_irq_demux_timer1);
- set_irq_chained_handler(IRQ_TIMER2_VIC, s3c_irq_demux_timer2);
- set_irq_chained_handler(IRQ_TIMER3_VIC, s3c_irq_demux_timer3);
- set_irq_chained_handler(IRQ_TIMER4_VIC, s3c_irq_demux_timer4);
-
- for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
- set_irq_chip(irq, &s3c_irq_timer);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
-
- for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
- s3c64xx_uart_irq(&uart_irqs[uart]);
-}
-
-
diff --git a/arch/arm/plat-s3c64xx/pm.c b/arch/arm/plat-s3c64xx/pm.c
deleted file mode 100644
index 47632fc7eb6..00000000000
--- a/arch/arm/plat-s3c64xx/pm.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/pm.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX CPU PM support.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/suspend.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <mach/map.h>
-
-#include <plat/pm.h>
-#include <plat/regs-sys.h>
-#include <plat/regs-gpio.h>
-#include <plat/regs-clock.h>
-#include <plat/regs-syscon-power.h>
-#include <plat/regs-gpio-memport.h>
-
-#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
-#include <plat/gpio-bank-n.h>
-
-void s3c_pm_debug_smdkled(u32 set, u32 clear)
-{
- unsigned long flags;
- u32 reg;
-
- local_irq_save(flags);
- reg = __raw_readl(S3C64XX_GPNCON);
- reg &= ~(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) |
- S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15));
- reg |= S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) |
- S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15);
- __raw_writel(reg, S3C64XX_GPNCON);
-
- reg = __raw_readl(S3C64XX_GPNDAT);
- reg &= ~(clear << 12);
- reg |= set << 12;
- __raw_writel(reg, S3C64XX_GPNDAT);
-
- local_irq_restore(flags);
-}
-#endif
-
-static struct sleep_save core_save[] = {
- SAVE_ITEM(S3C_APLL_LOCK),
- SAVE_ITEM(S3C_MPLL_LOCK),
- SAVE_ITEM(S3C_EPLL_LOCK),
- SAVE_ITEM(S3C_CLK_SRC),
- SAVE_ITEM(S3C_CLK_DIV0),
- SAVE_ITEM(S3C_CLK_DIV1),
- SAVE_ITEM(S3C_CLK_DIV2),
- SAVE_ITEM(S3C_CLK_OUT),
- SAVE_ITEM(S3C_HCLK_GATE),
- SAVE_ITEM(S3C_PCLK_GATE),
- SAVE_ITEM(S3C_SCLK_GATE),
- SAVE_ITEM(S3C_MEM0_GATE),
-
- SAVE_ITEM(S3C_EPLL_CON1),
- SAVE_ITEM(S3C_EPLL_CON0),
-
- SAVE_ITEM(S3C64XX_MEM0DRVCON),
- SAVE_ITEM(S3C64XX_MEM1DRVCON),
-
-#ifndef CONFIG_CPU_FREQ
- SAVE_ITEM(S3C_APLL_CON),
- SAVE_ITEM(S3C_MPLL_CON),
-#endif
-};
-
-static struct sleep_save misc_save[] = {
- SAVE_ITEM(S3C64XX_AHB_CON0),
- SAVE_ITEM(S3C64XX_AHB_CON1),
- SAVE_ITEM(S3C64XX_AHB_CON2),
-
- SAVE_ITEM(S3C64XX_SPCON),
-
- SAVE_ITEM(S3C64XX_MEM0CONSTOP),
- SAVE_ITEM(S3C64XX_MEM1CONSTOP),
- SAVE_ITEM(S3C64XX_MEM0CONSLP0),
- SAVE_ITEM(S3C64XX_MEM0CONSLP1),
- SAVE_ITEM(S3C64XX_MEM1CONSLP),
-};
-
-void s3c_pm_configure_extint(void)
-{
- __raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK);
-}
-
-void s3c_pm_restore_core(void)
-{
- __raw_writel(0, S3C64XX_EINT_MASK);
-
- s3c_pm_debug_smdkled(1 << 2, 0);
-
- s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
- s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
-}
-
-void s3c_pm_save_core(void)
-{
- s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
- s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
-}
-
-/* since both s3c6400 and s3c6410 share the same sleep pm calls, we
- * put the per-cpu code in here until any new cpu comes along and changes
- * this.
- */
-
-static void s3c64xx_cpu_suspend(void)
-{
- unsigned long tmp;
-
- /* set our standby method to sleep */
-
- tmp = __raw_readl(S3C64XX_PWR_CFG);
- tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
- tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP;
- __raw_writel(tmp, S3C64XX_PWR_CFG);
-
- /* clear any old wakeup */
-
- __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT),
- S3C64XX_WAKEUP_STAT);
-
- /* set the LED state to 0110 over sleep */
- s3c_pm_debug_smdkled(3 << 1, 0xf);
-
- /* issue the standby signal into the pm unit. Note, we
- * issue a write-buffer drain just in case */
-
- tmp = 0;
-
- asm("b 1f\n\t"
- ".align 5\n\t"
- "1:\n\t"
- "mcr p15, 0, %0, c7, c10, 5\n\t"
- "mcr p15, 0, %0, c7, c10, 4\n\t"
- "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
-
- /* we should never get past here */
-
- panic("sleep resumed to originator?");
-}
-
-static void s3c64xx_pm_prepare(void)
-{
- /* store address of resume. */
- __raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
-
- /* ensure previous wakeup state is cleared before sleeping */
- __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
-}
-
-static int s3c64xx_pm_init(void)
-{
- pm_cpu_prep = s3c64xx_pm_prepare;
- pm_cpu_sleep = s3c64xx_cpu_suspend;
- pm_uart_udivslot = 1;
- return 0;
-}
-
-arch_initcall(s3c64xx_pm_init);
diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c
deleted file mode 100644
index ffd56deb9e8..00000000000
--- a/arch/arm/plat-s3c64xx/s3c6400-clock.c
+++ /dev/null
@@ -1,758 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/s3c6400-clock.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C6400 based common clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/sysdev.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/cpu-freq.h>
-
-#include <plat/regs-clock.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-
-/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
- * ext_xtal_mux for want of an actual name from the manual.
-*/
-
-static struct clk clk_ext_xtal_mux = {
- .name = "ext_xtal",
- .id = -1,
-};
-
-#define clk_fin_apll clk_ext_xtal_mux
-#define clk_fin_mpll clk_ext_xtal_mux
-#define clk_fin_epll clk_ext_xtal_mux
-
-#define clk_fout_mpll clk_mpll
-#define clk_fout_epll clk_epll
-
-struct clk_sources {
- unsigned int nr_sources;
- struct clk **sources;
-};
-
-struct clksrc_clk {
- struct clk clk;
- unsigned int mask;
- unsigned int shift;
-
- struct clk_sources *sources;
-
- unsigned int divider_shift;
- void __iomem *reg_divider;
-};
-
-static struct clk clk_fout_apll = {
- .name = "fout_apll",
- .id = -1,
-};
-
-static struct clk *clk_src_apll_list[] = {
- [0] = &clk_fin_apll,
- [1] = &clk_fout_apll,
-};
-
-static struct clk_sources clk_src_apll = {
- .sources = clk_src_apll_list,
- .nr_sources = ARRAY_SIZE(clk_src_apll_list),
-};
-
-static struct clksrc_clk clk_mout_apll = {
- .clk = {
- .name = "mout_apll",
- .id = -1,
- },
- .shift = S3C6400_CLKSRC_APLL_MOUT_SHIFT,
- .mask = S3C6400_CLKSRC_APLL_MOUT,
- .sources = &clk_src_apll,
-};
-
-static struct clk *clk_src_epll_list[] = {
- [0] = &clk_fin_epll,
- [1] = &clk_fout_epll,
-};
-
-static struct clk_sources clk_src_epll = {
- .sources = clk_src_epll_list,
- .nr_sources = ARRAY_SIZE(clk_src_epll_list),
-};
-
-static struct clksrc_clk clk_mout_epll = {
- .clk = {
- .name = "mout_epll",
- .id = -1,
- },
- .shift = S3C6400_CLKSRC_EPLL_MOUT_SHIFT,
- .mask = S3C6400_CLKSRC_EPLL_MOUT,
- .sources = &clk_src_epll,
-};
-
-static struct clk *clk_src_mpll_list[] = {
- [0] = &clk_fin_mpll,
- [1] = &clk_fout_mpll,
-};
-
-static struct clk_sources clk_src_mpll = {
- .sources = clk_src_mpll_list,
- .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
-};
-
-static struct clksrc_clk clk_mout_mpll = {
- .clk = {
- .name = "mout_mpll",
- .id = -1,
- },
- .shift = S3C6400_CLKSRC_MPLL_MOUT_SHIFT,
- .mask = S3C6400_CLKSRC_MPLL_MOUT,
- .sources = &clk_src_mpll,
-};
-
-static unsigned int armclk_mask;
-
-static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk)
-{
- unsigned long rate = clk_get_rate(clk->parent);
- u32 clkdiv;
-
- /* divisor mask starts at bit0, so no need to shift */
- clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask;
-
- return rate / (clkdiv + 1);
-}
-
-static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk,
- unsigned long rate)
-{
- unsigned long parent = clk_get_rate(clk->parent);
- u32 div;
-
- if (parent < rate)
- return parent;
-
- div = (parent / rate) - 1;
- if (div > armclk_mask)
- div = armclk_mask;
-
- return parent / (div + 1);
-}
-
-static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long parent = clk_get_rate(clk->parent);
- u32 div;
- u32 val;
-
- if (rate < parent / (armclk_mask + 1))
- return -EINVAL;
-
- rate = clk_round_rate(clk, rate);
- div = clk_get_rate(clk->parent) / rate;
-
- val = __raw_readl(S3C_CLK_DIV0);
- val &= ~armclk_mask;
- val |= (div - 1);
- __raw_writel(val, S3C_CLK_DIV0);
-
- return 0;
-
-}
-
-static struct clk clk_arm = {
- .name = "armclk",
- .id = -1,
- .parent = &clk_mout_apll.clk,
- .get_rate = s3c64xx_clk_arm_get_rate,
- .set_rate = s3c64xx_clk_arm_set_rate,
- .round_rate = s3c64xx_clk_arm_round_rate,
-};
-
-static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
-{
- unsigned long rate = clk_get_rate(clk->parent);
-
- printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
- if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK)
- rate /= 2;
-
- return rate;
-}
-
-static struct clk clk_dout_mpll = {
- .name = "dout_mpll",
- .id = -1,
- .parent = &clk_mout_mpll.clk,
- .get_rate = s3c64xx_clk_doutmpll_get_rate,
-};
-
-static struct clk *clkset_spi_mmc_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll,
- &clk_fin_epll,
- &clk_27m,
-};
-
-static struct clk_sources clkset_spi_mmc = {
- .sources = clkset_spi_mmc_list,
- .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list),
-};
-
-static struct clk *clkset_irda_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll,
- NULL,
- &clk_27m,
-};
-
-static struct clk_sources clkset_irda = {
- .sources = clkset_irda_list,
- .nr_sources = ARRAY_SIZE(clkset_irda_list),
-};
-
-static struct clk *clkset_uart_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll,
- NULL,
- NULL
-};
-
-static struct clk_sources clkset_uart = {
- .sources = clkset_uart_list,
- .nr_sources = ARRAY_SIZE(clkset_uart_list),
-};
-
-static struct clk *clkset_uhost_list[] = {
- &clk_48m,
- &clk_mout_epll.clk,
- &clk_dout_mpll,
- &clk_fin_epll,
-};
-
-static struct clk_sources clkset_uhost = {
- .sources = clkset_uhost_list,
- .nr_sources = ARRAY_SIZE(clkset_uhost_list),
-};
-
-
-/* The peripheral clocks are all controlled via clocksource followed
- * by an optional divider and gate stage. We currently roll this into
- * one clock which hides the intermediate clock from the mux.
- *
- * Note, the JPEG clock can only be an even divider...
- *
- * The scaler and LCD clocks depend on the S3C64XX version, and also
- * have a common parent divisor so are not included here.
- */
-
-static inline struct clksrc_clk *to_clksrc(struct clk *clk)
-{
- return container_of(clk, struct clksrc_clk, clk);
-}
-
-static unsigned long s3c64xx_getrate_clksrc(struct clk *clk)
-{
- struct clksrc_clk *sclk = to_clksrc(clk);
- unsigned long rate = clk_get_rate(clk->parent);
- u32 clkdiv = __raw_readl(sclk->reg_divider);
-
- clkdiv >>= sclk->divider_shift;
- clkdiv &= 0xf;
- clkdiv++;
-
- rate /= clkdiv;
- return rate;
-}
-
-static int s3c64xx_setrate_clksrc(struct clk *clk, unsigned long rate)
-{
- struct clksrc_clk *sclk = to_clksrc(clk);
- void __iomem *reg = sclk->reg_divider;
- unsigned int div;
- u32 val;
-
- rate = clk_round_rate(clk, rate);
- div = clk_get_rate(clk->parent) / rate;
- if (div > 16)
- return -EINVAL;
-
- val = __raw_readl(reg);
- val &= ~(0xf << sclk->divider_shift);
- val |= (div - 1) << sclk->divider_shift;
- __raw_writel(val, reg);
-
- return 0;
-}
-
-static int s3c64xx_setparent_clksrc(struct clk *clk, struct clk *parent)
-{
- struct clksrc_clk *sclk = to_clksrc(clk);
- struct clk_sources *srcs = sclk->sources;
- u32 clksrc = __raw_readl(S3C_CLK_SRC);
- int src_nr = -1;
- int ptr;
-
- for (ptr = 0; ptr < srcs->nr_sources; ptr++)
- if (srcs->sources[ptr] == parent) {
- src_nr = ptr;
- break;
- }
-
- if (src_nr >= 0) {
- clksrc &= ~sclk->mask;
- clksrc |= src_nr << sclk->shift;
-
- __raw_writel(clksrc, S3C_CLK_SRC);
-
- clk->parent = parent;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static unsigned long s3c64xx_roundrate_clksrc(struct clk *clk,
- unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- int div;
-
- if (rate > parent_rate)
- rate = parent_rate;
- else {
- div = parent_rate / rate;
-
- if (div == 0)
- div = 1;
- if (div > 16)
- div = 16;
-
- rate = parent_rate / div;
- }
-
- return rate;
-}
-
-static struct clksrc_clk clk_mmc0 = {
- .clk = {
- .name = "mmc_bus",
- .id = 0,
- .ctrlbit = S3C_CLKCON_SCLK_MMC0,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_MMC0_SHIFT,
- .mask = S3C6400_CLKSRC_MMC0_MASK,
- .sources = &clkset_spi_mmc,
- .divider_shift = S3C6400_CLKDIV1_MMC0_SHIFT,
- .reg_divider = S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_mmc1 = {
- .clk = {
- .name = "mmc_bus",
- .id = 1,
- .ctrlbit = S3C_CLKCON_SCLK_MMC1,
- .enable = s3c64xx_sclk_ctrl,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .set_parent = s3c64xx_setparent_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_MMC1_SHIFT,
- .mask = S3C6400_CLKSRC_MMC1_MASK,
- .sources = &clkset_spi_mmc,
- .divider_shift = S3C6400_CLKDIV1_MMC1_SHIFT,
- .reg_divider = S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_mmc2 = {
- .clk = {
- .name = "mmc_bus",
- .id = 2,
- .ctrlbit = S3C_CLKCON_SCLK_MMC2,
- .enable = s3c64xx_sclk_ctrl,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .set_parent = s3c64xx_setparent_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_MMC2_SHIFT,
- .mask = S3C6400_CLKSRC_MMC2_MASK,
- .sources = &clkset_spi_mmc,
- .divider_shift = S3C6400_CLKDIV1_MMC2_SHIFT,
- .reg_divider = S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_usbhost = {
- .clk = {
- .name = "usb-bus-host",
- .id = -1,
- .ctrlbit = S3C_CLKCON_SCLK_UHOST,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_UHOST_SHIFT,
- .mask = S3C6400_CLKSRC_UHOST_MASK,
- .sources = &clkset_uhost,
- .divider_shift = S3C6400_CLKDIV1_UHOST_SHIFT,
- .reg_divider = S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_uart_uclk1 = {
- .clk = {
- .name = "uclk1",
- .id = -1,
- .ctrlbit = S3C_CLKCON_SCLK_UART,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_UART_SHIFT,
- .mask = S3C6400_CLKSRC_UART_MASK,
- .sources = &clkset_uart,
- .divider_shift = S3C6400_CLKDIV2_UART_SHIFT,
- .reg_divider = S3C_CLK_DIV2,
-};
-
-/* Where does UCLK0 come from? */
-
-static struct clksrc_clk clk_spi0 = {
- .clk = {
- .name = "spi-bus",
- .id = 0,
- .ctrlbit = S3C_CLKCON_SCLK_SPI0,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_SPI0_SHIFT,
- .mask = S3C6400_CLKSRC_SPI0_MASK,
- .sources = &clkset_spi_mmc,
- .divider_shift = S3C6400_CLKDIV2_SPI0_SHIFT,
- .reg_divider = S3C_CLK_DIV2,
-};
-
-static struct clksrc_clk clk_spi1 = {
- .clk = {
- .name = "spi-bus",
- .id = 1,
- .ctrlbit = S3C_CLKCON_SCLK_SPI1,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_SPI1_SHIFT,
- .mask = S3C6400_CLKSRC_SPI1_MASK,
- .sources = &clkset_spi_mmc,
- .divider_shift = S3C6400_CLKDIV2_SPI1_SHIFT,
- .reg_divider = S3C_CLK_DIV2,
-};
-
-static struct clk clk_iis_cd0 = {
- .name = "iis_cdclk0",
- .id = -1,
-};
-
-static struct clk clk_iis_cd1 = {
- .name = "iis_cdclk1",
- .id = -1,
-};
-
-static struct clk clk_pcm_cd = {
- .name = "pcm_cdclk",
- .id = -1,
-};
-
-static struct clk *clkset_audio0_list[] = {
- [0] = &clk_mout_epll.clk,
- [1] = &clk_dout_mpll,
- [2] = &clk_fin_epll,
- [3] = &clk_iis_cd0,
- [4] = &clk_pcm_cd,
-};
-
-static struct clk_sources clkset_audio0 = {
- .sources = clkset_audio0_list,
- .nr_sources = ARRAY_SIZE(clkset_audio0_list),
-};
-
-static struct clksrc_clk clk_audio0 = {
- .clk = {
- .name = "audio-bus",
- .id = 0,
- .ctrlbit = S3C_CLKCON_SCLK_AUDIO0,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_AUDIO0_SHIFT,
- .mask = S3C6400_CLKSRC_AUDIO0_MASK,
- .sources = &clkset_audio0,
- .divider_shift = S3C6400_CLKDIV2_AUDIO0_SHIFT,
- .reg_divider = S3C_CLK_DIV2,
-};
-
-static struct clk *clkset_audio1_list[] = {
- [0] = &clk_mout_epll.clk,
- [1] = &clk_dout_mpll,
- [2] = &clk_fin_epll,
- [3] = &clk_iis_cd1,
- [4] = &clk_pcm_cd,
-};
-
-static struct clk_sources clkset_audio1 = {
- .sources = clkset_audio1_list,
- .nr_sources = ARRAY_SIZE(clkset_audio1_list),
-};
-
-static struct clksrc_clk clk_audio1 = {
- .clk = {
- .name = "audio-bus",
- .id = 1,
- .ctrlbit = S3C_CLKCON_SCLK_AUDIO1,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_AUDIO1_SHIFT,
- .mask = S3C6400_CLKSRC_AUDIO1_MASK,
- .sources = &clkset_audio1,
- .divider_shift = S3C6400_CLKDIV2_AUDIO1_SHIFT,
- .reg_divider = S3C_CLK_DIV2,
-};
-
-static struct clksrc_clk clk_irda = {
- .clk = {
- .name = "irda-bus",
- .id = 0,
- .ctrlbit = S3C_CLKCON_SCLK_IRDA,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = S3C6400_CLKSRC_IRDA_SHIFT,
- .mask = S3C6400_CLKSRC_IRDA_MASK,
- .sources = &clkset_irda,
- .divider_shift = S3C6400_CLKDIV2_IRDA_SHIFT,
- .reg_divider = S3C_CLK_DIV2,
-};
-
-static struct clk *clkset_camif_list[] = {
- &clk_h2,
-};
-
-static struct clk_sources clkset_camif = {
- .sources = clkset_camif_list,
- .nr_sources = ARRAY_SIZE(clkset_camif_list),
-};
-
-static struct clksrc_clk clk_camif = {
- .clk = {
- .name = "camera",
- .id = -1,
- .ctrlbit = S3C_CLKCON_SCLK_CAM,
- .enable = s3c64xx_sclk_ctrl,
- .set_parent = s3c64xx_setparent_clksrc,
- .get_rate = s3c64xx_getrate_clksrc,
- .set_rate = s3c64xx_setrate_clksrc,
- .round_rate = s3c64xx_roundrate_clksrc,
- },
- .shift = 0,
- .mask = 0,
- .sources = &clkset_camif,
- .divider_shift = S3C6400_CLKDIV0_CAM_SHIFT,
- .reg_divider = S3C_CLK_DIV0,
-};
-
-/* Clock initialisation code */
-
-static struct clksrc_clk *init_parents[] = {
- &clk_mout_apll,
- &clk_mout_epll,
- &clk_mout_mpll,
- &clk_mmc0,
- &clk_mmc1,
- &clk_mmc2,
- &clk_usbhost,
- &clk_uart_uclk1,
- &clk_spi0,
- &clk_spi1,
- &clk_audio0,
- &clk_audio1,
- &clk_irda,
- &clk_camif,
-};
-
-static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk)
-{
- struct clk_sources *srcs = clk->sources;
- u32 clksrc = __raw_readl(S3C_CLK_SRC);
-
- clksrc &= clk->mask;
- clksrc >>= clk->shift;
-
- if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
- printk(KERN_ERR "%s: bad source %d\n",
- clk->clk.name, clksrc);
- return;
- }
-
- clk->clk.parent = srcs->sources[clksrc];
-
- printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
- clk->clk.name, clk->clk.parent->name, clksrc,
- clk_get_rate(&clk->clk));
-}
-
-#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
-
-void __init_or_cpufreq s3c6400_setup_clocks(void)
-{
- struct clk *xtal_clk;
- unsigned long xtal;
- unsigned long fclk;
- unsigned long hclk;
- unsigned long hclk2;
- unsigned long pclk;
- unsigned long epll;
- unsigned long apll;
- unsigned long mpll;
- unsigned int ptr;
- u32 clkdiv0;
-
- printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
- clkdiv0 = __raw_readl(S3C_CLK_DIV0);
- printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0);
-
- xtal_clk = clk_get(NULL, "xtal");
- BUG_ON(IS_ERR(xtal_clk));
-
- xtal = clk_get_rate(xtal_clk);
- clk_put(xtal_clk);
-
- printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
- /* For now assume the mux always selects the crystal */
- clk_ext_xtal_mux.parent = xtal_clk;
-
- epll = s3c6400_get_epll(xtal);
- mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
- apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
-
- fclk = mpll;
-
- printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
- apll, mpll, epll);
-
- hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
- hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
- pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
-
- printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n",
- hclk2, hclk, pclk);
-
- clk_fout_mpll.rate = mpll;
- clk_fout_epll.rate = epll;
- clk_fout_apll.rate = apll;
-
- clk_h2.rate = hclk2;
- clk_h.rate = hclk;
- clk_p.rate = pclk;
- clk_f.rate = fclk;
-
- for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
- s3c6400_set_clksrc(init_parents[ptr]);
-}
-
-static struct clk *clks[] __initdata = {
- &clk_ext_xtal_mux,
- &clk_iis_cd0,
- &clk_iis_cd1,
- &clk_pcm_cd,
- &clk_mout_epll.clk,
- &clk_mout_mpll.clk,
- &clk_dout_mpll,
- &clk_mmc0.clk,
- &clk_mmc1.clk,
- &clk_mmc2.clk,
- &clk_usbhost.clk,
- &clk_uart_uclk1.clk,
- &clk_spi0.clk,
- &clk_spi1.clk,
- &clk_audio0.clk,
- &clk_audio1.clk,
- &clk_irda.clk,
- &clk_camif.clk,
- &clk_arm,
-};
-
-/**
- * s3c6400_register_clocks - register clocks for s3c6400 and above
- * @armclk_divlimit: Divisor mask for ARMCLK
- *
- * Register the clocks for the S3C6400 and above SoC range, such
- * as ARMCLK and the clocks which have divider chains attached.
- *
- * This call does not setup the clocks, which is left to the
- * s3c6400_setup_clocks() call which may be needed by the cpufreq
- * or resume code to re-set the clocks if the bootloader has changed
- * them.
- */
-void __init s3c6400_register_clocks(unsigned armclk_divlimit)
-{
- struct clk *clkp;
- int ret;
- int ptr;
-
- armclk_mask = armclk_divlimit;
-
- for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
- clkp = clks[ptr];
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
- }
-}
diff --git a/arch/arm/plat-s3c64xx/s3c6400-init.c b/arch/arm/plat-s3c64xx/s3c6400-init.c
deleted file mode 100644
index 6c28f39df09..00000000000
--- a/arch/arm/plat-s3c64xx/s3c6400-init.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/s3c6400-init.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C6400 - CPU initialisation (common with other S3C64XX chips)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/s3c6400.h>
-#include <plat/s3c6410.h>
-
-/* uart registration process */
-
-void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
- s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
-}
diff --git a/arch/arm/plat-s3c64xx/setup-i2c0.c b/arch/arm/plat-s3c64xx/setup-i2c0.c
deleted file mode 100644
index 36448076372..00000000000
--- a/arch/arm/plat-s3c64xx/setup-i2c0.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/setup-i2c0.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * Base S3C64XX I2C bus 0 gpio configuration
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <mach/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-bank-b.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
- s3c_gpio_cfgpin(S3C64XX_GPB(5), S3C64XX_GPB5_I2C_SCL0);
- s3c_gpio_cfgpin(S3C64XX_GPB(6), S3C64XX_GPB6_I2C_SDA0);
- s3c_gpio_setpull(S3C64XX_GPB(5), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S3C64XX_GPB(6), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/plat-s3c64xx/setup-i2c1.c b/arch/arm/plat-s3c64xx/setup-i2c1.c
deleted file mode 100644
index bbe229bd90c..00000000000
--- a/arch/arm/plat-s3c64xx/setup-i2c1.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * Base S3C64XX I2C bus 1 gpio configuration
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <mach/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-bank-b.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
-{
- s3c_gpio_cfgpin(S3C64XX_GPB(2), S3C64XX_GPB2_I2C_SCL1);
- s3c_gpio_cfgpin(S3C64XX_GPB(3), S3C64XX_GPB3_I2C_SDA1);
- s3c_gpio_setpull(S3C64XX_GPB(2), S3C_GPIO_PULL_UP);
- s3c_gpio_setpull(S3C64XX_GPB(3), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/plat-s3c64xx/sleep.S b/arch/arm/plat-s3c64xx/sleep.S
deleted file mode 100644
index 8e71fe90a37..00000000000
--- a/arch/arm/plat-s3c64xx/sleep.S
+++ /dev/null
@@ -1,144 +0,0 @@
-/* linux/0arch/arm/plat-s3c64xx/sleep.S
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C64XX CPU sleep code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <mach/map.h>
-
-#undef S3C64XX_VA_GPIO
-#define S3C64XX_VA_GPIO (0x0)
-
-#include <plat/regs-gpio.h>
-#include <plat/gpio-bank-n.h>
-
-#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
-
- .text
-
- /* s3c_cpu_save
- *
- * Save enough processor state to allow the restart of the pm.c
- * code after resume.
- *
- * entry:
- * r0 = pointer to the save block
- */
-
-ENTRY(s3c_cpu_save)
- stmfd sp!, { r4 - r12, lr }
-
- mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
- mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
- mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
- mrc p15, 0, r9, c1, c0, 0 @ Control register
- mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
- mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
-
- stmia r0, { r4 - r13 } @ Save CP registers and SP
-
- @@ save our state to ram
- bl s3c_pm_cb_flushcache
-
- @@ call final suspend code
- ldr r0, =pm_cpu_sleep
- ldr pc, [r0]
-
- @@ return to the caller, after the MMU is turned on.
- @@ restore the last bits of the stack and return.
-resume_with_mmu:
- ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
-
- .data
-
- /* the next bit is code, but it requires easy access to the
- * s3c_sleep_save_phys data before the MMU is switched on, so
- * we store the code that needs this variable in the .data where
- * the value can be written to (the .text segment is RO).
- */
-
- .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
- .word 0
-
- /* Sleep magic, the word before the resume entry point so that the
- * bootloader can check for a resumeable image. */
-
- .word 0x2bedf00d
-
- /* s3c_cpu_reusme
- *
- * This is the entry point, stored by whatever method the bootloader
- * requires to get the kernel runnign again. This code expects to be
- * entered with no caches live and the MMU disabled. It will then
- * restore the MMU and other basic CP registers saved and restart
- * the kernel C code to finish the resume code.
- */
-
-ENTRY(s3c_cpu_resume)
- msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
- ldr r2, =LL_UART /* for debug */
-
-#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
- /* Initialise the GPIO state if we are debugging via the SMDK LEDs,
- * as the uboot version supplied resets these to inputs during the
- * resume checks.
- */
-
- ldr r3, =S3C64XX_PA_GPIO
- ldr r0, [ r3, #S3C64XX_GPNCON ]
- bic r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
- S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
- orr r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
- S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
- str r0, [ r3, #S3C64XX_GPNCON ]
-
- ldr r0, [ r3, #S3C64XX_GPNDAT ]
- bic r0, r0, #0xf << 12 @ GPN12..15
- orr r0, r0, #1 << 15 @ GPN15
- str r0, [ r3, #S3C64XX_GPNDAT ]
-#endif
-
- /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
- * are thoroughly cleaned just in case the bootloader didn't do it
- * for us. */
- mov r0, #0
- mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
- mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
- mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
- @@mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
- @@mcr p15, 0, r0, c7, c7, 0 @ Invalidate I + D caches
-
- ldr r0, s3c_sleep_save_phys
- ldmia r0, { r4 - r13 }
-
- mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mcr p15, 0, r5, c3, c0, 0 @ Domain ID
- mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
- mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
- mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
- mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
-
- mov r0, #0 @ restore copro access controls
- mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls
- mcr p15, 0, r0, c7, c5, 4
-
- ldr r2, =resume_with_mmu
- mcr p15, 0, r9, c1, c0, 0 /* turn mmu back on */
- nop
- mov pc, r2 /* jump back */
-
- .end
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
new file mode 100644
index 00000000000..d400a6a20fe
--- /dev/null
+++ b/arch/arm/plat-s5p/Kconfig
@@ -0,0 +1,25 @@
+# arch/arm/plat-s5p/Kconfig
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+config PLAT_S5P
+ bool
+ depends on (ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PV210)
+ default y
+ select ARM_VIC
+ select NO_IOPORT
+ select ARCH_REQUIRE_GPIOLIB
+ select S3C_GPIO_TRACK
+ select SAMSUNG_GPIOLIB_4BIT
+ select S3C_GPIO_CFG_S3C64XX
+ select S3C_GPIO_PULL_UPDOWN
+ select S3C_GPIO_CFG_S3C24XX
+ select PLAT_SAMSUNG
+ select SAMSUNG_CLKSRC
+ select SAMSUNG_IRQ_VIC_TIMER
+ select SAMSUNG_IRQ_UART
+ help
+ Base platform code for Samsung's S5P series SoC.
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
new file mode 100644
index 00000000000..a7c54b332d2
--- /dev/null
+++ b/arch/arm/plat-s5p/Makefile
@@ -0,0 +1,19 @@
+# arch/arm/plat-s5p/Makefile
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n := dummy.o
+obj- :=
+
+# Core files
+
+obj-y += dev-uart.o
+obj-y += cpu.o
+obj-y += clock.o
+obj-y += irq.o
+obj-y += setup-i2c0.o
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
new file mode 100644
index 00000000000..aa96e335073
--- /dev/null
+++ b/arch/arm/plat-s5p/clock.c
@@ -0,0 +1,149 @@
+/* linux/arch/arm/plat-s5p/clock.c
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Common clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p-clock.h>
+
+/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
+ * clk_ext_xtal_mux.
+*/
+struct clk clk_ext_xtal_mux = {
+ .name = "ext_xtal",
+ .id = -1,
+};
+
+static struct clk s5p_clk_27m = {
+ .name = "clk_27m",
+ .id = -1,
+ .rate = 27000000,
+};
+
+/* 48MHz USB Phy clock output */
+struct clk clk_48m = {
+ .name = "clk_48m",
+ .id = -1,
+ .rate = 48000000,
+};
+
+/* APLL clock output
+ * No need .ctrlbit, this is always on
+*/
+struct clk clk_fout_apll = {
+ .name = "fout_apll",
+ .id = -1,
+};
+
+/* MPLL clock output
+ * No need .ctrlbit, this is always on
+*/
+struct clk clk_fout_mpll = {
+ .name = "fout_mpll",
+ .id = -1,
+};
+
+/* EPLL clock output */
+struct clk clk_fout_epll = {
+ .name = "fout_epll",
+ .id = -1,
+ .ctrlbit = (1 << 31),
+};
+
+/* ARM clock */
+struct clk clk_arm = {
+ .name = "armclk",
+ .id = -1,
+ .rate = 0,
+ .ctrlbit = 0,
+};
+
+/* Possible clock sources for APLL Mux */
+static struct clk *clk_src_apll_list[] = {
+ [0] = &clk_fin_apll,
+ [1] = &clk_fout_apll,
+};
+
+struct clksrc_sources clk_src_apll = {
+ .sources = clk_src_apll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_apll_list),
+};
+
+/* Possible clock sources for MPLL Mux */
+static struct clk *clk_src_mpll_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &clk_fout_mpll,
+};
+
+struct clksrc_sources clk_src_mpll = {
+ .sources = clk_src_mpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
+};
+
+/* Possible clock sources for EPLL Mux */
+static struct clk *clk_src_epll_list[] = {
+ [0] = &clk_fin_epll,
+ [1] = &clk_fout_epll,
+};
+
+struct clksrc_sources clk_src_epll = {
+ .sources = clk_src_epll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_epll_list),
+};
+
+struct clk clk_vpll = {
+ .name = "vpll",
+ .id = -1,
+};
+
+int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ u32 con;
+
+ con = __raw_readl(reg);
+ con = enable ? (con | ctrlbit) : (con & ~ctrlbit);
+ __raw_writel(con, reg);
+ return 0;
+}
+
+static struct clk *s5p_clks[] __initdata = {
+ &clk_ext_xtal_mux,
+ &clk_48m,
+ &s5p_clk_27m,
+ &clk_fout_apll,
+ &clk_fout_mpll,
+ &clk_fout_epll,
+ &clk_arm,
+ &clk_vpll,
+};
+
+void __init s5p_register_clocks(unsigned long xtal_freq)
+{
+ int ret;
+
+ clk_ext_xtal_mux.rate = xtal_freq;
+
+ ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks));
+ if (ret > 0)
+ printk(KERN_ERR "Failed to register s5p clocks\n");
+}
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
new file mode 100644
index 00000000000..f92e5de3a75
--- /dev/null
+++ b/arch/arm/plat-s5p/cpu.c
@@ -0,0 +1,113 @@
+/* linux/arch/arm/plat-s5p/cpu.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P CPU Support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/regs-clock.h>
+#include <plat/cpu.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6442.h>
+#include <plat/s5pv210.h>
+
+/* table of supported CPUs */
+
+static const char name_s5p6440[] = "S5P6440";
+static const char name_s5p6442[] = "S5P6442";
+static const char name_s5pv210[] = "S5PV210/S5PC110";
+
+static struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = 0x56440100,
+ .idmask = 0xffffff00,
+ .map_io = s5p6440_map_io,
+ .init_clocks = s5p6440_init_clocks,
+ .init_uarts = s5p6440_init_uarts,
+ .init = s5p6440_init,
+ .name = name_s5p6440,
+ }, {
+ .idcode = 0x36442000,
+ .idmask = 0xffffff00,
+ .map_io = s5p6442_map_io,
+ .init_clocks = s5p6442_init_clocks,
+ .init_uarts = s5p6442_init_uarts,
+ .init = s5p6442_init,
+ .name = name_s5p6442,
+ }, {
+ .idcode = 0x43110000,
+ .idmask = 0xfffff000,
+ .map_io = s5pv210_map_io,
+ .init_clocks = s5pv210_init_clocks,
+ .init_uarts = s5pv210_init_uarts,
+ .init = s5pv210_init,
+ .name = name_s5pv210,
+ },
+};
+
+/* minimal IO mapping */
+
+static struct map_desc s5p_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_CHIPID,
+ .pfn = __phys_to_pfn(S5P_PA_CHIPID),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(S5P_PA_SYSCON),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5P_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5P_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_TIMER,
+ .pfn = __phys_to_pfn(S5P_PA_TIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5P_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+/* read cpu identification code */
+
+void __init s5p_init_io(struct map_desc *mach_desc,
+ int size, void __iomem *cpuid_addr)
+{
+ unsigned long idcode;
+
+ /* initialize the io descriptors we need for initialization */
+ iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
+ if (mach_desc)
+ iotable_init(mach_desc, size);
+
+ idcode = __raw_readl(cpuid_addr);
+ s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+}
diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c
new file mode 100644
index 00000000000..a89331ef4ae
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-uart.c
@@ -0,0 +1,139 @@
+/* linux/arch/arm/plat-s5p/dev-uart.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base S5P UART resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+ /* Serial port registrations */
+
+static struct resource s5p_uart0_resource[] = {
+ [0] = {
+ .start = S5P_PA_UART0,
+ .end = S5P_PA_UART0 + S5P_SZ_UART,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX0,
+ .end = IRQ_S5P_UART_RX0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX0,
+ .end = IRQ_S5P_UART_TX0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR0,
+ .end = IRQ_S5P_UART_ERR0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s5p_uart1_resource[] = {
+ [0] = {
+ .start = S5P_PA_UART1,
+ .end = S5P_PA_UART1 + S5P_SZ_UART,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX1,
+ .end = IRQ_S5P_UART_RX1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX1,
+ .end = IRQ_S5P_UART_TX1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR1,
+ .end = IRQ_S5P_UART_ERR1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource s5p_uart2_resource[] = {
+ [0] = {
+ .start = S5P_PA_UART2,
+ .end = S5P_PA_UART2 + S5P_SZ_UART,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX2,
+ .end = IRQ_S5P_UART_RX2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX2,
+ .end = IRQ_S5P_UART_TX2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR2,
+ .end = IRQ_S5P_UART_ERR2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource s5p_uart3_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
+ [0] = {
+ .start = S5P_PA_UART3,
+ .end = S5P_PA_UART3 + S5P_SZ_UART,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX3,
+ .end = IRQ_S5P_UART_RX3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX3,
+ .end = IRQ_S5P_UART_TX3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR3,
+ .end = IRQ_S5P_UART_ERR3,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
+struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s5p_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart0_resource),
+ },
+ [1] = {
+ .resources = s5p_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart1_resource),
+ },
+ [2] = {
+ .resources = s5p_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart2_resource),
+ },
+ [3] = {
+ .resources = s5p_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart3_resource),
+ },
+};
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
new file mode 100644
index 00000000000..42e757f2e40
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/irqs.h
@@ -0,0 +1,90 @@
+/* linux/arch/arm/plat-s5p/include/plat/irqs.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P Common IRQ support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_IRQS_H
+#define __ASM_PLAT_S5P_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S5P_IRQ_OFFSET (32)
+
+#define S5P_IRQ(x) ((x) + S5P_IRQ_OFFSET)
+
+#define S5P_VIC0_BASE S5P_IRQ(0)
+#define S5P_VIC1_BASE S5P_IRQ(32)
+#define S5P_VIC2_BASE S5P_IRQ(64)
+#define S5P_VIC3_BASE S5P_IRQ(96)
+
+#define VIC_BASE(x) (S5P_VIC0_BASE + ((x)*32))
+
+#define IRQ_VIC0_BASE S5P_VIC0_BASE
+#define IRQ_VIC1_BASE S5P_VIC1_BASE
+#define IRQ_VIC2_BASE S5P_VIC2_BASE
+
+/* UART interrupts, each UART has 4 intterupts per channel so
+ * use the space between the ISA and S3C main interrupts. Note, these
+ * are not in the same order as the S3C24XX series! */
+
+#define IRQ_S5P_UART_BASE0 (16)
+#define IRQ_S5P_UART_BASE1 (20)
+#define IRQ_S5P_UART_BASE2 (24)
+#define IRQ_S5P_UART_BASE3 (28)
+
+#define UART_IRQ_RXD (0)
+#define UART_IRQ_ERR (1)
+#define UART_IRQ_TXD (2)
+
+#define IRQ_S5P_UART_RX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR0 (IRQ_S5P_UART_BASE0 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR1 (IRQ_S5P_UART_BASE1 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR2 (IRQ_S5P_UART_BASE2 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR3 (IRQ_S5P_UART_BASE3 + UART_IRQ_ERR)
+
+/* S3C compatibilty defines */
+#define IRQ_S3CUART_RX0 IRQ_S5P_UART_RX0
+#define IRQ_S3CUART_RX1 IRQ_S5P_UART_RX1
+#define IRQ_S3CUART_RX2 IRQ_S5P_UART_RX2
+#define IRQ_S3CUART_RX3 IRQ_S5P_UART_RX3
+
+/* VIC based IRQs */
+
+#define S5P_IRQ_VIC0(x) (S5P_VIC0_BASE + (x))
+#define S5P_IRQ_VIC1(x) (S5P_VIC1_BASE + (x))
+#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x))
+#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x))
+
+#define S5P_TIMER_IRQ(x) S5P_IRQ(11 + (x))
+
+#define IRQ_TIMER0 S5P_TIMER_IRQ(0)
+#define IRQ_TIMER1 S5P_TIMER_IRQ(1)
+#define IRQ_TIMER2 S5P_TIMER_IRQ(2)
+#define IRQ_TIMER3 S5P_TIMER_IRQ(3)
+#define IRQ_TIMER4 S5P_TIMER_IRQ(4)
+
+#endif /* __ASM_PLAT_S5P_IRQS_H */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
new file mode 100644
index 00000000000..14828521f70
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s5p/include/plat/map-s5p.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_MAP_S5P_H
+#define __ASM_PLAT_MAP_S5P_H __FILE__
+
+#define S5P_VA_CHIPID S3C_ADDR(0x00700000)
+#define S5P_VA_GPIO S3C_ADDR(0x00500000)
+#define S5P_VA_SYSTIMER S3C_ADDR(0x01200000)
+#define S5P_VA_SROMC S3C_ADDR(0x01100000)
+
+#define S5P_VA_UART0 (S3C_VA_UART + 0x0)
+#define S5P_VA_UART1 (S3C_VA_UART + 0x400)
+#define S5P_VA_UART2 (S3C_VA_UART + 0x800)
+#define S5P_VA_UART3 (S3C_VA_UART + 0xC00)
+
+#define S3C_UART_OFFSET (0x400)
+
+#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
+#define VA_VIC0 VA_VIC(0)
+#define VA_VIC1 VA_VIC(1)
+#define VA_VIC2 VA_VIC(2)
+#define VA_VIC3 VA_VIC(3)
+
+#endif /* __ASM_PLAT_MAP_S5P_H */
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
new file mode 100644
index 00000000000..d48325bb29e
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -0,0 +1,83 @@
+/* arch/arm/plat-s5p/include/plat/pll.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P PLL code
+ *
+ * Based on arch/arm/plat-s3c64xx/include/plat/pll.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define PLL45XX_MDIV_MASK (0x3FF)
+#define PLL45XX_PDIV_MASK (0x3F)
+#define PLL45XX_SDIV_MASK (0x7)
+#define PLL45XX_MDIV_SHIFT (16)
+#define PLL45XX_PDIV_SHIFT (8)
+#define PLL45XX_SDIV_SHIFT (0)
+
+#include <asm/div64.h>
+
+enum pll45xx_type_t {
+ pll_4500,
+ pll_4502,
+ pll_4508
+};
+
+static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
+ enum pll45xx_type_t pll_type)
+{
+ u32 mdiv, pdiv, sdiv;
+ u64 fvco = baseclk;
+
+ mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+
+ if (pll_type == pll_4508)
+ sdiv = sdiv - 1;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+#define PLL90XX_MDIV_MASK (0xFF)
+#define PLL90XX_PDIV_MASK (0x3F)
+#define PLL90XX_SDIV_MASK (0x7)
+#define PLL90XX_KDIV_MASK (0xffff)
+#define PLL90XX_MDIV_SHIFT (16)
+#define PLL90XX_PDIV_SHIFT (8)
+#define PLL90XX_SDIV_SHIFT (0)
+#define PLL90XX_KDIV_SHIFT (0)
+
+static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
+ u32 pll_con, u32 pll_conk)
+{
+ unsigned long result;
+ u32 mdiv, pdiv, sdiv, kdiv;
+ u64 tmp;
+
+ mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
+ kdiv = pll_conk & PLL90XX_KDIV_MASK;
+
+ /* We need to multiple baseclk by mdiv (the integer part) and kdiv
+ * which is in 2^16ths, so shift mdiv up (does not overflow) and
+ * add kdiv before multiplying. The use of tmp is to avoid any
+ * overflows before shifting bac down into result when multipling
+ * by the mdiv and kdiv pair.
+ */
+
+ tmp = baseclk;
+ tmp *= (mdiv << 16) + kdiv;
+ do_div(tmp, (pdiv << sdiv));
+ result = tmp >> 16;
+
+ return result;
+}
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
new file mode 100644
index 00000000000..56fb8b414d4
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -0,0 +1,40 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5p clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_CLOCK_H
+#define __ASM_PLAT_S5P_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_mpll clk_ext_xtal_mux
+#define clk_fin_epll clk_ext_xtal_mux
+#define clk_fin_vpll clk_ext_xtal_mux
+
+extern struct clk clk_ext_xtal_mux;
+extern struct clk clk_48m;
+extern struct clk clk_fout_apll;
+extern struct clk clk_fout_mpll;
+extern struct clk clk_fout_epll;
+extern struct clk clk_arm;
+extern struct clk clk_vpll;
+
+extern struct clksrc_sources clk_src_apll;
+extern struct clksrc_sources clk_src_mpll;
+extern struct clksrc_sources clk_src_epll;
+
+extern int s5p6440_clk48m_ctrl(struct clk *clk, int enable);
+extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
+
+#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h
new file mode 100644
index 00000000000..a4cd75afeb3
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p6440.h
@@ -0,0 +1,37 @@
+/* arch/arm/plat-s5p/include/plat/s5p6440.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5p6440 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+ /* Common init code for S5P6440 related SoCs */
+
+extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5p6440_register_clocks(void);
+extern void s5p6440_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6440
+
+extern int s5p6440_init(void);
+extern void s5p6440_init_irq(void);
+extern void s5p6440_map_io(void);
+extern void s5p6440_init_clocks(int xtal);
+
+#define s5p6440_init_uarts s5p6440_common_init_uarts
+
+#else
+#define s5p6440_init_clocks NULL
+#define s5p6440_init_uarts NULL
+#define s5p6440_map_io NULL
+#define s5p6440_init NULL
+#endif
+
+/* S5P6440 timer */
+
+extern struct sys_timer s5p6440_timer;
diff --git a/arch/arm/plat-s5p/include/plat/s5p6442.h b/arch/arm/plat-s5p/include/plat/s5p6442.h
new file mode 100644
index 00000000000..7b8801349c9
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p6442.h
@@ -0,0 +1,33 @@
+/* arch/arm/plat-s5p/include/plat/s5p6442.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5p6442 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S5P6442 related SoCs */
+
+extern void s5p6442_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5p6442_register_clocks(void);
+extern void s5p6442_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6442
+
+extern int s5p6442_init(void);
+extern void s5p6442_init_irq(void);
+extern void s5p6442_map_io(void);
+extern void s5p6442_init_clocks(int xtal);
+
+#define s5p6442_init_uarts s5p6442_common_init_uarts
+
+#else
+#define s5p6442_init_clocks NULL
+#define s5p6442_init_uarts NULL
+#define s5p6442_map_io NULL
+#define s5p6442_init NULL
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-s5p/include/plat/s5pv210.h
new file mode 100644
index 00000000000..6c93a0c7810
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5pv210.h
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5pv210.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5pv210 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S5PV210 related SoCs */
+
+extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5pv210_register_clocks(void);
+extern void s5pv210_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5PV210
+
+extern int s5pv210_init(void);
+extern void s5pv210_init_irq(void);
+extern void s5pv210_map_io(void);
+extern void s5pv210_init_clocks(int xtal);
+
+#define s5pv210_init_uarts s5pv210_common_init_uarts
+
+#else
+#define s5pv210_init_clocks NULL
+#define s5pv210_init_uarts NULL
+#define s5pv210_map_io NULL
+#define s5pv210_init NULL
+#endif
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c
new file mode 100644
index 00000000000..25e1eb6de59
--- /dev/null
+++ b/arch/arm/plat-s5p/irq.c
@@ -0,0 +1,72 @@
+/* arch/arm/plat-s5p/irq.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Interrupt handling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <linux/serial_core.h>
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.h>
+
+/*
+ * Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
+ * are consecutive when looking up the interrupt in the demux routines.
+ */
+static struct s3c_uart_irq uart_irqs[] = {
+ [0] = {
+ .regs = S5P_VA_UART0,
+ .base_irq = IRQ_S5P_UART_BASE0,
+ .parent_irq = IRQ_UART0,
+ },
+ [1] = {
+ .regs = S5P_VA_UART1,
+ .base_irq = IRQ_S5P_UART_BASE1,
+ .parent_irq = IRQ_UART1,
+ },
+ [2] = {
+ .regs = S5P_VA_UART2,
+ .base_irq = IRQ_S5P_UART_BASE2,
+ .parent_irq = IRQ_UART2,
+ },
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
+ [3] = {
+ .regs = S5P_VA_UART3,
+ .base_irq = IRQ_S5P_UART_BASE3,
+ .parent_irq = IRQ_UART3,
+ },
+#endif
+};
+
+void __init s5p_init_irq(u32 *vic, u32 num_vic)
+{
+ int irq;
+
+ /* initialize the VICs */
+ for (irq = 0; irq < num_vic; irq++)
+ vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
+
+ s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
+ s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
+ s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
+ s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
+ s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
+
+ s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
+}
diff --git a/arch/arm/plat-s5p/setup-i2c0.c b/arch/arm/plat-s5p/setup-i2c0.c
new file mode 100644
index 00000000000..67a66e02a97
--- /dev/null
+++ b/arch/arm/plat-s5p/setup-i2c0.c
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-s5p/setup-i2c0.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ /* Will be populated later */
+}
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index b7b9e91c024..c7ccdf22eef 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -11,6 +11,9 @@ config PLAT_S5PC1XX
select ARM_VIC
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
+ select SAMSUNG_CLKSRC
+ select SAMSUNG_IRQ_UART
+ select SAMSUNG_IRQ_VIC_TIMER
select S3C_GPIO_TRACK
select S3C_GPIO_PULL_UPDOWN
select S3C_GPIO_CFG_S3C24XX
diff --git a/arch/arm/plat-s5pc1xx/clock.c b/arch/arm/plat-s5pc1xx/clock.c
index 26c21d84979..387f23190c3 100644
--- a/arch/arm/plat-s5pc1xx/clock.c
+++ b/arch/arm/plat-s5pc1xx/clock.c
@@ -64,25 +64,13 @@ struct clk clk_54m = {
.rate = 54000000,
};
-static int clk_default_setrate(struct clk *clk, unsigned long rate)
-{
- clk->rate = rate;
- return 0;
-}
-
-static int clk_dummy_enable(struct clk *clk, int enable)
-{
- return 0;
-}
-
struct clk clk_hd0 = {
.name = "hclkd0",
.id = -1,
.rate = 0,
.parent = NULL,
.ctrlbit = 0,
- .set_rate = clk_default_setrate,
- .enable = clk_dummy_enable,
+ .ops = &clk_ops_def_setrate,
};
struct clk clk_pd0 = {
@@ -91,8 +79,7 @@ struct clk clk_pd0 = {
.rate = 0,
.parent = NULL,
.ctrlbit = 0,
- .set_rate = clk_default_setrate,
- .enable = clk_dummy_enable,
+ .ops = &clk_ops_def_setrate,
};
static int s5pc1xx_clk_gate(void __iomem *reg, struct clk *clk, int enable)
@@ -686,6 +673,8 @@ static struct clk s5pc100_init_clocks[] = {
static struct clk *clks[] __initdata = {
&clk_ext,
&clk_epll,
+ &clk_pd0,
+ &clk_hd0,
&clk_27m,
&clk_48m,
&clk_54m,
@@ -700,16 +689,8 @@ void __init s5pc1xx_register_clocks(void)
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
- clkp = s5pc100_init_clocks;
- size = ARRAY_SIZE(s5pc100_init_clocks);
-
- for (ptr = 0; ptr < size; ptr++, clkp++) {
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
- }
+ s3c_register_clocks(s5pc100_init_clocks,
+ ARRAY_SIZE(s5pc100_init_clocks));
clkp = s5pc100_init_clocks_disable;
size = ARRAY_SIZE(s5pc100_init_clocks_disable);
diff --git a/arch/arm/plat-s5pc1xx/dev-uart.c b/arch/arm/plat-s5pc1xx/dev-uart.c
index f749bc5407b..586c95c60bf 100644
--- a/arch/arm/plat-s5pc1xx/dev-uart.c
+++ b/arch/arm/plat-s5pc1xx/dev-uart.c
@@ -143,32 +143,3 @@ struct s3c24xx_uart_resources s5pc1xx_uart_resources[] __initdata = {
.nr_resources = ARRAY_SIZE(s5pc1xx_uart3_resource),
},
};
-
-/* uart devices */
-
-static struct platform_device s3c24xx_uart_device0 = {
- .id = 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
- .id = 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
- .id = 2,
-};
-
-static struct platform_device s3c24xx_uart_device3 = {
- .id = 3,
-};
-
-struct platform_device *s3c24xx_uart_src[4] = {
- &s3c24xx_uart_device0,
- &s3c24xx_uart_device1,
- &s3c24xx_uart_device2,
- &s3c24xx_uart_device3,
-};
-
-struct platform_device *s3c24xx_uart_devs[4] = {
-};
-
diff --git a/arch/arm/plat-s5pc1xx/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c
index bba675df9c7..a4f67e80a15 100644
--- a/arch/arm/plat-s5pc1xx/gpio-config.c
+++ b/arch/arm/plat-s5pc1xx/gpio-config.c
@@ -16,7 +16,7 @@
#include <linux/gpio.h>
#include <linux/io.h>
-#include <mach/gpio-core.h>
+#include <plat/gpio-core.h>
#include <plat/gpio-cfg-s5pc1xx.h>
s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off)
diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c
index facb410e7a7..1ffc57ac293 100644
--- a/arch/arm/plat-s5pc1xx/gpiolib.c
+++ b/arch/arm/plat-s5pc1xx/gpiolib.c
@@ -17,8 +17,8 @@
#include <linux/gpio.h>
#include <mach/map.h>
-#include <mach/gpio-core.h>
+#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
#include <plat/regs-gpio.h>
diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
index ef8736366f0..409c804315e 100644
--- a/arch/arm/plat-s5pc1xx/include/plat/irqs.h
+++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
@@ -88,11 +88,11 @@
#define IRQ_MDMA S5PC1XX_IRQ_VIC0(18)
#define IRQ_PDMA0 S5PC1XX_IRQ_VIC0(19)
#define IRQ_PDMA1 S5PC1XX_IRQ_VIC0(20)
-#define IRQ_TIMER0 S5PC1XX_IRQ_VIC0(21)
-#define IRQ_TIMER1 S5PC1XX_IRQ_VIC0(22)
-#define IRQ_TIMER2 S5PC1XX_IRQ_VIC0(23)
-#define IRQ_TIMER3 S5PC1XX_IRQ_VIC0(24)
-#define IRQ_TIMER4 S5PC1XX_IRQ_VIC0(25)
+#define IRQ_TIMER0_VIC S5PC1XX_IRQ_VIC0(21)
+#define IRQ_TIMER1_VIC S5PC1XX_IRQ_VIC0(22)
+#define IRQ_TIMER2_VIC S5PC1XX_IRQ_VIC0(23)
+#define IRQ_TIMER3_VIC S5PC1XX_IRQ_VIC0(24)
+#define IRQ_TIMER4_VIC S5PC1XX_IRQ_VIC0(25)
#define IRQ_SYSTIMER S5PC1XX_IRQ_VIC0(26)
#define IRQ_WDT S5PC1XX_IRQ_VIC0(27)
#define IRQ_RTC_ALARM S5PC1XX_IRQ_VIC0(28)
@@ -171,8 +171,15 @@
#define IRQ_SDMIRQ S5PC1XX_IRQ_VIC2(30)
#define IRQ_SDMFIQ S5PC1XX_IRQ_VIC2(31)
+#define IRQ_TIMER(x) (IRQ_SDMFIQ + 1 + (x))
+#define IRQ_TIMER0 IRQ_TIMER(0)
+#define IRQ_TIMER1 IRQ_TIMER(1)
+#define IRQ_TIMER2 IRQ_TIMER(2)
+#define IRQ_TIMER3 IRQ_TIMER(3)
+#define IRQ_TIMER4 IRQ_TIMER(4)
+
/* External interrupt */
-#define S3C_IRQ_EINT_BASE (IRQ_SDMFIQ + 1)
+#define S3C_IRQ_EINT_BASE (IRQ_SDMFIQ + 6)
#define S3C_EINT(x) (S3C_IRQ_EINT_BASE + (x - 16))
#define IRQ_EINT(x) (x < 16 ? IRQ_EINT0 + x : S3C_EINT(x))
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
index c5cc86e92d6..24dec4e5253 100644
--- a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
@@ -61,73 +61,10 @@
#define S5PC100_EPLL_MASK 0xffffffff
#define S5PC100_EPLLVAL(_m, _p, _s) ((_m) << 16 | ((_p) << 8) | ((_s)))
-/* CLKSRC0 */
-#define S5PC100_CLKSRC0_APLL_MASK (0x1<<0)
-#define S5PC100_CLKSRC0_APLL_SHIFT (0)
-#define S5PC100_CLKSRC0_MPLL_MASK (0x1<<4)
-#define S5PC100_CLKSRC0_MPLL_SHIFT (4)
-#define S5PC100_CLKSRC0_EPLL_MASK (0x1<<8)
-#define S5PC100_CLKSRC0_EPLL_SHIFT (8)
-#define S5PC100_CLKSRC0_HPLL_MASK (0x1<<12)
-#define S5PC100_CLKSRC0_HPLL_SHIFT (12)
-#define S5PC100_CLKSRC0_AMMUX_MASK (0x1<<16)
-#define S5PC100_CLKSRC0_AMMUX_SHIFT (16)
-#define S5PC100_CLKSRC0_HREF_MASK (0x1<<20)
-#define S5PC100_CLKSRC0_HREF_SHIFT (20)
-#define S5PC100_CLKSRC0_ONENAND_MASK (0x1<<24)
-#define S5PC100_CLKSRC0_ONENAND_SHIFT (24)
-
-
-/* CLKSRC1 */
-#define S5PC100_CLKSRC1_UART_MASK (0x1<<0)
-#define S5PC100_CLKSRC1_UART_SHIFT (0)
-#define S5PC100_CLKSRC1_SPI0_MASK (0x3<<4)
-#define S5PC100_CLKSRC1_SPI0_SHIFT (4)
-#define S5PC100_CLKSRC1_SPI1_MASK (0x3<<8)
-#define S5PC100_CLKSRC1_SPI1_SHIFT (8)
-#define S5PC100_CLKSRC1_SPI2_MASK (0x3<<12)
-#define S5PC100_CLKSRC1_SPI2_SHIFT (12)
-#define S5PC100_CLKSRC1_IRDA_MASK (0x3<<16)
-#define S5PC100_CLKSRC1_IRDA_SHIFT (16)
-#define S5PC100_CLKSRC1_UHOST_MASK (0x3<<20)
-#define S5PC100_CLKSRC1_UHOST_SHIFT (20)
-#define S5PC100_CLKSRC1_CLK48M_MASK (0x1<<24)
+/* CLKSRC0..CLKSRC3 -> mostly removed due to clksrc updates */
+#define S5PC100_CLKSRC1_CLK48M_MASK (0x1<<24)
#define S5PC100_CLKSRC1_CLK48M_SHIFT (24)
-/* CLKSRC2 */
-#define S5PC100_CLKSRC2_MMC0_MASK (0x3<<0)
-#define S5PC100_CLKSRC2_MMC0_SHIFT (0)
-#define S5PC100_CLKSRC2_MMC1_MASK (0x3<<4)
-#define S5PC100_CLKSRC2_MMC1_SHIFT (4)
-#define S5PC100_CLKSRC2_MMC2_MASK (0x3<<8)
-#define S5PC100_CLKSRC2_MMC2_SHIFT (8)
-#define S5PC100_CLKSRC2_LCD_MASK (0x3<<12)
-#define S5PC100_CLKSRC2_LCD_SHIFT (12)
-#define S5PC100_CLKSRC2_FIMC0_MASK (0x3<<16)
-#define S5PC100_CLKSRC2_FIMC0_SHIFT (16)
-#define S5PC100_CLKSRC2_FIMC1_MASK (0x3<<20)
-#define S5PC100_CLKSRC2_FIMC1_SHIFT (20)
-#define S5PC100_CLKSRC2_FIMC2_MASK (0x3<<24)
-#define S5PC100_CLKSRC2_FIMC2_SHIFT (24)
-#define S5PC100_CLKSRC2_MIXER_MASK (0x3<<28)
-#define S5PC100_CLKSRC2_MIXER_SHIFT (28)
-
-/* CLKSRC3 */
-#define S5PC100_CLKSRC3_PWI_MASK (0x3<<0)
-#define S5PC100_CLKSRC3_PWI_SHIFT (0)
-#define S5PC100_CLKSRC3_HCLKD2_MASK (0x1<<4)
-#define S5PC100_CLKSRC3_HCLKD2_SHIFT (4)
-#define S5PC100_CLKSRC3_I2SD2_MASK (0x3<<8)
-#define S5PC100_CLKSRC3_I2SD2_SHIFT (8)
-#define S5PC100_CLKSRC3_AUDIO0_MASK (0x7<<12)
-#define S5PC100_CLKSRC3_AUDIO0_SHIFT (12)
-#define S5PC100_CLKSRC3_AUDIO1_MASK (0x7<<16)
-#define S5PC100_CLKSRC3_AUDIO1_SHIFT (16)
-#define S5PC100_CLKSRC3_AUDIO2_MASK (0x7<<20)
-#define S5PC100_CLKSRC3_AUDIO2_SHIFT (20)
-#define S5PC100_CLKSRC3_SPDIF_MASK (0x3<<24)
-#define S5PC100_CLKSRC3_SPDIF_SHIFT (24)
-
/* CLKDIV0 */
#define S5PC100_CLKDIV0_APLL_MASK (0x1<<0)
#define S5PC100_CLKDIV0_APLL_SHIFT (0)
@@ -140,7 +77,7 @@
#define S5PC100_CLKDIV0_SECSS_MASK (0x7<<16)
#define S5PC100_CLKDIV0_SECSS_SHIFT (16)
-/* CLKDIV1 */
+/* CLKDIV1 (OneNAND clock only used in one place, removed) */
#define S5PC100_CLKDIV1_APLL2_MASK (0x7<<0)
#define S5PC100_CLKDIV1_APLL2_SHIFT (0)
#define S5PC100_CLKDIV1_MPLL_MASK (0x3<<4)
@@ -151,56 +88,12 @@
#define S5PC100_CLKDIV1_D1_SHIFT (12)
#define S5PC100_CLKDIV1_PCLKD1_MASK (0x7<<16)
#define S5PC100_CLKDIV1_PCLKD1_SHIFT (16)
-#define S5PC100_CLKDIV1_ONENAND_MASK (0x3<<20)
-#define S5PC100_CLKDIV1_ONENAND_SHIFT (20)
#define S5PC100_CLKDIV1_CAM_MASK (0x1F<<24)
#define S5PC100_CLKDIV1_CAM_SHIFT (24)
-/* CLKDIV2 */
-#define S5PC100_CLKDIV2_UART_MASK (0x7<<0)
-#define S5PC100_CLKDIV2_UART_SHIFT (0)
-#define S5PC100_CLKDIV2_SPI0_MASK (0xf<<4)
-#define S5PC100_CLKDIV2_SPI0_SHIFT (4)
-#define S5PC100_CLKDIV2_SPI1_MASK (0xf<<8)
-#define S5PC100_CLKDIV2_SPI1_SHIFT (8)
-#define S5PC100_CLKDIV2_SPI2_MASK (0xf<<12)
-#define S5PC100_CLKDIV2_SPI2_SHIFT (12)
-#define S5PC100_CLKDIV2_IRDA_MASK (0xf<<16)
-#define S5PC100_CLKDIV2_IRDA_SHIFT (16)
-#define S5PC100_CLKDIV2_UHOST_MASK (0xf<<20)
-#define S5PC100_CLKDIV2_UHOST_SHIFT (20)
-
-/* CLKDIV3 */
-#define S5PC100_CLKDIV3_MMC0_MASK (0xf<<0)
-#define S5PC100_CLKDIV3_MMC0_SHIFT (0)
-#define S5PC100_CLKDIV3_MMC1_MASK (0xf<<4)
-#define S5PC100_CLKDIV3_MMC1_SHIFT (4)
-#define S5PC100_CLKDIV3_MMC2_MASK (0xf<<8)
-#define S5PC100_CLKDIV3_MMC2_SHIFT (8)
-#define S5PC100_CLKDIV3_LCD_MASK (0xf<<12)
-#define S5PC100_CLKDIV3_LCD_SHIFT (12)
-#define S5PC100_CLKDIV3_FIMC0_MASK (0xf<<16)
-#define S5PC100_CLKDIV3_FIMC0_SHIFT (16)
-#define S5PC100_CLKDIV3_FIMC1_MASK (0xf<<20)
-#define S5PC100_CLKDIV3_FIMC1_SHIFT (20)
-#define S5PC100_CLKDIV3_FIMC2_MASK (0xf<<24)
-#define S5PC100_CLKDIV3_FIMC2_SHIFT (24)
-#define S5PC100_CLKDIV3_HDMI_MASK (0xf<<28)
-#define S5PC100_CLKDIV3_HDMI_SHIFT (28)
-
-/* CLKDIV4 */
-#define S5PC100_CLKDIV4_PWI_MASK (0x7<<0)
-#define S5PC100_CLKDIV4_PWI_SHIFT (0)
-#define S5PC100_CLKDIV4_HCLKD2_MASK (0x7<<4)
-#define S5PC100_CLKDIV4_HCLKD2_SHIFT (4)
-#define S5PC100_CLKDIV4_I2SD2_MASK (0xf<<8)
-#define S5PC100_CLKDIV4_I2SD2_SHIFT (8)
-#define S5PC100_CLKDIV4_AUDIO0_MASK (0xf<<12)
-#define S5PC100_CLKDIV4_AUDIO0_SHIFT (12)
-#define S5PC100_CLKDIV4_AUDIO1_MASK (0xf<<16)
-#define S5PC100_CLKDIV4_AUDIO1_SHIFT (16)
-#define S5PC100_CLKDIV4_AUDIO2_MASK (0xf<<20)
-#define S5PC100_CLKDIV4_AUDIO2_SHIFT (20)
+/* CLKDIV2 => removed in clksrc update */
+/* CLKDIV3 => removed in clksrc update, or not needed */
+/* CLKDIV4 => removed in clksrc update, or not needed */
/* HCLKD0/PCLKD0 Clock Gate 0 Registers */
#define S5PC100_CLKGATE_D00_INTC (1<<0)
diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c
index e44fd04ef33..bfc52482781 100644
--- a/arch/arm/plat-s5pc1xx/irq.c
+++ b/arch/arm/plat-s5pc1xx/irq.c
@@ -20,87 +20,14 @@
#include <asm/hardware/vic.h>
#include <mach/map.h>
-#include <plat/regs-timer.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.h>
#include <plat/cpu.h>
-/* Timer interrupt handling */
-
-static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
-{
- generic_handle_irq(sub_irq);
-}
-
-static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER0);
-}
-
-static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER1);
-}
-
-static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER2);
-}
-
-static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER3);
-}
-
-static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
-{
- s3c_irq_demux_timer(irq, IRQ_TIMER4);
-}
-
-/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-
-static void s3c_irq_timer_mask(unsigned int irq)
-{
- u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
- reg &= 0x1f; /* mask out pending interrupts */
- reg &= ~(1 << (irq - IRQ_TIMER0));
- __raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_unmask(unsigned int irq)
-{
- u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
- reg &= 0x1f; /* mask out pending interrupts */
- reg |= 1 << (irq - IRQ_TIMER0);
- __raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_ack(unsigned int irq)
-{
- u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-
- reg &= 0x1f; /* mask out pending interrupts */
- reg |= (1 << 5) << (irq - IRQ_TIMER0);
- __raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static struct irq_chip s3c_irq_timer = {
- .name = "s3c-timer",
- .mask = s3c_irq_timer_mask,
- .unmask = s3c_irq_timer_unmask,
- .ack = s3c_irq_timer_ack,
-};
-
-struct uart_irq {
- void __iomem *regs;
- unsigned int base_irq;
- unsigned int parent_irq;
-};
-
/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
* are consecutive when looking up the interrupt in the demux routines.
*/
-static struct uart_irq uart_irqs[] = {
+static struct s3c_uart_irq uart_irqs[] = {
[0] = {
.regs = (void *)S3C_VA_UART0,
.base_irq = IRQ_S3CUART_BASE0,
@@ -123,113 +50,9 @@ static struct uart_irq uart_irqs[] = {
},
};
-static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
-{
- struct uart_irq *uirq = get_irq_chip_data(irq);
- return uirq->regs;
-}
-
-static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
-{
- return irq & 3;
-}
-
-/* UART interrupt registers, not worth adding to seperate include header */
-#define S3C64XX_UINTP 0x30
-#define S3C64XX_UINTSP 0x34
-#define S3C64XX_UINTM 0x38
-
-static void s3c_irq_uart_mask(unsigned int irq)
-{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
- u32 reg;
-
- reg = __raw_readl(regs + S3C64XX_UINTM);
- reg |= (1 << bit);
- __raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_maskack(unsigned int irq)
-{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
- u32 reg;
-
- reg = __raw_readl(regs + S3C64XX_UINTM);
- reg |= (1 << bit);
- __raw_writel(reg, regs + S3C64XX_UINTM);
- __raw_writel(1 << bit, regs + S3C64XX_UINTP);
-}
-
-static void s3c_irq_uart_unmask(unsigned int irq)
-{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
- u32 reg;
-
- reg = __raw_readl(regs + S3C64XX_UINTM);
- reg &= ~(1 << bit);
- __raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_ack(unsigned int irq)
-{
- void __iomem *regs = s3c_irq_uart_base(irq);
- unsigned int bit = s3c_irq_uart_bit(irq);
-
- __raw_writel(1 << bit, regs + S3C64XX_UINTP);
-}
-
-static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
-{
- struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
- u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
- int base = uirq->base_irq;
-
- if (pend & (1 << 0))
- generic_handle_irq(base);
- if (pend & (1 << 1))
- generic_handle_irq(base + 1);
- if (pend & (1 << 2))
- generic_handle_irq(base + 2);
- if (pend & (1 << 3))
- generic_handle_irq(base + 3);
-}
-
-static struct irq_chip s3c_irq_uart = {
- .name = "s3c-uart",
- .mask = s3c_irq_uart_mask,
- .unmask = s3c_irq_uart_unmask,
- .mask_ack = s3c_irq_uart_maskack,
- .ack = s3c_irq_uart_ack,
-};
-
-static void __init s5pc1xx_uart_irq(struct uart_irq *uirq)
-{
- void __iomem *reg_base = uirq->regs;
- unsigned int irq;
- int offs;
-
- /* mask all interrupts at the start. */
- __raw_writel(0xf, reg_base + S3C64XX_UINTM);
-
- for (offs = 0; offs < 3; offs++) {
- irq = uirq->base_irq + offs;
-
- set_irq_chip(irq, &s3c_irq_uart);
- set_irq_chip_data(irq, uirq);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
-
- set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
-}
-
void __init s5pc1xx_init_irq(u32 *vic_valid, int num)
{
int i;
- int uart, irq;
printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
@@ -240,20 +63,13 @@ void __init s5pc1xx_init_irq(u32 *vic_valid, int num)
/* add the timer sub-irqs */
- set_irq_chained_handler(IRQ_TIMER0, s3c_irq_demux_timer0);
- set_irq_chained_handler(IRQ_TIMER1, s3c_irq_demux_timer1);
- set_irq_chained_handler(IRQ_TIMER2, s3c_irq_demux_timer2);
- set_irq_chained_handler(IRQ_TIMER3, s3c_irq_demux_timer3);
- set_irq_chained_handler(IRQ_TIMER4, s3c_irq_demux_timer4);
-
- for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
- set_irq_chip(irq, &s3c_irq_timer);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
+ s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
+ s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
+ s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
+ s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
+ s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
- for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
- s5pc1xx_uart_irq(&uart_irqs[uart]);
+ s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
}
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
index b436d44510c..2bf6c57a96a 100644
--- a/arch/arm/plat-s5pc1xx/s5pc100-clock.c
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -29,6 +29,7 @@
#include <plat/regs-clock.h>
#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
#include <plat/cpu.h>
#include <plat/pll.h>
#include <plat/devs.h>
@@ -51,23 +52,6 @@ static struct clk clk_ext_xtal_mux = {
#define clk_fout_mpll clk_mpll
#define clk_vclk_54m clk_54m
-struct clk_sources {
- unsigned int nr_sources;
- struct clk **sources;
-};
-
-struct clksrc_clk {
- struct clk clk;
- unsigned int mask;
- unsigned int shift;
-
- struct clk_sources *sources;
-
- unsigned int divider_shift;
- void __iomem *reg_divider;
- void __iomem *reg_source;
-};
-
/* APLL */
static struct clk clk_fout_apll = {
.name = "fout_apll",
@@ -80,7 +64,7 @@ static struct clk *clk_src_apll_list[] = {
[1] = &clk_fout_apll,
};
-static struct clk_sources clk_src_apll = {
+static struct clksrc_sources clk_src_apll = {
.sources = clk_src_apll_list,
.nr_sources = ARRAY_SIZE(clk_src_apll_list),
};
@@ -90,10 +74,8 @@ static struct clksrc_clk clk_mout_apll = {
.name = "mout_apll",
.id = -1,
},
- .shift = S5PC100_CLKSRC0_APLL_SHIFT,
- .mask = S5PC100_CLKSRC0_APLL_MASK,
.sources = &clk_src_apll,
- .reg_source = S5PC100_CLKSRC0,
+ .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 0, .size = 1, },
};
static unsigned long s5pc100_clk_dout_apll_get_rate(struct clk *clk)
@@ -111,7 +93,9 @@ static struct clk clk_dout_apll = {
.name = "dout_apll",
.id = -1,
.parent = &clk_mout_apll.clk,
- .get_rate = s5pc100_clk_dout_apll_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_apll_get_rate,
+ },
};
static unsigned long s5pc100_clk_arm_get_rate(struct clk *clk)
@@ -165,9 +149,11 @@ static struct clk clk_arm = {
.name = "armclk",
.id = -1,
.parent = &clk_dout_apll,
- .get_rate = s5pc100_clk_arm_get_rate,
- .set_rate = s5pc100_clk_arm_set_rate,
- .round_rate = s5pc100_clk_arm_round_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_arm_get_rate,
+ .set_rate = s5pc100_clk_arm_set_rate,
+ .round_rate = s5pc100_clk_arm_round_rate,
+ },
};
static unsigned long s5pc100_clk_dout_d0_bus_get_rate(struct clk *clk)
@@ -185,7 +171,9 @@ static struct clk clk_dout_d0_bus = {
.name = "dout_d0_bus",
.id = -1,
.parent = &clk_arm,
- .get_rate = s5pc100_clk_dout_d0_bus_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_d0_bus_get_rate,
+ },
};
static unsigned long s5pc100_clk_dout_pclkd0_get_rate(struct clk *clk)
@@ -203,7 +191,9 @@ static struct clk clk_dout_pclkd0 = {
.name = "dout_pclkd0",
.id = -1,
.parent = &clk_dout_d0_bus,
- .get_rate = s5pc100_clk_dout_pclkd0_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_pclkd0_get_rate,
+ },
};
static unsigned long s5pc100_clk_dout_apll2_get_rate(struct clk *clk)
@@ -221,7 +211,9 @@ static struct clk clk_dout_apll2 = {
.name = "dout_apll2",
.id = -1,
.parent = &clk_mout_apll.clk,
- .get_rate = s5pc100_clk_dout_apll2_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_apll2_get_rate,
+ },
};
/* MPLL */
@@ -230,7 +222,7 @@ static struct clk *clk_src_mpll_list[] = {
[1] = &clk_fout_mpll,
};
-static struct clk_sources clk_src_mpll = {
+static struct clksrc_sources clk_src_mpll = {
.sources = clk_src_mpll_list,
.nr_sources = ARRAY_SIZE(clk_src_mpll_list),
};
@@ -240,10 +232,8 @@ static struct clksrc_clk clk_mout_mpll = {
.name = "mout_mpll",
.id = -1,
},
- .shift = S5PC100_CLKSRC0_MPLL_SHIFT,
- .mask = S5PC100_CLKSRC0_MPLL_MASK,
.sources = &clk_src_mpll,
- .reg_source = S5PC100_CLKSRC0,
+ .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 4, .size = 1, },
};
static struct clk *clkset_am_list[] = {
@@ -251,7 +241,7 @@ static struct clk *clkset_am_list[] = {
[1] = &clk_dout_apll2,
};
-static struct clk_sources clk_src_am = {
+static struct clksrc_sources clk_src_am = {
.sources = clkset_am_list,
.nr_sources = ARRAY_SIZE(clkset_am_list),
};
@@ -261,10 +251,8 @@ static struct clksrc_clk clk_mout_am = {
.name = "mout_am",
.id = -1,
},
- .shift = S5PC100_CLKSRC0_AMMUX_SHIFT,
- .mask = S5PC100_CLKSRC0_AMMUX_MASK,
.sources = &clk_src_am,
- .reg_source = S5PC100_CLKSRC0,
+ .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 16, .size = 1, },
};
static unsigned long s5pc100_clk_dout_d1_bus_get_rate(struct clk *clk)
@@ -284,7 +272,9 @@ static struct clk clk_dout_d1_bus = {
.name = "dout_d1_bus",
.id = -1,
.parent = &clk_mout_am.clk,
- .get_rate = s5pc100_clk_dout_d1_bus_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_d1_bus_get_rate,
+ },
};
static struct clk *clkset_onenand_list[] = {
@@ -292,7 +282,7 @@ static struct clk *clkset_onenand_list[] = {
[1] = &clk_dout_d1_bus,
};
-static struct clk_sources clk_src_onenand = {
+static struct clksrc_sources clk_src_onenand = {
.sources = clkset_onenand_list,
.nr_sources = ARRAY_SIZE(clkset_onenand_list),
};
@@ -302,10 +292,8 @@ static struct clksrc_clk clk_mout_onenand = {
.name = "mout_onenand",
.id = -1,
},
- .shift = S5PC100_CLKSRC0_ONENAND_SHIFT,
- .mask = S5PC100_CLKSRC0_ONENAND_MASK,
.sources = &clk_src_onenand,
- .reg_source = S5PC100_CLKSRC0,
+ .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 24, .size = 1, },
};
static unsigned long s5pc100_clk_dout_pclkd1_get_rate(struct clk *clk)
@@ -325,7 +313,9 @@ static struct clk clk_dout_pclkd1 = {
.name = "dout_pclkd1",
.id = -1,
.parent = &clk_dout_d1_bus,
- .get_rate = s5pc100_clk_dout_pclkd1_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_pclkd1_get_rate,
+ },
};
static unsigned long s5pc100_clk_dout_mpll2_get_rate(struct clk *clk)
@@ -345,7 +335,9 @@ static struct clk clk_dout_mpll2 = {
.name = "dout_mpll2",
.id = -1,
.parent = &clk_mout_am.clk,
- .get_rate = s5pc100_clk_dout_mpll2_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_mpll2_get_rate,
+ },
};
static unsigned long s5pc100_clk_dout_cam_get_rate(struct clk *clk)
@@ -365,7 +357,9 @@ static struct clk clk_dout_cam = {
.name = "dout_cam",
.id = -1,
.parent = &clk_dout_mpll2,
- .get_rate = s5pc100_clk_dout_cam_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_cam_get_rate,
+ },
};
static unsigned long s5pc100_clk_dout_mpll_get_rate(struct clk *clk)
@@ -385,7 +379,9 @@ static struct clk clk_dout_mpll = {
.name = "dout_mpll",
.id = -1,
.parent = &clk_mout_am.clk,
- .get_rate = s5pc100_clk_dout_mpll_get_rate,
+ .ops = &(struct clk_ops) {
+ .get_rate = s5pc100_clk_dout_mpll_get_rate,
+ },
};
/* EPLL */
@@ -399,7 +395,7 @@ static struct clk *clk_src_epll_list[] = {
[1] = &clk_fout_epll,
};
-static struct clk_sources clk_src_epll = {
+static struct clksrc_sources clk_src_epll = {
.sources = clk_src_epll_list,
.nr_sources = ARRAY_SIZE(clk_src_epll_list),
};
@@ -409,10 +405,8 @@ static struct clksrc_clk clk_mout_epll = {
.name = "mout_epll",
.id = -1,
},
- .shift = S5PC100_CLKSRC0_EPLL_SHIFT,
- .mask = S5PC100_CLKSRC0_EPLL_MASK,
- .sources = &clk_src_epll,
- .reg_source = S5PC100_CLKSRC0,
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 8, .size = 1, },
};
/* HPLL */
@@ -426,7 +420,7 @@ static struct clk *clk_src_hpll_list[] = {
[1] = &clk_fout_hpll,
};
-static struct clk_sources clk_src_hpll = {
+static struct clksrc_sources clk_src_hpll = {
.sources = clk_src_hpll_list,
.nr_sources = ARRAY_SIZE(clk_src_hpll_list),
};
@@ -436,10 +430,8 @@ static struct clksrc_clk clk_mout_hpll = {
.name = "mout_hpll",
.id = -1,
},
- .shift = S5PC100_CLKSRC0_HPLL_SHIFT,
- .mask = S5PC100_CLKSRC0_HPLL_MASK,
- .sources = &clk_src_hpll,
- .reg_source = S5PC100_CLKSRC0,
+ .sources = &clk_src_hpll,
+ .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 12, .size = 1, },
};
/* Peripherals */
@@ -454,190 +446,6 @@ static struct clksrc_clk clk_mout_hpll = {
* have a common parent divisor so are not included here.
*/
-static inline struct clksrc_clk *to_clksrc(struct clk *clk)
-{
- return container_of(clk, struct clksrc_clk, clk);
-}
-
-static unsigned long s5pc100_getrate_clksrc(struct clk *clk)
-{
- struct clksrc_clk *sclk = to_clksrc(clk);
- unsigned long rate = clk_get_rate(clk->parent);
- u32 clkdiv = __raw_readl(sclk->reg_divider);
-
- clkdiv >>= sclk->divider_shift;
- clkdiv &= 0xf;
- clkdiv++;
-
- rate /= clkdiv;
- return rate;
-}
-
-static int s5pc100_setrate_clksrc(struct clk *clk, unsigned long rate)
-{
- struct clksrc_clk *sclk = to_clksrc(clk);
- void __iomem *reg = sclk->reg_divider;
- unsigned int div;
- u32 val;
-
- rate = clk_round_rate(clk, rate);
- div = clk_get_rate(clk->parent) / rate;
- if (div > 16)
- return -EINVAL;
-
- val = __raw_readl(reg);
- val &= ~(0xf << sclk->divider_shift);
- val |= (div - 1) << sclk->divider_shift;
- __raw_writel(val, reg);
-
- return 0;
-}
-
-static int s5pc100_setparent_clksrc(struct clk *clk, struct clk *parent)
-{
- struct clksrc_clk *sclk = to_clksrc(clk);
- struct clk_sources *srcs = sclk->sources;
- u32 clksrc = __raw_readl(sclk->reg_source);
- int src_nr = -1;
- int ptr;
-
- for (ptr = 0; ptr < srcs->nr_sources; ptr++)
- if (srcs->sources[ptr] == parent) {
- src_nr = ptr;
- break;
- }
-
- if (src_nr >= 0) {
- clksrc &= ~sclk->mask;
- clksrc |= src_nr << sclk->shift;
-
- __raw_writel(clksrc, sclk->reg_source);
- return 0;
- }
-
- return -EINVAL;
-}
-
-static unsigned long s5pc100_roundrate_clksrc(struct clk *clk,
- unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- int div;
-
- if (rate > parent_rate)
- rate = parent_rate;
- else {
- div = rate / parent_rate;
-
- if (div == 0)
- div = 1;
- if (div > 16)
- div = 16;
-
- rate = parent_rate / div;
- }
-
- return rate;
-}
-
-static struct clk *clkset_spi_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll2,
- &clk_fin_epll,
- &clk_mout_hpll.clk,
-};
-
-static struct clk_sources clkset_spi = {
- .sources = clkset_spi_list,
- .nr_sources = ARRAY_SIZE(clkset_spi_list),
-};
-
-static struct clksrc_clk clk_spi0 = {
- .clk = {
- .name = "spi_bus",
- .id = 0,
- .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0,
- .enable = s5pc100_sclk0_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC1_SPI0_SHIFT,
- .mask = S5PC100_CLKSRC1_SPI0_MASK,
- .sources = &clkset_spi,
- .divider_shift = S5PC100_CLKDIV2_SPI0_SHIFT,
- .reg_divider = S5PC100_CLKDIV2,
- .reg_source = S5PC100_CLKSRC1,
-};
-
-static struct clksrc_clk clk_spi1 = {
- .clk = {
- .name = "spi_bus",
- .id = 1,
- .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1,
- .enable = s5pc100_sclk0_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC1_SPI1_SHIFT,
- .mask = S5PC100_CLKSRC1_SPI1_MASK,
- .sources = &clkset_spi,
- .divider_shift = S5PC100_CLKDIV2_SPI1_SHIFT,
- .reg_divider = S5PC100_CLKDIV2,
- .reg_source = S5PC100_CLKSRC1,
-};
-
-static struct clksrc_clk clk_spi2 = {
- .clk = {
- .name = "spi_bus",
- .id = 2,
- .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2,
- .enable = s5pc100_sclk0_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC1_SPI2_SHIFT,
- .mask = S5PC100_CLKSRC1_SPI2_MASK,
- .sources = &clkset_spi,
- .divider_shift = S5PC100_CLKDIV2_SPI2_SHIFT,
- .reg_divider = S5PC100_CLKDIV2,
- .reg_source = S5PC100_CLKSRC1,
-};
-
-static struct clk *clkset_uart_list[] = {
- &clk_mout_epll.clk,
- &clk_dout_mpll,
-};
-
-static struct clk_sources clkset_uart = {
- .sources = clkset_uart_list,
- .nr_sources = ARRAY_SIZE(clkset_uart_list),
-};
-
-static struct clksrc_clk clk_uart_uclk1 = {
- .clk = {
- .name = "uclk1",
- .id = -1,
- .ctrlbit = S5PC100_CLKGATE_SCLK0_UART,
- .enable = s5pc100_sclk0_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC1_UART_SHIFT,
- .mask = S5PC100_CLKSRC1_UART_MASK,
- .sources = &clkset_uart,
- .divider_shift = S5PC100_CLKDIV2_UART_SHIFT,
- .reg_divider = S5PC100_CLKDIV2,
- .reg_source = S5PC100_CLKSRC1,
-};
-
static struct clk clk_iis_cd0 = {
.name = "iis_cdclk0",
.id = -1,
@@ -672,28 +480,31 @@ static struct clk *clkset_audio0_list[] = {
&clk_mout_hpll.clk,
};
-static struct clk_sources clkset_audio0 = {
+static struct clksrc_sources clkset_audio0 = {
.sources = clkset_audio0_list,
.nr_sources = ARRAY_SIZE(clkset_audio0_list),
};
-static struct clksrc_clk clk_audio0 = {
- .clk = {
- .name = "audio-bus",
- .id = 0,
- .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO0,
- .enable = s5pc100_sclk1_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC3_AUDIO0_SHIFT,
- .mask = S5PC100_CLKSRC3_AUDIO0_MASK,
- .sources = &clkset_audio0,
- .divider_shift = S5PC100_CLKDIV4_AUDIO0_SHIFT,
- .reg_divider = S5PC100_CLKDIV4,
- .reg_source = S5PC100_CLKSRC3,
+static struct clk *clkset_spi_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll2,
+ &clk_fin_epll,
+ &clk_mout_hpll.clk,
+};
+
+static struct clksrc_sources clkset_spi = {
+ .sources = clkset_spi_list,
+ .nr_sources = ARRAY_SIZE(clkset_spi_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
};
static struct clk *clkset_audio1_list[] = {
@@ -705,30 +516,11 @@ static struct clk *clkset_audio1_list[] = {
&clk_mout_hpll.clk,
};
-static struct clk_sources clkset_audio1 = {
+static struct clksrc_sources clkset_audio1 = {
.sources = clkset_audio1_list,
.nr_sources = ARRAY_SIZE(clkset_audio1_list),
};
-static struct clksrc_clk clk_audio1 = {
- .clk = {
- .name = "audio-bus",
- .id = 1,
- .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO1,
- .enable = s5pc100_sclk1_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC3_AUDIO1_SHIFT,
- .mask = S5PC100_CLKSRC3_AUDIO1_MASK,
- .sources = &clkset_audio1,
- .divider_shift = S5PC100_CLKDIV4_AUDIO1_SHIFT,
- .reg_divider = S5PC100_CLKDIV4,
- .reg_source = S5PC100_CLKSRC3,
-};
-
static struct clk *clkset_audio2_list[] = {
&clk_mout_epll.clk,
&clk_dout_mpll,
@@ -737,52 +529,56 @@ static struct clk *clkset_audio2_list[] = {
&clk_mout_hpll.clk,
};
-static struct clk_sources clkset_audio2 = {
+static struct clksrc_sources clkset_audio2 = {
.sources = clkset_audio2_list,
.nr_sources = ARRAY_SIZE(clkset_audio2_list),
};
-static struct clksrc_clk clk_audio2 = {
- .clk = {
- .name = "audio-bus",
- .id = 2,
- .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO2,
- .enable = s5pc100_sclk1_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
+static struct clksrc_clk clksrc_audio[] = {
+ {
+ .clk = {
+ .name = "audio-bus",
+ .id = 0,
+ .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO0,
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clkset_audio0,
+ .reg_div = { .reg = S5PC100_CLKDIV4, .shift = 12, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC3, .shift = 12, .size = 3, },
+ }, {
+ .clk = {
+ .name = "audio-bus",
+ .id = 1,
+ .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO1,
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clkset_audio1,
+ .reg_div = { .reg = S5PC100_CLKDIV4, .shift = 16, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC3, .shift = 16, .size = 3, },
+ }, {
+ .clk = {
+ .name = "audio-bus",
+ .id = 2,
+ .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO2,
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clkset_audio2,
+ .reg_div = { .reg = S5PC100_CLKDIV4, .shift = 20, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC3, .shift = 20, .size = 3, },
},
- .shift = S5PC100_CLKSRC3_AUDIO2_SHIFT,
- .mask = S5PC100_CLKSRC3_AUDIO2_MASK,
- .sources = &clkset_audio2,
- .divider_shift = S5PC100_CLKDIV4_AUDIO2_SHIFT,
- .reg_divider = S5PC100_CLKDIV4,
- .reg_source = S5PC100_CLKSRC3,
};
static struct clk *clkset_spdif_list[] = {
- &clk_audio0.clk,
- &clk_audio1.clk,
- &clk_audio2.clk,
+ &clksrc_audio[0].clk,
+ &clksrc_audio[1].clk,
+ &clksrc_audio[2].clk,
};
-static struct clk_sources clkset_spdif = {
+static struct clksrc_sources clkset_spdif = {
.sources = clkset_spdif_list,
.nr_sources = ARRAY_SIZE(clkset_spdif_list),
};
-static struct clksrc_clk clk_spdif = {
- .clk = {
- .name = "spdif",
- .id = -1,
- },
- .shift = S5PC100_CLKSRC3_SPDIF_SHIFT,
- .mask = S5PC100_CLKSRC3_SPDIF_MASK,
- .sources = &clkset_spdif,
- .reg_source = S5PC100_CLKSRC3,
-};
-
static struct clk *clkset_lcd_fimc_list[] = {
&clk_mout_epll.clk,
&clk_dout_mpll,
@@ -790,87 +586,11 @@ static struct clk *clkset_lcd_fimc_list[] = {
&clk_vclk_54m,
};
-static struct clk_sources clkset_lcd_fimc = {
+static struct clksrc_sources clkset_lcd_fimc = {
.sources = clkset_lcd_fimc_list,
.nr_sources = ARRAY_SIZE(clkset_lcd_fimc_list),
};
-static struct clksrc_clk clk_lcd = {
- .clk = {
- .name = "lcd",
- .id = -1,
- .ctrlbit = S5PC100_CLKGATE_SCLK1_LCD,
- .enable = s5pc100_sclk1_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC2_LCD_SHIFT,
- .mask = S5PC100_CLKSRC2_LCD_MASK,
- .sources = &clkset_lcd_fimc,
- .divider_shift = S5PC100_CLKDIV3_LCD_SHIFT,
- .reg_divider = S5PC100_CLKDIV3,
- .reg_source = S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_fimc0 = {
- .clk = {
- .name = "fimc",
- .id = 0,
- .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC0,
- .enable = s5pc100_sclk1_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC2_FIMC0_SHIFT,
- .mask = S5PC100_CLKSRC2_FIMC0_MASK,
- .sources = &clkset_lcd_fimc,
- .divider_shift = S5PC100_CLKDIV3_FIMC0_SHIFT,
- .reg_divider = S5PC100_CLKDIV3,
- .reg_source = S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_fimc1 = {
- .clk = {
- .name = "fimc",
- .id = 1,
- .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC1,
- .enable = s5pc100_sclk1_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC2_FIMC1_SHIFT,
- .mask = S5PC100_CLKSRC2_FIMC1_MASK,
- .sources = &clkset_lcd_fimc,
- .divider_shift = S5PC100_CLKDIV3_FIMC1_SHIFT,
- .reg_divider = S5PC100_CLKDIV3,
- .reg_source = S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_fimc2 = {
- .clk = {
- .name = "fimc",
- .id = 2,
- .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC2,
- .enable = s5pc100_sclk1_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC2_FIMC2_SHIFT,
- .mask = S5PC100_CLKSRC2_FIMC2_MASK,
- .sources = &clkset_lcd_fimc,
- .divider_shift = S5PC100_CLKDIV3_FIMC2_SHIFT,
- .reg_divider = S5PC100_CLKDIV3,
- .reg_source = S5PC100_CLKSRC2,
-};
-
static struct clk *clkset_mmc_list[] = {
&clk_mout_epll.clk,
&clk_dout_mpll,
@@ -878,69 +598,11 @@ static struct clk *clkset_mmc_list[] = {
&clk_mout_hpll.clk ,
};
-static struct clk_sources clkset_mmc = {
+static struct clksrc_sources clkset_mmc = {
.sources = clkset_mmc_list,
.nr_sources = ARRAY_SIZE(clkset_mmc_list),
};
-static struct clksrc_clk clk_mmc0 = {
- .clk = {
- .name = "mmc_bus",
- .id = 0,
- .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0,
- .enable = s5pc100_sclk0_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC2_MMC0_SHIFT,
- .mask = S5PC100_CLKSRC2_MMC0_MASK,
- .sources = &clkset_mmc,
- .divider_shift = S5PC100_CLKDIV3_MMC0_SHIFT,
- .reg_divider = S5PC100_CLKDIV3,
- .reg_source = S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_mmc1 = {
- .clk = {
- .name = "mmc_bus",
- .id = 1,
- .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1,
- .enable = s5pc100_sclk0_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC2_MMC1_SHIFT,
- .mask = S5PC100_CLKSRC2_MMC1_MASK,
- .sources = &clkset_mmc,
- .divider_shift = S5PC100_CLKDIV3_MMC1_SHIFT,
- .reg_divider = S5PC100_CLKDIV3,
- .reg_source = S5PC100_CLKSRC2,
-};
-
-static struct clksrc_clk clk_mmc2 = {
- .clk = {
- .name = "mmc_bus",
- .id = 2,
- .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2,
- .enable = s5pc100_sclk0_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC2_MMC2_SHIFT,
- .mask = S5PC100_CLKSRC2_MMC2_MASK,
- .sources = &clkset_mmc,
- .divider_shift = S5PC100_CLKDIV3_MMC2_SHIFT,
- .reg_divider = S5PC100_CLKDIV3,
- .reg_source = S5PC100_CLKSRC2,
-};
-
-
static struct clk *clkset_usbhost_list[] = {
&clk_mout_epll.clk,
&clk_dout_mpll,
@@ -948,28 +610,141 @@ static struct clk *clkset_usbhost_list[] = {
&clk_48m,
};
-static struct clk_sources clkset_usbhost = {
+static struct clksrc_sources clkset_usbhost = {
.sources = clkset_usbhost_list,
.nr_sources = ARRAY_SIZE(clkset_usbhost_list),
};
-static struct clksrc_clk clk_usbhost = {
- .clk = {
- .name = "usbhost",
- .id = -1,
- .ctrlbit = S5PC100_CLKGATE_SCLK0_USBHOST,
- .enable = s5pc100_sclk0_ctrl,
- .set_parent = s5pc100_setparent_clksrc,
- .get_rate = s5pc100_getrate_clksrc,
- .set_rate = s5pc100_setrate_clksrc,
- .round_rate = s5pc100_roundrate_clksrc,
- },
- .shift = S5PC100_CLKSRC1_UHOST_SHIFT,
- .mask = S5PC100_CLKSRC1_UHOST_MASK,
- .sources = &clkset_usbhost,
- .divider_shift = S5PC100_CLKDIV2_UHOST_SHIFT,
- .reg_divider = S5PC100_CLKDIV2,
- .reg_source = S5PC100_CLKSRC1,
+static struct clksrc_clk clksrc_clks[] = {
+ {
+ .clk = {
+ .name = "spi_bus",
+ .id = 0,
+ .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0,
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clkset_spi,
+ .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 4, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 4, .size = 2, },
+ }, {
+ .clk = {
+ .name = "spi_bus",
+ .id = 1,
+ .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1,
+ .enable = s5pc100_sclk0_ctrl,
+ },
+ .sources = &clkset_spi,
+ .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 8, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 8, .size = 2, },
+ }, {
+ .clk = {
+ .name = "spi_bus",
+ .id = 2,
+ .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2,
+ .enable = s5pc100_sclk0_ctrl,
+ },
+ .sources = &clkset_spi,
+ .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 12, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 12, .size = 2, },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = S5PC100_CLKGATE_SCLK0_UART,
+ .enable = s5pc100_sclk0_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 0, .size = 3, },
+ .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 0, .size = 1, },
+ }, {
+ .clk = {
+ .name = "spdif",
+ .id = -1,
+ },
+ .sources = &clkset_spdif,
+ .reg_src = { .reg = S5PC100_CLKSRC3, .shift = 24, .size = 2, },
+ }, {
+ .clk = {
+ .name = "lcd",
+ .id = -1,
+ .ctrlbit = S5PC100_CLKGATE_SCLK1_LCD,
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clkset_lcd_fimc,
+ .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 12, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 12, .size = 2, },
+ }, {
+ .clk = {
+ .name = "fimc",
+ .id = 0,
+ .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC0,
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clkset_lcd_fimc,
+ .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 16, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 16, .size = 2, },
+ }, {
+ .clk = {
+ .name = "fimc",
+ .id = 1,
+ .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC1,
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clkset_lcd_fimc,
+ .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 20, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 20, .size = 2, },
+ }, {
+ .clk = {
+ .name = "fimc",
+ .id = 2,
+ .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC2,
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clkset_lcd_fimc,
+ .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 24, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 24, .size = 2, },
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 0,
+ .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0,
+ .enable = s5pc100_sclk0_ctrl,
+ },
+ .sources = &clkset_mmc,
+ .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 0, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 0, .size = 2, },
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 1,
+ .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1,
+ .enable = s5pc100_sclk0_ctrl,
+ },
+ .sources = &clkset_mmc,
+ .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 4, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 4, .size = 2, },
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 2,
+ .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2,
+ .enable = s5pc100_sclk0_ctrl,
+ },
+ .sources = &clkset_mmc,
+ .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 8, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 8, .size = 2, },
+ }, {
+ .clk = {
+ .name = "usbhost",
+ .id = -1,
+ .ctrlbit = S5PC100_CLKGATE_SCLK0_USBHOST,
+ .enable = s5pc100_sclk0_ctrl,
+ },
+ .sources = &clkset_usbhost,
+ .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 20, .size = 4, },
+ .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 20, .size = 2, },
+ }
};
/* Clock initialisation code */
@@ -981,45 +756,8 @@ static struct clksrc_clk *init_parents[] = {
&clk_mout_onenand,
&clk_mout_epll,
&clk_mout_hpll,
- &clk_spi0,
- &clk_spi1,
- &clk_spi2,
- &clk_uart_uclk1,
- &clk_audio0,
- &clk_audio1,
- &clk_audio2,
- &clk_spdif,
- &clk_lcd,
- &clk_fimc0,
- &clk_fimc1,
- &clk_fimc2,
- &clk_mmc0,
- &clk_mmc1,
- &clk_mmc2,
- &clk_usbhost,
};
-static void __init_or_cpufreq s5pc100_set_clksrc(struct clksrc_clk *clk)
-{
- struct clk_sources *srcs = clk->sources;
- u32 clksrc = __raw_readl(clk->reg_source);
-
- clksrc &= clk->mask;
- clksrc >>= clk->shift;
-
- if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
- printk(KERN_ERR "%s: bad source %d\n",
- clk->clk.name, clksrc);
- return;
- }
-
- clk->clk.parent = srcs->sources[clksrc];
-
- printk(KERN_INFO "%s: source is %s (%d), rate is %ld.%03ld MHz\n",
- clk->clk.name, clk->clk.parent->name, clksrc,
- print_mhz(clk_get_rate(&clk->clk)));
-}
-
#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
void __init_or_cpufreq s5pc100_setup_clocks(void)
@@ -1083,17 +821,25 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
clk_f.rate = armclk;
for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
- s5pc100_set_clksrc(init_parents[ptr]);
+ s3c_set_clksrc(init_parents[ptr], true);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_audio); ptr++)
+ s3c_set_clksrc(clksrc_audio + ptr, true);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
+ s3c_set_clksrc(clksrc_clks + ptr, true);
}
static struct clk *clks[] __initdata = {
&clk_ext_xtal_mux,
- &clk_mout_apll.clk,
&clk_dout_apll,
&clk_dout_d0_bus,
&clk_dout_pclkd0,
&clk_dout_apll2,
+ &clk_mout_apll.clk,
&clk_mout_mpll.clk,
+ &clk_mout_epll.clk,
+ &clk_mout_hpll.clk,
&clk_mout_am.clk,
&clk_dout_d1_bus,
&clk_mout_onenand.clk,
@@ -1101,29 +847,12 @@ static struct clk *clks[] __initdata = {
&clk_dout_mpll2,
&clk_dout_cam,
&clk_dout_mpll,
- &clk_mout_epll.clk,
&clk_fout_epll,
&clk_iis_cd0,
&clk_iis_cd1,
&clk_iis_cd2,
&clk_pcm_cd0,
&clk_pcm_cd1,
- &clk_spi0.clk,
- &clk_spi1.clk,
- &clk_spi2.clk,
- &clk_uart_uclk1.clk,
- &clk_audio0.clk,
- &clk_audio1.clk,
- &clk_audio2.clk,
- &clk_spdif.clk,
- &clk_lcd.clk,
- &clk_fimc0.clk,
- &clk_fimc1.clk,
- &clk_fimc2.clk,
- &clk_mmc0.clk,
- &clk_mmc1.clk,
- &clk_mmc2.clk,
- &clk_usbhost.clk,
&clk_arm,
};
@@ -1141,4 +870,7 @@ void __init s5pc100_register_clocks(void)
clkp->name, ret);
}
}
+
+ s3c_register_clksrc(clksrc_audio, ARRAY_SIZE(clksrc_audio));
+ s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
}
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 486a0d6301e..d552c65fa1b 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -7,11 +7,240 @@
config PLAT_SAMSUNG
bool
depends on ARCH_S3C2410 || ARCH_S3C24A0 || ARCH_S3C64XX || ARCH_S5PC1XX
+ select NO_IOPORT
default y
help
Base platform code for all Samsung SoC based systems
if PLAT_SAMSUNG
+# boot configurations
+
+comment "Boot options"
+
+config S3C_BOOT_WATCHDOG
+ bool "S3C Initialisation watchdog"
+ depends on S3C2410_WATCHDOG
+ help
+ Say y to enable the watchdog during the kernel decompression
+ stage. If the kernel fails to uncompress, then the watchdog
+ will trigger a reset and the system should restart.
+
+config S3C_BOOT_ERROR_RESET
+ bool "S3C Reboot on decompression error"
+ help
+ Say y here to use the watchdog to reset the system if the
+ kernel decompressor detects an error during decompression.
+
+config S3C_BOOT_UART_FORCE_FIFO
+ bool "Force UART FIFO on during boot process"
+ default y
+ help
+ Say Y here to force the UART FIFOs on during the kernel
+ uncompressor
+
+
+config S3C_LOWLEVEL_UART_PORT
+ int "S3C UART to use for low-level messages"
+ default 0
+ help
+ Choice of which UART port to use for the low-level messages,
+ such as the `Uncompressing...` at start time. The value of
+ this configuration should be between zero and two. The port
+ must have been initialised by the boot-loader before use.
+
+# clock options
+
+config SAMSUNG_CLKSRC
+ bool
+ help
+ Select the clock code for the clksrc implementation
+ used by newer systems such as the S3C64XX.
+
+# options for IRQ support
+
+config SAMSUNG_IRQ_VIC_TIMER
+ bool
+ help
+ Internal configuration to build the VIC timer interrupt code.
+
+config SAMSUNG_IRQ_UART
+ bool
+ help
+ Internal configuration to build the IRQ UART demux code.
+
+# options for gpio configuration support
+
+config SAMSUNG_GPIOLIB_4BIT
+ bool
+ help
+ GPIOlib file contains the 4 bit modification functions for gpio
+ configuration. GPIOlib shall be compiled only for S3C64XX and S5P
+ series of processors.
+
+config S3C_GPIO_CFG_S3C24XX
+ bool
+ help
+ Internal configuration to enable S3C24XX style GPIO configuration
+ functions.
+
+config S3C_GPIO_CFG_S3C64XX
+ bool
+ help
+ Internal configuration to enable S3C64XX style GPIO configuration
+ functions.
+
+config S5P_GPIO_CFG_S5PC1XX
+ bool
+ help
+ Internal configuration to enable S5PC1XX style GPIO configuration
+ functions.
+
+config S3C_GPIO_PULL_UPDOWN
+ bool
+ help
+ Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_PULL_DOWN
+ bool
+ help
+ Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_PULL_UP
+ bool
+ help
+ Internal configuration to enable the correct GPIO pull helper
+
+config SAMSUNG_GPIO_EXTRA
+ int "Number of additional GPIO pins"
+ default 0
+ help
+ Use additional GPIO space in addition to the GPIO's the SOC
+ provides. This allows expanding the GPIO space for use with
+ GPIO expanders.
+
+config S3C_GPIO_SPACE
+ int "Space between gpio banks"
+ default 0
+ help
+ Add a number of spare GPIO entries between each bank for debugging
+ purposes. This allows any problems where an counter overflows from
+ one bank to another to be caught, at the expense of using a little
+ more memory.
+
+config S3C_GPIO_TRACK
+ bool
+ help
+ Internal configuration option to enable the s3c specific gpio
+ chip tracking if the platform requires it.
+
+# ADC driver
+
+config S3C_ADC
+ bool "ADC common driver support"
+ help
+ Core support for the ADC block found in the Samsung SoC systems
+ for drivers such as the touchscreen and hwmon to use to share
+ this resource.
+
+# device definitions to compile in
+
+config S3C_DEV_HSMMC
+ bool
+ help
+ Compile in platform device definitions for HSMMC code
+
+config S3C_DEV_HSMMC1
+ bool
+ help
+ Compile in platform device definitions for HSMMC channel 1
+
+config S3C_DEV_HSMMC2
+ bool
+ help
+ Compile in platform device definitions for HSMMC channel 2
+
+config S3C_DEV_I2C1
+ bool
+ help
+ Compile in platform device definitions for I2C channel 1
+
+config S3C_DEV_FB
+ bool
+ help
+ Compile in platform device definition for framebuffer
+
+config S3C_DEV_USB_HOST
+ bool
+ help
+ Compile in platform device definition for USB host.
+
+config S3C_DEV_USB_HSOTG
+ bool
+ help
+ Compile in platform device definition for USB high-speed OtG
+
+config S3C_DEV_NAND
+ bool
+ help
+ Compile in platform device definition for NAND controller
+
+config S3C64XX_DEV_SPI
+ bool
+ help
+ Compile in platform device definitions for S3C64XX's type
+ SPI controllers.
+
+# DMA
+
+config S3C_DMA
+ bool
+ help
+ Internal configuration for S3C DMA core
+
+comment "Power management"
+
+config SAMSUNG_PM_DEBUG
+ bool "S3C2410 PM Suspend debug"
+ depends on PM
+ help
+ Say Y here if you want verbose debugging from the PM Suspend and
+ Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+ for more information.
+
+config S3C_PM_DEBUG_LED_SMDK
+ bool "SMDK LED suspend/resume debugging"
+ depends on PM && (MACH_SMDK6410)
+ help
+ Say Y here to enable the use of the SMDK LEDs on the baseboard
+ for debugging of the state of the suspend and resume process.
+
+ Note, this currently only works for S3C64XX based SMDK boards.
+
+config SAMSUNG_PM_CHECK
+ bool "S3C2410 PM Suspend Memory CRC"
+ depends on PM && CRC32
+ help
+ Enable the PM code's memory area checksum over sleep. This option
+ will generate CRCs of all blocks of memory, and store them before
+ going to sleep. The blocks are then checked on resume for any
+ errors.
+
+ Note, this can take several seconds depending on memory size
+ and CPU speed.
+
+ See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+
+config SAMSUNG_PM_CHECK_CHUNKSIZE
+ int "S3C2410 PM Suspend CRC Chunksize (KiB)"
+ depends on PM && SAMSUNG_PM_CHECK
+ default 64
+ help
+ Set the chunksize in Kilobytes of the CRC for checking memory
+ corruption over suspend and resume. A smaller value will mean that
+ the CRC data block will take more memory, but wil identify any
+ faults with better precision.
+
+ See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
endif
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 4478b9f7dc3..22c89d08f6e 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -9,3 +9,48 @@ obj-m :=
obj-n := dummy.o
obj- :=
+# Objects we always build independent of SoC choice
+
+obj-y += init.o
+obj-y += time.o
+obj-y += clock.o
+obj-y += pwm-clock.o
+obj-y += gpio.o
+obj-y += gpio-config.o
+
+obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o
+obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
+
+obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o
+obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
+
+# ADC
+
+obj-$(CONFIG_S3C_ADC) += adc.o
+
+# devices
+
+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-y += dev-i2c0.o
+obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
+obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
+obj-y += dev-uart.o
+obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
+obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
+obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o
+
+# DMA support
+
+obj-$(CONFIG_S3C_DMA) += dma.o
+
+# PM support
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += pm-gpio.o
+obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
+
+# PWM support
+
+obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
new file mode 100644
index 00000000000..210030d5cfe
--- /dev/null
+++ b/arch/arm/plat-samsung/adc.c
@@ -0,0 +1,475 @@
+/* arch/arm/plat-samsung/adc.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * Samsung ADC device core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <plat/regs-adc.h>
+#include <plat/adc.h>
+
+/* This driver is designed to control the usage of the ADC block between
+ * the touchscreen and any other drivers that may need to use it, such as
+ * the hwmon driver.
+ *
+ * Priority will be given to the touchscreen driver, but as this itself is
+ * rate limited it should not starve other requests which are processed in
+ * order that they are received.
+ *
+ * Each user registers to get a client block which uniquely identifies it
+ * and stores information such as the necessary functions to callback when
+ * action is required.
+ */
+
+enum s3c_cpu_type {
+ TYPE_S3C24XX,
+ TYPE_S3C64XX
+};
+
+struct s3c_adc_client {
+ struct platform_device *pdev;
+ struct list_head pend;
+ wait_queue_head_t *wait;
+
+ unsigned int nr_samples;
+ int result;
+ unsigned char is_ts;
+ unsigned char channel;
+
+ void (*select_cb)(struct s3c_adc_client *c, unsigned selected);
+ void (*convert_cb)(struct s3c_adc_client *c,
+ unsigned val1, unsigned val2,
+ unsigned *samples_left);
+};
+
+struct adc_device {
+ struct platform_device *pdev;
+ struct platform_device *owner;
+ struct clk *clk;
+ struct s3c_adc_client *cur;
+ struct s3c_adc_client *ts_pend;
+ void __iomem *regs;
+
+ unsigned int prescale;
+
+ int irq;
+};
+
+static struct adc_device *adc_dev;
+
+static LIST_HEAD(adc_pending);
+
+#define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg)
+
+static inline void s3c_adc_convert(struct adc_device *adc)
+{
+ unsigned con = readl(adc->regs + S3C2410_ADCCON);
+
+ con |= S3C2410_ADCCON_ENABLE_START;
+ writel(con, adc->regs + S3C2410_ADCCON);
+}
+
+static inline void s3c_adc_select(struct adc_device *adc,
+ struct s3c_adc_client *client)
+{
+ unsigned con = readl(adc->regs + S3C2410_ADCCON);
+
+ client->select_cb(client, 1);
+
+ con &= ~S3C2410_ADCCON_MUXMASK;
+ con &= ~S3C2410_ADCCON_STDBM;
+ con &= ~S3C2410_ADCCON_STARTMASK;
+
+ if (!client->is_ts)
+ con |= S3C2410_ADCCON_SELMUX(client->channel);
+
+ writel(con, adc->regs + S3C2410_ADCCON);
+}
+
+static void s3c_adc_dbgshow(struct adc_device *adc)
+{
+ adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
+ readl(adc->regs + S3C2410_ADCCON),
+ readl(adc->regs + S3C2410_ADCTSC),
+ readl(adc->regs + S3C2410_ADCDLY));
+}
+
+static void s3c_adc_try(struct adc_device *adc)
+{
+ struct s3c_adc_client *next = adc->ts_pend;
+
+ if (!next && !list_empty(&adc_pending)) {
+ next = list_first_entry(&adc_pending,
+ struct s3c_adc_client, pend);
+ list_del(&next->pend);
+ } else
+ adc->ts_pend = NULL;
+
+ if (next) {
+ adc_dbg(adc, "new client is %p\n", next);
+ adc->cur = next;
+ s3c_adc_select(adc, next);
+ s3c_adc_convert(adc);
+ s3c_adc_dbgshow(adc);
+ }
+}
+
+int s3c_adc_start(struct s3c_adc_client *client,
+ unsigned int channel, unsigned int nr_samples)
+{
+ struct adc_device *adc = adc_dev;
+ unsigned long flags;
+
+ if (!adc) {
+ printk(KERN_ERR "%s: failed to find adc\n", __func__);
+ return -EINVAL;
+ }
+
+ if (client->is_ts && adc->ts_pend)
+ return -EAGAIN;
+
+ local_irq_save(flags);
+
+ client->channel = channel;
+ client->nr_samples = nr_samples;
+
+ if (client->is_ts)
+ adc->ts_pend = client;
+ else
+ list_add_tail(&client->pend, &adc_pending);
+
+ if (!adc->cur)
+ s3c_adc_try(adc);
+ local_irq_restore(flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_adc_start);
+
+static void s3c_convert_done(struct s3c_adc_client *client,
+ unsigned v, unsigned u, unsigned *left)
+{
+ client->result = v;
+ wake_up(client->wait);
+}
+
+int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
+{
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+ int ret;
+
+ client->convert_cb = s3c_convert_done;
+ client->wait = &wake;
+ client->result = -1;
+
+ ret = s3c_adc_start(client, ch, 1);
+ if (ret < 0)
+ goto err;
+
+ ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
+ if (client->result < 0) {
+ ret = -ETIMEDOUT;
+ goto err;
+ }
+
+ client->convert_cb = NULL;
+ return client->result;
+
+err:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(s3c_adc_read);
+
+static void s3c_adc_default_select(struct s3c_adc_client *client,
+ unsigned select)
+{
+}
+
+struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
+ void (*select)(struct s3c_adc_client *client,
+ unsigned int selected),
+ void (*conv)(struct s3c_adc_client *client,
+ unsigned d0, unsigned d1,
+ unsigned *samples_left),
+ unsigned int is_ts)
+{
+ struct s3c_adc_client *client;
+
+ WARN_ON(!pdev);
+
+ if (!select)
+ select = s3c_adc_default_select;
+
+ if (!pdev)
+ return ERR_PTR(-EINVAL);
+
+ client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);
+ if (!client) {
+ dev_err(&pdev->dev, "no memory for adc client\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ client->pdev = pdev;
+ client->is_ts = is_ts;
+ client->select_cb = select;
+ client->convert_cb = conv;
+
+ return client;
+}
+EXPORT_SYMBOL_GPL(s3c_adc_register);
+
+void s3c_adc_release(struct s3c_adc_client *client)
+{
+ /* We should really check that nothing is in progress. */
+ if (adc_dev->cur == client)
+ adc_dev->cur = NULL;
+ if (adc_dev->ts_pend == client)
+ adc_dev->ts_pend = NULL;
+ else {
+ struct list_head *p, *n;
+ struct s3c_adc_client *tmp;
+
+ list_for_each_safe(p, n, &adc_pending) {
+ tmp = list_entry(p, struct s3c_adc_client, pend);
+ if (tmp == client)
+ list_del(&tmp->pend);
+ }
+ }
+
+ if (adc_dev->cur == NULL)
+ s3c_adc_try(adc_dev);
+ kfree(client);
+}
+EXPORT_SYMBOL_GPL(s3c_adc_release);
+
+static irqreturn_t s3c_adc_irq(int irq, void *pw)
+{
+ struct adc_device *adc = pw;
+ struct s3c_adc_client *client = adc->cur;
+ enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
+ unsigned long flags;
+ unsigned data0, data1;
+
+ if (!client) {
+ dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
+ goto exit;
+ }
+
+ data0 = readl(adc->regs + S3C2410_ADCDAT0);
+ data1 = readl(adc->regs + S3C2410_ADCDAT1);
+ adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
+
+ client->nr_samples--;
+
+ if (cpu == TYPE_S3C64XX) {
+ /* S3C64XX ADC resolution is 12-bit */
+ data0 &= 0xfff;
+ data1 &= 0xfff;
+ } else {
+ data0 &= 0x3ff;
+ data1 &= 0x3ff;
+ }
+
+ if (client->convert_cb)
+ (client->convert_cb)(client, data0, data1, &client->nr_samples);
+
+ if (client->nr_samples > 0) {
+ /* fire another conversion for this */
+
+ client->select_cb(client, 1);
+ s3c_adc_convert(adc);
+ } else {
+ local_irq_save(flags);
+ (client->select_cb)(client, 0);
+ adc->cur = NULL;
+
+ s3c_adc_try(adc);
+ local_irq_restore(flags);
+ }
+
+exit:
+ if (cpu == TYPE_S3C64XX) {
+ /* Clear ADC interrupt */
+ writel(0, adc->regs + S3C64XX_ADCCLRINT);
+ }
+ return IRQ_HANDLED;
+}
+
+static int s3c_adc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct adc_device *adc;
+ struct resource *regs;
+ int ret;
+ unsigned tmp;
+
+ adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
+ if (adc == NULL) {
+ dev_err(dev, "failed to allocate adc_device\n");
+ return -ENOMEM;
+ }
+
+ adc->pdev = pdev;
+ adc->prescale = S3C2410_ADCCON_PRSCVL(49);
+
+ adc->irq = platform_get_irq(pdev, 1);
+ if (adc->irq <= 0) {
+ dev_err(dev, "failed to get adc irq\n");
+ ret = -ENOENT;
+ goto err_alloc;
+ }
+
+ ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
+ if (ret < 0) {
+ dev_err(dev, "failed to attach adc irq\n");
+ goto err_alloc;
+ }
+
+ adc->clk = clk_get(dev, "adc");
+ if (IS_ERR(adc->clk)) {
+ dev_err(dev, "failed to get adc clock\n");
+ ret = PTR_ERR(adc->clk);
+ goto err_irq;
+ }
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!regs) {
+ dev_err(dev, "failed to find registers\n");
+ ret = -ENXIO;
+ goto err_clk;
+ }
+
+ adc->regs = ioremap(regs->start, resource_size(regs));
+ if (!adc->regs) {
+ dev_err(dev, "failed to map registers\n");
+ ret = -ENXIO;
+ goto err_clk;
+ }
+
+ clk_enable(adc->clk);
+
+ tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+ if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) {
+ /* Enable 12-bit ADC resolution */
+ tmp |= S3C64XX_ADCCON_RESSEL;
+ }
+ writel(tmp, adc->regs + S3C2410_ADCCON);
+
+ dev_info(dev, "attached adc driver\n");
+
+ platform_set_drvdata(pdev, adc);
+ adc_dev = adc;
+
+ return 0;
+
+ err_clk:
+ clk_put(adc->clk);
+
+ err_irq:
+ free_irq(adc->irq, adc);
+
+ err_alloc:
+ kfree(adc);
+ return ret;
+}
+
+static int __devexit s3c_adc_remove(struct platform_device *pdev)
+{
+ struct adc_device *adc = platform_get_drvdata(pdev);
+
+ iounmap(adc->regs);
+ free_irq(adc->irq, adc);
+ clk_disable(adc->clk);
+ clk_put(adc->clk);
+ kfree(adc);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct adc_device *adc = platform_get_drvdata(pdev);
+ u32 con;
+
+ con = readl(adc->regs + S3C2410_ADCCON);
+ con |= S3C2410_ADCCON_STDBM;
+ writel(con, adc->regs + S3C2410_ADCCON);
+
+ disable_irq(adc->irq);
+ clk_disable(adc->clk);
+
+ return 0;
+}
+
+static int s3c_adc_resume(struct platform_device *pdev)
+{
+ struct adc_device *adc = platform_get_drvdata(pdev);
+
+ clk_enable(adc->clk);
+ enable_irq(adc->irq);
+
+ writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
+ adc->regs + S3C2410_ADCCON);
+
+ return 0;
+}
+
+#else
+#define s3c_adc_suspend NULL
+#define s3c_adc_resume NULL
+#endif
+
+static struct platform_device_id s3c_adc_driver_ids[] = {
+ {
+ .name = "s3c24xx-adc",
+ .driver_data = TYPE_S3C24XX,
+ }, {
+ .name = "s3c64xx-adc",
+ .driver_data = TYPE_S3C64XX,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids);
+
+static struct platform_driver s3c_adc_driver = {
+ .id_table = s3c_adc_driver_ids,
+ .driver = {
+ .name = "s3c-adc",
+ .owner = THIS_MODULE,
+ },
+ .probe = s3c_adc_probe,
+ .remove = __devexit_p(s3c_adc_remove),
+ .suspend = s3c_adc_suspend,
+ .resume = s3c_adc_resume,
+};
+
+static int __init adc_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&s3c_adc_driver);
+ if (ret)
+ printk(KERN_ERR "%s: failed to add adc driver\n", __func__);
+
+ return ret;
+}
+
+arch_initcall(adc_init);
diff --git a/arch/arm/plat-samsung/clock-clksrc.c b/arch/arm/plat-samsung/clock-clksrc.c
new file mode 100644
index 00000000000..ae8b8507663
--- /dev/null
+++ b/arch/arm/plat-samsung/clock-clksrc.c
@@ -0,0 +1,212 @@
+/* linux/arch/arm/plat-samsung/clock-clksrc.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu-freq.h>
+
+static inline struct clksrc_clk *to_clksrc(struct clk *clk)
+{
+ return container_of(clk, struct clksrc_clk, clk);
+}
+
+static inline u32 bit_mask(u32 shift, u32 nr_bits)
+{
+ u32 mask = 0xffffffff >> (32 - nr_bits);
+
+ return mask << shift;
+}
+
+static unsigned long s3c_getrate_clksrc(struct clk *clk)
+{
+ struct clksrc_clk *sclk = to_clksrc(clk);
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 clkdiv = __raw_readl(sclk->reg_div.reg);
+ u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size);
+
+ clkdiv &= mask;
+ clkdiv >>= sclk->reg_div.shift;
+ clkdiv++;
+
+ rate /= clkdiv;
+ return rate;
+}
+
+static int s3c_setrate_clksrc(struct clk *clk, unsigned long rate)
+{
+ struct clksrc_clk *sclk = to_clksrc(clk);
+ void __iomem *reg = sclk->reg_div.reg;
+ unsigned int div;
+ u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size);
+ u32 val;
+
+ rate = clk_round_rate(clk, rate);
+ div = clk_get_rate(clk->parent) / rate;
+ if (div > (1 << sclk->reg_div.size))
+ return -EINVAL;
+
+ val = __raw_readl(reg);
+ val &= ~mask;
+ val |= (div - 1) << sclk->reg_div.shift;
+ __raw_writel(val, reg);
+
+ return 0;
+}
+
+static int s3c_setparent_clksrc(struct clk *clk, struct clk *parent)
+{
+ struct clksrc_clk *sclk = to_clksrc(clk);
+ struct clksrc_sources *srcs = sclk->sources;
+ u32 clksrc = __raw_readl(sclk->reg_src.reg);
+ u32 mask = bit_mask(sclk->reg_src.shift, sclk->reg_src.size);
+ int src_nr = -1;
+ int ptr;
+
+ for (ptr = 0; ptr < srcs->nr_sources; ptr++)
+ if (srcs->sources[ptr] == parent) {
+ src_nr = ptr;
+ break;
+ }
+
+ if (src_nr >= 0) {
+ clk->parent = parent;
+
+ clksrc &= ~mask;
+ clksrc |= src_nr << sclk->reg_src.shift;
+
+ __raw_writel(clksrc, sclk->reg_src.reg);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static unsigned long s3c_roundrate_clksrc(struct clk *clk,
+ unsigned long rate)
+{
+ struct clksrc_clk *sclk = to_clksrc(clk);
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ int max_div = 1 << sclk->reg_div.size;
+ int div;
+
+ if (rate >= parent_rate)
+ rate = parent_rate;
+ else {
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div == 0)
+ div = 1;
+ if (div > max_div)
+ div = max_div;
+
+ rate = parent_rate / div;
+ }
+
+ return rate;
+}
+
+/* Clock initialisation code */
+
+void __init_or_cpufreq s3c_set_clksrc(struct clksrc_clk *clk, bool announce)
+{
+ struct clksrc_sources *srcs = clk->sources;
+ u32 mask = bit_mask(clk->reg_src.shift, clk->reg_src.size);
+ u32 clksrc;
+
+ if (!clk->reg_src.reg) {
+ if (!clk->clk.parent)
+ printk(KERN_ERR "%s: no parent clock specified\n",
+ clk->clk.name);
+ return;
+ }
+
+ clksrc = __raw_readl(clk->reg_src.reg);
+ clksrc &= mask;
+ clksrc >>= clk->reg_src.shift;
+
+ if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
+ printk(KERN_ERR "%s: bad source %d\n",
+ clk->clk.name, clksrc);
+ return;
+ }
+
+ clk->clk.parent = srcs->sources[clksrc];
+
+ if (announce)
+ printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
+ clk->clk.name, clk->clk.parent->name, clksrc,
+ clk_get_rate(&clk->clk));
+}
+
+static struct clk_ops clksrc_ops = {
+ .set_parent = s3c_setparent_clksrc,
+ .get_rate = s3c_getrate_clksrc,
+ .set_rate = s3c_setrate_clksrc,
+ .round_rate = s3c_roundrate_clksrc,
+};
+
+static struct clk_ops clksrc_ops_nodiv = {
+ .set_parent = s3c_setparent_clksrc,
+};
+
+static struct clk_ops clksrc_ops_nosrc = {
+ .get_rate = s3c_getrate_clksrc,
+ .set_rate = s3c_setrate_clksrc,
+ .round_rate = s3c_roundrate_clksrc,
+};
+
+void __init s3c_register_clksrc(struct clksrc_clk *clksrc, int size)
+{
+ int ret;
+
+ for (; size > 0; size--, clksrc++) {
+ if (!clksrc->reg_div.reg && !clksrc->reg_src.reg)
+ printk(KERN_ERR "%s: clock %s has no registers set\n",
+ __func__, clksrc->clk.name);
+
+ /* fill in the default functions */
+
+ if (!clksrc->clk.ops) {
+ if (!clksrc->reg_div.reg)
+ clksrc->clk.ops = &clksrc_ops_nodiv;
+ else if (!clksrc->reg_src.reg)
+ clksrc->clk.ops = &clksrc_ops_nosrc;
+ else
+ clksrc->clk.ops = &clksrc_ops;
+ }
+
+ /* setup the clocksource, but do not announce it
+ * as it may be re-set by the setup routines
+ * called after the rest of the clocks have been
+ * registered
+ */
+ s3c_set_clksrc(clksrc, false);
+
+ ret = s3c24xx_register_clock(&clksrc->clk);
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: failed to register %s (%d)\n",
+ __func__, clksrc->clk.name, ret);
+ }
+ }
+}
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
new file mode 100644
index 00000000000..1b25c9d8c40
--- /dev/null
+++ b/arch/arm/plat-samsung/clock.c
@@ -0,0 +1,409 @@
+/* linux/arch/arm/plat-s3c24xx/clock.c
+ *
+ * Copyright 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Core clock control support
+ *
+ * Based on, and code from linux/arch/arm/mach-versatile/clock.c
+ **
+ ** Copyright (C) 2004 ARM Limited.
+ ** Written by Deep Blue Solutions Limited.
+ *
+ *
+ * This program is free software; 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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* clock information */
+
+static LIST_HEAD(clocks);
+
+/* We originally used an mutex here, but some contexts (see resume)
+ * are calling functions such as clk_set_parent() with IRQs disabled
+ * causing an BUG to be triggered.
+ */
+DEFINE_SPINLOCK(clocks_lock);
+
+/* enable and disable calls for use with the clk struct */
+
+static int clk_null_enable(struct clk *clk, int enable)
+{
+ return 0;
+}
+
+/* Clock API calls */
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ struct clk *p;
+ struct clk *clk = ERR_PTR(-ENOENT);
+ int idno;
+
+ if (dev == NULL || dev->bus != &platform_bus_type)
+ idno = -1;
+ else
+ idno = to_platform_device(dev)->id;
+
+ spin_lock(&clocks_lock);
+
+ list_for_each_entry(p, &clocks, list) {
+ if (p->id == idno &&
+ strcmp(id, p->name) == 0 &&
+ try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+
+ /* check for the case where a device was supplied, but the
+ * clock that was being searched for is not device specific */
+
+ if (IS_ERR(clk)) {
+ list_for_each_entry(p, &clocks, list) {
+ if (p->id == -1 && strcmp(id, p->name) == 0 &&
+ try_module_get(p->owner)) {
+ clk = p;
+ break;
+ }
+ }
+ }
+
+ spin_unlock(&clocks_lock);
+ return clk;
+}
+
+void clk_put(struct clk *clk)
+{
+ module_put(clk->owner);
+}
+
+int clk_enable(struct clk *clk)
+{
+ if (IS_ERR(clk) || clk == NULL)
+ return -EINVAL;
+
+ clk_enable(clk->parent);
+
+ spin_lock(&clocks_lock);
+
+ if ((clk->usage++) == 0)
+ (clk->enable)(clk, 1);
+
+ spin_unlock(&clocks_lock);
+ return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+ if (IS_ERR(clk) || clk == NULL)
+ return;
+
+ spin_lock(&clocks_lock);
+
+ if ((--clk->usage) == 0)
+ (clk->enable)(clk, 0);
+
+ spin_unlock(&clocks_lock);
+ clk_disable(clk->parent);
+}
+
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (IS_ERR(clk))
+ return 0;
+
+ if (clk->rate != 0)
+ return clk->rate;
+
+ if (clk->ops != NULL && clk->ops->get_rate != NULL)
+ return (clk->ops->get_rate)(clk);
+
+ if (clk->parent != NULL)
+ return clk_get_rate(clk->parent);
+
+ return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (!IS_ERR(clk) && clk->ops && clk->ops->round_rate)
+ return (clk->ops->round_rate)(clk, rate);
+
+ return rate;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret;
+
+ if (IS_ERR(clk))
+ return -EINVAL;
+
+ /* We do not default just do a clk->rate = rate as
+ * the clock may have been made this way by choice.
+ */
+
+ WARN_ON(clk->ops == NULL);
+ WARN_ON(clk->ops && clk->ops->set_rate == NULL);
+
+ if (clk->ops == NULL || clk->ops->set_rate == NULL)
+ return -EINVAL;
+
+ spin_lock(&clocks_lock);
+ ret = (clk->ops->set_rate)(clk, rate);
+ spin_unlock(&clocks_lock);
+
+ return ret;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = 0;
+
+ if (IS_ERR(clk))
+ return -EINVAL;
+
+ spin_lock(&clocks_lock);
+
+ if (clk->ops && clk->ops->set_parent)
+ ret = (clk->ops->set_parent)(clk, parent);
+
+ spin_unlock(&clocks_lock);
+
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_get);
+EXPORT_SYMBOL(clk_put);
+EXPORT_SYMBOL(clk_enable);
+EXPORT_SYMBOL(clk_disable);
+EXPORT_SYMBOL(clk_get_rate);
+EXPORT_SYMBOL(clk_round_rate);
+EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_get_parent);
+EXPORT_SYMBOL(clk_set_parent);
+
+/* base clocks */
+
+int clk_default_setrate(struct clk *clk, unsigned long rate)
+{
+ clk->rate = rate;
+ return 0;
+}
+
+struct clk_ops clk_ops_def_setrate = {
+ .set_rate = clk_default_setrate,
+};
+
+struct clk clk_xtal = {
+ .name = "xtal",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+};
+
+struct clk clk_ext = {
+ .name = "ext",
+ .id = -1,
+};
+
+struct clk clk_epll = {
+ .name = "epll",
+ .id = -1,
+};
+
+struct clk clk_mpll = {
+ .name = "mpll",
+ .id = -1,
+ .ops = &clk_ops_def_setrate,
+};
+
+struct clk clk_upll = {
+ .name = "upll",
+ .id = -1,
+ .parent = NULL,
+ .ctrlbit = 0,
+};
+
+struct clk clk_f = {
+ .name = "fclk",
+ .id = -1,
+ .rate = 0,
+ .parent = &clk_mpll,
+ .ctrlbit = 0,
+};
+
+struct clk clk_h = {
+ .name = "hclk",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+ .ops = &clk_ops_def_setrate,
+};
+
+struct clk clk_p = {
+ .name = "pclk",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+ .ops = &clk_ops_def_setrate,
+};
+
+struct clk clk_usb_bus = {
+ .name = "usb-bus",
+ .id = -1,
+ .rate = 0,
+ .parent = &clk_upll,
+};
+
+
+struct clk s3c24xx_uclk = {
+ .name = "uclk",
+ .id = -1,
+};
+
+/* initialise the clock system */
+
+/**
+ * s3c24xx_register_clock() - register a clock
+ * @clk: The clock to register
+ *
+ * Add the specified clock to the list of clocks known by the system.
+ */
+int s3c24xx_register_clock(struct clk *clk)
+{
+ if (clk->enable == NULL)
+ clk->enable = clk_null_enable;
+
+ /* add to the list of available clocks */
+
+ /* Quick check to see if this clock has already been registered. */
+ BUG_ON(clk->list.prev != clk->list.next);
+
+ spin_lock(&clocks_lock);
+ list_add(&clk->list, &clocks);
+ spin_unlock(&clocks_lock);
+
+ return 0;
+}
+
+/**
+ * s3c24xx_register_clocks() - register an array of clock pointers
+ * @clks: Pointer to an array of struct clk pointers
+ * @nr_clks: The number of clocks in the @clks array.
+ *
+ * Call s3c24xx_register_clock() for all the clock pointers contained
+ * in the @clks list. Returns the number of failures.
+ */
+int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
+{
+ int fails = 0;
+
+ for (; nr_clks > 0; nr_clks--, clks++) {
+ if (s3c24xx_register_clock(*clks) < 0) {
+ struct clk *clk = *clks;
+ printk(KERN_ERR "%s: failed to register %p: %s\n",
+ __func__, clk, clk->name);
+ fails++;
+ }
+ }
+
+ return fails;
+}
+
+/**
+ * s3c_register_clocks() - register an array of clocks
+ * @clkp: Pointer to the first clock in the array.
+ * @nr_clks: Number of clocks to register.
+ *
+ * Call s3c24xx_register_clock() on the @clkp array given, printing an
+ * error if it fails to register the clock (unlikely).
+ */
+void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
+{
+ int ret;
+
+ for (; nr_clks > 0; nr_clks--, clkp++) {
+ ret = s3c24xx_register_clock(clkp);
+
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ }
+}
+
+/* initalise all the clocks */
+
+int __init s3c24xx_register_baseclocks(unsigned long xtal)
+{
+ printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");
+
+ clk_xtal.rate = xtal;
+
+ /* register our clocks */
+
+ if (s3c24xx_register_clock(&clk_xtal) < 0)
+ printk(KERN_ERR "failed to register master xtal\n");
+
+ if (s3c24xx_register_clock(&clk_mpll) < 0)
+ printk(KERN_ERR "failed to register mpll clock\n");
+
+ if (s3c24xx_register_clock(&clk_upll) < 0)
+ printk(KERN_ERR "failed to register upll clock\n");
+
+ if (s3c24xx_register_clock(&clk_f) < 0)
+ printk(KERN_ERR "failed to register cpu fclk\n");
+
+ if (s3c24xx_register_clock(&clk_h) < 0)
+ printk(KERN_ERR "failed to register cpu hclk\n");
+
+ if (s3c24xx_register_clock(&clk_p) < 0)
+ printk(KERN_ERR "failed to register cpu pclk\n");
+
+ return 0;
+}
+
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
new file mode 100644
index 00000000000..002a15f313f
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -0,0 +1,74 @@
+/* linux/arch/arm/plat-s3c/dev-fb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for framebuffer device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_fb_resource[] = {
+ [0] = {
+ .start = S3C_PA_FB,
+ .end = S3C_PA_FB + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD_VSYNC,
+ .end = IRQ_LCD_VSYNC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_LCD_FIFO,
+ .end = IRQ_LCD_FIFO,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_LCD_SYSTEM,
+ .end = IRQ_LCD_SYSTEM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fb = {
+ .name = "s3c-fb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_fb_resource),
+ .resource = s3c_fb_resource,
+ .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask,
+ .dev.coherent_dma_mask = 0xffffffffUL,
+};
+
+void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
+{
+ struct s3c_fb_platdata *npd;
+
+ if (!pd) {
+ printk(KERN_ERR "%s: no platform data\n", __func__);
+ return;
+ }
+
+ npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+ s3c_device_fb.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-s3c/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index 4c05b39810e..4c05b39810e 100644
--- a/arch/arm/plat-s3c/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
diff --git a/arch/arm/plat-s3c/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index e49bc4cd0ee..e49bc4cd0ee 100644
--- a/arch/arm/plat-s3c/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
diff --git a/arch/arm/plat-s3c/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index 824580bc0e0..824580bc0e0 100644
--- a/arch/arm/plat-s3c/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
new file mode 100644
index 00000000000..3a601c16f03
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c0.c
@@ -0,0 +1,72 @@
+/* linux/arch/arm/plat-s3c/dev-i2c0.c
+ *
+ * Copyright 2008-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 0
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC,
+ .end = S3C_PA_IIC + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC,
+ .end = IRQ_IIC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c0 = {
+ .name = "s3c2410-i2c",
+#ifdef CONFIG_S3C_DEV_I2C1
+ .id = 0,
+#else
+ .id = -1,
+#endif
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data0;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c0_cfg_gpio;
+
+ s3c_device_i2c0.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
new file mode 100644
index 00000000000..858ee2a0414
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c1.c
@@ -0,0 +1,69 @@
+/* linux/arch/arm/plat-s3c/dev-i2c1.c
+ *
+ * Copyright 2008-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC1,
+ .end = S3C_PA_IIC1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC1,
+ .end = IRQ_IIC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c1 = {
+ .name = "s3c2410-i2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
+ .flags = 0,
+ .bus_num = 1,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data1;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c1_cfg_gpio;
+
+ s3c_device_i2c1.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c
new file mode 100644
index 00000000000..3a7b8891ba4
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-nand.c
@@ -0,0 +1,130 @@
+/*
+ * S3C series device definition for nand device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/nand.h>
+
+static struct resource s3c_nand_resource[] = {
+ [0] = {
+ .start = S3C_PA_NAND,
+ .end = S3C_PA_NAND + SZ_1M,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+struct platform_device s3c_device_nand = {
+ .name = "s3c2410-nand",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_nand_resource),
+ .resource = s3c_nand_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_nand);
+
+/**
+ * s3c_nand_copy_set() - copy nand set data
+ * @set: The new structure, directly copied from the old.
+ *
+ * Copy all the fields from the NAND set field from what is probably __initdata
+ * to new kernel memory. The code returns 0 if the copy happened correctly or
+ * an error code for the calling function to display.
+ *
+ * Note, we currently do not try and look to see if we've already copied the
+ * data in a previous set.
+ */
+static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
+{
+ void *ptr;
+ int size;
+
+ size = sizeof(struct mtd_partition) * set->nr_partitions;
+ if (size) {
+ ptr = kmemdup(set->partitions, size, GFP_KERNEL);
+ set->partitions = ptr;
+
+ if (!ptr)
+ return -ENOMEM;
+ }
+
+ if (set->nr_map && set->nr_chips) {
+ size = sizeof(int) * set->nr_chips;
+ ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
+ set->nr_map = ptr;
+
+ if (!ptr)
+ return -ENOMEM;
+ }
+
+ if (set->ecc_layout) {
+ ptr = kmemdup(set->ecc_layout,
+ sizeof(struct nand_ecclayout), GFP_KERNEL);
+ set->ecc_layout = ptr;
+
+ if (!ptr)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
+{
+ struct s3c2410_platform_nand *npd;
+ int size;
+ int ret;
+
+ /* note, if we get a failure in allocation, we simply drop out of the
+ * function. If there is so little memory available at initialisation
+ * time then there is little chance the system is going to run.
+ */
+
+ npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL);
+ if (!npd) {
+ printk(KERN_ERR "%s: failed copying platform data\n", __func__);
+ return;
+ }
+
+ /* now see if we need to copy any of the nand set data */
+
+ size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
+ if (size) {
+ struct s3c2410_nand_set *from = npd->sets;
+ struct s3c2410_nand_set *to;
+ int i;
+
+ to = kmemdup(from, size, GFP_KERNEL);
+ npd->sets = to; /* set, even if we failed */
+
+ if (!to) {
+ printk(KERN_ERR "%s: no memory for sets\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < npd->nr_sets; i++) {
+ ret = s3c_nand_copy_set(to);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to copy set %d\n",
+ __func__, i);
+ return;
+ }
+ to++;
+ }
+ }
+
+ s3c_device_nand.dev.platform_data = npd;
+}
+
+EXPORT_SYMBOL_GPL(s3c_nand_set_platdata);
diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c
new file mode 100644
index 00000000000..3776cd95245
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-uart.c
@@ -0,0 +1,44 @@
+/* linux/arch/arm/plat-samsung/dev-uart.c
+ * originally from arch/arm/plat-s3c24xx/devs.c
+ *x
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Base S3C24XX platform device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+/* uart devices */
+
+static struct platform_device s3c24xx_uart_device0 = {
+ .id = 0,
+};
+
+static struct platform_device s3c24xx_uart_device1 = {
+ .id = 1,
+};
+
+static struct platform_device s3c24xx_uart_device2 = {
+ .id = 2,
+};
+
+static struct platform_device s3c24xx_uart_device3 = {
+ .id = 3,
+};
+
+struct platform_device *s3c24xx_uart_src[4] = {
+ &s3c24xx_uart_device0,
+ &s3c24xx_uart_device1,
+ &s3c24xx_uart_device2,
+ &s3c24xx_uart_device3,
+};
+
+struct platform_device *s3c24xx_uart_devs[4] = {
+};
diff --git a/arch/arm/plat-samsung/dev-usb-hsotg.c b/arch/arm/plat-samsung/dev-usb-hsotg.c
new file mode 100644
index 00000000000..33a844ab691
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-usb-hsotg.c
@@ -0,0 +1,48 @@
+/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for USB high-speed UDC/OtG block
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+static struct resource s3c_usb_hsotg_resources[] = {
+ [0] = {
+ .start = S3C_PA_USB_HSOTG,
+ .end = S3C_PA_USB_HSOTG + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_OTG,
+ .end = IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c_device_usb_hsotg = {
+ .name = "s3c-hsotg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources),
+ .resource = s3c_usb_hsotg_resources,
+ .dev = {
+ .dma_mask = &s3c_hsotg_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c
new file mode 100644
index 00000000000..0e0a3bf5c98
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-usb.c
@@ -0,0 +1,70 @@
+/* linux/arch/arm/plat-s3c/dev-usb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for USB host
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/usb-control.h>
+
+static struct resource s3c_usb_resource[] = {
+ [0] = {
+ .start = S3C_PA_USBHOST,
+ .end = S3C_PA_USBHOST + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH,
+ .end = IRQ_USBH,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_usb_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_ohci = {
+ .name = "s3c2410-ohci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usb_resource),
+ .resource = s3c_usb_resource,
+ .dev = {
+ .dma_mask = &s3c_device_usb_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_ohci);
+
+/**
+ * s3c_ohci_set_platdata - initialise OHCI device platform data
+ * @info: The platform data.
+ *
+ * This call copies the @info passed in and sets the device .platform_data
+ * field to that copy. The @info is copied so that the original can be marked
+ * __initdata.
+ */
+void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
+{
+ struct s3c2410_hcd_info *npd;
+
+ npd = kmemdup(info, sizeof(struct s3c2410_hcd_info), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+ s3c_device_ohci.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dma.c b/arch/arm/plat-samsung/dma.c
new file mode 100644
index 00000000000..cb459dd9545
--- /dev/null
+++ b/arch/arm/plat-samsung/dma.c
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/dma.c
+ *
+ * Copyright (c) 2003-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C DMA core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct s3c2410_dma_buf;
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+/* dma channel state information */
+struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
+struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
+
+/* s3c_dma_lookup_channel
+ *
+ * change the dma channel number given into a real dma channel id
+*/
+
+struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
+{
+ if (channel & DMACH_LOW_LEVEL)
+ return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
+ else
+ return s3c_dma_chan_map[channel];
+}
+
+/* do we need to protect the settings of the fields from
+ * irq?
+*/
+
+int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
+
+ chan->op_fn = rtn;
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_opfn);
+
+int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
+
+ chan->callback_fn = rtn;
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ chan->flags = flags;
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_setflags);
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
new file mode 100644
index 00000000000..44a84e89654
--- /dev/null
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -0,0 +1,166 @@
+/* linux/arch/arm/plat-s3c/gpio-config.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO configuration core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset;
+ int ret;
+
+ if (!chip)
+ return -EINVAL;
+
+ offset = pin - chip->chip.base;
+
+ local_irq_save(flags);
+ ret = s3c_gpio_do_setcfg(chip, offset, config);
+ local_irq_restore(flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_cfgpin);
+
+int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset, ret;
+
+ if (!chip)
+ return -EINVAL;
+
+ offset = pin - chip->chip.base;
+
+ local_irq_save(flags);
+ ret = s3c_gpio_do_setpull(chip, offset, pull);
+ local_irq_restore(flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_setpull);
+
+#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
+int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = off;
+ u32 con;
+
+ if (s3c_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+
+ /* Map output to 0, and SFN2 to 1 */
+ cfg -= 1;
+ if (cfg > 1)
+ return -EINVAL;
+
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0x1 << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = off * 2;
+ u32 con;
+
+ if (s3c_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+ if (cfg > 3)
+ return -EINVAL;
+
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0x3 << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
+int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = (off & 7) * 4;
+ u32 con;
+
+ if (off < 8 && chip->chip.ngpio > 8)
+ reg -= 4;
+
+ if (s3c_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0xf << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
+
+#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
+int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ void __iomem *reg = chip->base + 0x08;
+ int shift = off * 2;
+ u32 pup;
+
+ pup = __raw_readl(reg);
+ pup &= ~(3 << shift);
+ pup |= pull << shift;
+ __raw_writel(pup, reg);
+
+ return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ void __iomem *reg = chip->base + 0x08;
+ int shift = off * 2;
+ u32 pup = __raw_readl(reg);
+
+ pup >>= shift;
+ pup &= 0x3;
+ return (__force s3c_gpio_pull_t)pup;
+}
+#endif
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
new file mode 100644
index 00000000000..28d2ab8a08d
--- /dev/null
+++ b/arch/arm/plat-samsung/gpio.c
@@ -0,0 +1,156 @@
+/* linux/arch/arm/plat-s3c/gpio.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-core.h>
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
+{
+ unsigned int gpn;
+ int i;
+
+ gpn = chip->chip.base;
+ for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
+ BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
+ s3c_gpios[gpn] = chip;
+ }
+}
+#endif /* CONFIG_S3C_GPIO_TRACK */
+
+/* Default routines for controlling GPIO, based on the original S3C24XX
+ * GPIO functions which deal with the case where each gpio bank of the
+ * chip is as following:
+ *
+ * base + 0x00: Control register, 2 bits per gpio
+ * gpio n: 2 bits starting at (2*n)
+ * 00 = input, 01 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ * bit n: data bit n
+*/
+
+static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long con;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~(3 << (offset * 2));
+
+ __raw_writel(con, base + 0x00);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+static int s3c_gpiolib_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+ unsigned long con;
+
+ local_irq_save(flags);
+
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+ __raw_writel(dat, base + 0x04);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~(3 << (offset * 2));
+ con |= 1 << (offset * 2);
+
+ __raw_writel(con, base + 0x00);
+ __raw_writel(dat, base + 0x04);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+static void s3c_gpiolib_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+
+ local_irq_save(flags);
+
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+ __raw_writel(dat, base + 0x04);
+
+ local_irq_restore(flags);
+}
+
+static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ unsigned long val;
+
+ val = __raw_readl(ourchip->base + 0x04);
+ val >>= offset;
+ val &= 1;
+
+ return val;
+}
+
+__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
+{
+ struct gpio_chip *gc = &chip->chip;
+ int ret;
+
+ BUG_ON(!chip->base);
+ BUG_ON(!gc->label);
+ BUG_ON(!gc->ngpio);
+
+ if (!gc->direction_input)
+ gc->direction_input = s3c_gpiolib_input;
+ if (!gc->direction_output)
+ gc->direction_output = s3c_gpiolib_output;
+ if (!gc->set)
+ gc->set = s3c_gpiolib_set;
+ if (!gc->get)
+ gc->get = s3c_gpiolib_get;
+
+#ifdef CONFIG_PM
+ if (chip->pm != NULL) {
+ if (!chip->pm->save || !chip->pm->resume)
+ printk(KERN_ERR "gpio: %s has missing PM functions\n",
+ gc->label);
+ } else
+ printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
+#endif
+
+ /* gpiochip_add() prints own failure message on error. */
+ ret = gpiochip_add(gc);
+ if (ret >= 0)
+ s3c_gpiolib_track(chip);
+}
diff --git a/arch/arm/plat-samsung/gpiolib.c b/arch/arm/plat-samsung/gpiolib.c
new file mode 100644
index 00000000000..8a8ba8bc1d9
--- /dev/null
+++ b/arch/arm/plat-samsung/gpiolib.c
@@ -0,0 +1,199 @@
+/* arch/arm/plat-samsung/gpiolib.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * SAMSUNG - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/gpio.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#ifndef DEBUG_GPIO
+#define gpio_dbg(x...) do { } while (0)
+#else
+#define gpio_dbg(x...) printk(KERN_DEBUG x)
+#endif
+
+/* The samsung_gpiolib_4bit routines are to control the gpio banks where
+ * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
+ * following example:
+ *
+ * base + 0x00: Control register, 4 bits per gpio
+ * gpio n: 4 bits starting at (4*n)
+ * 0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ * bit n: data bit n
+ *
+ * Note, since the data register is one bit per gpio and is at base + 0x4
+ * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
+ * the output.
+*/
+
+static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long con;
+
+ con = __raw_readl(base + GPIOCON_OFF);
+ con &= ~(0xf << con_4bit_shift(offset));
+ __raw_writel(con, base + GPIOCON_OFF);
+
+ gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
+
+ return 0;
+}
+
+static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long con;
+ unsigned long dat;
+
+ con = __raw_readl(base + GPIOCON_OFF);
+ con &= ~(0xf << con_4bit_shift(offset));
+ con |= 0x1 << con_4bit_shift(offset);
+
+ dat = __raw_readl(base + GPIODAT_OFF);
+
+ if (value)
+ dat |= 1 << offset;
+ else
+ dat &= ~(1 << offset);
+
+ __raw_writel(dat, base + GPIODAT_OFF);
+ __raw_writel(con, base + GPIOCON_OFF);
+ __raw_writel(dat, base + GPIODAT_OFF);
+
+ gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+ return 0;
+}
+
+/* The next set of routines are for the case where the GPIO configuration
+ * registers are 4 bits per GPIO but there is more than one register (the
+ * bank has more than 8 GPIOs.
+ *
+ * This case is the similar to the 4 bit case, but the registers are as
+ * follows:
+ *
+ * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
+ * gpio n: 4 bits starting at (4*n)
+ * 0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
+ * gpio n: 4 bits starting at (4*n)
+ * 0000 = input, 0001 = output, others mean special-function
+ * base + 0x08: Data register, 1 bit per gpio
+ * bit n: data bit n
+ *
+ * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we
+ * store the 'base + 0x4' address so that these routines see the data
+ * register at ourchip->base + 0x04.
+ */
+
+static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ void __iomem *regcon = base;
+ unsigned long con;
+
+ if (offset > 7)
+ offset -= 8;
+ else
+ regcon -= 4;
+
+ con = __raw_readl(regcon);
+ con &= ~(0xf << con_4bit_shift(offset));
+ __raw_writel(con, regcon);
+
+ gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
+
+ return 0;
+}
+
+static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ void __iomem *regcon = base;
+ unsigned long con;
+ unsigned long dat;
+ unsigned con_offset = offset;
+
+ if (con_offset > 7)
+ con_offset -= 8;
+ else
+ regcon -= 4;
+
+ con = __raw_readl(regcon);
+ con &= ~(0xf << con_4bit_shift(con_offset));
+ con |= 0x1 << con_4bit_shift(con_offset);
+
+ dat = __raw_readl(base + GPIODAT_OFF);
+
+ if (value)
+ dat |= 1 << offset;
+ else
+ dat &= ~(1 << offset);
+
+ __raw_writel(dat, base + GPIODAT_OFF);
+ __raw_writel(con, regcon);
+ __raw_writel(dat, base + GPIODAT_OFF);
+
+ gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+ return 0;
+}
+
+void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
+{
+ chip->chip.direction_input = samsung_gpiolib_4bit_input;
+ chip->chip.direction_output = samsung_gpiolib_4bit_output;
+ chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+}
+
+void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
+{
+ chip->chip.direction_input = samsung_gpiolib_4bit2_input;
+ chip->chip.direction_output = samsung_gpiolib_4bit2_output;
+ chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+}
+
+void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
+ int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chip++) {
+ samsung_gpiolib_add_4bit(chip);
+ s3c_gpiolib_add(chip);
+ }
+}
+
+void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
+ int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chip++) {
+ samsung_gpiolib_add_4bit2(chip);
+ s3c_gpiolib_add(chip);
+ }
+}
diff --git a/arch/arm/plat-samsung/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h
new file mode 100644
index 00000000000..e8382c7be10
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/adc.h
@@ -0,0 +1,35 @@
+/* arch/arm/plat-samsung/include/plat/adc.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simnte.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C ADC driver information
+ *
+ * This program is free software; you can 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_H
+#define __ASM_PLAT_ADC_H __FILE__
+
+struct s3c_adc_client;
+
+extern int s3c_adc_start(struct s3c_adc_client *client,
+ unsigned int channel, unsigned int nr_samples);
+
+extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
+
+extern struct s3c_adc_client *
+ s3c_adc_register(struct platform_device *pdev,
+ void (*select)(struct s3c_adc_client *client,
+ unsigned selected),
+ void (*conv)(struct s3c_adc_client *client,
+ unsigned d0, unsigned d1,
+ unsigned *samples_left),
+ unsigned int is_ts);
+
+extern void s3c_adc_release(struct s3c_adc_client *client);
+
+#endif /* __ASM_PLAT_ADC_H */
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
new file mode 100644
index 00000000000..e32f9edfd4b
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -0,0 +1,25 @@
+/* arch/arm/plat-samsung/include/plat/audio.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co. Ltd
+ * Author: Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* The machine init code calls s3c*_ac97_setup_gpio with
+ * one of these defines in order to select appropriate bank
+ * of GPIO for AC97 pins
+ */
+#define S3C64XX_AC97_GPD 0
+#define S3C64XX_AC97_GPE 1
+extern void s3c64xx_ac97_setup_gpio(int);
+
+/**
+ * struct s3c_audio_pdata - common platform data for audio device drivers
+ * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
+ */
+struct s3c_audio_pdata {
+ int (*cfg_gpio)(struct platform_device *);
+};
diff --git a/arch/arm/plat-samsung/include/plat/clock-clksrc.h b/arch/arm/plat-samsung/include/plat/clock-clksrc.h
new file mode 100644
index 00000000000..50a8ca7c376
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/clock-clksrc.h
@@ -0,0 +1,83 @@
+/* linux/arch/arm/plat-samsung/include/plat/clock-clksrc.h
+ *
+ * Parts taken from arch/arm/plat-s3c64xx/clock.c
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Copyright 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2009 Harald Welte
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/**
+ * struct clksrc_sources - list of sources for a given clock
+ * @sources: array of pointers to clocks
+ * @nr_sources: The size of @sources
+ */
+struct clksrc_sources {
+ unsigned int nr_sources;
+ struct clk **sources;
+};
+
+/**
+ * struct clksrc_reg - register definition for clock control bits
+ * @reg: pointer to the register in virtual memory.
+ * @shift: the shift in bits to where the bitfield is.
+ * @size: the size in bits of the bitfield.
+ *
+ * This specifies the size and position of the bits we are interested
+ * in within the register specified by @reg.
+ */
+struct clksrc_reg {
+ void __iomem *reg;
+ unsigned short shift;
+ unsigned short size;
+};
+
+/**
+ * struct clksrc_clk - class of clock for newer style samsung devices.
+ * @clk: the standard clock representation
+ * @sources: the sources for this clock
+ * @reg_src: the register definition for selecting the clock's source
+ * @reg_div: the register definition for the clock's output divisor
+ *
+ * This clock implements the features required by the newer SoCs where
+ * the standard clock block provides an input mux and a post-mux divisor
+ * to provide the periperhal's clock.
+ *
+ * The array of @sources provides the mapping of mux position to the
+ * clock, and @reg_src shows the code where to modify to change the mux
+ * position. The @reg_div defines how to change the divider settings on
+ * the output.
+ */
+struct clksrc_clk {
+ struct clk clk;
+ struct clksrc_sources *sources;
+
+ struct clksrc_reg reg_src;
+ struct clksrc_reg reg_div;
+};
+
+/**
+ * s3c_set_clksrc() - setup the clock from the register settings
+ * @clk: The clock to setup.
+ * @announce: true to announce the setting to printk().
+ *
+ * Setup the clock from the current register settings, for when the
+ * kernel boots or if it is resuming from a possibly unknown state.
+ */
+extern void s3c_set_clksrc(struct clksrc_clk *clk, bool announce);
+
+/**
+ * s3c_register_clksrc() register clocks from an array of clksrc clocks
+ * @srcs: The array of clocks to register
+ * @size: The size of the @srcs array.
+ *
+ * Initialise and register the array of clocks described by @srcs.
+ */
+extern void s3c_register_clksrc(struct clksrc_clk *srcs, int size);
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
new file mode 100644
index 00000000000..60b62692ac7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -0,0 +1,115 @@
+/* linux/arch/arm/plat-s3c/include/plat/clock.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/SWLINUX/
+ * Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/spinlock.h>
+
+struct clk;
+
+/**
+ * struct clk_ops - standard clock operations
+ * @set_rate: set the clock rate, see clk_set_rate().
+ * @get_rate: get the clock rate, see clk_get_rate().
+ * @round_rate: round a given clock rate, see clk_round_rate().
+ * @set_parent: set the clock's parent, see clk_set_parent().
+ *
+ * Group the common clock implementations together so that we
+ * don't have to keep setting the same fiels again. We leave
+ * enable in struct clk.
+ *
+ * Adding an extra layer of indirection into the process should
+ * not be a problem as it is unlikely these operations are going
+ * to need to be called quickly.
+ */
+struct clk_ops {
+ int (*set_rate)(struct clk *c, unsigned long rate);
+ unsigned long (*get_rate)(struct clk *c);
+ unsigned long (*round_rate)(struct clk *c, unsigned long rate);
+ int (*set_parent)(struct clk *c, struct clk *parent);
+};
+
+struct clk {
+ struct list_head list;
+ struct module *owner;
+ struct clk *parent;
+ const char *name;
+ int id;
+ int usage;
+ unsigned long rate;
+ unsigned long ctrlbit;
+
+ struct clk_ops *ops;
+ int (*enable)(struct clk *, int enable);
+};
+
+/* other clocks which may be registered by board support */
+
+extern struct clk s3c24xx_dclk0;
+extern struct clk s3c24xx_dclk1;
+extern struct clk s3c24xx_clkout0;
+extern struct clk s3c24xx_clkout1;
+extern struct clk s3c24xx_uclk;
+
+extern struct clk clk_usb_bus;
+
+/* core clock support */
+
+extern struct clk clk_f;
+extern struct clk clk_h;
+extern struct clk clk_p;
+extern struct clk clk_mpll;
+extern struct clk clk_upll;
+extern struct clk clk_epll;
+extern struct clk clk_xtal;
+extern struct clk clk_ext;
+
+/* S3C64XX specific clocks */
+extern struct clk clk_h2;
+extern struct clk clk_27m;
+extern struct clk clk_48m;
+
+extern int clk_default_setrate(struct clk *clk, unsigned long rate);
+extern struct clk_ops clk_ops_def_setrate;
+
+/* exports for arch/arm/mach-s3c2410
+ *
+ * Please DO NOT use these outside of arch/arm/mach-s3c2410
+*/
+
+extern spinlock_t clocks_lock;
+
+extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
+
+extern int s3c24xx_register_clock(struct clk *clk);
+extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
+
+extern void s3c_register_clocks(struct clk *clk, int nr_clks);
+
+extern int s3c24xx_register_baseclocks(unsigned long xtal);
+
+extern void s5p_register_clocks(unsigned long xtal_freq);
+
+extern void s3c24xx_setup_clocks(unsigned long fclk,
+ unsigned long hclk,
+ unsigned long pclk);
+
+extern void s3c2410_setup_clocks(void);
+extern void s3c2412_setup_clocks(void);
+extern void s3c244x_setup_clocks(void);
+extern void s3c2443_setup_clocks(void);
+
+/* S3C64XX specific functions and clocks */
+
+extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
+
+/* Init for pwm clock code */
+
+extern void s3c_pwmclk_init(void);
+
diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq.h b/arch/arm/plat-samsung/include/plat/cpu-freq.h
new file mode 100644
index 00000000000..80c4a809c72
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/cpu-freq.h
@@ -0,0 +1,145 @@
+/* arch/arm/plat-samsung/include/plat/cpu-freq.h
+ *
+ * Copyright (c) 2006-2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C CPU frequency scaling support - driver and board
+ *
+ * This program is free software; you can 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/cpufreq.h>
+
+struct s3c_cpufreq_info;
+struct s3c_cpufreq_board;
+struct s3c_iotimings;
+
+/**
+ * struct s3c_freq - frequency information (mainly for core drivers)
+ * @fclk: The FCLK frequency in Hz.
+ * @armclk: The ARMCLK frequency in Hz.
+ * @hclk_tns: HCLK cycle time in 10ths of nano-seconds.
+ * @hclk: The HCLK frequency in Hz.
+ * @pclk: The PCLK frequency in Hz.
+ *
+ * This contains the frequency information about the current configuration
+ * mainly for the core drivers to ensure we do not end up passing about
+ * a large number of parameters.
+ *
+ * The @hclk_tns field is a useful cache for the parts of the drivers that
+ * need to calculate IO timings and suchlike.
+ */
+struct s3c_freq {
+ unsigned long fclk;
+ unsigned long armclk;
+ unsigned long hclk_tns; /* in 10ths of ns */
+ unsigned long hclk;
+ unsigned long pclk;
+};
+
+/**
+ * struct s3c_cpufreq_freqs - s3c cpufreq notification information.
+ * @freqs: The cpufreq setting information.
+ * @old: The old clock settings.
+ * @new: The new clock settings.
+ * @pll_changing: Set if the PLL is changing.
+ *
+ * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the
+ * notification can use this information that is not provided by just
+ * having the core frequency alone.
+ *
+ * The pll_changing flag is used to indicate if the PLL itself is
+ * being set during this change. This is important as the clocks
+ * will temporarily be set to the XTAL clock during this time, so
+ * drivers may want to close down their output during this time.
+ *
+ * Note, this is not being used by any current drivers and therefore
+ * may be removed in the future.
+ */
+struct s3c_cpufreq_freqs {
+ struct cpufreq_freqs freqs;
+ struct s3c_freq old;
+ struct s3c_freq new;
+
+ unsigned int pll_changing:1;
+};
+
+#define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs)
+
+/**
+ * struct s3c_clkdivs - clock divisor information
+ * @p_divisor: Divisor from FCLK to PCLK.
+ * @h_divisor: Divisor from FCLK to HCLK.
+ * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs).
+ * @dvs: Non-zero if using DVS mode for ARMCLK.
+ *
+ * Divisor settings for the core clocks.
+ */
+struct s3c_clkdivs {
+ int p_divisor;
+ int h_divisor;
+ int arm_divisor;
+ unsigned char dvs;
+};
+
+#define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s))
+
+/**
+ * struct s3c_pllval - PLL value entry.
+ * @freq: The frequency for this entry in Hz.
+ * @pll_reg: The PLL register setting for this PLL value.
+ */
+struct s3c_pllval {
+ unsigned long freq;
+ unsigned long pll_reg;
+};
+
+/**
+ * struct s3c_cpufreq_board - per-board cpu frequency informatin
+ * @refresh: The SDRAM refresh period in nanoseconds.
+ * @auto_io: Set if the IO timing settings should be generated from the
+ * initialisation time hardware registers.
+ * @need_io: Set if the board has external IO on any of the chipselect
+ * lines that will require the hardware timing registers to be
+ * updated on a clock change.
+ * @max: The maxium frequency limits for the system. Any field that
+ * is left at zero will use the CPU's settings.
+ *
+ * This contains the board specific settings that affect how the CPU
+ * drivers chose settings. These include the memory refresh and IO
+ * timing information.
+ *
+ * Registration depends on the driver being used, the ARMCLK only
+ * implementation does not currently need this but the older style
+ * driver requires this to be available.
+ */
+struct s3c_cpufreq_board {
+ unsigned int refresh;
+ unsigned int auto_io:1; /* automatically init io timings. */
+ unsigned int need_io:1; /* set if needs io timing support. */
+
+ /* any non-zero field in here is taken as an upper limit. */
+ struct s3c_freq max; /* frequency limits */
+};
+
+/* Things depending on frequency scaling. */
+#ifdef CONFIG_CPU_FREQ_S3C
+#define __init_or_cpufreq
+#else
+#define __init_or_cpufreq __init
+#endif
+
+/* Board functions */
+
+#ifdef CONFIG_CPU_FREQ_S3C
+extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board);
+#else
+
+static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
+{
+ return 0;
+}
+#endif /* CONFIG_CPU_FREQ_S3C */
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
new file mode 100644
index 00000000000..d316b4a579f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/include/plat/cpu.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* todo - fix when rmk changes iodescs to use `void __iomem *` */
+
+#ifndef __SAMSUNG_PLAT_CPU_H
+#define __SAMSUNG_PLAT_CPU_H
+
+#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+#define print_mhz(m) ((m) / MHZ), (((m) / 1000) % 1000)
+
+/* forward declaration */
+struct s3c24xx_uart_resources;
+struct platform_device;
+struct s3c2410_uartcfg;
+struct map_desc;
+
+/* per-cpu initialisation function table. */
+
+struct cpu_table {
+ unsigned long idcode;
+ unsigned long idmask;
+ void (*map_io)(void);
+ void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
+ void (*init_clocks)(int xtal);
+ int (*init)(void);
+ const char *name;
+};
+
+extern void s3c_init_cpu(unsigned long idcode,
+ struct cpu_table *cpus, unsigned int cputab_size);
+
+/* core initialisation functions */
+
+extern void s3c24xx_init_irq(void);
+extern void s3c64xx_init_irq(u32 vic0, u32 vic1);
+extern void s5p_init_irq(u32 *vic, u32 num_vic);
+
+extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
+extern void s3c64xx_init_io(struct map_desc *mach_desc, int size);
+extern void s5p_init_io(struct map_desc *mach_desc,
+ int size, void __iomem *cpuid_addr);
+
+extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c24xx_init_clocks(int xtal);
+
+extern void s3c24xx_init_uartdevs(char *name,
+ struct s3c24xx_uart_resources *res,
+ struct s3c2410_uartcfg *cfg, int no);
+
+/* timer for 2410/2440 */
+
+struct sys_timer;
+extern struct sys_timer s3c24xx_timer;
+
+/* system device classes */
+
+extern struct sysdev_class s3c2410_sysclass;
+extern struct sysdev_class s3c2410a_sysclass;
+extern struct sysdev_class s3c2412_sysclass;
+extern struct sysdev_class s3c2440_sysclass;
+extern struct sysdev_class s3c2442_sysclass;
+extern struct sysdev_class s3c2443_sysclass;
+extern struct sysdev_class s3c6410_sysclass;
+extern struct sysdev_class s3c64xx_sysclass;
+
+extern void (*s5pc1xx_idle)(void);
+
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/debug-macro.S b/arch/arm/plat-samsung/include/plat/debug-macro.S
new file mode 100644
index 00000000000..dc6efd90e8f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/debug-macro.S
@@ -0,0 +1,87 @@
+/* arch/arm/plat-samsung/include/plat/debug-macro.S
+ *
+ * Copyright 2005, 2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <plat/regs-serial.h>
+
+/* The S5PV210/S5PC110 and S5P6442 implementations are as belows. */
+
+ .macro fifo_level_s5pv210 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ and \rd, \rd, #S5PV210_UFSTAT_TXMASK
+ .endm
+
+ .macro fifo_full_s5pv210 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ tst \rd, #S5PV210_UFSTAT_TXFULL
+ .endm
+
+/* The S3C2440 implementations are used by default as they are the
+ * most widely re-used */
+
+ .macro fifo_level_s3c2440 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ and \rd, \rd, #S3C2440_UFSTAT_TXMASK
+ .endm
+
+#ifndef fifo_level
+#define fifo_level fifo_level_s3c2440
+#endif
+
+ .macro fifo_full_s3c2440 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ tst \rd, #S3C2440_UFSTAT_TXFULL
+ .endm
+
+#ifndef fifo_full
+#define fifo_full fifo_full_s3c2440
+#endif
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, # S3C2410_UTXH ]
+ .endm
+
+ .macro busyuart, rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFCON ]
+ tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled?
+ beq 1001f @
+ @ FIFO enabled...
+1003:
+ fifo_full \rd, \rx
+ bne 1003b
+ b 1002f
+
+1001:
+ @ busy waiting for non fifo
+ ldr \rd, [ \rx, # S3C2410_UTRSTAT ]
+ tst \rd, #S3C2410_UTRSTAT_TXFE
+ beq 1001b
+
+1002: @ exit busyuart
+ .endm
+
+ .macro waituart,rd,rx
+ ldr \rd, [ \rx, # S3C2410_UFCON ]
+ tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled?
+ beq 1001f @
+ @ FIFO enabled...
+1003:
+ fifo_level \rd, \rx
+ teq \rd, #0
+ bne 1003b
+ b 1002f
+1001:
+ @ idle waiting for non fifo
+ ldr \rd, [ \rx, # S3C2410_UTRSTAT ]
+ tst \rd, #S3C2410_UTRSTAT_TXFE
+ beq 1001b
+
+1002: @ exit busyuart
+ .endm
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
new file mode 100644
index 00000000000..796d2425831
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -0,0 +1,74 @@
+/* arch/arm/plat-samsung/include/plat/devs.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 standard platform devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#include <linux/platform_device.h>
+
+struct s3c24xx_uart_resources {
+ struct resource *resources;
+ unsigned long nr_resources;
+};
+
+extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
+extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
+extern struct s3c24xx_uart_resources s5p_uart_resources[];
+
+extern struct platform_device *s3c24xx_uart_devs[];
+extern struct platform_device *s3c24xx_uart_src[];
+
+extern struct platform_device s3c_device_timer[];
+
+extern struct platform_device s3c64xx_device_iis0;
+extern struct platform_device s3c64xx_device_iis1;
+extern struct platform_device s3c64xx_device_iisv4;
+
+extern struct platform_device s3c64xx_device_spi0;
+extern struct platform_device s3c64xx_device_spi1;
+
+extern struct platform_device s3c64xx_device_pcm0;
+extern struct platform_device s3c64xx_device_pcm1;
+
+extern struct platform_device s3c64xx_device_ac97;
+
+extern struct platform_device s3c_device_ts;
+
+extern struct platform_device s3c_device_fb;
+extern struct platform_device s3c_device_ohci;
+extern struct platform_device s3c_device_lcd;
+extern struct platform_device s3c_device_wdt;
+extern struct platform_device s3c_device_i2c0;
+extern struct platform_device s3c_device_i2c1;
+extern struct platform_device s3c_device_rtc;
+extern struct platform_device s3c_device_adc;
+extern struct platform_device s3c_device_sdi;
+extern struct platform_device s3c_device_iis;
+extern struct platform_device s3c_device_hwmon;
+extern struct platform_device s3c_device_hsmmc0;
+extern struct platform_device s3c_device_hsmmc1;
+extern struct platform_device s3c_device_hsmmc2;
+
+extern struct platform_device s3c_device_spi0;
+extern struct platform_device s3c_device_spi1;
+
+extern struct platform_device s3c_device_hwmon;
+
+extern struct platform_device s3c_device_nand;
+
+extern struct platform_device s3c_device_usbgadget;
+extern struct platform_device s3c_device_usb_hsotg;
+
+/* s3c2440 specific devices */
+
+#ifdef CONFIG_CPU_S3C2440
+
+extern struct platform_device s3c_device_camif;
+extern struct platform_device s3c_device_ac97;
+
+#endif
diff --git a/arch/arm/plat-s3c/include/plat/dma-core.h b/arch/arm/plat-samsung/include/plat/dma-core.h
index 32ff2a92cb3..32ff2a92cb3 100644
--- a/arch/arm/plat-s3c/include/plat/dma-core.h
+++ b/arch/arm/plat-samsung/include/plat/dma-core.h
diff --git a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
new file mode 100644
index 00000000000..336d5ac0203
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
+ *
+ * Copyright (C) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support - per SoC 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.
+*/
+
+#include <plat/dma-core.h>
+
+extern struct sysdev_class dma_sysclass;
+extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
+
+#define DMA_CH_VALID (1<<31)
+#define DMA_CH_NEVER (1<<30)
+
+struct s3c24xx_dma_addr {
+ unsigned long from;
+ unsigned long to;
+};
+
+/* struct s3c24xx_dma_map
+ *
+ * this holds the mapping information for the channel selected
+ * to be connected to the specified device
+*/
+
+struct s3c24xx_dma_map {
+ const char *name;
+ struct s3c24xx_dma_addr hw_addr;
+
+ unsigned long channels[S3C_DMA_CHANNELS];
+ unsigned long channels_rx[S3C_DMA_CHANNELS];
+};
+
+struct s3c24xx_dma_selection {
+ struct s3c24xx_dma_map *map;
+ unsigned long map_size;
+ unsigned long dcon_mask;
+
+ void (*select)(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map);
+
+ void (*direction)(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map,
+ enum s3c2410_dmasrc dir);
+};
+
+extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
+
+/* struct s3c24xx_dma_order_ch
+ *
+ * channel map for one of the `enum dma_ch` dma channels. the list
+ * entry contains a set of low-level channel numbers, orred with
+ * DMA_CH_VALID, which are checked in the order in the array.
+*/
+
+struct s3c24xx_dma_order_ch {
+ unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */
+ unsigned int flags; /* flags */
+};
+
+/* struct s3c24xx_dma_order
+ *
+ * information provided by either the core or the board to give the
+ * dma system a hint on how to allocate channels
+*/
+
+struct s3c24xx_dma_order {
+ struct s3c24xx_dma_order_ch channels[DMACH_MAX];
+};
+
+extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
+
+/* DMA init code, called from the cpu support code */
+
+extern int s3c2410_dma_init(void);
+
+extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+ unsigned int stride);
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
new file mode 100644
index 00000000000..7584d751ed5
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/dma.h
@@ -0,0 +1,127 @@
+/* arch/arm/plat-samsung/include/plat/dma.h
+ *
+ * Copyright (C) 2003-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C DMA support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+enum s3c2410_dma_buffresult {
+ S3C2410_RES_OK,
+ S3C2410_RES_ERR,
+ S3C2410_RES_ABORT
+};
+
+enum s3c2410_dmasrc {
+ S3C2410_DMASRC_HW, /* source is memory */
+ S3C2410_DMASRC_MEM /* source is hardware */
+};
+
+/* enum s3c2410_chan_op
+ *
+ * operation codes passed to the DMA code by the user, and also used
+ * to inform the current channel owner of any changes to the system state
+*/
+
+enum s3c2410_chan_op {
+ S3C2410_DMAOP_START,
+ S3C2410_DMAOP_STOP,
+ S3C2410_DMAOP_PAUSE,
+ S3C2410_DMAOP_RESUME,
+ S3C2410_DMAOP_FLUSH,
+ S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */
+ S3C2410_DMAOP_STARTED, /* indicate channel started */
+};
+
+struct s3c2410_dma_client {
+ char *name;
+};
+
+struct s3c2410_dma_chan;
+
+/* s3c2410_dma_cbfn_t
+ *
+ * buffer callback routine type
+*/
+
+typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
+ void *buf, int size,
+ enum s3c2410_dma_buffresult result);
+
+typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
+ enum s3c2410_chan_op );
+
+
+
+/* s3c2410_dma_request
+ *
+ * request a dma channel exclusivley
+*/
+
+extern int s3c2410_dma_request(unsigned int channel,
+ struct s3c2410_dma_client *, void *dev);
+
+
+/* s3c2410_dma_ctrl
+ *
+ * change the state of the dma channel
+*/
+
+extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op);
+
+/* s3c2410_dma_setflags
+ *
+ * set the channel's flags to a given state
+*/
+
+extern int s3c2410_dma_setflags(unsigned int channel,
+ unsigned int flags);
+
+/* s3c2410_dma_free
+ *
+ * free the dma channel (will also abort any outstanding operations)
+*/
+
+extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *);
+
+/* s3c2410_dma_enqueue
+ *
+ * place the given buffer onto the queue of operations for the channel.
+ * The buffer must be allocated from dma coherent memory, or the Dcache/WB
+ * drained before the buffer is given to the DMA system.
+*/
+
+extern int s3c2410_dma_enqueue(unsigned int channel, void *id,
+ dma_addr_t data, int size);
+
+/* s3c2410_dma_config
+ *
+ * configure the dma channel
+*/
+
+extern int s3c2410_dma_config(unsigned int channel, int xferunit);
+
+/* s3c2410_dma_devconfig
+ *
+ * configure the device we're talking to
+*/
+
+extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
+ unsigned long devaddr);
+
+/* s3c2410_dma_getposition
+ *
+ * get the position that the dma transfer is currently at
+*/
+
+extern int s3c2410_dma_getposition(unsigned int channel,
+ dma_addr_t *src, dma_addr_t *dest);
+
+extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn);
+extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn);
+
+
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
new file mode 100644
index 00000000000..ffc01a76b7c
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -0,0 +1,80 @@
+/* arch/arm/plat-samsung/include/plat/fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - FB platform data definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S3C_FB_H
+#define __PLAT_S3C_FB_H __FILE__
+
+/**
+ * struct s3c_fb_pd_win - per window setup data
+ * @win_mode: The display parameters to initialise (not for window 0)
+ * @virtual_x: The virtual X size.
+ * @virtual_y: The virtual Y size.
+ */
+struct s3c_fb_pd_win {
+ struct fb_videomode win_mode;
+
+ unsigned short default_bpp;
+ unsigned short max_bpp;
+ unsigned short virtual_x;
+ unsigned short virtual_y;
+};
+
+/**
+ * struct s3c_fb_platdata - S3C driver platform specific information
+ * @setup_gpio: Setup the external GPIO pins to the right state to transfer
+ * the data from the display system to the connected display
+ * device.
+ * @vidcon0: The base vidcon0 values to control the panel data format.
+ * @vidcon1: The base vidcon1 values to control the panel data output.
+ * @win: The setup data for each hardware window, or NULL for unused.
+ * @display_mode: The LCD output display mode.
+ *
+ * The platform data supplies the video driver with all the information
+ * it requires to work with the display(s) attached to the machine. It
+ * controls the initial mode, the number of display windows (0 is always
+ * the base framebuffer) that are initialised etc.
+ *
+ */
+struct s3c_fb_platdata {
+ void (*setup_gpio)(void);
+
+ struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN];
+
+ u32 vidcon0;
+ u32 vidcon1;
+};
+
+/**
+ * s3c_fb_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ * so the machine data can mark the data __initdata so that any unused
+ * machines will end up dumping their data at runtime.
+ */
+extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
+ * s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s3c64xx_fb_gpio_setup_24bpp(void);
+
+/**
+ * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5pc100_fb_gpio_setup_24bpp(void);
+
+#endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
new file mode 100644
index 00000000000..dda19da037a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -0,0 +1,176 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO pin configuration helper definitions
+ *
+ * This program is free software; you can 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 is meant for core cpu support, machine or other driver files
+ * should not be including this header.
+ */
+
+#ifndef __PLAT_GPIO_CFG_HELPERS_H
+#define __PLAT_GPIO_CFG_HELPERS_H __FILE__
+
+/* As a note, all gpio configuration functions are entered exclusively, either
+ * with the relevant lock held or the system prevented from doing anything else
+ * by disabling interrupts.
+*/
+
+static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int config)
+{
+ return (chip->config->set_config)(chip, off, config);
+}
+
+static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ return (chip->config->set_pull)(chip, off, pull);
+}
+
+/**
+ * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has two bits of configuration per gpio, which have the following
+ * functions:
+ * 00 = input
+ * 01 = output
+ * 1x = special function
+*/
+extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg);
+
+/**
+ * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has one bit of configuration for the gpio, where setting the bit
+ * means the pin is in special function mode and unset means output.
+*/
+extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg);
+
+/**
+ * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependant on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of functions for
+ * each case.
+*/
+extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg);
+
+
+/* Pull-{up,down} resistor controls.
+ *
+ * S3C2410,S3C2440,S3C24A0 = Pull-UP,
+ * S3C2412,S3C2413 = Pull-Down
+ * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef]
+ * S3C2443 = Pull-Both [not same as S3C6400]
+ */
+
+/**
+ * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with one
+ * bit configuring the presence of a pull-up resistor.
+ */
+extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none
+ * @chip: The gpio chip that is being configured
+ * @off: The offset for the GPIO being configured
+ * @param: pull: The pull mode being requested
+ *
+ * This is a helper function for the case where we have GPIOs with one
+ * bit configuring the presence of a pull-down resistor.
+ */
+extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with two
+ * bits configuring the presence of a pull resistor, in the following
+ * order:
+ * 00 = No pull resistor connected
+ * 01 = Pull-up resistor connected
+ * 10 = Pull-down resistor connected
+ */
+extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+
+/**
+ * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-{up,down} resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_upown.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with two
+ * bits configuring the presence of a pull resistor, in the following
+ * order:
+ * 00 = Pull-up resistor connected
+ * 10 = Pull-down resistor connected
+ * x1 = No pull up resistor
+ */
+extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors
+ * @chip: The gpio chip that the GPIO pin belongs to.
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-{up,down} resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_upown.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+#endif /* __PLAT_GPIO_CFG_HELPERS_H */
+
diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 29cd6a86cad..29cd6a86cad 100644
--- a/arch/arm/plat-s3c/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
new file mode 100644
index 00000000000..49ff406a706
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -0,0 +1,137 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-core.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define GPIOCON_OFF (0x00)
+#define GPIODAT_OFF (0x04)
+
+#define con_4bit_shift(__off) ((__off) * 4)
+
+/* Define the core gpiolib support functions that the s3c platforms may
+ * need to extend or change depending on the hardware and the s3c chip
+ * selected at build or found at run time.
+ *
+ * These definitions are not intended for driver inclusion, there is
+ * nothing here that should not live outside the platform and core
+ * specific code.
+*/
+
+struct s3c_gpio_chip;
+
+/**
+ * struct s3c_gpio_pm - power management (suspend/resume) information
+ * @save: Routine to save the state of the GPIO block
+ * @resume: Routine to resume the GPIO block.
+ */
+struct s3c_gpio_pm {
+ void (*save)(struct s3c_gpio_chip *chip);
+ void (*resume)(struct s3c_gpio_chip *chip);
+};
+
+struct s3c_gpio_cfg;
+
+/**
+ * struct s3c_gpio_chip - wrapper for specific implementation of gpio
+ * @chip: The chip structure to be exported via gpiolib.
+ * @base: The base pointer to the gpio configuration registers.
+ * @config: special function and pull-resistor control information.
+ * @pm_save: Save information for suspend/resume support.
+ *
+ * This wrapper provides the necessary information for the Samsung
+ * specific gpios being registered with gpiolib.
+ */
+struct s3c_gpio_chip {
+ struct gpio_chip chip;
+ struct s3c_gpio_cfg *config;
+ struct s3c_gpio_pm *pm;
+ void __iomem *base;
+#ifdef CONFIG_PM
+ u32 pm_save[4];
+#endif
+};
+
+static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
+{
+ return container_of(gpc, struct s3c_gpio_chip, chip);
+}
+
+/** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip.
+ * @chip: The chip to register
+ *
+ * This is a wrapper to gpiochip_add() that takes our specific gpio chip
+ * information and makes the necessary alterations for the platform and
+ * notes the information for use with the configuration systems and any
+ * other parts of the system.
+ */
+extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
+
+/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
+ * for use with the configuration calls, and other parts of the s3c gpiolib
+ * support code.
+ *
+ * Not all s3c support code will need this, as some configurations of cpu
+ * may only support one or two different configuration options and have an
+ * easy gpio to s3c_gpio_chip mapping function. If this is the case, then
+ * the machine support file should provide its own s3c_gpiolib_getchip()
+ * and any other necessary functions.
+ */
+
+/**
+ * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependant on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a seperate set of function
+ * (samsung_gpiolib_add_4bit2_chips)for each case.
+ */
+extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
+ int nr_chips);
+extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
+ int nr_chips);
+
+extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
+extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
+{
+ return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
+}
+#else
+/* machine specific code should provide s3c_gpiolib_getchip */
+
+#include <mach/gpio-track.h>
+
+static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
+#endif
+
+#ifdef CONFIG_PM
+extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
+extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
+extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
+#define __gpio_pm(x) x
+#else
+#define s3c_gpio_pm_1bit NULL
+#define s3c_gpio_pm_2bit NULL
+#define s3c_gpio_pm_4bit NULL
+#define __gpio_pm(x) NULL
+
+#endif /* CONFIG_PM */
diff --git a/arch/arm/plat-s3c/include/plat/hwmon.h b/arch/arm/plat-samsung/include/plat/hwmon.h
index 1ba88ea0aa3..1ba88ea0aa3 100644
--- a/arch/arm/plat-s3c/include/plat/hwmon.h
+++ b/arch/arm/plat-samsung/include/plat/hwmon.h
diff --git a/arch/arm/plat-s3c/include/plat/iic-core.h b/arch/arm/plat-samsung/include/plat/iic-core.h
index 36397ca2096..36397ca2096 100644
--- a/arch/arm/plat-s3c/include/plat/iic-core.h
+++ b/arch/arm/plat-samsung/include/plat/iic-core.h
diff --git a/arch/arm/plat-s3c/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 3083df00dee..3083df00dee 100644
--- a/arch/arm/plat-s3c/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
diff --git a/arch/arm/plat-samsung/include/plat/irq-uart.h b/arch/arm/plat-samsung/include/plat/irq-uart.h
new file mode 100644
index 00000000000..a9331e49bea
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/irq-uart.h
@@ -0,0 +1,20 @@
+/* arch/arm/plat-samsung/include/plat/irq-uart.h
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for Samsung SoC UART IRQ demux for S3C64XX and later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct s3c_uart_irq {
+ void __iomem *regs;
+ unsigned int base_irq;
+ unsigned int parent_irq;
+};
+
+extern void s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs);
+
diff --git a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
new file mode 100644
index 00000000000..a90b53431b5
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
@@ -0,0 +1,13 @@
+/* arch/arm/plat-samsung/include/plat/irq-vic-timer.h
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for Samsung SoC IRQ VIC timer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void s3c_init_vic_timer_irq(unsigned int vic, unsigned int timer);
diff --git a/arch/arm/plat-s3c/include/plat/map-base.h b/arch/arm/plat-samsung/include/plat/map-base.h
index 250be311c85..250be311c85 100644
--- a/arch/arm/plat-s3c/include/plat/map-base.h
+++ b/arch/arm/plat-samsung/include/plat/map-base.h
diff --git a/arch/arm/plat-samsung/include/plat/nand.h b/arch/arm/plat-samsung/include/plat/nand.h
new file mode 100644
index 00000000000..b64115fa93a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/nand.h
@@ -0,0 +1,67 @@
+/* arch/arm/mach-s3c2410/include/mach/nand.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - NAND device controller 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.
+*/
+
+/**
+ * struct s3c2410_nand_set - define a set of one or more nand chips
+ * @disable_ecc: Entirely disable ECC - Dangerous
+ * @flash_bbt: Openmoko u-boot can create a Bad Block Table
+ * Setting this flag will allow the kernel to
+ * look for it at boot time and also skip the NAND
+ * scan.
+ * @options: Default value to set into 'struct nand_chip' options.
+ * @nr_chips: Number of chips in this set
+ * @nr_partitions: Number of partitions pointed to by @partitions
+ * @name: Name of set (optional)
+ * @nr_map: Map for low-layer logical to physical chip numbers (option)
+ * @partitions: The mtd partition list
+ *
+ * define a set of one or more nand chips registered with an unique mtd. Also
+ * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger
+ * a warning at boot time.
+ */
+struct s3c2410_nand_set {
+ unsigned int disable_ecc:1;
+ unsigned int flash_bbt:1;
+
+ unsigned int options;
+ int nr_chips;
+ int nr_partitions;
+ char *name;
+ int *nr_map;
+ struct mtd_partition *partitions;
+ struct nand_ecclayout *ecc_layout;
+};
+
+struct s3c2410_platform_nand {
+ /* timing information for controller, all times in nanoseconds */
+
+ int tacls; /* time for active CLE/ALE to nWE/nOE */
+ int twrph0; /* active time for nWE/nOE */
+ int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */
+
+ unsigned int ignore_unset_ecc:1;
+
+ int nr_sets;
+ struct s3c2410_nand_set *sets;
+
+ void (*select_chip)(struct s3c2410_nand_set *,
+ int chip);
+};
+
+/**
+ * s3c_nand_set_platdata() - register NAND platform data.
+ * @nand: The NAND platform data to register with s3c_device_nand.
+ *
+ * This function copies the given NAND platform data, @nand and registers
+ * it with the s3c_device_nand. This allows @nand to be __initdata.
+*/
+extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand);
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
new file mode 100644
index 00000000000..245836d9193
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -0,0 +1,189 @@
+/* arch/arm/plat-samsung/include/plat/pm.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* s3c_pm_init
+ *
+ * called from board at initialisation time to setup the power
+ * management
+*/
+
+#ifdef CONFIG_PM
+
+extern __init int s3c_pm_init(void);
+
+#else
+
+static inline int s3c_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+/* configuration for the IRQ mask over sleep */
+extern unsigned long s3c_irqwake_intmask;
+extern unsigned long s3c_irqwake_eintmask;
+
+/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
+extern unsigned long s3c_irqwake_intallow;
+extern unsigned long s3c_irqwake_eintallow;
+
+/* per-cpu sleep functions */
+
+extern void (*pm_cpu_prep)(void);
+extern void (*pm_cpu_sleep)(void);
+
+/* Flags for PM Control */
+
+extern unsigned long s3c_pm_flags;
+
+extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */
+
+/* from sleep.S */
+
+extern int s3c_cpu_save(unsigned long *saveblk);
+extern void s3c_cpu_resume(void);
+
+extern void s3c2410_cpu_suspend(void);
+
+extern unsigned long s3c_sleep_save_phys;
+
+/* sleep save info */
+
+/**
+ * struct sleep_save - save information for shared peripherals.
+ * @reg: Pointer to the register to save.
+ * @val: Holder for the value saved from reg.
+ *
+ * This describes a list of registers which is used by the pm core and
+ * other subsystem to save and restore register values over suspend.
+ */
+struct sleep_save {
+ void __iomem *reg;
+ unsigned long val;
+};
+
+#define SAVE_ITEM(x) \
+ { .reg = (x) }
+
+/**
+ * struct pm_uart_save - save block for core UART
+ * @ulcon: Save value for S3C2410_ULCON
+ * @ucon: Save value for S3C2410_UCON
+ * @ufcon: Save value for S3C2410_UFCON
+ * @umcon: Save value for S3C2410_UMCON
+ * @ubrdiv: Save value for S3C2410_UBRDIV
+ *
+ * Save block for UART registers to be held over sleep and restored if they
+ * are needed (say by debug).
+*/
+struct pm_uart_save {
+ u32 ulcon;
+ u32 ucon;
+ u32 ufcon;
+ u32 umcon;
+ u32 ubrdiv;
+ u32 udivslot;
+};
+
+/* helper functions to save/restore lists of registers. */
+
+extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
+
+#ifdef CONFIG_PM
+extern int s3c_irqext_wake(unsigned int irqno, unsigned int state);
+extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
+extern int s3c24xx_irq_resume(struct sys_device *dev);
+#else
+#define s3c_irqext_wake NULL
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume NULL
+#endif
+
+/* PM debug functions */
+
+#ifdef CONFIG_SAMSUNG_PM_DEBUG
+/**
+ * s3c_pm_dbg() - low level debug function for use in suspend/resume.
+ * @msg: The message to print.
+ *
+ * This function is used mainly to debug the resume process before the system
+ * can rely on printk/console output. It uses the low-level debugging output
+ * routine printascii() to do its work.
+ */
+extern void s3c_pm_dbg(const char *msg, ...);
+
+#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
+#else
+#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
+#endif
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+/**
+ * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
+ * @set: set bits for the state of the LEDs
+ * @clear: clear bits for the state of the LEDs.
+ */
+extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
+
+#else
+static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
+#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
+
+/* suspend memory checking */
+
+#ifdef CONFIG_SAMSUNG_PM_CHECK
+extern void s3c_pm_check_prepare(void);
+extern void s3c_pm_check_restore(void);
+extern void s3c_pm_check_cleanup(void);
+extern void s3c_pm_check_store(void);
+#else
+#define s3c_pm_check_prepare() do { } while(0)
+#define s3c_pm_check_restore() do { } while(0)
+#define s3c_pm_check_cleanup() do { } while(0)
+#define s3c_pm_check_store() do { } while(0)
+#endif
+
+/**
+ * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ
+ *
+ * Setup all the necessary GPIO pins for waking the system on external
+ * interrupt.
+ */
+extern void s3c_pm_configure_extint(void);
+
+/**
+ * s3c_pm_restore_gpios() - restore the state of the gpios after sleep.
+ *
+ * Restore the state of the GPIO pins after sleep, which may involve ensuring
+ * that we do not glitch the state of the pins from that the bootloader's
+ * resume code has done.
+*/
+extern void s3c_pm_restore_gpios(void);
+
+/**
+ * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
+ *
+ * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios().
+ */
+extern void s3c_pm_save_gpios(void);
+
+/**
+ * s3c_pm_cb_flushcache - callback for assembly code
+ *
+ * Callback to issue flush_cache_all() as this call is
+ * not a directly callable object.
+ */
+extern void s3c_pm_cb_flushcache(void);
+
+extern void s3c_pm_save_core(void);
+extern void s3c_pm_restore_core(void);
diff --git a/arch/arm/plat-s3c/include/plat/regs-ac97.h b/arch/arm/plat-samsung/include/plat/regs-ac97.h
index c3878f7acb8..c3878f7acb8 100644
--- a/arch/arm/plat-s3c/include/plat/regs-ac97.h
+++ b/arch/arm/plat-samsung/include/plat/regs-ac97.h
diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h
new file mode 100644
index 00000000000..7554c4fcddb
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-adc.h
@@ -0,0 +1,64 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-adc.h
+ *
+ * Copyright (c) 2004 Shannon Holland <holland@loser.net>
+ *
+ * This program is free software; yosu can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 ADC registers
+*/
+
+#ifndef __ASM_ARCH_REGS_ADC_H
+#define __ASM_ARCH_REGS_ADC_H "regs-adc.h"
+
+#define S3C2410_ADCREG(x) (x)
+
+#define S3C2410_ADCCON S3C2410_ADCREG(0x00)
+#define S3C2410_ADCTSC S3C2410_ADCREG(0x04)
+#define S3C2410_ADCDLY S3C2410_ADCREG(0x08)
+#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C)
+#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
+#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14)
+#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18)
+#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20)
+
+
+/* ADCCON Register Bits */
+#define S3C64XX_ADCCON_RESSEL (1<<16)
+#define S3C2410_ADCCON_ECFLG (1<<15)
+#define S3C2410_ADCCON_PRSCEN (1<<14)
+#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
+#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)
+#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)
+#define S3C2410_ADCCON_MUXMASK (0x7<<3)
+#define S3C2410_ADCCON_STDBM (1<<2)
+#define S3C2410_ADCCON_READ_START (1<<1)
+#define S3C2410_ADCCON_ENABLE_START (1<<0)
+#define S3C2410_ADCCON_STARTMASK (0x3<<0)
+
+
+/* ADCTSC Register Bits */
+#define S3C2410_ADCTSC_YM_SEN (1<<7)
+#define S3C2410_ADCTSC_YP_SEN (1<<6)
+#define S3C2410_ADCTSC_XM_SEN (1<<5)
+#define S3C2410_ADCTSC_XP_SEN (1<<4)
+#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)
+#define S3C2410_ADCTSC_AUTO_PST (1<<2)
+#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0)
+
+/* ADCDAT0 Bits */
+#define S3C2410_ADCDAT0_UPDOWN (1<<15)
+#define S3C2410_ADCDAT0_AUTO_PST (1<<14)
+#define S3C2410_ADCDAT0_XY_PST (0x3<<12)
+#define S3C2410_ADCDAT0_XPDATA_MASK (0x03FF)
+
+/* ADCDAT1 Bits */
+#define S3C2410_ADCDAT1_UPDOWN (1<<15)
+#define S3C2410_ADCDAT1_AUTO_PST (1<<14)
+#define S3C2410_ADCDAT1_XY_PST (0x3<<12)
+#define S3C2410_ADCDAT1_YPDATA_MASK (0x03FF)
+
+#endif /* __ASM_ARCH_REGS_ADC_H */
+
+
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
new file mode 100644
index 00000000000..0f43599248a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
@@ -0,0 +1,235 @@
+/* arch/arm/plat-samsung/include/plat/regs-fb-v4.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards and specifically the S3C64XX series
+ * S3C6400 and S3C6410.
+ *
+ * The file contains the cpu specific items which change between whichever
+ * architecture is selected. See <plat/regs-fb.h> for the core definitions
+ * that are the same.
+ *
+ * This program is free software; you can 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 the core definitions here, in case we really do need to
+ * override them at a later date.
+*/
+
+#include <plat/regs-fb.h>
+
+#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */
+#define VIDCON1_FSTATUS_EVEN (1 << 15)
+
+/* Video timing controls */
+#define VIDTCON0 (0x10)
+#define VIDTCON1 (0x14)
+#define VIDTCON2 (0x18)
+
+/* Window position controls */
+
+#define WINCON(_win) (0x20 + ((_win) * 4))
+
+/* OSD1 and OSD4 do not have register D */
+
+#define VIDOSD_A(_win) (0x40 + ((_win) * 16))
+#define VIDOSD_B(_win) (0x44 + ((_win) * 16))
+#define VIDOSD_C(_win) (0x48 + ((_win) * 16))
+#define VIDOSD_D(_win) (0x4C + ((_win) * 16))
+
+
+#define VIDINTCON0 (0x130)
+
+#define WxKEYCONy(_win, _con) ((0x140 + ((_win) * 8)) + ((_con) * 4))
+
+/* WINCONx */
+
+#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT (26)
+#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
+
+#define WINCONx_ENLOCAL (1 << 22)
+#define WINCONx_BUFSTATUS (1 << 21)
+#define WINCONx_BUFSEL (1 << 20)
+#define WINCONx_BUFAUTOEN (1 << 19)
+#define WINCONx_YCbCr (1 << 13)
+
+#define WINCON1_LOCALSEL_CAMIF (1 << 23)
+
+#define WINCON2_LOCALSEL_CAMIF (1 << 23)
+#define WINCON2_BLD_PIX (1 << 6)
+
+#define WINCON2_ALPHA_SEL (1 << 1)
+#define WINCON2_BPPMODE_MASK (0xf << 2)
+#define WINCON2_BPPMODE_SHIFT (2)
+#define WINCON2_BPPMODE_1BPP (0x0 << 2)
+#define WINCON2_BPPMODE_2BPP (0x1 << 2)
+#define WINCON2_BPPMODE_4BPP (0x2 << 2)
+#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2)
+#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2)
+#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2)
+#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2)
+#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2)
+#define WINCON2_BPPMODE_24BPP_888 (0xb << 2)
+#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2)
+#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2)
+#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2)
+
+#define WINCON3_BLD_PIX (1 << 6)
+
+#define WINCON3_ALPHA_SEL (1 << 1)
+#define WINCON3_BPPMODE_MASK (0xf << 2)
+#define WINCON3_BPPMODE_SHIFT (2)
+#define WINCON3_BPPMODE_1BPP (0x0 << 2)
+#define WINCON3_BPPMODE_2BPP (0x1 << 2)
+#define WINCON3_BPPMODE_4BPP (0x2 << 2)
+#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2)
+#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2)
+#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2)
+#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2)
+#define WINCON3_BPPMODE_24BPP_888 (0xb << 2)
+#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2)
+#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2)
+#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2)
+
+#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
+
+#define DITHMODE (0x170)
+#define WINxMAP(_win) (0x180 + ((_win) * 4))
+
+
+#define DITHMODE_R_POS_MASK (0x3 << 5)
+#define DITHMODE_R_POS_SHIFT (5)
+#define DITHMODE_R_POS_8BIT (0x0 << 5)
+#define DITHMODE_R_POS_6BIT (0x1 << 5)
+#define DITHMODE_R_POS_5BIT (0x2 << 5)
+
+#define DITHMODE_G_POS_MASK (0x3 << 3)
+#define DITHMODE_G_POS_SHIFT (3)
+#define DITHMODE_G_POS_8BIT (0x0 << 3)
+#define DITHMODE_G_POS_6BIT (0x1 << 3)
+#define DITHMODE_G_POS_5BIT (0x2 << 3)
+
+#define DITHMODE_B_POS_MASK (0x3 << 1)
+#define DITHMODE_B_POS_SHIFT (1)
+#define DITHMODE_B_POS_8BIT (0x0 << 1)
+#define DITHMODE_B_POS_6BIT (0x1 << 1)
+#define DITHMODE_B_POS_5BIT (0x2 << 1)
+
+#define DITHMODE_DITH_EN (1 << 0)
+
+#define WPALCON (0x1A0)
+
+/* Palette control */
+/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
+ * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
+#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
+#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
+#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
+
+
+/* system specific implementation code for palette sizes, and other
+ * information that changes depending on which architecture is being
+ * compiled.
+*/
+
+/* return true if window _win has OSD register D */
+#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
+
+static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
+{
+ if (win < 2)
+ return 256;
+ if (win < 4)
+ return 16;
+ if (win == 4)
+ return 4;
+
+ BUG(); /* shouldn't get here */
+}
+
+static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
+{
+ /* all windows can do 1/2 bpp */
+
+ if ((bpp == 25 || bpp == 19) && win == 0)
+ return 0; /* win 0 does not have 19 or 25bpp modes */
+
+ if (bpp == 4 && win == 4)
+ return 0;
+
+ if (bpp == 8 && (win >= 3))
+ return 0; /* win 3/4 cannot do 8bpp in any mode */
+
+ return 1;
+}
+
+static inline int s3c_fb_pal_is16(unsigned int window)
+{
+ return window > 1;
+}
+
+struct s3c_fb_palette {
+ struct fb_bitfield r;
+ struct fb_bitfield g;
+ struct fb_bitfield b;
+ struct fb_bitfield a;
+};
+
+static inline void s3c_fb_init_palette(unsigned int window,
+ struct s3c_fb_palette *palette)
+{
+ if (window < 2) {
+ /* Windows 0/1 are 8/8/8 or A/8/8/8 */
+ palette->r.offset = 16;
+ palette->r.length = 8;
+ palette->g.offset = 8;
+ palette->g.length = 8;
+ palette->b.offset = 0;
+ palette->b.length = 8;
+ } else {
+ /* currently we assume RGB 5/6/5 */
+ palette->r.offset = 11;
+ palette->r.length = 5;
+ palette->g.offset = 5;
+ palette->g.length = 6;
+ palette->b.offset = 0;
+ palette->b.length = 5;
+ }
+}
+
+/* Notes on per-window bpp settings
+ *
+ * Value Win0 Win1 Win2 Win3 Win 4
+ * 0000 1(P) 1(P) 1(P) 1(P) 1(P)
+ * 0001 2(P) 2(P) 2(P) 2(P) 2(P)
+ * 0010 4(P) 4(P) 4(P) 4(P) -none-
+ * 0011 8(P) 8(P) -none- -none- -none-
+ * 0100 -none- 8(A232) 8(A232) -none- -none-
+ * 0101 16(565) 16(565) 16(565) 16(565) 16(565)
+ * 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555)
+ * 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555)
+ * 1000 18(666) 18(666) 18(666) 18(666) 18(666)
+ * 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665)
+ * 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666)
+ * 1011 24(888) 24(888) 24(888) 24(888) 24(888)
+ * 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887)
+ * 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888)
+ * 1110 -none- -none- -none- -none- -none-
+ * 1111 -none- -none- -none- -none- -none-
+*/
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h
new file mode 100644
index 00000000000..0ef806e5034
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-fb.h
@@ -0,0 +1,366 @@
+/* arch/arm/plat-samsung/include/plat/regs-fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards into the S3C2416, S3C2450 and the
+ * S3C64XX series such as the S3C6400 and S3C6410.
+ *
+ * The file does not contain the cpu specific items which are based on
+ * whichever architecture is selected, it only contains the core of the
+ * register set. See <mach/regs-fb.h> to get the specifics.
+ *
+ * Note, we changed to using regs-fb.h as it avoids any clashes with
+ * the original regs-lcd.h so out of the way of regs-lcd.h as well as
+ * indicating the newer block is much more than just an LCD interface.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Please do not include this file directly, use <mach/regs-fb.h> to
+ * ensure all the localised SoC support is included as necessary.
+*/
+
+/* VIDCON0 */
+
+#define VIDCON0 (0x00)
+#define VIDCON0_INTERLACE (1 << 29)
+#define VIDCON0_VIDOUT_MASK (0x3 << 26)
+#define VIDCON0_VIDOUT_SHIFT (26)
+#define VIDCON0_VIDOUT_RGB (0x0 << 26)
+#define VIDCON0_VIDOUT_TV (0x1 << 26)
+#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26)
+#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26)
+
+#define VIDCON0_L1_DATA_MASK (0x7 << 23)
+#define VIDCON0_L1_DATA_SHIFT (23)
+#define VIDCON0_L1_DATA_16BPP (0x0 << 23)
+#define VIDCON0_L1_DATA_18BPP16 (0x1 << 23)
+#define VIDCON0_L1_DATA_18BPP9 (0x2 << 23)
+#define VIDCON0_L1_DATA_24BPP (0x3 << 23)
+#define VIDCON0_L1_DATA_18BPP (0x4 << 23)
+#define VIDCON0_L1_DATA_16BPP8 (0x5 << 23)
+
+#define VIDCON0_L0_DATA_MASK (0x7 << 20)
+#define VIDCON0_L0_DATA_SHIFT (20)
+#define VIDCON0_L0_DATA_16BPP (0x0 << 20)
+#define VIDCON0_L0_DATA_18BPP16 (0x1 << 20)
+#define VIDCON0_L0_DATA_18BPP9 (0x2 << 20)
+#define VIDCON0_L0_DATA_24BPP (0x3 << 20)
+#define VIDCON0_L0_DATA_18BPP (0x4 << 20)
+#define VIDCON0_L0_DATA_16BPP8 (0x5 << 20)
+
+#define VIDCON0_PNRMODE_MASK (0x3 << 17)
+#define VIDCON0_PNRMODE_SHIFT (17)
+#define VIDCON0_PNRMODE_RGB (0x0 << 17)
+#define VIDCON0_PNRMODE_BGR (0x1 << 17)
+#define VIDCON0_PNRMODE_SERIAL_RGB (0x2 << 17)
+#define VIDCON0_PNRMODE_SERIAL_BGR (0x3 << 17)
+
+#define VIDCON0_CLKVALUP (1 << 16)
+#define VIDCON0_CLKVAL_F_MASK (0xff << 6)
+#define VIDCON0_CLKVAL_F_SHIFT (6)
+#define VIDCON0_CLKVAL_F_LIMIT (0xff)
+#define VIDCON0_CLKVAL_F(_x) ((_x) << 6)
+#define VIDCON0_VLCKFREE (1 << 5)
+#define VIDCON0_CLKDIR (1 << 4)
+
+#define VIDCON0_CLKSEL_MASK (0x3 << 2)
+#define VIDCON0_CLKSEL_SHIFT (2)
+#define VIDCON0_CLKSEL_HCLK (0x0 << 2)
+#define VIDCON0_CLKSEL_LCD (0x1 << 2)
+#define VIDCON0_CLKSEL_27M (0x3 << 2)
+
+#define VIDCON0_ENVID (1 << 1)
+#define VIDCON0_ENVID_F (1 << 0)
+
+#define VIDCON1 (0x04)
+#define VIDCON1_LINECNT_MASK (0x7ff << 16)
+#define VIDCON1_LINECNT_SHIFT (16)
+#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff)
+#define VIDCON1_VSTATUS_MASK (0x3 << 13)
+#define VIDCON1_VSTATUS_SHIFT (13)
+#define VIDCON1_VSTATUS_VSYNC (0x0 << 13)
+#define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13)
+#define VIDCON1_VSTATUS_ACTIVE (0x2 << 13)
+#define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13)
+
+#define VIDCON1_INV_VCLK (1 << 7)
+#define VIDCON1_INV_HSYNC (1 << 6)
+#define VIDCON1_INV_VSYNC (1 << 5)
+#define VIDCON1_INV_VDEN (1 << 4)
+
+/* VIDCON2 */
+
+#define VIDCON2 (0x08)
+#define VIDCON2_EN601 (1 << 23)
+#define VIDCON2_TVFMTSEL_SW (1 << 14)
+
+#define VIDCON2_TVFMTSEL1_MASK (0x3 << 12)
+#define VIDCON2_TVFMTSEL1_SHIFT (12)
+#define VIDCON2_TVFMTSEL1_RGB (0x0 << 12)
+#define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12)
+#define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12)
+
+#define VIDCON2_ORGYCbCr (1 << 8)
+#define VIDCON2_YUVORDCrCb (1 << 7)
+
+/* VIDTCON0 */
+
+#define VIDTCON0_VBPDE_MASK (0xff << 24)
+#define VIDTCON0_VBPDE_SHIFT (24)
+#define VIDTCON0_VBPDE_LIMIT (0xff)
+#define VIDTCON0_VBPDE(_x) ((_x) << 24)
+
+#define VIDTCON0_VBPD_MASK (0xff << 16)
+#define VIDTCON0_VBPD_SHIFT (16)
+#define VIDTCON0_VBPD_LIMIT (0xff)
+#define VIDTCON0_VBPD(_x) ((_x) << 16)
+
+#define VIDTCON0_VFPD_MASK (0xff << 8)
+#define VIDTCON0_VFPD_SHIFT (8)
+#define VIDTCON0_VFPD_LIMIT (0xff)
+#define VIDTCON0_VFPD(_x) ((_x) << 8)
+
+#define VIDTCON0_VSPW_MASK (0xff << 0)
+#define VIDTCON0_VSPW_SHIFT (0)
+#define VIDTCON0_VSPW_LIMIT (0xff)
+#define VIDTCON0_VSPW(_x) ((_x) << 0)
+
+/* VIDTCON1 */
+
+#define VIDTCON1_VFPDE_MASK (0xff << 24)
+#define VIDTCON1_VFPDE_SHIFT (24)
+#define VIDTCON1_VFPDE_LIMIT (0xff)
+#define VIDTCON1_VFPDE(_x) ((_x) << 24)
+
+#define VIDTCON1_HBPD_MASK (0xff << 16)
+#define VIDTCON1_HBPD_SHIFT (16)
+#define VIDTCON1_HBPD_LIMIT (0xff)
+#define VIDTCON1_HBPD(_x) ((_x) << 16)
+
+#define VIDTCON1_HFPD_MASK (0xff << 8)
+#define VIDTCON1_HFPD_SHIFT (8)
+#define VIDTCON1_HFPD_LIMIT (0xff)
+#define VIDTCON1_HFPD(_x) ((_x) << 8)
+
+#define VIDTCON1_HSPW_MASK (0xff << 0)
+#define VIDTCON1_HSPW_SHIFT (0)
+#define VIDTCON1_HSPW_LIMIT (0xff)
+#define VIDTCON1_HSPW(_x) ((_x) << 0)
+
+#define VIDTCON2 (0x18)
+#define VIDTCON2_LINEVAL_MASK (0x7ff << 11)
+#define VIDTCON2_LINEVAL_SHIFT (11)
+#define VIDTCON2_LINEVAL_LIMIT (0x7ff)
+#define VIDTCON2_LINEVAL(_x) ((_x) << 11)
+
+#define VIDTCON2_HOZVAL_MASK (0x7ff << 0)
+#define VIDTCON2_HOZVAL_SHIFT (0)
+#define VIDTCON2_HOZVAL_LIMIT (0x7ff)
+#define VIDTCON2_HOZVAL(_x) ((_x) << 0)
+
+/* WINCONx */
+
+
+#define WINCONx_BITSWP (1 << 18)
+#define WINCONx_BYTSWP (1 << 17)
+#define WINCONx_HAWSWP (1 << 16)
+#define WINCONx_BURSTLEN_MASK (0x3 << 9)
+#define WINCONx_BURSTLEN_SHIFT (9)
+#define WINCONx_BURSTLEN_16WORD (0x0 << 9)
+#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
+#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
+
+#define WINCONx_ENWIN (1 << 0)
+#define WINCON0_BPPMODE_MASK (0xf << 2)
+#define WINCON0_BPPMODE_SHIFT (2)
+#define WINCON0_BPPMODE_1BPP (0x0 << 2)
+#define WINCON0_BPPMODE_2BPP (0x1 << 2)
+#define WINCON0_BPPMODE_4BPP (0x2 << 2)
+#define WINCON0_BPPMODE_8BPP_PALETTE (0x3 << 2)
+#define WINCON0_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON0_BPPMODE_16BPP_1555 (0x7 << 2)
+#define WINCON0_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
+
+#define WINCON1_BLD_PIX (1 << 6)
+
+#define WINCON1_ALPHA_SEL (1 << 1)
+#define WINCON1_BPPMODE_MASK (0xf << 2)
+#define WINCON1_BPPMODE_SHIFT (2)
+#define WINCON1_BPPMODE_1BPP (0x0 << 2)
+#define WINCON1_BPPMODE_2BPP (0x1 << 2)
+#define WINCON1_BPPMODE_4BPP (0x2 << 2)
+#define WINCON1_BPPMODE_8BPP_PALETTE (0x3 << 2)
+#define WINCON1_BPPMODE_8BPP_1232 (0x4 << 2)
+#define WINCON1_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON1_BPPMODE_16BPP_A1555 (0x6 << 2)
+#define WINCON1_BPPMODE_16BPP_I1555 (0x7 << 2)
+#define WINCON1_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON1_BPPMODE_18BPP_A1665 (0x9 << 2)
+#define WINCON1_BPPMODE_19BPP_A1666 (0xa << 2)
+#define WINCON1_BPPMODE_24BPP_888 (0xb << 2)
+#define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2)
+#define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2)
+#define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2)
+
+
+#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11)
+#define VIDOSDxA_TOPLEFT_X_SHIFT (11)
+#define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff)
+#define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11)
+
+#define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0)
+#define VIDOSDxA_TOPLEFT_Y_SHIFT (0)
+#define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff)
+#define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0)
+
+#define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11)
+#define VIDOSDxB_BOTRIGHT_X_SHIFT (11)
+#define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff)
+#define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11)
+
+#define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0)
+#define VIDOSDxB_BOTRIGHT_Y_SHIFT (0)
+#define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff)
+#define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0)
+
+/* For VIDOSD[1..4]C */
+#define VIDISD14C_ALPHA0_R(_x) ((_x) << 20)
+#define VIDISD14C_ALPHA0_G_MASK (0xf << 16)
+#define VIDISD14C_ALPHA0_G_SHIFT (16)
+#define VIDISD14C_ALPHA0_G_LIMIT (0xf)
+#define VIDISD14C_ALPHA0_G(_x) ((_x) << 16)
+#define VIDISD14C_ALPHA0_B_MASK (0xf << 12)
+#define VIDISD14C_ALPHA0_B_SHIFT (12)
+#define VIDISD14C_ALPHA0_B_LIMIT (0xf)
+#define VIDISD14C_ALPHA0_B(_x) ((_x) << 12)
+#define VIDISD14C_ALPHA1_R_MASK (0xf << 8)
+#define VIDISD14C_ALPHA1_R_SHIFT (8)
+#define VIDISD14C_ALPHA1_R_LIMIT (0xf)
+#define VIDISD14C_ALPHA1_R(_x) ((_x) << 8)
+#define VIDISD14C_ALPHA1_G_MASK (0xf << 4)
+#define VIDISD14C_ALPHA1_G_SHIFT (4)
+#define VIDISD14C_ALPHA1_G_LIMIT (0xf)
+#define VIDISD14C_ALPHA1_G(_x) ((_x) << 4)
+#define VIDISD14C_ALPHA1_B_MASK (0xf << 0)
+#define VIDISD14C_ALPHA1_B_SHIFT (0)
+#define VIDISD14C_ALPHA1_B_LIMIT (0xf)
+#define VIDISD14C_ALPHA1_B(_x) ((_x) << 0)
+
+/* Video buffer addresses */
+#define VIDW_BUF_START(_buff) (0xA0 + ((_buff) * 8))
+#define VIDW_BUF_START1(_buff) (0xA4 + ((_buff) * 8))
+#define VIDW_BUF_END(_buff) (0xD0 + ((_buff) * 8))
+#define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8))
+#define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4))
+
+#define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13)
+#define VIDW_BUF_SIZE_OFFSET_SHIFT (13)
+#define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff)
+#define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13)
+
+#define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0)
+#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0)
+#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff)
+#define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0)
+
+/* Interrupt controls and status */
+
+#define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20)
+#define VIDINTCON0_FIFOINTERVAL_SHIFT (20)
+#define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f)
+#define VIDINTCON0_FIFOINTERVAL(_x) ((_x) << 20)
+
+#define VIDINTCON0_INT_SYSMAINCON (1 << 19)
+#define VIDINTCON0_INT_SYSSUBCON (1 << 18)
+#define VIDINTCON0_INT_I80IFDONE (1 << 17)
+
+#define VIDINTCON0_FRAMESEL0_MASK (0x3 << 15)
+#define VIDINTCON0_FRAMESEL0_SHIFT (15)
+#define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15)
+#define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15)
+#define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15)
+#define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15)
+
+#define VIDINTCON0_FRAMESEL1 (1 << 14)
+#define VIDINTCON0_FRAMESEL1_NONE (0x0 << 14)
+#define VIDINTCON0_FRAMESEL1_BACKPORCH (0x1 << 14)
+#define VIDINTCON0_FRAMESEL1_VSYNC (0x2 << 14)
+#define VIDINTCON0_FRAMESEL1_FRONTPORCH (0x3 << 14)
+
+#define VIDINTCON0_INT_FRAME (1 << 12)
+#define VIDINTCON0_FIFIOSEL_MASK (0x7f << 5)
+#define VIDINTCON0_FIFIOSEL_SHIFT (5)
+#define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5)
+
+#define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2)
+#define VIDINTCON0_FIFOLEVEL_SHIFT (2)
+#define VIDINTCON0_FIFOLEVEL_TO25PC (0x0 << 2)
+#define VIDINTCON0_FIFOLEVEL_TO50PC (0x1 << 2)
+#define VIDINTCON0_FIFOLEVEL_TO75PC (0x2 << 2)
+#define VIDINTCON0_FIFOLEVEL_EMPTY (0x3 << 2)
+#define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 2)
+
+#define VIDINTCON0_INT_FIFO_MASK (0x3 << 0)
+#define VIDINTCON0_INT_FIFO_SHIFT (0)
+#define VIDINTCON0_INT_ENABLE (1 << 0)
+
+#define VIDINTCON1 (0x134)
+#define VIDINTCON1_INT_I180 (1 << 2)
+#define VIDINTCON1_INT_FRAME (1 << 1)
+#define VIDINTCON1_INT_FIFO (1 << 0)
+
+/* Window colour-key control registers */
+
+#define WxKEYCON0_KEYBL_EN (1 << 26)
+#define WxKEYCON0_KEYEN_F (1 << 25)
+#define WxKEYCON0_DIRCON (1 << 24)
+#define WxKEYCON0_COMPKEY_MASK (0xffffff << 0)
+#define WxKEYCON0_COMPKEY_SHIFT (0)
+#define WxKEYCON0_COMPKEY_LIMIT (0xffffff)
+#define WxKEYCON0_COMPKEY(_x) ((_x) << 0)
+#define WxKEYCON1_COLVAL_MASK (0xffffff << 0)
+#define WxKEYCON1_COLVAL_SHIFT (0)
+#define WxKEYCON1_COLVAL_LIMIT (0xffffff)
+#define WxKEYCON1_COLVAL(_x) ((_x) << 0)
+
+
+/* Window blanking (MAP) */
+
+#define WINxMAP_MAP (1 << 24)
+#define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0)
+#define WINxMAP_MAP_COLOUR_SHIFT (0)
+#define WINxMAP_MAP_COLOUR_LIMIT (0xffffff)
+#define WINxMAP_MAP_COLOUR(_x) ((_x) << 0)
+
+#define WPALCON_PAL_UPDATE (1 << 9)
+#define WPALCON_W1PAL_MASK (0x7 << 3)
+#define WPALCON_W1PAL_SHIFT (3)
+#define WPALCON_W1PAL_25BPP_A888 (0x0 << 3)
+#define WPALCON_W1PAL_24BPP (0x1 << 3)
+#define WPALCON_W1PAL_19BPP_A666 (0x2 << 3)
+#define WPALCON_W1PAL_18BPP_A665 (0x3 << 3)
+#define WPALCON_W1PAL_18BPP (0x4 << 3)
+#define WPALCON_W1PAL_16BPP_A555 (0x5 << 3)
+#define WPALCON_W1PAL_16BPP_565 (0x6 << 3)
+
+#define WPALCON_W0PAL_MASK (0x7 << 0)
+#define WPALCON_W0PAL_SHIFT (0)
+#define WPALCON_W0PAL_25BPP_A888 (0x0 << 0)
+#define WPALCON_W0PAL_24BPP (0x1 << 0)
+#define WPALCON_W0PAL_19BPP_A666 (0x2 << 0)
+#define WPALCON_W0PAL_18BPP_A665 (0x3 << 0)
+#define WPALCON_W0PAL_18BPP (0x4 << 0)
+#define WPALCON_W0PAL_16BPP_A555 (0x5 << 0)
+#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
+
diff --git a/arch/arm/plat-s3c/include/plat/regs-iic.h b/arch/arm/plat-samsung/include/plat/regs-iic.h
index 2f7c17de8ac..2f7c17de8ac 100644
--- a/arch/arm/plat-s3c/include/plat/regs-iic.h
+++ b/arch/arm/plat-samsung/include/plat/regs-iic.h
diff --git a/arch/arm/plat-s3c/include/plat/regs-irqtype.h b/arch/arm/plat-samsung/include/plat/regs-irqtype.h
index c63cd3fc5ad..c63cd3fc5ad 100644
--- a/arch/arm/plat-s3c/include/plat/regs-irqtype.h
+++ b/arch/arm/plat-samsung/include/plat/regs-irqtype.h
diff --git a/arch/arm/plat-s3c/include/plat/regs-nand.h b/arch/arm/plat-samsung/include/plat/regs-nand.h
index 238efea7b9e..238efea7b9e 100644
--- a/arch/arm/plat-s3c/include/plat/regs-nand.h
+++ b/arch/arm/plat-samsung/include/plat/regs-nand.h
diff --git a/arch/arm/plat-s3c/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h
index d5837cf8e40..d5837cf8e40 100644
--- a/arch/arm/plat-s3c/include/plat/regs-rtc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h
diff --git a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h b/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h
index abf2fbc2eb2..abf2fbc2eb2 100644
--- a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
+++ b/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h
diff --git a/arch/arm/plat-s3c/include/plat/regs-sdhci.h b/arch/arm/plat-samsung/include/plat/regs-sdhci.h
index e34049ad44c..e34049ad44c 100644
--- a/arch/arm/plat-s3c/include/plat/regs-sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/regs-sdhci.h
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
new file mode 100644
index 00000000000..a6eba8496b2
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -0,0 +1,281 @@
+/* arch/arm/plat-samsung/include/plat/regs-serial.h
+ *
+ * From linux/include/asm-arm/hardware/serial_s3c2410.h
+ *
+ * Internal header file for Samsung S3C2410 serial ports (UART0-2)
+ *
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk)
+ *
+ * Adapted from:
+ *
+ * Internal header file for MX1ADS serial ports (UART1 & 2)
+ *
+ * Copyright (C) 2002 Shane Nay (shane@minirl.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
+*/
+
+#ifndef __ASM_ARM_REGS_SERIAL_H
+#define __ASM_ARM_REGS_SERIAL_H
+
+#define S3C24XX_VA_UART0 (S3C_VA_UART)
+#define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 )
+#define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 )
+#define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 )
+
+#define S3C2410_PA_UART0 (S3C24XX_PA_UART)
+#define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 )
+#define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 )
+#define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 )
+
+#define S3C2410_URXH (0x24)
+#define S3C2410_UTXH (0x20)
+#define S3C2410_ULCON (0x00)
+#define S3C2410_UCON (0x04)
+#define S3C2410_UFCON (0x08)
+#define S3C2410_UMCON (0x0C)
+#define S3C2410_UBRDIV (0x28)
+#define S3C2410_UTRSTAT (0x10)
+#define S3C2410_UERSTAT (0x14)
+#define S3C2410_UFSTAT (0x18)
+#define S3C2410_UMSTAT (0x1C)
+
+#define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3))
+
+#define S3C2410_LCON_CS5 (0x0)
+#define S3C2410_LCON_CS6 (0x1)
+#define S3C2410_LCON_CS7 (0x2)
+#define S3C2410_LCON_CS8 (0x3)
+#define S3C2410_LCON_CSMASK (0x3)
+
+#define S3C2410_LCON_PNONE (0x0)
+#define S3C2410_LCON_PEVEN (0x5 << 3)
+#define S3C2410_LCON_PODD (0x4 << 3)
+#define S3C2410_LCON_PMASK (0x7 << 3)
+
+#define S3C2410_LCON_STOPB (1<<2)
+#define S3C2410_LCON_IRM (1<<6)
+
+#define S3C2440_UCON_CLKMASK (3<<10)
+#define S3C2440_UCON_PCLK (0<<10)
+#define S3C2440_UCON_UCLK (1<<10)
+#define S3C2440_UCON_PCLK2 (2<<10)
+#define S3C2440_UCON_FCLK (3<<10)
+#define S3C2443_UCON_EPLL (3<<10)
+
+#define S3C6400_UCON_CLKMASK (3<<10)
+#define S3C6400_UCON_PCLK (0<<10)
+#define S3C6400_UCON_PCLK2 (2<<10)
+#define S3C6400_UCON_UCLK0 (1<<10)
+#define S3C6400_UCON_UCLK1 (3<<10)
+
+#define S3C2440_UCON2_FCLK_EN (1<<15)
+#define S3C2440_UCON0_DIVMASK (15 << 12)
+#define S3C2440_UCON1_DIVMASK (15 << 12)
+#define S3C2440_UCON2_DIVMASK (7 << 12)
+#define S3C2440_UCON_DIVSHIFT (12)
+
+#define S3C2412_UCON_CLKMASK (3<<10)
+#define S3C2412_UCON_UCLK (1<<10)
+#define S3C2412_UCON_USYSCLK (3<<10)
+#define S3C2412_UCON_PCLK (0<<10)
+#define S3C2412_UCON_PCLK2 (2<<10)
+
+#define S3C2410_UCON_UCLK (1<<10)
+#define S3C2410_UCON_SBREAK (1<<4)
+
+#define S3C2410_UCON_TXILEVEL (1<<9)
+#define S3C2410_UCON_RXILEVEL (1<<8)
+#define S3C2410_UCON_TXIRQMODE (1<<2)
+#define S3C2410_UCON_RXIRQMODE (1<<0)
+#define S3C2410_UCON_RXFIFO_TOI (1<<7)
+#define S3C2443_UCON_RXERR_IRQEN (1<<6)
+#define S3C2443_UCON_LOOPBACK (1<<5)
+
+#define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI)
+
+#define S3C2410_UFCON_FIFOMODE (1<<0)
+#define S3C2410_UFCON_TXTRIG0 (0<<6)
+#define S3C2410_UFCON_RXTRIG8 (1<<4)
+#define S3C2410_UFCON_RXTRIG12 (2<<4)
+
+/* S3C2440 FIFO trigger levels */
+#define S3C2440_UFCON_RXTRIG1 (0<<4)
+#define S3C2440_UFCON_RXTRIG8 (1<<4)
+#define S3C2440_UFCON_RXTRIG16 (2<<4)
+#define S3C2440_UFCON_RXTRIG32 (3<<4)
+
+#define S3C2440_UFCON_TXTRIG0 (0<<6)
+#define S3C2440_UFCON_TXTRIG16 (1<<6)
+#define S3C2440_UFCON_TXTRIG32 (2<<6)
+#define S3C2440_UFCON_TXTRIG48 (3<<6)
+
+#define S3C2410_UFCON_RESETBOTH (3<<1)
+#define S3C2410_UFCON_RESETTX (1<<2)
+#define S3C2410_UFCON_RESETRX (1<<1)
+
+#define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S3C2410_UFCON_TXTRIG0 | \
+ S3C2410_UFCON_RXTRIG8 )
+
+#define S3C2410_UMCOM_AFC (1<<4)
+#define S3C2410_UMCOM_RTS_LOW (1<<0)
+
+#define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */
+#define S3C2412_UMCON_AFC_56 (1<<5)
+#define S3C2412_UMCON_AFC_48 (2<<5)
+#define S3C2412_UMCON_AFC_40 (3<<5)
+#define S3C2412_UMCON_AFC_32 (4<<5)
+#define S3C2412_UMCON_AFC_24 (5<<5)
+#define S3C2412_UMCON_AFC_16 (6<<5)
+#define S3C2412_UMCON_AFC_8 (7<<5)
+
+#define S3C2410_UFSTAT_TXFULL (1<<9)
+#define S3C2410_UFSTAT_RXFULL (1<<8)
+#define S3C2410_UFSTAT_TXMASK (15<<4)
+#define S3C2410_UFSTAT_TXSHIFT (4)
+#define S3C2410_UFSTAT_RXMASK (15<<0)
+#define S3C2410_UFSTAT_RXSHIFT (0)
+
+/* UFSTAT S3C24A0 */
+#define S3C24A0_UFSTAT_TXFULL (1 << 14)
+#define S3C24A0_UFSTAT_RXFULL (1 << 6)
+#define S3C24A0_UFSTAT_TXMASK (63 << 8)
+#define S3C24A0_UFSTAT_TXSHIFT (8)
+#define S3C24A0_UFSTAT_RXMASK (63)
+#define S3C24A0_UFSTAT_RXSHIFT (0)
+
+/* UFSTAT S3C2443 same as S3C2440 */
+#define S3C2440_UFSTAT_TXFULL (1<<14)
+#define S3C2440_UFSTAT_RXFULL (1<<6)
+#define S3C2440_UFSTAT_TXSHIFT (8)
+#define S3C2440_UFSTAT_RXSHIFT (0)
+#define S3C2440_UFSTAT_TXMASK (63<<8)
+#define S3C2440_UFSTAT_RXMASK (63)
+
+#define S3C2410_UTRSTAT_TXE (1<<2)
+#define S3C2410_UTRSTAT_TXFE (1<<1)
+#define S3C2410_UTRSTAT_RXDR (1<<0)
+
+#define S3C2410_UERSTAT_OVERRUN (1<<0)
+#define S3C2410_UERSTAT_FRAME (1<<2)
+#define S3C2410_UERSTAT_BREAK (1<<3)
+#define S3C2443_UERSTAT_PARITY (1<<1)
+
+#define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \
+ S3C2410_UERSTAT_FRAME | \
+ S3C2410_UERSTAT_BREAK)
+
+#define S3C2410_UMSTAT_CTS (1<<0)
+#define S3C2410_UMSTAT_DeltaCTS (1<<2)
+
+#define S3C2443_DIVSLOT (0x2C)
+
+/* S3C64XX interrupt registers. */
+#define S3C64XX_UINTP 0x30
+#define S3C64XX_UINTSP 0x34
+#define S3C64XX_UINTM 0x38
+
+/* Following are specific to S5PV210 and S5P6442 */
+#define S5PV210_UCON_CLKMASK (1<<10)
+#define S5PV210_UCON_PCLK (0<<10)
+#define S5PV210_UCON_UCLK (1<<10)
+
+#define S5PV210_UFCON_TXTRIG0 (0<<8)
+#define S5PV210_UFCON_TXTRIG4 (1<<8)
+#define S5PV210_UFCON_TXTRIG8 (2<<8)
+#define S5PV210_UFCON_TXTRIG16 (3<<8)
+#define S5PV210_UFCON_TXTRIG32 (4<<8)
+#define S5PV210_UFCON_TXTRIG64 (5<<8)
+#define S5PV210_UFCON_TXTRIG128 (6<<8)
+#define S5PV210_UFCON_TXTRIG256 (7<<8)
+
+#define S5PV210_UFCON_RXTRIG1 (0<<4)
+#define S5PV210_UFCON_RXTRIG4 (1<<4)
+#define S5PV210_UFCON_RXTRIG8 (2<<4)
+#define S5PV210_UFCON_RXTRIG16 (3<<4)
+#define S5PV210_UFCON_RXTRIG32 (4<<4)
+#define S5PV210_UFCON_RXTRIG64 (5<<4)
+#define S5PV210_UFCON_RXTRIG128 (6<<4)
+#define S5PV210_UFCON_RXTRIG256 (7<<4)
+
+#define S5PV210_UFSTAT_TXFULL (1<<24)
+#define S5PV210_UFSTAT_RXFULL (1<<8)
+#define S5PV210_UFSTAT_TXMASK (255<<16)
+#define S5PV210_UFSTAT_TXSHIFT (16)
+#define S5PV210_UFSTAT_RXMASK (255<<0)
+#define S5PV210_UFSTAT_RXSHIFT (0)
+
+#ifndef __ASSEMBLY__
+
+/* struct s3c24xx_uart_clksrc
+ *
+ * this structure defines a named clock source that can be used for the
+ * uart, so that the best clock can be selected for the requested baud
+ * rate.
+ *
+ * min_baud and max_baud define the range of baud-rates this clock is
+ * acceptable for, if they are both zero, it is assumed any baud rate that
+ * can be generated from this clock will be used.
+ *
+ * divisor gives the divisor from the clock to the one seen by the uart
+*/
+
+struct s3c24xx_uart_clksrc {
+ const char *name;
+ unsigned int divisor;
+ unsigned int min_baud;
+ unsigned int max_baud;
+};
+
+/* configuration structure for per-machine configurations for the
+ * serial port
+ *
+ * the pointer is setup by the machine specific initialisation from the
+ * arch/arm/mach-s3c2410/ directory.
+*/
+
+struct s3c2410_uartcfg {
+ unsigned char hwport; /* hardware port number */
+ unsigned char unused;
+ unsigned short flags;
+ upf_t uart_flags; /* default uart flags */
+
+ unsigned long ucon; /* value of ucon for port */
+ unsigned long ulcon; /* value of ulcon for port */
+ unsigned long ufcon; /* value of ufcon for port */
+
+ struct s3c24xx_uart_clksrc *clocks;
+ unsigned int clocks_size;
+};
+
+/* s3c24xx_uart_devs
+ *
+ * this is exported from the core as we cannot use driver_register(),
+ * or platform_add_device() before the console_initcall()
+*/
+
+extern struct platform_device *s3c24xx_uart_devs[4];
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ARM_REGS_SERIAL_H */
+
diff --git a/arch/arm/plat-s3c/include/plat/regs-timer.h b/arch/arm/plat-samsung/include/plat/regs-timer.h
index d097d92f8cc..d097d92f8cc 100644
--- a/arch/arm/plat-s3c/include/plat/regs-timer.h
+++ b/arch/arm/plat-samsung/include/plat/regs-timer.h
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
new file mode 100644
index 00000000000..a111ad87183
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
@@ -0,0 +1,50 @@
+/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - USB2.0 Highspeed/OtG device PHY registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Note, this is a separate header file as some of the clock framework
+ * needs to touch this if the clk_48m is used as the USB OHCI or other
+ * peripheral source.
+*/
+
+#ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H
+#define __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H __FILE__
+
+/* S3C64XX_PA_USB_HSPHY */
+
+#define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY)
+
+#define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00)
+#define SRC_PHYPWR_OTG_DISABLE (1 << 4)
+#define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3)
+#define SRC_PHYPWR_FORCE_SUSPEND (1 << 1)
+
+#define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04)
+#define S3C_PHYCLK_MODE_USB11 (1 << 6)
+#define S3C_PHYCLK_EXT_OSC (1 << 5)
+#define S3C_PHYCLK_CLK_FORCE (1 << 4)
+#define S3C_PHYCLK_ID_PULL (1 << 2)
+#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
+#define S3C_PHYCLK_CLKSEL_SHIFT (0)
+#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
+#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
+#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
+
+#define S3C_RSTCON S3C_HSOTG_PHYREG(0x08)
+#define S3C_RSTCON_PHYCLK (1 << 2)
+#define S3C_RSTCON_HCLK (1 << 2)
+#define S3C_RSTCON_PHY (1 << 0)
+
+#define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20)
+
+#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H */
diff --git a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
index 8d18d9d4d14..8d18d9d4d14 100644
--- a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
+++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
diff --git a/arch/arm/plat-s3c/include/plat/regs-watchdog.h b/arch/arm/plat-samsung/include/plat/regs-watchdog.h
index 4938492470f..4938492470f 100644
--- a/arch/arm/plat-s3c/include/plat/regs-watchdog.h
+++ b/arch/arm/plat-samsung/include/plat/regs-watchdog.h
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
new file mode 100644
index 00000000000..d1772414931
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+ *
+ * Copyright (C) 2009 Samsung Electronics Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __S3C64XX_PLAT_SPI_H
+#define __S3C64XX_PLAT_SPI_H
+
+/**
+ * struct s3c64xx_spi_csinfo - ChipSelect description
+ * @fb_delay: Slave specific feedback delay.
+ * Refer to FB_CLK_SEL register definition in SPI chapter.
+ * @line: Custom 'identity' of the CS line.
+ * @set_level: CS line control.
+ *
+ * This is per SPI-Slave Chipselect information.
+ * Allocate and initialize one in machine init code and make the
+ * spi_board_info.controller_data point to it.
+ */
+struct s3c64xx_spi_csinfo {
+ u8 fb_delay;
+ unsigned line;
+ void (*set_level)(unsigned line_id, int lvl);
+};
+
+/**
+ * struct s3c64xx_spi_info - SPI Controller defining structure
+ * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
+ * @src_clk_name: Platform name of the corresponding clock.
+ * @num_cs: Number of CS this controller emulates.
+ * @cfg_gpio: Configure pins for this SPI controller.
+ * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
+ * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number
+ * @high_speed: If the controller supports HIGH_SPEED_EN bit
+ */
+struct s3c64xx_spi_info {
+ int src_clk_nr;
+ char *src_clk_name;
+
+ int num_cs;
+
+ int (*cfg_gpio)(struct platform_device *pdev);
+
+ /* Following two fields are for future compatibility */
+ int fifo_lvl_mask;
+ int rx_lvl_offset;
+ int high_speed;
+};
+
+/**
+ * s3c64xx_spi_set_info - SPI Controller configure callback by the board
+ * initialization code.
+ * @cntrlr: SPI controller number the configuration is for.
+ * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
+ * @num_cs: Number of elements in the 'cs' array.
+ *
+ * Call this from machine init code for each SPI Controller that
+ * has some chips attached to it.
+ */
+extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
+
+#endif /* __S3C64XX_PLAT_SPI_H */
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
new file mode 100644
index 00000000000..7d07cd7aa4f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -0,0 +1,221 @@
+/* linux/arch/arm/plat-s3c/include/plat/sdhci.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - SDHCI (HSMMC) platform data definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S3C_SDHCI_H
+#define __PLAT_S3C_SDHCI_H __FILE__
+
+struct platform_device;
+struct mmc_host;
+struct mmc_card;
+struct mmc_ios;
+
+/**
+ * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
+ * @max_width: The maximum number of data bits supported.
+ * @host_caps: Standard MMC host capabilities bit field.
+ * @cfg_gpio: Configure the GPIO for a specific card bit-width
+ * @cfg_card: Configure the interface for a specific card and speed. This
+ * is necessary the controllers and/or GPIO blocks require the
+ * changing of driver-strength and other controls dependant on
+ * the card and speed of operation.
+ *
+ * Initialisation data specific to either the machine or the platform
+ * for the device driver to use or call-back when configuring gpio or
+ * card speed information.
+*/
+struct s3c_sdhci_platdata {
+ unsigned int max_width;
+ unsigned int host_caps;
+
+ char **clocks; /* set of clock sources */
+
+ void (*cfg_gpio)(struct platform_device *dev, int width);
+ void (*cfg_card)(struct platform_device *dev,
+ void __iomem *regbase,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+};
+
+/**
+ * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use withe S3C SDHCI device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+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);
+
+/* Default platform data, exported so that per-cpu initialisation can
+ * set the correct one when there are more than one cpu type selected.
+*/
+
+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;
+
+/* Helper function availablity */
+
+extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+
+/* S3C6400 SDHCI setup */
+
+#ifdef CONFIG_S3C64XX_SETUP_SDHCI
+extern char *s3c64xx_hsmmc_clksrcs[4];
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s3c6400_default_sdhci0(void)
+{
+ s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+}
+
+#else
+static inline void s3c6400_default_sdhci0(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s3c6400_default_sdhci1(void)
+{
+ s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6400_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s3c6400_default_sdhci2(void)
+{
+ s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6400_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC2 */
+
+/* S3C6410 SDHCI setup */
+
+extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static inline void s3c6410_default_sdhci0(void)
+{
+ s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6410_default_sdhci0(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s3c6410_default_sdhci1(void)
+{
+ s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6410_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s3c6410_default_sdhci2(void)
+{
+ s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+}
+#else
+static inline void s3c6410_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC2 */
+
+#else
+static inline void s3c6410_default_sdhci0(void) { }
+static inline void s3c6410_default_sdhci1(void) { }
+static inline void s3c6400_default_sdhci0(void) { }
+static inline void s3c6400_default_sdhci1(void) { }
+
+#endif /* CONFIG_S3C64XX_SETUP_SDHCI */
+
+/* S5PC100 SDHCI setup */
+
+#ifdef CONFIG_S5PC100_SETUP_SDHCI
+extern char *s5pc100_hsmmc_clksrcs[4];
+
+extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static inline void s5pc100_default_sdhci0(void)
+{
+ s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s5pc100_default_sdhci1(void)
+{
+ s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s5pc100_default_sdhci2(void)
+{
+ s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+static inline void s5pc100_default_sdhci1(void) { }
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S5PC100_SETUP_SDHCI */
+
+#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h
new file mode 100644
index 00000000000..a22a4f2eea9
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/udc-hs.h
@@ -0,0 +1,29 @@
+/* arch/arm/plat-s3c/include/plat/udc-hs.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C USB2.0 High-speed / OtG platform information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+enum s3c_hsotg_dmamode {
+ S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */
+ S3C_HSOTG_DMA_ONLY, /* always use DMA */
+ S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */
+};
+
+/**
+ * struct s3c_hsotg_plat - platform data for high-speed otg/udc
+ * @dma: Whether to use DMA or not.
+ * @is_osc: The clock source is an oscillator, not a crystal
+ */
+struct s3c_hsotg_plat {
+ enum s3c_hsotg_dmamode dma;
+ unsigned int is_osc : 1;
+};
diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h
new file mode 100644
index 00000000000..7d6ed7263d5
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/uncompress.h
@@ -0,0 +1,184 @@
+/* arch/arm/plat-samsung/include/plat/uncompress.h
+ *
+ * Copyright 2003, 2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_UNCOMPRESS_H
+#define __ASM_PLAT_UNCOMPRESS_H
+
+typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
+
+/* uart setup */
+
+static unsigned int fifo_mask;
+static unsigned int fifo_max;
+
+/* forward declerations */
+
+static void arch_detect_cpu(void);
+
+/* defines for UART registers */
+
+#include <plat/regs-serial.h>
+#include <plat/regs-watchdog.h>
+
+/* working in physical space... */
+#undef S3C2410_WDOGREG
+#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
+
+/* how many bytes we allow into the FIFO at a time in FIFO mode */
+#define FIFO_MAX (14)
+
+#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
+
+static __inline__ void
+uart_wr(unsigned int reg, unsigned int val)
+{
+ volatile unsigned int *ptr;
+
+ ptr = (volatile unsigned int *)(reg + uart_base);
+ *ptr = val;
+}
+
+static __inline__ unsigned int
+uart_rd(unsigned int reg)
+{
+ volatile unsigned int *ptr;
+
+ ptr = (volatile unsigned int *)(reg + uart_base);
+ return *ptr;
+}
+
+/* we can deal with the case the UARTs are being run
+ * in FIFO mode, so that we don't hold up our execution
+ * waiting for tx to happen...
+*/
+
+static void putc(int ch)
+{
+ if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
+ int level;
+
+ while (1) {
+ level = uart_rd(S3C2410_UFSTAT);
+ level &= fifo_mask;
+
+ if (level < fifo_max)
+ break;
+ }
+
+ } else {
+ /* not using fifos */
+
+ while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
+ barrier();
+ }
+
+ /* write byte to transmission register */
+ uart_wr(S3C2410_UTXH, ch);
+}
+
+static inline void flush(void)
+{
+}
+
+#define __raw_writel(d, ad) \
+ do { \
+ *((volatile unsigned int __force *)(ad)) = (d); \
+ } while (0)
+
+/* CONFIG_S3C_BOOT_WATCHDOG
+ *
+ * Simple boot-time watchdog setup, to reboot the system if there is
+ * any problem with the boot process
+*/
+
+#ifdef CONFIG_S3C_BOOT_WATCHDOG
+
+#define WDOG_COUNT (0xff00)
+
+static inline void arch_decomp_wdog(void)
+{
+ __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+}
+
+static void arch_decomp_wdog_start(void)
+{
+ __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
+ __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
+}
+
+#else
+#define arch_decomp_wdog_start()
+#define arch_decomp_wdog()
+#endif
+
+#ifdef CONFIG_S3C_BOOT_ERROR_RESET
+
+static void arch_decomp_error(const char *x)
+{
+ putstr("\n\n");
+ putstr(x);
+ putstr("\n\n -- System resetting\n");
+
+ __raw_writel(0x4000, S3C2410_WTDAT);
+ __raw_writel(0x4000, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
+
+ while(1);
+}
+
+#define arch_error arch_decomp_error
+#endif
+
+#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
+static inline void arch_enable_uart_fifo(void)
+{
+ u32 fifocon = uart_rd(S3C2410_UFCON);
+
+ if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
+ fifocon |= S3C2410_UFCON_RESETBOTH;
+ uart_wr(S3C2410_UFCON, fifocon);
+
+ /* wait for fifo reset to complete */
+ while (1) {
+ fifocon = uart_rd(S3C2410_UFCON);
+ if (!(fifocon & S3C2410_UFCON_RESETBOTH))
+ break;
+ }
+ }
+}
+#else
+#define arch_enable_uart_fifo() do { } while(0)
+#endif
+
+
+static void
+arch_decomp_setup(void)
+{
+ /* we may need to setup the uart(s) here if we are not running
+ * on an BAST... the BAST will have left the uarts configured
+ * after calling linux.
+ */
+
+ arch_detect_cpu();
+ arch_decomp_wdog_start();
+
+ /* Enable the UART FIFOs if they where not enabled and our
+ * configuration says we should turn them on.
+ */
+
+ arch_enable_uart_fifo();
+}
+
+
+#endif /* __ASM_PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/plat-samsung/include/plat/usb-control.h b/arch/arm/plat-samsung/include/plat/usb-control.h
new file mode 100644
index 00000000000..7fa1fbefc3f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/usb-control.h
@@ -0,0 +1,43 @@
+/* arch/arm/plat-samsung/include/plat/usb-control.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - USB host port information
+ *
+ * This program is free software; you can 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_USBCONTROL_H
+#define __ASM_ARCH_USBCONTROL_H
+
+#define S3C_HCDFLG_USED (1)
+
+struct s3c2410_hcd_port {
+ unsigned char flags;
+ unsigned char power;
+ unsigned char oc_status;
+ unsigned char oc_changed;
+};
+
+struct s3c2410_hcd_info {
+ struct usb_hcd *hcd;
+ struct s3c2410_hcd_port port[2];
+
+ void (*power_control)(int port, int to);
+ void (*enable_oc)(struct s3c2410_hcd_info *, int on);
+ void (*report_oc)(struct s3c2410_hcd_info *, int ports);
+};
+
+static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports)
+{
+ if (info->report_oc != NULL) {
+ (info->report_oc)(info, ports);
+ }
+}
+
+extern void s3c_ohci_set_platdata(struct s3c2410_hcd_info *info);
+
+#endif /*__ASM_ARCH_USBCONTROL_H */
diff --git a/arch/arm/plat-s3c/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
index 54b762acb5a..54b762acb5a 100644
--- a/arch/arm/plat-s3c/include/plat/watchdog-reset.h
+++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
diff --git a/arch/arm/plat-s3c/init.c b/arch/arm/plat-samsung/init.c
index 6790edfaca6..6790edfaca6 100644
--- a/arch/arm/plat-s3c/init.c
+++ b/arch/arm/plat-samsung/init.c
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
new file mode 100644
index 00000000000..4f8c102674a
--- /dev/null
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -0,0 +1,143 @@
+/* arch/arm/plat-samsung/irq-uart.c
+ * originally part of arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Samsung- UART Interrupt handling
+ *
+ * This program is free software; you can 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/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <plat/irq-uart.h>
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+
+/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
+ * are consecutive when looking up the interrupt in the demux routines.
+ */
+
+static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
+{
+ struct s3c_uart_irq *uirq = get_irq_chip_data(irq);
+ return uirq->regs;
+}
+
+static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
+{
+ return irq & 3;
+}
+
+static void s3c_irq_uart_mask(unsigned int irq)
+{
+ void __iomem *regs = s3c_irq_uart_base(irq);
+ unsigned int bit = s3c_irq_uart_bit(irq);
+ u32 reg;
+
+ reg = __raw_readl(regs + S3C64XX_UINTM);
+ reg |= (1 << bit);
+ __raw_writel(reg, regs + S3C64XX_UINTM);
+}
+
+static void s3c_irq_uart_maskack(unsigned int irq)
+{
+ void __iomem *regs = s3c_irq_uart_base(irq);
+ unsigned int bit = s3c_irq_uart_bit(irq);
+ u32 reg;
+
+ reg = __raw_readl(regs + S3C64XX_UINTM);
+ reg |= (1 << bit);
+ __raw_writel(reg, regs + S3C64XX_UINTM);
+ __raw_writel(1 << bit, regs + S3C64XX_UINTP);
+}
+
+static void s3c_irq_uart_unmask(unsigned int irq)
+{
+ void __iomem *regs = s3c_irq_uart_base(irq);
+ unsigned int bit = s3c_irq_uart_bit(irq);
+ u32 reg;
+
+ reg = __raw_readl(regs + S3C64XX_UINTM);
+ reg &= ~(1 << bit);
+ __raw_writel(reg, regs + S3C64XX_UINTM);
+}
+
+static void s3c_irq_uart_ack(unsigned int irq)
+{
+ void __iomem *regs = s3c_irq_uart_base(irq);
+ unsigned int bit = s3c_irq_uart_bit(irq);
+
+ __raw_writel(1 << bit, regs + S3C64XX_UINTP);
+}
+
+static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
+{
+ struct s3c_uart_irq *uirq = desc->handler_data;
+ u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
+ int base = uirq->base_irq;
+
+ if (pend & (1 << 0))
+ generic_handle_irq(base);
+ if (pend & (1 << 1))
+ generic_handle_irq(base + 1);
+ if (pend & (1 << 2))
+ generic_handle_irq(base + 2);
+ if (pend & (1 << 3))
+ generic_handle_irq(base + 3);
+}
+
+static struct irq_chip s3c_irq_uart = {
+ .name = "s3c-uart",
+ .mask = s3c_irq_uart_mask,
+ .unmask = s3c_irq_uart_unmask,
+ .mask_ack = s3c_irq_uart_maskack,
+ .ack = s3c_irq_uart_ack,
+};
+
+static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
+{
+ struct irq_desc *desc = irq_to_desc(uirq->parent_irq);
+ void __iomem *reg_base = uirq->regs;
+ unsigned int irq;
+ int offs;
+
+ /* mask all interrupts at the start. */
+ __raw_writel(0xf, reg_base + S3C64XX_UINTM);
+
+ for (offs = 0; offs < 3; offs++) {
+ irq = uirq->base_irq + offs;
+
+ set_irq_chip(irq, &s3c_irq_uart);
+ set_irq_chip_data(irq, uirq);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ desc->handler_data = uirq;
+ set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
+}
+
+/**
+ * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing
+ * @irq: The interrupt data for registering
+ * @nr_irqs: The number of interrupt descriptions in @irq.
+ *
+ * Register the UART interrupts specified by @irq including the demuxing
+ * routines. This supports the S3C6400 and newer style of devices.
+ */
+void __init s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs)
+{
+ for (; nr_irqs > 0; nr_irqs--, irq++)
+ s3c_init_uart_irq(irq);
+}
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
new file mode 100644
index 00000000000..0270519fcab
--- /dev/null
+++ b/arch/arm/plat-samsung/irq-vic-timer.c
@@ -0,0 +1,86 @@
+/* arch/arm/plat-samsung/irq-vic-timer.c
+ * originally part of arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/regs-timer.h>
+
+static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
+{
+ generic_handle_irq((int)desc->handler_data);
+}
+
+/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
+
+static void s3c_irq_timer_mask(unsigned int irq)
+{
+ u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+ reg &= 0x1f; /* mask out pending interrupts */
+ reg &= ~(1 << (irq - IRQ_TIMER0));
+ __raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static void s3c_irq_timer_unmask(unsigned int irq)
+{
+ u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+ reg &= 0x1f; /* mask out pending interrupts */
+ reg |= 1 << (irq - IRQ_TIMER0);
+ __raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static void s3c_irq_timer_ack(unsigned int irq)
+{
+ u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+ reg &= 0x1f;
+ reg |= (1 << 5) << (irq - IRQ_TIMER0);
+ __raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static struct irq_chip s3c_irq_timer = {
+ .name = "s3c-timer",
+ .mask = s3c_irq_timer_mask,
+ .unmask = s3c_irq_timer_unmask,
+ .ack = s3c_irq_timer_ack,
+};
+
+/**
+ * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\
+ * @parent_irq: The parent IRQ on the VIC for the timer.
+ * @timer_irq: The IRQ to be used for the timer.
+ *
+ * Register the necessary IRQ chaining and support for the timer IRQs
+ * chained of the VIC.
+ */
+void __init s3c_init_vic_timer_irq(unsigned int parent_irq,
+ unsigned int timer_irq)
+{
+ struct irq_desc *desc = irq_to_desc(parent_irq);
+
+ set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
+
+ set_irq_chip(timer_irq, &s3c_irq_timer);
+ set_irq_handler(timer_irq, handle_level_irq);
+ set_irq_flags(timer_irq, IRQF_VALID);
+
+ desc->handler_data = (void *)timer_irq;
+}
diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c
new file mode 100644
index 00000000000..e4baf76f374
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-check.c
@@ -0,0 +1,243 @@
+/* linux/arch/arm/plat-s3c/pm-check.c
+ * originally in linux/arch/arm/plat-s3c24xx/pm.c
+ *
+ * Copyright (c) 2004-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Power Mangament - suspend/resume memory corruptiuon check.
+ *
+ * This program is free software; you can 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/suspend.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <plat/pm.h>
+
+#if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1
+#error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value
+#endif
+
+/* suspend checking code...
+ *
+ * this next area does a set of crc checks over all the installed
+ * memory, so the system can verify if the resume was ok.
+ *
+ * CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
+ * increasing it will mean that the area corrupted will be less easy to spot,
+ * and reducing the size will cause the CRC save area to grow
+*/
+
+#define CHECK_CHUNKSIZE (CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE * 1024)
+
+static u32 crc_size; /* size needed for the crc block */
+static u32 *crcs; /* allocated over suspend/resume */
+
+typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
+
+/* s3c_pm_run_res
+ *
+ * go through the given resource list, and look for system ram
+*/
+
+static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
+{
+ while (ptr != NULL) {
+ if (ptr->child != NULL)
+ s3c_pm_run_res(ptr->child, fn, arg);
+
+ if ((ptr->flags & IORESOURCE_MEM) &&
+ strcmp(ptr->name, "System RAM") == 0) {
+ S3C_PMDBG("Found system RAM at %08lx..%08lx\n",
+ (unsigned long)ptr->start,
+ (unsigned long)ptr->end);
+ arg = (fn)(ptr, arg);
+ }
+
+ ptr = ptr->sibling;
+ }
+}
+
+static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg)
+{
+ s3c_pm_run_res(&iomem_resource, fn, arg);
+}
+
+static u32 *s3c_pm_countram(struct resource *res, u32 *val)
+{
+ u32 size = (u32)(res->end - res->start)+1;
+
+ size += CHECK_CHUNKSIZE-1;
+ size /= CHECK_CHUNKSIZE;
+
+ S3C_PMDBG("Area %08lx..%08lx, %d blocks\n",
+ (unsigned long)res->start, (unsigned long)res->end, size);
+
+ *val += size * sizeof(u32);
+ return val;
+}
+
+/* s3c_pm_prepare_check
+ *
+ * prepare the necessary information for creating the CRCs. This
+ * must be done before the final save, as it will require memory
+ * allocating, and thus touching bits of the kernel we do not
+ * know about.
+*/
+
+void s3c_pm_check_prepare(void)
+{
+ crc_size = 0;
+
+ s3c_pm_run_sysram(s3c_pm_countram, &crc_size);
+
+ S3C_PMDBG("s3c_pm_prepare_check: %u checks needed\n", crc_size);
+
+ crcs = kmalloc(crc_size+4, GFP_KERNEL);
+ if (crcs == NULL)
+ printk(KERN_ERR "Cannot allocated CRC save area\n");
+}
+
+static u32 *s3c_pm_makecheck(struct resource *res, u32 *val)
+{
+ unsigned long addr, left;
+
+ for (addr = res->start; addr < res->end;
+ addr += CHECK_CHUNKSIZE) {
+ left = res->end - addr;
+
+ if (left > CHECK_CHUNKSIZE)
+ left = CHECK_CHUNKSIZE;
+
+ *val = crc32_le(~0, phys_to_virt(addr), left);
+ val++;
+ }
+
+ return val;
+}
+
+/* s3c_pm_check_store
+ *
+ * compute the CRC values for the memory blocks before the final
+ * sleep.
+*/
+
+void s3c_pm_check_store(void)
+{
+ if (crcs != NULL)
+ s3c_pm_run_sysram(s3c_pm_makecheck, crcs);
+}
+
+/* in_region
+ *
+ * return TRUE if the area defined by ptr..ptr+size contains the
+ * what..what+whatsz
+*/
+
+static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
+{
+ if ((what+whatsz) < ptr)
+ return 0;
+
+ if (what > (ptr+size))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * s3c_pm_runcheck() - helper to check a resource on restore.
+ * @res: The resource to check
+ * @vak: Pointer to list of CRC32 values to check.
+ *
+ * Called from the s3c_pm_check_restore() via s3c_pm_run_sysram(), this
+ * function runs the given memory resource checking it against the stored
+ * CRC to ensure that memory is restored. The function tries to skip as
+ * many of the areas used during the suspend process.
+ */
+static u32 *s3c_pm_runcheck(struct resource *res, u32 *val)
+{
+ void *save_at = phys_to_virt(s3c_sleep_save_phys);
+ unsigned long addr;
+ unsigned long left;
+ void *stkpage;
+ void *ptr;
+ u32 calc;
+
+ stkpage = (void *)((u32)&calc & ~PAGE_MASK);
+
+ for (addr = res->start; addr < res->end;
+ addr += CHECK_CHUNKSIZE) {
+ left = res->end - addr;
+
+ if (left > CHECK_CHUNKSIZE)
+ left = CHECK_CHUNKSIZE;
+
+ ptr = phys_to_virt(addr);
+
+ if (in_region(ptr, left, stkpage, 4096)) {
+ S3C_PMDBG("skipping %08lx, has stack in\n", addr);
+ goto skip_check;
+ }
+
+ if (in_region(ptr, left, crcs, crc_size)) {
+ S3C_PMDBG("skipping %08lx, has crc block in\n", addr);
+ goto skip_check;
+ }
+
+ if (in_region(ptr, left, save_at, 32*4 )) {
+ S3C_PMDBG("skipping %08lx, has save block in\n", addr);
+ goto skip_check;
+ }
+
+ /* calculate and check the checksum */
+
+ calc = crc32_le(~0, ptr, left);
+ if (calc != *val) {
+ printk(KERN_ERR "Restore CRC error at "
+ "%08lx (%08x vs %08x)\n", addr, calc, *val);
+
+ S3C_PMDBG("Restore CRC error at %08lx (%08x vs %08x)\n",
+ addr, calc, *val);
+ }
+
+ skip_check:
+ val++;
+ }
+
+ return val;
+}
+
+/**
+ * s3c_pm_check_restore() - memory check called on resume
+ *
+ * check the CRCs after the restore event and free the memory used
+ * to hold them
+*/
+void s3c_pm_check_restore(void)
+{
+ if (crcs != NULL)
+ s3c_pm_run_sysram(s3c_pm_runcheck, crcs);
+}
+
+/**
+ * s3c_pm_check_cleanup() - free memory resources
+ *
+ * Free the resources that where allocated by the suspend
+ * memory check code. We do this separately from the
+ * s3c_pm_check_restore() function as we cannot call any
+ * functions that might sleep during that resume.
+ */
+void s3c_pm_check_cleanup(void)
+{
+ kfree(crcs);
+ crcs = NULL;
+}
+
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
new file mode 100644
index 00000000000..69a4c7f02e2
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -0,0 +1,380 @@
+
+/* linux/arch/arm/plat-s3c/pm-gpio.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO PM code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-core.h>
+#include <plat/pm.h>
+
+/* PM GPIO helpers */
+
+#define OFFS_CON (0x00)
+#define OFFS_DAT (0x04)
+#define OFFS_UP (0x08)
+
+static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
+}
+
+static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon = __raw_readl(base + OFFS_CON);
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpcon = chip->pm_save[0];
+ u32 gps_gpdat = chip->pm_save[1];
+ u32 gpcon;
+
+ /* GPACON only has one bit per control / data and no PULLUPs.
+ * GPACON[x] = 0 => Output, 1 => SFN */
+
+ /* first set all SFN bits to SFN */
+
+ gpcon = old_gpcon | gps_gpcon;
+ __raw_writel(gpcon, base + OFFS_CON);
+
+ /* now set all the other bits */
+
+ __raw_writel(gps_gpdat, base + OFFS_DAT);
+ __raw_writel(gps_gpcon, base + OFFS_CON);
+
+ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_1bit = {
+ .save = s3c_gpio_pm_1bit_save,
+ .resume = s3c_gpio_pm_1bit_resume,
+};
+
+static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
+ chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP);
+}
+
+/* Test whether the given masked+shifted bits of an GPIO configuration
+ * are one of the SFN (special function) modes. */
+
+static inline int is_sfn(unsigned long con)
+{
+ return con >= 2;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an input */
+
+static inline int is_in(unsigned long con)
+{
+ return con == 0;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an output */
+
+static inline int is_out(unsigned long con)
+{
+ return con == 1;
+}
+
+/**
+ * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank
+ * @chip: The chip information to resume.
+ *
+ * Restore one of the GPIO banks that was saved during suspend. This is
+ * not as simple as once thought, due to the possibility of glitches
+ * from the order that the CON and DAT registers are set in.
+ *
+ * The three states the pin can be are {IN,OUT,SFN} which gives us 9
+ * combinations of changes to check. Three of these, if the pin stays
+ * in the same configuration can be discounted. This leaves us with
+ * the following:
+ *
+ * { IN => OUT } Change DAT first
+ * { IN => SFN } Change CON first
+ * { OUT => SFN } Change CON first, so new data will not glitch
+ * { OUT => IN } Change CON first, so new data will not glitch
+ * { SFN => IN } Change CON first
+ * { SFN => OUT } Change DAT first, so new data will not glitch [1]
+ *
+ * We do not currently deal with the UP registers as these control
+ * weak resistors, so a small delay in change should not need to bring
+ * these into the calculations.
+ *
+ * [1] this assumes that writing to a pin DAT whilst in SFN will set the
+ * state for when it is next output.
+ */
+static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon = __raw_readl(base + OFFS_CON);
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpcon = chip->pm_save[0];
+ u32 gps_gpdat = chip->pm_save[1];
+ u32 gpcon, old, new, mask;
+ u32 change_mask = 0x0;
+ int nr;
+
+ /* restore GPIO pull-up settings */
+ __raw_writel(chip->pm_save[2], base + OFFS_UP);
+
+ /* Create a change_mask of all the items that need to have
+ * their CON value changed before their DAT value, so that
+ * we minimise the work between the two settings.
+ */
+
+ for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
+ old = (old_gpcon & mask) >> nr;
+ new = (gps_gpcon & mask) >> nr;
+
+ /* If there is no change, then skip */
+
+ if (old == new)
+ continue;
+
+ /* If both are special function, then skip */
+
+ if (is_sfn(old) && is_sfn(new))
+ continue;
+
+ /* Change is IN => OUT, do not change now */
+
+ if (is_in(old) && is_out(new))
+ continue;
+
+ /* Change is SFN => OUT, do not change now */
+
+ if (is_sfn(old) && is_out(new))
+ continue;
+
+ /* We should now be at the case of IN=>SFN,
+ * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+ change_mask |= mask;
+ }
+
+
+ /* Write the new CON settings */
+
+ gpcon = old_gpcon & ~change_mask;
+ gpcon |= gps_gpcon & change_mask;
+
+ __raw_writel(gpcon, base + OFFS_CON);
+
+ /* Now change any items that require DAT,CON */
+
+ __raw_writel(gps_gpdat, base + OFFS_DAT);
+ __raw_writel(gps_gpcon, base + OFFS_CON);
+
+ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_2bit = {
+ .save = s3c_gpio_pm_2bit_save,
+ .resume = s3c_gpio_pm_2bit_resume,
+};
+
+#ifdef CONFIG_ARCH_S3C64XX
+static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
+ chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
+
+ if (chip->chip.ngpio > 8)
+ chip->pm_save[0] = __raw_readl(chip->base - 4);
+}
+
+static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
+{
+ u32 old, new, mask;
+ u32 change_mask = 0x0;
+ int nr;
+
+ for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
+ old = (old_gpcon & mask) >> nr;
+ new = (gps_gpcon & mask) >> nr;
+
+ /* If there is no change, then skip */
+
+ if (old == new)
+ continue;
+
+ /* If both are special function, then skip */
+
+ if (is_sfn(old) && is_sfn(new))
+ continue;
+
+ /* Change is IN => OUT, do not change now */
+
+ if (is_in(old) && is_out(new))
+ continue;
+
+ /* Change is SFN => OUT, do not change now */
+
+ if (is_sfn(old) && is_out(new))
+ continue;
+
+ /* We should now be at the case of IN=>SFN,
+ * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+ change_mask |= mask;
+ }
+
+ return change_mask;
+}
+
+static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
+{
+ void __iomem *con = chip->base + (index * 4);
+ u32 old_gpcon = __raw_readl(con);
+ u32 gps_gpcon = chip->pm_save[index + 1];
+ u32 gpcon, mask;
+
+ mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
+
+ gpcon = old_gpcon & ~mask;
+ gpcon |= gps_gpcon & mask;
+
+ __raw_writel(gpcon, con);
+}
+
+static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon[2];
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpdat = chip->pm_save[2];
+
+ /* First, modify the CON settings */
+
+ old_gpcon[0] = 0;
+ old_gpcon[1] = __raw_readl(base + OFFS_CON);
+
+ s3c_gpio_pm_4bit_con(chip, 0);
+ if (chip->chip.ngpio > 8) {
+ old_gpcon[0] = __raw_readl(base - 4);
+ s3c_gpio_pm_4bit_con(chip, -1);
+ }
+
+ /* Now change the configurations that require DAT,CON */
+
+ __raw_writel(chip->pm_save[2], base + OFFS_DAT);
+ __raw_writel(chip->pm_save[1], base + OFFS_CON);
+ if (chip->chip.ngpio > 8)
+ __raw_writel(chip->pm_save[0], base - 4);
+
+ __raw_writel(chip->pm_save[2], base + OFFS_DAT);
+ __raw_writel(chip->pm_save[3], base + OFFS_UP);
+
+ if (chip->chip.ngpio > 8) {
+ S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon[0], old_gpcon[1],
+ __raw_readl(base - 4),
+ __raw_readl(base + OFFS_CON),
+ old_gpdat, gps_gpdat);
+ } else
+ S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon[1],
+ __raw_readl(base + OFFS_CON),
+ old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_4bit = {
+ .save = s3c_gpio_pm_4bit_save,
+ .resume = s3c_gpio_pm_4bit_resume,
+};
+#endif /* CONFIG_ARCH_S3C64XX */
+
+/**
+ * s3c_pm_save_gpio() - save gpio chip data for suspend
+ * @ourchip: The chip for suspend.
+ */
+static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
+{
+ struct s3c_gpio_pm *pm = ourchip->pm;
+
+ if (pm == NULL || pm->save == NULL)
+ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
+ else
+ pm->save(ourchip);
+}
+
+/**
+ * s3c_pm_save_gpios() - Save the state of the GPIO banks.
+ *
+ * For all the GPIO banks, save the state of each one ready for going
+ * into a suspend mode.
+ */
+void s3c_pm_save_gpios(void)
+{
+ struct s3c_gpio_chip *ourchip;
+ unsigned int gpio_nr;
+
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
+ if (!ourchip)
+ continue;
+
+ s3c_pm_save_gpio(ourchip);
+
+ S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
+ ourchip->chip.label,
+ ourchip->pm_save[0],
+ ourchip->pm_save[1],
+ ourchip->pm_save[2],
+ ourchip->pm_save[3]);
+
+ gpio_nr += ourchip->chip.ngpio;
+ gpio_nr += CONFIG_S3C_GPIO_SPACE;
+ }
+}
+
+/**
+ * s3c_pm_resume_gpio() - restore gpio chip data after suspend
+ * @ourchip: The suspended chip.
+ */
+static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
+{
+ struct s3c_gpio_pm *pm = ourchip->pm;
+
+ if (pm == NULL || pm->resume == NULL)
+ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
+ else
+ pm->resume(ourchip);
+}
+
+void s3c_pm_restore_gpios(void)
+{
+ struct s3c_gpio_chip *ourchip;
+ unsigned int gpio_nr;
+
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
+ if (!ourchip)
+ continue;
+
+ s3c_pm_resume_gpio(ourchip);
+
+ gpio_nr += ourchip->chip.ngpio;
+ gpio_nr += CONFIG_S3C_GPIO_SPACE;
+ }
+}
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
new file mode 100644
index 00000000000..27cfca59769
--- /dev/null
+++ b/arch/arm/plat-samsung/pm.c
@@ -0,0 +1,378 @@
+/* linux/arch/arm/plat-s3c/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2004-2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C common power management (suspend to ram) support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-irq.h>
+#include <asm/irq.h>
+
+#include <plat/pm.h>
+#include <mach/pm-core.h>
+
+/* for external use */
+
+unsigned long s3c_pm_flags;
+
+/* Debug code:
+ *
+ * This code supports debug output to the low level UARTs for use on
+ * resume before the console layer is available.
+*/
+
+#ifdef CONFIG_SAMSUNG_PM_DEBUG
+extern void printascii(const char *);
+
+void s3c_pm_dbg(const char *fmt, ...)
+{
+ va_list va;
+ char buff[256];
+
+ va_start(va, fmt);
+ vsprintf(buff, fmt, va);
+ va_end(va);
+
+ printascii(buff);
+}
+
+static inline void s3c_pm_debug_init(void)
+{
+ /* restart uart clocks so we can use them to output */
+ s3c_pm_debug_init_uart();
+}
+
+#else
+#define s3c_pm_debug_init() do { } while(0)
+
+#endif /* CONFIG_SAMSUNG_PM_DEBUG */
+
+/* Save the UART configurations if we are configured for debug. */
+
+unsigned char pm_uart_udivslot;
+
+#ifdef CONFIG_SAMSUNG_PM_DEBUG
+
+struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
+{
+ void __iomem *regs = S3C_VA_UARTx(uart);
+
+ save->ulcon = __raw_readl(regs + S3C2410_ULCON);
+ save->ucon = __raw_readl(regs + S3C2410_UCON);
+ save->ufcon = __raw_readl(regs + S3C2410_UFCON);
+ save->umcon = __raw_readl(regs + S3C2410_UMCON);
+ save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
+
+ if (pm_uart_udivslot)
+ save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
+
+ S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
+ uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
+}
+
+static void s3c_pm_save_uarts(void)
+{
+ struct pm_uart_save *save = uart_save;
+ unsigned int uart;
+
+ for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+ s3c_pm_save_uart(uart, save);
+}
+
+static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
+{
+ void __iomem *regs = S3C_VA_UARTx(uart);
+
+ s3c_pm_arch_update_uart(regs, save);
+
+ __raw_writel(save->ulcon, regs + S3C2410_ULCON);
+ __raw_writel(save->ucon, regs + S3C2410_UCON);
+ __raw_writel(save->ufcon, regs + S3C2410_UFCON);
+ __raw_writel(save->umcon, regs + S3C2410_UMCON);
+ __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
+
+ if (pm_uart_udivslot)
+ __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
+}
+
+static void s3c_pm_restore_uarts(void)
+{
+ struct pm_uart_save *save = uart_save;
+ unsigned int uart;
+
+ for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+ s3c_pm_restore_uart(uart, save);
+}
+#else
+static void s3c_pm_save_uarts(void) { }
+static void s3c_pm_restore_uarts(void) { }
+#endif
+
+/* The IRQ ext-int code goes here, it is too small to currently bother
+ * with its own file. */
+
+unsigned long s3c_irqwake_intmask = 0xffffffffL;
+unsigned long s3c_irqwake_eintmask = 0xffffffffL;
+
+int s3c_irqext_wake(unsigned int irqno, unsigned int state)
+{
+ unsigned long bit = 1L << IRQ_EINT_BIT(irqno);
+
+ if (!(s3c_irqwake_eintallow & bit))
+ return -ENOENT;
+
+ printk(KERN_INFO "wake %s for irq %d\n",
+ state ? "enabled" : "disabled", irqno);
+
+ if (!state)
+ s3c_irqwake_eintmask |= bit;
+ else
+ s3c_irqwake_eintmask &= ~bit;
+
+ return 0;
+}
+
+/* helper functions to save and restore register state */
+
+/**
+ * s3c_pm_do_save() - save a set of registers for restoration on resume.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Run through the list of registers given, saving their contents in the
+ * array for later restoration when we wakeup.
+ */
+void s3c_pm_do_save(struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++) {
+ ptr->val = __raw_readl(ptr->reg);
+ S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
+ }
+}
+
+/**
+ * s3c_pm_do_restore() - restore register values from the save list.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Restore the register values saved from s3c_pm_do_save().
+ *
+ * Note, we do not use S3C_PMDBG() in here, as the system may not have
+ * restore the UARTs state yet
+*/
+
+void s3c_pm_do_restore(struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++) {
+ printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+
+ __raw_writel(ptr->val, ptr->reg);
+ }
+}
+
+/**
+ * s3c_pm_do_restore_core() - early restore register values from save list.
+ *
+ * This is similar to s3c_pm_do_restore() except we try and minimise the
+ * side effects of the function in case registers that hardware might need
+ * to work has been restored.
+ *
+ * WARNING: Do not put any debug in here that may effect memory or use
+ * peripherals, as things may be changing!
+*/
+
+void s3c_pm_do_restore_core(struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++)
+ __raw_writel(ptr->val, ptr->reg);
+}
+
+/* s3c2410_pm_show_resume_irqs
+ *
+ * print any IRQs asserted at resume time (ie, we woke from)
+*/
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+ unsigned long mask)
+{
+ int i;
+
+ which &= ~mask;
+
+ for (i = 0; i <= 31; i++) {
+ if (which & (1L<<i)) {
+ S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
+ }
+ }
+}
+
+
+void (*pm_cpu_prep)(void);
+void (*pm_cpu_sleep)(void);
+
+#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
+
+/* s3c_pm_enter
+ *
+ * central control for sleep/resume process
+*/
+
+static int s3c_pm_enter(suspend_state_t state)
+{
+ static unsigned long regs_save[16];
+
+ /* ensure the debug is initialised (if enabled) */
+
+ s3c_pm_debug_init();
+
+ S3C_PMDBG("%s(%d)\n", __func__, state);
+
+ if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
+ printk(KERN_ERR "%s: error: no cpu sleep function\n", __func__);
+ return -EINVAL;
+ }
+
+ /* check if we have anything to wake-up with... bad things seem
+ * to happen if you suspend with no wakeup (system will often
+ * require a full power-cycle)
+ */
+
+ if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
+ !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
+ printk(KERN_ERR "%s: No wake-up sources!\n", __func__);
+ printk(KERN_ERR "%s: Aborting sleep\n", __func__);
+ return -EINVAL;
+ }
+
+ /* store the physical address of the register recovery block */
+
+ s3c_sleep_save_phys = virt_to_phys(regs_save);
+
+ S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys);
+
+ /* save all necessary core registers not covered by the drivers */
+
+ s3c_pm_save_gpios();
+ s3c_pm_save_uarts();
+ s3c_pm_save_core();
+
+ /* set the irq configuration for wake */
+
+ s3c_pm_configure_extint();
+
+ S3C_PMDBG("sleep: irq wakeup masks: %08lx,%08lx\n",
+ s3c_irqwake_intmask, s3c_irqwake_eintmask);
+
+ s3c_pm_arch_prepare_irqs();
+
+ /* call cpu specific preparation */
+
+ pm_cpu_prep();
+
+ /* flush cache back to ram */
+
+ flush_cache_all();
+
+ s3c_pm_check_store();
+
+ /* send the cpu to sleep... */
+
+ s3c_pm_arch_stop_clocks();
+
+ /* s3c_cpu_save will also act as our return point from when
+ * we resume as it saves its own register state and restores it
+ * during the resume. */
+
+ s3c_cpu_save(regs_save);
+
+ /* restore the cpu state using the kernel's cpu init code. */
+
+ cpu_init();
+
+ /* restore the system state */
+
+ s3c_pm_restore_core();
+ s3c_pm_restore_uarts();
+ s3c_pm_restore_gpios();
+
+ s3c_pm_debug_init();
+
+ /* check what irq (if any) restored the system */
+
+ s3c_pm_arch_show_resume_irqs();
+
+ S3C_PMDBG("%s: post sleep, preparing to return\n", __func__);
+
+ /* LEDs should now be 1110 */
+ s3c_pm_debug_smdkled(1 << 1, 0);
+
+ s3c_pm_check_restore();
+
+ /* ok, let's return from sleep */
+
+ S3C_PMDBG("S3C PM Resume (post-restore)\n");
+ return 0;
+}
+
+/* callback from assembly code */
+void s3c_pm_cb_flushcache(void)
+{
+ flush_cache_all();
+}
+
+static int s3c_pm_prepare(void)
+{
+ /* prepare check area if configured */
+
+ s3c_pm_check_prepare();
+ return 0;
+}
+
+static void s3c_pm_finish(void)
+{
+ s3c_pm_check_cleanup();
+}
+
+static struct platform_suspend_ops s3c_pm_ops = {
+ .enter = s3c_pm_enter,
+ .prepare = s3c_pm_prepare,
+ .finish = s3c_pm_finish,
+ .valid = suspend_valid_only_mem,
+};
+
+/* s3c_pm_init
+ *
+ * Attach the power management functions. This should be called
+ * from the board specific initialisation if the board supports
+ * it.
+*/
+
+int __init s3c_pm_init(void)
+{
+ printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
+
+ suspend_set_ops(&s3c_pm_ops);
+ return 0;
+}
diff --git a/arch/arm/plat-samsung/pwm-clock.c b/arch/arm/plat-samsung/pwm-clock.c
new file mode 100644
index 00000000000..46c9381e083
--- /dev/null
+++ b/arch/arm/plat-samsung/pwm-clock.c
@@ -0,0 +1,455 @@
+/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Copyright (c) 2007, 2008 Ben Dooks
+ * Ben Dooks <ben-linux@fluff.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.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/log2.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-timer.h>
+#include <mach/pwm-clock.h>
+
+/* Each of the timers 0 through 5 go through the following
+ * clock tree, with the inputs depending on the timers.
+ *
+ * pclk ---- [ prescaler 0 ] -+---> timer 0
+ * +---> timer 1
+ *
+ * pclk ---- [ prescaler 1 ] -+---> timer 2
+ * +---> timer 3
+ * \---> timer 4
+ *
+ * Which are fed into the timers as so:
+ *
+ * prescaled 0 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 0
+ * tclk 0 ------------------------------/
+ *
+ * prescaled 0 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 1
+ * tclk 0 ------------------------------/
+ *
+ *
+ * prescaled 1 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 2
+ * tclk 1 ------------------------------/
+ *
+ * prescaled 1 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 3
+ * tclk 1 ------------------------------/
+ *
+ * prescaled 1 ---- [ div 2,4,8, 16 ] --\
+ * [mux] -> timer 4
+ * tclk 1 ------------------------------/
+ *
+ * Since the mux and the divider are tied together in the
+ * same register space, it is impossible to set the parent
+ * and the rate at the same time. To avoid this, we add an
+ * intermediate 'prescaled-and-divided' clock to select
+ * as the parent for the timer input clock called tdiv.
+ *
+ * prescaled clk --> pwm-tdiv ---\
+ * [ mux ] --> timer X
+ * tclk -------------------------/
+*/
+
+static struct clk clk_timer_scaler[];
+
+static unsigned long clk_pwm_scaler_get_rate(struct clk *clk)
+{
+ unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+ if (clk == &clk_timer_scaler[1]) {
+ tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
+ tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
+ } else {
+ tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
+ }
+
+ return clk_get_rate(clk->parent) / (tcfg0 + 1);
+}
+
+static unsigned long clk_pwm_scaler_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long divisor = parent_rate / rate;
+
+ if (divisor > 256)
+ divisor = 256;
+ else if (divisor < 2)
+ divisor = 2;
+
+ return parent_rate / divisor;
+}
+
+static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long round = clk_pwm_scaler_round_rate(clk, rate);
+ unsigned long tcfg0;
+ unsigned long divisor;
+ unsigned long flags;
+
+ divisor = clk_get_rate(clk->parent) / round;
+ divisor--;
+
+ local_irq_save(flags);
+ tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+ if (clk == &clk_timer_scaler[1]) {
+ tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
+ tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT;
+ } else {
+ tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
+ tcfg0 |= divisor;
+ }
+
+ __raw_writel(tcfg0, S3C2410_TCFG0);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static struct clk_ops clk_pwm_scaler_ops = {
+ .get_rate = clk_pwm_scaler_get_rate,
+ .set_rate = clk_pwm_scaler_set_rate,
+ .round_rate = clk_pwm_scaler_round_rate,
+};
+
+static struct clk clk_timer_scaler[] = {
+ [0] = {
+ .name = "pwm-scaler0",
+ .id = -1,
+ .ops = &clk_pwm_scaler_ops,
+ },
+ [1] = {
+ .name = "pwm-scaler1",
+ .id = -1,
+ .ops = &clk_pwm_scaler_ops,
+ },
+};
+
+static struct clk clk_timer_tclk[] = {
+ [0] = {
+ .name = "pwm-tclk0",
+ .id = -1,
+ },
+ [1] = {
+ .name = "pwm-tclk1",
+ .id = -1,
+ },
+};
+
+struct pwm_tdiv_clk {
+ struct clk clk;
+ unsigned int divisor;
+};
+
+static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
+{
+ return container_of(clk, struct pwm_tdiv_clk, clk);
+}
+
+static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned int divisor;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ if (pwm_cfg_src_is_tclk(tcfg1))
+ divisor = to_tdiv(clk)->divisor;
+ else
+ divisor = tcfg_to_divisor(tcfg1);
+
+ return clk_get_rate(clk->parent) / divisor;
+}
+
+static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate;
+ unsigned long divisor;
+
+ parent_rate = clk_get_rate(clk->parent);
+ divisor = parent_rate / rate;
+
+ if (divisor <= 1 && pwm_tdiv_has_div1())
+ divisor = 1;
+ else if (divisor <= 2)
+ divisor = 2;
+ else if (divisor <= 4)
+ divisor = 4;
+ else if (divisor <= 8)
+ divisor = 8;
+ else
+ divisor = 16;
+
+ return parent_rate / divisor;
+}
+
+static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
+{
+ return pwm_tdiv_div_bits(divclk->divisor);
+}
+
+static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned long bits = clk_pwm_tdiv_bits(divclk);
+ unsigned long flags;
+ unsigned long shift = S3C2410_TCFG1_SHIFT(divclk->clk.id);
+
+ local_irq_save(flags);
+
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+ tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
+ tcfg1 |= bits << shift;
+ __raw_writel(tcfg1, S3C2410_TCFG1);
+
+ local_irq_restore(flags);
+}
+
+static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct pwm_tdiv_clk *divclk = to_tdiv(clk);
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long divisor;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ rate = clk_round_rate(clk, rate);
+ divisor = parent_rate / rate;
+
+ if (divisor > 16)
+ return -EINVAL;
+
+ divclk->divisor = divisor;
+
+ /* Update the current MUX settings if we are currently
+ * selected as the clock source for this clock. */
+
+ if (!pwm_cfg_src_is_tclk(tcfg1))
+ clk_pwm_tdiv_update(divclk);
+
+ return 0;
+}
+
+static struct clk_ops clk_tdiv_ops = {
+ .get_rate = clk_pwm_tdiv_get_rate,
+ .set_rate = clk_pwm_tdiv_set_rate,
+ .round_rate = clk_pwm_tdiv_round_rate,
+};
+
+static struct pwm_tdiv_clk clk_timer_tdiv[] = {
+ [0] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[0],
+ },
+ },
+ [1] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[0],
+ }
+ },
+ [2] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[1],
+ },
+ },
+ [3] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[1],
+ },
+ },
+ [4] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[1],
+ },
+ },
+};
+
+static int __init clk_pwm_tdiv_register(unsigned int id)
+{
+ struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ divclk->clk.id = id;
+ divclk->divisor = tcfg_to_divisor(tcfg1);
+
+ return s3c24xx_register_clock(&divclk->clk);
+}
+
+static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
+{
+ return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
+}
+
+static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
+{
+ return &clk_timer_tdiv[id].clk;
+}
+
+static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned int id = clk->id;
+ unsigned long tcfg1;
+ unsigned long flags;
+ unsigned long bits;
+ unsigned long shift = S3C2410_TCFG1_SHIFT(id);
+
+ if (parent == s3c24xx_pwmclk_tclk(id))
+ bits = S3C_TCFG1_MUX_TCLK << shift;
+ else if (parent == s3c24xx_pwmclk_tdiv(id))
+ bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ local_irq_save(flags);
+
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+ tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
+ __raw_writel(tcfg1 | bits, S3C2410_TCFG1);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static struct clk_ops clk_tin_ops = {
+ .set_parent = clk_pwm_tin_set_parent,
+};
+
+static struct clk clk_tin[] = {
+ [0] = {
+ .name = "pwm-tin",
+ .id = 0,
+ .ops = &clk_tin_ops,
+ },
+ [1] = {
+ .name = "pwm-tin",
+ .id = 1,
+ .ops = &clk_tin_ops,
+ },
+ [2] = {
+ .name = "pwm-tin",
+ .id = 2,
+ .ops = &clk_tin_ops,
+ },
+ [3] = {
+ .name = "pwm-tin",
+ .id = 3,
+ .ops = &clk_tin_ops,
+ },
+ [4] = {
+ .name = "pwm-tin",
+ .id = 4,
+ .ops = &clk_tin_ops,
+ },
+};
+
+static __init int clk_pwm_tin_register(struct clk *pwm)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned int id = pwm->id;
+
+ struct clk *parent;
+ int ret;
+
+ ret = s3c24xx_register_clock(pwm);
+ if (ret < 0)
+ return ret;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ if (pwm_cfg_src_is_tclk(tcfg1))
+ parent = s3c24xx_pwmclk_tclk(id);
+ else
+ parent = s3c24xx_pwmclk_tdiv(id);
+
+ return clk_set_parent(pwm, parent);
+}
+
+/**
+ * s3c_pwmclk_init() - initialise pwm clocks
+ *
+ * Initialise and register the clocks which provide the inputs for the
+ * pwm timer blocks.
+ *
+ * Note, this call is required by the time core, so must be called after
+ * the base clocks are added and before any of the initcalls are run.
+ */
+__init void s3c_pwmclk_init(void)
+{
+ struct clk *clk_timers;
+ unsigned int clk;
+ int ret;
+
+ clk_timers = clk_get(NULL, "timers");
+ if (IS_ERR(clk_timers)) {
+ printk(KERN_ERR "%s: no parent clock\n", __func__);
+ return;
+ }
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++)
+ clk_timer_scaler[clk].parent = clk_timers;
+
+ s3c_register_clocks(clk_timer_scaler, ARRAY_SIZE(clk_timer_scaler));
+ s3c_register_clocks(clk_timer_tclk, ARRAY_SIZE(clk_timer_tclk));
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
+ ret = clk_pwm_tdiv_register(clk);
+
+ if (ret < 0) {
+ printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
+ return;
+ }
+ }
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
+ ret = clk_pwm_tin_register(&clk_tin[clk]);
+ if (ret < 0) {
+ printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
+ return;
+ }
+ }
+}
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
new file mode 100644
index 00000000000..2eeb49fa056
--- /dev/null
+++ b/arch/arm/plat-samsung/pwm.c
@@ -0,0 +1,446 @@
+/* arch/arm/plat-s3c/pwm.c
+ *
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * S3C series PWM device core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/regs-timer.h>
+
+struct pwm_device {
+ struct list_head list;
+ struct platform_device *pdev;
+
+ struct clk *clk_div;
+ struct clk *clk;
+ const char *label;
+
+ unsigned int period_ns;
+ unsigned int duty_ns;
+
+ unsigned char tcon_base;
+ unsigned char running;
+ unsigned char use_count;
+ unsigned char pwm_id;
+};
+
+#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
+
+static struct clk *clk_scaler[2];
+
+/* Standard setup for a timer block. */
+
+#define TIMER_RESOURCE_SIZE (1)
+
+#define TIMER_RESOURCE(_tmr, _irq) \
+ (struct resource [TIMER_RESOURCE_SIZE]) { \
+ [0] = { \
+ .start = _irq, \
+ .end = _irq, \
+ .flags = IORESOURCE_IRQ \
+ } \
+ }
+
+#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
+ .name = "s3c24xx-pwm", \
+ .id = _tmr_no, \
+ .num_resources = TIMER_RESOURCE_SIZE, \
+ .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+
+/* since we already have an static mapping for the timer, we do not
+ * bother setting any IO resource for the base.
+ */
+
+struct platform_device s3c_device_timer[] = {
+ [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
+ [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
+ [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
+ [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
+ [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+};
+
+static inline int pwm_is_tdiv(struct pwm_device *pwm)
+{
+ return clk_get_parent(pwm->clk) == pwm->clk_div;
+}
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+ struct pwm_device *pwm;
+ int found = 0;
+
+ mutex_lock(&pwm_lock);
+
+ list_for_each_entry(pwm, &pwm_list, list) {
+ if (pwm->pwm_id == pwm_id) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ if (pwm->use_count == 0) {
+ pwm->use_count = 1;
+ pwm->label = label;
+ } else
+ pwm = ERR_PTR(-EBUSY);
+ } else
+ pwm = ERR_PTR(-ENOENT);
+
+ mutex_unlock(&pwm_lock);
+ return pwm;
+}
+
+EXPORT_SYMBOL(pwm_request);
+
+
+void pwm_free(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+
+ if (pwm->use_count) {
+ pwm->use_count--;
+ pwm->label = NULL;
+ } else
+ printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
+
+ mutex_unlock(&pwm_lock);
+}
+
+EXPORT_SYMBOL(pwm_free);
+
+#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
+#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
+#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
+#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
+
+int pwm_enable(struct pwm_device *pwm)
+{
+ unsigned long flags;
+ unsigned long tcon;
+
+ local_irq_save(flags);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ pwm->running = 1;
+ return 0;
+}
+
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+ unsigned long flags;
+ unsigned long tcon;
+
+ local_irq_save(flags);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon &= ~pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ pwm->running = 0;
+}
+
+EXPORT_SYMBOL(pwm_disable);
+
+static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
+{
+ unsigned long tin_parent_rate;
+ unsigned int div;
+
+ tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
+ pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
+
+ for (div = 2; div <= 16; div *= 2) {
+ if ((tin_parent_rate / (div << 16)) < freq)
+ return tin_parent_rate / div;
+ }
+
+ return tin_parent_rate / 16;
+}
+
+#define NS_IN_HZ (1000000000UL)
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ unsigned long tin_rate;
+ unsigned long tin_ns;
+ unsigned long period;
+ unsigned long flags;
+ unsigned long tcon;
+ unsigned long tcnt;
+ long tcmp;
+
+ /* We currently avoid using 64bit arithmetic by using the
+ * fact that anything faster than 1Hz is easily representable
+ * by 32bits. */
+
+ if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+ return -ERANGE;
+
+ if (duty_ns > period_ns)
+ return -EINVAL;
+
+ if (period_ns == pwm->period_ns &&
+ duty_ns == pwm->duty_ns)
+ return 0;
+
+ /* The TCMP and TCNT can be read without a lock, they're not
+ * shared between the timers. */
+
+ tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
+ tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
+
+ period = NS_IN_HZ / period_ns;
+
+ pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
+ duty_ns, period_ns, period);
+
+ /* Check to see if we are changing the clock rate of the PWM */
+
+ if (pwm->period_ns != period_ns) {
+ if (pwm_is_tdiv(pwm)) {
+ tin_rate = pwm_calc_tin(pwm, period);
+ clk_set_rate(pwm->clk_div, tin_rate);
+ } else
+ tin_rate = clk_get_rate(pwm->clk);
+
+ pwm->period_ns = period_ns;
+
+ pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
+
+ tin_ns = NS_IN_HZ / tin_rate;
+ tcnt = period_ns / tin_ns;
+ } else
+ tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
+
+ /* Note, counters count down */
+
+ tcmp = duty_ns / tin_ns;
+ tcmp = tcnt - tcmp;
+ /* the pwm hw only checks the compare register after a decrement,
+ so the pin never toggles if tcmp = tcnt */
+ if (tcmp == tcnt)
+ tcmp--;
+
+ pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
+
+ if (tcmp < 0)
+ tcmp = 0;
+
+ /* Update the PWM register block. */
+
+ local_irq_save(flags);
+
+ __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
+ __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_manulupdate(pwm);
+ tcon |= pwm_tcon_autoreload(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ tcon &= ~pwm_tcon_manulupdate(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(pwm_config);
+
+static int pwm_register(struct pwm_device *pwm)
+{
+ pwm->duty_ns = -1;
+ pwm->period_ns = -1;
+
+ mutex_lock(&pwm_lock);
+ list_add_tail(&pwm->list, &pwm_list);
+ mutex_unlock(&pwm_lock);
+
+ return 0;
+}
+
+static int s3c_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct pwm_device *pwm;
+ unsigned long flags;
+ unsigned long tcon;
+ unsigned int id = pdev->id;
+ int ret;
+
+ if (id == 4) {
+ dev_err(dev, "TIMER4 is currently not supported\n");
+ return -ENXIO;
+ }
+
+ pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (pwm == NULL) {
+ dev_err(dev, "failed to allocate pwm_device\n");
+ return -ENOMEM;
+ }
+
+ pwm->pdev = pdev;
+ pwm->pwm_id = id;
+
+ /* calculate base of control bits in TCON */
+ pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+
+ pwm->clk = clk_get(dev, "pwm-tin");
+ if (IS_ERR(pwm->clk)) {
+ dev_err(dev, "failed to get pwm tin clk\n");
+ ret = PTR_ERR(pwm->clk);
+ goto err_alloc;
+ }
+
+ pwm->clk_div = clk_get(dev, "pwm-tdiv");
+ if (IS_ERR(pwm->clk_div)) {
+ dev_err(dev, "failed to get pwm tdiv clk\n");
+ ret = PTR_ERR(pwm->clk_div);
+ goto err_clk_tin;
+ }
+
+ local_irq_save(flags);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_invert(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+
+ ret = pwm_register(pwm);
+ if (ret) {
+ dev_err(dev, "failed to register pwm\n");
+ goto err_clk_tdiv;
+ }
+
+ pwm_dbg(pwm, "config bits %02x\n",
+ (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
+
+ dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
+ clk_get_rate(pwm->clk),
+ clk_get_rate(pwm->clk_div),
+ pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
+
+ platform_set_drvdata(pdev, pwm);
+ return 0;
+
+ err_clk_tdiv:
+ clk_put(pwm->clk_div);
+
+ err_clk_tin:
+ clk_put(pwm->clk);
+
+ err_alloc:
+ kfree(pwm);
+ return ret;
+}
+
+static int __devexit s3c_pwm_remove(struct platform_device *pdev)
+{
+ struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+ clk_put(pwm->clk_div);
+ clk_put(pwm->clk);
+ kfree(pwm);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+ /* No one preserve these values during suspend so reset them
+ * Otherwise driver leaves PWM unconfigured if same values
+ * passed to pwm_config
+ */
+ pwm->period_ns = 0;
+ pwm->duty_ns = 0;
+
+ return 0;
+}
+
+static int s3c_pwm_resume(struct platform_device *pdev)
+{
+ struct pwm_device *pwm = platform_get_drvdata(pdev);
+ unsigned long tcon;
+
+ /* Restore invertion */
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_invert(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ return 0;
+}
+
+#else
+#define s3c_pwm_suspend NULL
+#define s3c_pwm_resume NULL
+#endif
+
+static struct platform_driver s3c_pwm_driver = {
+ .driver = {
+ .name = "s3c24xx-pwm",
+ .owner = THIS_MODULE,
+ },
+ .probe = s3c_pwm_probe,
+ .remove = __devexit_p(s3c_pwm_remove),
+ .suspend = s3c_pwm_suspend,
+ .resume = s3c_pwm_resume,
+};
+
+static int __init pwm_init(void)
+{
+ int ret;
+
+ clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
+ clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
+
+ if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
+ printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = platform_driver_register(&s3c_pwm_driver);
+ if (ret)
+ printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
+
+ return ret;
+}
+
+arch_initcall(pwm_init);
diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c
new file mode 100644
index 00000000000..2231d80ad81
--- /dev/null
+++ b/arch/arm/plat-samsung/time.c
@@ -0,0 +1,285 @@
+/* linux/arch/arm/plat-samsung/time.c
+ *
+ * Copyright (C) 2003-2005 Simtec Electronics
+ * Ben Dooks, <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include <asm/irq.h>
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <mach/regs-irq.h>
+#include <asm/mach/time.h>
+#include <mach/tick.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+static unsigned long timer_startval;
+static unsigned long timer_usec_ticks;
+
+#ifndef TICK_MAX
+#define TICK_MAX (0xffff)
+#endif
+
+#define TIMER_USEC_SHIFT 16
+
+/* we use the shifted arithmetic to work out the ratio of timer ticks
+ * to usecs, as often the peripheral clock is not a nice even multiple
+ * of 1MHz.
+ *
+ * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
+ * for the current HZ value of 200 without producing overflows.
+ *
+ * Original patch by Dimitry Andric, updated by Ben Dooks
+*/
+
+
+/* timer_mask_usec_ticks
+ *
+ * given a clock and divisor, make the value to pass into timer_ticks_to_usec
+ * to scale the ticks into usecs
+*/
+
+static inline unsigned long
+timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
+{
+ unsigned long den = pclk / 1000;
+
+ return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
+}
+
+/* timer_ticks_to_usec
+ *
+ * convert timer ticks to usec.
+*/
+
+static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
+{
+ unsigned long res;
+
+ res = ticks * timer_usec_ticks;
+ res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */
+
+ return res >> TIMER_USEC_SHIFT;
+}
+
+/***
+ * Returns microsecond since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ * IRQs are disabled before entering here from do_gettimeofday()
+ */
+
+static unsigned long s3c2410_gettimeoffset (void)
+{
+ unsigned long tdone;
+ unsigned long tval;
+
+ /* work out how many ticks have gone since last timer interrupt */
+
+ tval = __raw_readl(S3C2410_TCNTO(4));
+ tdone = timer_startval - tval;
+
+ /* check to see if there is an interrupt pending */
+
+ if (s3c24xx_ostimer_pending()) {
+ /* re-read the timer, and try and fix up for the missed
+ * interrupt. Note, the interrupt may go off before the
+ * timer has re-loaded from wrapping.
+ */
+
+ tval = __raw_readl(S3C2410_TCNTO(4));
+ tdone = timer_startval - tval;
+
+ if (tval != 0)
+ tdone += timer_startval;
+ }
+
+ return timer_ticks_to_usec(tdone);
+}
+
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+s3c2410_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction s3c2410_timer_irq = {
+ .name = "S3C2410 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = s3c2410_timer_interrupt,
+};
+
+#define use_tclk1_12() ( \
+ machine_is_bast() || \
+ machine_is_vr1000() || \
+ machine_is_anubis() || \
+ machine_is_osiris())
+
+static struct clk *tin;
+static struct clk *tdiv;
+static struct clk *timerclk;
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ *
+ * Currently we only use timer4, as it is the only timer which has no
+ * other function that can be exploited externally
+ */
+static void s3c2410_timer_setup (void)
+{
+ unsigned long tcon;
+ unsigned long tcnt;
+ unsigned long tcfg1;
+ unsigned long tcfg0;
+
+ tcnt = TICK_MAX; /* default value for tcnt */
+
+ /* configure the system for whichever machine is in use */
+
+ if (use_tclk1_12()) {
+ /* timer is at 12MHz, scaler is 1 */
+ timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
+ tcnt = 12000000 / HZ;
+
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+ tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
+ tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
+ __raw_writel(tcfg1, S3C2410_TCFG1);
+ } else {
+ unsigned long pclk;
+ struct clk *tscaler;
+
+ /* for the h1940 (and others), we use the pclk from the core
+ * to generate the timer values. since values around 50 to
+ * 70MHz are not values we can directly generate the timer
+ * value from, we need to pre-scale and divide before using it.
+ *
+ * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
+ * (8.45 ticks per usec)
+ */
+
+ pclk = clk_get_rate(timerclk);
+
+ /* configure clock tick */
+
+ timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
+
+ tscaler = clk_get_parent(tdiv);
+
+ clk_set_rate(tscaler, pclk / 3);
+ clk_set_rate(tdiv, pclk / 6);
+ clk_set_parent(tin, tdiv);
+
+ tcnt = clk_get_rate(tin) / HZ;
+ }
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcfg0 = __raw_readl(S3C2410_TCFG0);
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+
+ /* timers reload after counting zero, so reduce the count by 1 */
+
+ tcnt--;
+
+ printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
+ tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
+
+ /* check to see if timer is within 16bit range... */
+ if (tcnt > TICK_MAX) {
+ panic("setup_timer: HZ is too small, cannot configure timer!");
+ return;
+ }
+
+ __raw_writel(tcfg1, S3C2410_TCFG1);
+ __raw_writel(tcfg0, S3C2410_TCFG0);
+
+ timer_startval = tcnt;
+ __raw_writel(tcnt, S3C2410_TCNTB(4));
+
+ /* ensure timer is stopped... */
+
+ tcon &= ~(7<<20);
+ tcon |= S3C2410_TCON_T4RELOAD;
+ tcon |= S3C2410_TCON_T4MANUALUPD;
+
+ __raw_writel(tcon, S3C2410_TCON);
+ __raw_writel(tcnt, S3C2410_TCNTB(4));
+ __raw_writel(tcnt, S3C2410_TCMPB(4));
+
+ /* start the timer running */
+ tcon |= S3C2410_TCON_T4START;
+ tcon &= ~S3C2410_TCON_T4MANUALUPD;
+ __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void __init s3c2410_timer_resources(void)
+{
+ struct platform_device tmpdev;
+
+ tmpdev.dev.bus = &platform_bus_type;
+ tmpdev.id = 4;
+
+ timerclk = clk_get(NULL, "timers");
+ if (IS_ERR(timerclk))
+ panic("failed to get clock for system timer");
+
+ clk_enable(timerclk);
+
+ if (!use_tclk1_12()) {
+ tin = clk_get(&tmpdev.dev, "pwm-tin");
+ if (IS_ERR(tin))
+ panic("failed to get pwm-tin clock for system timer");
+
+ tdiv = clk_get(&tmpdev.dev, "pwm-tdiv");
+ if (IS_ERR(tdiv))
+ panic("failed to get pwm-tdiv clock for system timer");
+ }
+
+ clk_enable(tin);
+}
+
+static void __init s3c2410_timer_init(void)
+{
+ s3c2410_timer_resources();
+ s3c2410_timer_setup();
+ setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
+}
+
+struct sys_timer s3c24xx_timer = {
+ .init = s3c2410_timer_init,
+ .offset = s3c2410_gettimeoffset,
+ .resume = s3c2410_timer_setup
+};
diff --git a/arch/arm/plat-stmp3xxx/dma.c b/arch/arm/plat-stmp3xxx/dma.c
index ef88f25fb87..b4dcf8c0477 100644
--- a/arch/arm/plat-stmp3xxx/dma.c
+++ b/arch/arm/plat-stmp3xxx/dma.c
@@ -15,6 +15,7 @@
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/dmapool.h>
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 31c2f4c30a9..1536f1784ca 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 Feb 20 14:16:15 2010
+# Last update: Sat Mar 20 15:35:41 2010
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -2663,7 +2663,7 @@ reb01 MACH_REB01 REB01 2675
aquila MACH_AQUILA AQUILA 2676
spark_sls_hw2 MACH_SPARK_SLS_HW2 SPARK_SLS_HW2 2677
sheeva_esata MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
-surf7x30 MACH_SURF7X30 SURF7X30 2679
+msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
micro2440 MACH_MICRO2440 MICRO2440 2680
am2440 MACH_AM2440 AM2440 2681
tq2440 MACH_TQ2440 TQ2440 2682
@@ -2678,3 +2678,74 @@ vc088x MACH_VC088X VC088X 2690
mioa702 MACH_MIOA702 MIOA702 2691
hpmin MACH_HPMIN HPMIN 2692
ak880xak MACH_AK880XAK AK880XAK 2693
+arm926tomap850 MACH_ARM926TOMAP850 ARM926TOMAP850 2694
+lkevm MACH_LKEVM LKEVM 2695
+mw6410 MACH_MW6410 MW6410 2696
+terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697
+cpu8000e MACH_CPU8000E CPU8000E 2698
+catania MACH_CATANIA CATANIA 2699
+tokyo MACH_TOKYO TOKYO 2700
+msm7201a_surf MACH_MSM7201A_SURF MSM7201A_SURF 2701
+msm7201a_ffa MACH_MSM7201A_FFA MSM7201A_FFA 2702
+msm7x25_surf MACH_MSM7X25_SURF MSM7X25_SURF 2703
+msm7x25_ffa MACH_MSM7X25_FFA MSM7X25_FFA 2704
+msm7x27_surf MACH_MSM7X27_SURF MSM7X27_SURF 2705
+msm7x27_ffa MACH_MSM7X27_FFA MSM7X27_FFA 2706
+msm7x30_ffa MACH_MSM7X30_FFA MSM7X30_FFA 2707
+qsd8x50_surf MACH_QSD8X50_SURF QSD8X50_SURF 2708
+qsd8x50_comet MACH_QSD8X50_COMET QSD8X50_COMET 2709
+qsd8x50_ffa MACH_QSD8X50_FFA QSD8X50_FFA 2710
+qsd8x50a_surf MACH_QSD8X50A_SURF QSD8X50A_SURF 2711
+qsd8x50a_ffa MACH_QSD8X50A_FFA QSD8X50A_FFA 2712
+adx_xgcp10 MACH_ADX_XGCP10 ADX_XGCP10 2713
+mcgwumts2a MACH_MCGWUMTS2A MCGWUMTS2A 2714
+mobikt MACH_MOBIKT MOBIKT 2715
+mx53_evk MACH_MX53_EVK MX53_EVK 2716
+igep0030 MACH_IGEP0030 IGEP0030 2717
+axell_h40_h50_ctrl MACH_AXELL_H40_H50_CTRL AXELL_H40_H50_CTRL 2718
+dtcommod MACH_DTCOMMOD DTCOMMOD 2719
+gould MACH_GOULD GOULD 2720
+siberia MACH_SIBERIA SIBERIA 2721
+sbc3530 MACH_SBC3530 SBC3530 2722
+qarm MACH_QARM QARM 2723
+mips MACH_MIPS MIPS 2724
+mx27grb MACH_MX27GRB MX27GRB 2725
+sbc8100 MACH_SBC8100 SBC8100 2726
+saarb MACH_SAARB SAARB 2727
+omap3mini MACH_OMAP3MINI OMAP3MINI 2728
+cnmbook7se MACH_CNMBOOK7SE CNMBOOK7SE 2729
+catan MACH_CATAN CATAN 2730
+harmony MACH_HARMONY HARMONY 2731
+tonga MACH_TONGA TONGA 2732
+cybook_orizon MACH_CYBOOK_ORIZON CYBOOK_ORIZON 2733
+htcrhodiumcdma MACH_HTCRHODIUMCDMA HTCRHODIUMCDMA 2734
+epc_g45 MACH_EPC_G45 EPC_G45 2735
+epc_lpc3250 MACH_EPC_LPC3250 EPC_LPC3250 2736
+mxc91341evb MACH_MXC91341EVB MXC91341EVB 2737
+rtw1000 MACH_RTW1000 RTW1000 2738
+bobcat MACH_BOBCAT BOBCAT 2739
+trizeps6 MACH_TRIZEPS6 TRIZEPS6 2740
+msm7x30_fluid MACH_MSM7X30_FLUID MSM7X30_FLUID 2741
+nedap9263 MACH_NEDAP9263 NEDAP9263 2742
+netgear_ms2110 MACH_NETGEAR_MS2110 NETGEAR_MS2110 2743
+bmx MACH_BMX BMX 2744
+netstream MACH_NETSTREAM NETSTREAM 2745
+vpnext_rcu MACH_VPNEXT_RCU VPNEXT_RCU 2746
+vpnext_mpu MACH_VPNEXT_MPU VPNEXT_MPU 2747
+bcmring_tablet_v1 MACH_BCMRING_TABLET_V1 BCMRING_TABLET_V1 2748
+sgarm10 MACH_SGARM10 SGARM10 2749
+cm_t3517 MACH_CM_T3517 CM_T3517 2750
+omap3_cps MACH_OMAP3_CPS OMAP3_CPS 2751
+axar1500_receiver MACH_AXAR1500_RECEIVER AXAR1500_RECEIVER 2752
+wbd222 MACH_WBD222 WBD222 2753
+mt65xx MACH_MT65XX MT65XX 2754
+msm8x60_surf MACH_MSM8X60_SURF MSM8X60_SURF 2755
+msm8x60_sim MACH_MSM8X60_SIM MSM8X60_SIM 2756
+vmc300 MACH_VMC300 VMC300 2757
+tcc8000_sdk MACH_TCC8000_SDK TCC8000_SDK 2758
+nanos MACH_NANOS NANOS 2759
+stamp9g10 MACH_STAMP9G10 STAMP9G10 2760
+stamp9g45 MACH_STAMP9G45 STAMP9G45 2761
+h6053 MACH_H6053 H6053 2762
+smint01 MACH_SMINT01 SMINT01 2763
+prtlvt2 MACH_PRTLVT2 PRTLVT2 2764
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 7f3f59fcaa2..315a540c7ce 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -428,26 +428,6 @@ static void vfp_pm_init(void)
static inline void vfp_pm_init(void) { }
#endif /* CONFIG_PM */
-/*
- * Synchronise the hardware VFP state of a thread other than current with the
- * saved one. This function is used by the ptrace mechanism.
- */
-#ifdef CONFIG_SMP
-void vfp_sync_hwstate(struct thread_info *thread)
-{
-}
-
-void vfp_flush_hwstate(struct thread_info *thread)
-{
- /*
- * On SMP systems, the VFP state is automatically saved at every
- * context switch. We mark the thread VFP state as belonging to a
- * non-existent CPU so that the saved one will be reloaded when
- * needed.
- */
- thread->vfpstate.hard.cpu = NR_CPUS;
-}
-#else
void vfp_sync_hwstate(struct thread_info *thread)
{
unsigned int cpu = get_cpu();
@@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread)
last_VFP_context[cpu] = NULL;
}
+#ifdef CONFIG_SMP
+ /*
+ * For SMP we still have to take care of the case where the thread
+ * migrates to another CPU and then back to the original CPU on which
+ * the last VFP user is still the same thread. Mark the thread VFP
+ * state as belonging to a non-existent CPU so that the saved one will
+ * be reloaded in the above case.
+ */
+ thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
put_cpu();
}
-#endif
#include <linux/smp.h>
@@ -545,7 +534,7 @@ static int __init vfp_init(void)
*/
elf_hwcap |= HWCAP_VFP;
#ifdef CONFIG_VFPv3
- if (VFP_arch >= 3) {
+ if (VFP_arch >= 2) {
elf_hwcap |= HWCAP_VFPv3;
/*
diff --git a/arch/avr32/include/asm/ptrace.h b/arch/avr32/include/asm/ptrace.h
index 9e2d44f4e0f..e53dd0d900f 100644
--- a/arch/avr32/include/asm/ptrace.h
+++ b/arch/avr32/include/asm/ptrace.h
@@ -124,6 +124,8 @@ struct pt_regs {
#include <asm/ocd.h>
+#define arch_has_single_step() (1)
+
#define arch_ptrace_attach(child) ocd_enable(child)
#define user_mode(regs) (((regs)->sr & MODE_MASK) == MODE_USER)
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 93c0342530a..2d76515745a 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/pm.h>
#include <linux/ptrace.h>
+#include <linux/slab.h>
#include <linux/reboot.h>
#include <linux/tick.h>
#include <linux/uaccess.h>
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 1fed38fcf59..5e73c25f8f8 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -28,9 +28,9 @@ static struct pt_regs *get_user_regs(struct task_struct *tsk)
THREAD_SIZE - sizeof(struct pt_regs));
}
-static void ptrace_single_step(struct task_struct *tsk)
+void user_enable_single_step(struct task_struct *tsk)
{
- pr_debug("ptrace_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n",
+ pr_debug("user_enable_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n",
tsk->pid, task_pt_regs(tsk)->pc, task_pt_regs(tsk)->sr);
/*
@@ -49,6 +49,11 @@ static void ptrace_single_step(struct task_struct *tsk)
set_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
}
+void user_disable_single_step(struct task_struct *child)
+{
+ /* XXX(hch): a no-op here seems wrong.. */
+}
+
/*
* Called by kernel/ptrace.c when detaching
*
@@ -167,50 +172,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_write_user(child, addr, data);
break;
- /* continue and stop at next (return from) syscall */
- case PTRACE_SYSCALL:
- /* restart after signal */
- case PTRACE_CONT:
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- /* XXX: Are we sure no breakpoints are active here? */
- wake_up_process(child);
- ret = 0;
- break;
-
- /*
- * Make the child exit. Best I can do is send it a
- * SIGKILL. Perhaps it should be put in the status that it
- * wants to exit.
- */
- case PTRACE_KILL:
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE)
- break;
- child->exit_code = SIGKILL;
- wake_up_process(child);
- break;
-
- /*
- * execute single instruction.
- */
- case PTRACE_SINGLESTEP:
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- ptrace_single_step(child);
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
- break;
-
case PTRACE_GETREGS:
ret = ptrace_getregs(child, (void __user *)data);
break;
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 3a4bc1a1843..e67c9994542 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/usb/atmel_usba_udc.h>
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index 310477ba1bb..e9d12058ffd 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -14,6 +14,7 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <asm/io.h>
diff --git a/arch/avr32/mach-at32ap/hsmc.c b/arch/avr32/mach-at32ap/hsmc.c
index 2875c11be95..f7672d3e86b 100644
--- a/arch/avr32/mach-at32ap/hsmc.c
+++ b/arch/avr32/mach-at32ap/hsmc.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <mach/smc.h>
diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c
index 6d8c794c3b8..3c0042247ea 100644
--- a/arch/avr32/mm/dma-coherent.c
+++ b/arch/avr32/mm/dma-coherent.c
@@ -7,6 +7,7 @@
*/
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <asm/addrspace.h>
#include <asm/cacheflush.h>
diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c
index 94925641e53..a7314d44b17 100644
--- a/arch/avr32/mm/init.c
+++ b/arch/avr32/mm/init.c
@@ -7,6 +7,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/init.h>
diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c
index f03b79f0e0a..7def0d84cec 100644
--- a/arch/avr32/mm/ioremap.c
+++ b/arch/avr32/mm/ioremap.c
@@ -9,6 +9,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/pgtable.h>
#include <asm/addrspace.h>
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 53c1e1d45c6..c078849df7f 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -23,12 +23,15 @@ config RWSEM_XCHGADD_ALGORITHM
config BLACKFIN
def_bool y
+ select HAVE_ARCH_KGDB
+ select HAVE_ARCH_TRACEHOOK
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
+ select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_IDE
- select HAVE_KERNEL_GZIP
- select HAVE_KERNEL_BZIP2
- select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_GZIP if RAMKERNEL
+ select HAVE_KERNEL_BZIP2 if RAMKERNEL
+ select HAVE_KERNEL_LZMA if RAMKERNEL
select HAVE_OPROFILE
select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -45,9 +48,6 @@ config ZONE_DMA
config GENERIC_FIND_NEXT_BIT
def_bool y
-config GENERIC_HWEIGHT
- def_bool y
-
config GENERIC_HARDIRQS
def_bool y
@@ -239,7 +239,7 @@ endchoice
config SMP
depends on BF561
- select GENERIC_CLOCKEVENTS
+ select TICKSOURCE_CORETMR
bool "Symmetric multi-processing support"
---help---
This enables support for systems with more than one CPU,
@@ -253,11 +253,20 @@ config NR_CPUS
depends on SMP
default 2 if BF561
+config HOTPLUG_CPU
+ bool "Support for hot-pluggable CPUs"
+ depends on SMP && HOTPLUG
+ default y
+
config IRQ_PER_CPU
bool
depends on SMP
default y
+config HAVE_LEGACY_PER_CPU_AREA
+ def_bool y
+ depends on SMP
+
config BF_REV_MIN
int
default 0 if (BF51x || BF52x || (BF54x && !BF54xM))
@@ -349,7 +358,7 @@ config MEM_MT48LC8M32B2B5_7
config MEM_MT48LC32M16A2TG_75
bool
- depends on (BFIN527_EZKIT || BFIN532_IP0X || BLACKSTAMP)
+ depends on (BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN532_IP0X || BLACKSTAMP)
default y
config MEM_MT48LC32M8A2_75
@@ -401,10 +410,18 @@ config BOOT_LOAD
config ROM_BASE
hex "Kernel ROM Base"
depends on ROMKERNEL
- default "0x20040000"
+ default "0x20040040"
range 0x20000000 0x20400000 if !(BF54x || BF561)
range 0x20000000 0x30000000 if (BF54x || BF561)
help
+ Make sure your ROM base does not include any file-header
+ information that is prepended to the kernel.
+
+ For example, the bootable U-Boot format (created with
+ mkimage) has a 64 byte header (0x40). So while the image
+ you write to flash might start at say 0x20080000, you have
+ to add 0x40 to get the kernel's ROM base as it will come
+ after the header.
comment "Clock/PLL Setup"
@@ -448,7 +465,7 @@ config VCO_MULT
range 1 64
default "22" if BFIN533_EZKIT
default "45" if BFIN533_STAMP
- default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
+ default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
default "22" if BFIN533_BLUETECHNIX_CM
default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
default "20" if BFIN561_EZKIT
@@ -609,23 +626,23 @@ config GENERIC_CLOCKEVENTS
bool "Generic clock events"
default y
-choice
- prompt "Kernel Tick Source"
+menu "Clock event device"
depends on GENERIC_CLOCKEVENTS
- default TICKSOURCE_CORETMR
-
config TICKSOURCE_GPTMR0
- bool "Gptimer0 (SCLK domain)"
+ bool "GPTimer0"
+ depends on !SMP
select BFIN_GPTIMERS
config TICKSOURCE_CORETMR
- bool "Core timer (CCLK domain)"
-
-endchoice
+ bool "Core timer"
+ default y
+endmenu
-config CYCLES_CLOCKSOURCE
- bool "Use 'CYCLES' as a clocksource"
+menu "Clock souce"
depends on GENERIC_CLOCKEVENTS
+config CYCLES_CLOCKSOURCE
+ bool "CYCLES"
+ default y
depends on !BFIN_SCRATCH_REG_CYCLES
depends on !SMP
help
@@ -636,10 +653,10 @@ config CYCLES_CLOCKSOURCE
writing the registers will most likely crash the kernel.
config GPTMR0_CLOCKSOURCE
- bool "Use GPTimer0 as a clocksource"
+ bool "GPTimer0"
select BFIN_GPTIMERS
- depends on GENERIC_CLOCKEVENTS
depends on !TICKSOURCE_GPTMR0
+endmenu
config ARCH_USES_GETTIMEOFFSET
depends on !GENERIC_CLOCKEVENTS
@@ -1116,24 +1133,6 @@ config PCI
source "drivers/pci/Kconfig"
-config HOTPLUG
- bool "Support for hot-pluggable device"
- help
- Say Y here if you want to plug devices into your computer while
- the system is running, and be able to use them quickly. In many
- cases, the devices can likewise be unplugged at any time too.
-
- One well known example of this is PCMCIA- or PC-cards, credit-card
- size devices such as network cards, modems or hard drives which are
- plugged into slots found on all modern laptop computers. Another
- example, used on modern desktops as well as laptops, is USB.
-
- Enable HOTPLUG and build a modular kernel. Get agent software
- (from <http://linux-hotplug.sourceforge.net/>) and install it.
- Then your kernel will automatically call out to a user mode "policy
- agent" (/sbin/hotplug) to load modules and set up software needed
- to use devices as you hotplug them.
-
source "drivers/pcmcia/Kconfig"
source "drivers/pci/hotplug/Kconfig"
@@ -1147,7 +1146,6 @@ source "fs/Kconfig.binfmt"
endmenu
menu "Power management options"
- depends on !SMP
source "kernel/power/Kconfig"
@@ -1240,7 +1238,6 @@ config PM_BFIN_WAKE_GP
endmenu
menu "CPU Frequency scaling"
- depends on !SMP
source "drivers/cpufreq/Kconfig"
diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug
index 87f195ee2e0..aec89a5280b 100644
--- a/arch/blackfin/Kconfig.debug
+++ b/arch/blackfin/Kconfig.debug
@@ -18,9 +18,6 @@ config DEBUG_STACK_USAGE
This option will slow down process creation somewhat.
-config HAVE_ARCH_KGDB
- def_bool y
-
config DEBUG_VERBOSE
bool "Verbose fault messages"
default y
@@ -238,6 +235,15 @@ config EARLY_PRINTK
all of this lives in the init section and is thrown away after the
kernel boots completely.
+config NMI_WATCHDOG
+ bool "Enable NMI watchdog to help debugging lockup on SMP"
+ default n
+ depends on (SMP && !BFIN_SCRATCH_REG_RETN)
+ help
+ If any CPU in the system does not execute the period local timer
+ interrupt for more than 5 seconds, then the NMI handler dumps debug
+ information. This information can be used to debug the lockup.
+
config CPLB_INFO
bool "Display the CPLB information"
help
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index d4c7177e765..5a97a31d4bb 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -14,6 +14,9 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S
GZFLAGS := -9
KBUILD_CFLAGS += $(call cc-option,-mno-fdpic)
+ifeq ($(CONFIG_ROMKERNEL),y)
+KBUILD_CFLAGS += -mlong-calls
+endif
KBUILD_AFLAGS += $(call cc-option,-mno-fdpic)
CFLAGS_MODULE += -mlong-calls
LDFLAGS_MODULE += -m elf32bfin
@@ -130,7 +133,6 @@ KBUILD_CFLAGS += -Iarch/$(ARCH)/mach-$(MACHINE)/include
KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs))
CLEAN_FILES += \
- arch/$(ARCH)/include/asm/asm-offsets.h \
arch/$(ARCH)/kernel/asm-offsets.s \
archclean:
@@ -138,7 +140,7 @@ archclean:
INSTALL_PATH ?= /tftpboot
boot := arch/$(ARCH)/boot
-BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma
+BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip
PHONY += $(BOOT_TARGETS) install
KBUILD_IMAGE := $(boot)/vmImage
@@ -156,6 +158,7 @@ define archhelp
echo ' vmImage.bz2 - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)'
echo '* vmImage.gz - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)'
echo ' vmImage.lzma - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)'
+ echo ' vmImage.xip - XIP Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.xip)'
echo ' install - Install kernel using'
echo ' (your) ~/bin/$(INSTALLKERNEL) or'
echo ' (distribution) PATH: $(INSTALLKERNEL) or'
diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile
index e9c48c6f8c1..d1b3d6051fd 100644
--- a/arch/blackfin/boot/Makefile
+++ b/arch/blackfin/boot/Makefile
@@ -8,14 +8,18 @@
MKIMAGE := $(srctree)/scripts/mkuboot.sh
-targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma
-extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
+targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xip
+
+UIMAGE_OPTS-y :=
+UIMAGE_OPTS-$(CONFIG_RAMKERNEL) += -a $(CONFIG_BOOT_LOAD)
+UIMAGE_OPTS-$(CONFIG_ROMKERNEL) += -a $(CONFIG_ROM_BASE) -x
quiet_cmd_uimage = UIMAGE $@
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
- -C $(2) -n '$(MACHINE)-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
+ -C $(2) -n '$(MACHINE)-$(KERNELRELEASE)' \
-e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \
- -d $< $@
+ $(UIMAGE_OPTS-y) -d $< $@
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
@@ -29,6 +33,12 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
$(call if_changed,lzma)
+# The mkimage tool wants 64bytes prepended to the image
+quiet_cmd_mk_bin_xip = BIN $@
+ cmd_mk_bin_xip = ( printf '%64s' | tr ' ' '\377' ; cat $< ) > $@
+$(obj)/vmlinux.bin.xip: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,mk_bin_xip)
+
$(obj)/vmImage.bin: $(obj)/vmlinux.bin
$(call if_changed,uimage,none)
@@ -41,10 +51,15 @@ $(obj)/vmImage.gz: $(obj)/vmlinux.bin.gz
$(obj)/vmImage.lzma: $(obj)/vmlinux.bin.lzma
$(call if_changed,uimage,lzma)
+$(obj)/vmImage.xip: $(obj)/vmlinux.bin.xip
+ $(call if_changed,uimage,none)
+
suffix-y := bin
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
suffix-$(CONFIG_KERNEL_LZMA) := lzma
+suffix-$(CONFIG_ROMKERNEL) := xip
+
$(obj)/vmImage: $(obj)/vmImage.$(suffix-y)
@ln -sf $(notdir $<) $@
diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig
index e3155941981..cf7c9bc94f1 100644
--- a/arch/blackfin/configs/BF518F-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig
@@ -1,22 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -26,22 +31,41 @@ 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_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -101,7 +130,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF518=y
# CONFIG_BF537 is not set
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=0
@@ -154,8 +182,8 @@ CONFIG_BF_REV_0_0=y
# CONFIG_BF_REV_0_6 is not set
# CONFIG_BF_REV_ANY is not set
# CONFIG_BF_REV_NONE is not set
-CONFIG_BF51x=y
CONFIG_MEM_MT48LC32M8A2_75=y
+CONFIG_BF51x=y
CONFIG_BFIN518F_EZBRD=y
#
@@ -313,7 +341,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
@@ -322,16 +349,18 @@ CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
# Cache Support
#
CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -342,7 +371,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_MPU is not set
#
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
#
#
@@ -398,11 +427,6 @@ CONFIG_NET=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 is not set
@@ -426,7 +450,6 @@ CONFIG_IP_PNP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -437,6 +460,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -450,7 +474,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -461,13 +488,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -488,6 +510,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# 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
@@ -545,6 +568,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
#
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -560,6 +584,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=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
@@ -576,10 +605,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -614,6 +653,9 @@ CONFIG_PHYLIB=y
# 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
@@ -622,10 +664,14 @@ CONFIG_BFIN_MAC=y
CONFIG_BFIN_TX_DESC_NUM=10
CONFIG_BFIN_RX_DESC_NUM=20
# CONFIG_BFIN_MAC_RMII is not set
+CONFIG_BFIN_MAC_USE_HWSTAMP=y
# CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -634,15 +680,16 @@ CONFIG_BFIN_RX_DESC_NUM=20
# 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 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
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -677,7 +724,10 @@ CONFIG_INPUT=y
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
@@ -688,16 +738,13 @@ CONFIG_INPUT_MISC=y
#
# Character devices
#
-# CONFIG_AD9960 is not set
CONFIG_BFIN_DMA_INTERFACE=m
# CONFIG_BFIN_PPI is not set
# CONFIG_BFIN_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BFIN_SPI_ADC is not set
# CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
@@ -715,6 +762,7 @@ CONFIG_BFIN_JTAG_COMM=m
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_BFIN=y
CONFIG_SERIAL_BFIN_CONSOLE=y
CONFIG_SERIAL_BFIN_DMA=y
@@ -726,12 +774,10 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -739,6 +785,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -771,14 +818,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY 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
@@ -795,13 +834,18 @@ CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
#
# SPI Protocol Masters
#
-# CONFIG_SPI_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
@@ -817,6 +861,7 @@ CONFIG_GPIO_SYSFS=y
# 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:
@@ -827,11 +872,15 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -853,28 +902,20 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 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_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -912,10 +953,11 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
CONFIG_SDH_BFIN=m
CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND=y
-# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set
-# CONFIG_MMC_SPI is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
@@ -950,6 +992,7 @@ CONFIG_RTC_INTF_DEV=y
# 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
@@ -961,6 +1004,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -981,10 +1025,21 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_BFIN=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=m
@@ -994,9 +1049,13 @@ CONFIG_EXT2_FS=m
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=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
@@ -1006,6 +1065,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1027,13 +1091,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1042,8 +1102,8 @@ CONFIG_SYSFS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
-# CONFIG_YAFFS_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
@@ -1062,7 +1122,6 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1127,14 +1186,19 @@ 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_SECTION_MISMATCH=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
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
@@ -1142,31 +1206,39 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_SLAB 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_NOMMU_REGIONS 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_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
-
-#
-# 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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1191,6 +1263,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
#
# Security options
@@ -1199,14 +1272,14 @@ CONFIG_ACCESS_CHECK=y
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1238,11 +1311,13 @@ CONFIG_CRYPTO=y
#
# 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
@@ -1279,6 +1354,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1286,11 +1362,13 @@ CONFIG_CRYPTO=y
#
# 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=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1299,6 +1377,8 @@ 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/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig
index 075e0fdcb39..31c2a6db6ec 100644
--- a/arch/blackfin/configs/BF526-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF526-EZBRD_defconfig
@@ -1,22 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -26,22 +31,41 @@ 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_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -101,7 +130,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF526=y
# CONFIG_BF537 is not set
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=0
@@ -154,8 +182,7 @@ CONFIG_BF_REV_0_0=y
# CONFIG_BF_REV_0_6 is not set
# CONFIG_BF_REV_ANY is not set
# CONFIG_BF_REV_NONE is not set
-CONFIG_BF52x=y
-CONFIG_MEM_MT48LC32M16A2TG_75=y
+CONFIG_MEM_MT48H32M16LFCJ_75=y
CONFIG_IRQ_PLL_WAKEUP=7
CONFIG_IRQ_DMA0_ERROR=7
CONFIG_IRQ_DMAR0_BLK=7
@@ -200,7 +227,9 @@ CONFIG_IRQ_MEM_DMA1=13
CONFIG_IRQ_WATCH=13
CONFIG_IRQ_PORTF_INTA=13
CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
# CONFIG_BFIN527_EZKIT is not set
+# CONFIG_BFIN527_EZKIT_V2 is not set
# CONFIG_BFIN527_BLUETECHNIX_CM is not set
CONFIG_BFIN526_EZBRD=y
@@ -318,7 +347,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
@@ -327,16 +355,18 @@ CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
# Cache Support
#
CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -347,6 +377,10 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_MPU is not set
#
+# Asynchronous Memory Configuration
+#
+
+#
# EBIU_AMGCTL Global Control
#
CONFIG_C_AMCKEN=y
@@ -399,11 +433,6 @@ CONFIG_NET=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 is not set
@@ -427,7 +456,6 @@ CONFIG_IP_PNP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -438,6 +466,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -451,7 +480,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -462,13 +494,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -489,6 +516,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# 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
@@ -549,6 +577,7 @@ CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_DATAFLASH is not set
CONFIG_MTD_M25P80=y
CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -564,11 +593,6 @@ CONFIG_MTD_NAND=m
# 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
CONFIG_MTD_NAND_IDS=m
# CONFIG_MTD_NAND_BF5XX is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
@@ -578,6 +602,11 @@ CONFIG_MTD_NAND_IDS=m
# 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
@@ -595,10 +624,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -622,10 +661,6 @@ CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR 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 is not set
# CONFIG_SCSI_LOGGING is not set
@@ -642,6 +677,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL 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
@@ -666,6 +702,9 @@ CONFIG_PHYLIB=y
# 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
@@ -675,9 +714,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
CONFIG_BFIN_RX_DESC_NUM=20
CONFIG_BFIN_MAC_RMII=y
# CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -686,15 +728,16 @@ CONFIG_BFIN_MAC_RMII=y
# 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 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
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# USB Network Adapters
@@ -744,7 +787,11 @@ CONFIG_INPUT_MISC=y
# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_CM109 is not set
# CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
@@ -755,16 +802,13 @@ CONFIG_INPUT_MISC=y
#
# Character devices
#
-# CONFIG_AD9960 is not set
CONFIG_BFIN_DMA_INTERFACE=m
# CONFIG_BFIN_PPI is not set
# CONFIG_BFIN_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BFIN_SPI_ADC is not set
# CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
@@ -782,6 +826,7 @@ CONFIG_BFIN_JTAG_COMM=m
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_BFIN=y
CONFIG_SERIAL_BFIN_CONSOLE=y
CONFIG_SERIAL_BFIN_DMA=y
@@ -793,14 +838,10 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_BFIN_OTP=y
# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -808,6 +849,7 @@ CONFIG_BFIN_OTP=y
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
@@ -841,14 +883,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY 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
@@ -865,13 +899,18 @@ CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
@@ -887,6 +926,7 @@ CONFIG_GPIO_SYSFS=y
# 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:
@@ -897,11 +937,20 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD5252 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADCXX is not set
@@ -914,11 +963,13 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -934,17 +985,24 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1111 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_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 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_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
@@ -954,9 +1012,8 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -983,28 +1040,20 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 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_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -1026,7 +1075,6 @@ 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
#
@@ -1039,30 +1087,35 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
+# CONFIG_HID_DRAGONRISE is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
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 is not set
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_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=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
@@ -1088,6 +1141,7 @@ CONFIG_USB_MON=y
# 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
@@ -1118,18 +1172,17 @@ CONFIG_USB_INVENTRA_DMA=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
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
@@ -1165,7 +1218,6 @@ CONFIG_USB_STORAGE=y
# 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
@@ -1177,6 +1229,13 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1212,6 +1271,7 @@ CONFIG_RTC_INTF_DEV=y
# 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
@@ -1223,6 +1283,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1243,10 +1304,21 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_BFIN=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=m
@@ -1256,9 +1328,13 @@ CONFIG_EXT2_FS=m
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=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
@@ -1268,6 +1344,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
@@ -1291,13 +1372,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1316,17 +1393,8 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
# 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
@@ -1345,7 +1413,6 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1360,7 +1427,7 @@ CONFIG_SMB_FS=m
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=m
+CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=m
# CONFIG_NLS_CODEPAGE_737 is not set
@@ -1410,14 +1477,19 @@ 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_SECTION_MISMATCH=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
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
@@ -1425,31 +1497,39 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_SLAB 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_NOMMU_REGIONS 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_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
-
-#
-# 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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1474,6 +1554,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
#
# Security options
@@ -1482,15 +1563,15 @@ CONFIG_ACCESS_CHECK=y
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1522,11 +1603,13 @@ CONFIG_CRYPTO=y
#
# 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
@@ -1563,6 +1646,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1570,11 +1654,13 @@ CONFIG_CRYPTO=y
#
# 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=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1584,6 +1670,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/BF527-EZKIT-V2_defconfig b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
new file mode 100644
index 00000000000..d2dfcb0e7ce
--- /dev/null
+++ b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
@@ -0,0 +1,1811 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32.2
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=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_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# 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_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 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 is not set
+CONFIG_EPOLL=y
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=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 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 is not set
+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_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
+# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
+# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
+CONFIG_BF527=y
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
+# CONFIG_BF542_std is not set
+# CONFIG_BF542M is not set
+# CONFIG_BF544_std is not set
+# CONFIG_BF544M is not set
+# CONFIG_BF547_std is not set
+# CONFIG_BF547M is not set
+# CONFIG_BF548_std is not set
+# CONFIG_BF548M is not set
+# CONFIG_BF549_std is not set
+# CONFIG_BF549M is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=0
+CONFIG_BF_REV_MAX=2
+# CONFIG_BF_REV_0_0 is not set
+# CONFIG_BF_REV_0_1 is not set
+CONFIG_BF_REV_0_2=y
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_MEM_MT48LC32M16A2TG_75=y
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TIMER0=8
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
+# CONFIG_BFIN527_EZKIT is not set
+CONFIG_BFIN527_EZKIT_V2=y
+# CONFIG_BFIN527_BLUETECHNIX_CM is not set
+# CONFIG_BFIN526_EZBRD is not set
+
+#
+# BF527 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF527_SPORT0_PORTF is not set
+CONFIG_BF527_SPORT0_PORTG=y
+CONFIG_BF527_SPORT0_TSCLK_PG10=y
+# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
+CONFIG_BF527_UART1_PORTF=y
+# CONFIG_BF527_UART1_PORTG is not set
+# CONFIG_BF527_NAND_D_PORTF is not set
+CONFIG_BF527_NAND_D_PORTH=y
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_SPI=10
+CONFIG_IRQ_SPI_ERROR=7
+CONFIG_IRQ_NFC_ERROR=7
+CONFIG_IRQ_HDMA_ERROR=7
+CONFIG_IRQ_HDMA=7
+CONFIG_IRQ_USB_EINT=10
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133333333
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# 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_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Misc
+#
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL 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_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=y
+# CONFIG_DMA_UNCACHED_4M is not set
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+CONFIG_BFIN_EXTMEM_DCACHEABLE=y
+CONFIG_BFIN_EXTMEM_WRITEBACK=y
+# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
+
+#
+# Memory Protection Unit
+#
+# CONFIG_MPU is not set
+
+#
+# Asynchronous Memory Configuration
+#
+
+#
+# EBIU_AMGCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B2
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+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=y
+# CONFIG_IP_PNP_DHCP is not set
+# 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 is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_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_NETLABEL 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=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+CONFIG_BFIN_SIR=m
+CONFIG_BFIN_SIR0=y
+CONFIG_SIR_BFIN_DMA=y
+# CONFIG_SIR_BFIN_PIO is not set
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_MCS_FIR 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_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_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+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 is not set
+CONFIG_MTD_JEDECPROBE=m
+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 is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_GPIO_ADDR is not set
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# 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=m
+# 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_IDS=m
+# CONFIG_MTD_NAND_BF5XX is not set
+# 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_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 is not set
+# 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 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_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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 is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# 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=m
+# CONFIG_BLK_DEV_SR_VENDOR 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 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 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 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_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+CONFIG_BFIN_MAC_RMII=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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 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_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=m
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ADP5520=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 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_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+CONFIG_TOUCHSCREEN_AD7879_I2C=y
+CONFIG_TOUCHSCREEN_AD7879=y
+# 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_WM97XX is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 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
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
+# CONFIG_BFIN_SIMPLE_TIMER is not set
+# CONFIG_BFIN_SPI_ADC is not set
+CONFIG_BFIN_SPORT=m
+# CONFIG_BFIN_TWI_LCD is not set
+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 is not set
+CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_DMA=y
+# CONFIG_SERIAL_BFIN_PIO is not set
+# CONFIG_SERIAL_BFIN_UART0 is not set
+CONFIG_SERIAL_BFIN_UART1=y
+# CONFIG_BFIN_UART1_CTSRTS is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE 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=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
+# CONFIG_I2C_GPIO is not set
+# 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
+
+#
+# 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_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=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5520 is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+
+#
+# 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_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+CONFIG_PMIC_ADP5520=y
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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=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_BFIN_T350MCQB is not set
+CONFIG_FB_BFIN_LQ035Q1=y
+# CONFIG_FB_BFIN_7393 is not set
+# 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=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP5520 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+
+#
+# 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 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 is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_BLACKFIN_VGA16 is not set
+CONFIG_LOGO_BLACKFIN_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_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_SPI=y
+
+#
+# ALSA Blackfin devices
+#
+# CONFIG_SND_BFIN_AD73322 is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_BF5XX_I2S=m
+CONFIG_SND_BF5XX_SOC_SSM2602=m
+# CONFIG_SND_BF5XX_SOC_AD73311 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
+# CONFIG_SND_BF5XX_TDM is not set
+CONFIG_SND_BF5XX_AC97=m
+CONFIG_SND_BF5XX_MMAP_SUPPORT=y
+# CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
+CONFIG_SND_BF5XX_SOC_SPORT=m
+CONFIG_SND_BF5XX_SOC_I2S=m
+CONFIG_SND_BF5XX_SOC_AC97=m
+CONFIG_SND_BF5XX_SPORT_NUM=0
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AD1980=m
+CONFIG_SND_SOC_SSM2602=m
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# 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_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
+CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+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 is not set
+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_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=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 is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+CONFIG_USB_OTG_BLACKLIST_HUB=y
+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
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# Blackfin high speed USB Support
+#
+CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# 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=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_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_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_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+CONFIG_LEDS_ADP5520=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS 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 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_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
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# 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_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR 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_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=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# 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=m
+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_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=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+# 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=m
+# 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=m
+# 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_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+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_DEBUG_SLAB 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_NOMMU_REGIONS 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_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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES 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_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_VERBOSE=y
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HWERR=y
+CONFIG_EXACT_HWERR=y
+CONFIG_DEBUG_DOUBLEFAULT=y
+CONFIG_DEBUG_DOUBLEFAULT_PRINT=y
+# CONFIG_DEBUG_DOUBLEFAULT_RESET is not set
+# CONFIG_DEBUG_ICACHE_CHECK is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=1
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_TOMOYO is not set
+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_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 is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index 6d1a623fb14..edbb44d26bb 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -1,22 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -26,22 +31,41 @@ 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_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
@@ -132,29 +160,28 @@ CONFIG_BF527=y
# CONFIG_BF537 is not set
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=0
CONFIG_BF_REV_MAX=2
# CONFIG_BF_REV_0_0 is not set
-# CONFIG_BF_REV_0_1 is not set
-CONFIG_BF_REV_0_2=y
+CONFIG_BF_REV_0_1=y
+# CONFIG_BF_REV_0_2 is not set
# CONFIG_BF_REV_0_3 is not set
# CONFIG_BF_REV_0_4 is not set
# CONFIG_BF_REV_0_5 is not set
# CONFIG_BF_REV_0_6 is not set
# CONFIG_BF_REV_ANY is not set
# CONFIG_BF_REV_NONE is not set
-CONFIG_BF52x=y
CONFIG_MEM_MT48LC32M16A2TG_75=y
CONFIG_IRQ_PLL_WAKEUP=7
CONFIG_IRQ_DMA0_ERROR=7
@@ -200,7 +227,9 @@ CONFIG_IRQ_MEM_DMA1=13
CONFIG_IRQ_WATCH=13
CONFIG_IRQ_PORTF_INTA=13
CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
CONFIG_BFIN527_EZKIT=y
+# CONFIG_BFIN527_EZKIT_V2 is not set
# CONFIG_BFIN527_BLUETECHNIX_CM is not set
# CONFIG_BFIN526_EZBRD is not set
@@ -318,7 +347,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
@@ -327,16 +355,18 @@ CONFIG_BFIN_GPTIMERS=y
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
# Cache Support
#
CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -347,7 +377,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_MPU is not set
#
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
#
#
@@ -403,11 +433,6 @@ CONFIG_NET=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 is not set
@@ -431,7 +456,6 @@ CONFIG_IP_PNP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -442,6 +466,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -455,7 +480,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -508,13 +536,8 @@ CONFIG_SIR_BFIN_DMA=y
# CONFIG_MCS_FIR 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_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -535,6 +558,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# 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
@@ -593,6 +617,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
# CONFIG_MTD_DATAFLASH is not set
CONFIG_MTD_M25P80=y
CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -608,11 +633,6 @@ CONFIG_MTD_NAND=m
# 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
CONFIG_MTD_NAND_IDS=m
# CONFIG_MTD_NAND_BF5XX is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
@@ -622,6 +642,11 @@ CONFIG_MTD_NAND_IDS=m
# 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
@@ -639,10 +664,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -666,10 +701,6 @@ CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR 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 is not set
# CONFIG_SCSI_LOGGING is not set
@@ -686,6 +717,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL 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
@@ -710,6 +742,9 @@ CONFIG_PHYLIB=y
# 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
@@ -720,9 +755,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
CONFIG_BFIN_RX_DESC_NUM=20
CONFIG_BFIN_MAC_RMII=y
# CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -731,15 +769,16 @@ CONFIG_BFIN_MAC_RMII=y
# 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 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
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# USB Network Adapters
@@ -789,7 +828,11 @@ CONFIG_INPUT_MISC=y
# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_CM109 is not set
# CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
@@ -800,16 +843,13 @@ CONFIG_INPUT_MISC=y
#
# Character devices
#
-# CONFIG_AD9960 is not set
CONFIG_BFIN_DMA_INTERFACE=m
# CONFIG_BFIN_PPI is not set
# CONFIG_BFIN_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BFIN_SPI_ADC is not set
CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
@@ -827,6 +867,7 @@ CONFIG_BFIN_JTAG_COMM=m
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_BFIN=y
CONFIG_SERIAL_BFIN_CONSOLE=y
CONFIG_SERIAL_BFIN_DMA=y
@@ -838,14 +879,10 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_BFIN_OTP=y
# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -853,6 +890,7 @@ CONFIG_BFIN_OTP=y
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
@@ -886,14 +924,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY 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
@@ -910,13 +940,18 @@ CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
@@ -932,6 +967,7 @@ CONFIG_GPIO_SYSFS=y
# 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:
@@ -942,11 +978,15 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -973,28 +1013,21 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 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_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -1030,15 +1063,18 @@ CONFIG_FB_BFIN_T350MCQB=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=y
CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_LMS283GF05 is not set
CONFIG_LCD_LTV350QV=m
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_TDO24M is not set
# CONFIG_LCD_VGG2432A4 is not set
# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=m
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP8870 is not set
#
# Display device support
@@ -1066,6 +1102,7 @@ CONFIG_SOUND=m
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
@@ -1074,6 +1111,11 @@ 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
@@ -1084,7 +1126,6 @@ CONFIG_SND_SPI=y
#
# ALSA Blackfin devices
#
-# CONFIG_SND_BLACKFIN_AD1836 is not set
# CONFIG_SND_BFIN_AD73322 is not set
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
@@ -1094,15 +1135,19 @@ CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_BF5XX_I2S=m
CONFIG_SND_BF5XX_SOC_SSM2602=m
# CONFIG_SND_BF5XX_SOC_AD73311 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
+# CONFIG_SND_BF5XX_TDM is not set
CONFIG_SND_BF5XX_AC97=m
CONFIG_SND_BF5XX_MMAP_SUPPORT=y
# CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
CONFIG_SND_BF5XX_SOC_SPORT=m
CONFIG_SND_BF5XX_SOC_I2S=m
CONFIG_SND_BF5XX_SOC_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
CONFIG_SND_BF5XX_SPORT_NUM=0
-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
# CONFIG_SND_SOC_ALL_CODECS is not set
CONFIG_SND_SOC_AD1980=m
CONFIG_SND_SOC_SSM2602=m
@@ -1110,7 +1155,6 @@ CONFIG_SND_SOC_SSM2602=m
CONFIG_AC97_BUS=m
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1123,30 +1167,35 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
+# CONFIG_HID_DRAGONRISE is not set
CONFIG_HID_EZKEY=y
+# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
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 is not set
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_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=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
@@ -1172,6 +1221,7 @@ CONFIG_USB_MON=y
# 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
@@ -1188,9 +1238,7 @@ CONFIG_USB_MUSB_HOST=y
# CONFIG_USB_MUSB_PERIPHERAL is not set
# CONFIG_USB_MUSB_OTG is not set
CONFIG_USB_MUSB_HDRC_HCD=y
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_USB_INVENTRA_DMA=y
-# CONFIG_USB_TI_CPPI_DMA is not set
+CONFIG_MUSB_PIO_ONLY=y
# CONFIG_USB_MUSB_DEBUG is not set
#
@@ -1202,18 +1250,17 @@ CONFIG_USB_INVENTRA_DMA=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
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
@@ -1249,7 +1296,6 @@ CONFIG_USB_STORAGE=y
# 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
@@ -1261,6 +1307,13 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1296,6 +1349,7 @@ CONFIG_RTC_INTF_DEV=y
# 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
@@ -1307,6 +1361,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1327,10 +1382,21 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_BFIN=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=m
@@ -1340,9 +1406,13 @@ CONFIG_EXT2_FS=m
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=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
@@ -1352,6 +1422,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
@@ -1376,13 +1451,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1401,17 +1472,8 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
# 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
@@ -1430,7 +1492,6 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1445,7 +1506,7 @@ CONFIG_SMB_FS=m
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=m
+CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=m
# CONFIG_NLS_CODEPAGE_737 is not set
@@ -1495,14 +1556,19 @@ 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_SECTION_MISMATCH=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
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
@@ -1510,31 +1576,39 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_SLAB 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_NOMMU_REGIONS 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_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
-
-#
-# 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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1559,6 +1633,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
#
# Security options
@@ -1567,15 +1642,15 @@ CONFIG_ACCESS_CHECK=y
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1607,11 +1682,13 @@ CONFIG_CRYPTO=y
#
# 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
@@ -1648,6 +1725,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1655,11 +1733,13 @@ CONFIG_CRYPTO=y
#
# 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=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1669,6 +1749,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 50f9a23ccdb..0b13d5836a4 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -1,22 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -26,22 +31,41 @@ 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_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF533=y
# CONFIG_BF537 is not set
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=3
@@ -228,7 +256,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_TICKSOURCE_GPTMR0 is not set
CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
# CONFIG_GPTMR0_CLOCKSOURCE is not set
CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
@@ -280,7 +308,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
@@ -289,19 +316,18 @@ CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
# Cache Support
#
-#
-# Cache Support
-#
CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -312,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_MPU is not set
#
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
#
#
@@ -358,6 +384,7 @@ CONFIG_PM=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_PM_BFIN_SLEEP_DEEPER=y
# CONFIG_PM_BFIN_SLEEP is not set
@@ -379,11 +406,6 @@ CONFIG_NET=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 is not set
@@ -407,7 +429,6 @@ CONFIG_IP_PNP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -418,6 +439,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -431,7 +453,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -475,13 +500,8 @@ CONFIG_IRTTY_SIR=m
#
# 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_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -502,6 +522,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# 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
@@ -559,6 +580,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
#
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -574,6 +596,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=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
@@ -590,9 +617,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -616,9 +648,12 @@ CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -627,15 +662,16 @@ CONFIG_SMC91X=y
# 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 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
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -679,15 +715,12 @@ CONFIG_INPUT_EVDEV=m
#
# Character devices
#
-# CONFIG_AD9960 is not set
CONFIG_BFIN_DMA_INTERFACE=m
# CONFIG_BFIN_PPI is not set
# CONFIG_BFIN_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BFIN_SPI_ADC is not set
CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_SIMPLE_GPIO=m
# CONFIG_VT is not set
# CONFIG_DEVKMEM is not set
CONFIG_BFIN_JTAG_COMM=m
@@ -701,6 +734,7 @@ CONFIG_BFIN_JTAG_COMM=m
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_BFIN=y
CONFIG_SERIAL_BFIN_CONSOLE=y
CONFIG_SERIAL_BFIN_DMA=y
@@ -711,12 +745,8 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -734,13 +764,18 @@ CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
@@ -753,9 +788,6 @@ CONFIG_GPIO_SYSFS=y
#
# I2C GPIO expanders:
#
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
#
# PCI GPIO expanders:
@@ -766,11 +798,15 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -793,23 +829,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_EZX_PCAP 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -826,14 +849,12 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=m
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -864,6 +885,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -884,10 +906,20 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_BFIN=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -896,9 +928,13 @@ CONFIG_RTC_DRV_BFIN=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=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
@@ -908,6 +944,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -926,13 +967,9 @@ CONFIG_INOTIFY_USER=y
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -951,17 +988,8 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
# 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
@@ -980,7 +1008,6 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1045,14 +1072,19 @@ 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_SECTION_MISMATCH=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
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
@@ -1060,31 +1092,39 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_SLAB 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_NOMMU_REGIONS 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_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
-
-#
-# 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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1109,6 +1149,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
#
# Security options
@@ -1117,14 +1158,14 @@ CONFIG_ACCESS_CHECK=y
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1156,11 +1197,13 @@ CONFIG_CRYPTO=y
#
# 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
@@ -1197,6 +1240,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1204,11 +1248,13 @@ CONFIG_CRYPTO=y
#
# 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=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1218,6 +1264,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index 6c60c828631..c3fe6e5b612 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -1,22 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -26,22 +31,41 @@ 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_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF533=y
# CONFIG_BF537 is not set
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=3
@@ -228,7 +256,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_TICKSOURCE_GPTMR0 is not set
CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
# CONFIG_GPTMR0_CLOCKSOURCE is not set
CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
@@ -280,7 +308,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
@@ -289,16 +316,18 @@ CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
# Cache Support
#
CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -309,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_MPU is not set
#
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
#
#
@@ -355,6 +384,7 @@ CONFIG_PM=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_PM_BFIN_SLEEP_DEEPER=y
# CONFIG_PM_BFIN_SLEEP is not set
@@ -376,11 +406,6 @@ CONFIG_NET=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 is not set
@@ -404,7 +429,6 @@ CONFIG_IP_PNP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -415,6 +439,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -428,7 +453,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -474,13 +502,8 @@ CONFIG_SIR_BFIN_DMA=y
#
# 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_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -501,6 +524,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# 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
@@ -560,6 +584,7 @@ CONFIG_MTD_BFIN_ASYNC=m
#
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -575,6 +600,11 @@ CONFIG_MTD_BFIN_ASYNC=m
# 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
@@ -591,10 +621,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -618,9 +658,12 @@ CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -629,15 +672,16 @@ CONFIG_SMC91X=y
# 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 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
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -672,7 +716,10 @@ CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_UINPUT is not set
-CONFIG_CONFIG_INPUT_PCF8574=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
@@ -683,16 +730,13 @@ CONFIG_CONFIG_INPUT_PCF8574=m
#
# Character devices
#
-# CONFIG_AD9960 is not set
CONFIG_BFIN_DMA_INTERFACE=m
# CONFIG_BFIN_PPI is not set
# CONFIG_BFIN_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BFIN_SPI_ADC is not set
CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
# CONFIG_VT is not set
# CONFIG_DEVKMEM is not set
CONFIG_BFIN_JTAG_COMM=m
@@ -706,6 +750,7 @@ CONFIG_BFIN_JTAG_COMM=m
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_BFIN=y
CONFIG_SERIAL_BFIN_CONSOLE=y
CONFIG_SERIAL_BFIN_DMA=y
@@ -716,12 +761,8 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -729,6 +770,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_TCG_TPM is not set
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
@@ -759,14 +801,6 @@ CONFIG_I2C_HELPER_AUTO=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY 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
@@ -783,13 +817,18 @@ CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
@@ -805,6 +844,7 @@ CONFIG_GPIO_SYSFS=y
# 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:
@@ -815,11 +855,15 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -841,26 +885,18 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -904,6 +940,7 @@ CONFIG_ADV7393_1XMEM=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
#
@@ -913,19 +950,27 @@ CONFIG_ADV7393_1XMEM=y
# CONFIG_LOGO is not set
CONFIG_SOUND=m
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_PCM_OSS_PLUGINS=y
+# 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
@@ -936,13 +981,6 @@ CONFIG_SND_SPI=y
#
# ALSA Blackfin devices
#
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
CONFIG_SND_BFIN_SPORT=0
CONFIG_SND_BFIN_AD73322=m
CONFIG_SND_BFIN_AD73322_SPORT0_SE=10
@@ -953,16 +991,20 @@ CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_BF5XX_I2S=m
# CONFIG_SND_BF5XX_SOC_SSM2602 is not set
CONFIG_SND_BF5XX_SOC_AD73311=m
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
CONFIG_SND_BFIN_AD73311_SE=4
+# CONFIG_SND_BF5XX_TDM is not set
CONFIG_SND_BF5XX_AC97=m
CONFIG_SND_BF5XX_MMAP_SUPPORT=y
# CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
CONFIG_SND_BF5XX_SOC_SPORT=m
CONFIG_SND_BF5XX_SOC_I2S=m
CONFIG_SND_BF5XX_SOC_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
CONFIG_SND_BF5XX_SPORT_NUM=0
-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
# CONFIG_SND_SOC_ALL_CODECS is not set
CONFIG_SND_SOC_AD1980=m
CONFIG_SND_SOC_AD73311=m
@@ -970,14 +1012,12 @@ CONFIG_SND_SOC_AD73311=m
CONFIG_AC97_BUS=m
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1014,6 +1054,7 @@ CONFIG_RTC_INTF_DEV=y
# 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
@@ -1025,6 +1066,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1045,10 +1087,21 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_BFIN=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -1057,9 +1110,13 @@ CONFIG_RTC_DRV_BFIN=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=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
@@ -1069,6 +1126,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1087,13 +1149,9 @@ CONFIG_INOTIFY_USER=y
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1112,17 +1170,8 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
# 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
@@ -1141,7 +1190,6 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1206,14 +1254,19 @@ 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_SECTION_MISMATCH=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
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
@@ -1221,31 +1274,39 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_SLAB 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_NOMMU_REGIONS 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_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
-
-#
-# 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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1270,6 +1331,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
#
# Security options
@@ -1278,14 +1340,14 @@ CONFIG_ACCESS_CHECK=y
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1317,11 +1379,13 @@ CONFIG_CRYPTO=y
#
# 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
@@ -1358,6 +1422,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1365,11 +1430,13 @@ CONFIG_CRYPTO=y
#
# 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=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1379,6 +1446,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index 2908595b67c..7596cf7673f 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -1,22 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -26,22 +31,41 @@ 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_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_FREEZER=y
CONFIG_BF537=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=2
@@ -184,7 +212,8 @@ CONFIG_IRQ_MEM_DMA1=13
CONFIG_IRQ_WATCH=13
CONFIG_IRQ_SPI=10
CONFIG_BFIN537_STAMP=y
-# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set
# CONFIG_BFIN537_BLUETECHNIX_TCM is not set
# CONFIG_PNAV10 is not set
# CONFIG_CAMSIG_MINOTAUR is not set
@@ -235,7 +264,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_TICKSOURCE_GPTMR0 is not set
CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
# CONFIG_GPTMR0_CLOCKSOURCE is not set
CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
@@ -287,7 +316,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
@@ -296,16 +324,18 @@ CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
# Cache Support
#
CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -316,7 +346,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_MPU is not set
#
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
#
#
@@ -362,6 +392,7 @@ CONFIG_PM=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_PM_BFIN_SLEEP_DEEPER=y
# CONFIG_PM_BFIN_SLEEP is not set
@@ -384,11 +415,6 @@ CONFIG_NET=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 is not set
@@ -412,7 +438,6 @@ CONFIG_IP_PNP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -423,6 +448,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -436,14 +462,34 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
CONFIG_IRDA=m
#
@@ -483,13 +529,8 @@ CONFIG_SIR_BFIN_DMA=y
#
# 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_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -510,6 +551,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# 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
@@ -568,6 +610,7 @@ CONFIG_MTD_PHYSMAP=m
#
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -583,6 +626,11 @@ CONFIG_MTD_PHYSMAP=m
# 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
@@ -599,10 +647,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -637,6 +695,9 @@ CONFIG_SMSC_PHY=y
# 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
@@ -647,9 +708,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
CONFIG_BFIN_RX_DESC_NUM=20
# CONFIG_BFIN_MAC_RMII is not set
# CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -658,15 +722,16 @@ CONFIG_BFIN_RX_DESC_NUM=20
# 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 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
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -701,7 +766,10 @@ CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_UINPUT is not set
-CONFIG_CONFIG_INPUT_PCF8574=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
@@ -712,16 +780,13 @@ CONFIG_CONFIG_INPUT_PCF8574=m
#
# Character devices
#
-# CONFIG_AD9960 is not set
CONFIG_BFIN_DMA_INTERFACE=m
# CONFIG_BFIN_PPI is not set
# CONFIG_BFIN_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BFIN_SPI_ADC is not set
CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
# CONFIG_VT is not set
# CONFIG_DEVKMEM is not set
CONFIG_BFIN_JTAG_COMM=m
@@ -735,6 +800,7 @@ CONFIG_BFIN_JTAG_COMM=m
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_BFIN=y
CONFIG_SERIAL_BFIN_CONSOLE=y
CONFIG_SERIAL_BFIN_DMA=y
@@ -746,17 +812,8 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-CONFIG_CAN4LINUX=y
-
-#
-# linux embedded drivers
-#
-CONFIG_CAN_BLACKFIN=m
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -764,6 +821,7 @@ CONFIG_CAN_BLACKFIN=m
# CONFIG_TCG_TPM is not set
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
@@ -796,14 +854,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_SENSORS_AD5252=m
-# CONFIG_EEPROM_LEGACY 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
@@ -820,13 +870,18 @@ CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
@@ -842,6 +897,7 @@ CONFIG_GPIO_SYSFS=y
# 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:
@@ -852,11 +908,15 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -878,26 +938,18 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -929,9 +981,6 @@ CONFIG_FB_CFB_IMAGEBLIT=m
# CONFIG_FB_BFIN_T350MCQB is not set
# CONFIG_FB_BFIN_LQ035Q1 is not set
CONFIG_FB_BF537_LQ035=m
-CONFIG_LQ035_SLAVE_ADDR=0x58
-# CONFIG_FB_BFIN_LANDSCAPE is not set
-# CONFIG_FB_BFIN_BGR is not set
CONFIG_FB_BFIN_7393=m
CONFIG_NTSC=y
# CONFIG_PAL is not set
@@ -946,15 +995,18 @@ CONFIG_ADV7393_1XMEM=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=y
CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_LMS283GF05 is not set
# CONFIG_LCD_LTV350QV is not set
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_TDO24M is not set
# CONFIG_LCD_VGG2432A4 is not set
# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_CORGI=m
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP8870 is not set
#
# Display device support
@@ -963,19 +1015,27 @@ CONFIG_BACKLIGHT_CORGI=m
# CONFIG_LOGO is not set
CONFIG_SOUND=m
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_PCM_OSS_PLUGINS=y
+# 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
@@ -986,13 +1046,6 @@ CONFIG_SND_SPI=y
#
# ALSA Blackfin devices
#
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
CONFIG_SND_BFIN_SPORT=0
CONFIG_SND_BFIN_AD73322=m
CONFIG_SND_BFIN_AD73322_SPORT0_SE=10
@@ -1003,16 +1056,20 @@ CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_BF5XX_I2S=m
# CONFIG_SND_BF5XX_SOC_SSM2602 is not set
CONFIG_SND_BF5XX_SOC_AD73311=m
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
CONFIG_SND_BFIN_AD73311_SE=4
+# CONFIG_SND_BF5XX_TDM is not set
CONFIG_SND_BF5XX_AC97=m
CONFIG_SND_BF5XX_MMAP_SUPPORT=y
# CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
CONFIG_SND_BF5XX_SOC_SPORT=m
CONFIG_SND_BF5XX_SOC_I2S=m
CONFIG_SND_BF5XX_SOC_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
CONFIG_SND_BF5XX_SPORT_NUM=0
-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
# CONFIG_SND_SOC_ALL_CODECS is not set
CONFIG_SND_SOC_AD1980=m
CONFIG_SND_SOC_AD73311=m
@@ -1020,14 +1077,12 @@ CONFIG_SND_SOC_AD73311=m
CONFIG_AC97_BUS=m
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1064,6 +1119,7 @@ CONFIG_RTC_INTF_DEV=y
# 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
@@ -1075,6 +1131,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1095,10 +1152,21 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_BFIN=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -1107,9 +1175,13 @@ CONFIG_RTC_DRV_BFIN=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=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
@@ -1119,6 +1191,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1137,13 +1214,9 @@ CONFIG_INOTIFY_USER=y
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1162,17 +1235,8 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
# 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
@@ -1191,7 +1255,6 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1256,14 +1319,19 @@ 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_SECTION_MISMATCH=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
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
@@ -1271,31 +1339,39 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_SLAB 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_NOMMU_REGIONS 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_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
-
-#
-# 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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1320,6 +1396,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
#
# Security options
@@ -1328,14 +1405,14 @@ CONFIG_ACCESS_CHECK=y
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1367,11 +1444,13 @@ CONFIG_CRYPTO=y
#
# 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
@@ -1408,6 +1487,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1415,11 +1495,13 @@ CONFIG_CRYPTO=y
#
# 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=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1429,6 +1511,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig
index 09ea2499555..bc1871d89fd 100644
--- a/arch/blackfin/configs/BF538-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF538-EZKIT_defconfig
@@ -1,22 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -26,22 +31,41 @@ 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_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_BF537 is not set
CONFIG_BF538=y
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=4
@@ -246,7 +274,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_TICKSOURCE_GPTMR0 is not set
CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
# CONFIG_GPTMR0_CLOCKSOURCE is not set
CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
@@ -298,7 +326,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
@@ -307,16 +334,18 @@ CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
# Cache Support
#
CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -327,7 +356,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_MPU is not set
#
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
#
#
@@ -383,11 +412,6 @@ CONFIG_NET=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 is not set
@@ -411,7 +435,6 @@ CONFIG_IP_PNP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -422,6 +445,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -435,14 +459,34 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
CONFIG_IRDA=m
#
@@ -481,13 +525,8 @@ CONFIG_SIR_BFIN_DMA=y
#
# 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_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -508,6 +547,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# 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
@@ -566,6 +606,7 @@ CONFIG_MTD_PHYSMAP=m
#
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -581,11 +622,6 @@ CONFIG_MTD_NAND=m
# 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
CONFIG_MTD_NAND_IDS=m
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
@@ -593,6 +629,11 @@ CONFIG_MTD_NAND_IDS=m
# 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
@@ -643,14 +684,20 @@ CONFIG_SMSC_PHY=y
# 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_SMC91X=y
-# CONFIG_SMSC911X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -659,15 +706,16 @@ CONFIG_SMC91X=y
# 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 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
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -700,14 +748,17 @@ CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
# CONFIG_TOUCHSCREEN_AD7877 is not set
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
CONFIG_TOUCHSCREEN_AD7879_SPI=y
CONFIG_TOUCHSCREEN_AD7879=y
-# CONFIG_TOUCHSCREEN_ADS7846 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
@@ -715,9 +766,13 @@ CONFIG_TOUCHSCREEN_AD7879=y
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
@@ -728,16 +783,13 @@ CONFIG_INPUT_MISC=y
#
# Character devices
#
-# CONFIG_AD9960 is not set
CONFIG_BFIN_DMA_INTERFACE=m
# CONFIG_BFIN_PPI is not set
# CONFIG_BFIN_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BFIN_SPI_ADC is not set
CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
# CONFIG_VT is not set
# CONFIG_DEVKMEM is not set
CONFIG_BFIN_JTAG_COMM=m
@@ -751,6 +803,7 @@ CONFIG_BFIN_JTAG_COMM=m
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_BFIN=y
CONFIG_SERIAL_BFIN_CONSOLE=y
CONFIG_SERIAL_BFIN_DMA=y
@@ -765,12 +818,8 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -778,6 +827,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_TCG_TPM is not set
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
@@ -810,14 +860,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY 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
@@ -834,13 +876,18 @@ CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
@@ -856,6 +903,7 @@ CONFIG_GPIO_SYSFS=y
# 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:
@@ -866,11 +914,15 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -892,26 +944,17 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -947,6 +990,7 @@ CONFIG_FB_BFIN_LQ035Q1=m
# 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
#
@@ -957,14 +1001,12 @@ CONFIG_FB_BFIN_LQ035Q1=m
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1001,6 +1043,7 @@ CONFIG_RTC_INTF_DEV=y
# 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
@@ -1012,6 +1055,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1032,10 +1076,21 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_BFIN=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
# File systems
#
# CONFIG_EXT2_FS is not set
@@ -1044,9 +1099,13 @@ CONFIG_RTC_DRV_BFIN=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=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
@@ -1056,6 +1115,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1074,13 +1138,9 @@ CONFIG_INOTIFY_USER=y
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1099,17 +1159,8 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
# 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
@@ -1128,7 +1179,6 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1193,14 +1243,19 @@ 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_SECTION_MISMATCH=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
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
@@ -1208,31 +1263,39 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_SLAB 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_NOMMU_REGIONS 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_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
-
-#
-# 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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1257,6 +1320,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
#
# Security options
@@ -1265,14 +1329,14 @@ CONFIG_ACCESS_CHECK=y
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1304,11 +1368,13 @@ CONFIG_CRYPTO=y
#
# 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
@@ -1345,6 +1411,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1352,11 +1419,13 @@ CONFIG_CRYPTO=y
#
# 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=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1366,6 +1435,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index eb3e98b6f3f..ca309cfc6ac 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -1,7 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31.5
-# Mon Nov 2 22:02:56 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -12,7 +11,6 @@ CONFIG_GENERIC_CSUM=y
CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
@@ -49,11 +47,12 @@ 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_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=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -89,24 +88,23 @@ CONFIG_EPOLL=y
# CONFIG_AIO is not set
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_BASE_SMALL=0
@@ -163,15 +161,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_BF537 is not set
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
CONFIG_BF548_std=y
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=0
@@ -185,7 +183,6 @@ CONFIG_BF_REV_0_2=y
# CONFIG_BF_REV_0_6 is not set
# CONFIG_BF_REV_ANY is not set
# CONFIG_BF_REV_NONE is not set
-CONFIG_BF54x=y
CONFIG_IRQ_PLL_WAKEUP=7
CONFIG_IRQ_RTC=8
CONFIG_IRQ_SPORT0_RX=9
@@ -221,6 +218,8 @@ CONFIG_IRQ_SPI1=10
CONFIG_IRQ_SPI2=10
CONFIG_IRQ_TWI0=11
CONFIG_IRQ_TWI1=11
+CONFIG_BF548=y
+CONFIG_BF54x=y
CONFIG_BFIN548_EZKIT=y
# CONFIG_BFIN548_BLUETECHNIX_CM is not set
@@ -387,12 +386,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
CONFIG_DMA_UNCACHED_2M=y
# CONFIG_DMA_UNCACHED_1M is not set
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
@@ -505,6 +506,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -528,7 +530,24 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
CONFIG_IRDA=m
#
@@ -663,6 +682,7 @@ CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_DATAFLASH is not set
CONFIG_MTD_M25P80=y
CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -711,10 +731,10 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# 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_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_ISL29003 is not set
-# CONFIG_AD525X_DPOT is not set
# CONFIG_C2PORT is not set
#
@@ -767,7 +787,8 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
-CONFIG_SATA_PMP=y
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
CONFIG_ATA_SFF=y
# CONFIG_SATA_MV is not set
# CONFIG_PATA_PLATFORM is not set
@@ -808,6 +829,7 @@ CONFIG_MII=y
# CONFIG_ETHOC is not set
CONFIG_SMSC911X=y
# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -818,12 +840,10 @@ CONFIG_SMSC911X=y
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
+CONFIG_WLAN=y
# CONFIG_WLAN_PRE80211 is not set
CONFIG_WLAN_80211=y
CONFIG_LIBERTAS=m
@@ -877,10 +897,12 @@ CONFIG_INPUT_EVBUG=m
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
CONFIG_KEYBOARD_BFIN=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_GPIO 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
@@ -900,6 +922,7 @@ CONFIG_TOUCHSCREEN_AD7877=m
# 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
@@ -910,7 +933,6 @@ CONFIG_TOUCHSCREEN_AD7877=m
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
# CONFIG_TOUCHSCREEN_TSC2007 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
@@ -976,11 +998,6 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_BFIN_OTP=y
# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -988,6 +1005,7 @@ CONFIG_BFIN_OTP=y
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -1021,9 +1039,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -1078,11 +1093,15 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -1116,8 +1135,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
@@ -1192,6 +1213,7 @@ CONFIG_LOGO=y
CONFIG_LOGO_BLACKFIN_CLUT224=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
@@ -1245,7 +1267,6 @@ CONFIG_SND_SOC_AD1980=y
CONFIG_AC97_BUS=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -1268,6 +1289,7 @@ CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KYE is not set
CONFIG_HID_GYRATION=y
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
@@ -1422,10 +1444,11 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_SPI is not set
CONFIG_SDH_BFIN=y
# CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND is not set
-# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set
-# CONFIG_MMC_SPI is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
@@ -1472,6 +1495,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1522,6 +1546,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_XFS_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
@@ -1563,7 +1588,6 @@ CONFIG_NTFS_RW=y
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
@@ -1595,7 +1619,6 @@ CONFIG_JFFS2_RTIME=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=m
CONFIG_NFS_V3=y
@@ -1680,6 +1703,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
@@ -1714,12 +1738,14 @@ 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_FRAME_POINTER 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_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1730,7 +1756,6 @@ CONFIG_TRACING_SUPPORT=y
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_VERBOSE=y
@@ -1766,7 +1791,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1798,11 +1822,13 @@ CONFIG_CRYPTO=y
#
# 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
diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig
index b9b0f93d0bd..6a776ce75e9 100644
--- a/arch/blackfin/configs/BF561-ACVILON_defconfig
+++ b/arch/blackfin/configs/BF561-ACVILON_defconfig
@@ -114,7 +114,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-CONFIG_LBDAF=y
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -1486,19 +1486,10 @@ CONFIG_DEBUG_INFO=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=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_BOOT_TRACER is not set
-CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
# 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
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index e3ecdcc3e76..792ff093883 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -1,7 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31.5
-# Mon Nov 2 21:59:31 2009
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -12,7 +11,6 @@ CONFIG_GENERIC_CSUM=y
CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
@@ -49,11 +47,12 @@ 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_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=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -89,17 +88,15 @@ CONFIG_EPOLL=y
# CONFIG_AIO is not set
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
#
@@ -163,15 +160,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_BF537 is not set
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
CONFIG_BF561=y
# CONFIG_SMP is not set
@@ -180,9 +177,9 @@ CONFIG_BF_REV_MAX=5
# CONFIG_BF_REV_0_0 is not set
# CONFIG_BF_REV_0_1 is not set
# CONFIG_BF_REV_0_2 is not set
-# CONFIG_BF_REV_0_3 is not set
+CONFIG_BF_REV_0_3=y
# CONFIG_BF_REV_0_4 is not set
-CONFIG_BF_REV_0_5=y
+# CONFIG_BF_REV_0_5 is not set
# CONFIG_BF_REV_0_6 is not set
# CONFIG_BF_REV_ANY is not set
# CONFIG_BF_REV_NONE is not set
@@ -298,7 +295,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_TICKSOURCE_GPTMR0 is not set
CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
# CONFIG_GPTMR0_CLOCKSOURCE is not set
CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
@@ -353,12 +350,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
@@ -370,9 +369,11 @@ CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
-CONFIG_BFIN_EXTMEM_WRITEBACK=y
-# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
-# CONFIG_BFIN_L2_DCACHEABLE is not set
+# CONFIG_BFIN_EXTMEM_WRITEBACK is not set
+CONFIG_BFIN_EXTMEM_WRITETHROUGH=y
+CONFIG_BFIN_L2_DCACHEABLE=y
+# CONFIG_BFIN_L2_WRITEBACK is not set
+CONFIG_BFIN_L2_WRITETHROUGH=y
#
# Memory Protection Unit
@@ -472,6 +473,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -613,6 +615,7 @@ CONFIG_MTD_PHYSMAP=m
#
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -685,6 +688,7 @@ CONFIG_SMC91X=y
# CONFIG_ETHOC is not set
# CONFIG_SMSC911X is not set
# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -695,14 +699,10 @@ CONFIG_SMC91X=y
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 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
@@ -782,11 +782,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
@@ -838,11 +833,15 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -865,6 +864,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -884,7 +884,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=m
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set
@@ -923,6 +922,7 @@ CONFIG_HID=m
# CONFIG_XFS_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
@@ -957,7 +957,6 @@ CONFIG_INOTIFY_USER=y
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
@@ -989,7 +988,6 @@ CONFIG_JFFS2_RTIME=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=m
CONFIG_NFS_V3=y
@@ -1064,6 +1062,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
@@ -1098,26 +1097,24 @@ 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_FRAME_POINTER 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_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
-# CONFIG_BRANCH_PROFILE_NONE is not set
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILE_ALL_BRANCHES 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_KMEMCHECK is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_VERBOSE=y
@@ -1153,7 +1150,6 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1185,11 +1181,13 @@ CONFIG_CRYPTO=y
#
# 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
diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig
index bc7fae3d8b8..ed0a7ebeb85 100644
--- a/arch/blackfin/configs/H8606_defconfig
+++ b/arch/blackfin/configs/H8606_defconfig
@@ -834,13 +834,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
#
# ALSA Blackfin devices
#
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
# CONFIG_SND_BFIN_AD73311 is not set
#
diff --git a/arch/blackfin/configs/PNAV-10_defconfig b/arch/blackfin/configs/PNAV-10_defconfig
index 67d12768602..ad58fede1f4 100644
--- a/arch/blackfin/configs/PNAV-10_defconfig
+++ b/arch/blackfin/configs/PNAV-10_defconfig
@@ -1,21 +1,27 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
+# Linux kernel version: 2.6.32.2
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -25,16 +31,32 @@ 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_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA 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_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_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
@@ -58,6 +80,10 @@ CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
@@ -65,11 +91,14 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
CONFIG_MMAP_ALLOW_UNINITIALIZED=y
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -77,11 +106,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -97,7 +123,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
@@ -128,15 +153,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BF537=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
# CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
# CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
# CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
# CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=2
@@ -180,7 +205,8 @@ CONFIG_IRQ_MEM_DMA1=13
CONFIG_IRQ_WATCH=13
CONFIG_IRQ_SPI=10
# CONFIG_BFIN537_STAMP is not set
-# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set
# CONFIG_BFIN537_BLUETECHNIX_TCM is not set
CONFIG_PNAV10=y
# CONFIG_CAMSIG_MINOTAUR is not set
@@ -282,7 +308,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
@@ -291,16 +316,18 @@ CONFIG_BFIN_GPTIMERS=y
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
# CONFIG_DMA_UNCACHED_NONE is not set
#
# Cache Support
#
CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
CONFIG_BFIN_EXTMEM_DCACHEABLE=y
CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -311,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
# CONFIG_MPU is not set
#
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
#
#
@@ -367,11 +394,6 @@ CONFIG_NET=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 is not set
@@ -395,7 +417,6 @@ CONFIG_IP_PNP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -406,6 +427,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -419,7 +441,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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
@@ -430,13 +455,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# 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_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -455,6 +475,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# 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
@@ -506,6 +527,7 @@ CONFIG_MTD_UCLINUX=y
#
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -521,11 +543,6 @@ 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_BFIN=y
-CONFIG_BFIN_NAND_BASE=0x20100000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=44
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
@@ -533,6 +550,11 @@ CONFIG_MTD_NAND_IDS=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
@@ -549,10 +571,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -587,6 +619,9 @@ CONFIG_PHYLIB=y
# 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
@@ -597,9 +632,12 @@ CONFIG_BFIN_TX_DESC_NUM=100
CONFIG_BFIN_RX_DESC_NUM=100
CONFIG_BFIN_MAC_RMII=y
# CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -608,15 +646,16 @@ CONFIG_BFIN_MAC_RMII=y
# 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 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
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -649,14 +688,17 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
CONFIG_TOUCHSCREEN_AD7877=y
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_ADS7846 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
@@ -665,6 +707,7 @@ CONFIG_TOUCHSCREEN_AD7877=y
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_ATI_REMOTE is not set
# CONFIG_INPUT_ATI_REMOTE2 is not set
@@ -673,7 +716,9 @@ CONFIG_INPUT_MISC=y
# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_CM109 is not set
CONFIG_INPUT_UINPUT=y
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
@@ -684,16 +729,13 @@ CONFIG_INPUT_UINPUT=y
#
# Character devices
#
-# CONFIG_AD9960 is not set
CONFIG_BFIN_DMA_INTERFACE=m
# CONFIG_BFIN_PPI is not set
# CONFIG_BFIN_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BFIN_SPI_ADC is not set
CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_BFIN_TWI_LCD is not set
-# CONFIG_SIMPLE_GPIO is not set
# CONFIG_VT is not set
CONFIG_DEVKMEM=y
# CONFIG_BFIN_JTAG_COMM is not set
@@ -707,6 +749,7 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_BFIN=y
CONFIG_SERIAL_BFIN_CONSOLE=y
CONFIG_SERIAL_BFIN_DMA=y
@@ -719,24 +762,17 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-CONFIG_CAN4LINUX=y
-
-#
-# linux embedded drivers
-#
-CONFIG_CAN_BLACKFIN=m
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
@@ -769,14 +805,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-CONFIG_SENSORS_PCF8574=m
-# 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
@@ -792,20 +820,29 @@ CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB 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_AD5252 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADCXX is not set
@@ -818,11 +855,13 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -838,17 +877,24 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1111 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_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 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_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
@@ -858,9 +904,8 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -875,28 +920,19 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE 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_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -928,24 +964,24 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_BFIN_T350MCQB is not set
# CONFIG_FB_BFIN_LQ035Q1 is not set
CONFIG_FB_BF537_LQ035=y
-CONFIG_LQ035_SLAVE_ADDR=0x58
-CONFIG_FB_BFIN_LANDSCAPE=y
-# CONFIG_FB_BFIN_BGR is not set
# CONFIG_FB_BFIN_7393 is not set
# CONFIG_FB_HITACHI_TX09 is not set
# 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=y
CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LMS283GF05 is not set
# CONFIG_LCD_LTV350QV is not set
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_TDO24M is not set
# CONFIG_LCD_VGG2432A4 is not set
# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
+# CONFIG_BACKLIGHT_ADP8870 is not set
#
# Display device support
@@ -954,6 +990,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_LOGO is not set
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=m
# CONFIG_SND_SEQUENCER is not set
# CONFIG_SND_MIXER_OSS is not set
@@ -963,6 +1000,11 @@ CONFIG_SND=m
# CONFIG_SND_VERBOSE_PROCFS is not set
# 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
@@ -973,7 +1015,6 @@ CONFIG_SND_SPI=y
#
# ALSA Blackfin devices
#
-# CONFIG_SND_BLACKFIN_AD1836 is not set
# CONFIG_SND_BFIN_AD73322 is not set
# CONFIG_SND_SOC is not set
CONFIG_SOUND_PRIME=y
@@ -993,9 +1034,13 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1031,6 +1076,7 @@ CONFIG_RTC_INTF_DEV=y
# 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
@@ -1042,6 +1088,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
#
# Platform RTC drivers
@@ -1062,10 +1109,21 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_BFIN=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
# CONFIG_STAGING is not set
#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1078,9 +1136,13 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=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
@@ -1090,6 +1152,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1108,13 +1175,9 @@ CONFIG_INOTIFY_USER=y
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1123,17 +1186,8 @@ CONFIG_SYSFS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
-CONFIG_YAFFS_FS=y
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
# 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
@@ -1152,7 +1206,6 @@ CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1217,18 +1270,19 @@ 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_SECTION_MISMATCH=y
# CONFIG_DEBUG_KERNEL is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_DEBUG_VERBOSE=y
@@ -1245,6 +1299,7 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
# CONFIG_EARLY_PRINTK is not set
# CONFIG_CPLB_INFO is not set
# CONFIG_ACCESS_CHECK is not set
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
#
# Security options
@@ -1253,14 +1308,14 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1292,11 +1347,13 @@ CONFIG_CRYPTO=y
#
# 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
@@ -1333,6 +1390,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1340,11 +1398,13 @@ CONFIG_CRYPTO=y
#
# 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=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1356,3 +1416,4 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/TCM-BF518_defconfig b/arch/blackfin/configs/TCM-BF518_defconfig
new file mode 100644
index 00000000000..4d31e2a4ed4
--- /dev/null
+++ b/arch/blackfin/configs/TCM-BF518_defconfig
@@ -0,0 +1,1375 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32.3
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=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_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+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_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_GROUP_SCHED is not set
+# 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 is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
+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 is not set
+CONFIG_EPOLL=y
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=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 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 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_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+CONFIG_BF518=y
+# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
+# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
+# CONFIG_BF527 is not set
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
+# CONFIG_BF542_std is not set
+# CONFIG_BF542M is not set
+# CONFIG_BF544_std is not set
+# CONFIG_BF544M is not set
+# CONFIG_BF547_std is not set
+# CONFIG_BF547M is not set
+# CONFIG_BF548_std is not set
+# CONFIG_BF548M is not set
+# CONFIG_BF549_std is not set
+# CONFIG_BF549M is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=0
+CONFIG_BF_REV_MAX=2
+# CONFIG_BF_REV_0_0 is not set
+CONFIG_BF_REV_0_1=y
+# CONFIG_BF_REV_0_2 is not set
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_BF51x=y
+# CONFIG_BFIN518F_EZBRD is not set
+CONFIG_BFIN518F_TCM=y
+
+#
+# BF518 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF518_SPORT0_PORTF is not set
+CONFIG_BF518_SPORT0_PORTG=y
+CONFIG_BF518_SPORT0_TSCLK_PG10=y
+# CONFIG_BF518_SPORT0_TSCLK_PG14 is not set
+CONFIG_BF518_UART1_PORTF=y
+# CONFIG_BF518_UART1_PORTG is not set
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_PTP_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_SPI0=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_IRQ_SPI0_ERROR=7
+CONFIG_IRQ_SPI1_ERROR=7
+CONFIG_IRQ_RSI_INT0=7
+CONFIG_IRQ_RSI_INT1=7
+CONFIG_IRQ_PWM_TRIP=10
+CONFIG_IRQ_PWM_SYNC=10
+CONFIG_IRQ_PTP_STAT=10
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=400000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133333333
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# 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_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+
+#
+# Clock event device
+#
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+
+#
+# Clock souce
+#
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Misc
+#
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL 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_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=m
+# CONFIG_DMA_UNCACHED_4M is not set
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+CONFIG_BFIN_EXTMEM_DCACHEABLE=y
+CONFIG_BFIN_EXTMEM_WRITEBACK=y
+# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
+
+#
+# Memory Protection Unit
+#
+# CONFIG_MPU is not set
+
+#
+# Asynchronous Memory Configuration
+#
+
+#
+# EBIU_AMGCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B2
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+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=y
+# CONFIG_IP_PNP_DHCP is not set
+# 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 is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_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_NETLABEL 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_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=y
+# 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=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# 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 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP 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=y
+CONFIG_MTD_ROM=m
+# 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_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# 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 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=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP 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_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_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# 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 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_BFIN_MAC=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+# CONFIG_BFIN_MAC_RMII is not set
+CONFIG_BFIN_MAC_USE_HWSTAMP=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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 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
+#
+# 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
+
+#
+# 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=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
+# CONFIG_BFIN_SIMPLE_TIMER is not set
+# CONFIG_BFIN_SPI_ADC is not set
+# CONFIG_BFIN_SPORT is not set
+# CONFIG_BFIN_TWI_LCD is not set
+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 is not set
+CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_DMA=y
+# CONFIG_SERIAL_BFIN_PIO is not set
+CONFIG_SERIAL_BFIN_UART0=y
+# CONFIG_BFIN_UART0_CTSRTS is not set
+# CONFIG_SERIAL_BFIN_UART1 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE 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=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
+# CONFIG_I2C_GPIO is not set
+# 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
+
+#
+# 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_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=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+CONFIG_SPI_BFIN_LOCK=y
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# 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:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# 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=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+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_TPS65010 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_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP 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 is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+# 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_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+CONFIG_MMC_SPI=y
+# CONFIG_SDH_BFIN 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=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 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_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
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# 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_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR 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_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=m
+# CONFIG_MSDOS_FS is not set
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS 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 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# 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=m
+# 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_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+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_DEBUG_SLAB 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_NOMMU_REGIONS 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_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_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_VERBOSE=y
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HWERR=y
+CONFIG_EXACT_HWERR=y
+CONFIG_DEBUG_DOUBLEFAULT=y
+CONFIG_DEBUG_DOUBLEFAULT_PRINT=y
+# CONFIG_DEBUG_DOUBLEFAULT_RESET is not set
+# CONFIG_DEBUG_ICACHE_CHECK is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=1
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_TOMOYO is not set
+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_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 is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/include/asm/bfin-lq035q1.h b/arch/blackfin/include/asm/bfin-lq035q1.h
index 57bc21ac229..836895156b5 100644
--- a/arch/blackfin/include/asm/bfin-lq035q1.h
+++ b/arch/blackfin/include/asm/bfin-lq035q1.h
@@ -8,6 +8,9 @@
#ifndef BFIN_LQ035Q1_H
#define BFIN_LQ035Q1_H
+/*
+ * LCD Modes
+ */
#define LQ035_RL (0 << 8) /* Right -> Left Scan */
#define LQ035_LR (1 << 8) /* Left -> Right Scan */
#define LQ035_TB (1 << 9) /* Top -> Botton Scan */
@@ -17,9 +20,18 @@
#define LQ035_NORM (1 << 13) /* Reversal */
#define LQ035_REV (0 << 13) /* Reversal */
+/*
+ * PPI Modes
+ */
+
+#define USE_RGB565_16_BIT_PPI 1
+#define USE_RGB565_8_BIT_PPI 2
+#define USE_RGB888_8_BIT_PPI 3
+
struct bfin_lq035q1fb_disp_info {
unsigned mode;
+ unsigned ppi_mode;
/* GPIOs */
int use_bl;
unsigned gpio_bl;
diff --git a/arch/blackfin/include/asm/bfin_can.h b/arch/blackfin/include/asm/bfin_can.h
new file mode 100644
index 00000000000..eec0076a385
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_can.h
@@ -0,0 +1,725 @@
+/*
+ * bfin_can.h - interface to Blackfin CANs
+ *
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BFIN_CAN_H__
+#define __ASM_BFIN_CAN_H__
+
+/*
+ * transmit and receive channels
+ */
+#define TRANSMIT_CHL 24
+#define RECEIVE_STD_CHL 0
+#define RECEIVE_EXT_CHL 4
+#define RECEIVE_RTR_CHL 8
+#define RECEIVE_EXT_RTR_CHL 12
+#define MAX_CHL_NUMBER 32
+
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits. So use a helper macro to streamline this.
+ */
+#define __BFP(m) u16 m; u16 __pad_##m
+
+/*
+ * bfin can registers layout
+ */
+struct bfin_can_mask_regs {
+ __BFP(aml);
+ __BFP(amh);
+};
+
+struct bfin_can_channel_regs {
+ u16 data[8];
+ __BFP(dlc);
+ __BFP(tsv);
+ __BFP(id0);
+ __BFP(id1);
+};
+
+struct bfin_can_regs {
+ /*
+ * global control and status registers
+ */
+ __BFP(mc1); /* offset 0x00 */
+ __BFP(md1); /* offset 0x04 */
+ __BFP(trs1); /* offset 0x08 */
+ __BFP(trr1); /* offset 0x0c */
+ __BFP(ta1); /* offset 0x10 */
+ __BFP(aa1); /* offset 0x14 */
+ __BFP(rmp1); /* offset 0x18 */
+ __BFP(rml1); /* offset 0x1c */
+ __BFP(mbtif1); /* offset 0x20 */
+ __BFP(mbrif1); /* offset 0x24 */
+ __BFP(mbim1); /* offset 0x28 */
+ __BFP(rfh1); /* offset 0x2c */
+ __BFP(opss1); /* offset 0x30 */
+ u32 __pad1[3];
+ __BFP(mc2); /* offset 0x40 */
+ __BFP(md2); /* offset 0x44 */
+ __BFP(trs2); /* offset 0x48 */
+ __BFP(trr2); /* offset 0x4c */
+ __BFP(ta2); /* offset 0x50 */
+ __BFP(aa2); /* offset 0x54 */
+ __BFP(rmp2); /* offset 0x58 */
+ __BFP(rml2); /* offset 0x5c */
+ __BFP(mbtif2); /* offset 0x60 */
+ __BFP(mbrif2); /* offset 0x64 */
+ __BFP(mbim2); /* offset 0x68 */
+ __BFP(rfh2); /* offset 0x6c */
+ __BFP(opss2); /* offset 0x70 */
+ u32 __pad2[3];
+ __BFP(clock); /* offset 0x80 */
+ __BFP(timing); /* offset 0x84 */
+ __BFP(debug); /* offset 0x88 */
+ __BFP(status); /* offset 0x8c */
+ __BFP(cec); /* offset 0x90 */
+ __BFP(gis); /* offset 0x94 */
+ __BFP(gim); /* offset 0x98 */
+ __BFP(gif); /* offset 0x9c */
+ __BFP(control); /* offset 0xa0 */
+ __BFP(intr); /* offset 0xa4 */
+ u32 __pad3[1];
+ __BFP(mbtd); /* offset 0xac */
+ __BFP(ewr); /* offset 0xb0 */
+ __BFP(esr); /* offset 0xb4 */
+ u32 __pad4[2];
+ __BFP(ucreg); /* offset 0xc0 */
+ __BFP(uccnt); /* offset 0xc4 */
+ __BFP(ucrc); /* offset 0xc8 */
+ __BFP(uccnf); /* offset 0xcc */
+ u32 __pad5[12];
+
+ /*
+ * channel(mailbox) mask and message registers
+ */
+ struct bfin_can_mask_regs msk[MAX_CHL_NUMBER]; /* offset 0x100 */
+ struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */
+};
+
+#undef __BFP
+
+/* CAN_CONTROL Masks */
+#define SRS 0x0001 /* Software Reset */
+#define DNM 0x0002 /* Device Net Mode */
+#define ABO 0x0004 /* Auto-Bus On Enable */
+#define TXPRIO 0x0008 /* TX Priority (Priority/Mailbox*) */
+#define WBA 0x0010 /* Wake-Up On CAN Bus Activity Enable */
+#define SMR 0x0020 /* Sleep Mode Request */
+#define CSR 0x0040 /* CAN Suspend Mode Request */
+#define CCR 0x0080 /* CAN Configuration Mode Request */
+
+/* CAN_STATUS Masks */
+#define WT 0x0001 /* TX Warning Flag */
+#define WR 0x0002 /* RX Warning Flag */
+#define EP 0x0004 /* Error Passive Mode */
+#define EBO 0x0008 /* Error Bus Off Mode */
+#define SMA 0x0020 /* Sleep Mode Acknowledge */
+#define CSA 0x0040 /* Suspend Mode Acknowledge */
+#define CCA 0x0080 /* Configuration Mode Acknowledge */
+#define MBPTR 0x1F00 /* Mailbox Pointer */
+#define TRM 0x4000 /* Transmit Mode */
+#define REC 0x8000 /* Receive Mode */
+
+/* CAN_CLOCK Masks */
+#define BRP 0x03FF /* Bit-Rate Pre-Scaler */
+
+/* CAN_TIMING Masks */
+#define TSEG1 0x000F /* Time Segment 1 */
+#define TSEG2 0x0070 /* Time Segment 2 */
+#define SAM 0x0080 /* Sampling */
+#define SJW 0x0300 /* Synchronization Jump Width */
+
+/* CAN_DEBUG Masks */
+#define DEC 0x0001 /* Disable CAN Error Counters */
+#define DRI 0x0002 /* Disable CAN RX Input */
+#define DTO 0x0004 /* Disable CAN TX Output */
+#define DIL 0x0008 /* Disable CAN Internal Loop */
+#define MAA 0x0010 /* Mode Auto-Acknowledge Enable */
+#define MRB 0x0020 /* Mode Read Back Enable */
+#define CDE 0x8000 /* CAN Debug Enable */
+
+/* CAN_CEC Masks */
+#define RXECNT 0x00FF /* Receive Error Counter */
+#define TXECNT 0xFF00 /* Transmit Error Counter */
+
+/* CAN_INTR Masks */
+#define MBRIRQ 0x0001 /* Mailbox Receive Interrupt */
+#define MBTIRQ 0x0002 /* Mailbox Transmit Interrupt */
+#define GIRQ 0x0004 /* Global Interrupt */
+#define SMACK 0x0008 /* Sleep Mode Acknowledge */
+#define CANTX 0x0040 /* CAN TX Bus Value */
+#define CANRX 0x0080 /* CAN RX Bus Value */
+
+/* CAN_MBxx_ID1 and CAN_MBxx_ID0 Masks */
+#define DFC 0xFFFF /* Data Filtering Code (If Enabled) (ID0) */
+#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (ID0) */
+#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (ID1) */
+#define BASEID 0x1FFC /* Base Identifier */
+#define IDE 0x2000 /* Identifier Extension */
+#define RTR 0x4000 /* Remote Frame Transmission Request */
+#define AME 0x8000 /* Acceptance Mask Enable */
+
+/* CAN_MBxx_TIMESTAMP Masks */
+#define TSV 0xFFFF /* Timestamp */
+
+/* CAN_MBxx_LENGTH Masks */
+#define DLC 0x000F /* Data Length Code */
+
+/* CAN_AMxxH and CAN_AMxxL Masks */
+#define DFM 0xFFFF /* Data Field Mask (If Enabled) (CAN_AMxxL) */
+#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (CAN_AMxxL) */
+#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (CAN_AMxxH) */
+#define BASEID 0x1FFC /* Base Identifier */
+#define AMIDE 0x2000 /* Acceptance Mask ID Extension Enable */
+#define FMD 0x4000 /* Full Mask Data Field Enable */
+#define FDF 0x8000 /* Filter On Data Field Enable */
+
+/* CAN_MC1 Masks */
+#define MC0 0x0001 /* Enable Mailbox 0 */
+#define MC1 0x0002 /* Enable Mailbox 1 */
+#define MC2 0x0004 /* Enable Mailbox 2 */
+#define MC3 0x0008 /* Enable Mailbox 3 */
+#define MC4 0x0010 /* Enable Mailbox 4 */
+#define MC5 0x0020 /* Enable Mailbox 5 */
+#define MC6 0x0040 /* Enable Mailbox 6 */
+#define MC7 0x0080 /* Enable Mailbox 7 */
+#define MC8 0x0100 /* Enable Mailbox 8 */
+#define MC9 0x0200 /* Enable Mailbox 9 */
+#define MC10 0x0400 /* Enable Mailbox 10 */
+#define MC11 0x0800 /* Enable Mailbox 11 */
+#define MC12 0x1000 /* Enable Mailbox 12 */
+#define MC13 0x2000 /* Enable Mailbox 13 */
+#define MC14 0x4000 /* Enable Mailbox 14 */
+#define MC15 0x8000 /* Enable Mailbox 15 */
+
+/* CAN_MC2 Masks */
+#define MC16 0x0001 /* Enable Mailbox 16 */
+#define MC17 0x0002 /* Enable Mailbox 17 */
+#define MC18 0x0004 /* Enable Mailbox 18 */
+#define MC19 0x0008 /* Enable Mailbox 19 */
+#define MC20 0x0010 /* Enable Mailbox 20 */
+#define MC21 0x0020 /* Enable Mailbox 21 */
+#define MC22 0x0040 /* Enable Mailbox 22 */
+#define MC23 0x0080 /* Enable Mailbox 23 */
+#define MC24 0x0100 /* Enable Mailbox 24 */
+#define MC25 0x0200 /* Enable Mailbox 25 */
+#define MC26 0x0400 /* Enable Mailbox 26 */
+#define MC27 0x0800 /* Enable Mailbox 27 */
+#define MC28 0x1000 /* Enable Mailbox 28 */
+#define MC29 0x2000 /* Enable Mailbox 29 */
+#define MC30 0x4000 /* Enable Mailbox 30 */
+#define MC31 0x8000 /* Enable Mailbox 31 */
+
+/* CAN_MD1 Masks */
+#define MD0 0x0001 /* Enable Mailbox 0 For Receive */
+#define MD1 0x0002 /* Enable Mailbox 1 For Receive */
+#define MD2 0x0004 /* Enable Mailbox 2 For Receive */
+#define MD3 0x0008 /* Enable Mailbox 3 For Receive */
+#define MD4 0x0010 /* Enable Mailbox 4 For Receive */
+#define MD5 0x0020 /* Enable Mailbox 5 For Receive */
+#define MD6 0x0040 /* Enable Mailbox 6 For Receive */
+#define MD7 0x0080 /* Enable Mailbox 7 For Receive */
+#define MD8 0x0100 /* Enable Mailbox 8 For Receive */
+#define MD9 0x0200 /* Enable Mailbox 9 For Receive */
+#define MD10 0x0400 /* Enable Mailbox 10 For Receive */
+#define MD11 0x0800 /* Enable Mailbox 11 For Receive */
+#define MD12 0x1000 /* Enable Mailbox 12 For Receive */
+#define MD13 0x2000 /* Enable Mailbox 13 For Receive */
+#define MD14 0x4000 /* Enable Mailbox 14 For Receive */
+#define MD15 0x8000 /* Enable Mailbox 15 For Receive */
+
+/* CAN_MD2 Masks */
+#define MD16 0x0001 /* Enable Mailbox 16 For Receive */
+#define MD17 0x0002 /* Enable Mailbox 17 For Receive */
+#define MD18 0x0004 /* Enable Mailbox 18 For Receive */
+#define MD19 0x0008 /* Enable Mailbox 19 For Receive */
+#define MD20 0x0010 /* Enable Mailbox 20 For Receive */
+#define MD21 0x0020 /* Enable Mailbox 21 For Receive */
+#define MD22 0x0040 /* Enable Mailbox 22 For Receive */
+#define MD23 0x0080 /* Enable Mailbox 23 For Receive */
+#define MD24 0x0100 /* Enable Mailbox 24 For Receive */
+#define MD25 0x0200 /* Enable Mailbox 25 For Receive */
+#define MD26 0x0400 /* Enable Mailbox 26 For Receive */
+#define MD27 0x0800 /* Enable Mailbox 27 For Receive */
+#define MD28 0x1000 /* Enable Mailbox 28 For Receive */
+#define MD29 0x2000 /* Enable Mailbox 29 For Receive */
+#define MD30 0x4000 /* Enable Mailbox 30 For Receive */
+#define MD31 0x8000 /* Enable Mailbox 31 For Receive */
+
+/* CAN_RMP1 Masks */
+#define RMP0 0x0001 /* RX Message Pending In Mailbox 0 */
+#define RMP1 0x0002 /* RX Message Pending In Mailbox 1 */
+#define RMP2 0x0004 /* RX Message Pending In Mailbox 2 */
+#define RMP3 0x0008 /* RX Message Pending In Mailbox 3 */
+#define RMP4 0x0010 /* RX Message Pending In Mailbox 4 */
+#define RMP5 0x0020 /* RX Message Pending In Mailbox 5 */
+#define RMP6 0x0040 /* RX Message Pending In Mailbox 6 */
+#define RMP7 0x0080 /* RX Message Pending In Mailbox 7 */
+#define RMP8 0x0100 /* RX Message Pending In Mailbox 8 */
+#define RMP9 0x0200 /* RX Message Pending In Mailbox 9 */
+#define RMP10 0x0400 /* RX Message Pending In Mailbox 10 */
+#define RMP11 0x0800 /* RX Message Pending In Mailbox 11 */
+#define RMP12 0x1000 /* RX Message Pending In Mailbox 12 */
+#define RMP13 0x2000 /* RX Message Pending In Mailbox 13 */
+#define RMP14 0x4000 /* RX Message Pending In Mailbox 14 */
+#define RMP15 0x8000 /* RX Message Pending In Mailbox 15 */
+
+/* CAN_RMP2 Masks */
+#define RMP16 0x0001 /* RX Message Pending In Mailbox 16 */
+#define RMP17 0x0002 /* RX Message Pending In Mailbox 17 */
+#define RMP18 0x0004 /* RX Message Pending In Mailbox 18 */
+#define RMP19 0x0008 /* RX Message Pending In Mailbox 19 */
+#define RMP20 0x0010 /* RX Message Pending In Mailbox 20 */
+#define RMP21 0x0020 /* RX Message Pending In Mailbox 21 */
+#define RMP22 0x0040 /* RX Message Pending In Mailbox 22 */
+#define RMP23 0x0080 /* RX Message Pending In Mailbox 23 */
+#define RMP24 0x0100 /* RX Message Pending In Mailbox 24 */
+#define RMP25 0x0200 /* RX Message Pending In Mailbox 25 */
+#define RMP26 0x0400 /* RX Message Pending In Mailbox 26 */
+#define RMP27 0x0800 /* RX Message Pending In Mailbox 27 */
+#define RMP28 0x1000 /* RX Message Pending In Mailbox 28 */
+#define RMP29 0x2000 /* RX Message Pending In Mailbox 29 */
+#define RMP30 0x4000 /* RX Message Pending In Mailbox 30 */
+#define RMP31 0x8000 /* RX Message Pending In Mailbox 31 */
+
+/* CAN_RML1 Masks */
+#define RML0 0x0001 /* RX Message Lost In Mailbox 0 */
+#define RML1 0x0002 /* RX Message Lost In Mailbox 1 */
+#define RML2 0x0004 /* RX Message Lost In Mailbox 2 */
+#define RML3 0x0008 /* RX Message Lost In Mailbox 3 */
+#define RML4 0x0010 /* RX Message Lost In Mailbox 4 */
+#define RML5 0x0020 /* RX Message Lost In Mailbox 5 */
+#define RML6 0x0040 /* RX Message Lost In Mailbox 6 */
+#define RML7 0x0080 /* RX Message Lost In Mailbox 7 */
+#define RML8 0x0100 /* RX Message Lost In Mailbox 8 */
+#define RML9 0x0200 /* RX Message Lost In Mailbox 9 */
+#define RML10 0x0400 /* RX Message Lost In Mailbox 10 */
+#define RML11 0x0800 /* RX Message Lost In Mailbox 11 */
+#define RML12 0x1000 /* RX Message Lost In Mailbox 12 */
+#define RML13 0x2000 /* RX Message Lost In Mailbox 13 */
+#define RML14 0x4000 /* RX Message Lost In Mailbox 14 */
+#define RML15 0x8000 /* RX Message Lost In Mailbox 15 */
+
+/* CAN_RML2 Masks */
+#define RML16 0x0001 /* RX Message Lost In Mailbox 16 */
+#define RML17 0x0002 /* RX Message Lost In Mailbox 17 */
+#define RML18 0x0004 /* RX Message Lost In Mailbox 18 */
+#define RML19 0x0008 /* RX Message Lost In Mailbox 19 */
+#define RML20 0x0010 /* RX Message Lost In Mailbox 20 */
+#define RML21 0x0020 /* RX Message Lost In Mailbox 21 */
+#define RML22 0x0040 /* RX Message Lost In Mailbox 22 */
+#define RML23 0x0080 /* RX Message Lost In Mailbox 23 */
+#define RML24 0x0100 /* RX Message Lost In Mailbox 24 */
+#define RML25 0x0200 /* RX Message Lost In Mailbox 25 */
+#define RML26 0x0400 /* RX Message Lost In Mailbox 26 */
+#define RML27 0x0800 /* RX Message Lost In Mailbox 27 */
+#define RML28 0x1000 /* RX Message Lost In Mailbox 28 */
+#define RML29 0x2000 /* RX Message Lost In Mailbox 29 */
+#define RML30 0x4000 /* RX Message Lost In Mailbox 30 */
+#define RML31 0x8000 /* RX Message Lost In Mailbox 31 */
+
+/* CAN_OPSS1 Masks */
+#define OPSS0 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 0 */
+#define OPSS1 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 1 */
+#define OPSS2 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 2 */
+#define OPSS3 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 3 */
+#define OPSS4 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 4 */
+#define OPSS5 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 5 */
+#define OPSS6 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 6 */
+#define OPSS7 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 7 */
+#define OPSS8 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 8 */
+#define OPSS9 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 9 */
+#define OPSS10 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 10 */
+#define OPSS11 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 11 */
+#define OPSS12 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 12 */
+#define OPSS13 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 13 */
+#define OPSS14 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 14 */
+#define OPSS15 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 15 */
+
+/* CAN_OPSS2 Masks */
+#define OPSS16 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 16 */
+#define OPSS17 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 17 */
+#define OPSS18 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 18 */
+#define OPSS19 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 19 */
+#define OPSS20 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 20 */
+#define OPSS21 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 21 */
+#define OPSS22 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 22 */
+#define OPSS23 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 23 */
+#define OPSS24 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 24 */
+#define OPSS25 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 25 */
+#define OPSS26 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 26 */
+#define OPSS27 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 27 */
+#define OPSS28 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 28 */
+#define OPSS29 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 29 */
+#define OPSS30 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 30 */
+#define OPSS31 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 31 */
+
+/* CAN_TRR1 Masks */
+#define TRR0 0x0001 /* Deny But Don't Lock Access To Mailbox 0 */
+#define TRR1 0x0002 /* Deny But Don't Lock Access To Mailbox 1 */
+#define TRR2 0x0004 /* Deny But Don't Lock Access To Mailbox 2 */
+#define TRR3 0x0008 /* Deny But Don't Lock Access To Mailbox 3 */
+#define TRR4 0x0010 /* Deny But Don't Lock Access To Mailbox 4 */
+#define TRR5 0x0020 /* Deny But Don't Lock Access To Mailbox 5 */
+#define TRR6 0x0040 /* Deny But Don't Lock Access To Mailbox 6 */
+#define TRR7 0x0080 /* Deny But Don't Lock Access To Mailbox 7 */
+#define TRR8 0x0100 /* Deny But Don't Lock Access To Mailbox 8 */
+#define TRR9 0x0200 /* Deny But Don't Lock Access To Mailbox 9 */
+#define TRR10 0x0400 /* Deny But Don't Lock Access To Mailbox 10 */
+#define TRR11 0x0800 /* Deny But Don't Lock Access To Mailbox 11 */
+#define TRR12 0x1000 /* Deny But Don't Lock Access To Mailbox 12 */
+#define TRR13 0x2000 /* Deny But Don't Lock Access To Mailbox 13 */
+#define TRR14 0x4000 /* Deny But Don't Lock Access To Mailbox 14 */
+#define TRR15 0x8000 /* Deny But Don't Lock Access To Mailbox 15 */
+
+/* CAN_TRR2 Masks */
+#define TRR16 0x0001 /* Deny But Don't Lock Access To Mailbox 16 */
+#define TRR17 0x0002 /* Deny But Don't Lock Access To Mailbox 17 */
+#define TRR18 0x0004 /* Deny But Don't Lock Access To Mailbox 18 */
+#define TRR19 0x0008 /* Deny But Don't Lock Access To Mailbox 19 */
+#define TRR20 0x0010 /* Deny But Don't Lock Access To Mailbox 20 */
+#define TRR21 0x0020 /* Deny But Don't Lock Access To Mailbox 21 */
+#define TRR22 0x0040 /* Deny But Don't Lock Access To Mailbox 22 */
+#define TRR23 0x0080 /* Deny But Don't Lock Access To Mailbox 23 */
+#define TRR24 0x0100 /* Deny But Don't Lock Access To Mailbox 24 */
+#define TRR25 0x0200 /* Deny But Don't Lock Access To Mailbox 25 */
+#define TRR26 0x0400 /* Deny But Don't Lock Access To Mailbox 26 */
+#define TRR27 0x0800 /* Deny But Don't Lock Access To Mailbox 27 */
+#define TRR28 0x1000 /* Deny But Don't Lock Access To Mailbox 28 */
+#define TRR29 0x2000 /* Deny But Don't Lock Access To Mailbox 29 */
+#define TRR30 0x4000 /* Deny But Don't Lock Access To Mailbox 30 */
+#define TRR31 0x8000 /* Deny But Don't Lock Access To Mailbox 31 */
+
+/* CAN_TRS1 Masks */
+#define TRS0 0x0001 /* Remote Frame Request For Mailbox 0 */
+#define TRS1 0x0002 /* Remote Frame Request For Mailbox 1 */
+#define TRS2 0x0004 /* Remote Frame Request For Mailbox 2 */
+#define TRS3 0x0008 /* Remote Frame Request For Mailbox 3 */
+#define TRS4 0x0010 /* Remote Frame Request For Mailbox 4 */
+#define TRS5 0x0020 /* Remote Frame Request For Mailbox 5 */
+#define TRS6 0x0040 /* Remote Frame Request For Mailbox 6 */
+#define TRS7 0x0080 /* Remote Frame Request For Mailbox 7 */
+#define TRS8 0x0100 /* Remote Frame Request For Mailbox 8 */
+#define TRS9 0x0200 /* Remote Frame Request For Mailbox 9 */
+#define TRS10 0x0400 /* Remote Frame Request For Mailbox 10 */
+#define TRS11 0x0800 /* Remote Frame Request For Mailbox 11 */
+#define TRS12 0x1000 /* Remote Frame Request For Mailbox 12 */
+#define TRS13 0x2000 /* Remote Frame Request For Mailbox 13 */
+#define TRS14 0x4000 /* Remote Frame Request For Mailbox 14 */
+#define TRS15 0x8000 /* Remote Frame Request For Mailbox 15 */
+
+/* CAN_TRS2 Masks */
+#define TRS16 0x0001 /* Remote Frame Request For Mailbox 16 */
+#define TRS17 0x0002 /* Remote Frame Request For Mailbox 17 */
+#define TRS18 0x0004 /* Remote Frame Request For Mailbox 18 */
+#define TRS19 0x0008 /* Remote Frame Request For Mailbox 19 */
+#define TRS20 0x0010 /* Remote Frame Request For Mailbox 20 */
+#define TRS21 0x0020 /* Remote Frame Request For Mailbox 21 */
+#define TRS22 0x0040 /* Remote Frame Request For Mailbox 22 */
+#define TRS23 0x0080 /* Remote Frame Request For Mailbox 23 */
+#define TRS24 0x0100 /* Remote Frame Request For Mailbox 24 */
+#define TRS25 0x0200 /* Remote Frame Request For Mailbox 25 */
+#define TRS26 0x0400 /* Remote Frame Request For Mailbox 26 */
+#define TRS27 0x0800 /* Remote Frame Request For Mailbox 27 */
+#define TRS28 0x1000 /* Remote Frame Request For Mailbox 28 */
+#define TRS29 0x2000 /* Remote Frame Request For Mailbox 29 */
+#define TRS30 0x4000 /* Remote Frame Request For Mailbox 30 */
+#define TRS31 0x8000 /* Remote Frame Request For Mailbox 31 */
+
+/* CAN_AA1 Masks */
+#define AA0 0x0001 /* Aborted Message In Mailbox 0 */
+#define AA1 0x0002 /* Aborted Message In Mailbox 1 */
+#define AA2 0x0004 /* Aborted Message In Mailbox 2 */
+#define AA3 0x0008 /* Aborted Message In Mailbox 3 */
+#define AA4 0x0010 /* Aborted Message In Mailbox 4 */
+#define AA5 0x0020 /* Aborted Message In Mailbox 5 */
+#define AA6 0x0040 /* Aborted Message In Mailbox 6 */
+#define AA7 0x0080 /* Aborted Message In Mailbox 7 */
+#define AA8 0x0100 /* Aborted Message In Mailbox 8 */
+#define AA9 0x0200 /* Aborted Message In Mailbox 9 */
+#define AA10 0x0400 /* Aborted Message In Mailbox 10 */
+#define AA11 0x0800 /* Aborted Message In Mailbox 11 */
+#define AA12 0x1000 /* Aborted Message In Mailbox 12 */
+#define AA13 0x2000 /* Aborted Message In Mailbox 13 */
+#define AA14 0x4000 /* Aborted Message In Mailbox 14 */
+#define AA15 0x8000 /* Aborted Message In Mailbox 15 */
+
+/* CAN_AA2 Masks */
+#define AA16 0x0001 /* Aborted Message In Mailbox 16 */
+#define AA17 0x0002 /* Aborted Message In Mailbox 17 */
+#define AA18 0x0004 /* Aborted Message In Mailbox 18 */
+#define AA19 0x0008 /* Aborted Message In Mailbox 19 */
+#define AA20 0x0010 /* Aborted Message In Mailbox 20 */
+#define AA21 0x0020 /* Aborted Message In Mailbox 21 */
+#define AA22 0x0040 /* Aborted Message In Mailbox 22 */
+#define AA23 0x0080 /* Aborted Message In Mailbox 23 */
+#define AA24 0x0100 /* Aborted Message In Mailbox 24 */
+#define AA25 0x0200 /* Aborted Message In Mailbox 25 */
+#define AA26 0x0400 /* Aborted Message In Mailbox 26 */
+#define AA27 0x0800 /* Aborted Message In Mailbox 27 */
+#define AA28 0x1000 /* Aborted Message In Mailbox 28 */
+#define AA29 0x2000 /* Aborted Message In Mailbox 29 */
+#define AA30 0x4000 /* Aborted Message In Mailbox 30 */
+#define AA31 0x8000 /* Aborted Message In Mailbox 31 */
+
+/* CAN_TA1 Masks */
+#define TA0 0x0001 /* Transmit Successful From Mailbox 0 */
+#define TA1 0x0002 /* Transmit Successful From Mailbox 1 */
+#define TA2 0x0004 /* Transmit Successful From Mailbox 2 */
+#define TA3 0x0008 /* Transmit Successful From Mailbox 3 */
+#define TA4 0x0010 /* Transmit Successful From Mailbox 4 */
+#define TA5 0x0020 /* Transmit Successful From Mailbox 5 */
+#define TA6 0x0040 /* Transmit Successful From Mailbox 6 */
+#define TA7 0x0080 /* Transmit Successful From Mailbox 7 */
+#define TA8 0x0100 /* Transmit Successful From Mailbox 8 */
+#define TA9 0x0200 /* Transmit Successful From Mailbox 9 */
+#define TA10 0x0400 /* Transmit Successful From Mailbox 10 */
+#define TA11 0x0800 /* Transmit Successful From Mailbox 11 */
+#define TA12 0x1000 /* Transmit Successful From Mailbox 12 */
+#define TA13 0x2000 /* Transmit Successful From Mailbox 13 */
+#define TA14 0x4000 /* Transmit Successful From Mailbox 14 */
+#define TA15 0x8000 /* Transmit Successful From Mailbox 15 */
+
+/* CAN_TA2 Masks */
+#define TA16 0x0001 /* Transmit Successful From Mailbox 16 */
+#define TA17 0x0002 /* Transmit Successful From Mailbox 17 */
+#define TA18 0x0004 /* Transmit Successful From Mailbox 18 */
+#define TA19 0x0008 /* Transmit Successful From Mailbox 19 */
+#define TA20 0x0010 /* Transmit Successful From Mailbox 20 */
+#define TA21 0x0020 /* Transmit Successful From Mailbox 21 */
+#define TA22 0x0040 /* Transmit Successful From Mailbox 22 */
+#define TA23 0x0080 /* Transmit Successful From Mailbox 23 */
+#define TA24 0x0100 /* Transmit Successful From Mailbox 24 */
+#define TA25 0x0200 /* Transmit Successful From Mailbox 25 */
+#define TA26 0x0400 /* Transmit Successful From Mailbox 26 */
+#define TA27 0x0800 /* Transmit Successful From Mailbox 27 */
+#define TA28 0x1000 /* Transmit Successful From Mailbox 28 */
+#define TA29 0x2000 /* Transmit Successful From Mailbox 29 */
+#define TA30 0x4000 /* Transmit Successful From Mailbox 30 */
+#define TA31 0x8000 /* Transmit Successful From Mailbox 31 */
+
+/* CAN_MBTD Masks */
+#define TDPTR 0x001F /* Mailbox To Temporarily Disable */
+#define TDA 0x0040 /* Temporary Disable Acknowledge */
+#define TDR 0x0080 /* Temporary Disable Request */
+
+/* CAN_RFH1 Masks */
+#define RFH0 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 0 */
+#define RFH1 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 1 */
+#define RFH2 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 2 */
+#define RFH3 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 3 */
+#define RFH4 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 4 */
+#define RFH5 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 5 */
+#define RFH6 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 6 */
+#define RFH7 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 7 */
+#define RFH8 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 8 */
+#define RFH9 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 9 */
+#define RFH10 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 10 */
+#define RFH11 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 11 */
+#define RFH12 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 12 */
+#define RFH13 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 13 */
+#define RFH14 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 14 */
+#define RFH15 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 15 */
+
+/* CAN_RFH2 Masks */
+#define RFH16 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 16 */
+#define RFH17 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 17 */
+#define RFH18 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 18 */
+#define RFH19 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 19 */
+#define RFH20 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 20 */
+#define RFH21 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 21 */
+#define RFH22 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 22 */
+#define RFH23 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 23 */
+#define RFH24 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 24 */
+#define RFH25 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 25 */
+#define RFH26 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 26 */
+#define RFH27 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 27 */
+#define RFH28 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 28 */
+#define RFH29 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 29 */
+#define RFH30 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 30 */
+#define RFH31 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 31 */
+
+/* CAN_MBTIF1 Masks */
+#define MBTIF0 0x0001 /* TX Interrupt Active In Mailbox 0 */
+#define MBTIF1 0x0002 /* TX Interrupt Active In Mailbox 1 */
+#define MBTIF2 0x0004 /* TX Interrupt Active In Mailbox 2 */
+#define MBTIF3 0x0008 /* TX Interrupt Active In Mailbox 3 */
+#define MBTIF4 0x0010 /* TX Interrupt Active In Mailbox 4 */
+#define MBTIF5 0x0020 /* TX Interrupt Active In Mailbox 5 */
+#define MBTIF6 0x0040 /* TX Interrupt Active In Mailbox 6 */
+#define MBTIF7 0x0080 /* TX Interrupt Active In Mailbox 7 */
+#define MBTIF8 0x0100 /* TX Interrupt Active In Mailbox 8 */
+#define MBTIF9 0x0200 /* TX Interrupt Active In Mailbox 9 */
+#define MBTIF10 0x0400 /* TX Interrupt Active In Mailbox 10 */
+#define MBTIF11 0x0800 /* TX Interrupt Active In Mailbox 11 */
+#define MBTIF12 0x1000 /* TX Interrupt Active In Mailbox 12 */
+#define MBTIF13 0x2000 /* TX Interrupt Active In Mailbox 13 */
+#define MBTIF14 0x4000 /* TX Interrupt Active In Mailbox 14 */
+#define MBTIF15 0x8000 /* TX Interrupt Active In Mailbox 15 */
+
+/* CAN_MBTIF2 Masks */
+#define MBTIF16 0x0001 /* TX Interrupt Active In Mailbox 16 */
+#define MBTIF17 0x0002 /* TX Interrupt Active In Mailbox 17 */
+#define MBTIF18 0x0004 /* TX Interrupt Active In Mailbox 18 */
+#define MBTIF19 0x0008 /* TX Interrupt Active In Mailbox 19 */
+#define MBTIF20 0x0010 /* TX Interrupt Active In Mailbox 20 */
+#define MBTIF21 0x0020 /* TX Interrupt Active In Mailbox 21 */
+#define MBTIF22 0x0040 /* TX Interrupt Active In Mailbox 22 */
+#define MBTIF23 0x0080 /* TX Interrupt Active In Mailbox 23 */
+#define MBTIF24 0x0100 /* TX Interrupt Active In Mailbox 24 */
+#define MBTIF25 0x0200 /* TX Interrupt Active In Mailbox 25 */
+#define MBTIF26 0x0400 /* TX Interrupt Active In Mailbox 26 */
+#define MBTIF27 0x0800 /* TX Interrupt Active In Mailbox 27 */
+#define MBTIF28 0x1000 /* TX Interrupt Active In Mailbox 28 */
+#define MBTIF29 0x2000 /* TX Interrupt Active In Mailbox 29 */
+#define MBTIF30 0x4000 /* TX Interrupt Active In Mailbox 30 */
+#define MBTIF31 0x8000 /* TX Interrupt Active In Mailbox 31 */
+
+/* CAN_MBRIF1 Masks */
+#define MBRIF0 0x0001 /* RX Interrupt Active In Mailbox 0 */
+#define MBRIF1 0x0002 /* RX Interrupt Active In Mailbox 1 */
+#define MBRIF2 0x0004 /* RX Interrupt Active In Mailbox 2 */
+#define MBRIF3 0x0008 /* RX Interrupt Active In Mailbox 3 */
+#define MBRIF4 0x0010 /* RX Interrupt Active In Mailbox 4 */
+#define MBRIF5 0x0020 /* RX Interrupt Active In Mailbox 5 */
+#define MBRIF6 0x0040 /* RX Interrupt Active In Mailbox 6 */
+#define MBRIF7 0x0080 /* RX Interrupt Active In Mailbox 7 */
+#define MBRIF8 0x0100 /* RX Interrupt Active In Mailbox 8 */
+#define MBRIF9 0x0200 /* RX Interrupt Active In Mailbox 9 */
+#define MBRIF10 0x0400 /* RX Interrupt Active In Mailbox 10 */
+#define MBRIF11 0x0800 /* RX Interrupt Active In Mailbox 11 */
+#define MBRIF12 0x1000 /* RX Interrupt Active In Mailbox 12 */
+#define MBRIF13 0x2000 /* RX Interrupt Active In Mailbox 13 */
+#define MBRIF14 0x4000 /* RX Interrupt Active In Mailbox 14 */
+#define MBRIF15 0x8000 /* RX Interrupt Active In Mailbox 15 */
+
+/* CAN_MBRIF2 Masks */
+#define MBRIF16 0x0001 /* RX Interrupt Active In Mailbox 16 */
+#define MBRIF17 0x0002 /* RX Interrupt Active In Mailbox 17 */
+#define MBRIF18 0x0004 /* RX Interrupt Active In Mailbox 18 */
+#define MBRIF19 0x0008 /* RX Interrupt Active In Mailbox 19 */
+#define MBRIF20 0x0010 /* RX Interrupt Active In Mailbox 20 */
+#define MBRIF21 0x0020 /* RX Interrupt Active In Mailbox 21 */
+#define MBRIF22 0x0040 /* RX Interrupt Active In Mailbox 22 */
+#define MBRIF23 0x0080 /* RX Interrupt Active In Mailbox 23 */
+#define MBRIF24 0x0100 /* RX Interrupt Active In Mailbox 24 */
+#define MBRIF25 0x0200 /* RX Interrupt Active In Mailbox 25 */
+#define MBRIF26 0x0400 /* RX Interrupt Active In Mailbox 26 */
+#define MBRIF27 0x0800 /* RX Interrupt Active In Mailbox 27 */
+#define MBRIF28 0x1000 /* RX Interrupt Active In Mailbox 28 */
+#define MBRIF29 0x2000 /* RX Interrupt Active In Mailbox 29 */
+#define MBRIF30 0x4000 /* RX Interrupt Active In Mailbox 30 */
+#define MBRIF31 0x8000 /* RX Interrupt Active In Mailbox 31 */
+
+/* CAN_MBIM1 Masks */
+#define MBIM0 0x0001 /* Enable Interrupt For Mailbox 0 */
+#define MBIM1 0x0002 /* Enable Interrupt For Mailbox 1 */
+#define MBIM2 0x0004 /* Enable Interrupt For Mailbox 2 */
+#define MBIM3 0x0008 /* Enable Interrupt For Mailbox 3 */
+#define MBIM4 0x0010 /* Enable Interrupt For Mailbox 4 */
+#define MBIM5 0x0020 /* Enable Interrupt For Mailbox 5 */
+#define MBIM6 0x0040 /* Enable Interrupt For Mailbox 6 */
+#define MBIM7 0x0080 /* Enable Interrupt For Mailbox 7 */
+#define MBIM8 0x0100 /* Enable Interrupt For Mailbox 8 */
+#define MBIM9 0x0200 /* Enable Interrupt For Mailbox 9 */
+#define MBIM10 0x0400 /* Enable Interrupt For Mailbox 10 */
+#define MBIM11 0x0800 /* Enable Interrupt For Mailbox 11 */
+#define MBIM12 0x1000 /* Enable Interrupt For Mailbox 12 */
+#define MBIM13 0x2000 /* Enable Interrupt For Mailbox 13 */
+#define MBIM14 0x4000 /* Enable Interrupt For Mailbox 14 */
+#define MBIM15 0x8000 /* Enable Interrupt For Mailbox 15 */
+
+/* CAN_MBIM2 Masks */
+#define MBIM16 0x0001 /* Enable Interrupt For Mailbox 16 */
+#define MBIM17 0x0002 /* Enable Interrupt For Mailbox 17 */
+#define MBIM18 0x0004 /* Enable Interrupt For Mailbox 18 */
+#define MBIM19 0x0008 /* Enable Interrupt For Mailbox 19 */
+#define MBIM20 0x0010 /* Enable Interrupt For Mailbox 20 */
+#define MBIM21 0x0020 /* Enable Interrupt For Mailbox 21 */
+#define MBIM22 0x0040 /* Enable Interrupt For Mailbox 22 */
+#define MBIM23 0x0080 /* Enable Interrupt For Mailbox 23 */
+#define MBIM24 0x0100 /* Enable Interrupt For Mailbox 24 */
+#define MBIM25 0x0200 /* Enable Interrupt For Mailbox 25 */
+#define MBIM26 0x0400 /* Enable Interrupt For Mailbox 26 */
+#define MBIM27 0x0800 /* Enable Interrupt For Mailbox 27 */
+#define MBIM28 0x1000 /* Enable Interrupt For Mailbox 28 */
+#define MBIM29 0x2000 /* Enable Interrupt For Mailbox 29 */
+#define MBIM30 0x4000 /* Enable Interrupt For Mailbox 30 */
+#define MBIM31 0x8000 /* Enable Interrupt For Mailbox 31 */
+
+/* CAN_GIM Masks */
+#define EWTIM 0x0001 /* Enable TX Error Count Interrupt */
+#define EWRIM 0x0002 /* Enable RX Error Count Interrupt */
+#define EPIM 0x0004 /* Enable Error-Passive Mode Interrupt */
+#define BOIM 0x0008 /* Enable Bus Off Interrupt */
+#define WUIM 0x0010 /* Enable Wake-Up Interrupt */
+#define UIAIM 0x0020 /* Enable Access To Unimplemented Address Interrupt */
+#define AAIM 0x0040 /* Enable Abort Acknowledge Interrupt */
+#define RMLIM 0x0080 /* Enable RX Message Lost Interrupt */
+#define UCEIM 0x0100 /* Enable Universal Counter Overflow Interrupt */
+#define EXTIM 0x0200 /* Enable External Trigger Output Interrupt */
+#define ADIM 0x0400 /* Enable Access Denied Interrupt */
+
+/* CAN_GIS Masks */
+#define EWTIS 0x0001 /* TX Error Count IRQ Status */
+#define EWRIS 0x0002 /* RX Error Count IRQ Status */
+#define EPIS 0x0004 /* Error-Passive Mode IRQ Status */
+#define BOIS 0x0008 /* Bus Off IRQ Status */
+#define WUIS 0x0010 /* Wake-Up IRQ Status */
+#define UIAIS 0x0020 /* Access To Unimplemented Address IRQ Status */
+#define AAIS 0x0040 /* Abort Acknowledge IRQ Status */
+#define RMLIS 0x0080 /* RX Message Lost IRQ Status */
+#define UCEIS 0x0100 /* Universal Counter Overflow IRQ Status */
+#define EXTIS 0x0200 /* External Trigger Output IRQ Status */
+#define ADIS 0x0400 /* Access Denied IRQ Status */
+
+/* CAN_GIF Masks */
+#define EWTIF 0x0001 /* TX Error Count IRQ Flag */
+#define EWRIF 0x0002 /* RX Error Count IRQ Flag */
+#define EPIF 0x0004 /* Error-Passive Mode IRQ Flag */
+#define BOIF 0x0008 /* Bus Off IRQ Flag */
+#define WUIF 0x0010 /* Wake-Up IRQ Flag */
+#define UIAIF 0x0020 /* Access To Unimplemented Address IRQ Flag */
+#define AAIF 0x0040 /* Abort Acknowledge IRQ Flag */
+#define RMLIF 0x0080 /* RX Message Lost IRQ Flag */
+#define UCEIF 0x0100 /* Universal Counter Overflow IRQ Flag */
+#define EXTIF 0x0200 /* External Trigger Output IRQ Flag */
+#define ADIF 0x0400 /* Access Denied IRQ Flag */
+
+/* CAN_UCCNF Masks */
+#define UCCNF 0x000F /* Universal Counter Mode */
+#define UC_STAMP 0x0001 /* Timestamp Mode */
+#define UC_WDOG 0x0002 /* Watchdog Mode */
+#define UC_AUTOTX 0x0003 /* Auto-Transmit Mode */
+#define UC_ERROR 0x0006 /* CAN Error Frame Count */
+#define UC_OVER 0x0007 /* CAN Overload Frame Count */
+#define UC_LOST 0x0008 /* Arbitration Lost During TX Count */
+#define UC_AA 0x0009 /* TX Abort Count */
+#define UC_TA 0x000A /* TX Successful Count */
+#define UC_REJECT 0x000B /* RX Message Rejected Count */
+#define UC_RML 0x000C /* RX Message Lost Count */
+#define UC_RX 0x000D /* Total Successful RX Messages Count */
+#define UC_RMP 0x000E /* Successful RX W/Matching ID Count */
+#define UC_ALL 0x000F /* Correct Message On CAN Bus Line Count */
+#define UCRC 0x0020 /* Universal Counter Reload/Clear */
+#define UCCT 0x0040 /* Universal Counter CAN Trigger */
+#define UCE 0x0080 /* Universal Counter Enable */
+
+/* CAN_ESR Masks */
+#define ACKE 0x0004 /* Acknowledge Error */
+#define SER 0x0008 /* Stuff Error */
+#define CRCE 0x0010 /* CRC Error */
+#define SA0 0x0020 /* Stuck At Dominant Error */
+#define BEF 0x0040 /* Bit Error Flag */
+#define FER 0x0080 /* Form Error Flag */
+
+/* CAN_EWR Masks */
+#define EWLREC 0x00FF /* RX Error Count Limit (For EWRIS) */
+#define EWLTEC 0xFF00 /* TX Error Count Limit (For EWTIS) */
+
+#endif
diff --git a/arch/blackfin/include/asm/bfin_sport.h b/arch/blackfin/include/asm/bfin_sport.h
index b558908e1c7..9626cf7e425 100644
--- a/arch/blackfin/include/asm/bfin_sport.h
+++ b/arch/blackfin/include/asm/bfin_sport.h
@@ -1,7 +1,7 @@
/*
- * bfin_sport.h - userspace header for bfin sport driver
+ * bfin_sport.h - interface to Blackfin SPORTs
*
- * Copyright 2004-2008 Analog Devices Inc.
+ * Copyright 2004-2009 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -9,16 +9,6 @@
#ifndef __BFIN_SPORT_H__
#define __BFIN_SPORT_H__
-#ifdef __KERNEL__
-#include <linux/cdev.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#endif
-
-#define SPORT_MAJOR 237
-#define SPORT_NR_DEVS 2
-
/* Sport mode: it can be set to TDM, i2s or others */
#define NORM_MODE 0x0
#define TDM_MODE 0x1
@@ -35,7 +25,7 @@ struct sport_config {
unsigned int mode:3;
/* if TDM mode is selected, channels must be set */
- int channels; /* Must be in 8 units */
+ int channels; /* Must be in 8 units */
unsigned int frame_delay:4; /* Delay between frame sync pulse and first bit */
/* I2S mode */
@@ -69,94 +59,137 @@ struct sport_config {
#ifdef __KERNEL__
-struct sport_register {
- unsigned short tcr1;
- unsigned short reserved0;
- unsigned short tcr2;
- unsigned short reserved1;
- unsigned short tclkdiv;
- unsigned short reserved2;
- unsigned short tfsdiv;
- unsigned short reserved3;
- unsigned long tx;
- unsigned long reserved_l0;
- unsigned long rx;
- unsigned long reserved_l1;
- unsigned short rcr1;
- unsigned short reserved4;
- unsigned short rcr2;
- unsigned short reserved5;
- unsigned short rclkdiv;
- unsigned short reserved6;
- unsigned short rfsdiv;
- unsigned short reserved7;
- unsigned short stat;
- unsigned short reserved8;
- unsigned short chnl;
- unsigned short reserved9;
- unsigned short mcmc1;
- unsigned short reserved10;
- unsigned short mcmc2;
- unsigned short reserved11;
- unsigned long mtcs0;
- unsigned long mtcs1;
- unsigned long mtcs2;
- unsigned long mtcs3;
- unsigned long mrcs0;
- unsigned long mrcs1;
- unsigned long mrcs2;
- unsigned long mrcs3;
-};
-
-struct sport_dev {
- struct cdev cdev; /* Char device structure */
-
- int sport_num;
+#include <linux/types.h>
- int dma_rx_chan;
- int dma_tx_chan;
-
- int rx_irq;
- unsigned char *rx_buf; /* Buffer store the received data */
- int rx_len; /* How many bytes will be received */
- int rx_received; /* How many bytes has been received */
-
- int tx_irq;
- const unsigned char *tx_buf;
- int tx_len;
- int tx_sent;
-
- int err_irq;
-
- struct mutex mutex; /* mutual exclusion semaphore */
- struct task_struct *task;
-
- wait_queue_head_t waitq;
- int wait_con;
- struct sport_register *regs;
- struct sport_config config;
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits. So use a helper macro to streamline this.
+ */
+#define __BFP(m) u16 m; u16 __pad_##m
+struct sport_register {
+ __BFP(tcr1);
+ __BFP(tcr2);
+ __BFP(tclkdiv);
+ __BFP(tfsdiv);
+ union {
+ u32 tx32;
+ u16 tx16;
+ };
+ u32 __pad_tx;
+ union {
+ u32 rx32; /* use the anomaly wrapper below */
+ u16 rx16;
+ };
+ u32 __pad_rx;
+ __BFP(rcr1);
+ __BFP(rcr2);
+ __BFP(rclkdiv);
+ __BFP(rfsdiv);
+ __BFP(stat);
+ __BFP(chnl);
+ __BFP(mcmc1);
+ __BFP(mcmc2);
+ u32 mtcs0;
+ u32 mtcs1;
+ u32 mtcs2;
+ u32 mtcs3;
+ u32 mrcs0;
+ u32 mrcs1;
+ u32 mrcs2;
+ u32 mrcs3;
};
+#undef __BFP
+
+#define bfin_read_sport_rx32(base) \
+({ \
+ struct sport_register *__mmrs = (void *)base; \
+ u32 __ret; \
+ unsigned long flags; \
+ if (ANOMALY_05000473) \
+ local_irq_save(flags); \
+ __ret = __mmrs->rx32; \
+ if (ANOMALY_05000473) \
+ local_irq_restore(flags); \
+ __ret; \
+})
#endif
-#define SPORT_TCR1 0
-#define SPORT_TCR2 1
-#define SPORT_TCLKDIV 2
-#define SPORT_TFSDIV 3
-#define SPORT_RCR1 8
-#define SPORT_RCR2 9
-#define SPORT_RCLKDIV 10
-#define SPORT_RFSDIV 11
-#define SPORT_CHANNEL 13
-#define SPORT_MCMC1 14
-#define SPORT_MCMC2 15
-#define SPORT_MTCS0 16
-#define SPORT_MTCS1 17
-#define SPORT_MTCS2 18
-#define SPORT_MTCS3 19
-#define SPORT_MRCS0 20
-#define SPORT_MRCS1 21
-#define SPORT_MRCS2 22
-#define SPORT_MRCS3 23
+/* Workaround defBF*.h SPORT MMRs till they get cleansed */
+#undef DTYPE_NORM
+#undef SLEN
+#undef SP_WOFF
+#undef SP_WSIZE
+
+/* SPORT_TCR1 Masks */
+#define TSPEN 0x0001 /* TX enable */
+#define ITCLK 0x0002 /* Internal TX Clock Select */
+#define TDTYPE 0x000C /* TX Data Formatting Select */
+#define DTYPE_NORM 0x0000 /* Data Format Normal */
+#define DTYPE_ULAW 0x0008 /* Compand Using u-Law */
+#define DTYPE_ALAW 0x000C /* Compand Using A-Law */
+#define TLSBIT 0x0010 /* TX Bit Order */
+#define ITFS 0x0200 /* Internal TX Frame Sync Select */
+#define TFSR 0x0400 /* TX Frame Sync Required Select */
+#define DITFS 0x0800 /* Data Independent TX Frame Sync Select */
+#define LTFS 0x1000 /* Low TX Frame Sync Select */
+#define LATFS 0x2000 /* Late TX Frame Sync Select */
+#define TCKFE 0x4000 /* TX Clock Falling Edge Select */
+
+/* SPORT_TCR2 Masks */
+#define SLEN 0x001F /* SPORT TX Word Length (2 - 31) */
+#define DP_SLEN(x) BFIN_DEPOSIT(SLEN, x)
+#define EX_SLEN(x) BFIN_EXTRACT(SLEN, x)
+#define TXSE 0x0100 /* TX Secondary Enable */
+#define TSFSE 0x0200 /* TX Stereo Frame Sync Enable */
+#define TRFST 0x0400 /* TX Right-First Data Order */
+
+/* SPORT_RCR1 Masks */
+#define RSPEN 0x0001 /* RX enable */
+#define IRCLK 0x0002 /* Internal RX Clock Select */
+#define RDTYPE 0x000C /* RX Data Formatting Select */
+/* DTYPE_* defined above */
+#define RLSBIT 0x0010 /* RX Bit Order */
+#define IRFS 0x0200 /* Internal RX Frame Sync Select */
+#define RFSR 0x0400 /* RX Frame Sync Required Select */
+#define LRFS 0x1000 /* Low RX Frame Sync Select */
+#define LARFS 0x2000 /* Late RX Frame Sync Select */
+#define RCKFE 0x4000 /* RX Clock Falling Edge Select */
+
+/* SPORT_RCR2 Masks */
+/* SLEN defined above */
+#define RXSE 0x0100 /* RX Secondary Enable */
+#define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */
+#define RRFST 0x0400 /* Right-First Data Order */
+
+/* SPORT_STAT Masks */
+#define RXNE 0x0001 /* RX FIFO Not Empty Status */
+#define RUVF 0x0002 /* RX Underflow Status */
+#define ROVF 0x0004 /* RX Overflow Status */
+#define TXF 0x0008 /* TX FIFO Full Status */
+#define TUVF 0x0010 /* TX Underflow Status */
+#define TOVF 0x0020 /* TX Overflow Status */
+#define TXHRE 0x0040 /* TX Hold Register Empty */
+
+/* SPORT_MCMC1 Masks */
+#define SP_WOFF 0x03FF /* Multichannel Window Offset Field */
+#define DP_SP_WOFF(x) BFIN_DEPOSIT(SP_WOFF, x)
+#define EX_SP_WOFF(x) BFIN_EXTRACT(SP_WOFF, x)
+#define SP_WSIZE 0xF000 /* Multichannel Window Size Field */
+#define DP_SP_WSIZE(x) BFIN_DEPOSIT(SP_WSIZE, x)
+#define EX_SP_WSIZE(x) BFIN_EXTRACT(SP_WSIZE, x)
+
+/* SPORT_MCMC2 Masks */
+#define MCCRM 0x0003 /* Multichannel Clock Recovery Mode */
+#define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */
+#define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */
+#define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */
+#define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */
+#define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */
+#define MCMEN 0x0010 /* Multichannel Frame Mode Enable */
+#define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */
+#define MFD 0xF000 /* Multichannel Frame Delay */
+#define DP_MFD(x) BFIN_DEPOSIT(MFD, x)
+#define EX_MFD(x) BFIN_EXTRACT(MFD, x)
#endif
diff --git a/arch/blackfin/include/asm/bfin_watchdog.h b/arch/blackfin/include/asm/bfin_watchdog.h
new file mode 100644
index 00000000000..dce09829a09
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_watchdog.h
@@ -0,0 +1,30 @@
+/*
+ * bfin_watchdog.h - Blackfin watchdog definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _BFIN_WATCHDOG_H
+#define _BFIN_WATCHDOG_H
+
+/* Bit in SWRST that indicates boot caused by watchdog */
+#define SWRST_RESET_WDOG 0x4000
+
+/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */
+#define WDOG_EXPIRED 0x8000
+
+/* Masks for WDEV field in WDOG_CTL register */
+#define ICTL_RESET 0x0
+#define ICTL_NMI 0x2
+#define ICTL_GPI 0x4
+#define ICTL_NONE 0x6
+#define ICTL_MASK 0x6
+
+/* Masks for WDEN field in WDOG_CTL register */
+#define WDEN_MASK 0x0FF0
+#define WDEN_ENABLE 0x0000
+#define WDEN_DISABLE 0x0AD0
+
+#endif
diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h
index a2ff3fb3568..605ba8e9b2e 100644
--- a/arch/blackfin/include/asm/bitops.h
+++ b/arch/blackfin/include/asm/bitops.h
@@ -7,22 +7,41 @@
#ifndef _BLACKFIN_BITOPS_H
#define _BLACKFIN_BITOPS_H
-#ifndef CONFIG_SMP
-# include <asm-generic/bitops.h>
-#else
+#include <linux/compiler.h>
+
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
#ifndef _LINUX_BITOPS_H
#error only <linux/bitops.h> can be included directly
#endif
-#include <linux/compiler.h>
-#include <asm/byteorder.h> /* swab32 */
-
-#include <asm-generic/bitops/ffs.h>
-#include <asm-generic/bitops/__ffs.h>
#include <asm-generic/bitops/sched.h>
-#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/ext2-non-atomic.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+#include <asm-generic/bitops/minix.h>
+
+#ifndef CONFIG_SMP
+#include <linux/irqflags.h>
+
+/*
+ * clear_bit may not imply a memory barrier
+ */
+#ifndef smp_mb__before_clear_bit
+#define smp_mb__before_clear_bit() smp_mb()
+#define smp_mb__after_clear_bit() smp_mb()
+#endif
+#include <asm-generic/bitops/atomic.h>
+#include <asm-generic/bitops/non-atomic.h>
+#else
+#include <asm/byteorder.h> /* swab32 */
#include <linux/linkage.h>
asmlinkage int __raw_bit_set_asm(volatile unsigned long *addr, int nr);
@@ -89,19 +108,36 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
#include <asm-generic/bitops/non-atomic.h>
-#include <asm-generic/bitops/find.h>
-#include <asm-generic/bitops/hweight.h>
-#include <asm-generic/bitops/lock.h>
+#endif /* CONFIG_SMP */
-#include <asm-generic/bitops/ext2-atomic.h>
-#include <asm-generic/bitops/ext2-non-atomic.h>
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
-#include <asm-generic/bitops/minix.h>
+static inline unsigned int hweight32(unsigned int w)
+{
+ unsigned int res;
-#include <asm-generic/bitops/fls.h>
-#include <asm-generic/bitops/__fls.h>
-#include <asm-generic/bitops/fls64.h>
+ __asm__ ("%0.l = ONES %0;"
+ "%0 = %0.l (Z);"
+ : "=d" (res) : "d" (w));
+ return res;
+}
-#endif /* CONFIG_SMP */
+static inline unsigned int hweight64(__u64 w)
+{
+ return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+ return hweight32(w & 0xffff);
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+ return hweight32(w & 0xff);
+}
#endif /* _BLACKFIN_BITOPS_H */
diff --git a/arch/blackfin/include/asm/context.S b/arch/blackfin/include/asm/context.S
index 5dffaf582a2..1f9060395a0 100644
--- a/arch/blackfin/include/asm/context.S
+++ b/arch/blackfin/include/asm/context.S
@@ -73,6 +73,11 @@
#else
cli r0;
#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+ sp += -12;
+ call _trace_hardirqs_off;
+ sp += 12;
+#endif
[--sp] = RETI; /*orig_pc*/
/* Clear all L registers. */
r0 = 0 (x);
@@ -279,6 +284,13 @@
RETN = [sp++];
RETX = [sp++];
RETI = [sp++];
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+ sp += -12;
+ call _trace_hardirqs_on;
+ sp += 12;
+#endif
+
RETS = [sp++];
#ifdef CONFIG_SMP
@@ -374,3 +386,13 @@
(R7:0, P5:0) = [SP++];
.endm
+
+.macro pseudo_long_call func:req, scratch:req
+#ifdef CONFIG_ROMKERNEL
+ \scratch\().l = \func;
+ \scratch\().h = \func;
+ call (\scratch);
+#else
+ call \func;
+#endif
+.endm
diff --git a/arch/blackfin/include/asm/cpu.h b/arch/blackfin/include/asm/cpu.h
index b191dc662bd..16883e582e3 100644
--- a/arch/blackfin/include/asm/cpu.h
+++ b/arch/blackfin/include/asm/cpu.h
@@ -17,8 +17,6 @@ struct blackfin_cpudata {
struct task_struct *idle;
unsigned int imemctl;
unsigned int dmemctl;
- unsigned long dcache_invld_count;
- unsigned long icache_invld_count;
};
DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data);
diff --git a/arch/blackfin/include/asm/def_LPBlackfin.h b/arch/blackfin/include/asm/def_LPBlackfin.h
index 25906468622..f342ff0319d 100644
--- a/arch/blackfin/include/asm/def_LPBlackfin.h
+++ b/arch/blackfin/include/asm/def_LPBlackfin.h
@@ -12,6 +12,8 @@
#include <mach/anomaly.h>
#define MK_BMSK_(x) (1<<x)
+#define BFIN_DEPOSIT(mask, x) (((x) << __ffs(mask)) & (mask))
+#define BFIN_EXTRACT(mask, x) (((x) & (mask)) >> __ffs(mask))
#ifndef __ASSEMBLY__
@@ -23,62 +25,30 @@
# define NOP_PAD_ANOMALY_05000198
#endif
-#define bfin_read8(addr) ({ \
- uint32_t __v; \
+#define _bfin_readX(addr, size, asm_size, asm_ext) ({ \
+ u32 __v; \
__asm__ __volatile__( \
NOP_PAD_ANOMALY_05000198 \
- "%0 = b[%1] (z);" \
+ "%0 = " #asm_size "[%1]" #asm_ext ";" \
: "=d" (__v) \
: "a" (addr) \
); \
__v; })
-
-#define bfin_read16(addr) ({ \
- uint32_t __v; \
- __asm__ __volatile__( \
- NOP_PAD_ANOMALY_05000198 \
- "%0 = w[%1] (z);" \
- : "=d" (__v) \
- : "a" (addr) \
- ); \
- __v; })
-
-#define bfin_read32(addr) ({ \
- uint32_t __v; \
- __asm__ __volatile__( \
- NOP_PAD_ANOMALY_05000198 \
- "%0 = [%1];" \
- : "=d" (__v) \
- : "a" (addr) \
- ); \
- __v; })
-
-#define bfin_write8(addr, val) \
+#define _bfin_writeX(addr, val, size, asm_size) \
__asm__ __volatile__( \
NOP_PAD_ANOMALY_05000198 \
- "b[%0] = %1;" \
+ #asm_size "[%0] = %1;" \
: \
- : "a" (addr), "d" ((uint8_t)(val)) \
+ : "a" (addr), "d" ((u##size)(val)) \
: "memory" \
)
-#define bfin_write16(addr, val) \
- __asm__ __volatile__( \
- NOP_PAD_ANOMALY_05000198 \
- "w[%0] = %1;" \
- : \
- : "a" (addr), "d" ((uint16_t)(val)) \
- : "memory" \
- )
-
-#define bfin_write32(addr, val) \
- __asm__ __volatile__( \
- NOP_PAD_ANOMALY_05000198 \
- "[%0] = %1;" \
- : \
- : "a" (addr), "d" (val) \
- : "memory" \
- )
+#define bfin_read8(addr) _bfin_readX(addr, 8, b, (z))
+#define bfin_read16(addr) _bfin_readX(addr, 16, w, (z))
+#define bfin_read32(addr) _bfin_readX(addr, 32, , )
+#define bfin_write8(addr, val) _bfin_writeX(addr, val, 8, b)
+#define bfin_write16(addr, val) _bfin_writeX(addr, val, 16, w)
+#define bfin_write32(addr, val) _bfin_writeX(addr, val, 32, )
#endif /* __ASSEMBLY__ */
diff --git a/arch/blackfin/include/asm/delay.h b/arch/blackfin/include/asm/delay.h
index c31f91cc1d5..171d8deb04a 100644
--- a/arch/blackfin/include/asm/delay.h
+++ b/arch/blackfin/include/asm/delay.h
@@ -30,10 +30,22 @@ __asm__ __volatile__ (
#define HZSCALE (268435456 / (1000000/HZ))
-static inline void udelay(unsigned long usecs)
+static inline unsigned long __to_delay(unsigned long scale)
{
extern unsigned long loops_per_jiffy;
- __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6);
+ return (((scale * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6;
+}
+
+static inline void udelay(unsigned long usecs)
+{
+ __delay(__to_delay(usecs));
}
+static inline void ndelay(unsigned long nsecs)
+{
+ __delay(__to_delay(1) * nsecs / 1000);
+}
+
+#define ndelay ndelay
+
#endif
diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h
index f9172ff30e5..212cb80fd74 100644
--- a/arch/blackfin/include/asm/dma-mapping.h
+++ b/arch/blackfin/include/asm/dma-mapping.h
@@ -44,13 +44,8 @@ dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
extern void
__dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir);
static inline void
-_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
+__dma_sync_inline(dma_addr_t addr, size_t size, enum dma_data_direction dir)
{
- if (!__builtin_constant_p(dir)) {
- __dma_sync(addr, size, dir);
- return;
- }
-
switch (dir) {
case DMA_NONE:
BUG();
@@ -64,14 +59,15 @@ _dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
break;
}
}
+static inline void
+_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
+{
+ if (__builtin_constant_p(dir))
+ __dma_sync_inline(addr, size, dir);
+ else
+ __dma_sync(addr, size, dir);
+}
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single is performed.
- */
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction dir)
@@ -88,14 +84,6 @@ dma_map_page(struct device *dev, struct page *page,
return dma_map_single(dev, page_address(page) + offset, size, dir);
}
-/*
- * Unmap a single streaming mode DMA translation. The dma_addr and size
- * must match what was provided for in a previous pci_map_single call. All
- * other usages are undefined.
- *
- * After this call, reads by the cpu to the buffer are guarenteed to see
- * whatever the device wrote there.
- */
static inline void
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
@@ -110,30 +98,9 @@ dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
dma_unmap_single(dev, dma_addr, size, dir);
}
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA. This is the scather-gather version of the
- * above pci_map_single interface. Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length. They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- * DMA address/length pairs than there are SG table elements.
- * (for example via virtual mapping capabilities)
- * The routine returns the number of addr/length pairs actually
- * used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir);
-/*
- * Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
static inline void
dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction dir)
diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h
index bd2e62243ab..2c09b1d50ec 100644
--- a/arch/blackfin/include/asm/dma.h
+++ b/arch/blackfin/include/asm/dma.h
@@ -262,6 +262,10 @@ static inline void dma_disable_irq(unsigned int channel)
{
disable_irq(dma_ch[channel].irq);
}
+static inline void dma_disable_irq_nosync(unsigned int channel)
+{
+ disable_irq_nosync(dma_ch[channel].irq);
+}
static inline void dma_enable_irq(unsigned int channel)
{
enable_irq(dma_ch[channel].irq);
diff --git a/arch/blackfin/include/asm/dpmc.h b/arch/blackfin/include/asm/dpmc.h
index 1597ae5041e..efcc3aebeae 100644
--- a/arch/blackfin/include/asm/dpmc.h
+++ b/arch/blackfin/include/asm/dpmc.h
@@ -75,7 +75,7 @@
#define VLEV 0x00F0 /* Internal Voltage Level */
#ifdef __ADSPBF52x__
-#define VLEV_085 0x0040 /* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_085 0x0040 /* VLEV = 0.85 V (-5% - +10% Accuracy) */
#define VLEV_090 0x0050 /* VLEV = 0.90 V (-5% - +10% Accuracy) */
#define VLEV_095 0x0060 /* VLEV = 0.95 V (-5% - +10% Accuracy) */
#define VLEV_100 0x0070 /* VLEV = 1.00 V (-5% - +10% Accuracy) */
@@ -84,7 +84,7 @@
#define VLEV_115 0x00A0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */
#define VLEV_120 0x00B0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */
#else
-#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */
#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */
#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */
#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index 5b50f0ecacf..117713adea7 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -22,12 +22,15 @@
#define EF_BFIN_CODE_IN_L2 0x00000040 /* --code-in-l2 */
#define EF_BFIN_DATA_IN_L2 0x00000080 /* --data-in-l2 */
+#if 1 /* core dumps not supported, but linux/elfcore.h needs these */
typedef unsigned long elf_greg_t;
-#define ELF_NGREG 40 /* (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) */
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct { } elf_fpregset_t;
+#endif
+
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
@@ -55,6 +58,9 @@ do { \
_regs->p2 = _dynamic_addr; \
} while(0)
+#if 0
+#define CORE_DUMP_USE_REGSET
+#endif
#define ELF_FDPIC_CORE_EFLAGS EF_BFIN_FDPIC
#define ELF_EXEC_PAGESIZE 4096
diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h
index 90c9b400ba6..4cfe2d9ba7e 100644
--- a/arch/blackfin/include/asm/ftrace.h
+++ b/arch/blackfin/include/asm/ftrace.h
@@ -10,4 +10,57 @@
#define MCOUNT_INSN_SIZE 6 /* sizeof "[++sp] = rets; call __mcount;" */
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_FRAME_POINTER
+#include <linux/mm.h>
+
+extern inline void *return_address(unsigned int level)
+{
+ unsigned long *endstack, *fp, *ret_addr;
+ unsigned int current_level = 0;
+
+ if (level == 0)
+ return __builtin_return_address(0);
+
+ fp = (unsigned long *)__builtin_frame_address(0);
+ endstack = (unsigned long *)PAGE_ALIGN((unsigned long)&level);
+
+ while (((unsigned long)fp & 0x3) == 0 && fp &&
+ (fp + 1) < endstack && current_level < level) {
+ fp = (unsigned long *)*fp;
+ current_level++;
+ }
+
+ if (((unsigned long)fp & 0x3) == 0 && fp &&
+ (fp + 1) < endstack)
+ ret_addr = (unsigned long *)*(fp + 1);
+ else
+ ret_addr = NULL;
+
+ return ret_addr;
+}
+
+#else
+
+extern inline void *return_address(unsigned int level)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_FRAME_POINTER */
+
+#define HAVE_ARCH_CALLER_ADDR
+
+/* inline function or macro may lead to unexpected result */
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* __ASSEMBLY__ */
+
#endif
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h
index 539468a0505..91bd2d7b9d5 100644
--- a/arch/blackfin/include/asm/gpio.h
+++ b/arch/blackfin/include/asm/gpio.h
@@ -70,6 +70,8 @@
#ifndef __ASSEMBLY__
+#include <linux/compiler.h>
+
/***********************************************************
*
* FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -223,6 +225,9 @@ int bfin_gpio_direction_output(unsigned gpio, int value);
int bfin_gpio_get_value(unsigned gpio);
void bfin_gpio_set_value(unsigned gpio, int value);
+#include <asm/irq.h>
+#include <asm/errno.h>
+
#ifdef CONFIG_GPIOLIB
#include <asm-generic/gpio.h> /* cansleep wrappers */
@@ -247,6 +252,11 @@ static inline int gpio_cansleep(unsigned int gpio)
return __gpio_cansleep(gpio);
}
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return __gpio_to_irq(gpio);
+}
+
#else /* !CONFIG_GPIOLIB */
static inline int gpio_request(unsigned gpio, const char *label)
@@ -279,10 +289,6 @@ static inline void gpio_set_value(unsigned gpio, int value)
return bfin_gpio_set_value(gpio, value);
}
-#include <asm-generic/gpio.h> /* cansleep wrappers */
-#endif /* !CONFIG_GPIOLIB */
-#include <asm/irq.h>
-
static inline int gpio_to_irq(unsigned gpio)
{
if (likely(gpio < MAX_BLACKFIN_GPIOS))
@@ -291,6 +297,9 @@ static inline int gpio_to_irq(unsigned gpio)
return -EINVAL;
}
+#include <asm-generic/gpio.h> /* cansleep wrappers */
+#endif /* !CONFIG_GPIOLIB */
+
static inline int irq_to_gpio(unsigned irq)
{
return (irq - GPIO_IRQ_BASE);
diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h
index e7c0623f909..12f4060a31b 100644
--- a/arch/blackfin/include/asm/irq.h
+++ b/arch/blackfin/include/asm/irq.h
@@ -12,6 +12,9 @@
#include <linux/irqflags.h>
+/* IRQs that may be used by external irq_chip controllers */
+#define NR_SPARE_IRQS 32
+
#include <mach/anomaly.h>
/* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */
@@ -35,4 +38,8 @@
#include <asm-generic/irq.h>
+#ifdef CONFIG_NMI_WATCHDOG
+# define ARCH_HAS_NMI_WATCHDOG
+#endif
+
#endif /* _BFIN_IRQ_H_ */
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index ae8ef4ffd80..e1a9b4624f9 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -7,12 +7,13 @@
#ifndef __BLACKFIN_MMU_CONTEXT_H__
#define __BLACKFIN_MMU_CONTEXT_H__
-#include <linux/gfp.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <asm/setup.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/cplbinit.h>
+#include <asm/sections.h>
/* Note: L1 stacks are CPU-private things, so we bluntly disable this
feature in SMP mode, and use the per-CPU scratch SRAM bank only to
@@ -117,9 +118,16 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr,
unsigned long flags)
{
unsigned long *mask = mm->context.page_rwx_mask;
- unsigned long page = addr >> 12;
- unsigned long idx = page >> 5;
- unsigned long bit = 1 << (page & 31);
+ unsigned long page;
+ unsigned long idx;
+ unsigned long bit;
+
+ if (unlikely(addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE))
+ page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> 12;
+ else
+ page = addr >> 12;
+ idx = page >> 5;
+ bit = 1 << (page & 31);
if (flags & VM_READ)
mask[idx] |= bit;
diff --git a/arch/blackfin/include/asm/nand.h b/arch/blackfin/include/asm/nand.h
index 3ae8b569edf..3a1e79dfc8d 100644
--- a/arch/blackfin/include/asm/nand.h
+++ b/arch/blackfin/include/asm/nand.h
@@ -1,5 +1,5 @@
/*
- * BF5XX - NAND flash controller platfrom_device info
+ * BF5XX - NAND flash controller platform_device info
*
* Copyright 2007-2008 Analog Devices, Inc.
*
@@ -8,7 +8,7 @@
/* struct bf5xx_nand_platform
*
- * define a interface between platfrom board specific code and
+ * define a interface between platform board specific code and
* bf54x NFC driver.
*
* nr_partitions = number of partitions pointed to be partitoons (or zero)
diff --git a/arch/blackfin/include/asm/nmi.h b/arch/blackfin/include/asm/nmi.h
new file mode 100644
index 00000000000..b9caac4fcfd
--- /dev/null
+++ b/arch/blackfin/include/asm/nmi.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2
+ */
+
+#ifndef _BFIN_NMI_H_
+#define _BFIN_NMI_H_
+
+#include <linux/nmi.h>
+
+#endif
diff --git a/arch/blackfin/include/asm/page.h b/arch/blackfin/include/asm/page.h
index 1d04e407834..d0ce975bcd4 100644
--- a/arch/blackfin/include/asm/page.h
+++ b/arch/blackfin/include/asm/page.h
@@ -15,4 +15,7 @@
((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
#endif
diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h
index b33a4488f49..aaa1c6c2bc1 100644
--- a/arch/blackfin/include/asm/ptrace.h
+++ b/arch/blackfin/include/asm/ptrace.h
@@ -24,6 +24,8 @@
#ifndef __ASSEMBLY__
+struct task_struct;
+
/* this struct defines the way the registers are stored on the
stack during a system call. */
@@ -101,9 +103,30 @@ struct pt_regs {
master interrupt enable. */
#define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1)))
#define instruction_pointer(regs) ((regs)->pc)
+#define user_stack_pointer(regs) ((regs)->usp)
#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
+#define arch_has_single_step() (1)
+extern void user_enable_single_step(struct task_struct *child);
+extern void user_disable_single_step(struct task_struct *child);
+/* common code demands this function */
+#define ptrace_disable(child) user_disable_single_step(child)
+
+/*
+ * Get the address of the live pt_regs for the specified task.
+ * These are saved onto the top kernel stack when the process
+ * is not running.
+ *
+ * Note: if a user thread is execve'd from kernel space, the
+ * kernel stack will not be empty on entry to the kernel, so
+ * ptracing these tasks will fail.
+ */
+#define task_pt_regs(task) \
+ (struct pt_regs *) \
+ ((unsigned long)task_stack_page(task) + \
+ (THREAD_SIZE - sizeof(struct pt_regs)))
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
@@ -173,4 +196,6 @@ extern void show_regs(struct pt_regs *);
#define PT_FDPIC_EXEC 232
#define PT_FDPIC_INTERP 236
+#define PT_LAST_PSEUDO PT_FDPIC_INTERP
+
#endif /* _BFIN_PTRACE_H */
diff --git a/arch/blackfin/include/asm/sections.h b/arch/blackfin/include/asm/sections.h
index 42f6c53c59c..14a3e66d916 100644
--- a/arch/blackfin/include/asm/sections.h
+++ b/arch/blackfin/include/asm/sections.h
@@ -21,6 +21,9 @@ extern unsigned long memory_start, memory_end, physical_mem_end;
extern char _stext_l1[], _etext_l1[], _text_l1_lma[], __weak _text_l1_len[];
extern char _sdata_l1[], _edata_l1[], _sbss_l1[], _ebss_l1[],
_data_l1_lma[], __weak _data_l1_len[];
+#ifdef CONFIG_ROMKERNEL
+extern char _data_lma[], _data_len[], _sinitdata[], _einitdata[], _init_data_lma[], _init_data_len[];
+#endif
extern char _sdata_b_l1[], _edata_b_l1[], _sbss_b_l1[], _ebss_b_l1[],
_data_b_l1_lma[], __weak _data_b_l1_len[];
extern char _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[],
diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h
index 6a0fe94b84a..f5b53796711 100644
--- a/arch/blackfin/include/asm/smp.h
+++ b/arch/blackfin/include/asm/smp.h
@@ -22,8 +22,23 @@ extern char coreb_trampoline_start, coreb_trampoline_end;
struct corelock_slot {
int lock;
};
+extern struct corelock_slot corelock;
+
+#ifdef __ARCH_SYNC_CORE_ICACHE
+extern unsigned long icache_invld_count[NR_CPUS];
+#endif
+#ifdef __ARCH_SYNC_CORE_DCACHE
+extern unsigned long dcache_invld_count[NR_CPUS];
+#endif
void smp_icache_flush_range_others(unsigned long start,
unsigned long end);
+#ifdef CONFIG_HOTPLUG_CPU
+void coreb_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void cpu_die(void);
+void platform_cpu_die(void);
+int __cpu_disable(void);
+int __cpu_die(unsigned int cpu);
+#endif
#endif /* !__ASM_BLACKFIN_SMP_H */
diff --git a/arch/blackfin/include/asm/syscall.h b/arch/blackfin/include/asm/syscall.h
new file mode 100644
index 00000000000..4921a4815cc
--- /dev/null
+++ b/arch/blackfin/include/asm/syscall.h
@@ -0,0 +1,96 @@
+/*
+ * Magic syscall break down functions
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BLACKFIN_SYSCALL_H__
+#define __ASM_BLACKFIN_SYSCALL_H__
+
+/*
+ * Blackfin syscalls are simple:
+ * enter:
+ * p0: syscall number
+ * r{0,1,2,3,4,5}: syscall args 0,1,2,3,4,5
+ * exit:
+ * r0: return/error value
+ */
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+static inline long
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+ return regs->p0;
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+ regs->p0 = regs->orig_p0;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+ return IS_ERR_VALUE(regs->r0) ? regs->r0 : 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+ return regs->r0;
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+ int error, long val)
+{
+ regs->r0 = error ? -error : val;
+}
+
+/**
+ * syscall_get_arguments()
+ * @task: unused
+ * @regs: the register layout to extract syscall arguments from
+ * @i: first syscall argument to extract
+ * @n: number of syscall arguments to extract
+ * @args: array to return the syscall arguments in
+ *
+ * args[0] gets i'th argument, args[n - 1] gets the i+n-1'th argument
+ */
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+ unsigned int i, unsigned int n, unsigned long *args)
+{
+ /*
+ * Assume the ptrace layout doesn't change -- r5 is first in memory,
+ * then r4, ..., then r0. So we simply reverse the ptrace register
+ * array in memory to store into the args array.
+ */
+ long *aregs = &regs->r0 - i;
+
+ BUG_ON(i > 5 || i + n > 6);
+
+ while (n--)
+ *args++ = *aregs--;
+}
+
+/* See syscall_get_arguments() comments */
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+ unsigned int i, unsigned int n, const unsigned long *args)
+{
+ long *aregs = &regs->r0 - i;
+
+ BUG_ON(i > 5 || i + n > 6);
+
+ while (n--)
+ *aregs-- = *args++;
+}
+
+#endif
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index a40d9368c38..e9a5614cdbb 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2009 Analog Devices Inc.
+ * Copyright 2004-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -17,7 +17,7 @@
/* Thread Align Mask to reach to the top of the stack
* for any process
*/
-#define ALIGN_PAGE_MASK 0xffffe000
+#define ALIGN_PAGE_MASK 0xffffe000
/*
* Size of kernel stack for each process. This must be a power of 2...
@@ -57,7 +57,7 @@ struct thread_info {
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = INIT_PREEMPT_COUNT, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
@@ -73,8 +73,7 @@ __attribute_const__
static inline struct thread_info *current_thread_info(void)
{
struct thread_info *ti;
- __asm__("%0 = sp;" : "=da"(ti) :
- );
+ __asm__("%0 = sp;" : "=da"(ti));
return (struct thread_info *)((long)ti & ~((long)THREAD_SIZE-1));
}
@@ -99,21 +98,23 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
-#define TIF_MEMDIE 4
+#define TIF_MEMDIE 4
#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
-#define TIF_FREEZE 6 /* is freezing for suspend */
-#define TIF_IRQ_SYNC 7 /* sync pipeline stage */
-#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
+#define TIF_FREEZE 6 /* is freezing for suspend */
+#define TIF_IRQ_SYNC 7 /* sync pipeline stage */
+#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
+#define TIF_SINGLESTEP 9
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_FREEZE (1<<TIF_FREEZE)
-#define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
+#define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC)
+#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
diff --git a/arch/blackfin/include/asm/time.h b/arch/blackfin/include/asm/time.h
index 589e937ed1e..9ca7db844d1 100644
--- a/arch/blackfin/include/asm/time.h
+++ b/arch/blackfin/include/asm/time.h
@@ -23,9 +23,7 @@
*/
#ifndef CONFIG_CPU_FREQ
-#define TIME_SCALE 1
-#define __bfin_cycles_off (0)
-#define __bfin_cycles_mod (0)
+# define TIME_SCALE 1
#else
/*
* Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 .
@@ -33,9 +31,16 @@
* adjust the Core Timer Presale Register. This way we don't lose time.
*/
#define TIME_SCALE 4
+
+# ifdef CONFIG_CYCLES_CLOCKSOURCE
extern unsigned long long __bfin_cycles_off;
extern unsigned int __bfin_cycles_mod;
+# endif
+#endif
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+extern void bfin_coretmr_init(void);
+extern void bfin_coretmr_clockevent_init(void);
#endif
-extern void __init setup_core_timer(void);
#endif
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index a8ddbc8ed5a..346a421f156 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_KGDB_TESTS) += kgdb_test.o
+obj-$(CONFIG_NMI_WATCHDOG) += nmi.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_EARLY_PRINTK) += shadow_console.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 924c00286ba..26403d1c9e6 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -91,7 +91,7 @@ late_initcall(proc_dma_init);
*/
int request_dma(unsigned int channel, const char *device_id)
{
- pr_debug("request_dma() : BEGIN \n");
+ pr_debug("request_dma() : BEGIN\n");
if (device_id == NULL)
printk(KERN_WARNING "request_dma(%u): no device_id given\n", channel);
@@ -107,7 +107,7 @@ int request_dma(unsigned int channel, const char *device_id)
#endif
if (atomic_cmpxchg(&dma_ch[channel].chan_status, 0, 1)) {
- pr_debug("DMA CHANNEL IN USE \n");
+ pr_debug("DMA CHANNEL IN USE\n");
return -EBUSY;
}
@@ -131,7 +131,7 @@ int request_dma(unsigned int channel, const char *device_id)
* you have to request DMA, before doing any operations on
* descriptor/channel
*/
- pr_debug("request_dma() : END \n");
+ pr_debug("request_dma() : END\n");
return 0;
}
EXPORT_SYMBOL(request_dma);
@@ -171,7 +171,7 @@ static void clear_dma_buffer(unsigned int channel)
void free_dma(unsigned int channel)
{
- pr_debug("freedma() : BEGIN \n");
+ pr_debug("freedma() : BEGIN\n");
BUG_ON(channel >= MAX_DMA_CHANNELS ||
!atomic_read(&dma_ch[channel].chan_status));
@@ -185,7 +185,7 @@ void free_dma(unsigned int channel)
/* Clear the DMA Variable in the Channel */
atomic_set(&dma_ch[channel].chan_status, 0);
- pr_debug("freedma() : END \n");
+ pr_debug("freedma() : END\n");
}
EXPORT_SYMBOL(free_dma);
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index a174596cc00..e35e20f00d9 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -1289,44 +1289,50 @@ __initcall(gpio_register_proc);
#endif
#ifdef CONFIG_GPIOLIB
-int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
{
return bfin_gpio_direction_input(gpio);
}
-int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
+static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
{
return bfin_gpio_direction_output(gpio, level);
}
-int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
{
return bfin_gpio_get_value(gpio);
}
-void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
{
return bfin_gpio_set_value(gpio, value);
}
-int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
{
return bfin_gpio_request(gpio, chip->label);
}
-void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
+static void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
{
return bfin_gpio_free(gpio);
}
+static int bfin_gpiolib_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+ return gpio + GPIO_IRQ_BASE;
+}
+
static struct gpio_chip bfin_chip = {
- .label = "Blackfin-GPIOlib",
+ .label = "BFIN-GPIO",
.direction_input = bfin_gpiolib_direction_input,
.get = bfin_gpiolib_get_value,
.direction_output = bfin_gpiolib_direction_output,
.set = bfin_gpiolib_set_value,
.request = bfin_gpiolib_gpio_request,
.free = bfin_gpiolib_gpio_free,
+ .to_irq = bfin_gpiolib_gpio_to_irq,
.base = 0,
.ngpio = MAX_BLACKFIN_GPIOS,
};
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
index 8d42b9e50df..30fd6417f06 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
@@ -64,6 +64,15 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
icplb_tbl[cpu][i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0);
}
+#ifdef CONFIG_ROMKERNEL
+ /* Cover kernel XIP flash area */
+ addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1);
+ dcplb_tbl[cpu][i_d].addr = addr;
+ dcplb_tbl[cpu][i_d++].data = d_data | CPLB_USER_RD;
+ icplb_tbl[cpu][i_i].addr = addr;
+ icplb_tbl[cpu][i_i++].data = i_data | CPLB_USER_RD;
+#endif
+
/* Cover L1 memory. One 4M area for code and data each is enough. */
#if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0
dcplb_tbl[cpu][i_d].addr = get_l1_data_a_start_cpu(cpu);
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index 930c01c0681..87b25b1b30e 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -31,6 +31,12 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS];
int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS];
int nr_cplb_flush[NR_CPUS];
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+#define MGR_ATTR __attribute__((l1_text))
+#else
+#define MGR_ATTR
+#endif
+
/*
* Given the contents of the status register, return the index of the
* CPLB that caused the fault.
@@ -59,7 +65,7 @@ static int icplb_rr_index[NR_CPUS], dcplb_rr_index[NR_CPUS];
/*
* Find an ICPLB entry to be evicted and return its index.
*/
-static int evict_one_icplb(unsigned int cpu)
+MGR_ATTR static int evict_one_icplb(unsigned int cpu)
{
int i;
for (i = first_switched_icplb; i < MAX_CPLBS; i++)
@@ -74,7 +80,7 @@ static int evict_one_icplb(unsigned int cpu)
return i;
}
-static int evict_one_dcplb(unsigned int cpu)
+MGR_ATTR static int evict_one_dcplb(unsigned int cpu)
{
int i;
for (i = first_switched_dcplb; i < MAX_CPLBS; i++)
@@ -89,7 +95,7 @@ static int evict_one_dcplb(unsigned int cpu)
return i;
}
-static noinline int dcplb_miss(unsigned int cpu)
+MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)
{
unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();
int status = bfin_read_DCPLB_STATUS();
@@ -114,10 +120,15 @@ static noinline int dcplb_miss(unsigned int cpu)
d_data = L2_DMEMORY;
} else if (addr >= physical_mem_end) {
if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
- addr &= ~(4 * 1024 * 1024 - 1);
- d_data &= ~PAGE_SIZE_4KB;
- d_data |= PAGE_SIZE_4MB;
- d_data |= CPLB_USER_RD | CPLB_USER_WR;
+ mask = current_rwx_mask[cpu];
+ if (mask) {
+ int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
+ int idx = page >> 5;
+ int bit = 1 << (page & 31);
+
+ if (mask[idx] & bit)
+ d_data |= CPLB_USER_RD;
+ }
} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
&& (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {
addr &= ~(1 * 1024 * 1024 - 1);
@@ -126,7 +137,9 @@ static noinline int dcplb_miss(unsigned int cpu)
} else
return CPLB_PROT_VIOL;
} else if (addr >= _ramend) {
- d_data |= CPLB_USER_RD | CPLB_USER_WR;
+ d_data |= CPLB_USER_RD | CPLB_USER_WR;
+ if (reserved_mem_dcache_on)
+ d_data |= CPLB_L1_CHBL;
} else {
mask = current_rwx_mask[cpu];
if (mask) {
@@ -156,7 +169,7 @@ static noinline int dcplb_miss(unsigned int cpu)
return 0;
}
-static noinline int icplb_miss(unsigned int cpu)
+MGR_ATTR static noinline int icplb_miss(unsigned int cpu)
{
unsigned long addr = bfin_read_ICPLB_FAULT_ADDR();
int status = bfin_read_ICPLB_STATUS();
@@ -204,10 +217,19 @@ static noinline int icplb_miss(unsigned int cpu)
i_data = L2_IMEMORY;
} else if (addr >= physical_mem_end) {
if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
- addr &= ~(4 * 1024 * 1024 - 1);
- i_data &= ~PAGE_SIZE_4KB;
- i_data |= PAGE_SIZE_4MB;
- i_data |= CPLB_USER_RD;
+ if (!(status & FAULT_USERSUPV)) {
+ unsigned long *mask = current_rwx_mask[cpu];
+
+ if (mask) {
+ int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
+ int idx = page >> 5;
+ int bit = 1 << (page & 31);
+
+ mask += 2 * page_mask_nelts;
+ if (mask[idx] & bit)
+ i_data |= CPLB_USER_RD;
+ }
+ }
} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
&& (status & FAULT_USERSUPV)) {
addr &= ~(1 * 1024 * 1024 - 1);
@@ -217,6 +239,8 @@ static noinline int icplb_miss(unsigned int cpu)
return CPLB_PROT_VIOL;
} else if (addr >= _ramend) {
i_data |= CPLB_USER_RD;
+ if (reserved_mem_icache_on)
+ i_data |= CPLB_L1_CHBL;
} else {
/*
* Two cases to distinguish - a supervisor access must
@@ -251,7 +275,7 @@ static noinline int icplb_miss(unsigned int cpu)
return 0;
}
-static noinline int dcplb_protection_fault(unsigned int cpu)
+MGR_ATTR static noinline int dcplb_protection_fault(unsigned int cpu)
{
int status = bfin_read_DCPLB_STATUS();
@@ -271,7 +295,7 @@ static noinline int dcplb_protection_fault(unsigned int cpu)
return CPLB_PROT_VIOL;
}
-int cplb_hdr(int seqstat, struct pt_regs *regs)
+MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
{
int cause = seqstat & 0x3f;
unsigned int cpu = raw_smp_processor_id();
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 282a7919821..bfe75af4e8b 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -56,6 +56,15 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB;
}
+#ifdef CONFIG_ROMKERNEL
+ /* Cover kernel XIP flash area */
+ addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1);
+ d_tbl[i_d].addr = addr;
+ d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB;
+ i_tbl[i_i].addr = addr;
+ i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB;
+#endif
+
/* Cover L1 memory. One 4M area for code and data each is enough. */
if (cpu == 0) {
if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) {
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index e937f323d82..04ddcfeb798 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -116,7 +116,7 @@ EXPORT_SYMBOL(dma_free_coherent);
void __dma_sync(dma_addr_t addr, size_t size,
enum dma_data_direction dir)
{
- _dma_sync(addr, size, dir);
+ __dma_sync_inline(addr, size, dir);
}
EXPORT_SYMBOL(__dma_sync);
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S
index f27dc2292e1..686478f5f66 100644
--- a/arch/blackfin/kernel/entry.S
+++ b/arch/blackfin/kernel/entry.S
@@ -44,7 +44,7 @@ ENTRY(_ret_from_fork)
sti r4;
#endif /* CONFIG_IPIPE */
SP += -12;
- call _schedule_tail;
+ pseudo_long_call _schedule_tail, p5;
SP += 12;
r0 = [sp + PT_IPEND];
cc = bittst(r0,1);
@@ -79,7 +79,7 @@ ENTRY(_sys_vfork)
r0 += 24;
[--sp] = rets;
SP += -12;
- call _bfin_vfork;
+ pseudo_long_call _bfin_vfork, p2;
SP += 12;
rets = [sp++];
rts;
@@ -90,7 +90,7 @@ ENTRY(_sys_clone)
r0 += 24;
[--sp] = rets;
SP += -12;
- call _bfin_clone;
+ pseudo_long_call _bfin_clone, p2;
SP += 12;
rets = [sp++];
rts;
@@ -101,7 +101,7 @@ ENTRY(_sys_rt_sigreturn)
r0 += 24;
[--sp] = rets;
SP += -12;
- call _do_rt_sigreturn;
+ pseudo_long_call _do_rt_sigreturn, p2;
SP += 12;
rets = [sp++];
rts;
diff --git a/arch/blackfin/kernel/ftrace-entry.S b/arch/blackfin/kernel/ftrace-entry.S
index 76dd4fbcd17..d66446b572c 100644
--- a/arch/blackfin/kernel/ftrace-entry.S
+++ b/arch/blackfin/kernel/ftrace-entry.S
@@ -1,7 +1,7 @@
/*
* mcount and friends -- ftrace stuff
*
- * Copyright (C) 2009 Analog Devices Inc.
+ * Copyright (C) 2009-2010 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
@@ -21,6 +21,15 @@
* function will be waiting there. mmmm pie.
*/
ENTRY(__mcount)
+#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
+ /* optional micro optimization: return if stopped */
+ p1.l = _function_trace_stop;
+ p1.h = _function_trace_stop;
+ r3 = [p1];
+ cc = r3 == 0;
+ if ! cc jump _ftrace_stub (bp);
+#endif
+
/* save third function arg early so we can do testing below */
[--sp] = r2;
@@ -106,9 +115,12 @@ ENTRY(_ftrace_graph_caller)
[--sp] = r1;
[--sp] = rets;
- /* prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) */
- r0 = sp;
- r1 = rets;
+ /* prepare_ftrace_return(parent, self_addr, frame_pointer) */
+ r0 = sp; /* unsigned long *parent */
+ r1 = rets; /* unsigned long self_addr */
+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
+ r2 = fp; /* unsigned long frame_pointer */
+#endif
r0 += 16; /* skip the 4 local regs on stack */
r1 += -MCOUNT_INSN_SIZE;
call _prepare_ftrace_return;
@@ -127,6 +139,9 @@ ENTRY(_return_to_handler)
[--sp] = r1;
/* get original return address */
+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
+ r0 = fp; /* Blackfin is sane, so omit this */
+#endif
call _ftrace_return_to_handler;
rets = r0;
diff --git a/arch/blackfin/kernel/ftrace.c b/arch/blackfin/kernel/ftrace.c
index f2c85ac6f2d..a61d948ea92 100644
--- a/arch/blackfin/kernel/ftrace.c
+++ b/arch/blackfin/kernel/ftrace.c
@@ -16,7 +16,8 @@
* Hook the return address and push it in the stack of return addrs
* in current thread info.
*/
-void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+ unsigned long frame_pointer)
{
struct ftrace_graph_ent trace;
unsigned long return_hooker = (unsigned long)&return_to_handler;
@@ -24,7 +25,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
if (unlikely(atomic_read(&current->tracing_graph_pause)))
return;
- if (ftrace_push_return_trace(*parent, self_addr, &trace.depth, 0) == -EBUSY)
+ if (ftrace_push_return_trace(*parent, self_addr, &trace.depth,
+ frame_pointer) == -EBUSY)
return;
trace.func = self_addr;
diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c
index 118c5b9deda..d3970e8acd1 100644
--- a/arch/blackfin/kernel/init_task.c
+++ b/arch/blackfin/kernel/init_task.c
@@ -28,5 +28,5 @@ EXPORT_SYMBOL(init_task);
* "init_task" linker map entry.
*/
union thread_union init_thread_union
- __attribute__ ((__section__(".init_task.data"))) = {
+ __init_task_data = {
INIT_THREAD_INFO(init_task)};
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
index a77307a4473..1a496cd71ba 100644
--- a/arch/blackfin/kernel/ipipe.c
+++ b/arch/blackfin/kernel/ipipe.c
@@ -27,7 +27,6 @@
#include <linux/interrupt.h>
#include <linux/percpu.h>
#include <linux/bitops.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kthread.h>
#include <linux/unistd.h>
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
index 34c7c3ed2c9..2c501ceb1e5 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -145,7 +145,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
#endif
}
-struct hw_breakpoint {
+static struct hw_breakpoint {
unsigned int occupied:1;
unsigned int skip:1;
unsigned int enabled:1;
@@ -155,7 +155,7 @@ struct hw_breakpoint {
unsigned int addr;
} breakinfo[HW_WATCHPOINT_NUM];
-int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
+static int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
{
int breakno;
int bfin_type;
@@ -202,7 +202,7 @@ int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
return -ENOSPC;
}
-int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
+static int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
{
int breakno;
int bfin_type;
@@ -230,7 +230,7 @@ int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
return 0;
}
-void bfin_remove_all_hw_break(void)
+static void bfin_remove_all_hw_break(void)
{
int breakno;
@@ -242,7 +242,7 @@ void bfin_remove_all_hw_break(void)
breakinfo[breakno].type = TYPE_DATA_WATCHPOINT;
}
-void bfin_correct_hw_break(void)
+static void bfin_correct_hw_break(void)
{
int breakno;
unsigned int wpiactl = 0;
diff --git a/arch/blackfin/kernel/nmi.c b/arch/blackfin/kernel/nmi.c
new file mode 100644
index 00000000000..0b5f72f17fd
--- /dev/null
+++ b/arch/blackfin/kernel/nmi.c
@@ -0,0 +1,299 @@
+/*
+ * Blackfin nmi_watchdog Driver
+ *
+ * Originally based on bfin_wdt.c
+ * Copyright 2010-2010 Analog Devices Inc.
+ * Graff Yang <graf.yang@analog.com>
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/bitops.h>
+#include <linux/hardirq.h>
+#include <linux/sysdev.h>
+#include <linux/pm.h>
+#include <linux/nmi.h>
+#include <linux/smp.h>
+#include <linux/timer.h>
+#include <asm/blackfin.h>
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/bfin_watchdog.h>
+
+#define DRV_NAME "nmi-wdt"
+
+#define NMI_WDT_TIMEOUT 5 /* 5 seconds */
+#define NMI_CHECK_TIMEOUT (4 * HZ) /* 4 seconds in jiffies */
+static int nmi_wdt_cpu = 1;
+
+static unsigned int timeout = NMI_WDT_TIMEOUT;
+static int nmi_active;
+
+static unsigned short wdoga_ctl;
+static unsigned int wdoga_cnt;
+static struct corelock_slot saved_corelock;
+static atomic_t nmi_touched[NR_CPUS];
+static struct timer_list ntimer;
+
+enum {
+ COREA_ENTER_NMI = 0,
+ COREA_EXIT_NMI,
+ COREB_EXIT_NMI,
+
+ NMI_EVENT_NR,
+};
+static unsigned long nmi_event __attribute__ ((__section__(".l2.bss")));
+
+/* we are in nmi, non-atomic bit ops is safe */
+static inline void set_nmi_event(int event)
+{
+ __set_bit(event, &nmi_event);
+}
+
+static inline void wait_nmi_event(int event)
+{
+ while (!test_bit(event, &nmi_event))
+ barrier();
+ __clear_bit(event, &nmi_event);
+}
+
+static inline void send_corea_nmi(void)
+{
+ wdoga_ctl = bfin_read_WDOGA_CTL();
+ wdoga_cnt = bfin_read_WDOGA_CNT();
+
+ bfin_write_WDOGA_CTL(WDEN_DISABLE);
+ bfin_write_WDOGA_CNT(0);
+ bfin_write_WDOGA_CTL(WDEN_ENABLE | ICTL_NMI);
+}
+
+static inline void restore_corea_nmi(void)
+{
+ bfin_write_WDOGA_CTL(WDEN_DISABLE);
+ bfin_write_WDOGA_CTL(WDOG_EXPIRED | WDEN_DISABLE | ICTL_NONE);
+
+ bfin_write_WDOGA_CNT(wdoga_cnt);
+ bfin_write_WDOGA_CTL(wdoga_ctl);
+}
+
+static inline void save_corelock(void)
+{
+ saved_corelock = corelock;
+ corelock.lock = 0;
+}
+
+static inline void restore_corelock(void)
+{
+ corelock = saved_corelock;
+}
+
+
+static inline void nmi_wdt_keepalive(void)
+{
+ bfin_write_WDOGB_STAT(0);
+}
+
+static inline void nmi_wdt_stop(void)
+{
+ bfin_write_WDOGB_CTL(WDEN_DISABLE);
+}
+
+/* before calling this function, you must stop the WDT */
+static inline void nmi_wdt_clear(void)
+{
+ /* clear TRO bit, disable event generation */
+ bfin_write_WDOGB_CTL(WDOG_EXPIRED | WDEN_DISABLE | ICTL_NONE);
+}
+
+static inline void nmi_wdt_start(void)
+{
+ bfin_write_WDOGB_CTL(WDEN_ENABLE | ICTL_NMI);
+}
+
+static inline int nmi_wdt_running(void)
+{
+ return ((bfin_read_WDOGB_CTL() & WDEN_MASK) != WDEN_DISABLE);
+}
+
+static inline int nmi_wdt_set_timeout(unsigned long t)
+{
+ u32 cnt, max_t, sclk;
+ int run;
+
+ sclk = get_sclk();
+ max_t = -1 / sclk;
+ cnt = t * sclk;
+ if (t > max_t) {
+ pr_warning("NMI: timeout value is too large\n");
+ return -EINVAL;
+ }
+
+ run = nmi_wdt_running();
+ nmi_wdt_stop();
+ bfin_write_WDOGB_CNT(cnt);
+ if (run)
+ nmi_wdt_start();
+
+ timeout = t;
+
+ return 0;
+}
+
+int check_nmi_wdt_touched(void)
+{
+ unsigned int this_cpu = smp_processor_id();
+ unsigned int cpu;
+
+ cpumask_t mask = cpu_online_map;
+
+ if (!atomic_read(&nmi_touched[this_cpu]))
+ return 0;
+
+ atomic_set(&nmi_touched[this_cpu], 0);
+
+ cpu_clear(this_cpu, mask);
+ for_each_cpu_mask(cpu, mask) {
+ invalidate_dcache_range((unsigned long)(&nmi_touched[cpu]),
+ (unsigned long)(&nmi_touched[cpu]));
+ if (!atomic_read(&nmi_touched[cpu]))
+ return 0;
+ atomic_set(&nmi_touched[cpu], 0);
+ }
+
+ return 1;
+}
+
+static void nmi_wdt_timer(unsigned long data)
+{
+ if (check_nmi_wdt_touched())
+ nmi_wdt_keepalive();
+
+ mod_timer(&ntimer, jiffies + NMI_CHECK_TIMEOUT);
+}
+
+static int __init init_nmi_wdt(void)
+{
+ nmi_wdt_set_timeout(timeout);
+ nmi_wdt_start();
+ nmi_active = true;
+
+ init_timer(&ntimer);
+ ntimer.function = nmi_wdt_timer;
+ ntimer.expires = jiffies + NMI_CHECK_TIMEOUT;
+ add_timer(&ntimer);
+
+ pr_info("nmi_wdt: initialized: timeout=%d sec\n", timeout);
+ return 0;
+}
+device_initcall(init_nmi_wdt);
+
+void touch_nmi_watchdog(void)
+{
+ atomic_set(&nmi_touched[smp_processor_id()], 1);
+}
+
+/* Suspend/resume support */
+#ifdef CONFIG_PM
+static int nmi_wdt_suspend(struct sys_device *dev, pm_message_t state)
+{
+ nmi_wdt_stop();
+ return 0;
+}
+
+static int nmi_wdt_resume(struct sys_device *dev)
+{
+ if (nmi_active)
+ nmi_wdt_start();
+ return 0;
+}
+
+static struct sysdev_class nmi_sysclass = {
+ .name = DRV_NAME,
+ .resume = nmi_wdt_resume,
+ .suspend = nmi_wdt_suspend,
+};
+
+static struct sys_device device_nmi_wdt = {
+ .id = 0,
+ .cls = &nmi_sysclass,
+};
+
+static int __init init_nmi_wdt_sysfs(void)
+{
+ int error;
+
+ if (!nmi_active)
+ return 0;
+
+ error = sysdev_class_register(&nmi_sysclass);
+ if (!error)
+ error = sysdev_register(&device_nmi_wdt);
+ return error;
+}
+late_initcall(init_nmi_wdt_sysfs);
+
+#endif /* CONFIG_PM */
+
+
+asmlinkage notrace void do_nmi(struct pt_regs *fp)
+{
+ unsigned int cpu = smp_processor_id();
+ nmi_enter();
+
+ cpu_pda[cpu].__nmi_count += 1;
+
+ if (cpu == nmi_wdt_cpu) {
+ /* CoreB goes here first */
+
+ /* reload the WDOG_STAT */
+ nmi_wdt_keepalive();
+
+ /* clear nmi interrupt for CoreB */
+ nmi_wdt_stop();
+ nmi_wdt_clear();
+
+ /* trigger NMI interrupt of CoreA */
+ send_corea_nmi();
+
+ /* waiting CoreB to enter NMI */
+ wait_nmi_event(COREA_ENTER_NMI);
+
+ /* recover WDOGA's settings */
+ restore_corea_nmi();
+
+ save_corelock();
+
+ /* corelock is save/cleared, CoreA is dummping messages */
+
+ wait_nmi_event(COREA_EXIT_NMI);
+ } else {
+ /* OK, CoreA entered NMI */
+ set_nmi_event(COREA_ENTER_NMI);
+ }
+
+ pr_emerg("\nNMI Watchdog detected LOCKUP, dump for CPU %d\n", cpu);
+ dump_bfin_process(fp);
+ dump_bfin_mem(fp);
+ show_regs(fp);
+ dump_bfin_trace_buffer();
+ show_stack(current, (unsigned long *)fp);
+
+ if (cpu == nmi_wdt_cpu) {
+ pr_emerg("This fault is not recoverable, sorry!\n");
+
+ /* CoreA dump finished, restore the corelock */
+ restore_corelock();
+
+ set_nmi_event(COREB_EXIT_NMI);
+ } else {
+ /* CoreB dump finished, notice the CoreA we are done */
+ set_nmi_event(COREA_EXIT_NMI);
+
+ /* synchronize with CoreA */
+ wait_nmi_event(COREB_EXIT_NMI);
+ }
+
+ nmi_exit();
+}
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index b56b0e485e0..93ec07da2e5 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -11,6 +11,7 @@
#include <linux/unistd.h>
#include <linux/user.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/tick.h>
#include <linux/fs.h>
@@ -98,13 +99,6 @@ void cpu_idle(void)
}
}
-/* Fill in the fpu structure for a core dump. */
-
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
-{
- return 1;
-}
-
/*
* This gets run with P1 containing the
* function to call, and R1 containing
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 65567dc4b9f..43eb969405d 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -1,6 +1,6 @@
/*
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
- * these modifications are Copyright 2004-2009 Analog Devices Inc.
+ * these modifications are Copyright 2004-2010 Analog Devices Inc.
*
* Licensed under the GPL-2
*/
@@ -9,10 +9,13 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
+#include <linux/elf.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
+#include <linux/regset.h>
#include <linux/signal.h>
+#include <linux/tracehook.h>
#include <linux/uaccess.h>
#include <asm/page.h>
@@ -25,90 +28,57 @@
#include <asm/cacheflush.h>
#include <asm/mem_map.h>
-#define TEXT_OFFSET 0
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
-/* determines which bits in the SYSCFG reg the user has access to. */
-/* 1 = access 0 = no access */
-#define SYSCFG_MASK 0x0007 /* SYSCFG reg */
-/* sets the trace bits. */
-#define TRACE_BITS 0x0001
-
-/* Find the stack offset for a register, relative to thread.esp0. */
-#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
-
-/*
- * Get the address of the live pt_regs for the specified task.
- * These are saved onto the top kernel stack when the process
- * is not running.
- *
- * Note: if a user thread is execve'd from kernel space, the
- * kernel stack will not be empty on entry to the kernel, so
- * ptracing these tasks will fail.
- */
-static inline struct pt_regs *get_user_regs(struct task_struct *task)
-{
- return (struct pt_regs *)
- ((unsigned long)task_stack_page(task) +
- (THREAD_SIZE - sizeof(struct pt_regs)));
-}
-
-/*
- * Get all user integer registers.
- */
-static inline int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
-{
- struct pt_regs regs;
- memcpy(&regs, get_user_regs(tsk), sizeof(regs));
- regs.usp = tsk->thread.usp;
- return copy_to_user(uregs, &regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
-}
-
-/* Mapping from PT_xxx to the stack offset at which the register is
- * saved. Notice that usp has no stack-slot and needs to be treated
- * specially (see get_reg/put_reg below).
- */
-
/*
* Get contents of register REGNO in task TASK.
*/
-static inline long get_reg(struct task_struct *task, int regno)
+static inline long
+get_reg(struct task_struct *task, long regno, unsigned long __user *datap)
{
- unsigned char *reg_ptr;
+ long tmp;
+ struct pt_regs *regs = task_pt_regs(task);
- struct pt_regs *regs =
- (struct pt_regs *)((unsigned long)task_stack_page(task) +
- (THREAD_SIZE - sizeof(struct pt_regs)));
- reg_ptr = (char *)regs;
+ if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+ return -EIO;
switch (regno) {
+ case PT_TEXT_ADDR:
+ tmp = task->mm->start_code;
+ break;
+ case PT_TEXT_END_ADDR:
+ tmp = task->mm->end_code;
+ break;
+ case PT_DATA_ADDR:
+ tmp = task->mm->start_data;
+ break;
case PT_USP:
- return task->thread.usp;
+ tmp = task->thread.usp;
+ break;
default:
- if (regno <= 216)
- return *(long *)(reg_ptr + regno);
+ if (regno < sizeof(*regs)) {
+ void *reg_ptr = regs;
+ tmp = *(long *)(reg_ptr + regno);
+ } else
+ return -EIO;
}
- /* slight mystery ... never seems to come here but kernel misbehaves without this code! */
- printk(KERN_WARNING "Request to get for unknown register %d\n", regno);
- return 0;
+ return put_user(tmp, datap);
}
/*
* Write contents of register REGNO in task TASK.
*/
static inline int
-put_reg(struct task_struct *task, int regno, unsigned long data)
+put_reg(struct task_struct *task, long regno, unsigned long data)
{
- char *reg_ptr;
+ struct pt_regs *regs = task_pt_regs(task);
- struct pt_regs *regs =
- (struct pt_regs *)((unsigned long)task_stack_page(task) +
- (THREAD_SIZE - sizeof(struct pt_regs)));
- reg_ptr = (char *)regs;
+ if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+ return -EIO;
switch (regno) {
case PT_PC:
@@ -125,10 +95,18 @@ put_reg(struct task_struct *task, int regno, unsigned long data)
regs->usp = data;
task->thread.usp = data;
break;
+ case PT_SYSCFG: /* don't let userspace screw with this */
+ if ((data & ~1) != 0x6)
+ pr_warning("ptrace: ignore syscfg write of %#lx\n", data);
+ break; /* regs->syscfg = data; break; */
default:
- if (regno <= 216)
- *(long *)(reg_ptr + regno) = data;
+ if (regno < sizeof(*regs)) {
+ void *reg_offset = regs;
+ *(long *)(reg_offset + regno) = data;
+ }
+ /* Ignore writes to pseudo registers */
}
+
return 0;
}
@@ -160,24 +138,98 @@ static inline int is_user_addr_valid(struct task_struct *child,
return -EIO;
}
-void ptrace_enable(struct task_struct *child)
+/*
+ * retrieve the contents of Blackfin userspace general registers
+ */
+static int genregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
{
- unsigned long tmp;
- tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS);
- put_reg(child, PT_SYSCFG, tmp);
+ struct pt_regs *regs = task_pt_regs(target);
+ int ret;
+
+ /* This sucks ... */
+ regs->usp = target->thread.usp;
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ regs, 0, sizeof(*regs));
+ if (ret < 0)
+ return ret;
+
+ return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+ sizeof(*regs), -1);
}
/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
+ * update the contents of the Blackfin userspace general registers
+ */
+static int genregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct pt_regs *regs = task_pt_regs(target);
+ int ret;
+
+ /* Don't let people set SYSCFG (it's at the end of pt_regs) */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ regs, 0, PT_SYSCFG);
+ if (ret < 0)
+ return ret;
+
+ /* This sucks ... */
+ target->thread.usp = regs->usp;
+ /* regs->retx = regs->pc; */
+
+ return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ PT_SYSCFG, -1);
+}
+
+/*
+ * Define the register sets available on the Blackfin under Linux
*/
-void ptrace_disable(struct task_struct *child)
+enum bfin_regset {
+ REGSET_GENERAL,
+};
+
+static const struct user_regset bfin_regsets[] = {
+ [REGSET_GENERAL] = {
+ .core_note_type = NT_PRSTATUS,
+ .n = sizeof(struct pt_regs) / sizeof(long),
+ .size = sizeof(long),
+ .align = sizeof(long),
+ .get = genregs_get,
+ .set = genregs_set,
+ },
+};
+
+static const struct user_regset_view user_bfin_native_view = {
+ .name = "Blackfin",
+ .e_machine = EM_BLACKFIN,
+ .regsets = bfin_regsets,
+ .n = ARRAY_SIZE(bfin_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+ return &user_bfin_native_view;
+}
+
+void user_enable_single_step(struct task_struct *child)
+{
+ struct pt_regs *regs = task_pt_regs(child);
+ regs->syscfg |= SYSCFG_SSSTEP;
+
+ set_tsk_thread_flag(child, TIF_SINGLESTEP);
+}
+
+void user_disable_single_step(struct task_struct *child)
{
- unsigned long tmp;
- /* make sure the single step bit is not set. */
- tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS;
- put_reg(child, PT_SYSCFG, tmp);
+ struct pt_regs *regs = task_pt_regs(child);
+ regs->syscfg &= ~SYSCFG_SSSTEP;
+
+ clear_tsk_thread_flag(child, TIF_SINGLESTEP);
}
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -240,40 +292,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- /* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR:
- {
- unsigned long tmp;
- ret = -EIO;
- tmp = 0;
- if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
- printk(KERN_WARNING "ptrace error : PEEKUSR : temporarily returning "
- "0 - %x sizeof(pt_regs) is %lx\n",
- (int)addr, sizeof(struct pt_regs));
- break;
- }
- if (addr == sizeof(struct pt_regs)) {
- /* PT_TEXT_ADDR */
- tmp = child->mm->start_code + TEXT_OFFSET;
- } else if (addr == (sizeof(struct pt_regs) + 4)) {
- /* PT_TEXT_END_ADDR */
- tmp = child->mm->end_code;
- } else if (addr == (sizeof(struct pt_regs) + 8)) {
- /* PT_DATA_ADDR */
- tmp = child->mm->start_data;
-#ifdef CONFIG_BINFMT_ELF_FDPIC
- } else if (addr == (sizeof(struct pt_regs) + 12)) {
- goto case_PTRACE_GETFDPIC_EXEC;
- } else if (addr == (sizeof(struct pt_regs) + 16)) {
- goto case_PTRACE_GETFDPIC_INTERP;
-#endif
- } else {
- tmp = get_reg(child, addr);
- }
- ret = put_user(tmp, datap);
- break;
- }
-
#ifdef CONFIG_BINFMT_ELF_FDPIC
case PTRACE_GETFDPIC: {
unsigned long tmp = 0;
@@ -336,78 +354,36 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
- ret = -EIO;
- if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
- printk(KERN_WARNING "ptrace error : POKEUSR: temporarily returning 0\n");
- break;
- }
-
- if (addr >= (sizeof(struct pt_regs))) {
- ret = 0;
- break;
- }
- if (addr == PT_SYSCFG) {
- data &= SYSCFG_MASK;
- data |= get_reg(child, PT_SYSCFG);
+ case PTRACE_PEEKUSR:
+ switch (addr) {
+#ifdef CONFIG_BINFMT_ELF_FDPIC /* backwards compat */
+ case PT_FDPIC_EXEC: goto case_PTRACE_GETFDPIC_EXEC;
+ case PT_FDPIC_INTERP: goto case_PTRACE_GETFDPIC_INTERP;
+#endif
+ default:
+ ret = get_reg(child, addr, datap);
}
- ret = put_reg(child, addr, data);
+ pr_debug("ptrace: PEEKUSR reg %li with %#lx = %i\n", addr, data, ret);
break;
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: /* restart after signal. */
- pr_debug("ptrace: syscall/cont\n");
-
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- ptrace_disable(child);
- pr_debug("ptrace: before wake_up_process\n");
- wake_up_process(child);
- ret = 0;
- break;
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL:
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- ptrace_disable(child);
- wake_up_process(child);
- break;
-
- case PTRACE_SINGLESTEP: /* set the trap flag. */
- pr_debug("ptrace: single step\n");
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- ptrace_enable(child);
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
+ case PTRACE_POKEUSR:
+ ret = put_reg(child, addr, data);
+ pr_debug("ptrace: POKEUSR reg %li with %li = %i\n", addr, data, ret);
break;
case PTRACE_GETREGS:
- /* Get all gp regs from the child. */
- ret = ptrace_getregs(child, datap);
- break;
+ pr_debug("ptrace: PTRACE_GETREGS\n");
+ return copy_regset_to_user(child, &user_bfin_native_view,
+ REGSET_GENERAL,
+ 0, sizeof(struct pt_regs),
+ (void __user *)data);
case PTRACE_SETREGS:
- printk(KERN_WARNING "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n");
- /* Set all gp regs in the child. */
- ret = 0;
- break;
+ pr_debug("ptrace: PTRACE_SETREGS\n");
+ return copy_regset_from_user(child, &user_bfin_native_view,
+ REGSET_GENERAL,
+ 0, sizeof(struct pt_regs),
+ (const void __user *)data);
default:
ret = ptrace_request(child, request, addr, data);
@@ -417,27 +393,21 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return ret;
}
-asmlinkage void syscall_trace(void)
+asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{
- 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;
- }
+ int ret = 0;
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ ret = tracehook_report_syscall_entry(regs);
+
+ return ret;
+}
+
+asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+{
+ int step;
+
+ step = test_thread_flag(TIF_SINGLESTEP);
+ if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(regs, step);
}
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 95448ae9c43..8e2efceb364 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -220,6 +220,16 @@ void __init bfin_relocate_l1_mem(void)
memcpy(_stext_l2, _l2_lma, l2_len);
}
+#ifdef CONFIG_ROMKERNEL
+void __init bfin_relocate_xip_data(void)
+{
+ early_shadow_stamp();
+
+ memcpy(_sdata, _data_lma, (unsigned long)_data_len - THREAD_SIZE + sizeof(struct thread_info));
+ memcpy(_sinitdata, _init_data_lma, (unsigned long)_init_data_len);
+}
+#endif
+
/* add_memory_region to memmap */
static void __init add_memory_region(unsigned long long start,
unsigned long long size, int type)
@@ -504,7 +514,7 @@ static __init void memory_setup(void)
#endif
unsigned long max_mem;
- _rambase = (unsigned long)_stext;
+ _rambase = CONFIG_BOOT_LOAD;
_ramstart = (unsigned long)_end;
if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) {
@@ -597,7 +607,12 @@ static __init void memory_setup(void)
}
#ifdef CONFIG_MPU
+#if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM)
+ page_mask_nelts = (((_ramend + ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE -
+ ASYNC_BANK0_BASE) >> PAGE_SHIFT) + 31) / 32;
+#else
page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32;
+#endif
page_mask_order = get_order(3 * page_mask_nelts * sizeof(long));
#endif
@@ -630,7 +645,7 @@ static __init void memory_setup(void)
__bss_start, __bss_stop,
_sdata, _edata,
(void *)&init_thread_union,
- (void *)((int)(&init_thread_union) + 0x2000),
+ (void *)((int)(&init_thread_union) + THREAD_SIZE),
__init_begin, __init_end,
(void *)_ramstart, (void *)memory_end
#ifdef CONFIG_MTD_UCLINUX
@@ -792,10 +807,17 @@ static inline int __init get_mem_size(void)
BUG();
}
+__attribute__((weak))
+void __init native_machine_early_platform_add_devices(void)
+{
+}
+
void __init setup_arch(char **cmdline_p)
{
unsigned long sclk, cclk;
+ native_machine_early_platform_add_devices();
+
enable_shadow_console();
/* Check to make sure we are running on the right processor */
@@ -1217,10 +1239,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
BFIN_DLINES);
#ifdef __ARCH_SYNC_CORE_DCACHE
- seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count);
+ seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", dcache_invld_count[cpu_num]);
#endif
#ifdef __ARCH_SYNC_CORE_ICACHE
- seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count);
+ seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", icache_invld_count[cpu_num]);
#endif
if (cpu_num != num_possible_cpus() - 1)
@@ -1249,8 +1271,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n",
physical_mem_end >> 10, (void *)0, (void *)physical_mem_end);
seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n",
- ((int)memory_end - (int)_stext) >> 10,
- _stext,
+ ((int)memory_end - (int)_rambase) >> 10,
+ (void *)_rambase,
(void *)memory_end);
seq_printf(m, "\n");
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index e0fd63e9e38..d536f35d1f4 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2009 Analog Devices Inc.
+ * Copyright 2004-2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later
*/
@@ -17,6 +17,7 @@
#include <asm/cacheflush.h>
#include <asm/ucontext.h>
#include <asm/fixed_code.h>
+#include <asm/syscall.h>
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -50,6 +51,9 @@ rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *p
unsigned long usp = 0;
int err = 0;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
#define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x)
/* restore passed registers */
@@ -206,16 +210,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
regs->r1 = (unsigned long)(&frame->info);
regs->r2 = (unsigned long)(&frame->uc);
- /*
- * Clear the trace flag when entering the signal handler, but
- * notify any tracer that was single-stepping it. The tracer
- * may want to single-step inside the handler too.
- */
- if (regs->syscfg & TRACE_BITS) {
- regs->syscfg &= ~TRACE_BITS;
- ptrace_notify(SIGTRAP);
- }
-
return 0;
give_sigsegv:
@@ -247,6 +241,11 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
regs->r0 = regs->orig_r0;
regs->pc -= 2;
break;
+
+ case -ERESTART_RESTARTBLOCK:
+ regs->p0 = __NR_restart_syscall;
+ regs->pc -= 2;
+ break;
}
}
@@ -315,6 +314,9 @@ asmlinkage void do_signal(struct pt_regs *regs)
* clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
+
+ tracehook_signal_handler(signr, &info, &ka, regs,
+ test_thread_flag(TIF_SINGLESTEP));
}
return;
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 17c38c5b5b2..cb7a01d4f00 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -21,6 +21,7 @@
#include <asm/blackfin.h>
#include <asm/time.h>
#include <asm/gptimers.h>
+#include <asm/nmi.h>
/* Accelerators for sched_clock()
* convert from cycles(64bits) => nanoseconds (64bits)
@@ -50,7 +51,11 @@
static notrace cycle_t bfin_read_cycles(struct clocksource *cs)
{
+#ifdef CONFIG_CPU_FREQ
return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
+#else
+ return get_cycles();
+#endif
}
static struct clocksource bfin_cs_cycles = {
@@ -132,7 +137,6 @@ static int __init bfin_cs_gptimer0_init(void)
# define bfin_cs_gptimer0_init()
#endif
-
#if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE)
/* prefer to use cycles since it has higher rating */
notrace unsigned long long sched_clock(void)
@@ -145,47 +149,8 @@ notrace unsigned long long sched_clock(void)
}
#endif
-#ifdef CONFIG_CORE_TIMER_IRQ_L1
-__attribute__((l1_text))
-#endif
-irqreturn_t timer_interrupt(int irq, void *dev_id);
-
-static int bfin_timer_set_next_event(unsigned long, \
- struct clock_event_device *);
-
-static void bfin_timer_set_mode(enum clock_event_mode, \
- struct clock_event_device *);
-
-static struct clock_event_device clockevent_bfin = {
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
- .name = "bfin_gptimer0",
- .rating = 300,
- .irq = IRQ_TIMER0,
-#else
- .name = "bfin_core_timer",
- .rating = 350,
- .irq = IRQ_CORETMR,
-#endif
- .shift = 32,
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .set_next_event = bfin_timer_set_next_event,
- .set_mode = bfin_timer_set_mode,
-};
-
-static struct irqaction bfin_timer_irq = {
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
- .name = "Blackfin GPTimer0",
-#else
- .name = "Blackfin CoreTimer",
-#endif
- .flags = IRQF_DISABLED | IRQF_TIMER | \
- IRQF_IRQPOLL | IRQF_PERCPU,
- .handler = timer_interrupt,
- .dev_id = &clockevent_bfin,
-};
-
#if defined(CONFIG_TICKSOURCE_GPTMR0)
-static int bfin_timer_set_next_event(unsigned long cycles,
+static int bfin_gptmr0_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
disable_gptimers(TIMER0bit);
@@ -196,7 +161,7 @@ static int bfin_timer_set_next_event(unsigned long cycles,
return 0;
}
-static void bfin_timer_set_mode(enum clock_event_mode mode,
+static void bfin_gptmr0_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
switch (mode) {
@@ -224,25 +189,65 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
}
}
-static void bfin_timer_ack(void)
+static void bfin_gptmr0_ack(void)
{
set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0);
}
-static void __init bfin_timer_init(void)
+static void __init bfin_gptmr0_init(void)
{
disable_gptimers(TIMER0bit);
}
-static unsigned long __init bfin_clockevent_check(void)
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+__attribute__((l1_text))
+#endif
+irqreturn_t bfin_gptmr0_interrupt(int irq, void *dev_id)
{
- setup_irq(IRQ_TIMER0, &bfin_timer_irq);
- return get_sclk();
+ struct clock_event_device *evt = dev_id;
+ smp_mb();
+ evt->event_handler(evt);
+ bfin_gptmr0_ack();
+ return IRQ_HANDLED;
}
-#else /* CONFIG_TICKSOURCE_CORETMR */
+static struct irqaction gptmr0_irq = {
+ .name = "Blackfin GPTimer0",
+ .flags = IRQF_DISABLED | IRQF_TIMER | \
+ IRQF_IRQPOLL | IRQF_PERCPU,
+ .handler = bfin_gptmr0_interrupt,
+};
-static int bfin_timer_set_next_event(unsigned long cycles,
+static struct clock_event_device clockevent_gptmr0 = {
+ .name = "bfin_gptimer0",
+ .rating = 300,
+ .irq = IRQ_TIMER0,
+ .shift = 32,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = bfin_gptmr0_set_next_event,
+ .set_mode = bfin_gptmr0_set_mode,
+};
+
+static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)
+{
+ unsigned long clock_tick;
+
+ clock_tick = get_sclk();
+ evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
+ evt->max_delta_ns = clockevent_delta2ns(-1, evt);
+ evt->min_delta_ns = clockevent_delta2ns(100, evt);
+
+ evt->cpumask = cpumask_of(0);
+
+ clockevents_register_device(evt);
+}
+#endif /* CONFIG_TICKSOURCE_GPTMR0 */
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+/* per-cpu local core timer */
+static DEFINE_PER_CPU(struct clock_event_device, coretmr_events);
+
+static int bfin_coretmr_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
bfin_write_TCNTL(TMPWR);
@@ -253,7 +258,7 @@ static int bfin_timer_set_next_event(unsigned long cycles,
return 0;
}
-static void bfin_timer_set_mode(enum clock_event_mode mode,
+static void bfin_coretmr_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
switch (mode) {
@@ -285,19 +290,13 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
}
}
-static void bfin_timer_ack(void)
-{
-}
-
-static void __init bfin_timer_init(void)
+void bfin_coretmr_init(void)
{
/* power up the timer, but don't enable it just yet */
bfin_write_TCNTL(TMPWR);
CSYNC();
- /*
- * the TSCALE prescaler counter.
- */
+ /* the TSCALE prescaler counter. */
bfin_write_TSCALE(TIME_SCALE - 1);
bfin_write_TPERIOD(0);
bfin_write_TCOUNT(0);
@@ -305,48 +304,54 @@ static void __init bfin_timer_init(void)
CSYNC();
}
-static unsigned long __init bfin_clockevent_check(void)
-{
- setup_irq(IRQ_CORETMR, &bfin_timer_irq);
- return get_cclk() / TIME_SCALE;
-}
-
-void __init setup_core_timer(void)
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+__attribute__((l1_text))
+#endif
+irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id)
{
- bfin_timer_init();
- bfin_timer_set_mode(CLOCK_EVT_MODE_PERIODIC, NULL);
-}
-#endif /* CONFIG_TICKSOURCE_GPTMR0 */
+ int cpu = smp_processor_id();
+ struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *evt = dev_id;
smp_mb();
evt->event_handler(evt);
- bfin_timer_ack();
- return IRQ_HANDLED;
-}
-
-static int __init bfin_clockevent_init(void)
-{
- unsigned long timer_clk;
- timer_clk = bfin_clockevent_check();
+ touch_nmi_watchdog();
- bfin_timer_init();
+ return IRQ_HANDLED;
+}
- clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
- clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
- clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
- clockevent_bfin.cpumask = cpumask_of(0);
- clockevents_register_device(&clockevent_bfin);
+static struct irqaction coretmr_irq = {
+ .name = "Blackfin CoreTimer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | \
+ IRQF_IRQPOLL | IRQF_PERCPU,
+ .handler = bfin_coretmr_interrupt,
+};
- return 0;
+void bfin_coretmr_clockevent_init(void)
+{
+ unsigned long clock_tick;
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
+
+ evt->name = "bfin_core_timer";
+ evt->rating = 350;
+ evt->irq = -1;
+ evt->shift = 32;
+ evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+ evt->set_next_event = bfin_coretmr_set_next_event;
+ evt->set_mode = bfin_coretmr_set_mode;
+
+ clock_tick = get_cclk() / TIME_SCALE;
+ evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
+ evt->max_delta_ns = clockevent_delta2ns(-1, evt);
+ evt->min_delta_ns = clockevent_delta2ns(100, evt);
+
+ evt->cpumask = cpumask_of(cpu);
+
+ clockevents_register_device(evt);
}
+#endif /* CONFIG_TICKSOURCE_CORETMR */
+
void __init time_init(void)
{
@@ -370,5 +375,21 @@ void __init time_init(void)
bfin_cs_cycles_init();
bfin_cs_gptimer0_init();
- bfin_clockevent_init();
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+ bfin_coretmr_init();
+ setup_irq(IRQ_CORETMR, &coretmr_irq);
+ bfin_coretmr_clockevent_init();
+#endif
+
+#if defined(CONFIG_TICKSOURCE_GPTMR0)
+ bfin_gptmr0_init();
+ setup_irq(IRQ_TIMER0, &gptmr0_irq);
+ gptmr0_irq.dev_id = &clockevent_gptmr0;
+ bfin_gptmr0_clockevent_init(&clockevent_gptmr0);
+#endif
+
+#if !defined(CONFIG_TICKSOURCE_CORETMR) && !defined(CONFIG_TICKSOURCE_GPTMR0)
+# error at least one clock event device is required
+#endif
}
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index d3cbcd6bd98..ba70c4bc269 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -138,6 +138,12 @@ static void decode_address(char *buf, unsigned long address)
if (!mm)
continue;
+ if (!down_read_trylock(&mm->mmap_sem)) {
+ if (!in_atomic)
+ mmput(mm);
+ continue;
+ }
+
for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
struct vm_area_struct *vma;
@@ -177,6 +183,7 @@ static void decode_address(char *buf, unsigned long address)
sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
name, vma->vm_start, vma->vm_end);
+ up_read(&mm->mmap_sem);
if (!in_atomic)
mmput(mm);
@@ -186,11 +193,16 @@ static void decode_address(char *buf, unsigned long address)
goto done;
}
}
+
+ up_read(&mm->mmap_sem);
if (!in_atomic)
mmput(mm);
}
- /* we were unable to find this address anywhere */
+ /*
+ * we were unable to find this address anywhere,
+ * or some MMs were skipped because they were in use.
+ */
sprintf(buf, "/* kernel dynamic memory */");
done:
@@ -248,9 +260,7 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
int j;
#endif
-#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
unsigned int cpu = raw_smp_processor_id();
-#endif
const char *strerror = NULL;
int sig = 0;
siginfo_t info;
@@ -639,7 +649,17 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
{
info.si_signo = sig;
info.si_errno = 0;
- info.si_addr = (void __user *)fp->pc;
+ switch (trapnr) {
+ case VEC_CPLB_VL:
+ case VEC_MISALI_D:
+ case VEC_CPLB_M:
+ case VEC_CPLB_MHIT:
+ info.si_addr = (void __user *)cpu_pda[cpu].dcplb_fault_addr;
+ break;
+ default:
+ info.si_addr = (void __user *)fp->pc;
+ break;
+ }
force_sig_info(sig, &info, current);
}
@@ -712,7 +732,7 @@ static void decode_instruction(unsigned short *address)
verbose_printk("RTE");
else if (opcode == 0x0025)
verbose_printk("EMUEXCPT");
- else if (opcode == 0x0040 && opcode <= 0x0047)
+ else if (opcode >= 0x0040 && opcode <= 0x0047)
verbose_printk("STI R%i", opcode & 7);
else if (opcode >= 0x0050 && opcode <= 0x0057)
verbose_printk("JUMP (P%i)", opcode & 7);
@@ -1096,7 +1116,7 @@ void dump_bfin_mem(struct pt_regs *fp)
/* And the last RETI points to the current userspace context */
if ((fp + 1)->pc >= current->mm->start_code &&
(fp + 1)->pc <= current->mm->end_code) {
- verbose_printk(KERN_NOTICE "It might be better to look around here : \n");
+ verbose_printk(KERN_NOTICE "It might be better to look around here :\n");
verbose_printk(KERN_NOTICE "-------------------------------------------\n");
show_regs(fp + 1);
verbose_printk(KERN_NOTICE "-------------------------------------------\n");
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 66799e763dc..984c7817239 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -15,7 +15,12 @@ _jiffies = _jiffies_64;
SECTIONS
{
+#ifdef CONFIG_RAMKERNEL
. = CONFIG_BOOT_LOAD;
+#else
+ . = CONFIG_ROM_BASE;
+#endif
+
/* Neither the text, ro_data or bss section need to be aligned
* So pack them back to back
*/
@@ -31,6 +36,12 @@ SECTIONS
LOCK_TEXT
IRQENTRY_TEXT
KPROBES_TEXT
+#ifdef CONFIG_ROMKERNEL
+ __sinittext = .;
+ INIT_TEXT
+ __einittext = .;
+ EXIT_TEXT
+#endif
*(.text.*)
*(.fixup)
@@ -50,8 +61,14 @@ SECTIONS
/* Just in case the first read only is a 32-bit access */
RO_DATA(4)
+ __rodata_end = .;
+#ifdef CONFIG_ROMKERNEL
+ . = CONFIG_BOOT_LOAD;
+ .bss : AT(__rodata_end)
+#else
.bss :
+#endif
{
. = ALIGN(4);
___bss_start = .;
@@ -67,7 +84,11 @@ SECTIONS
___bss_stop = .;
}
+#if defined(CONFIG_ROMKERNEL)
+ .data : AT(LOADADDR(.bss) + SIZEOF(.bss))
+#else
.data :
+#endif
{
__sdata = .;
/* This gets done first, so the glob doesn't suck it in */
@@ -94,6 +115,8 @@ SECTIONS
__edata = .;
}
+ __data_lma = LOADADDR(.data);
+ __data_len = SIZEOF(.data);
/* The init section should be last, so when we free it, it goes into
* the general memory pool, and (hopefully) will decrease fragmentation
@@ -103,25 +126,58 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
___init_begin = .;
+#ifdef CONFIG_RAMKERNEL
INIT_TEXT_SECTION(PAGE_SIZE)
- . = ALIGN(16);
- INIT_DATA_SECTION(16)
- PERCPU(4)
- /* we have to discard exit text and such at runtime, not link time, to
+ /* We have to discard exit text and such at runtime, not link time, to
* handle embedded cross-section references (alt instructions, bug
- * table, eh_frame, etc...)
+ * table, eh_frame, etc...). We need all of our .text up front and
+ * .data after it for PCREL call issues.
*/
.exit.text :
{
EXIT_TEXT
}
+
+ . = ALIGN(16);
+ INIT_DATA_SECTION(16)
+ PERCPU(4)
+
.exit.data :
{
EXIT_DATA
}
.text_l1 L1_CODE_START : AT(LOADADDR(.exit.data) + SIZEOF(.exit.data))
+#else
+ .init.data : AT(__data_lma + __data_len)
+ {
+ __sinitdata = .;
+ INIT_DATA
+ INIT_SETUP(16)
+ INIT_CALLS
+ CON_INITCALL
+ SECURITY_INITCALL
+ INIT_RAM_FS
+
+ . = ALIGN(4);
+ ___per_cpu_load = .;
+ ___per_cpu_start = .;
+ *(.data.percpu.first)
+ *(.data.percpu.page_aligned)
+ *(.data.percpu)
+ *(.data.percpu.shared_aligned)
+ ___per_cpu_end = .;
+
+ EXIT_DATA
+ __einitdata = .;
+ }
+ __init_data_lma = LOADADDR(.init.data);
+ __init_data_len = SIZEOF(.init.data);
+ __init_data_end = .;
+
+ .text_l1 L1_CODE_START : AT(__init_data_lma + __init_data_len)
+#endif
{
. = ALIGN(4);
__stext_l1 = .;
@@ -202,7 +258,11 @@ SECTIONS
/* Force trailing alignment of our init section so that when we
* free our init memory, we don't leave behind a partial page.
*/
+#ifdef CONFIG_RAMKERNEL
. = __l2_lma + __l2_len;
+#else
+ . = __init_data_end;
+#endif
. = ALIGN(PAGE_SIZE);
___init_end = .;
diff --git a/arch/blackfin/mach-bf518/boards/Kconfig b/arch/blackfin/mach-bf518/boards/Kconfig
index 96163514ed2..252261ec04c 100644
--- a/arch/blackfin/mach-bf518/boards/Kconfig
+++ b/arch/blackfin/mach-bf518/boards/Kconfig
@@ -9,4 +9,9 @@ config BFIN518F_EZBRD
help
BF518-EZBRD board support.
+config BFIN518F_TCM
+ bool "Bluetechnix TCM-BF518"
+ help
+ Bluetechnix TCM-BF518 board support.
+
endchoice
diff --git a/arch/blackfin/mach-bf518/boards/Makefile b/arch/blackfin/mach-bf518/boards/Makefile
index 172e859c3a7..a9ef25c6b30 100644
--- a/arch/blackfin/mach-bf518/boards/Makefile
+++ b/arch/blackfin/mach-bf518/boards/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_BFIN518F_EZBRD) += ezbrd.o
+obj-$(CONFIG_BFIN518F_TCM) += tcm-bf518.o
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c
index 01975c01711..44d6d529902 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -382,30 +382,93 @@ static struct platform_device bfin_spi1_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
-#endif
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -499,16 +562,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#include <linux/input.h>
@@ -593,7 +715,12 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -610,9 +737,13 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
@@ -644,6 +775,33 @@ static int __init ezbrd_init(void)
arch_initcall(ezbrd_init);
+static struct platform_device *ezbrd_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ezbrd_early_devices,
+ ARRAY_SIZE(ezbrd_early_devices));
+}
+
void native_machine_restart(char *cmd)
{
/* workaround reboot hang when booting from SPI */
diff --git a/arch/blackfin/mach-bf518/boards/tcm-bf518.c b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
new file mode 100644
index 00000000000..9b72e5cb21f
--- /dev/null
+++ b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
@@ -0,0 +1,753 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+#include <asm/bfin_sdh.h>
+#include <linux/spi/ad7877.h>
+#include <net/dsa.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "Bluetechnix TCM-BF518";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition tcm_partitions[] = {
+ {
+ .name = "bootloader(nor)",
+ .size = 0x40000,
+ .offset = 0,
+ },
+ {
+ .name = "linux(nor)",
+ .size = 0x1C0000,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct physmap_flash_data tcm_flash_data = {
+ .width = 2,
+ .parts = tcm_partitions,
+ .nr_parts = ARRAY_SIZE(tcm_partitions),
+};
+
+static struct resource tcm_flash_resource = {
+ .start = 0x20000000,
+ .end = 0x201fffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device tcm_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &tcm_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &tcm_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+ .name = "bfin_mii_bus",
+};
+
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+ .dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader(spi)",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ }, {
+ .name = "linux kernel(spi)",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p16",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) \
+ || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip mmc_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+ .model = 7877,
+ .vref_delay_usecs = 50, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .pressure_max = 1000,
+ .pressure_min = 0,
+ .stopacq_polarity = 1,
+ .first_conversion_delay = 3,
+ .acquisition_time = 1,
+ .averaging = 1,
+ .pen_down_acc_interval = 1,
+};
+#endif
+
+#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
+ && defined(CONFIG_SND_SOC_WM8731_SPI)
+static struct bfin5xx_spi_chip spi_wm8731_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+static struct bfin5xx_spi_chip spidev_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0, /* Framework bus number */
+ .chip_select = 2, /* SPI0_SSEL2 */
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) \
+ || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+ {
+ .modalias = "mmc_spi",
+ .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5,
+ .controller_data = &mmc_spi_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+ {
+ .modalias = "ad7877",
+ .platform_data = &bfin_ad7877_ts_info,
+ .irq = IRQ_PF8,
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 2,
+ .controller_data = &spi_ad7877_chip_info,
+ },
+#endif
+#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
+ && defined(CONFIG_SND_SOC_WM8731_SPI)
+ {
+ .modalias = "wm8731",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 5,
+ .controller_data = &spi_wm8731_chip_info,
+ .mode = SPI_MODE_0,
+ },
+#endif
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1,
+ .controller_data = &spidev_chip_info,
+ },
+#endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+ {
+ .modalias = "bfin-lq035q1-spi",
+ .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1,
+ .controller_data = &lq035q1_spi_chip_info,
+ .mode = SPI_CPHA | SPI_CPOL,
+ },
+#endif
+};
+
+/* SPI controller data */
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* SPI (0) */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+ .num_chipselect = 6,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+ .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+static struct resource bfin_spi0_resource[] = {
+ [0] = {
+ .start = SPI0_REGBASE,
+ .end = SPI0_REGBASE + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CH_SPI0,
+ .end = CH_SPI0,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = IRQ_SPI0,
+ .end = IRQ_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_spi0_device = {
+ .name = "bfin-spi",
+ .id = 0, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+ .resource = bfin_spi0_resource,
+ .dev = {
+ .platform_data = &bfin_spi0_info, /* Passed to driver */
+ },
+};
+
+/* SPI (1) */
+static struct bfin5xx_spi_master bfin_spi1_info = {
+ .num_chipselect = 5,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+ .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
+};
+
+static struct resource bfin_spi1_resource[] = {
+ [0] = {
+ .start = SPI1_REGBASE,
+ .end = SPI1_REGBASE + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CH_SPI1,
+ .end = CH_SPI1,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = IRQ_SPI1,
+ .end = IRQ_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_spi1_device = {
+ .name = "bfin-spi",
+ .id = 1, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_spi1_resource),
+ .resource = bfin_spi1_resource,
+ .dev = {
+ .platform_data = &bfin_spi1_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+ {
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+ {
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX+1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device bfin_sir0_device = {
+ .name = "bfin_sir",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sir0_resources),
+ .resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+ {
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX+1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device bfin_sir1_device = {
+ .name = "bfin_sir",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sir1_resources),
+ .resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+ [0] = {
+ .start = TWI0_REGBASE,
+ .end = TWI0_REGBASE,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TWI,
+ .end = IRQ_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+ .name = "i2c-bfin-twi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+ .resource = bfin_twi0_resource,
+};
+#endif
+
+static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
+ {
+ I2C_BOARD_INFO("pcf8574_lcd", 0x22),
+ },
+#endif
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
+ {
+ I2C_BOARD_INFO("pcf8574_keypad", 0x27),
+ .irq = IRQ_PF8,
+ },
+#endif
+};
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+static struct gpio_keys_button bfin_gpio_keys_table[] = {
+ {BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"},
+ {BTN_1, GPIO_PG13, 1, "gpio-keys: BTN1"},
+};
+
+static struct gpio_keys_platform_data bfin_gpio_keys_data = {
+ .buttons = bfin_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table),
+};
+
+static struct platform_device bfin_device_gpiokeys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &bfin_gpio_keys_data,
+ },
+};
+#endif
+
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE)
+
+static struct bfin_sd_host bfin_sdh_data = {
+ .dma_chan = CH_RSI,
+ .irq_int0 = IRQ_RSI_INT0,
+ .pin_req = {P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0},
+};
+
+static struct platform_device bf51x_sdh_device = {
+ .name = "bfin-sdh",
+ .id = 0,
+ .dev = {
+ .platform_data = &bfin_sdh_data,
+ },
+};
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] =
+{
+ VRPAIR(VLEV_100, 400000000),
+ VRPAIR(VLEV_105, 426000000),
+ VRPAIR(VLEV_110, 500000000),
+ VRPAIR(VLEV_115, 533000000),
+ VRPAIR(VLEV_120, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+ .tuple_tab = cclk_vlev_datasheet,
+ .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+ .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+ .name = "bfin dpmc",
+ .dev = {
+ .platform_data = &bfin_dmpc_vreg_data,
+ },
+};
+
+static struct platform_device *tcm_devices[] __initdata = {
+
+ &bfin_dpmc,
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mii_bus,
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &bfin_spi0_device,
+ &bfin_spi1_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+ &bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+ &bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+ &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+ &bfin_device_gpiokeys,
+#endif
+
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE)
+ &bf51x_sdh_device,
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+ &tcm_flash_device,
+#endif
+};
+
+static int __init tcm_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __func__);
+ i2c_register_board_info(0, bfin_i2c_board_info,
+ ARRAY_SIZE(bfin_i2c_board_info));
+ platform_add_devices(tcm_devices, ARRAY_SIZE(tcm_devices));
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+ return 0;
+}
+
+arch_initcall(tcm_init);
+
+static struct platform_device *tcm_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(tcm_early_devices,
+ ARRAY_SIZE(tcm_early_devices));
+}
+
+void native_machine_restart(char *cmd)
+{
+ /* workaround reboot hang when booting from SPI */
+ if ((bfin_read_SYSCR() & 0x7) == 0x3)
+ bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
+}
+
+void bfin_get_ether_addr(char *addr)
+{
+ random_ether_addr(addr);
+ printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf518/include/mach/irq.h b/arch/blackfin/mach-bf518/include/mach/irq.h
index 14e52ec7afa..435e76e31aa 100644
--- a/arch/blackfin/mach-bf518/include/mach/irq.h
+++ b/arch/blackfin/mach-bf518/include/mach/irq.h
@@ -151,7 +151,17 @@
#define GPIO_IRQ_BASE IRQ_PF0
-#define NR_IRQS (IRQ_PH15 + 1)
+#define IRQ_MAC_PHYINT 119 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT 120 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT 121 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT 122 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET 123 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR 124 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR 125 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE 126 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1)
+#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
#define IVG7 7
#define IVG8 8
diff --git a/arch/blackfin/mach-bf518/include/mach/mem_map.h b/arch/blackfin/mach-bf518/include/mach/mem_map.h
index 3c6777cb353..073b5d73d39 100644
--- a/arch/blackfin/mach-bf518/include/mach/mem_map.h
+++ b/arch/blackfin/mach-bf518/include/mach/mem_map.h
@@ -41,7 +41,7 @@
#define L1_DATA_A_START 0xFF800000
#define L1_DATA_B_START 0xFF900000
-#define L1_CODE_LENGTH 0xC000
+#define L1_CODE_LENGTH 0x8000
#ifdef CONFIG_BFIN_DCACHE
diff --git a/arch/blackfin/mach-bf527/boards/Kconfig b/arch/blackfin/mach-bf527/boards/Kconfig
index df224d04e16..b14c28810a4 100644
--- a/arch/blackfin/mach-bf527/boards/Kconfig
+++ b/arch/blackfin/mach-bf527/boards/Kconfig
@@ -9,6 +9,11 @@ config BFIN527_EZKIT
help
BF527-EZKIT-LITE board support.
+config BFIN527_EZKIT_V2
+ bool "BF527-EZKIT-V2"
+ help
+ BF527-EZKIT-LITE V2.1+ board support.
+
config BFIN527_BLUETECHNIX_CM
bool "Bluetechnix CM-BF527"
help
diff --git a/arch/blackfin/mach-bf527/boards/Makefile b/arch/blackfin/mach-bf527/boards/Makefile
index eb6ed3362f9..51a5817c4a9 100644
--- a/arch/blackfin/mach-bf527/boards/Makefile
+++ b/arch/blackfin/mach-bf527/boards/Makefile
@@ -3,5 +3,6 @@
#
obj-$(CONFIG_BFIN527_EZKIT) += ezkit.o
+obj-$(CONFIG_BFIN527_EZKIT_V2) += ezkit.o
obj-$(CONFIG_BFIN527_BLUETECHNIX_CM) += cm_bf527.o
obj-$(CONFIG_BFIN526_EZBRD) += ezbrd.o
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index 7ab0800e291..ebe76d1e874 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -18,7 +18,6 @@
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
-#include <linux/usb/sl811.h>
#include <linux/usb/musb.h>
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
@@ -270,50 +269,6 @@ static struct platform_device dm9000_device = {
};
#endif
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
- {
- .start = 0x20340000,
- .end = 0x20340000,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 0x20340004,
- .end = 0x20340004,
- .flags = IORESOURCE_MEM,
- }, {
- .start = CONFIG_USB_SL811_BFIN_IRQ,
- .end = CONFIG_USB_SL811_BFIN_IRQ,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
- },
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
- gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
- gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
- .potpg = 10,
- .power = 250, /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
- .port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
- .name = "sl811-hcd",
- .id = 0,
- .dev = {
- .platform_data = &sl811_priv,
- },
- .num_resources = ARRAY_SIZE(sl811_hcd_resources),
- .resource = sl811_hcd_resources,
-};
-#endif
-
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
static struct platform_device bfin_mii_bus = {
.name = "bfin_mii_bus",
@@ -384,8 +339,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -462,8 +417,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -603,30 +558,105 @@ static struct platform_device cm_flash_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ { /* CTS pin */
+ .start = GPIO_PF9,
+ .end = GPIO_PF9,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin */
+ .start = GPIO_PF10,
+ .end = GPIO_PF10,
+ .flags = IORESOURCE_IO,
+ },
#endif
};
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -725,16 +755,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#include <linux/input.h>
@@ -795,10 +884,6 @@ static struct platform_device *cmbf527_devices[] __initdata = {
&rtc_device,
#endif
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
- &sl811_hcd_device,
-#endif
-
#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
&bfin_isp1760_device,
#endif
@@ -829,7 +914,12 @@ static struct platform_device *cmbf527_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -846,9 +936,13 @@ static struct platform_device *cmbf527_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
@@ -871,6 +965,33 @@ static int __init cm_init(void)
arch_initcall(cm_init);
+static struct platform_device *cmbf527_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(cmbf527_early_devices,
+ ARRAY_SIZE(cmbf527_early_devices));
+}
+
void native_machine_restart(char *cmd)
{
/* workaround reboot hang when booting from SPI */
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index cad23b15d83..55069af4f67 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -274,8 +274,8 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.median = 2, /* do 8 measurements */
.averaging = 1, /* take the average of 4 middle samples */
.pen_down_acc_interval = 255, /* 9.4 ms */
- .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */
- .gpio_default = 1, /* During initialization set GPIO = HIGH */
+ .gpio_export = 1, /* Export GPIO to gpiolib */
+ .gpio_base = -1, /* Dynamic allocation */
};
#endif
@@ -439,30 +439,105 @@ static struct platform_device bfin_spi0_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ { /* CTS pin */
+ .start = GPIO_PG0,
+ .end = GPIO_PG0,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin */
+ .start = GPIO_PF10,
+ .end = GPIO_PF10,
+ .flags = IORESOURCE_IO,
+ },
#endif
};
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -556,16 +631,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#include <linux/input.h>
@@ -615,9 +749,10 @@ static struct platform_device bfin_dpmc = {
#include <asm/bfin-lq035q1.h>
static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
- .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
- .use_bl = 1,
- .gpio_bl = GPIO_PG12,
+ .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+ .ppi_mode = USE_RGB565_16_BIT_PPI,
+ .use_bl = 1,
+ .gpio_bl = GPIO_PG12,
};
static struct resource bfin_lq035q1_resources[] = {
@@ -665,7 +800,12 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
@@ -686,9 +826,13 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
@@ -711,6 +855,33 @@ static int __init ezbrd_init(void)
arch_initcall(ezbrd_init);
+static struct platform_device *ezbrd_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ezbrd_early_devices,
+ ARRAY_SIZE(ezbrd_early_devices));
+}
+
void native_machine_restart(char *cmd)
{
/* workaround reboot hang when booting from SPI */
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 5294fdd2073..923383386aa 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -16,8 +16,9 @@
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
-#include <linux/usb/sl811.h>
#include <linux/usb/musb.h>
+#include <linux/leds.h>
+#include <linux/input.h>
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/reboot.h>
@@ -29,7 +30,11 @@
/*
* Name the Board for the /proc/cpuinfo
*/
+#ifdef CONFIG_BFIN527_EZKIT_V2
+const char bfin_board_name[] = "ADI BF527-EZKIT V2";
+#else
const char bfin_board_name[] = "ADI BF527-EZKIT";
+#endif
/*
* Driver needs to know address, irq and flag pin.
@@ -143,6 +148,33 @@ static struct platform_device bf52x_t350mcqb_device = {
};
#endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+#include <asm/bfin-lq035q1.h>
+
+static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
+ .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+ .ppi_mode = USE_RGB565_8_BIT_PPI,
+};
+
+static struct resource bfin_lq035q1_resources[] = {
+ {
+ .start = IRQ_PPI_ERROR,
+ .end = IRQ_PPI_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_lq035q1_device = {
+ .name = "bfin-lq035q1",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_lq035q1_resources),
+ .resource = bfin_lq035q1_resources,
+ .dev = {
+ .platform_data = &bfin_lq035q1_data,
+ },
+};
+#endif
+
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
static struct mtd_partition ezkit_partitions[] = {
{
@@ -326,50 +358,6 @@ static struct platform_device dm9000_device = {
};
#endif
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
- {
- .start = 0x20340000,
- .end = 0x20340000,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 0x20340004,
- .end = 0x20340004,
- .flags = IORESOURCE_MEM,
- }, {
- .start = CONFIG_USB_SL811_BFIN_IRQ,
- .end = CONFIG_USB_SL811_BFIN_IRQ,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
- },
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
- gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
- gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
- .potpg = 10,
- .power = 250, /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
- .port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
- .name = "sl811-hcd",
- .id = 0,
- .dev = {
- .platform_data = &sl811_priv,
- },
- .num_resources = ARRAY_SIZE(sl811_hcd_resources),
- .resource = sl811_hcd_resources,
-};
-#endif
-
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
static struct platform_device bfin_mii_bus = {
.name = "bfin_mii_bus",
@@ -440,8 +428,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -488,8 +476,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.median = 2, /* do 8 measurements */
.averaging = 1, /* take the average of 4 middle samples */
.pen_down_acc_interval = 255, /* 9.4 ms */
- .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */
- .gpio_default = 1, /* During initialization set GPIO = HIGH */
+ .gpio_export = 0, /* Export GPIO to gpiolib */
};
#endif
@@ -500,14 +487,6 @@ static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
};
#endif
-#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
- && defined(CONFIG_SND_SOC_WM8731_SPI)
-static struct bfin5xx_spi_chip spi_wm8731_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
static struct bfin5xx_spi_chip spidev_chip_info = {
.enable_dma = 0,
@@ -515,6 +494,29 @@ static struct bfin5xx_spi_chip spidev_chip_info = {
};
#endif
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+ .name = "bfin-tdm",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+static struct bfin5xx_spi_chip lq035q1_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
static struct spi_board_info bfin_spi_board_info[] __initdata = {
#if defined(CONFIG_MTD_M25P80) \
|| defined(CONFIG_MTD_M25P80_MODULE)
@@ -542,8 +544,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -586,17 +588,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_CPHA | SPI_CPOL,
},
#endif
-#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
- && defined(CONFIG_SND_SOC_WM8731_SPI)
- {
- .modalias = "wm8731",
- .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 5,
- .controller_data = &spi_wm8731_chip_info,
- .mode = SPI_MODE_0,
- },
-#endif
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
{
.modalias = "spidev",
@@ -606,6 +597,16 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.controller_data = &spidev_chip_info,
},
#endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+ {
+ .modalias = "bfin-lq035q1-spi",
+ .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 7,
+ .controller_data = &lq035q1_spi_chip_info,
+ .mode = SPI_CPHA | SPI_CPOL,
+ },
+#endif
};
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -647,30 +648,105 @@ static struct platform_device bfin_spi0_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ { /* CTS pin */
+ .start = GPIO_PF9,
+ .end = GPIO_PF9,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin */
+ .start = GPIO_PF10,
+ .end = GPIO_PF10,
+ .flags = IORESOURCE_IO,
+ },
#endif
};
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -749,6 +825,71 @@ static struct platform_device i2c_bfin_twi_device = {
};
#endif
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+#include <linux/mfd/adp5520.h>
+
+ /*
+ * ADP5520/5501 LEDs Data
+ */
+
+static struct led_info adp5520_leds[] = {
+ {
+ .name = "adp5520-led1",
+ .default_trigger = "none",
+ .flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | ADP5520_LED_OFFT_600ms,
+ },
+};
+
+static struct adp5520_leds_platform_data adp5520_leds_data = {
+ .num_leds = ARRAY_SIZE(adp5520_leds),
+ .leds = adp5520_leds,
+ .fade_in = ADP5520_FADE_T_600ms,
+ .fade_out = ADP5520_FADE_T_600ms,
+ .led_on_time = ADP5520_LED_ONT_600ms,
+};
+
+ /*
+ * ADP5520 Keypad Data
+ */
+
+static const unsigned short adp5520_keymap[ADP5520_KEYMAPSIZE] = {
+ [ADP5520_KEY(3, 3)] = KEY_1,
+ [ADP5520_KEY(2, 3)] = KEY_2,
+ [ADP5520_KEY(1, 3)] = KEY_3,
+ [ADP5520_KEY(0, 3)] = KEY_UP,
+ [ADP5520_KEY(3, 2)] = KEY_4,
+ [ADP5520_KEY(2, 2)] = KEY_5,
+ [ADP5520_KEY(1, 2)] = KEY_6,
+ [ADP5520_KEY(0, 2)] = KEY_DOWN,
+ [ADP5520_KEY(3, 1)] = KEY_7,
+ [ADP5520_KEY(2, 1)] = KEY_8,
+ [ADP5520_KEY(1, 1)] = KEY_9,
+ [ADP5520_KEY(0, 1)] = KEY_DOT,
+ [ADP5520_KEY(3, 0)] = KEY_BACKSPACE,
+ [ADP5520_KEY(2, 0)] = KEY_0,
+ [ADP5520_KEY(1, 0)] = KEY_HELP,
+ [ADP5520_KEY(0, 0)] = KEY_ENTER,
+};
+
+static struct adp5520_keys_platform_data adp5520_keys_data = {
+ .rows_en_mask = ADP5520_ROW_R3 | ADP5520_ROW_R2 | ADP5520_ROW_R1 | ADP5520_ROW_R0,
+ .cols_en_mask = ADP5520_COL_C3 | ADP5520_COL_C2 | ADP5520_COL_C1 | ADP5520_COL_C0,
+ .keymap = adp5520_keymap,
+ .keymapsize = ARRAY_SIZE(adp5520_keymap),
+ .repeat = 0,
+};
+
+ /*
+ * ADP5520/5501 Multifuction Device Init Data
+ */
+
+static struct adp5520_platform_data adp5520_pdev_data = {
+ .leds = &adp5520_leds_data,
+ .keys = &adp5520_keys_data,
+};
+
+#endif
+
static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
{
@@ -766,22 +907,99 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
I2C_BOARD_INFO("bfin-adv7393", 0x2B),
},
#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+ {
+ I2C_BOARD_INFO("ad7879", 0x2C),
+ .irq = IRQ_PF8,
+ .platform_data = (void *)&bfin_ad7879_ts_info,
+ },
+#endif
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+ {
+ I2C_BOARD_INFO("pmic-adp5520", 0x32),
+ .irq = IRQ_PF9,
+ .platform_data = (void *)&adp5520_pdev_data,
+ },
+#endif
+#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE)
+ {
+ I2C_BOARD_INFO("ssm2602", 0x1b),
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
-#include <linux/input.h>
#include <linux/gpio_keys.h>
static struct gpio_keys_button bfin_gpio_keys_table[] = {
@@ -803,7 +1021,6 @@ static struct platform_device bfin_device_gpiokeys = {
#endif
#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
-#include <linux/input.h>
#include <asm/bfin_rotary.h>
static struct bfin_rotary_platform_data bfin_rotary_data = {
@@ -872,10 +1089,6 @@ static struct platform_device *stamp_devices[] __initdata = {
&rtc_device,
#endif
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
- &sl811_hcd_device,
-#endif
-
#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
&bfin_isp1760_device,
#endif
@@ -909,8 +1122,17 @@ static struct platform_device *stamp_devices[] __initdata = {
&bf52x_t350mcqb_device,
#endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+ &bfin_lq035q1_device,
+#endif
+
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -927,9 +1149,13 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
@@ -942,6 +1168,14 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezkit_flash_device,
#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+ &bfin_tdm,
+#endif
};
static int __init ezkit_init(void)
@@ -956,6 +1190,33 @@ static int __init ezkit_init(void)
arch_initcall(ezkit_init);
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ezkit_early_devices,
+ ARRAY_SIZE(ezkit_early_devices));
+}
+
void native_machine_restart(char *cmd)
{
/* workaround reboot hang when booting from SPI */
diff --git a/arch/blackfin/mach-bf527/include/mach/irq.h b/arch/blackfin/mach-bf527/include/mach/irq.h
index aa6579a64a2..704d9253e41 100644
--- a/arch/blackfin/mach-bf527/include/mach/irq.h
+++ b/arch/blackfin/mach-bf527/include/mach/irq.h
@@ -151,7 +151,17 @@
#define GPIO_IRQ_BASE IRQ_PF0
-#define NR_IRQS (IRQ_PH15+1)
+#define IRQ_MAC_PHYINT 119 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT 120 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT 121 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT 122 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET 123 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR 124 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR 125 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE 126 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1)
+#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
#define IVG7 7
#define IVG8 8
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
index 4adceb0bdb6..175371af069 100644
--- a/arch/blackfin/mach-bf533/boards/H8606.c
+++ b/arch/blackfin/mach-bf533/boards/H8606.c
@@ -171,7 +171,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -206,7 +206,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 16,
@@ -257,21 +257,50 @@ static struct platform_device bfin_spi0_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX + 1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -394,7 +423,9 @@ static struct platform_device *h8606_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
#endif
#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
@@ -424,3 +455,18 @@ static int __init H8606_init(void)
}
arch_initcall(H8606_init);
+
+static struct platform_device *H8606_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(H8606_early_devices,
+ ARRAY_SIZE(H8606_early_devices));
+}
diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c
index b580884848d..842b4fa76ea 100644
--- a/arch/blackfin/mach-bf533/boards/blackstamp.c
+++ b/arch/blackfin/mach-bf533/boards/blackstamp.c
@@ -195,21 +195,50 @@ static struct platform_device bfin_spi0_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX + 1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -241,16 +270,75 @@ static struct platform_device bfin_sir0_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#include <linux/input.h>
@@ -344,7 +432,9 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -354,9 +444,13 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
@@ -392,3 +486,27 @@ static int __init blackstamp_init(void)
}
arch_initcall(blackstamp_init);
+
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(stamp_early_devices,
+ ARRAY_SIZE(stamp_early_devices));
+}
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index 7fc3b860d4a..fdcde61906d 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -71,7 +71,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -110,7 +110,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -242,21 +242,50 @@ static struct platform_device smsc911x_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX + 1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -288,16 +317,75 @@ static struct platform_device bfin_sir0_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
static struct resource isp1362_hcd_resources[] = {
@@ -432,7 +520,9 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
&bfin_dpmc,
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -442,9 +532,13 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
&rtc_device,
@@ -486,3 +580,27 @@ static int __init cm_bf533_init(void)
}
arch_initcall(cm_bf533_init);
+
+static struct platform_device *cm_bf533_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(cm_bf533_early_devices,
+ ARRAY_SIZE(cm_bf533_early_devices));
+}
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index d4689dcc198..739773cb7fc 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -222,7 +222,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -261,7 +261,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -320,21 +320,50 @@ static struct platform_device bfin_spi0_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX + 1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -444,6 +473,30 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
#endif
};
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+ .name = "bfin-tdm",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+ .name = "bfin-ac97",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
static struct platform_device *ezkit_devices[] __initdata = {
&bfin_dpmc,
@@ -471,7 +524,9 @@ static struct platform_device *ezkit_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -487,6 +542,18 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
&i2c_gpio_device,
#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+ &bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+ &bfin_ac97,
+#endif
};
static int __init ezkit_init(void)
@@ -500,3 +567,18 @@ static int __init ezkit_init(void)
}
arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ezkit_early_devices,
+ ARRAY_SIZE(ezkit_early_devices));
+}
diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c
index 8ec42ba35b9..7349970db97 100644
--- a/arch/blackfin/mach-bf533/boards/ip0x.c
+++ b/arch/blackfin/mach-bf533/boards/ip0x.c
@@ -19,6 +19,7 @@
#include <linux/usb/isp1362.h>
#endif
#include <asm/irq.h>
+#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
@@ -143,21 +144,50 @@ static struct platform_device spi_bfin_master_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX + 1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -241,7 +271,9 @@ static struct platform_device *ip0x_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -276,3 +308,18 @@ static int __init ip0x_init(void)
}
arch_initcall(ip0x_init);
+
+static struct platform_device *ip0x_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ip0x_early_devices,
+ ARRAY_SIZE(ip0x_early_devices));
+}
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 6d68dcfa2da..c457eaa6023 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -184,7 +184,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -251,7 +251,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -322,21 +322,50 @@ static struct platform_device bfin_spi0_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX + 1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
};
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -368,16 +397,75 @@ static struct platform_device bfin_sir0_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#include <linux/input.h>
@@ -474,6 +562,30 @@ static struct platform_device bfin_dpmc = {
},
};
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+ .name = "bfin-tdm",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+ .name = "bfin-ac97",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
static struct platform_device *stamp_devices[] __initdata = {
&bfin_dpmc,
@@ -495,7 +607,9 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -505,9 +619,13 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
@@ -520,6 +638,18 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE)
&stamp_flash_device,
#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+ &bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+ &bfin_ac97,
+#endif
};
static int __init stamp_init(void)
@@ -548,6 +678,30 @@ static int __init stamp_init(void)
arch_initcall(stamp_init);
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(stamp_early_devices,
+ ARRAY_SIZE(stamp_early_devices));
+}
+
void native_machine_restart(char *cmd)
{
/* workaround pull up on cpld / flash pin not being strong enough */
diff --git a/arch/blackfin/mach-bf533/include/mach/irq.h b/arch/blackfin/mach-bf533/include/mach/irq.h
index c31498be0bb..1f7e9765d95 100644
--- a/arch/blackfin/mach-bf533/include/mach/irq.h
+++ b/arch/blackfin/mach-bf533/include/mach/irq.h
@@ -104,7 +104,8 @@ Core Emulation **
#define GPIO_IRQ_BASE IRQ_PF0
-#define NR_IRQS (IRQ_PF15+1)
+#define NR_MACH_IRQS (IRQ_PF15 + 1)
+#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
#define IVG7 7
#define IVG8 8
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
index c85f4d77053..d35fc5fe4c2 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -73,7 +73,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -112,7 +112,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -329,8 +329,8 @@ static struct platform_device cm_flash_device = {
#ifdef CONFIG_SERIAL_BFIN_UART0
static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
},
{
@@ -373,18 +373,25 @@ static struct resource bfin_uart0_resources[] = {
#endif
};
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
.id = 0,
.num_resources = ARRAY_SIZE(bfin_uart0_resources),
.resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
{
@@ -427,11 +434,18 @@ static struct resource bfin_uart1_resources[] = {
#endif
};
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
+};
+
static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
.num_resources = ARRAY_SIZE(bfin_uart1_resources),
.resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
#endif
@@ -512,16 +526,75 @@ static struct platform_device i2c_bfin_twi_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
static struct platform_device bfin_mii_bus = {
@@ -633,9 +706,13 @@ static struct platform_device *cm_bf537e_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
&isp1362_hcd_device,
@@ -683,6 +760,33 @@ static int __init cm_bf537e_init(void)
arch_initcall(cm_bf537e_init);
+static struct platform_device *cm_bf537e_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(cm_bf537e_early_devices,
+ ARRAY_SIZE(cm_bf537e_early_devices));
+}
+
void bfin_get_ether_addr(char *addr)
{
random_ether_addr(addr);
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
index ea11aa81340..d464ad5b72b 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
@@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -113,7 +113,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -327,25 +327,93 @@ static struct platform_device cm_flash_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
- }, {
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+ {
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -423,16 +491,75 @@ static struct platform_device i2c_bfin_twi_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
static struct platform_device bfin_mii_bus = {
@@ -522,7 +649,12 @@ static struct platform_device *cm_bf537u_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -539,9 +671,13 @@ static struct platform_device *cm_bf537u_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
&isp1362_hcd_device,
@@ -589,6 +725,33 @@ static int __init cm_bf537u_init(void)
arch_initcall(cm_bf537u_init);
+static struct platform_device *cm_bf537u_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(cm_bf537u_early_devices,
+ ARRAY_SIZE(cm_bf537u_early_devices));
+}
+
void bfin_get_ether_addr(char *addr)
{
random_ether_addr(addr);
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c
index 0da92725270..c489d602c59 100644
--- a/arch/blackfin/mach-bf537/boards/minotaur.c
+++ b/arch/blackfin/mach-bf537/boards/minotaur.c
@@ -211,25 +211,93 @@ static struct platform_device bfin_spi0_device = {
#endif /* spi master and devices */
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
- }, {
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+ {
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -309,16 +377,75 @@ static struct platform_device i2c_bfin_twi_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
static struct platform_device *minotaur_devices[] __initdata = {
#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
@@ -343,7 +470,12 @@ static struct platform_device *minotaur_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -360,9 +492,13 @@ static struct platform_device *minotaur_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
};
@@ -380,6 +516,33 @@ static int __init minotaur_init(void)
arch_initcall(minotaur_init);
+static struct platform_device *minotaur_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(minotaur_early_devices,
+ ARRAY_SIZE(minotaur_early_devices));
+}
+
void native_machine_restart(char *cmd)
{
/* workaround reboot hang when booting from SPI */
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 4e0afda472a..812e8f99160 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -17,7 +17,6 @@
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
-#include <linux/usb/sl811.h>
#include <linux/spi/ad7877.h>
@@ -99,51 +98,6 @@ static struct platform_device smc91x_device = {
};
#endif
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
- {
- .start = 0x20340000,
- .end = 0x20340000,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 0x20340004,
- .end = 0x20340004,
- .flags = IORESOURCE_MEM,
- }, {
- .start = CONFIG_USB_SL811_BFIN_IRQ,
- .end = CONFIG_USB_SL811_BFIN_IRQ,
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
- },
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
- gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
- gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
- .potpg = 10,
- .power = 250, /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
- .port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
- .name = "sl811-hcd",
- .id = 0,
- .dev = {
- .platform_data = &sl811_priv,
- },
- .num_resources = ARRAY_SIZE(sl811_hcd_resources),
- .resource = sl811_hcd_resources,
-};
-#endif
-
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
static struct platform_device bfin_mii_bus = {
.name = "bfin_mii_bus",
@@ -221,8 +175,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -284,8 +238,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -362,25 +316,93 @@ static struct platform_device bfin_fb_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
- }, {
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+ {
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -446,10 +468,6 @@ static struct platform_device *stamp_devices[] __initdata = {
&rtc_device,
#endif
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
- &sl811_hcd_device,
-#endif
-
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
&smc91x_device,
#endif
@@ -472,7 +490,12 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -498,6 +521,24 @@ static int __init pnav_init(void)
arch_initcall(pnav_init);
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(stamp_early_devices,
+ ARRAY_SIZE(stamp_early_devices));
+}
+
void bfin_get_ether_addr(char *addr)
{
random_ether_addr(addr);
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index ac9b52e0087..9eaf5b05c11 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -20,10 +20,12 @@
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
#include <linux/usb/isp1362.h>
#endif
+#include <linux/i2c.h>
+#include <linux/i2c/adp5588.h>
+#include <linux/etherdevice.h>
#include <linux/ata_platform.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
-#include <linux/i2c.h>
#include <linux/usb/sl811.h>
#include <linux/spi/mmc_spi.h>
#include <linux/leds.h>
@@ -33,6 +35,14 @@
#include <asm/reboot.h>
#include <asm/portmux.h>
#include <asm/dpmc.h>
+#ifdef CONFIG_REGULATOR_ADP_SWITCH
+#include <linux/regulator/adp_switch.h>
+#endif
+#ifdef CONFIG_REGULATOR_AD5398
+#include <linux/regulator/ad5398.h>
+#endif
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/userspace-consumer.h>
/*
* Name the Board for the /proc/cpuinfo
@@ -208,8 +218,8 @@ static struct resource sl811_hcd_resources[] = {
.end = 0x20340004,
.flags = IORESOURCE_MEM,
}, {
- .start = CONFIG_USB_SL811_BFIN_IRQ,
- .end = CONFIG_USB_SL811_BFIN_IRQ,
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
},
};
@@ -454,6 +464,9 @@ static struct physmap_flash_data stamp_flash_data = {
.width = 2,
.parts = stamp_partitions,
.nr_parts = ARRAY_SIZE(stamp_partitions),
+#ifdef CONFIG_ROMKERNEL
+ .probe_type = "map_rom",
+#endif
};
static struct resource stamp_flash_resource = {
@@ -515,20 +528,19 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
- || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
};
#endif
-#if defined(CONFIG_SND_BF5XX_SOC_AD1938) \
- || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD193X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
static struct bfin5xx_spi_chip ad1938_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 8,
- .cs_gpio = GPIO_PF5,
};
#endif
@@ -644,6 +656,42 @@ static struct ad714x_platform_data ad7142_i2c_platform_data = {
};
#endif
+#if defined(CONFIG_AD2S90) || defined(CONFIG_AD2S90_MODULE)
+static struct bfin5xx_spi_chip ad2s90_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD2S120X) || defined(CONFIG_AD2S120X_MODULE)
+unsigned short ad2s120x_platform_data[] = {
+ /* used as SAMPLE and RDVEL */
+ GPIO_PF5, GPIO_PF6, 0
+};
+
+static struct bfin5xx_spi_chip ad2s120x_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD2S1210) || defined(CONFIG_AD2S1210_MODULE)
+unsigned short ad2s1210_platform_data[] = {
+ /* use as SAMPLE, A0, A1 */
+ GPIO_PF7, GPIO_PF8, GPIO_PF9,
+# if defined(CONFIG_AD2S1210_GPIO_INPUT) || defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+ /* the RES0 and RES1 pins */
+ GPIO_PF4, GPIO_PF5,
+# endif
+ 0,
+};
+
+static struct bfin5xx_spi_chip ad2s1210_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 8,
+};
+#endif
+
#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
#define MMC_SPI_CARD_DETECT_INT IRQ_PF5
@@ -686,11 +734,11 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = {
.y_plate_ohms = 486,
.pressure_max = 1000,
.pressure_min = 0,
- .stopacq_polarity = 1,
- .first_conversion_delay = 3,
- .acquisition_time = 1,
- .averaging = 1,
- .pen_down_acc_interval = 1,
+ .stopacq_polarity = 1,
+ .first_conversion_delay = 3,
+ .acquisition_time = 1,
+ .averaging = 1,
+ .pen_down_acc_interval = 1,
};
#endif
@@ -701,13 +749,13 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */
.pressure_max = 10000,
.pressure_min = 0,
- .first_conversion_delay = 3, /* wait 512us before do a first conversion */
- .acquisition_time = 1, /* 4us acquisition time per sample */
+ .first_conversion_delay = 3, /* wait 512us before do a first conversion */
+ .acquisition_time = 1, /* 4us acquisition time per sample */
.median = 2, /* do 8 measurements */
- .averaging = 1, /* take the average of 4 middle samples */
- .pen_down_acc_interval = 255, /* 9.4 ms */
- .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */
- .gpio_default = 1, /* During initialization set GPIO = HIGH */
+ .averaging = 1, /* take the average of 4 middle samples */
+ .pen_down_acc_interval = 255, /* 9.4 ms */
+ .gpio_export = 1, /* Export GPIO to gpiolib */
+ .gpio_base = -1, /* Dynamic allocation */
};
#endif
@@ -742,6 +790,11 @@ static const struct adxl34x_platform_data adxl34x_info = {
/* .ev_code_act_inactivity = KEY_A,*/ /* EV_KEY */
.power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
.fifo_mode = ADXL_FIFO_STREAM,
+ .orientation_enable = ADXL_EN_ORIENTATION_3D,
+ .deadzone_angle = ADXL_DEADZONE_ANGLE_10p8,
+ .divisor_length = ADXL_LP_FILTER_DIVISOR_16,
+ /* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */
+ .ev_codes_orient_3d = {BTN_Z, BTN_Y, BTN_X, BTN_A, BTN_B, BTN_C},
};
#endif
@@ -813,6 +866,35 @@ static struct adf702x_platform_data adf7021_platform_data = {
.adf702x_regs = adf7021_regs,
.tx_reg = TXREG,
};
+static inline void adf702x_mac_init(void)
+{
+ random_ether_addr(adf7021_platform_data.mac_addr);
+}
+#else
+static inline void adf702x_mac_init(void) {}
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+#include <linux/spi/ads7846.h>
+static struct bfin5xx_spi_chip ad7873_spi_chip_info = {
+ .bits_per_word = 8,
+};
+
+static int ads7873_get_pendown_state(void)
+{
+ return gpio_get_value(GPIO_PF6);
+}
+
+static struct ads7846_platform_data __initdata ad7873_pdata = {
+ .model = 7873, /* AD7873 */
+ .x_max = 0xfff,
+ .y_max = 0xfff,
+ .x_plate_ohms = 620,
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7873_get_pendown_state,
+};
#endif
#if defined(CONFIG_MTD_DATAFLASH) \
@@ -893,24 +975,25 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
- || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
{
- .modalias = "ad1836",
+ .modalias = "ad183x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
.chip_select = 4,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+ .platform_data = "ad1836", /* only includes chip name for the moment */
.controller_data = &ad1836_spi_chip_info,
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_SND_BF5XX_SOC_AD1938) || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD193X) || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
{
- .modalias = "ad1938",
+ .modalias = "ad193x",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0,
- .chip_select = 0,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+ .chip_select = 5,
.controller_data = &ad1938_spi_chip_info,
.mode = SPI_MODE_3,
},
@@ -929,6 +1012,37 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
+#if defined(CONFIG_AD2S90) || defined(CONFIG_AD2S90_MODULE)
+ {
+ .modalias = "ad2s90",
+ .bus_num = 0,
+ .chip_select = 3, /* change it for your board */
+ .platform_data = NULL,
+ .controller_data = &ad2s90_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_AD2S120X) || defined(CONFIG_AD2S120X_MODULE)
+ {
+ .modalias = "ad2s120x",
+ .bus_num = 0,
+ .chip_select = 4, /* CS, change it for your board */
+ .platform_data = ad2s120x_platform_data,
+ .controller_data = &ad2s120x_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_AD2S1210) || defined(CONFIG_AD2S1210_MODULE)
+ {
+ .modalias = "ad2s1210",
+ .max_speed_hz = 8192000,
+ .bus_num = 0,
+ .chip_select = 4, /* CS, change it for your board */
+ .platform_data = ad2s1210_platform_data,
+ .controller_data = &ad2s1210_spi_chip_info,
+ },
+#endif
+
#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
{
.modalias = "mmc_spi",
@@ -1016,7 +1130,18 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_0,
},
#endif
-
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .max_speed_hz = 2000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .irq = IRQ_PF6,
+ .chip_select = GPIO_PF10 + MAX_CTRL_CS, /* GPIO controlled SSEL */
+ .controller_data = &ad7873_spi_chip_info,
+ .platform_data = &ad7873_pdata,
+ .mode = SPI_MODE_0,
+ },
+#endif
};
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -1132,9 +1257,10 @@ static struct platform_device bfin_fb_device = {
#include <asm/bfin-lq035q1.h>
static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
- .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
- .use_bl = 0, /* let something else control the LCD Blacklight */
- .gpio_bl = GPIO_PF7,
+ .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+ .ppi_mode = USE_RGB565_16_BIT_PPI,
+ .use_bl = 0, /* let something else control the LCD Blacklight */
+ .gpio_bl = GPIO_PF7,
};
static struct resource bfin_lq035q1_resources[] = {
@@ -1148,8 +1274,8 @@ static struct resource bfin_lq035q1_resources[] = {
static struct platform_device bfin_lq035q1_device = {
.name = "bfin-lq035q1",
.id = -1,
- .num_resources = ARRAY_SIZE(bfin_lq035q1_resources),
- .resource = bfin_lq035q1_resources,
+ .num_resources = ARRAY_SIZE(bfin_lq035q1_resources),
+ .resource = bfin_lq035q1_resources,
.dev = {
.platform_data = &bfin_lq035q1_data,
},
@@ -1157,30 +1283,105 @@ static struct platform_device bfin_lq035q1_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+ { /* CTS pin */
+ .start = GPIO_PG7,
+ .end = GPIO_PG7,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin */
+ .start = GPIO_PG6,
+ .end = GPIO_PG6,
+ .flags = IORESOURCE_IO,
+ },
+#endif
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
-#endif
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -1260,7 +1461,6 @@ static struct platform_device i2c_bfin_twi_device = {
#endif
#if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE)
-#include <linux/i2c/adp5588.h>
static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = {
[0] = KEY_GRAVE,
[1] = KEY_1,
@@ -1457,7 +1657,6 @@ static struct adp5520_platform_data adp5520_pdev_data = {
#endif
#if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE)
-#include <linux/i2c/adp5588.h>
static struct adp5588_gpio_platform_data adp5588_gpio_data = {
.gpio_start = 50,
.pullup_dis_mask = 0,
@@ -1516,6 +1715,101 @@ static struct adp8870_backlight_platform_data adp8870_pdata = {
};
#endif
+#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE)
+#include <linux/i2c/adp8860.h>
+static struct led_info adp8860_leds[] = {
+ {
+ .name = "adp8860-led7",
+ .default_trigger = "none",
+ .flags = ADP8860_LED_D7 | ADP8860_LED_OFFT_600ms,
+ },
+};
+
+static struct adp8860_backlight_platform_data adp8860_pdata = {
+ .bl_led_assign = ADP8860_BL_D1 | ADP8860_BL_D2 | ADP8860_BL_D3 |
+ ADP8860_BL_D4 | ADP8860_BL_D5 | ADP8860_BL_D6, /* 1 = Backlight 0 = Individual LED */
+
+ .bl_fade_in = ADP8860_FADE_T_1200ms, /* Backlight Fade-In Timer */
+ .bl_fade_out = ADP8860_FADE_T_1200ms, /* Backlight Fade-Out Timer */
+ .bl_fade_law = ADP8860_FADE_LAW_CUBIC1, /* fade-on/fade-off transfer characteristic */
+
+ .en_ambl_sens = 1, /* 1 = enable ambient light sensor */
+ .abml_filt = ADP8860_BL_AMBL_FILT_320ms, /* Light sensor filter time */
+
+ .l1_daylight_max = ADP8860_BL_CUR_mA(20), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+ .l1_daylight_dim = ADP8860_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+ .l2_office_max = ADP8860_BL_CUR_mA(6), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+ .l2_office_dim = ADP8860_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+ .l3_dark_max = ADP8860_BL_CUR_mA(2), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+ .l3_dark_dim = ADP8860_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+
+ .l2_trip = ADP8860_L2_COMP_CURR_uA(710), /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */
+ .l2_hyst = ADP8860_L2_COMP_CURR_uA(73), /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */
+ .l3_trip = ADP8860_L3_COMP_CURR_uA(43), /* use L3_COMP_CURR_uA(I) 0 <= I <= 138 uA */
+ .l3_hyst = ADP8860_L3_COMP_CURR_uA(11), /* use L3_COMP_CURR_uA(I) 0 <= I <= 138 uA */
+
+ .leds = adp8860_leds,
+ .num_leds = ARRAY_SIZE(adp8860_leds),
+ .led_fade_law = ADP8860_FADE_LAW_SQUARE, /* fade-on/fade-off transfer characteristic */
+ .led_fade_in = ADP8860_FADE_T_600ms,
+ .led_fade_out = ADP8860_FADE_T_600ms,
+ .led_on_time = ADP8860_LED_ONT_200ms,
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+static struct regulator_consumer_supply ad5398_consumer = {
+ .supply = "current",
+};
+
+static struct regulator_init_data ad5398_regulator_data = {
+ .constraints = {
+ .name = "current range",
+ .max_uA = 120000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ad5398_consumer,
+};
+
+static struct ad5398_platform_data ad5398_i2c_platform_data = {
+ .current_bits = 10,
+ .current_offset = 4,
+ .regulator_data = &ad5398_regulator_data,
+};
+
+#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \
+ defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE)
+static struct platform_device ad5398_virt_consumer_device = {
+ .name = "reg-virt-consumer",
+ .id = 0,
+ .dev = {
+ .platform_data = "current", /* Passed to driver */
+ },
+};
+#endif
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+ defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+static struct regulator_bulk_data ad5398_bulk_data = {
+ .supply = "current",
+};
+
+static struct regulator_userspace_consumer_data ad5398_userspace_comsumer_data = {
+ .name = "ad5398",
+ .num_supplies = 1,
+ .supplies = &ad5398_bulk_data,
+};
+
+static struct platform_device ad5398_userspace_consumer_device = {
+ .name = "reg-userspace-consumer",
+ .id = 0,
+ .dev = {
+ .platform_data = &ad5398_userspace_comsumer_data,
+ },
+};
+#endif
+#endif
+
static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
#if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE)
{
@@ -1524,6 +1818,52 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
.platform_data = (void *)&ad7142_i2c_platform_data,
},
#endif
+
+#if defined(CONFIG_AD7150) || defined(CONFIG_AD7150_MODULE)
+ {
+ I2C_BOARD_INFO("ad7150", 0x48),
+ .irq = IRQ_PG5, /* fixme: use real interrupt number */
+ },
+#endif
+
+#if defined(CONFIG_AD7152) || defined(CONFIG_AD7152_MODULE)
+ {
+ I2C_BOARD_INFO("ad7152", 0x48),
+ },
+#endif
+
+#if defined(CONFIG_AD774X) || defined(CONFIG_AD774X_MODULE)
+ {
+ I2C_BOARD_INFO("ad774x", 0x48),
+ },
+#endif
+
+#if defined(CONFIG_AD7414) || defined(CONFIG_AD7414_MODULE)
+ {
+ I2C_BOARD_INFO("ad7414", 0x9),
+ .irq = IRQ_PG5,
+ /*
+ * platform_data pointer is borrwoed by the driver to
+ * store custimer defined IRQ ALART level mode.
+ * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid.
+ */
+ .platform_data = (void *)IRQF_TRIGGER_LOW,
+ },
+#endif
+
+#if defined(CONFIG_AD7416) || defined(CONFIG_AD7416_MODULE)
+ {
+ I2C_BOARD_INFO("ad7417", 0xb),
+ .irq = IRQ_PG5,
+ /*
+ * platform_data pointer is borrwoed by the driver to
+ * store custimer defined IRQ ALART level mode.
+ * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid.
+ */
+ .platform_data = (void *)IRQF_TRIGGER_LOW,
+ },
+#endif
+
#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
{
I2C_BOARD_INFO("pcf8574_lcd", 0x22),
@@ -1595,24 +1935,105 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
I2C_BOARD_INFO("adau1761", 0x38),
},
#endif
+#if defined(CONFIG_SND_SOC_ADAU1361) || defined(CONFIG_SND_SOC_ADAU1361_MODULE)
+ {
+ I2C_BOARD_INFO("adau1361", 0x38),
+ },
+#endif
#if defined(CONFIG_AD525X_DPOT) || defined(CONFIG_AD525X_DPOT_MODULE)
{
I2C_BOARD_INFO("ad5258", 0x18),
},
#endif
+#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE)
+ {
+ I2C_BOARD_INFO("ssm2602", 0x1b),
+ },
+#endif
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+ {
+ I2C_BOARD_INFO("ad5398", 0xC),
+ .platform_data = (void *)&ad5398_i2c_platform_data,
+ },
+#endif
+#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE)
+ {
+ I2C_BOARD_INFO("adp8860", 0x2A),
+ .platform_data = (void *)&adp8860_pdata,
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
#define CF_IDE_NAND_CARD_USE_HDD_INTERFACE
@@ -1701,13 +2122,121 @@ static struct platform_device bfin_dpmc = {
},
};
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
static struct platform_device bfin_tdm = {
.name = "bfin-tdm",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
/* TODO: add platform data here */
};
#endif
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+ .name = "bfin-ac97",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE)
+#define REGULATOR_ADP122 "adp122"
+#define REGULATOR_ADP150 "adp150"
+
+static struct regulator_consumer_supply adp122_consumers = {
+ .supply = REGULATOR_ADP122,
+};
+
+static struct regulator_consumer_supply adp150_consumers = {
+ .supply = REGULATOR_ADP150,
+};
+
+static struct regulator_init_data adp_switch_regulator_data[] = {
+ {
+ .constraints = {
+ .name = REGULATOR_ADP122,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .min_uA = 0,
+ .max_uA = 300000,
+ },
+ .num_consumer_supplies = 1, /* only 1 */
+ .consumer_supplies = &adp122_consumers,
+ .driver_data = (void *)GPIO_PF2, /* gpio port only */
+ },
+ {
+ .constraints = {
+ .name = REGULATOR_ADP150,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .min_uA = 0,
+ .max_uA = 150000,
+ },
+ .num_consumer_supplies = 1, /* only 1 */
+ .consumer_supplies = &adp150_consumers,
+ .driver_data = (void *)GPIO_PF3, /* gpio port only */
+ },
+};
+
+static struct adp_switch_platform_data adp_switch_pdata = {
+ .regulator_num = ARRAY_SIZE(adp_switch_regulator_data),
+ .regulator_data = adp_switch_regulator_data,
+};
+
+static struct platform_device adp_switch_device = {
+ .name = "adp_switch",
+ .id = 0,
+ .dev = {
+ .platform_data = &adp_switch_pdata,
+ },
+};
+
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+ defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+static struct regulator_bulk_data adp122_bulk_data = {
+ .supply = REGULATOR_ADP122,
+};
+
+static struct regulator_userspace_consumer_data adp122_userspace_comsumer_data = {
+ .name = REGULATOR_ADP122,
+ .num_supplies = 1,
+ .supplies = &adp122_bulk_data,
+};
+
+static struct platform_device adp122_userspace_consumer_device = {
+ .name = "reg-userspace-consumer",
+ .id = 0,
+ .dev = {
+ .platform_data = &adp122_userspace_comsumer_data,
+ },
+};
+
+static struct regulator_bulk_data adp150_bulk_data = {
+ .supply = REGULATOR_ADP150,
+};
+
+static struct regulator_userspace_consumer_data adp150_userspace_comsumer_data = {
+ .name = REGULATOR_ADP150,
+ .num_supplies = 1,
+ .supplies = &adp150_bulk_data,
+};
+
+static struct platform_device adp150_userspace_consumer_device = {
+ .name = "reg-userspace-consumer",
+ .id = 1,
+ .dev = {
+ .platform_data = &adp150_userspace_comsumer_data,
+ },
+};
+#endif
+#endif
+
+
static struct platform_device *stamp_devices[] __initdata = {
&bfin_dpmc,
@@ -1771,7 +2300,12 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -1788,9 +2322,13 @@ static struct platform_device *stamp_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
&bfin_pata_device,
@@ -1808,18 +2346,46 @@ static struct platform_device *stamp_devices[] __initdata = {
&stamp_flash_device,
#endif
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
&bfin_tdm,
#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+ &bfin_ac97,
+#endif
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \
+ defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE)
+ &ad5398_virt_consumer_device,
+#endif
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+ defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+ &ad5398_userspace_consumer_device,
+#endif
+#endif
+
+#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE)
+ &adp_switch_device,
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+ defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+ &adp122_userspace_consumer_device,
+ &adp150_userspace_consumer_device,
+#endif
+#endif
};
static int __init stamp_init(void)
{
printk(KERN_INFO "%s(): registering device resources\n", __func__);
- i2c_register_board_info(0, bfin_i2c_board_info,
- ARRAY_SIZE(bfin_i2c_board_info));
bfin_plat_nand_init();
+ adf702x_mac_init();
platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+ i2c_register_board_info(0, bfin_i2c_board_info,
+ ARRAY_SIZE(bfin_i2c_board_info));
spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
return 0;
@@ -1827,6 +2393,34 @@ static int __init stamp_init(void)
arch_initcall(stamp_init);
+
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(stamp_early_devices,
+ ARRAY_SIZE(stamp_early_devices));
+}
+
void native_machine_restart(char *cmd)
{
/* workaround reboot hang when booting from SPI */
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
index 57163b65a4f..4f0a2e72ce4 100644
--- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -113,7 +113,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -327,25 +327,93 @@ static struct platform_device cm_flash_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
- }, {
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ },
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+ {
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
.name = "bfin-uart",
.id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -425,16 +493,75 @@ static struct platform_device i2c_bfin_twi_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
};
static struct platform_device bfin_sport1_uart_device = {
.name = "bfin-sport-uart",
.id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
static struct platform_device bfin_mii_bus = {
@@ -524,7 +651,12 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -541,9 +673,13 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
&bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
&bfin_sport1_uart_device,
#endif
+#endif
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
&isp1362_hcd_device,
@@ -591,6 +727,33 @@ static int __init tcm_bf537_init(void)
arch_initcall(tcm_bf537_init);
+static struct platform_device *cm_bf537_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(cm_bf537_early_devices,
+ ARRAY_SIZE(cm_bf537_early_devices));
+}
+
void bfin_get_ether_addr(char *addr)
{
random_ether_addr(addr);
diff --git a/arch/blackfin/mach-bf537/include/mach/irq.h b/arch/blackfin/mach-bf537/include/mach/irq.h
index 0defa9457e7..789a4f226f7 100644
--- a/arch/blackfin/mach-bf537/include/mach/irq.h
+++ b/arch/blackfin/mach-bf537/include/mach/irq.h
@@ -134,7 +134,17 @@
#define GPIO_IRQ_BASE IRQ_PF0
-#define NR_IRQS (IRQ_PH15+1)
+#define IRQ_MAC_PHYINT 98 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT 99 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT 100 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT 101 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET 102 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR 103 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR 104 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE 105 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1)
+#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
#define IVG7 7
#define IVG8 8
diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c
index c296bb1ed50..1a1f65855b0 100644
--- a/arch/blackfin/mach-bf538/boards/ezkit.c
+++ b/arch/blackfin/mach-bf538/boards/ezkit.c
@@ -41,37 +41,148 @@ static struct platform_device rtc_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_THR,
+ .end = UART0_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+ { /* CTS pin */
+ .start = GPIO_PG7,
+ .end = GPIO_PG7,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin */
+ .start = GPIO_PG6,
+ .end = GPIO_PG6,
+ .flags = IORESOURCE_IO,
+ },
+#endif
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_THR,
+ .end = UART1_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
{
- .start = 0xFFC02100,
- .end = 0xFFC021FF,
+ .start = UART2_THR,
+ .end = UART2_GCTL+2,
.flags = IORESOURCE_MEM,
},
-#endif
+ {
+ .start = IRQ_UART2_RX,
+ .end = IRQ_UART2_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART2_ERROR,
+ .end = IRQ_UART2_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART2_TX,
+ .end = CH_UART2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART2_RX,
+ .end = CH_UART2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart2_peripherals[] = {
+ P_UART2_TX, P_UART2_RX, 0
};
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart2_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bfin_uart2_resources),
+ .resource = bfin_uart2_resources,
+ .dev = {
+ .platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -151,6 +262,145 @@ static struct platform_device bfin_sir2_device = {
#endif
#endif
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+ {
+ .start = SPORT2_TCR1,
+ .end = SPORT2_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT2_RX,
+ .end = IRQ_SPORT2_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT2_ERROR,
+ .end = IRQ_SPORT2_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+ P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+ P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+ .resource = bfin_sport2_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+ {
+ .start = SPORT3_TCR1,
+ .end = SPORT3_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT3_RX,
+ .end = IRQ_SPORT3_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT3_ERROR,
+ .end = IRQ_SPORT3_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+ P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+ P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+ .resource = bfin_sport3_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#endif
+
#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
unsigned short bfin_can_peripherals[] = {
P_CAN0_RX, P_CAN0_TX, 0
@@ -268,8 +518,8 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.median = 2, /* do 8 measurements */
.averaging = 1, /* take the average of 4 middle samples */
.pen_down_acc_interval = 255, /* 9.4 ms */
- .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */
- .gpio_default = 1, /* During initialization set GPIO = HIGH */
+ .gpio_export = 1, /* Export GPIO to gpiolib */
+ .gpio_base = -1, /* Dynamic allocation */
};
#endif
@@ -284,9 +534,10 @@ static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
#include <asm/bfin-lq035q1.h>
static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
- .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
- .use_bl = 0, /* let something else control the LCD Blacklight */
- .gpio_bl = GPIO_PF7,
+ .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+ .ppi_mode = USE_RGB565_16_BIT_PPI,
+ .use_bl = 0, /* let something else control the LCD Blacklight */
+ .gpio_bl = GPIO_PF7,
};
static struct resource bfin_lq035q1_resources[] = {
@@ -622,7 +873,15 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+ &bfin_uart2_device,
+#endif
#endif
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -648,6 +907,21 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
#endif
#endif
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+ &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+ &bfin_sport3_uart_device,
+#endif
+#endif
+
#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
&bfin_can_device,
#endif
@@ -683,3 +957,39 @@ static int __init ezkit_init(void)
}
arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+ &bfin_uart2_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+ &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+ &bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ezkit_early_devices,
+ ARRAY_SIZE(ezkit_early_devices));
+}
diff --git a/arch/blackfin/mach-bf538/include/mach/irq.h b/arch/blackfin/mach-bf538/include/mach/irq.h
index a4b7fcbc556..7a479d224dc 100644
--- a/arch/blackfin/mach-bf538/include/mach/irq.h
+++ b/arch/blackfin/mach-bf538/include/mach/irq.h
@@ -110,7 +110,8 @@
#define GPIO_IRQ_BASE IRQ_PF0
-#define NR_IRQS (IRQ_PF15+1)
+#define NR_MACH_IRQS (IRQ_PF15 + 1)
+#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
#define IVG7 7
#define IVG8 8
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index ccdcd6da2e9..f60c333fec6 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -127,44 +127,211 @@ static struct platform_device rtc_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_DLL,
+ .end = UART0_RBR+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_DLL,
+ .end = UART1_RBR+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ { /* CTS pin -- 0 means not supported */
+ .start = GPIO_PE10,
+ .end = GPIO_PE10,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin -- 0 means not supported */
+ .start = GPIO_PE9,
+ .end = GPIO_PE9,
+ .flags = IORESOURCE_IO,
+ },
+#endif
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX,
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ P_UART1_RTS, P_UART1_CTS,
+#endif
+ 0
+};
+
+static struct platform_device bfin_uart1_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
{
- .start = 0xFFC02100,
- .end = 0xFFC021FF,
+ .start = UART2_DLL,
+ .end = UART2_RBR+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART2_RX,
+ .end = IRQ_UART2_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART2_ERROR,
+ .end = IRQ_UART2_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART2_TX,
+ .end = CH_UART2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART2_RX,
+ .end = CH_UART2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart2_peripherals[] = {
+ P_UART2_TX, P_UART2_RX, 0
+};
+
+static struct platform_device bfin_uart2_device = {
+ .name = "bfin-uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bfin_uart2_resources),
+ .resource = bfin_uart2_resources,
+ .dev = {
+ .platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART3
+static struct resource bfin_uart3_resources[] = {
{
- .start = 0xFFC03100,
- .end = 0xFFC031FF,
+ .start = UART3_DLL,
+ .end = UART3_RBR+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART3_RX,
+ .end = IRQ_UART3_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART3_ERROR,
+ .end = IRQ_UART3_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART3_TX,
+ .end = CH_UART3_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART3_RX,
+ .end = CH_UART3_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+ { /* CTS pin -- 0 means not supported */
+ .start = GPIO_PB3,
+ .end = GPIO_PB3,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin -- 0 means not supported */
+ .start = GPIO_PB2,
+ .end = GPIO_PB2,
+ .flags = IORESOURCE_IO,
+ },
#endif
};
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart3_peripherals[] = {
+ P_UART3_TX, P_UART3_RX,
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+ P_UART3_RTS, P_UART3_CTS,
+#endif
+ 0
+};
+
+static struct platform_device bfin_uart3_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 3,
+ .num_resources = ARRAY_SIZE(bfin_uart3_resources),
+ .resource = bfin_uart3_resources,
+ .dev = {
+ .platform_data = &bfin_uart3_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -359,6 +526,145 @@ static struct platform_device musb_device = {
};
#endif
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+ {
+ .start = SPORT2_TCR1,
+ .end = SPORT2_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT2_RX,
+ .end = IRQ_SPORT2_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT2_ERROR,
+ .end = IRQ_SPORT2_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+ P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+ P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+ .resource = bfin_sport2_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+ {
+ .start = SPORT3_TCR1,
+ .end = SPORT3_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT3_RX,
+ .end = IRQ_SPORT3_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT3_ERROR,
+ .end = IRQ_SPORT3_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+ P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+ P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+ .resource = bfin_sport3_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#endif
+
#if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
static struct resource bfin_atapi_resources[] = {
{
@@ -752,7 +1058,18 @@ static struct platform_device *cm_bf548_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+ &bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+ &bfin_uart3_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -782,6 +1099,21 @@ static struct platform_device *cm_bf548_devices[] __initdata = {
&musb_device,
#endif
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+ &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+ &bfin_sport3_uart_device,
+#endif
+#endif
+
#if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
&bfin_atapi_device,
#endif
@@ -833,3 +1165,42 @@ static int __init cm_bf548_init(void)
}
arch_initcall(cm_bf548_init);
+
+static struct platform_device *cm_bf548_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+ &bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+ &bfin_uart3_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+ &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+ &bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(cm_bf548_early_devices,
+ ARRAY_SIZE(cm_bf548_early_devices));
+}
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 60193f72777..06919db00a7 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -232,44 +232,211 @@ static struct platform_device rtc_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = UART0_DLL,
+ .end = UART0_RBR+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART0_RX,
+ .end = IRQ_UART0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART0_ERROR,
+ .end = IRQ_UART0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART0_TX,
+ .end = CH_UART0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART0_RX,
+ .end = CH_UART0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
{
- .start = 0xFFC02000,
- .end = 0xFFC020FF,
+ .start = UART1_DLL,
+ .end = UART1_RBR+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART1_RX,
+ .end = IRQ_UART1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART1_ERROR,
+ .end = IRQ_UART1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART1_TX,
+ .end = CH_UART1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART1_RX,
+ .end = CH_UART1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ { /* CTS pin -- 0 means not supported */
+ .start = GPIO_PE10,
+ .end = GPIO_PE10,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin -- 0 means not supported */
+ .start = GPIO_PE9,
+ .end = GPIO_PE9,
+ .flags = IORESOURCE_IO,
+ },
+#endif
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+ P_UART1_TX, P_UART1_RX,
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ P_UART1_RTS, P_UART1_CTS,
+#endif
+ 0
+};
+
+static struct platform_device bfin_uart1_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+ .resource = bfin_uart1_resources,
+ .dev = {
+ .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
{
- .start = 0xFFC02100,
- .end = 0xFFC021FF,
+ .start = UART2_DLL,
+ .end = UART2_RBR+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART2_RX,
+ .end = IRQ_UART2_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART2_ERROR,
+ .end = IRQ_UART2_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART2_TX,
+ .end = CH_UART2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART2_RX,
+ .end = CH_UART2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart2_peripherals[] = {
+ P_UART2_TX, P_UART2_RX, 0
+};
+
+static struct platform_device bfin_uart2_device = {
+ .name = "bfin-uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bfin_uart2_resources),
+ .resource = bfin_uart2_resources,
+ .dev = {
+ .platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+ },
+};
#endif
#ifdef CONFIG_SERIAL_BFIN_UART3
+static struct resource bfin_uart3_resources[] = {
{
- .start = 0xFFC03100,
- .end = 0xFFC031FF,
+ .start = UART3_DLL,
+ .end = UART3_RBR+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART3_RX,
+ .end = IRQ_UART3_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART3_ERROR,
+ .end = IRQ_UART3_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART3_TX,
+ .end = CH_UART3_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART3_RX,
+ .end = CH_UART3_RX,
+ .flags = IORESOURCE_DMA,
+ },
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+ { /* CTS pin -- 0 means not supported */
+ .start = GPIO_PB3,
+ .end = GPIO_PB3,
+ .flags = IORESOURCE_IO,
+ },
+ { /* RTS pin -- 0 means not supported */
+ .start = GPIO_PB2,
+ .end = GPIO_PB2,
+ .flags = IORESOURCE_IO,
+ },
#endif
};
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart3_peripherals[] = {
+ P_UART3_TX, P_UART3_RX,
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+ P_UART3_RTS, P_UART3_CTS,
+#endif
+ 0
+};
+
+static struct platform_device bfin_uart3_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 3,
+ .num_resources = ARRAY_SIZE(bfin_uart3_resources),
+ .resource = bfin_uart3_resources,
+ .dev = {
+ .platform_data = &bfin_uart3_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -464,6 +631,145 @@ static struct platform_device musb_device = {
};
#endif
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+ .resource = bfin_sport0_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+ {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT1_RX,
+ .end = IRQ_SPORT1_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+ P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+ P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+ .resource = bfin_sport1_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+ {
+ .start = SPORT2_TCR1,
+ .end = SPORT2_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT2_RX,
+ .end = IRQ_SPORT2_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT2_ERROR,
+ .end = IRQ_SPORT2_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+ P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+ P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+ .resource = bfin_sport2_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+ {
+ .start = SPORT3_TCR1,
+ .end = SPORT3_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT3_RX,
+ .end = IRQ_SPORT3_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT3_ERROR,
+ .end = IRQ_SPORT3_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+ P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+ P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+ .resource = bfin_sport3_uart_resources,
+ .dev = {
+ .platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#endif
+
#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
unsigned short bfin_can_peripherals[] = {
P_CAN0_RX, P_CAN0_TX, 0
@@ -657,8 +963,8 @@ static struct bfin5xx_spi_chip spi_flash_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -714,8 +1020,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -951,6 +1257,30 @@ static struct platform_device bfin_dpmc = {
},
};
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+ .name = "bfin-i2s",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+ .name = "bfin-tdm",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+ .name = "bfin-ac97",
+ .id = CONFIG_SND_BF5XX_SPORT_NUM,
+ /* TODO: add platform data here */
+};
+#endif
+
static struct platform_device *ezkit_devices[] __initdata = {
&bfin_dpmc,
@@ -960,7 +1290,18 @@ static struct platform_device *ezkit_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+ &bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+ &bfin_uart3_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -994,6 +1335,21 @@ static struct platform_device *ezkit_devices[] __initdata = {
&bfin_isp1760_device,
#endif
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+ &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+ &bfin_sport3_uart_device,
+#endif
+#endif
+
#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
&bfin_can_device,
#endif
@@ -1037,6 +1393,18 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezkit_flash_device,
#endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+ &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+ &bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+ &bfin_ac97,
+#endif
};
static int __init ezkit_init(void)
@@ -1058,3 +1426,42 @@ static int __init ezkit_init(void)
}
arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+ &bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+ &bfin_uart3_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+ &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+ &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+ &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+ &bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ezkit_early_devices,
+ ARRAY_SIZE(ezkit_early_devices));
+}
diff --git a/arch/blackfin/mach-bf548/include/mach/irq.h b/arch/blackfin/mach-bf548/include/mach/irq.h
index 106db05684a..1f99b51a3d5 100644
--- a/arch/blackfin/mach-bf548/include/mach/irq.h
+++ b/arch/blackfin/mach-bf548/include/mach/irq.h
@@ -317,7 +317,8 @@ Events (highest priority) EMU 0
#define GPIO_IRQ_BASE IRQ_PA0
-#define NR_IRQS (IRQ_PJ15+1)
+#define NR_MACH_IRQS (IRQ_PJ15 + 1)
+#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
/* For compatibility reasons with existing code */
diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile
index 59e18afe28c..b3402971831 100644
--- a/arch/blackfin/mach-bf561/Makefile
+++ b/arch/blackfin/mach-bf561/Makefile
@@ -6,3 +6,4 @@ obj-y := ints-priority.o dma.o
obj-$(CONFIG_BF561_COREB) += coreb.o
obj-$(CONFIG_SMP) += smp.o secondary.o atomic.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c
index 07e8dc8770d..5163e2c383c 100644
--- a/arch/blackfin/mach-bf561/boards/acvilon.c
+++ b/arch/blackfin/mach-bf561/boards/acvilon.c
@@ -176,7 +176,7 @@ static struct resource smsc911x_resources[] = {
};
static struct smsc911x_platform_config smsc911x_config = {
- .flags = SMSC911X_USE_32BIT,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
.phy_interface = PHY_INTERFACE_MODE_MII,
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index dfc8d5b7798..e127aedc1d7 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -72,7 +72,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -111,7 +111,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -305,21 +305,50 @@ static struct platform_device isp1362_hcd_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART_RX,
+ .end = IRQ_UART_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART_ERROR,
+ .end = IRQ_UART_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART_TX,
+ .end = CH_UART_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART_RX,
+ .end = CH_UART_RX,
+ .flags = IORESOURCE_DMA,
+ },
};
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -463,7 +492,9 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -516,3 +547,18 @@ static int __init cm_bf561_init(void)
}
arch_initcall(cm_bf561_init);
+
+static struct platform_device *cm_bf561_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(cm_bf561_early_devices,
+ ARRAY_SIZE(cm_bf561_early_devices));
+}
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index ffd3e6a80d1..9b93e2f9579 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -160,21 +160,50 @@ static struct platform_device smc91x_device = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
{
- .start = 0xFFC00400,
- .end = 0xFFC004FF,
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = IRQ_UART_RX,
+ .end = IRQ_UART_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART_ERROR,
+ .end = IRQ_UART_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART_TX,
+ .end = CH_UART_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART_RX,
+ .end = CH_UART_RX,
+ .flags = IORESOURCE_DMA,
+ },
};
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
.name = "bfin-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(bfin_uart_resources),
- .resource = bfin_uart_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
};
#endif
+#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
@@ -245,8 +274,8 @@ static struct platform_device ezkit_flash_device = {
};
#endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 16,
@@ -299,8 +328,8 @@ static struct platform_device bfin_spi0_device = {
#endif
static struct spi_board_info bfin_spi_board_info[] __initdata = {
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
- || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+ || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
{
.modalias = "ad1836",
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
@@ -412,7 +441,9 @@ static struct platform_device *ezkit_devices[] __initdata = {
#endif
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
- &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
#endif
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -458,3 +489,18 @@ static int __init ezkit_init(void)
}
arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(ezkit_early_devices,
+ ARRAY_SIZE(ezkit_early_devices));
+}
diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c
index 8ba7252455e..d3017e53686 100644
--- a/arch/blackfin/mach-bf561/boards/tepla.c
+++ b/arch/blackfin/mach-bf561/boards/tepla.c
@@ -42,6 +42,52 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+ {
+ .start = BFIN_UART_THR,
+ .end = BFIN_UART_GCTL+2,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_UART_RX,
+ .end = IRQ_UART_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_UART_ERROR,
+ .end = IRQ_UART_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_UART_TX,
+ .end = CH_UART_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_UART_RX,
+ .end = CH_UART_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+ P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+ .name = "bfin-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+ .resource = bfin_uart0_resources,
+ .dev = {
+ .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+ },
+};
+#endif
+#endif
+
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
static struct resource bfin_sir0_resources[] = {
@@ -73,6 +119,13 @@ static struct platform_device bfin_sir0_device = {
static struct platform_device *tepla_devices[] __initdata = {
&smc91x_device,
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+
#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
#ifdef CONFIG_BFIN_SIR0
&bfin_sir0_device,
@@ -87,3 +140,18 @@ static int __init tepla_init(void)
}
arch_initcall(tepla_init);
+
+static struct platform_device *tepla_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+ printk(KERN_INFO "register early platform devices\n");
+ early_platform_add_devices(tepla_early_devices,
+ ARRAY_SIZE(tepla_early_devices));
+}
diff --git a/arch/blackfin/mach-bf561/hotplug.c b/arch/blackfin/mach-bf561/hotplug.c
new file mode 100644
index 00000000000..c95169b612d
--- /dev/null
+++ b/arch/blackfin/mach-bf561/hotplug.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ * Graff Yang <graf.yang@analog.com>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <asm/blackfin.h>
+#include <asm/smp.h>
+#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
+
+int hotplug_coreb;
+
+void platform_cpu_die(void)
+{
+ unsigned long iwr[2] = {0, 0};
+ unsigned long bank = SIC_SYSIRQ(IRQ_SUPPLE_0) / 32;
+ unsigned long bit = 1 << (SIC_SYSIRQ(IRQ_SUPPLE_0) % 32);
+
+ hotplug_coreb = 1;
+
+ iwr[bank] = bit;
+
+ /* disable core timer */
+ bfin_write_TCNTL(0);
+
+ /* clear ipi interrupt IRQ_SUPPLE_0 */
+ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + 1)));
+ SSYNC();
+
+ coreb_sleep(iwr[0], iwr[1], 0);
+}
diff --git a/arch/blackfin/mach-bf561/include/mach/irq.h b/arch/blackfin/mach-bf561/include/mach/irq.h
index 7b208db267b..c95566ade51 100644
--- a/arch/blackfin/mach-bf561/include/mach/irq.h
+++ b/arch/blackfin/mach-bf561/include/mach/irq.h
@@ -265,7 +265,8 @@
#define GPIO_IRQ_BASE IRQ_PF0
-#define NR_IRQS (IRQ_PF47 + 1)
+#define NR_MACH_IRQS (IRQ_PF47 + 1)
+#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
#define IVG7 7
#define IVG8 8
diff --git a/arch/blackfin/mach-bf561/include/mach/smp.h b/arch/blackfin/mach-bf561/include/mach/smp.h
index 390c7f4ae7b..2c8c514dd38 100644
--- a/arch/blackfin/mach-bf561/include/mach/smp.h
+++ b/arch/blackfin/mach-bf561/include/mach/smp.h
@@ -25,4 +25,6 @@ void platform_send_ipi_cpu(unsigned int cpu);
void platform_clear_ipi(unsigned int cpu);
+void bfin_local_timer_setup(void);
+
#endif /* !_MACH_BF561_SMP */
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S
index 8e6050369c0..4624eebbf9c 100644
--- a/arch/blackfin/mach-bf561/secondary.S
+++ b/arch/blackfin/mach-bf561/secondary.S
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <asm/blackfin.h>
#include <asm/asm-offsets.h>
+#include <asm/trace.h>
__INIT
@@ -62,6 +63,8 @@ ENTRY(_coreb_trampoline_start)
M2 = r0;
M3 = r0;
+ trace_buffer_init(p0,r0);
+
/* Turn off the icache */
p0.l = LO(IMEM_CONTROL);
p0.h = HI(IMEM_CONTROL);
@@ -159,6 +162,41 @@ ENTRY(_coreb_trampoline_start)
ENDPROC(_coreb_trampoline_start)
ENTRY(_coreb_trampoline_end)
+.section ".text"
+ENTRY(_set_sicb_iwr)
+ P0.H = hi(SICB_IWR0);
+ P0.L = lo(SICB_IWR0);
+ P1.H = hi(SICB_IWR1);
+ P1.L = lo(SICB_IWR1);
+ [P0] = R0;
+ [P1] = R1;
+ SSYNC;
+ RTS;
+ENDPROC(_set_sicb_iwr)
+
+ENTRY(_coreb_sleep)
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+ call _set_sicb_iwr;
+
+ CLI R2;
+ SSYNC;
+ IDLE;
+ STI R2;
+
+ R0 = IWR_DISABLE_ALL;
+ R1 = IWR_DISABLE_ALL;
+ call _set_sicb_iwr;
+
+ p0.h = hi(COREB_L1_CODE_START);
+ p0.l = lo(COREB_L1_CODE_START);
+ jump (p0);
+ENDPROC(_coreb_sleep)
+
+__CPUINIT
ENTRY(_coreb_start)
[--sp] = reti;
@@ -176,12 +214,20 @@ ENTRY(_coreb_start)
sp = [p0];
usp = sp;
fp = sp;
+#ifdef CONFIG_HOTPLUG_CPU
+ p0.l = _hotplug_coreb;
+ p0.h = _hotplug_coreb;
+ r0 = [p0];
+ cc = BITTST(r0, 0);
+ if cc jump 3f;
+#endif
sp += -12;
call _init_pda
sp += 12;
+#ifdef CONFIG_HOTPLUG_CPU
+3:
+#endif
call _secondary_start_kernel;
.L_exit:
jump.s .L_exit;
ENDPROC(_coreb_start)
-
-__FINIT
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index 0192532e96a..3b9a4bf7dac 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -11,11 +11,10 @@
#include <linux/delay.h>
#include <asm/smp.h>
#include <asm/dma.h>
+#include <asm/time.h>
static DEFINE_SPINLOCK(boot_lock);
-static cpumask_t cpu_callin_map;
-
/*
* platform_init_cpus() - Tell the world about how many cores we
* have. This is called while setting up the architecture support
@@ -66,13 +65,15 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
bfin_write_SICB_IAR5(bfin_read_SICA_IAR5());
bfin_write_SICB_IAR6(bfin_read_SICA_IAR6());
bfin_write_SICB_IAR7(bfin_read_SICA_IAR7());
+ bfin_write_SICB_IWR0(IWR_DISABLE_ALL);
+ bfin_write_SICB_IWR1(IWR_DISABLE_ALL);
SSYNC();
/* Store CPU-private information to the cpu_data array. */
bfin_setup_cpudata(cpu);
/* We are done with local CPU inits, unblock the boot CPU. */
- cpu_set(cpu, cpu_callin_map);
+ set_cpu_online(cpu, true);
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}
@@ -81,28 +82,28 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
{
unsigned long timeout;
- /* CoreB already running?! */
- BUG_ON((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0);
-
printk(KERN_INFO "Booting Core B.\n");
spin_lock(&boot_lock);
- /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
- SSYNC();
- bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
- SSYNC();
+ if ((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0) {
+ /* CoreB already running, sending ipi to wakeup it */
+ platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0);
+ } else {
+ /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
+ bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
+ SSYNC();
+ }
timeout = jiffies + 1 * HZ;
while (time_before(jiffies, timeout)) {
- if (cpu_isset(cpu, cpu_callin_map))
+ if (cpu_online(cpu))
break;
udelay(100);
barrier();
}
- if (cpu_isset(cpu, cpu_callin_map)) {
- cpu_set(cpu, cpu_online_map);
+ if (cpu_online(cpu)) {
/* release the lock and let coreb run */
spin_unlock(&boot_lock);
return 0;
@@ -147,3 +148,20 @@ void platform_clear_ipi(unsigned int cpu)
bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + cpu)));
SSYNC();
}
+
+/*
+ * Setup core B's local core timer.
+ * In SMP, core timer is used for clock event device.
+ */
+void __cpuinit bfin_local_timer_setup(void)
+{
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+ bfin_coretmr_init();
+ bfin_coretmr_clockevent_init();
+ get_irq_chip(IRQ_CORETMR)->unmask(IRQ_CORETMR);
+#else
+ /* Power down the core timer, just to play safe. */
+ bfin_write_TCNTL(0);
+#endif
+
+}
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index 77758289725..4391d03dc84 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -11,10 +11,13 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/fs.h>
+#include <linux/delay.h>
#include <asm/blackfin.h>
#include <asm/time.h>
#include <asm/dpmc.h>
+#define CPUFREQ_CPU 0
+
/* this is the table of CCLK frequencies, in Hz */
/* .index is the entry in the auxillary dpm_state_table[] */
static struct cpufreq_frequency_table bfin_freq_table[] = {
@@ -41,64 +44,124 @@ static struct bfin_dpm_state {
unsigned int tscale; /* change the divider on the core timer interrupt */
} dpm_state_table[3];
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
/*
- normalized to maximum frequncy offset for CYCLES,
- used in time-ts cycles clock source, but could be used
- somewhere also.
+ * normalized to maximum frequncy offset for CYCLES,
+ * used in time-ts cycles clock source, but could be used
+ * somewhere also.
*/
unsigned long long __bfin_cycles_off;
unsigned int __bfin_cycles_mod;
+#endif
/**************************************************************************/
+static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk)
+{
-static unsigned int bfin_getfreq_khz(unsigned int cpu)
+ unsigned long csel, min_cclk;
+ int index;
+
+ /* Anomaly 273 seems to still exist on non-BF54x w/dcache turned on */
+#if ANOMALY_05000273 || ANOMALY_05000274 || \
+ (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE))
+ min_cclk = sclk * 2;
+#else
+ min_cclk = sclk;
+#endif
+ csel = ((bfin_read_PLL_DIV() & CSEL) >> 4);
+
+ for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
+ bfin_freq_table[index].frequency = cclk >> index;
+ dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
+ dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1;
+
+ pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
+ bfin_freq_table[index].frequency,
+ dpm_state_table[index].csel,
+ dpm_state_table[index].tscale);
+ }
+ return;
+}
+
+static void bfin_adjust_core_timer(void *info)
{
- /* The driver only support single cpu */
- if (cpu != 0)
- return -1;
+ unsigned int tscale;
+ unsigned int index = *(unsigned int *)info;
- return get_cclk() / 1000;
+ /* we have to adjust the core timer, because it is using cclk */
+ tscale = dpm_state_table[index].tscale;
+ bfin_write_TSCALE(tscale);
+ return;
}
+static unsigned int bfin_getfreq_khz(unsigned int cpu)
+{
+ /* Both CoreA/B have the same core clock */
+ return get_cclk() / 1000;
+}
-static int bfin_target(struct cpufreq_policy *policy,
+static int bfin_target(struct cpufreq_policy *poli,
unsigned int target_freq, unsigned int relation)
{
- unsigned int index, plldiv, tscale;
+ unsigned int index, plldiv, cpu;
unsigned long flags, cclk_hz;
struct cpufreq_freqs freqs;
+ static unsigned long lpj_ref;
+ static unsigned int lpj_ref_freq;
+
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
cycles_t cycles;
+#endif
- if (cpufreq_frequency_table_target(policy, bfin_freq_table,
- target_freq, relation, &index))
- return -EINVAL;
-
- cclk_hz = bfin_freq_table[index].frequency;
-
- freqs.old = bfin_getfreq_khz(0);
- freqs.new = cclk_hz;
- freqs.cpu = 0;
-
- pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
- cclk_hz, target_freq, freqs.old);
-
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- local_irq_save_hw(flags);
- plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel;
- tscale = dpm_state_table[index].tscale;
- bfin_write_PLL_DIV(plldiv);
- /* we have to adjust the core timer, because it is using cclk */
- bfin_write_TSCALE(tscale);
- cycles = get_cycles();
- SSYNC();
- cycles += 10; /* ~10 cycles we lose after get_cycles() */
- __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
- __bfin_cycles_mod = index;
- local_irq_restore_hw(flags);
- /* TODO: just test case for cycles clock source, remove later */
- pr_debug("cpufreq: done\n");
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ for_each_online_cpu(cpu) {
+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+
+ if (!policy)
+ continue;
+
+ if (cpufreq_frequency_table_target(policy, bfin_freq_table,
+ target_freq, relation, &index))
+ return -EINVAL;
+
+ cclk_hz = bfin_freq_table[index].frequency;
+
+ freqs.old = bfin_getfreq_khz(0);
+ freqs.new = cclk_hz;
+ freqs.cpu = cpu;
+
+ pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
+ cclk_hz, target_freq, freqs.old);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ if (cpu == CPUFREQ_CPU) {
+ local_irq_save_hw(flags);
+ plldiv = (bfin_read_PLL_DIV() & SSEL) |
+ dpm_state_table[index].csel;
+ bfin_write_PLL_DIV(plldiv);
+ on_each_cpu(bfin_adjust_core_timer, &index, 1);
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
+ cycles = get_cycles();
+ SSYNC();
+ cycles += 10; /* ~10 cycles we lose after get_cycles() */
+ __bfin_cycles_off +=
+ (cycles << __bfin_cycles_mod) - (cycles << index);
+ __bfin_cycles_mod = index;
+#endif
+ if (!lpj_ref_freq) {
+ lpj_ref = loops_per_jiffy;
+ lpj_ref_freq = freqs.old;
+ }
+ if (freqs.new != freqs.old) {
+ loops_per_jiffy = cpufreq_scale(lpj_ref,
+ lpj_ref_freq, freqs.new);
+ }
+ local_irq_restore_hw(flags);
+ }
+ /* TODO: just test case for cycles clock source, remove later */
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+ pr_debug("cpufreq: done\n");
return 0;
}
@@ -110,37 +173,16 @@ static int bfin_verify_speed(struct cpufreq_policy *policy)
static int __init __bfin_cpu_init(struct cpufreq_policy *policy)
{
- unsigned long cclk, sclk, csel, min_cclk;
- int index;
-
- if (policy->cpu != 0)
- return -EINVAL;
+ unsigned long cclk, sclk;
cclk = get_cclk() / 1000;
sclk = get_sclk() / 1000;
-#if ANOMALY_05000273 || ANOMALY_05000274 || \
- (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE))
- min_cclk = sclk * 2;
-#else
- min_cclk = sclk;
-#endif
- csel = ((bfin_read_PLL_DIV() & CSEL) >> 4);
-
- for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
- bfin_freq_table[index].frequency = cclk >> index;
- dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
- dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1;
-
- pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
- bfin_freq_table[index].frequency,
- dpm_state_table[index].csel,
- dpm_state_table[index].tscale);
- }
+ if (policy->cpu == CPUFREQ_CPU)
+ bfin_init_tables(cclk, sclk);
policy->cpuinfo.transition_latency = 50000; /* 50us assumed */
- /*Now ,only support one cpu */
policy->cur = cclk;
cpufreq_frequency_table_get_attr(bfin_freq_table, policy->cpu);
return cpufreq_frequency_table_cpuinfo(policy, bfin_freq_table);
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 01b2f58dfb9..a5847f5d67c 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -405,7 +405,7 @@ ENTRY(_double_fault)
r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
SP += -12;
- call _double_fault_c;
+ pseudo_long_call _double_fault_c, p5;
SP += 12;
.L_double_fault_panic:
JUMP .L_double_fault_panic
@@ -447,7 +447,7 @@ ENTRY(_exception_to_level5)
r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
SP += -12;
- call _trap_c;
+ pseudo_long_call _trap_c, p4;
SP += 12;
/* If interrupts were off during the exception (IPEND[4] = 1), turn them off
@@ -482,6 +482,8 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
[--sp] = ASTAT;
[--sp] = (R7:6,P5:4);
+ ANOMALY_283_315_WORKAROUND(p5, r7)
+
#ifdef CONFIG_EXACT_HWERR
/* Make sure all pending read/writes complete. This will ensure any
* accesses which could cause hardware errors completes, and signal
@@ -492,8 +494,6 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
ssync;
#endif
- ANOMALY_283_315_WORKAROUND(p5, r7)
-
#ifdef CONFIG_DEBUG_DOUBLEFAULT
/*
* Save these registers, as they are only valid in exception context
@@ -551,7 +551,7 @@ ENTRY(_kernel_execve)
p0 = sp;
sp += -16;
[sp + 12] = p0;
- call _do_execve;
+ pseudo_long_call _do_execve, p5;
SP += 16;
cc = r0 == 0;
if ! cc jump .Lexecve_failed;
@@ -626,13 +626,6 @@ ENTRY(_system_call)
p0 = [sp + PT_ORIG_P0];
#endif /* CONFIG_IPIPE */
- /* Check the System Call */
- r7 = __NR_syscall;
- /* System call number is passed in P0 */
- r6 = p0;
- cc = r6 < r7;
- if ! cc jump .Lbadsys;
-
/* are we tracing syscalls?*/
r7 = sp;
r6.l = lo(ALIGN_PAGE_MASK);
@@ -642,6 +635,14 @@ ENTRY(_system_call)
r7 = [p2+TI_FLAGS];
CC = BITTST(r7,TIF_SYSCALL_TRACE);
if CC JUMP _sys_trace;
+ CC = BITTST(r7,TIF_SINGLESTEP);
+ if CC JUMP _sys_trace;
+
+ /* Make sure the system call # is valid */
+ p4 = __NR_syscall;
+ /* System call number is passed in P0 */
+ cc = p4 <= p0;
+ if cc jump .Lbadsys;
/* Execute the appropriate system call */
@@ -704,7 +705,7 @@ ENTRY(_system_call)
sp += 4;
SP += -12;
- call _schedule;
+ pseudo_long_call _schedule, p4;
SP += 12;
jump .Lresume_userspace_1;
@@ -723,7 +724,7 @@ ENTRY(_system_call)
r0 = sp;
SP += -12;
- call _do_notify_resume;
+ pseudo_long_call _do_notify_resume, p5;
SP += 12;
.Lsyscall_really_exit:
@@ -736,11 +737,17 @@ ENDPROC(_system_call)
* this symbol need not be global anyways, so ...
*/
_sys_trace:
- call _syscall_trace;
-
- /* Execute the appropriate system call */
+ r0 = sp;
+ pseudo_long_call _syscall_trace_enter, p5;
+ /* Make sure the system call # is valid */
p4 = [SP + PT_P0];
+ p3 = __NR_syscall;
+ cc = p3 <= p4;
+ r0 = -ENOSYS;
+ if cc jump .Lsys_trace_badsys;
+
+ /* Execute the appropriate system call */
p5.l = _sys_call_table;
p5.h = _sys_call_table;
p5 = p5 + (p4 << 2);
@@ -758,9 +765,11 @@ _sys_trace:
SP += -12;
call (p5);
SP += 24;
+.Lsys_trace_badsys:
[sp + PT_R0] = r0;
- call _syscall_trace;
+ r0 = sp;
+ pseudo_long_call _syscall_trace_leave, p5;
jump .Lresume_userspace;
ENDPROC(_sys_trace)
@@ -966,6 +975,13 @@ ENTRY(_evt_evt14)
#else
cli r0;
#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+ [--sp] = rets;
+ sp += -12;
+ call _trace_hardirqs_off;
+ sp += 12;
+ rets = [sp++];
+#endif
[--sp] = RETI;
SP += 4;
rts;
@@ -989,6 +1005,14 @@ ENTRY(_schedule_and_signal_from_int)
p1 = rets;
[sp + PT_RESERVED] = p1;
+#ifdef CONFIG_TRACE_IRQFLAGS
+ /* trace_hardirqs_on() checks if all irqs are disabled. But here IRQ 15
+ * is turned on, so disable all irqs. */
+ cli r0;
+ sp += -12;
+ call _trace_hardirqs_on;
+ sp += 12;
+#endif
#ifdef CONFIG_SMP
GET_PDA(p0, r0); /* Fetch current PDA (can't migrate to other CPU here) */
r0 = [p0 + PDA_IRQFLAGS];
@@ -1007,7 +1031,8 @@ ENTRY(_schedule_and_signal_from_int)
r0 = sp;
sp += -12;
- call _finish_atomic_sections;
+
+ pseudo_long_call _finish_atomic_sections, p5;
sp += 12;
jump.s .Lresume_userspace;
ENDPROC(_schedule_and_signal_from_int)
@@ -1357,7 +1382,7 @@ ENTRY(_sys_call_table)
.long _sys_newuname
.long _sys_ni_syscall /* old sys_modify_ldt */
.long _sys_adjtimex
- .long _sys_ni_syscall /* 125 */ /* sys_mprotect */
+ .long _sys_mprotect /* 125 */
.long _sys_ni_syscall /* old sys_sigprocmask */
.long _sys_ni_syscall /* old "creat_module" */
.long _sys_init_module
@@ -1376,16 +1401,16 @@ ENTRY(_sys_call_table)
.long _sys_getdents
.long _sys_ni_syscall /* sys_select */
.long _sys_flock
- .long _sys_ni_syscall /* sys_msync */
+ .long _sys_msync
.long _sys_readv /* 145 */
.long _sys_writev
.long _sys_getsid
.long _sys_fdatasync
.long _sys_sysctl
- .long _sys_ni_syscall /* 150 */ /* sys_mlock */
- .long _sys_ni_syscall /* sys_munlock */
- .long _sys_ni_syscall /* sys_mlockall */
- .long _sys_ni_syscall /* sys_munlockall */
+ .long _sys_mlock /* 150 */
+ .long _sys_munlock
+ .long _sys_mlockall
+ .long _sys_munlockall
.long _sys_sched_setparam
.long _sys_sched_getparam /* 155 */
.long _sys_sched_setscheduler
@@ -1450,8 +1475,8 @@ ENTRY(_sys_call_table)
.long _sys_setfsuid /* 215 */
.long _sys_setfsgid
.long _sys_pivot_root
- .long _sys_ni_syscall /* sys_mincore */
- .long _sys_ni_syscall /* sys_madvise */
+ .long _sys_mincore
+ .long _sys_madvise
.long _sys_getdents64 /* 220 */
.long _sys_fcntl64
.long _sys_ni_syscall /* reserved for TUX */
@@ -1507,7 +1532,7 @@ ENTRY(_sys_call_table)
.long _sys_utimes
.long _sys_fadvise64_64
.long _sys_ni_syscall /* vserver */
- .long _sys_ni_syscall /* 275, mbind */
+ .long _sys_mbind /* 275 */
.long _sys_ni_syscall /* get_mempolicy */
.long _sys_ni_syscall /* set_mempolicy */
.long _sys_mq_open
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index cab0a0031ee..4391621d904 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -144,8 +144,8 @@ ENTRY(__start)
#endif
/* Initialize stack pointer */
- sp.l = _init_thread_union;
- sp.h = _init_thread_union;
+ sp.l = _init_thread_union + THREAD_SIZE;
+ sp.h = _init_thread_union + THREAD_SIZE;
fp = sp;
usp = sp;
@@ -186,6 +186,11 @@ ENTRY(__start)
/* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
call _bfin_relocate_l1_mem;
+
+#ifdef CONFIG_ROMKERNEL
+ call _bfin_relocate_xip_data;
+#endif
+
#ifdef CONFIG_BFIN_KERNEL_CLOCK
/* Only use on-chip scratch space for stack when absolutely required
* to avoid Anomaly 05000227 ... we know the init_clocks() func only
@@ -257,12 +262,7 @@ ENTRY(_real_start)
R0 = R7;
call _cmdline_init;
- /* Load the current thread pointer and stack */
- p1 = THREAD_SIZE + 4 (z); /* +4 is for reti loading */
- sp = sp + p1;
- usp = sp;
- fp = sp;
- sp += -12;
+ sp += -12 + 4; /* +4 is for reti loading above */
call _init_pda
sp += 12;
jump.l _start_kernel;
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 8085ff1cce0..cee62cf4acd 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -88,6 +88,13 @@ __common_int_entry:
#else
cli r1;
#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+ [--sp] = r0;
+ sp += -12;
+ call _trace_hardirqs_off;
+ sp += 12;
+ r0 = [sp++];
+#endif
[--sp] = RETI; /* orig_pc */
/* Clear all L registers. */
r1 = 0 (x);
@@ -109,10 +116,10 @@ __common_int_entry:
cc = r0 == 0;
if cc jump .Lcommon_restore_context;
#else /* CONFIG_IPIPE */
- call _do_irq;
+ pseudo_long_call _do_irq, p2;
SP += 12;
#endif /* CONFIG_IPIPE */
- call _return_from_int;
+ pseudo_long_call _return_from_int, p2;
.Lcommon_restore_context:
RESTORE_CONTEXT
rti;
@@ -168,7 +175,7 @@ ENTRY(_evt_ivhw)
r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
SP += -12;
- call _trap_c;
+ pseudo_long_call _trap_c, p5;
SP += 12;
#ifdef EBIU_ERRMST
@@ -179,7 +186,7 @@ ENTRY(_evt_ivhw)
w[p0] = r0.l;
#endif
- call _ret_from_exception;
+ pseudo_long_call _ret_from_exception, p2;
.Lcommon_restore_all_sys:
RESTORE_ALL_SYS
@@ -187,12 +194,28 @@ ENTRY(_evt_ivhw)
ENDPROC(_evt_ivhw)
/* Interrupt routine for evt2 (NMI).
- * We don't actually use this, so just return.
* For inner circle type details, please see:
* http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:nmi
*/
ENTRY(_evt_nmi)
+#ifndef CONFIG_NMI_WATCHDOG
.weak _evt_nmi
+#else
+ /* Not take account of CPLBs, this handler will not return */
+ SAVE_ALL_SYS
+ r0 = sp;
+ r1 = retn;
+ [sp + PT_PC] = r1;
+ trace_buffer_save(p4,r5);
+
+ ANOMALY_283_315_WORKAROUND(p4, r5)
+
+ SP += -12;
+ call _do_nmi;
+ SP += 12;
+1:
+ jump 1b;
+#endif
rtn;
ENDPROC(_evt_nmi)
@@ -223,7 +246,7 @@ ENTRY(_evt_system_call)
#ifdef CONFIG_FRAME_POINTER
fp = 0;
#endif
- call _system_call;
+ pseudo_long_call _system_call, p2;
jump .Lcommon_restore_context;
ENDPROC(_evt_system_call)
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 1873b2c1fed..7ad8878bfa1 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -28,6 +28,7 @@
#include <asm/dpmc.h>
#include <asm/bfin5xx_spi.h>
#include <asm/bfin_sport.h>
+#include <asm/bfin_can.h>
#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
@@ -172,7 +173,12 @@ static void bfin_internal_mask_irq(unsigned int irq)
local_irq_restore_hw(flags);
}
+#ifdef CONFIG_SMP
+static void bfin_internal_unmask_irq_affinity(unsigned int irq,
+ const struct cpumask *affinity)
+#else
static void bfin_internal_unmask_irq(unsigned int irq)
+#endif
{
unsigned long flags;
@@ -185,16 +191,38 @@ static void bfin_internal_unmask_irq(unsigned int irq)
local_irq_save_hw(flags);
mask_bank = SIC_SYSIRQ(irq) / 32;
mask_bit = SIC_SYSIRQ(irq) % 32;
- bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
- (1 << mask_bit));
#ifdef CONFIG_SMP
- bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) |
- (1 << mask_bit));
+ if (cpumask_test_cpu(0, affinity))
+#endif
+ bfin_write_SIC_IMASK(mask_bank,
+ bfin_read_SIC_IMASK(mask_bank) |
+ (1 << mask_bit));
+#ifdef CONFIG_SMP
+ if (cpumask_test_cpu(1, affinity))
+ bfin_write_SICB_IMASK(mask_bank,
+ bfin_read_SICB_IMASK(mask_bank) |
+ (1 << mask_bit));
#endif
#endif
local_irq_restore_hw(flags);
}
+#ifdef CONFIG_SMP
+static void bfin_internal_unmask_irq(unsigned int irq)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ bfin_internal_unmask_irq_affinity(irq, desc->affinity);
+}
+
+static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask)
+{
+ bfin_internal_mask_irq(irq);
+ bfin_internal_unmask_irq_affinity(irq, mask);
+
+ return 0;
+}
+#endif
+
#ifdef CONFIG_PM
int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
@@ -224,11 +252,6 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
wakeup |= USBWE;
break;
#endif
-#ifdef IRQ_KEY
- case IRQ_KEY:
- wakeup |= KPADWE;
- break;
-#endif
#ifdef CONFIG_BF54x
case IRQ_CNT:
wakeup |= ROTWE;
@@ -270,6 +293,9 @@ static struct irq_chip bfin_internal_irqchip = {
.mask_ack = bfin_internal_mask_irq,
.disable = bfin_internal_mask_irq,
.enable = bfin_internal_unmask_irq,
+#ifdef CONFIG_SMP
+ .set_affinity = bfin_internal_set_affinity,
+#endif
#ifdef CONFIG_PM
.set_wake = bfin_internal_set_wake,
#endif
@@ -294,7 +320,6 @@ static int error_int_mask;
static void bfin_generic_error_mask_irq(unsigned int irq)
{
error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
-
if (!error_int_mask)
bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
}
@@ -385,6 +410,127 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
}
#endif /* BF537_GENERIC_ERROR_INT_DEMUX */
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static int mac_stat_int_mask;
+
+static void bfin_mac_status_ack_irq(unsigned int irq)
+{
+ switch (irq) {
+ case IRQ_MAC_MMCINT:
+ bfin_write_EMAC_MMC_TIRQS(
+ bfin_read_EMAC_MMC_TIRQE() &
+ bfin_read_EMAC_MMC_TIRQS());
+ bfin_write_EMAC_MMC_RIRQS(
+ bfin_read_EMAC_MMC_RIRQE() &
+ bfin_read_EMAC_MMC_RIRQS());
+ break;
+ case IRQ_MAC_RXFSINT:
+ bfin_write_EMAC_RX_STKY(
+ bfin_read_EMAC_RX_IRQE() &
+ bfin_read_EMAC_RX_STKY());
+ break;
+ case IRQ_MAC_TXFSINT:
+ bfin_write_EMAC_TX_STKY(
+ bfin_read_EMAC_TX_IRQE() &
+ bfin_read_EMAC_TX_STKY());
+ break;
+ case IRQ_MAC_WAKEDET:
+ bfin_write_EMAC_WKUP_CTL(
+ bfin_read_EMAC_WKUP_CTL() | MPKS | RWKS);
+ break;
+ default:
+ /* These bits are W1C */
+ bfin_write_EMAC_SYSTAT(1L << (irq - IRQ_MAC_PHYINT));
+ break;
+ }
+}
+
+static void bfin_mac_status_mask_irq(unsigned int irq)
+{
+ mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT));
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ switch (irq) {
+ case IRQ_MAC_PHYINT:
+ bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE);
+ break;
+ default:
+ break;
+ }
+#else
+ if (!mac_stat_int_mask)
+ bfin_internal_mask_irq(IRQ_MAC_ERROR);
+#endif
+ bfin_mac_status_ack_irq(irq);
+}
+
+static void bfin_mac_status_unmask_irq(unsigned int irq)
+{
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ switch (irq) {
+ case IRQ_MAC_PHYINT:
+ bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE);
+ break;
+ default:
+ break;
+ }
+#else
+ if (!mac_stat_int_mask)
+ bfin_internal_unmask_irq(IRQ_MAC_ERROR);
+#endif
+ mac_stat_int_mask |= 1L << (irq - IRQ_MAC_PHYINT);
+}
+
+#ifdef CONFIG_PM
+int bfin_mac_status_set_wake(unsigned int irq, unsigned int state)
+{
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state);
+#else
+ return bfin_internal_set_wake(IRQ_MAC_ERROR, state);
+#endif
+}
+#endif
+
+static struct irq_chip bfin_mac_status_irqchip = {
+ .name = "MACST",
+ .ack = bfin_ack_noop,
+ .mask_ack = bfin_mac_status_mask_irq,
+ .mask = bfin_mac_status_mask_irq,
+ .unmask = bfin_mac_status_unmask_irq,
+#ifdef CONFIG_PM
+ .set_wake = bfin_mac_status_set_wake,
+#endif
+};
+
+static void bfin_demux_mac_status_irq(unsigned int int_err_irq,
+ struct irq_desc *inta_desc)
+{
+ int i, irq = 0;
+ u32 status = bfin_read_EMAC_SYSTAT();
+
+ for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++)
+ if (status & (1L << i)) {
+ irq = IRQ_MAC_PHYINT + i;
+ break;
+ }
+
+ if (irq) {
+ if (mac_stat_int_mask & (1L << (irq - IRQ_MAC_PHYINT))) {
+ bfin_handle_irq(irq);
+ } else {
+ bfin_mac_status_ack_irq(irq);
+ pr_debug("IRQ %d:"
+ " MASKED MAC ERROR INTERRUPT ASSERTED\n",
+ irq);
+ }
+ } else
+ printk(KERN_ERR
+ "%s : %s : LINE %d :\nIRQ ?: MAC ERROR"
+ " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
+ __func__, __FILE__, __LINE__);
+}
+#endif
+
static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)
{
#ifdef CONFIG_IPIPE
@@ -1031,7 +1177,6 @@ int __init init_arch_irq(void)
#elif defined(CONFIG_BF538) || defined(CONFIG_BF539)
case IRQ_PORTF_INTA:
#endif
-
set_irq_chained_handler(irq,
bfin_demux_gpio_irq);
break;
@@ -1040,29 +1185,36 @@ int __init init_arch_irq(void)
set_irq_chained_handler(irq, bfin_demux_error_irq);
break;
#endif
-
-#ifdef CONFIG_SMP
-#ifdef CONFIG_TICKSOURCE_GPTMR0
- case IRQ_TIMER0:
-#endif
-#ifdef CONFIG_TICKSOURCE_CORETMR
- case IRQ_CORETMR:
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ case IRQ_MAC_ERROR:
+ set_irq_chained_handler(irq, bfin_demux_mac_status_irq);
+ break;
#endif
+#ifdef CONFIG_SMP
case IRQ_SUPPLE_0:
case IRQ_SUPPLE_1:
set_irq_handler(irq, handle_percpu_irq);
break;
#endif
-#ifdef CONFIG_IPIPE
-#ifndef CONFIG_TICKSOURCE_CORETMR
- case IRQ_TIMER0:
+#ifdef CONFIG_TICKSOURCE_CORETMR
+ case IRQ_CORETMR:
+# ifdef CONFIG_SMP
+ set_irq_handler(irq, handle_percpu_irq);
+ break;
+# else
set_irq_handler(irq, handle_simple_irq);
break;
+# endif
#endif
- case IRQ_CORETMR:
+
+#ifdef CONFIG_TICKSOURCE_GPTMR0
+ case IRQ_TIMER0:
set_irq_handler(irq, handle_simple_irq);
break;
+#endif
+
+#ifdef CONFIG_IPIPE
default:
set_irq_handler(irq, handle_level_irq);
break;
@@ -1078,14 +1230,22 @@ int __init init_arch_irq(void)
for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
handle_level_irq);
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
+#endif
#endif
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
+ set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip,
+ handle_level_irq);
+#endif
/* if configured as edge, then will be changed to do_edge_IRQ */
- for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++)
+ for (irq = GPIO_IRQ_BASE;
+ irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)
set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,
handle_level_irq);
-
bfin_write_IMASK(0);
CSYNC();
ilat = bfin_read_ILAT();
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 8837be4edb4..c1f1ccc846f 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -11,6 +11,7 @@
#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <linux/irq.h>
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 369e687582b..7cecbaf0358 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -21,6 +21,7 @@
#include <linux/smp.h>
#include <linux/seq_file.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
@@ -122,9 +123,17 @@ static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)
wait = msg->call_struct.wait;
cpu_clear(cpu, msg->call_struct.pending);
func(info);
- if (wait)
+ if (wait) {
+#ifdef __ARCH_SYNC_CORE_DCACHE
+ /*
+ * 'wait' usually means synchronization between CPUs.
+ * Invalidate D cache in case shared data was changed
+ * by func() to ensure cache coherence.
+ */
+ resync_core_dcache();
+#endif
cpu_clear(cpu, msg->call_struct.waitmask);
- else
+ } else
kfree(msg);
}
@@ -219,6 +228,13 @@ int smp_call_function(void (*func)(void *info), void *info, int wait)
blackfin_dcache_invalidate_range(
(unsigned long)(&msg->call_struct.waitmask),
(unsigned long)(&msg->call_struct.waitmask));
+#ifdef __ARCH_SYNC_CORE_DCACHE
+ /*
+ * Invalidate D cache in case shared data was changed by
+ * other processors to ensure cache coherence.
+ */
+ resync_core_dcache();
+#endif
kfree(msg);
}
return 0;
@@ -261,6 +277,13 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
blackfin_dcache_invalidate_range(
(unsigned long)(&msg->call_struct.waitmask),
(unsigned long)(&msg->call_struct.waitmask));
+#ifdef __ARCH_SYNC_CORE_DCACHE
+ /*
+ * Invalidate D cache in case shared data was changed by
+ * other processors to ensure cache coherence.
+ */
+ resync_core_dcache();
+#endif
kfree(msg);
}
return 0;
@@ -322,8 +345,11 @@ void smp_send_stop(void)
int __cpuinit __cpu_up(unsigned int cpu)
{
- struct task_struct *idle;
int ret;
+ static struct task_struct *idle;
+
+ if (idle)
+ free_task(idle);
idle = fork_idle(cpu);
if (IS_ERR(idle)) {
@@ -332,7 +358,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
}
secondary_stack = task_stack_page(idle) + THREAD_SIZE;
- smp_wmb();
ret = platform_boot_secondary(cpu, idle);
@@ -343,9 +368,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
static void __cpuinit setup_secondary(unsigned int cpu)
{
-#if !defined(CONFIG_TICKSOURCE_GPTMR0)
- struct irq_desc *timer_desc;
-#endif
unsigned long ilat;
bfin_write_IMASK(0);
@@ -360,17 +382,6 @@ static void __cpuinit setup_secondary(unsigned int cpu)
bfin_irq_flags |= IMASK_IVG15 |
IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
-
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
- /* Power down the core timer, just to play safe. */
- bfin_write_TCNTL(0);
-
- /* system timer0 has been setup by CoreA. */
-#else
- timer_desc = irq_desc + IRQ_CORETMR;
- setup_core_timer();
- timer_desc->chip->enable(IRQ_CORETMR);
-#endif
}
void __cpuinit secondary_start_kernel(void)
@@ -405,7 +416,6 @@ void __cpuinit secondary_start_kernel(void)
atomic_inc(&mm->mm_users);
atomic_inc(&mm->mm_count);
current->active_mm = mm;
- BUG_ON(current->mm); /* Can't be, but better be safe than sorry. */
preempt_disable();
@@ -413,6 +423,9 @@ void __cpuinit secondary_start_kernel(void)
platform_secondary_init(cpu);
+ /* setup local core timer */
+ bfin_local_timer_setup();
+
local_irq_enable();
/*
@@ -462,25 +475,58 @@ void smp_icache_flush_range_others(unsigned long start, unsigned long end)
EXPORT_SYMBOL_GPL(smp_icache_flush_range_others);
#ifdef __ARCH_SYNC_CORE_ICACHE
+unsigned long icache_invld_count[NR_CPUS];
void resync_core_icache(void)
{
unsigned int cpu = get_cpu();
blackfin_invalidate_entire_icache();
- ++per_cpu(cpu_data, cpu).icache_invld_count;
+ icache_invld_count[cpu]++;
put_cpu();
}
EXPORT_SYMBOL(resync_core_icache);
#endif
#ifdef __ARCH_SYNC_CORE_DCACHE
+unsigned long dcache_invld_count[NR_CPUS];
unsigned long barrier_mask __attribute__ ((__section__(".l2.bss")));
void resync_core_dcache(void)
{
unsigned int cpu = get_cpu();
blackfin_invalidate_entire_dcache();
- ++per_cpu(cpu_data, cpu).dcache_invld_count;
+ dcache_invld_count[cpu]++;
put_cpu();
}
EXPORT_SYMBOL(resync_core_dcache);
#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+int __cpuexit __cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ if (cpu == 0)
+ return -EPERM;
+
+ set_cpu_online(cpu, false);
+ return 0;
+}
+
+static DECLARE_COMPLETION(cpu_killed);
+
+int __cpuexit __cpu_die(unsigned int cpu)
+{
+ return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+void cpu_die(void)
+{
+ complete(&cpu_killed);
+
+ atomic_dec(&init_mm.mm_users);
+ atomic_dec(&init_mm.mm_count);
+
+ local_irq_disable();
+ platform_cpu_die();
+}
+#endif
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index bb9c98f9cb5..355b87aa6b9 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -4,6 +4,7 @@
* Licensed under the GPL-2 or later.
*/
+#include <linux/gfp.h>
#include <linux/swap.h>
#include <linux/bootmem.h>
#include <linux/uaccess.h>
diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c
index 84cdc5a1c13..39b058564f6 100644
--- a/arch/blackfin/mm/isram-driver.c
+++ b/arch/blackfin/mm/isram-driver.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
@@ -62,7 +63,7 @@ static void isram_write(const void *addr, uint64_t data)
uint32_t cmd;
unsigned long flags;
- if (addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH))
+ if (unlikely(addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH)))
return;
cmd = IADDR2DTEST(addr) | 2; /* write */
@@ -93,7 +94,7 @@ static uint64_t isram_read(const void *addr)
unsigned long flags;
uint64_t ret;
- if (addr > (void *)(L1_CODE_START + L1_CODE_LENGTH))
+ if (unlikely(addr > (void *)(L1_CODE_START + L1_CODE_LENGTH)))
return 0;
cmd = IADDR2DTEST(addr) | 0; /* read */
@@ -120,7 +121,7 @@ static bool isram_check_addr(const void *addr, size_t n)
{
if ((addr >= (void *)L1_CODE_START) &&
(addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))) {
- if ((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH)) {
+ if (unlikely((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH))) {
show_stack(NULL, NULL);
pr_err("copy involving %p length (%zu) too long\n", addr, n);
}
diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c
index f068c11ea98..49b2ff2c8b7 100644
--- a/arch/blackfin/mm/sram-alloc.c
+++ b/arch/blackfin/mm/sram-alloc.c
@@ -17,6 +17,7 @@
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
#include <asm/blackfin.h>
#include <asm/mem_map.h>
#include "blackfin_sram.h"
@@ -402,7 +403,7 @@ void *l1_data_A_sram_alloc(size_t size)
void *addr;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
@@ -411,7 +412,6 @@ void *l1_data_A_sram_alloc(size_t size)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
- put_cpu();
pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n",
(long unsigned int)addr, size);
@@ -430,7 +430,7 @@ int l1_data_A_sram_free(const void *addr)
int ret;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
@@ -439,7 +439,6 @@ int l1_data_A_sram_free(const void *addr)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
- put_cpu();
return ret;
#else
@@ -455,7 +454,7 @@ void *l1_data_B_sram_alloc(size_t size)
void *addr;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
@@ -464,7 +463,6 @@ void *l1_data_B_sram_alloc(size_t size)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
- put_cpu();
pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n",
(long unsigned int)addr, size);
@@ -483,7 +481,7 @@ int l1_data_B_sram_free(const void *addr)
int ret;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
@@ -492,7 +490,6 @@ int l1_data_B_sram_free(const void *addr)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
- put_cpu();
return ret;
#else
@@ -540,7 +537,7 @@ void *l1_inst_sram_alloc(size_t size)
void *addr;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags);
@@ -549,7 +546,6 @@ void *l1_inst_sram_alloc(size_t size)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags);
- put_cpu();
pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n",
(long unsigned int)addr, size);
@@ -568,7 +564,7 @@ int l1_inst_sram_free(const void *addr)
int ret;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags);
@@ -577,7 +573,6 @@ int l1_inst_sram_free(const void *addr)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags);
- put_cpu();
return ret;
#else
@@ -593,7 +588,7 @@ void *l1sram_alloc(size_t size)
void *addr;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
@@ -602,7 +597,6 @@ void *l1sram_alloc(size_t size)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
- put_cpu();
return addr;
}
@@ -614,7 +608,7 @@ void *l1sram_alloc_max(size_t *psize)
void *addr;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
@@ -623,7 +617,6 @@ void *l1sram_alloc_max(size_t *psize)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
- put_cpu();
return addr;
}
@@ -635,7 +628,7 @@ int l1sram_free(const void *addr)
int ret;
unsigned int cpu;
- cpu = get_cpu();
+ cpu = smp_processor_id();
/* add mutex operation */
spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
@@ -644,7 +637,6 @@ int l1sram_free(const void *addr)
/* add mutex operation */
spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
- put_cpu();
return ret;
}
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 7adac388a77..059eac6abda 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -20,6 +20,12 @@ config RWSEM_GENERIC_SPINLOCK
config RWSEM_XCHGADD_ALGORITHM
bool
+config GENERIC_TIME
+ def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
+ def_bool y
+
config GENERIC_IOMAP
bool
default y
diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c
index 7f656ae0b21..a8737a8eb22 100644
--- a/arch/cris/arch-v10/drivers/i2c.c
+++ b/arch/cris/arch-v10/drivers/i2c.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/kernel.h>
diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c
index 562b9a7feae..109dcd826d1 100644
--- a/arch/cris/arch-v10/drivers/sync_serial.c
+++ b/arch/cris/arch-v10/drivers/sync_serial.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/init.h>
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S
index c52bef39e25..0d6420d087f 100644
--- a/arch/cris/arch-v10/kernel/entry.S
+++ b/arch/cris/arch-v10/kernel/entry.S
@@ -692,7 +692,7 @@ sys_call_table:
.long sys_swapon
.long sys_reboot
.long sys_old_readdir
- .long old_mmap /* 90 */
+ .long sys_old_mmap /* 90 */
.long sys_munmap
.long sys_truncate
.long sys_ftruncate
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c
index c4c69cf721e..93f0f64b132 100644
--- a/arch/cris/arch-v10/kernel/process.c
+++ b/arch/cris/arch-v10/kernel/process.c
@@ -11,9 +11,9 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/fs.h>
-#include <linux/slab.h>
#include <arch/svinto.h>
#include <linux/init.h>
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index ee505b2eb4d..e70c804e937 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -127,57 +127,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = 0;
break;
- case PTRACE_SYSCALL:
- case PTRACE_CONT:
- ret = -EIO;
-
- if (!valid_signal(data))
- break;
-
- if (request == PTRACE_SYSCALL) {
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
- else {
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
-
- child->exit_code = data;
-
- /* TODO: make sure any pending breakpoint is killed */
- wake_up_process(child);
- ret = 0;
-
- break;
-
- /* Make the child exit by sending it a sigkill. */
- case PTRACE_KILL:
- ret = 0;
-
- if (child->exit_state == EXIT_ZOMBIE)
- break;
-
- child->exit_code = SIGKILL;
-
- /* TODO: make sure any pending breakpoint is killed */
- wake_up_process(child);
- break;
-
- /* Set the trap flag. */
- case PTRACE_SINGLESTEP:
- ret = -EIO;
-
- if (!valid_signal(data))
- break;
-
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
- /* TODO: set some clever breakpoint mechanism... */
-
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
- break;
-
/* Get all GP registers from the child. */
case PTRACE_GETREGS: {
int i;
diff --git a/arch/cris/arch-v10/lib/old_checksum.c b/arch/cris/arch-v10/lib/old_checksum.c
index 1734b467efa..8f79163f139 100644
--- a/arch/cris/arch-v10/lib/old_checksum.c
+++ b/arch/cris/arch-v10/lib/old_checksum.c
@@ -77,7 +77,7 @@ __wsum csum_partial(const void *p, int len, __wsum __sum)
sum += *buff++;
if (endMarker > buff)
- sum += *(const u8 *)buff; /* add extra byte seperately */
+ sum += *(const u8 *)buff; /* add extra byte separately */
BITOFF;
return (__force __wsum)sum;
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index fd529a0ec75..b70fb34939d 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -628,9 +628,9 @@ static int create_output_descriptors(struct cryptocop_operation *operation, int
cdesc->dma_descr->buf = (char*)virt_to_phys(operation->tfrm_op.indata[*iniov_ix].iov_base + *iniov_offset);
cdesc->dma_descr->after = cdesc->dma_descr->buf + dlength;
+ assert(desc_len >= dlength);
desc_len -= dlength;
*iniov_offset += dlength;
- assert(desc_len >= 0);
if (*iniov_offset >= operation->tfrm_op.indata[*iniov_ix].iov_len) {
*iniov_offset = 0;
++(*iniov_ix);
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
index 179e7b80433..506826399ae 100644
--- a/arch/cris/arch-v32/drivers/i2c.c
+++ b/arch/cris/arch-v32/drivers/i2c.c
@@ -27,7 +27,6 @@
#include <linux/module.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c
index d4b9c36ddc0..bc0cfdad1cb 100644
--- a/arch/cris/arch-v32/drivers/pci/bios.c
+++ b/arch/cris/arch-v32/drivers/pci/bios.c
@@ -50,7 +50,7 @@ pcibios_align_resource(void *data, const struct resource *res,
if ((res->flags & IORESOURCE_IO) && (start & 0x300))
start = (start + 0x3ff) & ~0x3ff;
- return start
+ return start;
}
int pcibios_enable_resources(struct pci_dev *dev, int mask)
diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c
index fbe65954ee6..ee55578d983 100644
--- a/arch/cris/arch-v32/drivers/pci/dma.c
+++ b/arch/cris/arch-v32/drivers/pci/dma.c
@@ -13,6 +13,7 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <asm/io.h>
void *dma_alloc_coherent(struct device *dev, size_t size,
diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c
index d2a0fbf5341..4889f196ecd 100644
--- a/arch/cris/arch-v32/drivers/sync_serial.c
+++ b/arch/cris/arch-v32/drivers/sync_serial.c
@@ -13,7 +13,6 @@
#include <linux/errno.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S
index 435b9671bd4..1f39861eac8 100644
--- a/arch/cris/arch-v32/kernel/entry.S
+++ b/arch/cris/arch-v32/kernel/entry.S
@@ -615,7 +615,7 @@ sys_call_table:
.long sys_swapon
.long sys_reboot
.long sys_old_readdir
- .long old_mmap /* 90 */
+ .long sys_old_mmap /* 90 */
.long sys_munmap
.long sys_truncate
.long sys_ftruncate
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c
index 120e7f796fe..2661a9529d7 100644
--- a/arch/cris/arch-v32/kernel/process.c
+++ b/arch/cris/arch-v32/kernel/process.c
@@ -9,9 +9,9 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/fs.h>
-#include <linux/slab.h>
#include <hwregs/reg_rdwr.h>
#include <hwregs/reg_map.h>
#include <hwregs/timer_defs.h>
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index dd401473f5b..f4ebd1e7d0f 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -78,6 +78,35 @@ int put_reg(struct task_struct *task, unsigned int regno, unsigned long data)
return 0;
}
+void user_enable_single_step(struct task_struct *child)
+{
+ unsigned long tmp;
+
+ /*
+ * Set up SPC if not set already (in which case we have no other
+ * choice but to trust it).
+ */
+ if (!get_reg(child, PT_SPC)) {
+ /* In case we're stopped in a delay slot. */
+ tmp = get_reg(child, PT_ERP) & ~1;
+ put_reg(child, PT_SPC, tmp);
+ }
+ tmp = get_reg(child, PT_CCS) | SBIT_USER;
+ put_reg(child, PT_CCS, tmp);
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+ put_reg(child, PT_SPC, 0);
+
+ if (!get_debugreg(child->pid, PT_BP_CTRL)) {
+ unsigned long tmp;
+ /* If no h/w bp configured, disable S bit. */
+ tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
+ put_reg(child, PT_CCS, tmp);
+ }
+}
+
/*
* Called by kernel/ptrace.c when detaching.
*
@@ -89,8 +118,7 @@ ptrace_disable(struct task_struct *child)
unsigned long tmp;
/* Deconfigure SPC and S-bit. */
- tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
- put_reg(child, PT_CCS, tmp);
+ user_disable_single_step(child);
put_reg(child, PT_SPC, 0);
/* Deconfigure any watchpoints associated with the child. */
@@ -169,83 +197,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = 0;
break;
- case PTRACE_SYSCALL:
- case PTRACE_CONT:
- ret = -EIO;
-
- if (!valid_signal(data))
- break;
-
- /* Continue means no single-step. */
- put_reg(child, PT_SPC, 0);
-
- if (!get_debugreg(child->pid, PT_BP_CTRL)) {
- unsigned long tmp;
- /* If no h/w bp configured, disable S bit. */
- tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
- put_reg(child, PT_CCS, tmp);
- }
-
- if (request == PTRACE_SYSCALL) {
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
- else {
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
-
- child->exit_code = data;
-
- /* TODO: make sure any pending breakpoint is killed */
- wake_up_process(child);
- ret = 0;
-
- break;
-
- /* Make the child exit by sending it a sigkill. */
- case PTRACE_KILL:
- ret = 0;
-
- if (child->exit_state == EXIT_ZOMBIE)
- break;
-
- child->exit_code = SIGKILL;
-
- /* Deconfigure single-step and h/w bp. */
- ptrace_disable(child);
-
- /* TODO: make sure any pending breakpoint is killed */
- wake_up_process(child);
- break;
-
- /* Set the trap flag. */
- case PTRACE_SINGLESTEP: {
- unsigned long tmp;
- ret = -EIO;
-
- /* Set up SPC if not set already (in which case we have
- no other choice but to trust it). */
- if (!get_reg(child, PT_SPC)) {
- /* In case we're stopped in a delay slot. */
- tmp = get_reg(child, PT_ERP) & ~1;
- put_reg(child, PT_SPC, tmp);
- }
- tmp = get_reg(child, PT_CCS) | SBIT_USER;
- put_reg(child, PT_CCS, tmp);
-
- if (!valid_signal(data))
- break;
-
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
- /* TODO: set some clever breakpoint mechanism... */
-
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
- break;
-
- }
-
/* Get all GP registers from the child. */
case PTRACE_GETREGS: {
int i;
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 372d0ca6efb..0b7e3f14328 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -4,6 +4,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/cris/arch-v32/mach-fs/arbiter.c b/arch/cris/arch-v32/mach-fs/arbiter.c
index 84d31bd7b69..82ef293c4c8 100644
--- a/arch/cris/arch-v32/mach-fs/arbiter.c
+++ b/arch/cris/arch-v32/mach-fs/arbiter.c
@@ -332,7 +332,7 @@ int crisv32_arbiter_unwatch(int id)
if (id == 0)
intr_mask.bp0 = regk_marb_no;
else if (id == 1)
- intr_mask.bp2 = regk_marb_no;
+ intr_mask.bp1 = regk_marb_no;
else if (id == 2)
intr_mask.bp2 = regk_marb_no;
else if (id == 3)
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index 6779bcb28ab..c030d020660 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -189,7 +189,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
spin_unlock(&mmu_context_lock);
/*
- * Remember the pgd for the fault handlers. Keep a seperate
+ * Remember the pgd for the fault handlers. Keep a separate
* copy of it because current and active_mm might be invalid
* at points where * there's still a need to derefer the pgd.
*/
diff --git a/arch/cris/include/arch-v32/arch/ptrace.h b/arch/cris/include/arch-v32/arch/ptrace.h
index 41f4e8662bc..ffca8d0f2e1 100644
--- a/arch/cris/include/arch-v32/arch/ptrace.h
+++ b/arch/cris/include/arch-v32/arch/ptrace.h
@@ -108,6 +108,7 @@ struct switch_stack {
#ifdef __KERNEL__
+#define arch_has_single_step() (1)
#define user_mode(regs) (((regs)->ccs & (1 << (U_CCS_BITNR + CCS_SHIFT))) != 0)
#define instruction_pointer(regs) ((regs)->erp)
extern void show_regs(struct pt_regs *);
diff --git a/arch/cris/include/asm/pci.h b/arch/cris/include/asm/pci.h
index 730ce40fdd0..9f1cd56da28 100644
--- a/arch/cris/include/asm/pci.h
+++ b/arch/cris/include/asm/pci.h
@@ -44,14 +44,6 @@ struct pci_dev;
*/
#define PCI_DMA_BUS_IS_PHYS (1)
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME) (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-
#define HAVE_PCI_MMAP
extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
diff --git a/arch/cris/include/asm/unistd.h b/arch/cris/include/asm/unistd.h
index c17079388bb..f6fad83b3a8 100644
--- a/arch/cris/include/asm/unistd.h
+++ b/arch/cris/include/asm/unistd.h
@@ -352,6 +352,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -364,6 +365,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_MMAP
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
index 6d7b9eda403..469f7f9d62e 100644
--- a/arch/cris/kernel/irq.c
+++ b/arch/cris/kernel/irq.c
@@ -29,7 +29,6 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/seq_file.h>
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c
index abc13e368b9..bcd502f74cd 100644
--- a/arch/cris/kernel/module.c
+++ b/arch/cris/kernel/module.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#if 0
#define DEBUGP printk
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c
index 9aa571169bc..b917549a7d9 100644
--- a/arch/cris/kernel/profile.c
+++ b/arch/cris/kernel/profile.c
@@ -2,6 +2,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c
index c2bbb1ac98a..7aa036ec78f 100644
--- a/arch/cris/kernel/sys_cris.c
+++ b/arch/cris/kernel/sys_cris.c
@@ -26,24 +26,6 @@
#include <asm/uaccess.h>
#include <asm/segment.h>
-asmlinkage unsigned long old_mmap(unsigned long __user *args)
-{
- unsigned long buffer[6];
- int err = -EFAULT;
-
- if (copy_from_user(&buffer, args, sizeof(buffer)))
- goto out;
-
- err = -EINVAL;
- if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
- goto out;
-
- err = sys_mmap_pgoff(buffer[0], buffer[1], buffer[2], buffer[3],
- buffer[4], buffer[5] >> PAGE_SHIFT);
-out:
- return err;
-}
-
asmlinkage long
sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long fd, unsigned long pgoff)
@@ -51,81 +33,3 @@ sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
/* bug(?): 8Kb pages here */
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly. (same as arch/i386)
- */
-
-asmlinkage int sys_ipc (uint call, int first, int second,
- int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
- (const struct timespec __user *)fifth);
-
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void * __user *) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
-
- case SHMAT: {
- ulong raddr;
- ret = do_shmat (first, (char __user *) ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong __user *) third);
- }
- case SHMDT:
- return sys_shmdt ((char __user *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -ENOSYS;
- }
-}
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index 074fe7dea96..a05dd31f3ef 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -42,75 +42,11 @@ unsigned long loops_per_usec;
extern unsigned long do_slow_gettimeoffset(void);
static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
-/*
- * This version of gettimeofday has near microsecond resolution.
- *
- * Note: Division is quite slow on CRIS and do_gettimeofday is called
- * rather often. Maybe we should do some kind of approximation here
- * (a naive approximation would be to divide by 1024).
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- signed long usec, sec;
- local_irq_save(flags);
- usec = do_gettimeoffset();
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0) && usec > tickadj)
- usec = tickadj;
-
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / 1000;
- local_irq_restore(flags);
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
+u32 arch_gettimeoffset(void)
{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= do_gettimeoffset() * NSEC_PER_USEC;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
+ return do_gettimeoffset() * 1000;
}
-EXPORT_SYMBOL(do_settimeofday);
-
-
/*
* BUG: This routine does not handle hour overflow properly; it just
* sets the minutes. Usually you'll only notice that after reboot!
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c
index ff68b9f516a..df33ab89d70 100644
--- a/arch/cris/mm/init.c
+++ b/arch/cris/mm/init.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <asm/tlb.h>
diff --git a/arch/frv/include/asm/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h
index b2898877c07..6af5d83e2fb 100644
--- a/arch/frv/include/asm/dma-mapping.h
+++ b/arch/frv/include/asm/dma-mapping.h
@@ -7,6 +7,11 @@
#include <asm/scatterlist.h>
#include <asm/io.h>
+/*
+ * See Documentation/DMA-API.txt for the description of how the
+ * following DMA API should work.
+ */
+
#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)
@@ -16,24 +21,9 @@ extern unsigned long __nongprelbss dma_coherent_mem_end;
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single is performed.
- */
extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction);
-/*
- * Unmap a single streaming mode DMA translation. The dma_addr and size
- * must match what was provided for in a previous pci_map_single call. All
- * other usages are undefined.
- *
- * After this call, reads by the cpu to the buffer are guarenteed to see
- * whatever the device wrote there.
- */
static inline
void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
@@ -41,30 +31,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
BUG_ON(direction == DMA_NONE);
}
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA. This is the scather-gather version of the
- * above pci_map_single interface. Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length. They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- * DMA address/length pairs than there are SG table elements.
- * (for example via virtual mapping capabilities)
- * The routine returns the number of addr/length pairs actually
- * used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction);
-/*
- * Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
static inline
void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
enum dma_data_direction direction)
diff --git a/arch/frv/include/asm/pci.h b/arch/frv/include/asm/pci.h
index 492b5c4dfed..0d599790985 100644
--- a/arch/frv/include/asm/pci.h
+++ b/arch/frv/include/asm/pci.h
@@ -43,14 +43,6 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
/* Return the index of the PCI controller for device PDEV. */
#define pci_controller_num(PDEV) (0)
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME) (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-
#ifdef CONFIG_PCI
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
enum pci_dma_burst_strategy *strat,
@@ -68,41 +60,4 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
#define PCIBIOS_MIN_IO 0x100
#define PCIBIOS_MIN_MEM 0x00010000
-/* Make physical memory consistent for a single
- * streaming mode DMA translation after a transfer.
- *
- * If you perform a pci_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so. At the
- * next point you give the PCI dma address back to the card, the
- * device again owns the buffer.
- */
-static inline void pci_dma_sync_single(struct pci_dev *hwdev,
- dma_addr_t dma_handle,
- size_t size, int direction)
-{
- BUG_ON(direction == PCI_DMA_NONE);
-
- frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle),
- (unsigned long)bus_to_virt(dma_handle) + size);
-}
-
-/* Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as pci_dma_sync_single but for a scatter-gather list,
- * same rules and usage.
- */
-static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
- struct scatterlist *sg,
- int nelems, int direction)
-{
- int i;
- BUG_ON(direction == PCI_DMA_NONE);
-
- for (i = 0; i < nelems; i++)
- frv_cache_wback_inv(sg_dma_address(&sg[i]),
- sg_dma_address(&sg[i])+sg_dma_len(&sg[i]));
-}
-
#endif /* _ASM_FRV_PCI_H */
diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h
index a54b535c9e4..6bfad4cf190 100644
--- a/arch/frv/include/asm/ptrace.h
+++ b/arch/frv/include/asm/ptrace.h
@@ -84,8 +84,6 @@ extern void show_regs(struct pt_regs *);
#define task_pt_regs(task) ((task)->thread.frame0)
#define arch_has_single_step() (1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/frv/include/asm/segment.h b/arch/frv/include/asm/segment.h
index e3616a6f941..a2320a4a004 100644
--- a/arch/frv/include/asm/segment.h
+++ b/arch/frv/include/asm/segment.h
@@ -21,12 +21,12 @@ typedef struct {
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define KERNEL_DS MAKE_MM_SEG(0xdfffffffUL)
-
#ifdef CONFIG_MMU
#define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
+#define KERNEL_DS MAKE_MM_SEG(0xdfffffffUL)
#else
-#define USER_DS KERNEL_DS
+#define USER_DS MAKE_MM_SEG(memory_end)
+#define KERNEL_DS MAKE_MM_SEG(0xe0000000UL)
#endif
#define get_ds() (KERNEL_DS)
diff --git a/arch/frv/include/asm/uaccess.h b/arch/frv/include/asm/uaccess.h
index 53650c958f4..0b67ec5b441 100644
--- a/arch/frv/include/asm/uaccess.h
+++ b/arch/frv/include/asm/uaccess.h
@@ -27,8 +27,6 @@
#define VERIFY_READ 0
#define VERIFY_WRITE 1
-#define __addr_ok(addr) ((unsigned long)(addr) < get_addr_limit())
-
/*
* check that a range of addresses falls within the current address limit
*/
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h
index be6ef0f5cd4..b28da499e22 100644
--- a/arch/frv/include/asm/unistd.h
+++ b/arch/frv/include/asm/unistd.h
@@ -354,6 +354,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
/* #define __ARCH_WANT_SYS_GETHOSTNAME */
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
/* #define __ARCH_WANT_SYS_SGETMASK */
/* #define __ARCH_WANT_SYS_SIGNAL */
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 62d1aba615d..625136625a7 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -16,7 +16,6 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c
index 1d3d4c9e252..9c4980825bb 100644
--- a/arch/frv/kernel/sys_frv.c
+++ b/arch/frv/kernel/sys_frv.c
@@ -42,92 +42,3 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
return sys_mmap_pgoff(addr, len, prot, flags, fd,
pgoff >> (PAGE_SHIFT - 12));
}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage long sys_ipc(unsigned long call,
- unsigned long first,
- unsigned long second,
- unsigned long third,
- void __user *ptr,
- unsigned long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
- (const struct timespec __user *)fifth);
-
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void * __user *) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
-
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat (first, (char __user *) ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong __user *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- /* The "(ulong *) third" is valid _only_ because of the kernel segment thing */
- return do_shmat (first, (char __user *) ptr, second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char __user *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -ENOSYS;
- }
-}
diff --git a/arch/frv/kernel/sysctl.c b/arch/frv/kernel/sysctl.c
index 035516cb7a9..71abd1510a5 100644
--- a/arch/frv/kernel/sysctl.c
+++ b/arch/frv/kernel/sysctl.c
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 4e1ba0b1544..e47857f889b 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -106,13 +106,6 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_
EXPORT_SYMBOL(dma_free_coherent);
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory
- * until either dma_unmap_single or pci_dma_sync_single is performed.
- */
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
@@ -125,22 +118,6 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
EXPORT_SYMBOL(dma_map_single);
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA. This is the scather-gather version of the
- * above dma_map_single interface. Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length. They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- * DMA address/length pairs than there are SG table elements.
- * (for example via virtual mapping capabilities)
- * The routine returns the number of addr/length pairs actually
- * used, at most nents.
- *
- * Device ownership issues as mentioned above for dma_map_single are
- * the same here.
- */
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction)
{
@@ -157,13 +134,6 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
EXPORT_SYMBOL(dma_map_sg);
-/*
- * Map a single page of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Device ownership issues as mentioned above for dma_map_single are
- * the same here.
- */
dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
size_t size, enum dma_data_direction direction)
{
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 45954f0813d..85d110b71cf 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -10,7 +10,6 @@
*/
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/pci.h>
@@ -38,13 +37,6 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_
EXPORT_SYMBOL(dma_free_coherent);
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single is performed.
- */
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
@@ -57,22 +49,6 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
EXPORT_SYMBOL(dma_map_single);
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA. This is the scather-gather version of the
- * above dma_map_single interface. Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length. They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- * DMA address/length pairs than there are SG table elements.
- * (for example via virtual mapping capabilities)
- * The routine returns the number of addr/length pairs actually
- * used, at most nents.
- *
- * Device ownership issues as mentioned above for dma_map_single are
- * the same here.
- */
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction)
{
@@ -103,13 +79,6 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
EXPORT_SYMBOL(dma_map_sg);
-/*
- * Map a single page of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Device ownership issues as mentioned above for dma_map_single are
- * the same here.
- */
dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
size_t size, enum dma_data_direction direction)
{
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index 1ed15d7fea2..6b4fb28e9f9 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -41,7 +41,7 @@ pcibios_align_resource(void *data, const struct resource *res,
if ((res->flags & IORESOURCE_IO) && (start & 0x300))
start = (start + 0x3ff) & ~0x3ff;
- return start
+ return start;
}
@@ -94,8 +94,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
r = &dev->resource[idx];
if (!r->start)
continue;
- if (pci_claim_resource(dev, idx) < 0)
- printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
+ pci_claim_resource(dev, idx);
}
}
pcibios_allocate_bus_resources(&bus->children);
@@ -125,7 +124,6 @@ static void __init pcibios_allocate_resources(int pass)
DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
r->start, r->end, r->flags, disabled, pass);
if (pci_claim_resource(dev, idx) < 0) {
- printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev));
/* We'll assign a new address later */
r->end -= r->start;
r->start = 0;
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
index ba587523c01..20f6497b2cd 100644
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index c0dcec65c6b..f8dd37e4953 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -16,7 +16,6 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <asm/segment.h>
#include <asm/io.h>
diff --git a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c
index 44840e73e90..7a73aaeae3a 100644
--- a/arch/frv/mm/dma-alloc.c
+++ b/arch/frv/mm/dma-alloc.c
@@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/hardirq.h>
+#include <linux/gfp.h>
#include <asm/pgalloc.h>
#include <asm/io.h>
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c
index 0708284f85f..ed64588ac3a 100644
--- a/arch/frv/mm/init.c
+++ b/arch/frv/mm/init.c
@@ -19,6 +19,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/pagemap.h>
+#include <linux/gfp.h>
#include <linux/swap.h>
#include <linux/mm.h>
#include <linux/kernel.h>
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 66f616fb486..c42c83d507b 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -10,7 +10,7 @@
*/
#include <linux/sched.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/quicklist.h>
diff --git a/arch/h8300/include/asm/io.h b/arch/h8300/include/asm/io.h
index 33e842f3284..c1a8df22080 100644
--- a/arch/h8300/include/asm/io.h
+++ b/arch/h8300/include/asm/io.h
@@ -25,7 +25,7 @@
* memory location directly.
*/
/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
- * two accesses to memory, which may be undesireable for some devices.
+ * two accesses to memory, which may be undesirable for some devices.
*/
/*
diff --git a/arch/h8300/include/asm/ptrace.h b/arch/h8300/include/asm/ptrace.h
index c2e05e4b512..d866c0efba8 100644
--- a/arch/h8300/include/asm/ptrace.h
+++ b/arch/h8300/include/asm/ptrace.h
@@ -55,6 +55,8 @@ struct pt_regs {
/* Find the stack offset for a register, relative to thread.esp0. */
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
+#define arch_has_single_step() (1)
+
#define user_mode(regs) (!((regs)->ccr & PS_S))
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h
index 99f3c3561ec..50f2c5a3659 100644
--- a/arch/h8300/include/asm/unistd.h
+++ b/arch/h8300/include/asm/unistd.h
@@ -336,6 +336,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -348,6 +349,8 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index bd883faa983..8c8b0ffa6ad 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -32,11 +32,11 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index d32bbf02fc4..df114122ebd 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -34,25 +34,20 @@
/* cpu depend functions */
extern long h8300_get_reg(struct task_struct *task, int regno);
extern int h8300_put_reg(struct task_struct *task, int regno, unsigned long data);
-extern void h8300_disable_trace(struct task_struct *child);
-extern void h8300_enable_trace(struct task_struct *child);
+
+
+void user_disable_single_step(struct task_struct *child)
+{
+}
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
-inline
-static int read_long(struct task_struct * tsk, unsigned long addr,
- unsigned long * result)
-{
- *result = *(unsigned long *)addr;
- return 0;
-}
-
void ptrace_disable(struct task_struct *child)
{
- h8300_disable_trace(child);
+ user_disable_single_step(child);
}
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -60,17 +55,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
int ret;
switch (request) {
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA: {
- unsigned long tmp;
-
- ret = read_long(child, addr, &tmp);
- if (ret < 0)
- break ;
- ret = put_user(tmp, (unsigned long *) data);
- break ;
- }
-
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp = 0;
@@ -109,11 +93,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
/* when I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = generic_ptrace_pokedata(child, addr, data);
- break;
-
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
ret = -EIO;
@@ -131,53 +110,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
ret = -EIO;
break ;
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: { /* restart after signal. */
- ret = -EIO;
- if (!valid_signal(data))
- break ;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- wake_up_process(child);
- /* make sure the single step bit is not set. */
- h8300_disable_trace(child);
- ret = 0;
- }
-
-/*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL: {
-
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- h8300_disable_trace(child);
- wake_up_process(child);
- break;
- }
-
- case PTRACE_SINGLESTEP: { /* set the trap flag. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- h8300_enable_trace(child);
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
int i;
@@ -210,7 +142,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
default:
- ret = -EIO;
+ ret = ptrace_request(child, request, addr, data);
break;
}
return ret;
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index b5969db0ca1..f9b3f44da69 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -26,144 +26,6 @@
#include <asm/traps.h>
#include <asm/unistd.h>
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
- * handle more than 4 system call parameters, so these system calls
- * used a memory block for parameter passing..
- */
-
-struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct *arg)
-{
- struct mmap_arg_struct a;
- int error = -EFAULT;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
-
- error = -EINVAL;
- if (a.offset & ~PAGE_MASK)
- goto out;
-
- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
- a.offset >> PAGE_SHIFT);
-out:
- return error;
-}
-
-struct sel_arg_struct {
- unsigned long n;
- fd_set *inp, *outp, *exp;
- struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct *arg)
-{
- struct sel_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
- /* sys_select() does the appropriate kernel locking */
- return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc (uint call, int first, int second,
- int third, void *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- return sys_semop (first, (struct sembuf *)ptr, second);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void **) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
- default:
- return -EINVAL;
- }
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
- if (copy_from_user (&tmp,
- (struct ipc_kludge *)ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second,
- (struct msqid_ds *) ptr);
- default:
- return -EINVAL;
- }
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat (first, (char *) ptr,
- second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong *) third);
- }
- }
- case SHMDT:
- return sys_shmdt ((char *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds *) ptr);
- default:
- return -EINVAL;
- }
-
- return -EINVAL;
-}
-
/* sys_cacheflush -- no support. */
asmlinkage int
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
index 2d69881eda6..faefaff7d43 100644
--- a/arch/h8300/kernel/syscalls.S
+++ b/arch/h8300/kernel/syscalls.S
@@ -96,7 +96,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_settimeofday)
.long SYMBOL_NAME(sys_getgroups16) /* 80 */
.long SYMBOL_NAME(sys_setgroups16)
- .long SYMBOL_NAME(old_select)
+ .long SYMBOL_NAME(sys_old_select)
.long SYMBOL_NAME(sys_symlink)
.long SYMBOL_NAME(sys_lstat)
.long SYMBOL_NAME(sys_readlink) /* 85 */
@@ -104,7 +104,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_swapon)
.long SYMBOL_NAME(sys_reboot)
.long SYMBOL_NAME(sys_old_readdir)
- .long SYMBOL_NAME(old_mmap) /* 90 */
+ .long SYMBOL_NAME(sys_old_mmap) /* 90 */
.long SYMBOL_NAME(sys_munmap)
.long SYMBOL_NAME(sys_truncate)
.long SYMBOL_NAME(sys_ftruncate)
diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c
index 9942f24aff9..7cc3380f250 100644
--- a/arch/h8300/mm/init.c
+++ b/arch/h8300/mm/init.c
@@ -30,7 +30,7 @@
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/bootmem.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <asm/setup.h>
#include <asm/segment.h>
diff --git a/arch/h8300/mm/kmap.c b/arch/h8300/mm/kmap.c
index 5c7af09ae8d..944a502c2e5 100644
--- a/arch/h8300/mm/kmap.c
+++ b/arch/h8300/mm/kmap.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/setup.h>
diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c
index 40d8aa811e4..5552ddfaab5 100644
--- a/arch/h8300/mm/memory.c
+++ b/arch/h8300/mm/memory.c
@@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <asm/setup.h>
#include <asm/segment.h>
diff --git a/arch/h8300/platform/h8300h/ptrace_h8300h.c b/arch/h8300/platform/h8300h/ptrace_h8300h.c
index 746b1ae672a..4f1ed027963 100644
--- a/arch/h8300/platform/h8300h/ptrace_h8300h.c
+++ b/arch/h8300/platform/h8300h/ptrace_h8300h.c
@@ -60,7 +60,7 @@ int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
}
/* disable singlestep */
-void h8300_disable_trace(struct task_struct *child)
+void user_disable_single_step(struct task_struct *child)
{
if((long)child->thread.breakinfo.addr != -1L) {
*child->thread.breakinfo.addr = child->thread.breakinfo.inst;
@@ -264,7 +264,7 @@ static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc)
/* Set breakpoint(s) to simulate a single step from the current PC. */
-void h8300_enable_trace(struct task_struct *child)
+void user_enable_single_step(struct task_struct *child)
{
unsigned short *nextpc;
nextpc = getnextpc(child,(unsigned short *)h8300_get_reg(child, PT_PC));
@@ -276,7 +276,7 @@ void h8300_enable_trace(struct task_struct *child)
asmlinkage void trace_trap(unsigned long bp)
{
if ((unsigned long)current->thread.breakinfo.addr == bp) {
- h8300_disable_trace(current);
+ user_disable_single_step(current);
force_sig(SIGTRAP,current);
} else
force_sig(SIGILL,current);
diff --git a/arch/h8300/platform/h8s/ptrace_h8s.c b/arch/h8300/platform/h8s/ptrace_h8s.c
index e8cd46f9255..c058ab1a849 100644
--- a/arch/h8300/platform/h8s/ptrace_h8s.c
+++ b/arch/h8300/platform/h8s/ptrace_h8s.c
@@ -65,13 +65,13 @@ int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
}
/* disable singlestep */
-void h8300_disable_trace(struct task_struct *child)
+void user_disable_single_step(struct task_struct *child)
{
*(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE;
}
/* enable singlestep */
-void h8300_enable_trace(struct task_struct *child)
+void user_enable_single_step(struct task_struct *child)
{
*(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE;
}
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 9a50d7dd2a0..4d4f4188cdf 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -53,6 +53,9 @@ config MMU
bool
default y
+config NEED_DMA_MAP_STATE
+ def_bool y
+
config SWIOTLB
bool
diff --git a/arch/ia64/include/asm/compat.h b/arch/ia64/include/asm/compat.h
index dfcf75b8426..f90edc85b50 100644
--- a/arch/ia64/include/asm/compat.h
+++ b/arch/ia64/include/asm/compat.h
@@ -5,7 +5,8 @@
*/
#include <linux/types.h>
-#define COMPAT_USER_HZ 100
+#define COMPAT_USER_HZ 100
+#define COMPAT_UTS_MACHINE "i686\0\0\0"
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
diff --git a/arch/ia64/include/asm/dmi.h b/arch/ia64/include/asm/dmi.h
index 00eb1b130b6..1ed4c8fedb8 100644
--- a/arch/ia64/include/asm/dmi.h
+++ b/arch/ia64/include/asm/dmi.h
@@ -1,6 +1,7 @@
#ifndef _ASM_DMI_H
#define _ASM_DMI_H 1
+#include <linux/slab.h>
#include <asm/io.h>
/* Use normal IO mappings for DMI */
diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index 4c41656ede8..b5298eb09ad 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -219,54 +219,6 @@ do { \
NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \
} while (0)
-
-/*
- * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
- * extra segments containing the gate DSO contents. Dumping its
- * contents makes post-mortem fully interpretable later without matching up
- * the same kernel and hardware config to see what PC values meant.
- * Dumping its extra ELF program headers includes all the other information
- * a debugger needs to easily find how the gate DSO was being used.
- */
-#define ELF_CORE_EXTRA_PHDRS (GATE_EHDR->e_phnum)
-#define ELF_CORE_WRITE_EXTRA_PHDRS \
-do { \
- const struct elf_phdr *const gate_phdrs = \
- (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \
- int i; \
- Elf64_Off ofs = 0; \
- for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \
- struct elf_phdr phdr = gate_phdrs[i]; \
- if (phdr.p_type == PT_LOAD) { \
- phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \
- phdr.p_filesz = phdr.p_memsz; \
- if (ofs == 0) { \
- ofs = phdr.p_offset = offset; \
- offset += phdr.p_filesz; \
- } \
- else \
- phdr.p_offset = ofs; \
- } \
- else \
- phdr.p_offset += ofs; \
- phdr.p_paddr = 0; /* match other core phdrs */ \
- DUMP_WRITE(&phdr, sizeof(phdr)); \
- } \
-} while (0)
-#define ELF_CORE_WRITE_EXTRA_DATA \
-do { \
- const struct elf_phdr *const gate_phdrs = \
- (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \
- int i; \
- for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \
- if (gate_phdrs[i].p_type == PT_LOAD) { \
- DUMP_WRITE((void *) gate_phdrs[i].p_vaddr, \
- PAGE_ALIGN(gate_phdrs[i].p_memsz)); \
- break; \
- } \
- } \
-} while (0)
-
/*
* format for entries in the Global Offset Table
*/
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 55281aabe5f..73b5f785e70 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -56,20 +56,6 @@ pcibios_penalize_isa_irq (int irq, int active)
#include <asm-generic/pci-dma-compat.h>
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
#ifdef CONFIG_PCI
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
enum pci_dma_burst_strategy *strat,
diff --git a/arch/ia64/include/asm/ptrace.h b/arch/ia64/include/asm/ptrace.h
index 14055c636ad..7ae9c3f15a1 100644
--- a/arch/ia64/include/asm/ptrace.h
+++ b/arch/ia64/include/asm/ptrace.h
@@ -319,11 +319,7 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
ptrace_attach_sync_user_rbs(child)
#define arch_has_single_step() (1)
- extern void user_enable_single_step(struct task_struct *);
- extern void user_disable_single_step(struct task_struct *);
-
#define arch_has_block_step() (1)
- extern void user_enable_block_step(struct task_struct *);
#endif /* !__KERNEL__ */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 4138282aefa..db10b1e378b 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -45,6 +45,8 @@ endif
obj-$(CONFIG_DMAR) += pci-dma.o
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
+obj-$(CONFIG_BINFMT_ELF) += elfcore.o
+
# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c
index b7515bc808a..8b9318d311a 100644
--- a/arch/ia64/kernel/acpi-ext.c
+++ b/arch/ia64/kernel/acpi-ext.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/acpi.h>
#include <asm/acpi-ext.h>
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index a7ca07f3754..4d1a7e9314c 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -44,6 +44,8 @@
#include <linux/efi.h>
#include <linux/mmzone.h>
#include <linux/nodemask.h>
+#include <linux/slab.h>
+#include <acpi/processor.h>
#include <asm/io.h>
#include <asm/iosapic.h>
#include <asm/machvec.h>
@@ -907,6 +909,8 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu)
cpu_set(cpu, cpu_present_map);
ia64_cpu_to_sapicid[cpu] = physid;
+ acpi_processor_set_pdc(handle);
+
*pcpu = cpu;
return (0);
}
diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
index 7b435451b3d..b0b4e6e710f 100644
--- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
+++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index c745d0aeb6e..a0f00192850 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/time.h>
#include <linux/efi.h>
#include <linux/kexec.h>
diff --git a/arch/ia64/kernel/elfcore.c b/arch/ia64/kernel/elfcore.c
new file mode 100644
index 00000000000..bac1639bc32
--- /dev/null
+++ b/arch/ia64/kernel/elfcore.c
@@ -0,0 +1,80 @@
+#include <linux/elf.h>
+#include <linux/coredump.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf64_Half elf_core_extra_phdrs(void)
+{
+ return GATE_EHDR->e_phnum;
+}
+
+int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+ unsigned long limit)
+{
+ const struct elf_phdr *const gate_phdrs =
+ (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+ int i;
+ Elf64_Off ofs = 0;
+
+ for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+ struct elf_phdr phdr = gate_phdrs[i];
+
+ if (phdr.p_type == PT_LOAD) {
+ phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);
+ phdr.p_filesz = phdr.p_memsz;
+ if (ofs == 0) {
+ ofs = phdr.p_offset = offset;
+ offset += phdr.p_filesz;
+ } else {
+ phdr.p_offset = ofs;
+ }
+ } else {
+ phdr.p_offset += ofs;
+ }
+ phdr.p_paddr = 0; /* match other core phdrs */
+ *size += sizeof(phdr);
+ if (*size > limit || !dump_write(file, &phdr, sizeof(phdr)))
+ return 0;
+ }
+ return 1;
+}
+
+int elf_core_write_extra_data(struct file *file, size_t *size,
+ unsigned long limit)
+{
+ const struct elf_phdr *const gate_phdrs =
+ (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+ int i;
+
+ for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+ if (gate_phdrs[i].p_type == PT_LOAD) {
+ void *addr = (void *)gate_phdrs[i].p_vaddr;
+ size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz);
+
+ *size += memsz;
+ if (*size > limit || !dump_write(file, addr, memsz))
+ return 0;
+ break;
+ }
+ }
+ return 1;
+}
+
+size_t elf_core_extra_data_size(void)
+{
+ const struct elf_phdr *const gate_phdrs =
+ (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+ int i;
+ size_t size = 0;
+
+ for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+ if (gate_phdrs[i].p_type == PT_LOAD) {
+ size += PAGE_ALIGN(gate_phdrs[i].p_memsz);
+ break;
+ }
+ }
+ return size;
+}
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 95ac77aeae9..7ded76658d2 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -86,6 +86,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/bootmem.h>
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index d4093a173a3..640479304ac 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -22,7 +22,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/kernel_stat.h>
-#include <linux/slab.h>
#include <linux/ptrace.h>
#include <linux/random.h> /* for rand_initialize_irq() */
#include <linux/signal.h>
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 378b4833024..a0220dc5ff4 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -85,6 +85,7 @@
#include <linux/cpumask.h>
#include <linux/kdebug.h>
#include <linux/cpu.h>
+#include <linux/gfp.h>
#include <asm/delay.h>
#include <asm/machvec.h>
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index f94aaa86933..09b4d6828c4 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -22,6 +22,7 @@
#include <linux/smp.h>
#include <linux/workqueue.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <asm/delay.h>
#include <asm/machvec.h>
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index 53292abf846..3095654f9ab 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -1,6 +1,7 @@
/* Glue code to lib/swiotlb.c */
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <linux/cache.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index b81e46b1629..ab985f785c1 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -41,6 +41,7 @@
#include <linux/rcupdate.h>
#include <linux/completion.h>
#include <linux/tracehook.h>
+#include <linux/slab.h>
#include <asm/errno.h>
#include <asm/intrinsics.h>
@@ -2315,6 +2316,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
DPRINT(("Cannot allocate vma\n"));
goto error_kmem;
}
+ INIT_LIST_HEAD(&vma->anon_vma_chain);
/*
* partially initialize the vma for the sampling buffer
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index d92765cae10..53f1648c8b8 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -15,11 +15,11 @@
#include <linux/kallsyms.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/personality.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/thread_info.h>
#include <linux/unistd.h>
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index b61afbbe076..0dec7f70244 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -11,7 +11,6 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 8f060352e12..28f299de290 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/node.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/nodemask.h>
@@ -282,7 +283,7 @@ static ssize_t cache_show(struct kobject * kobj, struct attribute * attr, char *
return ret;
}
-static struct sysfs_ops cache_sysfs_ops = {
+static const struct sysfs_ops cache_sysfs_ops = {
.show = cache_show
};
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index a595823582d..c4696d217ce 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -18,9 +18,9 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/efi.h>
#include <linux/genalloc.h>
+#include <linux/gfp.h>
#include <asm/page.h>
#include <asm/pal.h>
#include <asm/system.h>
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 01c75797119..fa4d1e59deb 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -26,6 +26,7 @@ config KVM
select ANON_INODES
select HAVE_KVM_IRQCHIP
select KVM_APIC_ARCHITECTURE
+ select KVM_MMIO
---help---
Support hosting fully virtualized guest machines using hardware
virtualization extensions. You will need a fairly recent
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 5fdeec5fddc..7f3c0a2e60c 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -23,8 +23,8 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/percpu.h>
-#include <linux/gfp.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/kvm_host.h>
#include <linux/kvm.h>
@@ -241,10 +241,10 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 0;
mmio:
if (p->dir)
- r = kvm_io_bus_read(&vcpu->kvm->mmio_bus, p->addr,
+ r = kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, p->addr,
p->size, &p->data);
else
- r = kvm_io_bus_write(&vcpu->kvm->mmio_bus, p->addr,
+ r = kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, p->addr,
p->size, &p->data);
if (r)
printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr);
@@ -636,12 +636,9 @@ static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu)
static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
union context *host_ctx, *guest_ctx;
- int r;
+ int r, idx;
- /*
- * down_read() may sleep and return with interrupts enabled
- */
- down_read(&vcpu->kvm->slots_lock);
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
again:
if (signal_pending(current)) {
@@ -663,7 +660,7 @@ again:
if (r < 0)
goto vcpu_run_fail;
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
kvm_guest_enter();
/*
@@ -687,7 +684,7 @@ again:
kvm_guest_exit();
preempt_enable();
- down_read(&vcpu->kvm->slots_lock);
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
r = kvm_handle_exit(kvm_run, vcpu);
@@ -697,10 +694,10 @@ again:
}
out:
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
if (r > 0) {
kvm_resched(vcpu);
- down_read(&vcpu->kvm->slots_lock);
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
goto again;
}
@@ -971,7 +968,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
goto out;
r = kvm_setup_default_irq_routing(kvm);
if (r) {
- kfree(kvm->arch.vioapic);
+ kvm_ioapic_destroy(kvm);
goto out;
}
break;
@@ -1377,12 +1374,14 @@ static void free_kvm(struct kvm *kvm)
static void kvm_release_vm_pages(struct kvm *kvm)
{
+ struct kvm_memslots *slots;
struct kvm_memory_slot *memslot;
int i, j;
unsigned long base_gfn;
- for (i = 0; i < kvm->nmemslots; i++) {
- memslot = &kvm->memslots[i];
+ slots = rcu_dereference(kvm->memslots);
+ for (i = 0; i < slots->nmemslots; i++) {
+ memslot = &slots->memslots[i];
base_gfn = memslot->base_gfn;
for (j = 0; j < memslot->npages; j++) {
@@ -1405,6 +1404,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
kfree(kvm->arch.vioapic);
kvm_release_vm_pages(kvm);
kvm_free_physmem(kvm);
+ cleanup_srcu_struct(&kvm->srcu);
free_kvm(kvm);
}
@@ -1576,15 +1576,15 @@ out:
return r;
}
-int kvm_arch_set_memory_region(struct kvm *kvm,
- struct kvm_userspace_memory_region *mem,
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
struct kvm_memory_slot old,
+ struct kvm_userspace_memory_region *mem,
int user_alloc)
{
unsigned long i;
unsigned long pfn;
- int npages = mem->memory_size >> PAGE_SHIFT;
- struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot];
+ int npages = memslot->npages;
unsigned long base_gfn = memslot->base_gfn;
if (base_gfn + npages > (KVM_MAX_MEM_SIZE >> PAGE_SHIFT))
@@ -1608,6 +1608,14 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
return 0;
}
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+ struct kvm_userspace_memory_region *mem,
+ struct kvm_memory_slot old,
+ int user_alloc)
+{
+ return;
+}
+
void kvm_arch_flush_shadow(struct kvm *kvm)
{
kvm_flush_remote_tlbs(kvm);
@@ -1794,7 +1802,8 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
{
struct kvm_memory_slot *memslot;
int r, i;
- long n, base;
+ long base;
+ unsigned long n;
unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base +
offsetof(struct kvm_vm_data, kvm_mem_dirty_log));
@@ -1802,12 +1811,12 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
if (log->slot >= KVM_MEMORY_SLOTS)
goto out;
- memslot = &kvm->memslots[log->slot];
+ memslot = &kvm->memslots->memslots[log->slot];
r = -ENOENT;
if (!memslot->dirty_bitmap)
goto out;
- n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+ n = kvm_dirty_bitmap_bytes(memslot);
base = memslot->base_gfn / BITS_PER_LONG;
for (i = 0; i < n/sizeof(long); ++i) {
@@ -1823,10 +1832,11 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
struct kvm_dirty_log *log)
{
int r;
- int n;
+ unsigned long n;
struct kvm_memory_slot *memslot;
int is_dirty = 0;
+ mutex_lock(&kvm->slots_lock);
spin_lock(&kvm->arch.dirty_log_lock);
r = kvm_ia64_sync_dirty_log(kvm, log);
@@ -1840,12 +1850,13 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
/* If nothing is dirty, don't bother messing with page tables. */
if (is_dirty) {
kvm_flush_remote_tlbs(kvm);
- memslot = &kvm->memslots[log->slot];
- n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+ memslot = &kvm->memslots->memslots[log->slot];
+ n = kvm_dirty_bitmap_bytes(memslot);
memset(memslot->dirty_bitmap, 0, n);
}
r = 0;
out:
+ mutex_unlock(&kvm->slots_lock);
spin_unlock(&kvm->arch.dirty_log_lock);
return r;
}
diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c
index e4b82319881..cb548ee9fca 100644
--- a/arch/ia64/kvm/kvm_fw.c
+++ b/arch/ia64/kvm/kvm_fw.c
@@ -75,7 +75,7 @@ static void set_pal_result(struct kvm_vcpu *vcpu,
struct exit_ctl_data *p;
p = kvm_get_exit_data(vcpu);
- if (p && p->exit_reason == EXIT_REASON_PAL_CALL) {
+ if (p->exit_reason == EXIT_REASON_PAL_CALL) {
p->u.pal_data.ret = result;
return ;
}
@@ -87,7 +87,7 @@ static void set_sal_result(struct kvm_vcpu *vcpu,
struct exit_ctl_data *p;
p = kvm_get_exit_data(vcpu);
- if (p && p->exit_reason == EXIT_REASON_SAL_CALL) {
+ if (p->exit_reason == EXIT_REASON_SAL_CALL) {
p->u.sal_data.ret = result;
return ;
}
@@ -322,7 +322,7 @@ static u64 kvm_get_pal_call_index(struct kvm_vcpu *vcpu)
struct exit_ctl_data *p;
p = kvm_get_exit_data(vcpu);
- if (p && (p->exit_reason == EXIT_REASON_PAL_CALL))
+ if (p->exit_reason == EXIT_REASON_PAL_CALL)
index = p->u.pal_data.gr28;
return index;
@@ -646,18 +646,16 @@ static void kvm_get_sal_call_data(struct kvm_vcpu *vcpu, u64 *in0, u64 *in1,
p = kvm_get_exit_data(vcpu);
- if (p) {
- if (p->exit_reason == EXIT_REASON_SAL_CALL) {
- *in0 = p->u.sal_data.in0;
- *in1 = p->u.sal_data.in1;
- *in2 = p->u.sal_data.in2;
- *in3 = p->u.sal_data.in3;
- *in4 = p->u.sal_data.in4;
- *in5 = p->u.sal_data.in5;
- *in6 = p->u.sal_data.in6;
- *in7 = p->u.sal_data.in7;
- return ;
- }
+ if (p->exit_reason == EXIT_REASON_SAL_CALL) {
+ *in0 = p->u.sal_data.in0;
+ *in1 = p->u.sal_data.in1;
+ *in2 = p->u.sal_data.in2;
+ *in3 = p->u.sal_data.in3;
+ *in4 = p->u.sal_data.in4;
+ *in5 = p->u.sal_data.in5;
+ *in6 = p->u.sal_data.in6;
+ *in7 = p->u.sal_data.in7;
+ return ;
}
*in0 = 0;
}
diff --git a/arch/ia64/kvm/mmio.c b/arch/ia64/kvm/mmio.c
index 9bf55afd08d..fb8f9f59a1e 100644
--- a/arch/ia64/kvm/mmio.c
+++ b/arch/ia64/kvm/mmio.c
@@ -316,8 +316,8 @@ void emulate_io_inst(struct kvm_vcpu *vcpu, u64 padr, u64 ma)
return;
} else {
inst_type = -1;
- panic_vm(vcpu, "Unsupported MMIO access instruction! \
- Bunld[0]=0x%lx, Bundle[1]=0x%lx\n",
+ panic_vm(vcpu, "Unsupported MMIO access instruction! "
+ "Bunld[0]=0x%lx, Bundle[1]=0x%lx\n",
bundle.i64[0], bundle.i64[1]);
}
diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c
index dce75b70cdd..958815c9787 100644
--- a/arch/ia64/kvm/vcpu.c
+++ b/arch/ia64/kvm/vcpu.c
@@ -1639,8 +1639,8 @@ void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val)
* Otherwise panic
*/
if (val & (IA64_PSR_PK | IA64_PSR_IS | IA64_PSR_VM))
- panic_vm(vcpu, "Only support guests with vpsr.pk =0 \
- & vpsr.is=0\n");
+ panic_vm(vcpu, "Only support guests with vpsr.pk =0 "
+ "& vpsr.is=0\n");
/*
* For those IA64_PSR bits: id/da/dd/ss/ed/ia
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 8d586d1e251..61620323bb6 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -22,6 +22,7 @@
#include <linux/acpi.h>
#include <linux/efi.h>
#include <linux/nodemask.h>
+#include <linux/slab.h>
#include <asm/pgalloc.h>
#include <asm/tlb.h>
#include <asm/meminit.h>
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index b0f615759e9..1841ee7e65f 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -14,7 +14,6 @@
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/log2.h>
#include <asm/mman.h>
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index ca3335ea56c..ed41759efca 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -117,6 +117,7 @@ ia64_init_addr_space (void)
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (vma) {
+ INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_mm = current->mm;
vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
vma->vm_end = vma->vm_start + PAGE_SIZE;
@@ -135,6 +136,7 @@ ia64_init_addr_space (void)
if (!(current->personality & MMAP_PAGE_ZERO)) {
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (vma) {
+ INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_mm = current->mm;
vma->vm_end = PAGE_SIZE;
vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index f3de9d7a98b..5dfd916e9ea 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -22,6 +22,7 @@
#include <linux/smp.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/slab.h>
#include <asm/delay.h>
#include <asm/mmu_context.h>
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index c6d6b62db66..cad775a1a15 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -19,6 +19,7 @@
#include <linux/bootmem.h>
#include <linux/string.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/sn/bte.h>
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c
index 66f633bff05..8cdcb173a13 100644
--- a/arch/ia64/sn/kernel/io_acpi_init.c
+++ b/arch/ia64/sn/kernel/io_acpi_init.c
@@ -13,6 +13,7 @@
#include <asm/sn/sn_sal.h>
#include "xtalk/hubdev.h"
#include <linux/acpi.h>
+#include <linux/slab.h>
/*
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index 308e6595110..4433dd019d3 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -7,6 +7,7 @@
*/
#include <linux/bootmem.h>
+#include <linux/slab.h>
#include <asm/sn/types.h>
#include <asm/sn/addrs.h>
#include <asm/sn/sn_feature_sets.h>
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index ee774c366a0..98079f29d9a 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -6,6 +6,7 @@
* Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved.
*/
+#include <linux/slab.h>
#include <asm/sn/types.h>
#include <asm/sn/addrs.h>
#include <asm/sn/io.h>
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 40d6eeda1c4..13c15d96809 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -12,6 +12,7 @@
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/rculist.h>
+#include <linux/slab.h>
#include <asm/sn/addrs.h>
#include <asm/sn/arch.h>
#include <asm/sn/intr.h>
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index fbbfb970120..ebfdd6a9ae1 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -11,6 +11,7 @@
#include <linux/pci.h>
#include <linux/cpumask.h>
#include <linux/msi.h>
+#include <linux/slab.h>
#include <asm/sn/addrs.h>
#include <asm/sn/intr.h>
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index e456f062f24..d00dfc18002 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -241,7 +241,7 @@ static void __cpuinit sn_check_for_wars(void)
* Note: This stuff is duped here because Altix requires the PCDP to
* locate a usable VGA device due to lack of proper ACPI support. Structures
* could be used from drivers/firmware/pcdp.h, but it was decided that moving
- * this file to a more public location just for Altix use was undesireable.
+ * this file to a more public location just for Altix use was undesirable.
*/
struct hcdp_uart_desc {
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 98b684928e1..a9d310de57d 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -9,6 +9,7 @@
* a description of how these routines should be used.
*/
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <asm/dma.h>
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index d13e5a22a55..3cb5cf37764 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -8,6 +8,7 @@
#include <linux/interrupt.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <asm/sn/addrs.h>
#include <asm/sn/geo.h>
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index efb454534e5..4d4536e3b6f 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/bitmap.h>
+#include <linux/slab.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
#include <asm/sn/io.h>
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c
index 012f3b82ee5..27faba035f3 100644
--- a/arch/ia64/sn/pci/tioce_provider.c
+++ b/arch/ia64/sn/pci/tioce_provider.c
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
diff --git a/arch/ia64/xen/grant-table.c b/arch/ia64/xen/grant-table.c
index 777dd9a9108..48cca37625e 100644
--- a/arch/ia64/xen/grant-table.c
+++ b/arch/ia64/xen/grant-table.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <xen/interface/xen.h>
diff --git a/arch/m32r/include/asm/ptrace.h b/arch/m32r/include/asm/ptrace.h
index a0755b98202..840a1231ede 100644
--- a/arch/m32r/include/asm/ptrace.h
+++ b/arch/m32r/include/asm/ptrace.h
@@ -120,6 +120,8 @@ struct pt_regs {
#include <asm/m32r.h> /* M32R_PSW_BSM, M32R_PSW_BPM */
+#define arch_has_single_step() (1)
+
struct task_struct;
extern void init_debug_traps(struct task_struct *);
#define arch_ptrace_attach(child) \
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h
index cf701c93324..76125777483 100644
--- a/arch/m32r/include/asm/unistd.h
+++ b/arch/m32r/include/asm/unistd.h
@@ -339,6 +339,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_TIME
#define __ARCH_WANT_SYS_UTIME
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index 67a01e1e428..bc8c8c1511b 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -21,10 +21,10 @@
*/
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/hardirq.h>
#include <asm/io.h>
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 98682bba0ed..e555091eb97 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -580,6 +580,35 @@ init_debug_traps(struct task_struct *child)
}
}
+void user_enable_single_step(struct task_struct *child)
+{
+ unsigned long next_pc;
+ unsigned long pc, insn;
+
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+ /* Compute next pc. */
+ pc = get_stack_long(child, PT_BPC);
+
+ if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
+ != sizeof(insn))
+ break;
+
+ compute_next_pc(insn, pc, &next_pc, child);
+ if (next_pc & 0x80000000)
+ break;
+
+ if (embed_debug_trap(child, next_pc))
+ break;
+
+ invalidate_cache();
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+ unregister_all_debug_traps(child);
+ invalidate_cache();
+}
/*
* Called by kernel/ptrace.c when detaching..
@@ -630,74 +659,6 @@ arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_write_user(child, addr, data);
break;
- /*
- * continue/restart and stop at next (return from) syscall
- */
- case PTRACE_SYSCALL:
- case PTRACE_CONT:
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
- break;
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL: {
- ret = 0;
- unregister_all_debug_traps(child);
- invalidate_cache();
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- wake_up_process(child);
- break;
- }
-
- /*
- * execute single instruction.
- */
- case PTRACE_SINGLESTEP: {
- unsigned long next_pc;
- unsigned long pc, insn;
-
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
- /* Compute next pc. */
- pc = get_stack_long(child, PT_BPC);
-
- if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
- != sizeof(insn))
- break;
-
- compute_next_pc(insn, pc, &next_pc, child);
- if (next_pc & 0x80000000)
- break;
-
- if (embed_debug_trap(child, next_pc))
- break;
-
- invalidate_cache();
- child->exit_code = data;
-
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- break;
- }
-
case PTRACE_GETREGS:
ret = ptrace_getregs(child, (void __user *)data);
break;
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index d3c865c5a6b..0a00f467edf 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -76,98 +76,6 @@ asmlinkage int sys_tas(int __user *addr)
return oldval;
}
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc(uint call, int first, int second,
- int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr,
- second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr,
- second, (const struct timespec __user *)fifth);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void __user * __user *) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second,
- (struct msqid_ds __user *) ptr);
- case SHMAT: {
- ulong raddr;
-
- if (!access_ok(VERIFY_WRITE, (ulong __user *) third,
- sizeof(ulong)))
- return -EFAULT;
- ret = do_shmat (first, (char __user *) ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong __user *) third);
- }
- case SHMDT:
- return sys_shmdt ((char __user *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -ENOSYS;
- }
-}
-
-asmlinkage int sys_uname(struct old_utsname __user * name)
-{
- int err;
- if (!name)
- return -EFAULT;
- down_read(&uts_sem);
- err = copy_to_user(name, utsname(), sizeof (*name));
- up_read(&uts_sem);
- return err?-EFAULT:0;
-}
-
asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
{
/* This should flush more selectively ... */
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index 9f581df3952..73e2205ebf5 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -19,6 +19,7 @@
#include <linux/bitops.h>
#include <linux/nodemask.h>
#include <linux/pfn.h>
+#include <linux/gfp.h>
#include <asm/types.h>
#include <asm/processor.h>
#include <asm/page.h>
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index 4add96d13b1..5890897d28b 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -121,7 +121,7 @@ KEYBOARD_STATE kb_state;
* bytes have been lost and in which state of the packet structure we are now.
* This usually causes keyboards bytes to be interpreted as mouse movements
* and vice versa, which is very annoying. It seems better to throw away some
- * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I
+ * bytes (that are usually mouse bytes) than to misinterpret them. Therefore I
* introduced the RESYNC state for IKBD data. In this state, the bytes up to
* one that really looks like a key event (0x04..0xf2) or the start of a mouse
* packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least
diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
index c50bec8aabb..b46ea1714a8 100644
--- a/arch/m68k/bvme6000/rtc.c
+++ b/arch/m68k/bvme6000/rtc.c
@@ -9,7 +9,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
-#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/capability.h>
diff --git a/arch/m68k/include/asm/atomic_mm.h b/arch/m68k/include/asm/atomic_mm.h
index 88b7af20a99..d9d2ed64743 100644
--- a/arch/m68k/include/asm/atomic_mm.h
+++ b/arch/m68k/include/asm/atomic_mm.h
@@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *v, int new)
static inline int atomic_sub_and_test(int i, atomic_t *v)
{
char c;
- __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i));
+ __asm__ __volatile__("subl %2,%1; seq %0"
+ : "=d" (c), "+m" (*v)
+ : "id" (i));
return c != 0;
}
static inline int atomic_add_negative(int i, atomic_t *v)
{
char c;
- __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
+ __asm__ __volatile__("addl %2,%1; smi %0"
+ : "=d" (c), "+m" (*v)
+ : "id" (i));
return c != 0;
}
diff --git a/arch/m68k/include/asm/fbio.h b/arch/m68k/include/asm/fbio.h
index b9215a0907d..0a21da87f7d 100644
--- a/arch/m68k/include/asm/fbio.h
+++ b/arch/m68k/include/asm/fbio.h
@@ -173,7 +173,7 @@ struct mdi_cfginfo {
int mdi_ncluts; /* Number of implemented CLUTs in this MDI */
int mdi_type; /* FBTYPE name */
int mdi_height; /* height */
- int mdi_width; /* widht */
+ int mdi_width; /* width */
int mdi_size; /* available ram */
int mdi_mode; /* 8bpp, 16bpp or 32bpp */
int mdi_pixfreq; /* pixel clock (from PROM) */
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index 359065d5a9f..6e2413e518c 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -16,7 +16,7 @@
* memory location directly.
*/
/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
- * two accesses to memory, which may be undesireable for some devices.
+ * two accesses to memory, which may be undesirable for some devices.
*/
/*
diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h
index ef229387361..01a8716c5fc 100644
--- a/arch/m68k/include/asm/mcfuart.h
+++ b/arch/m68k/include/asm/mcfuart.h
@@ -212,5 +212,10 @@ struct mcf_platform_uart {
#define MCFUART_URF_RXS 0xc0 /* Receiver status */
#endif
+#if defined(CONFIG_M5272)
+#define MCFUART_TXFIFOSIZE 25
+#else
+#define MCFUART_TXFIFOSIZE 1
+#endif
/****************************************************************************/
#endif /* mcfuart_h */
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
index 21605c736f6..6e6e3ac1d91 100644
--- a/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -87,18 +87,10 @@ struct switch_stack {
#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
-/*
- * These are defined as per linux/ptrace.h.
- */
-struct task_struct;
-
#define arch_has_single_step() (1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
#ifdef CONFIG_MMU
#define arch_has_block_step() (1)
-extern void user_enable_block_step(struct task_struct *);
#endif
#endif /* __KERNEL__ */
diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h
index 1320eaa4cc2..a29dd74a17c 100644
--- a/arch/m68k/include/asm/sigcontext.h
+++ b/arch/m68k/include/asm/sigcontext.h
@@ -17,13 +17,11 @@ struct sigcontext {
#ifndef __uClinux__
# ifdef __mcoldfire__
unsigned long sc_fpregs[2][2]; /* room for two fp registers */
- unsigned long sc_fpcntl[3];
- unsigned char sc_fpstate[16+6*8];
# else
unsigned long sc_fpregs[2*3]; /* room for two fp registers */
+# endif
unsigned long sc_fpcntl[3];
unsigned char sc_fpstate[216];
-# endif
#endif
};
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index d72a71dabec..60b15d0aa07 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -351,6 +351,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -363,6 +364,8 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 2bb4245404d..4bbb3c2a888 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -10,6 +10,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/pgalloc.h>
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index e136b8cbe9b..2391bdff099 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -510,7 +510,7 @@ sys_call_table:
.long sys_settimeofday
.long sys_getgroups16 /* 80 */
.long sys_setgroups16
- .long old_select
+ .long sys_old_select
.long sys_symlink
.long sys_lstat
.long sys_readlink /* 85 */
@@ -518,7 +518,7 @@ sys_call_table:
.long sys_swapon
.long sys_reboot
.long sys_old_readdir
- .long old_mmap /* 90 */
+ .long sys_old_mmap /* 90 */
.long sys_munmap
.long sys_truncate
.long sys_ftruncate
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 17c3f325255..1a6be27cf16 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -15,13 +15,13 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/reboot.h>
#include <linux/init_task.h>
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index e3ad2d67197..77896692eb0 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -46,137 +46,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
}
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
- * handle more than 4 system call parameters, so these system calls
- * used a memory block for parameter passing..
- */
-
-struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
-{
- struct mmap_arg_struct a;
- int error = -EFAULT;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
-
- error = -EINVAL;
- if (a.offset & ~PAGE_MASK)
- goto out;
-
- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
- a.offset >> PAGE_SHIFT);
-out:
- return error;
-}
-
-struct sel_arg_struct {
- unsigned long n;
- fd_set __user *inp, *outp, *exp;
- struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
- struct sel_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
- /* sys_select() does the appropriate kernel locking */
- return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc (uint call, int first, int second,
- int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- return sys_semop (first, ptr, second);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void __user *__user *) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
- default:
- return -ENOSYS;
- }
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return sys_msgsnd (first, ptr, second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
- if (copy_from_user (&tmp, ptr, sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first, ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second, ptr);
- default:
- return -ENOSYS;
- }
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat (first, ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong __user *) third);
- }
- }
- case SHMDT:
- return sys_shmdt (ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second, ptr);
- default:
- return -ENOSYS;
- }
-
- return -EINVAL;
-}
-
/* Convert virtual (user) address VADDR to physical address PADDR */
#define virt_to_phys_040(vaddr) \
({ \
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index 5d818568b34..0f118ca156d 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -8,7 +8,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/time.h>
#include <linux/rtc.h>
#include <linux/mm.h>
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
index 774549accd2..8bc842554e5 100644
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/gfp.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c
index b7473525b43..34c77ce24fb 100644
--- a/arch/m68k/mm/memory.c
+++ b/arch/m68k/mm/memory.c
@@ -9,9 +9,9 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pagemap.h>
+#include <linux/gfp.h>
#include <asm/setup.h>
#include <asm/segment.h>
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index 4665fc84b7d..02b7a03e422 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/gfp.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index cea5e3e4e63..8da9c250d3e 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -9,7 +9,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
-#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/capability.h>
diff --git a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c
index f9277e8b415..ca0966cac72 100644
--- a/arch/m68k/sun3/sun3dvma.c
+++ b/arch/m68k/sun3/sun3dvma.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/list.h>
diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c
index 117481e8630..d5ddcdaa234 100644
--- a/arch/m68k/sun3x/dvma.c
+++ b/arch/m68k/sun3x/dvma.c
@@ -15,7 +15,6 @@
#include <linux/bitops.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/sun3x.h>
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index ce404bc9ccb..14042574ac2 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -94,7 +94,7 @@ cflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200)
cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307)
cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200)
cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5271,-m5200)
+cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5272,-m5307)
cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307)
cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307)
cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200)
diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68knommu/kernel/dma.c
index aaf38bbbb6c..fc61541aeb7 100644
--- a/arch/m68knommu/kernel/dma.c
+++ b/arch/m68knommu/kernel/dma.c
@@ -6,6 +6,7 @@
*/
#include <linux/types.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
index 56043ade394..aff6f57ef8b 100644
--- a/arch/m68knommu/kernel/entry.S
+++ b/arch/m68knommu/kernel/entry.S
@@ -145,6 +145,6 @@ ENTRY(ret_from_user_signal)
trap #0
ENTRY(ret_from_user_rt_signal)
- move #__NR_rt_sigreturn,%d0
+ movel #__NR_rt_sigreturn,%d0
trap #0
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 959cb249c75..6aa66134b43 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -23,11 +23,11 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 85ed2f988f9..f6be1248d21 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -116,12 +116,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
int ret;
switch (request) {
- /* when I and D space are separate, these will need to be fixed. */
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA:
- ret = generic_ptrace_peekdata(child, addr, data);
- break;
-
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp;
@@ -160,12 +154,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- /* when I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = generic_ptrace_pokedata(child, addr, data);
- break;
-
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
if ((addr & 3) || addr < 0 ||
@@ -202,66 +190,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
break;
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: { /* restart after signal. */
- long tmp;
-
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- /* make sure the single step bit is not set. */
- tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
- put_reg(child, PT_SR, tmp);
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL: {
- long tmp;
-
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- /* make sure the single step bit is not set. */
- tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
- put_reg(child, PT_SR, tmp);
- wake_up_process(child);
- break;
- }
-
- case PTRACE_SINGLESTEP: { /* set the trap flag. */
- long tmp;
-
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
- put_reg(child, PT_SR, tmp);
-
- child->exit_code = data;
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
int i;
unsigned long tmp;
@@ -325,7 +253,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
default:
- ret = -EIO;
+ ret = ptrace_request(child, request, addr, data);
break;
}
return ret;
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index 923dd4aab87..d65e9c4c930 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -27,142 +27,6 @@
#include <asm/cacheflush.h>
#include <asm/unistd.h>
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
- * handle more than 4 system call parameters, so these system calls
- * used a memory block for parameter passing..
- */
-
-struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct *arg)
-{
- struct mmap_arg_struct a;
- int error = -EFAULT;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
-
- error = -EINVAL;
- if (a.offset & ~PAGE_MASK)
- goto out;
-
- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
- a.offset >> PAGE_SHIFT);
-out:
- return error;
-}
-
-struct sel_arg_struct {
- unsigned long n;
- fd_set *inp, *outp, *exp;
- struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct *arg)
-{
- struct sel_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
- /* sys_select() does the appropriate kernel locking */
- return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc (uint call, int first, int second,
- int third, void *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- return sys_semop (first, (struct sembuf *)ptr, second);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void **) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
- default:
- return -EINVAL;
- }
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
- if (copy_from_user (&tmp,
- (struct ipc_kludge *)ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second,
- (struct msqid_ds *) ptr);
- default:
- return -EINVAL;
- }
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat (first, ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong __user *) third);
- }
- }
- case SHMDT:
- return sys_shmdt (ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second, ptr);
- default:
- return -ENOSYS;
- }
-
- return -EINVAL;
-}
-
/* sys_cacheflush -- flush (part of) the processor cache. */
asmlinkage int
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
index 56dd01ded14..b30b3eb197a 100644
--- a/arch/m68knommu/kernel/syscalltable.S
+++ b/arch/m68knommu/kernel/syscalltable.S
@@ -100,7 +100,7 @@ ENTRY(sys_call_table)
.long sys_settimeofday
.long sys_getgroups16 /* 80 */
.long sys_setgroups16
- .long old_select
+ .long sys_old_select
.long sys_symlink
.long sys_lstat
.long sys_readlink /* 85 */
@@ -108,7 +108,7 @@ ENTRY(sys_call_table)
.long sys_ni_syscall /* sys_swapon */
.long sys_reboot
.long sys_old_readdir
- .long old_mmap /* 90 */
+ .long sys_old_mmap /* 90 */
.long sys_munmap
.long sys_truncate
.long sys_ftruncate
diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
index f3236d0b522..8a6653f56bd 100644
--- a/arch/m68knommu/mm/init.c
+++ b/arch/m68knommu/mm/init.c
@@ -29,7 +29,7 @@
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/bootmem.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <asm/setup.h>
#include <asm/segment.h>
diff --git a/arch/m68knommu/mm/kmap.c b/arch/m68knommu/mm/kmap.c
index bc32f38843f..902c1dfda9e 100644
--- a/arch/m68knommu/mm/kmap.c
+++ b/arch/m68knommu/mm/kmap.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/setup.h>
diff --git a/arch/m68knommu/mm/memory.c b/arch/m68knommu/mm/memory.c
index d5b9e135780..8f7949e786d 100644
--- a/arch/m68knommu/mm/memory.c
+++ b/arch/m68knommu/mm/memory.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <asm/segment.h>
#include <asm/page.h>
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
index 1143f77caca..6f22970d8c2 100644
--- a/arch/m68knommu/platform/68360/ints.c
+++ b/arch/m68knommu/platform/68360/ints.c
@@ -107,7 +107,6 @@ void init_IRQ(void)
_ramvec[vba+CPMVEC_PIO_PC7] = inthandler; /* pio - pc7 */
_ramvec[vba+CPMVEC_PIO_PC6] = inthandler; /* pio - pc6 */
_ramvec[vba+CPMVEC_TIMER3] = inthandler; /* timer 3 */
- _ramvec[vba+CPMVEC_RISCTIMER] = inthandler; /* reserved */
_ramvec[vba+CPMVEC_PIO_PC5] = inthandler; /* pio - pc5 */
_ramvec[vba+CPMVEC_PIO_PC4] = inthandler; /* pio - pc4 */
_ramvec[vba+CPMVEC_RESERVED2] = inthandler; /* reserved */
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index b008168ae94..76818f92653 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -14,6 +14,8 @@ config MICROBLAZE
select USB_ARCH_HAS_EHCI
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_OPROFILE
+ select HAVE_DMA_ATTRS
+ select HAVE_DMA_API_DEBUG
select TRACING_SUPPORT
config SWAP
@@ -73,12 +75,6 @@ config LOCKDEP_SUPPORT
config HAVE_LATENCYTOP_SUPPORT
def_bool y
-config PCI
- def_bool n
-
-config NO_DMA
- def_bool y
-
config DTC
def_bool y
@@ -146,7 +142,6 @@ menu "Advanced setup"
config ADVANCED_OPTIONS
bool "Prompt for advanced kernel configuration options"
- depends on MMU
help
This option will enable prompting for a variety of advanced kernel
configuration options. These options can cause the kernel to not
@@ -158,6 +153,15 @@ config ADVANCED_OPTIONS
comment "Default settings for advanced configuration options are used"
depends on !ADVANCED_OPTIONS
+config XILINX_UNCACHED_SHADOW
+ bool "Are you using uncached shadow for RAM ?"
+ depends on ADVANCED_OPTIONS && !MMU
+ default n
+ help
+ This is needed to be able to allocate uncachable memory regions.
+ The feature requires the design to define the RAM memory controller
+ window to be twice as large as the actual physical memory.
+
config HIGHMEM_START_BOOL
bool "Set high memory pool address"
depends on ADVANCED_OPTIONS && HIGHMEM
@@ -175,7 +179,7 @@ config HIGHMEM_START
config LOWMEM_SIZE_BOOL
bool "Set maximum low memory"
- depends on ADVANCED_OPTIONS
+ depends on ADVANCED_OPTIONS && MMU
help
This option allows you to set the maximum amount of memory which
will be used as "low memory", that is, memory which the kernel can
@@ -187,7 +191,6 @@ config LOWMEM_SIZE_BOOL
config LOWMEM_SIZE
hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
- depends on MMU
default "0x30000000"
config KERNEL_START_BOOL
@@ -208,7 +211,7 @@ config KERNEL_START
config TASK_SIZE_BOOL
bool "Set custom user task size"
- depends on ADVANCED_OPTIONS
+ depends on ADVANCED_OPTIONS && MMU
help
This option allows you to set the amount of virtual address space
allocated to user tasks. This can be useful in optimizing the
@@ -218,42 +221,34 @@ config TASK_SIZE_BOOL
config TASK_SIZE
hex "Size of user task space" if TASK_SIZE_BOOL
- depends on MMU
default "0x80000000"
-config CONSISTENT_START_BOOL
- bool "Set custom consistent memory pool address"
- depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
- help
- This option allows you to set the base virtual address
- of the the consistent memory pool. This pool of virtual
- memory is used to make consistent memory allocations.
+endmenu
-config CONSISTENT_START
- hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
- depends on MMU
- default "0xff100000" if NOT_COHERENT_CACHE
+source "mm/Kconfig"
-config CONSISTENT_SIZE_BOOL
- bool "Set custom consistent memory pool size"
- depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
- help
- This option allows you to set the size of the the
- consistent memory pool. This pool of virtual memory
- is used to make consistent memory allocations.
+menu "Exectuable file formats"
-config CONSISTENT_SIZE
- hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
- depends on MMU
- default "0x00200000" if NOT_COHERENT_CACHE
+source "fs/Kconfig.binfmt"
endmenu
-source "mm/Kconfig"
+menu "Bus Options"
-menu "Exectuable file formats"
+config PCI
+ bool "PCI support"
-source "fs/Kconfig.binfmt"
+config PCI_DOMAINS
+ def_bool PCI
+
+config PCI_SYSCALL
+ def_bool PCI
+
+config PCI_XILINX
+ bool "Xilinx PCI host bridge support"
+ depends on PCI
+
+source "drivers/pci/Kconfig"
endmenu
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
index d2d6cfcb1a3..72f6e858374 100644
--- a/arch/microblaze/Makefile
+++ b/arch/microblaze/Makefile
@@ -50,6 +50,7 @@ libs-y += $(LIBGCC)
core-y += arch/microblaze/kernel/
core-y += arch/microblaze/mm/
core-y += arch/microblaze/platform/
+core-$(CONFIG_PCI) += arch/microblaze/pci/
drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/
@@ -83,7 +84,7 @@ define archhelp
echo '* linux.bin - Create raw binary'
echo ' linux.bin.gz - Create compressed raw binary'
echo ' simpleImage.<dt> - ELF image with $(arch)/boot/dts/<dt>.dts linked in'
- echo ' - stripped elf with fdt blob
+ echo ' - stripped elf with fdt blob'
echo ' simpleImage.<dt>.unstrip - full ELF image with fdt blob'
echo ' *_defconfig - Select default config from arch/microblaze/configs'
echo ''
@@ -93,3 +94,5 @@ define archhelp
echo ' name of a dts file from the arch/microblaze/boot/dts/ directory'
echo ' (minus the .dts extension).'
endef
+
+MRPROPER_FILES += $(boot)/simpleImage.*
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
index 902cf9846c3..57f50c2371c 100644
--- a/arch/microblaze/boot/Makefile
+++ b/arch/microblaze/boot/Makefile
@@ -23,8 +23,6 @@ $(obj)/system.dtb: $(obj)/$(DTB).dtb
endif
$(obj)/linux.bin: vmlinux FORCE
- [ -n $(CONFIG_INITRAMFS_SOURCE) ] && [ ! -e $(CONFIG_INITRAMFS_SOURCE) ] && \
- touch $(CONFIG_INITRAMFS_SOURCE) || echo "No CPIO image"
$(call if_changed,objcopy)
$(call if_changed,uimage)
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
@@ -62,6 +60,4 @@ quiet_cmd_dtc = DTC $@
$(obj)/%.dtb: $(dtstree)/%.dts FORCE
$(call if_changed,dtc)
-clean-kernel += linux.bin linux.bin.gz simpleImage.*
-
-clean-files += *.dtb simpleImage.*.unstrip
+clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub
diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h
index 78a038452c0..402b46e630f 100644
--- a/arch/microblaze/include/asm/device.h
+++ b/arch/microblaze/include/asm/device.h
@@ -14,6 +14,10 @@ struct device_node;
struct dev_archdata {
/* Optional pointer to an OF device node */
struct device_node *of_node;
+
+ /* DMA operations on that device */
+ struct dma_map_ops *dma_ops;
+ void *dma_data;
};
struct pdev_archdata {
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
index d00e4009916..18b3731c850 100644
--- a/arch/microblaze/include/asm/dma-mapping.h
+++ b/arch/microblaze/include/asm/dma-mapping.h
@@ -1 +1,153 @@
-#include <asm-generic/dma-mapping-broken.h>
+/*
+ * Implements the generic device dma API for microblaze and the pci
+ *
+ * Copyright (C) 2009-2010 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009-2010 PetaLogix
+ *
+ * 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 base on powerpc and x86 dma-mapping.h versions
+ * Copyright (C) 2004 IBM
+ */
+
+#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H
+#define _ASM_MICROBLAZE_DMA_MAPPING_H
+
+/*
+ * See Documentation/PCI/PCI-DMA-mapping.txt and
+ * Documentation/DMA-API.txt for documentation.
+ */
+
+#include <linux/types.h>
+#include <linux/cache.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+#include <linux/dma-attrs.h>
+#include <asm/io.h>
+#include <asm-generic/dma-coherent.h>
+
+#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
+
+#define __dma_alloc_coherent(dev, gfp, size, handle) NULL
+#define __dma_free_coherent(size, addr) ((void)0)
+#define __dma_sync(addr, size, rw) ((void)0)
+
+static inline unsigned long device_to_mask(struct device *dev)
+{
+ if (dev->dma_mask && *dev->dma_mask)
+ return *dev->dma_mask;
+ /* Assume devices without mask can take 32 bit addresses */
+ return 0xfffffffful;
+}
+
+extern struct dma_map_ops *dma_ops;
+
+/*
+ * Available generic sets of operations
+ */
+extern struct dma_map_ops dma_direct_ops;
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+ /* We don't handle the NULL dev case for ISA for now. We could
+ * do it via an out of line call but it is not needed for now. The
+ * only ISA DMA device we support is the floppy and we have a hack
+ * in the floppy driver directly to get a device for us.
+ */
+ if (unlikely(!dev) || !dev->archdata.dma_ops)
+ return NULL;
+
+ return dev->archdata.dma_ops;
+}
+
+static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
+{
+ dev->archdata.dma_ops = ops;
+}
+
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
+ if (unlikely(!ops))
+ return 0;
+ if (!ops->dma_supported)
+ return 1;
+ 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);
+
+ if (unlikely(ops == NULL))
+ return -EIO;
+ if (ops->set_dma_mask)
+ return ops->set_dma_mask(dev, dma_mask);
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+ return -EIO;
+ *dev->dma_mask = dma_mask;
+ return 0;
+}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ if (ops->mapping_error)
+ return ops->mapping_error(dev, dma_addr);
+
+ return (dma_addr == DMA_ERROR_CODE);
+}
+
+#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)
+#define dma_is_consistent(d, h) (1)
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ void *memory;
+
+ BUG_ON(!ops);
+
+ memory = ops->alloc_coherent(dev, size, dma_handle, flag);
+
+ debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
+ return memory;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
+ BUG_ON(!ops);
+ debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+ ops->free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+static inline int dma_get_cache_alignment(void)
+{
+ return L1_CACHE_BYTES;
+}
+
+static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+ __dma_sync(vaddr, size, (int)direction);
+}
+
+#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */
diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h
index 8dbb6e7a03a..ad3fd61b2fe 100644
--- a/arch/microblaze/include/asm/futex.h
+++ b/arch/microblaze/include/asm/futex.h
@@ -55,7 +55,7 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
__futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ANDN:
- __futex_atomic_op("and %1,%0,%4;", ret, oldval, uaddr, oparg);
+ __futex_atomic_op("andn %1,%0,%4;", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg);
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 267c7c779e5..e45a6eea92e 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -15,7 +15,23 @@
#include <asm/page.h>
#include <linux/types.h>
#include <linux/mm.h> /* Get struct page {...} */
+#include <asm-generic/iomap.h>
+#ifndef CONFIG_PCI
+#define _IO_BASE 0
+#define _ISA_MEM_BASE 0
+#define PCI_DRAM_OFFSET 0
+#else
+#define _IO_BASE isa_io_base
+#define _ISA_MEM_BASE isa_mem_base
+#define PCI_DRAM_OFFSET pci_dram_offset
+#endif
+
+extern unsigned long isa_io_base;
+extern unsigned long pci_io_base;
+extern unsigned long pci_dram_offset;
+
+extern resource_size_t isa_mem_base;
#define IO_SPACE_LIMIT (0xFFFFFFFF)
@@ -92,6 +108,11 @@ static inline void writel(unsigned int v, volatile void __iomem *addr)
#define iowrite16(v, addr) __raw_writew((u16)(v), (u16 *)(addr))
#define iowrite32(v, addr) __raw_writel((u32)(v), (u32 *)(addr))
+#define ioread16be(addr) __raw_readw((u16 *)(addr))
+#define ioread32be(addr) __raw_readl((u32 *)(addr))
+#define iowrite16be(v, addr) __raw_writew((u16)(v), (u16 *)(addr))
+#define iowrite32be(v, addr) __raw_writel((u32)(v), (u32 *)(addr))
+
/* These are the definitions for the x86 IO instructions
* inb/inw/inl/outb/outw/outl, the "string" versions
* insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
@@ -124,9 +145,6 @@ static inline void writel(unsigned int v, volatile void __iomem *addr)
#define virt_to_phys(addr) ((unsigned long)__virt_to_phys(addr))
#define virt_to_bus(addr) ((unsigned long)__virt_to_phys(addr))
-#define __page_address(page) \
- (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define page_to_phys(page) virt_to_phys((void *)__page_address(page))
#define page_to_bus(page) (page_to_phys(page))
#define bus_to_virt(addr) (phys_to_virt(addr))
@@ -227,15 +245,7 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
#define out_8(a, v) __raw_writeb((v), (a))
#define in_8(a) __raw_readb(a)
-/* FIXME */
-static inline void __iomem *ioport_map(unsigned long port, unsigned int len)
-{
- return (void __iomem *) (port);
-}
-
-static inline void ioport_unmap(void __iomem *addr)
-{
- /* Nothing to do */
-}
+#define ioport_map(port, nr) ((void __iomem *)(port))
+#define ioport_unmap(addr)
#endif /* _ASM_MICROBLAZE_IO_H */
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index 90f050535eb..31a35c33df6 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -14,6 +14,12 @@
#include <linux/interrupt.h>
+/* This type is the placeholder for a hardware interrupt number. It has to
+ * be big enough to enclose whatever representation is used by a given
+ * platform.
+ */
+typedef unsigned long irq_hw_number_t;
+
extern unsigned int nr_irq;
#define NO_IRQ (-1)
@@ -21,7 +27,8 @@ extern unsigned int nr_irq;
struct pt_regs;
extern void do_IRQ(struct pt_regs *regs);
-/* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
+/**
+ * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
* @device: Device node of the device whose interrupt is to be mapped
* @index: Index of the interrupt to map
*
@@ -40,4 +47,32 @@ static inline void irq_dispose_mapping(unsigned int virq)
return;
}
+struct irq_host;
+
+/**
+ * irq_create_mapping - Map a hardware interrupt into linux virq space
+ * @host: host owning this hardware interrupt or NULL for default host
+ * @hwirq: hardware irq number in that host space
+ *
+ * Only one mapping per hardware interrupt is permitted. Returns a linux
+ * virq number.
+ * If the sense/trigger is to be specified, set_irq_type() should be called
+ * on the number returned from that call.
+ */
+extern unsigned int irq_create_mapping(struct irq_host *host,
+ irq_hw_number_t hwirq);
+
+/**
+ * irq_create_of_mapping - Map a hardware interrupt into linux virq space
+ * @controller: Device node of the interrupt controller
+ * @inspec: Interrupt specifier from the device-tree
+ * @intsize: Size of the interrupt specifier from the device-tree
+ *
+ * This function is identical to irq_create_mapping except that it takes
+ * as input informations straight from the device-tree (typically the results
+ * of the of_irq_map_*() functions.
+ */
+extern unsigned int irq_create_of_mapping(struct device_node *controller,
+ u32 *intspec, unsigned int intsize);
+
#endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
index 9b66c0fa9a3..2dd1d04129e 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -62,12 +62,6 @@ extern unsigned int __page_offset;
#define PAGE_OFFSET CONFIG_KERNEL_START
/*
- * MAP_NR -- given an address, calculate the index of the page struct which
- * points to the address's page.
- */
-#define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
-
-/*
* The basic type of a PTE - 32 bit physical addressing.
*/
typedef unsigned long pte_basic_t;
@@ -154,7 +148,11 @@ extern int page_is_ram(unsigned long pfn);
# define pfn_to_virt(pfn) __va(pfn_to_phys((pfn)))
# ifdef CONFIG_MMU
-# define virt_to_page(kaddr) (mem_map + MAP_NR(kaddr))
+
+# define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
+# define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT)
+# define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
+
# else /* CONFIG_MMU */
# define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr)))
# define page_to_virt(page) (pfn_to_virt(page_to_pfn(page)))
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index 7ad28f6f5f1..0c77cda9f5d 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -1 +1,196 @@
+#ifndef _ASM_MICROBLAZE_PCI_BRIDGE_H
+#define _ASM_MICROBLAZE_PCI_BRIDGE_H
+#ifdef __KERNEL__
+/*
+ * This program is free software; 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/pci.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+
+struct device_node;
+
+enum {
+ /* Force re-assigning all resources (ignore firmware
+ * setup completely)
+ */
+ PCI_REASSIGN_ALL_RSRC = 0x00000001,
+
+ /* Re-assign all bus numbers */
+ PCI_REASSIGN_ALL_BUS = 0x00000002,
+
+ /* Do not try to assign, just use existing setup */
+ PCI_PROBE_ONLY = 0x00000004,
+
+ /* Don't bother with ISA alignment unless the bridge has
+ * ISA forwarding enabled
+ */
+ PCI_CAN_SKIP_ISA_ALIGN = 0x00000008,
+
+ /* Enable domain numbers in /proc */
+ PCI_ENABLE_PROC_DOMAINS = 0x00000010,
+ /* ... except for domain 0 */
+ PCI_COMPAT_DOMAIN_0 = 0x00000020,
+};
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+ struct pci_bus *bus;
+ char is_dynamic;
+ struct device_node *dn;
+ struct list_head list_node;
+ struct device *parent;
+
+ int first_busno;
+ int last_busno;
+
+ int self_busno;
+
+ void __iomem *io_base_virt;
+ resource_size_t io_base_phys;
+
+ resource_size_t pci_io_size;
+
+ /* Some machines (PReP) have a non 1:1 mapping of
+ * the PCI memory space in the CPU bus space
+ */
+ resource_size_t pci_mem_offset;
+
+ /* Some machines have a special region to forward the ISA
+ * "memory" cycles such as VGA memory regions. Left to 0
+ * if unsupported
+ */
+ resource_size_t isa_mem_phys;
+ resource_size_t isa_mem_size;
+
+ struct pci_ops *ops;
+ unsigned int __iomem *cfg_addr;
+ void __iomem *cfg_data;
+
+ /*
+ * Used for variants of PCI indirect handling and possible quirks:
+ * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
+ * EXT_REG - provides access to PCI-e extended registers
+ * SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS
+ * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
+ * to determine which bus number to match on when generating type0
+ * config cycles
+ * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
+ * hanging if we don't have link and try to do config cycles to
+ * anything but the PHB. Only allow talking to the PHB if this is
+ * set.
+ * BIG_ENDIAN - cfg_addr is a big endian register
+ * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs
+ * on the PLB4. Effectively disable MRM commands by setting this.
+ */
+#define INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
+#define INDIRECT_TYPE_EXT_REG 0x00000002
+#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
+#define INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
+#define INDIRECT_TYPE_BIG_ENDIAN 0x00000010
+#define INDIRECT_TYPE_BROKEN_MRM 0x00000020
+ u32 indirect_type;
+
+ /* Currently, we limit ourselves to 1 IO range and 3 mem
+ * ranges since the common pci_bus structure can't handle more
+ */
+ struct resource io_resource;
+ struct resource mem_resources[3];
+ int global_number; /* PCI domain number */
+};
+
+static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
+{
+ return bus->sysdata;
+}
+
+static inline int isa_vaddr_is_ioport(void __iomem *address)
+{
+ /* No specific ISA handling on ppc32 at this stage, it
+ * all goes through PCI
+ */
+ return 0;
+}
+
+/* These are used for config access before all the PCI probing
+ has been done. */
+extern int early_read_config_byte(struct pci_controller *hose, int bus,
+ int dev_fn, int where, u8 *val);
+extern int early_read_config_word(struct pci_controller *hose, int bus,
+ int dev_fn, int where, u16 *val);
+extern int early_read_config_dword(struct pci_controller *hose, int bus,
+ int dev_fn, int where, u32 *val);
+extern int early_write_config_byte(struct pci_controller *hose, int bus,
+ int dev_fn, int where, u8 val);
+extern int early_write_config_word(struct pci_controller *hose, int bus,
+ int dev_fn, int where, u16 val);
+extern int early_write_config_dword(struct pci_controller *hose, int bus,
+ int dev_fn, int where, u32 val);
+
+extern int early_find_capability(struct pci_controller *hose, int bus,
+ int dev_fn, int cap);
+
+extern void setup_indirect_pci(struct pci_controller *hose,
+ resource_size_t cfg_addr,
+ resource_size_t cfg_data, u32 flags);
+
+/* Get the PCI host controller for an OF device */
+extern struct pci_controller *pci_find_hose_for_OF_device(
+ struct device_node *node);
+
+/* Fill up host controller resources from the OF node */
+extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
+ struct device_node *dev, int primary);
+
+/* Allocate & free a PCI host bridge structure */
+extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
+extern void pcibios_free_controller(struct pci_controller *phb);
+extern void pcibios_setup_phb_resources(struct pci_controller *hose);
+
+#ifdef CONFIG_PCI
+extern unsigned int pci_flags;
+
+static inline void pci_set_flags(int flags)
+{
+ pci_flags = flags;
+}
+
+static inline void pci_add_flags(int flags)
+{
+ pci_flags |= flags;
+}
+
+static inline int pci_has_flag(int flag)
+{
+ return pci_flags & flag;
+}
+
+extern struct list_head hose_list;
+
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+extern int pcibios_vaddr_is_ioport(void __iomem *address);
+#else
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
+{
+ return (unsigned long)-1;
+}
+static inline int pcibios_vaddr_is_ioport(void __iomem *address)
+{
+ return 0;
+}
+
+static inline void pci_set_flags(int flags) { }
+static inline void pci_add_flags(int flags) { }
+static inline int pci_has_flag(int flag)
+{
+ return 0;
+}
+#endif /* CONFIG_PCI */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_PCI_BRIDGE_H */
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index 9f0df5faf2c..bdd65aaee30 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -1 +1,177 @@
-#include <asm-generic/pci.h>
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Based on powerpc version
+ */
+
+#ifndef __ASM_MICROBLAZE_PCI_H
+#define __ASM_MICROBLAZE_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+#define PCIBIOS_MIN_IO 0x1000
+#define PCIBIOS_MIN_MEM 0x10000000
+
+struct pci_dev;
+
+/* Values for the `which' argument to sys_pciconfig_iobase syscall. */
+#define IOBASE_BRIDGE_NUMBER 0
+#define IOBASE_MEMORY 1
+#define IOBASE_IO 2
+#define IOBASE_ISA_IO 3
+#define IOBASE_ISA_MEM 4
+
+#define pcibios_scan_all_fns(a, b) 0
+
+/*
+ * Set this to 1 if you want the kernel to re-assign all PCI
+ * bus numbers (don't do that on ppc64 yet !)
+ */
+#define pcibios_assign_all_busses() \
+ (pci_has_flag(PCI_REASSIGN_ALL_BUS))
+
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+ /* We don't do dynamic PCI IRQ allocation */
+}
+
+#ifdef CONFIG_PCI
+extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
+extern struct dma_map_ops *get_pci_dma_ops(void);
+#else /* CONFIG_PCI */
+#define set_pci_dma_ops(d)
+#define get_pci_dma_ops() NULL
+#endif
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+ enum pci_dma_burst_strategy *strat,
+ unsigned long *strategy_parameter)
+{
+ *strat = PCI_DMA_BURST_INFINITY;
+ *strategy_parameter = ~0UL;
+}
+#endif
+
+extern int pci_domain_nr(struct pci_bus *bus);
+
+/* Decide whether to display the domain number in /proc */
+extern int pci_proc_domain(struct pci_bus *bus);
+
+struct vm_area_struct;
+/* Map a range of PCI memory or I/O space for a device into user space */
+int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine);
+
+/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
+#define HAVE_PCI_MMAP 1
+
+extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
+ size_t count);
+extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
+ size_t count);
+extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
+ struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state);
+
+#define HAVE_PCI_LEGACY 1
+
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME) (0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME) (0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
+
+/* The PCI address space does equal the physical memory
+ * address space (no IOMMU). The IDE and SCSI device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS (1)
+
+extern void pcibios_resource_to_bus(struct pci_dev *dev,
+ struct pci_bus_region *region,
+ struct resource *res);
+
+extern void pcibios_bus_to_resource(struct pci_dev *dev,
+ struct resource *res,
+ struct pci_bus_region *region);
+
+static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
+ struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
+extern void pcibios_claim_one_bus(struct pci_bus *b);
+
+extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
+
+extern void pcibios_resource_survey(void);
+
+extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
+extern int remove_phb_dynamic(struct pci_controller *phb);
+
+extern struct pci_dev *of_create_pci_dev(struct device_node *node,
+ struct pci_bus *bus, int devfn);
+
+extern void of_scan_pci_bridge(struct device_node *node,
+ struct pci_dev *dev);
+
+extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
+extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
+
+extern int pci_read_irq_line(struct pci_dev *dev);
+
+extern int pci_bus_find_capability(struct pci_bus *bus,
+ unsigned int devfn, int cap);
+
+struct file;
+extern pgprot_t pci_phys_mem_access_prot(struct file *file,
+ unsigned long pfn,
+ unsigned long size,
+ pgprot_t prot);
+
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+ const struct resource *rsrc,
+ resource_size_t *start, resource_size_t *end);
+
+extern void pcibios_setup_bus_devices(struct pci_bus *bus);
+extern void pcibios_setup_bus_self(struct pci_bus *bus);
+
+/* This part of code was originaly in xilinx-pci.h */
+#ifdef CONFIG_PCI_XILINX
+extern void __init xilinx_pci_init(void);
+#else
+static inline void __init xilinx_pci_init(void) { return; }
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_MICROBLAZE_PCI_H */
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
index 7547f506456..f44b0d696fe 100644
--- a/arch/microblaze/include/asm/pgalloc.h
+++ b/arch/microblaze/include/asm/pgalloc.h
@@ -19,6 +19,7 @@
#include <asm/io.h>
#include <asm/page.h>
#include <asm/cache.h>
+#include <asm/pgtable.h>
#define PGDIR_ORDER 0
@@ -111,7 +112,6 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
pte_t *pte;
- extern int mem_init_done;
extern void *early_get_page(void);
if (mem_init_done) {
pte = (pte_t *)__get_free_page(GFP_KERNEL |
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index cc3a4dfc3ea..dd2bb60651c 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -16,6 +16,10 @@
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
+#ifndef __ASSEMBLY__
+extern int mem_init_done;
+#endif
+
#ifndef CONFIG_MMU
#define pgd_present(pgd) (1) /* pages are always present on non MMU */
@@ -51,6 +55,8 @@ static inline int pte_file(pte_t pte) { return 0; }
#define arch_enter_lazy_cpu_mode() do {} while (0)
+#define pgprot_noncached_wc(prot) prot
+
#else /* CONFIG_MMU */
#include <asm-generic/4level-fixup.h>
@@ -68,7 +74,6 @@ static inline int pte_file(pte_t pte) { return 0; }
extern unsigned long va_to_phys(unsigned long address);
extern pte_t *va_to_pte(unsigned long address);
-extern unsigned long ioremap_bot, ioremap_base;
/*
* The following only work if pte_present() is true.
@@ -85,11 +90,25 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
#define VMALLOC_START (CONFIG_KERNEL_START + \
max(32 * 1024 * 1024UL, memory_size))
#define VMALLOC_END ioremap_bot
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
#endif /* __ASSEMBLY__ */
/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+
+#define _PAGE_CACHE_CTL (_PAGE_GUARDED | _PAGE_NO_CACHE | \
+ _PAGE_WRITETHRU)
+
+#define pgprot_noncached(prot) \
+ (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+ _PAGE_NO_CACHE | _PAGE_GUARDED))
+
+#define pgprot_noncached_wc(prot) \
+ (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+ _PAGE_NO_CACHE))
+
+/*
* The MicroBlaze MMU is identical to the PPC-40x MMU, and uses a hash
* table containing PTEs, together with a set of 16 segment registers, to
* define the virtual to physical address mapping.
@@ -397,7 +416,7 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr,
mts rmsr, %2\n\
nop"
: "=&r" (old), "=&r" (tmp), "=&r" (msr), "=m" (*p)
- : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p)
+ : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set), "m" (*p)
: "cc");
return old;
@@ -566,18 +585,11 @@ void mapin_ram(void);
int map_page(unsigned long va, phys_addr_t pa, int flags);
extern int mem_init_done;
-extern unsigned long ioremap_base;
-extern unsigned long ioremap_bot;
asmlinkage void __init mmu_init(void);
void __init *early_get_page(void);
-void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
-void consistent_free(void *vaddr);
-void consistent_sync(void *vaddr, size_t size, int direction);
-void consistent_sync_page(struct page *page, unsigned long offset,
- size_t size, int direction);
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
@@ -586,6 +598,14 @@ void consistent_sync_page(struct page *page, unsigned long offset,
#ifndef __ASSEMBLY__
#include <asm-generic/pgtable.h>
+extern unsigned long ioremap_bot, ioremap_base;
+
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
+void consistent_free(void *vaddr);
+void consistent_sync(void *vaddr, size_t size, int direction);
+void consistent_sync_page(struct page *page, unsigned long offset,
+ size_t size, int direction);
+
void setup_memory(void);
#endif /* __ASSEMBLY__ */
diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h
index 563c6b9453f..8eeb09211ec 100644
--- a/arch/microblaze/include/asm/processor.h
+++ b/arch/microblaze/include/asm/processor.h
@@ -14,7 +14,6 @@
#include <asm/ptrace.h>
#include <asm/setup.h>
#include <asm/registers.h>
-#include <asm/segment.h>
#include <asm/entry.h>
#include <asm/current.h>
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 03f45a96320..e7d67a329bd 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -31,6 +31,21 @@
/* Other Prototypes */
extern int early_uartlite_console(void);
+#ifdef CONFIG_PCI
+/*
+ * PCI <-> OF matching functions
+ * (XXX should these be here?)
+ */
+struct pci_bus;
+struct pci_dev;
+extern int pci_device_from_OF_node(struct device_node *node,
+ u8 *bus, u8 *devfn);
+extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *bus,
+ int devfn);
+extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
+extern void pci_create_OF_bus_map(void);
+#endif
+
/*
* OF address retreival & translation
*/
diff --git a/arch/microblaze/include/asm/segment.h b/arch/microblaze/include/asm/segment.h
deleted file mode 100644
index 0e7102c3fb1..00000000000
--- a/arch/microblaze/include/asm/segment.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2008-2009 PetaLogix
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_SEGMENT_H
-#define _ASM_MICROBLAZE_SEGMENT_H
-
-# ifndef __ASSEMBLY__
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-/*
- * On Microblaze the fs value is actually the top of the corresponding
- * address space.
- *
- * 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.
- *
- * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
- */
-# define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-
-# ifndef CONFIG_MMU
-# define KERNEL_DS MAKE_MM_SEG(0)
-# define USER_DS KERNEL_DS
-# else
-# define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
-# define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
-# endif
-
-# define get_ds() (KERNEL_DS)
-# define get_fs() (current_thread_info()->addr_limit)
-# define set_fs(val) (current_thread_info()->addr_limit = (val))
-
-# define segment_eq(a, b) ((a).seg == (b).seg)
-
-# endif /* __ASSEMBLY__ */
-#endif /* _ASM_MICROBLAZE_SEGMENT_H */
diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h
index 157970688b2..59efb3fef95 100644
--- a/arch/microblaze/include/asm/system.h
+++ b/arch/microblaze/include/asm/system.h
@@ -87,6 +87,9 @@ void free_initmem(void);
extern char *klimit;
extern void ret_from_fork(void);
+extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
+extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
+
#ifdef CONFIG_DEBUG_FS
extern struct dentry *of_debugfs_root;
#endif
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
index 6e92885d381..b2ca80f6464 100644
--- a/arch/microblaze/include/asm/thread_info.h
+++ b/arch/microblaze/include/asm/thread_info.h
@@ -19,7 +19,6 @@
#ifndef __ASSEMBLY__
# include <linux/types.h>
# include <asm/processor.h>
-# include <asm/segment.h>
/*
* low level task data that entry.S needs immediate access to
@@ -60,6 +59,10 @@ struct cpu_context {
__u32 fsr;
};
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
diff --git a/arch/microblaze/include/asm/tlbflush.h b/arch/microblaze/include/asm/tlbflush.h
index 10ec70cd873..2e1353c2d18 100644
--- a/arch/microblaze/include/asm/tlbflush.h
+++ b/arch/microblaze/include/asm/tlbflush.h
@@ -23,7 +23,8 @@
extern void _tlbie(unsigned long address);
extern void _tlbia(void);
-#define __tlbia() _tlbia()
+#define __tlbia() { preempt_disable(); _tlbia(); preempt_enable(); }
+#define __tlbie(x) { _tlbie(x); }
static inline void local_flush_tlb_all(void)
{ __tlbia(); }
@@ -31,7 +32,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
{ __tlbia(); }
static inline void local_flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
- { _tlbie(vmaddr); }
+ { __tlbie(vmaddr); }
static inline void local_flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{ __tlbia(); }
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index 371bd6e56d9..446bec29b14 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -22,101 +22,73 @@
#include <asm/mmu.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/segment.h>
#include <linux/string.h>
#define VERIFY_READ 0
#define VERIFY_WRITE 1
-#define __clear_user(addr, n) (memset((void *)(addr), 0, (n)), 0)
-
-#ifndef CONFIG_MMU
-
-extern int ___range_ok(unsigned long addr, unsigned long size);
-
-#define __range_ok(addr, size) \
- ___range_ok((unsigned long)(addr), (unsigned long)(size))
-
-#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
-#define __access_ok(add, size) (__range_ok((addr), (size)) == 0)
-
-/* Undefined function to trigger linker error */
-extern int bad_user_access_length(void);
-
-/* FIXME this is function for optimalization -> memcpy */
-#define __get_user(var, ptr) \
-({ \
- int __gu_err = 0; \
- switch (sizeof(*(ptr))) { \
- case 1: \
- case 2: \
- case 4: \
- (var) = *(ptr); \
- break; \
- case 8: \
- memcpy((void *) &(var), (ptr), 8); \
- break; \
- default: \
- (var) = 0; \
- __gu_err = __get_user_bad(); \
- break; \
- } \
- __gu_err; \
-})
+/*
+ * On Microblaze the fs value is actually the top of the corresponding
+ * address space.
+ *
+ * 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.
+ *
+ * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
+ */
+# define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define __get_user_bad() (bad_user_access_length(), (-EFAULT))
+# ifndef CONFIG_MMU
+# define KERNEL_DS MAKE_MM_SEG(0)
+# define USER_DS KERNEL_DS
+# else
+# define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
+# define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
+# endif
-/* FIXME is not there defined __pu_val */
-#define __put_user(var, ptr) \
-({ \
- int __pu_err = 0; \
- switch (sizeof(*(ptr))) { \
- case 1: \
- case 2: \
- case 4: \
- *(ptr) = (var); \
- break; \
- case 8: { \
- typeof(*(ptr)) __pu_val = (var); \
- memcpy(ptr, &__pu_val, sizeof(__pu_val)); \
- } \
- break; \
- default: \
- __pu_err = __put_user_bad(); \
- break; \
- } \
- __pu_err; \
-})
+# define get_ds() (KERNEL_DS)
+# define get_fs() (current_thread_info()->addr_limit)
+# define set_fs(val) (current_thread_info()->addr_limit = (val))
-#define __put_user_bad() (bad_user_access_length(), (-EFAULT))
+# define segment_eq(a, b) ((a).seg == (b).seg)
-#define put_user(x, ptr) __put_user((x), (ptr))
-#define get_user(x, ptr) __get_user((x), (ptr))
+/*
+ * 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;
+};
-#define copy_to_user(to, from, n) (memcpy((to), (from), (n)), 0)
-#define copy_from_user(to, from, n) (memcpy((to), (from), (n)), 0)
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
-#define __copy_to_user(to, from, n) (copy_to_user((to), (from), (n)))
-#define __copy_from_user(to, from, n) (copy_from_user((to), (from), (n)))
-#define __copy_to_user_inatomic(to, from, n) \
- (__copy_to_user((to), (from), (n)))
-#define __copy_from_user_inatomic(to, from, n) \
- (__copy_from_user((to), (from), (n)))
+#ifndef CONFIG_MMU
-static inline unsigned long clear_user(void *addr, unsigned long size)
+/* Check against bounds of physical memory */
+static inline int ___range_ok(unsigned long addr, unsigned long size)
{
- if (access_ok(VERIFY_WRITE, addr, size))
- size = __clear_user(addr, size);
- return size;
+ return ((addr < memory_start) ||
+ ((addr + size) > memory_end));
}
-/* Returns 0 if exception not found and fixup otherwise. */
-extern unsigned long search_exception_table(unsigned long);
+#define __range_ok(addr, size) \
+ ___range_ok((unsigned long)(addr), (unsigned long)(size))
-extern long strncpy_from_user(char *dst, const char *src, long count);
-extern long strnlen_user(const char *src, long count);
+#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
-#else /* CONFIG_MMU */
+#else
/*
* Address is valid if:
@@ -129,24 +101,88 @@ extern long strnlen_user(const char *src, long count);
/* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n",
type?"WRITE":"READ",addr,size,get_fs().seg)) */
-/*
- * All the __XXX versions macros/functions below do not perform
- * access checking. It is assumed that the necessary checks have been
- * already performed before the finction (macro) is called.
- */
+#endif
-#define get_user(x, ptr) \
-({ \
- access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \
- ? __get_user((x), (ptr)) : -EFAULT; \
-})
+#ifdef CONFIG_MMU
+# define __FIXUP_SECTION ".section .fixup,\"ax\"\n"
+# define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n"
+#else
+# define __FIXUP_SECTION ".section .discard,\"ax\"\n"
+# define __EX_TABLE_SECTION ".section .discard,\"a\"\n"
+#endif
-#define put_user(x, ptr) \
-({ \
- access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) \
- ? __put_user((x), (ptr)) : -EFAULT; \
+extern unsigned long __copy_tofrom_user(void __user *to,
+ const void __user *from, unsigned long size);
+
+/* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
+static inline unsigned long __must_check __clear_user(void __user *to,
+ unsigned long n)
+{
+ /* normal memset with two words to __ex_table */
+ __asm__ __volatile__ ( \
+ "1: sb r0, %2, r0;" \
+ " addik %0, %0, -1;" \
+ " bneid %0, 1b;" \
+ " addik %2, %2, 1;" \
+ "2: " \
+ __EX_TABLE_SECTION \
+ ".word 1b,2b;" \
+ ".previous;" \
+ : "=r"(n) \
+ : "0"(n), "r"(to)
+ );
+ return n;
+}
+
+static inline unsigned long __must_check clear_user(void __user *to,
+ unsigned long n)
+{
+ might_sleep();
+ if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
+ return n;
+
+ return __clear_user(to, n);
+}
+
+/* put_user and get_user macros */
+extern long __user_bad(void);
+
+#define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \
+({ \
+ __asm__ __volatile__ ( \
+ "1:" insn " %1, %2, r0;" \
+ " addk %0, r0, r0;" \
+ "2: " \
+ __FIXUP_SECTION \
+ "3: brid 2b;" \
+ " addik %0, r0, %3;" \
+ ".previous;" \
+ __EX_TABLE_SECTION \
+ ".word 1b,3b;" \
+ ".previous;" \
+ : "=&r"(__gu_err), "=r"(__gu_val) \
+ : "r"(__gu_ptr), "i"(-EFAULT) \
+ ); \
})
+/**
+ * get_user: - Get a simple variable from user space.
+ * @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.
+ */
+
#define __get_user(x, ptr) \
({ \
unsigned long __gu_val; \
@@ -163,30 +199,74 @@ extern long strnlen_user(const char *src, long count);
__get_user_asm("lw", (ptr), __gu_val, __gu_err); \
break; \
default: \
- __gu_val = 0; __gu_err = -EINVAL; \
+ /* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\
} \
x = (__typeof__(*(ptr))) __gu_val; \
__gu_err; \
})
-#define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \
+
+#define get_user(x, ptr) \
({ \
- __asm__ __volatile__ ( \
- "1:" insn " %1, %2, r0; \
- addk %0, r0, r0; \
- 2: \
- .section .fixup,\"ax\"; \
- 3: brid 2b; \
- addik %0, r0, %3; \
- .previous; \
- .section __ex_table,\"a\"; \
- .word 1b,3b; \
- .previous;" \
- : "=r"(__gu_err), "=r"(__gu_val) \
- : "r"(__gu_ptr), "i"(-EFAULT) \
- ); \
+ access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \
+ ? __get_user((x), (ptr)) : -EFAULT; \
+})
+
+#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \
+({ \
+ __asm__ __volatile__ ( \
+ "1:" insn " %1, %2, r0;" \
+ " addk %0, r0, r0;" \
+ "2: " \
+ __FIXUP_SECTION \
+ "3: brid 2b;" \
+ " addik %0, r0, %3;" \
+ ".previous;" \
+ __EX_TABLE_SECTION \
+ ".word 1b,3b;" \
+ ".previous;" \
+ : "=&r"(__gu_err) \
+ : "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT) \
+ ); \
})
+#define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err) \
+({ \
+ __asm__ __volatile__ (" lwi %0, %1, 0;" \
+ "1: swi %0, %2, 0;" \
+ " lwi %0, %1, 4;" \
+ "2: swi %0, %2, 4;" \
+ " addk %0, r0, r0;" \
+ "3: " \
+ __FIXUP_SECTION \
+ "4: brid 3b;" \
+ " addik %0, r0, %3;" \
+ ".previous;" \
+ __EX_TABLE_SECTION \
+ ".word 1b,4b,2b,4b;" \
+ ".previous;" \
+ : "=&r"(__gu_err) \
+ : "r"(&__gu_val), "r"(__gu_ptr), "i"(-EFAULT) \
+ ); \
+})
+
+/**
+ * put_user: - Write a simple value into user space.
+ * @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.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+
#define __put_user(x, ptr) \
({ \
__typeof__(*(ptr)) volatile __gu_val = (x); \
@@ -195,7 +275,7 @@ extern long strnlen_user(const char *src, long count);
case 1: \
__put_user_asm("sb", (ptr), __gu_val, __gu_err); \
break; \
- case 2: \
+ case 2: \
__put_user_asm("sh", (ptr), __gu_val, __gu_err); \
break; \
case 4: \
@@ -205,121 +285,82 @@ extern long strnlen_user(const char *src, long count);
__put_user_asm_8((ptr), __gu_val, __gu_err); \
break; \
default: \
- __gu_err = -EINVAL; \
+ /*__gu_err = -EINVAL;*/ __gu_err = __user_bad(); \
} \
__gu_err; \
})
-#define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err) \
-({ \
-__asm__ __volatile__ (" lwi %0, %1, 0; \
- 1: swi %0, %2, 0; \
- lwi %0, %1, 4; \
- 2: swi %0, %2, 4; \
- addk %0,r0,r0; \
- 3: \
- .section .fixup,\"ax\"; \
- 4: brid 3b; \
- addik %0, r0, %3; \
- .previous; \
- .section __ex_table,\"a\"; \
- .word 1b,4b,2b,4b; \
- .previous;" \
- : "=&r"(__gu_err) \
- : "r"(&__gu_val), \
- "r"(__gu_ptr), "i"(-EFAULT) \
- ); \
-})
+#ifndef CONFIG_MMU
-#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \
-({ \
- __asm__ __volatile__ ( \
- "1:" insn " %1, %2, r0; \
- addk %0, r0, r0; \
- 2: \
- .section .fixup,\"ax\"; \
- 3: brid 2b; \
- addik %0, r0, %3; \
- .previous; \
- .section __ex_table,\"a\"; \
- .word 1b,3b; \
- .previous;" \
- : "=r"(__gu_err) \
- : "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT) \
- ); \
-})
+#define put_user(x, ptr) __put_user((x), (ptr))
-/*
- * Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail.
- */
-static inline int clear_user(char *to, int size)
-{
- if (size && access_ok(VERIFY_WRITE, to, size)) {
- __asm__ __volatile__ (" \
- 1: \
- sb r0, %2, r0; \
- addik %0, %0, -1; \
- bneid %0, 1b; \
- addik %2, %2, 1; \
- 2: \
- .section __ex_table,\"a\"; \
- .word 1b,2b; \
- .section .text;" \
- : "=r"(size) \
- : "0"(size), "r"(to)
- );
- }
- return size;
-}
+#else /* CONFIG_MMU */
-#define __copy_from_user(to, from, n) copy_from_user((to), (from), (n))
+#define put_user(x, ptr) \
+({ \
+ access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) \
+ ? __put_user((x), (ptr)) : -EFAULT; \
+})
+#endif /* CONFIG_MMU */
+
+/* copy_to_from_user */
+#define __copy_from_user(to, from, n) \
+ __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))
-#define copy_to_user(to, from, n) \
- (access_ok(VERIFY_WRITE, (to), (n)) ? \
- __copy_tofrom_user((void __user *)(to), \
- (__force const void __user *)(from), (n)) \
- : -EFAULT)
+static inline long copy_from_user(void *to,
+ const void __user *from, unsigned long n)
+{
+ might_sleep();
+ if (access_ok(VERIFY_READ, from, n))
+ return __copy_from_user(to, from, n);
+ return n;
+}
-#define __copy_to_user(to, from, n) copy_to_user((to), (from), (n))
+#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_from_user(to, from, n) \
- (access_ok(VERIFY_READ, (from), (n)) ? \
- __copy_tofrom_user((__force void __user *)(to), \
- (void __user *)(from), (n)) \
- : -EFAULT)
+static inline long copy_to_user(void __user *to,
+ const void *from, unsigned long n)
+{
+ might_sleep();
+ if (access_ok(VERIFY_WRITE, to, n))
+ return __copy_to_user(to, from, n);
+ return n;
+}
+/*
+ * Copy a null terminated string from userspace.
+ */
extern int __strncpy_user(char *to, const char __user *from, int len);
-extern int __strnlen_user(const char __user *sstr, int len);
-#define strncpy_from_user(to, from, len) \
- (access_ok(VERIFY_READ, from, 1) ? \
- __strncpy_user(to, from, len) : -EFAULT)
-#define strnlen_user(str, len) \
- (access_ok(VERIFY_READ, str, 1) ? __strnlen_user(str, len) : 0)
+#define __strncpy_from_user __strncpy_user
-#endif /* CONFIG_MMU */
-
-extern unsigned long __copy_tofrom_user(void __user *to,
- const void __user *from, unsigned long size);
+static inline long
+strncpy_from_user(char *dst, const char __user *src, long count)
+{
+ if (!access_ok(VERIFY_READ, src, 1))
+ return -EFAULT;
+ return __strncpy_from_user(dst, src, count);
+}
/*
- * 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.
+ * Return the size of a string (including the ending 0)
*
- * 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.
+ * Return 0 on exception, a value greater than N if too long
*/
-struct exception_table_entry {
- unsigned long insn, fixup;
-};
+extern int __strnlen_user(const char __user *sstr, int len);
+
+static inline long strnlen_user(const char __user *src, long n)
+{
+ if (!access_ok(VERIFY_READ, src, 1))
+ return 0;
+ return __strnlen_user(src, n);
+}
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index b07594eccf9..e51bc152082 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -14,7 +14,7 @@ endif
extra-y := head.o vmlinux.lds
-obj-y += exceptions.o \
+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
diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c
index 7bc7b68f97d..0071260a672 100644
--- a/arch/microblaze/kernel/asm-offsets.c
+++ b/arch/microblaze/kernel/asm-offsets.c
@@ -90,6 +90,7 @@ int main(int argc, char *argv[])
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
+ DEFINE(TI_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count));
BLANK();
/* struct cpu_context */
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
index 2a56bccce4e..f04d8a86dea 100644
--- a/arch/microblaze/kernel/cpu/cache.c
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -15,25 +15,6 @@
#include <asm/cpuinfo.h>
#include <asm/pvr.h>
-static inline void __invalidate_flush_icache(unsigned int addr)
-{
- __asm__ __volatile__ ("wic %0, r0;" \
- : : "r" (addr));
-}
-
-static inline void __flush_dcache(unsigned int addr)
-{
- __asm__ __volatile__ ("wdc.flush %0, r0;" \
- : : "r" (addr));
-}
-
-static inline void __invalidate_dcache(unsigned int baseaddr,
- unsigned int offset)
-{
- __asm__ __volatile__ ("wdc.clear %0, %1;" \
- : : "r" (baseaddr), "r" (offset));
-}
-
static inline void __enable_icache_msr(void)
{
__asm__ __volatile__ (" msrset r0, %0; \
@@ -148,9 +129,9 @@ do { \
int step = -line_length; \
BUG_ON(step >= 0); \
\
- __asm__ __volatile__ (" 1: " #op " r0, %0; \
- bgtid %0, 1b; \
- addk %0, %0, %1; \
+ __asm__ __volatile__ (" 1: " #op " r0, %0; \
+ bgtid %0, 1b; \
+ addk %0, %0, %1; \
" : : "r" (len), "r" (step) \
: "memory"); \
} while (0);
@@ -162,9 +143,9 @@ do { \
int count = end - start; \
BUG_ON(count <= 0); \
\
- __asm__ __volatile__ (" 1: " #op " %0, %1; \
- bgtid %1, 1b; \
- addk %1, %1, %2; \
+ __asm__ __volatile__ (" 1: " #op " %0, %1; \
+ bgtid %1, 1b; \
+ addk %1, %1, %2; \
" : : "r" (start), "r" (count), \
"r" (step) : "memory"); \
} while (0);
@@ -175,7 +156,7 @@ do { \
int volatile temp; \
BUG_ON(end - start <= 0); \
\
- __asm__ __volatile__ (" 1: " #op " %1, r0; \
+ __asm__ __volatile__ (" 1: " #op " %1, r0; \
cmpu %0, %1, %2; \
bgtid %0, 1b; \
addk %1, %1, %3; \
@@ -183,10 +164,14 @@ do { \
"r" (line_length) : "memory"); \
} while (0);
+#define ASM_LOOP
+
static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
{
unsigned long flags;
-
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
(unsigned int)start, (unsigned int) end);
@@ -196,8 +181,13 @@ static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
local_irq_save(flags);
__disable_icache_msr();
+#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
-
+#else
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wic %0, r0;" \
+ : : "r" (i));
+#endif
__enable_icache_msr();
local_irq_restore(flags);
}
@@ -206,7 +196,9 @@ static void __flush_icache_range_nomsr_irq(unsigned long start,
unsigned long end)
{
unsigned long flags;
-
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
(unsigned int)start, (unsigned int) end);
@@ -216,7 +208,13 @@ static void __flush_icache_range_nomsr_irq(unsigned long start,
local_irq_save(flags);
__disable_icache_nomsr();
+#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+#else
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wic %0, r0;" \
+ : : "r" (i));
+#endif
__enable_icache_nomsr();
local_irq_restore(flags);
@@ -225,25 +223,41 @@ static void __flush_icache_range_nomsr_irq(unsigned long start,
static void __flush_icache_range_noirq(unsigned long start,
unsigned long end)
{
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
(unsigned int)start, (unsigned int) end);
CACHE_LOOP_LIMITS(start, end,
cpuinfo.icache_line_length, cpuinfo.icache_size);
+#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+#else
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wic %0, r0;" \
+ : : "r" (i));
+#endif
}
static void __flush_icache_all_msr_irq(void)
{
unsigned long flags;
-
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s\n", __func__);
local_irq_save(flags);
__disable_icache_msr();
-
+#ifdef ASM_LOOP
CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
-
+#else
+ for (i = 0; i < cpuinfo.icache_size;
+ i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wic %0, r0;" \
+ : : "r" (i));
+#endif
__enable_icache_msr();
local_irq_restore(flags);
}
@@ -251,35 +265,59 @@ static void __flush_icache_all_msr_irq(void)
static void __flush_icache_all_nomsr_irq(void)
{
unsigned long flags;
-
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s\n", __func__);
local_irq_save(flags);
__disable_icache_nomsr();
-
+#ifdef ASM_LOOP
CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
-
+#else
+ for (i = 0; i < cpuinfo.icache_size;
+ i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wic %0, r0;" \
+ : : "r" (i));
+#endif
__enable_icache_nomsr();
local_irq_restore(flags);
}
static void __flush_icache_all_noirq(void)
{
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
+#else
+ for (i = 0; i < cpuinfo.icache_size;
+ i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wic %0, r0;" \
+ : : "r" (i));
+#endif
}
static void __invalidate_dcache_all_msr_irq(void)
{
unsigned long flags;
-
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s\n", __func__);
local_irq_save(flags);
__disable_dcache_msr();
-
+#ifdef ASM_LOOP
CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
-
+#else
+ for (i = 0; i < cpuinfo.dcache_size;
+ i += cpuinfo.dcache_line_length)
+ __asm__ __volatile__ ("wdc %0, r0;" \
+ : : "r" (i));
+#endif
__enable_dcache_msr();
local_irq_restore(flags);
}
@@ -287,60 +325,107 @@ static void __invalidate_dcache_all_msr_irq(void)
static void __invalidate_dcache_all_nomsr_irq(void)
{
unsigned long flags;
-
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s\n", __func__);
local_irq_save(flags);
__disable_dcache_nomsr();
-
+#ifdef ASM_LOOP
CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
-
+#else
+ for (i = 0; i < cpuinfo.dcache_size;
+ i += cpuinfo.dcache_line_length)
+ __asm__ __volatile__ ("wdc %0, r0;" \
+ : : "r" (i));
+#endif
__enable_dcache_nomsr();
local_irq_restore(flags);
}
static void __invalidate_dcache_all_noirq_wt(void)
{
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc)
+#else
+ for (i = 0; i < cpuinfo.dcache_size;
+ i += cpuinfo.dcache_line_length)
+ __asm__ __volatile__ ("wdc %0, r0;" \
+ : : "r" (i));
+#endif
}
/* FIXME this is weird - should be only wdc but not work
* MS: I am getting bus errors and other weird things */
static void __invalidate_dcache_all_wb(void)
{
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
wdc.clear)
+#else
+ for (i = 0; i < cpuinfo.dcache_size;
+ i += cpuinfo.dcache_line_length)
+ __asm__ __volatile__ ("wdc.clear %0, r0;" \
+ : : "r" (i));
+#endif
}
static void __invalidate_dcache_range_wb(unsigned long start,
unsigned long end)
{
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
(unsigned int)start, (unsigned int) end);
CACHE_LOOP_LIMITS(start, end,
cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+#ifdef ASM_LOOP
CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
+#else
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wdc.clear %0, r0;" \
+ : : "r" (i));
+#endif
}
static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
unsigned long end)
{
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
(unsigned int)start, (unsigned int) end);
CACHE_LOOP_LIMITS(start, end,
cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wdc %0, r0;" \
+ : : "r" (i));
+#endif
}
static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
unsigned long end)
{
unsigned long flags;
-
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
(unsigned int)start, (unsigned int) end);
CACHE_LOOP_LIMITS(start, end,
@@ -349,7 +434,13 @@ static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
local_irq_save(flags);
__disable_dcache_msr();
+#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wdc %0, r0;" \
+ : : "r" (i));
+#endif
__enable_dcache_msr();
local_irq_restore(flags);
@@ -359,7 +450,9 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
unsigned long end)
{
unsigned long flags;
-
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
(unsigned int)start, (unsigned int) end);
@@ -369,7 +462,13 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
local_irq_save(flags);
__disable_dcache_nomsr();
+#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wdc %0, r0;" \
+ : : "r" (i));
+#endif
__enable_dcache_nomsr();
local_irq_restore(flags);
@@ -377,19 +476,38 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
static void __flush_dcache_all_wb(void)
{
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
wdc.flush);
+#else
+ for (i = 0; i < cpuinfo.dcache_size;
+ i += cpuinfo.dcache_line_length)
+ __asm__ __volatile__ ("wdc.flush %0, r0;" \
+ : : "r" (i));
+#endif
}
static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
{
+#ifndef ASM_LOOP
+ int i;
+#endif
pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
(unsigned int)start, (unsigned int) end);
CACHE_LOOP_LIMITS(start, end,
cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+#ifdef ASM_LOOP
CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
+#else
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
+ __asm__ __volatile__ ("wdc.flush %0, r0;" \
+ : : "r" (i));
+#endif
}
/* struct for wb caches and for wt caches */
@@ -493,7 +611,7 @@ const struct scache wt_nomsr_noirq = {
#define CPUVER_7_20_A 0x0c
#define CPUVER_7_20_D 0x0f
-#define INFO(s) printk(KERN_INFO "cache: " s " \n");
+#define INFO(s) printk(KERN_INFO "cache: " s "\n");
void microblaze_cache_init(void)
{
@@ -532,4 +650,9 @@ void microblaze_cache_init(void)
}
}
}
+ invalidate_dcache();
+ enable_dcache();
+
+ invalidate_icache();
+ enable_icache();
}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index 991d71311b0..255ef880351 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -9,7 +9,6 @@
*/
#include <linux/init.h>
-#include <linux/slab.h>
#include <asm/cpuinfo.h>
#include <asm/pvr.h>
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
new file mode 100644
index 00000000000..ce72dd4967c
--- /dev/null
+++ b/arch/microblaze/kernel/dma.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2009-2010 PetaLogix
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
+ *
+ * Provide default implementations of the DMA mapping callbacks for
+ * directly mapped busses.
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/dma-debug.h>
+#include <asm/bug.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Generic direct DMA implementation
+ *
+ * This implementation supports a per-device offset that can be applied if
+ * the address at which memory is visible to devices is not 0. Platform code
+ * can set archdata.dma_data to an unsigned long holding the offset. By
+ * default the offset is PCI_DRAM_OFFSET.
+ */
+static inline void __dma_sync_page(unsigned long paddr, unsigned long offset,
+ size_t size, enum dma_data_direction direction)
+{
+ switch (direction) {
+ case DMA_TO_DEVICE:
+ flush_dcache_range(paddr + offset, paddr + offset + size);
+ break;
+ case DMA_FROM_DEVICE:
+ invalidate_dcache_range(paddr + offset, paddr + offset + size);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static unsigned long get_dma_direct_offset(struct device *dev)
+{
+ if (likely(dev))
+ return (unsigned long)dev->archdata.dma_data;
+
+ return PCI_DRAM_OFFSET; /* FIXME Not sure if is correct */
+}
+
+#define NOT_COHERENT_CACHE
+
+static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+#ifdef NOT_COHERENT_CACHE
+ return consistent_alloc(flag, size, dma_handle);
+#else
+ void *ret;
+ struct page *page;
+ int node = dev_to_node(dev);
+
+ /* ignore region specifiers */
+ flag &= ~(__GFP_HIGHMEM);
+
+ page = alloc_pages_node(node, flag, get_order(size));
+ if (page == NULL)
+ return NULL;
+ ret = page_address(page);
+ memset(ret, 0, size);
+ *dma_handle = virt_to_phys(ret) + get_dma_direct_offset(dev);
+
+ return ret;
+#endif
+}
+
+static void dma_direct_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+#ifdef NOT_COHERENT_CACHE
+ consistent_free(vaddr);
+#else
+ free_pages((unsigned long)vaddr, get_order(size));
+#endif
+}
+
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct scatterlist *sg;
+ int i;
+
+ /* FIXME this part of code is untested */
+ for_each_sg(sgl, sg, nents, i) {
+ sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
+ sg->dma_length = sg->length;
+ __dma_sync_page(page_to_phys(sg_page(sg)), sg->offset,
+ sg->length, direction);
+ }
+
+ return nents;
+}
+
+static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+}
+
+static int dma_direct_dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+
+static inline dma_addr_t dma_direct_map_page(struct device *dev,
+ struct page *page,
+ unsigned long offset,
+ size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ __dma_sync_page(page_to_phys(page), offset, size, direction);
+ return page_to_phys(page) + offset + get_dma_direct_offset(dev);
+}
+
+static inline void dma_direct_unmap_page(struct device *dev,
+ dma_addr_t dma_address,
+ size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+/* There is not necessary to do cache cleanup
+ *
+ * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and
+ * dma_address is physical address
+ */
+ __dma_sync_page(dma_address, 0 , size, direction);
+}
+
+struct dma_map_ops dma_direct_ops = {
+ .alloc_coherent = dma_direct_alloc_coherent,
+ .free_coherent = dma_direct_free_coherent,
+ .map_sg = dma_direct_map_sg,
+ .unmap_sg = dma_direct_unmap_sg,
+ .dma_supported = dma_direct_dma_supported,
+ .map_page = dma_direct_map_page,
+ .unmap_page = dma_direct_unmap_page,
+};
+EXPORT_SYMBOL(dma_direct_ops);
+
+/* Number of entries preallocated for DMA-API debugging */
+#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+
+static int __init dma_init(void)
+{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+ return 0;
+}
+fs_initcall(dma_init);
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 3bad4ff4947..c0ede25c5b9 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -305,7 +305,7 @@ C_ENTRY(_user_exception):
swi r11, r1, PTO+PT_R1; /* Store user SP. */
addi r11, r0, 1;
swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode. */
-2: lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
+2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
/* Save away the syscall number. */
swi r12, r1, PTO+PT_R0;
tovirt(r1,r1)
@@ -322,8 +322,7 @@ C_ENTRY(_user_exception):
rtid r11, 0
nop
3:
- add r11, r0, CURRENT_TASK /* Get current task ptr into r11 */
- lwi r11, r11, TS_THREAD_INFO /* get thread info */
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO /* get thread info */
lwi r11, r11, TI_FLAGS /* get flags in thread info */
andi r11, r11, _TIF_WORK_SYSCALL_MASK
beqi r11, 4f
@@ -382,60 +381,50 @@ C_ENTRY(ret_from_trap):
/* See if returning to kernel mode, if so, skip resched &c. */
bnei r11, 2f;
+ swi r3, r1, PTO + PT_R3
+ swi r4, r1, PTO + PT_R4
+
/* We're returning to user mode, so check for various conditions that
* trigger rescheduling. */
- # FIXME: Restructure all these flag checks.
- add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- lwi r11, r11, TS_THREAD_INFO; /* get thread info */
+ /* FIXME: Restructure all these flag checks. */
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_WORK_SYSCALL_MASK
beqi r11, 1f
- swi r3, r1, PTO + PT_R3
- swi r4, r1, PTO + PT_R4
brlid r15, do_syscall_trace_leave
addik r5, r1, PTO + PT_R0
- lwi r3, r1, PTO + PT_R3
- lwi r4, r1, PTO + PT_R4
1:
-
/* We're returning to user mode, so check for various conditions that
* trigger rescheduling. */
- /* Get current task ptr into r11 */
- add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- lwi r11, r11, TS_THREAD_INFO; /* get thread info */
+ /* get thread info from current task */
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO;
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_NEED_RESCHED;
beqi r11, 5f;
- swi r3, r1, PTO + PT_R3; /* store syscall result */
- swi r4, r1, PTO + PT_R4;
bralid r15, schedule; /* Call scheduler */
nop; /* delay slot */
- lwi r3, r1, PTO + PT_R3; /* restore syscall result */
- lwi r4, r1, PTO + PT_R4;
/* Maybe handle a signal */
-5: add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- lwi r11, r11, TS_THREAD_INFO; /* get thread info */
+5: /* get thread info from current task*/
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO;
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_SIGPENDING;
beqi r11, 1f; /* Signals to handle, handle them */
- swi r3, r1, PTO + PT_R3; /* store syscall result */
- swi r4, r1, PTO + PT_R4;
la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
- add r6, r0, r0; /* Arg 2: sigset_t *oldset */
addi r7, r0, 1; /* Arg 3: int in_syscall */
bralid r15, do_signal; /* Handle any signals */
- nop;
+ add r6, r0, r0; /* Arg 2: sigset_t *oldset */
+
+/* Finally, return to user state. */
+1:
lwi r3, r1, PTO + PT_R3; /* restore syscall result */
lwi r4, r1, PTO + PT_R4;
-/* Finally, return to user state. */
-1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */
- add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+ swi r0, r0, PER_CPU(KM); /* Now officially in user state. */
+ swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
VM_OFF;
tophys(r1,r1);
RESTORE_REGS;
@@ -565,7 +554,7 @@ C_ENTRY(sys_rt_sigreturn_wrapper):
swi r11, r1, PTO+PT_R1; /* Store user SP. */ \
addi r11, r0, 1; \
swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode.*/\
-2: lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
+2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); \
/* Save away the syscall number. */ \
swi r0, r1, PTO+PT_R0; \
tovirt(r1,r1)
@@ -673,9 +662,7 @@ C_ENTRY(ret_from_exc):
/* We're returning to user mode, so check for various conditions that
trigger rescheduling. */
- /* Get current task ptr into r11 */
- add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- lwi r11, r11, TS_THREAD_INFO; /* get thread info */
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_NEED_RESCHED;
beqi r11, 5f;
@@ -685,8 +672,7 @@ C_ENTRY(ret_from_exc):
nop; /* delay slot */
/* Maybe handle a signal */
-5: add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- lwi r11, r11, TS_THREAD_INFO; /* get thread info */
+5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_SIGPENDING;
beqi r11, 1f; /* Signals to handle, handle them */
@@ -705,15 +691,13 @@ C_ENTRY(ret_from_exc):
* store return registers separately because this macros is use
* for others exceptions */
la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
- add r6, r0, r0; /* Arg 2: sigset_t *oldset */
addi r7, r0, 0; /* Arg 3: int in_syscall */
bralid r15, do_signal; /* Handle any signals */
- nop;
+ add r6, r0, r0; /* Arg 2: sigset_t *oldset */
/* Finally, return to user state. */
1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */
- add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+ swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
VM_OFF;
tophys(r1,r1);
@@ -802,7 +786,7 @@ C_ENTRY(_interrupt):
swi r11, r0, TOPHYS(PER_CPU(KM));
2:
- lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
+ lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
swi r0, r1, PTO + PT_R0;
tovirt(r1,r1)
la r5, r1, PTO;
@@ -817,8 +801,7 @@ ret_from_irq:
lwi r11, r1, PTO + PT_MODE;
bnei r11, 2f;
- add r11, r0, CURRENT_TASK;
- lwi r11, r11, TS_THREAD_INFO;
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO;
lwi r11, r11, TI_FLAGS; /* MS: get flags from thread info */
andi r11, r11, _TIF_NEED_RESCHED;
beqi r11, 5f
@@ -826,8 +809,7 @@ ret_from_irq:
nop; /* delay slot */
/* Maybe handle a signal */
-5: add r11, r0, CURRENT_TASK;
- lwi r11, r11, TS_THREAD_INFO; /* MS: get thread info */
+5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_SIGPENDING;
beqid r11, no_intr_resched
@@ -842,8 +824,7 @@ no_intr_resched:
/* Disable interrupts, we are now committed to the state restore */
disable_irq
swi r0, r0, PER_CPU(KM); /* MS: Now officially in user state. */
- add r11, r0, CURRENT_TASK;
- swi r11, r0, PER_CPU(CURRENT_SAVE);
+ swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE);
VM_OFF;
tophys(r1,r1);
lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
@@ -853,7 +834,28 @@ no_intr_resched:
lwi r1, r1, PT_R1 - PT_SIZE;
bri 6f;
/* MS: Return to kernel state. */
-2: VM_OFF /* MS: turn off MMU */
+2:
+#ifdef CONFIG_PREEMPT
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO;
+ /* MS: get preempt_count from thread info */
+ lwi r5, r11, TI_PREEMPT_COUNT;
+ bgti r5, restore;
+
+ lwi r5, r11, TI_FLAGS; /* get flags in thread info */
+ andi r5, r5, _TIF_NEED_RESCHED;
+ beqi r5, restore /* if zero jump over */
+
+preempt:
+ /* interrupts are off that's why I am calling preempt_chedule_irq */
+ bralid r15, preempt_schedule_irq
+ nop
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
+ lwi r5, r11, TI_FLAGS; /* get flags in thread info */
+ andi r5, r5, _TIF_NEED_RESCHED;
+ bnei r5, preempt /* if non zero jump to resched */
+restore:
+#endif
+ VM_OFF /* MS: turn off MMU */
tophys(r1,r1)
lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
lwi r4, r1, PTO + PT_R4;
@@ -915,7 +917,7 @@ C_ENTRY(_debug_exception):
swi r11, r1, PTO+PT_R1; /* Store user SP. */
addi r11, r0, 1;
swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode. */
-2: lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
+2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
/* Save away the syscall number. */
swi r0, r1, PTO+PT_R0;
tovirt(r1,r1)
@@ -935,8 +937,7 @@ dbtrap_call: rtbd r11, 0;
bnei r11, 2f;
/* Get current task ptr into r11 */
- add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- lwi r11, r11, TS_THREAD_INFO; /* get thread info */
+ lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_NEED_RESCHED;
beqi r11, 5f;
@@ -949,8 +950,7 @@ dbtrap_call: rtbd r11, 0;
/* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here. */
/* Maybe handle a signal */
-5: add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- lwi r11, r11, TS_THREAD_INFO; /* get thread info */
+5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_SIGPENDING;
beqi r11, 1f; /* Signals to handle, handle them */
@@ -966,16 +966,14 @@ dbtrap_call: rtbd r11, 0;
(in a possibly modified form) after do_signal returns. */
la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
- add r6, r0, r0; /* Arg 2: sigset_t *oldset */
addi r7, r0, 0; /* Arg 3: int in_syscall */
bralid r15, do_signal; /* Handle any signals */
- nop;
+ add r6, r0, r0; /* Arg 2: sigset_t *oldset */
/* Finally, return to user state. */
1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */
- add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
- swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+ swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
VM_OFF;
tophys(r1,r1);
@@ -1007,7 +1005,7 @@ DBTRAP_return: /* Make global symbol for debugging */
ENTRY(_switch_to)
/* prepare return value */
- addk r3, r0, r31
+ addk r3, r0, CURRENT_TASK
/* save registers in cpu_context */
/* use r11 and r12, volatile registers, as temp register */
@@ -1051,10 +1049,10 @@ ENTRY(_switch_to)
nop
swi r12, r11, CC_FSR
- /* update r31, the current */
- lwi r31, r6, TI_TASK/* give me pointer to task which will be next */
+ /* update r31, the current-give me pointer to task which will be next */
+ lwi CURRENT_TASK, r6, TI_TASK
/* stored it to current_save too */
- swi r31, r0, PER_CPU(CURRENT_SAVE)
+ swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE)
/* get new process' cpu context and restore */
/* give me start where start context of next task */
diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c
index 388b31ca65a..515feb40455 100644
--- a/arch/microblaze/kernel/ftrace.c
+++ b/arch/microblaze/kernel/ftrace.c
@@ -151,13 +151,10 @@ int ftrace_make_nop(struct module *mod,
return ret;
}
-static int ret_addr; /* initialized as 0 by default */
-
/* I believe that first is called ftrace_make_nop before this function */
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
int ret;
- ret_addr = addr; /* saving where the barrier jump is */
pr_debug("%s: addr:0x%x, rec->ip: 0x%x, imm:0x%x\n",
__func__, (unsigned int)addr, (unsigned int)rec->ip, imm);
ret = ftrace_modify_code(rec->ip, imm);
@@ -194,12 +191,9 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
ret = ftrace_modify_code(ip, upper);
ret += ftrace_modify_code(ip + 4, lower);
- /* We just need to remove the rtsd r15, 8 by NOP */
- BUG_ON(!ret_addr);
- if (ret_addr)
- ret += ftrace_modify_code(ret_addr, MICROBLAZE_NOP);
- else
- ret = 1; /* fault */
+ /* We just need to replace the rtsd r15, 8 with NOP */
+ ret += ftrace_modify_code((unsigned long)&ftrace_caller,
+ MICROBLAZE_NOP);
/* All changes are done - lets do caches consistent */
flush_icache();
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index 30916193fcc..da6a5f5dc76 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -51,6 +51,12 @@ swapper_pg_dir:
.text
ENTRY(_start)
+#if CONFIG_KERNEL_BASE_ADDR == 0
+ brai TOPHYS(real_start)
+ .org 0x100
+real_start:
+#endif
+
mfs r1, rmsr
andi r1, r1, ~2
mts rmsr, r1
@@ -99,8 +105,8 @@ no_fdt_arg:
tophys(r4,r4) /* convert to phys address */
ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */
_copy_command_line:
- lbu r7, r5, r6 /* r7=r5+r6 - r5 contain pointer to command line */
- sb r7, r4, r6 /* addr[r4+r6]= r7*/
+ lbu r2, r5, r6 /* r2=r5+r6 - r5 contain pointer to command line */
+ sb r2, r4, r6 /* addr[r4+r6]= r2*/
addik r6, r6, 1 /* increment counting */
bgtid r3, _copy_command_line /* loop for all entries */
addik r3, r3, -1 /* descrement loop */
@@ -128,7 +134,7 @@ _copy_bram:
* virtual to physical.
*/
nop
- addik r3, r0, 63 /* Invalidate all TLB entries */
+ addik r3, r0, MICROBLAZE_TLB_SIZE -1 /* Invalidate all TLB entries */
_invalidate:
mts rtlbx, r3
mts rtlbhi, r0 /* flush: ensure V is clear */
@@ -136,6 +142,11 @@ _invalidate:
addik r3, r3, -1
/* sync */
+ /* Setup the kernel PID */
+ mts rpid,r0 /* Load the kernel PID */
+ nop
+ bri 4
+
/*
* We should still be executing code at physical address area
* RAM_BASEADDR at this point. However, kernel code is at
@@ -146,10 +157,6 @@ _invalidate:
addik r3,r0, CONFIG_KERNEL_START /* Load the kernel virtual address */
tophys(r4,r3) /* Load the kernel physical address */
- mts rpid,r0 /* Load the kernel PID */
- nop
- bri 4
-
/*
* Configure and load two entries into TLB slots 0 and 1.
* In case we are pinning TLBs, these are reserved in by the
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 2b86c03aa84..995a2123635 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -313,13 +313,13 @@ _hw_exception_handler:
mfs r5, rmsr;
nop
swi r5, r1, 0;
- mfs r3, resr
+ mfs r4, resr
nop
- mfs r4, rear;
+ mfs r3, rear;
nop
#ifndef CONFIG_MMU
- andi r5, r3, 0x1000; /* Check ESR[DS] */
+ andi r5, r4, 0x1000; /* Check ESR[DS] */
beqi r5, not_in_delay_slot; /* Branch if ESR[DS] not set */
mfs r17, rbtr; /* ESR[DS] set - return address in BTR */
nop
@@ -327,13 +327,14 @@ not_in_delay_slot:
swi r17, r1, PT_R17
#endif
- andi r5, r3, 0x1F; /* Extract ESR[EXC] */
+ andi r5, r4, 0x1F; /* Extract ESR[EXC] */
#ifdef CONFIG_MMU
/* Calculate exception vector offset = r5 << 2 */
addk r6, r5, r5; /* << 1 */
addk r6, r6, r6; /* << 2 */
+#ifdef DEBUG
/* counting which exception happen */
lwi r5, r0, 0x200 + TOPHYS(r0_ram)
addi r5, r5, 1
@@ -341,6 +342,7 @@ not_in_delay_slot:
lwi r5, r6, 0x200 + TOPHYS(r0_ram)
addi r5, r5, 1
swi r5, r6, 0x200 + TOPHYS(r0_ram)
+#endif
/* end */
/* Load the HW Exception vector */
lwi r6, r6, TOPHYS(_MB_HW_ExceptionVectorTable)
@@ -376,7 +378,7 @@ handle_other_ex: /* Handle Other exceptions here */
swi r18, r1, PT_R18
or r5, r1, r0
- andi r6, r3, 0x1F; /* Load ESR[EC] */
+ andi r6, r4, 0x1F; /* Load ESR[EC] */
lwi r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */
swi r7, r1, PT_MODE
mfs r7, rfsr
@@ -426,11 +428,11 @@ handle_other_ex: /* Handle Other exceptions here */
*/
handle_unaligned_ex:
/* Working registers already saved: R3, R4, R5, R6
- * R3 = ESR
- * R4 = EAR
+ * R4 = ESR
+ * R3 = EAR
*/
#ifdef CONFIG_MMU
- andi r6, r3, 0x1000 /* Check ESR[DS] */
+ andi r6, r4, 0x1000 /* Check ESR[DS] */
beqi r6, _no_delayslot /* Branch if ESR[DS] not set */
mfs r17, rbtr; /* ESR[DS] set - return address in BTR */
nop
@@ -439,7 +441,7 @@ _no_delayslot:
RESTORE_STATE;
bri unaligned_data_trap
#endif
- andi r6, r3, 0x3E0; /* Mask and extract the register operand */
+ andi r6, r4, 0x3E0; /* Mask and extract the register operand */
srl r6, r6; /* r6 >> 5 */
srl r6, r6;
srl r6, r6;
@@ -448,33 +450,33 @@ _no_delayslot:
/* Store the register operand in a temporary location */
sbi r6, r0, TOPHYS(ex_reg_op);
- andi r6, r3, 0x400; /* Extract ESR[S] */
+ andi r6, r4, 0x400; /* Extract ESR[S] */
bnei r6, ex_sw;
ex_lw:
- andi r6, r3, 0x800; /* Extract ESR[W] */
+ andi r6, r4, 0x800; /* Extract ESR[W] */
beqi r6, ex_lhw;
- lbui r5, r4, 0; /* Exception address in r4 */
+ lbui r5, r3, 0; /* Exception address in r3 */
/* Load a word, byte-by-byte from destination address
and save it in tmp space */
sbi r5, r0, TOPHYS(ex_tmp_data_loc_0);
- lbui r5, r4, 1;
+ lbui r5, r3, 1;
sbi r5, r0, TOPHYS(ex_tmp_data_loc_1);
- lbui r5, r4, 2;
+ lbui r5, r3, 2;
sbi r5, r0, TOPHYS(ex_tmp_data_loc_2);
- lbui r5, r4, 3;
+ lbui r5, r3, 3;
sbi r5, r0, TOPHYS(ex_tmp_data_loc_3);
- /* Get the destination register value into r3 */
- lwi r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ /* Get the destination register value into r4 */
+ lwi r4, r0, TOPHYS(ex_tmp_data_loc_0);
bri ex_lw_tail;
ex_lhw:
- lbui r5, r4, 0; /* Exception address in r4 */
+ lbui r5, r3, 0; /* Exception address in r3 */
/* Load a half-word, byte-by-byte from destination
address and save it in tmp space */
sbi r5, r0, TOPHYS(ex_tmp_data_loc_0);
- lbui r5, r4, 1;
+ lbui r5, r3, 1;
sbi r5, r0, TOPHYS(ex_tmp_data_loc_1);
- /* Get the destination register value into r3 */
- lhui r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ /* Get the destination register value into r4 */
+ lhui r4, r0, TOPHYS(ex_tmp_data_loc_0);
ex_lw_tail:
/* Get the destination register number into r5 */
lbui r5, r0, TOPHYS(ex_reg_op);
@@ -502,25 +504,25 @@ ex_sw_tail:
andi r6, r6, 0x800; /* Extract ESR[W] */
beqi r6, ex_shw;
/* Get the word - delay slot */
- swi r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ swi r4, r0, TOPHYS(ex_tmp_data_loc_0);
/* Store the word, byte-by-byte into destination address */
- lbui r3, r0, TOPHYS(ex_tmp_data_loc_0);
- sbi r3, r4, 0;
- lbui r3, r0, TOPHYS(ex_tmp_data_loc_1);
- sbi r3, r4, 1;
- lbui r3, r0, TOPHYS(ex_tmp_data_loc_2);
- sbi r3, r4, 2;
- lbui r3, r0, TOPHYS(ex_tmp_data_loc_3);
- sbi r3, r4, 3;
+ lbui r4, r0, TOPHYS(ex_tmp_data_loc_0);
+ sbi r4, r3, 0;
+ lbui r4, r0, TOPHYS(ex_tmp_data_loc_1);
+ sbi r4, r3, 1;
+ lbui r4, r0, TOPHYS(ex_tmp_data_loc_2);
+ sbi r4, r3, 2;
+ lbui r4, r0, TOPHYS(ex_tmp_data_loc_3);
+ sbi r4, r3, 3;
bri ex_handler_done;
ex_shw:
/* Store the lower half-word, byte-by-byte into destination address */
- swi r3, r0, TOPHYS(ex_tmp_data_loc_0);
- lbui r3, r0, TOPHYS(ex_tmp_data_loc_2);
- sbi r3, r4, 0;
- lbui r3, r0, TOPHYS(ex_tmp_data_loc_3);
- sbi r3, r4, 1;
+ swi r4, r0, TOPHYS(ex_tmp_data_loc_0);
+ lbui r4, r0, TOPHYS(ex_tmp_data_loc_2);
+ sbi r4, r3, 0;
+ lbui r4, r0, TOPHYS(ex_tmp_data_loc_3);
+ sbi r4, r3, 1;
ex_sw_end: /* Exception handling of store word, ends. */
ex_handler_done:
@@ -560,21 +562,16 @@ ex_handler_done:
*/
mfs r11, rpid
nop
- bri 4
- mfs r3, rear /* Get faulting address */
- nop
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
- ori r4, r0, CONFIG_KERNEL_START
- cmpu r4, r3, r4
- bgti r4, ex3
+ ori r5, r0, CONFIG_KERNEL_START
+ cmpu r5, r3, r5
+ bgti r5, ex3
/* First, check if it was a zone fault (which means a user
* tried to access a kernel or read-protected page - always
* a SEGV). All other faults here must be stores, so no
* need to check ESR_S as well. */
- mfs r4, resr
- nop
andi r4, r4, 0x800 /* ESR_Z - zone protection */
bnei r4, ex2
@@ -589,8 +586,6 @@ ex_handler_done:
* tried to access a kernel or read-protected page - always
* a SEGV). All other faults here must be stores, so no
* need to check ESR_S as well. */
- mfs r4, resr
- nop
andi r4, r4, 0x800 /* ESR_Z */
bnei r4, ex2
/* get current task address */
@@ -665,8 +660,6 @@ ex_handler_done:
* R3 = ESR
*/
- mfs r3, rear /* Get faulting address */
- nop
RESTORE_STATE;
bri page_fault_instr_trap
@@ -677,18 +670,15 @@ ex_handler_done:
*/
handle_data_tlb_miss_exception:
/* Working registers already saved: R3, R4, R5, R6
- * R3 = ESR
+ * R3 = EAR, R4 = ESR
*/
mfs r11, rpid
nop
- bri 4
- mfs r3, rear /* Get faulting address */
- nop
/* If we are faulting a kernel address, we have to use the
* kernel page tables. */
- ori r4, r0, CONFIG_KERNEL_START
- cmpu r4, r3, r4
+ ori r6, r0, CONFIG_KERNEL_START
+ cmpu r4, r3, r6
bgti r4, ex5
ori r4, r0, swapper_pg_dir
mts rpid, r0 /* TLB will have 0 TID */
@@ -731,9 +721,8 @@ ex_handler_done:
* Many of these bits are software only. Bits we don't set
* here we (properly should) assume have the appropriate value.
*/
+ brid finish_tlb_load
andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */
-
- bri finish_tlb_load
ex7:
/* The bailout. Restore registers to pre-exception conditions
* and call the heavyweights to help us out.
@@ -754,9 +743,6 @@ ex_handler_done:
*/
mfs r11, rpid
nop
- bri 4
- mfs r3, rear /* Get faulting address */
- nop
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
@@ -792,7 +778,7 @@ ex_handler_done:
lwi r4, r5, 0 /* Get Linux PTE */
andi r6, r4, _PAGE_PRESENT
- beqi r6, ex7
+ beqi r6, ex10
ori r4, r4, _PAGE_ACCESSED
swi r4, r5, 0
@@ -805,9 +791,8 @@ ex_handler_done:
* Many of these bits are software only. Bits we don't set
* here we (properly should) assume have the appropriate value.
*/
+ brid finish_tlb_load
andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */
-
- bri finish_tlb_load
ex10:
/* The bailout. Restore registers to pre-exception conditions
* and call the heavyweights to help us out.
@@ -837,9 +822,9 @@ ex_handler_done:
andi r5, r5, (MICROBLAZE_TLB_SIZE-1)
ori r6, r0, 1
cmp r31, r5, r6
- blti r31, sem
+ blti r31, ex12
addik r5, r6, 1
- sem:
+ ex12:
/* MS: save back current TLB index */
swi r5, r0, TOPHYS(tlb_index)
@@ -859,7 +844,6 @@ ex_handler_done:
nop
/* Done...restore registers and get out of here. */
- ex12:
mts rpid, r11
nop
bri 4
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index 0f06034d1fe..6f39e2c001f 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -93,3 +93,18 @@ skip:
}
return 0;
}
+
+/* MS: There is no any advance mapping mechanism. We are using simple 32bit
+ intc without any cascades or any connection that's why mapping is 1:1 */
+unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
+{
+ return hwirq;
+}
+EXPORT_SYMBOL_GPL(irq_create_mapping);
+
+unsigned int irq_create_of_mapping(struct device_node *controller,
+ u32 *intspec, unsigned int intsize)
+{
+ return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff --git a/arch/microblaze/kernel/misc.S b/arch/microblaze/kernel/misc.S
index df16c6287a8..7cf86498326 100644
--- a/arch/microblaze/kernel/misc.S
+++ b/arch/microblaze/kernel/misc.S
@@ -26,9 +26,10 @@
* We avoid flushing the pinned 0, 1 and possibly 2 entries.
*/
.globl _tlbia;
+.type _tlbia, @function
.align 4;
_tlbia:
- addik r12, r0, 63 /* flush all entries (63 - 3) */
+ addik r12, r0, MICROBLAZE_TLB_SIZE - 1 /* flush all entries (63 - 3) */
/* isync */
_tlbia_1:
mts rtlbx, r12
@@ -41,11 +42,13 @@ _tlbia_1:
/* sync */
rtsd r15, 8
nop
+ .size _tlbia, . - _tlbia
/*
* Flush MMU TLB for a particular address (in r5)
*/
.globl _tlbie;
+.type _tlbie, @function
.align 4;
_tlbie:
mts rtlbsx, r5 /* look up the address in TLB */
@@ -59,17 +62,20 @@ _tlbie_1:
rtsd r15, 8
nop
+ .size _tlbie, . - _tlbie
+
/*
* Allocate TLB entry for early console
*/
.globl early_console_reg_tlb_alloc;
+.type early_console_reg_tlb_alloc, @function
.align 4;
early_console_reg_tlb_alloc:
/*
* Load a TLB entry for the UART, so that microblaze_progress() can use
* the UARTs nice and early. We use a 4k real==virtual mapping.
*/
- ori r4, r0, 63
+ ori r4, r0, MICROBLAZE_TLB_SIZE - 1
mts rtlbx, r4 /* TLB slot 2 */
or r4,r5,r0
@@ -86,6 +92,8 @@ early_console_reg_tlb_alloc:
rtsd r15, 8
nop
+ .size early_console_reg_tlb_alloc, . - early_console_reg_tlb_alloc
+
/*
* Copy a whole page (4096 bytes).
*/
@@ -104,6 +112,7 @@ early_console_reg_tlb_alloc:
#define DCACHE_LINE_BYTES (4 * 4)
.globl copy_page;
+.type copy_page, @function
.align 4;
copy_page:
ori r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1
@@ -118,3 +127,5 @@ _copy_page_loop:
addik r11, r11, -1
rtsd r15, 8
nop
+
+ .size copy_page, . - copy_page
diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c
index 5a45b1adfef..cbecf110dc3 100644
--- a/arch/microblaze/kernel/module.c
+++ b/arch/microblaze/kernel/module.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/string.h>
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c
index 1c6d684996d..0dc755286d3 100644
--- a/arch/microblaze/kernel/of_platform.c
+++ b/arch/microblaze/kernel/of_platform.c
@@ -17,7 +17,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/of.h>
#include <linux/of_device.h>
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 812f1bf06c9..09bed44dfcd 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -15,6 +15,7 @@
#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/pgalloc.h>
+#include <asm/uaccess.h> /* for USER_DS macros */
#include <asm/cacheflush.h>
void show_regs(struct pt_regs *regs)
@@ -74,7 +75,10 @@ __setup("hlt", hlt_setup);
void default_idle(void)
{
- if (!hlt_counter) {
+ if (likely(hlt_counter)) {
+ while (!need_resched())
+ cpu_relax();
+ } else {
clear_thread_flag(TIF_POLLING_NRFLAG);
smp_mb__after_clear_bit();
local_irq_disable();
@@ -82,9 +86,7 @@ void default_idle(void)
cpu_sleep();
local_irq_enable();
set_thread_flag(TIF_POLLING_NRFLAG);
- } else
- while (!need_resched())
- cpu_relax();
+ }
}
void cpu_idle(void)
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index 4b3ac32754d..a4a7770c614 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -75,29 +75,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
int rval;
unsigned long val = 0;
- unsigned long copied;
switch (request) {
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA:
- pr_debug("PEEKTEXT/PEEKDATA at %08lX\n", addr);
- copied = access_process_vm(child, addr, &val, sizeof(val), 0);
- rval = -EIO;
- if (copied != sizeof(val))
- break;
- rval = put_user(val, (unsigned long *)data);
- break;
-
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- pr_debug("POKETEXT/POKEDATA to %08lX\n", addr);
- rval = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1)
- == sizeof(data))
- break;
- rval = -EIO;
- break;
-
/* Read/write the word at location ADDR in the registers. */
case PTRACE_PEEKUSR:
case PTRACE_POKEUSR:
@@ -130,50 +109,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (rval == 0 && request == PTRACE_PEEKUSR)
rval = put_user(val, (unsigned long *)data);
break;
- /* Continue and stop at next (return from) syscall */
- case PTRACE_SYSCALL:
- pr_debug("PTRACE_SYSCALL\n");
- case PTRACE_SINGLESTEP:
- pr_debug("PTRACE_SINGLESTEP\n");
- /* Restart after a signal. */
- case PTRACE_CONT:
- pr_debug("PTRACE_CONT\n");
- rval = -EIO;
- if (!valid_signal(data))
- break;
-
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-
- child->exit_code = data;
- pr_debug("wakeup_process\n");
- wake_up_process(child);
- rval = 0;
- break;
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL:
- pr_debug("PTRACE_KILL\n");
- rval = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- wake_up_process(child);
- break;
-
- case PTRACE_DETACH: /* detach a process that was attached. */
- pr_debug("PTRACE_DETACH\n");
- rval = ptrace_detach(child, data);
- break;
default:
- /* rval = ptrace_request(child, request, addr, data); noMMU */
- rval = -EIO;
+ rval = ptrace_request(child, request, addr, data);
}
return rval;
}
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index bb8c4b9ccb8..17c98dbcec8 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -22,7 +22,10 @@
#include <linux/io.h>
#include <linux/bug.h>
#include <linux/param.h>
+#include <linux/pci.h>
#include <linux/cache.h>
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
#include <asm/cacheflush.h>
#include <asm/entry.h>
#include <asm/cpuinfo.h>
@@ -54,14 +57,10 @@ void __init setup_arch(char **cmdline_p)
microblaze_cache_init();
- invalidate_dcache();
- enable_dcache();
-
- invalidate_icache();
- enable_icache();
-
setup_memory();
+ xilinx_pci_init();
+
#if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
printk(KERN_NOTICE "Self modified code enable\n");
#endif
@@ -93,6 +92,12 @@ inline unsigned get_romfs_len(unsigned *addr)
}
#endif /* CONFIG_MTD_UCLINUX_EBSS */
+#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
+#define eprintk early_printk
+#else
+#define eprintk printk
+#endif
+
void __init machine_early_init(const char *cmdline, unsigned int ram,
unsigned int fdt, unsigned int msr)
{
@@ -140,32 +145,32 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
setup_early_printk(NULL);
#endif
- early_printk("Ramdisk addr 0x%08x, ", ram);
+ eprintk("Ramdisk addr 0x%08x, ", ram);
if (fdt)
- early_printk("FDT at 0x%08x\n", fdt);
+ eprintk("FDT at 0x%08x\n", fdt);
else
- early_printk("Compiled-in FDT at 0x%08x\n",
+ eprintk("Compiled-in FDT at 0x%08x\n",
(unsigned int)_fdt_start);
#ifdef CONFIG_MTD_UCLINUX
- early_printk("Found romfs @ 0x%08x (0x%08x)\n",
+ eprintk("Found romfs @ 0x%08x (0x%08x)\n",
romfs_base, romfs_size);
- early_printk("#### klimit %p ####\n", old_klimit);
+ eprintk("#### klimit %p ####\n", old_klimit);
BUG_ON(romfs_size < 0); /* What else can we do? */
- early_printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
+ eprintk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
romfs_size, romfs_base, (unsigned)&_ebss);
- early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
+ eprintk("New klimit: 0x%08x\n", (unsigned)klimit);
#endif
#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
if (msr)
- early_printk("!!!Your kernel has setup MSR instruction but "
+ eprintk("!!!Your kernel has setup MSR instruction but "
"CPU don't have it %d\n", msr);
#else
if (!msr)
- early_printk("!!!Your kernel not setup MSR instruction but "
+ eprintk("!!!Your kernel not setup MSR instruction but "
"CPU have it %d\n", msr);
#endif
@@ -188,3 +193,37 @@ static int microblaze_debugfs_init(void)
}
arch_initcall(microblaze_debugfs_init);
#endif
+
+static int dflt_bus_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+
+ /* We are only intereted in device addition */
+ if (action != BUS_NOTIFY_ADD_DEVICE)
+ return 0;
+
+ set_dma_ops(dev, &dma_direct_ops);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block dflt_plat_bus_notifier = {
+ .notifier_call = dflt_bus_notify,
+ .priority = INT_MAX,
+};
+
+static struct notifier_block dflt_of_bus_notifier = {
+ .notifier_call = dflt_bus_notify,
+ .priority = INT_MAX,
+};
+
+static int __init setup_bus_notifier(void)
+{
+ bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier);
+ bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier);
+
+ return 0;
+}
+
+arch_initcall(setup_bus_notifier);
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index 9f3c205fb75..f4e00b7f125 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -30,6 +30,7 @@
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>
+#include <linux/slab.h>
#include <asm/syscalls.h>
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c
index eaaaf805f31..5e4570ef515 100644
--- a/arch/microblaze/kernel/traps.c
+++ b/arch/microblaze/kernel/traps.c
@@ -22,13 +22,11 @@ void trap_init(void)
__enable_hw_exceptions();
}
-static int kstack_depth_to_print = 24;
+static unsigned long kstack_depth_to_print = 24;
static int __init kstack_setup(char *s)
{
- kstack_depth_to_print = strict_strtoul(s, 0, NULL);
-
- return 1;
+ return !strict_strtoul(s, 0, &kstack_depth_to_print);
}
__setup("kstack=", kstack_setup);
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index b579db068c0..4dfe47d3cd9 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -10,5 +10,4 @@ else
lib-y += memcpy.o memmove.o
endif
-lib-$(CONFIG_NO_MMU) += uaccess.o
-lib-$(CONFIG_MMU) += uaccess_old.o
+lib-y += uaccess_old.o
diff --git a/arch/microblaze/lib/fastcopy.S b/arch/microblaze/lib/fastcopy.S
index 02e3ab4eddf..fdc48bb065d 100644
--- a/arch/microblaze/lib/fastcopy.S
+++ b/arch/microblaze/lib/fastcopy.S
@@ -30,8 +30,9 @@
*/
#include <linux/linkage.h>
-
+ .text
.globl memcpy
+ .type memcpy, @function
.ent memcpy
memcpy:
@@ -345,9 +346,11 @@ a_done:
rtsd r15, 8
nop
+.size memcpy, . - memcpy
.end memcpy
/*----------------------------------------------------------------------------*/
.globl memmove
+ .type memmove, @function
.ent memmove
memmove:
@@ -659,4 +662,5 @@ d_done:
rtsd r15, 8
nop
+.size memmove, . - memmove
.end memmove
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
index cc2108b6b26..014bac92bdf 100644
--- a/arch/microblaze/lib/memcpy.c
+++ b/arch/microblaze/lib/memcpy.c
@@ -53,7 +53,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
const uint32_t *i_src;
uint32_t *i_dst;
- if (c >= 4) {
+ if (likely(c >= 4)) {
unsigned value, buf_hold;
/* Align the dstination to a word boundry. */
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
index 4df851d41a2..ecfb663e1fc 100644
--- a/arch/microblaze/lib/memset.c
+++ b/arch/microblaze/lib/memset.c
@@ -33,22 +33,23 @@
#ifdef __HAVE_ARCH_MEMSET
void *memset(void *v_src, int c, __kernel_size_t n)
{
-
char *src = v_src;
#ifdef CONFIG_OPT_LIB_FUNCTION
uint32_t *i_src;
- uint32_t w32;
+ uint32_t w32 = 0;
#endif
/* Truncate c to 8 bits */
c = (c & 0xFF);
#ifdef CONFIG_OPT_LIB_FUNCTION
- /* Make a repeating word out of it */
- w32 = c;
- w32 |= w32 << 8;
- w32 |= w32 << 16;
+ if (unlikely(c)) {
+ /* Make a repeating word out of it */
+ w32 = c;
+ w32 |= w32 << 8;
+ w32 |= w32 << 16;
+ }
- if (n >= 4) {
+ if (likely(n >= 4)) {
/* Align the destination to a word boundary */
/* This is done in an endian independant manner */
switch ((unsigned) src & 3) {
diff --git a/arch/microblaze/lib/uaccess.c b/arch/microblaze/lib/uaccess.c
deleted file mode 100644
index a853fe089c4..00000000000
--- a/arch/microblaze/lib/uaccess.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/string.h>
-#include <asm/uaccess.h>
-
-#include <asm/bug.h>
-
-long strnlen_user(const char __user *src, long count)
-{
- return strlen(src) + 1;
-}
-
-#define __do_strncpy_from_user(dst, src, count, res) \
- do { \
- char *tmp; \
- strncpy(dst, src, count); \
- for (tmp = dst; *tmp && count > 0; tmp++, count--) \
- ; \
- res = (tmp - dst); \
- } while (0)
-
-long __strncpy_from_user(char *dst, const char __user *src, long count)
-{
- long res;
- __do_strncpy_from_user(dst, src, count, res);
- return res;
-}
-
-long strncpy_from_user(char *dst, const char __user *src, long count)
-{
- long res = -EFAULT;
- if (access_ok(VERIFY_READ, src, 1))
- __do_strncpy_from_user(dst, src, count, res);
- return res;
-}
-
-unsigned long __copy_tofrom_user(void __user *to,
- const void __user *from, unsigned long size)
-{
- memcpy(to, from, size);
- return 0;
-}
diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S
index 67f991c14b8..5810cec54a7 100644
--- a/arch/microblaze/lib/uaccess_old.S
+++ b/arch/microblaze/lib/uaccess_old.S
@@ -22,6 +22,7 @@
.text
.globl __strncpy_user;
+.type __strncpy_user, @function
.align 4;
__strncpy_user:
@@ -50,7 +51,7 @@ __strncpy_user:
3:
rtsd r15,8
nop
-
+ .size __strncpy_user, . - __strncpy_user
.section .fixup, "ax"
.align 2
@@ -72,6 +73,7 @@ __strncpy_user:
.text
.globl __strnlen_user;
+.type __strnlen_user, @function
.align 4;
__strnlen_user:
addik r3,r6,0
@@ -90,7 +92,7 @@ __strnlen_user:
3:
rtsd r15,8
nop
-
+ .size __strnlen_user, . - __strnlen_user
.section .fixup,"ax"
4:
@@ -108,6 +110,7 @@ __strnlen_user:
*/
.text
.globl __copy_tofrom_user;
+.type __copy_tofrom_user, @function
.align 4;
__copy_tofrom_user:
/*
@@ -116,20 +119,34 @@ __copy_tofrom_user:
* r7, r3 - count
* r4 - tempval
*/
- addik r3,r7,0
- beqi r3,3f
-1:
- lbu r4,r6,r0
- addik r6,r6,1
-2:
- sb r4,r5,r0
- addik r3,r3,-1
- bneid r3,1b
- addik r5,r5,1 /* delay slot */
+ beqid r7, 3f /* zero size is not likely */
+ andi r3, r7, 0x3 /* filter add count */
+ bneid r3, 4f /* if is odd value then byte copying */
+ or r3, r5, r6 /* find if is any to/from unaligned */
+ andi r3, r3, 0x3 /* mask unaligned */
+ bneid r3, 1f /* it is unaligned -> then jump */
+ or r3, r0, r0
+
+/* at least one 4 byte copy */
+5: lw r4, r6, r3
+6: sw r4, r5, r3
+ addik r7, r7, -4
+ bneid r7, 5b
+ addik r3, r3, 4
+ addik r3, r7, 0
+ rtsd r15, 8
+ nop
+4: or r3, r0, r0
+1: lbu r4,r6,r3
+2: sb r4,r5,r3
+ addik r7,r7,-1
+ bneid r7,1b
+ addik r3,r3,1 /* delay slot */
3:
+ addik r3,r7,0
rtsd r15,8
nop
-
+ .size __copy_tofrom_user, . - __copy_tofrom_user
.section __ex_table,"a"
- .word 1b,3b,2b,3b
+ .word 1b,3b,2b,3b,5b,3b,6b,3b
diff --git a/arch/microblaze/mm/Makefile b/arch/microblaze/mm/Makefile
index 6c8a924d9e2..09c49ed8723 100644
--- a/arch/microblaze/mm/Makefile
+++ b/arch/microblaze/mm/Makefile
@@ -2,6 +2,6 @@
# Makefile
#
-obj-y := init.o
+obj-y := consistent.o init.o
obj-$(CONFIG_MMU) += pgtable.o mmu_context.o fault.o
diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c
new file mode 100644
index 00000000000..f956e24fe49
--- /dev/null
+++ b/arch/microblaze/mm/consistent.c
@@ -0,0 +1,247 @@
+/*
+ * Microblaze support for cache consistent memory.
+ * Copyright (C) 2010 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2010 PetaLogix
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * Based on PowerPC version derived from arch/arm/mm/consistent.c
+ * Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#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/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/gfp.h>
+
+#include <asm/pgalloc.h>
+#include <linux/io.h>
+#include <linux/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/mmu.h>
+#include <linux/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/cpuinfo.h>
+
+#ifndef CONFIG_MMU
+
+/* I have to use dcache values because I can't relate on ram size */
+#define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1)
+
+/*
+ * Consistent memory allocators. Used for DMA devices that want to
+ * share uncached memory with the processor core.
+ * My crufty no-MMU approach is simple. In the HW platform we can optionally
+ * mirror the DDR up above the processor cacheable region. So, memory accessed
+ * in this mirror region will not be cached. It's alloced from the same
+ * pool as normal memory, but the handle we return is shifted up into the
+ * uncached region. This will no doubt cause big problems if memory allocated
+ * here is not also freed properly. -- JW
+ */
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+ struct page *page, *end, *free;
+ unsigned long order;
+ void *ret, *virt;
+
+ if (in_interrupt())
+ BUG();
+
+ size = PAGE_ALIGN(size);
+ order = get_order(size);
+
+ page = alloc_pages(gfp, order);
+ if (!page)
+ goto no_page;
+
+ /* We could do with a page_to_phys and page_to_bus here. */
+ virt = page_address(page);
+ ret = ioremap(virt_to_phys(virt), size);
+ if (!ret)
+ goto no_remap;
+
+ /*
+ * Here's the magic! Note if the uncached shadow is not implemented,
+ * it's up to the calling code to also test that condition and make
+ * other arranegments, such as manually flushing the cache and so on.
+ */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+ ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK);
+#endif
+ /* dma_handle is same as physical (shadowed) address */
+ *dma_handle = (dma_addr_t)ret;
+
+ /*
+ * free wasted pages. We skip the first page since we know
+ * that it will have count = 1 and won't require freeing.
+ * We also mark the pages in use as reserved so that
+ * remap_page_range works.
+ */
+ page = virt_to_page(virt);
+ free = page + (size >> PAGE_SHIFT);
+ end = page + (1 << order);
+
+ for (; page < end; page++) {
+ init_page_count(page);
+ if (page >= free)
+ __free_page(page);
+ else
+ SetPageReserved(page);
+ }
+
+ return ret;
+no_remap:
+ __free_pages(page, order);
+no_page:
+ return NULL;
+}
+
+#else
+
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+ int order, err, i;
+ unsigned long page, va, flags;
+ phys_addr_t pa;
+ struct vm_struct *area;
+ void *ret;
+
+ if (in_interrupt())
+ BUG();
+
+ /* Only allocate page size areas. */
+ size = PAGE_ALIGN(size);
+ order = get_order(size);
+
+ page = __get_free_pages(gfp, order);
+ if (!page) {
+ BUG();
+ return NULL;
+ }
+
+ /*
+ * we need to ensure that there are no cachelines in use,
+ * or worse dirty in this area.
+ */
+ flush_dcache_range(virt_to_phys(page), virt_to_phys(page) + size);
+
+ /* Allocate some common virtual space to map the new pages. */
+ area = get_vm_area(size, VM_ALLOC);
+ if (area == NULL) {
+ free_pages(page, order);
+ return NULL;
+ }
+ va = (unsigned long) area->addr;
+ ret = (void *)va;
+
+ /* This gives us the real physical address of the first page. */
+ *dma_handle = pa = virt_to_bus((void *)page);
+
+ /* MS: This is the whole magic - use cache inhibit pages */
+ flags = _PAGE_KERNEL | _PAGE_NO_CACHE;
+
+ /*
+ * Set refcount=1 on all pages in an order>0
+ * allocation so that vfree() will actually
+ * free all pages that were allocated.
+ */
+ if (order > 0) {
+ struct page *rpage = virt_to_page(page);
+ for (i = 1; i < (1 << order); i++)
+ init_page_count(rpage+i);
+ }
+
+ err = 0;
+ for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+ err = map_page(va+i, pa+i, flags);
+
+ if (err) {
+ vfree((void *)va);
+ return NULL;
+ }
+
+ return ret;
+}
+#endif /* CONFIG_MMU */
+EXPORT_SYMBOL(consistent_alloc);
+
+/*
+ * free page(s) as defined by the above mapping.
+ */
+void consistent_free(void *vaddr)
+{
+ if (in_interrupt())
+ BUG();
+
+ /* Clear SHADOW_MASK bit in address, and free as per usual */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+ vaddr = (void *)((unsigned)vaddr & ~UNCACHED_SHADOW_MASK);
+#endif
+ vfree(vaddr);
+}
+EXPORT_SYMBOL(consistent_free);
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+ unsigned long start;
+ unsigned long end;
+
+ start = (unsigned long)vaddr;
+
+ /* Convert start address back down to unshadowed memory region */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+ start &= ~UNCACHED_SHADOW_MASK;
+#endif
+ end = start + size;
+
+ switch (direction) {
+ case PCI_DMA_NONE:
+ BUG();
+ case PCI_DMA_FROMDEVICE: /* invalidate only */
+ flush_dcache_range(start, end);
+ break;
+ case PCI_DMA_TODEVICE: /* writeback only */
+ flush_dcache_range(start, end);
+ break;
+ case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */
+ flush_dcache_range(start, end);
+ break;
+ }
+}
+EXPORT_SYMBOL(consistent_sync);
+
+/*
+ * consistent_sync_page makes memory consistent. identical
+ * to consistent_sync, but takes a struct page instead of a
+ * virtual address
+ */
+void consistent_sync_page(struct page *page, unsigned long offset,
+ size_t size, int direction)
+{
+ unsigned long start = (unsigned long)page_address(page) + offset;
+ consistent_sync((void *)start, size, direction);
+}
+EXPORT_SYMBOL(consistent_sync_page);
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index d9d249a66ff..7af87f4b2c2 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -106,7 +106,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
regs->esr = error_code;
/* On a kernel SLB miss we can only check for a valid exception entry */
- if (kernel_mode(regs) && (address >= TASK_SIZE)) {
+ if (unlikely(kernel_mode(regs) && (address >= TASK_SIZE))) {
printk(KERN_WARNING "kernel task_size exceed");
_exception(SIGSEGV, regs, code, address);
}
@@ -122,7 +122,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
}
#endif /* CONFIG_KGDB */
- if (in_atomic() || !mm) {
+ if (unlikely(in_atomic() || !mm)) {
if (kernel_mode(regs))
goto bad_area_nosemaphore;
@@ -150,7 +150,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
* source. If this is invalid we can skip the address space check,
* thus avoiding the deadlock.
*/
- if (!down_read_trylock(&mm->mmap_sem)) {
+ if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
if (kernel_mode(regs) && !search_exception_tables(regs->pc))
goto bad_area_nosemaphore;
@@ -158,16 +158,16 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
}
vma = find_vma(mm, address);
- if (!vma)
+ if (unlikely(!vma))
goto bad_area;
if (vma->vm_start <= address)
goto good_area;
- if (!(vma->vm_flags & VM_GROWSDOWN))
+ if (unlikely(!(vma->vm_flags & VM_GROWSDOWN)))
goto bad_area;
- if (!is_write)
+ if (unlikely(!is_write))
goto bad_area;
/*
@@ -179,7 +179,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
* before setting the user r1. Thus we allow the stack to
* expand to 1MB without further checks.
*/
- if (address + 0x100000 < vma->vm_end) {
+ if (unlikely(address + 0x100000 < vma->vm_end)) {
/* get user regs even if this fault is in kernel mode */
struct pt_regs *uregs = current->thread.regs;
@@ -209,15 +209,15 @@ good_area:
code = SEGV_ACCERR;
/* a write */
- if (is_write) {
- if (!(vma->vm_flags & VM_WRITE))
+ if (unlikely(is_write)) {
+ if (unlikely(!(vma->vm_flags & VM_WRITE)))
goto bad_area;
/* a read */
} else {
/* protection fault */
- if (error_code & 0x08000000)
+ if (unlikely(error_code & 0x08000000))
goto bad_area;
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC))))
goto bad_area;
}
@@ -235,7 +235,7 @@ survive:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
+ if (unlikely(fault & VM_FAULT_MAJOR))
current->maj_flt++;
else
current->min_flt++;
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index a57cedf3671..f42c2dde8b1 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -15,6 +15,7 @@
#include <linux/initrd.h>
#include <linux/pagemap.h>
#include <linux/pfn.h>
+#include <linux/slab.h>
#include <linux/swap.h>
#include <asm/page.h>
@@ -23,6 +24,9 @@
#include <asm/sections.h>
#include <asm/tlb.h>
+/* Use for MMU and noMMU because of PCI generic code */
+int mem_init_done;
+
#ifndef CONFIG_MMU
unsigned int __page_offset;
EXPORT_SYMBOL(__page_offset);
@@ -30,7 +34,6 @@ EXPORT_SYMBOL(__page_offset);
#else
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-int mem_init_done;
static int init_bootmem_done;
#endif /* CONFIG_MMU */
@@ -163,7 +166,6 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
for (addr = begin; addr < end; addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
init_page_count(virt_to_page(addr));
- memset((void *)addr, 0xcc, PAGE_SIZE);
free_page(addr);
totalram_pages++;
}
@@ -193,12 +195,6 @@ void free_initmem(void)
(unsigned long)(&__init_end));
}
-/* FIXME from arch/powerpc/mm/mem.c*/
-void show_mem(void)
-{
- printk(KERN_NOTICE "%s\n", __func__);
-}
-
void __init mem_init(void)
{
high_memory = (void *)__va(memory_end);
@@ -208,20 +204,14 @@ void __init mem_init(void)
printk(KERN_INFO "Memory: %luk/%luk available\n",
nr_free_pages() << (PAGE_SHIFT-10),
num_physpages << (PAGE_SHIFT-10));
-#ifdef CONFIG_MMU
mem_init_done = 1;
-#endif
}
#ifndef CONFIG_MMU
-/* Check against bounds of physical memory */
-int ___range_ok(unsigned long addr, unsigned long size)
+int page_is_ram(unsigned long pfn)
{
- return ((addr < memory_start) ||
- ((addr + size) > memory_end));
+ return __range_ok(pfn, 0);
}
-EXPORT_SYMBOL(___range_ok);
-
#else
int page_is_ram(unsigned long pfn)
{
@@ -349,4 +339,27 @@ void __init *early_get_page(void)
}
return p;
}
+
#endif /* CONFIG_MMU */
+
+void * __init_refok alloc_maybe_bootmem(size_t size, gfp_t mask)
+{
+ if (mem_init_done)
+ return kmalloc(size, mask);
+ else
+ return alloc_bootmem(size);
+}
+
+void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask)
+{
+ void *p;
+
+ if (mem_init_done)
+ p = kzalloc(size, mask);
+ else {
+ p = alloc_bootmem(size);
+ if (p)
+ memset(p, 0, size);
+ }
+ return p;
+}
diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c
index 2820081b21a..d31312cde6e 100644
--- a/arch/microblaze/mm/pgtable.c
+++ b/arch/microblaze/mm/pgtable.c
@@ -103,7 +103,7 @@ static void __iomem *__ioremap(phys_addr_t addr, unsigned long size,
area = get_vm_area(size, VM_IOREMAP);
if (area == NULL)
return NULL;
- v = VMALLOC_VMADDR(area->addr);
+ v = (unsigned long) area->addr;
} else {
v = (ioremap_bot -= size);
}
@@ -154,7 +154,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
err = 0;
set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT,
__pgprot(flags)));
- if (mem_init_done)
+ if (unlikely(mem_init_done))
flush_HPTE(0, va, pmd_val(*pd));
/* flush_HPTE(0, va, pg); */
}
diff --git a/arch/microblaze/pci/Makefile b/arch/microblaze/pci/Makefile
new file mode 100644
index 00000000000..9889cc2e129
--- /dev/null
+++ b/arch/microblaze/pci/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile
+#
+
+obj-$(CONFIG_PCI) += pci_32.o pci-common.o indirect_pci.o iomap.o
+obj-$(CONFIG_PCI_XILINX) += xilinx_pci.o
diff --git a/arch/microblaze/pci/indirect_pci.c b/arch/microblaze/pci/indirect_pci.c
new file mode 100644
index 00000000000..25f18f017f2
--- /dev/null
+++ b/arch/microblaze/pci/indirect_pci.c
@@ -0,0 +1,163 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (C) 1998 Gabriel Paubert.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+static int
+indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 *val)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ volatile void __iomem *cfg_data;
+ u8 cfg_type = 0;
+ u32 bus_no, reg;
+
+ if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
+ if (bus->number != hose->first_busno)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (devfn != 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE)
+ if (bus->number != hose->first_busno)
+ cfg_type = 1;
+
+ bus_no = (bus->number == hose->first_busno) ?
+ hose->self_busno : bus->number;
+
+ if (hose->indirect_type & INDIRECT_TYPE_EXT_REG)
+ reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
+ else
+ reg = offset & 0xfc; /* Only 3 bits for function */
+
+ if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
+ out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+ (devfn << 8) | reg | cfg_type));
+ else
+ out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+ (devfn << 8) | reg | cfg_type));
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ cfg_data = hose->cfg_data + (offset & 3); /* Only 3 bits for function */
+ switch (len) {
+ case 1:
+ *val = in_8(cfg_data);
+ break;
+ case 2:
+ *val = in_le16(cfg_data);
+ break;
+ default:
+ *val = in_le32(cfg_data);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 val)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ volatile void __iomem *cfg_data;
+ u8 cfg_type = 0;
+ u32 bus_no, reg;
+
+ if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
+ if (bus->number != hose->first_busno)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (devfn != 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE)
+ if (bus->number != hose->first_busno)
+ cfg_type = 1;
+
+ bus_no = (bus->number == hose->first_busno) ?
+ hose->self_busno : bus->number;
+
+ if (hose->indirect_type & INDIRECT_TYPE_EXT_REG)
+ reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
+ else
+ reg = offset & 0xfc;
+
+ if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
+ out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+ (devfn << 8) | reg | cfg_type));
+ else
+ out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+ (devfn << 8) | reg | cfg_type));
+
+ /* surpress setting of PCI_PRIMARY_BUS */
+ if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
+ if ((offset == PCI_PRIMARY_BUS) &&
+ (bus->number == hose->first_busno))
+ val &= 0xffffff00;
+
+ /* Workaround for PCI_28 Errata in 440EPx/GRx */
+ if ((hose->indirect_type & INDIRECT_TYPE_BROKEN_MRM) &&
+ offset == PCI_CACHE_LINE_SIZE) {
+ val = 0;
+ }
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ cfg_data = hose->cfg_data + (offset & 3);
+ switch (len) {
+ case 1:
+ out_8(cfg_data, val);
+ break;
+ case 2:
+ out_le16(cfg_data, val);
+ break;
+ default:
+ out_le32(cfg_data, val);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops indirect_pci_ops = {
+ .read = indirect_read_config,
+ .write = indirect_write_config,
+};
+
+void __init
+setup_indirect_pci(struct pci_controller *hose,
+ resource_size_t cfg_addr,
+ resource_size_t cfg_data, u32 flags)
+{
+ resource_size_t base = cfg_addr & PAGE_MASK;
+ void __iomem *mbase;
+
+ mbase = ioremap(base, PAGE_SIZE);
+ hose->cfg_addr = mbase + (cfg_addr & ~PAGE_MASK);
+ if ((cfg_data & PAGE_MASK) != base)
+ mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
+ hose->cfg_data = mbase + (cfg_data & ~PAGE_MASK);
+ hose->ops = &indirect_pci_ops;
+ hose->indirect_type = flags;
+}
diff --git a/arch/microblaze/pci/iomap.c b/arch/microblaze/pci/iomap.c
new file mode 100644
index 00000000000..3fbf16f4e16
--- /dev/null
+++ b/arch/microblaze/pci/iomap.c
@@ -0,0 +1,39 @@
+/*
+ * ppc64 "iomap" interface implementation.
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+ resource_size_t start = pci_resource_start(dev, bar);
+ resource_size_t len = pci_resource_len(dev, bar);
+ unsigned long flags = pci_resource_flags(dev, bar);
+
+ if (!len)
+ return NULL;
+ if (max && len > max)
+ len = max;
+ if (flags & IORESOURCE_IO)
+ return ioport_map(start, len);
+ if (flags & IORESOURCE_MEM)
+ return ioremap(start, len);
+ /* What? */
+ return NULL;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+ if (isa_vaddr_is_ioport(addr))
+ return;
+ if (pcibios_vaddr_is_ioport(addr))
+ return;
+ iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
new file mode 100644
index 00000000000..740bb32ec57
--- /dev/null
+++ b/arch/microblaze/pci/pci-common.c
@@ -0,0 +1,1643 @@
+/*
+ * Contains common pci routines for ALL ppc platform
+ * (based on pci_32.c and pci_64.c)
+ *
+ * Port for PPC64 David Engebretsen, IBM Corp.
+ * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Rework, based on alpha PCI code.
+ *
+ * Common pmac/prep/chrp pci routines. -- Cort
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/syscalls.h>
+#include <linux/irq.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+
+static DEFINE_SPINLOCK(hose_spinlock);
+LIST_HEAD(hose_list);
+
+/* XXX kill that some day ... */
+static int global_phb_number; /* Global phb counter */
+
+/* ISA Memory physical address */
+resource_size_t isa_mem_base;
+
+/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
+unsigned int pci_flags;
+
+static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
+
+void set_pci_dma_ops(struct dma_map_ops *dma_ops)
+{
+ pci_dma_ops = dma_ops;
+}
+
+struct dma_map_ops *get_pci_dma_ops(void)
+{
+ return pci_dma_ops;
+}
+EXPORT_SYMBOL(get_pci_dma_ops);
+
+int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ return dma_set_mask(&dev->dev, mask);
+}
+
+int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ int rc;
+
+ rc = dma_set_mask(&dev->dev, mask);
+ dev->dev.coherent_dma_mask = dev->dma_mask;
+
+ return rc;
+}
+
+struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
+{
+ struct pci_controller *phb;
+
+ phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL);
+ if (!phb)
+ return NULL;
+ spin_lock(&hose_spinlock);
+ phb->global_number = global_phb_number++;
+ list_add_tail(&phb->list_node, &hose_list);
+ spin_unlock(&hose_spinlock);
+ phb->dn = dev;
+ phb->is_dynamic = mem_init_done;
+ return phb;
+}
+
+void pcibios_free_controller(struct pci_controller *phb)
+{
+ spin_lock(&hose_spinlock);
+ list_del(&phb->list_node);
+ spin_unlock(&hose_spinlock);
+
+ if (phb->is_dynamic)
+ kfree(phb);
+}
+
+static resource_size_t pcibios_io_size(const struct pci_controller *hose)
+{
+ return hose->io_resource.end - hose->io_resource.start + 1;
+}
+
+int pcibios_vaddr_is_ioport(void __iomem *address)
+{
+ int ret = 0;
+ struct pci_controller *hose;
+ resource_size_t size;
+
+ spin_lock(&hose_spinlock);
+ list_for_each_entry(hose, &hose_list, list_node) {
+ size = pcibios_io_size(hose);
+ if (address >= hose->io_base_virt &&
+ address < (hose->io_base_virt + size)) {
+ ret = 1;
+ break;
+ }
+ }
+ spin_unlock(&hose_spinlock);
+ return ret;
+}
+
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+ struct pci_controller *hose;
+ resource_size_t size;
+ unsigned long ret = ~0;
+
+ spin_lock(&hose_spinlock);
+ list_for_each_entry(hose, &hose_list, list_node) {
+ size = pcibios_io_size(hose);
+ if (address >= hose->io_base_phys &&
+ address < (hose->io_base_phys + size)) {
+ unsigned long base =
+ (unsigned long)hose->io_base_virt - _IO_BASE;
+ ret = base + (address - hose->io_base_phys);
+ break;
+ }
+ }
+ spin_unlock(&hose_spinlock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pci_address_to_pio);
+
+/*
+ * Return the domain number for this bus.
+ */
+int pci_domain_nr(struct pci_bus *bus)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+
+ return hose->global_number;
+}
+EXPORT_SYMBOL(pci_domain_nr);
+
+/* This routine is meant to be used early during boot, when the
+ * PCI bus numbers have not yet been assigned, and you need to
+ * issue PCI config cycles to an OF device.
+ * It could also be used to "fix" RTAS config cycles if you want
+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
+ * config cycles.
+ */
+struct pci_controller *pci_find_hose_for_OF_device(struct device_node *node)
+{
+ while (node) {
+ struct pci_controller *hose, *tmp;
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+ if (hose->dn == node)
+ return hose;
+ node = node->parent;
+ }
+ return NULL;
+}
+
+static ssize_t pci_show_devspec(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pci_dev *pdev;
+ struct device_node *np;
+
+ pdev = to_pci_dev(dev);
+ np = pci_device_to_OF_node(pdev);
+ if (np == NULL || np->full_name == NULL)
+ return 0;
+ return sprintf(buf, "%s", np->full_name);
+}
+static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+
+/* Add sysfs properties */
+int pcibios_add_platform_entries(struct pci_dev *pdev)
+{
+ return device_create_file(&pdev->dev, &dev_attr_devspec);
+}
+
+char __devinit *pcibios_setup(char *str)
+{
+ return str;
+}
+
+/*
+ * Reads the interrupt pin to determine if interrupt is use by card.
+ * If the interrupt is used, then gets the interrupt line from the
+ * openfirmware and sets it in the pci_dev and pci_config line.
+ */
+int pci_read_irq_line(struct pci_dev *pci_dev)
+{
+ struct of_irq oirq;
+ unsigned int virq;
+
+ /* The current device-tree that iSeries generates from the HV
+ * PCI informations doesn't contain proper interrupt routing,
+ * and all the fallback would do is print out crap, so we
+ * don't attempt to resolve the interrupts here at all, some
+ * iSeries specific fixup does it.
+ *
+ * In the long run, we will hopefully fix the generated device-tree
+ * instead.
+ */
+ pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
+
+#ifdef DEBUG
+ memset(&oirq, 0xff, sizeof(oirq));
+#endif
+ /* Try to get a mapping from the device-tree */
+ if (of_irq_map_pci(pci_dev, &oirq)) {
+ u8 line, pin;
+
+ /* If that fails, lets fallback to what is in the config
+ * space and map that through the default controller. We
+ * also set the type to level low since that's what PCI
+ * interrupts are. If your platform does differently, then
+ * either provide a proper interrupt tree or don't use this
+ * function.
+ */
+ if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
+ return -1;
+ if (pin == 0)
+ return -1;
+ if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
+ line == 0xff || line == 0) {
+ return -1;
+ }
+ pr_debug(" No map ! Using line %d (pin %d) from PCI config\n",
+ line, pin);
+
+ virq = irq_create_mapping(NULL, line);
+ if (virq != NO_IRQ)
+ set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+ } else {
+ pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+ oirq.size, oirq.specifier[0], oirq.specifier[1],
+ oirq.controller ? oirq.controller->full_name :
+ "<default>");
+
+ virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ oirq.size);
+ }
+ if (virq == NO_IRQ) {
+ pr_debug(" Failed to map !\n");
+ return -1;
+ }
+
+ pr_debug(" Mapped to linux irq %d\n", virq);
+
+ pci_dev->irq = virq;
+
+ return 0;
+}
+EXPORT_SYMBOL(pci_read_irq_line);
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ * -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap. They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
+ resource_size_t *offset,
+ enum pci_mmap_state mmap_state)
+{
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ unsigned long io_offset = 0;
+ int i, res_bit;
+
+ if (hose == 0)
+ return NULL; /* should never happen */
+
+ /* If memory, add on the PCI bridge address offset */
+ if (mmap_state == pci_mmap_mem) {
+#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
+ *offset += hose->pci_mem_offset;
+#endif
+ res_bit = IORESOURCE_MEM;
+ } else {
+ io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ *offset += io_offset;
+ res_bit = IORESOURCE_IO;
+ }
+
+ /*
+ * Check that the offset requested corresponds to one of the
+ * resources of the device.
+ */
+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+ struct resource *rp = &dev->resource[i];
+ int flags = rp->flags;
+
+ /* treat ROM as memory (should be already) */
+ if (i == PCI_ROM_RESOURCE)
+ flags |= IORESOURCE_MEM;
+
+ /* Active and same type? */
+ if ((flags & res_bit) == 0)
+ continue;
+
+ /* In the range of this resource? */
+ if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
+ continue;
+
+ /* found it! construct the final physical address */
+ if (mmap_state == pci_mmap_io)
+ *offset += hose->io_base_phys - io_offset;
+ return rp;
+ }
+
+ return NULL;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
+ pgprot_t protection,
+ enum pci_mmap_state mmap_state,
+ int write_combine)
+{
+ pgprot_t prot = protection;
+
+ /* Write combine is always 0 on non-memory space mappings. On
+ * memory space, if the user didn't pass 1, we check for a
+ * "prefetchable" resource. This is a bit hackish, but we use
+ * this to workaround the inability of /sysfs to provide a write
+ * combine bit
+ */
+ if (mmap_state != pci_mmap_mem)
+ write_combine = 0;
+ else if (write_combine == 0) {
+ if (rp->flags & IORESOURCE_PREFETCH)
+ write_combine = 1;
+ }
+
+ return pgprot_noncached(prot);
+}
+
+/*
+ * This one is used by /dev/mem and fbdev who have no clue about the
+ * PCI device, it tries to find the PCI device first and calls the
+ * above routine
+ */
+pgprot_t pci_phys_mem_access_prot(struct file *file,
+ unsigned long pfn,
+ unsigned long size,
+ pgprot_t prot)
+{
+ struct pci_dev *pdev = NULL;
+ struct resource *found = NULL;
+ resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT;
+ int i;
+
+ if (page_is_ram(pfn))
+ return prot;
+
+ prot = pgprot_noncached(prot);
+ for_each_pci_dev(pdev) {
+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+ struct resource *rp = &pdev->resource[i];
+ int flags = rp->flags;
+
+ /* Active and same type? */
+ if ((flags & IORESOURCE_MEM) == 0)
+ continue;
+ /* In the range of this resource? */
+ if (offset < (rp->start & PAGE_MASK) ||
+ offset > rp->end)
+ continue;
+ found = rp;
+ break;
+ }
+ if (found)
+ break;
+ }
+ if (found) {
+ if (found->flags & IORESOURCE_PREFETCH)
+ prot = pgprot_noncached_wc(prot);
+ pci_dev_put(pdev);
+ }
+
+ pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n",
+ (unsigned long long)offset, pgprot_val(prot));
+
+ return prot;
+}
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture. The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine)
+{
+ resource_size_t offset =
+ ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
+ struct resource *rp;
+ int ret;
+
+ rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
+ if (rp == NULL)
+ return -EINVAL;
+
+ vma->vm_pgoff = offset >> PAGE_SHIFT;
+ vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
+ vma->vm_page_prot,
+ mmap_state, write_combine);
+
+ ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+ return ret;
+}
+
+/* This provides legacy IO read access on a bus */
+int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
+{
+ unsigned long offset;
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct resource *rp = &hose->io_resource;
+ void __iomem *addr;
+
+ /* Check if port can be supported by that bus. We only check
+ * the ranges of the PHB though, not the bus itself as the rules
+ * for forwarding legacy cycles down bridges are not our problem
+ * here. So if the host bridge supports it, we do it.
+ */
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ offset += port;
+
+ if (!(rp->flags & IORESOURCE_IO))
+ return -ENXIO;
+ if (offset < rp->start || (offset + size) > rp->end)
+ return -ENXIO;
+ addr = hose->io_base_virt + port;
+
+ switch (size) {
+ case 1:
+ *((u8 *)val) = in_8(addr);
+ return 1;
+ case 2:
+ if (port & 1)
+ return -EINVAL;
+ *((u16 *)val) = in_le16(addr);
+ return 2;
+ case 4:
+ if (port & 3)
+ return -EINVAL;
+ *((u32 *)val) = in_le32(addr);
+ return 4;
+ }
+ return -EINVAL;
+}
+
+/* This provides legacy IO write access on a bus */
+int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
+{
+ unsigned long offset;
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct resource *rp = &hose->io_resource;
+ void __iomem *addr;
+
+ /* Check if port can be supported by that bus. We only check
+ * the ranges of the PHB though, not the bus itself as the rules
+ * for forwarding legacy cycles down bridges are not our problem
+ * here. So if the host bridge supports it, we do it.
+ */
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ offset += port;
+
+ if (!(rp->flags & IORESOURCE_IO))
+ return -ENXIO;
+ if (offset < rp->start || (offset + size) > rp->end)
+ return -ENXIO;
+ addr = hose->io_base_virt + port;
+
+ /* WARNING: The generic code is idiotic. It gets passed a pointer
+ * to what can be a 1, 2 or 4 byte quantity and always reads that
+ * as a u32, which means that we have to correct the location of
+ * the data read within those 32 bits for size 1 and 2
+ */
+ switch (size) {
+ case 1:
+ out_8(addr, val >> 24);
+ return 1;
+ case 2:
+ if (port & 1)
+ return -EINVAL;
+ out_le16(addr, val >> 16);
+ return 2;
+ case 4:
+ if (port & 3)
+ return -EINVAL;
+ out_le32(addr, val);
+ return 4;
+ }
+ return -EINVAL;
+}
+
+/* This provides legacy IO or memory mmap access on a bus */
+int pci_mmap_legacy_page_range(struct pci_bus *bus,
+ struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ resource_size_t offset =
+ ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
+ resource_size_t size = vma->vm_end - vma->vm_start;
+ struct resource *rp;
+
+ pr_debug("pci_mmap_legacy_page_range(%04x:%02x, %s @%llx..%llx)\n",
+ pci_domain_nr(bus), bus->number,
+ mmap_state == pci_mmap_mem ? "MEM" : "IO",
+ (unsigned long long)offset,
+ (unsigned long long)(offset + size - 1));
+
+ if (mmap_state == pci_mmap_mem) {
+ /* Hack alert !
+ *
+ * Because X is lame and can fail starting if it gets an error
+ * trying to mmap legacy_mem (instead of just moving on without
+ * legacy memory access) we fake it here by giving it anonymous
+ * memory, effectively behaving just like /dev/zero
+ */
+ if ((offset + size) > hose->isa_mem_size) {
+#ifdef CONFIG_MMU
+ printk(KERN_DEBUG
+ "Process %s (pid:%d) mapped non-existing PCI"
+ "legacy memory for 0%04x:%02x\n",
+ current->comm, current->pid, pci_domain_nr(bus),
+ bus->number);
+#endif
+ if (vma->vm_flags & VM_SHARED)
+ return shmem_zero_setup(vma);
+ return 0;
+ }
+ offset += hose->isa_mem_phys;
+ } else {
+ unsigned long io_offset = (unsigned long)hose->io_base_virt - \
+ _IO_BASE;
+ unsigned long roffset = offset + io_offset;
+ rp = &hose->io_resource;
+ if (!(rp->flags & IORESOURCE_IO))
+ return -ENXIO;
+ if (roffset < rp->start || (roffset + size) > rp->end)
+ return -ENXIO;
+ offset += hose->io_base_phys;
+ }
+ pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset);
+
+ vma->vm_pgoff = offset >> PAGE_SHIFT;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+ const struct resource *rsrc,
+ resource_size_t *start, resource_size_t *end)
+{
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ resource_size_t offset = 0;
+
+ if (hose == NULL)
+ return;
+
+ if (rsrc->flags & IORESOURCE_IO)
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+
+ /* We pass a fully fixed up address to userland for MMIO instead of
+ * a BAR value because X is lame and expects to be able to use that
+ * to pass to /dev/mem !
+ *
+ * That means that we'll have potentially 64 bits values where some
+ * userland apps only expect 32 (like X itself since it thinks only
+ * Sparc has 64 bits MMIO) but if we don't do that, we break it on
+ * 32 bits CHRPs :-(
+ *
+ * Hopefully, the sysfs insterface is immune to that gunk. Once X
+ * has been fixed (and the fix spread enough), we can re-enable the
+ * 2 lines below and pass down a BAR value to userland. In that case
+ * we'll also have to re-enable the matching code in
+ * __pci_mmap_make_offset().
+ *
+ * BenH.
+ */
+#if 0
+ else if (rsrc->flags & IORESOURCE_MEM)
+ offset = hose->pci_mem_offset;
+#endif
+
+ *start = rsrc->start - offset;
+ *end = rsrc->end - offset;
+}
+
+/**
+ * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
+ * @hose: newly allocated pci_controller to be setup
+ * @dev: device node of the host bridge
+ * @primary: set if primary bus (32 bits only, soon to be deprecated)
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping of a pci controller based on its
+ * content.
+ *
+ * Life would be boring if it wasn't for a few issues that we have to deal
+ * with here:
+ *
+ * - We can only cope with one IO space range and up to 3 Memory space
+ * ranges. However, some machines (thanks Apple !) tend to split their
+ * space into lots of small contiguous ranges. So we have to coalesce.
+ *
+ * - We can only cope with all memory ranges having the same offset
+ * between CPU addresses and PCI addresses. Unfortunately, some bridges
+ * are setup for a large 1:1 mapping along with a small "window" which
+ * maps PCI address 0 to some arbitrary high address of the CPU space in
+ * order to give access to the ISA memory hole.
+ * The way out of here that I've chosen for now is to always set the
+ * offset based on the first resource found, then override it if we
+ * have a different offset and the previous was set by an ISA hole.
+ *
+ * - Some busses have IO space not starting at 0, which causes trouble with
+ * the way we do our IO resource renumbering. The code somewhat deals with
+ * it for 64 bits but I would expect problems on 32 bits.
+ *
+ * - Some 32 bits platforms such as 4xx can have physical space larger than
+ * 32 bits so we need to use 64 bits values for the parsing
+ */
+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+ struct device_node *dev,
+ int primary)
+{
+ const u32 *ranges;
+ int rlen;
+ int pna = of_n_addr_cells(dev);
+ int np = pna + 5;
+ int memno = 0, isa_hole = -1;
+ u32 pci_space;
+ unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
+ unsigned long long isa_mb = 0;
+ struct resource *res;
+
+ printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
+ dev->full_name, primary ? "(primary)" : "");
+
+ /* Get ranges property */
+ ranges = of_get_property(dev, "ranges", &rlen);
+ if (ranges == NULL)
+ return;
+
+ /* Parse it */
+ pr_debug("Parsing ranges property...\n");
+ while ((rlen -= np * 4) >= 0) {
+ /* Read next ranges element */
+ pci_space = ranges[0];
+ pci_addr = of_read_number(ranges + 1, 2);
+ cpu_addr = of_translate_address(dev, ranges + 3);
+ size = of_read_number(ranges + pna + 3, 2);
+
+ pr_debug("pci_space: 0x%08x pci_addr:0x%016llx "
+ "cpu_addr:0x%016llx size:0x%016llx\n",
+ pci_space, pci_addr, cpu_addr, size);
+
+ ranges += np;
+
+ /* If we failed translation or got a zero-sized region
+ * (some FW try to feed us with non sensical zero sized regions
+ * such as power3 which look like some kind of attempt
+ * at exposing the VGA memory hole)
+ */
+ if (cpu_addr == OF_BAD_ADDR || size == 0)
+ continue;
+
+ /* Now consume following elements while they are contiguous */
+ for (; rlen >= np * sizeof(u32);
+ ranges += np, rlen -= np * 4) {
+ if (ranges[0] != pci_space)
+ break;
+ pci_next = of_read_number(ranges + 1, 2);
+ cpu_next = of_translate_address(dev, ranges + 3);
+ if (pci_next != pci_addr + size ||
+ cpu_next != cpu_addr + size)
+ break;
+ size += of_read_number(ranges + pna + 3, 2);
+ }
+
+ /* Act based on address space type */
+ res = NULL;
+ switch ((pci_space >> 24) & 0x3) {
+ case 1: /* PCI IO space */
+ printk(KERN_INFO
+ " IO 0x%016llx..0x%016llx -> 0x%016llx\n",
+ cpu_addr, cpu_addr + size - 1, pci_addr);
+
+ /* We support only one IO range */
+ if (hose->pci_io_size) {
+ printk(KERN_INFO
+ " \\--> Skipped (too many) !\n");
+ continue;
+ }
+ /* On 32 bits, limit I/O space to 16MB */
+ if (size > 0x01000000)
+ size = 0x01000000;
+
+ /* 32 bits needs to map IOs here */
+ hose->io_base_virt = ioremap(cpu_addr, size);
+
+ /* Expect trouble if pci_addr is not 0 */
+ if (primary)
+ isa_io_base =
+ (unsigned long)hose->io_base_virt;
+ /* pci_io_size and io_base_phys always represent IO
+ * space starting at 0 so we factor in pci_addr
+ */
+ hose->pci_io_size = pci_addr + size;
+ hose->io_base_phys = cpu_addr - pci_addr;
+
+ /* Build resource */
+ res = &hose->io_resource;
+ res->flags = IORESOURCE_IO;
+ res->start = pci_addr;
+ break;
+ case 2: /* PCI Memory space */
+ case 3: /* PCI 64 bits Memory space */
+ printk(KERN_INFO
+ " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
+ cpu_addr, cpu_addr + size - 1, pci_addr,
+ (pci_space & 0x40000000) ? "Prefetch" : "");
+
+ /* We support only 3 memory ranges */
+ if (memno >= 3) {
+ printk(KERN_INFO
+ " \\--> Skipped (too many) !\n");
+ continue;
+ }
+ /* Handles ISA memory hole space here */
+ if (pci_addr == 0) {
+ isa_mb = cpu_addr;
+ isa_hole = memno;
+ if (primary || isa_mem_base == 0)
+ isa_mem_base = cpu_addr;
+ hose->isa_mem_phys = cpu_addr;
+ hose->isa_mem_size = size;
+ }
+
+ /* We get the PCI/Mem offset from the first range or
+ * the, current one if the offset came from an ISA
+ * hole. If they don't match, bugger.
+ */
+ if (memno == 0 ||
+ (isa_hole >= 0 && pci_addr != 0 &&
+ hose->pci_mem_offset == isa_mb))
+ hose->pci_mem_offset = cpu_addr - pci_addr;
+ else if (pci_addr != 0 &&
+ hose->pci_mem_offset != cpu_addr - pci_addr) {
+ printk(KERN_INFO
+ " \\--> Skipped (offset mismatch) !\n");
+ continue;
+ }
+
+ /* Build resource */
+ res = &hose->mem_resources[memno++];
+ res->flags = IORESOURCE_MEM;
+ if (pci_space & 0x40000000)
+ res->flags |= IORESOURCE_PREFETCH;
+ res->start = cpu_addr;
+ break;
+ }
+ if (res != NULL) {
+ res->name = dev->full_name;
+ res->end = res->start + size - 1;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
+ }
+ }
+
+ /* If there's an ISA hole and the pci_mem_offset is -not- matching
+ * the ISA hole offset, then we need to remove the ISA hole from
+ * the resource list for that brige
+ */
+ if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) {
+ unsigned int next = isa_hole + 1;
+ printk(KERN_INFO " Removing ISA hole at 0x%016llx\n", isa_mb);
+ if (next < memno)
+ memmove(&hose->mem_resources[isa_hole],
+ &hose->mem_resources[next],
+ sizeof(struct resource) * (memno - next));
+ hose->mem_resources[--memno].flags = 0;
+ }
+}
+
+/* Decide whether to display the domain number in /proc */
+int pci_proc_domain(struct pci_bus *bus)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+
+ if (!(pci_flags & PCI_ENABLE_PROC_DOMAINS))
+ return 0;
+ if (pci_flags & PCI_COMPAT_DOMAIN_0)
+ return hose->global_number != 0;
+ return 1;
+}
+
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+ struct resource *res)
+{
+ resource_size_t offset = 0, mask = (resource_size_t)-1;
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+ if (!hose)
+ return;
+ if (res->flags & IORESOURCE_IO) {
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ mask = 0xffffffffu;
+ } else if (res->flags & IORESOURCE_MEM)
+ offset = hose->pci_mem_offset;
+
+ region->start = (res->start - offset) & mask;
+ region->end = (res->end - offset) & mask;
+}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region)
+{
+ resource_size_t offset = 0, mask = (resource_size_t)-1;
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+ if (!hose)
+ return;
+ if (res->flags & IORESOURCE_IO) {
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ mask = 0xffffffffu;
+ } else if (res->flags & IORESOURCE_MEM)
+ offset = hose->pci_mem_offset;
+ res->start = (region->start + offset) & mask;
+ res->end = (region->end + offset) & mask;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+/* Fixup a bus resource into a linux resource */
+static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
+{
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ resource_size_t offset = 0, mask = (resource_size_t)-1;
+
+ if (res->flags & IORESOURCE_IO) {
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ mask = 0xffffffffu;
+ } else if (res->flags & IORESOURCE_MEM)
+ offset = hose->pci_mem_offset;
+
+ res->start = (res->start + offset) & mask;
+ res->end = (res->end + offset) & mask;
+}
+
+/* This header fixup will do the resource fixup for all devices as they are
+ * probed, but not for bridge ranges
+ */
+static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
+{
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ int i;
+
+ if (!hose) {
+ printk(KERN_ERR "No host bridge for PCI dev %s !\n",
+ pci_name(dev));
+ return;
+ }
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ struct resource *res = dev->resource + i;
+ if (!res->flags)
+ continue;
+ /* On platforms that have PCI_PROBE_ONLY set, we don't
+ * consider 0 as an unassigned BAR value. It's technically
+ * a valid value, but linux doesn't like it... so when we can
+ * re-assign things, we do so, but if we can't, we keep it
+ * around and hope for the best...
+ */
+ if (res->start == 0 && !(pci_flags & PCI_PROBE_ONLY)) {
+ pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]" \
+ "is unassigned\n",
+ pci_name(dev), i,
+ (unsigned long long)res->start,
+ (unsigned long long)res->end,
+ (unsigned int)res->flags);
+ res->end -= res->start;
+ res->start = 0;
+ res->flags |= IORESOURCE_UNSET;
+ continue;
+ }
+
+ pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
+ pci_name(dev), i,
+ (unsigned long long)res->start,\
+ (unsigned long long)res->end,
+ (unsigned int)res->flags);
+
+ fixup_resource(res, dev);
+
+ pr_debug("PCI:%s %016llx-%016llx\n",
+ pci_name(dev),
+ (unsigned long long)res->start,
+ (unsigned long long)res->end);
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
+
+/* This function tries to figure out if a bridge resource has been initialized
+ * by the firmware or not. It doesn't have to be absolutely bullet proof, but
+ * things go more smoothly when it gets it right. It should covers cases such
+ * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges
+ */
+static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
+ struct resource *res)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct pci_dev *dev = bus->self;
+ resource_size_t offset;
+ u16 command;
+ int i;
+
+ /* We don't do anything if PCI_PROBE_ONLY is set */
+ if (pci_flags & PCI_PROBE_ONLY)
+ return 0;
+
+ /* Job is a bit different between memory and IO */
+ if (res->flags & IORESOURCE_MEM) {
+ /* If the BAR is non-0 (res != pci_mem_offset) then it's
+ * probably been initialized by somebody
+ */
+ if (res->start != hose->pci_mem_offset)
+ return 0;
+
+ /* The BAR is 0, let's check if memory decoding is enabled on
+ * the bridge. If not, we consider it unassigned
+ */
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+ if ((command & PCI_COMMAND_MEMORY) == 0)
+ return 1;
+
+ /* Memory decoding is enabled and the BAR is 0. If any of
+ * the bridge resources covers that starting address (0 then
+ * it's good enough for us for memory
+ */
+ for (i = 0; i < 3; i++) {
+ if ((hose->mem_resources[i].flags & IORESOURCE_MEM) &&
+ hose->mem_resources[i].start == hose->pci_mem_offset)
+ return 0;
+ }
+
+ /* Well, it starts at 0 and we know it will collide so we may as
+ * well consider it as unassigned. That covers the Apple case.
+ */
+ return 1;
+ } else {
+ /* If the BAR is non-0, then we consider it assigned */
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ if (((res->start - offset) & 0xfffffffful) != 0)
+ return 0;
+
+ /* Here, we are a bit different than memory as typically IO
+ * space starting at low addresses -is- valid. What we do
+ * instead if that we consider as unassigned anything that
+ * doesn't have IO enabled in the PCI command register,
+ * and that's it.
+ */
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+ if (command & PCI_COMMAND_IO)
+ return 0;
+
+ /* It's starting at 0 and IO is disabled in the bridge, consider
+ * it unassigned
+ */
+ return 1;
+ }
+}
+
+/* Fixup resources of a PCI<->PCI bridge */
+static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
+{
+ struct resource *res;
+ int i;
+
+ struct pci_dev *dev = bus->self;
+
+ for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
+ res = bus->resource[i];
+ if (!res)
+ continue;
+ if (!res->flags)
+ continue;
+ if (i >= 3 && bus->self->transparent)
+ continue;
+
+ pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
+ pci_name(dev), i,
+ (unsigned long long)res->start,\
+ (unsigned long long)res->end,
+ (unsigned int)res->flags);
+
+ /* Perform fixup */
+ fixup_resource(res, dev);
+
+ /* Try to detect uninitialized P2P bridge resources,
+ * and clear them out so they get re-assigned later
+ */
+ if (pcibios_uninitialized_bridge_resource(bus, res)) {
+ res->flags = 0;
+ pr_debug("PCI:%s (unassigned)\n",
+ pci_name(dev));
+ } else {
+ pr_debug("PCI:%s %016llx-%016llx\n",
+ pci_name(dev),
+ (unsigned long long)res->start,
+ (unsigned long long)res->end);
+ }
+ }
+}
+
+void __devinit pcibios_setup_bus_self(struct pci_bus *bus)
+{
+ /* Fix up the bus resources for P2P bridges */
+ if (bus->self != NULL)
+ pcibios_fixup_bridge(bus);
+}
+
+void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+
+ pr_debug("PCI: Fixup bus devices %d (%s)\n",
+ bus->number, bus->self ? pci_name(bus->self) : "PHB");
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ struct dev_archdata *sd = &dev->dev.archdata;
+
+ /* Setup OF node pointer in archdata */
+ sd->of_node = pci_device_to_OF_node(dev);
+
+ /* Fixup NUMA node as it may not be setup yet by the generic
+ * code and is needed by the DMA init
+ */
+ set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
+
+ /* Hook up default DMA ops */
+ sd->dma_ops = pci_dma_ops;
+ sd->dma_data = (void *)PCI_DRAM_OFFSET;
+
+ /* Read default IRQs and fixup if necessary */
+ pci_read_irq_line(dev);
+ }
+}
+
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+ /* When called from the generic PCI probe, read PCI<->PCI bridge
+ * bases. This is -not- called when generating the PCI tree from
+ * the OF device-tree.
+ */
+ if (bus->self != NULL)
+ pci_read_bridge_bases(bus);
+
+ /* Now fixup the bus bus */
+ pcibios_setup_bus_self(bus);
+
+ /* Now fixup devices on that bus */
+ pcibios_setup_bus_devices(bus);
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
+
+static int skip_isa_ioresource_align(struct pci_dev *dev)
+{
+ if ((pci_flags & PCI_CAN_SKIP_ISA_ALIGN) &&
+ !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
+ return 1;
+ return 0;
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void pcibios_align_resource(void *data, struct resource *res,
+ resource_size_t size, resource_size_t align)
+{
+ struct pci_dev *dev = data;
+
+ if (res->flags & IORESOURCE_IO) {
+ resource_size_t start = res->start;
+
+ if (skip_isa_ioresource_align(dev))
+ return;
+ if (start & 0x300) {
+ start = (start + 0x3ff) & ~0x3ff;
+ res->start = start;
+ }
+ }
+}
+EXPORT_SYMBOL(pcibios_align_resource);
+
+/*
+ * Reparent resource children of pr that conflict with res
+ * under res, and make res replace those children.
+ */
+static int __init reparent_resources(struct resource *parent,
+ struct resource *res)
+{
+ struct resource *p, **pp;
+ struct resource **firstpp = NULL;
+
+ for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
+ if (p->end < res->start)
+ continue;
+ if (res->end < p->start)
+ break;
+ if (p->start < res->start || p->end > res->end)
+ return -1; /* not completely contained */
+ if (firstpp == NULL)
+ firstpp = pp;
+ }
+ if (firstpp == NULL)
+ return -1; /* didn't find any conflicting entries? */
+ res->parent = parent;
+ res->child = *firstpp;
+ res->sibling = *pp;
+ *firstpp = res;
+ *pp = NULL;
+ for (p = res->child; p != NULL; p = p->sibling) {
+ p->parent = res;
+ pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
+ p->name,
+ (unsigned long long)p->start,
+ (unsigned long long)p->end, res->name);
+ }
+ return 0;
+}
+
+/*
+ * Handle resources of PCI devices. If the world were perfect, we could
+ * just allocate all the resource regions and do nothing more. It isn't.
+ * On the other hand, we cannot just re-allocate all devices, as it would
+ * require us to know lots of host bridge internals. So we attempt to
+ * keep as much of the original configuration as possible, but tweak it
+ * when it's found to be wrong.
+ *
+ * Known BIOS problems we have to work around:
+ * - I/O or memory regions not configured
+ * - regions configured, but not enabled in the command register
+ * - bogus I/O addresses above 64K used
+ * - expansion ROMs left enabled (this may sound harmless, but given
+ * the fact the PCI specs explicitly allow address decoders to be
+ * shared between expansion ROMs and other resource regions, it's
+ * at least dangerous)
+ *
+ * Our solution:
+ * (1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ * This gives us fixed barriers on where we can allocate.
+ * (2) Allocate resources for all enabled devices. If there is
+ * a collision, just mark the resource as unallocated. Also
+ * disable expansion ROMs during this step.
+ * (3) Try to allocate resources for disabled devices. If the
+ * resources were assigned correctly, everything goes well,
+ * if they weren't, they won't disturb allocation of other
+ * resources.
+ * (4) Assign new addresses to resources which were either
+ * not configured at all or misconfigured. If explicitly
+ * requested by the user, configure expansion ROM address
+ * as well.
+ */
+
+void pcibios_allocate_bus_resources(struct pci_bus *bus)
+{
+ struct pci_bus *b;
+ int i;
+ struct resource *res, *pr;
+
+ pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
+ pci_domain_nr(bus), bus->number);
+
+ for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
+ res = bus->resource[i];
+ if (!res || !res->flags
+ || res->start > res->end || res->parent)
+ continue;
+ if (bus->parent == NULL)
+ pr = (res->flags & IORESOURCE_IO) ?
+ &ioport_resource : &iomem_resource;
+ else {
+ /* Don't bother with non-root busses when
+ * re-assigning all resources. We clear the
+ * resource flags as if they were colliding
+ * and as such ensure proper re-allocation
+ * later.
+ */
+ if (pci_flags & PCI_REASSIGN_ALL_RSRC)
+ goto clear_resource;
+ pr = pci_find_parent_resource(bus->self, res);
+ if (pr == res) {
+ /* this happens when the generic PCI
+ * code (wrongly) decides that this
+ * bridge is transparent -- paulus
+ */
+ continue;
+ }
+ }
+
+ pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
+ "[0x%x], parent %p (%s)\n",
+ bus->self ? pci_name(bus->self) : "PHB",
+ bus->number, i,
+ (unsigned long long)res->start,
+ (unsigned long long)res->end,
+ (unsigned int)res->flags,
+ pr, (pr && pr->name) ? pr->name : "nil");
+
+ if (pr && !(pr->flags & IORESOURCE_UNSET)) {
+ if (request_resource(pr, res) == 0)
+ continue;
+ /*
+ * Must be a conflict with an existing entry.
+ * Move that entry (or entries) under the
+ * bridge resource and try again.
+ */
+ if (reparent_resources(pr, res) == 0)
+ continue;
+ }
+ printk(KERN_WARNING "PCI: Cannot allocate resource region "
+ "%d of PCI bridge %d, will remap\n", i, bus->number);
+clear_resource:
+ res->flags = 0;
+ }
+
+ list_for_each_entry(b, &bus->children, node)
+ pcibios_allocate_bus_resources(b);
+}
+
+static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
+{
+ struct resource *pr, *r = &dev->resource[idx];
+
+ pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
+ pci_name(dev), idx,
+ (unsigned long long)r->start,
+ (unsigned long long)r->end,
+ (unsigned int)r->flags);
+
+ pr = pci_find_parent_resource(dev, r);
+ if (!pr || (pr->flags & IORESOURCE_UNSET) ||
+ request_resource(pr, r) < 0) {
+ printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
+ " of device %s, will remap\n", idx, pci_name(dev));
+ if (pr)
+ pr_debug("PCI: parent is %p: %016llx-%016llx [%x]\n",
+ pr,
+ (unsigned long long)pr->start,
+ (unsigned long long)pr->end,
+ (unsigned int)pr->flags);
+ /* We'll assign a new address later */
+ r->flags |= IORESOURCE_UNSET;
+ r->end -= r->start;
+ r->start = 0;
+ }
+}
+
+static void __init pcibios_allocate_resources(int pass)
+{
+ struct pci_dev *dev = NULL;
+ int idx, disabled;
+ u16 command;
+ struct resource *r;
+
+ for_each_pci_dev(dev) {
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+ for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
+ r = &dev->resource[idx];
+ if (r->parent) /* Already allocated */
+ continue;
+ if (!r->flags || (r->flags & IORESOURCE_UNSET))
+ continue; /* Not assigned at all */
+ /* We only allocate ROMs on pass 1 just in case they
+ * have been screwed up by firmware
+ */
+ if (idx == PCI_ROM_RESOURCE)
+ disabled = 1;
+ if (r->flags & IORESOURCE_IO)
+ disabled = !(command & PCI_COMMAND_IO);
+ else
+ disabled = !(command & PCI_COMMAND_MEMORY);
+ if (pass == disabled)
+ alloc_resource(dev, idx);
+ }
+ if (pass)
+ continue;
+ r = &dev->resource[PCI_ROM_RESOURCE];
+ if (r->flags) {
+ /* Turn the ROM off, leave the resource region,
+ * but keep it unregistered.
+ */
+ u32 reg;
+ pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+ if (reg & PCI_ROM_ADDRESS_ENABLE) {
+ pr_debug("PCI: Switching off ROM of %s\n",
+ pci_name(dev));
+ r->flags &= ~IORESOURCE_ROM_ENABLE;
+ pci_write_config_dword(dev, dev->rom_base_reg,
+ reg & ~PCI_ROM_ADDRESS_ENABLE);
+ }
+ }
+ }
+}
+
+static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ resource_size_t offset;
+ struct resource *res, *pres;
+ int i;
+
+ pr_debug("Reserving legacy ranges for domain %04x\n",
+ pci_domain_nr(bus));
+
+ /* Check for IO */
+ if (!(hose->io_resource.flags & IORESOURCE_IO))
+ goto no_io;
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ BUG_ON(res == NULL);
+ res->name = "Legacy IO";
+ res->flags = IORESOURCE_IO;
+ res->start = offset;
+ res->end = (offset + 0xfff) & 0xfffffffful;
+ pr_debug("Candidate legacy IO: %pR\n", res);
+ if (request_resource(&hose->io_resource, res)) {
+ printk(KERN_DEBUG
+ "PCI %04x:%02x Cannot reserve Legacy IO %pR\n",
+ pci_domain_nr(bus), bus->number, res);
+ kfree(res);
+ }
+
+ no_io:
+ /* Check for memory */
+ offset = hose->pci_mem_offset;
+ pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset);
+ for (i = 0; i < 3; i++) {
+ pres = &hose->mem_resources[i];
+ if (!(pres->flags & IORESOURCE_MEM))
+ continue;
+ pr_debug("hose mem res: %pR\n", pres);
+ if ((pres->start - offset) <= 0xa0000 &&
+ (pres->end - offset) >= 0xbffff)
+ break;
+ }
+ if (i >= 3)
+ return;
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ BUG_ON(res == NULL);
+ res->name = "Legacy VGA memory";
+ res->flags = IORESOURCE_MEM;
+ res->start = 0xa0000 + offset;
+ res->end = 0xbffff + offset;
+ pr_debug("Candidate VGA memory: %pR\n", res);
+ if (request_resource(pres, res)) {
+ printk(KERN_DEBUG
+ "PCI %04x:%02x Cannot reserve VGA memory %pR\n",
+ pci_domain_nr(bus), bus->number, res);
+ kfree(res);
+ }
+}
+
+void __init pcibios_resource_survey(void)
+{
+ struct pci_bus *b;
+
+ /* Allocate and assign resources. If we re-assign everything, then
+ * we skip the allocate phase
+ */
+ list_for_each_entry(b, &pci_root_buses, node)
+ pcibios_allocate_bus_resources(b);
+
+ if (!(pci_flags & PCI_REASSIGN_ALL_RSRC)) {
+ pcibios_allocate_resources(0);
+ pcibios_allocate_resources(1);
+ }
+
+ /* Before we start assigning unassigned resource, we try to reserve
+ * the low IO area and the VGA memory area if they intersect the
+ * bus available resources to avoid allocating things on top of them
+ */
+ if (!(pci_flags & PCI_PROBE_ONLY)) {
+ list_for_each_entry(b, &pci_root_buses, node)
+ pcibios_reserve_legacy_regions(b);
+ }
+
+ /* Now, if the platform didn't decide to blindly trust the firmware,
+ * we proceed to assigning things that were left unassigned
+ */
+ if (!(pci_flags & PCI_PROBE_ONLY)) {
+ pr_debug("PCI: Assigning unassigned resources...\n");
+ pci_assign_unassigned_resources();
+ }
+}
+
+#ifdef CONFIG_HOTPLUG
+
+/* This is used by the PCI hotplug driver to allocate resource
+ * of newly plugged busses. We can try to consolidate with the
+ * rest of the code later, for now, keep it as-is as our main
+ * resource allocation function doesn't deal with sub-trees yet.
+ */
+void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+ struct pci_bus *child_bus;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ struct resource *r = &dev->resource[i];
+
+ if (r->parent || !r->start || !r->flags)
+ continue;
+
+ pr_debug("PCI: Claiming %s: "
+ "Resource %d: %016llx..%016llx [%x]\n",
+ pci_name(dev), i,
+ (unsigned long long)r->start,
+ (unsigned long long)r->end,
+ (unsigned int)r->flags);
+
+ pci_claim_resource(dev, i);
+ }
+ }
+
+ list_for_each_entry(child_bus, &bus->children, node)
+ pcibios_claim_one_bus(child_bus);
+}
+EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
+
+
+/* pcibios_finish_adding_to_bus
+ *
+ * This is to be called by the hotplug code after devices have been
+ * added to a bus, this include calling it for a PHB that is just
+ * being added
+ */
+void pcibios_finish_adding_to_bus(struct pci_bus *bus)
+{
+ pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n",
+ pci_domain_nr(bus), bus->number);
+
+ /* Allocate bus and devices resources */
+ pcibios_allocate_bus_resources(bus);
+ pcibios_claim_one_bus(bus);
+
+ /* Add new devices to global lists. Register in proc, sysfs. */
+ pci_bus_add_devices(bus);
+
+ /* Fixup EEH */
+ eeh_add_device_tree_late(bus);
+}
+EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
+
+#endif /* CONFIG_HOTPLUG */
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+ return pci_enable_resources(dev, mask);
+}
+
+void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
+{
+ struct pci_bus *bus = hose->bus;
+ struct resource *res;
+ int i;
+
+ /* Hookup PHB IO resource */
+ bus->resource[0] = res = &hose->io_resource;
+
+ if (!res->flags) {
+ printk(KERN_WARNING "PCI: I/O resource not set for host"
+ " bridge %s (domain %d)\n",
+ hose->dn->full_name, hose->global_number);
+ /* Workaround for lack of IO resource only on 32-bit */
+ res->start = (unsigned long)hose->io_base_virt - isa_io_base;
+ res->end = res->start + IO_SPACE_LIMIT;
+ res->flags = IORESOURCE_IO;
+ }
+
+ pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n",
+ (unsigned long long)res->start,
+ (unsigned long long)res->end,
+ (unsigned long)res->flags);
+
+ /* Hookup PHB Memory resources */
+ for (i = 0; i < 3; ++i) {
+ res = &hose->mem_resources[i];
+ if (!res->flags) {
+ if (i > 0)
+ continue;
+ printk(KERN_ERR "PCI: Memory resource 0 not set for "
+ "host bridge %s (domain %d)\n",
+ hose->dn->full_name, hose->global_number);
+
+ /* Workaround for lack of MEM resource only on 32-bit */
+ res->start = hose->pci_mem_offset;
+ res->end = (resource_size_t)-1LL;
+ res->flags = IORESOURCE_MEM;
+
+ }
+ bus->resource[i+1] = res;
+
+ pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n",
+ i, (unsigned long long)res->start,
+ (unsigned long long)res->end,
+ (unsigned long)res->flags);
+ }
+
+ pr_debug("PCI: PHB MEM offset = %016llx\n",
+ (unsigned long long)hose->pci_mem_offset);
+ pr_debug("PCI: PHB IO offset = %08lx\n",
+ (unsigned long)hose->io_base_virt - _IO_BASE);
+}
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type) \
+static int \
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ return PCIBIOS_DEVICE_NOT_FOUND; \
+}
+
+static int
+null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 *val)
+{
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int
+null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+ int len, u32 val)
+{
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static struct pci_ops null_pci_ops = {
+ .read = null_read_config,
+ .write = null_write_config,
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_bus *
+fake_pci_bus(struct pci_controller *hose, int busnr)
+{
+ static struct pci_bus bus;
+
+ if (!hose)
+ printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+
+ bus.number = busnr;
+ bus.sysdata = hose;
+ bus.ops = hose ? hose->ops : &null_pci_ops;
+ return &bus;
+}
+
+#define EARLY_PCI_OP(rw, size, type) \
+int early_##rw##_config_##size(struct pci_controller *hose, int bus, \
+ int devfn, int offset, type value) \
+{ \
+ return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \
+ devfn, offset, value); \
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+int early_find_capability(struct pci_controller *hose, int bus, int devfn,
+ int cap)
+{
+ return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
+}
diff --git a/arch/microblaze/pci/pci_32.c b/arch/microblaze/pci/pci_32.c
new file mode 100644
index 00000000000..3c3d808d7ce
--- /dev/null
+++ b/arch/microblaze/pci/pci_32.c
@@ -0,0 +1,431 @@
+/*
+ * Common pmac/prep/chrp pci routines. -- Cort
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#undef DEBUG
+
+unsigned long isa_io_base;
+unsigned long pci_dram_offset;
+int pcibios_assign_bus_offset = 1;
+
+static u8 *pci_to_OF_bus_map;
+
+/* By default, we don't re-assign bus numbers. We do this only on
+ * some pmacs
+ */
+static int pci_assign_all_buses;
+
+static int pci_bus_count;
+
+/*
+ * Functions below are used on OpenFirmware machines.
+ */
+static void
+make_one_node_map(struct device_node *node, u8 pci_bus)
+{
+ const int *bus_range;
+ int len;
+
+ if (pci_bus >= pci_bus_count)
+ return;
+ bus_range = of_get_property(node, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, "
+ "assuming it starts at 0\n", node->full_name);
+ pci_to_OF_bus_map[pci_bus] = 0;
+ } else
+ pci_to_OF_bus_map[pci_bus] = bus_range[0];
+
+ for_each_child_of_node(node, node) {
+ struct pci_dev *dev;
+ const unsigned int *class_code, *reg;
+
+ class_code = of_get_property(node, "class-code", NULL);
+ if (!class_code ||
+ ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+ continue;
+ reg = of_get_property(node, "reg", NULL);
+ if (!reg)
+ continue;
+ dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff));
+ if (!dev || !dev->subordinate) {
+ pci_dev_put(dev);
+ continue;
+ }
+ make_one_node_map(node, dev->subordinate->number);
+ pci_dev_put(dev);
+ }
+}
+
+void
+pcibios_make_OF_bus_map(void)
+{
+ int i;
+ struct pci_controller *hose, *tmp;
+ struct property *map_prop;
+ struct device_node *dn;
+
+ pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL);
+ if (!pci_to_OF_bus_map) {
+ printk(KERN_ERR "Can't allocate OF bus map !\n");
+ return;
+ }
+
+ /* We fill the bus map with invalid values, that helps
+ * debugging.
+ */
+ for (i = 0; i < pci_bus_count; i++)
+ pci_to_OF_bus_map[i] = 0xff;
+
+ /* For each hose, we begin searching bridges */
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ struct device_node *node = hose->dn;
+
+ if (!node)
+ continue;
+ make_one_node_map(node, hose->first_busno);
+ }
+ dn = of_find_node_by_path("/");
+ map_prop = of_find_property(dn, "pci-OF-bus-map", NULL);
+ if (map_prop) {
+ BUG_ON(pci_bus_count > map_prop->length);
+ memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count);
+ }
+ of_node_put(dn);
+#ifdef DEBUG
+ printk(KERN_INFO "PCI->OF bus map:\n");
+ for (i = 0; i < pci_bus_count; i++) {
+ if (pci_to_OF_bus_map[i] == 0xff)
+ continue;
+ printk(KERN_INFO "%d -> %d\n", i, pci_to_OF_bus_map[i]);
+ }
+#endif
+}
+
+typedef int (*pci_OF_scan_iterator)(struct device_node *node, void *data);
+
+static struct device_node *scan_OF_pci_childs(struct device_node *parent,
+ pci_OF_scan_iterator filter, void *data)
+{
+ struct device_node *node;
+ struct device_node *sub_node;
+
+ for_each_child_of_node(parent, node) {
+ const unsigned int *class_code;
+
+ if (filter(node, data)) {
+ of_node_put(node);
+ return node;
+ }
+
+ /* For PCI<->PCI bridges or CardBus bridges, we go down
+ * Note: some OFs create a parent node "multifunc-device" as
+ * a fake root for all functions of a multi-function device,
+ * we go down them as well.
+ */
+ class_code = of_get_property(node, "class-code", NULL);
+ if ((!class_code ||
+ ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
+ strcmp(node->name, "multifunc-device"))
+ continue;
+ sub_node = scan_OF_pci_childs(node, filter, data);
+ if (sub_node) {
+ of_node_put(node);
+ return sub_node;
+ }
+ }
+ return NULL;
+}
+
+static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
+ unsigned int devfn)
+{
+ struct device_node *np, *cnp;
+ const u32 *reg;
+ unsigned int psize;
+
+ for_each_child_of_node(parent, np) {
+ reg = of_get_property(np, "reg", &psize);
+ if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn)
+ return np;
+
+ /* Note: some OFs create a parent node "multifunc-device" as
+ * a fake root for all functions of a multi-function device,
+ * we go down them as well. */
+ if (!strcmp(np->name, "multifunc-device")) {
+ cnp = scan_OF_for_pci_dev(np, devfn);
+ if (cnp)
+ return cnp;
+ }
+ }
+ return NULL;
+}
+
+
+static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
+{
+ struct device_node *parent, *np;
+
+ /* Are we a root bus ? */
+ if (bus->self == NULL || bus->parent == NULL) {
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ if (hose == NULL)
+ return NULL;
+ return of_node_get(hose->dn);
+ }
+
+ /* not a root bus, we need to get our parent */
+ parent = scan_OF_for_pci_bus(bus->parent);
+ if (parent == NULL)
+ return NULL;
+
+ /* now iterate for children for a match */
+ np = scan_OF_for_pci_dev(parent, bus->self->devfn);
+ of_node_put(parent);
+
+ return np;
+}
+
+/*
+ * Scans the OF tree for a device node matching a PCI device
+ */
+struct device_node *
+pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
+{
+ struct device_node *parent, *np;
+
+ pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
+ parent = scan_OF_for_pci_bus(bus);
+ if (parent == NULL)
+ return NULL;
+ pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>");
+ np = scan_OF_for_pci_dev(parent, devfn);
+ of_node_put(parent);
+ pr_debug(" result is %s\n", np ? np->full_name : "<NULL>");
+
+ /* XXX most callers don't release the returned node
+ * mostly because ppc64 doesn't increase the refcount,
+ * we need to fix that.
+ */
+ return np;
+}
+EXPORT_SYMBOL(pci_busdev_to_OF_node);
+
+struct device_node*
+pci_device_to_OF_node(struct pci_dev *dev)
+{
+ return pci_busdev_to_OF_node(dev->bus, dev->devfn);
+}
+EXPORT_SYMBOL(pci_device_to_OF_node);
+
+static int
+find_OF_pci_device_filter(struct device_node *node, void *data)
+{
+ return ((void *)node == data);
+}
+
+/*
+ * Returns the PCI device matching a given OF node
+ */
+int
+pci_device_from_OF_node(struct device_node *node, u8 *bus, u8 *devfn)
+{
+ const unsigned int *reg;
+ struct pci_controller *hose;
+ struct pci_dev *dev = NULL;
+
+ /* Make sure it's really a PCI device */
+ hose = pci_find_hose_for_OF_device(node);
+ if (!hose || !hose->dn)
+ return -ENODEV;
+ if (!scan_OF_pci_childs(hose->dn,
+ find_OF_pci_device_filter, (void *)node))
+ return -ENODEV;
+ reg = of_get_property(node, "reg", NULL);
+ if (!reg)
+ return -ENODEV;
+ *bus = (reg[0] >> 16) & 0xff;
+ *devfn = ((reg[0] >> 8) & 0xff);
+
+ /* Ok, here we need some tweak. If we have already renumbered
+ * all busses, we can't rely on the OF bus number any more.
+ * the pci_to_OF_bus_map is not enough as several PCI busses
+ * may match the same OF bus number.
+ */
+ if (!pci_to_OF_bus_map)
+ return 0;
+
+ for_each_pci_dev(dev)
+ if (pci_to_OF_bus_map[dev->bus->number] == *bus &&
+ dev->devfn == *devfn) {
+ *bus = dev->bus->number;
+ pci_dev_put(dev);
+ return 0;
+ }
+
+ return -ENODEV;
+}
+EXPORT_SYMBOL(pci_device_from_OF_node);
+
+/* We create the "pci-OF-bus-map" property now so it appears in the
+ * /proc device tree
+ */
+void __init
+pci_create_OF_bus_map(void)
+{
+ struct property *of_prop;
+ struct device_node *dn;
+
+ of_prop = (struct property *) alloc_bootmem(sizeof(struct property) + \
+ 256);
+ if (!of_prop)
+ return;
+ dn = of_find_node_by_path("/");
+ if (dn) {
+ memset(of_prop, -1, sizeof(struct property) + 256);
+ of_prop->name = "pci-OF-bus-map";
+ of_prop->length = 256;
+ of_prop->value = &of_prop[1];
+ prom_add_property(dn, of_prop);
+ of_node_put(dn);
+ }
+}
+
+static void __devinit pcibios_scan_phb(struct pci_controller *hose)
+{
+ struct pci_bus *bus;
+ struct device_node *node = hose->dn;
+ unsigned long io_offset;
+ struct resource *res = &hose->io_resource;
+
+ pr_debug("PCI: Scanning PHB %s\n",
+ node ? node->full_name : "<NO NAME>");
+
+ /* Create an empty bus for the toplevel */
+ bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
+ if (bus == NULL) {
+ printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
+ hose->global_number);
+ return;
+ }
+ bus->secondary = hose->first_busno;
+ hose->bus = bus;
+
+ /* Fixup IO space offset */
+ io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+ res->start = (res->start + io_offset) & 0xffffffffu;
+ res->end = (res->end + io_offset) & 0xffffffffu;
+
+ /* Wire up PHB bus resources */
+ pcibios_setup_phb_resources(hose);
+
+ /* Scan children */
+ hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+}
+
+static int __init pcibios_init(void)
+{
+ struct pci_controller *hose, *tmp;
+ int next_busno = 0;
+
+ printk(KERN_INFO "PCI: Probing PCI hardware\n");
+
+ if (pci_flags & PCI_REASSIGN_ALL_BUS) {
+ printk(KERN_INFO "setting pci_asign_all_busses\n");
+ pci_assign_all_buses = 1;
+ }
+
+ /* Scan all of the recorded PCI controllers. */
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ if (pci_assign_all_buses)
+ hose->first_busno = next_busno;
+ hose->last_busno = 0xff;
+ pcibios_scan_phb(hose);
+ printk(KERN_INFO "calling pci_bus_add_devices()\n");
+ pci_bus_add_devices(hose->bus);
+ if (pci_assign_all_buses || next_busno <= hose->last_busno)
+ next_busno = hose->last_busno + \
+ pcibios_assign_bus_offset;
+ }
+ pci_bus_count = next_busno;
+
+ /* OpenFirmware based machines need a map of OF bus
+ * numbers vs. kernel bus numbers since we may have to
+ * remap them.
+ */
+ if (pci_assign_all_buses)
+ pcibios_make_OF_bus_map();
+
+ /* Call common code to handle resource allocation */
+ pcibios_resource_survey();
+
+ return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+static struct pci_controller*
+pci_bus_to_hose(int bus)
+{
+ struct pci_controller *hose, *tmp;
+
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+ if (bus >= hose->first_busno && bus <= hose->last_busno)
+ return hose;
+ return NULL;
+}
+
+/* Provide information on locations of various I/O regions in physical
+ * memory. Do this on a per-card basis so that we choose the right
+ * root bridge.
+ * Note that the returned IO or memory base is a physical address
+ */
+
+long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
+{
+ struct pci_controller *hose;
+ long result = -EOPNOTSUPP;
+
+ hose = pci_bus_to_hose(bus);
+ if (!hose)
+ return -ENODEV;
+
+ switch (which) {
+ case IOBASE_BRIDGE_NUMBER:
+ return (long)hose->first_busno;
+ case IOBASE_MEMORY:
+ return (long)hose->pci_mem_offset;
+ case IOBASE_IO:
+ return (long)hose->io_base_phys;
+ case IOBASE_ISA_IO:
+ return (long)isa_io_base;
+ case IOBASE_ISA_MEM:
+ return (long)isa_mem_base;
+ }
+
+ return result;
+}
diff --git a/arch/microblaze/pci/xilinx_pci.c b/arch/microblaze/pci/xilinx_pci.c
new file mode 100644
index 00000000000..7869a41b0f9
--- /dev/null
+++ b/arch/microblaze/pci/xilinx_pci.c
@@ -0,0 +1,168 @@
+/*
+ * PCI support for Xilinx plbv46_pci soft-core which can be used on
+ * Xilinx Virtex ML410 / ML510 boards.
+ *
+ * Copyright 2009 Roderick Colenbrander
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ *
+ * The pci bridge fixup code was copied from ppc4xx_pci.c and was written
+ * by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#define XPLB_PCI_ADDR 0x10c
+#define XPLB_PCI_DATA 0x110
+#define XPLB_PCI_BUS 0x114
+
+#define PCI_HOST_ENABLE_CMD (PCI_COMMAND_SERR | PCI_COMMAND_PARITY | \
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY)
+
+static struct of_device_id xilinx_pci_match[] = {
+ { .compatible = "xlnx,plbv46-pci-1.03.a", },
+ {}
+};
+
+/**
+ * xilinx_pci_fixup_bridge - Block Xilinx PHB configuration.
+ */
+static void xilinx_pci_fixup_bridge(struct pci_dev *dev)
+{
+ struct pci_controller *hose;
+ int i;
+
+ if (dev->devfn || dev->bus->self)
+ return;
+
+ hose = pci_bus_to_host(dev->bus);
+ if (!hose)
+ return;
+
+ if (!of_match_node(xilinx_pci_match, hose->dn))
+ return;
+
+ /* Hide the PCI host BARs from the kernel as their content doesn't
+ * fit well in the resource management
+ */
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+
+ dev_info(&dev->dev, "Hiding Xilinx plb-pci host bridge resources %s\n",
+ pci_name(dev));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, xilinx_pci_fixup_bridge);
+
+#ifdef DEBUG
+/**
+ * xilinx_pci_exclude_device - Don't do config access for non-root bus
+ *
+ * This is a hack. Config access to any bus other than bus 0 does not
+ * currently work on the ML510 so we prevent it here.
+ */
+static int
+xilinx_pci_exclude_device(struct pci_controller *hose, u_char bus, u8 devfn)
+{
+ return (bus != 0);
+}
+
+/**
+ * xilinx_early_pci_scan - List pci config space for available devices
+ *
+ * List pci devices in very early phase.
+ */
+void __init xilinx_early_pci_scan(struct pci_controller *hose)
+{
+ u32 bus = 0;
+ u32 val, dev, func, offset;
+
+ /* Currently we have only 2 device connected - up-to 32 devices */
+ for (dev = 0; dev < 2; dev++) {
+ /* List only first function number - up-to 8 functions */
+ for (func = 0; func < 1; func++) {
+ printk(KERN_INFO "%02x:%02x:%02x", bus, dev, func);
+ /* read the first 64 standardized bytes */
+ /* Up-to 192 bytes can be list of capabilities */
+ for (offset = 0; offset < 64; offset += 4) {
+ early_read_config_dword(hose, bus,
+ PCI_DEVFN(dev, func), offset, &val);
+ if (offset == 0 && val == 0xFFFFFFFF) {
+ printk(KERN_CONT "\nABSENT");
+ break;
+ }
+ if (!(offset % 0x10))
+ printk(KERN_CONT "\n%04x: ", offset);
+
+ printk(KERN_CONT "%08x ", val);
+ }
+ printk(KERN_INFO "\n");
+ }
+ }
+}
+#else
+void __init xilinx_early_pci_scan(struct pci_controller *hose)
+{
+}
+#endif
+
+/**
+ * xilinx_pci_init - Find and register a Xilinx PCI host bridge
+ */
+void __init xilinx_pci_init(void)
+{
+ struct pci_controller *hose;
+ struct resource r;
+ void __iomem *pci_reg;
+ struct device_node *pci_node;
+
+ pci_node = of_find_matching_node(NULL, xilinx_pci_match);
+ if (!pci_node)
+ return;
+
+ if (of_address_to_resource(pci_node, 0, &r)) {
+ pr_err("xilinx-pci: cannot resolve base address\n");
+ return;
+ }
+
+ hose = pcibios_alloc_controller(pci_node);
+ if (!hose) {
+ pr_err("xilinx-pci: pcibios_alloc_controller() failed\n");
+ return;
+ }
+
+ /* Setup config space */
+ setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR,
+ r.start + XPLB_PCI_DATA,
+ INDIRECT_TYPE_SET_CFG_TYPE);
+
+ /* According to the xilinx plbv46_pci documentation the soft-core starts
+ * a self-init when the bus master enable bit is set. Without this bit
+ * set the pci bus can't be scanned.
+ */
+ early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD);
+
+ /* Set the max latency timer to 255 */
+ early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff);
+
+ /* Set the max bus number to 255, and bus/subbus no's to 0 */
+ pci_reg = of_iomap(pci_node, 0);
+ out_be32(pci_reg + XPLB_PCI_BUS, 0x000000ff);
+ iounmap(pci_reg);
+
+ /* Register the host bridge with the linux kernel! */
+ pci_process_bridge_OF_ranges(hose, pci_node,
+ INDIRECT_TYPE_SET_CFG_TYPE);
+
+ pr_info("xilinx-pci: Registered PCI host bridge\n");
+ xilinx_early_pci_scan(hose);
+}
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 591ca0cd4c2..29e86923d1b 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -812,9 +812,9 @@ config DMA_COHERENT
config DMA_NONCOHERENT
bool
- select DMA_NEED_PCI_MAP_STATE
+ select NEED_DMA_MAP_STATE
-config DMA_NEED_PCI_MAP_STATE
+config NEED_DMA_MAP_STATE
bool
config SYS_HAS_EARLY_PRINTK
diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c
index 379536e3abd..be7e92ea01f 100644
--- a/arch/mips/alchemy/devboards/db1200/setup.c
+++ b/arch/mips/alchemy/devboards/db1200/setup.c
@@ -60,43 +60,6 @@ void __init board_setup(void)
wmb();
}
-/* use the hexleds to count the number of times the cpu has entered
- * wait, the dots to indicate whether the CPU is currently idle or
- * active (dots off = sleeping, dots on = working) for cases where
- * the number doesn't change for a long(er) period of time.
- */
-static void db1200_wait(void)
-{
- __asm__(" .set push \n"
- " .set mips3 \n"
- " .set noreorder \n"
- " cache 0x14, 0(%0) \n"
- " cache 0x14, 32(%0) \n"
- " cache 0x14, 64(%0) \n"
- /* dots off: we're about to call wait */
- " lui $26, 0xb980 \n"
- " ori $27, $0, 3 \n"
- " sb $27, 0x18($26) \n"
- " sync \n"
- " nop \n"
- " wait \n"
- " nop \n"
- " nop \n"
- " nop \n"
- " nop \n"
- " nop \n"
- /* dots on: there's work to do, increment cntr */
- " lui $26, 0xb980 \n"
- " sb $0, 0x18($26) \n"
- " lui $26, 0xb9c0 \n"
- " lb $27, 0($26) \n"
- " addiu $27, $27, 1 \n"
- " sb $27, 0($26) \n"
- " sync \n"
- " .set pop \n"
- : : "r" (db1200_wait));
-}
-
static int __init db1200_arch_init(void)
{
/* GPIO7 is low-level triggered CPLD cascade */
@@ -110,9 +73,6 @@ static int __init db1200_arch_init(void)
irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
- if (cpu_wait)
- cpu_wait = db1200_wait;
-
return 0;
}
arch_initcall(db1200_arch_init);
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 246df7aca2e..2fafc78e5ce 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = {
.on = vlynq_on,
.off = vlynq_off,
},
- .reset_bit = 26,
+ .reset_bit = 16,
.gpio_bit = 19,
};
@@ -600,6 +600,7 @@ static int __init ar7_register_devices(void)
}
if (ar7_has_high_cpmac()) {
+ res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
if (!res) {
cpmac_get_mac(1, cpmac_high_data.dev_addr);
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index ea17941168c..8dba8cfb752 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -18,6 +18,7 @@
#include <asm/addrspace.h>
#include <bcm63xx_board.h>
#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_uart.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_io.h>
#include <bcm63xx_dev_pci.h>
@@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = {
.name = "96338GW",
.expected_cpu_id = 0x6338,
+ .has_uart0 = 1,
.has_enet0 = 1,
.enet0 = {
.force_speed_100 = 1,
@@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = {
.name = "96338W",
.expected_cpu_id = 0x6338,
+ .has_uart0 = 1,
.has_enet0 = 1,
.enet0 = {
.force_speed_100 = 1,
@@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = {
static struct board_info __initdata board_96345gw2 = {
.name = "96345GW2",
.expected_cpu_id = 0x6345,
+
+ .has_uart0 = 1,
};
#endif
@@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = {
.name = "96348R",
.expected_cpu_id = 0x6348,
+ .has_uart0 = 1,
.has_enet0 = 1,
.has_pci = 1,
@@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = {
.name = "96348GW-10",
.expected_cpu_id = 0x6348,
+ .has_uart0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.has_pci = 1,
@@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = {
.name = "96348GW-11",
.expected_cpu_id = 0x6348,
+ .has_uart0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.has_pci = 1,
@@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = {
.name = "96348GW",
.expected_cpu_id = 0x6348,
+ .has_uart0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.has_pci = 1,
@@ -349,9 +358,10 @@ static struct board_info __initdata board_FAST2404 = {
.name = "F@ST2404",
.expected_cpu_id = 0x6348,
- .has_enet0 = 1,
- .has_enet1 = 1,
- .has_pci = 1,
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
.enet0 = {
.has_phy = 1,
@@ -368,10 +378,30 @@ static struct board_info __initdata board_FAST2404 = {
.has_ehci0 = 1,
};
+static struct board_info __initdata board_rta1025w_16 = {
+ .name = "RTA1025W_16",
+ .expected_cpu_id = 0x6348,
+
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+};
+
+
static struct board_info __initdata board_DV201AMR = {
.name = "DV201AMR",
.expected_cpu_id = 0x6348,
+ .has_uart0 = 1,
.has_pci = 1,
.has_ohci0 = 1,
@@ -391,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = {
.name = "96348GW-A",
.expected_cpu_id = 0x6348,
+ .has_uart0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.has_pci = 1,
@@ -416,6 +447,7 @@ static struct board_info __initdata board_96358vw = {
.name = "96358VW",
.expected_cpu_id = 0x6358,
+ .has_uart0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.has_pci = 1,
@@ -467,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = {
.name = "96358VW2",
.expected_cpu_id = 0x6358,
+ .has_uart0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.has_pci = 1,
@@ -514,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = {
.name = "AGPF-S0",
.expected_cpu_id = 0x6358,
+ .has_uart0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.has_pci = 1,
@@ -531,6 +565,27 @@ static struct board_info __initdata board_AGPFS0 = {
.has_ohci0 = 1,
.has_ehci0 = 1,
};
+
+static struct board_info __initdata board_DWVS0 = {
+ .name = "DWV-S0",
+ .expected_cpu_id = 0x6358,
+
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+};
#endif
/*
@@ -552,16 +607,88 @@ static const struct board_info __initdata *bcm963xx_boards[] = {
&board_FAST2404,
&board_DV201AMR,
&board_96348gw_a,
+ &board_rta1025w_16,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
&board_96358vw,
&board_96358vw2,
&board_AGPFS0,
+ &board_DWVS0,
#endif
};
/*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+ .revision = 0x02,
+ .board_rev = 0x17,
+ .country_code = 0x0,
+ .ant_available_bg = 0x3,
+ .pa0b0 = 0x15ae,
+ .pa0b1 = 0xfa85,
+ .pa0b2 = 0xfe8d,
+ .pa1b0 = 0xffff,
+ .pa1b1 = 0xffff,
+ .pa1b2 = 0xffff,
+ .gpio0 = 0xff,
+ .gpio1 = 0xff,
+ .gpio2 = 0xff,
+ .gpio3 = 0xff,
+ .maxpwr_bg = 0x004c,
+ .itssi_bg = 0x00,
+ .boardflags_lo = 0x2848,
+ .boardflags_hi = 0x0000,
+};
+#endif
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+ return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+ u8 *p;
+ int count;
+
+ if (mac_addr_used >= nvram.mac_addr_count) {
+ printk(KERN_ERR PFX "not enough mac address\n");
+ return -ENODEV;
+ }
+
+ memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+ p = mac + ETH_ALEN - 1;
+ count = mac_addr_used;
+
+ while (count--) {
+ do {
+ (*p)++;
+ if (*p != 0)
+ break;
+ p--;
+ } while (p != mac);
+ }
+
+ if (p == mac) {
+ printk(KERN_ERR PFX "unable to fetch mac address\n");
+ return -ENODEV;
+ }
+
+ mac_addr_used++;
+ return 0;
+}
+
+/*
* early init callback, read nvram data from flash and checksum it
*/
void __init board_prom_init(void)
@@ -659,6 +786,17 @@ void __init board_prom_init(void)
}
bcm_gpio_writel(val, GPIO_MODE_REG);
+
+ /* Generate MAC address for WLAN and
+ * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+ if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+ memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+ memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+ if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+ printk(KERN_ERR "failed to register fallback SPROM\n");
+ }
+#endif
}
/*
@@ -676,49 +814,6 @@ void __init board_setup(void)
panic("unexpected CPU for bcm963xx board");
}
-/*
- * return board name for /proc/cpuinfo
- */
-const char *board_get_name(void)
-{
- return board.name;
-}
-
-/*
- * register & return a new board mac address
- */
-static int board_get_mac_address(u8 *mac)
-{
- u8 *p;
- int count;
-
- if (mac_addr_used >= nvram.mac_addr_count) {
- printk(KERN_ERR PFX "not enough mac address\n");
- return -ENODEV;
- }
-
- memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
- p = mac + ETH_ALEN - 1;
- count = mac_addr_used;
-
- while (count--) {
- do {
- (*p)++;
- if (*p != 0)
- break;
- p--;
- } while (p != mac);
- }
-
- if (p == mac) {
- printk(KERN_ERR PFX "unable to fetch mac address\n");
- return -ENODEV;
- }
-
- mac_addr_used++;
- return 0;
-}
-
static struct mtd_partition mtd_partitions[] = {
{
.name = "cfe",
@@ -750,33 +845,6 @@ static struct platform_device mtd_dev = {
},
};
-/*
- * Register a sane SPROMv2 to make the on-board
- * bcm4318 WLAN work
- */
-#ifdef CONFIG_SSB_PCIHOST
-static struct ssb_sprom bcm63xx_sprom = {
- .revision = 0x02,
- .board_rev = 0x17,
- .country_code = 0x0,
- .ant_available_bg = 0x3,
- .pa0b0 = 0x15ae,
- .pa0b1 = 0xfa85,
- .pa0b2 = 0xfe8d,
- .pa1b0 = 0xffff,
- .pa1b1 = 0xffff,
- .pa1b2 = 0xffff,
- .gpio0 = 0xff,
- .gpio1 = 0xff,
- .gpio2 = 0xff,
- .gpio3 = 0xff,
- .maxpwr_bg = 0x004c,
- .itssi_bg = 0x00,
- .boardflags_lo = 0x2848,
- .boardflags_hi = 0x0000,
-};
-#endif
-
static struct gpio_led_platform_data bcm63xx_led_data;
static struct platform_device bcm63xx_gpio_leds = {
@@ -792,6 +860,12 @@ int __init board_register_devices(void)
{
u32 val;
+ if (board.has_uart0)
+ bcm63xx_uart_register(0);
+
+ if (board.has_uart1)
+ bcm63xx_uart_register(1);
+
if (board.has_pccard)
bcm63xx_pcmcia_register();
@@ -806,17 +880,6 @@ int __init board_register_devices(void)
if (board.has_dsp)
bcm63xx_dsp_register(&board.dsp);
- /* Generate MAC address for WLAN and
- * register our SPROM */
-#ifdef CONFIG_SSB_PCIHOST
- if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
- memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
- memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
- if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
- printk(KERN_ERR "failed to register fallback SPROM\n");
- }
-#endif
-
/* read base address of boot chip select (0) */
if (BCMCPU_IS_6345())
val = 0x1fc00000;
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 70378bb5e3f..cbb7caf86d7 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = {
[RSET_TIMER] = BCM_6338_TIMER_BASE,
[RSET_WDT] = BCM_6338_WDT_BASE,
[RSET_UART0] = BCM_6338_UART0_BASE,
+ [RSET_UART1] = BCM_6338_UART1_BASE,
[RSET_GPIO] = BCM_6338_GPIO_BASE,
[RSET_SPI] = BCM_6338_SPI_BASE,
[RSET_OHCI0] = BCM_6338_OHCI0_BASE,
@@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = {
[RSET_TIMER] = BCM_6345_TIMER_BASE,
[RSET_WDT] = BCM_6345_WDT_BASE,
[RSET_UART0] = BCM_6345_UART0_BASE,
+ [RSET_UART1] = BCM_6345_UART1_BASE,
[RSET_GPIO] = BCM_6345_GPIO_BASE,
[RSET_SPI] = BCM_6345_SPI_BASE,
[RSET_UDC0] = BCM_6345_UDC0_BASE,
@@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = {
[RSET_TIMER] = BCM_6348_TIMER_BASE,
[RSET_WDT] = BCM_6348_WDT_BASE,
[RSET_UART0] = BCM_6348_UART0_BASE,
+ [RSET_UART1] = BCM_6348_UART1_BASE,
[RSET_GPIO] = BCM_6348_GPIO_BASE,
[RSET_SPI] = BCM_6348_SPI_BASE,
[RSET_OHCI0] = BCM_6348_OHCI0_BASE,
@@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = {
[RSET_TIMER] = BCM_6358_TIMER_BASE,
[RSET_WDT] = BCM_6358_WDT_BASE,
[RSET_UART0] = BCM_6358_UART0_BASE,
+ [RSET_UART1] = BCM_6358_UART1_BASE,
[RSET_GPIO] = BCM_6358_GPIO_BASE,
[RSET_SPI] = BCM_6358_SPI_BASE,
[RSET_OHCI0] = BCM_6358_OHCI0_BASE,
@@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = {
static const int bcm96358_irqs[] = {
[IRQ_TIMER] = BCM_6358_TIMER_IRQ,
[IRQ_UART0] = BCM_6358_UART0_IRQ,
+ [IRQ_UART1] = BCM_6358_UART1_IRQ,
[IRQ_DSL] = BCM_6358_DSL_IRQ,
[IRQ_ENET0] = BCM_6358_ENET0_IRQ,
[IRQ_ENET1] = BCM_6358_ENET1_IRQ,
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c
index b0519461ad9..c2963da0253 100644
--- a/arch/mips/bcm63xx/dev-uart.c
+++ b/arch/mips/bcm63xx/dev-uart.c
@@ -11,31 +11,65 @@
#include <linux/platform_device.h>
#include <bcm63xx_cpu.h>
-static struct resource uart_resources[] = {
+static struct resource uart0_resources[] = {
{
- .start = -1, /* filled at runtime */
- .end = -1, /* filled at runtime */
+ /* start & end filled at runtime */
.flags = IORESOURCE_MEM,
},
{
- .start = -1, /* filled at runtime */
+ /* start filled at runtime */
.flags = IORESOURCE_IRQ,
},
};
-static struct platform_device bcm63xx_uart_device = {
- .name = "bcm63xx_uart",
- .id = 0,
- .num_resources = ARRAY_SIZE(uart_resources),
- .resource = uart_resources,
+static struct resource uart1_resources[] = {
+ {
+ /* start & end filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* start filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bcm63xx_uart_devices[] = {
+ {
+ .name = "bcm63xx_uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+ .resource = uart0_resources,
+ },
+
+ {
+ .name = "bcm63xx_uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+ .resource = uart1_resources,
+ }
};
-int __init bcm63xx_uart_register(void)
+int __init bcm63xx_uart_register(unsigned int id)
{
- uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
- uart_resources[0].end = uart_resources[0].start;
- uart_resources[0].end += RSET_UART_SIZE - 1;
- uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
- return platform_device_register(&bcm63xx_uart_device);
+ if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
+ return -ENODEV;
+
+ if (id == 1 && !BCMCPU_IS_6358())
+ return -ENODEV;
+
+ if (id == 0) {
+ uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
+ uart0_resources[0].end = uart0_resources[0].start +
+ RSET_UART_SIZE - 1;
+ uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
+ }
+
+ if (id == 1) {
+ uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
+ uart1_resources[0].end = uart1_resources[0].start +
+ RSET_UART_SIZE - 1;
+ uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
+ }
+
+ return platform_device_register(&bcm63xx_uart_devices[id]);
}
-arch_initcall(bcm63xx_uart_register);
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c
index 87ca3904633..315bc7f79ce 100644
--- a/arch/mips/bcm63xx/gpio.c
+++ b/arch/mips/bcm63xx/gpio.c
@@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chip = {
int __init bcm63xx_gpio_init(void)
{
+ gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
+ gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
return gpiochip_add(&bcm63xx_gpio_chip);
}
-
-arch_initcall(bcm63xx_gpio_init);
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index b321d3b1687..9a06fa9f9f0 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops;
extern void pci_console_init(const char *arg);
#endif
-#ifdef CONFIG_CAVIUM_RESERVE32
-extern uint64_t octeon_reserve32_memory;
-#endif
static unsigned long long MAX_MEMORY = 512ull << 20;
struct octeon_boot_descriptor *octeon_boot_desc_ptr;
@@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void)
write_octeon_c0_dcacheerr(0);
}
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-/**
- * Called on every core to setup the wired tlb entry needed
- * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
- *
- */
-static void octeon_hal_setup_per_cpu_reserved32(void *unused)
-{
- /*
- * The config has selected to wire the reserve32 memory for all
- * userspace applications. We need to put a wired TLB entry in for each
- * 512MB of reserve32 memory. We only handle double 256MB pages here,
- * so reserve32 must be multiple of 512MB.
- */
- uint32_t size = CONFIG_CAVIUM_RESERVE32;
- uint32_t entrylo0 =
- 0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
- uint32_t entrylo1 = entrylo0 + (256 << 14);
- uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
- while (size >= 512) {
-#if 0
- pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
- smp_processor_id(), entryhi);
-#endif
- add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
- entrylo0 += 512 << 14;
- entrylo1 += 512 << 14;
- entryhi += 512 << 20;
- size -= 512;
- }
-}
-#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
-
-/**
- * Called to release the named block which was used to made sure
- * that nobody used the memory for something else during
- * init. Now we'll free it so userspace apps can use this
- * memory region with bootmem_alloc.
- *
- * This function is called only once from prom_free_prom_memory().
- */
-void octeon_hal_setup_reserved32(void)
-{
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
- on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
-#endif
-}
-
/**
* Reboot Octeon
*
@@ -294,18 +243,6 @@ static void octeon_halt(void)
octeon_kill_core(NULL);
}
-#if 0
-/**
- * Platform time init specifics.
- * Returns
- */
-void __init plat_time_init(void)
-{
- /* Nothing special here, but we are required to have one */
-}
-
-#endif
-
/**
* Handle all the error condition interrupts that might occur.
*
@@ -502,25 +439,13 @@ void __init prom_init(void)
* memory when it is getting memory from the
* bootloader. Later, after the memory allocations are
* complete, the reserve32 will be freed.
- */
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
- if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
- pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
- "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
- "is set\n");
- else
- addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
- 0, 0, 512 << 20,
- "CAVIUM_RESERVE32", 0);
-#else
- /*
+ *
* Allocate memory for RESERVED32 aligned on 2MB boundary. This
* is in case we later use hugetlb entries with it.
*/
addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
0, 0, 2 << 20,
"CAVIUM_RESERVE32", 0);
-#endif
if (addr < 0)
pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
else
@@ -817,9 +742,4 @@ void prom_free_prom_memory(void)
panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
}
#endif
-
- /* This call is here so that it is performed after any TLB
- initializations. It needs to be after these in case the
- CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
- octeon_hal_setup_reserved32();
}
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 51e980290ce..6d99b9d8887 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu)
uint32_t avail_coremask;
struct cvmx_bootmem_named_block_desc *block_desc;
-#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
- /* Disable the watchdog */
- cvmx_ciu_wdogx_t ciu_wdog;
- ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
- ciu_wdog.s.mode = 0;
- cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
-#endif
-
while (per_cpu(cpu_state, cpu) != CPU_DEAD)
cpu_relax();
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index c2f06e38c85..0583bb29150 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc8
-# Wed Jul 2 17:02:55 2008
+# Linux kernel version: 2.6.34-rc3
+# Sat Apr 3 16:32:11 2010
#
CONFIG_MIPS=y
@@ -9,20 +9,25 @@ CONFIG_MIPS=y
# Machine selection
#
# 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_MARKEINS is not set
+# CONFIG_NEC_MARKEINS is not set
# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
@@ -36,10 +41,13 @@ CONFIG_MIPS=y
# CONFIG_SIBYTE_SENTOSA is not set
CONFIG_SIBYTE_BIGSUR=y
# CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
CONFIG_SIBYTE_BCM1x80=y
CONFIG_SIBYTE_SB1xxx_SOC=y
# CONFIG_CPU_SB1_PASS_1 is not set
@@ -48,14 +56,13 @@ CONFIG_SIBYTE_SB1xxx_SOC=y
# CONFIG_CPU_SB1_PASS_4 is not set
# CONFIG_CPU_SB1_PASS_2_112x is not set
# CONFIG_CPU_SB1_PASS_3 is not set
-# CONFIG_SIMULATION is not set
# CONFIG_SB1_CEX_ALWAYS_FATAL is not set
# CONFIG_SB1_CERR_STALL is not set
-CONFIG_SIBYTE_CFE=y
# CONFIG_SIBYTE_CFE_CONSOLE is not set
# CONFIG_SIBYTE_BUS_WATCHER is not set
# CONFIG_SIBYTE_TBPROF is not set
CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y
+CONFIG_LOONGSON_UART_BASE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -66,15 +73,13 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_CEVT_BCM1480=y
CONFIG_CSRC_BCM1480=y
CONFIG_CFE=y
CONFIG_DMA_COHERENT=y
-CONFIG_EARLY_PRINTK=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
# CONFIG_NO_IOPORT is not set
CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -88,7 +93,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 is not set
# CONFIG_CPU_MIPS64_R1 is not set
@@ -101,6 +107,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_TX49XX is not set
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
# CONFIG_CPU_R6000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R8000 is not set
@@ -108,6 +115,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
CONFIG_CPU_SB1=y
+# CONFIG_CPU_CAVIUM_OCTEON is not set
CONFIG_SYS_HAS_CPU_SB1=y
CONFIG_WEAK_ORDERING=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
@@ -123,11 +131,13 @@ CONFIG_64BIT=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
# CONFIG_SIBYTE_DMA_PAGEOPS is not set
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
CONFIG_CPU_HAS_SYNC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
@@ -142,18 +152,17 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_SMP=y
CONFIG_SYS_SUPPORTS_SMP=y
CONFIG_NR_CPUS_DEFAULT_4=y
CONFIG_NR_CPUS=4
-# CONFIG_MIPS_CMP is not set
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -175,6 +184,7 @@ CONFIG_SECCOMP=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -188,6 +198,7 @@ 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=y
CONFIG_TASKSTATS=y
@@ -195,23 +206,39 @@ CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_AUDIT=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=64
+# 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=16
# CONFIG_CGROUPS is not set
-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_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
CONFIG_RELAY=y
-# CONFIG_NAMESPACES is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
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_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
@@ -222,29 +249,36 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
# CONFIG_PCSPKR_PLATFORM is not set
-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
+
+#
+# Kernel Performance Events And Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=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_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -252,26 +286,52 @@ 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
+# 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_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+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=y
+# CONFIG_FREEZER is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -280,8 +340,9 @@ CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_MMU=y
CONFIG_ZONE_DMA32=y
# CONFIG_PCCARD is not set
@@ -291,6 +352,8 @@ CONFIG_ZONE_DMA32=y
# 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
CONFIG_MIPS32_COMPAT=y
CONFIG_COMPAT=y
@@ -304,23 +367,20 @@ CONFIG_BINFMT_ELF32=y
#
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
-
-#
-# Networking
-#
+# CONFIG_PM_RUNTIME is not set
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
# CONFIG_XFRM_SUB_POLICY is not set
CONFIG_XFRM_MIGRATE=y
# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
CONFIG_NET_KEY=y
CONFIG_NET_KEY_MIGRATE=y
CONFIG_INET=y
@@ -353,36 +413,6 @@ CONFIG_INET_TCP_DIAG=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_TCP_MD5SIG=y
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
CONFIG_IPV6=m
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
@@ -399,11 +429,13 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
# CONFIG_IPV6_MROUTE is not set
+CONFIG_NETLABEL=y
CONFIG_NETWORK_SECMARK=y
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
@@ -421,19 +453,53 @@ CONFIG_NF_CONNTRACK_IRC=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
#
# IP: Netfilter Configuration
#
+CONFIG_NF_DEFRAG_IPV4=m
CONFIG_NF_CONNTRACK_IPV4=m
CONFIG_NF_CONNTRACK_PROC_COMPAT=y
CONFIG_IP_NF_IPTABLES=m
@@ -459,22 +525,44 @@ CONFIG_IP_NF_MANGLE=m
CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP_DCCP is not set
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=y
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=y
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
CONFIG_IP_SCTP=m
# CONFIG_SCTP_DBG_MSG is not set
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
+CONFIG_SCTP_HMAC_SHA1=y
+# CONFIG_SCTP_HMAC_MD5 is not set
+# CONFIG_RDS 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_STP=m
+CONFIG_GARP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
# CONFIG_DECNET is not set
+CONFIG_LLC=m
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
@@ -482,26 +570,47 @@ CONFIG_SCTP_HMAC_MD5=y
# 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_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
# 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
#
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -513,9 +622,12 @@ CONFIG_FIB_RULES=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=m
+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
@@ -530,33 +642,53 @@ CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
CONFIG_BLK_DEV_NBD=m
# 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_EEPROM_93CX6 is not set
CONFIG_SGI_IOC4=m
# 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=y
+CONFIG_EEPROM_MAX6875=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
+CONFIG_IDE_XFER_MODE=y
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=y
# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE 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=y
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
CONFIG_IDE_PROC_FS=y
@@ -581,14 +713,13 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# 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_IT8172 is not set
CONFIG_BLK_DEV_IT8213=m
# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
@@ -600,14 +731,12 @@ CONFIG_BLK_DEV_IT8213=m
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_TC86C001=m
-# CONFIG_BLK_DEV_IDE_SWARM is not set
CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -625,10 +754,6 @@ CONFIG_BLK_DEV_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
CONFIG_CHR_DEV_SCH=m
-
-#
-# 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
@@ -645,27 +770,36 @@ CONFIG_SCSI_WAIT_SCAN=m
# 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_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_MVSAS is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
@@ -676,9 +810,15 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T 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_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
@@ -700,6 +840,7 @@ CONFIG_ATA_SFF=y
# 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
@@ -715,6 +856,7 @@ CONFIG_ATA_SFF=y
# 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
@@ -725,14 +867,16 @@ CONFIG_ATA_SFF=y
# 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_PDC2027X is not set
CONFIG_PATA_SIL680=y
# 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
@@ -745,13 +889,16 @@ CONFIG_PATA_SIL680=y
#
#
-# Enable only one of the two stacks, unless you know what you are doing
+# 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_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -774,6 +921,9 @@ CONFIG_PHYLIB=y
# 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
@@ -783,23 +933,33 @@ CONFIG_MII=y
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
+# 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
# 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 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
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
-# CONFIG_E1000E_ENABLED is not set
# 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
@@ -811,29 +971,42 @@ CONFIG_SB1250_MAC=y
# 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=y
+CONFIG_MDIO=m
# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
CONFIG_CHELSIO_T3=m
+# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
CONFIG_NETXEN_NIC=m
# 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_QLCNIC is not set
+# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
#
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -856,6 +1029,7 @@ CONFIG_SLIP_MODE_SLIP6=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
@@ -873,6 +1047,7 @@ CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_PCIPS2 is not set
# CONFIG_SERIO_LIBPS2 is not set
CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_GAMEPORT is not set
#
@@ -893,8 +1068,6 @@ CONFIG_SERIAL_NONSTANDARD=y
# 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
@@ -911,7 +1084,9 @@ CONFIG_SERIAL_SB1250_DUART_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# 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=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
@@ -923,89 +1098,99 @@ CONFIG_LEGACY_PTY_COUNT=256
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_I810 is not set
+# CONFIG_I2C_ISCH 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_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-CONFIG_I2C_SIBYTE=y
-# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM 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_PLATFORM is not set
#
-# Miscellaneous I2C Chip support
+# I2C system bus drivers (mostly embedded / system-on-chip)
#
-# CONFIG_DS1682 is not set
-CONFIG_EEPROM_LEGACY=y
-CONFIG_SENSORS_PCF8574=y
-# CONFIG_PCF8575 is not set
-CONFIG_SENSORS_PCF8591=y
-CONFIG_EEPROM_MAX6875=y
-# CONFIG_SENSORS_TSL2550 is not set
+# 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_SIBYTE=y
+# CONFIG_I2C_STUB is not set
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
CONFIG_I2C_DEBUG_BUS=y
-CONFIG_I2C_DEBUG_CHIP=y
# 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_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# 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
-
-#
-# 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 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=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1016,10 +1201,6 @@ CONFIG_SSB_POSSIBLE=y
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
# CONFIG_SOUND is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
@@ -1030,9 +1211,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# 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
@@ -1040,41 +1230,66 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_INFINIBAND 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=m
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_EXT3_FS=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=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_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=m
+CONFIG_JBD2=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_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=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=m
CONFIG_QUOTACTL=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
@@ -1103,15 +1318,13 @@ CONFIG_NTFS_RW=y
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_HUGETLB_PAGE is not set
CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_ECRYPT_FS is not set
@@ -1120,9 +1333,12 @@ CONFIG_CONFIGFS_FS=m
# 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
@@ -1133,16 +1349,17 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
# 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
@@ -1205,12 +1422,18 @@ 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
@@ -1219,23 +1442,53 @@ CONFIG_SCHED_DEBUG=y
# 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_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_SPINLOCK_SLEEP=y
# 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_LIST is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
# 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=y
# 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_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_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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
# CONFIG_CMDLINE_BOOL is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_SB1XXX_CORELIS is not set
@@ -1246,20 +1499,50 @@ CONFIG_DEBUG_MUTEXES=y
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+# CONFIG_SECURITY_PATH is not set
+CONFIG_LSM_MMAP_MIN_ADDR=65536
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+# CONFIG_SECURITY_SMACK is not set
+# CONFIG_SECURITY_TOMOYO 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=m
+CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=m
# CONFIG_CRYPTO_TEST is not set
@@ -1276,7 +1559,7 @@ CONFIG_CRYPTO_SEQIV=m
#
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_CTR=m
-# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
@@ -1287,14 +1570,20 @@ CONFIG_CRYPTO_XTS=m
#
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
#
# Digest
#
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
@@ -1325,25 +1614,36 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
# Compression
#
CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+
+#
+# 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 is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=m
CONFIG_LIBCRC32C=m
CONFIG_AUDIT_GENERIC=y
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h
index 1dd74fbdc09..9252d9b50e5 100644
--- a/arch/mips/include/asm/abi.h
+++ b/arch/mips/include/asm/abi.h
@@ -13,12 +13,14 @@
#include <asm/siginfo.h>
struct mips_abi {
- int (* const setup_frame)(struct k_sigaction * ka,
+ int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr,
sigset_t *set);
- int (* const setup_rt_frame)(struct k_sigaction * ka,
+ const unsigned long signal_return_offset;
+ int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr,
sigset_t *set, siginfo_t *info);
+ const unsigned long rt_signal_return_offset;
const unsigned long restart;
};
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index f58aed354bf..613f6912dfc 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -8,7 +8,8 @@
#include <asm/page.h>
#include <asm/ptrace.h>
-#define COMPAT_USER_HZ 100
+#define COMPAT_USER_HZ 100
+#define COMPAT_UTS_MACHINE "mips\0\0\0"
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index e53d7bed5cd..ea77a42c5f8 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -310,6 +310,7 @@ do { \
#endif /* CONFIG_64BIT */
+struct pt_regs;
struct task_struct;
extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
@@ -367,4 +368,8 @@ extern const char *__elf_platform;
#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
#endif
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+ int uses_interp);
#endif /* _ASM_ELF_H */
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index aecada6f611..3b409270556 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats {
DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
#define MIPS_FPU_EMU_INC_STATS(M) \
- cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
+do { \
+ preempt_disable(); \
+ __local_inc(&__get_cpu_var(fpuemustats).M); \
+ preempt_enable(); \
+} while (0)
#else
#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
index b12c4aca2cc..96a2391ad85 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -85,6 +85,7 @@ enum bcm63xx_regs_set {
RSET_TIMER,
RSET_WDT,
RSET_UART0,
+ RSET_UART1,
RSET_GPIO,
RSET_SPI,
RSET_UDC0,
@@ -123,6 +124,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_TIMER_BASE (0xfffe0200)
#define BCM_6338_WDT_BASE (0xfffe021c)
#define BCM_6338_UART0_BASE (0xfffe0300)
+#define BCM_6338_UART1_BASE (0xdeadbeef)
#define BCM_6338_GPIO_BASE (0xfffe0400)
#define BCM_6338_SPI_BASE (0xfffe0c00)
#define BCM_6338_UDC0_BASE (0xdeadbeef)
@@ -153,6 +155,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_TIMER_BASE (0xfffe0200)
#define BCM_6345_WDT_BASE (0xfffe021c)
#define BCM_6345_UART0_BASE (0xfffe0300)
+#define BCM_6345_UART1_BASE (0xdeadbeef)
#define BCM_6345_GPIO_BASE (0xfffe0400)
#define BCM_6345_SPI_BASE (0xdeadbeef)
#define BCM_6345_UDC0_BASE (0xdeadbeef)
@@ -182,6 +185,7 @@ enum bcm63xx_regs_set {
#define BCM_6348_TIMER_BASE (0xfffe0200)
#define BCM_6348_WDT_BASE (0xfffe021c)
#define BCM_6348_UART0_BASE (0xfffe0300)
+#define BCM_6348_UART1_BASE (0xdeadbeef)
#define BCM_6348_GPIO_BASE (0xfffe0400)
#define BCM_6348_SPI_BASE (0xfffe0c00)
#define BCM_6348_UDC0_BASE (0xfffe1000)
@@ -208,6 +212,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_TIMER_BASE (0xfffe0040)
#define BCM_6358_WDT_BASE (0xfffe005c)
#define BCM_6358_UART0_BASE (0xfffe0100)
+#define BCM_6358_UART1_BASE (0xfffe0120)
#define BCM_6358_GPIO_BASE (0xfffe0080)
#define BCM_6358_SPI_BASE (0xdeadbeef)
#define BCM_6358_UDC0_BASE (0xfffe0800)
@@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
return BCM_6338_WDT_BASE;
case RSET_UART0:
return BCM_6338_UART0_BASE;
+ case RSET_UART1:
+ return BCM_6338_UART1_BASE;
case RSET_GPIO:
return BCM_6338_GPIO_BASE;
case RSET_SPI:
@@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
return BCM_6345_WDT_BASE;
case RSET_UART0:
return BCM_6345_UART0_BASE;
+ case RSET_UART1:
+ return BCM_6345_UART1_BASE;
case RSET_GPIO:
return BCM_6345_GPIO_BASE;
case RSET_SPI:
@@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
return BCM_6348_WDT_BASE;
case RSET_UART0:
return BCM_6348_UART0_BASE;
+ case RSET_UART1:
+ return BCM_6348_UART1_BASE;
case RSET_GPIO:
return BCM_6348_GPIO_BASE;
case RSET_SPI:
@@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
return BCM_6358_WDT_BASE;
case RSET_UART0:
return BCM_6358_UART0_BASE;
+ case RSET_UART1:
+ return BCM_6358_UART1_BASE;
case RSET_GPIO:
return BCM_6358_GPIO_BASE;
case RSET_SPI:
@@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
enum bcm63xx_irq {
IRQ_TIMER = 0,
IRQ_UART0,
+ IRQ_UART1,
IRQ_DSL,
IRQ_ENET0,
IRQ_ENET1,
@@ -510,6 +524,7 @@ enum bcm63xx_irq {
*/
#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
#define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
new file mode 100644
index 00000000000..23c705baf17
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_UART_H_
+#define BCM63XX_DEV_UART_H_
+
+int bcm63xx_uart_register(unsigned int id);
+
+#endif /* BCM63XX_DEV_UART_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
index 76a0b7216af..43d4da0b1e9 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void)
switch (bcm63xx_get_cpu_id()) {
case BCM6358_CPU_ID:
return 40;
+ case BCM6338_CPU_ID:
+ return 8;
+ case BCM6345_CPU_ID:
+ return 16;
case BCM6348_CPU_ID:
default:
return 37;
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
index 6479090a410..474daaa5349 100644
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -45,6 +45,8 @@ struct board_info {
unsigned int has_ohci0:1;
unsigned int has_ehci0:1;
unsigned int has_dsp:1;
+ unsigned int has_uart0:1;
+ unsigned int has_uart1:1;
/* ethernet config */
struct bcm63xx_enet_platform_data enet0;
diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
index 71742bac940..f453c01d067 100644
--- a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
@@ -24,7 +24,7 @@
#define cpu_has_smartmips 0
#define cpu_has_vtag_icache 0
-#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
#define cpu_has_dc_aliases 0
#endif
diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h
index 7950ef4f032..743385d7b5f 100644
--- a/arch/mips/include/asm/mach-sibyte/war.h
+++ b/arch/mips/include/asm/mach-sibyte/war.h
@@ -16,7 +16,11 @@
#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
-#define BCM1250_M3_WAR 1
+#ifndef __ASSEMBLY__
+extern int sb1250_m3_workaround_needed(void);
+#endif
+
+#define BCM1250_M3_WAR sb1250_m3_workaround_needed()
#define SIBYTE_1956_WAR 1
#else
diff --git a/arch/mips/include/asm/mmu.h b/arch/mips/include/asm/mmu.h
index 4063edd7962..c436138945a 100644
--- a/arch/mips/include/asm/mmu.h
+++ b/arch/mips/include/asm/mmu.h
@@ -1,6 +1,9 @@
#ifndef __ASM_MMU_H
#define __ASM_MMU_H
-typedef unsigned long mm_context_t[NR_CPUS];
+typedef struct {
+ unsigned long asid[NR_CPUS];
+ void *vdso;
+} mm_context_t;
#endif /* __ASM_MMU_H */
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index 145bb81ccaa..d9592733a7b 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask;
#endif
-#define cpu_context(cpu, mm) ((mm)->context[cpu])
+#define cpu_context(cpu, mm) ((mm)->context.asid[cpu])
#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index ac32572430f..a16beafcea9 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
-#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
+#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \
+ PHYS_OFFSET)
+#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \
+ PHYS_OFFSET)
#include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h>
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 5ebf82572ec..3beea1479b4 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -102,28 +102,6 @@ struct pci_dev;
*/
extern unsigned int PCI_DMA_BUS_IS_PHYS;
-#ifdef CONFIG_DMA_NEED_PCI_MAP_STATE
-
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
-
-#else /* CONFIG_DMA_NEED_PCI_MAP_STATE */
-
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME) (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-
-#endif /* CONFIG_DMA_NEED_PCI_MAP_STATE */
-
#ifdef CONFIG_PCI
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
enum pci_dma_burst_strategy *strat,
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 087a8884ef0..ab387910009 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -33,13 +33,19 @@ extern void (*cpu_wait)(void);
extern unsigned int vced_count, vcei_count;
+/*
+ * A special page (the vdso) is mapped into all processes at the very
+ * top of the virtual memory space.
+ */
+#define SPECIAL_PAGES_SIZE PAGE_SIZE
+
#ifdef CONFIG_32BIT
/*
* User space process size: 2GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing.
*/
#define TASK_SIZE 0x7fff8000UL
-#define STACK_TOP TASK_SIZE
+#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
/*
* This decides where the kernel will search for a free chunk of vm
@@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count;
#define TASK_SIZE32 0x7fff8000UL
#define TASK_SIZE 0x10000000000UL
#define STACK_TOP \
- (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+ (((test_thread_flag(TIF_32BIT_ADDR) ? \
+ TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
/*
* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index 3b6da3330e3..c8419129e77 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -121,6 +121,25 @@
.endm
#else
.macro get_saved_sp /* Uniprocessor variation */
+#ifdef CONFIG_CPU_LOONGSON2F
+ /*
+ * Clear BTB (branch target buffer), forbid RAS (return address
+ * stack) to workaround the Out-of-order Issue in Loongson2F
+ * via its diagnostic register.
+ */
+ move k0, ra
+ jal 1f
+ nop
+1: jal 1f
+ nop
+1: jal 1f
+ nop
+1: jal 1f
+ nop
+1: move ra, k0
+ li k0, 3
+ mtc0 k0, $22
+#endif /* CONFIG_CPU_LOONGSON2F */
#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
lui k1, %hi(kernelsp)
#else
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index b99bd07e199..11a8b525254 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -84,6 +84,7 @@ Ip_u2s3u1(_lw);
Ip_u1u2u3(_mfc0);
Ip_u1u2u3(_mtc0);
Ip_u2u1u3(_ori);
+Ip_u3u1u2(_or);
Ip_u2s3u1(_pref);
Ip_0(_rfe);
Ip_u2s3u1(_sc);
@@ -102,6 +103,7 @@ Ip_0(_tlbwr);
Ip_u3u1u2(_xor);
Ip_u2u1u3(_xori);
Ip_u2u1msbu3(_dins);
+Ip_u1(_syscall);
/* Handle labels. */
struct uasm_label {
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index 65c679ecbe6..1b5a6648eb8 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -1004,6 +1004,7 @@
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_UTIME
@@ -1013,6 +1014,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
new file mode 100644
index 00000000000..cca56aa40ff
--- /dev/null
+++ b/arch/mips/include/asm/vdso.h
@@ -0,0 +1,29 @@
+/*
+ * 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) 2009 Cavium Networks
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#include <linux/types.h>
+
+
+#ifdef CONFIG_32BIT
+struct mips_vdso {
+ u32 signal_trampoline[2];
+ u32 rt_signal_trampoline[2];
+};
+#else /* !CONFIG_32BIT */
+struct mips_vdso {
+ u32 o32_signal_trampoline[2];
+ u32 o32_rt_signal_trampoline[2];
+ u32 rt_signal_trampoline[2];
+ u32 n32_rt_signal_trampoline[2];
+};
+#endif /* CONFIG_32BIT */
+
+#endif /* __ASM_VDSO_H */
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index 0d64d0f4641..9ce9f64cb76 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <linux/bootmem.h>
#include <linux/spinlock.h>
+#include <linux/gfp.h>
#include <asm/mipsregs.h>
#include <asm/jazz.h>
#include <asm/io.h>
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index ef20957ca14..7a6ac501cbb 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds
obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
ptrace.o reset.o setup.o signal.o syscall.o \
- time.o topology.o traps.o unaligned.o watch.o
+ time.o topology.o traps.o unaligned.o watch.o vdso.o
ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_ftrace.o = -pg
diff --git a/arch/mips/kernel/cpufreq/loongson2_clock.c b/arch/mips/kernel/cpufreq/loongson2_clock.c
index d7ca256e33e..cefc6e259ba 100644
--- a/arch/mips/kernel/cpufreq/loongson2_clock.c
+++ b/arch/mips/kernel/cpufreq/loongson2_clock.c
@@ -164,3 +164,7 @@ void loongson2_cpu_wait(void)
spin_unlock_irqrestore(&loongson2_wait_lock, flags);
}
EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 981f86c2616..c6345f579a8 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -15,7 +15,6 @@
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/random.h>
#include <linux/sched.h>
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index bde79ef602e..c2dab140dc9 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -15,7 +15,6 @@
#include <linux/time.h>
#include <linux/times.h>
#include <linux/poll.h>
-#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/filter.h>
#include <linux/shm.h>
@@ -34,6 +33,7 @@
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/ipc.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/scm.h>
@@ -249,22 +249,6 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
}
#endif
-SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name)
-{
- int ret = 0;
-
- down_read(&uts_sem);
- if (copy_to_user(name, utsname(), sizeof *name))
- ret = -EFAULT;
- up_read(&uts_sem);
-
- if (current->personality == PER_LINUX32 && !ret)
- if (copy_to_user(name->machine, "mips\0\0\0", 8))
- ret = -EFAULT;
-
- return ret;
-}
-
SYSCALL_DEFINE1(32_personality, unsigned long, personality)
{
int ret;
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index f3d73e1831c..99960940d4a 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -17,7 +17,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/mman.h>
#include <linux/personality.h>
#include <linux/sys.h>
@@ -64,8 +63,13 @@ void __noreturn cpu_idle(void)
smtc_idle_loop_hook();
#endif
- if (cpu_wait)
+
+ if (cpu_wait) {
+ /* Don't trace irqs off for idle */
+ stop_critical_timings();
(*cpu_wait)();
+ start_critical_timings();
+ }
}
#ifdef CONFIG_HOTPLUG_CPU
if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 054861ccb4d..c51b95ff864 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -493,36 +493,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_setfpregs(child, (__u32 __user *) data);
break;
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: { /* restart after signal. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL) {
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
- else {
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL:
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- wake_up_process(child);
- break;
-
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->tp_value,
(unsigned long __user *) data);
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index dcaed1bbbfe..26f9b9ab19c 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -23,7 +23,6 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/uaccess.h>
-#include <linux/slab.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/elf.h>
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 66b5a48676d..44337ba0371 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -181,7 +181,7 @@ EXPORT(sysn32_call_table)
PTR sys_exit
PTR compat_sys_wait4
PTR sys_kill /* 6060 */
- PTR sys_32_newuname
+ PTR sys_newuname
PTR sys_semget
PTR sys_semop
PTR sys_n32_semctl
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 515f9eab2b2..813689ef238 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -325,7 +325,7 @@ sys_call_table:
PTR sys32_sigreturn
PTR sys32_clone /* 4120 */
PTR sys_setdomainname
- PTR sys_32_newuname
+ PTR sys_newuname
PTR sys_ni_syscall /* sys_modify_ldt */
PTR compat_sys_adjtimex
PTR sys_mprotect /* 4125 */
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index 6c8e8c4246f..10263b40598 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -26,11 +26,6 @@
*/
extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
size_t frame_size);
-/*
- * install trampoline code to get back from the sig handler
- */
-extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
-
/* Check and clear pending FPU exceptions in saved CSR */
extern int fpcsr_pending(unsigned int __user *fpcsr);
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index d0c68b5d717..2099d5a4c4b 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -32,6 +32,7 @@
#include <asm/ucontext.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
+#include <asm/vdso.h>
#include "signal-common.h"
@@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
struct sigframe {
u32 sf_ass[4]; /* argument save space for o32 */
- u32 sf_code[2]; /* signal trampoline */
+ u32 sf_pad[2]; /* Was: signal trampoline */
struct sigcontext sf_sc;
sigset_t sf_mask;
};
struct rt_sigframe {
u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_code[2]; /* signal trampoline */
+ u32 rs_pad[2]; /* Was: signal trampoline */
struct siginfo rs_info;
struct ucontext rs_uc;
};
-#else
-
-struct sigframe {
- u32 sf_ass[4]; /* argument save space for o32 */
- u32 sf_pad[2];
- struct sigcontext sf_sc; /* hw context */
- sigset_t sf_mask;
- u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
-};
-
-struct rt_sigframe {
- u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_pad[2];
- struct siginfo rs_info;
- struct ucontext rs_uc;
- u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
-};
-
-#endif
-
/*
* Helper routines
*/
@@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
}
-int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
-{
- int err;
-
- /*
- * Set up the return code ...
- *
- * li v0, __NR__foo_sigreturn
- * syscall
- */
-
- err = __put_user(0x24020000 + syscall, tramp + 0);
- err |= __put_user(0x0000000c , tramp + 1);
- if (ICACHE_REFILLS_WORKAROUND_WAR) {
- err |= __put_user(0, tramp + 2);
- err |= __put_user(0, tramp + 3);
- err |= __put_user(0, tramp + 4);
- err |= __put_user(0, tramp + 5);
- err |= __put_user(0, tramp + 6);
- err |= __put_user(0, tramp + 7);
- }
- flush_cache_sigtramp((unsigned long) tramp);
-
- return err;
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
@@ -484,8 +432,8 @@ badframe:
}
#ifdef CONFIG_TRAD_SIGNALS
-static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
- int signr, sigset_t *set)
+static int setup_frame(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set)
{
struct sigframe __user *frame;
int err = 0;
@@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
-
err |= setup_sigcontext(regs, &frame->sf_sc);
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
if (err)
@@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
regs->regs[ 5] = 0;
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
regs->regs[29] = (unsigned long) frame;
- regs->regs[31] = (unsigned long) frame->sf_code;
+ regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -529,8 +475,9 @@ give_sigsegv:
}
#endif
-static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
- int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set,
+ siginfo_t *info)
{
struct rt_sigframe __user *frame;
int err = 0;
@@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
-
/* Create siginfo. */
err |= copy_siginfo_to_user(&frame->rs_info, info);
@@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
regs->regs[ 5] = (unsigned long) &frame->rs_info;
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
regs->regs[29] = (unsigned long) frame;
- regs->regs[31] = (unsigned long) frame->rs_code;
+ regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -590,8 +535,11 @@ give_sigsegv:
struct mips_abi mips_abi = {
#ifdef CONFIG_TRAD_SIGNALS
.setup_frame = setup_frame,
+ .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
#endif
.setup_rt_frame = setup_rt_frame,
+ .rt_signal_return_offset =
+ offsetof(struct mips_vdso, rt_signal_trampoline),
.restart = __NR_restart_syscall
};
@@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
{
int ret;
+ struct mips_abi *abi = current->thread.abi;
+ void *vdso = current->mm->context.vdso;
switch(regs->regs[0]) {
case ERESTART_RESTARTBLOCK:
@@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
if (sig_uses_siginfo(ka))
- ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
+ ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+ ka, regs, sig, oldset, info);
else
- ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
+ ret = abi->setup_frame(vdso + abi->signal_return_offset,
+ ka, regs, sig, oldset);
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 03abaf048f0..a0ed0e052b2 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -32,6 +32,7 @@
#include <asm/system.h>
#include <asm/fpu.h>
#include <asm/war.h>
+#include <asm/vdso.h>
#include "signal-common.h"
@@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user
/*
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
*/
-#define __NR_O32_sigreturn 4119
-#define __NR_O32_rt_sigreturn 4193
#define __NR_O32_restart_syscall 4253
/* 32-bit compatibility types */
@@ -77,47 +76,20 @@ struct ucontext32 {
compat_sigset_t uc_sigmask; /* mask last for extensibility */
};
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
struct sigframe32 {
u32 sf_ass[4]; /* argument save space for o32 */
- u32 sf_code[2]; /* signal trampoline */
+ u32 sf_pad[2]; /* Was: signal trampoline */
struct sigcontext32 sf_sc;
compat_sigset_t sf_mask;
};
struct rt_sigframe32 {
u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_code[2]; /* signal trampoline */
+ u32 rs_pad[2]; /* Was: signal trampoline */
compat_siginfo_t rs_info;
struct ucontext32 rs_uc;
};
-#else /* ICACHE_REFILLS_WORKAROUND_WAR */
-
-struct sigframe32 {
- u32 sf_ass[4]; /* argument save space for o32 */
- u32 sf_pad[2];
- struct sigcontext32 sf_sc; /* hw context */
- compat_sigset_t sf_mask;
- u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
-};
-
-struct rt_sigframe32 {
- u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_pad[2];
- compat_siginfo_t rs_info;
- struct ucontext32 rs_uc;
- u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
-};
-
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
/*
* sigcontext handlers
*/
@@ -598,8 +570,8 @@ badframe:
force_sig(SIGSEGV, current);
}
-static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
- int signr, sigset_t *set)
+static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set)
{
struct sigframe32 __user *frame;
int err = 0;
@@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
-
err |= setup_sigcontext32(regs, &frame->sf_sc);
err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
@@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
regs->regs[ 5] = 0;
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
regs->regs[29] = (unsigned long) frame;
- regs->regs[31] = (unsigned long) frame->sf_code;
+ regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -644,8 +614,9 @@ give_sigsegv:
return -EFAULT;
}
-static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
- int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set,
+ siginfo_t *info)
{
struct rt_sigframe32 __user *frame;
int err = 0;
@@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
-
/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
err |= copy_siginfo_to_user32(&frame->rs_info, info);
@@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
regs->regs[ 5] = (unsigned long) &frame->rs_info;
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
regs->regs[29] = (unsigned long) frame;
- regs->regs[31] = (unsigned long) frame->rs_code;
+ regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -709,7 +678,11 @@ give_sigsegv:
*/
struct mips_abi mips_abi_32 = {
.setup_frame = setup_frame_32,
+ .signal_return_offset =
+ offsetof(struct mips_vdso, o32_signal_trampoline),
.setup_rt_frame = setup_rt_frame_32,
+ .rt_signal_return_offset =
+ offsetof(struct mips_vdso, o32_rt_signal_trampoline),
.restart = __NR_O32_restart_syscall
};
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index bb277e82d42..2c5df818c65 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -39,13 +39,13 @@
#include <asm/fpu.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
+#include <asm/vdso.h>
#include "signal-common.h"
/*
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
*/
-#define __NR_N32_rt_sigreturn 6211
#define __NR_N32_restart_syscall 6214
extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
@@ -67,27 +67,13 @@ struct ucontextn32 {
compat_sigset_t uc_sigmask; /* mask last for extensibility */
};
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
-struct rt_sigframe_n32 {
- u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_code[2]; /* signal trampoline */
- struct compat_siginfo rs_info;
- struct ucontextn32 rs_uc;
-};
-
-#else /* ICACHE_REFILLS_WORKAROUND_WAR */
-
struct rt_sigframe_n32 {
u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_pad[2];
+ u32 rs_pad[2]; /* Was: signal trampoline */
struct compat_siginfo rs_info;
struct ucontextn32 rs_uc;
- u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
};
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -173,7 +159,7 @@ badframe:
force_sig(SIGSEGV, current);
}
-static int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
{
struct rt_sigframe_n32 __user *frame;
@@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;
- install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
-
/* Create siginfo. */
err |= copy_siginfo_to_user32(&frame->rs_info, info);
@@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
regs->regs[ 5] = (unsigned long) &frame->rs_info;
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
regs->regs[29] = (unsigned long) frame;
- regs->regs[31] = (unsigned long) frame->rs_code;
+ regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -235,5 +219,7 @@ give_sigsegv:
struct mips_abi mips_abi_n32 = {
.setup_rt_frame = setup_rt_frame_n32,
+ .rt_signal_return_offset =
+ offsetof(struct mips_vdso, n32_rt_signal_trampoline),
.restart = __NR_N32_restart_syscall
};
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 23499b5bd9c..a95dea5459c 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -26,6 +26,7 @@
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/ftrace.h>
+#include <linux/slab.h>
#include <asm/cpu.h>
#include <asm/processor.h>
@@ -181,7 +182,7 @@ static int vpemask[2][8] = {
{0, 0, 0, 0, 0, 0, 0, 1}
};
int tcnoprog[NR_CPUS];
-static atomic_t idle_hook_initialized = {0};
+static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
static int clock_hang_reported[NR_CPUS];
#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 3f7f466190b..dd81b0f8751 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -19,7 +19,6 @@
#include <linux/string.h>
#include <linux/syscalls.h>
#include <linux/file.h>
-#include <linux/slab.h>
#include <linux/utsname.h>
#include <linux/unistd.h>
#include <linux/sem.h>
@@ -29,6 +28,7 @@
#include <linux/module.h>
#include <linux/ipc.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <asm/asm.h>
#include <asm/branch.h>
@@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
int do_color_align;
unsigned long task_size;
- task_size = STACK_TOP;
+#ifdef CONFIG_32BIT
+ task_size = TASK_SIZE;
+#else /* Must be CONFIG_64BIT*/
+ task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
+#endif
if (len > task_size)
return -ENOMEM;
@@ -215,48 +219,6 @@ out:
return error;
}
-/*
- * Compacrapability ...
- */
-SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
-{
- if (name && !copy_to_user(name, utsname(), sizeof (*name)))
- return 0;
- return -EFAULT;
-}
-
-/*
- * Compacrapability ...
- */
-SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
-{
- int error;
-
- if (!name)
- return -EFAULT;
- if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- error = __copy_to_user(&name->sysname, &utsname()->sysname,
- __OLD_UTS_LEN);
- error -= __put_user(0, name->sysname + __OLD_UTS_LEN);
- error -= __copy_to_user(&name->nodename, &utsname()->nodename,
- __OLD_UTS_LEN);
- error -= __put_user(0, name->nodename + __OLD_UTS_LEN);
- error -= __copy_to_user(&name->release, &utsname()->release,
- __OLD_UTS_LEN);
- error -= __put_user(0, name->release + __OLD_UTS_LEN);
- error -= __copy_to_user(&name->version, &utsname()->version,
- __OLD_UTS_LEN);
- error -= __put_user(0, name->version + __OLD_UTS_LEN);
- error -= __copy_to_user(&name->machine, &utsname()->machine,
- __OLD_UTS_LEN);
- error = __put_user(0, name->machine + __OLD_UTS_LEN);
- error = error ? -EFAULT : 0;
-
- return error;
-}
-
SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
{
struct thread_info *ti = task_thread_info(current);
@@ -407,94 +369,6 @@ _sys_sysmips(nabi_no_regargs struct pt_regs regs)
}
/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
- unsigned long, third, void __user *, ptr, long, fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr,
- second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr,
- second,
- (const struct timespec __user *)fifth);
- case SEMGET:
- return sys_semget(first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void __user *__user *) ptr))
- return -EFAULT;
- return sys_semctl(first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd(first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof(tmp)))
- return -EFAULT;
- return sys_msgrcv(first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv(first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget((key_t) first, second);
- case MSGCTL:
- return sys_msgctl(first, second,
- (struct msqid_ds __user *) ptr);
-
- case SHMAT:
- switch (version) {
- default: {
- unsigned long raddr;
- ret = do_shmat(first, (char __user *) ptr, second,
- &raddr);
- if (ret)
- return ret;
- return put_user(raddr, (unsigned long __user *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return do_shmat(first, (char __user *) ptr, second,
- (unsigned long *) third);
- }
- case SHMDT:
- return sys_shmdt((char __user *)ptr);
- case SHMGET:
- return sys_shmget(first, second, third);
- case SHMCTL:
- return sys_shmctl(first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -ENOSYS;
- }
-}
-
-/*
* No implemented yet ...
*/
SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 4e00f9bc23e..1a4dd657ccb 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1599,7 +1599,7 @@ void __init trap_init(void)
ebase = (unsigned long)
__alloc_bootmem(size, 1 << fls(size), 0);
} else {
- ebase = CAC_BASE;
+ ebase = CKSEG0;
if (cpu_has_mips_r2)
ebase += (read_c0_ebase() & 0x3ffff000);
}
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
new file mode 100644
index 00000000000..b773c1112b1
--- /dev/null
+++ b/arch/mips/kernel/vdso.c
@@ -0,0 +1,112 @@
+/*
+ * 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) 2009, 2010 Cavium Networks, Inc.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+
+#include <asm/vdso.h>
+#include <asm/uasm.h>
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_sigreturn 4119
+#define __NR_O32_rt_sigreturn 4193
+#define __NR_N32_rt_sigreturn 6211
+
+static struct page *vdso_page;
+
+static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+{
+ uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */
+ uasm_i_syscall(&tramp, 0);
+}
+
+static int __init init_vdso(void)
+{
+ struct mips_vdso *vdso;
+
+ vdso_page = alloc_page(GFP_KERNEL);
+ if (!vdso_page)
+ panic("Cannot allocate vdso");
+
+ vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
+ if (!vdso)
+ panic("Cannot map vdso");
+ clear_page(vdso);
+
+ install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
+#ifdef CONFIG_32BIT
+ install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
+#else
+ install_trampoline(vdso->n32_rt_signal_trampoline,
+ __NR_N32_rt_sigreturn);
+ install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
+ install_trampoline(vdso->o32_rt_signal_trampoline,
+ __NR_O32_rt_sigreturn);
+#endif
+
+ vunmap(vdso);
+
+ pr_notice("init_vdso successfull\n");
+
+ return 0;
+}
+device_initcall(init_vdso);
+
+static unsigned long vdso_addr(unsigned long start)
+{
+ return STACK_TOP;
+}
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+ int ret;
+ unsigned long addr;
+ struct mm_struct *mm = current->mm;
+
+ down_write(&mm->mmap_sem);
+
+ addr = vdso_addr(mm->start_stack);
+
+ addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
+ if (IS_ERR_VALUE(addr)) {
+ ret = addr;
+ goto up_fail;
+ }
+
+ ret = install_special_mapping(mm, addr, PAGE_SIZE,
+ VM_READ|VM_EXEC|
+ VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+ VM_ALWAYSDUMP,
+ &vdso_page);
+
+ if (ret)
+ goto up_fail;
+
+ mm->context.vdso = (void *)addr;
+
+up_fail:
+ up_write(&mm->mmap_sem);
+ return ret;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
+ return "[vdso]";
+ return NULL;
+}
diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c
index 6b3b1de9dca..5995969e8c4 100644
--- a/arch/mips/lib/delay.c
+++ b/arch/mips/lib/delay.c
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay);
void __udelay(unsigned long us)
{
- unsigned int lpj = current_cpu_data.udelay_val;
+ unsigned int lpj = raw_current_cpu_data.udelay_val;
__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
}
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay);
void __ndelay(unsigned long ns)
{
- unsigned int lpj = current_cpu_data.udelay_val;
+ unsigned int lpj = raw_current_cpu_data.udelay_val;
__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
}
diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h
index 3f19d1c5d94..05909d58e2f 100644
--- a/arch/mips/lib/libgcc.h
+++ b/arch/mips/lib/libgcc.h
@@ -17,8 +17,7 @@ struct DWstruct {
#error I feel sick.
#endif
-typedef union
-{
+typedef union {
struct DWstruct s;
long long ll;
} DWunion;
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c
index 46067ad542d..5c779be6f08 100644
--- a/arch/mips/mipssim/sim_int.c
+++ b/arch/mips/mipssim/sim_int.c
@@ -17,7 +17,6 @@
*/
#include <linux/init.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <asm/mips-boards/simint.h>
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index be8627bc5b0..12af739048f 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
}
unsigned long _page_cachable_default;
-EXPORT_SYMBOL_GPL(_page_cachable_default);
+EXPORT_SYMBOL(_page_cachable_default);
static inline void setup_protection_map(void)
{
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 9367e33fbd1..9547bc0cf18 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/string.h>
+#include <linux/gfp.h>
#include <asm/cache.h>
#include <asm/io.h>
diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c
index cd0660c51f2..a7fee0dfb7a 100644
--- a/arch/mips/mm/hugetlbpage.c
+++ b/arch/mips/mm/hugetlbpage.c
@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/slab.h>
#include <linux/err.h>
#include <linux/sysctl.h>
#include <asm/mman.h>
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 12539af38a9..2efcbd24c82 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -28,6 +28,7 @@
#include <linux/proc_fs.h>
#include <linux/pfn.h>
#include <linux/hardirq.h>
+#include <linux/gfp.h>
#include <asm/asm-offsets.h>
#include <asm/bootinfo.h>
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index 0c43248347b..cacfd31e8ec 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -10,6 +10,7 @@
#include <asm/addrspace.h>
#include <asm/byteorder.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/cacheflush.h>
#include <asm/io.h>
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 0de0e4127d6..d1f68aadbc4 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -788,10 +788,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
* create the plain linear handler
*/
if (bcm1250_m3_war()) {
- UASM_i_MFC0(&p, K0, C0_BADVADDR);
- UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+ unsigned int segbits = 44;
+
+ uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+ uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
uasm_i_xor(&p, K0, K0, K1);
- UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+ uasm_i_dsrl32(&p, K1, K0, 62 - 32);
+ uasm_i_dsrl(&p, K0, K0, 12 + 1);
+ uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
+ uasm_i_or(&p, K0, K0, K1);
uasm_il_bnez(&p, &r, K0, label_leave);
/* No need for uasm_i_nop */
}
@@ -1312,10 +1317,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
memset(relocs, 0, sizeof(relocs));
if (bcm1250_m3_war()) {
- UASM_i_MFC0(&p, K0, C0_BADVADDR);
- UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+ unsigned int segbits = 44;
+
+ uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+ uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
uasm_i_xor(&p, K0, K0, K1);
- UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+ uasm_i_dsrl32(&p, K1, K0, 62 - 32);
+ uasm_i_dsrl(&p, K0, K0, 12 + 1);
+ uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
+ uasm_i_or(&p, K0, K0, K1);
uasm_il_bnez(&p, &r, K0, label_leave);
/* No need for uasm_i_nop */
}
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 1581e985246..611d564fdcf 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -31,7 +31,8 @@ enum fields {
BIMM = 0x040,
JIMM = 0x080,
FUNC = 0x100,
- SET = 0x200
+ SET = 0x200,
+ SCIMM = 0x400
};
#define OP_MASK 0x3f
@@ -52,6 +53,8 @@ enum fields {
#define FUNC_SH 0
#define SET_MASK 0x7
#define SET_SH 0
+#define SCIMM_MASK 0xfffff
+#define SCIMM_SH 6
enum opcode {
insn_invalid,
@@ -61,10 +64,10 @@ enum opcode {
insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
- insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
+ insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
- insn_dins
+ insn_dins, insn_syscall
};
struct insn {
@@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = {
{ insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
{ insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
{ insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
{ insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
@@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = {
{ insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
{ insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+ { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
{ insn_invalid, 0, 0 }
};
@@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg)
return (arg >> 2) & JIMM_MASK;
}
+static inline __cpuinit u32 build_scimm(u32 arg)
+{
+ if (arg & ~SCIMM_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & SCIMM_MASK) << SCIMM_SH;
+}
+
static inline __cpuinit u32 build_func(u32 arg)
{
if (arg & ~FUNC_MASK)
@@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
op |= build_func(va_arg(ap, u32));
if (ip->fields & SET)
op |= build_set(va_arg(ap, u32));
+ if (ip->fields & SCIMM)
+ op |= build_scimm(va_arg(ap, u32));
va_end(ap);
**buf = op;
@@ -373,6 +388,7 @@ I_u2s3u1(_lw)
I_u1u2u3(_mfc0)
I_u1u2u3(_mtc0)
I_u2u1u3(_ori)
+I_u3u1u2(_or)
I_u2s3u1(_pref)
I_0(_rfe)
I_u2s3u1(_sc)
@@ -391,6 +407,7 @@ I_0(_tlbwr)
I_u3u1u2(_xor)
I_u2u1u3(_xori)
I_u2u1msbu3(_dins);
+I_u1(_syscall);
/* Handle labels. */
void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 2cb5ae79020..15949b0be81 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -25,7 +25,6 @@
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel_stat.h>
diff --git a/arch/mips/nxp/pnx833x/common/reset.c b/arch/mips/nxp/pnx833x/common/reset.c
index a9bc9bacad2..e0ea96d29fd 100644
--- a/arch/mips/nxp/pnx833x/common/reset.c
+++ b/arch/mips/nxp/pnx833x/common/reset.c
@@ -22,7 +22,6 @@
* 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 <linux/reboot.h>
#include <pnx833x.h>
diff --git a/arch/mips/nxp/pnx8550/common/int.c b/arch/mips/nxp/pnx8550/common/int.c
index 7aca7d5375e..cfed5051dc6 100644
--- a/arch/mips/nxp/pnx8550/common/int.c
+++ b/arch/mips/nxp/pnx8550/common/int.c
@@ -27,7 +27,6 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/random.h>
diff --git a/arch/mips/nxp/pnx8550/common/proc.c b/arch/mips/nxp/pnx8550/common/proc.c
index af094cd1d85..3bba5ec828e 100644
--- a/arch/mips/nxp/pnx8550/common/proc.c
+++ b/arch/mips/nxp/pnx8550/common/proc.c
@@ -16,7 +16,6 @@
#include <linux/proc_fs.h>
#include <linux/irq.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/random.h>
diff --git a/arch/mips/nxp/pnx8550/common/reset.c b/arch/mips/nxp/pnx8550/common/reset.c
index 7b2cbc5b2c7..76bc3ec634e 100644
--- a/arch/mips/nxp/pnx8550/common/reset.c
+++ b/arch/mips/nxp/pnx8550/common/reset.c
@@ -20,7 +20,6 @@
* Reset the PNX8550 board.
*
*/
-#include <linux/slab.h>
#include <asm/reboot.h>
#include <glb.h>
diff --git a/arch/mips/pci/ops-loongson2.c b/arch/mips/pci/ops-loongson2.c
index 2bb4057bf6c..d657ee0bc13 100644
--- a/arch/mips/pci/ops-loongson2.c
+++ b/arch/mips/pci/ops-loongson2.c
@@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = {
};
#ifdef CONFIG_CS5536
+DEFINE_RAW_SPINLOCK(msr_lock);
+
void _rdmsr(u32 msr, u32 *hi, u32 *lo)
{
struct pci_bus bus = {
.number = PCI_BUS_CS5536
};
u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&msr_lock, flags);
loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+ raw_spin_unlock_irqrestore(&msr_lock, flags);
}
EXPORT_SYMBOL(_rdmsr);
@@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo)
.number = PCI_BUS_CS5536
};
u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&msr_lock, flags);
loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+ raw_spin_unlock_irqrestore(&msr_lock, flags);
}
EXPORT_SYMBOL(_wrmsr);
#endif
diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c
index 46c636c27e0..749c1922d42 100644
--- a/arch/mips/pci/ops-titan-ht.c
+++ b/arch/mips/pci/ops-titan-ht.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/io.h>
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_prom.c b/arch/mips/pmc-sierra/msp71xx/msp_prom.c
index db98d87a092..db00deb59b9 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_prom.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_prom.c
@@ -40,6 +40,7 @@
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c
index fd22597edb6..63be40e470d 100644
--- a/arch/mips/pmc-sierra/yosemite/ht.c
+++ b/arch/mips/pmc-sierra/yosemite/ht.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <asm/pci.h>
#include <asm/io.h>
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c
index 5f673eba142..51021cfd04b 100644
--- a/arch/mips/pmc-sierra/yosemite/irq.c
+++ b/arch/mips/pmc-sierra/yosemite/irq.c
@@ -37,7 +37,6 @@
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/timex.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c
index 217424231eb..8ee77887306 100644
--- a/arch/mips/powertv/asic/asic_devices.c
+++ b/arch/mips/powertv/asic/asic_devices.c
@@ -39,6 +39,7 @@
#include <linux/mm.h>
#include <linux/platform_device.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <asm/page.h>
#include <linux/swap.h>
#include <linux/highmem.h>
diff --git a/arch/mips/powertv/asic/asic_int.c b/arch/mips/powertv/asic/asic_int.c
index 325fab9685d..529c44a52d6 100644
--- a/arch/mips/powertv/asic/asic_int.c
+++ b/arch/mips/powertv/asic/asic_int.c
@@ -26,7 +26,6 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/kernel.h>
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c
index f07882029a9..ea6cec3c1e0 100644
--- a/arch/mips/rb532/irq.c
+++ b/arch/mips/rb532/irq.c
@@ -36,7 +36,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index c1c8e40d65d..6a123ea72de 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -17,7 +17,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
-#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/random.h>
#include <linux/kernel.h>
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index d8b65204d28..eb40824b172 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -15,7 +15,6 @@
#include <linux/irq.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/random.h>
#include <linux/sched.h>
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 06e25d94976..7a8b0a8b643 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -22,7 +22,6 @@
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/kernel_stat.h>
#include <asm/errno.h>
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index ed2453eab5c..d4ed7a9156f 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -27,7 +27,6 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/errno.h>
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index ab44a2f59ee..62371f77255 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -22,7 +22,6 @@
#include <linux/spinlock.h>
#include <linux/smp.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/kernel_stat.h>
#include <asm/errno.h>
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
index 0444da1e23c..92da3155ce0 100644
--- a/arch/mips/sibyte/sb1250/setup.c
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -87,6 +87,21 @@ static int __init setup_bcm1250(void)
return ret;
}
+int sb1250_m3_workaround_needed(void)
+{
+ switch (soc_type) {
+ case K_SYS_SOC_TYPE_BCM1250:
+ case K_SYS_SOC_TYPE_BCM1250_ALT:
+ case K_SYS_SOC_TYPE_BCM1250_ALT2:
+ case K_SYS_SOC_TYPE_BCM1125:
+ case K_SYS_SOC_TYPE_BCM1125H:
+ return soc_pass < K_SYS_REVISION_BCM1250_C0;
+
+ default:
+ return 0;
+ }
+}
+
static int __init setup_bcm112x(void)
{
int ret = 0;
diff --git a/arch/mips/txx9/generic/7segled.c b/arch/mips/txx9/generic/7segled.c
index 727ab21b661..7f8416f8622 100644
--- a/arch/mips/txx9/generic/7segled.c
+++ b/arch/mips/txx9/generic/7segled.c
@@ -58,13 +58,16 @@ static ssize_t raw_store(struct sys_device *dev,
static SYSDEV_ATTR(ascii, 0200, NULL, ascii_store);
static SYSDEV_ATTR(raw, 0200, NULL, raw_store);
-static ssize_t map_seg7_show(struct sysdev_class *class, char *buf)
+static ssize_t map_seg7_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map));
return sizeof(txx9_seg7map);
}
static ssize_t map_seg7_store(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
const char *buf, size_t size)
{
if (size != sizeof(txx9_seg7map))
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
index 707cfa9c547..9a0be810caf 100644
--- a/arch/mips/txx9/generic/pci.c
+++ b/arch/mips/txx9/generic/pci.c
@@ -20,6 +20,7 @@
#include <asm/txx9/pci.h>
#ifdef CONFIG_TOSHIBA_FPCIB0
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <asm/i8259.h>
#include <asm/txx9/smsc_fdc37m81x.h>
#endif
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index 7174d830dd0..adc69291f9e 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -23,6 +23,7 @@
#include <linux/mtd/physmap.h>
#include <linux/leds.h>
#include <linux/sysdev.h>
+#include <linux/slab.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/reboot.h>
@@ -956,6 +957,7 @@ void __init txx9_sramc_init(struct resource *r)
if (!dev->base)
goto exit;
dev->dev.cls = &txx9_sramc_sysdev_class;
+ sysfs_bin_attr_init(&dev->bindata_attr);
dev->bindata_attr.attr.name = "bindata";
dev->bindata_attr.attr.mode = S_IRUSR | S_IWUSR;
dev->bindata_attr.read = txx9_sram_read;
diff --git a/arch/mips/txx9/generic/spi_eeprom.c b/arch/mips/txx9/generic/spi_eeprom.c
index 75c347238f4..103abc13d62 100644
--- a/arch/mips/txx9/generic/spi_eeprom.c
+++ b/arch/mips/txx9/generic/spi_eeprom.c
@@ -10,6 +10,7 @@
* Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index b0c241ecf60..7dc0fafbec8 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/interrupt.h>
diff --git a/arch/mn10300/include/asm/dma-mapping.h b/arch/mn10300/include/asm/dma-mapping.h
index ccae8f6c632..4ed1522b38d 100644
--- a/arch/mn10300/include/asm/dma-mapping.h
+++ b/arch/mn10300/include/asm/dma-mapping.h
@@ -17,6 +17,11 @@
#include <asm/cache.h>
#include <asm/io.h>
+/*
+ * See Documentation/DMA-API.txt for the description of how the
+ * following DMA API should work.
+ */
+
extern void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, int flag);
@@ -26,13 +31,6 @@ extern void dma_free_coherent(struct device *dev, size_t size,
#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))
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode. The
- * 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory until
- * either pci_unmap_single or pci_dma_sync_single is performed.
- */
static inline
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
@@ -42,14 +40,6 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
return virt_to_bus(ptr);
}
-/*
- * Unmap a single streaming mode DMA translation. The dma_addr and size must
- * match what was provided for in a previous pci_map_single call. All other
- * usages are undefined.
- *
- * After this call, reads by the cpu to the buffer are guarenteed to see
- * whatever the device wrote there.
- */
static inline
void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
@@ -57,20 +47,6 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
BUG_ON(direction == DMA_NONE);
}
-/*
- * Map a set of buffers described by scatterlist in streaming mode for DMA.
- * This is the scather-gather version of the above pci_map_single interface.
- * Here the scatter gather list elements are each tagged with the appropriate
- * dma address and length. They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of DMA
- * address/length pairs than there are SG table elements. (for example
- * via virtual mapping capabilities) The routine returns the number of
- * addr/length pairs actually used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are the same
- * here.
- */
static inline
int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
enum dma_data_direction direction)
@@ -91,11 +67,6 @@ int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
return nents;
}
-/*
- * Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
static inline
void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
enum dma_data_direction direction)
@@ -103,10 +74,6 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
BUG_ON(!valid_dma_direction(direction));
}
-/*
- * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
- * to pci_map_single, but takes a struct page instead of a virtual address
- */
static inline
dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
@@ -123,15 +90,6 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
BUG_ON(direction == DMA_NONE);
}
-/*
- * Make physical memory consistent for a single streaming mode DMA translation
- * after a transfer.
- *
- * If you perform a pci_map_single() but wish to interrogate the buffer using
- * the cpu, yet do not wish to teardown the PCI dma mapping, you must call this
- * function before doing so. At the next point you give the PCI dma address
- * back to the card, the device again owns the buffer.
- */
static inline
void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
size_t size, enum dma_data_direction direction)
@@ -161,13 +119,6 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
}
-/*
- * Make physical memory consistent for a set of streaming mode DMA translations
- * after a transfer.
- *
- * The same as pci_dma_sync_single but for a scatter-gather list, same rules
- * and usage.
- */
static inline
void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
int nelems, enum dma_data_direction direction)
@@ -187,12 +138,6 @@ int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
return 0;
}
-/*
- * Return whether the given PCI device DMA address mask can be supported
- * properly. For example, if your device can only drive the low 24-bits during
- * PCI bus mastering, then you would pass 0x00ffffff as the mask to this
- * function.
- */
static inline
int dma_supported(struct device *dev, u64 mask)
{
diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h
index 1b0ba5e182b..7c2e911052b 100644
--- a/arch/mn10300/include/asm/ptrace.h
+++ b/arch/mn10300/include/asm/ptrace.h
@@ -99,8 +99,6 @@ struct task_struct;
extern void show_regs(struct pt_regs *);
#define arch_has_single_step() (1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
#endif /* !__ASSEMBLY */
diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h
index c05acb95c2a..9d056f51592 100644
--- a/arch/mn10300/include/asm/unistd.h
+++ b/arch/mn10300/include/asm/unistd.h
@@ -363,6 +363,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -375,6 +376,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_SELECT
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index 88e3e1c3cc2..d9ed5a15c54 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -468,7 +468,7 @@ ENTRY(sys_call_table)
.long sys_settimeofday
.long sys_getgroups16 /* 80 */
.long sys_setgroups16
- .long old_select
+ .long sys_old_select
.long sys_symlink
.long sys_lstat
.long sys_readlink /* 85 */
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index ec8a21df114..82b817c7f7b 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -18,7 +18,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
@@ -26,6 +25,7 @@
#include <linux/percpu.h>
#include <linux/err.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c
index 3f24c298a3a..d464affcba0 100644
--- a/arch/mn10300/kernel/setup.c
+++ b/arch/mn10300/kernel/setup.c
@@ -15,7 +15,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/tty.h>
#include <linux/ioport.h>
diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c
index 17cc6ce04e8..815f1355fad 100644
--- a/arch/mn10300/kernel/sys_mn10300.c
+++ b/arch/mn10300/kernel/sys_mn10300.c
@@ -31,109 +31,3 @@ asmlinkage long old_mmap(unsigned long addr, unsigned long len,
return -EINVAL;
return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
}
-
-struct sel_arg_struct {
- unsigned long n;
- fd_set *inp;
- fd_set *outp;
- fd_set *exp;
- struct timeval *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
- struct sel_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
- /* sys_select() does the appropriate kernel locking */
- return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage long sys_ipc(uint call, int first, int second,
- int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr,
- second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr,
- second,
- (const struct timespec __user *)fifth);
- case SEMGET:
- return sys_semget(first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void __user * __user *) ptr))
- return -EFAULT;
- return sys_semctl(first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd(first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof(tmp)))
- return -EFAULT;
- return sys_msgrcv(first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv(first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget((key_t) first, second);
- case MSGCTL:
- return sys_msgctl(first, second,
- (struct msqid_ds __user *) ptr);
-
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat(first, (char __user *) ptr, second,
- &raddr);
- if (ret)
- return ret;
- return put_user(raddr, (ulong *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return do_shmat(first, (char __user *) ptr, second,
- (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt((char __user *)ptr);
- case SHMGET:
- return sys_shmget(first, second, third);
- case SHMCTL:
- return sys_shmctl(first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -EINVAL;
- }
-}
diff --git a/arch/mn10300/mm/dma-alloc.c b/arch/mn10300/mm/dma-alloc.c
index ee82d624b3c..4e34880bea0 100644
--- a/arch/mn10300/mm/dma-alloc.c
+++ b/arch/mn10300/mm/dma-alloc.c
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <asm/io.h>
static unsigned long pci_sram_allocated = 0xbc000000;
diff --git a/arch/mn10300/mm/init.c b/arch/mn10300/mm/init.c
index dd27a9a3515..6e6bc0e5152 100644
--- a/arch/mn10300/mm/init.c
+++ b/arch/mn10300/mm/init.c
@@ -17,7 +17,6 @@
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/swap.h>
@@ -27,6 +26,7 @@
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/bootmem.h>
+#include <linux/gfp.h>
#include <asm/processor.h>
#include <asm/system.h>
diff --git a/arch/mn10300/mm/pgtable.c b/arch/mn10300/mm/pgtable.c
index baffc581e03..9c1624c9e4e 100644
--- a/arch/mn10300/mm/pgtable.c
+++ b/arch/mn10300/mm/pgtable.c
@@ -12,11 +12,11 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/gfp.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/quicklist.h>
diff --git a/arch/mn10300/unit-asb2305/pci-irq.c b/arch/mn10300/unit-asb2305/pci-irq.c
index 58cfb44f0ac..91212ea71e6 100644
--- a/arch/mn10300/unit-asb2305/pci-irq.c
+++ b/arch/mn10300/unit-asb2305/pci-irq.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/io.h>
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index f388dc68f60..9c4da3d63bf 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -95,6 +95,9 @@ config PM
config STACKTRACE_SUPPORT
def_bool y
+config NEED_DMA_MAP_STATE
+ def_bool y
+
config ISA_DMA_API
bool
diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug
index bc989e522a0..7305ac8f7f5 100644
--- a/arch/parisc/Kconfig.debug
+++ b/arch/parisc/Kconfig.debug
@@ -12,4 +12,18 @@ config DEBUG_RODATA
portion of the kernel code won't be covered by a TLB anymore.
If in doubt, say "N".
+config DEBUG_STRICT_USER_COPY_CHECKS
+ bool "Strict copy size checks"
+ depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING
+ ---help---
+ Enabling this option turns a certain set of sanity checks for user
+ copy operations into compile time failures.
+
+ The copy_from_user() etc checks are there to help test if there
+ are sufficient security checks on the length argument of
+ the copy operation, by having gcc prove that the argument is
+ within bounds.
+
+ If unsure, or if you run an older (pre 4.4) gcc, say N.
+
endmenu
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index 54075360a8f..6935123178e 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -26,8 +26,8 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/file.h>
-#include <linux/slab.h>
#include <linux/ptrace.h>
+#include <linux/slab.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index 7f32611a7a5..02b77baa5da 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -7,7 +7,8 @@
#include <linux/sched.h>
#include <linux/thread_info.h>
-#define COMPAT_USER_HZ 100
+#define COMPAT_USER_HZ 100
+#define COMPAT_UTS_MACHINE "parisc\0\0"
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
diff --git a/arch/parisc/include/asm/param.h b/arch/parisc/include/asm/param.h
index 32e03d87785..965d4542797 100644
--- a/arch/parisc/include/asm/param.h
+++ b/arch/parisc/include/asm/param.h
@@ -1,22 +1 @@
-#ifndef _ASMPARISC_PARAM_H
-#define _ASMPARISC_PARAM_H
-
-#ifdef __KERNEL__
-#define HZ CONFIG_HZ
-#define USER_HZ 100 /* some user API use "ticks" */
-#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif
+#include <asm-generic/param.h>
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 64c7aa590ae..2242a5c636c 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -183,20 +183,6 @@ struct pci_bios_ops {
void (*fixup_bus)(struct pci_bus *bus);
};
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
/*
** Stuff declared in arch/parisc/kernel/pci.c
*/
diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h
index aead40b16dd..7f09533da77 100644
--- a/arch/parisc/include/asm/ptrace.h
+++ b/arch/parisc/include/asm/ptrace.h
@@ -47,13 +47,8 @@ struct pt_regs {
#define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS))
-struct task_struct;
#define arch_has_single_step() 1
-void user_disable_single_step(struct task_struct *task);
-void user_enable_single_step(struct task_struct *task);
-
#define arch_has_block_step() 1
-void user_enable_block_step(struct task_struct *task);
/* XXX should we use iaoq[1] or iaoq[0] ? */
#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
diff --git a/arch/parisc/include/asm/system.h b/arch/parisc/include/asm/system.h
index d91357bca5b..4653c77bf9d 100644
--- a/arch/parisc/include/asm/system.h
+++ b/arch/parisc/include/asm/system.h
@@ -160,7 +160,7 @@ static inline void set_eiem(unsigned long val)
ldcd). */
#define __PA_LDCW_ALIGNMENT 4
-#define __ldcw_align(a) ((volatile unsigned int *)a)
+#define __ldcw_align(a) (&(a)->slock)
#define __LDCW "ldcw,co"
#endif /*!CONFIG_PA20*/
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
index 7cf799d70b4..ff4cf9dab8d 100644
--- a/arch/parisc/include/asm/uaccess.h
+++ b/arch/parisc/include/asm/uaccess.h
@@ -7,6 +7,7 @@
#include <asm/page.h>
#include <asm/system.h>
#include <asm/cache.h>
+#include <asm/errno.h>
#include <asm-generic/uaccess-unaligned.h>
#define VERIFY_READ 0
@@ -234,13 +235,35 @@ extern long lstrnlen_user(const char __user *,long);
unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len);
#define __copy_to_user copy_to_user
-unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len);
-#define __copy_from_user copy_from_user
+unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len);
unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len);
#define __copy_in_user copy_in_user
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+ __compiletime_error("copy_from_user() buffer size is not provably correct")
+#else
+ __compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
+static inline unsigned long __must_check copy_from_user(void *to,
+ const void __user *from,
+ unsigned long n)
+{
+ int sz = __compiletime_object_size(to);
+ int ret = -EFAULT;
+
+ if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n))
+ ret = __copy_from_user(to, from, n);
+ else
+ copy_from_user_overflow();
+
+ return ret;
+}
+
struct pt_regs;
int fixup_exception(struct pt_regs *regs);
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index cda158318c6..1ce7d2851d9 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -811,8 +811,10 @@
#define __NR_pwritev (__NR_Linux + 316)
#define __NR_rt_tgsigqueueinfo (__NR_Linux + 317)
#define __NR_perf_event_open (__NR_Linux + 318)
+#define __NR_recvmmsg (__NR_Linux + 319)
+#define __NR_accept4 (__NR_Linux + 320)
-#define __NR_Linux_syscalls (__NR_perf_event_open + 1)
+#define __NR_Linux_syscalls (__NR_accept4 + 1)
#define __IGNORE_select /* newselect */
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 1054baa2fc6..d054f3da3ff 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -171,14 +171,14 @@ parisc_cache_init(void)
cache_info.ic_conf.cc_cst,
cache_info.ic_conf.cc_hv);
- printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+ printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n",
cache_info.dt_conf.tc_sh,
cache_info.dt_conf.tc_page,
cache_info.dt_conf.tc_cst,
cache_info.dt_conf.tc_aid,
cache_info.dt_conf.tc_pad1);
- printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+ printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n",
cache_info.it_conf.tc_sh,
cache_info.it_conf.tc_page,
cache_info.it_conf.tc_cst,
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 212074653df..159a2b81e90 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -61,6 +61,7 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/bug.h>
+#include <linux/slab.h>
#include <asm/unwind.h>
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index c07f618ff7d..a029f74a3c5 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -18,11 +18,11 @@
*/
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/scatterlist.h>
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 38372e7cbb8..9efd9740531 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <asm/io.h>
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 1f3aa8db020..76332dadc6e 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -43,6 +43,7 @@
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/kallsyms.h>
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index fb59852006d..e1413243076 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -23,7 +23,6 @@
*/
#include <linux/compat.h>
-#include <linux/slab.h>
#include <linux/module.h>
#include <linux/unistd.h>
#include <linux/init.h>
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 3f2fce8ce6b..69d63d354ef 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -18,7 +18,6 @@
*/
#include <linux/types.h>
#include <linux/spinlock.h>
-#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 9147391afb0..c9b932260f4 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -234,18 +234,3 @@ long parisc_personality(unsigned long personality)
return err;
}
-
-long parisc_newuname(struct new_utsname __user *name)
-{
- int err = sys_newuname(name);
-
-#ifdef CONFIG_COMPAT
- if (!err && personality(current->personality) == PER_LINUX32) {
- if (__put_user(0, name->machine + 6) ||
- __put_user(0, name->machine + 7))
- err = -EFAULT;
- }
-#endif
-
- return err;
-}
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 01c4fcf8f48..3d52c978738 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -127,7 +127,7 @@
ENTRY_SAME(socketpair)
ENTRY_SAME(setpgid)
ENTRY_SAME(send)
- ENTRY_OURS(newuname)
+ ENTRY_SAME(newuname)
ENTRY_SAME(umask) /* 60 */
ENTRY_SAME(chroot)
ENTRY_COMP(ustat)
@@ -417,6 +417,8 @@
ENTRY_COMP(pwritev)
ENTRY_COMP(rt_tgsigqueueinfo)
ENTRY_SAME(perf_event_open)
+ ENTRY_COMP(recvmmsg)
+ ENTRY_SAME(accept4) /* 320 */
/* Nothing yet */
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index a79c6f9e7e2..05511ccb61d 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -250,9 +250,21 @@ static int __init rtc_init(void)
}
module_init(rtc_init);
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
{
static struct pdc_tod tod_data;
+ if (pdc_tod_read(&tod_data) == 0) {
+ ts->tv_sec = tod_data.tod_sec;
+ ts->tv_nsec = tod_data.tod_usec * 1000;
+ } else {
+ printk(KERN_ERR "Error reading tod clock\n");
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ }
+}
+
+void __init time_init(void)
+{
unsigned long current_cr16_khz;
clocktick = (100 * PAGE0->mem_10msec) / HZ;
@@ -264,19 +276,4 @@ void __init time_init(void)
clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz,
clocksource_cr16.shift);
clocksource_register(&clocksource_cr16);
-
- if (pdc_tod_read(&tod_data) == 0) {
- unsigned long flags;
-
- write_seqlock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = tod_data.tod_sec;
- xtime.tv_nsec = tod_data.tod_usec * 1000;
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
- write_sequnlock_irqrestore(&xtime_lock, flags);
- } else {
- printk(KERN_ERR "Error reading tod clock\n");
- xtime.tv_sec = 0;
- xtime.tv_nsec = 0;
- }
}
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index e6f4b7a4b7e..92d977bb5ea 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/signal.h>
+#include <linux/ratelimit.h>
#include <asm/uaccess.h>
/* #define DEBUG_UNALIGNED 1 */
@@ -446,8 +447,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
void handle_unaligned(struct pt_regs *regs)
{
- static unsigned long unaligned_count = 0;
- static unsigned long last_time = 0;
+ static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
int modify = 0;
int ret = ERR_NOTHANDLED;
@@ -460,14 +460,8 @@ void handle_unaligned(struct pt_regs *regs)
goto force_sigbus;
}
- if (unaligned_count > 5 &&
- time_after(jiffies, last_time + 5 * HZ)) {
- unaligned_count = 0;
- last_time = jiffies;
- }
-
- if (!(current->thread.flags & PARISC_UAC_NOPRINT)
- && ++unaligned_count < 5) {
+ if (!(current->thread.flags & PARISC_UAC_NOPRINT) &&
+ __ratelimit(&ratelimit)) {
char buf[256];
sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index abf41f4632a..1dbca5c31b3 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -475,7 +475,8 @@ unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len)
return pa_memcpy((void __force *)dst, src, len);
}
-unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len)
+EXPORT_SYMBOL(__copy_from_user);
+unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len)
{
mtsp(get_user_space(), 1);
mtsp(get_kernel_space(), 2);
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 13b6e3e59b9..f4f4d700833 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/pci.h> /* for hppa_dma_ops and pcxl_dma_ops */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 155d571f5e2..2e19500921f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -313,19 +313,6 @@ config 8XX_MINIMAL_FPEMU
It is recommended that you build a soft-float userspace instead.
-config IOMMU_VMERGE
- bool "Enable IOMMU virtual merging"
- depends on PPC64
- default y
- help
- Cause IO segments sent to a device for DMA to be merged virtually
- by the IOMMU when they happen to have been allocated contiguously.
- This doesn't add pressure to the IOMMU allocator. However, some
- drivers don't support getting large merged segments coming back
- from *_map_sg().
-
- Most drivers don't have this problem; it is safe to say Y here.
-
config IOMMU_HELPER
def_bool PPC64
@@ -672,6 +659,9 @@ config ZONE_DMA
bool
default y
+config NEED_DMA_MAP_STATE
+ def_bool (PPC64 || NOT_COHERENT_CACHE)
+
config GENERIC_ISA_DMA
bool
depends on PPC64 || POWER4 || 6xx && !CPM2
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts
index 977f260d5e6..83f4b79dff8 100644
--- a/arch/powerpc/boot/dts/gef_ppc9a.dts
+++ b/arch/powerpc/boot/dts/gef_ppc9a.dts
@@ -1,7 +1,7 @@
/*
- * GE Fanuc PPC9A Device Tree Source
+ * GE PPC9A Device Tree Source
*
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
index 8e4efff3bda..fc3a331dd39 100644
--- a/arch/powerpc/boot/dts/gef_sbc310.dts
+++ b/arch/powerpc/boot/dts/gef_sbc310.dts
@@ -1,7 +1,7 @@
/*
- * GE Fanuc SBC310 Device Tree Source
+ * GE SBC310 Device Tree Source
*
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
index bb7060078fb..c0671cc9812 100644
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ b/arch/powerpc/boot/dts/gef_sbc610.dts
@@ -1,7 +1,7 @@
/*
- * GE Fanuc SBC610 Device Tree Source
+ * GE SBC610 Device Tree Source
*
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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
diff --git a/arch/powerpc/boot/dts/kmeter1.dts b/arch/powerpc/boot/dts/kmeter1.dts
index 65b8b4f27ef..d8b5d12fb66 100644
--- a/arch/powerpc/boot/dts/kmeter1.dts
+++ b/arch/powerpc/boot/dts/kmeter1.dts
@@ -490,7 +490,7 @@
compatible = "cfi-flash";
/*
* The Intel P30 chip has 2 non-identical chips on
- * one die, so we need to define 2 seperate regions
+ * one die, so we need to define 2 separate regions
* that are scanned by physmap_of independantly.
*/
reg = <0 0x00000000 0x02000000
diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig
index ff9bdb28197..218d49b36a0 100644
--- a/arch/powerpc/configs/52xx/cm5200_defconfig
+++ b/arch/powerpc/configs/52xx/cm5200_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:07 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:22 2010
#
# CONFIG_PPC64 is not set
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ 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
@@ -340,7 +336,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -517,6 +512,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -684,6 +681,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=57600
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -714,6 +712,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -754,6 +753,7 @@ CONFIG_WATCHDOG=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
# CONFIG_MPC5200_WDT is not set
#
@@ -771,18 +771,20 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -813,7 +815,6 @@ CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -891,7 +892,6 @@ CONFIG_USB_STORAGE=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
@@ -903,7 +903,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1009,6 +1008,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
diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig
index 7b3f4d0ed40..90492ff2523 100644
--- a/arch/powerpc/configs/52xx/lite5200b_defconfig
+++ b/arch/powerpc/configs/52xx/lite5200b_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:09 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:24 2010
#
# CONFIG_PPC64 is not set
@@ -95,11 +95,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -110,6 +105,7 @@ 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
@@ -317,6 +313,7 @@ CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_HIBERNATION is not set
# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -333,7 +330,6 @@ 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_PCI_IOV is not set
@@ -360,7 +356,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -457,6 +452,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -631,6 +628,7 @@ CONFIG_ATA_SFF=y
# 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_MPC52xx=y
@@ -668,7 +666,7 @@ CONFIG_PATA_MPC52xx=y
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -768,6 +766,7 @@ 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
@@ -828,6 +827,7 @@ CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -879,6 +879,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -924,18 +925,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -944,6 +948,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1062,6 +1067,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig
index eaae2d469aa..dffc8cac825 100644
--- a/arch/powerpc/configs/52xx/motionpro_defconfig
+++ b/arch/powerpc/configs/52xx/motionpro_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:08 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:23 2010
#
# CONFIG_PPC64 is not set
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ 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
@@ -341,7 +337,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -518,6 +513,8 @@ CONFIG_MTD_ROM=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -699,6 +696,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -728,6 +726,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -773,10 +772,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
@@ -811,6 +811,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -831,6 +832,7 @@ CONFIG_WATCHDOG=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
# CONFIG_MPC5200_WDT is not set
CONFIG_SSB_POSSIBLE=y
@@ -843,18 +845,20 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1050,6 +1054,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
diff --git a/arch/powerpc/configs/52xx/pcm030_defconfig b/arch/powerpc/configs/52xx/pcm030_defconfig
index 1742c0200b7..3cb2a522046 100644
--- a/arch/powerpc/configs/52xx/pcm030_defconfig
+++ b/arch/powerpc/configs/52xx/pcm030_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:10 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:25 2010
#
# CONFIG_PPC64 is not set
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -326,7 +321,6 @@ 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_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -352,7 +346,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -525,6 +518,8 @@ CONFIG_MTD_PHYSMAP=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -610,6 +605,7 @@ CONFIG_ATA_SFF=y
# 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_MPC52xx=m
@@ -647,7 +643,7 @@ CONFIG_PATA_MPC52xx=m
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -775,6 +771,7 @@ CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -824,6 +821,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -870,18 +868,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -890,6 +891,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -997,7 +999,6 @@ CONFIG_USB_STORAGE=m
# 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
@@ -1009,7 +1010,6 @@ CONFIG_USB_STORAGE=m
# 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
#
@@ -1172,6 +1172,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig
index 3972438db71..96181c62abf 100644
--- a/arch/powerpc/configs/52xx/tqm5200_defconfig
+++ b/arch/powerpc/configs/52xx/tqm5200_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:09 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:24 2010
#
# CONFIG_PPC64 is not set
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ 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
@@ -346,7 +342,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -524,6 +519,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -704,6 +701,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -733,6 +731,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -780,10 +779,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
@@ -818,6 +818,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -838,6 +839,7 @@ CONFIG_WATCHDOG=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
# CONFIG_MPC5200_WDT is not set
#
@@ -855,18 +857,20 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -897,7 +901,6 @@ CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -975,7 +978,6 @@ CONFIG_USB_STORAGE=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
@@ -987,7 +989,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1151,6 +1152,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
diff --git a/arch/powerpc/configs/83xx/asp8347_defconfig b/arch/powerpc/configs/83xx/asp8347_defconfig
index baa2bbb6c09..04f16268e1c 100644
--- a/arch/powerpc/configs/83xx/asp8347_defconfig
+++ b/arch/powerpc/configs/83xx/asp8347_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:14 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:38 2010
#
# CONFIG_PPC64 is not set
@@ -97,14 +97,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -112,6 +106,7 @@ 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
@@ -124,7 +119,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -543,6 +537,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -579,6 +575,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -596,6 +593,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -788,6 +786,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -836,6 +835,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -849,15 +849,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -883,10 +877,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -923,6 +918,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -971,18 +967,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -991,6 +990,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1083,7 +1083,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
@@ -1096,7 +1095,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
#
@@ -1259,6 +1257,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1285,6 +1284,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/kmeter1_defconfig b/arch/powerpc/configs/83xx/kmeter1_defconfig
index 8b1aa806e54..1843ee11823 100644
--- a/arch/powerpc/configs/83xx/kmeter1_defconfig
+++ b/arch/powerpc/configs/83xx/kmeter1_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:14 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:39 2010
#
# CONFIG_PPC64 is not set
@@ -98,7 +98,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_FSL_SOC=y
CONFIG_PPC_PCI_CHOICE=y
@@ -346,7 +346,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -387,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ATM is not set
CONFIG_STP=m
CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
# CONFIG_NET_DSA is not set
CONFIG_VLAN_8021Q=y
# CONFIG_VLAN_8021Q_GVRP is not set
@@ -539,6 +539,8 @@ CONFIG_MTD_UBI_DEBUG=y
# CONFIG_MTD_UBI_DEBUG_MSG_EBA is not set
# CONFIG_MTD_UBI_DEBUG_MSG_WL is not set
# CONFIG_MTD_UBI_DEBUG_MSG_IO is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -563,6 +565,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -690,6 +693,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -720,6 +724,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -732,15 +737,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -765,18 +764,20 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -805,8 +806,6 @@ CONFIG_SSB_POSSIBLE=y
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not set
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
#
# TI VLYNQ
@@ -887,6 +886,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_UBIFS_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
@@ -911,6 +911,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
@@ -976,6 +977,7 @@ CONFIG_DEBUG_FS=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
diff --git a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
index 2f2d98558e4..78ae3bf1e9c 100644
--- a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:15 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:40 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -362,7 +357,6 @@ 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
@@ -556,6 +550,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_SPI=y
@@ -593,6 +589,7 @@ CONFIG_MISC_DEVICES=y
# 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_TI_DAC7512 is not set
# CONFIG_C2PORT is not set
@@ -612,6 +609,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
@@ -772,6 +770,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -824,6 +823,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
@@ -836,6 +837,7 @@ 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
@@ -931,6 +933,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -980,6 +983,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -993,15 +997,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
@@ -1044,10 +1042,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1086,6 +1085,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1134,21 +1134,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1157,6 +1160,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1289,7 +1293,6 @@ CONFIG_USB_STORAGE=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
@@ -1302,7 +1305,6 @@ CONFIG_USB_STORAGE=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=y
# CONFIG_USB_GADGET_DEBUG is not set
# CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1341,6 +1343,7 @@ CONFIG_USB_ETH_RNDIS=y
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
# CONFIG_USB_G_MULTI is not set
#
@@ -1511,6 +1514,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1537,6 +1541,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
index 633e6119460..cccb71393ac 100644
--- a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:16 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:40 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -362,7 +357,6 @@ 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
@@ -556,6 +550,8 @@ CONFIG_MTD_NAND_IDS=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_SPI=y
@@ -593,6 +589,7 @@ CONFIG_MISC_DEVICES=y
# 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_TI_DAC7512 is not set
# CONFIG_C2PORT is not set
@@ -612,6 +609,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
@@ -735,6 +733,7 @@ CONFIG_ATA_SFF=y
# 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
@@ -837,6 +836,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -889,6 +889,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
@@ -901,6 +903,7 @@ 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
@@ -996,6 +999,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1045,6 +1049,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1058,15 +1063,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
@@ -1109,10 +1108,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1151,6 +1151,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1199,21 +1200,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1222,6 +1226,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1354,7 +1359,6 @@ CONFIG_USB_STORAGE=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
@@ -1367,7 +1371,6 @@ CONFIG_USB_STORAGE=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=y
# CONFIG_USB_GADGET_DEBUG is not set
# CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1406,6 +1409,7 @@ CONFIG_USB_ETH_RNDIS=y
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
# CONFIG_USB_G_MULTI is not set
#
@@ -1576,6 +1580,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1602,6 +1607,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
index 0b4262bd491..74cb27aa9d1 100644
--- a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
+++ b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:17 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:41 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ 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
@@ -457,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -492,6 +488,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -509,6 +506,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,6 +691,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
@@ -705,6 +705,7 @@ 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
@@ -790,6 +791,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -839,6 +841,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -851,15 +854,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -885,10 +882,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -925,6 +923,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -967,18 +966,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -987,6 +989,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1171,6 +1174,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -1197,6 +1201,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
index 155af009f7b..10412a9c7f9 100644
--- a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:18 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:42 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ 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
@@ -457,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_SPI=y
@@ -494,6 +490,7 @@ CONFIG_MISC_DEVICES=y
# 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_TI_DAC7512 is not set
# CONFIG_C2PORT is not set
@@ -514,6 +511,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
@@ -700,6 +698,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
@@ -712,6 +712,7 @@ 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
@@ -808,6 +809,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -859,6 +861,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -872,15 +875,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
CONFIG_SPI_MASTER=y
@@ -922,10 +919,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -964,6 +962,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1012,21 +1011,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1035,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1166,7 +1169,6 @@ CONFIG_USB_STORAGE=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
@@ -1179,7 +1181,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1204,8 +1205,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# CONFIG_MMC_SDHCI is not set
# CONFIG_MMC_WBSD is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
# CONFIG_MMC_TIFM_SD is not set
CONFIG_MMC_SPI=y
# CONFIG_MMC_CB710 is not set
@@ -1298,6 +1297,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -1324,6 +1324,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
index ff45f490448..7b31fc3f354 100644
--- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
+++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:19 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:43 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ 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
@@ -540,6 +534,8 @@ CONFIG_MTD_PHYSMAP=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_SPI=y
@@ -577,6 +573,7 @@ CONFIG_MISC_DEVICES=y
# 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_TI_DAC7512 is not set
# CONFIG_C2PORT is not set
@@ -644,6 +641,7 @@ CONFIG_IDE_PROC_FS=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -767,6 +765,7 @@ CONFIG_SATA_SIL=y
# 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
@@ -880,6 +879,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
@@ -892,6 +893,7 @@ 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
@@ -966,6 +968,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1015,6 +1018,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1028,15 +1032,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
CONFIG_SPI_MASTER=y
@@ -1095,21 +1093,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1118,6 +1119,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1222,7 +1224,6 @@ CONFIG_USB_STORAGE=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
@@ -1235,7 +1236,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1399,6 +1399,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1425,6 +1426,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
index 28d8ff3e8fc..41401a9b355 100644
--- a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
+++ b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:20 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:44 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ 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
@@ -540,6 +534,8 @@ CONFIG_MTD_PHYSMAP=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_SPI=y
@@ -577,6 +573,7 @@ CONFIG_MISC_DEVICES=y
# 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_TI_DAC7512 is not set
# CONFIG_C2PORT is not set
@@ -596,6 +593,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
@@ -756,6 +754,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
@@ -768,6 +768,7 @@ 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
@@ -842,6 +843,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -891,6 +893,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -904,15 +907,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
CONFIG_SPI_MASTER=y
@@ -971,21 +968,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -994,6 +994,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1098,7 +1099,6 @@ CONFIG_USB_STORAGE=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
@@ -1111,7 +1111,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1275,6 +1274,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1301,6 +1301,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
index 6252ab5bf18..dc176b676dc 100644
--- a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
+++ b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:21 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:45 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -456,6 +450,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -491,6 +487,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -508,6 +505,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -580,6 +578,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -631,6 +630,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
@@ -643,6 +644,7 @@ 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
@@ -726,6 +728,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -774,6 +777,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -786,15 +790,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -820,10 +818,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -860,6 +859,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -902,18 +902,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -922,6 +925,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1106,6 +1110,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -1132,6 +1137,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
index 78227378e67..f512972c717 100644
--- a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
+++ b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:21 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:46 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -323,6 +318,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -334,7 +330,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -360,7 +355,6 @@ 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
@@ -538,6 +532,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -573,6 +569,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -590,6 +587,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
@@ -774,6 +772,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
@@ -786,6 +786,7 @@ 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
@@ -871,6 +872,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -920,6 +922,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -932,15 +935,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -966,10 +963,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1006,6 +1004,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1048,18 +1047,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1068,6 +1070,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1253,6 +1256,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1279,6 +1283,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
index 9451d6e5c80..77abfe8ff19 100644
--- a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
+++ b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:23 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:47 2010
#
# CONFIG_PPC64 is not set
@@ -97,14 +97,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -112,6 +106,7 @@ 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
@@ -124,7 +119,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -323,6 +318,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ 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
@@ -550,6 +544,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -587,6 +583,7 @@ CONFIG_MISC_DEVICES=y
# 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_TI_DAC7512 is not set
# CONFIG_C2PORT is not set
@@ -606,6 +603,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -774,6 +772,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_SERIAL_QE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -825,6 +824,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -837,15 +837,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
CONFIG_SPI_MASTER=y
@@ -876,14 +870,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -932,22 +930,27 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -956,6 +959,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1145,6 +1149,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1171,6 +1176,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
index f67b70d0b29..0cdb41418d5 100644
--- a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
+++ b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:22 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:47 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -124,7 +119,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -456,6 +450,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -491,6 +487,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -508,6 +505,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
@@ -631,6 +629,7 @@ CONFIG_ATA_SFF=y
# 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
@@ -755,6 +754,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
@@ -767,6 +768,7 @@ 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
@@ -851,6 +853,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -901,6 +904,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -913,15 +917,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -947,10 +945,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +986,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1029,18 +1029,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1049,6 +1052,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1175,6 +1179,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -1201,6 +1206,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
index a84fd1194e2..e69ed1b6142 100644
--- a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:24 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:48 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -124,7 +119,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -451,6 +445,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -487,6 +483,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -504,6 +501,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
@@ -626,6 +624,7 @@ CONFIG_ATA_SFF=y
# 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
@@ -850,6 +849,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -900,6 +900,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -913,15 +914,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -947,10 +942,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +983,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1034,18 +1031,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1054,6 +1054,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1079,6 +1080,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1094,14 +1096,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1190,7 +1197,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
@@ -1203,7 +1209,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
#
@@ -1297,6 +1302,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -1323,6 +1329,7 @@ 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
diff --git a/arch/powerpc/configs/83xx/sbc834x_defconfig b/arch/powerpc/configs/83xx/sbc834x_defconfig
index 72c2067137b..56e3995d898 100644
--- a/arch/powerpc/configs/83xx/sbc834x_defconfig
+++ b/arch/powerpc/configs/83xx/sbc834x_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:25 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:49 2010
#
# CONFIG_PPC64 is not set
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ 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
@@ -123,7 +118,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -322,6 +317,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -333,7 +329,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -359,7 +354,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -537,6 +531,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -573,6 +569,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -590,6 +587,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
@@ -812,6 +810,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -862,6 +861,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -875,15 +875,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -909,10 +903,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -949,6 +944,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -996,18 +992,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1016,6 +1015,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1140,7 +1140,6 @@ CONFIG_USB_STORAGE=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
@@ -1153,7 +1152,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1245,6 +1243,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1271,6 +1270,7 @@ 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
diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig
index 21dad38b156..f67a8d1cd0b 100644
--- a/arch/powerpc/configs/85xx/ksi8560_defconfig
+++ b/arch/powerpc/configs/85xx/ksi8560_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:26 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:50 2010
#
# CONFIG_PPC64 is not set
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -99,10 +103,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -110,6 +112,7 @@ 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
@@ -315,6 +318,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_FSL_SOC=y
CONFIG_PPC_PCI_CHOICE=y
# CONFIG_PCI is not set
@@ -345,7 +349,6 @@ 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
@@ -522,6 +525,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_MDIO=y
@@ -575,6 +580,7 @@ CONFIG_IDE_PROC_FS=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -701,6 +707,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -732,6 +739,7 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
#
@@ -915,6 +923,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -937,6 +946,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
@@ -1036,6 +1046,7 @@ CONFIG_DEBUG_MUTEXES=y
# 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=y
diff --git a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
index 5db54cd274c..61b122a25cd 100644
--- a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
+++ b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:27 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:51 2010
#
# CONFIG_PPC64 is not set
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ 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
@@ -316,6 +315,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_FSL_SOC=y
CONFIG_PPC_PCI_CHOICE=y
# CONFIG_PCI is not set
@@ -346,7 +346,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -443,6 +442,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -477,6 +478,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -602,6 +604,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -788,6 +791,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -810,6 +814,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
diff --git a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
index 76c7018c5cd..a5ceaa4b5e4 100644
--- a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
+++ b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:28 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:52 2010
#
# CONFIG_PPC64 is not set
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ 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
@@ -319,6 +318,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -329,7 +329,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
CONFIG_PCI_DEBUG=y
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
@@ -358,7 +357,6 @@ 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
@@ -455,6 +453,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_MDIO=y
@@ -500,6 +500,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -609,6 +610,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
@@ -621,6 +624,7 @@ 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
@@ -700,6 +704,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -733,7 +738,9 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
#
# I2C GPIO expanders:
@@ -793,6 +800,8 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -801,6 +810,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -927,6 +937,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -949,6 +960,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
diff --git a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
index fab8adacbf7..4adb4eba2d4 100644
--- a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
+++ b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:53 2010
#
# CONFIG_PPC64 is not set
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ 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
@@ -317,6 +316,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -327,7 +327,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -356,7 +355,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -453,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -552,6 +552,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -657,6 +658,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
@@ -669,6 +672,7 @@ 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
@@ -753,6 +757,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -817,6 +822,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -825,6 +831,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -951,6 +958,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -973,6 +981,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
diff --git a/arch/powerpc/configs/85xx/sbc8548_defconfig b/arch/powerpc/configs/85xx/sbc8548_defconfig
index 8290385e9b9..3de8450cd55 100644
--- a/arch/powerpc/configs/85xx/sbc8548_defconfig
+++ b/arch/powerpc/configs/85xx/sbc8548_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:54 2010
#
# CONFIG_PPC64 is not set
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ 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
@@ -314,6 +313,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -324,7 +324,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -352,7 +351,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -447,6 +445,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -491,6 +491,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -596,6 +597,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
@@ -608,6 +611,7 @@ 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
@@ -692,6 +696,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -756,6 +761,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -764,6 +770,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -856,6 +863,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -878,6 +886,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
diff --git a/arch/powerpc/configs/85xx/sbc8560_defconfig b/arch/powerpc/configs/85xx/sbc8560_defconfig
index 2499b5ba714..bd467fe1393 100644
--- a/arch/powerpc/configs/85xx/sbc8560_defconfig
+++ b/arch/powerpc/configs/85xx/sbc8560_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:30 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:54 2010
#
# CONFIG_PPC64 is not set
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ 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
@@ -314,6 +313,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_FSL_SOC=y
CONFIG_PPC_PCI_CHOICE=y
# CONFIG_PCI is not set
@@ -344,7 +344,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -441,6 +440,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -475,6 +476,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -600,6 +602,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -815,6 +818,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -837,6 +841,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
diff --git a/arch/powerpc/configs/85xx/socrates_defconfig b/arch/powerpc/configs/85xx/socrates_defconfig
index e2edb79cfd1..9803e031165 100644
--- a/arch/powerpc/configs/85xx/socrates_defconfig
+++ b/arch/powerpc/configs/85xx/socrates_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:31 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:55 2010
#
# CONFIG_PPC64 is not set
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ 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
@@ -319,6 +318,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -329,7 +329,6 @@ 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_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_HAS_RAPIDIO is not set
@@ -355,7 +354,6 @@ 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
@@ -554,6 +552,8 @@ CONFIG_MTD_NAND_SOCRATES=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_SPI=y
@@ -591,6 +591,7 @@ CONFIG_MISC_DEVICES=y
# 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_TI_DAC7512 is not set
# CONFIG_C2PORT is not set
@@ -610,6 +611,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
@@ -867,6 +869,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -916,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -929,15 +933,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
CONFIG_SPI_MASTER=y
@@ -979,10 +977,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1021,6 +1020,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1050,21 +1050,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1073,6 +1076,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1180,6 +1184,7 @@ CONFIG_USB_HID=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
@@ -1194,12 +1199,16 @@ CONFIG_USB_HID=y
# 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_QUANTA 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
@@ -1307,7 +1316,6 @@ CONFIG_USB_STORAGE=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
@@ -1320,7 +1328,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1491,6 +1498,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
@@ -1515,6 +1523,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
diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig
index ce313259df1..880ab7aaf20 100644
--- a/arch/powerpc/configs/85xx/stx_gp3_defconfig
+++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:32 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:56 2010
#
# CONFIG_PPC64 is not set
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ 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
@@ -324,6 +323,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -334,7 +334,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -363,7 +362,6 @@ 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
@@ -520,6 +518,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=m
@@ -563,6 +563,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -630,6 +631,7 @@ CONFIG_IDE_PROC_FS=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=m
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=m
CONFIG_SCSI_DMA=y
@@ -817,6 +819,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
@@ -829,6 +833,7 @@ 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
@@ -947,6 +952,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1004,6 +1010,7 @@ CONFIG_I2C_ALGOBIT=m
# CONFIG_I2C_MPC is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1017,15 +1024,9 @@ CONFIG_I2C_ALGOBIT=m
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1041,14 +1042,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1081,10 +1086,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1122,6 +1128,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1155,9 +1162,10 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_TPS65010 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 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_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1166,6 +1174,7 @@ CONFIG_SSB_POSSIBLE=y
#
CONFIG_AGP=m
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
CONFIG_DRM=m
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
@@ -1308,6 +1317,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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=m
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1333,6 +1343,7 @@ CONFIG_SUNRPC=y
# 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
diff --git a/arch/powerpc/configs/85xx/tqm8540_defconfig b/arch/powerpc/configs/85xx/tqm8540_defconfig
index 0824b466722..230aa2fc062 100644
--- a/arch/powerpc/configs/85xx/tqm8540_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8540_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:33 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:57 2010
#
# CONFIG_PPC64 is not set
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ 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
@@ -315,6 +314,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -325,7 +325,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_HAS_RAPIDIO is not set
@@ -351,7 +350,6 @@ 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
@@ -525,6 +523,8 @@ CONFIG_MTD_CFI_UTIL=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -560,6 +560,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -632,6 +633,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -704,6 +706,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -755,6 +758,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
@@ -767,6 +772,7 @@ 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
@@ -851,6 +857,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -902,6 +909,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -913,15 +921,9 @@ CONFIG_I2C_MPC=y
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -947,10 +949,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +990,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1015,18 +1019,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1035,6 +1042,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1172,6 +1180,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
@@ -1194,6 +1203,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
diff --git a/arch/powerpc/configs/85xx/tqm8541_defconfig b/arch/powerpc/configs/85xx/tqm8541_defconfig
index 2137be4100e..dbe04b981b8 100644
--- a/arch/powerpc/configs/85xx/tqm8541_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8541_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:34 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:58 2010
#
# CONFIG_PPC64 is not set
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ 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
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ 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
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -760,6 +763,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
@@ -772,6 +777,7 @@ 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
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,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
@@ -1235,6 +1250,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
diff --git a/arch/powerpc/configs/85xx/tqm8548_defconfig b/arch/powerpc/configs/85xx/tqm8548_defconfig
index 5cc89aac3fe..845efa79dd2 100644
--- a/arch/powerpc/configs/85xx/tqm8548_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8548_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:35 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:59 2010
#
# CONFIG_PPC64 is not set
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ 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
@@ -324,6 +323,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -339,7 +339,6 @@ CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -368,7 +367,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -559,6 +557,8 @@ CONFIG_MTD_NAND_FSL_UPM=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -594,6 +594,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -611,6 +612,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -716,6 +718,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
@@ -728,6 +732,7 @@ 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
@@ -812,6 +817,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -860,6 +866,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -872,15 +879,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -906,10 +907,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -946,6 +948,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -974,18 +977,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -994,6 +1000,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1162,6 +1169,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1184,6 +1192,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
diff --git a/arch/powerpc/configs/85xx/tqm8555_defconfig b/arch/powerpc/configs/85xx/tqm8555_defconfig
index e7b9148e58c..b958136a12f 100644
--- a/arch/powerpc/configs/85xx/tqm8555_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8555_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:00 2010
#
# CONFIG_PPC64 is not set
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ 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
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ 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
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -760,6 +763,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
@@ -772,6 +777,7 @@ 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
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,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
@@ -1235,6 +1250,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
diff --git a/arch/powerpc/configs/85xx/tqm8560_defconfig b/arch/powerpc/configs/85xx/tqm8560_defconfig
index a998e401bbf..008bc975492 100644
--- a/arch/powerpc/configs/85xx/tqm8560_defconfig
+++ b/arch/powerpc/configs/85xx/tqm8560_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:01 2010
#
# CONFIG_PPC64 is not set
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ 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
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ 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
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -760,6 +763,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
@@ -772,6 +777,7 @@ 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
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,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
@@ -1235,6 +1250,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
diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
index fc656af04ea..2cf80dba028 100644
--- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
+++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:37 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:01 2010
#
# CONFIG_PPC64 is not set
@@ -69,6 +69,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -104,10 +108,8 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -115,6 +117,7 @@ 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
@@ -328,6 +331,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_FSL_PCI=y
@@ -343,7 +347,6 @@ CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
-CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
@@ -375,7 +378,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -600,6 +602,8 @@ CONFIG_MTD_NAND_FSL_UPM=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -637,6 +641,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -654,6 +659,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
@@ -777,6 +783,7 @@ CONFIG_PATA_ALI=y
# 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
@@ -1004,6 +1011,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1053,6 +1061,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1066,15 +1075,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1090,14 +1093,19 @@ CONFIG_GPIO_SYSFS=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
#
# I2C GPIO expanders:
#
+# CONFIG_GPIO_MAX7300 is not set
# CONFIG_GPIO_MAX732X is not set
CONFIG_GPIO_PCA953X=y
+# CONFIG_GPIO_PCA953X_IRQ is not set
# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
#
# PCI GPIO expanders:
@@ -1130,10 +1138,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
CONFIG_SENSORS_DS1621=y
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1171,6 +1180,7 @@ CONFIG_SENSORS_LM90=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1218,19 +1228,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1239,6 +1254,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1271,6 +1287,7 @@ CONFIG_USB_HID=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
@@ -1285,12 +1302,16 @@ CONFIG_USB_HID=y
# 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_QUANTA 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
@@ -1386,7 +1407,6 @@ CONFIG_USB_STORAGE=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
@@ -1398,7 +1418,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1423,11 +1442,11 @@ CONFIG_LEDS_GPIO_OF=y
CONFIG_LEDS_PCA955X=y
# CONFIG_LEDS_BD2802 is not set
# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
#
# LED Triggers
#
-CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
@@ -1506,6 +1525,7 @@ CONFIG_RTC_DRV_CMOS=y
#
# CONFIG_RTC_DRV_GENERIC is not set
CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
@@ -1614,6 +1634,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1641,6 +1662,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
@@ -1851,6 +1873,7 @@ 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 is not set
diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
index 622d84f48ab..183c59c6d89 100644
--- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
+++ b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:43 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:07 2010
#
# CONFIG_PPC64 is not set
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ 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
@@ -325,6 +321,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -340,13 +337,11 @@ CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
CONFIG_PCMCIA=y
# CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_IOCTL is not set
# CONFIG_CARDBUS is not set
#
@@ -382,7 +377,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -592,6 +586,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -629,6 +625,7 @@ CONFIG_MISC_DEVICES=y
# 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=y
# CONFIG_C2PORT is not set
@@ -695,6 +692,7 @@ CONFIG_IDE_PROC_FS=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -819,6 +817,7 @@ CONFIG_SATA_SIL=y
# 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
@@ -1059,6 +1058,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1116,6 +1116,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1129,15 +1130,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1152,14 +1147,18 @@ CONFIG_GPIO_SYSFS=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1192,10 +1191,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1233,6 +1233,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1281,19 +1282,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1302,6 +1308,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1334,6 +1341,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1349,14 +1357,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1463,7 +1476,6 @@ CONFIG_USB_STORAGE=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
@@ -1476,7 +1488,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1560,43 +1571,35 @@ CONFIG_RTC_DRV_RX8581=y
CONFIG_STAGING=y
# CONFIG_STAGING_EXCLUDE_BUILD is not set
# CONFIG_ET131X is not set
-# CONFIG_ME4000 is not set
-# CONFIG_MEILHAUS is not set
# CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
# CONFIG_ECHO is not set
# CONFIG_COMEDI is not set
# CONFIG_ASUS_OLED is not set
-# CONFIG_ALTERA_PCIE_CHDMA is not set
-# CONFIG_INPUT_MIMIO is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTL8192E is not set
# CONFIG_TRANZPORT is not set
#
-# Android
-#
-# CONFIG_ANDROID is not set
-# CONFIG_DST is not set
-# CONFIG_POHMELFS is not set
-# CONFIG_B3DFG is not set
-# CONFIG_IDE_PHISON is not set
-# CONFIG_PLAN9AUTH is not set
-# CONFIG_HECI is not set
-# CONFIG_USB_CPC is not set
-
-#
# Qualcomm MSM Camera And Video
#
#
# Camera Sensor Selection
#
-# CONFIG_HYPERV_STORAGE is not set
-# CONFIG_HYPERV_BLOCK is not set
-# CONFIG_HYPERV_NET is not set
+# CONFIG_INPUT_GPIO is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_IDE_PHISON is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VT6656 is not set
CONFIG_VME_BUS=y
#
# VME Bridge Drivers
#
+# CONFIG_VME_CA91CX42 is not set
CONFIG_VME_TSI148=y
#
@@ -1605,6 +1608,24 @@ CONFIG_VME_TSI148=y
# CONFIG_VME_USER is not set
#
+# VME Board Drivers
+#
+# CONFIG_VMIVME_7805 is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1693,6 +1714,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1719,6 +1741,7 @@ 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=m
# CONFIG_CIFS_STATS is not set
# CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1864,6 +1887,7 @@ 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=m
diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
index eb58dec11a6..1524d948a2b 100644
--- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:41 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:05 2010
#
# CONFIG_PPC64 is not set
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ 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
@@ -325,6 +321,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -340,13 +337,11 @@ CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
CONFIG_PCMCIA=y
# CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_IOCTL is not set
# CONFIG_CARDBUS is not set
#
@@ -382,7 +377,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -592,6 +586,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -629,6 +625,7 @@ CONFIG_MISC_DEVICES=y
# 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=y
# CONFIG_C2PORT is not set
@@ -695,6 +692,7 @@ CONFIG_IDE_PROC_FS=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -1001,6 +999,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1058,6 +1057,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1071,15 +1071,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1094,14 +1088,18 @@ CONFIG_GPIO_SYSFS=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1134,10 +1132,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1175,6 +1174,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1223,19 +1223,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1244,6 +1249,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1276,6 +1282,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1291,14 +1298,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1405,7 +1417,6 @@ CONFIG_USB_STORAGE=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
@@ -1418,7 +1429,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1590,6 +1600,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1616,6 +1627,7 @@ 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=m
# CONFIG_CIFS_STATS is not set
# CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1761,6 +1773,7 @@ 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=m
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
index 62c2b81a4a8..767c204c060 100644
--- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:42 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:06 2010
#
# CONFIG_PPC64 is not set
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ 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
@@ -326,6 +322,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -341,7 +338,6 @@ CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
CONFIG_PCI_DEBUG=y
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
@@ -369,7 +365,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -552,6 +547,7 @@ CONFIG_ATM_BR2684=m
# CONFIG_ATM_BR2684_IPFILTER is not set
CONFIG_STP=m
CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
# CONFIG_NET_DSA is not set
CONFIG_VLAN_8021Q=m
# CONFIG_VLAN_8021Q_GVRP is not set
@@ -728,6 +724,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -765,6 +763,7 @@ CONFIG_MISC_DEVICES=y
# 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=y
# CONFIG_C2PORT is not set
@@ -782,6 +781,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
@@ -905,6 +905,7 @@ CONFIG_SATA_SIL=y
# 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
@@ -1155,6 +1156,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1204,6 +1206,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1217,15 +1220,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1241,14 +1238,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1281,10 +1282,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1322,6 +1324,7 @@ CONFIG_SENSORS_LM92=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1370,19 +1373,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1391,6 +1399,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1423,6 +1432,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1438,14 +1448,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1552,7 +1567,6 @@ CONFIG_USB_STORAGE=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
@@ -1565,7 +1579,6 @@ CONFIG_USB_STORAGE=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_ATM is not set
# CONFIG_USB_GADGET is not set
@@ -1650,29 +1663,29 @@ CONFIG_RTC_DRV_RX8581=y
CONFIG_STAGING=y
# CONFIG_STAGING_EXCLUDE_BUILD is not set
# CONFIG_ET131X is not set
-# CONFIG_ME4000 is not set
-# CONFIG_MEILHAUS is not set
# CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
# CONFIG_ECHO is not set
# CONFIG_COMEDI is not set
# CONFIG_ASUS_OLED is not set
-# CONFIG_ALTERA_PCIE_CHDMA is not set
-# CONFIG_INPUT_MIMIO is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTL8192E is not set
# CONFIG_TRANZPORT is not set
#
-# Android
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
#
-# CONFIG_ANDROID is not set
-# CONFIG_DST is not set
+# CONFIG_INPUT_GPIO is not set
# CONFIG_POHMELFS is not set
-# CONFIG_B3DFG is not set
# CONFIG_IDE_PHISON is not set
-# CONFIG_PLAN9AUTH is not set
-# CONFIG_HECI is not set
# CONFIG_VT6655 is not set
-# CONFIG_USB_CPC is not set
-# CONFIG_RDC_17F3101X is not set
+# CONFIG_VT6656 is not set
CONFIG_VME_BUS=y
#
@@ -1687,6 +1700,22 @@ CONFIG_VME_TSI148=y
# CONFIG_VME_USER is not set
#
+# VME Board Drivers
+#
+# CONFIG_VMIVME_7805 is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1772,6 +1801,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1798,6 +1828,7 @@ 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=m
# CONFIG_CIFS_STATS is not set
# CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1870,7 +1901,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_DEFLATE=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
@@ -2006,6 +2037,7 @@ CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=m
diff --git a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
index aab3baebab8..55b9e4e867a 100644
--- a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
+++ b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:39 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:03 2010
#
# CONFIG_PPC64 is not set
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -112,6 +107,7 @@ 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
@@ -320,6 +316,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -335,7 +332,6 @@ CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
CONFIG_PCI_DEBUG=y
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
@@ -362,7 +358,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -571,6 +566,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
# CONFIG_PARPORT is not set
@@ -605,6 +602,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -670,6 +668,7 @@ CONFIG_IDE_PROC_FS=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -792,6 +791,7 @@ CONFIG_PATA_ALI=y
# 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
@@ -970,6 +970,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1017,6 +1018,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1029,15 +1031,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1062,18 +1058,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1082,6 +1081,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1434,6 +1434,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1461,6 +1462,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
diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
index 727a8c8d15b..1be38eb0578 100644
--- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
+++ b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:40 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:04 2010
#
# CONFIG_PPC64 is not set
@@ -97,15 +97,11 @@ CONFIG_TREE_RCU=y
# 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=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +112,7 @@ 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
@@ -326,6 +323,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -337,7 +335,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -365,7 +362,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -498,6 +494,8 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -534,6 +532,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -551,6 +550,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
@@ -675,6 +675,7 @@ CONFIG_PATA_ALI=y
# 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
@@ -799,6 +800,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
@@ -811,6 +814,7 @@ 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
@@ -920,6 +924,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -968,6 +973,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -981,15 +987,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1014,18 +1014,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1034,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1151,6 +1155,7 @@ CONFIG_SND_INTEL8X0=y
CONFIG_SND_PPC=y
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
# CONFIG_SND_USB_USX2Y is not set
# CONFIG_SND_USB_CAIAQ is not set
# CONFIG_SND_SOC is not set
@@ -1170,6 +1175,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1185,14 +1191,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1300,7 +1311,6 @@ CONFIG_USB_STORAGE=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
@@ -1313,7 +1323,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1475,6 +1484,7 @@ CONFIG_BEFS_FS=m
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
CONFIG_VXFS_FS=m
@@ -1506,6 +1516,7 @@ 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
@@ -1717,6 +1728,7 @@ 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 is not set
diff --git a/arch/powerpc/configs/86xx/sbc8641d_defconfig b/arch/powerpc/configs/86xx/sbc8641d_defconfig
index 4fb04dd2cde..a6300945732 100644
--- a/arch/powerpc/configs/86xx/sbc8641d_defconfig
+++ b/arch/powerpc/configs/86xx/sbc8641d_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:38 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:02 2010
#
# CONFIG_PPC64 is not set
@@ -101,11 +101,6 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +111,7 @@ 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
@@ -327,6 +323,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -342,7 +339,6 @@ CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -369,7 +365,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -552,6 +547,7 @@ CONFIG_ATM_BR2684=m
# CONFIG_ATM_BR2684_IPFILTER is not set
CONFIG_STP=m
CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
# CONFIG_NET_DSA is not set
CONFIG_VLAN_8021Q=m
# CONFIG_VLAN_8021Q_GVRP is not set
@@ -733,6 +729,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -768,6 +766,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -785,6 +784,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -1024,6 +1024,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1074,6 +1075,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1086,15 +1088,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1120,10 +1116,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1160,6 +1157,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1202,18 +1200,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1222,6 +1223,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1376,6 +1378,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1408,6 +1411,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
CONFIG_SMB_FS=m
CONFIG_SMB_NLS_DEFAULT=y
CONFIG_SMB_NLS_REMOTE="cp437"
+# CONFIG_CEPH_FS is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
# CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1540,6 +1544,7 @@ CONFIG_DEBUG_INFO=y
# 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=y
@@ -1618,6 +1623,7 @@ CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=m
diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig
index 5c1dc768bbd..9f89d5c9c0b 100644
--- a/arch/powerpc/configs/adder875_defconfig
+++ b/arch/powerpc/configs/adder875_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:23:58 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:22 2010
#
# CONFIG_PPC64 is not set
@@ -91,11 +91,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -307,6 +302,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_FSL_SOC=y
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
@@ -336,7 +332,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -505,6 +500,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -516,6 +513,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -664,6 +662,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -802,6 +801,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -826,6 +826,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
@@ -924,6 +925,7 @@ CONFIG_DEBUG_INFO=y
# 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
diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig
index 72137cd881d..4ab6074db3c 100644
--- a/arch/powerpc/configs/c2k_defconfig
+++ b/arch/powerpc/configs/c2k_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:23:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:23 2010
#
# CONFIG_PPC64 is not set
@@ -101,11 +101,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -121,6 +116,7 @@ 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
@@ -147,7 +143,6 @@ CONFIG_HAVE_PERF_EVENTS=y
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
# CONFIG_PERF_COUNTERS is not set
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
@@ -158,7 +153,6 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
CONFIG_OPROFILE=m
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
@@ -357,6 +351,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_PCI=y
@@ -365,7 +360,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
@@ -396,7 +390,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -527,6 +520,7 @@ CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
+# CONFIG_IP_VS_PROTO_SCTP is not set
#
# IPVS scheduler
@@ -630,6 +624,7 @@ CONFIG_ATM_BR2684=m
# CONFIG_ATM_BR2684_IPFILTER is not set
CONFIG_STP=m
CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
# CONFIG_NET_DSA is not set
CONFIG_VLAN_8021Q=m
# CONFIG_VLAN_8021Q_GVRP is not set
@@ -690,7 +685,6 @@ CONFIG_NET_SCH_FIFO=y
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
@@ -833,6 +827,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=m
CONFIG_OF_MDIO=y
@@ -867,6 +863,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=m
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=m
CONFIG_SCSI_DMA=y
@@ -1179,6 +1176,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
CONFIG_SERIAL_CORE=y
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_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1231,6 +1229,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MV64XXX=m
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1244,15 +1243,9 @@ CONFIG_I2C_MV64XXX=m
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1278,10 +1271,11 @@ CONFIG_SENSORS_ADM1026=m
# CONFIG_SENSORS_ADM1029 is not set
CONFIG_SENSORS_ADM1031=m
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
CONFIG_SENSORS_DS1621=m
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1318,6 +1312,7 @@ CONFIG_SENSORS_SMSC47M1=m
# CONFIG_SENSORS_SMSC47M192 is not set
CONFIG_SENSORS_SMSC47B397=m
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1369,9 +1364,9 @@ CONFIG_SSB_POSSIBLE=y
# 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_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
@@ -1380,6 +1375,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1413,7 +1409,6 @@ CONFIG_USB=m
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
# CONFIG_USB_OTG is not set
CONFIG_USB_MON=m
# CONFIG_USB_WUSB is not set
@@ -1535,6 +1530,7 @@ CONFIG_USB_SERIAL_MCT_U232=m
# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
# 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
@@ -1549,6 +1545,7 @@ CONFIG_USB_SERIAL_XIRCOM=m
# CONFIG_USB_SERIAL_OPTION is not set
CONFIG_USB_SERIAL_OMNINET=m
# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
# CONFIG_USB_SERIAL_DEBUG is not set
#
@@ -1561,7 +1558,6 @@ CONFIG_USB_EMI62=m
CONFIG_USB_RIO500=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
-# CONFIG_USB_BERRY_CHARGE is not set
CONFIG_USB_LED=m
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1574,7 +1570,6 @@ CONFIG_USB_LED=m
# CONFIG_USB_IOWARRIOR is not set
CONFIG_USB_TEST=m
# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
CONFIG_USB_ATM=m
CONFIG_USB_SPEEDTOUCH=m
# CONFIG_USB_CXACRU is not set
@@ -1611,6 +1606,7 @@ CONFIG_INFINIBAND_SRP=m
# CONFIG_EDAC is not set
# CONFIG_RTC_CLASS is not set
CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
@@ -1714,6 +1710,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=m
# CONFIG_SQUASHFS is not set
CONFIG_VXFS_FS=m
@@ -1742,6 +1739,7 @@ CONFIG_SUNRPC_XPRT_RDMA=m
CONFIG_RPCSEC_GSS_KRB5=y
CONFIG_RPCSEC_GSS_SPKM3=m
# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
# CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1817,7 +1815,7 @@ CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
# CONFIG_DLM is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
@@ -1833,9 +1831,11 @@ CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=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
@@ -1880,7 +1880,6 @@ CONFIG_DEBUG_SPINLOCK=y
# 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=y
CONFIG_DEBUG_BUGVERBOSE=y
@@ -1903,16 +1902,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_LATENCYTOP is not set
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_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
diff --git a/arch/powerpc/configs/ep8248e_defconfig b/arch/powerpc/configs/ep8248e_defconfig
index 79105413884..81e904e9f39 100644
--- a/arch/powerpc/configs/ep8248e_defconfig
+++ b/arch/powerpc/configs/ep8248e_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:23:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:24 2010
#
# CONFIG_PPC64 is not set
@@ -298,6 +298,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_PPC_PCI_CHOICE=y
@@ -308,7 +309,6 @@ CONFIG_PCI_8260=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -335,7 +335,6 @@ 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
@@ -537,6 +536,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_MDIO=y
@@ -566,6 +567,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -671,6 +673,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
@@ -683,6 +687,7 @@ 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
@@ -737,6 +742,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -765,7 +771,9 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
#
# I2C GPIO expanders:
@@ -804,6 +812,8 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -812,6 +822,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -869,6 +880,7 @@ CONFIG_AUTOFS4_FS=y
#
# Caches
#
+# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig
index 58f7ca71a59..c5af46ef5f4 100644
--- a/arch/powerpc/configs/ep88xc_defconfig
+++ b/arch/powerpc/configs/ep88xc_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:00 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:24 2010
#
# CONFIG_PPC64 is not set
@@ -90,11 +90,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -306,6 +301,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_FSL_SOC=y
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
@@ -335,7 +331,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -504,6 +499,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -515,6 +512,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -616,6 +614,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -753,6 +752,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -777,6 +777,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
diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
index 9a0c981277e..588a2add393 100644
--- a/arch/powerpc/configs/linkstation_defconfig
+++ b/arch/powerpc/configs/linkstation_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:01 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:25 2010
#
# CONFIG_PPC64 is not set
@@ -96,11 +96,6 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +111,7 @@ 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
@@ -328,6 +324,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -337,7 +334,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -364,7 +360,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
@@ -433,6 +428,7 @@ CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NETFILTER_XTABLES=m
# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
CONFIG_NETFILTER_XT_TARGET_HL=m
# CONFIG_NETFILTER_XT_TARGET_MARK is not set
@@ -665,6 +661,8 @@ CONFIG_MTD_PHYSMAP=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
# CONFIG_PARPORT is not set
@@ -700,6 +698,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -717,6 +716,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
@@ -840,6 +840,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_IT821X=y
# 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
@@ -954,6 +955,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
@@ -966,6 +969,7 @@ 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
@@ -1082,6 +1086,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1131,6 +1136,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1144,15 +1150,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1178,10 +1178,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1218,6 +1219,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1246,18 +1248,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1266,6 +1271,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1417,6 +1423,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=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
@@ -1430,6 +1437,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=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_DEBUG is not set
#
@@ -1442,7 +1450,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=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
@@ -1455,7 +1462,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=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
#
@@ -1620,6 +1626,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1651,6 +1658,7 @@ 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=m
# CONFIG_CIFS_STATS is not set
# CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1723,9 +1731,11 @@ CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_DECOMPRESS=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_HAS_IOMEM=y
diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig
index 4c2c877f936..0cbd56fe2e1 100644
--- a/arch/powerpc/configs/mgcoge_defconfig
+++ b/arch/powerpc/configs/mgcoge_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:02 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:26 2010
#
# CONFIG_PPC64 is not set
@@ -105,6 +105,7 @@ 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
@@ -311,6 +312,7 @@ CONFIG_ISA_DMA_API=y
#
# CONFIG_ISA is not set
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_PPC_PCI_CHOICE=y
@@ -321,7 +323,6 @@ CONFIG_PCI_8260=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -348,7 +349,6 @@ 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
@@ -536,6 +536,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -570,6 +572,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -704,6 +707,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -769,14 +773,9 @@ CONFIG_I2C_CPM=y
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
# 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
#
@@ -790,14 +789,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -829,19 +832,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -850,6 +858,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -908,6 +917,7 @@ CONFIG_AUTOFS4_FS=y
#
# Caches
#
+# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
@@ -1100,6 +1110,7 @@ CONFIG_DEBUG_INFO=y
# 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=y
diff --git a/arch/powerpc/configs/mgsuvd_defconfig b/arch/powerpc/configs/mgsuvd_defconfig
index 9e090f2c7e3..c1be2615102 100644
--- a/arch/powerpc/configs/mgsuvd_defconfig
+++ b/arch/powerpc/configs/mgsuvd_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:03 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:27 2010
#
# CONFIG_PPC64 is not set
@@ -89,11 +89,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -104,6 +99,7 @@ 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
@@ -309,6 +305,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_FSL_SOC=y
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
@@ -337,7 +334,6 @@ 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
@@ -515,6 +511,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -542,6 +540,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -643,6 +642,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -801,6 +801,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
@@ -825,6 +826,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
@@ -892,6 +894,7 @@ CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_KERNEL is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
CONFIG_HAVE_FUNCTION_TRACER=y
diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig
index 61cf73d0000..7012ac0134f 100644
--- a/arch/powerpc/configs/mpc5200_defconfig
+++ b/arch/powerpc/configs/mpc5200_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 15:08:52 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:38:54 2010
#
# CONFIG_PPC64 is not set
@@ -96,30 +96,37 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
# 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_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_NET_NS 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_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
-CONFIG_EMBEDDED=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
+# 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 is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -141,6 +148,7 @@ CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
@@ -320,6 +328,7 @@ CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_HIBERNATION is not set
# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y
@@ -336,7 +345,6 @@ 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_PCI_IOV is not set
@@ -363,7 +371,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -454,7 +461,9 @@ 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_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
@@ -554,6 +563,8 @@ CONFIG_MTD_UBI_BEB_RESERVE=1
# UBI debugging options
#
# CONFIG_MTD_UBI_DEBUG is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -732,6 +743,7 @@ CONFIG_ATA_SFF=y
# 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_MPC52xx=y
@@ -770,7 +782,7 @@ CONFIG_PATA_PLATFORM=y
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -929,6 +941,7 @@ CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -981,6 +994,7 @@ CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1010,9 +1024,9 @@ CONFIG_SPI_MASTER=y
#
# SPI Master Controller Drivers
#
-# CONFIG_SPI_BITBANG is not set
-# CONFIG_SPI_GPIO is not set
-# CONFIG_SPI_MPC52xx is not set
+CONFIG_SPI_BITBANG=m
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_MPC52xx=m
CONFIG_SPI_MPC52xx_PSC=m
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -1036,14 +1050,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1080,10 +1098,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1123,6 +1142,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1147,6 +1167,7 @@ CONFIG_WATCHDOG=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
# CONFIG_ALIM7101_WDT is not set
# CONFIG_MPC5200_WDT is not set
# CONFIG_WATCHDOG_RTAS is not set
@@ -1172,22 +1193,27 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1196,6 +1222,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
@@ -1309,32 +1336,46 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
-# CONFIG_HID_APPLE is not set
+CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
-# CONFIG_HID_CHICONY is not set
+CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
-# CONFIG_HID_DRAGONRISE is not set
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
-# 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_MONTEREY is not set
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
+CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SONY 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_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1349,10 +1390,7 @@ CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND 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=y
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set
@@ -1433,7 +1471,6 @@ CONFIG_USB_STORAGE=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
@@ -1445,7 +1482,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1636,6 +1672,7 @@ CONFIG_UBIFS_FS=m
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1730,8 +1767,11 @@ CONFIG_CRC32=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+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
@@ -1776,11 +1816,11 @@ CONFIG_SCHED_DEBUG=y
# 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_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_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig
index 1315b775a6d..27c63ceeb45 100644
--- a/arch/powerpc/configs/mpc7448_hpc2_defconfig
+++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:04 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:28 2010
#
# CONFIG_PPC64 is not set
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ 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
@@ -311,6 +307,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
# CONFIG_PPC_INDIRECT_PCI is not set
CONFIG_PCI=y
@@ -319,7 +316,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -345,7 +341,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -440,6 +435,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -484,6 +481,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
@@ -605,6 +603,7 @@ CONFIG_SATA_MV=y
# 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
@@ -696,6 +695,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -750,6 +750,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
@@ -762,6 +764,7 @@ 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
@@ -846,6 +849,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -910,6 +914,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -918,6 +923,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1044,6 +1050,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -1066,6 +1073,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
diff --git a/arch/powerpc/configs/mpc8272_ads_defconfig b/arch/powerpc/configs/mpc8272_ads_defconfig
index 9073778d357..6875fb89377 100644
--- a/arch/powerpc/configs/mpc8272_ads_defconfig
+++ b/arch/powerpc/configs/mpc8272_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:05 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:29 2010
#
# CONFIG_PPC64 is not set
@@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
@@ -301,6 +300,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_PPC_PCI_CHOICE=y
@@ -311,7 +311,6 @@ CONFIG_PCI_8260=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -338,7 +337,6 @@ 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
@@ -540,6 +538,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_MDIO=y
@@ -569,6 +569,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -674,6 +675,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
@@ -686,6 +689,7 @@ 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
@@ -797,6 +801,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -825,7 +830,9 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
#
# I2C GPIO expanders:
@@ -864,6 +871,8 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -872,6 +881,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -933,6 +943,7 @@ CONFIG_AUTOFS4_FS=y
#
# Caches
#
+# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig
index 05bec483568..bbe5ae61d97 100644
--- a/arch/powerpc/configs/mpc83xx_defconfig
+++ b/arch/powerpc/configs/mpc83xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:30 2010
#
# CONFIG_PPC64 is not set
@@ -98,14 +98,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +107,7 @@ 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
@@ -126,7 +121,7 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
@@ -331,6 +326,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -344,7 +340,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -370,7 +365,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
@@ -560,6 +554,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -597,6 +593,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -614,6 +611,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
@@ -712,7 +710,7 @@ CONFIG_ATA_SFF=y
# 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_SIL=y
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
@@ -737,6 +735,7 @@ CONFIG_ATA_SFF=y
# 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
@@ -863,6 +862,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
@@ -875,6 +876,7 @@ 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
@@ -970,6 +972,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
# CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -980,8 +983,6 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_NVRAM is not set
-CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -1022,6 +1023,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1035,15 +1037,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1058,14 +1054,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1098,10 +1098,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1139,6 +1140,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1186,19 +1188,24 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1207,6 +1214,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1232,6 +1240,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1247,14 +1256,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1344,7 +1358,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
@@ -1357,7 +1370,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
#
@@ -1372,7 +1384,65 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS 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=y
+CONFIG_RTC_DRV_DS1374=y
+# 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_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_RTC_DRV_GENERIC is not set
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
@@ -1453,6 +1523,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1479,6 +1550,7 @@ 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
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index 8f35f8049c9..cfebef9f912 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:31 2010
#
# CONFIG_PPC64 is not set
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -103,14 +107,8 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -118,6 +116,7 @@ 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
@@ -334,6 +333,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -345,7 +345,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
@@ -376,7 +375,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -509,6 +507,8 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -546,6 +546,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -563,6 +564,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
@@ -687,6 +689,7 @@ CONFIG_PATA_ALI=y
# 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
@@ -817,8 +820,11 @@ 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
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_VXGE is not set
@@ -829,6 +835,7 @@ 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
@@ -941,6 +948,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -993,6 +1001,7 @@ CONFIG_I2C_CPM=m
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1006,15 +1015,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1030,14 +1033,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1069,20 +1076,25 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_UCB1400_CORE is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1091,6 +1103,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1208,6 +1221,7 @@ CONFIG_SND_INTEL8X0=y
CONFIG_SND_PPC=y
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
# CONFIG_SND_USB_USX2Y is not set
# CONFIG_SND_USB_CAIAQ is not set
# CONFIG_SND_SOC is not set
@@ -1227,6 +1241,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1242,14 +1257,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1358,7 +1378,6 @@ CONFIG_USB_STORAGE=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
@@ -1371,7 +1390,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1452,6 +1470,7 @@ CONFIG_RTC_DRV_CMOS=y
#
# CONFIG_RTC_DRV_GENERIC is not set
CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
@@ -1554,6 +1573,7 @@ CONFIG_BEFS_FS=m
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
CONFIG_VXFS_FS=m
@@ -1585,6 +1605,7 @@ 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
@@ -1730,6 +1751,7 @@ CONFIG_DEBUG_INFO=y
# 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=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index 8755ea3c7f5..f5451d80f19 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:07 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:31 2010
#
# CONFIG_PPC64 is not set
@@ -69,6 +69,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -100,18 +104,13 @@ CONFIG_TREE_RCU=y
# 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=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -119,6 +118,7 @@ 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
@@ -338,6 +338,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -349,7 +350,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
@@ -380,7 +380,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -513,6 +512,8 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -550,6 +551,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -567,6 +569,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
@@ -691,6 +694,7 @@ CONFIG_PATA_ALI=y
# 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
@@ -821,8 +825,11 @@ 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
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_VXGE is not set
@@ -833,6 +840,7 @@ 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
@@ -945,6 +953,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -997,6 +1006,7 @@ CONFIG_I2C_CPM=m
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1010,15 +1020,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1034,14 +1038,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1073,20 +1081,25 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_UCB1400_CORE is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1095,6 +1108,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1212,6 +1226,7 @@ CONFIG_SND_INTEL8X0=y
CONFIG_SND_PPC=y
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
# CONFIG_SND_USB_USX2Y is not set
# CONFIG_SND_USB_CAIAQ is not set
# CONFIG_SND_SOC is not set
@@ -1231,6 +1246,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1246,14 +1262,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1362,7 +1383,6 @@ CONFIG_USB_STORAGE=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
@@ -1375,7 +1395,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1456,6 +1475,7 @@ CONFIG_RTC_DRV_CMOS=y
#
# CONFIG_RTC_DRV_GENERIC is not set
CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
@@ -1558,6 +1578,7 @@ CONFIG_BEFS_FS=m
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
CONFIG_VXFS_FS=m
@@ -1589,6 +1610,7 @@ 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
@@ -1734,6 +1756,7 @@ CONFIG_DEBUG_INFO=y
# 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=y
@@ -1806,6 +1829,7 @@ 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
diff --git a/arch/powerpc/configs/mpc866_ads_defconfig b/arch/powerpc/configs/mpc866_ads_defconfig
index 3f6b11b6f4f..d8d3d1d60c8 100644
--- a/arch/powerpc/configs/mpc866_ads_defconfig
+++ b/arch/powerpc/configs/mpc866_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:08 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:32 2010
#
# CONFIG_PPC64 is not set
@@ -89,14 +89,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
@@ -305,6 +299,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_FSL_SOC=y
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
@@ -333,7 +328,6 @@ 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
@@ -425,6 +419,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -456,6 +452,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -607,6 +604,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -795,6 +793,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -819,6 +818,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
diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig
index 41884c97a4f..624eae9a7e2 100644
--- a/arch/powerpc/configs/mpc86xx_defconfig
+++ b/arch/powerpc/configs/mpc86xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:09 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:33 2010
#
# CONFIG_PPC64 is not set
@@ -98,18 +98,13 @@ CONFIG_TREE_RCU=y
# 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=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
@@ -117,6 +112,7 @@ 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
@@ -328,6 +324,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -339,7 +336,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -367,7 +363,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -500,6 +495,8 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
@@ -537,6 +534,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -554,6 +552,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
@@ -678,6 +677,7 @@ CONFIG_PATA_ALI=y
# 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
@@ -802,6 +802,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
@@ -814,6 +816,7 @@ 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
@@ -923,6 +926,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -972,6 +976,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -985,15 +990,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1009,14 +1008,18 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH 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:
@@ -1048,20 +1051,25 @@ CONFIG_SSB_POSSIBLE=y
# 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_HTC_I2CPLD is not set
# CONFIG_UCB1400_CORE is not set
# CONFIG_TPS65010 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_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1070,6 +1078,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1187,6 +1196,7 @@ CONFIG_SND_INTEL8X0=y
CONFIG_SND_PPC=y
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
# CONFIG_SND_USB_USX2Y is not set
# CONFIG_SND_USB_CAIAQ is not set
# CONFIG_SND_SOC is not set
@@ -1206,6 +1216,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1221,14 +1232,19 @@ CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1336,7 +1352,6 @@ CONFIG_USB_STORAGE=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
@@ -1349,7 +1364,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1512,6 +1526,7 @@ CONFIG_BEFS_FS=m
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
CONFIG_VXFS_FS=m
@@ -1543,6 +1558,7 @@ 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
@@ -1754,6 +1770,7 @@ 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 is not set
diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig
index 6b9e6bd2c98..45bd499630d 100644
--- a/arch/powerpc/configs/mpc885_ads_defconfig
+++ b/arch/powerpc/configs/mpc885_ads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:10 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:34 2010
#
# CONFIG_PPC64 is not set
@@ -90,14 +90,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
@@ -313,6 +307,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_FSL_SOC=y
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
@@ -342,7 +337,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -515,6 +509,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
@@ -526,6 +522,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -627,6 +624,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -764,6 +762,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -788,6 +787,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
diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig
index 5d06f2cb8e5..68c175ea427 100644
--- a/arch/powerpc/configs/pq2fads_defconfig
+++ b/arch/powerpc/configs/pq2fads_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:11 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:35 2010
#
# CONFIG_PPC64 is not set
@@ -105,6 +105,7 @@ 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
@@ -304,6 +305,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
CONFIG_PPC_PCI_CHOICE=y
@@ -315,7 +317,6 @@ CONFIG_PCI_8260=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_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
@@ -342,7 +343,6 @@ 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
@@ -544,6 +544,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_GPIO=y
CONFIG_OF_MDIO=y
@@ -629,6 +631,7 @@ CONFIG_IDE_PROC_FS=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -734,6 +737,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
@@ -746,6 +751,7 @@ 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
@@ -859,6 +865,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -887,7 +894,9 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
+# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
#
# I2C GPIO expanders:
@@ -926,6 +935,8 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -934,6 +945,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -996,6 +1008,7 @@ CONFIG_USB_ETH_RNDIS=y
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
# CONFIG_USB_G_MULTI is not set
#
@@ -1051,6 +1064,7 @@ CONFIG_AUTOFS4_FS=y
#
# Caches
#
+# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig
index 57ab5748a34..93f4505b5ac 100644
--- a/arch/powerpc/configs/prpmc2800_defconfig
+++ b/arch/powerpc/configs/prpmc2800_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:12 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:36 2010
#
# CONFIG_PPC64 is not set
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -319,6 +315,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_PCI=y
@@ -327,7 +324,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -354,7 +350,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
@@ -533,6 +528,8 @@ CONFIG_MTD_PHYSMAP_OF=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
CONFIG_OF_MDIO=y
@@ -569,6 +566,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -640,6 +638,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -761,6 +760,7 @@ CONFIG_SATA_MV=y
# 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
@@ -854,6 +854,7 @@ CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_E100=y
@@ -907,6 +908,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
@@ -919,6 +922,7 @@ 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
@@ -1016,6 +1020,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
CONFIG_SERIAL_CORE=y
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_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1065,6 +1070,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MV64XXX=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -1077,15 +1083,9 @@ CONFIG_I2C_MV64XXX=y
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -1111,10 +1111,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1151,6 +1152,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
@@ -1179,18 +1181,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1199,6 +1204,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1231,6 +1237,7 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
@@ -1247,14 +1254,19 @@ CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=y
CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=y
CONFIG_HID_GREENASIA=y
# CONFIG_GREENASIA_FF is not set
@@ -1350,7 +1362,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=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
@@ -1363,7 +1374,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=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
#
@@ -1516,6 +1526,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_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
@@ -1538,6 +1549,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
@@ -1620,9 +1632,11 @@ 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/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index 32f7058bb17..3808bc2be86 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc7
-# Mon Aug 24 17:38:50 2009
+# Linux kernel version: 2.6.34-rc4
+# Thu Apr 15 11:32:15 2010
#
CONFIG_PPC64=y
@@ -9,6 +9,7 @@ CONFIG_PPC64=y
# Processor support
#
CONFIG_PPC_BOOK3S_64=y
+# CONFIG_PPC_BOOK3E_64 is not set
CONFIG_PPC_BOOK3S=y
# CONFIG_POWER4_ONLY is not set
CONFIG_POWER3=y
@@ -35,7 +36,9 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -60,6 +63,7 @@ CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
CONFIG_DTC=y
# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -86,14 +90,15 @@ CONFIG_POSIX_MQUEUE_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=64
+# 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=17
-# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
@@ -108,6 +113,7 @@ 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
@@ -128,21 +134,19 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
+# CONFIG_PERF_EVENTS is not set
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
-CONFIG_MARKERS=y
CONFIG_OPROFILE=m
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
@@ -154,12 +158,14 @@ CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -180,14 +186,41 @@ 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_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+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 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
#
@@ -226,7 +259,6 @@ CONFIG_PPC_CELL=y
#
CONFIG_SPU_FS=m
CONFIG_SPU_FS_64K_LS=y
-# CONFIG_SPU_TRACE is not set
CONFIG_SPU_BASE=y
# CONFIG_PQ2ADS is not set
# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
@@ -267,7 +299,6 @@ CONFIG_COMPAT_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=y
CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
-# CONFIG_IOMMU_VMERGE is not set
CONFIG_IOMMU_HELPER=y
# CONFIG_SWIOTLB is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -276,12 +307,15 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_SPARSE_IRQ=y
# CONFIG_NUMA is not set
+CONFIG_MAX_ACTIVE_REGIONS=256
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -295,13 +329,12 @@ CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTPLUG_SPARSE=y
# CONFIG_MEMORY_HOTREMOVE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
CONFIG_MIGRATION=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_MEMORY_PROBE=y
CONFIG_PPC_HAS_HASH_64K=y
@@ -312,11 +345,15 @@ CONFIG_PPC_4K_PAGES=y
CONFIG_FORCE_MAX_ZONEORDER=13
CONFIG_SCHED_SMT=y
CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
CONFIG_EXTRA_TARGETS=""
CONFIG_PM=y
CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
# CONFIG_PM_VERBOSE is not set
+# CONFIG_HIBERNATION is not set
+# CONFIG_PM_RUNTIME is not set
# CONFIG_SECCOMP is not set
CONFIG_ISA_DMA_API=y
@@ -324,6 +361,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_PCI_CHOICE=y
# CONFIG_PCI is not set
@@ -337,12 +375,12 @@ CONFIG_PAGE_OFFSET=0xc000000000000000
CONFIG_KERNEL_START=0xc000000000000000
CONFIG_PHYSICAL_START=0x00000000
CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
#
# Networking options
#
CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
@@ -392,6 +430,7 @@ 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
@@ -400,6 +439,7 @@ CONFIG_IPV6_NDISC_NODETYPE=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_BRIDGE is not set
@@ -422,7 +462,6 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
@@ -445,27 +484,30 @@ CONFIG_BT_HCIBTUSB=m
# CONFIG_BT_HCIBPA10X is not set
# CONFIG_BT_HCIBFUSB is not set
# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
# CONFIG_CFG80211_DEBUGFS is not set
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
# CONFIG_WIRELESS_EXT_SYSFS is not set
# CONFIG_LIB80211 is not set
CONFIG_MAC80211=m
-CONFIG_MAC80211_DEFAULT_PS=y
-CONFIG_MAC80211_DEFAULT_PS_VALUE=1
-
-#
-# Rate control algorithm selection
-#
CONFIG_MAC80211_RC_PID=y
# CONFIG_MAC80211_RC_MINSTREL is not set
CONFIG_MAC80211_RC_DEFAULT_PID=y
# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
# CONFIG_MAC80211_LEDS is not set
# CONFIG_MAC80211_DEBUGFS is not set
# CONFIG_MAC80211_DEBUG_MENU is not set
@@ -481,6 +523,7 @@ CONFIG_MAC80211_RC_DEFAULT="pid"
# 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
@@ -491,6 +534,8 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
@@ -498,6 +543,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_UB is not set
CONFIG_BLK_DEV_RAM=y
@@ -521,6 +570,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
@@ -590,30 +640,27 @@ CONFIG_MII=m
# 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_GELIC_NET=y
CONFIG_GELIC_WIRELESS=y
# CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-# CONFIG_LIBERTAS is not set
+CONFIG_WLAN=y
# CONFIG_LIBERTAS_THINFIRM is not set
# CONFIG_AT76C50X_USB is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_USB_NET_RNDIS_WLAN is not set
# CONFIG_RTL8187 is not set
# CONFIG_MAC80211_HWSIM is not set
-# CONFIG_P54_COMMON is not set
-# CONFIG_AR9170_USB is not set
-# CONFIG_HOSTAP is not set
+# CONFIG_ATH_COMMON is not set
# CONFIG_B43 is not set
# CONFIG_B43LEGACY is not set
-# CONFIG_ZD1211RW is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -631,6 +678,7 @@ CONFIG_USB_NET_AX8817X=m
# CONFIG_USB_NET_CDCETHER is not set
# CONFIG_USB_NET_CDC_EEM is not set
# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC75XX is not set
# CONFIG_USB_NET_SMSC95XX is not set
# CONFIG_USB_NET_GL620A is not set
# CONFIG_USB_NET_NET1080 is not set
@@ -665,6 +713,7 @@ CONFIG_SLHC=m
CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=m
# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
#
# Userland interfaces
@@ -712,6 +761,8 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
@@ -735,7 +786,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=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
@@ -841,13 +891,13 @@ CONFIG_SND_PS3=m
CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_UA101 is not set
# CONFIG_SND_USB_USX2Y is not set
# CONFIG_SND_USB_CAIAQ is not set
# CONFIG_SND_SOC is not set
# CONFIG_SOUND_PRIME is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
CONFIG_HIDRAW=y
#
@@ -866,6 +916,7 @@ CONFIG_USB_HIDDEV=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
# CONFIG_HID_A4TECH is not set
CONFIG_HID_APPLE=m
CONFIG_HID_BELKIN=m
@@ -876,17 +927,24 @@ CONFIG_HID_CHERRY=m
CONFIG_HID_EZKEY=m
# CONFIG_HID_KYE is not set
# CONFIG_HID_GYRATION is not set
+CONFIG_HID_TWINHAN=m
# 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_MAGICMOUSE is not set
CONFIG_HID_MICROSOFT=m
+# 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_QUANTA is not set
# CONFIG_HID_SAMSUNG is not set
CONFIG_HID_SONY=m
+# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=m
# CONFIG_HID_GREENASIA is not set
CONFIG_HID_SMARTJOYPLUS=m
@@ -901,7 +959,7 @@ 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
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
#
# Miscellaneous USB options
@@ -909,7 +967,6 @@ CONFIG_USB=m
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -923,12 +980,13 @@ CONFIG_USB_MON=m
# 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_EHCI_TT_NEWSCHED=y
CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
# CONFIG_USB_EHCI_HCD_PPC_OF 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_OHCI_HCD=m
# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -995,7 +1053,6 @@ CONFIG_USB_STORAGE=m
# 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
@@ -1008,7 +1065,6 @@ CONFIG_USB_STORAGE=m
# 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
#
@@ -1048,7 +1104,9 @@ CONFIG_RTC_INTF_DEV=y
# 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
#
@@ -1077,10 +1135,10 @@ CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_EXT4_FS=y
-# CONFIG_EXT4DEV_COMPAT is not set
CONFIG_EXT4_FS_XATTR=y
# CONFIG_EXT4_FS_POSIX_ACL is not set
# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD=m
# CONFIG_JBD_DEBUG is not set
CONFIG_JBD2=y
@@ -1093,6 +1151,7 @@ CONFIG_FS_MBCACHE=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=y
@@ -1154,6 +1213,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -1164,7 +1224,6 @@ CONFIG_MISC_FILESYSTEMS=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
@@ -1181,6 +1240,7 @@ 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=m
# CONFIG_CIFS_STATS is not set
# CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1237,7 +1297,7 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
# CONFIG_DLM is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
@@ -1270,6 +1330,7 @@ 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=y
# CONFIG_HEADERS_CHECK is not set
@@ -1292,6 +1353,7 @@ CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
+# CONFIG_PROVE_RCU is not set
CONFIG_LOCKDEP=y
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_LOCKDEP=y
@@ -1308,26 +1370,27 @@ CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_LIST=y
# 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_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
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_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
-CONFIG_TRACING=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1352,13 +1415,16 @@ CONFIG_IRQSTACKS=y
# 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=m
@@ -1374,6 +1440,7 @@ CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=m
# 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 is not set
@@ -1402,11 +1469,13 @@ CONFIG_CRYPTO_PCBC=m
#
# 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=m
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/powerpc/configs/storcenter_defconfig b/arch/powerpc/configs/storcenter_defconfig
index f2f83216146..b1625801526 100644
--- a/arch/powerpc/configs/storcenter_defconfig
+++ b/arch/powerpc/configs/storcenter_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan 6 09:24:13 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:37 2010
#
# CONFIG_PPC64 is not set
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -314,6 +309,7 @@ CONFIG_ISA_DMA_API=y
# Bus options
#
CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
CONFIG_GENERIC_ISA_DMA=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_FSL_SOC=y
@@ -323,7 +319,6 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
@@ -349,7 +344,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=m
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -524,6 +518,8 @@ CONFIG_MTD_PHYSMAP=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
CONFIG_OF_DEVICE=y
CONFIG_OF_I2C=y
# CONFIG_PARPORT is not set
@@ -555,6 +551,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -626,6 +623,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -846,6 +844,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -895,6 +894,7 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MPC=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -908,15 +908,9 @@ CONFIG_I2C_MPC=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -941,18 +935,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -961,6 +958,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1071,7 +1069,6 @@ CONFIG_USB_STORAGE=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
@@ -1084,7 +1081,6 @@ CONFIG_USB_STORAGE=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
#
@@ -1251,6 +1247,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 is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h
index c1b475a941e..a9b91ed3d4b 100644
--- a/arch/powerpc/include/asm/asm-compat.h
+++ b/arch/powerpc/include/asm/asm-compat.h
@@ -28,6 +28,7 @@
#define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh)
#define PPC_STLCX stringify_in_c(stdcx.)
#define PPC_CNTLZL stringify_in_c(cntlzd)
+#define PPC_LR_STKOFF 16
/* Move to CR, single-entry optimized version. Only available
* on POWER4 and later.
@@ -51,6 +52,7 @@
#define PPC_STLCX stringify_in_c(stwcx.)
#define PPC_CNTLZL stringify_in_c(cntlzw)
#define PPC_MTOCRF stringify_in_c(mtcrf)
+#define PPC_LR_STKOFF 4
#endif
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 4774c2f9223..396d21a8005 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -7,7 +7,8 @@
#include <linux/types.h>
#include <linux/sched.h>
-#define COMPAT_USER_HZ 100
+#define COMPAT_USER_HZ 100
+#define COMPAT_UTS_MACHINE "ppc\0\0"
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 80a973bb9e7..c85ef230135 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -127,9 +127,6 @@ static inline int dma_supported(struct device *dev, u64 mask)
return dma_ops->dma_supported(dev, mask);
}
-/* We have our own implementation of pci_set_dma_mask() */
-#define HAVE_ARCH_PCI_SET_DMA_MASK
-
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index af2abe74f54..aadf2dd6f84 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -97,4 +97,10 @@
#define RESUME_HOST RESUME_FLAG_HOST
#define RESUME_HOST_NV (RESUME_FLAG_HOST|RESUME_FLAG_NV)
+#define KVM_GUEST_MODE_NONE 0
+#define KVM_GUEST_MODE_GUEST 1
+#define KVM_GUEST_MODE_SKIP 2
+
+#define KVM_INST_FETCH_FAILED -1
+
#endif /* __POWERPC_KVM_ASM_H__ */
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index 74b7369770d..db7db0a9696 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -22,7 +22,7 @@
#include <linux/types.h>
#include <linux/kvm_host.h>
-#include <asm/kvm_ppc.h>
+#include <asm/kvm_book3s_64_asm.h>
struct kvmppc_slb {
u64 esid;
@@ -33,7 +33,8 @@ struct kvmppc_slb {
bool Ks;
bool Kp;
bool nx;
- bool large;
+ bool large; /* PTEs are 16MB */
+ bool tb; /* 1TB segment */
bool class;
};
@@ -69,6 +70,7 @@ struct kvmppc_sid_map {
struct kvmppc_vcpu_book3s {
struct kvm_vcpu vcpu;
+ struct kvmppc_book3s_shadow_vcpu shadow_vcpu;
struct kvmppc_sid_map sid_map[SID_MAP_NUM];
struct kvmppc_slb slb[64];
struct {
@@ -89,6 +91,7 @@ struct kvmppc_vcpu_book3s {
u64 vsid_next;
u64 vsid_max;
int context_id;
+ ulong prog_flags; /* flags to inject when giving a 700 trap */
};
#define CONTEXT_HOST 0
@@ -119,6 +122,10 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
extern u32 kvmppc_trampoline_lowmem;
extern u32 kvmppc_trampoline_enter;
+extern void kvmppc_rmcall(ulong srr0, ulong srr1);
+extern void kvmppc_load_up_fpu(void);
+extern void kvmppc_load_up_altivec(void);
+extern void kvmppc_load_up_vsx(void);
static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
{
diff --git a/arch/powerpc/include/asm/kvm_book3s_64_asm.h b/arch/powerpc/include/asm/kvm_book3s_64_asm.h
index 2e06ee8184e..183461b4840 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64_asm.h
@@ -20,6 +20,8 @@
#ifndef __ASM_KVM_BOOK3S_ASM_H__
#define __ASM_KVM_BOOK3S_ASM_H__
+#ifdef __ASSEMBLY__
+
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
#include <asm/kvm_asm.h>
@@ -55,4 +57,20 @@ kvmppc_resume_\intno:
#endif /* CONFIG_KVM_BOOK3S_64_HANDLER */
+#else /*__ASSEMBLY__ */
+
+struct kvmppc_book3s_shadow_vcpu {
+ ulong gpr[14];
+ u32 cr;
+ u32 xer;
+ ulong host_r1;
+ ulong host_r2;
+ ulong handler;
+ ulong scratch0;
+ ulong scratch1;
+ ulong vmhandler;
+};
+
+#endif /*__ASSEMBLY__ */
+
#endif /* __ASM_KVM_BOOK3S_ASM_H__ */
diff --git a/arch/powerpc/include/asm/kvm_e500.h b/arch/powerpc/include/asm/kvm_e500.h
index 9d497ce4972..7fea26fffb2 100644
--- a/arch/powerpc/include/asm/kvm_e500.h
+++ b/arch/powerpc/include/asm/kvm_e500.h
@@ -52,9 +52,12 @@ struct kvmppc_vcpu_e500 {
u32 mas5;
u32 mas6;
u32 mas7;
+ u32 l1csr0;
u32 l1csr1;
u32 hid0;
u32 hid1;
+ u32 tlb0cfg;
+ u32 tlb1cfg;
struct kvm_vcpu vcpu;
};
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 1201f62d0d7..5e5bae7e152 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -167,23 +167,40 @@ struct kvm_vcpu_arch {
ulong trampoline_lowmem;
ulong trampoline_enter;
ulong highmem_handler;
+ ulong rmcall;
ulong host_paca_phys;
struct kvmppc_mmu mmu;
#endif
- u64 fpr[32];
ulong gpr[32];
+ u64 fpr[32];
+ u32 fpscr;
+
+#ifdef CONFIG_ALTIVEC
+ vector128 vr[32];
+ vector128 vscr;
+#endif
+
+#ifdef CONFIG_VSX
+ u64 vsr[32];
+#endif
+
ulong pc;
- u32 cr;
ulong ctr;
ulong lr;
+
+#ifdef CONFIG_BOOKE
ulong xer;
+ u32 cr;
+#endif
ulong msr;
#ifdef CONFIG_PPC64
ulong shadow_msr;
+ ulong shadow_srr1;
ulong hflags;
+ ulong guest_owned_ext;
#endif
u32 mmucr;
ulong sprg0;
@@ -242,6 +259,8 @@ struct kvm_vcpu_arch {
#endif
ulong fault_dear;
ulong fault_esr;
+ ulong queued_dear;
+ ulong queued_esr;
gpa_t paddr_accessed;
u8 io_gpr; /* GPR used as IO source/target */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 269ee46ab02..e2642829e43 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -28,6 +28,9 @@
#include <linux/types.h>
#include <linux/kvm_types.h>
#include <linux/kvm_host.h>
+#ifdef CONFIG_PPC_BOOK3S
+#include <asm/kvm_book3s.h>
+#endif
enum emulation_result {
EMULATE_DONE, /* no further processing */
@@ -80,8 +83,9 @@ extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
extern void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu);
extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);
-extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu);
+extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags);
extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
+extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq);
@@ -95,4 +99,81 @@ extern void kvmppc_booke_exit(void);
extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu);
+#ifdef CONFIG_PPC_BOOK3S
+
+/* We assume we're always acting on the current vcpu */
+
+static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
+{
+ if ( num < 14 ) {
+ get_paca()->shadow_vcpu.gpr[num] = val;
+ to_book3s(vcpu)->shadow_vcpu.gpr[num] = val;
+ } else
+ vcpu->arch.gpr[num] = val;
+}
+
+static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num)
+{
+ if ( num < 14 )
+ return get_paca()->shadow_vcpu.gpr[num];
+ else
+ return vcpu->arch.gpr[num];
+}
+
+static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val)
+{
+ get_paca()->shadow_vcpu.cr = val;
+ to_book3s(vcpu)->shadow_vcpu.cr = val;
+}
+
+static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
+{
+ return get_paca()->shadow_vcpu.cr;
+}
+
+static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
+{
+ get_paca()->shadow_vcpu.xer = val;
+ to_book3s(vcpu)->shadow_vcpu.xer = val;
+}
+
+static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
+{
+ return get_paca()->shadow_vcpu.xer;
+}
+
+#else
+
+static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
+{
+ vcpu->arch.gpr[num] = val;
+}
+
+static inline ulong kvmppc_get_gpr(struct kvm_vcpu *vcpu, int num)
+{
+ return vcpu->arch.gpr[num];
+}
+
+static inline void kvmppc_set_cr(struct kvm_vcpu *vcpu, u32 val)
+{
+ vcpu->arch.cr = val;
+}
+
+static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.cr;
+}
+
+static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
+{
+ vcpu->arch.xer = val;
+}
+
+static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.xer;
+}
+
+#endif
+
#endif /* __POWERPC_KVM_PPC_H__ */
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 5e9b4ef7141..a011603d407 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -14,11 +14,17 @@
#define _ASM_POWERPC_PACA_H
#ifdef __KERNEL__
+#ifdef CONFIG_PPC64
+
+#include <linux/init.h>
#include <asm/types.h>
#include <asm/lppaca.h>
#include <asm/mmu.h>
#include <asm/page.h>
#include <asm/exception-64e.h>
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+#include <asm/kvm_book3s_64_asm.h>
+#endif
register struct paca_struct *local_paca asm("r13");
@@ -135,13 +141,26 @@ struct paca_struct {
u64 esid;
u64 vsid;
} kvm_slb[64]; /* guest SLB */
+ /* We use this to store guest state in */
+ struct kvmppc_book3s_shadow_vcpu shadow_vcpu;
u8 kvm_slb_max; /* highest used guest slb entry */
u8 kvm_in_guest; /* are we inside the guest? */
#endif
};
-extern struct paca_struct paca[];
-extern void initialise_pacas(void);
+extern struct paca_struct *paca;
+extern __initdata struct paca_struct boot_paca;
+extern void initialise_paca(struct paca_struct *new_paca, int cpu);
+
+extern void allocate_pacas(void);
+extern void free_unused_pacas(void);
+
+#else /* CONFIG_PPC64 */
+
+static inline void allocate_pacas(void) { };
+static inline void free_unused_pacas(void) { };
+
+#endif /* CONFIG_PPC64 */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PACA_H */
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index e96d52a516b..53b64be40eb 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -108,8 +108,21 @@ extern phys_addr_t kernstart_addr;
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - MEMORY_START))
+/*
+ * On Book-E parts we need __va to parse the device tree and we can't
+ * determine MEMORY_START until then. However we can determine PHYSICAL_START
+ * from information at hand (program counter, TLB lookup).
+ *
+ * On non-Book-E PPC64 PAGE_OFFSET and MEMORY_START are constants so use
+ * the other definitions for __va & __pa.
+ */
+#ifdef CONFIG_BOOKE
+#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + KERNELBASE))
+#define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE)
+#else
+#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START))
#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START)
+#endif
/*
* Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index b5ea626eea2..a20a9ad2258 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -141,38 +141,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
#define HAVE_PCI_LEGACY 1
-#if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE)
-/*
- * For 64-bit kernels, pci_unmap_{single,page} is not a nop.
- * For 32-bit non-coherent kernels, pci_dma_sync_single_for_cpu() and
- * so on are not nops.
- * and thus...
- */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
-#else /* 32-bit && coherent */
-
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME) (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-
-#endif /* CONFIG_PPC64 || CONFIG_NOT_COHERENT_CACHE */
-
#ifdef CONFIG_PPC64
/* The PCI address space does not equal the physical memory address
diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h
index 3288ce3997e..e6d4ce69b12 100644
--- a/arch/powerpc/include/asm/perf_event.h
+++ b/arch/powerpc/include/asm/perf_event.h
@@ -1,110 +1,23 @@
/*
- * Performance event support - PowerPC-specific definitions.
+ * Performance event support - hardware-specific disambiguation
*
- * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ * For now this is a compile-time decision, but eventually it should be
+ * runtime. This would allow multiplatform perf event support for e300 (fsl
+ * embedded perf counters) plus server/classic, and would accommodate
+ * devices other than the core which provide their own performance counters.
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/types.h>
-
-#include <asm/hw_irq.h>
-
-#define MAX_HWEVENTS 8
-#define MAX_EVENT_ALTERNATIVES 8
-#define MAX_LIMITED_HWCOUNTERS 2
-
-/*
- * This struct provides the constants and functions needed to
- * describe the PMU on a particular POWER-family CPU.
- */
-struct power_pmu {
- const char *name;
- int n_counter;
- int max_alternatives;
- unsigned long add_fields;
- unsigned long test_adder;
- int (*compute_mmcr)(u64 events[], int n_ev,
- unsigned int hwc[], unsigned long mmcr[]);
- int (*get_constraint)(u64 event_id, unsigned long *mskp,
- unsigned long *valp);
- int (*get_alternatives)(u64 event_id, unsigned int flags,
- u64 alt[]);
- void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
- int (*limited_pmc_event)(u64 event_id);
- u32 flags;
- int n_generic;
- int *generic_events;
- int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX];
-};
-
-/*
- * Values for power_pmu.flags
- */
-#define PPMU_LIMITED_PMC5_6 1 /* PMC5/6 have limited function */
-#define PPMU_ALT_SIPR 2 /* uses alternate posn for SIPR/HV */
-
-/*
- * Values for flags to get_alternatives()
- */
-#define PPMU_LIMITED_PMC_OK 1 /* can put this on a limited PMC */
-#define PPMU_LIMITED_PMC_REQD 2 /* have to put this on a limited PMC */
-#define PPMU_ONLY_COUNT_RUN 4 /* only counting in run state */
-
-extern int register_power_pmu(struct power_pmu *);
-struct pt_regs;
-extern unsigned long perf_misc_flags(struct pt_regs *regs);
-extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
-
-#define PERF_EVENT_INDEX_OFFSET 1
-
-/*
- * Only override the default definitions in include/linux/perf_event.h
- * if we have hardware PMU support.
- */
#ifdef CONFIG_PPC_PERF_CTRS
-#define perf_misc_flags(regs) perf_misc_flags(regs)
+#include <asm/perf_event_server.h>
#endif
-/*
- * The power_pmu.get_constraint function returns a 32/64-bit value and
- * a 32/64-bit mask that express the constraints between this event_id and
- * other events.
- *
- * The value and mask are divided up into (non-overlapping) bitfields
- * of three different types:
- *
- * Select field: this expresses the constraint that some set of bits
- * in MMCR* needs to be set to a specific value for this event_id. For a
- * select field, the mask contains 1s in every bit of the field, and
- * the value contains a unique value for each possible setting of the
- * MMCR* bits. The constraint checking code will ensure that two events
- * that set the same field in their masks have the same value in their
- * value dwords.
- *
- * Add field: this expresses the constraint that there can be at most
- * N events in a particular class. A field of k bits can be used for
- * N <= 2^(k-1) - 1. The mask has the most significant bit of the field
- * set (and the other bits 0), and the value has only the least significant
- * bit of the field set. In addition, the 'add_fields' and 'test_adder'
- * in the struct power_pmu for this processor come into play. The
- * add_fields value contains 1 in the LSB of the field, and the
- * test_adder contains 2^(k-1) - 1 - N in the field.
- *
- * NAND field: this expresses the constraint that you may not have events
- * in all of a set of classes. (For example, on PPC970, you can't select
- * events from the FPU, ISU and IDU simultaneously, although any two are
- * possible.) For N classes, the field is N+1 bits wide, and each class
- * is assigned one bit from the least-significant N bits. The mask has
- * only the most-significant bit set, and the value has only the bit
- * for the event_id's class set. The test_adder has the least significant
- * bit set in the field.
- *
- * If an event_id is not subject to the constraint expressed by a particular
- * field, then it will have 0 in both the mask and value for that field.
- */
+#ifdef CONFIG_FSL_EMB_PERF_EVENT
+#include <asm/perf_event_fsl_emb.h>
+#endif
diff --git a/arch/powerpc/include/asm/perf_event_fsl_emb.h b/arch/powerpc/include/asm/perf_event_fsl_emb.h
new file mode 100644
index 00000000000..718a9fa94e6
--- /dev/null
+++ b/arch/powerpc/include/asm/perf_event_fsl_emb.h
@@ -0,0 +1,50 @@
+/*
+ * Performance event support - Freescale embedded specific definitions.
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ * Copyright 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/types.h>
+#include <asm/hw_irq.h>
+
+#define MAX_HWEVENTS 4
+
+/* event flags */
+#define FSL_EMB_EVENT_VALID 1
+#define FSL_EMB_EVENT_RESTRICTED 2
+
+/* upper half of event flags is PMLCb */
+#define FSL_EMB_EVENT_THRESHMUL 0x0000070000000000ULL
+#define FSL_EMB_EVENT_THRESH 0x0000003f00000000ULL
+
+struct fsl_emb_pmu {
+ const char *name;
+ int n_counter; /* total number of counters */
+
+ /*
+ * The number of contiguous counters starting at zero that
+ * can hold restricted events, or zero if there are no
+ * restricted events.
+ *
+ * This isn't a very flexible method of expressing constraints,
+ * but it's very simple and is adequate for existing chips.
+ */
+ int n_restricted;
+
+ /* Returns event flags and PMLCb (FSL_EMB_EVENT_*) */
+ u64 (*xlate_event)(u64 event_id);
+
+ int n_generic;
+ int *generic_events;
+ int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+};
+
+int register_fsl_emb_pmu(struct fsl_emb_pmu *);
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
new file mode 100644
index 00000000000..8f1df1208d2
--- /dev/null
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -0,0 +1,110 @@
+/*
+ * Performance event support - PowerPC classic/server specific definitions.
+ *
+ * Copyright 2008-2009 Paul Mackerras, 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.
+ */
+
+#include <linux/types.h>
+#include <asm/hw_irq.h>
+
+#define MAX_HWEVENTS 8
+#define MAX_EVENT_ALTERNATIVES 8
+#define MAX_LIMITED_HWCOUNTERS 2
+
+/*
+ * This struct provides the constants and functions needed to
+ * describe the PMU on a particular POWER-family CPU.
+ */
+struct power_pmu {
+ const char *name;
+ int n_counter;
+ int max_alternatives;
+ unsigned long add_fields;
+ unsigned long test_adder;
+ int (*compute_mmcr)(u64 events[], int n_ev,
+ unsigned int hwc[], unsigned long mmcr[]);
+ int (*get_constraint)(u64 event_id, unsigned long *mskp,
+ unsigned long *valp);
+ int (*get_alternatives)(u64 event_id, unsigned int flags,
+ u64 alt[]);
+ void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
+ int (*limited_pmc_event)(u64 event_id);
+ u32 flags;
+ int n_generic;
+ int *generic_events;
+ int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+};
+
+/*
+ * Values for power_pmu.flags
+ */
+#define PPMU_LIMITED_PMC5_6 1 /* PMC5/6 have limited function */
+#define PPMU_ALT_SIPR 2 /* uses alternate posn for SIPR/HV */
+
+/*
+ * Values for flags to get_alternatives()
+ */
+#define PPMU_LIMITED_PMC_OK 1 /* can put this on a limited PMC */
+#define PPMU_LIMITED_PMC_REQD 2 /* have to put this on a limited PMC */
+#define PPMU_ONLY_COUNT_RUN 4 /* only counting in run state */
+
+extern int register_power_pmu(struct power_pmu *);
+
+struct pt_regs;
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+
+#define PERF_EVENT_INDEX_OFFSET 1
+
+/*
+ * Only override the default definitions in include/linux/perf_event.h
+ * if we have hardware PMU support.
+ */
+#ifdef CONFIG_PPC_PERF_CTRS
+#define perf_misc_flags(regs) perf_misc_flags(regs)
+#endif
+
+/*
+ * The power_pmu.get_constraint function returns a 32/64-bit value and
+ * a 32/64-bit mask that express the constraints between this event_id and
+ * other events.
+ *
+ * The value and mask are divided up into (non-overlapping) bitfields
+ * of three different types:
+ *
+ * Select field: this expresses the constraint that some set of bits
+ * in MMCR* needs to be set to a specific value for this event_id. For a
+ * select field, the mask contains 1s in every bit of the field, and
+ * the value contains a unique value for each possible setting of the
+ * MMCR* bits. The constraint checking code will ensure that two events
+ * that set the same field in their masks have the same value in their
+ * value dwords.
+ *
+ * Add field: this expresses the constraint that there can be at most
+ * N events in a particular class. A field of k bits can be used for
+ * N <= 2^(k-1) - 1. The mask has the most significant bit of the field
+ * set (and the other bits 0), and the value has only the least significant
+ * bit of the field set. In addition, the 'add_fields' and 'test_adder'
+ * in the struct power_pmu for this processor come into play. The
+ * add_fields value contains 1 in the LSB of the field, and the
+ * test_adder contains 2^(k-1) - 1 - N in the field.
+ *
+ * NAND field: this expresses the constraint that you may not have events
+ * in all of a set of classes. (For example, on PPC970, you can't select
+ * events from the FPU, ISU and IDU simultaneously, although any two are
+ * possible.) For N classes, the field is N+1 bits wide, and each class
+ * is assigned one bit from the least-significant N bits. The mask has
+ * only the most-significant bit set, and the value has only the bit
+ * for the event_id's class set. The test_adder has the least significant
+ * bit set in the field.
+ *
+ * If an event_id is not subject to the constraint expressed by a particular
+ * field, then it will have 0 in both the mask and value for that field.
+ */
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index aea71479759..d553bbeb726 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -25,7 +25,7 @@
#define PPC_INST_LDARX 0x7c0000a8
#define PPC_INST_LSWI 0x7c0004aa
#define PPC_INST_LSWX 0x7c00042a
-#define PPC_INST_LWARX 0x7c000029
+#define PPC_INST_LWARX 0x7c000028
#define PPC_INST_LWSYNC 0x7c2004ac
#define PPC_INST_LXVD2X 0x7c000698
#define PPC_INST_MCRXR 0x7c000400
@@ -62,8 +62,8 @@
#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
#define __PPC_WC(w) (((w) & 0x3) << 21)
/*
- * Only use the larx hint bit on 64bit CPUs. Once we verify it doesn't have
- * any side effects on all 32bit processors, we can do this all the time.
+ * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a
+ * larx with EH set as an illegal instruction.
*/
#ifdef CONFIG_PPC64
#define __PPC_EH(eh) (((eh) & 0x1) << 0)
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index b4510812656..9e2d84c06b7 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -137,15 +137,8 @@ do { \
} while (0)
#endif /* __powerpc64__ */
-/*
- * These are defined as per linux/ptrace.h, which see.
- */
#define arch_has_single_step() (1)
#define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601))
-extern void user_enable_single_step(struct task_struct *);
-extern void user_enable_block_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
-
#define ARCH_HAS_USER_SINGLE_STEP_INFO
#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index bc8dd53f718..5572e86223f 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -426,6 +426,10 @@
#define SRR1_WAKEMT 0x00280000 /* mtctrl */
#define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */
#define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */
+#define SRR1_PROGFPE 0x00100000 /* Floating Point Enabled */
+#define SRR1_PROGPRIV 0x00040000 /* Privileged instruction */
+#define SRR1_PROGTRAP 0x00020000 /* Trap */
+#define SRR1_PROGADDR 0x00010000 /* SRR0 contains subsequent addr */
#define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */
#define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 8808d307fe7..414d434a66d 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -421,8 +421,8 @@
/* Bit definitions related to the DBCR2. */
#define DBCR2_DAC1US 0xC0000000 /* Data Addr Cmp 1 Sup/User */
#define DBCR2_DAC1ER 0x30000000 /* Data Addr Cmp 1 Eff/Real */
-#define DBCR2_DAC2US 0x00000000 /* Data Addr Cmp 2 Sup/User */
-#define DBCR2_DAC2ER 0x00000000 /* Data Addr Cmp 2 Eff/Real */
+#define DBCR2_DAC2US 0x0C000000 /* Data Addr Cmp 2 Sup/User */
+#define DBCR2_DAC2ER 0x03000000 /* Data Addr Cmp 2 Eff/Real */
#define DBCR2_DAC12M 0x00800000 /* DAC 1-2 range enable */
#define DBCR2_DAC12MM 0x00400000 /* DAC 1-2 Mask mode*/
#define DBCR2_DAC12MX 0x00C00000 /* DAC 1-2 range eXclusive */
diff --git a/arch/powerpc/include/asm/reg_fsl_emb.h b/arch/powerpc/include/asm/reg_fsl_emb.h
index 0de404dfee8..77bb71cfd99 100644
--- a/arch/powerpc/include/asm/reg_fsl_emb.h
+++ b/arch/powerpc/include/asm/reg_fsl_emb.h
@@ -31,7 +31,7 @@
#define PMLCA_FCM0 0x08000000 /* Freeze when PMM==0 */
#define PMLCA_CE 0x04000000 /* Condition Enable */
-#define PMLCA_EVENT_MASK 0x007f0000 /* Event field */
+#define PMLCA_EVENT_MASK 0x00ff0000 /* Event field */
#define PMLCA_EVENT_SHIFT 16
#define PMRN_PMLCB0 0x110 /* PM Local Control B0 */
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index efa7f0b879f..23913e902fc 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -30,7 +30,7 @@ static inline void syscall_rollback(struct task_struct *task,
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
- return (regs->ccr & 0x1000) ? -regs->gpr[3] : 0;
+ return (regs->ccr & 0x10000000) ? -regs->gpr[3] : 0;
}
static inline long syscall_get_return_value(struct task_struct *task,
@@ -44,10 +44,10 @@ static inline void syscall_set_return_value(struct task_struct *task,
int error, long val)
{
if (error) {
- regs->ccr |= 0x1000L;
+ regs->ccr |= 0x10000000L;
regs->gpr[3] = -error;
} else {
- regs->ccr &= ~0x1000L;
+ regs->ccr &= ~0x10000000L;
regs->gpr[3] = val;
}
}
diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h
index eb8eb400c66..4084e567d28 100644
--- a/arch/powerpc/include/asm/syscalls.h
+++ b/arch/powerpc/include/asm/syscalls.h
@@ -7,7 +7,6 @@
#include <linux/types.h>
#include <asm/signal.h>
-struct new_utsname;
struct pt_regs;
struct rtas_args;
struct sigaction;
@@ -35,12 +34,9 @@ asmlinkage long sys_pipe2(int __user *fildes, int flags);
asmlinkage long sys_rt_sigaction(int sig,
const struct sigaction __user *act,
struct sigaction __user *oact, size_t sigsetsize);
-asmlinkage int sys_ipc(uint call, int first, unsigned long second,
- long third, void __user *ptr, long fifth);
asmlinkage long ppc64_personality(unsigned long personality);
asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
asmlinkage time_t sys64_time(time_t __user * tloc);
-asmlinkage long ppc_newuname(struct new_utsname __user * name);
asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset,
size_t sigsetsize);
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 07d2d19ab5e..a5ee345b6a5 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -125,7 +125,7 @@ SYSCALL_SPU(fsync)
SYS32ONLY(sigreturn)
PPC_SYS(clone)
COMPAT_SYS_SPU(setdomainname)
-PPC_SYS_SPU(newuname)
+SYSCALL_SPU(newuname)
SYSCALL(ni_syscall)
COMPAT_SYS_SPU(adjtimex)
SYSCALL_SPU(mprotect)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index f6ca7617676..f0a10266e7f 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -364,6 +364,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -376,6 +377,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index c002b041021..877326320e7 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -98,11 +98,16 @@ obj64-$(CONFIG_AUDIT) += compat_audit.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
-obj-$(CONFIG_PPC_PERF_CTRS) += perf_event.o perf_callchain.o
+obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
+
+obj-$(CONFIG_PPC_PERF_CTRS) += perf_event.o
obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \
power5+-pmu.o power6-pmu.o power7-pmu.o
obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
+obj-$(CONFIG_FSL_EMB_PERF_EVENT) += perf_event_fsl_emb.o
+obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o
+
obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
ifneq ($(CONFIG_PPC_INDIRECT_IO),y)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index a6c2b63227b..957ceb7059c 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -194,6 +194,30 @@ int main(void)
DEFINE(PACA_KVM_IN_GUEST, offsetof(struct paca_struct, kvm_in_guest));
DEFINE(PACA_KVM_SLB, offsetof(struct paca_struct, kvm_slb));
DEFINE(PACA_KVM_SLB_MAX, offsetof(struct paca_struct, kvm_slb_max));
+ DEFINE(PACA_KVM_CR, offsetof(struct paca_struct, shadow_vcpu.cr));
+ DEFINE(PACA_KVM_XER, offsetof(struct paca_struct, shadow_vcpu.xer));
+ DEFINE(PACA_KVM_R0, offsetof(struct paca_struct, shadow_vcpu.gpr[0]));
+ DEFINE(PACA_KVM_R1, offsetof(struct paca_struct, shadow_vcpu.gpr[1]));
+ DEFINE(PACA_KVM_R2, offsetof(struct paca_struct, shadow_vcpu.gpr[2]));
+ DEFINE(PACA_KVM_R3, offsetof(struct paca_struct, shadow_vcpu.gpr[3]));
+ DEFINE(PACA_KVM_R4, offsetof(struct paca_struct, shadow_vcpu.gpr[4]));
+ DEFINE(PACA_KVM_R5, offsetof(struct paca_struct, shadow_vcpu.gpr[5]));
+ DEFINE(PACA_KVM_R6, offsetof(struct paca_struct, shadow_vcpu.gpr[6]));
+ DEFINE(PACA_KVM_R7, offsetof(struct paca_struct, shadow_vcpu.gpr[7]));
+ DEFINE(PACA_KVM_R8, offsetof(struct paca_struct, shadow_vcpu.gpr[8]));
+ DEFINE(PACA_KVM_R9, offsetof(struct paca_struct, shadow_vcpu.gpr[9]));
+ DEFINE(PACA_KVM_R10, offsetof(struct paca_struct, shadow_vcpu.gpr[10]));
+ DEFINE(PACA_KVM_R11, offsetof(struct paca_struct, shadow_vcpu.gpr[11]));
+ DEFINE(PACA_KVM_R12, offsetof(struct paca_struct, shadow_vcpu.gpr[12]));
+ DEFINE(PACA_KVM_R13, offsetof(struct paca_struct, shadow_vcpu.gpr[13]));
+ DEFINE(PACA_KVM_HOST_R1, offsetof(struct paca_struct, shadow_vcpu.host_r1));
+ DEFINE(PACA_KVM_HOST_R2, offsetof(struct paca_struct, shadow_vcpu.host_r2));
+ DEFINE(PACA_KVM_VMHANDLER, offsetof(struct paca_struct,
+ shadow_vcpu.vmhandler));
+ DEFINE(PACA_KVM_SCRATCH0, offsetof(struct paca_struct,
+ shadow_vcpu.scratch0));
+ DEFINE(PACA_KVM_SCRATCH1, offsetof(struct paca_struct,
+ shadow_vcpu.scratch1));
#endif
#endif /* CONFIG_PPC64 */
@@ -389,8 +413,6 @@ int main(void)
DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
- DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
- DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr));
DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc));
DEFINE(VCPU_MSR, offsetof(struct kvm_vcpu, arch.msr));
@@ -411,11 +433,16 @@ int main(void)
DEFINE(VCPU_HOST_R2, offsetof(struct kvm_vcpu, arch.host_r2));
DEFINE(VCPU_HOST_MSR, offsetof(struct kvm_vcpu, arch.host_msr));
DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr));
+ DEFINE(VCPU_SHADOW_SRR1, offsetof(struct kvm_vcpu, arch.shadow_srr1));
DEFINE(VCPU_TRAMPOLINE_LOWMEM, offsetof(struct kvm_vcpu, arch.trampoline_lowmem));
DEFINE(VCPU_TRAMPOLINE_ENTER, offsetof(struct kvm_vcpu, arch.trampoline_enter));
DEFINE(VCPU_HIGHMEM_HANDLER, offsetof(struct kvm_vcpu, arch.highmem_handler));
+ DEFINE(VCPU_RMCALL, offsetof(struct kvm_vcpu, arch.rmcall));
DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags));
-#endif
+#else
+ DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
+ DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
+#endif /* CONFIG_PPC64 */
#endif
#ifdef CONFIG_44x
DEFINE(PGD_T_LOG2, PGD_T_LOG2);
diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c
index bb37b1d19a5..a3c684b4c86 100644
--- a/arch/powerpc/kernel/cacheinfo.c
+++ b/arch/powerpc/kernel/cacheinfo.c
@@ -19,6 +19,7 @@
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/percpu.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include "cacheinfo.h"
@@ -642,7 +643,7 @@ static struct kobj_attribute *cache_index_opt_attrs[] = {
&cache_assoc_attr,
};
-static struct sysfs_ops cache_index_ops = {
+static const struct sysfs_ops cache_index_ops = {
.show = cache_index_show,
};
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 2fc82bac3bb..8af4949434b 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1808,7 +1808,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 64,
.dcache_bsize = 64,
.num_pmcs = 4,
- .oprofile_cpu_type = "ppc/e500", /* xxx - galak, e500mc? */
+ .oprofile_cpu_type = "ppc/e500mc",
.oprofile_type = PPC_OPROFILE_FSL_EMB,
.cpu_setup = __setup_cpu_e500mc,
.machine_check = machine_check_e500,
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 6215062caf8..6c1df5757cd 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -8,6 +8,7 @@
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/dma-debug.h>
+#include <linux/gfp.h>
#include <linux/lmb.h>
#include <asm/bug.h>
#include <asm/abs_addr.h>
diff --git a/arch/powerpc/kernel/e500-pmu.c b/arch/powerpc/kernel/e500-pmu.c
new file mode 100644
index 00000000000..7c07de0d894
--- /dev/null
+++ b/arch/powerpc/kernel/e500-pmu.c
@@ -0,0 +1,129 @@
+/*
+ * Performance counter support for e500 family processors.
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ * Copyright 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/string.h>
+#include <linux/perf_event.h>
+#include <asm/reg.h>
+#include <asm/cputable.h>
+
+/*
+ * Map of generic hardware event types to hardware events
+ * Zero if unsupported
+ */
+static int e500_generic_events[] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = 1,
+ [PERF_COUNT_HW_INSTRUCTIONS] = 2,
+ [PERF_COUNT_HW_CACHE_MISSES] = 41, /* Data L1 cache reloads */
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 12,
+ [PERF_COUNT_HW_BRANCH_MISSES] = 15,
+};
+
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+/*
+ * Table of generalized cache-related events.
+ * 0 means not supported, -1 means nonsensical, other values
+ * are event codes.
+ */
+static int e500_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
+ /*
+ * D-cache misses are not split into read/write/prefetch;
+ * use raw event 41.
+ */
+ [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
+ [C(OP_READ)] = { 27, 0 },
+ [C(OP_WRITE)] = { 28, 0 },
+ [C(OP_PREFETCH)] = { 29, 0 },
+ },
+ [C(L1I)] = { /* RESULT_ACCESS RESULT_MISS */
+ [C(OP_READ)] = { 2, 60 },
+ [C(OP_WRITE)] = { -1, -1 },
+ [C(OP_PREFETCH)] = { 0, 0 },
+ },
+ /*
+ * Assuming LL means L2, it's not a good match for this model.
+ * It allocates only on L1 castout or explicit prefetch, and
+ * does not have separate read/write events (but it does have
+ * separate instruction/data events).
+ */
+ [C(LL)] = { /* RESULT_ACCESS RESULT_MISS */
+ [C(OP_READ)] = { 0, 0 },
+ [C(OP_WRITE)] = { 0, 0 },
+ [C(OP_PREFETCH)] = { 0, 0 },
+ },
+ /*
+ * There are data/instruction MMU misses, but that's a miss on
+ * the chip's internal level-one TLB which is probably not
+ * what the user wants. Instead, unified level-two TLB misses
+ * are reported here.
+ */
+ [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */
+ [C(OP_READ)] = { 26, 66 },
+ [C(OP_WRITE)] = { -1, -1 },
+ [C(OP_PREFETCH)] = { -1, -1 },
+ },
+ [C(BPU)] = { /* RESULT_ACCESS RESULT_MISS */
+ [C(OP_READ)] = { 12, 15 },
+ [C(OP_WRITE)] = { -1, -1 },
+ [C(OP_PREFETCH)] = { -1, -1 },
+ },
+};
+
+static int num_events = 128;
+
+/* Upper half of event id is PMLCb, for threshold events */
+static u64 e500_xlate_event(u64 event_id)
+{
+ u32 event_low = (u32)event_id;
+ u64 ret;
+
+ if (event_low >= num_events)
+ return 0;
+
+ ret = FSL_EMB_EVENT_VALID;
+
+ if (event_low >= 76 && event_low <= 81) {
+ ret |= FSL_EMB_EVENT_RESTRICTED;
+ ret |= event_id &
+ (FSL_EMB_EVENT_THRESHMUL | FSL_EMB_EVENT_THRESH);
+ } else if (event_id &
+ (FSL_EMB_EVENT_THRESHMUL | FSL_EMB_EVENT_THRESH)) {
+ /* Threshold requested on non-threshold event */
+ return 0;
+ }
+
+ return ret;
+}
+
+static struct fsl_emb_pmu e500_pmu = {
+ .name = "e500 family",
+ .n_counter = 4,
+ .n_restricted = 2,
+ .xlate_event = e500_xlate_event,
+ .n_generic = ARRAY_SIZE(e500_generic_events),
+ .generic_events = e500_generic_events,
+ .cache_events = &e500_cache_events,
+};
+
+static int init_e500_pmu(void)
+{
+ if (!cur_cpu_spec->oprofile_cpu_type)
+ return -ENODEV;
+
+ if (!strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/e500mc"))
+ num_events = 256;
+ else if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/e500"))
+ return -ENODEV;
+
+ return register_fsl_emb_pmu(&e500_pmu);
+}
+
+arch_initcall(init_e500_pmu);
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 92580748802..bed9a29ee38 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -219,7 +219,8 @@ generic_secondary_common_init:
* physical cpu id in r24, we need to search the pacas to find
* which logical id maps to our physical one.
*/
- LOAD_REG_ADDR(r13, paca) /* Get base vaddr of paca array */
+ LOAD_REG_ADDR(r13, paca) /* Load paca pointer */
+ ld r13,0(r13) /* Get base vaddr of paca array */
li r5,0 /* logical cpu id */
1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */
cmpw r6,r24 /* Compare to our id */
@@ -536,7 +537,8 @@ _GLOBAL(pmac_secondary_start)
mtmsrd r3 /* RI on */
/* Set up a paca value for this processor. */
- LOAD_REG_ADDR(r4,paca) /* Get base vaddr of paca array */
+ LOAD_REG_ADDR(r4,paca) /* Load paca pointer */
+ ld r4,0(r4) /* Get base vaddr of paca array */
mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r4 /* for this processor. */
mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/
@@ -615,6 +617,17 @@ _GLOBAL(start_secondary_prolog)
std r3,0(r1) /* Zero the stack frame pointer */
bl .start_secondary
b .
+/*
+ * Reset stack pointer and call start_secondary
+ * to continue with online operation when woken up
+ * from cede in cpu offline.
+ */
+_GLOBAL(start_secondary_resume)
+ ld r1,PACAKSAVE(r13) /* Reload kernel stack pointer */
+ li r3,0
+ std r3,0(r1) /* Zero the stack frame pointer */
+ bl .start_secondary
+ b .
#endif
/*
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 25793bb0e78..72552654799 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -747,9 +747,6 @@ finish_tlb_load:
#else
rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */
#endif
-#ifdef CONFIG_SMP
- ori r12, r12, MAS2_M
-#endif
mtspr SPRN_MAS2, r12
#ifdef CONFIG_PTE_64BIT
@@ -887,13 +884,17 @@ KernelSPE:
lwz r3,_MSR(r1)
oris r3,r3,MSR_SPE@h
stw r3,_MSR(r1) /* enable use of SPE after return */
+#ifdef CONFIG_PRINTK
lis r3,87f@h
ori r3,r3,87f@l
mr r4,r2 /* current */
lwz r5,_NIP(r1)
bl printk
+#endif
b ret_from_except
+#ifdef CONFIG_PRINTK
87: .string "SPE used in kernel (task=%p, pc=%x) \n"
+#endif
.align 4,0
#endif /* CONFIG_SPE */
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index a4c8b38b0ba..71cf280da18 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -42,6 +42,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <linux/of_platform.h>
#include <asm/ibmebus.h>
#include <asm/abs_addr.h>
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 5547ae6e6b0..ec94f906ea4 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -42,12 +42,7 @@
#define DBG(...)
-#ifdef CONFIG_IOMMU_VMERGE
-static int novmerge = 0;
-#else
-static int novmerge = 1;
-#endif
-
+static int novmerge;
static int protect4gb = 1;
static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int);
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 3fd1af90211..b36f074524a 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -31,6 +31,7 @@
#include <linux/preempt.h>
#include <linux/module.h>
#include <linux/kdebug.h>
+#include <linux/slab.h>
#include <asm/cacheflush.h>
#include <asm/sstep.h>
#include <asm/uaccess.h>
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 9ddfaef1a18..035ada5443e 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -469,7 +469,7 @@ static int __init serial_dev_init(void)
return -ENODEV;
/*
- * Before we register the platfrom serial devices, we need
+ * Before we register the platform serial devices, we need
* to fixup their interrupts and their IO ports.
*/
DBG("Fixing serial ports interrupts and IO ports ...\n");
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index d09d1c61515..c2c70e1b32c 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -24,6 +24,7 @@
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/iseries/hv_lp_config.h>
#include <asm/lppaca.h>
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index 2d29752cbe1..22e507c8a55 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -127,3 +127,29 @@ _GLOBAL(__setup_cpu_power7)
_GLOBAL(__restore_cpu_power7)
/* place holder */
blr
+
+/*
+ * Get a minimal set of registers for our caller's nth caller.
+ * r3 = regs pointer, r5 = n.
+ *
+ * We only get R1 (stack pointer), NIP (next instruction pointer)
+ * and LR (link register). These are all we can get in the
+ * general case without doing complicated stack unwinding, but
+ * fortunately they are enough to do a stack backtrace, which
+ * is all we need them for.
+ */
+_GLOBAL(perf_arch_fetch_caller_regs)
+ mr r6,r1
+ cmpwi r5,0
+ mflr r4
+ ble 2f
+ mtctr r5
+1: PPC_LL r6,0(r6)
+ bdnz 1b
+ PPC_LL r4,PPC_LR_STKOFF(r6)
+2: PPC_LL r7,0(r6)
+ PPC_LL r7,PPC_LR_STKOFF(r7)
+ PPC_STL r6,GPR1-STACK_FRAME_OVERHEAD(r3)
+ PPC_STL r4,_NIP-STACK_FRAME_OVERHEAD(r3)
+ PPC_STL r7,_LINK-STACK_FRAME_OVERHEAD(r3)
+ blr
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 666d08db319..6c1dfc3ff8b 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -17,7 +17,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/of.h>
#include <linux/of_device.h>
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index d16b1ea55d4..0c40c6f476f 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -9,11 +9,15 @@
#include <linux/threads.h>
#include <linux/module.h>
+#include <linux/lmb.h>
+#include <asm/firmware.h>
#include <asm/lppaca.h>
#include <asm/paca.h>
#include <asm/sections.h>
#include <asm/pgtable.h>
+#include <asm/iseries/lpar_map.h>
+#include <asm/iseries/hv_types.h>
/* This symbol is provided by the linker - let it fill in the paca
* field correctly */
@@ -70,37 +74,82 @@ struct slb_shadow slb_shadow[] __cacheline_aligned = {
* processors. The processor VPD array needs one entry per physical
* processor (not thread).
*/
-struct paca_struct paca[NR_CPUS];
+struct paca_struct *paca;
EXPORT_SYMBOL(paca);
-void __init initialise_pacas(void)
-{
- int cpu;
+struct paca_struct boot_paca;
- /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB
- * of the TOC can be addressed using a single machine instruction.
- */
+void __init initialise_paca(struct paca_struct *new_paca, int cpu)
+{
+ /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB
+ * of the TOC can be addressed using a single machine instruction.
+ */
unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL;
- /* Can't use for_each_*_cpu, as they aren't functional yet */
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- struct paca_struct *new_paca = &paca[cpu];
-
#ifdef CONFIG_PPC_BOOK3S
- new_paca->lppaca_ptr = &lppaca[cpu];
+ new_paca->lppaca_ptr = &lppaca[cpu];
#else
- new_paca->kernel_pgd = swapper_pg_dir;
+ new_paca->kernel_pgd = swapper_pg_dir;
#endif
- new_paca->lock_token = 0x8000;
- new_paca->paca_index = cpu;
- new_paca->kernel_toc = kernel_toc;
- new_paca->kernelbase = (unsigned long) _stext;
- new_paca->kernel_msr = MSR_KERNEL;
- new_paca->hw_cpu_id = 0xffff;
- new_paca->__current = &init_task;
+ new_paca->lock_token = 0x8000;
+ new_paca->paca_index = cpu;
+ new_paca->kernel_toc = kernel_toc;
+ new_paca->kernelbase = (unsigned long) _stext;
+ new_paca->kernel_msr = MSR_KERNEL;
+ new_paca->hw_cpu_id = 0xffff;
+ new_paca->__current = &init_task;
#ifdef CONFIG_PPC_STD_MMU_64
- new_paca->slb_shadow_ptr = &slb_shadow[cpu];
+ new_paca->slb_shadow_ptr = &slb_shadow[cpu];
#endif /* CONFIG_PPC_STD_MMU_64 */
+}
+
+static int __initdata paca_size;
+
+void __init allocate_pacas(void)
+{
+ int nr_cpus, cpu, limit;
+
+ /*
+ * We can't take SLB misses on the paca, and we want to access them
+ * in real mode, so allocate them within the RMA and also within
+ * the first segment. On iSeries they must be within the area mapped
+ * by the HV, which is HvPagesToMap * HVPAGESIZE bytes.
+ */
+ limit = min(0x10000000ULL, lmb.rmo_size);
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ limit = min(limit, HvPagesToMap * HVPAGESIZE);
+
+ nr_cpus = NR_CPUS;
+ /* On iSeries we know we can never have more than 64 cpus */
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ nr_cpus = min(64, nr_cpus);
+
+ paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpus);
+
+ paca = __va(lmb_alloc_base(paca_size, PAGE_SIZE, limit));
+ memset(paca, 0, paca_size);
+
+ printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n",
+ paca_size, nr_cpus, paca);
+
+ /* Can't use for_each_*_cpu, as they aren't functional yet */
+ for (cpu = 0; cpu < nr_cpus; cpu++)
+ initialise_paca(&paca[cpu], cpu);
+}
+
+void __init free_unused_pacas(void)
+{
+ int new_size;
+
+ new_size = PAGE_ALIGN(sizeof(struct paca_struct) * num_possible_cpus());
+
+ if (new_size >= paca_size)
+ return;
+
+ lmb_free(__pa(paca) + new_size, paca_size - new_size);
+
+ printk(KERN_DEBUG "Freed %u bytes for unused pacas\n",
+ paca_size - new_size);
- }
+ paca_size = new_size;
}
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 2597f9545d8..0c0567e5840 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -26,6 +26,7 @@
#include <linux/syscalls.h>
#include <linux/irq.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -63,21 +64,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
}
EXPORT_SYMBOL(get_pci_dma_ops);
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- return dma_set_mask(&dev->dev, mask);
-}
-
-int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- int rc;
-
- rc = dma_set_mask(&dev->dev, mask);
- dev->dev.coherent_dma_mask = dev->dma_mask;
-
- return rc;
-}
-
struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
{
struct pci_controller *phb;
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index c13668cf36d..e7db5b48004 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -14,6 +14,7 @@
#include <linux/irq.h>
#include <linux/list.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/io.h>
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index d5e36e5dc7c..d56b35ee7f7 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -23,6 +23,7 @@
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index b6cf8f1f4d3..08460a2e9f4 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -1164,10 +1164,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
* Finally record data if requested.
*/
if (record) {
- struct perf_sample_data data = {
- .addr = ~0ULL,
- .period = event->hw.last_period,
- };
+ struct perf_sample_data data;
+
+ perf_sample_data_init(&data, ~0ULL);
+ data.period = event->hw.last_period;
if (event->attr.sample_type & PERF_SAMPLE_ADDR)
perf_get_data_addr(regs, &data.addr);
@@ -1287,7 +1287,7 @@ static void perf_event_interrupt(struct pt_regs *regs)
irq_exit();
}
-void hw_perf_event_setup(int cpu)
+static void power_pmu_setup(int cpu)
{
struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
@@ -1297,6 +1297,23 @@ void hw_perf_event_setup(int cpu)
cpuhw->mmcr[0] = MMCR0_FC;
}
+static int __cpuinit
+power_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ power_pmu_setup(cpu);
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
int register_power_pmu(struct power_pmu *pmu)
{
if (ppmu)
@@ -1314,5 +1331,7 @@ int register_power_pmu(struct power_pmu *pmu)
freeze_events_kernel = MMCR0_FCHV;
#endif /* CONFIG_PPC64 */
+ perf_cpu_notifier(power_pmu_notifier);
+
return 0;
}
diff --git a/arch/powerpc/kernel/perf_event_fsl_emb.c b/arch/powerpc/kernel/perf_event_fsl_emb.c
new file mode 100644
index 00000000000..369872f6cf7
--- /dev/null
+++ b/arch/powerpc/kernel/perf_event_fsl_emb.c
@@ -0,0 +1,654 @@
+/*
+ * Performance event support - Freescale Embedded Performance Monitor
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ * Copyright 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/hardirq.h>
+#include <asm/reg_fsl_emb.h>
+#include <asm/pmc.h>
+#include <asm/machdep.h>
+#include <asm/firmware.h>
+#include <asm/ptrace.h>
+
+struct cpu_hw_events {
+ int n_events;
+ int disabled;
+ u8 pmcs_enabled;
+ struct perf_event *event[MAX_HWEVENTS];
+};
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+static struct fsl_emb_pmu *ppmu;
+
+/* Number of perf_events counting hardware events */
+static atomic_t num_events;
+/* Used to avoid races in calling reserve/release_pmc_hardware */
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+/*
+ * If interrupts were soft-disabled when a PMU interrupt occurs, treat
+ * it as an NMI.
+ */
+static inline int perf_intr_is_nmi(struct pt_regs *regs)
+{
+#ifdef __powerpc64__
+ return !regs->softe;
+#else
+ return 0;
+#endif
+}
+
+static void perf_event_interrupt(struct pt_regs *regs);
+
+/*
+ * Read one performance monitor counter (PMC).
+ */
+static unsigned long read_pmc(int idx)
+{
+ unsigned long val;
+
+ switch (idx) {
+ case 0:
+ val = mfpmr(PMRN_PMC0);
+ break;
+ case 1:
+ val = mfpmr(PMRN_PMC1);
+ break;
+ case 2:
+ val = mfpmr(PMRN_PMC2);
+ break;
+ case 3:
+ val = mfpmr(PMRN_PMC3);
+ break;
+ default:
+ printk(KERN_ERR "oops trying to read PMC%d\n", idx);
+ val = 0;
+ }
+ return val;
+}
+
+/*
+ * Write one PMC.
+ */
+static void write_pmc(int idx, unsigned long val)
+{
+ switch (idx) {
+ case 0:
+ mtpmr(PMRN_PMC0, val);
+ break;
+ case 1:
+ mtpmr(PMRN_PMC1, val);
+ break;
+ case 2:
+ mtpmr(PMRN_PMC2, val);
+ break;
+ case 3:
+ mtpmr(PMRN_PMC3, val);
+ break;
+ default:
+ printk(KERN_ERR "oops trying to write PMC%d\n", idx);
+ }
+
+ isync();
+}
+
+/*
+ * Write one local control A register
+ */
+static void write_pmlca(int idx, unsigned long val)
+{
+ switch (idx) {
+ case 0:
+ mtpmr(PMRN_PMLCA0, val);
+ break;
+ case 1:
+ mtpmr(PMRN_PMLCA1, val);
+ break;
+ case 2:
+ mtpmr(PMRN_PMLCA2, val);
+ break;
+ case 3:
+ mtpmr(PMRN_PMLCA3, val);
+ break;
+ default:
+ printk(KERN_ERR "oops trying to write PMLCA%d\n", idx);
+ }
+
+ isync();
+}
+
+/*
+ * Write one local control B register
+ */
+static void write_pmlcb(int idx, unsigned long val)
+{
+ switch (idx) {
+ case 0:
+ mtpmr(PMRN_PMLCB0, val);
+ break;
+ case 1:
+ mtpmr(PMRN_PMLCB1, val);
+ break;
+ case 2:
+ mtpmr(PMRN_PMLCB2, val);
+ break;
+ case 3:
+ mtpmr(PMRN_PMLCB3, val);
+ break;
+ default:
+ printk(KERN_ERR "oops trying to write PMLCB%d\n", idx);
+ }
+
+ isync();
+}
+
+static void fsl_emb_pmu_read(struct perf_event *event)
+{
+ s64 val, delta, prev;
+
+ /*
+ * Performance monitor interrupts come even when interrupts
+ * are soft-disabled, as long as interrupts are hard-enabled.
+ * Therefore we treat them like NMIs.
+ */
+ do {
+ prev = atomic64_read(&event->hw.prev_count);
+ barrier();
+ val = read_pmc(event->hw.idx);
+ } while (atomic64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
+
+ /* The counters are only 32 bits wide */
+ delta = (val - prev) & 0xfffffffful;
+ atomic64_add(delta, &event->count);
+ atomic64_sub(delta, &event->hw.period_left);
+}
+
+/*
+ * Disable all events to prevent PMU interrupts and to allow
+ * events to be added or removed.
+ */
+void hw_perf_disable(void)
+{
+ struct cpu_hw_events *cpuhw;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ cpuhw = &__get_cpu_var(cpu_hw_events);
+
+ if (!cpuhw->disabled) {
+ cpuhw->disabled = 1;
+
+ /*
+ * Check if we ever enabled the PMU on this cpu.
+ */
+ if (!cpuhw->pmcs_enabled) {
+ ppc_enable_pmcs();
+ cpuhw->pmcs_enabled = 1;
+ }
+
+ if (atomic_read(&num_events)) {
+ /*
+ * Set the 'freeze all counters' bit, and disable
+ * interrupts. The barrier is to make sure the
+ * mtpmr has been executed and the PMU has frozen
+ * the events before we return.
+ */
+
+ mtpmr(PMRN_PMGC0, PMGC0_FAC);
+ isync();
+ }
+ }
+ local_irq_restore(flags);
+}
+
+/*
+ * Re-enable all events if disable == 0.
+ * If we were previously disabled and events were added, then
+ * put the new config on the PMU.
+ */
+void hw_perf_enable(void)
+{
+ struct cpu_hw_events *cpuhw;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ cpuhw = &__get_cpu_var(cpu_hw_events);
+ if (!cpuhw->disabled)
+ goto out;
+
+ cpuhw->disabled = 0;
+ ppc_set_pmu_inuse(cpuhw->n_events != 0);
+
+ if (cpuhw->n_events > 0) {
+ mtpmr(PMRN_PMGC0, PMGC0_PMIE | PMGC0_FCECE);
+ isync();
+ }
+
+ out:
+ local_irq_restore(flags);
+}
+
+static int collect_events(struct perf_event *group, int max_count,
+ struct perf_event *ctrs[])
+{
+ int n = 0;
+ struct perf_event *event;
+
+ if (!is_software_event(group)) {
+ if (n >= max_count)
+ return -1;
+ ctrs[n] = group;
+ n++;
+ }
+ list_for_each_entry(event, &group->sibling_list, group_entry) {
+ if (!is_software_event(event) &&
+ event->state != PERF_EVENT_STATE_OFF) {
+ if (n >= max_count)
+ return -1;
+ ctrs[n] = event;
+ n++;
+ }
+ }
+ return n;
+}
+
+/* perf must be disabled, context locked on entry */
+static int fsl_emb_pmu_enable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuhw;
+ int ret = -EAGAIN;
+ int num_counters = ppmu->n_counter;
+ u64 val;
+ int i;
+
+ cpuhw = &get_cpu_var(cpu_hw_events);
+
+ if (event->hw.config & FSL_EMB_EVENT_RESTRICTED)
+ num_counters = ppmu->n_restricted;
+
+ /*
+ * Allocate counters from top-down, so that restricted-capable
+ * counters are kept free as long as possible.
+ */
+ for (i = num_counters - 1; i >= 0; i--) {
+ if (cpuhw->event[i])
+ continue;
+
+ break;
+ }
+
+ if (i < 0)
+ goto out;
+
+ event->hw.idx = i;
+ cpuhw->event[i] = event;
+ ++cpuhw->n_events;
+
+ val = 0;
+ if (event->hw.sample_period) {
+ s64 left = atomic64_read(&event->hw.period_left);
+ if (left < 0x80000000L)
+ val = 0x80000000L - left;
+ }
+ atomic64_set(&event->hw.prev_count, val);
+ write_pmc(i, val);
+ perf_event_update_userpage(event);
+
+ write_pmlcb(i, event->hw.config >> 32);
+ write_pmlca(i, event->hw.config_base);
+
+ ret = 0;
+ out:
+ put_cpu_var(cpu_hw_events);
+ return ret;
+}
+
+/* perf must be disabled, context locked on entry */
+static void fsl_emb_pmu_disable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuhw;
+ int i = event->hw.idx;
+
+ if (i < 0)
+ goto out;
+
+ fsl_emb_pmu_read(event);
+
+ cpuhw = &get_cpu_var(cpu_hw_events);
+
+ WARN_ON(event != cpuhw->event[event->hw.idx]);
+
+ write_pmlca(i, 0);
+ write_pmlcb(i, 0);
+ write_pmc(i, 0);
+
+ cpuhw->event[i] = NULL;
+ event->hw.idx = -1;
+
+ /*
+ * TODO: if at least one restricted event exists, and we
+ * just freed up a non-restricted-capable counter, and
+ * there is a restricted-capable counter occupied by
+ * a non-restricted event, migrate that event to the
+ * vacated counter.
+ */
+
+ cpuhw->n_events--;
+
+ out:
+ put_cpu_var(cpu_hw_events);
+}
+
+/*
+ * Re-enable interrupts on a event after they were throttled
+ * because they were coming too fast.
+ *
+ * Context is locked on entry, but perf is not disabled.
+ */
+static void fsl_emb_pmu_unthrottle(struct perf_event *event)
+{
+ s64 val, left;
+ unsigned long flags;
+
+ if (event->hw.idx < 0 || !event->hw.sample_period)
+ return;
+ local_irq_save(flags);
+ perf_disable();
+ fsl_emb_pmu_read(event);
+ left = event->hw.sample_period;
+ event->hw.last_period = left;
+ val = 0;
+ if (left < 0x80000000L)
+ val = 0x80000000L - left;
+ write_pmc(event->hw.idx, val);
+ atomic64_set(&event->hw.prev_count, val);
+ atomic64_set(&event->hw.period_left, left);
+ perf_event_update_userpage(event);
+ perf_enable();
+ local_irq_restore(flags);
+}
+
+static struct pmu fsl_emb_pmu = {
+ .enable = fsl_emb_pmu_enable,
+ .disable = fsl_emb_pmu_disable,
+ .read = fsl_emb_pmu_read,
+ .unthrottle = fsl_emb_pmu_unthrottle,
+};
+
+/*
+ * Release the PMU if this is the last perf_event.
+ */
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+ if (!atomic_add_unless(&num_events, -1, 1)) {
+ mutex_lock(&pmc_reserve_mutex);
+ if (atomic_dec_return(&num_events) == 0)
+ release_pmc_hardware();
+ mutex_unlock(&pmc_reserve_mutex);
+ }
+}
+
+/*
+ * Translate a generic cache event_id config to a raw event_id code.
+ */
+static int hw_perf_cache_event(u64 config, u64 *eventp)
+{
+ unsigned long type, op, result;
+ int ev;
+
+ if (!ppmu->cache_events)
+ return -EINVAL;
+
+ /* unpack config */
+ type = config & 0xff;
+ op = (config >> 8) & 0xff;
+ result = (config >> 16) & 0xff;
+
+ if (type >= PERF_COUNT_HW_CACHE_MAX ||
+ op >= PERF_COUNT_HW_CACHE_OP_MAX ||
+ result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+ return -EINVAL;
+
+ ev = (*ppmu->cache_events)[type][op][result];
+ if (ev == 0)
+ return -EOPNOTSUPP;
+ if (ev == -1)
+ return -EINVAL;
+ *eventp = ev;
+ return 0;
+}
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+ u64 ev;
+ struct perf_event *events[MAX_HWEVENTS];
+ int n;
+ int err;
+ int num_restricted;
+ int i;
+
+ switch (event->attr.type) {
+ case PERF_TYPE_HARDWARE:
+ ev = event->attr.config;
+ if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0)
+ return ERR_PTR(-EOPNOTSUPP);
+ ev = ppmu->generic_events[ev];
+ break;
+
+ case PERF_TYPE_HW_CACHE:
+ err = hw_perf_cache_event(event->attr.config, &ev);
+ if (err)
+ return ERR_PTR(err);
+ break;
+
+ case PERF_TYPE_RAW:
+ ev = event->attr.config;
+ break;
+
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+
+ event->hw.config = ppmu->xlate_event(ev);
+ if (!(event->hw.config & FSL_EMB_EVENT_VALID))
+ return ERR_PTR(-EINVAL);
+
+ /*
+ * If this is in a group, check if it can go on with all the
+ * other hardware events in the group. We assume the event
+ * hasn't been linked into its leader's sibling list at this point.
+ */
+ n = 0;
+ if (event->group_leader != event) {
+ n = collect_events(event->group_leader,
+ ppmu->n_counter - 1, events);
+ if (n < 0)
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) {
+ num_restricted = 0;
+ for (i = 0; i < n; i++) {
+ if (events[i]->hw.config & FSL_EMB_EVENT_RESTRICTED)
+ num_restricted++;
+ }
+
+ if (num_restricted >= ppmu->n_restricted)
+ return ERR_PTR(-EINVAL);
+ }
+
+ event->hw.idx = -1;
+
+ event->hw.config_base = PMLCA_CE | PMLCA_FCM1 |
+ (u32)((ev << 16) & PMLCA_EVENT_MASK);
+
+ if (event->attr.exclude_user)
+ event->hw.config_base |= PMLCA_FCU;
+ if (event->attr.exclude_kernel)
+ event->hw.config_base |= PMLCA_FCS;
+ if (event->attr.exclude_idle)
+ return ERR_PTR(-ENOTSUPP);
+
+ event->hw.last_period = event->hw.sample_period;
+ atomic64_set(&event->hw.period_left, event->hw.last_period);
+
+ /*
+ * See if we need to reserve the PMU.
+ * If no events are currently in use, then we have to take a
+ * mutex to ensure that we don't race with another task doing
+ * reserve_pmc_hardware or release_pmc_hardware.
+ */
+ err = 0;
+ if (!atomic_inc_not_zero(&num_events)) {
+ mutex_lock(&pmc_reserve_mutex);
+ if (atomic_read(&num_events) == 0 &&
+ reserve_pmc_hardware(perf_event_interrupt))
+ err = -EBUSY;
+ else
+ atomic_inc(&num_events);
+ mutex_unlock(&pmc_reserve_mutex);
+
+ mtpmr(PMRN_PMGC0, PMGC0_FAC);
+ isync();
+ }
+ event->destroy = hw_perf_event_destroy;
+
+ if (err)
+ return ERR_PTR(err);
+ return &fsl_emb_pmu;
+}
+
+/*
+ * A counter has overflowed; update its count and record
+ * things if requested. Note that interrupts are hard-disabled
+ * here so there is no possibility of being interrupted.
+ */
+static void record_and_restart(struct perf_event *event, unsigned long val,
+ struct pt_regs *regs, int nmi)
+{
+ u64 period = event->hw.sample_period;
+ s64 prev, delta, left;
+ int record = 0;
+
+ /* we don't have to worry about interrupts here */
+ prev = atomic64_read(&event->hw.prev_count);
+ delta = (val - prev) & 0xfffffffful;
+ atomic64_add(delta, &event->count);
+
+ /*
+ * See if the total period for this event has expired,
+ * and update for the next period.
+ */
+ val = 0;
+ left = atomic64_read(&event->hw.period_left) - delta;
+ if (period) {
+ if (left <= 0) {
+ left += period;
+ if (left <= 0)
+ left = period;
+ record = 1;
+ }
+ if (left < 0x80000000LL)
+ val = 0x80000000LL - left;
+ }
+
+ /*
+ * Finally record data if requested.
+ */
+ if (record) {
+ struct perf_sample_data data = {
+ .period = event->hw.last_period,
+ };
+
+ if (perf_event_overflow(event, nmi, &data, regs)) {
+ /*
+ * Interrupts are coming too fast - throttle them
+ * by setting the event to 0, so it will be
+ * at least 2^30 cycles until the next interrupt
+ * (assuming each event counts at most 2 counts
+ * per cycle).
+ */
+ val = 0;
+ left = ~0ULL >> 1;
+ }
+ }
+
+ write_pmc(event->hw.idx, val);
+ atomic64_set(&event->hw.prev_count, val);
+ atomic64_set(&event->hw.period_left, left);
+ perf_event_update_userpage(event);
+}
+
+static void perf_event_interrupt(struct pt_regs *regs)
+{
+ int i;
+ struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+ struct perf_event *event;
+ unsigned long val;
+ int found = 0;
+ int nmi;
+
+ nmi = perf_intr_is_nmi(regs);
+ if (nmi)
+ nmi_enter();
+ else
+ irq_enter();
+
+ for (i = 0; i < ppmu->n_counter; ++i) {
+ event = cpuhw->event[i];
+
+ val = read_pmc(i);
+ if ((int)val < 0) {
+ if (event) {
+ /* event has overflowed */
+ found = 1;
+ record_and_restart(event, val, regs, nmi);
+ } else {
+ /*
+ * Disabled counter is negative,
+ * reset it just in case.
+ */
+ write_pmc(i, 0);
+ }
+ }
+ }
+
+ /* PMM will keep counters frozen until we return from the interrupt. */
+ mtmsr(mfmsr() | MSR_PMM);
+ mtpmr(PMRN_PMGC0, PMGC0_PMIE | PMGC0_FCECE);
+ isync();
+
+ if (nmi)
+ nmi_exit();
+ else
+ irq_exit();
+}
+
+void hw_perf_event_setup(int cpu)
+{
+ struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+ memset(cpuhw, 0, sizeof(*cpuhw));
+}
+
+int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu)
+{
+ if (ppmu)
+ return -EBUSY; /* something's already registered */
+
+ ppmu = pmu;
+ pr_info("%s performance monitor hardware support registered\n",
+ pmu->name);
+
+ return 0;
+}
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 425451453e9..ab3e392ac63 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -107,6 +107,7 @@ EXPORT_SYMBOL(giveup_altivec);
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_VSX
EXPORT_SYMBOL(giveup_vsx);
+EXPORT_SYMBOL_GPL(__giveup_vsx);
#endif /* CONFIG_VSX */
#ifdef CONFIG_SPE
EXPORT_SYMBOL(giveup_spe);
diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c
index 1ed3b8d7981..c8ae3714e79 100644
--- a/arch/powerpc/kernel/proc_powerpc.c
+++ b/arch/powerpc/kernel/proc_powerpc.c
@@ -19,7 +19,6 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
-#include <linux/slab.h>
#include <linux/kernel.h>
#include <asm/machdep.h>
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 43238b2054b..05131d634e7 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -43,6 +43,7 @@
#include <asm/smp.h>
#include <asm/system.h>
#include <asm/mmu.h>
+#include <asm/paca.h>
#include <asm/pgtable.h>
#include <asm/pci.h>
#include <asm/iommu.h>
@@ -721,6 +722,8 @@ void __init early_init_devtree(void *params)
* FIXME .. and the initrd too? */
move_device_tree();
+ allocate_pacas();
+
DBG("Scanning CPUs ...\n");
/* Retreive CPU related informations from the flat tree
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 5f306c4946e..97d4bd9442d 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -653,6 +653,7 @@ static void __init early_cmdline_parse(void)
#else
#define OV5_CMO 0x00
#endif
+#define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */
/* Option Vector 6: IBM PAPR hints */
#define OV6_LINUX 0x02 /* Linux is our OS */
@@ -706,7 +707,7 @@ static unsigned char ibm_architecture_vec[] = {
OV5_DONATE_DEDICATE_CPU | OV5_MSI,
0,
OV5_CMO,
- 0,
+ OV5_TYPE1_AFFINITY,
0,
0,
0,
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index d9b05866615..ed2cfe17d25 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -940,7 +940,7 @@ static int del_instruction_bp(struct task_struct *child, int slot)
{
switch (slot) {
case 1:
- if (child->thread.iac1 == 0)
+ if ((child->thread.dbcr0 & DBCR0_IAC1) == 0)
return -ENOENT;
if (dbcr_iac_range(child) & DBCR_IAC12MODE) {
@@ -952,7 +952,7 @@ static int del_instruction_bp(struct task_struct *child, int slot)
child->thread.dbcr0 &= ~DBCR0_IAC1;
break;
case 2:
- if (child->thread.iac2 == 0)
+ if ((child->thread.dbcr0 & DBCR0_IAC2) == 0)
return -ENOENT;
if (dbcr_iac_range(child) & DBCR_IAC12MODE)
@@ -963,7 +963,7 @@ static int del_instruction_bp(struct task_struct *child, int slot)
break;
#if CONFIG_PPC_ADV_DEBUG_IACS > 2
case 3:
- if (child->thread.iac3 == 0)
+ if ((child->thread.dbcr0 & DBCR0_IAC3) == 0)
return -ENOENT;
if (dbcr_iac_range(child) & DBCR_IAC34MODE) {
@@ -975,7 +975,7 @@ static int del_instruction_bp(struct task_struct *child, int slot)
child->thread.dbcr0 &= ~DBCR0_IAC3;
break;
case 4:
- if (child->thread.iac4 == 0)
+ if ((child->thread.dbcr0 & DBCR0_IAC4) == 0)
return -ENOENT;
if (dbcr_iac_range(child) & DBCR_IAC34MODE)
@@ -1054,7 +1054,7 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
static int del_dac(struct task_struct *child, int slot)
{
if (slot == 1) {
- if (child->thread.dac1 == 0)
+ if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0)
return -ENOENT;
child->thread.dac1 = 0;
@@ -1070,7 +1070,7 @@ static int del_dac(struct task_struct *child, int slot)
child->thread.dvc1 = 0;
#endif
} else if (slot == 2) {
- if (child->thread.dac1 == 0)
+ if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0)
return -ENOENT;
#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index fd0d29493fd..74367841615 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -23,6 +23,7 @@
#include <linux/completion.h>
#include <linux/cpumask.h>
#include <linux/lmb.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/rtas.h>
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index a85117d5c9a..bfc2abafac4 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 2e4832ab210..4190eae7850 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -20,6 +20,7 @@
#include <linux/spinlock.h>
#include <linux/cpu.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 03dd6a24819..48f0a008b20 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -36,6 +36,7 @@
#include <linux/lmb.h>
#include <linux/of_platform.h>
#include <asm/io.h>
+#include <asm/paca.h>
#include <asm/prom.h>
#include <asm/processor.h>
#include <asm/vdso_datapage.h>
@@ -493,6 +494,8 @@ void __init smp_setup_cpu_maps(void)
* here will have to be reworked
*/
cpu_init_thread_core_maps(nthreads);
+
+ free_unused_pacas();
}
#endif /* CONFIG_SMP */
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index b152de3e64d..8f58986c2ad 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -39,7 +39,6 @@
#include <asm/serial.h>
#include <asm/udbg.h>
#include <asm/mmu_context.h>
-#include <asm/swiotlb.h>
#include "setup.h"
@@ -343,11 +342,6 @@ void __init setup_arch(char **cmdline_p)
ppc_md.setup_arch();
if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
-#ifdef CONFIG_SWIOTLB
- if (ppc_swiotlb_enable)
- swiotlb_init(1);
-#endif
-
paging_init();
/* Initialize the MMU context management stuff */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 6568406b2a3..914389158a9 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -61,7 +61,6 @@
#include <asm/xmon.h>
#include <asm/udbg.h>
#include <asm/kexec.h>
-#include <asm/swiotlb.h>
#include <asm/mmu_context.h>
#include "setup.h"
@@ -144,9 +143,9 @@ early_param("smt-enabled", early_smt_enabled);
#endif /* CONFIG_SMP */
/* Put the paca pointer into r13 and SPRG_PACA */
-void __init setup_paca(int cpu)
+static void __init setup_paca(struct paca_struct *new_paca)
{
- local_paca = &paca[cpu];
+ local_paca = new_paca;
mtspr(SPRN_SPRG_PACA, local_paca);
#ifdef CONFIG_PPC_BOOK3E
mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
@@ -176,14 +175,12 @@ void __init early_setup(unsigned long dt_ptr)
{
/* -------- printk is _NOT_ safe to use here ! ------- */
- /* Fill in any unititialised pacas */
- initialise_pacas();
-
/* Identify CPU type */
identify_cpu(0, mfspr(SPRN_PVR));
/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
- setup_paca(0);
+ initialise_paca(&boot_paca, 0);
+ setup_paca(&boot_paca);
/* Initialize lockdep early or else spinlocks will blow */
lockdep_init();
@@ -203,7 +200,7 @@ void __init early_setup(unsigned long dt_ptr)
early_init_devtree(__va(dt_ptr));
/* Now we know the logical id of our boot cpu, setup the paca. */
- setup_paca(boot_cpuid);
+ setup_paca(&paca[boot_cpuid]);
/* Fix up paca fields required for the boot cpu */
get_paca()->cpu_start = 1;
@@ -543,11 +540,6 @@ void __init setup_arch(char **cmdline_p)
if (ppc_md.setup_arch)
ppc_md.setup_arch();
-#ifdef CONFIG_SWIOTLB
- if (ppc_swiotlb_enable)
- swiotlb_init(1);
-#endif
-
paging_init();
/* Initialize the MMU context management stuff */
diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c
index a5e54526403..03e45c4a9ef 100644
--- a/arch/powerpc/kernel/smp-tbsync.c
+++ b/arch/powerpc/kernel/smp-tbsync.c
@@ -10,6 +10,7 @@
#include <linux/smp.h>
#include <linux/unistd.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/smp.h>
#include <asm/time.h>
diff --git a/arch/powerpc/kernel/softemu8xx.c b/arch/powerpc/kernel/softemu8xx.c
index 23c8c5e7dc4..af0e8290b4f 100644
--- a/arch/powerpc/kernel/softemu8xx.c
+++ b/arch/powerpc/kernel/softemu8xx.c
@@ -21,7 +21,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/interrupt.h>
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index c5a4732bcc4..19471a1cef1 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -41,6 +41,7 @@
#include <linux/ptrace.h>
#include <linux/elf.h>
#include <linux/ipc.h>
+#include <linux/slab.h>
#include <asm/ptrace.h>
#include <asm/types.h>
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 3370e62e43d..f2496f2faec 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -42,100 +42,6 @@
#include <asm/time.h>
#include <asm/unistd.h>
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-int sys_ipc(uint call, int first, unsigned long second, long third,
- void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- ret = -ENOSYS;
- switch (call) {
- case SEMOP:
- ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
- (unsigned)second, NULL);
- break;
- case SEMTIMEDOP:
- ret = sys_semtimedop(first, (struct sembuf __user *)ptr,
- (unsigned)second,
- (const struct timespec __user *) fifth);
- break;
- case SEMGET:
- ret = sys_semget (first, (int)second, third);
- break;
- case SEMCTL: {
- union semun fourth;
-
- ret = -EINVAL;
- if (!ptr)
- break;
- if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr)))
- break;
- ret = sys_semctl(first, (int)second, third, fourth);
- break;
- }
- case MSGSND:
- ret = sys_msgsnd(first, (struct msgbuf __user *)ptr,
- (size_t)second, third);
- break;
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
-
- ret = -EINVAL;
- if (!ptr)
- break;
- if ((ret = copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof (tmp)) ? -EFAULT : 0))
- break;
- ret = sys_msgrcv(first, tmp.msgp, (size_t) second,
- tmp.msgtyp, third);
- break;
- }
- default:
- ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
- (size_t)second, fifth, third);
- break;
- }
- break;
- case MSGGET:
- ret = sys_msgget((key_t)first, (int)second);
- break;
- case MSGCTL:
- ret = sys_msgctl(first, (int)second,
- (struct msqid_ds __user *)ptr);
- break;
- case SHMAT: {
- ulong raddr;
- ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr);
- if (ret)
- break;
- ret = put_user(raddr, (ulong __user *) third);
- break;
- }
- case SHMDT:
- ret = sys_shmdt((char __user *)ptr);
- break;
- case SHMGET:
- ret = sys_shmget(first, (size_t)second, third);
- break;
- case SHMCTL:
- ret = sys_shmctl(first, (int)second,
- (struct shmid_ds __user *)ptr);
- break;
- }
-
- return ret;
-}
-
static inline unsigned long do_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long off, int shift)
@@ -210,76 +116,6 @@ long ppc64_personality(unsigned long personality)
}
#endif
-#ifdef CONFIG_PPC64
-#define OVERRIDE_MACHINE (personality(current->personality) == PER_LINUX32)
-#else
-#define OVERRIDE_MACHINE 0
-#endif
-
-static inline int override_machine(char __user *mach)
-{
- if (OVERRIDE_MACHINE) {
- /* change ppc64 to ppc */
- if (__put_user(0, mach+3) || __put_user(0, mach+4))
- return -EFAULT;
- }
- return 0;
-}
-
-long ppc_newuname(struct new_utsname __user * name)
-{
- int err = 0;
-
- down_read(&uts_sem);
- if (copy_to_user(name, utsname(), sizeof(*name)))
- err = -EFAULT;
- up_read(&uts_sem);
- if (!err)
- err = override_machine(name->machine);
- return err;
-}
-
-int sys_uname(struct old_utsname __user *name)
-{
- int err = 0;
-
- down_read(&uts_sem);
- if (copy_to_user(name, utsname(), sizeof(*name)))
- err = -EFAULT;
- up_read(&uts_sem);
- if (!err)
- err = override_machine(name->machine);
- return err;
-}
-
-int sys_olduname(struct oldold_utsname __user *name)
-{
- int error;
-
- if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
- error = __copy_to_user(&name->sysname, &utsname()->sysname,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename, &utsname()->nodename,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->release, &utsname()->release,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->release + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->version, &utsname()->version,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->version + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine, &utsname()->machine,
- __OLD_UTS_LEN);
- error |= override_machine(name->machine);
- up_read(&uts_sem);
-
- return error? -EFAULT: 0;
-}
-
long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
u32 len_high, u32 len_low)
{
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 696626a2e83..29d128eb6c4 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -21,7 +21,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/interrupt.h>
#include <linux/init.h>
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 77f64218abf..82237176a2a 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/console.h>
#include <linux/module.h>
#include <linux/mm.h>
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index f4d1b55aa70..689a57c2ac8 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -18,6 +18,7 @@
*/
#include <linux/kvm_host.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <asm/reg.h>
diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulate.c
index 61af58fcece..65ea083a5b2 100644
--- a/arch/powerpc/kvm/44x_emulate.c
+++ b/arch/powerpc/kvm/44x_emulate.c
@@ -65,13 +65,14 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
*/
switch (dcrn) {
case DCRN_CPR0_CONFIG_ADDR:
- vcpu->arch.gpr[rt] = vcpu->arch.cpr0_cfgaddr;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.cpr0_cfgaddr);
break;
case DCRN_CPR0_CONFIG_DATA:
local_irq_disable();
mtdcr(DCRN_CPR0_CONFIG_ADDR,
vcpu->arch.cpr0_cfgaddr);
- vcpu->arch.gpr[rt] = mfdcr(DCRN_CPR0_CONFIG_DATA);
+ kvmppc_set_gpr(vcpu, rt,
+ mfdcr(DCRN_CPR0_CONFIG_DATA));
local_irq_enable();
break;
default:
@@ -93,11 +94,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
/* emulate some access in kernel */
switch (dcrn) {
case DCRN_CPR0_CONFIG_ADDR:
- vcpu->arch.cpr0_cfgaddr = vcpu->arch.gpr[rs];
+ vcpu->arch.cpr0_cfgaddr = kvmppc_get_gpr(vcpu, rs);
break;
default:
run->dcr.dcrn = dcrn;
- run->dcr.data = vcpu->arch.gpr[rs];
+ run->dcr.data = kvmppc_get_gpr(vcpu, rs);
run->dcr.is_write = 1;
vcpu->arch.dcr_needed = 1;
kvmppc_account_exit(vcpu, DCR_EXITS);
@@ -146,13 +147,13 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
switch (sprn) {
case SPRN_PID:
- kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break;
+ kvmppc_set_pid(vcpu, kvmppc_get_gpr(vcpu, rs)); break;
case SPRN_MMUCR:
- vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.mmucr = kvmppc_get_gpr(vcpu, rs); break;
case SPRN_CCR0:
- vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.ccr0 = kvmppc_get_gpr(vcpu, rs); break;
case SPRN_CCR1:
- vcpu->arch.ccr1 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.ccr1 = kvmppc_get_gpr(vcpu, rs); break;
default:
emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
}
@@ -167,13 +168,13 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
switch (sprn) {
case SPRN_PID:
- vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.pid); break;
case SPRN_MMUCR:
- vcpu->arch.gpr[rt] = vcpu->arch.mmucr; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.mmucr); break;
case SPRN_CCR0:
- vcpu->arch.gpr[rt] = vcpu->arch.ccr0; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr0); break;
case SPRN_CCR1:
- vcpu->arch.gpr[rt] = vcpu->arch.ccr1; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr1); break;
default:
emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
}
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index ff3cb63b811..2570fcc7665 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -439,7 +439,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
struct kvmppc_44x_tlbe *tlbe;
unsigned int gtlb_index;
- gtlb_index = vcpu->arch.gpr[ra];
+ gtlb_index = kvmppc_get_gpr(vcpu, ra);
if (gtlb_index > KVM44x_GUEST_TLB_SIZE) {
printk("%s: index %d\n", __func__, gtlb_index);
kvmppc_dump_vcpu(vcpu);
@@ -455,15 +455,15 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
switch (ws) {
case PPC44x_TLB_PAGEID:
tlbe->tid = get_mmucr_stid(vcpu);
- tlbe->word0 = vcpu->arch.gpr[rs];
+ tlbe->word0 = kvmppc_get_gpr(vcpu, rs);
break;
case PPC44x_TLB_XLAT:
- tlbe->word1 = vcpu->arch.gpr[rs];
+ tlbe->word1 = kvmppc_get_gpr(vcpu, rs);
break;
case PPC44x_TLB_ATTRIB:
- tlbe->word2 = vcpu->arch.gpr[rs];
+ tlbe->word2 = kvmppc_get_gpr(vcpu, rs);
break;
default:
@@ -500,18 +500,20 @@ int kvmppc_44x_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb, u8 rc)
unsigned int as = get_mmucr_sts(vcpu);
unsigned int pid = get_mmucr_stid(vcpu);
- ea = vcpu->arch.gpr[rb];
+ ea = kvmppc_get_gpr(vcpu, rb);
if (ra)
- ea += vcpu->arch.gpr[ra];
+ ea += kvmppc_get_gpr(vcpu, ra);
gtlb_index = kvmppc_44x_tlb_index(vcpu, ea, pid, as);
if (rc) {
+ u32 cr = kvmppc_get_cr(vcpu);
+
if (gtlb_index < 0)
- vcpu->arch.cr &= ~0x20000000;
+ kvmppc_set_cr(vcpu, cr & ~0x20000000);
else
- vcpu->arch.cr |= 0x20000000;
+ kvmppc_set_cr(vcpu, cr | 0x20000000);
}
- vcpu->arch.gpr[rt] = gtlb_index;
+ kvmppc_set_gpr(vcpu, rt, gtlb_index);
kvmppc_set_exit_type(vcpu, EMULATED_TLBSX_EXITS);
return EMULATE_DONE;
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index fe037fdaf1b..60624cc9f4d 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -20,6 +20,7 @@ config KVM
bool
select PREEMPT_NOTIFIERS
select ANON_INODES
+ select KVM_MMIO
config KVM_BOOK3S_64_HANDLER
bool
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 3e294bd9b8c..604af29b71e 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -26,6 +26,7 @@
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
#include <asm/mmu_context.h>
+#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/vmalloc.h>
@@ -33,12 +34,9 @@
/* #define EXIT_DEBUG */
/* #define EXIT_DEBUG_SIMPLE */
+/* #define DEBUG_EXT */
-/* Without AGGRESSIVE_DEC we only fire off a DEC interrupt when DEC turns 0.
- * When set, we retrigger a DEC interrupt after that if DEC <= 0.
- * PPC32 Linux runs faster without AGGRESSIVE_DEC, PPC64 Linux requires it. */
-
-/* #define AGGRESSIVE_DEC */
+static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "exits", VCPU_STAT(sum_exits) },
@@ -72,16 +70,24 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
memcpy(get_paca()->kvm_slb, to_book3s(vcpu)->slb_shadow, sizeof(get_paca()->kvm_slb));
+ memcpy(&get_paca()->shadow_vcpu, &to_book3s(vcpu)->shadow_vcpu,
+ sizeof(get_paca()->shadow_vcpu));
get_paca()->kvm_slb_max = to_book3s(vcpu)->slb_shadow_max;
}
void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
{
memcpy(to_book3s(vcpu)->slb_shadow, get_paca()->kvm_slb, sizeof(get_paca()->kvm_slb));
+ memcpy(&to_book3s(vcpu)->shadow_vcpu, &get_paca()->shadow_vcpu,
+ sizeof(get_paca()->shadow_vcpu));
to_book3s(vcpu)->slb_shadow_max = get_paca()->kvm_slb_max;
+
+ kvmppc_giveup_ext(vcpu, MSR_FP);
+ kvmppc_giveup_ext(vcpu, MSR_VEC);
+ kvmppc_giveup_ext(vcpu, MSR_VSX);
}
-#if defined(AGGRESSIVE_DEC) || defined(EXIT_DEBUG)
+#if defined(EXIT_DEBUG)
static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
{
u64 jd = mftb() - vcpu->arch.dec_jiffies;
@@ -89,6 +95,23 @@ static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
}
#endif
+static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.shadow_msr = vcpu->arch.msr;
+ /* Guest MSR values */
+ vcpu->arch.shadow_msr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE |
+ MSR_BE | MSR_DE;
+ /* Process MSR values */
+ vcpu->arch.shadow_msr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR |
+ MSR_EE;
+ /* External providers the guest reserved */
+ vcpu->arch.shadow_msr |= (vcpu->arch.msr & vcpu->arch.guest_owned_ext);
+ /* 64-bit Process MSR values */
+#ifdef CONFIG_PPC_BOOK3S_64
+ vcpu->arch.shadow_msr |= MSR_ISF | MSR_HV;
+#endif
+}
+
void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
{
ulong old_msr = vcpu->arch.msr;
@@ -96,12 +119,10 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
#ifdef EXIT_DEBUG
printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
#endif
+
msr &= to_book3s(vcpu)->msr_mask;
vcpu->arch.msr = msr;
- vcpu->arch.shadow_msr = msr | MSR_USER32;
- vcpu->arch.shadow_msr &= ( MSR_VEC | MSR_VSX | MSR_FP | MSR_FE0 |
- MSR_USER64 | MSR_SE | MSR_BE | MSR_DE |
- MSR_FE1);
+ kvmppc_recalc_shadow_msr(vcpu);
if (msr & (MSR_WE|MSR_POW)) {
if (!vcpu->arch.pending_exceptions) {
@@ -125,11 +146,10 @@ void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags)
vcpu->arch.mmu.reset_msr(vcpu);
}
-void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
+static int kvmppc_book3s_vec2irqprio(unsigned int vec)
{
unsigned int prio;
- vcpu->stat.queue_intr++;
switch (vec) {
case 0x100: prio = BOOK3S_IRQPRIO_SYSTEM_RESET; break;
case 0x200: prio = BOOK3S_IRQPRIO_MACHINE_CHECK; break;
@@ -149,15 +169,31 @@ void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
default: prio = BOOK3S_IRQPRIO_MAX; break;
}
- set_bit(prio, &vcpu->arch.pending_exceptions);
+ return prio;
+}
+
+static void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
+ unsigned int vec)
+{
+ clear_bit(kvmppc_book3s_vec2irqprio(vec),
+ &vcpu->arch.pending_exceptions);
+}
+
+void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
+{
+ vcpu->stat.queue_intr++;
+
+ set_bit(kvmppc_book3s_vec2irqprio(vec),
+ &vcpu->arch.pending_exceptions);
#ifdef EXIT_DEBUG
printk(KERN_INFO "Queueing interrupt %x\n", vec);
#endif
}
-void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
+void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags)
{
+ to_book3s(vcpu)->prog_flags = flags;
kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM);
}
@@ -171,6 +207,11 @@ int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions);
}
+void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
+{
+ kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
+}
+
void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
@@ -181,6 +222,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
{
int deliver = 1;
int vec = 0;
+ ulong flags = 0ULL;
switch (priority) {
case BOOK3S_IRQPRIO_DECREMENTER:
@@ -214,6 +256,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
break;
case BOOK3S_IRQPRIO_PROGRAM:
vec = BOOK3S_INTERRUPT_PROGRAM;
+ flags = to_book3s(vcpu)->prog_flags;
break;
case BOOK3S_IRQPRIO_VSX:
vec = BOOK3S_INTERRUPT_VSX;
@@ -244,7 +287,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
#endif
if (deliver)
- kvmppc_inject_interrupt(vcpu, vec, 0ULL);
+ kvmppc_inject_interrupt(vcpu, vec, flags);
return deliver;
}
@@ -254,21 +297,15 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
unsigned long *pending = &vcpu->arch.pending_exceptions;
unsigned int priority;
- /* XXX be more clever here - no need to mftb() on every entry */
- /* Issue DEC again if it's still active */
-#ifdef AGGRESSIVE_DEC
- if (vcpu->arch.msr & MSR_EE)
- if (kvmppc_get_dec(vcpu) & 0x80000000)
- kvmppc_core_queue_dec(vcpu);
-#endif
-
#ifdef EXIT_DEBUG
if (vcpu->arch.pending_exceptions)
printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
#endif
priority = __ffs(*pending);
while (priority <= (sizeof(unsigned int) * 8)) {
- if (kvmppc_book3s_irqprio_deliver(vcpu, priority)) {
+ if (kvmppc_book3s_irqprio_deliver(vcpu, priority) &&
+ (priority != BOOK3S_IRQPRIO_DECREMENTER)) {
+ /* DEC interrupts get cleared by mtdec */
clear_bit(priority, &vcpu->arch.pending_exceptions);
break;
}
@@ -503,14 +540,14 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
/* Page not found in guest PTE entries */
vcpu->arch.dear = vcpu->arch.fault_dear;
to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr;
- vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
+ vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL);
kvmppc_book3s_queue_irqprio(vcpu, vec);
} else if (page_found == -EPERM) {
/* Storage protection */
vcpu->arch.dear = vcpu->arch.fault_dear;
to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr & ~DSISR_NOHPTE;
to_book3s(vcpu)->dsisr |= DSISR_PROTFAULT;
- vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
+ vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL);
kvmppc_book3s_queue_irqprio(vcpu, vec);
} else if (page_found == -EINVAL) {
/* Page not found in guest SLB */
@@ -532,13 +569,122 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
r = kvmppc_emulate_mmio(run, vcpu);
if ( r == RESUME_HOST_NV )
r = RESUME_HOST;
- if ( r == RESUME_GUEST_NV )
- r = RESUME_GUEST;
}
return r;
}
+static inline int get_fpr_index(int i)
+{
+#ifdef CONFIG_VSX
+ i *= 2;
+#endif
+ return i;
+}
+
+/* Give up external provider (FPU, Altivec, VSX) */
+static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
+{
+ struct thread_struct *t = &current->thread;
+ u64 *vcpu_fpr = vcpu->arch.fpr;
+ u64 *vcpu_vsx = vcpu->arch.vsr;
+ u64 *thread_fpr = (u64*)t->fpr;
+ int i;
+
+ if (!(vcpu->arch.guest_owned_ext & msr))
+ return;
+
+#ifdef DEBUG_EXT
+ printk(KERN_INFO "Giving up ext 0x%lx\n", msr);
+#endif
+
+ switch (msr) {
+ case MSR_FP:
+ giveup_fpu(current);
+ for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
+ vcpu_fpr[i] = thread_fpr[get_fpr_index(i)];
+
+ vcpu->arch.fpscr = t->fpscr.val;
+ break;
+ case MSR_VEC:
+#ifdef CONFIG_ALTIVEC
+ giveup_altivec(current);
+ memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr));
+ vcpu->arch.vscr = t->vscr;
+#endif
+ break;
+ case MSR_VSX:
+#ifdef CONFIG_VSX
+ __giveup_vsx(current);
+ for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr); i++)
+ vcpu_vsx[i] = thread_fpr[get_fpr_index(i) + 1];
+#endif
+ break;
+ default:
+ BUG();
+ }
+
+ vcpu->arch.guest_owned_ext &= ~msr;
+ current->thread.regs->msr &= ~msr;
+ kvmppc_recalc_shadow_msr(vcpu);
+}
+
+/* Handle external providers (FPU, Altivec, VSX) */
+static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
+ ulong msr)
+{
+ struct thread_struct *t = &current->thread;
+ u64 *vcpu_fpr = vcpu->arch.fpr;
+ u64 *vcpu_vsx = vcpu->arch.vsr;
+ u64 *thread_fpr = (u64*)t->fpr;
+ int i;
+
+ if (!(vcpu->arch.msr & msr)) {
+ kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+ return RESUME_GUEST;
+ }
+
+#ifdef DEBUG_EXT
+ printk(KERN_INFO "Loading up ext 0x%lx\n", msr);
+#endif
+
+ current->thread.regs->msr |= msr;
+
+ switch (msr) {
+ case MSR_FP:
+ for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
+ thread_fpr[get_fpr_index(i)] = vcpu_fpr[i];
+
+ t->fpscr.val = vcpu->arch.fpscr;
+ t->fpexc_mode = 0;
+ kvmppc_load_up_fpu();
+ break;
+ case MSR_VEC:
+#ifdef CONFIG_ALTIVEC
+ memcpy(t->vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
+ t->vscr = vcpu->arch.vscr;
+ t->vrsave = -1;
+ kvmppc_load_up_altivec();
+#endif
+ break;
+ case MSR_VSX:
+#ifdef CONFIG_VSX
+ for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr); i++)
+ thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i];
+ kvmppc_load_up_vsx();
+#endif
+ break;
+ default:
+ BUG();
+ }
+
+ vcpu->arch.guest_owned_ext |= msr;
+
+ kvmppc_recalc_shadow_msr(vcpu);
+
+ return RESUME_GUEST;
+}
+
int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int exit_nr)
{
@@ -563,7 +709,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
case BOOK3S_INTERRUPT_INST_STORAGE:
vcpu->stat.pf_instruc++;
/* only care about PTEG not found errors, but leave NX alone */
- if (vcpu->arch.shadow_msr & 0x40000000) {
+ if (vcpu->arch.shadow_srr1 & 0x40000000) {
r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.pc, exit_nr);
vcpu->stat.sp_instruc++;
} else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
@@ -575,7 +721,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
*/
kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
} else {
- vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x58000000);
+ vcpu->arch.msr |= vcpu->arch.shadow_srr1 & 0x58000000;
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
r = RESUME_GUEST;
@@ -621,6 +767,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
case BOOK3S_INTERRUPT_PROGRAM:
{
enum emulation_result er;
+ ulong flags;
+
+ flags = vcpu->arch.shadow_srr1 & 0x1f0000ull;
if (vcpu->arch.msr & MSR_PR) {
#ifdef EXIT_DEBUG
@@ -628,7 +777,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
#endif
if ((vcpu->arch.last_inst & 0xff0007ff) !=
(INS_DCBZ & 0xfffffff7)) {
- kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+ kvmppc_core_queue_program(vcpu, flags);
r = RESUME_GUEST;
break;
}
@@ -638,12 +787,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
er = kvmppc_emulate_instruction(run, vcpu);
switch (er) {
case EMULATE_DONE:
- r = RESUME_GUEST;
+ r = RESUME_GUEST_NV;
break;
case EMULATE_FAIL:
printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
__func__, vcpu->arch.pc, vcpu->arch.last_inst);
- kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+ kvmppc_core_queue_program(vcpu, flags);
r = RESUME_GUEST;
break;
default:
@@ -653,23 +802,30 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
}
case BOOK3S_INTERRUPT_SYSCALL:
#ifdef EXIT_DEBUG
- printk(KERN_INFO "Syscall Nr %d\n", (int)vcpu->arch.gpr[0]);
+ printk(KERN_INFO "Syscall Nr %d\n", (int)kvmppc_get_gpr(vcpu, 0));
#endif
vcpu->stat.syscall_exits++;
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
r = RESUME_GUEST;
break;
- case BOOK3S_INTERRUPT_MACHINE_CHECK:
case BOOK3S_INTERRUPT_FP_UNAVAIL:
- case BOOK3S_INTERRUPT_TRACE:
+ r = kvmppc_handle_ext(vcpu, exit_nr, MSR_FP);
+ break;
case BOOK3S_INTERRUPT_ALTIVEC:
+ r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VEC);
+ break;
case BOOK3S_INTERRUPT_VSX:
+ r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VSX);
+ break;
+ case BOOK3S_INTERRUPT_MACHINE_CHECK:
+ case BOOK3S_INTERRUPT_TRACE:
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
r = RESUME_GUEST;
break;
default:
/* Ugh - bork here! What did we get? */
- printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n", exit_nr, vcpu->arch.pc, vcpu->arch.shadow_msr);
+ printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n",
+ exit_nr, vcpu->arch.pc, vcpu->arch.shadow_srr1);
r = RESUME_HOST;
BUG();
break;
@@ -712,10 +868,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
int i;
regs->pc = vcpu->arch.pc;
- regs->cr = vcpu->arch.cr;
+ regs->cr = kvmppc_get_cr(vcpu);
regs->ctr = vcpu->arch.ctr;
regs->lr = vcpu->arch.lr;
- regs->xer = vcpu->arch.xer;
+ regs->xer = kvmppc_get_xer(vcpu);
regs->msr = vcpu->arch.msr;
regs->srr0 = vcpu->arch.srr0;
regs->srr1 = vcpu->arch.srr1;
@@ -729,7 +885,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
regs->sprg7 = vcpu->arch.sprg6;
for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
- regs->gpr[i] = vcpu->arch.gpr[i];
+ regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
return 0;
}
@@ -739,10 +895,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
int i;
vcpu->arch.pc = regs->pc;
- vcpu->arch.cr = regs->cr;
+ kvmppc_set_cr(vcpu, regs->cr);
vcpu->arch.ctr = regs->ctr;
vcpu->arch.lr = regs->lr;
- vcpu->arch.xer = regs->xer;
+ kvmppc_set_xer(vcpu, regs->xer);
kvmppc_set_msr(vcpu, regs->msr);
vcpu->arch.srr0 = regs->srr0;
vcpu->arch.srr1 = regs->srr1;
@@ -754,8 +910,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
vcpu->arch.sprg6 = regs->sprg5;
vcpu->arch.sprg7 = regs->sprg6;
- for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
- vcpu->arch.gpr[i] = regs->gpr[i];
+ for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
+ kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
return 0;
}
@@ -848,9 +1004,10 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
struct kvm_vcpu *vcpu;
ulong ga, ga_end;
int is_dirty = 0;
- int r, n;
+ int r;
+ unsigned long n;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
r = kvm_get_dirty_log(kvm, log, &is_dirty);
if (r)
@@ -858,7 +1015,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
/* If nothing is dirty, don't bother messing with page tables. */
if (is_dirty) {
- memslot = &kvm->memslots[log->slot];
+ memslot = &kvm->memslots->memslots[log->slot];
ga = memslot->base_gfn << PAGE_SHIFT;
ga_end = ga + (memslot->npages << PAGE_SHIFT);
@@ -866,13 +1023,13 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
kvm_for_each_vcpu(n, vcpu, kvm)
kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
- n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+ n = kvm_dirty_bitmap_bytes(memslot);
memset(memslot->dirty_bitmap, 0, n);
}
r = 0;
out:
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return r;
}
@@ -910,6 +1067,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
vcpu->arch.trampoline_lowmem = kvmppc_trampoline_lowmem;
vcpu->arch.trampoline_enter = kvmppc_trampoline_enter;
vcpu->arch.highmem_handler = (ulong)kvmppc_handler_highmem;
+ vcpu->arch.rmcall = *(ulong*)kvmppc_rmcall;
vcpu->arch.shadow_msr = MSR_USER64;
@@ -943,6 +1101,10 @@ extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
{
int ret;
+ struct thread_struct ext_bkp;
+ bool save_vec = current->thread.used_vr;
+ bool save_vsx = current->thread.used_vsr;
+ ulong ext_msr;
/* No need to go into the guest when all we do is going out */
if (signal_pending(current)) {
@@ -950,6 +1112,35 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
return -EINTR;
}
+ /* Save FPU state in stack */
+ if (current->thread.regs->msr & MSR_FP)
+ giveup_fpu(current);
+ memcpy(ext_bkp.fpr, current->thread.fpr, sizeof(current->thread.fpr));
+ ext_bkp.fpscr = current->thread.fpscr;
+ ext_bkp.fpexc_mode = current->thread.fpexc_mode;
+
+#ifdef CONFIG_ALTIVEC
+ /* Save Altivec state in stack */
+ if (save_vec) {
+ if (current->thread.regs->msr & MSR_VEC)
+ giveup_altivec(current);
+ memcpy(ext_bkp.vr, current->thread.vr, sizeof(ext_bkp.vr));
+ ext_bkp.vscr = current->thread.vscr;
+ ext_bkp.vrsave = current->thread.vrsave;
+ }
+ ext_bkp.used_vr = current->thread.used_vr;
+#endif
+
+#ifdef CONFIG_VSX
+ /* Save VSX state in stack */
+ if (save_vsx && (current->thread.regs->msr & MSR_VSX))
+ __giveup_vsx(current);
+ ext_bkp.used_vsr = current->thread.used_vsr;
+#endif
+
+ /* Remember the MSR with disabled extensions */
+ ext_msr = current->thread.regs->msr;
+
/* XXX we get called with irq disabled - change that! */
local_irq_enable();
@@ -957,6 +1148,32 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
local_irq_disable();
+ current->thread.regs->msr = ext_msr;
+
+ /* Make sure we save the guest FPU/Altivec/VSX state */
+ kvmppc_giveup_ext(vcpu, MSR_FP);
+ kvmppc_giveup_ext(vcpu, MSR_VEC);
+ kvmppc_giveup_ext(vcpu, MSR_VSX);
+
+ /* Restore FPU state from stack */
+ memcpy(current->thread.fpr, ext_bkp.fpr, sizeof(ext_bkp.fpr));
+ current->thread.fpscr = ext_bkp.fpscr;
+ current->thread.fpexc_mode = ext_bkp.fpexc_mode;
+
+#ifdef CONFIG_ALTIVEC
+ /* Restore Altivec state from stack */
+ if (save_vec && current->thread.used_vr) {
+ memcpy(current->thread.vr, ext_bkp.vr, sizeof(ext_bkp.vr));
+ current->thread.vscr = ext_bkp.vscr;
+ current->thread.vrsave= ext_bkp.vrsave;
+ }
+ current->thread.used_vr = ext_bkp.used_vr;
+#endif
+
+#ifdef CONFIG_VSX
+ current->thread.used_vsr = ext_bkp.used_vsr;
+#endif
+
return ret;
}
diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c
index 1027eac6d47..2b0ee7e040c 100644
--- a/arch/powerpc/kvm/book3s_64_emulate.c
+++ b/arch/powerpc/kvm/book3s_64_emulate.c
@@ -65,11 +65,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
case 31:
switch (get_xop(inst)) {
case OP_31_XOP_MFMSR:
- vcpu->arch.gpr[get_rt(inst)] = vcpu->arch.msr;
+ kvmppc_set_gpr(vcpu, get_rt(inst), vcpu->arch.msr);
break;
case OP_31_XOP_MTMSRD:
{
- ulong rs = vcpu->arch.gpr[get_rs(inst)];
+ ulong rs = kvmppc_get_gpr(vcpu, get_rs(inst));
if (inst & 0x10000) {
vcpu->arch.msr &= ~(MSR_RI | MSR_EE);
vcpu->arch.msr |= rs & (MSR_RI | MSR_EE);
@@ -78,30 +78,30 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
break;
}
case OP_31_XOP_MTMSR:
- kvmppc_set_msr(vcpu, vcpu->arch.gpr[get_rs(inst)]);
+ kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst)));
break;
case OP_31_XOP_MFSRIN:
{
int srnum;
- srnum = (vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf;
+ srnum = (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf;
if (vcpu->arch.mmu.mfsrin) {
u32 sr;
sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
- vcpu->arch.gpr[get_rt(inst)] = sr;
+ kvmppc_set_gpr(vcpu, get_rt(inst), sr);
}
break;
}
case OP_31_XOP_MTSRIN:
vcpu->arch.mmu.mtsrin(vcpu,
- (vcpu->arch.gpr[get_rb(inst)] >> 28) & 0xf,
- vcpu->arch.gpr[get_rs(inst)]);
+ (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf,
+ kvmppc_get_gpr(vcpu, get_rs(inst)));
break;
case OP_31_XOP_TLBIE:
case OP_31_XOP_TLBIEL:
{
bool large = (inst & 0x00200000) ? true : false;
- ulong addr = vcpu->arch.gpr[get_rb(inst)];
+ ulong addr = kvmppc_get_gpr(vcpu, get_rb(inst));
vcpu->arch.mmu.tlbie(vcpu, addr, large);
break;
}
@@ -111,14 +111,16 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
if (!vcpu->arch.mmu.slbmte)
return EMULATE_FAIL;
- vcpu->arch.mmu.slbmte(vcpu, vcpu->arch.gpr[get_rs(inst)],
- vcpu->arch.gpr[get_rb(inst)]);
+ vcpu->arch.mmu.slbmte(vcpu,
+ kvmppc_get_gpr(vcpu, get_rs(inst)),
+ kvmppc_get_gpr(vcpu, get_rb(inst)));
break;
case OP_31_XOP_SLBIE:
if (!vcpu->arch.mmu.slbie)
return EMULATE_FAIL;
- vcpu->arch.mmu.slbie(vcpu, vcpu->arch.gpr[get_rb(inst)]);
+ vcpu->arch.mmu.slbie(vcpu,
+ kvmppc_get_gpr(vcpu, get_rb(inst)));
break;
case OP_31_XOP_SLBIA:
if (!vcpu->arch.mmu.slbia)
@@ -132,9 +134,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
} else {
ulong t, rb;
- rb = vcpu->arch.gpr[get_rb(inst)];
+ rb = kvmppc_get_gpr(vcpu, get_rb(inst));
t = vcpu->arch.mmu.slbmfee(vcpu, rb);
- vcpu->arch.gpr[get_rt(inst)] = t;
+ kvmppc_set_gpr(vcpu, get_rt(inst), t);
}
break;
case OP_31_XOP_SLBMFEV:
@@ -143,20 +145,20 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
} else {
ulong t, rb;
- rb = vcpu->arch.gpr[get_rb(inst)];
+ rb = kvmppc_get_gpr(vcpu, get_rb(inst));
t = vcpu->arch.mmu.slbmfev(vcpu, rb);
- vcpu->arch.gpr[get_rt(inst)] = t;
+ kvmppc_set_gpr(vcpu, get_rt(inst), t);
}
break;
case OP_31_XOP_DCBZ:
{
- ulong rb = vcpu->arch.gpr[get_rb(inst)];
+ ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst));
ulong ra = 0;
ulong addr;
u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
if (get_ra(inst))
- ra = vcpu->arch.gpr[get_ra(inst)];
+ ra = kvmppc_get_gpr(vcpu, get_ra(inst));
addr = (ra + rb) & ~31ULL;
if (!(vcpu->arch.msr & MSR_SF))
@@ -233,43 +235,44 @@ static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val)
int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
{
int emulated = EMULATE_DONE;
+ ulong spr_val = kvmppc_get_gpr(vcpu, rs);
switch (sprn) {
case SPRN_SDR1:
- to_book3s(vcpu)->sdr1 = vcpu->arch.gpr[rs];
+ to_book3s(vcpu)->sdr1 = spr_val;
break;
case SPRN_DSISR:
- to_book3s(vcpu)->dsisr = vcpu->arch.gpr[rs];
+ to_book3s(vcpu)->dsisr = spr_val;
break;
case SPRN_DAR:
- vcpu->arch.dear = vcpu->arch.gpr[rs];
+ vcpu->arch.dear = spr_val;
break;
case SPRN_HIOR:
- to_book3s(vcpu)->hior = vcpu->arch.gpr[rs];
+ to_book3s(vcpu)->hior = spr_val;
break;
case SPRN_IBAT0U ... SPRN_IBAT3L:
case SPRN_IBAT4U ... SPRN_IBAT7L:
case SPRN_DBAT0U ... SPRN_DBAT3L:
case SPRN_DBAT4U ... SPRN_DBAT7L:
- kvmppc_write_bat(vcpu, sprn, (u32)vcpu->arch.gpr[rs]);
+ kvmppc_write_bat(vcpu, sprn, (u32)spr_val);
/* BAT writes happen so rarely that we're ok to flush
* everything here */
kvmppc_mmu_pte_flush(vcpu, 0, 0);
break;
case SPRN_HID0:
- to_book3s(vcpu)->hid[0] = vcpu->arch.gpr[rs];
+ to_book3s(vcpu)->hid[0] = spr_val;
break;
case SPRN_HID1:
- to_book3s(vcpu)->hid[1] = vcpu->arch.gpr[rs];
+ to_book3s(vcpu)->hid[1] = spr_val;
break;
case SPRN_HID2:
- to_book3s(vcpu)->hid[2] = vcpu->arch.gpr[rs];
+ to_book3s(vcpu)->hid[2] = spr_val;
break;
case SPRN_HID4:
- to_book3s(vcpu)->hid[4] = vcpu->arch.gpr[rs];
+ to_book3s(vcpu)->hid[4] = spr_val;
break;
case SPRN_HID5:
- to_book3s(vcpu)->hid[5] = vcpu->arch.gpr[rs];
+ to_book3s(vcpu)->hid[5] = spr_val;
/* guest HID5 set can change is_dcbz32 */
if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
(mfmsr() & MSR_HV))
@@ -299,38 +302,38 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
switch (sprn) {
case SPRN_SDR1:
- vcpu->arch.gpr[rt] = to_book3s(vcpu)->sdr1;
+ kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1);
break;
case SPRN_DSISR:
- vcpu->arch.gpr[rt] = to_book3s(vcpu)->dsisr;
+ kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->dsisr);
break;
case SPRN_DAR:
- vcpu->arch.gpr[rt] = vcpu->arch.dear;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear);
break;
case SPRN_HIOR:
- vcpu->arch.gpr[rt] = to_book3s(vcpu)->hior;
+ kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hior);
break;
case SPRN_HID0:
- vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[0];
+ kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[0]);
break;
case SPRN_HID1:
- vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[1];
+ kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]);
break;
case SPRN_HID2:
- vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[2];
+ kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]);
break;
case SPRN_HID4:
- vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[4];
+ kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]);
break;
case SPRN_HID5:
- vcpu->arch.gpr[rt] = to_book3s(vcpu)->hid[5];
+ kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]);
break;
case SPRN_THRM1:
case SPRN_THRM2:
case SPRN_THRM3:
case SPRN_CTRLF:
case SPRN_CTRLT:
- vcpu->arch.gpr[rt] = 0;
+ kvmppc_set_gpr(vcpu, rt, 0);
break;
default:
printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
diff --git a/arch/powerpc/kvm/book3s_64_exports.c b/arch/powerpc/kvm/book3s_64_exports.c
index 5b2db38ed86..1dd5a1ddfd0 100644
--- a/arch/powerpc/kvm/book3s_64_exports.c
+++ b/arch/powerpc/kvm/book3s_64_exports.c
@@ -22,3 +22,11 @@
EXPORT_SYMBOL_GPL(kvmppc_trampoline_enter);
EXPORT_SYMBOL_GPL(kvmppc_trampoline_lowmem);
+EXPORT_SYMBOL_GPL(kvmppc_rmcall);
+EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu);
+#ifdef CONFIG_ALTIVEC
+EXPORT_SYMBOL_GPL(kvmppc_load_up_altivec);
+#endif
+#ifdef CONFIG_VSX
+EXPORT_SYMBOL_GPL(kvmppc_load_up_vsx);
+#endif
diff --git a/arch/powerpc/kvm/book3s_64_interrupts.S b/arch/powerpc/kvm/book3s_64_interrupts.S
index 7b55d8094c8..c1584d0cbce 100644
--- a/arch/powerpc/kvm/book3s_64_interrupts.S
+++ b/arch/powerpc/kvm/book3s_64_interrupts.S
@@ -28,11 +28,6 @@
#define ULONG_SIZE 8
#define VCPU_GPR(n) (VCPU_GPRS + (n * ULONG_SIZE))
-.macro mfpaca tmp_reg, src_reg, offset, vcpu_reg
- ld \tmp_reg, (PACA_EXMC+\offset)(r13)
- std \tmp_reg, VCPU_GPR(\src_reg)(\vcpu_reg)
-.endm
-
.macro DISABLE_INTERRUPTS
mfmsr r0
rldicl r0,r0,48,1
@@ -40,6 +35,26 @@
mtmsrd r0,1
.endm
+#define VCPU_LOAD_NVGPRS(vcpu) \
+ ld r14, VCPU_GPR(r14)(vcpu); \
+ ld r15, VCPU_GPR(r15)(vcpu); \
+ ld r16, VCPU_GPR(r16)(vcpu); \
+ ld r17, VCPU_GPR(r17)(vcpu); \
+ ld r18, VCPU_GPR(r18)(vcpu); \
+ ld r19, VCPU_GPR(r19)(vcpu); \
+ ld r20, VCPU_GPR(r20)(vcpu); \
+ ld r21, VCPU_GPR(r21)(vcpu); \
+ ld r22, VCPU_GPR(r22)(vcpu); \
+ ld r23, VCPU_GPR(r23)(vcpu); \
+ ld r24, VCPU_GPR(r24)(vcpu); \
+ ld r25, VCPU_GPR(r25)(vcpu); \
+ ld r26, VCPU_GPR(r26)(vcpu); \
+ ld r27, VCPU_GPR(r27)(vcpu); \
+ ld r28, VCPU_GPR(r28)(vcpu); \
+ ld r29, VCPU_GPR(r29)(vcpu); \
+ ld r30, VCPU_GPR(r30)(vcpu); \
+ ld r31, VCPU_GPR(r31)(vcpu); \
+
/*****************************************************************************
* *
* Guest entry / exit code that is in kernel module memory (highmem) *
@@ -67,61 +82,32 @@ kvm_start_entry:
SAVE_NVGPRS(r1)
/* Save LR */
- mflr r14
- std r14, _LINK(r1)
-
-/* XXX optimize non-volatile loading away */
-kvm_start_lightweight:
+ std r0, _LINK(r1)
- DISABLE_INTERRUPTS
+ /* Load non-volatile guest state from the vcpu */
+ VCPU_LOAD_NVGPRS(r4)
/* Save R1/R2 in the PACA */
- std r1, PACAR1(r13)
- std r2, (PACA_EXMC+EX_SRR0)(r13)
+ std r1, PACA_KVM_HOST_R1(r13)
+ std r2, PACA_KVM_HOST_R2(r13)
+
+ /* XXX swap in/out on load? */
ld r3, VCPU_HIGHMEM_HANDLER(r4)
- std r3, PACASAVEDMSR(r13)
+ std r3, PACA_KVM_VMHANDLER(r13)
- /* Load non-volatile guest state from the vcpu */
- ld r14, VCPU_GPR(r14)(r4)
- ld r15, VCPU_GPR(r15)(r4)
- ld r16, VCPU_GPR(r16)(r4)
- ld r17, VCPU_GPR(r17)(r4)
- ld r18, VCPU_GPR(r18)(r4)
- ld r19, VCPU_GPR(r19)(r4)
- ld r20, VCPU_GPR(r20)(r4)
- ld r21, VCPU_GPR(r21)(r4)
- ld r22, VCPU_GPR(r22)(r4)
- ld r23, VCPU_GPR(r23)(r4)
- ld r24, VCPU_GPR(r24)(r4)
- ld r25, VCPU_GPR(r25)(r4)
- ld r26, VCPU_GPR(r26)(r4)
- ld r27, VCPU_GPR(r27)(r4)
- ld r28, VCPU_GPR(r28)(r4)
- ld r29, VCPU_GPR(r29)(r4)
- ld r30, VCPU_GPR(r30)(r4)
- ld r31, VCPU_GPR(r31)(r4)
+kvm_start_lightweight:
ld r9, VCPU_PC(r4) /* r9 = vcpu->arch.pc */
ld r10, VCPU_SHADOW_MSR(r4) /* r10 = vcpu->arch.shadow_msr */
- ld r3, VCPU_TRAMPOLINE_ENTER(r4)
- mtsrr0 r3
-
- LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR))
- mtsrr1 r3
-
- /* Load guest state in the respective registers */
- lwz r3, VCPU_CR(r4) /* r3 = vcpu->arch.cr */
- stw r3, (PACA_EXMC + EX_CCR)(r13)
-
- ld r3, VCPU_CTR(r4) /* r3 = vcpu->arch.ctr */
- mtctr r3 /* CTR = r3 */
+ /* Load some guest state in the respective registers */
+ ld r5, VCPU_CTR(r4) /* r5 = vcpu->arch.ctr */
+ /* will be swapped in by rmcall */
ld r3, VCPU_LR(r4) /* r3 = vcpu->arch.lr */
mtlr r3 /* LR = r3 */
- ld r3, VCPU_XER(r4) /* r3 = vcpu->arch.xer */
- std r3, (PACA_EXMC + EX_R3)(r13)
+ DISABLE_INTERRUPTS
/* Some guests may need to have dcbz set to 32 byte length.
*
@@ -141,36 +127,15 @@ kvm_start_lightweight:
mtspr SPRN_HID5,r3
no_dcbz32_on:
- /* Load guest GPRs */
-
- ld r3, VCPU_GPR(r9)(r4)
- std r3, (PACA_EXMC + EX_R9)(r13)
- ld r3, VCPU_GPR(r10)(r4)
- std r3, (PACA_EXMC + EX_R10)(r13)
- ld r3, VCPU_GPR(r11)(r4)
- std r3, (PACA_EXMC + EX_R11)(r13)
- ld r3, VCPU_GPR(r12)(r4)
- std r3, (PACA_EXMC + EX_R12)(r13)
- ld r3, VCPU_GPR(r13)(r4)
- std r3, (PACA_EXMC + EX_R13)(r13)
-
- ld r0, VCPU_GPR(r0)(r4)
- ld r1, VCPU_GPR(r1)(r4)
- ld r2, VCPU_GPR(r2)(r4)
- ld r3, VCPU_GPR(r3)(r4)
- ld r5, VCPU_GPR(r5)(r4)
- ld r6, VCPU_GPR(r6)(r4)
- ld r7, VCPU_GPR(r7)(r4)
- ld r8, VCPU_GPR(r8)(r4)
- ld r4, VCPU_GPR(r4)(r4)
-
- /* This sets the Magic value for the trampoline */
-
- li r11, 1
- stb r11, PACA_KVM_IN_GUEST(r13)
+
+ ld r6, VCPU_RMCALL(r4)
+ mtctr r6
+
+ ld r3, VCPU_TRAMPOLINE_ENTER(r4)
+ LOAD_REG_IMMEDIATE(r4, MSR_KERNEL & ~(MSR_IR | MSR_DR))
/* Jump to SLB patching handlder and into our guest */
- RFI
+ bctr
/*
* This is the handler in module memory. It gets jumped at from the
@@ -184,125 +149,70 @@ kvmppc_handler_highmem:
/*
* Register usage at this point:
*
- * R00 = guest R13
- * R01 = host R1
- * R02 = host R2
- * R10 = guest PC
- * R11 = guest MSR
- * R12 = exit handler id
- * R13 = PACA
- * PACA.exmc.R9 = guest R1
- * PACA.exmc.R10 = guest R10
- * PACA.exmc.R11 = guest R11
- * PACA.exmc.R12 = guest R12
- * PACA.exmc.R13 = guest R2
- * PACA.exmc.DAR = guest DAR
- * PACA.exmc.DSISR = guest DSISR
- * PACA.exmc.LR = guest instruction
- * PACA.exmc.CCR = guest CR
- * PACA.exmc.SRR0 = guest R0
+ * R0 = guest last inst
+ * R1 = host R1
+ * R2 = host R2
+ * R3 = guest PC
+ * R4 = guest MSR
+ * R5 = guest DAR
+ * R6 = guest DSISR
+ * R13 = PACA
+ * PACA.KVM.* = guest *
*
*/
- std r3, (PACA_EXMC+EX_R3)(r13)
+ /* R7 = vcpu */
+ ld r7, GPR4(r1)
- /* save the exit id in R3 */
- mr r3, r12
+ /* Now save the guest state */
- /* R12 = vcpu */
- ld r12, GPR4(r1)
+ stw r0, VCPU_LAST_INST(r7)
- /* Now save the guest state */
+ std r3, VCPU_PC(r7)
+ std r4, VCPU_SHADOW_SRR1(r7)
+ std r5, VCPU_FAULT_DEAR(r7)
+ std r6, VCPU_FAULT_DSISR(r7)
- std r0, VCPU_GPR(r13)(r12)
- std r4, VCPU_GPR(r4)(r12)
- std r5, VCPU_GPR(r5)(r12)
- std r6, VCPU_GPR(r6)(r12)
- std r7, VCPU_GPR(r7)(r12)
- std r8, VCPU_GPR(r8)(r12)
- std r9, VCPU_GPR(r9)(r12)
-
- /* get registers from PACA */
- mfpaca r5, r0, EX_SRR0, r12
- mfpaca r5, r3, EX_R3, r12
- mfpaca r5, r1, EX_R9, r12
- mfpaca r5, r10, EX_R10, r12
- mfpaca r5, r11, EX_R11, r12
- mfpaca r5, r12, EX_R12, r12
- mfpaca r5, r2, EX_R13, r12
-
- lwz r5, (PACA_EXMC+EX_LR)(r13)
- stw r5, VCPU_LAST_INST(r12)
-
- lwz r5, (PACA_EXMC+EX_CCR)(r13)
- stw r5, VCPU_CR(r12)
-
- ld r5, VCPU_HFLAGS(r12)
+ ld r5, VCPU_HFLAGS(r7)
rldicl. r5, r5, 0, 63 /* CR = ((r5 & 1) == 0) */
beq no_dcbz32_off
+ li r4, 0
mfspr r5,SPRN_HID5
- rldimi r5,r5,6,56
+ rldimi r5,r4,6,56
mtspr SPRN_HID5,r5
no_dcbz32_off:
- /* XXX maybe skip on lightweight? */
- std r14, VCPU_GPR(r14)(r12)
- std r15, VCPU_GPR(r15)(r12)
- std r16, VCPU_GPR(r16)(r12)
- std r17, VCPU_GPR(r17)(r12)
- std r18, VCPU_GPR(r18)(r12)
- std r19, VCPU_GPR(r19)(r12)
- std r20, VCPU_GPR(r20)(r12)
- std r21, VCPU_GPR(r21)(r12)
- std r22, VCPU_GPR(r22)(r12)
- std r23, VCPU_GPR(r23)(r12)
- std r24, VCPU_GPR(r24)(r12)
- std r25, VCPU_GPR(r25)(r12)
- std r26, VCPU_GPR(r26)(r12)
- std r27, VCPU_GPR(r27)(r12)
- std r28, VCPU_GPR(r28)(r12)
- std r29, VCPU_GPR(r29)(r12)
- std r30, VCPU_GPR(r30)(r12)
- std r31, VCPU_GPR(r31)(r12)
-
- /* Restore non-volatile host registers (r14 - r31) */
- REST_NVGPRS(r1)
-
- /* Save guest PC (R10) */
- std r10, VCPU_PC(r12)
-
- /* Save guest msr (R11) */
- std r11, VCPU_SHADOW_MSR(r12)
-
- /* Save guest CTR (in R12) */
+ std r14, VCPU_GPR(r14)(r7)
+ std r15, VCPU_GPR(r15)(r7)
+ std r16, VCPU_GPR(r16)(r7)
+ std r17, VCPU_GPR(r17)(r7)
+ std r18, VCPU_GPR(r18)(r7)
+ std r19, VCPU_GPR(r19)(r7)
+ std r20, VCPU_GPR(r20)(r7)
+ std r21, VCPU_GPR(r21)(r7)
+ std r22, VCPU_GPR(r22)(r7)
+ std r23, VCPU_GPR(r23)(r7)
+ std r24, VCPU_GPR(r24)(r7)
+ std r25, VCPU_GPR(r25)(r7)
+ std r26, VCPU_GPR(r26)(r7)
+ std r27, VCPU_GPR(r27)(r7)
+ std r28, VCPU_GPR(r28)(r7)
+ std r29, VCPU_GPR(r29)(r7)
+ std r30, VCPU_GPR(r30)(r7)
+ std r31, VCPU_GPR(r31)(r7)
+
+ /* Save guest CTR */
mfctr r5
- std r5, VCPU_CTR(r12)
+ std r5, VCPU_CTR(r7)
/* Save guest LR */
mflr r5
- std r5, VCPU_LR(r12)
-
- /* Save guest XER */
- mfxer r5
- std r5, VCPU_XER(r12)
-
- /* Save guest DAR */
- ld r5, (PACA_EXMC+EX_DAR)(r13)
- std r5, VCPU_FAULT_DEAR(r12)
-
- /* Save guest DSISR */
- lwz r5, (PACA_EXMC+EX_DSISR)(r13)
- std r5, VCPU_FAULT_DSISR(r12)
+ std r5, VCPU_LR(r7)
/* Restore host msr -> SRR1 */
- ld r7, VCPU_HOST_MSR(r12)
- mtsrr1 r7
-
- /* Restore host IP -> SRR0 */
- ld r6, VCPU_HOST_RETIP(r12)
- mtsrr0 r6
+ ld r6, VCPU_HOST_MSR(r7)
/*
* For some interrupts, we need to call the real Linux
@@ -314,13 +224,14 @@ no_dcbz32_off:
* r3 = address of interrupt handler (exit reason)
*/
- cmpwi r3, BOOK3S_INTERRUPT_EXTERNAL
+ cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
beq call_linux_handler
- cmpwi r3, BOOK3S_INTERRUPT_DECREMENTER
+ cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
beq call_linux_handler
- /* Back to Interruptable Mode! (goto kvm_return_point) */
- RFI
+ /* Back to EE=1 */
+ mtmsr r6
+ b kvm_return_point
call_linux_handler:
@@ -333,16 +244,22 @@ call_linux_handler:
* interrupt handler!
*
* R3 still contains the exit code,
- * R6 VCPU_HOST_RETIP and
- * R7 VCPU_HOST_MSR
+ * R5 VCPU_HOST_RETIP and
+ * R6 VCPU_HOST_MSR
*/
- mtlr r3
+ /* Restore host IP -> SRR0 */
+ ld r5, VCPU_HOST_RETIP(r7)
+
+ /* XXX Better move to a safe function?
+ * What if we get an HTAB flush in between mtsrr0 and mtsrr1? */
- ld r5, VCPU_TRAMPOLINE_LOWMEM(r12)
- mtsrr0 r5
- LOAD_REG_IMMEDIATE(r5, MSR_KERNEL & ~(MSR_IR | MSR_DR))
- mtsrr1 r5
+ mtlr r12
+
+ ld r4, VCPU_TRAMPOLINE_LOWMEM(r7)
+ mtsrr0 r4
+ LOAD_REG_IMMEDIATE(r3, MSR_KERNEL & ~(MSR_IR | MSR_DR))
+ mtsrr1 r3
RFI
@@ -351,42 +268,51 @@ kvm_return_point:
/* Jump back to lightweight entry if we're supposed to */
/* go back into the guest */
- mr r5, r3
+
+ /* Pass the exit number as 3rd argument to kvmppc_handle_exit */
+ mr r5, r12
+
/* Restore r3 (kvm_run) and r4 (vcpu) */
REST_2GPRS(3, r1)
bl KVMPPC_HANDLE_EXIT
-#if 0 /* XXX get lightweight exits back */
+ /* If RESUME_GUEST, get back in the loop */
cmpwi r3, RESUME_GUEST
- bne kvm_exit_heavyweight
+ beq kvm_loop_lightweight
- /* put VCPU and KVM_RUN back into place and roll again! */
- REST_2GPRS(3, r1)
- b kvm_start_lightweight
+ cmpwi r3, RESUME_GUEST_NV
+ beq kvm_loop_heavyweight
-kvm_exit_heavyweight:
- /* Restore non-volatile host registers */
- ld r14, _LINK(r1)
- mtlr r14
- REST_NVGPRS(r1)
+kvm_exit_loop:
- addi r1, r1, SWITCH_FRAME_SIZE
-#else
ld r4, _LINK(r1)
mtlr r4
- cmpwi r3, RESUME_GUEST
- bne kvm_exit_heavyweight
+ /* Restore non-volatile host registers (r14 - r31) */
+ REST_NVGPRS(r1)
+
+ addi r1, r1, SWITCH_FRAME_SIZE
+ blr
+
+kvm_loop_heavyweight:
+
+ ld r4, _LINK(r1)
+ std r4, (16 + SWITCH_FRAME_SIZE)(r1)
+ /* Load vcpu and cpu_run */
REST_2GPRS(3, r1)
- addi r1, r1, SWITCH_FRAME_SIZE
+ /* Load non-volatile guest state from the vcpu */
+ VCPU_LOAD_NVGPRS(r4)
- b kvm_start_entry
+ /* Jump back into the beginning of this function */
+ b kvm_start_lightweight
-kvm_exit_heavyweight:
+kvm_loop_lightweight:
- addi r1, r1, SWITCH_FRAME_SIZE
-#endif
+ /* We'll need the vcpu pointer */
+ REST_GPR(4, r1)
+
+ /* Jump back into the beginning of this function */
+ b kvm_start_lightweight
- blr
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
index e4beeb371a7..512dcff7755 100644
--- a/arch/powerpc/kvm/book3s_64_mmu.c
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -54,7 +54,7 @@ static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe(
if (!vcpu_book3s->slb[i].valid)
continue;
- if (vcpu_book3s->slb[i].large)
+ if (vcpu_book3s->slb[i].tb)
cmp_esid = esid_1t;
if (vcpu_book3s->slb[i].esid == cmp_esid)
@@ -65,9 +65,10 @@ static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe(
eaddr, esid, esid_1t);
for (i = 0; i < vcpu_book3s->slb_nr; i++) {
if (vcpu_book3s->slb[i].vsid)
- dprintk(" %d: %c%c %llx %llx\n", i,
+ dprintk(" %d: %c%c%c %llx %llx\n", i,
vcpu_book3s->slb[i].valid ? 'v' : ' ',
vcpu_book3s->slb[i].large ? 'l' : ' ',
+ vcpu_book3s->slb[i].tb ? 't' : ' ',
vcpu_book3s->slb[i].esid,
vcpu_book3s->slb[i].vsid);
}
@@ -84,7 +85,7 @@ static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
if (!slb)
return 0;
- if (slb->large)
+ if (slb->tb)
return (((u64)eaddr >> 12) & 0xfffffff) |
(((u64)slb->vsid) << 28);
@@ -309,7 +310,8 @@ static void kvmppc_mmu_book3s_64_slbmte(struct kvm_vcpu *vcpu, u64 rs, u64 rb)
slbe = &vcpu_book3s->slb[slb_nr];
slbe->large = (rs & SLB_VSID_L) ? 1 : 0;
- slbe->esid = slbe->large ? esid_1t : esid;
+ slbe->tb = (rs & SLB_VSID_B_1T) ? 1 : 0;
+ slbe->esid = slbe->tb ? esid_1t : esid;
slbe->vsid = rs >> 12;
slbe->valid = (rb & SLB_ESID_V) ? 1 : 0;
slbe->Ks = (rs & SLB_VSID_KS) ? 1 : 0;
diff --git a/arch/powerpc/kvm/book3s_64_rmhandlers.S b/arch/powerpc/kvm/book3s_64_rmhandlers.S
index fb7dd2e9ac8..c83c60ad96c 100644
--- a/arch/powerpc/kvm/book3s_64_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_64_rmhandlers.S
@@ -45,36 +45,25 @@ kvmppc_trampoline_\intno:
* To distinguish, we check a magic byte in the PACA
*/
mfspr r13, SPRN_SPRG_PACA /* r13 = PACA */
- std r12, (PACA_EXMC + EX_R12)(r13)
+ std r12, PACA_KVM_SCRATCH0(r13)
mfcr r12
- stw r12, (PACA_EXMC + EX_CCR)(r13)
+ stw r12, PACA_KVM_SCRATCH1(r13)
lbz r12, PACA_KVM_IN_GUEST(r13)
- cmpwi r12, 0
+ cmpwi r12, KVM_GUEST_MODE_NONE
bne ..kvmppc_handler_hasmagic_\intno
/* No KVM guest? Then jump back to the Linux handler! */
- lwz r12, (PACA_EXMC + EX_CCR)(r13)
+ lwz r12, PACA_KVM_SCRATCH1(r13)
mtcr r12
- ld r12, (PACA_EXMC + EX_R12)(r13)
+ ld r12, PACA_KVM_SCRATCH0(r13)
mfspr r13, SPRN_SPRG_SCRATCH0 /* r13 = original r13 */
b kvmppc_resume_\intno /* Get back original handler */
/* Now we know we're handling a KVM guest */
..kvmppc_handler_hasmagic_\intno:
- /* Unset guest state */
- li r12, 0
- stb r12, PACA_KVM_IN_GUEST(r13)
- std r1, (PACA_EXMC+EX_R9)(r13)
- std r10, (PACA_EXMC+EX_R10)(r13)
- std r11, (PACA_EXMC+EX_R11)(r13)
- std r2, (PACA_EXMC+EX_R13)(r13)
-
- mfsrr0 r10
- mfsrr1 r11
-
- /* Restore R1/R2 so we can handle faults */
- ld r1, PACAR1(r13)
- ld r2, (PACA_EXMC+EX_SRR0)(r13)
+ /* Should we just skip the faulting instruction? */
+ cmpwi r12, KVM_GUEST_MODE_SKIP
+ beq kvmppc_handler_skip_ins
/* Let's store which interrupt we're handling */
li r12, \intno
@@ -102,23 +91,107 @@ INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC
INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_VSX
/*
+ * Bring us back to the faulting code, but skip the
+ * faulting instruction.
+ *
+ * This is a generic exit path from the interrupt
+ * trampolines above.
+ *
+ * Input Registers:
+ *
+ * R12 = free
+ * R13 = PACA
+ * PACA.KVM.SCRATCH0 = guest R12
+ * PACA.KVM.SCRATCH1 = guest CR
+ * SPRG_SCRATCH0 = guest R13
+ *
+ */
+kvmppc_handler_skip_ins:
+
+ /* Patch the IP to the next instruction */
+ mfsrr0 r12
+ addi r12, r12, 4
+ mtsrr0 r12
+
+ /* Clean up all state */
+ lwz r12, PACA_KVM_SCRATCH1(r13)
+ mtcr r12
+ ld r12, PACA_KVM_SCRATCH0(r13)
+ mfspr r13, SPRN_SPRG_SCRATCH0
+
+ /* And get back into the code */
+ RFI
+
+/*
* This trampoline brings us back to a real mode handler
*
* Input Registers:
*
- * R6 = SRR0
- * R7 = SRR1
+ * R5 = SRR0
+ * R6 = SRR1
* LR = real-mode IP
*
*/
.global kvmppc_handler_lowmem_trampoline
kvmppc_handler_lowmem_trampoline:
- mtsrr0 r6
- mtsrr1 r7
+ mtsrr0 r5
+ mtsrr1 r6
blr
kvmppc_handler_lowmem_trampoline_end:
+/*
+ * Call a function in real mode
+ *
+ * Input Registers:
+ *
+ * R3 = function
+ * R4 = MSR
+ * R5 = CTR
+ *
+ */
+_GLOBAL(kvmppc_rmcall)
+ mtmsr r4 /* Disable relocation, so mtsrr
+ doesn't get interrupted */
+ mtctr r5
+ mtsrr0 r3
+ mtsrr1 r4
+ RFI
+
+/*
+ * Activate current's external feature (FPU/Altivec/VSX)
+ */
+#define define_load_up(what) \
+ \
+_GLOBAL(kvmppc_load_up_ ## what); \
+ subi r1, r1, INT_FRAME_SIZE; \
+ mflr r3; \
+ std r3, _LINK(r1); \
+ mfmsr r4; \
+ std r31, GPR3(r1); \
+ mr r31, r4; \
+ li r5, MSR_DR; \
+ oris r5, r5, MSR_EE@h; \
+ andc r4, r4, r5; \
+ mtmsr r4; \
+ \
+ bl .load_up_ ## what; \
+ \
+ mtmsr r31; \
+ ld r3, _LINK(r1); \
+ ld r31, GPR3(r1); \
+ addi r1, r1, INT_FRAME_SIZE; \
+ mtlr r3; \
+ blr
+
+define_load_up(fpu)
+#ifdef CONFIG_ALTIVEC
+define_load_up(altivec)
+#endif
+#ifdef CONFIG_VSX
+define_load_up(vsx)
+#endif
+
.global kvmppc_trampoline_lowmem
kvmppc_trampoline_lowmem:
.long kvmppc_handler_lowmem_trampoline - _stext
diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S
index ecd237a03fd..35b76272218 100644
--- a/arch/powerpc/kvm/book3s_64_slb.S
+++ b/arch/powerpc/kvm/book3s_64_slb.S
@@ -31,7 +31,7 @@
#define REBOLT_SLB_ENTRY(num) \
ld r10, SHADOW_SLB_ESID(num)(r11); \
cmpdi r10, 0; \
- beq slb_exit_skip_1; \
+ beq slb_exit_skip_ ## num; \
oris r10, r10, SLB_ESID_V@h; \
ld r9, SHADOW_SLB_VSID(num)(r11); \
slbmte r9, r10; \
@@ -51,23 +51,21 @@ kvmppc_handler_trampoline_enter:
*
* MSR = ~IR|DR
* R13 = PACA
+ * R1 = host R1
+ * R2 = host R2
* R9 = guest IP
* R10 = guest MSR
- * R11 = free
- * R12 = free
- * PACA[PACA_EXMC + EX_R9] = guest R9
- * PACA[PACA_EXMC + EX_R10] = guest R10
- * PACA[PACA_EXMC + EX_R11] = guest R11
- * PACA[PACA_EXMC + EX_R12] = guest R12
- * PACA[PACA_EXMC + EX_R13] = guest R13
- * PACA[PACA_EXMC + EX_CCR] = guest CR
- * PACA[PACA_EXMC + EX_R3] = guest XER
+ * all other GPRS = free
+ * PACA[KVM_CR] = guest CR
+ * PACA[KVM_XER] = guest XER
*/
mtsrr0 r9
mtsrr1 r10
- mtspr SPRN_SPRG_SCRATCH0, r0
+ /* Activate guest mode, so faults get handled by KVM */
+ li r11, KVM_GUEST_MODE_GUEST
+ stb r11, PACA_KVM_IN_GUEST(r13)
/* Remove LPAR shadow entries */
@@ -131,20 +129,27 @@ slb_do_enter:
/* Enter guest */
- mfspr r0, SPRN_SPRG_SCRATCH0
-
- ld r9, (PACA_EXMC+EX_R9)(r13)
- ld r10, (PACA_EXMC+EX_R10)(r13)
- ld r12, (PACA_EXMC+EX_R12)(r13)
-
- lwz r11, (PACA_EXMC+EX_CCR)(r13)
+ ld r0, (PACA_KVM_R0)(r13)
+ ld r1, (PACA_KVM_R1)(r13)
+ ld r2, (PACA_KVM_R2)(r13)
+ ld r3, (PACA_KVM_R3)(r13)
+ ld r4, (PACA_KVM_R4)(r13)
+ ld r5, (PACA_KVM_R5)(r13)
+ ld r6, (PACA_KVM_R6)(r13)
+ ld r7, (PACA_KVM_R7)(r13)
+ ld r8, (PACA_KVM_R8)(r13)
+ ld r9, (PACA_KVM_R9)(r13)
+ ld r10, (PACA_KVM_R10)(r13)
+ ld r12, (PACA_KVM_R12)(r13)
+
+ lwz r11, (PACA_KVM_CR)(r13)
mtcr r11
- ld r11, (PACA_EXMC+EX_R3)(r13)
+ ld r11, (PACA_KVM_XER)(r13)
mtxer r11
- ld r11, (PACA_EXMC+EX_R11)(r13)
- ld r13, (PACA_EXMC+EX_R13)(r13)
+ ld r11, (PACA_KVM_R11)(r13)
+ ld r13, (PACA_KVM_R13)(r13)
RFI
kvmppc_handler_trampoline_enter_end:
@@ -162,28 +167,54 @@ kvmppc_handler_trampoline_exit:
/* Register usage at this point:
*
- * SPRG_SCRATCH0 = guest R13
- * R01 = host R1
- * R02 = host R2
- * R10 = guest PC
- * R11 = guest MSR
- * R12 = exit handler id
- * R13 = PACA
- * PACA.exmc.CCR = guest CR
- * PACA.exmc.R9 = guest R1
- * PACA.exmc.R10 = guest R10
- * PACA.exmc.R11 = guest R11
- * PACA.exmc.R12 = guest R12
- * PACA.exmc.R13 = guest R2
+ * SPRG_SCRATCH0 = guest R13
+ * R12 = exit handler id
+ * R13 = PACA
+ * PACA.KVM.SCRATCH0 = guest R12
+ * PACA.KVM.SCRATCH1 = guest CR
*
*/
/* Save registers */
- std r0, (PACA_EXMC+EX_SRR0)(r13)
- std r9, (PACA_EXMC+EX_R3)(r13)
- std r10, (PACA_EXMC+EX_LR)(r13)
- std r11, (PACA_EXMC+EX_DAR)(r13)
+ std r0, PACA_KVM_R0(r13)
+ std r1, PACA_KVM_R1(r13)
+ std r2, PACA_KVM_R2(r13)
+ std r3, PACA_KVM_R3(r13)
+ std r4, PACA_KVM_R4(r13)
+ std r5, PACA_KVM_R5(r13)
+ std r6, PACA_KVM_R6(r13)
+ std r7, PACA_KVM_R7(r13)
+ std r8, PACA_KVM_R8(r13)
+ std r9, PACA_KVM_R9(r13)
+ std r10, PACA_KVM_R10(r13)
+ std r11, PACA_KVM_R11(r13)
+
+ /* Restore R1/R2 so we can handle faults */
+ ld r1, PACA_KVM_HOST_R1(r13)
+ ld r2, PACA_KVM_HOST_R2(r13)
+
+ /* Save guest PC and MSR in GPRs */
+ mfsrr0 r3
+ mfsrr1 r4
+
+ /* Get scratch'ed off registers */
+ mfspr r9, SPRN_SPRG_SCRATCH0
+ std r9, PACA_KVM_R13(r13)
+
+ ld r8, PACA_KVM_SCRATCH0(r13)
+ std r8, PACA_KVM_R12(r13)
+
+ lwz r7, PACA_KVM_SCRATCH1(r13)
+ stw r7, PACA_KVM_CR(r13)
+
+ /* Save more register state */
+
+ mfxer r6
+ stw r6, PACA_KVM_XER(r13)
+
+ mfdar r5
+ mfdsisr r6
/*
* In order for us to easily get the last instruction,
@@ -202,17 +233,28 @@ kvmppc_handler_trampoline_exit:
ld_last_inst:
/* Save off the guest instruction we're at */
+
+ /* Set guest mode to 'jump over instruction' so if lwz faults
+ * we'll just continue at the next IP. */
+ li r9, KVM_GUEST_MODE_SKIP
+ stb r9, PACA_KVM_IN_GUEST(r13)
+
/* 1) enable paging for data */
mfmsr r9
ori r11, r9, MSR_DR /* Enable paging for data */
mtmsr r11
/* 2) fetch the instruction */
- lwz r0, 0(r10)
+ li r0, KVM_INST_FETCH_FAILED /* In case lwz faults */
+ lwz r0, 0(r3)
/* 3) disable paging again */
mtmsr r9
no_ld_last_inst:
+ /* Unset guest mode */
+ li r9, KVM_GUEST_MODE_NONE
+ stb r9, PACA_KVM_IN_GUEST(r13)
+
/* Restore bolted entries from the shadow and fix it along the way */
/* We don't store anything in entry 0, so we don't need to take care of it */
@@ -233,29 +275,27 @@ no_ld_last_inst:
slb_do_exit:
- /* Restore registers */
-
- ld r11, (PACA_EXMC+EX_DAR)(r13)
- ld r10, (PACA_EXMC+EX_LR)(r13)
- ld r9, (PACA_EXMC+EX_R3)(r13)
-
- /* Save last inst */
- stw r0, (PACA_EXMC+EX_LR)(r13)
-
- /* Save DAR and DSISR before going to paged mode */
- mfdar r0
- std r0, (PACA_EXMC+EX_DAR)(r13)
- mfdsisr r0
- stw r0, (PACA_EXMC+EX_DSISR)(r13)
+ /* Register usage at this point:
+ *
+ * R0 = guest last inst
+ * R1 = host R1
+ * R2 = host R2
+ * R3 = guest PC
+ * R4 = guest MSR
+ * R5 = guest DAR
+ * R6 = guest DSISR
+ * R12 = exit handler id
+ * R13 = PACA
+ * PACA.KVM.* = guest *
+ *
+ */
/* RFI into the highmem handler */
- mfmsr r0
- ori r0, r0, MSR_IR|MSR_DR|MSR_RI /* Enable paging */
- mtsrr1 r0
- ld r0, PACASAVEDMSR(r13) /* Highmem handler address */
- mtsrr0 r0
-
- mfspr r0, SPRN_SPRG_SCRATCH0
+ mfmsr r7
+ ori r7, r7, MSR_IR|MSR_DR|MSR_RI /* Enable paging */
+ mtsrr1 r7
+ ld r8, PACA_KVM_VMHANDLER(r13) /* Highmem handler address */
+ mtsrr0 r8
RFI
kvmppc_handler_trampoline_exit_end:
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 06f5a9ecc42..2a3a1953d4b 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/kvm_host.h>
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
@@ -69,10 +70,10 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu)
for (i = 0; i < 32; i += 4) {
printk("gpr%02d: %08lx %08lx %08lx %08lx\n", i,
- vcpu->arch.gpr[i],
- vcpu->arch.gpr[i+1],
- vcpu->arch.gpr[i+2],
- vcpu->arch.gpr[i+3]);
+ kvmppc_get_gpr(vcpu, i),
+ kvmppc_get_gpr(vcpu, i+1),
+ kvmppc_get_gpr(vcpu, i+2),
+ kvmppc_get_gpr(vcpu, i+3));
}
}
@@ -82,8 +83,32 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu,
set_bit(priority, &vcpu->arch.pending_exceptions);
}
-void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
+static void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu,
+ ulong dear_flags, ulong esr_flags)
{
+ vcpu->arch.queued_dear = dear_flags;
+ vcpu->arch.queued_esr = esr_flags;
+ kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
+}
+
+static void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu,
+ ulong dear_flags, ulong esr_flags)
+{
+ vcpu->arch.queued_dear = dear_flags;
+ vcpu->arch.queued_esr = esr_flags;
+ kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
+}
+
+static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu,
+ ulong esr_flags)
+{
+ vcpu->arch.queued_esr = esr_flags;
+ kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
+}
+
+void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags)
+{
+ vcpu->arch.queued_esr = esr_flags;
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
}
@@ -97,6 +122,11 @@ int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
return test_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
}
+void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
+{
+ clear_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
+}
+
void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
@@ -109,14 +139,19 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
{
int allowed = 0;
ulong msr_mask;
+ bool update_esr = false, update_dear = false;
switch (priority) {
- case BOOKE_IRQPRIO_PROGRAM:
case BOOKE_IRQPRIO_DTLB_MISS:
- case BOOKE_IRQPRIO_ITLB_MISS:
- case BOOKE_IRQPRIO_SYSCALL:
case BOOKE_IRQPRIO_DATA_STORAGE:
+ update_dear = true;
+ /* fall through */
case BOOKE_IRQPRIO_INST_STORAGE:
+ case BOOKE_IRQPRIO_PROGRAM:
+ update_esr = true;
+ /* fall through */
+ case BOOKE_IRQPRIO_ITLB_MISS:
+ case BOOKE_IRQPRIO_SYSCALL:
case BOOKE_IRQPRIO_FP_UNAVAIL:
case BOOKE_IRQPRIO_SPE_UNAVAIL:
case BOOKE_IRQPRIO_SPE_FP_DATA:
@@ -151,6 +186,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
vcpu->arch.srr0 = vcpu->arch.pc;
vcpu->arch.srr1 = vcpu->arch.msr;
vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority];
+ if (update_esr == true)
+ vcpu->arch.esr = vcpu->arch.queued_esr;
+ if (update_dear == true)
+ vcpu->arch.dear = vcpu->arch.queued_dear;
kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask);
clear_bit(priority, &vcpu->arch.pending_exceptions);
@@ -223,8 +262,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
if (vcpu->arch.msr & MSR_PR) {
/* Program traps generated by user-level software must be handled
* by the guest kernel. */
- vcpu->arch.esr = vcpu->arch.fault_esr;
- kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
+ kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr);
r = RESUME_GUEST;
kvmppc_account_exit(vcpu, USR_PR_INST);
break;
@@ -280,16 +318,14 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
break;
case BOOKE_INTERRUPT_DATA_STORAGE:
- vcpu->arch.dear = vcpu->arch.fault_dear;
- vcpu->arch.esr = vcpu->arch.fault_esr;
- kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
+ kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear,
+ vcpu->arch.fault_esr);
kvmppc_account_exit(vcpu, DSI_EXITS);
r = RESUME_GUEST;
break;
case BOOKE_INTERRUPT_INST_STORAGE:
- vcpu->arch.esr = vcpu->arch.fault_esr;
- kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
+ kvmppc_core_queue_inst_storage(vcpu, vcpu->arch.fault_esr);
kvmppc_account_exit(vcpu, ISI_EXITS);
r = RESUME_GUEST;
break;
@@ -310,9 +346,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr);
if (gtlb_index < 0) {
/* The guest didn't have a mapping for it. */
- kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
- vcpu->arch.dear = vcpu->arch.fault_dear;
- vcpu->arch.esr = vcpu->arch.fault_esr;
+ kvmppc_core_queue_dtlb_miss(vcpu,
+ vcpu->arch.fault_dear,
+ vcpu->arch.fault_esr);
kvmppc_mmu_dtlb_miss(vcpu);
kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS);
r = RESUME_GUEST;
@@ -426,7 +462,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
{
vcpu->arch.pc = 0;
vcpu->arch.msr = 0;
- vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */
+ kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save LR slot */
vcpu->arch.shadow_pid = 1;
@@ -444,10 +480,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
int i;
regs->pc = vcpu->arch.pc;
- regs->cr = vcpu->arch.cr;
+ regs->cr = kvmppc_get_cr(vcpu);
regs->ctr = vcpu->arch.ctr;
regs->lr = vcpu->arch.lr;
- regs->xer = vcpu->arch.xer;
+ regs->xer = kvmppc_get_xer(vcpu);
regs->msr = vcpu->arch.msr;
regs->srr0 = vcpu->arch.srr0;
regs->srr1 = vcpu->arch.srr1;
@@ -461,7 +497,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
regs->sprg7 = vcpu->arch.sprg6;
for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
- regs->gpr[i] = vcpu->arch.gpr[i];
+ regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
return 0;
}
@@ -471,10 +507,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
int i;
vcpu->arch.pc = regs->pc;
- vcpu->arch.cr = regs->cr;
+ kvmppc_set_cr(vcpu, regs->cr);
vcpu->arch.ctr = regs->ctr;
vcpu->arch.lr = regs->lr;
- vcpu->arch.xer = regs->xer;
+ kvmppc_set_xer(vcpu, regs->xer);
kvmppc_set_msr(vcpu, regs->msr);
vcpu->arch.srr0 = regs->srr0;
vcpu->arch.srr1 = regs->srr1;
@@ -486,8 +522,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
vcpu->arch.sprg6 = regs->sprg5;
vcpu->arch.sprg7 = regs->sprg6;
- for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++)
- vcpu->arch.gpr[i] = regs->gpr[i];
+ for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
+ kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
return 0;
}
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index aebc65e93f4..cbc790ee192 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -62,20 +62,20 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
case OP_31_XOP_MFMSR:
rt = get_rt(inst);
- vcpu->arch.gpr[rt] = vcpu->arch.msr;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.msr);
kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
break;
case OP_31_XOP_MTMSR:
rs = get_rs(inst);
kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
- kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]);
+ kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
break;
case OP_31_XOP_WRTEE:
rs = get_rs(inst);
vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
- | (vcpu->arch.gpr[rs] & MSR_EE);
+ | (kvmppc_get_gpr(vcpu, rs) & MSR_EE);
kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
break;
@@ -101,22 +101,23 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
{
int emulated = EMULATE_DONE;
+ ulong spr_val = kvmppc_get_gpr(vcpu, rs);
switch (sprn) {
case SPRN_DEAR:
- vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.dear = spr_val; break;
case SPRN_ESR:
- vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.esr = spr_val; break;
case SPRN_DBCR0:
- vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.dbcr0 = spr_val; break;
case SPRN_DBCR1:
- vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.dbcr1 = spr_val; break;
case SPRN_DBSR:
- vcpu->arch.dbsr &= ~vcpu->arch.gpr[rs]; break;
+ vcpu->arch.dbsr &= ~spr_val; break;
case SPRN_TSR:
- vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
+ vcpu->arch.tsr &= ~spr_val; break;
case SPRN_TCR:
- vcpu->arch.tcr = vcpu->arch.gpr[rs];
+ vcpu->arch.tcr = spr_val;
kvmppc_emulate_dec(vcpu);
break;
@@ -124,64 +125,64 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
* loaded into the real SPRGs when resuming the
* guest. */
case SPRN_SPRG4:
- vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.sprg4 = spr_val; break;
case SPRN_SPRG5:
- vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.sprg5 = spr_val; break;
case SPRN_SPRG6:
- vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.sprg6 = spr_val; break;
case SPRN_SPRG7:
- vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.sprg7 = spr_val; break;
case SPRN_IVPR:
- vcpu->arch.ivpr = vcpu->arch.gpr[rs];
+ vcpu->arch.ivpr = spr_val;
break;
case SPRN_IVOR0:
- vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val;
break;
case SPRN_IVOR1:
- vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = spr_val;
break;
case SPRN_IVOR2:
- vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val;
break;
case SPRN_IVOR3:
- vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val;
break;
case SPRN_IVOR4:
- vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = spr_val;
break;
case SPRN_IVOR5:
- vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = spr_val;
break;
case SPRN_IVOR6:
- vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = spr_val;
break;
case SPRN_IVOR7:
- vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = spr_val;
break;
case SPRN_IVOR8:
- vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val;
break;
case SPRN_IVOR9:
- vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val;
break;
case SPRN_IVOR10:
- vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = spr_val;
break;
case SPRN_IVOR11:
- vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = spr_val;
break;
case SPRN_IVOR12:
- vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = spr_val;
break;
case SPRN_IVOR13:
- vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = spr_val;
break;
case SPRN_IVOR14:
- vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = spr_val;
break;
case SPRN_IVOR15:
- vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = spr_val;
break;
default:
@@ -197,65 +198,65 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
switch (sprn) {
case SPRN_IVPR:
- vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivpr); break;
case SPRN_DEAR:
- vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear); break;
case SPRN_ESR:
- vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.esr); break;
case SPRN_DBCR0:
- vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbcr0); break;
case SPRN_DBCR1:
- vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbcr1); break;
case SPRN_DBSR:
- vcpu->arch.gpr[rt] = vcpu->arch.dbsr; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbsr); break;
case SPRN_IVOR0:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL]);
break;
case SPRN_IVOR1:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK]);
break;
case SPRN_IVOR2:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]);
break;
case SPRN_IVOR3:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE]);
break;
case SPRN_IVOR4:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL]);
break;
case SPRN_IVOR5:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT]);
break;
case SPRN_IVOR6:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM]);
break;
case SPRN_IVOR7:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL]);
break;
case SPRN_IVOR8:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]);
break;
case SPRN_IVOR9:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL]);
break;
case SPRN_IVOR10:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER]);
break;
case SPRN_IVOR11:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_FIT]);
break;
case SPRN_IVOR12:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG]);
break;
case SPRN_IVOR13:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS]);
break;
case SPRN_IVOR14:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS]);
break;
case SPRN_IVOR15:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG]);
break;
default:
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 64949eef43f..669a5c5fc7d 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -13,6 +13,7 @@
*/
#include <linux/kvm_host.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <asm/reg.h>
@@ -60,6 +61,12 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
kvmppc_e500_tlb_setup(vcpu_e500);
+ /* Registers init */
+ vcpu->arch.pvr = mfspr(SPRN_PVR);
+
+ /* Since booke kvm only support one core, update all vcpus' PIR to 0 */
+ vcpu->vcpu_id = 0;
+
return 0;
}
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index be95b8d8e3b..8e3edfbc963 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -74,54 +74,59 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
{
struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
int emulated = EMULATE_DONE;
+ ulong spr_val = kvmppc_get_gpr(vcpu, rs);
switch (sprn) {
case SPRN_PID:
vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
- vcpu->arch.pid = vcpu->arch.gpr[rs];
+ vcpu->arch.pid = spr_val;
break;
case SPRN_PID1:
- vcpu_e500->pid[1] = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->pid[1] = spr_val; break;
case SPRN_PID2:
- vcpu_e500->pid[2] = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->pid[2] = spr_val; break;
case SPRN_MAS0:
- vcpu_e500->mas0 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->mas0 = spr_val; break;
case SPRN_MAS1:
- vcpu_e500->mas1 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->mas1 = spr_val; break;
case SPRN_MAS2:
- vcpu_e500->mas2 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->mas2 = spr_val; break;
case SPRN_MAS3:
- vcpu_e500->mas3 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->mas3 = spr_val; break;
case SPRN_MAS4:
- vcpu_e500->mas4 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->mas4 = spr_val; break;
case SPRN_MAS6:
- vcpu_e500->mas6 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->mas6 = spr_val; break;
case SPRN_MAS7:
- vcpu_e500->mas7 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->mas7 = spr_val; break;
+ case SPRN_L1CSR0:
+ vcpu_e500->l1csr0 = spr_val;
+ vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC);
+ break;
case SPRN_L1CSR1:
- vcpu_e500->l1csr1 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->l1csr1 = spr_val; break;
case SPRN_HID0:
- vcpu_e500->hid0 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->hid0 = spr_val; break;
case SPRN_HID1:
- vcpu_e500->hid1 = vcpu->arch.gpr[rs]; break;
+ vcpu_e500->hid1 = spr_val; break;
case SPRN_MMUCSR0:
emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
- vcpu->arch.gpr[rs]);
+ spr_val);
break;
/* extra exceptions */
case SPRN_IVOR32:
- vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val;
break;
case SPRN_IVOR33:
- vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = spr_val;
break;
case SPRN_IVOR34:
- vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val;
break;
case SPRN_IVOR35:
- vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = vcpu->arch.gpr[rs];
+ vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val;
break;
default:
@@ -138,63 +143,57 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
switch (sprn) {
case SPRN_PID:
- vcpu->arch.gpr[rt] = vcpu_e500->pid[0]; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[0]); break;
case SPRN_PID1:
- vcpu->arch.gpr[rt] = vcpu_e500->pid[1]; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[1]); break;
case SPRN_PID2:
- vcpu->arch.gpr[rt] = vcpu_e500->pid[2]; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[2]); break;
case SPRN_MAS0:
- vcpu->arch.gpr[rt] = vcpu_e500->mas0; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas0); break;
case SPRN_MAS1:
- vcpu->arch.gpr[rt] = vcpu_e500->mas1; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas1); break;
case SPRN_MAS2:
- vcpu->arch.gpr[rt] = vcpu_e500->mas2; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas2); break;
case SPRN_MAS3:
- vcpu->arch.gpr[rt] = vcpu_e500->mas3; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas3); break;
case SPRN_MAS4:
- vcpu->arch.gpr[rt] = vcpu_e500->mas4; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas4); break;
case SPRN_MAS6:
- vcpu->arch.gpr[rt] = vcpu_e500->mas6; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas6); break;
case SPRN_MAS7:
- vcpu->arch.gpr[rt] = vcpu_e500->mas7; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas7); break;
case SPRN_TLB0CFG:
- vcpu->arch.gpr[rt] = mfspr(SPRN_TLB0CFG);
- vcpu->arch.gpr[rt] &= ~0xfffUL;
- vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[0];
- break;
-
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->tlb0cfg); break;
case SPRN_TLB1CFG:
- vcpu->arch.gpr[rt] = mfspr(SPRN_TLB1CFG);
- vcpu->arch.gpr[rt] &= ~0xfffUL;
- vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[1];
- break;
-
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->tlb1cfg); break;
+ case SPRN_L1CSR0:
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr0); break;
case SPRN_L1CSR1:
- vcpu->arch.gpr[rt] = vcpu_e500->l1csr1; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr1); break;
case SPRN_HID0:
- vcpu->arch.gpr[rt] = vcpu_e500->hid0; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid0); break;
case SPRN_HID1:
- vcpu->arch.gpr[rt] = vcpu_e500->hid1; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid1); break;
case SPRN_MMUCSR0:
- vcpu->arch.gpr[rt] = 0; break;
+ kvmppc_set_gpr(vcpu, rt, 0); break;
case SPRN_MMUCFG:
- vcpu->arch.gpr[rt] = mfspr(SPRN_MMUCFG); break;
+ kvmppc_set_gpr(vcpu, rt, mfspr(SPRN_MMUCFG)); break;
/* extra exceptions */
case SPRN_IVOR32:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]);
break;
case SPRN_IVOR33:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]);
break;
case SPRN_IVOR34:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]);
break;
case SPRN_IVOR35:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]);
break;
default:
emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index fb1e1dc11ba..21011e12cae 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -13,6 +13,7 @@
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/kvm.h>
#include <linux/kvm_host.h>
@@ -417,7 +418,7 @@ int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb)
int esel, tlbsel;
gva_t ea;
- ea = ((ra) ? vcpu->arch.gpr[ra] : 0) + vcpu->arch.gpr[rb];
+ ea = ((ra) ? kvmppc_get_gpr(vcpu, ra) : 0) + kvmppc_get_gpr(vcpu, rb);
ia = (ea >> 2) & 0x1;
@@ -470,7 +471,7 @@ int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb)
struct tlbe *gtlbe = NULL;
gva_t ea;
- ea = vcpu->arch.gpr[rb];
+ ea = kvmppc_get_gpr(vcpu, rb);
for (tlbsel = 0; tlbsel < 2; tlbsel++) {
esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, as);
@@ -728,6 +729,12 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
if (vcpu_e500->shadow_pages[1] == NULL)
goto err_out_page0;
+ /* Init TLB configuration register */
+ vcpu_e500->tlb0cfg = mfspr(SPRN_TLB0CFG) & ~0xfffUL;
+ vcpu_e500->tlb0cfg |= vcpu_e500->guest_tlb_size[0];
+ vcpu_e500->tlb1cfg = mfspr(SPRN_TLB1CFG) & ~0xfffUL;
+ vcpu_e500->tlb1cfg |= vcpu_e500->guest_tlb_size[1];
+
return 0;
err_out_page0:
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 4a9ac6640fa..cb72a65f4ec 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -83,6 +83,9 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
pr_debug("mtDEC: %x\n", vcpu->arch.dec);
#ifdef CONFIG_PPC64
+ /* mtdec lowers the interrupt line when positive. */
+ kvmppc_core_dequeue_dec(vcpu);
+
/* POWER4+ triggers a dec interrupt if the value is < 0 */
if (vcpu->arch.dec & 0x80000000) {
hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
@@ -140,14 +143,18 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
+ /* Try again next time */
+ if (inst == KVM_INST_FETCH_FAILED)
+ return EMULATE_DONE;
+
switch (get_op(inst)) {
case OP_TRAP:
#ifdef CONFIG_PPC64
case OP_TRAP_64:
+ kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
#else
- vcpu->arch.esr |= ESR_PTR;
+ kvmppc_core_queue_program(vcpu, vcpu->arch.esr | ESR_PTR);
#endif
- kvmppc_core_queue_program(vcpu);
advance = 0;
break;
@@ -167,14 +174,14 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
case OP_31_XOP_STWX:
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu,
- vcpu->arch.gpr[rs],
+ kvmppc_get_gpr(vcpu, rs),
4, 1);
break;
case OP_31_XOP_STBX:
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu,
- vcpu->arch.gpr[rs],
+ kvmppc_get_gpr(vcpu, rs),
1, 1);
break;
@@ -183,14 +190,14 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
ra = get_ra(inst);
rb = get_rb(inst);
- ea = vcpu->arch.gpr[rb];
+ ea = kvmppc_get_gpr(vcpu, rb);
if (ra)
- ea += vcpu->arch.gpr[ra];
+ ea += kvmppc_get_gpr(vcpu, ra);
emulated = kvmppc_handle_store(run, vcpu,
- vcpu->arch.gpr[rs],
+ kvmppc_get_gpr(vcpu, rs),
1, 1);
- vcpu->arch.gpr[rs] = ea;
+ kvmppc_set_gpr(vcpu, rs, ea);
break;
case OP_31_XOP_LHZX:
@@ -203,12 +210,12 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
ra = get_ra(inst);
rb = get_rb(inst);
- ea = vcpu->arch.gpr[rb];
+ ea = kvmppc_get_gpr(vcpu, rb);
if (ra)
- ea += vcpu->arch.gpr[ra];
+ ea += kvmppc_get_gpr(vcpu, ra);
emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
- vcpu->arch.gpr[ra] = ea;
+ kvmppc_set_gpr(vcpu, ra, ea);
break;
case OP_31_XOP_MFSPR:
@@ -217,47 +224,49 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
switch (sprn) {
case SPRN_SRR0:
- vcpu->arch.gpr[rt] = vcpu->arch.srr0; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr0); break;
case SPRN_SRR1:
- vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr1); break;
case SPRN_PVR:
- vcpu->arch.gpr[rt] = vcpu->arch.pvr; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break;
case SPRN_PIR:
- vcpu->arch.gpr[rt] = vcpu->vcpu_id; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break;
case SPRN_MSSSR0:
- vcpu->arch.gpr[rt] = 0; break;
+ kvmppc_set_gpr(vcpu, rt, 0); break;
/* Note: mftb and TBRL/TBWL are user-accessible, so
* the guest can always access the real TB anyways.
* In fact, we probably will never see these traps. */
case SPRN_TBWL:
- vcpu->arch.gpr[rt] = get_tb() >> 32; break;
+ kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break;
case SPRN_TBWU:
- vcpu->arch.gpr[rt] = get_tb(); break;
+ kvmppc_set_gpr(vcpu, rt, get_tb()); break;
case SPRN_SPRG0:
- vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg0); break;
case SPRN_SPRG1:
- vcpu->arch.gpr[rt] = vcpu->arch.sprg1; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg1); break;
case SPRN_SPRG2:
- vcpu->arch.gpr[rt] = vcpu->arch.sprg2; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg2); break;
case SPRN_SPRG3:
- vcpu->arch.gpr[rt] = vcpu->arch.sprg3; break;
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg3); break;
/* Note: SPRG4-7 are user-readable, so we don't get
* a trap. */
case SPRN_DEC:
{
u64 jd = get_tb() - vcpu->arch.dec_jiffies;
- vcpu->arch.gpr[rt] = vcpu->arch.dec - jd;
- pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n", vcpu->arch.dec, jd, vcpu->arch.gpr[rt]);
+ kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd);
+ pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n",
+ vcpu->arch.dec, jd,
+ kvmppc_get_gpr(vcpu, rt));
break;
}
default:
emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
if (emulated == EMULATE_FAIL) {
printk("mfspr: unknown spr %x\n", sprn);
- vcpu->arch.gpr[rt] = 0;
+ kvmppc_set_gpr(vcpu, rt, 0);
}
break;
}
@@ -269,7 +278,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
rb = get_rb(inst);
emulated = kvmppc_handle_store(run, vcpu,
- vcpu->arch.gpr[rs],
+ kvmppc_get_gpr(vcpu, rs),
2, 1);
break;
@@ -278,14 +287,14 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
ra = get_ra(inst);
rb = get_rb(inst);
- ea = vcpu->arch.gpr[rb];
+ ea = kvmppc_get_gpr(vcpu, rb);
if (ra)
- ea += vcpu->arch.gpr[ra];
+ ea += kvmppc_get_gpr(vcpu, ra);
emulated = kvmppc_handle_store(run, vcpu,
- vcpu->arch.gpr[rs],
+ kvmppc_get_gpr(vcpu, rs),
2, 1);
- vcpu->arch.gpr[ra] = ea;
+ kvmppc_set_gpr(vcpu, ra, ea);
break;
case OP_31_XOP_MTSPR:
@@ -293,9 +302,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
rs = get_rs(inst);
switch (sprn) {
case SPRN_SRR0:
- vcpu->arch.srr0 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.srr0 = kvmppc_get_gpr(vcpu, rs); break;
case SPRN_SRR1:
- vcpu->arch.srr1 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.srr1 = kvmppc_get_gpr(vcpu, rs); break;
/* XXX We need to context-switch the timebase for
* watchdog and FIT. */
@@ -305,18 +314,18 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
case SPRN_MSSSR0: break;
case SPRN_DEC:
- vcpu->arch.dec = vcpu->arch.gpr[rs];
+ vcpu->arch.dec = kvmppc_get_gpr(vcpu, rs);
kvmppc_emulate_dec(vcpu);
break;
case SPRN_SPRG0:
- vcpu->arch.sprg0 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.sprg0 = kvmppc_get_gpr(vcpu, rs); break;
case SPRN_SPRG1:
- vcpu->arch.sprg1 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.sprg1 = kvmppc_get_gpr(vcpu, rs); break;
case SPRN_SPRG2:
- vcpu->arch.sprg2 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.sprg2 = kvmppc_get_gpr(vcpu, rs); break;
case SPRN_SPRG3:
- vcpu->arch.sprg3 = vcpu->arch.gpr[rs]; break;
+ vcpu->arch.sprg3 = kvmppc_get_gpr(vcpu, rs); break;
default:
emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs);
@@ -348,7 +357,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
rb = get_rb(inst);
emulated = kvmppc_handle_store(run, vcpu,
- vcpu->arch.gpr[rs],
+ kvmppc_get_gpr(vcpu, rs),
4, 0);
break;
@@ -363,7 +372,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
rb = get_rb(inst);
emulated = kvmppc_handle_store(run, vcpu,
- vcpu->arch.gpr[rs],
+ kvmppc_get_gpr(vcpu, rs),
2, 0);
break;
@@ -382,7 +391,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
ra = get_ra(inst);
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
- vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+ kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
break;
case OP_LBZ:
@@ -394,35 +403,39 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
ra = get_ra(inst);
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
- vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+ kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
break;
case OP_STW:
rs = get_rs(inst);
- emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+ emulated = kvmppc_handle_store(run, vcpu,
+ kvmppc_get_gpr(vcpu, rs),
4, 1);
break;
case OP_STWU:
ra = get_ra(inst);
rs = get_rs(inst);
- emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+ emulated = kvmppc_handle_store(run, vcpu,
+ kvmppc_get_gpr(vcpu, rs),
4, 1);
- vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+ kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
break;
case OP_STB:
rs = get_rs(inst);
- emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+ emulated = kvmppc_handle_store(run, vcpu,
+ kvmppc_get_gpr(vcpu, rs),
1, 1);
break;
case OP_STBU:
ra = get_ra(inst);
rs = get_rs(inst);
- emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+ emulated = kvmppc_handle_store(run, vcpu,
+ kvmppc_get_gpr(vcpu, rs),
1, 1);
- vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+ kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
break;
case OP_LHZ:
@@ -434,21 +447,23 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
ra = get_ra(inst);
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
- vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+ kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
break;
case OP_STH:
rs = get_rs(inst);
- emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+ emulated = kvmppc_handle_store(run, vcpu,
+ kvmppc_get_gpr(vcpu, rs),
2, 1);
break;
case OP_STHU:
ra = get_ra(inst);
rs = get_rs(inst);
- emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
+ emulated = kvmppc_handle_store(run, vcpu,
+ kvmppc_get_gpr(vcpu, rs),
2, 1);
- vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
+ kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
break;
default:
@@ -461,6 +476,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
advance = 0;
printk(KERN_ERR "Couldn't emulate instruction 0x%08x "
"(op %d xop %d)\n", inst, get_op(inst), get_xop(inst));
+ kvmppc_core_queue_program(vcpu, 0);
}
}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index f06cf93b178..297fcd2ff7d 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -25,6 +25,7 @@
#include <linux/vmalloc.h>
#include <linux/hrtimer.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <asm/cputable.h>
#include <asm/uaccess.h>
#include <asm/kvm_ppc.h>
@@ -137,6 +138,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
{
kvmppc_free_vcpus(kvm);
kvm_free_physmem(kvm);
+ cleanup_srcu_struct(&kvm->srcu);
kfree(kvm);
}
@@ -165,14 +167,24 @@ long kvm_arch_dev_ioctl(struct file *filp,
return -EINVAL;
}
-int kvm_arch_set_memory_region(struct kvm *kvm,
- struct kvm_userspace_memory_region *mem,
- struct kvm_memory_slot old,
- int user_alloc)
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
+ struct kvm_memory_slot old,
+ struct kvm_userspace_memory_region *mem,
+ int user_alloc)
{
return 0;
}
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+ struct kvm_userspace_memory_region *mem,
+ struct kvm_memory_slot old,
+ int user_alloc)
+{
+ return;
+}
+
+
void kvm_arch_flush_shadow(struct kvm *kvm)
{
}
@@ -260,34 +272,35 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
struct kvm_run *run)
{
- ulong *gpr = &vcpu->arch.gpr[vcpu->arch.io_gpr];
- *gpr = run->dcr.data;
+ kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->dcr.data);
}
static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
struct kvm_run *run)
{
- ulong *gpr = &vcpu->arch.gpr[vcpu->arch.io_gpr];
+ ulong gpr;
- if (run->mmio.len > sizeof(*gpr)) {
+ if (run->mmio.len > sizeof(gpr)) {
printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len);
return;
}
if (vcpu->arch.mmio_is_bigendian) {
switch (run->mmio.len) {
- case 4: *gpr = *(u32 *)run->mmio.data; break;
- case 2: *gpr = *(u16 *)run->mmio.data; break;
- case 1: *gpr = *(u8 *)run->mmio.data; break;
+ case 4: gpr = *(u32 *)run->mmio.data; break;
+ case 2: gpr = *(u16 *)run->mmio.data; break;
+ case 1: gpr = *(u8 *)run->mmio.data; break;
}
} else {
/* Convert BE data from userland back to LE. */
switch (run->mmio.len) {
- case 4: *gpr = ld_le32((u32 *)run->mmio.data); break;
- case 2: *gpr = ld_le16((u16 *)run->mmio.data); break;
- case 1: *gpr = *(u8 *)run->mmio.data; break;
+ case 4: gpr = ld_le32((u32 *)run->mmio.data); break;
+ case 2: gpr = ld_le16((u16 *)run->mmio.data); break;
+ case 1: gpr = *(u8 *)run->mmio.data; break;
}
}
+
+ kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr);
}
int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/lib/devres.c b/arch/powerpc/lib/devres.c
index 292115d98ea..deac4d30daf 100644
--- a/arch/powerpc/lib/devres.c
+++ b/arch/powerpc/lib/devres.c
@@ -8,6 +8,7 @@
*/
#include <linux/device.h> /* devres_*(), devm_ioremap_release() */
+#include <linux/gfp.h>
#include <linux/io.h> /* ioremap_flags() */
#include <linux/module.h> /* EXPORT_SYMBOL() */
diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c
index 36692f5c9a7..757c0bed9a9 100644
--- a/arch/powerpc/mm/dma-noncoherent.c
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -23,6 +23,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index c5394728bf2..1ed6b52f303 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -116,7 +116,7 @@ void loadcam_entry(int idx)
mtspr(SPRN_MAS2, TLBCAM[idx].MAS2);
mtspr(SPRN_MAS3, TLBCAM[idx].MAS3);
- if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+ if (mmu_has_feature(MMU_FTR_BIG_PHYS))
mtspr(SPRN_MAS7, TLBCAM[idx].MAS7);
asm volatile("isync;tlbwe;isync" : : : "memory");
@@ -152,18 +152,13 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
TLBCAM[index].MAS3 = (phys & MAS3_RPN) | MAS3_SX | MAS3_SR;
TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
- if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+ if (mmu_has_feature(MMU_FTR_BIG_PHYS))
TLBCAM[index].MAS7 = (u64)phys >> 32;
-#ifndef CONFIG_KGDB /* want user access for breakpoints */
if (flags & _PAGE_USER) {
TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
}
-#else
- TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
- TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
-#endif
tlbcam_addrs[index].start = virt;
tlbcam_addrs[index].limit = virt + size - 1;
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 123f7070238..9bb249c3046 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -9,6 +9,7 @@
#include <linux/mm.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/hugetlb.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 4ec900af332..767333005eb 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -31,6 +31,7 @@
#include <linux/initrd.h>
#include <linux/pagemap.h>
#include <linux/lmb.h>
+#include <linux/gfp.h>
#include <asm/pgalloc.h>
#include <asm/prom.h>
@@ -47,7 +48,7 @@
#include "mmu_decl.h"
#if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
-/* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */
+/* The amount of lowmem must be within 0xF0000000 - KERNELBASE. */
#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - PAGE_OFFSET))
#error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL"
#endif
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 776f28d02b6..d7fa50b09b4 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -42,6 +42,7 @@
#include <linux/poison.h>
#include <linux/lmb.h>
#include <linux/hugetlb.h>
+#include <linux/slab.h>
#include <asm/pgalloc.h>
#include <asm/page.h>
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 311224cdb7a..0f594d774bf 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/gfp.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/stddef.h>
@@ -48,6 +49,7 @@
#include <asm/sparsemem.h>
#include <asm/vdso.h>
#include <asm/fixmap.h>
+#include <asm/swiotlb.h>
#include "mmu_decl.h"
@@ -320,6 +322,11 @@ void __init mem_init(void)
struct page *page;
unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
+#ifdef CONFIG_SWIOTLB
+ if (ppc_swiotlb_enable)
+ swiotlb_init(1);
+#endif
+
num_physpages = lmb.memory.size >> PAGE_SHIFT;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index 51622daae09..2535828aa84 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/idr.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <asm/mmu_context.h>
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index dbc692145ec..1f2d9ff0989 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -47,6 +47,7 @@
#include <linux/bootmem.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
+#include <linux/slab.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b037d95eead..eaa7633515b 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -242,10 +242,11 @@ EXPORT_SYMBOL_GPL(of_node_to_nid);
*/
static int __init find_min_common_depth(void)
{
- int depth;
+ int depth, index;
const unsigned int *ref_points;
struct device_node *rtas_root;
unsigned int len;
+ struct device_node *options;
rtas_root = of_find_node_by_path("/rtas");
@@ -258,11 +259,23 @@ static int __init find_min_common_depth(void)
* configuration (should be all 0's) and the second is for a normal
* NUMA configuration.
*/
+ index = 1;
ref_points = of_get_property(rtas_root,
"ibm,associativity-reference-points", &len);
+ /*
+ * For type 1 affinity information we want the first field
+ */
+ options = of_find_node_by_path("/options");
+ if (options) {
+ const char *str;
+ str = of_get_property(options, "ibm,associativity-form", NULL);
+ if (str && !strcmp(str, "1"))
+ index = 0;
+ }
+
if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
- depth = ref_points[1];
+ depth = ref_points[index];
} else {
dbg("NUMA: ibm,associativity-reference-points not found.\n");
depth = -1;
@@ -451,7 +464,7 @@ static int __cpuinit numa_setup_cpu(unsigned long lcpu)
nid = of_node_to_nid_single(cpu);
if (nid < 0 || !node_online(nid))
- nid = any_online_node(NODE_MASK_ALL);
+ nid = first_online_node;
out:
map_cpu_to_node(lcpu, nid);
@@ -1114,7 +1127,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
int nid, found = 0;
if (!numa_enabled || (min_common_depth < 0))
- return any_online_node(NODE_MASK_ALL);
+ return first_online_node;
memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
if (memory) {
@@ -1125,7 +1138,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
}
if (nid < 0 || !node_online(nid))
- nid = any_online_node(NODE_MASK_ALL);
+ nid = first_online_node;
if (NODE_DATA(nid)->node_spanned_pages)
return nid;
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 99df697c601..ebc2f38eb38 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -22,6 +22,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/percpu.h>
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 573b3bd1c45..b9243e7557a 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/highmem.h>
#include <linux/lmb.h>
+#include <linux/slab.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 853d5565eed..d95679a5fb2 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/lmb.h>
+#include <linux/slab.h>
#include <asm/pgalloc.h>
#include <asm/page.h>
diff --git a/arch/powerpc/mm/subpage-prot.c b/arch/powerpc/mm/subpage-prot.c
index a040b81e93b..e4f8f1fc81a 100644
--- a/arch/powerpc/mm/subpage-prot.c
+++ b/arch/powerpc/mm/subpage-prot.c
@@ -10,7 +10,6 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/hugetlb.h>
diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c
index 6b793aeda72..642fca137cc 100644
--- a/arch/powerpc/oprofile/cell/spu_task_sync.c
+++ b/arch/powerpc/oprofile/cell/spu_task_sync.c
@@ -26,6 +26,7 @@
#include <linux/notifier.h>
#include <linux/numa.h>
#include <linux/oprofile.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include "pr_util.h"
diff --git a/arch/powerpc/oprofile/cell/vma_map.c b/arch/powerpc/oprofile/cell/vma_map.c
index c591339daf5..c579b16845d 100644
--- a/arch/powerpc/oprofile/cell/vma_map.c
+++ b/arch/powerpc/oprofile/cell/vma_map.c
@@ -20,6 +20,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/elf.h>
+#include <linux/slab.h>
#include "pr_util.h"
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index e5c1b096c3e..8f771395f42 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/of_gpio.h>
#include <linux/of_i2c.h>
+#include <linux/slab.h>
#include <asm/machdep.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
index 2b8d8ef32e4..fda7c2a1828 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
@@ -19,6 +19,7 @@
#include <linux/of.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/of_gpio.h>
#include <linux/io.h>
#include <linux/of_platform.h>
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 6f8ebe1085b..a60ee39d3b7 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -62,6 +62,7 @@
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/watchdog.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
@@ -553,7 +554,7 @@ static ssize_t mpc52xx_wdt_write(struct file *file, const char __user *data,
return 0;
}
-static struct watchdog_info mpc5200_wdt_info = {
+static const struct watchdog_info mpc5200_wdt_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
.identity = WDT_IDENTITY,
};
@@ -711,7 +712,11 @@ static int __devinit mpc52xx_gpt_wdt_init(void)
return 0;
}
-#define mpc52xx_gpt_wdt_setup(x, y) (0)
+static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
+ const u32 *period)
+{
+ return 0;
+}
#endif /* CONFIG_MPC5200_WDT */
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index 929d017535a..d4f8be307cd 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -481,6 +481,8 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
if (rc)
goto err_bcom_rx_irq;
+ lpbfifo.dma_irqs_enabled = 1;
+
/* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
lpbfifo.bcom_tx_task =
bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index f9aee182e6f..f21555d3395 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -15,6 +15,7 @@
#include <linux/fsl_devices.h>
#include <linux/mdio-bitbang.h>
#include <linux/of_mdio.h>
+#include <linux/slab.h>
#include <linux/of_platform.h>
#include <asm/io.h>
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 9d962d7c72c..5a55d87d6bd 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -17,6 +17,7 @@
#include <linux/irq.h>
#include <linux/types.h>
#include <linux/bootmem.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -24,7 +25,7 @@
#include "pq2.h"
-static DEFINE_SPINLOCK(pci_pic_lock);
+static DEFINE_RAW_SPINLOCK(pci_pic_lock);
struct pq2ads_pci_pic {
struct device_node *node;
@@ -45,12 +46,12 @@ static void pq2ads_pci_mask_irq(unsigned int virq)
if (irq != -1) {
unsigned long flags;
- spin_lock_irqsave(&pci_pic_lock, flags);
+ raw_spin_lock_irqsave(&pci_pic_lock, flags);
setbits32(&priv->regs->mask, 1 << irq);
mb();
- spin_unlock_irqrestore(&pci_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pci_pic_lock, flags);
}
}
@@ -62,9 +63,9 @@ static void pq2ads_pci_unmask_irq(unsigned int virq)
if (irq != -1) {
unsigned long flags;
- spin_lock_irqsave(&pci_pic_lock, flags);
+ raw_spin_lock_irqsave(&pci_pic_lock, flags);
clrbits32(&priv->regs->mask, 1 << irq);
- spin_unlock_irqrestore(&pci_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pci_pic_lock, flags);
}
}
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
index 82a9bcb858b..d119a7c1c17 100644
--- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
+++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
@@ -20,6 +20,7 @@
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/machdep.h>
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index d95121894eb..3a2ade2e443 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -51,7 +51,7 @@ config MPC85xx_DS
bool "Freescale MPC85xx DS"
select PPC_I8259
select DEFAULT_UIMAGE
- select FSL_ULI1575
+ select FSL_ULI1575 if PCI
select SWIOTLB
help
This option enables support for the MPC85xx DS (MPC8544 DS) board
@@ -60,7 +60,7 @@ config MPC85xx_RDB
bool "Freescale MPC85xx RDB"
select PPC_I8259
select DEFAULT_UIMAGE
- select FSL_ULI1575
+ select FSL_ULI1575 if PCI
select SWIOTLB
help
This option enables support for the MPC85xx RDB (P2020 RDB) board
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 42e87f08aa0..d48527ffc42 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -50,7 +50,7 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
#define socrates_fpga_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
-static DEFINE_SPINLOCK(socrates_fpga_pic_lock);
+static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
static void __iomem *socrates_fpga_pic_iobase;
static struct irq_host *socrates_fpga_pic_irq_host;
@@ -80,9 +80,9 @@ static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq)
if (i == 3)
return NO_IRQ;
- spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i));
- spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) {
if (cause >> (i + 16))
break;
@@ -116,12 +116,12 @@ static void socrates_fpga_pic_ack(unsigned int virq)
hwirq = socrates_fpga_irq_to_hw(virq);
irq_line = fpga_irqs[hwirq].irq_line;
- spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
& SOCRATES_FPGA_IRQ_MASK;
mask |= (1 << (hwirq + 16));
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
- spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static void socrates_fpga_pic_mask(unsigned int virq)
@@ -134,12 +134,12 @@ static void socrates_fpga_pic_mask(unsigned int virq)
hwirq = socrates_fpga_irq_to_hw(virq);
irq_line = fpga_irqs[hwirq].irq_line;
- spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
& SOCRATES_FPGA_IRQ_MASK;
mask &= ~(1 << hwirq);
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
- spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static void socrates_fpga_pic_mask_ack(unsigned int virq)
@@ -152,13 +152,13 @@ static void socrates_fpga_pic_mask_ack(unsigned int virq)
hwirq = socrates_fpga_irq_to_hw(virq);
irq_line = fpga_irqs[hwirq].irq_line;
- spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
& SOCRATES_FPGA_IRQ_MASK;
mask &= ~(1 << hwirq);
mask |= (1 << (hwirq + 16));
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
- spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static void socrates_fpga_pic_unmask(unsigned int virq)
@@ -171,12 +171,12 @@ static void socrates_fpga_pic_unmask(unsigned int virq)
hwirq = socrates_fpga_irq_to_hw(virq);
irq_line = fpga_irqs[hwirq].irq_line;
- spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
& SOCRATES_FPGA_IRQ_MASK;
mask |= (1 << hwirq);
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
- spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static void socrates_fpga_pic_eoi(unsigned int virq)
@@ -189,12 +189,12 @@ static void socrates_fpga_pic_eoi(unsigned int virq)
hwirq = socrates_fpga_irq_to_hw(virq);
irq_line = fpga_irqs[hwirq].irq_line;
- spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
& SOCRATES_FPGA_IRQ_MASK;
mask |= (1 << (hwirq + 16));
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
- spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static int socrates_fpga_pic_set_type(unsigned int virq,
@@ -220,14 +220,14 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
default:
return -EINVAL;
}
- spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG);
if (polarity)
mask |= (1 << hwirq);
else
mask &= ~(1 << hwirq);
socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask);
- spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
return 0;
}
@@ -314,14 +314,14 @@ void socrates_fpga_pic_init(struct device_node *pic)
socrates_fpga_pic_iobase = of_iomap(pic, 0);
- spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0),
SOCRATES_FPGA_IRQ_MASK << 16);
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1),
SOCRATES_FPGA_IRQ_MASK << 16);
socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2),
SOCRATES_FPGA_IRQ_MASK << 16);
- spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n");
}
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 2bbfd530d6d..a0b5638c5dc 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -13,7 +13,7 @@ config MPC8641_HPCN
bool "Freescale MPC8641 HPCN"
select PPC_I8259
select DEFAULT_UIMAGE
- select FSL_ULI1575
+ select FSL_ULI1575 if PCI
select HAS_RAPIDIO
select SWIOTLB
help
@@ -28,37 +28,37 @@ config SBC8641D
config MPC8610_HPCD
bool "Freescale MPC8610 HPCD"
select DEFAULT_UIMAGE
- select FSL_ULI1575
+ select FSL_ULI1575 if PCI
help
This option enables support for the MPC8610 HPCD board.
config GEF_PPC9A
- bool "GE Fanuc PPC9A"
+ bool "GE PPC9A"
select DEFAULT_UIMAGE
select MMIO_NVRAM
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
help
- This option enables support for GE Fanuc's PPC9A.
+ This option enables support for the GE PPC9A.
config GEF_SBC310
- bool "GE Fanuc SBC310"
+ bool "GE SBC310"
select DEFAULT_UIMAGE
select MMIO_NVRAM
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
help
- This option enables support for GE Fanuc's SBC310.
+ This option enables support for the GE SBC310.
config GEF_SBC610
- bool "GE Fanuc SBC610"
+ bool "GE SBC610"
select DEFAULT_UIMAGE
select MMIO_NVRAM
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select HAS_RAPIDIO
help
- This option enables support for GE Fanuc's SBC610.
+ This option enables support for the GE SBC610.
endif
diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c
index b2ea8875adb..b8cb08dbd89 100644
--- a/arch/powerpc/platforms/86xx/gef_gpio.c
+++ b/arch/powerpc/platforms/86xx/gef_gpio.c
@@ -1,9 +1,9 @@
/*
- * Driver for GE Fanuc's FPGA based GPIO pins
+ * Driver for GE FPGA based GPIO
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
*
- * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * 2008 (c) GE Intelligent Platforms Embedded Systems, 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
@@ -26,6 +26,7 @@
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#define GEF_GPIO_DIRECT 0x00
#define GEF_GPIO_IN 0x04
@@ -164,6 +165,6 @@ static int __init gef_gpio_init(void)
};
arch_initcall(gef_gpio_init);
-MODULE_DESCRIPTION("GE Fanuc I/O FPGA GPIO driver");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 0110a8736d3..6df9e2561c0 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -1,9 +1,9 @@
/*
- * Interrupt handling for GE Fanuc's FPGA based PIC
+ * Interrupt handling for GE FPGA based PIC
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
*
- * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * 2008 (c) GE Intelligent Platforms Embedded Systems, 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
@@ -49,7 +49,7 @@
#define gef_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
-static DEFINE_SPINLOCK(gef_pic_lock);
+static DEFINE_RAW_SPINLOCK(gef_pic_lock);
static void __iomem *gef_pic_irq_reg_base;
static struct irq_host *gef_pic_irq_host;
@@ -118,11 +118,11 @@ static void gef_pic_mask(unsigned int virq)
hwirq = gef_irq_to_hw(virq);
- spin_lock_irqsave(&gef_pic_lock, flags);
+ raw_spin_lock_irqsave(&gef_pic_lock, flags);
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
mask &= ~(1 << hwirq);
out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
- spin_unlock_irqrestore(&gef_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
}
static void gef_pic_mask_ack(unsigned int virq)
@@ -141,11 +141,11 @@ static void gef_pic_unmask(unsigned int virq)
hwirq = gef_irq_to_hw(virq);
- spin_lock_irqsave(&gef_pic_lock, flags);
+ raw_spin_lock_irqsave(&gef_pic_lock, flags);
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
mask |= (1 << hwirq);
out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
- spin_unlock_irqrestore(&gef_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
}
static struct irq_chip gef_pic_chip = {
@@ -199,7 +199,7 @@ void __init gef_pic_init(struct device_node *np)
/* Map the devices registers into memory */
gef_pic_irq_reg_base = of_iomap(np, 0);
- spin_lock_irqsave(&gef_pic_lock, flags);
+ raw_spin_lock_irqsave(&gef_pic_lock, flags);
/* Initialise everything as masked. */
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0);
@@ -208,7 +208,7 @@ void __init gef_pic_init(struct device_node *np)
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0);
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0);
- spin_unlock_irqrestore(&gef_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
/* Map controller */
gef_pic_cascade_irq = irq_of_parse_and_map(np, 0);
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index a792e5d8581..60ce07e3910 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -1,9 +1,9 @@
/*
- * GE Fanuc PPC9A board support
+ * GE PPC9A board support
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
*
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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
@@ -82,7 +82,7 @@ static void __init gef_ppc9a_setup_arch(void)
}
#endif
- printk(KERN_INFO "GE Fanuc Intelligent Platforms PPC9A 6U VME SBC\n");
+ printk(KERN_INFO "GE Intelligent Platforms PPC9A 6U VME SBC\n");
#ifdef CONFIG_SMP
mpc86xx_smp_init();
@@ -151,7 +151,7 @@ static void gef_ppc9a_show_cpuinfo(struct seq_file *m)
{
uint svid = mfspr(SPRN_SVR);
- seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+ seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(),
('A' + gef_ppc9a_get_board_rev()));
@@ -235,7 +235,7 @@ static int __init declare_of_platform_devices(void)
machine_device_initcall(gef_ppc9a, declare_of_platform_devices);
define_machine(gef_ppc9a) {
- .name = "GE Fanuc PPC9A",
+ .name = "GE PPC9A",
.probe = gef_ppc9a_probe,
.setup_arch = gef_ppc9a_setup_arch,
.init_IRQ = gef_ppc9a_init_irq,
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
index 6a1a613836c..3ecee25bf3e 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -1,9 +1,9 @@
/*
- * GE Fanuc SBC310 board support
+ * GE SBC310 board support
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
*
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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
@@ -82,7 +82,7 @@ static void __init gef_sbc310_setup_arch(void)
}
#endif
- printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC310 6U VPX SBC\n");
+ printk(KERN_INFO "GE Intelligent Platforms SBC310 6U VPX SBC\n");
#ifdef CONFIG_SMP
mpc86xx_smp_init();
@@ -142,7 +142,7 @@ static void gef_sbc310_show_cpuinfo(struct seq_file *m)
{
uint svid = mfspr(SPRN_SVR);
- seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+ seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
seq_printf(m, "Board ID\t: 0x%2.2x\n", gef_sbc310_get_board_id());
seq_printf(m, "Revision\t: %u%c\n", gef_sbc310_get_pcb_rev(),
@@ -223,7 +223,7 @@ static int __init declare_of_platform_devices(void)
machine_device_initcall(gef_sbc310, declare_of_platform_devices);
define_machine(gef_sbc310) {
- .name = "GE Fanuc SBC310",
+ .name = "GE SBC310",
.probe = gef_sbc310_probe,
.setup_arch = gef_sbc310_setup_arch,
.init_IRQ = gef_sbc310_init_irq,
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index e10688a0fc4..5090d608d9e 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -1,9 +1,9 @@
/*
- * GE Fanuc SBC610 board support
+ * GE SBC610 board support
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
*
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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
@@ -82,7 +82,7 @@ static void __init gef_sbc610_setup_arch(void)
}
#endif
- printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC610 6U VPX SBC\n");
+ printk(KERN_INFO "GE Intelligent Platforms SBC610 6U VPX SBC\n");
#ifdef CONFIG_SMP
mpc86xx_smp_init();
@@ -133,7 +133,7 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m)
{
uint svid = mfspr(SPRN_SVR);
- seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+ seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
seq_printf(m, "Revision\t: %u%c\n", gef_sbc610_get_pcb_rev(),
('A' + gef_sbc610_get_board_rev() - 1));
@@ -212,7 +212,7 @@ static int __init declare_of_platform_devices(void)
machine_device_initcall(gef_sbc610, declare_of_platform_devices);
define_machine(gef_sbc610) {
- .name = "GE Fanuc SBC610",
+ .name = "GE SBC610",
.probe = gef_sbc610_probe,
.setup_arch = gef_sbc610_setup_arch,
.init_IRQ = gef_sbc610_init_irq,
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 242954c4293..60168c1f98f 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -11,7 +11,6 @@
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/time.h>
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index fa0f690d386..a8aae0b5457 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -144,6 +144,16 @@ config FSL_EMB_PERFMON
and some e300 cores (c3 and c4). Select this only if your
core supports the Embedded Performance Monitor APU
+config FSL_EMB_PERF_EVENT
+ bool
+ depends on FSL_EMB_PERFMON && PERF_EVENTS && !PPC_PERF_CTRS
+ default y
+
+config FSL_EMB_PERF_EVENT_E500
+ bool
+ depends on FSL_EMB_PERF_EVENT && E500
+ default y
+
config 4xx
bool
depends on 40x || 44x
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 96fe896f6df..8efe48192f3 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -15,6 +15,7 @@
#include <linux/msi.h>
#include <linux/of_platform.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <asm/dcr.h>
#include <asm/machdep.h>
diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c
index 00eaaa71630..404d1fc04d5 100644
--- a/arch/powerpc/platforms/cell/celleb_pci.c
+++ b/arch/powerpc/platforms/cell/celleb_pci.c
@@ -33,6 +33,7 @@
#include <linux/pci_regs.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index 7fca09f990b..a881bbee8de 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/delay.h>
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index ca5bfdfe47f..e3ec4976fae 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -28,6 +28,7 @@
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <linux/lmb.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c
index 608fd2b584c..1d3c4effea1 100644
--- a/arch/powerpc/platforms/cell/ras.c
+++ b/arch/powerpc/platforms/cell/ras.c
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/reboot.h>
#include <linux/kexec.h>
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 59305369f6b..50385db586b 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -19,7 +19,6 @@
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/reboot.h>
#include <linux/init.h>
diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c
index 5122ec14527..ca7731c0b59 100644
--- a/arch/powerpc/platforms/cell/spider-pci.c
+++ b/arch/powerpc/platforms/cell/spider-pci.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <asm/ppc-pci.h>
diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index 891f18e337a..f465d474ad9 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -23,7 +23,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/io.h>
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
index 1410443731e..121aec353f2 100644
--- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c
+++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
@@ -22,7 +22,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/io.h>
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index eea120229cd..6cf3ec62852 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -24,6 +24,7 @@
#include <linux/file.h>
#include <linux/fdtable.h>
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/syscalls.h>
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 64a4c2d85f7..5c280825251 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -29,6 +29,7 @@
#include <linux/poll.h>
#include <linux/ptrace.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/time.h>
diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
index 0e9f325c9ff..a101abf1750 100644
--- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
+++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/spu.h>
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 4678078fede..0b046628493 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -27,6 +27,7 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index c23617c6baf..187a7d32f86 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -3,6 +3,7 @@
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
index 8efd4244701..ba3588f2d8e 100644
--- a/arch/powerpc/platforms/chrp/nvram.c
+++ b/arch/powerpc/platforms/chrp/nvram.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 8f41685d8f4..8553cc49e0d 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -15,7 +15,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/tty.h>
#include <linux/major.h>
diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S
index 5369653dcf6..fba5bf91507 100644
--- a/arch/powerpc/platforms/iseries/exception.S
+++ b/arch/powerpc/platforms/iseries/exception.S
@@ -43,17 +43,14 @@ system_reset_iSeries:
LOAD_REG_ADDR(r23, alpaca)
li r0,ALPACA_SIZE
sub r23,r13,r23
- divdu r23,r23,r0 /* r23 has cpu number */
- LOAD_REG_ADDR(r13, paca)
- mulli r0,r23,PACA_SIZE
- add r13,r13,r0
- mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */
- mfmsr r24
- ori r24,r24,MSR_RI
- mtmsrd r24 /* RI on */
- mr r24,r23
+ divdu r24,r23,r0 /* r24 has cpu number */
cmpwi 0,r24,0 /* Are we processor 0? */
bne 1f
+ LOAD_REG_ADDR(r13, boot_paca)
+ mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */
+ mfmsr r23
+ ori r23,r23,MSR_RI
+ mtmsrd r23 /* RI on */
b .__start_initialization_iSeries /* Start up the first processor */
1: mfspr r4,SPRN_CTRLF
li r5,CTRL_RUNLATCH /* Turn off the run light */
@@ -86,6 +83,16 @@ system_reset_iSeries:
#endif
2:
+ /* Load our paca now that it's been allocated */
+ LOAD_REG_ADDR(r13, paca)
+ ld r13,0(r13)
+ mulli r0,r24,PACA_SIZE
+ add r13,r13,r0
+ mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */
+ mfmsr r23
+ ori r23,r23,MSR_RI
+ mtmsrd r23 /* RI on */
+
HMT_LOW
#ifdef CONFIG_SMP
lbz r23,PACAPROCSTART(r13) /* Test if this processor
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 9d53cb481a7..ce61cea0afb 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -29,6 +29,7 @@
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/iommu.h>
#include <asm/vio.h>
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 6617915bcb1..d2c1d497846 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -33,6 +33,7 @@
#include <linux/dma-mapping.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
#include <asm/time.h>
#include <asm/uaccess.h>
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 175aac8ca7e..b841c9a9db8 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 2aa8b5631be..00b6730bc48 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -22,7 +22,7 @@
*/
#include <linux/of.h>
#include <linux/init.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 5aea94f3083..b5f05d943a9 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -29,6 +29,7 @@
*/
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/vmalloc.h>
#include <linux/string.h>
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 0636a3df697..39df70529d2 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -21,7 +21,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/tty.h>
#include <linux/string.h>
diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c
index a6152d92224..09695ae50f9 100644
--- a/arch/powerpc/platforms/pasemi/dma_lib.c
+++ b/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/of.h>
#include <asm/pasemi_dma.h>
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index 3bf546797cb..0f881f64583 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/ioport.h>
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 242f8095c2d..ac6fdd97329 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -28,6 +28,7 @@
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/of_platform.h>
+#include <linux/gfp.h>
#include <asm/prom.h>
#include <asm/system.h>
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index d4f127d1814..1e9eba175ff 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -21,7 +21,6 @@
#include <linux/sched.h>
#include <linux/adb.h>
#include <linux/pmu.h>
-#include <linux/slab.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/sysdev.h>
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 3ed288e68ec..3ca09d3ccce 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/completion.h>
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 345e2da5676..f45331ab97c 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -43,6 +43,7 @@
#include <linux/timer.h>
#include <linux/mutex.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <asm/keylargo.h>
#include <asm/uninorth.h>
#include <asm/io.h>
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 80a5258d036..b1cdcf94aa8 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -14,7 +14,6 @@
#include <linux/string.h>
#include <linux/nvram.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/adb.h>
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index ede49e78a8d..cec63594265 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mutex.h>
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index c2052265636..15c2241f9c7 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -31,7 +31,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/tty.h>
#include <linux/string.h>
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index bb028f165fb..b341018326d 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/reboot.h>
#include <asm/firmware.h>
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index e81b028a2a4..7925751e464 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/memory_hotplug.h>
#include <linux/lmb.h>
+#include <linux/slab.h>
#include <asm/cell-regs.h>
#include <asm/firmware.h>
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index d6487a9c801..dd521a181f2 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -26,6 +26,7 @@
#include <linux/ctype.h>
#include <linux/lmb.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index b3c6a993f9f..39a472e9e80 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mmzone.h>
#include <linux/io.h>
#include <linux/mm.h>
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index e34b305a7a5..6d09f5e3e7e 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <asm/udbg.h>
#include <asm/lv1call.h>
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c
index a277f2e28db..f4803868642 100644
--- a/arch/powerpc/platforms/pseries/cmm.c
+++ b/arch/powerpc/platforms/pseries/cmm.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/module.h>
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 37bce52526d..e1682bc168a 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -16,6 +16,7 @@
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/cpu.h>
+#include <linux/slab.h>
#include "offline_states.h"
#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index c5f3116b6ca..a00addb5594 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -21,6 +21,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/debugfs.h>
#include <asm/smp.h>
#include <asm/system.h>
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index ce37040af87..30b987b73c2 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -23,6 +23,7 @@
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/rbtree.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
#include <asm/pci-bridge.h>
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index ec5df8f519c..2ec500c130b 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -22,6 +22,7 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <asm/eeh_event.h>
#include <asm/ppc-pci.h>
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index d1b124e44d7..a8e1d5d17a2 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -122,44 +122,32 @@ static void pseries_mach_cpu_die(void)
if (!get_lppaca()->shared_proc)
get_lppaca()->donate_dedicated_cpu = 1;
- printk(KERN_INFO
- "cpu %u (hwid %u) ceding for offline with hint %d\n",
- cpu, hwcpu, cede_latency_hint);
while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
extended_cede_processor(cede_latency_hint);
- printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n",
- cpu, hwcpu);
- printk(KERN_INFO
- "Decrementer value = %x Timebase value = %llx\n",
- get_dec(), get_tb());
}
- printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n",
- cpu, hwcpu);
-
if (!get_lppaca()->shared_proc)
get_lppaca()->donate_dedicated_cpu = 0;
get_lppaca()->idle = 0;
- }
- if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
- unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+ if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
+ unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
- /*
- * NOTE: Calling start_secondary() here for now to
- * start new context.
- * However, need to do it cleanly by resetting the
- * stack pointer.
- */
- start_secondary();
+ /*
+ * Call to start_secondary_resume() will not return.
+ * Kernel stack will be reset and start_secondary()
+ * will be called to continue the online operation.
+ */
+ start_secondary_resume();
+ }
+ }
- } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
+ /* Requested state is CPU_STATE_OFFLINE at this point */
+ WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE);
- set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
- unregister_slb_shadow(hard_smp_processor_id(),
- __pa(get_slb_shadow()));
- rtas_stop_self();
- }
+ set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
+ unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+ rtas_stop_self();
/* Should never get here... */
BUG();
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 9b21ee68ea5..01e7b5bb3c1 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -11,6 +11,7 @@
#include <linux/of.h>
#include <linux/lmb.h>
+#include <linux/vmalloc.h>
#include <asm/firmware.h>
#include <asm/machdep.h>
#include <asm/pSeries_reconfig.h>
@@ -54,6 +55,12 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size)
*/
start = (unsigned long)__va(base);
ret = remove_section_mapping(start, start + lmb_size);
+
+ /* Ensure all vmalloc mappings are flushed in case they also
+ * hit that section of memory
+ */
+ vm_unmap_aliases();
+
return ret;
}
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 42f7e384e6c..bc3c7f2abd7 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -15,7 +15,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <asm/nvram.h>
diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h
index 22574e0d9d9..75a6f480d93 100644
--- a/arch/powerpc/platforms/pseries/offline_states.h
+++ b/arch/powerpc/platforms/pseries/offline_states.h
@@ -9,10 +9,31 @@ enum cpu_state_vals {
CPU_MAX_OFFLINE_STATES
};
+#ifdef CONFIG_HOTPLUG_CPU
extern enum cpu_state_vals get_cpu_current_state(int cpu);
extern void set_cpu_current_state(int cpu, enum cpu_state_vals state);
-extern enum cpu_state_vals get_preferred_offline_state(int cpu);
extern void set_preferred_offline_state(int cpu, enum cpu_state_vals state);
extern void set_default_offline_state(int cpu);
+#else
+static inline enum cpu_state_vals get_cpu_current_state(int cpu)
+{
+ return CPU_STATE_ONLINE;
+}
+
+static inline void set_cpu_current_state(int cpu, enum cpu_state_vals state)
+{
+}
+
+static inline void set_preferred_offline_state(int cpu, enum cpu_state_vals state)
+{
+}
+
+static inline void set_default_offline_state(int cpu)
+{
+}
+#endif
+
+extern enum cpu_state_vals get_preferred_offline_state(int cpu);
extern int start_secondary(void);
+extern void start_secondary_resume(void);
#endif
diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c
index 225a50ab14b..7ebd9e88d36 100644
--- a/arch/powerpc/platforms/pseries/phyp_dump.c
+++ b/arch/powerpc/platforms/pseries/phyp_dump.c
@@ -11,6 +11,7 @@
*
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/mm.h>
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index 0603c91538a..a05f8d42785 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -259,12 +259,12 @@ static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
return plpar_hcall_norets(H_IPI, servernum, mfrr);
}
-static inline long plpar_xirr(unsigned long *xirr_ret)
+static inline long plpar_xirr(unsigned long *xirr_ret, unsigned char cppr)
{
long rc;
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
- rc = plpar_hcall(H_XIRR, retbuf);
+ rc = plpar_hcall(H_XIRR, retbuf, cppr);
*xirr_ret = retbuf[0];
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index d20b96e22c2..db940d2c39a 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -30,7 +30,6 @@
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/random.h>
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index a2305d29bbb..1a58637bcea 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -15,6 +15,7 @@
#include <linux/kref.h>
#include <linux/notifier.h>
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/machdep.h>
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 1b45c458f95..80e9e7652a4 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -26,6 +26,7 @@
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/rtas.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ca5f2e10972..6710761bf60 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -23,7 +23,6 @@
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/tty.h>
#include <linux/major.h>
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 4ca641042ec..1bcedd8b461 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -120,12 +120,12 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
/* LPAR low level accessors */
-static inline unsigned int lpar_xirr_info_get(void)
+static inline unsigned int lpar_xirr_info_get(unsigned char cppr)
{
unsigned long lpar_rc;
unsigned long return_value;
- lpar_rc = plpar_xirr(&return_value);
+ lpar_rc = plpar_xirr(&return_value, cppr);
if (lpar_rc != H_SUCCESS)
panic(" bad return code xirr - rc = %lx\n", lpar_rc);
return (unsigned int)return_value;
@@ -331,7 +331,8 @@ static unsigned int xics_get_irq_direct(void)
static unsigned int xics_get_irq_lpar(void)
{
- unsigned int xirr = lpar_xirr_info_get();
+ struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+ unsigned int xirr = lpar_xirr_info_get(os_cppr->stack[os_cppr->index]);
unsigned int vec = xics_xirr_vector(xirr);
unsigned int irq;
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index ecad10d4e92..8d103ca6d6a 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -31,6 +31,7 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/8xx_immap.h>
@@ -485,9 +486,6 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
return -EINVAL;
}
- if (reg == &mpc8xx_immr->im_cpm.cp_sicr && mode == CPM_CLK_RX)
- shift += 3;
-
for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
if (clk_map[i][0] == target && clk_map[i][1] == clock) {
bits = clk_map[i][2];
@@ -502,6 +500,17 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
bits <<= shift;
mask <<= shift;
+
+ if (reg == &mpc8xx_immr->im_cpm.cp_sicr) {
+ if (mode == CPM_CLK_RTX) {
+ bits |= bits << 3;
+ mask |= mask << 3;
+ } else if (mode == CPM_CLK_RX) {
+ bits <<= 3;
+ mask <<= 3;
+ }
+ }
+
out_be32(reg, (in_be32(reg) & ~mask) | bits);
return 0;
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
index eb5927212fa..8dc1e24f3c2 100644
--- a/arch/powerpc/sysdev/cpm2.c
+++ b/arch/powerpc/sysdev/cpm2.c
@@ -244,9 +244,6 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
return -EINVAL;
}
- if (mode == CPM_CLK_RX)
- shift += 3;
-
for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
if (clk_map[i][0] == target && clk_map[i][1] == clock) {
bits = clk_map[i][2];
@@ -259,6 +256,14 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
bits <<= shift;
mask <<= shift;
+ if (mode == CPM_CLK_RTX) {
+ bits |= bits << 3;
+ mask |= mask << 3;
+ } else if (mode == CPM_CLK_RX) {
+ bits <<= 3;
+ mask <<= 3;
+ }
+
out_be32(reg, (in_be32(reg) & ~mask) | bits);
cpm2_unmap(im_cpmux);
diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/cpm2_pic.h
index 30e5828a278..2c5f70c2448 100644
--- a/arch/powerpc/sysdev/cpm2_pic.h
+++ b/arch/powerpc/sysdev/cpm2_pic.h
@@ -3,6 +3,6 @@
extern unsigned int cpm2_get_irq(void);
-extern void cpm2_pic_init(struct device_node*);
+extern void cpm2_pic_init(struct device_node *);
#endif /* _PPC_KERNEL_CPM2_H */
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index 9de72c96e6d..88b9812c854 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -21,6 +21,7 @@
#include <linux/of_device.h>
#include <linux/spinlock.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <asm/udbg.h>
#include <asm/io.h>
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index bafc3f85360..c8b96ed7c01 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -29,7 +29,6 @@
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/string.h>
@@ -38,6 +37,7 @@
#include <linux/vmalloc.h>
#include <linux/suspend.h>
#include <linux/lmb.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/iommu.h>
diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c
index 714ec02fed2..eca4545dd52 100644
--- a/arch/powerpc/sysdev/fsl_gtm.c
+++ b/arch/powerpc/sysdev/fsl_gtm.c
@@ -20,6 +20,7 @@
#include <linux/of.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/fsl_gtm.h>
#define GTCFR_STP(x) ((x) & 1 ? 1 << 5 : 1 << 1)
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index e094367d773..3482e3fd89c 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -16,6 +16,7 @@
#include <linux/bootmem.h>
#include <linux/msi.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/of_platform.h>
#include <sysdev/fsl_soc.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index e1a028c1f18..a14760fe513 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -25,6 +25,7 @@
#include <linux/bootmem.h>
#include <linux/lmb.h>
#include <linux/log2.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/prom.h>
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 757a83fe5e5..71fba88f50d 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -23,6 +23,7 @@
#include <linux/rio_drv.h>
#include <linux/of_platform.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/io.h>
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
index ee1c0e1cf4a..6478eb10691 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c
@@ -15,6 +15,7 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#define MPC8XXX_GPIO_PINS 32
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 339e8a3e26d..260295b1055 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -26,6 +26,7 @@
#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <asm/ptrace.h>
#include <asm/signal.h>
diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c
index 5a32cbef9b6..5287e95cec3 100644
--- a/arch/powerpc/sysdev/msi_bitmap.c
+++ b/arch/powerpc/sysdev/msi_bitmap.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/bitmap.h>
#include <asm/msi_bitmap.h>
diff --git a/arch/powerpc/sysdev/of_rtc.c b/arch/powerpc/sysdev/of_rtc.c
index 3d54450640c..c9e803f3e26 100644
--- a/arch/powerpc/sysdev/of_rtc.c
+++ b/arch/powerpc/sysdev/of_rtc.c
@@ -12,6 +12,7 @@
#include <linux/of.h>
#include <linux/init.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
static __initdata struct {
const char *compatible;
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index aaa915998eb..652652db4ce 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -25,6 +25,7 @@
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c
index 110efe2a54f..3812fc366be 100644
--- a/arch/powerpc/sysdev/ppc4xx_gpio.c
+++ b/arch/powerpc/sysdev/ppc4xx_gpio.c
@@ -29,6 +29,7 @@
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/types.h>
+#include <linux/slab.h>
#define GPIO_MASK(gpio) (0x80000000 >> (gpio))
#define GPIO_MASK2(gpio) (0xc0000000 >> ((gpio) * 2))
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 8aa33021e50..106d767bf65 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -24,6 +24,7 @@
#include <linux/of.h>
#include <linux/bootmem.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/pci-bridge.h>
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c
index 8e7a7767dd5..dc8f8d61807 100644
--- a/arch/powerpc/sysdev/qe_lib/gpio.c
+++ b/arch/powerpc/sysdev/qe_lib/gpio.c
@@ -19,6 +19,7 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <asm/qe.h>
struct qe_gpio_chip {
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index d927da893ec..541ba986364 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -33,7 +33,7 @@
#include "qe_ic.h"
-static DEFINE_SPINLOCK(qe_ic_lock);
+static DEFINE_RAW_SPINLOCK(qe_ic_lock);
static struct qe_ic_info qe_ic_info[] = {
[1] = {
@@ -201,13 +201,13 @@ static void qe_ic_unmask_irq(unsigned int virq)
unsigned long flags;
u32 temp;
- spin_lock_irqsave(&qe_ic_lock, flags);
+ raw_spin_lock_irqsave(&qe_ic_lock, flags);
temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
temp | qe_ic_info[src].mask);
- spin_unlock_irqrestore(&qe_ic_lock, flags);
+ raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
}
static void qe_ic_mask_irq(unsigned int virq)
@@ -217,7 +217,7 @@ static void qe_ic_mask_irq(unsigned int virq)
unsigned long flags;
u32 temp;
- spin_lock_irqsave(&qe_ic_lock, flags);
+ raw_spin_lock_irqsave(&qe_ic_lock, flags);
temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
@@ -233,7 +233,7 @@ static void qe_ic_mask_irq(unsigned int virq)
*/
mb();
- spin_unlock_irqrestore(&qe_ic_lock, flags);
+ raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
}
static struct irq_chip qe_ic_irq_chip = {
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c
index ebb442ea191..fa589b21dbc 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/module.h>
diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c
index 43c4569e24b..d5fb173e588 100644
--- a/arch/powerpc/sysdev/simple_gpio.c
+++ b/arch/powerpc/sysdev/simple_gpio.c
@@ -21,6 +21,7 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include "simple_gpio.h"
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 595034cfb85..0ab9281e49a 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -24,7 +24,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index 4188cbe63a5..e43fe753703 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/pagemap.h>
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index 4ce7fa95880..9a9586f4103 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/netdevice.h>
diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c
index a97d6952582..14e0479d388 100644
--- a/arch/s390/boot/compressed/misc.c
+++ b/arch/s390/boot/compressed/misc.c
@@ -24,8 +24,8 @@
/* Symbols defined by linker scripts */
extern char input_data[];
extern int input_len;
-extern int _text;
-extern int _end;
+extern char _text, _end;
+extern char _bss, _ebss;
static void error(char *m);
@@ -129,12 +129,12 @@ unsigned long decompress_kernel(void)
unsigned long output_addr;
unsigned char *output;
+ check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
+ memset(&_bss, 0, &_ebss - &_bss);
free_mem_ptr = (unsigned long)&_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL);
- check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
-
#ifdef CONFIG_BLK_DEV_INITRD
/*
* Move the initrd right behind the end of the decompressed
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index a3209906739..aa819dac236 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <asm/debug.h>
#include <asm/uaccess.h>
diff --git a/arch/s390/crypto/sha_common.c b/arch/s390/crypto/sha_common.c
index 7903ec47e6b..f42dbabc0d3 100644
--- a/arch/s390/crypto/sha_common.c
+++ b/arch/s390/crypto/sha_common.c
@@ -79,7 +79,7 @@ int s390_sha_final(struct shash_desc *desc, u8 *out)
memset(ctx->buf + index, 0x00, end - index - 8);
/*
- * Append message length. Well, SHA-512 wants a 128 bit lenght value,
+ * Append message length. Well, SHA-512 wants a 128 bit length value,
* nevertheless we use u64, should be enough for now...
*/
bits = ctx->count * 8;
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 7ae71cc5697..bcd6884985a 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan 4 09:03:07 2010
+# Linux kernel version: 2.6.34-rc3
+# Fri Apr 9 09:57:10 2010
#
CONFIG_SCHED_MC=y
CONFIG_MMU=y
@@ -17,6 +17,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_NO_IOMEM=y
CONFIG_NO_DMA=y
CONFIG_GENERIC_LOCKBREAK=y
@@ -62,15 +63,11 @@ CONFIG_TREE_RCU=y
# CONFIG_RCU_TRACE is not set
CONFIG_RCU_FANOUT=64
# 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_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=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_NS=y
@@ -79,6 +76,7 @@ CONFIG_CGROUP_NS=y
# CONFIG_CPUSETS is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -93,6 +91,7 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -126,6 +125,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_HAVE_SYSCALL_WRAPPERS=y
@@ -134,6 +134,7 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y
#
@@ -246,6 +247,7 @@ CONFIG_64BIT=y
CONFIG_SMP=y
CONFIG_NR_CPUS=32
CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_BOOK is not set
CONFIG_COMPAT=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_AUDIT_ARCH=y
@@ -345,13 +347,13 @@ CONFIG_PM_SLEEP=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""
# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=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
@@ -529,6 +531,7 @@ CONFIG_NET_SCH_FIFO=y
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
CONFIG_CAN=m
CONFIG_CAN_RAW=m
CONFIG_CAN_BCM=m
@@ -605,6 +608,7 @@ CONFIG_MISC_DEVICES=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
# CONFIG_SCSI_DMA is not set
@@ -863,6 +867,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -891,6 +896,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
@@ -952,6 +958,7 @@ CONFIG_DEBUG_MUTEXES=y
# 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_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
@@ -973,12 +980,17 @@ CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
# CONFIG_LATENCYTOP is not set
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_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
@@ -995,10 +1007,15 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_KPROBE_EVENT=y
+# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_DYNAMIC_DEBUG is not set
CONFIG_SAMPLES=y
+# CONFIG_SAMPLE_TRACEPOINTS is not set
+# CONFIG_SAMPLE_TRACE_EVENTS is not set
# CONFIG_SAMPLE_KOBJECT is not set
# CONFIG_SAMPLE_KPROBES is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
#
# Security options
@@ -1032,6 +1049,7 @@ CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=m
# 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=m
@@ -1119,7 +1137,7 @@ CONFIG_CRYPTO_SHA512_S390=m
# CONFIG_CRYPTO_DES_S390 is not set
# CONFIG_CRYPTO_AES_S390 is not set
CONFIG_S390_PRNG=m
-# CONFIG_BINARY_PRINTF is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
@@ -1136,14 +1154,16 @@ CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_LZO_DECOMPRESS=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
CONFIG_NLATTR=y
CONFIG_HAVE_KVM=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
+# CONFIG_VHOST_NET is not set
CONFIG_VIRTIO=y
CONFIG_VIRTIO_RING=y
CONFIG_VIRTIO_BALLOON=m
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 87cf523192e..5b1acdba649 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -12,7 +12,6 @@
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index cd128b07bed..c53f8ac825c 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -14,8 +14,8 @@
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/vfs.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
-#include <linux/gfp.h>
#include <linux/time.h>
#include <linux/parser.h>
#include <linux/sysfs.h>
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index e85679af54d..e34347d567a 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -20,7 +20,7 @@
/**
* struct ccw1 - channel command word
* @cmd_code: command code
- * @flags: flags, like IDA adressing, etc.
+ * @flags: flags, like IDA addressing, etc.
* @count: byte count
* @cda: data address
*
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 01a08020bc0..104f2007f09 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -35,7 +35,8 @@
extern long psw32_user_bits;
-#define COMPAT_USER_HZ 100
+#define COMPAT_USER_HZ 100
+#define COMPAT_UTS_MACHINE "s390\0\0\0\0"
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 9b5b9189c15..89a504c3f12 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -105,7 +105,7 @@ extern char empty_zero_page[PAGE_SIZE];
#ifndef __ASSEMBLY__
/*
* The vmalloc area will always be on the topmost area of the kernel
- * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc,
+ * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
* which should be enough for any sane case.
* By putting vmalloc at the top, we maximise the gap between physical
* memory and vmalloc to catch misplaced memory accesses. As a side
@@ -120,8 +120,8 @@ extern unsigned long VMALLOC_START;
#define VMALLOC_END 0x7e000000UL
#define VMEM_MAP_END 0x80000000UL
#else /* __s390x__ */
-#define VMALLOC_SIZE (1UL << 30)
-#define VMALLOC_END 0x3e040000000UL
+#define VMALLOC_SIZE (128UL << 30)
+#define VMALLOC_END 0x3e000000000UL
#define VMEM_MAP_END 0x40000000000UL
#endif /* __s390x__ */
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index dd2d913afca..fef9b33cdd5 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -489,9 +489,6 @@ struct user_regs_struct
* These are defined as per linux/ptrace.h, which see.
*/
#define arch_has_single_step() (1)
-struct task_struct;
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
extern void show_regs(struct pt_regs * regs);
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index c666bfe5e98..9b04b1102bb 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -321,11 +321,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40
#define QDIO_ERROR_SLSB_STATE 0x80
-/* for qdio_initialize */
-#define QDIO_INBOUND_0COPY_SBALS 0x01
-#define QDIO_OUTBOUND_0COPY_SBALS 0x02
-#define QDIO_USE_OUTBOUND_PCIS 0x04
-
/* for qdio_cleanup */
#define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01
#define QDIO_FLAG_CLEANUP_USING_HALT 0x02
@@ -344,7 +339,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
* @input_handler: handler to be called for input queues
* @output_handler: handler to be called for output queues
* @int_parm: interruption parameter
- * @flags: initialization flags
* @input_sbal_addr_array: address of no_input_qs * 128 pointers
* @output_sbal_addr_array: address of no_output_qs * 128 pointers
*/
@@ -361,7 +355,6 @@ struct qdio_initialize {
qdio_handler_t *input_handler;
qdio_handler_t *output_handler;
unsigned long int_parm;
- unsigned long flags;
void **input_sbal_addr_array;
void **output_sbal_addr_array;
};
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index 67ee6c3c6bb..1741c1556a4 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -110,6 +110,7 @@ extern void pfault_fini(void);
#endif /* CONFIG_PFAULT */
extern void cmma_init(void);
+extern int memcpy_real(void *, void *, size_t);
#define finish_arch_switch(prev) do { \
set_fs(current->thread.mm_segment); \
@@ -218,8 +219,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
" l %0,%2\n"
"0: nr %0,%5\n"
" lr %1,%0\n"
- " or %0,%2\n"
- " or %1,%3\n"
+ " or %0,%3\n"
+ " or %1,%4\n"
" cs %0,%1,%2\n"
" jnl 1f\n"
" xr %1,%0\n"
@@ -239,8 +240,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
" l %0,%2\n"
"0: nr %0,%5\n"
" lr %1,%0\n"
- " or %0,%2\n"
- " or %1,%3\n"
+ " or %0,%3\n"
+ " or %1,%4\n"
" cs %0,%1,%2\n"
" jnl 1f\n"
" xr %1,%0\n"
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 6e9f049fa82..5f0075150a6 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -392,6 +392,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_MMAP
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h
index 4a76d9480cc..533f35751ae 100644
--- a/arch/s390/include/asm/vdso.h
+++ b/arch/s390/include/asm/vdso.h
@@ -29,6 +29,7 @@ struct vdso_data {
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
__u32 tz_dsttime; /* Type of dst correction 0x34 */
__u32 ectg_available;
+ __u32 ntp_mult; /* NTP adjusted multiplier 0x3C */
};
struct vdso_per_cpu_data {
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 08db736dded..a09408952ed 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -61,6 +61,7 @@ int main(void)
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
+ DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
/* constants used by the vdso */
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 11c3aba664e..73b624ed9cd 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -29,7 +29,6 @@
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
-#include <linux/slab.h>
#include <linux/uio.h>
#include <linux/quota.h>
#include <linux/module.h>
@@ -52,6 +51,7 @@
#include <linux/ptrace.h>
#include <linux/fadvise.h>
#include <linux/ipc.h>
+#include <linux/slab.h>
#include <asm/types.h>
#include <asm/uaccess.h>
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 30de2d0e52b..672ce52341b 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -547,7 +547,7 @@ sys32_setdomainname_wrapper:
.globl sys32_newuname_wrapper
sys32_newuname_wrapper:
llgtr %r2,%r2 # struct new_utsname *
- jg sys_s390_newuname # branch to system call
+ jg sys_newuname # branch to system call
.globl compat_sys_adjtimex_wrapper
compat_sys_adjtimex_wrapper:
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 31d618a443a..2d92c2cf92d 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -82,7 +82,8 @@ asm(
" lm 6,15,24(15)\n"
#endif
" br 14\n"
- " .size savesys_ipl_nss, .-savesys_ipl_nss\n");
+ " .size savesys_ipl_nss, .-savesys_ipl_nss\n"
+ " .previous\n");
static __initdata char upper_command_line[COMMAND_LINE_SIZE];
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 4348f9bc539..6af7045280a 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -964,7 +964,7 @@ cleanup_critical:
clc 4(4,%r12),BASED(cleanup_table_io_work_loop)
bl BASED(0f)
clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4)
- bl BASED(cleanup_io_return)
+ bl BASED(cleanup_io_work_loop)
0:
br %r14
@@ -1039,6 +1039,12 @@ cleanup_sysc_leave_insn:
cleanup_io_return:
mvc __LC_RETURN_PSW(4),0(%r12)
+ mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return)
+ la %r12,__LC_RETURN_PSW
+ br %r14
+
+cleanup_io_work_loop:
+ mvc __LC_RETURN_PSW(4),0(%r12)
mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
la %r12,__LC_RETURN_PSW
br %r14
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index e1e5e767ab5..eb15c12ec15 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -24,17 +24,13 @@ int __cpuinit start_secondary(void *cpuvoid);
void __init startup_init(void);
void die(const char * str, struct pt_regs * regs, long err);
-struct new_utsname;
-struct mmap_arg_struct;
+struct s390_mmap_arg_struct;
struct fadvise64_64_args;
struct old_sigaction;
-struct sel_arg_struct;
-long sys_mmap2(struct mmap_arg_struct __user *arg);
-long sys_s390_old_mmap(struct mmap_arg_struct __user *arg);
-long sys_ipc(uint call, int first, unsigned long second,
+long sys_mmap2(struct s390_mmap_arg_struct __user *arg);
+long sys_s390_ipc(uint call, int first, unsigned long second,
unsigned long third, void __user *ptr);
-long sys_s390_newuname(struct new_utsname __user *name);
long sys_s390_personality(unsigned long personality);
long sys_s390_fadvise64(int fd, u32 offset_high, u32 offset_low,
size_t len, int advice);
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 29fd0f1e6ec..52106d53271 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -946,7 +946,7 @@ cleanup_critical:
clc 8(8,%r12),BASED(cleanup_table_io_work_loop)
jl 0f
clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8)
- jl cleanup_io_return
+ jl cleanup_io_work_loop
0:
br %r14
@@ -1021,6 +1021,12 @@ cleanup_sysc_leave_insn:
cleanup_io_return:
mvc __LC_RETURN_PSW(8),0(%r12)
+ mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return)
+ la %r12,__LC_RETURN_PSW
+ br %r14
+
+cleanup_io_work_loop:
+ mvc __LC_RETURN_PSW(8),0(%r12)
mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop)
la %r12,__LC_RETURN_PSW
br %r14
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index ca4a62bd862..9d1f76702d4 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -517,7 +517,10 @@ startup:
lhi %r1,2 # mode 2 = esame (dump)
sigp %r1,%r0,0x12 # switch to esame mode
sam64 # switch to 64 bit mode
+ larl %r13,4f
+ lmh %r0,%r15,0(%r13) # clear high-order half
jg startup_continue
+4: .fill 16,4,0x0
#else
mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
l %r13,4f-.LPG0(%r13)
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 39580e76865..1f70970de0a 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -21,7 +21,6 @@ startup_continue:
larl %r1,sched_clock_base_cc
mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
larl %r13,.LPG1 # get base
- lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore
@@ -67,7 +66,6 @@ startup_continue:
.L4malign:.quad 0xffffffffffc00000
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
.Lnop: .long 0x07000700
-.Lzero64:.fill 16,4,0x0
.Lparmaddr:
.quad PARMAREA
.align 64
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 7eedbbcb54a..72c8b0d070c 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -15,6 +15,7 @@
#include <linux/reboot.h>
#include <linux/ctype.h>
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <asm/ipl.h>
#include <asm/smp.h>
#include <asm/setup.h>
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 86783efa24e..3d34eef5a2c 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -29,6 +29,7 @@
#include <asm/cacheflush.h>
#include <asm/sections.h>
#include <linux/module.h>
+#include <linux/slab.h>
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 00b6d1d292f..1039fdea15b 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -16,9 +16,9 @@
#include <linux/fs.h>
#include <linux/smp.h>
#include <linux/stddef.h>
+#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/user.h>
#include <linux/interrupt.h>
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S
index 27af3bf3a00..2e82fdd8932 100644
--- a/arch/s390/kernel/sclp.S
+++ b/arch/s390/kernel/sclp.S
@@ -235,7 +235,7 @@ _sclp_print:
lh %r9,0(%r8) # update sccb length
ar %r9,%r6
sth %r9,0(%r8)
- ar %r7,%r6 # update current mto adress
+ ar %r7,%r6 # update current mto address
ltr %r0,%r0 # more characters?
jnz .LinitmtoS4
l %r2,.LwritedataS4-.LbaseS4(%r13)# write data
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 77a63ae419f..91625f759cc 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -25,7 +25,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/tty.h>
#include <linux/ioport.h>
@@ -401,7 +400,7 @@ setup_lowcore(void)
* Setup lowcore for boot cpu
*/
BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
- lc = __alloc_bootmem(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
+ lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
lc->restart_psw.addr =
PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
@@ -433,7 +432,7 @@ setup_lowcore(void)
#ifndef CONFIG_64BIT
if (MACHINE_HAS_IEEE) {
lc->extended_save_area_addr = (__u32)
- __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
+ __alloc_bootmem_low(PAGE_SIZE, PAGE_SIZE, 0);
/* enable extended save area */
__ctl_set_bit(14, 29);
}
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8b10127c00a..e4d98de83dd 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -36,6 +36,7 @@
#include <linux/cpu.h>
#include <linux/timex.h>
#include <linux/bootmem.h>
+#include <linux/slab.h>
#include <asm/asm-offsets.h>
#include <asm/ipl.h>
#include <asm/setup.h>
@@ -292,9 +293,9 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
cpu_relax();
- memcpy(zfcpdump_save_areas[cpu],
- (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
- sizeof(struct save_area));
+ memcpy_real(zfcpdump_save_areas[cpu],
+ (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
+ sizeof(struct save_area));
}
struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
@@ -1020,7 +1021,9 @@ out:
return rc;
}
-static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
+static ssize_t __ref rescan_store(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ const char *buf,
size_t count)
{
int rc;
@@ -1031,7 +1034,9 @@ static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store);
#endif /* CONFIG_HOTPLUG_CPU */
-static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
+static ssize_t dispatching_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
ssize_t count;
@@ -1041,7 +1046,9 @@ static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
return count;
}
-static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf,
+static ssize_t dispatching_store(struct sysdev_class *dev,
+ struct sysdev_class_attribute *attr,
+ const char *buf,
size_t count)
{
int val, rc;
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index b354427e03b..c56d3f56d02 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -256,6 +256,9 @@ restore_registers:
lghi %r2,0
brasl %r14,arch_set_page_states
+ /* Reinitialize the channel subsystem */
+ brasl %r14,channel_subsystem_reinit
+
/* Return 0 */
lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
lghi %r2,0
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 86a74c9c9e6..7b6b0f81a28 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -33,13 +33,12 @@
#include "entry.h"
/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux for S/390 isn't able to handle more than 5
- * system call parameters, so these system calls used a memory
- * block for parameter passing..
+ * Perform the mmap() system call. Linux for S/390 isn't able to handle more
+ * than 5 system call parameters, so this system call uses a memory block
+ * for parameter passing.
*/
-struct mmap_arg_struct {
+struct s390_mmap_arg_struct {
unsigned long addr;
unsigned long len;
unsigned long prot;
@@ -48,9 +47,9 @@ struct mmap_arg_struct {
unsigned long offset;
};
-SYSCALL_DEFINE1(mmap2, struct mmap_arg_struct __user *, arg)
+SYSCALL_DEFINE1(mmap2, struct s390_mmap_arg_struct __user *, arg)
{
- struct mmap_arg_struct a;
+ struct s390_mmap_arg_struct a;
int error = -EFAULT;
if (copy_from_user(&a, arg, sizeof(a)))
@@ -60,29 +59,12 @@ out:
return error;
}
-SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct __user *, arg)
-{
- struct mmap_arg_struct a;
- long error = -EFAULT;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
-
- error = -EINVAL;
- if (a.offset & ~PAGE_MASK)
- goto out;
-
- error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-out:
- return error;
-}
-
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
* This is really horribly ugly.
*/
-SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second,
+SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
unsigned long, third, void __user *, ptr)
{
struct ipc_kludge tmp;
@@ -149,17 +131,6 @@ SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second,
}
#ifdef CONFIG_64BIT
-SYSCALL_DEFINE1(s390_newuname, struct new_utsname __user *, name)
-{
- int ret = sys_newuname(name);
-
- if (personality(current->personality) == PER_LINUX32 && !ret) {
- ret = copy_to_user(name->machine, "s390\0\0\0\0", 8);
- if (ret) ret = -EFAULT;
- }
- return ret;
-}
-
SYSCALL_DEFINE1(s390_personality, unsigned long, personality)
{
int ret;
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 30eca070d42..201ce6bed34 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -98,7 +98,7 @@ SYSCALL(sys_uselib,sys_uselib,sys32_uselib_wrapper)
SYSCALL(sys_swapon,sys_swapon,sys32_swapon_wrapper)
SYSCALL(sys_reboot,sys_reboot,sys32_reboot_wrapper)
SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */
-SYSCALL(sys_s390_old_mmap,sys_s390_old_mmap,old32_mmap_wrapper) /* 90 */
+SYSCALL(sys_old_mmap,sys_old_mmap,old32_mmap_wrapper) /* 90 */
SYSCALL(sys_munmap,sys_munmap,sys32_munmap_wrapper)
SYSCALL(sys_truncate,sys_truncate,sys32_truncate_wrapper)
SYSCALL(sys_ftruncate,sys_ftruncate,sys32_ftruncate_wrapper)
@@ -125,12 +125,12 @@ NI_SYSCALL /* vm86old for i386 */
SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper)
SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper) /* 115 */
SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper)
-SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper)
+SYSCALL(sys_s390_ipc,sys_s390_ipc,sys32_ipc_wrapper)
SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper)
SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn)
SYSCALL(sys_clone,sys_clone,sys_clone_wrapper) /* 120 */
SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper)
-SYSCALL(sys_newuname,sys_s390_newuname,sys32_newuname_wrapper)
+SYSCALL(sys_newuname,sys_newuname,sys32_newuname_wrapper)
NI_SYSCALL /* modify_ldt for i386 */
SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper)
SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper) /* 125 */
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c
index b5e75e1061c..a0ffc7717ed 100644
--- a/arch/s390/kernel/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/ebcdic.h>
#include <asm/sysinfo.h>
#include <asm/cpcmd.h>
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index a8f93f1705a..d906bf19c14 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -36,6 +36,7 @@
#include <linux/notifier.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/s390_ext.h>
@@ -73,15 +74,15 @@ unsigned long long monotonic_clock(void)
}
EXPORT_SYMBOL(monotonic_clock);
-void tod_to_timeval(__u64 todval, struct timespec *xtime)
+void tod_to_timeval(__u64 todval, struct timespec *xt)
{
unsigned long long sec;
sec = todval >> 12;
do_div(sec, 1000000);
- xtime->tv_sec = sec;
+ xt->tv_sec = sec;
todval -= (sec * 1000000) << 12;
- xtime->tv_nsec = ((todval * 1000) >> 12);
+ xt->tv_nsec = ((todval * 1000) >> 12);
}
EXPORT_SYMBOL(tod_to_timeval);
@@ -216,10 +217,11 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
++vdso_data->tb_update_count;
smp_wmb();
vdso_data->xtime_tod_stamp = clock->cycle_last;
- vdso_data->xtime_clock_sec = xtime.tv_sec;
- vdso_data->xtime_clock_nsec = xtime.tv_nsec;
+ vdso_data->xtime_clock_sec = wall_time->tv_sec;
+ vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
+ vdso_data->ntp_mult = mult;
smp_wmb();
++vdso_data->tb_update_count;
}
@@ -1116,14 +1118,18 @@ static struct sys_device etr_port1_dev = {
/*
* ETR class attributes
*/
-static ssize_t etr_stepping_port_show(struct sysdev_class *class, char *buf)
+static ssize_t etr_stepping_port_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%i\n", etr_port0.esw.p);
}
static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
-static ssize_t etr_stepping_mode_show(struct sysdev_class *class, char *buf)
+static ssize_t etr_stepping_mode_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
char *mode_str;
@@ -1584,7 +1590,9 @@ static struct sysdev_class stp_sysclass = {
.name = "stp",
};
-static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_ctn_id_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online)
return -ENODATA;
@@ -1594,7 +1602,9 @@ static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL);
-static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_ctn_type_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online)
return -ENODATA;
@@ -1603,7 +1613,9 @@ static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL);
-static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_dst_offset_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online || !(stp_info.vbits & 0x2000))
return -ENODATA;
@@ -1612,7 +1624,9 @@ static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL);
-static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_leap_seconds_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online || !(stp_info.vbits & 0x8000))
return -ENODATA;
@@ -1621,7 +1635,9 @@ static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL);
-static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_stratum_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online)
return -ENODATA;
@@ -1630,7 +1646,9 @@ static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL);
-static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_time_offset_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online || !(stp_info.vbits & 0x0800))
return -ENODATA;
@@ -1639,7 +1657,9 @@ static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL);
-static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_time_zone_offset_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online || !(stp_info.vbits & 0x4000))
return -ENODATA;
@@ -1649,7 +1669,9 @@ static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(time_zone_offset, 0400,
stp_time_zone_offset_show, NULL);
-static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_timing_mode_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online)
return -ENODATA;
@@ -1658,7 +1680,9 @@ static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL);
-static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_timing_state_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
if (!stp_online)
return -ENODATA;
@@ -1667,12 +1691,15 @@ static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL);
-static ssize_t stp_online_show(struct sysdev_class *class, char *buf)
+static ssize_t stp_online_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%i\n", stp_online);
}
static ssize_t stp_online_store(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
const char *buf, size_t count)
{
unsigned int value;
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 14ef6f05e43..247b4c2d1e5 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -165,10 +165,11 @@ static void tl_to_cores(struct tl_info *info)
default:
clear_cores();
machine_has_topology = 0;
- return;
+ goto out;
}
tle = next_tle(tle);
}
+out:
spin_unlock_irq(&topology_lock);
}
diff --git a/arch/s390/kernel/vdso32/clock_gettime.S b/arch/s390/kernel/vdso32/clock_gettime.S
index 4a98909a831..96964395427 100644
--- a/arch/s390/kernel/vdso32/clock_gettime.S
+++ b/arch/s390/kernel/vdso32/clock_gettime.S
@@ -38,13 +38,13 @@ __kernel_clock_gettime:
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,2f
ahi %r0,-1
-2: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
+2: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
lr %r2,%r0
- lhi %r0,1000
+ l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 3f
- ahi %r0,1000
+ a %r0,__VDSO_NTP_MULT(%r5)
3: alr %r0,%r2
srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
@@ -86,13 +86,13 @@ __kernel_clock_gettime:
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,12f
ahi %r0,-1
-12: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
+12: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
lr %r2,%r0
- lhi %r0,1000
+ l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 13f
- ahi %r0,1000
+ a %r0,__VDSO_NTP_MULT(%r5)
13: alr %r0,%r2
srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
diff --git a/arch/s390/kernel/vdso32/gettimeofday.S b/arch/s390/kernel/vdso32/gettimeofday.S
index ad8acfc949f..2d3633175e3 100644
--- a/arch/s390/kernel/vdso32/gettimeofday.S
+++ b/arch/s390/kernel/vdso32/gettimeofday.S
@@ -35,13 +35,13 @@ __kernel_gettimeofday:
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,3f
ahi %r0,-1
-3: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
+3: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
st %r0,24(%r15)
- lhi %r0,1000
+ l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 4f
- ahi %r0,1000
+ a %r0,__VDSO_NTP_MULT(%r5)
4: al %r0,24(%r15)
srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S
index 49106c6e6f8..f40467884a0 100644
--- a/arch/s390/kernel/vdso64/clock_gettime.S
+++ b/arch/s390/kernel/vdso64/clock_gettime.S
@@ -36,7 +36,7 @@ __kernel_clock_gettime:
stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
- mghi %r1,1000
+ msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
lg %r0,__VDSO_XTIME_SEC(%r5)
@@ -64,7 +64,7 @@ __kernel_clock_gettime:
stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
- mghi %r1,1000
+ msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
lg %r0,__VDSO_XTIME_SEC(%r5)
diff --git a/arch/s390/kernel/vdso64/gettimeofday.S b/arch/s390/kernel/vdso64/gettimeofday.S
index f873e75634e..36ee674722e 100644
--- a/arch/s390/kernel/vdso64/gettimeofday.S
+++ b/arch/s390/kernel/vdso64/gettimeofday.S
@@ -31,7 +31,7 @@ __kernel_gettimeofday:
stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
- mghi %r1,1000
+ msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */
lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 834774d8d5f..35c21bf910c 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -14,6 +14,7 @@
#include <linux/kvm_host.h>
#include <linux/hrtimer.h>
#include <linux/signal.h>
+#include <linux/slab.h>
#include <asm/asm-offsets.h>
#include <asm/uaccess.h>
#include "kvm-s390.h"
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 3fa0a10e466..49292869a5c 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -242,6 +242,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
kvm_free_physmem(kvm);
free_page((unsigned long)(kvm->arch.sca));
debug_unregister(kvm->arch.dbf);
+ cleanup_srcu_struct(&kvm->srcu);
kfree(kvm);
}
@@ -690,14 +691,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
}
/* Section: memory related */
-int kvm_arch_set_memory_region(struct kvm *kvm,
- struct kvm_userspace_memory_region *mem,
- struct kvm_memory_slot old,
- int user_alloc)
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
+ struct kvm_memory_slot old,
+ struct kvm_userspace_memory_region *mem,
+ int user_alloc)
{
- int i;
- struct kvm_vcpu *vcpu;
-
/* A few sanity checks. We can have exactly one memory slot which has
to start at guest virtual zero and which has to be located at a
page boundary in userland and which has to end at a page boundary.
@@ -720,14 +719,23 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
if (!user_alloc)
return -EINVAL;
+ return 0;
+}
+
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+ struct kvm_userspace_memory_region *mem,
+ struct kvm_memory_slot old,
+ int user_alloc)
+{
+ int i;
+ struct kvm_vcpu *vcpu;
+
/* request update of sie control block for all available vcpus */
kvm_for_each_vcpu(i, vcpu, kvm) {
if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
continue;
kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP);
}
-
- return 0;
}
void kvm_arch_flush_shadow(struct kvm *kvm)
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 06cce8285ba..60f09ab3672 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -67,10 +67,14 @@ static inline long kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu)
static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu)
{
+ int idx;
struct kvm_memory_slot *mem;
+ struct kvm_memslots *memslots;
- down_read(&vcpu->kvm->slots_lock);
- mem = &vcpu->kvm->memslots[0];
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
+ memslots = rcu_dereference(vcpu->kvm->memslots);
+
+ mem = &memslots->memslots[0];
vcpu->arch.sie_block->gmsor = mem->userspace_addr;
vcpu->arch.sie_block->gmslm =
@@ -78,7 +82,7 @@ static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu)
(mem->npages << PAGE_SHIFT) +
VIRTIODESCSPACE - 1ul;
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
}
/* implemented in priv.c */
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 28c55677eb3..44205507717 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -12,6 +12,7 @@
*/
#include <linux/kvm.h>
+#include <linux/gfp.h>
#include <linux/errno.h>
#include <asm/current.h>
#include <asm/debug.h>
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 241a48459b6..eff3c5989b4 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -14,6 +14,7 @@
#include <linux/kvm.h>
#include <linux/kvm_host.h>
+#include <linux/slab.h>
#include "gaccess.h"
#include "kvm-s390.h"
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index cd54a1c352a..761ab8b56af 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -2,7 +2,8 @@
# Makefile for s390-specific library files..
#
-lib-y += delay.o string.o uaccess_std.o uaccess_pt.o usercopy.o
+lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
+obj-y += usercopy.o
obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o
lib-$(CONFIG_64BIT) += uaccess_mvcos.o
lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index 76a3637b88e..f87b34731e1 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -12,6 +12,7 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/sysctl.h>
#include <linux/ctype.h>
@@ -374,7 +375,7 @@ static struct ctl_table cmm_dir_table[] = {
#ifdef CONFIG_CMM_IUCV
#define SMSG_PREFIX "CMM"
static void
-cmm_smsg_target(char *from, char *msg)
+cmm_smsg_target(const char *from, char *msg)
{
long nr, seconds;
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index d5865e4024c..acc91c75bc9 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -26,6 +26,7 @@
#include <linux/pfn.h>
#include <linux/poison.h>
#include <linux/initrd.h>
+#include <linux/gfp.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index 81756271dc4..a8c2af8c650 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -59,3 +59,29 @@ long probe_kernel_write(void *dst, void *src, size_t size)
}
return copied < 0 ? -EFAULT : 0;
}
+
+int memcpy_real(void *dest, void *src, size_t count)
+{
+ register unsigned long _dest asm("2") = (unsigned long) dest;
+ register unsigned long _len1 asm("3") = (unsigned long) count;
+ register unsigned long _src asm("4") = (unsigned long) src;
+ register unsigned long _len2 asm("5") = (unsigned long) count;
+ unsigned long flags;
+ int rc = -EFAULT;
+
+ if (!count)
+ return 0;
+ flags = __raw_local_irq_stnsm(0xf8UL);
+ asm volatile (
+ "0: mvcle %1,%2,0x0\n"
+ "1: jo 0b\n"
+ " lhi %0,0x0\n"
+ "2:\n"
+ EX_TABLE(1b,2b)
+ : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
+ "+d" (_len2), "=m" (*((long *) dest))
+ : "m" (*((long *) src))
+ : "cc", "memory");
+ __raw_local_irq_ssm(flags);
+ return rc;
+}
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c
index 098923ae458..a90d45e9dfb 100644
--- a/arch/s390/mm/page-states.c
+++ b/arch/s390/mm/page-states.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#define ESSA_SET_STABLE 1
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index ad621e06ada..8d999249d35 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -6,11 +6,11 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/gfp.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/module.h>
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 300ab012b0f..90165e7ca04 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/list.h>
#include <linux/hugetlb.h>
+#include <linux/slab.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/setup.h>
@@ -70,12 +71,8 @@ static pte_t __ref *vmem_pte_alloc(void)
pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
if (!pte)
return NULL;
- if (MACHINE_HAS_HPAGE)
- clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO,
- PTRS_PER_PTE * sizeof(pte_t));
- else
- clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
- PTRS_PER_PTE * sizeof(pte_t));
+ clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
+ PTRS_PER_PTE * sizeof(pte_t));
return pte;
}
@@ -116,8 +113,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
(address + HPAGE_SIZE <= start + size) &&
(address >= HPAGE_SIZE)) {
- pte_val(pte) |= _SEGMENT_ENTRY_LARGE |
- _SEGMENT_ENTRY_CO;
+ pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
pmd_val(*pm_dir) = pte_val(pte);
address += HPAGE_SIZE - PAGE_SIZE;
continue;
diff --git a/arch/score/include/asm/ptrace.h b/arch/score/include/asm/ptrace.h
index d40e691f23e..e89dc9b1ef4 100644
--- a/arch/score/include/asm/ptrace.h
+++ b/arch/score/include/asm/ptrace.h
@@ -90,8 +90,7 @@ extern int read_tsk_short(struct task_struct *, unsigned long,
unsigned short *);
#define arch_has_single_step() (1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
+
#endif /* __KERNEL__ */
#endif /* _ASM_SCORE_PTRACE_H */
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c
index 856ed68a58e..651096ff8db 100644
--- a/arch/score/kernel/sys_score.c
+++ b/arch/score/kernel/sys_score.c
@@ -28,6 +28,7 @@
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <asm/syscalls.h>
diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c
index 7f001bbedb0..50fdec54c70 100644
--- a/arch/score/mm/init.c
+++ b/arch/score/mm/init.c
@@ -26,6 +26,7 @@
#include <linux/errno.h>
#include <linux/bootmem.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/mman.h>
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 05cef506129..8d90564c2bc 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -183,6 +183,9 @@ config DMA_COHERENT
config DMA_NONCOHERENT
def_bool !DMA_COHERENT
+config NEED_DMA_MAP_STATE
+ def_bool DMA_NONCOHERENT
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 39ed8722d11..6c13b92742e 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -836,6 +836,8 @@ static void __init sh_eth_init(struct sh_eth_plat_data *pd)
pd->mac_addr[i] = mac_read(a, 0x10 + i);
msleep(10);
}
+
+ i2c_put_adapter(a);
}
#else
static void __init sh_eth_init(struct sh_eth_plat_data *pd)
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index be300aaca6f..7da0fc94a01 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -419,6 +419,9 @@ static struct i2c_board_info migor_i2c_devices[] = {
I2C_BOARD_INFO("migor_ts", 0x51),
.irq = 38, /* IRQ6 */
},
+ {
+ I2C_BOARD_INFO("wm8978", 0x1a),
+ },
};
static struct i2c_board_info migor_i2c_camera[] = {
@@ -619,6 +622,19 @@ static int __init migor_devices_setup(void)
platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20);
+ /* SIU: Port B */
+ gpio_request(GPIO_FN_SIUBOLR, NULL);
+ gpio_request(GPIO_FN_SIUBOBT, NULL);
+ gpio_request(GPIO_FN_SIUBISLD, NULL);
+ gpio_request(GPIO_FN_SIUBOSLD, NULL);
+ gpio_request(GPIO_FN_SIUMCKB, NULL);
+
+ /*
+ * The original driver sets SIUB OLR/OBT, ILR/IBT, and SIUA OLR/OBT to
+ * output. Need only SIUB, set to output for master mode (table 34.2)
+ */
+ __raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA);
+
i2c_register_board_info(0, migor_i2c_devices,
ARRAY_SIZE(migor_i2c_devices));
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 66cdbc3c7af..ccaa290e9ab 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -52,6 +52,13 @@
* and change SW41 to use 720p
*/
+/*
+ * about sound
+ *
+ * This setup.c supports FSI slave mode.
+ * Please change J20, J21, J22 pin to 1-2 connection.
+ */
+
/* Heartbeat */
static struct resource heartbeat_resource = {
.start = PA_LED,
@@ -276,6 +283,7 @@ static struct clk fsimcka_clk = {
.rate = 0, /* unknown */
};
+/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
struct sh_fsi_platform_info fsi_info = {
.porta_flags = SH_FSI_BRS_INV |
SH_FSI_OUT_SLAVE_MODE |
diff --git a/arch/sh/boot/compressed/cache.c b/arch/sh/boot/compressed/cache.c
index e27fc74f228..d0b77b68a4d 100644
--- a/arch/sh/boot/compressed/cache.c
+++ b/arch/sh/boot/compressed/cache.c
@@ -5,7 +5,7 @@ int cache_control(unsigned int command)
for (i = 0; i < (32 * 1024); i += 32) {
(void)*p;
- p += (32 / sizeof (int));
+ p += (32 / sizeof(int));
}
return 0;
diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig
index 18e3356406f..6041c66dd10 100644
--- a/arch/sh/configs/ecovec24_defconfig
+++ b/arch/sh/configs/ecovec24_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan 4 11:20:36 2010
+# Linux kernel version: 2.6.34-rc2
+# Mon Mar 29 02:21:58 2010
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ 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_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION=""
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
@@ -71,14 +74,8 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-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=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
@@ -107,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y
#
# Kernel Performance Events And Counters
#
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
@@ -116,13 +113,13 @@ CONFIG_SLAB=y
# 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_CLK=y
CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
#
# GCOV-based kernel profiling
@@ -234,12 +231,12 @@ CONFIG_CPU_SUBTYPE_SH7724=y
CONFIG_QUICKLIST=y
CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
-CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_FORCE_MAX_ZONEORDER=12
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x10000000
CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
CONFIG_VSYSCALL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -247,6 +244,8 @@ 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
@@ -262,7 +261,7 @@ 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=2
+CONFIG_NR_QUICK=1
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
@@ -337,7 +336,6 @@ CONFIG_SECCOMP=y
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
#
# Boot options
@@ -347,7 +345,7 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
CONFIG_ENTRY_OFFSET=0x00001000
CONFIG_CMDLINE_OVERWRITE=y
# CONFIG_CMDLINE_EXTEND is not set
-CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=120M memchunk.vpu=4m"
+CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=248M memchunk.vpu=8m memchunk.veu0=4m"
#
# Bus options
@@ -373,6 +371,7 @@ CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_HIBERNATION is not set
CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
# CONFIG_CPU_IDLE is not set
CONFIG_NET=y
@@ -380,7 +379,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -445,7 +443,45 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+# CONFIG_IRLAN is not set
+# CONFIG_IRCOMM is not set
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+CONFIG_SH_SIR=y
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_MCS_FIR is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
@@ -556,6 +592,7 @@ CONFIG_MTD_NAND_IDS=y
# 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
#
@@ -597,6 +634,7 @@ CONFIG_MISC_DEVICES=y
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_DS1682 is not set
# CONFIG_TI_DAC7512 is not set
# CONFIG_C2PORT is not set
@@ -616,6 +654,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
@@ -768,7 +807,29 @@ CONFIG_KEYBOARD_SH_KEYSC=y
# 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_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO 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_INPUT_MISC is not set
#
@@ -802,10 +863,10 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
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=y
-CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
@@ -830,6 +891,7 @@ CONFIG_I2C_HELPER_AUTO=y
# 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
@@ -843,15 +905,9 @@ CONFIG_I2C_SH_MOBILE=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
CONFIG_SPI_MASTER=y
@@ -882,13 +938,16 @@ CONFIG_GPIOLIB=y
#
# 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:
@@ -919,23 +978,26 @@ CONFIG_SSB_POSSIBLE=y
#
# Multifunction device drivers
#
-# CONFIG_MFD_CORE is not set
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_SH_MOBILE_SDHI is not set
+CONFIG_MFD_SH_MOBILE_SDHI=y
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
# CONFIG_TPS65010 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_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
# CONFIG_REGULATOR is not set
CONFIG_MEDIA_SUPPORT=y
@@ -985,10 +1047,10 @@ CONFIG_SOC_CAMERA=y
# CONFIG_SOC_CAMERA_MT9M001 is not set
# CONFIG_SOC_CAMERA_MT9M111 is not set
# CONFIG_SOC_CAMERA_MT9T031 is not set
-# CONFIG_SOC_CAMERA_MT9T112 is not set
+CONFIG_SOC_CAMERA_MT9T112=y
# CONFIG_SOC_CAMERA_MT9V022 is not set
# CONFIG_SOC_CAMERA_RJ54N1 is not set
-# CONFIG_SOC_CAMERA_TW9910 is not set
+CONFIG_SOC_CAMERA_TW9910=y
# CONFIG_SOC_CAMERA_PLATFORM is not set
# CONFIG_SOC_CAMERA_OV772X is not set
# CONFIG_SOC_CAMERA_OV9640 is not set
@@ -1001,6 +1063,7 @@ CONFIG_RADIO_ADAPTERS=y
# CONFIG_RADIO_SI470X is not set
# CONFIG_USB_MR800 is not set
# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_SAA7706H is not set
# CONFIG_RADIO_TEF6862 is not set
# CONFIG_DAB is not set
@@ -1034,6 +1097,7 @@ CONFIG_FB_DEFERRED_IO=y
#
# CONFIG_FB_S1D13XXX is not set
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
@@ -1062,7 +1126,46 @@ CONFIG_LOGO=y
# CONFIG_LOGO_SUPERH_MONO is not set
# CONFIG_LOGO_SUPERH_VGA16 is not set
CONFIG_LOGO_SUPERH_CLUT224=y
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_SEQ_DUMMY=y
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_SEQUENCER_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 is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SUPERH=y
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+
+#
+# SoC Audio support for SuperH
+#
+CONFIG_SND_SOC_SH4_FSI=y
+# CONFIG_SND_FSI_AK4642 is not set
+CONFIG_SND_FSI_DA7210=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_DA7210=y
+# CONFIG_SOUND_PRIME is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HIDRAW is not set
@@ -1077,6 +1180,7 @@ CONFIG_USB_HID=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
@@ -1091,12 +1195,16 @@ CONFIG_USB_HID=y
# 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_QUANTA 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
@@ -1136,6 +1244,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_SL811_HCD is not set
CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
#
# USB Device Class drivers
@@ -1188,7 +1297,6 @@ CONFIG_USB_STORAGE=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
@@ -1200,8 +1308,45 @@ CONFIG_USB_STORAGE=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
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+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=y
+CONFIG_USB_R8A66597=y
+# 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 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
#
# OTG and related infrastructure
@@ -1224,10 +1369,8 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
CONFIG_MMC_SPI=y
-# CONFIG_MMC_TMIO is not set
+CONFIG_MMC_TMIO=y
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
@@ -1253,10 +1396,10 @@ CONFIG_RTC_INTF_DEV=y
# 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_RS5C372=y
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_X1205 is not set
-CONFIG_RTC_DRV_PCF8563=y
+# 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
@@ -1303,8 +1446,6 @@ CONFIG_RTC_DRV_PCF8563=y
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
#
# TI VLYNQ
@@ -1390,6 +1531,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_UBIFS_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
@@ -1418,6 +1560,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
@@ -1487,6 +1630,7 @@ CONFIG_DEBUG_FS=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1618,7 +1762,7 @@ CONFIG_CRYPTO_HW=y
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
+CONFIG_CRC_CCITT=y
# CONFIG_CRC16 is not set
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
index 727126e907e..4a277224a87 100644
--- a/arch/sh/drivers/dma/dma-api.c
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/dma.h>
DEFINE_SPINLOCK(dma_spin_lock);
diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c
index 72622e30761..6ab9c4a1543 100644
--- a/arch/sh/drivers/dma/dmabrg.c
+++ b/arch/sh/drivers/dma/dmabrg.c
@@ -8,6 +8,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <asm/dma.h>
#include <asm/dmabrg.h>
#include <asm/io.h>
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index 2acbc793032..7efc9c354fc 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -24,6 +24,7 @@
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/heartbeat.h>
#define DRV_NAME "heartbeat"
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index ae91a2dd918..68cb9b0ac9d 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "pcie-sh7786.h"
#include <asm/sizes.h>
diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c
index 725be6de589..7b42c247316 100644
--- a/arch/sh/drivers/push-switch.c
+++ b/arch/sh/drivers/push-switch.c
@@ -8,6 +8,7 @@
* for more details.
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index da3ebec921a..1f4e562c5e8 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -86,8 +86,8 @@ extern void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len);
-#define flush_cache_vmap(start, end) flush_cache_all()
-#define flush_cache_vunmap(start, end) flush_cache_all()
+#define flush_cache_vmap(start, end) local_flush_cache_all(NULL)
+#define flush_cache_vunmap(start, end) local_flush_cache_all(NULL)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
diff --git a/arch/sh/include/asm/dma-register.h b/arch/sh/include/asm/dma-register.h
new file mode 100644
index 00000000000..51cd78feacf
--- /dev/null
+++ b/arch/sh/include/asm/dma-register.h
@@ -0,0 +1,51 @@
+/*
+ * Common header for the legacy SH DMA driver and the new dmaengine driver
+ *
+ * extracted from arch/sh/include/asm/dma-sh.h:
+ *
+ * Copyright (C) 2000 Takashi YOSHII
+ * Copyright (C) 2003 Paul Mundt
+ *
+ * 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 DMA_REGISTER_H
+#define DMA_REGISTER_H
+
+/* DMA register */
+#define SAR 0x00
+#define DAR 0x04
+#define TCR 0x08
+#define CHCR 0x0C
+#define DMAOR 0x40
+
+/* DMAOR definitions */
+#define DMAOR_AE 0x00000004
+#define DMAOR_NMIF 0x00000002
+#define DMAOR_DME 0x00000001
+
+/* Definitions for the SuperH DMAC */
+#define REQ_L 0x00000000
+#define REQ_E 0x00080000
+#define RACK_H 0x00000000
+#define RACK_L 0x00040000
+#define ACK_R 0x00000000
+#define ACK_W 0x00020000
+#define ACK_H 0x00000000
+#define ACK_L 0x00010000
+#define DM_INC 0x00004000
+#define DM_DEC 0x00008000
+#define DM_FIX 0x0000c000
+#define SM_INC 0x00001000
+#define SM_DEC 0x00002000
+#define SM_FIX 0x00003000
+#define RS_IN 0x00000200
+#define RS_OUT 0x00000300
+#define TS_BLK 0x00000040
+#define TM_BUR 0x00000020
+#define CHCR_DE 0x00000001
+#define CHCR_TE 0x00000002
+#define CHCR_IE 0x00000004
+
+#endif
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
index e934a2e6665..f3acb8e34c6 100644
--- a/arch/sh/include/asm/dma-sh.h
+++ b/arch/sh/include/asm/dma-sh.h
@@ -11,7 +11,8 @@
#ifndef __DMA_SH_H
#define __DMA_SH_H
-#include <asm/dma.h>
+#include <asm/dma-register.h>
+#include <cpu/dma-register.h>
#include <cpu/dma.h>
/* DMAOR contorl: The DMAOR access size is different by CPU.*/
@@ -53,34 +54,6 @@ static int dmte_irq_map[] __maybe_unused = {
#endif
};
-/* Definitions for the SuperH DMAC */
-#define REQ_L 0x00000000
-#define REQ_E 0x00080000
-#define RACK_H 0x00000000
-#define RACK_L 0x00040000
-#define ACK_R 0x00000000
-#define ACK_W 0x00020000
-#define ACK_H 0x00000000
-#define ACK_L 0x00010000
-#define DM_INC 0x00004000
-#define DM_DEC 0x00008000
-#define DM_FIX 0x0000c000
-#define SM_INC 0x00001000
-#define SM_DEC 0x00002000
-#define SM_FIX 0x00003000
-#define RS_IN 0x00000200
-#define RS_OUT 0x00000300
-#define TS_BLK 0x00000040
-#define TM_BUR 0x00000020
-#define CHCR_DE 0x00000001
-#define CHCR_TE 0x00000002
-#define CHCR_IE 0x00000004
-
-/* DMAOR definitions */
-#define DMAOR_AE 0x00000004
-#define DMAOR_NMIF 0x00000002
-#define DMAOR_DME 0x00000001
-
/*
* Define the default configuration for dual address memory-memory transfer.
* The 0x400 value represents auto-request, external->external.
@@ -111,61 +84,4 @@ static u32 dma_base_addr[] __maybe_unused = {
#endif
};
-/* DMA register */
-#define SAR 0x00
-#define DAR 0x04
-#define TCR 0x08
-#define CHCR 0x0C
-#define DMAOR 0x40
-
-/*
- * for dma engine
- *
- * SuperH DMA mode
- */
-#define SHDMA_MIX_IRQ (1 << 1)
-#define SHDMA_DMAOR1 (1 << 2)
-#define SHDMA_DMAE1 (1 << 3)
-
-enum sh_dmae_slave_chan_id {
- 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_SIUA_TX,
- SHDMA_SLAVE_SIUA_RX,
- SHDMA_SLAVE_SIUB_TX,
- SHDMA_SLAVE_SIUB_RX,
- SHDMA_SLAVE_NUMBER, /* Must stay last */
-};
-
-struct sh_dmae_slave_config {
- enum sh_dmae_slave_chan_id slave_id;
- dma_addr_t addr;
- u32 chcr;
- char mid_rid;
-};
-
-struct sh_dmae_pdata {
- unsigned int mode;
- struct sh_dmae_slave_config *config;
- int config_num;
-};
-
-struct device;
-
-struct sh_dmae_slave {
- enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */
- struct device *dma_dev; /* Set by the platform */
- struct sh_dmae_slave_config *config; /* Set by the driver */
-};
-
#endif /* __DMA_SH_H */
diff --git a/arch/sh/include/asm/dmaengine.h b/arch/sh/include/asm/dmaengine.h
new file mode 100644
index 00000000000..bf2f30cf0a2
--- /dev/null
+++ b/arch/sh/include/asm/dmaengine.h
@@ -0,0 +1,93 @@
+/*
+ * Header for the new SH dmaengine driver
+ *
+ * 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 ASM_DMAENGINE_H
+#define ASM_DMAENGINE_H
+
+#include <linux/dmaengine.h>
+#include <linux/list.h>
+
+#include <asm/dma-register.h>
+
+#define SH_DMAC_MAX_CHANNELS 6
+
+enum sh_dmae_slave_chan_id {
+ 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_SIUA_TX,
+ SHDMA_SLAVE_SIUA_RX,
+ SHDMA_SLAVE_SIUB_TX,
+ SHDMA_SLAVE_SIUB_RX,
+ SHDMA_SLAVE_NUMBER, /* Must stay last */
+};
+
+struct sh_dmae_slave_config {
+ enum sh_dmae_slave_chan_id slave_id;
+ dma_addr_t addr;
+ u32 chcr;
+ char mid_rid;
+};
+
+struct sh_dmae_channel {
+ unsigned int offset;
+ unsigned int dmars;
+ unsigned int dmars_bit;
+};
+
+struct sh_dmae_pdata {
+ struct sh_dmae_slave_config *slave;
+ int slave_num;
+ struct sh_dmae_channel *channel;
+ int channel_num;
+ unsigned int ts_low_shift;
+ unsigned int ts_low_mask;
+ unsigned int ts_high_shift;
+ unsigned int ts_high_mask;
+ unsigned int *ts_shift;
+ int ts_shift_num;
+ u16 dmaor_init;
+};
+
+struct device;
+
+/* Used by slave DMA clients to request DMA to/from a specific peripheral */
+struct sh_dmae_slave {
+ enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */
+ struct device *dma_dev; /* Set by the platform */
+ struct sh_dmae_slave_config *config; /* Set by the driver */
+};
+
+struct sh_dmae_regs {
+ u32 sar; /* SAR / source address */
+ u32 dar; /* DAR / destination address */
+ u32 tcr; /* TCR / transfer count */
+};
+
+struct sh_desc {
+ struct sh_dmae_regs hw;
+ struct list_head node;
+ struct dma_async_tx_descriptor async_tx;
+ enum dma_data_direction direction;
+ dma_cookie_t cookie;
+ size_t partial;
+ int chunks;
+ int mark;
+};
+
+#endif
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index ac04255022b..ce830faeebb 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -211,7 +211,9 @@ extern void __kernel_vsyscall;
#define VSYSCALL_AUX_ENT \
if (vdso_enabled) \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE);
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \
+ else \
+ NEW_AUX_ENT(AT_IGNORE, 0);
#else
#define VSYSCALL_AUX_ENT
#endif /* CONFIG_VSYSCALL */
@@ -219,7 +221,7 @@ extern void __kernel_vsyscall;
#ifdef CONFIG_SH_FPU
#define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT)
#else
-#define FPU_AUX_ENT
+#define FPU_AUX_ENT NEW_AUX_ENT(AT_IGNORE, 0)
#endif
extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 7dab7b23a5e..f689554e17c 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -291,21 +291,21 @@ unsigned long long poke_real_address_q(unsigned long long addr,
* doesn't exist, so everything must go through page tables.
*/
#ifdef CONFIG_MMU
-void __iomem *__ioremap_caller(unsigned long offset, unsigned long size,
+void __iomem *__ioremap_caller(phys_addr_t offset, unsigned long size,
pgprot_t prot, void *caller);
void __iounmap(void __iomem *addr);
static inline void __iomem *
-__ioremap(unsigned long offset, unsigned long size, pgprot_t prot)
+__ioremap(phys_addr_t offset, unsigned long size, pgprot_t prot)
{
return __ioremap_caller(offset, size, prot, __builtin_return_address(0));
}
static inline void __iomem *
-__ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot)
+__ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
{
#ifdef CONFIG_29BIT
- unsigned long last_addr = offset + size - 1;
+ phys_addr_t last_addr = offset + size - 1;
/*
* For P1 and P2 space this is trivial, as everything is already
@@ -329,7 +329,7 @@ __ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot)
}
static inline void __iomem *
-__ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot)
+__ioremap_mode(phys_addr_t offset, unsigned long size, pgprot_t prot)
{
void __iomem *ret;
@@ -349,35 +349,32 @@ __ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot)
#define __iounmap(addr) do { } while (0)
#endif /* CONFIG_MMU */
-static inline void __iomem *
-ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
{
return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
}
static inline void __iomem *
-ioremap_cache(unsigned long offset, unsigned long size)
+ioremap_cache(phys_addr_t offset, unsigned long size)
{
return __ioremap_mode(offset, size, PAGE_KERNEL);
}
#ifdef CONFIG_HAVE_IOREMAP_PROT
static inline void __iomem *
-ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags)
+ioremap_prot(phys_addr_t offset, unsigned long size, unsigned long flags)
{
return __ioremap_mode(offset, size, __pgprot(flags));
}
#endif
#ifdef CONFIG_IOREMAP_FIXED
-extern void __iomem *ioremap_fixed(resource_size_t, unsigned long,
- unsigned long, pgprot_t);
+extern void __iomem *ioremap_fixed(phys_addr_t, unsigned long, pgprot_t);
extern int iounmap_fixed(void __iomem *);
extern void ioremap_fixed_init(void);
#else
static inline void __iomem *
-ioremap_fixed(resource_size_t phys_addr, unsigned long offset,
- unsigned long size, pgprot_t prot)
+ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
{
BUG();
return NULL;
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h
index 15a05b615ba..56e4418c19b 100644
--- a/arch/sh/include/asm/mmu.h
+++ b/arch/sh/include/asm/mmu.h
@@ -55,19 +55,36 @@ typedef struct {
#ifdef CONFIG_PMB
/* arch/sh/mm/pmb.c */
-long pmb_remap(unsigned long virt, unsigned long phys,
- unsigned long size, pgprot_t prot);
-void pmb_unmap(unsigned long addr);
-void pmb_init(void);
bool __in_29bit_mode(void);
+
+void pmb_init(void);
+int pmb_bolt_mapping(unsigned long virt, phys_addr_t phys,
+ unsigned long size, pgprot_t prot);
+void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
+ pgprot_t prot, void *caller);
+int pmb_unmap(void __iomem *addr);
+
#else
-static inline long pmb_remap(unsigned long virt, unsigned long phys,
- unsigned long size, pgprot_t prot)
+
+static inline int
+pmb_bolt_mapping(unsigned long virt, phys_addr_t phys,
+ unsigned long size, pgprot_t prot)
+{
+ return -EINVAL;
+}
+
+static inline void __iomem *
+pmb_remap_caller(phys_addr_t phys, unsigned long size,
+ pgprot_t prot, void *caller)
+{
+ return NULL;
+}
+
+static inline int pmb_unmap(void __iomem *addr)
{
return -EINVAL;
}
-#define pmb_unmap(addr) do { } while (0)
#define pmb_init(addr) do { } while (0)
#ifdef CONFIG_29BIT
@@ -77,6 +94,13 @@ static inline long pmb_remap(unsigned long virt, unsigned long phys,
#endif
#endif /* CONFIG_PMB */
+
+static inline void __iomem *
+pmb_remap(phys_addr_t phys, unsigned long size, pgprot_t prot)
+{
+ return pmb_remap_caller(phys, size, prot, __builtin_return_address(0));
+}
+
#endif /* __ASSEMBLY__ */
#endif /* __MMU_H */
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 1042f7f0a48..8bd952fcf3b 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -83,25 +83,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
*/
#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-/* pci_unmap_{single,page} being a nop depends upon the
- * configuration.
- */
-#ifdef CONFIG_DMA_NONCOHERENT
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
-#else
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME) (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-#endif
-
#ifdef CONFIG_PCI
/*
* None of the SH PCI controllers support MWI, it is always treated as a
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index e11b14ea2c4..2168fde2561 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -123,8 +123,6 @@ extern void show_regs(struct pt_regs *);
struct task_struct;
#define arch_has_single_step() (1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
struct perf_event;
struct perf_sample_data;
diff --git a/arch/sh/include/asm/siu.h b/arch/sh/include/asm/siu.h
index 57565a3b551..f1b1e6944a5 100644
--- a/arch/sh/include/asm/siu.h
+++ b/arch/sh/include/asm/siu.h
@@ -11,7 +11,7 @@
#ifndef ASM_SIU_H
#define ASM_SIU_H
-#include <asm/dma-sh.h>
+#include <asm/dmaengine.h>
struct device;
diff --git a/arch/sh/include/asm/syscalls.h b/arch/sh/include/asm/syscalls.h
index c1e2b8deb83..507725af2e5 100644
--- a/arch/sh/include/asm/syscalls.h
+++ b/arch/sh/include/asm/syscalls.h
@@ -3,17 +3,12 @@
#ifdef __KERNEL__
-struct old_utsname;
-
asmlinkage int old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
int fd, unsigned long off);
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_ipc(uint call, int first, int second,
- int third, void __user *ptr, long fifth);
-asmlinkage int sys_uname(struct old_utsname __user *name);
#ifdef CONFIG_SUPERH32
# include "syscalls_32.h"
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h
index 37cdadd975a..88e734069fa 100644
--- a/arch/sh/include/asm/topology.h
+++ b/arch/sh/include/asm/topology.h
@@ -35,7 +35,7 @@
#define pcibus_to_node(bus) ((void)(bus), -1)
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
- CPU_MASK_ALL_PTR : \
+ cpu_all_mask : \
cpumask_of_node(pcibus_to_node(bus)))
#endif
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index 365744b0526..0e7f0fc8f08 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -358,6 +358,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -370,6 +371,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index 25de158aac3..0580c33a1e0 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -398,6 +398,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -410,6 +411,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/sh/include/cpu-sh3/cpu/dma-register.h b/arch/sh/include/cpu-sh3/cpu/dma-register.h
new file mode 100644
index 00000000000..2349e488c9a
--- /dev/null
+++ b/arch/sh/include/cpu-sh3/cpu/dma-register.h
@@ -0,0 +1,41 @@
+/*
+ * SH3 CPU-specific DMA definitions, used by both DMA drivers
+ *
+ * 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 CPU_DMA_REGISTER_H
+#define CPU_DMA_REGISTER_H
+
+#define CHCR_TS_LOW_MASK 0x18
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+
+#define DMAOR_INIT DMAOR_DME
+
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ */
+enum {
+ XMIT_SZ_8BIT,
+ XMIT_SZ_16BIT,
+ XMIT_SZ_32BIT,
+ XMIT_SZ_128BIT,
+};
+
+/* 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_128BIT] = 4, \
+}
+
+#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT)
+
+#endif
diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h
index 207811a7a65..24e28b91c9d 100644
--- a/arch/sh/include/cpu-sh3/cpu/dma.h
+++ b/arch/sh/include/cpu-sh3/cpu/dma.h
@@ -20,31 +20,4 @@
#define TS_32 0x00000010
#define TS_128 0x00000018
-#define CHCR_TS_LOW_MASK 0x18
-#define CHCR_TS_LOW_SHIFT 3
-#define CHCR_TS_HIGH_MASK 0
-#define CHCR_TS_HIGH_SHIFT 0
-
-#define DMAOR_INIT DMAOR_DME
-
-/*
- * The SuperH DMAC supports a number of transmit sizes, we list them here,
- * with their respective values as they appear in the CHCR registers.
- */
-enum {
- XMIT_SZ_8BIT,
- XMIT_SZ_16BIT,
- XMIT_SZ_32BIT,
- XMIT_SZ_128BIT,
-};
-
-#define TS_SHIFT { \
- [XMIT_SZ_8BIT] = 0, \
- [XMIT_SZ_16BIT] = 1, \
- [XMIT_SZ_32BIT] = 2, \
- [XMIT_SZ_128BIT] = 4, \
-}
-
-#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT)
-
#endif /* __ASM_CPU_SH3_DMA_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-register.h b/arch/sh/include/cpu-sh4/cpu/dma-register.h
new file mode 100644
index 00000000000..55f9fec082d
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/dma-register.h
@@ -0,0 +1,112 @@
+/*
+ * SH4 CPU-specific DMA definitions, used by both DMA drivers
+ *
+ * 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 CPU_DMA_REGISTER_H
+#define CPU_DMA_REGISTER_H
+
+/* SH7751/7760/7780 DMA IRQ sources */
+
+#ifdef CONFIG_CPU_SH4A
+
+#define DMAOR_INIT DMAOR_DME
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7730)
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0x00300000
+#define CHCR_TS_HIGH_SHIFT (20 - 2) /* 2 bits for shifted low TS */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7764)
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+#else /* SH7785 */
+#define CHCR_TS_LOW_MASK 0x00000018
+#define CHCR_TS_LOW_SHIFT 3
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+#endif
+
+/* 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_128BIT_BLK = 0xb,
+ XMIT_SZ_256BIT_BLK = 0xc,
+};
+
+/* 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_128BIT_BLK] = 4, \
+ [XMIT_SZ_256BIT_BLK] = 5, \
+}
+
+#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
+ ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
+
+#else /* CONFIG_CPU_SH4A */
+
+#define DMAOR_INIT (0x8000 | DMAOR_DME)
+
+#define CHCR_TS_LOW_MASK 0x70
+#define CHCR_TS_LOW_SHIFT 4
+#define CHCR_TS_HIGH_MASK 0
+#define CHCR_TS_HIGH_SHIFT 0
+
+/* Transmit sizes and respective CHCR register values */
+enum {
+ XMIT_SZ_8BIT = 1,
+ XMIT_SZ_16BIT = 2,
+ XMIT_SZ_32BIT = 3,
+ XMIT_SZ_64BIT = 0,
+ XMIT_SZ_256BIT = 4,
+};
+
+/* 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_256BIT] = 5, \
+}
+
+#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT)
+
+#endif /* CONFIG_CPU_SH4A */
+
+#endif
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
index e734ea47d8a..9647e681fd2 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
@@ -8,20 +8,12 @@
#define DMAE0_IRQ 78 /* DMA Error IRQ*/
#define SH_DMAC_BASE0 0xFE008020
#define SH_DMARS_BASE0 0xFE009000
-#define CHCR_TS_LOW_MASK 0x00000018
-#define CHCR_TS_LOW_SHIFT 3
-#define CHCR_TS_HIGH_MASK 0
-#define CHCR_TS_HIGH_SHIFT 0
#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
#define DMTE0_IRQ 48
#define DMTE4_IRQ 76
#define DMAE0_IRQ 78 /* DMA Error IRQ*/
#define SH_DMAC_BASE0 0xFE008020
#define SH_DMARS_BASE0 0xFE009000
-#define CHCR_TS_LOW_MASK 0x00000018
-#define CHCR_TS_LOW_SHIFT 3
-#define CHCR_TS_HIGH_MASK 0x00300000
-#define CHCR_TS_HIGH_SHIFT 20
#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7764)
#define DMTE0_IRQ 34
@@ -29,10 +21,6 @@
#define DMAE0_IRQ 38
#define SH_DMAC_BASE0 0xFF608020
#define SH_DMARS_BASE0 0xFF609000
-#define CHCR_TS_LOW_MASK 0x00000018
-#define CHCR_TS_LOW_SHIFT 3
-#define CHCR_TS_HIGH_MASK 0
-#define CHCR_TS_HIGH_SHIFT 0
#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
#define DMTE0_IRQ 48 /* DMAC0A*/
#define DMTE4_IRQ 76 /* DMAC0B */
@@ -46,10 +34,6 @@
#define SH_DMAC_BASE0 0xFE008020
#define SH_DMAC_BASE1 0xFDC08020
#define SH_DMARS_BASE0 0xFDC09000
-#define CHCR_TS_LOW_MASK 0x00000018
-#define CHCR_TS_LOW_SHIFT 3
-#define CHCR_TS_HIGH_MASK 0
-#define CHCR_TS_HIGH_SHIFT 0
#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
#define DMTE0_IRQ 48 /* DMAC0A*/
#define DMTE4_IRQ 76 /* DMAC0B */
@@ -64,10 +48,6 @@
#define SH_DMAC_BASE1 0xFDC08020
#define SH_DMARS_BASE0 0xFE009000
#define SH_DMARS_BASE1 0xFDC09000
-#define CHCR_TS_LOW_MASK 0x00000018
-#define CHCR_TS_LOW_SHIFT 3
-#define CHCR_TS_HIGH_MASK 0x00600000
-#define CHCR_TS_HIGH_SHIFT 21
#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
#define DMTE0_IRQ 34
#define DMTE4_IRQ 44
@@ -80,10 +60,6 @@
#define SH_DMAC_BASE0 0xFC808020
#define SH_DMAC_BASE1 0xFC818020
#define SH_DMARS_BASE0 0xFC809000
-#define CHCR_TS_LOW_MASK 0x00000018
-#define CHCR_TS_LOW_SHIFT 3
-#define CHCR_TS_HIGH_MASK 0
-#define CHCR_TS_HIGH_SHIFT 0
#else /* SH7785 */
#define DMTE0_IRQ 33
#define DMTE4_IRQ 37
@@ -97,10 +73,6 @@
#define SH_DMAC_BASE0 0xFC808020
#define SH_DMAC_BASE1 0xFCC08020
#define SH_DMARS_BASE0 0xFC809000
-#define CHCR_TS_LOW_MASK 0x00000018
-#define CHCR_TS_LOW_SHIFT 3
-#define CHCR_TS_HIGH_MASK 0
-#define CHCR_TS_HIGH_SHIFT 0
#endif
#define REQ_HE 0x000000C0
@@ -108,38 +80,4 @@
#define REQ_LE 0x00000040
#define TM_BURST 0x00000020
-/*
- * The SuperH DMAC supports a number of transmit sizes, we list them here,
- * with their respective values as they appear in the CHCR registers.
- *
- * Defaults to a 64-bit transfer size.
- */
-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_128BIT_BLK = 0xb,
- XMIT_SZ_256BIT_BLK = 0xc,
-};
-
-/*
- * The DMA count is defined as the number of bytes to transfer.
- */
-#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_128BIT_BLK] = 4, \
- [XMIT_SZ_256BIT_BLK] = 5, \
-}
-
-#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
- ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
-
#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h
index 114a369705b..ca747e93c2e 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma.h
@@ -5,9 +5,8 @@
#ifdef CONFIG_CPU_SH4A
-#define DMAOR_INIT (DMAOR_DME)
-
#include <cpu/dma-sh4a.h>
+
#else /* CONFIG_CPU_SH4A */
/*
* SH7750/SH7751/SH7760
@@ -17,7 +16,6 @@
#define DMTE6_IRQ 46
#define DMAE0_IRQ 38
-#define DMAOR_INIT (0x8000|DMAOR_DME)
#define SH_DMAC_BASE0 0xffa00000
#define SH_DMAC_BASE1 0xffa00070
/* Definitions for the SuperH DMAC */
@@ -27,40 +25,8 @@
#define TS_32 0x00000030
#define TS_64 0x00000000
-#define CHCR_TS_LOW_MASK 0x70
-#define CHCR_TS_LOW_SHIFT 4
-#define CHCR_TS_HIGH_MASK 0
-#define CHCR_TS_HIGH_SHIFT 0
-
#define DMAOR_COD 0x00000008
-/*
- * The SuperH DMAC supports a number of transmit sizes, we list them here,
- * with their respective values as they appear in the CHCR registers.
- *
- * Defaults to a 64-bit transfer size.
- */
-enum {
- XMIT_SZ_8BIT = 1,
- XMIT_SZ_16BIT = 2,
- XMIT_SZ_32BIT = 3,
- XMIT_SZ_64BIT = 0,
- XMIT_SZ_256BIT = 4,
-};
-
-/*
- * The DMA count is defined as the number of bytes to transfer.
- */
-#define TS_SHIFT { \
- [XMIT_SZ_8BIT] = 0, \
- [XMIT_SZ_16BIT] = 1, \
- [XMIT_SZ_32BIT] = 2, \
- [XMIT_SZ_64BIT] = 3, \
- [XMIT_SZ_256BIT] = 5, \
-}
-
-#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT)
-
#endif
#endif /* __ASM_CPU_SH4_DMA_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/mmu_context.h b/arch/sh/include/cpu-sh4/cpu/mmu_context.h
index 03ea75c5315..5963124c1d4 100644
--- a/arch/sh/include/cpu-sh4/cpu/mmu_context.h
+++ b/arch/sh/include/cpu-sh4/cpu/mmu_context.h
@@ -19,6 +19,8 @@
#define MMUCR 0xFF000010 /* MMU Control Register */
+#define MMU_ITLB_ADDRESS_ARRAY 0xF2000000
+#define MMU_ITLB_ADDRESS_ARRAY2 0xF2800000
#define MMU_UTLB_ADDRESS_ARRAY 0xF6000000
#define MMU_UTLB_ADDRESS_ARRAY2 0xF6800000
#define MMU_PAGE_ASSOC_BIT 0x80
@@ -28,6 +30,8 @@
#define MMUCR_URB 0x00FC0000
#define MMUCR_URB_SHIFT 18
#define MMUCR_URB_NENTRIES 64
+#define MMUCR_URC 0x0000FC00
+#define MMUCR_URC_SHIFT 10
#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40)
#define MMUCR_SE (1 << 4)
diff --git a/arch/sh/include/cpu-sh4/cpu/watchdog.h b/arch/sh/include/cpu-sh4/cpu/watchdog.h
index 7672301d0c7..7f62b938093 100644
--- a/arch/sh/include/cpu-sh4/cpu/watchdog.h
+++ b/arch/sh/include/cpu-sh4/cpu/watchdog.h
@@ -21,6 +21,12 @@
#define WTCNT 0xffcc0000 /*WDTST*/
#define WTST WTCNT
#define WTBST 0xffcc0008 /*WDTBST*/
+/* Register definitions */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define WTCNT 0xa4520000
+#define WTCSR 0xa4520004
#else
/* Register definitions */
#define WTCNT 0xffc00008
diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h
index cee6cb88e02..42fccf93412 100644
--- a/arch/sh/include/mach-migor/mach/migor.h
+++ b/arch/sh/include/mach-migor/mach/migor.h
@@ -1,6 +1,7 @@
#ifndef __ASM_SH_MIGOR_H
#define __ASM_SH_MIGOR_H
+#define PORT_MSELCRA 0xa4050180
#define PORT_MSELCRB 0xa4050182
#define BSC_CS4BCR 0xfec10010
#define BSC_CS6ABCR 0xfec1001c
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 83da5debeed..e9fa1bfed53 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -404,7 +404,7 @@ EXPORT_SYMBOL_GPL(clk_round_rate);
* If an entry has a device ID, it must match
* If an entry has a connection ID, it must match
* Then we take the most specific entry - with the following
- * order of precidence: dev+con > dev only > con only.
+ * order of precedence: dev+con > dev only > con only.
*/
static struct clk *clk_find(const char *dev_id, const char *con_id)
{
diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c
index f059ed62cf5..7f1b70cace3 100644
--- a/arch/sh/kernel/cpu/fpu.c
+++ b/arch/sh/kernel/cpu/fpu.c
@@ -1,4 +1,5 @@
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/fpu.h>
diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c
index c0ad7d46e78..67a1e811cfe 100644
--- a/arch/sh/kernel/cpu/hwblk.c
+++ b/arch/sh/kernel/cpu/hwblk.c
@@ -1,6 +1,5 @@
#include <linux/clk.h>
#include <linux/compiler.h>
-#include <linux/slab.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm/suspend.h>
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index fc065f9da6e..14726eef1ce 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -326,7 +326,7 @@ static struct attribute *sq_sysfs_attrs[] = {
NULL,
};
-static struct sysfs_ops sq_sysfs_ops = {
+static const struct sysfs_ops sq_sysfs_ops = {
.show = sq_sysfs_show,
.store = sq_sysfs_store,
};
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index ef3f9782780..fd7e3639e84 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -7,19 +7,167 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
-#include <linux/platform_device.h>
#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
-#include <linux/mm.h>
+#include <linux/sh_timer.h>
#include <linux/uio_driver.h>
#include <linux/usb/m66592.h>
-#include <linux/sh_timer.h>
+
#include <asm/clock.h>
+#include <asm/dmaengine.h>
#include <asm/mmzone.h>
-#include <asm/dma-sh.h>
+#include <asm/siu.h>
+
+#include <cpu/dma-register.h>
#include <cpu/sh7722.h>
+static struct sh_dmae_slave_config sh7722_dmae_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_SCIF0_TX,
+ .addr = 0xffe0000c,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x21,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF0_RX,
+ .addr = 0xffe00014,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x22,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF1_TX,
+ .addr = 0xffe1000c,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x25,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF1_RX,
+ .addr = 0xffe10014,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x26,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF2_TX,
+ .addr = 0xffe2000c,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x29,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF2_RX,
+ .addr = 0xffe20014,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x2a,
+ }, {
+ .slave_id = SHDMA_SLAVE_SIUA_TX,
+ .addr = 0xa454c098,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .mid_rid = 0xb1,
+ }, {
+ .slave_id = SHDMA_SLAVE_SIUA_RX,
+ .addr = 0xa454c090,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .mid_rid = 0xb2,
+ }, {
+ .slave_id = SHDMA_SLAVE_SIUB_TX,
+ .addr = 0xa454c09c,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .mid_rid = 0xb5,
+ }, {
+ .slave_id = SHDMA_SLAVE_SIUB_RX,
+ .addr = 0xa454c094,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .mid_rid = 0xb6,
+ },
+};
+
+static struct sh_dmae_channel sh7722_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 unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma_platform_data = {
+ .slave = sh7722_dmae_slaves,
+ .slave_num = ARRAY_SIZE(sh7722_dmae_slaves),
+ .channel = sh7722_dmae_channels,
+ .channel_num = ARRAY_SIZE(sh7722_dmae_channels),
+ .ts_low_shift = CHCR_TS_LOW_SHIFT,
+ .ts_low_mask = CHCR_TS_LOW_MASK,
+ .ts_high_shift = CHCR_TS_HIGH_SHIFT,
+ .ts_high_mask = CHCR_TS_HIGH_MASK,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_INIT,
+};
+
+static struct resource sh7722_dmae_resources[] = {
+ [0] = {
+ /* Channel registers and DMAOR */
+ .start = 0xfe008020,
+ .end = 0xfe00808f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* DMARSx */
+ .start = 0xfe009000,
+ .end = 0xfe00900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = 78,
+ .end = 78,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-3 */
+ .start = 48,
+ .end = 51,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 4-5 */
+ .start = 76,
+ .end = 77,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device dma_device = {
+ .name = "sh-dma-engine",
+ .id = -1,
+ .resource = sh7722_dmae_resources,
+ .num_resources = ARRAY_SIZE(sh7722_dmae_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+ .archdata = {
+ .hwblk_id = HWBLK_DMAC,
+ },
+};
+
/* Serial */
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xffe00000,
@@ -388,15 +536,36 @@ static struct platform_device tmu2_device = {
},
};
-static struct sh_dmae_pdata dma_platform_data = {
- .mode = 0,
+static struct siu_platform siu_platform_data = {
+ .dma_dev = &dma_device.dev,
+ .dma_slave_tx_a = SHDMA_SLAVE_SIUA_TX,
+ .dma_slave_rx_a = SHDMA_SLAVE_SIUA_RX,
+ .dma_slave_tx_b = SHDMA_SLAVE_SIUB_TX,
+ .dma_slave_rx_b = SHDMA_SLAVE_SIUB_RX,
};
-static struct platform_device dma_device = {
- .name = "sh-dma-engine",
+static struct resource siu_resources[] = {
+ [0] = {
+ .start = 0xa4540000,
+ .end = 0xa454c10f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 108,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device siu_device = {
+ .name = "sh_siu",
.id = -1,
- .dev = {
- .platform_data = &dma_platform_data,
+ .dev = {
+ .platform_data = &siu_platform_data,
+ },
+ .resource = siu_resources,
+ .num_resources = ARRAY_SIZE(siu_resources),
+ .archdata = {
+ .hwblk_id = HWBLK_SIU,
},
};
@@ -414,6 +583,7 @@ static struct platform_device *sh7722_devices[] __initdata = {
&vpu_device,
&veu_device,
&jpu_device,
+ &siu_device,
&dma_device,
};
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 31e3451f7e3..e7fa2a92fc1 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -21,22 +21,189 @@
#include <linux/sh_timer.h>
#include <linux/io.h>
#include <linux/notifier.h>
+
#include <asm/suspend.h>
#include <asm/clock.h>
-#include <asm/dma-sh.h>
+#include <asm/dmaengine.h>
#include <asm/mmzone.h>
+
+#include <cpu/dma-register.h>
#include <cpu/sh7724.h>
/* DMA */
-static struct sh_dmae_pdata dma_platform_data = {
- .mode = SHDMA_DMAOR1,
+static struct sh_dmae_channel sh7724_dmae0_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 struct sh_dmae_channel sh7724_dmae1_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 unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma0_platform_data = {
+ .channel = sh7724_dmae0_channels,
+ .channel_num = ARRAY_SIZE(sh7724_dmae0_channels),
+ .ts_low_shift = CHCR_TS_LOW_SHIFT,
+ .ts_low_mask = CHCR_TS_LOW_MASK,
+ .ts_high_shift = CHCR_TS_HIGH_SHIFT,
+ .ts_high_mask = CHCR_TS_HIGH_MASK,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_INIT,
+};
+
+static struct sh_dmae_pdata dma1_platform_data = {
+ .channel = sh7724_dmae1_channels,
+ .channel_num = ARRAY_SIZE(sh7724_dmae1_channels),
+ .ts_low_shift = CHCR_TS_LOW_SHIFT,
+ .ts_low_mask = CHCR_TS_LOW_MASK,
+ .ts_high_shift = CHCR_TS_HIGH_SHIFT,
+ .ts_high_mask = CHCR_TS_HIGH_MASK,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_INIT,
+};
+
+/* Resource order important! */
+static struct resource sh7724_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 = 78,
+ .end = 78,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-3 */
+ .start = 48,
+ .end = 51,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 4-5 */
+ .start = 76,
+ .end = 77,
+ .flags = IORESOURCE_IRQ,
+ },
};
-static struct platform_device dma_device = {
- .name = "sh-dma-engine",
- .id = -1,
- .dev = {
- .platform_data = &dma_platform_data,
+/* Resource order important! */
+static struct resource sh7724_dmae1_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfdc08020,
+ .end = 0xfdc0808f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfdc09000,
+ .end = 0xfdc0900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = 74,
+ .end = 74,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-3 */
+ .start = 40,
+ .end = 43,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 4-5 */
+ .start = 72,
+ .end = 73,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dma0_device = {
+ .name = "sh-dma-engine",
+ .id = 0,
+ .resource = sh7724_dmae0_resources,
+ .num_resources = ARRAY_SIZE(sh7724_dmae0_resources),
+ .dev = {
+ .platform_data = &dma0_platform_data,
+ },
+ .archdata = {
+ .hwblk_id = HWBLK_DMAC0,
+ },
+};
+
+static struct platform_device dma1_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = sh7724_dmae1_resources,
+ .num_resources = ARRAY_SIZE(sh7724_dmae1_resources),
+ .dev = {
+ .platform_data = &dma1_platform_data,
+ },
+ .archdata = {
+ .hwblk_id = HWBLK_DMAC1,
},
};
@@ -663,7 +830,8 @@ static struct platform_device *sh7724_devices[] __initdata = {
&tmu3_device,
&tmu4_device,
&tmu5_device,
- &dma_device,
+ &dma0_device,
+ &dma1_device,
&rtc_device,
&iic0_device,
&iic1_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index f8f21618d78..02e792c90de 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -13,7 +13,10 @@
#include <linux/io.h>
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
-#include <asm/dma-sh.h>
+
+#include <asm/dmaengine.h>
+
+#include <cpu/dma-register.h>
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xffe00000,
@@ -247,15 +250,131 @@ static struct platform_device rtc_device = {
.resource = rtc_resources,
};
-static struct sh_dmae_pdata dma_platform_data = {
- .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1),
+/* DMA */
+static struct sh_dmae_channel sh7780_dmae0_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 struct sh_dmae_channel sh7780_dmae1_channels[] = {
+ {
+ .offset = 0,
+ }, {
+ .offset = 0x10,
+ }, {
+ .offset = 0x20,
+ }, {
+ .offset = 0x30,
+ }, {
+ .offset = 0x50,
+ }, {
+ .offset = 0x60,
+ }
+};
+
+static unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma0_platform_data = {
+ .channel = sh7780_dmae0_channels,
+ .channel_num = ARRAY_SIZE(sh7780_dmae0_channels),
+ .ts_low_shift = CHCR_TS_LOW_SHIFT,
+ .ts_low_mask = CHCR_TS_LOW_MASK,
+ .ts_high_shift = CHCR_TS_HIGH_SHIFT,
+ .ts_high_mask = CHCR_TS_HIGH_MASK,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_INIT,
+};
+
+static struct sh_dmae_pdata dma1_platform_data = {
+ .channel = sh7780_dmae1_channels,
+ .channel_num = ARRAY_SIZE(sh7780_dmae1_channels),
+ .ts_low_shift = CHCR_TS_LOW_SHIFT,
+ .ts_low_mask = CHCR_TS_LOW_MASK,
+ .ts_high_shift = CHCR_TS_HIGH_SHIFT,
+ .ts_high_mask = CHCR_TS_HIGH_MASK,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_INIT,
};
-static struct platform_device dma_device = {
+static struct resource sh7780_dmae0_resources[] = {
+ [0] = {
+ /* Channel registers and DMAOR */
+ .start = 0xfc808020,
+ .end = 0xfc80808f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* DMARSx */
+ .start = 0xfc809000,
+ .end = 0xfc80900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* Real DMA error IRQ is 38, and channel IRQs are 34-37, 44-45 */
+ .start = 34,
+ .end = 34,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+ },
+};
+
+static struct resource sh7780_dmae1_resources[] = {
+ [0] = {
+ /* Channel registers and DMAOR */
+ .start = 0xfc818020,
+ .end = 0xfc81808f,
+ .flags = IORESOURCE_MEM,
+ },
+ /* DMAC1 has no DMARS */
+ {
+ /* Real DMA error IRQ is 38, and channel IRQs are 46-47, 92-95 */
+ .start = 46,
+ .end = 46,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+ },
+};
+
+static struct platform_device dma0_device = {
.name = "sh-dma-engine",
- .id = -1,
+ .id = 0,
+ .resource = sh7780_dmae0_resources,
+ .num_resources = ARRAY_SIZE(sh7780_dmae0_resources),
.dev = {
- .platform_data = &dma_platform_data,
+ .platform_data = &dma0_platform_data,
+ },
+};
+
+static struct platform_device dma1_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = sh7780_dmae1_resources,
+ .num_resources = ARRAY_SIZE(sh7780_dmae1_resources),
+ .dev = {
+ .platform_data = &dma1_platform_data,
},
};
@@ -269,7 +388,8 @@ static struct platform_device *sh7780_devices[] __initdata = {
&tmu4_device,
&tmu5_device,
&rtc_device,
- &dma_device,
+ &dma0_device,
+ &dma1_device,
};
static int __init sh7780_devices_setup(void)
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 23448d8c671..1fcd88b1671 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -14,9 +14,12 @@
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/sh_timer.h>
-#include <asm/dma-sh.h>
+
+#include <asm/dmaengine.h>
#include <asm/mmzone.h>
+#include <cpu/dma-register.h>
+
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xffea0000,
.flags = UPF_BOOT_AUTOCONF,
@@ -295,15 +298,131 @@ static struct platform_device tmu5_device = {
.num_resources = ARRAY_SIZE(tmu5_resources),
};
-static struct sh_dmae_pdata dma_platform_data = {
- .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1),
+/* DMA */
+static struct sh_dmae_channel sh7785_dmae0_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 struct sh_dmae_channel sh7785_dmae1_channels[] = {
+ {
+ .offset = 0,
+ }, {
+ .offset = 0x10,
+ }, {
+ .offset = 0x20,
+ }, {
+ .offset = 0x30,
+ }, {
+ .offset = 0x50,
+ }, {
+ .offset = 0x60,
+ }
+};
+
+static unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma0_platform_data = {
+ .channel = sh7785_dmae0_channels,
+ .channel_num = ARRAY_SIZE(sh7785_dmae0_channels),
+ .ts_low_shift = CHCR_TS_LOW_SHIFT,
+ .ts_low_mask = CHCR_TS_LOW_MASK,
+ .ts_high_shift = CHCR_TS_HIGH_SHIFT,
+ .ts_high_mask = CHCR_TS_HIGH_MASK,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_INIT,
+};
+
+static struct sh_dmae_pdata dma1_platform_data = {
+ .channel = sh7785_dmae1_channels,
+ .channel_num = ARRAY_SIZE(sh7785_dmae1_channels),
+ .ts_low_shift = CHCR_TS_LOW_SHIFT,
+ .ts_low_mask = CHCR_TS_LOW_MASK,
+ .ts_high_shift = CHCR_TS_HIGH_SHIFT,
+ .ts_high_mask = CHCR_TS_HIGH_MASK,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_INIT,
};
-static struct platform_device dma_device = {
+static struct resource sh7785_dmae0_resources[] = {
+ [0] = {
+ /* Channel registers and DMAOR */
+ .start = 0xfc808020,
+ .end = 0xfc80808f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* DMARSx */
+ .start = 0xfc809000,
+ .end = 0xfc80900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* Real DMA error IRQ is 39, and channel IRQs are 33-38 */
+ .start = 33,
+ .end = 33,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+ },
+};
+
+static struct resource sh7785_dmae1_resources[] = {
+ [0] = {
+ /* Channel registers and DMAOR */
+ .start = 0xfcc08020,
+ .end = 0xfcc0808f,
+ .flags = IORESOURCE_MEM,
+ },
+ /* DMAC1 has no DMARS */
+ {
+ /* Real DMA error IRQ is 58, and channel IRQs are 52-57 */
+ .start = 52,
+ .end = 52,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+ },
+};
+
+static struct platform_device dma0_device = {
.name = "sh-dma-engine",
- .id = -1,
+ .id = 0,
+ .resource = sh7785_dmae0_resources,
+ .num_resources = ARRAY_SIZE(sh7785_dmae0_resources),
.dev = {
- .platform_data = &dma_platform_data,
+ .platform_data = &dma0_platform_data,
+ },
+};
+
+static struct platform_device dma1_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = sh7785_dmae1_resources,
+ .num_resources = ARRAY_SIZE(sh7785_dmae1_resources),
+ .dev = {
+ .platform_data = &dma1_platform_data,
},
};
@@ -320,7 +439,8 @@ static struct platform_device *sh7785_devices[] __initdata = {
&tmu3_device,
&tmu4_device,
&tmu5_device,
- &dma_device,
+ &dma0_device,
+ &dma1_device,
};
static int __init sh7785_devices_setup(void)
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
index dce4f3ff093..0fffacea6ed 100644
--- a/arch/sh/kernel/cpufreq.c
+++ b/arch/sh/kernel/cpufreq.c
@@ -48,7 +48,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
return -ENODEV;
cpus_allowed = current->cpus_allowed;
- set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ set_cpus_allowed_ptr(current, cpumask_of(cpu));
BUG_ON(smp_processor_id() != cpu);
@@ -66,7 +66,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
freqs.flags = 0;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- set_cpus_allowed(current, cpus_allowed);
+ set_cpus_allowed_ptr(current, &cpus_allowed);
clk_set_rate(cpuclk, freq);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index bd1c497280a..a8234b2010d 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -22,6 +22,7 @@
#include <linux/mm.h>
#include <linux/elf.h>
#include <linux/ftrace.h>
+#include <linux/slab.h>
#include <asm/dwarf.h>
#include <asm/unwinder.h>
#include <asm/sections.h>
@@ -727,7 +728,7 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
unsigned char *end, struct module *mod)
{
struct rb_node **rb_node = &cie_root.rb_node;
- struct rb_node *parent;
+ struct rb_node *parent = *rb_node;
struct dwarf_cie *cie;
unsigned long flags;
int count;
@@ -856,7 +857,7 @@ static int dwarf_parse_fde(void *entry, u32 entry_type,
unsigned char *end, struct module *mod)
{
struct rb_node **rb_node = &fde_root.rb_node;
- struct rb_node *parent;
+ struct rb_node *parent = *rb_node;
struct dwarf_fde *fde;
struct dwarf_cie *cie;
unsigned long flags;
diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c
index e2f1753d275..675eea7785d 100644
--- a/arch/sh/kernel/hw_breakpoint.c
+++ b/arch/sh/kernel/hw_breakpoint.c
@@ -143,26 +143,6 @@ static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
}
-/*
- * Store a breakpoint's encoded address, length, and type.
- */
-static int arch_store_info(struct perf_event *bp)
-{
- struct arch_hw_breakpoint *info = counter_arch_bp(bp);
-
- /*
- * User-space requests will always have the address field populated
- * For kernel-addresses, either the address or symbol name can be
- * specified.
- */
- if (info->name)
- info->address = (unsigned long)kallsyms_lookup_name(info->name);
- if (info->address)
- return 0;
-
- return -EINVAL;
-}
-
int arch_bp_generic_fields(int sh_len, int sh_type,
int *gen_len, int *gen_type)
{
@@ -276,10 +256,12 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
return ret;
}
- ret = arch_store_info(bp);
-
- if (ret < 0)
- return ret;
+ /*
+ * For kernel-addresses, either the address or symbol name can be
+ * specified.
+ */
+ if (info->name)
+ info->address = (unsigned long)kallsyms_lookup_name(info->name);
/*
* Check that the low-order bits of the address are appropriate
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 0fd7b41f0a2..273f890b17a 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -112,7 +112,7 @@ void cpu_idle(void)
}
}
-void __cpuinit select_idle_routine(void)
+void __init select_idle_routine(void)
{
/*
* If a platform has set its own idle routine, leave it alone.
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index c96850b061f..4049d99f76e 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -13,6 +13,7 @@
#include <linux/ptrace.h>
#include <linux/preempt.h>
#include <linux/kdebug.h>
+#include <linux/slab.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c
index 7ff0943e7a0..81b6de41ae5 100644
--- a/arch/sh/kernel/perf_event.c
+++ b/arch/sh/kernel/perf_event.c
@@ -275,13 +275,30 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
return &pmu;
}
-void hw_perf_event_setup(int cpu)
+static void sh_pmu_setup(int cpu)
{
struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
memset(cpuhw, 0, sizeof(struct cpu_hw_events));
}
+static int __cpuinit
+sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ sh_pmu_setup(cpu);
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
void hw_perf_enable(void)
{
if (!sh_pmu_initialized())
@@ -298,7 +315,7 @@ void hw_perf_disable(void)
sh_pmu->disable_all();
}
-int register_sh_pmu(struct sh_pmu *pmu)
+int __cpuinit register_sh_pmu(struct sh_pmu *pmu)
{
if (sh_pmu)
return -EBUSY;
@@ -308,5 +325,6 @@ int register_sh_pmu(struct sh_pmu *pmu)
WARN_ON(pmu->num_events > MAX_HWEVENTS);
+ perf_cpu_notifier(sh_pmu_notifier);
return 0;
}
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 81add9b9ea6..17f89aa4e1b 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -1,5 +1,6 @@
#include <linux/mm.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/sched.h>
struct kmem_cache *task_xstate_cachep = NULL;
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 3cb88f114d7..052981972ae 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -15,6 +15,7 @@
*/
#include <linux/module.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/elfcore.h>
#include <linux/kallsyms.h>
#include <linux/fs.h>
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index c90957a459a..d4ca6480e35 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/ptrace.h>
#include <linux/reboot.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
@@ -504,13 +505,6 @@ out:
return error;
}
-/*
- * These bracket the sleeping functions..
- */
-extern void interruptible_sleep_on(wait_queue_head_t *q);
-
-#define mid_sched ((unsigned long) interruptible_sleep_on)
-
#ifdef CONFIG_FRAME_POINTER
static int in_sh64_switch_to(unsigned long pc)
{
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index c625cdab76d..7759a9a9321 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
-#include <linux/slab.h>
#include <linux/security.h>
#include <linux/signal.h>
#include <linux/io.h>
diff --git a/arch/sh/kernel/return_address.c b/arch/sh/kernel/return_address.c
index df3ab581107..cbf1dd5372b 100644
--- a/arch/sh/kernel/return_address.c
+++ b/arch/sh/kernel/return_address.c
@@ -9,6 +9,7 @@
* for more details.
*/
#include <linux/kernel.h>
+#include <linux/module.h>
#include <asm/dwarf.h>
#ifdef CONFIG_DWARF_UNWINDER
@@ -52,3 +53,5 @@ void *return_address(unsigned int depth)
}
#endif
+
+EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 3459e70eed7..8870d6ba64b 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -443,7 +443,7 @@ void __init setup_arch(char **cmdline_p)
nodes_clear(node_online_map);
- /* Setup bootmem with available RAM */
+ pmb_init();
lmb_init();
setup_memory();
sparse_init();
@@ -452,7 +452,6 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
paging_init();
- pmb_init();
ioremap_fixed_init();
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index e124cf7008d..002cc612dee 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -69,6 +69,7 @@ asmlinkage void __cpuinit start_secondary(void)
unsigned int cpu;
struct mm_struct *mm = &init_mm;
+ enable_mmu();
atomic_inc(&mm->mm_count);
atomic_inc(&mm->mm_users);
current->active_mm = mm;
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 71399cde03b..81f58371613 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -53,110 +53,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
}
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc(uint call, int first, int second,
- int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- if (call <= SEMTIMEDOP)
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first,
- (struct sembuf __user *)ptr,
- second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first,
- (struct sembuf __user *)ptr, second,
- (const struct timespec __user *)fifth);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void __user * __user *) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
- default:
- return -EINVAL;
- }
-
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0:
- {
- struct ipc_kludge tmp;
-
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof (tmp)))
- return -EFAULT;
-
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second,
- (struct msqid_ds __user *) ptr);
- default:
- return -EINVAL;
- }
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat (first, (char __user *) ptr,
- second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong __user *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return do_shmat (first, (char __user *) ptr,
- second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char __user *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -EINVAL;
- }
-
- return -EINVAL;
-}
-
/* sys_cacheflush -- flush (part of) the processor cache. */
asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
{
@@ -197,14 +93,3 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
up_read(&current->mm->mmap_sem);
return 0;
}
-
-asmlinkage int sys_uname(struct old_utsname __user *name)
-{
- int err;
- if (!name)
- return -EFAULT;
- down_read(&uts_sem);
- err = copy_to_user(name, utsname(), sizeof(*name));
- up_read(&uts_sem);
- return err?-EFAULT:0;
-}
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 953fa161331..8a0072de2bc 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -39,12 +39,12 @@ static int null_rtc_set_time(const time_t secs)
void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
-#ifdef CONFIG_GENERIC_CMOS_UPDATE
void read_persistent_clock(struct timespec *ts)
{
rtc_sh_get_time(ts);
}
+#ifdef CONFIG_GENERIC_CMOS_UPDATE
int update_persistent_clock(struct timespec now)
{
return rtc_sh_set_time(now.tv_sec);
@@ -113,9 +113,5 @@ void __init time_init(void)
hwblk_init();
clk_init();
- rtc_sh_get_time(&xtime);
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
-
late_time_init = sh_late_time_init;
}
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c
index 3f7e415be86..242117cbad6 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.c
+++ b/arch/sh/kernel/vsyscall/vsyscall.c
@@ -11,7 +11,6 @@
* for more details.
*/
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gfp.h>
diff --git a/arch/sh/lib/libgcc.h b/arch/sh/lib/libgcc.h
index 3f19d1c5d94..05909d58e2f 100644
--- a/arch/sh/lib/libgcc.h
+++ b/arch/sh/lib/libgcc.h
@@ -17,8 +17,7 @@ struct DWstruct {
#error I feel sick.
#endif
-typedef union
-{
+typedef union {
struct DWstruct s;
long long ll;
} DWunion;
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index 902967e3f84..c86a0854025 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -16,6 +16,7 @@
#include <linux/dma-debug.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <asm/cacheflush.h>
#include <asm/addrspace.h>
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index 9304117039c..9163db3e8d1 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/slab.h>
#include <linux/sysctl.h>
#include <asm/mman.h>
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 68028e8f26c..c505de61a5c 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -10,6 +10,7 @@
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/bootmem.h>
#include <linux/proc_fs.h>
#include <linux/pagemap.h>
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index c68d2d7d00a..0c99ec2e7ed 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -14,6 +14,7 @@
*/
#include <linux/vmalloc.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/io.h>
@@ -34,11 +35,12 @@
* caller shouldn't need to know that small detail.
*/
void __iomem * __init_refok
-__ioremap_caller(unsigned long phys_addr, unsigned long size,
+__ioremap_caller(phys_addr_t phys_addr, unsigned long size,
pgprot_t pgprot, void *caller)
{
struct vm_struct *area;
unsigned long offset, last_addr, addr, orig_addr;
+ void __iomem *mapped;
/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
@@ -46,6 +48,20 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size,
return NULL;
/*
+ * If we can't yet use the regular approach, go the fixmap route.
+ */
+ if (!mem_init_done)
+ return ioremap_fixed(phys_addr, size, pgprot);
+
+ /*
+ * First try to remap through the PMB.
+ * PMB entries are all pre-faulted.
+ */
+ mapped = pmb_remap_caller(phys_addr, size, pgprot, caller);
+ if (mapped && !IS_ERR(mapped))
+ return mapped;
+
+ /*
* Mappings have to be page-aligned
*/
offset = phys_addr & ~PAGE_MASK;
@@ -53,12 +69,6 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size,
size = PAGE_ALIGN(last_addr+1) - phys_addr;
/*
- * If we can't yet use the regular approach, go the fixmap route.
- */
- if (!mem_init_done)
- return ioremap_fixed(phys_addr, offset, size, pgprot);
-
- /*
* Ok, go for it..
*/
area = get_vm_area_caller(size, VM_IOREMAP, caller);
@@ -67,33 +77,10 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size,
area->phys_addr = phys_addr;
orig_addr = addr = (unsigned long)area->addr;
-#ifdef CONFIG_PMB
- /*
- * First try to remap through the PMB once a valid VMA has been
- * established. Smaller allocations (or the rest of the size
- * remaining after a PMB mapping due to the size not being
- * perfectly aligned on a PMB size boundary) are then mapped
- * through the UTLB using conventional page tables.
- *
- * PMB entries are all pre-faulted.
- */
- if (unlikely(phys_addr >= P1SEG)) {
- unsigned long mapped;
-
- mapped = pmb_remap(addr, phys_addr, size, pgprot);
- if (likely(mapped)) {
- addr += mapped;
- phys_addr += mapped;
- size -= mapped;
- }
+ if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) {
+ vunmap((void *)orig_addr);
+ return NULL;
}
-#endif
-
- if (likely(size))
- if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) {
- vunmap((void *)orig_addr);
- return NULL;
- }
return (void __iomem *)(offset + (char *)orig_addr);
}
@@ -133,23 +120,11 @@ void __iounmap(void __iomem *addr)
if (iounmap_fixed(addr) == 0)
return;
-#ifdef CONFIG_PMB
/*
- * Purge any PMB entries that may have been established for this
- * mapping, then proceed with conventional VMA teardown.
- *
- * XXX: Note that due to the way that remove_vm_area() does
- * matching of the resultant VMA, we aren't able to fast-forward
- * the address past the PMB space until the end of the VMA where
- * the page tables reside. As such, unmap_vm_area() will be
- * forced to linearly scan over the area until it finds the page
- * tables where PTEs that need to be unmapped actually reside,
- * which is far from optimal. Perhaps we need to use a separate
- * VMA for the PMB mappings?
- * -- PFM.
+ * If the PMB handled it, there's nothing else to do.
*/
- pmb_unmap(vaddr);
-#endif
+ if (pmb_unmap(addr) == 0)
+ return;
p = remove_vm_area((void *)(vaddr & PAGE_MASK));
if (!p) {
diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c
index 0b78b1e20ef..efbe84af998 100644
--- a/arch/sh/mm/ioremap_fixed.c
+++ b/arch/sh/mm/ioremap_fixed.c
@@ -15,7 +15,6 @@
#include <linux/io.h>
#include <linux/bootmem.h>
#include <linux/proc_fs.h>
-#include <linux/slab.h>
#include <asm/fixmap.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
@@ -45,14 +44,21 @@ void __init ioremap_fixed_init(void)
}
void __init __iomem *
-ioremap_fixed(resource_size_t phys_addr, unsigned long offset,
- unsigned long size, pgprot_t prot)
+ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
{
enum fixed_addresses idx0, idx;
struct ioremap_map *map;
unsigned int nrpages;
+ unsigned long offset;
int i, slot;
+ /*
+ * Mappings have to be page-aligned
+ */
+ offset = phys_addr & ~PAGE_MASK;
+ phys_addr &= PAGE_MASK;
+ size = PAGE_ALIGN(phys_addr + size) - phys_addr;
+
slot = -1;
for (i = 0; i < FIX_N_IOREMAPS; i++) {
map = &ioremap_maps[i];
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c
index 422e9272187..961b34085e3 100644
--- a/arch/sh/mm/numa.c
+++ b/arch/sh/mm/numa.c
@@ -74,6 +74,9 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
start_pfn = start >> PAGE_SHIFT;
end_pfn = end >> PAGE_SHIFT;
+ pmb_bolt_mapping((unsigned long)__va(start), start, end - start,
+ PAGE_KERNEL);
+
lmb_add(start, end - start);
__add_active_range(nid, start_pfn, end_pfn);
diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c
index 6f21fb1d872..26e03a1f7ca 100644
--- a/arch/sh/mm/pgtable.c
+++ b/arch/sh/mm/pgtable.c
@@ -1,4 +1,5 @@
#include <linux/mm.h>
+#include <linux/slab.h>
#define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 198bcff5e96..e43ec600afc 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -15,7 +15,6 @@
#include <linux/sysdev.h>
#include <linux/cpu.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
@@ -23,7 +22,8 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/spinlock.h>
-#include <linux/rwlock.h>
+#include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
#include <asm/sizes.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -52,12 +52,24 @@ struct pmb_entry {
struct pmb_entry *link;
};
+static struct {
+ unsigned long size;
+ int flag;
+} pmb_sizes[] = {
+ { .size = SZ_512M, .flag = PMB_SZ_512M, },
+ { .size = SZ_128M, .flag = PMB_SZ_128M, },
+ { .size = SZ_64M, .flag = PMB_SZ_64M, },
+ { .size = SZ_16M, .flag = PMB_SZ_16M, },
+};
+
static void pmb_unmap_entry(struct pmb_entry *, int depth);
static DEFINE_RWLOCK(pmb_rwlock);
static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES];
static DECLARE_BITMAP(pmb_map, NR_PMB_ENTRIES);
+static unsigned int pmb_iomapping_enabled;
+
static __always_inline unsigned long mk_pmb_entry(unsigned int entry)
{
return (entry & PMB_E_MASK) << PMB_E_SHIFT;
@@ -73,6 +85,142 @@ static __always_inline unsigned long mk_pmb_data(unsigned int entry)
return mk_pmb_entry(entry) | PMB_DATA;
}
+static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn)
+{
+ return ppn >= __pa(memory_start) && ppn < __pa(memory_end);
+}
+
+/*
+ * Ensure that the PMB entries match our cache configuration.
+ *
+ * When we are in 32-bit address extended mode, CCR.CB becomes
+ * invalid, so care must be taken to manually adjust cacheable
+ * translations.
+ */
+static __always_inline unsigned long pmb_cache_flags(void)
+{
+ unsigned long flags = 0;
+
+#if defined(CONFIG_CACHE_OFF)
+ flags |= PMB_WT | PMB_UB;
+#elif defined(CONFIG_CACHE_WRITETHROUGH)
+ flags |= PMB_C | PMB_WT | PMB_UB;
+#elif defined(CONFIG_CACHE_WRITEBACK)
+ flags |= PMB_C;
+#endif
+
+ return flags;
+}
+
+/*
+ * Convert typical pgprot value to the PMB equivalent
+ */
+static inline unsigned long pgprot_to_pmb_flags(pgprot_t prot)
+{
+ unsigned long pmb_flags = 0;
+ u64 flags = pgprot_val(prot);
+
+ if (flags & _PAGE_CACHABLE)
+ pmb_flags |= PMB_C;
+ if (flags & _PAGE_WT)
+ pmb_flags |= PMB_WT | PMB_UB;
+
+ return pmb_flags;
+}
+
+static inline bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b)
+{
+ return (b->vpn == (a->vpn + a->size)) &&
+ (b->ppn == (a->ppn + a->size)) &&
+ (b->flags == a->flags);
+}
+
+static bool pmb_mapping_exists(unsigned long vaddr, phys_addr_t phys,
+ unsigned long size)
+{
+ int i;
+
+ read_lock(&pmb_rwlock);
+
+ for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
+ struct pmb_entry *pmbe, *iter;
+ unsigned long span;
+
+ if (!test_bit(i, pmb_map))
+ continue;
+
+ pmbe = &pmb_entry_list[i];
+
+ /*
+ * See if VPN and PPN are bounded by an existing mapping.
+ */
+ if ((vaddr < pmbe->vpn) || (vaddr >= (pmbe->vpn + pmbe->size)))
+ continue;
+ if ((phys < pmbe->ppn) || (phys >= (pmbe->ppn + pmbe->size)))
+ continue;
+
+ /*
+ * Now see if we're in range of a simple mapping.
+ */
+ if (size <= pmbe->size) {
+ read_unlock(&pmb_rwlock);
+ return true;
+ }
+
+ span = pmbe->size;
+
+ /*
+ * Finally for sizes that involve compound mappings, walk
+ * the chain.
+ */
+ for (iter = pmbe->link; iter; iter = iter->link)
+ span += iter->size;
+
+ /*
+ * Nothing else to do if the range requirements are met.
+ */
+ if (size <= span) {
+ read_unlock(&pmb_rwlock);
+ return true;
+ }
+ }
+
+ read_unlock(&pmb_rwlock);
+ return false;
+}
+
+static bool pmb_size_valid(unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
+ if (pmb_sizes[i].size == size)
+ return true;
+
+ return false;
+}
+
+static inline bool pmb_addr_valid(unsigned long addr, unsigned long size)
+{
+ return (addr >= P1SEG && (addr + size - 1) < P3SEG);
+}
+
+static inline bool pmb_prot_valid(pgprot_t prot)
+{
+ return (pgprot_val(prot) & _PAGE_USER) == 0;
+}
+
+static int pmb_size_to_flags(unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
+ if (pmb_sizes[i].size == size)
+ return pmb_sizes[i].flag;
+
+ return 0;
+}
+
static int pmb_alloc_entry(void)
{
int pos;
@@ -140,33 +288,22 @@ static void pmb_free(struct pmb_entry *pmbe)
}
/*
- * Ensure that the PMB entries match our cache configuration.
- *
- * When we are in 32-bit address extended mode, CCR.CB becomes
- * invalid, so care must be taken to manually adjust cacheable
- * translations.
+ * Must be run uncached.
*/
-static __always_inline unsigned long pmb_cache_flags(void)
+static void __set_pmb_entry(struct pmb_entry *pmbe)
{
- unsigned long flags = 0;
+ unsigned long addr, data;
-#if defined(CONFIG_CACHE_WRITETHROUGH)
- flags |= PMB_C | PMB_WT | PMB_UB;
-#elif defined(CONFIG_CACHE_WRITEBACK)
- flags |= PMB_C;
-#endif
+ addr = mk_pmb_addr(pmbe->entry);
+ data = mk_pmb_data(pmbe->entry);
- return flags;
-}
+ jump_to_uncached();
-/*
- * Must be run uncached.
- */
-static void __set_pmb_entry(struct pmb_entry *pmbe)
-{
- writel_uncached(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry));
- writel_uncached(pmbe->ppn | pmbe->flags | PMB_V,
- mk_pmb_data(pmbe->entry));
+ /* Set V-bit */
+ __raw_writel(pmbe->vpn | PMB_V, addr);
+ __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, data);
+
+ back_to_cached();
}
static void __clear_pmb_entry(struct pmb_entry *pmbe)
@@ -185,6 +322,7 @@ static void __clear_pmb_entry(struct pmb_entry *pmbe)
writel_uncached(data_val & ~PMB_V, data);
}
+#ifdef CONFIG_PM
static void set_pmb_entry(struct pmb_entry *pmbe)
{
unsigned long flags;
@@ -193,145 +331,157 @@ static void set_pmb_entry(struct pmb_entry *pmbe)
__set_pmb_entry(pmbe);
spin_unlock_irqrestore(&pmbe->lock, flags);
}
+#endif /* CONFIG_PM */
-static struct {
- unsigned long size;
- int flag;
-} pmb_sizes[] = {
- { .size = SZ_512M, .flag = PMB_SZ_512M, },
- { .size = SZ_128M, .flag = PMB_SZ_128M, },
- { .size = SZ_64M, .flag = PMB_SZ_64M, },
- { .size = SZ_16M, .flag = PMB_SZ_16M, },
-};
-
-long pmb_remap(unsigned long vaddr, unsigned long phys,
- unsigned long size, pgprot_t prot)
+int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
+ unsigned long size, pgprot_t prot)
{
struct pmb_entry *pmbp, *pmbe;
- unsigned long wanted;
- int pmb_flags, i;
- long err;
- u64 flags;
-
- flags = pgprot_val(prot);
+ unsigned long orig_addr, orig_size;
+ unsigned long flags, pmb_flags;
+ int i, mapped;
- pmb_flags = PMB_WT | PMB_UB;
+ if (!pmb_addr_valid(vaddr, size))
+ return -EFAULT;
+ if (pmb_mapping_exists(vaddr, phys, size))
+ return 0;
- /* Convert typical pgprot value to the PMB equivalent */
- if (flags & _PAGE_CACHABLE) {
- pmb_flags |= PMB_C;
+ orig_addr = vaddr;
+ orig_size = size;
- if ((flags & _PAGE_WT) == 0)
- pmb_flags &= ~(PMB_WT | PMB_UB);
- }
+ flush_tlb_kernel_range(vaddr, vaddr + size);
+ pmb_flags = pgprot_to_pmb_flags(prot);
pmbp = NULL;
- wanted = size;
-again:
- for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
- unsigned long flags;
+ do {
+ for (i = mapped = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
+ if (size < pmb_sizes[i].size)
+ continue;
+
+ pmbe = pmb_alloc(vaddr, phys, pmb_flags |
+ pmb_sizes[i].flag, PMB_NO_ENTRY);
+ if (IS_ERR(pmbe)) {
+ pmb_unmap_entry(pmbp, mapped);
+ return PTR_ERR(pmbe);
+ }
- if (size < pmb_sizes[i].size)
- continue;
+ spin_lock_irqsave(&pmbe->lock, flags);
- pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag,
- PMB_NO_ENTRY);
- if (IS_ERR(pmbe)) {
- err = PTR_ERR(pmbe);
- goto out;
- }
+ pmbe->size = pmb_sizes[i].size;
- spin_lock_irqsave(&pmbe->lock, flags);
+ __set_pmb_entry(pmbe);
- __set_pmb_entry(pmbe);
+ phys += pmbe->size;
+ vaddr += pmbe->size;
+ size -= pmbe->size;
- phys += pmb_sizes[i].size;
- vaddr += pmb_sizes[i].size;
- size -= pmb_sizes[i].size;
+ /*
+ * Link adjacent entries that span multiple PMB
+ * entries for easier tear-down.
+ */
+ if (likely(pmbp)) {
+ spin_lock(&pmbp->lock);
+ pmbp->link = pmbe;
+ spin_unlock(&pmbp->lock);
+ }
- pmbe->size = pmb_sizes[i].size;
+ pmbp = pmbe;
- /*
- * Link adjacent entries that span multiple PMB entries
- * for easier tear-down.
- */
- if (likely(pmbp)) {
- spin_lock(&pmbp->lock);
- pmbp->link = pmbe;
- spin_unlock(&pmbp->lock);
+ /*
+ * Instead of trying smaller sizes on every
+ * iteration (even if we succeed in allocating
+ * space), try using pmb_sizes[i].size again.
+ */
+ i--;
+ mapped++;
+
+ spin_unlock_irqrestore(&pmbe->lock, flags);
}
+ } while (size >= SZ_16M);
- pmbp = pmbe;
+ flush_cache_vmap(orig_addr, orig_addr + orig_size);
- /*
- * Instead of trying smaller sizes on every iteration
- * (even if we succeed in allocating space), try using
- * pmb_sizes[i].size again.
- */
- i--;
+ return 0;
+}
- spin_unlock_irqrestore(&pmbe->lock, flags);
- }
+void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
+ pgprot_t prot, void *caller)
+{
+ unsigned long vaddr;
+ phys_addr_t offset, last_addr;
+ phys_addr_t align_mask;
+ unsigned long aligned;
+ struct vm_struct *area;
+ int i, ret;
- if (size >= SZ_16M)
- goto again;
+ if (!pmb_iomapping_enabled)
+ return NULL;
- return wanted - size;
+ /*
+ * Small mappings need to go through the TLB.
+ */
+ if (size < SZ_16M)
+ return ERR_PTR(-EINVAL);
+ if (!pmb_prot_valid(prot))
+ return ERR_PTR(-EINVAL);
-out:
- pmb_unmap_entry(pmbp, NR_PMB_ENTRIES);
+ for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
+ if (size >= pmb_sizes[i].size)
+ break;
+
+ last_addr = phys + size;
+ align_mask = ~(pmb_sizes[i].size - 1);
+ offset = phys & ~align_mask;
+ phys &= align_mask;
+ aligned = ALIGN(last_addr, pmb_sizes[i].size) - phys;
+
+ /*
+ * XXX: This should really start from uncached_end, but this
+ * causes the MMU to reset, so for now we restrict it to the
+ * 0xb000...0xc000 range.
+ */
+ area = __get_vm_area_caller(aligned, VM_IOREMAP, 0xb0000000,
+ P3SEG, caller);
+ if (!area)
+ return NULL;
+
+ area->phys_addr = phys;
+ vaddr = (unsigned long)area->addr;
- return err;
+ ret = pmb_bolt_mapping(vaddr, phys, size, prot);
+ if (unlikely(ret != 0))
+ return ERR_PTR(ret);
+
+ return (void __iomem *)(offset + (char *)vaddr);
}
-void pmb_unmap(unsigned long addr)
+int pmb_unmap(void __iomem *addr)
{
struct pmb_entry *pmbe = NULL;
- int i;
+ unsigned long vaddr = (unsigned long __force)addr;
+ int i, found = 0;
read_lock(&pmb_rwlock);
for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
if (test_bit(i, pmb_map)) {
pmbe = &pmb_entry_list[i];
- if (pmbe->vpn == addr)
+ if (pmbe->vpn == vaddr) {
+ found = 1;
break;
+ }
}
}
read_unlock(&pmb_rwlock);
- pmb_unmap_entry(pmbe, NR_PMB_ENTRIES);
-}
-
-static bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b)
-{
- return (b->vpn == (a->vpn + a->size)) &&
- (b->ppn == (a->ppn + a->size)) &&
- (b->flags == a->flags);
-}
-
-static bool pmb_size_valid(unsigned long size)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
- if (pmb_sizes[i].size == size)
- return true;
-
- return false;
-}
-
-static int pmb_size_to_flags(unsigned long size)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
- if (pmb_sizes[i].size == size)
- return pmb_sizes[i].flag;
+ if (found) {
+ pmb_unmap_entry(pmbe, NR_PMB_ENTRIES);
+ return 0;
+ }
- return 0;
+ return -EINVAL;
}
static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
@@ -351,6 +501,8 @@ static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
*/
__clear_pmb_entry(pmbe);
+ flush_cache_vunmap(pmbe->vpn, pmbe->vpn + pmbe->size);
+
pmbe = pmblink->link;
pmb_free(pmblink);
@@ -369,11 +521,6 @@ static void pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
write_unlock_irqrestore(&pmb_rwlock, flags);
}
-static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn)
-{
- return ppn >= __pa(memory_start) && ppn < __pa(memory_end);
-}
-
static void __init pmb_notify(void)
{
int i;
@@ -625,6 +772,18 @@ static void __init pmb_resize(void)
}
#endif
+static int __init early_pmb(char *p)
+{
+ if (!p)
+ return 0;
+
+ if (strstr(p, "iomap"))
+ pmb_iomapping_enabled = 1;
+
+ return 0;
+}
+early_param("pmb", early_pmb);
+
void __init pmb_init(void)
{
/* Synchronize software state */
@@ -644,7 +803,7 @@ void __init pmb_init(void)
writel_uncached(0, PMB_IRMCR);
/* Flush out the TLB */
- __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
+ local_flush_tlb_all();
ctrl_barrier();
}
@@ -713,7 +872,7 @@ static int __init pmb_debugfs_init(void)
return 0;
}
-postcore_initcall(pmb_debugfs_init);
+subsys_initcall(pmb_debugfs_init);
#ifdef CONFIG_PM
static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)
diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c
index 32dc674c550..b71db6af806 100644
--- a/arch/sh/mm/tlb-pteaex.c
+++ b/arch/sh/mm/tlb-pteaex.c
@@ -73,5 +73,35 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
jump_to_uncached();
__raw_writel(page, MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
__raw_writel(asid, MMU_UTLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT);
+ __raw_writel(page, MMU_ITLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
+ __raw_writel(asid, MMU_ITLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT);
back_to_cached();
}
+
+void local_flush_tlb_all(void)
+{
+ unsigned long flags, status;
+ int i;
+
+ /*
+ * Flush all the TLB.
+ */
+ local_irq_save(flags);
+ jump_to_uncached();
+
+ status = __raw_readl(MMUCR);
+ status = ((status & MMUCR_URB) >> MMUCR_URB_SHIFT);
+
+ if (status == 0)
+ status = MMUCR_URB_NENTRIES;
+
+ for (i = 0; i < status; i++)
+ __raw_writel(0x0, MMU_UTLB_ADDRESS_ARRAY | (i << 8));
+
+ for (i = 0; i < 4; i++)
+ __raw_writel(0x0, MMU_ITLB_ADDRESS_ARRAY | (i << 8));
+
+ back_to_cached();
+ ctrl_barrier();
+ local_irq_restore(flags);
+}
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index 4f5f7cbdd50..7a940dbfc2e 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -77,3 +77,22 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
for (i = 0; i < ways; i++)
__raw_writel(data, addr + (i << 8));
}
+
+void local_flush_tlb_all(void)
+{
+ unsigned long flags, status;
+
+ /*
+ * Flush all the TLB.
+ *
+ * Write to the MMU control register's bit:
+ * TF-bit for SH-3, TI-bit for SH-4.
+ * It's same position, bit #2.
+ */
+ local_irq_save(flags);
+ status = __raw_readl(MMUCR);
+ status |= 0x04;
+ __raw_writel(status, MMUCR);
+ ctrl_barrier();
+ local_irq_restore(flags);
+}
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index ccac77f504a..cfdf7930d29 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -80,3 +80,31 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
__raw_writel(data, addr);
back_to_cached();
}
+
+void local_flush_tlb_all(void)
+{
+ unsigned long flags, status;
+ int i;
+
+ /*
+ * Flush all the TLB.
+ */
+ local_irq_save(flags);
+ jump_to_uncached();
+
+ status = __raw_readl(MMUCR);
+ status = ((status & MMUCR_URB) >> MMUCR_URB_SHIFT);
+
+ if (status == 0)
+ status = MMUCR_URB_NENTRIES;
+
+ for (i = 0; i < status; i++)
+ __raw_writel(0x0, MMU_UTLB_ADDRESS_ARRAY | (i << 8));
+
+ for (i = 0; i < 4; i++)
+ __raw_writel(0x0, MMU_ITLB_ADDRESS_ARRAY | (i << 8));
+
+ back_to_cached();
+ ctrl_barrier();
+ local_irq_restore(flags);
+}
diff --git a/arch/sh/mm/tlb-urb.c b/arch/sh/mm/tlb-urb.c
index bb5b9098956..c92ce20db39 100644
--- a/arch/sh/mm/tlb-urb.c
+++ b/arch/sh/mm/tlb-urb.c
@@ -24,13 +24,9 @@ void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
local_irq_save(flags);
- /* Load the entry into the TLB */
- __update_tlb(vma, addr, pte);
-
- /* ... and wire it up. */
status = __raw_readl(MMUCR);
urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;
- status &= ~MMUCR_URB;
+ status &= ~MMUCR_URC;
/*
* Make sure we're not trying to wire the last TLB entry slot.
@@ -39,7 +35,23 @@ void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
urb = urb % MMUCR_URB_NENTRIES;
+ /*
+ * Insert this entry into the highest non-wired TLB slot (via
+ * the URC field).
+ */
+ status |= (urb << MMUCR_URC_SHIFT);
+ __raw_writel(status, MMUCR);
+ ctrl_barrier();
+
+ /* Load the entry into the TLB */
+ __update_tlb(vma, addr, pte);
+
+ /* ... and wire it up. */
+ status = __raw_readl(MMUCR);
+
+ status &= ~MMUCR_URB;
status |= (urb << MMUCR_URB_SHIFT);
+
__raw_writel(status, MMUCR);
ctrl_barrier();
diff --git a/arch/sh/mm/tlbflush_32.c b/arch/sh/mm/tlbflush_32.c
index 004bb3f25b5..3fbe03ce8fe 100644
--- a/arch/sh/mm/tlbflush_32.c
+++ b/arch/sh/mm/tlbflush_32.c
@@ -119,22 +119,3 @@ void local_flush_tlb_mm(struct mm_struct *mm)
local_irq_restore(flags);
}
}
-
-void local_flush_tlb_all(void)
-{
- unsigned long flags, status;
-
- /*
- * Flush all the TLB.
- *
- * Write to the MMU control register's bit:
- * TF-bit for SH-3, TI-bit for SH-4.
- * It's same position, bit #2.
- */
- local_irq_save(flags);
- status = __raw_readl(MMUCR);
- status |= 0x04;
- __raw_writel(status, MMUCR);
- ctrl_barrier();
- local_irq_restore(flags);
-}
diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c
index cf20a5c5136..8a4eca551fc 100644
--- a/arch/sh/mm/uncached.c
+++ b/arch/sh/mm/uncached.c
@@ -1,6 +1,8 @@
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/sizes.h>
#include <asm/page.h>
+#include <asm/addrspace.h>
/*
* This is the offset of the uncached section from its cached alias.
@@ -15,15 +17,22 @@
unsigned long cached_to_uncached = SZ_512M;
unsigned long uncached_size = SZ_512M;
unsigned long uncached_start, uncached_end;
+EXPORT_SYMBOL(uncached_start);
+EXPORT_SYMBOL(uncached_end);
int virt_addr_uncached(unsigned long kaddr)
{
return (kaddr >= uncached_start) && (kaddr < uncached_end);
}
+EXPORT_SYMBOL(virt_addr_uncached);
void __init uncached_init(void)
{
+#ifdef CONFIG_29BIT
+ uncached_start = P2SEG;
+#else
uncached_start = memory_end;
+#endif
uncached_end = uncached_start + uncached_size;
}
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 4097f6a1086..9908d477ccd 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -37,6 +37,9 @@ config SPARC64
def_bool 64BIT
select ARCH_SUPPORTS_MSI
select HAVE_FUNCTION_TRACER
+ select HAVE_FUNCTION_GRAPH_TRACER
+ select HAVE_FUNCTION_GRAPH_FP_TEST
+ select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_KRETPROBES
select HAVE_KPROBES
select HAVE_LMB
@@ -127,6 +130,9 @@ config ZONE_DMA
bool
default y if SPARC32
+config NEED_DMA_MAP_STATE
+ def_bool y
+
config GENERIC_ISA_DMA
bool
default y if SPARC32
diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug
index 9d3c889718a..1b4a831565f 100644
--- a/arch/sparc/Kconfig.debug
+++ b/arch/sparc/Kconfig.debug
@@ -19,13 +19,10 @@ config DEBUG_DCFLUSH
bool "D-cache flush debugging"
depends on SPARC64 && DEBUG_KERNEL
-config STACK_DEBUG
- bool "Stack Overflow Detection Support"
-
config MCOUNT
bool
depends on SPARC64
- depends on STACK_DEBUG || FUNCTION_TRACER
+ depends on FUNCTION_TRACER
default y
config FRAME_POINTER
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig
index 56e3163673e..259e3fd5099 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.33
-# Wed Mar 3 02:54:29 2010
+# Linux kernel version: 2.6.34-rc3
+# Sat Apr 3 15:49:56 2010
#
CONFIG_64BIT=y
CONFIG_SPARC=y
@@ -23,6 +23,7 @@ CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_MMU=y
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_ARCH_NO_VIRT_TO_BUS=y
CONFIG_OF=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -439,6 +440,7 @@ CONFIG_MISC_DEVICES=y
# 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
@@ -511,6 +513,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -888,6 +891,7 @@ CONFIG_SERIAL_SUNHV=y
CONFIG_SERIAL_CORE=y
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_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -935,6 +939,7 @@ CONFIG_I2C_ALGOBIT=y
#
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -948,15 +953,9 @@ CONFIG_I2C_ALGOBIT=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
#
@@ -982,10 +981,11 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -1052,18 +1052,21 @@ CONFIG_SSB_POSSIBLE=y
# 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_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
@@ -1113,6 +1116,7 @@ CONFIG_FB_FFB=y
# CONFIG_FB_LEO is not set
CONFIG_FB_XVR500=y
CONFIG_FB_XVR2500=y
+CONFIG_FB_XVR1000=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
@@ -1430,7 +1434,6 @@ CONFIG_USB_STORAGE=m
# 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
@@ -1443,7 +1446,6 @@ CONFIG_USB_STORAGE=m
# 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
#
@@ -1610,6 +1612,7 @@ CONFIG_MISC_FILESYSTEMS=y
# 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
@@ -1624,6 +1627,7 @@ 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
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index 0e706257918..5016f76ea98 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -5,7 +5,8 @@
*/
#include <linux/types.h>
-#define COMPAT_USER_HZ 100
+#define COMPAT_USER_HZ 100
+#define COMPAT_UTS_MACHINE "sparc\0\0"
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h
index 926397d345f..050ef35b9dc 100644
--- a/arch/sparc/include/asm/cpudata_64.h
+++ b/arch/sparc/include/asm/cpudata_64.h
@@ -17,7 +17,7 @@ typedef struct {
unsigned int __nmi_count;
unsigned long clock_tick; /* %tick's per second */
unsigned long __pad;
- unsigned int __pad1;
+ unsigned int irq0_irqs;
unsigned int __pad2;
/* Dcache line 2, rarely used */
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index 5a8c308e2b5..4b4a0c0b0cc 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -8,7 +8,6 @@
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
extern int dma_supported(struct device *dev, u64 mask);
-extern int dma_set_mask(struct device *dev, u64 dma_mask);
#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)
@@ -62,4 +61,17 @@ static inline int dma_get_cache_alignment(void)
return (1 << INTERNODE_CACHE_SHIFT);
}
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+#ifdef CONFIG_PCI
+ if (dev->bus == &pci_bus_type) {
+ if (!dev->dma_mask || !dma_supported(dev, mask))
+ return -EINVAL;
+ *dev->dma_mask = mask;
+ return 0;
+ }
+#endif
+ return -EINVAL;
+}
+
#endif
diff --git a/arch/sparc/include/asm/fbio.h b/arch/sparc/include/asm/fbio.h
index b9215a0907d..0a21da87f7d 100644
--- a/arch/sparc/include/asm/fbio.h
+++ b/arch/sparc/include/asm/fbio.h
@@ -173,7 +173,7 @@ struct mdi_cfginfo {
int mdi_ncluts; /* Number of implemented CLUTs in this MDI */
int mdi_type; /* FBTYPE name */
int mdi_height; /* height */
- int mdi_width; /* widht */
+ int mdi_width; /* width */
int mdi_size; /* available ram */
int mdi_mode; /* 8bpp, 16bpp or 32bpp */
int mdi_pixfreq; /* pixel clock (from PROM) */
diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h
index 8b49bf920df..bfa1ea45b4c 100644
--- a/arch/sparc/include/asm/irqflags_64.h
+++ b/arch/sparc/include/asm/irqflags_64.h
@@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void)
*/
static inline unsigned long __raw_local_irq_save(void)
{
- unsigned long flags = __raw_local_save_flags();
-
- raw_local_irq_disable();
+ unsigned long flags, tmp;
+
+ /* Disable interrupts to PIL_NORMAL_MAX unless we already
+ * are using PIL_NMI, in which case PIL_NMI is retained.
+ *
+ * The only values we ever program into the %pil are 0,
+ * PIL_NORMAL_MAX and PIL_NMI.
+ *
+ * Since PIL_NMI is the largest %pil value and all bits are
+ * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX
+ * actually is.
+ */
+ __asm__ __volatile__(
+ "rdpr %%pil, %0\n\t"
+ "or %0, %2, %1\n\t"
+ "wrpr %1, 0x0, %%pil"
+ : "=r" (flags), "=r" (tmp)
+ : "i" (PIL_NORMAL_MAX)
+ : "memory"
+ );
return flags;
}
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index e769f668a4b..332ac9ab36b 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -32,20 +32,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
struct pci_dev;
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
#ifdef CONFIG_PCI
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
enum pci_dma_burst_strategy *strat,
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index b0576df6ec8..5312782f0b5 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -32,20 +32,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
*/
#define PCI_DMA_BUS_IS_PHYS (0)
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
/* PCI IOMMU mapping bypass support. */
/* PCI 64-bit addressing works for all slots on all controller
diff --git a/arch/sparc/include/asm/stat.h b/arch/sparc/include/asm/stat.h
index 39327d6a57e..a232e9e1f4e 100644
--- a/arch/sparc/include/asm/stat.h
+++ b/arch/sparc/include/asm/stat.h
@@ -53,8 +53,8 @@ struct stat {
ino_t st_ino;
mode_t st_mode;
short st_nlink;
- uid16_t st_uid;
- gid16_t st_gid;
+ unsigned short st_uid;
+ unsigned short st_gid;
unsigned short st_rdev;
off_t st_size;
time_t st_atime;
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 9e2d9447f2a..4827a3aeac7 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -111,7 +111,7 @@ struct thread_info {
#define THREAD_SHIFT PAGE_SHIFT
#endif /* PAGE_SHIFT == 13 */
-#define PREEMPT_ACTIVE 0x4000000
+#define PREEMPT_ACTIVE 0x10000000
/*
* macros/functions for gaining access to the thread information structure
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index cb4b9bfd0d8..d0b3b01ac9d 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -432,7 +432,9 @@
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#ifndef __32bit_syscall_numbers__
+#ifdef __32bit_syscall_numbers__
+#define __ARCH_WANT_SYS_IPC
+#else
#define __ARCH_WANT_COMPAT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#endif
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index c6316142db4..0c2dc1f24a9 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -13,6 +13,14 @@ extra-y += init_task.o
CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
extra-y += vmlinux.lds
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o := -pg
+CFLAGS_REMOVE_time_$(BITS).o := -pg
+CFLAGS_REMOVE_perf_event.o := -pg
+CFLAGS_REMOVE_pcr.o := -pg
+endif
+
obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o
obj-$(CONFIG_SPARC32) += etrap_32.o
obj-$(CONFIG_SPARC32) += rtrap_32.o
@@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB) += kgdb_$(BITS).o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-CFLAGS_REMOVE_ftrace.o := -pg
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_EARLYFB) += btext.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c
index 4589ca33220..415c86d5a8d 100644
--- a/arch/sparc/kernel/central.c
+++ b/arch/sparc/kernel/central.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/of_device.h>
diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c
index 7430ed080b2..8de64c8126b 100644
--- a/arch/sparc/kernel/cpumap.c
+++ b/arch/sparc/kernel/cpumap.c
@@ -4,6 +4,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cpumask.h>
diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c
index 9103a56b39e..03ab022e51c 100644
--- a/arch/sparc/kernel/ftrace.c
+++ b/arch/sparc/kernel/ftrace.c
@@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000;
static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
{
- static u32 call;
+ u32 call;
s32 off;
off = ((s32)addr - (s32)ip);
@@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data)
return 0;
}
#endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+ unsigned long ip = (unsigned long)(&ftrace_graph_call);
+ u32 old, new;
+
+ old = *(u32 *) &ftrace_graph_call;
+ new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller);
+ return ftrace_modify_code(ip, old, new);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+ unsigned long ip = (unsigned long)(&ftrace_graph_call);
+ u32 old, new;
+
+ old = *(u32 *) &ftrace_graph_call;
+ new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub);
+
+ return ftrace_modify_code(ip, old, new);
+}
+
+#endif /* !CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+unsigned long prepare_ftrace_return(unsigned long parent,
+ unsigned long self_addr,
+ unsigned long frame_pointer)
+{
+ unsigned long return_hooker = (unsigned long) &return_to_handler;
+ struct ftrace_graph_ent trace;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return parent + 8UL;
+
+ if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
+ frame_pointer) == -EBUSY)
+ return parent + 8UL;
+
+ trace.func = self_addr;
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ current->curr_ret_stack--;
+ return parent + 8UL;
+ }
+
+ return return_hooker;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/sparc/kernel/helpers.S b/arch/sparc/kernel/helpers.S
index 314dd0c9fc5..92090cc9e82 100644
--- a/arch/sparc/kernel/helpers.S
+++ b/arch/sparc/kernel/helpers.S
@@ -46,6 +46,81 @@ stack_trace_flush:
nop
.size stack_trace_flush,.-stack_trace_flush
+#ifdef CONFIG_PERF_EVENTS
+ .globl perf_arch_fetch_caller_regs
+ .type perf_arch_fetch_caller_regs,#function
+perf_arch_fetch_caller_regs:
+ /* We always read the %pstate into %o5 since we will use
+ * that to construct a fake %tstate to store into the regs.
+ */
+ rdpr %pstate, %o5
+ brz,pn %o2, 50f
+ mov %o2, %g7
+
+ /* Turn off interrupts while we walk around the register
+ * window by hand.
+ */
+ wrpr %o5, PSTATE_IE, %pstate
+
+ /* The %canrestore tells us how many register windows are
+ * still live in the chip above us, past that we have to
+ * walk the frame as saved on the stack. We stash away
+ * the %cwp in %g1 so we can return back to the original
+ * register window.
+ */
+ rdpr %cwp, %g1
+ rdpr %canrestore, %g2
+ sub %g1, 1, %g3
+
+ /* We have the skip count in %g7, if it hits zero then
+ * %fp/%i7 are the registers we need. Otherwise if our
+ * %canrestore count maintained in %g2 hits zero we have
+ * to start traversing the stack.
+ */
+10: brz,pn %g2, 4f
+ sub %g2, 1, %g2
+ wrpr %g3, %cwp
+ subcc %g7, 1, %g7
+ bne,pt %xcc, 10b
+ sub %g3, 1, %g3
+
+ /* We found the values we need in the cpu's register
+ * windows.
+ */
+ mov %fp, %g3
+ ba,pt %xcc, 3f
+ mov %i7, %g2
+
+50: mov %fp, %g3
+ ba,pt %xcc, 2f
+ mov %i7, %g2
+
+ /* We hit the end of the valid register windows in the
+ * cpu, start traversing the stack frame.
+ */
+4: mov %fp, %g3
+
+20: ldx [%g3 + STACK_BIAS + RW_V9_I7], %g2
+ subcc %g7, 1, %g7
+ bne,pn %xcc, 20b
+ ldx [%g3 + STACK_BIAS + RW_V9_I6], %g3
+
+ /* Restore the current register window position and
+ * re-enable interrupts.
+ */
+3: wrpr %g1, %cwp
+ wrpr %o5, %pstate
+
+2: stx %g3, [%o0 + PT_V9_FP]
+ sllx %o5, 8, %o5
+ stx %o5, [%o0 + PT_V9_TSTATE]
+ stx %g2, [%o0 + PT_V9_TPC]
+ add %g2, 4, %g2
+ retl
+ stx %g2, [%o0 + PT_V9_TNPC]
+ .size perf_arch_fetch_caller_regs,.-perf_arch_fetch_caller_regs
+#endif /* CONFIG_PERF_EVENTS */
+
#ifdef CONFIG_SMP
.globl hard_smp_processor_id
.type hard_smp_processor_id,#function
diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c
index 1d272c3b574..7c60afb835b 100644
--- a/arch/sparc/kernel/hvapi.c
+++ b/arch/sparc/kernel/hvapi.c
@@ -5,7 +5,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <asm/hypervisor.h>
#include <asm/oplib.h>
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 5fad94950e7..47977a77f6c 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -6,6 +6,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
@@ -862,13 +863,3 @@ int dma_supported(struct device *dev, u64 device_mask)
return 0;
}
EXPORT_SYMBOL(dma_supported);
-
-int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-#ifdef CONFIG_PCI
- if (dev->bus == &pci_bus_type)
- return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
- return -EINVAL;
-}
-EXPORT_SYMBOL(dma_set_mask);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 3c8c44f6a41..84e5386714c 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -676,17 +676,6 @@ int dma_supported(struct device *dev, u64 mask)
}
EXPORT_SYMBOL(dma_supported);
-int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-#ifdef CONFIG_PCI
- if (dev->bus == &pci_bus_type)
- return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
- return -EOPNOTSUPP;
-}
-EXPORT_SYMBOL(dma_set_mask);
-
-
#ifdef CONFIG_PROC_FS
static int sparc_io_proc_show(struct seq_file *m, void *v)
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index e1cbdb94d97..830d70a3e20 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -20,7 +20,9 @@
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/ftrace.h>
#include <linux/irq.h>
+#include <linux/kmemleak.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
@@ -45,6 +47,7 @@
#include "entry.h"
#include "cpumap.h"
+#include "kstack.h"
#define NUM_IVECS (IMAP_INR + 1)
@@ -647,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
if (unlikely(!bucket))
return 0;
+
+ /* The only reference we store to the IRQ bucket is
+ * by physical address which kmemleak can't see, tell
+ * it that this object explicitly is not a leak and
+ * should be scanned.
+ */
+ kmemleak_not_leak(bucket);
+
__flush_dcache_range((unsigned long) bucket,
((unsigned long) bucket +
sizeof(struct ino_bucket)));
@@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq)
void *hardirq_stack[NR_CPUS];
void *softirq_stack[NR_CPUS];
-static __attribute__((always_inline)) void *set_hardirq_stack(void)
-{
- void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
-
- __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
- if (orig_sp < sp ||
- orig_sp > (sp + THREAD_SIZE)) {
- sp += THREAD_SIZE - 192 - STACK_BIAS;
- __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
- }
-
- return orig_sp;
-}
-static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
-{
- __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
-}
-
-void handler_irq(int irq, struct pt_regs *regs)
+void __irq_entry handler_irq(int irq, struct pt_regs *regs)
{
unsigned long pstate, bucket_pa;
struct pt_regs *old_regs;
diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c
index f5a0fd490b5..0a2bd0f99fc 100644
--- a/arch/sparc/kernel/kgdb_64.c
+++ b/arch/sparc/kernel/kgdb_64.c
@@ -5,6 +5,7 @@
#include <linux/kgdb.h>
#include <linux/kdebug.h>
+#include <linux/ftrace.h>
#include <asm/kdebug.h>
#include <asm/ptrace.h>
@@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
}
#ifdef CONFIG_SMP
-void smp_kgdb_capture_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs)
{
unsigned long flags;
diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c
index 6716584e48a..a39d1ba5a11 100644
--- a/arch/sparc/kernel/kprobes.c
+++ b/arch/sparc/kernel/kprobes.c
@@ -7,6 +7,7 @@
#include <linux/kprobes.h>
#include <linux/module.h>
#include <linux/kdebug.h>
+#include <linux/slab.h>
#include <asm/signal.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc/kernel/kstack.h b/arch/sparc/kernel/kstack.h
index 5247283d1c0..53dfb92e09f 100644
--- a/arch/sparc/kernel/kstack.h
+++ b/arch/sparc/kernel/kstack.h
@@ -61,4 +61,23 @@ check_magic:
}
+static inline __attribute__((always_inline)) void *set_hardirq_stack(void)
+{
+ void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
+
+ __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
+ if (orig_sp < sp ||
+ orig_sp > (sp + THREAD_SIZE)) {
+ sp += THREAD_SIZE - 192 - STACK_BIAS;
+ __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
+ }
+
+ return orig_sp;
+}
+
+static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
+{
+ __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
+}
+
#endif /* _KSTACK_H */
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c
index 00d034ea216..3ae36f36e75 100644
--- a/arch/sparc/kernel/led.c
+++ b/arch/sparc/kernel/led.c
@@ -3,6 +3,7 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 0409d62d8ca..6a7b4dbc8e0 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -7,7 +7,6 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/mutex.h>
-#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/interrupt.h>
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 85787577f68..e1656fc41cc 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -22,6 +22,7 @@
#include <linux/profile.h>
#include <linux/pm.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index 0ee642f6323..f848aadf54d 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -9,9 +9,9 @@
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/string.h>
#include <linux/ctype.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <asm/processor.h>
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index b287b62c7ea..a4bd7ba74c8 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -23,6 +23,8 @@
#include <asm/ptrace.h>
#include <asm/pcr.h>
+#include "kstack.h"
+
/* We don't have a real NMI on sparc64, but we can fake one
* up using profiling counter overflow interrupts and interrupt
* levels.
@@ -92,7 +94,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
{
unsigned int sum, touched = 0;
- int cpu = smp_processor_id();
+ void *orig_sp;
clear_softint(1 << irq);
@@ -100,13 +102,15 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
nmi_enter();
+ orig_sp = set_hardirq_stack();
+
if (notify_die(DIE_NMI, "nmi", regs, 0,
pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
touched = 1;
else
pcr_ops->write(PCR_PIC_PRIV);
- sum = kstat_irqs_cpu(0, cpu);
+ sum = local_cpu_data().irq0_irqs;
if (__get_cpu_var(nmi_touch)) {
__get_cpu_var(nmi_touch) = 0;
touched = 1;
@@ -125,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
pcr_ops->write(pcr_enable);
}
+ restore_hardirq_stack(orig_sp);
+
nmi_exit();
}
diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c
index cb8eb799bb6..0247e68210b 100644
--- a/arch/sparc/kernel/of_device_common.c
+++ b/arch/sparc/kernel/of_device_common.c
@@ -4,7 +4,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/irq.h>
#include <linux/of_device.h>
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index b775658a927..8a000583b5c 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -371,14 +371,19 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm)
struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
if (!rp) {
- prom_printf("Cannot allocate IOMMU resource.\n");
- prom_halt();
+ pr_info("%s: Cannot allocate IOMMU resource.\n",
+ pbm->name);
+ return;
}
rp->name = "IOMMU";
rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
rp->flags = IORESOURCE_BUSY;
- request_resource(&pbm->mem_space, rp);
+ if (request_resource(&pbm->mem_space, rp)) {
+ pr_info("%s: Unable to request IOMMU resource.\n",
+ pbm->name);
+ kfree(rp);
+ }
}
}
diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c
index e1b0541feb1..e0ef847219c 100644
--- a/arch/sparc/kernel/pci_msi.c
+++ b/arch/sparc/kernel/pci_msi.c
@@ -4,6 +4,7 @@
*/
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/irq.h>
#include "pci_impl.h"
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c
index 2d94e7a03af..c4a6a50b484 100644
--- a/arch/sparc/kernel/pcr.c
+++ b/arch/sparc/kernel/pcr.c
@@ -8,6 +8,7 @@
#include <linux/irq.h>
#include <linux/perf_event.h>
+#include <linux/ftrace.h>
#include <asm/pil.h>
#include <asm/pcr.h>
@@ -34,7 +35,7 @@ unsigned int picl_shift;
* Therefore in such situations we defer the work by signalling
* a lower level cpu IRQ.
*/
-void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
+void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs)
{
struct pt_regs *old_regs;
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 9f2b2bac8b2..e2771939341 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1189,7 +1189,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
regs = args->regs;
- data.addr = 0;
+ perf_sample_data_init(&data, 0);
cpuc = &__get_cpu_var(cpu_hw_events);
@@ -1337,7 +1337,7 @@ static void perf_callchain_user_32(struct pt_regs *regs,
callchain_store(entry, PERF_CONTEXT_USER);
callchain_store(entry, regs->tpc);
- ufp = regs->u_regs[UREG_I6];
+ ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
do {
struct sparc_stackf32 *usf, sf;
unsigned long pc;
@@ -1353,7 +1353,7 @@ static void perf_callchain_user_32(struct pt_regs *regs,
}
/* Like powerpc we can't get PMU interrupts within the PMU handler,
- * so no need for seperate NMI and IRQ chains as on x86.
+ * so no need for separate NMI and IRQ chains as on x86.
*/
static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index c49865b3071..40e29fc8a4d 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -17,13 +17,13 @@
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/smp.h>
#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/auxio.h>
#include <asm/oplib.h>
diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c
index 7e3dfd9bb97..e608f397e11 100644
--- a/arch/sparc/kernel/ptrace_32.c
+++ b/arch/sparc/kernel/ptrace_32.c
@@ -65,6 +65,7 @@ static int genregs32_get(struct task_struct *target,
*k++ = regs->u_regs[pos++];
reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+ reg_window -= 16;
for (; count > 0 && pos < 32; count--) {
if (get_user(*k++, &reg_window[pos++]))
return -EFAULT;
@@ -76,6 +77,7 @@ static int genregs32_get(struct task_struct *target,
}
reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+ reg_window -= 16;
for (; count > 0 && pos < 32; count--) {
if (get_user(reg, &reg_window[pos++]) ||
put_user(reg, u++))
@@ -141,6 +143,7 @@ static int genregs32_set(struct task_struct *target,
regs->u_regs[pos++] = *k++;
reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+ reg_window -= 16;
for (; count > 0 && pos < 32; count--) {
if (put_user(*k++, &reg_window[pos++]))
return -EFAULT;
@@ -153,6 +156,7 @@ static int genregs32_set(struct task_struct *target,
}
reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+ reg_window -= 16;
for (; count > 0 && pos < 32; count--) {
if (get_user(reg, u++) ||
put_user(reg, &reg_window[pos++]))
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index 2f6524d1a81..aa90da08bf6 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -492,6 +492,7 @@ static int genregs32_get(struct task_struct *target,
*k++ = regs->u_regs[pos++];
reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+ reg_window -= 16;
if (target == current) {
for (; count > 0 && pos < 32; count--) {
if (get_user(*k++, &reg_window[pos++]))
@@ -516,6 +517,7 @@ static int genregs32_get(struct task_struct *target,
}
reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+ reg_window -= 16;
if (target == current) {
for (; count > 0 && pos < 32; count--) {
if (get_user(reg, &reg_window[pos++]) ||
@@ -599,6 +601,7 @@ static int genregs32_set(struct task_struct *target,
regs->u_regs[pos++] = *k++;
reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+ reg_window -= 16;
if (target == current) {
for (; count > 0 && pos < 32; count--) {
if (put_user(*k++, &reg_window[pos++]))
@@ -625,6 +628,7 @@ static int genregs32_set(struct task_struct *target,
}
reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+ reg_window -= 16;
if (target == current) {
for (; count > 0 && pos < 32; count--) {
if (get_user(reg, u++) ||
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
index 83f1873c6c1..090b9e9ad5e 100644
--- a/arch/sparc/kernel/rtrap_64.S
+++ b/arch/sparc/kernel/rtrap_64.S
@@ -130,7 +130,17 @@ rtrap_xcall:
nop
call trace_hardirqs_on
nop
- wrpr %l4, %pil
+ /* Do not actually set the %pil here. We will do that
+ * below after we clear PSTATE_IE in the %pstate register.
+ * If we re-enable interrupts here, we can recurse down
+ * the hardirq stack potentially endlessly, causing a
+ * stack overflow.
+ *
+ * It is tempting to put this test and trace_hardirqs_on
+ * call at the 'rt_continue' label, but that will not work
+ * as that path hits unconditionally and we do not want to
+ * execute this in NMI return paths, for example.
+ */
#endif
rtrap_no_irq_enable:
andcc %l1, TSTATE_PRIV, %l3
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index a2a79e76344..5f72de67588 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -12,7 +12,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <asm/smp.h>
#include <linux/user.h>
#include <linux/screen_info.h>
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index eb14844a002..b6a2b8f4704 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -22,7 +22,9 @@
#include <linux/profile.h>
#include <linux/bootmem.h>
#include <linux/vmalloc.h>
+#include <linux/ftrace.h>
#include <linux/cpu.h>
+#include <linux/slab.h>
#include <asm/head.h>
#include <asm/ptrace.h>
@@ -822,13 +824,13 @@ void arch_send_call_function_single_ipi(int cpu)
&cpumask_of_cpu(cpu));
}
-void smp_call_function_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
{
clear_softint(1 << irq);
generic_smp_call_function_interrupt();
}
-void smp_call_function_single_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
{
clear_softint(1 << irq);
generic_smp_call_function_single_interrupt();
@@ -964,7 +966,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
put_cpu();
}
-void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
{
struct mm_struct *mm;
unsigned long flags;
@@ -1148,7 +1150,7 @@ void smp_release(void)
*/
extern void prom_world(int);
-void smp_penguin_jailcell(int irq, struct pt_regs *regs)
+void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs)
{
clear_softint(1 << irq);
@@ -1364,7 +1366,7 @@ void smp_send_reschedule(int cpu)
&cpumask_of_cpu(cpu));
}
-void smp_receive_signal_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
{
clear_softint(1 << irq);
}
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c
index bc3adbf79c6..892fb884910 100644
--- a/arch/sparc/kernel/sun4c_irq.c
+++ b/arch/sparc/kernel/sun4c_irq.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_device.h>
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index 301892e2d71..7f3b97ff62c 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -17,7 +17,6 @@
#include <linux/ptrace.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/of.h>
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index daded3b9639..c0ca87553e1 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -21,7 +21,6 @@
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
-#include <linux/slab.h>
#include <linux/uio.h>
#include <linux/nfs_fs.h>
#include <linux/quota.h>
@@ -44,6 +43,7 @@
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/ptrace.h>
+#include <linux/slab.h>
#include <asm/types.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 3a82e65d8db..ee995b7dae7 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -98,119 +98,6 @@ out:
return error;
}
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-
-asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth)
-{
- int version, err;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
- goto out;
- case SEMTIMEDOP:
- err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, (const struct timespec __user *) fifth);
- goto out;
- case SEMGET:
- err = sys_semget (first, second, third);
- goto out;
- case SEMCTL: {
- union semun fourth;
- err = -EINVAL;
- if (!ptr)
- goto out;
- err = -EFAULT;
- if (get_user(fourth.__pad,
- (void __user * __user *)ptr))
- goto out;
- err = sys_semctl (first, second, third, fourth);
- goto out;
- }
- default:
- err = -ENOSYS;
- goto out;
- }
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- err = sys_msgsnd (first, (struct msgbuf __user *) ptr,
- second, third);
- goto out;
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- err = -EINVAL;
- if (!ptr)
- goto out;
- err = -EFAULT;
- if (copy_from_user(&tmp, (struct ipc_kludge __user *) ptr, sizeof (tmp)))
- goto out;
- err = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
- goto out;
- }
- case 1: default:
- err = sys_msgrcv (first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- goto out;
- }
- case MSGGET:
- err = sys_msgget ((key_t) first, second);
- goto out;
- case MSGCTL:
- err = sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
- goto out;
- default:
- err = -ENOSYS;
- goto out;
- }
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- case 0: default: {
- ulong raddr;
- err = do_shmat (first, (char __user *) ptr, second, &raddr);
- if (err)
- goto out;
- err = -EFAULT;
- if (put_user (raddr, (ulong __user *) third))
- goto out;
- err = 0;
- goto out;
- }
- case 1: /* iBCS2 emulator entry point */
- err = -EINVAL;
- goto out;
- }
- case SHMDT:
- err = sys_shmdt ((char __user *)ptr);
- goto out;
- case SHMGET:
- err = sys_shmget (first, second, third);
- goto out;
- case SHMCTL:
- err = sys_shmctl (first, second, (struct shmid_ds __user *) ptr);
- goto out;
- default:
- err = -ENOSYS;
- goto out;
- }
- else
- err = -ENOSYS;
-out:
- return err;
-}
-
int sparc_mmap_check(unsigned long addr, unsigned long len)
{
if (ARCH_SUN4C &&
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index cb1bef6f14b..3d435c42e6d 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -426,7 +426,7 @@ out:
* This is really horribly ugly.
*/
-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
+SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second,
unsigned long, third, void __user *, ptr, long, fifth)
{
long err;
@@ -510,17 +510,6 @@ out:
return err;
}
-SYSCALL_DEFINE1(sparc64_newuname, struct new_utsname __user *, name)
-{
- int ret = sys_newuname(name);
-
- if (current->personality == PER_LINUX32 && !ret) {
- ret = (copy_to_user(name->machine, "sparc\0\0", 8)
- ? -EFAULT : 0);
- }
- return ret;
-}
-
SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality)
{
int ret;
diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c
index ca39c606fe8..1eb8b00aed7 100644
--- a/arch/sparc/kernel/sysfs.c
+++ b/arch/sparc/kernel/sysfs.c
@@ -107,12 +107,12 @@ static unsigned long run_on_cpu(unsigned long cpu,
unsigned long ret;
/* should return -EINVAL to userspace */
- if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
+ if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
return 0;
ret = func(arg);
- set_cpus_allowed(current, old_affinity);
+ set_cpus_allowed_ptr(current, &old_affinity);
return ret;
}
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h
index 68312fe8da7..118759cd734 100644
--- a/arch/sparc/kernel/systbls.h
+++ b/arch/sparc/kernel/systbls.h
@@ -6,15 +6,12 @@
#include <asm/utrap.h>
#include <asm/signal.h>
-struct new_utsname;
-
extern asmlinkage unsigned long sys_getpagesize(void);
extern asmlinkage long sparc_pipe(struct pt_regs *regs);
-extern asmlinkage long sys_ipc(unsigned int call, int first,
+extern asmlinkage long sys_sparc_ipc(unsigned int call, int first,
unsigned long second,
unsigned long third,
void __user *ptr, long fifth);
-extern asmlinkage long sparc64_newuname(struct new_utsname __user *name);
extern asmlinkage long sparc64_personality(unsigned long personality);
extern asmlinkage long sys64_munmap(unsigned long addr, size_t len);
extern asmlinkage unsigned long sys64_mremap(unsigned long addr,
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 17614251fb6..9db058dd039 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -55,7 +55,7 @@ sys_call_table32:
/*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents
.word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall
- .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_sparc64_newuname
+ .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_newuname
/*190*/ .word sys32_init_module, sys_sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl
.word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask
/*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir
@@ -130,13 +130,13 @@ sys_call_table:
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
- .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_sparc64_newuname
+ .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
/*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
.word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
.word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
/*210*/ .word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo
- .word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
+ .word sys_sparc_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
/*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
.word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
/*230*/ .word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 67e16510288..c7bbe6cf7b8 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -35,6 +35,7 @@
#include <linux/clocksource.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/ftrace.h>
#include <asm/oplib.h>
#include <asm/timer.h>
@@ -717,7 +718,7 @@ static struct clock_event_device sparc64_clockevent = {
};
static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
-void timer_interrupt(int irq, struct pt_regs *regs)
+void __irq_entry timer_interrupt(int irq, struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
unsigned long tick_mask = tick_ops->softint_mask;
@@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs)
irq_enter();
+ local_cpu_data().irq0_irqs++;
kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
if (unlikely(!evt->event_handler)) {
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index bdc05a21908..9da57f03298 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -17,6 +17,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/kdebug.h>
+#include <linux/gfp.h>
#include <asm/smp.h>
#include <asm/delay.h>
@@ -2202,27 +2203,6 @@ void dump_stack(void)
EXPORT_SYMBOL(dump_stack);
-static inline int is_kernel_stack(struct task_struct *task,
- struct reg_window *rw)
-{
- unsigned long rw_addr = (unsigned long) rw;
- unsigned long thread_base, thread_end;
-
- if (rw_addr < PAGE_OFFSET) {
- if (task != &init_task)
- return 0;
- }
-
- thread_base = (unsigned long) task_stack_page(task);
- thread_end = thread_base + sizeof(union thread_union);
- if (rw_addr >= thread_base &&
- rw_addr < thread_end &&
- !(rw_addr & 0x7UL))
- return 1;
-
- return 0;
-}
-
static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
{
unsigned long fp = rw->ins[6];
@@ -2251,6 +2231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
show_regs(regs);
add_taint(TAINT_DIE);
if (regs->tstate & TSTATE_PRIV) {
+ struct thread_info *tp = current_thread_info();
struct reg_window *rw = (struct reg_window *)
(regs->u_regs[UREG_FP] + STACK_BIAS);
@@ -2258,8 +2239,8 @@ void die_if_kernel(char *str, struct pt_regs *regs)
* find some badly aligned kernel stack.
*/
while (rw &&
- count++ < 30&&
- is_kernel_stack(current, rw)) {
+ count++ < 30 &&
+ kstack_valid(tp, (unsigned long) rw)) {
printk("Caller[%016lx]: %pS\n", rw->ins[7],
(void *) rw->ins[7]);
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index ebce43018c4..c752c4c479b 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -50,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn)
}
/* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */
-static inline int decode_access_size(unsigned int insn)
+static inline int decode_access_size(struct pt_regs *regs, unsigned int insn)
{
unsigned int tmp;
@@ -66,7 +66,7 @@ static inline int decode_access_size(unsigned int insn)
return 2;
else {
printk("Impossible unaligned trap. insn=%08x\n", insn);
- die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs);
+ die_if_kernel("Byte sized unaligned access?!?!", regs);
/* GCC should never warn that control reaches the end
* of this function without returning a value because
@@ -286,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs)
asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
{
enum direction dir = decode_direction(insn);
- int size = decode_access_size(insn);
+ int size = decode_access_size(regs, insn);
int orig_asi, asi;
current_thread_info()->kern_una_regs = regs;
diff --git a/arch/sparc/kernel/us2e_cpufreq.c b/arch/sparc/kernel/us2e_cpufreq.c
index 791c15138f3..8f982b76c71 100644
--- a/arch/sparc/kernel/us2e_cpufreq.c
+++ b/arch/sparc/kernel/us2e_cpufreq.c
@@ -238,12 +238,12 @@ static unsigned int us2e_freq_get(unsigned int cpu)
return 0;
cpus_allowed = current->cpus_allowed;
- set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ set_cpus_allowed_ptr(current, cpumask_of(cpu));
clock_tick = sparc64_get_clock_tick(cpu) / 1000;
estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
- set_cpus_allowed(current, cpus_allowed);
+ set_cpus_allowed_ptr(current, &cpus_allowed);
return clock_tick / estar_to_divisor(estar);
}
@@ -259,7 +259,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
return;
cpus_allowed = current->cpus_allowed;
- set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ set_cpus_allowed_ptr(current, cpumask_of(cpu));
new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
new_bits = index_to_estar_mode(index);
@@ -281,7 +281,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- set_cpus_allowed(current, cpus_allowed);
+ set_cpus_allowed_ptr(current, &cpus_allowed);
}
static int us2e_freq_target(struct cpufreq_policy *policy,
diff --git a/arch/sparc/kernel/us3_cpufreq.c b/arch/sparc/kernel/us3_cpufreq.c
index 365b6464e2c..f35d1e79454 100644
--- a/arch/sparc/kernel/us3_cpufreq.c
+++ b/arch/sparc/kernel/us3_cpufreq.c
@@ -86,12 +86,12 @@ static unsigned int us3_freq_get(unsigned int cpu)
return 0;
cpus_allowed = current->cpus_allowed;
- set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ set_cpus_allowed_ptr(current, cpumask_of(cpu));
reg = read_safari_cfg();
ret = get_current_freq(cpu, reg);
- set_cpus_allowed(current, cpus_allowed);
+ set_cpus_allowed_ptr(current, &cpus_allowed);
return ret;
}
@@ -106,7 +106,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
return;
cpus_allowed = current->cpus_allowed;
- set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ set_cpus_allowed_ptr(current, cpumask_of(cpu));
new_freq = sparc64_get_clock_tick(cpu) / 1000;
switch (index) {
@@ -140,7 +140,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- set_cpus_allowed(current, cpus_allowed);
+ set_cpus_allowed_ptr(current, &cpus_allowed);
}
static int us3_freq_target(struct cpufreq_policy *policy,
diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c
index c28c71449a6..3cb1def9806 100644
--- a/arch/sparc/kernel/vio.c
+++ b/arch/sparc/kernel/vio.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/init.h>
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 4e599259396..0c1e6783657 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -46,11 +46,16 @@ SECTIONS
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
+ IRQENTRY_TEXT
*(.gnu.warning)
} = 0
_etext = .;
RO_DATA(PAGE_SIZE)
+
+ /* Start of data section */
+ _sdata = .;
+
.data1 : {
*(.data1)
}
diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S
index 24b8b12deed..3ad6cbdc216 100644
--- a/arch/sparc/lib/mcount.S
+++ b/arch/sparc/lib/mcount.S
@@ -7,26 +7,11 @@
#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm/thread_info.h>
-
/*
* This is the main variant and is called by C code. GCC's -pg option
* automatically instruments every C function with a call to this.
*/
-#ifdef CONFIG_STACK_DEBUG
-
-#define OVSTACKSIZE 4096 /* lets hope this is enough */
-
- .data
- .align 8
-panicstring:
- .asciz "Stack overflow\n"
- .align 8
-ovstack:
- .skip OVSTACKSIZE
-#endif
.text
.align 32
.globl _mcount
@@ -35,84 +20,48 @@ ovstack:
.type mcount,#function
_mcount:
mcount:
-#ifdef CONFIG_STACK_DEBUG
- /*
- * Check whether %sp is dangerously low.
- */
- ldub [%g6 + TI_FPDEPTH], %g1
- srl %g1, 1, %g3
- add %g3, 1, %g3
- sllx %g3, 8, %g3 ! each fpregs frame is 256b
- add %g3, 192, %g3
- add %g6, %g3, %g3 ! where does task_struct+frame end?
- sub %g3, STACK_BIAS, %g3
- cmp %sp, %g3
- bg,pt %xcc, 1f
- nop
- lduh [%g6 + TI_CPU], %g1
- sethi %hi(hardirq_stack), %g3
- or %g3, %lo(hardirq_stack), %g3
- sllx %g1, 3, %g1
- ldx [%g3 + %g1], %g7
- sub %g7, STACK_BIAS, %g7
- cmp %sp, %g7
- bleu,pt %xcc, 2f
- sethi %hi(THREAD_SIZE), %g3
- add %g7, %g3, %g7
- cmp %sp, %g7
- blu,pn %xcc, 1f
-2: sethi %hi(softirq_stack), %g3
- or %g3, %lo(softirq_stack), %g3
- ldx [%g3 + %g1], %g7
- sub %g7, STACK_BIAS, %g7
- cmp %sp, %g7
- bleu,pt %xcc, 3f
- sethi %hi(THREAD_SIZE), %g3
- add %g7, %g3, %g7
- cmp %sp, %g7
- blu,pn %xcc, 1f
- nop
- /* If we are already on ovstack, don't hop onto it
- * again, we are already trying to output the stack overflow
- * message.
- */
-3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough
- or %g7, %lo(ovstack), %g7
- add %g7, OVSTACKSIZE, %g3
- sub %g3, STACK_BIAS + 192, %g3
- sub %g7, STACK_BIAS, %g7
- cmp %sp, %g7
- blu,pn %xcc, 2f
- cmp %sp, %g3
- bleu,pn %xcc, 1f
- nop
-2: mov %g3, %sp
- sethi %hi(panicstring), %g3
- call prom_printf
- or %g3, %lo(panicstring), %o0
- call prom_halt
- nop
-1:
-#endif
#ifdef CONFIG_FUNCTION_TRACER
#ifdef CONFIG_DYNAMIC_FTRACE
- mov %o7, %o0
- .globl mcount_call
-mcount_call:
- call ftrace_stub
- mov %o0, %o7
+ /* Do nothing, the retl/nop below is all we need. */
#else
- sethi %hi(ftrace_trace_function), %g1
+ sethi %hi(function_trace_stop), %g1
+ lduw [%g1 + %lo(function_trace_stop)], %g2
+ brnz,pn %g2, 2f
+ sethi %hi(ftrace_trace_function), %g1
sethi %hi(ftrace_stub), %g2
ldx [%g1 + %lo(ftrace_trace_function)], %g1
or %g2, %lo(ftrace_stub), %g2
cmp %g1, %g2
be,pn %icc, 1f
- mov %i7, %o1
- jmpl %g1, %g0
- mov %o7, %o0
+ mov %i7, %g3
+ save %sp, -176, %sp
+ mov %g3, %o1
+ jmpl %g1, %o7
+ mov %i7, %o0
+ ret
+ restore
/* not reached */
1:
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ sethi %hi(ftrace_graph_return), %g1
+ ldx [%g1 + %lo(ftrace_graph_return)], %g3
+ cmp %g2, %g3
+ bne,pn %xcc, 5f
+ sethi %hi(ftrace_graph_entry_stub), %g2
+ sethi %hi(ftrace_graph_entry), %g1
+ or %g2, %lo(ftrace_graph_entry_stub), %g2
+ ldx [%g1 + %lo(ftrace_graph_entry)], %g1
+ cmp %g1, %g2
+ be,pt %xcc, 2f
+ nop
+5: mov %i7, %g2
+ mov %fp, %g3
+ save %sp, -176, %sp
+ mov %g2, %l0
+ ba,pt %xcc, ftrace_graph_caller
+ mov %g3, %l1
+#endif
+2:
#endif
#endif
retl
@@ -131,14 +80,50 @@ ftrace_stub:
.globl ftrace_caller
.type ftrace_caller,#function
ftrace_caller:
- mov %i7, %o1
- mov %o7, %o0
+ sethi %hi(function_trace_stop), %g1
+ mov %i7, %g2
+ lduw [%g1 + %lo(function_trace_stop)], %g1
+ brnz,pn %g1, ftrace_stub
+ mov %fp, %g3
+ save %sp, -176, %sp
+ mov %g2, %o1
+ mov %g2, %l0
+ mov %g3, %l1
.globl ftrace_call
ftrace_call:
call ftrace_stub
- mov %o0, %o7
- retl
+ mov %i7, %o0
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ .globl ftrace_graph_call
+ftrace_graph_call:
+ call ftrace_stub
nop
+#endif
+ ret
+ restore
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ .size ftrace_graph_call,.-ftrace_graph_call
+#endif
+ .size ftrace_call,.-ftrace_call
.size ftrace_caller,.-ftrace_caller
#endif
#endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+ mov %l0, %o0
+ mov %i7, %o1
+ call prepare_ftrace_return
+ mov %l1, %o2
+ ret
+ restore %o0, -8, %i7
+END(ftrace_graph_caller)
+
+ENTRY(return_to_handler)
+ save %sp, -176, %sp
+ call ftrace_return_to_handler
+ mov %fp, %o0
+ jmpl %o0 + 8, %g0
+ restore
+END(return_to_handler)
+#endif
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index f27d10369e0..5fdddf134ca 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -10,7 +10,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/slab.h>
#include <linux/sysctl.h>
#include <asm/mman.h>
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index dc7c3b17a15..6d0e02c4fe0 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -24,6 +24,7 @@
#include <linux/bootmem.h>
#include <linux/pagemap.h>
#include <linux/poison.h>
+#include <linux/gfp.h>
#include <asm/sections.h>
#include <asm/system.h>
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 9245a822a2f..b2831dc3c12 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -13,7 +13,6 @@
#include <linux/bootmem.h>
#include <linux/mm.h>
#include <linux/hugetlb.h>
-#include <linux/slab.h>
#include <linux/initrd.h>
#include <linux/swap.h>
#include <linux/pagemap.h>
@@ -26,6 +25,7 @@
#include <linux/percpu.h>
#include <linux/lmb.h>
#include <linux/mmzone.h>
+#include <linux/gfp.h>
#include <asm/head.h>
#include <asm/system.h>
@@ -2117,7 +2117,7 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
"node=%d entry=%lu/%lu\n", start, block, nr,
node,
addr >> VMEMMAP_CHUNK_SHIFT,
- VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT);
+ VMEMMAP_SIZE);
}
}
return 0;
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index df49b200ca4..f5f75a58e0b 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/init.h>
@@ -20,6 +19,7 @@
#include <linux/seq_file.h>
#include <linux/kdebug.h>
#include <linux/log2.h>
+#include <linux/gfp.h>
#include <asm/bitext.h>
#include <asm/page.h>
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 18652534b91..cf38846753d 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/fs.h>
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
index 36a0813f951..101d7c82870 100644
--- a/arch/sparc/mm/tsb.c
+++ b/arch/sparc/mm/tsb.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/preempt.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
diff --git a/arch/um/.gitignore b/arch/um/.gitignore
new file mode 100644
index 00000000000..a73d3a1cc74
--- /dev/null
+++ b/arch/um/.gitignore
@@ -0,0 +1,3 @@
+kernel/config.c
+kernel/config.tmp
+kernel/vmlinux.lds
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index cf8a97f3451..7a656bd8bd3 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -6,6 +6,7 @@
#include "linux/irqreturn.h"
#include "linux/kd.h"
#include "linux/sched.h"
+#include "linux/slab.h"
#include "chan_kern.h"
#include "irq_kern.h"
#include "irq_user.h"
@@ -18,10 +19,10 @@ static irqreturn_t line_interrupt(int irq, void *data)
{
struct chan *chan = data;
struct line *line = chan->line;
- struct tty_struct *tty = line->tty;
+ struct tty_struct *tty;
if (line)
- chan_interrupt(&line->chan_list, &line->task, tty, irq);
+ chan_interrupt(&line->chan_list, &line->task, line->tty, irq);
return IRQ_HANDLED;
}
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index a74245ae3a8..f0537269423 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include "init.h"
#include "irq_kern.h"
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 4ebc8a34738..a11573be096 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -7,6 +7,7 @@
#include "linux/interrupt.h"
#include "linux/list.h"
#include "linux/mutex.h"
+#include "linux/slab.h"
#include "linux/workqueue.h"
#include "asm/atomic.h"
#include "init.h"
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index c1ff6903b62..da992a3ad6b 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -31,6 +31,7 @@
#include "linux/ctype.h"
#include "linux/capability.h"
#include "linux/mm.h"
+#include "linux/slab.h"
#include "linux/vmalloc.h"
#include "linux/blkpg.h"
#include "linux/genhd.h"
diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h
index 378de4bbf49..b948c14a786 100644
--- a/arch/um/include/asm/dma-mapping.h
+++ b/arch/um/include/asm/dma-mapping.h
@@ -104,14 +104,6 @@ dma_get_cache_alignment(void)
}
static inline void
-dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- BUG();
-}
-
-static inline void
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index 6c8899013c9..2cd899f75a3 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -16,6 +16,8 @@ struct pt_regs {
struct uml_pt_regs regs;
};
+#define arch_has_single_step() (1)
+
#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index fda30d21fb9..97974c1bdd1 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -8,6 +8,7 @@
#include "linux/smp_lock.h"
#include "linux/ptrace.h"
#include "linux/sched.h"
+#include "linux/slab.h"
#include "asm/current.h"
#include "asm/processor.h"
#include "asm/uaccess.h"
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 89474ba0741..a3f0b04d710 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -12,6 +12,7 @@
#include "linux/module.h"
#include "linux/sched.h"
#include "linux/seq_file.h"
+#include "linux/slab.h"
#include "as-layout.h"
#include "kern_util.h"
#include "os.h"
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index a5d5e70cf6f..8137ccc9635 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -5,10 +5,10 @@
#include <linux/stddef.h>
#include <linux/bootmem.h>
-#include <linux/gfp.h>
#include <linux/highmem.h>
#include <linux/mm.h>
#include <linux/swap.h>
+#include <linux/slab.h>
#include <asm/fixmap.h>
#include <asm/page.h>
#include "as-layout.h"
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 2f910a1b745..fab4371184f 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -7,13 +7,13 @@
#include <linux/stddef.h>
#include <linux/err.h>
#include <linux/hardirq.h>
-#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/personality.h>
#include <linux/proc_fs.h>
#include <linux/ptrace.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/tick.h>
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 8e3d69e4fcb..484509948ee 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -12,16 +12,25 @@
#endif
#include "skas_ptrace.h"
-static inline void set_singlestepping(struct task_struct *child, int on)
+
+
+void user_enable_single_step(struct task_struct *child)
{
- if (on)
- child->ptrace |= PT_DTRACE;
- else
- child->ptrace &= ~PT_DTRACE;
+ child->ptrace |= PT_DTRACE;
child->thread.singlestep_syscall = 0;
#ifdef SUBARCH_SET_SINGLESTEPPING
- SUBARCH_SET_SINGLESTEPPING(child, on);
+ SUBARCH_SET_SINGLESTEPPING(child, 1);
+#endif
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+ child->ptrace &= ~PT_DTRACE;
+ child->thread.singlestep_syscall = 0;
+
+#ifdef SUBARCH_SET_SINGLESTEPPING
+ SUBARCH_SET_SINGLESTEPPING(child, 0);
#endif
}
@@ -30,7 +39,7 @@ static inline void set_singlestepping(struct task_struct *child, int on)
*/
void ptrace_disable(struct task_struct *child)
{
- set_singlestepping(child,0);
+ user_disable_single_step(child);
}
extern int peek_user(struct task_struct * child, long addr, long data);
@@ -69,53 +78,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = -EIO;
break;
- /* continue and stop at next (return from) syscall */
- case PTRACE_SYSCALL:
- /* restart after signal. */
- case PTRACE_CONT: {
- ret = -EIO;
- if (!valid_signal(data))
- break;
-
- set_singlestepping(child, 0);
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
- break;
- }
-
-/*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL: {
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
-
- set_singlestepping(child, 0);
- child->exit_code = SIGKILL;
- wake_up_process(child);
- break;
- }
-
- case PTRACE_SINGLESTEP: { /* set the trap flag. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- set_singlestepping(child, 1);
- child->exit_code = data;
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- break;
- }
-
#ifdef PTRACE_GETREGS
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 00197d3d21e..869bec9f251 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -4,6 +4,7 @@
*/
#include "linux/sched.h"
+#include "linux/slab.h"
#include "kern_util.h"
#include "os.h"
#include "skas.h"
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 8bfd1e90581..3d099f97478 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -5,6 +5,7 @@
#include "linux/mm.h"
#include "linux/sched.h"
+#include "linux/slab.h"
#include "asm/pgalloc.h"
#include "asm/pgtable.h"
#include "as-layout.h"
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index cccab850c27..4393173923f 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -51,51 +51,6 @@ long old_mmap(unsigned long addr, unsigned long len,
return err;
}
-long sys_uname(struct old_utsname __user * name)
-{
- long err;
- if (!name)
- return -EFAULT;
- down_read(&uts_sem);
- err = copy_to_user(name, utsname(), sizeof (*name));
- up_read(&uts_sem);
- return err?-EFAULT:0;
-}
-
-long sys_olduname(struct oldold_utsname __user * name)
-{
- long error;
-
- if (!name)
- return -EFAULT;
- if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
-
- error = __copy_to_user(&name->sysname, &utsname()->sysname,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename, &utsname()->nodename,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->release, &utsname()->release,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->release + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->version, &utsname()->version,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->version + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine, &utsname()->machine,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->machine + __OLD_UTS_LEN);
-
- up_read(&uts_sem);
-
- error = error ? -EFAULT : 0;
-
- return error;
-}
-
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
mm_segment_t fs;
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 1b549bca464..804b28dd032 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -6,6 +6,8 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
sys_call_table.o tls.o
+obj-$(CONFIG_BINFMT_ELF) += elfcore.o
+
subarch-obj-y = lib/semaphore_32.o lib/string_32.o
subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
subarch-obj-$(CONFIG_MODULES) += kernel/module.o
diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h
index 770885472ed..e64cd41d7ba 100644
--- a/arch/um/sys-i386/asm/elf.h
+++ b/arch/um/sys-i386/asm/elf.h
@@ -116,47 +116,4 @@ do { \
} \
} while (0)
-/*
- * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
- * extra segments containing the vsyscall DSO contents. Dumping its
- * contents makes post-mortem fully interpretable later without matching up
- * the same kernel and hardware config to see what PC values meant.
- * Dumping its extra ELF program headers includes all the other information
- * a debugger needs to easily find how the vsyscall DSO was being used.
- */
-#define ELF_CORE_EXTRA_PHDRS \
- (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
-
-#define ELF_CORE_WRITE_EXTRA_PHDRS \
-if ( vsyscall_ehdr ) { \
- const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
- const struct elf_phdr *const phdrp = \
- (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
- int i; \
- Elf32_Off ofs = 0; \
- for (i = 0; i < ehdrp->e_phnum; ++i) { \
- struct elf_phdr phdr = phdrp[i]; \
- if (phdr.p_type == PT_LOAD) { \
- ofs = phdr.p_offset = offset; \
- offset += phdr.p_filesz; \
- } \
- else \
- phdr.p_offset += ofs; \
- phdr.p_paddr = 0; /* match other core phdrs */ \
- DUMP_WRITE(&phdr, sizeof(phdr)); \
- } \
-}
-#define ELF_CORE_WRITE_EXTRA_DATA \
-if ( vsyscall_ehdr ) { \
- const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
- const struct elf_phdr *const phdrp = \
- (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
- int i; \
- for (i = 0; i < ehdrp->e_phnum; ++i) { \
- if (phdrp[i].p_type == PT_LOAD) \
- DUMP_WRITE((void *) phdrp[i].p_vaddr, \
- phdrp[i].p_filesz); \
- } \
-}
-
#endif
diff --git a/arch/um/sys-i386/elfcore.c b/arch/um/sys-i386/elfcore.c
new file mode 100644
index 00000000000..6bb49b687c9
--- /dev/null
+++ b/arch/um/sys-i386/elfcore.c
@@ -0,0 +1,83 @@
+#include <linux/elf.h>
+#include <linux/coredump.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf32_Half elf_core_extra_phdrs(void)
+{
+ return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0;
+}
+
+int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+ unsigned long limit)
+{
+ if ( vsyscall_ehdr ) {
+ const struct elfhdr *const ehdrp =
+ (struct elfhdr *) vsyscall_ehdr;
+ const struct elf_phdr *const phdrp =
+ (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
+ int i;
+ Elf32_Off ofs = 0;
+
+ for (i = 0; i < ehdrp->e_phnum; ++i) {
+ struct elf_phdr phdr = phdrp[i];
+
+ if (phdr.p_type == PT_LOAD) {
+ ofs = phdr.p_offset = offset;
+ offset += phdr.p_filesz;
+ } else {
+ phdr.p_offset += ofs;
+ }
+ phdr.p_paddr = 0; /* match other core phdrs */
+ *size += sizeof(phdr);
+ if (*size > limit
+ || !dump_write(file, &phdr, sizeof(phdr)))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int elf_core_write_extra_data(struct file *file, size_t *size,
+ unsigned long limit)
+{
+ if ( vsyscall_ehdr ) {
+ const struct elfhdr *const ehdrp =
+ (struct elfhdr *) vsyscall_ehdr;
+ const struct elf_phdr *const phdrp =
+ (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
+ int i;
+
+ for (i = 0; i < ehdrp->e_phnum; ++i) {
+ if (phdrp[i].p_type == PT_LOAD) {
+ void *addr = (void *) phdrp[i].p_vaddr;
+ size_t filesz = phdrp[i].p_filesz;
+
+ *size += filesz;
+ if (*size > limit
+ || !dump_write(file, addr, filesz))
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+size_t elf_core_extra_data_size(void)
+{
+ if ( vsyscall_ehdr ) {
+ const struct elfhdr *const ehdrp =
+ (struct elfhdr *)vsyscall_ehdr;
+ const struct elf_phdr *const phdrp =
+ (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
+ int i;
+
+ for (i = 0; i < ehdrp->e_phnum; ++i)
+ if (phdrp[i].p_type == PT_LOAD)
+ return (size_t) phdrp[i].p_filesz;
+ }
+ return 0;
+}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index a4846a84a7b..3f2bf208d88 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -5,6 +5,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/unistd.h>
#include "os.h"
#include "proc_mm.h"
diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h
index e7787679e31..05cb796aecb 100644
--- a/arch/um/sys-i386/shared/sysdep/syscalls.h
+++ b/arch/um/sys-i386/shared/sysdep/syscalls.h
@@ -13,8 +13,6 @@ typedef long syscall_handler_t(struct pt_regs);
*/
extern syscall_handler_t sys_rt_sigaction;
-extern syscall_handler_t old_mmap_i386;
-
extern syscall_handler_t *sys_call_table[];
#define EXECUTE_SYSCALL(syscall, regs) \
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
index c6260dd6ebb..de274071455 100644
--- a/arch/um/sys-i386/sys_call_table.S
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -7,7 +7,7 @@
#define sys_vm86old sys_ni_syscall
#define sys_vm86 sys_ni_syscall
-#define old_mmap old_mmap_i386
+#define old_mmap sys_old_mmap
#define ptregs_fork sys_fork
#define ptregs_execve sys_execve
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
index 857ca0b3bde..70ca357393b 100644
--- a/arch/um/sys-i386/syscalls.c
+++ b/arch/um/sys-i386/syscalls.c
@@ -12,57 +12,6 @@
#include "asm/unistd.h"
/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/i386 didn't use to be able to handle more than
- * 4 system call parameters, so these system calls used a memory
- * block for parameter passing..
- */
-
-struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
-};
-
-extern int old_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long offset);
-
-long old_mmap_i386(struct mmap_arg_struct __user *arg)
-{
- struct mmap_arg_struct a;
- int err = -EFAULT;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
-
- err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
- out:
- return err;
-}
-
-struct sel_arg_struct {
- unsigned long n;
- fd_set __user *inp;
- fd_set __user *outp;
- fd_set __user *exp;
- struct timeval __user *tvp;
-};
-
-long old_select(struct sel_arg_struct __user *arg)
-{
- struct sel_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
- /* sys_select() does the appropriate kernel locking */
- return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
* The prototype on i386 is:
*
* int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
@@ -85,92 +34,6 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
return ret;
}
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-long sys_ipc (uint call, int first, int second,
- int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first, (struct sembuf __user *) ptr,
- second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *) ptr,
- second,
- (const struct timespec __user *) fifth);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void __user * __user *) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- panic("msgrcv with version != 0");
- return sys_msgrcv (first,
- (struct msgbuf *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second, (struct msqid_ds *) ptr);
-
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat (first, (char *) ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return do_shmat (first, (char *) ptr, second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds *) ptr);
- default:
- return -ENOSYS;
- }
-}
-
long sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact)
{
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c
index dd21d69715e..47d469e7e7c 100644
--- a/arch/um/sys-x86_64/syscall_table.c
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -26,11 +26,6 @@
/* On UML we call it this way ("old" means it's not mmap2) */
#define sys_mmap old_mmap
-/*
- * On x86-64 sys_uname is actually sys_newuname plus a compatibility trick.
- * See arch/x86_64/kernel/sys_x86_64.c
- */
-#define sys_uname sys_uname64
#define stub_clone sys_clone
#define stub_fork sys_fork
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index f1199fd34d3..f3d82bb6e15 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -12,20 +12,6 @@
#include "asm/uaccess.h"
#include "os.h"
-asmlinkage long sys_uname64(struct new_utsname __user * name)
-{
- int err;
-
- down_read(&uts_sem);
- err = copy_to_user(name, utsname(), sizeof (*name));
- up_read(&uts_sem);
-
- if (personality(current->personality) == PER_LINUX32)
- err |= copy_to_user(&name->machine, "i686", 5);
-
- return err ? -EFAULT : 0;
-}
-
long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
{
unsigned long *ptr = addr, tmp;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 57ccdcec146..9458685902b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -31,6 +31,7 @@ config X86
select ARCH_WANT_FRAME_POINTERS
select HAVE_DMA_ATTRS
select HAVE_KRETPROBES
+ select HAVE_OPTPROBES
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACER
@@ -101,6 +102,9 @@ config ZONE_DMA
config SBUS
bool
+config NEED_DMA_MAP_STATE
+ def_bool (X86_64 || DMAR || DMA_API_DEBUG)
+
config GENERIC_ISA_DMA
def_bool y
@@ -392,8 +396,12 @@ config X86_ELAN
config X86_MRST
bool "Moorestown MID platform"
+ depends on PCI
+ depends on PCI_GOANY
depends on X86_32
depends on X86_EXTENDED_PLATFORM
+ depends on X86_IO_APIC
+ select APB_TIMER
---help---
Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
Internet Device(MID) platform. Moorestown consists of two chips:
@@ -428,6 +436,7 @@ config X86_32_NON_STANDARD
config X86_NUMAQ
bool "NUMAQ (IBM/Sequent)"
depends on X86_32_NON_STANDARD
+ depends on PCI
select NUMA
select X86_MPPARSE
---help---
@@ -628,6 +637,16 @@ config HPET_EMULATE_RTC
def_bool y
depends on HPET_TIMER && (RTC=y || RTC=m || RTC_DRV_CMOS=m || RTC_DRV_CMOS=y)
+config APB_TIMER
+ def_bool y if MRST
+ prompt "Langwell APB Timer Support" if X86_MRST
+ help
+ APB timer is the replacement for 8254, HPET on X86 MID platforms.
+ The APBT provides a stable time base on SMP
+ systems, unlike the TSC, but it is more expensive to access,
+ as it is off-chip. APB timers are always running regardless of CPU
+ C states, they are used as per CPU clockevent device when possible.
+
# Mark as embedded because too many people got it wrong.
# The code disables itself when not needed.
config DMI
@@ -643,7 +662,7 @@ config GART_IOMMU
bool "GART IOMMU support" if EMBEDDED
default y
select SWIOTLB
- depends on X86_64 && PCI
+ depends on X86_64 && PCI && K8_NB
---help---
Support for full DMA access of devices with 32bit memory access only
on systems with more than 3GB. This is usually needed for USB,
@@ -1197,8 +1216,8 @@ config NUMA_EMU
config NODES_SHIFT
int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP
- range 1 9
- default "9" if MAXSMP
+ range 1 10
+ default "10" if MAXSMP
default "6" if X86_64
default "4" if X86_NUMAQ
default "3"
@@ -2042,7 +2061,7 @@ endif # X86_32
config K8_NB
def_bool y
- depends on AGP_AMD64 || (X86_64 && (GART_IOMMU || (PCI && NUMA)))
+ depends on CPU_SUP_AMD && PCI
source "drivers/pcmcia/Kconfig"
diff --git a/arch/x86/crypto/fpu.c b/arch/x86/crypto/fpu.c
index daef6cd2b45..1a8f8649c03 100644
--- a/arch/x86/crypto/fpu.c
+++ b/arch/x86/crypto/fpu.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/i387.h>
struct crypto_fpu_ctx {
diff --git a/arch/x86/crypto/twofish-i586-asm_32.S b/arch/x86/crypto/twofish-i586-asm_32.S
index 39b98ed2c1b..575331cb2a8 100644
--- a/arch/x86/crypto/twofish-i586-asm_32.S
+++ b/arch/x86/crypto/twofish-i586-asm_32.S
@@ -22,7 +22,7 @@
#include <asm/asm-offsets.h>
-/* return adress at 0 */
+/* return address at 0 */
#define in_blk 12 /* input byte array address parameter*/
#define out_blk 8 /* output byte array address parameter*/
@@ -230,8 +230,8 @@ twofish_enc_blk:
push %edi
mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
- add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
- mov in_blk+16(%esp),%edi /* input adress in edi */
+ add $crypto_tfm_ctx_offset, %ebp /* ctx address */
+ mov in_blk+16(%esp),%edi /* input address in edi */
mov (%edi), %eax
mov b_offset(%edi), %ebx
@@ -286,8 +286,8 @@ twofish_dec_blk:
mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
- add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
- mov in_blk+16(%esp),%edi /* input adress in edi */
+ add $crypto_tfm_ctx_offset, %ebp /* ctx address */
+ mov in_blk+16(%esp),%edi /* input address in edi */
mov (%edi), %eax
mov b_offset(%edi), %ebx
diff --git a/arch/x86/crypto/twofish-x86_64-asm_64.S b/arch/x86/crypto/twofish-x86_64-asm_64.S
index 35974a58661..573aa102542 100644
--- a/arch/x86/crypto/twofish-x86_64-asm_64.S
+++ b/arch/x86/crypto/twofish-x86_64-asm_64.S
@@ -221,11 +221,11 @@
twofish_enc_blk:
pushq R1
- /* %rdi contains the crypto tfm adress */
- /* %rsi contains the output adress */
- /* %rdx contains the input adress */
- add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */
- /* ctx adress is moved to free one non-rex register
+ /* %rdi contains the crypto tfm address */
+ /* %rsi contains the output address */
+ /* %rdx contains the input address */
+ add $crypto_tfm_ctx_offset, %rdi /* set ctx address */
+ /* ctx address is moved to free one non-rex register
as target for the 8bit high operations */
mov %rdi, %r11
@@ -274,11 +274,11 @@ twofish_enc_blk:
twofish_dec_blk:
pushq R1
- /* %rdi contains the crypto tfm adress */
- /* %rsi contains the output adress */
- /* %rdx contains the input adress */
- add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */
- /* ctx adress is moved to free one non-rex register
+ /* %rdi contains the crypto tfm address */
+ /* %rsi contains the output address */
+ /* %rdx contains the input address */
+ add $crypto_tfm_ctx_offset, %rdi /* set ctx address */
+ /* ctx address is moved to free one non-rex register
as target for the 8bit high operations */
mov %rdi, %r11
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
index 280c019cfad..0350311906a 100644
--- a/arch/x86/ia32/ia32_aout.c
+++ b/arch/x86/ia32/ia32_aout.c
@@ -21,7 +21,6 @@
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/user.h>
-#include <linux/slab.h>
#include <linux/binfmts.h>
#include <linux/personality.h>
#include <linux/init.h>
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 53147ad85b9..e790bc1fbfa 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -563,7 +563,7 @@ ia32_sys_call_table:
.quad quiet_ni_syscall /* old mpx syscall holder */
.quad sys_setpgid
.quad quiet_ni_syscall /* old ulimit syscall holder */
- .quad sys32_olduname
+ .quad sys_olduname
.quad sys_umask /* 60 */
.quad sys_chroot
.quad compat_sys_ustat
@@ -586,7 +586,7 @@ ia32_sys_call_table:
.quad compat_sys_settimeofday
.quad sys_getgroups16 /* 80 */
.quad sys_setgroups16
- .quad sys32_old_select
+ .quad compat_sys_old_select
.quad sys_symlink
.quad sys_lstat
.quad sys_readlink /* 85 */
@@ -613,7 +613,7 @@ ia32_sys_call_table:
.quad compat_sys_newstat
.quad compat_sys_newlstat
.quad compat_sys_newfstat
- .quad sys32_uname
+ .quad sys_uname
.quad stub32_iopl /* 110 */
.quad sys_vhangup
.quad quiet_ni_syscall /* old "idle" system call */
@@ -626,7 +626,7 @@ ia32_sys_call_table:
.quad stub32_sigreturn
.quad stub32_clone /* 120 */
.quad sys_setdomainname
- .quad sys_uname
+ .quad sys_newuname
.quad sys_modify_ldt
.quad compat_sys_adjtimex
.quad sys32_mprotect /* 125 */
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index 422572c7792..626be156d88 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -40,6 +40,7 @@
#include <linux/ptrace.h>
#include <linux/highuid.h>
#include <linux/sysctl.h>
+#include <linux/slab.h>
#include <asm/mman.h>
#include <asm/types.h>
#include <asm/uaccess.h>
@@ -143,7 +144,7 @@ asmlinkage long sys32_fstatat(unsigned int dfd, char __user *filename,
* block for parameter passing..
*/
-struct mmap_arg_struct {
+struct mmap_arg_struct32 {
unsigned int addr;
unsigned int len;
unsigned int prot;
@@ -152,9 +153,9 @@ struct mmap_arg_struct {
unsigned int offset;
};
-asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg)
+asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *arg)
{
- struct mmap_arg_struct a;
+ struct mmap_arg_struct32 a;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
@@ -332,24 +333,6 @@ asmlinkage long sys32_alarm(unsigned int seconds)
return alarm_setitimer(seconds);
}
-struct sel_arg_struct {
- unsigned int n;
- unsigned int inp;
- unsigned int outp;
- unsigned int exp;
- unsigned int tvp;
-};
-
-asmlinkage long sys32_old_select(struct sel_arg_struct __user *arg)
-{
- struct sel_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
- return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
- compat_ptr(a.exp), compat_ptr(a.tvp));
-}
-
asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr,
int options)
{
@@ -466,58 +449,6 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd,
return ret;
}
-asmlinkage long sys32_olduname(struct oldold_utsname __user *name)
-{
- char *arch = "x86_64";
- int err;
-
- if (!name)
- return -EFAULT;
- if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
-
- err = __copy_to_user(&name->sysname, &utsname()->sysname,
- __OLD_UTS_LEN);
- err |= __put_user(0, name->sysname+__OLD_UTS_LEN);
- err |= __copy_to_user(&name->nodename, &utsname()->nodename,
- __OLD_UTS_LEN);
- err |= __put_user(0, name->nodename+__OLD_UTS_LEN);
- err |= __copy_to_user(&name->release, &utsname()->release,
- __OLD_UTS_LEN);
- err |= __put_user(0, name->release+__OLD_UTS_LEN);
- err |= __copy_to_user(&name->version, &utsname()->version,
- __OLD_UTS_LEN);
- err |= __put_user(0, name->version+__OLD_UTS_LEN);
-
- if (personality(current->personality) == PER_LINUX32)
- arch = "i686";
-
- err |= __copy_to_user(&name->machine, arch, strlen(arch) + 1);
-
- up_read(&uts_sem);
-
- err = err ? -EFAULT : 0;
-
- return err;
-}
-
-long sys32_uname(struct old_utsname __user *name)
-{
- int err;
-
- if (!name)
- return -EFAULT;
- down_read(&uts_sem);
- err = copy_to_user(name, utsname(), sizeof(*name));
- up_read(&uts_sem);
- if (personality(current->personality) == PER_LINUX32)
- err |= copy_to_user(&name->machine, "i686", 5);
-
- return err ? -EFAULT : 0;
-}
-
asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs *regs)
{
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index 9f828f87ca3..493092efaa3 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -11,6 +11,7 @@ header-y += sigcontext32.h
header-y += ucontext.h
header-y += processor-flags.h
header-y += hw_breakpoint.h
+header-y += hyperv.h
unifdef-y += e820.h
unifdef-y += ist.h
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index f1e253ceba4..b09ec55650b 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -165,10 +165,12 @@ static inline void apply_paravirt(struct paravirt_patch_site *start,
* invalid instruction possible) or if the instructions are changed from a
* consistent state to another consistent state atomically.
* More care must be taken when modifying code in the SMP case because of
- * Intel's errata.
+ * Intel's errata. text_poke_smp() takes care that errata, but still
+ * doesn't support NMI/MCE handler code modifying.
* On the local CPU you need to be protected again NMI or MCE handlers seeing an
* inconsistent instruction while you patch.
*/
extern void *text_poke(void *addr, const void *opcode, size_t len);
+extern void *text_poke_smp(void *addr, const void *opcode, size_t len);
#endif /* _ASM_X86_ALTERNATIVE_H */
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h
index ba19ad4c47d..86a0ff0aeac 100644
--- a/arch/x86/include/asm/amd_iommu_types.h
+++ b/arch/x86/include/asm/amd_iommu_types.h
@@ -21,6 +21,7 @@
#define _ASM_X86_AMD_IOMMU_TYPES_H
#include <linux/types.h>
+#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/spinlock.h>
@@ -140,6 +141,7 @@
/* constants to configure the command buffer */
#define CMD_BUFFER_SIZE 8192
+#define CMD_BUFFER_UNINITIALIZED 1
#define CMD_BUFFER_ENTRIES 512
#define MMIO_CMD_SIZE_SHIFT 56
#define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT)
@@ -237,6 +239,7 @@ struct protection_domain {
struct list_head list; /* for list of all protection domains */
struct list_head dev_list; /* List of all devices in this domain */
spinlock_t lock; /* mostly used to lock the page table*/
+ struct mutex api_lock; /* protect page tables in the iommu-api path */
u16 id; /* the domain id written to the device table */
int mode; /* paging mode (0-6 levels) */
u64 *pt_root; /* page table root pointer */
diff --git a/arch/x86/include/asm/apb_timer.h b/arch/x86/include/asm/apb_timer.h
new file mode 100644
index 00000000000..c74a2eebe57
--- /dev/null
+++ b/arch/x86/include/asm/apb_timer.h
@@ -0,0 +1,70 @@
+/*
+ * apb_timer.h: Driver for Langwell APB timer based on Synopsis DesignWare
+ *
+ * (C) Copyright 2009 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.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.
+ *
+ * Note:
+ */
+
+#ifndef ASM_X86_APBT_H
+#define ASM_X86_APBT_H
+#include <linux/sfi.h>
+
+#ifdef CONFIG_APB_TIMER
+
+/* Langwell DW APB timer registers */
+#define APBTMR_N_LOAD_COUNT 0x00
+#define APBTMR_N_CURRENT_VALUE 0x04
+#define APBTMR_N_CONTROL 0x08
+#define APBTMR_N_EOI 0x0c
+#define APBTMR_N_INT_STATUS 0x10
+
+#define APBTMRS_INT_STATUS 0xa0
+#define APBTMRS_EOI 0xa4
+#define APBTMRS_RAW_INT_STATUS 0xa8
+#define APBTMRS_COMP_VERSION 0xac
+#define APBTMRS_REG_SIZE 0x14
+
+/* register bits */
+#define APBTMR_CONTROL_ENABLE (1<<0)
+#define APBTMR_CONTROL_MODE_PERIODIC (1<<1) /*1: periodic 0:free running */
+#define APBTMR_CONTROL_INT (1<<2)
+
+/* default memory mapped register base */
+#define LNW_SCU_ADDR 0xFF100000
+#define LNW_EXT_TIMER_OFFSET 0x1B800
+#define APBT_DEFAULT_BASE (LNW_SCU_ADDR+LNW_EXT_TIMER_OFFSET)
+#define LNW_EXT_TIMER_PGOFFSET 0x800
+
+/* APBT clock speed range from PCLK to fabric base, 25-100MHz */
+#define APBT_MAX_FREQ 50
+#define APBT_MIN_FREQ 1
+#define APBT_MMAP_SIZE 1024
+
+#define APBT_DEV_USED 1
+
+extern void apbt_time_init(void);
+extern struct clock_event_device *global_clock_event;
+extern unsigned long apbt_quick_calibrate(void);
+extern int arch_setup_apbt_irqs(int irq, int trigger, int mask, int cpu);
+extern void apbt_setup_secondary_clock(void);
+extern unsigned int boot_cpu_id;
+extern int disable_apbt_percpu;
+
+extern struct sfi_timer_table_entry *sfi_get_mtmr(int hint);
+extern void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr);
+extern int sfi_mtimer_num;
+
+#else /* CONFIG_APB_TIMER */
+
+static inline unsigned long apbt_quick_calibrate(void) {return 0; }
+static inline void apbt_time_init(void) {return 0; }
+
+#endif
+#endif /* ASM_X86_APBT_H */
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 9a9c7bdc923..306160e58b4 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -8,7 +8,8 @@
#include <linux/sched.h>
#include <asm/user32.h>
-#define COMPAT_USER_HZ 100
+#define COMPAT_USER_HZ 100
+#define COMPAT_UTS_MACHINE "i686\0\0"
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 635f03bb499..d07b44f7d1d 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -82,6 +82,9 @@ enum fixed_addresses {
#endif
FIX_DBGP_BASE,
FIX_EARLYCON_MEM_BASE,
+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
+ FIX_OHCI1394_BASE,
+#endif
#ifdef CONFIG_X86_LOCAL_APIC
FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
#endif
@@ -132,9 +135,6 @@ enum fixed_addresses {
(__end_of_permanent_fixed_addresses & (TOTAL_FIX_BTMAPS - 1))
: __end_of_permanent_fixed_addresses,
FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
-#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
- FIX_OHCI1394_BASE,
-#endif
#ifdef CONFIG_X86_32
FIX_WP_TEST,
#endif
diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h
index 0675a7c4c20..2a1bd8f4f23 100644
--- a/arch/x86/include/asm/hw_breakpoint.h
+++ b/arch/x86/include/asm/hw_breakpoint.h
@@ -10,7 +10,6 @@
* (display/resolving)
*/
struct arch_hw_breakpoint {
- char *name; /* Contains name of the symbol to set bkpt */
unsigned long address;
u8 len;
u8 type;
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index eeac829a0f4..46c0fe05f23 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -53,13 +53,6 @@ extern void threshold_interrupt(void);
extern void call_function_interrupt(void);
extern void call_function_single_interrupt(void);
-/* PIC specific functions */
-extern void disable_8259A_irq(unsigned int irq);
-extern void enable_8259A_irq(unsigned int irq);
-extern int i8259A_irq_pending(unsigned int irq);
-extern void make_8259A_irq(unsigned int irq);
-extern void init_8259A(int aeoi);
-
/* IOAPIC */
#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
extern unsigned long io_apic_irqs;
@@ -140,6 +133,7 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
typedef int vector_irq_t[NR_VECTORS];
DECLARE_PER_CPU(vector_irq_t, vector_irq);
+extern void setup_vector_irq(int cpu);
#ifdef CONFIG_X86_IO_APIC
extern void lock_vector_lock(void);
diff --git a/arch/x86/include/asm/hyperv.h b/arch/x86/include/asm/hyperv.h
new file mode 100644
index 00000000000..e153a2b3889
--- /dev/null
+++ b/arch/x86/include/asm/hyperv.h
@@ -0,0 +1,186 @@
+#ifndef _ASM_X86_KVM_HYPERV_H
+#define _ASM_X86_KVM_HYPERV_H
+
+#include <linux/types.h>
+
+/*
+ * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
+ * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
+ */
+#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS 0x40000000
+#define HYPERV_CPUID_INTERFACE 0x40000001
+#define HYPERV_CPUID_VERSION 0x40000002
+#define HYPERV_CPUID_FEATURES 0x40000003
+#define HYPERV_CPUID_ENLIGHTMENT_INFO 0x40000004
+#define HYPERV_CPUID_IMPLEMENT_LIMITS 0x40000005
+
+/*
+ * Feature identification. EAX indicates which features are available
+ * to the partition based upon the current partition privileges.
+ */
+
+/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
+#define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0)
+/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
+#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
+/*
+ * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
+ * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
+ */
+#define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2)
+/*
+ * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
+ * HV_X64_MSR_STIMER3_COUNT) available
+ */
+#define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3)
+/*
+ * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
+ * are available
+ */
+#define HV_X64_MSR_APIC_ACCESS_AVAILABLE (1 << 4)
+/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/
+#define HV_X64_MSR_HYPERCALL_AVAILABLE (1 << 5)
+/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/
+#define HV_X64_MSR_VP_INDEX_AVAILABLE (1 << 6)
+/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/
+#define HV_X64_MSR_RESET_AVAILABLE (1 << 7)
+ /*
+ * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE,
+ * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE,
+ * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available
+ */
+#define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8)
+
+/*
+ * Feature identification: EBX indicates which flags were specified at
+ * partition creation. The format is the same as the partition creation
+ * flag structure defined in section Partition Creation Flags.
+ */
+#define HV_X64_CREATE_PARTITIONS (1 << 0)
+#define HV_X64_ACCESS_PARTITION_ID (1 << 1)
+#define HV_X64_ACCESS_MEMORY_POOL (1 << 2)
+#define HV_X64_ADJUST_MESSAGE_BUFFERS (1 << 3)
+#define HV_X64_POST_MESSAGES (1 << 4)
+#define HV_X64_SIGNAL_EVENTS (1 << 5)
+#define HV_X64_CREATE_PORT (1 << 6)
+#define HV_X64_CONNECT_PORT (1 << 7)
+#define HV_X64_ACCESS_STATS (1 << 8)
+#define HV_X64_DEBUGGING (1 << 11)
+#define HV_X64_CPU_POWER_MANAGEMENT (1 << 12)
+#define HV_X64_CONFIGURE_PROFILER (1 << 13)
+
+/*
+ * Feature identification. EDX indicates which miscellaneous features
+ * are available to the partition.
+ */
+/* The MWAIT instruction is available (per section MONITOR / MWAIT) */
+#define HV_X64_MWAIT_AVAILABLE (1 << 0)
+/* Guest debugging support is available */
+#define HV_X64_GUEST_DEBUGGING_AVAILABLE (1 << 1)
+/* Performance Monitor support is available*/
+#define HV_X64_PERF_MONITOR_AVAILABLE (1 << 2)
+/* Support for physical CPU dynamic partitioning events is available*/
+#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE (1 << 3)
+/*
+ * Support for passing hypercall input parameter block via XMM
+ * registers is available
+ */
+#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE (1 << 4)
+/* Support for a virtual guest idle state is available */
+#define HV_X64_GUEST_IDLE_STATE_AVAILABLE (1 << 5)
+
+/*
+ * Implementation recommendations. Indicates which behaviors the hypervisor
+ * recommends the OS implement for optimal performance.
+ */
+ /*
+ * Recommend using hypercall for address space switches rather
+ * than MOV to CR3 instruction
+ */
+#define HV_X64_MWAIT_RECOMMENDED (1 << 0)
+/* Recommend using hypercall for local TLB flushes rather
+ * than INVLPG or MOV to CR3 instructions */
+#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED (1 << 1)
+/*
+ * Recommend using hypercall for remote TLB flushes rather
+ * than inter-processor interrupts
+ */
+#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED (1 << 2)
+/*
+ * Recommend using MSRs for accessing APIC registers
+ * EOI, ICR and TPR rather than their memory-mapped counterparts
+ */
+#define HV_X64_APIC_ACCESS_RECOMMENDED (1 << 3)
+/* Recommend using the hypervisor-provided MSR to initiate a system RESET */
+#define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4)
+/*
+ * Recommend using relaxed timing for this partition. If used,
+ * the VM should disable any watchdog timeouts that rely on the
+ * timely delivery of external interrupts
+ */
+#define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5)
+
+/* MSR used to identify the guest OS. */
+#define HV_X64_MSR_GUEST_OS_ID 0x40000000
+
+/* MSR used to setup pages used to communicate with the hypervisor. */
+#define HV_X64_MSR_HYPERCALL 0x40000001
+
+/* MSR used to provide vcpu index */
+#define HV_X64_MSR_VP_INDEX 0x40000002
+
+/* Define the virtual APIC registers */
+#define HV_X64_MSR_EOI 0x40000070
+#define HV_X64_MSR_ICR 0x40000071
+#define HV_X64_MSR_TPR 0x40000072
+#define HV_X64_MSR_APIC_ASSIST_PAGE 0x40000073
+
+/* Define synthetic interrupt controller model specific registers. */
+#define HV_X64_MSR_SCONTROL 0x40000080
+#define HV_X64_MSR_SVERSION 0x40000081
+#define HV_X64_MSR_SIEFP 0x40000082
+#define HV_X64_MSR_SIMP 0x40000083
+#define HV_X64_MSR_EOM 0x40000084
+#define HV_X64_MSR_SINT0 0x40000090
+#define HV_X64_MSR_SINT1 0x40000091
+#define HV_X64_MSR_SINT2 0x40000092
+#define HV_X64_MSR_SINT3 0x40000093
+#define HV_X64_MSR_SINT4 0x40000094
+#define HV_X64_MSR_SINT5 0x40000095
+#define HV_X64_MSR_SINT6 0x40000096
+#define HV_X64_MSR_SINT7 0x40000097
+#define HV_X64_MSR_SINT8 0x40000098
+#define HV_X64_MSR_SINT9 0x40000099
+#define HV_X64_MSR_SINT10 0x4000009A
+#define HV_X64_MSR_SINT11 0x4000009B
+#define HV_X64_MSR_SINT12 0x4000009C
+#define HV_X64_MSR_SINT13 0x4000009D
+#define HV_X64_MSR_SINT14 0x4000009E
+#define HV_X64_MSR_SINT15 0x4000009F
+
+
+#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001
+#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
+#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
+ (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
+
+/* Declare the various hypercall operations. */
+#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT 0x0008
+
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK \
+ (~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
+
+#define HV_PROCESSOR_POWER_STATE_C0 0
+#define HV_PROCESSOR_POWER_STATE_C1 1
+#define HV_PROCESSOR_POWER_STATE_C2 2
+#define HV_PROCESSOR_POWER_STATE_C3 3
+
+/* hypercall status code */
+#define HV_STATUS_SUCCESS 0
+#define HV_STATUS_INVALID_HYPERCALL_CODE 2
+#define HV_STATUS_INVALID_HYPERCALL_INPUT 3
+#define HV_STATUS_INVALID_ALIGNMENT 4
+
+#endif
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index 7ec65b18085..1655147646a 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -26,11 +26,6 @@ extern unsigned int cached_irq_mask;
extern raw_spinlock_t i8259A_lock;
-extern void init_8259A(int auto_eoi);
-extern void enable_8259A_irq(unsigned int irq);
-extern void disable_8259A_irq(unsigned int irq);
-extern unsigned int startup_8259A_irq(unsigned int irq);
-
/* the PIC may need a careful delay on some platforms, hence specific calls */
static inline unsigned char inb_pic(unsigned int port)
{
@@ -57,7 +52,17 @@ static inline void outb_pic(unsigned char value, unsigned int port)
extern struct irq_chip i8259A_chip;
-extern void mask_8259A(void);
-extern void unmask_8259A(void);
+struct legacy_pic {
+ int nr_legacy_irqs;
+ struct irq_chip *chip;
+ void (*mask_all)(void);
+ void (*restore_mask)(void);
+ void (*init)(int auto_eoi);
+ int (*irq_pending)(unsigned int irq);
+ void (*make_irq)(unsigned int irq);
+};
+
+extern struct legacy_pic *legacy_pic;
+extern struct legacy_pic null_legacy_pic;
#endif /* _ASM_X86_I8259_H */
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 5f61f6e0ffd..35832a03a51 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -143,8 +143,6 @@ extern int noioapicreroute;
/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
extern int timer_through_8259;
-extern void io_apic_disable_legacy(void);
-
/*
* If we use the IO-APIC for IRQ routing, disable automatic
* assignment of PCI IRQ's.
@@ -189,6 +187,7 @@ extern struct mp_ioapic_gsi mp_gsi_routing[];
int mp_find_ioapic(int gsi);
int mp_find_ioapic_pin(int ioapic, int gsi);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
+extern void __init pre_init_apic_IRQ0(void);
#else /* !CONFIG_X86_IO_APIC */
@@ -198,7 +197,11 @@ static const int timer_through_8259 = 0;
static inline void ioapic_init_mappings(void) { }
static inline void ioapic_insert_resources(void) { }
static inline void probe_nr_irqs_gsi(void) { }
+static inline int mp_find_ioapic(int gsi) { return 0; }
+struct io_apic_irq_attr;
+static inline int io_apic_set_pci_routing(struct device *dev, int irq,
+ struct io_apic_irq_attr *irq_attr) { return 0; }
#endif
#endif /* _ASM_X86_IO_APIC_H */
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 262292729fc..5458380b6ef 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -48,6 +48,5 @@ extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
extern int vector_used_by_percpu_irq(unsigned int vector);
extern void init_ISA_irqs(void);
-extern int nr_legacy_irqs;
#endif /* _ASM_X86_IRQ_H */
diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h
index 4fe681de1e7..4ffa345a8cc 100644
--- a/arch/x86/include/asm/kprobes.h
+++ b/arch/x86/include/asm/kprobes.h
@@ -32,7 +32,10 @@ struct kprobe;
typedef u8 kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0xcc
-#define RELATIVEJUMP_INSTRUCTION 0xe9
+#define RELATIVEJUMP_OPCODE 0xe9
+#define RELATIVEJUMP_SIZE 5
+#define RELATIVECALL_OPCODE 0xe8
+#define RELATIVE_ADDR_SIZE 4
#define MAX_INSN_SIZE 16
#define MAX_STACK_SIZE 64
#define MIN_STACK_SIZE(ADDR) \
@@ -44,6 +47,17 @@ typedef u8 kprobe_opcode_t;
#define flush_insn_slot(p) do { } while (0)
+/* optinsn template addresses */
+extern kprobe_opcode_t optprobe_template_entry;
+extern kprobe_opcode_t optprobe_template_val;
+extern kprobe_opcode_t optprobe_template_call;
+extern kprobe_opcode_t optprobe_template_end;
+#define MAX_OPTIMIZED_LENGTH (MAX_INSN_SIZE + RELATIVE_ADDR_SIZE)
+#define MAX_OPTINSN_SIZE \
+ (((unsigned long)&optprobe_template_end - \
+ (unsigned long)&optprobe_template_entry) + \
+ MAX_OPTIMIZED_LENGTH + RELATIVEJUMP_SIZE)
+
extern const int kretprobe_blacklist_size;
void arch_remove_kprobe(struct kprobe *p);
@@ -64,6 +78,21 @@ struct arch_specific_insn {
int boostable;
};
+struct arch_optimized_insn {
+ /* copy of the original instructions */
+ kprobe_opcode_t copied_insn[RELATIVE_ADDR_SIZE];
+ /* detour code buffer */
+ kprobe_opcode_t *insn;
+ /* the size of instructions copied to detour code buffer */
+ size_t size;
+};
+
+/* Return true (!0) if optinsn is prepared for optimization. */
+static inline int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
+{
+ return optinsn->size;
+}
+
struct prev_kprobe {
struct kprobe *kp;
unsigned long status;
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 7c18e1230f5..7a6f54fa13b 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -54,13 +54,23 @@ struct x86_emulate_ctxt;
struct x86_emulate_ops {
/*
* read_std: Read bytes of standard (non-emulated/special) memory.
- * Used for instruction fetch, stack operations, and others.
+ * Used for descriptor reading.
* @addr: [IN ] Linear address from which to read.
* @val: [OUT] Value read from memory, zero-extended to 'u_long'.
* @bytes: [IN ] Number of bytes to read from memory.
*/
int (*read_std)(unsigned long addr, void *val,
- unsigned int bytes, struct kvm_vcpu *vcpu);
+ unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error);
+
+ /*
+ * fetch: Read bytes of standard (non-emulated/special) memory.
+ * Used for instruction fetch.
+ * @addr: [IN ] Linear address from which to read.
+ * @val: [OUT] Value read from memory, zero-extended to 'u_long'.
+ * @bytes: [IN ] Number of bytes to read from memory.
+ */
+ int (*fetch)(unsigned long addr, void *val,
+ unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error);
/*
* read_emulated: Read bytes from emulated/special memory area.
@@ -74,7 +84,7 @@ struct x86_emulate_ops {
struct kvm_vcpu *vcpu);
/*
- * write_emulated: Read bytes from emulated/special memory area.
+ * write_emulated: Write bytes to emulated/special memory area.
* @addr: [IN ] Linear address to which to write.
* @val: [IN ] Value to write to memory (low-order bytes used as
* required).
@@ -168,6 +178,7 @@ struct x86_emulate_ctxt {
/* Execution mode, passed to the emulator. */
#define X86EMUL_MODE_REAL 0 /* Real mode. */
+#define X86EMUL_MODE_VM86 1 /* Virtual 8086 mode. */
#define X86EMUL_MODE_PROT16 2 /* 16-bit protected mode. */
#define X86EMUL_MODE_PROT32 4 /* 32-bit protected mode. */
#define X86EMUL_MODE_PROT64 8 /* 64-bit (long) mode. */
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4f865e8b854..06d9e79ca37 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -25,7 +25,7 @@
#include <asm/mtrr.h>
#include <asm/msr-index.h>
-#define KVM_MAX_VCPUS 16
+#define KVM_MAX_VCPUS 64
#define KVM_MEMORY_SLOTS 32
/* memory slots that does not exposed to userspace */
#define KVM_PRIVATE_MEM_SLOTS 4
@@ -38,19 +38,6 @@
#define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS | \
0xFFFFFF0000000000ULL)
-#define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST \
- (X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD)
-#define KVM_GUEST_CR0_MASK \
- (KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
-#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST \
- (X86_CR0_WP | X86_CR0_NE | X86_CR0_TS | X86_CR0_MP)
-#define KVM_VM_CR0_ALWAYS_ON \
- (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
-#define KVM_GUEST_CR4_MASK \
- (X86_CR4_VME | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE | X86_CR4_VMXE)
-#define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
-#define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
-
#define INVALID_PAGE (~(hpa_t)0)
#define UNMAPPED_GVA (~(gpa_t)0)
@@ -256,7 +243,8 @@ struct kvm_mmu {
void (*new_cr3)(struct kvm_vcpu *vcpu);
int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err);
void (*free)(struct kvm_vcpu *vcpu);
- gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva);
+ gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access,
+ u32 *error);
void (*prefetch_page)(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *page);
int (*sync_page)(struct kvm_vcpu *vcpu,
@@ -282,13 +270,15 @@ struct kvm_vcpu_arch {
u32 regs_dirty;
unsigned long cr0;
+ unsigned long cr0_guest_owned_bits;
unsigned long cr2;
unsigned long cr3;
unsigned long cr4;
+ unsigned long cr4_guest_owned_bits;
unsigned long cr8;
u32 hflags;
u64 pdptrs[4]; /* pae */
- u64 shadow_efer;
+ u64 efer;
u64 apic_base;
struct kvm_lapic *apic; /* kernel irqchip context */
int32_t apic_arb_prio;
@@ -374,17 +364,27 @@ struct kvm_vcpu_arch {
/* used for guest single stepping over the given code position */
u16 singlestep_cs;
unsigned long singlestep_rip;
+ /* fields used by HYPER-V emulation */
+ u64 hv_vapic;
};
struct kvm_mem_alias {
gfn_t base_gfn;
unsigned long npages;
gfn_t target_gfn;
+#define KVM_ALIAS_INVALID 1UL
+ unsigned long flags;
};
-struct kvm_arch{
- int naliases;
+#define KVM_ARCH_HAS_UNALIAS_INSTANTIATION
+
+struct kvm_mem_aliases {
struct kvm_mem_alias aliases[KVM_ALIAS_SLOTS];
+ int naliases;
+};
+
+struct kvm_arch {
+ struct kvm_mem_aliases *aliases;
unsigned int n_free_mmu_pages;
unsigned int n_requested_mmu_pages;
@@ -416,6 +416,10 @@ struct kvm_arch{
s64 kvmclock_offset;
struct kvm_xen_hvm_config xen_hvm_config;
+
+ /* fields used by HYPER-V emulation */
+ u64 hv_guest_os_id;
+ u64 hv_hypercall;
};
struct kvm_vm_stat {
@@ -471,6 +475,7 @@ struct kvm_x86_ops {
int (*hardware_setup)(void); /* __init */
void (*hardware_unsetup)(void); /* __exit */
bool (*cpu_has_accelerated_tpr)(void);
+ void (*cpuid_update)(struct kvm_vcpu *vcpu);
/* Create, but do not attach this VCPU */
struct kvm_vcpu *(*vcpu_create)(struct kvm *kvm, unsigned id);
@@ -492,6 +497,7 @@ struct kvm_x86_ops {
void (*set_segment)(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg);
void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l);
+ void (*decache_cr0_guest_bits)(struct kvm_vcpu *vcpu);
void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu);
void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0);
void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
@@ -501,12 +507,13 @@ struct kvm_x86_ops {
void (*set_idt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
void (*get_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
void (*set_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
- unsigned long (*get_dr)(struct kvm_vcpu *vcpu, int dr);
- void (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value,
- int *exception);
+ int (*get_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long *dest);
+ int (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value);
void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg);
unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
+ void (*fpu_activate)(struct kvm_vcpu *vcpu);
+ void (*fpu_deactivate)(struct kvm_vcpu *vcpu);
void (*tlb_flush)(struct kvm_vcpu *vcpu);
@@ -531,7 +538,8 @@ struct kvm_x86_ops {
int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
int (*get_tdp_level)(void);
u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
- bool (*gb_page_enable)(void);
+ int (*get_lpage_level)(void);
+ bool (*rdtscp_supported)(void);
const struct trace_print_flags *exit_reasons_str;
};
@@ -606,8 +614,7 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr,
unsigned long value);
void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
-int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
- int type_bits, int seg);
+int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg);
int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason);
@@ -653,6 +660,10 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
int kvm_mmu_load(struct kvm_vcpu *vcpu);
void kvm_mmu_unload(struct kvm_vcpu *vcpu);
void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu);
+gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error);
+gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error);
+gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error);
+gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error);
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
@@ -666,6 +677,7 @@ void kvm_disable_tdp(void);
int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
int complete_pio(struct kvm_vcpu *vcpu);
+bool kvm_check_iopl(struct kvm_vcpu *vcpu);
struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn);
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index c584076a47f..ffae1420e7d 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -2,6 +2,7 @@
#define _ASM_X86_KVM_PARA_H
#include <linux/types.h>
+#include <asm/hyperv.h>
/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It
* should be used to determine that a VM is running under KVM.
diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h
index ba0eed8aa1a..b60f2924c41 100644
--- a/arch/x86/include/asm/lguest_hcall.h
+++ b/arch/x86/include/asm/lguest_hcall.h
@@ -28,22 +28,39 @@
#ifndef __ASSEMBLY__
#include <asm/hw_irq.h>
-#include <asm/kvm_para.h>
/*G:030
* But first, how does our Guest contact the Host to ask for privileged
* operations? There are two ways: the direct way is to make a "hypercall",
* to make requests of the Host Itself.
*
- * We use the KVM hypercall mechanism, though completely different hypercall
- * numbers. Seventeen hypercalls are available: the hypercall number is put in
- * the %eax register, and the arguments (when required) are placed in %ebx,
- * %ecx, %edx and %esi. If a return value makes sense, it's returned in %eax.
+ * Our hypercall mechanism uses the highest unused trap code (traps 32 and
+ * above are used by real hardware interrupts). Seventeen hypercalls are
+ * available: the hypercall number is put in the %eax register, and the
+ * arguments (when required) are placed in %ebx, %ecx, %edx and %esi.
+ * If a return value makes sense, it's returned in %eax.
*
* Grossly invalid calls result in Sudden Death at the hands of the vengeful
* Host, rather than returning failure. This reflects Winston Churchill's
* definition of a gentleman: "someone who is only rude intentionally".
-:*/
+ */
+static inline unsigned long
+hcall(unsigned long call,
+ unsigned long arg1, unsigned long arg2, unsigned long arg3,
+ unsigned long arg4)
+{
+ /* "int" is the Intel instruction to trigger a trap. */
+ asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
+ /* The call in %eax (aka "a") might be overwritten */
+ : "=a"(call)
+ /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */
+ : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4)
+ /* "memory" means this might write somewhere in memory.
+ * This isn't true for all calls, but it's safe to tell
+ * gcc that it might happen so it doesn't get clever. */
+ : "memory");
+ return call;
+}
/* Can't use our min() macro here: needs to be a constant */
#define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
new file mode 100644
index 00000000000..451d30e7f62
--- /dev/null
+++ b/arch/x86/include/asm/mrst.h
@@ -0,0 +1,19 @@
+/*
+ * mrst.h: Intel Moorestown platform specific setup code
+ *
+ * (C) Copyright 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+#ifndef _ASM_X86_MRST_H
+#define _ASM_X86_MRST_H
+extern int pci_mrst_init(void);
+int __init sfi_parse_mrtc(struct sfi_table_header *table);
+
+#define SFI_MTMR_MAX_NUM 8
+#define SFI_MRTC_MAX 8
+
+#endif /* _ASM_X86_MRST_H */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 1cd58cdbc03..4604e6a54d3 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -105,6 +105,8 @@
#define MSR_AMD64_PATCH_LEVEL 0x0000008b
#define MSR_AMD64_NB_CFG 0xc001001f
#define MSR_AMD64_PATCH_LOADER 0xc0010020
+#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
+#define MSR_AMD64_OSVW_STATUS 0xc0010141
#define MSR_AMD64_IBSFETCHCTL 0xc0011030
#define MSR_AMD64_IBSFETCHLINAD 0xc0011031
#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032
diff --git a/arch/x86/include/asm/numaq.h b/arch/x86/include/asm/numaq.h
index 13370b95ea9..37c516545ec 100644
--- a/arch/x86/include/asm/numaq.h
+++ b/arch/x86/include/asm/numaq.h
@@ -30,6 +30,7 @@
extern int found_numaq;
extern int get_memcfg_numaq(void);
+extern int pci_numaq_init(void);
extern void *xquad_portio;
diff --git a/arch/x86/include/asm/olpc.h b/arch/x86/include/asm/olpc.h
index 3a57385d9fa..101229b0d8e 100644
--- a/arch/x86/include/asm/olpc.h
+++ b/arch/x86/include/asm/olpc.h
@@ -13,7 +13,6 @@ struct olpc_platform_t {
#define OLPC_F_PRESENT 0x01
#define OLPC_F_DCON 0x02
-#define OLPC_F_VSA 0x04
#ifdef CONFIG_OLPC
@@ -51,18 +50,6 @@ static inline int olpc_has_dcon(void)
}
/*
- * The VSA is software from AMD that typical Geode bioses will include.
- * It is used to emulate the PCI bus, VGA, etc. OLPC's Open Firmware does
- * not include the VSA; instead, PCI is emulated by the kernel.
- *
- * The VSA is described further in arch/x86/pci/olpc.c.
- */
-static inline int olpc_has_vsa(void)
-{
- return (olpc_platform_info.flags & OLPC_F_VSA) ? 1 : 0;
-}
-
-/*
* The "Mass Production" version of OLPC's XO is identified as being model
* C2. During the prototype phase, the following models (in chronological
* order) were created: A1, B1, B2, B3, B4, C1. The A1 through B2 models
@@ -87,13 +74,10 @@ static inline int olpc_has_dcon(void)
return 0;
}
-static inline int olpc_has_vsa(void)
-{
- return 0;
-}
-
#endif
+extern int pci_olpc_init(void);
+
/* EC related functions */
extern int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen,
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index b4a00dd4eed..404a880ea32 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -45,8 +45,15 @@ static inline int pci_proc_domain(struct pci_bus *bus)
#ifdef CONFIG_PCI
extern unsigned int pcibios_assign_all_busses(void);
+extern int pci_legacy_init(void);
+# ifdef CONFIG_ACPI
+# define x86_default_pci_init pci_acpi_init
+# else
+# define x86_default_pci_init pci_legacy_init
+# endif
#else
-#define pcibios_assign_all_busses() 0
+# define pcibios_assign_all_busses() 0
+# define x86_default_pci_init NULL
#endif
extern unsigned long pci_mem_start;
@@ -90,34 +97,6 @@ extern void pci_iommu_alloc(void);
#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-#if defined(CONFIG_X86_64) || defined(CONFIG_DMAR) || defined(CONFIG_DMA_API_DEBUG)
-
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
-#else
-
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME[0];
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) unsigned LEN_NAME[0];
-#define pci_unmap_addr(PTR, ADDR_NAME) sizeof((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
-#define pci_unmap_len(PTR, LEN_NAME) sizeof((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- do { break; } while (pci_unmap_len(PTR, LEN_NAME))
-
-#endif
-
#endif /* __KERNEL__ */
#ifdef CONFIG_X86_64
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 05b58ccb2e8..1a0422348d6 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -83,7 +83,6 @@ struct irq_routing_table {
extern unsigned int pcibios_irq_mask;
-extern int pcibios_scanned;
extern spinlock_t pci_config_lock;
extern int (*pcibios_enable_irq)(struct pci_dev *dev);
@@ -106,16 +105,15 @@ extern bool port_cf9_safe;
extern int pci_direct_probe(void);
extern void pci_direct_init(int type);
extern void pci_pcbios_init(void);
-extern int pci_olpc_init(void);
extern void __init dmi_check_pciprobe(void);
extern void __init dmi_check_skip_isa_align(void);
/* some common used subsys_initcalls */
extern int __init pci_acpi_init(void);
-extern int __init pcibios_irq_init(void);
-extern int __init pci_visws_init(void);
-extern int __init pci_numaq_init(void);
+extern void __init pcibios_irq_init(void);
extern int __init pcibios_init(void);
+extern int pci_legacy_init(void);
+extern void pcibios_fixup_irqs(void);
/* pci-mmconfig.c */
@@ -183,3 +181,17 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val)
{
asm volatile("movl %%eax,(%1)" : : "a" (val), "r" (pos) : "memory");
}
+
+#ifdef CONFIG_PCI
+# ifdef CONFIG_ACPI
+# define x86_default_pci_init pci_acpi_init
+# else
+# define x86_default_pci_init pci_legacy_init
+# endif
+# define x86_default_pci_init_irq pcibios_irq_init
+# define x86_default_pci_fixup_irqs pcibios_fixup_irqs
+#else
+# define x86_default_pci_init NULL
+# define x86_default_pci_init_irq NULL
+# define x86_default_pci_fixup_irqs NULL
+#endif
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index befd172c82a..db6109a885a 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -18,7 +18,7 @@
#define MSR_ARCH_PERFMON_EVENTSEL0 0x186
#define MSR_ARCH_PERFMON_EVENTSEL1 0x187
-#define ARCH_PERFMON_EVENTSEL0_ENABLE (1 << 22)
+#define ARCH_PERFMON_EVENTSEL_ENABLE (1 << 22)
#define ARCH_PERFMON_EVENTSEL_ANY (1 << 21)
#define ARCH_PERFMON_EVENTSEL_INT (1 << 20)
#define ARCH_PERFMON_EVENTSEL_OS (1 << 17)
@@ -50,7 +50,7 @@
INTEL_ARCH_INV_MASK| \
INTEL_ARCH_EDGE_MASK|\
INTEL_ARCH_UNIT_MASK|\
- INTEL_ARCH_EVTSEL_MASK)
+ INTEL_ARCH_EVENT_MASK)
#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c
#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8)
@@ -117,6 +117,18 @@ union cpuid10_edx {
*/
#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16)
+/* IbsFetchCtl bits/masks */
+#define IBS_FETCH_RAND_EN (1ULL<<57)
+#define IBS_FETCH_VAL (1ULL<<49)
+#define IBS_FETCH_ENABLE (1ULL<<48)
+#define IBS_FETCH_CNT 0xFFFF0000ULL
+#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
+
+/* IbsOpCtl bits */
+#define IBS_OP_CNT_CTL (1ULL<<19)
+#define IBS_OP_VAL (1ULL<<18)
+#define IBS_OP_ENABLE (1ULL<<17)
+#define IBS_OP_MAX_CNT 0x0000FFFFULL
#ifdef CONFIG_PERF_EVENTS
extern void init_hw_perf_events(void);
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
index 47339a1ac7b..2984a25ff38 100644
--- a/arch/x86/include/asm/pgtable_32.h
+++ b/arch/x86/include/asm/pgtable_32.h
@@ -19,7 +19,6 @@
#include <asm/paravirt.h>
#include <linux/bitops.h>
-#include <linux/slab.h>
#include <linux/list.h>
#include <linux/spinlock.h>
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index 20102808b19..69a686a7dff 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -274,14 +274,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
return 0;
}
-/*
- * These are defined as per linux/ptrace.h, which see.
- */
#define arch_has_single_step() (1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
-
-extern void user_enable_block_step(struct task_struct *);
#ifdef CONFIG_X86_DEBUGCTLMSR
#define arch_has_block_step() (1)
#else
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 18e496c98ff..86b1506f417 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -37,10 +37,8 @@ void setup_bios_corruption_check(void);
#ifdef CONFIG_X86_VISWS
extern void visws_early_detect(void);
-extern int is_visws_box(void);
#else
static inline void visws_early_detect(void) { }
-static inline int is_visws_box(void) { return 0; }
#endif
extern unsigned long saved_video_mode;
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 1fecb7e6113..38638cd2fa4 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -313,7 +313,7 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_EXIT_ERR -1
-#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
+#define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"
#define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8"
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index d5f69045c10..3ad421784ae 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -26,8 +26,8 @@ asmlinkage long sys32_lstat64(char __user *, struct stat64 __user *);
asmlinkage long sys32_fstat64(unsigned int, struct stat64 __user *);
asmlinkage long sys32_fstatat(unsigned int, char __user *,
struct stat64 __user *, int);
-struct mmap_arg_struct;
-asmlinkage long sys32_mmap(struct mmap_arg_struct __user *);
+struct mmap_arg_struct32;
+asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *);
asmlinkage long sys32_mprotect(unsigned long, size_t, unsigned long);
struct sigaction32;
@@ -40,8 +40,6 @@ asmlinkage long sys32_rt_sigprocmask(int, compat_sigset_t __user *,
compat_sigset_t __user *, unsigned int);
asmlinkage long sys32_alarm(unsigned int);
-struct sel_arg_struct;
-asmlinkage long sys32_old_select(struct sel_arg_struct __user *);
asmlinkage long sys32_waitpid(compat_pid_t, unsigned int *, int);
asmlinkage long sys32_sysfs(int, u32, u32);
@@ -56,11 +54,6 @@ asmlinkage long sys32_pwrite(unsigned int, char __user *, u32, u32, u32);
asmlinkage long sys32_personality(unsigned long);
asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
-struct oldold_utsname;
-struct old_utsname;
-asmlinkage long sys32_olduname(struct oldold_utsname __user *);
-long sys32_uname(struct old_utsname __user *);
-
asmlinkage long sys32_execve(char __user *, compat_uptr_t __user *,
compat_uptr_t __user *, struct pt_regs *);
asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *);
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 8868b9420b0..5c044b43e9a 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -50,18 +50,6 @@ asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
struct old_sigaction __user *);
unsigned long sys_sigreturn(struct pt_regs *);
-/* kernel/sys_i386_32.c */
-struct mmap_arg_struct;
-struct sel_arg_struct;
-struct oldold_utsname;
-struct old_utsname;
-
-asmlinkage int old_mmap(struct mmap_arg_struct __user *);
-asmlinkage int old_select(struct sel_arg_struct __user *);
-asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
-asmlinkage int sys_uname(struct old_utsname __user *);
-asmlinkage int sys_olduname(struct oldold_utsname __user *);
-
/* kernel/vm86_32.c */
int sys_vm86old(struct vm86_struct __user *, struct pt_regs *);
int sys_vm86(unsigned long, unsigned long, struct pt_regs *);
@@ -73,11 +61,8 @@ int sys_vm86(unsigned long, unsigned long, struct pt_regs *);
long sys_arch_prctl(int, unsigned long);
/* kernel/sys_x86_64.c */
-struct new_utsname;
-
asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long, unsigned long);
-asmlinkage long sys_uname(struct new_utsname __user *);
#endif /* CONFIG_X86_32 */
#endif /* _ASM_X86_SYSCALLS_H */
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index 3baf379fa84..beb9b5f8f8a 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -354,6 +354,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -366,6 +367,9 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index 4843f7ba754..ff4307b0e81 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -146,7 +146,7 @@ __SYSCALL(__NR_wait4, sys_wait4)
#define __NR_kill 62
__SYSCALL(__NR_kill, sys_kill)
#define __NR_uname 63
-__SYSCALL(__NR_uname, sys_uname)
+__SYSCALL(__NR_uname, sys_newuname)
#define __NR_semget 64
__SYSCALL(__NR_semget, sys_semget)
@@ -680,6 +680,7 @@ __SYSCALL(__NR_recvmmsg, sys_recvmmsg)
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/x86/include/asm/visws/cobalt.h b/arch/x86/include/asm/visws/cobalt.h
index 166adf61e77..2edb37637ea 100644
--- a/arch/x86/include/asm/visws/cobalt.h
+++ b/arch/x86/include/asm/visws/cobalt.h
@@ -122,4 +122,6 @@ extern char visws_board_type;
extern char visws_board_rev;
+extern int pci_visws_init(void);
+
#endif /* _ASM_X86_VISWS_COBALT_H */
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 2b4945419a8..fb9a080740e 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -53,6 +53,7 @@
*/
#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
#define SECONDARY_EXEC_ENABLE_EPT 0x00000002
+#define SECONDARY_EXEC_RDTSCP 0x00000008
#define SECONDARY_EXEC_ENABLE_VPID 0x00000020
#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
@@ -251,6 +252,7 @@ enum vmcs_field {
#define EXIT_REASON_MSR_READ 31
#define EXIT_REASON_MSR_WRITE 32
#define EXIT_REASON_MWAIT_INSTRUCTION 36
+#define EXIT_REASON_MONITOR_INSTRUCTION 39
#define EXIT_REASON_PAUSE_INSTRUCTION 40
#define EXIT_REASON_MCE_DURING_VMENTRY 41
#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
@@ -362,6 +364,7 @@ enum vmcs_field {
#define VMX_EPTP_UC_BIT (1ull << 8)
#define VMX_EPTP_WB_BIT (1ull << 14)
#define VMX_EPT_2MB_PAGE_BIT (1ull << 16)
+#define VMX_EPT_1GB_PAGE_BIT (1ull << 17)
#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24)
#define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25)
#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26)
@@ -374,7 +377,7 @@ enum vmcs_field {
#define VMX_EPT_READABLE_MASK 0x1ull
#define VMX_EPT_WRITABLE_MASK 0x2ull
#define VMX_EPT_EXECUTABLE_MASK 0x4ull
-#define VMX_EPT_IGMT_BIT (1ull << 6)
+#define VMX_EPT_IPAT_BIT (1ull << 6)
#define VMX_EPT_IDENTITY_PAGETABLE_ADDR 0xfffbc000ul
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 60cc3526908..519b54327d7 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -99,6 +99,20 @@ struct x86_init_iommu {
};
/**
+ * struct x86_init_pci - platform specific pci init functions
+ * @arch_init: platform specific pci arch init call
+ * @init: platform specific pci subsystem init
+ * @init_irq: platform specific pci irq init
+ * @fixup_irqs: platform specific pci irq fixup
+ */
+struct x86_init_pci {
+ int (*arch_init)(void);
+ int (*init)(void);
+ void (*init_irq)(void);
+ void (*fixup_irqs)(void);
+};
+
+/**
* struct x86_init_ops - functions for platform specific setup
*
*/
@@ -110,6 +124,7 @@ struct x86_init_ops {
struct x86_init_paging paging;
struct x86_init_timers timers;
struct x86_init_iommu iommu;
+ struct x86_init_pci pci;
};
/**
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index d87f09bc5a5..4c58352209e 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_VM86) += vm86_32.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_HPET_TIMER) += hpet.o
+obj-$(CONFIG_APB_TIMER) += apb_timer.o
obj-$(CONFIG_K8_NB) += k8.o
obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 738fcb60e70..cd40aba6aa9 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -31,10 +31,12 @@
#include <linux/module.h>
#include <linux/dmi.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <linux/bootmem.h>
#include <linux/ioport.h>
#include <linux/pci.h>
+#include <asm/pci_x86.h>
#include <asm/pgtable.h>
#include <asm/io_apic.h>
#include <asm/apic.h>
@@ -489,6 +491,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
* ACPI based hotplug support for CPU
*/
#ifdef CONFIG_ACPI_HOTPLUG_CPU
+#include <acpi/processor.h>
static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
{
@@ -566,6 +569,8 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
goto free_new_map;
}
+ acpi_processor_set_pdc(handle);
+
cpu = cpumask_first(new_map);
acpi_map_cpu2node(handle, cpu, physid);
@@ -1292,23 +1297,6 @@ static int __init dmi_disable_acpi(const struct dmi_system_id *d)
}
/*
- * Limit ACPI to CPU enumeration for HT
- */
-static int __init force_acpi_ht(const struct dmi_system_id *d)
-{
- if (!acpi_force) {
- printk(KERN_NOTICE "%s detected: force use of acpi=ht\n",
- d->ident);
- disable_acpi();
- acpi_ht = 1;
- } else {
- printk(KERN_NOTICE
- "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
- }
- return 0;
-}
-
-/*
* Force ignoring BIOS IRQ0 pin2 override
*/
static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
@@ -1344,82 +1332,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
},
/*
- * Boxes that need acpi=ht
- */
- {
- .callback = force_acpi_ht,
- .ident = "FSC Primergy T850",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
- DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
- },
- },
- {
- .callback = force_acpi_ht,
- .ident = "HP VISUALIZE NT Workstation",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
- DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
- },
- },
- {
- .callback = force_acpi_ht,
- .ident = "Compaq Workstation W8000",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
- },
- },
- {
- .callback = force_acpi_ht,
- .ident = "ASUS CUR-DLS",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
- DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
- },
- },
- {
- .callback = force_acpi_ht,
- .ident = "ABIT i440BX-W83977",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
- DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
- },
- },
- {
- .callback = force_acpi_ht,
- .ident = "IBM Bladecenter",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
- },
- },
- {
- .callback = force_acpi_ht,
- .ident = "IBM eServer xSeries 360",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
- },
- },
- {
- .callback = force_acpi_ht,
- .ident = "IBM eserver xSeries 330",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
- },
- },
- {
- .callback = force_acpi_ht,
- .ident = "IBM eserver xSeries 440",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
- DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
- },
- },
-
- /*
* Boxes that need ACPI PCI IRQ routing disabled
*/
{
@@ -1624,6 +1536,9 @@ int __init acpi_boot_init(void)
acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
+ if (!acpi_noirq)
+ x86_init.pci.init = pci_acpi_init;
+
return 0;
}
@@ -1648,8 +1563,10 @@ static int __init parse_acpi(char *arg)
}
/* Limit ACPI just to boot-time to enable HT */
else if (strcmp(arg, "ht") == 0) {
- if (!acpi_force)
+ if (!acpi_force) {
+ printk(KERN_WARNING "acpi=ht will be removed in Linux-2.6.35\n");
disable_acpi();
+ }
acpi_ht = 1;
}
/* acpi=rsdt use RSDT instead of XSDT */
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index e6ea0342c8f..1a160d5d44d 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -7,6 +7,8 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/memory.h>
+#include <linux/stop_machine.h>
+#include <linux/slab.h>
#include <asm/alternative.h>
#include <asm/sections.h>
#include <asm/pgtable.h>
@@ -572,3 +574,62 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
local_irq_restore(flags);
return addr;
}
+
+/*
+ * Cross-modifying kernel text with stop_machine().
+ * This code originally comes from immediate value.
+ */
+static atomic_t stop_machine_first;
+static int wrote_text;
+
+struct text_poke_params {
+ void *addr;
+ const void *opcode;
+ size_t len;
+};
+
+static int __kprobes stop_machine_text_poke(void *data)
+{
+ struct text_poke_params *tpp = data;
+
+ if (atomic_dec_and_test(&stop_machine_first)) {
+ text_poke(tpp->addr, tpp->opcode, tpp->len);
+ smp_wmb(); /* Make sure other cpus see that this has run */
+ wrote_text = 1;
+ } else {
+ while (!wrote_text)
+ cpu_relax();
+ smp_mb(); /* Load wrote_text before following execution */
+ }
+
+ flush_icache_range((unsigned long)tpp->addr,
+ (unsigned long)tpp->addr + tpp->len);
+ return 0;
+}
+
+/**
+ * text_poke_smp - Update instructions on a live kernel on SMP
+ * @addr: address to modify
+ * @opcode: source of the copy
+ * @len: length to copy
+ *
+ * Modify multi-byte instruction by using stop_machine() on SMP. This allows
+ * user to poke/set multi-byte text on SMP. Only non-NMI/MCE code modifying
+ * should be allowed, since stop_machine() does _not_ protect code against
+ * NMI and MCE.
+ *
+ * Note: Must be called under get_online_cpus() and text_mutex.
+ */
+void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len)
+{
+ struct text_poke_params tpp;
+
+ tpp.addr = addr;
+ tpp.opcode = opcode;
+ tpp.len = len;
+ atomic_set(&stop_machine_first, 1);
+ wrote_text = 0;
+ stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
+ return addr;
+}
+
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index adb0ba02570..f854d89b7ed 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -18,8 +18,8 @@
*/
#include <linux/pci.h>
-#include <linux/gfp.h>
#include <linux/bitmap.h>
+#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
@@ -118,7 +118,7 @@ static bool check_device(struct device *dev)
return false;
/* No device or no PCI device */
- if (!dev || dev->bus != &pci_bus_type)
+ if (dev->bus != &pci_bus_type)
return false;
devid = get_device_id(dev);
@@ -392,6 +392,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
u32 tail, head;
u8 *target;
+ WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED);
tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
target = iommu->cmd_buf + tail;
memcpy_toio(target, cmd, sizeof(*cmd));
@@ -2186,7 +2187,7 @@ static void prealloc_protection_domains(void)
struct dma_ops_domain *dma_dom;
u16 devid;
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+ for_each_pci_dev(dev) {
/* Do we handle this device? */
if (!check_device(&dev->dev))
@@ -2298,7 +2299,7 @@ static void cleanup_domain(struct protection_domain *domain)
list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
struct device *dev = dev_data->dev;
- do_detach(dev);
+ __detach_device(dev);
atomic_set(&dev_data->bind, 0);
}
@@ -2327,6 +2328,7 @@ static struct protection_domain *protection_domain_alloc(void)
return NULL;
spin_lock_init(&domain->lock);
+ mutex_init(&domain->api_lock);
domain->id = domain_id_alloc();
if (!domain->id)
goto out_err;
@@ -2379,9 +2381,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom)
free_pagetable(domain);
- domain_id_free(domain->id);
-
- kfree(domain);
+ protection_domain_free(domain);
dom->priv = NULL;
}
@@ -2456,6 +2456,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom,
iova &= PAGE_MASK;
paddr &= PAGE_MASK;
+ mutex_lock(&domain->api_lock);
+
for (i = 0; i < npages; ++i) {
ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k);
if (ret)
@@ -2465,6 +2467,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom,
paddr += PAGE_SIZE;
}
+ mutex_unlock(&domain->api_lock);
+
return 0;
}
@@ -2477,12 +2481,16 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom,
iova &= PAGE_MASK;
+ mutex_lock(&domain->api_lock);
+
for (i = 0; i < npages; ++i) {
iommu_unmap_page(domain, iova, PM_MAP_4k);
iova += PAGE_SIZE;
}
iommu_flush_tlb_pde(domain);
+
+ mutex_unlock(&domain->api_lock);
}
static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 9dc91b43147..6360abf993d 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -19,8 +19,8 @@
#include <linux/pci.h>
#include <linux/acpi.h>
-#include <linux/gfp.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
#include <linux/msi.h>
@@ -138,9 +138,9 @@ int amd_iommus_present;
bool amd_iommu_np_cache __read_mostly;
/*
- * Set to true if ACPI table parsing and hardware intialization went properly
+ * The ACPI table parsing functions set this variable on an error
*/
-static bool amd_iommu_initialized;
+static int __initdata amd_iommu_init_err;
/*
* List of protection domains - used during resume
@@ -391,9 +391,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table)
*/
for (i = 0; i < table->length; ++i)
checksum += p[i];
- if (checksum != 0)
+ if (checksum != 0) {
/* ACPI table corrupt */
- return -ENODEV;
+ amd_iommu_init_err = -ENODEV;
+ return 0;
+ }
p += IVRS_HEADER_LENGTH;
@@ -436,7 +438,7 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
if (cmd_buf == NULL)
return NULL;
- iommu->cmd_buf_size = CMD_BUFFER_SIZE;
+ iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED;
return cmd_buf;
}
@@ -472,12 +474,13 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu)
&entry, sizeof(entry));
amd_iommu_reset_cmd_buffer(iommu);
+ iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED);
}
static void __init free_command_buffer(struct amd_iommu *iommu)
{
free_pages((unsigned long)iommu->cmd_buf,
- get_order(iommu->cmd_buf_size));
+ get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED)));
}
/* allocates the memory where the IOMMU will log its events to */
@@ -920,11 +923,16 @@ static int __init init_iommu_all(struct acpi_table_header *table)
h->mmio_phys);
iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL);
- if (iommu == NULL)
- return -ENOMEM;
+ if (iommu == NULL) {
+ amd_iommu_init_err = -ENOMEM;
+ return 0;
+ }
+
ret = init_iommu_one(iommu, h);
- if (ret)
- return ret;
+ if (ret) {
+ amd_iommu_init_err = ret;
+ return 0;
+ }
break;
default:
break;
@@ -934,8 +942,6 @@ static int __init init_iommu_all(struct acpi_table_header *table)
}
WARN_ON(p != end);
- amd_iommu_initialized = true;
-
return 0;
}
@@ -1211,6 +1217,10 @@ static int __init amd_iommu_init(void)
if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0)
return -ENODEV;
+ ret = amd_iommu_init_err;
+ if (ret)
+ goto out;
+
dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE);
alias_table_size = tbl_size(ALIAS_TABLE_ENTRY_SIZE);
rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE);
@@ -1270,12 +1280,19 @@ static int __init amd_iommu_init(void)
if (acpi_table_parse("IVRS", init_iommu_all) != 0)
goto free;
- if (!amd_iommu_initialized)
+ if (amd_iommu_init_err) {
+ ret = amd_iommu_init_err;
goto free;
+ }
if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
goto free;
+ if (amd_iommu_init_err) {
+ ret = amd_iommu_init_err;
+ goto free;
+ }
+
ret = sysdev_class_register(&amd_iommu_sysdev_class);
if (ret)
goto free;
@@ -1288,6 +1305,8 @@ static int __init amd_iommu_init(void)
if (ret)
goto free;
+ enable_iommus();
+
if (iommu_pass_through)
ret = amd_iommu_init_passthrough();
else
@@ -1300,8 +1319,6 @@ static int __init amd_iommu_init(void)
amd_iommu_init_notifier();
- enable_iommus();
-
if (iommu_pass_through)
goto out;
@@ -1315,6 +1332,7 @@ out:
return ret;
free:
+ disable_iommus();
amd_iommu_uninit_devices();
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c
new file mode 100644
index 00000000000..a35347501d3
--- /dev/null
+++ b/arch/x86/kernel/apb_timer.c
@@ -0,0 +1,785 @@
+/*
+ * apb_timer.c: Driver for Langwell APB timers
+ *
+ * (C) Copyright 2009 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.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.
+ *
+ * Note:
+ * Langwell is the south complex of Intel Moorestown MID platform. There are
+ * eight external timers in total that can be used by the operating system.
+ * The timer information, such as frequency and addresses, is provided to the
+ * OS via SFI tables.
+ * Timer interrupts are routed via FW/HW emulated IOAPIC independently via
+ * individual redirection table entries (RTE).
+ * Unlike HPET, there is no master counter, therefore one of the timers are
+ * used as clocksource. The overall allocation looks like:
+ * - timer 0 - NR_CPUs for per cpu timer
+ * - one timer for clocksource
+ * - one timer for watchdog driver.
+ * It is also worth notice that APB timer does not support true one-shot mode,
+ * free-running mode will be used here to emulate one-shot mode.
+ * APB timer can also be used as broadcast timer along with per cpu local APIC
+ * timer, but by default APB timer has higher rating than local APIC timers.
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/pci.h>
+#include <linux/sfi.h>
+#include <linux/interrupt.h>
+#include <linux/cpu.h>
+#include <linux/irq.h>
+
+#include <asm/fixmap.h>
+#include <asm/apb_timer.h>
+
+#define APBT_MASK CLOCKSOURCE_MASK(32)
+#define APBT_SHIFT 22
+#define APBT_CLOCKEVENT_RATING 150
+#define APBT_CLOCKSOURCE_RATING 250
+#define APBT_MIN_DELTA_USEC 200
+
+#define EVT_TO_APBT_DEV(evt) container_of(evt, struct apbt_dev, evt)
+#define APBT_CLOCKEVENT0_NUM (0)
+#define APBT_CLOCKEVENT1_NUM (1)
+#define APBT_CLOCKSOURCE_NUM (2)
+
+static unsigned long apbt_address;
+static int apb_timer_block_enabled;
+static void __iomem *apbt_virt_address;
+static int phy_cs_timer_id;
+
+/*
+ * Common DW APB timer info
+ */
+static uint64_t apbt_freq;
+
+static void apbt_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt);
+static int apbt_next_event(unsigned long delta,
+ struct clock_event_device *evt);
+static cycle_t apbt_read_clocksource(struct clocksource *cs);
+static void apbt_restart_clocksource(struct clocksource *cs);
+
+struct apbt_dev {
+ struct clock_event_device evt;
+ unsigned int num;
+ int cpu;
+ unsigned int irq;
+ unsigned int tick;
+ unsigned int count;
+ unsigned int flags;
+ char name[10];
+};
+
+int disable_apbt_percpu __cpuinitdata;
+
+static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev);
+
+#ifdef CONFIG_SMP
+static unsigned int apbt_num_timers_used;
+static struct apbt_dev *apbt_devs;
+#endif
+
+static inline unsigned long apbt_readl_reg(unsigned long a)
+{
+ return readl(apbt_virt_address + a);
+}
+
+static inline void apbt_writel_reg(unsigned long d, unsigned long a)
+{
+ writel(d, apbt_virt_address + a);
+}
+
+static inline unsigned long apbt_readl(int n, unsigned long a)
+{
+ return readl(apbt_virt_address + a + n * APBTMRS_REG_SIZE);
+}
+
+static inline void apbt_writel(int n, unsigned long d, unsigned long a)
+{
+ writel(d, apbt_virt_address + a + n * APBTMRS_REG_SIZE);
+}
+
+static inline void apbt_set_mapping(void)
+{
+ struct sfi_timer_table_entry *mtmr;
+
+ if (apbt_virt_address) {
+ pr_debug("APBT base already mapped\n");
+ return;
+ }
+ mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
+ if (mtmr == NULL) {
+ printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
+ APBT_CLOCKEVENT0_NUM);
+ return;
+ }
+ apbt_address = (unsigned long)mtmr->phys_addr;
+ if (!apbt_address) {
+ printk(KERN_WARNING "No timer base from SFI, use default\n");
+ apbt_address = APBT_DEFAULT_BASE;
+ }
+ apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE);
+ if (apbt_virt_address) {
+ pr_debug("Mapped APBT physical addr %p at virtual addr %p\n",\
+ (void *)apbt_address, (void *)apbt_virt_address);
+ } else {
+ pr_debug("Failed mapping APBT phy address at %p\n",\
+ (void *)apbt_address);
+ goto panic_noapbt;
+ }
+ apbt_freq = mtmr->freq_hz / USEC_PER_SEC;
+ sfi_free_mtmr(mtmr);
+
+ /* Now figure out the physical timer id for clocksource device */
+ mtmr = sfi_get_mtmr(APBT_CLOCKSOURCE_NUM);
+ if (mtmr == NULL)
+ goto panic_noapbt;
+
+ /* Now figure out the physical timer id */
+ phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff)
+ / APBTMRS_REG_SIZE;
+ pr_debug("Use timer %d for clocksource\n", phy_cs_timer_id);
+ return;
+
+panic_noapbt:
+ panic("Failed to setup APB system timer\n");
+
+}
+
+static inline void apbt_clear_mapping(void)
+{
+ iounmap(apbt_virt_address);
+ apbt_virt_address = NULL;
+}
+
+/*
+ * APBT timer interrupt enable / disable
+ */
+static inline int is_apbt_capable(void)
+{
+ return apbt_virt_address ? 1 : 0;
+}
+
+static struct clocksource clocksource_apbt = {
+ .name = "apbt",
+ .rating = APBT_CLOCKSOURCE_RATING,
+ .read = apbt_read_clocksource,
+ .mask = APBT_MASK,
+ .shift = APBT_SHIFT,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .resume = apbt_restart_clocksource,
+};
+
+/* boot APB clock event device */
+static struct clock_event_device apbt_clockevent = {
+ .name = "apbt0",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = apbt_set_mode,
+ .set_next_event = apbt_next_event,
+ .shift = APBT_SHIFT,
+ .irq = 0,
+ .rating = APBT_CLOCKEVENT_RATING,
+};
+
+/*
+ * if user does not want to use per CPU apb timer, just give it a lower rating
+ * than local apic timer and skip the late per cpu timer init.
+ */
+static inline int __init setup_x86_mrst_timer(char *arg)
+{
+ if (!arg)
+ return -EINVAL;
+
+ if (strcmp("apbt_only", arg) == 0)
+ disable_apbt_percpu = 0;
+ else if (strcmp("lapic_and_apbt", arg) == 0)
+ disable_apbt_percpu = 1;
+ else {
+ pr_warning("X86 MRST timer option %s not recognised"
+ " use x86_mrst_timer=apbt_only or lapic_and_apbt\n",
+ arg);
+ return -EINVAL;
+ }
+ return 0;
+}
+__setup("x86_mrst_timer=", setup_x86_mrst_timer);
+
+/*
+ * start count down from 0xffff_ffff. this is done by toggling the enable bit
+ * then load initial load count to ~0.
+ */
+static void apbt_start_counter(int n)
+{
+ unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+ apbt_writel(n, ~0, APBTMR_N_LOAD_COUNT);
+ /* enable, mask interrupt */
+ ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
+ ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+ /* read it once to get cached counter value initialized */
+ apbt_read_clocksource(&clocksource_apbt);
+}
+
+static irqreturn_t apbt_interrupt_handler(int irq, void *data)
+{
+ struct apbt_dev *dev = (struct apbt_dev *)data;
+ struct clock_event_device *aevt = &dev->evt;
+
+ if (!aevt->event_handler) {
+ printk(KERN_INFO "Spurious APBT timer interrupt on %d\n",
+ dev->num);
+ return IRQ_NONE;
+ }
+ aevt->event_handler(aevt);
+ return IRQ_HANDLED;
+}
+
+static void apbt_restart_clocksource(struct clocksource *cs)
+{
+ apbt_start_counter(phy_cs_timer_id);
+}
+
+/* Setup IRQ routing via IOAPIC */
+#ifdef CONFIG_SMP
+static void apbt_setup_irq(struct apbt_dev *adev)
+{
+ struct irq_chip *chip;
+ struct irq_desc *desc;
+
+ /* timer0 irq has been setup early */
+ if (adev->irq == 0)
+ return;
+ desc = irq_to_desc(adev->irq);
+ chip = get_irq_chip(adev->irq);
+ disable_irq(adev->irq);
+ desc->status |= IRQ_MOVE_PCNTXT;
+ irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
+ /* APB timer irqs are set up as mp_irqs, timer is edge triggerred */
+ set_irq_chip_and_handler_name(adev->irq, chip, handle_edge_irq, "edge");
+ enable_irq(adev->irq);
+ if (system_state == SYSTEM_BOOTING)
+ if (request_irq(adev->irq, apbt_interrupt_handler,
+ IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+ adev->name, adev)) {
+ printk(KERN_ERR "Failed request IRQ for APBT%d\n",
+ adev->num);
+ }
+}
+#endif
+
+static void apbt_enable_int(int n)
+{
+ unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+ /* clear pending intr */
+ apbt_readl(n, APBTMR_N_EOI);
+ ctrl &= ~APBTMR_CONTROL_INT;
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+}
+
+static void apbt_disable_int(int n)
+{
+ unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+
+ ctrl |= APBTMR_CONTROL_INT;
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+}
+
+
+static int __init apbt_clockevent_register(void)
+{
+ struct sfi_timer_table_entry *mtmr;
+ struct apbt_dev *adev = &__get_cpu_var(cpu_apbt_dev);
+
+ mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
+ if (mtmr == NULL) {
+ printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
+ APBT_CLOCKEVENT0_NUM);
+ return -ENODEV;
+ }
+
+ /*
+ * We need to calculate the scaled math multiplication factor for
+ * nanosecond to apbt tick conversion.
+ * mult = (nsec/cycle)*2^APBT_SHIFT
+ */
+ apbt_clockevent.mult = div_sc((unsigned long) mtmr->freq_hz
+ , NSEC_PER_SEC, APBT_SHIFT);
+
+ /* Calculate the min / max delta */
+ apbt_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
+ &apbt_clockevent);
+ apbt_clockevent.min_delta_ns = clockevent_delta2ns(
+ APBT_MIN_DELTA_USEC*apbt_freq,
+ &apbt_clockevent);
+ /*
+ * Start apbt with the boot cpu mask and make it
+ * global if not used for per cpu timer.
+ */
+ apbt_clockevent.cpumask = cpumask_of(smp_processor_id());
+ adev->num = smp_processor_id();
+ memcpy(&adev->evt, &apbt_clockevent, sizeof(struct clock_event_device));
+
+ if (disable_apbt_percpu) {
+ apbt_clockevent.rating = APBT_CLOCKEVENT_RATING - 100;
+ global_clock_event = &adev->evt;
+ printk(KERN_DEBUG "%s clockevent registered as global\n",
+ global_clock_event->name);
+ }
+
+ if (request_irq(apbt_clockevent.irq, apbt_interrupt_handler,
+ IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+ apbt_clockevent.name, adev)) {
+ printk(KERN_ERR "Failed request IRQ for APBT%d\n",
+ apbt_clockevent.irq);
+ }
+
+ clockevents_register_device(&adev->evt);
+ /* Start APBT 0 interrupts */
+ apbt_enable_int(APBT_CLOCKEVENT0_NUM);
+
+ sfi_free_mtmr(mtmr);
+ return 0;
+}
+
+#ifdef CONFIG_SMP
+/* Should be called with per cpu */
+void apbt_setup_secondary_clock(void)
+{
+ struct apbt_dev *adev;
+ struct clock_event_device *aevt;
+ int cpu;
+
+ /* Don't register boot CPU clockevent */
+ cpu = smp_processor_id();
+ if (cpu == boot_cpu_id)
+ return;
+ /*
+ * We need to calculate the scaled math multiplication factor for
+ * nanosecond to apbt tick conversion.
+ * mult = (nsec/cycle)*2^APBT_SHIFT
+ */
+ printk(KERN_INFO "Init per CPU clockevent %d\n", cpu);
+ adev = &per_cpu(cpu_apbt_dev, cpu);
+ aevt = &adev->evt;
+
+ memcpy(aevt, &apbt_clockevent, sizeof(*aevt));
+ aevt->cpumask = cpumask_of(cpu);
+ aevt->name = adev->name;
+ aevt->mode = CLOCK_EVT_MODE_UNUSED;
+
+ printk(KERN_INFO "Registering CPU %d clockevent device %s, mask %08x\n",
+ cpu, aevt->name, *(u32 *)aevt->cpumask);
+
+ apbt_setup_irq(adev);
+
+ clockevents_register_device(aevt);
+
+ apbt_enable_int(cpu);
+
+ return;
+}
+
+/*
+ * this notify handler process CPU hotplug events. in case of S0i3, nonboot
+ * cpus are disabled/enabled frequently, for performance reasons, we keep the
+ * per cpu timer irq registered so that we do need to do free_irq/request_irq.
+ *
+ * TODO: it might be more reliable to directly disable percpu clockevent device
+ * without the notifier chain. currently, cpu 0 may get interrupts from other
+ * cpu timers during the offline process due to the ordering of notification.
+ * the extra interrupt is harmless.
+ */
+static int apbt_cpuhp_notify(struct notifier_block *n,
+ unsigned long action, void *hcpu)
+{
+ unsigned long cpu = (unsigned long)hcpu;
+ struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu);
+
+ switch (action & 0xf) {
+ case CPU_DEAD:
+ apbt_disable_int(cpu);
+ if (system_state == SYSTEM_RUNNING)
+ pr_debug("skipping APBT CPU %lu offline\n", cpu);
+ else if (adev) {
+ pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
+ free_irq(adev->irq, adev);
+ }
+ break;
+ default:
+ pr_debug(KERN_INFO "APBT notified %lu, no action\n", action);
+ }
+ return NOTIFY_OK;
+}
+
+static __init int apbt_late_init(void)
+{
+ if (disable_apbt_percpu || !apb_timer_block_enabled)
+ return 0;
+ /* This notifier should be called after workqueue is ready */
+ hotcpu_notifier(apbt_cpuhp_notify, -20);
+ return 0;
+}
+fs_initcall(apbt_late_init);
+#else
+
+void apbt_setup_secondary_clock(void) {}
+
+#endif /* CONFIG_SMP */
+
+static void apbt_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long ctrl;
+ uint64_t delta;
+ int timer_num;
+ struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
+
+ timer_num = adev->num;
+ pr_debug("%s CPU %d timer %d mode=%d\n",
+ __func__, first_cpu(*evt->cpumask), timer_num, mode);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * apbt_clockevent.mult;
+ delta >>= apbt_clockevent.shift;
+ ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+ ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ /*
+ * DW APB p. 46, have to disable timer before load counter,
+ * may cause sync problem.
+ */
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ udelay(1);
+ pr_debug("Setting clock period %d for HZ %d\n", (int)delta, HZ);
+ apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
+ ctrl |= APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ break;
+ /* APB timer does not have one-shot mode, use free running mode */
+ case CLOCK_EVT_MODE_ONESHOT:
+ ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+ /*
+ * set free running mode, this mode will let timer reload max
+ * timeout which will give time (3min on 25MHz clock) to rearm
+ * the next event, therefore emulate the one-shot mode.
+ */
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
+
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ /* write again to set free running mode */
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+
+ /*
+ * DW APB p. 46, load counter with all 1s before starting free
+ * running mode.
+ */
+ apbt_writel(timer_num, ~0, APBTMR_N_LOAD_COUNT);
+ ctrl &= ~APBTMR_CONTROL_INT;
+ ctrl |= APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ apbt_disable_int(timer_num);
+ ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ apbt_enable_int(timer_num);
+ break;
+ }
+}
+
+static int apbt_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned long ctrl;
+ int timer_num;
+
+ struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
+
+ timer_num = adev->num;
+ /* Disable timer */
+ ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ /* write new count */
+ apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
+ ctrl |= APBTMR_CONTROL_ENABLE;
+ apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
+ return 0;
+}
+
+/*
+ * APB timer clock is not in sync with pclk on Langwell, which translates to
+ * unreliable read value caused by sampling error. the error does not add up
+ * overtime and only happens when sampling a 0 as a 1 by mistake. so the time
+ * would go backwards. the following code is trying to prevent time traveling
+ * backwards. little bit paranoid.
+ */
+static cycle_t apbt_read_clocksource(struct clocksource *cs)
+{
+ unsigned long t0, t1, t2;
+ static unsigned long last_read;
+
+bad_count:
+ t1 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ t2 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ if (unlikely(t1 < t2)) {
+ pr_debug("APBT: read current count error %lx:%lx:%lx\n",
+ t1, t2, t2 - t1);
+ goto bad_count;
+ }
+ /*
+ * check against cached last read, makes sure time does not go back.
+ * it could be a normal rollover but we will do tripple check anyway
+ */
+ if (unlikely(t2 > last_read)) {
+ /* check if we have a normal rollover */
+ unsigned long raw_intr_status =
+ apbt_readl_reg(APBTMRS_RAW_INT_STATUS);
+ /*
+ * cs timer interrupt is masked but raw intr bit is set if
+ * rollover occurs. then we read EOI reg to clear it.
+ */
+ if (raw_intr_status & (1 << phy_cs_timer_id)) {
+ apbt_readl(phy_cs_timer_id, APBTMR_N_EOI);
+ goto out;
+ }
+ pr_debug("APB CS going back %lx:%lx:%lx ",
+ t2, last_read, t2 - last_read);
+bad_count_x3:
+ pr_debug(KERN_INFO "tripple check enforced\n");
+ t0 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ udelay(1);
+ t1 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ udelay(1);
+ t2 = apbt_readl(phy_cs_timer_id,
+ APBTMR_N_CURRENT_VALUE);
+ if ((t2 > t1) || (t1 > t0)) {
+ printk(KERN_ERR "Error: APB CS tripple check failed\n");
+ goto bad_count_x3;
+ }
+ }
+out:
+ last_read = t2;
+ return (cycle_t)~t2;
+}
+
+static int apbt_clocksource_register(void)
+{
+ u64 start, now;
+ cycle_t t1;
+
+ /* Start the counter, use timer 2 as source, timer 0/1 for event */
+ apbt_start_counter(phy_cs_timer_id);
+
+ /* Verify whether apbt counter works */
+ t1 = apbt_read_clocksource(&clocksource_apbt);
+ rdtscll(start);
+
+ /*
+ * We don't know the TSC frequency yet, but waiting for
+ * 200000 TSC cycles is safe:
+ * 4 GHz == 50us
+ * 1 GHz == 200us
+ */
+ do {
+ rep_nop();
+ rdtscll(now);
+ } while ((now - start) < 200000UL);
+
+ /* APBT is the only always on clocksource, it has to work! */
+ if (t1 == apbt_read_clocksource(&clocksource_apbt))
+ panic("APBT counter not counting. APBT disabled\n");
+
+ /*
+ * initialize and register APBT clocksource
+ * convert that to ns/clock cycle
+ * mult = (ns/c) * 2^APBT_SHIFT
+ */
+ clocksource_apbt.mult = div_sc(MSEC_PER_SEC,
+ (unsigned long) apbt_freq, APBT_SHIFT);
+ clocksource_register(&clocksource_apbt);
+
+ return 0;
+}
+
+/*
+ * Early setup the APBT timer, only use timer 0 for booting then switch to
+ * per CPU timer if possible.
+ * returns 1 if per cpu apbt is setup
+ * returns 0 if no per cpu apbt is chosen
+ * panic if set up failed, this is the only platform timer on Moorestown.
+ */
+void __init apbt_time_init(void)
+{
+#ifdef CONFIG_SMP
+ int i;
+ struct sfi_timer_table_entry *p_mtmr;
+ unsigned int percpu_timer;
+ struct apbt_dev *adev;
+#endif
+
+ if (apb_timer_block_enabled)
+ return;
+ apbt_set_mapping();
+ if (apbt_virt_address) {
+ pr_debug("Found APBT version 0x%lx\n",\
+ apbt_readl_reg(APBTMRS_COMP_VERSION));
+ } else
+ goto out_noapbt;
+ /*
+ * Read the frequency and check for a sane value, for ESL model
+ * we extend the possible clock range to allow time scaling.
+ */
+
+ if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) {
+ pr_debug("APBT has invalid freq 0x%llx\n", apbt_freq);
+ goto out_noapbt;
+ }
+ if (apbt_clocksource_register()) {
+ pr_debug("APBT has failed to register clocksource\n");
+ goto out_noapbt;
+ }
+ if (!apbt_clockevent_register())
+ apb_timer_block_enabled = 1;
+ else {
+ pr_debug("APBT has failed to register clockevent\n");
+ goto out_noapbt;
+ }
+#ifdef CONFIG_SMP
+ /* kernel cmdline disable apb timer, so we will use lapic timers */
+ if (disable_apbt_percpu) {
+ printk(KERN_INFO "apbt: disabled per cpu timer\n");
+ return;
+ }
+ pr_debug("%s: %d CPUs online\n", __func__, num_online_cpus());
+ if (num_possible_cpus() <= sfi_mtimer_num) {
+ percpu_timer = 1;
+ apbt_num_timers_used = num_possible_cpus();
+ } else {
+ percpu_timer = 0;
+ apbt_num_timers_used = 1;
+ adev = &per_cpu(cpu_apbt_dev, 0);
+ adev->flags &= ~APBT_DEV_USED;
+ }
+ pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used);
+
+ /* here we set up per CPU timer data structure */
+ apbt_devs = kzalloc(sizeof(struct apbt_dev) * apbt_num_timers_used,
+ GFP_KERNEL);
+ if (!apbt_devs) {
+ printk(KERN_ERR "Failed to allocate APB timer devices\n");
+ return;
+ }
+ for (i = 0; i < apbt_num_timers_used; i++) {
+ adev = &per_cpu(cpu_apbt_dev, i);
+ adev->num = i;
+ adev->cpu = i;
+ p_mtmr = sfi_get_mtmr(i);
+ if (p_mtmr) {
+ adev->tick = p_mtmr->freq_hz;
+ adev->irq = p_mtmr->irq;
+ } else
+ printk(KERN_ERR "Failed to get timer for cpu %d\n", i);
+ adev->count = 0;
+ sprintf(adev->name, "apbt%d", i);
+ }
+#endif
+
+ return;
+
+out_noapbt:
+ apbt_clear_mapping();
+ apb_timer_block_enabled = 0;
+ panic("failed to enable APB timer\n");
+}
+
+static inline void apbt_disable(int n)
+{
+ if (is_apbt_capable()) {
+ unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
+ ctrl &= ~APBTMR_CONTROL_ENABLE;
+ apbt_writel(n, ctrl, APBTMR_N_CONTROL);
+ }
+}
+
+/* called before apb_timer_enable, use early map */
+unsigned long apbt_quick_calibrate()
+{
+ int i, scale;
+ u64 old, new;
+ cycle_t t1, t2;
+ unsigned long khz = 0;
+ u32 loop, shift;
+
+ apbt_set_mapping();
+ apbt_start_counter(phy_cs_timer_id);
+
+ /* check if the timer can count down, otherwise return */
+ old = apbt_read_clocksource(&clocksource_apbt);
+ i = 10000;
+ while (--i) {
+ if (old != apbt_read_clocksource(&clocksource_apbt))
+ break;
+ }
+ if (!i)
+ goto failed;
+
+ /* count 16 ms */
+ loop = (apbt_freq * 1000) << 4;
+
+ /* restart the timer to ensure it won't get to 0 in the calibration */
+ apbt_start_counter(phy_cs_timer_id);
+
+ old = apbt_read_clocksource(&clocksource_apbt);
+ old += loop;
+
+ t1 = __native_read_tsc();
+
+ do {
+ new = apbt_read_clocksource(&clocksource_apbt);
+ } while (new < old);
+
+ t2 = __native_read_tsc();
+
+ shift = 5;
+ if (unlikely(loop >> shift == 0)) {
+ printk(KERN_INFO
+ "APBT TSC calibration failed, not enough resolution\n");
+ return 0;
+ }
+ scale = (int)div_u64((t2 - t1), loop >> shift);
+ khz = (scale * apbt_freq * 1000) >> shift;
+ printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz);
+ return khz;
+failed:
+ return 0;
+}
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index f147a95fd84..b5d8b0bcf23 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -31,7 +31,6 @@
#include <asm/x86_init.h>
int gart_iommu_aperture;
-EXPORT_SYMBOL_GPL(gart_iommu_aperture);
int gart_iommu_aperture_disabled __initdata;
int gart_iommu_aperture_allowed __initdata;
@@ -394,6 +393,7 @@ void __init gart_iommu_hole_init(void)
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
int bus;
int dev_base, dev_limit;
+ u32 ctl;
bus = bus_dev_ranges[i].bus;
dev_base = bus_dev_ranges[i].dev_base;
@@ -407,7 +407,19 @@ void __init gart_iommu_hole_init(void)
gart_iommu_aperture = 1;
x86_init.iommu.iommu_init = gart_iommu_init;
- aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
+ ctl = read_pci_config(bus, slot, 3,
+ AMD64_GARTAPERTURECTL);
+
+ /*
+ * Before we do anything else disable the GART. It may
+ * still be enabled if we boot into a crash-kernel here.
+ * Reconfiguring the GART while it is enabled could have
+ * unknown side-effects.
+ */
+ ctl &= ~GARTEN;
+ write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
+
+ aper_order = (ctl >> 1) & 7;
aper_size = (32 * 1024 * 1024) << aper_order;
aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
aper_base <<= 25;
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 6e29b2a77aa..e5a4a1e0161 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1390,7 +1390,7 @@ void __init enable_IR_x2apic(void)
}
local_irq_save(flags);
- mask_8259A();
+ legacy_pic->mask_all();
mask_IO_APIC_setup(ioapic_entries);
if (dmar_table_init_ret)
@@ -1422,7 +1422,7 @@ void __init enable_IR_x2apic(void)
nox2apic:
if (!ret) /* IR enabling failed */
restore_IO_APIC_setup(ioapic_entries);
- unmask_8259A();
+ legacy_pic->restore_mask();
local_irq_restore(flags);
out:
@@ -1640,8 +1640,10 @@ int __init APIC_init_uniprocessor(void)
}
#endif
+#ifndef CONFIG_SMP
enable_IR_x2apic();
default_setup_apic_routing();
+#endif
verify_local_APIC();
connect_bsp_APIC();
@@ -2018,7 +2020,7 @@ static int lapic_resume(struct sys_device *dev)
}
mask_IO_APIC_setup(ioapic_entries);
- mask_8259A();
+ legacy_pic->mask_all();
}
if (x2apic_mode)
@@ -2062,7 +2064,7 @@ static int lapic_resume(struct sys_device *dev)
if (intr_remapping_enabled) {
reenable_intr_remapping(x2apic_mode);
- unmask_8259A();
+ legacy_pic->restore_mask();
restore_IO_APIC_setup(ioapic_entries);
free_ioapic_entries(ioapic_entries);
}
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c
index e3c3d820c32..09d3b17ce0c 100644
--- a/arch/x86/kernel/apic/apic_flat_64.c
+++ b/arch/x86/kernel/apic/apic_flat_64.c
@@ -223,7 +223,7 @@ struct apic apic_flat = {
};
/*
- * Physflat mode is used when there are more than 8 CPUs on a AMD system.
+ * Physflat mode is used when there are more than 8 CPUs on a system.
* We cannot use logical delivery in this case because the mask
* overflows, so use physical mode.
*/
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index dd2b5f26464..03ba1b895f5 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -42,6 +42,7 @@
#include <linux/errno.h>
#include <linux/acpi.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/nmi.h>
#include <linux/smp.h>
#include <linux/io.h>
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 14862f11cc4..127b8718abf 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -36,6 +36,7 @@
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <linux/jiffies.h> /* time_after() */
+#include <linux/slab.h>
#ifdef CONFIG_ACPI
#include <acpi/acpi_bus.h>
#endif
@@ -143,12 +144,6 @@ static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY];
static struct irq_cfg irq_cfgx[NR_IRQS];
#endif
-void __init io_apic_disable_legacy(void)
-{
- nr_legacy_irqs = 0;
- nr_irqs_gsi = 0;
-}
-
int __init arch_early_irq_init(void)
{
struct irq_cfg *cfg;
@@ -157,6 +152,11 @@ int __init arch_early_irq_init(void)
int node;
int i;
+ if (!legacy_pic->nr_legacy_irqs) {
+ nr_irqs_gsi = 0;
+ io_apic_irqs = ~0UL;
+ }
+
cfg = irq_cfgx;
count = ARRAY_SIZE(irq_cfgx);
node= cpu_to_node(boot_cpu_id);
@@ -170,7 +170,7 @@ int __init arch_early_irq_init(void)
* For legacy IRQ's, start with assigning irq0 to irq15 to
* IRQ0_VECTOR to IRQ15_VECTOR on cpu 0.
*/
- if (i < nr_legacy_irqs) {
+ if (i < legacy_pic->nr_legacy_irqs) {
cfg[i].vector = IRQ0_VECTOR + i;
cpumask_set_cpu(0, cfg[i].domain);
}
@@ -852,7 +852,7 @@ static int __init find_isa_irq_apic(int irq, int type)
*/
static int EISA_ELCR(unsigned int irq)
{
- if (irq < nr_legacy_irqs) {
+ if (irq < legacy_pic->nr_legacy_irqs) {
unsigned int port = 0x4d0 + (irq >> 3);
return (inb(port) >> (irq & 7)) & 1;
}
@@ -1269,6 +1269,14 @@ void __setup_vector_irq(int cpu)
/* Mark the inuse vectors */
for_each_irq_desc(irq, desc) {
cfg = desc->chip_data;
+
+ /*
+ * If it is a legacy IRQ handled by the legacy PIC, this cpu
+ * will be part of the irq_cfg's domain.
+ */
+ if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
+ cpumask_set_cpu(cpu, cfg->domain);
+
if (!cpumask_test_cpu(cpu, cfg->domain))
continue;
vector = cfg->vector;
@@ -1439,7 +1447,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
* controllers like 8259. Now that IO-APIC can handle this irq, update
* the cfg->domain.
*/
- if (irq < nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain))
+ if (irq < legacy_pic->nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain))
apic->vector_allocation_domain(0, cfg->domain);
if (assign_irq_vector(irq, cfg, apic->target_cpus()))
@@ -1463,8 +1471,8 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
}
ioapic_register_intr(irq, desc, trigger);
- if (irq < nr_legacy_irqs)
- disable_8259A_irq(irq);
+ if (irq < legacy_pic->nr_legacy_irqs)
+ legacy_pic->chip->mask(irq);
ioapic_write_entry(apic_id, pin, entry);
}
@@ -1873,7 +1881,7 @@ __apicdebuginit(void) print_PIC(void)
unsigned int v;
unsigned long flags;
- if (!nr_legacy_irqs)
+ if (!legacy_pic->nr_legacy_irqs)
return;
printk(KERN_DEBUG "\nprinting PIC contents\n");
@@ -1957,7 +1965,7 @@ void __init enable_IO_APIC(void)
nr_ioapic_registers[apic] = reg_01.bits.entries+1;
}
- if (!nr_legacy_irqs)
+ if (!legacy_pic->nr_legacy_irqs)
return;
for(apic = 0; apic < nr_ioapics; apic++) {
@@ -2014,7 +2022,7 @@ void disable_IO_APIC(void)
*/
clear_IO_APIC();
- if (!nr_legacy_irqs)
+ if (!legacy_pic->nr_legacy_irqs)
return;
/*
@@ -2247,9 +2255,9 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
struct irq_cfg *cfg;
raw_spin_lock_irqsave(&ioapic_lock, flags);
- if (irq < nr_legacy_irqs) {
- disable_8259A_irq(irq);
- if (i8259A_irq_pending(irq))
+ if (irq < legacy_pic->nr_legacy_irqs) {
+ legacy_pic->chip->mask(irq);
+ if (legacy_pic->irq_pending(irq))
was_pending = 1;
}
cfg = irq_cfg(irq);
@@ -2782,8 +2790,8 @@ static inline void init_IO_APIC_traps(void)
* so default to an old-fashioned 8259
* interrupt if we can..
*/
- if (irq < nr_legacy_irqs)
- make_8259A_irq(irq);
+ if (irq < legacy_pic->nr_legacy_irqs)
+ legacy_pic->make_irq(irq);
else
/* Strange. Oh, well.. */
desc->chip = &no_irq_chip;
@@ -2940,7 +2948,7 @@ static inline void __init check_timer(void)
/*
* get/set the timer IRQ vector:
*/
- disable_8259A_irq(0);
+ legacy_pic->chip->mask(0);
assign_irq_vector(0, cfg, apic->target_cpus());
/*
@@ -2953,7 +2961,7 @@ static inline void __init check_timer(void)
* automatically.
*/
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
- init_8259A(1);
+ legacy_pic->init(1);
#ifdef CONFIG_X86_32
{
unsigned int ver;
@@ -3012,7 +3020,7 @@ static inline void __init check_timer(void)
if (timer_irq_works()) {
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
- enable_8259A_irq(0);
+ legacy_pic->chip->unmask(0);
}
if (disable_timer_pin_1 > 0)
clear_IO_APIC_pin(0, pin1);
@@ -3035,14 +3043,14 @@ static inline void __init check_timer(void)
*/
replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
- enable_8259A_irq(0);
+ legacy_pic->chip->unmask(0);
if (timer_irq_works()) {
apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
timer_through_8259 = 1;
if (nmi_watchdog == NMI_IO_APIC) {
- disable_8259A_irq(0);
+ legacy_pic->chip->mask(0);
setup_nmi();
- enable_8259A_irq(0);
+ legacy_pic->chip->unmask(0);
}
goto out;
}
@@ -3050,7 +3058,7 @@ static inline void __init check_timer(void)
* Cleanup, just in case ...
*/
local_irq_disable();
- disable_8259A_irq(0);
+ legacy_pic->chip->mask(0);
clear_IO_APIC_pin(apic2, pin2);
apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
}
@@ -3069,22 +3077,22 @@ static inline void __init check_timer(void)
lapic_register_intr(0, desc);
apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
- enable_8259A_irq(0);
+ legacy_pic->chip->unmask(0);
if (timer_irq_works()) {
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
goto out;
}
local_irq_disable();
- disable_8259A_irq(0);
+ legacy_pic->chip->mask(0);
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
apic_printk(APIC_QUIET, KERN_INFO
"...trying to set up timer as ExtINT IRQ...\n");
- init_8259A(0);
- make_8259A_irq(0);
+ legacy_pic->init(0);
+ legacy_pic->make_irq(0);
apic_write(APIC_LVT0, APIC_DM_EXTINT);
unlock_ExtINT_logic();
@@ -3126,7 +3134,7 @@ void __init setup_IO_APIC(void)
/*
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
*/
- io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
+ io_apic_irqs = legacy_pic->nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
/*
@@ -3137,7 +3145,7 @@ void __init setup_IO_APIC(void)
sync_Arb_IDs();
setup_IO_APIC_irqs();
init_IO_APIC_traps();
- if (nr_legacy_irqs)
+ if (legacy_pic->nr_legacy_irqs)
check_timer();
}
@@ -3928,7 +3936,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
/*
* IRQs < 16 are already in the irq_2_pin[] map
*/
- if (irq >= nr_legacy_irqs) {
+ if (irq >= legacy_pic->nr_legacy_irqs) {
cfg = desc->chip_data;
if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
printk(KERN_INFO "can not add pin %d for irq %d\n",
@@ -4302,3 +4310,24 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
nr_ioapics++;
}
+
+/* Enable IOAPIC early just for system timer */
+void __init pre_init_apic_IRQ0(void)
+{
+ struct irq_cfg *cfg;
+ struct irq_desc *desc;
+
+ printk(KERN_INFO "Early APIC setup for system timer0\n");
+#ifndef CONFIG_SMP
+ phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
+#endif
+ desc = irq_to_desc_alloc_node(0, 0);
+
+ setup_local_APIC();
+
+ cfg = irq_cfg(0);
+ add_pin_to_irq_node(cfg, 0, 0, 0);
+ set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
+
+ setup_IO_APIC_irq(0, 0, 0, desc, 0, 0);
+}
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index bd7c96b5e8d..1edaf15c0b8 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/sysdev.h>
#include <linux/sysctl.h>
#include <linux/percpu.h>
@@ -177,7 +178,7 @@ int __init check_nmi_watchdog(void)
error:
if (nmi_watchdog == NMI_IO_APIC) {
if (!timer_through_8259)
- disable_8259A_irq(0);
+ legacy_pic->chip->mask(0);
on_each_cpu(__acpi_nmi_disable, NULL, 1);
}
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index 47dd856708e..3e28401f161 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -277,6 +277,7 @@ static __init void early_check_numaq(void)
x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
x86_init.timers.tsc_pre_init = numaq_tsc_init;
+ x86_init.pci.init = pci_numaq_init;
}
}
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 3740c8a4eae..c085d52dbaf 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -17,6 +17,7 @@
#include <linux/ctype.h>
#include <linux/sched.h>
#include <linux/timer.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/io.h>
@@ -120,11 +121,9 @@ EXPORT_SYMBOL_GPL(uv_possible_blades);
unsigned long sn_rtc_cycles_per_second;
EXPORT_SYMBOL(sn_rtc_cycles_per_second);
-/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */
-
static const struct cpumask *uv_target_cpus(void)
{
- return cpumask_of(0);
+ return cpu_online_mask;
}
static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask)
diff --git a/arch/x86/kernel/bootflag.c b/arch/x86/kernel/bootflag.c
index 30f25a75fe2..5de7f4c5697 100644
--- a/arch/x86/kernel/bootflag.c
+++ b/arch/x86/kernel/bootflag.c
@@ -5,7 +5,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/acpi.h>
#include <asm/io.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig
index f138c6c389b..870e6cc6ad2 100644
--- a/arch/x86/kernel/cpu/cpufreq/Kconfig
+++ b/arch/x86/kernel/cpu/cpufreq/Kconfig
@@ -10,6 +10,20 @@ if CPU_FREQ
comment "CPUFreq processor drivers"
+config X86_PCC_CPUFREQ
+ tristate "Processor Clocking Control interface driver"
+ depends on ACPI && ACPI_PROCESSOR
+ help
+ This driver adds support for the PCC interface.
+
+ For details, take a look at:
+ <file:Documentation/cpu-freq/pcc-cpufreq.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pcc-cpufreq.
+
+ If in doubt, say N.
+
config X86_ACPI_CPUFREQ
tristate "ACPI Processor P-States driver"
select CPU_FREQ_TABLE
diff --git a/arch/x86/kernel/cpu/cpufreq/Makefile b/arch/x86/kernel/cpu/cpufreq/Makefile
index 509296df294..1840c0a5170 100644
--- a/arch/x86/kernel/cpu/cpufreq/Makefile
+++ b/arch/x86/kernel/cpu/cpufreq/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
+obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 1b1920fa7c8..459168083b7 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -33,6 +33,7 @@
#include <linux/cpufreq.h>
#include <linux/compiler.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#include <trace/events/power.h>
#include <linux/acpi.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
index 006b278b0d5..c587db472a7 100644
--- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
@@ -20,7 +20,6 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/cpufreq.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
index ac27ec2264d..16e3483be9e 100644
--- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
@@ -80,6 +80,7 @@
#include <linux/cpufreq.h>
#include <linux/pci.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <asm/processor-cyrix.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c
index da5f70fcb76..e7b559d74c5 100644
--- a/arch/x86/kernel/cpu/cpufreq/longrun.c
+++ b/arch/x86/kernel/cpu/cpufreq/longrun.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/cpufreq.h>
#include <linux/timex.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 86961519372..7b8a8ba67b0 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/cpufreq.h>
-#include <linux/slab.h>
#include <linux/cpumask.h>
#include <linux/timex.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
new file mode 100644
index 00000000000..ce7cde713e7
--- /dev/null
+++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
@@ -0,0 +1,621 @@
+/*
+ * pcc-cpufreq.c - Processor Clocking Control firmware cpufreq interface
+ *
+ * Copyright (C) 2009 Red Hat, Matthew Garrett <mjg@redhat.com>
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ * Nagananda Chumbalkar <nagananda.chumbalkar@hp.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, GOOD TITLE or NON
+ * INFRINGEMENT. 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+
+#include <linux/acpi.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+
+#include <acpi/processor.h>
+
+#define PCC_VERSION "1.00.00"
+#define POLL_LOOPS 300
+
+#define CMD_COMPLETE 0x1
+#define CMD_GET_FREQ 0x0
+#define CMD_SET_FREQ 0x1
+
+#define BUF_SZ 4
+
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "pcc-cpufreq", msg)
+
+struct pcc_register_resource {
+ u8 descriptor;
+ u16 length;
+ u8 space_id;
+ u8 bit_width;
+ u8 bit_offset;
+ u8 access_size;
+ u64 address;
+} __attribute__ ((packed));
+
+struct pcc_memory_resource {
+ u8 descriptor;
+ u16 length;
+ u8 space_id;
+ u8 resource_usage;
+ u8 type_specific;
+ u64 granularity;
+ u64 minimum;
+ u64 maximum;
+ u64 translation_offset;
+ u64 address_length;
+} __attribute__ ((packed));
+
+static struct cpufreq_driver pcc_cpufreq_driver;
+
+struct pcc_header {
+ u32 signature;
+ u16 length;
+ u8 major;
+ u8 minor;
+ u32 features;
+ u16 command;
+ u16 status;
+ u32 latency;
+ u32 minimum_time;
+ u32 maximum_time;
+ u32 nominal;
+ u32 throttled_frequency;
+ u32 minimum_frequency;
+};
+
+static void __iomem *pcch_virt_addr;
+static struct pcc_header __iomem *pcch_hdr;
+
+static DEFINE_SPINLOCK(pcc_lock);
+
+static struct acpi_generic_address doorbell;
+
+static u64 doorbell_preserve;
+static u64 doorbell_write;
+
+static u8 OSC_UUID[16] = {0x63, 0x9B, 0x2C, 0x9F, 0x70, 0x91, 0x49, 0x1f,
+ 0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46};
+
+struct pcc_cpu {
+ u32 input_offset;
+ u32 output_offset;
+};
+
+static struct pcc_cpu *pcc_cpu_info;
+
+static int pcc_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+ return 0;
+}
+
+static inline void pcc_cmd(void)
+{
+ u64 doorbell_value;
+ int i;
+
+ acpi_read(&doorbell_value, &doorbell);
+ acpi_write((doorbell_value & doorbell_preserve) | doorbell_write,
+ &doorbell);
+
+ for (i = 0; i < POLL_LOOPS; i++) {
+ if (ioread16(&pcch_hdr->status) & CMD_COMPLETE)
+ break;
+ }
+}
+
+static inline void pcc_clear_mapping(void)
+{
+ if (pcch_virt_addr)
+ iounmap(pcch_virt_addr);
+ pcch_virt_addr = NULL;
+}
+
+static unsigned int pcc_get_freq(unsigned int cpu)
+{
+ struct pcc_cpu *pcc_cpu_data;
+ unsigned int curr_freq;
+ unsigned int freq_limit;
+ u16 status;
+ u32 input_buffer;
+ u32 output_buffer;
+
+ spin_lock(&pcc_lock);
+
+ dprintk("get: get_freq for CPU %d\n", cpu);
+ pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
+
+ input_buffer = 0x1;
+ iowrite32(input_buffer,
+ (pcch_virt_addr + pcc_cpu_data->input_offset));
+ iowrite16(CMD_GET_FREQ, &pcch_hdr->command);
+
+ pcc_cmd();
+
+ output_buffer =
+ ioread32(pcch_virt_addr + pcc_cpu_data->output_offset);
+
+ /* Clear the input buffer - we are done with the current command */
+ memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
+
+ status = ioread16(&pcch_hdr->status);
+ if (status != CMD_COMPLETE) {
+ dprintk("get: FAILED: for CPU %d, status is %d\n",
+ cpu, status);
+ goto cmd_incomplete;
+ }
+ iowrite16(0, &pcch_hdr->status);
+ curr_freq = (((ioread32(&pcch_hdr->nominal) * (output_buffer & 0xff))
+ / 100) * 1000);
+
+ dprintk("get: SUCCESS: (virtual) output_offset for cpu %d is "
+ "0x%x, contains a value of: 0x%x. Speed is: %d MHz\n",
+ cpu, (pcch_virt_addr + pcc_cpu_data->output_offset),
+ output_buffer, curr_freq);
+
+ freq_limit = (output_buffer >> 8) & 0xff;
+ if (freq_limit != 0xff) {
+ dprintk("get: frequency for cpu %d is being temporarily"
+ " capped at %d\n", cpu, curr_freq);
+ }
+
+ spin_unlock(&pcc_lock);
+ return curr_freq;
+
+cmd_incomplete:
+ iowrite16(0, &pcch_hdr->status);
+ spin_unlock(&pcc_lock);
+ return -EINVAL;
+}
+
+static int pcc_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct pcc_cpu *pcc_cpu_data;
+ struct cpufreq_freqs freqs;
+ u16 status;
+ u32 input_buffer;
+ int cpu;
+
+ spin_lock(&pcc_lock);
+ cpu = policy->cpu;
+ pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
+
+ dprintk("target: CPU %d should go to target freq: %d "
+ "(virtual) input_offset is 0x%x\n",
+ cpu, target_freq,
+ (pcch_virt_addr + pcc_cpu_data->input_offset));
+
+ freqs.new = target_freq;
+ freqs.cpu = cpu;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ input_buffer = 0x1 | (((target_freq * 100)
+ / (ioread32(&pcch_hdr->nominal) * 1000)) << 8);
+ iowrite32(input_buffer,
+ (pcch_virt_addr + pcc_cpu_data->input_offset));
+ iowrite16(CMD_SET_FREQ, &pcch_hdr->command);
+
+ pcc_cmd();
+
+ /* Clear the input buffer - we are done with the current command */
+ memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
+
+ status = ioread16(&pcch_hdr->status);
+ if (status != CMD_COMPLETE) {
+ dprintk("target: FAILED for cpu %d, with status: 0x%x\n",
+ cpu, status);
+ goto cmd_incomplete;
+ }
+ iowrite16(0, &pcch_hdr->status);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ dprintk("target: was SUCCESSFUL for cpu %d\n", cpu);
+ spin_unlock(&pcc_lock);
+
+ return 0;
+
+cmd_incomplete:
+ iowrite16(0, &pcch_hdr->status);
+ spin_unlock(&pcc_lock);
+ return -EINVAL;
+}
+
+static int pcc_get_offset(int cpu)
+{
+ acpi_status status;
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *pccp, *offset;
+ struct pcc_cpu *pcc_cpu_data;
+ struct acpi_processor *pr;
+ int ret = 0;
+
+ pr = per_cpu(processors, cpu);
+ pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
+
+ status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ pccp = buffer.pointer;
+ if (!pccp || pccp->type != ACPI_TYPE_PACKAGE) {
+ ret = -ENODEV;
+ goto out_free;
+ };
+
+ offset = &(pccp->package.elements[0]);
+ if (!offset || offset->type != ACPI_TYPE_INTEGER) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ pcc_cpu_data->input_offset = offset->integer.value;
+
+ offset = &(pccp->package.elements[1]);
+ if (!offset || offset->type != ACPI_TYPE_INTEGER) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ pcc_cpu_data->output_offset = offset->integer.value;
+
+ memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
+ memset_io((pcch_virt_addr + pcc_cpu_data->output_offset), 0, BUF_SZ);
+
+ dprintk("pcc_get_offset: for CPU %d: pcc_cpu_data "
+ "input_offset: 0x%x, pcc_cpu_data output_offset: 0x%x\n",
+ cpu, pcc_cpu_data->input_offset, pcc_cpu_data->output_offset);
+out_free:
+ kfree(buffer.pointer);
+ return ret;
+}
+
+static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
+{
+ acpi_status status;
+ struct acpi_object_list input;
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object in_params[4];
+ union acpi_object *out_obj;
+ u32 capabilities[2];
+ u32 errors;
+ u32 supported;
+ int ret = 0;
+
+ input.count = 4;
+ input.pointer = in_params;
+ input.count = 4;
+ input.pointer = in_params;
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = 16;
+ in_params[0].buffer.pointer = OSC_UUID;
+ in_params[1].type = ACPI_TYPE_INTEGER;
+ in_params[1].integer.value = 1;
+ in_params[2].type = ACPI_TYPE_INTEGER;
+ in_params[2].integer.value = 2;
+ in_params[3].type = ACPI_TYPE_BUFFER;
+ in_params[3].buffer.length = 8;
+ in_params[3].buffer.pointer = (u8 *)&capabilities;
+
+ capabilities[0] = OSC_QUERY_ENABLE;
+ capabilities[1] = 0x1;
+
+ status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ if (!output.length)
+ return -ENODEV;
+
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+ if (errors) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ supported = *((u32 *)(out_obj->buffer.pointer + 4));
+ if (!(supported & 0x1)) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ kfree(output.pointer);
+ capabilities[0] = 0x0;
+ capabilities[1] = 0x1;
+
+ status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ if (!output.length)
+ return -ENODEV;
+
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+ if (errors) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ supported = *((u32 *)(out_obj->buffer.pointer + 4));
+ if (!(supported & 0x1)) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+out_free:
+ kfree(output.pointer);
+ return ret;
+}
+
+static int __init pcc_cpufreq_probe(void)
+{
+ acpi_status status;
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct pcc_memory_resource *mem_resource;
+ struct pcc_register_resource *reg_resource;
+ union acpi_object *out_obj, *member;
+ acpi_handle handle, osc_handle;
+ int ret = 0;
+
+ status = acpi_get_handle(NULL, "\\_SB", &handle);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ status = acpi_get_handle(handle, "_OSC", &osc_handle);
+ if (ACPI_SUCCESS(status)) {
+ ret = pcc_cpufreq_do_osc(&osc_handle);
+ if (ret)
+ dprintk("probe: _OSC evaluation did not succeed\n");
+ /* Firmware's use of _OSC is optional */
+ ret = 0;
+ }
+
+ status = acpi_evaluate_object(handle, "PCCH", NULL, &output);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_PACKAGE) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ member = &out_obj->package.elements[0];
+ if (member->type != ACPI_TYPE_BUFFER) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ mem_resource = (struct pcc_memory_resource *)member->buffer.pointer;
+
+ dprintk("probe: mem_resource descriptor: 0x%x,"
+ " length: %d, space_id: %d, resource_usage: %d,"
+ " type_specific: %d, granularity: 0x%llx,"
+ " minimum: 0x%llx, maximum: 0x%llx,"
+ " translation_offset: 0x%llx, address_length: 0x%llx\n",
+ mem_resource->descriptor, mem_resource->length,
+ mem_resource->space_id, mem_resource->resource_usage,
+ mem_resource->type_specific, mem_resource->granularity,
+ mem_resource->minimum, mem_resource->maximum,
+ mem_resource->translation_offset,
+ mem_resource->address_length);
+
+ if (mem_resource->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+ ret = -ENODEV;
+ goto out_free;
+ }
+
+ pcch_virt_addr = ioremap_nocache(mem_resource->minimum,
+ mem_resource->address_length);
+ if (pcch_virt_addr == NULL) {
+ dprintk("probe: could not map shared mem region\n");
+ goto out_free;
+ }
+ pcch_hdr = pcch_virt_addr;
+
+ dprintk("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr);
+ dprintk("probe: PCCH header is at physical address: 0x%llx,"
+ " signature: 0x%x, length: %d bytes, major: %d, minor: %d,"
+ " supported features: 0x%x, command field: 0x%x,"
+ " status field: 0x%x, nominal latency: %d us\n",
+ mem_resource->minimum, ioread32(&pcch_hdr->signature),
+ ioread16(&pcch_hdr->length), ioread8(&pcch_hdr->major),
+ ioread8(&pcch_hdr->minor), ioread32(&pcch_hdr->features),
+ ioread16(&pcch_hdr->command), ioread16(&pcch_hdr->status),
+ ioread32(&pcch_hdr->latency));
+
+ dprintk("probe: min time between commands: %d us,"
+ " max time between commands: %d us,"
+ " nominal CPU frequency: %d MHz,"
+ " minimum CPU frequency: %d MHz,"
+ " minimum CPU frequency without throttling: %d MHz\n",
+ ioread32(&pcch_hdr->minimum_time),
+ ioread32(&pcch_hdr->maximum_time),
+ ioread32(&pcch_hdr->nominal),
+ ioread32(&pcch_hdr->throttled_frequency),
+ ioread32(&pcch_hdr->minimum_frequency));
+
+ member = &out_obj->package.elements[1];
+ if (member->type != ACPI_TYPE_BUFFER) {
+ ret = -ENODEV;
+ goto pcch_free;
+ }
+
+ reg_resource = (struct pcc_register_resource *)member->buffer.pointer;
+
+ doorbell.space_id = reg_resource->space_id;
+ doorbell.bit_width = reg_resource->bit_width;
+ doorbell.bit_offset = reg_resource->bit_offset;
+ doorbell.access_width = 64;
+ doorbell.address = reg_resource->address;
+
+ dprintk("probe: doorbell: space_id is %d, bit_width is %d, "
+ "bit_offset is %d, access_width is %d, address is 0x%llx\n",
+ doorbell.space_id, doorbell.bit_width, doorbell.bit_offset,
+ doorbell.access_width, reg_resource->address);
+
+ member = &out_obj->package.elements[2];
+ if (member->type != ACPI_TYPE_INTEGER) {
+ ret = -ENODEV;
+ goto pcch_free;
+ }
+
+ doorbell_preserve = member->integer.value;
+
+ member = &out_obj->package.elements[3];
+ if (member->type != ACPI_TYPE_INTEGER) {
+ ret = -ENODEV;
+ goto pcch_free;
+ }
+
+ doorbell_write = member->integer.value;
+
+ dprintk("probe: doorbell_preserve: 0x%llx,"
+ " doorbell_write: 0x%llx\n",
+ doorbell_preserve, doorbell_write);
+
+ pcc_cpu_info = alloc_percpu(struct pcc_cpu);
+ if (!pcc_cpu_info) {
+ ret = -ENOMEM;
+ goto pcch_free;
+ }
+
+ printk(KERN_DEBUG "pcc-cpufreq: (v%s) driver loaded with frequency"
+ " limits: %d MHz, %d MHz\n", PCC_VERSION,
+ ioread32(&pcch_hdr->minimum_frequency),
+ ioread32(&pcch_hdr->nominal));
+ kfree(output.pointer);
+ return ret;
+pcch_free:
+ pcc_clear_mapping();
+out_free:
+ kfree(output.pointer);
+ return ret;
+}
+
+static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ unsigned int cpu = policy->cpu;
+ unsigned int result = 0;
+
+ if (!pcch_virt_addr) {
+ result = -1;
+ goto pcch_null;
+ }
+
+ result = pcc_get_offset(cpu);
+ if (result) {
+ dprintk("init: PCCP evaluation failed\n");
+ goto free;
+ }
+
+ policy->max = policy->cpuinfo.max_freq =
+ ioread32(&pcch_hdr->nominal) * 1000;
+ policy->min = policy->cpuinfo.min_freq =
+ ioread32(&pcch_hdr->minimum_frequency) * 1000;
+ policy->cur = pcc_get_freq(cpu);
+
+ dprintk("init: policy->max is %d, policy->min is %d\n",
+ policy->max, policy->min);
+
+ return 0;
+free:
+ pcc_clear_mapping();
+ free_percpu(pcc_cpu_info);
+pcch_null:
+ return result;
+}
+
+static int pcc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+
+static struct cpufreq_driver pcc_cpufreq_driver = {
+ .flags = CPUFREQ_CONST_LOOPS,
+ .get = pcc_get_freq,
+ .verify = pcc_cpufreq_verify,
+ .target = pcc_cpufreq_target,
+ .init = pcc_cpufreq_cpu_init,
+ .exit = pcc_cpufreq_cpu_exit,
+ .name = "pcc-cpufreq",
+ .owner = THIS_MODULE,
+};
+
+static int __init pcc_cpufreq_init(void)
+{
+ int ret;
+
+ if (acpi_disabled)
+ return 0;
+
+ ret = pcc_cpufreq_probe();
+ if (ret) {
+ dprintk("pcc_cpufreq_init: PCCH evaluation failed\n");
+ return ret;
+ }
+
+ ret = cpufreq_register_driver(&pcc_cpufreq_driver);
+
+ return ret;
+}
+
+static void __exit pcc_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&pcc_cpufreq_driver);
+
+ pcc_clear_mapping();
+
+ free_percpu(pcc_cpu_info);
+}
+
+MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar");
+MODULE_VERSION(PCC_VERSION);
+MODULE_DESCRIPTION("Processor Clocking Control interface driver");
+MODULE_LICENSE("GPL");
+
+late_initcall(pcc_cpufreq_init);
+module_exit(pcc_cpufreq_exit);
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
index cb01dac267d..b3379d6a5c5 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/timex.h>
#include <linux/io.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
index 8d672ef162c..9b1ff37de46 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -20,6 +20,7 @@
#include <linux/sched.h> /* current */
#include <linux/delay.h>
#include <linux/compiler.h>
+#include <linux/gfp.h>
#include <asm/msr.h>
#include <asm/processor.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 2ce8e0b5cc5..561758e9518 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -23,7 +23,6 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/sched.h>
#include "speedstep-lib.h"
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
index ad0083abfa2..a94ec6be69f 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
@@ -13,7 +13,6 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
-#include <linux/slab.h>
#include <asm/msr.h>
#include <asm/tsc.h>
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
index 04d73c114e4..8abd869baab 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
@@ -17,7 +17,6 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <asm/ist.h>
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 879666f4d87..1366c7cfd48 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -47,6 +47,27 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
(c->x86 == 0x6 && c->x86_model >= 0x0e))
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+ /*
+ * Atom erratum AAE44/AAF40/AAG38/AAH41:
+ *
+ * A race condition between speculative fetches and invalidating
+ * a large page. This is worked around in microcode, but we
+ * need the microcode to have already been loaded... so if it is
+ * not, recommend a BIOS update and disable large pages.
+ */
+ if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2) {
+ u32 ucode, junk;
+
+ wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+ sync_core();
+ rdmsr(MSR_IA32_UCODE_REV, junk, ucode);
+
+ if (ucode < 0x20e) {
+ printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n");
+ clear_cpu_cap(c, X86_FEATURE_PSE);
+ }
+ }
+
#ifdef CONFIG_X86_64
set_cpu_cap(c, X86_FEATURE_SYSENTER32);
#else
@@ -70,7 +91,8 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
if (c->x86_power & (1 << 8)) {
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
- sched_clock_stable = 1;
+ if (!check_tsc_unstable())
+ sched_clock_stable = 1;
}
/*
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index eddb1bdd1b8..b3eeb66c0a5 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -903,7 +903,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static struct sysfs_ops sysfs_ops = {
+static const struct sysfs_ops sysfs_ops = {
.show = show,
.store = store,
};
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index 73734baa50f..e7dbde7bfed 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -22,6 +22,7 @@
#include <linux/kdebug.h>
#include <linux/cpu.h>
#include <linux/sched.h>
+#include <linux/gfp.h>
#include <asm/mce.h>
#include <asm/apic.h>
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index a8aacd4b513..8a6f0afa767 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -26,6 +26,7 @@
#include <linux/sched.h>
#include <linux/sysfs.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kmod.h>
#include <linux/poll.h>
@@ -46,6 +47,13 @@
#include "mce-internal.h"
+static DEFINE_MUTEX(mce_read_mutex);
+
+#define rcu_dereference_check_mce(p) \
+ rcu_dereference_check((p), \
+ rcu_read_lock_sched_held() || \
+ lockdep_is_held(&mce_read_mutex))
+
#define CREATE_TRACE_POINTS
#include <trace/events/mce.h>
@@ -158,7 +166,7 @@ void mce_log(struct mce *mce)
mce->finished = 0;
wmb();
for (;;) {
- entry = rcu_dereference(mcelog.next);
+ entry = rcu_dereference_check_mce(mcelog.next);
for (;;) {
/*
* When the buffer fills up discard new entries.
@@ -1485,8 +1493,6 @@ static void collect_tscs(void *data)
rdtscll(cpu_tsc[smp_processor_id()]);
}
-static DEFINE_MUTEX(mce_read_mutex);
-
static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize,
loff_t *off)
{
@@ -1500,7 +1506,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize,
return -ENOMEM;
mutex_lock(&mce_read_mutex);
- next = rcu_dereference(mcelog.next);
+ next = rcu_dereference_check_mce(mcelog.next);
/* Only supports full reads right now */
if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) {
@@ -1565,7 +1571,7 @@ timeout:
static unsigned int mce_poll(struct file *file, poll_table *wait)
{
poll_wait(file, &mce_wait, wait);
- if (rcu_dereference(mcelog.next))
+ if (rcu_dereference_check_mce(mcelog.next))
return POLLIN | POLLRDNORM;
return 0;
}
@@ -2044,6 +2050,7 @@ static __init void mce_init_banks(void)
struct mce_bank *b = &mce_banks[i];
struct sysdev_attribute *a = &b->attr;
+ sysfs_attr_init(&a->attr);
a->attr.name = b->attrname;
snprintf(b->attrname, ATTR_LEN, "bank%d", i);
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 83a3d1f4efc..224392d8fe8 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sysfs.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/cpu.h>
#include <linux/smp.h>
@@ -388,7 +389,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static struct sysfs_ops threshold_ops = {
+static const struct sysfs_ops threshold_ops = {
.show = show,
.store = store,
};
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c
index 7c785634af2..62b48e40920 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c
@@ -5,6 +5,7 @@
* Author: Andi Kleen
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/percpu.h>
@@ -95,7 +96,7 @@ static void cmci_discover(int banks, int boot)
/* Already owned by someone else? */
if (val & CMCI_EN) {
- if (test_and_clear_bit(i, owned) || boot)
+ if (test_and_clear_bit(i, owned) && !boot)
print_update("SHD", &hdr, i);
__clear_bit(i, __get_cpu_var(mce_poll_banks));
continue;
@@ -107,7 +108,7 @@ static void cmci_discover(int banks, int boot)
/* Did the enable bit stick? -- the bank supports CMCI */
if (val & CMCI_EN) {
- if (!test_and_set_bit(i, owned) || boot)
+ if (!test_and_set_bit(i, owned) && !boot)
print_update("CMCI", &hdr, i);
__clear_bit(i, __get_cpu_var(mce_poll_banks));
} else {
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 9aa5dc76ff4..fd31a441c61 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/io.h>
#include <linux/mm.h>
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
index e006e56f699..79289632cb2 100644
--- a/arch/x86/kernel/cpu/mtrr/if.c
+++ b/arch/x86/kernel/cpu/mtrr/if.c
@@ -5,6 +5,7 @@
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/init.h>
#define LINE_SIZE 80
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index fe4622e8c83..79556bd9b60 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -145,6 +145,7 @@ struct set_mtrr_data {
/**
* ipi_handler - Synchronisation handler. Executed by "other" CPUs.
+ * @info: pointer to mtrr configuration data
*
* Returns nothing.
*/
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 641ccb9dddb..db5bdc8addf 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -21,6 +21,7 @@
#include <linux/kdebug.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/cpu.h>
#include <linux/bitops.h>
@@ -28,6 +29,7 @@
#include <asm/apic.h>
#include <asm/stacktrace.h>
#include <asm/nmi.h>
+#include <asm/compat.h>
static u64 perf_event_mask __read_mostly;
@@ -73,10 +75,10 @@ struct debug_store {
struct event_constraint {
union {
unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
- u64 idxmsk64[1];
+ u64 idxmsk64;
};
- int code;
- int cmask;
+ u64 code;
+ u64 cmask;
int weight;
};
@@ -103,7 +105,7 @@ struct cpu_hw_events {
};
#define __EVENT_CONSTRAINT(c, n, m, w) {\
- { .idxmsk64[0] = (n) }, \
+ { .idxmsk64 = (n) }, \
.code = (c), \
.cmask = (m), \
.weight = (w), \
@@ -116,7 +118,7 @@ struct cpu_hw_events {
EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK)
#define FIXED_EVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, n, INTEL_ARCH_FIXED_MASK)
+ EVENT_CONSTRAINT(c, (1ULL << (32+n)), INTEL_ARCH_FIXED_MASK)
#define EVENT_CONSTRAINT_END \
EVENT_CONSTRAINT(0, 0, 0)
@@ -133,8 +135,8 @@ struct x86_pmu {
int (*handle_irq)(struct pt_regs *);
void (*disable_all)(void);
void (*enable_all)(void);
- void (*enable)(struct hw_perf_event *, int);
- void (*disable)(struct hw_perf_event *, int);
+ void (*enable)(struct perf_event *);
+ void (*disable)(struct perf_event *);
unsigned eventsel;
unsigned perfctr;
u64 (*event_map)(int);
@@ -157,6 +159,11 @@ struct x86_pmu {
void (*put_event_constraints)(struct cpu_hw_events *cpuc,
struct perf_event *event);
struct event_constraint *event_constraints;
+
+ int (*cpu_prepare)(int cpu);
+ void (*cpu_starting)(int cpu);
+ void (*cpu_dying)(int cpu);
+ void (*cpu_dead)(int cpu);
};
static struct x86_pmu x86_pmu __read_mostly;
@@ -165,8 +172,7 @@ static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
.enabled = 1,
};
-static int x86_perf_event_set_period(struct perf_event *event,
- struct hw_perf_event *hwc, int idx);
+static int x86_perf_event_set_period(struct perf_event *event);
/*
* Generalized hw caching related hw_event table, filled
@@ -189,11 +195,12 @@ static u64 __read_mostly hw_cache_event_ids
* Returns the delta events processed.
*/
static u64
-x86_perf_event_update(struct perf_event *event,
- struct hw_perf_event *hwc, int idx)
+x86_perf_event_update(struct perf_event *event)
{
+ struct hw_perf_event *hwc = &event->hw;
int shift = 64 - x86_pmu.event_bits;
u64 prev_raw_count, new_raw_count;
+ int idx = hwc->idx;
s64 delta;
if (idx == X86_PMC_IDX_FIXED_BTS)
@@ -293,7 +300,7 @@ static inline bool bts_available(void)
return x86_pmu.enable_bts != NULL;
}
-static inline void init_debug_store_on_cpu(int cpu)
+static void init_debug_store_on_cpu(int cpu)
{
struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
@@ -305,7 +312,7 @@ static inline void init_debug_store_on_cpu(int cpu)
(u32)((u64)(unsigned long)ds >> 32));
}
-static inline void fini_debug_store_on_cpu(int cpu)
+static void fini_debug_store_on_cpu(int cpu)
{
if (!per_cpu(cpu_hw_events, cpu).ds)
return;
@@ -503,6 +510,9 @@ static int __hw_perf_event_init(struct perf_event *event)
*/
if (attr->type == PERF_TYPE_RAW) {
hwc->config |= x86_pmu.raw_event(attr->config);
+ if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) &&
+ perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+ return -EACCES;
return 0;
}
@@ -553,9 +563,9 @@ static void x86_pmu_disable_all(void)
if (!test_bit(idx, cpuc->active_mask))
continue;
rdmsrl(x86_pmu.eventsel + idx, val);
- if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE))
+ if (!(val & ARCH_PERFMON_EVENTSEL_ENABLE))
continue;
- val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsrl(x86_pmu.eventsel + idx, val);
}
}
@@ -590,7 +600,7 @@ static void x86_pmu_enable_all(void)
continue;
val = event->hw.config;
- val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsrl(x86_pmu.eventsel + idx, val);
}
}
@@ -612,8 +622,8 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
bitmap_zero(used_mask, X86_PMC_IDX_MAX);
for (i = 0; i < n; i++) {
- constraints[i] =
- x86_pmu.get_event_constraints(cpuc, cpuc->event_list[i]);
+ c = x86_pmu.get_event_constraints(cpuc, cpuc->event_list[i]);
+ constraints[i] = c;
}
/*
@@ -635,7 +645,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
if (test_bit(hwc->idx, used_mask))
break;
- set_bit(hwc->idx, used_mask);
+ __set_bit(hwc->idx, used_mask);
if (assign)
assign[i] = hwc->idx;
}
@@ -676,7 +686,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
if (c->weight != w)
continue;
- for_each_bit(j, c->idxmsk, X86_PMC_IDX_MAX) {
+ for_each_set_bit(j, c->idxmsk, X86_PMC_IDX_MAX) {
if (!test_bit(j, used_mask))
break;
}
@@ -684,7 +694,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
if (j == X86_PMC_IDX_MAX)
break;
- set_bit(j, used_mask);
+ __set_bit(j, used_mask);
if (assign)
assign[i] = j;
@@ -777,6 +787,7 @@ static inline int match_prev_assignment(struct hw_perf_event *hwc,
hwc->last_tag == cpuc->tags[i];
}
+static int x86_pmu_start(struct perf_event *event);
static void x86_pmu_stop(struct perf_event *event);
void hw_perf_enable(void)
@@ -793,6 +804,7 @@ void hw_perf_enable(void)
return;
if (cpuc->n_added) {
+ int n_running = cpuc->n_events - cpuc->n_added;
/*
* apply assignment obtained either from
* hw_perf_group_sched_in() or x86_pmu_enable()
@@ -800,8 +812,7 @@ void hw_perf_enable(void)
* step1: save events moving to new counters
* step2: reprogram moved events into new counters
*/
- for (i = 0; i < cpuc->n_events; i++) {
-
+ for (i = 0; i < n_running; i++) {
event = cpuc->event_list[i];
hwc = &event->hw;
@@ -816,29 +827,18 @@ void hw_perf_enable(void)
continue;
x86_pmu_stop(event);
-
- hwc->idx = -1;
}
for (i = 0; i < cpuc->n_events; i++) {
-
event = cpuc->event_list[i];
hwc = &event->hw;
- if (hwc->idx == -1) {
+ if (!match_prev_assignment(hwc, cpuc, i))
x86_assign_hw_event(event, cpuc, i);
- x86_perf_event_set_period(event, hwc, hwc->idx);
- }
- /*
- * need to mark as active because x86_pmu_disable()
- * clear active_mask and events[] yet it preserves
- * idx
- */
- set_bit(hwc->idx, cpuc->active_mask);
- cpuc->events[hwc->idx] = event;
+ else if (i < n_running)
+ continue;
- x86_pmu.enable(hwc, hwc->idx);
- perf_event_update_userpage(event);
+ x86_pmu_start(event);
}
cpuc->n_added = 0;
perf_events_lapic_init();
@@ -850,15 +850,16 @@ void hw_perf_enable(void)
x86_pmu.enable_all();
}
-static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc)
{
- (void)checking_wrmsrl(hwc->config_base + idx,
- hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE);
+ (void)checking_wrmsrl(hwc->config_base + hwc->idx,
+ hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE);
}
-static inline void x86_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+static inline void x86_pmu_disable_event(struct perf_event *event)
{
- (void)checking_wrmsrl(hwc->config_base + idx, hwc->config);
+ struct hw_perf_event *hwc = &event->hw;
+ (void)checking_wrmsrl(hwc->config_base + hwc->idx, hwc->config);
}
static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
@@ -868,12 +869,12 @@ static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
* To be called with the event disabled in hw:
*/
static int
-x86_perf_event_set_period(struct perf_event *event,
- struct hw_perf_event *hwc, int idx)
+x86_perf_event_set_period(struct perf_event *event)
{
+ struct hw_perf_event *hwc = &event->hw;
s64 left = atomic64_read(&hwc->period_left);
s64 period = hwc->sample_period;
- int err, ret = 0;
+ int err, ret = 0, idx = hwc->idx;
if (idx == X86_PMC_IDX_FIXED_BTS)
return 0;
@@ -919,11 +920,11 @@ x86_perf_event_set_period(struct perf_event *event,
return ret;
}
-static void x86_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void x86_pmu_enable_event(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
if (cpuc->enabled)
- __x86_pmu_enable_event(hwc, idx);
+ __x86_pmu_enable_event(&event->hw);
}
/*
@@ -959,34 +960,32 @@ static int x86_pmu_enable(struct perf_event *event)
memcpy(cpuc->assign, assign, n*sizeof(int));
cpuc->n_events = n;
- cpuc->n_added = n - n0;
+ cpuc->n_added += n - n0;
return 0;
}
static int x86_pmu_start(struct perf_event *event)
{
- struct hw_perf_event *hwc = &event->hw;
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int idx = event->hw.idx;
- if (hwc->idx == -1)
+ if (idx == -1)
return -EAGAIN;
- x86_perf_event_set_period(event, hwc, hwc->idx);
- x86_pmu.enable(hwc, hwc->idx);
+ x86_perf_event_set_period(event);
+ cpuc->events[idx] = event;
+ __set_bit(idx, cpuc->active_mask);
+ x86_pmu.enable(event);
+ perf_event_update_userpage(event);
return 0;
}
static void x86_pmu_unthrottle(struct perf_event *event)
{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
-
- if (WARN_ON_ONCE(hwc->idx >= X86_PMC_IDX_MAX ||
- cpuc->events[hwc->idx] != event))
- return;
-
- x86_pmu.enable(hwc, hwc->idx);
+ int ret = x86_pmu_start(event);
+ WARN_ON_ONCE(ret);
}
void perf_event_print_debug(void)
@@ -1046,18 +1045,16 @@ static void x86_pmu_stop(struct perf_event *event)
struct hw_perf_event *hwc = &event->hw;
int idx = hwc->idx;
- /*
- * Must be done before we disable, otherwise the nmi handler
- * could reenable again:
- */
- clear_bit(idx, cpuc->active_mask);
- x86_pmu.disable(hwc, idx);
+ if (!__test_and_clear_bit(idx, cpuc->active_mask))
+ return;
+
+ x86_pmu.disable(event);
/*
* Drain the remaining delta count out of a event
* that we are disabling:
*/
- x86_perf_event_update(event, hwc, idx);
+ x86_perf_event_update(event);
cpuc->events[idx] = NULL;
}
@@ -1094,8 +1091,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
int idx, handled = 0;
u64 val;
- data.addr = 0;
- data.raw = NULL;
+ perf_sample_data_init(&data, 0);
cpuc = &__get_cpu_var(cpu_hw_events);
@@ -1106,7 +1102,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
event = cpuc->events[idx];
hwc = &event->hw;
- val = x86_perf_event_update(event, hwc, idx);
+ val = x86_perf_event_update(event);
if (val & (1ULL << (x86_pmu.event_bits - 1)))
continue;
@@ -1116,11 +1112,11 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
handled = 1;
data.period = event->hw.last_period;
- if (!x86_perf_event_set_period(event, hwc, idx))
+ if (!x86_perf_event_set_period(event))
continue;
if (perf_event_overflow(event, 1, &data, regs))
- x86_pmu.disable(hwc, idx);
+ x86_pmu_stop(event);
}
if (handled)
@@ -1307,7 +1303,7 @@ int hw_perf_group_sched_in(struct perf_event *leader,
memcpy(cpuc->assign, assign, n0*sizeof(int));
cpuc->n_events = n0;
- cpuc->n_added = n1;
+ cpuc->n_added += n1;
ctx->nr_active += n1;
/*
@@ -1335,6 +1331,41 @@ undo:
#include "perf_event_p6.c"
#include "perf_event_intel.c"
+static int __cpuinit
+x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (long)hcpu;
+ int ret = NOTIFY_OK;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_UP_PREPARE:
+ if (x86_pmu.cpu_prepare)
+ ret = x86_pmu.cpu_prepare(cpu);
+ break;
+
+ case CPU_STARTING:
+ if (x86_pmu.cpu_starting)
+ x86_pmu.cpu_starting(cpu);
+ break;
+
+ case CPU_DYING:
+ if (x86_pmu.cpu_dying)
+ x86_pmu.cpu_dying(cpu);
+ break;
+
+ case CPU_UP_CANCELED:
+ case CPU_DEAD:
+ if (x86_pmu.cpu_dead)
+ x86_pmu.cpu_dead(cpu);
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static void __init pmu_check_apic(void)
{
if (cpu_has_apic)
@@ -1347,6 +1378,7 @@ static void __init pmu_check_apic(void)
void __init init_hw_perf_events(void)
{
+ struct event_constraint *c;
int err;
pr_info("Performance Events: ");
@@ -1395,6 +1427,16 @@ void __init init_hw_perf_events(void)
__EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_events) - 1,
0, x86_pmu.num_events);
+ if (x86_pmu.event_constraints) {
+ for_each_event_constraint(c, x86_pmu.event_constraints) {
+ if (c->cmask != INTEL_ARCH_FIXED_MASK)
+ continue;
+
+ c->idxmsk64 |= (1ULL << x86_pmu.num_events) - 1;
+ c->weight += x86_pmu.num_events;
+ }
+ }
+
pr_info("... version: %d\n", x86_pmu.version);
pr_info("... bit width: %d\n", x86_pmu.event_bits);
pr_info("... generic registers: %d\n", x86_pmu.num_events);
@@ -1402,11 +1444,13 @@ void __init init_hw_perf_events(void)
pr_info("... max period: %016Lx\n", x86_pmu.max_period);
pr_info("... fixed-purpose events: %d\n", x86_pmu.num_events_fixed);
pr_info("... event mask: %016Lx\n", perf_event_mask);
+
+ perf_cpu_notifier(x86_pmu_notifier);
}
static inline void x86_pmu_read(struct perf_event *event)
{
- x86_perf_event_update(event, &event->hw, event->hw.idx);
+ x86_perf_event_update(event);
}
static const struct pmu pmu = {
@@ -1588,14 +1632,42 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
return len;
}
-static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
+#ifdef CONFIG_COMPAT
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
{
- unsigned long bytes;
+ /* 32-bit process in 64-bit kernel. */
+ struct stack_frame_ia32 frame;
+ const void __user *fp;
- bytes = copy_from_user_nmi(frame, fp, sizeof(*frame));
+ if (!test_thread_flag(TIF_IA32))
+ return 0;
- return bytes == sizeof(*frame);
+ fp = compat_ptr(regs->bp);
+ while (entry->nr < PERF_MAX_STACK_DEPTH) {
+ unsigned long bytes;
+ frame.next_frame = 0;
+ frame.return_address = 0;
+
+ bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
+ if (bytes != sizeof(frame))
+ break;
+
+ if (fp < compat_ptr(regs->sp))
+ break;
+
+ callchain_store(entry, frame.return_address);
+ fp = compat_ptr(frame.next_frame);
+ }
+ return 1;
+}
+#else
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+ return 0;
}
+#endif
static void
perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
@@ -1611,11 +1683,16 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
callchain_store(entry, PERF_CONTEXT_USER);
callchain_store(entry, regs->ip);
+ if (perf_callchain_user32(regs, entry))
+ return;
+
while (entry->nr < PERF_MAX_STACK_DEPTH) {
+ unsigned long bytes;
frame.next_frame = NULL;
frame.return_address = 0;
- if (!copy_stack_frame(fp, &frame))
+ bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
+ if (bytes != sizeof(frame))
break;
if ((unsigned long)fp < regs->sp)
@@ -1662,28 +1739,14 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
return entry;
}
-void hw_perf_event_setup_online(int cpu)
-{
- init_debug_store_on_cpu(cpu);
-
- switch (boot_cpu_data.x86_vendor) {
- case X86_VENDOR_AMD:
- amd_pmu_cpu_online(cpu);
- break;
- default:
- return;
- }
-}
-
-void hw_perf_event_setup_offline(int cpu)
+void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
{
- init_debug_store_on_cpu(cpu);
-
- switch (boot_cpu_data.x86_vendor) {
- case X86_VENDOR_AMD:
- amd_pmu_cpu_offline(cpu);
- break;
- default:
- return;
- }
+ regs->ip = ip;
+ /*
+ * perf_arch_fetch_caller_regs adds another call, we need to increment
+ * the skip level
+ */
+ regs->bp = rewind_frame_pointer(skip + 1);
+ regs->cs = __KERNEL_CS;
+ local_save_flags(regs->flags);
}
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 8f3dbfda3c4..db6f7d4056e 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -137,6 +137,13 @@ static inline int amd_is_nb_event(struct hw_perf_event *hwc)
return (hwc->config & 0xe0) == 0xe0;
}
+static inline int amd_has_nb(struct cpu_hw_events *cpuc)
+{
+ struct amd_nb *nb = cpuc->amd_nb;
+
+ return nb && nb->nb_id != -1;
+}
+
static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
struct perf_event *event)
{
@@ -147,7 +154,7 @@ static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
/*
* only care about NB events
*/
- if (!(nb && amd_is_nb_event(hwc)))
+ if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc)))
return;
/*
@@ -214,7 +221,7 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
/*
* if not NB event or no NB, then no constraints
*/
- if (!(nb && amd_is_nb_event(hwc)))
+ if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc)))
return &unconstrained;
/*
@@ -271,28 +278,6 @@ done:
return &emptyconstraint;
}
-static __initconst struct x86_pmu amd_pmu = {
- .name = "AMD",
- .handle_irq = x86_pmu_handle_irq,
- .disable_all = x86_pmu_disable_all,
- .enable_all = x86_pmu_enable_all,
- .enable = x86_pmu_enable_event,
- .disable = x86_pmu_disable_event,
- .eventsel = MSR_K7_EVNTSEL0,
- .perfctr = MSR_K7_PERFCTR0,
- .event_map = amd_pmu_event_map,
- .raw_event = amd_pmu_raw_event,
- .max_events = ARRAY_SIZE(amd_perfmon_event_map),
- .num_events = 4,
- .event_bits = 48,
- .event_mask = (1ULL << 48) - 1,
- .apic = 1,
- /* use highest bit to detect overflow */
- .max_period = (1ULL << 47) - 1,
- .get_event_constraints = amd_get_event_constraints,
- .put_event_constraints = amd_put_event_constraints
-};
-
static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
{
struct amd_nb *nb;
@@ -309,57 +294,61 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
* initialize all possible NB constraints
*/
for (i = 0; i < x86_pmu.num_events; i++) {
- set_bit(i, nb->event_constraints[i].idxmsk);
+ __set_bit(i, nb->event_constraints[i].idxmsk);
nb->event_constraints[i].weight = 1;
}
return nb;
}
-static void amd_pmu_cpu_online(int cpu)
+static int amd_pmu_cpu_prepare(int cpu)
{
- struct cpu_hw_events *cpu1, *cpu2;
- struct amd_nb *nb = NULL;
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+
+ WARN_ON_ONCE(cpuc->amd_nb);
+
+ if (boot_cpu_data.x86_max_cores < 2)
+ return NOTIFY_OK;
+
+ cpuc->amd_nb = amd_alloc_nb(cpu, -1);
+ if (!cpuc->amd_nb)
+ return NOTIFY_BAD;
+
+ return NOTIFY_OK;
+}
+
+static void amd_pmu_cpu_starting(int cpu)
+{
+ struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+ struct amd_nb *nb;
int i, nb_id;
if (boot_cpu_data.x86_max_cores < 2)
return;
- /*
- * function may be called too early in the
- * boot process, in which case nb_id is bogus
- */
nb_id = amd_get_nb_id(cpu);
- if (nb_id == BAD_APICID)
- return;
-
- cpu1 = &per_cpu(cpu_hw_events, cpu);
- cpu1->amd_nb = NULL;
+ WARN_ON_ONCE(nb_id == BAD_APICID);
raw_spin_lock(&amd_nb_lock);
for_each_online_cpu(i) {
- cpu2 = &per_cpu(cpu_hw_events, i);
- nb = cpu2->amd_nb;
- if (!nb)
+ nb = per_cpu(cpu_hw_events, i).amd_nb;
+ if (WARN_ON_ONCE(!nb))
continue;
- if (nb->nb_id == nb_id)
- goto found;
- }
- nb = amd_alloc_nb(cpu, nb_id);
- if (!nb) {
- pr_err("perf_events: failed NB allocation for CPU%d\n", cpu);
- raw_spin_unlock(&amd_nb_lock);
- return;
+ if (nb->nb_id == nb_id) {
+ kfree(cpuc->amd_nb);
+ cpuc->amd_nb = nb;
+ break;
+ }
}
-found:
- nb->refcnt++;
- cpu1->amd_nb = nb;
+
+ cpuc->amd_nb->nb_id = nb_id;
+ cpuc->amd_nb->refcnt++;
raw_spin_unlock(&amd_nb_lock);
}
-static void amd_pmu_cpu_offline(int cpu)
+static void amd_pmu_cpu_dead(int cpu)
{
struct cpu_hw_events *cpuhw;
@@ -370,14 +359,44 @@ static void amd_pmu_cpu_offline(int cpu)
raw_spin_lock(&amd_nb_lock);
- if (--cpuhw->amd_nb->refcnt == 0)
- kfree(cpuhw->amd_nb);
+ if (cpuhw->amd_nb) {
+ struct amd_nb *nb = cpuhw->amd_nb;
+
+ if (nb->nb_id == -1 || --nb->refcnt == 0)
+ kfree(nb);
- cpuhw->amd_nb = NULL;
+ cpuhw->amd_nb = NULL;
+ }
raw_spin_unlock(&amd_nb_lock);
}
+static __initconst struct x86_pmu amd_pmu = {
+ .name = "AMD",
+ .handle_irq = x86_pmu_handle_irq,
+ .disable_all = x86_pmu_disable_all,
+ .enable_all = x86_pmu_enable_all,
+ .enable = x86_pmu_enable_event,
+ .disable = x86_pmu_disable_event,
+ .eventsel = MSR_K7_EVNTSEL0,
+ .perfctr = MSR_K7_PERFCTR0,
+ .event_map = amd_pmu_event_map,
+ .raw_event = amd_pmu_raw_event,
+ .max_events = ARRAY_SIZE(amd_perfmon_event_map),
+ .num_events = 4,
+ .event_bits = 48,
+ .event_mask = (1ULL << 48) - 1,
+ .apic = 1,
+ /* use highest bit to detect overflow */
+ .max_period = (1ULL << 47) - 1,
+ .get_event_constraints = amd_get_event_constraints,
+ .put_event_constraints = amd_put_event_constraints,
+
+ .cpu_prepare = amd_pmu_cpu_prepare,
+ .cpu_starting = amd_pmu_cpu_starting,
+ .cpu_dead = amd_pmu_cpu_dead,
+};
+
static __init int amd_pmu_init(void)
{
/* Performance-monitoring supported from K7 and later: */
@@ -390,11 +409,6 @@ static __init int amd_pmu_init(void)
memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
- /*
- * explicitly initialize the boot cpu, other cpus will get
- * the cpu hotplug callbacks from smp_init()
- */
- amd_pmu_cpu_online(smp_processor_id());
return 0;
}
@@ -405,12 +419,4 @@ static int amd_pmu_init(void)
return 0;
}
-static void amd_pmu_cpu_online(int cpu)
-{
-}
-
-static void amd_pmu_cpu_offline(int cpu)
-{
-}
-
#endif
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index cf6590cf4a5..9c794ac8783 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1,7 +1,7 @@
#ifdef CONFIG_CPU_SUP_INTEL
/*
- * Intel PerfMon v3. Used on Core2 and later.
+ * Intel PerfMon, used on Core and later.
*/
static const u64 intel_perfmon_event_map[] =
{
@@ -27,8 +27,14 @@ static struct event_constraint intel_core_event_constraints[] =
static struct event_constraint intel_core2_event_constraints[] =
{
- FIXED_EVENT_CONSTRAINT(0xc0, (0x3|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */
- FIXED_EVENT_CONSTRAINT(0x3c, (0x3|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ /*
+ * Core2 has Fixed Counter 2 listed as CPU_CLK_UNHALTED.REF and event
+ * 0x013c as CPU_CLK_UNHALTED.BUS and specifies there is a fixed
+ * ratio between these counters.
+ */
+ /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
@@ -37,14 +43,16 @@ static struct event_constraint intel_core2_event_constraints[] =
INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
+ INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */
INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
EVENT_CONSTRAINT_END
};
static struct event_constraint intel_nehalem_event_constraints[] =
{
- FIXED_EVENT_CONSTRAINT(0xc0, (0xf|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */
- FIXED_EVENT_CONSTRAINT(0x3c, (0xf|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
@@ -58,8 +66,9 @@ static struct event_constraint intel_nehalem_event_constraints[] =
static struct event_constraint intel_westmere_event_constraints[] =
{
- FIXED_EVENT_CONSTRAINT(0xc0, (0xf|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */
- FIXED_EVENT_CONSTRAINT(0x3c, (0xf|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
@@ -68,8 +77,9 @@ static struct event_constraint intel_westmere_event_constraints[] =
static struct event_constraint intel_gen_event_constraints[] =
{
- FIXED_EVENT_CONSTRAINT(0xc0, (0x3|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */
- FIXED_EVENT_CONSTRAINT(0x3c, (0x3|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
EVENT_CONSTRAINT_END
};
@@ -538,9 +548,9 @@ static inline void intel_pmu_ack_status(u64 ack)
}
static inline void
-intel_pmu_disable_fixed(struct hw_perf_event *hwc, int __idx)
+intel_pmu_disable_fixed(struct hw_perf_event *hwc)
{
- int idx = __idx - X86_PMC_IDX_FIXED;
+ int idx = hwc->idx - X86_PMC_IDX_FIXED;
u64 ctrl_val, mask;
mask = 0xfULL << (idx * 4);
@@ -580,10 +590,9 @@ static void intel_pmu_drain_bts_buffer(void)
ds->bts_index = ds->bts_buffer_base;
+ perf_sample_data_init(&data, 0);
data.period = event->hw.last_period;
- data.addr = 0;
- data.raw = NULL;
regs.ip = 0;
/*
@@ -612,26 +621,28 @@ static void intel_pmu_drain_bts_buffer(void)
}
static inline void
-intel_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+intel_pmu_disable_event(struct perf_event *event)
{
- if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
intel_pmu_disable_bts();
intel_pmu_drain_bts_buffer();
return;
}
if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
- intel_pmu_disable_fixed(hwc, idx);
+ intel_pmu_disable_fixed(hwc);
return;
}
- x86_pmu_disable_event(hwc, idx);
+ x86_pmu_disable_event(event);
}
static inline void
-intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx)
+intel_pmu_enable_fixed(struct hw_perf_event *hwc)
{
- int idx = __idx - X86_PMC_IDX_FIXED;
+ int idx = hwc->idx - X86_PMC_IDX_FIXED;
u64 ctrl_val, bits, mask;
int err;
@@ -661,9 +672,11 @@ intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx)
err = checking_wrmsrl(hwc->config_base, ctrl_val);
}
-static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void intel_pmu_enable_event(struct perf_event *event)
{
- if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
if (!__get_cpu_var(cpu_hw_events).enabled)
return;
@@ -672,11 +685,11 @@ static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
}
if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
- intel_pmu_enable_fixed(hwc, idx);
+ intel_pmu_enable_fixed(hwc);
return;
}
- __x86_pmu_enable_event(hwc, idx);
+ __x86_pmu_enable_event(hwc);
}
/*
@@ -685,14 +698,8 @@ static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
*/
static int intel_pmu_save_and_restart(struct perf_event *event)
{
- struct hw_perf_event *hwc = &event->hw;
- int idx = hwc->idx;
- int ret;
-
- x86_perf_event_update(event, hwc, idx);
- ret = x86_perf_event_set_period(event, hwc, idx);
-
- return ret;
+ x86_perf_event_update(event);
+ return x86_perf_event_set_period(event);
}
static void intel_pmu_reset(void)
@@ -732,16 +739,15 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
int bit, loops;
u64 ack, status;
- data.addr = 0;
- data.raw = NULL;
+ perf_sample_data_init(&data, 0);
cpuc = &__get_cpu_var(cpu_hw_events);
- perf_disable();
+ intel_pmu_disable_all();
intel_pmu_drain_bts_buffer();
status = intel_pmu_get_status();
if (!status) {
- perf_enable();
+ intel_pmu_enable_all();
return 0;
}
@@ -751,16 +757,14 @@ again:
WARN_ONCE(1, "perfevents: irq loop stuck!\n");
perf_event_print_debug();
intel_pmu_reset();
- perf_enable();
- return 1;
+ goto done;
}
inc_irq_stat(apic_perf_irqs);
ack = status;
- for_each_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
+ for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
struct perf_event *event = cpuc->events[bit];
- clear_bit(bit, (unsigned long *) &status);
if (!test_bit(bit, cpuc->active_mask))
continue;
@@ -770,7 +774,7 @@ again:
data.period = event->hw.last_period;
if (perf_event_overflow(event, 1, &data, regs))
- intel_pmu_disable_event(&event->hw, bit);
+ x86_pmu_stop(event);
}
intel_pmu_ack_status(ack);
@@ -782,8 +786,8 @@ again:
if (status)
goto again;
- perf_enable();
-
+done:
+ intel_pmu_enable_all();
return 1;
}
@@ -862,7 +866,10 @@ static __initconst struct x86_pmu intel_pmu = {
.max_period = (1ULL << 31) - 1,
.enable_bts = intel_pmu_enable_bts,
.disable_bts = intel_pmu_disable_bts,
- .get_event_constraints = intel_get_event_constraints
+ .get_event_constraints = intel_get_event_constraints,
+
+ .cpu_starting = init_debug_store_on_cpu,
+ .cpu_dying = fini_debug_store_on_cpu,
};
static __init int intel_pmu_init(void)
@@ -929,13 +936,14 @@ static __init int intel_pmu_init(void)
case 26: /* 45 nm nehalem, "Bloomfield" */
case 30: /* 45 nm nehalem, "Lynnfield" */
+ case 46: /* 45 nm nehalem-ex, "Beckton" */
memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
x86_pmu.event_constraints = intel_nehalem_event_constraints;
pr_cont("Nehalem/Corei7 events, ");
break;
- case 28:
+ case 28: /* Atom */
memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
@@ -951,6 +959,7 @@ static __init int intel_pmu_init(void)
x86_pmu.event_constraints = intel_westmere_event_constraints;
pr_cont("Westmere events, ");
break;
+
default:
/*
* default constraints for v2 and up
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c
index 1ca5ba078af..a330485d14d 100644
--- a/arch/x86/kernel/cpu/perf_event_p6.c
+++ b/arch/x86/kernel/cpu/perf_event_p6.c
@@ -62,7 +62,7 @@ static void p6_pmu_disable_all(void)
/* p6 only has one enable register */
rdmsrl(MSR_P6_EVNTSEL0, val);
- val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsrl(MSR_P6_EVNTSEL0, val);
}
@@ -72,32 +72,34 @@ static void p6_pmu_enable_all(void)
/* p6 only has one enable register */
rdmsrl(MSR_P6_EVNTSEL0, val);
- val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsrl(MSR_P6_EVNTSEL0, val);
}
static inline void
-p6_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+p6_pmu_disable_event(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
u64 val = P6_NOP_EVENT;
if (cpuc->enabled)
- val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
- (void)checking_wrmsrl(hwc->config_base + idx, val);
+ (void)checking_wrmsrl(hwc->config_base + hwc->idx, val);
}
-static void p6_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void p6_pmu_enable_event(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
u64 val;
val = hwc->config;
if (cpuc->enabled)
- val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
- (void)checking_wrmsrl(hwc->config_base + idx, val);
+ (void)checking_wrmsrl(hwc->config_base + hwc->idx, val);
}
static __initconst struct x86_pmu p6_pmu = {
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index 74f4e85a572..fb329e9f849 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -680,7 +680,7 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz)
cpu_nmi_set_wd_enabled();
apic_write(APIC_LVTPC, APIC_DM_NMI);
- evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+ evntsel |= ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsr(evntsel_msr, evntsel, 0);
intel_arch_wd_ops.checkbit = 1ULL << (eax.split.bit_width - 1);
return 1;
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 1cbed97b59c..dfdb4dba232 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -22,6 +22,7 @@
*/
#include <linux/dmi.h>
+#include <linux/module.h>
#include <asm/div64.h>
#include <asm/vmware.h>
#include <asm/x86_init.h>
@@ -101,6 +102,7 @@ int vmware_platform(void)
return 0;
}
+EXPORT_SYMBOL(vmware_platform);
/*
* VMware hypervisor takes care of exporting a reliable TSC to the guest.
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 83e5e628de7..8b862d5900f 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -40,6 +40,7 @@
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <linux/uaccess.h>
+#include <linux/gfp.h>
#include <asm/processor.h>
#include <asm/msr.h>
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index a4849c10a77..ebd4c51d096 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -27,7 +27,6 @@
#include <asm/cpu.h>
#include <asm/reboot.h>
#include <asm/virtext.h>
-#include <asm/x86_init.h>
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
@@ -103,10 +102,5 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
#ifdef CONFIG_HPET_TIMER
hpet_disable();
#endif
-
-#ifdef CONFIG_X86_64
- x86_platform.iommu_shutdown();
-#endif
-
crash_save_cpu(regs, safe_smp_processor_id());
}
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c
index cd97ce18c29..67414550c3c 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -5,6 +5,7 @@
* Copyright (C) IBM Corporation, 2004. All rights reserved
*/
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/highmem.h>
#include <linux/crash_dump.h>
diff --git a/arch/x86/kernel/dumpstack.h b/arch/x86/kernel/dumpstack.h
index 4fd1420faff..e1a93be4fd4 100644
--- a/arch/x86/kernel/dumpstack.h
+++ b/arch/x86/kernel/dumpstack.h
@@ -14,6 +14,8 @@
#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
#endif
+#include <linux/uaccess.h>
+
extern void
show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
unsigned long *stack, unsigned long bp, char *log_lvl);
@@ -29,4 +31,26 @@ struct stack_frame {
struct stack_frame *next_frame;
unsigned long return_address;
};
+
+struct stack_frame_ia32 {
+ u32 next_frame;
+ u32 return_address;
+};
+
+static inline unsigned long rewind_frame_pointer(int n)
+{
+ struct stack_frame *frame;
+
+ get_bp(frame);
+
+#ifdef CONFIG_FRAME_POINTER
+ while (n--) {
+ if (probe_kernel_address(&frame->next_frame, frame))
+ break;
+ }
#endif
+
+ return (unsigned long)frame;
+}
+
+#endif /* DUMPSTACK_H */
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index dce99abb449..272c9f1f05f 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -120,9 +120,15 @@ fixup_bp_irq_link(unsigned long bp, unsigned long *stack,
{
#ifdef CONFIG_FRAME_POINTER
struct stack_frame *frame = (struct stack_frame *)bp;
+ unsigned long next;
- if (!in_irq_stack(stack, irq_stack, irq_stack_end))
- return (unsigned long)frame->next_frame;
+ if (!in_irq_stack(stack, irq_stack, irq_stack_end)) {
+ if (!probe_kernel_address(&frame->next_frame, next))
+ return next;
+ else
+ WARN_ONCE(1, "Perf: bad frame pointer = %p in "
+ "callchain\n", &frame->next_frame);
+ }
#endif
return bp;
}
@@ -202,7 +208,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
if (ops->stack(data, "IRQ") < 0)
break;
- bp = print_context_stack(tinfo, stack, bp,
+ bp = ops->walk_stack(tinfo, stack, bp,
ops, data, irq_stack_end, &graph);
/*
* We link to the next stack (which would be
@@ -223,7 +229,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
/*
* This handles the process stack:
*/
- bp = print_context_stack(tinfo, stack, bp, ops, data, NULL, &graph);
+ bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph);
put_cpu();
}
EXPORT_SYMBOL(dump_trace);
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 740b440fbd7..7bca3c6a02f 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -519,29 +519,45 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
(unsigned long long) start,
(unsigned long long) end);
- e820_print_type(old_type);
+ if (checktype)
+ e820_print_type(old_type);
printk(KERN_CONT "\n");
for (i = 0; i < e820.nr_map; i++) {
struct e820entry *ei = &e820.map[i];
u64 final_start, final_end;
+ u64 ei_end;
if (checktype && ei->type != old_type)
continue;
+
+ ei_end = ei->addr + ei->size;
/* totally covered? */
- if (ei->addr >= start &&
- (ei->addr + ei->size) <= (start + size)) {
+ if (ei->addr >= start && ei_end <= end) {
real_removed_size += ei->size;
memset(ei, 0, sizeof(struct e820entry));
continue;
}
+
+ /* new range is totally covered? */
+ if (ei->addr < start && ei_end > end) {
+ e820_add_region(end, ei_end - end, ei->type);
+ ei->size = start - ei->addr;
+ real_removed_size += size;
+ continue;
+ }
+
/* partially covered */
final_start = max(start, ei->addr);
- final_end = min(start + size, ei->addr + ei->size);
+ final_end = min(end, ei_end);
if (final_start >= final_end)
continue;
real_removed_size += final_end - final_start;
+ /*
+ * left range could be head or tail, so need to update
+ * size at first.
+ */
ei->size -= final_end - final_start;
if (ei->addr < final_start)
continue;
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index adedeef1ded..b2e24603739 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/start_kernel.h>
+#include <linux/mm.h>
#include <asm/setup.h>
#include <asm/sections.h>
@@ -44,9 +45,10 @@ void __init i386_start_kernel(void)
#ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */
if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+ /* Assume only end is not page aligned */
u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
- u64 ramdisk_end = ramdisk_image + ramdisk_size;
+ u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
}
#endif
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index b5a9896ca1e..7147143fd61 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -103,9 +103,10 @@ void __init x86_64_start_reservations(char *real_mode_data)
#ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */
if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+ /* Assume only end is not page aligned */
unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
- unsigned long ramdisk_end = ramdisk_image + ramdisk_size;
+ unsigned long ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
}
#endif
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 2d8b5035371..3d1e6f16b7a 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -27,7 +27,7 @@
#define GET_CR2_INTO_RCX movq %cr2, %rcx
#endif
-/* we are not able to switch in one step to the final KERNEL ADRESS SPACE
+/* we are not able to switch in one step to the final KERNEL ADDRESS SPACE
* because we need identity-mapped pages.
*
*/
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index ee4fa1bfcb3..23b4ecdffa9 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -4,6 +4,7 @@
#include <linux/sysdev.h>
#include <linux/delay.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/hpet.h>
#include <linux/init.h>
#include <linux/cpu.h>
@@ -399,9 +400,15 @@ static int hpet_next_event(unsigned long delta,
* then we might have a real hardware problem. We can not do
* much about it here, but at least alert the user/admin with
* a prominent warning.
+ * An erratum on some chipsets (ICH9,..), results in comparator read
+ * immediately following a write returning old value. Workaround
+ * for this is to read this value second time, when first
+ * read returns old value.
*/
- WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
+ if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
+ WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
KERN_WARNING "hpet: compare register read back failed.\n");
+ }
return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
}
@@ -1143,6 +1150,7 @@ int hpet_set_periodic_freq(unsigned long freq)
do_div(clc, freq);
clc >>= hpet_clockevent.shift;
hpet_pie_delta = clc;
+ hpet_pie_limit = 0;
}
return 1;
}
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
index dca2802c666..d6cc065f519 100644
--- a/arch/x86/kernel/hw_breakpoint.c
+++ b/arch/x86/kernel/hw_breakpoint.c
@@ -344,13 +344,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
}
/*
- * For kernel-addresses, either the address or symbol name can be
- * specified.
- */
- if (info->name)
- info->address = (unsigned long)
- kallsyms_lookup_name(info->name);
- /*
* Check that the low-order bits of the address are appropriate
* for the alignment implied by len.
*/
@@ -535,8 +528,3 @@ void hw_breakpoint_pmu_read(struct perf_event *bp)
{
/* TODO */
}
-
-void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
-{
- /* TODO */
-}
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index c01a2b846d4..54c31c28548 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/regset.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/sigcontext.h>
#include <asm/processor.h>
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 8c93a84bb62..7c9f02c130f 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -5,7 +5,6 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
@@ -34,6 +33,12 @@
static int i8259A_auto_eoi;
DEFINE_RAW_SPINLOCK(i8259A_lock);
static void mask_and_ack_8259A(unsigned int);
+static void mask_8259A(void);
+static void unmask_8259A(void);
+static void disable_8259A_irq(unsigned int irq);
+static void enable_8259A_irq(unsigned int irq);
+static void init_8259A(int auto_eoi);
+static int i8259A_irq_pending(unsigned int irq);
struct irq_chip i8259A_chip = {
.name = "XT-PIC",
@@ -63,7 +68,7 @@ unsigned int cached_irq_mask = 0xffff;
*/
unsigned long io_apic_irqs;
-void disable_8259A_irq(unsigned int irq)
+static void disable_8259A_irq(unsigned int irq)
{
unsigned int mask = 1 << irq;
unsigned long flags;
@@ -77,7 +82,7 @@ void disable_8259A_irq(unsigned int irq)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
-void enable_8259A_irq(unsigned int irq)
+static void enable_8259A_irq(unsigned int irq)
{
unsigned int mask = ~(1 << irq);
unsigned long flags;
@@ -91,7 +96,7 @@ void enable_8259A_irq(unsigned int irq)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
-int i8259A_irq_pending(unsigned int irq)
+static int i8259A_irq_pending(unsigned int irq)
{
unsigned int mask = 1<<irq;
unsigned long flags;
@@ -107,7 +112,7 @@ int i8259A_irq_pending(unsigned int irq)
return ret;
}
-void make_8259A_irq(unsigned int irq)
+static void make_8259A_irq(unsigned int irq)
{
disable_irq_nosync(irq);
io_apic_irqs &= ~(1<<irq);
@@ -281,7 +286,7 @@ static int __init i8259A_init_sysfs(void)
device_initcall(i8259A_init_sysfs);
-void mask_8259A(void)
+static void mask_8259A(void)
{
unsigned long flags;
@@ -293,7 +298,7 @@ void mask_8259A(void)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
-void unmask_8259A(void)
+static void unmask_8259A(void)
{
unsigned long flags;
@@ -305,7 +310,7 @@ void unmask_8259A(void)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
-void init_8259A(int auto_eoi)
+static void init_8259A(int auto_eoi)
{
unsigned long flags;
@@ -358,3 +363,47 @@ void init_8259A(int auto_eoi)
raw_spin_unlock_irqrestore(&i8259A_lock, flags);
}
+
+/*
+ * make i8259 a driver so that we can select pic functions at run time. the goal
+ * is to make x86 binary compatible among pc compatible and non-pc compatible
+ * platforms, such as x86 MID.
+ */
+
+static void legacy_pic_noop(void) { };
+static void legacy_pic_uint_noop(unsigned int unused) { };
+static void legacy_pic_int_noop(int unused) { };
+
+static struct irq_chip dummy_pic_chip = {
+ .name = "dummy pic",
+ .mask = legacy_pic_uint_noop,
+ .unmask = legacy_pic_uint_noop,
+ .disable = legacy_pic_uint_noop,
+ .mask_ack = legacy_pic_uint_noop,
+};
+static int legacy_pic_irq_pending_noop(unsigned int irq)
+{
+ return 0;
+}
+
+struct legacy_pic null_legacy_pic = {
+ .nr_legacy_irqs = 0,
+ .chip = &dummy_pic_chip,
+ .mask_all = legacy_pic_noop,
+ .restore_mask = legacy_pic_noop,
+ .init = legacy_pic_int_noop,
+ .irq_pending = legacy_pic_irq_pending_noop,
+ .make_irq = legacy_pic_uint_noop,
+};
+
+struct legacy_pic default_legacy_pic = {
+ .nr_legacy_irqs = NR_IRQS_LEGACY,
+ .chip = &i8259A_chip,
+ .mask_all = mask_8259A,
+ .restore_mask = unmask_8259A,
+ .init = init_8259A,
+ .irq_pending = i8259A_irq_pending,
+ .make_irq = make_8259A_irq,
+};
+
+struct legacy_pic *legacy_pic = &default_legacy_pic;
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index fce55d53263..0ed2d300cd4 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -5,7 +5,6 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/kprobes.h>
#include <linux/init.h>
@@ -99,9 +98,6 @@ int vector_used_by_percpu_irq(unsigned int vector)
return 0;
}
-/* Number of legacy interrupts */
-int nr_legacy_irqs __read_mostly = NR_IRQS_LEGACY;
-
void __init init_ISA_irqs(void)
{
int i;
@@ -109,12 +105,12 @@ void __init init_ISA_irqs(void)
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
init_bsp_APIC();
#endif
- init_8259A(0);
+ legacy_pic->init(0);
/*
* 16 old-style INTA-cycle interrupts:
*/
- for (i = 0; i < NR_IRQS_LEGACY; i++) {
+ for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) {
struct irq_desc *desc = irq_to_desc(i);
desc->status = IRQ_DISABLED;
@@ -138,12 +134,34 @@ void __init init_IRQ(void)
* then this vector space can be freed and re-used dynamically as the
* irq's migrate etc.
*/
- for (i = 0; i < nr_legacy_irqs; i++)
+ for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
per_cpu(vector_irq, 0)[IRQ0_VECTOR + i] = i;
x86_init.irqs.intr_init();
}
+/*
+ * Setup the vector to irq mappings.
+ */
+void setup_vector_irq(int cpu)
+{
+#ifndef CONFIG_X86_IO_APIC
+ int irq;
+
+ /*
+ * On most of the platforms, legacy PIC delivers the interrupts on the
+ * boot cpu. But there are certain platforms where PIC interrupts are
+ * delivered to multiple cpu's. If the legacy IRQ is handled by the
+ * legacy PIC, for the new cpu that is coming online, setup the static
+ * legacy vector to irq mapping:
+ */
+ for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
+ per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+#endif
+
+ __setup_vector_irq(cpu);
+}
+
static void __init smp_intr_init(void)
{
#ifdef CONFIG_SMP
diff --git a/arch/x86/kernel/k8.c b/arch/x86/kernel/k8.c
index cbc4332a77b..0f7bc20cfcd 100644
--- a/arch/x86/kernel/k8.c
+++ b/arch/x86/kernel/k8.c
@@ -2,8 +2,8 @@
* Shared support code for AMD K8 northbridges and derivates.
* Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2.
*/
-#include <linux/gfp.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -121,3 +121,17 @@ void k8_flush_garts(void)
}
EXPORT_SYMBOL_GPL(k8_flush_garts);
+static __init int init_k8_nbs(void)
+{
+ int err = 0;
+
+ err = cache_k8_northbridges();
+
+ if (err < 0)
+ printk(KERN_NOTICE "K8 NB: Cannot enumerate AMD northbridges.\n");
+
+ return err;
+}
+
+/* This has to go after the PCI subsystem */
+fs_initcall(init_k8_nbs);
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index e444357375c..8afd9f321f1 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -9,6 +9,7 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/stat.h>
#include <linux/io.h>
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index bfba6019d76..b2258ca9100 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -618,8 +618,8 @@ int kgdb_arch_init(void)
* portion of kgdb because this operation requires mutexs to
* complete.
*/
+ hw_breakpoint_init(&attr);
attr.bp_addr = (unsigned long)kgdb_arch_init;
- attr.type = PERF_TYPE_BREAKPOINT;
attr.bp_len = HW_BREAKPOINT_LEN_1;
attr.bp_type = HW_BREAKPOINT_W;
attr.disabled = 1;
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 5de9f4a9c3f..b43bbaebe2c 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -49,6 +49,7 @@
#include <linux/module.h>
#include <linux/kdebug.h>
#include <linux/kallsyms.h>
+#include <linux/ftrace.h>
#include <asm/cacheflush.h>
#include <asm/desc.h>
@@ -106,16 +107,22 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = {
};
const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
-/* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
-static void __kprobes set_jmp_op(void *from, void *to)
+static void __kprobes __synthesize_relative_insn(void *from, void *to, u8 op)
{
- struct __arch_jmp_op {
- char op;
+ struct __arch_relative_insn {
+ u8 op;
s32 raddr;
- } __attribute__((packed)) * jop;
- jop = (struct __arch_jmp_op *)from;
- jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
- jop->op = RELATIVEJUMP_INSTRUCTION;
+ } __attribute__((packed)) *insn;
+
+ insn = (struct __arch_relative_insn *)from;
+ insn->raddr = (s32)((long)(to) - ((long)(from) + 5));
+ insn->op = op;
+}
+
+/* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
+static void __kprobes synthesize_reljump(void *from, void *to)
+{
+ __synthesize_relative_insn(from, to, RELATIVEJUMP_OPCODE);
}
/*
@@ -202,7 +209,7 @@ static int recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr)
/*
* Basically, kp->ainsn.insn has an original instruction.
* However, RIP-relative instruction can not do single-stepping
- * at different place, fix_riprel() tweaks the displacement of
+ * at different place, __copy_instruction() tweaks the displacement of
* that instruction. In that case, we can't recover the instruction
* from the kp->ainsn.insn.
*
@@ -284,21 +291,37 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
}
/*
- * Adjust the displacement if the instruction uses the %rip-relative
- * addressing mode.
+ * Copy an instruction and adjust the displacement if the instruction
+ * uses the %rip-relative addressing mode.
* If it does, Return the address of the 32-bit displacement word.
* If not, return null.
* Only applicable to 64-bit x86.
*/
-static void __kprobes fix_riprel(struct kprobe *p)
+static int __kprobes __copy_instruction(u8 *dest, u8 *src, int recover)
{
-#ifdef CONFIG_X86_64
struct insn insn;
- kernel_insn_init(&insn, p->ainsn.insn);
+ int ret;
+ kprobe_opcode_t buf[MAX_INSN_SIZE];
+ kernel_insn_init(&insn, src);
+ if (recover) {
+ insn_get_opcode(&insn);
+ if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) {
+ ret = recover_probed_instruction(buf,
+ (unsigned long)src);
+ if (ret)
+ return 0;
+ kernel_insn_init(&insn, buf);
+ }
+ }
+ insn_get_length(&insn);
+ memcpy(dest, insn.kaddr, insn.length);
+
+#ifdef CONFIG_X86_64
if (insn_rip_relative(&insn)) {
s64 newdisp;
u8 *disp;
+ kernel_insn_init(&insn, dest);
insn_get_displacement(&insn);
/*
* The copied instruction uses the %rip-relative addressing
@@ -312,20 +335,23 @@ static void __kprobes fix_riprel(struct kprobe *p)
* extension of the original signed 32-bit displacement would
* have given.
*/
- newdisp = (u8 *) p->addr + (s64) insn.displacement.value -
- (u8 *) p->ainsn.insn;
+ newdisp = (u8 *) src + (s64) insn.displacement.value -
+ (u8 *) dest;
BUG_ON((s64) (s32) newdisp != newdisp); /* Sanity check. */
- disp = (u8 *) p->ainsn.insn + insn_offset_displacement(&insn);
+ disp = (u8 *) dest + insn_offset_displacement(&insn);
*(s32 *) disp = (s32) newdisp;
}
#endif
+ return insn.length;
}
static void __kprobes arch_copy_kprobe(struct kprobe *p)
{
- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
-
- fix_riprel(p);
+ /*
+ * Copy an instruction without recovering int3, because it will be
+ * put by another subsystem.
+ */
+ __copy_instruction(p->ainsn.insn, p->addr, 0);
if (can_boost(p->addr))
p->ainsn.boostable = 0;
@@ -406,18 +432,6 @@ static void __kprobes restore_btf(void)
update_debugctlmsr(current->thread.debugctlmsr);
}
-static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
-{
- clear_btf();
- regs->flags |= X86_EFLAGS_TF;
- regs->flags &= ~X86_EFLAGS_IF;
- /* single step inline if the instruction is an int3 */
- if (p->opcode == BREAKPOINT_INSTRUCTION)
- regs->ip = (unsigned long)p->addr;
- else
- regs->ip = (unsigned long)p->ainsn.insn;
-}
-
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
@@ -429,20 +443,50 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
*sara = (unsigned long) &kretprobe_trampoline;
}
+#ifdef CONFIG_OPTPROBES
+static int __kprobes setup_detour_execution(struct kprobe *p,
+ struct pt_regs *regs,
+ int reenter);
+#else
+#define setup_detour_execution(p, regs, reenter) (0)
+#endif
+
static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs,
- struct kprobe_ctlblk *kcb)
+ struct kprobe_ctlblk *kcb, int reenter)
{
+ if (setup_detour_execution(p, regs, reenter))
+ return;
+
#if !defined(CONFIG_PREEMPT)
if (p->ainsn.boostable == 1 && !p->post_handler) {
/* Boost up -- we can execute copied instructions directly */
- reset_current_kprobe();
+ if (!reenter)
+ reset_current_kprobe();
+ /*
+ * Reentering boosted probe doesn't reset current_kprobe,
+ * nor set current_kprobe, because it doesn't use single
+ * stepping.
+ */
regs->ip = (unsigned long)p->ainsn.insn;
preempt_enable_no_resched();
return;
}
#endif
- prepare_singlestep(p, regs);
- kcb->kprobe_status = KPROBE_HIT_SS;
+ if (reenter) {
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, regs, kcb);
+ kcb->kprobe_status = KPROBE_REENTER;
+ } else
+ kcb->kprobe_status = KPROBE_HIT_SS;
+ /* Prepare real single stepping */
+ clear_btf();
+ regs->flags |= X86_EFLAGS_TF;
+ regs->flags &= ~X86_EFLAGS_IF;
+ /* single step inline if the instruction is an int3 */
+ if (p->opcode == BREAKPOINT_INSTRUCTION)
+ regs->ip = (unsigned long)p->addr;
+ else
+ regs->ip = (unsigned long)p->ainsn.insn;
}
/*
@@ -456,11 +500,8 @@ static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
switch (kcb->kprobe_status) {
case KPROBE_HIT_SSDONE:
case KPROBE_HIT_ACTIVE:
- save_previous_kprobe(kcb);
- set_current_kprobe(p, regs, kcb);
kprobes_inc_nmissed_count(p);
- prepare_singlestep(p, regs);
- kcb->kprobe_status = KPROBE_REENTER;
+ setup_singlestep(p, regs, kcb, 1);
break;
case KPROBE_HIT_SS:
/* A probe has been hit in the codepath leading up to, or just
@@ -535,13 +576,13 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
* more here.
*/
if (!p->pre_handler || !p->pre_handler(p, regs))
- setup_singlestep(p, regs, kcb);
+ setup_singlestep(p, regs, kcb, 0);
return 1;
}
} else if (kprobe_running()) {
p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
- setup_singlestep(p, regs, kcb);
+ setup_singlestep(p, regs, kcb, 0);
return 1;
}
} /* else: not a kprobe fault; let the kernel handle it */
@@ -550,6 +591,69 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
return 0;
}
+#ifdef CONFIG_X86_64
+#define SAVE_REGS_STRING \
+ /* Skip cs, ip, orig_ax. */ \
+ " subq $24, %rsp\n" \
+ " pushq %rdi\n" \
+ " pushq %rsi\n" \
+ " pushq %rdx\n" \
+ " pushq %rcx\n" \
+ " pushq %rax\n" \
+ " pushq %r8\n" \
+ " pushq %r9\n" \
+ " pushq %r10\n" \
+ " pushq %r11\n" \
+ " pushq %rbx\n" \
+ " pushq %rbp\n" \
+ " pushq %r12\n" \
+ " pushq %r13\n" \
+ " pushq %r14\n" \
+ " pushq %r15\n"
+#define RESTORE_REGS_STRING \
+ " popq %r15\n" \
+ " popq %r14\n" \
+ " popq %r13\n" \
+ " popq %r12\n" \
+ " popq %rbp\n" \
+ " popq %rbx\n" \
+ " popq %r11\n" \
+ " popq %r10\n" \
+ " popq %r9\n" \
+ " popq %r8\n" \
+ " popq %rax\n" \
+ " popq %rcx\n" \
+ " popq %rdx\n" \
+ " popq %rsi\n" \
+ " popq %rdi\n" \
+ /* Skip orig_ax, ip, cs */ \
+ " addq $24, %rsp\n"
+#else
+#define SAVE_REGS_STRING \
+ /* Skip cs, ip, orig_ax and gs. */ \
+ " subl $16, %esp\n" \
+ " pushl %fs\n" \
+ " pushl %ds\n" \
+ " pushl %es\n" \
+ " pushl %eax\n" \
+ " pushl %ebp\n" \
+ " pushl %edi\n" \
+ " pushl %esi\n" \
+ " pushl %edx\n" \
+ " pushl %ecx\n" \
+ " pushl %ebx\n"
+#define RESTORE_REGS_STRING \
+ " popl %ebx\n" \
+ " popl %ecx\n" \
+ " popl %edx\n" \
+ " popl %esi\n" \
+ " popl %edi\n" \
+ " popl %ebp\n" \
+ " popl %eax\n" \
+ /* Skip ds, es, fs, gs, orig_ax, and ip. Note: don't pop cs here*/\
+ " addl $24, %esp\n"
+#endif
+
/*
* When a retprobed function returns, this code saves registers and
* calls trampoline_handler() runs, which calls the kretprobe's handler.
@@ -563,65 +667,16 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
/* We don't bother saving the ss register */
" pushq %rsp\n"
" pushfq\n"
- /*
- * Skip cs, ip, orig_ax.
- * trampoline_handler() will plug in these values
- */
- " subq $24, %rsp\n"
- " pushq %rdi\n"
- " pushq %rsi\n"
- " pushq %rdx\n"
- " pushq %rcx\n"
- " pushq %rax\n"
- " pushq %r8\n"
- " pushq %r9\n"
- " pushq %r10\n"
- " pushq %r11\n"
- " pushq %rbx\n"
- " pushq %rbp\n"
- " pushq %r12\n"
- " pushq %r13\n"
- " pushq %r14\n"
- " pushq %r15\n"
+ SAVE_REGS_STRING
" movq %rsp, %rdi\n"
" call trampoline_handler\n"
/* Replace saved sp with true return address. */
" movq %rax, 152(%rsp)\n"
- " popq %r15\n"
- " popq %r14\n"
- " popq %r13\n"
- " popq %r12\n"
- " popq %rbp\n"
- " popq %rbx\n"
- " popq %r11\n"
- " popq %r10\n"
- " popq %r9\n"
- " popq %r8\n"
- " popq %rax\n"
- " popq %rcx\n"
- " popq %rdx\n"
- " popq %rsi\n"
- " popq %rdi\n"
- /* Skip orig_ax, ip, cs */
- " addq $24, %rsp\n"
+ RESTORE_REGS_STRING
" popfq\n"
#else
" pushf\n"
- /*
- * Skip cs, ip, orig_ax and gs.
- * trampoline_handler() will plug in these values
- */
- " subl $16, %esp\n"
- " pushl %fs\n"
- " pushl %es\n"
- " pushl %ds\n"
- " pushl %eax\n"
- " pushl %ebp\n"
- " pushl %edi\n"
- " pushl %esi\n"
- " pushl %edx\n"
- " pushl %ecx\n"
- " pushl %ebx\n"
+ SAVE_REGS_STRING
" movl %esp, %eax\n"
" call trampoline_handler\n"
/* Move flags to cs */
@@ -629,15 +684,7 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
" movl %edx, 52(%esp)\n"
/* Replace saved flags with true return address. */
" movl %eax, 56(%esp)\n"
- " popl %ebx\n"
- " popl %ecx\n"
- " popl %edx\n"
- " popl %esi\n"
- " popl %edi\n"
- " popl %ebp\n"
- " popl %eax\n"
- /* Skip ds, es, fs, gs, orig_ax and ip */
- " addl $24, %esp\n"
+ RESTORE_REGS_STRING
" popf\n"
#endif
" ret\n");
@@ -805,8 +852,8 @@ static void __kprobes resume_execution(struct kprobe *p,
* These instructions can be executed directly if it
* jumps back to correct address.
*/
- set_jmp_op((void *)regs->ip,
- (void *)orig_ip + (regs->ip - copy_ip));
+ synthesize_reljump((void *)regs->ip,
+ (void *)orig_ip + (regs->ip - copy_ip));
p->ainsn.boostable = 1;
} else {
p->ainsn.boostable = -1;
@@ -1033,6 +1080,358 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
return 0;
}
+
+#ifdef CONFIG_OPTPROBES
+
+/* Insert a call instruction at address 'from', which calls address 'to'.*/
+static void __kprobes synthesize_relcall(void *from, void *to)
+{
+ __synthesize_relative_insn(from, to, RELATIVECALL_OPCODE);
+}
+
+/* Insert a move instruction which sets a pointer to eax/rdi (1st arg). */
+static void __kprobes synthesize_set_arg1(kprobe_opcode_t *addr,
+ unsigned long val)
+{
+#ifdef CONFIG_X86_64
+ *addr++ = 0x48;
+ *addr++ = 0xbf;
+#else
+ *addr++ = 0xb8;
+#endif
+ *(unsigned long *)addr = val;
+}
+
+void __kprobes kprobes_optinsn_template_holder(void)
+{
+ asm volatile (
+ ".global optprobe_template_entry\n"
+ "optprobe_template_entry: \n"
+#ifdef CONFIG_X86_64
+ /* We don't bother saving the ss register */
+ " pushq %rsp\n"
+ " pushfq\n"
+ SAVE_REGS_STRING
+ " movq %rsp, %rsi\n"
+ ".global optprobe_template_val\n"
+ "optprobe_template_val: \n"
+ ASM_NOP5
+ ASM_NOP5
+ ".global optprobe_template_call\n"
+ "optprobe_template_call: \n"
+ ASM_NOP5
+ /* Move flags to rsp */
+ " movq 144(%rsp), %rdx\n"
+ " movq %rdx, 152(%rsp)\n"
+ RESTORE_REGS_STRING
+ /* Skip flags entry */
+ " addq $8, %rsp\n"
+ " popfq\n"
+#else /* CONFIG_X86_32 */
+ " pushf\n"
+ SAVE_REGS_STRING
+ " movl %esp, %edx\n"
+ ".global optprobe_template_val\n"
+ "optprobe_template_val: \n"
+ ASM_NOP5
+ ".global optprobe_template_call\n"
+ "optprobe_template_call: \n"
+ ASM_NOP5
+ RESTORE_REGS_STRING
+ " addl $4, %esp\n" /* skip cs */
+ " popf\n"
+#endif
+ ".global optprobe_template_end\n"
+ "optprobe_template_end: \n");
+}
+
+#define TMPL_MOVE_IDX \
+ ((long)&optprobe_template_val - (long)&optprobe_template_entry)
+#define TMPL_CALL_IDX \
+ ((long)&optprobe_template_call - (long)&optprobe_template_entry)
+#define TMPL_END_IDX \
+ ((long)&optprobe_template_end - (long)&optprobe_template_entry)
+
+#define INT3_SIZE sizeof(kprobe_opcode_t)
+
+/* Optimized kprobe call back function: called from optinsn */
+static void __kprobes optimized_callback(struct optimized_kprobe *op,
+ struct pt_regs *regs)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ preempt_disable();
+ if (kprobe_running()) {
+ kprobes_inc_nmissed_count(&op->kp);
+ } else {
+ /* Save skipped registers */
+#ifdef CONFIG_X86_64
+ regs->cs = __KERNEL_CS;
+#else
+ regs->cs = __KERNEL_CS | get_kernel_rpl();
+ regs->gs = 0;
+#endif
+ regs->ip = (unsigned long)op->kp.addr + INT3_SIZE;
+ regs->orig_ax = ~0UL;
+
+ __get_cpu_var(current_kprobe) = &op->kp;
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+ opt_pre_handler(&op->kp, regs);
+ __get_cpu_var(current_kprobe) = NULL;
+ }
+ preempt_enable_no_resched();
+}
+
+static int __kprobes copy_optimized_instructions(u8 *dest, u8 *src)
+{
+ int len = 0, ret;
+
+ while (len < RELATIVEJUMP_SIZE) {
+ ret = __copy_instruction(dest + len, src + len, 1);
+ if (!ret || !can_boost(dest + len))
+ return -EINVAL;
+ len += ret;
+ }
+ /* Check whether the address range is reserved */
+ if (ftrace_text_reserved(src, src + len - 1) ||
+ alternatives_text_reserved(src, src + len - 1))
+ return -EBUSY;
+
+ return len;
+}
+
+/* Check whether insn is indirect jump */
+static int __kprobes insn_is_indirect_jump(struct insn *insn)
+{
+ return ((insn->opcode.bytes[0] == 0xff &&
+ (X86_MODRM_REG(insn->modrm.value) & 6) == 4) || /* Jump */
+ insn->opcode.bytes[0] == 0xea); /* Segment based jump */
+}
+
+/* Check whether insn jumps into specified address range */
+static int insn_jump_into_range(struct insn *insn, unsigned long start, int len)
+{
+ unsigned long target = 0;
+
+ switch (insn->opcode.bytes[0]) {
+ case 0xe0: /* loopne */
+ case 0xe1: /* loope */
+ case 0xe2: /* loop */
+ case 0xe3: /* jcxz */
+ case 0xe9: /* near relative jump */
+ case 0xeb: /* short relative jump */
+ break;
+ case 0x0f:
+ if ((insn->opcode.bytes[1] & 0xf0) == 0x80) /* jcc near */
+ break;
+ return 0;
+ default:
+ if ((insn->opcode.bytes[0] & 0xf0) == 0x70) /* jcc short */
+ break;
+ return 0;
+ }
+ target = (unsigned long)insn->next_byte + insn->immediate.value;
+
+ return (start <= target && target <= start + len);
+}
+
+/* Decode whole function to ensure any instructions don't jump into target */
+static int __kprobes can_optimize(unsigned long paddr)
+{
+ int ret;
+ unsigned long addr, size = 0, offset = 0;
+ struct insn insn;
+ kprobe_opcode_t buf[MAX_INSN_SIZE];
+ /* Dummy buffers for lookup_symbol_attrs */
+ static char __dummy_buf[KSYM_NAME_LEN];
+
+ /* Lookup symbol including addr */
+ if (!kallsyms_lookup(paddr, &size, &offset, NULL, __dummy_buf))
+ return 0;
+
+ /* Check there is enough space for a relative jump. */
+ if (size - offset < RELATIVEJUMP_SIZE)
+ return 0;
+
+ /* Decode instructions */
+ addr = paddr - offset;
+ while (addr < paddr - offset + size) { /* Decode until function end */
+ if (search_exception_tables(addr))
+ /*
+ * Since some fixup code will jumps into this function,
+ * we can't optimize kprobe in this function.
+ */
+ return 0;
+ kernel_insn_init(&insn, (void *)addr);
+ insn_get_opcode(&insn);
+ if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) {
+ ret = recover_probed_instruction(buf, addr);
+ if (ret)
+ return 0;
+ kernel_insn_init(&insn, buf);
+ }
+ insn_get_length(&insn);
+ /* Recover address */
+ insn.kaddr = (void *)addr;
+ insn.next_byte = (void *)(addr + insn.length);
+ /* Check any instructions don't jump into target */
+ if (insn_is_indirect_jump(&insn) ||
+ insn_jump_into_range(&insn, paddr + INT3_SIZE,
+ RELATIVE_ADDR_SIZE))
+ return 0;
+ addr += insn.length;
+ }
+
+ return 1;
+}
+
+/* Check optimized_kprobe can actually be optimized. */
+int __kprobes arch_check_optimized_kprobe(struct optimized_kprobe *op)
+{
+ int i;
+ struct kprobe *p;
+
+ for (i = 1; i < op->optinsn.size; i++) {
+ p = get_kprobe(op->kp.addr + i);
+ if (p && !kprobe_disabled(p))
+ return -EEXIST;
+ }
+
+ return 0;
+}
+
+/* Check the addr is within the optimized instructions. */
+int __kprobes arch_within_optimized_kprobe(struct optimized_kprobe *op,
+ unsigned long addr)
+{
+ return ((unsigned long)op->kp.addr <= addr &&
+ (unsigned long)op->kp.addr + op->optinsn.size > addr);
+}
+
+/* Free optimized instruction slot */
+static __kprobes
+void __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
+{
+ if (op->optinsn.insn) {
+ free_optinsn_slot(op->optinsn.insn, dirty);
+ op->optinsn.insn = NULL;
+ op->optinsn.size = 0;
+ }
+}
+
+void __kprobes arch_remove_optimized_kprobe(struct optimized_kprobe *op)
+{
+ __arch_remove_optimized_kprobe(op, 1);
+}
+
+/*
+ * Copy replacing target instructions
+ * Target instructions MUST be relocatable (checked inside)
+ */
+int __kprobes arch_prepare_optimized_kprobe(struct optimized_kprobe *op)
+{
+ u8 *buf;
+ int ret;
+ long rel;
+
+ if (!can_optimize((unsigned long)op->kp.addr))
+ return -EILSEQ;
+
+ op->optinsn.insn = get_optinsn_slot();
+ if (!op->optinsn.insn)
+ return -ENOMEM;
+
+ /*
+ * Verify if the address gap is in 2GB range, because this uses
+ * a relative jump.
+ */
+ rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
+ if (abs(rel) > 0x7fffffff)
+ return -ERANGE;
+
+ buf = (u8 *)op->optinsn.insn;
+
+ /* Copy instructions into the out-of-line buffer */
+ ret = copy_optimized_instructions(buf + TMPL_END_IDX, op->kp.addr);
+ if (ret < 0) {
+ __arch_remove_optimized_kprobe(op, 0);
+ return ret;
+ }
+ op->optinsn.size = ret;
+
+ /* Copy arch-dep-instance from template */
+ memcpy(buf, &optprobe_template_entry, TMPL_END_IDX);
+
+ /* Set probe information */
+ synthesize_set_arg1(buf + TMPL_MOVE_IDX, (unsigned long)op);
+
+ /* Set probe function call */
+ synthesize_relcall(buf + TMPL_CALL_IDX, optimized_callback);
+
+ /* Set returning jmp instruction at the tail of out-of-line buffer */
+ synthesize_reljump(buf + TMPL_END_IDX + op->optinsn.size,
+ (u8 *)op->kp.addr + op->optinsn.size);
+
+ flush_icache_range((unsigned long) buf,
+ (unsigned long) buf + TMPL_END_IDX +
+ op->optinsn.size + RELATIVEJUMP_SIZE);
+ return 0;
+}
+
+/* Replace a breakpoint (int3) with a relative jump. */
+int __kprobes arch_optimize_kprobe(struct optimized_kprobe *op)
+{
+ unsigned char jmp_code[RELATIVEJUMP_SIZE];
+ s32 rel = (s32)((long)op->optinsn.insn -
+ ((long)op->kp.addr + RELATIVEJUMP_SIZE));
+
+ /* Backup instructions which will be replaced by jump address */
+ memcpy(op->optinsn.copied_insn, op->kp.addr + INT3_SIZE,
+ RELATIVE_ADDR_SIZE);
+
+ jmp_code[0] = RELATIVEJUMP_OPCODE;
+ *(s32 *)(&jmp_code[1]) = rel;
+
+ /*
+ * text_poke_smp doesn't support NMI/MCE code modifying.
+ * However, since kprobes itself also doesn't support NMI/MCE
+ * code probing, it's not a problem.
+ */
+ text_poke_smp(op->kp.addr, jmp_code, RELATIVEJUMP_SIZE);
+ return 0;
+}
+
+/* Replace a relative jump with a breakpoint (int3). */
+void __kprobes arch_unoptimize_kprobe(struct optimized_kprobe *op)
+{
+ u8 buf[RELATIVEJUMP_SIZE];
+
+ /* Set int3 to first byte for kprobes */
+ buf[0] = BREAKPOINT_INSTRUCTION;
+ memcpy(buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE);
+ text_poke_smp(op->kp.addr, buf, RELATIVEJUMP_SIZE);
+}
+
+static int __kprobes setup_detour_execution(struct kprobe *p,
+ struct pt_regs *regs,
+ int reenter)
+{
+ struct optimized_kprobe *op;
+
+ if (p->flags & KPROBE_FLAG_OPTIMIZED) {
+ /* This kprobe is really able to run optimized path. */
+ op = container_of(p, struct optimized_kprobe, kp);
+ /* Detour through copied instructions */
+ regs->ip = (unsigned long)op->optinsn.insn + TMPL_END_IDX;
+ if (!reenter)
+ reset_current_kprobe();
+ preempt_enable_no_resched();
+ return 1;
+ }
+ return 0;
+}
+#endif
+
int __init arch_init_kprobes(void)
{
return 0;
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index ec6ef60cbd1..ea697263b37 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -7,6 +7,7 @@
*/
#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 4a8bb82248a..035c8c52918 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -9,6 +9,7 @@
#include <linux/mm.h>
#include <linux/kexec.h>
#include <linux/string.h>
+#include <linux/gfp.h>
#include <linux/reboot.h>
#include <linux/numa.h>
#include <linux/ftrace.h>
diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c
index 845d80ce1ef..63eaf659623 100644
--- a/arch/x86/kernel/mca_32.c
+++ b/arch/x86/kernel/mca_32.c
@@ -42,6 +42,7 @@
#include <linux/kernel.h>
#include <linux/mca.h>
#include <linux/kprobes.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
#include <linux/proc_fs.h>
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 89f386f044e..e0bc186d750 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/bug.h>
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/page.h>
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index a2c1edd2d3a..e81030f71a8 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -664,7 +664,7 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf)
{
unsigned long size = get_mpc_size(mpf->physptr);
- reserve_early(mpf->physptr, mpf->physptr+size, "MP-table mpc");
+ reserve_early_overlap_ok(mpf->physptr, mpf->physptr+size, "MP-table mpc");
}
static int __init smp_scan_config(unsigned long base, unsigned long length)
@@ -693,7 +693,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
mpf, (u64)virt_to_phys(mpf));
mem = virt_to_phys(mpf);
- reserve_early(mem, mem + sizeof(*mpf), "MP-table mpf");
+ reserve_early_overlap_ok(mem, mem + sizeof(*mpf), "MP-table mpf");
if (mpf->physptr)
smp_reserve_memory(mpf);
diff --git a/arch/x86/kernel/mrst.c b/arch/x86/kernel/mrst.c
index 3b7078abc87..0aad8670858 100644
--- a/arch/x86/kernel/mrst.c
+++ b/arch/x86/kernel/mrst.c
@@ -10,8 +10,211 @@
* of the License.
*/
#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sfi.h>
+#include <linux/irq.h>
+#include <linux/module.h>
#include <asm/setup.h>
+#include <asm/mpspec_def.h>
+#include <asm/hw_irq.h>
+#include <asm/apic.h>
+#include <asm/io_apic.h>
+#include <asm/mrst.h>
+#include <asm/io.h>
+#include <asm/i8259.h>
+#include <asm/apb_timer.h>
+
+static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
+static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
+int sfi_mtimer_num;
+
+struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
+EXPORT_SYMBOL_GPL(sfi_mrtc_array);
+int sfi_mrtc_num;
+
+static inline void assign_to_mp_irq(struct mpc_intsrc *m,
+ struct mpc_intsrc *mp_irq)
+{
+ memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
+}
+
+static inline int mp_irq_cmp(struct mpc_intsrc *mp_irq,
+ struct mpc_intsrc *m)
+{
+ return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
+}
+
+static void save_mp_irq(struct mpc_intsrc *m)
+{
+ int i;
+
+ for (i = 0; i < mp_irq_entries; i++) {
+ if (!mp_irq_cmp(&mp_irqs[i], m))
+ return;
+ }
+
+ assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
+ if (++mp_irq_entries == MAX_IRQ_SOURCES)
+ panic("Max # of irq sources exceeded!!\n");
+}
+
+/* parse all the mtimer info to a static mtimer array */
+static int __init sfi_parse_mtmr(struct sfi_table_header *table)
+{
+ struct sfi_table_simple *sb;
+ struct sfi_timer_table_entry *pentry;
+ struct mpc_intsrc mp_irq;
+ int totallen;
+
+ sb = (struct sfi_table_simple *)table;
+ if (!sfi_mtimer_num) {
+ sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb,
+ struct sfi_timer_table_entry);
+ pentry = (struct sfi_timer_table_entry *) sb->pentry;
+ totallen = sfi_mtimer_num * sizeof(*pentry);
+ memcpy(sfi_mtimer_array, pentry, totallen);
+ }
+
+ printk(KERN_INFO "SFI: MTIMER info (num = %d):\n", sfi_mtimer_num);
+ pentry = sfi_mtimer_array;
+ for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) {
+ printk(KERN_INFO "timer[%d]: paddr = 0x%08x, freq = %dHz,"
+ " irq = %d\n", totallen, (u32)pentry->phys_addr,
+ pentry->freq_hz, pentry->irq);
+ if (!pentry->irq)
+ continue;
+ mp_irq.type = MP_IOAPIC;
+ mp_irq.irqtype = mp_INT;
+/* triggering mode edge bit 2-3, active high polarity bit 0-1 */
+ mp_irq.irqflag = 5;
+ mp_irq.srcbus = 0;
+ mp_irq.srcbusirq = pentry->irq; /* IRQ */
+ mp_irq.dstapic = MP_APIC_ALL;
+ mp_irq.dstirq = pentry->irq;
+ save_mp_irq(&mp_irq);
+ }
+
+ return 0;
+}
+
+struct sfi_timer_table_entry *sfi_get_mtmr(int hint)
+{
+ int i;
+ if (hint < sfi_mtimer_num) {
+ if (!sfi_mtimer_usage[hint]) {
+ pr_debug("hint taken for timer %d irq %d\n",\
+ hint, sfi_mtimer_array[hint].irq);
+ sfi_mtimer_usage[hint] = 1;
+ return &sfi_mtimer_array[hint];
+ }
+ }
+ /* take the first timer available */
+ for (i = 0; i < sfi_mtimer_num;) {
+ if (!sfi_mtimer_usage[i]) {
+ sfi_mtimer_usage[i] = 1;
+ return &sfi_mtimer_array[i];
+ }
+ i++;
+ }
+ return NULL;
+}
+
+void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr)
+{
+ int i;
+ for (i = 0; i < sfi_mtimer_num;) {
+ if (mtmr->irq == sfi_mtimer_array[i].irq) {
+ sfi_mtimer_usage[i] = 0;
+ return;
+ }
+ i++;
+ }
+}
+
+/* parse all the mrtc info to a global mrtc array */
+int __init sfi_parse_mrtc(struct sfi_table_header *table)
+{
+ struct sfi_table_simple *sb;
+ struct sfi_rtc_table_entry *pentry;
+ struct mpc_intsrc mp_irq;
+
+ int totallen;
+
+ sb = (struct sfi_table_simple *)table;
+ if (!sfi_mrtc_num) {
+ sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb,
+ struct sfi_rtc_table_entry);
+ pentry = (struct sfi_rtc_table_entry *)sb->pentry;
+ totallen = sfi_mrtc_num * sizeof(*pentry);
+ memcpy(sfi_mrtc_array, pentry, totallen);
+ }
+
+ printk(KERN_INFO "SFI: RTC info (num = %d):\n", sfi_mrtc_num);
+ pentry = sfi_mrtc_array;
+ for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) {
+ printk(KERN_INFO "RTC[%d]: paddr = 0x%08x, irq = %d\n",
+ totallen, (u32)pentry->phys_addr, pentry->irq);
+ mp_irq.type = MP_IOAPIC;
+ mp_irq.irqtype = mp_INT;
+ mp_irq.irqflag = 0;
+ mp_irq.srcbus = 0;
+ mp_irq.srcbusirq = pentry->irq; /* IRQ */
+ mp_irq.dstapic = MP_APIC_ALL;
+ mp_irq.dstirq = pentry->irq;
+ save_mp_irq(&mp_irq);
+ }
+ return 0;
+}
+
+/*
+ * the secondary clock in Moorestown can be APBT or LAPIC clock, default to
+ * APBT but cmdline option can also override it.
+ */
+static void __cpuinit mrst_setup_secondary_clock(void)
+{
+ /* restore default lapic clock if disabled by cmdline */
+ if (disable_apbt_percpu)
+ return setup_secondary_APIC_clock();
+ apbt_setup_secondary_clock();
+}
+
+static unsigned long __init mrst_calibrate_tsc(void)
+{
+ unsigned long flags, fast_calibrate;
+
+ local_irq_save(flags);
+ fast_calibrate = apbt_quick_calibrate();
+ local_irq_restore(flags);
+
+ if (fast_calibrate)
+ return fast_calibrate;
+
+ return 0;
+}
+
+void __init mrst_time_init(void)
+{
+ sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr);
+ pre_init_apic_IRQ0();
+ apbt_time_init();
+}
+
+void __init mrst_rtc_init(void)
+{
+ sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
+}
+
+/*
+ * if we use per cpu apb timer, the bootclock already setup. if we use lapic
+ * timer and one apbt timer for broadcast, we need to set up lapic boot clock.
+ */
+static void __init mrst_setup_boot_clock(void)
+{
+ pr_info("%s: per cpu apbt flag %d \n", __func__, disable_apbt_percpu);
+ if (disable_apbt_percpu)
+ setup_boot_APIC_clock();
+};
/*
* Moorestown specific x86_init function overrides and early setup
@@ -21,4 +224,17 @@ void __init x86_mrst_early_setup(void)
{
x86_init.resources.probe_roms = x86_init_noop;
x86_init.resources.reserve_resources = x86_init_noop;
+
+ x86_init.timers.timer_init = mrst_time_init;
+ x86_init.timers.setup_percpu_clockev = mrst_setup_boot_clock;
+
+ x86_init.irqs.pre_vector_init = x86_init_noop;
+
+ x86_cpuinit.setup_percpu_clockev = mrst_setup_secondary_clock;
+
+ x86_platform.calibrate_tsc = mrst_calibrate_tsc;
+ x86_init.pci.init = pci_mrst_init;
+ x86_init.pci.fixup_irqs = x86_init_noop;
+
+ legacy_pic = &null_legacy_pic;
}
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 206735ac8cb..4d4468e9f47 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -37,6 +37,7 @@
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <linux/uaccess.h>
+#include <linux/gfp.h>
#include <asm/processor.h>
#include <asm/msr.h>
diff --git a/arch/x86/kernel/olpc.c b/arch/x86/kernel/olpc.c
index 9d1d263f786..8297160c41b 100644
--- a/arch/x86/kernel/olpc.c
+++ b/arch/x86/kernel/olpc.c
@@ -17,7 +17,9 @@
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/string.h>
+
#include <asm/geode.h>
+#include <asm/setup.h>
#include <asm/olpc.h>
#ifdef CONFIG_OPEN_FIRMWARE
@@ -243,9 +245,11 @@ static int __init olpc_init(void)
olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0,
(unsigned char *) &olpc_platform_info.ecver, 1);
- /* check to see if the VSA exists */
- if (cs5535_has_vsa2())
- olpc_platform_info.flags |= OLPC_F_VSA;
+#ifdef CONFIG_PCI_OLPC
+ /* If the VSA exists let it emulate PCI, if not emulate in kernel */
+ if (!cs5535_has_vsa2())
+ x86_init.pci.arch_init = pci_olpc_init;
+#endif
printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n",
((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "",
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 2bbde607814..fb99f7edb34 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -1309,7 +1309,7 @@ static void calgary_init_bitmap_from_tce_table(struct iommu_table *tbl)
/*
* get_tce_space_from_tar():
* Function for kdump case. Get the tce tables from first kernel
- * by reading the contents of the base adress register of calgary iommu
+ * by reading the contents of the base address register of calgary iommu
*/
static void __init get_tce_space_from_tar(void)
{
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 1aa966c565f..4b7e3d8b01d 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -2,6 +2,7 @@
#include <linux/dma-debug.h>
#include <linux/dmar.h>
#include <linux/bootmem.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/kmemleak.h>
@@ -38,7 +39,7 @@ int iommu_detected __read_mostly = 0;
* This variable becomes 1 if iommu=pt is passed on the kernel command line.
* If this variable is 1, IOMMU implementations do no DMA translation for
* devices and allow every device to access to whole physical memory. This is
- * useful if a user want to use an IOMMU only for KVM device assignment to
+ * useful if a user wants to use an IOMMU only for KVM device assignment to
* guests and not for driver dma translation.
*/
int iommu_pass_through __read_mostly;
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 34de53b46f8..0f7f130caa6 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -29,6 +29,7 @@
#include <linux/iommu-helper.h>
#include <linux/sysdev.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <asm/atomic.h>
#include <asm/mtrr.h>
#include <asm/pgtable.h>
@@ -564,6 +565,9 @@ static void enable_gart_translations(void)
enable_gart_translation(dev, __pa(agp_gatt_table));
}
+
+ /* Flush the GART-TLB to remove stale entries */
+ k8_flush_garts();
}
/*
@@ -735,7 +739,7 @@ int __init gart_iommu_init(void)
unsigned long scratch;
long i;
- if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0)
+ if (num_k8_northbridges == 0)
return 0;
#ifndef CONFIG_AGP_AMD64
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index 22be12b60a8..3af4af810c0 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -4,6 +4,7 @@
#include <linux/scatterlist.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/mm.h>
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 02d678065d7..28ad9f4d8b9 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -526,21 +526,37 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
}
/*
- * Check for AMD CPUs, which have potentially C1E support
+ * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e.
+ * For more information see
+ * - Erratum #400 for NPT family 0xf and family 0x10 CPUs
+ * - Erratum #365 for family 0x11 (not affected because C1e not in use)
*/
static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
{
+ u64 val;
if (c->x86_vendor != X86_VENDOR_AMD)
- return 0;
-
- if (c->x86 < 0x0F)
- return 0;
+ goto no_c1e_idle;
/* Family 0x0f models < rev F do not have C1E */
- if (c->x86 == 0x0f && c->x86_model < 0x40)
- return 0;
+ if (c->x86 == 0x0F && c->x86_model >= 0x40)
+ return 1;
- return 1;
+ if (c->x86 == 0x10) {
+ /*
+ * check OSVW bit for CPUs that are not affected
+ * by erratum #400
+ */
+ rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
+ if (val >= 2) {
+ rdmsrl(MSR_AMD64_OSVW_STATUS, val);
+ if (!(val & BIT(1)))
+ goto no_c1e_idle;
+ }
+ return 1;
+ }
+
+no_c1e_idle:
+ return 0;
}
static cpumask_var_t c1e_mask;
@@ -607,7 +623,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
{
#ifdef CONFIG_SMP
if (pm_idle == poll_idle && smp_num_siblings > 1) {
- printk(KERN_WARNING "WARNING: polling idle and HT enabled,"
+ printk_once(KERN_WARNING "WARNING: polling idle and HT enabled,"
" performance may degrade.\n");
}
#endif
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index dc9690b4c4c..17cb3295cbf 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -276,12 +276,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
set_tsk_thread_flag(p, TIF_FORK);
- p->thread.fs = me->thread.fs;
- p->thread.gs = me->thread.gs;
p->thread.io_bitmap_ptr = NULL;
savesegment(gs, p->thread.gsindex);
+ p->thread.gs = p->thread.gsindex ? 0 : me->thread.gs;
savesegment(fs, p->thread.fsindex);
+ p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
savesegment(es, p->thread.es);
savesegment(ds, p->thread.ds);
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 2d96aab82a4..2e9b55027b7 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/ptrace.h>
#include <linux/regset.h>
#include <linux/tracehook.h>
@@ -581,7 +582,7 @@ ptrace_modify_breakpoint(struct perf_event *bp, int len, int type,
struct perf_event_attr attr;
/*
- * We shoud have at least an inactive breakpoint at this
+ * We should have at least an inactive breakpoint at this
* slot. It means the user is writing dr7 without having
* written the address register first
*/
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 5d7ba1a449b..c4851eff57b 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -55,7 +55,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/user.h>
#include <linux/delay.h>
@@ -314,16 +313,17 @@ static void __init reserve_brk(void)
#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT)
static void __init relocate_initrd(void)
{
-
+ /* Assume only end is not page aligned */
u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
+ u64 area_size = PAGE_ALIGN(ramdisk_size);
u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
u64 ramdisk_here;
unsigned long slop, clen, mapaddr;
char *p, *q;
/* We need to move the initrd down into lowmem */
- ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size,
+ ramdisk_here = find_e820_area(0, end_of_lowmem, area_size,
PAGE_SIZE);
if (ramdisk_here == -1ULL)
@@ -332,7 +332,7 @@ static void __init relocate_initrd(void)
/* Note: this includes all the lowmem currently occupied by
the initrd, we rely on that fact to keep the data intact. */
- reserve_early(ramdisk_here, ramdisk_here + ramdisk_size,
+ reserve_early(ramdisk_here, ramdisk_here + area_size,
"NEW RAMDISK");
initrd_start = ramdisk_here + PAGE_OFFSET;
initrd_end = initrd_start + ramdisk_size;
@@ -376,9 +376,10 @@ static void __init relocate_initrd(void)
static void __init reserve_initrd(void)
{
+ /* Assume only end is not page aligned */
u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
- u64 ramdisk_end = ramdisk_image + ramdisk_size;
+ u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
if (!boot_params.hdr.type_of_loader ||
@@ -606,6 +607,16 @@ static int __init setup_elfcorehdr(char *arg)
early_param("elfcorehdr", setup_elfcorehdr);
#endif
+static __init void reserve_ibft_region(void)
+{
+ unsigned long addr, size = 0;
+
+ addr = find_ibft_region(&size);
+
+ if (size)
+ reserve_early_overlap_ok(addr, addr + size, "ibft");
+}
+
#ifdef CONFIG_X86_RESERVE_LOW_64K
static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
{
@@ -908,6 +919,8 @@ void __init setup_arch(char **cmdline_p)
*/
find_smp_config();
+ reserve_ibft_region();
+
reserve_trampoline_memory();
#ifdef CONFIG_ACPI_SLEEP
@@ -975,8 +988,6 @@ void __init setup_arch(char **cmdline_p)
dma32_reserve_bootmem();
- reserve_ibft_region();
-
#ifdef CONFIG_KVM_CLOCK
kvmclock_init();
#endif
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index ec1de97600e..d801210945d 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -21,6 +21,7 @@
#include <linux/cache.h>
#include <linux/interrupt.h>
#include <linux/cpu.h>
+#include <linux/gfp.h>
#include <asm/mtrr.h>
#include <asm/tlbflush.h>
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index a435c76d714..763d815e27a 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -48,6 +48,8 @@
#include <linux/err.h>
#include <linux/nmi.h>
#include <linux/tboot.h>
+#include <linux/stackprotector.h>
+#include <linux/gfp.h>
#include <asm/acpi.h>
#include <asm/desc.h>
@@ -67,6 +69,7 @@
#include <linux/mc146818rtc.h>
#include <asm/smpboot_hooks.h>
+#include <asm/i8259.h>
#ifdef CONFIG_X86_32
u8 apicid_2_node[MAX_APICID];
@@ -240,12 +243,10 @@ static void __cpuinit smp_callin(void)
end_local_APIC_setup();
map_cpu_to_logical_apicid();
- notify_cpu_starting(cpuid);
-
/*
* Need to setup vector mappings before we enable interrupts.
*/
- __setup_vector_irq(smp_processor_id());
+ setup_vector_irq(smp_processor_id());
/*
* Get our bogomips.
*
@@ -262,6 +263,8 @@ static void __cpuinit smp_callin(void)
*/
smp_store_cpu_info(cpuid);
+ notify_cpu_starting(cpuid);
+
/*
* Allow the master to continue.
*/
@@ -291,9 +294,9 @@ notrace static void __cpuinit start_secondary(void *unused)
check_tsc_sync_target();
if (nmi_watchdog == NMI_IO_APIC) {
- disable_8259A_irq(0);
+ legacy_pic->chip->mask(0);
enable_NMI_through_LVT0();
- enable_8259A_irq(0);
+ legacy_pic->chip->unmask(0);
}
#ifdef CONFIG_X86_32
@@ -329,6 +332,9 @@ notrace static void __cpuinit start_secondary(void *unused)
/* enable local interrupts */
local_irq_enable();
+ /* to prevent fake stack check failure in clock setup */
+ boot_init_stack_canary();
+
x86_cpuinit.setup_percpu_clockev();
wmb();
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
index dee1ff7cba5..196552bb412 100644
--- a/arch/x86/kernel/sys_i386_32.c
+++ b/arch/x86/kernel/sys_i386_32.c
@@ -25,191 +25,6 @@
#include <asm/syscalls.h>
/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/i386 didn't use to be able to handle more than
- * 4 system call parameters, so these system calls used a memory
- * block for parameter passing..
- */
-
-struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
-};
-
-asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
-{
- struct mmap_arg_struct a;
- int err = -EFAULT;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
-
- err = -EINVAL;
- if (a.offset & ~PAGE_MASK)
- goto out;
-
- err = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags,
- a.fd, a.offset >> PAGE_SHIFT);
-out:
- return err;
-}
-
-
-struct sel_arg_struct {
- unsigned long n;
- fd_set __user *inp, *outp, *exp;
- struct timeval __user *tvp;
-};
-
-asmlinkage int old_select(struct sel_arg_struct __user *arg)
-{
- struct sel_arg_struct a;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
- /* sys_select() does the appropriate kernel locking */
- return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-}
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage int sys_ipc(uint call, int first, int second,
- int third, void __user *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
- (const struct timespec __user *)fifth);
-
- case SEMGET:
- return sys_semget(first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void __user * __user *) ptr))
- return -EFAULT;
- return sys_semctl(first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd(first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof(tmp)))
- return -EFAULT;
- return sys_msgrcv(first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv(first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget((key_t) first, second);
- case MSGCTL:
- return sys_msgctl(first, second, (struct msqid_ds __user *) ptr);
-
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat(first, (char __user *) ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user(raddr, (ulong __user *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- /* The "(ulong *) third" is valid _only_ because of the kernel segment thing */
- return do_shmat(first, (char __user *) ptr, second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt((char __user *)ptr);
- case SHMGET:
- return sys_shmget(first, second, third);
- case SHMCTL:
- return sys_shmctl(first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -ENOSYS;
- }
-}
-
-/*
- * Old cruft
- */
-asmlinkage int sys_uname(struct old_utsname __user *name)
-{
- int err;
- if (!name)
- return -EFAULT;
- down_read(&uts_sem);
- err = copy_to_user(name, utsname(), sizeof(*name));
- up_read(&uts_sem);
- return err? -EFAULT:0;
-}
-
-asmlinkage int sys_olduname(struct oldold_utsname __user *name)
-{
- int error;
-
- if (!name)
- return -EFAULT;
- if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
-
- error = __copy_to_user(&name->sysname, &utsname()->sysname,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename, &utsname()->nodename,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->release, &utsname()->release,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->release + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->version, &utsname()->version,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->version + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine, &utsname()->machine,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->machine + __OLD_UTS_LEN);
-
- up_read(&uts_sem);
-
- error = error ? -EFAULT : 0;
-
- return error;
-}
-
-
-/*
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 8aa2057efd1..ff14a5044ce 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -209,15 +209,3 @@ bottomup:
return addr;
}
-
-
-SYSCALL_DEFINE1(uname, struct new_utsname __user *, name)
-{
- int err;
- down_read(&uts_sem);
- err = copy_to_user(name, utsname(), sizeof(*name));
- up_read(&uts_sem);
- if (personality(current->personality) == PER_LINUX32)
- err |= copy_to_user(&name->machine, "i686", 5);
- return err ? -EFAULT : 0;
-}
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index 15228b5d3eb..8b372934121 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -81,7 +81,7 @@ ENTRY(sys_call_table)
.long sys_settimeofday
.long sys_getgroups16 /* 80 */
.long sys_setgroups16
- .long old_select
+ .long sys_old_select
.long sys_symlink
.long sys_lstat
.long sys_readlink /* 85 */
@@ -89,7 +89,7 @@ ENTRY(sys_call_table)
.long sys_swapon
.long sys_reboot
.long sys_old_readdir
- .long old_mmap /* 90 */
+ .long sys_old_mmap /* 90 */
.long sys_munmap
.long sys_truncate
.long sys_ftruncate
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 364d015efeb..17b03dd3a6b 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -9,6 +9,7 @@
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <asm/mmu_context.h>
#include <asm/uv/uv.h>
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 208a857c679..9faf91ae184 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -50,7 +50,7 @@ u64 native_sched_clock(void)
* unstable. We do this because unlike Time Of Day,
* the scheduler clock tolerates small errors and it's
* very important for it to be as fast as the platform
- * can achive it. )
+ * can achieve it. )
*/
if (unlikely(tsc_disabled)) {
/* No locking but a rare wrong value is not a big deal: */
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
index ece73d8e324..1d40336b030 100644
--- a/arch/x86/kernel/uv_irq.c
+++ b/arch/x86/kernel/uv_irq.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/rbtree.h>
+#include <linux/slab.h>
#include <linux/irq.h>
#include <asm/apic.h>
diff --git a/arch/x86/kernel/uv_time.c b/arch/x86/kernel/uv_time.c
index 2b75ef638db..56e421bc379 100644
--- a/arch/x86/kernel/uv_time.c
+++ b/arch/x86/kernel/uv_time.c
@@ -19,6 +19,7 @@
* Copyright (c) Dimitri Sivanich
*/
#include <linux/clockchips.h>
+#include <linux/slab.h>
#include <asm/uv/uv_mmrs.h>
#include <asm/uv/uv_hub.h>
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index ab38ce0984f..e680ea52db9 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -49,11 +49,6 @@ extern int no_broadcast;
char visws_board_type = -1;
char visws_board_rev = -1;
-int is_visws_box(void)
-{
- return visws_board_type >= 0;
-}
-
static void __init visws_time_init(void)
{
printk(KERN_INFO "Starting Cobalt Timer system clock\n");
@@ -242,6 +237,8 @@ void __init visws_early_detect(void)
x86_init.irqs.pre_vector_init = visws_pre_intr_init;
x86_init.irqs.trap_init = visws_trap_init;
x86_init.timers.timer_init = visws_time_init;
+ x86_init.pci.init = pci_visws_init;
+ x86_init.pci.init_irq = x86_init_noop;
/*
* Install reboot quirks:
@@ -508,7 +505,7 @@ static struct irq_chip cobalt_irq_type = {
*/
static unsigned int startup_piix4_master_irq(unsigned int irq)
{
- init_8259A(0);
+ legacy_pic->init(0);
return startup_cobalt_irq(irq);
}
@@ -532,9 +529,6 @@ static struct irq_chip piix4_master_irq_type = {
static struct irq_chip piix4_virtual_irq_type = {
.name = "PIIX4-virtual",
- .shutdown = disable_8259A_irq,
- .enable = enable_8259A_irq,
- .disable = disable_8259A_irq,
};
@@ -609,7 +603,7 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id)
handle_IRQ_event(realirq, desc->action);
if (!(desc->status & IRQ_DISABLED))
- enable_8259A_irq(realirq);
+ legacy_pic->chip->unmask(realirq);
return IRQ_HANDLED;
@@ -628,6 +622,12 @@ static struct irqaction cascade_action = {
.name = "cascade",
};
+static inline void set_piix4_virtual_irq_type(void)
+{
+ piix4_virtual_irq_type.shutdown = i8259A_chip.mask;
+ piix4_virtual_irq_type.enable = i8259A_chip.unmask;
+ piix4_virtual_irq_type.disable = i8259A_chip.mask;
+}
void init_VISWS_APIC_irqs(void)
{
@@ -653,6 +653,7 @@ void init_VISWS_APIC_irqs(void)
desc->chip = &piix4_master_irq_type;
}
else if (i < CO_IRQ_APIC0) {
+ set_piix4_virtual_irq_type();
desc->chip = &piix4_virtual_irq_type;
}
else if (IS_CO_APIC(i)) {
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 7dd599deca4..ce9fbacb752 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -28,6 +28,7 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/sched.h>
+#include <linux/gfp.h>
#include <asm/vmi.h>
#include <asm/io.h>
#include <asm/fixmap.h>
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index 2f1ca561429..5e1ff66ecd7 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -167,7 +167,7 @@ static int vmi_timer_next_event(unsigned long delta,
{
/* Unfortunately, set_next_event interface only passes relative
* expiry, but we want absolute expiry. It'd be better if were
- * were passed an aboslute expiry, since a bunch of time may
+ * were passed an absolute expiry, since a bunch of time may
* have been stolen between the time the delta is computed and
* when we set the alarm below. */
cycle_t now = vmi_timer_ops.get_cycle_counter(vmi_counter(VMI_ONESHOT));
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 44879df5569..2cc249718c4 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -291,8 +291,8 @@ SECTIONS
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
__smp_locks = .;
*(.smp_locks)
- __smp_locks_end = .;
. = ALIGN(PAGE_SIZE);
+ __smp_locks_end = .;
}
#ifdef CONFIG_X86_64
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 9055e5872ff..1c0c6ab9c60 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -301,7 +301,8 @@ static int __init vsyscall_init(void)
register_sysctl_table(kernel_root_table2);
#endif
on_each_cpu(cpu_vsyscall_init, NULL, 1);
- hotcpu_notifier(cpu_vsyscall_notifier, 0);
+ /* notifier priority > KVM */
+ hotcpu_notifier(cpu_vsyscall_notifier, 30);
return 0;
}
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index ee5746c9462..61a1e8c7e19 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -4,9 +4,11 @@
* For licencing details see kernel-base/COPYING
*/
#include <linux/init.h>
+#include <linux/ioport.h>
#include <asm/bios_ebda.h>
#include <asm/paravirt.h>
+#include <asm/pci_x86.h>
#include <asm/mpspec.h>
#include <asm/setup.h>
#include <asm/apic.h>
@@ -70,6 +72,12 @@ struct x86_init_ops x86_init __initdata = {
.iommu = {
.iommu_init = iommu_init_noop,
},
+
+ .pci = {
+ .init = x86_default_pci_init,
+ .init_irq = x86_default_pci_init_irq,
+ .fixup_irqs = x86_default_pci_fixup_irqs,
+ },
};
struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 3c4d0109ad2..970bbd47951 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -29,6 +29,7 @@ config KVM
select HAVE_KVM_EVENTFD
select KVM_APIC_ARCHITECTURE
select USER_RETURN_NOTIFIER
+ select KVM_MMIO
---help---
Support hosting fully virtualized guest machines using hardware
virtualization extensions. You will need a fairly recent
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 7e8faea4651..4dade6ac082 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -32,7 +32,7 @@
#include <linux/module.h>
#include <asm/kvm_emulate.h>
-#include "mmu.h" /* for is_long_mode() */
+#include "x86.h"
/*
* Opcode effective-address decode tables.
@@ -76,6 +76,8 @@
#define GroupDual (1<<15) /* Alternate decoding of mod == 3 */
#define GroupMask 0xff /* Group number stored in bits 0:7 */
/* Misc flags */
+#define Lock (1<<26) /* lock prefix is allowed for the instruction */
+#define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */
#define No64 (1<<28)
/* Source 2 operand type */
#define Src2None (0<<29)
@@ -88,39 +90,40 @@
enum {
Group1_80, Group1_81, Group1_82, Group1_83,
Group1A, Group3_Byte, Group3, Group4, Group5, Group7,
+ Group8, Group9,
};
static u32 opcode_table[256] = {
/* 0x00 - 0x07 */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
/* 0x08 - 0x0F */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
ImplicitOps | Stack | No64, 0,
/* 0x10 - 0x17 */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
/* 0x18 - 0x1F */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
/* 0x20 - 0x27 */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
/* 0x28 - 0x2F */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
0, 0, 0, 0,
/* 0x30 - 0x37 */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
0, 0, 0, 0,
/* 0x38 - 0x3F */
@@ -156,7 +159,7 @@ static u32 opcode_table[256] = {
Group | Group1_80, Group | Group1_81,
Group | Group1_82, Group | Group1_83,
ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
/* 0x88 - 0x8F */
ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
@@ -210,7 +213,7 @@ static u32 opcode_table[256] = {
SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
/* 0xF0 - 0xF7 */
0, 0, 0, 0,
- ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3,
+ ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3,
/* 0xF8 - 0xFF */
ImplicitOps, 0, ImplicitOps, ImplicitOps,
ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
@@ -218,16 +221,20 @@ static u32 opcode_table[256] = {
static u32 twobyte_table[256] = {
/* 0x00 - 0x0F */
- 0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0,
- ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
+ 0, Group | GroupDual | Group7, 0, 0,
+ 0, ImplicitOps, ImplicitOps | Priv, 0,
+ ImplicitOps | Priv, ImplicitOps | Priv, 0, 0,
+ 0, ImplicitOps | ModRM, 0, 0,
/* 0x10 - 0x1F */
0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
/* 0x20 - 0x2F */
- ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
+ ModRM | ImplicitOps | Priv, ModRM | Priv,
+ ModRM | ImplicitOps | Priv, ModRM | Priv,
+ 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
/* 0x30 - 0x3F */
- ImplicitOps, 0, ImplicitOps, 0,
- ImplicitOps, ImplicitOps, 0, 0,
+ ImplicitOps | Priv, 0, ImplicitOps | Priv, 0,
+ ImplicitOps, ImplicitOps | Priv, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
/* 0x40 - 0x47 */
DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
@@ -257,21 +264,23 @@ static u32 twobyte_table[256] = {
DstMem | SrcReg | Src2CL | ModRM, 0, 0,
/* 0xA8 - 0xAF */
ImplicitOps | Stack, ImplicitOps | Stack,
- 0, DstMem | SrcReg | ModRM | BitOp,
+ 0, DstMem | SrcReg | ModRM | BitOp | Lock,
DstMem | SrcReg | Src2ImmByte | ModRM,
DstMem | SrcReg | Src2CL | ModRM,
ModRM, 0,
/* 0xB0 - 0xB7 */
- ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0,
- DstMem | SrcReg | ModRM | BitOp,
+ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
+ 0, DstMem | SrcReg | ModRM | BitOp | Lock,
0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
DstReg | SrcMem16 | ModRM | Mov,
/* 0xB8 - 0xBF */
- 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp,
+ 0, 0,
+ Group | Group8, DstMem | SrcReg | ModRM | BitOp | Lock,
0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
DstReg | SrcMem16 | ModRM | Mov,
/* 0xC0 - 0xCF */
- 0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
+ 0, 0, 0, DstMem | SrcReg | ModRM | Mov,
+ 0, 0, 0, Group | GroupDual | Group9,
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xD0 - 0xDF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -283,25 +292,41 @@ static u32 twobyte_table[256] = {
static u32 group_table[] = {
[Group1_80*8] =
- ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
- ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
- ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
- ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+ ByteOp | DstMem | SrcImm | ModRM | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | Lock,
+ ByteOp | DstMem | SrcImm | ModRM,
[Group1_81*8] =
- DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
- DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
- DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
- DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
+ DstMem | SrcImm | ModRM | Lock,
+ DstMem | SrcImm | ModRM | Lock,
+ DstMem | SrcImm | ModRM | Lock,
+ DstMem | SrcImm | ModRM | Lock,
+ DstMem | SrcImm | ModRM | Lock,
+ DstMem | SrcImm | ModRM | Lock,
+ DstMem | SrcImm | ModRM | Lock,
+ DstMem | SrcImm | ModRM,
[Group1_82*8] =
- ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
- ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
- ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
- ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+ ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | No64 | Lock,
+ ByteOp | DstMem | SrcImm | ModRM | No64,
[Group1_83*8] =
- DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
- DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
- DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
- DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
+ DstMem | SrcImmByte | ModRM | Lock,
+ DstMem | SrcImmByte | ModRM | Lock,
+ DstMem | SrcImmByte | ModRM | Lock,
+ DstMem | SrcImmByte | ModRM | Lock,
+ DstMem | SrcImmByte | ModRM | Lock,
+ DstMem | SrcImmByte | ModRM | Lock,
+ DstMem | SrcImmByte | ModRM | Lock,
+ DstMem | SrcImmByte | ModRM,
[Group1A*8] =
DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0,
[Group3_Byte*8] =
@@ -320,24 +345,39 @@ static u32 group_table[] = {
SrcMem | ModRM | Stack, 0,
SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0,
[Group7*8] =
- 0, 0, ModRM | SrcMem, ModRM | SrcMem,
+ 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv,
SrcNone | ModRM | DstMem | Mov, 0,
- SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp,
+ SrcMem16 | ModRM | Mov | Priv, SrcMem | ModRM | ByteOp | Priv,
+ [Group8*8] =
+ 0, 0, 0, 0,
+ DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock,
+ DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock,
+ [Group9*8] =
+ 0, ImplicitOps | ModRM | Lock, 0, 0, 0, 0, 0, 0,
};
static u32 group2_table[] = {
[Group7*8] =
- SrcNone | ModRM, 0, 0, SrcNone | ModRM,
+ SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM,
SrcNone | ModRM | DstMem | Mov, 0,
SrcMem16 | ModRM | Mov, 0,
+ [Group9*8] =
+ 0, 0, 0, 0, 0, 0, 0, 0,
};
/* EFLAGS bit definitions. */
+#define EFLG_ID (1<<21)
+#define EFLG_VIP (1<<20)
+#define EFLG_VIF (1<<19)
+#define EFLG_AC (1<<18)
#define EFLG_VM (1<<17)
#define EFLG_RF (1<<16)
+#define EFLG_IOPL (3<<12)
+#define EFLG_NT (1<<14)
#define EFLG_OF (1<<11)
#define EFLG_DF (1<<10)
#define EFLG_IF (1<<9)
+#define EFLG_TF (1<<8)
#define EFLG_SF (1<<7)
#define EFLG_ZF (1<<6)
#define EFLG_AF (1<<4)
@@ -606,7 +646,7 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
if (linear < fc->start || linear >= fc->end) {
size = min(15UL, PAGE_SIZE - offset_in_page(linear));
- rc = ops->read_std(linear, fc->data, size, ctxt->vcpu);
+ rc = ops->fetch(linear, fc->data, size, ctxt->vcpu, NULL);
if (rc)
return rc;
fc->start = linear;
@@ -661,11 +701,11 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
op_bytes = 3;
*address = 0;
rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
- ctxt->vcpu);
+ ctxt->vcpu, NULL);
if (rc)
return rc;
rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
- ctxt->vcpu);
+ ctxt->vcpu, NULL);
return rc;
}
@@ -889,6 +929,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
switch (mode) {
case X86EMUL_MODE_REAL:
+ case X86EMUL_MODE_VM86:
case X86EMUL_MODE_PROT16:
def_op_bytes = def_ad_bytes = 2;
break;
@@ -975,7 +1016,7 @@ done_prefixes:
}
if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) {
- kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction");;
+ kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction");
return -1;
}
@@ -1196,13 +1237,56 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,
rc = ops->read_emulated(register_address(c, ss_base(ctxt),
c->regs[VCPU_REGS_RSP]),
dest, len, ctxt->vcpu);
- if (rc != 0)
+ if (rc != X86EMUL_CONTINUE)
return rc;
register_address_increment(c, &c->regs[VCPU_REGS_RSP], len);
return rc;
}
+static int emulate_popf(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops,
+ void *dest, int len)
+{
+ int rc;
+ unsigned long val, change_mask;
+ int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+ int cpl = kvm_x86_ops->get_cpl(ctxt->vcpu);
+
+ rc = emulate_pop(ctxt, ops, &val, len);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ change_mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_OF
+ | EFLG_TF | EFLG_DF | EFLG_NT | EFLG_RF | EFLG_AC | EFLG_ID;
+
+ switch(ctxt->mode) {
+ case X86EMUL_MODE_PROT64:
+ case X86EMUL_MODE_PROT32:
+ case X86EMUL_MODE_PROT16:
+ if (cpl == 0)
+ change_mask |= EFLG_IOPL;
+ if (cpl <= iopl)
+ change_mask |= EFLG_IF;
+ break;
+ case X86EMUL_MODE_VM86:
+ if (iopl < 3) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ return X86EMUL_PROPAGATE_FAULT;
+ }
+ change_mask |= EFLG_IF;
+ break;
+ default: /* real mode */
+ change_mask |= (EFLG_IOPL | EFLG_IF);
+ break;
+ }
+
+ *(unsigned long *)dest =
+ (ctxt->eflags & ~change_mask) | (val & change_mask);
+
+ return rc;
+}
+
static void emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg)
{
struct decode_cache *c = &ctxt->decode;
@@ -1225,7 +1309,7 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
if (rc != 0)
return rc;
- rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg);
+ rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, seg);
return rc;
}
@@ -1370,7 +1454,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
int rc;
rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu);
- if (rc != 0)
+ if (rc != X86EMUL_CONTINUE)
return rc;
if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
@@ -1385,7 +1469,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
(u32) c->regs[VCPU_REGS_RBX];
rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu);
- if (rc != 0)
+ if (rc != X86EMUL_CONTINUE)
return rc;
ctxt->eflags |= EFLG_ZF;
}
@@ -1407,7 +1491,7 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
if (rc)
return rc;
- rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS);
+ rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, VCPU_SREG_CS);
return rc;
}
@@ -1451,7 +1535,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
&c->dst.val,
c->dst.bytes,
ctxt->vcpu);
- if (rc != 0)
+ if (rc != X86EMUL_CONTINUE)
return rc;
break;
case OP_NONE:
@@ -1514,9 +1598,8 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt)
u64 msr_data;
/* syscall is not available in real mode */
- if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL
- || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE))
- return -1;
+ if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86)
+ return X86EMUL_UNHANDLEABLE;
setup_syscalls_segments(ctxt, &cs, &ss);
@@ -1553,7 +1636,7 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt)
ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
}
- return 0;
+ return X86EMUL_CONTINUE;
}
static int
@@ -1563,22 +1646,17 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt)
struct kvm_segment cs, ss;
u64 msr_data;
- /* inject #UD if LOCK prefix is used */
- if (c->lock_prefix)
- return -1;
-
- /* inject #GP if in real mode or paging is disabled */
- if (ctxt->mode == X86EMUL_MODE_REAL ||
- !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
+ /* inject #GP if in real mode */
+ if (ctxt->mode == X86EMUL_MODE_REAL) {
kvm_inject_gp(ctxt->vcpu, 0);
- return -1;
+ return X86EMUL_UNHANDLEABLE;
}
/* XXX sysenter/sysexit have not been tested in 64bit mode.
* Therefore, we inject an #UD.
*/
if (ctxt->mode == X86EMUL_MODE_PROT64)
- return -1;
+ return X86EMUL_UNHANDLEABLE;
setup_syscalls_segments(ctxt, &cs, &ss);
@@ -1587,13 +1665,13 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt)
case X86EMUL_MODE_PROT32:
if ((msr_data & 0xfffc) == 0x0) {
kvm_inject_gp(ctxt->vcpu, 0);
- return -1;
+ return X86EMUL_PROPAGATE_FAULT;
}
break;
case X86EMUL_MODE_PROT64:
if (msr_data == 0x0) {
kvm_inject_gp(ctxt->vcpu, 0);
- return -1;
+ return X86EMUL_PROPAGATE_FAULT;
}
break;
}
@@ -1618,7 +1696,7 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt)
kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data);
c->regs[VCPU_REGS_RSP] = msr_data;
- return 0;
+ return X86EMUL_CONTINUE;
}
static int
@@ -1629,21 +1707,11 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
u64 msr_data;
int usermode;
- /* inject #UD if LOCK prefix is used */
- if (c->lock_prefix)
- return -1;
-
- /* inject #GP if in real mode or paging is disabled */
- if (ctxt->mode == X86EMUL_MODE_REAL
- || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
- kvm_inject_gp(ctxt->vcpu, 0);
- return -1;
- }
-
- /* sysexit must be called from CPL 0 */
- if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) {
+ /* inject #GP if in real mode or Virtual 8086 mode */
+ if (ctxt->mode == X86EMUL_MODE_REAL ||
+ ctxt->mode == X86EMUL_MODE_VM86) {
kvm_inject_gp(ctxt->vcpu, 0);
- return -1;
+ return X86EMUL_UNHANDLEABLE;
}
setup_syscalls_segments(ctxt, &cs, &ss);
@@ -1661,7 +1729,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
cs.selector = (u16)(msr_data + 16);
if ((msr_data & 0xfffc) == 0x0) {
kvm_inject_gp(ctxt->vcpu, 0);
- return -1;
+ return X86EMUL_PROPAGATE_FAULT;
}
ss.selector = (u16)(msr_data + 24);
break;
@@ -1669,7 +1737,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
cs.selector = (u16)(msr_data + 32);
if (msr_data == 0x0) {
kvm_inject_gp(ctxt->vcpu, 0);
- return -1;
+ return X86EMUL_PROPAGATE_FAULT;
}
ss.selector = cs.selector + 8;
cs.db = 0;
@@ -1685,7 +1753,58 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt)
c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX];
c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX];
- return 0;
+ return X86EMUL_CONTINUE;
+}
+
+static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt)
+{
+ int iopl;
+ if (ctxt->mode == X86EMUL_MODE_REAL)
+ return false;
+ if (ctxt->mode == X86EMUL_MODE_VM86)
+ return true;
+ iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+ return kvm_x86_ops->get_cpl(ctxt->vcpu) > iopl;
+}
+
+static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops,
+ u16 port, u16 len)
+{
+ struct kvm_segment tr_seg;
+ int r;
+ u16 io_bitmap_ptr;
+ u8 perm, bit_idx = port & 0x7;
+ unsigned mask = (1 << len) - 1;
+
+ kvm_get_segment(ctxt->vcpu, &tr_seg, VCPU_SREG_TR);
+ if (tr_seg.unusable)
+ return false;
+ if (tr_seg.limit < 103)
+ return false;
+ r = ops->read_std(tr_seg.base + 102, &io_bitmap_ptr, 2, ctxt->vcpu,
+ NULL);
+ if (r != X86EMUL_CONTINUE)
+ return false;
+ if (io_bitmap_ptr + port/8 > tr_seg.limit)
+ return false;
+ r = ops->read_std(tr_seg.base + io_bitmap_ptr + port/8, &perm, 1,
+ ctxt->vcpu, NULL);
+ if (r != X86EMUL_CONTINUE)
+ return false;
+ if ((perm >> bit_idx) & mask)
+ return false;
+ return true;
+}
+
+static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops,
+ u16 port, u16 len)
+{
+ if (emulator_bad_iopl(ctxt))
+ if (!emulator_io_port_access_allowed(ctxt, ops, port, len))
+ return false;
+ return true;
}
int
@@ -1709,6 +1828,18 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
saved_eip = c->eip;
+ /* LOCK prefix is allowed only with some instructions */
+ if (c->lock_prefix && !(c->d & Lock)) {
+ kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
+ goto done;
+ }
+
+ /* Privileged instruction can be executed only in CPL=0 */
+ if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ goto done;
+ }
+
if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs))
memop = c->modrm_ea;
@@ -1749,7 +1880,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
&c->src.val,
c->src.bytes,
ctxt->vcpu);
- if (rc != 0)
+ if (rc != X86EMUL_CONTINUE)
goto done;
c->src.orig_val = c->src.val;
}
@@ -1768,12 +1899,15 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
c->dst.ptr = (void *)c->dst.ptr +
(c->src.val & mask) / 8;
}
- if (!(c->d & Mov) &&
- /* optimisation - avoid slow emulated read */
- ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
- &c->dst.val,
- c->dst.bytes, ctxt->vcpu)) != 0))
- goto done;
+ if (!(c->d & Mov)) {
+ /* optimisation - avoid slow emulated read */
+ rc = ops->read_emulated((unsigned long)c->dst.ptr,
+ &c->dst.val,
+ c->dst.bytes,
+ ctxt->vcpu);
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+ }
}
c->dst.orig_val = c->dst.val;
@@ -1876,7 +2010,12 @@ special_insn:
break;
case 0x6c: /* insb */
case 0x6d: /* insw/insd */
- if (kvm_emulate_pio_string(ctxt->vcpu,
+ if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX],
+ (c->d & ByteOp) ? 1 : c->op_bytes)) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ goto done;
+ }
+ if (kvm_emulate_pio_string(ctxt->vcpu,
1,
(c->d & ByteOp) ? 1 : c->op_bytes,
c->rep_prefix ?
@@ -1892,6 +2031,11 @@ special_insn:
return 0;
case 0x6e: /* outsb */
case 0x6f: /* outsw/outsd */
+ if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX],
+ (c->d & ByteOp) ? 1 : c->op_bytes)) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ goto done;
+ }
if (kvm_emulate_pio_string(ctxt->vcpu,
0,
(c->d & ByteOp) ? 1 : c->op_bytes,
@@ -1978,25 +2122,19 @@ special_insn:
break;
case 0x8e: { /* mov seg, r/m16 */
uint16_t sel;
- int type_bits;
- int err;
sel = c->src.val;
- if (c->modrm_reg == VCPU_SREG_SS)
- toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);
- if (c->modrm_reg <= 5) {
- type_bits = (c->modrm_reg == 1) ? 9 : 1;
- err = kvm_load_segment_descriptor(ctxt->vcpu, sel,
- type_bits, c->modrm_reg);
- } else {
- printk(KERN_INFO "Invalid segreg in modrm byte 0x%02x\n",
- c->modrm);
- goto cannot_emulate;
+ if (c->modrm_reg == VCPU_SREG_CS ||
+ c->modrm_reg > VCPU_SREG_GS) {
+ kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
+ goto done;
}
- if (err < 0)
- goto cannot_emulate;
+ if (c->modrm_reg == VCPU_SREG_SS)
+ toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);
+
+ rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg);
c->dst.type = OP_NONE; /* Disable writeback. */
break;
@@ -2025,7 +2163,10 @@ special_insn:
c->dst.type = OP_REG;
c->dst.ptr = (unsigned long *) &ctxt->eflags;
c->dst.bytes = c->op_bytes;
- goto pop_instruction;
+ rc = emulate_popf(ctxt, ops, &c->dst.val, c->op_bytes);
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+ break;
case 0xa0 ... 0xa1: /* mov */
c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
c->dst.val = c->src.val;
@@ -2039,11 +2180,12 @@ special_insn:
c->dst.ptr = (unsigned long *)register_address(c,
es_base(ctxt),
c->regs[VCPU_REGS_RDI]);
- if ((rc = ops->read_emulated(register_address(c,
- seg_override_base(ctxt, c),
- c->regs[VCPU_REGS_RSI]),
+ rc = ops->read_emulated(register_address(c,
+ seg_override_base(ctxt, c),
+ c->regs[VCPU_REGS_RSI]),
&c->dst.val,
- c->dst.bytes, ctxt->vcpu)) != 0)
+ c->dst.bytes, ctxt->vcpu);
+ if (rc != X86EMUL_CONTINUE)
goto done;
register_address_increment(c, &c->regs[VCPU_REGS_RSI],
(ctxt->eflags & EFLG_DF) ? -c->dst.bytes
@@ -2058,10 +2200,11 @@ special_insn:
c->src.ptr = (unsigned long *)register_address(c,
seg_override_base(ctxt, c),
c->regs[VCPU_REGS_RSI]);
- if ((rc = ops->read_emulated((unsigned long)c->src.ptr,
- &c->src.val,
- c->src.bytes,
- ctxt->vcpu)) != 0)
+ rc = ops->read_emulated((unsigned long)c->src.ptr,
+ &c->src.val,
+ c->src.bytes,
+ ctxt->vcpu);
+ if (rc != X86EMUL_CONTINUE)
goto done;
c->dst.type = OP_NONE; /* Disable writeback. */
@@ -2069,10 +2212,11 @@ special_insn:
c->dst.ptr = (unsigned long *)register_address(c,
es_base(ctxt),
c->regs[VCPU_REGS_RDI]);
- if ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
- &c->dst.val,
- c->dst.bytes,
- ctxt->vcpu)) != 0)
+ rc = ops->read_emulated((unsigned long)c->dst.ptr,
+ &c->dst.val,
+ c->dst.bytes,
+ ctxt->vcpu);
+ if (rc != X86EMUL_CONTINUE)
goto done;
DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr);
@@ -2102,12 +2246,13 @@ special_insn:
c->dst.type = OP_REG;
c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
- if ((rc = ops->read_emulated(register_address(c,
- seg_override_base(ctxt, c),
- c->regs[VCPU_REGS_RSI]),
- &c->dst.val,
- c->dst.bytes,
- ctxt->vcpu)) != 0)
+ rc = ops->read_emulated(register_address(c,
+ seg_override_base(ctxt, c),
+ c->regs[VCPU_REGS_RSI]),
+ &c->dst.val,
+ c->dst.bytes,
+ ctxt->vcpu);
+ if (rc != X86EMUL_CONTINUE)
goto done;
register_address_increment(c, &c->regs[VCPU_REGS_RSI],
(ctxt->eflags & EFLG_DF) ? -c->dst.bytes
@@ -2163,11 +2308,9 @@ special_insn:
case 0xe9: /* jmp rel */
goto jmp;
case 0xea: /* jmp far */
- if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9,
- VCPU_SREG_CS) < 0) {
- DPRINTF("jmp far: Failed to load CS descriptor\n");
- goto cannot_emulate;
- }
+ if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val,
+ VCPU_SREG_CS))
+ goto done;
c->eip = c->src.val;
break;
@@ -2185,7 +2328,13 @@ special_insn:
case 0xef: /* out (e/r)ax,dx */
port = c->regs[VCPU_REGS_RDX];
io_dir_in = 0;
- do_io: if (kvm_emulate_pio(ctxt->vcpu, io_dir_in,
+ do_io:
+ if (!emulator_io_permited(ctxt, ops, port,
+ (c->d & ByteOp) ? 1 : c->op_bytes)) {
+ kvm_inject_gp(ctxt->vcpu, 0);
+ goto done;
+ }
+ if (kvm_emulate_pio(ctxt->vcpu, io_dir_in,
(c->d & ByteOp) ? 1 : c->op_bytes,
port) != 0) {
c->eip = saved_eip;
@@ -2210,13 +2359,21 @@ special_insn:
c->dst.type = OP_NONE; /* Disable writeback. */
break;
case 0xfa: /* cli */
- ctxt->eflags &= ~X86_EFLAGS_IF;
- c->dst.type = OP_NONE; /* Disable writeback. */
+ if (emulator_bad_iopl(ctxt))
+ kvm_inject_gp(ctxt->vcpu, 0);
+ else {
+ ctxt->eflags &= ~X86_EFLAGS_IF;
+ c->dst.type = OP_NONE; /* Disable writeback. */
+ }
break;
case 0xfb: /* sti */
- toggle_interruptibility(ctxt, X86_SHADOW_INT_STI);
- ctxt->eflags |= X86_EFLAGS_IF;
- c->dst.type = OP_NONE; /* Disable writeback. */
+ if (emulator_bad_iopl(ctxt))
+ kvm_inject_gp(ctxt->vcpu, 0);
+ else {
+ toggle_interruptibility(ctxt, X86_SHADOW_INT_STI);
+ ctxt->eflags |= X86_EFLAGS_IF;
+ c->dst.type = OP_NONE; /* Disable writeback. */
+ }
break;
case 0xfc: /* cld */
ctxt->eflags &= ~EFLG_DF;
@@ -2319,8 +2476,9 @@ twobyte_insn:
}
break;
case 0x05: /* syscall */
- if (emulate_syscall(ctxt) == -1)
- goto cannot_emulate;
+ rc = emulate_syscall(ctxt);
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
else
goto writeback;
break;
@@ -2391,14 +2549,16 @@ twobyte_insn:
c->dst.type = OP_NONE;
break;
case 0x34: /* sysenter */
- if (emulate_sysenter(ctxt) == -1)
- goto cannot_emulate;
+ rc = emulate_sysenter(ctxt);
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
else
goto writeback;
break;
case 0x35: /* sysexit */
- if (emulate_sysexit(ctxt) == -1)
- goto cannot_emulate;
+ rc = emulate_sysexit(ctxt);
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
else
goto writeback;
break;
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 15578f180e5..0150affad25 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -32,6 +32,7 @@
#define pr_fmt(fmt) "pit: " fmt
#include <linux/kvm_host.h>
+#include <linux/slab.h>
#include "irq.h"
#include "i8254.h"
@@ -242,11 +243,11 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
{
struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state,
irq_ack_notifier);
- spin_lock(&ps->inject_lock);
+ raw_spin_lock(&ps->inject_lock);
if (atomic_dec_return(&ps->pit_timer.pending) < 0)
atomic_inc(&ps->pit_timer.pending);
ps->irq_ack = 1;
- spin_unlock(&ps->inject_lock);
+ raw_spin_unlock(&ps->inject_lock);
}
void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
@@ -605,7 +606,7 @@ static const struct kvm_io_device_ops speaker_dev_ops = {
.write = speaker_ioport_write,
};
-/* Caller must have writers lock on slots_lock */
+/* Caller must hold slots_lock */
struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
{
struct kvm_pit *pit;
@@ -624,7 +625,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
mutex_init(&pit->pit_state.lock);
mutex_lock(&pit->pit_state.lock);
- spin_lock_init(&pit->pit_state.inject_lock);
+ raw_spin_lock_init(&pit->pit_state.inject_lock);
kvm->arch.vpit = pit;
pit->kvm = kvm;
@@ -645,13 +646,13 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
kvm_iodevice_init(&pit->dev, &pit_dev_ops);
- ret = __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
+ ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, &pit->dev);
if (ret < 0)
goto fail;
if (flags & KVM_PIT_SPEAKER_DUMMY) {
kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops);
- ret = __kvm_io_bus_register_dev(&kvm->pio_bus,
+ ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS,
&pit->speaker_dev);
if (ret < 0)
goto fail_unregister;
@@ -660,11 +661,12 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
return pit;
fail_unregister:
- __kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->dev);
+ kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &pit->dev);
fail:
- if (pit->irq_source_id >= 0)
- kvm_free_irq_source_id(kvm, pit->irq_source_id);
+ kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
+ kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
+ kvm_free_irq_source_id(kvm, pit->irq_source_id);
kfree(pit);
return NULL;
@@ -723,12 +725,12 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
/* Try to inject pending interrupts when
* last one has been acked.
*/
- spin_lock(&ps->inject_lock);
+ raw_spin_lock(&ps->inject_lock);
if (atomic_read(&ps->pit_timer.pending) && ps->irq_ack) {
ps->irq_ack = 0;
inject = 1;
}
- spin_unlock(&ps->inject_lock);
+ raw_spin_unlock(&ps->inject_lock);
if (inject)
__inject_pit_timer_intr(kvm);
}
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index d4c1c7ffdc0..900d6b0ba7c 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -27,7 +27,7 @@ struct kvm_kpit_state {
u32 speaker_data_on;
struct mutex lock;
struct kvm_pit *pit;
- spinlock_t inject_lock;
+ raw_spinlock_t inject_lock;
unsigned long irq_ack;
struct kvm_irq_ack_notifier irq_ack_notifier;
};
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index d057c0cbd24..a790fa128a9 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -26,6 +26,7 @@
* Port from Qemu.
*/
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/bitops.h>
#include "irq.h"
@@ -44,18 +45,19 @@ static void pic_clear_isr(struct kvm_kpic_state *s, int irq)
* Other interrupt may be delivered to PIC while lock is dropped but
* it should be safe since PIC state is already updated at this stage.
*/
- spin_unlock(&s->pics_state->lock);
+ raw_spin_unlock(&s->pics_state->lock);
kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq);
- spin_lock(&s->pics_state->lock);
+ raw_spin_lock(&s->pics_state->lock);
}
void kvm_pic_clear_isr_ack(struct kvm *kvm)
{
struct kvm_pic *s = pic_irqchip(kvm);
- spin_lock(&s->lock);
+
+ raw_spin_lock(&s->lock);
s->pics[0].isr_ack = 0xff;
s->pics[1].isr_ack = 0xff;
- spin_unlock(&s->lock);
+ raw_spin_unlock(&s->lock);
}
/*
@@ -156,9 +158,9 @@ static void pic_update_irq(struct kvm_pic *s)
void kvm_pic_update_irq(struct kvm_pic *s)
{
- spin_lock(&s->lock);
+ raw_spin_lock(&s->lock);
pic_update_irq(s);
- spin_unlock(&s->lock);
+ raw_spin_unlock(&s->lock);
}
int kvm_pic_set_irq(void *opaque, int irq, int level)
@@ -166,14 +168,14 @@ int kvm_pic_set_irq(void *opaque, int irq, int level)
struct kvm_pic *s = opaque;
int ret = -1;
- spin_lock(&s->lock);
+ raw_spin_lock(&s->lock);
if (irq >= 0 && irq < PIC_NUM_PINS) {
ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
pic_update_irq(s);
trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr,
s->pics[irq >> 3].imr, ret == 0);
}
- spin_unlock(&s->lock);
+ raw_spin_unlock(&s->lock);
return ret;
}
@@ -203,7 +205,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
int irq, irq2, intno;
struct kvm_pic *s = pic_irqchip(kvm);
- spin_lock(&s->lock);
+ raw_spin_lock(&s->lock);
irq = pic_get_irq(&s->pics[0]);
if (irq >= 0) {
pic_intack(&s->pics[0], irq);
@@ -228,7 +230,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
intno = s->pics[0].irq_base + irq;
}
pic_update_irq(s);
- spin_unlock(&s->lock);
+ raw_spin_unlock(&s->lock);
return intno;
}
@@ -442,7 +444,7 @@ static int picdev_write(struct kvm_io_device *this,
printk(KERN_ERR "PIC: non byte write\n");
return 0;
}
- spin_lock(&s->lock);
+ raw_spin_lock(&s->lock);
switch (addr) {
case 0x20:
case 0x21:
@@ -455,7 +457,7 @@ static int picdev_write(struct kvm_io_device *this,
elcr_ioport_write(&s->pics[addr & 1], addr, data);
break;
}
- spin_unlock(&s->lock);
+ raw_spin_unlock(&s->lock);
return 0;
}
@@ -472,7 +474,7 @@ static int picdev_read(struct kvm_io_device *this,
printk(KERN_ERR "PIC: non byte read\n");
return 0;
}
- spin_lock(&s->lock);
+ raw_spin_lock(&s->lock);
switch (addr) {
case 0x20:
case 0x21:
@@ -486,7 +488,7 @@ static int picdev_read(struct kvm_io_device *this,
break;
}
*(unsigned char *)val = data;
- spin_unlock(&s->lock);
+ raw_spin_unlock(&s->lock);
return 0;
}
@@ -520,7 +522,7 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
if (!s)
return NULL;
- spin_lock_init(&s->lock);
+ raw_spin_lock_init(&s->lock);
s->kvm = kvm;
s->pics[0].elcr_mask = 0xf8;
s->pics[1].elcr_mask = 0xde;
@@ -533,7 +535,9 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
* Initialize PIO device
*/
kvm_iodevice_init(&s->dev, &picdev_ops);
- ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &s->dev);
+ mutex_lock(&kvm->slots_lock);
+ ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, &s->dev);
+ mutex_unlock(&kvm->slots_lock);
if (ret < 0) {
kfree(s);
return NULL;
@@ -541,3 +545,14 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
return s;
}
+
+void kvm_destroy_pic(struct kvm *kvm)
+{
+ struct kvm_pic *vpic = kvm->arch.vpic;
+
+ if (vpic) {
+ kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &vpic->dev);
+ kvm->arch.vpic = NULL;
+ kfree(vpic);
+ }
+}
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index be399e207d5..34b15915754 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -62,7 +62,7 @@ struct kvm_kpic_state {
};
struct kvm_pic {
- spinlock_t lock;
+ raw_spinlock_t lock;
unsigned pending_acks;
struct kvm *kvm;
struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */
@@ -75,6 +75,7 @@ struct kvm_pic {
};
struct kvm_pic *kvm_create_pic(struct kvm *kvm);
+void kvm_destroy_pic(struct kvm *kvm);
int kvm_pic_read_irq(struct kvm *kvm);
void kvm_pic_update_irq(struct kvm_pic *s);
void kvm_pic_clear_isr_ack(struct kvm *kvm);
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h
index 7bcc5b6a440..cff851cf532 100644
--- a/arch/x86/kvm/kvm_cache_regs.h
+++ b/arch/x86/kvm/kvm_cache_regs.h
@@ -1,6 +1,11 @@
#ifndef ASM_KVM_CACHE_REGS_H
#define ASM_KVM_CACHE_REGS_H
+#define KVM_POSSIBLE_CR0_GUEST_BITS X86_CR0_TS
+#define KVM_POSSIBLE_CR4_GUEST_BITS \
+ (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \
+ | X86_CR4_OSXMMEXCPT | X86_CR4_PGE)
+
static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu,
enum kvm_reg reg)
{
@@ -38,4 +43,30 @@ static inline u64 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index)
return vcpu->arch.pdptrs[index];
}
+static inline ulong kvm_read_cr0_bits(struct kvm_vcpu *vcpu, ulong mask)
+{
+ ulong tmask = mask & KVM_POSSIBLE_CR0_GUEST_BITS;
+ if (tmask & vcpu->arch.cr0_guest_owned_bits)
+ kvm_x86_ops->decache_cr0_guest_bits(vcpu);
+ return vcpu->arch.cr0 & mask;
+}
+
+static inline ulong kvm_read_cr0(struct kvm_vcpu *vcpu)
+{
+ return kvm_read_cr0_bits(vcpu, ~0UL);
+}
+
+static inline ulong kvm_read_cr4_bits(struct kvm_vcpu *vcpu, ulong mask)
+{
+ ulong tmask = mask & KVM_POSSIBLE_CR4_GUEST_BITS;
+ if (tmask & vcpu->arch.cr4_guest_owned_bits)
+ kvm_x86_ops->decache_cr4_guest_bits(vcpu);
+ return vcpu->arch.cr4 & mask;
+}
+
+static inline ulong kvm_read_cr4(struct kvm_vcpu *vcpu)
+{
+ return kvm_read_cr4_bits(vcpu, ~0UL);
+}
+
#endif
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index ba8c045da78..1eb7a4ae0c9 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -26,6 +26,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/math64.h>
+#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/page.h>
@@ -1246,3 +1247,34 @@ int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
return 0;
}
+
+int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 reg, u64 data)
+{
+ struct kvm_lapic *apic = vcpu->arch.apic;
+
+ if (!irqchip_in_kernel(vcpu->kvm))
+ return 1;
+
+ /* if this is ICR write vector before command */
+ if (reg == APIC_ICR)
+ apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32));
+ return apic_reg_write(apic, reg, (u32)data);
+}
+
+int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
+{
+ struct kvm_lapic *apic = vcpu->arch.apic;
+ u32 low, high = 0;
+
+ if (!irqchip_in_kernel(vcpu->kvm))
+ return 1;
+
+ if (apic_reg_read(apic, reg, 4, &low))
+ return 1;
+ if (reg == APIC_ICR)
+ apic_reg_read(apic, APIC_ICR2, 4, &high);
+
+ *data = (((u64)high) << 32) | low;
+
+ return 0;
+}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 40010b09c4a..f5fe32c5eda 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -48,4 +48,12 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu);
int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data);
int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
+
+int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data);
+int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
+
+static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.hv_vapic & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE;
+}
#endif
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 89a49fb46a2..19a8906bcaa 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -18,6 +18,7 @@
*/
#include "mmu.h"
+#include "x86.h"
#include "kvm_cache_regs.h"
#include <linux/kvm_host.h>
@@ -29,6 +30,8 @@
#include <linux/swap.h>
#include <linux/hugetlb.h>
#include <linux/compiler.h>
+#include <linux/srcu.h>
+#include <linux/slab.h>
#include <asm/page.h>
#include <asm/cmpxchg.h>
@@ -136,16 +139,6 @@ module_param(oos_shadow, bool, 0644);
#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \
| PT64_NX_MASK)
-#define PFERR_PRESENT_MASK (1U << 0)
-#define PFERR_WRITE_MASK (1U << 1)
-#define PFERR_USER_MASK (1U << 2)
-#define PFERR_RSVD_MASK (1U << 3)
-#define PFERR_FETCH_MASK (1U << 4)
-
-#define PT_PDPE_LEVEL 3
-#define PT_DIRECTORY_LEVEL 2
-#define PT_PAGE_TABLE_LEVEL 1
-
#define RMAP_EXT 4
#define ACC_EXEC_MASK 1
@@ -153,6 +146,9 @@ module_param(oos_shadow, bool, 0644);
#define ACC_USER_MASK PT_USER_MASK
#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK)
+#include <trace/events/kvm.h>
+
+#undef TRACE_INCLUDE_FILE
#define CREATE_TRACE_POINTS
#include "mmutrace.h"
@@ -229,7 +225,7 @@ EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes);
static int is_write_protection(struct kvm_vcpu *vcpu)
{
- return vcpu->arch.cr0 & X86_CR0_WP;
+ return kvm_read_cr0_bits(vcpu, X86_CR0_WP);
}
static int is_cpuid_PSE36(void)
@@ -239,7 +235,7 @@ static int is_cpuid_PSE36(void)
static int is_nx(struct kvm_vcpu *vcpu)
{
- return vcpu->arch.shadow_efer & EFER_NX;
+ return vcpu->arch.efer & EFER_NX;
}
static int is_shadow_present_pte(u64 pte)
@@ -253,7 +249,7 @@ static int is_large_pte(u64 pte)
return pte & PT_PAGE_SIZE_MASK;
}
-static int is_writeble_pte(unsigned long pte)
+static int is_writable_pte(unsigned long pte)
{
return pte & PT_WRITABLE_MASK;
}
@@ -470,24 +466,10 @@ static int has_wrprotected_page(struct kvm *kvm,
static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
{
- unsigned long page_size = PAGE_SIZE;
- struct vm_area_struct *vma;
- unsigned long addr;
+ unsigned long page_size;
int i, ret = 0;
- addr = gfn_to_hva(kvm, gfn);
- if (kvm_is_error_hva(addr))
- return PT_PAGE_TABLE_LEVEL;
-
- down_read(&current->mm->mmap_sem);
- vma = find_vma(current->mm, addr);
- if (!vma)
- goto out;
-
- page_size = vma_kernel_pagesize(vma);
-
-out:
- up_read(&current->mm->mmap_sem);
+ page_size = kvm_host_page_size(kvm, gfn);
for (i = PT_PAGE_TABLE_LEVEL;
i < (PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES); ++i) {
@@ -503,8 +485,7 @@ out:
static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
{
struct kvm_memory_slot *slot;
- int host_level;
- int level = PT_PAGE_TABLE_LEVEL;
+ int host_level, level, max_level;
slot = gfn_to_memslot(vcpu->kvm, large_gfn);
if (slot && slot->dirty_bitmap)
@@ -515,7 +496,10 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
if (host_level == PT_PAGE_TABLE_LEVEL)
return host_level;
- for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level)
+ max_level = kvm_x86_ops->get_lpage_level() < host_level ?
+ kvm_x86_ops->get_lpage_level() : host_level;
+
+ for (level = PT_DIRECTORY_LEVEL; level <= max_level; ++level)
if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
break;
@@ -633,7 +617,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
pfn = spte_to_pfn(*spte);
if (*spte & shadow_accessed_mask)
kvm_set_pfn_accessed(pfn);
- if (is_writeble_pte(*spte))
+ if (is_writable_pte(*spte))
kvm_set_pfn_dirty(pfn);
rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], sp->role.level);
if (!*rmapp) {
@@ -662,6 +646,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
prev_desc = desc;
desc = desc->more;
}
+ pr_err("rmap_remove: %p %llx many->many\n", spte, *spte);
BUG();
}
}
@@ -708,7 +693,7 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
BUG_ON(!spte);
BUG_ON(!(*spte & PT_PRESENT_MASK));
rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
- if (is_writeble_pte(*spte)) {
+ if (is_writable_pte(*spte)) {
__set_spte(spte, *spte & ~PT_WRITABLE_MASK);
write_protected = 1;
}
@@ -732,7 +717,7 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
BUG_ON(!(*spte & PT_PRESENT_MASK));
BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK));
pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn);
- if (is_writeble_pte(*spte)) {
+ if (is_writable_pte(*spte)) {
rmap_remove(kvm, spte);
--kvm->stat.lpages;
__set_spte(spte, shadow_trap_nonpresent_pte);
@@ -787,7 +772,7 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
new_spte &= ~PT_WRITABLE_MASK;
new_spte &= ~SPTE_HOST_WRITEABLE;
- if (is_writeble_pte(*spte))
+ if (is_writable_pte(*spte))
kvm_set_pfn_dirty(spte_to_pfn(*spte));
__set_spte(spte, new_spte);
spte = rmap_next(kvm, rmapp, spte);
@@ -805,35 +790,32 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
unsigned long data))
{
int i, j;
+ int ret;
int retval = 0;
+ struct kvm_memslots *slots;
- /*
- * If mmap_sem isn't taken, we can look the memslots with only
- * the mmu_lock by skipping over the slots with userspace_addr == 0.
- */
- for (i = 0; i < kvm->nmemslots; i++) {
- struct kvm_memory_slot *memslot = &kvm->memslots[i];
+ slots = rcu_dereference(kvm->memslots);
+
+ for (i = 0; i < slots->nmemslots; i++) {
+ struct kvm_memory_slot *memslot = &slots->memslots[i];
unsigned long start = memslot->userspace_addr;
unsigned long end;
- /* mmu_lock protects userspace_addr */
- if (!start)
- continue;
-
end = start + (memslot->npages << PAGE_SHIFT);
if (hva >= start && hva < end) {
gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
- retval |= handler(kvm, &memslot->rmap[gfn_offset],
- data);
+ ret = handler(kvm, &memslot->rmap[gfn_offset], data);
for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) {
int idx = gfn_offset;
idx /= KVM_PAGES_PER_HPAGE(PT_DIRECTORY_LEVEL + j);
- retval |= handler(kvm,
+ ret |= handler(kvm,
&memslot->lpage_info[j][idx].rmap_pde,
data);
}
+ trace_kvm_age_page(hva, memslot, ret);
+ retval |= ret;
}
}
@@ -856,9 +838,15 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
u64 *spte;
int young = 0;
- /* always return old for EPT */
+ /*
+ * Emulate the accessed bit for EPT, by checking if this page has
+ * an EPT mapping, and clearing it if it does. On the next access,
+ * a new EPT mapping will be established.
+ * This has some overhead, but not as much as the cost of swapping
+ * out actively used pages or breaking up actively used hugepages.
+ */
if (!shadow_accessed_mask)
- return 0;
+ return kvm_unmap_rmapp(kvm, rmapp, data);
spte = rmap_next(kvm, rmapp, NULL);
while (spte) {
@@ -1502,8 +1490,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm,
for_each_sp(pages, sp, parents, i) {
kvm_mmu_zap_page(kvm, sp);
mmu_pages_clear_parents(&parents);
+ zapped++;
}
- zapped += pages.nr;
kvm_mmu_pages_init(parent, &parents, &pages);
}
@@ -1554,14 +1542,16 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
*/
if (used_pages > kvm_nr_mmu_pages) {
- while (used_pages > kvm_nr_mmu_pages) {
+ while (used_pages > kvm_nr_mmu_pages &&
+ !list_empty(&kvm->arch.active_mmu_pages)) {
struct kvm_mmu_page *page;
page = container_of(kvm->arch.active_mmu_pages.prev,
struct kvm_mmu_page, link);
- kvm_mmu_zap_page(kvm, page);
+ used_pages -= kvm_mmu_zap_page(kvm, page);
used_pages--;
}
+ kvm_nr_mmu_pages = used_pages;
kvm->arch.n_free_mmu_pages = 0;
}
else
@@ -1608,14 +1598,15 @@ static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
&& !sp->role.invalid) {
pgprintk("%s: zap %lx %x\n",
__func__, gfn, sp->role.word);
- kvm_mmu_zap_page(kvm, sp);
+ if (kvm_mmu_zap_page(kvm, sp))
+ nn = bucket->first;
}
}
}
static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn)
{
- int slot = memslot_id(kvm, gfn_to_memslot(kvm, gfn));
+ int slot = memslot_id(kvm, gfn);
struct kvm_mmu_page *sp = page_header(__pa(pte));
__set_bit(slot, sp->slot_bitmap);
@@ -1639,7 +1630,7 @@ struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva)
{
struct page *page;
- gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
+ gpa_t gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL);
if (gpa == UNMAPPED_GVA)
return NULL;
@@ -1852,7 +1843,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
* is responsibility of mmu_get_page / kvm_sync_page.
* Same reasoning can be applied to dirty page accounting.
*/
- if (!can_unsync && is_writeble_pte(*sptep))
+ if (!can_unsync && is_writable_pte(*sptep))
goto set_pte;
if (mmu_need_write_protect(vcpu, gfn, can_unsync)) {
@@ -1860,7 +1851,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
__func__, gfn);
ret = 1;
pte_access &= ~ACC_WRITE_MASK;
- if (is_writeble_pte(spte))
+ if (is_writable_pte(spte))
spte &= ~PT_WRITABLE_MASK;
}
}
@@ -1881,7 +1872,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
bool reset_host_protection)
{
int was_rmapped = 0;
- int was_writeble = is_writeble_pte(*sptep);
+ int was_writable = is_writable_pte(*sptep);
int rmap_count;
pgprintk("%s: spte %llx access %x write_fault %d"
@@ -1932,7 +1923,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
if (rmap_count > RMAP_RECYCLE_THRESHOLD)
rmap_recycle(vcpu, sptep, gfn);
} else {
- if (was_writeble)
+ if (was_writable)
kvm_release_pfn_dirty(pfn);
else
kvm_release_pfn_clean(pfn);
@@ -2162,8 +2153,11 @@ void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
spin_unlock(&vcpu->kvm->mmu_lock);
}
-static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr)
+static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr,
+ u32 access, u32 *error)
{
+ if (error)
+ *error = 0;
return vaddr;
}
@@ -2747,7 +2741,7 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
if (tdp_enabled)
return 0;
- gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
+ gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL);
spin_lock(&vcpu->kvm->mmu_lock);
r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT);
@@ -2847,16 +2841,13 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
*/
page = alloc_page(GFP_KERNEL | __GFP_DMA32);
if (!page)
- goto error_1;
+ return -ENOMEM;
+
vcpu->arch.mmu.pae_root = page_address(page);
for (i = 0; i < 4; ++i)
vcpu->arch.mmu.pae_root[i] = INVALID_PAGE;
return 0;
-
-error_1:
- free_mmu_pages(vcpu);
- return -ENOMEM;
}
int kvm_mmu_create(struct kvm_vcpu *vcpu)
@@ -2936,10 +2927,9 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask)
spin_lock(&kvm_lock);
list_for_each_entry(kvm, &vm_list, vm_list) {
- int npages;
+ int npages, idx;
- if (!down_read_trylock(&kvm->slots_lock))
- continue;
+ idx = srcu_read_lock(&kvm->srcu);
spin_lock(&kvm->mmu_lock);
npages = kvm->arch.n_alloc_mmu_pages -
kvm->arch.n_free_mmu_pages;
@@ -2952,7 +2942,7 @@ static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask)
nr_to_scan--;
spin_unlock(&kvm->mmu_lock);
- up_read(&kvm->slots_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
}
if (kvm_freed)
list_move_tail(&kvm_freed->vm_list, &vm_list);
@@ -3019,9 +3009,11 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
int i;
unsigned int nr_mmu_pages;
unsigned int nr_pages = 0;
+ struct kvm_memslots *slots;
- for (i = 0; i < kvm->nmemslots; i++)
- nr_pages += kvm->memslots[i].npages;
+ slots = rcu_dereference(kvm->memslots);
+ for (i = 0; i < slots->nmemslots; i++)
+ nr_pages += slots->memslots[i].npages;
nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000;
nr_mmu_pages = max(nr_mmu_pages,
@@ -3246,7 +3238,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
if (is_shadow_present_pte(ent) && !is_last_spte(ent, level))
audit_mappings_page(vcpu, ent, va, level - 1);
else {
- gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va);
+ gpa_t gpa = kvm_mmu_gva_to_gpa_read(vcpu, va, NULL);
gfn_t gfn = gpa >> PAGE_SHIFT;
pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn);
hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT;
@@ -3291,10 +3283,12 @@ static void audit_mappings(struct kvm_vcpu *vcpu)
static int count_rmaps(struct kvm_vcpu *vcpu)
{
int nmaps = 0;
- int i, j, k;
+ int i, j, k, idx;
+ idx = srcu_read_lock(&kvm->srcu);
+ slots = rcu_dereference(kvm->memslots);
for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
- struct kvm_memory_slot *m = &vcpu->kvm->memslots[i];
+ struct kvm_memory_slot *m = &slots->memslots[i];
struct kvm_rmap_desc *d;
for (j = 0; j < m->npages; ++j) {
@@ -3317,6 +3311,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu)
}
}
}
+ srcu_read_unlock(&kvm->srcu, idx);
return nmaps;
}
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 61a1b3884b4..be66759321a 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -2,6 +2,7 @@
#define __KVM_X86_MMU_H
#include <linux/kvm_host.h>
+#include "kvm_cache_regs.h"
#define PT64_PT_BITS 9
#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)
@@ -37,6 +38,16 @@
#define PT32_ROOT_LEVEL 2
#define PT32E_ROOT_LEVEL 3
+#define PT_PDPE_LEVEL 3
+#define PT_DIRECTORY_LEVEL 2
+#define PT_PAGE_TABLE_LEVEL 1
+
+#define PFERR_PRESENT_MASK (1U << 0)
+#define PFERR_WRITE_MASK (1U << 1)
+#define PFERR_USER_MASK (1U << 2)
+#define PFERR_RSVD_MASK (1U << 3)
+#define PFERR_FETCH_MASK (1U << 4)
+
int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
@@ -53,30 +64,6 @@ static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu)
return kvm_mmu_load(vcpu);
}
-static inline int is_long_mode(struct kvm_vcpu *vcpu)
-{
-#ifdef CONFIG_X86_64
- return vcpu->arch.shadow_efer & EFER_LMA;
-#else
- return 0;
-#endif
-}
-
-static inline int is_pae(struct kvm_vcpu *vcpu)
-{
- return vcpu->arch.cr4 & X86_CR4_PAE;
-}
-
-static inline int is_pse(struct kvm_vcpu *vcpu)
-{
- return vcpu->arch.cr4 & X86_CR4_PSE;
-}
-
-static inline int is_paging(struct kvm_vcpu *vcpu)
-{
- return vcpu->arch.cr0 & X86_CR0_PG;
-}
-
static inline int is_present_gpte(unsigned long pte)
{
return pte & PT_PRESENT_MASK;
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index ede2131a922..81eab9a50e6 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -162,7 +162,7 @@ walk:
if (rsvd_fault)
goto access_error;
- if (write_fault && !is_writeble_pte(pte))
+ if (write_fault && !is_writable_pte(pte))
if (user_fault || is_write_protection(vcpu))
goto access_error;
@@ -490,18 +490,23 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
spin_unlock(&vcpu->kvm->mmu_lock);
}
-static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
+static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access,
+ u32 *error)
{
struct guest_walker walker;
gpa_t gpa = UNMAPPED_GVA;
int r;
- r = FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0);
+ r = FNAME(walk_addr)(&walker, vcpu, vaddr,
+ !!(access & PFERR_WRITE_MASK),
+ !!(access & PFERR_USER_MASK),
+ !!(access & PFERR_FETCH_MASK));
if (r) {
gpa = gfn_to_gpa(walker.gfn);
gpa |= vaddr & ~PAGE_MASK;
- }
+ } else if (error)
+ *error = walker.error_code;
return gpa;
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1d9b33843c8..2ba58206812 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -26,6 +26,7 @@
#include <linux/highmem.h>
#include <linux/sched.h>
#include <linux/ftrace_event.h>
+#include <linux/slab.h>
#include <asm/desc.h>
@@ -231,7 +232,7 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
efer &= ~EFER_LME;
to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME;
- vcpu->arch.shadow_efer = efer;
+ vcpu->arch.efer = efer;
}
static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
@@ -540,6 +541,8 @@ static void init_vmcb(struct vcpu_svm *svm)
struct vmcb_control_area *control = &svm->vmcb->control;
struct vmcb_save_area *save = &svm->vmcb->save;
+ svm->vcpu.fpu_active = 1;
+
control->intercept_cr_read = INTERCEPT_CR0_MASK |
INTERCEPT_CR3_MASK |
INTERCEPT_CR4_MASK;
@@ -552,13 +555,19 @@ static void init_vmcb(struct vcpu_svm *svm)
control->intercept_dr_read = INTERCEPT_DR0_MASK |
INTERCEPT_DR1_MASK |
INTERCEPT_DR2_MASK |
- INTERCEPT_DR3_MASK;
+ INTERCEPT_DR3_MASK |
+ INTERCEPT_DR4_MASK |
+ INTERCEPT_DR5_MASK |
+ INTERCEPT_DR6_MASK |
+ INTERCEPT_DR7_MASK;
control->intercept_dr_write = INTERCEPT_DR0_MASK |
INTERCEPT_DR1_MASK |
INTERCEPT_DR2_MASK |
INTERCEPT_DR3_MASK |
+ INTERCEPT_DR4_MASK |
INTERCEPT_DR5_MASK |
+ INTERCEPT_DR6_MASK |
INTERCEPT_DR7_MASK;
control->intercept_exceptions = (1 << PF_VECTOR) |
@@ -569,6 +578,7 @@ static void init_vmcb(struct vcpu_svm *svm)
control->intercept = (1ULL << INTERCEPT_INTR) |
(1ULL << INTERCEPT_NMI) |
(1ULL << INTERCEPT_SMI) |
+ (1ULL << INTERCEPT_SELECTIVE_CR0) |
(1ULL << INTERCEPT_CPUID) |
(1ULL << INTERCEPT_INVD) |
(1ULL << INTERCEPT_HLT) |
@@ -641,10 +651,8 @@ static void init_vmcb(struct vcpu_svm *svm)
control->intercept &= ~((1ULL << INTERCEPT_TASK_SWITCH) |
(1ULL << INTERCEPT_INVLPG));
control->intercept_exceptions &= ~(1 << PF_VECTOR);
- control->intercept_cr_read &= ~(INTERCEPT_CR0_MASK|
- INTERCEPT_CR3_MASK);
- control->intercept_cr_write &= ~(INTERCEPT_CR0_MASK|
- INTERCEPT_CR3_MASK);
+ control->intercept_cr_read &= ~INTERCEPT_CR3_MASK;
+ control->intercept_cr_write &= ~INTERCEPT_CR3_MASK;
save->g_pat = 0x0007040600070406ULL;
save->cr3 = 0;
save->cr4 = 0;
@@ -698,29 +706,28 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
if (err)
goto free_svm;
+ err = -ENOMEM;
page = alloc_page(GFP_KERNEL);
- if (!page) {
- err = -ENOMEM;
+ if (!page)
goto uninit;
- }
- err = -ENOMEM;
msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
if (!msrpm_pages)
- goto uninit;
+ goto free_page1;
nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
if (!nested_msrpm_pages)
- goto uninit;
-
- svm->msrpm = page_address(msrpm_pages);
- svm_vcpu_init_msrpm(svm->msrpm);
+ goto free_page2;
hsave_page = alloc_page(GFP_KERNEL);
if (!hsave_page)
- goto uninit;
+ goto free_page3;
+
svm->nested.hsave = page_address(hsave_page);
+ svm->msrpm = page_address(msrpm_pages);
+ svm_vcpu_init_msrpm(svm->msrpm);
+
svm->nested.msrpm = page_address(nested_msrpm_pages);
svm->vmcb = page_address(page);
@@ -730,13 +737,18 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
init_vmcb(svm);
fx_init(&svm->vcpu);
- svm->vcpu.fpu_active = 1;
svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
if (kvm_vcpu_is_bsp(&svm->vcpu))
svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP;
return &svm->vcpu;
+free_page3:
+ __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page2:
+ __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page1:
+ __free_page(page);
uninit:
kvm_vcpu_uninit(&svm->vcpu);
free_svm:
@@ -765,14 +777,16 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (unlikely(cpu != vcpu->cpu)) {
u64 delta;
- /*
- * Make sure that the guest sees a monotonically
- * increasing TSC.
- */
- delta = vcpu->arch.host_tsc - native_read_tsc();
- svm->vmcb->control.tsc_offset += delta;
- if (is_nested(svm))
- svm->nested.hsave->control.tsc_offset += delta;
+ if (check_tsc_unstable()) {
+ /*
+ * Make sure that the guest sees a monotonically
+ * increasing TSC.
+ */
+ delta = vcpu->arch.host_tsc - native_read_tsc();
+ svm->vmcb->control.tsc_offset += delta;
+ if (is_nested(svm))
+ svm->nested.hsave->control.tsc_offset += delta;
+ }
vcpu->cpu = cpu;
kvm_migrate_timers(vcpu);
svm->asid_generation = 0;
@@ -954,42 +968,59 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
svm->vmcb->save.gdtr.base = dt->base ;
}
+static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
+{
+}
+
static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
{
}
+static void update_cr0_intercept(struct vcpu_svm *svm)
+{
+ ulong gcr0 = svm->vcpu.arch.cr0;
+ u64 *hcr0 = &svm->vmcb->save.cr0;
+
+ if (!svm->vcpu.fpu_active)
+ *hcr0 |= SVM_CR0_SELECTIVE_MASK;
+ else
+ *hcr0 = (*hcr0 & ~SVM_CR0_SELECTIVE_MASK)
+ | (gcr0 & SVM_CR0_SELECTIVE_MASK);
+
+
+ if (gcr0 == *hcr0 && svm->vcpu.fpu_active) {
+ svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK;
+ svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK;
+ } else {
+ svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK;
+ svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK;
+ }
+}
+
static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
struct vcpu_svm *svm = to_svm(vcpu);
#ifdef CONFIG_X86_64
- if (vcpu->arch.shadow_efer & EFER_LME) {
+ if (vcpu->arch.efer & EFER_LME) {
if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
- vcpu->arch.shadow_efer |= EFER_LMA;
+ vcpu->arch.efer |= EFER_LMA;
svm->vmcb->save.efer |= EFER_LMA | EFER_LME;
}
if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) {
- vcpu->arch.shadow_efer &= ~EFER_LMA;
+ vcpu->arch.efer &= ~EFER_LMA;
svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME);
}
}
#endif
- if (npt_enabled)
- goto set;
+ vcpu->arch.cr0 = cr0;
- if ((vcpu->arch.cr0 & X86_CR0_TS) && !(cr0 & X86_CR0_TS)) {
- svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
- vcpu->fpu_active = 1;
- }
+ if (!npt_enabled)
+ cr0 |= X86_CR0_PG | X86_CR0_WP;
- vcpu->arch.cr0 = cr0;
- cr0 |= X86_CR0_PG | X86_CR0_WP;
- if (!vcpu->fpu_active) {
- svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+ if (!vcpu->fpu_active)
cr0 |= X86_CR0_TS;
- }
-set:
/*
* re-enable caching here because the QEMU bios
* does not do it - this results in some delay at
@@ -997,6 +1028,7 @@ set:
*/
cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
svm->vmcb->save.cr0 = cr0;
+ update_cr0_intercept(svm);
}
static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -1102,76 +1134,70 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
svm->vmcb->control.asid = sd->next_asid++;
}
-static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
+static int svm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *dest)
{
struct vcpu_svm *svm = to_svm(vcpu);
- unsigned long val;
switch (dr) {
case 0 ... 3:
- val = vcpu->arch.db[dr];
+ *dest = vcpu->arch.db[dr];
break;
+ case 4:
+ if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
+ return EMULATE_FAIL; /* will re-inject UD */
+ /* fall through */
case 6:
if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
- val = vcpu->arch.dr6;
+ *dest = vcpu->arch.dr6;
else
- val = svm->vmcb->save.dr6;
+ *dest = svm->vmcb->save.dr6;
break;
+ case 5:
+ if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
+ return EMULATE_FAIL; /* will re-inject UD */
+ /* fall through */
case 7:
if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
- val = vcpu->arch.dr7;
+ *dest = vcpu->arch.dr7;
else
- val = svm->vmcb->save.dr7;
+ *dest = svm->vmcb->save.dr7;
break;
- default:
- val = 0;
}
- return val;
+ return EMULATE_DONE;
}
-static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
- int *exception)
+static int svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value)
{
struct vcpu_svm *svm = to_svm(vcpu);
- *exception = 0;
-
switch (dr) {
case 0 ... 3:
vcpu->arch.db[dr] = value;
if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
vcpu->arch.eff_db[dr] = value;
- return;
- case 4 ... 5:
- if (vcpu->arch.cr4 & X86_CR4_DE)
- *exception = UD_VECTOR;
- return;
+ break;
+ case 4:
+ if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
+ return EMULATE_FAIL; /* will re-inject UD */
+ /* fall through */
case 6:
- if (value & 0xffffffff00000000ULL) {
- *exception = GP_VECTOR;
- return;
- }
vcpu->arch.dr6 = (value & DR6_VOLATILE) | DR6_FIXED_1;
- return;
+ break;
+ case 5:
+ if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
+ return EMULATE_FAIL; /* will re-inject UD */
+ /* fall through */
case 7:
- if (value & 0xffffffff00000000ULL) {
- *exception = GP_VECTOR;
- return;
- }
vcpu->arch.dr7 = (value & DR7_VOLATILE) | DR7_FIXED_1;
if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
svm->vmcb->save.dr7 = vcpu->arch.dr7;
vcpu->arch.switch_db_regs = (value & DR7_BP_EN_MASK);
}
- return;
- default:
- /* FIXME: Possible case? */
- printk(KERN_DEBUG "%s: unexpected dr %u\n",
- __func__, dr);
- *exception = UD_VECTOR;
- return;
+ break;
}
+
+ return EMULATE_DONE;
}
static int pf_interception(struct vcpu_svm *svm)
@@ -1239,13 +1265,17 @@ static int ud_interception(struct vcpu_svm *svm)
return 1;
}
-static int nm_interception(struct vcpu_svm *svm)
+static void svm_fpu_activate(struct kvm_vcpu *vcpu)
{
+ struct vcpu_svm *svm = to_svm(vcpu);
svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
- if (!(svm->vcpu.arch.cr0 & X86_CR0_TS))
- svm->vmcb->save.cr0 &= ~X86_CR0_TS;
svm->vcpu.fpu_active = 1;
+ update_cr0_intercept(svm);
+}
+static int nm_interception(struct vcpu_svm *svm)
+{
+ svm_fpu_activate(&svm->vcpu);
return 1;
}
@@ -1337,7 +1367,7 @@ static int vmmcall_interception(struct vcpu_svm *svm)
static int nested_svm_check_permissions(struct vcpu_svm *svm)
{
- if (!(svm->vcpu.arch.shadow_efer & EFER_SVME)
+ if (!(svm->vcpu.arch.efer & EFER_SVME)
|| !is_paging(&svm->vcpu)) {
kvm_queue_exception(&svm->vcpu, UD_VECTOR);
return 1;
@@ -1740,8 +1770,8 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
hsave->save.ds = vmcb->save.ds;
hsave->save.gdtr = vmcb->save.gdtr;
hsave->save.idtr = vmcb->save.idtr;
- hsave->save.efer = svm->vcpu.arch.shadow_efer;
- hsave->save.cr0 = svm->vcpu.arch.cr0;
+ hsave->save.efer = svm->vcpu.arch.efer;
+ hsave->save.cr0 = kvm_read_cr0(&svm->vcpu);
hsave->save.cr4 = svm->vcpu.arch.cr4;
hsave->save.rflags = vmcb->save.rflags;
hsave->save.rip = svm->next_rip;
@@ -2153,9 +2183,10 @@ static int rdmsr_interception(struct vcpu_svm *svm)
u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
u64 data;
- if (svm_get_msr(&svm->vcpu, ecx, &data))
+ if (svm_get_msr(&svm->vcpu, ecx, &data)) {
+ trace_kvm_msr_read_ex(ecx);
kvm_inject_gp(&svm->vcpu, 0);
- else {
+ } else {
trace_kvm_msr_read(ecx, data);
svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff;
@@ -2247,13 +2278,15 @@ static int wrmsr_interception(struct vcpu_svm *svm)
u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
| ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
- trace_kvm_msr_write(ecx, data);
svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
- if (svm_set_msr(&svm->vcpu, ecx, data))
+ if (svm_set_msr(&svm->vcpu, ecx, data)) {
+ trace_kvm_msr_write_ex(ecx, data);
kvm_inject_gp(&svm->vcpu, 0);
- else
+ } else {
+ trace_kvm_msr_write(ecx, data);
skip_emulated_instruction(&svm->vcpu);
+ }
return 1;
}
@@ -2297,7 +2330,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_READ_CR3] = emulate_on_interception,
[SVM_EXIT_READ_CR4] = emulate_on_interception,
[SVM_EXIT_READ_CR8] = emulate_on_interception,
- /* for now: */
+ [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception,
[SVM_EXIT_WRITE_CR0] = emulate_on_interception,
[SVM_EXIT_WRITE_CR3] = emulate_on_interception,
[SVM_EXIT_WRITE_CR4] = emulate_on_interception,
@@ -2306,11 +2339,17 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_READ_DR1] = emulate_on_interception,
[SVM_EXIT_READ_DR2] = emulate_on_interception,
[SVM_EXIT_READ_DR3] = emulate_on_interception,
+ [SVM_EXIT_READ_DR4] = emulate_on_interception,
+ [SVM_EXIT_READ_DR5] = emulate_on_interception,
+ [SVM_EXIT_READ_DR6] = emulate_on_interception,
+ [SVM_EXIT_READ_DR7] = emulate_on_interception,
[SVM_EXIT_WRITE_DR0] = emulate_on_interception,
[SVM_EXIT_WRITE_DR1] = emulate_on_interception,
[SVM_EXIT_WRITE_DR2] = emulate_on_interception,
[SVM_EXIT_WRITE_DR3] = emulate_on_interception,
+ [SVM_EXIT_WRITE_DR4] = emulate_on_interception,
[SVM_EXIT_WRITE_DR5] = emulate_on_interception,
+ [SVM_EXIT_WRITE_DR6] = emulate_on_interception,
[SVM_EXIT_WRITE_DR7] = emulate_on_interception,
[SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception,
[SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception,
@@ -2383,20 +2422,10 @@ static int handle_exit(struct kvm_vcpu *vcpu)
svm_complete_interrupts(svm);
- if (npt_enabled) {
- int mmu_reload = 0;
- if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) {
- svm_set_cr0(vcpu, svm->vmcb->save.cr0);
- mmu_reload = 1;
- }
+ if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR0_MASK))
vcpu->arch.cr0 = svm->vmcb->save.cr0;
+ if (npt_enabled)
vcpu->arch.cr3 = svm->vmcb->save.cr3;
- if (mmu_reload) {
- kvm_mmu_reset_context(vcpu);
- kvm_mmu_load(vcpu);
- }
- }
-
if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) {
kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
@@ -2798,12 +2827,6 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
svm->vmcb->save.cr3 = root;
force_new_asid(vcpu);
-
- if (vcpu->fpu_active) {
- svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
- svm->vmcb->save.cr0 |= X86_CR0_TS;
- vcpu->fpu_active = 0;
- }
}
static int is_disabled(void)
@@ -2852,6 +2875,10 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
return 0;
}
+static void svm_cpuid_update(struct kvm_vcpu *vcpu)
+{
+}
+
static const struct trace_print_flags svm_exit_reasons_str[] = {
{ SVM_EXIT_READ_CR0, "read_cr0" },
{ SVM_EXIT_READ_CR3, "read_cr3" },
@@ -2905,9 +2932,22 @@ static const struct trace_print_flags svm_exit_reasons_str[] = {
{ -1, NULL }
};
-static bool svm_gb_page_enable(void)
+static int svm_get_lpage_level(void)
{
- return true;
+ return PT_PDPE_LEVEL;
+}
+
+static bool svm_rdtscp_supported(void)
+{
+ return false;
+}
+
+static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ update_cr0_intercept(svm);
+ svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR;
}
static struct kvm_x86_ops svm_x86_ops = {
@@ -2936,6 +2976,7 @@ static struct kvm_x86_ops svm_x86_ops = {
.set_segment = svm_set_segment,
.get_cpl = svm_get_cpl,
.get_cs_db_l_bits = kvm_get_cs_db_l_bits,
+ .decache_cr0_guest_bits = svm_decache_cr0_guest_bits,
.decache_cr4_guest_bits = svm_decache_cr4_guest_bits,
.set_cr0 = svm_set_cr0,
.set_cr3 = svm_set_cr3,
@@ -2950,6 +2991,8 @@ static struct kvm_x86_ops svm_x86_ops = {
.cache_reg = svm_cache_reg,
.get_rflags = svm_get_rflags,
.set_rflags = svm_set_rflags,
+ .fpu_activate = svm_fpu_activate,
+ .fpu_deactivate = svm_fpu_deactivate,
.tlb_flush = svm_flush_tlb,
@@ -2975,7 +3018,11 @@ static struct kvm_x86_ops svm_x86_ops = {
.get_mt_mask = svm_get_mt_mask,
.exit_reasons_str = svm_exit_reasons_str,
- .gb_page_enable = svm_gb_page_enable,
+ .get_lpage_level = svm_get_lpage_level,
+
+ .cpuid_update = svm_cpuid_update,
+
+ .rdtscp_supported = svm_rdtscp_supported,
};
static int __init svm_init(void)
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 816e0449db0..6ad30a29f04 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -56,6 +56,38 @@ TRACE_EVENT(kvm_hypercall,
);
/*
+ * Tracepoint for hypercall.
+ */
+TRACE_EVENT(kvm_hv_hypercall,
+ TP_PROTO(__u16 code, bool fast, __u16 rep_cnt, __u16 rep_idx,
+ __u64 ingpa, __u64 outgpa),
+ TP_ARGS(code, fast, rep_cnt, rep_idx, ingpa, outgpa),
+
+ TP_STRUCT__entry(
+ __field( __u16, code )
+ __field( bool, fast )
+ __field( __u16, rep_cnt )
+ __field( __u16, rep_idx )
+ __field( __u64, ingpa )
+ __field( __u64, outgpa )
+ ),
+
+ TP_fast_assign(
+ __entry->code = code;
+ __entry->fast = fast;
+ __entry->rep_cnt = rep_cnt;
+ __entry->rep_idx = rep_idx;
+ __entry->ingpa = ingpa;
+ __entry->outgpa = outgpa;
+ ),
+
+ TP_printk("code 0x%x %s cnt 0x%x idx 0x%x in 0x%llx out 0x%llx",
+ __entry->code, __entry->fast ? "fast" : "slow",
+ __entry->rep_cnt, __entry->rep_idx, __entry->ingpa,
+ __entry->outgpa)
+);
+
+/*
* Tracepoint for PIO.
*/
TRACE_EVENT(kvm_pio,
@@ -214,28 +246,33 @@ TRACE_EVENT(kvm_page_fault,
* Tracepoint for guest MSR access.
*/
TRACE_EVENT(kvm_msr,
- TP_PROTO(unsigned int rw, unsigned int ecx, unsigned long data),
- TP_ARGS(rw, ecx, data),
+ TP_PROTO(unsigned write, u32 ecx, u64 data, bool exception),
+ TP_ARGS(write, ecx, data, exception),
TP_STRUCT__entry(
- __field( unsigned int, rw )
- __field( unsigned int, ecx )
- __field( unsigned long, data )
+ __field( unsigned, write )
+ __field( u32, ecx )
+ __field( u64, data )
+ __field( u8, exception )
),
TP_fast_assign(
- __entry->rw = rw;
+ __entry->write = write;
__entry->ecx = ecx;
__entry->data = data;
+ __entry->exception = exception;
),
- TP_printk("msr_%s %x = 0x%lx",
- __entry->rw ? "write" : "read",
- __entry->ecx, __entry->data)
+ TP_printk("msr_%s %x = 0x%llx%s",
+ __entry->write ? "write" : "read",
+ __entry->ecx, __entry->data,
+ __entry->exception ? " (#GP)" : "")
);
-#define trace_kvm_msr_read(ecx, data) trace_kvm_msr(0, ecx, data)
-#define trace_kvm_msr_write(ecx, data) trace_kvm_msr(1, ecx, data)
+#define trace_kvm_msr_read(ecx, data) trace_kvm_msr(0, ecx, data, false)
+#define trace_kvm_msr_write(ecx, data) trace_kvm_msr(1, ecx, data, false)
+#define trace_kvm_msr_read_ex(ecx) trace_kvm_msr(0, ecx, 0, true)
+#define trace_kvm_msr_write_ex(ecx, data) trace_kvm_msr(1, ecx, data, true)
/*
* Tracepoint for guest CR access.
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index d4918d6fc92..bc933cfb4e6 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -26,6 +26,7 @@
#include <linux/sched.h>
#include <linux/moduleparam.h>
#include <linux/ftrace_event.h>
+#include <linux/slab.h>
#include "kvm_cache_regs.h"
#include "x86.h"
@@ -61,6 +62,23 @@ module_param_named(unrestricted_guest,
static int __read_mostly emulate_invalid_guest_state = 0;
module_param(emulate_invalid_guest_state, bool, S_IRUGO);
+#define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST \
+ (X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD)
+#define KVM_GUEST_CR0_MASK \
+ (KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
+#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST \
+ (X86_CR0_WP | X86_CR0_NE)
+#define KVM_VM_CR0_ALWAYS_ON \
+ (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
+#define KVM_CR4_GUEST_OWNED_BITS \
+ (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \
+ | X86_CR4_OSXMMEXCPT)
+
+#define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
+#define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
+
+#define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM))
+
/*
* These 2 parameters are used to config the controls for Pause-Loop Exiting:
* ple_gap: upper bound on the amount of time between two successive
@@ -115,7 +133,7 @@ struct vcpu_vmx {
} host_state;
struct {
int vm86_active;
- u8 save_iopl;
+ ulong save_rflags;
struct kvm_save_segment {
u16 selector;
unsigned long base;
@@ -136,6 +154,8 @@ struct vcpu_vmx {
ktime_t entry_time;
s64 vnmi_blocked_time;
u32 exit_reason;
+
+ bool rdtscp_enabled;
};
static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
@@ -210,7 +230,7 @@ static const u32 vmx_msr_index[] = {
#ifdef CONFIG_X86_64
MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR,
#endif
- MSR_EFER, MSR_K6_STAR,
+ MSR_EFER, MSR_TSC_AUX, MSR_K6_STAR,
};
#define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
@@ -301,6 +321,11 @@ static inline bool cpu_has_vmx_ept_2m_page(void)
return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT);
}
+static inline bool cpu_has_vmx_ept_1g_page(void)
+{
+ return !!(vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT);
+}
+
static inline int cpu_has_vmx_invept_individual_addr(void)
{
return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT);
@@ -336,9 +361,7 @@ static inline int cpu_has_vmx_ple(void)
static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
{
- return flexpriority_enabled &&
- (cpu_has_vmx_virtualize_apic_accesses()) &&
- (irqchip_in_kernel(kvm));
+ return flexpriority_enabled && irqchip_in_kernel(kvm);
}
static inline int cpu_has_vmx_vpid(void)
@@ -347,6 +370,12 @@ static inline int cpu_has_vmx_vpid(void)
SECONDARY_EXEC_ENABLE_VPID;
}
+static inline int cpu_has_vmx_rdtscp(void)
+{
+ return vmcs_config.cpu_based_2nd_exec_ctrl &
+ SECONDARY_EXEC_RDTSCP;
+}
+
static inline int cpu_has_virtual_nmis(void)
{
return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS;
@@ -551,22 +580,18 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
{
u32 eb;
- eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR);
- if (!vcpu->fpu_active)
- eb |= 1u << NM_VECTOR;
- /*
- * Unconditionally intercept #DB so we can maintain dr6 without
- * reading it every exit.
- */
- eb |= 1u << DB_VECTOR;
- if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
- if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
- eb |= 1u << BP_VECTOR;
- }
+ eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
+ (1u << NM_VECTOR) | (1u << DB_VECTOR);
+ if ((vcpu->guest_debug &
+ (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) ==
+ (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP))
+ eb |= 1u << BP_VECTOR;
if (to_vmx(vcpu)->rmode.vm86_active)
eb = ~0;
if (enable_ept)
eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */
+ if (vcpu->fpu_active)
+ eb &= ~(1u << NM_VECTOR);
vmcs_write32(EXCEPTION_BITMAP, eb);
}
@@ -589,7 +614,7 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
u64 guest_efer;
u64 ignore_bits;
- guest_efer = vmx->vcpu.arch.shadow_efer;
+ guest_efer = vmx->vcpu.arch.efer;
/*
* NX is emulated; LMA and LME handled by hardware; SCE meaninless
@@ -767,38 +792,51 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
{
+ ulong cr0;
+
if (vcpu->fpu_active)
return;
vcpu->fpu_active = 1;
- vmcs_clear_bits(GUEST_CR0, X86_CR0_TS);
- if (vcpu->arch.cr0 & X86_CR0_TS)
- vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
+ cr0 = vmcs_readl(GUEST_CR0);
+ cr0 &= ~(X86_CR0_TS | X86_CR0_MP);
+ cr0 |= kvm_read_cr0_bits(vcpu, X86_CR0_TS | X86_CR0_MP);
+ vmcs_writel(GUEST_CR0, cr0);
update_exception_bitmap(vcpu);
+ vcpu->arch.cr0_guest_owned_bits = X86_CR0_TS;
+ vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
}
+static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
+
static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
{
- if (!vcpu->fpu_active)
- return;
- vcpu->fpu_active = 0;
- vmcs_set_bits(GUEST_CR0, X86_CR0_TS);
+ vmx_decache_cr0_guest_bits(vcpu);
+ vmcs_set_bits(GUEST_CR0, X86_CR0_TS | X86_CR0_MP);
update_exception_bitmap(vcpu);
+ vcpu->arch.cr0_guest_owned_bits = 0;
+ vmcs_writel(CR0_GUEST_HOST_MASK, ~vcpu->arch.cr0_guest_owned_bits);
+ vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
}
static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
{
- unsigned long rflags;
+ unsigned long rflags, save_rflags;
rflags = vmcs_readl(GUEST_RFLAGS);
- if (to_vmx(vcpu)->rmode.vm86_active)
- rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
+ if (to_vmx(vcpu)->rmode.vm86_active) {
+ rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+ save_rflags = to_vmx(vcpu)->rmode.save_rflags;
+ rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
+ }
return rflags;
}
static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
{
- if (to_vmx(vcpu)->rmode.vm86_active)
+ if (to_vmx(vcpu)->rmode.vm86_active) {
+ to_vmx(vcpu)->rmode.save_rflags = rflags;
rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
+ }
vmcs_writel(GUEST_RFLAGS, rflags);
}
@@ -878,6 +916,11 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
}
+static bool vmx_rdtscp_supported(void)
+{
+ return cpu_has_vmx_rdtscp();
+}
+
/*
* Swap MSR entry in host/guest MSR entry array.
*/
@@ -913,12 +956,15 @@ static void setup_msrs(struct vcpu_vmx *vmx)
index = __find_msr_index(vmx, MSR_CSTAR);
if (index >= 0)
move_msr_up(vmx, index, save_nmsrs++);
+ index = __find_msr_index(vmx, MSR_TSC_AUX);
+ if (index >= 0 && vmx->rdtscp_enabled)
+ move_msr_up(vmx, index, save_nmsrs++);
/*
* MSR_K6_STAR is only needed on long mode guests, and only
* if efer.sce is enabled.
*/
index = __find_msr_index(vmx, MSR_K6_STAR);
- if ((index >= 0) && (vmx->vcpu.arch.shadow_efer & EFER_SCE))
+ if ((index >= 0) && (vmx->vcpu.arch.efer & EFER_SCE))
move_msr_up(vmx, index, save_nmsrs++);
}
#endif
@@ -1002,6 +1048,10 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
case MSR_IA32_SYSENTER_ESP:
data = vmcs_readl(GUEST_SYSENTER_ESP);
break;
+ case MSR_TSC_AUX:
+ if (!to_vmx(vcpu)->rdtscp_enabled)
+ return 1;
+ /* Otherwise falls through */
default:
vmx_load_host_state(to_vmx(vcpu));
msr = find_msr_entry(to_vmx(vcpu), msr_index);
@@ -1065,7 +1115,15 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
vcpu->arch.pat = data;
break;
}
- /* Otherwise falls through to kvm_set_msr_common */
+ ret = kvm_set_msr_common(vcpu, msr_index, data);
+ break;
+ case MSR_TSC_AUX:
+ if (!vmx->rdtscp_enabled)
+ return 1;
+ /* Check reserved bit, higher 32 bits should be zero */
+ if ((data >> 32) != 0)
+ return 1;
+ /* Otherwise falls through */
default:
msr = find_msr_entry(vmx, msr_index);
if (msr) {
@@ -1224,6 +1282,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
CPU_BASED_USE_IO_BITMAPS |
CPU_BASED_MOV_DR_EXITING |
CPU_BASED_USE_TSC_OFFSETING |
+ CPU_BASED_MWAIT_EXITING |
+ CPU_BASED_MONITOR_EXITING |
CPU_BASED_INVLPG_EXITING;
opt = CPU_BASED_TPR_SHADOW |
CPU_BASED_USE_MSR_BITMAPS |
@@ -1243,7 +1303,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
SECONDARY_EXEC_ENABLE_VPID |
SECONDARY_EXEC_ENABLE_EPT |
SECONDARY_EXEC_UNRESTRICTED_GUEST |
- SECONDARY_EXEC_PAUSE_LOOP_EXITING;
+ SECONDARY_EXEC_PAUSE_LOOP_EXITING |
+ SECONDARY_EXEC_RDTSCP;
if (adjust_vmx_controls(min2, opt2,
MSR_IA32_VMX_PROCBASED_CTLS2,
&_cpu_based_2nd_exec_control) < 0)
@@ -1429,8 +1490,8 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
flags = vmcs_readl(GUEST_RFLAGS);
- flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
- flags |= (vmx->rmode.save_iopl << IOPL_SHIFT);
+ flags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+ flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
vmcs_writel(GUEST_RFLAGS, flags);
vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
@@ -1457,8 +1518,12 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
static gva_t rmode_tss_base(struct kvm *kvm)
{
if (!kvm->arch.tss_addr) {
- gfn_t base_gfn = kvm->memslots[0].base_gfn +
- kvm->memslots[0].npages - 3;
+ struct kvm_memslots *slots;
+ gfn_t base_gfn;
+
+ slots = rcu_dereference(kvm->memslots);
+ base_gfn = kvm->memslots->memslots[0].base_gfn +
+ kvm->memslots->memslots[0].npages - 3;
return base_gfn << PAGE_SHIFT;
}
return kvm->arch.tss_addr;
@@ -1499,8 +1564,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
flags = vmcs_readl(GUEST_RFLAGS);
- vmx->rmode.save_iopl
- = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+ vmx->rmode.save_rflags = flags;
flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
@@ -1544,9 +1608,7 @@ static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
* of this msr depends on is_long_mode().
*/
vmx_load_host_state(to_vmx(vcpu));
- vcpu->arch.shadow_efer = efer;
- if (!msr)
- return;
+ vcpu->arch.efer = efer;
if (efer & EFER_LMA) {
vmcs_write32(VM_ENTRY_CONTROLS,
vmcs_read32(VM_ENTRY_CONTROLS) |
@@ -1576,13 +1638,13 @@ static void enter_lmode(struct kvm_vcpu *vcpu)
(guest_tr_ar & ~AR_TYPE_MASK)
| AR_TYPE_BUSY_64_TSS);
}
- vcpu->arch.shadow_efer |= EFER_LMA;
- vmx_set_efer(vcpu, vcpu->arch.shadow_efer);
+ vcpu->arch.efer |= EFER_LMA;
+ vmx_set_efer(vcpu, vcpu->arch.efer);
}
static void exit_lmode(struct kvm_vcpu *vcpu)
{
- vcpu->arch.shadow_efer &= ~EFER_LMA;
+ vcpu->arch.efer &= ~EFER_LMA;
vmcs_write32(VM_ENTRY_CONTROLS,
vmcs_read32(VM_ENTRY_CONTROLS)
@@ -1598,10 +1660,20 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa));
}
+static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
+{
+ ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits;
+
+ vcpu->arch.cr0 &= ~cr0_guest_owned_bits;
+ vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & cr0_guest_owned_bits;
+}
+
static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
{
- vcpu->arch.cr4 &= KVM_GUEST_CR4_MASK;
- vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK;
+ ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits;
+
+ vcpu->arch.cr4 &= ~cr4_guest_owned_bits;
+ vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & cr4_guest_owned_bits;
}
static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
@@ -1646,7 +1718,7 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
(CPU_BASED_CR3_LOAD_EXITING |
CPU_BASED_CR3_STORE_EXITING));
vcpu->arch.cr0 = cr0;
- vmx_set_cr4(vcpu, vcpu->arch.cr4);
+ vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
} else if (!is_paging(vcpu)) {
/* From nonpaging to paging */
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
@@ -1654,23 +1726,13 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
~(CPU_BASED_CR3_LOAD_EXITING |
CPU_BASED_CR3_STORE_EXITING));
vcpu->arch.cr0 = cr0;
- vmx_set_cr4(vcpu, vcpu->arch.cr4);
+ vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
}
if (!(cr0 & X86_CR0_WP))
*hw_cr0 &= ~X86_CR0_WP;
}
-static void ept_update_paging_mode_cr4(unsigned long *hw_cr4,
- struct kvm_vcpu *vcpu)
-{
- if (!is_paging(vcpu)) {
- *hw_cr4 &= ~X86_CR4_PAE;
- *hw_cr4 |= X86_CR4_PSE;
- } else if (!(vcpu->arch.cr4 & X86_CR4_PAE))
- *hw_cr4 &= ~X86_CR4_PAE;
-}
-
static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -1682,8 +1744,6 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
else
hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON;
- vmx_fpu_deactivate(vcpu);
-
if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE))
enter_pmode(vcpu);
@@ -1691,7 +1751,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
enter_rmode(vcpu);
#ifdef CONFIG_X86_64
- if (vcpu->arch.shadow_efer & EFER_LME) {
+ if (vcpu->arch.efer & EFER_LME) {
if (!is_paging(vcpu) && (cr0 & X86_CR0_PG))
enter_lmode(vcpu);
if (is_paging(vcpu) && !(cr0 & X86_CR0_PG))
@@ -1702,12 +1762,12 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
if (enable_ept)
ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu);
+ if (!vcpu->fpu_active)
+ hw_cr0 |= X86_CR0_TS | X86_CR0_MP;
+
vmcs_writel(CR0_READ_SHADOW, cr0);
vmcs_writel(GUEST_CR0, hw_cr0);
vcpu->arch.cr0 = cr0;
-
- if (!(cr0 & X86_CR0_TS) || !(cr0 & X86_CR0_PE))
- vmx_fpu_activate(vcpu);
}
static u64 construct_eptp(unsigned long root_hpa)
@@ -1738,8 +1798,6 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
vmx_flush_tlb(vcpu);
vmcs_writel(GUEST_CR3, guest_cr3);
- if (vcpu->arch.cr0 & X86_CR0_PE)
- vmx_fpu_deactivate(vcpu);
}
static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -1748,8 +1806,14 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON);
vcpu->arch.cr4 = cr4;
- if (enable_ept)
- ept_update_paging_mode_cr4(&hw_cr4, vcpu);
+ if (enable_ept) {
+ if (!is_paging(vcpu)) {
+ hw_cr4 &= ~X86_CR4_PAE;
+ hw_cr4 |= X86_CR4_PSE;
+ } else if (!(cr4 & X86_CR4_PAE)) {
+ hw_cr4 &= ~X86_CR4_PAE;
+ }
+ }
vmcs_writel(CR4_READ_SHADOW, cr4);
vmcs_writel(GUEST_CR4, hw_cr4);
@@ -1787,7 +1851,7 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
static int vmx_get_cpl(struct kvm_vcpu *vcpu)
{
- if (!(vcpu->arch.cr0 & X86_CR0_PE)) /* if real mode */
+ if (!is_protmode(vcpu))
return 0;
if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */
@@ -2042,7 +2106,7 @@ static bool cs_ss_rpl_check(struct kvm_vcpu *vcpu)
static bool guest_state_valid(struct kvm_vcpu *vcpu)
{
/* real mode guest state checks */
- if (!(vcpu->arch.cr0 & X86_CR0_PE)) {
+ if (!is_protmode(vcpu)) {
if (!rmode_segment_valid(vcpu, VCPU_SREG_CS))
return false;
if (!rmode_segment_valid(vcpu, VCPU_SREG_SS))
@@ -2175,7 +2239,7 @@ static int alloc_apic_access_page(struct kvm *kvm)
struct kvm_userspace_memory_region kvm_userspace_mem;
int r = 0;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
if (kvm->arch.apic_access_page)
goto out;
kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
@@ -2188,7 +2252,7 @@ static int alloc_apic_access_page(struct kvm *kvm)
kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00);
out:
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return r;
}
@@ -2197,7 +2261,7 @@ static int alloc_identity_pagetable(struct kvm *kvm)
struct kvm_userspace_memory_region kvm_userspace_mem;
int r = 0;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
if (kvm->arch.ept_identity_pagetable)
goto out;
kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
@@ -2212,7 +2276,7 @@ static int alloc_identity_pagetable(struct kvm *kvm)
kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
kvm->arch.ept_identity_map_addr >> PAGE_SHIFT);
out:
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return r;
}
@@ -2384,14 +2448,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
for (i = 0; i < NR_VMX_MSR; ++i) {
u32 index = vmx_msr_index[i];
u32 data_low, data_high;
- u64 data;
int j = vmx->nmsrs;
if (rdmsr_safe(index, &data_low, &data_high) < 0)
continue;
if (wrmsr_safe(index, data_low, data_high) < 0)
continue;
- data = data_low | ((u64)data_high << 32);
vmx->guest_msrs[j].index = i;
vmx->guest_msrs[j].data = 0;
vmx->guest_msrs[j].mask = -1ull;
@@ -2404,7 +2466,10 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_ctrl);
vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
- vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
+ vmx->vcpu.arch.cr4_guest_owned_bits = KVM_CR4_GUEST_OWNED_BITS;
+ if (enable_ept)
+ vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE;
+ vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits);
tsc_base = vmx->vcpu.kvm->arch.vm_init_tsc;
rdtscll(tsc_this);
@@ -2429,10 +2494,10 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
u64 msr;
- int ret;
+ int ret, idx;
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP));
- down_read(&vcpu->kvm->slots_lock);
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
if (!init_rmode(vmx->vcpu.kvm)) {
ret = -ENOMEM;
goto out;
@@ -2526,7 +2591,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
vmx->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
- vmx_set_cr0(&vmx->vcpu, vmx->vcpu.arch.cr0); /* enter rmode */
+ vmx_set_cr0(&vmx->vcpu, kvm_read_cr0(vcpu)); /* enter rmode */
vmx_set_cr4(&vmx->vcpu, 0);
vmx_set_efer(&vmx->vcpu, 0);
vmx_fpu_activate(&vmx->vcpu);
@@ -2540,7 +2605,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
vmx->emulation_required = 0;
out:
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
return ret;
}
@@ -2717,6 +2782,12 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
kvm_queue_exception(vcpu, vec);
return 1;
case BP_VECTOR:
+ /*
+ * Update instruction length as we may reinject the exception
+ * from user space while in guest debugging mode.
+ */
+ to_vmx(vcpu)->vcpu.arch.event_exit_inst_len =
+ vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
return 0;
/* fall through */
@@ -2839,6 +2910,13 @@ static int handle_exception(struct kvm_vcpu *vcpu)
kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
/* fall through */
case BP_VECTOR:
+ /*
+ * Update instruction length as we may reinject #BP from
+ * user space while in guest debugging mode. Reading it for
+ * #DB as well causes no harm, it is not used in that case.
+ */
+ vmx->vcpu.arch.event_exit_inst_len =
+ vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
kvm_run->exit_reason = KVM_EXIT_DEBUG;
kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip;
kvm_run->debug.arch.exception = ex_no;
@@ -2940,11 +3018,10 @@ static int handle_cr(struct kvm_vcpu *vcpu)
};
break;
case 2: /* clts */
- vmx_fpu_deactivate(vcpu);
- vcpu->arch.cr0 &= ~X86_CR0_TS;
- vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
- vmx_fpu_activate(vcpu);
+ vmx_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
+ trace_kvm_cr_write(0, kvm_read_cr0(vcpu));
skip_emulated_instruction(vcpu);
+ vmx_fpu_activate(vcpu);
return 1;
case 1: /*mov from cr*/
switch (cr) {
@@ -2962,7 +3039,9 @@ static int handle_cr(struct kvm_vcpu *vcpu)
}
break;
case 3: /* lmsw */
- kvm_lmsw(vcpu, (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f);
+ val = (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f;
+ trace_kvm_cr_write(0, (kvm_read_cr0(vcpu) & ~0xful) | val);
+ kvm_lmsw(vcpu, val);
skip_emulated_instruction(vcpu);
return 1;
@@ -2975,12 +3054,22 @@ static int handle_cr(struct kvm_vcpu *vcpu)
return 0;
}
+static int check_dr_alias(struct kvm_vcpu *vcpu)
+{
+ if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ return -1;
+ }
+ return 0;
+}
+
static int handle_dr(struct kvm_vcpu *vcpu)
{
unsigned long exit_qualification;
unsigned long val;
int dr, reg;
+ /* Do not handle if the CPL > 0, will trigger GP on re-entry */
if (!kvm_require_cpl(vcpu, 0))
return 1;
dr = vmcs_readl(GUEST_DR7);
@@ -3016,14 +3105,20 @@ static int handle_dr(struct kvm_vcpu *vcpu)
case 0 ... 3:
val = vcpu->arch.db[dr];
break;
+ case 4:
+ if (check_dr_alias(vcpu) < 0)
+ return 1;
+ /* fall through */
case 6:
val = vcpu->arch.dr6;
break;
- case 7:
+ case 5:
+ if (check_dr_alias(vcpu) < 0)
+ return 1;
+ /* fall through */
+ default: /* 7 */
val = vcpu->arch.dr7;
break;
- default:
- val = 0;
}
kvm_register_write(vcpu, reg, val);
} else {
@@ -3034,21 +3129,25 @@ static int handle_dr(struct kvm_vcpu *vcpu)
if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
vcpu->arch.eff_db[dr] = val;
break;
- case 4 ... 5:
- if (vcpu->arch.cr4 & X86_CR4_DE)
- kvm_queue_exception(vcpu, UD_VECTOR);
- break;
+ case 4:
+ if (check_dr_alias(vcpu) < 0)
+ return 1;
+ /* fall through */
case 6:
if (val & 0xffffffff00000000ULL) {
- kvm_queue_exception(vcpu, GP_VECTOR);
- break;
+ kvm_inject_gp(vcpu, 0);
+ return 1;
}
vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
break;
- case 7:
+ case 5:
+ if (check_dr_alias(vcpu) < 0)
+ return 1;
+ /* fall through */
+ default: /* 7 */
if (val & 0xffffffff00000000ULL) {
- kvm_queue_exception(vcpu, GP_VECTOR);
- break;
+ kvm_inject_gp(vcpu, 0);
+ return 1;
}
vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
@@ -3075,6 +3174,7 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu)
u64 data;
if (vmx_get_msr(vcpu, ecx, &data)) {
+ trace_kvm_msr_read_ex(ecx);
kvm_inject_gp(vcpu, 0);
return 1;
}
@@ -3094,13 +3194,13 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu)
u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
| ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
- trace_kvm_msr_write(ecx, data);
-
if (vmx_set_msr(vcpu, ecx, data) != 0) {
+ trace_kvm_msr_write_ex(ecx, data);
kvm_inject_gp(vcpu, 0);
return 1;
}
+ trace_kvm_msr_write(ecx, data);
skip_emulated_instruction(vcpu);
return 1;
}
@@ -3385,7 +3485,6 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
}
if (err != EMULATE_DONE) {
- kvm_report_emulation_failure(vcpu, "emulation failure");
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
vcpu->run->internal.ndata = 0;
@@ -3416,6 +3515,12 @@ static int handle_pause(struct kvm_vcpu *vcpu)
return 1;
}
+static int handle_invalid_op(struct kvm_vcpu *vcpu)
+{
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ return 1;
+}
+
/*
* The exit handlers return 1 if the exit was handled fully and guest execution
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
@@ -3453,6 +3558,8 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[EXIT_REASON_EPT_VIOLATION] = handle_ept_violation,
[EXIT_REASON_EPT_MISCONFIG] = handle_ept_misconfig,
[EXIT_REASON_PAUSE_INSTRUCTION] = handle_pause,
+ [EXIT_REASON_MWAIT_INSTRUCTION] = handle_invalid_op,
+ [EXIT_REASON_MONITOR_INSTRUCTION] = handle_invalid_op,
};
static const int kvm_vmx_max_exit_handlers =
@@ -3686,9 +3793,6 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
*/
vmcs_writel(HOST_CR0, read_cr0());
- if (vcpu->arch.switch_db_regs)
- set_debugreg(vcpu->arch.dr6, 6);
-
asm(
/* Store host registers */
"push %%"R"dx; push %%"R"bp;"
@@ -3789,9 +3893,6 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
| (1 << VCPU_EXREG_PDPTR));
vcpu->arch.regs_dirty = 0;
- if (vcpu->arch.switch_db_regs)
- get_debugreg(vcpu->arch.dr6, 6);
-
vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
if (vmx->rmode.irq.pending)
fixup_rmode_irq(vmx);
@@ -3920,7 +4021,7 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
* b. VT-d with snooping control feature: snooping control feature of
* VT-d engine can guarantee the cache correctness. Just set it
* to WB to keep consistent with host. So the same as item 3.
- * 3. EPT without VT-d: always map as WB and set IGMT=1 to keep
+ * 3. EPT without VT-d: always map as WB and set IPAT=1 to keep
* consistent with host MTRR
*/
if (is_mmio)
@@ -3931,37 +4032,88 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
VMX_EPT_MT_EPTE_SHIFT;
else
ret = (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT)
- | VMX_EPT_IGMT_BIT;
+ | VMX_EPT_IPAT_BIT;
return ret;
}
+#define _ER(x) { EXIT_REASON_##x, #x }
+
static const struct trace_print_flags vmx_exit_reasons_str[] = {
- { EXIT_REASON_EXCEPTION_NMI, "exception" },
- { EXIT_REASON_EXTERNAL_INTERRUPT, "ext_irq" },
- { EXIT_REASON_TRIPLE_FAULT, "triple_fault" },
- { EXIT_REASON_NMI_WINDOW, "nmi_window" },
- { EXIT_REASON_IO_INSTRUCTION, "io_instruction" },
- { EXIT_REASON_CR_ACCESS, "cr_access" },
- { EXIT_REASON_DR_ACCESS, "dr_access" },
- { EXIT_REASON_CPUID, "cpuid" },
- { EXIT_REASON_MSR_READ, "rdmsr" },
- { EXIT_REASON_MSR_WRITE, "wrmsr" },
- { EXIT_REASON_PENDING_INTERRUPT, "interrupt_window" },
- { EXIT_REASON_HLT, "halt" },
- { EXIT_REASON_INVLPG, "invlpg" },
- { EXIT_REASON_VMCALL, "hypercall" },
- { EXIT_REASON_TPR_BELOW_THRESHOLD, "tpr_below_thres" },
- { EXIT_REASON_APIC_ACCESS, "apic_access" },
- { EXIT_REASON_WBINVD, "wbinvd" },
- { EXIT_REASON_TASK_SWITCH, "task_switch" },
- { EXIT_REASON_EPT_VIOLATION, "ept_violation" },
+ _ER(EXCEPTION_NMI),
+ _ER(EXTERNAL_INTERRUPT),
+ _ER(TRIPLE_FAULT),
+ _ER(PENDING_INTERRUPT),
+ _ER(NMI_WINDOW),
+ _ER(TASK_SWITCH),
+ _ER(CPUID),
+ _ER(HLT),
+ _ER(INVLPG),
+ _ER(RDPMC),
+ _ER(RDTSC),
+ _ER(VMCALL),
+ _ER(VMCLEAR),
+ _ER(VMLAUNCH),
+ _ER(VMPTRLD),
+ _ER(VMPTRST),
+ _ER(VMREAD),
+ _ER(VMRESUME),
+ _ER(VMWRITE),
+ _ER(VMOFF),
+ _ER(VMON),
+ _ER(CR_ACCESS),
+ _ER(DR_ACCESS),
+ _ER(IO_INSTRUCTION),
+ _ER(MSR_READ),
+ _ER(MSR_WRITE),
+ _ER(MWAIT_INSTRUCTION),
+ _ER(MONITOR_INSTRUCTION),
+ _ER(PAUSE_INSTRUCTION),
+ _ER(MCE_DURING_VMENTRY),
+ _ER(TPR_BELOW_THRESHOLD),
+ _ER(APIC_ACCESS),
+ _ER(EPT_VIOLATION),
+ _ER(EPT_MISCONFIG),
+ _ER(WBINVD),
{ -1, NULL }
};
-static bool vmx_gb_page_enable(void)
+#undef _ER
+
+static int vmx_get_lpage_level(void)
{
- return false;
+ if (enable_ept && !cpu_has_vmx_ept_1g_page())
+ return PT_DIRECTORY_LEVEL;
+ else
+ /* For shadow and EPT supported 1GB page */
+ return PT_PDPE_LEVEL;
+}
+
+static inline u32 bit(int bitno)
+{
+ return 1 << (bitno & 31);
+}
+
+static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpuid_entry2 *best;
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ u32 exec_control;
+
+ vmx->rdtscp_enabled = false;
+ if (vmx_rdtscp_supported()) {
+ exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+ if (exec_control & SECONDARY_EXEC_RDTSCP) {
+ best = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
+ if (best && (best->edx & bit(X86_FEATURE_RDTSCP)))
+ vmx->rdtscp_enabled = true;
+ else {
+ exec_control &= ~SECONDARY_EXEC_RDTSCP;
+ vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+ exec_control);
+ }
+ }
+ }
}
static struct kvm_x86_ops vmx_x86_ops = {
@@ -3990,6 +4142,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
.set_segment = vmx_set_segment,
.get_cpl = vmx_get_cpl,
.get_cs_db_l_bits = vmx_get_cs_db_l_bits,
+ .decache_cr0_guest_bits = vmx_decache_cr0_guest_bits,
.decache_cr4_guest_bits = vmx_decache_cr4_guest_bits,
.set_cr0 = vmx_set_cr0,
.set_cr3 = vmx_set_cr3,
@@ -4002,6 +4155,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
.cache_reg = vmx_cache_reg,
.get_rflags = vmx_get_rflags,
.set_rflags = vmx_set_rflags,
+ .fpu_activate = vmx_fpu_activate,
+ .fpu_deactivate = vmx_fpu_deactivate,
.tlb_flush = vmx_flush_tlb,
@@ -4027,7 +4182,11 @@ static struct kvm_x86_ops vmx_x86_ops = {
.get_mt_mask = vmx_get_mt_mask,
.exit_reasons_str = vmx_exit_reasons_str,
- .gb_page_enable = vmx_gb_page_enable,
+ .get_lpage_level = vmx_get_lpage_level,
+
+ .cpuid_update = vmx_cpuid_update,
+
+ .rdtscp_supported = vmx_rdtscp_supported,
};
static int __init vmx_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a1e1bc9d412..3c4ca98ad27 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -38,6 +38,8 @@
#include <linux/intel-iommu.h>
#include <linux/cpufreq.h>
#include <linux/user-return-notifier.h>
+#include <linux/srcu.h>
+#include <linux/slab.h>
#include <trace/events/kvm.h>
#undef TRACE_INCLUDE_FILE
#define CREATE_TRACE_POINTS
@@ -93,16 +95,16 @@ module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);
struct kvm_shared_msrs_global {
int nr;
- struct kvm_shared_msr {
- u32 msr;
- u64 value;
- } msrs[KVM_NR_SHARED_MSRS];
+ u32 msrs[KVM_NR_SHARED_MSRS];
};
struct kvm_shared_msrs {
struct user_return_notifier urn;
bool registered;
- u64 current_value[KVM_NR_SHARED_MSRS];
+ struct kvm_shared_msr_values {
+ u64 host;
+ u64 curr;
+ } values[KVM_NR_SHARED_MSRS];
};
static struct kvm_shared_msrs_global __read_mostly shared_msrs_global;
@@ -147,53 +149,64 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
static void kvm_on_user_return(struct user_return_notifier *urn)
{
unsigned slot;
- struct kvm_shared_msr *global;
struct kvm_shared_msrs *locals
= container_of(urn, struct kvm_shared_msrs, urn);
+ struct kvm_shared_msr_values *values;
for (slot = 0; slot < shared_msrs_global.nr; ++slot) {
- global = &shared_msrs_global.msrs[slot];
- if (global->value != locals->current_value[slot]) {
- wrmsrl(global->msr, global->value);
- locals->current_value[slot] = global->value;
+ values = &locals->values[slot];
+ if (values->host != values->curr) {
+ wrmsrl(shared_msrs_global.msrs[slot], values->host);
+ values->curr = values->host;
}
}
locals->registered = false;
user_return_notifier_unregister(urn);
}
-void kvm_define_shared_msr(unsigned slot, u32 msr)
+static void shared_msr_update(unsigned slot, u32 msr)
{
- int cpu;
+ struct kvm_shared_msrs *smsr;
u64 value;
+ smsr = &__get_cpu_var(shared_msrs);
+ /* only read, and nobody should modify it at this time,
+ * so don't need lock */
+ if (slot >= shared_msrs_global.nr) {
+ printk(KERN_ERR "kvm: invalid MSR slot!");
+ return;
+ }
+ rdmsrl_safe(msr, &value);
+ smsr->values[slot].host = value;
+ smsr->values[slot].curr = value;
+}
+
+void kvm_define_shared_msr(unsigned slot, u32 msr)
+{
if (slot >= shared_msrs_global.nr)
shared_msrs_global.nr = slot + 1;
- shared_msrs_global.msrs[slot].msr = msr;
- rdmsrl_safe(msr, &value);
- shared_msrs_global.msrs[slot].value = value;
- for_each_online_cpu(cpu)
- per_cpu(shared_msrs, cpu).current_value[slot] = value;
+ shared_msrs_global.msrs[slot] = msr;
+ /* we need ensured the shared_msr_global have been updated */
+ smp_wmb();
}
EXPORT_SYMBOL_GPL(kvm_define_shared_msr);
static void kvm_shared_msr_cpu_online(void)
{
unsigned i;
- struct kvm_shared_msrs *locals = &__get_cpu_var(shared_msrs);
for (i = 0; i < shared_msrs_global.nr; ++i)
- locals->current_value[i] = shared_msrs_global.msrs[i].value;
+ shared_msr_update(i, shared_msrs_global.msrs[i]);
}
void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
{
struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs);
- if (((value ^ smsr->current_value[slot]) & mask) == 0)
+ if (((value ^ smsr->values[slot].curr) & mask) == 0)
return;
- smsr->current_value[slot] = value;
- wrmsrl(shared_msrs_global.msrs[slot].msr, value);
+ smsr->values[slot].curr = value;
+ wrmsrl(shared_msrs_global.msrs[slot], value);
if (!smsr->registered) {
smsr->urn.on_user_return = kvm_on_user_return;
user_return_notifier_register(&smsr->urn);
@@ -257,12 +270,68 @@ void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data)
}
EXPORT_SYMBOL_GPL(kvm_set_apic_base);
+#define EXCPT_BENIGN 0
+#define EXCPT_CONTRIBUTORY 1
+#define EXCPT_PF 2
+
+static int exception_class(int vector)
+{
+ switch (vector) {
+ case PF_VECTOR:
+ return EXCPT_PF;
+ case DE_VECTOR:
+ case TS_VECTOR:
+ case NP_VECTOR:
+ case SS_VECTOR:
+ case GP_VECTOR:
+ return EXCPT_CONTRIBUTORY;
+ default:
+ break;
+ }
+ return EXCPT_BENIGN;
+}
+
+static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
+ unsigned nr, bool has_error, u32 error_code)
+{
+ u32 prev_nr;
+ int class1, class2;
+
+ if (!vcpu->arch.exception.pending) {
+ queue:
+ vcpu->arch.exception.pending = true;
+ vcpu->arch.exception.has_error_code = has_error;
+ vcpu->arch.exception.nr = nr;
+ vcpu->arch.exception.error_code = error_code;
+ return;
+ }
+
+ /* to check exception */
+ prev_nr = vcpu->arch.exception.nr;
+ if (prev_nr == DF_VECTOR) {
+ /* triple fault -> shutdown */
+ set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
+ return;
+ }
+ class1 = exception_class(prev_nr);
+ class2 = exception_class(nr);
+ if ((class1 == EXCPT_CONTRIBUTORY && class2 == EXCPT_CONTRIBUTORY)
+ || (class1 == EXCPT_PF && class2 != EXCPT_BENIGN)) {
+ /* generate double fault per SDM Table 5-5 */
+ vcpu->arch.exception.pending = true;
+ vcpu->arch.exception.has_error_code = true;
+ vcpu->arch.exception.nr = DF_VECTOR;
+ vcpu->arch.exception.error_code = 0;
+ } else
+ /* replace previous exception with a new one in a hope
+ that instruction re-execution will regenerate lost
+ exception */
+ goto queue;
+}
+
void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr)
{
- WARN_ON(vcpu->arch.exception.pending);
- vcpu->arch.exception.pending = true;
- vcpu->arch.exception.has_error_code = false;
- vcpu->arch.exception.nr = nr;
+ kvm_multiple_exception(vcpu, nr, false, 0);
}
EXPORT_SYMBOL_GPL(kvm_queue_exception);
@@ -270,25 +339,6 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
u32 error_code)
{
++vcpu->stat.pf_guest;
-
- if (vcpu->arch.exception.pending) {
- switch(vcpu->arch.exception.nr) {
- case DF_VECTOR:
- /* triple fault -> shutdown */
- set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
- return;
- case PF_VECTOR:
- vcpu->arch.exception.nr = DF_VECTOR;
- vcpu->arch.exception.error_code = 0;
- return;
- default:
- /* replace previous exception with a new one in a hope
- that instruction re-execution will regenerate lost
- exception */
- vcpu->arch.exception.pending = false;
- break;
- }
- }
vcpu->arch.cr2 = addr;
kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
}
@@ -301,11 +351,7 @@ EXPORT_SYMBOL_GPL(kvm_inject_nmi);
void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
{
- WARN_ON(vcpu->arch.exception.pending);
- vcpu->arch.exception.pending = true;
- vcpu->arch.exception.has_error_code = true;
- vcpu->arch.exception.nr = nr;
- vcpu->arch.exception.error_code = error_code;
+ kvm_multiple_exception(vcpu, nr, true, error_code);
}
EXPORT_SYMBOL_GPL(kvm_queue_exception_e);
@@ -383,41 +429,38 @@ out:
void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
- if (cr0 & CR0_RESERVED_BITS) {
- printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n",
- cr0, vcpu->arch.cr0);
+ cr0 |= X86_CR0_ET;
+
+#ifdef CONFIG_X86_64
+ if (cr0 & 0xffffffff00000000UL) {
kvm_inject_gp(vcpu, 0);
return;
}
+#endif
+
+ cr0 &= ~CR0_RESERVED_BITS;
if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) {
- printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n");
kvm_inject_gp(vcpu, 0);
return;
}
if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) {
- printk(KERN_DEBUG "set_cr0: #GP, set PG flag "
- "and a clear PE flag\n");
kvm_inject_gp(vcpu, 0);
return;
}
if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
#ifdef CONFIG_X86_64
- if ((vcpu->arch.shadow_efer & EFER_LME)) {
+ if ((vcpu->arch.efer & EFER_LME)) {
int cs_db, cs_l;
if (!is_pae(vcpu)) {
- printk(KERN_DEBUG "set_cr0: #GP, start paging "
- "in long mode while PAE is disabled\n");
kvm_inject_gp(vcpu, 0);
return;
}
kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
if (cs_l) {
- printk(KERN_DEBUG "set_cr0: #GP, start paging "
- "in long mode while CS.L == 1\n");
kvm_inject_gp(vcpu, 0);
return;
@@ -425,8 +468,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
} else
#endif
if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
- printk(KERN_DEBUG "set_cr0: #GP, pdptrs "
- "reserved bits\n");
kvm_inject_gp(vcpu, 0);
return;
}
@@ -443,38 +484,33 @@ EXPORT_SYMBOL_GPL(kvm_set_cr0);
void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
{
- kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f));
+ kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0ful) | (msw & 0x0f));
}
EXPORT_SYMBOL_GPL(kvm_lmsw);
void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
{
- unsigned long old_cr4 = vcpu->arch.cr4;
+ unsigned long old_cr4 = kvm_read_cr4(vcpu);
unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE;
if (cr4 & CR4_RESERVED_BITS) {
- printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n");
kvm_inject_gp(vcpu, 0);
return;
}
if (is_long_mode(vcpu)) {
if (!(cr4 & X86_CR4_PAE)) {
- printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while "
- "in long mode\n");
kvm_inject_gp(vcpu, 0);
return;
}
} else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
&& ((cr4 ^ old_cr4) & pdptr_bits)
&& !load_pdptrs(vcpu, vcpu->arch.cr3)) {
- printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
kvm_inject_gp(vcpu, 0);
return;
}
if (cr4 & X86_CR4_VMXE) {
- printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n");
kvm_inject_gp(vcpu, 0);
return;
}
@@ -495,21 +531,16 @@ void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
if (is_long_mode(vcpu)) {
if (cr3 & CR3_L_MODE_RESERVED_BITS) {
- printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
kvm_inject_gp(vcpu, 0);
return;
}
} else {
if (is_pae(vcpu)) {
if (cr3 & CR3_PAE_RESERVED_BITS) {
- printk(KERN_DEBUG
- "set_cr3: #GP, reserved bits\n");
kvm_inject_gp(vcpu, 0);
return;
}
if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) {
- printk(KERN_DEBUG "set_cr3: #GP, pdptrs "
- "reserved bits\n");
kvm_inject_gp(vcpu, 0);
return;
}
@@ -541,7 +572,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr3);
void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
{
if (cr8 & CR8_RESERVED_BITS) {
- printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8);
kvm_inject_gp(vcpu, 0);
return;
}
@@ -575,9 +605,11 @@ static inline u32 bit(int bitno)
* kvm-specific. Those are put in the beginning of the list.
*/
-#define KVM_SAVE_MSRS_BEGIN 2
+#define KVM_SAVE_MSRS_BEGIN 5
static u32 msrs_to_save[] = {
MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
+ HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
+ HV_X64_MSR_APIC_ASSIST_PAGE,
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
MSR_K6_STAR,
#ifdef CONFIG_X86_64
@@ -595,15 +627,12 @@ static u32 emulated_msrs[] = {
static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
{
if (efer & efer_reserved_bits) {
- printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
- efer);
kvm_inject_gp(vcpu, 0);
return;
}
if (is_paging(vcpu)
- && (vcpu->arch.shadow_efer & EFER_LME) != (efer & EFER_LME)) {
- printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n");
+ && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) {
kvm_inject_gp(vcpu, 0);
return;
}
@@ -613,7 +642,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) {
- printk(KERN_DEBUG "set_efer: #GP, enable FFXSR w/o CPUID capability\n");
kvm_inject_gp(vcpu, 0);
return;
}
@@ -624,7 +652,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) {
- printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n");
kvm_inject_gp(vcpu, 0);
return;
}
@@ -633,9 +660,9 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
kvm_x86_ops->set_efer(vcpu, efer);
efer &= ~EFER_LMA;
- efer |= vcpu->arch.shadow_efer & EFER_LMA;
+ efer |= vcpu->arch.efer & EFER_LMA;
- vcpu->arch.shadow_efer = efer;
+ vcpu->arch.efer = efer;
vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled;
kvm_mmu_reset_context(vcpu);
@@ -913,9 +940,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
if (msr >= MSR_IA32_MC0_CTL &&
msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
u32 offset = msr - MSR_IA32_MC0_CTL;
- /* only 0 or all 1s can be written to IA32_MCi_CTL */
+ /* only 0 or all 1s can be written to IA32_MCi_CTL
+ * some Linux kernels though clear bit 10 in bank 4 to
+ * workaround a BIOS/GART TBL issue on AMD K8s, ignore
+ * this to avoid an uncatched #GP in the guest
+ */
if ((offset & 0x3) == 0 &&
- data != 0 && data != ~(u64)0)
+ data != 0 && (data | (1 << 10)) != ~(u64)0)
return -1;
vcpu->arch.mce_banks[offset] = data;
break;
@@ -957,6 +988,100 @@ out:
return r;
}
+static bool kvm_hv_hypercall_enabled(struct kvm *kvm)
+{
+ return kvm->arch.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
+}
+
+static bool kvm_hv_msr_partition_wide(u32 msr)
+{
+ bool r = false;
+ switch (msr) {
+ case HV_X64_MSR_GUEST_OS_ID:
+ case HV_X64_MSR_HYPERCALL:
+ r = true;
+ break;
+ }
+
+ return r;
+}
+
+static int set_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+ struct kvm *kvm = vcpu->kvm;
+
+ switch (msr) {
+ case HV_X64_MSR_GUEST_OS_ID:
+ kvm->arch.hv_guest_os_id = data;
+ /* setting guest os id to zero disables hypercall page */
+ if (!kvm->arch.hv_guest_os_id)
+ kvm->arch.hv_hypercall &= ~HV_X64_MSR_HYPERCALL_ENABLE;
+ break;
+ case HV_X64_MSR_HYPERCALL: {
+ u64 gfn;
+ unsigned long addr;
+ u8 instructions[4];
+
+ /* if guest os id is not set hypercall should remain disabled */
+ if (!kvm->arch.hv_guest_os_id)
+ break;
+ if (!(data & HV_X64_MSR_HYPERCALL_ENABLE)) {
+ kvm->arch.hv_hypercall = data;
+ break;
+ }
+ gfn = data >> HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT;
+ addr = gfn_to_hva(kvm, gfn);
+ if (kvm_is_error_hva(addr))
+ return 1;
+ kvm_x86_ops->patch_hypercall(vcpu, instructions);
+ ((unsigned char *)instructions)[3] = 0xc3; /* ret */
+ if (copy_to_user((void __user *)addr, instructions, 4))
+ return 1;
+ kvm->arch.hv_hypercall = data;
+ break;
+ }
+ default:
+ pr_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x "
+ "data 0x%llx\n", msr, data);
+ return 1;
+ }
+ return 0;
+}
+
+static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+ switch (msr) {
+ case HV_X64_MSR_APIC_ASSIST_PAGE: {
+ unsigned long addr;
+
+ if (!(data & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE)) {
+ vcpu->arch.hv_vapic = data;
+ break;
+ }
+ addr = gfn_to_hva(vcpu->kvm, data >>
+ HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT);
+ if (kvm_is_error_hva(addr))
+ return 1;
+ if (clear_user((void __user *)addr, PAGE_SIZE))
+ return 1;
+ vcpu->arch.hv_vapic = data;
+ break;
+ }
+ case HV_X64_MSR_EOI:
+ return kvm_hv_vapic_msr_write(vcpu, APIC_EOI, data);
+ case HV_X64_MSR_ICR:
+ return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
+ case HV_X64_MSR_TPR:
+ return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
+ default:
+ pr_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x "
+ "data 0x%llx\n", msr, data);
+ return 1;
+ }
+
+ return 0;
+}
+
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
switch (msr) {
@@ -1071,6 +1196,16 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
"0x%x data 0x%llx\n", msr, data);
break;
+ case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
+ if (kvm_hv_msr_partition_wide(msr)) {
+ int r;
+ mutex_lock(&vcpu->kvm->lock);
+ r = set_msr_hyperv_pw(vcpu, msr, data);
+ mutex_unlock(&vcpu->kvm->lock);
+ return r;
+ } else
+ return set_msr_hyperv(vcpu, msr, data);
+ break;
default:
if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
return xen_hvm_config(vcpu, data);
@@ -1170,6 +1305,54 @@ static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
return 0;
}
+static int get_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+ u64 data = 0;
+ struct kvm *kvm = vcpu->kvm;
+
+ switch (msr) {
+ case HV_X64_MSR_GUEST_OS_ID:
+ data = kvm->arch.hv_guest_os_id;
+ break;
+ case HV_X64_MSR_HYPERCALL:
+ data = kvm->arch.hv_hypercall;
+ break;
+ default:
+ pr_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
+ return 1;
+ }
+
+ *pdata = data;
+ return 0;
+}
+
+static int get_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+ u64 data = 0;
+
+ switch (msr) {
+ case HV_X64_MSR_VP_INDEX: {
+ int r;
+ struct kvm_vcpu *v;
+ kvm_for_each_vcpu(r, v, vcpu->kvm)
+ if (v == vcpu)
+ data = r;
+ break;
+ }
+ case HV_X64_MSR_EOI:
+ return kvm_hv_vapic_msr_read(vcpu, APIC_EOI, pdata);
+ case HV_X64_MSR_ICR:
+ return kvm_hv_vapic_msr_read(vcpu, APIC_ICR, pdata);
+ case HV_X64_MSR_TPR:
+ return kvm_hv_vapic_msr_read(vcpu, APIC_TASKPRI, pdata);
+ default:
+ pr_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
+ return 1;
+ }
+ *pdata = data;
+ return 0;
+}
+
int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
{
u64 data;
@@ -1221,7 +1404,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
data |= (((uint64_t)4ULL) << 40);
break;
case MSR_EFER:
- data = vcpu->arch.shadow_efer;
+ data = vcpu->arch.efer;
break;
case MSR_KVM_WALL_CLOCK:
data = vcpu->kvm->arch.wall_clock;
@@ -1236,6 +1419,16 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_IA32_MCG_STATUS:
case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
return get_msr_mce(vcpu, msr, pdata);
+ case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
+ if (kvm_hv_msr_partition_wide(msr)) {
+ int r;
+ mutex_lock(&vcpu->kvm->lock);
+ r = get_msr_hyperv_pw(vcpu, msr, pdata);
+ mutex_unlock(&vcpu->kvm->lock);
+ return r;
+ } else
+ return get_msr_hyperv(vcpu, msr, pdata);
+ break;
default:
if (!ignore_msrs) {
pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);
@@ -1261,15 +1454,15 @@ static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs,
int (*do_msr)(struct kvm_vcpu *vcpu,
unsigned index, u64 *data))
{
- int i;
+ int i, idx;
vcpu_load(vcpu);
- down_read(&vcpu->kvm->slots_lock);
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
for (i = 0; i < msrs->nmsrs; ++i)
if (do_msr(vcpu, entries[i].index, &entries[i].data))
break;
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
vcpu_put(vcpu);
@@ -1351,6 +1544,11 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_XEN_HVM:
case KVM_CAP_ADJUST_CLOCK:
case KVM_CAP_VCPU_EVENTS:
+ case KVM_CAP_HYPERV:
+ case KVM_CAP_HYPERV_VAPIC:
+ case KVM_CAP_HYPERV_SPIN:
+ case KVM_CAP_PCI_SEGMENT:
+ case KVM_CAP_X86_ROBUST_SINGLESTEP:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -1464,8 +1662,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
{
- kvm_x86_ops->vcpu_put(vcpu);
kvm_put_guest_fpu(vcpu);
+ kvm_x86_ops->vcpu_put(vcpu);
}
static int is_efer_nx(void)
@@ -1530,6 +1728,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
cpuid_fix_nx_cap(vcpu);
r = 0;
kvm_apic_set_version(vcpu);
+ kvm_x86_ops->cpuid_update(vcpu);
out_free:
vfree(cpuid_entries);
@@ -1552,6 +1751,7 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
goto out;
vcpu->arch.cpuid_nent = cpuid->nent;
kvm_apic_set_version(vcpu);
+ kvm_x86_ops->cpuid_update(vcpu);
return 0;
out:
@@ -1594,12 +1794,15 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
u32 index, int *nent, int maxnent)
{
unsigned f_nx = is_efer_nx() ? F(NX) : 0;
- unsigned f_gbpages = kvm_x86_ops->gb_page_enable() ? F(GBPAGES) : 0;
#ifdef CONFIG_X86_64
+ unsigned f_gbpages = (kvm_x86_ops->get_lpage_level() == PT_PDPE_LEVEL)
+ ? F(GBPAGES) : 0;
unsigned f_lm = F(LM);
#else
+ unsigned f_gbpages = 0;
unsigned f_lm = 0;
#endif
+ unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
/* cpuid 1.edx */
const u32 kvm_supported_word0_x86_features =
@@ -1619,7 +1822,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
F(PAT) | F(PSE36) | 0 /* Reserved */ |
f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
- F(FXSR) | F(FXSR_OPT) | f_gbpages | 0 /* RDTSCP */ |
+ F(FXSR) | F(FXSR_OPT) | f_gbpages | f_rdtscp |
0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
/* cpuid 1.ecx */
const u32 kvm_supported_word4_x86_features =
@@ -1866,7 +2069,7 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
return 0;
if (mce->status & MCI_STATUS_UC) {
if ((vcpu->arch.mcg_status & MCG_STATUS_MCIP) ||
- !(vcpu->arch.cr4 & X86_CR4_MCE)) {
+ !kvm_read_cr4_bits(vcpu, X86_CR4_MCE)) {
printk(KERN_DEBUG "kvm: set_mce: "
"injects mce exception while "
"previous one is in progress!\n");
@@ -2160,14 +2363,14 @@ static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
return -EINVAL;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
spin_lock(&kvm->mmu_lock);
kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
spin_unlock(&kvm->mmu_lock);
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return 0;
}
@@ -2176,13 +2379,35 @@ static int kvm_vm_ioctl_get_nr_mmu_pages(struct kvm *kvm)
return kvm->arch.n_alloc_mmu_pages;
}
+gfn_t unalias_gfn_instantiation(struct kvm *kvm, gfn_t gfn)
+{
+ int i;
+ struct kvm_mem_alias *alias;
+ struct kvm_mem_aliases *aliases;
+
+ aliases = rcu_dereference(kvm->arch.aliases);
+
+ for (i = 0; i < aliases->naliases; ++i) {
+ alias = &aliases->aliases[i];
+ if (alias->flags & KVM_ALIAS_INVALID)
+ continue;
+ if (gfn >= alias->base_gfn
+ && gfn < alias->base_gfn + alias->npages)
+ return alias->target_gfn + gfn - alias->base_gfn;
+ }
+ return gfn;
+}
+
gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
{
int i;
struct kvm_mem_alias *alias;
+ struct kvm_mem_aliases *aliases;
- for (i = 0; i < kvm->arch.naliases; ++i) {
- alias = &kvm->arch.aliases[i];
+ aliases = rcu_dereference(kvm->arch.aliases);
+
+ for (i = 0; i < aliases->naliases; ++i) {
+ alias = &aliases->aliases[i];
if (gfn >= alias->base_gfn
&& gfn < alias->base_gfn + alias->npages)
return alias->target_gfn + gfn - alias->base_gfn;
@@ -2200,6 +2425,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
{
int r, n;
struct kvm_mem_alias *p;
+ struct kvm_mem_aliases *aliases, *old_aliases;
r = -EINVAL;
/* General sanity checks */
@@ -2216,26 +2442,48 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
< alias->target_phys_addr)
goto out;
- down_write(&kvm->slots_lock);
- spin_lock(&kvm->mmu_lock);
+ r = -ENOMEM;
+ aliases = kzalloc(sizeof(struct kvm_mem_aliases), GFP_KERNEL);
+ if (!aliases)
+ goto out;
+
+ mutex_lock(&kvm->slots_lock);
- p = &kvm->arch.aliases[alias->slot];
+ /* invalidate any gfn reference in case of deletion/shrinking */
+ memcpy(aliases, kvm->arch.aliases, sizeof(struct kvm_mem_aliases));
+ aliases->aliases[alias->slot].flags |= KVM_ALIAS_INVALID;
+ old_aliases = kvm->arch.aliases;
+ rcu_assign_pointer(kvm->arch.aliases, aliases);
+ synchronize_srcu_expedited(&kvm->srcu);
+ kvm_mmu_zap_all(kvm);
+ kfree(old_aliases);
+
+ r = -ENOMEM;
+ aliases = kzalloc(sizeof(struct kvm_mem_aliases), GFP_KERNEL);
+ if (!aliases)
+ goto out_unlock;
+
+ memcpy(aliases, kvm->arch.aliases, sizeof(struct kvm_mem_aliases));
+
+ p = &aliases->aliases[alias->slot];
p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
p->npages = alias->memory_size >> PAGE_SHIFT;
p->target_gfn = alias->target_phys_addr >> PAGE_SHIFT;
+ p->flags &= ~(KVM_ALIAS_INVALID);
for (n = KVM_ALIAS_SLOTS; n > 0; --n)
- if (kvm->arch.aliases[n - 1].npages)
+ if (aliases->aliases[n - 1].npages)
break;
- kvm->arch.naliases = n;
+ aliases->naliases = n;
- spin_unlock(&kvm->mmu_lock);
- kvm_mmu_zap_all(kvm);
-
- up_write(&kvm->slots_lock);
-
- return 0;
+ old_aliases = kvm->arch.aliases;
+ rcu_assign_pointer(kvm->arch.aliases, aliases);
+ synchronize_srcu_expedited(&kvm->srcu);
+ kfree(old_aliases);
+ r = 0;
+out_unlock:
+ mutex_unlock(&kvm->slots_lock);
out:
return r;
}
@@ -2273,18 +2521,18 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
r = 0;
switch (chip->chip_id) {
case KVM_IRQCHIP_PIC_MASTER:
- spin_lock(&pic_irqchip(kvm)->lock);
+ raw_spin_lock(&pic_irqchip(kvm)->lock);
memcpy(&pic_irqchip(kvm)->pics[0],
&chip->chip.pic,
sizeof(struct kvm_pic_state));
- spin_unlock(&pic_irqchip(kvm)->lock);
+ raw_spin_unlock(&pic_irqchip(kvm)->lock);
break;
case KVM_IRQCHIP_PIC_SLAVE:
- spin_lock(&pic_irqchip(kvm)->lock);
+ raw_spin_lock(&pic_irqchip(kvm)->lock);
memcpy(&pic_irqchip(kvm)->pics[1],
&chip->chip.pic,
sizeof(struct kvm_pic_state));
- spin_unlock(&pic_irqchip(kvm)->lock);
+ raw_spin_unlock(&pic_irqchip(kvm)->lock);
break;
case KVM_IRQCHIP_IOAPIC:
r = kvm_set_ioapic(kvm, &chip->chip.ioapic);
@@ -2364,29 +2612,63 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
struct kvm_dirty_log *log)
{
- int r;
- int n;
+ int r, i;
struct kvm_memory_slot *memslot;
- int is_dirty = 0;
+ unsigned long n;
+ unsigned long is_dirty = 0;
+ unsigned long *dirty_bitmap = NULL;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
- r = kvm_get_dirty_log(kvm, log, &is_dirty);
- if (r)
+ r = -EINVAL;
+ if (log->slot >= KVM_MEMORY_SLOTS)
+ goto out;
+
+ memslot = &kvm->memslots->memslots[log->slot];
+ r = -ENOENT;
+ if (!memslot->dirty_bitmap)
+ goto out;
+
+ n = kvm_dirty_bitmap_bytes(memslot);
+
+ r = -ENOMEM;
+ dirty_bitmap = vmalloc(n);
+ if (!dirty_bitmap)
goto out;
+ memset(dirty_bitmap, 0, n);
+
+ for (i = 0; !is_dirty && i < n/sizeof(long); i++)
+ is_dirty = memslot->dirty_bitmap[i];
/* If nothing is dirty, don't bother messing with page tables. */
if (is_dirty) {
+ struct kvm_memslots *slots, *old_slots;
+
spin_lock(&kvm->mmu_lock);
kvm_mmu_slot_remove_write_access(kvm, log->slot);
spin_unlock(&kvm->mmu_lock);
- memslot = &kvm->memslots[log->slot];
- n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
- memset(memslot->dirty_bitmap, 0, n);
+
+ slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
+ if (!slots)
+ goto out_free;
+
+ memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
+ slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+
+ old_slots = kvm->memslots;
+ rcu_assign_pointer(kvm->memslots, slots);
+ synchronize_srcu_expedited(&kvm->srcu);
+ dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
+ kfree(old_slots);
}
+
r = 0;
+ if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
+ r = -EFAULT;
+out_free:
+ vfree(dirty_bitmap);
out:
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return r;
}
@@ -2469,6 +2751,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (vpic) {
r = kvm_ioapic_init(kvm);
if (r) {
+ kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS,
+ &vpic->dev);
kfree(vpic);
goto create_irqchip_unlock;
}
@@ -2480,10 +2764,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = kvm_setup_default_irq_routing(kvm);
if (r) {
mutex_lock(&kvm->irq_lock);
- kfree(kvm->arch.vpic);
- kfree(kvm->arch.vioapic);
- kvm->arch.vpic = NULL;
- kvm->arch.vioapic = NULL;
+ kvm_ioapic_destroy(kvm);
+ kvm_destroy_pic(kvm);
mutex_unlock(&kvm->irq_lock);
}
create_irqchip_unlock:
@@ -2499,7 +2781,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
sizeof(struct kvm_pit_config)))
goto out;
create_pit:
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
r = -EEXIST;
if (kvm->arch.vpit)
goto create_pit_unlock;
@@ -2508,7 +2790,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (kvm->arch.vpit)
r = 0;
create_pit_unlock:
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
break;
case KVM_IRQ_LINE_STATUS:
case KVM_IRQ_LINE: {
@@ -2725,7 +3007,7 @@ static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
!kvm_iodevice_write(&vcpu->arch.apic->dev, addr, len, v))
return 0;
- return kvm_io_bus_write(&vcpu->kvm->mmio_bus, addr, len, v);
+ return kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, addr, len, v);
}
static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
@@ -2734,17 +3016,44 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
!kvm_iodevice_read(&vcpu->arch.apic->dev, addr, len, v))
return 0;
- return kvm_io_bus_read(&vcpu->kvm->mmio_bus, addr, len, v);
+ return kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, len, v);
}
-static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
- struct kvm_vcpu *vcpu)
+gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+{
+ u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+}
+
+ gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+{
+ u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ access |= PFERR_FETCH_MASK;
+ return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+}
+
+gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+{
+ u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ access |= PFERR_WRITE_MASK;
+ return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error);
+}
+
+/* uses this to access any guest's mapped memory without checking CPL */
+gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error)
+{
+ return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, 0, error);
+}
+
+static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
+ struct kvm_vcpu *vcpu, u32 access,
+ u32 *error)
{
void *data = val;
int r = X86EMUL_CONTINUE;
while (bytes) {
- gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+ gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, access, error);
unsigned offset = addr & (PAGE_SIZE-1);
unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
@@ -2767,14 +3076,37 @@ out:
return r;
}
+/* used for instruction fetching */
+static int kvm_fetch_guest_virt(gva_t addr, void *val, unsigned int bytes,
+ struct kvm_vcpu *vcpu, u32 *error)
+{
+ u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ return kvm_read_guest_virt_helper(addr, val, bytes, vcpu,
+ access | PFERR_FETCH_MASK, error);
+}
+
+static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
+ struct kvm_vcpu *vcpu, u32 *error)
+{
+ u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access,
+ error);
+}
+
+static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes,
+ struct kvm_vcpu *vcpu, u32 *error)
+{
+ return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error);
+}
+
static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
- struct kvm_vcpu *vcpu)
+ struct kvm_vcpu *vcpu, u32 *error)
{
void *data = val;
int r = X86EMUL_CONTINUE;
while (bytes) {
- gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+ gpa_t gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error);
unsigned offset = addr & (PAGE_SIZE-1);
unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
@@ -2804,6 +3136,7 @@ static int emulator_read_emulated(unsigned long addr,
struct kvm_vcpu *vcpu)
{
gpa_t gpa;
+ u32 error_code;
if (vcpu->mmio_read_completed) {
memcpy(val, vcpu->mmio_data, bytes);
@@ -2813,17 +3146,20 @@ static int emulator_read_emulated(unsigned long addr,
return X86EMUL_CONTINUE;
}
- gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+ gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, &error_code);
+
+ if (gpa == UNMAPPED_GVA) {
+ kvm_inject_page_fault(vcpu, addr, error_code);
+ return X86EMUL_PROPAGATE_FAULT;
+ }
/* For APIC access vmexit */
if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
goto mmio;
- if (kvm_read_guest_virt(addr, val, bytes, vcpu)
+ if (kvm_read_guest_virt(addr, val, bytes, vcpu, NULL)
== X86EMUL_CONTINUE)
return X86EMUL_CONTINUE;
- if (gpa == UNMAPPED_GVA)
- return X86EMUL_PROPAGATE_FAULT;
mmio:
/*
@@ -2862,11 +3198,12 @@ static int emulator_write_emulated_onepage(unsigned long addr,
struct kvm_vcpu *vcpu)
{
gpa_t gpa;
+ u32 error_code;
- gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+ gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, &error_code);
if (gpa == UNMAPPED_GVA) {
- kvm_inject_page_fault(vcpu, addr, 2);
+ kvm_inject_page_fault(vcpu, addr, error_code);
return X86EMUL_PROPAGATE_FAULT;
}
@@ -2930,7 +3267,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
char *kaddr;
u64 val;
- gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+ gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL);
if (gpa == UNMAPPED_GVA ||
(gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
@@ -2967,35 +3304,21 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
int emulate_clts(struct kvm_vcpu *vcpu)
{
- kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS);
+ kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
+ kvm_x86_ops->fpu_activate(vcpu);
return X86EMUL_CONTINUE;
}
int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest)
{
- struct kvm_vcpu *vcpu = ctxt->vcpu;
-
- switch (dr) {
- case 0 ... 3:
- *dest = kvm_x86_ops->get_dr(vcpu, dr);
- return X86EMUL_CONTINUE;
- default:
- pr_unimpl(vcpu, "%s: unexpected dr %u\n", __func__, dr);
- return X86EMUL_UNHANDLEABLE;
- }
+ return kvm_x86_ops->get_dr(ctxt->vcpu, dr, dest);
}
int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
{
unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U;
- int exception;
- kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask, &exception);
- if (exception) {
- /* FIXME: better handling */
- return X86EMUL_UNHANDLEABLE;
- }
- return X86EMUL_CONTINUE;
+ return kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask);
}
void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
@@ -3009,7 +3332,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
- kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu);
+ kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu, NULL);
printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
@@ -3017,7 +3340,8 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
static struct x86_emulate_ops emulate_ops = {
- .read_std = kvm_read_guest_virt,
+ .read_std = kvm_read_guest_virt_system,
+ .fetch = kvm_fetch_guest_virt,
.read_emulated = emulator_read_emulated,
.write_emulated = emulator_write_emulated,
.cmpxchg_emulated = emulator_cmpxchg_emulated,
@@ -3060,8 +3384,9 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
vcpu->arch.emulate_ctxt.vcpu = vcpu;
vcpu->arch.emulate_ctxt.eflags = kvm_get_rflags(vcpu);
vcpu->arch.emulate_ctxt.mode =
+ (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
(vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
- ? X86EMUL_MODE_REAL : cs_l
+ ? X86EMUL_MODE_VM86 : cs_l
? X86EMUL_MODE_PROT64 : cs_db
? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
@@ -3153,12 +3478,17 @@ static int pio_copy_data(struct kvm_vcpu *vcpu)
gva_t q = vcpu->arch.pio.guest_gva;
unsigned bytes;
int ret;
+ u32 error_code;
bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count;
if (vcpu->arch.pio.in)
- ret = kvm_write_guest_virt(q, p, bytes, vcpu);
+ ret = kvm_write_guest_virt(q, p, bytes, vcpu, &error_code);
else
- ret = kvm_read_guest_virt(q, p, bytes, vcpu);
+ ret = kvm_read_guest_virt(q, p, bytes, vcpu, &error_code);
+
+ if (ret == X86EMUL_PROPAGATE_FAULT)
+ kvm_inject_page_fault(vcpu, q, error_code);
+
return ret;
}
@@ -3179,7 +3509,7 @@ int complete_pio(struct kvm_vcpu *vcpu)
if (io->in) {
r = pio_copy_data(vcpu);
if (r)
- return r;
+ goto out;
}
delta = 1;
@@ -3206,7 +3536,7 @@ int complete_pio(struct kvm_vcpu *vcpu)
kvm_register_write(vcpu, VCPU_REGS_RSI, val);
}
}
-
+out:
io->count -= io->cur_count;
io->cur_count = 0;
@@ -3219,11 +3549,12 @@ static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
int r;
if (vcpu->arch.pio.in)
- r = kvm_io_bus_read(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
+ r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port,
vcpu->arch.pio.size, pd);
else
- r = kvm_io_bus_write(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
- vcpu->arch.pio.size, pd);
+ r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
+ vcpu->arch.pio.port, vcpu->arch.pio.size,
+ pd);
return r;
}
@@ -3234,7 +3565,7 @@ static int pio_string_write(struct kvm_vcpu *vcpu)
int i, r = 0;
for (i = 0; i < io->cur_count; i++) {
- if (kvm_io_bus_write(&vcpu->kvm->pio_bus,
+ if (kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
io->port, io->size, pd)) {
r = -EOPNOTSUPP;
break;
@@ -3248,6 +3579,8 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port)
{
unsigned long val;
+ trace_kvm_pio(!in, port, size, 1);
+
vcpu->run->exit_reason = KVM_EXIT_IO;
vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
vcpu->run->io.size = vcpu->arch.pio.size = size;
@@ -3259,11 +3592,10 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port)
vcpu->arch.pio.down = 0;
vcpu->arch.pio.rep = 0;
- trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
- size, 1);
-
- val = kvm_register_read(vcpu, VCPU_REGS_RAX);
- memcpy(vcpu->arch.pio_data, &val, 4);
+ if (!vcpu->arch.pio.in) {
+ val = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ memcpy(vcpu->arch.pio_data, &val, 4);
+ }
if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
complete_pio(vcpu);
@@ -3280,6 +3612,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
unsigned now, in_page;
int ret = 0;
+ trace_kvm_pio(!in, port, size, count);
+
vcpu->run->exit_reason = KVM_EXIT_IO;
vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
vcpu->run->io.size = vcpu->arch.pio.size = size;
@@ -3291,9 +3625,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
vcpu->arch.pio.down = down;
vcpu->arch.pio.rep = rep;
- trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
- size, count);
-
if (!count) {
kvm_x86_ops->skip_emulated_instruction(vcpu);
return 1;
@@ -3325,10 +3656,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
if (!vcpu->arch.pio.in) {
/* string PIO write */
ret = pio_copy_data(vcpu);
- if (ret == X86EMUL_PROPAGATE_FAULT) {
- kvm_inject_gp(vcpu, 0);
+ if (ret == X86EMUL_PROPAGATE_FAULT)
return 1;
- }
if (ret == 0 && !pio_string_write(vcpu)) {
complete_pio(vcpu);
if (vcpu->arch.pio.count == 0)
@@ -3487,11 +3816,76 @@ static inline gpa_t hc_gpa(struct kvm_vcpu *vcpu, unsigned long a0,
return a0 | ((gpa_t)a1 << 32);
}
+int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
+{
+ u64 param, ingpa, outgpa, ret;
+ uint16_t code, rep_idx, rep_cnt, res = HV_STATUS_SUCCESS, rep_done = 0;
+ bool fast, longmode;
+ int cs_db, cs_l;
+
+ /*
+ * hypercall generates UD from non zero cpl and real mode
+ * per HYPER-V spec
+ */
+ if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ return 0;
+ }
+
+ kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+ longmode = is_long_mode(vcpu) && cs_l == 1;
+
+ if (!longmode) {
+ param = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDX) << 32) |
+ (kvm_register_read(vcpu, VCPU_REGS_RAX) & 0xffffffff);
+ ingpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RBX) << 32) |
+ (kvm_register_read(vcpu, VCPU_REGS_RCX) & 0xffffffff);
+ outgpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDI) << 32) |
+ (kvm_register_read(vcpu, VCPU_REGS_RSI) & 0xffffffff);
+ }
+#ifdef CONFIG_X86_64
+ else {
+ param = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ ingpa = kvm_register_read(vcpu, VCPU_REGS_RDX);
+ outgpa = kvm_register_read(vcpu, VCPU_REGS_R8);
+ }
+#endif
+
+ code = param & 0xffff;
+ fast = (param >> 16) & 0x1;
+ rep_cnt = (param >> 32) & 0xfff;
+ rep_idx = (param >> 48) & 0xfff;
+
+ trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
+
+ switch (code) {
+ case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
+ kvm_vcpu_on_spin(vcpu);
+ break;
+ default:
+ res = HV_STATUS_INVALID_HYPERCALL_CODE;
+ break;
+ }
+
+ ret = res | (((u64)rep_done & 0xfff) << 32);
+ if (longmode) {
+ kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
+ } else {
+ kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
+ kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff);
+ }
+
+ return 1;
+}
+
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
{
unsigned long nr, a0, a1, a2, a3, ret;
int r = 1;
+ if (kvm_hv_hypercall_enabled(vcpu->kvm))
+ return kvm_hv_hypercall(vcpu);
+
nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
a0 = kvm_register_read(vcpu, VCPU_REGS_RBX);
a1 = kvm_register_read(vcpu, VCPU_REGS_RCX);
@@ -3534,10 +3928,8 @@ EXPORT_SYMBOL_GPL(kvm_emulate_hypercall);
int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
{
char instruction[3];
- int ret = 0;
unsigned long rip = kvm_rip_read(vcpu);
-
/*
* Blow out the MMU to ensure that no other VCPU has an active mapping
* to ensure that the updated hypercall appears atomically across all
@@ -3546,11 +3938,8 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
kvm_mmu_zap_all(vcpu->kvm);
kvm_x86_ops->patch_hypercall(vcpu, instruction);
- if (emulator_write_emulated(rip, instruction, 3, vcpu)
- != X86EMUL_CONTINUE)
- ret = -EFAULT;
- return ret;
+ return emulator_write_emulated(rip, instruction, 3, vcpu);
}
static u64 mk_cr_64(u64 curr_cr, u32 new_val)
@@ -3583,10 +3972,9 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
{
unsigned long value;
- kvm_x86_ops->decache_cr4_guest_bits(vcpu);
switch (cr) {
case 0:
- value = vcpu->arch.cr0;
+ value = kvm_read_cr0(vcpu);
break;
case 2:
value = vcpu->arch.cr2;
@@ -3595,7 +3983,7 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
value = vcpu->arch.cr3;
break;
case 4:
- value = vcpu->arch.cr4;
+ value = kvm_read_cr4(vcpu);
break;
case 8:
value = kvm_get_cr8(vcpu);
@@ -3613,7 +4001,7 @@ void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val,
{
switch (cr) {
case 0:
- kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val));
+ kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val));
*rflags = kvm_get_rflags(vcpu);
break;
case 2:
@@ -3623,7 +4011,7 @@ void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val,
kvm_set_cr3(vcpu, val);
break;
case 4:
- kvm_set_cr4(vcpu, mk_cr_64(vcpu->arch.cr4, val));
+ kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val));
break;
case 8:
kvm_set_cr8(vcpu, val & 0xfUL);
@@ -3690,6 +4078,7 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
}
return best;
}
+EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
int cpuid_maxphyaddr(struct kvm_vcpu *vcpu)
{
@@ -3773,14 +4162,15 @@ static void vapic_enter(struct kvm_vcpu *vcpu)
static void vapic_exit(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
+ int idx;
if (!apic || !apic->vapic_addr)
return;
- down_read(&vcpu->kvm->slots_lock);
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
kvm_release_page_dirty(apic->vapic_page);
mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
}
static void update_cr8_intercept(struct kvm_vcpu *vcpu)
@@ -3876,12 +4266,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
r = 0;
goto out;
}
+ if (test_and_clear_bit(KVM_REQ_DEACTIVATE_FPU, &vcpu->requests)) {
+ vcpu->fpu_active = 0;
+ kvm_x86_ops->fpu_deactivate(vcpu);
+ }
}
preempt_disable();
kvm_x86_ops->prepare_guest_switch(vcpu);
- kvm_load_guest_fpu(vcpu);
+ if (vcpu->fpu_active)
+ kvm_load_guest_fpu(vcpu);
local_irq_disable();
@@ -3909,7 +4304,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_lapic_sync_to_vapic(vcpu);
}
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
kvm_guest_enter();
@@ -3951,7 +4346,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
preempt_enable();
- down_read(&vcpu->kvm->slots_lock);
+ vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
/*
* Profile KVM exit RIPs:
@@ -3973,6 +4368,7 @@ out:
static int __vcpu_run(struct kvm_vcpu *vcpu)
{
int r;
+ struct kvm *kvm = vcpu->kvm;
if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED)) {
pr_debug("vcpu %d received sipi with vector # %x\n",
@@ -3984,7 +4380,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
}
- down_read(&vcpu->kvm->slots_lock);
+ vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
vapic_enter(vcpu);
r = 1;
@@ -3992,9 +4388,9 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
r = vcpu_enter_guest(vcpu);
else {
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
kvm_vcpu_block(vcpu);
- down_read(&vcpu->kvm->slots_lock);
+ vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests))
{
switch(vcpu->arch.mp_state) {
@@ -4029,13 +4425,13 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
++vcpu->stat.signal_exits;
}
if (need_resched()) {
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
kvm_resched(vcpu);
- down_read(&vcpu->kvm->slots_lock);
+ vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
}
}
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
post_kvm_run_save(vcpu);
vapic_exit(vcpu);
@@ -4065,7 +4461,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_set_cr8(vcpu, kvm_run->cr8);
if (vcpu->arch.pio.cur_count) {
+ vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
r = complete_pio(vcpu);
+ srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
if (r)
goto out;
}
@@ -4074,10 +4472,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
vcpu->mmio_read_completed = 1;
vcpu->mmio_needed = 0;
- down_read(&vcpu->kvm->slots_lock);
+ vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
r = emulate_instruction(vcpu, vcpu->arch.mmio_fault_cr2, 0,
EMULTYPE_NO_DECODE);
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
if (r == EMULATE_DO_MMIO) {
/*
* Read-modify-write. Back to userspace.
@@ -4204,13 +4602,12 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
sregs->gdt.limit = dt.limit;
sregs->gdt.base = dt.base;
- kvm_x86_ops->decache_cr4_guest_bits(vcpu);
- sregs->cr0 = vcpu->arch.cr0;
+ sregs->cr0 = kvm_read_cr0(vcpu);
sregs->cr2 = vcpu->arch.cr2;
sregs->cr3 = vcpu->arch.cr3;
- sregs->cr4 = vcpu->arch.cr4;
+ sregs->cr4 = kvm_read_cr4(vcpu);
sregs->cr8 = kvm_get_cr8(vcpu);
- sregs->efer = vcpu->arch.shadow_efer;
+ sregs->efer = vcpu->arch.efer;
sregs->apic_base = kvm_get_apic_base(vcpu);
memset(sregs->interrupt_bitmap, 0, sizeof sregs->interrupt_bitmap);
@@ -4298,14 +4695,23 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
{
struct descriptor_table dtable;
u16 index = selector >> 3;
+ int ret;
+ u32 err;
+ gva_t addr;
get_segment_descriptor_dtable(vcpu, selector, &dtable);
if (dtable.limit < index * 8 + 7) {
kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
- return 1;
+ return X86EMUL_PROPAGATE_FAULT;
}
- return kvm_read_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
+ addr = dtable.base + index * 8;
+ ret = kvm_read_guest_virt_system(addr, seg_desc, sizeof(*seg_desc),
+ vcpu, &err);
+ if (ret == X86EMUL_PROPAGATE_FAULT)
+ kvm_inject_page_fault(vcpu, addr, err);
+
+ return ret;
}
/* allowed just for 8 bytes segments */
@@ -4319,15 +4725,23 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
if (dtable.limit < index * 8 + 7)
return 1;
- return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
+ return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu, NULL);
}
-static gpa_t get_tss_base_addr(struct kvm_vcpu *vcpu,
+static gpa_t get_tss_base_addr_write(struct kvm_vcpu *vcpu,
+ struct desc_struct *seg_desc)
+{
+ u32 base_addr = get_desc_base(seg_desc);
+
+ return kvm_mmu_gva_to_gpa_write(vcpu, base_addr, NULL);
+}
+
+static gpa_t get_tss_base_addr_read(struct kvm_vcpu *vcpu,
struct desc_struct *seg_desc)
{
u32 base_addr = get_desc_base(seg_desc);
- return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
+ return kvm_mmu_gva_to_gpa_read(vcpu, base_addr, NULL);
}
static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg)
@@ -4338,18 +4752,6 @@ static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg)
return kvm_seg.selector;
}
-static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu,
- u16 selector,
- struct kvm_segment *kvm_seg)
-{
- struct desc_struct seg_desc;
-
- if (load_guest_segment_descriptor(vcpu, selector, &seg_desc))
- return 1;
- seg_desct_to_kvm_desct(&seg_desc, selector, kvm_seg);
- return 0;
-}
-
static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg)
{
struct kvm_segment segvar = {
@@ -4367,7 +4769,7 @@ static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int se
.unusable = 0,
};
kvm_x86_ops->set_segment(vcpu, &segvar, seg);
- return 0;
+ return X86EMUL_CONTINUE;
}
static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg)
@@ -4377,24 +4779,112 @@ static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg)
(kvm_get_rflags(vcpu) & X86_EFLAGS_VM);
}
-int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
- int type_bits, int seg)
+int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg)
{
struct kvm_segment kvm_seg;
+ struct desc_struct seg_desc;
+ u8 dpl, rpl, cpl;
+ unsigned err_vec = GP_VECTOR;
+ u32 err_code = 0;
+ bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */
+ int ret;
- if (is_vm86_segment(vcpu, seg) || !(vcpu->arch.cr0 & X86_CR0_PE))
+ if (is_vm86_segment(vcpu, seg) || !is_protmode(vcpu))
return kvm_load_realmode_segment(vcpu, selector, seg);
- if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
- return 1;
- kvm_seg.type |= type_bits;
- if (seg != VCPU_SREG_SS && seg != VCPU_SREG_CS &&
- seg != VCPU_SREG_LDTR)
- if (!kvm_seg.s)
- kvm_seg.unusable = 1;
+ /* NULL selector is not valid for TR, CS and SS */
+ if ((seg == VCPU_SREG_CS || seg == VCPU_SREG_SS || seg == VCPU_SREG_TR)
+ && null_selector)
+ goto exception;
+
+ /* TR should be in GDT only */
+ if (seg == VCPU_SREG_TR && (selector & (1 << 2)))
+ goto exception;
+
+ ret = load_guest_segment_descriptor(vcpu, selector, &seg_desc);
+ if (ret)
+ return ret;
+
+ seg_desct_to_kvm_desct(&seg_desc, selector, &kvm_seg);
+
+ if (null_selector) { /* for NULL selector skip all following checks */
+ kvm_seg.unusable = 1;
+ goto load;
+ }
+
+ err_code = selector & 0xfffc;
+ err_vec = GP_VECTOR;
+ /* can't load system descriptor into segment selecor */
+ if (seg <= VCPU_SREG_GS && !kvm_seg.s)
+ goto exception;
+
+ if (!kvm_seg.present) {
+ err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR;
+ goto exception;
+ }
+
+ rpl = selector & 3;
+ dpl = kvm_seg.dpl;
+ cpl = kvm_x86_ops->get_cpl(vcpu);
+
+ switch (seg) {
+ case VCPU_SREG_SS:
+ /*
+ * segment is not a writable data segment or segment
+ * selector's RPL != CPL or segment selector's RPL != CPL
+ */
+ if (rpl != cpl || (kvm_seg.type & 0xa) != 0x2 || dpl != cpl)
+ goto exception;
+ break;
+ case VCPU_SREG_CS:
+ if (!(kvm_seg.type & 8))
+ goto exception;
+
+ if (kvm_seg.type & 4) {
+ /* conforming */
+ if (dpl > cpl)
+ goto exception;
+ } else {
+ /* nonconforming */
+ if (rpl > cpl || dpl != cpl)
+ goto exception;
+ }
+ /* CS(RPL) <- CPL */
+ selector = (selector & 0xfffc) | cpl;
+ break;
+ case VCPU_SREG_TR:
+ if (kvm_seg.s || (kvm_seg.type != 1 && kvm_seg.type != 9))
+ goto exception;
+ break;
+ case VCPU_SREG_LDTR:
+ if (kvm_seg.s || kvm_seg.type != 2)
+ goto exception;
+ break;
+ default: /* DS, ES, FS, or GS */
+ /*
+ * segment is not a data or readable code segment or
+ * ((segment is a data or nonconforming code segment)
+ * and (both RPL and CPL > DPL))
+ */
+ if ((kvm_seg.type & 0xa) == 0x8 ||
+ (((kvm_seg.type & 0xc) != 0xc) && (rpl > dpl && cpl > dpl)))
+ goto exception;
+ break;
+ }
+
+ if (!kvm_seg.unusable && kvm_seg.s) {
+ /* mark segment as accessed */
+ kvm_seg.type |= 1;
+ seg_desc.type |= 1;
+ save_guest_segment_descriptor(vcpu, selector, &seg_desc);
+ }
+load:
kvm_set_segment(vcpu, &kvm_seg, seg);
- return 0;
+ return X86EMUL_CONTINUE;
+exception:
+ kvm_queue_exception_e(vcpu, err_vec, err_code);
+ return X86EMUL_PROPAGATE_FAULT;
}
static void save_state_to_tss32(struct kvm_vcpu *vcpu,
@@ -4420,6 +4910,14 @@ static void save_state_to_tss32(struct kvm_vcpu *vcpu,
tss->ldt_selector = get_segment_selector(vcpu, VCPU_SREG_LDTR);
}
+static void kvm_load_segment_selector(struct kvm_vcpu *vcpu, u16 sel, int seg)
+{
+ struct kvm_segment kvm_seg;
+ kvm_get_segment(vcpu, &kvm_seg, seg);
+ kvm_seg.selector = sel;
+ kvm_set_segment(vcpu, &kvm_seg, seg);
+}
+
static int load_state_from_tss32(struct kvm_vcpu *vcpu,
struct tss_segment_32 *tss)
{
@@ -4437,25 +4935,41 @@ static int load_state_from_tss32(struct kvm_vcpu *vcpu,
kvm_register_write(vcpu, VCPU_REGS_RSI, tss->esi);
kvm_register_write(vcpu, VCPU_REGS_RDI, tss->edi);
- if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, 0, VCPU_SREG_LDTR))
+ /*
+ * SDM says that segment selectors are loaded before segment
+ * descriptors
+ */
+ kvm_load_segment_selector(vcpu, tss->ldt_selector, VCPU_SREG_LDTR);
+ kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES);
+ kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS);
+ kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS);
+ kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS);
+ kvm_load_segment_selector(vcpu, tss->fs, VCPU_SREG_FS);
+ kvm_load_segment_selector(vcpu, tss->gs, VCPU_SREG_GS);
+
+ /*
+ * Now load segment descriptors. If fault happenes at this stage
+ * it is handled in a context of new task
+ */
+ if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, VCPU_SREG_LDTR))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES))
+ if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS))
+ if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS))
+ if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS))
+ if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->fs, 1, VCPU_SREG_FS))
+ if (kvm_load_segment_descriptor(vcpu, tss->fs, VCPU_SREG_FS))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->gs, 1, VCPU_SREG_GS))
+ if (kvm_load_segment_descriptor(vcpu, tss->gs, VCPU_SREG_GS))
return 1;
return 0;
}
@@ -4495,19 +5009,33 @@ static int load_state_from_tss16(struct kvm_vcpu *vcpu,
kvm_register_write(vcpu, VCPU_REGS_RSI, tss->si);
kvm_register_write(vcpu, VCPU_REGS_RDI, tss->di);
- if (kvm_load_segment_descriptor(vcpu, tss->ldt, 0, VCPU_SREG_LDTR))
+ /*
+ * SDM says that segment selectors are loaded before segment
+ * descriptors
+ */
+ kvm_load_segment_selector(vcpu, tss->ldt, VCPU_SREG_LDTR);
+ kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES);
+ kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS);
+ kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS);
+ kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS);
+
+ /*
+ * Now load segment descriptors. If fault happenes at this stage
+ * it is handled in a context of new task
+ */
+ if (kvm_load_segment_descriptor(vcpu, tss->ldt, VCPU_SREG_LDTR))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES))
+ if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS))
+ if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS))
+ if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS))
return 1;
- if (kvm_load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS))
+ if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS))
return 1;
return 0;
}
@@ -4529,7 +5057,7 @@ static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
sizeof tss_segment_16))
goto out;
- if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
+ if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc),
&tss_segment_16, sizeof tss_segment_16))
goto out;
@@ -4537,7 +5065,7 @@ static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
tss_segment_16.prev_task_link = old_tss_sel;
if (kvm_write_guest(vcpu->kvm,
- get_tss_base_addr(vcpu, nseg_desc),
+ get_tss_base_addr_write(vcpu, nseg_desc),
&tss_segment_16.prev_task_link,
sizeof tss_segment_16.prev_task_link))
goto out;
@@ -4568,7 +5096,7 @@ static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
sizeof tss_segment_32))
goto out;
- if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
+ if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc),
&tss_segment_32, sizeof tss_segment_32))
goto out;
@@ -4576,7 +5104,7 @@ static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
tss_segment_32.prev_task_link = old_tss_sel;
if (kvm_write_guest(vcpu->kvm,
- get_tss_base_addr(vcpu, nseg_desc),
+ get_tss_base_addr_write(vcpu, nseg_desc),
&tss_segment_32.prev_task_link,
sizeof tss_segment_32.prev_task_link))
goto out;
@@ -4598,8 +5126,9 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
int ret = 0;
u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR);
u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR);
+ u32 desc_limit;
- old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base);
+ old_tss_base = kvm_mmu_gva_to_gpa_write(vcpu, old_tss_base, NULL);
/* FIXME: Handle errors. Failure to read either TSS or their
* descriptors should generate a pagefault.
@@ -4620,7 +5149,10 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
}
}
- if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) {
+ desc_limit = get_desc_limit(&nseg_desc);
+ if (!nseg_desc.p ||
+ ((desc_limit < 0x67 && (nseg_desc.type & 8)) ||
+ desc_limit < 0x2b)) {
kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc);
return 1;
}
@@ -4658,7 +5190,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
&nseg_desc);
}
- kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 | X86_CR0_TS);
+ kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0(vcpu) | X86_CR0_TS);
seg_desct_to_kvm_desct(&nseg_desc, tss_selector, &tr_seg);
tr_seg.type = 11;
kvm_set_segment(vcpu, &tr_seg, VCPU_SREG_TR);
@@ -4689,17 +5221,15 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
kvm_set_cr8(vcpu, sregs->cr8);
- mmu_reset_needed |= vcpu->arch.shadow_efer != sregs->efer;
+ mmu_reset_needed |= vcpu->arch.efer != sregs->efer;
kvm_x86_ops->set_efer(vcpu, sregs->efer);
kvm_set_apic_base(vcpu, sregs->apic_base);
- kvm_x86_ops->decache_cr4_guest_bits(vcpu);
-
- mmu_reset_needed |= vcpu->arch.cr0 != sregs->cr0;
+ mmu_reset_needed |= kvm_read_cr0(vcpu) != sregs->cr0;
kvm_x86_ops->set_cr0(vcpu, sregs->cr0);
vcpu->arch.cr0 = sregs->cr0;
- mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4;
+ mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
if (!is_long_mode(vcpu) && is_pae(vcpu)) {
load_pdptrs(vcpu, vcpu->arch.cr3);
@@ -4734,7 +5264,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
/* Older userspace won't unhalt the vcpu on reset. */
if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 &&
- !(vcpu->arch.cr0 & X86_CR0_PE))
+ !is_protmode(vcpu))
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
vcpu_put(vcpu);
@@ -4832,11 +5362,12 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
{
unsigned long vaddr = tr->linear_address;
gpa_t gpa;
+ int idx;
vcpu_load(vcpu);
- down_read(&vcpu->kvm->slots_lock);
- gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
- up_read(&vcpu->kvm->slots_lock);
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
+ gpa = kvm_mmu_gva_to_gpa_system(vcpu, vaddr, NULL);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
tr->physical_address = gpa;
tr->valid = gpa != UNMAPPED_GVA;
tr->writeable = 1;
@@ -4917,14 +5448,14 @@ EXPORT_SYMBOL_GPL(fx_init);
void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
{
- if (!vcpu->fpu_active || vcpu->guest_fpu_loaded)
+ if (vcpu->guest_fpu_loaded)
return;
vcpu->guest_fpu_loaded = 1;
kvm_fx_save(&vcpu->arch.host_fx_image);
kvm_fx_restore(&vcpu->arch.guest_fx_image);
+ trace_kvm_fpu(1);
}
-EXPORT_SYMBOL_GPL(kvm_load_guest_fpu);
void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
{
@@ -4935,8 +5466,9 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
kvm_fx_save(&vcpu->arch.guest_fx_image);
kvm_fx_restore(&vcpu->arch.host_fx_image);
++vcpu->stat.fpu_reload;
+ set_bit(KVM_REQ_DEACTIVATE_FPU, &vcpu->requests);
+ trace_kvm_fpu(0);
}
-EXPORT_SYMBOL_GPL(kvm_put_guest_fpu);
void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
{
@@ -5088,11 +5620,13 @@ fail:
void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
{
+ int idx;
+
kfree(vcpu->arch.mce_banks);
kvm_free_lapic(vcpu);
- down_read(&vcpu->kvm->slots_lock);
+ idx = srcu_read_lock(&vcpu->kvm->srcu);
kvm_mmu_destroy(vcpu);
- up_read(&vcpu->kvm->slots_lock);
+ srcu_read_unlock(&vcpu->kvm->srcu, idx);
free_page((unsigned long)vcpu->arch.pio_data);
}
@@ -5103,6 +5637,12 @@ struct kvm *kvm_arch_create_vm(void)
if (!kvm)
return ERR_PTR(-ENOMEM);
+ kvm->arch.aliases = kzalloc(sizeof(struct kvm_mem_aliases), GFP_KERNEL);
+ if (!kvm->arch.aliases) {
+ kfree(kvm);
+ return ERR_PTR(-ENOMEM);
+ }
+
INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
@@ -5159,16 +5699,18 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
put_page(kvm->arch.apic_access_page);
if (kvm->arch.ept_identity_pagetable)
put_page(kvm->arch.ept_identity_pagetable);
+ cleanup_srcu_struct(&kvm->srcu);
+ kfree(kvm->arch.aliases);
kfree(kvm);
}
-int kvm_arch_set_memory_region(struct kvm *kvm,
- struct kvm_userspace_memory_region *mem,
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
struct kvm_memory_slot old,
+ struct kvm_userspace_memory_region *mem,
int user_alloc)
{
- int npages = mem->memory_size >> PAGE_SHIFT;
- struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot];
+ int npages = memslot->npages;
/*To keep backward compatibility with older userspace,
*x86 needs to hanlde !user_alloc case.
@@ -5188,26 +5730,35 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
if (IS_ERR((void *)userspace_addr))
return PTR_ERR((void *)userspace_addr);
- /* set userspace_addr atomically for kvm_hva_to_rmapp */
- spin_lock(&kvm->mmu_lock);
memslot->userspace_addr = userspace_addr;
- spin_unlock(&kvm->mmu_lock);
- } else {
- if (!old.user_alloc && old.rmap) {
- int ret;
-
- down_write(&current->mm->mmap_sem);
- ret = do_munmap(current->mm, old.userspace_addr,
- old.npages * PAGE_SIZE);
- up_write(&current->mm->mmap_sem);
- if (ret < 0)
- printk(KERN_WARNING
- "kvm_vm_ioctl_set_memory_region: "
- "failed to munmap memory\n");
- }
}
}
+
+ return 0;
+}
+
+void kvm_arch_commit_memory_region(struct kvm *kvm,
+ struct kvm_userspace_memory_region *mem,
+ struct kvm_memory_slot old,
+ int user_alloc)
+{
+
+ int npages = mem->memory_size >> PAGE_SHIFT;
+
+ if (!user_alloc && !old.user_alloc && old.rmap && !npages) {
+ int ret;
+
+ down_write(&current->mm->mmap_sem);
+ ret = do_munmap(current->mm, old.userspace_addr,
+ old.npages * PAGE_SIZE);
+ up_write(&current->mm->mmap_sem);
+ if (ret < 0)
+ printk(KERN_WARNING
+ "kvm_vm_ioctl_set_memory_region: "
+ "failed to munmap memory\n");
+ }
+
spin_lock(&kvm->mmu_lock);
if (!kvm->arch.n_requested_mmu_pages) {
unsigned int nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm);
@@ -5216,8 +5767,6 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
kvm_mmu_slot_remove_write_access(kvm, mem->slot);
spin_unlock(&kvm->mmu_lock);
-
- return 0;
}
void kvm_arch_flush_shadow(struct kvm *kvm)
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 5eadea585d2..2d101639bd8 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -2,6 +2,7 @@
#define ARCH_X86_KVM_X86_H
#include <linux/kvm_host.h>
+#include "kvm_cache_regs.h"
static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu)
{
@@ -35,4 +36,33 @@ static inline bool kvm_exception_is_soft(unsigned int nr)
struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
u32 function, u32 index);
+static inline bool is_protmode(struct kvm_vcpu *vcpu)
+{
+ return kvm_read_cr0_bits(vcpu, X86_CR0_PE);
+}
+
+static inline int is_long_mode(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_X86_64
+ return vcpu->arch.efer & EFER_LMA;
+#else
+ return 0;
+#endif
+}
+
+static inline int is_pae(struct kvm_vcpu *vcpu)
+{
+ return kvm_read_cr4_bits(vcpu, X86_CR4_PAE);
+}
+
+static inline int is_pse(struct kvm_vcpu *vcpu)
+{
+ return kvm_read_cr4_bits(vcpu, X86_CR4_PSE);
+}
+
+static inline int is_paging(struct kvm_vcpu *vcpu)
+{
+ return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
+}
+
#endif
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 7e59dc1d3fc..2bdf628066b 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -115,7 +115,7 @@ static void async_hcall(unsigned long call, unsigned long arg1,
local_irq_save(flags);
if (lguest_data.hcall_status[next_call] != 0xFF) {
/* Table full, so do normal hcall which will flush table. */
- kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+ hcall(call, arg1, arg2, arg3, arg4);
} else {
lguest_data.hcalls[next_call].arg0 = call;
lguest_data.hcalls[next_call].arg1 = arg1;
@@ -145,46 +145,45 @@ static void async_hcall(unsigned long call, unsigned long arg1,
* So, when we're in lazy mode, we call async_hcall() to store the call for
* future processing:
*/
-static void lazy_hcall1(unsigned long call,
- unsigned long arg1)
+static void lazy_hcall1(unsigned long call, unsigned long arg1)
{
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
- kvm_hypercall1(call, arg1);
+ hcall(call, arg1, 0, 0, 0);
else
async_hcall(call, arg1, 0, 0, 0);
}
/* You can imagine what lazy_hcall2, 3 and 4 look like. :*/
static void lazy_hcall2(unsigned long call,
- unsigned long arg1,
- unsigned long arg2)
+ unsigned long arg1,
+ unsigned long arg2)
{
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
- kvm_hypercall2(call, arg1, arg2);
+ hcall(call, arg1, arg2, 0, 0);
else
async_hcall(call, arg1, arg2, 0, 0);
}
static void lazy_hcall3(unsigned long call,
- unsigned long arg1,
- unsigned long arg2,
- unsigned long arg3)
+ unsigned long arg1,
+ unsigned long arg2,
+ unsigned long arg3)
{
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
- kvm_hypercall3(call, arg1, arg2, arg3);
+ hcall(call, arg1, arg2, arg3, 0);
else
async_hcall(call, arg1, arg2, arg3, 0);
}
#ifdef CONFIG_X86_PAE
static void lazy_hcall4(unsigned long call,
- unsigned long arg1,
- unsigned long arg2,
- unsigned long arg3,
- unsigned long arg4)
+ unsigned long arg1,
+ unsigned long arg2,
+ unsigned long arg3,
+ unsigned long arg4)
{
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
- kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+ hcall(call, arg1, arg2, arg3, arg4);
else
async_hcall(call, arg1, arg2, arg3, arg4);
}
@@ -196,13 +195,13 @@ static void lazy_hcall4(unsigned long call,
:*/
static void lguest_leave_lazy_mmu_mode(void)
{
- kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+ hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
paravirt_leave_lazy_mmu();
}
static void lguest_end_context_switch(struct task_struct *next)
{
- kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+ hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
paravirt_end_context_switch(next);
}
@@ -286,7 +285,7 @@ static void lguest_write_idt_entry(gate_desc *dt,
/* Keep the local copy up to date. */
native_write_idt_entry(dt, entrynum, g);
/* Tell Host about this new entry. */
- kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
+ hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1], 0);
}
/*
@@ -300,7 +299,7 @@ static void lguest_load_idt(const struct desc_ptr *desc)
struct desc_struct *idt = (void *)desc->address;
for (i = 0; i < (desc->size+1)/8; i++)
- kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
+ hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0);
}
/*
@@ -321,7 +320,7 @@ static void lguest_load_gdt(const struct desc_ptr *desc)
struct desc_struct *gdt = (void *)desc->address;
for (i = 0; i < (desc->size+1)/8; i++)
- kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b);
+ hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0);
}
/*
@@ -334,8 +333,8 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
{
native_write_gdt_entry(dt, entrynum, desc, type);
/* Tell Host about this new entry. */
- kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum,
- dt[entrynum].a, dt[entrynum].b);
+ hcall(LHCALL_LOAD_GDT_ENTRY, entrynum,
+ dt[entrynum].a, dt[entrynum].b, 0);
}
/*
@@ -931,7 +930,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta,
}
/* Please wake us this far in the future. */
- kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta);
+ hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0, 0);
return 0;
}
@@ -942,7 +941,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode,
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
/* A 0 argument shuts the clock down. */
- kvm_hypercall0(LHCALL_SET_CLOCKEVENT);
+ hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0, 0);
break;
case CLOCK_EVT_MODE_ONESHOT:
/* This is what we expect. */
@@ -1100,7 +1099,7 @@ static void set_lguest_basic_apic_ops(void)
/* STOP! Until an interrupt comes in. */
static void lguest_safe_halt(void)
{
- kvm_hypercall0(LHCALL_HALT);
+ hcall(LHCALL_HALT, 0, 0, 0, 0);
}
/*
@@ -1112,8 +1111,8 @@ static void lguest_safe_halt(void)
*/
static void lguest_power_off(void)
{
- kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"),
- LGUEST_SHUTDOWN_POWEROFF);
+ hcall(LHCALL_SHUTDOWN, __pa("Power down"),
+ LGUEST_SHUTDOWN_POWEROFF, 0, 0);
}
/*
@@ -1123,7 +1122,7 @@ static void lguest_power_off(void)
*/
static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
{
- kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF);
+ hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0, 0);
/* The hcall won't return, but to keep gcc happy, we're "done". */
return NOTIFY_DONE;
}
@@ -1162,7 +1161,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
len = sizeof(scratch) - 1;
scratch[len] = '\0';
memcpy(scratch, buf, len);
- kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch));
+ hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0);
/* This routine returns the number of bytes actually written. */
return len;
@@ -1174,7 +1173,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
*/
static void lguest_restart(char *reason)
{
- kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART);
+ hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0);
}
/*G:050
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S
index 27eac0faee4..4f420c2f2d5 100644
--- a/arch/x86/lguest/i386_head.S
+++ b/arch/x86/lguest/i386_head.S
@@ -32,7 +32,7 @@ ENTRY(lguest_entry)
*/
movl $LHCALL_LGUEST_INIT, %eax
movl $lguest_data - __PAGE_OFFSET, %ebx
- .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */
+ int $LGUEST_TRAP_ENTRY
/* Set up the initial stack so we can run C code. */
movl $(init_thread_union+THREAD_SIZE),%esp
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index f46c340727b..069ce7c37c0 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -9,7 +9,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/slab.h>
#include <linux/err.h>
#include <linux/sysctl.h>
#include <asm/mman.h>
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index e71c5cbc8f3..b278535b14a 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -1,3 +1,4 @@
+#include <linux/gfp.h>
#include <linux/initrd.h>
#include <linux/ioport.h>
#include <linux/swap.h>
@@ -331,11 +332,23 @@ int devmem_is_allowed(unsigned long pagenr)
void free_init_pages(char *what, unsigned long begin, unsigned long end)
{
- unsigned long addr = begin;
+ unsigned long addr;
+ unsigned long begin_aligned, end_aligned;
- if (addr >= end)
+ /* Make sure boundaries are page aligned */
+ begin_aligned = PAGE_ALIGN(begin);
+ end_aligned = end & PAGE_MASK;
+
+ if (WARN_ON(begin_aligned != begin || end_aligned != end)) {
+ begin = begin_aligned;
+ end = end_aligned;
+ }
+
+ if (begin >= end)
return;
+ addr = begin;
+
/*
* If debugging page accesses then do not free this memory but
* mark them not present - any buggy init-section access will
@@ -343,7 +356,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
*/
#ifdef CONFIG_DEBUG_PAGEALLOC
printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
- begin, PAGE_ALIGN(end));
+ begin, end);
set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
#else
/*
@@ -358,8 +371,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
for (; addr < end; addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
init_page_count(virt_to_page(addr));
- memset((void *)(addr & ~(PAGE_SIZE-1)),
- POISON_FREE_INITMEM, PAGE_SIZE);
+ memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
free_page(addr);
totalram_pages++;
}
@@ -376,6 +388,15 @@ void free_initmem(void)
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
- free_init_pages("initrd memory", start, end);
+ /*
+ * end could be not aligned, and We can not align that,
+ * decompresser could be confused by aligned initrd_end
+ * We already reserve the end partial page before in
+ * - i386_start_kernel()
+ * - x86_64_start_kernel()
+ * - relocate_initrd()
+ * So here We can do PAGE_ALIGN() safely to get partial page to be freed
+ */
+ free_init_pages("initrd memory", start, PAGE_ALIGN(end));
}
#endif
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 5cb3f0f54f4..bca79091b9d 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -25,11 +25,11 @@
#include <linux/pfn.h>
#include <linux/poison.h>
#include <linux/bootmem.h>
-#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/memory_hotplug.h>
#include <linux/initrd.h>
#include <linux/cpumask.h>
+#include <linux/gfp.h>
#include <asm/asm.h>
#include <asm/bios_ebda.h>
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index e9b040e1cde..ee41bba315d 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/memory_hotplug.h>
#include <linux/nmi.h>
+#include <linux/gfp.h>
#include <asm/processor.h>
#include <asm/bios_ebda.h>
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 536fb682336..5d0e67fff1a 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -21,6 +21,7 @@
#include <linux/kdebug.h>
#include <linux/mutex.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <linux/errno.h>
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 34a3291ca10..3adff7dcc14 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/version.h>
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 1d4eb93d333..28195c350b9 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -6,13 +6,13 @@
#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/pfn.h>
#include <linux/percpu.h>
+#include <linux/gfp.h>
#include <asm/e820.h>
#include <asm/processor.h>
@@ -291,8 +291,29 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
*/
if (kernel_set_to_readonly &&
within(address, (unsigned long)_text,
- (unsigned long)__end_rodata_hpage_align))
- pgprot_val(forbidden) |= _PAGE_RW;
+ (unsigned long)__end_rodata_hpage_align)) {
+ unsigned int level;
+
+ /*
+ * Don't enforce the !RW mapping for the kernel text mapping,
+ * if the current mapping is already using small page mapping.
+ * No need to work hard to preserve large page mappings in this
+ * case.
+ *
+ * This also fixes the Linux Xen paravirt guest boot failure
+ * (because of unexpected read-only mappings for kernel identity
+ * mappings). In this paravirt guest case, the kernel text
+ * mapping and the kernel identity mapping share the same
+ * page-table pages. Thus we can't really use different
+ * protections for the kernel text and identity mappings. Also,
+ * these shared mappings are made of small page mappings.
+ * Thus this don't enforce !RW mapping for small page kernel
+ * text mapping logic will help Linux Xen parvirt guest boot
+ * aswell.
+ */
+ if (lookup_address(address, &level) && (level != PG_LEVEL_4K))
+ pgprot_val(forbidden) |= _PAGE_RW;
+ }
#endif
prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index ae9648eb1c7..edc8b95afc1 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -12,7 +12,7 @@
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/rbtree.h>
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index c9ba9deafe8..5c4ee422590 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -1,4 +1,5 @@
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/tlb.h>
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index 46c8834aedc..1a8faf09afe 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -6,7 +6,6 @@
#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/module.h>
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 6a58256dce9..090cbbec7db 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -46,17 +46,6 @@
static unsigned long reset_value[NUM_VIRT_COUNTERS];
-/* IbsFetchCtl bits/masks */
-#define IBS_FETCH_RAND_EN (1ULL<<57)
-#define IBS_FETCH_VAL (1ULL<<49)
-#define IBS_FETCH_ENABLE (1ULL<<48)
-#define IBS_FETCH_CNT_MASK 0xFFFF0000ULL
-
-/* IbsOpCtl bits */
-#define IBS_OP_CNT_CTL (1ULL<<19)
-#define IBS_OP_VAL (1ULL<<18)
-#define IBS_OP_ENABLE (1ULL<<17)
-
#define IBS_FETCH_SIZE 6
#define IBS_OP_SIZE 12
@@ -182,7 +171,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
continue;
}
rdmsrl(msrs->controls[i].addr, val);
- if (val & ARCH_PERFMON_EVENTSEL0_ENABLE)
+ if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
op_x86_warn_in_use(i);
val &= model->reserved;
wrmsrl(msrs->controls[i].addr, val);
@@ -290,7 +279,7 @@ op_amd_handle_ibs(struct pt_regs * const regs,
oprofile_write_commit(&entry);
/* reenable the IRQ */
- ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT_MASK);
+ ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT);
ctl |= IBS_FETCH_ENABLE;
wrmsrl(MSR_AMD64_IBSFETCHCTL, ctl);
}
@@ -330,7 +319,7 @@ static inline void op_amd_start_ibs(void)
return;
if (ibs_config.fetch_enabled) {
- val = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF;
+ val = (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT;
val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0;
val |= IBS_FETCH_ENABLE;
wrmsrl(MSR_AMD64_IBSFETCHCTL, val);
@@ -352,7 +341,7 @@ static inline void op_amd_start_ibs(void)
* avoid underflows.
*/
ibs_op_ctl = min(ibs_op_ctl + IBS_RANDOM_MAXCNT_OFFSET,
- 0xFFFFULL);
+ IBS_OP_MAX_CNT);
}
if (ibs_caps & IBS_CAPS_OPCNT && ibs_config.dispatched_ops)
ibs_op_ctl |= IBS_OP_CNT_CTL;
@@ -409,7 +398,7 @@ static void op_amd_start(struct op_msrs const * const msrs)
if (!reset_value[op_x86_phys_to_virt(i)])
continue;
rdmsrl(msrs->controls[i].addr, val);
- val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsrl(msrs->controls[i].addr, val);
}
@@ -429,7 +418,7 @@ static void op_amd_stop(struct op_msrs const * const msrs)
if (!reset_value[op_x86_phys_to_virt(i)])
continue;
rdmsrl(msrs->controls[i].addr, val);
- val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsrl(msrs->controls[i].addr, val);
}
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
index 5d1727ba409..2bf90fafa7b 100644
--- a/arch/x86/oprofile/op_model_ppro.c
+++ b/arch/x86/oprofile/op_model_ppro.c
@@ -88,7 +88,7 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model,
continue;
}
rdmsrl(msrs->controls[i].addr, val);
- if (val & ARCH_PERFMON_EVENTSEL0_ENABLE)
+ if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
op_x86_warn_in_use(i);
val &= model->reserved;
wrmsrl(msrs->controls[i].addr, val);
@@ -166,7 +166,7 @@ static void ppro_start(struct op_msrs const * const msrs)
for (i = 0; i < num_counters; ++i) {
if (reset_value[i]) {
rdmsrl(msrs->controls[i].addr, val);
- val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsrl(msrs->controls[i].addr, val);
}
}
@@ -184,7 +184,7 @@ static void ppro_stop(struct op_msrs const * const msrs)
if (!reset_value[i])
continue;
rdmsrl(msrs->controls[i].addr, val);
- val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+ val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
wrmsrl(msrs->controls[i].addr, val);
}
}
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 0b7d3e9593e..b110d97fb92 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_X86_VISWS) += visws.o
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
+obj-$(CONFIG_X86_MRST) += mrst.o
+
obj-y += common.o early.o
obj-y += amd_bus.o bus_numa.o
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 5f11ff6f538..31930fd30ea 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -3,6 +3,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#include <asm/numa.h>
#include <asm/pci_x86.h>
@@ -65,14 +66,44 @@ resource_to_addr(struct acpi_resource *resource,
struct acpi_resource_address64 *addr)
{
acpi_status status;
-
- status = acpi_resource_to_address64(resource, addr);
- if (ACPI_SUCCESS(status) &&
- (addr->resource_type == ACPI_MEMORY_RANGE ||
- addr->resource_type == ACPI_IO_RANGE) &&
- addr->address_length > 0 &&
- addr->producer_consumer == ACPI_PRODUCER) {
+ struct acpi_resource_memory24 *memory24;
+ struct acpi_resource_memory32 *memory32;
+ struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+ memset(addr, 0, sizeof(*addr));
+ switch (resource->type) {
+ case ACPI_RESOURCE_TYPE_MEMORY24:
+ memory24 = &resource->data.memory24;
+ addr->resource_type = ACPI_MEMORY_RANGE;
+ addr->minimum = memory24->minimum;
+ addr->address_length = memory24->address_length;
+ addr->maximum = addr->minimum + addr->address_length - 1;
+ return AE_OK;
+ case ACPI_RESOURCE_TYPE_MEMORY32:
+ memory32 = &resource->data.memory32;
+ addr->resource_type = ACPI_MEMORY_RANGE;
+ addr->minimum = memory32->minimum;
+ addr->address_length = memory32->address_length;
+ addr->maximum = addr->minimum + addr->address_length - 1;
return AE_OK;
+ case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+ fixed_memory32 = &resource->data.fixed_memory32;
+ addr->resource_type = ACPI_MEMORY_RANGE;
+ addr->minimum = fixed_memory32->address;
+ addr->address_length = fixed_memory32->address_length;
+ addr->maximum = addr->minimum + addr->address_length - 1;
+ return AE_OK;
+ case ACPI_RESOURCE_TYPE_ADDRESS16:
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+ status = acpi_resource_to_address64(resource, addr);
+ if (ACPI_SUCCESS(status) &&
+ (addr->resource_type == ACPI_MEMORY_RANGE ||
+ addr->resource_type == ACPI_IO_RANGE) &&
+ addr->address_length > 0) {
+ return AE_OK;
+ }
+ break;
}
return AE_ERROR;
}
@@ -90,30 +121,6 @@ count_resource(struct acpi_resource *acpi_res, void *data)
return AE_OK;
}
-static void
-align_resource(struct acpi_device *bridge, struct resource *res)
-{
- int align = (res->flags & IORESOURCE_MEM) ? 16 : 4;
-
- /*
- * Host bridge windows are not BARs, but the decoders on the PCI side
- * that claim this address space have starting alignment and length
- * constraints, so fix any obvious BIOS goofs.
- */
- if (!IS_ALIGNED(res->start, align)) {
- dev_printk(KERN_DEBUG, &bridge->dev,
- "host bridge window %pR invalid; "
- "aligning start to %d-byte boundary\n", res, align);
- res->start &= ~(align - 1);
- }
- if (!IS_ALIGNED(res->end + 1, align)) {
- dev_printk(KERN_DEBUG, &bridge->dev,
- "host bridge window %pR invalid; "
- "aligning end to %d-byte boundary\n", res, align);
- res->end = ALIGN(res->end, align) - 1;
- }
-}
-
static acpi_status
setup_resource(struct acpi_resource *acpi_res, void *data)
{
@@ -122,7 +129,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
struct acpi_resource_address64 addr;
acpi_status status;
unsigned long flags;
- struct resource *root;
+ struct resource *root, *conflict;
u64 start, end;
status = resource_to_addr(acpi_res, &addr);
@@ -141,7 +148,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
return AE_OK;
start = addr.minimum + addr.translation_offset;
- end = start + addr.address_length - 1;
+ end = addr.maximum + addr.translation_offset;
res = &info->res[info->res_num];
res->name = info->name;
@@ -149,7 +156,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
res->start = start;
res->end = end;
res->child = NULL;
- align_resource(info->bridge, res);
if (!pci_use_crs) {
dev_printk(KERN_DEBUG, &info->bridge->dev,
@@ -157,9 +163,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
return AE_OK;
}
- if (insert_resource(root, res)) {
+ conflict = insert_resource_conflict(root, res);
+ if (conflict) {
dev_err(&info->bridge->dev,
- "can't allocate host bridge window %pR\n", res);
+ "address space collision: host bridge window %pR "
+ "conflicts with %s %pR\n",
+ res, conflict->name, conflict);
} else {
pci_bus_add_resource(info->bus, res, 0);
info->res_num++;
@@ -298,17 +307,14 @@ int __init pci_acpi_init(void)
{
struct pci_dev *dev = NULL;
- if (pcibios_scanned)
- return 0;
-
if (acpi_noirq)
- return 0;
+ return -ENODEV;
printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
acpi_irq_penalty_init();
- pcibios_scanned++;
pcibios_enable_irq = acpi_pci_irq_enable;
pcibios_disable_irq = acpi_pci_irq_disable;
+ x86_init.pci.init_irq = x86_init_noop;
if (pci_routeirq) {
/*
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 3736176acaa..cf2e93869c4 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -9,6 +9,7 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#include <asm/acpi.h>
#include <asm/segment.h>
@@ -72,12 +73,6 @@ struct pci_ops pci_root_ops = {
};
/*
- * legacy, numa, and acpi all want to call pcibios_scan_root
- * from their initcalls. This flag prevents that.
- */
-int pcibios_scanned;
-
-/*
* This interrupt-safe spinlock protects all accesses to PCI
* configuration space.
*/
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index dece3eb9c90..97da2ba9344 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -72,6 +72,9 @@ pcibios_align_resource(void *data, const struct resource *res,
return start;
if (start & 0x300)
start = (start + 0x3ff) & ~0x3ff;
+ } else if (res->flags & IORESOURCE_MEM) {
+ if (start < BIOS_END)
+ start = BIOS_END;
}
return start;
}
@@ -127,9 +130,6 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
continue;
if (!r->start ||
pci_claim_resource(dev, idx) < 0) {
- dev_info(&dev->dev,
- "can't reserve window %pR\n",
- r);
/*
* Something is wrong with the region.
* Invalidate the resource to prevent
@@ -181,8 +181,6 @@ static void __init pcibios_allocate_resources(int pass)
"BAR %d: reserving %pr (d=%d, p=%d)\n",
idx, r, disabled, pass);
if (pci_claim_resource(dev, idx) < 0) {
- dev_info(&dev->dev,
- "can't reserve %pR\n", r);
/* We'll assign a new address later */
r->end -= r->start;
r->start = 0;
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c
index 25a1f8efed4..adb62aaa7ec 100644
--- a/arch/x86/pci/init.c
+++ b/arch/x86/pci/init.c
@@ -1,6 +1,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/pci_x86.h>
+#include <asm/x86_init.h>
/* arch_initcall has too random ordering, so call the initializers
in the right sequence from here. */
@@ -15,10 +16,9 @@ static __init int pci_arch_init(void)
if (!(pci_probe & PCI_PROBE_NOEARLY))
pci_mmcfg_early_init();
-#ifdef CONFIG_PCI_OLPC
- if (!pci_olpc_init())
- return 0; /* skip additional checks if it's an XO */
-#endif
+ if (x86_init.pci.arch_init && !x86_init.pci.arch_init())
+ return 0;
+
#ifdef CONFIG_PCI_BIOS
pci_pcbios_init();
#endif
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index b02f6d8ac92..5d362b5ba06 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -8,7 +8,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dmi.h>
#include <linux/io.h>
@@ -53,7 +52,7 @@ struct irq_router_handler {
int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
};
-int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
+int (*pcibios_enable_irq)(struct pci_dev *dev) = pirq_enable_irq;
void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
/*
@@ -1018,7 +1017,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
return 1;
}
-static void __init pcibios_fixup_irqs(void)
+void __init pcibios_fixup_irqs(void)
{
struct pci_dev *dev = NULL;
u8 pin;
@@ -1112,12 +1111,12 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = {
{ }
};
-int __init pcibios_irq_init(void)
+void __init pcibios_irq_init(void)
{
DBG(KERN_DEBUG "PCI: IRQ init\n");
- if (pcibios_enable_irq || raw_pci_ops == NULL)
- return 0;
+ if (raw_pci_ops == NULL)
+ return;
dmi_check_system(pciirq_dmi_table);
@@ -1144,9 +1143,7 @@ int __init pcibios_irq_init(void)
pirq_table = NULL;
}
- pcibios_enable_irq = pirq_enable_irq;
-
- pcibios_fixup_irqs();
+ x86_init.pci.fixup_irqs();
if (io_apic_assign_pci_irqs && pci_routeirq) {
struct pci_dev *dev = NULL;
@@ -1159,8 +1156,6 @@ int __init pcibios_irq_init(void)
for_each_pci_dev(dev)
pirq_enable_irq(dev);
}
-
- return 0;
}
static void pirq_penalize_isa_irq(int irq, int active)
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index 4061bb0f267..0db5eaf5456 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -35,16 +35,13 @@ static void __devinit pcibios_fixup_peer_bridges(void)
}
}
-static int __init pci_legacy_init(void)
+int __init pci_legacy_init(void)
{
if (!raw_pci_ops) {
printk("PCI: System does not support PCI\n");
return 0;
}
- if (pcibios_scanned++)
- return 0;
-
printk("PCI: Probing PCI hardware\n");
pci_root_bus = pcibios_scan_root(0);
if (pci_root_bus)
@@ -55,18 +52,15 @@ static int __init pci_legacy_init(void)
int __init pci_subsys_init(void)
{
-#ifdef CONFIG_X86_NUMAQ
- pci_numaq_init();
-#endif
-#ifdef CONFIG_ACPI
- pci_acpi_init();
-#endif
-#ifdef CONFIG_X86_VISWS
- pci_visws_init();
-#endif
- pci_legacy_init();
+ /*
+ * The init function returns an non zero value when
+ * pci_legacy_init should be invoked.
+ */
+ if (x86_init.pci.init())
+ pci_legacy_init();
+
pcibios_fixup_peer_bridges();
- pcibios_irq_init();
+ x86_init.pci.init_irq();
pcibios_init();
return 0;
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 8f3f9a50b1e..39b9ebe8f88 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -16,6 +16,7 @@
#include <linux/sfi_acpi.h>
#include <linux/bitmap.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#include <asm/e820.h>
#include <asm/pci_x86.h>
#include <asm/acpi.h>
diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c
new file mode 100644
index 00000000000..8bf2fcb88d0
--- /dev/null
+++ b/arch/x86/pci/mrst.c
@@ -0,0 +1,262 @@
+/*
+ * Moorestown PCI support
+ * Copyright (c) 2008 Intel Corporation
+ * Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Moorestown has an interesting PCI implementation:
+ * - configuration space is memory mapped (as defined by MCFG)
+ * - Lincroft devices also have a real, type 1 configuration space
+ * - Early Lincroft silicon has a type 1 access bug that will cause
+ * a hang if non-existent devices are accessed
+ * - some devices have the "fixed BAR" capability, which means
+ * they can't be relocated or modified; check for that during
+ * BAR sizing
+ *
+ * So, we use the MCFG space for all reads and writes, but also send
+ * Lincroft writes to type 1 space. But only read/write if the device
+ * actually exists, otherwise return all 1s for reads and bit bucket
+ * the writes.
+ */
+
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/dmi.h>
+
+#include <asm/acpi.h>
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/pci_x86.h>
+#include <asm/hw_irq.h>
+#include <asm/io_apic.h>
+
+#define PCIE_CAP_OFFSET 0x100
+
+/* Fixed BAR fields */
+#define PCIE_VNDR_CAP_ID_FIXED_BAR 0x00 /* Fixed BAR (TBD) */
+#define PCI_FIXED_BAR_0_SIZE 0x04
+#define PCI_FIXED_BAR_1_SIZE 0x08
+#define PCI_FIXED_BAR_2_SIZE 0x0c
+#define PCI_FIXED_BAR_3_SIZE 0x10
+#define PCI_FIXED_BAR_4_SIZE 0x14
+#define PCI_FIXED_BAR_5_SIZE 0x1c
+
+/**
+ * fixed_bar_cap - return the offset of the fixed BAR cap if found
+ * @bus: PCI bus
+ * @devfn: device in question
+ *
+ * Look for the fixed BAR cap on @bus and @devfn, returning its offset
+ * if found or 0 otherwise.
+ */
+static int fixed_bar_cap(struct pci_bus *bus, unsigned int devfn)
+{
+ int pos;
+ u32 pcie_cap = 0, cap_data;
+
+ pos = PCIE_CAP_OFFSET;
+
+ if (!raw_pci_ext_ops)
+ return 0;
+
+ while (pos) {
+ if (raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
+ devfn, pos, 4, &pcie_cap))
+ return 0;
+
+ if (pcie_cap == 0xffffffff)
+ return 0;
+
+ if (PCI_EXT_CAP_ID(pcie_cap) == PCI_EXT_CAP_ID_VNDR) {
+ raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
+ devfn, pos + 4, 4, &cap_data);
+ if ((cap_data & 0xffff) == PCIE_VNDR_CAP_ID_FIXED_BAR)
+ return pos;
+ }
+
+ pos = pcie_cap >> 20;
+ }
+
+ return 0;
+}
+
+static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
+ int reg, int len, u32 val, int offset)
+{
+ u32 size;
+ unsigned int domain, busnum;
+ int bar = (reg - PCI_BASE_ADDRESS_0) >> 2;
+
+ domain = pci_domain_nr(bus);
+ busnum = bus->number;
+
+ if (val == ~0 && len == 4) {
+ unsigned long decode;
+
+ raw_pci_ext_ops->read(domain, busnum, devfn,
+ offset + 8 + (bar * 4), 4, &size);
+
+ /* Turn the size into a decode pattern for the sizing code */
+ if (size) {
+ decode = size - 1;
+ decode |= decode >> 1;
+ decode |= decode >> 2;
+ decode |= decode >> 4;
+ decode |= decode >> 8;
+ decode |= decode >> 16;
+ decode++;
+ decode = ~(decode - 1);
+ } else {
+ decode = ~0;
+ }
+
+ /*
+ * If val is all ones, the core code is trying to size the reg,
+ * so update the mmconfig space with the real size.
+ *
+ * Note: this assumes the fixed size we got is a power of two.
+ */
+ return raw_pci_ext_ops->write(domain, busnum, devfn, reg, 4,
+ decode);
+ }
+
+ /* This is some other kind of BAR write, so just do it. */
+ return raw_pci_ext_ops->write(domain, busnum, devfn, reg, len, val);
+}
+
+/**
+ * type1_access_ok - check whether to use type 1
+ * @bus: bus number
+ * @devfn: device & function in question
+ *
+ * If the bus is on a Lincroft chip and it exists, or is not on a Lincroft at
+ * all, the we can go ahead with any reads & writes. If it's on a Lincroft,
+ * but doesn't exist, avoid the access altogether to keep the chip from
+ * hanging.
+ */
+static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
+{
+ /* This is a workaround for A0 LNC bug where PCI status register does
+ * not have new CAP bit set. can not be written by SW either.
+ *
+ * PCI header type in real LNC indicates a single function device, this
+ * will prevent probing other devices under the same function in PCI
+ * shim. Therefore, use the header type in shim instead.
+ */
+ if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE)
+ return 0;
+ if (bus == 0 && (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(0, 0)))
+ return 1;
+ return 0; /* langwell on others */
+}
+
+static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ if (type1_access_ok(bus->number, devfn, where))
+ return pci_direct_conf1.read(pci_domain_nr(bus), bus->number,
+ devfn, where, size, value);
+ return raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
+ devfn, where, size, value);
+}
+
+static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
+{
+ int offset;
+
+ /* On MRST, there is no PCI ROM BAR, this will cause a subsequent read
+ * to ROM BAR return 0 then being ignored.
+ */
+ if (where == PCI_ROM_ADDRESS)
+ return 0;
+
+ /*
+ * Devices with fixed BARs need special handling:
+ * - BAR sizing code will save, write ~0, read size, restore
+ * - so writes to fixed BARs need special handling
+ * - other writes to fixed BAR devices should go through mmconfig
+ */
+ offset = fixed_bar_cap(bus, devfn);
+ if (offset &&
+ (where >= PCI_BASE_ADDRESS_0 && where <= PCI_BASE_ADDRESS_5)) {
+ return pci_device_update_fixed(bus, devfn, where, size, value,
+ offset);
+ }
+
+ /*
+ * On Moorestown update both real & mmconfig space
+ * Note: early Lincroft silicon can't handle type 1 accesses to
+ * non-existent devices, so just eat the write in that case.
+ */
+ if (type1_access_ok(bus->number, devfn, where))
+ return pci_direct_conf1.write(pci_domain_nr(bus), bus->number,
+ devfn, where, size, value);
+ return raw_pci_ext_ops->write(pci_domain_nr(bus), bus->number, devfn,
+ where, size, value);
+}
+
+static int mrst_pci_irq_enable(struct pci_dev *dev)
+{
+ u8 pin;
+ struct io_apic_irq_attr irq_attr;
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+ /* MRST only have IOAPIC, the PCI irq lines are 1:1 mapped to
+ * IOAPIC RTE entries, so we just enable RTE for the device.
+ */
+ irq_attr.ioapic = mp_find_ioapic(dev->irq);
+ irq_attr.ioapic_pin = dev->irq;
+ irq_attr.trigger = 1; /* level */
+ irq_attr.polarity = 1; /* active low */
+ io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr);
+
+ return 0;
+}
+
+struct pci_ops pci_mrst_ops = {
+ .read = pci_read,
+ .write = pci_write,
+};
+
+/**
+ * pci_mrst_init - installs pci_mrst_ops
+ *
+ * Moorestown has an interesting PCI implementation (see above).
+ * Called when the early platform detection installs it.
+ */
+int __init pci_mrst_init(void)
+{
+ printk(KERN_INFO "Moorestown platform detected, using MRST PCI ops\n");
+ pci_mmcfg_late_init();
+ pcibios_enable_irq = mrst_pci_irq_enable;
+ pci_root_ops = pci_mrst_ops;
+ /* Continue with standard init */
+ return 1;
+}
+
+/*
+ * Langwell devices reside at fixed offsets, don't try to move them.
+ */
+static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
+{
+ unsigned long offset;
+ u32 size;
+ int i;
+
+ /* Fixup the BAR sizes for fixed BAR devices and make them unmoveable */
+ offset = fixed_bar_cap(dev->bus, dev->devfn);
+ if (!offset || PCI_DEVFN(2, 0) == dev->devfn ||
+ PCI_DEVFN(2, 2) == dev->devfn)
+ return;
+
+ for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+ pci_read_config_dword(dev, offset + 8 + (i * 4), &size);
+ dev->resource[i].end = dev->resource[i].start + size - 1;
+ dev->resource[i].flags |= IORESOURCE_PCI_FIXED;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixed_bar_fixup);
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c
index 8884a1c1ada..8223738ad80 100644
--- a/arch/x86/pci/numaq_32.c
+++ b/arch/x86/pci/numaq_32.c
@@ -148,14 +148,8 @@ int __init pci_numaq_init(void)
{
int quad;
- if (!found_numaq)
- return 0;
-
raw_pci_ops = &pci_direct_conf1_mq;
- if (pcibios_scanned++)
- return 0;
-
pci_root_bus = pcibios_scan_root(0);
if (pci_root_bus)
pci_bus_add_devices(pci_root_bus);
diff --git a/arch/x86/pci/olpc.c b/arch/x86/pci/olpc.c
index b889d824f7c..b34815408f5 100644
--- a/arch/x86/pci/olpc.c
+++ b/arch/x86/pci/olpc.c
@@ -304,9 +304,6 @@ static struct pci_raw_ops pci_olpc_conf = {
int __init pci_olpc_init(void)
{
- if (!machine_is_olpc() || olpc_has_vsa())
- return -ENODEV;
-
printk(KERN_INFO "PCI: Using configuration type OLPC\n");
raw_pci_ops = &pci_olpc_conf;
is_lx = is_geode_lx();
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
index 1c975cc9839..59a225c17b8 100644
--- a/arch/x86/pci/pcbios.c
+++ b/arch/x86/pci/pcbios.c
@@ -4,6 +4,7 @@
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <asm/pci_x86.h>
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c
index bcead7a4687..03008f72eb0 100644
--- a/arch/x86/pci/visws.c
+++ b/arch/x86/pci/visws.c
@@ -69,9 +69,6 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
int __init pci_visws_init(void)
{
- if (!is_visws_box())
- return -1;
-
pcibios_enable_irq = &pci_visws_enable_irq;
pcibios_disable_irq = &pci_visws_disable_irq;
@@ -90,5 +87,6 @@ int __init pci_visws_init(void)
pci_scan_bus_with_sysdata(pci_bus1);
pci_fixup_irqs(pci_common_swizzle, visws_map_irq);
pcibios_resource_survey();
- return 0;
+ /* Request bus scan */
+ return 1;
}
diff --git a/arch/x86/power/hibernate_32.c b/arch/x86/power/hibernate_32.c
index 81197c62d5b..3769079874d 100644
--- a/arch/x86/power/hibernate_32.c
+++ b/arch/x86/power/hibernate_32.c
@@ -6,6 +6,7 @@
* Copyright (c) 2006 Rafael J. Wysocki <rjw@sisk.pl>
*/
+#include <linux/gfp.h>
#include <linux/suspend.h>
#include <linux/bootmem.h>
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
index 65fdc86e923..d24f983ba1e 100644
--- a/arch/x86/power/hibernate_64.c
+++ b/arch/x86/power/hibernate_64.c
@@ -8,6 +8,7 @@
* Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
*/
+#include <linux/gfp.h>
#include <linux/smp.h>
#include <linux/suspend.h>
#include <asm/proto.h>
diff --git a/arch/x86/power/hibernate_asm_32.S b/arch/x86/power/hibernate_asm_32.S
index b641388d828..ad47daeafa4 100644
--- a/arch/x86/power/hibernate_asm_32.S
+++ b/arch/x86/power/hibernate_asm_32.S
@@ -27,10 +27,17 @@ ENTRY(swsusp_arch_suspend)
ret
ENTRY(restore_image)
+ movl mmu_cr4_features, %ecx
movl resume_pg_dir, %eax
subl $__PAGE_OFFSET, %eax
movl %eax, %cr3
+ jecxz 1f # cr4 Pentium and higher, skip if zero
+ andl $~(X86_CR4_PGE), %ecx
+ movl %ecx, %cr4; # turn off PGE
+ movl %cr3, %eax; # flush TLB
+ movl %eax, %cr3
+1:
movl restore_pblist, %edx
.p2align 4,,7
@@ -54,16 +61,8 @@ done:
movl $swapper_pg_dir, %eax
subl $__PAGE_OFFSET, %eax
movl %eax, %cr3
- /* Flush TLB, including "global" things (vmalloc) */
movl mmu_cr4_features, %ecx
jecxz 1f # cr4 Pentium and higher, skip if zero
- movl %ecx, %edx
- andl $~(X86_CR4_PGE), %edx
- movl %edx, %cr4; # turn off PGE
-1:
- movl %cr3, %eax; # flush TLB
- movl %eax, %cr3
- jecxz 1f # cr4 Pentium and higher, skip if zero
movl %ecx, %cr4; # turn PGE back on
1:
diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index 21e1aeb9f3e..ac74869b814 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -6,6 +6,7 @@
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/random.h>
#include <linux/elf.h>
diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c
index e133ce25e29..1304bcec8ee 100644
--- a/arch/x86/xen/debugfs.c
+++ b/arch/x86/xen/debugfs.c
@@ -1,5 +1,6 @@
#include <linux/init.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include "debugfs.h"
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index b607239c1ba..65d8d79b46a 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -28,6 +28,7 @@
#include <linux/highmem.h>
#include <linux/console.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <xen/xen.h>
#include <xen/interface/xen.h>
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index f9eb7de74f4..914f04695ce 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -43,6 +43,7 @@
#include <linux/debugfs.h>
#include <linux/bug.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 563d2050498..a29693fd313 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -14,6 +14,7 @@
*/
#include <linux/sched.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/smp.h>
#include <asm/paravirt.h>
@@ -361,7 +362,7 @@ static void xen_cpu_die(unsigned int cpu)
alternatives_smp_switch(0);
}
-static void __cpuinit xen_play_dead(void) /* used only with CPU_HOTPLUG */
+static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */
{
play_dead_common();
HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 24ded31b5ae..e0500646585 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -6,6 +6,7 @@
#include <linux/spinlock.h>
#include <linux/debugfs.h>
#include <linux/log2.h>
+#include <linux/gfp.h>
#include <asm/paravirt.h>
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 0d3f07cd1b5..32764b8880b 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -13,6 +13,7 @@
#include <linux/clockchips.h>
#include <linux/kernel_stat.h>
#include <linux/math64.h>
+#include <linux/gfp.h>
#include <asm/pvclock.h>
#include <asm/xen/hypervisor.h>
diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h
index 66410acf18b..4609b0f15f1 100644
--- a/arch/xtensa/include/asm/pci.h
+++ b/arch/xtensa/include/asm/pci.h
@@ -56,14 +56,6 @@ struct pci_dev;
#define PCI_DMA_BUS_IS_PHYS (1)
-/* pci_unmap_{page,single} is a no-op, so */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
-#define pci_ubnmap_len(PTR, LEN_NAME) (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-
/* Map a range of PCI memory or I/O space for a device into user space */
int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h
index 905e1e61965..3c549f79872 100644
--- a/arch/xtensa/include/asm/ptrace.h
+++ b/arch/xtensa/include/asm/ptrace.h
@@ -113,6 +113,7 @@ struct pt_regs {
#include <variant/core.h>
+# define arch_has_single_step() (1)
# define task_pt_regs(tsk) ((struct pt_regs*) \
(task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1)
# define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 80d24c485fd..77fc9f6dc01 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -104,7 +104,7 @@
* excsave has been restored, and
* stack pointer (a1) has been set.
*
- * Note: _user_exception might be at an odd adress. Don't use call0..call12
+ * Note: _user_exception might be at an odd address. Don't use call0..call12
*/
ENTRY(user_exception)
@@ -244,7 +244,7 @@ _user_exception:
* excsave has been restored, and
* stack pointer (a1) has been set.
*
- * Note: _kernel_exception might be at an odd adress. Don't use call0..call12
+ * Note: _kernel_exception might be at an odd address. Don't use call0..call12
*/
ENTRY(kernel_exception)
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index f5319d78c87..2783fda76dd 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -20,6 +20,7 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index e1a04a346e7..f167e0f5e05 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -23,7 +23,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/elf.h>
#include <linux/init.h>
#include <linux/prctl.h>
@@ -31,6 +30,7 @@
#include <linux/module.h>
#include <linux/mqueue.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 9486882ef0a..9d4e1ceb3f0 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -30,6 +30,17 @@
#include <asm/elf.h>
#include <asm/coprocessor.h>
+
+void user_enable_single_step(struct task_struct *child)
+{
+ child->ptrace |= PT_SINGLESTEP;
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+ child->ptrace &= ~PT_SINGLESTEP;
+}
+
/*
* Called by kernel/ptrace.c when detaching to disable single stepping.
*/
@@ -268,51 +279,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_pokeusr(child, addr, data);
break;
- /* continue and stop at next (return from) syscall */
-
- case PTRACE_SYSCALL:
- case PTRACE_CONT: /* restart after signal. */
- {
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- /* Make sure the single step bit is not set. */
- child->ptrace &= ~PT_SINGLESTEP;
- wake_up_process(child);
- ret = 0;
- break;
- }
-
- /*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL:
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- child->ptrace &= ~PT_SINGLESTEP;
- wake_up_process(child);
- break;
-
- case PTRACE_SINGLESTEP:
- ret = -EIO;
- if (!valid_signal(data))
- break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->ptrace |= PT_SINGLESTEP;
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
- break;
-
case PTRACE_GETREGS:
ret = ptrace_getregs(child, (void __user *) data);
break;
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index cdbc27ca966..ba150e5de2e 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -18,11 +18,11 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/bootmem.h>
+#include <linux/gfp.h>
#include <linux/swap.h>
#include <linux/mman.h>
#include <linux/nodemask.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <asm/bootparam.h>
#include <asm/page.h>
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index e60a1f57022..2c723e8b30d 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/console.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/major.h>
#include <linux/param.h>
diff --git a/block/Kconfig b/block/Kconfig
index e20fbde0875..f9e89f4d94b 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -78,8 +78,9 @@ config BLK_DEV_INTEGRITY
Protection. If in doubt, say N.
config BLK_CGROUP
- bool
+ tristate "Block cgroup support"
depends on CGROUPS
+ depends on CFQ_GROUP_IOSCHED
default n
---help---
Generic block IO controller cgroup interface. This is the common
diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
index b71abfb0d72..fc71cf071fb 100644
--- a/block/Kconfig.iosched
+++ b/block/Kconfig.iosched
@@ -23,6 +23,7 @@ config IOSCHED_DEADLINE
config IOSCHED_CFQ
tristate "CFQ I/O scheduler"
+ select BLK_CGROUP if CFQ_GROUP_IOSCHED
default y
---help---
The CFQ I/O scheduler tries to distribute bandwidth equally
@@ -35,7 +36,6 @@ config IOSCHED_CFQ
config CFQ_GROUP_IOSCHED
bool "CFQ Group Scheduling support"
depends on IOSCHED_CFQ && CGROUPS
- select BLK_CGROUP
default n
---help---
Enable group IO scheduling in CFQ.
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 8618d8996fe..6d88544b677 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -5,6 +5,7 @@
#include <linux/module.h>
#include <linux/bio.h>
#include <linux/blkdev.h>
+#include <linux/gfp.h>
#include "blk.h"
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index c85d74cae20..5fe03def34b 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -15,6 +15,7 @@
#include <linux/kdev_t.h>
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include "blk-cgroup.h"
static DEFINE_SPINLOCK(blkio_list_lock);
@@ -23,6 +24,31 @@ static LIST_HEAD(blkio_list);
struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
EXPORT_SYMBOL_GPL(blkio_root_cgroup);
+static struct cgroup_subsys_state *blkiocg_create(struct cgroup_subsys *,
+ struct cgroup *);
+static int blkiocg_can_attach(struct cgroup_subsys *, struct cgroup *,
+ struct task_struct *, bool);
+static void blkiocg_attach(struct cgroup_subsys *, struct cgroup *,
+ struct cgroup *, struct task_struct *, bool);
+static void blkiocg_destroy(struct cgroup_subsys *, struct cgroup *);
+static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *);
+
+struct cgroup_subsys blkio_subsys = {
+ .name = "blkio",
+ .create = blkiocg_create,
+ .can_attach = blkiocg_can_attach,
+ .attach = blkiocg_attach,
+ .destroy = blkiocg_destroy,
+ .populate = blkiocg_populate,
+#ifdef CONFIG_BLK_CGROUP
+ /* note: blkio_subsys_id is otherwise defined in blk-cgroup.h */
+ .subsys_id = blkio_subsys_id,
+#endif
+ .use_id = 1,
+ .module = THIS_MODULE,
+};
+EXPORT_SYMBOL_GPL(blkio_subsys);
+
struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
{
return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id),
@@ -253,7 +279,8 @@ remove_entry:
done:
free_css_id(&blkio_subsys, &blkcg->css);
rcu_read_unlock();
- kfree(blkcg);
+ if (blkcg != &blkio_root_cgroup)
+ kfree(blkcg);
}
static struct cgroup_subsys_state *
@@ -319,17 +346,6 @@ static void blkiocg_attach(struct cgroup_subsys *subsys, struct cgroup *cgroup,
task_unlock(tsk);
}
-struct cgroup_subsys blkio_subsys = {
- .name = "blkio",
- .create = blkiocg_create,
- .can_attach = blkiocg_can_attach,
- .attach = blkiocg_attach,
- .destroy = blkiocg_destroy,
- .populate = blkiocg_populate,
- .subsys_id = blkio_subsys_id,
- .use_id = 1,
-};
-
void blkio_policy_register(struct blkio_policy_type *blkiop)
{
spin_lock(&blkio_list_lock);
@@ -345,3 +361,17 @@ void blkio_policy_unregister(struct blkio_policy_type *blkiop)
spin_unlock(&blkio_list_lock);
}
EXPORT_SYMBOL_GPL(blkio_policy_unregister);
+
+static int __init init_cgroup_blkio(void)
+{
+ return cgroup_load_subsys(&blkio_subsys);
+}
+
+static void __exit exit_cgroup_blkio(void)
+{
+ cgroup_unload_subsys(&blkio_subsys);
+}
+
+module_init(init_cgroup_blkio);
+module_exit(exit_cgroup_blkio);
+MODULE_LICENSE("GPL");
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
index 84bf745fa77..8ccc20464da 100644
--- a/block/blk-cgroup.h
+++ b/block/blk-cgroup.h
@@ -15,7 +15,13 @@
#include <linux/cgroup.h>
-#ifdef CONFIG_BLK_CGROUP
+#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
+
+#ifndef CONFIG_BLK_CGROUP
+/* When blk-cgroup is a module, its subsys_id isn't a compile-time constant */
+extern struct cgroup_subsys blkio_subsys;
+#define blkio_subsys_id blkio_subsys.subsys_id
+#endif
struct blkio_cgroup {
struct cgroup_subsys_state css;
@@ -91,7 +97,7 @@ static inline void blkiocg_update_blkio_group_dequeue_stats(
struct blkio_group *blkg, unsigned long dequeue) {}
#endif
-#ifdef CONFIG_BLK_CGROUP
+#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
extern struct blkio_cgroup blkio_root_cgroup;
extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup);
extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 15c630813b1..edce1ef7933 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -24,6 +24,7 @@
#include <linux/mempool.h>
#include <linux/bio.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include "blk.h"
@@ -278,7 +279,7 @@ static struct attribute *integrity_attrs[] = {
NULL,
};
-static struct sysfs_ops integrity_ops = {
+static const struct sysfs_ops integrity_ops = {
.show = &integrity_attr_show,
.store = &integrity_attr_store,
};
diff --git a/block/blk-ioc.c b/block/blk-ioc.c
index 3f65c8aadb2..d22c4c55c40 100644
--- a/block/blk-ioc.c
+++ b/block/blk-ioc.c
@@ -7,6 +7,7 @@
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/bootmem.h> /* for max_pfn/max_low_pfn */
+#include <linux/slab.h>
#include "blk.h"
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 31e7a9375c1..f5ed5a1187b 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -8,7 +8,9 @@
#include <linux/blkdev.h>
#include <linux/bootmem.h> /* for max_pfn/max_low_pfn */
#include <linux/gcd.h>
+#include <linux/lcm.h>
#include <linux/jiffies.h>
+#include <linux/gfp.h>
#include "blk.h"
@@ -461,16 +463,6 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
}
EXPORT_SYMBOL(blk_queue_stack_limits);
-static unsigned int lcm(unsigned int a, unsigned int b)
-{
- if (a && b)
- return (a * b) / gcd(a, b);
- else if (b)
- return b;
-
- return a;
-}
-
/**
* blk_stack_limits - adjust queue_limits for stacked devices
* @t: the stacking driver limits (top device)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index e85442415db..306759bbdf1 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -2,6 +2,7 @@
* Functions related to sysfs handling
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/bio.h>
#include <linux/blkdev.h>
@@ -106,6 +107,19 @@ static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
return queue_var_show(max_sectors_kb, (page));
}
+static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
+{
+ return queue_var_show(queue_max_segments(q), (page));
+}
+
+static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
+{
+ if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
+ return queue_var_show(queue_max_segment_size(q), (page));
+
+ return queue_var_show(PAGE_CACHE_SIZE, (page));
+}
+
static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)
{
return queue_var_show(queue_logical_block_size(q), page);
@@ -280,6 +294,16 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
.show = queue_max_hw_sectors_show,
};
+static struct queue_sysfs_entry queue_max_segments_entry = {
+ .attr = {.name = "max_segments", .mode = S_IRUGO },
+ .show = queue_max_segments_show,
+};
+
+static struct queue_sysfs_entry queue_max_segment_size_entry = {
+ .attr = {.name = "max_segment_size", .mode = S_IRUGO },
+ .show = queue_max_segment_size_show,
+};
+
static struct queue_sysfs_entry queue_iosched_entry = {
.attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
.show = elv_iosched_show,
@@ -355,6 +379,8 @@ static struct attribute *default_attrs[] = {
&queue_ra_entry.attr,
&queue_max_hw_sectors_entry.attr,
&queue_max_sectors_entry.attr,
+ &queue_max_segments_entry.attr,
+ &queue_max_segment_size_entry.attr,
&queue_iosched_entry.attr,
&queue_hw_sector_size_entry.attr,
&queue_logical_block_size_entry.attr,
@@ -450,7 +476,7 @@ static void blk_release_queue(struct kobject *kobj)
kmem_cache_free(blk_requestq_cachep, q);
}
-static struct sysfs_ops queue_sysfs_ops = {
+static const struct sysfs_ops queue_sysfs_ops = {
.show = queue_attr_show,
.store = queue_attr_store,
};
diff --git a/block/blk-tag.c b/block/blk-tag.c
index 6b0f52c2096..ece65fc4c79 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -5,6 +5,7 @@
#include <linux/module.h>
#include <linux/bio.h>
#include <linux/blkdev.h>
+#include <linux/slab.h>
#include "blk.h"
diff --git a/block/blk-timeout.c b/block/blk-timeout.c
index 1ba7e0aca87..4f0c06c7a33 100644
--- a/block/blk-timeout.c
+++ b/block/blk-timeout.c
@@ -109,6 +109,7 @@ void blk_rq_timed_out_timer(unsigned long data)
struct request_queue *q = (struct request_queue *) data;
unsigned long flags, next = 0;
struct request *rq, *tmp;
+ int next_set = 0;
spin_lock_irqsave(q->queue_lock, flags);
@@ -122,16 +123,13 @@ void blk_rq_timed_out_timer(unsigned long data)
if (blk_mark_rq_complete(rq))
continue;
blk_rq_timed_out(rq);
- } else if (!next || time_after(next, rq->deadline))
+ } else if (!next_set || time_after(next, rq->deadline)) {
next = rq->deadline;
+ next_set = 1;
+ }
}
- /*
- * next can never be 0 here with the list non-empty, since we always
- * bump ->deadline to 1 so we can detect if the timer was ever added
- * or not. See comment in blk_add_timer()
- */
- if (next)
+ if (next_set)
mod_timer(&q->timeout, round_jiffies_up(next));
spin_unlock_irqrestore(q->queue_lock, flags);
diff --git a/block/bsg.c b/block/bsg.c
index a9fd2d84b53..82d58829ba5 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -21,6 +21,7 @@
#include <linux/idr.h>
#include <linux/bsg.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
@@ -260,7 +261,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
return ERR_PTR(ret);
/*
- * map scatter-gather elements seperately and string them to request
+ * map scatter-gather elements separately and string them to request
*/
rq = blk_get_request(q, rw, GFP_KERNEL);
if (!rq)
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index dee9d9378fe..838834be115 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -7,6 +7,7 @@
* Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/elevator.h>
#include <linux/jiffies.h>
@@ -47,6 +48,7 @@ static const int cfq_hist_divisor = 4;
#define CFQ_SERVICE_SHIFT 12
#define CFQQ_SEEK_THR (sector_t)(8 * 100)
+#define CFQQ_CLOSE_THR (sector_t)(8 * 1024)
#define CFQQ_SECT_THR_NONROT (sector_t)(2 * 32)
#define CFQQ_SEEKY(cfqq) (hweight32(cfqq->seek_history) > 32/8)
@@ -947,6 +949,11 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
unsigned int major, minor;
cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
+ if (cfqg && !cfqg->blkg.dev && bdi->dev && dev_name(bdi->dev)) {
+ sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
+ cfqg->blkg.dev = MKDEV(major, minor);
+ goto done;
+ }
if (cfqg || !create)
goto done;
@@ -1517,7 +1524,8 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd,
struct cfq_queue *cfqq)
{
if (cfqq) {
- cfq_log_cfqq(cfqd, cfqq, "set_active");
+ cfq_log_cfqq(cfqd, cfqq, "set_active wl_prio:%d wl_type:%d",
+ cfqd->serving_prio, cfqd->serving_type);
cfqq->slice_start = 0;
cfqq->dispatch_start = jiffies;
cfqq->allocated_slice = 0;
@@ -1660,9 +1668,9 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd,
}
static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq,
- struct request *rq, bool for_preempt)
+ struct request *rq)
{
- return cfq_dist_from_last(cfqd, rq) <= CFQQ_SEEK_THR;
+ return cfq_dist_from_last(cfqd, rq) <= CFQQ_CLOSE_THR;
}
static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
@@ -1689,7 +1697,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
* will contain the closest sector.
*/
__cfqq = rb_entry(parent, struct cfq_queue, p_node);
- if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
+ if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq))
return __cfqq;
if (blk_rq_pos(__cfqq->next_rq) < sector)
@@ -1700,7 +1708,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
return NULL;
__cfqq = rb_entry(node, struct cfq_queue, p_node);
- if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
+ if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq))
return __cfqq;
return NULL;
@@ -1721,6 +1729,8 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
{
struct cfq_queue *cfqq;
+ if (cfq_class_idle(cur_cfqq))
+ return NULL;
if (!cfq_cfqq_sync(cur_cfqq))
return NULL;
if (CFQQ_SEEKY(cur_cfqq))
@@ -1787,7 +1797,11 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
* Otherwise, we do only if they are the last ones
* in their service tree.
*/
- return service_tree->count == 1 && cfq_cfqq_sync(cfqq);
+ if (service_tree->count == 1 && cfq_cfqq_sync(cfqq))
+ return 1;
+ cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d",
+ service_tree->count);
+ return 0;
}
static void cfq_arm_slice_timer(struct cfq_data *cfqd)
@@ -1832,8 +1846,11 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
* time slice.
*/
if (sample_valid(cic->ttime_samples) &&
- (cfqq->slice_end - jiffies < cic->ttime_mean))
+ (cfqq->slice_end - jiffies < cic->ttime_mean)) {
+ cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%d",
+ cic->ttime_mean);
return;
+ }
cfq_mark_cfqq_wait_request(cfqq);
@@ -2041,6 +2058,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
slice = max(slice, 2 * cfqd->cfq_slice_idle);
slice = max_t(unsigned, slice, CFQ_MIN_TT);
+ cfq_log(cfqd, "workload slice:%d", slice);
cfqd->workload_expires = jiffies + slice;
cfqd->noidle_tree_requires_idle = false;
}
@@ -2188,10 +2206,13 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
struct cfq_queue *cfqq;
int dispatched = 0;
- while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL)
+ /* Expire the timeslice of the current active queue first */
+ cfq_slice_expired(cfqd, 0);
+ while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL) {
+ __cfq_set_active_queue(cfqd, cfqq);
dispatched += __cfq_forced_dispatch_cfqq(cfqq);
+ }
- cfq_slice_expired(cfqd, 0);
BUG_ON(cfqd->busy_queues);
cfq_log(cfqd, "forced_dispatch=%d", dispatched);
@@ -3103,7 +3124,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
* if this request is as-good as one we would expect from the
* current cfqq, let it preempt
*/
- if (cfq_rq_close(cfqd, cfqq, rq, true))
+ if (cfq_rq_close(cfqd, cfqq, rq))
return true;
return false;
@@ -3307,6 +3328,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
if (cfq_should_wait_busy(cfqd, cfqq)) {
cfqq->slice_end = jiffies + cfqd->cfq_slice_idle;
cfq_mark_cfqq_wait_busy(cfqq);
+ cfq_log_cfqq(cfqd, cfqq, "will busy wait");
}
/*
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 4eb8e9ea4af..f26051f4468 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -6,6 +6,7 @@
#include <linux/elevator.h>
#include <linux/fd.h>
#include <linux/hdreg.h>
+#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/smp_lock.h>
#include <linux/types.h>
diff --git a/block/elevator.c b/block/elevator.c
index ee3a883840f..76e3702d538 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -154,7 +154,7 @@ static struct elevator_type *elevator_get(const char *name)
spin_unlock(&elv_list_lock);
- sprintf(elv, "%s-iosched", name);
+ snprintf(elv, sizeof(elv), "%s-iosched", name);
request_module("%s", elv);
spin_lock(&elv_list_lock);
@@ -892,7 +892,7 @@ elv_attr_store(struct kobject *kobj, struct attribute *attr,
return error;
}
-static struct sysfs_ops elv_sysfs_ops = {
+static const struct sysfs_ops elv_sysfs_ops = {
.show = elv_attr_show,
.store = elv_attr_store,
};
diff --git a/block/ioctl.c b/block/ioctl.c
index be48ea51fae..8905d2a2a71 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -1,5 +1,6 @@
#include <linux/capability.h>
#include <linux/blkdev.h>
+#include <linux/gfp.h>
#include <linux/blkpg.h>
#include <linux/hdreg.h>
#include <linux/backing-dev.h>
diff --git a/block/noop-iosched.c b/block/noop-iosched.c
index 3a0d369d08c..232c4b38cd3 100644
--- a/block/noop-iosched.c
+++ b/block/noop-iosched.c
@@ -5,6 +5,7 @@
#include <linux/elevator.h>
#include <linux/bio.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
struct noop_data {
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6a2e295ee22..403857ad06d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -826,8 +826,8 @@ config CRYPTO_ANSI_CPRNG
help
This option enables the generic pseudo random number generator
for cryptographic modules. Uses the Algorithm specified in
- ANSI X9.31 A.2.4. Not this option must be enabled if CRYPTO_FIPS
- is selected
+ ANSI X9.31 A.2.4. Note that this option must be enabled if
+ CRYPTO_FIPS is selected
source "drivers/crypto/Kconfig"
diff --git a/crypto/ahash.c b/crypto/ahash.c
index 33a4ff45f84..b8c59b889c6 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -78,7 +78,6 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
walk->data -= walk->offset;
if (nbytes && walk->offset & alignmask && !err) {
- walk->offset += alignmask - 1;
walk->offset = ALIGN(walk->offset, alignmask + 1);
walk->data += walk->offset;
diff --git a/crypto/algapi.c b/crypto/algapi.c
index d49d7091cec..c3cf1a69a47 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include "internal.h"
diff --git a/crypto/algboss.c b/crypto/algboss.c
index 412241ce4cf..c3c196b5823 100644
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -19,6 +19,7 @@
#include <linux/notifier.h>
#include <linux/rtnetlink.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include "internal.h"
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index ec87f53d505..fdd8257d35d 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -24,6 +24,7 @@
#include <linux/dma-mapping.h>
#include <linux/raid/pq.h>
#include <linux/async_tx.h>
+#include <linux/gfp.h>
/**
* pq_scribble_page - space to hold throwaway P or Q buffer for
diff --git a/crypto/async_tx/raid6test.c b/crypto/async_tx/raid6test.c
index f84f6b4301d..c1321935ebc 100644
--- a/crypto/async_tx/raid6test.c
+++ b/crypto/async_tx/raid6test.c
@@ -20,6 +20,7 @@
*
*/
#include <linux/async_tx.h>
+#include <linux/gfp.h>
#include <linux/random.h>
#undef pr
diff --git a/crypto/authenc.c b/crypto/authenc.c
index 18870906ea0..05eb32e0d94 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -46,6 +46,12 @@ struct authenc_request_ctx {
char tail[];
};
+static void authenc_request_complete(struct aead_request *req, int err)
+{
+ if (err != -EINPROGRESS)
+ aead_request_complete(req, err);
+}
+
static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
unsigned int keylen)
{
@@ -142,7 +148,7 @@ static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq,
crypto_aead_authsize(authenc), 1);
out:
- aead_request_complete(req, err);
+ authenc_request_complete(req, err);
}
static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err)
@@ -208,7 +214,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
err = crypto_ablkcipher_decrypt(abreq);
out:
- aead_request_complete(req, err);
+ authenc_request_complete(req, err);
}
static void authenc_verify_ahash_done(struct crypto_async_request *areq,
@@ -245,7 +251,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
err = crypto_ablkcipher_decrypt(abreq);
out:
- aead_request_complete(req, err);
+ authenc_request_complete(req, err);
}
static u8 *crypto_authenc_ahash_fb(struct aead_request *req, unsigned int flags)
@@ -379,18 +385,20 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
err = crypto_authenc_genicv(areq, iv, 0);
}
- aead_request_complete(areq, err);
+ authenc_request_complete(areq, err);
}
static int crypto_authenc_encrypt(struct aead_request *req)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
- struct ablkcipher_request *abreq = aead_request_ctx(req);
+ struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
struct crypto_ablkcipher *enc = ctx->enc;
struct scatterlist *dst = req->dst;
unsigned int cryptlen = req->cryptlen;
- u8 *iv = (u8 *)(abreq + 1) + crypto_ablkcipher_reqsize(enc);
+ struct ablkcipher_request *abreq = (void *)(areq_ctx->tail
+ + ctx->reqoff);
+ u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc);
int err;
ablkcipher_request_set_tfm(abreq, enc);
@@ -418,7 +426,7 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
err = crypto_authenc_genicv(areq, greq->giv, 0);
}
- aead_request_complete(areq, err);
+ authenc_request_complete(areq, err);
}
static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)
@@ -454,7 +462,7 @@ static int crypto_authenc_verify(struct aead_request *req,
unsigned int authsize;
areq_ctx->complete = authenc_verify_ahash_done;
- areq_ctx->complete = authenc_verify_ahash_update_done;
+ areq_ctx->update_complete = authenc_verify_ahash_update_done;
ohash = authenc_ahash_fn(req, CRYPTO_TFM_REQ_MAY_SLEEP);
if (IS_ERR(ohash))
@@ -546,10 +554,6 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm)
if (IS_ERR(auth))
return PTR_ERR(auth);
- ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
- crypto_ahash_alignmask(auth),
- crypto_ahash_alignmask(auth) + 1);
-
enc = crypto_spawn_skcipher(&ictx->enc);
err = PTR_ERR(enc);
if (IS_ERR(enc))
@@ -558,13 +562,18 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm)
ctx->auth = auth;
ctx->enc = enc;
- tfm->crt_aead.reqsize = max_t(unsigned int,
- crypto_ahash_reqsize(auth) + ctx->reqoff +
- sizeof(struct authenc_request_ctx) +
+ ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
+ crypto_ahash_alignmask(auth),
+ crypto_ahash_alignmask(auth) + 1) +
+ crypto_ablkcipher_ivsize(enc);
+
+ tfm->crt_aead.reqsize = sizeof(struct authenc_request_ctx) +
+ ctx->reqoff +
+ max_t(unsigned int,
+ crypto_ahash_reqsize(auth) +
sizeof(struct ahash_request),
sizeof(struct skcipher_givcrypt_request) +
- crypto_ablkcipher_reqsize(enc) +
- crypto_ablkcipher_ivsize(enc));
+ crypto_ablkcipher_reqsize(enc));
return 0;
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 15c2eb53454..8d9544cf816 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -23,7 +23,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
-#include <linux/slab.h>
#include <linux/string.h>
struct hmac_ctx {
diff --git a/crypto/md5.c b/crypto/md5.c
index 9fda213a592..30efc7dad89 100644
--- a/crypto/md5.c
+++ b/crypto/md5.c
@@ -234,6 +234,7 @@ static struct shash_alg alg = {
.export = md5_export,
.import = md5_import,
.descsize = sizeof(struct md5_state),
+ .statesize = sizeof(struct md5_state),
.base = {
.cra_name = "md5",
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
diff --git a/crypto/rng.c b/crypto/rng.c
index ba05e7380e7..f93cb531118 100644
--- a/crypto/rng.c
+++ b/crypto/rng.c
@@ -19,6 +19,7 @@
#include <linux/mutex.h>
#include <linux/random.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/string.h>
static DEFINE_MUTEX(crypto_default_rng_lock);
diff --git a/crypto/seqiv.c b/crypto/seqiv.c
index 5a013a8bf87..4c449122941 100644
--- a/crypto/seqiv.c
+++ b/crypto/seqiv.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 0b7a8435255..ea610ad45aa 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -18,8 +18,8 @@
#include <crypto/hash.h>
#include <linux/err.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/string.h>
#include <linux/moduleparam.h>
diff --git a/crypto/xor.c b/crypto/xor.c
index fc5b836f343..b75182d8ab1 100644
--- a/crypto/xor.c
+++ b/crypto/xor.c
@@ -18,6 +18,7 @@
#define BH_TRACE 0
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/raid/xor.h>
#include <linux/jiffies.h>
#include <asm/xor.h>
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 368ae6d3a09..a2b902f4d43 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -96,8 +96,6 @@ source "drivers/edac/Kconfig"
source "drivers/rtc/Kconfig"
-source "drivers/clocksource/Kconfig"
-
source "drivers/dma/Kconfig"
source "drivers/dca/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 81e36596b1e..34f1e1064db 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_SGI_SN) += sn/
obj-y += firmware/
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/
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 66cc3f36a95..a8d8998dd5c 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -32,7 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o
#
acpi-y += bus.o glue.o
acpi-y += scan.o
-acpi-y += processor_pdc.o
+acpi-y += processor_core.o
acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o
acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
@@ -61,7 +61,7 @@ obj-$(CONFIG_ACPI_SBS) += sbs.o
obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o
# processor has its own "processor." module_param namespace
-processor-y := processor_core.o processor_throttling.o
+processor-y := processor_driver.o processor_throttling.o
processor-y += processor_idle.o processor_thermal.o
processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index b6ed60b57b0..56205a0b85d 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#ifdef CONFIG_ACPI_PROCFS_POWER
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 3597d73f28f..d9857138565 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/memory_hotplug.h>
+#include <linux/slab.h>
#include <acpi/acpi_drivers.h>
#define ACPI_MEMORY_DEVICE_CLASS "memory"
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 7e52295f1ec..19dacfd4316 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -27,6 +27,7 @@
#include <linux/freezer.h>
#include <linux/cpu.h>
#include <linux/clockchips.h>
+#include <linux/slab.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index 837de669743..78c55508aff 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -117,19 +117,14 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
- /* Mark wake-enabled or HW enable, or both */
-
- if (gpe_event_info->runtime_count) {
- /* Clear the GPE (of stale events), then enable it */
- status = acpi_hw_clear_gpe(gpe_event_info);
- if (ACPI_FAILURE(status))
- return_ACPI_STATUS(status);
-
- /* Enable the requested runtime GPE */
- status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
- }
+ /* Clear the GPE (of stale events), then enable it */
+ status = acpi_hw_clear_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status))
+ return_ACPI_STATUS(status);
- return_ACPI_STATUS(AE_OK);
+ /* Enable the requested GPE */
+ status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c
index cc8a10268f6..7116bc86494 100644
--- a/drivers/acpi/acpica/exmutex.c
+++ b/drivers/acpi/acpica/exmutex.c
@@ -375,8 +375,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
}
- /* Must have a valid thread ID */
-
+ /* Must have a valid thread. */
if (!walk_state->thread) {
ACPI_ERROR((AE_INFO,
"Cannot release Mutex [%4.4s], null thread info",
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index edf62bf5b26..2fbfe51fb14 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -468,6 +468,23 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
acpi_ut_add_reference(obj_desc->field.region_obj);
+ /* allow full data read from EC address space */
+ if (obj_desc->field.region_obj->region.space_id ==
+ ACPI_ADR_SPACE_EC) {
+ if (obj_desc->common_field.bit_length > 8) {
+ unsigned width =
+ ACPI_ROUND_BITS_UP_TO_BYTES(
+ obj_desc->common_field.bit_length);
+ // access_bit_width is u8, don't overflow it
+ if (width > 8)
+ width = 8;
+ obj_desc->common_field.access_byte_width =
+ width;
+ obj_desc->common_field.access_bit_width =
+ 8 * width;
+ }
+ }
+
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
obj_desc->field.start_field_bit_offset,
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 58d2c91ba62..3026e3fa83e 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -32,6 +32,7 @@
#include <linux/jiffies.h>
#include <linux/async.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
@@ -54,6 +55,7 @@
#define ACPI_BATTERY_DEVICE_NAME "Battery"
#define ACPI_BATTERY_NOTIFY_STATUS 0x80
#define ACPI_BATTERY_NOTIFY_INFO 0x81
+#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82
#define _COMPONENT ACPI_BATTERY_COMPONENT
@@ -88,10 +90,15 @@ static const struct acpi_device_id battery_device_ids[] = {
MODULE_DEVICE_TABLE(acpi, battery_device_ids);
-/* For buggy DSDTs that report negative 16-bit values for either charging
- * or discharging current and/or report 0 as 65536 due to bad math.
- */
-#define QUIRK_SIGNED16_CURRENT 0x0001
+enum {
+ ACPI_BATTERY_ALARM_PRESENT,
+ ACPI_BATTERY_XINFO_PRESENT,
+ /* For buggy DSDTs that report negative 16-bit values for either
+ * charging or discharging current and/or report 0 as 65536
+ * due to bad math.
+ */
+ ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
+};
struct acpi_battery {
struct mutex lock;
@@ -109,6 +116,12 @@ struct acpi_battery {
int design_voltage;
int design_capacity_warning;
int design_capacity_low;
+ int cycle_count;
+ int measurement_accuracy;
+ int max_sampling_time;
+ int min_sampling_time;
+ int max_averaging_interval;
+ int min_averaging_interval;
int capacity_granularity_1;
int capacity_granularity_2;
int alarm;
@@ -118,8 +131,7 @@ struct acpi_battery {
char oem_info[32];
int state;
int power_unit;
- u8 alarm_present;
- long quirks;
+ unsigned long flags;
};
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
@@ -198,6 +210,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = acpi_battery_technology(battery);
break;
+ case POWER_SUPPLY_PROP_CYCLE_COUNT:
+ val->intval = battery->cycle_count;
+ break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
val->intval = battery->design_voltage * 1000;
break;
@@ -239,6 +254,7 @@ static enum power_supply_property charge_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -254,6 +270,7 @@ static enum power_supply_property energy_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -305,6 +322,28 @@ static struct acpi_offsets info_offsets[] = {
{offsetof(struct acpi_battery, oem_info), 1},
};
+static struct acpi_offsets extended_info_offsets[] = {
+ {offsetof(struct acpi_battery, power_unit), 0},
+ {offsetof(struct acpi_battery, design_capacity), 0},
+ {offsetof(struct acpi_battery, full_charge_capacity), 0},
+ {offsetof(struct acpi_battery, technology), 0},
+ {offsetof(struct acpi_battery, design_voltage), 0},
+ {offsetof(struct acpi_battery, design_capacity_warning), 0},
+ {offsetof(struct acpi_battery, design_capacity_low), 0},
+ {offsetof(struct acpi_battery, cycle_count), 0},
+ {offsetof(struct acpi_battery, measurement_accuracy), 0},
+ {offsetof(struct acpi_battery, max_sampling_time), 0},
+ {offsetof(struct acpi_battery, min_sampling_time), 0},
+ {offsetof(struct acpi_battery, max_averaging_interval), 0},
+ {offsetof(struct acpi_battery, min_averaging_interval), 0},
+ {offsetof(struct acpi_battery, capacity_granularity_1), 0},
+ {offsetof(struct acpi_battery, capacity_granularity_2), 0},
+ {offsetof(struct acpi_battery, model_number), 1},
+ {offsetof(struct acpi_battery, serial_number), 1},
+ {offsetof(struct acpi_battery, type), 1},
+ {offsetof(struct acpi_battery, oem_info), 1},
+};
+
static int extract_package(struct acpi_battery *battery,
union acpi_object *package,
struct acpi_offsets *offsets, int num)
@@ -350,22 +389,29 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
{
int result = -EFAULT;
acpi_status status = 0;
+ char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
+ "_BIX" : "_BIF";
+
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
if (!acpi_battery_present(battery))
return 0;
mutex_lock(&battery->lock);
- status = acpi_evaluate_object(battery->device->handle, "_BIF",
- NULL, &buffer);
+ status = acpi_evaluate_object(battery->device->handle, name,
+ NULL, &buffer);
mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
+ ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
return -ENODEV;
}
-
- result = extract_package(battery, buffer.pointer,
- info_offsets, ARRAY_SIZE(info_offsets));
+ if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
+ result = extract_package(battery, buffer.pointer,
+ extended_info_offsets,
+ ARRAY_SIZE(extended_info_offsets));
+ else
+ result = extract_package(battery, buffer.pointer,
+ info_offsets, ARRAY_SIZE(info_offsets));
kfree(buffer.pointer);
return result;
}
@@ -399,7 +445,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
battery->update_time = jiffies;
kfree(buffer.pointer);
- if ((battery->quirks & QUIRK_SIGNED16_CURRENT) &&
+ if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) &&
battery->rate_now != -1)
battery->rate_now = abs((s16)battery->rate_now);
@@ -412,7 +458,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &arg0 };
- if (!acpi_battery_present(battery)|| !battery->alarm_present)
+ if (!acpi_battery_present(battery) ||
+ !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
return -ENODEV;
arg0.integer.value = battery->alarm;
@@ -437,10 +484,10 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
/* See if alarms are supported, and if so, set default */
status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
if (ACPI_FAILURE(status)) {
- battery->alarm_present = 0;
+ clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
return 0;
}
- battery->alarm_present = 1;
+ set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
if (!battery->alarm)
battery->alarm = battery->design_capacity_warning;
return acpi_battery_set_alarm(battery);
@@ -510,9 +557,8 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
static void acpi_battery_quirks(struct acpi_battery *battery)
{
- battery->quirks = 0;
if (dmi_name_in_vendors("Acer") && battery->power_unit) {
- battery->quirks |= QUIRK_SIGNED16_CURRENT;
+ set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags);
}
}
@@ -522,13 +568,13 @@ static int acpi_battery_update(struct acpi_battery *battery)
result = acpi_battery_get_status(battery);
if (result)
return result;
-#ifdef CONFIG_ACPI_SYSFS_POWER
if (!acpi_battery_present(battery)) {
+#ifdef CONFIG_ACPI_SYSFS_POWER
sysfs_remove_battery(battery);
+#endif
battery->update_time = 0;
return 0;
}
-#endif
if (!battery->update_time ||
old_present != acpi_battery_present(battery)) {
result = acpi_battery_get_info(battery);
@@ -590,6 +636,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
seq_printf(seq, "design capacity low: %d %sh\n",
battery->design_capacity_low,
acpi_battery_units(battery));
+ seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
seq_printf(seq, "capacity granularity 1: %d %sh\n",
battery->capacity_granularity_1,
acpi_battery_units(battery));
@@ -833,7 +880,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
#ifdef CONFIG_ACPI_SYSFS_POWER
/* acpi_battery_update could remove power_supply object */
if (battery->bat.dev)
- kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
+ power_supply_changed(&battery->bat);
#endif
}
@@ -841,6 +888,7 @@ static int acpi_battery_add(struct acpi_device *device)
{
int result = 0;
struct acpi_battery *battery = NULL;
+ acpi_handle handle;
if (!device)
return -EINVAL;
battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
@@ -851,6 +899,9 @@ static int acpi_battery_add(struct acpi_device *device)
strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
device->driver_data = battery;
mutex_init(&battery->lock);
+ if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
+ "_BIX", &handle)))
+ set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
acpi_battery_update(battery);
#ifdef CONFIG_ACPI_PROCFS_POWER
result = acpi_battery_add_fs(device);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index a52126e4630..37132dc2da0 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -32,6 +32,7 @@
#include <linux/device.h>
#include <linux/proc_fs.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#ifdef CONFIG_X86
#include <asm/mpspec.h>
#endif
@@ -190,16 +191,16 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
* Get the device's power state either directly (via _PSC) or
* indirectly (via power resources).
*/
- if (device->power.flags.explicit_get) {
+ if (device->power.flags.power_resources) {
+ result = acpi_power_get_inferred_state(device);
+ if (result)
+ return result;
+ } else if (device->power.flags.explicit_get) {
status = acpi_evaluate_integer(device->handle, "_PSC",
NULL, &psc);
if (ACPI_FAILURE(status))
return -ENODEV;
device->power.state = (int)psc;
- } else if (device->power.flags.power_resources) {
- result = acpi_power_get_inferred_state(device);
- if (result)
- return result;
}
*state = device->power.state;
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index f53fbe307c9..fd51c4ab482 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -30,6 +30,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 5faf6c21257..45cd03b4630 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/acpi.h>
#include <acpi/acpi_bus.h>
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index cc421b7ae16..146135e7a6a 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index b2586f57e1f..3fe29e992be 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/notifier.h>
@@ -605,7 +606,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
list_for_each_entry(dock_station, &dock_stations, sibling) {
/*
* An ATA bay can be in a dock and itself can be ejected
- * seperately, so there are two 'dock stations' which need the
+ * separately, so there are two 'dock stations' which need the
* ops
*/
dd = find_dock_dependent_device(dock_station, handle);
@@ -1025,13 +1026,10 @@ static int dock_remove(struct dock_station *ds)
static acpi_status
find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
{
- acpi_status status = AE_OK;
-
if (is_dock(handle))
- if (dock_add(handle) >= 0)
- status = AE_CTRL_TERMINATE;
+ dock_add(handle);
- return status;
+ return AE_OK;
}
static acpi_status
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index d7a6bbbb834..f2234db85da 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -39,6 +39,7 @@
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -76,8 +77,9 @@ enum ec_command {
enum {
EC_FLAGS_QUERY_PENDING, /* Query is pending */
EC_FLAGS_GPE_STORM, /* GPE storm detected */
- EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and
+ EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and
* OpReg are installed */
+ EC_FLAGS_FROZEN, /* Transactions are suspended */
};
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -291,6 +293,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
if (t->rdata)
memset(t->rdata, 0, t->rlen);
mutex_lock(&ec->lock);
+ if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) {
+ status = -EINVAL;
+ goto unlock;
+ }
if (ec->global_lock) {
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
if (ACPI_FAILURE(status)) {
@@ -453,6 +459,32 @@ int ec_transaction(u8 command,
EXPORT_SYMBOL(ec_transaction);
+void acpi_ec_suspend_transactions(void)
+{
+ struct acpi_ec *ec = first_ec;
+
+ if (!ec)
+ return;
+
+ mutex_lock(&ec->lock);
+ /* Prevent transactions from being carried out */
+ set_bit(EC_FLAGS_FROZEN, &ec->flags);
+ mutex_unlock(&ec->lock);
+}
+
+void acpi_ec_resume_transactions(void)
+{
+ struct acpi_ec *ec = first_ec;
+
+ if (!ec)
+ return;
+
+ mutex_lock(&ec->lock);
+ /* Allow transactions to be carried out again */
+ clear_bit(EC_FLAGS_FROZEN, &ec->flags);
+ mutex_unlock(&ec->lock);
+}
+
static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
{
int result;
@@ -597,12 +629,12 @@ static u32 acpi_ec_gpe_handler(void *data)
static acpi_status
acpi_ec_space_handler(u32 function, acpi_physical_address address,
- u32 bits, u64 *value,
+ u32 bits, u64 *value64,
void *handler_context, void *region_context)
{
struct acpi_ec *ec = handler_context;
- int result = 0, i;
- u8 temp = 0;
+ int result = 0, i, bytes = bits / 8;
+ u8 *value = (u8 *)value64;
if ((address > 0xFF) || !value || !handler_context)
return AE_BAD_PARAMETER;
@@ -610,32 +642,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
if (function != ACPI_READ && function != ACPI_WRITE)
return AE_BAD_PARAMETER;
- if (bits != 8 && acpi_strict)
- return AE_BAD_PARAMETER;
-
- if (EC_FLAGS_MSI)
+ if (EC_FLAGS_MSI || bits > 8)
acpi_ec_burst_enable(ec);
- if (function == ACPI_READ) {
- result = acpi_ec_read(ec, address, &temp);
- *value = temp;
- } else {
- temp = 0xff & (*value);
- result = acpi_ec_write(ec, address, temp);
- }
+ for (i = 0; i < bytes; ++i, ++address, ++value)
+ result = (function == ACPI_READ) ?
+ acpi_ec_read(ec, address, value) :
+ acpi_ec_write(ec, address, *value);
- for (i = 8; unlikely(bits - i > 0); i += 8) {
- ++address;
- if (function == ACPI_READ) {
- result = acpi_ec_read(ec, address, &temp);
- (*value) |= ((u64)temp) << i;
- } else {
- temp = 0xff & ((*value) >> i);
- result = acpi_ec_write(ec, address, temp);
- }
- }
-
- if (EC_FLAGS_MSI)
+ if (EC_FLAGS_MSI || bits > 8)
acpi_ec_burst_disable(ec);
switch (result) {
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index c511071bfd7..d439314a75d 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -10,6 +10,7 @@
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/poll.h>
+#include <linux/gfp.h>
#include <acpi/acpi_drivers.h>
#include <net/netlink.h>
#include <net/genetlink.h>
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 6d5b64b7d52..4af6301601e 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -9,6 +9,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/rwsem.h>
#include <linux/acpi.h>
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 9c4c962e46e..e2841136723 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -49,6 +49,8 @@ void acpi_early_processor_set_pdc(void);
int acpi_ec_init(void);
int acpi_ec_ecdt_probe(void);
int acpi_boot_ec_enable(void);
+void acpi_ec_suspend_transactions(void);
+void acpi_ec_resume_transactions(void);
/*--------------------------------------------------------------------------
Suspend/Resume
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index b8725461d88..b0337d31460 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -61,8 +61,10 @@ int node_to_pxm(int node)
void __acpi_map_pxm_to_node(int pxm, int node)
{
- pxm_to_node_map[pxm] = node;
- node_to_pxm_map[node] = pxm;
+ if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm])
+ pxm_to_node_map[pxm] = node;
+ if (node_to_pxm_map[node] == PXM_INVAL || pxm < node_to_pxm_map[node])
+ node_to_pxm_map[node] = pxm;
}
int acpi_map_pxm_to_node(int pxm)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 8e6d8665f0a..7594f65800c 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -758,7 +758,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
queue = hp ? kacpi_hotplug_wq :
(type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
dpc->wait = hp ? 1 : 0;
- INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+
+ if (queue == kacpi_hotplug_wq)
+ INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+ else if (queue == kacpi_notify_wq)
+ INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+ else
+ INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+
ret = queue_work(queue, &dpc->work);
if (!ret) {
@@ -1151,16 +1158,10 @@ int acpi_check_resource_conflict(const struct resource *res)
if (clash) {
if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
- printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
- " conflicts with ACPI region %s"
- " [0x%llx-0x%llx]\n",
- acpi_enforce_resources == ENFORCE_RESOURCES_LAX
- ? KERN_WARNING : KERN_ERR,
- ioport ? "I/O" : "Memory", res->name,
- (long long) res->start, (long long) res->end,
- res_list_elem->name,
- (long long) res_list_elem->start,
- (long long) res_list_elem->end);
+ printk(KERN_WARNING "ACPI: resource %s %pR"
+ " conflicts with ACPI region %s %pR\n",
+ res->name, res, res_list_elem->name,
+ res_list_elem);
if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
printk(KERN_NOTICE "ACPI: This conflict may"
" cause random problems and system"
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 843699ed93f..b0a71ecee68 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -37,6 +37,7 @@
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 04b0f007c9b..8d47a5846ae 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -39,6 +39,7 @@
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d724736d56c..aefce33f2a0 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -34,6 +34,7 @@
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
index 11f21974320..07f7fea8a4e 100644
--- a/drivers/acpi/pci_slot.c
+++ b/drivers/acpi/pci_slot.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/acpi.h>
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 0f30c3c1eea..ddc76787b84 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -39,6 +39,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <acpi/acpi_bus.h>
diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c
index 834c5af0de4..e8c32a49f14 100644
--- a/drivers/acpi/power_meter.c
+++ b/drivers/acpi/power_meter.c
@@ -25,6 +25,7 @@
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/sched.h>
#include <linux/time.h>
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index d0d25e2e1ce..1ac678d2c51 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -435,7 +435,7 @@ acpi_system_write_wakeup_device(struct file *file,
found_dev->wakeup.gpe_device)) {
printk(KERN_WARNING
"ACPI: '%s' and '%s' have the same GPE, "
- "can't disable/enable one seperately\n",
+ "can't disable/enable one separately\n",
dev->pnp.bus_id, found_dev->pnp.bus_id);
dev->wakeup.state.enabled =
found_dev->wakeup.state.enabled;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 9863c98c81b..51284351418 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -1,381 +1,63 @@
/*
- * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
+ * Copyright (C) 2005 Intel Corporation
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
*
- * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
- * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
- * - Added processor hotplug support
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * TBD:
- * 1. Make # power states dynamic.
- * 2. Support duty_cycle values that span bit 4.
- * 3. Optimize by having scheduler determine business instead of
- * having us try to calculate it here.
- * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
+ * Alex Chiang <achiang@hp.com>
+ * - Unified x86/ia64 implementations
+ * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * - Added _PDC for platforms with Intel CPUs
*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/cpufreq.h>
-#include <linux/cpu.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <linux/dmi.h>
-#include <linux/moduleparam.h>
-#include <linux/cpuidle.h>
+#include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/cpu.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/smp.h>
-#include <asm/acpi.h>
-
-#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
-#define PREFIX "ACPI: "
-
-#define ACPI_PROCESSOR_CLASS "processor"
-#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
-#define ACPI_PROCESSOR_FILE_INFO "info"
-#define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
-#define ACPI_PROCESSOR_FILE_LIMIT "limit"
-#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
-#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
-#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
-
-#define ACPI_PROCESSOR_LIMIT_USER 0
-#define ACPI_PROCESSOR_LIMIT_THERMAL 1
+#include "internal.h"
+#define PREFIX "ACPI: "
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_core");
-MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_DESCRIPTION("ACPI Processor Driver");
-MODULE_LICENSE("GPL");
-
-static int acpi_processor_add(struct acpi_device *device);
-static int acpi_processor_remove(struct acpi_device *device, int type);
-#ifdef CONFIG_ACPI_PROCFS
-static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-#endif
-static void acpi_processor_notify(struct acpi_device *device, u32 event);
-static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
-static int acpi_processor_handle_eject(struct acpi_processor *pr);
-
-
-static const struct acpi_device_id processor_device_ids[] = {
- {ACPI_PROCESSOR_OBJECT_HID, 0},
- {"ACPI0007", 0},
- {"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, processor_device_ids);
-
-static struct acpi_driver acpi_processor_driver = {
- .name = "processor",
- .class = ACPI_PROCESSOR_CLASS,
- .ids = processor_device_ids,
- .ops = {
- .add = acpi_processor_add,
- .remove = acpi_processor_remove,
- .suspend = acpi_processor_suspend,
- .resume = acpi_processor_resume,
- .notify = acpi_processor_notify,
- },
-};
-
-#define INSTALL_NOTIFY_HANDLER 1
-#define UNINSTALL_NOTIFY_HANDLER 2
-#ifdef CONFIG_ACPI_PROCFS
-static const struct file_operations acpi_processor_info_fops = {
- .owner = THIS_MODULE,
- .open = acpi_processor_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-#endif
-
-DEFINE_PER_CPU(struct acpi_processor *, processors);
-struct acpi_processor_errata errata __read_mostly;
-
-/* --------------------------------------------------------------------------
- Errata Handling
- -------------------------------------------------------------------------- */
-
-static int acpi_processor_errata_piix4(struct pci_dev *dev)
+static int set_no_mwait(const struct dmi_system_id *id)
{
- u8 value1 = 0;
- u8 value2 = 0;
-
-
- if (!dev)
- return -EINVAL;
-
- /*
- * Note that 'dev' references the PIIX4 ACPI Controller.
- */
-
- switch (dev->revision) {
- case 0:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
- break;
- case 1:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
- break;
- case 2:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
- break;
- case 3:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
- break;
- default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
- break;
- }
-
- switch (dev->revision) {
-
- case 0: /* PIIX4 A-step */
- case 1: /* PIIX4 B-step */
- /*
- * See specification changes #13 ("Manual Throttle Duty Cycle")
- * and #14 ("Enabling and Disabling Manual Throttle"), plus
- * erratum #5 ("STPCLK# Deassertion Time") from the January
- * 2002 PIIX4 specification update. Applies to only older
- * PIIX4 models.
- */
- errata.piix4.throttle = 1;
-
- case 2: /* PIIX4E */
- case 3: /* PIIX4M */
- /*
- * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
- * Livelock") from the January 2002 PIIX4 specification update.
- * Applies to all PIIX4 models.
- */
-
- /*
- * BM-IDE
- * ------
- * Find the PIIX4 IDE Controller and get the Bus Master IDE
- * Status register address. We'll use this later to read
- * each IDE controller's DMA status to make sure we catch all
- * DMA activity.
- */
- dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB,
- PCI_ANY_ID, PCI_ANY_ID, NULL);
- if (dev) {
- errata.piix4.bmisx = pci_resource_start(dev, 4);
- pci_dev_put(dev);
- }
-
- /*
- * Type-F DMA
- * ----------
- * Find the PIIX4 ISA Controller and read the Motherboard
- * DMA controller's status to see if Type-F (Fast) DMA mode
- * is enabled (bit 7) on either channel. Note that we'll
- * disable C3 support if this is enabled, as some legacy
- * devices won't operate well if fast DMA is disabled.
- */
- dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_0,
- PCI_ANY_ID, PCI_ANY_ID, NULL);
- if (dev) {
- pci_read_config_byte(dev, 0x76, &value1);
- pci_read_config_byte(dev, 0x77, &value2);
- if ((value1 & 0x80) || (value2 & 0x80))
- errata.piix4.fdma = 1;
- pci_dev_put(dev);
- }
-
- break;
- }
-
- if (errata.piix4.bmisx)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Bus master activity detection (BM-IDE) erratum enabled\n"));
- if (errata.piix4.fdma)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Type-F DMA livelock erratum (C3 disabled)\n"));
-
+ printk(KERN_NOTICE PREFIX "%s detected - "
+ "disabling mwait for CPU C-states\n", id->ident);
+ idle_nomwait = 1;
return 0;
}
-static int acpi_processor_errata(struct acpi_processor *pr)
-{
- int result = 0;
- struct pci_dev *dev = NULL;
-
-
- if (!pr)
- return -EINVAL;
-
- /*
- * PIIX4
- */
- dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
- PCI_ANY_ID, NULL);
- if (dev) {
- result = acpi_processor_errata_piix4(dev);
- pci_dev_put(dev);
- }
-
- return result;
-}
-
-/* --------------------------------------------------------------------------
- FS Interface (/proc)
- -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI_PROCFS
-static struct proc_dir_entry *acpi_processor_dir = NULL;
-
-static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
-{
- struct acpi_processor *pr = seq->private;
-
-
- if (!pr)
- goto end;
-
- seq_printf(seq, "processor id: %d\n"
- "acpi id: %d\n"
- "bus mastering control: %s\n"
- "power management: %s\n"
- "throttling control: %s\n"
- "limit interface: %s\n",
- pr->id,
- pr->acpi_id,
- pr->flags.bm_control ? "yes" : "no",
- pr->flags.power ? "yes" : "no",
- pr->flags.throttling ? "yes" : "no",
- pr->flags.limit ? "yes" : "no");
-
- end:
- return 0;
-}
-
-static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_processor_info_seq_show,
- PDE(inode)->data);
-}
-
-static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
-{
- struct proc_dir_entry *entry = NULL;
-
-
- if (!acpi_device_dir(device)) {
- acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_processor_dir);
- if (!acpi_device_dir(device))
- return -ENODEV;
- }
-
- /* 'info' [R] */
- entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
- S_IRUGO, acpi_device_dir(device),
- &acpi_processor_info_fops,
- acpi_driver_data(device));
- if (!entry)
- return -EIO;
-
- /* 'throttling' [R/W] */
- entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
- S_IFREG | S_IRUGO | S_IWUSR,
- acpi_device_dir(device),
- &acpi_processor_throttling_fops,
- acpi_driver_data(device));
- if (!entry)
- return -EIO;
-
- /* 'limit' [R/W] */
- entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT,
- S_IFREG | S_IRUGO | S_IWUSR,
- acpi_device_dir(device),
- &acpi_processor_limit_fops,
- acpi_driver_data(device));
- if (!entry)
- return -EIO;
- return 0;
-}
-static int acpi_processor_remove_fs(struct acpi_device *device)
-{
-
- if (acpi_device_dir(device)) {
- remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
- acpi_device_dir(device));
- remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
- acpi_device_dir(device));
- remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
- acpi_device_dir(device));
- remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
- acpi_device_dir(device) = NULL;
- }
-
- return 0;
-}
-#else
-static inline int acpi_processor_add_fs(struct acpi_device *device)
-{
- return 0;
-}
-static inline int acpi_processor_remove_fs(struct acpi_device *device)
-{
- return 0;
-}
-#endif
-
-/* Use the acpiid in MADT to map cpus in case of SMP */
-
-#ifndef CONFIG_SMP
-static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; }
-#else
-
-static struct acpi_table_madt *madt;
+static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
+ {
+ set_no_mwait, "IFL91 board", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
+ DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
+ DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
+ {
+ set_no_mwait, "Extensa 5220", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
+ DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
+ {},
+};
+#ifdef CONFIG_SMP
static int map_lapic_id(struct acpi_subtable_header *entry,
u32 acpi_id, int *apic_id)
{
struct acpi_madt_local_apic *lapic =
(struct acpi_madt_local_apic *)entry;
- if ((lapic->lapic_flags & ACPI_MADT_ENABLED) &&
- lapic->processor_id == acpi_id) {
- *apic_id = lapic->id;
- return 1;
- }
- return 0;
+
+ if (!(lapic->lapic_flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ if (lapic->processor_id != acpi_id)
+ return 0;
+
+ *apic_id = lapic->id;
+ return 1;
}
static int map_x2apic_id(struct acpi_subtable_header *entry,
@@ -383,22 +65,16 @@ static int map_x2apic_id(struct acpi_subtable_header *entry,
{
struct acpi_madt_local_x2apic *apic =
(struct acpi_madt_local_x2apic *)entry;
- u32 tmp = apic->local_apic_id;
- /* Only check enabled APICs*/
if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
return 0;
- /* Device statement declaration type */
- if (device_declaration) {
- if (apic->uid == acpi_id)
- goto found;
+ if (device_declaration && (apic->uid == acpi_id)) {
+ *apic_id = apic->local_apic_id;
+ return 1;
}
return 0;
-found:
- *apic_id = tmp;
- return 1;
}
static int map_lsapic_id(struct acpi_subtable_header *entry,
@@ -406,35 +82,34 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
{
struct acpi_madt_local_sapic *lsapic =
(struct acpi_madt_local_sapic *)entry;
- u32 tmp = (lsapic->id << 8) | lsapic->eid;
- /* Only check enabled APICs*/
if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
return 0;
- /* Device statement declaration type */
if (device_declaration) {
- if (entry->length < 16)
- printk(KERN_ERR PREFIX
- "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n",
- tmp);
- else if (lsapic->uid == acpi_id)
- goto found;
- /* Processor statement declaration type */
- } else if (lsapic->processor_id == acpi_id)
- goto found;
+ if ((entry->length < 16) || (lsapic->uid != acpi_id))
+ return 0;
+ } else if (lsapic->processor_id != acpi_id)
+ return 0;
- return 0;
-found:
- *apic_id = tmp;
+ *apic_id = (lsapic->id << 8) | lsapic->eid;
return 1;
}
static int map_madt_entry(int type, u32 acpi_id)
{
unsigned long madt_end, entry;
+ static struct acpi_table_madt *madt;
+ static int read_madt;
int apic_id = -1;
+ if (!read_madt) {
+ if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
+ (struct acpi_table_header **)&madt)))
+ madt = NULL;
+ read_madt++;
+ }
+
if (!madt)
return apic_id;
@@ -494,7 +169,7 @@ exit:
return apic_id;
}
-static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id)
+int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
{
int i;
int apic_id = -1;
@@ -511,630 +186,170 @@ static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id)
}
return -1;
}
+EXPORT_SYMBOL_GPL(acpi_get_cpuid);
#endif
-/* --------------------------------------------------------------------------
- Driver Interface
- -------------------------------------------------------------------------- */
-
-static int acpi_processor_get_info(struct acpi_device *device)
+static bool processor_physically_present(acpi_handle handle)
{
- acpi_status status = 0;
+ int cpuid, type;
+ u32 acpi_id;
+ acpi_status status;
+ acpi_object_type acpi_type;
+ unsigned long long tmp;
union acpi_object object = { 0 };
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
- struct acpi_processor *pr;
- int cpu_index, device_declaration = 0;
- static int cpu0_initialized;
-
- pr = acpi_driver_data(device);
- if (!pr)
- return -EINVAL;
-
- if (num_online_cpus() > 1)
- errata.smp = TRUE;
-
- acpi_processor_errata(pr);
-
- /*
- * Check to see if we have bus mastering arbitration control. This
- * is required for proper C3 usage (to maintain cache coherency).
- */
- if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
- pr->flags.bm_control = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Bus mastering arbitration control present\n"));
- } else
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "No bus mastering arbitration control\n"));
-
- if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
- /* Declared with "Processor" statement; match ProcessorID */
- status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Evaluating processor object\n");
- return -ENODEV;
- }
-
- /*
- * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
- * >>> 'acpi_get_processor_id(acpi_id, &id)' in
- * arch/xxx/acpi.c
- */
- pr->acpi_id = object.processor.proc_id;
- } else {
- /*
- * Declared with "Device" statement; match _UID.
- * Note that we don't handle string _UIDs yet.
- */
- unsigned long long value;
- status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
- NULL, &value);
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX
- "Evaluating processor _UID [%#x]\n", status);
- return -ENODEV;
- }
- device_declaration = 1;
- pr->acpi_id = value;
- }
- cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id);
-
- /* Handle UP system running SMP kernel, with no LAPIC in MADT */
- if (!cpu0_initialized && (cpu_index == -1) &&
- (num_online_cpus() == 1)) {
- cpu_index = 0;
- }
-
- cpu0_initialized = 1;
-
- pr->id = cpu_index;
-
- /*
- * Extra Processor objects may be enumerated on MP systems with
- * less than the max # of CPUs. They should be ignored _iff
- * they are physically not present.
- */
- if (pr->id == -1) {
- if (ACPI_FAILURE
- (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
- return -ENODEV;
- }
- }
- /*
- * On some boxes several processors use the same processor bus id.
- * But they are located in different scope. For example:
- * \_SB.SCK0.CPU0
- * \_SB.SCK1.CPU0
- * Rename the processor device bus id. And the new bus id will be
- * generated as the following format:
- * CPU+CPU ID.
- */
- sprintf(acpi_device_bid(device), "CPU%X", pr->id);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
- pr->acpi_id));
-
- if (!object.processor.pblk_address)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
- else if (object.processor.pblk_length != 6)
- printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
- object.processor.pblk_length);
- else {
- pr->throttling.address = object.processor.pblk_address;
- pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
- pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
-
- pr->pblk = object.processor.pblk_address;
-
- /*
- * We don't care about error returns - we just try to mark
- * these reserved so that nobody else is confused into thinking
- * that this region might be unused..
- *
- * (In particular, allocating the IO range for Cardbus)
- */
- request_region(pr->throttling.address, 6, "ACPI CPU throttle");
- }
-
- /*
- * If ACPI describes a slot number for this CPU, we can use it
- * ensure we get the right value in the "physical id" field
- * of /proc/cpuinfo
- */
- status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
- if (ACPI_SUCCESS(status))
- arch_fix_phys_package_id(pr->id, object.integer.value);
-
- return 0;
-}
-static DEFINE_PER_CPU(void *, processor_device_array);
-
-static void acpi_processor_notify(struct acpi_device *device, u32 event)
-{
- struct acpi_processor *pr = acpi_driver_data(device);
- int saved;
-
- if (!pr)
- return;
-
- switch (event) {
- case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
- saved = pr->performance_platform_limit;
- acpi_processor_ppc_has_changed(pr, 1);
- if (saved == pr->performance_platform_limit)
- break;
- acpi_bus_generate_proc_event(device, event,
- pr->performance_platform_limit);
- acpi_bus_generate_netlink_event(device->pnp.device_class,
- dev_name(&device->dev), event,
- pr->performance_platform_limit);
+ status = acpi_get_type(handle, &acpi_type);
+ if (ACPI_FAILURE(status))
+ return false;
+
+ switch (acpi_type) {
+ case ACPI_TYPE_PROCESSOR:
+ status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
+ if (ACPI_FAILURE(status))
+ return false;
+ acpi_id = object.processor.proc_id;
break;
- case ACPI_PROCESSOR_NOTIFY_POWER:
- acpi_processor_cst_has_changed(pr);
- acpi_bus_generate_proc_event(device, event, 0);
- acpi_bus_generate_netlink_event(device->pnp.device_class,
- dev_name(&device->dev), event, 0);
+ case ACPI_TYPE_DEVICE:
+ status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
+ if (ACPI_FAILURE(status))
+ return false;
+ acpi_id = tmp;
break;
- case ACPI_PROCESSOR_NOTIFY_THROTTLING:
- acpi_processor_tstate_has_changed(pr);
- acpi_bus_generate_proc_event(device, event, 0);
- acpi_bus_generate_netlink_event(device->pnp.device_class,
- dev_name(&device->dev), event, 0);
default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
- break;
+ return false;
}
- return;
-}
+ type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
+ cpuid = acpi_get_cpuid(handle, type, acpi_id);
-static int acpi_cpu_soft_notify(struct notifier_block *nfb,
- unsigned long action, void *hcpu)
-{
- unsigned int cpu = (unsigned long)hcpu;
- struct acpi_processor *pr = per_cpu(processors, cpu);
+ if (cpuid == -1)
+ return false;
- if (action == CPU_ONLINE && pr) {
- acpi_processor_ppc_has_changed(pr, 0);
- acpi_processor_cst_has_changed(pr);
- acpi_processor_tstate_has_changed(pr);
- }
- return NOTIFY_OK;
+ return true;
}
-static struct notifier_block acpi_cpu_notifier =
+static void acpi_set_pdc_bits(u32 *buf)
{
- .notifier_call = acpi_cpu_soft_notify,
-};
-
-static int __cpuinit acpi_processor_add(struct acpi_device *device)
-{
- struct acpi_processor *pr = NULL;
- int result = 0;
- struct sys_device *sysdev;
-
- pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
- if (!pr)
- return -ENOMEM;
-
- if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
- kfree(pr);
- return -ENOMEM;
- }
-
- pr->handle = device->handle;
- strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
- strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
- device->driver_data = pr;
-
- result = acpi_processor_get_info(device);
- if (result) {
- /* Processor is physically not present */
- return 0;
- }
-
- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
-
- /*
- * Buggy BIOS check
- * ACPI id of processors can be reported wrongly by the BIOS.
- * Don't trust it blindly
- */
- if (per_cpu(processor_device_array, pr->id) != NULL &&
- per_cpu(processor_device_array, pr->id) != device) {
- printk(KERN_WARNING "BIOS reported wrong ACPI id "
- "for the processor\n");
- result = -ENODEV;
- goto err_free_cpumask;
- }
- per_cpu(processor_device_array, pr->id) = device;
-
- per_cpu(processors, pr->id) = pr;
-
- result = acpi_processor_add_fs(device);
- if (result)
- goto err_free_cpumask;
-
- sysdev = get_cpu_sysdev(pr->id);
- if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
- result = -EFAULT;
- goto err_remove_fs;
- }
-
- /* _PDC call should be done before doing anything else (if reqd.). */
- acpi_processor_set_pdc(pr->handle);
-
-#ifdef CONFIG_CPU_FREQ
- acpi_processor_ppc_has_changed(pr, 0);
-#endif
- acpi_processor_get_throttling_info(pr);
- acpi_processor_get_limit_info(pr);
-
-
- acpi_processor_power_init(pr, device);
-
- pr->cdev = thermal_cooling_device_register("Processor", device,
- &processor_cooling_ops);
- if (IS_ERR(pr->cdev)) {
- result = PTR_ERR(pr->cdev);
- goto err_power_exit;
- }
-
- dev_dbg(&device->dev, "registered as cooling_device%d\n",
- pr->cdev->id);
-
- result = sysfs_create_link(&device->dev.kobj,
- &pr->cdev->device.kobj,
- "thermal_cooling");
- if (result) {
- printk(KERN_ERR PREFIX "Create sysfs link\n");
- goto err_thermal_unregister;
- }
- result = sysfs_create_link(&pr->cdev->device.kobj,
- &device->dev.kobj,
- "device");
- if (result) {
- printk(KERN_ERR PREFIX "Create sysfs link\n");
- goto err_remove_sysfs;
- }
+ buf[0] = ACPI_PDC_REVISION_ID;
+ buf[1] = 1;
- return 0;
-
-err_remove_sysfs:
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
-err_thermal_unregister:
- thermal_cooling_device_unregister(pr->cdev);
-err_power_exit:
- acpi_processor_power_exit(pr, device);
-err_remove_fs:
- acpi_processor_remove_fs(device);
-err_free_cpumask:
- free_cpumask_var(pr->throttling.shared_cpu_map);
+ /* Enable coordination with firmware's _TSD info */
+ buf[2] = ACPI_PDC_SMP_T_SWCOORD;
- return result;
+ /* Twiddle arch-specific bits needed for _PDC */
+ arch_acpi_set_pdc_bits(buf);
}
-static int acpi_processor_remove(struct acpi_device *device, int type)
+static struct acpi_object_list *acpi_processor_alloc_pdc(void)
{
- struct acpi_processor *pr = NULL;
-
-
- if (!device || !acpi_driver_data(device))
- return -EINVAL;
-
- pr = acpi_driver_data(device);
-
- if (pr->id >= nr_cpu_ids)
- goto free;
+ struct acpi_object_list *obj_list;
+ union acpi_object *obj;
+ u32 *buf;
- if (type == ACPI_BUS_REMOVAL_EJECT) {
- if (acpi_processor_handle_eject(pr))
- return -EINVAL;
+ /* allocate and initialize pdc. It will be used later. */
+ obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+ if (!obj_list) {
+ printk(KERN_ERR "Memory allocation error\n");
+ return NULL;
}
- acpi_processor_power_exit(pr, device);
-
- sysfs_remove_link(&device->dev.kobj, "sysdev");
-
- acpi_processor_remove_fs(device);
-
- if (pr->cdev) {
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
- sysfs_remove_link(&pr->cdev->device.kobj, "device");
- thermal_cooling_device_unregister(pr->cdev);
- pr->cdev = NULL;
+ obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+ if (!obj) {
+ printk(KERN_ERR "Memory allocation error\n");
+ kfree(obj_list);
+ return NULL;
}
- per_cpu(processors, pr->id) = NULL;
- per_cpu(processor_device_array, pr->id) = NULL;
-
-free:
- free_cpumask_var(pr->throttling.shared_cpu_map);
- kfree(pr);
-
- return 0;
-}
-
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-/****************************************************************************
- * Acpi processor hotplug support *
- ****************************************************************************/
-
-static int is_processor_present(acpi_handle handle)
-{
- acpi_status status;
- unsigned long long sta = 0;
-
-
- status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-
- if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
- return 1;
-
- /*
- * _STA is mandatory for a processor that supports hot plug
- */
- if (status == AE_NOT_FOUND)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Processor does not support hot plug\n"));
- else
- ACPI_EXCEPTION((AE_INFO, status,
- "Processor Device is not present"));
- return 0;
-}
-
-static
-int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
-{
- acpi_handle phandle;
- struct acpi_device *pdev;
-
-
- if (acpi_get_parent(handle, &phandle)) {
- return -ENODEV;
+ buf = kmalloc(12, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "Memory allocation error\n");
+ kfree(obj);
+ kfree(obj_list);
+ return NULL;
}
- if (acpi_bus_get_device(phandle, &pdev)) {
- return -ENODEV;
- }
+ acpi_set_pdc_bits(buf);
- if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
- return -ENODEV;
- }
+ obj->type = ACPI_TYPE_BUFFER;
+ obj->buffer.length = 12;
+ obj->buffer.pointer = (u8 *) buf;
+ obj_list->count = 1;
+ obj_list->pointer = obj;
- return 0;
+ return obj_list;
}
-static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
- u32 event, void *data)
+/*
+ * _PDC is required for a BIOS-OS handshake for most of the newer
+ * ACPI processor features.
+ */
+static int
+acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
{
- struct acpi_processor *pr;
- struct acpi_device *device = NULL;
- int result;
-
+ acpi_status status = AE_OK;
- switch (event) {
- case ACPI_NOTIFY_BUS_CHECK:
- case ACPI_NOTIFY_DEVICE_CHECK:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Processor driver received %s event\n",
- (event == ACPI_NOTIFY_BUS_CHECK) ?
- "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
-
- if (!is_processor_present(handle))
- break;
+ if (idle_nomwait) {
+ /*
+ * If mwait is disabled for CPU C-states, the C2C3_FFH access
+ * mode will be disabled in the parameter of _PDC object.
+ * Of course C1_FFH access mode will also be disabled.
+ */
+ union acpi_object *obj;
+ u32 *buffer = NULL;
- if (acpi_bus_get_device(handle, &device)) {
- result = acpi_processor_device_add(handle, &device);
- if (result)
- printk(KERN_ERR PREFIX
- "Unable to add the device\n");
- break;
- }
- break;
- case ACPI_NOTIFY_EJECT_REQUEST:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "received ACPI_NOTIFY_EJECT_REQUEST\n"));
+ obj = pdc_in->pointer;
+ buffer = (u32 *)(obj->buffer.pointer);
+ buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
- if (acpi_bus_get_device(handle, &device)) {
- printk(KERN_ERR PREFIX
- "Device don't exist, dropping EJECT\n");
- break;
- }
- pr = acpi_driver_data(device);
- if (!pr) {
- printk(KERN_ERR PREFIX
- "Driver data is NULL, dropping EJECT\n");
- return;
- }
- break;
- default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
- break;
}
+ status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
- return;
-}
-
-static acpi_status
-processor_walk_namespace_cb(acpi_handle handle,
- u32 lvl, void *context, void **rv)
-{
- acpi_status status;
- int *action = context;
- acpi_object_type type = 0;
-
- status = acpi_get_type(handle, &type);
if (ACPI_FAILURE(status))
- return (AE_OK);
-
- if (type != ACPI_TYPE_PROCESSOR)
- return (AE_OK);
-
- switch (*action) {
- case INSTALL_NOTIFY_HANDLER:
- acpi_install_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- acpi_processor_hotplug_notify,
- NULL);
- break;
- case UNINSTALL_NOTIFY_HANDLER:
- acpi_remove_notify_handler(handle,
- ACPI_SYSTEM_NOTIFY,
- acpi_processor_hotplug_notify);
- break;
- default:
- break;
- }
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Could not evaluate _PDC, using legacy perf. control.\n"));
- return (AE_OK);
+ return status;
}
-static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
+void acpi_processor_set_pdc(acpi_handle handle)
{
+ struct acpi_object_list *obj_list;
- if (!is_processor_present(handle)) {
- return AE_ERROR;
- }
+ if (arch_has_acpi_pdc() == false)
+ return;
- if (acpi_map_lsapic(handle, p_cpu))
- return AE_ERROR;
+ obj_list = acpi_processor_alloc_pdc();
+ if (!obj_list)
+ return;
- if (arch_register_cpu(*p_cpu)) {
- acpi_unmap_lsapic(*p_cpu);
- return AE_ERROR;
- }
+ acpi_processor_eval_pdc(handle, obj_list);
- return AE_OK;
+ kfree(obj_list->pointer->buffer.pointer);
+ kfree(obj_list->pointer);
+ kfree(obj_list);
}
+EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
+static acpi_status
+early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
{
- if (cpu_online(pr->id))
- cpu_down(pr->id);
+ if (processor_physically_present(handle) == false)
+ return AE_OK;
- arch_unregister_cpu(pr->id);
- acpi_unmap_lsapic(pr->id);
- return (0);
-}
-#else
-static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
-{
- return AE_ERROR;
-}
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
-{
- return (-EINVAL);
+ acpi_processor_set_pdc(handle);
+ return AE_OK;
}
-#endif
-static
-void acpi_processor_install_hotplug_notify(void)
+void __init acpi_early_processor_set_pdc(void)
{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
- int action = INSTALL_NOTIFY_HANDLER;
- acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
- register_hotcpu_notifier(&acpi_cpu_notifier);
-}
+ /*
+ * Check whether the system is DMI table. If yes, OSPM
+ * should not use mwait for CPU-states.
+ */
+ dmi_check_system(processor_idle_dmi_table);
-static
-void acpi_processor_uninstall_hotplug_notify(void)
-{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
- int action = UNINSTALL_NOTIFY_HANDLER;
- acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
- ACPI_ROOT_OBJECT,
+ acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX,
- processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
- unregister_hotcpu_notifier(&acpi_cpu_notifier);
+ early_init_pdc, NULL, NULL, NULL);
}
-
-/*
- * We keep the driver loaded even when ACPI is not running.
- * This is needed for the powernow-k8 driver, that works even without
- * ACPI, but needs symbols from this driver
- */
-
-static int __init acpi_processor_init(void)
-{
- int result = 0;
-
- if (acpi_disabled)
- return 0;
-
- memset(&errata, 0, sizeof(errata));
-
-#ifdef CONFIG_SMP
- if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
- (struct acpi_table_header **)&madt)))
- madt = NULL;
-#endif
-#ifdef CONFIG_ACPI_PROCFS
- acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
- if (!acpi_processor_dir)
- return -ENOMEM;
-#endif
- result = cpuidle_register_driver(&acpi_idle_driver);
- if (result < 0)
- goto out_proc;
-
- result = acpi_bus_register_driver(&acpi_processor_driver);
- if (result < 0)
- goto out_cpuidle;
-
- acpi_processor_install_hotplug_notify();
-
- acpi_thermal_cpufreq_init();
-
- acpi_processor_ppc_init();
-
- acpi_processor_throttling_init();
-
- return 0;
-
-out_cpuidle:
- cpuidle_unregister_driver(&acpi_idle_driver);
-
-out_proc:
-#ifdef CONFIG_ACPI_PROCFS
- remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-#endif
-
- return result;
-}
-
-static void __exit acpi_processor_exit(void)
-{
- if (acpi_disabled)
- return;
-
- acpi_processor_ppc_exit();
-
- acpi_thermal_cpufreq_exit();
-
- acpi_processor_uninstall_hotplug_notify();
-
- acpi_bus_unregister_driver(&acpi_processor_driver);
-
- cpuidle_unregister_driver(&acpi_idle_driver);
-
-#ifdef CONFIG_ACPI_PROCFS
- remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-#endif
-
- return;
-}
-
-module_init(acpi_processor_init);
-module_exit(acpi_processor_exit);
-
-EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
-
-MODULE_ALIAS("processor");
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
new file mode 100644
index 00000000000..5675d9747e8
--- /dev/null
+++ b/drivers/acpi/processor_driver.c
@@ -0,0 +1,979 @@
+/*
+ * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
+ *
+ * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
+ * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ * - Added processor hotplug support
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * TBD:
+ * 1. Make # power states dynamic.
+ * 2. Support duty_cycle values that span bit 4.
+ * 3. Optimize by having scheduler determine business instead of
+ * having us try to calculate it here.
+ * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/dmi.h>
+#include <linux/moduleparam.h>
+#include <linux/cpuidle.h>
+#include <linux/slab.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/cpu.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/smp.h>
+#include <asm/acpi.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/processor.h>
+
+#define PREFIX "ACPI: "
+
+#define ACPI_PROCESSOR_CLASS "processor"
+#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
+#define ACPI_PROCESSOR_FILE_INFO "info"
+#define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
+#define ACPI_PROCESSOR_FILE_LIMIT "limit"
+#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
+#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
+#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
+
+#define ACPI_PROCESSOR_LIMIT_USER 0
+#define ACPI_PROCESSOR_LIMIT_THERMAL 1
+
+#define _COMPONENT ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME("processor_driver");
+
+MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_DESCRIPTION("ACPI Processor Driver");
+MODULE_LICENSE("GPL");
+
+static int acpi_processor_add(struct acpi_device *device);
+static int acpi_processor_remove(struct acpi_device *device, int type);
+#ifdef CONFIG_ACPI_PROCFS
+static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
+#endif
+static void acpi_processor_notify(struct acpi_device *device, u32 event);
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
+static int acpi_processor_handle_eject(struct acpi_processor *pr);
+
+
+static const struct acpi_device_id processor_device_ids[] = {
+ {ACPI_PROCESSOR_OBJECT_HID, 0},
+ {"ACPI0007", 0},
+ {"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, processor_device_ids);
+
+static struct acpi_driver acpi_processor_driver = {
+ .name = "processor",
+ .class = ACPI_PROCESSOR_CLASS,
+ .ids = processor_device_ids,
+ .ops = {
+ .add = acpi_processor_add,
+ .remove = acpi_processor_remove,
+ .suspend = acpi_processor_suspend,
+ .resume = acpi_processor_resume,
+ .notify = acpi_processor_notify,
+ },
+};
+
+#define INSTALL_NOTIFY_HANDLER 1
+#define UNINSTALL_NOTIFY_HANDLER 2
+#ifdef CONFIG_ACPI_PROCFS
+static const struct file_operations acpi_processor_info_fops = {
+ .owner = THIS_MODULE,
+ .open = acpi_processor_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#endif
+
+DEFINE_PER_CPU(struct acpi_processor *, processors);
+EXPORT_PER_CPU_SYMBOL(processors);
+
+struct acpi_processor_errata errata __read_mostly;
+
+/* --------------------------------------------------------------------------
+ Errata Handling
+ -------------------------------------------------------------------------- */
+
+static int acpi_processor_errata_piix4(struct pci_dev *dev)
+{
+ u8 value1 = 0;
+ u8 value2 = 0;
+
+
+ if (!dev)
+ return -EINVAL;
+
+ /*
+ * Note that 'dev' references the PIIX4 ACPI Controller.
+ */
+
+ switch (dev->revision) {
+ case 0:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
+ break;
+ case 1:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
+ break;
+ case 2:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
+ break;
+ case 3:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
+ break;
+ default:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
+ break;
+ }
+
+ switch (dev->revision) {
+
+ case 0: /* PIIX4 A-step */
+ case 1: /* PIIX4 B-step */
+ /*
+ * See specification changes #13 ("Manual Throttle Duty Cycle")
+ * and #14 ("Enabling and Disabling Manual Throttle"), plus
+ * erratum #5 ("STPCLK# Deassertion Time") from the January
+ * 2002 PIIX4 specification update. Applies to only older
+ * PIIX4 models.
+ */
+ errata.piix4.throttle = 1;
+
+ case 2: /* PIIX4E */
+ case 3: /* PIIX4M */
+ /*
+ * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
+ * Livelock") from the January 2002 PIIX4 specification update.
+ * Applies to all PIIX4 models.
+ */
+
+ /*
+ * BM-IDE
+ * ------
+ * Find the PIIX4 IDE Controller and get the Bus Master IDE
+ * Status register address. We'll use this later to read
+ * each IDE controller's DMA status to make sure we catch all
+ * DMA activity.
+ */
+ dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB,
+ PCI_ANY_ID, PCI_ANY_ID, NULL);
+ if (dev) {
+ errata.piix4.bmisx = pci_resource_start(dev, 4);
+ pci_dev_put(dev);
+ }
+
+ /*
+ * Type-F DMA
+ * ----------
+ * Find the PIIX4 ISA Controller and read the Motherboard
+ * DMA controller's status to see if Type-F (Fast) DMA mode
+ * is enabled (bit 7) on either channel. Note that we'll
+ * disable C3 support if this is enabled, as some legacy
+ * devices won't operate well if fast DMA is disabled.
+ */
+ dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_0,
+ PCI_ANY_ID, PCI_ANY_ID, NULL);
+ if (dev) {
+ pci_read_config_byte(dev, 0x76, &value1);
+ pci_read_config_byte(dev, 0x77, &value2);
+ if ((value1 & 0x80) || (value2 & 0x80))
+ errata.piix4.fdma = 1;
+ pci_dev_put(dev);
+ }
+
+ break;
+ }
+
+ if (errata.piix4.bmisx)
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Bus master activity detection (BM-IDE) erratum enabled\n"));
+ if (errata.piix4.fdma)
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Type-F DMA livelock erratum (C3 disabled)\n"));
+
+ return 0;
+}
+
+static int acpi_processor_errata(struct acpi_processor *pr)
+{
+ int result = 0;
+ struct pci_dev *dev = NULL;
+
+
+ if (!pr)
+ return -EINVAL;
+
+ /*
+ * PIIX4
+ */
+ dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
+ PCI_ANY_ID, NULL);
+ if (dev) {
+ result = acpi_processor_errata_piix4(dev);
+ pci_dev_put(dev);
+ }
+
+ return result;
+}
+
+/* --------------------------------------------------------------------------
+ FS Interface (/proc)
+ -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_PROCFS
+static struct proc_dir_entry *acpi_processor_dir = NULL;
+
+static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
+{
+ struct acpi_processor *pr = seq->private;
+
+
+ if (!pr)
+ goto end;
+
+ seq_printf(seq, "processor id: %d\n"
+ "acpi id: %d\n"
+ "bus mastering control: %s\n"
+ "power management: %s\n"
+ "throttling control: %s\n"
+ "limit interface: %s\n",
+ pr->id,
+ pr->acpi_id,
+ pr->flags.bm_control ? "yes" : "no",
+ pr->flags.power ? "yes" : "no",
+ pr->flags.throttling ? "yes" : "no",
+ pr->flags.limit ? "yes" : "no");
+
+ end:
+ return 0;
+}
+
+static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
+{
+ return single_open(file, acpi_processor_info_seq_show,
+ PDE(inode)->data);
+}
+
+static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
+{
+ struct proc_dir_entry *entry = NULL;
+
+
+ if (!acpi_device_dir(device)) {
+ acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
+ acpi_processor_dir);
+ if (!acpi_device_dir(device))
+ return -ENODEV;
+ }
+
+ /* 'info' [R] */
+ entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
+ S_IRUGO, acpi_device_dir(device),
+ &acpi_processor_info_fops,
+ acpi_driver_data(device));
+ if (!entry)
+ return -EIO;
+
+ /* 'throttling' [R/W] */
+ entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device),
+ &acpi_processor_throttling_fops,
+ acpi_driver_data(device));
+ if (!entry)
+ return -EIO;
+
+ /* 'limit' [R/W] */
+ entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT,
+ S_IFREG | S_IRUGO | S_IWUSR,
+ acpi_device_dir(device),
+ &acpi_processor_limit_fops,
+ acpi_driver_data(device));
+ if (!entry)
+ return -EIO;
+ return 0;
+}
+static int acpi_processor_remove_fs(struct acpi_device *device)
+{
+
+ if (acpi_device_dir(device)) {
+ remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
+ acpi_device_dir(device));
+ remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
+ acpi_device_dir(device));
+ remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
+ acpi_device_dir(device));
+ remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
+ acpi_device_dir(device) = NULL;
+ }
+
+ return 0;
+}
+#else
+static inline int acpi_processor_add_fs(struct acpi_device *device)
+{
+ return 0;
+}
+static inline int acpi_processor_remove_fs(struct acpi_device *device)
+{
+ return 0;
+}
+#endif
+
+/* --------------------------------------------------------------------------
+ Driver Interface
+ -------------------------------------------------------------------------- */
+
+static int acpi_processor_get_info(struct acpi_device *device)
+{
+ acpi_status status = 0;
+ union acpi_object object = { 0 };
+ struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
+ struct acpi_processor *pr;
+ int cpu_index, device_declaration = 0;
+ static int cpu0_initialized;
+
+ pr = acpi_driver_data(device);
+ if (!pr)
+ return -EINVAL;
+
+ if (num_online_cpus() > 1)
+ errata.smp = TRUE;
+
+ acpi_processor_errata(pr);
+
+ /*
+ * Check to see if we have bus mastering arbitration control. This
+ * is required for proper C3 usage (to maintain cache coherency).
+ */
+ if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
+ pr->flags.bm_control = 1;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Bus mastering arbitration control present\n"));
+ } else
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "No bus mastering arbitration control\n"));
+
+ if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
+ /* Declared with "Processor" statement; match ProcessorID */
+ status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "Evaluating processor object\n");
+ return -ENODEV;
+ }
+
+ /*
+ * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
+ * >>> 'acpi_get_processor_id(acpi_id, &id)' in
+ * arch/xxx/acpi.c
+ */
+ pr->acpi_id = object.processor.proc_id;
+ } else {
+ /*
+ * Declared with "Device" statement; match _UID.
+ * Note that we don't handle string _UIDs yet.
+ */
+ unsigned long long value;
+ status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
+ NULL, &value);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX
+ "Evaluating processor _UID [%#x]\n", status);
+ return -ENODEV;
+ }
+ device_declaration = 1;
+ pr->acpi_id = value;
+ }
+ cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id);
+
+ /* Handle UP system running SMP kernel, with no LAPIC in MADT */
+ if (!cpu0_initialized && (cpu_index == -1) &&
+ (num_online_cpus() == 1)) {
+ cpu_index = 0;
+ }
+
+ cpu0_initialized = 1;
+
+ pr->id = cpu_index;
+
+ /*
+ * Extra Processor objects may be enumerated on MP systems with
+ * less than the max # of CPUs. They should be ignored _iff
+ * they are physically not present.
+ */
+ if (pr->id == -1) {
+ if (ACPI_FAILURE
+ (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
+ return -ENODEV;
+ }
+ }
+ /*
+ * On some boxes several processors use the same processor bus id.
+ * But they are located in different scope. For example:
+ * \_SB.SCK0.CPU0
+ * \_SB.SCK1.CPU0
+ * Rename the processor device bus id. And the new bus id will be
+ * generated as the following format:
+ * CPU+CPU ID.
+ */
+ sprintf(acpi_device_bid(device), "CPU%X", pr->id);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
+ pr->acpi_id));
+
+ if (!object.processor.pblk_address)
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
+ else if (object.processor.pblk_length != 6)
+ printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
+ object.processor.pblk_length);
+ else {
+ pr->throttling.address = object.processor.pblk_address;
+ pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
+ pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
+
+ pr->pblk = object.processor.pblk_address;
+
+ /*
+ * We don't care about error returns - we just try to mark
+ * these reserved so that nobody else is confused into thinking
+ * that this region might be unused..
+ *
+ * (In particular, allocating the IO range for Cardbus)
+ */
+ request_region(pr->throttling.address, 6, "ACPI CPU throttle");
+ }
+
+ /*
+ * If ACPI describes a slot number for this CPU, we can use it
+ * ensure we get the right value in the "physical id" field
+ * of /proc/cpuinfo
+ */
+ status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
+ if (ACPI_SUCCESS(status))
+ arch_fix_phys_package_id(pr->id, object.integer.value);
+
+ return 0;
+}
+
+static DEFINE_PER_CPU(void *, processor_device_array);
+
+static void acpi_processor_notify(struct acpi_device *device, u32 event)
+{
+ struct acpi_processor *pr = acpi_driver_data(device);
+ int saved;
+
+ if (!pr)
+ return;
+
+ switch (event) {
+ case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
+ saved = pr->performance_platform_limit;
+ acpi_processor_ppc_has_changed(pr, 1);
+ if (saved == pr->performance_platform_limit)
+ break;
+ acpi_bus_generate_proc_event(device, event,
+ pr->performance_platform_limit);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ dev_name(&device->dev), event,
+ pr->performance_platform_limit);
+ break;
+ case ACPI_PROCESSOR_NOTIFY_POWER:
+ acpi_processor_cst_has_changed(pr);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ dev_name(&device->dev), event, 0);
+ break;
+ case ACPI_PROCESSOR_NOTIFY_THROTTLING:
+ acpi_processor_tstate_has_changed(pr);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ dev_name(&device->dev), event, 0);
+ default:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Unsupported event [0x%x]\n", event));
+ break;
+ }
+
+ return;
+}
+
+static int acpi_cpu_soft_notify(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+ struct acpi_processor *pr = per_cpu(processors, cpu);
+
+ if (action == CPU_ONLINE && pr) {
+ acpi_processor_ppc_has_changed(pr, 0);
+ acpi_processor_cst_has_changed(pr);
+ acpi_processor_tstate_has_changed(pr);
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block acpi_cpu_notifier =
+{
+ .notifier_call = acpi_cpu_soft_notify,
+};
+
+static int __cpuinit acpi_processor_add(struct acpi_device *device)
+{
+ struct acpi_processor *pr = NULL;
+ int result = 0;
+ struct sys_device *sysdev;
+
+ pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
+ if (!pr)
+ return -ENOMEM;
+
+ if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
+ kfree(pr);
+ return -ENOMEM;
+ }
+
+ pr->handle = device->handle;
+ strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
+ strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
+ device->driver_data = pr;
+
+ result = acpi_processor_get_info(device);
+ if (result) {
+ /* Processor is physically not present */
+ return 0;
+ }
+
+ BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+
+ /*
+ * Buggy BIOS check
+ * ACPI id of processors can be reported wrongly by the BIOS.
+ * Don't trust it blindly
+ */
+ if (per_cpu(processor_device_array, pr->id) != NULL &&
+ per_cpu(processor_device_array, pr->id) != device) {
+ printk(KERN_WARNING "BIOS reported wrong ACPI id "
+ "for the processor\n");
+ result = -ENODEV;
+ goto err_free_cpumask;
+ }
+ per_cpu(processor_device_array, pr->id) = device;
+
+ per_cpu(processors, pr->id) = pr;
+
+ result = acpi_processor_add_fs(device);
+ if (result)
+ goto err_free_cpumask;
+
+ sysdev = get_cpu_sysdev(pr->id);
+ if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
+ result = -EFAULT;
+ goto err_remove_fs;
+ }
+
+#ifdef CONFIG_CPU_FREQ
+ acpi_processor_ppc_has_changed(pr, 0);
+#endif
+ acpi_processor_get_throttling_info(pr);
+ acpi_processor_get_limit_info(pr);
+
+
+ acpi_processor_power_init(pr, device);
+
+ pr->cdev = thermal_cooling_device_register("Processor", device,
+ &processor_cooling_ops);
+ if (IS_ERR(pr->cdev)) {
+ result = PTR_ERR(pr->cdev);
+ goto err_power_exit;
+ }
+
+ dev_dbg(&device->dev, "registered as cooling_device%d\n",
+ pr->cdev->id);
+
+ result = sysfs_create_link(&device->dev.kobj,
+ &pr->cdev->device.kobj,
+ "thermal_cooling");
+ if (result) {
+ printk(KERN_ERR PREFIX "Create sysfs link\n");
+ goto err_thermal_unregister;
+ }
+ result = sysfs_create_link(&pr->cdev->device.kobj,
+ &device->dev.kobj,
+ "device");
+ if (result) {
+ printk(KERN_ERR PREFIX "Create sysfs link\n");
+ goto err_remove_sysfs;
+ }
+
+ return 0;
+
+err_remove_sysfs:
+ sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+err_thermal_unregister:
+ thermal_cooling_device_unregister(pr->cdev);
+err_power_exit:
+ acpi_processor_power_exit(pr, device);
+err_remove_fs:
+ acpi_processor_remove_fs(device);
+err_free_cpumask:
+ free_cpumask_var(pr->throttling.shared_cpu_map);
+
+ return result;
+}
+
+static int acpi_processor_remove(struct acpi_device *device, int type)
+{
+ struct acpi_processor *pr = NULL;
+
+
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+
+ pr = acpi_driver_data(device);
+
+ if (pr->id >= nr_cpu_ids)
+ goto free;
+
+ if (type == ACPI_BUS_REMOVAL_EJECT) {
+ if (acpi_processor_handle_eject(pr))
+ return -EINVAL;
+ }
+
+ acpi_processor_power_exit(pr, device);
+
+ sysfs_remove_link(&device->dev.kobj, "sysdev");
+
+ acpi_processor_remove_fs(device);
+
+ if (pr->cdev) {
+ sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+ sysfs_remove_link(&pr->cdev->device.kobj, "device");
+ thermal_cooling_device_unregister(pr->cdev);
+ pr->cdev = NULL;
+ }
+
+ per_cpu(processors, pr->id) = NULL;
+ per_cpu(processor_device_array, pr->id) = NULL;
+
+free:
+ free_cpumask_var(pr->throttling.shared_cpu_map);
+ kfree(pr);
+
+ return 0;
+}
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+/****************************************************************************
+ * Acpi processor hotplug support *
+ ****************************************************************************/
+
+static int is_processor_present(acpi_handle handle)
+{
+ acpi_status status;
+ unsigned long long sta = 0;
+
+
+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+
+ if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
+ return 1;
+
+ /*
+ * _STA is mandatory for a processor that supports hot plug
+ */
+ if (status == AE_NOT_FOUND)
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Processor does not support hot plug\n"));
+ else
+ ACPI_EXCEPTION((AE_INFO, status,
+ "Processor Device is not present"));
+ return 0;
+}
+
+static
+int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
+{
+ acpi_handle phandle;
+ struct acpi_device *pdev;
+
+
+ if (acpi_get_parent(handle, &phandle)) {
+ return -ENODEV;
+ }
+
+ if (acpi_bus_get_device(phandle, &pdev)) {
+ return -ENODEV;
+ }
+
+ if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
+ u32 event, void *data)
+{
+ struct acpi_processor *pr;
+ struct acpi_device *device = NULL;
+ int result;
+
+
+ switch (event) {
+ case ACPI_NOTIFY_BUS_CHECK:
+ case ACPI_NOTIFY_DEVICE_CHECK:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Processor driver received %s event\n",
+ (event == ACPI_NOTIFY_BUS_CHECK) ?
+ "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
+
+ if (!is_processor_present(handle))
+ break;
+
+ if (acpi_bus_get_device(handle, &device)) {
+ result = acpi_processor_device_add(handle, &device);
+ if (result)
+ printk(KERN_ERR PREFIX
+ "Unable to add the device\n");
+ break;
+ }
+ break;
+ case ACPI_NOTIFY_EJECT_REQUEST:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "received ACPI_NOTIFY_EJECT_REQUEST\n"));
+
+ if (acpi_bus_get_device(handle, &device)) {
+ printk(KERN_ERR PREFIX
+ "Device don't exist, dropping EJECT\n");
+ break;
+ }
+ pr = acpi_driver_data(device);
+ if (!pr) {
+ printk(KERN_ERR PREFIX
+ "Driver data is NULL, dropping EJECT\n");
+ return;
+ }
+ break;
+ default:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Unsupported event [0x%x]\n", event));
+ break;
+ }
+
+ return;
+}
+
+static acpi_status
+processor_walk_namespace_cb(acpi_handle handle,
+ u32 lvl, void *context, void **rv)
+{
+ acpi_status status;
+ int *action = context;
+ acpi_object_type type = 0;
+
+ status = acpi_get_type(handle, &type);
+ if (ACPI_FAILURE(status))
+ return (AE_OK);
+
+ if (type != ACPI_TYPE_PROCESSOR)
+ return (AE_OK);
+
+ switch (*action) {
+ case INSTALL_NOTIFY_HANDLER:
+ acpi_install_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ acpi_processor_hotplug_notify,
+ NULL);
+ break;
+ case UNINSTALL_NOTIFY_HANDLER:
+ acpi_remove_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ acpi_processor_hotplug_notify);
+ break;
+ default:
+ break;
+ }
+
+ return (AE_OK);
+}
+
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
+{
+
+ if (!is_processor_present(handle)) {
+ return AE_ERROR;
+ }
+
+ if (acpi_map_lsapic(handle, p_cpu))
+ return AE_ERROR;
+
+ if (arch_register_cpu(*p_cpu)) {
+ acpi_unmap_lsapic(*p_cpu);
+ return AE_ERROR;
+ }
+
+ return AE_OK;
+}
+
+static int acpi_processor_handle_eject(struct acpi_processor *pr)
+{
+ if (cpu_online(pr->id))
+ cpu_down(pr->id);
+
+ arch_unregister_cpu(pr->id);
+ acpi_unmap_lsapic(pr->id);
+ return (0);
+}
+#else
+static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
+{
+ return AE_ERROR;
+}
+static int acpi_processor_handle_eject(struct acpi_processor *pr)
+{
+ return (-EINVAL);
+}
+#endif
+
+static
+void acpi_processor_install_hotplug_notify(void)
+{
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+ int action = INSTALL_NOTIFY_HANDLER;
+ acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+ ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ processor_walk_namespace_cb, NULL, &action, NULL);
+#endif
+ register_hotcpu_notifier(&acpi_cpu_notifier);
+}
+
+static
+void acpi_processor_uninstall_hotplug_notify(void)
+{
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+ int action = UNINSTALL_NOTIFY_HANDLER;
+ acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+ ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ processor_walk_namespace_cb, NULL, &action, NULL);
+#endif
+ unregister_hotcpu_notifier(&acpi_cpu_notifier);
+}
+
+/*
+ * We keep the driver loaded even when ACPI is not running.
+ * This is needed for the powernow-k8 driver, that works even without
+ * ACPI, but needs symbols from this driver
+ */
+
+static int __init acpi_processor_init(void)
+{
+ int result = 0;
+
+ if (acpi_disabled)
+ return 0;
+
+ memset(&errata, 0, sizeof(errata));
+
+#ifdef CONFIG_ACPI_PROCFS
+ acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+ if (!acpi_processor_dir)
+ return -ENOMEM;
+#endif
+ result = cpuidle_register_driver(&acpi_idle_driver);
+ if (result < 0)
+ goto out_proc;
+
+ result = acpi_bus_register_driver(&acpi_processor_driver);
+ if (result < 0)
+ goto out_cpuidle;
+
+ acpi_processor_install_hotplug_notify();
+
+ acpi_thermal_cpufreq_init();
+
+ acpi_processor_ppc_init();
+
+ acpi_processor_throttling_init();
+
+ return 0;
+
+out_cpuidle:
+ cpuidle_unregister_driver(&acpi_idle_driver);
+
+out_proc:
+#ifdef CONFIG_ACPI_PROCFS
+ remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+#endif
+
+ return result;
+}
+
+static void __exit acpi_processor_exit(void)
+{
+ if (acpi_disabled)
+ return;
+
+ acpi_processor_ppc_exit();
+
+ acpi_thermal_cpufreq_exit();
+
+ acpi_processor_uninstall_hotplug_notify();
+
+ acpi_bus_unregister_driver(&acpi_processor_driver);
+
+ cpuidle_unregister_driver(&acpi_idle_driver);
+
+#ifdef CONFIG_ACPI_PROCFS
+ remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+#endif
+
+ return;
+}
+
+module_init(acpi_processor_init);
+module_exit(acpi_processor_exit);
+
+EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
+
+MODULE_ALIAS("processor");
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 37dfce74939..5939e7f7d8e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
+#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/acpi.h>
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
deleted file mode 100644
index e306ba9aa34..00000000000
--- a/drivers/acpi/processor_pdc.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2005 Intel Corporation
- * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
- *
- * Alex Chiang <achiang@hp.com>
- * - Unified x86/ia64 implementations
- * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
- * - Added _PDC for platforms with Intel CPUs
- */
-#include <linux/dmi.h>
-
-#include <acpi/acpi_drivers.h>
-#include <acpi/processor.h>
-
-#include "internal.h"
-
-#define PREFIX "ACPI: "
-#define _COMPONENT ACPI_PROCESSOR_COMPONENT
-ACPI_MODULE_NAME("processor_pdc");
-
-static int set_no_mwait(const struct dmi_system_id *id)
-{
- printk(KERN_NOTICE PREFIX "%s detected - "
- "disabling mwait for CPU C-states\n", id->ident);
- idle_nomwait = 1;
- return 0;
-}
-
-static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
- {
- set_no_mwait, "IFL91 board", {
- DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
- DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
- DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
- {
- set_no_mwait, "Extensa 5220", {
- DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
- DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
- DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
- {},
-};
-
-static void acpi_set_pdc_bits(u32 *buf)
-{
- buf[0] = ACPI_PDC_REVISION_ID;
- buf[1] = 1;
-
- /* Enable coordination with firmware's _TSD info */
- buf[2] = ACPI_PDC_SMP_T_SWCOORD;
-
- /* Twiddle arch-specific bits needed for _PDC */
- arch_acpi_set_pdc_bits(buf);
-}
-
-static struct acpi_object_list *acpi_processor_alloc_pdc(void)
-{
- struct acpi_object_list *obj_list;
- union acpi_object *obj;
- u32 *buf;
-
- /* allocate and initialize pdc. It will be used later. */
- obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
- if (!obj_list) {
- printk(KERN_ERR "Memory allocation error\n");
- return NULL;
- }
-
- obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
- if (!obj) {
- printk(KERN_ERR "Memory allocation error\n");
- kfree(obj_list);
- return NULL;
- }
-
- buf = kmalloc(12, GFP_KERNEL);
- if (!buf) {
- printk(KERN_ERR "Memory allocation error\n");
- kfree(obj);
- kfree(obj_list);
- return NULL;
- }
-
- acpi_set_pdc_bits(buf);
-
- obj->type = ACPI_TYPE_BUFFER;
- obj->buffer.length = 12;
- obj->buffer.pointer = (u8 *) buf;
- obj_list->count = 1;
- obj_list->pointer = obj;
-
- return obj_list;
-}
-
-/*
- * _PDC is required for a BIOS-OS handshake for most of the newer
- * ACPI processor features.
- */
-static int
-acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
-{
- acpi_status status = AE_OK;
-
- if (idle_nomwait) {
- /*
- * If mwait is disabled for CPU C-states, the C2C3_FFH access
- * mode will be disabled in the parameter of _PDC object.
- * Of course C1_FFH access mode will also be disabled.
- */
- union acpi_object *obj;
- u32 *buffer = NULL;
-
- obj = pdc_in->pointer;
- buffer = (u32 *)(obj->buffer.pointer);
- buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
-
- }
- status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
-
- if (ACPI_FAILURE(status))
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Could not evaluate _PDC, using legacy perf. control.\n"));
-
- return status;
-}
-
-static int early_pdc_done;
-
-void acpi_processor_set_pdc(acpi_handle handle)
-{
- struct acpi_object_list *obj_list;
-
- if (arch_has_acpi_pdc() == false)
- return;
-
- if (early_pdc_done)
- return;
-
- obj_list = acpi_processor_alloc_pdc();
- if (!obj_list)
- return;
-
- acpi_processor_eval_pdc(handle, obj_list);
-
- kfree(obj_list->pointer->buffer.pointer);
- kfree(obj_list->pointer);
- kfree(obj_list);
-}
-EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
-
-static int early_pdc_optin;
-static int set_early_pdc_optin(const struct dmi_system_id *id)
-{
- early_pdc_optin = 1;
- return 0;
-}
-
-static int param_early_pdc_optin(char *s)
-{
- early_pdc_optin = 1;
- return 1;
-}
-__setup("acpi_early_pdc_eval", param_early_pdc_optin);
-
-static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = {
- {
- set_early_pdc_optin, "HP Envy", {
- DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
- DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL},
- {
- set_early_pdc_optin, "HP Pavilion dv6", {
- DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
- DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL},
- {
- set_early_pdc_optin, "HP Pavilion dv7", {
- DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
- DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL},
- {},
-};
-
-static acpi_status
-early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- acpi_processor_set_pdc(handle);
- return AE_OK;
-}
-
-void __init acpi_early_processor_set_pdc(void)
-{
- /*
- * Check whether the system is DMI table. If yes, OSPM
- * should not use mwait for CPU-states.
- */
- dmi_check_system(processor_idle_dmi_table);
-
- /*
- * Allow systems to opt-in to early _PDC evaluation.
- */
- dmi_check_system(early_pdc_optin_table);
- if (!early_pdc_optin)
- return;
-
- acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- early_init_pdc, NULL, NULL, NULL);
-
- early_pdc_done = 1;
-}
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index d648a9860b8..ba1bd263d90 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
+#include <linux/slab.h>
#ifdef CONFIG_X86
#include <asm/cpufeature.h>
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 7ded7542fc9..9ade1a5b32e 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/cpufreq.h>
@@ -1133,9 +1134,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
int result = 0;
struct acpi_processor_throttling *pthrottling;
- if (!pr)
- return -EINVAL;
-
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
pr->throttling.address,
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index b16ddbf23a9..4ff76e8174e 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -25,6 +25,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -217,6 +218,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = acpi_battery_technology(battery);
break;
+ case POWER_SUPPLY_PROP_CYCLE_COUNT:
+ val->intval = battery->cycle_count;
+ break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
val->intval = battery->design_voltage *
acpi_battery_vscale(battery) * 1000;
@@ -276,6 +280,7 @@ static enum power_supply_property sbs_charge_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -560,6 +565,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
battery->design_voltage * acpi_battery_vscale(battery));
seq_printf(seq, "design capacity warning: unknown\n");
seq_printf(seq, "design capacity low: unknown\n");
+ seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
seq_printf(seq, "capacity granularity 1: unknown\n");
seq_printf(seq, "capacity granularity 2: unknown\n");
seq_printf(seq, "model number: %s\n", battery->device_name);
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index fd09229282e..36704b887cc 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -11,6 +11,7 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include "sbshc.h"
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fb7fc24fe72..0338f513a01 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -4,10 +4,12 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/signal.h>
#include <linux/kthread.h>
+#include <linux/dmi.h>
#include <acpi/acpi_drivers.h>
@@ -1032,6 +1034,41 @@ static void acpi_add_id(struct acpi_device *device, const char *dev_id)
list_add_tail(&id->list, &device->pnp.ids);
}
+/*
+ * Old IBM workstations have a DSDT bug wherein the SMBus object
+ * lacks the SMBUS01 HID and the methods do not have the necessary "_"
+ * prefix. Work around this.
+ */
+static int acpi_ibm_smbus_match(struct acpi_device *device)
+{
+ acpi_handle h_dummy;
+ struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+ int result;
+
+ if (!dmi_name_in_vendors("IBM"))
+ return -ENODEV;
+
+ /* Look for SMBS object */
+ result = acpi_get_name(device->handle, ACPI_SINGLE_NAME, &path);
+ if (result)
+ return result;
+
+ if (strcmp("SMBS", path.pointer)) {
+ result = -ENODEV;
+ goto out;
+ }
+
+ /* Does it have the necessary (but misnamed) methods? */
+ result = -ENODEV;
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "SBI", &h_dummy)) &&
+ ACPI_SUCCESS(acpi_get_handle(device->handle, "SBR", &h_dummy)) &&
+ ACPI_SUCCESS(acpi_get_handle(device->handle, "SBW", &h_dummy)))
+ result = 0;
+out:
+ kfree(path.pointer);
+ return result;
+}
+
static void acpi_device_set_id(struct acpi_device *device)
{
acpi_status status;
@@ -1044,12 +1081,6 @@ static void acpi_device_set_id(struct acpi_device *device)
if (ACPI_IS_ROOT_DEVICE(device)) {
acpi_add_id(device, ACPI_SYSTEM_HID);
break;
- } else if (ACPI_IS_ROOT_DEVICE(device->parent)) {
- /* \_SB_, the only root-level namespace device */
- acpi_add_id(device, ACPI_BUS_HID);
- strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
- strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
- break;
}
status = acpi_get_object_info(device->handle, &info);
@@ -1082,6 +1113,14 @@ static void acpi_device_set_id(struct acpi_device *device)
acpi_add_id(device, ACPI_BAY_HID);
else if (ACPI_SUCCESS(acpi_dock_match(device)))
acpi_add_id(device, ACPI_DOCK_HID);
+ else if (!acpi_ibm_smbus_match(device))
+ acpi_add_id(device, ACPI_SMBUS_IBM_HID);
+ else if (!acpi_device_hid(device) &&
+ ACPI_IS_ROOT_DEVICE(device->parent)) {
+ acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
+ strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
+ strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
+ }
break;
case ACPI_BUS_TYPE_POWER:
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 3bde594a997..f74834a544f 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -552,8 +552,17 @@ static void acpi_hibernation_leave(void)
hibernate_nvs_restore();
}
-static void acpi_pm_enable_gpes(void)
+static int acpi_pm_pre_restore(void)
{
+ acpi_disable_all_gpes();
+ acpi_os_wait_events_complete(NULL);
+ acpi_ec_suspend_transactions();
+ return 0;
+}
+
+static void acpi_pm_restore_cleanup(void)
+{
+ acpi_ec_resume_transactions();
acpi_enable_all_runtime_gpes();
}
@@ -565,8 +574,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
.prepare = acpi_pm_prepare,
.enter = acpi_hibernation_enter,
.leave = acpi_hibernation_leave,
- .pre_restore = acpi_pm_disable_gpes,
- .restore_cleanup = acpi_pm_enable_gpes,
+ .pre_restore = acpi_pm_pre_restore,
+ .restore_cleanup = acpi_pm_restore_cleanup,
};
/**
@@ -618,8 +627,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
.prepare = acpi_pm_disable_gpes,
.enter = acpi_hibernation_enter,
.leave = acpi_hibernation_leave,
- .pre_restore = acpi_pm_disable_gpes,
- .restore_cleanup = acpi_pm_enable_gpes,
+ .pre_restore = acpi_pm_pre_restore,
+ .restore_cleanup = acpi_pm_restore_cleanup,
.recover = acpi_pm_finish,
};
#endif /* CONFIG_HIBERNATION */
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index a206a12da78..4aaf2497613 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -25,6 +25,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/string.h>
#include <asm/uaccess.h>
@@ -101,6 +102,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
struct acpi_table_header *header = NULL;
struct acpi_table_attr *attr = NULL;
+ sysfs_attr_init(&table_attr->attr.attr);
if (table_header->signature[0] != '\0')
memcpy(table_attr->name, table_header->signature,
ACPI_NAME_SIZE);
@@ -475,6 +477,7 @@ void acpi_irq_stats_init(void)
goto fail;
strncpy(name, buffer, strlen(buffer) + 1);
+ sysfs_attr_init(&counter_attrs[i].attr);
counter_attrs[i].attr.name = name;
counter_attrs[i].attr.mode = 0644;
counter_attrs[i].show = counter_show;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 9073ada8883..efad1f33aeb 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/dmi.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/jiffies.h>
@@ -368,7 +369,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
int valid = 0;
int i;
- /* Critical Shutdown (required) */
+ /* Critical Shutdown */
if (flag & ACPI_TRIPS_CRITICAL) {
status = acpi_evaluate_integer(tz->device->handle,
"_CRT", NULL, &tmp);
@@ -379,17 +380,19 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
* Below zero (Celsius) values clearly aren't right for sure..
* ... so lets discard those as invalid.
*/
- if (ACPI_FAILURE(status) ||
- tz->trips.critical.temperature <= 2732) {
+ if (ACPI_FAILURE(status)) {
+ tz->trips.critical.flags.valid = 0;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "No critical threshold\n"));
+ } else if (tmp <= 2732) {
+ printk(KERN_WARNING FW_BUG "Invalid critical threshold "
+ "(%llu)\n", tmp);
tz->trips.critical.flags.valid = 0;
- ACPI_EXCEPTION((AE_INFO, status,
- "No or invalid critical threshold"));
- return -ENODEV;
} else {
tz->trips.critical.flags.valid = 1;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Found critical threshold [%lu]\n",
- tz->trips.critical.temperature));
+ "Found critical threshold [%lu]\n",
+ tz->trips.critical.temperature));
}
if (tz->trips.critical.flags.valid == 1) {
if (crt == -1) {
@@ -575,7 +578,23 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
{
- return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
+ int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
+
+ if (ret)
+ return ret;
+
+ valid = tz->trips.critical.flags.valid |
+ tz->trips.hot.flags.valid |
+ tz->trips.passive.flags.valid;
+
+ for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
+ valid |= tz->trips.active[i].flags.valid;
+
+ if (!valid) {
+ printk(KERN_WARNING FW_BUG "No valid trip found\n");
+ return -ENODEV;
+ }
+ return 0;
}
static void acpi_thermal_check(void *data)
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 11882dbe209..b002a471c5d 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <acpi/acpi_bus.h>
@@ -289,51 +290,6 @@ acpi_evaluate_integer(acpi_handle handle,
EXPORT_SYMBOL(acpi_evaluate_integer);
-#if 0
-acpi_status
-acpi_evaluate_string(acpi_handle handle,
- acpi_string pathname,
- acpi_object_list * arguments, acpi_string * data)
-{
- acpi_status status = AE_OK;
- acpi_object *element = NULL;
- acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-
-
- if (!data)
- return AE_BAD_PARAMETER;
-
- status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
- if (ACPI_FAILURE(status)) {
- acpi_util_eval_error(handle, pathname, status);
- return status;
- }
-
- element = (acpi_object *) buffer.pointer;
-
- if ((element->type != ACPI_TYPE_STRING)
- || (element->type != ACPI_TYPE_BUFFER)
- || !element->string.length) {
- acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
- return AE_BAD_DATA;
- }
-
- *data = kzalloc(element->string.length + 1, GFP_KERNEL);
- if (!data) {
- printk(KERN_ERR PREFIX "Memory allocation\n");
- return -ENOMEM;
- }
-
- memcpy(*data, element->string.pointer, element->string.length);
-
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data));
-
- kfree(buffer.pointer);
-
- return AE_OK;
-}
-#endif
-
acpi_status
acpi_evaluate_reference(acpi_handle handle,
acpi_string pathname,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 6e9b49149fc..a0c93b32148 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -39,10 +39,12 @@
#include <linux/sort.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/dmi.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
+#include <linux/suspend.h>
#define PREFIX "ACPI: "
@@ -88,7 +90,6 @@ module_param(allow_duplicates, bool, 0644);
static int register_count = 0;
static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device, int type);
-static int acpi_video_resume(struct acpi_device *device);
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id video_device_ids[] = {
@@ -104,7 +105,6 @@ static struct acpi_driver acpi_video_bus = {
.ops = {
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
- .resume = acpi_video_resume,
.notify = acpi_video_bus_notify,
},
};
@@ -159,6 +159,7 @@ struct acpi_video_bus {
struct proc_dir_entry *dir;
struct input_dev *input;
char phys[32]; /* for input device */
+ struct notifier_block pm_nb;
};
struct acpi_video_device_flags {
@@ -327,7 +328,7 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
int level);
static int acpi_video_device_lcd_get_level_current(
struct acpi_video_device *device,
- unsigned long long *level);
+ unsigned long long *level, int init);
static int acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event);
static int acpi_video_switch_brightness(struct acpi_video_device *device,
@@ -345,7 +346,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
- if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
+ if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0))
return -EINVAL;
for (i = 2; i < vd->brightness->count; i++) {
if (vd->brightness->levels[i] == cur_level)
@@ -414,7 +415,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsig
unsigned long long level;
int offset;
- if (acpi_video_device_lcd_get_level_current(video, &level))
+ if (acpi_video_device_lcd_get_level_current(video, &level, 0))
return -EINVAL;
for (offset = 2; offset < video->brightness->count; offset++)
if (level == video->brightness->levels[offset]) {
@@ -609,7 +610,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
- unsigned long long *level)
+ unsigned long long *level, int init)
{
acpi_status status = AE_OK;
int i;
@@ -633,10 +634,16 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
device->brightness->curr = *level;
return 0;
}
- /* BQC returned an invalid level. Stop using it. */
- ACPI_WARNING((AE_INFO, "%s returned an invalid level",
- buf));
- device->cap._BQC = device->cap._BCQ = 0;
+ if (!init) {
+ /*
+ * BQC returned an invalid level.
+ * Stop using it.
+ */
+ ACPI_WARNING((AE_INFO,
+ "%s returned an invalid level",
+ buf));
+ device->cap._BQC = device->cap._BCQ = 0;
+ }
} else {
/* Fixme:
* should we return an error or ignore this failure?
@@ -892,7 +899,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
if (!device->cap._BQC)
goto set_level;
- result = acpi_video_device_lcd_get_level_current(device, &level_old);
+ result = acpi_video_device_lcd_get_level_current(device, &level_old, 1);
if (result)
goto out_free_levels;
@@ -903,7 +910,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
if (result)
goto out_free_levels;
- result = acpi_video_device_lcd_get_level_current(device, &level);
+ result = acpi_video_device_lcd_get_level_current(device, &level, 0);
if (result)
goto out_free_levels;
@@ -992,6 +999,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
}
if (acpi_video_backlight_support()) {
+ struct backlight_properties props;
int result;
static int count = 0;
char *name;
@@ -1004,12 +1012,21 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
return;
sprintf(name, "acpi_video%d", count++);
- device->backlight = backlight_device_register(name,
- NULL, device, &acpi_backlight_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = device->brightness->count - 3;
+ device->backlight = backlight_device_register(name, NULL, device,
+ &acpi_backlight_ops,
+ &props);
kfree(name);
if (IS_ERR(device->backlight))
return;
- device->backlight->props.max_brightness = device->brightness->count-3;
+
+ /*
+ * Save current brightness level in case we have to restore it
+ * before acpi_video_device_lcd_set_level() is called next time.
+ */
+ device->backlight->props.brightness =
+ acpi_video_get_brightness(device->backlight);
result = sysfs_create_link(&device->backlight->dev.kobj,
&device->dev->dev.kobj, "device");
@@ -1996,7 +2013,7 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
goto out;
result = acpi_video_device_lcd_get_level_current(device,
- &level_current);
+ &level_current, 0);
if (result)
goto out;
@@ -2113,7 +2130,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
{
struct acpi_video_bus *video = acpi_driver_data(device);
struct input_dev *input;
- int keycode;
+ int keycode = 0;
if (!video)
return;
@@ -2149,17 +2166,19 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
break;
default:
- keycode = KEY_UNKNOWN;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
acpi_notifier_call_chain(device, event, 0);
- input_report_key(input, keycode, 1);
- input_sync(input);
- input_report_key(input, keycode, 0);
- input_sync(input);
+
+ if (keycode) {
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ input_sync(input);
+ }
return;
}
@@ -2170,7 +2189,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
struct acpi_device *device = NULL;
struct acpi_video_bus *bus;
struct input_dev *input;
- int keycode;
+ int keycode = 0;
if (!video_device)
return;
@@ -2211,39 +2230,48 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
keycode = KEY_DISPLAY_OFF;
break;
default:
- keycode = KEY_UNKNOWN;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
acpi_notifier_call_chain(device, event, 0);
- input_report_key(input, keycode, 1);
- input_sync(input);
- input_report_key(input, keycode, 0);
- input_sync(input);
+
+ if (keycode) {
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ input_sync(input);
+ }
return;
}
-static int instance;
-static int acpi_video_resume(struct acpi_device *device)
+static int acpi_video_resume(struct notifier_block *nb,
+ unsigned long val, void *ign)
{
struct acpi_video_bus *video;
struct acpi_video_device *video_device;
int i;
- if (!device || !acpi_driver_data(device))
- return -EINVAL;
+ switch (val) {
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ case PM_RESTORE_PREPARE:
+ return NOTIFY_DONE;
+ }
- video = acpi_driver_data(device);
+ video = container_of(nb, struct acpi_video_bus, pm_nb);
+
+ dev_info(&video->device->dev, "Restoring backlight state\n");
for (i = 0; i < video->attached_count; i++) {
video_device = video->attached_array[i].bind_info;
if (video_device && video_device->backlight)
acpi_video_set_brightness(video_device->backlight);
}
- return AE_OK;
+
+ return NOTIFY_OK;
}
static acpi_status
@@ -2267,6 +2295,8 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
return AE_OK;
}
+static int instance;
+
static int acpi_video_bus_add(struct acpi_device *device)
{
struct acpi_video_bus *video;
@@ -2348,7 +2378,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
set_bit(KEY_DISPLAY_OFF, input->keybit);
- set_bit(KEY_UNKNOWN, input->keybit);
error = input_register_device(input);
if (error)
@@ -2360,6 +2389,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
video->flags.rom ? "yes" : "no",
video->flags.post ? "yes" : "no");
+ video->pm_nb.notifier_call = acpi_video_resume;
+ video->pm_nb.priority = 0;
+ register_pm_notifier(&video->pm_nb);
+
return 0;
err_free_input_dev:
@@ -2386,6 +2419,8 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
video = acpi_driver_data(device);
+ unregister_pm_notifier(&video->pm_nb);
+
acpi_video_bus_stop_devices(video);
acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 6bd930b93bc..5326af28a41 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -42,6 +42,7 @@
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/dmi.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
@@ -641,6 +642,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_yesncq }, /* Linux ID */
+ { PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_yesncq }, /* Linux ID */
{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */
{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */
{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */
@@ -2263,7 +2279,7 @@ static void ahci_port_intr(struct ata_port *ap)
struct ahci_port_priv *pp = ap->private_data;
struct ahci_host_priv *hpriv = ap->host->private_data;
int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
- u32 status, qc_active;
+ u32 status, qc_active = 0;
int rc;
status = readl(port_mmio + PORT_IRQ_STAT);
@@ -2321,11 +2337,22 @@ static void ahci_port_intr(struct ata_port *ap)
}
}
- /* pp->active_link is valid iff any command is in flight */
- if (ap->qc_active && pp->active_link->sactive)
- qc_active = readl(port_mmio + PORT_SCR_ACT);
- else
- qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+ /* pp->active_link is not reliable once FBS is enabled, both
+ * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because
+ * NCQ and non-NCQ commands may be in flight at the same time.
+ */
+ if (pp->fbs_enabled) {
+ if (ap->qc_active) {
+ qc_active = readl(port_mmio + PORT_SCR_ACT);
+ qc_active |= readl(port_mmio + PORT_CMD_ISSUE);
+ }
+ } else {
+ /* pp->active_link is valid iff any command is in flight */
+ if (ap->qc_active && pp->active_link->sactive)
+ qc_active = readl(port_mmio + PORT_SCR_ACT);
+ else
+ qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+ }
rc = ata_qc_complete_multiple(ap, qc_active);
@@ -3022,6 +3049,14 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
* On HP dv[4-6] and HDX18 with earlier BIOSen, link
* to the harddisk doesn't become online after
* resuming from STR. Warn and fail suspend.
+ *
+ * http://bugzilla.kernel.org/show_bug.cgi?id=12276
+ *
+ * Use dates instead of versions to match as HP is
+ * apparently recycling both product and version
+ * strings.
+ *
+ * http://bugzilla.kernel.org/show_bug.cgi?id=15462
*/
{
.ident = "dv4",
@@ -3030,7 +3065,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
DMI_MATCH(DMI_PRODUCT_NAME,
"HP Pavilion dv4 Notebook PC"),
},
- .driver_data = "F.30", /* cutoff BIOS version */
+ .driver_data = "20090105", /* F.30 */
},
{
.ident = "dv5",
@@ -3039,7 +3074,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
DMI_MATCH(DMI_PRODUCT_NAME,
"HP Pavilion dv5 Notebook PC"),
},
- .driver_data = "F.16", /* cutoff BIOS version */
+ .driver_data = "20090506", /* F.16 */
},
{
.ident = "dv6",
@@ -3048,7 +3083,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
DMI_MATCH(DMI_PRODUCT_NAME,
"HP Pavilion dv6 Notebook PC"),
},
- .driver_data = "F.21", /* cutoff BIOS version */
+ .driver_data = "20090423", /* F.21 */
},
{
.ident = "HDX18",
@@ -3057,7 +3092,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
DMI_MATCH(DMI_PRODUCT_NAME,
"HP HDX18 Notebook PC"),
},
- .driver_data = "F.23", /* cutoff BIOS version */
+ .driver_data = "20090430", /* F.23 */
},
/*
* Acer eMachines G725 has the same problem. BIOS
@@ -3065,6 +3100,8 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
* work. Inbetween, there are V1.06, V2.06 and V3.03
* that we don't have much idea about. For now,
* blacklist anything older than V3.04.
+ *
+ * http://bugzilla.kernel.org/show_bug.cgi?id=15104
*/
{
.ident = "G725",
@@ -3072,19 +3109,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
DMI_MATCH(DMI_SYS_VENDOR, "eMachines"),
DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"),
},
- .driver_data = "V3.04", /* cutoff BIOS version */
+ .driver_data = "20091216", /* V3.04 */
},
{ } /* terminate list */
};
const struct dmi_system_id *dmi = dmi_first_match(sysids);
- const char *ver;
+ int year, month, date;
+ char buf[9];
if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2))
return false;
- ver = dmi_get_system_info(DMI_BIOS_VERSION);
+ dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
- return !ver || strcmp(ver, dmi->driver_data) < 0;
+ return strcmp(buf, dmi->driver_data) < 0;
}
static bool ahci_broken_online(struct pci_dev *pdev)
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index c33806654e4..83bc49fac9b 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -90,6 +90,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/dmi.h>
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 292fdbc0431..7b5eea7e01d 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -15,6 +15,7 @@
#include <linux/acpi.h>
#include <linux/libata.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <scsi/scsi_device.h>
#include "libata.h"
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 9c77b0d1a9d..49cffb6094a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -58,6 +58,7 @@
#include <linux/io.h>
#include <linux/async.h>
#include <linux/log2.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
@@ -1493,6 +1494,7 @@ static int ata_hpa_resize(struct ata_device *dev)
{
struct ata_eh_context *ehc = &dev->link->eh_context;
int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
+ bool unlock_hpa = ata_ignore_hpa || dev->flags & ATA_DFLAG_UNLOCK_HPA;
u64 sectors = ata_id_n_sectors(dev->id);
u64 native_sectors;
int rc;
@@ -1509,7 +1511,7 @@ static int ata_hpa_resize(struct ata_device *dev)
/* If device aborted the command or HPA isn't going to
* be unlocked, skip HPA resizing.
*/
- if (rc == -EACCES || !ata_ignore_hpa) {
+ if (rc == -EACCES || !unlock_hpa) {
ata_dev_printk(dev, KERN_WARNING, "HPA support seems "
"broken, skipping HPA handling\n");
dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
@@ -1524,7 +1526,7 @@ static int ata_hpa_resize(struct ata_device *dev)
dev->n_native_sectors = native_sectors;
/* nothing to do? */
- if (native_sectors <= sectors || !ata_ignore_hpa) {
+ if (native_sectors <= sectors || !unlock_hpa) {
if (!print_info || native_sectors == sectors)
return 0;
@@ -2232,7 +2234,7 @@ retry:
* Some drives were very specific about that exact sequence.
*
* Note that ATA4 says lba is mandatory so the second check
- * shoud never trigger.
+ * should never trigger.
*/
if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
err_mask = ata_dev_init_params(dev, id[3], id[6]);
@@ -4185,36 +4187,51 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
goto fail;
/* verify n_sectors hasn't changed */
- if (dev->class == ATA_DEV_ATA && n_sectors &&
- dev->n_sectors != n_sectors) {
- ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch "
- "%llu != %llu\n",
- (unsigned long long)n_sectors,
- (unsigned long long)dev->n_sectors);
- /*
- * Something could have caused HPA to be unlocked
- * involuntarily. If n_native_sectors hasn't changed
- * and the new size matches it, keep the device.
- */
- if (dev->n_native_sectors == n_native_sectors &&
- dev->n_sectors > n_sectors &&
- dev->n_sectors == n_native_sectors) {
- ata_dev_printk(dev, KERN_WARNING,
- "new n_sectors matches native, probably "
- "late HPA unlock, continuing\n");
- /* keep using the old n_sectors */
- dev->n_sectors = n_sectors;
- } else {
- /* restore original n_[native]_sectors and fail */
- dev->n_native_sectors = n_native_sectors;
- dev->n_sectors = n_sectors;
- rc = -ENODEV;
- goto fail;
- }
+ if (dev->class != ATA_DEV_ATA || !n_sectors ||
+ dev->n_sectors == n_sectors)
+ return 0;
+
+ /* n_sectors has changed */
+ ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch %llu != %llu\n",
+ (unsigned long long)n_sectors,
+ (unsigned long long)dev->n_sectors);
+
+ /*
+ * Something could have caused HPA to be unlocked
+ * involuntarily. If n_native_sectors hasn't changed and the
+ * new size matches it, keep the device.
+ */
+ if (dev->n_native_sectors == n_native_sectors &&
+ dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) {
+ ata_dev_printk(dev, KERN_WARNING,
+ "new n_sectors matches native, probably "
+ "late HPA unlock, continuing\n");
+ /* keep using the old n_sectors */
+ dev->n_sectors = n_sectors;
+ return 0;
}
- return 0;
+ /*
+ * Some BIOSes boot w/o HPA but resume w/ HPA locked. Try
+ * unlocking HPA in those cases.
+ *
+ * https://bugzilla.kernel.org/show_bug.cgi?id=15396
+ */
+ if (dev->n_native_sectors == n_native_sectors &&
+ dev->n_sectors < n_sectors && n_sectors == n_native_sectors &&
+ !(dev->horkage & ATA_HORKAGE_BROKEN_HPA)) {
+ ata_dev_printk(dev, KERN_WARNING,
+ "old n_sectors matches native, probably "
+ "late HPA lock, will try to unlock HPA\n");
+ /* try unlocking HPA */
+ dev->flags |= ATA_DFLAG_UNLOCK_HPA;
+ rc = -EIO;
+ } else
+ rc = -ENODEV;
+ /* restore original n_[native_]sectors and fail */
+ dev->n_native_sectors = n_native_sectors;
+ dev->n_sectors = n_sectors;
fail:
ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
return rc;
@@ -4353,6 +4370,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, },
{ "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, },
+ /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
+ { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, },
+
/* devices which puke on READ_NATIVE_MAX */
{ "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, },
{ "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 9f6cfac0f2c..228740f356c 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -879,6 +879,8 @@ static void ata_eh_set_pending(struct ata_port *ap, int fastdrain)
void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
+ struct request_queue *q = qc->scsicmd->device->request_queue;
+ unsigned long flags;
WARN_ON(!ap->ops->error_handler);
@@ -890,7 +892,9 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
* Note that ATA_QCFLAG_FAILED is unconditionally set after
* this function completes.
*/
+ spin_lock_irqsave(q->queue_lock, flags);
blk_abort_request(qc->scsicmd->request);
+ spin_unlock_irqrestore(q->queue_lock, flags);
}
/**
@@ -1624,6 +1628,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
}
/* okay, this error is ours */
+ memset(&tf, 0, sizeof(tf));
rc = ata_eh_read_log_10h(dev, &tag, &tf);
if (rc) {
ata_link_printk(link, KERN_ERR, "failed to read log page 10h "
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 51f0ffb78cb..00305f41ed8 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/libata.h>
+#include <linux/slab.h>
#include "libata.h"
const struct ata_port_operations sata_pmp_port_ops = {
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index bea003a24d2..0088cdeb0b1 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -33,6 +33,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/blkdev.h>
#include <linux/spinlock.h>
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 02441fd57e9..e3877b6843c 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -33,6 +33,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/libata.h>
#include <linux/highmem.h>
@@ -1667,6 +1668,7 @@ unsigned int ata_sff_host_intr(struct ata_port *ap,
{
struct ata_eh_info *ehi = &ap->link.eh_info;
u8 status, host_stat = 0;
+ bool bmdma_stopped = false;
VPRINTK("ata%u: protocol %d task_state %d\n",
ap->print_id, qc->tf.protocol, ap->hsm_task_state);
@@ -1699,6 +1701,7 @@ unsigned int ata_sff_host_intr(struct ata_port *ap,
/* before we do anything else, clear DMA-Start bit */
ap->ops->bmdma_stop(qc);
+ bmdma_stopped = true;
if (unlikely(host_stat & ATA_DMA_ERR)) {
/* error when transfering data to/from memory */
@@ -1716,8 +1719,14 @@ unsigned int ata_sff_host_intr(struct ata_port *ap,
/* check main status, clearing INTRQ if needed */
status = ata_sff_irq_status(ap);
- if (status & ATA_BUSY)
- goto idle_irq;
+ if (status & ATA_BUSY) {
+ if (bmdma_stopped) {
+ /* BMDMA engine is already stopped, we're screwed */
+ qc->err_mask |= AC_ERR_HSM;
+ ap->hsm_task_state = HSM_ST_ERR;
+ } else
+ goto idle_irq;
+ }
/* ack bmdma irq events */
ap->ops->sff_irq_clear(ap);
@@ -1762,13 +1771,16 @@ EXPORT_SYMBOL_GPL(ata_sff_host_intr);
irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
+ bool retried = false;
unsigned int i;
- unsigned int handled = 0, polling = 0;
+ unsigned int handled, idle, polling;
unsigned long flags;
/* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
spin_lock_irqsave(&host->lock, flags);
+retry:
+ handled = idle = polling = 0;
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
struct ata_queued_cmd *qc;
@@ -1782,7 +1794,8 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
handled |= ata_sff_host_intr(ap, qc);
else
polling |= 1 << i;
- }
+ } else
+ idle |= 1 << i;
}
/*
@@ -1790,7 +1803,9 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
* asserting IRQ line, nobody cared will ensue. Check IRQ
* pending status if available and clear spurious IRQ.
*/
- if (!handled) {
+ if (!handled && !retried) {
+ bool retry = false;
+
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
@@ -1801,12 +1816,23 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
!ap->ops->sff_irq_check(ap))
continue;
- if (printk_ratelimit())
- ata_port_printk(ap, KERN_INFO,
- "clearing spurious IRQ\n");
+ if (idle & (1 << i)) {
+ ap->ops->sff_check_status(ap);
+ ap->ops->sff_irq_clear(ap);
+ } else {
+ /* clear INTRQ and check if BUSY cleared */
+ if (!(ap->ops->sff_check_status(ap) & ATA_BUSY))
+ retry |= true;
+ /*
+ * With command in flight, we can't do
+ * sff_irq_clear() w/o racing with completion.
+ */
+ }
+ }
- ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
+ if (retry) {
+ retried = true;
+ goto retry;
}
}
@@ -2287,7 +2313,7 @@ EXPORT_SYMBOL_GPL(ata_sff_postreset);
* @qc: command
*
* Drain the FIFO and device of any stuck data following a command
- * failing to complete. In some cases this is neccessary before a
+ * failing to complete. In some cases this is necessary before a
* reset will recover the device.
*
*/
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 294f3020a78..1ea2be0f4b9 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -11,6 +11,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <acpi/acpi_bus.h>
@@ -161,7 +162,7 @@ static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings if
- * neccessary.
+ * necessary.
*/
static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c
index 5c129f99a7e..66ce6a526f2 100644
--- a/drivers/ata/pata_at32.c
+++ b/drivers/ata/pata_at32.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <scsi/scsi_host.h>
#include <linux/ata.h>
#include <linux/libata.h>
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c
index 376dd380b43..c6a946aa252 100644
--- a/drivers/ata/pata_at91.c
+++ b/drivers/ata/pata_at91.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/blkdev.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <linux/ata.h>
#include <linux/clk.h>
diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c
index 6fe7ded40c6..bb6e0746e07 100644
--- a/drivers/ata/pata_atp867x.c
+++ b/drivers/ata/pata_atp867x.c
@@ -33,6 +33,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 6cd5d5dd9e3..45896b3c653 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index c86c71639a9..727a81ce4c9 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -180,7 +180,7 @@ static void hpt3x3_init_chipset(struct pci_dev *dev)
* @id: Entry in match table
*
* Perform basic initialisation. We set the device up so we access all
- * ports via BAR4. This is neccessary to work around errata.
+ * ports via BAR4. This is necessary to work around errata.
*/
static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index b663b7ffae4..fa812e206ee 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -2,6 +2,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/blkdev.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <linux/ata.h>
#include <linux/libata.h>
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 9bde1cb5f98..5cb286fd839 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -75,6 +75,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c
index 4cc7bbd10ec..211b6438b3a 100644
--- a/drivers/ata/pata_macio.c
+++ b/drivers/ata/pata_macio.c
@@ -21,6 +21,7 @@
#include <linux/pmu.h>
#include <linux/scatterlist.h>
#include <linux/of.h>
+#include <linux/gfp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 2bc2dbe30e8..9f5b053611d 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -16,7 +16,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/libata.h>
#include <linux/of_platform.h>
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c
index 37ef416c124..005a44483a7 100644
--- a/drivers/ata/pata_octeon_cf.c
+++ b/drivers/ata/pata_octeon_cf.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/libata.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 36103531fee..4164dd244dd 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -29,6 +29,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <scsi/scsi_host.h>
#include <linux/ata.h>
#include <linux/libata.h>
@@ -131,7 +132,7 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev,
* @qc: command
*
* Drain the FIFO and device of any stuck data following a command
- * failing to complete. In some cases this is neccessary before a
+ * failing to complete. In some cases this is necessary before a
* reset will recover the device.
*
*/
@@ -423,6 +424,8 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+ PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x3e520e17),
+ PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -443,6 +446,8 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x9351e59d),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c
index 45f1e10f917..0ffd631000b 100644
--- a/drivers/ata/pata_rb532_cf.c
+++ b/drivers/ata/pata_rb532_cf.c
@@ -19,6 +19,7 @@
*
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c
index 237a24d41a2..37092cfd7bc 100644
--- a/drivers/ata/pata_rdc.c
+++ b/drivers/ata/pata_rdc.c
@@ -28,6 +28,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/dmi.h>
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 3059ec017de..741e7cb69d8 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -58,6 +58,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/dmi.h>
@@ -576,6 +577,10 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
u8 rev = isa->revision;
pci_dev_put(isa);
+ if ((id->device == 0x0415 || id->device == 0x3164) &&
+ (config->id != id->device))
+ continue;
+
if (rev >= config->rev_min && rev <= config->rev_max)
break;
}
@@ -677,6 +682,7 @@ static const struct pci_device_id via[] = {
{ PCI_VDEVICE(VIA, 0x3164), },
{ PCI_VDEVICE(VIA, 0x5324), },
{ PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE },
+ { PCI_VDEVICE(VIA, 0x9001), VIA_IDFLAG_SINGLE },
{ },
};
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 6c65b0776a2..5904cfdb8db 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -34,6 +34,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index ce4136eea08..a69192b38b4 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 4406902b429..27dc6c86a4c 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -39,6 +39,7 @@
* happy to assist.
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index df8ee325d3c..71cc0d42f9e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -64,6 +64,7 @@
#include <linux/ata_platform.h>
#include <linux/mbus.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 684fe04dbbb..2a98b09ab73 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -38,6 +38,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 63306285c84..5356ec00d2b 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -33,6 +33,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 326c0cfc29b..92ba45e6689 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 1370df6c420..433b6b89c79 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index bbcf970068a..232468f2ea9 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -81,6 +81,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index e5bff47e8aa..011e098590d 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
index 5effec6f545..6d44f07b69f 100644
--- a/drivers/atm/adummy.c
+++ b/drivers/atm/adummy.c
@@ -13,6 +13,7 @@
#include <linux/mm.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 8af23411743..9d18644c897 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -36,6 +36,7 @@
#include <linux/mutex.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/io.h>
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
index 02ad83d6b56..b86712167eb 100644
--- a/drivers/atm/atmtcp.c
+++ b/drivers/atm/atmtcp.c
@@ -9,6 +9,7 @@
#include <linux/atm_tcp.h>
#include <linux/bitops.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 0c302614544..719ec5a0dca 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/atm_eni.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/atomic.h>
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index cd5049af47a..6e600afd06a 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -46,6 +46,7 @@
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/system.h>
#include <asm/string.h>
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index e8c6529dc36..c213e0da034 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -67,6 +67,7 @@
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 4e49021e67e..54720baa736 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -40,6 +40,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c
index 84672dc57f7..dab5cf5274f 100644
--- a/drivers/atm/idt77105.c
+++ b/drivers/atm/idt77105.c
@@ -15,6 +15,7 @@
#include <linux/capability.h>
#include <linux/atm_idt77105.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/param.h>
#include <asm/uaccess.h>
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 01f36c08cb5..98657a6a330 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -41,6 +41,7 @@
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 25a4c86f839..ee9ddeb5341 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -54,6 +54,7 @@
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/atomic.h>
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 7fe7c324e7e..cbe15a86c66 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -55,6 +55,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/atmdev.h>
#include <asm/io.h>
@@ -306,11 +307,10 @@ static void vci_bitfield_iterate(struct lanai_dev *lanai,
const unsigned long *lp,
void (*func)(struct lanai_dev *,vci_t vci))
{
- vci_t vci = find_first_bit(lp, NUM_VCI);
- while (vci < NUM_VCI) {
+ vci_t vci;
+
+ for_each_set_bit(vci, lp, NUM_VCI)
func(lanai, vci);
- vci = find_next_bit(lp, NUM_VCI, vci + 1);
- }
}
/* -------------------- BUFFER UTILITIES: */
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 50838407b11..b7473a6110a 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -49,6 +49,7 @@
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 51eed679a05..ded76c4c9f4 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -40,6 +40,7 @@
#include <linux/firmware.h>
#include <linux/ctype.h>
#include <linux/swab.h>
+#include <linux/slab.h>
#define VERSION "0.07"
#define PTAG "solos-pci"
diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c
index 6dd3f591996..da4b91ffa53 100644
--- a/drivers/atm/suni.c
+++ b/drivers/atm/suni.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/atm_suni.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/param.h>
#include <asm/uaccess.h>
diff --git a/drivers/atm/uPD98402.c b/drivers/atm/uPD98402.c
index fc8cb07c247..c45ae0573bb 100644
--- a/drivers/atm/uPD98402.c
+++ b/drivers/atm/uPD98402.c
@@ -9,6 +9,7 @@
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 2e9635be048..702accec89e 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -21,6 +21,7 @@
#include <linux/capability.h>
#include <linux/bitops.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/system.h>
#include <asm/string.h>
diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c
index eacb175f6bd..49758593a5b 100644
--- a/drivers/auxdisplay/cfag12864b.c
+++ b/drivers/auxdisplay/cfag12864b.c
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/device.h>
diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c
index fe3a865be4e..3fecfb446d9 100644
--- a/drivers/auxdisplay/cfag12864bfb.c
+++ b/drivers/auxdisplay/cfag12864bfb.c
@@ -31,7 +31,6 @@
#include <linux/fb.h>
#include <linux/mm.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/cfag12864b.h>
@@ -81,7 +80,7 @@ static struct fb_ops cfag12864bfb_ops = {
.fb_mmap = cfag12864bfb_mmap,
};
-static int __init cfag12864bfb_probe(struct platform_device *device)
+static int __devinit cfag12864bfb_probe(struct platform_device *device)
{
int ret = -EINVAL;
struct fb_info *info = framebuffer_alloc(0, &device->dev);
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index ee377270beb..fd52c48ee76 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -3,35 +3,50 @@ menu "Generic Driver Options"
config UEVENT_HELPER_PATH
string "path to uevent helper"
depends on HOTPLUG
- default "/sbin/hotplug"
+ default ""
help
Path to uevent helper program forked by the kernel for
every uevent.
+ Before the switch to the netlink-based uevent source, this was
+ used to hook hotplug scripts into kernel device events. It
+ usually pointed to a shell script at /sbin/hotplug.
+ This should not be used today, because usual systems create
+ many events at bootup or device discovery in a very short time
+ frame. One forked process per event can create so many processes
+ that it creates a high system load, or on smaller systems
+ it is known to create out-of-memory situations during bootup.
config DEVTMPFS
- bool "Create a kernel maintained /dev tmpfs (EXPERIMENTAL)"
+ bool "Maintain a devtmpfs filesystem to mount at /dev"
depends on HOTPLUG && SHMEM && TMPFS
help
- This creates a tmpfs filesystem, and mounts it at bootup
- and mounts it at /dev. The kernel driver core creates device
- nodes for all registered devices in that filesystem. All device
- nodes are owned by root and have the default mode of 0600.
- Userspace can add and delete the nodes as needed. This is
- intended to simplify bootup, and make it possible to delay
- the initial coldplug at bootup done by udev in userspace.
- It should also provide a simpler way for rescue systems
- to bring up a kernel with dynamic major/minor numbers.
- Meaningful symlinks, permissions and device ownership must
- still be handled by userspace.
- If unsure, say N here.
+ This creates a tmpfs filesystem instance early at bootup.
+ In this filesystem, the kernel driver core maintains device
+ nodes with their default names and permissions for all
+ registered devices with an assigned major/minor number.
+ Userspace can modify the filesystem content as needed, add
+ symlinks, and apply needed permissions.
+ It provides a fully functional /dev directory, where usually
+ udev runs on top, managing permissions and adding meaningful
+ symlinks.
+ In very limited environments, it may provide a sufficient
+ functional /dev without any further help. It also allows simple
+ rescue systems, and reliably handles dynamic major/minor numbers.
config DEVTMPFS_MOUNT
- bool "Automount devtmpfs at /dev"
+ bool "Automount devtmpfs at /dev, after the kernel mounted the rootfs"
depends on DEVTMPFS
help
- This will mount devtmpfs at /dev if the kernel mounts the root
- filesystem. It will not affect initramfs based mounting.
- If unsure, say N here.
+ This will instruct the kernel to automatically mount the
+ devtmpfs filesystem at /dev, directly after the kernel has
+ mounted the root filesystem. The behavior can be overridden
+ with the commandline parameter: devtmpfs.mount=0|1.
+ This option does not affect initramfs based booting, here
+ the devtmpfs filesystem always needs to be mounted manually
+ after the roots is mounted.
+ With this option enabled, it allows to bring up a system in
+ rescue mode with init=/bin/sh, even when the /dev directory
+ on the rootfs is completely empty.
config STANDALONE
bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index b9cda053d3c..8fc200b2e2c 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -328,6 +328,7 @@ attribute_container_add_attrs(struct device *classdev)
return sysfs_create_group(&classdev->kobj, cont->grp);
for (i = 0; attrs[i]; i++) {
+ sysfs_attr_init(&attrs[i]->attr);
error = device_create_file(classdev, attrs[i]);
if (error)
return error;
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index c0c5a43d9fb..12eec3f633b 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/string.h>
#include "base.h"
@@ -70,7 +71,7 @@ static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static struct sysfs_ops driver_sysfs_ops = {
+static const struct sysfs_ops driver_sysfs_ops = {
.show = drv_attr_show,
.store = drv_attr_store,
};
@@ -115,7 +116,7 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static struct sysfs_ops bus_sysfs_ops = {
+static const struct sysfs_ops bus_sysfs_ops = {
.show = bus_attr_show,
.store = bus_attr_store,
};
@@ -154,7 +155,7 @@ static int bus_uevent_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
-static struct kset_uevent_ops bus_uevent_ops = {
+static const struct kset_uevent_ops bus_uevent_ops = {
.filter = bus_uevent_filter,
};
@@ -173,10 +174,10 @@ static ssize_t driver_unbind(struct device_driver *drv,
dev = bus_find_device_by_name(bus, NULL, buf);
if (dev && dev->driver == drv) {
if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
+ device_lock(dev->parent);
device_release_driver(dev);
if (dev->parent)
- up(&dev->parent->sem);
+ device_unlock(dev->parent);
err = count;
}
put_device(dev);
@@ -200,12 +201,12 @@ static ssize_t driver_bind(struct device_driver *drv,
dev = bus_find_device_by_name(bus, NULL, buf);
if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
- down(&dev->sem);
+ device_lock(dev->parent);
+ device_lock(dev);
err = driver_probe_device(drv, dev);
- up(&dev->sem);
+ device_unlock(dev);
if (dev->parent)
- up(&dev->parent->sem);
+ device_unlock(dev->parent);
if (err > 0) {
/* success */
@@ -744,10 +745,10 @@ static int __must_check bus_rescan_devices_helper(struct device *dev,
if (!dev->driver) {
if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
+ device_lock(dev->parent);
ret = device_attach(dev);
if (dev->parent)
- up(&dev->parent->sem);
+ device_unlock(dev->parent);
}
return ret < 0 ? ret : 0;
}
@@ -779,10 +780,10 @@ int device_reprobe(struct device *dev)
{
if (dev->driver) {
if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
+ device_lock(dev->parent);
device_release_driver(dev);
if (dev->parent)
- up(&dev->parent->sem);
+ device_unlock(dev->parent);
}
return bus_rescan_devices_helper(dev, NULL);
}
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 6e2c3b064f5..9c6a0d6408e 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -31,7 +31,7 @@ static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,
ssize_t ret = -EIO;
if (class_attr->show)
- ret = class_attr->show(cp->class, buf);
+ ret = class_attr->show(cp->class, class_attr, buf);
return ret;
}
@@ -43,7 +43,7 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
ssize_t ret = -EIO;
if (class_attr->store)
- ret = class_attr->store(cp->class, buf, count);
+ ret = class_attr->store(cp->class, class_attr, buf, count);
return ret;
}
@@ -63,7 +63,7 @@ static void class_release(struct kobject *kobj)
kfree(cp);
}
-static struct sysfs_ops class_sysfs_ops = {
+static const struct sysfs_ops class_sysfs_ops = {
.show = class_attr_show,
.store = class_attr_store,
};
@@ -219,6 +219,8 @@ static void class_create_release(struct class *cls)
* This is used to create a struct class pointer that can then be used
* in calls to device_create().
*
+ * Returns &struct class pointer on success, or ERR_PTR() on error.
+ *
* Note, the pointer created here is to be destroyed when finished by
* making a call to class_destroy().
*/
@@ -490,6 +492,16 @@ void class_interface_unregister(struct class_interface *class_intf)
class_put(parent);
}
+ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr,
+ char *buf)
+{
+ struct class_attribute_string *cs;
+ cs = container_of(attr, struct class_attribute_string, attr);
+ return snprintf(buf, PAGE_SIZE, "%s\n", cs->str);
+}
+
+EXPORT_SYMBOL_GPL(show_class_attr_string);
+
struct class_compat {
struct kobject *kobj;
};
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 28202577042..b56a0ba31d4 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -100,7 +100,7 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static struct sysfs_ops dev_sysfs_ops = {
+static const struct sysfs_ops dev_sysfs_ops = {
.show = dev_attr_show,
.store = dev_attr_store,
};
@@ -252,7 +252,7 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
return retval;
}
-static struct kset_uevent_ops device_uevent_ops = {
+static const struct kset_uevent_ops device_uevent_ops = {
.filter = dev_uevent_filter,
.name = dev_uevent_name,
.uevent = dev_uevent,
@@ -306,15 +306,10 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
{
enum kobject_action action;
- if (kobject_action_type(buf, count, &action) == 0) {
+ if (kobject_action_type(buf, count, &action) == 0)
kobject_uevent(&dev->kobj, action);
- goto out;
- }
-
- dev_err(dev, "uevent: unsupported action-string; this will "
- "be ignored in a future kernel version\n");
- kobject_uevent(&dev->kobj, KOBJ_ADD);
-out:
+ else
+ dev_err(dev, "uevent: unknown action-string\n");
return count;
}
@@ -607,6 +602,7 @@ static struct kobject *get_device_parent(struct device *dev,
int retval;
if (dev->class) {
+ static DEFINE_MUTEX(gdp_mutex);
struct kobject *kobj = NULL;
struct kobject *parent_kobj;
struct kobject *k;
@@ -623,6 +619,8 @@ static struct kobject *get_device_parent(struct device *dev,
else
parent_kobj = &parent->kobj;
+ mutex_lock(&gdp_mutex);
+
/* find our class-directory at the parent and reference it */
spin_lock(&dev->class->p->class_dirs.list_lock);
list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)
@@ -631,20 +629,26 @@ static struct kobject *get_device_parent(struct device *dev,
break;
}
spin_unlock(&dev->class->p->class_dirs.list_lock);
- if (kobj)
+ if (kobj) {
+ mutex_unlock(&gdp_mutex);
return kobj;
+ }
/* or create a new class-directory at the parent device */
k = kobject_create();
- if (!k)
+ if (!k) {
+ mutex_unlock(&gdp_mutex);
return NULL;
+ }
k->kset = &dev->class->p->class_dirs;
retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
if (retval < 0) {
+ mutex_unlock(&gdp_mutex);
kobject_put(k);
return NULL;
}
/* do not emit an uevent for this simple "glue" directory */
+ mutex_unlock(&gdp_mutex);
return k;
}
@@ -1341,6 +1345,8 @@ static void root_device_release(struct device *dev)
* 'module' symlink which points to the @owner directory
* in sysfs.
*
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
* Note: You probably want to use root_device_register().
*/
struct device *__root_device_register(const char *name, struct module *owner)
@@ -1428,6 +1434,8 @@ static void device_create_release(struct device *dev)
* Any further sysfs files that might be required can be created using this
* pointer.
*
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
@@ -1488,6 +1496,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs);
* Any further sysfs files that might be required can be created using this
* pointer.
*
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
@@ -1574,22 +1584,16 @@ int device_rename(struct device *dev, char *new_name)
if (old_class_name) {
new_class_name = make_class_name(dev->class->name, &dev->kobj);
if (new_class_name) {
- error = sysfs_create_link_nowarn(&dev->parent->kobj,
- &dev->kobj,
- new_class_name);
- if (error)
- goto out;
- sysfs_remove_link(&dev->parent->kobj, old_class_name);
+ error = sysfs_rename_link(&dev->parent->kobj,
+ &dev->kobj,
+ old_class_name,
+ new_class_name);
}
}
#else
if (dev->class) {
- error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj,
- &dev->kobj, dev_name(dev));
- if (error)
- goto out;
- sysfs_remove_link(&dev->class->p->class_subsys.kobj,
- old_device_name);
+ error = sysfs_rename_link(&dev->class->p->class_subsys.kobj,
+ &dev->kobj, old_device_name, new_name);
}
#endif
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 958bd1540c3..f35719aab3c 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -10,11 +10,15 @@
#include <linux/topology.h>
#include <linux/device.h>
#include <linux/node.h>
+#include <linux/gfp.h>
#include "base.h"
+static struct sysdev_class_attribute *cpu_sysdev_class_attrs[];
+
struct sysdev_class cpu_sysdev_class = {
.name = "cpu",
+ .attrs = cpu_sysdev_class_attrs,
};
EXPORT_SYMBOL(cpu_sysdev_class);
@@ -76,34 +80,24 @@ void unregister_cpu(struct cpu *cpu)
}
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
-static ssize_t cpu_probe_store(struct class *class, const char *buf,
+static ssize_t cpu_probe_store(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ const char *buf,
size_t count)
{
return arch_cpu_probe(buf, count);
}
-static ssize_t cpu_release_store(struct class *class, const char *buf,
+static ssize_t cpu_release_store(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ const char *buf,
size_t count)
{
return arch_cpu_release(buf, count);
}
-static CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
-static CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
-
-int __init cpu_probe_release_init(void)
-{
- int rc;
-
- rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
- &class_attr_probe.attr);
- if (!rc)
- rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
- &class_attr_release.attr);
-
- return rc;
-}
-device_initcall(cpu_probe_release_init);
+static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
+static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
#else /* ... !CONFIG_HOTPLUG_CPU */
@@ -141,31 +135,39 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
/*
* Print cpu online, possible, present, and system maps
*/
-static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
+
+struct cpu_attr {
+ struct sysdev_class_attribute attr;
+ const struct cpumask *const * const map;
+};
+
+static ssize_t show_cpus_attr(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
- int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map);
+ struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
+ int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map));
buf[n++] = '\n';
buf[n] = '\0';
return n;
}
-#define print_cpus_func(type) \
-static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \
-{ \
- return print_cpus_map(buf, cpu_##type##_mask); \
-} \
-static struct sysdev_class_attribute attr_##type##_map = \
- _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
+#define _CPU_ATTR(name, map) \
+ { _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map }
-print_cpus_func(online);
-print_cpus_func(possible);
-print_cpus_func(present);
+/* Keep in sync with cpu_sysdev_class_attrs */
+static struct cpu_attr cpu_attrs[] = {
+ _CPU_ATTR(online, &cpu_online_mask),
+ _CPU_ATTR(possible, &cpu_possible_mask),
+ _CPU_ATTR(present, &cpu_present_mask),
+};
/*
* Print values for NR_CPUS and offlined cpus
*/
-static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf)
+static ssize_t print_cpus_kernel_max(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, char *buf)
{
int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1);
return n;
@@ -175,7 +177,8 @@ static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
unsigned int total_cpus;
-static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf)
+static ssize_t print_cpus_offline(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, char *buf)
{
int n = 0, len = PAGE_SIZE-2;
cpumask_var_t offline;
@@ -204,29 +207,6 @@ static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf)
}
static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
-static struct sysdev_class_attribute *cpu_state_attr[] = {
- &attr_online_map,
- &attr_possible_map,
- &attr_present_map,
- &attr_kernel_max,
- &attr_offline,
-};
-
-static int cpu_states_init(void)
-{
- int i;
- int err = 0;
-
- for (i = 0; i < ARRAY_SIZE(cpu_state_attr); i++) {
- int ret;
- ret = sysdev_class_create_file(&cpu_sysdev_class,
- cpu_state_attr[i]);
- if (!err)
- err = ret;
- }
- return err;
-}
-
/*
* register_cpu - Setup a sysfs device for a CPU.
* @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -272,9 +252,6 @@ int __init cpu_dev_init(void)
int err;
err = sysdev_class_register(&cpu_sysdev_class);
- if (!err)
- err = cpu_states_init();
-
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
if (!err)
err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
@@ -282,3 +259,16 @@ int __init cpu_dev_init(void)
return err;
}
+
+static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = {
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+ &attr_probe,
+ &attr_release,
+#endif
+ &cpu_attrs[0].attr,
+ &cpu_attrs[1].attr,
+ &cpu_attrs[2].attr,
+ &attr_kernel_max,
+ &attr_offline,
+ NULL
+};
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index ee95c76bfd3..c89291f8a16 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -85,7 +85,7 @@ static void driver_sysfs_remove(struct device *dev)
* for before calling this. (It is ok to call with no other effort
* from a driver's probe() method.)
*
- * This function must be called with @dev->sem held.
+ * This function must be called with the device lock held.
*/
int device_bind_driver(struct device *dev)
{
@@ -190,8 +190,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe);
* This function returns -ENODEV if the device is not registered,
* 1 if the device is bound successfully and 0 otherwise.
*
- * This function must be called with @dev->sem held. When called for a
- * USB interface, @dev->parent->sem must be held as well.
+ * This function must be called with @dev lock held. When called for a
+ * USB interface, @dev->parent lock must be held as well.
*/
int driver_probe_device(struct device_driver *drv, struct device *dev)
{
@@ -233,13 +233,13 @@ static int __device_attach(struct device_driver *drv, void *data)
* 0 if no matching driver was found;
* -ENODEV if the device is not registered.
*
- * When called for a USB interface, @dev->parent->sem must be held.
+ * When called for a USB interface, @dev->parent lock must be held.
*/
int device_attach(struct device *dev)
{
int ret = 0;
- down(&dev->sem);
+ device_lock(dev);
if (dev->driver) {
ret = device_bind_driver(dev);
if (ret == 0)
@@ -253,7 +253,7 @@ int device_attach(struct device *dev)
ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
pm_runtime_put_sync(dev);
}
- up(&dev->sem);
+ device_unlock(dev);
return ret;
}
EXPORT_SYMBOL_GPL(device_attach);
@@ -276,13 +276,13 @@ static int __driver_attach(struct device *dev, void *data)
return 0;
if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
- down(&dev->sem);
+ device_lock(dev->parent);
+ device_lock(dev);
if (!dev->driver)
driver_probe_device(drv, dev);
- up(&dev->sem);
+ device_unlock(dev);
if (dev->parent)
- up(&dev->parent->sem);
+ device_unlock(dev->parent);
return 0;
}
@@ -303,8 +303,8 @@ int driver_attach(struct device_driver *drv)
EXPORT_SYMBOL_GPL(driver_attach);
/*
- * __device_release_driver() must be called with @dev->sem held.
- * When called for a USB interface, @dev->parent->sem must be held as well.
+ * __device_release_driver() must be called with @dev lock held.
+ * When called for a USB interface, @dev->parent lock must be held as well.
*/
static void __device_release_driver(struct device *dev)
{
@@ -343,7 +343,7 @@ static void __device_release_driver(struct device *dev)
* @dev: device.
*
* Manually detach device from driver.
- * When called for a USB interface, @dev->parent->sem must be held.
+ * When called for a USB interface, @dev->parent lock must be held.
*/
void device_release_driver(struct device *dev)
{
@@ -352,9 +352,9 @@ void device_release_driver(struct device *dev)
* within their ->remove callback for the same device, they
* will deadlock right here.
*/
- down(&dev->sem);
+ device_lock(dev);
__device_release_driver(dev);
- up(&dev->sem);
+ device_unlock(dev);
}
EXPORT_SYMBOL_GPL(device_release_driver);
@@ -381,13 +381,13 @@ void driver_detach(struct device_driver *drv)
spin_unlock(&drv->p->klist_devices.k_lock);
if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
- down(&dev->sem);
+ device_lock(dev->parent);
+ device_lock(dev);
if (dev->driver == drv)
__device_release_driver(dev);
- up(&dev->sem);
+ device_unlock(dev);
if (dev->parent)
- up(&dev->parent->sem);
+ device_unlock(dev->parent);
put_device(dev);
}
}
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index 05dd307e8f0..cf7a0c78805 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "base.h"
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 42ae452b36b..057cf11326b 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -23,6 +23,7 @@
#include <linux/cred.h>
#include <linux/sched.h>
#include <linux/init_task.h>
+#include <linux/slab.h>
static struct vfsmount *dev_mnt;
@@ -301,6 +302,19 @@ int devtmpfs_delete_node(struct device *dev)
if (dentry->d_inode) {
err = vfs_getattr(nd.path.mnt, dentry, &stat);
if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
+ struct iattr newattrs;
+ /*
+ * before unlinking this node, reset permissions
+ * of possible references like hardlinks
+ */
+ newattrs.ia_uid = 0;
+ newattrs.ia_gid = 0;
+ newattrs.ia_mode = stat.mode & ~0777;
+ newattrs.ia_valid =
+ ATTR_UID|ATTR_GID|ATTR_MODE;
+ mutex_lock(&dentry->d_inode->i_mutex);
+ notify_change(dentry, &newattrs);
+ mutex_unlock(&dentry->d_inode->i_mutex);
err = vfs_unlink(nd.path.dentry->d_inode,
dentry);
if (!err || err == -ENOENT)
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 962a3b574f2..d4d8ce53886 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -2,6 +2,7 @@
* Coherent per-device memory handling.
* Borrowed from i386
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index ca9186f70a6..763d59c1eb6 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -8,6 +8,7 @@
*/
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
/*
* Managed DMA API
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 90c9fff09ea..b631f7c5945 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include "base.h"
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index a95024166b6..985da11174e 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -19,7 +19,7 @@
#include <linux/kthread.h>
#include <linux/highmem.h>
#include <linux/firmware.h>
-#include "base.h"
+#include <linux/slab.h>
#define to_dev(obj) container_of(obj, struct device, kobj)
@@ -69,7 +69,9 @@ fw_load_abort(struct firmware_priv *fw_priv)
}
static ssize_t
-firmware_timeout_show(struct class *class, char *buf)
+firmware_timeout_show(struct class *class,
+ struct class_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%d\n", loading_timeout);
}
@@ -77,6 +79,7 @@ firmware_timeout_show(struct class *class, char *buf)
/**
* firmware_timeout_store - set number of seconds to wait for firmware
* @class: device class pointer
+ * @attr: device attribute pointer
* @buf: buffer to scan for timeout value
* @count: number of bytes in @buf
*
@@ -87,7 +90,9 @@ firmware_timeout_show(struct class *class, char *buf)
* Note: zero means 'wait forever'.
**/
static ssize_t
-firmware_timeout_store(struct class *class, const char *buf, size_t count)
+firmware_timeout_store(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
{
loading_timeout = simple_strtol(buf, NULL, 10);
if (loading_timeout < 0)
@@ -439,6 +444,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
fw_priv = dev_get_drvdata(f_dev);
fw_priv->fw = fw;
+ sysfs_bin_attr_init(&fw_priv->attr_data);
retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
if (retval) {
dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
@@ -610,7 +616,7 @@ request_firmware_work_func(void *arg)
}
/**
- * request_firmware_nowait: asynchronous version of request_firmware
+ * request_firmware_nowait - asynchronous version of request_firmware
* @module: module requesting the firmware
* @uevent: sends uevent to copy the firmware image if this flag
* is non-zero else the firmware copy must be done manually.
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index bd025059711..933442f4032 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -22,6 +22,7 @@
#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/stat.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
@@ -44,7 +45,7 @@ static int memory_uevent(struct kset *kset, struct kobject *obj, struct kobj_uev
return retval;
}
-static struct kset_uevent_ops memory_uevent_ops = {
+static const struct kset_uevent_ops memory_uevent_ops = {
.name = memory_uevent_name,
.uevent = memory_uevent,
};
@@ -309,17 +310,18 @@ static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL);
* Block size attribute stuff
*/
static ssize_t
-print_block_size(struct class *class, char *buf)
+print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr,
+ char *buf)
{
- return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
+ return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
}
-static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
+static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
static int block_size_init(void)
{
return sysfs_create_file(&memory_sysdev_class.kset.kobj,
- &class_attr_block_size_bytes.attr);
+ &attr_block_size_bytes.attr);
}
/*
@@ -330,7 +332,8 @@ static int block_size_init(void)
*/
#ifdef CONFIG_ARCH_MEMORY_PROBE
static ssize_t
-memory_probe_store(struct class *class, const char *buf, size_t count)
+memory_probe_store(struct class *class, struct class_attribute *attr,
+ const char *buf, size_t count)
{
u64 phys_addr;
int nid;
@@ -367,7 +370,9 @@ static inline int memory_probe_init(void)
/* Soft offline a page */
static ssize_t
-store_soft_offline_page(struct class *class, const char *buf, size_t count)
+store_soft_offline_page(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
{
int ret;
u64 pfn;
@@ -384,7 +389,9 @@ store_soft_offline_page(struct class *class, const char *buf, size_t count)
/* Forcibly offline a page, including killing processes. */
static ssize_t
-store_hard_offline_page(struct class *class, const char *buf, size_t count)
+store_hard_offline_page(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
{
int ret;
u64 pfn;
@@ -423,12 +430,16 @@ static inline int memory_fail_init(void)
* differentiation between which *physical* devices each
* section belongs to...
*/
+int __weak arch_get_memory_phys_device(unsigned long start_pfn)
+{
+ return 0;
+}
static int add_memory_block(int nid, struct mem_section *section,
- unsigned long state, int phys_device,
- enum mem_add_context context)
+ unsigned long state, enum mem_add_context context)
{
struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ unsigned long start_pfn;
int ret = 0;
if (!mem)
@@ -437,7 +448,8 @@ static int add_memory_block(int nid, struct mem_section *section,
mem->phys_index = __section_nr(section);
mem->state = state;
mutex_init(&mem->state_mutex);
- mem->phys_device = phys_device;
+ start_pfn = section_nr_to_pfn(mem->phys_index);
+ mem->phys_device = arch_get_memory_phys_device(start_pfn);
ret = register_memory(mem, section);
if (!ret)
@@ -509,7 +521,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
*/
int register_new_memory(int nid, struct mem_section *section)
{
- return add_memory_block(nid, section, MEM_OFFLINE, 0, HOTPLUG);
+ return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG);
}
int unregister_memory_section(struct mem_section *section)
@@ -542,7 +554,7 @@ int __init memory_dev_init(void)
if (!present_section_nr(i))
continue;
err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE,
- 0, BOOT);
+ BOOT);
if (!ret)
ret = err;
}
diff --git a/drivers/base/module.c b/drivers/base/module.c
index 103be9cacb0..f32f2f9b7be 100644
--- a/drivers/base/module.c
+++ b/drivers/base/module.c
@@ -7,6 +7,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include "base.h"
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 70122791683..057979a19ee 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -15,9 +15,13 @@
#include <linux/cpu.h>
#include <linux/device.h>
#include <linux/swap.h>
+#include <linux/slab.h>
+
+static struct sysdev_class_attribute *node_state_attrs[];
static struct sysdev_class node_class = {
.name = "node",
+ .attrs = node_state_attrs,
};
@@ -162,8 +166,11 @@ static ssize_t node_read_distance(struct sys_device * dev,
int len = 0;
int i;
- /* buf currently PAGE_SIZE, need ~4 chars per node */
- BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2);
+ /*
+ * buf is currently PAGE_SIZE in length and each node needs 4 chars
+ * at the most (distance + space or newline).
+ */
+ BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE);
for_each_online_node(i)
len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
@@ -544,76 +551,52 @@ static ssize_t print_nodes_state(enum node_states state, char *buf)
return n;
}
-static ssize_t print_nodes_possible(struct sysdev_class *class, char *buf)
-{
- return print_nodes_state(N_POSSIBLE, buf);
-}
-
-static ssize_t print_nodes_online(struct sysdev_class *class, char *buf)
-{
- return print_nodes_state(N_ONLINE, buf);
-}
-
-static ssize_t print_nodes_has_normal_memory(struct sysdev_class *class,
- char *buf)
-{
- return print_nodes_state(N_NORMAL_MEMORY, buf);
-}
+struct node_attr {
+ struct sysdev_class_attribute attr;
+ enum node_states state;
+};
-static ssize_t print_nodes_has_cpu(struct sysdev_class *class, char *buf)
+static ssize_t show_node_state(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, char *buf)
{
- return print_nodes_state(N_CPU, buf);
+ struct node_attr *na = container_of(attr, struct node_attr, attr);
+ return print_nodes_state(na->state, buf);
}
-static SYSDEV_CLASS_ATTR(possible, 0444, print_nodes_possible, NULL);
-static SYSDEV_CLASS_ATTR(online, 0444, print_nodes_online, NULL);
-static SYSDEV_CLASS_ATTR(has_normal_memory, 0444, print_nodes_has_normal_memory,
- NULL);
-static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL);
+#define _NODE_ATTR(name, state) \
+ { _SYSDEV_CLASS_ATTR(name, 0444, show_node_state, NULL), state }
+static struct node_attr node_state_attr[] = {
+ _NODE_ATTR(possible, N_POSSIBLE),
+ _NODE_ATTR(online, N_ONLINE),
+ _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
+ _NODE_ATTR(has_cpu, N_CPU),
#ifdef CONFIG_HIGHMEM
-static ssize_t print_nodes_has_high_memory(struct sysdev_class *class,
- char *buf)
-{
- return print_nodes_state(N_HIGH_MEMORY, buf);
-}
-
-static SYSDEV_CLASS_ATTR(has_high_memory, 0444, print_nodes_has_high_memory,
- NULL);
+ _NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
#endif
+};
-struct sysdev_class_attribute *node_state_attr[] = {
- &attr_possible,
- &attr_online,
- &attr_has_normal_memory,
+static struct sysdev_class_attribute *node_state_attrs[] = {
+ &node_state_attr[0].attr,
+ &node_state_attr[1].attr,
+ &node_state_attr[2].attr,
+ &node_state_attr[3].attr,
#ifdef CONFIG_HIGHMEM
- &attr_has_high_memory,
+ &node_state_attr[4].attr,
#endif
- &attr_has_cpu,
+ NULL
};
-static int node_states_init(void)
-{
- int i;
- int err = 0;
-
- for (i = 0; i < NR_NODE_STATES; i++) {
- int ret;
- ret = sysdev_class_create_file(&node_class, node_state_attr[i]);
- if (!err)
- err = ret;
- }
- return err;
-}
-
#define NODE_CALLBACK_PRI 2 /* lower than SLAB */
static int __init register_node_type(void)
{
int ret;
+ BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
+ BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES);
+
ret = sysdev_class_register(&node_class);
if (!ret) {
- ret = node_states_init();
hotplug_memory_notifier(node_memory_callback,
NODE_CALLBACK_PRI);
}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 58efaf2f125..4b4b565c835 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -128,7 +128,7 @@ struct platform_object {
};
/**
- * platform_device_put
+ * platform_device_put - destroy a platform device
* @pdev: platform device to free
*
* Free all memory associated with a platform device. This function must
@@ -152,7 +152,7 @@ static void platform_device_release(struct device *dev)
}
/**
- * platform_device_alloc
+ * platform_device_alloc - create a platform device
* @name: base name of the device we're adding
* @id: instance id
*
@@ -177,7 +177,7 @@ struct platform_device *platform_device_alloc(const char *name, int id)
EXPORT_SYMBOL_GPL(platform_device_alloc);
/**
- * platform_device_add_resources
+ * platform_device_add_resources - add resources to a platform device
* @pdev: platform device allocated by platform_device_alloc to add resources to
* @res: set of resources that needs to be allocated for the device
* @num: number of resources
@@ -202,7 +202,7 @@ int platform_device_add_resources(struct platform_device *pdev,
EXPORT_SYMBOL_GPL(platform_device_add_resources);
/**
- * platform_device_add_data
+ * platform_device_add_data - add platform-specific data to a platform device
* @pdev: platform device allocated by platform_device_alloc to add resources to
* @data: platform specific data for this platform device
* @size: size of platform specific data
@@ -344,7 +344,7 @@ void platform_device_unregister(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(platform_device_unregister);
/**
- * platform_device_register_simple
+ * platform_device_register_simple - add a platform-level device and its resources
* @name: base name of the device we're adding
* @id: instance id
* @res: set of resources that needs to be allocated for the device
@@ -362,6 +362,8 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
* enumeration tasks, they don't fully conform to the Linux driver model.
* In particular, when such drivers are built as modules, they can't be
* "hotplugged".
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
struct platform_device *platform_device_register_simple(const char *name,
int id,
@@ -396,7 +398,7 @@ error:
EXPORT_SYMBOL_GPL(platform_device_register_simple);
/**
- * platform_device_register_data
+ * platform_device_register_data - add a platform-level device with platform-specific data
* @parent: parent device for the device we're adding
* @name: base name of the device we're adding
* @id: instance id
@@ -408,6 +410,8 @@ EXPORT_SYMBOL_GPL(platform_device_register_simple);
* allocated for the device allows drivers using such devices to be
* unloaded without waiting for the last reference to the device to be
* dropped.
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
struct platform_device *platform_device_register_data(
struct device *parent,
@@ -473,7 +477,7 @@ static void platform_drv_shutdown(struct device *_dev)
}
/**
- * platform_driver_register
+ * platform_driver_register - register a driver for platform-level devices
* @drv: platform driver structure
*/
int platform_driver_register(struct platform_driver *drv)
@@ -491,7 +495,7 @@ int platform_driver_register(struct platform_driver *drv)
EXPORT_SYMBOL_GPL(platform_driver_register);
/**
- * platform_driver_unregister
+ * platform_driver_unregister - unregister a driver for platform-level devices
* @drv: platform driver structure
*/
void platform_driver_unregister(struct platform_driver *drv)
@@ -548,6 +552,66 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
}
EXPORT_SYMBOL_GPL(platform_driver_probe);
+/**
+ * platform_create_bundle - register driver and create corresponding device
+ * @driver: platform driver structure
+ * @probe: the driver probe routine, probably from an __init section
+ * @res: set of resources that needs to be allocated for the device
+ * @n_res: number of resources
+ * @data: platform specific data for this platform device
+ * @size: size of platform specific data
+ *
+ * Use this in legacy-style modules that probe hardware directly and
+ * register a single platform device and corresponding platform driver.
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
+ */
+struct platform_device * __init_or_module platform_create_bundle(
+ struct platform_driver *driver,
+ int (*probe)(struct platform_device *),
+ struct resource *res, unsigned int n_res,
+ const void *data, size_t size)
+{
+ struct platform_device *pdev;
+ int error;
+
+ pdev = platform_device_alloc(driver->driver.name, -1);
+ if (!pdev) {
+ error = -ENOMEM;
+ goto err_out;
+ }
+
+ if (res) {
+ error = platform_device_add_resources(pdev, res, n_res);
+ if (error)
+ goto err_pdev_put;
+ }
+
+ if (data) {
+ error = platform_device_add_data(pdev, data, size);
+ if (error)
+ goto err_pdev_put;
+ }
+
+ error = platform_device_add(pdev);
+ if (error)
+ goto err_pdev_put;
+
+ error = platform_driver_probe(driver, probe);
+ if (error)
+ goto err_pdev_del;
+
+ return pdev;
+
+err_pdev_del:
+ platform_device_del(pdev);
+err_pdev_put:
+ platform_device_put(pdev);
+err_out:
+ return ERR_PTR(error);
+}
+EXPORT_SYMBOL_GPL(platform_create_bundle);
+
/* modalias support enables more hands-off userspace setup:
* (a) environment variable lets new-style hotplug events work once system is
* fully running: "modprobe $MODALIAS"
@@ -578,7 +642,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
}
static const struct platform_device_id *platform_match_id(
- struct platform_device_id *id,
+ const struct platform_device_id *id,
struct platform_device *pdev)
{
while (id->name[0]) {
@@ -994,9 +1058,11 @@ static __initdata LIST_HEAD(early_platform_driver_list);
static __initdata LIST_HEAD(early_platform_device_list);
/**
- * early_platform_driver_register
+ * early_platform_driver_register - register early platform driver
* @epdrv: early_platform driver structure
* @buf: string passed from early_param()
+ *
+ * Helper function for early_platform_init() / early_platform_init_buffer()
*/
int __init early_platform_driver_register(struct early_platform_driver *epdrv,
char *buf)
@@ -1048,9 +1114,12 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
}
/**
- * early_platform_add_devices - add a numbers of early platform devices
+ * early_platform_add_devices - adds a number of early platform devices
* @devs: array of early platform devices to add
* @num: number of early platform devices in array
+ *
+ * Used by early architecture code to register early platform devices and
+ * their platform data.
*/
void __init early_platform_add_devices(struct platform_device **devs, int num)
{
@@ -1070,8 +1139,12 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
}
/**
- * early_platform_driver_register_all
+ * early_platform_driver_register_all - register early platform drivers
* @class_str: string to identify early platform driver class
+ *
+ * Used by architecture code to register all early platform drivers
+ * for a certain class. If omitted then only early platform drivers
+ * with matching kernel command line class parameters will be registered.
*/
void __init early_platform_driver_register_all(char *class_str)
{
@@ -1093,7 +1166,7 @@ void __init early_platform_driver_register_all(char *class_str)
}
/**
- * early_platform_match
+ * early_platform_match - find early platform device matching driver
* @epdrv: early platform driver structure
* @id: id to match against
*/
@@ -1111,7 +1184,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id)
}
/**
- * early_platform_left
+ * early_platform_left - check if early platform driver has matching devices
* @epdrv: early platform driver structure
* @id: return true if id or above exists
*/
@@ -1129,7 +1202,7 @@ static __init int early_platform_left(struct early_platform_driver *epdrv,
}
/**
- * early_platform_driver_probe_id
+ * early_platform_driver_probe_id - probe drivers matching class_str and id
* @class_str: string to identify early platform driver class
* @id: id to match against
* @nr_probe: number of platform devices to successfully probe before exiting
@@ -1199,10 +1272,14 @@ static int __init early_platform_driver_probe_id(char *class_str,
}
/**
- * early_platform_driver_probe
+ * early_platform_driver_probe - probe a class of registered drivers
* @class_str: string to identify early platform driver class
* @nr_probe: number of platform devices to successfully probe before exiting
* @user_only: only probe user specified early platform devices
+ *
+ * Used by architecture code to probe registered early platform drivers
+ * within a certain class. For probe to happen a registered early platform
+ * device matching a registered early platform driver is needed.
*/
int __init early_platform_driver_probe(char *class_str,
int nr_probe,
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index 3ce3519e8f3..89de75325ce 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_PM) += sysfs.o
obj-$(CONFIG_PM_SLEEP) += main.o
obj-$(CONFIG_PM_RUNTIME) += runtime.o
+obj-$(CONFIG_PM_OPS) += generic_ops.o
obj-$(CONFIG_PM_TRACE_RTC) += trace.o
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
new file mode 100644
index 00000000000..4b29d498125
--- /dev/null
+++ b/drivers/base/power/generic_ops.c
@@ -0,0 +1,233 @@
+/*
+ * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems
+ *
+ * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#ifdef CONFIG_PM_RUNTIME
+/**
+ * pm_generic_runtime_idle - Generic runtime idle callback for subsystems.
+ * @dev: Device to handle.
+ *
+ * If PM operations are defined for the @dev's driver and they include
+ * ->runtime_idle(), execute it and return its error code, if nonzero.
+ * Otherwise, execute pm_runtime_suspend() for the device and return 0.
+ */
+int pm_generic_runtime_idle(struct device *dev)
+{
+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+ if (pm && pm->runtime_idle) {
+ int ret = pm->runtime_idle(dev);
+ if (ret)
+ return ret;
+ }
+
+ pm_runtime_suspend(dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
+
+/**
+ * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
+ * @dev: Device to suspend.
+ *
+ * If PM operations are defined for the @dev's driver and they include
+ * ->runtime_suspend(), execute it and return its error code. Otherwise,
+ * return -EINVAL.
+ */
+int pm_generic_runtime_suspend(struct device *dev)
+{
+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+ int ret;
+
+ ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : -EINVAL;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
+
+/**
+ * pm_generic_runtime_resume - Generic runtime resume callback for subsystems.
+ * @dev: Device to resume.
+ *
+ * If PM operations are defined for the @dev's driver and they include
+ * ->runtime_resume(), execute it and return its error code. Otherwise,
+ * return -EINVAL.
+ */
+int pm_generic_runtime_resume(struct device *dev)
+{
+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+ int ret;
+
+ ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : -EINVAL;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
+#endif /* CONFIG_PM_RUNTIME */
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback.
+ * @dev: Device to handle.
+ * @event: PM transition of the system under way.
+ *
+ * If the device has not been suspended at run time, execute the
+ * suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and
+ * return its error code. Otherwise, return zero.
+ */
+static int __pm_generic_call(struct device *dev, int event)
+{
+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+ int (*callback)(struct device *);
+
+ if (!pm || pm_runtime_suspended(dev))
+ return 0;
+
+ switch (event) {
+ case PM_EVENT_SUSPEND:
+ callback = pm->suspend;
+ break;
+ case PM_EVENT_FREEZE:
+ callback = pm->freeze;
+ break;
+ case PM_EVENT_HIBERNATE:
+ callback = pm->poweroff;
+ break;
+ case PM_EVENT_THAW:
+ callback = pm->thaw;
+ break;
+ default:
+ callback = NULL;
+ break;
+ }
+
+ return callback ? callback(dev) : 0;
+}
+
+/**
+ * pm_generic_suspend - Generic suspend callback for subsystems.
+ * @dev: Device to suspend.
+ */
+int pm_generic_suspend(struct device *dev)
+{
+ return __pm_generic_call(dev, PM_EVENT_SUSPEND);
+}
+EXPORT_SYMBOL_GPL(pm_generic_suspend);
+
+/**
+ * pm_generic_freeze - Generic freeze callback for subsystems.
+ * @dev: Device to freeze.
+ */
+int pm_generic_freeze(struct device *dev)
+{
+ return __pm_generic_call(dev, PM_EVENT_FREEZE);
+}
+EXPORT_SYMBOL_GPL(pm_generic_freeze);
+
+/**
+ * pm_generic_poweroff - Generic poweroff callback for subsystems.
+ * @dev: Device to handle.
+ */
+int pm_generic_poweroff(struct device *dev)
+{
+ return __pm_generic_call(dev, PM_EVENT_HIBERNATE);
+}
+EXPORT_SYMBOL_GPL(pm_generic_poweroff);
+
+/**
+ * pm_generic_thaw - Generic thaw callback for subsystems.
+ * @dev: Device to thaw.
+ */
+int pm_generic_thaw(struct device *dev)
+{
+ return __pm_generic_call(dev, PM_EVENT_THAW);
+}
+EXPORT_SYMBOL_GPL(pm_generic_thaw);
+
+/**
+ * __pm_generic_resume - Generic resume/restore callback for subsystems.
+ * @dev: Device to handle.
+ * @event: PM transition of the system under way.
+ *
+ * Execute the resume/resotre callback provided by the @dev's driver, if
+ * defined. If it returns 0, change the device's runtime PM status to 'active'.
+ * Return the callback's error code.
+ */
+static int __pm_generic_resume(struct device *dev, int event)
+{
+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+ int (*callback)(struct device *);
+ int ret;
+
+ if (!pm)
+ return 0;
+
+ switch (event) {
+ case PM_EVENT_RESUME:
+ callback = pm->resume;
+ break;
+ case PM_EVENT_RESTORE:
+ callback = pm->restore;
+ break;
+ default:
+ callback = NULL;
+ break;
+ }
+
+ if (!callback)
+ return 0;
+
+ ret = callback(dev);
+ if (!ret) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ }
+
+ return ret;
+}
+
+/**
+ * pm_generic_resume - Generic resume callback for subsystems.
+ * @dev: Device to resume.
+ */
+int pm_generic_resume(struct device *dev)
+{
+ return __pm_generic_resume(dev, PM_EVENT_RESUME);
+}
+EXPORT_SYMBOL_GPL(pm_generic_resume);
+
+/**
+ * pm_generic_restore - Generic restore callback for subsystems.
+ * @dev: Device to restore.
+ */
+int pm_generic_restore(struct device *dev)
+{
+ return __pm_generic_resume(dev, PM_EVENT_RESTORE);
+}
+EXPORT_SYMBOL_GPL(pm_generic_restore);
+#endif /* CONFIG_PM_SLEEP */
+
+struct dev_pm_ops generic_subsys_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+ .suspend = pm_generic_suspend,
+ .resume = pm_generic_resume,
+ .freeze = pm_generic_freeze,
+ .thaw = pm_generic_thaw,
+ .poweroff = pm_generic_poweroff,
+ .restore = pm_generic_restore,
+#endif
+#ifdef CONFIG_PM_RUNTIME
+ .runtime_suspend = pm_generic_runtime_suspend,
+ .runtime_resume = pm_generic_runtime_resume,
+ .runtime_idle = pm_generic_runtime_idle,
+#endif
+};
+EXPORT_SYMBOL_GPL(generic_subsys_pm_ops);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 0e26a6f6fd4..941fcb87e52 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -35,8 +35,8 @@
* because children are guaranteed to be discovered after parents, and
* are inserted at the back of the list on discovery.
*
- * Since device_pm_add() may be called with a device semaphore held,
- * we must never try to acquire a device semaphore while holding
+ * Since device_pm_add() may be called with a device lock held,
+ * we must never try to acquire a device lock while holding
* dpm_list_mutex.
*/
@@ -439,8 +439,23 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
if (dev->bus && dev->bus->pm) {
pm_dev_dbg(dev, state, "EARLY ");
error = pm_noirq_op(dev, dev->bus->pm, state);
+ if (error)
+ goto End;
}
+ if (dev->type && dev->type->pm) {
+ pm_dev_dbg(dev, state, "EARLY type ");
+ error = pm_noirq_op(dev, dev->type->pm, state);
+ if (error)
+ goto End;
+ }
+
+ if (dev->class && dev->class->pm) {
+ pm_dev_dbg(dev, state, "EARLY class ");
+ error = pm_noirq_op(dev, dev->class->pm, state);
+ }
+
+End:
TRACE_RESUME(error);
return error;
}
@@ -508,7 +523,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
TRACE_RESUME(0);
dpm_wait(dev->parent, async);
- down(&dev->sem);
+ device_lock(dev);
dev->power.status = DPM_RESUMING;
@@ -543,7 +558,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
}
}
End:
- up(&dev->sem);
+ device_unlock(dev);
complete_all(&dev->power.completion);
TRACE_RESUME(error);
@@ -629,7 +644,7 @@ static void dpm_resume(pm_message_t state)
*/
static void device_complete(struct device *dev, pm_message_t state)
{
- down(&dev->sem);
+ device_lock(dev);
if (dev->class && dev->class->pm && dev->class->pm->complete) {
pm_dev_dbg(dev, state, "completing class ");
@@ -646,7 +661,7 @@ static void device_complete(struct device *dev, pm_message_t state)
dev->bus->pm->complete(dev);
}
- up(&dev->sem);
+ device_unlock(dev);
}
/**
@@ -735,10 +750,26 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
{
int error = 0;
+ if (dev->class && dev->class->pm) {
+ pm_dev_dbg(dev, state, "LATE class ");
+ error = pm_noirq_op(dev, dev->class->pm, state);
+ if (error)
+ goto End;
+ }
+
+ if (dev->type && dev->type->pm) {
+ pm_dev_dbg(dev, state, "LATE type ");
+ error = pm_noirq_op(dev, dev->type->pm, state);
+ if (error)
+ goto End;
+ }
+
if (dev->bus && dev->bus->pm) {
pm_dev_dbg(dev, state, "LATE ");
error = pm_noirq_op(dev, dev->bus->pm, state);
}
+
+End:
return error;
}
@@ -809,7 +840,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
int error = 0;
dpm_wait_for_children(dev, async);
- down(&dev->sem);
+ device_lock(dev);
if (async_error)
goto End;
@@ -849,7 +880,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
dev->power.status = DPM_OFF;
End:
- up(&dev->sem);
+ device_unlock(dev);
complete_all(&dev->power.completion);
return error;
@@ -938,7 +969,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
{
int error = 0;
- down(&dev->sem);
+ device_lock(dev);
if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) {
pm_dev_dbg(dev, state, "preparing ");
@@ -962,7 +993,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
suspend_report_result(dev->class->pm->prepare, error);
}
End:
- up(&dev->sem);
+ device_unlock(dev);
return error;
}
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 0d903909af7..9354dc10a36 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -17,7 +17,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/pm.h>
#include <linux/device.h>
@@ -54,7 +53,7 @@ sysdev_store(struct kobject *kobj, struct attribute *attr,
return -EIO;
}
-static struct sysfs_ops sysfs_ops = {
+static const struct sysfs_ops sysfs_ops = {
.show = sysdev_show,
.store = sysdev_store,
};
@@ -89,7 +88,7 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
if (class_attr->show)
- return class_attr->show(class, buffer);
+ return class_attr->show(class, class_attr, buffer);
return -EIO;
}
@@ -100,11 +99,11 @@ static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
if (class_attr->store)
- return class_attr->store(class, buffer, count);
+ return class_attr->store(class, class_attr, buffer, count);
return -EIO;
}
-static struct sysfs_ops sysfs_class_ops = {
+static const struct sysfs_ops sysfs_class_ops = {
.show = sysdev_class_show,
.store = sysdev_class_store,
};
@@ -145,13 +144,20 @@ int sysdev_class_register(struct sysdev_class *cls)
if (retval)
return retval;
- return kset_register(&cls->kset);
+ retval = kset_register(&cls->kset);
+ if (!retval && cls->attrs)
+ retval = sysfs_create_files(&cls->kset.kobj,
+ (const struct attribute **)cls->attrs);
+ return retval;
}
void sysdev_class_unregister(struct sysdev_class *cls)
{
pr_debug("Unregistering sysdev class '%s'\n",
kobject_name(&cls->kset.kobj));
+ if (cls->attrs)
+ sysfs_remove_files(&cls->kset.kobj,
+ (const struct attribute **)cls->attrs);
kset_unregister(&cls->kset);
}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 459f1bc25a7..c5f22bb0a48 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -2533,7 +2533,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
Controller->RequestQueue[n] = RequestQueue;
blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit);
RequestQueue->queuedata = Controller;
- blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit);
blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit);
blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
disk->queue = RequestQueue;
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 05522583902..0182a22c423 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -54,6 +54,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/fd.h>
#include <linux/hdreg.h>
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 3af97d4da2d..035cefe4045 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -9,6 +9,7 @@
#include <linux/backing-dev.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include <linux/genhd.h>
#include <linux/netdevice.h>
#include "aoe.h"
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 62141ec09a2..4a1b9e7464a 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -8,6 +8,7 @@
#include <linux/blkdev.h>
#include <linux/completion.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include "aoe.h"
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 64a223b0cc2..5674bd01d96 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -5,6 +5,7 @@
*/
#include <linux/ata.h>
+#include <linux/slab.h>
#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/skbuff.h>
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index fa67027789a..0849280bfc1 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -8,6 +8,7 @@
#include <linux/blkdev.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "aoe.h"
static void dummy_timer(ulong);
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index ce0d62cd71b..4d3bc0d49df 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -4,6 +4,7 @@
* Ethernet portion of AoE driver
*/
+#include <linux/gfp.h>
#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/netdevice.h>
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index c6ddeacb77f..6081e81d573 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -15,9 +15,9 @@
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/highmem.h>
-#include <linux/gfp.h>
#include <linux/radix-tree.h>
#include <linux/buffer_head.h> /* invalidate_bh_lrus() */
+#include <linux/slab.h>
#include <asm/uaccess.h>
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 9e3af307aae..eb5ff0531cf 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3341,6 +3341,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
printk(KERN_WARNING
"cciss: controller cciss%d failed, stopping.\n",
h->ctlr);
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
fail_all_cmds(h->ctlr);
return IRQ_HANDLED;
}
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 17956ff6a08..df018990c42 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -536,7 +536,9 @@ static void atodb_endio(struct bio *bio, int error)
put_ldev(mdev);
}
+/* sector to word */
#define S2W(s) ((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL))
+
/* activity log to on disk bitmap -- prepare bio unless that sector
* is already covered by previously prepared bios */
static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
@@ -546,13 +548,20 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
{
struct bio *bio;
struct page *page;
- sector_t on_disk_sector = enr + mdev->ldev->md.md_offset
- + mdev->ldev->md.bm_offset;
+ sector_t on_disk_sector;
unsigned int page_offset = PAGE_SIZE;
int offset;
int i = 0;
int err = -ENOMEM;
+ /* We always write aligned, full 4k blocks,
+ * so we can ignore the logical_block_size (for now) */
+ enr &= ~7U;
+ on_disk_sector = enr + mdev->ldev->md.md_offset
+ + mdev->ldev->md.bm_offset;
+
+ D_ASSERT(!(on_disk_sector & 7U));
+
/* Check if that enr is already covered by an already created bio.
* Caution, bios[] is not NULL terminated,
* but only initialized to all NULL.
@@ -588,7 +597,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
offset = S2W(enr);
drbd_bm_get_lel(mdev, offset,
- min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset),
+ min_t(size_t, S2W(8), drbd_bm_words(mdev) - offset),
kmap(page) + page_offset);
kunmap(page);
@@ -597,7 +606,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
bio->bi_bdev = mdev->ldev->md_bdev;
bio->bi_sector = on_disk_sector;
- if (bio_add_page(bio, page, MD_SECTOR_SIZE, page_offset) != MD_SECTOR_SIZE)
+ if (bio_add_page(bio, page, 4096, page_offset) != 4096)
goto out_put_page;
atomic_inc(&wc->count);
@@ -1327,7 +1336,7 @@ int drbd_rs_del_all(struct drbd_conf *mdev)
/* ok, ->resync is there. */
for (i = 0; i < mdev->resync->nr_elements; i++) {
e = lc_element_by_index(mdev->resync, i);
- bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+ bm_ext = lc_entry(e, struct bm_extent, lce);
if (bm_ext->lce.lc_number == LC_FREE)
continue;
if (bm_ext->lce.lc_number == mdev->resync_wenr) {
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index b61057e7788..3390716898d 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -26,6 +26,7 @@
#include <linux/vmalloc.h>
#include <linux/string.h>
#include <linux/drbd.h>
+#include <linux/slab.h>
#include <asm/kmap_types.h>
#include "drbd_int.h"
@@ -66,7 +67,7 @@ struct drbd_bitmap {
size_t bm_words;
size_t bm_number_of_pages;
sector_t bm_dev_capacity;
- struct semaphore bm_change; /* serializes resize operations */
+ struct mutex bm_change; /* serializes resize operations */
atomic_t bm_async_io;
wait_queue_head_t bm_io_wait;
@@ -114,7 +115,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why)
return;
}
- trylock_failed = down_trylock(&b->bm_change);
+ trylock_failed = !mutex_trylock(&b->bm_change);
if (trylock_failed) {
dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
@@ -125,7 +126,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why)
b->bm_task == mdev->receiver.task ? "receiver" :
b->bm_task == mdev->asender.task ? "asender" :
b->bm_task == mdev->worker.task ? "worker" : "?");
- down(&b->bm_change);
+ mutex_lock(&b->bm_change);
}
if (__test_and_set_bit(BM_LOCKED, &b->bm_flags))
dev_err(DEV, "FIXME bitmap already locked in bm_lock\n");
@@ -147,7 +148,7 @@ void drbd_bm_unlock(struct drbd_conf *mdev)
b->bm_why = NULL;
b->bm_task = NULL;
- up(&b->bm_change);
+ mutex_unlock(&b->bm_change);
}
/* word offset to long pointer */
@@ -295,7 +296,7 @@ int drbd_bm_init(struct drbd_conf *mdev)
if (!b)
return -ENOMEM;
spin_lock_init(&b->bm_lock);
- init_MUTEX(&b->bm_change);
+ mutex_init(&b->bm_change);
init_waitqueue_head(&b->bm_io_wait);
mdev->bitmap = b;
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 2bf3a6ef368..e5e86a78182 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -95,7 +95,7 @@ extern char usermode_helper[];
/* All EEs on the free list should have ID_VACANT (== 0)
* freshly allocated EEs get !ID_VACANT (== 1)
- * so if it says "cannot dereference null pointer at adress 0x00000001",
+ * so if it says "cannot dereference null pointer at address 0x00000001",
* it is most likely one of these :( */
#define ID_IN_SYNC (4711ULL)
@@ -261,6 +261,9 @@ static inline const char *cmdname(enum drbd_packets cmd)
[P_OV_REQUEST] = "OVRequest",
[P_OV_REPLY] = "OVReply",
[P_OV_RESULT] = "OVResult",
+ [P_CSUM_RS_REQUEST] = "CsumRSRequest",
+ [P_RS_IS_IN_SYNC] = "CsumRSIsInSync",
+ [P_COMPRESSED_BITMAP] = "CBitmap",
[P_MAX_CMD] = NULL,
};
@@ -443,13 +446,18 @@ struct p_rs_param_89 {
char csums_alg[SHARED_SECRET_MAX];
} __packed;
+enum drbd_conn_flags {
+ CF_WANT_LOSE = 1,
+ CF_DRY_RUN = 2,
+};
+
struct p_protocol {
struct p_header head;
u32 protocol;
u32 after_sb_0p;
u32 after_sb_1p;
u32 after_sb_2p;
- u32 want_lose;
+ u32 conn_flags;
u32 two_primaries;
/* Since protocol version 87 and higher. */
@@ -791,6 +799,8 @@ enum {
* while this is set. */
RESIZE_PENDING, /* Size change detected locally, waiting for the response from
* the peer, if it changed there as well. */
+ CONN_DRY_RUN, /* Expect disconnect after resync handshake. */
+ GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */
};
struct drbd_bitmap; /* opaque for drbd_conf */
@@ -1171,7 +1181,7 @@ extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf
/* Meta data layout
We reserve a 128MB Block (4k aligned)
* either at the end of the backing device
- * or on a seperate meta data device. */
+ * or on a separate meta data device. */
#define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */
/* The following numbers are sectors */
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index ab871e00ffc..93d1f9b469d 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1668,7 +1668,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
int drbd_send_protocol(struct drbd_conf *mdev)
{
struct p_protocol *p;
- int size, rv;
+ int size, cf, rv;
size = sizeof(struct p_protocol);
@@ -1685,9 +1685,22 @@ int drbd_send_protocol(struct drbd_conf *mdev)
p->after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p);
p->after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p);
p->after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p);
- p->want_lose = cpu_to_be32(mdev->net_conf->want_lose);
p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
+ cf = 0;
+ if (mdev->net_conf->want_lose)
+ cf |= CF_WANT_LOSE;
+ if (mdev->net_conf->dry_run) {
+ if (mdev->agreed_pro_version >= 92)
+ cf |= CF_DRY_RUN;
+ else {
+ dev_err(DEV, "--dry-run is not supported by peer");
+ kfree(p);
+ return 0;
+ }
+ }
+ p->conn_flags = cpu_to_be32(cf);
+
if (mdev->agreed_pro_version >= 87)
strcpy(p->integrity_alg, mdev->net_conf->integrity_alg);
@@ -3161,14 +3174,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
void drbd_free_sock(struct drbd_conf *mdev)
{
if (mdev->data.socket) {
+ mutex_lock(&mdev->data.mutex);
kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR);
sock_release(mdev->data.socket);
mdev->data.socket = NULL;
+ mutex_unlock(&mdev->data.mutex);
}
if (mdev->meta.socket) {
+ mutex_lock(&mdev->meta.mutex);
kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR);
sock_release(mdev->meta.socket);
mdev->meta.socket = NULL;
+ mutex_unlock(&mdev->meta.mutex);
}
}
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 4df3b40b105..6429d2b19e0 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -285,8 +285,8 @@ int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
}
if (r == SS_NO_UP_TO_DATE_DISK && force &&
- (mdev->state.disk == D_INCONSISTENT ||
- mdev->state.disk == D_OUTDATED)) {
+ (mdev->state.disk < D_UP_TO_DATE &&
+ mdev->state.disk >= D_INCONSISTENT)) {
mask.disk = D_MASK;
val.disk = D_UP_TO_DATE;
forced = 1;
@@ -407,7 +407,7 @@ static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
}
reply->ret_code =
- drbd_set_role(mdev, R_PRIMARY, primary_args.overwrite_peer);
+ drbd_set_role(mdev, R_PRIMARY, primary_args.primary_force);
return 0;
}
@@ -941,6 +941,25 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
drbd_md_set_sector_offsets(mdev, nbc);
+ /* allocate a second IO page if logical_block_size != 512 */
+ logical_block_size = bdev_logical_block_size(nbc->md_bdev);
+ if (logical_block_size == 0)
+ logical_block_size = MD_SECTOR_SIZE;
+
+ if (logical_block_size != MD_SECTOR_SIZE) {
+ if (!mdev->md_io_tmpp) {
+ struct page *page = alloc_page(GFP_NOIO);
+ if (!page)
+ goto force_diskless_dec;
+
+ dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
+ logical_block_size, MD_SECTOR_SIZE);
+ dev_warn(DEV, "Workaround engaged (has performance impact).\n");
+
+ mdev->md_io_tmpp = page;
+ }
+ }
+
if (!mdev->bitmap) {
if (drbd_bm_init(mdev)) {
retcode = ERR_NOMEM;
@@ -980,25 +999,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
goto force_diskless_dec;
}
- /* allocate a second IO page if logical_block_size != 512 */
- logical_block_size = bdev_logical_block_size(nbc->md_bdev);
- if (logical_block_size == 0)
- logical_block_size = MD_SECTOR_SIZE;
-
- if (logical_block_size != MD_SECTOR_SIZE) {
- if (!mdev->md_io_tmpp) {
- struct page *page = alloc_page(GFP_NOIO);
- if (!page)
- goto force_diskless_dec;
-
- dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
- logical_block_size, MD_SECTOR_SIZE);
- dev_warn(DEV, "Workaround engaged (has performance impact).\n");
-
- mdev->md_io_tmpp = page;
- }
- }
-
/* Reset the "barriers don't work" bits here, then force meta data to
* be written, to ensure we determine if barriers are supported. */
if (nbc->dc.no_md_flush)
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c
index df8ad9660d8..be3374b6846 100644
--- a/drivers/block/drbd/drbd_proc.c
+++ b/drivers/block/drbd/drbd_proc.c
@@ -28,7 +28,6 @@
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/file.h>
-#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/drbd.h>
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index d065c646b35..3f096e7959b 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -899,7 +899,8 @@ retry:
drbd_thread_start(&mdev->asender);
- drbd_send_protocol(mdev);
+ if (!drbd_send_protocol(mdev))
+ return -1;
drbd_send_sync_param(mdev, &mdev->sync_conf);
drbd_send_sizes(mdev, 0);
drbd_send_uuids(mdev);
@@ -2513,6 +2514,10 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
}
if (hg == -100) {
+ /* FIXME this log message is not correct if we end up here
+ * after an attempted attach on a diskless node.
+ * We just refuse to attach -- well, we drop the "connection"
+ * to that disk, in a way... */
dev_alert(DEV, "Split-Brain detected, dropping connection!\n");
drbd_khelper(mdev, "split-brain");
return C_MASK;
@@ -2538,6 +2543,16 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
}
}
+ if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) {
+ if (hg == 0)
+ dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n");
+ else
+ dev_info(DEV, "dry-run connect: Would become %s, doing a %s resync.",
+ drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET),
+ abs(hg) >= 2 ? "full" : "bit-map based");
+ return C_MASK;
+ }
+
if (abs(hg) >= 2) {
dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n");
if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake"))
@@ -2585,7 +2600,7 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h)
struct p_protocol *p = (struct p_protocol *)h;
int header_size, data_size;
int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
- int p_want_lose, p_two_primaries;
+ int p_want_lose, p_two_primaries, cf;
char p_integrity_alg[SHARED_SECRET_MAX] = "";
header_size = sizeof(*p) - sizeof(*h);
@@ -2598,8 +2613,14 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h)
p_after_sb_0p = be32_to_cpu(p->after_sb_0p);
p_after_sb_1p = be32_to_cpu(p->after_sb_1p);
p_after_sb_2p = be32_to_cpu(p->after_sb_2p);
- p_want_lose = be32_to_cpu(p->want_lose);
p_two_primaries = be32_to_cpu(p->two_primaries);
+ cf = be32_to_cpu(p->conn_flags);
+ p_want_lose = cf & CF_WANT_LOSE;
+
+ clear_bit(CONN_DRY_RUN, &mdev->flags);
+
+ if (cf & CF_DRY_RUN)
+ set_bit(CONN_DRY_RUN, &mdev->flags);
if (p_proto != mdev->net_conf->wire_protocol) {
dev_err(DEV, "incompatible communication protocols\n");
@@ -3118,13 +3139,16 @@ static int receive_state(struct drbd_conf *mdev, struct p_header *h)
put_ldev(mdev);
if (nconn == C_MASK) {
+ nconn = C_CONNECTED;
if (mdev->state.disk == D_NEGOTIATING) {
drbd_force_state(mdev, NS(disk, D_DISKLESS));
- nconn = C_CONNECTED;
} else if (peer_state.disk == D_NEGOTIATING) {
dev_err(DEV, "Disk attach process on the peer node was aborted.\n");
peer_state.disk = D_DISKLESS;
+ real_peer_disk = D_DISKLESS;
} else {
+ if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags))
+ return FALSE;
D_ASSERT(oconn == C_WF_REPORT_PARAMS);
drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
return FALSE;
@@ -3594,10 +3618,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
/* asender does not clean up anything. it must not interfere, either */
drbd_thread_stop(&mdev->asender);
-
- mutex_lock(&mdev->data.mutex);
drbd_free_sock(mdev);
- mutex_unlock(&mdev->data.mutex);
spin_lock_irq(&mdev->req_lock);
_drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
@@ -4054,6 +4075,8 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header *h)
{
/* restore idle timeout */
mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
+ if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags))
+ wake_up(&mdev->misc_wait);
return TRUE;
}
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index f22c1bc8ec7..16119d7056c 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -57,7 +57,7 @@
*
* It may me handed over to the local disk subsystem.
* It may be completed by the local disk subsystem,
- * either sucessfully or with io-error.
+ * either successfully or with io-error.
* In case it is a READ request, and it failed locally,
* it may be retried remotely.
*
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index b453c2bca3b..44bf6d11197 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -938,7 +938,8 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
if (eq) {
drbd_set_in_sync(mdev, e->sector, e->size);
- mdev->rs_same_csum++;
+ /* rs_same_csums unit is BM_BLOCK_SIZE */
+ mdev->rs_same_csum += e->size >> BM_BLOCK_SHIFT;
ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e);
} else {
inc_rs_pending(mdev);
@@ -1288,6 +1289,14 @@ int drbd_alter_sa(struct drbd_conf *mdev, int na)
return retcode;
}
+static void ping_peer(struct drbd_conf *mdev)
+{
+ clear_bit(GOT_PING_ACK, &mdev->flags);
+ request_ping(mdev);
+ wait_event(mdev->misc_wait,
+ test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED);
+}
+
/**
* drbd_start_resync() - Start the resync process
* @mdev: DRBD device.
@@ -1371,7 +1380,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
_drbd_pause_after(mdev);
}
write_unlock_irq(&global_state_lock);
- drbd_state_unlock(mdev);
put_ldev(mdev);
if (r == SS_SUCCESS) {
@@ -1382,11 +1390,8 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
if (mdev->rs_total == 0) {
/* Peer still reachable? Beware of failing before-resync-target handlers! */
- request_ping(mdev);
- __set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(mdev->net_conf->ping_timeo*HZ/9); /* 9 instead 10 */
+ ping_peer(mdev);
drbd_resync_finished(mdev);
- return;
}
/* ns.conn may already be != mdev->state.conn,
@@ -1398,6 +1403,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
drbd_md_sync(mdev);
}
+ drbd_state_unlock(mdev);
}
int drbd_worker(struct drbd_thread *thi)
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index b9b117059b6..90c4038702d 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -144,13 +144,23 @@
* Better audit of register_blkdev.
*/
-#define FLOPPY_SANITY_CHECK
#undef FLOPPY_SILENT_DCL_CLEAR
#define REALLY_SLOW_IO
#define DEBUGT 2
-#define DCL_DEBUG /* debug disk change line */
+
+#define DPRINT(format, args...) \
+ pr_info("floppy%d: " format, current_drive, ##args)
+
+#define DCL_DEBUG /* debug disk change line */
+#ifdef DCL_DEBUG
+#define debug_dcl(test, fmt, args...) \
+ do { if ((test) & FD_DEBUG) DPRINT(fmt, ##args); } while (0)
+#else
+#define debug_dcl(test, fmt, args...) \
+ do { if (0) DPRINT(fmt, ##args); } while (0)
+#endif
/* do print messages for unexpected interrupts */
static int print_unex = 1;
@@ -180,6 +190,8 @@ static int print_unex = 1;
#include <linux/mod_devicetable.h>
#include <linux/buffer_head.h> /* for invalidate_buffers() */
#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
/*
* PS/2 floppies have much slower step rates than regular floppies.
@@ -191,8 +203,6 @@ static int slow_floppy;
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
static int FLOPPY_IRQ = 6;
static int FLOPPY_DMA = 2;
@@ -241,8 +251,6 @@ static int allowed_drive_mask = 0x33;
static int irqdma_allocated;
-#define DEVICE_NAME "floppy"
-
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/cdrom.h> /* for the compatibility eject ioctl */
@@ -250,7 +258,7 @@ static int irqdma_allocated;
static struct request *current_req;
static struct request_queue *floppy_queue;
-static void do_fd_request(struct request_queue * q);
+static void do_fd_request(struct request_queue *q);
#ifndef fd_get_dma_residue
#define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA)
@@ -263,7 +271,7 @@ static void do_fd_request(struct request_queue * q);
#endif
#ifndef fd_dma_mem_alloc
-#define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
+#define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL, get_order(size))
#endif
static inline void fallback_on_nodma_alloc(char **addr, size_t l)
@@ -273,7 +281,7 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l)
return; /* we have the memory */
if (can_use_virtual_dma != 2)
return; /* no fallback allowed */
- printk("DMA memory shortage. Temporarily falling back on virtual DMA\n");
+ pr_info("DMA memory shortage. Temporarily falling back on virtual DMA\n");
*addr = (char *)nodma_mem_alloc(l);
#else
return;
@@ -283,59 +291,50 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l)
/* End dma memory related stuff */
static unsigned long fake_change;
-static int initialising = 1;
+static bool initialized;
-#define ITYPE(x) (((x)>>2) & 0x1f)
-#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
-#define UNIT(x) ((x) & 0x03) /* drive on fdc */
-#define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */
+#define ITYPE(x) (((x) >> 2) & 0x1f)
+#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
+#define UNIT(x) ((x) & 0x03) /* drive on fdc */
+#define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */
/* reverse mapping from unit and fdc to drive */
#define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2))
-#define DP (&drive_params[current_drive])
-#define DRS (&drive_state[current_drive])
-#define DRWE (&write_errors[current_drive])
-#define FDCS (&fdc_state[fdc])
-#define CLEARF(x) clear_bit(x##_BIT, &DRS->flags)
-#define SETF(x) set_bit(x##_BIT, &DRS->flags)
-#define TESTF(x) test_bit(x##_BIT, &DRS->flags)
-#define UDP (&drive_params[drive])
-#define UDRS (&drive_state[drive])
-#define UDRWE (&write_errors[drive])
-#define UFDCS (&fdc_state[FDC(drive)])
-#define UCLEARF(x) clear_bit(x##_BIT, &UDRS->flags)
-#define USETF(x) set_bit(x##_BIT, &UDRS->flags)
-#define UTESTF(x) test_bit(x##_BIT, &UDRS->flags)
+#define DP (&drive_params[current_drive])
+#define DRS (&drive_state[current_drive])
+#define DRWE (&write_errors[current_drive])
+#define FDCS (&fdc_state[fdc])
-#define DPRINT(format, args...) printk(DEVICE_NAME "%d: " format, current_drive , ## args)
+#define UDP (&drive_params[drive])
+#define UDRS (&drive_state[drive])
+#define UDRWE (&write_errors[drive])
+#define UFDCS (&fdc_state[FDC(drive)])
-#define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2)
-#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
-
-#define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x)))
+#define PH_HEAD(floppy, head) (((((floppy)->stretch & 2) >> 1) ^ head) << 2)
+#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
/* read/write */
-#define COMMAND raw_cmd->cmd[0]
-#define DR_SELECT raw_cmd->cmd[1]
-#define TRACK raw_cmd->cmd[2]
-#define HEAD raw_cmd->cmd[3]
-#define SECTOR raw_cmd->cmd[4]
-#define SIZECODE raw_cmd->cmd[5]
-#define SECT_PER_TRACK raw_cmd->cmd[6]
-#define GAP raw_cmd->cmd[7]
-#define SIZECODE2 raw_cmd->cmd[8]
+#define COMMAND (raw_cmd->cmd[0])
+#define DR_SELECT (raw_cmd->cmd[1])
+#define TRACK (raw_cmd->cmd[2])
+#define HEAD (raw_cmd->cmd[3])
+#define SECTOR (raw_cmd->cmd[4])
+#define SIZECODE (raw_cmd->cmd[5])
+#define SECT_PER_TRACK (raw_cmd->cmd[6])
+#define GAP (raw_cmd->cmd[7])
+#define SIZECODE2 (raw_cmd->cmd[8])
#define NR_RW 9
/* format */
-#define F_SIZECODE raw_cmd->cmd[2]
-#define F_SECT_PER_TRACK raw_cmd->cmd[3]
-#define F_GAP raw_cmd->cmd[4]
-#define F_FILL raw_cmd->cmd[5]
+#define F_SIZECODE (raw_cmd->cmd[2])
+#define F_SECT_PER_TRACK (raw_cmd->cmd[3])
+#define F_GAP (raw_cmd->cmd[4])
+#define F_FILL (raw_cmd->cmd[5])
#define NR_F 6
/*
- * Maximum disk size (in kilobytes). This default is used whenever the
- * current disk size is unknown.
+ * Maximum disk size (in kilobytes).
+ * This default is used whenever the current disk size is unknown.
* [Now it is rather a minimum]
*/
#define MAX_DISK_SIZE 4 /* 3984 */
@@ -345,16 +344,17 @@ static int initialising = 1;
*/
#define MAX_REPLIES 16
static unsigned char reply_buffer[MAX_REPLIES];
-static int inr; /* size of reply buffer, when called from interrupt */
-#define ST0 (reply_buffer[0])
-#define ST1 (reply_buffer[1])
-#define ST2 (reply_buffer[2])
-#define ST3 (reply_buffer[0]) /* result of GETSTATUS */
-#define R_TRACK (reply_buffer[3])
-#define R_HEAD (reply_buffer[4])
-#define R_SECTOR (reply_buffer[5])
-#define R_SIZECODE (reply_buffer[6])
-#define SEL_DLY (2*HZ/100)
+static int inr; /* size of reply buffer, when called from interrupt */
+#define ST0 (reply_buffer[0])
+#define ST1 (reply_buffer[1])
+#define ST2 (reply_buffer[2])
+#define ST3 (reply_buffer[0]) /* result of GETSTATUS */
+#define R_TRACK (reply_buffer[3])
+#define R_HEAD (reply_buffer[4])
+#define R_SECTOR (reply_buffer[5])
+#define R_SIZECODE (reply_buffer[6])
+
+#define SEL_DLY (2 * HZ / 100)
/*
* this struct defines the different floppy drive types.
@@ -505,9 +505,9 @@ static char floppy_device_name[] = "floppy";
static int probing;
/* Synchronization of FDC access. */
-#define FD_COMMAND_NONE -1
-#define FD_COMMAND_ERROR 2
-#define FD_COMMAND_OKAY 3
+#define FD_COMMAND_NONE -1
+#define FD_COMMAND_ERROR 2
+#define FD_COMMAND_OKAY 3
static volatile int command_status = FD_COMMAND_NONE;
static unsigned long fdc_busy;
@@ -515,11 +515,6 @@ static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
static DECLARE_WAIT_QUEUE_HEAD(command_done);
#define NO_SIGNAL (!interruptible || !signal_pending(current))
-#define CALL(x) if ((x) == -EINTR) return -EINTR
-#define ECALL(x) if ((ret = (x))) return ret;
-#define _WAIT(x,i) CALL(ret=wait_til_done((x),i))
-#define WAIT(x) _WAIT((x),interruptible)
-#define IWAIT(x) _WAIT((x),1)
/* Errors during formatting are counted here. */
static int format_errors;
@@ -545,8 +540,9 @@ static int max_buffer_sectors;
static int *errors;
typedef void (*done_f)(int);
static struct cont_t {
- void (*interrupt)(void); /* this is called after the interrupt of the
- * main command */
+ void (*interrupt)(void);
+ /* this is called after the interrupt of the
+ * main command */
void (*redo)(void); /* this is called to retry the operation */
void (*error)(void); /* this is called to tally an error */
done_f done; /* this is called to say if the operation has
@@ -571,7 +567,6 @@ static void floppy_release_irq_and_dma(void);
* reset doesn't need to be tested before sending commands, because
* output_byte is automatically disabled when reset is set.
*/
-#define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } }
static void reset_fdc(void);
/*
@@ -579,9 +574,9 @@ static void reset_fdc(void);
* information to interrupts. They are the data used for the current
* request.
*/
-#define NO_TRACK -1
-#define NEED_1_RECAL -2
-#define NEED_2_RECAL -3
+#define NO_TRACK -1
+#define NEED_1_RECAL -2
+#define NEED_2_RECAL -3
static int usage_count;
@@ -621,39 +616,35 @@ static inline void set_debugt(void)
debugtimer = jiffies;
}
-static inline void debugt(const char *message)
+static inline void debugt(const char *func, const char *msg)
{
if (DP->flags & DEBUGT)
- printk("%s dtime=%lu\n", message, jiffies - debugtimer);
+ pr_info("%s:%s dtime=%lu\n", func, msg, jiffies - debugtimer);
}
#else
static inline void set_debugt(void) { }
-static inline void debugt(const char *message) { }
+static inline void debugt(const char *func, const char *msg) { }
#endif /* DEBUGT */
-typedef void (*timeout_fn) (unsigned long);
+typedef void (*timeout_fn)(unsigned long);
static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0);
static const char *timeout_message;
-#ifdef FLOPPY_SANITY_CHECK
-static void is_alive(const char *message)
+static void is_alive(const char *func, const char *message)
{
/* this routine checks whether the floppy driver is "alive" */
- if (test_bit(0, &fdc_busy) && command_status < 2
- && !timer_pending(&fd_timeout)) {
- DPRINT("timeout handler died: %s\n", message);
+ if (test_bit(0, &fdc_busy) && command_status < 2 &&
+ !timer_pending(&fd_timeout)) {
+ DPRINT("%s: timeout handler died. %s\n", func, message);
}
}
-#endif
-static void (*do_floppy) (void) = NULL;
-
-#ifdef FLOPPY_SANITY_CHECK
+static void (*do_floppy)(void) = NULL;
#define OLOGSIZE 20
-static void (*lasthandler) (void);
+static void (*lasthandler)(void);
static unsigned long interruptjiffies;
static unsigned long resultjiffies;
static int resultsize;
@@ -666,12 +657,11 @@ static struct output_log {
} output_log[OLOGSIZE];
static int output_log_pos;
-#endif
#define current_reqD -1
#define MAXTIMEOUT -2
-static void __reschedule_timeout(int drive, const char *message, int marg)
+static void __reschedule_timeout(int drive, const char *message)
{
if (drive == current_reqD)
drive = current_drive;
@@ -682,25 +672,22 @@ static void __reschedule_timeout(int drive, const char *message, int marg)
} else
fd_timeout.expires = jiffies + UDP->timeout;
add_timer(&fd_timeout);
- if (UDP->flags & FD_DEBUG) {
- DPRINT("reschedule timeout ");
- printk(message, marg);
- printk("\n");
- }
+ if (UDP->flags & FD_DEBUG)
+ DPRINT("reschedule timeout %s\n", message);
timeout_message = message;
}
-static void reschedule_timeout(int drive, const char *message, int marg)
+static void reschedule_timeout(int drive, const char *message)
{
unsigned long flags;
spin_lock_irqsave(&floppy_lock, flags);
- __reschedule_timeout(drive, message, marg);
+ __reschedule_timeout(drive, message);
spin_unlock_irqrestore(&floppy_lock, flags);
}
-#define INFBOUND(a,b) (a)=max_t(int, a, b)
-#define SUPBOUND(a,b) (a)=min_t(int, a, b)
+#define INFBOUND(a, b) (a) = max_t(int, a, b)
+#define SUPBOUND(a, b) (a) = min_t(int, a, b)
/*
* Bottom half floppy driver.
@@ -739,7 +726,6 @@ static int disk_change(int drive)
{
int fdc = FDC(drive);
-#ifdef FLOPPY_SANITY_CHECK
if (time_before(jiffies, UDRS->select_date + UDP->select_delay))
DPRINT("WARNING disk change called early\n");
if (!(FDCS->dor & (0x10 << UNIT(drive))) ||
@@ -748,31 +734,27 @@ static int disk_change(int drive)
DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive),
(unsigned int)FDCS->dor);
}
-#endif
-#ifdef DCL_DEBUG
- if (UDP->flags & FD_DEBUG) {
- DPRINT("checking disk change line for drive %d\n", drive);
- DPRINT("jiffies=%lu\n", jiffies);
- DPRINT("disk change line=%x\n", fd_inb(FD_DIR) & 0x80);
- DPRINT("flags=%lx\n", UDRS->flags);
- }
-#endif
+ debug_dcl(UDP->flags,
+ "checking disk change line for drive %d\n", drive);
+ debug_dcl(UDP->flags, "jiffies=%lu\n", jiffies);
+ debug_dcl(UDP->flags, "disk change line=%x\n", fd_inb(FD_DIR) & 0x80);
+ debug_dcl(UDP->flags, "flags=%lx\n", UDRS->flags);
+
if (UDP->flags & FD_BROKEN_DCL)
- return UTESTF(FD_DISK_CHANGED);
+ return test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) {
- USETF(FD_VERIFY); /* verify write protection */
- if (UDRS->maxblock) {
- /* mark it changed */
- USETF(FD_DISK_CHANGED);
- }
+ set_bit(FD_VERIFY_BIT, &UDRS->flags);
+ /* verify write protection */
+
+ if (UDRS->maxblock) /* mark it changed */
+ set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
/* invalidate its geometry */
if (UDRS->keep_data >= 0) {
if ((UDP->flags & FTD_MSG) &&
current_type[drive] != NULL)
- DPRINT("Disk type is undefined after "
- "disk change\n");
+ DPRINT("Disk type is undefined after disk change\n");
current_type[drive] = NULL;
floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1;
}
@@ -780,7 +762,7 @@ static int disk_change(int drive)
return 1;
} else {
UDRS->last_checked = jiffies;
- UCLEARF(FD_DISK_NEWCHANGE);
+ clear_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags);
}
return 0;
}
@@ -790,6 +772,12 @@ static inline int is_selected(int dor, int unit)
return ((dor & (0x10 << unit)) && (dor & 3) == unit);
}
+static bool is_ready_state(int status)
+{
+ int state = status & (STATUS_READY | STATUS_DIR | STATUS_DMA);
+ return state == STATUS_READY;
+}
+
static int set_dor(int fdc, char mask, char data)
{
unsigned char unit;
@@ -806,11 +794,8 @@ static int set_dor(int fdc, char mask, char data)
unit = olddor & 0x3;
if (is_selected(olddor, unit) && !is_selected(newdor, unit)) {
drive = REVDRIVE(fdc, unit);
-#ifdef DCL_DEBUG
- if (UDP->flags & FD_DEBUG) {
- DPRINT("calling disk change from set_dor\n");
- }
-#endif
+ debug_dcl(UDP->flags,
+ "calling disk change from set_dor\n");
disk_change(drive);
}
FDCS->dor = newdor;
@@ -834,8 +819,10 @@ static void twaddle(void)
DRS->select_date = jiffies;
}
-/* reset all driver information about the current fdc. This is needed after
- * a reset, and after a raw command. */
+/*
+ * Reset all driver information about the current fdc.
+ * This is needed after a reset, and after a raw command.
+ */
static void reset_fdc_info(int mode)
{
int drive;
@@ -857,7 +844,7 @@ static void set_fdc(int drive)
current_drive = drive;
}
if (fdc != 1 && fdc != 0) {
- printk("bad fdc value\n");
+ pr_info("bad fdc value\n");
return;
}
set_dor(fdc, ~0, 8);
@@ -871,11 +858,10 @@ static void set_fdc(int drive)
}
/* locks the driver */
-static int _lock_fdc(int drive, int interruptible, int line)
+static int _lock_fdc(int drive, bool interruptible, int line)
{
if (!usage_count) {
- printk(KERN_ERR
- "Trying to lock fdc while usage count=0 at line %d\n",
+ pr_err("Trying to lock fdc while usage count=0 at line %d\n",
line);
return -1;
}
@@ -904,15 +890,13 @@ static int _lock_fdc(int drive, int interruptible, int line)
}
command_status = FD_COMMAND_NONE;
- __reschedule_timeout(drive, "lock fdc", 0);
+ __reschedule_timeout(drive, "lock fdc");
set_fdc(drive);
return 0;
}
-#define lock_fdc(drive,interruptible) _lock_fdc(drive,interruptible, __LINE__)
-
-#define LOCK_FDC(drive,interruptible) \
-if (lock_fdc(drive,interruptible)) return -EINTR;
+#define lock_fdc(drive, interruptible) \
+ _lock_fdc(drive, interruptible, __LINE__)
/* unlocks the driver */
static inline void unlock_fdc(void)
@@ -924,7 +908,7 @@ static inline void unlock_fdc(void)
DPRINT("FDC access conflict!\n");
if (do_floppy)
- DPRINT("device interrupt still active at FDC release: %p!\n",
+ DPRINT("device interrupt still active at FDC release: %pf!\n",
do_floppy);
command_status = FD_COMMAND_NONE;
spin_lock_irqsave(&floppy_lock, flags);
@@ -1003,7 +987,7 @@ static void empty(void)
static DECLARE_WORK(floppy_work, NULL);
-static void schedule_bh(void (*handler) (void))
+static void schedule_bh(void (*handler)(void))
{
PREPARE_WORK(&floppy_work, (work_func_t)handler);
schedule_work(&floppy_work);
@@ -1026,11 +1010,7 @@ static void cancel_activity(void)
* transfer */
static void fd_watchdog(void)
{
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("calling disk change from watchdog\n");
- }
-#endif
+ debug_dcl(DP->flags, "calling disk change from watchdog\n");
if (disk_change(current_drive)) {
DPRINT("disk removed during i/o\n");
@@ -1039,7 +1019,7 @@ static void fd_watchdog(void)
reset_fdc();
} else {
del_timer(&fd_timer);
- fd_timer.function = (timeout_fn) fd_watchdog;
+ fd_timer.function = (timeout_fn)fd_watchdog;
fd_timer.expires = jiffies + HZ / 10;
add_timer(&fd_timer);
}
@@ -1105,25 +1085,23 @@ static void setup_DMA(void)
{
unsigned long f;
-#ifdef FLOPPY_SANITY_CHECK
if (raw_cmd->length == 0) {
int i;
- printk("zero dma transfer size:");
+ pr_info("zero dma transfer size:");
for (i = 0; i < raw_cmd->cmd_count; i++)
- printk("%x,", raw_cmd->cmd[i]);
- printk("\n");
+ pr_cont("%x,", raw_cmd->cmd[i]);
+ pr_cont("\n");
cont->done(0);
FDCS->reset = 1;
return;
}
if (((unsigned long)raw_cmd->kernel_data) % 512) {
- printk("non aligned address: %p\n", raw_cmd->kernel_data);
+ pr_info("non aligned address: %p\n", raw_cmd->kernel_data);
cont->done(0);
FDCS->reset = 1;
return;
}
-#endif
f = claim_dma_lock();
fd_disable_dma();
#ifdef fd_dma_setup
@@ -1165,7 +1143,7 @@ static int wait_til_ready(void)
if (status & STATUS_READY)
return status;
}
- if (!initialising) {
+ if (initialized) {
DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc);
show_floppy();
}
@@ -1176,22 +1154,21 @@ static int wait_til_ready(void)
/* sends a command byte to the fdc */
static int output_byte(char byte)
{
- int status;
+ int status = wait_til_ready();
- if ((status = wait_til_ready()) < 0)
+ if (status < 0)
return -1;
- if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) {
+
+ if (is_ready_state(status)) {
fd_outb(byte, FD_DATA);
-#ifdef FLOPPY_SANITY_CHECK
output_log[output_log_pos].data = byte;
output_log[output_log_pos].status = status;
output_log[output_log_pos].jiffies = jiffies;
output_log_pos = (output_log_pos + 1) % OLOGSIZE;
-#endif
return 0;
}
FDCS->reset = 1;
- if (!initialising) {
+ if (initialized) {
DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
byte, fdc, status);
show_floppy();
@@ -1199,8 +1176,6 @@ static int output_byte(char byte)
return -1;
}
-#define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;}
-
/* gets the response from the fdc */
static int result(void)
{
@@ -1208,14 +1183,13 @@ static int result(void)
int status = 0;
for (i = 0; i < MAX_REPLIES; i++) {
- if ((status = wait_til_ready()) < 0)
+ status = wait_til_ready();
+ if (status < 0)
break;
status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
if ((status & ~STATUS_BUSY) == STATUS_READY) {
-#ifdef FLOPPY_SANITY_CHECK
resultjiffies = jiffies;
resultsize = i;
-#endif
return i;
}
if (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
@@ -1223,10 +1197,9 @@ static int result(void)
else
break;
}
- if (!initialising) {
- DPRINT
- ("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
- fdc, status, i);
+ if (initialized) {
+ DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
+ fdc, status, i);
show_floppy();
}
FDCS->reset = 1;
@@ -1237,12 +1210,14 @@ static int result(void)
/* does the fdc need more output? */
static int need_more_output(void)
{
- int status;
+ int status = wait_til_ready();
- if ((status = wait_til_ready()) < 0)
+ if (status < 0)
return -1;
- if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
+
+ if (is_ready_state(status))
return MORE_OUTPUT;
+
return result();
}
@@ -1264,9 +1239,12 @@ static inline void perpendicular_mode(void)
default:
DPRINT("Invalid data rate for perpendicular mode!\n");
cont->done(0);
- FDCS->reset = 1; /* convenient way to return to
- * redo without to much hassle (deep
- * stack et al. */
+ FDCS->reset = 1;
+ /*
+ * convenient way to return to
+ * redo without too much hassle
+ * (deep stack et al.)
+ */
return;
}
} else
@@ -1366,9 +1344,9 @@ static void fdc_specify(void)
/* Convert step rate from microseconds to milliseconds and 4 bits */
srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR);
- if (slow_floppy) {
+ if (slow_floppy)
srt = srt / 4;
- }
+
SUPBOUND(srt, 0xf);
INFBOUND(srt, 0);
@@ -1415,16 +1393,46 @@ static int fdc_dtr(void)
* Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
*/
FDCS->dtr = raw_cmd->rate & 3;
- return (fd_wait_for_completion(jiffies + 2UL * HZ / 100,
- (timeout_fn) floppy_ready));
+ return fd_wait_for_completion(jiffies + 2UL * HZ / 100,
+ (timeout_fn)floppy_ready);
} /* fdc_dtr */
static void tell_sector(void)
{
- printk(": track %d, head %d, sector %d, size %d",
- R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
+ pr_cont(": track %d, head %d, sector %d, size %d",
+ R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
} /* tell_sector */
+static void print_errors(void)
+{
+ DPRINT("");
+ if (ST0 & ST0_ECE) {
+ pr_cont("Recalibrate failed!");
+ } else if (ST2 & ST2_CRC) {
+ pr_cont("data CRC error");
+ tell_sector();
+ } else if (ST1 & ST1_CRC) {
+ pr_cont("CRC error");
+ tell_sector();
+ } else if ((ST1 & (ST1_MAM | ST1_ND)) ||
+ (ST2 & ST2_MAM)) {
+ if (!probing) {
+ pr_cont("sector not found");
+ tell_sector();
+ } else
+ pr_cont("probe failed...");
+ } else if (ST2 & ST2_WC) { /* seek error */
+ pr_cont("wrong cylinder");
+ } else if (ST2 & ST2_BC) { /* cylinder marked as bad */
+ pr_cont("bad cylinder");
+ } else {
+ pr_cont("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x",
+ ST0, ST1, ST2);
+ tell_sector();
+ }
+ pr_cont("\n");
+}
+
/*
* OK, this error interpreting routine is called after a
* DMA read/write has succeeded
@@ -1437,7 +1445,7 @@ static int interpret_errors(void)
char bad;
if (inr != 7) {
- DPRINT("-- FDC reply error");
+ DPRINT("-- FDC reply error\n");
FDCS->reset = 1;
return 1;
}
@@ -1450,43 +1458,17 @@ static int interpret_errors(void)
bad = 1;
if (ST1 & ST1_WP) {
DPRINT("Drive is write protected\n");
- CLEARF(FD_DISK_WRITABLE);
+ clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
cont->done(0);
bad = 2;
} else if (ST1 & ST1_ND) {
- SETF(FD_NEED_TWADDLE);
+ set_bit(FD_NEED_TWADDLE_BIT, &DRS->flags);
} else if (ST1 & ST1_OR) {
if (DP->flags & FTD_MSG)
DPRINT("Over/Underrun - retrying\n");
bad = 0;
} else if (*errors >= DP->max_errors.reporting) {
- DPRINT("");
- if (ST0 & ST0_ECE) {
- printk("Recalibrate failed!");
- } else if (ST2 & ST2_CRC) {
- printk("data CRC error");
- tell_sector();
- } else if (ST1 & ST1_CRC) {
- printk("CRC error");
- tell_sector();
- } else if ((ST1 & (ST1_MAM | ST1_ND))
- || (ST2 & ST2_MAM)) {
- if (!probing) {
- printk("sector not found");
- tell_sector();
- } else
- printk("probe failed...");
- } else if (ST2 & ST2_WC) { /* seek error */
- printk("wrong cylinder");
- } else if (ST2 & ST2_BC) { /* cylinder marked as bad */
- printk("bad cylinder");
- } else {
- printk
- ("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x",
- ST0, ST1, ST2);
- tell_sector();
- }
- printk("\n");
+ print_errors();
}
if (ST2 & ST2_WC || ST2 & ST2_BC)
/* wrong cylinder => recal */
@@ -1531,9 +1513,9 @@ static void setup_rw_floppy(void)
*/
if (time_after(ready_date, jiffies + DP->select_delay)) {
ready_date -= DP->select_delay;
- function = (timeout_fn) floppy_start;
+ function = (timeout_fn)floppy_start;
} else
- function = (timeout_fn) setup_rw_floppy;
+ function = (timeout_fn)setup_rw_floppy;
/* wait until the floppy is spinning fast enough */
if (fd_wait_for_completion(ready_date, function))
@@ -1551,7 +1533,7 @@ static void setup_rw_floppy(void)
for (i = 0; i < raw_cmd->cmd_count; i++)
r |= output_byte(raw_cmd->cmd[i]);
- debugt("rw_command: ");
+ debugt(__func__, "rw_command");
if (r) {
cont->error();
@@ -1574,7 +1556,7 @@ static int blind_seek;
*/
static void seek_interrupt(void)
{
- debugt("seek interrupt:");
+ debugt(__func__, "");
if (inr != 2 || (ST0 & 0xF8) != 0x20) {
DPRINT("seek failed\n");
DRS->track = NEED_2_RECAL;
@@ -1583,14 +1565,11 @@ static void seek_interrupt(void)
return;
}
if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) {
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT
- ("clearing NEWCHANGE flag because of effective seek\n");
- DPRINT("jiffies=%lu\n", jiffies);
- }
-#endif
- CLEARF(FD_DISK_NEWCHANGE); /* effective seek */
+ debug_dcl(DP->flags,
+ "clearing NEWCHANGE flag because of effective seek\n");
+ debug_dcl(DP->flags, "jiffies=%lu\n", jiffies);
+ clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
+ /* effective seek */
DRS->select_date = jiffies;
}
DRS->track = ST1;
@@ -1599,26 +1578,23 @@ static void seek_interrupt(void)
static void check_wp(void)
{
- if (TESTF(FD_VERIFY)) {
- /* check write protection */
+ if (test_bit(FD_VERIFY_BIT, &DRS->flags)) {
+ /* check write protection */
output_byte(FD_GETSTATUS);
output_byte(UNIT(current_drive));
if (result() != 1) {
FDCS->reset = 1;
return;
}
- CLEARF(FD_VERIFY);
- CLEARF(FD_NEED_TWADDLE);
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("checking whether disk is write protected\n");
- DPRINT("wp=%x\n", ST3 & 0x40);
- }
-#endif
+ clear_bit(FD_VERIFY_BIT, &DRS->flags);
+ clear_bit(FD_NEED_TWADDLE_BIT, &DRS->flags);
+ debug_dcl(DP->flags,
+ "checking whether disk is write protected\n");
+ debug_dcl(DP->flags, "wp=%x\n", ST3 & 0x40);
if (!(ST3 & 0x40))
- SETF(FD_DISK_WRITABLE);
+ set_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
else
- CLEARF(FD_DISK_WRITABLE);
+ clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
}
}
@@ -1628,19 +1604,15 @@ static void seek_floppy(void)
blind_seek = 0;
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("calling disk change from seek\n");
- }
-#endif
+ debug_dcl(DP->flags, "calling disk change from %s\n", __func__);
- if (!TESTF(FD_DISK_NEWCHANGE) &&
+ if (!test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) &&
disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) {
/* the media changed flag should be cleared after the seek.
* If it isn't, this means that there is really no disk in
* the drive.
*/
- SETF(FD_DISK_CHANGED);
+ set_bit(FD_DISK_CHANGED_BIT, &DRS->flags);
cont->done(0);
cont->redo();
return;
@@ -1648,7 +1620,7 @@ static void seek_floppy(void)
if (DRS->track <= NEED_1_RECAL) {
recalibrate_floppy();
return;
- } else if (TESTF(FD_DISK_NEWCHANGE) &&
+ } else if (test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) &&
(raw_cmd->flags & FD_RAW_NEED_DISK) &&
(DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) {
/* we seek to clear the media-changed condition. Does anybody
@@ -1677,19 +1649,22 @@ static void seek_floppy(void)
do_floppy = seek_interrupt;
output_byte(FD_SEEK);
output_byte(UNIT(current_drive));
- LAST_OUT(track);
- debugt("seek command:");
+ if (output_byte(track) < 0) {
+ reset_fdc();
+ return;
+ }
+ debugt(__func__, "");
}
static void recal_interrupt(void)
{
- debugt("recal interrupt:");
+ debugt(__func__, "");
if (inr != 2)
FDCS->reset = 1;
else if (ST0 & ST0_ECE) {
switch (DRS->track) {
case NEED_1_RECAL:
- debugt("recal interrupt need 1 recal:");
+ debugt(__func__, "need 1 recal");
/* after a second recalibrate, we still haven't
* reached track 0. Probably no drive. Raise an
* error, as failing immediately might upset
@@ -1698,25 +1673,21 @@ static void recal_interrupt(void)
cont->redo();
return;
case NEED_2_RECAL:
- debugt("recal interrupt need 2 recal:");
+ debugt(__func__, "need 2 recal");
/* If we already did a recalibrate,
* and we are not at track 0, this
* means we have moved. (The only way
* not to move at recalibration is to
* be already at track 0.) Clear the
* new change flag */
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT
- ("clearing NEWCHANGE flag because of second recalibrate\n");
- }
-#endif
+ debug_dcl(DP->flags,
+ "clearing NEWCHANGE flag because of second recalibrate\n");
- CLEARF(FD_DISK_NEWCHANGE);
+ clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
DRS->select_date = jiffies;
/* fall through */
default:
- debugt("recal interrupt default:");
+ debugt(__func__, "default");
/* Recalibrate moves the head by at
* most 80 steps. If after one
* recalibrate we don't have reached
@@ -1738,8 +1709,8 @@ static void print_result(char *message, int inr)
DPRINT("%s ", message);
if (inr >= 0)
for (i = 0; i < inr; i++)
- printk("repl[%d]=%x ", i, reply_buffer[i]);
- printk("\n");
+ pr_cont("repl[%d]=%x ", i, reply_buffer[i]);
+ pr_cont("\n");
}
/* interrupt handler. Note that this can be called externally on the Sparc */
@@ -1760,10 +1731,10 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id)
do_floppy = NULL;
if (fdc >= N_FDC || FDCS->address == -1) {
/* we don't even know which FDC is the culprit */
- printk("DOR0=%x\n", fdc_state[0].dor);
- printk("floppy interrupt on bizarre fdc %d\n", fdc);
- printk("handler=%p\n", handler);
- is_alive("bizarre fdc");
+ pr_info("DOR0=%x\n", fdc_state[0].dor);
+ pr_info("floppy interrupt on bizarre fdc %d\n", fdc);
+ pr_info("handler=%pf\n", handler);
+ is_alive(__func__, "bizarre fdc");
return IRQ_NONE;
}
@@ -1777,7 +1748,7 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id)
* activity.
*/
- do_print = !handler && print_unex && !initialising;
+ do_print = !handler && print_unex && initialized;
inr = result();
if (do_print)
@@ -1790,15 +1761,15 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id)
if (do_print)
print_result("sensei", inr);
max_sensei--;
- } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2
- && max_sensei);
+ } while ((ST0 & 0x83) != UNIT(current_drive) &&
+ inr == 2 && max_sensei);
}
if (!handler) {
FDCS->reset = 1;
return IRQ_NONE;
}
schedule_bh(handler);
- is_alive("normal interrupt end");
+ is_alive(__func__, "normal interrupt end");
/* FIXME! Was it really for us? */
return IRQ_HANDLED;
@@ -1806,10 +1777,11 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id)
static void recalibrate_floppy(void)
{
- debugt("recalibrate floppy:");
+ debugt(__func__, "");
do_floppy = recal_interrupt;
output_byte(FD_RECALIBRATE);
- LAST_OUT(UNIT(current_drive));
+ if (output_byte(UNIT(current_drive)) < 0)
+ reset_fdc();
}
/*
@@ -1817,10 +1789,10 @@ static void recalibrate_floppy(void)
*/
static void reset_interrupt(void)
{
- debugt("reset interrupt:");
+ debugt(__func__, "");
result(); /* get the status ready for set_fdc */
if (FDCS->reset) {
- printk("reset set in interrupt, calling %p\n", cont->error);
+ pr_info("reset set in interrupt, calling %pf\n", cont->error);
cont->error(); /* a reset just after a reset. BAD! */
}
cont->redo();
@@ -1858,53 +1830,49 @@ static void show_floppy(void)
{
int i;
- printk("\n");
- printk("floppy driver state\n");
- printk("-------------------\n");
- printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n",
- jiffies, interruptjiffies, jiffies - interruptjiffies,
- lasthandler);
+ pr_info("\n");
+ pr_info("floppy driver state\n");
+ pr_info("-------------------\n");
+ pr_info("now=%lu last interrupt=%lu diff=%lu last called handler=%pf\n",
+ jiffies, interruptjiffies, jiffies - interruptjiffies,
+ lasthandler);
-#ifdef FLOPPY_SANITY_CHECK
- printk("timeout_message=%s\n", timeout_message);
- printk("last output bytes:\n");
+ pr_info("timeout_message=%s\n", timeout_message);
+ pr_info("last output bytes:\n");
for (i = 0; i < OLOGSIZE; i++)
- printk("%2x %2x %lu\n",
- output_log[(i + output_log_pos) % OLOGSIZE].data,
- output_log[(i + output_log_pos) % OLOGSIZE].status,
- output_log[(i + output_log_pos) % OLOGSIZE].jiffies);
- printk("last result at %lu\n", resultjiffies);
- printk("last redo_fd_request at %lu\n", lastredo);
- for (i = 0; i < resultsize; i++) {
- printk("%2x ", reply_buffer[i]);
- }
- printk("\n");
-#endif
-
- printk("status=%x\n", fd_inb(FD_STATUS));
- printk("fdc_busy=%lu\n", fdc_busy);
+ pr_info("%2x %2x %lu\n",
+ output_log[(i + output_log_pos) % OLOGSIZE].data,
+ output_log[(i + output_log_pos) % OLOGSIZE].status,
+ output_log[(i + output_log_pos) % OLOGSIZE].jiffies);
+ pr_info("last result at %lu\n", resultjiffies);
+ pr_info("last redo_fd_request at %lu\n", lastredo);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1,
+ reply_buffer, resultsize, true);
+
+ pr_info("status=%x\n", fd_inb(FD_STATUS));
+ pr_info("fdc_busy=%lu\n", fdc_busy);
if (do_floppy)
- printk("do_floppy=%p\n", do_floppy);
+ pr_info("do_floppy=%pf\n", do_floppy);
if (work_pending(&floppy_work))
- printk("floppy_work.func=%p\n", floppy_work.func);
+ pr_info("floppy_work.func=%pf\n", floppy_work.func);
if (timer_pending(&fd_timer))
- printk("fd_timer.function=%p\n", fd_timer.function);
+ pr_info("fd_timer.function=%pf\n", fd_timer.function);
if (timer_pending(&fd_timeout)) {
- printk("timer_function=%p\n", fd_timeout.function);
- printk("expires=%lu\n", fd_timeout.expires - jiffies);
- printk("now=%lu\n", jiffies);
- }
- printk("cont=%p\n", cont);
- printk("current_req=%p\n", current_req);
- printk("command_status=%d\n", command_status);
- printk("\n");
+ pr_info("timer_function=%pf\n", fd_timeout.function);
+ pr_info("expires=%lu\n", fd_timeout.expires - jiffies);
+ pr_info("now=%lu\n", jiffies);
+ }
+ pr_info("cont=%p\n", cont);
+ pr_info("current_req=%p\n", current_req);
+ pr_info("command_status=%d\n", command_status);
+ pr_info("\n");
}
static void floppy_shutdown(unsigned long data)
{
unsigned long flags;
- if (!initialising)
+ if (initialized)
show_floppy();
cancel_activity();
@@ -1916,17 +1884,17 @@ static void floppy_shutdown(unsigned long data)
/* avoid dma going to a random drive after shutdown */
- if (!initialising)
+ if (initialized)
DPRINT("floppy timeout called\n");
FDCS->reset = 1;
if (cont) {
cont->done(0);
cont->redo(); /* this will recall reset when needed */
} else {
- printk("no cont in shutdown!\n");
+ pr_info("no cont in shutdown!\n");
process_fd_request();
}
- is_alive("floppy shutdown");
+ is_alive(__func__, "");
}
/* start motor, check media-changed condition and write protection */
@@ -1954,27 +1922,26 @@ static int start_motor(void (*function)(void))
set_dor(fdc, mask, data);
/* wait_for_completion also schedules reset if needed. */
- return (fd_wait_for_completion(DRS->select_date + DP->select_delay,
- (timeout_fn) function));
+ return fd_wait_for_completion(DRS->select_date + DP->select_delay,
+ (timeout_fn)function);
}
static void floppy_ready(void)
{
- CHECK_RESET;
+ if (FDCS->reset) {
+ reset_fdc();
+ return;
+ }
if (start_motor(floppy_ready))
return;
if (fdc_dtr())
return;
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("calling disk change from floppy_ready\n");
- }
-#endif
+ debug_dcl(DP->flags, "calling disk change from floppy_ready\n");
if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) &&
disk_change(current_drive) && !DP->select_delay)
- twaddle(); /* this clears the dcl on certain drive/controller
- * combinations */
+ twaddle(); /* this clears the dcl on certain
+ * drive/controller combinations */
#ifdef fd_chose_dma_mode
if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) {
@@ -1998,15 +1965,11 @@ static void floppy_ready(void)
static void floppy_start(void)
{
- reschedule_timeout(current_reqD, "floppy start", 0);
+ reschedule_timeout(current_reqD, "floppy start");
scandrives();
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("setting NEWCHANGE in floppy_start\n");
- }
-#endif
- SETF(FD_DISK_NEWCHANGE);
+ debug_dcl(DP->flags, "setting NEWCHANGE in floppy_start\n");
+ set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
floppy_ready();
}
@@ -2026,7 +1989,7 @@ static void floppy_start(void)
static void do_wakeup(void)
{
- reschedule_timeout(MAXTIMEOUT, "do wakeup", 0);
+ reschedule_timeout(MAXTIMEOUT, "do wakeup");
cont = NULL;
command_status += 2;
wake_up(&command_done);
@@ -2046,7 +2009,7 @@ static struct cont_t intr_cont = {
.done = (done_f)empty
};
-static int wait_til_done(void (*handler)(void), int interruptible)
+static int wait_til_done(void (*handler)(void), bool interruptible)
{
int ret;
@@ -2064,7 +2027,7 @@ static int wait_til_done(void (*handler)(void), int interruptible)
if (command_status >= 2 || !NO_SIGNAL)
break;
- is_alive("wait_til_done");
+ is_alive(__func__, "");
schedule();
}
@@ -2180,9 +2143,9 @@ static void format_interrupt(void)
cont->redo();
}
-#define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2)
-#define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1))
+#define FM_MODE(x, y) ((y) & ~(((x)->rate & 0x80) >> 1))
#define CT(x) ((x) | 0xc0)
+
static void setup_format_params(int track)
{
int n;
@@ -2197,8 +2160,8 @@ static void setup_format_params(int track)
raw_cmd = &default_raw_cmd;
raw_cmd->track = track;
- raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
- FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK;
+ raw_cmd->flags = (FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
+ FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK);
raw_cmd->rate = _floppy->rate & 0x43;
raw_cmd->cmd_count = NR_F;
COMMAND = FM_MODE(_floppy, FD_FORMAT);
@@ -2257,7 +2220,7 @@ static void redo_format(void)
buffer_track = -1;
setup_format_params(format_req.track << STRETCH(_floppy));
floppy_start();
- debugt("queue format request");
+ debugt(__func__, "queue format request");
}
static struct cont_t format_cont = {
@@ -2271,7 +2234,9 @@ static int do_format(int drive, struct format_descr *tmp_format_req)
{
int ret;
- LOCK_FDC(drive, 1);
+ if (lock_fdc(drive, true))
+ return -EINTR;
+
set_floppy(drive);
if (!_floppy ||
_floppy->track > DP->tracks ||
@@ -2286,7 +2251,9 @@ static int do_format(int drive, struct format_descr *tmp_format_req)
format_errors = 0;
cont = &format_cont;
errors = &format_errors;
- IWAIT(redo_format);
+ ret = wait_til_done(redo_format, true);
+ if (ret == -EINTR)
+ return -EINTR;
process_fd_request();
return ret;
}
@@ -2320,12 +2287,14 @@ static void request_done(int uptodate)
struct request *req = current_req;
unsigned long flags;
int block;
+ char msg[sizeof("request done ") + sizeof(int) * 3];
probing = 0;
- reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
+ snprintf(msg, sizeof(msg), "request done %d", uptodate);
+ reschedule_timeout(MAXTIMEOUT, msg);
if (!req) {
- printk("floppy.c: no request in request_done\n");
+ pr_info("floppy.c: no request in request_done\n");
return;
}
@@ -2377,7 +2346,7 @@ static void rw_interrupt(void)
DRS->first_read_date = jiffies;
nr_sectors = 0;
- CODE2SIZE;
+ ssize = DIV_ROUND_UP(1 << SIZECODE, 4);
if (ST1 & ST1_EOC)
eoc = 1;
@@ -2393,20 +2362,18 @@ static void rw_interrupt(void)
R_HEAD - HEAD) * SECT_PER_TRACK +
R_SECTOR - SECTOR + eoc) << SIZECODE >> 2;
-#ifdef FLOPPY_SANITY_CHECK
if (nr_sectors / ssize >
DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) {
DPRINT("long rw: %x instead of %lx\n",
nr_sectors, current_count_sectors);
- printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
- printk("rh=%d h=%d\n", R_HEAD, HEAD);
- printk("rt=%d t=%d\n", R_TRACK, TRACK);
- printk("heads=%d eoc=%d\n", heads, eoc);
- printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
- fsector_t, ssize);
- printk("in_sector_offset=%d\n", in_sector_offset);
+ pr_info("rs=%d s=%d\n", R_SECTOR, SECTOR);
+ pr_info("rh=%d h=%d\n", R_HEAD, HEAD);
+ pr_info("rt=%d t=%d\n", R_TRACK, TRACK);
+ pr_info("heads=%d eoc=%d\n", heads, eoc);
+ pr_info("spt=%d st=%d ss=%d\n",
+ SECT_PER_TRACK, fsector_t, ssize);
+ pr_info("in_sector_offset=%d\n", in_sector_offset);
}
-#endif
nr_sectors -= in_sector_offset;
INFBOUND(nr_sectors, 0);
@@ -2511,19 +2478,17 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
blk_rq_sectors(current_req));
remaining = current_count_sectors << 9;
-#ifdef FLOPPY_SANITY_CHECK
if (remaining > blk_rq_bytes(current_req) && CT(COMMAND) == FD_WRITE) {
DPRINT("in copy buffer\n");
- printk("current_count_sectors=%ld\n", current_count_sectors);
- printk("remaining=%d\n", remaining >> 9);
- printk("current_req->nr_sectors=%u\n",
- blk_rq_sectors(current_req));
- printk("current_req->current_nr_sectors=%u\n",
- blk_rq_cur_sectors(current_req));
- printk("max_sector=%d\n", max_sector);
- printk("ssize=%d\n", ssize);
+ pr_info("current_count_sectors=%ld\n", current_count_sectors);
+ pr_info("remaining=%d\n", remaining >> 9);
+ pr_info("current_req->nr_sectors=%u\n",
+ blk_rq_sectors(current_req));
+ pr_info("current_req->current_nr_sectors=%u\n",
+ blk_rq_cur_sectors(current_req));
+ pr_info("max_sector=%d\n", max_sector);
+ pr_info("ssize=%d\n", ssize);
}
-#endif
buffer_max = max(max_sector, buffer_max);
@@ -2539,26 +2504,24 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
SUPBOUND(size, remaining);
buffer = page_address(bv->bv_page) + bv->bv_offset;
-#ifdef FLOPPY_SANITY_CHECK
if (dma_buffer + size >
floppy_track_buffer + (max_buffer_sectors << 10) ||
dma_buffer < floppy_track_buffer) {
DPRINT("buffer overrun in copy buffer %d\n",
- (int)((floppy_track_buffer -
- dma_buffer) >> 9));
- printk("fsector_t=%d buffer_min=%d\n",
- fsector_t, buffer_min);
- printk("current_count_sectors=%ld\n",
- current_count_sectors);
+ (int)((floppy_track_buffer - dma_buffer) >> 9));
+ pr_info("fsector_t=%d buffer_min=%d\n",
+ fsector_t, buffer_min);
+ pr_info("current_count_sectors=%ld\n",
+ current_count_sectors);
if (CT(COMMAND) == FD_READ)
- printk("read\n");
+ pr_info("read\n");
if (CT(COMMAND) == FD_WRITE)
- printk("write\n");
+ pr_info("write\n");
break;
}
if (((unsigned long)buffer) % 512)
DPRINT("%p buffer not aligned\n", buffer);
-#endif
+
if (CT(COMMAND) == FD_READ)
memcpy(buffer, dma_buffer, size);
else
@@ -2567,13 +2530,11 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
remaining -= size;
dma_buffer += size;
}
-#ifdef FLOPPY_SANITY_CHECK
if (remaining) {
if (remaining > 0)
max_sector -= remaining >> 9;
DPRINT("weirdness: remaining %d\n", remaining >> 9);
}
-#endif
}
/* work around a bug in pseudo DMA
@@ -2593,15 +2554,14 @@ static void virtualdmabug_workaround(void)
hard_sectors = raw_cmd->length >> (7 + SIZECODE);
end_sector = SECTOR + hard_sectors - 1;
-#ifdef FLOPPY_SANITY_CHECK
if (end_sector > SECT_PER_TRACK) {
- printk("too many sectors %d > %d\n",
- end_sector, SECT_PER_TRACK);
+ pr_info("too many sectors %d > %d\n",
+ end_sector, SECT_PER_TRACK);
return;
}
-#endif
- SECT_PER_TRACK = end_sector; /* make sure SECT_PER_TRACK points
- * to end of transfer */
+ SECT_PER_TRACK = end_sector;
+ /* make sure SECT_PER_TRACK
+ * points to end of transfer */
}
}
@@ -2624,7 +2584,7 @@ static int make_raw_rw_request(void)
int ssize;
if (max_buffer_sectors == 0) {
- printk("VFS: Block I/O scheduled on unopened device\n");
+ pr_info("VFS: Block I/O scheduled on unopened device\n");
return 0;
}
@@ -2641,7 +2601,7 @@ static int make_raw_rw_request(void)
raw_cmd->flags |= FD_RAW_WRITE;
COMMAND = FM_MODE(_floppy, FD_WRITE);
} else {
- DPRINT("make_raw_rw_request: unknown command\n");
+ DPRINT("%s: unknown command\n", __func__);
return 0;
}
@@ -2659,7 +2619,8 @@ static int make_raw_rw_request(void)
HEAD = fsector_t / _floppy->sect;
if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) ||
- TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect)
+ test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) &&
+ fsector_t < _floppy->sect)
max_sector = _floppy->sect;
/* 2M disks have phantom sectors on the first track */
@@ -2685,7 +2646,7 @@ static int make_raw_rw_request(void)
raw_cmd->track = TRACK << STRETCH(_floppy);
DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, HEAD);
GAP = _floppy->gap;
- CODE2SIZE;
+ ssize = DIV_ROUND_UP(1 << SIZECODE, 4);
SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) +
FD_SECTBASE(_floppy);
@@ -2730,8 +2691,10 @@ static int make_raw_rw_request(void)
}
} else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) {
if (CT(COMMAND) == FD_WRITE) {
- if (fsector_t + blk_rq_sectors(current_req) > ssize &&
- fsector_t + blk_rq_sectors(current_req) < ssize + ssize)
+ unsigned int sectors;
+
+ sectors = fsector_t + blk_rq_sectors(current_req);
+ if (sectors > ssize && sectors < ssize + ssize)
max_size = ssize + ssize;
else
max_size = ssize;
@@ -2752,12 +2715,10 @@ static int make_raw_rw_request(void)
* on a 64 bit machine!
*/
max_size = buffer_chain_size();
- dma_limit =
- (MAX_DMA_ADDRESS -
- ((unsigned long)current_req->buffer)) >> 9;
- if ((unsigned long)max_size > dma_limit) {
+ dma_limit = (MAX_DMA_ADDRESS -
+ ((unsigned long)current_req->buffer)) >> 9;
+ if ((unsigned long)max_size > dma_limit)
max_size = dma_limit;
- }
/* 64 kb boundaries */
if (CROSS_64KB(current_req->buffer, max_size << 9))
max_size = (K_64 -
@@ -2773,16 +2734,16 @@ static int make_raw_rw_request(void)
*/
if (!direct ||
(indirect * 2 > direct * 3 &&
- *errors < DP->max_errors.read_track && ((!probing
- || (DP->read_track & (1 << DRS->probed_format)))))) {
+ *errors < DP->max_errors.read_track &&
+ ((!probing ||
+ (DP->read_track & (1 << DRS->probed_format)))))) {
max_size = blk_rq_sectors(current_req);
} else {
raw_cmd->kernel_data = current_req->buffer;
raw_cmd->length = current_count_sectors << 9;
if (raw_cmd->length == 0) {
- DPRINT
- ("zero dma transfer attempted from make_raw_request\n");
- DPRINT("indirect=%d direct=%d fsector_t=%d",
+ DPRINT("%s: zero dma transfer attempted\n", __func__);
+ DPRINT("indirect=%d direct=%d fsector_t=%d\n",
indirect, direct, fsector_t);
return 0;
}
@@ -2802,25 +2763,22 @@ static int make_raw_rw_request(void)
((CT(COMMAND) == FD_READ ||
(!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) &&
max_sector > 2 * max_buffer_sectors + buffer_min &&
- max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)
- /* not enough space */
- ) {
+ max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)) {
+ /* not enough space */
buffer_track = -1;
buffer_drive = current_drive;
buffer_max = buffer_min = aligned_sector_t;
}
raw_cmd->kernel_data = floppy_track_buffer +
- ((aligned_sector_t - buffer_min) << 9);
+ ((aligned_sector_t - buffer_min) << 9);
if (CT(COMMAND) == FD_WRITE) {
/* copy write buffer to track buffer.
* if we get here, we know that the write
* is either aligned or the data already in the buffer
* (buffer will be overwritten) */
-#ifdef FLOPPY_SANITY_CHECK
if (in_sector_offset && buffer_track == -1)
DPRINT("internal error offset !=0 on write\n");
-#endif
buffer_track = raw_cmd->track;
buffer_drive = current_drive;
copy_buffer(ssize, max_sector,
@@ -2834,7 +2792,6 @@ static int make_raw_rw_request(void)
raw_cmd->length = in_sector_offset + current_count_sectors;
raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1;
raw_cmd->length <<= 9;
-#ifdef FLOPPY_SANITY_CHECK
if ((raw_cmd->length < current_count_sectors << 9) ||
(raw_cmd->kernel_data != current_req->buffer &&
CT(COMMAND) == FD_WRITE &&
@@ -2845,19 +2802,19 @@ static int make_raw_rw_request(void)
DPRINT("fractionary current count b=%lx s=%lx\n",
raw_cmd->length, current_count_sectors);
if (raw_cmd->kernel_data != current_req->buffer)
- printk("addr=%d, length=%ld\n",
- (int)((raw_cmd->kernel_data -
- floppy_track_buffer) >> 9),
- current_count_sectors);
- printk("st=%d ast=%d mse=%d msi=%d\n",
- fsector_t, aligned_sector_t, max_sector, max_size);
- printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
- printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
- COMMAND, SECTOR, HEAD, TRACK);
- printk("buffer drive=%d\n", buffer_drive);
- printk("buffer track=%d\n", buffer_track);
- printk("buffer_min=%d\n", buffer_min);
- printk("buffer_max=%d\n", buffer_max);
+ pr_info("addr=%d, length=%ld\n",
+ (int)((raw_cmd->kernel_data -
+ floppy_track_buffer) >> 9),
+ current_count_sectors);
+ pr_info("st=%d ast=%d mse=%d msi=%d\n",
+ fsector_t, aligned_sector_t, max_sector, max_size);
+ pr_info("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
+ pr_info("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
+ COMMAND, SECTOR, HEAD, TRACK);
+ pr_info("buffer drive=%d\n", buffer_drive);
+ pr_info("buffer track=%d\n", buffer_track);
+ pr_info("buffer_min=%d\n", buffer_min);
+ pr_info("buffer_max=%d\n", buffer_max);
return 0;
}
@@ -2868,14 +2825,14 @@ static int make_raw_rw_request(void)
raw_cmd->kernel_data + raw_cmd->length >
floppy_track_buffer + (max_buffer_sectors << 10)) {
DPRINT("buffer overrun in schedule dma\n");
- printk("fsector_t=%d buffer_min=%d current_count=%ld\n",
- fsector_t, buffer_min, raw_cmd->length >> 9);
- printk("current_count_sectors=%ld\n",
- current_count_sectors);
+ pr_info("fsector_t=%d buffer_min=%d current_count=%ld\n",
+ fsector_t, buffer_min, raw_cmd->length >> 9);
+ pr_info("current_count_sectors=%ld\n",
+ current_count_sectors);
if (CT(COMMAND) == FD_READ)
- printk("read\n");
+ pr_info("read\n");
if (CT(COMMAND) == FD_WRITE)
- printk("write\n");
+ pr_info("write\n");
return 0;
}
} else if (raw_cmd->length > blk_rq_bytes(current_req) ||
@@ -2884,14 +2841,13 @@ static int make_raw_rw_request(void)
return 0;
} else if (raw_cmd->length < current_count_sectors << 9) {
DPRINT("more sectors than bytes\n");
- printk("bytes=%ld\n", raw_cmd->length >> 9);
- printk("sectors=%ld\n", current_count_sectors);
+ pr_info("bytes=%ld\n", raw_cmd->length >> 9);
+ pr_info("sectors=%ld\n", current_count_sectors);
}
if (raw_cmd->length == 0) {
DPRINT("zero dma transfer attempted from make_raw_request\n");
return 0;
}
-#endif
virtualdmabug_workaround();
return 2;
@@ -2899,7 +2855,6 @@ static int make_raw_rw_request(void)
static void redo_fd_request(void)
{
-#define REPEAT {request_done(0); continue; }
int drive;
int tmp;
@@ -2907,63 +2862,63 @@ static void redo_fd_request(void)
if (current_drive < N_DRIVE)
floppy_off(current_drive);
- for (;;) {
- if (!current_req) {
- struct request *req;
-
- spin_lock_irq(floppy_queue->queue_lock);
- req = blk_fetch_request(floppy_queue);
- spin_unlock_irq(floppy_queue->queue_lock);
- if (!req) {
- do_floppy = NULL;
- unlock_fdc();
- return;
- }
- current_req = req;
- }
- drive = (long)current_req->rq_disk->private_data;
- set_fdc(drive);
- reschedule_timeout(current_reqD, "redo fd request", 0);
+do_request:
+ if (!current_req) {
+ struct request *req;
- set_floppy(drive);
- raw_cmd = &default_raw_cmd;
- raw_cmd->flags = 0;
- if (start_motor(redo_fd_request))
+ spin_lock_irq(floppy_queue->queue_lock);
+ req = blk_fetch_request(floppy_queue);
+ spin_unlock_irq(floppy_queue->queue_lock);
+ if (!req) {
+ do_floppy = NULL;
+ unlock_fdc();
return;
- disk_change(current_drive);
- if (test_bit(current_drive, &fake_change) ||
- TESTF(FD_DISK_CHANGED)) {
- DPRINT("disk absent or changed during operation\n");
- REPEAT;
- }
- if (!_floppy) { /* Autodetection */
- if (!probing) {
- DRS->probed_format = 0;
- if (next_valid_format()) {
- DPRINT("no autodetectable formats\n");
- _floppy = NULL;
- REPEAT;
- }
- }
- probing = 1;
- _floppy =
- floppy_type + DP->autodetect[DRS->probed_format];
- } else
- probing = 0;
- errors = &(current_req->errors);
- tmp = make_raw_rw_request();
- if (tmp < 2) {
- request_done(tmp);
- continue;
}
+ current_req = req;
+ }
+ drive = (long)current_req->rq_disk->private_data;
+ set_fdc(drive);
+ reschedule_timeout(current_reqD, "redo fd request");
- if (TESTF(FD_NEED_TWADDLE))
- twaddle();
- schedule_bh(floppy_start);
- debugt("queue fd request");
+ set_floppy(drive);
+ raw_cmd = &default_raw_cmd;
+ raw_cmd->flags = 0;
+ if (start_motor(redo_fd_request))
return;
+
+ disk_change(current_drive);
+ if (test_bit(current_drive, &fake_change) ||
+ test_bit(FD_DISK_CHANGED_BIT, &DRS->flags)) {
+ DPRINT("disk absent or changed during operation\n");
+ request_done(0);
+ goto do_request;
+ }
+ if (!_floppy) { /* Autodetection */
+ if (!probing) {
+ DRS->probed_format = 0;
+ if (next_valid_format()) {
+ DPRINT("no autodetectable formats\n");
+ _floppy = NULL;
+ request_done(0);
+ goto do_request;
+ }
+ }
+ probing = 1;
+ _floppy = floppy_type + DP->autodetect[DRS->probed_format];
+ } else
+ probing = 0;
+ errors = &(current_req->errors);
+ tmp = make_raw_rw_request();
+ if (tmp < 2) {
+ request_done(tmp);
+ goto do_request;
}
-#undef REPEAT
+
+ if (test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags))
+ twaddle();
+ schedule_bh(floppy_start);
+ debugt(__func__, "queue fd request");
+ return;
}
static struct cont_t rw_cont = {
@@ -2979,30 +2934,30 @@ static void process_fd_request(void)
schedule_bh(redo_fd_request);
}
-static void do_fd_request(struct request_queue * q)
+static void do_fd_request(struct request_queue *q)
{
if (max_buffer_sectors == 0) {
- printk("VFS: do_fd_request called on non-open device\n");
+ pr_info("VFS: %s called on non-open device\n", __func__);
return;
}
if (usage_count == 0) {
- printk("warning: usage count=0, current_req=%p exiting\n",
- current_req);
- printk("sect=%ld type=%x flags=%x\n",
- (long)blk_rq_pos(current_req), current_req->cmd_type,
- current_req->cmd_flags);
+ pr_info("warning: usage count=0, current_req=%p exiting\n",
+ current_req);
+ pr_info("sect=%ld type=%x flags=%x\n",
+ (long)blk_rq_pos(current_req), current_req->cmd_type,
+ current_req->cmd_flags);
return;
}
if (test_bit(0, &fdc_busy)) {
/* fdc busy, this new request will be treated when the
current one is done */
- is_alive("do fd request, old request running");
+ is_alive(__func__, "old request running");
return;
}
- lock_fdc(MAXTIMEOUT, 0);
+ lock_fdc(MAXTIMEOUT, false);
process_fd_request();
- is_alive("do fd request");
+ is_alive(__func__, "");
}
static struct cont_t poll_cont = {
@@ -3012,24 +2967,18 @@ static struct cont_t poll_cont = {
.done = generic_done
};
-static int poll_drive(int interruptible, int flag)
+static int poll_drive(bool interruptible, int flag)
{
- int ret;
-
/* no auto-sense, just clear dcl */
raw_cmd = &default_raw_cmd;
raw_cmd->flags = flag;
raw_cmd->track = 0;
raw_cmd->cmd_count = 0;
cont = &poll_cont;
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("setting NEWCHANGE in poll_drive\n");
- }
-#endif
- SETF(FD_DISK_NEWCHANGE);
- WAIT(floppy_ready);
- return ret;
+ debug_dcl(DP->flags, "setting NEWCHANGE in poll_drive\n");
+ set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
+
+ return wait_til_done(floppy_ready, interruptible);
}
/*
@@ -3039,7 +2988,7 @@ static int poll_drive(int interruptible, int flag)
static void reset_intr(void)
{
- printk("weird, reset interrupt called\n");
+ pr_info("weird, reset interrupt called\n");
}
static struct cont_t reset_cont = {
@@ -3049,20 +2998,23 @@ static struct cont_t reset_cont = {
.done = generic_done
};
-static int user_reset_fdc(int drive, int arg, int interruptible)
+static int user_reset_fdc(int drive, int arg, bool interruptible)
{
int ret;
- ret = 0;
- LOCK_FDC(drive, interruptible);
+ if (lock_fdc(drive, interruptible))
+ return -EINTR;
+
if (arg == FD_RESET_ALWAYS)
FDCS->reset = 1;
if (FDCS->reset) {
cont = &reset_cont;
- WAIT(reset_fdc);
+ ret = wait_til_done(reset_fdc, interruptible);
+ if (ret == -EINTR)
+ return -EINTR;
}
process_fd_request();
- return ret;
+ return 0;
}
/*
@@ -3075,17 +3027,12 @@ static inline int fd_copyout(void __user *param, const void *address,
return copy_to_user(param, address, size) ? -EFAULT : 0;
}
-static inline int fd_copyin(void __user *param, void *address, unsigned long size)
+static inline int fd_copyin(void __user *param, void *address,
+ unsigned long size)
{
return copy_from_user(address, param, size) ? -EFAULT : 0;
}
-#define _COPYOUT(x) (copy_to_user((void __user *)param, &(x), sizeof(x)) ? -EFAULT : 0)
-#define _COPYIN(x) (copy_from_user(&(x), (void __user *)param, sizeof(x)) ? -EFAULT : 0)
-
-#define COPYOUT(x) ECALL(_COPYOUT(x))
-#define COPYIN(x) ECALL(_COPYIN(x))
-
static inline const char *drive_name(int type, int drive)
{
struct floppy_struct *floppy;
@@ -3156,23 +3103,29 @@ static struct cont_t raw_cmd_cont = {
.done = raw_cmd_done
};
-static inline int raw_cmd_copyout(int cmd, char __user *param,
+static inline int raw_cmd_copyout(int cmd, void __user *param,
struct floppy_raw_cmd *ptr)
{
int ret;
while (ptr) {
- COPYOUT(*ptr);
+ ret = copy_to_user(param, ptr, sizeof(*ptr));
+ if (ret)
+ return -EFAULT;
param += sizeof(struct floppy_raw_cmd);
if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) {
- if (ptr->length >= 0
- && ptr->length <= ptr->buffer_length)
- ECALL(fd_copyout
- (ptr->data, ptr->kernel_data,
- ptr->buffer_length - ptr->length));
+ if (ptr->length >= 0 &&
+ ptr->length <= ptr->buffer_length) {
+ long length = ptr->buffer_length - ptr->length;
+ ret = fd_copyout(ptr->data, ptr->kernel_data,
+ length);
+ if (ret)
+ return ret;
+ }
}
ptr = ptr->next;
}
+
return 0;
}
@@ -3195,7 +3148,7 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr)
}
}
-static inline int raw_cmd_copyin(int cmd, char __user *param,
+static inline int raw_cmd_copyin(int cmd, void __user *param,
struct floppy_raw_cmd **rcmd)
{
struct floppy_raw_cmd *ptr;
@@ -3203,17 +3156,19 @@ static inline int raw_cmd_copyin(int cmd, char __user *param,
int i;
*rcmd = NULL;
- while (1) {
- ptr = (struct floppy_raw_cmd *)
- kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
- if (!ptr)
- return -ENOMEM;
- *rcmd = ptr;
- COPYIN(*ptr);
- ptr->next = NULL;
- ptr->buffer_length = 0;
- param += sizeof(struct floppy_raw_cmd);
- if (ptr->cmd_count > 33)
+
+loop:
+ ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
+ if (!ptr)
+ return -ENOMEM;
+ *rcmd = ptr;
+ ret = copy_from_user(ptr, param, sizeof(*ptr));
+ if (ret)
+ return -EFAULT;
+ ptr->next = NULL;
+ ptr->buffer_length = 0;
+ param += sizeof(struct floppy_raw_cmd);
+ if (ptr->cmd_count > 33)
/* the command may now also take up the space
* initially intended for the reply & the
* reply count. Needed for long 82078 commands
@@ -3222,31 +3177,35 @@ static inline int raw_cmd_copyin(int cmd, char __user *param,
* 16 bytes for a structure, you'll one day
* discover that you really need 17...
*/
+ return -EINVAL;
+
+ for (i = 0; i < 16; i++)
+ ptr->reply[i] = 0;
+ ptr->resultcode = 0;
+ ptr->kernel_data = NULL;
+
+ if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
+ if (ptr->length <= 0)
return -EINVAL;
+ ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length);
+ fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
+ if (!ptr->kernel_data)
+ return -ENOMEM;
+ ptr->buffer_length = ptr->length;
+ }
+ if (ptr->flags & FD_RAW_WRITE) {
+ ret = fd_copyin(ptr->data, ptr->kernel_data, ptr->length);
+ if (ret)
+ return ret;
+ }
- for (i = 0; i < 16; i++)
- ptr->reply[i] = 0;
- ptr->resultcode = 0;
- ptr->kernel_data = NULL;
-
- if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
- if (ptr->length <= 0)
- return -EINVAL;
- ptr->kernel_data =
- (char *)fd_dma_mem_alloc(ptr->length);
- fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
- if (!ptr->kernel_data)
- return -ENOMEM;
- ptr->buffer_length = ptr->length;
- }
- if (ptr->flags & FD_RAW_WRITE)
- ECALL(fd_copyin(ptr->data, ptr->kernel_data,
- ptr->length));
+ if (ptr->flags & FD_RAW_MORE) {
rcmd = &(ptr->next);
- if (!(ptr->flags & FD_RAW_MORE))
- return 0;
ptr->rate &= 0x43;
+ goto loop;
}
+
+ return 0;
}
static int raw_cmd_ioctl(int cmd, void __user *param)
@@ -3283,12 +3242,8 @@ static int raw_cmd_ioctl(int cmd, void __user *param)
raw_cmd = my_raw_cmd;
cont = &raw_cmd_cont;
- ret = wait_til_done(floppy_start, 1);
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("calling disk change from raw_cmd ioctl\n");
- }
-#endif
+ ret = wait_til_done(floppy_start, true);
+ debug_dcl(DP->flags, "calling disk change from raw_cmd ioctl\n");
if (ret != -EINTR && FDCS->reset)
ret = -EIO;
@@ -3327,7 +3282,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
mutex_lock(&open_lock);
- if (lock_fdc(drive, 1)) {
+ if (lock_fdc(drive, true)) {
mutex_unlock(&open_lock);
return -EINTR;
}
@@ -3346,11 +3301,15 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
mutex_unlock(&open_lock);
} else {
int oldStretch;
- LOCK_FDC(drive, 1);
- if (cmd != FDDEFPRM)
+
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ if (cmd != FDDEFPRM) {
/* notice a disk change immediately, else
* we lose our settings immediately*/
- CALL(poll_drive(1, FD_RAW_NEED_DISK));
+ if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+ return -EINTR;
+ }
oldStretch = g->stretch;
user_params[drive] = *g;
if (buffer_drive == drive)
@@ -3415,7 +3374,7 @@ static inline int normalize_ioctl(int *cmd, int *size)
*size = _IOC_SIZE(*cmd);
*cmd = ioctl_table[i];
if (*size > _IOC_SIZE(*cmd)) {
- printk("ioctl not yet supported\n");
+ pr_info("ioctl not yet supported\n");
return -EFAULT;
}
return 0;
@@ -3429,8 +3388,10 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g)
if (type)
*g = &floppy_type[type];
else {
- LOCK_FDC(drive, 0);
- CALL(poll_drive(0, 0));
+ if (lock_fdc(drive, false))
+ return -EINTR;
+ if (poll_drive(false, 0) == -EINTR)
+ return -EINTR;
process_fd_request();
*g = current_type[drive];
}
@@ -3459,10 +3420,6 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
unsigned long param)
{
-#define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL))
-#define OUT(c,x) case c: outparam = (const char *) (x); break
-#define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
-
int drive = (long)bdev->bd_disk->private_data;
int type = ITYPE(UDRS->fd_device);
int i;
@@ -3474,26 +3431,28 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
struct floppy_max_errors max_errors;
struct floppy_drive_params dp;
} inparam; /* parameters coming from user space */
- const char *outparam; /* parameters passed back to user space */
+ const void *outparam; /* parameters passed back to user space */
/* convert compatibility eject ioctls into floppy eject ioctl.
* We do this in order to provide a means to eject floppy disks before
* installing the new fdutils package */
if (cmd == CDROMEJECT || /* CD-ROM eject */
- cmd == 0x6470 /* SunOS floppy eject */ ) {
+ cmd == 0x6470) { /* SunOS floppy eject */
DPRINT("obsolete eject ioctl\n");
DPRINT("please use floppycontrol --eject\n");
cmd = FDEJECT;
}
- /* convert the old style command into a new style command */
- if ((cmd & 0xff00) == 0x0200) {
- ECALL(normalize_ioctl(&cmd, &size));
- } else
+ if (!((cmd & 0xff00) == 0x0200))
return -EINVAL;
+ /* convert the old style command into a new style command */
+ ret = normalize_ioctl(&cmd, &size);
+ if (ret)
+ return ret;
+
/* permission checks */
- if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) ||
+ if (((cmd & 0x40) && !(mode & (FMODE_WRITE | FMODE_WRITE_IOCTL))) ||
((cmd & 0x80) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
@@ -3501,129 +3460,142 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
return -EINVAL;
/* copyin */
- CLEARSTRUCT(&inparam);
- if (_IOC_DIR(cmd) & _IOC_WRITE)
- ECALL(fd_copyin((void __user *)param, &inparam, size))
-
- switch (cmd) {
- case FDEJECT:
- if (UDRS->fd_ref != 1)
- /* somebody else has this drive open */
- return -EBUSY;
- LOCK_FDC(drive, 1);
-
- /* do the actual eject. Fails on
- * non-Sparc architectures */
- ret = fd_eject(UNIT(drive));
-
- USETF(FD_DISK_CHANGED);
- USETF(FD_VERIFY);
- process_fd_request();
+ memset(&inparam, 0, sizeof(inparam));
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ ret = fd_copyin((void __user *)param, &inparam, size);
+ if (ret)
return ret;
- case FDCLRPRM:
- LOCK_FDC(drive, 1);
- current_type[drive] = NULL;
- floppy_sizes[drive] = MAX_DISK_SIZE << 1;
- UDRS->keep_data = 0;
- return invalidate_drive(bdev);
- case FDSETPRM:
- case FDDEFPRM:
- return set_geometry(cmd, &inparam.g,
- drive, type, bdev);
- case FDGETPRM:
- ECALL(get_floppy_geometry(drive, type,
- (struct floppy_struct **)
- &outparam));
- break;
-
- case FDMSGON:
- UDP->flags |= FTD_MSG;
- return 0;
- case FDMSGOFF:
- UDP->flags &= ~FTD_MSG;
- return 0;
-
- case FDFMTBEG:
- LOCK_FDC(drive, 1);
- CALL(poll_drive(1, FD_RAW_NEED_DISK));
- ret = UDRS->flags;
- process_fd_request();
- if (ret & FD_VERIFY)
- return -ENODEV;
- if (!(ret & FD_DISK_WRITABLE))
- return -EROFS;
- return 0;
- case FDFMTTRK:
- if (UDRS->fd_ref != 1)
- return -EBUSY;
- return do_format(drive, &inparam.f);
- case FDFMTEND:
- case FDFLUSH:
- LOCK_FDC(drive, 1);
- return invalidate_drive(bdev);
-
- case FDSETEMSGTRESH:
- UDP->max_errors.reporting =
- (unsigned short)(param & 0x0f);
- return 0;
- OUT(FDGETMAXERRS, &UDP->max_errors);
- IN(FDSETMAXERRS, &UDP->max_errors, max_errors);
-
- case FDGETDRVTYP:
- outparam = drive_name(type, drive);
- SUPBOUND(size, strlen(outparam) + 1);
- break;
-
- IN(FDSETDRVPRM, UDP, dp);
- OUT(FDGETDRVPRM, UDP);
-
- case FDPOLLDRVSTAT:
- LOCK_FDC(drive, 1);
- CALL(poll_drive(1, FD_RAW_NEED_DISK));
- process_fd_request();
- /* fall through */
- OUT(FDGETDRVSTAT, UDRS);
-
- case FDRESET:
- return user_reset_fdc(drive, (int)param, 1);
-
- OUT(FDGETFDCSTAT, UFDCS);
+ }
- case FDWERRORCLR:
- CLEARSTRUCT(UDRWE);
- return 0;
- OUT(FDWERRORGET, UDRWE);
-
- case FDRAWCMD:
- if (type)
- return -EINVAL;
- LOCK_FDC(drive, 1);
- set_floppy(drive);
- CALL(i = raw_cmd_ioctl(cmd, (void __user *)param));
- process_fd_request();
- return i;
+ switch (cmd) {
+ case FDEJECT:
+ if (UDRS->fd_ref != 1)
+ /* somebody else has this drive open */
+ return -EBUSY;
+ if (lock_fdc(drive, true))
+ return -EINTR;
- case FDTWADDLE:
- LOCK_FDC(drive, 1);
- twaddle();
- process_fd_request();
- return 0;
+ /* do the actual eject. Fails on
+ * non-Sparc architectures */
+ ret = fd_eject(UNIT(drive));
- default:
+ set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+ set_bit(FD_VERIFY_BIT, &UDRS->flags);
+ process_fd_request();
+ return ret;
+ case FDCLRPRM:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ current_type[drive] = NULL;
+ floppy_sizes[drive] = MAX_DISK_SIZE << 1;
+ UDRS->keep_data = 0;
+ return invalidate_drive(bdev);
+ case FDSETPRM:
+ case FDDEFPRM:
+ return set_geometry(cmd, &inparam.g, drive, type, bdev);
+ case FDGETPRM:
+ ret = get_floppy_geometry(drive, type,
+ (struct floppy_struct **)&outparam);
+ if (ret)
+ return ret;
+ break;
+ case FDMSGON:
+ UDP->flags |= FTD_MSG;
+ return 0;
+ case FDMSGOFF:
+ UDP->flags &= ~FTD_MSG;
+ return 0;
+ case FDFMTBEG:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+ return -EINTR;
+ ret = UDRS->flags;
+ process_fd_request();
+ if (ret & FD_VERIFY)
+ return -ENODEV;
+ if (!(ret & FD_DISK_WRITABLE))
+ return -EROFS;
+ return 0;
+ case FDFMTTRK:
+ if (UDRS->fd_ref != 1)
+ return -EBUSY;
+ return do_format(drive, &inparam.f);
+ case FDFMTEND:
+ case FDFLUSH:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ return invalidate_drive(bdev);
+ case FDSETEMSGTRESH:
+ UDP->max_errors.reporting = (unsigned short)(param & 0x0f);
+ return 0;
+ case FDGETMAXERRS:
+ outparam = &UDP->max_errors;
+ break;
+ case FDSETMAXERRS:
+ UDP->max_errors = inparam.max_errors;
+ break;
+ case FDGETDRVTYP:
+ outparam = drive_name(type, drive);
+ SUPBOUND(size, strlen((const char *)outparam) + 1);
+ break;
+ case FDSETDRVPRM:
+ *UDP = inparam.dp;
+ break;
+ case FDGETDRVPRM:
+ outparam = UDP;
+ break;
+ case FDPOLLDRVSTAT:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+ return -EINTR;
+ process_fd_request();
+ /* fall through */
+ case FDGETDRVSTAT:
+ outparam = UDRS;
+ break;
+ case FDRESET:
+ return user_reset_fdc(drive, (int)param, true);
+ case FDGETFDCSTAT:
+ outparam = UFDCS;
+ break;
+ case FDWERRORCLR:
+ memset(UDRWE, 0, sizeof(*UDRWE));
+ return 0;
+ case FDWERRORGET:
+ outparam = UDRWE;
+ break;
+ case FDRAWCMD:
+ if (type)
return -EINVAL;
- }
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ set_floppy(drive);
+ i = raw_cmd_ioctl(cmd, (void __user *)param);
+ if (i == -EINTR)
+ return -EINTR;
+ process_fd_request();
+ return i;
+ case FDTWADDLE:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ twaddle();
+ process_fd_request();
+ return 0;
+ default:
+ return -EINVAL;
+ }
if (_IOC_DIR(cmd) & _IOC_READ)
return fd_copyout((void __user *)param, outparam, size);
- else
- return 0;
-#undef OUT
-#undef IN
+
+ return 0;
}
static void __init config_types(void)
{
- int first = 1;
+ bool has_drive = false;
int drive;
/* read drive info out of physical CMOS */
@@ -3655,17 +3627,22 @@ static void __init config_types(void)
name = temparea;
}
if (name) {
- const char *prepend = ",";
- if (first) {
- prepend = KERN_INFO "Floppy drive(s):";
- first = 0;
+ const char *prepend;
+ if (!has_drive) {
+ prepend = "";
+ has_drive = true;
+ pr_info("Floppy drive(s):");
+ } else {
+ prepend = ",";
}
- printk("%s fd%d is %s", prepend, drive, name);
+
+ pr_cont("%s fd%d is %s", prepend, drive, name);
}
*UDP = *params;
}
- if (!first)
- printk("\n");
+
+ if (has_drive)
+ pr_cont("\n");
}
static int floppy_release(struct gendisk *disk, fmode_t mode)
@@ -3705,8 +3682,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
goto out2;
if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) {
- USETF(FD_DISK_CHANGED);
- USETF(FD_VERIFY);
+ set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+ set_bit(FD_VERIFY_BIT, &UDRS->flags);
}
if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL)))
@@ -3735,9 +3712,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
INFBOUND(try, 16);
tmp = (char *)fd_dma_mem_alloc(1024 * try);
}
- if (!tmp && !floppy_track_buffer) {
+ if (!tmp && !floppy_track_buffer)
fallback_on_nodma_alloc(&tmp, 2048 * try);
- }
if (!tmp && !floppy_track_buffer) {
DPRINT("Unable to allocate DMA memory\n");
goto out;
@@ -3767,11 +3743,12 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
if (mode & (FMODE_READ|FMODE_WRITE)) {
UDRS->last_checked = 0;
check_disk_change(bdev);
- if (UTESTF(FD_DISK_CHANGED))
+ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags))
goto out;
}
res = -EROFS;
- if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE)))
+ if ((mode & FMODE_WRITE) &&
+ !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags))
goto out;
}
mutex_unlock(&open_lock);
@@ -3795,17 +3772,18 @@ static int check_floppy_change(struct gendisk *disk)
{
int drive = (long)disk->private_data;
- if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
+ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+ test_bit(FD_VERIFY_BIT, &UDRS->flags))
return 1;
if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) {
- lock_fdc(drive, 0);
- poll_drive(0, 0);
+ lock_fdc(drive, false);
+ poll_drive(false, 0);
process_fd_request();
}
- if (UTESTF(FD_DISK_CHANGED) ||
- UTESTF(FD_VERIFY) ||
+ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+ test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
test_bit(drive, &fake_change) ||
(!ITYPE(UDRS->fd_device) && !current_type[drive]))
return 1;
@@ -3818,8 +3796,7 @@ static int check_floppy_change(struct gendisk *disk)
* a disk in the drive, and whether that disk is writable.
*/
-static void floppy_rb0_complete(struct bio *bio,
- int err)
+static void floppy_rb0_complete(struct bio *bio, int err)
{
complete((struct completion *)bio->bi_private);
}
@@ -3877,14 +3854,16 @@ static int floppy_revalidate(struct gendisk *disk)
int cf;
int res = 0;
- if (UTESTF(FD_DISK_CHANGED) ||
- UTESTF(FD_VERIFY) || test_bit(drive, &fake_change) || NO_GEOM) {
+ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+ test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
+ test_bit(drive, &fake_change) || NO_GEOM) {
if (usage_count == 0) {
- printk("VFS: revalidate called on non-open device.\n");
+ pr_info("VFS: revalidate called on non-open device.\n");
return -EFAULT;
}
- lock_fdc(drive, 0);
- cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
+ lock_fdc(drive, false);
+ cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+ test_bit(FD_VERIFY_BIT, &UDRS->flags));
if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) {
process_fd_request(); /*already done by another thread */
return 0;
@@ -3894,7 +3873,7 @@ static int floppy_revalidate(struct gendisk *disk)
if (buffer_drive == drive)
buffer_track = -1;
clear_bit(drive, &fake_change);
- UCLEARF(FD_DISK_CHANGED);
+ clear_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
if (cf)
UDRS->generation++;
if (NO_GEOM) {
@@ -3902,7 +3881,7 @@ static int floppy_revalidate(struct gendisk *disk)
res = __floppy_read_block_0(opened_bdev[drive]);
} else {
if (cf)
- poll_drive(0, FD_RAW_NEED_DISK);
+ poll_drive(false, FD_RAW_NEED_DISK);
process_fd_request();
}
}
@@ -3934,21 +3913,21 @@ static char __init get_fdc_version(void)
output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */
if (FDCS->reset)
return FDC_NONE;
- if ((r = result()) <= 0x00)
+ r = result();
+ if (r <= 0x00)
return FDC_NONE; /* No FDC present ??? */
if ((r == 1) && (reply_buffer[0] == 0x80)) {
- printk(KERN_INFO "FDC %d is an 8272A\n", fdc);
+ pr_info("FDC %d is an 8272A\n", fdc);
return FDC_8272A; /* 8272a/765 don't know DUMPREGS */
}
if (r != 10) {
- printk
- ("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
- fdc, r);
+ pr_info("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
+ fdc, r);
return FDC_UNKNOWN;
}
if (!fdc_configure()) {
- printk(KERN_INFO "FDC %d is an 82072\n", fdc);
+ pr_info("FDC %d is an 82072\n", fdc);
return FDC_82072; /* 82072 doesn't know CONFIGURE */
}
@@ -3956,52 +3935,50 @@ static char __init get_fdc_version(void)
if (need_more_output() == MORE_OUTPUT) {
output_byte(0);
} else {
- printk(KERN_INFO "FDC %d is an 82072A\n", fdc);
+ pr_info("FDC %d is an 82072A\n", fdc);
return FDC_82072A; /* 82072A as found on Sparcs. */
}
output_byte(FD_UNLOCK);
r = result();
if ((r == 1) && (reply_buffer[0] == 0x80)) {
- printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc);
- return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
+ pr_info("FDC %d is a pre-1991 82077\n", fdc);
+ return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
* LOCK/UNLOCK */
}
if ((r != 1) || (reply_buffer[0] != 0x00)) {
- printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
- fdc, r);
+ pr_info("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
+ fdc, r);
return FDC_UNKNOWN;
}
output_byte(FD_PARTID);
r = result();
if (r != 1) {
- printk("FDC %d init: PARTID: unexpected return of %d bytes.\n",
- fdc, r);
+ pr_info("FDC %d init: PARTID: unexpected return of %d bytes.\n",
+ fdc, r);
return FDC_UNKNOWN;
}
if (reply_buffer[0] == 0x80) {
- printk(KERN_INFO "FDC %d is a post-1991 82077\n", fdc);
+ pr_info("FDC %d is a post-1991 82077\n", fdc);
return FDC_82077; /* Revised 82077AA passes all the tests */
}
switch (reply_buffer[0] >> 5) {
case 0x0:
/* Either a 82078-1 or a 82078SL running at 5Volt */
- printk(KERN_INFO "FDC %d is an 82078.\n", fdc);
+ pr_info("FDC %d is an 82078.\n", fdc);
return FDC_82078;
case 0x1:
- printk(KERN_INFO "FDC %d is a 44pin 82078\n", fdc);
+ pr_info("FDC %d is a 44pin 82078\n", fdc);
return FDC_82078;
case 0x2:
- printk(KERN_INFO "FDC %d is a S82078B\n", fdc);
+ pr_info("FDC %d is a S82078B\n", fdc);
return FDC_S82078B;
case 0x3:
- printk(KERN_INFO "FDC %d is a National Semiconductor PC87306\n",
- fdc);
+ pr_info("FDC %d is a National Semiconductor PC87306\n", fdc);
return FDC_87306;
default:
- printk(KERN_INFO
- "FDC %d init: 82078 variant with unknown PARTID=%d.\n",
- fdc, reply_buffer[0] >> 5);
+ pr_info("FDC %d init: 82078 variant with unknown PARTID=%d.\n",
+ fdc, reply_buffer[0] >> 5);
return FDC_82078_UNKN;
}
} /* get_fdc_version */
@@ -4113,9 +4090,9 @@ static int __init floppy_setup(char *str)
else
param = config_params[i].def_param;
if (config_params[i].fn)
- config_params[i].
- fn(ints, param,
- config_params[i].param2);
+ config_params[i].fn(ints, param,
+ config_params[i].
+ param2);
if (config_params[i].var) {
DPRINT("%s=%d\n", str, param);
*config_params[i].var = param;
@@ -4129,8 +4106,8 @@ static int __init floppy_setup(char *str)
DPRINT("allowed options are:");
for (i = 0; i < ARRAY_SIZE(config_params); i++)
- printk(" %s", config_params[i].name);
- printk("\n");
+ pr_cont(" %s", config_params[i].name);
+ pr_cont("\n");
} else
DPRINT("botched floppy option\n");
DPRINT("Read Documentation/blockdev/floppy.txt\n");
@@ -4148,7 +4125,8 @@ static ssize_t floppy_cmos_show(struct device *dev,
drive = p->id;
return sprintf(buf, "%X\n", UDP->cmos);
}
-DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL);
+
+DEVICE_ATTR(cmos, S_IRUGO, floppy_cmos_show, NULL);
static void floppy_device_release(struct device *dev)
{
@@ -4160,7 +4138,7 @@ static int floppy_resume(struct device *dev)
for (fdc = 0; fdc < N_FDC; fdc++)
if (FDCS->address != -1)
- user_reset_fdc(-1, FD_RESET_ALWAYS, 0);
+ user_reset_fdc(-1, FD_RESET_ALWAYS, false);
return 0;
}
@@ -4172,8 +4150,8 @@ static const struct dev_pm_ops floppy_pm_ops = {
static struct platform_driver floppy_driver = {
.driver = {
- .name = "floppy",
- .pm = &floppy_pm_ops,
+ .name = "floppy",
+ .pm = &floppy_pm_ops,
},
};
@@ -4245,16 +4223,16 @@ static int __init floppy_init(void)
else
floppy_sizes[i] = MAX_DISK_SIZE << 1;
- reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
+ reschedule_timeout(MAXTIMEOUT, "floppy init");
config_types();
for (i = 0; i < N_FDC; i++) {
fdc = i;
- CLEARSTRUCT(FDCS);
+ memset(FDCS, 0, sizeof(*FDCS));
FDCS->dtr = -1;
FDCS->dor = 0x4;
#if defined(__sparc__) || defined(__mc68000__)
- /*sparcs/sun3x don't have a DOR reset which we can fall back on to */
+ /*sparcs/sun3x don't have a DOR reset which we can fall back on to */
#ifdef __mc68000__
if (MACH_IS_SUN3X)
#endif
@@ -4283,11 +4261,11 @@ static int __init floppy_init(void)
/* initialise drive state */
for (drive = 0; drive < N_DRIVE; drive++) {
- CLEARSTRUCT(UDRS);
- CLEARSTRUCT(UDRWE);
- USETF(FD_DISK_NEWCHANGE);
- USETF(FD_DISK_CHANGED);
- USETF(FD_VERIFY);
+ memset(UDRS, 0, sizeof(*UDRS));
+ memset(UDRWE, 0, sizeof(*UDRWE));
+ set_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags);
+ set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+ set_bit(FD_VERIFY_BIT, &UDRS->flags);
UDRS->fd_device = -1;
floppy_track_buffer = NULL;
max_buffer_sectors = 0;
@@ -4307,7 +4285,7 @@ static int __init floppy_init(void)
if (FDCS->address == -1)
continue;
FDCS->rawcmd = 2;
- if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) {
+ if (user_reset_fdc(-1, FD_RESET_ALWAYS, false)) {
/* free ioports reserved by floppy_grab_irq_and_dma() */
floppy_release_regions(fdc);
FDCS->address = -1;
@@ -4330,12 +4308,12 @@ static int __init floppy_init(void)
* properly, so force a reset for the standard FDC clones,
* to avoid interrupt garbage.
*/
- user_reset_fdc(-1, FD_RESET_ALWAYS, 0);
+ user_reset_fdc(-1, FD_RESET_ALWAYS, false);
}
fdc = 0;
del_timer(&fd_timeout);
current_drive = 0;
- initialising = 0;
+ initialized = true;
if (have_no_fdc) {
DPRINT("no floppy controllers found\n");
err = have_no_fdc;
@@ -4356,7 +4334,8 @@ static int __init floppy_init(void)
if (err)
goto out_flush_work;
- err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
+ err = device_create_file(&floppy_device[drive].dev,
+ &dev_attr_cmos);
if (err)
goto out_unreg_platform_dev;
@@ -4420,8 +4399,10 @@ static int floppy_request_regions(int fdc)
const struct io_region *p;
for (p = io_regions; p < ARRAY_END(io_regions); p++) {
- if (!request_region(FDCS->address + p->offset, p->size, "floppy")) {
- DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset);
+ if (!request_region(FDCS->address + p->offset,
+ p->size, "floppy")) {
+ DPRINT("Floppy io-port 0x%04lx in use\n",
+ FDCS->address + p->offset);
floppy_release_allocated_regions(fdc, p);
return -EBUSY;
}
@@ -4512,11 +4493,9 @@ cleanup:
static void floppy_release_irq_and_dma(void)
{
int old_fdc;
-#ifdef FLOPPY_SANITY_CHECK
#ifndef __sparc__
int drive;
#endif
-#endif
long tmpsize;
unsigned long tmpaddr;
unsigned long flags;
@@ -4547,20 +4526,18 @@ static void floppy_release_irq_and_dma(void)
buffer_min = buffer_max = -1;
fd_dma_mem_free(tmpaddr, tmpsize);
}
-#ifdef FLOPPY_SANITY_CHECK
#ifndef __sparc__
for (drive = 0; drive < N_FDC * 4; drive++)
if (timer_pending(motor_off_timer + drive))
- printk("motor off timer %d still active\n", drive);
+ pr_info("motor off timer %d still active\n", drive);
#endif
if (timer_pending(&fd_timeout))
- printk("floppy timer still active:%s\n", timeout_message);
+ pr_info("floppy timer still active:%s\n", timeout_message);
if (timer_pending(&fd_timer))
- printk("auxiliary floppy timer still active\n");
+ pr_info("auxiliary floppy timer still active\n");
if (work_pending(&floppy_work))
- printk("work still pending\n");
-#endif
+ pr_info("work still pending\n");
old_fdc = fdc;
for (fdc = 0; fdc < N_FDC; fdc++)
if (FDCS->address != -1)
@@ -4577,7 +4554,9 @@ static void __init parse_floppy_cfg_string(char *cfg)
char *ptr;
while (*cfg) {
- for (ptr = cfg; *cfg && *cfg != ' ' && *cfg != '\t'; cfg++) ;
+ ptr = cfg;
+ while (*cfg && *cfg != ' ' && *cfg != '\t')
+ cfg++;
if (*cfg) {
*cfg = '\0';
cfg++;
@@ -4625,6 +4604,7 @@ static void __exit floppy_module_exit(void)
/* eject disk, if any */
fd_eject(0);
}
+
module_exit(floppy_module_exit);
module_param(floppy, charp, 0);
@@ -4636,9 +4616,10 @@ MODULE_LICENSE("GPL");
/* This doesn't actually get used other than for module information */
static const struct pnp_device_id floppy_pnpids[] = {
- { "PNP0700", 0 },
- { }
+ {"PNP0700", 0},
+ {}
};
+
MODULE_DEVICE_TABLE(pnp, floppy_pnpids);
#else
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index 5116c65c07c..034e6dfc878 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -34,7 +34,6 @@
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/genhd.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/init.h>
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index bd112c8c7bc..8546d123b9a 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -71,7 +71,6 @@
#include <linux/buffer_head.h> /* for invalidate_bdev() */
#include <linux/completion.h>
#include <linux/highmem.h>
-#include <linux/gfp.h>
#include <linux/kthread.h>
#include <linux/splice.h>
@@ -238,6 +237,8 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
if (ret)
goto fail;
+ file_update_time(file);
+
transfer_result = lo_do_transfer(lo, WRITE, page, offset,
bvec->bv_page, bv_offs, size, IV);
copied = size;
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index 5416c9a606e..28db925dbda 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/mg_disk.h>
+#include <linux/slab.h>
#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index cc923a5b430..218d091f3c5 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -27,6 +27,7 @@
#include <linux/compiler.h>
#include <linux/err.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/net.h>
#include <linux/kthread.h>
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c
index a808b1530b3..6cd8b705b11 100644
--- a/drivers/block/osdblk.c
+++ b/drivers/block/osdblk.c
@@ -63,6 +63,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <scsi/osd_initiator.h>
#include <scsi/osd_attributes.h>
#include <scsi/osd_sec.h>
@@ -476,7 +477,9 @@ static void class_osdblk_release(struct class *cls)
kfree(cls);
}
-static ssize_t class_osdblk_list(struct class *c, char *data)
+static ssize_t class_osdblk_list(struct class *c,
+ struct class_attribute *attr,
+ char *data)
{
int n = 0;
struct list_head *tmp;
@@ -500,7 +503,9 @@ static ssize_t class_osdblk_list(struct class *c, char *data)
return n;
}
-static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count)
+static ssize_t class_osdblk_add(struct class *c,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
{
struct osdblk_device *osdev;
ssize_t rc;
@@ -592,7 +597,9 @@ err_out_mod:
return rc;
}
-static ssize_t class_osdblk_remove(struct class *c, const char *buf,
+static ssize_t class_osdblk_remove(struct class *c,
+ struct class_attribute *attr,
+ const char *buf,
size_t count)
{
struct osdblk_device *osdev = NULL;
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 8866ca369d5..71acf4e5335 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -341,11 +341,11 @@ static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
&& (j++ < PCD_SPIN))
udelay(PCD_DELAY);
- if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) {
+ if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) {
s = read_reg(cd, 7);
e = read_reg(cd, 1);
p = read_reg(cd, 2);
- if (j >= PCD_SPIN)
+ if (j > PCD_SPIN)
e |= 0x100;
if (fun)
printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index e712cd51af1..c1e5cd029b2 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -145,6 +145,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/hdreg.h>
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index ddb4f9abd48..c059aab3006 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -391,11 +391,11 @@ static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg)
&& (j++ < PF_SPIN))
udelay(PF_SPIN_DEL);
- if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) {
+ if ((r & (STAT_ERR & stop)) || (j > PF_SPIN)) {
s = read_reg(pf, 7);
e = read_reg(pf, 1);
p = read_reg(pf, 2);
- if (j >= PF_SPIN)
+ if (j > PF_SPIN)
e |= 0x100;
if (fun)
printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 1e4006e18f0..bc5825fdeaa 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -274,11 +274,11 @@ static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg)
&& (j++ < PT_SPIN))
udelay(PT_SPIN_DEL);
- if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) {
+ if ((r & (STAT_ERR & stop)) || (j > PT_SPIN)) {
s = read_reg(pi, 7);
e = read_reg(pi, 1);
p = read_reg(pi, 2);
- if (j >= PT_SPIN)
+ if (j > PT_SPIN)
e |= 0x100;
if (fun)
printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index b72935b8f20..8a549db2aa7 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -48,6 +48,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/compat.h>
#include <linux/kthread.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
@@ -57,6 +58,7 @@
#include <linux/miscdevice.h>
#include <linux/freezer.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi.h>
@@ -284,7 +286,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj,
return len;
}
-static struct sysfs_ops kobj_pkt_ops = {
+static const struct sysfs_ops kobj_pkt_ops = {
.show = kobj_pkt_show,
.store = kobj_pkt_store
};
@@ -337,7 +339,9 @@ static void class_pktcdvd_release(struct class *cls)
{
kfree(cls);
}
-static ssize_t class_pktcdvd_show_map(struct class *c, char *data)
+static ssize_t class_pktcdvd_show_map(struct class *c,
+ struct class_attribute *attr,
+ char *data)
{
int n = 0;
int idx;
@@ -356,7 +360,9 @@ static ssize_t class_pktcdvd_show_map(struct class *c, char *data)
return n;
}
-static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
+static ssize_t class_pktcdvd_store_add(struct class *c,
+ struct class_attribute *attr,
+ const char *buf,
size_t count)
{
unsigned int major, minor;
@@ -376,7 +382,9 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
return -EINVAL;
}
-static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf,
+static ssize_t class_pktcdvd_store_remove(struct class *c,
+ struct class_attribute *attr,
+ const char *buf,
size_t count)
{
unsigned int major, minor;
@@ -2977,7 +2985,7 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
mutex_unlock(&ctl_mutex);
}
-static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
struct pkt_ctrl_command ctrl_cmd;
@@ -3014,10 +3022,20 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
return ret;
}
+#ifdef CONFIG_COMPAT
+static long pkt_ctl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ return pkt_ctl_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
static const struct file_operations pkt_ctl_fops = {
- .ioctl = pkt_ctl_ioctl,
- .owner = THIS_MODULE,
+ .open = nonseekable_open,
+ .unlocked_ioctl = pkt_ctl_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = pkt_ctl_compat_ioctl,
+#endif
+ .owner = THIS_MODULE,
};
static struct miscdevice pkt_misc = {
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index bc95469d33c..3b419e3fffa 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -20,6 +20,7 @@
#include <linux/ata.h>
#include <linux/blkdev.h>
+#include <linux/slab.h>
#include <asm/lv1call.h>
#include <asm/ps3stor.h>
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index e4460822997..b3bdb8af89c 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/cell-regs.h>
#include <asm/firmware.h>
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index 821c2833f9c..e463657569f 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/fd.h>
+#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/kernel.h>
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 2e889838e81..0536b5b29ad 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -27,6 +27,7 @@
#include <linux/blkdev.h>
#include <linux/timer.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#define DRV_NAME "ub"
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index ad1ba393801..2f9470ff8f7 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -40,13 +40,13 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/mman.h>
+#include <linux/gfp.h>
#include <linux/ioctl.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/fcntl.h> /* O_ACCMODE */
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 3c64af05fa8..2138a7ae050 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -1,5 +1,6 @@
//#define DEBUG
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/virtio.h>
@@ -347,14 +348,13 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
set_capacity(vblk->disk, cap);
/* We can handle whatever the host told us to handle. */
- blk_queue_max_phys_segments(q, vblk->sg_elems-2);
- blk_queue_max_hw_segments(q, vblk->sg_elems-2);
+ blk_queue_max_segments(q, vblk->sg_elems-2);
/* No need to bounce any requests */
blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
/* No real sector limit. */
- blk_queue_max_sectors(q, -1U);
+ blk_queue_max_hw_sectors(q, -1U);
/* Host can optionally specify maximum segment size and number of
* segments. */
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 1a325fb05c9..18a80ff57ce 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -49,6 +49,7 @@
#include <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 9c09694b252..82ed403147c 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -40,6 +40,7 @@
#include <linux/hdreg.h>
#include <linux/cdrom.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <xen/xen.h>
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index 64f941e0f14..9114654b54d 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/setup.h>
#include <asm/amigahw.h>
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c
index 3126a3d0c45..b50b41d97a7 100644
--- a/drivers/bluetooth/btmrvl_debugfs.c
+++ b/drivers/bluetooth/btmrvl_debugfs.c
@@ -19,6 +19,7 @@
**/
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index 523d197b982..204727586ee 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -21,6 +21,7 @@
#include <linux/kthread.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <net/bluetooth/bluetooth.h>
#define BTM_HEADER_LEN 4
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 94f1f55f81f..0dba76aa223 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -19,6 +19,7 @@
**/
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio_func.h>
diff --git a/drivers/char/ChangeLog b/drivers/char/ChangeLog
deleted file mode 100644
index 56b8a2e76ab..00000000000
--- a/drivers/char/ChangeLog
+++ /dev/null
@@ -1,775 +0,0 @@
-2001-08-11 Tim Waugh <twaugh@redhat.com>
-
- * serial.c (get_pci_port): Deal with awkward Titan cards.
-
-1998-08-26 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c (rs_open): Correctly decrement the module in-use count
- on errors.
-
-Thu Feb 19 14:24:08 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * tty_io.c (tty_name): Remove the non-reentrant (and non-SMP safe)
- version of tty_name, and rename the reentrant _tty_name
- function to be tty_name.
- (tty_open): Add a warning message stating callout devices
- are deprecated.
-
-Mon Dec 1 08:24:15 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * tty_io.c (tty_get_baud_rate): Print a warning syslog if the
- tty->alt_speed kludge is used; this means the system is
- using the deprecated SPD_HI ioctls.
-
-Mon Nov 24 10:37:49 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c, esp.c, rocket.c: Change drivers to take advantage of
- tty_get_baud_rate().
-
- * tty_io.c (tty_get_baud_rate): New function which computes the
- correct baud rate for the tty. More factoring out of
- common code out of the serial driver to the high-level tty
- functions....
-
-Sat Nov 22 07:53:36 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c, esp.c, rocket.c: Add tty->driver.break() routine, and
- allow high-level tty code to handle the break and soft
- carrier ioctls.
-
- * tty_ioctl.c (n_tty_ioctl): Support TIOCGSOFTCAR and
- TIOCSSOFTCAR, so that device drivers don't have to support
- it.
-
- * serial.c (autoconfig): Change 16750 test to hopefully eliminate
- false results by people with strange 16550As being
- detected as 16750s. Hopefully 16750s will still be
- detected as 16750, and other weird UARTs won't get poorly
- autodetected. If this doesn't work, I'll have to disable
- the auto identification for the 16750.
-
- * tty_io.c (tty_hangup): Now actually do the tty hangup
- processing during the timer processing, and disable
- interrupts while doing the hangup processing. This avoids
- several nasty race conditions which happened when the
- hangup processing was done asynchronously.
- (tty_ioctl): Do break handling in the tty driver if
- driver's break function is supported.
- (tty_flip_buffer_push): New exported function which should
- be used by drivers to push characters in the flip buffer
- to the tty handler. This may either be done using a task
- queue function for better CPU efficiency, or directly for
- low latency operation.
-
- * serial.c (rs_set_termios): Fix bug rs_set_termios when
- transitioning away from B0, submitted by Stanislav
- Voronyi.
-
-Thu Jun 19 20:05:58 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c (begin_break, end_break, rs_ioctl): Applied patch
- to support BSD ioctls to set and clear the break
- condition explicitly.
-
- * console.c (scrup, scrdown, insert_line, delete_line): Applied
- fix suggested by Aaron Tiensivu to speed up block scrolls
- up and down.
-
- * n_tty.c (opost_block, write_chan): Added a modified "fast
- console" patch which processes a block of text via
- "cooking" efficiently.
-
-Wed Jun 18 15:25:50 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * tty_io.c (init_dev, release_dev): Applied fix suggested by Bill
- Hawes to prevent race conditions in the tty code.
-
- * n_tty.c (n_tty_chars_in_buffer): Applied fix suggested by Bill
- Hawes so that n_tty_chars_in_buffer returns the correct
- value in the case when the tty is in cannonical mode. (To
- avoid a pty deadlock with telnetd.)
-
-Thu Feb 27 01:53:08 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c (change_speed): Add support for the termios flag
- CMSPAR, which allows the user to select stick parity.
- (i.e, if PARODD is set, the parity bit is always 1; if
- PARRODD is not set, then the parity bit is always 0).
-
-Wed Feb 26 19:03:10 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c (cleanup_module): Fix memory leak when using the serial
- driver as a module; make sure tmp_buf gets freed!
-
-Tue Feb 25 11:01:59 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c (set_modem_info): Add support for setting and clearing
- the OUT1 and OUT2 bits. (For special case UART's, usually
- for half-duplex.)
- (autoconfig, change_speed): Fix TI 16750 support.
-
-Sun Feb 16 00:14:43 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * tty_io.c (release_dev): Add sanity check to make sure there are
- no waiters on tty->read_wait or tty->write_wait.
-
- * serial.c (rs_init): Don't autoconfig a device if the I/O region
- is already reserved.
-
- * serial.c (serial_proc_info): Add support for /proc/serial.
-
-Thu Feb 13 00:49:10 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c (receive_chars): When the UART repotrs an overrun
- condition, it does so with a valid character. Changed to
- not throw away the valid character, but instead report the
- overrun after the valid character.
-
- * serial.c: Added new #ifdef's for some of the advanced serial
- driver features. A minimal driver that only supports COM
- 1/2/3/4 without sharing serial interrupts only takes 17k;
- the full driver takes 32k.
-
-Wed Feb 12 14:50:44 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * vt.c:
- * pty.c:
- * tty_ioctl.c:
- * serial.c: Update routines to use the new 2.1 memory access
- routines.
-
-Wed Dec 4 07:51:52 1996 Theodore Ts'o <tytso@localhost.mit.edu>
-
- * serial.c (change_speed): Use save_flags(); cli() and
- restore_flags() in order to ensure we don't accidentally
- turn on interrupts when starting up the port.
- (startup): Move the insertion of serial structure into the
- IRQ chain earlier into the startup processing. Interrupts
- should be off this whole time, but we eventually will want
- to reduce this window.
-
-Thu Nov 21 10:05:22 1996 Theodore Ts'o <tytso@localhost.mit.edu>
-
- * tty_ioctl.c (tty_wait_until_sent): Always check the driver
- wait_until_ready routine, even if there are no characters
- in the xmit buffer. (There may be charactes in the device
- FIFO.)
- (n_tty_ioctl): Add new flag tty->flow_stopped which
- indicates whether the tty is stopped due to a request by
- the TCXONC ioctl (used by tcflow). If so, don't let an
- incoming XOFF character restart the tty. The tty can only
- be restarted by another TCXONC request.
-
- * tty_io.c (start_tty): Don't allow the tty to be restarted if
- tty->flow_stopped is true.
-
- * n_tty.c (n_tty_receive_char): If tty->flow_stopped is true, and
- IXANY is set, don't eat a character trying to restart the
- tty.
-
- * serial.c (startup): Remove need for MCR_noint from the
- async_struct structure. Only turn on DTR and RTS if the
- baud rate is not zero.
- (change_speed): More accurately calculate the timeout
- value based on the word size. Move responsibility of
- hangup when speed becomes B0 to rs_set_termios()
- (set_serial_info): When changing the UART type set the
- current xmit_fifo_size as well as the permanent
- xmit_fifo_size.
- (rs_ioctl): Fix TCSBRK (used by tcdrain) and TCSBRKP
- ioctls to return EINTR if interrupted by a signal.
- (rs_set_termios): If the baud rate changes to or from B0,
- this function is now responsible for setting or clearing
- DTR and RTS. DTR and RTS are only be changed on the
- transition to or from the B0 state.
- (rs_close): Wait for the characters to drain based on
- info->timeout. At low baud rates (50 bps), it may take a
- long time for the FIFO to completely drain out!
- (rs_wait_until_sent): Fixed timeout handling. Now
- releases control to the scheduler, but checks frequently
- enough so that the function is sensitive enough to pass
- the timing requirements of the NIST-PCTS.
- (block_til_ready): When opening the device, don't turn on
- DTR and RTS if the baud rate is B0.
-
-Thu Nov 14 00:06:09 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c (autoconfig): Fix autoconfiguration problems;
- info->flags wasn't getting initialized from the state
- structure. Put in more paranoid test for the 16750.
-
-Fri Nov 8 20:19:50 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * n_tty.c (n_tty_flush_buffer): Only call driver->unthrottle() if
- the tty was previous throttled.
- (n_tty_set_termios, write_chan): Add changes suggested by
- Simon P. Allen to allow hardware cooking.
-
- * tty_ioctl.c (set_termios): If we get a signal while waiting for
- the tty to drain, return -EINTR.
-
- * serial.c (change_speed): Add support for CREAD, as required by
- POSIX.
-
-Sat Nov 2 20:43:10 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * serial.c: Wholesale changes. Added support for the Startech
- 16650 and 16650V2 chips. (WARNING: the new startech
- 16650A may or may not work!) Added support for the
- TI16750 (not yet tested). Split async_struct into a
- transient part (async_struct) and a permanent part
- (serial_state) which contains the configuration
- information for the ports. Added new driver routines
- wait_until_sent() and send_xchar() to help with POSIX
- compliance. Added support for radio clocks which waggle
- the carrier detect line (CONFIG_HARD_PPS).
-
- * tty_ioctl.c (tty_wait_until_sent): Added call to new driver
- function tty->driver.wait_until_sent(), which returns when
- the tty's device xmit buffers are drained. Needed for
- full POSIX compliance.
-
- (send_prio_char): New function, called by the ioctl's
- TCIOFF and TCION; uses the new driver call send_xchar(),
- which will send the XON or XOFF character at high priority
- (and even if tty output is stopped).
-
-Wed Jun 5 18:52:04 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * pty.c (pty_close): When closing a pty, make sure packet mode is
- cleared.
-
-Sun May 26 09:33:52 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * vesa_blank.c (set_vesa_blanking): Add missing verify_area() call.
-
- * selection.c (set_selection): Add missing verify_area() call.
-
- * tty_io.c (tty_ioctl): Add missing verify_area() calls.
-
- * serial.c (rs_ioctl): Add missing verify_area() calls.
- (rs_init): Allow initialization of serial driver
- configuration from a module.
-
- * random.c (extract_entropy): Add missing verify_area call.
- Don't limit number of characters returned to
- 32,768. Extract entropy is now no longer a inlined
- function.
-
- (random_read): Check return value in case extract_entropy
- returns an error.
-
- (secure_tcp_sequence_number): New function which returns a
- secure TCP sequence number. This is needed to prevent some
- nasty TCP hijacking attacks.
-
- (init_std_data): Initialize using gettimeofday() instead of
- struct timeval xtime.
-
- (fast_add_entropy_word, add_entropy_word): Rename the
- inline function add_entropy_word() to
- fast_add_entropy_word(). Make add_entropy_word() be the
- non-inlined function which is used in non-timing critical
- places, in order to save space.
-
- (initialize_benchmark, begin_benchmark, end_benchmark): New
- functions defined when RANDOM_BENCHMARK is defined. They
- allow us to benchmark the speed of the
- add_timer_randomness() call.
-
- (int_ln, rotate_left): Add two new inline functions with
- i386 optimized asm instructions. This speeds up the
- critical add_entropy_word() and add_timer_randomness()
- functions, which are called from interrupt handlers.
-
-Tue May 7 22:51:11 1996 <tytso@rsts-11.mit.edu>
-
- * random.c (add_timer_randomness): Limit the amount randomness
- that we estimate to 12 bits. (An arbitrary amount).
-
- (extract_entropy): To make it harder to analyze the hash
- function, fold the hash function in half using XOR, and
- use the folded result as the value to emit to the user.
- Also, add timer randomness each pass through the
- exact_entropy call, to increase the amount of unknown
- values during the extraction process.
-
- (random_ioctl): Use IOR/IOW definitions to define the
- ioctl values used by the /dev/random driver. Allow the
- old ioctl values to be used for backwards compatibility
- (for a limited amount of time).
-
-Wed Apr 24 14:02:04 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
-
- * random.c (add_timer_randomness): Use 2nd derivative as well to
- better estimate entropy.
-
- (rand_initialize): Explicitly initialize all the pointers
- to NULL. (Clearing pointers using memset isn't portable.)
- Initialize the random pool with OS-dependent data.
-
- (random_write): Add sanity checking to the arguments to
- random_write(), so that bad arguments won't cause a kernel
- SEGV.
-
- (random_read): Update the access time of the device inode
- when you return data to the user.
-
- (random_ioctl): Wake up the random_wait channel when there
- are only WAIT_INPUT_BITS available. Add more paranoia
- checks to make sure entropy_count doesn't go beyond the
- bounds of (0, POOLSIZE). Add a few missing verify_area
- checks. Add support for the RNDCLEARPOOL ioctl, which
- zaps the random pool.
-
- (add_timer_randomness): Wake up the random_wait
- channel only when there are WAIT_INPUT_BITS available.
-
- (random_select): Allow a random refresh daemon process to
- select on /dev/random for writing; wake up the daemon when
- there are less than WAIT_OUTPUT_BITS bits of randomness
- available.
-
-Tue Apr 23 22:56:07 1996 <tytso@rsts-11.mit.edu>
-
- * tty_io.c (init_dev): Change return code when user attempts to
- open master pty which is already open from EAGAIN to EIO,
- to match with BSD expectations. EIO is more correct
- anyway, since EAGAIN implies that retrying will be
- successful --- which it might be.... Eventually!!
-
- * pty.c (pty_open, pty_close): Fix wait loop so that we don't
- busy loop while waiting for the master side to open.
- Fix tty opening/closing logic. TTY_SLAVE_CLOSED was
- renamed to TTY_OTHER_CLOSED, so that the name is more
- descriptive. Also fixed code so that the tty flag
- actually works correctly now....
-
-Mon Apr 1 10:22:01 1996 <tytso@rsts-11.mit.edu>
-
- * serial.c (rs_close): Cleaned up modularization changes.
- Remove code which forced line discipline back to N_TTY
- this is done in the tty upper layers, and there's no
- reason to do it here. (Making this change also
- removed the requirement that the serial module access
- the internal kernel symbol "ldiscs".)
-
- * tty_io.c (tty_init): Formally register a tty_driver entry for
- /dev/tty (device 4, 0) and /dev/console (device 5, 0).
- This guarantees that major device numbers 4 and 5 will be
- reserved for the tty subsystem (as they have to be because
- of /dev/tty and /dev/console). Removed tty_regdev, as
- this interface is no longer necessary.
-
-Sun Mar 17 20:42:47 GMT 1996 <ah@doc.ic.ac.uk>
-
- * serial.c : modularisation (changes in linux/fs/device.c allow
- kerneld to automatically load the serial module).
-
- * Makefile, Config.in : serial modularisation adds.
-
- * tty_io.c : tty_init_ctty used by to register "cua" driver just
- for the /dev/tty device (5,0). Added tty_regdev.
-
- * serial.c (shutdown, rs_ioctl) : when port shuts down wakeup processes
- waiting on delta_msr_wait. The TIOCMIWAIT ioctl returns EIO
- if no change was done since the time of call.
-
-Sat Mar 16 14:33:13 1996 <aeb@cwi.nl>
-
- * tty_io.c (disassociate_ctty): If disassociate_ctty is called by
- exit, do not perform an implicit vhangup on a pty.
-
-Fri Feb 9 14:15:47 1996 <tytso@rsts-11.mit.edu>
-
- * serial.c (block_til_ready): Fixed another race condition which
- happens if a hangup happens during the open.
-
-Wed Jan 10 10:08:00 1996 <tytso@rsts-11.mit.edu>
-
- * serial.c (block_til_ready): Remove race condition which happened
- if a hangup condition happened during the setup of the
- UART, before rs_open() called block_til_ready(). This
- caused the info->count counter to be erroneously
- decremented.
-
- * serial.c (startup, rs_open): Remove race condition that could
- cause a memory leak of one page. (Fortunately, both race
- conditions were relatively rare in practice.)
-
-Tue Dec 5 13:21:27 1995 <tytso@rsts-11.mit.edu>
-
- * serial.c (check_modem_status, rs_ioctl): Support the new
- ioctl()'s TIOCGICOUNT, TIOCMIWAIT. These allow an
- application program to wait on a modem serial register
- status bit change, and to find out how many changes have
- taken place for the MSR bits.
-
- (rs_write): Eliminate a race condition which is introduced
- if it is necessary to wait for the semaphore.
-
-Sat Nov 4 17:14:45 1995 <tytso@rsts-11.mit.edu>
-
- * tty_io.c (tty_init): Move registration of TTY_MAJOR and
- TTY_AUX_MAJOR to the end, so that /proc/devices looks
- prettier.
-
- * pty.c (pty_init): Use new major numbers for PTY master and slave
- devices. This allow us to have more than 64 pty's. We
- register the old pty devices for backwards compatibility.
- Note that a system should either be using the old pty
- devices or the new pty devices --- in general, it should
- try to use both, since they map into the same pty table.
- The old pty devices are strictly for backwards compatibility.
-
-Wed Oct 11 12:45:24 1995 <tytso@rsts-11.mit.edu>
-
- * tty_io.c (disassociate_ctty): If disassociate_ctty is called by
- exit, perform an implicit vhangup on the tty.
-
- * pty.c (pty_close): When the master pty is closed, send a hangup
- to the slave pty.
- (pty_open): Use the flag TTY_SLAVE_CLOSED to test to see
- if there are any open slave ptys, instead of using
- tty->link->count. The old method got confused if there
- were processes that had hung-up file descriptors on the
- slave tty.
-
-Tue May 2 00:53:25 1995 <tytso@rsx-11.mit.edu>
-
- * tty_io.c (tty_set_ldisc): Wait until the output buffer is
- drained before closing the old line discipline --- needed
- in only one case: XON/XOFF processing.
-
- * n_tty.c (n_tty_close): Don't bother waiting until the output
- driver is closed; in general, the line discipline
- shouldn't care if the hardware is finished
- transmitting before the line discipline terminates.
-
- * tty_io.c (release_dev): Shutdown the line discipline after
- decrementing the tty count variable; but set the
- TTY_CLOSING flag so that we know that this tty structure
- isn't long for this world.
-
- * tty_io.c (init_dev): Add sanity code to check to see if
- TTY_CLOSING is set on a tty structure; if so, something
- bad has happened (probably a line discipline close blocked
- when it shouldn't have; so do a kernel printk and then
- return an error).
-
-Wed Apr 26 10:23:44 1995 Theodore Y. Ts'o <tytso@localhost>
-
- * tty_io.c (release_dev): Try to shutdown the line discipline
- *before* decrementing the tty count variable; this removes
- a potential race condition which occurs when the line
- discipline close blocks, and another process then tries
- open the same serial port.
-
- * serial.c (rs_hangup): When hanging up, flush the output buffer
- before shutting down the UART. Otherwise the line
- discipline close blocks waiting for the characters to get
- flushed, which never happens until the serial port gets reused.
-
-Wed Apr 12 08:06:16 1995 Theodore Y. Ts'o <tytso@localhost>
-
- * serial.c (do_serial_hangup, do_softint, check_modem_status,
- rs_init): Hangups are now scheduled via a separate tqueue
- structure in the async_struct structure, tqueue_hangup.
- This task is pushed on to the tq_schedule queue, so that
- it is processed synchronously by the scheduler.
-
-Sat Feb 18 12:13:51 1995 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_io.c (disassociate_ctty, tty_open, tty_ioctl): Clear
- current->tty_old_pgrp field when a session leader
- acquires a controlling tty, and after a session leader
- has disassociated from a controlling tty.
-
-Fri Feb 17 09:34:09 1995 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi):
- Change the number of passes made from 64 to be 256,
- configurable with the #define RS_ISR_PASS_LIMIT.
-
- * serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
- Remove support for closing_wait2. Instead, set
- tty->closing and rely on the line discipline to prevent
- echo wars.
-
- * n_tty.c (n_tty_receive_char): IEXTEN does not need to be
- enabled in order for IXANY to be active.
-
- If tty->closing is set, then only process XON and XOFF
- characters.
-
-Sun Feb 12 23:57:48 1995 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_timer): Change the interrupt poll time from 60
- seconds to 10 seconds, configurable with the #define
- RS_STROBE_TIME.
-
- * serial.c (rs_interrupt_multi, startup, shutdown, rs_ioctl,
- set_multiport_struct, get_multiport_struct): Add
- provisions for a new type of interrupt service routine,
- which better supports multiple serial ports on a single
- IRQ.
-
-Sun Feb 5 19:35:11 1995 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_ioctl.c (n_tty_ioctl, set_termios, tty_wait_until_sent):
- * serial.c (rs_ioctl, rs_close):
- * cyclades.c (cy_ioctl, cy_close):
- * n_tty.c (n_tty_close): Rename wait_until_sent to
- tty_wait_until_sent, so that it's a better name to export
- in ksyms.c.
-
-Sat Feb 4 23:36:20 1995 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_close): Added missing check for closing_wait2 being
- ASYNC_CLOSING_WAIT_NONE.
-
-Thu Jan 26 09:02:49 1995 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_init, set_serial_info, get_serial_info,
- rs_close): Support close_wait in the serial driver.
- This is helpful for slow devices (like serial
- plotters) so that their outputs don't get flushed upon
- device close. This has to be configurable because
- normally we don't want ports to be hung up for long
- periods of time during a close when they are not
- connected to a device, or the device is powered off.
-
- The default is to wait 30 seconds; in the case of a
- very slow device, the close_wait timeout should be
- lengthened. If it is set to 0, the kernel will wait
- forever for all of the data to be transmitted.
-
-Thu Jan 17 01:17:20 1995 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (startup, change_speed, rs_init): Add support to detect
- the StarTech 16650 chip. Treat it as a 16450 for now,
- because of its FIFO bugs.
-
-Thu Jan 5 21:21:57 1995 <dahinds@users.sourceforge.net>
-
- * serial.c: (receive_char): Added counter to prevent infinite loop
- when a PCMCIA serial device is ejected.
-
-Thu Dec 29 17:53:48 1994 <tytso@rsx-11.mit.edu>
-
- * tty_io.c (check_tty_count): New procedure which checks
- tty->count to make sure that it matches with the number of
- open file descriptors which point at the structure. If
- the number doesn't match, it prints a warning message.
-
-Wed Dec 28 15:41:51 1994 <tytso@rsx-11.mit.edu>
-
- * tty_io.c (do_tty_hangup, disassociate_ctty): At hangup time,
- save the tty's current foreground process group in the
- session leader's task structure. When the session leader
- terminates, send a SIGHUP, SIGCONT to that process group.
- This is not required by POSIX, but it's not prohibited
- either, and it appears to be the least intrusive way
- to fix a problem that dialup servers have with
- orphaned process groups caused by modem hangups.
-
-Thu Dec 8 14:52:11 1994 <tytso@rsx-11.mit.edu>
-
- * serial.c (rs_ioctl): Don't allow most ioctl's if the serial port
- isn't initialized.
-
- * serial.c (rs_close): Don't clear the IER if the serial port
- isn't initialized.
-
- * serial.c (block_til_ready): Don't try to block on the dialin
- port if the serial port isn't initialized.
-
-Wed Dec 7 10:48:30 1994 Si Park (si@wimpol.demon.co.uk)
- * tty_io.c (tty_register_driver): Fix bug when linking onto
- the tty_drivers list. We now test that there are elements
- already on the list before setting the back link from the
- first element to the new driver.
-
- * tty_io.c (tty_unregister_driver): Fix bug in unlinking the
- specified driver from the tty_drivers list. We were not
- setting the back link correctly. This used to result in
- a dangling back link pointer and cause panics on the next
- call to get_tty_driver().
-
-Tue Nov 29 10:21:09 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_io.c (tty_unregister_driver): Fix bug in
- tty_unregister_driver where the pointer to the refcount is
- tested, instead of the refcount itself. This caused
- tty_unregister_driver to always return EBUSY.
-
-Sat Nov 26 11:59:24 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_io.c (tty_ioctl): Add support for the new ioctl
- TIOCTTYGSTRUCT, which allow a kernel debugging program
- direct read access to the tty and tty_driver structures.
-
-Fri Nov 25 17:26:22 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_set_termios): Don't wake up processes blocked in
- open when the CLOCAL flag changes, since a blocking
- open only samples the CLOCAL flag once when it blocks,
- and doesn't check it again. (n.b. FreeBSD has a
- different behavior for blocking opens; it's not clear
- whether Linux or FreeBSD's interpretation is correct.
- POSIX doesn't give clear guidance on this issue, so
- this may change in the future....)
-
- * serial.c (block_til_ready): Use the correct termios structure to
- check the CLOCAL flag. If the cuaXX device is active,
- then check the saved termios for the ttySXX device.
- Otherwise, use the currently active termios structure.
-
-Sun Nov 6 21:05:44 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (change_speed): Add support for direct access of
- 57,600 and 115,200 bps.
-
-Wed Nov 2 10:32:36 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * n_tty.c (n_tty_receive_room): Only allow excess characters
- through if we are in ICANON mode *and* there are other no
- pending lines in the buffer. Otherwise cut and paste over
- 4k breaks.
-
-Sat Oct 29 18:17:34 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_ioctl, get_lsr_info): Added patch suggested by Arne
- Riiber so that user mode programs can tell when the
- transmitter shift register is empty.
-
-Thu Oct 27 23:14:29 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_ioctl.c (wait_until_sent): Added debugging printk statements
- (under the #ifdef TTY_DEBUG_WAIT_UNTIL_SENT)
-
- * serial.c (rs_interrupt, rs_interrupt_single, receive_chars,
- change_speed, rs_close): rs_close now disables receiver
- interrupts when closing the serial port. This allows the
- serial port to close quickly when Linux and a modem (or a
- mouse) are engaged in an echo war; when closing the serial
- port, we now first stop listening to incoming characters,
- and *then* wait for the transmit buffer to drain.
-
- In order to make this change, the info->read_status_mask
- is now used to control what bits of the line status
- register are looked at in the interrupt routine in all
- cases; previously it was only used in receive_chars to
- select a few of the status bits.
-
-Mon Oct 24 23:36:21 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_close): Add a timeout to the transmitter flush
- loop; this is just a sanity check in case we have flaky
- (or non-existent-but-configured-by-the-user) hardware.
-
-Fri Oct 21 09:37:23 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_io.c (tty_fasync): When asynchronous I/O is enabled, if the
- process or process group has not be specified yet, set it
- to be the tty's process group, or if that is not yet set,
- to the current process's pid.
-
-Thu Oct 20 23:17:28 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * n_tty.c (n_tty_receive_room): If we are doing input
- canonicalization, let as many characters through as
- possible, so that the excess characters can be "beeped".
-
-Tue Oct 18 10:02:43 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_start): Removed an incorrect '!' that was
- preventing transmit interrupts from being re-enabled in
- rs_start(). Fortunately in most cases it would be
- re-enabled elsewhere, but this still should be fixed
- correctly.
-
-Sun Oct 9 23:46:03 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_io.c (do_tty_hangup): If the tty driver flags
- TTY_DRIVER_RESET_TERMIOS is set, then reset the termios
- settings back to the driver's initial configuration. This
- allows the termios settings to be reset even if a process
- has hung up file descriptors keeping a pty's termios from
- being freed and reset.
-
- * tty_io.c (release_dev): Fix memory leak. The pty's other
- termios structure should also be freed.
-
- * serial.c (rs_close, shutdown): Change how we wait for the
- transmitter to completely drain before shutting down the
- serial port. We now do it by scheduling in another
- process instead of busy looping with the interrupts turned
- on. This may eliminate some race condition problems that
- some people seem to be reporting.
-
-Sun Sep 25 14:18:14 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_io.c (release_dev): When freeing a tty make sure that both
- the tty and the o_tty (if present) aren't a process's
- controlling tty. (Previously, we only checked the tty.)
-
- * serial.c (change_speed): Only enable the Modem Status
- Interrupt for a port if CLOCAL is not set or CRTSCTS
- is set. If we're not checking the carrier detect and
- CTS line, there's no point in enabling the modem
- status interrupt. This will save spurious interrupts
- from slowing down systems who have terminals that
- don't support either line. (Of course, if you want
- only one of CD and CTS support, you will need a
- properly wired serial cable.)
-
-Thu Sep 22 08:32:48 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_io.c (do_SAK): Return if tty is null.
-
- * tty_io.c (_tty_name): Return "NULL tty" if the passed in tty is
- NULL.
-
-Sat Sep 17 13:19:25 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_ioctl.c (n_tty_ioctl): Fix TIOCGLCKTRMIOS and
- TIOCSLCKTRMIOS, which were totally broken. Remove
- extra indirection from argument; it should be a struct
- termios *, not a struct termios **.
- &real_tty->termios_locked should have been
- real_tty->termios_locked. This caused us to be
- reading and writing the termios_locked structure to
- random places in kernel memory.
-
- * tty_io.c (release_dev): Oops! Forgot to delete a critical kfree
- of the locked_termios. This leaves the locked_termios
- structure pointed at a freed object.
-
-Fri Sep 16 08:13:25 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * tty_io.c (tty_open): Don't check for an exclusive open until
- after the device specific open routine has been called.
- Otherwise, the serial device ref counting will be screwed
- up.
-
- * serial.c (rs_open, block_til_ready): Don't set termios structure
- until after block_til_ready has returned successfully.
- Modify block_til_ready to check the normal_termios
- structure directly, so it doesn't rely on termios being
- set before it's called.
-
-Thu Sep 15 23:34:01 1994 Theodore Y. Ts'o (tytso@rt-11)
-
- * serial.c (rs_close): Turn off interrupts during rs_close() to
- prevent a race condition with the hangup code (which
- runs during a software interrupt).
-
- * tty_io.c (release_dev): Don't free the locked_termios structure;
- its state must be retained across device opens.
-
-
- * tty_io.c (tty_unregister_driver): Added function to unregister a
- tty driver. (For loadable device drivers.)
-
-
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 2fb3a480f6b..4b66c69eaf5 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -57,7 +57,7 @@ config AGP_AMD
config AGP_AMD64
tristate "AMD Opteron/Athlon64 on-CPU GART support"
- depends on AGP && X86
+ depends on AGP && X86 && K8_NB
help
This option gives you AGP support for the GLX component of
X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 73dbf40c874..a7637d72cef 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -6,9 +6,9 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
-#include <linux/gfp.h>
#include <linux/page-flags.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include "agp.h"
#define AMD_MMBASE 0x14
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index c3ab46da51a..ee4f855611b 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/miscdevice.h>
#include <linux/pm.h>
diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c
index 58c57cb2518..9d2c97a69cd 100644
--- a/drivers/char/agp/compat_ioctl.c
+++ b/drivers/char/agp/compat_ioctl.c
@@ -30,6 +30,7 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/agpgart.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include "agp.h"
#include "compat_ioctl.h"
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index c50543966eb..fb86708e47e 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -38,6 +38,7 @@
#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
#include <asm/pgtable.h>
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 58752b70efe..056b289a1e8 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <linux/log2.h>
+#include <linux/slab.h>
#include <asm/acpi-ext.h>
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 919a28558d3..aa4248efc5d 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -4,6 +4,7 @@
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/pagemap.h>
@@ -97,6 +98,9 @@ EXPORT_SYMBOL(intel_agp_enabled);
#define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
+#define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
+
#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
@@ -107,8 +111,7 @@ EXPORT_SYMBOL(intel_agp_enabled);
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
+ IS_SNB)
extern int agp_memory_reserved;
@@ -175,6 +178,10 @@ extern int agp_memory_reserved;
#define SNB_GMCH_GMS_STOLEN_448M (0xe << 3)
#define SNB_GMCH_GMS_STOLEN_480M (0xf << 3)
#define SNB_GMCH_GMS_STOLEN_512M (0x10 << 3)
+#define SNB_GTT_SIZE_0M (0 << 8)
+#define SNB_GTT_SIZE_1M (1 << 8)
+#define SNB_GTT_SIZE_2M (2 << 8)
+#define SNB_GTT_SIZE_MASK (3 << 8)
static const struct aper_size_info_fixed intel_i810_sizes[] =
{
@@ -298,7 +305,7 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
j++;
}
} else {
- /* sg may merge pages, but we have to seperate
+ /* sg may merge pages, but we have to separate
* per-page addr for GTT */
unsigned int len, m;
@@ -1200,6 +1207,9 @@ static void intel_i9xx_setup_flush(void)
if (intel_private.ifp_resource.start)
return;
+ if (IS_SNB)
+ return;
+
/* setup a resource for this object */
intel_private.ifp_resource.name = "Intel Flush Page";
intel_private.ifp_resource.flags = IORESOURCE_MEM;
@@ -1438,6 +1448,8 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
{
+ u16 snb_gmch_ctl;
+
switch (agp_bridge->dev->device) {
case PCI_DEVICE_ID_INTEL_GM45_HB:
case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB:
@@ -1449,9 +1461,26 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB:
case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB:
case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB:
+ *gtt_offset = *gtt_size = MB(2);
+ break;
case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB:
case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB:
- *gtt_offset = *gtt_size = MB(2);
+ *gtt_offset = MB(2);
+
+ pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl);
+ switch (snb_gmch_ctl & SNB_GTT_SIZE_MASK) {
+ default:
+ case SNB_GTT_SIZE_0M:
+ printk(KERN_ERR "Bad GTT size mask: 0x%04x.\n", snb_gmch_ctl);
+ *gtt_size = MB(0);
+ break;
+ case SNB_GTT_SIZE_1M:
+ *gtt_size = MB(1);
+ break;
+ case SNB_GTT_SIZE_2M:
+ *gtt_size = MB(2);
+ break;
+ }
break;
default:
*gtt_offset = *gtt_size = KB(512);
@@ -1788,8 +1817,6 @@ static int intel_845_configure(void)
pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
/* clear any possible error conditions */
pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
-
- intel_i830_setup_flush();
return 0;
}
@@ -2159,7 +2186,6 @@ static const struct agp_bridge_driver intel_845_driver = {
.agp_destroy_page = agp_generic_destroy_page,
.agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
- .chipset_flush = intel_i830_chipset_flush,
};
static const struct agp_bridge_driver intel_850_driver = {
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 7e36d2b4f9d..10f24e349a2 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -8,7 +8,6 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
-#include <linux/gfp.h>
#include <linux/page-flags.h>
#include <linux/mm.h>
#include <linux/jiffies.h>
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 0d426ae39c8..ffa888cd1c8 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -14,6 +14,7 @@
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <asm/sn/addrs.h>
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index d89da4ac061..6f48931ac1c 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -3,6 +3,7 @@
*/
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pagemap.h>
#include <linux/agp_backend.h>
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 6c32fbf0716..56b27671adc 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -2021,8 +2021,6 @@ static int __init rs_init(void)
state->baud_base = amiga_colorclock;
state->xmit_fifo_size = 1;
- local_irq_save(flags);
-
/* set ISRs, and then disable the rx interrupts */
error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
if (error)
@@ -2033,6 +2031,8 @@ static int __init rs_init(void)
if (error)
goto fail_free_irq;
+ local_irq_save(flags);
+
/* turn off Rx and Tx interrupts */
custom.intena = IF_RBF | IF_TBE;
mb();
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index fe2cb2f5db1..a7424bf7eac 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -14,7 +14,7 @@
/* et passe en argument a acinit, mais est scrute sur le bus pour s'adapter */
/* au nombre de cartes presentes sur le bus. IOCL code 6 affichait V2.4.3 */
/* F.LAFORSE 28/11/95 creation de fichiers acXX.o avec les differentes */
-/* adresses de base des cartes, IOCTL 6 plus complet */
+/* addresses de base des cartes, IOCTL 6 plus complet */
/* J.PAGET le 19/08/96 copie de la version V2.6 en V2.8.0 sans modification */
/* de code autre que le texte V2.6.1 en V2.8.0 */
/*****************************************************************************/
diff --git a/drivers/char/bfin_jtag_comm.c b/drivers/char/bfin_jtag_comm.c
index 2628c7415ea..e397df3ad98 100644
--- a/drivers/char/bfin_jtag_comm.c
+++ b/drivers/char/bfin_jtag_comm.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index d8cff909001..555cd93c2ee 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index c02db01f736..7fef305774d 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -27,6 +27,7 @@
#include <linux/cdev.h>
#include <linux/list.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <asm/pgtable.h>
#include <asm/io.h>
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index b861c08263a..9824b416290 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -79,6 +79,7 @@
#include <linux/bitops.h>
#include <linux/firmware.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <linux/uaccess.h>
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 85832ab924e..8a1b28a10ef 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -24,7 +24,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h> /* for kmalloc() and kfree() */
#include <linux/major.h>
#include <linux/types.h>
#include <linux/errno.h>
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 17b044a71e0..6f5ffe1320f 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -36,7 +36,6 @@
#include <linux/ctype.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
-#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index d400cbd280f..5954ee1dc95 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -29,6 +29,7 @@
#include <linux/interrupt.h>
#include <linux/tty_flip.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#define DEBUG
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index e481c5938ba..9ded667625a 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -31,6 +31,7 @@
#include <linux/seq_file.h>
#include <linux/bitops.h>
#include <linux/clocksource.h>
+#include <linux/slab.h>
#include <asm/current.h>
#include <asm/uaccess.h>
@@ -215,9 +216,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
else
v &= ~0xffff;
- for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
- irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
-
+ for_each_set_bit(irq, &v, HPET_MAX_IRQ) {
if (irq >= nr_irqs) {
irq = HPET_MAX_IRQ;
break;
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 465185fc0f5..35cca4c7fb1 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -38,6 +38,7 @@
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/freezer.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -312,6 +313,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
spin_lock_irqsave(&hp->lock, flags);
/* Check and then increment for fast path open. */
if (hp->count++ > 0) {
+ tty_kref_get(tty);
spin_unlock_irqrestore(&hp->lock, flags);
hvc_kick();
return 0;
@@ -319,7 +321,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
tty->driver_data = hp;
- hp->tty = tty;
+ hp->tty = tty_kref_get(tty);
spin_unlock_irqrestore(&hp->lock, flags);
@@ -336,6 +338,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
spin_lock_irqsave(&hp->lock, flags);
hp->tty = NULL;
spin_unlock_irqrestore(&hp->lock, flags);
+ tty_kref_put(tty);
tty->driver_data = NULL;
kref_put(&hp->kref, destroy_hvc_struct);
printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
@@ -363,6 +366,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
return;
hp = tty->driver_data;
+
spin_lock_irqsave(&hp->lock, flags);
if (--hp->count == 0) {
@@ -389,6 +393,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
spin_unlock_irqrestore(&hp->lock, flags);
}
+ tty_kref_put(tty);
kref_put(&hp->kref, destroy_hvc_struct);
}
@@ -424,10 +429,11 @@ static void hvc_hangup(struct tty_struct *tty)
spin_unlock_irqrestore(&hp->lock, flags);
if (hp->ops->notifier_hangup)
- hp->ops->notifier_hangup(hp, hp->data);
+ hp->ops->notifier_hangup(hp, hp->data);
while(temp_open_count) {
--temp_open_count;
+ tty_kref_put(tty);
kref_put(&hp->kref, destroy_hvc_struct);
}
}
@@ -592,7 +598,7 @@ int hvc_poll(struct hvc_struct *hp)
}
/* No tty attached, just skip */
- tty = hp->tty;
+ tty = tty_kref_get(hp->tty);
if (tty == NULL)
goto bail;
@@ -672,6 +678,8 @@ int hvc_poll(struct hvc_struct *hp)
tty_flip_buffer_push(tty);
}
+ if (tty)
+ tty_kref_put(tty);
return poll_mask;
}
@@ -807,7 +815,7 @@ int hvc_remove(struct hvc_struct *hp)
struct tty_struct *tty;
spin_lock_irqsave(&hp->lock, flags);
- tty = hp->tty;
+ tty = tty_kref_get(hp->tty);
if (hp->index < MAX_NR_HVC_CONSOLES)
vtermnos[hp->index] = -1;
@@ -819,18 +827,18 @@ int hvc_remove(struct hvc_struct *hp)
/*
* We 'put' the instance that was grabbed when the kref instance
* was initialized using kref_init(). Let the last holder of this
- * kref cause it to be removed, which will probably be the tty_hangup
+ * kref cause it to be removed, which will probably be the tty_vhangup
* below.
*/
kref_put(&hp->kref, destroy_hvc_struct);
/*
- * This function call will auto chain call hvc_hangup. The tty should
- * always be valid at this time unless a simultaneous tty close already
- * cleaned up the hvc_struct.
+ * This function call will auto chain call hvc_hangup.
*/
- if (tty)
- tty_hangup(tty);
+ if (tty) {
+ tty_vhangup(tty);
+ tty_kref_put(tty);
+ }
return 0;
}
EXPORT_SYMBOL_GPL(hvc_remove);
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
index fd0242676a2..21c54955084 100644
--- a/drivers/char/hvc_iseries.c
+++ b/drivers/char/hvc_iseries.c
@@ -353,7 +353,7 @@ static void hvc_close_event(struct HvLpEvent *event)
if (!hvlpevent_is_int(event)) {
printk(KERN_WARNING
- "hvc: got unexpected close acknowlegement\n");
+ "hvc: got unexpected close acknowledgement\n");
return;
}
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index 21681a81cc3..5a80ad68ef2 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -12,6 +12,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/types.h>
+#include <linux/slab.h>
#include <asm/ebcdic.h>
#include <linux/ctype.h>
#include <linux/delay.h>
@@ -139,6 +140,8 @@ struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
*
* This function allocates a new struct iucv_tty_buffer element and, optionally,
* allocates an internal data buffer with the specified size @size.
+ * The internal data buffer is always allocated with GFP_DMA which is
+ * required for receiving and sending data with IUCV.
* Note: The total message size arises from the internal buffer size and the
* members of the iucv_tty_msg structure.
* The function returns NULL if memory allocation has failed.
@@ -154,7 +157,7 @@ static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
if (size > 0) {
bufp->msg.length = MSG_SIZE(size);
- bufp->mbuf = kmalloc(bufp->msg.length, flags);
+ bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA);
if (!bufp->mbuf) {
mempool_free(bufp, hvc_iucv_mempool);
return NULL;
@@ -237,7 +240,7 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv,
if (!rb->mbuf) { /* message not yet received ... */
/* allocate mem to store msg data; if no memory is available
* then leave the buffer on the list and re-try later */
- rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC);
+ rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA);
if (!rb->mbuf)
return -ENOMEM;
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 266b858b8f8..bedc6c1b6fa 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -74,6 +74,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stat.h>
#include <linux/tty.h>
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index 91b53eb1c05..86fe45c1996 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -30,6 +30,7 @@
#include <linux/pci.h>
#include <linux/stop_machine.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/io.h>
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index 9b3e09cd41f..10f868eefaa 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -71,7 +71,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
* x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1
*
* The RNG_CTL_VCO value of each noise cell must be programmed
- * seperately. This is why 4 control register values must be provided
+ * separately. This is why 4 control register values must be provided
* to the hypervisor. During a write, the hypervisor writes them all,
* one at a time, to the actual RNG_CTL register. The first three
* values are used to setup the desired RNG_CTL_VCO for each entropy
diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c
index 54b0d9ba65c..9cd0feca318 100644
--- a/drivers/char/hw_random/octeon-rng.c
+++ b/drivers/char/hw_random/octeon-rng.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/hw_random.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-rnm-defs.h>
diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c
index 544d9085a8e..0bc0cb70210 100644
--- a/drivers/char/hw_random/tx4939-rng.c
+++ b/drivers/char/hw_random/tx4939-rng.c
@@ -14,6 +14,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>
+#include <linux/gfp.h>
#define TX4939_RNG_RCSR 0x00000000
#define TX4939_RNG_ROR(n) (0x00000018 + (n) * 8)
diff --git a/drivers/char/ip2/i2hw.h b/drivers/char/ip2/i2hw.h
index 8aa6e7ab8d5..c0ba6c05f0c 100644
--- a/drivers/char/ip2/i2hw.h
+++ b/drivers/char/ip2/i2hw.h
@@ -559,7 +559,7 @@ Loadware may be sent to the board in two ways:
2) It may be hard-coded into your source by including a .h file (typically
supplied by Computone), which declares a data array and initializes every
- element. This acheives the same result as if an entire loadware file had
+ element. This achieves the same result as if an entire loadware file had
been read into the array.
This requires more data space in your program, but access to the file system
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index ec5e3f8df64..c6ad4234378 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2272,42 +2272,52 @@ static int create_files(struct bmc_device *bmc)
bmc->device_id_attr.attr.name = "device_id";
bmc->device_id_attr.attr.mode = S_IRUGO;
bmc->device_id_attr.show = device_id_show;
+ sysfs_attr_init(&bmc->device_id_attr.attr);
bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
+ sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr);
bmc->revision_attr.attr.name = "revision";
bmc->revision_attr.attr.mode = S_IRUGO;
bmc->revision_attr.show = revision_show;
+ sysfs_attr_init(&bmc->revision_attr.attr);
bmc->firmware_rev_attr.attr.name = "firmware_revision";
bmc->firmware_rev_attr.attr.mode = S_IRUGO;
bmc->firmware_rev_attr.show = firmware_rev_show;
+ sysfs_attr_init(&bmc->firmware_rev_attr.attr);
bmc->version_attr.attr.name = "ipmi_version";
bmc->version_attr.attr.mode = S_IRUGO;
bmc->version_attr.show = ipmi_version_show;
+ sysfs_attr_init(&bmc->version_attr.attr);
bmc->add_dev_support_attr.attr.name = "additional_device_support";
bmc->add_dev_support_attr.attr.mode = S_IRUGO;
bmc->add_dev_support_attr.show = add_dev_support_show;
+ sysfs_attr_init(&bmc->add_dev_support_attr.attr);
bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
bmc->manufacturer_id_attr.show = manufacturer_id_show;
+ sysfs_attr_init(&bmc->manufacturer_id_attr.attr);
bmc->product_id_attr.attr.name = "product_id";
bmc->product_id_attr.attr.mode = S_IRUGO;
bmc->product_id_attr.show = product_id_show;
+ sysfs_attr_init(&bmc->product_id_attr.attr);
bmc->guid_attr.attr.name = "guid";
bmc->guid_attr.attr.mode = S_IRUGO;
bmc->guid_attr.show = guid_show;
+ sysfs_attr_init(&bmc->guid_attr.attr);
bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
+ sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr);
err = device_create_file(&bmc->dev->dev,
&bmc->device_id_attr);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 176f1751237..4462b113ba3 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -295,6 +295,9 @@ struct smi_info {
static int force_kipmid[SI_MAX_PARMS];
static int num_force_kipmid;
+static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
+static int num_max_busy_us;
+
static int unload_when_empty = 1;
static int try_smi_init(struct smi_info *smi);
@@ -925,23 +928,77 @@ static void set_run_to_completion(void *send_info, int i_run_to_completion)
}
}
+/*
+ * Use -1 in the nsec value of the busy waiting timespec to tell that
+ * we are spinning in kipmid looking for something and not delaying
+ * between checks
+ */
+static inline void ipmi_si_set_not_busy(struct timespec *ts)
+{
+ ts->tv_nsec = -1;
+}
+static inline int ipmi_si_is_busy(struct timespec *ts)
+{
+ return ts->tv_nsec != -1;
+}
+
+static int ipmi_thread_busy_wait(enum si_sm_result smi_result,
+ const struct smi_info *smi_info,
+ struct timespec *busy_until)
+{
+ unsigned int max_busy_us = 0;
+
+ if (smi_info->intf_num < num_max_busy_us)
+ max_busy_us = kipmid_max_busy_us[smi_info->intf_num];
+ if (max_busy_us == 0 || smi_result != SI_SM_CALL_WITH_DELAY)
+ ipmi_si_set_not_busy(busy_until);
+ else if (!ipmi_si_is_busy(busy_until)) {
+ getnstimeofday(busy_until);
+ timespec_add_ns(busy_until, max_busy_us*NSEC_PER_USEC);
+ } else {
+ struct timespec now;
+ getnstimeofday(&now);
+ if (unlikely(timespec_compare(&now, busy_until) > 0)) {
+ ipmi_si_set_not_busy(busy_until);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+/*
+ * A busy-waiting loop for speeding up IPMI operation.
+ *
+ * Lousy hardware makes this hard. This is only enabled for systems
+ * that are not BT and do not have interrupts. It starts spinning
+ * when an operation is complete or until max_busy tells it to stop
+ * (if that is enabled). See the paragraph on kimid_max_busy_us in
+ * Documentation/IPMI.txt for details.
+ */
static int ipmi_thread(void *data)
{
struct smi_info *smi_info = data;
unsigned long flags;
enum si_sm_result smi_result;
+ struct timespec busy_until;
+ ipmi_si_set_not_busy(&busy_until);
set_user_nice(current, 19);
while (!kthread_should_stop()) {
+ int busy_wait;
+
spin_lock_irqsave(&(smi_info->si_lock), flags);
smi_result = smi_event_handler(smi_info, 0);
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
+ busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
+ &busy_until);
if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
; /* do nothing */
- else if (smi_result == SI_SM_CALL_WITH_DELAY)
+ else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
schedule();
else
- schedule_timeout_interruptible(1);
+ schedule_timeout_interruptible(0);
}
return 0;
}
@@ -1144,7 +1201,7 @@ static int regsizes[SI_MAX_PARMS];
static unsigned int num_regsizes;
static int regshifts[SI_MAX_PARMS];
static unsigned int num_regshifts;
-static int slave_addrs[SI_MAX_PARMS];
+static int slave_addrs[SI_MAX_PARMS]; /* Leaving 0 chooses the default value */
static unsigned int num_slave_addrs;
#define IPMI_IO_ADDR_SPACE 0
@@ -1212,6 +1269,11 @@ module_param(unload_when_empty, int, 0);
MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are"
" specified or found, default is 1. Setting to 0"
" is useful for hot add of devices using hotmod.");
+module_param_array(kipmid_max_busy_us, uint, &num_max_busy_us, 0644);
+MODULE_PARM_DESC(kipmid_max_busy_us,
+ "Max time (in microseconds) to busy-wait for IPMI data before"
+ " sleeping. 0 (default) means to wait forever. Set to 100-500"
+ " if kipmid is using up a lot of CPU time.");
static void std_irq_cleanup(struct smi_info *info)
@@ -1607,7 +1669,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
regsize = 1;
regshift = 0;
irq = 0;
- ipmb = 0x20;
+ ipmb = 0; /* Choose the default if not specified */
next = strchr(curr, ':');
if (next) {
@@ -1799,6 +1861,7 @@ static __devinit void hardcode_find_bmc(void)
info->irq = irqs[i];
if (info->irq)
info->irq_setup = std_irq_setup;
+ info->slave_addr = slave_addrs[i];
try_smi_init(info);
}
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index be2e8f9a27c..c1ab303455c 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -130,6 +130,7 @@
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>
@@ -878,8 +879,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
if (tport == NULL)
return -ENODEV;
port = container_of(tport, struct isi_port, port);
- card = &isi_card[BOARD(tty->index)];
+ tty->driver_data = port;
return tty_port_open(tport, tty, filp);
}
@@ -935,7 +936,12 @@ static void isicom_shutdown(struct tty_port *port)
static void isicom_close(struct tty_struct *tty, struct file *filp)
{
struct isi_port *ip = tty->driver_data;
- struct tty_port *port = &ip->port;
+ struct tty_port *port;
+
+ if (ip == NULL)
+ return;
+
+ port = &ip->port;
if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
return;
tty_port_close(port, tty, filp);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 4cd6c527ee4..4e395c956a0 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -827,6 +827,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
return -ENODEV;
if (portp->devnr < 1)
return -ENODEV;
+
+ tty->driver_data = portp;
return tty_port_open(&portp->port, tty, filp);
}
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 87c67b42bc0..83bef4efe37 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -26,6 +26,7 @@
#include <linux/uio.h>
#include <linux/mutex.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 48788db4e28..f54dab8acdc 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
- * Added devfs support.
+ * Added devfs support.
* Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
* Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
*/
@@ -44,36 +44,6 @@ static inline unsigned long size_inside_page(unsigned long start,
return min(sz, size);
}
-/*
- * Architectures vary in how they handle caching for addresses
- * outside of main memory.
- *
- */
-static inline int uncached_access(struct file *file, unsigned long addr)
-{
-#if defined(CONFIG_IA64)
- /*
- * On ia64, we ignore O_DSYNC because we cannot tolerate memory attribute aliases.
- */
- return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
-#elif defined(CONFIG_MIPS)
- {
- extern int __uncached_access(struct file *file,
- unsigned long addr);
-
- return __uncached_access(file, addr);
- }
-#else
- /*
- * Accessing memory above the top the kernel knows about or through a file pointer
- * that was marked O_DSYNC will be done non-cached.
- */
- if (file->f_flags & O_DSYNC)
- return 1;
- return addr >= __pa(high_memory);
-#endif
-}
-
#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
static inline int valid_phys_addr_range(unsigned long addr, size_t count)
{
@@ -115,15 +85,15 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
}
#endif
-void __attribute__((weak)) unxlate_dev_mem_ptr(unsigned long phys, void *addr)
+void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr)
{
}
/*
- * This funcion reads the *physical* memory. The f_pos points directly to the
- * memory location.
+ * This funcion reads the *physical* memory. The f_pos points directly to the
+ * memory location.
*/
-static ssize_t read_mem(struct file * file, char __user * buf,
+static ssize_t read_mem(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
@@ -140,10 +110,10 @@ static ssize_t read_mem(struct file * file, char __user * buf,
if (sz > 0) {
if (clear_user(buf, sz))
return -EFAULT;
- buf += sz;
- p += sz;
- count -= sz;
- read += sz;
+ buf += sz;
+ p += sz;
+ count -= sz;
+ read += sz;
}
}
#endif
@@ -157,9 +127,9 @@ static ssize_t read_mem(struct file * file, char __user * buf,
return -EPERM;
/*
- * On ia64 if a page has been mapped somewhere as
- * uncached, then it must also be accessed uncached
- * by the kernel or data corruption may occur
+ * On ia64 if a page has been mapped somewhere as uncached, then
+ * it must also be accessed uncached by the kernel or data
+ * corruption may occur.
*/
ptr = xlate_dev_mem_ptr(p);
if (!ptr)
@@ -180,7 +150,7 @@ static ssize_t read_mem(struct file * file, char __user * buf,
return read;
}
-static ssize_t write_mem(struct file * file, const char __user * buf,
+static ssize_t write_mem(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
@@ -212,9 +182,9 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
return -EPERM;
/*
- * On ia64 if a page has been mapped somewhere as
- * uncached, then it must also be accessed uncached
- * by the kernel or data corruption may occur
+ * On ia64 if a page has been mapped somewhere as uncached, then
+ * it must also be accessed uncached by the kernel or data
+ * corruption may occur.
*/
ptr = xlate_dev_mem_ptr(p);
if (!ptr) {
@@ -242,13 +212,48 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
return written;
}
-int __attribute__((weak)) phys_mem_access_prot_allowed(struct file *file,
+int __weak phys_mem_access_prot_allowed(struct file *file,
unsigned long pfn, unsigned long size, pgprot_t *vma_prot)
{
return 1;
}
#ifndef __HAVE_PHYS_MEM_ACCESS_PROT
+
+/*
+ * Architectures vary in how they handle caching for addresses
+ * outside of main memory.
+ *
+ */
+#ifdef pgprot_noncached
+static int uncached_access(struct file *file, unsigned long addr)
+{
+#if defined(CONFIG_IA64)
+ /*
+ * On ia64, we ignore O_DSYNC because we cannot tolerate memory
+ * attribute aliases.
+ */
+ return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
+#elif defined(CONFIG_MIPS)
+ {
+ extern int __uncached_access(struct file *file,
+ unsigned long addr);
+
+ return __uncached_access(file, addr);
+ }
+#else
+ /*
+ * Accessing memory above the top the kernel knows about or through a
+ * file pointer
+ * that was marked O_DSYNC will be done non-cached.
+ */
+ if (file->f_flags & O_DSYNC)
+ return 1;
+ return addr >= __pa(high_memory);
+#endif
+}
+#endif
+
static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
{
@@ -294,7 +299,7 @@ static const struct vm_operations_struct mmap_mem_ops = {
#endif
};
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+static int mmap_mem(struct file *file, struct vm_area_struct *vma)
{
size_t size = vma->vm_end - vma->vm_start;
@@ -329,7 +334,7 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
}
#ifdef CONFIG_DEVKMEM
-static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
+static int mmap_kmem(struct file *file, struct vm_area_struct *vma)
{
unsigned long pfn;
@@ -337,9 +342,9 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
/*
- * RED-PEN: on some architectures there is more mapped memory
- * than available in mem_map which pfn_valid checks
- * for. Perhaps should add a new macro here.
+ * RED-PEN: on some architectures there is more mapped memory than
+ * available in mem_map which pfn_valid checks for. Perhaps should add a
+ * new macro here.
*
* RED-PEN: vmalloc is not supported right now.
*/
@@ -389,7 +394,7 @@ static ssize_t read_oldmem(struct file *file, char __user *buf,
/*
* This function reads the *virtual* memory as seen by the kernel.
*/
-static ssize_t read_kmem(struct file *file, char __user *buf,
+static ssize_t read_kmem(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
@@ -400,8 +405,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
read = 0;
if (p < (unsigned long) high_memory) {
low_count = count;
- if (count > (unsigned long) high_memory - p)
- low_count = (unsigned long) high_memory - p;
+ if (count > (unsigned long)high_memory - p)
+ low_count = (unsigned long)high_memory - p;
#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
/* we don't have page 0 mapped on sparc and m68k.. */
@@ -465,9 +470,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
}
-static inline ssize_t
-do_write_kmem(unsigned long p, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t do_write_kmem(unsigned long p, const char __user *buf,
+ size_t count, loff_t *ppos)
{
ssize_t written, sz;
unsigned long copied;
@@ -491,9 +495,9 @@ do_write_kmem(unsigned long p, const char __user *buf,
sz = size_inside_page(p, count);
/*
- * On ia64 if a page has been mapped somewhere as
- * uncached, then it must also be accessed uncached
- * by the kernel or data corruption may occur
+ * On ia64 if a page has been mapped somewhere as uncached, then
+ * it must also be accessed uncached by the kernel or data
+ * corruption may occur.
*/
ptr = xlate_dev_kmem_ptr((char *)p);
@@ -514,11 +518,10 @@ do_write_kmem(unsigned long p, const char __user *buf,
return written;
}
-
/*
* This function writes to the *virtual* memory as seen by the kernel.
*/
-static ssize_t write_kmem(struct file * file, const char __user * buf,
+static ssize_t write_kmem(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
@@ -570,17 +573,17 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
#endif
#ifdef CONFIG_DEVPORT
-static ssize_t read_port(struct file * file, char __user * buf,
+static ssize_t read_port(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long i = *ppos;
char __user *tmp = buf;
if (!access_ok(VERIFY_WRITE, buf, count))
- return -EFAULT;
+ return -EFAULT;
while (count-- > 0 && i < 65536) {
- if (__put_user(inb(i),tmp) < 0)
- return -EFAULT;
+ if (__put_user(inb(i), tmp) < 0)
+ return -EFAULT;
i++;
tmp++;
}
@@ -588,22 +591,22 @@ static ssize_t read_port(struct file * file, char __user * buf,
return tmp-buf;
}
-static ssize_t write_port(struct file * file, const char __user * buf,
+static ssize_t write_port(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long i = *ppos;
const char __user * tmp = buf;
- if (!access_ok(VERIFY_READ,buf,count))
+ if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
while (count-- > 0 && i < 65536) {
char c;
if (__get_user(c, tmp)) {
if (tmp > buf)
break;
- return -EFAULT;
+ return -EFAULT;
}
- outb(c,i);
+ outb(c, i);
i++;
tmp++;
}
@@ -612,13 +615,13 @@ static ssize_t write_port(struct file * file, const char __user * buf,
}
#endif
-static ssize_t read_null(struct file * file, char __user * buf,
+static ssize_t read_null(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
return 0;
}
-static ssize_t write_null(struct file * file, const char __user * buf,
+static ssize_t write_null(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return count;
@@ -630,13 +633,13 @@ static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
return sd->len;
}
-static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out,
+static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out,
loff_t *ppos, size_t len, unsigned int flags)
{
return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
}
-static ssize_t read_zero(struct file * file, char __user * buf,
+static ssize_t read_zero(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
size_t written;
@@ -667,7 +670,7 @@ static ssize_t read_zero(struct file * file, char __user * buf,
return written ? written : -EFAULT;
}
-static int mmap_zero(struct file * file, struct vm_area_struct * vma)
+static int mmap_zero(struct file *file, struct vm_area_struct *vma)
{
#ifndef CONFIG_MMU
return -ENOSYS;
@@ -677,7 +680,7 @@ static int mmap_zero(struct file * file, struct vm_area_struct * vma)
return 0;
}
-static ssize_t write_full(struct file * file, const char __user * buf,
+static ssize_t write_full(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return -ENOSPC;
@@ -688,8 +691,7 @@ static ssize_t write_full(struct file * file, const char __user * buf,
* can fopen() both devices with "a" now. This was previously impossible.
* -- SRB.
*/
-
-static loff_t null_lseek(struct file * file, loff_t offset, int orig)
+static loff_t null_lseek(struct file *file, loff_t offset, int orig)
{
return file->f_pos = 0;
}
@@ -702,24 +704,26 @@ static loff_t null_lseek(struct file * file, loff_t offset, int orig)
* also note that seeking relative to the "end of file" isn't supported:
* it has no meaning, so it returns -EINVAL.
*/
-static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
+static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
{
loff_t ret;
mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
switch (orig) {
- case 0:
- file->f_pos = offset;
- ret = file->f_pos;
- force_successful_syscall_return();
- break;
- case 1:
- file->f_pos += offset;
- ret = file->f_pos;
- force_successful_syscall_return();
+ case SEEK_CUR:
+ offset += file->f_pos;
+ case SEEK_SET:
+ /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */
+ if ((unsigned long long)offset >= ~0xFFFULL) {
+ ret = -EOVERFLOW;
break;
- default:
- ret = -EINVAL;
+ }
+ file->f_pos = offset;
+ ret = file->f_pos;
+ force_successful_syscall_return();
+ break;
+ default:
+ ret = -EINVAL;
}
mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
return ret;
@@ -803,7 +807,7 @@ static const struct file_operations oldmem_fops = {
};
#endif
-static ssize_t kmsg_write(struct file * file, const char __user * buf,
+static ssize_t kmsg_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char *tmp;
@@ -825,7 +829,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf,
}
static const struct file_operations kmsg_fops = {
- .write = kmsg_write,
+ .write = kmsg_write,
};
static const struct memdev {
@@ -876,7 +880,7 @@ static int memory_open(struct inode *inode, struct file *filp)
}
static const struct file_operations memory_fops = {
- .open = memory_open,
+ .open = memory_open,
};
static char *mem_devnode(struct device *dev, mode_t *mode)
@@ -897,10 +901,13 @@ static int __init chr_dev_init(void)
if (err)
return err;
- if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
+ if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
mem_class = class_create(THIS_MODULE, "mem");
+ if (IS_ERR(mem_class))
+ return PTR_ERR(mem_class);
+
mem_class->devnode = mem_devnode;
for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
if (!devlist[minor].name)
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 94a136e96c0..92ab03d2829 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -40,7 +40,6 @@
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
-#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
@@ -49,6 +48,7 @@
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
+#include <linux/gfp.h>
/*
* Head entry for the doubly linked miscdevice list
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index 918711aa56f..ea7c99fa978 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -33,6 +33,7 @@
#include <linux/time.h>
#include <linux/math64.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/sn/addrs.h>
@@ -546,7 +547,7 @@ static void mmtimer_tasklet(unsigned long data)
{
int nodeid = data;
struct mmtimer_node *mn = &timers[nodeid];
- struct mmtimer *x = rb_entry(mn->next, struct mmtimer, list);
+ struct mmtimer *x;
struct k_itimer *t;
unsigned long flags;
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 166495d6a1d..107b0bd58d1 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -43,6 +43,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index e0c5d2a6904..d2692d443f7 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -33,12 +33,12 @@
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
-#include <linux/gfp.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -1011,6 +1011,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
if (!info->ioaddr)
return -ENODEV;
+ tty->driver_data = info;
return tty_port_open(&info->port, tty, filp);
}
@@ -1074,7 +1075,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
struct mxser_port *info = tty->driver_data;
struct tty_port *port = &info->port;
- if (tty->index == MXSER_PORTS)
+ if (tty->index == MXSER_PORTS || info == NULL)
return;
if (tty_port_close_start(port, tty, filp) == 0)
return;
@@ -1768,7 +1769,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
int len, lsr;
len = mxser_chars_in_buffer(tty);
- spin_lock(&info->slock);
+ spin_lock_irq(&info->slock);
lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
spin_unlock_irq(&info->slock);
len += (lsr ? 0 : 1);
@@ -1778,12 +1779,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
case MOXA_ASPP_MON: {
int mcr, status;
- spin_lock(&info->slock);
+ spin_lock_irq(&info->slock);
status = mxser_get_msr(info->ioaddr, 1, tty->index);
mxser_check_modem_status(tty, info, status);
mcr = inb(info->ioaddr + UART_MCR);
- spin_unlock(&info->slock);
+ spin_unlock_irq(&info->slock);
if (mcr & MOXA_MUST_MCR_XON_FLAG)
info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 2e50f4dfc79..bdae8327143 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -48,6 +48,7 @@
#include <linux/audit.h>
#include <linux/file.h>
#include <linux/uaccess.h>
+#include <linux/module.h>
#include <asm/system.h>
@@ -2091,3 +2092,19 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = {
.receive_buf = n_tty_receive_buf,
.write_wakeup = n_tty_write_wakeup
};
+
+/**
+ * n_tty_inherit_ops - inherit N_TTY methods
+ * @ops: struct tty_ldisc_ops where to save N_TTY methods
+ *
+ * Used by a generic struct tty_ldisc_ops to easily inherit N_TTY
+ * methods.
+ */
+
+void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
+{
+ *ops = tty_ldisc_N_TTY;
+ ops->owner = NULL;
+ ops->refcount = ops->flags = 0;
+}
+EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index a3f32a15fde..a6638003f53 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -55,6 +55,7 @@
#include <linux/init.h>
#include <linux/kfifo.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <linux/delay.h>
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 5eb83c3ca20..47e8f7b0e4c 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -100,7 +100,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/mc146818rtc.h>
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index c9bc896d68a..90b199f97be 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */
/* last check before exit */
- if (!io_detect_cm4000(iobase, dev))
- count = -ENODEV;
+ if (!io_detect_cm4000(iobase, dev)) {
+ rc = -ENODEV;
+ goto release_io;
+ }
if (test_bit(IS_INVREV, &dev->flags) && count > 0)
str_invert_revert(dev->rbuf, count);
if (copy_to_user(buf, dev->rbuf, count))
- return -EFAULT;
+ rc = -EFAULT;
release_io:
clear_bit(LOCK_IO, &dev->flags);
diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c
index 590762a7f21..65920163f53 100644
--- a/drivers/char/pcmcia/ipwireless/network.c
+++ b/drivers/char/pcmcia/ipwireless/network.c
@@ -21,6 +21,7 @@
#include <linux/netdevice.h>
#include <linux/ppp_channel.h>
#include <linux/ppp_defs.h>
+#include <linux/slab.h>
#include <linux/if_ppp.h>
#include <linux/skbuff.h>
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 432655bcb04..fdd37543aa7 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -64,6 +64,7 @@
#include <linux/parport.h>
#include <linux/ctype.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/major.h>
#include <linux/ppdev.h>
#include <linux/smp_lock.h>
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index f424d394a28..606048b72bc 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <asm/lv1call.h>
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 385c44b3034..d83a43130df 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -29,6 +29,7 @@
#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/devpts_fs.h>
+#include <linux/slab.h>
#include <asm/system.h>
@@ -220,7 +221,7 @@ static void pty_set_termios(struct tty_struct *tty,
* @tty: tty being resized
* @ws: window size being set.
*
- * Update the termios variables and send the neccessary signals to
+ * Update the termios variables and send the necessary signals to
* peform a terminal resize correctly
*/
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 2849713d223..2fd3d39995d 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1191,7 +1191,7 @@ const struct file_operations urandom_fops = {
void generate_random_uuid(unsigned char uuid_out[16])
{
get_random_bytes(uuid_out, 16);
- /* Set UUID version to 4 --- truely random generation */
+ /* Set UUID version to 4 --- truly random generation */
uuid_out[6] = (uuid_out[6] & 0x0F) | 0x40;
/* Set the UUID variant to DCE */
uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80;
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 64acd05f71c..8756ab0daa8 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/smp_lock.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
@@ -247,6 +248,7 @@ static const struct file_operations raw_fops = {
.aio_read = generic_file_aio_read,
.write = do_sync_write,
.aio_write = blkdev_aio_write,
+ .fsync = blkdev_fsync,
.open = raw_open,
.release= raw_release,
.ioctl = raw_ioctl,
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index be0ba401966..24a282bb89d 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -31,7 +31,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <asm/io.h>
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
index 71f87600907..2e71aecae20 100644
--- a/drivers/char/rio/riointr.c
+++ b/drivers/char/rio/riointr.c
@@ -31,7 +31,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
index d687c17be15..6415f3f32a7 100644
--- a/drivers/char/rio/rioparam.c
+++ b/drivers/char/rio/rioparam.c
@@ -31,7 +31,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <asm/io.h>
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
index 706c2a25f7a..f9b936ac339 100644
--- a/drivers/char/rio/rioroute.c
+++ b/drivers/char/rio/rioroute.c
@@ -31,7 +31,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/system.h>
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index 47fab7c3307..8a90393faf3 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -34,7 +34,6 @@
#include <linux/module.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/string.h>
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 0a8d1e56c99..b02332a5412 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -909,6 +909,7 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
if (error)
return error;
+ tty->driver_data = port;
return tty_port_open(&port->port, tty, filp);
}
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 986aa606a6b..8dfd24721a8 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -64,6 +64,7 @@
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/tty_flip.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -1989,7 +1990,7 @@ void mvme167_serial_console_setup(int cflag)
/*
* Attempt to set up all channels to something reasonable, and
* bang out a INIT_CHAN command. We should then be able to limit
- * the ammount of fiddling we have to do in normal running.
+ * the amount of fiddling we have to do in normal running.
*/
for (ch = 3; ch >= 0; ch--) {
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index 55a95892ccf..ee156948b9f 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/sn/sn_sal.h>
#include <asm/unaligned.h>
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index bba727c3807..73f66d03624 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -50,6 +50,7 @@
#include <linux/err.h>
#include <linux/kfifo.h>
#include <linux/platform_device.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 07ac14d949c..2c24fcdc722 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -94,6 +94,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/uaccess.h>
+#include <linux/gfp.h>
#include "specialix_io8.h"
#include "cd1865.h"
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 0e511d61f54..6049fd73192 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -724,7 +724,6 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
{
struct stlport *portp;
struct stlbrd *brdp;
- struct tty_port *port;
unsigned int minordev, brdnr, panelnr;
int portnr;
@@ -754,7 +753,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
portp = brdp->panels[panelnr]->ports[portnr];
if (portp == NULL)
return -ENODEV;
- port = &portp->port;
+
+ tty->driver_data = portp;
return tty_port_open(&portp->port, tty, filp);
}
@@ -841,7 +841,8 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
portp = tty->driver_data;
- BUG_ON(portp == NULL);
+ if(portp == NULL)
+ return;
tty_port_close(&portp->port, tty, filp);
}
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 1ae2de7d8b4..59de2525d30 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -38,6 +38,7 @@
#include <linux/workqueue.h>
#include <linux/hrtimer.h>
#include <linux/oom.h>
+#include <linux/slab.h>
#include <asm/ptrace.h>
#include <asm/irq_regs.h>
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index f06bb37defb..068c816e694 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -24,6 +24,7 @@
*/
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index bf2170fb1cd..0636520fa9b 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -22,6 +22,7 @@
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <acpi/acpi.h>
#include "tpm.h"
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 70efba2ee05..a605cb7dd89 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -20,6 +20,7 @@
*/
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "tpm.h"
/* National definitions */
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 2405f17b29d..94345994f8a 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pnp.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include "tpm.h"
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index ac16fbec72d..1b8ee590b4c 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -10,6 +10,7 @@
*/
#include <linux/audit.h>
+#include <linux/slab.h>
#include <linux/tty.h>
struct tty_audit_buf {
@@ -148,7 +149,6 @@ void tty_audit_fork(struct signal_struct *sig)
spin_lock_irq(&current->sighand->siglock);
sig->audit_tty = current->signal->audit_tty;
spin_unlock_irq(&current->sighand->siglock);
- sig->tty_audit_buf = NULL;
}
/**
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index af8d9771572..7ee52164d47 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -248,7 +248,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
{
int copied = 0;
do {
- int goal = min(size - copied, TTY_BUFFER_PAGE);
+ int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
int space = tty_buffer_request_room(tty, goal);
struct tty_buffer *tb = tty->buf.tail;
/* If there is no space then tb may be NULL */
@@ -285,7 +285,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
{
int copied = 0;
do {
- int goal = min(size - copied, TTY_BUFFER_PAGE);
+ int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
int space = tty_buffer_request_room(tty, goal);
struct tty_buffer *tb = tty->buf.tail;
/* If there is no space then tb may be NULL */
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index dcb9083ecde..6da962c9b21 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1423,6 +1423,8 @@ static void release_one_tty(struct work_struct *work)
list_del_init(&tty->tty_files);
file_list_unlock();
+ put_pid(tty->pgrp);
+ put_pid(tty->session);
free_tty_struct(tty);
}
@@ -2028,7 +2030,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
* @rows: rows (character)
* @cols: cols (character)
*
- * Update the termios variables and send the neccessary signals to
+ * Update the termios variables and send the necessary signals to
* peform a terminal resize correctly
*/
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index be492dd6643..a3bd1d0b66c 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set);
static void tty_port_shutdown(struct tty_port *port)
{
mutex_lock(&port->mutex);
- if (port->ops->shutdown &&
+ if (port->ops->shutdown && !port->console &&
test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
port->ops->shutdown(port);
mutex_unlock(&port->mutex);
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 042c8149a6d..1144a04cda6 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -47,6 +47,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 213373b5f17..196428c2287 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -25,6 +25,7 @@
#include <linux/list.h>
#include <linux/poll.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/virtio.h>
#include <linux/virtio_console.h>
@@ -32,6 +33,35 @@
#include <linux/workqueue.h>
#include "hvc_console.h"
+/* Moved here from .h file in order to disable MULTIPORT. */
+#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */
+
+struct virtio_console_multiport_conf {
+ struct virtio_console_config config;
+ /* max. number of ports this device can hold */
+ __u32 max_nr_ports;
+ /* number of ports added so far */
+ __u32 nr_ports;
+} __attribute__((packed));
+
+/*
+ * A message that's passed between the Host and the Guest for a
+ * particular port.
+ */
+struct virtio_console_control {
+ __u32 id; /* Port number */
+ __u16 event; /* The kind of control event (see below) */
+ __u16 value; /* Extra information for the key */
+};
+
+/* Some events for control messages */
+#define VIRTIO_CONSOLE_PORT_READY 0
+#define VIRTIO_CONSOLE_CONSOLE_PORT 1
+#define VIRTIO_CONSOLE_RESIZE 2
+#define VIRTIO_CONSOLE_PORT_OPEN 3
+#define VIRTIO_CONSOLE_PORT_NAME 4
+#define VIRTIO_CONSOLE_PORT_REMOVE 5
+
/*
* This is a global struct for storing common data for all the devices
* this driver handles.
@@ -120,7 +150,7 @@ struct ports_device {
spinlock_t cvq_lock;
/* The current config space is stored here */
- struct virtio_console_config config;
+ struct virtio_console_multiport_conf config;
/* The virtio device we're associated with */
struct virtio_device *vdev;
@@ -379,7 +409,7 @@ static ssize_t send_control_msg(struct port *port, unsigned int event,
struct scatterlist sg[1];
struct virtio_console_control cpkt;
struct virtqueue *vq;
- int len;
+ unsigned int len;
if (!use_multiport(port->portdev))
return 0;
@@ -415,20 +445,16 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count)
out_vq->vq_ops->kick(out_vq);
if (ret < 0) {
- len = 0;
+ in_count = 0;
goto fail;
}
- /*
- * Wait till the host acknowledges it pushed out the data we
- * sent. Also ensure we return to userspace the number of
- * bytes that were successfully consumed by the host.
- */
+ /* Wait till the host acknowledges it pushed out the data we sent. */
while (!out_vq->vq_ops->get_buf(out_vq, &len))
cpu_relax();
fail:
/* We're expected to return the amount of data we wrote */
- return len;
+ return in_count;
}
/*
@@ -645,13 +671,13 @@ static int put_chars(u32 vtermno, const char *buf, int count)
{
struct port *port;
+ if (unlikely(early_put_chars))
+ return early_put_chars(vtermno, buf, count);
+
port = find_port_by_vtermno(vtermno);
if (!port)
return 0;
- if (unlikely(early_put_chars))
- return early_put_chars(vtermno, buf, count);
-
return send_buf(port, (void *)buf, count);
}
@@ -681,6 +707,10 @@ static void resize_console(struct port *port)
struct virtio_device *vdev;
struct winsize ws;
+ /* The port could have been hot-unplugged */
+ if (!port)
+ return;
+
vdev = port->portdev->vdev;
if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) {
vdev->config->get(vdev,
@@ -947,11 +977,18 @@ static void handle_control_message(struct ports_device *portdev,
*/
err = sysfs_create_group(&port->dev->kobj,
&port_attribute_group);
- if (err)
+ if (err) {
dev_err(port->dev,
"Error %d creating sysfs device attributes\n",
err);
-
+ } else {
+ /*
+ * Generate a udev event so that appropriate
+ * symlinks can be created based on udev
+ * rules.
+ */
+ kobject_uevent(&port->dev->kobj, KOBJ_CHANGE);
+ }
break;
case VIRTIO_CONSOLE_PORT_REMOVE:
/*
@@ -1071,27 +1108,27 @@ static void config_intr(struct virtio_device *vdev)
static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
{
struct port_buffer *buf;
- unsigned int ret;
- int err;
+ unsigned int nr_added_bufs;
+ int ret;
- ret = 0;
+ nr_added_bufs = 0;
do {
buf = alloc_buf(PAGE_SIZE);
if (!buf)
break;
spin_lock_irq(lock);
- err = add_inbuf(vq, buf);
- if (err < 0) {
+ ret = add_inbuf(vq, buf);
+ if (ret < 0) {
spin_unlock_irq(lock);
free_buf(buf);
break;
}
- ret++;
+ nr_added_bufs++;
spin_unlock_irq(lock);
- } while (err > 0);
+ } while (ret > 0);
- return ret;
+ return nr_added_bufs;
}
static int add_port(struct ports_device *portdev, u32 id)
@@ -1100,6 +1137,7 @@ static int add_port(struct ports_device *portdev, u32 id)
struct port *port;
struct port_buffer *buf;
dev_t devt;
+ unsigned int nr_added_bufs;
int err;
port = kmalloc(sizeof(*port), GFP_KERNEL);
@@ -1144,8 +1182,8 @@ static int add_port(struct ports_device *portdev, u32 id)
init_waitqueue_head(&port->waitqueue);
/* Fill the in_vq with buffers so the host can send us data. */
- err = fill_queue(port->in_vq, &port->inbuf_lock);
- if (!err) {
+ nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
+ if (!nr_added_bufs) {
dev_err(port->dev, "Error allocating inbufs\n");
err = -ENOMEM;
goto free_device;
@@ -1205,7 +1243,7 @@ fail:
*/
static void config_work_handler(struct work_struct *work)
{
- struct virtio_console_config virtconconf;
+ struct virtio_console_multiport_conf virtconconf;
struct ports_device *portdev;
struct virtio_device *vdev;
int err;
@@ -1214,7 +1252,8 @@ static void config_work_handler(struct work_struct *work)
vdev = portdev->vdev;
vdev->config->get(vdev,
- offsetof(struct virtio_console_config, nr_ports),
+ offsetof(struct virtio_console_multiport_conf,
+ nr_ports),
&virtconconf.nr_ports,
sizeof(virtconconf.nr_ports));
@@ -1406,16 +1445,19 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
multiport = false;
portdev->config.nr_ports = 1;
portdev->config.max_nr_ports = 1;
+#if 0 /* Multiport is not quite ready yet --RR */
if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
multiport = true;
vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT;
- vdev->config->get(vdev, offsetof(struct virtio_console_config,
- nr_ports),
+ vdev->config->get(vdev,
+ offsetof(struct virtio_console_multiport_conf,
+ nr_ports),
&portdev->config.nr_ports,
sizeof(portdev->config.nr_ports));
- vdev->config->get(vdev, offsetof(struct virtio_console_config,
- max_nr_ports),
+ vdev->config->get(vdev,
+ offsetof(struct virtio_console_multiport_conf,
+ max_nr_ports),
&portdev->config.max_nr_ports,
sizeof(portdev->config.max_nr_ports));
if (portdev->config.nr_ports > portdev->config.max_nr_ports) {
@@ -1431,6 +1473,7 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
/* Let the Host know we support multiple ports.*/
vdev->config->finalize_features(vdev);
+#endif
err = init_vqs(portdev);
if (err < 0) {
@@ -1442,12 +1485,14 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
INIT_LIST_HEAD(&portdev->ports);
if (multiport) {
+ unsigned int nr_added_bufs;
+
spin_lock_init(&portdev->cvq_lock);
INIT_WORK(&portdev->control_work, &control_work_handler);
INIT_WORK(&portdev->config_work, &config_work_handler);
- err = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
- if (!err) {
+ nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
+ if (!nr_added_bufs) {
dev_err(&vdev->dev,
"Error allocating buffers for control queue\n");
err = -ENOMEM;
@@ -1511,7 +1556,6 @@ static struct virtio_device_id id_table[] = {
static unsigned int features[] = {
VIRTIO_CONSOLE_F_SIZE,
- VIRTIO_CONSOLE_F_MULTIPORT,
};
static struct virtio_driver virtio_console = {
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index 8b24729fec8..12de1202d22 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -27,7 +27,6 @@
#include <linux/fcntl.h>
#include <linux/major.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/console.h>
#include <linux/init.h>
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 50faa1fb0f0..bd1d1164fec 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -821,7 +821,7 @@ static inline int resize_screen(struct vc_data *vc, int width, int height,
*
* Resize a virtual console, clipping according to the actual constraints.
* If the caller passes a tty structure then update the termios winsize
- * information and perform any neccessary signal handling.
+ * information and perform any necessary signal handling.
*
* Caller must hold the console semaphore. Takes the termios mutex and
* ctrl_lock of the tty IFF a tty is passed.
@@ -2119,8 +2119,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
uint8_t inverse;
uint8_t width;
u16 himask, charmask;
- const unsigned char *orig_buf = NULL;
- int orig_count;
if (in_interrupt())
return count;
@@ -2142,8 +2140,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
release_console_sem();
return 0;
}
- orig_buf = buf;
- orig_count = count;
himask = vc->vc_hi_font_mask;
charmask = himask ? 0x1ff : 0xff;
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 87778dcf872..6aa10284104 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
ret = -EFAULT;
goto out;
}
- if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) {
+ if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
ret = -EINVAL;
goto out;
}
@@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc)
* telling it that it has acquired. Also check if it has died and
* clean up (similar to logic employed in change_console())
*/
- if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) {
+ if (vc->vt_mode.mode == VT_PROCESS) {
/*
* Send the signal as privileged - kill_pid() will
* tell us if the process has gone or something else
@@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc)
* vt to auto control.
*/
vc = vc_cons[fg_console].d;
- if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) {
+ if (vc->vt_mode.mode == VT_PROCESS) {
/*
* Send the signal as privileged - kill_pid() will
* tell us if the process has gone or something else
@@ -1693,28 +1693,27 @@ void change_console(struct vc_data *new_vc)
*/
vc->vt_newvt = new_vc->vc_num;
if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
- if(vc->vt_mode.mode == VT_PROCESS)
- /*
- * It worked. Mark the vt to switch to and
- * return. The process needs to send us a
- * VT_RELDISP ioctl to complete the switch.
- */
- return;
- } else {
/*
- * The controlling process has died, so we revert back to
- * normal operation. In this case, we'll also change back
- * to KD_TEXT mode. I'm not sure if this is strictly correct
- * but it saves the agony when the X server dies and the screen
- * remains blanked due to KD_GRAPHICS! It would be nice to do
- * this outside of VT_PROCESS but there is no single process
- * to account for and tracking tty count may be undesirable.
+ * It worked. Mark the vt to switch to and
+ * return. The process needs to send us a
+ * VT_RELDISP ioctl to complete the switch.
*/
- reset_vc(vc);
+ return;
}
/*
- * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch...
+ * The controlling process has died, so we revert back to
+ * normal operation. In this case, we'll also change back
+ * to KD_TEXT mode. I'm not sure if this is strictly correct
+ * but it saves the agony when the X server dies and the screen
+ * remains blanked due to KD_GRAPHICS! It would be nice to do
+ * this outside of VT_PROCESS but there is no single process
+ * to account for and tracking tty count may be undesirable.
+ */
+ reset_vc(vc);
+
+ /*
+ * Fall through to normal (VT_AUTO) handling of the switch...
*/
}
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 4846d50199f..7261b8d9087 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -86,6 +86,7 @@
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
deleted file mode 100644
index 08f726c5fee..00000000000
--- a/drivers/clocksource/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config CS5535_CLOCK_EVENT_SRC
- tristate "CS5535/CS5536 high-res timer (MFGPT) events"
- depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
- help
- This driver provides a clock event source based on the MFGPT
- timer(s) in the CS5535 and CS5536 companion chips.
- MFGPTs have a better resolution and max interval than the
- generic PIT, and are suitable for use as high-res timers.
-
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 578595c4425..744f748cc84 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -29,6 +29,7 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/sh_timer.h>
+#include <linux/slab.h>
struct sh_cmt_priv {
void __iomem *mapbase;
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index 4c8a759e60c..5fb78bfd73b 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -29,6 +29,7 @@
#include <linux/err.h>
#include <linux/clockchips.h>
#include <linux/sh_timer.h>
+#include <linux/slab.h>
struct sh_mtu2_priv {
void __iomem *mapbase;
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 961f5b5ef6a..fc9ff1e5b77 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -30,6 +30,7 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/sh_timer.h>
+#include <linux/slab.h>
struct sh_tmu_priv {
void __iomem *mapbase;
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 60697909ebd..a7f046b0096 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -27,6 +27,7 @@
#include <linux/ktime.h>
#include <linux/init.h>
#include <linux/connector.h>
+#include <linux/gfp.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 537c29ac448..1d48f40342c 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -26,6 +26,7 @@
#include <linux/netlink.h>
#include <linux/moduleparam.h>
#include <linux/connector.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 67bc2ece7b4..75d293eeb3e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -766,7 +766,7 @@ static void cpufreq_sysfs_release(struct kobject *kobj)
complete(&policy->kobj_unregister);
}
-static struct sysfs_ops sysfs_ops = {
+static const struct sysfs_ops sysfs_ops = {
.show = show,
.store = store,
};
@@ -1113,6 +1113,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
unsigned int cpu = sys_dev->id;
unsigned long flags;
struct cpufreq_policy *data;
+ struct kobject *kobj;
+ struct completion *cmp;
#ifdef CONFIG_SMP
struct sys_device *cpu_sys_dev;
unsigned int j;
@@ -1141,10 +1143,11 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
dprintk("removing link\n");
cpumask_clear_cpu(cpu, data->cpus);
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
- sysfs_remove_link(&sys_dev->kobj, "cpufreq");
+ kobj = &sys_dev->kobj;
cpufreq_cpu_put(data);
cpufreq_debug_enable_ratelimit();
unlock_policy_rwsem_write(cpu);
+ sysfs_remove_link(kobj, "cpufreq");
return 0;
}
#endif
@@ -1181,7 +1184,10 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
data->governor->name, CPUFREQ_NAME_LEN);
#endif
cpu_sys_dev = get_cpu_sysdev(j);
- sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
+ kobj = &cpu_sys_dev->kobj;
+ unlock_policy_rwsem_write(cpu);
+ sysfs_remove_link(kobj, "cpufreq");
+ lock_policy_rwsem_write(cpu);
cpufreq_cpu_put(data);
}
}
@@ -1192,19 +1198,22 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
if (cpufreq_driver->target)
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
- kobject_put(&data->kobj);
+ kobj = &data->kobj;
+ cmp = &data->kobj_unregister;
+ unlock_policy_rwsem_write(cpu);
+ kobject_put(kobj);
/* we need to make sure that the underlying kobj is actually
* not referenced anymore by anybody before we proceed with
* unloading.
*/
dprintk("waiting for dropping of refcount\n");
- wait_for_completion(&data->kobj_unregister);
+ wait_for_completion(cmp);
dprintk("wait complete\n");
+ lock_policy_rwsem_write(cpu);
if (cpufreq_driver->exit)
cpufreq_driver->exit(data);
-
unlock_policy_rwsem_write(cpu);
free_cpumask_var(data->related_cpus);
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 599a40b25cb..3a147874a46 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -444,6 +444,7 @@ static struct attribute_group dbs_attr_group_old = {
static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
{
unsigned int load = 0;
+ unsigned int max_load = 0;
unsigned int freq_target;
struct cpufreq_policy *policy;
@@ -501,6 +502,9 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
continue;
load = 100 * (wall_time - idle_time) / wall_time;
+
+ if (load > max_load)
+ max_load = load;
}
/*
@@ -511,7 +515,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
return;
/* Check for frequency increase */
- if (load > dbs_tuners_ins.up_threshold) {
+ if (max_load > dbs_tuners_ins.up_threshold) {
this_dbs_info->down_skip = 0;
/* if we are already at full speed then break out early */
@@ -538,7 +542,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
* can support the current CPU usage without triggering the up
* policy. To be safe, we focus 10 points under the threshold.
*/
- if (load < (dbs_tuners_ins.down_threshold - 10)) {
+ if (max_load < (dbs_tuners_ins.down_threshold - 10)) {
freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
this_dbs_info->requested_freq -= freq_target;
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 5a62d678dd1..00d73fc8e4e 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/sysdev.h>
#include <linux/cpu.h>
#include <linux/sysfs.h>
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 73655aeb3a6..1aea7157d8f 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -100,8 +100,8 @@ struct menu_device {
int needs_update;
unsigned int expected_us;
- u64 predicted_us;
unsigned int measured_us;
+ u64 predicted_us;
unsigned int exit_us;
unsigned int bucket;
u64 correction_factor[BUCKETS];
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
index 97b003839fb..0ba9c8b8ee7 100644
--- a/drivers/cpuidle/sysfs.c
+++ b/drivers/cpuidle/sysfs.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/cpuidle.h>
#include <linux/sysfs.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
#include "cpuidle.h"
@@ -22,6 +23,7 @@ static int __init cpuidle_sysfs_setup(char *unused)
__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
static ssize_t show_available_governors(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
char *buf)
{
ssize_t i = 0;
@@ -41,6 +43,7 @@ out:
}
static ssize_t show_current_driver(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
char *buf)
{
ssize_t ret;
@@ -56,6 +59,7 @@ static ssize_t show_current_driver(struct sysdev_class *class,
}
static ssize_t show_current_governor(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
char *buf)
{
ssize_t ret;
@@ -71,6 +75,7 @@ static ssize_t show_current_governor(struct sysdev_class *class,
}
static ssize_t store_current_governor(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
const char *buf, size_t count)
{
char gov_name[CPUIDLE_NAME_LEN];
@@ -191,7 +196,7 @@ static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr,
return ret;
}
-static struct sysfs_ops cpuidle_sysfs_ops = {
+static const struct sysfs_ops cpuidle_sysfs_ops = {
.show = cpuidle_show,
.store = cpuidle_store,
};
@@ -277,7 +282,7 @@ static ssize_t cpuidle_state_show(struct kobject * kobj,
return ret;
}
-static struct sysfs_ops cpuidle_state_sysfs_ops = {
+static const struct sysfs_ops cpuidle_state_sysfs_ops = {
.show = cpuidle_state_show,
};
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
index 1c3849f6b7a..6c4c8b7ce3a 100644
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -28,6 +28,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <asm/dcr.h>
#include <asm/dcr-regs.h>
#include <asm/cacheflush.h>
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 09ad9154d86..73e8b1713b5 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -321,7 +321,7 @@ static atomic_t hifn_dev_number;
#define HIFN_PUBOPLEN_MOD_M 0x0000007f /* modulus length mask */
#define HIFN_PUBOPLEN_MOD_S 0 /* modulus length shift */
#define HIFN_PUBOPLEN_EXP_M 0x0003ff80 /* exponent length mask */
-#define HIFN_PUBOPLEN_EXP_S 7 /* exponent lenght shift */
+#define HIFN_PUBOPLEN_EXP_S 7 /* exponent length shift */
#define HIFN_PUBOPLEN_RED_M 0x003c0000 /* reducend length mask */
#define HIFN_PUBOPLEN_RED_S 18 /* reducend length shift */
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 6c6656d3b1e..f17ddf37a1e 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -17,6 +17,7 @@
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/gfp.h>
#include <crypto/ctr.h>
#include <crypto/des.h>
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 1cee5a93709..18a436cafc1 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -14,6 +14,7 @@
#include <linux/kthread.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <crypto/internal/hash.h>
#include <crypto/sha.h>
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 8c2f3703ec8..2e992bc8015 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/percpu.h>
#include <linux/smp.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/processor.h>
#include <asm/i387.h>
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index fd529d68c5b..dc558a09731 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -37,6 +37,7 @@
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <crypto/algapi.h>
#include <crypto/aes.h>
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
index 52e6bb70a49..8661c84a105 100644
--- a/drivers/dca/dca-core.c
+++ b/drivers/dca/dca-core.c
@@ -27,6 +27,7 @@
#include <linux/notifier.h>
#include <linux/device.h>
#include <linux/dca.h>
+#include <linux/slab.h>
#define DCA_VERSION "1.12.1"
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
index ee916c9857e..5e8f335e6f6 100644
--- a/drivers/dca/dca-sysfs.c
+++ b/drivers/dca/dca-sysfs.c
@@ -26,6 +26,7 @@
#include <linux/kdev_t.h>
#include <linux/err.h>
#include <linux/dca.h>
+#include <linux/gfp.h>
static struct class *dca_class;
static struct idr dca_idr;
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index efc1a61ca23..278cf5bceef 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "at_hdmac_regs.h"
diff --git a/drivers/dma/coh901318_lli.c b/drivers/dma/coh901318_lli.c
index 71d58c1a1e8..9f7e0e6a7ee 100644
--- a/drivers/dma/coh901318_lli.c
+++ b/drivers/dma/coh901318_lli.c
@@ -11,6 +11,7 @@
#include <linux/spinlock.h>
#include <linux/dmapool.h>
#include <linux/memory.h>
+#include <linux/gfp.h>
#include <mach/coh901318.h>
#include "coh901318_lli.h"
diff --git a/drivers/dma/coh901318_lli.h b/drivers/dma/coh901318_lli.h
index 7bf713b79c6..7a5c80990e9 100644
--- a/drivers/dma/coh901318_lli.h
+++ b/drivers/dma/coh901318_lli.h
@@ -30,7 +30,7 @@ struct device;
* @pool: pool handle
* @dev: dma device
* @lli_nbr: number of lli:s in the pool
- * @algin: adress alignemtn of lli:s
+ * @algin: address alignemtn of lli:s
* returns 0 on success otherwise none zero
*/
int coh901318_pool_create(struct coh901318_pool *pool,
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 87399cafce3..d18b5d069d7 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -58,6 +58,7 @@
#include <linux/jiffies.h>
#include <linux/rculist.h>
#include <linux/idr.h>
+#include <linux/slab.h>
static DEFINE_MUTEX(dma_list_mutex);
static LIST_HEAD(dma_device_list);
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 6fa55fe3dd2..68d58c414cf 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/wait.h>
static unsigned int test_buf_size = 16384;
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index bbb4be5a3ff..88f470f0d82 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
#include <linux/delay.h>
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 5d0e42b263d..3e5a8005c62 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
@@ -71,7 +72,7 @@ static irqreturn_t ioat_dma_do_interrupt(int irq, void *data)
}
attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
- for_each_bit(bit, &attnstatus, BITS_PER_LONG) {
+ for_each_set_bit(bit, &attnstatus, BITS_PER_LONG) {
chan = ioat_chan_by_index(instance, bit);
tasklet_schedule(&chan->cleanup_task);
}
@@ -1138,7 +1139,7 @@ ioat_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
return entry->show(&chan->common, page);
}
-struct sysfs_ops ioat_sysfs_ops = {
+const struct sysfs_ops ioat_sysfs_ops = {
.show = ioat_attr_show,
};
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index 4f747a25407..86b97ac8774 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -346,7 +346,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
unsigned long *phys_complete);
void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type);
void ioat_kobject_del(struct ioatdma_device *device);
-extern struct sysfs_ops ioat_sysfs_ops;
+extern const struct sysfs_ops ioat_sysfs_ops;
extern struct ioat_sysfs_entry ioat_version_attr;
extern struct ioat_sysfs_entry ioat_cap_attr;
#endif /* IOATDMA_H */
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 1ed5d66d7dc..b5ae56c211e 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 26febc56dab..6740e319c9c 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -57,6 +57,7 @@
*/
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include "registers.h"
diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c
index d545fae30f3..99ec26725ba 100644
--- a/drivers/dma/ioat/pci.c
+++ b/drivers/dma/ioat/pci.c
@@ -30,6 +30,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/dca.h>
+#include <linux/slab.h>
#include "dma.h"
#include "dma_v2.h"
#include "registers.h"
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index ca6e6a0cb79..1ebc801678b 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -32,6 +32,7 @@
#include <linux/memory.h>
#include <linux/ioport.h>
#include <linux/raid/pq.h>
+#include <linux/slab.h>
#include <mach/adma.h>
diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c
index c0a272c7368..bb48a57c2fc 100644
--- a/drivers/dma/iovlock.c
+++ b/drivers/dma/iovlock.c
@@ -27,6 +27,7 @@
#include <linux/dmaengine.h>
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <net/tcp.h> /* for memcpy_toiovec */
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 3fdf1f46bd6..bbbd5856662 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -37,6 +37,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 466ab10c1ff..e2fd34da64f 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
index e69d87f24a2..d44626fa35a 100644
--- a/drivers/dma/ppc4xx/adma.c
+++ b/drivers/dma/ppc4xx/adma.c
@@ -38,6 +38,7 @@
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/of.h>
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index b75ce8b84c4..7cc31b3f40d 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -19,13 +19,16 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
-#include <cpu/dma.h>
-#include <asm/dma-sh.h>
+#include <linux/pm_runtime.h>
+
+#include <asm/dmaengine.h>
+
#include "shdma.h"
/* DMA descriptor control */
@@ -38,30 +41,32 @@ enum sh_dmae_desc_status {
};
#define NR_DESCS_PER_CHANNEL 32
-/*
- * Define the default configuration for dual address memory-memory transfer.
- * The 0x400 value represents auto-request, external->external.
- *
- * And this driver set 4byte burst mode.
- * If you want to change mode, you need to change RS_DEFAULT of value.
- * (ex 1byte burst mode -> (RS_DUAL & ~TS_32)
- */
-#define RS_DEFAULT (RS_DUAL)
+/* Default MEMCPY transfer size = 2^2 = 4 bytes */
+#define LOG2_DEFAULT_XFER_SIZE 2
/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)];
static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all);
-#define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id])
static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
{
- ctrl_outl(data, SH_DMAC_CHAN_BASE(sh_dc->id) + reg);
+ __raw_writel(data, sh_dc->base + reg / sizeof(u32));
}
static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg)
{
- return ctrl_inl(SH_DMAC_CHAN_BASE(sh_dc->id) + reg);
+ return __raw_readl(sh_dc->base + reg / sizeof(u32));
+}
+
+static u16 dmaor_read(struct sh_dmae_device *shdev)
+{
+ return __raw_readw(shdev->chan_reg + DMAOR / sizeof(u32));
+}
+
+static void dmaor_write(struct sh_dmae_device *shdev, u16 data)
+{
+ __raw_writew(data, shdev->chan_reg + DMAOR / sizeof(u32));
}
/*
@@ -69,24 +74,23 @@ static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg)
*
* SH7780 has two DMAOR register
*/
-static void sh_dmae_ctl_stop(int id)
+static void sh_dmae_ctl_stop(struct sh_dmae_device *shdev)
{
- unsigned short dmaor = dmaor_read_reg(id);
+ unsigned short dmaor = dmaor_read(shdev);
- dmaor &= ~(DMAOR_NMIF | DMAOR_AE);
- dmaor_write_reg(id, dmaor);
+ dmaor_write(shdev, dmaor & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME));
}
-static int sh_dmae_rst(int id)
+static int sh_dmae_rst(struct sh_dmae_device *shdev)
{
unsigned short dmaor;
- sh_dmae_ctl_stop(id);
- dmaor = dmaor_read_reg(id) | DMAOR_INIT;
+ sh_dmae_ctl_stop(shdev);
+ dmaor = dmaor_read(shdev) | shdev->pdata->dmaor_init;
- dmaor_write_reg(id, dmaor);
- if (dmaor_read_reg(id) & (DMAOR_AE | DMAOR_NMIF)) {
- pr_warning(KERN_ERR "dma-sh: Can't initialize DMAOR.\n");
+ dmaor_write(shdev, dmaor);
+ if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) {
+ pr_warning("dma-sh: Can't initialize DMAOR.\n");
return -EINVAL;
}
return 0;
@@ -102,13 +106,36 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
return false; /* waiting */
}
-static unsigned int ts_shift[] = TS_SHIFT;
-static inline unsigned int calc_xmit_shift(u32 chcr)
+static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr)
{
- int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |
- ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT);
+ struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
+ struct sh_dmae_device, common);
+ struct sh_dmae_pdata *pdata = shdev->pdata;
+ int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) |
+ ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift);
+
+ if (cnt >= pdata->ts_shift_num)
+ cnt = 0;
- return ts_shift[cnt];
+ return pdata->ts_shift[cnt];
+}
+
+static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size)
+{
+ struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
+ struct sh_dmae_device, common);
+ struct sh_dmae_pdata *pdata = shdev->pdata;
+ int i;
+
+ for (i = 0; i < pdata->ts_shift_num; i++)
+ if (pdata->ts_shift[i] == l2size)
+ break;
+
+ if (i == pdata->ts_shift_num)
+ i = 0;
+
+ return ((i << pdata->ts_low_shift) & pdata->ts_low_mask) |
+ ((i << pdata->ts_high_shift) & pdata->ts_high_mask);
}
static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
@@ -136,8 +163,13 @@ static void dmae_halt(struct sh_dmae_chan *sh_chan)
static void dmae_init(struct sh_dmae_chan *sh_chan)
{
- u32 chcr = RS_DEFAULT; /* default is DUAL mode */
- sh_chan->xmit_shift = calc_xmit_shift(chcr);
+ /*
+ * Default configuration for dual address memory-memory transfer.
+ * 0x400 represents auto-request.
+ */
+ u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan,
+ LOG2_DEFAULT_XFER_SIZE);
+ sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr);
sh_dmae_writel(sh_chan, chcr, CHCR);
}
@@ -147,37 +179,26 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
if (dmae_is_busy(sh_chan))
return -EBUSY;
- sh_chan->xmit_shift = calc_xmit_shift(val);
+ sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val);
sh_dmae_writel(sh_chan, val, CHCR);
return 0;
}
-#define DMARS_SHIFT 8
-#define DMARS_CHAN_MSK 0x01
static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
{
- u32 addr;
- int shift = 0;
+ struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
+ struct sh_dmae_device, common);
+ struct sh_dmae_pdata *pdata = shdev->pdata;
+ struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
+ u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
+ int shift = chan_pdata->dmars_bit;
if (dmae_is_busy(sh_chan))
return -EBUSY;
- if (sh_chan->id & DMARS_CHAN_MSK)
- shift = DMARS_SHIFT;
-
- if (sh_chan->id < 6)
- /* DMA0RS0 - DMA0RS2 */
- addr = SH_DMARS_BASE0 + (sh_chan->id / 2) * 4;
-#ifdef SH_DMARS_BASE1
- else if (sh_chan->id < 12)
- /* DMA1RS0 - DMA1RS2 */
- addr = SH_DMARS_BASE1 + ((sh_chan->id - 6) / 2) * 4;
-#endif
- else
- return -EINVAL;
-
- ctrl_outw((val << shift) | (ctrl_inw(addr) & (0xFF00 >> shift)), addr);
+ __raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift),
+ addr);
return 0;
}
@@ -251,15 +272,15 @@ static struct sh_dmae_slave_config *sh_dmae_find_slave(
struct dma_device *dma_dev = sh_chan->common.device;
struct sh_dmae_device *shdev = container_of(dma_dev,
struct sh_dmae_device, common);
- struct sh_dmae_pdata *pdata = &shdev->pdata;
+ struct sh_dmae_pdata *pdata = shdev->pdata;
int i;
if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER)
return NULL;
- for (i = 0; i < pdata->config_num; i++)
- if (pdata->config[i].slave_id == slave_id)
- return pdata->config + i;
+ for (i = 0; i < pdata->slave_num; i++)
+ if (pdata->slave[i].slave_id == slave_id)
+ return pdata->slave + i;
return NULL;
}
@@ -270,6 +291,8 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
struct sh_desc *desc;
struct sh_dmae_slave *param = chan->private;
+ pm_runtime_get_sync(sh_chan->dev);
+
/*
* This relies on the guarantee from dmaengine that alloc_chan_resources
* never runs concurrently with itself or free_chan_resources.
@@ -288,9 +311,8 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
dmae_set_dmars(sh_chan, cfg->mid_rid);
dmae_set_chcr(sh_chan, cfg->chcr);
- } else {
- if ((sh_dmae_readl(sh_chan, CHCR) & 0x700) != 0x400)
- dmae_set_chcr(sh_chan, RS_DEFAULT);
+ } else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) {
+ dmae_init(sh_chan);
}
spin_lock_bh(&sh_chan->desc_lock);
@@ -312,6 +334,9 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
}
spin_unlock_bh(&sh_chan->desc_lock);
+ if (!sh_chan->descs_allocated)
+ pm_runtime_put(sh_chan->dev);
+
return sh_chan->descs_allocated;
}
@@ -323,6 +348,7 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
struct sh_desc *desc, *_desc;
LIST_HEAD(list);
+ int descs = sh_chan->descs_allocated;
dmae_halt(sh_chan);
@@ -343,6 +369,9 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
spin_unlock_bh(&sh_chan->desc_lock);
+ if (descs > 0)
+ pm_runtime_put(sh_chan->dev);
+
list_for_each_entry_safe(desc, _desc, &list, node)
kfree(desc);
}
@@ -559,6 +588,19 @@ static void sh_dmae_terminate_all(struct dma_chan *chan)
if (!chan)
return;
+ dmae_halt(sh_chan);
+
+ spin_lock_bh(&sh_chan->desc_lock);
+ if (!list_empty(&sh_chan->ld_queue)) {
+ /* Record partial transfer */
+ struct sh_desc *desc = list_entry(sh_chan->ld_queue.next,
+ struct sh_desc, node);
+ desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
+ sh_chan->xmit_shift;
+
+ }
+ spin_unlock_bh(&sh_chan->desc_lock);
+
sh_dmae_chan_ld_cleanup(sh_chan, true);
}
@@ -661,7 +703,7 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
{
- struct sh_desc *sd;
+ struct sh_desc *desc;
spin_lock_bh(&sh_chan->desc_lock);
/* DMA work check */
@@ -671,10 +713,13 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
}
/* Find the first not transferred desciptor */
- list_for_each_entry(sd, &sh_chan->ld_queue, node)
- if (sd->mark == DESC_SUBMITTED) {
+ list_for_each_entry(desc, &sh_chan->ld_queue, node)
+ if (desc->mark == DESC_SUBMITTED) {
+ dev_dbg(sh_chan->dev, "Queue #%d to %d: %u@%x -> %x\n",
+ desc->async_tx.cookie, sh_chan->id,
+ desc->hw.tcr, desc->hw.sar, desc->hw.dar);
/* Get the ld start address from ld_queue */
- dmae_set_reg(sh_chan, &sd->hw);
+ dmae_set_reg(sh_chan, &desc->hw);
dmae_start(sh_chan);
break;
}
@@ -696,6 +741,7 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan,
struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
dma_cookie_t last_used;
dma_cookie_t last_complete;
+ enum dma_status status;
sh_dmae_chan_ld_cleanup(sh_chan, false);
@@ -709,7 +755,27 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan,
if (used)
*used = last_used;
- return dma_async_is_complete(cookie, last_complete, last_used);
+ spin_lock_bh(&sh_chan->desc_lock);
+
+ status = dma_async_is_complete(cookie, last_complete, last_used);
+
+ /*
+ * If we don't find cookie on the queue, it has been aborted and we have
+ * to report error
+ */
+ if (status != DMA_SUCCESS) {
+ struct sh_desc *desc;
+ status = DMA_ERROR;
+ list_for_each_entry(desc, &sh_chan->ld_queue, node)
+ if (desc->cookie == cookie) {
+ status = DMA_IN_PROGRESS;
+ break;
+ }
+ }
+
+ spin_unlock_bh(&sh_chan->desc_lock);
+
+ return status;
}
static irqreturn_t sh_dmae_interrupt(int irq, void *data)
@@ -732,40 +798,32 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data)
#if defined(CONFIG_CPU_SH4)
static irqreturn_t sh_dmae_err(int irq, void *data)
{
- int err = 0;
struct sh_dmae_device *shdev = (struct sh_dmae_device *)data;
+ int i;
- /* IRQ Multi */
- if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
- int __maybe_unused cnt = 0;
- switch (irq) {
-#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ)
- case DMTE6_IRQ:
- cnt++;
-#endif
- case DMTE0_IRQ:
- if (dmaor_read_reg(cnt) & (DMAOR_NMIF | DMAOR_AE)) {
- disable_irq(irq);
- return IRQ_HANDLED;
+ /* halt the dma controller */
+ sh_dmae_ctl_stop(shdev);
+
+ /* We cannot detect, which channel caused the error, have to reset all */
+ for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) {
+ struct sh_dmae_chan *sh_chan = shdev->chan[i];
+ if (sh_chan) {
+ struct sh_desc *desc;
+ /* Stop the channel */
+ dmae_halt(sh_chan);
+ /* Complete all */
+ list_for_each_entry(desc, &sh_chan->ld_queue, node) {
+ struct dma_async_tx_descriptor *tx = &desc->async_tx;
+ desc->mark = DESC_IDLE;
+ if (tx->callback)
+ tx->callback(tx->callback_param);
}
- default:
- return IRQ_NONE;
+ list_splice_init(&sh_chan->ld_queue, &sh_chan->ld_free);
}
- } else {
- /* reset dma controller */
- err = sh_dmae_rst(0);
- if (err)
- return err;
-#ifdef SH_DMAC_BASE1
- if (shdev->pdata.mode & SHDMA_DMAOR1) {
- err = sh_dmae_rst(1);
- if (err)
- return err;
- }
-#endif
- disable_irq(irq);
- return IRQ_HANDLED;
}
+ sh_dmae_rst(shdev);
+
+ return IRQ_HANDLED;
}
#endif
@@ -796,19 +854,12 @@ static void dmae_do_tasklet(unsigned long data)
sh_dmae_chan_ld_cleanup(sh_chan, false);
}
-static unsigned int get_dmae_irq(unsigned int id)
-{
- unsigned int irq = 0;
- if (id < ARRAY_SIZE(dmte_irq_map))
- irq = dmte_irq_map[id];
- return irq;
-}
-
-static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
+static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
+ int irq, unsigned long flags)
{
int err;
- unsigned int irq = get_dmae_irq(id);
- unsigned long irqflags = IRQF_DISABLED;
+ struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
+ struct platform_device *pdev = to_platform_device(shdev->common.dev);
struct sh_dmae_chan *new_sh_chan;
/* alloc channel */
@@ -819,8 +870,13 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
return -ENOMEM;
}
+ /* copy struct dma_device */
+ new_sh_chan->common.device = &shdev->common;
+
new_sh_chan->dev = shdev->common.dev;
new_sh_chan->id = id;
+ new_sh_chan->irq = irq;
+ new_sh_chan->base = shdev->chan_reg + chan_pdata->offset / sizeof(u32);
/* Init DMA tasklet */
tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet,
@@ -835,29 +891,20 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
INIT_LIST_HEAD(&new_sh_chan->ld_queue);
INIT_LIST_HEAD(&new_sh_chan->ld_free);
- /* copy struct dma_device */
- new_sh_chan->common.device = &shdev->common;
-
/* Add the channel to DMA device channel list */
list_add_tail(&new_sh_chan->common.device_node,
&shdev->common.channels);
shdev->common.chancnt++;
- if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
- irqflags = IRQF_SHARED;
-#if defined(DMTE6_IRQ)
- if (irq >= DMTE6_IRQ)
- irq = DMTE6_IRQ;
- else
-#endif
- irq = DMTE0_IRQ;
- }
-
- snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
- "sh-dmae%d", new_sh_chan->id);
+ if (pdev->id >= 0)
+ snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
+ "sh-dmae%d.%d", pdev->id, new_sh_chan->id);
+ else
+ snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
+ "sh-dma%d", new_sh_chan->id);
/* set up channel irq */
- err = request_irq(irq, &sh_dmae_interrupt, irqflags,
+ err = request_irq(irq, &sh_dmae_interrupt, flags,
new_sh_chan->dev_id, new_sh_chan);
if (err) {
dev_err(shdev->common.dev, "DMA channel %d request_irq error "
@@ -881,12 +928,12 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev)
for (i = shdev->common.chancnt - 1 ; i >= 0 ; i--) {
if (shdev->chan[i]) {
- struct sh_dmae_chan *shchan = shdev->chan[i];
- if (!(shdev->pdata.mode & SHDMA_MIX_IRQ))
- free_irq(dmte_irq_map[i], shchan);
+ struct sh_dmae_chan *sh_chan = shdev->chan[i];
- list_del(&shchan->common.device_node);
- kfree(shchan);
+ free_irq(sh_chan->irq, sh_chan);
+
+ list_del(&sh_chan->common.device_node);
+ kfree(sh_chan);
shdev->chan[i] = NULL;
}
}
@@ -895,47 +942,84 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev)
static int __init sh_dmae_probe(struct platform_device *pdev)
{
- int err = 0, cnt, ecnt;
- unsigned long irqflags = IRQF_DISABLED;
-#if defined(CONFIG_CPU_SH4)
- int eirq[] = { DMAE0_IRQ,
-#if defined(DMAE1_IRQ)
- DMAE1_IRQ
-#endif
- };
-#endif
+ struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
+ unsigned long irqflags = IRQF_DISABLED,
+ chan_flag[SH_DMAC_MAX_CHANNELS] = {};
+ int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
+ int err, i, irq_cnt = 0, irqres = 0;
struct sh_dmae_device *shdev;
+ struct resource *chan, *dmars, *errirq_res, *chanirq_res;
/* get platform data */
- if (!pdev->dev.platform_data)
+ if (!pdata || !pdata->channel_num)
return -ENODEV;
+ chan = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ /* DMARS area is optional, if absent, this controller cannot do slave DMA */
+ dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ /*
+ * IRQ resources:
+ * 1. there always must be at least one IRQ IO-resource. On SH4 it is
+ * the error IRQ, in which case it is the only IRQ in this resource:
+ * start == end. If it is the only IRQ resource, all channels also
+ * use the same IRQ.
+ * 2. DMA channel IRQ resources can be specified one per resource or in
+ * ranges (start != end)
+ * 3. iff all events (channels and, optionally, error) on this
+ * controller use the same IRQ, only one IRQ resource can be
+ * specified, otherwise there must be one IRQ per channel, even if
+ * some of them are equal
+ * 4. if all IRQs on this controller are equal or if some specific IRQs
+ * specify IORESOURCE_IRQ_SHAREABLE in their resources, they will be
+ * requested with the IRQF_SHARED flag
+ */
+ errirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!chan || !errirq_res)
+ return -ENODEV;
+
+ if (!request_mem_region(chan->start, resource_size(chan), pdev->name)) {
+ dev_err(&pdev->dev, "DMAC register region already claimed\n");
+ return -EBUSY;
+ }
+
+ if (dmars && !request_mem_region(dmars->start, resource_size(dmars), pdev->name)) {
+ dev_err(&pdev->dev, "DMAC DMARS region already claimed\n");
+ err = -EBUSY;
+ goto ermrdmars;
+ }
+
+ err = -ENOMEM;
shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL);
if (!shdev) {
- dev_err(&pdev->dev, "No enough memory\n");
- return -ENOMEM;
+ dev_err(&pdev->dev, "Not enough memory\n");
+ goto ealloc;
+ }
+
+ shdev->chan_reg = ioremap(chan->start, resource_size(chan));
+ if (!shdev->chan_reg)
+ goto emapchan;
+ if (dmars) {
+ shdev->dmars = ioremap(dmars->start, resource_size(dmars));
+ if (!shdev->dmars)
+ goto emapdmars;
}
/* platform data */
- memcpy(&shdev->pdata, pdev->dev.platform_data,
- sizeof(struct sh_dmae_pdata));
+ shdev->pdata = pdata;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
/* reset dma controller */
- err = sh_dmae_rst(0);
+ err = sh_dmae_rst(shdev);
if (err)
goto rst_err;
- /* SH7780/85/23 has DMAOR1 */
- if (shdev->pdata.mode & SHDMA_DMAOR1) {
- err = sh_dmae_rst(1);
- if (err)
- goto rst_err;
- }
-
INIT_LIST_HEAD(&shdev->common.channels);
dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
- dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
+ if (dmars)
+ dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
shdev->common.device_alloc_chan_resources
= sh_dmae_alloc_chan_resources;
@@ -950,37 +1034,72 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
shdev->common.dev = &pdev->dev;
/* Default transfer size of 32 bytes requires 32-byte alignment */
- shdev->common.copy_align = 5;
+ shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE;
#if defined(CONFIG_CPU_SH4)
- /* Non Mix IRQ mode SH7722/SH7730 etc... */
- if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
+ chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+
+ if (!chanirq_res)
+ chanirq_res = errirq_res;
+ else
+ irqres++;
+
+ if (chanirq_res == errirq_res ||
+ (errirq_res->flags & IORESOURCE_BITS) == IORESOURCE_IRQ_SHAREABLE)
irqflags = IRQF_SHARED;
- eirq[0] = DMTE0_IRQ;
-#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ)
- eirq[1] = DMTE6_IRQ;
-#endif
+
+ errirq = errirq_res->start;
+
+ err = request_irq(errirq, sh_dmae_err, irqflags,
+ "DMAC Address Error", shdev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "DMA failed requesting irq #%d, error %d\n",
+ errirq, err);
+ goto eirq_err;
}
- for (ecnt = 0 ; ecnt < ARRAY_SIZE(eirq); ecnt++) {
- err = request_irq(eirq[ecnt], sh_dmae_err, irqflags,
- "DMAC Address Error", shdev);
- if (err) {
- dev_err(&pdev->dev, "DMA device request_irq"
- "error (irq %d) with return %d\n",
- eirq[ecnt], err);
- goto eirq_err;
+#else
+ chanirq_res = errirq_res;
+#endif /* CONFIG_CPU_SH4 */
+
+ if (chanirq_res->start == chanirq_res->end &&
+ !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
+ /* Special case - all multiplexed */
+ for (; irq_cnt < pdata->channel_num; irq_cnt++) {
+ chan_irq[irq_cnt] = chanirq_res->start;
+ chan_flag[irq_cnt] = IRQF_SHARED;
}
+ } else {
+ do {
+ for (i = chanirq_res->start; i <= chanirq_res->end; i++) {
+ if ((errirq_res->flags & IORESOURCE_BITS) ==
+ IORESOURCE_IRQ_SHAREABLE)
+ chan_flag[irq_cnt] = IRQF_SHARED;
+ else
+ chan_flag[irq_cnt] = IRQF_DISABLED;
+ dev_dbg(&pdev->dev,
+ "Found IRQ %d for channel %d\n",
+ i, irq_cnt);
+ chan_irq[irq_cnt++] = i;
+ }
+ chanirq_res = platform_get_resource(pdev,
+ IORESOURCE_IRQ, ++irqres);
+ } while (irq_cnt < pdata->channel_num && chanirq_res);
}
-#endif /* CONFIG_CPU_SH4 */
+
+ if (irq_cnt < pdata->channel_num)
+ goto eirqres;
/* Create DMA Channel */
- for (cnt = 0 ; cnt < MAX_DMA_CHANNELS ; cnt++) {
- err = sh_dmae_chan_probe(shdev, cnt);
+ for (i = 0; i < pdata->channel_num; i++) {
+ err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
if (err)
goto chan_probe_err;
}
+ pm_runtime_put(&pdev->dev);
+
platform_set_drvdata(pdev, shdev);
dma_async_device_register(&shdev->common);
@@ -988,13 +1107,24 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
chan_probe_err:
sh_dmae_chan_remove(shdev);
-
+eirqres:
+#if defined(CONFIG_CPU_SH4)
+ free_irq(errirq, shdev);
eirq_err:
- for (ecnt-- ; ecnt >= 0; ecnt--)
- free_irq(eirq[ecnt], shdev);
-
+#endif
rst_err:
+ pm_runtime_put(&pdev->dev);
+ if (dmars)
+ iounmap(shdev->dmars);
+emapdmars:
+ iounmap(shdev->chan_reg);
+emapchan:
kfree(shdev);
+ealloc:
+ if (dmars)
+ release_mem_region(dmars->start, resource_size(dmars));
+ermrdmars:
+ release_mem_region(chan->start, resource_size(chan));
return err;
}
@@ -1002,36 +1132,39 @@ rst_err:
static int __exit sh_dmae_remove(struct platform_device *pdev)
{
struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
+ struct resource *res;
+ int errirq = platform_get_irq(pdev, 0);
dma_async_device_unregister(&shdev->common);
- if (shdev->pdata.mode & SHDMA_MIX_IRQ) {
- free_irq(DMTE0_IRQ, shdev);
-#if defined(DMTE6_IRQ)
- free_irq(DMTE6_IRQ, shdev);
-#endif
- }
+ if (errirq > 0)
+ free_irq(errirq, shdev);
/* channel data remove */
sh_dmae_chan_remove(shdev);
- if (!(shdev->pdata.mode & SHDMA_MIX_IRQ)) {
- free_irq(DMAE0_IRQ, shdev);
-#if defined(DMAE1_IRQ)
- free_irq(DMAE1_IRQ, shdev);
-#endif
- }
+ pm_runtime_disable(&pdev->dev);
+
+ if (shdev->dmars)
+ iounmap(shdev->dmars);
+ iounmap(shdev->chan_reg);
+
kfree(shdev);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ release_mem_region(res->start, resource_size(res));
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res)
+ release_mem_region(res->start, resource_size(res));
+
return 0;
}
static void sh_dmae_shutdown(struct platform_device *pdev)
{
struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
- sh_dmae_ctl_stop(0);
- if (shdev->pdata.mode & SHDMA_DMAOR1)
- sh_dmae_ctl_stop(1);
+ sh_dmae_ctl_stop(shdev);
}
static struct platform_driver sh_dmae_driver = {
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 7e227f3c87c..153609a1e96 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -17,23 +17,9 @@
#include <linux/interrupt.h>
#include <linux/list.h>
-#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */
-
-struct sh_dmae_regs {
- u32 sar; /* SAR / source address */
- u32 dar; /* DAR / destination address */
- u32 tcr; /* TCR / transfer count */
-};
+#include <asm/dmaengine.h>
-struct sh_desc {
- struct sh_dmae_regs hw;
- struct list_head node;
- struct dma_async_tx_descriptor async_tx;
- enum dma_data_direction direction;
- dma_cookie_t cookie;
- int chunks;
- int mark;
-};
+#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */
struct device;
@@ -47,14 +33,18 @@ struct sh_dmae_chan {
struct tasklet_struct tasklet; /* Tasklet */
int descs_allocated; /* desc count */
int xmit_shift; /* log_2(bytes_per_xfer) */
+ int irq;
int id; /* Raw id of this channel */
+ u32 __iomem *base;
char dev_id[16]; /* unique name per DMAC of channel */
};
struct sh_dmae_device {
struct dma_device common;
- struct sh_dmae_chan *chan[MAX_DMA_CHANNELS];
- struct sh_dmae_pdata pdata;
+ struct sh_dmae_chan *chan[SH_DMAC_MAX_CHANNELS];
+ struct sh_dmae_pdata *pdata;
+ u32 __iomem *chan_reg;
+ u16 __iomem *dmars;
};
#define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common)
diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c
index 2b95f1a3edf..f2330f81cb5 100644
--- a/drivers/edac/amd76x_edac.c
+++ b/drivers/edac/amd76x_edac.c
@@ -16,7 +16,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c
index 3d50274f134..1609a19df49 100644
--- a/drivers/edac/cpc925_edac.c
+++ b/drivers/edac/cpc925_edac.c
@@ -25,6 +25,7 @@
#include <linux/edac.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/gfp.h>
#include "edac_core.h"
#include "edac_module.h"
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c
index d205d493a68..ae3f80c5419 100644
--- a/drivers/edac/e752x_edac.c
+++ b/drivers/edac/e752x_edac.c
@@ -21,7 +21,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
@@ -75,6 +74,14 @@ static struct edac_pci_ctl_info *e752x_pci;
#define E752X_NR_CSROWS 8 /* number of csrows */
/* E752X register addresses - device 0 function 0 */
+#define E752X_MCHSCRB 0x52 /* Memory Scrub register (16b) */
+ /*
+ * 6:5 Scrub Completion Count
+ * 3:2 Scrub Rate (i3100 only)
+ * 01=fast 10=normal
+ * 1:0 Scrub Mode enable
+ * 00=off 10=on
+ */
#define E752X_DRB 0x60 /* DRAM row boundary register (8b) */
#define E752X_DRA 0x70 /* DRAM row attribute register (8b) */
/*
@@ -240,6 +247,41 @@ static const struct e752x_dev_info e752x_devs[] = {
.ctl_name = "3100"},
};
+/* Valid scrub rates for the e752x/3100 hardware memory scrubber. We
+ * map the scrubbing bandwidth to a hardware register value. The 'set'
+ * operation finds the 'matching or higher value'. Note that scrubbing
+ * on the e752x can only be enabled/disabled. The 3100 supports
+ * a normal and fast mode.
+ */
+
+#define SDRATE_EOT 0xFFFFFFFF
+
+struct scrubrate {
+ u32 bandwidth; /* bandwidth consumed by scrubbing in bytes/sec */
+ u16 scrubval; /* register value for scrub rate */
+};
+
+/* Rate below assumes same performance as i3100 using PC3200 DDR2 in
+ * normal mode. e752x bridges don't support choosing normal or fast mode,
+ * so the scrubbing bandwidth value isn't all that important - scrubbing is
+ * either on or off.
+ */
+static const struct scrubrate scrubrates_e752x[] = {
+ {0, 0x00}, /* Scrubbing Off */
+ {500000, 0x02}, /* Scrubbing On */
+ {SDRATE_EOT, 0x00} /* End of Table */
+};
+
+/* Fast mode: 2 GByte PC3200 DDR2 scrubbed in 33s = 63161283 bytes/s
+ * Normal mode: 125 (32000 / 256) times slower than fast mode.
+ */
+static const struct scrubrate scrubrates_i3100[] = {
+ {0, 0x00}, /* Scrubbing Off */
+ {500000, 0x0a}, /* Normal mode - 32k clocks */
+ {62500000, 0x06}, /* Fast mode - 256 clocks */
+ {SDRATE_EOT, 0x00} /* End of Table */
+};
+
static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci,
unsigned long page)
{
@@ -915,6 +957,68 @@ static void e752x_check(struct mem_ctl_info *mci)
e752x_process_error_info(mci, &info, 1);
}
+/* Program byte/sec bandwidth scrub rate to hardware */
+static int set_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *new_bw)
+{
+ const struct scrubrate *scrubrates;
+ struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
+ struct pci_dev *pdev = pvt->dev_d0f0;
+ int i;
+
+ if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0)
+ scrubrates = scrubrates_i3100;
+ else
+ scrubrates = scrubrates_e752x;
+
+ /* Translate the desired scrub rate to a e752x/3100 register value.
+ * Search for the bandwidth that is equal or greater than the
+ * desired rate and program the cooresponding register value.
+ */
+ for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++)
+ if (scrubrates[i].bandwidth >= *new_bw)
+ break;
+
+ if (scrubrates[i].bandwidth == SDRATE_EOT)
+ return -1;
+
+ pci_write_config_word(pdev, E752X_MCHSCRB, scrubrates[i].scrubval);
+
+ return 0;
+}
+
+/* Convert current scrub rate value into byte/sec bandwidth */
+static int get_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
+{
+ const struct scrubrate *scrubrates;
+ struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
+ struct pci_dev *pdev = pvt->dev_d0f0;
+ u16 scrubval;
+ int i;
+
+ if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0)
+ scrubrates = scrubrates_i3100;
+ else
+ scrubrates = scrubrates_e752x;
+
+ /* Find the bandwidth matching the memory scrubber configuration */
+ pci_read_config_word(pdev, E752X_MCHSCRB, &scrubval);
+ scrubval = scrubval & 0x0f;
+
+ for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++)
+ if (scrubrates[i].scrubval == scrubval)
+ break;
+
+ if (scrubrates[i].bandwidth == SDRATE_EOT) {
+ e752x_printk(KERN_WARNING,
+ "Invalid sdram scrub control value: 0x%x\n", scrubval);
+ return -1;
+ }
+
+ *bw = scrubrates[i].bandwidth;
+
+ return 0;
+}
+
/* Return 1 if dual channel mode is active. Else return 0. */
static inline int dual_channel_active(u16 ddrcsr)
{
@@ -1073,10 +1177,7 @@ fail:
/* Setup system bus parity mask register.
* Sysbus parity supported on:
- * e7320/e7520/e7525 + Xeon
- * i3100 + Xeon/Celeron
- * Sysbus parity not supported on:
- * i3100 + Pentium M/Celeron M/Core Duo/Core2 Duo
+ * e7320/e7520/e7525 + Xeon
*/
static void e752x_init_sysbus_parity_mask(struct e752x_pvt *pvt)
{
@@ -1087,10 +1188,7 @@ static void e752x_init_sysbus_parity_mask(struct e752x_pvt *pvt)
/* Allow module parameter override, else see if CPU supports parity */
if (sysbus_parity != -1) {
enable = sysbus_parity;
- } else if (cpu_id[0] &&
- ((strstr(cpu_id, "Pentium") && strstr(cpu_id, " M ")) ||
- (strstr(cpu_id, "Celeron") && strstr(cpu_id, " M ")) ||
- (strstr(cpu_id, "Core") && strstr(cpu_id, "Duo")))) {
+ } else if (cpu_id[0] && !strstr(cpu_id, "Xeon")) {
e752x_printk(KERN_INFO, "System Bus Parity not "
"supported by CPU, disabling\n");
enable = 0;
@@ -1187,6 +1285,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
mci->dev_name = pci_name(pdev);
mci->edac_check = e752x_check;
mci->ctl_page_to_phys = ctl_page_to_phys;
+ mci->set_sdram_scrub_rate = set_sdram_scrub_rate;
+ mci->get_sdram_scrub_rate = get_sdram_scrub_rate;
/* set the map type. 1 = normal, 0 = reversed
* Must be set before e752x_init_csrows in case csrow mapping
diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c
index c7d11cc4e21..1731d724581 100644
--- a/drivers/edac/e7xxx_edac.c
+++ b/drivers/edac/e7xxx_edac.c
@@ -26,7 +26,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
index 53764577035..070968178a2 100644
--- a/drivers/edac/edac_device_sysfs.c
+++ b/drivers/edac/edac_device_sysfs.c
@@ -12,6 +12,7 @@
#include <linux/ctype.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "edac_core.h"
#include "edac_module.h"
@@ -137,7 +138,7 @@ static ssize_t edac_dev_ctl_info_store(struct kobject *kobj,
}
/* edac_dev file operations for an 'ctl_info' */
-static struct sysfs_ops device_ctl_info_ops = {
+static const struct sysfs_ops device_ctl_info_ops = {
.show = edac_dev_ctl_info_show,
.store = edac_dev_ctl_info_store
};
@@ -373,7 +374,7 @@ static ssize_t edac_dev_instance_store(struct kobject *kobj,
}
/* edac_dev file operations for an 'instance' */
-static struct sysfs_ops device_instance_ops = {
+static const struct sysfs_ops device_instance_ops = {
.show = edac_dev_instance_show,
.store = edac_dev_instance_store
};
@@ -476,7 +477,7 @@ static ssize_t edac_dev_block_store(struct kobject *kobj,
}
/* edac_dev file operations for a 'block' */
-static struct sysfs_ops device_block_ops = {
+static const struct sysfs_ops device_block_ops = {
.show = edac_dev_block_show,
.store = edac_dev_block_store
};
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index e1d4ce08348..418b65f1a1d 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -10,6 +10,7 @@
*/
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <linux/bug.h>
#include "edac_core.h"
@@ -245,7 +246,7 @@ static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr,
return -EIO;
}
-static struct sysfs_ops csrowfs_ops = {
+static const struct sysfs_ops csrowfs_ops = {
.show = csrowdev_show,
.store = csrowdev_store
};
@@ -575,7 +576,7 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
}
/* Intermediate show/store table */
-static struct sysfs_ops mci_ops = {
+static const struct sysfs_ops mci_ops = {
.show = mcidev_show,
.store = mcidev_store
};
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 8fc91a01962..97e64bcdbc0 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -294,7 +294,6 @@ wrong_ls_mce:
void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
{
u32 ec = ERROR_CODE(regs->nbsl);
- u32 xec = EXT_ERROR_CODE(regs->nbsl);
if (!handle_errors)
return;
@@ -316,10 +315,15 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
} else {
- pr_cont(", core: %d\n", fls((regs->nbsh & 0xf) - 1));
+ u8 assoc_cpus = regs->nbsh & 0xf;
+
+ if (assoc_cpus > 0)
+ pr_cont(", core: %d", fls(assoc_cpus) - 1);
+
+ pr_cont("\n");
}
- pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+ pr_emerg("%s.\n", EXT_ERR_MSG(regs->nbsl));
if (BUS_ERROR(ec) && nb_bus_decoder)
nb_bus_decoder(node_id, regs);
@@ -369,7 +373,7 @@ static int amd_decode_mce(struct notifier_block *nb, unsigned long val,
((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
/* do the two bits[14:13] together */
- ecc = m->status & (3ULL << 45);
+ ecc = (m->status >> 45) & 0x3;
if (ecc)
pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c
index fb60a877d76..c39697df9cb 100644
--- a/drivers/edac/edac_pci_sysfs.c
+++ b/drivers/edac/edac_pci_sysfs.c
@@ -8,6 +8,7 @@
*/
#include <linux/module.h>
#include <linux/sysdev.h>
+#include <linux/slab.h>
#include <linux/ctype.h>
#include "edac_core.h"
@@ -121,7 +122,7 @@ static ssize_t edac_pci_instance_store(struct kobject *kobj,
}
/* fs_ops table */
-static struct sysfs_ops pci_instance_ops = {
+static const struct sysfs_ops pci_instance_ops = {
.show = edac_pci_instance_show,
.store = edac_pci_instance_store
};
@@ -261,7 +262,7 @@ static ssize_t edac_pci_dev_store(struct kobject *kobj,
return -EIO;
}
-static struct sysfs_ops edac_pci_sysfs_ops = {
+static const struct sysfs_ops edac_pci_sysfs_ops = {
.show = edac_pci_dev_show,
.store = edac_pci_dev_store
};
diff --git a/drivers/edac/i3000_edac.c b/drivers/edac/i3000_edac.c
index 6c9a0f2a593..c0510b3d703 100644
--- a/drivers/edac/i3000_edac.c
+++ b/drivers/edac/i3000_edac.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c
index fde4db91c4d..d41f9002da4 100644
--- a/drivers/edac/i3200_edac.c
+++ b/drivers/edac/i3200_edac.c
@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include <linux/io.h>
#include "edac_core.h"
diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c
index 7785d8ffa40..ee9753cf362 100644
--- a/drivers/edac/i5100_edac.c
+++ b/drivers/edac/i5100_edac.c
@@ -19,7 +19,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include <linux/delay.h>
#include <linux/mmzone.h>
diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c
index 577760a82a0..7f3884fcbd4 100644
--- a/drivers/edac/i82443bxgx_edac.c
+++ b/drivers/edac/i82443bxgx_edac.c
@@ -27,7 +27,6 @@
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c
index c0088ba9672..b8a95cf5071 100644
--- a/drivers/edac/i82860_edac.c
+++ b/drivers/edac/i82860_edac.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c
index b2d83b95033..b2fd1e89914 100644
--- a/drivers/edac/i82875p_edac.c
+++ b/drivers/edac/i82875p_edac.c
@@ -17,7 +17,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c
index 2eed3ea2cf6..3218819b728 100644
--- a/drivers/edac/i82975x_edac.c
+++ b/drivers/edac/i82975x_edac.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index ecd5928d711..4471647b480 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -11,13 +11,13 @@
*/
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/ctype.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/edac.h>
#include <linux/smp.h>
+#include <linux/gfp.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
@@ -239,16 +239,15 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
/* we only need the error registers */
r.start += 0xe00;
- if (!devm_request_mem_region(&op->dev, r.start,
- r.end - r.start + 1, pdata->name)) {
+ if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
+ pdata->name)) {
printk(KERN_ERR "%s: Error while requesting mem region\n",
__func__);
res = -EBUSY;
goto err;
}
- pdata->pci_vbase = devm_ioremap(&op->dev, r.start,
- r.end - r.start + 1);
+ pdata->pci_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
if (!pdata->pci_vbase) {
printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
res = -ENOMEM;
@@ -668,15 +667,125 @@ static struct of_platform_driver mpc85xx_l2_err_driver = {
/**************************** MC Err device ***************************/
+/*
+ * Taken from table 8-55 in the MPC8641 User's Manual and/or 9-61 in the
+ * MPC8572 User's Manual. Each line represents a syndrome bit column as a
+ * 64-bit value, but split into an upper and lower 32-bit chunk. The labels
+ * below correspond to Freescale's manuals.
+ */
+static unsigned int ecc_table[16] = {
+ /* MSB LSB */
+ /* [0:31] [32:63] */
+ 0xf00fe11e, 0xc33c0ff7, /* Syndrome bit 7 */
+ 0x00ff00ff, 0x00fff0ff,
+ 0x0f0f0f0f, 0x0f0fff00,
+ 0x11113333, 0x7777000f,
+ 0x22224444, 0x8888222f,
+ 0x44448888, 0xffff4441,
+ 0x8888ffff, 0x11118882,
+ 0xffff1111, 0x22221114, /* Syndrome bit 0 */
+};
+
+/*
+ * Calculate the correct ECC value for a 64-bit value specified by high:low
+ */
+static u8 calculate_ecc(u32 high, u32 low)
+{
+ u32 mask_low;
+ u32 mask_high;
+ int bit_cnt;
+ u8 ecc = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < 8; i++) {
+ mask_high = ecc_table[i * 2];
+ mask_low = ecc_table[i * 2 + 1];
+ bit_cnt = 0;
+
+ for (j = 0; j < 32; j++) {
+ if ((mask_high >> j) & 1)
+ bit_cnt ^= (high >> j) & 1;
+ if ((mask_low >> j) & 1)
+ bit_cnt ^= (low >> j) & 1;
+ }
+
+ ecc |= bit_cnt << i;
+ }
+
+ return ecc;
+}
+
+/*
+ * Create the syndrome code which is generated if the data line specified by
+ * 'bit' failed. Eg generate an 8-bit codes seen in Table 8-55 in the MPC8641
+ * User's Manual and 9-61 in the MPC8572 User's Manual.
+ */
+static u8 syndrome_from_bit(unsigned int bit) {
+ int i;
+ u8 syndrome = 0;
+
+ /*
+ * Cycle through the upper or lower 32-bit portion of each value in
+ * ecc_table depending on if 'bit' is in the upper or lower half of
+ * 64-bit data.
+ */
+ for (i = bit < 32; i < 16; i += 2)
+ syndrome |= ((ecc_table[i] >> (bit % 32)) & 1) << (i / 2);
+
+ return syndrome;
+}
+
+/*
+ * Decode data and ecc syndrome to determine what went wrong
+ * Note: This can only decode single-bit errors
+ */
+static void sbe_ecc_decode(u32 cap_high, u32 cap_low, u32 cap_ecc,
+ int *bad_data_bit, int *bad_ecc_bit)
+{
+ int i;
+ u8 syndrome;
+
+ *bad_data_bit = -1;
+ *bad_ecc_bit = -1;
+
+ /*
+ * Calculate the ECC of the captured data and XOR it with the captured
+ * ECC to find an ECC syndrome value we can search for
+ */
+ syndrome = calculate_ecc(cap_high, cap_low) ^ cap_ecc;
+
+ /* Check if a data line is stuck... */
+ for (i = 0; i < 64; i++) {
+ if (syndrome == syndrome_from_bit(i)) {
+ *bad_data_bit = i;
+ return;
+ }
+ }
+
+ /* If data is correct, check ECC bits for errors... */
+ for (i = 0; i < 8; i++) {
+ if ((syndrome >> i) & 0x1) {
+ *bad_ecc_bit = i;
+ return;
+ }
+ }
+}
+
static void mpc85xx_mc_check(struct mem_ctl_info *mci)
{
struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
struct csrow_info *csrow;
+ u32 bus_width;
u32 err_detect;
u32 syndrome;
u32 err_addr;
u32 pfn;
int row_index;
+ u32 cap_high;
+ u32 cap_low;
+ int bad_data_bit;
+ int bad_ecc_bit;
err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT);
if (!err_detect)
@@ -692,6 +801,15 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
}
syndrome = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ECC);
+
+ /* Mask off appropriate bits of syndrome based on bus width */
+ bus_width = (in_be32(pdata->mc_vbase + MPC85XX_MC_DDR_SDRAM_CFG) &
+ DSC_DBW_MASK) ? 32 : 64;
+ if (bus_width == 64)
+ syndrome &= 0xff;
+ else
+ syndrome &= 0xffff;
+
err_addr = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ADDRESS);
pfn = err_addr >> PAGE_SHIFT;
@@ -701,14 +819,35 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
break;
}
- mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data High: %#8.8x\n",
- in_be32(pdata->mc_vbase +
- MPC85XX_MC_CAPTURE_DATA_HI));
- mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data Low: %#8.8x\n",
- in_be32(pdata->mc_vbase +
- MPC85XX_MC_CAPTURE_DATA_LO));
- mpc85xx_mc_printk(mci, KERN_ERR, "syndrome: %#8.8x\n", syndrome);
- mpc85xx_mc_printk(mci, KERN_ERR, "err addr: %#8.8x\n", err_addr);
+ cap_high = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_HI);
+ cap_low = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_LO);
+
+ /*
+ * Analyze single-bit errors on 64-bit wide buses
+ * TODO: Add support for 32-bit wide buses
+ */
+ if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) {
+ sbe_ecc_decode(cap_high, cap_low, syndrome,
+ &bad_data_bit, &bad_ecc_bit);
+
+ if (bad_data_bit != -1)
+ mpc85xx_mc_printk(mci, KERN_ERR,
+ "Faulty Data bit: %d\n", bad_data_bit);
+ if (bad_ecc_bit != -1)
+ mpc85xx_mc_printk(mci, KERN_ERR,
+ "Faulty ECC bit: %d\n", bad_ecc_bit);
+
+ mpc85xx_mc_printk(mci, KERN_ERR,
+ "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
+ cap_high ^ (1 << (bad_data_bit - 32)),
+ cap_low ^ (1 << bad_data_bit),
+ syndrome ^ (1 << bad_ecc_bit));
+ }
+
+ mpc85xx_mc_printk(mci, KERN_ERR,
+ "Captured Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
+ cap_high, cap_low, syndrome);
+ mpc85xx_mc_printk(mci, KERN_ERR, "Err addr: %#8.8x\n", err_addr);
mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn);
/* we are out of range */
diff --git a/drivers/edac/mpc85xx_edac.h b/drivers/edac/mpc85xx_edac.h
index 52432ee7c4b..cb24df83946 100644
--- a/drivers/edac/mpc85xx_edac.h
+++ b/drivers/edac/mpc85xx_edac.h
@@ -48,6 +48,9 @@
#define DSC_MEM_EN 0x80000000
#define DSC_ECC_EN 0x20000000
#define DSC_RD_EN 0x10000000
+#define DSC_DBW_MASK 0x00180000
+#define DSC_DBW_32 0x00080000
+#define DSC_DBW_64 0x00000000
#define DSC_SDTYPE_MASK 0x07000000
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c
index a6b9fec13a7..7e5ff367705 100644
--- a/drivers/edac/mv64x60_edac.c
+++ b/drivers/edac/mv64x60_edac.c
@@ -12,10 +12,10 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/edac.h>
+#include <linux/gfp.h>
#include "edac_core.h"
#include "edac_module.h"
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index 8e6b91bd2e9..7f71ee43674 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c
index 9900675e959..d55f8e9de78 100644
--- a/drivers/edac/r82600_edac.c
+++ b/drivers/edac/r82600_edac.c
@@ -19,7 +19,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c
index d4ec6059317..b6f47de152f 100644
--- a/drivers/edac/x38_edac.c
+++ b/drivers/edac/x38_edac.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/slab.h>
#include <linux/edac.h>
#include "edac_core.h"
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index 66958b3f10b..806c77bfd43 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -39,10 +39,10 @@ static unsigned int enable_dev_count;
static int disable_dev[EISA_MAX_FORCED_DEV];
static unsigned int disable_dev_count;
-static int is_forced_dev (int *forced_tab,
- int forced_count,
- struct eisa_root_device *root,
- struct eisa_device *edev)
+static int is_forced_dev(int *forced_tab,
+ int forced_count,
+ struct eisa_root_device *root,
+ struct eisa_device *edev)
{
int i, x;
@@ -55,21 +55,21 @@ static int is_forced_dev (int *forced_tab,
return 0;
}
-static void __init eisa_name_device (struct eisa_device *edev)
+static void __init eisa_name_device(struct eisa_device *edev)
{
#ifdef CONFIG_EISA_NAMES
int i;
for (i = 0; i < EISA_INFOS; i++) {
- if (!strcmp (edev->id.sig, eisa_table[i].id.sig)) {
- strlcpy (edev->pretty_name,
- eisa_table[i].name,
- sizeof(edev->pretty_name));
+ if (!strcmp(edev->id.sig, eisa_table[i].id.sig)) {
+ strlcpy(edev->pretty_name,
+ eisa_table[i].name,
+ sizeof(edev->pretty_name));
return;
}
}
/* No name was found */
- sprintf (edev->pretty_name, "EISA device %.7s", edev->id.sig);
+ sprintf(edev->pretty_name, "EISA device %.7s", edev->id.sig);
#endif
}
@@ -91,7 +91,7 @@ static char __init *decode_eisa_sig(unsigned long addr)
*/
outb(0x80 + i, addr);
#endif
- sig[i] = inb (addr + i);
+ sig[i] = inb(addr + i);
if (!i && (sig[0] & 0x80))
return NULL;
@@ -106,17 +106,17 @@ static char __init *decode_eisa_sig(unsigned long addr)
return sig_str;
}
-static int eisa_bus_match (struct device *dev, struct device_driver *drv)
+static int eisa_bus_match(struct device *dev, struct device_driver *drv)
{
- struct eisa_device *edev = to_eisa_device (dev);
- struct eisa_driver *edrv = to_eisa_driver (drv);
+ struct eisa_device *edev = to_eisa_device(dev);
+ struct eisa_driver *edrv = to_eisa_driver(drv);
const struct eisa_device_id *eids = edrv->id_table;
if (!eids)
return 0;
- while (strlen (eids->sig)) {
- if (!strcmp (eids->sig, edev->id.sig) &&
+ while (strlen(eids->sig)) {
+ if (!strcmp(eids->sig, edev->id.sig) &&
edev->state & EISA_CONFIG_ENABLED) {
edev->id.driver_data = eids->driver_data;
return 1;
@@ -141,61 +141,71 @@ struct bus_type eisa_bus_type = {
.match = eisa_bus_match,
.uevent = eisa_bus_uevent,
};
+EXPORT_SYMBOL(eisa_bus_type);
-int eisa_driver_register (struct eisa_driver *edrv)
+int eisa_driver_register(struct eisa_driver *edrv)
{
edrv->driver.bus = &eisa_bus_type;
- return driver_register (&edrv->driver);
+ return driver_register(&edrv->driver);
}
+EXPORT_SYMBOL(eisa_driver_register);
-void eisa_driver_unregister (struct eisa_driver *edrv)
+void eisa_driver_unregister(struct eisa_driver *edrv)
{
- driver_unregister (&edrv->driver);
+ driver_unregister(&edrv->driver);
}
+EXPORT_SYMBOL(eisa_driver_unregister);
-static ssize_t eisa_show_sig (struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t eisa_show_sig(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct eisa_device *edev = to_eisa_device (dev);
- return sprintf (buf,"%s\n", edev->id.sig);
+ struct eisa_device *edev = to_eisa_device(dev);
+ return sprintf(buf, "%s\n", edev->id.sig);
}
static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL);
-static ssize_t eisa_show_state (struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t eisa_show_state(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct eisa_device *edev = to_eisa_device (dev);
- return sprintf (buf,"%d\n", edev->state & EISA_CONFIG_ENABLED);
+ struct eisa_device *edev = to_eisa_device(dev);
+ return sprintf(buf, "%d\n", edev->state & EISA_CONFIG_ENABLED);
}
static DEVICE_ATTR(enabled, S_IRUGO, eisa_show_state, NULL);
-static ssize_t eisa_show_modalias (struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t eisa_show_modalias(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct eisa_device *edev = to_eisa_device (dev);
- return sprintf (buf, EISA_DEVICE_MODALIAS_FMT "\n", edev->id.sig);
+ struct eisa_device *edev = to_eisa_device(dev);
+ return sprintf(buf, EISA_DEVICE_MODALIAS_FMT "\n", edev->id.sig);
}
static DEVICE_ATTR(modalias, S_IRUGO, eisa_show_modalias, NULL);
-static int __init eisa_init_device (struct eisa_root_device *root,
- struct eisa_device *edev,
- int slot)
+static int __init eisa_init_device(struct eisa_root_device *root,
+ struct eisa_device *edev,
+ int slot)
{
char *sig;
- unsigned long sig_addr;
+ unsigned long sig_addr;
int i;
- sig_addr = SLOT_ADDRESS (root, slot) + EISA_VENDOR_ID_OFFSET;
+ sig_addr = SLOT_ADDRESS(root, slot) + EISA_VENDOR_ID_OFFSET;
- if (!(sig = decode_eisa_sig (sig_addr)))
+ sig = decode_eisa_sig(sig_addr);
+ if (!sig)
return -1; /* No EISA device here */
- memcpy (edev->id.sig, sig, EISA_SIG_LEN);
+ memcpy(edev->id.sig, sig, EISA_SIG_LEN);
edev->slot = slot;
- edev->state = inb (SLOT_ADDRESS (root, slot) + EISA_CONFIG_OFFSET) & EISA_CONFIG_ENABLED;
- edev->base_addr = SLOT_ADDRESS (root, slot);
+ edev->state = inb(SLOT_ADDRESS(root, slot) + EISA_CONFIG_OFFSET)
+ & EISA_CONFIG_ENABLED;
+ edev->base_addr = SLOT_ADDRESS(root, slot);
edev->dma_mask = root->dma_mask; /* Default DMA mask */
- eisa_name_device (edev);
+ eisa_name_device(edev);
edev->dev.parent = root->dev;
edev->dev.bus = &eisa_bus_type;
edev->dev.dma_mask = &edev->dma_mask;
@@ -210,42 +220,45 @@ static int __init eisa_init_device (struct eisa_root_device *root,
#endif
}
- if (is_forced_dev (enable_dev, enable_dev_count, root, edev))
+ if (is_forced_dev(enable_dev, enable_dev_count, root, edev))
edev->state = EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED;
- if (is_forced_dev (disable_dev, disable_dev_count, root, edev))
+ if (is_forced_dev(disable_dev, disable_dev_count, root, edev))
edev->state = EISA_CONFIG_FORCED;
return 0;
}
-static int __init eisa_register_device (struct eisa_device *edev)
+static int __init eisa_register_device(struct eisa_device *edev)
{
- int rc = device_register (&edev->dev);
+ int rc = device_register(&edev->dev);
if (rc)
return rc;
- rc = device_create_file (&edev->dev, &dev_attr_signature);
- if (rc) goto err_devreg;
- rc = device_create_file (&edev->dev, &dev_attr_enabled);
- if (rc) goto err_sig;
- rc = device_create_file (&edev->dev, &dev_attr_modalias);
- if (rc) goto err_enab;
+ rc = device_create_file(&edev->dev, &dev_attr_signature);
+ if (rc)
+ goto err_devreg;
+ rc = device_create_file(&edev->dev, &dev_attr_enabled);
+ if (rc)
+ goto err_sig;
+ rc = device_create_file(&edev->dev, &dev_attr_modalias);
+ if (rc)
+ goto err_enab;
return 0;
err_enab:
- device_remove_file (&edev->dev, &dev_attr_enabled);
+ device_remove_file(&edev->dev, &dev_attr_enabled);
err_sig:
- device_remove_file (&edev->dev, &dev_attr_signature);
+ device_remove_file(&edev->dev, &dev_attr_signature);
err_devreg:
device_unregister(&edev->dev);
return rc;
}
-static int __init eisa_request_resources (struct eisa_root_device *root,
- struct eisa_device *edev,
- int slot)
+static int __init eisa_request_resources(struct eisa_root_device *root,
+ struct eisa_device *edev,
+ int slot)
{
int i;
@@ -263,17 +276,19 @@ static int __init eisa_request_resources (struct eisa_root_device *root,
if (slot) {
edev->res[i].name = NULL;
- edev->res[i].start = SLOT_ADDRESS (root, slot) + (i * 0x400);
+ edev->res[i].start = SLOT_ADDRESS(root, slot)
+ + (i * 0x400);
edev->res[i].end = edev->res[i].start + 0xff;
edev->res[i].flags = IORESOURCE_IO;
} else {
edev->res[i].name = NULL;
- edev->res[i].start = SLOT_ADDRESS (root, slot) + EISA_VENDOR_ID_OFFSET;
+ edev->res[i].start = SLOT_ADDRESS(root, slot)
+ + EISA_VENDOR_ID_OFFSET;
edev->res[i].end = edev->res[i].start + 3;
edev->res[i].flags = IORESOURCE_BUSY;
}
- if (request_resource (root->res, &edev->res[i]))
+ if (request_resource(root->res, &edev->res[i]))
goto failed;
}
@@ -281,99 +296,100 @@ static int __init eisa_request_resources (struct eisa_root_device *root,
failed:
while (--i >= 0)
- release_resource (&edev->res[i]);
+ release_resource(&edev->res[i]);
return -1;
}
-static void __init eisa_release_resources (struct eisa_device *edev)
+static void __init eisa_release_resources(struct eisa_device *edev)
{
int i;
for (i = 0; i < EISA_MAX_RESOURCES; i++)
if (edev->res[i].start || edev->res[i].end)
- release_resource (&edev->res[i]);
+ release_resource(&edev->res[i]);
}
-static int __init eisa_probe (struct eisa_root_device *root)
+static int __init eisa_probe(struct eisa_root_device *root)
{
int i, c;
struct eisa_device *edev;
- printk (KERN_INFO "EISA: Probing bus %d at %s\n",
- root->bus_nr, dev_name(root->dev));
+ printk(KERN_INFO "EISA: Probing bus %d at %s\n",
+ root->bus_nr, dev_name(root->dev));
/* First try to get hold of slot 0. If there is no device
* here, simply fail, unless root->force_probe is set. */
- if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
- printk (KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
+ edev = kzalloc(sizeof(*edev), GFP_KERNEL);
+ if (!edev) {
+ printk(KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
return -ENOMEM;
}
- if (eisa_request_resources (root, edev, 0)) {
- printk (KERN_WARNING \
- "EISA: Cannot allocate resource for mainboard\n");
- kfree (edev);
+ if (eisa_request_resources(root, edev, 0)) {
+ printk(KERN_WARNING \
+ "EISA: Cannot allocate resource for mainboard\n");
+ kfree(edev);
if (!root->force_probe)
return -EBUSY;
goto force_probe;
}
- if (eisa_init_device (root, edev, 0)) {
- eisa_release_resources (edev);
- kfree (edev);
+ if (eisa_init_device(root, edev, 0)) {
+ eisa_release_resources(edev);
+ kfree(edev);
if (!root->force_probe)
return -ENODEV;
goto force_probe;
}
- printk (KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig);
+ printk(KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig);
- if (eisa_register_device (edev)) {
- printk (KERN_ERR "EISA: Failed to register %s\n",
- edev->id.sig);
- eisa_release_resources (edev);
- kfree (edev);
+ if (eisa_register_device(edev)) {
+ printk(KERN_ERR "EISA: Failed to register %s\n",
+ edev->id.sig);
+ eisa_release_resources(edev);
+ kfree(edev);
}
force_probe:
for (c = 0, i = 1; i <= root->slots; i++) {
- if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
- printk (KERN_ERR "EISA: Out of memory for slot %d\n",
- i);
+ edev = kzalloc(sizeof(*edev), GFP_KERNEL);
+ if (!edev) {
+ printk(KERN_ERR "EISA: Out of memory for slot %d\n", i);
continue;
}
- if (eisa_request_resources (root, edev, i)) {
- printk (KERN_WARNING \
- "Cannot allocate resource for EISA slot %d\n",
- i);
- kfree (edev);
+ if (eisa_request_resources(root, edev, i)) {
+ printk(KERN_WARNING \
+ "Cannot allocate resource for EISA slot %d\n",
+ i);
+ kfree(edev);
continue;
}
- if (eisa_init_device (root, edev, i)) {
- eisa_release_resources (edev);
- kfree (edev);
+ if (eisa_init_device(root, edev, i)) {
+ eisa_release_resources(edev);
+ kfree(edev);
continue;
}
- printk (KERN_INFO "EISA: slot %d : %s detected",
- i, edev->id.sig);
+ printk(KERN_INFO "EISA: slot %d : %s detected",
+ i, edev->id.sig);
switch (edev->state) {
case EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED:
- printk (" (forced enabled)");
+ printk(" (forced enabled)");
break;
case EISA_CONFIG_FORCED:
- printk (" (forced disabled)");
+ printk(" (forced disabled)");
break;
case 0:
- printk (" (disabled)");
+ printk(" (disabled)");
break;
}
@@ -381,15 +397,15 @@ static int __init eisa_probe (struct eisa_root_device *root)
c++;
- if (eisa_register_device (edev)) {
- printk (KERN_ERR "EISA: Failed to register %s\n",
- edev->id.sig);
- eisa_release_resources (edev);
- kfree (edev);
+ if (eisa_register_device(edev)) {
+ printk(KERN_ERR "EISA: Failed to register %s\n",
+ edev->id.sig);
+ eisa_release_resources(edev);
+ kfree(edev);
}
}
- printk (KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s");
+ printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s");
return 0;
}
@@ -403,7 +419,7 @@ static struct resource eisa_root_res = {
static int eisa_bus_count;
-int __init eisa_root_register (struct eisa_root_device *root)
+int __init eisa_root_register(struct eisa_root_device *root)
{
int err;
@@ -417,35 +433,35 @@ int __init eisa_root_register (struct eisa_root_device *root)
root->eisa_root_res.end = root->res->end;
root->eisa_root_res.flags = IORESOURCE_BUSY;
- if ((err = request_resource (&eisa_root_res, &root->eisa_root_res)))
+ err = request_resource(&eisa_root_res, &root->eisa_root_res);
+ if (err)
return err;
root->bus_nr = eisa_bus_count++;
- if ((err = eisa_probe (root)))
- release_resource (&root->eisa_root_res);
+ err = eisa_probe(root);
+ if (err)
+ release_resource(&root->eisa_root_res);
return err;
}
-static int __init eisa_init (void)
+static int __init eisa_init(void)
{
int r;
- if ((r = bus_register (&eisa_bus_type)))
+ r = bus_register(&eisa_bus_type);
+ if (r)
return r;
- printk (KERN_INFO "EISA bus registered\n");
+ printk(KERN_INFO "EISA bus registered\n");
return 0;
}
module_param_array(enable_dev, int, &enable_dev_count, 0444);
module_param_array(disable_dev, int, &disable_dev_count, 0444);
-postcore_initcall (eisa_init);
+postcore_initcall(eisa_init);
int EISA_bus; /* for legacy drivers */
-EXPORT_SYMBOL (EISA_bus);
-EXPORT_SYMBOL (eisa_bus_type);
-EXPORT_SYMBOL (eisa_driver_register);
-EXPORT_SYMBOL (eisa_driver_unregister);
+EXPORT_SYMBOL(EISA_bus);
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 8be720b278b..14a34d99eea 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -34,6 +34,7 @@
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/time.h>
@@ -959,6 +960,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
u.packet.header_length = GET_HEADER_LENGTH(control);
if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
+ if (u.packet.header_length % 4 != 0)
+ return -EINVAL;
header_length = u.packet.header_length;
} else {
/*
@@ -968,7 +971,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
if (ctx->header_size == 0) {
if (u.packet.header_length > 0)
return -EINVAL;
- } else if (u.packet.header_length % ctx->header_size != 0) {
+ } else if (u.packet.header_length == 0 ||
+ u.packet.header_length % ctx->header_size != 0) {
return -EINVAL;
}
header_length = 0;
@@ -1353,24 +1357,24 @@ static int dispatch_ioctl(struct client *client,
return -ENODEV;
if (_IOC_TYPE(cmd) != '#' ||
- _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
+ _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
+ _IOC_SIZE(cmd) > sizeof(buffer))
return -EINVAL;
- if (_IOC_DIR(cmd) & _IOC_WRITE) {
- if (_IOC_SIZE(cmd) > sizeof(buffer) ||
- copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
+ if (_IOC_DIR(cmd) == _IOC_READ)
+ memset(&buffer, 0, _IOC_SIZE(cmd));
+
+ if (_IOC_DIR(cmd) & _IOC_WRITE)
+ if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
return -EFAULT;
- }
ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer);
if (ret < 0)
return ret;
- if (_IOC_DIR(cmd) & _IOC_READ) {
- if (_IOC_SIZE(cmd) > sizeof(buffer) ||
- copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
return -EFAULT;
- }
return ret;
}
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index 014cabd3afd..4b8523f00dc 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -33,7 +33,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
-#include <linux/semaphore.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/workqueue.h>
@@ -127,97 +127,74 @@ int fw_csr_string(const u32 *directory, int key, char *buf, size_t size)
}
EXPORT_SYMBOL(fw_csr_string);
-static bool is_fw_unit(struct device *dev);
-
-static int match_unit_directory(const u32 *directory, u32 match_flags,
- const struct ieee1394_device_id *id)
+static void get_ids(const u32 *directory, int *id)
{
struct fw_csr_iterator ci;
- int key, value, match;
+ int key, value;
- match = 0;
fw_csr_iterator_init(&ci, directory);
while (fw_csr_iterator_next(&ci, &key, &value)) {
- if (key == CSR_VENDOR && value == id->vendor_id)
- match |= IEEE1394_MATCH_VENDOR_ID;
- if (key == CSR_MODEL && value == id->model_id)
- match |= IEEE1394_MATCH_MODEL_ID;
- if (key == CSR_SPECIFIER_ID && value == id->specifier_id)
- match |= IEEE1394_MATCH_SPECIFIER_ID;
- if (key == CSR_VERSION && value == id->version)
- match |= IEEE1394_MATCH_VERSION;
+ switch (key) {
+ case CSR_VENDOR: id[0] = value; break;
+ case CSR_MODEL: id[1] = value; break;
+ case CSR_SPECIFIER_ID: id[2] = value; break;
+ case CSR_VERSION: id[3] = value; break;
+ }
}
+}
+
+static void get_modalias_ids(struct fw_unit *unit, int *id)
+{
+ get_ids(&fw_parent_device(unit)->config_rom[5], id);
+ get_ids(unit->directory, id);
+}
+
+static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
+{
+ int match = 0;
+
+ if (id[0] == id_table->vendor_id)
+ match |= IEEE1394_MATCH_VENDOR_ID;
+ if (id[1] == id_table->model_id)
+ match |= IEEE1394_MATCH_MODEL_ID;
+ if (id[2] == id_table->specifier_id)
+ match |= IEEE1394_MATCH_SPECIFIER_ID;
+ if (id[3] == id_table->version)
+ match |= IEEE1394_MATCH_VERSION;
- return (match & match_flags) == match_flags;
+ return (match & id_table->match_flags) == id_table->match_flags;
}
+static bool is_fw_unit(struct device *dev);
+
static int fw_unit_match(struct device *dev, struct device_driver *drv)
{
- struct fw_unit *unit = fw_unit(dev);
- struct fw_device *device;
- const struct ieee1394_device_id *id;
+ const struct ieee1394_device_id *id_table =
+ container_of(drv, struct fw_driver, driver)->id_table;
+ int id[] = {0, 0, 0, 0};
/* We only allow binding to fw_units. */
if (!is_fw_unit(dev))
return 0;
- device = fw_parent_device(unit);
- id = container_of(drv, struct fw_driver, driver)->id_table;
+ get_modalias_ids(fw_unit(dev), id);
- for (; id->match_flags != 0; id++) {
- if (match_unit_directory(unit->directory, id->match_flags, id))
+ for (; id_table->match_flags != 0; id_table++)
+ if (match_ids(id_table, id))
return 1;
- /* Also check vendor ID in the root directory. */
- if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
- match_unit_directory(&device->config_rom[5],
- IEEE1394_MATCH_VENDOR_ID, id) &&
- match_unit_directory(unit->directory, id->match_flags
- & ~IEEE1394_MATCH_VENDOR_ID, id))
- return 1;
- }
-
return 0;
}
static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
{
- struct fw_device *device = fw_parent_device(unit);
- struct fw_csr_iterator ci;
+ int id[] = {0, 0, 0, 0};
- int key, value;
- int vendor = 0;
- int model = 0;
- int specifier_id = 0;
- int version = 0;
-
- fw_csr_iterator_init(&ci, &device->config_rom[5]);
- while (fw_csr_iterator_next(&ci, &key, &value)) {
- switch (key) {
- case CSR_VENDOR:
- vendor = value;
- break;
- case CSR_MODEL:
- model = value;
- break;
- }
- }
-
- fw_csr_iterator_init(&ci, unit->directory);
- while (fw_csr_iterator_next(&ci, &key, &value)) {
- switch (key) {
- case CSR_SPECIFIER_ID:
- specifier_id = value;
- break;
- case CSR_VERSION:
- version = value;
- break;
- }
- }
+ get_modalias_ids(unit, id);
return snprintf(buffer, buffer_size,
"ieee1394:ven%08Xmo%08Xsp%08Xver%08X",
- vendor, model, specifier_id, version);
+ id[0], id[1], id[2], id[3]);
}
static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -828,9 +805,9 @@ static int update_unit(struct device *dev, void *data)
struct fw_driver *driver = (struct fw_driver *)dev->driver;
if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
- down(&dev->sem);
+ device_lock(dev);
driver->update(unit);
- up(&dev->sem);
+ device_unlock(dev);
}
return 0;
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index 1c0b504a42f..8f5aebfb29d 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -26,6 +26,7 @@
#include <linux/firewire-constants.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
@@ -189,7 +190,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
for (try = 0; try < 5; try++) {
new = allocate ? old - bandwidth : old + bandwidth;
if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
- break;
+ return -EBUSY;
data[0] = cpu_to_be32(old);
data[1] = cpu_to_be32(new);
@@ -217,7 +218,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
{
__be32 c, all, old;
- int i, retry = 5;
+ int i, ret = -EIO, retry = 5;
old = all = allocate ? cpu_to_be32(~0) : 0;
@@ -225,6 +226,8 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
if (!(channels_mask & 1 << i))
continue;
+ ret = -EBUSY;
+
c = cpu_to_be32(1 << (31 - i));
if ((old & c) != (all & c))
continue;
@@ -250,12 +253,16 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
/* 1394-1995 IRM, fall through to retry. */
default:
- if (retry--)
+ if (retry) {
+ retry--;
i--;
+ } else {
+ ret = -EIO;
+ }
}
}
- return -EIO;
+ return ret;
}
static void deallocate_channel(struct fw_card *card, int irm_id,
@@ -331,8 +338,9 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
if (ret < 0)
*bandwidth = 0;
- if (allocate && ret < 0 && c >= 0) {
- deallocate_channel(card, irm_id, generation, c, buffer);
+ if (allocate && ret < 0) {
+ if (c >= 0)
+ deallocate_channel(card, irm_id, generation, c, buffer);
*channel = ret;
}
}
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 2d3dc7ded0a..7142eeec807 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -21,6 +21,7 @@
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/unaligned.h>
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 75dc6988cff..94b16e0340a 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -24,7 +24,6 @@
#include <linux/dma-mapping.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
-#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -35,6 +34,7 @@
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
@@ -231,6 +231,8 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
static char ohci_driver_name[] = KBUILD_MODNAME;
+#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
+
#define QUIRK_CYCLE_TIMER 1
#define QUIRK_RESET_PACKET 2
#define QUIRK_BE_HEADERS 4
@@ -239,6 +241,8 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
static const struct {
unsigned short vendor, device, flags;
} ohci_quirks[] = {
+ {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER |
+ QUIRK_RESET_PACKET},
{PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET},
{PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
{PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
@@ -1154,7 +1158,7 @@ static void handle_local_lock(struct fw_ohci *ohci,
struct fw_packet *packet, u32 csr)
{
struct fw_packet response;
- int tcode, length, ext_tcode, sel;
+ int tcode, length, ext_tcode, sel, try;
__be32 *payload, lock_old;
u32 lock_arg, lock_data;
@@ -1181,21 +1185,26 @@ static void handle_local_lock(struct fw_ohci *ohci,
reg_write(ohci, OHCI1394_CSRCompareData, lock_arg);
reg_write(ohci, OHCI1394_CSRControl, sel);
- if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000)
- lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData));
- else
- fw_notify("swap not done yet\n");
+ for (try = 0; try < 20; try++)
+ if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) {
+ lock_old = cpu_to_be32(reg_read(ohci,
+ OHCI1394_CSRData));
+ fw_fill_response(&response, packet->header,
+ RCODE_COMPLETE,
+ &lock_old, sizeof(lock_old));
+ goto out;
+ }
+
+ fw_error("swap not done (CSR lock timeout)\n");
+ fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
- fw_fill_response(&response, packet->header,
- RCODE_COMPLETE, &lock_old, sizeof(lock_old));
out:
fw_core_handle_response(&ohci->card, &response);
}
static void handle_local_request(struct context *ctx, struct fw_packet *packet)
{
- u64 offset;
- u32 csr;
+ u64 offset, csr;
if (ctx == &ctx->ohci->at_request_ctx) {
packet->ack = ACK_PENDING;
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 18d65fb42ee..fb09bb3c0ad 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mc146818rtc.h>
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index b3a0cf57442..3a4460265b1 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -36,6 +36,7 @@
*/
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/blkdev.h>
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
index dbdf6fadfc7..a777a35381d 100644
--- a/drivers/firmware/dmi-id.c
+++ b/drivers/firmware/dmi-id.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/dmi.h>
#include <linux/device.h>
+#include <linux/slab.h>
struct dmi_device_attribute{
struct device_attribute dev_attr;
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 31b983d9462..d4646727134 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -5,7 +5,6 @@
#include <linux/dmi.h>
#include <linux/efi.h>
#include <linux/bootmem.h>
-#include <linux/slab.h>
#include <asm/dmi.h>
/*
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 9e4f59dc7f1..110e24e5088 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -122,7 +122,7 @@ edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
return ret;
}
-static struct sysfs_ops edd_attr_ops = {
+static const struct sysfs_ops edd_attr_ops = {
.show = edd_attr_show,
};
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index f4f709d1370..81b70bd0758 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -77,6 +77,7 @@
#include <linux/sysfs.h>
#include <linux/kobject.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -362,7 +363,7 @@ static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static struct sysfs_ops efivar_attr_ops = {
+static const struct sysfs_ops efivar_attr_ops = {
.show = efivar_attr_show,
.store = efivar_attr_store,
};
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index a3600e3ed0f..ed2801c378d 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -519,7 +519,7 @@ static ssize_t ibft_show_attribute(struct kobject *kobj,
return ret;
}
-static struct sysfs_ops ibft_attr_ops = {
+static const struct sysfs_ops ibft_attr_ops = {
.show = ibft_show_attribute,
};
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index dfb15c06c88..d6470ef36e4 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -27,7 +27,6 @@
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/types.h>
@@ -52,7 +51,7 @@ EXPORT_SYMBOL_GPL(ibft_addr);
* Routine used to find the iSCSI Boot Format Table. The logical
* kernel address is set in the ibft_addr global variable.
*/
-void __init reserve_ibft_region(void)
+unsigned long __init find_ibft_region(unsigned long *sizep)
{
unsigned long pos;
unsigned int len = 0;
@@ -78,6 +77,11 @@ void __init reserve_ibft_region(void)
}
}
}
- if (ibft_addr)
- reserve_bootmem(pos, PAGE_ALIGN(len), BOOTMEM_DEFAULT);
+ if (ibft_addr) {
+ *sizep = PAGE_ALIGN(len);
+ return pos;
+ }
+
+ *sizep = 0;
+ return 0;
}
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index 56f9234781f..adc07102a20 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/bootmem.h>
+#include <linux/slab.h>
/*
* Data types ------------------------------------------------------------------
@@ -74,7 +75,7 @@ static struct attribute *def_attrs[] = {
NULL
};
-static struct sysfs_ops memmap_attr_ops = {
+static const struct sysfs_ops memmap_attr_ops = {
.show = memmap_attr_show,
};
@@ -122,29 +123,53 @@ static int firmware_map_add_entry(u64 start, u64 end,
return 0;
}
+/*
+ * Add memmap entry on sysfs
+ */
+static int add_sysfs_fw_map_entry(struct firmware_map_entry *entry)
+{
+ static int map_entries_nr;
+ static struct kset *mmap_kset;
+
+ if (!mmap_kset) {
+ mmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
+ if (!mmap_kset)
+ return -ENOMEM;
+ }
+
+ entry->kobj.kset = mmap_kset;
+ if (kobject_add(&entry->kobj, NULL, "%d", map_entries_nr++))
+ kobject_put(&entry->kobj);
+
+ return 0;
+}
+
/**
- * firmware_map_add() - Adds a firmware mapping entry.
+ * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do
+ * memory hotplug.
* @start: Start of the memory range.
* @end: End of the memory range (inclusive).
* @type: Type of the memory range.
*
- * This function uses kmalloc() for memory
- * allocation. Use firmware_map_add_early() if you want to use the bootmem
- * allocator.
- *
- * That function must be called before late_initcall.
+ * Adds a firmware mapping entry. This function is for memory hotplug, it is
+ * similar to function firmware_map_add_early(). The only difference is that
+ * it will create the syfs entry dynamically.
*
* Returns 0 on success, or -ENOMEM if no memory could be allocated.
**/
-int firmware_map_add(u64 start, u64 end, const char *type)
+int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type)
{
struct firmware_map_entry *entry;
- entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
+ entry = kzalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
if (!entry)
return -ENOMEM;
- return firmware_map_add_entry(start, end, type, entry);
+ firmware_map_add_entry(start, end, type, entry);
+ /* create the memmap entry */
+ add_sysfs_fw_map_entry(entry);
+
+ return 0;
}
/**
@@ -154,7 +179,7 @@ int firmware_map_add(u64 start, u64 end, const char *type)
* @type: Type of the memory range.
*
* Adds a firmware mapping entry. This function uses the bootmem allocator
- * for memory allocation. Use firmware_map_add() if you want to use kmalloc().
+ * for memory allocation.
*
* That function must be called before late_initcall.
*
@@ -214,19 +239,10 @@ static ssize_t memmap_attr_show(struct kobject *kobj,
*/
static int __init memmap_init(void)
{
- int i = 0;
struct firmware_map_entry *entry;
- struct kset *memmap_kset;
-
- memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
- if (WARN_ON(!memmap_kset))
- return -ENOMEM;
- list_for_each_entry(entry, &map_entries, list) {
- entry->kobj.kset = memmap_kset;
- if (kobject_add(&entry->kobj, NULL, "%d", i++))
- kobject_put(&entry->kobj);
- }
+ list_for_each_entry(entry, &map_entries, list)
+ add_sysfs_fw_map_entry(entry);
return 0;
}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 1f1d88ae68d..fee678f74a1 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -65,8 +65,17 @@ config GPIO_SYSFS
# put expanders in the right section, in alphabetical order
+config GPIO_MAX730X
+ tristate
+
comment "Memory mapped GPIO expanders:"
+config GPIO_IT8761E
+ tristate "IT8761E GPIO support"
+ depends on GPIOLIB
+ help
+ Say yes here to support GPIO functionality of IT8761E super I/O chip.
+
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
@@ -85,8 +94,32 @@ config GPIO_VR41XX
help
Say yes here to support the NEC VR4100 series General-purpose I/O Uint
+config GPIO_SCH
+ tristate "Intel SCH GPIO"
+ depends on GPIOLIB && PCI
+ select MFD_CORE
+ select LPC_SCH
+ help
+ Say yes here to support GPIO interface on Intel Poulsbo SCH.
+ The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are
+ powered by the core power rail and are turned off during sleep
+ modes (S3 and higher). The remaining four GPIOs are powered by
+ the Intel SCH suspend power supply. These GPIOs remain
+ active during S3. The suspend powered GPIOs can be used to wake the
+ system from the Suspend-to-RAM state.
+
+ This driver can also be built as a module. If so, the module
+ will be called sch-gpio.
+
comment "I2C GPIO expanders:"
+config GPIO_MAX7300
+ tristate "Maxim MAX7300 GPIO expander"
+ depends on I2C
+ select GPIO_MAX730X
+ help
+ GPIO driver for Maxim MAX7301 I2C-based GPIO expander.
+
config GPIO_MAX732X
tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
depends on I2C
@@ -124,6 +157,13 @@ config GPIO_PCA953X
This driver can also be built as a module. If so, the module
will be called pca953x.
+config GPIO_PCA953X_IRQ
+ bool "Interrupt controller support for PCA953x"
+ depends on GPIO_PCA953X=y
+ help
+ Say yes here to enable the pca953x to be used as an interrupt
+ controller. It requires the driver to be built in the kernel.
+
config GPIO_PCF857X
tristate "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders"
depends on I2C
@@ -162,6 +202,20 @@ config GPIO_WM831X
Say yes here to access the GPIO signals of WM831x power management
chips from Wolfson Microelectronics.
+config GPIO_WM8350
+ tristate "WM8350 GPIOs"
+ depends on MFD_WM8350
+ help
+ Say yes here to access the GPIO signals of WM8350 power management
+ chips from Wolfson Microelectronics.
+
+config GPIO_WM8994
+ tristate "WM8994 GPIOs"
+ depends on MFD_WM8994
+ help
+ Say yes here to access the GPIO signals of WM8994 audio hub
+ CODECs from Wolfson Microelectronics.
+
config GPIO_ADP5520
tristate "GPIO Support for ADP5520 PMIC"
depends on PMIC_ADP5520
@@ -226,8 +280,9 @@ comment "SPI GPIO expanders:"
config GPIO_MAX7301
tristate "Maxim MAX7301 GPIO expander"
depends on SPI_MASTER
+ select GPIO_MAX730X
help
- gpio driver for Maxim MAX7301 SPI GPIO expander.
+ GPIO driver for Maxim MAX7301 SPI-based GPIO expander.
config GPIO_MCP23S08
tristate "Microchip MCP23S08 I/O expander"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 48687238edb..10f3f8d958b 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_GPIOLIB) += gpiolib.o
obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o
obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o
obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o
+obj-$(CONFIG_GPIO_MAX730X) += max730x.o
+obj-$(CONFIG_GPIO_MAX7300) += max7300.o
obj-$(CONFIG_GPIO_MAX7301) += max7301.o
obj-$(CONFIG_GPIO_MAX732X) += max732x.o
obj-$(CONFIG_GPIO_MC33880) += mc33880.o
@@ -20,5 +22,9 @@ obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o
obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o
obj-$(CONFIG_GPIO_CS5535) += cs5535-gpio.o
obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o
+obj-$(CONFIG_GPIO_IT8761E) += it8761e_gpio.o
obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o
+obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o
+obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o
+obj-$(CONFIG_GPIO_SCH) += sch_gpio.o \ No newline at end of file
diff --git a/drivers/gpio/adp5520-gpio.c b/drivers/gpio/adp5520-gpio.c
index 0f93105873c..9f278153700 100644
--- a/drivers/gpio/adp5520-gpio.c
+++ b/drivers/gpio/adp5520-gpio.c
@@ -7,6 +7,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/adp5588-gpio.c
index afc097a16b3..2e8e9e24f88 100644
--- a/drivers/gpio/adp5588-gpio.c
+++ b/drivers/gpio/adp5588-gpio.c
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/bt8xxgpio.c
index 2559f228940..aa4f09ad3ce 100644
--- a/drivers/gpio/bt8xxgpio.c
+++ b/drivers/gpio/bt8xxgpio.c
@@ -47,6 +47,7 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
/* Steal the hardware definitions from the bttv driver. */
#include "../media/video/bt8xx/bt848.h"
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c
index 0fdbe94f24a..0c3c498f226 100644
--- a/drivers/gpio/cs5535-gpio.c
+++ b/drivers/gpio/cs5535-gpio.c
@@ -154,7 +154,7 @@ static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
{
- return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL);
+ return cs5535_gpio_isset(offset, GPIO_READ_BACK);
}
static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
@@ -172,6 +172,7 @@ static int chip_direction_input(struct gpio_chip *c, unsigned offset)
spin_lock_irqsave(&chip->lock, flags);
__cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
+ __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -184,6 +185,7 @@ static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
spin_lock_irqsave(&chip->lock, flags);
+ __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
if (val)
__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 350842ad363..eb0c3fe44b2 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -9,6 +9,7 @@
#include <linux/seq_file.h>
#include <linux/gpio.h>
#include <linux/idr.h>
+#include <linux/slab.h>
/* Optional implementation infrastructure for GPIO interfaces.
@@ -415,7 +416,8 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
return 0;
free_sd:
- sysfs_put(pdesc->value_sd);
+ if (pdesc)
+ sysfs_put(pdesc->value_sd);
free_id:
idr_remove(&pdesc_idr, id);
desc->flags &= GPIO_FLAGS_MASK;
@@ -623,7 +625,9 @@ static const struct attribute_group gpiochip_attr_group = {
* /sys/class/gpio/unexport ... write-only
* integer N ... number of GPIO to unexport
*/
-static ssize_t export_store(struct class *class, const char *buf, size_t len)
+static ssize_t export_store(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t len)
{
long gpio;
int status;
@@ -653,7 +657,9 @@ done:
return status ? : len;
}
-static ssize_t unexport_store(struct class *class, const char *buf, size_t len)
+static ssize_t unexport_store(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t len)
{
long gpio;
int status;
@@ -1237,6 +1243,64 @@ void gpio_free(unsigned gpio)
}
EXPORT_SYMBOL_GPL(gpio_free);
+/**
+ * gpio_request_one - request a single GPIO with initial configuration
+ * @gpio: the GPIO number
+ * @flags: GPIO configuration as specified by GPIOF_*
+ * @label: a literal description string of this GPIO
+ */
+int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+{
+ int err;
+
+ err = gpio_request(gpio, label);
+ if (err)
+ return err;
+
+ if (flags & GPIOF_DIR_IN)
+ err = gpio_direction_input(gpio);
+ else
+ err = gpio_direction_output(gpio,
+ (flags & GPIOF_INIT_HIGH) ? 1 : 0);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(gpio_request_one);
+
+/**
+ * gpio_request_array - request multiple GPIOs in a single call
+ * @array: array of the 'struct gpio'
+ * @num: how many GPIOs in the array
+ */
+int gpio_request_array(struct gpio *array, size_t num)
+{
+ int i, err;
+
+ for (i = 0; i < num; i++, array++) {
+ err = gpio_request_one(array->gpio, array->flags, array->label);
+ if (err)
+ goto err_free;
+ }
+ return 0;
+
+err_free:
+ while (i--)
+ gpio_free((--array)->gpio);
+ return err;
+}
+EXPORT_SYMBOL_GPL(gpio_request_array);
+
+/**
+ * gpio_free_array - release multiple GPIOs in a single call
+ * @array: array of the 'struct gpio'
+ * @num: how many GPIOs in the array
+ */
+void gpio_free_array(struct gpio *array, size_t num)
+{
+ while (num--)
+ gpio_free((array++)->gpio);
+}
+EXPORT_SYMBOL_GPL(gpio_free_array);
/**
* gpiochip_is_requested - return string iff signal was requested
diff --git a/drivers/gpio/it8761e_gpio.c b/drivers/gpio/it8761e_gpio.c
new file mode 100644
index 00000000000..753219cf993
--- /dev/null
+++ b/drivers/gpio/it8761e_gpio.c
@@ -0,0 +1,231 @@
+/*
+ * it8761_gpio.c - GPIO interface for IT8761E Super I/O chip
+ *
+ * Author: Denis Turischev <denis@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+
+#include <linux/gpio.h>
+
+#define SIO_CHIP_ID 0x8761
+#define CHIP_ID_HIGH_BYTE 0x20
+#define CHIP_ID_LOW_BYTE 0x21
+
+static u8 ports[2] = { 0x2e, 0x4e };
+static u8 port;
+
+static DEFINE_SPINLOCK(sio_lock);
+
+#define GPIO_NAME "it8761-gpio"
+#define GPIO_BA_HIGH_BYTE 0x60
+#define GPIO_BA_LOW_BYTE 0x61
+#define GPIO_IOSIZE 4
+#define GPIO1X_IO 0xf0
+#define GPIO2X_IO 0xf1
+
+static u16 gpio_ba;
+
+static u8 read_reg(u8 addr, u8 port)
+{
+ outb(addr, port);
+ return inb(port + 1);
+}
+
+static void write_reg(u8 data, u8 addr, u8 port)
+{
+ outb(addr, port);
+ outb(data, port + 1);
+}
+
+static void enter_conf_mode(u8 port)
+{
+ outb(0x87, port);
+ outb(0x61, port);
+ outb(0x55, port);
+ outb((port == 0x2e) ? 0x55 : 0xaa, port);
+}
+
+static void exit_conf_mode(u8 port)
+{
+ outb(0x2, port);
+ outb(0x2, port + 1);
+}
+
+static void enter_gpio_mode(u8 port)
+{
+ write_reg(0x2, 0x7, port);
+}
+
+static int it8761e_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
+{
+ u16 reg;
+ u8 bit;
+
+ bit = gpio_num % 7;
+ reg = (gpio_num >= 7) ? gpio_ba + 1 : gpio_ba;
+
+ return !!(inb(reg) & (1 << bit));
+}
+
+static int it8761e_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
+{
+ u8 curr_dirs;
+ u8 io_reg, bit;
+
+ bit = gpio_num % 7;
+ io_reg = (gpio_num >= 7) ? GPIO2X_IO : GPIO1X_IO;
+
+ spin_lock(&sio_lock);
+
+ enter_conf_mode(port);
+ enter_gpio_mode(port);
+
+ curr_dirs = read_reg(io_reg, port);
+
+ if (curr_dirs & (1 << bit))
+ write_reg(curr_dirs & ~(1 << bit), io_reg, port);
+
+ exit_conf_mode(port);
+
+ spin_unlock(&sio_lock);
+ return 0;
+}
+
+static void it8761e_gpio_set(struct gpio_chip *gc,
+ unsigned gpio_num, int val)
+{
+ u8 curr_vals, bit;
+ u16 reg;
+
+ bit = gpio_num % 7;
+ reg = (gpio_num >= 7) ? gpio_ba + 1 : gpio_ba;
+
+ spin_lock(&sio_lock);
+
+ curr_vals = inb(reg);
+ if (val)
+ outb(curr_vals | (1 << bit) , reg);
+ else
+ outb(curr_vals & ~(1 << bit), reg);
+
+ spin_unlock(&sio_lock);
+}
+
+static int it8761e_gpio_direction_out(struct gpio_chip *gc,
+ unsigned gpio_num, int val)
+{
+ u8 curr_dirs, io_reg, bit;
+
+ bit = gpio_num % 7;
+ io_reg = (gpio_num >= 7) ? GPIO2X_IO : GPIO1X_IO;
+
+ it8761e_gpio_set(gc, gpio_num, val);
+
+ spin_lock(&sio_lock);
+
+ enter_conf_mode(port);
+ enter_gpio_mode(port);
+
+ curr_dirs = read_reg(io_reg, port);
+
+ if (!(curr_dirs & (1 << bit)))
+ write_reg(curr_dirs | (1 << bit), io_reg, port);
+
+ exit_conf_mode(port);
+
+ spin_unlock(&sio_lock);
+ return 0;
+}
+
+static struct gpio_chip it8761e_gpio_chip = {
+ .label = GPIO_NAME,
+ .owner = THIS_MODULE,
+ .get = it8761e_gpio_get,
+ .direction_input = it8761e_gpio_direction_in,
+ .set = it8761e_gpio_set,
+ .direction_output = it8761e_gpio_direction_out,
+};
+
+static int __init it8761e_gpio_init(void)
+{
+ int i, id, err;
+
+ /* chip and port detection */
+ for (i = 0; i < ARRAY_SIZE(ports); i++) {
+ spin_lock(&sio_lock);
+ enter_conf_mode(ports[i]);
+
+ id = (read_reg(CHIP_ID_HIGH_BYTE, ports[i]) << 8) +
+ read_reg(CHIP_ID_LOW_BYTE, ports[i]);
+
+ exit_conf_mode(ports[i]);
+ spin_unlock(&sio_lock);
+
+ if (id == SIO_CHIP_ID) {
+ port = ports[i];
+ break;
+ }
+ }
+
+ if (!port)
+ return -ENODEV;
+
+ /* fetch GPIO base address */
+ enter_conf_mode(port);
+ enter_gpio_mode(port);
+ gpio_ba = (read_reg(GPIO_BA_HIGH_BYTE, port) << 8) +
+ read_reg(GPIO_BA_LOW_BYTE, port);
+ exit_conf_mode(port);
+
+ if (!request_region(gpio_ba, GPIO_IOSIZE, GPIO_NAME))
+ return -EBUSY;
+
+ it8761e_gpio_chip.base = -1;
+ it8761e_gpio_chip.ngpio = 14;
+
+ err = gpiochip_add(&it8761e_gpio_chip);
+ if (err < 0)
+ goto gpiochip_add_err;
+
+ return 0;
+
+gpiochip_add_err:
+ release_region(gpio_ba, GPIO_IOSIZE);
+ gpio_ba = 0;
+ return err;
+}
+
+static void __exit it8761e_gpio_exit(void)
+{
+ if (gpio_ba) {
+ gpiochip_remove(&it8761e_gpio_chip);
+
+ release_region(gpio_ba, GPIO_IOSIZE);
+ gpio_ba = 0;
+ }
+}
+module_init(it8761e_gpio_init);
+module_exit(it8761e_gpio_exit);
+
+MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
+MODULE_DESCRIPTION("GPIO interface for IT8761E Super I/O chip");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 6c0ebbdc659..00c3a14127a 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -29,6 +29,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
struct lnw_gpio_register {
u32 GPLR[2];
diff --git a/drivers/gpio/max7300.c b/drivers/gpio/max7300.c
new file mode 100644
index 00000000000..962f661c18c
--- /dev/null
+++ b/drivers/gpio/max7300.c
@@ -0,0 +1,95 @@
+/*
+ * drivers/gpio/max7300.c
+ *
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Check max730x.c for further details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+#include <linux/spi/max7301.h>
+#include <linux/slab.h>
+
+static int max7300_i2c_write(struct device *dev, unsigned int reg,
+ unsigned int val)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int max7300_i2c_read(struct device *dev, unsigned int reg)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int __devinit max7300_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct max7301 *ts;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ ts = kzalloc(sizeof(struct max7301), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ ts->read = max7300_i2c_read;
+ ts->write = max7300_i2c_write;
+ ts->dev = &client->dev;
+
+ ret = __max730x_probe(ts);
+ if (ret)
+ kfree(ts);
+ return ret;
+}
+
+static int __devexit max7300_remove(struct i2c_client *client)
+{
+ return __max730x_remove(&client->dev);
+}
+
+static const struct i2c_device_id max7300_id[] = {
+ { "max7300", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max7300_id);
+
+static struct i2c_driver max7300_driver = {
+ .driver = {
+ .name = "max7300",
+ .owner = THIS_MODULE,
+ },
+ .probe = max7300_probe,
+ .remove = __devexit_p(max7300_remove),
+ .id_table = max7300_id,
+};
+
+static int __init max7300_init(void)
+{
+ return i2c_add_driver(&max7300_driver);
+}
+subsys_initcall(max7300_init);
+
+static void __exit max7300_exit(void)
+{
+ i2c_del_driver(&max7300_driver);
+}
+module_exit(max7300_exit);
+
+MODULE_AUTHOR("Wolfram Sang");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MAX7300 GPIO-Expander");
diff --git a/drivers/gpio/max7301.c b/drivers/gpio/max7301.c
index 480956f1ca5..92a100ddef6 100644
--- a/drivers/gpio/max7301.c
+++ b/drivers/gpio/max7301.c
@@ -1,98 +1,42 @@
-/**
+/*
* drivers/gpio/max7301.c
*
* Copyright (C) 2006 Juergen Beisert, Pengutronix
* Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * The Maxim's MAX7301 device is an SPI driven GPIO expander. There are
- * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
- * details
- * Note:
- * - DIN must be stable at the rising edge of clock.
- * - when writing:
- * - always clock in 16 clocks at once
- * - at DIN: D15 first, D0 last
- * - D0..D7 = databyte, D8..D14 = commandbyte
- * - D15 = low -> write command
- * - when reading
- * - always clock in 16 clocks at once
- * - at DIN: D15 first, D0 last
- * - D0..D7 = dummy, D8..D14 = register address
- * - D15 = high -> read command
- * - raise CS and assert it again
- * - always clock in 16 clocks at once
- * - at DOUT: D15 first, D0 last
- * - D0..D7 contains the data from the first cycle
- *
- * The driver exports a standard gpiochip interface
+ * Check max730x.c for further details.
*/
+#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/max7301.h>
-#include <linux/gpio.h>
-
-#define DRIVER_NAME "max7301"
-
-/*
- * Pin configurations, see MAX7301 datasheet page 6
- */
-#define PIN_CONFIG_MASK 0x03
-#define PIN_CONFIG_IN_PULLUP 0x03
-#define PIN_CONFIG_IN_WO_PULLUP 0x02
-#define PIN_CONFIG_OUT 0x01
-
-#define PIN_NUMBER 28
-
-
-/*
- * Some registers must be read back to modify.
- * To save time we cache them here in memory
- */
-struct max7301 {
- struct mutex lock;
- u8 port_config[8]; /* field 0 is unused */
- u32 out_level; /* cached output levels */
- struct gpio_chip chip;
- struct spi_device *spi;
-};
-/**
- * max7301_write - Write a new register content
- * @spi: The SPI device
- * @reg: Register offset
- * @val: Value to write
- *
- * A write to the MAX7301 means one message with one transfer
- *
- * Returns 0 if successful or a negative value on error
- */
-static int max7301_write(struct spi_device *spi, unsigned int reg, unsigned int val)
+/* A write to the MAX7301 means one message with one transfer */
+static int max7301_spi_write(struct device *dev, unsigned int reg,
+ unsigned int val)
{
+ struct spi_device *spi = to_spi_device(dev);
u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);
+
return spi_write(spi, (const u8 *)&word, sizeof(word));
}
-/**
- * max7301_read - Read back register content
- * @spi: The SPI device
- * @reg: Register offset
- *
- * A read from the MAX7301 means two transfers; here, one message each
- *
- * Returns positive 8 bit value from device if successful or a
- * negative value on error
- */
-static int max7301_read(struct spi_device *spi, unsigned int reg)
+/* A read from the MAX7301 means two transfers; here, one message each */
+
+static int max7301_spi_read(struct device *dev, unsigned int reg)
{
int ret;
u16 word;
+ struct spi_device *spi = to_spi_device(dev);
word = 0x8000 | (reg << 8);
ret = spi_write(spi, (const u8 *)&word, sizeof(word));
@@ -108,125 +52,13 @@ static int max7301_read(struct spi_device *spi, unsigned int reg)
return word & 0xff;
}
-static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
-{
- struct max7301 *ts = container_of(chip, struct max7301, chip);
- u8 *config;
- int ret;
-
- /* First 4 pins are unused in the controller */
- offset += 4;
-
- config = &ts->port_config[offset >> 2];
-
- mutex_lock(&ts->lock);
-
- /* Standard GPIO API doesn't support pull-ups, has to be extended.
- * Hard-coding no pollup for now. */
- *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
-
- ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
-
- mutex_unlock(&ts->lock);
-
- return ret;
-}
-
-static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
-{
- if (value) {
- ts->out_level |= 1 << offset;
- return max7301_write(ts->spi, 0x20 + offset, 0x01);
- } else {
- ts->out_level &= ~(1 << offset);
- return max7301_write(ts->spi, 0x20 + offset, 0x00);
- }
-}
-
-static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
- int value)
-{
- struct max7301 *ts = container_of(chip, struct max7301, chip);
- u8 *config;
- int ret;
-
- /* First 4 pins are unused in the controller */
- offset += 4;
-
- config = &ts->port_config[offset >> 2];
-
- mutex_lock(&ts->lock);
-
- *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
-
- ret = __max7301_set(ts, offset, value);
-
- if (!ret)
- ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
-
- mutex_unlock(&ts->lock);
-
- return ret;
-}
-
-static int max7301_get(struct gpio_chip *chip, unsigned offset)
-{
- struct max7301 *ts = container_of(chip, struct max7301, chip);
- int config, level = -EINVAL;
-
- /* First 4 pins are unused in the controller */
- offset += 4;
-
- mutex_lock(&ts->lock);
-
- config = (ts->port_config[offset >> 2] >> ((offset & 3) * 2)) & 3;
-
- switch (config) {
- case 1:
- /* Output: return cached level */
- level = !!(ts->out_level & (1 << offset));
- break;
- case 2:
- case 3:
- /* Input: read out */
- level = max7301_read(ts->spi, 0x20 + offset) & 0x01;
- }
- mutex_unlock(&ts->lock);
-
- return level;
-}
-
-static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- struct max7301 *ts = container_of(chip, struct max7301, chip);
-
- /* First 4 pins are unused in the controller */
- offset += 4;
-
- mutex_lock(&ts->lock);
-
- __max7301_set(ts, offset, value);
-
- mutex_unlock(&ts->lock);
-}
-
static int __devinit max7301_probe(struct spi_device *spi)
{
struct max7301 *ts;
- struct max7301_platform_data *pdata;
- int i, ret;
-
- pdata = spi->dev.platform_data;
- if (!pdata || !pdata->base) {
- dev_dbg(&spi->dev, "incorrect or missing platform data\n");
- return -EINVAL;
- }
+ int ret;
- /*
- * bits_per_word cannot be configured in platform data
- */
+ /* bits_per_word cannot be configured in platform data */
spi->bits_per_word = 16;
-
ret = spi_setup(spi);
if (ret < 0)
return ret;
@@ -235,90 +67,35 @@ static int __devinit max7301_probe(struct spi_device *spi)
if (!ts)
return -ENOMEM;
- mutex_init(&ts->lock);
-
- dev_set_drvdata(&spi->dev, ts);
+ ts->read = max7301_spi_read;
+ ts->write = max7301_spi_write;
+ ts->dev = &spi->dev;
- /* Power up the chip and disable IRQ output */
- max7301_write(spi, 0x04, 0x01);
-
- ts->spi = spi;
-
- ts->chip.label = DRIVER_NAME,
-
- ts->chip.direction_input = max7301_direction_input;
- ts->chip.get = max7301_get;
- ts->chip.direction_output = max7301_direction_output;
- ts->chip.set = max7301_set;
-
- ts->chip.base = pdata->base;
- ts->chip.ngpio = PIN_NUMBER;
- ts->chip.can_sleep = 1;
- ts->chip.dev = &spi->dev;
- ts->chip.owner = THIS_MODULE;
-
- /*
- * tristate all pins in hardware and cache the
- * register values for later use.
- */
- for (i = 1; i < 8; i++) {
- int j;
- /* 0xAA means input with internal pullup disabled */
- max7301_write(spi, 0x08 + i, 0xAA);
- ts->port_config[i] = 0xAA;
- for (j = 0; j < 4; j++) {
- int offset = (i - 1) * 4 + j;
- ret = max7301_direction_input(&ts->chip, offset);
- if (ret)
- goto exit_destroy;
- }
- }
-
- ret = gpiochip_add(&ts->chip);
+ ret = __max730x_probe(ts);
if (ret)
- goto exit_destroy;
-
- return ret;
-
-exit_destroy:
- dev_set_drvdata(&spi->dev, NULL);
- mutex_destroy(&ts->lock);
- kfree(ts);
+ kfree(ts);
return ret;
}
static int __devexit max7301_remove(struct spi_device *spi)
{
- struct max7301 *ts;
- int ret;
-
- ts = dev_get_drvdata(&spi->dev);
- if (ts == NULL)
- return -ENODEV;
-
- dev_set_drvdata(&spi->dev, NULL);
-
- /* Power down the chip and disable IRQ output */
- max7301_write(spi, 0x04, 0x00);
-
- ret = gpiochip_remove(&ts->chip);
- if (!ret) {
- mutex_destroy(&ts->lock);
- kfree(ts);
- } else
- dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
- ret);
-
- return ret;
+ return __max730x_remove(&spi->dev);
}
+static const struct spi_device_id max7301_id[] = {
+ { "max7301", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, max7301_id);
+
static struct spi_driver max7301_driver = {
.driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
+ .name = "max7301",
+ .owner = THIS_MODULE,
},
- .probe = max7301_probe,
- .remove = __devexit_p(max7301_remove),
+ .probe = max7301_probe,
+ .remove = __devexit_p(max7301_remove),
+ .id_table = max7301_id,
};
static int __init max7301_init(void)
@@ -336,7 +113,6 @@ static void __exit max7301_exit(void)
}
module_exit(max7301_exit);
-MODULE_AUTHOR("Juergen Beisert");
+MODULE_AUTHOR("Juergen Beisert, Wolfram Sang");
MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander");
-MODULE_ALIAS("spi:" DRIVER_NAME);
+MODULE_DESCRIPTION("MAX7301 GPIO-Expander");
diff --git a/drivers/gpio/max730x.c b/drivers/gpio/max730x.c
new file mode 100644
index 00000000000..7696a5625d5
--- /dev/null
+++ b/drivers/gpio/max730x.c
@@ -0,0 +1,249 @@
+/**
+ * drivers/gpio/max7301.c
+ *
+ * Copyright (C) 2006 Juergen Beisert, Pengutronix
+ * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The Maxim MAX7300/1 device is an I2C/SPI driven GPIO expander. There are
+ * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
+ * details
+ * Note:
+ * - DIN must be stable at the rising edge of clock.
+ * - when writing:
+ * - always clock in 16 clocks at once
+ * - at DIN: D15 first, D0 last
+ * - D0..D7 = databyte, D8..D14 = commandbyte
+ * - D15 = low -> write command
+ * - when reading
+ * - always clock in 16 clocks at once
+ * - at DIN: D15 first, D0 last
+ * - D0..D7 = dummy, D8..D14 = register address
+ * - D15 = high -> read command
+ * - raise CS and assert it again
+ * - always clock in 16 clocks at once
+ * - at DOUT: D15 first, D0 last
+ * - D0..D7 contains the data from the first cycle
+ *
+ * The driver exports a standard gpiochip interface
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/spi/max7301.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+/*
+ * Pin configurations, see MAX7301 datasheet page 6
+ */
+#define PIN_CONFIG_MASK 0x03
+#define PIN_CONFIG_IN_PULLUP 0x03
+#define PIN_CONFIG_IN_WO_PULLUP 0x02
+#define PIN_CONFIG_OUT 0x01
+
+#define PIN_NUMBER 28
+
+static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+ u8 *config;
+ u8 offset_bits;
+ int ret;
+
+ /* First 4 pins are unused in the controller */
+ offset += 4;
+ offset_bits = (offset & 3) << 1;
+
+ config = &ts->port_config[offset >> 2];
+
+ mutex_lock(&ts->lock);
+
+ /* Standard GPIO API doesn't support pull-ups, has to be extended.
+ * Hard-coding no pollup for now. */
+ *config = (*config & ~(PIN_CONFIG_MASK << offset_bits))
+ | (PIN_CONFIG_IN_WO_PULLUP << offset_bits);
+
+ ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config);
+
+ mutex_unlock(&ts->lock);
+
+ return ret;
+}
+
+static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
+{
+ if (value) {
+ ts->out_level |= 1 << offset;
+ return ts->write(ts->dev, 0x20 + offset, 0x01);
+ } else {
+ ts->out_level &= ~(1 << offset);
+ return ts->write(ts->dev, 0x20 + offset, 0x00);
+ }
+}
+
+static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+ u8 *config;
+ u8 offset_bits;
+ int ret;
+
+ /* First 4 pins are unused in the controller */
+ offset += 4;
+ offset_bits = (offset & 3) << 1;
+
+ config = &ts->port_config[offset >> 2];
+
+ mutex_lock(&ts->lock);
+
+ *config = (*config & ~(PIN_CONFIG_MASK << offset_bits))
+ | (PIN_CONFIG_OUT << offset_bits);
+
+ ret = __max7301_set(ts, offset, value);
+
+ if (!ret)
+ ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config);
+
+ mutex_unlock(&ts->lock);
+
+ return ret;
+}
+
+static int max7301_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+ int config, level = -EINVAL;
+
+ /* First 4 pins are unused in the controller */
+ offset += 4;
+
+ mutex_lock(&ts->lock);
+
+ config = (ts->port_config[offset >> 2] >> ((offset & 3) << 1))
+ & PIN_CONFIG_MASK;
+
+ switch (config) {
+ case PIN_CONFIG_OUT:
+ /* Output: return cached level */
+ level = !!(ts->out_level & (1 << offset));
+ break;
+ case PIN_CONFIG_IN_WO_PULLUP:
+ case PIN_CONFIG_IN_PULLUP:
+ /* Input: read out */
+ level = ts->read(ts->dev, 0x20 + offset) & 0x01;
+ }
+ mutex_unlock(&ts->lock);
+
+ return level;
+}
+
+static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct max7301 *ts = container_of(chip, struct max7301, chip);
+
+ /* First 4 pins are unused in the controller */
+ offset += 4;
+
+ mutex_lock(&ts->lock);
+
+ __max7301_set(ts, offset, value);
+
+ mutex_unlock(&ts->lock);
+}
+
+int __devinit __max730x_probe(struct max7301 *ts)
+{
+ struct device *dev = ts->dev;
+ struct max7301_platform_data *pdata;
+ int i, ret;
+
+ pdata = dev->platform_data;
+ if (!pdata || !pdata->base) {
+ dev_err(dev, "incorrect or missing platform data\n");
+ return -EINVAL;
+ }
+
+ mutex_init(&ts->lock);
+ dev_set_drvdata(dev, ts);
+
+ /* Power up the chip and disable IRQ output */
+ ts->write(dev, 0x04, 0x01);
+
+ ts->chip.label = dev->driver->name;
+
+ ts->chip.direction_input = max7301_direction_input;
+ ts->chip.get = max7301_get;
+ ts->chip.direction_output = max7301_direction_output;
+ ts->chip.set = max7301_set;
+
+ ts->chip.base = pdata->base;
+ ts->chip.ngpio = PIN_NUMBER;
+ ts->chip.can_sleep = 1;
+ ts->chip.dev = dev;
+ ts->chip.owner = THIS_MODULE;
+
+ /*
+ * tristate all pins in hardware and cache the
+ * register values for later use.
+ */
+ for (i = 1; i < 8; i++) {
+ int j;
+ /* 0xAA means input with internal pullup disabled */
+ ts->write(dev, 0x08 + i, 0xAA);
+ ts->port_config[i] = 0xAA;
+ for (j = 0; j < 4; j++) {
+ int offset = (i - 1) * 4 + j;
+ ret = max7301_direction_input(&ts->chip, offset);
+ if (ret)
+ goto exit_destroy;
+ }
+ }
+
+ ret = gpiochip_add(&ts->chip);
+ if (ret)
+ goto exit_destroy;
+
+ return ret;
+
+exit_destroy:
+ dev_set_drvdata(dev, NULL);
+ mutex_destroy(&ts->lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__max730x_probe);
+
+int __devexit __max730x_remove(struct device *dev)
+{
+ struct max7301 *ts = dev_get_drvdata(dev);
+ int ret;
+
+ if (ts == NULL)
+ return -ENODEV;
+
+ dev_set_drvdata(dev, NULL);
+
+ /* Power down the chip and disable IRQ output */
+ ts->write(dev, 0x04, 0x00);
+
+ ret = gpiochip_remove(&ts->chip);
+ if (!ret) {
+ mutex_destroy(&ts->lock);
+ kfree(ts);
+ } else
+ dev_err(dev, "Failed to remove GPIO controller: %d\n", ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__max730x_remove);
+
+MODULE_AUTHOR("Juergen Beisert, Wolfram Sang");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MAX730x GPIO-Expanders, generic parts");
diff --git a/drivers/gpio/mc33880.c b/drivers/gpio/mc33880.c
index e7d01bd8fdb..935479da670 100644
--- a/drivers/gpio/mc33880.c
+++ b/drivers/gpio/mc33880.c
@@ -25,6 +25,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/mc33880.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#define DRIVER_NAME "mc33880"
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c
index cd651ec8d03..69f6f1955a3 100644
--- a/drivers/gpio/mcp23s08.c
+++ b/drivers/gpio/mcp23s08.c
@@ -9,6 +9,7 @@
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/mcp23s08.h>
+#include <linux/slab.h>
/* Registers are all 8 bits wide.
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index 6a2fb3fbb3d..b827c976dc6 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -14,8 +14,11 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
+#include <linux/slab.h>
#ifdef CONFIG_OF_GPIO
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
@@ -26,23 +29,28 @@
#define PCA953X_INVERT 2
#define PCA953X_DIRECTION 3
+#define PCA953X_GPIOS 0x00FF
+#define PCA953X_INT 0x0100
+
static const struct i2c_device_id pca953x_id[] = {
- { "pca9534", 8, },
- { "pca9535", 16, },
+ { "pca9534", 8 | PCA953X_INT, },
+ { "pca9535", 16 | PCA953X_INT, },
{ "pca9536", 4, },
- { "pca9537", 4, },
- { "pca9538", 8, },
- { "pca9539", 16, },
- { "pca9554", 8, },
- { "pca9555", 16, },
+ { "pca9537", 4 | PCA953X_INT, },
+ { "pca9538", 8 | PCA953X_INT, },
+ { "pca9539", 16 | PCA953X_INT, },
+ { "pca9554", 8 | PCA953X_INT, },
+ { "pca9555", 16 | PCA953X_INT, },
{ "pca9556", 8, },
{ "pca9557", 8, },
{ "max7310", 8, },
- { "max7315", 8, },
- { "pca6107", 8, },
- { "tca6408", 8, },
- { "tca6416", 16, },
+ { "max7312", 16 | PCA953X_INT, },
+ { "max7313", 16 | PCA953X_INT, },
+ { "max7315", 8 | PCA953X_INT, },
+ { "pca6107", 8 | PCA953X_INT, },
+ { "tca6408", 8 | PCA953X_INT, },
+ { "tca6416", 16 | PCA953X_INT, },
/* NYET: { "tca6424", 24, }, */
{ }
};
@@ -53,6 +61,15 @@ struct pca953x_chip {
uint16_t reg_output;
uint16_t reg_direction;
+#ifdef CONFIG_GPIO_PCA953X_IRQ
+ struct mutex irq_lock;
+ uint16_t irq_mask;
+ uint16_t irq_stat;
+ uint16_t irq_trig_raise;
+ uint16_t irq_trig_fall;
+ int irq_base;
+#endif
+
struct i2c_client *client;
struct pca953x_platform_data *dyn_pdata;
struct gpio_chip gpio_chip;
@@ -202,6 +219,222 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
gc->names = chip->names;
}
+#ifdef CONFIG_GPIO_PCA953X_IRQ
+static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
+{
+ struct pca953x_chip *chip;
+
+ chip = container_of(gc, struct pca953x_chip, gpio_chip);
+ return chip->irq_base + off;
+}
+
+static void pca953x_irq_mask(unsigned int irq)
+{
+ struct pca953x_chip *chip = get_irq_chip_data(irq);
+
+ chip->irq_mask &= ~(1 << (irq - chip->irq_base));
+}
+
+static void pca953x_irq_unmask(unsigned int irq)
+{
+ struct pca953x_chip *chip = get_irq_chip_data(irq);
+
+ chip->irq_mask |= 1 << (irq - chip->irq_base);
+}
+
+static void pca953x_irq_bus_lock(unsigned int irq)
+{
+ struct pca953x_chip *chip = get_irq_chip_data(irq);
+
+ mutex_lock(&chip->irq_lock);
+}
+
+static void pca953x_irq_bus_sync_unlock(unsigned int irq)
+{
+ struct pca953x_chip *chip = get_irq_chip_data(irq);
+ uint16_t new_irqs;
+ uint16_t level;
+
+ /* Look for any newly setup interrupt */
+ new_irqs = chip->irq_trig_fall | chip->irq_trig_raise;
+ new_irqs &= ~chip->reg_direction;
+
+ while (new_irqs) {
+ level = __ffs(new_irqs);
+ pca953x_gpio_direction_input(&chip->gpio_chip, level);
+ new_irqs &= ~(1 << level);
+ }
+
+ mutex_unlock(&chip->irq_lock);
+}
+
+static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
+{
+ struct pca953x_chip *chip = get_irq_chip_data(irq);
+ uint16_t level = irq - chip->irq_base;
+ uint16_t mask = 1 << level;
+
+ if (!(type & IRQ_TYPE_EDGE_BOTH)) {
+ dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
+ irq, type);
+ return -EINVAL;
+ }
+
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ chip->irq_trig_fall |= mask;
+ else
+ chip->irq_trig_fall &= ~mask;
+
+ if (type & IRQ_TYPE_EDGE_RISING)
+ chip->irq_trig_raise |= mask;
+ else
+ chip->irq_trig_raise &= ~mask;
+
+ return 0;
+}
+
+static struct irq_chip pca953x_irq_chip = {
+ .name = "pca953x",
+ .mask = pca953x_irq_mask,
+ .unmask = pca953x_irq_unmask,
+ .bus_lock = pca953x_irq_bus_lock,
+ .bus_sync_unlock = pca953x_irq_bus_sync_unlock,
+ .set_type = pca953x_irq_set_type,
+};
+
+static uint16_t pca953x_irq_pending(struct pca953x_chip *chip)
+{
+ uint16_t cur_stat;
+ uint16_t old_stat;
+ uint16_t pending;
+ uint16_t trigger;
+ int ret;
+
+ ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat);
+ if (ret)
+ return 0;
+
+ /* Remove output pins from the equation */
+ cur_stat &= chip->reg_direction;
+
+ old_stat = chip->irq_stat;
+ trigger = (cur_stat ^ old_stat) & chip->irq_mask;
+
+ if (!trigger)
+ return 0;
+
+ chip->irq_stat = cur_stat;
+
+ pending = (old_stat & chip->irq_trig_fall) |
+ (cur_stat & chip->irq_trig_raise);
+ pending &= trigger;
+
+ return pending;
+}
+
+static irqreturn_t pca953x_irq_handler(int irq, void *devid)
+{
+ struct pca953x_chip *chip = devid;
+ uint16_t pending;
+ uint16_t level;
+
+ pending = pca953x_irq_pending(chip);
+
+ if (!pending)
+ return IRQ_HANDLED;
+
+ do {
+ level = __ffs(pending);
+ handle_nested_irq(level + chip->irq_base);
+
+ pending &= ~(1 << level);
+ } while (pending);
+
+ return IRQ_HANDLED;
+}
+
+static int pca953x_irq_setup(struct pca953x_chip *chip,
+ const struct i2c_device_id *id)
+{
+ struct i2c_client *client = chip->client;
+ struct pca953x_platform_data *pdata = client->dev.platform_data;
+ int ret;
+
+ if (pdata->irq_base && (id->driver_data & PCA953X_INT)) {
+ int lvl;
+
+ ret = pca953x_read_reg(chip, PCA953X_INPUT,
+ &chip->irq_stat);
+ if (ret)
+ goto out_failed;
+
+ /*
+ * There is no way to know which GPIO line generated the
+ * interrupt. We have to rely on the previous read for
+ * this purpose.
+ */
+ chip->irq_stat &= chip->reg_direction;
+ chip->irq_base = pdata->irq_base;
+ mutex_init(&chip->irq_lock);
+
+ for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
+ int irq = lvl + chip->irq_base;
+
+ set_irq_chip_data(irq, chip);
+ set_irq_chip_and_handler(irq, &pca953x_irq_chip,
+ handle_edge_irq);
+ set_irq_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID);
+#else
+ set_irq_noprobe(irq);
+#endif
+ }
+
+ ret = request_threaded_irq(client->irq,
+ NULL,
+ pca953x_irq_handler,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ dev_name(&client->dev), chip);
+ if (ret) {
+ dev_err(&client->dev, "failed to request irq %d\n",
+ client->irq);
+ goto out_failed;
+ }
+
+ chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
+ }
+
+ return 0;
+
+out_failed:
+ chip->irq_base = 0;
+ return ret;
+}
+
+static void pca953x_irq_teardown(struct pca953x_chip *chip)
+{
+ if (chip->irq_base)
+ free_irq(chip->client->irq, chip);
+}
+#else /* CONFIG_GPIO_PCA953X_IRQ */
+static int pca953x_irq_setup(struct pca953x_chip *chip,
+ const struct i2c_device_id *id)
+{
+ struct i2c_client *client = chip->client;
+ struct pca953x_platform_data *pdata = client->dev.platform_data;
+
+ if (pdata->irq_base && (id->driver_data & PCA953X_INT))
+ dev_warn(&client->dev, "interrupt support not compiled in\n");
+
+ return 0;
+}
+
+static void pca953x_irq_teardown(struct pca953x_chip *chip)
+{
+}
+#endif
+
/*
* Handlers for alternative sources of platform_data
*/
@@ -286,7 +519,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
/* initialize cached registers from their original values.
* we can't share this chip with another i2c master.
*/
- pca953x_setup_gpio(chip, id->driver_data);
+ pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS);
ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
if (ret)
@@ -301,6 +534,9 @@ static int __devinit pca953x_probe(struct i2c_client *client,
if (ret)
goto out_failed;
+ ret = pca953x_irq_setup(chip, id);
+ if (ret)
+ goto out_failed;
ret = gpiochip_add(&chip->gpio_chip);
if (ret)
@@ -317,6 +553,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
return 0;
out_failed:
+ pca953x_irq_teardown(chip);
kfree(chip->dyn_pdata);
kfree(chip);
return ret;
@@ -345,6 +582,7 @@ static int pca953x_remove(struct i2c_client *client)
return ret;
}
+ pca953x_irq_teardown(chip);
kfree(chip->dyn_pdata);
kfree(chip);
return 0;
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c
index 4ee4c8367a3..105701a1f05 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -24,6 +24,7 @@
#include <linux/device.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl061.h>
+#include <linux/slab.h>
#define GPIODIR 0x400
#define GPIOIS 0x404
@@ -90,6 +91,12 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
gpiodir = readb(chip->base + GPIODIR);
gpiodir |= 1 << offset;
writeb(gpiodir, chip->base + GPIODIR);
+
+ /*
+ * gpio value is set again, because pl061 doesn't allow to set value of
+ * a gpio pin before configuring it in OUT mode.
+ */
+ writeb(!!value << offset, chip->base + (1 << (offset + 2)));
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -182,7 +189,7 @@ static int pl061_irq_type(unsigned irq, unsigned trigger)
gpioibe &= ~(1 << offset);
if (trigger & IRQ_TYPE_EDGE_RISING)
gpioiev |= 1 << offset;
- else
+ else if (trigger & IRQ_TYPE_EDGE_FALLING)
gpioiev &= ~(1 << offset);
}
writeb(gpioibe, chip->base + GPIOIBE);
@@ -203,7 +210,7 @@ static struct irq_chip pl061_irqchip = {
static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct list_head *chip_list = get_irq_chip_data(irq);
+ struct list_head *chip_list = get_irq_data(irq);
struct list_head *ptr;
struct pl061_gpio *chip;
@@ -219,7 +226,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
if (pending == 0)
continue;
- for_each_bit(offset, &pending, PL061_GPIO_NR)
+ for_each_set_bit(offset, &pending, PL061_GPIO_NR)
generic_handle_irq(pl061_to_irq(&chip->gc, offset));
}
desc->chip->unmask(irq);
@@ -296,9 +303,9 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id)
goto iounmap;
}
INIT_LIST_HEAD(chip_list);
- set_irq_chip_data(irq, chip_list);
+ set_irq_data(irq, chip_list);
} else
- chip_list = get_irq_chip_data(irq);
+ chip_list = get_irq_data(irq);
list_add(&chip->list, chip_list);
for (i = 0; i < PL061_GPIO_NR; i++) {
diff --git a/drivers/gpio/sch_gpio.c b/drivers/gpio/sch_gpio.c
new file mode 100644
index 00000000000..583521352c1
--- /dev/null
+++ b/drivers/gpio/sch_gpio.c
@@ -0,0 +1,295 @@
+/*
+ * sch_gpio.c - GPIO interface for Intel Poulsbo SCH
+ *
+ * Copyright (c) 2010 CompuLab Ltd
+ * Author: Denis Turischev <denis@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/platform_device.h>
+
+#include <linux/gpio.h>
+
+static DEFINE_SPINLOCK(gpio_lock);
+
+#define CGEN (0x00)
+#define CGIO (0x04)
+#define CGLV (0x08)
+
+#define RGEN (0x20)
+#define RGIO (0x24)
+#define RGLV (0x28)
+
+static unsigned short gpio_ba;
+
+static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned gpio_num)
+{
+ u8 curr_dirs;
+ unsigned short offset, bit;
+
+ spin_lock(&gpio_lock);
+
+ offset = CGIO + gpio_num / 8;
+ bit = gpio_num % 8;
+
+ curr_dirs = inb(gpio_ba + offset);
+
+ if (!(curr_dirs & (1 << bit)))
+ outb(curr_dirs | (1 << bit), gpio_ba + offset);
+
+ spin_unlock(&gpio_lock);
+ return 0;
+}
+
+static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num)
+{
+ int res;
+ unsigned short offset, bit;
+
+ offset = CGLV + gpio_num / 8;
+ bit = gpio_num % 8;
+
+ res = !!(inb(gpio_ba + offset) & (1 << bit));
+ return res;
+}
+
+static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val)
+{
+ u8 curr_vals;
+ unsigned short offset, bit;
+
+ spin_lock(&gpio_lock);
+
+ offset = CGLV + gpio_num / 8;
+ bit = gpio_num % 8;
+
+ curr_vals = inb(gpio_ba + offset);
+
+ if (val)
+ outb(curr_vals | (1 << bit), gpio_ba + offset);
+ else
+ outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
+ spin_unlock(&gpio_lock);
+}
+
+static int sch_gpio_core_direction_out(struct gpio_chip *gc,
+ unsigned gpio_num, int val)
+{
+ u8 curr_dirs;
+ unsigned short offset, bit;
+
+ sch_gpio_core_set(gc, gpio_num, val);
+
+ spin_lock(&gpio_lock);
+
+ offset = CGIO + gpio_num / 8;
+ bit = gpio_num % 8;
+
+ curr_dirs = inb(gpio_ba + offset);
+ if (curr_dirs & (1 << bit))
+ outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
+
+ spin_unlock(&gpio_lock);
+ return 0;
+}
+
+static struct gpio_chip sch_gpio_core = {
+ .label = "sch_gpio_core",
+ .owner = THIS_MODULE,
+ .direction_input = sch_gpio_core_direction_in,
+ .get = sch_gpio_core_get,
+ .direction_output = sch_gpio_core_direction_out,
+ .set = sch_gpio_core_set,
+};
+
+static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
+ unsigned gpio_num)
+{
+ u8 curr_dirs;
+
+ spin_lock(&gpio_lock);
+
+ curr_dirs = inb(gpio_ba + RGIO);
+
+ if (!(curr_dirs & (1 << gpio_num)))
+ outb(curr_dirs | (1 << gpio_num) , gpio_ba + RGIO);
+
+ spin_unlock(&gpio_lock);
+ return 0;
+}
+
+static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num)
+{
+ return !!(inb(gpio_ba + RGLV) & (1 << gpio_num));
+}
+
+static void sch_gpio_resume_set(struct gpio_chip *gc,
+ unsigned gpio_num, int val)
+{
+ u8 curr_vals;
+
+ spin_lock(&gpio_lock);
+
+ curr_vals = inb(gpio_ba + RGLV);
+
+ if (val)
+ outb(curr_vals | (1 << gpio_num), gpio_ba + RGLV);
+ else
+ outb((curr_vals & ~(1 << gpio_num)), gpio_ba + RGLV);
+
+ spin_unlock(&gpio_lock);
+}
+
+static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
+ unsigned gpio_num, int val)
+{
+ u8 curr_dirs;
+
+ sch_gpio_resume_set(gc, gpio_num, val);
+
+ spin_lock(&gpio_lock);
+
+ curr_dirs = inb(gpio_ba + RGIO);
+ if (curr_dirs & (1 << gpio_num))
+ outb(curr_dirs & ~(1 << gpio_num), gpio_ba + RGIO);
+
+ spin_unlock(&gpio_lock);
+ return 0;
+}
+
+static struct gpio_chip sch_gpio_resume = {
+ .label = "sch_gpio_resume",
+ .owner = THIS_MODULE,
+ .direction_input = sch_gpio_resume_direction_in,
+ .get = sch_gpio_resume_get,
+ .direction_output = sch_gpio_resume_direction_out,
+ .set = sch_gpio_resume_set,
+};
+
+static int __devinit sch_gpio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ int err;
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!res)
+ return -EBUSY;
+
+ if (!request_region(res->start, resource_size(res), pdev->name))
+ return -EBUSY;
+
+ gpio_ba = res->start;
+
+ sch_gpio_core.base = 0;
+ sch_gpio_core.ngpio = 10;
+ sch_gpio_core.dev = &pdev->dev;
+
+ sch_gpio_resume.base = 10;
+ sch_gpio_resume.ngpio = 4;
+ sch_gpio_resume.dev = &pdev->dev;
+
+ err = gpiochip_add(&sch_gpio_core);
+ if (err < 0)
+ goto err_sch_gpio_core;
+
+ err = gpiochip_add(&sch_gpio_resume);
+ if (err < 0)
+ goto err_sch_gpio_resume;
+
+ /*
+ * GPIO[6:0] enabled by default
+ * GPIO7 is configured by the CMC as SLPIOVR
+ * Enable GPIO[9:8] core powered gpios explicitly
+ */
+ outb(0x3, gpio_ba + CGEN + 1);
+ /*
+ * SUS_GPIO[2:0] enabled by default
+ * Enable SUS_GPIO3 resume powered gpio explicitly
+ */
+ outb(0x8, gpio_ba + RGEN);
+
+ return 0;
+
+err_sch_gpio_resume:
+ err = gpiochip_remove(&sch_gpio_core);
+ if (err)
+ dev_err(&pdev->dev, "%s failed, %d\n",
+ "gpiochip_remove()", err);
+
+err_sch_gpio_core:
+ release_region(res->start, resource_size(res));
+ gpio_ba = 0;
+
+ return err;
+}
+
+static int __devexit sch_gpio_remove(struct platform_device *pdev)
+{
+ struct resource *res;
+ if (gpio_ba) {
+ int err;
+
+ err = gpiochip_remove(&sch_gpio_core);
+ if (err)
+ dev_err(&pdev->dev, "%s failed, %d\n",
+ "gpiochip_remove()", err);
+ err = gpiochip_remove(&sch_gpio_resume);
+ if (err)
+ dev_err(&pdev->dev, "%s failed, %d\n",
+ "gpiochip_remove()", err);
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+
+ release_region(res->start, resource_size(res));
+ gpio_ba = 0;
+
+ return err;
+ }
+
+ return 0;
+}
+
+static struct platform_driver sch_gpio_driver = {
+ .driver = {
+ .name = "sch_gpio",
+ .owner = THIS_MODULE,
+ },
+ .probe = sch_gpio_probe,
+ .remove = __devexit_p(sch_gpio_remove),
+};
+
+static int __init sch_gpio_init(void)
+{
+ return platform_driver_register(&sch_gpio_driver);
+}
+
+static void __exit sch_gpio_exit(void)
+{
+ platform_driver_unregister(&sch_gpio_driver);
+}
+
+module_init(sch_gpio_init);
+module_exit(sch_gpio_exit);
+
+MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
+MODULE_DESCRIPTION("GPIO interface for Intel Poulsbo SCH");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sch_gpio");
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index a4d344ba8e5..ddd053108a1 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/timbgpio.c
@@ -23,9 +23,11 @@
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
+#include <linux/irq.h>
#include <linux/io.h>
#include <linux/timb_gpio.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#define DRIVER_NAME "timb-gpio"
@@ -37,6 +39,8 @@
#define TGPIO_ICR 0x14
#define TGPIO_FLR 0x18
#define TGPIO_LVR 0x1c
+#define TGPIO_VER 0x20
+#define TGPIO_BFLR 0x24
struct timbgpio {
void __iomem *membase;
@@ -125,17 +129,24 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
struct timbgpio *tgpio = get_irq_chip_data(irq);
int offset = irq - tgpio->irq_base;
unsigned long flags;
- u32 lvr, flr;
+ u32 lvr, flr, bflr = 0;
+ u32 ver;
+ int ret = 0;
if (offset < 0 || offset > tgpio->gpio.ngpio)
return -EINVAL;
+ ver = ioread32(tgpio->membase + TGPIO_VER);
+
spin_lock_irqsave(&tgpio->lock, flags);
lvr = ioread32(tgpio->membase + TGPIO_LVR);
flr = ioread32(tgpio->membase + TGPIO_FLR);
+ if (ver > 2)
+ bflr = ioread32(tgpio->membase + TGPIO_BFLR);
if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+ bflr &= ~(1 << offset);
flr &= ~(1 << offset);
if (trigger & IRQ_TYPE_LEVEL_HIGH)
lvr |= 1 << offset;
@@ -143,25 +154,34 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
lvr &= ~(1 << offset);
}
- if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
- return -EINVAL;
- else {
+ if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+ if (ver < 3) {
+ ret = -EINVAL;
+ goto out;
+ }
+ else {
+ flr |= 1 << offset;
+ bflr |= 1 << offset;
+ }
+ } else {
+ bflr &= ~(1 << offset);
flr |= 1 << offset;
- /* opposite compared to the datasheet, but it mirrors the
- * reality
- */
if (trigger & IRQ_TYPE_EDGE_FALLING)
- lvr |= 1 << offset;
- else
lvr &= ~(1 << offset);
+ else
+ lvr |= 1 << offset;
}
iowrite32(lvr, tgpio->membase + TGPIO_LVR);
iowrite32(flr, tgpio->membase + TGPIO_FLR);
+ if (ver > 2)
+ iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
+
iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
- spin_unlock_irqrestore(&tgpio->lock, flags);
- return 0;
+out:
+ spin_unlock_irqrestore(&tgpio->lock, flags);
+ return ret;
}
static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
@@ -174,7 +194,7 @@ static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
ipr = ioread32(tgpio->membase + TGPIO_IPR);
iowrite32(ipr, tgpio->membase + TGPIO_ICR);
- for_each_bit(offset, &ipr, tgpio->gpio.ngpio)
+ for_each_set_bit(offset, &ipr, tgpio->gpio.ngpio)
generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset));
}
diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/twl4030-gpio.c
index 7fe881e2bdf..57635ac35a7 100644
--- a/drivers/gpio/twl4030-gpio.c
+++ b/drivers/gpio/twl4030-gpio.c
@@ -32,7 +32,6 @@
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <linux/i2c/twl.h>
diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c
index b4468b61689..1fa449a1a4c 100644
--- a/drivers/gpio/wm831x-gpio.c
+++ b/drivers/gpio/wm831x-gpio.c
@@ -13,6 +13,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/mfd/core.h>
@@ -38,10 +39,14 @@ static int wm831x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
struct wm831x *wm831x = wm831x_gpio->wm831x;
+ int val = WM831X_GPN_DIR;
+
+ if (wm831x->has_gpio_ena)
+ val |= WM831X_GPN_TRI;
return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
- WM831X_GPN_DIR | WM831X_GPN_TRI,
- WM831X_GPN_DIR);
+ WM831X_GPN_DIR | WM831X_GPN_TRI |
+ WM831X_GPN_FN_MASK, val);
}
static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -60,23 +65,36 @@ static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
return 0;
}
-static int wm831x_gpio_direction_out(struct gpio_chip *chip,
- unsigned offset, int value)
+static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
struct wm831x *wm831x = wm831x_gpio->wm831x;
- return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
- WM831X_GPN_DIR | WM831X_GPN_TRI, 0);
+ wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
+ value << offset);
}
-static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+static int wm831x_gpio_direction_out(struct gpio_chip *chip,
+ unsigned offset, int value)
{
struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
struct wm831x *wm831x = wm831x_gpio->wm831x;
+ int val = 0;
+ int ret;
- wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
- value << offset);
+ if (wm831x->has_gpio_ena)
+ val |= WM831X_GPN_TRI;
+
+ ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
+ WM831X_GPN_DIR | WM831X_GPN_TRI |
+ WM831X_GPN_FN_MASK, val);
+ if (ret < 0)
+ return ret;
+
+ /* Can only set GPIO state once it's in output mode */
+ wm831x_gpio_set(chip, offset, value);
+
+ return 0;
}
static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -95,7 +113,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
struct wm831x *wm831x = wm831x_gpio->wm831x;
- int i;
+ int i, tristated;
for (i = 0; i < chip->ngpio; i++) {
int gpio = i + chip->base;
@@ -162,15 +180,19 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
break;
}
+ tristated = reg & WM831X_GPN_TRI;
+ if (wm831x->has_gpio_ena)
+ tristated = !tristated;
+
seq_printf(s, " %s %s %s %s%s\n"
" %s%s (0x%4x)\n",
reg & WM831X_GPN_DIR ? "in" : "out",
wm831x_gpio_get(chip, i) ? "high" : "low",
pull,
powerdomain,
- reg & WM831X_GPN_POL ? " inverted" : "",
+ reg & WM831X_GPN_POL ? "" : " inverted",
reg & WM831X_GPN_OD ? "open-drain" : "CMOS",
- reg & WM831X_GPN_TRI ? " tristated" : "",
+ tristated ? " tristated" : "",
reg);
}
}
diff --git a/drivers/gpio/wm8350-gpiolib.c b/drivers/gpio/wm8350-gpiolib.c
new file mode 100644
index 00000000000..359999290f5
--- /dev/null
+++ b/drivers/gpio/wm8350-gpiolib.c
@@ -0,0 +1,182 @@
+/*
+ * wm835x-gpiolib.c -- gpiolib support for Wolfson WM835x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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/slab.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/gpio.h>
+
+struct wm8350_gpio_data {
+ struct wm8350 *wm8350;
+ struct gpio_chip gpio_chip;
+};
+
+static inline struct wm8350_gpio_data *to_wm8350_gpio(struct gpio_chip *chip)
+{
+ return container_of(chip, struct wm8350_gpio_data, gpio_chip);
+}
+
+static int wm8350_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+ struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+
+ return wm8350_set_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
+ 1 << offset);
+}
+
+static int wm8350_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+ struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+ int ret;
+
+ ret = wm8350_reg_read(wm8350, WM8350_GPIO_LEVEL);
+ if (ret < 0)
+ return ret;
+
+ if (ret & (1 << offset))
+ return 1;
+ else
+ return 0;
+}
+
+static void wm8350_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+ struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+
+ if (value)
+ wm8350_set_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
+ else
+ wm8350_clear_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
+}
+
+static int wm8350_gpio_direction_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+ struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+ int ret;
+
+ ret = wm8350_clear_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
+ 1 << offset);
+ if (ret < 0)
+ return ret;
+
+ /* Don't have an atomic direction/value setup */
+ wm8350_gpio_set(chip, offset, value);
+
+ return 0;
+}
+
+static int wm8350_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
+ struct wm8350 *wm8350 = wm8350_gpio->wm8350;
+
+ if (!wm8350->irq_base)
+ return -EINVAL;
+
+ return wm8350->irq_base + WM8350_IRQ_GPIO(offset);
+}
+
+static struct gpio_chip template_chip = {
+ .label = "wm8350",
+ .owner = THIS_MODULE,
+ .direction_input = wm8350_gpio_direction_in,
+ .get = wm8350_gpio_get,
+ .direction_output = wm8350_gpio_direction_out,
+ .set = wm8350_gpio_set,
+ .to_irq = wm8350_gpio_to_irq,
+ .can_sleep = 1,
+};
+
+static int __devinit wm8350_gpio_probe(struct platform_device *pdev)
+{
+ struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent);
+ struct wm8350_platform_data *pdata = wm8350->dev->platform_data;
+ struct wm8350_gpio_data *wm8350_gpio;
+ int ret;
+
+ wm8350_gpio = kzalloc(sizeof(*wm8350_gpio), GFP_KERNEL);
+ if (wm8350_gpio == NULL)
+ return -ENOMEM;
+
+ wm8350_gpio->wm8350 = wm8350;
+ wm8350_gpio->gpio_chip = template_chip;
+ wm8350_gpio->gpio_chip.ngpio = 13;
+ wm8350_gpio->gpio_chip.dev = &pdev->dev;
+ if (pdata && pdata->gpio_base)
+ wm8350_gpio->gpio_chip.base = pdata->gpio_base;
+ else
+ wm8350_gpio->gpio_chip.base = -1;
+
+ ret = gpiochip_add(&wm8350_gpio->gpio_chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
+ ret);
+ goto err;
+ }
+
+ platform_set_drvdata(pdev, wm8350_gpio);
+
+ return ret;
+
+err:
+ kfree(wm8350_gpio);
+ return ret;
+}
+
+static int __devexit wm8350_gpio_remove(struct platform_device *pdev)
+{
+ struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = gpiochip_remove(&wm8350_gpio->gpio_chip);
+ if (ret == 0)
+ kfree(wm8350_gpio);
+
+ return ret;
+}
+
+static struct platform_driver wm8350_gpio_driver = {
+ .driver.name = "wm8350-gpio",
+ .driver.owner = THIS_MODULE,
+ .probe = wm8350_gpio_probe,
+ .remove = __devexit_p(wm8350_gpio_remove),
+};
+
+static int __init wm8350_gpio_init(void)
+{
+ return platform_driver_register(&wm8350_gpio_driver);
+}
+subsys_initcall(wm8350_gpio_init);
+
+static void __exit wm8350_gpio_exit(void)
+{
+ platform_driver_unregister(&wm8350_gpio_driver);
+}
+module_exit(wm8350_gpio_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("GPIO interface for WM8350 PMICs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8350-gpio");
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c
new file mode 100644
index 00000000000..7607cc61e1d
--- /dev/null
+++ b/drivers/gpio/wm8994-gpio.c
@@ -0,0 +1,205 @@
+/*
+ * wm8994-gpio.c -- gpiolib support for Wolfson WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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/slab.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+
+#include <linux/mfd/wm8994/core.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/wm8994/gpio.h>
+#include <linux/mfd/wm8994/registers.h>
+
+struct wm8994_gpio {
+ struct wm8994 *wm8994;
+ struct gpio_chip gpio_chip;
+};
+
+static inline struct wm8994_gpio *to_wm8994_gpio(struct gpio_chip *chip)
+{
+ return container_of(chip, struct wm8994_gpio, gpio_chip);
+}
+
+static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+ struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+ return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset,
+ WM8994_GPN_DIR, WM8994_GPN_DIR);
+}
+
+static int wm8994_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+ struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+ int ret;
+
+ ret = wm8994_reg_read(wm8994, WM8994_GPIO_1 + offset);
+ if (ret < 0)
+ return ret;
+
+ if (ret & WM8994_GPN_LVL)
+ return 1;
+ else
+ return 0;
+}
+
+static int wm8994_gpio_direction_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+ struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+ return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset,
+ WM8994_GPN_DIR, 0);
+}
+
+static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+ struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+
+ if (value)
+ value = WM8994_GPN_LVL;
+
+ wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_LVL, value);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
+ struct wm8994 *wm8994 = wm8994_gpio->wm8994;
+ int i;
+
+ for (i = 0; i < chip->ngpio; i++) {
+ int gpio = i + chip->base;
+ int reg;
+ const char *label;
+
+ /* We report the GPIO even if it's not requested since
+ * we're also reporting things like alternate
+ * functions which apply even when the GPIO is not in
+ * use as a GPIO.
+ */
+ label = gpiochip_is_requested(chip, i);
+ if (!label)
+ label = "Unrequested";
+
+ seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label);
+
+ reg = wm8994_reg_read(wm8994, WM8994_GPIO_1 + i);
+ if (reg < 0) {
+ dev_err(wm8994->dev,
+ "GPIO control %d read failed: %d\n",
+ gpio, reg);
+ seq_printf(s, "\n");
+ continue;
+ }
+
+ /* No decode yet; note that GPIO2 is special */
+ seq_printf(s, "(%x)\n", reg);
+ }
+}
+#else
+#define wm8994_gpio_dbg_show NULL
+#endif
+
+static struct gpio_chip template_chip = {
+ .label = "wm8994",
+ .owner = THIS_MODULE,
+ .direction_input = wm8994_gpio_direction_in,
+ .get = wm8994_gpio_get,
+ .direction_output = wm8994_gpio_direction_out,
+ .set = wm8994_gpio_set,
+ .dbg_show = wm8994_gpio_dbg_show,
+ .can_sleep = 1,
+};
+
+static int __devinit wm8994_gpio_probe(struct platform_device *pdev)
+{
+ struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
+ struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+ struct wm8994_gpio *wm8994_gpio;
+ int ret;
+
+ wm8994_gpio = kzalloc(sizeof(*wm8994_gpio), GFP_KERNEL);
+ if (wm8994_gpio == NULL)
+ return -ENOMEM;
+
+ wm8994_gpio->wm8994 = wm8994;
+ wm8994_gpio->gpio_chip = template_chip;
+ wm8994_gpio->gpio_chip.ngpio = WM8994_GPIO_MAX;
+ wm8994_gpio->gpio_chip.dev = &pdev->dev;
+ if (pdata && pdata->gpio_base)
+ wm8994_gpio->gpio_chip.base = pdata->gpio_base;
+ else
+ wm8994_gpio->gpio_chip.base = -1;
+
+ ret = gpiochip_add(&wm8994_gpio->gpio_chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
+ ret);
+ goto err;
+ }
+
+ platform_set_drvdata(pdev, wm8994_gpio);
+
+ return ret;
+
+err:
+ kfree(wm8994_gpio);
+ return ret;
+}
+
+static int __devexit wm8994_gpio_remove(struct platform_device *pdev)
+{
+ struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = gpiochip_remove(&wm8994_gpio->gpio_chip);
+ if (ret == 0)
+ kfree(wm8994_gpio);
+
+ return ret;
+}
+
+static struct platform_driver wm8994_gpio_driver = {
+ .driver.name = "wm8994-gpio",
+ .driver.owner = THIS_MODULE,
+ .probe = wm8994_gpio_probe,
+ .remove = __devexit_p(wm8994_gpio_remove),
+};
+
+static int __init wm8994_gpio_init(void)
+{
+ return platform_driver_register(&wm8994_gpio_driver);
+}
+subsys_initcall(wm8994_gpio_init);
+
+static void __exit wm8994_gpio_exit(void)
+{
+ platform_driver_unregister(&wm8994_gpio_driver);
+}
+module_exit(wm8994_gpio_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("GPIO interface for WM8994");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8994-gpio");
diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c
index 3c1177abebd..b8fa65b5bfc 100644
--- a/drivers/gpio/xilinx_gpio.c
+++ b/drivers/gpio/xilinx_gpio.c
@@ -19,6 +19,7 @@
#include <linux/of_gpio.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
/* Register Offset Definitions */
#define XGPIO_DATA_OFFSET (0x0) /* Data register */
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
index d68888fe3df..ba38e014722 100644
--- a/drivers/gpu/drm/drm_agpsupport.c
+++ b/drivers/gpu/drm/drm_agpsupport.c
@@ -33,6 +33,7 @@
#include "drmP.h"
#include <linux/module.h>
+#include <linux/slab.h>
#if __OS_HAS_AGP
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 8417cc4c43f..f7ba82ebf65 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -34,6 +34,7 @@
*/
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/log2.h>
#include <asm/shmparam.h>
#include "drmP.h"
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d91fb8c0b7b..61b9bcfdf04 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -30,6 +30,7 @@
* Jesse Barnes <jesse.barnes@intel.com>
*/
#include <linux/list.h>
+#include <linux/slab.h>
#include "drm.h"
#include "drmP.h"
#include "drm_crtc.h"
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index f2aaf39be39..51103aa469f 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
if (connector->status == connector_status_disconnected) {
DRM_DEBUG_KMS("%s is disconnected\n",
drm_get_connector_name(connector));
+ drm_mode_connector_update_edid_property(connector, NULL);
goto prune;
}
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 9903f270e44..677b275fa72 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -32,6 +32,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "drmP.h"
#if defined(CONFIG_DEBUG_FS)
diff --git a/drivers/gpu/drm/drm_dp_i2c_helper.c b/drivers/gpu/drm/drm_dp_i2c_helper.c
index 548887c8506..f7eba0a0973 100644
--- a/drivers/gpu/drm/drm_dp_i2c_helper.c
+++ b/drivers/gpu/drm/drm_dp_i2c_helper.c
@@ -23,7 +23,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index f3c58e2bd75..4a66201edae 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -47,6 +47,7 @@
*/
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm_core.h"
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f97e7c42ac8..18f41d7061f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -27,6 +27,7 @@
* DEALINGS IN THE SOFTWARE.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include "drmP.h"
@@ -84,6 +85,8 @@ static struct edid_quirk {
/* Envision Peripherals, Inc. EN-7100e */
{ "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
+ /* Envision EN2028 */
+ { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
/* Funai Electronics PM36B */
{ "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
@@ -707,15 +710,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
mode->vsync_end = mode->vsync_start + vsync_pulse_width;
mode->vtotal = mode->vdisplay + vblank;
- /* perform the basic check for the detailed timing */
- if (mode->hsync_end > mode->htotal ||
- mode->vsync_end > mode->vtotal) {
- drm_mode_destroy(dev, mode);
- DRM_DEBUG_KMS("Incorrect detailed timing. "
- "Sync is beyond the blank.\n");
- return NULL;
- }
-
/* Some EDIDs have bogus h/vtotal values */
if (mode->hsync_end > mode->htotal)
mode->htotal = mode->hsync_end + 1;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 50549703584..288ea2f3277 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -29,6 +29,7 @@
*/
#include <linux/kernel.h>
#include <linux/sysrq.h>
+#include <linux/slab.h>
#include <linux/fb.h>
#include "drmP.h"
#include "drm_crtc.h"
@@ -283,6 +284,8 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
.help_msg = "force-fb(V)",
.action_msg = "Restore framebuffer console",
};
+#else
+static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
#endif
static void drm_fb_helper_on(struct fb_info *info)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 08d14df3bb4..9d532d7fdf5 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -36,6 +36,7 @@
#include "drmP.h"
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
static int drm_open_helper(struct inode *inode, struct file *filp,
@@ -140,14 +141,16 @@ int drm_open(struct inode *inode, struct file *filp)
spin_unlock(&dev->count_lock);
}
out:
- mutex_lock(&dev->struct_mutex);
- if (minor->type == DRM_MINOR_LEGACY) {
- BUG_ON((dev->dev_mapping != NULL) &&
- (dev->dev_mapping != inode->i_mapping));
- if (dev->dev_mapping == NULL)
- dev->dev_mapping = inode->i_mapping;
+ if (!retcode) {
+ mutex_lock(&dev->struct_mutex);
+ if (minor->type == DRM_MINOR_LEGACY) {
+ if (dev->dev_mapping == NULL)
+ dev->dev_mapping = inode->i_mapping;
+ else if (dev->dev_mapping != inode->i_mapping)
+ retcode = -ENODEV;
+ }
+ mutex_unlock(&dev->struct_mutex);
}
- mutex_unlock(&dev->struct_mutex);
return retcode;
}
diff --git a/drivers/gpu/drm/drm_hashtab.c b/drivers/gpu/drm/drm_hashtab.c
index f36b21c5b2e..a93d7b4ddaa 100644
--- a/drivers/gpu/drm/drm_hashtab.c
+++ b/drivers/gpu/drm/drm_hashtab.c
@@ -35,6 +35,7 @@
#include "drmP.h"
#include "drm_hashtab.h"
#include <linux/hash.h>
+#include <linux/slab.h>
int drm_ht_create(struct drm_open_hash *ht, unsigned int order)
{
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index b98384dbd9a..a263b7070fc 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -36,6 +36,7 @@
#include "drmP.h"
#include <linux/interrupt.h> /* For task queue support */
+#include <linux/slab.h>
#include <linux/vgaarb.h>
/**
@@ -475,6 +476,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
unsigned long irqflags;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ dev->driver->disable_vblank(dev, crtc);
DRM_WAKEUP(&dev->vbl_queue[crtc]);
dev->vblank_enabled[crtc] = 0;
dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index e68ebf92fa2..2ea9ad4a8d6 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -37,6 +37,7 @@
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include "drmP.h"
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index d379c4f2892..a9ba6b69ad3 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -38,6 +38,7 @@
*/
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "drmP.h"
/***************************************************
diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c
index c7823c863d4..9034c4c6100 100644
--- a/drivers/gpu/drm/drm_scatter.c
+++ b/drivers/gpu/drm/drm_scatter.c
@@ -32,6 +32,7 @@
*/
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include "drmP.h"
#define DEBUG_SCATTER 0
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index ad73e141afd..a0c365f2e52 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm_core.h"
@@ -515,8 +516,6 @@ void drm_put_dev(struct drm_device *dev)
}
driver = dev->driver;
- drm_vblank_cleanup(dev);
-
drm_lastclose(dev);
if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
@@ -536,6 +535,8 @@ void drm_put_dev(struct drm_device *dev)
dev->agp = NULL;
}
+ drm_vblank_cleanup(dev);
+
list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
drm_rmmap(dev, r_list->map);
drm_ht_remove(&dev->map_hash);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 7e42b7e9d43..1a1825b29f5 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -14,6 +14,7 @@
#include <linux/device.h>
#include <linux/kdev_t.h>
+#include <linux/gfp.h>
#include <linux/err.h>
#include "drm_sysfs.h"
@@ -70,19 +71,17 @@ static int drm_class_resume(struct device *dev)
return 0;
}
-/* Display the version of drm_core. This doesn't work right in current design */
-static ssize_t version_show(struct class *dev, char *buf)
-{
- return sprintf(buf, "%s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR,
- CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
-}
-
static char *drm_devnode(struct device *dev, mode_t *mode)
{
return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
}
-static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+static CLASS_ATTR_STRING(version, S_IRUGO,
+ CORE_NAME " "
+ __stringify(CORE_MAJOR) "."
+ __stringify(CORE_MINOR) "."
+ __stringify(CORE_PATCHLEVEL) " "
+ CORE_DATE);
/**
* drm_sysfs_create - create a struct drm_sysfs_class structure
@@ -109,7 +108,7 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
class->suspend = drm_class_suspend;
class->resume = drm_class_resume;
- err = class_create_file(class, &class_attr_version);
+ err = class_create_file(class, &class_attr_version.attr);
if (err)
goto err_out_class;
@@ -132,7 +131,7 @@ void drm_sysfs_destroy(void)
{
if ((drm_class == NULL) || (IS_ERR(drm_class)))
return;
- class_remove_file(drm_class, &class_attr_version);
+ class_remove_file(drm_class, &class_attr_version.attr);
class_destroy(drm_class);
}
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 4ac900f4647..c3b13fb41d0 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -36,6 +36,7 @@
#include "drmP.h"
#if defined(__ia64__)
#include <linux/efi.h>
+#include <linux/slab.h>
#endif
static void drm_vm_open(struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index de32d22a8c3..997d91707ad 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -36,6 +36,7 @@
#include "i810_drv.h"
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
#define I810_BUF_FREE 2
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c
index 06bd732e646..65759a9a85c 100644
--- a/drivers/gpu/drm/i830/i830_dma.c
+++ b/drivers/gpu/drm/i830/i830_dma.c
@@ -38,6 +38,7 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/pagemap.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#define I830_BUF_FREE 2
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 1376dfe44c9..a0b8447b06e 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -28,6 +28,7 @@
#include <linux/seq_file.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
@@ -225,7 +226,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
} else {
struct drm_i915_gem_object *obj_priv;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
seq_printf(m, "Fenced object[%2d] = %p: %s "
"%08x %08zx %08x %s %08x %08x %d",
i, obj, get_pin_flag(obj_priv),
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 8bfc0bbf13e..c3cfafcbfe7 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -38,6 +38,7 @@
#include <linux/acpi.h>
#include <linux/pnp.h>
#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
/* Really want an OS-independent resettable timer. Would like to have
* this loop run for (eg) 3 sec, but have the timer reset every time
@@ -1356,6 +1357,8 @@ static void i915_setup_compression(struct drm_device *dev, int size)
dev_priv->cfb_size = size;
+ dev_priv->compressed_fb = compressed_fb;
+
if (IS_GM45(dev)) {
g4x_disable_fbc(dev);
I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
@@ -1363,12 +1366,22 @@ static void i915_setup_compression(struct drm_device *dev, int size)
i8xx_disable_fbc(dev);
I915_WRITE(FBC_CFB_BASE, cfb_base);
I915_WRITE(FBC_LL_BASE, ll_base);
+ dev_priv->compressed_llb = compressed_llb;
}
DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
ll_base, size >> 20);
}
+static void i915_cleanup_compression(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ drm_mm_put_block(dev_priv->compressed_fb);
+ if (!IS_GM45(dev))
+ drm_mm_put_block(dev_priv->compressed_llb);
+}
+
/* true = enable decode, false = disable decoder */
static unsigned int i915_vga_set_decode(void *cookie, bool state)
{
@@ -1786,6 +1799,8 @@ int i915_driver_unload(struct drm_device *dev)
mutex_lock(&dev->struct_mutex);
i915_gem_cleanup_ringbuffer(dev);
mutex_unlock(&dev->struct_mutex);
+ if (I915_HAS_FBC(dev) && i915_powersave)
+ i915_cleanup_compression(dev);
drm_mm_takedown(&dev_priv->vram);
i915_gem_lastclose(dev);
@@ -1881,29 +1896,29 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
- DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0),
- DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW),
- DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW),
+ DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 1b2e95455c0..cc03537bb88 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -69,7 +69,8 @@ const static struct intel_device_info intel_845g_info = {
};
const static struct intel_device_info intel_i85x_info = {
- .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
+ .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
+ .cursor_needs_physical = 1,
};
const static struct intel_device_info intel_i865g_info = {
@@ -80,14 +81,14 @@ const static struct intel_device_info intel_i915g_info = {
.is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
};
const static struct intel_device_info intel_i915gm_info = {
- .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1,
+ .is_i9xx = 1, .is_mobile = 1,
.cursor_needs_physical = 1,
};
const static struct intel_device_info intel_i945g_info = {
.is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
};
const static struct intel_device_info intel_i945gm_info = {
- .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1,
+ .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
.has_hotplug = 1, .cursor_needs_physical = 1,
};
@@ -139,19 +140,19 @@ const static struct intel_device_info intel_ironlake_m_info = {
const static struct intel_device_info intel_sandybridge_d_info = {
.is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
- .has_hotplug = 1,
+ .has_hotplug = 1, .is_gen6 = 1,
};
const static struct intel_device_info intel_sandybridge_m_info = {
.is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1,
- .has_hotplug = 1,
+ .has_hotplug = 1, .is_gen6 = 1,
};
const static struct pci_device_id pciidlist[] = {
INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
- INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info),
+ INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
@@ -361,7 +362,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
!dev_priv->mm.suspended) {
drm_i915_ring_buffer_t *ring = &dev_priv->ring;
struct drm_gem_object *obj = ring->ring_obj;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
dev_priv->mm.suspended = 0;
/* Stop the ring if it's running. */
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 979439cfb82..6e4790065d9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -195,6 +195,7 @@ struct intel_overlay;
struct intel_device_info {
u8 is_mobile : 1;
u8 is_i8xx : 1;
+ u8 is_i85x : 1;
u8 is_i915g : 1;
u8 is_i9xx : 1;
u8 is_i945gm : 1;
@@ -205,6 +206,7 @@ struct intel_device_info {
u8 is_g4x : 1;
u8 is_pineview : 1;
u8 is_ironlake : 1;
+ u8 is_gen6 : 1;
u8 has_fbc : 1;
u8 has_rc6 : 1;
u8 has_pipe_cxsr : 1;
@@ -234,11 +236,14 @@ typedef struct drm_i915_private {
drm_dma_handle_t *status_page_dmah;
void *hw_status_page;
+ void *seqno_page;
dma_addr_t dma_status_page;
uint32_t counter;
unsigned int status_gfx_addr;
+ unsigned int seqno_gfx_addr;
drm_local_map_t hws_map;
struct drm_gem_object *hws_obj;
+ struct drm_gem_object *seqno_obj;
struct drm_gem_object *pwrctx;
struct resource mch_res;
@@ -610,6 +615,8 @@ typedef struct drm_i915_private {
/* Reclocking support */
bool render_reclock_avail;
bool lvds_downclock_avail;
+ /* indicate whether the LVDS EDID is OK */
+ bool lvds_edid_good;
/* indicates the reduced downclock for LVDS*/
int lvds_downclock;
struct work_struct idle_work;
@@ -627,6 +634,9 @@ typedef struct drm_i915_private {
u8 max_delay;
enum no_fbc_reason no_fbc_reason;
+
+ struct drm_mm_node *compressed_fb;
+ struct drm_mm_node *compressed_llb;
} drm_i915_private_t;
/** driver private structure attached to each drm_gem_object */
@@ -730,6 +740,8 @@ struct drm_i915_gem_object {
atomic_t pending_flip;
};
+#define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private)
+
/**
* Request queue structure.
*
@@ -1065,7 +1077,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_I830(dev) ((dev)->pci_device == 0x3577)
#define IS_845G(dev) ((dev)->pci_device == 0x2562)
-#define IS_I85X(dev) ((dev)->pci_device == 0x3582)
+#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x)
#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
#define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx)
#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g)
@@ -1084,6 +1096,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046)
#define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake)
#define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx)
+#define IS_GEN6(dev) (INTEL_INFO(dev)->is_gen6)
#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile)
#define IS_GEN3(dev) (IS_I915G(dev) || \
@@ -1107,8 +1120,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
-#define IS_GEN6(dev) ((dev)->pci_device == 0x0102)
-
/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
* rows, which changed the alignment requirements and fence programming.
*/
@@ -1131,6 +1142,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \
IS_GEN6(dev))
+#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fba37e9f775..ef3d91dda71 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -31,6 +31,7 @@
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
+#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/pci.h>
@@ -162,7 +163,7 @@ fast_shmem_read(struct page **pages,
static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
{
drm_i915_private_t *dev_priv = obj->dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
obj_priv->tiling_mode != I915_TILING_NONE;
@@ -263,7 +264,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pread *args,
struct drm_file *file_priv)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
ssize_t remain;
loff_t offset, page_base;
char __user *user_data;
@@ -284,7 +285,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
if (ret != 0)
goto fail_put_pages;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
offset = args->offset;
while (remain > 0) {
@@ -353,7 +354,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pread *args,
struct drm_file *file_priv)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct mm_struct *mm = current->mm;
struct page **user_pages;
ssize_t remain;
@@ -402,7 +403,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
if (ret != 0)
goto fail_put_pages;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
offset = args->offset;
while (remain > 0) {
@@ -478,7 +479,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL)
return -EBADF;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
/* Bounds check source.
*
@@ -580,7 +581,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pwrite *args,
struct drm_file *file_priv)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
drm_i915_private_t *dev_priv = dev->dev_private;
ssize_t remain;
loff_t offset, page_base;
@@ -604,7 +605,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
if (ret)
goto fail;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
offset = obj_priv->gtt_offset + args->offset;
while (remain > 0) {
@@ -654,7 +655,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pwrite *args,
struct drm_file *file_priv)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
drm_i915_private_t *dev_priv = dev->dev_private;
ssize_t remain;
loff_t gtt_page_base, offset;
@@ -698,7 +699,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
if (ret)
goto out_unpin_object;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
offset = obj_priv->gtt_offset + args->offset;
while (remain > 0) {
@@ -760,7 +761,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pwrite *args,
struct drm_file *file_priv)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
ssize_t remain;
loff_t offset, page_base;
char __user *user_data;
@@ -780,7 +781,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
if (ret != 0)
goto fail_put_pages;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
offset = args->offset;
obj_priv->dirty = 1;
@@ -828,7 +829,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pwrite *args,
struct drm_file *file_priv)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct mm_struct *mm = current->mm;
struct page **user_pages;
ssize_t remain;
@@ -876,7 +877,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
if (ret != 0)
goto fail_put_pages;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
offset = args->offset;
obj_priv->dirty = 1;
@@ -951,7 +952,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL)
return -EBADF;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
/* Bounds check destination.
*
@@ -1033,7 +1034,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL)
return -EBADF;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
mutex_lock(&dev->struct_mutex);
@@ -1095,7 +1096,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
DRM_INFO("%s: sw_finish %d (%p %zd)\n",
__func__, args->handle, obj, obj->size);
#endif
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
/* Pinned buffers may be scanout, so flush the cache */
if (obj_priv->pin_count)
@@ -1166,7 +1167,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
struct drm_gem_object *obj = vma->vm_private_data;
struct drm_device *dev = obj->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
pgoff_t page_offset;
unsigned long pfn;
int ret = 0;
@@ -1233,7 +1234,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
struct drm_gem_mm *mm = dev->mm_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct drm_map_list *list;
struct drm_local_map *map;
int ret = 0;
@@ -1304,7 +1305,7 @@ void
i915_gem_release_mmap(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
if (dev->dev_mapping)
unmap_mapping_range(dev->dev_mapping,
@@ -1315,7 +1316,7 @@ static void
i915_gem_free_mmap_offset(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct drm_gem_mm *mm = dev->mm_private;
struct drm_map_list *list;
@@ -1346,7 +1347,7 @@ static uint32_t
i915_gem_get_gtt_alignment(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int start, i;
/*
@@ -1405,7 +1406,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
mutex_lock(&dev->struct_mutex);
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
if (obj_priv->madv != I915_MADV_WILLNEED) {
DRM_ERROR("Attempting to mmap a purgeable buffer\n");
@@ -1449,7 +1450,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
void
i915_gem_object_put_pages(struct drm_gem_object *obj)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int page_count = obj->size / PAGE_SIZE;
int i;
@@ -1466,9 +1467,6 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
obj_priv->dirty = 0;
for (i = 0; i < page_count; i++) {
- if (obj_priv->pages[i] == NULL)
- break;
-
if (obj_priv->dirty)
set_page_dirty(obj_priv->pages[i]);
@@ -1488,7 +1486,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
/* Add a reference if we're newly entering the active list. */
if (!obj_priv->active) {
@@ -1508,7 +1506,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
BUG_ON(!obj_priv->active);
list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list);
@@ -1519,7 +1517,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
static void
i915_gem_object_truncate(struct drm_gem_object *obj)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct inode *inode;
inode = obj->filp->f_path.dentry->d_inode;
@@ -1540,7 +1538,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
i915_verify_inactive(dev, __FILE__, __LINE__);
if (obj_priv->pin_count != 0)
@@ -1590,6 +1588,13 @@ i915_gem_process_flushing_list(struct drm_device *dev,
}
}
+#define PIPE_CONTROL_FLUSH(addr) \
+ OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \
+ PIPE_CONTROL_DEPTH_STALL); \
+ OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \
+ OUT_RING(0); \
+ OUT_RING(0); \
+
/**
* Creates a new sequence number, emitting a write of it to the status page
* plus an interrupt, which will trigger i915_user_interrupt_handler.
@@ -1624,13 +1629,47 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
if (dev_priv->mm.next_gem_seqno == 0)
dev_priv->mm.next_gem_seqno++;
- BEGIN_LP_RING(4);
- OUT_RING(MI_STORE_DWORD_INDEX);
- OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
- OUT_RING(seqno);
+ if (HAS_PIPE_CONTROL(dev)) {
+ u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
- OUT_RING(MI_USER_INTERRUPT);
- ADVANCE_LP_RING();
+ /*
+ * Workaround qword write incoherence by flushing the
+ * PIPE_NOTIFY buffers out to memory before requesting
+ * an interrupt.
+ */
+ BEGIN_LP_RING(32);
+ OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+ PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
+ OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+ OUT_RING(seqno);
+ OUT_RING(0);
+ PIPE_CONTROL_FLUSH(scratch_addr);
+ scratch_addr += 128; /* write to separate cachelines */
+ PIPE_CONTROL_FLUSH(scratch_addr);
+ scratch_addr += 128;
+ PIPE_CONTROL_FLUSH(scratch_addr);
+ scratch_addr += 128;
+ PIPE_CONTROL_FLUSH(scratch_addr);
+ scratch_addr += 128;
+ PIPE_CONTROL_FLUSH(scratch_addr);
+ scratch_addr += 128;
+ PIPE_CONTROL_FLUSH(scratch_addr);
+ OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+ PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
+ PIPE_CONTROL_NOTIFY);
+ OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+ OUT_RING(seqno);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(4);
+ OUT_RING(MI_STORE_DWORD_INDEX);
+ OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+ OUT_RING(seqno);
+
+ OUT_RING(MI_USER_INTERRUPT);
+ ADVANCE_LP_RING();
+ }
DRM_DEBUG_DRIVER("%d\n", seqno);
@@ -1754,7 +1793,10 @@ i915_get_gem_seqno(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
+ if (HAS_PIPE_CONTROL(dev))
+ return ((volatile u32 *)(dev_priv->seqno_page))[0];
+ else
+ return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
}
/**
@@ -1967,7 +2009,7 @@ static int
i915_gem_object_wait_rendering(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int ret;
/* This function only exists to support waiting for existing rendering,
@@ -1999,7 +2041,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int ret = 0;
#if WATCH_BUF
@@ -2175,7 +2217,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
#if WATCH_LRU
DRM_INFO("%s: evicting %p\n", __func__, obj);
#endif
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
BUG_ON(obj_priv->pin_count != 0);
BUG_ON(obj_priv->active);
@@ -2227,11 +2269,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
seqno = i915_add_request(dev, NULL, obj->write_domain);
if (seqno == 0)
return -ENOMEM;
-
- ret = i915_wait_request(dev, seqno);
- if (ret)
- return ret;
-
continue;
}
}
@@ -2251,12 +2288,11 @@ int
i915_gem_object_get_pages(struct drm_gem_object *obj,
gfp_t gfpmask)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int page_count, i;
struct address_space *mapping;
struct inode *inode;
struct page *page;
- int ret;
if (obj_priv->pages_refcount++ != 0)
return 0;
@@ -2279,11 +2315,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,
mapping_gfp_mask (mapping) |
__GFP_COLD |
gfpmask);
- if (IS_ERR(page)) {
- ret = PTR_ERR(page);
- i915_gem_object_put_pages(obj);
- return ret;
- }
+ if (IS_ERR(page))
+ goto err_pages;
+
obj_priv->pages[i] = page;
}
@@ -2291,6 +2325,15 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,
i915_gem_object_do_bit_17_swizzle(obj);
return 0;
+
+err_pages:
+ while (i--)
+ page_cache_release(obj_priv->pages[i]);
+
+ drm_free_large(obj_priv->pages);
+ obj_priv->pages = NULL;
+ obj_priv->pages_refcount--;
+ return PTR_ERR(page);
}
static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
@@ -2298,7 +2341,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
struct drm_gem_object *obj = reg->obj;
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int regnum = obj_priv->fence_reg;
uint64_t val;
@@ -2320,7 +2363,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
struct drm_gem_object *obj = reg->obj;
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int regnum = obj_priv->fence_reg;
uint64_t val;
@@ -2340,7 +2383,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
struct drm_gem_object *obj = reg->obj;
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int regnum = obj_priv->fence_reg;
int tile_width;
uint32_t fence_reg, val;
@@ -2363,6 +2406,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
pitch_val = obj_priv->stride / tile_width;
pitch_val = ffs(pitch_val) - 1;
+ if (obj_priv->tiling_mode == I915_TILING_Y &&
+ HAS_128_BYTE_Y_TILING(dev))
+ WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL);
+ else
+ WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL);
+
val = obj_priv->gtt_offset;
if (obj_priv->tiling_mode == I915_TILING_Y)
val |= 1 << I830_FENCE_TILING_Y_SHIFT;
@@ -2382,7 +2431,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
struct drm_gem_object *obj = reg->obj;
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int regnum = obj_priv->fence_reg;
uint32_t val;
uint32_t pitch_val;
@@ -2426,7 +2475,7 @@ static int i915_find_fence_reg(struct drm_device *dev)
if (!reg->obj)
return i;
- obj_priv = reg->obj->driver_private;
+ obj_priv = to_intel_bo(reg->obj);
if (!obj_priv->pin_count)
avail++;
}
@@ -2481,7 +2530,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct drm_i915_fence_reg *reg = NULL;
int ret;
@@ -2548,7 +2597,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
if (IS_GEN6(dev)) {
I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
@@ -2584,7 +2633,7 @@ int
i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
if (obj_priv->fence_reg == I915_FENCE_REG_NONE)
return 0;
@@ -2622,7 +2671,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct drm_mm_node *free_space;
gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN;
int ret;
@@ -2729,7 +2778,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
void
i915_gem_clflush_object(struct drm_gem_object *obj)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
/* If we don't have a page list set up, then we're not pinned
* to GPU, and we can ignore the cache flush because it'll happen
@@ -2830,7 +2879,7 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
int
i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
uint32_t old_write_domain, old_read_domains;
int ret;
@@ -2880,7 +2929,7 @@ int
i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
uint32_t old_write_domain, old_read_domains;
int ret;
@@ -3093,7 +3142,7 @@ static void
i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
uint32_t invalidate_domains = 0;
uint32_t flush_domains = 0;
uint32_t old_read_domains;
@@ -3178,7 +3227,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
static void
i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
if (!obj_priv->page_cpu_valid)
return;
@@ -3218,7 +3267,7 @@ static int
i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
uint64_t offset, uint64_t size)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
uint32_t old_read_domains;
int i, ret;
@@ -3287,7 +3336,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int i, ret;
void __iomem *reloc_page;
bool need_fence;
@@ -3338,7 +3387,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
i915_gem_object_unpin(obj);
return -EBADF;
}
- target_obj_priv = target_obj->driver_private;
+ target_obj_priv = to_intel_bo(target_obj);
#if WATCH_RELOC
DRM_INFO("%s: obj %p offset %08x target %d "
@@ -3690,7 +3739,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev,
prepare_to_wait(&dev_priv->pending_flip_queue,
&wait, TASK_INTERRUPTIBLE);
for (i = 0; i < count; i++) {
- obj_priv = object_list[i]->driver_private;
+ obj_priv = to_intel_bo(object_list[i]);
if (atomic_read(&obj_priv->pending_flip) > 0)
break;
}
@@ -3799,7 +3848,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
goto err;
}
- obj_priv = object_list[i]->driver_private;
+ obj_priv = to_intel_bo(object_list[i]);
if (obj_priv->in_execbuffer) {
DRM_ERROR("Object %p appears more than once in object list\n",
object_list[i]);
@@ -3925,7 +3974,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
for (i = 0; i < args->buffer_count; i++) {
struct drm_gem_object *obj = object_list[i];
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
uint32_t old_write_domain = obj->write_domain;
obj->write_domain = obj->pending_write_domain;
@@ -4000,7 +4049,7 @@ err:
for (i = 0; i < args->buffer_count; i++) {
if (object_list[i]) {
- obj_priv = object_list[i]->driver_private;
+ obj_priv = to_intel_bo(object_list[i]);
obj_priv->in_execbuffer = false;
}
drm_gem_object_unreference(object_list[i]);
@@ -4178,7 +4227,7 @@ int
i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int ret;
i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -4211,7 +4260,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
i915_verify_inactive(dev, __FILE__, __LINE__);
obj_priv->pin_count--;
@@ -4251,7 +4300,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
mutex_unlock(&dev->struct_mutex);
return -EBADF;
}
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
if (obj_priv->madv != I915_MADV_WILLNEED) {
DRM_ERROR("Attempting to pin a purgeable buffer\n");
@@ -4308,7 +4357,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
return -EBADF;
}
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
if (obj_priv->pin_filp != file_priv) {
DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
args->handle);
@@ -4350,7 +4399,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
*/
i915_gem_retire_requests(dev);
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
/* Don't count being on the flushing list against the object being
* done. Otherwise, a buffer left on the flushing list but not getting
* flushed (because nobody's flushing that domain) won't ever return
@@ -4396,7 +4445,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
}
mutex_lock(&dev->struct_mutex);
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
if (obj_priv->pin_count) {
drm_gem_object_unreference(obj);
@@ -4457,7 +4506,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
void i915_gem_free_object(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
trace_i915_gem_object_destroy(obj);
@@ -4547,6 +4596,49 @@ i915_gem_idle(struct drm_device *dev)
return 0;
}
+/*
+ * 965+ support PIPE_CONTROL commands, which provide finer grained control
+ * over cache flushing.
+ */
+static int
+i915_gem_init_pipe_control(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ int ret;
+
+ obj = drm_gem_object_alloc(dev, 4096);
+ if (obj == NULL) {
+ DRM_ERROR("Failed to allocate seqno page\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+ obj_priv = to_intel_bo(obj);
+ obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
+
+ ret = i915_gem_object_pin(obj, 4096);
+ if (ret)
+ goto err_unref;
+
+ dev_priv->seqno_gfx_addr = obj_priv->gtt_offset;
+ dev_priv->seqno_page = kmap(obj_priv->pages[0]);
+ if (dev_priv->seqno_page == NULL)
+ goto err_unpin;
+
+ dev_priv->seqno_obj = obj;
+ memset(dev_priv->seqno_page, 0, PAGE_SIZE);
+
+ return 0;
+
+err_unpin:
+ i915_gem_object_unpin(obj);
+err_unref:
+ drm_gem_object_unreference(obj);
+err:
+ return ret;
+}
+
static int
i915_gem_init_hws(struct drm_device *dev)
{
@@ -4564,15 +4656,16 @@ i915_gem_init_hws(struct drm_device *dev)
obj = drm_gem_object_alloc(dev, 4096);
if (obj == NULL) {
DRM_ERROR("Failed to allocate status page\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err;
}
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
ret = i915_gem_object_pin(obj, 4096);
if (ret != 0) {
drm_gem_object_unreference(obj);
- return ret;
+ goto err_unref;
}
dev_priv->status_gfx_addr = obj_priv->gtt_offset;
@@ -4581,10 +4674,16 @@ i915_gem_init_hws(struct drm_device *dev)
if (dev_priv->hw_status_page == NULL) {
DRM_ERROR("Failed to map status page.\n");
memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
- i915_gem_object_unpin(obj);
- drm_gem_object_unreference(obj);
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_unpin;
+ }
+
+ if (HAS_PIPE_CONTROL(dev)) {
+ ret = i915_gem_init_pipe_control(dev);
+ if (ret)
+ goto err_unpin;
}
+
dev_priv->hws_obj = obj;
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
if (IS_GEN6(dev)) {
@@ -4597,6 +4696,30 @@ i915_gem_init_hws(struct drm_device *dev)
DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
return 0;
+
+err_unpin:
+ i915_gem_object_unpin(obj);
+err_unref:
+ drm_gem_object_unreference(obj);
+err:
+ return 0;
+}
+
+static void
+i915_gem_cleanup_pipe_control(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ obj = dev_priv->seqno_obj;
+ obj_priv = to_intel_bo(obj);
+ kunmap(obj_priv->pages[0]);
+ i915_gem_object_unpin(obj);
+ drm_gem_object_unreference(obj);
+ dev_priv->seqno_obj = NULL;
+
+ dev_priv->seqno_page = NULL;
}
static void
@@ -4610,7 +4733,7 @@ i915_gem_cleanup_hws(struct drm_device *dev)
return;
obj = dev_priv->hws_obj;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
kunmap(obj_priv->pages[0]);
i915_gem_object_unpin(obj);
@@ -4620,6 +4743,9 @@ i915_gem_cleanup_hws(struct drm_device *dev)
memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
dev_priv->hw_status_page = NULL;
+ if (HAS_PIPE_CONTROL(dev))
+ i915_gem_cleanup_pipe_control(dev);
+
/* Write high address into HWS_PGA when disabling. */
I915_WRITE(HWS_PGA, 0x1ffff000);
}
@@ -4644,7 +4770,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
i915_gem_cleanup_hws(dev);
return -ENOMEM;
}
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
ret = i915_gem_object_pin(obj, 4096);
if (ret != 0) {
@@ -4730,6 +4856,11 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
ring->space += ring->Size;
}
+ if (IS_I9XX(dev) && !IS_GEN3(dev)) {
+ I915_WRITE(MI_MODE,
+ (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
+ }
+
return 0;
}
@@ -4932,7 +5063,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
int ret;
int page_count;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
if (!obj_priv->phys_obj)
return;
@@ -4971,7 +5102,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
if (id > I915_MAX_PHYS_OBJECT)
return -EINVAL;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
if (obj_priv->phys_obj) {
if (obj_priv->phys_obj->id == id)
@@ -5022,7 +5153,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_i915_gem_pwrite *args,
struct drm_file *file_priv)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
void *obj_addr;
int ret;
char __user *user_data;
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
index e602614bd3f..35507cf53fa 100644
--- a/drivers/gpu/drm/i915/i915_gem_debug.c
+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
@@ -72,7 +72,7 @@ void
i915_gem_dump_object(struct drm_gem_object *obj, int len,
const char *where, uint32_t mark)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int page;
DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
@@ -137,7 +137,7 @@ void
i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int page;
uint32_t *gtt_mapping;
uint32_t *backing_map = NULL;
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index b5c55d88ff7..4bdccefcf2c 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -202,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
* reg, so dont bother to check the size */
if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
return false;
- } else if (IS_I9XX(dev)) {
- uint32_t pitch_val = ffs(stride / tile_width) - 1;
-
- /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
- * instead of 4 (2KB) on 945s.
- */
- if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
- size > (I830_FENCE_MAX_SIZE_VAL << 20))
+ } else if (IS_GEN3(dev) || IS_GEN2(dev)) {
+ if (stride > 8192)
return false;
- } else {
- uint32_t pitch_val = ffs(stride / tile_width) - 1;
- if (pitch_val > I830_FENCE_MAX_PITCH_VAL ||
- size > (I830_FENCE_MAX_SIZE_VAL << 19))
- return false;
+ if (IS_GEN3(dev)) {
+ if (size > I830_FENCE_MAX_SIZE_VAL << 20)
+ return false;
+ } else {
+ if (size > I830_FENCE_MAX_SIZE_VAL << 19)
+ return false;
+ }
}
/* 965+ just needs multiples of tile width */
@@ -240,7 +236,7 @@ bool
i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)
{
struct drm_device *dev = obj->dev;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
if (obj_priv->gtt_space == NULL)
return true;
@@ -280,7 +276,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL)
return -EINVAL;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
drm_gem_object_unreference_unlocked(obj);
@@ -325,9 +321,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
* need to ensure that any fence register is cleared.
*/
if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode))
- ret = i915_gem_object_unbind(obj);
+ ret = i915_gem_object_unbind(obj);
+ else if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+ ret = i915_gem_object_put_fence_reg(obj);
else
- ret = i915_gem_object_put_fence_reg(obj);
+ i915_gem_release_mmap(obj);
+
if (ret != 0) {
WARN(ret != -ERESTARTSYS,
"failed to reset object for tiling switch");
@@ -361,7 +360,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL)
return -EINVAL;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
mutex_lock(&dev->struct_mutex);
@@ -424,7 +423,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int page_count = obj->size >> PAGE_SHIFT;
int i;
@@ -453,7 +452,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
int page_count = obj->size >> PAGE_SHIFT;
int i;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5388354da0d..2b8b969d0c1 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -27,6 +27,7 @@
*/
#include <linux/sysrq.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
@@ -259,10 +260,10 @@ static void i915_hotplug_work_func(struct work_struct *work)
if (mode_config->num_connector) {
list_for_each_entry(connector, &mode_config->connector_list, head) {
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
- if (intel_output->hot_plug)
- (*intel_output->hot_plug) (intel_output);
+ if (intel_encoder->hot_plug)
+ (*intel_encoder->hot_plug) (intel_encoder);
}
}
/* Just fire off a uevent and let userspace tell us what to do */
@@ -348,7 +349,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
READ_BREADCRUMB(dev_priv);
}
- if (gt_iir & GT_USER_INTERRUPT) {
+ if (gt_iir & GT_PIPE_NOTIFY) {
u32 seqno = i915_get_gem_seqno(dev);
dev_priv->mm.irq_gem_seqno = seqno;
trace_i915_gem_request_complete(dev, seqno);
@@ -443,7 +444,7 @@ i915_error_object_create(struct drm_device *dev,
if (src == NULL)
return NULL;
- src_priv = src->driver_private;
+ src_priv = to_intel_bo(src);
if (src_priv->pages == NULL)
return NULL;
@@ -1004,7 +1005,7 @@ void i915_user_irq_get(struct drm_device *dev)
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
if (HAS_PCH_SPLIT(dev))
- ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+ ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
else
i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
}
@@ -1020,7 +1021,7 @@ void i915_user_irq_put(struct drm_device *dev)
BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
if (HAS_PCH_SPLIT(dev))
- ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+ ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
else
i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
}
@@ -1304,7 +1305,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
/* enable kind of interrupts always enabled */
u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
- u32 render_mask = GT_USER_INTERRUPT;
+ u32 render_mask = GT_PIPE_NOTIFY;
u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 7cc8410239c..8fcc75c1aa2 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_opregion *opregion = &dev_priv->opregion;
struct drm_connector *connector;
+ acpi_handle handle;
+ struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
+ unsigned long long device_id;
+ acpi_status status;
int i = 0;
+ handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
+ if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev)))
+ return;
+
+ if (acpi_is_video_device(acpi_dev))
+ acpi_video_bus = acpi_dev;
+ else {
+ list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
+ if (acpi_is_video_device(acpi_cdev)) {
+ acpi_video_bus = acpi_cdev;
+ break;
+ }
+ }
+ }
+
+ if (!acpi_video_bus) {
+ printk(KERN_WARNING "No ACPI video bus found\n");
+ return;
+ }
+
+ list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
+ if (i >= 8) {
+ dev_printk (KERN_ERR, &dev->pdev->dev,
+ "More than 8 outputs detected\n");
+ return;
+ }
+ status =
+ acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
+ NULL, &device_id);
+ if (ACPI_SUCCESS(status)) {
+ if (!device_id)
+ goto blind_set;
+ opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f);
+ i++;
+ }
+ }
+
+end:
+ /* If fewer than 8 outputs, the list must be null terminated */
+ if (i < 8)
+ opregion->acpi->didl[i] = 0;
+ return;
+
+blind_set:
+ i = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
int output_type = ACPI_OTHER_OUTPUT;
if (i >= 8) {
@@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev)
opregion->acpi->didl[i] |= (1<<31) | output_type | i;
i++;
}
-
- /* If fewer than 8 outputs, the list must be null terminated */
- if (i < 8)
- opregion->acpi->didl[i] = 0;
+ goto end;
}
int intel_opregion_init(struct drm_device *dev, int resume)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3d59862c7cc..4cbc5210fd3 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -230,6 +230,16 @@
#define ASYNC_FLIP (1<<22)
#define DISPLAY_PLANE_A (0<<20)
#define DISPLAY_PLANE_B (1<<20)
+#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
+#define PIPE_CONTROL_QW_WRITE (1<<14)
+#define PIPE_CONTROL_DEPTH_STALL (1<<13)
+#define PIPE_CONTROL_WC_FLUSH (1<<12)
+#define PIPE_CONTROL_IS_FLUSH (1<<11) /* MBZ on Ironlake */
+#define PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */
+#define PIPE_CONTROL_ISP_DIS (1<<9)
+#define PIPE_CONTROL_NOTIFY (1<<8)
+#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
+#define PIPE_CONTROL_STALL_EN (1<<1) /* in addr word, Ironlake+ only */
/*
* Fence registers
@@ -241,7 +251,7 @@
#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
#define I830_FENCE_PITCH_SHIFT 4
#define I830_FENCE_REG_VALID (1<<0)
-#define I915_FENCE_MAX_PITCH_VAL 0x10
+#define I915_FENCE_MAX_PITCH_VAL 4
#define I830_FENCE_MAX_PITCH_VAL 6
#define I830_FENCE_MAX_SIZE_VAL (1<<8)
@@ -298,6 +308,10 @@
#define INSTDONE 0x02090
#define NOPID 0x02094
#define HWSTAM 0x02098
+
+#define MI_MODE 0x0209c
+# define VS_TIMER_DISPATCH (1 << 6)
+
#define SCPD0 0x0209c /* 915+ only */
#define IER 0x020a0
#define IIR 0x020a4
@@ -366,7 +380,7 @@
#define FBC_CTL_PERIODIC (1<<30)
#define FBC_CTL_INTERVAL_SHIFT (16)
#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
-#define FBC_C3_IDLE (1<<13)
+#define FBC_CTL_C3_IDLE (1<<13)
#define FBC_CTL_STRIDE_SHIFT (5)
#define FBC_CTL_FENCENO (1<<0)
#define FBC_COMMAND 0x0320c
@@ -2172,6 +2186,14 @@
#define DISPLAY_PORT_PLL_BIOS_1 0x46010
#define DISPLAY_PORT_PLL_BIOS_2 0x46014
+#define PCH_DSPCLK_GATE_D 0x42020
+# define DPFDUNIT_CLOCK_GATE_DISABLE (1 << 7)
+# define DPARBUNIT_CLOCK_GATE_DISABLE (1 << 5)
+
+#define PCH_3DCGDIS0 0x46020
+# define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18)
+# define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1)
+
#define FDI_PLL_FREQ_CTL 0x46030
#define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24)
#define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00
@@ -2273,6 +2295,7 @@
#define DEIER 0x4400c
/* GT interrupt */
+#define GT_PIPE_NOTIFY (1 << 4)
#define GT_SYNC_STATUS (1 << 2)
#define GT_USER_INTERRUPT (1 << 0)
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 70c9d4ba704..f9ba452f0cb 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -417,8 +417,9 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
edp = find_section(bdb, BDB_EDP);
if (!edp) {
if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) {
- DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported,\
- assume 18bpp panel color depth.\n");
+ DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
+ "supported, assume 18bpp panel color "
+ "depth.\n");
dev_priv->edp_bpp = 18;
}
return;
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index fccf07470c8..759c2ef72ef 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -25,6 +25,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "drm_crtc.h"
@@ -246,19 +247,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
static bool intel_crt_detect_ddc(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
/* CRT should always be at 0, but check anyway */
- if (intel_output->type != INTEL_OUTPUT_ANALOG)
+ if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
return false;
- return intel_ddc_probe(intel_output);
+ return intel_ddc_probe(intel_encoder);
}
static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
{
- struct drm_encoder *encoder = &intel_output->enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -386,8 +387,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct intel_output *intel_output = to_intel_output(connector);
- struct drm_encoder *encoder = &intel_output->enc;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_crtc *crtc;
int dpms_mode;
enum drm_connector_status status;
@@ -404,13 +405,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
/* for pre-945g platforms use load detect */
if (encoder->crtc && encoder->crtc->enabled) {
- status = intel_crt_load_detect(encoder->crtc, intel_output);
+ status = intel_crt_load_detect(encoder->crtc, intel_encoder);
} else {
- crtc = intel_get_load_detect_pipe(intel_output,
+ crtc = intel_get_load_detect_pipe(intel_encoder,
NULL, &dpms_mode);
if (crtc) {
- status = intel_crt_load_detect(crtc, intel_output);
- intel_release_load_detect_pipe(intel_output, dpms_mode);
+ status = intel_crt_load_detect(crtc, intel_encoder);
+ intel_release_load_detect_pipe(intel_encoder, dpms_mode);
} else
status = connector_status_unknown;
}
@@ -420,9 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
static void intel_crt_destroy(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
- intel_i2c_destroy(intel_output->ddc_bus);
+ intel_i2c_destroy(intel_encoder->ddc_bus);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
@@ -431,28 +432,28 @@ static void intel_crt_destroy(struct drm_connector *connector)
static int intel_crt_get_modes(struct drm_connector *connector)
{
int ret;
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
struct i2c_adapter *ddcbus;
struct drm_device *dev = connector->dev;
- ret = intel_ddc_get_modes(intel_output);
+ ret = intel_ddc_get_modes(intel_encoder);
if (ret || !IS_G4X(dev))
goto end;
- ddcbus = intel_output->ddc_bus;
+ ddcbus = intel_encoder->ddc_bus;
/* Try to probe digital port for output in DVI-I -> VGA mode. */
- intel_output->ddc_bus =
+ intel_encoder->ddc_bus =
intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
- if (!intel_output->ddc_bus) {
- intel_output->ddc_bus = ddcbus;
+ if (!intel_encoder->ddc_bus) {
+ intel_encoder->ddc_bus = ddcbus;
dev_printk(KERN_ERR, &connector->dev->pdev->dev,
"DDC bus registration failed for CRTDDC_D.\n");
goto end;
}
/* Try to get modes by GPIOD port */
- ret = intel_ddc_get_modes(intel_output);
+ ret = intel_ddc_get_modes(intel_encoder);
intel_i2c_destroy(ddcbus);
end:
@@ -505,23 +506,23 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
void intel_crt_init(struct drm_device *dev)
{
struct drm_connector *connector;
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 i2c_reg;
- intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
- if (!intel_output)
+ intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
+ if (!intel_encoder)
return;
- connector = &intel_output->base;
- drm_connector_init(dev, &intel_output->base,
+ connector = &intel_encoder->base;
+ drm_connector_init(dev, &intel_encoder->base,
&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
- drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
+ drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs,
DRM_MODE_ENCODER_DAC);
- drm_mode_connector_attach_encoder(&intel_output->base,
- &intel_output->enc);
+ drm_mode_connector_attach_encoder(&intel_encoder->base,
+ &intel_encoder->enc);
/* Set up the DDC bus. */
if (HAS_PCH_SPLIT(dev))
@@ -532,22 +533,22 @@ void intel_crt_init(struct drm_device *dev)
if (dev_priv->crt_ddc_bus != 0)
i2c_reg = dev_priv->crt_ddc_bus;
}
- intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
- if (!intel_output->ddc_bus) {
+ intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
+ if (!intel_encoder->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n");
return;
}
- intel_output->type = INTEL_OUTPUT_ANALOG;
- intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+ intel_encoder->type = INTEL_OUTPUT_ANALOG;
+ intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT) |
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
- intel_output->crtc_mask = (1 << 0) | (1 << 1);
+ intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
- drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
+ drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
drm_sysfs_connector_add(connector);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9cd6de5f990..c7502b6b160 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -28,6 +28,7 @@
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "intel_drv.h"
#include "i915_drm.h"
@@ -746,16 +747,16 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
list_for_each_entry(l_entry, &mode_config->connector_list, head) {
if (l_entry->encoder &&
l_entry->encoder->crtc == crtc) {
- struct intel_output *intel_output = to_intel_output(l_entry);
- if (intel_output->type == type)
+ struct intel_encoder *intel_encoder = to_intel_encoder(l_entry);
+ if (intel_encoder->type == type)
return true;
}
}
return false;
}
-struct drm_connector *
-intel_pipe_get_output (struct drm_crtc *crtc)
+static struct drm_connector *
+intel_pipe_get_connector (struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
@@ -1002,7 +1003,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = crtc->fb;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
- struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int plane, i;
u32 fbc_ctl, fbc_ctl2;
@@ -1032,7 +1033,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
/* enable it... */
fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC;
if (IS_I945GM(dev))
- fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */
+ fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
if (obj_priv->tiling_mode != I915_TILING_NONE)
@@ -1079,7 +1080,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = crtc->fb;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
- struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA :
DPFC_CTL_PLANEB);
@@ -1175,7 +1176,7 @@ static void intel_update_fbc(struct drm_crtc *crtc,
return;
intel_fb = to_intel_framebuffer(fb);
- obj_priv = intel_fb->obj->driver_private;
+ obj_priv = to_intel_bo(intel_fb->obj);
/*
* If FBC is already on, we just have to verify that we can
@@ -1242,7 +1243,7 @@ out_disable:
static int
intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
{
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
u32 alignment;
int ret;
@@ -1322,7 +1323,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
intel_fb = to_intel_framebuffer(crtc->fb);
obj = intel_fb->obj;
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(dev, obj);
@@ -1400,7 +1401,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
if (old_fb) {
intel_fb = to_intel_framebuffer(old_fb);
- obj_priv = intel_fb->obj->driver_private;
+ obj_priv = to_intel_bo(intel_fb->obj);
i915_gem_object_unpin(intel_fb->obj);
}
intel_increase_pllclock(crtc, true);
@@ -2916,7 +2917,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
- int refclk, num_outputs = 0;
+ int refclk, num_connectors = 0;
intel_clock_t clock, reduced_clock;
u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
@@ -2942,19 +2943,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
drm_vblank_pre_modeset(dev, pipe);
list_for_each_entry(connector, &mode_config->connector_list, head) {
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
if (!connector->encoder || connector->encoder->crtc != crtc)
continue;
- switch (intel_output->type) {
+ switch (intel_encoder->type) {
case INTEL_OUTPUT_LVDS:
is_lvds = true;
break;
case INTEL_OUTPUT_SDVO:
case INTEL_OUTPUT_HDMI:
is_sdvo = true;
- if (intel_output->needs_tv_clock)
+ if (intel_encoder->needs_tv_clock)
is_tv = true;
break;
case INTEL_OUTPUT_DVO:
@@ -2974,10 +2975,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
break;
}
- num_outputs++;
+ num_connectors++;
}
- if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
+ if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) {
refclk = dev_priv->lvds_ssc_freq * 1000;
DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
refclk / 1000);
@@ -3048,8 +3049,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
if (is_edp) {
struct drm_connector *edp;
target_clock = mode->clock;
- edp = intel_pipe_get_output(crtc);
- intel_edp_link_config(to_intel_output(edp),
+ edp = intel_pipe_get_connector(crtc);
+ intel_edp_link_config(to_intel_encoder(edp),
&lane, &link_bw);
} else {
/* DP over FDI requires target mode clock
@@ -3230,7 +3231,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
/* XXX: just matching BIOS for now */
/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
dpll |= 3;
- else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
+ else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2)
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
@@ -3510,7 +3511,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
if (!bo)
return -ENOENT;
- obj_priv = bo->driver_private;
+ obj_priv = to_intel_bo(bo);
if (bo->size < width * height * 4) {
DRM_ERROR("buffer is to small\n");
@@ -3654,9 +3655,9 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
* detection.
*
* It will be up to the load-detect code to adjust the pipe as appropriate for
- * its requirements. The pipe will be connected to no other outputs.
+ * its requirements. The pipe will be connected to no other encoders.
*
- * Currently this code will only succeed if there is a pipe with no outputs
+ * Currently this code will only succeed if there is a pipe with no encoders
* configured for it. In the future, it could choose to temporarily disable
* some outputs to free up a pipe for its use.
*
@@ -3669,14 +3670,14 @@ static struct drm_display_mode load_detect_mode = {
704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
};
-struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
+struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
struct drm_display_mode *mode,
int *dpms_mode)
{
struct intel_crtc *intel_crtc;
struct drm_crtc *possible_crtc;
struct drm_crtc *supported_crtc =NULL;
- struct drm_encoder *encoder = &intel_output->enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_crtc *crtc = NULL;
struct drm_device *dev = encoder->dev;
struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
@@ -3728,8 +3729,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
}
encoder->crtc = crtc;
- intel_output->base.encoder = encoder;
- intel_output->load_detect_temp = true;
+ intel_encoder->base.encoder = encoder;
+ intel_encoder->load_detect_temp = true;
intel_crtc = to_intel_crtc(crtc);
*dpms_mode = intel_crtc->dpms_mode;
@@ -3754,23 +3755,23 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
return crtc;
}
-void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
+void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode)
{
- struct drm_encoder *encoder = &intel_output->enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_device *dev = encoder->dev;
struct drm_crtc *crtc = encoder->crtc;
struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
- if (intel_output->load_detect_temp) {
+ if (intel_encoder->load_detect_temp) {
encoder->crtc = NULL;
- intel_output->base.encoder = NULL;
- intel_output->load_detect_temp = false;
+ intel_encoder->base.encoder = NULL;
+ intel_encoder->load_detect_temp = false;
crtc->enabled = drm_helper_crtc_in_use(crtc);
drm_helper_disable_unused_functions(dev);
}
- /* Switch crtc and output back off if necessary */
+ /* Switch crtc and encoder back off if necessary */
if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
if (encoder->crtc == crtc)
encoder_funcs->dpms(encoder, dpms_mode);
@@ -4155,7 +4156,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
work = intel_crtc->unpin_work;
if (work == NULL || !work->pending) {
if (work && !work->pending) {
- obj_priv = work->pending_flip_obj->driver_private;
+ obj_priv = to_intel_bo(work->pending_flip_obj);
DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
obj_priv,
atomic_read(&obj_priv->pending_flip));
@@ -4180,7 +4181,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
spin_unlock_irqrestore(&dev->event_lock, flags);
- obj_priv = work->pending_flip_obj->driver_private;
+ obj_priv = to_intel_bo(work->pending_flip_obj);
/* Initial scanout buffer will have a 0 pending flip count */
if ((atomic_read(&obj_priv->pending_flip) == 0) ||
@@ -4251,7 +4252,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
ret = intel_pin_and_fence_fb_obj(dev, obj);
if (ret != 0) {
DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
- obj->driver_private);
+ to_intel_bo(obj));
kfree(work);
intel_crtc->unpin_work = NULL;
mutex_unlock(&dev->struct_mutex);
@@ -4265,7 +4266,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
crtc->fb = fb;
i915_gem_object_flush_write_domain(obj);
drm_vblank_get(dev, intel_crtc->pipe);
- obj_priv = obj->driver_private;
+ obj_priv = to_intel_bo(obj);
atomic_inc(&obj_priv->pending_flip);
work->pending_flip_obj = obj;
@@ -4398,8 +4399,8 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
int entry = 0;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- struct intel_output *intel_output = to_intel_output(connector);
- if (type_mask & intel_output->clone_mask)
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ if (type_mask & intel_encoder->clone_mask)
index_mask |= (1 << entry);
entry++;
}
@@ -4494,12 +4495,12 @@ static void intel_setup_outputs(struct drm_device *dev)
intel_tv_init(dev);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- struct intel_output *intel_output = to_intel_output(connector);
- struct drm_encoder *encoder = &intel_output->enc;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct drm_encoder *encoder = &intel_encoder->enc;
- encoder->possible_crtcs = intel_output->crtc_mask;
+ encoder->possible_crtcs = intel_encoder->crtc_mask;
encoder->possible_clones = intel_connector_clones(dev,
- intel_output->clone_mask);
+ intel_encoder->clone_mask);
}
}
@@ -4717,6 +4718,20 @@ void intel_init_clock_gating(struct drm_device *dev)
* specs, but enable as much else as we can.
*/
if (HAS_PCH_SPLIT(dev)) {
+ uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
+
+ if (IS_IRONLAKE(dev)) {
+ /* Required for FBC */
+ dspclk_gate |= DPFDUNIT_CLOCK_GATE_DISABLE;
+ /* Required for CxSR */
+ dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE;
+
+ I915_WRITE(PCH_3DCGDIS0,
+ MARIUNIT_CLOCK_GATE_DISABLE |
+ SVSMUNIT_CLOCK_GATE_DISABLE);
+ }
+
+ I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
return;
} else if (IS_G4X(dev)) {
uint32_t dspclk_gate;
@@ -4764,14 +4779,14 @@ void intel_init_clock_gating(struct drm_device *dev)
struct drm_i915_gem_object *obj_priv = NULL;
if (dev_priv->pwrctx) {
- obj_priv = dev_priv->pwrctx->driver_private;
+ obj_priv = to_intel_bo(dev_priv->pwrctx);
} else {
struct drm_gem_object *pwrctx;
pwrctx = intel_alloc_power_context(dev);
if (pwrctx) {
dev_priv->pwrctx = pwrctx;
- obj_priv = pwrctx->driver_private;
+ obj_priv = to_intel_bo(pwrctx);
}
}
@@ -4800,7 +4815,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.fbc_enabled = g4x_fbc_enabled;
dev_priv->display.enable_fbc = g4x_enable_fbc;
dev_priv->display.disable_fbc = g4x_disable_fbc;
- } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) {
+ } else if (IS_I965GM(dev)) {
dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
dev_priv->display.enable_fbc = i8xx_enable_fbc;
dev_priv->display.disable_fbc = i8xx_disable_fbc;
@@ -4838,17 +4853,18 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.update_wm = g4x_update_wm;
else if (IS_I965G(dev))
dev_priv->display.update_wm = i965_update_wm;
- else if (IS_I9XX(dev) || IS_MOBILE(dev)) {
+ else if (IS_I9XX(dev)) {
dev_priv->display.update_wm = i9xx_update_wm;
dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+ } else if (IS_I85X(dev)) {
+ dev_priv->display.update_wm = i9xx_update_wm;
+ dev_priv->display.get_fifo_size = i85x_get_fifo_size;
} else {
- if (IS_I85X(dev))
- dev_priv->display.get_fifo_size = i85x_get_fifo_size;
- else if (IS_845G(dev))
+ dev_priv->display.update_wm = i830_update_wm;
+ if (IS_845G(dev))
dev_priv->display.get_fifo_size = i845_get_fifo_size;
else
dev_priv->display.get_fifo_size = i830_get_fifo_size;
- dev_priv->display.update_wm = i830_update_wm;
}
}
@@ -4942,7 +4958,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
if (dev_priv->pwrctx) {
struct drm_i915_gem_object *obj_priv;
- obj_priv = dev_priv->pwrctx->driver_private;
+ obj_priv = to_intel_bo(dev_priv->pwrctx);
I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);
I915_READ(PWRCTXA);
i915_gem_object_unpin(dev_priv->pwrctx);
@@ -4963,9 +4979,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
*/
struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
- return &intel_output->enc;
+ return &intel_encoder->enc;
}
/*
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3ef3a0d0edd..77e40cfcf21 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -26,6 +26,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "drm_crtc.h"
@@ -54,23 +55,23 @@ struct intel_dp_priv {
uint8_t link_bw;
uint8_t lane_count;
uint8_t dpcd[4];
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct i2c_adapter adapter;
struct i2c_algo_dp_aux_data algo;
};
static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);
static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP);
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);
void
-intel_edp_link_config (struct intel_output *intel_output,
+intel_edp_link_config (struct intel_encoder *intel_encoder,
int *lane_num, int *link_bw)
{
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
*lane_num = dp_priv->lane_count;
if (dp_priv->link_bw == DP_LINK_BW_1_62)
@@ -80,9 +81,9 @@ intel_edp_link_config (struct intel_output *intel_output,
}
static int
-intel_dp_max_lane_count(struct intel_output *intel_output)
+intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
{
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int max_lane_count = 4;
if (dp_priv->dpcd[0] >= 0x11) {
@@ -98,9 +99,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output)
}
static int
-intel_dp_max_link_bw(struct intel_output *intel_output)
+intel_dp_max_link_bw(struct intel_encoder *intel_encoder)
{
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int max_link_bw = dp_priv->dpcd[1];
switch (max_link_bw) {
@@ -126,11 +127,11 @@ intel_dp_link_clock(uint8_t link_bw)
/* I think this is a fiction */
static int
intel_dp_link_required(struct drm_device *dev,
- struct intel_output *intel_output, int pixel_clock)
+ struct intel_encoder *intel_encoder, int pixel_clock)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (IS_eDP(intel_output))
+ if (IS_eDP(intel_encoder))
return (pixel_clock * dev_priv->edp_bpp) / 8;
else
return pixel_clock * 3;
@@ -140,11 +141,11 @@ static int
intel_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- struct intel_output *intel_output = to_intel_output(connector);
- int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
- int max_lanes = intel_dp_max_lane_count(intel_output);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
+ int max_lanes = intel_dp_max_lane_count(intel_encoder);
- if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
+ if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
> max_link_clock * max_lanes)
return MODE_CLOCK_HIGH;
@@ -208,13 +209,13 @@ intel_hrawclk(struct drm_device *dev)
}
static int
-intel_dp_aux_ch(struct intel_output *intel_output,
+intel_dp_aux_ch(struct intel_encoder *intel_encoder,
uint8_t *send, int send_bytes,
uint8_t *recv, int recv_size)
{
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint32_t output_reg = dp_priv->output_reg;
- struct drm_device *dev = intel_output->base.dev;
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t ch_ctl = output_reg + 0x10;
uint32_t ch_data = ch_ctl + 4;
@@ -229,7 +230,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
* and would like to run at 2MHz. So, take the
* hrawclk value and divide by 2 and use that
*/
- if (IS_eDP(intel_output))
+ if (IS_eDP(intel_encoder))
aux_clock_divider = 225; /* eDP input clock at 450Mhz */
else if (HAS_PCH_SPLIT(dev))
aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
@@ -312,7 +313,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
/* Write data to the aux channel in native mode */
static int
-intel_dp_aux_native_write(struct intel_output *intel_output,
+intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
uint16_t address, uint8_t *send, int send_bytes)
{
int ret;
@@ -329,7 +330,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
memcpy(&msg[4], send, send_bytes);
msg_bytes = send_bytes + 4;
for (;;) {
- ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1);
+ ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);
if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
@@ -344,15 +345,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
/* Write a single byte to the aux channel in native mode */
static int
-intel_dp_aux_native_write_1(struct intel_output *intel_output,
+intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,
uint16_t address, uint8_t byte)
{
- return intel_dp_aux_native_write(intel_output, address, &byte, 1);
+ return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);
}
/* read bytes from a native aux channel */
static int
-intel_dp_aux_native_read(struct intel_output *intel_output,
+intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
uint16_t address, uint8_t *recv, int recv_bytes)
{
uint8_t msg[4];
@@ -371,7 +372,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
reply_bytes = recv_bytes + 1;
for (;;) {
- ret = intel_dp_aux_ch(intel_output, msg, msg_bytes,
+ ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,
reply, reply_bytes);
if (ret == 0)
return -EPROTO;
@@ -397,7 +398,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
struct intel_dp_priv *dp_priv = container_of(adapter,
struct intel_dp_priv,
adapter);
- struct intel_output *intel_output = dp_priv->intel_output;
+ struct intel_encoder *intel_encoder = dp_priv->intel_encoder;
uint16_t address = algo_data->address;
uint8_t msg[5];
uint8_t reply[2];
@@ -436,7 +437,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
}
for (;;) {
- ret = intel_dp_aux_ch(intel_output,
+ ret = intel_dp_aux_ch(intel_encoder,
msg, msg_bytes,
reply, reply_bytes);
if (ret < 0) {
@@ -464,9 +465,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
}
static int
-intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
+intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name)
{
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
DRM_DEBUG_KMS("i2c_init %s\n", name);
dp_priv->algo.running = false;
@@ -479,7 +480,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
dp_priv->adapter.algo_data = &dp_priv->algo;
- dp_priv->adapter.dev.parent = &intel_output->base.kdev;
+ dp_priv->adapter.dev.parent = &intel_encoder->base.kdev;
return i2c_dp_aux_add_bus(&dp_priv->adapter);
}
@@ -488,18 +489,18 @@ static bool
intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int lane_count, clock;
- int max_lane_count = intel_dp_max_lane_count(intel_output);
- int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0;
+ int max_lane_count = intel_dp_max_lane_count(intel_encoder);
+ int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
- if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
+ if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
<= link_avail) {
dp_priv->link_bw = bws[clock];
dp_priv->lane_count = lane_count;
@@ -561,16 +562,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct intel_dp_m_n m_n;
/*
- * Find the lane count in the intel_output private
+ * Find the lane count in the intel_encoder private
*/
list_for_each_entry(connector, &mode_config->connector_list, head) {
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
if (!connector->encoder || connector->encoder->crtc != crtc)
continue;
- if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) {
+ if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
lane_count = dp_priv->lane_count;
break;
}
@@ -625,9 +626,9 @@ static void
intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
- struct drm_crtc *crtc = intel_output->enc.crtc;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ struct drm_crtc *crtc = intel_encoder->enc.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
dp_priv->DP = (DP_LINK_TRAIN_OFF |
@@ -666,7 +667,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
if (intel_crtc->pipe == 1)
dp_priv->DP |= DP_PIPEB_SELECT;
- if (IS_eDP(intel_output)) {
+ if (IS_eDP(intel_encoder)) {
/* don't miss out required setting for eDP */
dp_priv->DP |= DP_PLL_ENABLE;
if (adjusted_mode->clock < 200000)
@@ -701,22 +702,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)
static void
intel_dp_dpms(struct drm_encoder *encoder, int mode)
{
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
- struct drm_device *dev = intel_output->base.dev;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t dp_reg = I915_READ(dp_priv->output_reg);
if (mode != DRM_MODE_DPMS_ON) {
if (dp_reg & DP_PORT_EN) {
- intel_dp_link_down(intel_output, dp_priv->DP);
- if (IS_eDP(intel_output))
+ intel_dp_link_down(intel_encoder, dp_priv->DP);
+ if (IS_eDP(intel_encoder))
ironlake_edp_backlight_off(dev);
}
} else {
if (!(dp_reg & DP_PORT_EN)) {
- intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
- if (IS_eDP(intel_output))
+ intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
+ if (IS_eDP(intel_encoder))
ironlake_edp_backlight_on(dev);
}
}
@@ -728,12 +729,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
* link status information
*/
static bool
-intel_dp_get_link_status(struct intel_output *intel_output,
+intel_dp_get_link_status(struct intel_encoder *intel_encoder,
uint8_t link_status[DP_LINK_STATUS_SIZE])
{
int ret;
- ret = intel_dp_aux_native_read(intel_output,
+ ret = intel_dp_aux_native_read(intel_encoder,
DP_LANE0_1_STATUS,
link_status, DP_LINK_STATUS_SIZE);
if (ret != DP_LINK_STATUS_SIZE)
@@ -751,13 +752,13 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
static void
intel_dp_save(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct drm_device *dev = intel_output->base.dev;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
dp_priv->save_DP = I915_READ(dp_priv->output_reg);
- intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET,
+ intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET,
dp_priv->save_link_configuration,
sizeof (dp_priv->save_link_configuration));
}
@@ -824,7 +825,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
}
static void
-intel_get_adjust_train(struct intel_output *intel_output,
+intel_get_adjust_train(struct intel_encoder *intel_encoder,
uint8_t link_status[DP_LINK_STATUS_SIZE],
int lane_count,
uint8_t train_set[4])
@@ -941,15 +942,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
}
static bool
-intel_dp_set_link_train(struct intel_output *intel_output,
+intel_dp_set_link_train(struct intel_encoder *intel_encoder,
uint32_t dp_reg_value,
uint8_t dp_train_pat,
uint8_t train_set[4],
bool first)
{
- struct drm_device *dev = intel_output->base.dev;
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
int ret;
I915_WRITE(dp_priv->output_reg, dp_reg_value);
@@ -957,11 +958,11 @@ intel_dp_set_link_train(struct intel_output *intel_output,
if (first)
intel_wait_for_vblank(dev);
- intel_dp_aux_native_write_1(intel_output,
+ intel_dp_aux_native_write_1(intel_encoder,
DP_TRAINING_PATTERN_SET,
dp_train_pat);
- ret = intel_dp_aux_native_write(intel_output,
+ ret = intel_dp_aux_native_write(intel_encoder,
DP_TRAINING_LANE0_SET, train_set, 4);
if (ret != 4)
return false;
@@ -970,12 +971,12 @@ intel_dp_set_link_train(struct intel_output *intel_output,
}
static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])
{
- struct drm_device *dev = intel_output->base.dev;
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint8_t train_set[4];
uint8_t link_status[DP_LINK_STATUS_SIZE];
int i;
@@ -986,7 +987,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
int tries;
/* Write the link configuration data */
- intel_dp_aux_native_write(intel_output, 0x100,
+ intel_dp_aux_native_write(intel_encoder, 0x100,
link_configuration, DP_LINK_CONFIGURATION_SIZE);
DP |= DP_PORT_EN;
@@ -1000,14 +1001,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
- if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1,
+ if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1,
DP_TRAINING_PATTERN_1, train_set, first))
break;
first = false;
/* Set training pattern 1 */
udelay(100);
- if (!intel_dp_get_link_status(intel_output, link_status))
+ if (!intel_dp_get_link_status(intel_encoder, link_status))
break;
if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) {
@@ -1032,7 +1033,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
/* Compute new train_set as requested by target */
- intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+ intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
}
/* channel equalization */
@@ -1044,13 +1045,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
/* channel eq pattern */
- if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2,
+ if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2,
DP_TRAINING_PATTERN_2, train_set,
false))
break;
udelay(400);
- if (!intel_dp_get_link_status(intel_output, link_status))
+ if (!intel_dp_get_link_status(intel_encoder, link_status))
break;
if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) {
@@ -1063,26 +1064,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
break;
/* Compute new train_set as requested by target */
- intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+ intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
++tries;
}
I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF);
POSTING_READ(dp_priv->output_reg);
- intel_dp_aux_native_write_1(intel_output,
+ intel_dp_aux_native_write_1(intel_encoder,
DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
}
static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
{
- struct drm_device *dev = intel_output->base.dev;
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
DRM_DEBUG_KMS("\n");
- if (IS_eDP(intel_output)) {
+ if (IS_eDP(intel_encoder)) {
DP &= ~DP_PLL_ENABLE;
I915_WRITE(dp_priv->output_reg, DP);
POSTING_READ(dp_priv->output_reg);
@@ -1095,7 +1096,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
udelay(17000);
- if (IS_eDP(intel_output))
+ if (IS_eDP(intel_encoder))
DP |= DP_LINK_TRAIN_OFF;
I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
POSTING_READ(dp_priv->output_reg);
@@ -1104,13 +1105,13 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
static void
intel_dp_restore(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
if (dp_priv->save_DP & DP_PORT_EN)
- intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration);
+ intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration);
else
- intel_dp_link_down(intel_output, dp_priv->save_DP);
+ intel_dp_link_down(intel_encoder, dp_priv->save_DP);
}
/*
@@ -1123,32 +1124,32 @@ intel_dp_restore(struct drm_connector *connector)
*/
static void
-intel_dp_check_link_status(struct intel_output *intel_output)
+intel_dp_check_link_status(struct intel_encoder *intel_encoder)
{
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint8_t link_status[DP_LINK_STATUS_SIZE];
- if (!intel_output->enc.crtc)
+ if (!intel_encoder->enc.crtc)
return;
- if (!intel_dp_get_link_status(intel_output, link_status)) {
- intel_dp_link_down(intel_output, dp_priv->DP);
+ if (!intel_dp_get_link_status(intel_encoder, link_status)) {
+ intel_dp_link_down(intel_encoder, dp_priv->DP);
return;
}
if (!intel_channel_eq_ok(link_status, dp_priv->lane_count))
- intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
+ intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
}
static enum drm_connector_status
ironlake_dp_detect(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
enum drm_connector_status status;
status = connector_status_disconnected;
- if (intel_dp_aux_native_read(intel_output,
+ if (intel_dp_aux_native_read(intel_encoder,
0x000, dp_priv->dpcd,
sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
{
@@ -1167,10 +1168,10 @@ ironlake_dp_detect(struct drm_connector *connector)
static enum drm_connector_status
intel_dp_detect(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct drm_device *dev = intel_output->base.dev;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
uint32_t temp, bit;
enum drm_connector_status status;
@@ -1209,7 +1210,7 @@ intel_dp_detect(struct drm_connector *connector)
return connector_status_disconnected;
status = connector_status_disconnected;
- if (intel_dp_aux_native_read(intel_output,
+ if (intel_dp_aux_native_read(intel_encoder,
0x000, dp_priv->dpcd,
sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
{
@@ -1221,20 +1222,20 @@ intel_dp_detect(struct drm_connector *connector)
static int intel_dp_get_modes(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct drm_device *dev = intel_output->base.dev;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
/* We should parse the EDID data and find out if it has an audio sink
*/
- ret = intel_ddc_get_modes(intel_output);
+ ret = intel_ddc_get_modes(intel_encoder);
if (ret)
return ret;
/* if eDP has no EDID, try to use fixed panel mode from VBT */
- if (IS_eDP(intel_output)) {
+ if (IS_eDP(intel_encoder)) {
if (dev_priv->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1248,13 +1249,13 @@ static int intel_dp_get_modes(struct drm_connector *connector)
static void
intel_dp_destroy (struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
- if (intel_output->i2c_bus)
- intel_i2c_destroy(intel_output->i2c_bus);
+ if (intel_encoder->i2c_bus)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
- kfree(intel_output);
+ kfree(intel_encoder);
}
static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
@@ -1290,12 +1291,12 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
};
void
-intel_dp_hot_plug(struct intel_output *intel_output)
+intel_dp_hot_plug(struct intel_encoder *intel_encoder)
{
- struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
- intel_dp_check_link_status(intel_output);
+ intel_dp_check_link_status(intel_encoder);
}
void
@@ -1303,53 +1304,53 @@ intel_dp_init(struct drm_device *dev, int output_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct intel_dp_priv *dp_priv;
const char *name = NULL;
- intel_output = kcalloc(sizeof(struct intel_output) +
+ intel_encoder = kcalloc(sizeof(struct intel_encoder) +
sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
- if (!intel_output)
+ if (!intel_encoder)
return;
- dp_priv = (struct intel_dp_priv *)(intel_output + 1);
+ dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
- connector = &intel_output->base;
+ connector = &intel_encoder->base;
drm_connector_init(dev, connector, &intel_dp_connector_funcs,
DRM_MODE_CONNECTOR_DisplayPort);
drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
if (output_reg == DP_A)
- intel_output->type = INTEL_OUTPUT_EDP;
+ intel_encoder->type = INTEL_OUTPUT_EDP;
else
- intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+ intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
if (output_reg == DP_B || output_reg == PCH_DP_B)
- intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
+ intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
else if (output_reg == DP_C || output_reg == PCH_DP_C)
- intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
+ intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
else if (output_reg == DP_D || output_reg == PCH_DP_D)
- intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
+ intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
- if (IS_eDP(intel_output))
- intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
+ if (IS_eDP(intel_encoder))
+ intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
- intel_output->crtc_mask = (1 << 0) | (1 << 1);
+ intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
connector->interlace_allowed = true;
connector->doublescan_allowed = 0;
- dp_priv->intel_output = intel_output;
+ dp_priv->intel_encoder = intel_encoder;
dp_priv->output_reg = output_reg;
dp_priv->has_audio = false;
dp_priv->dpms_mode = DRM_MODE_DPMS_ON;
- intel_output->dev_priv = dp_priv;
+ intel_encoder->dev_priv = dp_priv;
- drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs,
+ drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs,
DRM_MODE_ENCODER_TMDS);
- drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs);
+ drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs);
- drm_mode_connector_attach_encoder(&intel_output->base,
- &intel_output->enc);
+ drm_mode_connector_attach_encoder(&intel_encoder->base,
+ &intel_encoder->enc);
drm_sysfs_connector_add(connector);
/* Set up the DDC bus. */
@@ -1377,10 +1378,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
break;
}
- intel_dp_i2c_init(intel_output, name);
+ intel_dp_i2c_init(intel_encoder, name);
- intel_output->ddc_bus = &dp_priv->adapter;
- intel_output->hot_plug = intel_dp_hot_plug;
+ intel_encoder->ddc_bus = &dp_priv->adapter;
+ intel_encoder->hot_plug = intel_dp_hot_plug;
if (output_reg == DP_A) {
/* initialize panel mode from VBT if available for eDP */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3a467ca5785..e30253755f1 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -95,7 +95,7 @@ struct intel_framebuffer {
};
-struct intel_output {
+struct intel_encoder {
struct drm_connector base;
struct drm_encoder enc;
@@ -105,7 +105,7 @@ struct intel_output {
bool load_detect_temp;
bool needs_tv_clock;
void *dev_priv;
- void (*hot_plug)(struct intel_output *);
+ void (*hot_plug)(struct intel_encoder *);
int crtc_mask;
int clone_mask;
};
@@ -152,15 +152,15 @@ struct intel_crtc {
};
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
-#define to_intel_output(x) container_of(x, struct intel_output, base)
-#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
+#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
+#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
const char *name);
void intel_i2c_destroy(struct i2c_adapter *adapter);
-int intel_ddc_get_modes(struct intel_output *intel_output);
-extern bool intel_ddc_probe(struct intel_output *intel_output);
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder);
+extern bool intel_ddc_probe(struct intel_encoder *intel_encoder);
void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
void intel_i2c_reset_gmbus(struct drm_device *dev);
@@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);
void
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
-extern void intel_edp_link_config (struct intel_output *, int *, int *);
+extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
extern int intel_panel_fitter_pipe (struct drm_device *dev);
@@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern void intel_wait_for_vblank(struct drm_device *dev);
extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
-extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
+extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
struct drm_display_mode *mode,
int *dpms_mode);
-extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
+extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
int dpms_mode);
extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index a4d2606de77..ebf213c96b9 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -25,6 +25,7 @@
* Eric Anholt <eric@anholt.net>
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "drm_crtc.h"
@@ -79,8 +80,8 @@ static struct intel_dvo_device intel_dvo_devices[] = {
static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_i915_private *dev_priv = encoder->dev->dev_private;
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
u32 dvo_reg = dvo->dvo_reg;
u32 temp = I915_READ(dvo_reg);
@@ -98,8 +99,8 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
static void intel_dvo_save(struct drm_connector *connector)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
/* Each output should probably just save the registers it touches,
* but for now, use more overkill.
@@ -114,8 +115,8 @@ static void intel_dvo_save(struct drm_connector *connector)
static void intel_dvo_restore(struct drm_connector *connector)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
dvo->dev_ops->restore(dvo);
@@ -127,8 +128,8 @@ static void intel_dvo_restore(struct drm_connector *connector)
static int intel_dvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
@@ -149,8 +150,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
/* If we have timings from the BIOS for the panel, put them in
* to the adjusted mode. The CRTC will be set up for this mode,
@@ -185,8 +186,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
int pipe = intel_crtc->pipe;
u32 dvo_val;
u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
@@ -240,23 +241,23 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
*/
static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
return dvo->dev_ops->detect(dvo);
}
static int intel_dvo_get_modes(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
/* We should probably have an i2c driver get_modes function for those
* devices which will have a fixed set of modes determined by the chip
* (TV-out, for example), but for now with just TMDS and LVDS,
* that's not the case.
*/
- intel_ddc_get_modes(intel_output);
+ intel_ddc_get_modes(intel_encoder);
if (!list_empty(&connector->probed_modes))
return 1;
@@ -274,8 +275,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
static void intel_dvo_destroy (struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
if (dvo) {
if (dvo->dev_ops->destroy)
@@ -285,13 +286,13 @@ static void intel_dvo_destroy (struct drm_connector *connector)
/* no need, in i830_dvoices[] now */
//kfree(dvo);
}
- if (intel_output->i2c_bus)
- intel_i2c_destroy(intel_output->i2c_bus);
- if (intel_output->ddc_bus)
- intel_i2c_destroy(intel_output->ddc_bus);
+ if (intel_encoder->i2c_bus)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
+ if (intel_encoder->ddc_bus)
+ intel_i2c_destroy(intel_encoder->ddc_bus);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
- kfree(intel_output);
+ kfree(intel_encoder);
}
#ifdef RANDR_GET_CRTC_INTERFACE
@@ -299,8 +300,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
return intel_pipe_to_crtc(pScrn, pipe);
@@ -351,8 +352,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_dvo_device *dvo = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_dvo_device *dvo = intel_encoder->dev_priv;
uint32_t dvo_reg = dvo->dvo_reg;
uint32_t dvo_val = I915_READ(dvo_reg);
struct drm_display_mode *mode = NULL;
@@ -382,24 +383,24 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
void intel_dvo_init(struct drm_device *dev)
{
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct intel_dvo_device *dvo;
struct i2c_adapter *i2cbus = NULL;
int ret = 0;
int i;
int encoder_type = DRM_MODE_ENCODER_NONE;
- intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
- if (!intel_output)
+ intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL);
+ if (!intel_encoder)
return;
/* Set up the DDC bus */
- intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
- if (!intel_output->ddc_bus)
+ intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
+ if (!intel_encoder->ddc_bus)
goto free_intel;
/* Now, try to find a controller */
for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
- struct drm_connector *connector = &intel_output->base;
+ struct drm_connector *connector = &intel_encoder->base;
int gpio;
dvo = &intel_dvo_devices[i];
@@ -434,11 +435,11 @@ void intel_dvo_init(struct drm_device *dev)
if (!ret)
continue;
- intel_output->type = INTEL_OUTPUT_DVO;
- intel_output->crtc_mask = (1 << 0) | (1 << 1);
+ intel_encoder->type = INTEL_OUTPUT_DVO;
+ intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
switch (dvo->type) {
case INTEL_DVO_CHIP_TMDS:
- intel_output->clone_mask =
+ intel_encoder->clone_mask =
(1 << INTEL_DVO_TMDS_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
drm_connector_init(dev, connector,
@@ -447,7 +448,7 @@ void intel_dvo_init(struct drm_device *dev)
encoder_type = DRM_MODE_ENCODER_TMDS;
break;
case INTEL_DVO_CHIP_LVDS:
- intel_output->clone_mask =
+ intel_encoder->clone_mask =
(1 << INTEL_DVO_LVDS_CLONE_BIT);
drm_connector_init(dev, connector,
&intel_dvo_connector_funcs,
@@ -462,16 +463,16 @@ void intel_dvo_init(struct drm_device *dev)
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
- intel_output->dev_priv = dvo;
- intel_output->i2c_bus = i2cbus;
+ intel_encoder->dev_priv = dvo;
+ intel_encoder->i2c_bus = i2cbus;
- drm_encoder_init(dev, &intel_output->enc,
+ drm_encoder_init(dev, &intel_encoder->enc,
&intel_dvo_enc_funcs, encoder_type);
- drm_encoder_helper_add(&intel_output->enc,
+ drm_encoder_helper_add(&intel_encoder->enc,
&intel_dvo_helper_funcs);
- drm_mode_connector_attach_encoder(&intel_output->base,
- &intel_output->enc);
+ drm_mode_connector_attach_encoder(&intel_encoder->base,
+ &intel_encoder->enc);
if (dvo->type == INTEL_DVO_CHIP_LVDS) {
/* For our LVDS chipsets, we should hopefully be able
* to dig the fixed panel mode out of the BIOS data.
@@ -489,10 +490,10 @@ void intel_dvo_init(struct drm_device *dev)
return;
}
- intel_i2c_destroy(intel_output->ddc_bus);
+ intel_i2c_destroy(intel_encoder->ddc_bus);
/* Didn't find a chip, so tear down. */
if (i2cbus != NULL)
intel_i2c_destroy(i2cbus);
free_intel:
- kfree(intel_output);
+ kfree(intel_encoder);
}
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 8cd791dc5b2..8a0b3bcdc7b 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -30,7 +30,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/slab.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
#include <linux/fb.h>
@@ -145,7 +144,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
ret = -ENOMEM;
goto out;
}
- obj_priv = fbo->driver_private;
+ obj_priv = to_intel_bo(fbo);
mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index a30f8bfc198..48cade0cf7b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -27,6 +27,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "drmP.h"
#include "drm.h"
@@ -50,8 +51,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
u32 sdvox;
sdvox = SDVO_ENCODING_HDMI |
@@ -73,8 +74,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
u32 temp;
temp = I915_READ(hdmi_priv->sdvox_reg);
@@ -109,8 +110,8 @@ static void intel_hdmi_save(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg);
}
@@ -119,8 +120,8 @@ static void intel_hdmi_restore(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX);
POSTING_READ(hdmi_priv->sdvox_reg);
@@ -150,21 +151,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
struct edid *edid = NULL;
enum drm_connector_status status = connector_status_disconnected;
hdmi_priv->has_hdmi_sink = false;
- edid = drm_get_edid(&intel_output->base,
- intel_output->ddc_bus);
+ edid = drm_get_edid(&intel_encoder->base,
+ intel_encoder->ddc_bus);
if (edid) {
if (edid->input & DRM_EDID_INPUT_DIGITAL) {
status = connector_status_connected;
hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
}
- intel_output->base.display_info.raw_edid = NULL;
+ intel_encoder->base.display_info.raw_edid = NULL;
kfree(edid);
}
@@ -173,24 +174,24 @@ intel_hdmi_detect(struct drm_connector *connector)
static int intel_hdmi_get_modes(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
/* We should parse the EDID data and find out if it's an HDMI sink so
* we can send audio to it.
*/
- return intel_ddc_get_modes(intel_output);
+ return intel_ddc_get_modes(intel_encoder);
}
static void intel_hdmi_destroy(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
- if (intel_output->i2c_bus)
- intel_i2c_destroy(intel_output->i2c_bus);
+ if (intel_encoder->i2c_bus)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
- kfree(intel_output);
+ kfree(intel_encoder);
}
static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
@@ -229,63 +230,63 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct intel_hdmi_priv *hdmi_priv;
- intel_output = kcalloc(sizeof(struct intel_output) +
+ intel_encoder = kcalloc(sizeof(struct intel_encoder) +
sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
- if (!intel_output)
+ if (!intel_encoder)
return;
- hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1);
+ hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
- connector = &intel_output->base;
+ connector = &intel_encoder->base;
drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);
drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
- intel_output->type = INTEL_OUTPUT_HDMI;
+ intel_encoder->type = INTEL_OUTPUT_HDMI;
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
- intel_output->crtc_mask = (1 << 0) | (1 << 1);
+ intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
/* Set up the DDC bus. */
if (sdvox_reg == SDVOB) {
- intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
- intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
+ intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
+ intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
} else if (sdvox_reg == SDVOC) {
- intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
- intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
+ intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
+ intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
} else if (sdvox_reg == HDMIB) {
- intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
- intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
+ intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
+ intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
"HDMIB");
dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
} else if (sdvox_reg == HDMIC) {
- intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
- intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
+ intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
+ intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
"HDMIC");
dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
} else if (sdvox_reg == HDMID) {
- intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
- intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
+ intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
+ intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
"HDMID");
dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
}
- if (!intel_output->ddc_bus)
+ if (!intel_encoder->ddc_bus)
goto err_connector;
hdmi_priv->sdvox_reg = sdvox_reg;
- intel_output->dev_priv = hdmi_priv;
+ intel_encoder->dev_priv = hdmi_priv;
- drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs,
+ drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,
DRM_MODE_ENCODER_TMDS);
- drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs);
+ drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs);
- drm_mode_connector_attach_encoder(&intel_output->base,
- &intel_output->enc);
+ drm_mode_connector_attach_encoder(&intel_encoder->base,
+ &intel_encoder->enc);
drm_sysfs_connector_add(connector);
/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
@@ -301,7 +302,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
err_connector:
drm_connector_cleanup(connector);
- kfree(intel_output);
+ kfree(intel_encoder);
return;
}
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index fcc753ca5d9..c2649c7df14 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -26,6 +26,7 @@
* Eric Anholt <eric@anholt.net>
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
#include "drmP.h"
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 14e516fdc2d..b66806a37d3 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -30,6 +30,7 @@
#include <acpi/button.h>
#include <linux/dmi.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "drm_crtc.h"
@@ -238,8 +239,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct drm_encoder *tmp_encoder;
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
u32 pfit_control = 0, pfit_pgm_ratios = 0;
int left_border = 0, right_border = 0, top_border = 0;
int bottom_border = 0;
@@ -586,8 +587,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
/*
* The LVDS pin pair will already have been turned on in the
@@ -607,53 +608,6 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control);
}
-/* Some lid devices report incorrect lid status, assume they're connected */
-static const struct dmi_system_id bad_lid_status[] = {
- {
- .ident = "Compaq nx9020",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
- DMI_MATCH(DMI_BOARD_NAME, "3084"),
- },
- },
- {
- .ident = "Samsung SX20S",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
- DMI_MATCH(DMI_BOARD_NAME, "SX20S"),
- },
- },
- {
- .ident = "Aspire One",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"),
- },
- },
- {
- .ident = "Aspire 1810T",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1810T"),
- },
- },
- {
- .ident = "PC-81005",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "MALATA"),
- DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"),
- },
- },
- {
- .ident = "Clevo M5x0N",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
- DMI_MATCH(DMI_BOARD_NAME, "M5x0N"),
- },
- },
- { }
-};
-
/**
* Detect the LVDS connection.
*
@@ -669,12 +623,9 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
/* ACPI lid methods were generally unreliable in this generation, so
* don't even bother.
*/
- if (IS_GEN2(dev))
+ if (IS_GEN2(dev) || IS_GEN3(dev))
return connector_status_connected;
- if (!dmi_check_system(bad_lid_status) && !acpi_lid_open())
- status = connector_status_disconnected;
-
return status;
}
@@ -684,14 +635,16 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
static int intel_lvds_get_modes(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
- ret = intel_ddc_get_modes(intel_output);
+ if (dev_priv->lvds_edid_good) {
+ ret = intel_ddc_get_modes(intel_encoder);
- if (ret)
- return ret;
+ if (ret)
+ return ret;
+ }
/* Didn't get an EDID, so
* Set wide sync ranges so we get all modes
@@ -764,11 +717,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
static void intel_lvds_destroy(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
struct drm_i915_private *dev_priv = dev->dev_private;
- if (intel_output->ddc_bus)
- intel_i2c_destroy(intel_output->ddc_bus);
+ if (intel_encoder->ddc_bus)
+ intel_i2c_destroy(intel_encoder->ddc_bus);
if (dev_priv->lid_notifier.notifier_call)
acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
drm_sysfs_connector_remove(connector);
@@ -781,13 +734,13 @@ static int intel_lvds_set_property(struct drm_connector *connector,
uint64_t value)
{
struct drm_device *dev = connector->dev;
- struct intel_output *intel_output =
- to_intel_output(connector);
+ struct intel_encoder *intel_encoder =
+ to_intel_encoder(connector);
if (property == dev->mode_config.scaling_mode_property &&
connector->encoder) {
struct drm_crtc *crtc = connector->encoder->crtc;
- struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+ struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
if (value == DRM_MODE_SCALE_NONE) {
DRM_DEBUG_KMS("no scaling not supported\n");
return 0;
@@ -907,6 +860,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
},
},
+ {
+ .callback = intel_no_lvds_dmi_callback,
+ .ident = "Clientron U800",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
+ },
+ },
{ } /* terminating entry */
};
@@ -1017,7 +978,7 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)
void intel_lvds_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_display_mode *scan; /* *modes, *bios_mode; */
@@ -1045,40 +1006,40 @@ void intel_lvds_init(struct drm_device *dev)
gpio = PCH_GPIOC;
}
- intel_output = kzalloc(sizeof(struct intel_output) +
+ intel_encoder = kzalloc(sizeof(struct intel_encoder) +
sizeof(struct intel_lvds_priv), GFP_KERNEL);
- if (!intel_output) {
+ if (!intel_encoder) {
return;
}
- connector = &intel_output->base;
- encoder = &intel_output->enc;
- drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
+ connector = &intel_encoder->base;
+ encoder = &intel_encoder->enc;
+ drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs,
DRM_MODE_CONNECTOR_LVDS);
- drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
+ drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs,
DRM_MODE_ENCODER_LVDS);
- drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
- intel_output->type = INTEL_OUTPUT_LVDS;
+ drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+ intel_encoder->type = INTEL_OUTPUT_LVDS;
- intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
- intel_output->crtc_mask = (1 << 1);
+ intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
+ intel_encoder->crtc_mask = (1 << 1);
drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
- lvds_priv = (struct intel_lvds_priv *)(intel_output + 1);
- intel_output->dev_priv = lvds_priv;
+ lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
+ intel_encoder->dev_priv = lvds_priv;
/* create the scaling mode property */
drm_mode_create_scaling_mode_property(dev);
/*
* the initial panel fitting mode will be FULL_SCREEN.
*/
- drm_connector_attach_property(&intel_output->base,
+ drm_connector_attach_property(&intel_encoder->base,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_FULLSCREEN);
lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN;
@@ -1093,8 +1054,8 @@ void intel_lvds_init(struct drm_device *dev)
*/
/* Set up the DDC bus. */
- intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
- if (!intel_output->ddc_bus) {
+ intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
+ if (!intel_encoder->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n");
goto failed;
@@ -1104,7 +1065,10 @@ void intel_lvds_init(struct drm_device *dev)
* Attempt to get the fixed panel mode from DDC. Assume that the
* preferred mode is the right one.
*/
- intel_ddc_get_modes(intel_output);
+ dev_priv->lvds_edid_good = true;
+
+ if (!intel_ddc_get_modes(intel_encoder))
+ dev_priv->lvds_edid_good = false;
list_for_each_entry(scan, &connector->probed_modes, head) {
mutex_lock(&dev->mode_config.mutex);
@@ -1182,9 +1146,9 @@ out:
failed:
DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
- if (intel_output->ddc_bus)
- intel_i2c_destroy(intel_output->ddc_bus);
+ if (intel_encoder->ddc_bus)
+ intel_i2c_destroy(intel_encoder->ddc_bus);
drm_connector_cleanup(connector);
drm_encoder_cleanup(encoder);
- kfree(intel_output);
+ kfree(intel_encoder);
}
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
index 67e2f4632a2..8e5c83b2d12 100644
--- a/drivers/gpu/drm/i915/intel_modes.c
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -23,6 +23,7 @@
* DEALINGS IN THE SOFTWARE.
*/
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/fb.h>
#include "drmP.h"
@@ -33,7 +34,7 @@
* intel_ddc_probe
*
*/
-bool intel_ddc_probe(struct intel_output *intel_output)
+bool intel_ddc_probe(struct intel_encoder *intel_encoder)
{
u8 out_buf[] = { 0x0, 0x0};
u8 buf[2];
@@ -53,9 +54,9 @@ bool intel_ddc_probe(struct intel_output *intel_output)
}
};
- intel_i2c_quirk_set(intel_output->base.dev, true);
- ret = i2c_transfer(intel_output->ddc_bus, msgs, 2);
- intel_i2c_quirk_set(intel_output->base.dev, false);
+ intel_i2c_quirk_set(intel_encoder->base.dev, true);
+ ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2);
+ intel_i2c_quirk_set(intel_encoder->base.dev, false);
if (ret == 2)
return true;
@@ -68,19 +69,19 @@ bool intel_ddc_probe(struct intel_output *intel_output)
*
* Fetch the EDID information from @connector using the DDC bus.
*/
-int intel_ddc_get_modes(struct intel_output *intel_output)
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder)
{
struct edid *edid;
int ret = 0;
- intel_i2c_quirk_set(intel_output->base.dev, true);
- edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus);
- intel_i2c_quirk_set(intel_output->base.dev, false);
+ intel_i2c_quirk_set(intel_encoder->base.dev, true);
+ edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus);
+ intel_i2c_quirk_set(intel_encoder->base.dev, false);
if (edid) {
- drm_mode_connector_update_edid_property(&intel_output->base,
+ drm_mode_connector_update_edid_property(&intel_encoder->base,
edid);
- ret = drm_add_edid_modes(&intel_output->base, edid);
- intel_output->base.display_info.raw_edid = NULL;
+ ret = drm_add_edid_modes(&intel_encoder->base, edid);
+ intel_encoder->base.display_info.raw_edid = NULL;
kfree(edid);
}
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index d355d1d527e..6d524a1fc27 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -724,7 +724,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
int ret, tmp_width;
struct overlay_registers *regs;
bool scale_changed = false;
- struct drm_i915_gem_object *bo_priv = new_bo->driver_private;
+ struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);
struct drm_device *dev = overlay->dev;
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
@@ -809,7 +809,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
intel_overlay_continue(overlay, scale_changed);
overlay->old_vid_bo = overlay->vid_bo;
- overlay->vid_bo = new_bo->driver_private;
+ overlay->vid_bo = to_intel_bo(new_bo);
return 0;
@@ -1068,14 +1068,18 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
DRM_MODE_OBJECT_CRTC);
- if (!drmmode_obj)
- return -ENOENT;
+ if (!drmmode_obj) {
+ ret = -ENOENT;
+ goto out_free;
+ }
crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
new_bo = drm_gem_object_lookup(dev, file_priv,
put_image_rec->bo_handle);
- if (!new_bo)
- return -ENOENT;
+ if (!new_bo) {
+ ret = -ENOENT;
+ goto out_free;
+ }
mutex_lock(&dev->mode_config.mutex);
mutex_lock(&dev->struct_mutex);
@@ -1165,6 +1169,7 @@ out_unlock:
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&dev->mode_config.mutex);
drm_gem_object_unreference_unlocked(new_bo);
+out_free:
kfree(params);
return ret;
@@ -1339,7 +1344,7 @@ void intel_setup_overlay(struct drm_device *dev)
reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE);
if (!reg_bo)
goto out_free;
- overlay->reg_bo = reg_bo->driver_private;
+ overlay->reg_bo = to_intel_bo(reg_bo);
if (OVERLAY_NONPHYSICAL(dev)) {
ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 48daee5c9c6..87d953664cb 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -26,6 +26,7 @@
* Eric Anholt <eric@anholt.net>
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "drmP.h"
#include "drm.h"
@@ -53,7 +54,7 @@ struct intel_sdvo_priv {
u8 slave_addr;
/* Register for the SDVO device: SDVOB or SDVOC */
- int output_device;
+ int sdvo_reg;
/* Active outputs controlled by this SDVO output */
uint16_t controlled_output;
@@ -123,7 +124,7 @@ struct intel_sdvo_priv {
*/
struct intel_sdvo_encode encode;
- /* DDC bus used by this SDVO output */
+ /* DDC bus used by this SDVO encoder */
uint8_t ddc_bus;
/* Mac mini hack -- use the same DDC as the analog connector */
@@ -161,22 +162,22 @@ struct intel_sdvo_priv {
};
static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags);
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags);
/**
* Writes the SDVOB or SDVOC with the given value, but always writes both
* SDVOB and SDVOC to work around apparent hardware issues (according to
* comments in the BIOS).
*/
-static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
+static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
{
- struct drm_device *dev = intel_output->base.dev;
+ struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u32 bval = val, cval = val;
int i;
- if (sdvo_priv->output_device == SDVOB) {
+ if (sdvo_priv->sdvo_reg == SDVOB) {
cval = I915_READ(SDVOC);
} else {
bval = I915_READ(SDVOB);
@@ -195,10 +196,10 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
}
}
-static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
+static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
u8 *ch)
{
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u8 out_buf[2];
u8 buf[2];
int ret;
@@ -221,7 +222,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
out_buf[0] = addr;
out_buf[1] = 0;
- if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2)
+ if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)
{
*ch = buf[0];
return true;
@@ -231,10 +232,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
return false;
}
-static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
+static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
u8 ch)
{
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u8 out_buf[2];
struct i2c_msg msgs[] = {
{
@@ -248,7 +249,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
out_buf[0] = addr;
out_buf[1] = ch;
- if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1)
+ if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)
{
return true;
}
@@ -352,13 +353,13 @@ static const struct _sdvo_cmd_name {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
};
-#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
-#define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv)
+#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC")
+#define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv)
-static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
void *args, int args_len)
{
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int i;
DRM_DEBUG_KMS("%s: W: %02X ",
@@ -378,19 +379,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
DRM_LOG_KMS("\n");
}
-static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,
void *args, int args_len)
{
int i;
- intel_sdvo_debug_write(intel_output, cmd, args, args_len);
+ intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);
for (i = 0; i < args_len; i++) {
- intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i,
+ intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,
((u8*)args)[i]);
}
- intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
+ intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);
}
static const char *cmd_status_names[] = {
@@ -403,11 +404,11 @@ static const char *cmd_status_names[] = {
"Scaling not supported"
};
-static void intel_sdvo_debug_response(struct intel_output *intel_output,
+static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
void *response, int response_len,
u8 status)
{
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int i;
DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
@@ -422,7 +423,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
DRM_LOG_KMS("\n");
}
-static u8 intel_sdvo_read_response(struct intel_output *intel_output,
+static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
void *response, int response_len)
{
int i;
@@ -432,16 +433,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output,
while (retry--) {
/* Read the command response */
for (i = 0; i < response_len; i++) {
- intel_sdvo_read_byte(intel_output,
+ intel_sdvo_read_byte(intel_encoder,
SDVO_I2C_RETURN_0 + i,
&((u8 *)response)[i]);
}
/* read the return status */
- intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS,
+ intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,
&status);
- intel_sdvo_debug_response(intel_output, response, response_len,
+ intel_sdvo_debug_response(intel_encoder, response, response_len,
status);
if (status != SDVO_CMD_STATUS_PENDING)
return status;
@@ -469,10 +470,10 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
* another I2C transaction after issuing the DDC bus switch, it will be
* switched to the internal SDVO register.
*/
-static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
+static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,
u8 target)
{
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
struct i2c_msg msgs[] = {
{
@@ -496,10 +497,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
},
};
- intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+ intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
&target, 1);
/* write the DDC switch command argument */
- intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
+ intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);
out_buf[0] = SDVO_I2C_OPCODE;
out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
@@ -508,7 +509,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
ret_value[0] = 0;
ret_value[1] = 0;
- ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
+ ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);
if (ret != 3) {
/* failure in I2C transfer */
DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
@@ -522,7 +523,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
return;
}
-static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
+static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)
{
struct intel_sdvo_set_target_input_args targets = {0};
u8 status;
@@ -533,10 +534,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
if (target_1)
targets.target_1 = 1;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,
sizeof(targets));
- status = intel_sdvo_read_response(intel_output, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
@@ -547,13 +548,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
* This function is making an assumption about the layout of the response,
* which should be checked against the docs.
*/
-static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
+static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)
{
struct intel_sdvo_get_trained_inputs_response response;
u8 status;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
- status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -562,29 +563,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo
return true;
}
-static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder,
u16 *outputs)
{
u8 status;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
- status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs));
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,
u16 outputs)
{
u8 status;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
sizeof(outputs));
- status = intel_sdvo_read_response(intel_output, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
+static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,
int mode)
{
u8 status, state = SDVO_ENCODER_STATE_ON;
@@ -604,24 +605,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output
break;
}
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
sizeof(state));
- status = intel_sdvo_read_response(intel_output, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,
int *clock_min,
int *clock_max)
{
struct intel_sdvo_pixel_clock_range clocks;
u8 status;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
NULL, 0);
- status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
+ status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -633,31 +634,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou
return true;
}
-static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
+static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,
u16 outputs)
{
u8 status;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
sizeof(outputs));
- status = intel_sdvo_read_response(intel_output, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd,
struct intel_sdvo_dtd *dtd)
{
u8 status;
- intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
- status = intel_sdvo_read_response(intel_output, &dtd->part1,
+ intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
sizeof(dtd->part1));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
- intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
- status = intel_sdvo_read_response(intel_output, &dtd->part2,
+ intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
sizeof(dtd->part2));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -665,60 +666,60 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
return true;
}
-static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_get_timing(intel_output,
+ return intel_sdvo_get_timing(intel_encoder,
SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
}
-static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_get_timing(intel_output,
+ return intel_sdvo_get_timing(intel_encoder,
SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
}
-static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,
struct intel_sdvo_dtd *dtd)
{
u8 status;
- intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
- status = intel_sdvo_read_response(intel_output, NULL, 0);
+ intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
- intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
- status = intel_sdvo_read_response(intel_output, NULL, 0);
+ intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
return true;
}
-static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_set_timing(intel_output,
+ return intel_sdvo_set_timing(intel_encoder,
SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
}
-static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_set_timing(intel_output,
+ return intel_sdvo_set_timing(intel_encoder,
SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
}
static bool
-intel_sdvo_create_preferred_input_timing(struct intel_output *output,
+intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
uint16_t clock,
uint16_t width,
uint16_t height)
{
struct intel_sdvo_preferred_input_timing_args args;
- struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
uint8_t status;
memset(&args, 0, sizeof(args));
@@ -732,32 +733,33 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
args.scaled = 1;
- intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+ intel_sdvo_write_cmd(intel_encoder,
+ SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
&args, sizeof(args));
- status = intel_sdvo_read_response(output, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
return true;
}
-static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
+static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,
struct intel_sdvo_dtd *dtd)
{
bool status;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
NULL, 0);
- status = intel_sdvo_read_response(output, &dtd->part1,
+ status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
sizeof(dtd->part1));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
NULL, 0);
- status = intel_sdvo_read_response(output, &dtd->part2,
+ status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
sizeof(dtd->part2));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -765,12 +767,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
return false;
}
-static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
+static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder)
{
u8 response, status;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
- status = intel_sdvo_read_response(intel_output, &response, 1);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &response, 1);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n");
@@ -782,12 +784,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
return response;
}
-static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
+static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)
{
u8 status;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
- status = intel_sdvo_read_response(intel_output, NULL, 0);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -876,13 +878,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode->flags |= DRM_MODE_FLAG_PVSYNC;
}
-static bool intel_sdvo_get_supp_encode(struct intel_output *output,
+static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
struct intel_sdvo_encode *encode)
{
uint8_t status;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
- status = intel_sdvo_read_response(output, encode, sizeof(*encode));
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));
if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
memset(encode, 0, sizeof(*encode));
return false;
@@ -891,29 +893,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output,
return true;
}
-static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode)
+static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder,
+ uint8_t mode)
{
uint8_t status;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
- status = intel_sdvo_read_response(output, NULL, 0);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_set_colorimetry(struct intel_output *output,
+static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,
uint8_t mode)
{
uint8_t status;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
- status = intel_sdvo_read_response(output, NULL, 0);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
#if 0
-static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
+static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)
{
int i, j;
uint8_t set_buf_index[2];
@@ -922,43 +925,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
uint8_t buf[48];
uint8_t *pos;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
- intel_sdvo_read_response(output, &av_split, 1);
+ intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+ intel_sdvo_read_response(encoder, &av_split, 1);
for (i = 0; i <= av_split; i++) {
set_buf_index[0] = i; set_buf_index[1] = 0;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+ intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,
set_buf_index, 2);
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
- intel_sdvo_read_response(output, &buf_size, 1);
+ intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+ intel_sdvo_read_response(encoder, &buf_size, 1);
pos = buf;
for (j = 0; j <= buf_size; j += 8) {
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA,
+ intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,
NULL, 0);
- intel_sdvo_read_response(output, pos, 8);
+ intel_sdvo_read_response(encoder, pos, 8);
pos += 8;
}
}
}
#endif
-static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
- uint8_t *data, int8_t size, uint8_t tx_rate)
+static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder,
+ int index,
+ uint8_t *data, int8_t size, uint8_t tx_rate)
{
uint8_t set_buf_index[2];
set_buf_index[0] = index;
set_buf_index[1] = 0;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX,
+ set_buf_index, 2);
for (; size > 0; size -= 8) {
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);
data += 8;
}
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
}
static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
@@ -1033,7 +1038,7 @@ struct dip_infoframe {
} __attribute__ ((packed)) u;
} __attribute__((packed));
-static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
+static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
struct drm_display_mode * mode)
{
struct dip_infoframe avi_if = {
@@ -1044,15 +1049,16 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
4 + avi_if.len);
- intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+ intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if,
+ 4 + avi_if.len,
SDVO_HBUF_TX_VSYNC);
}
-static void intel_sdvo_set_tv_format(struct intel_output *output)
+static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)
{
struct intel_sdvo_tv_format format;
- struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
uint32_t format_map, i;
uint8_t status;
@@ -1065,10 +1071,10 @@ static void intel_sdvo_set_tv_format(struct intel_output *output)
memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
sizeof(format) : sizeof(format_map));
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map,
sizeof(format));
- status = intel_sdvo_read_response(output, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
DRM_DEBUG_KMS("%s: Failed to set TV format\n",
SDVO_NAME(sdvo_priv));
@@ -1078,8 +1084,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct intel_output *output = enc_to_intel_output(encoder);
- struct intel_sdvo_priv *dev_priv = output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv;
if (dev_priv->is_tv) {
struct intel_sdvo_dtd output_dtd;
@@ -1094,22 +1100,22 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
/* Set output timings */
intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
- intel_sdvo_set_target_output(output,
+ intel_sdvo_set_target_output(intel_encoder,
dev_priv->controlled_output);
- intel_sdvo_set_output_timing(output, &output_dtd);
+ intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
/* Set the input timing to the screen. Assume always input 0. */
- intel_sdvo_set_target_input(output, true, false);
+ intel_sdvo_set_target_input(intel_encoder, true, false);
- success = intel_sdvo_create_preferred_input_timing(output,
+ success = intel_sdvo_create_preferred_input_timing(intel_encoder,
mode->clock / 10,
mode->hdisplay,
mode->vdisplay);
if (success) {
struct intel_sdvo_dtd input_dtd;
- intel_sdvo_get_preferred_input_timing(output,
+ intel_sdvo_get_preferred_input_timing(intel_encoder,
&input_dtd);
intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1132,16 +1138,16 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
intel_sdvo_get_dtd_from_mode(&output_dtd,
dev_priv->sdvo_lvds_fixed_mode);
- intel_sdvo_set_target_output(output,
+ intel_sdvo_set_target_output(intel_encoder,
dev_priv->controlled_output);
- intel_sdvo_set_output_timing(output, &output_dtd);
+ intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
/* Set the input timing to the screen. Assume always input 0. */
- intel_sdvo_set_target_input(output, true, false);
+ intel_sdvo_set_target_input(intel_encoder, true, false);
success = intel_sdvo_create_preferred_input_timing(
- output,
+ intel_encoder,
mode->clock / 10,
mode->hdisplay,
mode->vdisplay);
@@ -1149,7 +1155,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
if (success) {
struct intel_sdvo_dtd input_dtd;
- intel_sdvo_get_preferred_input_timing(output,
+ intel_sdvo_get_preferred_input_timing(intel_encoder,
&input_dtd);
intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1181,8 +1187,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_output *output = enc_to_intel_output(encoder);
- struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u32 sdvox = 0;
int sdvo_pixel_multiply;
struct intel_sdvo_in_out_map in_out;
@@ -1201,12 +1207,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
in_out.in0 = sdvo_priv->controlled_output;
in_out.in1 = 0;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,
&in_out, sizeof(in_out));
- status = intel_sdvo_read_response(output, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, NULL, 0);
if (sdvo_priv->is_hdmi) {
- intel_sdvo_set_avi_infoframe(output, mode);
+ intel_sdvo_set_avi_infoframe(intel_encoder, mode);
sdvox |= SDVO_AUDIO_ENABLE;
}
@@ -1223,16 +1229,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
*/
if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
/* Set the output timing to the screen */
- intel_sdvo_set_target_output(output,
+ intel_sdvo_set_target_output(intel_encoder,
sdvo_priv->controlled_output);
- intel_sdvo_set_output_timing(output, &input_dtd);
+ intel_sdvo_set_output_timing(intel_encoder, &input_dtd);
}
/* Set the input timing to the screen. Assume always input 0. */
- intel_sdvo_set_target_input(output, true, false);
+ intel_sdvo_set_target_input(intel_encoder, true, false);
if (sdvo_priv->is_tv)
- intel_sdvo_set_tv_format(output);
+ intel_sdvo_set_tv_format(intel_encoder);
/* We would like to use intel_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
@@ -1240,29 +1246,29 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
* output the preferred timing, and we don't support that currently.
*/
#if 0
- success = intel_sdvo_create_preferred_input_timing(output, clock,
+ success = intel_sdvo_create_preferred_input_timing(encoder, clock,
width, height);
if (success) {
struct intel_sdvo_dtd *input_dtd;
- intel_sdvo_get_preferred_input_timing(output, &input_dtd);
- intel_sdvo_set_input_timing(output, &input_dtd);
+ intel_sdvo_get_preferred_input_timing(encoder, &input_dtd);
+ intel_sdvo_set_input_timing(encoder, &input_dtd);
}
#else
- intel_sdvo_set_input_timing(output, &input_dtd);
+ intel_sdvo_set_input_timing(intel_encoder, &input_dtd);
#endif
switch (intel_sdvo_get_pixel_multiplier(mode)) {
case 1:
- intel_sdvo_set_clock_rate_mult(output,
+ intel_sdvo_set_clock_rate_mult(intel_encoder,
SDVO_CLOCK_RATE_MULT_1X);
break;
case 2:
- intel_sdvo_set_clock_rate_mult(output,
+ intel_sdvo_set_clock_rate_mult(intel_encoder,
SDVO_CLOCK_RATE_MULT_2X);
break;
case 4:
- intel_sdvo_set_clock_rate_mult(output,
+ intel_sdvo_set_clock_rate_mult(intel_encoder,
SDVO_CLOCK_RATE_MULT_4X);
break;
}
@@ -1273,8 +1279,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
SDVO_VSYNC_ACTIVE_HIGH |
SDVO_HSYNC_ACTIVE_HIGH;
} else {
- sdvox |= I915_READ(sdvo_priv->output_device);
- switch (sdvo_priv->output_device) {
+ sdvox |= I915_READ(sdvo_priv->sdvo_reg);
+ switch (sdvo_priv->sdvo_reg) {
case SDVOB:
sdvox &= SDVOB_PRESERVE_MASK;
break;
@@ -1298,26 +1304,26 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
sdvox |= SDVO_STALL_SELECT;
- intel_sdvo_write_sdvox(output, sdvox);
+ intel_sdvo_write_sdvox(intel_encoder, sdvox);
}
static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
u32 temp;
if (mode != DRM_MODE_DPMS_ON) {
- intel_sdvo_set_active_outputs(intel_output, 0);
+ intel_sdvo_set_active_outputs(intel_encoder, 0);
if (0)
- intel_sdvo_set_encoder_power_state(intel_output, mode);
+ intel_sdvo_set_encoder_power_state(intel_encoder, mode);
if (mode == DRM_MODE_DPMS_OFF) {
- temp = I915_READ(sdvo_priv->output_device);
+ temp = I915_READ(sdvo_priv->sdvo_reg);
if ((temp & SDVO_ENABLE) != 0) {
- intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
+ intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);
}
}
} else {
@@ -1325,13 +1331,13 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
int i;
u8 status;
- temp = I915_READ(sdvo_priv->output_device);
+ temp = I915_READ(sdvo_priv->sdvo_reg);
if ((temp & SDVO_ENABLE) == 0)
- intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
+ intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
for (i = 0; i < 2; i++)
intel_wait_for_vblank(dev);
- status = intel_sdvo_get_trained_inputs(intel_output, &input1,
+ status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
&input2);
@@ -1345,8 +1351,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
}
if (0)
- intel_sdvo_set_encoder_power_state(intel_output, mode);
- intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output);
+ intel_sdvo_set_encoder_power_state(intel_encoder, mode);
+ intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output);
}
return;
}
@@ -1355,22 +1361,22 @@ static void intel_sdvo_save(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int o;
- sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
- intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
+ sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder);
+ intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs);
if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
- intel_sdvo_set_target_input(intel_output, true, false);
- intel_sdvo_get_input_timing(intel_output,
+ intel_sdvo_set_target_input(intel_encoder, true, false);
+ intel_sdvo_get_input_timing(intel_encoder,
&sdvo_priv->save_input_dtd_1);
}
if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
- intel_sdvo_set_target_input(intel_output, false, true);
- intel_sdvo_get_input_timing(intel_output,
+ intel_sdvo_set_target_input(intel_encoder, false, true);
+ intel_sdvo_get_input_timing(intel_encoder,
&sdvo_priv->save_input_dtd_2);
}
@@ -1379,8 +1385,8 @@ static void intel_sdvo_save(struct drm_connector *connector)
u16 this_output = (1 << o);
if (sdvo_priv->caps.output_flags & this_output)
{
- intel_sdvo_set_target_output(intel_output, this_output);
- intel_sdvo_get_output_timing(intel_output,
+ intel_sdvo_set_target_output(intel_encoder, this_output);
+ intel_sdvo_get_output_timing(intel_encoder,
&sdvo_priv->save_output_dtd[o]);
}
}
@@ -1388,66 +1394,66 @@ static void intel_sdvo_save(struct drm_connector *connector)
/* XXX: Save TV format/enhancements. */
}
- sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
+ sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg);
}
static void intel_sdvo_restore(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int o;
int i;
bool input1, input2;
u8 status;
- intel_sdvo_set_active_outputs(intel_output, 0);
+ intel_sdvo_set_active_outputs(intel_encoder, 0);
for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
{
u16 this_output = (1 << o);
if (sdvo_priv->caps.output_flags & this_output) {
- intel_sdvo_set_target_output(intel_output, this_output);
- intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
+ intel_sdvo_set_target_output(intel_encoder, this_output);
+ intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]);
}
}
if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
- intel_sdvo_set_target_input(intel_output, true, false);
- intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
+ intel_sdvo_set_target_input(intel_encoder, true, false);
+ intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1);
}
if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
- intel_sdvo_set_target_input(intel_output, false, true);
- intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
+ intel_sdvo_set_target_input(intel_encoder, false, true);
+ intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2);
}
- intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
+ intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult);
if (sdvo_priv->is_tv) {
/* XXX: Restore TV format/enhancements. */
}
- intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX);
+ intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX);
if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
{
for (i = 0; i < 2; i++)
intel_wait_for_vblank(dev);
- status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
+ status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2);
if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
DRM_DEBUG_KMS("First %s output reported failure to "
"sync\n", SDVO_NAME(sdvo_priv));
}
- intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
+ intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs);
}
static int intel_sdvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
@@ -1472,12 +1478,12 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector,
return MODE_OK;
}
-static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
+static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)
{
u8 status;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
- status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -1487,22 +1493,22 @@ static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struc
struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
{
struct drm_connector *connector = NULL;
- struct intel_output *iout = NULL;
+ struct intel_encoder *iout = NULL;
struct intel_sdvo_priv *sdvo;
/* find the sdvo connector */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- iout = to_intel_output(connector);
+ iout = to_intel_encoder(connector);
if (iout->type != INTEL_OUTPUT_SDVO)
continue;
sdvo = iout->dev_priv;
- if (sdvo->output_device == SDVOB && sdvoB)
+ if (sdvo->sdvo_reg == SDVOB && sdvoB)
return connector;
- if (sdvo->output_device == SDVOC && !sdvoB)
+ if (sdvo->sdvo_reg == SDVOC && !sdvoB)
return connector;
}
@@ -1514,16 +1520,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)
{
u8 response[2];
u8 status;
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
DRM_DEBUG_KMS("\n");
if (!connector)
return 0;
- intel_output = to_intel_output(connector);
+ intel_encoder = to_intel_encoder(connector);
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
- status = intel_sdvo_read_response(intel_output, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &response, 2);
if (response[0] !=0)
return 1;
@@ -1535,30 +1541,30 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
{
u8 response[2];
u8 status;
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
- intel_sdvo_read_response(intel_output, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+ intel_sdvo_read_response(intel_encoder, &response, 2);
if (on) {
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
- status = intel_sdvo_read_response(intel_output, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+ status = intel_sdvo_read_response(intel_encoder, &response, 2);
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
} else {
response[0] = 0;
response[1] = 0;
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
}
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
- intel_sdvo_read_response(intel_output, &response, 2);
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+ intel_sdvo_read_response(intel_encoder, &response, 2);
}
static bool
-intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
+intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)
{
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int caps = 0;
if (sdvo_priv->caps.output_flags &
@@ -1592,11 +1598,11 @@ static struct drm_connector *
intel_find_analog_connector(struct drm_device *dev)
{
struct drm_connector *connector;
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- intel_output = to_intel_output(connector);
- if (intel_output->type == INTEL_OUTPUT_ANALOG)
+ intel_encoder = to_intel_encoder(connector);
+ if (intel_encoder->type == INTEL_OUTPUT_ANALOG)
return connector;
}
return NULL;
@@ -1621,16 +1627,16 @@ intel_analog_is_connected(struct drm_device *dev)
enum drm_connector_status
intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
enum drm_connector_status status = connector_status_connected;
struct edid *edid = NULL;
- edid = drm_get_edid(&intel_output->base,
- intel_output->ddc_bus);
+ edid = drm_get_edid(&intel_encoder->base,
+ intel_encoder->ddc_bus);
/* This is only applied to SDVO cards with multiple outputs */
- if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
+ if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
uint8_t saved_ddc, temp_ddc;
saved_ddc = sdvo_priv->ddc_bus;
temp_ddc = sdvo_priv->ddc_bus >> 1;
@@ -1640,8 +1646,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
*/
while(temp_ddc > 1) {
sdvo_priv->ddc_bus = temp_ddc;
- edid = drm_get_edid(&intel_output->base,
- intel_output->ddc_bus);
+ edid = drm_get_edid(&intel_encoder->base,
+ intel_encoder->ddc_bus);
if (edid) {
/*
* When we can get the EDID, maybe it is the
@@ -1660,8 +1666,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
*/
if (edid == NULL &&
sdvo_priv->analog_ddc_bus &&
- !intel_analog_is_connected(intel_output->base.dev))
- edid = drm_get_edid(&intel_output->base,
+ !intel_analog_is_connected(intel_encoder->base.dev))
+ edid = drm_get_edid(&intel_encoder->base,
sdvo_priv->analog_ddc_bus);
if (edid != NULL) {
/* Don't report the output as connected if it's a DVI-I
@@ -1676,7 +1682,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
}
kfree(edid);
- intel_output->base.display_info.raw_edid = NULL;
+ intel_encoder->base.display_info.raw_edid = NULL;
} else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
status = connector_status_disconnected;
@@ -1688,16 +1694,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
{
uint16_t response;
u8 status;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
if (sdvo_priv->is_tv) {
/* add 30ms delay when the output type is SDVO-TV */
mdelay(30);
}
- status = intel_sdvo_read_response(intel_output, &response, 2);
+ status = intel_sdvo_read_response(intel_encoder, &response, 2);
DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
@@ -1707,10 +1713,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
if (response == 0)
return connector_status_disconnected;
- if (intel_sdvo_multifunc_encoder(intel_output) &&
+ if (intel_sdvo_multifunc_encoder(intel_encoder) &&
sdvo_priv->attached_output != response) {
if (sdvo_priv->controlled_output != response &&
- intel_sdvo_output_setup(intel_output, response) != true)
+ intel_sdvo_output_setup(intel_encoder, response) != true)
return connector_status_unknown;
sdvo_priv->attached_output = response;
}
@@ -1719,12 +1725,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
int num_modes;
/* set the bus switch and get the modes */
- num_modes = intel_ddc_get_modes(intel_output);
+ num_modes = intel_ddc_get_modes(intel_encoder);
/*
* Mac mini hack. On this device, the DVI-I connector shares one DDC
@@ -1734,17 +1740,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
*/
if (num_modes == 0 &&
sdvo_priv->analog_ddc_bus &&
- !intel_analog_is_connected(intel_output->base.dev)) {
+ !intel_analog_is_connected(intel_encoder->base.dev)) {
struct i2c_adapter *digital_ddc_bus;
/* Switch to the analog ddc bus and try that
*/
- digital_ddc_bus = intel_output->ddc_bus;
- intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
+ digital_ddc_bus = intel_encoder->ddc_bus;
+ intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus;
- (void) intel_ddc_get_modes(intel_output);
+ (void) intel_ddc_get_modes(intel_encoder);
- intel_output->ddc_bus = digital_ddc_bus;
+ intel_encoder->ddc_bus = digital_ddc_bus;
}
}
@@ -1815,7 +1821,7 @@ struct drm_display_mode sdvo_tv_modes[] = {
static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
{
- struct intel_output *output = to_intel_output(connector);
+ struct intel_encoder *output = to_intel_encoder(connector);
struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
struct intel_sdvo_sdtv_resolution_request tv_res;
uint32_t reply = 0, format_map = 0;
@@ -1857,9 +1863,9 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
struct drm_i915_private *dev_priv = connector->dev->dev_private;
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_display_mode *newmode;
/*
@@ -1867,7 +1873,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
* Assume that the preferred modes are
* arranged in priority order.
*/
- intel_ddc_get_modes(intel_output);
+ intel_ddc_get_modes(intel_encoder);
if (list_empty(&connector->probed_modes) == false)
goto end;
@@ -1896,7 +1902,7 @@ end:
static int intel_sdvo_get_modes(struct drm_connector *connector)
{
- struct intel_output *output = to_intel_output(connector);
+ struct intel_encoder *output = to_intel_encoder(connector);
struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
if (sdvo_priv->is_tv)
@@ -1914,8 +1920,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)
static
void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct drm_device *dev = connector->dev;
if (sdvo_priv->is_tv) {
@@ -1952,13 +1958,13 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
static void intel_sdvo_destroy(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
- if (intel_output->i2c_bus)
- intel_i2c_destroy(intel_output->i2c_bus);
- if (intel_output->ddc_bus)
- intel_i2c_destroy(intel_output->ddc_bus);
+ if (intel_encoder->i2c_bus)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
+ if (intel_encoder->ddc_bus)
+ intel_i2c_destroy(intel_encoder->ddc_bus);
if (sdvo_priv->analog_ddc_bus)
intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
@@ -1976,7 +1982,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
- kfree(intel_output);
+ kfree(intel_encoder);
}
static int
@@ -1984,9 +1990,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t val)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
- struct drm_encoder *encoder = &intel_output->enc;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_crtc *crtc = encoder->crtc;
int ret = 0;
bool changed = false;
@@ -2094,8 +2100,8 @@ intel_sdvo_set_property(struct drm_connector *connector,
sdvo_priv->cur_brightness = temp_value;
}
if (cmd) {
- intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2);
- status = intel_sdvo_read_response(intel_output,
+ intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2);
+ status = intel_sdvo_read_response(intel_encoder,
NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO command \n");
@@ -2190,7 +2196,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
}
static bool
-intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
+intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output)
{
struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
uint8_t status;
@@ -2204,42 +2210,42 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
return true;
}
-static struct intel_output *
-intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
+static struct intel_encoder *
+intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan)
{
struct drm_device *dev = chan->drm_dev;
struct drm_connector *connector;
- struct intel_output *intel_output = NULL;
+ struct intel_encoder *intel_encoder = NULL;
list_for_each_entry(connector,
&dev->mode_config.connector_list, head) {
- if (to_intel_output(connector)->ddc_bus == &chan->adapter) {
- intel_output = to_intel_output(connector);
+ if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) {
+ intel_encoder = to_intel_encoder(connector);
break;
}
}
- return intel_output;
+ return intel_encoder;
}
static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msgs[], int num)
{
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct intel_sdvo_priv *sdvo_priv;
struct i2c_algo_bit_data *algo_data;
const struct i2c_algorithm *algo;
algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
- intel_output =
- intel_sdvo_chan_to_intel_output(
+ intel_encoder =
+ intel_sdvo_chan_to_intel_encoder(
(struct intel_i2c_chan *)(algo_data->data));
- if (intel_output == NULL)
+ if (intel_encoder == NULL)
return -EINVAL;
- sdvo_priv = intel_output->dev_priv;
- algo = intel_output->i2c_bus->algo;
+ sdvo_priv = intel_encoder->dev_priv;
+ algo = intel_encoder->i2c_bus->algo;
- intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+ intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus);
return algo->master_xfer(i2c_adap, msgs, num);
}
@@ -2248,12 +2254,12 @@ static struct i2c_algorithm intel_sdvo_i2c_bit_algo = {
};
static u8
-intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
+intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct sdvo_device_mapping *my_mapping, *other_mapping;
- if (output_device == SDVOB) {
+ if (sdvo_reg == SDVOB) {
my_mapping = &dev_priv->sdvo_mappings[0];
other_mapping = &dev_priv->sdvo_mappings[1];
} else {
@@ -2278,7 +2284,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
/* No SDVO device info is found for another DVO port,
* so use mapping assumption we had before BIOS parsing.
*/
- if (output_device == SDVOB)
+ if (sdvo_reg == SDVOB)
return 0x70;
else
return 0x72;
@@ -2304,15 +2310,15 @@ static struct dmi_system_id intel_sdvo_bad_tv[] = {
};
static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)
{
- struct drm_connector *connector = &intel_output->base;
- struct drm_encoder *encoder = &intel_output->enc;
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct drm_connector *connector = &intel_encoder->base;
+ struct drm_encoder *encoder = &intel_encoder->enc;
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
bool ret = true, registered = false;
sdvo_priv->is_tv = false;
- intel_output->needs_tv_clock = false;
+ intel_encoder->needs_tv_clock = false;
sdvo_priv->is_lvds = false;
if (device_is_registered(&connector->kdev)) {
@@ -2330,16 +2336,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
- if (intel_sdvo_get_supp_encode(intel_output,
+ if (intel_sdvo_get_supp_encode(intel_encoder,
&sdvo_priv->encode) &&
- intel_sdvo_get_digital_encoding_mode(intel_output) &&
+ intel_sdvo_get_digital_encoding_mode(intel_encoder) &&
sdvo_priv->is_hdmi) {
/* enable hdmi encoding mode if supported */
- intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
- intel_sdvo_set_colorimetry(intel_output,
+ intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI);
+ intel_sdvo_set_colorimetry(intel_encoder,
SDVO_COLORIMETRY_RGB256);
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
- intel_output->clone_mask =
+ intel_encoder->clone_mask =
(1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
}
@@ -2350,21 +2356,21 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
sdvo_priv->is_tv = true;
- intel_output->needs_tv_clock = true;
- intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+ intel_encoder->needs_tv_clock = true;
+ intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
} else if (flags & SDVO_OUTPUT_RGB0) {
sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
encoder->encoder_type = DRM_MODE_ENCODER_DAC;
connector->connector_type = DRM_MODE_CONNECTOR_VGA;
- intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+ intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
} else if (flags & SDVO_OUTPUT_RGB1) {
sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
encoder->encoder_type = DRM_MODE_ENCODER_DAC;
connector->connector_type = DRM_MODE_CONNECTOR_VGA;
- intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+ intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
} else if (flags & SDVO_OUTPUT_CVBS0) {
@@ -2372,15 +2378,15 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
sdvo_priv->is_tv = true;
- intel_output->needs_tv_clock = true;
- intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+ intel_encoder->needs_tv_clock = true;
+ intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
} else if (flags & SDVO_OUTPUT_LVDS0) {
sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
sdvo_priv->is_lvds = true;
- intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+ intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
} else if (flags & SDVO_OUTPUT_LVDS1) {
@@ -2388,7 +2394,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
sdvo_priv->is_lvds = true;
- intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+ intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
} else {
@@ -2401,7 +2407,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
bytes[0], bytes[1]);
ret = false;
}
- intel_output->crtc_mask = (1 << 0) | (1 << 1);
+ intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
if (ret && registered)
ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
@@ -2413,18 +2419,18 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
static void intel_sdvo_tv_create_property(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo_tv_format format;
uint32_t format_map, i;
uint8_t status;
- intel_sdvo_set_target_output(intel_output,
+ intel_sdvo_set_target_output(intel_encoder,
sdvo_priv->controlled_output);
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&format, sizeof(format));
if (status != SDVO_CMD_STATUS_SUCCESS)
return;
@@ -2462,16 +2468,16 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector)
static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
struct intel_sdvo_enhancements_reply sdvo_data;
struct drm_device *dev = connector->dev;
uint8_t status;
uint16_t response, data_value[2];
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+ intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
NULL, 0);
- status = intel_sdvo_read_response(intel_output, &sdvo_data,
+ status = intel_sdvo_read_response(intel_encoder, &sdvo_data,
sizeof(sdvo_data));
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS(" incorrect response is returned\n");
@@ -2487,18 +2493,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
* property
*/
if (sdvo_data.overscan_h) {
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO max "
"h_overscan\n");
return;
}
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_OVERSCAN_H, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n");
@@ -2528,18 +2534,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
data_value[0], data_value[1], response);
}
if (sdvo_data.overscan_v) {
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO max "
"v_overscan\n");
return;
}
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_OVERSCAN_V, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n");
@@ -2569,17 +2575,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
data_value[0], data_value[1], response);
}
if (sdvo_data.position_h) {
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_MAX_POSITION_H, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");
return;
}
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_POSITION_H, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n");
@@ -2600,17 +2606,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
data_value[0], data_value[1], response);
}
if (sdvo_data.position_v) {
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_MAX_POSITION_V, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");
return;
}
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_POSITION_V, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n");
@@ -2633,17 +2639,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
}
if (sdvo_priv->is_tv) {
if (sdvo_data.saturation) {
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_MAX_SATURATION, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");
return;
}
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_SATURATION, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get sat\n");
@@ -2665,17 +2671,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
data_value[0], data_value[1], response);
}
if (sdvo_data.contrast) {
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_MAX_CONTRAST, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");
return;
}
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_CONTRAST, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get contrast\n");
@@ -2696,17 +2702,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
data_value[0], data_value[1], response);
}
if (sdvo_data.hue) {
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_MAX_HUE, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");
return;
}
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_HUE, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get hue\n");
@@ -2729,17 +2735,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
}
if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
if (sdvo_data.brightness) {
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&data_value, 4);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");
return;
}
- intel_sdvo_write_cmd(intel_output,
+ intel_sdvo_write_cmd(intel_encoder,
SDVO_CMD_GET_BRIGHTNESS, NULL, 0);
- status = intel_sdvo_read_response(intel_output,
+ status = intel_sdvo_read_response(intel_encoder,
&response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("Incorrect SDVO get brigh\n");
@@ -2764,81 +2770,81 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
return;
}
-bool intel_sdvo_init(struct drm_device *dev, int output_device)
+bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct intel_sdvo_priv *sdvo_priv;
u8 ch[0x40];
int i;
- intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
- if (!intel_output) {
+ intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
+ if (!intel_encoder) {
return false;
}
- sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
- sdvo_priv->output_device = output_device;
+ sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1);
+ sdvo_priv->sdvo_reg = sdvo_reg;
- intel_output->dev_priv = sdvo_priv;
- intel_output->type = INTEL_OUTPUT_SDVO;
+ intel_encoder->dev_priv = sdvo_priv;
+ intel_encoder->type = INTEL_OUTPUT_SDVO;
/* setup the DDC bus. */
- if (output_device == SDVOB)
- intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
+ if (sdvo_reg == SDVOB)
+ intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
else
- intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
+ intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
- if (!intel_output->i2c_bus)
+ if (!intel_encoder->i2c_bus)
goto err_inteloutput;
- sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device);
+ sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
/* Save the bit-banging i2c functionality for use by the DDC wrapper */
- intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality;
+ intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
- if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
+ if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
- output_device == SDVOB ? 'B' : 'C');
+ sdvo_reg == SDVOB ? 'B' : 'C');
goto err_i2c;
}
}
/* setup the DDC bus. */
- if (output_device == SDVOB) {
- intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+ if (sdvo_reg == SDVOB) {
+ intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
"SDVOB/VGA DDC BUS");
dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
} else {
- intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+ intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
"SDVOC/VGA DDC BUS");
dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
}
- if (intel_output->ddc_bus == NULL)
+ if (intel_encoder->ddc_bus == NULL)
goto err_i2c;
/* Wrap with our custom algo which switches to DDC mode */
- intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
+ intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
/* In default case sdvo lvds is false */
- intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
+ intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps);
- if (intel_sdvo_output_setup(intel_output,
+ if (intel_sdvo_output_setup(intel_encoder,
sdvo_priv->caps.output_flags) != true) {
DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
- output_device == SDVOB ? 'B' : 'C');
+ sdvo_reg == SDVOB ? 'B' : 'C');
goto err_i2c;
}
- connector = &intel_output->base;
+ connector = &intel_encoder->base;
drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
connector->connector_type);
@@ -2847,12 +2853,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
connector->doublescan_allowed = 0;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- drm_encoder_init(dev, &intel_output->enc,
- &intel_sdvo_enc_funcs, intel_output->enc.encoder_type);
+ drm_encoder_init(dev, &intel_encoder->enc,
+ &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type);
- drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
+ drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs);
- drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
+ drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
if (sdvo_priv->is_tv)
intel_sdvo_tv_create_property(connector);
@@ -2864,9 +2870,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
intel_sdvo_select_ddc_bus(sdvo_priv);
/* Set the input timing to the screen. Assume always input 0. */
- intel_sdvo_set_target_input(intel_output, true, false);
+ intel_sdvo_set_target_input(intel_encoder, true, false);
- intel_sdvo_get_input_pixel_clock_range(intel_output,
+ intel_sdvo_get_input_pixel_clock_range(intel_encoder,
&sdvo_priv->pixel_clock_min,
&sdvo_priv->pixel_clock_max);
@@ -2893,12 +2899,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
err_i2c:
if (sdvo_priv->analog_ddc_bus != NULL)
intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
- if (intel_output->ddc_bus != NULL)
- intel_i2c_destroy(intel_output->ddc_bus);
- if (intel_output->i2c_bus != NULL)
- intel_i2c_destroy(intel_output->i2c_bus);
+ if (intel_encoder->ddc_bus != NULL)
+ intel_i2c_destroy(intel_encoder->ddc_bus);
+ if (intel_encoder->i2c_bus != NULL)
+ intel_i2c_destroy(intel_encoder->i2c_bus);
err_inteloutput:
- kfree(intel_output);
+ kfree(intel_encoder);
return false;
}
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 552ec110b74..d7d39b2327d 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
int i;
tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1);
@@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
struct drm_crtc *crtc = connector->encoder->crtc;
struct intel_crtc *intel_crtc;
int i;
@@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format)
}
static const struct tv_mode *
-intel_tv_mode_find (struct intel_output *intel_output)
+intel_tv_mode_find (struct intel_encoder *intel_encoder)
{
- struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
return intel_tv_mode_lookup(tv_priv->tv_format);
}
@@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output *intel_output)
static enum drm_mode_status
intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
{
- struct intel_output *intel_output = to_intel_output(connector);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
/* Ensure TV refresh is close to desired refresh */
if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
@@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
{
struct drm_device *dev = encoder->dev;
struct drm_mode_config *drm_config = &dev->mode_config;
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
struct drm_encoder *other_encoder;
if (!tv_mode)
@@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_tv_priv *tv_priv = intel_output->dev_priv;
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
u32 tv_ctl;
u32 hctl1, hctl2, hctl3;
u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -1360,9 +1360,9 @@ static const struct drm_display_mode reported_modes[] = {
* \return false if TV is disconnected.
*/
static int
-intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
{
- struct drm_encoder *encoder = &intel_output->enc;
+ struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
@@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
*/
static void intel_tv_find_better_format(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_tv_priv *tv_priv = intel_output->dev_priv;
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
int i;
if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
@@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *connector)
{
struct drm_crtc *crtc;
struct drm_display_mode mode;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_tv_priv *tv_priv = intel_output->dev_priv;
- struct drm_encoder *encoder = &intel_output->enc;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+ struct drm_encoder *encoder = &intel_encoder->enc;
int dpms_mode;
int type = tv_priv->type;
@@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *connector)
drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
if (encoder->crtc && encoder->crtc->enabled) {
- type = intel_tv_detect_type(encoder->crtc, intel_output);
+ type = intel_tv_detect_type(encoder->crtc, intel_encoder);
} else {
- crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
+ crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode);
if (crtc) {
- type = intel_tv_detect_type(crtc, intel_output);
- intel_release_load_detect_pipe(intel_output, dpms_mode);
+ type = intel_tv_detect_type(crtc, intel_encoder);
+ intel_release_load_detect_pipe(intel_encoder, dpms_mode);
} else
type = -1;
}
@@ -1525,8 +1525,8 @@ static void
intel_tv_chose_preferred_modes(struct drm_connector *connector,
struct drm_display_mode *mode_ptr)
{
- struct intel_output *intel_output = to_intel_output(connector);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
@@ -1550,8 +1550,8 @@ static int
intel_tv_get_modes(struct drm_connector *connector)
{
struct drm_display_mode *mode_ptr;
- struct intel_output *intel_output = to_intel_output(connector);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
int j, count = 0;
u64 tmp;
@@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector *connector)
static void
intel_tv_destroy (struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
- kfree(intel_output);
+ kfree(intel_encoder);
}
@@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
uint64_t val)
{
struct drm_device *dev = connector->dev;
- struct intel_output *intel_output = to_intel_output(connector);
- struct intel_tv_priv *tv_priv = intel_output->dev_priv;
- struct drm_encoder *encoder = &intel_output->enc;
+ struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+ struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+ struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_crtc *crtc = encoder->crtc;
int ret = 0;
bool changed = false;
@@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
- struct intel_output *intel_output;
+ struct intel_encoder *intel_encoder;
struct intel_tv_priv *tv_priv;
u32 tv_dac_on, tv_dac_off, save_tv_dac;
char **tv_format_names;
@@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev)
(tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
return;
- intel_output = kzalloc(sizeof(struct intel_output) +
+ intel_encoder = kzalloc(sizeof(struct intel_encoder) +
sizeof(struct intel_tv_priv), GFP_KERNEL);
- if (!intel_output) {
+ if (!intel_encoder) {
return;
}
- connector = &intel_output->base;
+ connector = &intel_encoder->base;
drm_connector_init(dev, connector, &intel_tv_connector_funcs,
DRM_MODE_CONNECTOR_SVIDEO);
- drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
+ drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs,
DRM_MODE_ENCODER_TVDAC);
- drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
- tv_priv = (struct intel_tv_priv *)(intel_output + 1);
- intel_output->type = INTEL_OUTPUT_TVOUT;
- intel_output->crtc_mask = (1 << 0) | (1 << 1);
- intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
- intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
- intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
- intel_output->dev_priv = tv_priv;
+ drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+ tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
+ intel_encoder->type = INTEL_OUTPUT_TVOUT;
+ intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+ intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
+ intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
+ intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
+ intel_encoder->dev_priv = tv_priv;
tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
/* BIOS margin values */
@@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev)
tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
- drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
+ drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 32db806f3b5..453df3f6053 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -12,7 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nouveau_dp.o nouveau_grctx.o \
nv04_timer.o \
nv04_mc.o nv40_mc.o nv50_mc.o \
- nv04_fb.o nv10_fb.o nv40_fb.o \
+ nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
nv04_graph.o nv10_graph.o nv20_graph.o \
nv40_graph.o nv50_graph.o \
@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nv50_cursor.o nv50_display.o nv50_fbcon.o \
nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
- nv17_gpio.o
+ nv17_gpio.o nv50_gpio.o
nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 0e0730a5313..e13f6af0037 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -1,5 +1,6 @@
#include <linux/pci.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index 20564f8cb0e..406228f4a2a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -89,19 +89,21 @@ static struct backlight_ops nv50_bl_ops = {
static int nouveau_nv40_backlight_init(struct drm_device *dev)
{
+ struct backlight_properties props;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct backlight_device *bd;
if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
return 0;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 31;
bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
- &nv40_bl_ops);
+ &nv40_bl_ops, &props);
if (IS_ERR(bd))
return PTR_ERR(bd);
dev_priv->backlight = bd;
- bd->props.max_brightness = 31;
bd->props.brightness = nv40_get_intensity(bd);
backlight_update_status(bd);
@@ -110,19 +112,21 @@ static int nouveau_nv40_backlight_init(struct drm_device *dev)
static int nouveau_nv50_backlight_init(struct drm_device *dev)
{
+ struct backlight_properties props;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct backlight_device *bd;
if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
return 0;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 1025;
bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
- &nv50_bl_ops);
+ &nv50_bl_ops, &props);
if (IS_ERR(bd))
return PTR_ERR(bd);
dev_priv->backlight = bd;
- bd->props.max_brightness = 1025;
bd->props.brightness = nv50_get_intensity(bd);
backlight_update_status(bd);
return 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 71247da17da..abc382a9918 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -2573,48 +2573,34 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
* each GPIO according to various values listed in each entry
*/
- const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+ struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
- const uint8_t *gpio_table = &bios->data[bios->dcb.gpio_table_ptr];
- const uint8_t *gpio_entry;
int i;
- if (!iexec->execute)
- return 1;
-
- if (bios->dcb.version != 0x40) {
- NV_ERROR(bios->dev, "DCB table not version 4.0\n");
- return 0;
+ if (dev_priv->card_type != NV_50) {
+ NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
+ return -ENODEV;
}
- if (!bios->dcb.gpio_table_ptr) {
- NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n");
- return 0;
- }
+ if (!iexec->execute)
+ return 1;
- gpio_entry = gpio_table + gpio_table[1];
- for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) {
- uint32_t entry = ROM32(gpio_entry[0]), r, s, v;
- int line = (entry & 0x0000001f);
+ for (i = 0; i < bios->dcb.gpio.entries; i++) {
+ struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i];
+ uint32_t r, s, v;
- BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry);
+ BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
- if ((entry & 0x0000ff00) == 0x0000ff00)
- continue;
+ nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
- r = nv50_gpio_reg[line >> 3];
- s = (line & 0x07) << 2;
- v = bios_rd32(bios, r) & ~(0x00000003 << s);
- if (entry & 0x01000000)
- v |= (((entry & 0x60000000) >> 29) ^ 2) << s;
- else
- v |= (((entry & 0x18000000) >> 27) ^ 2) << s;
- bios_wr32(bios, r, v);
-
- r = nv50_gpio_ctl[line >> 4];
- s = (line & 0x0f);
+ /* The NVIDIA binary driver doesn't appear to actually do
+ * any of this, my VBIOS does however.
+ */
+ /* Not a clue, needs de-magicing */
+ r = nv50_gpio_ctl[gpio->line >> 4];
+ s = (gpio->line & 0x0f);
v = bios_rd32(bios, r) & ~(0x00010001 << s);
- switch ((entry & 0x06000000) >> 25) {
+ switch ((gpio->entry & 0x06000000) >> 25) {
case 1:
v |= (0x00000001 << s);
break;
@@ -3198,7 +3184,6 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
struct nvbios *bios = &dev_priv->vbios;
unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
uint16_t scriptptr = 0, clktable;
- uint8_t clktableptr = 0;
/*
* For now we assume version 3.0 table - g80 support will need some
@@ -3217,26 +3202,29 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
break;
case LVDS_RESET:
+ clktable = bios->fp.lvdsmanufacturerpointer + 15;
+ if (dcbent->or == 4)
+ clktable += 8;
+
if (dcbent->lvdsconf.use_straps_for_mode) {
if (bios->fp.dual_link)
- clktableptr += 2;
- if (bios->fp.BITbit1)
- clktableptr++;
+ clktable += 4;
+ if (bios->fp.if_is_24bit)
+ clktable += 2;
} else {
/* using EDID */
- uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
- int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
+ int cmpval_24bit = (dcbent->or == 4) ? 4 : 1;
if (bios->fp.dual_link) {
- clktableptr += 2;
- fallbackcmpval *= 2;
+ clktable += 4;
+ cmpval_24bit <<= 1;
}
- if (fallbackcmpval & fallback)
- clktableptr++;
+
+ if (bios->fp.strapless_is_24bit & cmpval_24bit)
+ clktable += 2;
}
- /* adding outputset * 8 may not be correct */
- clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
+ clktable = ROM16(bios->data[clktable]);
if (!clktable) {
NV_ERROR(dev, "Pixel clock comparison table not found\n");
return -ENOENT;
@@ -3545,7 +3533,7 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
* at which modes should be set up in the dual link style.
*
* Following the header, the BMP (ver 0xa) table has several records,
- * indexed by a seperate xlat table, indexed in turn by the fp strap in
+ * indexed by a separate xlat table, indexed in turn by the fp strap in
* EXTDEV_BOOT. Each record had a config byte, followed by 6 script
* numbers for use by INIT_SUB which controlled panel init and power,
* and finally a dword of ms to sleep between power off and on
@@ -3638,37 +3626,40 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
*if_is_24bit = bios->data[lvdsofs] & 16;
break;
case 0x30:
- /*
- * My money would be on there being a 24 bit interface bit in
- * this table, but I have no example of a laptop bios with a
- * 24 bit panel to confirm that. Hence we shout loudly if any
- * bit other than bit 0 is set (I've not even seen bit 1)
- */
- if (bios->data[lvdsofs] > 1)
- NV_ERROR(dev,
- "You have a very unusual laptop display; please report it\n");
+ case 0x40:
/*
* No sign of the "power off for reset" or "reset for panel
* on" bits, but it's safer to assume we should
*/
bios->fp.power_off_for_reset = true;
bios->fp.reset_after_pclk_change = true;
+
/*
* It's ok lvdsofs is wrong for nv4x edid case; dual_link is
- * over-written, and BITbit1 isn't used
+ * over-written, and if_is_24bit isn't used
*/
bios->fp.dual_link = bios->data[lvdsofs] & 1;
- bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
- bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
- break;
- case 0x40:
- bios->fp.dual_link = bios->data[lvdsofs] & 1;
bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;
bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
break;
}
+ /* Dell Latitude D620 reports a too-high value for the dual-link
+ * transition freq, causing us to program the panel incorrectly.
+ *
+ * It doesn't appear the VBIOS actually uses its transition freq
+ * (90000kHz), instead it uses the "Number of LVDS channels" field
+ * out of the panel ID structure (http://www.spwg.org/).
+ *
+ * For the moment, a quirk will do :)
+ */
+ if ((dev->pdev->device == 0x01d7) &&
+ (dev->pdev->subsystem_vendor == 0x1028) &&
+ (dev->pdev->subsystem_device == 0x01c2)) {
+ bios->fp.duallink_transition_clk = 80000;
+ }
+
/* set dual_link flag for EDID case */
if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
@@ -5077,25 +5068,25 @@ parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)
gpio->tag = tag;
gpio->line = line;
gpio->invert = flags != 4;
+ gpio->entry = ent;
}
static void
parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
{
+ uint32_t entry = ROM32(bios->data[offset]);
struct dcb_gpio_entry *gpio;
- uint32_t ent = ROM32(bios->data[offset]);
- uint8_t line = ent & 0x1f,
- tag = ent >> 8 & 0xff;
- if (tag == 0xff)
+ if ((entry & 0x0000ff00) == 0x0000ff00)
return;
gpio = new_gpio_entry(bios);
-
- /* Currently unused, we may need more fields parsed at some
- * point. */
- gpio->tag = tag;
- gpio->line = line;
+ gpio->tag = (entry & 0x0000ff00) >> 8;
+ gpio->line = (entry & 0x0000001f) >> 0;
+ gpio->state_default = (entry & 0x01000000) >> 24;
+ gpio->state[0] = (entry & 0x18000000) >> 27;
+ gpio->state[1] = (entry & 0x60000000) >> 29;
+ gpio->entry = entry;
}
static void
@@ -5211,6 +5202,21 @@ divine_connector_type(struct nvbios *bios, int index)
}
static void
+apply_dcb_connector_quirks(struct nvbios *bios, int idx)
+{
+ struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[idx];
+ struct drm_device *dev = bios->dev;
+
+ /* Gigabyte NX85T */
+ if ((dev->pdev->device == 0x0421) &&
+ (dev->pdev->subsystem_vendor == 0x1458) &&
+ (dev->pdev->subsystem_device == 0x344c)) {
+ if (cte->type == DCB_CONNECTOR_HDMI_1)
+ cte->type = DCB_CONNECTOR_DVI_I;
+ }
+}
+
+static void
parse_dcb_connector_table(struct nvbios *bios)
{
struct drm_device *dev = bios->dev;
@@ -5238,13 +5244,14 @@ parse_dcb_connector_table(struct nvbios *bios)
entry = conntab + conntab[1];
cte = &ct->entry[0];
for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) {
+ cte->index = i;
if (conntab[3] == 2)
cte->entry = ROM16(entry[0]);
else
cte->entry = ROM32(entry[0]);
cte->type = (cte->entry & 0x000000ff) >> 0;
- cte->index = (cte->entry & 0x00000f00) >> 8;
+ cte->index2 = (cte->entry & 0x00000f00) >> 8;
switch (cte->entry & 0x00033000) {
case 0x00001000:
cte->gpio_tag = 0x07;
@@ -5266,6 +5273,8 @@ parse_dcb_connector_table(struct nvbios *bios)
if (cte->type == 0xff)
continue;
+ apply_dcb_connector_quirks(bios, i);
+
NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n",
i, cte->entry, cte->type, cte->index, cte->gpio_tag);
@@ -5287,10 +5296,16 @@ parse_dcb_connector_table(struct nvbios *bios)
break;
default:
cte->type = divine_connector_type(bios, cte->index);
- NV_WARN(dev, "unknown type, using 0x%02x", cte->type);
+ NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type);
break;
}
+ if (nouveau_override_conntype) {
+ int type = divine_connector_type(bios, cte->index);
+ if (type != cte->type)
+ NV_WARN(dev, " -> type 0x%02x\n", cte->type);
+ }
+
}
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 9f688aa9a65..c0d7b0a3ece 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -49,6 +49,9 @@ struct dcb_gpio_entry {
enum dcb_gpio_tag tag;
int line;
bool invert;
+ uint32_t entry;
+ uint8_t state_default;
+ uint8_t state[2];
};
struct dcb_gpio_table {
@@ -72,9 +75,10 @@ enum dcb_connector_type {
};
struct dcb_connector_table_entry {
+ uint8_t index;
uint32_t entry;
enum dcb_connector_type type;
- uint8_t index;
+ uint8_t index2;
uint8_t gpio_tag;
};
@@ -266,7 +270,6 @@ struct nvbios {
bool reset_after_pclk_change;
bool dual_link;
bool link_c_increment;
- bool BITbit1;
bool if_is_24bit;
int duallink_transition_clk;
uint8_t strapless_is_24bit;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 028719fddf7..957d1762984 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -34,6 +34,7 @@
#include "nouveau_dma.h"
#include <linux/log2.h>
+#include <linux/slab.h>
static void
nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
@@ -71,7 +72,7 @@ nouveau_bo_fixup_align(struct drm_device *dev,
* many small buffers.
*/
if (dev_priv->card_type == NV_50) {
- uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15;
+ uint32_t block_size = dev_priv->vram_size >> 15;
int i;
switch (tile_flags) {
@@ -153,7 +154,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
nvbo->placement.fpfn = 0;
nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0;
- nouveau_bo_placement_set(nvbo, flags);
+ nouveau_bo_placement_set(nvbo, flags, 0);
nvbo->channel = chan;
ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
@@ -172,26 +173,33 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
return 0;
}
+static void
+set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
+{
+ *n = 0;
+
+ if (type & TTM_PL_FLAG_VRAM)
+ pl[(*n)++] = TTM_PL_FLAG_VRAM | flags;
+ if (type & TTM_PL_FLAG_TT)
+ pl[(*n)++] = TTM_PL_FLAG_TT | flags;
+ if (type & TTM_PL_FLAG_SYSTEM)
+ pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
+}
+
void
-nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype)
+nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
{
- int n = 0;
-
- if (memtype & TTM_PL_FLAG_VRAM)
- nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING;
- if (memtype & TTM_PL_FLAG_TT)
- nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
- if (memtype & TTM_PL_FLAG_SYSTEM)
- nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
- nvbo->placement.placement = nvbo->placements;
- nvbo->placement.busy_placement = nvbo->placements;
- nvbo->placement.num_placement = n;
- nvbo->placement.num_busy_placement = n;
-
- if (nvbo->pin_refcnt) {
- while (n--)
- nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT;
- }
+ struct ttm_placement *pl = &nvbo->placement;
+ uint32_t flags = TTM_PL_MASK_CACHING |
+ (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0);
+
+ pl->placement = nvbo->placements;
+ set_placement_list(nvbo->placements, &pl->num_placement,
+ type, flags);
+
+ pl->busy_placement = nvbo->busy_placements;
+ set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
+ type | busy, flags);
}
int
@@ -199,7 +207,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
{
struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
struct ttm_buffer_object *bo = &nvbo->bo;
- int ret, i;
+ int ret;
if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
NV_ERROR(nouveau_bdev(bo->bdev)->dev,
@@ -215,9 +223,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
if (ret)
goto out;
- nouveau_bo_placement_set(nvbo, memtype);
- for (i = 0; i < nvbo->placement.num_placement; i++)
- nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+ nouveau_bo_placement_set(nvbo, memtype, 0);
ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
if (ret == 0) {
@@ -244,7 +250,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
{
struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
struct ttm_buffer_object *bo = &nvbo->bo;
- int ret, i;
+ int ret;
if (--nvbo->pin_refcnt)
return 0;
@@ -253,8 +259,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
if (ret)
return ret;
- for (i = 0; i < nvbo->placement.num_placement; i++)
- nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
+ nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
if (ret == 0) {
@@ -395,8 +400,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
man->io_addr = NULL;
man->io_offset = drm_get_resource_start(dev, 1);
man->io_size = drm_get_resource_len(dev, 1);
- if (man->io_size > nouveau_mem_fb_amount(dev))
- man->io_size = nouveau_mem_fb_amount(dev);
+ if (man->io_size > dev_priv->vram_size)
+ man->io_size = dev_priv->vram_size;
man->gpu_offset = dev_priv->vm_vram_base;
break;
@@ -439,11 +444,11 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
switch (bo->mem.mem_type) {
case TTM_PL_VRAM:
- nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT |
+ nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT,
TTM_PL_FLAG_SYSTEM);
break;
default:
- nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM);
+ nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0);
break;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index 6dfb425cbae..1fc57ef5829 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -142,7 +142,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
GFP_KERNEL);
if (!dev_priv->fifos[channel])
return -ENOMEM;
- dev_priv->fifo_alloc_count++;
chan = dev_priv->fifos[channel];
INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
INIT_LIST_HEAD(&chan->fence.pending);
@@ -321,7 +320,6 @@ nouveau_channel_free(struct nouveau_channel *chan)
iounmap(chan->user);
dev_priv->fifos[chan->id] = NULL;
- dev_priv->fifo_alloc_count--;
kfree(chan);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 24327f468c4..14afe1e47e5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -302,7 +302,7 @@ nouveau_connector_detect(struct drm_connector *connector)
detect_analog:
nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
- if (!nv_encoder)
+ if (!nv_encoder && !nouveau_tv_disable)
nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
if (nv_encoder) {
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
index 8ff9ef5d4b4..a251886a0ce 100644
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
@@ -137,10 +137,9 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_minor *minor = node->minor;
- struct drm_device *dev = minor->dev;
+ struct drm_nouveau_private *dev_priv = minor->dev->dev_private;
- seq_printf(m, "VRAM total: %dKiB\n",
- (int)(nouveau_mem_fb_amount(dev) >> 10));
+ seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10));
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index c8482a108a7..65c441a1999 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -190,6 +190,11 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);
chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
+
+ DRM_MEMORYBARRIER();
+ /* Flush writes. */
+ nouveau_bo_rd32(pb, 0);
+
nvchan_wr32(chan, 0x8c, chan->dma.ib_put);
chan->dma.ib_free--;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index f954ad93e81..deeb21c6865 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -483,7 +483,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT);
ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT);
- for (;;) {
+ for (i = 0; i < 16; i++) {
nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000);
nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl);
nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000);
@@ -502,6 +502,12 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
break;
}
+ if (i == 16) {
+ NV_ERROR(dev, "auxch DEFER too many times, bailing\n");
+ ret = -EREMOTEIO;
+ goto out;
+ }
+
if (cmd & 1) {
if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) {
ret = -EREMOTEIO;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index 30cc09e8a70..1de974acbc6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -83,6 +83,14 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
int nouveau_nofbaccel = 0;
module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
+MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type");
+int nouveau_override_conntype = 0;
+module_param_named(override_conntype, nouveau_override_conntype, int, 0400);
+
+MODULE_PARM_DESC(tv_disable, "Disable TV-out detection\n");
+int nouveau_tv_disable = 0;
+module_param_named(tv_disable, nouveau_tv_disable, int, 0400);
+
MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
"\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
"\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
@@ -154,9 +162,11 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
if (pm_state.event == PM_EVENT_PRETHAW)
return 0;
+ NV_INFO(dev, "Disabling fbcon acceleration...\n");
fbdev_flags = dev_priv->fbdev_info->flags;
dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
+ NV_INFO(dev, "Unpinning framebuffer(s)...\n");
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 5f8d987af36..ace630aa89e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -76,6 +76,7 @@ struct nouveau_bo {
struct ttm_buffer_object bo;
struct ttm_placement placement;
u32 placements[3];
+ u32 busy_placements[3];
struct ttm_bo_kmap_obj kmap;
struct list_head head;
@@ -519,6 +520,7 @@ struct drm_nouveau_private {
struct workqueue_struct *wq;
struct work_struct irq_work;
+ struct work_struct hpd_work;
struct list_head vbl_waiting;
@@ -533,7 +535,6 @@ struct drm_nouveau_private {
struct fb_info *fbdev_info;
- int fifo_alloc_count;
struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
struct nouveau_engine engine;
@@ -553,12 +554,6 @@ struct drm_nouveau_private {
uint32_t ramro_offset;
uint32_t ramro_size;
- /* base physical adresses */
- uint64_t fb_phys;
- uint64_t fb_available_size;
- uint64_t fb_mappable_pages;
- uint64_t fb_aper_free;
-
struct {
enum {
NOUVEAU_GART_NONE = 0,
@@ -572,10 +567,6 @@ struct drm_nouveau_private {
struct nouveau_gpuobj *sg_ctxdma;
struct page *sg_dummy_page;
dma_addr_t sg_dummy_bus;
-
- /* nottm hack */
- struct drm_ttm_backend *sg_be;
- unsigned long sg_handle;
} gart_info;
/* nv10-nv40 tiling regions */
@@ -584,6 +575,16 @@ struct drm_nouveau_private {
spinlock_t lock;
} tile;
+ /* VRAM/fb configuration */
+ uint64_t vram_size;
+ uint64_t vram_sys_base;
+
+ uint64_t fb_phys;
+ uint64_t fb_available_size;
+ uint64_t fb_mappable_pages;
+ uint64_t fb_aper_free;
+ int fb_mtrr;
+
/* G8x/G9x virtual address space */
uint64_t vm_gart_base;
uint64_t vm_gart_size;
@@ -592,10 +593,6 @@ struct drm_nouveau_private {
uint64_t vm_end;
struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
int vm_vram_pt_nr;
- uint64_t vram_sys_base;
-
- /* the mtrr covering the FB */
- int fb_mtrr;
struct mem_block *ramin_heap;
@@ -614,11 +611,7 @@ struct drm_nouveau_private {
uint32_t dac_users[4];
struct nouveau_suspend_resume {
- uint32_t fifo_mode;
- uint32_t graph_ctx_control;
- uint32_t graph_state;
uint32_t *ramin_copy;
- uint64_t ramin_size;
} susres;
struct backlight_device *backlight;
@@ -681,6 +674,7 @@ extern int nouveau_uscript_tmds;
extern int nouveau_vram_pushbuf;
extern int nouveau_vram_notify;
extern int nouveau_fbpercrtc;
+extern int nouveau_tv_disable;
extern char *nouveau_tv_norm;
extern int nouveau_reg_debug;
extern char *nouveau_vbios;
@@ -688,6 +682,7 @@ extern int nouveau_ctxfw;
extern int nouveau_ignorelid;
extern int nouveau_nofbaccel;
extern int nouveau_noaccel;
+extern int nouveau_override_conntype;
extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);
extern int nouveau_pci_resume(struct pci_dev *pdev);
@@ -715,7 +710,7 @@ extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
struct drm_file *, int tail);
extern void nouveau_mem_takedown(struct mem_block **heap);
extern void nouveau_mem_free_block(struct mem_block *);
-extern uint64_t nouveau_mem_fb_amount(struct drm_device *);
+extern int nouveau_mem_detect(struct drm_device *dev);
extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
extern int nouveau_mem_init(struct drm_device *);
extern int nouveau_mem_init_agp(struct drm_device *);
@@ -926,6 +921,10 @@ extern void nv40_fb_takedown(struct drm_device *);
extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,
uint32_t, uint32_t);
+/* nv50_fb.c */
+extern int nv50_fb_init(struct drm_device *);
+extern void nv50_fb_takedown(struct drm_device *);
+
/* nv04_fifo.c */
extern int nv04_fifo_init(struct drm_device *);
extern void nv04_fifo_disable(struct drm_device *);
@@ -1118,7 +1117,8 @@ extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);
extern int nouveau_bo_unpin(struct nouveau_bo *);
extern int nouveau_bo_map(struct nouveau_bo *);
extern void nouveau_bo_unmap(struct nouveau_bo *);
-extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype);
+extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type,
+ uint32_t busy);
extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
@@ -1162,6 +1162,10 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+/* nv50_gpio.c */
+int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
+int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+
#ifndef ioread32_native
#ifdef __BIG_ENDIAN
#define ioread16_native ioread16be
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index bc4a24029ed..9f28b94e479 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -47,6 +47,7 @@ struct nouveau_encoder {
union {
struct {
+ int mc_unknown;
int dpcd_version;
int link_nr;
int link_bw;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 68cedd9194f..8e7dc1d4912 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -30,7 +30,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/slab.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 0d22f66f1c7..1bc0b38a516 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -180,40 +180,35 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
{
struct nouveau_bo *nvbo = gem->driver_private;
struct ttm_buffer_object *bo = &nvbo->bo;
- uint64_t flags;
+ uint32_t domains = valid_domains &
+ (write_domains ? write_domains : read_domains);
+ uint32_t pref_flags = 0, valid_flags = 0;
- if (!valid_domains || (!read_domains && !write_domains))
+ if (!domains)
return -EINVAL;
- if (write_domains) {
- if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
- (write_domains & NOUVEAU_GEM_DOMAIN_VRAM))
- flags = TTM_PL_FLAG_VRAM;
- else
- if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
- (write_domains & NOUVEAU_GEM_DOMAIN_GART))
- flags = TTM_PL_FLAG_TT;
- else
- return -EINVAL;
- } else {
- if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
- (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
- bo->mem.mem_type == TTM_PL_VRAM)
- flags = TTM_PL_FLAG_VRAM;
- else
- if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
- (read_domains & NOUVEAU_GEM_DOMAIN_GART) &&
- bo->mem.mem_type == TTM_PL_TT)
- flags = TTM_PL_FLAG_TT;
- else
- if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
- (read_domains & NOUVEAU_GEM_DOMAIN_VRAM))
- flags = TTM_PL_FLAG_VRAM;
- else
- flags = TTM_PL_FLAG_TT;
- }
+ if (valid_domains & NOUVEAU_GEM_DOMAIN_VRAM)
+ valid_flags |= TTM_PL_FLAG_VRAM;
+
+ if (valid_domains & NOUVEAU_GEM_DOMAIN_GART)
+ valid_flags |= TTM_PL_FLAG_TT;
+
+ if ((domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+ bo->mem.mem_type == TTM_PL_VRAM)
+ pref_flags |= TTM_PL_FLAG_VRAM;
+
+ else if ((domains & NOUVEAU_GEM_DOMAIN_GART) &&
+ bo->mem.mem_type == TTM_PL_TT)
+ pref_flags |= TTM_PL_FLAG_TT;
+
+ else if (domains & NOUVEAU_GEM_DOMAIN_VRAM)
+ pref_flags |= TTM_PL_FLAG_VRAM;
+
+ else
+ pref_flags |= TTM_PL_FLAG_TT;
+
+ nouveau_bo_placement_set(nvbo, pref_flags, valid_flags);
- nouveau_bo_placement_set(nvbo, flags);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c
index c7ebec69674..32f0e495464 100644
--- a/drivers/gpu/drm/nouveau/nouveau_grctx.c
+++ b/drivers/gpu/drm/nouveau/nouveau_grctx.c
@@ -23,6 +23,7 @@
*/
#include <linux/firmware.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "nouveau_drv.h"
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index 95220ddebb4..13e73cee4c4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -51,6 +51,7 @@ nouveau_irq_preinstall(struct drm_device *dev)
if (dev_priv->card_type == NV_50) {
INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
+ INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
INIT_LIST_HEAD(&dev_priv->vbl_waiting);
}
}
@@ -311,6 +312,31 @@ nouveau_print_bitfield_names_(uint32_t value,
#define nouveau_print_bitfield_names(val, namelist) \
nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist))
+struct nouveau_enum_names {
+ uint32_t value;
+ const char *name;
+};
+
+static void
+nouveau_print_enum_names_(uint32_t value,
+ const struct nouveau_enum_names *namelist,
+ const int namelist_len)
+{
+ /*
+ * Caller must have already printed the KERN_* log level for us.
+ * Also the caller is responsible for adding the newline.
+ */
+ int i;
+ for (i = 0; i < namelist_len; ++i) {
+ if (value == namelist[i].value) {
+ printk("%s", namelist[i].name);
+ return;
+ }
+ }
+ printk("unknown value 0x%08x", value);
+}
+#define nouveau_print_enum_names(val, namelist) \
+ nouveau_print_enum_names_((val), (namelist), ARRAY_SIZE(namelist))
static int
nouveau_graph_chid_from_grctx(struct drm_device *dev)
@@ -427,14 +453,16 @@ nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id,
struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t nsource = trap->nsource, nstatus = trap->nstatus;
- NV_INFO(dev, "%s - nSource:", id);
- nouveau_print_bitfield_names(nsource, nsource_names);
- printk(", nStatus:");
- if (dev_priv->card_type < NV_10)
- nouveau_print_bitfield_names(nstatus, nstatus_names);
- else
- nouveau_print_bitfield_names(nstatus, nstatus_names_nv10);
- printk("\n");
+ if (dev_priv->card_type < NV_50) {
+ NV_INFO(dev, "%s - nSource:", id);
+ nouveau_print_bitfield_names(nsource, nsource_names);
+ printk(", nStatus:");
+ if (dev_priv->card_type < NV_10)
+ nouveau_print_bitfield_names(nstatus, nstatus_names);
+ else
+ nouveau_print_bitfield_names(nstatus, nstatus_names_nv10);
+ printk("\n");
+ }
NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x "
"Data 0x%08x:0x%08x\n",
@@ -578,27 +606,502 @@ nouveau_pgraph_irq_handler(struct drm_device *dev)
}
static void
+nv50_pfb_vm_trap(struct drm_device *dev, int display, const char *name)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t trap[6];
+ int i, ch;
+ uint32_t idx = nv_rd32(dev, 0x100c90);
+ if (idx & 0x80000000) {
+ idx &= 0xffffff;
+ if (display) {
+ for (i = 0; i < 6; i++) {
+ nv_wr32(dev, 0x100c90, idx | i << 24);
+ trap[i] = nv_rd32(dev, 0x100c94);
+ }
+ for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) {
+ struct nouveau_channel *chan = dev_priv->fifos[ch];
+
+ if (!chan || !chan->ramin)
+ continue;
+
+ if (trap[1] == chan->ramin->instance >> 12)
+ break;
+ }
+ NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x %08x channel %d\n",
+ name, (trap[5]&0x100?"read":"write"),
+ trap[5]&0xff, trap[4]&0xffff,
+ trap[3]&0xffff, trap[0], trap[2], ch);
+ }
+ nv_wr32(dev, 0x100c90, idx | 0x80000000);
+ } else if (display) {
+ NV_INFO(dev, "%s - no VM fault?\n", name);
+ }
+}
+
+static struct nouveau_enum_names nv50_mp_exec_error_names[] =
+{
+ { 3, "STACK_UNDERFLOW" },
+ { 4, "QUADON_ACTIVE" },
+ { 8, "TIMEOUT" },
+ { 0x10, "INVALID_OPCODE" },
+ { 0x40, "BREAKPOINT" },
+};
+
+static void
+nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t units = nv_rd32(dev, 0x1540);
+ uint32_t addr, mp10, status, pc, oplow, ophigh;
+ int i;
+ int mps = 0;
+ for (i = 0; i < 4; i++) {
+ if (!(units & 1 << (i+24)))
+ continue;
+ if (dev_priv->chipset < 0xa0)
+ addr = 0x408200 + (tpid << 12) + (i << 7);
+ else
+ addr = 0x408100 + (tpid << 11) + (i << 7);
+ mp10 = nv_rd32(dev, addr + 0x10);
+ status = nv_rd32(dev, addr + 0x14);
+ if (!status)
+ continue;
+ if (display) {
+ nv_rd32(dev, addr + 0x20);
+ pc = nv_rd32(dev, addr + 0x24);
+ oplow = nv_rd32(dev, addr + 0x70);
+ ophigh= nv_rd32(dev, addr + 0x74);
+ NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - "
+ "TP %d MP %d: ", tpid, i);
+ nouveau_print_enum_names(status,
+ nv50_mp_exec_error_names);
+ printk(" at %06x warp %d, opcode %08x %08x\n",
+ pc&0xffffff, pc >> 24,
+ oplow, ophigh);
+ }
+ nv_wr32(dev, addr + 0x10, mp10);
+ nv_wr32(dev, addr + 0x14, 0);
+ mps++;
+ }
+ if (!mps && display)
+ NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: "
+ "No MPs claiming errors?\n", tpid);
+}
+
+static void
+nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old,
+ uint32_t ustatus_new, int display, const char *name)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int tps = 0;
+ uint32_t units = nv_rd32(dev, 0x1540);
+ int i, r;
+ uint32_t ustatus_addr, ustatus;
+ for (i = 0; i < 16; i++) {
+ if (!(units & (1 << i)))
+ continue;
+ if (dev_priv->chipset < 0xa0)
+ ustatus_addr = ustatus_old + (i << 12);
+ else
+ ustatus_addr = ustatus_new + (i << 11);
+ ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff;
+ if (!ustatus)
+ continue;
+ tps++;
+ switch (type) {
+ case 6: /* texture error... unknown for now */
+ nv50_pfb_vm_trap(dev, display, name);
+ if (display) {
+ NV_ERROR(dev, "magic set %d:\n", i);
+ for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
+ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+ nv_rd32(dev, r));
+ }
+ break;
+ case 7: /* MP error */
+ if (ustatus & 0x00010000) {
+ nv50_pgraph_mp_trap(dev, i, display);
+ ustatus &= ~0x00010000;
+ }
+ break;
+ case 8: /* TPDMA error */
+ {
+ uint32_t e0c = nv_rd32(dev, ustatus_addr + 4);
+ uint32_t e10 = nv_rd32(dev, ustatus_addr + 8);
+ uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc);
+ uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10);
+ uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14);
+ uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18);
+ uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c);
+ nv50_pfb_vm_trap(dev, display, name);
+ /* 2d engine destination */
+ if (ustatus & 0x00000010) {
+ if (display) {
+ NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n",
+ i, e14, e10);
+ NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+ i, e0c, e18, e1c, e20, e24);
+ }
+ ustatus &= ~0x00000010;
+ }
+ /* Render target */
+ if (ustatus & 0x00000040) {
+ if (display) {
+ NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n",
+ i, e14, e10);
+ NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+ i, e0c, e18, e1c, e20, e24);
+ }
+ ustatus &= ~0x00000040;
+ }
+ /* CUDA memory: l[], g[] or stack. */
+ if (ustatus & 0x00000080) {
+ if (display) {
+ if (e18 & 0x80000000) {
+ /* g[] read fault? */
+ NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n",
+ i, e14, e10 | ((e18 >> 24) & 0x1f));
+ e18 &= ~0x1f000000;
+ } else if (e18 & 0xc) {
+ /* g[] write fault? */
+ NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n",
+ i, e14, e10 | ((e18 >> 7) & 0x1f));
+ e18 &= ~0x00000f80;
+ } else {
+ NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n",
+ i, e14, e10);
+ }
+ NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+ i, e0c, e18, e1c, e20, e24);
+ }
+ ustatus &= ~0x00000080;
+ }
+ }
+ break;
+ }
+ if (ustatus) {
+ if (display)
+ NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus);
+ }
+ nv_wr32(dev, ustatus_addr, 0xc0000000);
+ }
+
+ if (!tps && display)
+ NV_INFO(dev, "%s - No TPs claiming errors?\n", name);
+}
+
+static void
+nv50_pgraph_trap_handler(struct drm_device *dev)
+{
+ struct nouveau_pgraph_trap trap;
+ uint32_t status = nv_rd32(dev, 0x400108);
+ uint32_t ustatus;
+ int display = nouveau_ratelimit();
+
+
+ if (!status && display) {
+ nouveau_graph_trap_info(dev, &trap);
+ nouveau_graph_dump_trap_info(dev, "PGRAPH_TRAP", &trap);
+ NV_INFO(dev, "PGRAPH_TRAP - no units reporting traps?\n");
+ }
+
+ /* DISPATCH: Relays commands to other units and handles NOTIFY,
+ * COND, QUERY. If you get a trap from it, the command is still stuck
+ * in DISPATCH and you need to do something about it. */
+ if (status & 0x001) {
+ ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff;
+ if (!ustatus && display) {
+ NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n");
+ }
+
+ /* Known to be triggered by screwed up NOTIFY and COND... */
+ if (ustatus & 0x00000001) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT");
+ nv_wr32(dev, 0x400500, 0);
+ if (nv_rd32(dev, 0x400808) & 0x80000000) {
+ if (display) {
+ if (nouveau_graph_trapped_channel(dev, &trap.channel))
+ trap.channel = -1;
+ trap.class = nv_rd32(dev, 0x400814);
+ trap.mthd = nv_rd32(dev, 0x400808) & 0x1ffc;
+ trap.subc = (nv_rd32(dev, 0x400808) >> 16) & 0x7;
+ trap.data = nv_rd32(dev, 0x40080c);
+ trap.data2 = nv_rd32(dev, 0x400810);
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_TRAP_DISPATCH_FAULT", &trap);
+ NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400808: %08x\n", nv_rd32(dev, 0x400808));
+ NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400848: %08x\n", nv_rd32(dev, 0x400848));
+ }
+ nv_wr32(dev, 0x400808, 0);
+ } else if (display) {
+ NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - No stuck command?\n");
+ }
+ nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3);
+ nv_wr32(dev, 0x400848, 0);
+ ustatus &= ~0x00000001;
+ }
+ if (ustatus & 0x00000002) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY");
+ nv_wr32(dev, 0x400500, 0);
+ if (nv_rd32(dev, 0x40084c) & 0x80000000) {
+ if (display) {
+ if (nouveau_graph_trapped_channel(dev, &trap.channel))
+ trap.channel = -1;
+ trap.class = nv_rd32(dev, 0x400814);
+ trap.mthd = nv_rd32(dev, 0x40084c) & 0x1ffc;
+ trap.subc = (nv_rd32(dev, 0x40084c) >> 16) & 0x7;
+ trap.data = nv_rd32(dev, 0x40085c);
+ trap.data2 = 0;
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_TRAP_DISPATCH_QUERY", &trap);
+ NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - 40084c: %08x\n", nv_rd32(dev, 0x40084c));
+ }
+ nv_wr32(dev, 0x40084c, 0);
+ } else if (display) {
+ NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - No stuck command?\n");
+ }
+ ustatus &= ~0x00000002;
+ }
+ if (ustatus && display)
+ NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - Unhandled ustatus 0x%08x\n", ustatus);
+ nv_wr32(dev, 0x400804, 0xc0000000);
+ nv_wr32(dev, 0x400108, 0x001);
+ status &= ~0x001;
+ }
+
+ /* TRAPs other than dispatch use the "normal" trap regs. */
+ if (status && display) {
+ nouveau_graph_trap_info(dev, &trap);
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_TRAP", &trap);
+ }
+
+ /* M2MF: Memory to memory copy engine. */
+ if (status & 0x002) {
+ ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff;
+ if (!ustatus && display) {
+ NV_INFO(dev, "PGRAPH_TRAP_M2MF - no ustatus?\n");
+ }
+ if (ustatus & 0x00000001) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY");
+ ustatus &= ~0x00000001;
+ }
+ if (ustatus & 0x00000002) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN");
+ ustatus &= ~0x00000002;
+ }
+ if (ustatus & 0x00000004) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT");
+ ustatus &= ~0x00000004;
+ }
+ NV_INFO (dev, "PGRAPH_TRAP_M2MF - %08x %08x %08x %08x\n",
+ nv_rd32(dev, 0x406804),
+ nv_rd32(dev, 0x406808),
+ nv_rd32(dev, 0x40680c),
+ nv_rd32(dev, 0x406810));
+ if (ustatus && display)
+ NV_INFO(dev, "PGRAPH_TRAP_M2MF - Unhandled ustatus 0x%08x\n", ustatus);
+ /* No sane way found yet -- just reset the bugger. */
+ nv_wr32(dev, 0x400040, 2);
+ nv_wr32(dev, 0x400040, 0);
+ nv_wr32(dev, 0x406800, 0xc0000000);
+ nv_wr32(dev, 0x400108, 0x002);
+ status &= ~0x002;
+ }
+
+ /* VFETCH: Fetches data from vertex buffers. */
+ if (status & 0x004) {
+ ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff;
+ if (!ustatus && display) {
+ NV_INFO(dev, "PGRAPH_TRAP_VFETCH - no ustatus?\n");
+ }
+ if (ustatus & 0x00000001) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT");
+ NV_INFO (dev, "PGRAPH_TRAP_VFETCH_FAULT - %08x %08x %08x %08x\n",
+ nv_rd32(dev, 0x400c00),
+ nv_rd32(dev, 0x400c08),
+ nv_rd32(dev, 0x400c0c),
+ nv_rd32(dev, 0x400c10));
+ ustatus &= ~0x00000001;
+ }
+ if (ustatus && display)
+ NV_INFO(dev, "PGRAPH_TRAP_VFETCH - Unhandled ustatus 0x%08x\n", ustatus);
+ nv_wr32(dev, 0x400c04, 0xc0000000);
+ nv_wr32(dev, 0x400108, 0x004);
+ status &= ~0x004;
+ }
+
+ /* STRMOUT: DirectX streamout / OpenGL transform feedback. */
+ if (status & 0x008) {
+ ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff;
+ if (!ustatus && display) {
+ NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - no ustatus?\n");
+ }
+ if (ustatus & 0x00000001) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT");
+ NV_INFO (dev, "PGRAPH_TRAP_STRMOUT_FAULT - %08x %08x %08x %08x\n",
+ nv_rd32(dev, 0x401804),
+ nv_rd32(dev, 0x401808),
+ nv_rd32(dev, 0x40180c),
+ nv_rd32(dev, 0x401810));
+ ustatus &= ~0x00000001;
+ }
+ if (ustatus && display)
+ NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - Unhandled ustatus 0x%08x\n", ustatus);
+ /* No sane way found yet -- just reset the bugger. */
+ nv_wr32(dev, 0x400040, 0x80);
+ nv_wr32(dev, 0x400040, 0);
+ nv_wr32(dev, 0x401800, 0xc0000000);
+ nv_wr32(dev, 0x400108, 0x008);
+ status &= ~0x008;
+ }
+
+ /* CCACHE: Handles code and c[] caches and fills them. */
+ if (status & 0x010) {
+ ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff;
+ if (!ustatus && display) {
+ NV_INFO(dev, "PGRAPH_TRAP_CCACHE - no ustatus?\n");
+ }
+ if (ustatus & 0x00000001) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT");
+ NV_INFO (dev, "PGRAPH_TRAP_CCACHE_FAULT - %08x %08x %08x %08x %08x %08x %08x\n",
+ nv_rd32(dev, 0x405800),
+ nv_rd32(dev, 0x405804),
+ nv_rd32(dev, 0x405808),
+ nv_rd32(dev, 0x40580c),
+ nv_rd32(dev, 0x405810),
+ nv_rd32(dev, 0x405814),
+ nv_rd32(dev, 0x40581c));
+ ustatus &= ~0x00000001;
+ }
+ if (ustatus && display)
+ NV_INFO(dev, "PGRAPH_TRAP_CCACHE - Unhandled ustatus 0x%08x\n", ustatus);
+ nv_wr32(dev, 0x405018, 0xc0000000);
+ nv_wr32(dev, 0x400108, 0x010);
+ status &= ~0x010;
+ }
+
+ /* Unknown, not seen yet... 0x402000 is the only trap status reg
+ * remaining, so try to handle it anyway. Perhaps related to that
+ * unknown DMA slot on tesla? */
+ if (status & 0x20) {
+ nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04");
+ ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff;
+ if (display)
+ NV_INFO(dev, "PGRAPH_TRAP_UNKC04 - Unhandled ustatus 0x%08x\n", ustatus);
+ nv_wr32(dev, 0x402000, 0xc0000000);
+ /* no status modifiction on purpose */
+ }
+
+ /* TEXTURE: CUDA texturing units */
+ if (status & 0x040) {
+ nv50_pgraph_tp_trap (dev, 6, 0x408900, 0x408600, display,
+ "PGRAPH_TRAP_TEXTURE");
+ nv_wr32(dev, 0x400108, 0x040);
+ status &= ~0x040;
+ }
+
+ /* MP: CUDA execution engines. */
+ if (status & 0x080) {
+ nv50_pgraph_tp_trap (dev, 7, 0x408314, 0x40831c, display,
+ "PGRAPH_TRAP_MP");
+ nv_wr32(dev, 0x400108, 0x080);
+ status &= ~0x080;
+ }
+
+ /* TPDMA: Handles TP-initiated uncached memory accesses:
+ * l[], g[], stack, 2d surfaces, render targets. */
+ if (status & 0x100) {
+ nv50_pgraph_tp_trap (dev, 8, 0x408e08, 0x408708, display,
+ "PGRAPH_TRAP_TPDMA");
+ nv_wr32(dev, 0x400108, 0x100);
+ status &= ~0x100;
+ }
+
+ if (status) {
+ if (display)
+ NV_INFO(dev, "PGRAPH_TRAP - Unknown trap 0x%08x\n",
+ status);
+ nv_wr32(dev, 0x400108, status);
+ }
+}
+
+/* There must be a *lot* of these. Will take some time to gather them up. */
+static struct nouveau_enum_names nv50_data_error_names[] =
+{
+ { 4, "INVALID_VALUE" },
+ { 5, "INVALID_ENUM" },
+ { 8, "INVALID_OBJECT" },
+ { 0xc, "INVALID_BITFIELD" },
+ { 0x28, "MP_NO_REG_SPACE" },
+ { 0x2b, "MP_BLOCK_SIZE_MISMATCH" },
+};
+
+static void
nv50_pgraph_irq_handler(struct drm_device *dev)
{
+ struct nouveau_pgraph_trap trap;
+ int unhandled = 0;
uint32_t status;
while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
- uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
-
+ /* NOTIFY: You've set a NOTIFY an a command and it's done. */
if (status & 0x00000001) {
- nouveau_pgraph_intr_notify(dev, nsource);
+ nouveau_graph_trap_info(dev, &trap);
+ if (nouveau_ratelimit())
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_NOTIFY", &trap);
status &= ~0x00000001;
nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
}
- if (status & 0x00000010) {
- nouveau_pgraph_intr_error(dev, nsource |
- NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
+ /* COMPUTE_QUERY: Purpose and exact cause unknown, happens
+ * when you write 0x200 to 0x50c0 method 0x31c. */
+ if (status & 0x00000002) {
+ nouveau_graph_trap_info(dev, &trap);
+ if (nouveau_ratelimit())
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_COMPUTE_QUERY", &trap);
+ status &= ~0x00000002;
+ nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000002);
+ }
+ /* Unknown, never seen: 0x4 */
+
+ /* ILLEGAL_MTHD: You used a wrong method for this class. */
+ if (status & 0x00000010) {
+ nouveau_graph_trap_info(dev, &trap);
+ if (nouveau_pgraph_intr_swmthd(dev, &trap))
+ unhandled = 1;
+ if (unhandled && nouveau_ratelimit())
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_ILLEGAL_MTHD", &trap);
status &= ~0x00000010;
nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
}
+ /* ILLEGAL_CLASS: You used a wrong class. */
+ if (status & 0x00000020) {
+ nouveau_graph_trap_info(dev, &trap);
+ if (nouveau_ratelimit())
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_ILLEGAL_CLASS", &trap);
+ status &= ~0x00000020;
+ nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000020);
+ }
+
+ /* DOUBLE_NOTIFY: You tried to set a NOTIFY on another NOTIFY. */
+ if (status & 0x00000040) {
+ nouveau_graph_trap_info(dev, &trap);
+ if (nouveau_ratelimit())
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_DOUBLE_NOTIFY", &trap);
+ status &= ~0x00000040;
+ nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000040);
+ }
+
+ /* CONTEXT_SWITCH: PGRAPH needs us to load a new context */
if (status & 0x00001000) {
nv_wr32(dev, 0x400500, 0x00000000);
nv_wr32(dev, NV03_PGRAPH_INTR,
@@ -613,49 +1116,59 @@ nv50_pgraph_irq_handler(struct drm_device *dev)
status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
}
- if (status & 0x00100000) {
- nouveau_pgraph_intr_error(dev, nsource |
- NV03_PGRAPH_NSOURCE_DATA_ERROR);
+ /* BUFFER_NOTIFY: Your m2mf transfer finished */
+ if (status & 0x00010000) {
+ nouveau_graph_trap_info(dev, &trap);
+ if (nouveau_ratelimit())
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_BUFFER_NOTIFY", &trap);
+ status &= ~0x00010000;
+ nv_wr32(dev, NV03_PGRAPH_INTR, 0x00010000);
+ }
+ /* DATA_ERROR: Invalid value for this method, or invalid
+ * state in current PGRAPH context for this operation */
+ if (status & 0x00100000) {
+ nouveau_graph_trap_info(dev, &trap);
+ if (nouveau_ratelimit()) {
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_DATA_ERROR", &trap);
+ NV_INFO (dev, "PGRAPH_DATA_ERROR - ");
+ nouveau_print_enum_names(nv_rd32(dev, 0x400110),
+ nv50_data_error_names);
+ printk("\n");
+ }
status &= ~0x00100000;
nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
}
+ /* TRAP: Something bad happened in the middle of command
+ * execution. Has a billion types, subtypes, and even
+ * subsubtypes. */
if (status & 0x00200000) {
- int r;
-
- nouveau_pgraph_intr_error(dev, nsource |
- NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
-
- NV_ERROR(dev, "magic set 1:\n");
- for (r = 0x408900; r <= 0x408910; r += 4)
- NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
- nv_rd32(dev, r));
- nv_wr32(dev, 0x408900,
- nv_rd32(dev, 0x408904) | 0xc0000000);
- for (r = 0x408e08; r <= 0x408e24; r += 4)
- NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
- nv_rd32(dev, r));
- nv_wr32(dev, 0x408e08,
- nv_rd32(dev, 0x408e08) | 0xc0000000);
-
- NV_ERROR(dev, "magic set 2:\n");
- for (r = 0x409900; r <= 0x409910; r += 4)
- NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
- nv_rd32(dev, r));
- nv_wr32(dev, 0x409900,
- nv_rd32(dev, 0x409904) | 0xc0000000);
- for (r = 0x409e08; r <= 0x409e24; r += 4)
- NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
- nv_rd32(dev, r));
- nv_wr32(dev, 0x409e08,
- nv_rd32(dev, 0x409e08) | 0xc0000000);
-
+ nv50_pgraph_trap_handler(dev);
status &= ~0x00200000;
- nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
}
+ /* Unknown, never seen: 0x00400000 */
+
+ /* SINGLE_STEP: Happens on every method if you turned on
+ * single stepping in 40008c */
+ if (status & 0x01000000) {
+ nouveau_graph_trap_info(dev, &trap);
+ if (nouveau_ratelimit())
+ nouveau_graph_dump_trap_info(dev,
+ "PGRAPH_SINGLE_STEP", &trap);
+ status &= ~0x01000000;
+ nv_wr32(dev, NV03_PGRAPH_INTR, 0x01000000);
+ }
+
+ /* 0x02000000 happens when you pause a ctxprog...
+ * but the only way this can happen that I know is by
+ * poking the relevant MMIO register, and we don't
+ * do that. */
+
if (status) {
NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n",
status);
@@ -672,7 +1185,8 @@ nv50_pgraph_irq_handler(struct drm_device *dev)
}
nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
- nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
+ if (nv_rd32(dev, 0x400824) & (1 << 31))
+ nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
}
static void
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 2dc09dbd817..775a7017af6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -347,6 +347,20 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
return -EBUSY;
}
+ nv_wr32(dev, 0x100c80, 0x00040001);
+ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+ return -EBUSY;
+ }
+
+ nv_wr32(dev, 0x100c80, 0x00060001);
+ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+ return -EBUSY;
+ }
+
return 0;
}
@@ -387,6 +401,20 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+ return;
+ }
+
+ nv_wr32(dev, 0x100c80, 0x00040001);
+ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+ return;
+ }
+
+ nv_wr32(dev, 0x100c80, 0x00060001);
+ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
}
}
@@ -449,9 +477,30 @@ void nouveau_mem_close(struct drm_device *dev)
}
}
-/*XXX won't work on BSD because of pci_read_config_dword */
static uint32_t
-nouveau_mem_fb_amount_igp(struct drm_device *dev)
+nouveau_mem_detect_nv04(struct drm_device *dev)
+{
+ uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0);
+
+ if (boot0 & 0x00000100)
+ return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
+
+ switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
+ case NV04_BOOT_0_RAM_AMOUNT_32MB:
+ return 32 * 1024 * 1024;
+ case NV04_BOOT_0_RAM_AMOUNT_16MB:
+ return 16 * 1024 * 1024;
+ case NV04_BOOT_0_RAM_AMOUNT_8MB:
+ return 8 * 1024 * 1024;
+ case NV04_BOOT_0_RAM_AMOUNT_4MB:
+ return 4 * 1024 * 1024;
+ }
+
+ return 0;
+}
+
+static uint32_t
+nouveau_mem_detect_nforce(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct pci_dev *bridge;
@@ -463,11 +512,11 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)
return 0;
}
- if (dev_priv->flags&NV_NFORCE) {
+ if (dev_priv->flags & NV_NFORCE) {
pci_read_config_dword(bridge, 0x7C, &mem);
return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
} else
- if (dev_priv->flags&NV_NFORCE2) {
+ if (dev_priv->flags & NV_NFORCE2) {
pci_read_config_dword(bridge, 0x84, &mem);
return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
}
@@ -477,50 +526,32 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)
}
/* returns the amount of FB ram in bytes */
-uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
+int
+nouveau_mem_detect(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t boot0;
-
- switch (dev_priv->card_type) {
- case NV_04:
- boot0 = nv_rd32(dev, NV03_BOOT_0);
- if (boot0 & 0x00000100)
- return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
-
- switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
- case NV04_BOOT_0_RAM_AMOUNT_32MB:
- return 32 * 1024 * 1024;
- case NV04_BOOT_0_RAM_AMOUNT_16MB:
- return 16 * 1024 * 1024;
- case NV04_BOOT_0_RAM_AMOUNT_8MB:
- return 8 * 1024 * 1024;
- case NV04_BOOT_0_RAM_AMOUNT_4MB:
- return 4 * 1024 * 1024;
- }
- break;
- case NV_10:
- case NV_20:
- case NV_30:
- case NV_40:
- case NV_50:
- default:
- if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
- return nouveau_mem_fb_amount_igp(dev);
- } else {
- uint64_t mem;
- mem = (nv_rd32(dev, NV04_FIFO_DATA) &
- NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
- NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
- return mem * 1024 * 1024;
- }
- break;
+
+ if (dev_priv->card_type == NV_04) {
+ dev_priv->vram_size = nouveau_mem_detect_nv04(dev);
+ } else
+ if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
+ dev_priv->vram_size = nouveau_mem_detect_nforce(dev);
+ } else {
+ dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA);
+ dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
+ if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
+ dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
}
- NV_ERROR(dev,
- "Unable to detect video ram size. Please report your setup to "
- DRIVER_EMAIL "\n");
- return 0;
+ NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
+ if (dev_priv->vram_sys_base) {
+ NV_INFO(dev, "Stolen system memory at: 0x%010llx\n",
+ dev_priv->vram_sys_base);
+ }
+
+ if (dev_priv->vram_size)
+ return 0;
+ return -ENOMEM;
}
#if __OS_HAS_AGP
@@ -631,15 +662,12 @@ nouveau_mem_init(struct drm_device *dev)
spin_lock_init(&dev_priv->ttm.bo_list_lock);
spin_lock_init(&dev_priv->tile.lock);
- dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
-
+ dev_priv->fb_available_size = dev_priv->vram_size;
dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
- NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20));
-
/* remove reserved space at end of vram from available amount */
dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
dev_priv->fb_aper_free = dev_priv->fb_available_size;
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index ed1590577b6..1d6ee8b5515 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -1,6 +1,7 @@
#include "drmP.h"
#include "nouveau_drv.h"
#include <linux/pagemap.h>
+#include <linux/slab.h>
#define NV_CTXDMA_PAGE_SHIFT 12
#define NV_CTXDMA_PAGE_SIZE (1 << NV_CTXDMA_PAGE_SHIFT)
@@ -171,6 +172,24 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
}
dev_priv->engine.instmem.finish_access(nvbe->dev);
+ if (dev_priv->card_type == NV_50) {
+ nv_wr32(dev, 0x100c80, 0x00050001);
+ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+ NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+ nv_rd32(dev, 0x100c80));
+ return -EBUSY;
+ }
+
+ nv_wr32(dev, 0x100c80, 0x00000001);
+ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+ NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+ nv_rd32(dev, 0x100c80));
+ return -EBUSY;
+ }
+ }
+
nvbe->bound = false;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index eb8f084d5f5..e1710640a27 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -24,6 +24,7 @@
*/
#include <linux/swab.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "drm_sarea.h"
@@ -35,7 +36,6 @@
#include "nouveau_drm.h"
#include "nv50_display.h"
-static int nouveau_stub_init(struct drm_device *dev) { return 0; }
static void nouveau_stub_takedown(struct drm_device *dev) {}
static int nouveau_init_engine_ptrs(struct drm_device *dev)
@@ -277,8 +277,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->timer.init = nv04_timer_init;
engine->timer.read = nv04_timer_read;
engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nouveau_stub_init;
- engine->fb.takedown = nouveau_stub_takedown;
+ engine->fb.init = nv50_fb_init;
+ engine->fb.takedown = nv50_fb_takedown;
engine->graph.grclass = nv50_graph_grclass;
engine->graph.init = nv50_graph_init;
engine->graph.takedown = nv50_graph_takedown;
@@ -341,7 +341,7 @@ nouveau_card_init_channel(struct drm_device *dev)
gpuobj = NULL;
ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
- 0, nouveau_mem_fb_amount(dev),
+ 0, dev_priv->vram_size,
NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
&gpuobj);
if (ret)
@@ -427,6 +427,10 @@ nouveau_card_init(struct drm_device *dev)
goto out;
}
+ ret = nouveau_mem_detect(dev);
+ if (ret)
+ goto out_bios;
+
ret = nouveau_gpuobj_early_init(dev);
if (ret)
goto out_bios;
@@ -502,7 +506,7 @@ nouveau_card_init(struct drm_device *dev)
else
ret = nv04_display_create(dev);
if (ret)
- goto out_irq;
+ goto out_channel;
}
ret = nouveau_backlight_init(dev);
@@ -516,6 +520,11 @@ nouveau_card_init(struct drm_device *dev)
return 0;
+out_channel:
+ if (dev_priv->channel) {
+ nouveau_channel_free(dev_priv->channel);
+ dev_priv->channel = NULL;
+ }
out_irq:
drm_irq_uninstall(dev);
out_fifo:
@@ -533,6 +542,7 @@ out_mc:
out_gpuobj:
nouveau_gpuobj_takedown(dev);
out_mem:
+ nouveau_sgdma_takedown(dev);
nouveau_mem_close(dev);
out_instmem:
engine->instmem.takedown(dev);
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index a1d1ebb073d..eba687f1099 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -230,9 +230,9 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
struct drm_framebuffer *fb = crtc->fb;
/* Calculate our timings */
- int horizDisplay = (mode->crtc_hdisplay >> 3) - 1;
- int horizStart = (mode->crtc_hsync_start >> 3) - 1;
- int horizEnd = (mode->crtc_hsync_end >> 3) - 1;
+ int horizDisplay = (mode->crtc_hdisplay >> 3) - 1;
+ int horizStart = (mode->crtc_hsync_start >> 3) + 1;
+ int horizEnd = (mode->crtc_hsync_end >> 3) + 1;
int horizTotal = (mode->crtc_htotal >> 3) - 5;
int horizBlankStart = (mode->crtc_hdisplay >> 3) - 1;
int horizBlankEnd = (mode->crtc_htotal >> 3) - 1;
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
index 3da90c2c4e6..813b25cec72 100644
--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -118,8 +118,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
return;
}
- width = ALIGN(image->width, 32);
- dsize = (width * image->height) >> 5;
+ width = ALIGN(image->width, 8);
+ dsize = ALIGN(width * image->height, 32) >> 5;
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
@@ -136,8 +136,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
((image->dx + image->width) & 0xffff));
OUT_RING(chan, bg);
OUT_RING(chan, fg);
- OUT_RING(chan, (image->height << 16) | image->width);
OUT_RING(chan, (image->height << 16) | width);
+ OUT_RING(chan, (image->height << 16) | image->width);
OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
while (dsize) {
diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c
index 6b2ef4a9fce..500ccfd3a0b 100644
--- a/drivers/gpu/drm/nouveau/nv40_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv40_fifo.c
@@ -278,7 +278,7 @@ nv40_fifo_init_ramxx(struct drm_device *dev)
default:
nv_wr32(dev, 0x2230, 0);
nv_wr32(dev, NV40_PFIFO_RAMFC,
- ((nouveau_mem_fb_amount(dev) - 512 * 1024 +
+ ((dev_priv->vram_size - 512 * 1024 +
dev_priv->ramfc_offset) >> 16) | (3 << 16));
break;
}
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c
index 53e8afe1dcd..0616c96e4b6 100644
--- a/drivers/gpu/drm/nouveau/nv40_graph.c
+++ b/drivers/gpu/drm/nouveau/nv40_graph.c
@@ -335,6 +335,27 @@ nv40_graph_init(struct drm_device *dev)
nv_wr32(dev, 0x400b38, 0x2ffff800);
nv_wr32(dev, 0x400b3c, 0x00006000);
+ /* Tiling related stuff. */
+ switch (dev_priv->chipset) {
+ case 0x44:
+ case 0x4a:
+ nv_wr32(dev, 0x400bc4, 0x1003d888);
+ nv_wr32(dev, 0x400bbc, 0xb7a7b500);
+ break;
+ case 0x46:
+ nv_wr32(dev, 0x400bc4, 0x0000e024);
+ nv_wr32(dev, 0x400bbc, 0xb7a7b520);
+ break;
+ case 0x4c:
+ case 0x4e:
+ case 0x67:
+ nv_wr32(dev, 0x400bc4, 0x1003d888);
+ nv_wr32(dev, 0x400bbc, 0xb7a7b540);
+ break;
+ default:
+ break;
+ }
+
/* Turn all the tiling regions off. */
for (i = 0; i < pfb->num_tiles; i++)
nv40_graph_set_region_tiling(dev, i, 0, 0, 0);
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 61a89f2dc55..649db4c1b69 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -143,7 +143,7 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
}
ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19,
- 0, nouveau_mem_fb_amount(dev));
+ 0, dev_priv->vram_size);
if (ret) {
nv50_evo_channel_del(pchan);
return ret;
@@ -231,7 +231,7 @@ nv50_display_init(struct drm_device *dev)
/* This used to be in crtc unblank, but seems out of place there. */
nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);
/* RAM is clamped to 256 MiB. */
- ram_amount = nouveau_mem_fb_amount(dev);
+ ram_amount = dev_priv->vram_size;
NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount);
if (ram_amount > 256*1024*1024)
ram_amount = 256*1024*1024;
@@ -522,15 +522,17 @@ int nv50_display_create(struct drm_device *dev)
}
for (i = 0 ; i < dcb->connector.entries; i++) {
- if (i != 0 && dcb->connector.entry[i].index ==
- dcb->connector.entry[i - 1].index)
+ if (i != 0 && dcb->connector.entry[i].index2 ==
+ dcb->connector.entry[i - 1].index2)
continue;
nouveau_connector_create(dev, &dcb->connector.entry[i]);
}
ret = nv50_display_init(dev);
- if (ret)
+ if (ret) {
+ nv50_display_destroy(dev);
return ret;
+ }
return 0;
}
@@ -885,10 +887,12 @@ nv50_display_error_handler(struct drm_device *dev)
nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000);
}
-static void
-nv50_display_irq_hotplug(struct drm_device *dev)
+void
+nv50_display_irq_hotplug_bh(struct work_struct *work)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct drm_nouveau_private *dev_priv =
+ container_of(work, struct drm_nouveau_private, hpd_work);
+ struct drm_device *dev = dev_priv->dev;
struct drm_connector *connector;
const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
uint32_t unplug_mask, plug_mask, change_mask;
@@ -949,8 +953,10 @@ nv50_display_irq_handler(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t delayed = 0;
- while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG)
- nv50_display_irq_hotplug(dev);
+ if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) {
+ if (!work_pending(&dev_priv->hpd_work))
+ queue_work(dev_priv->wq, &dev_priv->hpd_work);
+ }
while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h
index 3ae8d0725f6..581d405ac01 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.h
+++ b/drivers/gpu/drm/nouveau/nv50_display.h
@@ -37,6 +37,7 @@
void nv50_display_irq_handler(struct drm_device *dev);
void nv50_display_irq_handler_bh(struct work_struct *work);
+void nv50_display_irq_hotplug_bh(struct work_struct *work);
int nv50_display_init(struct drm_device *dev);
int nv50_display_create(struct drm_device *dev);
int nv50_display_destroy(struct drm_device *dev);
diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c
new file mode 100644
index 00000000000..a95e6941ba8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_fb.c
@@ -0,0 +1,32 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv50_fb_init(struct drm_device *dev)
+{
+ /* This is needed to get meaningful information from 100c90
+ * on traps. No idea what these values mean exactly. */
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ switch (dev_priv->chipset) {
+ case 0x50:
+ nv_wr32(dev, 0x100c90, 0x0707ff);
+ break;
+ case 0xa5:
+ case 0xa8:
+ nv_wr32(dev, 0x100c90, 0x0d0fff);
+ break;
+ default:
+ nv_wr32(dev, 0x100c90, 0x1d07ff);
+ break;
+ }
+
+ return 0;
+}
+
+void
+nv50_fb_takedown(struct drm_device *dev)
+{
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c
index 993c7126fbd..a8c70e7e918 100644
--- a/drivers/gpu/drm/nouveau/nv50_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
@@ -157,8 +157,11 @@ nv50_fbcon_accel_init(struct fb_info *info)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_channel *chan = dev_priv->channel;
struct nouveau_gpuobj *eng2d = NULL;
+ uint64_t fb;
int ret, format;
+ fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base;
+
switch (info->var.bits_per_pixel) {
case 8:
format = 0xf3;
@@ -233,7 +236,7 @@ nv50_fbcon_accel_init(struct fb_info *info)
BEGIN_RING(chan, NvSub2D, 0x0808, 3);
OUT_RING(chan, 0);
OUT_RING(chan, 0);
- OUT_RING(chan, 0);
+ OUT_RING(chan, 1);
BEGIN_RING(chan, NvSub2D, 0x081c, 1);
OUT_RING(chan, 1);
BEGIN_RING(chan, NvSub2D, 0x0840, 4);
@@ -248,9 +251,8 @@ nv50_fbcon_accel_init(struct fb_info *info)
OUT_RING(chan, info->fix.line_length);
OUT_RING(chan, info->var.xres_virtual);
OUT_RING(chan, info->var.yres_virtual);
- OUT_RING(chan, 0);
- OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
- dev_priv->vm_vram_base);
+ OUT_RING(chan, upper_32_bits(fb));
+ OUT_RING(chan, lower_32_bits(fb));
BEGIN_RING(chan, NvSub2D, 0x0230, 2);
OUT_RING(chan, format);
OUT_RING(chan, 1);
@@ -258,9 +260,8 @@ nv50_fbcon_accel_init(struct fb_info *info)
OUT_RING(chan, info->fix.line_length);
OUT_RING(chan, info->var.xres_virtual);
OUT_RING(chan, info->var.yres_virtual);
- OUT_RING(chan, 0);
- OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
- dev_priv->vm_vram_base);
+ OUT_RING(chan, upper_32_bits(fb));
+ OUT_RING(chan, lower_32_bits(fb));
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c
new file mode 100644
index 00000000000..c61782b314e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_gpio.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+static int
+nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift)
+{
+ const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+
+ if (gpio->line > 32)
+ return -EINVAL;
+
+ *reg = nv50_gpio_reg[gpio->line >> 3];
+ *shift = (gpio->line & 7) << 2;
+ return 0;
+}
+
+int
+nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
+{
+ struct dcb_gpio_entry *gpio;
+ uint32_t r, s, v;
+
+ gpio = nouveau_bios_gpio_entry(dev, tag);
+ if (!gpio)
+ return -ENOENT;
+
+ if (nv50_gpio_location(gpio, &r, &s))
+ return -EINVAL;
+
+ v = nv_rd32(dev, r) >> (s + 2);
+ return ((v & 1) == (gpio->state[1] & 1));
+}
+
+int
+nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
+{
+ struct dcb_gpio_entry *gpio;
+ uint32_t r, s, v;
+
+ gpio = nouveau_bios_gpio_entry(dev, tag);
+ if (!gpio)
+ return -ENOENT;
+
+ if (nv50_gpio_location(gpio, &r, &s))
+ return -EINVAL;
+
+ v = nv_rd32(dev, r) & ~(0x3 << s);
+ v |= (gpio->state[state] ^ 2) << s;
+ nv_wr32(dev, r, v);
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
index 857a09671a3..b203d06f601 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -56,6 +56,10 @@ nv50_graph_init_intr(struct drm_device *dev)
static void
nv50_graph_init_regs__nv(struct drm_device *dev)
{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t units = nv_rd32(dev, 0x1540);
+ int i;
+
NV_DEBUG(dev, "\n");
nv_wr32(dev, 0x400804, 0xc0000000);
@@ -65,6 +69,20 @@ nv50_graph_init_regs__nv(struct drm_device *dev)
nv_wr32(dev, 0x405018, 0xc0000000);
nv_wr32(dev, 0x402000, 0xc0000000);
+ for (i = 0; i < 16; i++) {
+ if (units & 1 << i) {
+ if (dev_priv->chipset < 0xa0) {
+ nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000);
+ nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000);
+ nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000);
+ } else {
+ nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000);
+ nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000);
+ nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000);
+ }
+ }
+ }
+
nv_wr32(dev, 0x400108, 0xffffffff);
nv_wr32(dev, 0x400824, 0x00004000);
@@ -229,10 +247,6 @@ nv50_graph_create_context(struct nouveau_channel *chan)
nouveau_grctx_vals_load(dev, ctx);
}
nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
- if ((dev_priv->chipset & 0xf0) == 0xa0)
- nv_wo32(dev, ctx, 0x00004/4, 0x00000000);
- else
- nv_wo32(dev, ctx, 0x0011c/4, 0x00000000);
dev_priv->engine.instmem.finish_access(dev);
return 0;
@@ -396,9 +410,10 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
{ 0x5039, false, NULL }, /* m2mf */
{ 0x502d, false, NULL }, /* 2d */
{ 0x50c0, false, NULL }, /* compute */
+ { 0x85c0, false, NULL }, /* compute (nva3, nva5, nva8) */
{ 0x5097, false, NULL }, /* tesla (nv50) */
- { 0x8297, false, NULL }, /* tesla (nv80/nv90) */
- { 0x8397, false, NULL }, /* tesla (nva0) */
- { 0x8597, false, NULL }, /* tesla (nva8) */
+ { 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */
+ { 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */
+ { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
{}
};
diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c
index d105fcd42ca..42a8fb20c1e 100644
--- a/drivers/gpu/drm/nouveau/nv50_grctx.c
+++ b/drivers/gpu/drm/nouveau/nv50_grctx.c
@@ -55,15 +55,18 @@
#define CP_FLAG_AUTO_LOAD ((2 * 32) + 5)
#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0
#define CP_FLAG_AUTO_LOAD_PENDING 1
+#define CP_FLAG_NEWCTX ((2 * 32) + 10)
+#define CP_FLAG_NEWCTX_BUSY 0
+#define CP_FLAG_NEWCTX_DONE 1
#define CP_FLAG_XFER ((2 * 32) + 11)
#define CP_FLAG_XFER_IDLE 0
#define CP_FLAG_XFER_BUSY 1
-#define CP_FLAG_NEWCTX ((2 * 32) + 12)
-#define CP_FLAG_NEWCTX_BUSY 0
-#define CP_FLAG_NEWCTX_DONE 1
#define CP_FLAG_ALWAYS ((2 * 32) + 13)
#define CP_FLAG_ALWAYS_FALSE 0
#define CP_FLAG_ALWAYS_TRUE 1
+#define CP_FLAG_INTR ((2 * 32) + 15)
+#define CP_FLAG_INTR_NOT_PENDING 0
+#define CP_FLAG_INTR_PENDING 1
#define CP_CTX 0x00100000
#define CP_CTX_COUNT 0x000f0000
@@ -174,6 +177,7 @@ nv50_grctx_init(struct nouveau_grctx *ctx)
case 0x96:
case 0x98:
case 0xa0:
+ case 0xa3:
case 0xa5:
case 0xa8:
case 0xaa:
@@ -214,6 +218,8 @@ nv50_grctx_init(struct nouveau_grctx *ctx)
cp_name(ctx, cp_setup_save);
cp_set (ctx, UNK1D, SET);
cp_wait(ctx, STATUS, BUSY);
+ cp_wait(ctx, INTR, PENDING);
+ cp_bra (ctx, STATUS, BUSY, cp_setup_save);
cp_set (ctx, UNK01, SET);
cp_set (ctx, SWAP_DIRECTION, SAVE);
@@ -269,7 +275,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
int offset, base;
uint32_t units = nv_rd32 (ctx->dev, 0x1540);
- /* 0800 */
+ /* 0800: DISPATCH */
cp_ctx(ctx, 0x400808, 7);
gr_def(ctx, 0x400814, 0x00000030);
cp_ctx(ctx, 0x400834, 0x32);
@@ -300,7 +306,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, 0x400b20, 0x0001629d);
}
- /* 0C00 */
+ /* 0C00: VFETCH */
cp_ctx(ctx, 0x400c08, 0x2);
gr_def(ctx, 0x400c08, 0x0000fe0c);
@@ -326,7 +332,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
cp_ctx(ctx, 0x401540, 0x5);
gr_def(ctx, 0x401550, 0x00001018);
- /* 1800 */
+ /* 1800: STREAMOUT */
cp_ctx(ctx, 0x401814, 0x1);
gr_def(ctx, 0x401814, 0x000000ff);
if (dev_priv->chipset == 0x50) {
@@ -359,6 +365,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
case 0xac:
gr_def(ctx, 0x401c00, 0x042500df);
break;
+ case 0xa3:
case 0xa5:
case 0xa8:
gr_def(ctx, 0x401c00, 0x142500df);
@@ -413,6 +420,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
break;
case 0x84:
case 0xa0:
+ case 0xa3:
case 0xa5:
case 0xa8:
case 0xaa:
@@ -641,7 +649,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
if (dev_priv->chipset == 0x50)
cp_ctx(ctx, 0x4063e0, 0x1);
- /* 6800 */
+ /* 6800: M2MF */
if (dev_priv->chipset < 0x90) {
cp_ctx(ctx, 0x406814, 0x2b);
gr_def(ctx, 0x406818, 0x00000f80);
@@ -787,6 +795,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
case 0xa5:
gr_def(ctx, offset + 0x1c, 0x310c0000);
break;
+ case 0xa3:
case 0xa8:
case 0xaa:
case 0xac:
@@ -854,6 +863,8 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
else
gr_def(ctx, offset + 0x8, 0x05010202);
gr_def(ctx, offset + 0xc, 0x00030201);
+ if (dev_priv->chipset == 0xa3)
+ cp_ctx(ctx, base + 0x36c, 1);
cp_ctx(ctx, base + 0x400, 2);
gr_def(ctx, base + 0x404, 0x00000040);
@@ -1154,7 +1165,9 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
nv50_graph_construct_gene_unk8(ctx);
if (dev_priv->chipset == 0xa0)
xf_emit(ctx, 0x189, 0);
- else if (dev_priv->chipset < 0xa8)
+ else if (dev_priv->chipset == 0xa3)
+ xf_emit(ctx, 0xd5, 0);
+ else if (dev_priv->chipset == 0xa5)
xf_emit(ctx, 0x99, 0);
else if (dev_priv->chipset == 0xaa)
xf_emit(ctx, 0x65, 0);
@@ -1192,6 +1205,8 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
ctx->ctxvals_pos = offset + 4;
if (dev_priv->chipset == 0xa0)
xf_emit(ctx, 0xa80, 0);
+ else if (dev_priv->chipset == 0xa3)
+ xf_emit(ctx, 0xa7c, 0);
else
xf_emit(ctx, 0xa7a, 0);
xf_emit(ctx, 1, 0x3fffff);
@@ -1336,6 +1351,7 @@ nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx)
xf_emit(ctx, 0x942, 0);
break;
case 0xa0:
+ case 0xa3:
xf_emit(ctx, 0x2042, 0);
break;
case 0xa5:
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index de1f5b0062c..5f21df31f3a 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -63,9 +63,10 @@ nv50_instmem_init(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_channel *chan;
uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size;
+ uint32_t save_nv001700;
+ uint64_t v;
struct nv50_instmem_priv *priv;
int ret, i;
- uint32_t v, save_nv001700;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -76,17 +77,12 @@ nv50_instmem_init(struct drm_device *dev)
for (i = 0x1700; i <= 0x1710; i += 4)
priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i);
- if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
- dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
- else
- dev_priv->vram_sys_base = 0;
-
/* Reserve the last MiB of VRAM, we should probably try to avoid
* setting up the below tables over the top of the VBIOS image at
* some point.
*/
dev_priv->ramin_rsvd_vram = 1 << 20;
- c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram;
+ c_offset = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;
c_size = 128 << 10;
c_vmpd = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200;
c_ramfc = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20;
@@ -106,7 +102,7 @@ nv50_instmem_init(struct drm_device *dev)
dev_priv->vm_gart_size = NV50_VM_BLOCK;
dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size;
- dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev);
+ dev_priv->vm_vram_size = dev_priv->vram_size;
if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM)
dev_priv->vm_vram_size = NV50_VM_MAX_VRAM;
dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK);
@@ -189,8 +185,8 @@ nv50_instmem_init(struct drm_device *dev)
i = 0;
while (v < dev_priv->vram_sys_base + c_offset + c_size) {
- BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v);
- BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
+ BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, lower_32_bits(v));
+ BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, upper_32_bits(v));
v += 0x1000;
i += 8;
}
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
index c2fff543b06..0c68698f23d 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode_ctl = 0x0200;
break;
case OUTPUT_DP:
- mode_ctl |= 0x00050000;
+ mode_ctl |= (nv_encoder->dp.mc_unknown << 16);
if (nv_encoder->dcb->sorconf.link & 1)
mode_ctl |= 0x00000800;
else
@@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
int
nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_encoder *nv_encoder = NULL;
struct drm_encoder *encoder;
bool dum;
@@ -319,5 +320,27 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
encoder->possible_crtcs = entry->heads;
encoder->possible_clones = 0;
+ if (nv_encoder->dcb->type == OUTPUT_DP) {
+ uint32_t mc, or = nv_encoder->or;
+
+ if (dev_priv->chipset < 0x90 ||
+ dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
+ mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
+ else
+ mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
+
+ switch ((mc & 0x00000f00) >> 8) {
+ case 8:
+ case 9:
+ nv_encoder->dp.mc_unknown = (mc & 0x000f0000) >> 16;
+ break;
+ default:
+ break;
+ }
+
+ if (!nv_encoder->dp.mc_unknown)
+ nv_encoder->dp.mc_unknown = 5;
+ }
+
return 0;
}
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c
index 4c39a407aa4..e671d0e74d4 100644
--- a/drivers/gpu/drm/r128/r128_cce.c
+++ b/drivers/gpu/drm/r128/r128_cce.c
@@ -31,6 +31,7 @@
#include <linux/firmware.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index ed38262d998..3c91312dea9 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -50,7 +50,7 @@ $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h
radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
radeon_irq.o r300_cmdbuf.o r600_cp.o
# add KMS driver
-radeon-y += radeon_device.o radeon_kms.o \
+radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \
atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \
radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index d75788feac6..1d569830ed9 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#define ATOM_DEBUG
@@ -52,15 +53,17 @@
typedef struct {
struct atom_context *ctx;
-
uint32_t *ps, *ws;
int ps_shift;
uint16_t start;
+ unsigned last_jump;
+ unsigned long last_jump_jiffies;
+ bool abort;
} atom_exec_context;
int atom_debug = 0;
-static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
-void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
+static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
+int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
static uint32_t atom_arg_mask[8] =
{ 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
@@ -604,12 +607,17 @@ static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg)
static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
{
int idx = U8((*ptr)++);
+ int r = 0;
+
if (idx < ATOM_TABLE_NAMES_CNT)
SDEBUG(" table: %d (%s)\n", idx, atom_table_names[idx]);
else
SDEBUG(" table: %d\n", idx);
if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
- atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+ r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+ if (r) {
+ ctx->abort = true;
+ }
}
static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
@@ -673,6 +681,8 @@ static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg)
static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
{
int execute = 0, target = U16(*ptr);
+ unsigned long cjiffies;
+
(*ptr) += 2;
switch (arg) {
case ATOM_COND_ABOVE:
@@ -700,8 +710,25 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
if (arg != ATOM_COND_ALWAYS)
SDEBUG(" taken: %s\n", execute ? "yes" : "no");
SDEBUG(" target: 0x%04X\n", target);
- if (execute)
+ if (execute) {
+ if (ctx->last_jump == (ctx->start + target)) {
+ cjiffies = jiffies;
+ if (time_after(cjiffies, ctx->last_jump_jiffies)) {
+ cjiffies -= ctx->last_jump_jiffies;
+ if ((jiffies_to_msecs(cjiffies) > 1000)) {
+ DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n");
+ ctx->abort = true;
+ }
+ } else {
+ /* jiffies wrap around we will just wait a little longer */
+ ctx->last_jump_jiffies = jiffies;
+ }
+ } else {
+ ctx->last_jump = ctx->start + target;
+ ctx->last_jump_jiffies = jiffies;
+ }
*ptr = ctx->start + target;
+ }
}
static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
@@ -881,11 +908,16 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
uint8_t attr = U8((*ptr)++), shift;
uint32_t saved, dst;
int dptr = *ptr;
+ uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
SDEBUG(" dst: ");
dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+ /* op needs to full dst value */
+ dst = saved;
shift = atom_get_src(ctx, attr, ptr);
SDEBUG(" shift: %d\n", shift);
dst <<= shift;
+ dst &= atom_arg_mask[dst_align];
+ dst >>= atom_arg_shift[dst_align];
SDEBUG(" dst: ");
atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
}
@@ -895,11 +927,16 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
uint8_t attr = U8((*ptr)++), shift;
uint32_t saved, dst;
int dptr = *ptr;
+ uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
SDEBUG(" dst: ");
dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+ /* op needs to full dst value */
+ dst = saved;
shift = atom_get_src(ctx, attr, ptr);
SDEBUG(" shift: %d\n", shift);
dst >>= shift;
+ dst &= atom_arg_mask[dst_align];
+ dst >>= atom_arg_shift[dst_align];
SDEBUG(" dst: ");
atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
}
@@ -1104,15 +1141,16 @@ static struct {
atom_op_shr, ATOM_ARG_MC}, {
atom_op_debug, 0},};
-static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
+static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
{
int base = CU16(ctx->cmd_table + 4 + 2 * index);
int len, ws, ps, ptr;
unsigned char op;
atom_exec_context ectx;
+ int ret = 0;
if (!base)
- return;
+ return -EINVAL;
len = CU16(base + ATOM_CT_SIZE_PTR);
ws = CU8(base + ATOM_CT_WS_PTR);
@@ -1125,6 +1163,8 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
ectx.ps_shift = ps / 4;
ectx.start = base;
ectx.ps = params;
+ ectx.abort = false;
+ ectx.last_jump = 0;
if (ws)
ectx.ws = kzalloc(4 * ws, GFP_KERNEL);
else
@@ -1137,6 +1177,12 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1);
else
SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1);
+ if (ectx.abort) {
+ DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n",
+ base, len, ws, ps, ptr - 1);
+ ret = -EINVAL;
+ goto free;
+ }
if (op < ATOM_OP_CNT && op > 0)
opcode_table[op].func(&ectx, &ptr,
@@ -1150,12 +1196,16 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
debug_depth--;
SDEBUG("<<\n");
+free:
if (ws)
kfree(ectx.ws);
+ return ret;
}
-void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
{
+ int r;
+
mutex_lock(&ctx->mutex);
/* reset reg block */
ctx->reg_block = 0;
@@ -1163,8 +1213,9 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
ctx->fb_base = 0;
/* reset io mode */
ctx->io_mode = ATOM_IO_MM;
- atom_execute_table_locked(ctx, index, params);
+ r = atom_execute_table_locked(ctx, index, params);
mutex_unlock(&ctx->mutex);
+ return r;
}
static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
@@ -1248,9 +1299,7 @@ int atom_asic_init(struct atom_context *ctx)
if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))
return 1;
- atom_execute_table(ctx, ATOM_CMD_INIT, ps);
-
- return 0;
+ return atom_execute_table(ctx, ATOM_CMD_INIT, ps);
}
void atom_destroy(struct atom_context *ctx)
@@ -1260,12 +1309,16 @@ void atom_destroy(struct atom_context *ctx)
kfree(ctx);
}
-void atom_parse_data_header(struct atom_context *ctx, int index,
+bool atom_parse_data_header(struct atom_context *ctx, int index,
uint16_t * size, uint8_t * frev, uint8_t * crev,
uint16_t * data_start)
{
int offset = index * 2 + 4;
int idx = CU16(ctx->data_table + offset);
+ u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4);
+
+ if (!mdt[index])
+ return false;
if (size)
*size = CU16(idx);
@@ -1274,38 +1327,42 @@ void atom_parse_data_header(struct atom_context *ctx, int index,
if (crev)
*crev = CU8(idx + 3);
*data_start = idx;
- return;
+ return true;
}
-void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
+bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
uint8_t * crev)
{
int offset = index * 2 + 4;
int idx = CU16(ctx->cmd_table + offset);
+ u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
+
+ if (!mct[index])
+ return false;
if (frev)
*frev = CU8(idx + 2);
if (crev)
*crev = CU8(idx + 3);
- return;
+ return true;
}
int atom_allocate_fb_scratch(struct atom_context *ctx)
{
int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
uint16_t data_offset;
- int usage_bytes;
+ int usage_bytes = 0;
struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
- atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
+ if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
+ firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
- firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
+ DRM_DEBUG("atom firmware requested %08x %dkb\n",
+ firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
+ firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
- DRM_DEBUG("atom firmware requested %08x %dkb\n",
- firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
- firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
-
- usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+ usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+ }
if (usage_bytes == 0)
usage_bytes = 20 * 1024;
/* allocate some scratch memory */
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index bc73781423a..cd1b64ab5ca 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -140,11 +140,13 @@ struct atom_context {
extern int atom_debug;
struct atom_context *atom_parse(struct card_info *, void *);
-void atom_execute_table(struct atom_context *, int, uint32_t *);
+int atom_execute_table(struct atom_context *, int, uint32_t *);
int atom_asic_init(struct atom_context *);
void atom_destroy(struct atom_context *);
-void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
-void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
+bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
+ uint8_t *frev, uint8_t *crev, uint16_t *data_start);
+bool atom_parse_cmd_header(struct atom_context *ctx, int index,
+ uint8_t *frev, uint8_t *crev);
int atom_allocate_fb_scratch(struct atom_context *ctx);
#include "atom-types.h"
#include "atombios.h"
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index dd9fdf56061..a87990b3ae8 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -353,12 +353,55 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
+static void atombios_disable_ss(struct drm_crtc *crtc)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ u32 ss_cntl;
+
+ if (ASIC_IS_DCE4(rdev)) {
+ switch (radeon_crtc->pll_id) {
+ case ATOM_PPLL1:
+ ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
+ ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
+ WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
+ break;
+ case ATOM_PPLL2:
+ ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
+ ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
+ WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
+ break;
+ case ATOM_DCPLL:
+ case ATOM_PPLL_INVALID:
+ return;
+ }
+ } else if (ASIC_IS_AVIVO(rdev)) {
+ switch (radeon_crtc->pll_id) {
+ case ATOM_PPLL1:
+ ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
+ ss_cntl &= ~1;
+ WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
+ break;
+ case ATOM_PPLL2:
+ ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
+ ss_cntl &= ~1;
+ WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
+ break;
+ case ATOM_DCPLL:
+ case ATOM_PPLL_INVALID:
+ return;
+ }
+ }
+}
+
+
union atom_enable_ss {
ENABLE_LVDS_SS_PARAMETERS legacy;
ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
};
-static void atombios_set_ss(struct drm_crtc *crtc, int enable)
+static void atombios_enable_ss(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
@@ -387,9 +430,9 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
step = dig->ss->step;
delay = dig->ss->delay;
range = dig->ss->range;
- } else if (enable)
+ } else
return;
- } else if (enable)
+ } else
return;
break;
}
@@ -406,13 +449,13 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
args.v1.ucSpreadSpectrumDelay = delay;
args.v1.ucSpreadSpectrumRange = range;
args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
- args.v1.ucEnable = enable;
+ args.v1.ucEnable = ATOM_ENABLE;
} else {
args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
args.legacy.ucSpreadSpectrumType = type;
args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
- args.legacy.ucEnable = enable;
+ args.legacy.ucEnable = ATOM_ENABLE;
}
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
@@ -478,10 +521,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
adjusted_clock = mode->clock * 2;
- /* LVDS PLL quirks */
- if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- pll->algo = dig->pll_algo;
+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+ pll->algo = PLL_ALGO_LEGACY;
+ pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
}
} else {
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
@@ -503,8 +545,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
int index;
index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
- atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
- &crev);
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+ &crev))
+ return adjusted_clock;
memset(&args, 0, sizeof(args));
@@ -542,11 +585,16 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
}
} else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
/* may want to enable SS on DP/eDP eventually */
- args.v3.sInput.ucDispPllConfig |=
- DISPPLL_CONFIG_SS_ENABLE;
- if (mode->clock > 165000)
+ /*args.v3.sInput.ucDispPllConfig |=
+ DISPPLL_CONFIG_SS_ENABLE;*/
+ if (encoder_mode == ATOM_ENCODER_MODE_DP)
args.v3.sInput.ucDispPllConfig |=
- DISPPLL_CONFIG_DUAL_LINK;
+ DISPPLL_CONFIG_COHERENT_MODE;
+ else {
+ if (mode->clock > 165000)
+ args.v3.sInput.ucDispPllConfig |=
+ DISPPLL_CONFIG_DUAL_LINK;
+ }
}
atom_execute_table(rdev->mode_info.atom_context,
index, (uint32_t *)&args);
@@ -592,8 +640,9 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
memset(&args, 0, sizeof(args));
index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
- atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
- &crev);
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+ &crev))
+ return;
switch (frev) {
case 1:
@@ -667,8 +716,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
&ref_div, &post_div);
index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
- atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
- &crev);
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+ &crev))
+ return;
switch (frev) {
case 1:
@@ -1083,15 +1133,12 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
/* TODO color tiling */
- /* pick pll */
- radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
-
- atombios_set_ss(crtc, 0);
+ atombios_disable_ss(crtc);
/* always set DCPLL */
if (ASIC_IS_DCE4(rdev))
atombios_crtc_set_dcpll(crtc);
atombios_crtc_set_pll(crtc, adjusted_mode);
- atombios_set_ss(crtc, 1);
+ atombios_enable_ss(crtc);
if (ASIC_IS_DCE4(rdev))
atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
@@ -1120,6 +1167,11 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
static void atombios_crtc_prepare(struct drm_crtc *crtc)
{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+ /* pick pll */
+ radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
+
atombios_lock_crtc(crtc, ATOM_ENABLE);
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
}
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 8a133bda00a..28b31c64f48 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -745,14 +745,14 @@ void dp_link_train(struct drm_encoder *encoder,
>> DP_TRAIN_PRE_EMPHASIS_SHIFT);
/* disable the training pattern on the sink */
+ dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
+
+ /* disable the training pattern on the source */
if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
else
radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
dig_connector->dp_clock, enc_id, 0);
-
- radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
- dig_connector->dp_clock, enc_id, 0);
}
int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index bd2e7aa85c1..e8f447e2050 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -23,8 +23,10 @@
*/
#include <linux/firmware.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "radeon_drm.h"
#include "rv770d.h"
#include "atom.h"
@@ -436,7 +438,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
int evergreen_mc_init(struct radeon_device *rdev)
{
- fixed20_12 a;
u32 tmp;
int chansize, numchan;
@@ -481,12 +482,8 @@ int evergreen_mc_init(struct radeon_device *rdev)
rdev->mc.real_vram_size = rdev->mc.aper_size;
}
r600_vram_gtt_location(rdev, &rdev->mc);
- /* FIXME: we should enforce default clock in case GPU is not in
- * default setup
- */
- a.full = rfixed_const(100);
- rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
- rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+ radeon_update_bandwidth_info(rdev);
+
return 0;
}
@@ -746,6 +743,7 @@ int evergreen_init(struct radeon_device *rdev)
void evergreen_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
evergreen_suspend(rdev);
#if 0
r600_blit_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 91eb762eb3f..d7388fdb6d0 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -26,11 +26,13 @@
* Jerome Glisse
*/
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "radeon_drm.h"
#include "radeon_reg.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "r100d.h"
#include "rs100d.h"
#include "rv200d.h"
@@ -235,9 +237,9 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
void r100_pci_gart_fini(struct radeon_device *rdev)
{
+ radeon_gart_fini(rdev);
r100_pci_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
- radeon_gart_fini(rdev);
}
int r100_irq_set(struct radeon_device *rdev)
@@ -312,10 +314,12 @@ int r100_irq_process(struct radeon_device *rdev)
/* Vertical blank interrupts */
if (status & RADEON_CRTC_VBLANK_STAT) {
drm_handle_vblank(rdev->ddev, 0);
+ rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue);
}
if (status & RADEON_CRTC2_VBLANK_STAT) {
drm_handle_vblank(rdev->ddev, 1);
+ rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue);
}
if (status & RADEON_FP_DETECT_STAT) {
@@ -741,6 +745,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
udelay(10);
rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR);
+ /* protect against crazy HW on resume */
+ rdev->cp.wptr &= rdev->cp.ptr_mask;
/* Set cp mode to bus mastering & enable cp*/
WREG32(RADEON_CP_CSQ_MODE,
REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
@@ -1804,6 +1810,7 @@ void r100_set_common_regs(struct radeon_device *rdev)
{
struct drm_device *dev = rdev->ddev;
bool force_dac2 = false;
+ u32 tmp;
/* set these so they don't interfere with anything */
WREG32(RADEON_OV0_SCALE_CNTL, 0);
@@ -1875,6 +1882,12 @@ void r100_set_common_regs(struct radeon_device *rdev)
WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
WREG32(RADEON_DAC_CNTL2, dac2_cntl);
}
+
+ /* switch PM block to ACPI mode */
+ tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
+ tmp &= ~RADEON_PM_MODE_SEL;
+ WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
+
}
/*
@@ -2022,6 +2035,7 @@ void r100_mc_init(struct radeon_device *rdev)
radeon_vram_location(rdev, &rdev->mc, base);
if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc);
+ radeon_update_bandwidth_info(rdev);
}
@@ -2385,6 +2399,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)
uint32_t pixel_bytes1 = 0;
uint32_t pixel_bytes2 = 0;
+ radeon_update_display_priority(rdev);
+
if (rdev->mode_info.crtcs[0]->base.enabled) {
mode1 = &rdev->mode_info.crtcs[0]->base.mode;
pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
@@ -2413,11 +2429,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)
/*
* determine is there is enough bw for current mode
*/
- mclk_ff.full = rfixed_const(rdev->clock.default_mclk);
- temp_ff.full = rfixed_const(100);
- mclk_ff.full = rfixed_div(mclk_ff, temp_ff);
- sclk_ff.full = rfixed_const(rdev->clock.default_sclk);
- sclk_ff.full = rfixed_div(sclk_ff, temp_ff);
+ sclk_ff = rdev->pm.sclk;
+ mclk_ff = rdev->pm.mclk;
temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);
temp_ff.full = rfixed_const(temp);
@@ -2878,7 +2891,7 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
{
struct radeon_bo *robj;
unsigned long size;
- unsigned u, i, w, h;
+ unsigned u, i, w, h, d;
int ret;
for (u = 0; u < track->num_texture; u++) {
@@ -2910,20 +2923,25 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
h = h / (1 << i);
if (track->textures[u].roundup_h)
h = roundup_pow_of_two(h);
+ if (track->textures[u].tex_coord_type == 1) {
+ d = (1 << track->textures[u].txdepth) / (1 << i);
+ if (!d)
+ d = 1;
+ } else {
+ d = 1;
+ }
if (track->textures[u].compress_format) {
- size += r100_track_compress_size(track->textures[u].compress_format, w, h);
+ size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d;
/* compressed textures are block based */
} else
- size += w * h;
+ size += w * h * d;
}
size *= track->textures[u].cpp;
switch (track->textures[u].tex_coord_type) {
case 0:
- break;
case 1:
- size *= (1 << track->textures[u].txdepth);
break;
case 2:
if (track->separate_cube) {
@@ -2994,7 +3012,11 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
}
}
prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
- nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+ if (track->vap_vf_cntl & (1 << 14)) {
+ nverts = track->vap_alt_nverts;
+ } else {
+ nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+ }
switch (prim_walk) {
case 1:
for (i = 0; i < track->num_arrays; i++) {
@@ -3440,6 +3462,7 @@ int r100_suspend(struct radeon_device *rdev)
void r100_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r100_cp_fini(rdev);
r100_wb_fini(rdev);
r100_ib_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h
index b27a6999d21..fadfe68de9c 100644
--- a/drivers/gpu/drm/radeon/r100_track.h
+++ b/drivers/gpu/drm/radeon/r100_track.h
@@ -64,6 +64,7 @@ struct r100_cs_track {
unsigned maxy;
unsigned vtx_size;
unsigned vap_vf_cntl;
+ unsigned vap_alt_nverts;
unsigned immd_dwords;
unsigned num_arrays;
unsigned max_indx;
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index 1146c9909c2..85617c31121 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -30,6 +30,7 @@
#include "radeon_drm.h"
#include "radeon_reg.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "r100d.h"
#include "r200_reg_safe.h"
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 4cef90cd74e..eaf1f6bc44f 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -26,10 +26,12 @@
* Jerome Glisse
*/
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "radeon_reg.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "radeon_drm.h"
#include "r100_track.h"
#include "r300d.h"
@@ -164,9 +166,9 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
void rv370_pcie_gart_fini(struct radeon_device *rdev)
{
+ radeon_gart_fini(rdev);
rv370_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
- radeon_gart_fini(rdev);
}
void r300_fence_ring_emit(struct radeon_device *rdev,
@@ -322,12 +324,12 @@ void r300_gpu_init(struct radeon_device *rdev)
uint32_t gb_tile_config, tmp;
r100_hdp_reset(rdev);
- /* FIXME: rv380 one pipes ? */
- if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) {
+ if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
+ (rdev->family == CHIP_R350 && rdev->pdev->device != 0x4148)) {
/* r300,r350 */
rdev->num_gb_pipes = 2;
} else {
- /* rv350,rv370,rv380 */
+ /* rv350,rv370,rv380,r300 AD, r350 AH */
rdev->num_gb_pipes = 1;
}
rdev->num_z_pipes = 1;
@@ -481,6 +483,7 @@ void r300_mc_init(struct radeon_device *rdev)
radeon_vram_location(rdev, &rdev->mc, base);
if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc);
+ radeon_update_bandwidth_info(rdev);
}
void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
@@ -726,6 +729,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
/* VAP_VF_MAX_VTX_INDX */
track->max_indx = idx_value & 0x00FFFFFFUL;
break;
+ case 0x2088:
+ /* VAP_ALT_NUM_VERTICES - only valid on r500 */
+ if (p->rdev->family < CHIP_RV515)
+ goto fail;
+ track->vap_alt_nverts = idx_value & 0xFFFFFF;
+ break;
case 0x43E4:
/* SC_SCISSOR1 */
track->maxy = ((idx_value >> 13) & 0x1FFF) + 1;
@@ -763,7 +772,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
tmp = idx_value & ~(0x7 << 16);
tmp |= tile_flags;
ib[idx] = tmp;
-
i = (reg - 0x4E38) >> 2;
track->cb[i].pitch = idx_value & 0x3FFE;
switch (((idx_value >> 21) & 0xF)) {
@@ -1048,11 +1056,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
break;
/* fallthrough do not move */
default:
- printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
- reg, idx);
- return -EINVAL;
+ goto fail;
}
return 0;
+fail:
+ printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+ reg, idx);
+ return -EINVAL;
}
static int r300_packet3_check(struct radeon_cs_parser *p,
@@ -1334,6 +1344,7 @@ int r300_suspend(struct radeon_device *rdev)
void r300_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r100_cp_fini(rdev);
r100_wb_fini(rdev);
r100_ib_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
index ea46d558e8f..c5c2742e414 100644
--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -921,7 +921,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
ptr_addr = drm_buffer_read_object(cmdbuf->buffer,
sizeof(stack_ptr_addr), &stack_ptr_addr);
- ref_age_base = (u32 *)(unsigned long)*ptr_addr;
+ ref_age_base = (u32 *)(unsigned long)get_unaligned(ptr_addr);
for (i=0; i < header.scratch.n_bufs; i++) {
buf_idx = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index c7593b8f58e..c2bda4ad62e 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -26,9 +26,11 @@
* Jerome Glisse
*/
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "radeon_reg.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "atom.h"
#include "r100d.h"
#include "r420d.h"
@@ -57,6 +59,12 @@ void r420_pipes_init(struct radeon_device *rdev)
/* get max number of pipes */
gb_pipe_select = RREG32(0x402C);
num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
+
+ /* SE chips have 1 pipe */
+ if ((rdev->pdev->device == 0x5e4c) ||
+ (rdev->pdev->device == 0x5e4f))
+ num_pipes = 1;
+
rdev->num_gb_pipes = num_pipes;
tmp = 0;
switch (num_pipes) {
@@ -266,6 +274,7 @@ int r420_suspend(struct radeon_device *rdev)
void r420_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r100_cp_fini(rdev);
r100_wb_fini(rdev);
r100_ib_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 2b8a5dd1351..3c44b8d3931 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -27,6 +27,7 @@
*/
#include "drmP.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "atom.h"
#include "r520d.h"
@@ -121,19 +122,13 @@ static void r520_vram_get_type(struct radeon_device *rdev)
void r520_mc_init(struct radeon_device *rdev)
{
- fixed20_12 a;
r520_vram_get_type(rdev);
r100_vram_init_sizes(rdev);
radeon_vram_location(rdev, &rdev->mc, 0);
if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc);
- /* FIXME: we should enforce default clock in case GPU is not in
- * default setup
- */
- a.full = rfixed_const(100);
- rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
- rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+ radeon_update_bandwidth_info(rdev);
}
void r520_mc_program(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c5229019729..8f3454e2056 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -25,12 +25,14 @@
* Alex Deucher
* Jerome Glisse
*/
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include "drmP.h"
#include "radeon_drm.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "radeon_mode.h"
#include "r600d.h"
#include "atom.h"
@@ -491,9 +493,9 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
void r600_pcie_gart_fini(struct radeon_device *rdev)
{
+ radeon_gart_fini(rdev);
r600_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
- radeon_gart_fini(rdev);
}
void r600_agp_enable(struct radeon_device *rdev)
@@ -675,7 +677,6 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
int r600_mc_init(struct radeon_device *rdev)
{
- fixed20_12 a;
u32 tmp;
int chansize, numchan;
@@ -719,14 +720,10 @@ int r600_mc_init(struct radeon_device *rdev)
rdev->mc.real_vram_size = rdev->mc.aper_size;
}
r600_vram_gtt_location(rdev, &rdev->mc);
- /* FIXME: we should enforce default clock in case GPU is not in
- * default setup
- */
- a.full = rfixed_const(100);
- rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
- rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+
if (rdev->flags & RADEON_IS_IGP)
rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+ radeon_update_bandwidth_info(rdev);
return 0;
}
@@ -1132,6 +1129,7 @@ void r600_gpu_init(struct radeon_device *rdev)
/* Setup pipes */
WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+ WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK);
@@ -2119,6 +2117,7 @@ int r600_init(struct radeon_device *rdev)
void r600_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r600_audio_fini(rdev);
r600_blit_fini(rdev);
r600_cp_fini(rdev);
@@ -2398,19 +2397,19 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev)
WREG32(DC_HPD4_INT_CONTROL, tmp);
if (ASIC_IS_DCE32(rdev)) {
tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
- WREG32(DC_HPD5_INT_CONTROL, 0);
+ WREG32(DC_HPD5_INT_CONTROL, tmp);
tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
- WREG32(DC_HPD6_INT_CONTROL, 0);
+ WREG32(DC_HPD6_INT_CONTROL, tmp);
}
} else {
WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
- WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0);
+ WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
- WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0);
+ WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
- WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0);
+ WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
}
}
@@ -2765,6 +2764,7 @@ restart_ih:
case 0: /* D1 vblank */
if (disp_int & LB_D1_VBLANK_INTERRUPT) {
drm_handle_vblank(rdev->ddev, 0);
+ rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue);
disp_int &= ~LB_D1_VBLANK_INTERRUPT;
DRM_DEBUG("IH: D1 vblank\n");
@@ -2786,6 +2786,7 @@ restart_ih:
case 0: /* D2 vblank */
if (disp_int & LB_D2_VBLANK_INTERRUPT) {
drm_handle_vblank(rdev->ddev, 1);
+ rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue);
disp_int &= ~LB_D2_VBLANK_INTERRUPT;
DRM_DEBUG("IH: D2 vblank\n");
@@ -2834,14 +2835,14 @@ restart_ih:
break;
case 10:
if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
- disp_int_cont &= ~DC_HPD5_INTERRUPT;
+ disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
queue_hotplug = true;
DRM_DEBUG("IH: HPD5\n");
}
break;
case 12:
if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
- disp_int_cont &= ~DC_HPD6_INTERRUPT;
+ disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
queue_hotplug = true;
DRM_DEBUG("IH: HPD6\n");
}
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c
index db928016d03..1d898051c63 100644
--- a/drivers/gpu/drm/radeon/r600_audio.c
+++ b/drivers/gpu/drm/radeon/r600_audio.c
@@ -35,7 +35,7 @@
*/
static int r600_audio_chipset_supported(struct radeon_device *rdev)
{
- return rdev->family >= CHIP_R600
+ return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR)
|| rdev->family == CHIP_RS600
|| rdev->family == CHIP_RS690
|| rdev->family == CHIP_RS740;
@@ -182,41 +182,6 @@ int r600_audio_init(struct radeon_device *rdev)
}
/*
- * determin how the encoders and audio interface is wired together
- */
-int r600_audio_tmds_index(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct drm_encoder *other;
-
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- return 0;
-
- case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
- /* special case check if an TMDS1 is present */
- list_for_each_entry(other, &dev->mode_config.encoder_list, head) {
- if (to_radeon_encoder(other)->encoder_id ==
- ENCODER_OBJECT_ID_INTERNAL_TMDS1)
- return 1;
- }
- return 0;
-
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- return 1;
-
- default:
- DRM_ERROR("Unsupported encoder type 0x%02X\n",
- radeon_encoder->encoder_id);
- return -1;
- }
-}
-
-/*
* atach the audio codec to the clock source of the encoder
*/
void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
@@ -224,6 +189,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
int base_rate = 48000;
switch (radeon_encoder->encoder_id) {
@@ -231,32 +197,34 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);
break;
-
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);
break;
-
default:
DRM_ERROR("Unsupported encoder type 0x%02X\n",
radeon_encoder->encoder_id);
return;
}
- switch (r600_audio_tmds_index(encoder)) {
+ switch (dig->dig_encoder) {
case 0:
- WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);
- WREG32(R600_AUDIO_PLL1_DIV, clock*100);
+ WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50);
+ WREG32(R600_AUDIO_PLL1_DIV, clock * 100);
WREG32(R600_AUDIO_CLK_SRCSEL, 0);
break;
case 1:
- WREG32(R600_AUDIO_PLL2_MUL, base_rate*50);
- WREG32(R600_AUDIO_PLL2_DIV, clock*100);
+ WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50);
+ WREG32(R600_AUDIO_PLL2_DIV, clock * 100);
WREG32(R600_AUDIO_CLK_SRCSEL, 1);
break;
+ default:
+ dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n",
+ radeon_encoder->encoder_id);
+ return;
}
}
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c
index a112c59f9d8..0271b53fa2d 100644
--- a/drivers/gpu/drm/radeon/r600_blit_shaders.c
+++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c
@@ -1,7 +1,42 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Alex Deucher <alexander.deucher@amd.com>
+ */
#include <linux/types.h>
#include <linux/kernel.h>
+/*
+ * R6xx+ cards need to use the 3D engine to blit data which requires
+ * quite a bit of hw state setup. Rather than pull the whole 3D driver
+ * (which normally generates the 3D state) into the DRM, we opt to use
+ * statically generated state tables. The regsiter state and shaders
+ * were hand generated to support blitting functionality. See the 3D
+ * driver or documentation for descriptions of the registers and
+ * shader instructions.
+ */
+
const u32 r6xx_default_state[] =
{
0xc0002400,
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
index 40416c068d9..68e6f434930 100644
--- a/drivers/gpu/drm/radeon/r600_cp.c
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -1548,10 +1548,13 @@ static void r700_gfx_init(struct drm_device *dev,
RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+ RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0);
RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0);
+ RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0);
+ RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0);
num_qd_pipes =
R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8);
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index cd2c63bce50..c39c1bc1301 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -45,6 +45,7 @@ struct r600_cs_track {
u32 nbanks;
u32 npipes;
/* value we track */
+ u32 sq_config;
u32 nsamples;
u32 cb_color_base_last[8];
struct radeon_bo *cb_color_bo[8];
@@ -141,6 +142,8 @@ static void r600_cs_track_init(struct r600_cs_track *track)
{
int i;
+ /* assume DX9 mode */
+ track->sq_config = DX9_CONSTS;
for (i = 0; i < 8; i++) {
track->cb_color_base_last[i] = 0;
track->cb_color_size[i] = 0;
@@ -715,6 +718,9 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
tmp =radeon_get_ib_value(p, idx);
ib[idx] = 0;
break;
+ case SQ_CONFIG:
+ track->sq_config = radeon_get_ib_value(p, idx);
+ break;
case R_028800_DB_DEPTH_CONTROL:
track->db_depth_control = radeon_get_ib_value(p, idx);
break;
@@ -869,6 +875,54 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
case SQ_PGM_START_VS:
case SQ_PGM_START_GS:
case SQ_PGM_START_PS:
+ case SQ_ALU_CONST_CACHE_GS_0:
+ case SQ_ALU_CONST_CACHE_GS_1:
+ case SQ_ALU_CONST_CACHE_GS_2:
+ case SQ_ALU_CONST_CACHE_GS_3:
+ case SQ_ALU_CONST_CACHE_GS_4:
+ case SQ_ALU_CONST_CACHE_GS_5:
+ case SQ_ALU_CONST_CACHE_GS_6:
+ case SQ_ALU_CONST_CACHE_GS_7:
+ case SQ_ALU_CONST_CACHE_GS_8:
+ case SQ_ALU_CONST_CACHE_GS_9:
+ case SQ_ALU_CONST_CACHE_GS_10:
+ case SQ_ALU_CONST_CACHE_GS_11:
+ case SQ_ALU_CONST_CACHE_GS_12:
+ case SQ_ALU_CONST_CACHE_GS_13:
+ case SQ_ALU_CONST_CACHE_GS_14:
+ case SQ_ALU_CONST_CACHE_GS_15:
+ case SQ_ALU_CONST_CACHE_PS_0:
+ case SQ_ALU_CONST_CACHE_PS_1:
+ case SQ_ALU_CONST_CACHE_PS_2:
+ case SQ_ALU_CONST_CACHE_PS_3:
+ case SQ_ALU_CONST_CACHE_PS_4:
+ case SQ_ALU_CONST_CACHE_PS_5:
+ case SQ_ALU_CONST_CACHE_PS_6:
+ case SQ_ALU_CONST_CACHE_PS_7:
+ case SQ_ALU_CONST_CACHE_PS_8:
+ case SQ_ALU_CONST_CACHE_PS_9:
+ case SQ_ALU_CONST_CACHE_PS_10:
+ case SQ_ALU_CONST_CACHE_PS_11:
+ case SQ_ALU_CONST_CACHE_PS_12:
+ case SQ_ALU_CONST_CACHE_PS_13:
+ case SQ_ALU_CONST_CACHE_PS_14:
+ case SQ_ALU_CONST_CACHE_PS_15:
+ case SQ_ALU_CONST_CACHE_VS_0:
+ case SQ_ALU_CONST_CACHE_VS_1:
+ case SQ_ALU_CONST_CACHE_VS_2:
+ case SQ_ALU_CONST_CACHE_VS_3:
+ case SQ_ALU_CONST_CACHE_VS_4:
+ case SQ_ALU_CONST_CACHE_VS_5:
+ case SQ_ALU_CONST_CACHE_VS_6:
+ case SQ_ALU_CONST_CACHE_VS_7:
+ case SQ_ALU_CONST_CACHE_VS_8:
+ case SQ_ALU_CONST_CACHE_VS_9:
+ case SQ_ALU_CONST_CACHE_VS_10:
+ case SQ_ALU_CONST_CACHE_VS_11:
+ case SQ_ALU_CONST_CACHE_VS_12:
+ case SQ_ALU_CONST_CACHE_VS_13:
+ case SQ_ALU_CONST_CACHE_VS_14:
+ case SQ_ALU_CONST_CACHE_VS_15:
r = r600_cs_packet_next_reloc(p, &reloc);
if (r) {
dev_warn(p->dev, "bad SET_CONTEXT_REG "
@@ -1226,13 +1280,15 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
}
break;
case PACKET3_SET_ALU_CONST:
- start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
- end_reg = 4 * pkt->count + start_reg - 4;
- if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
- (start_reg >= PACKET3_SET_ALU_CONST_END) ||
- (end_reg >= PACKET3_SET_ALU_CONST_END)) {
- DRM_ERROR("bad SET_ALU_CONST\n");
- return -EINVAL;
+ if (track->sq_config & DX9_CONSTS) {
+ start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
+ end_reg = 4 * pkt->count + start_reg - 4;
+ if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
+ (start_reg >= PACKET3_SET_ALU_CONST_END) ||
+ (end_reg >= PACKET3_SET_ALU_CONST_END)) {
+ DRM_ERROR("bad SET_ALU_CONST\n");
+ return -EINVAL;
+ }
}
break;
case PACKET3_SET_BOOL_CONST:
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index fcc949df0e5..2616b822ba6 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -42,13 +42,13 @@ enum r600_hdmi_color_format {
*/
enum r600_hdmi_iec_status_bits {
AUDIO_STATUS_DIG_ENABLE = 0x01,
- AUDIO_STATUS_V = 0x02,
- AUDIO_STATUS_VCFG = 0x04,
+ AUDIO_STATUS_V = 0x02,
+ AUDIO_STATUS_VCFG = 0x04,
AUDIO_STATUS_EMPHASIS = 0x08,
AUDIO_STATUS_COPYRIGHT = 0x10,
AUDIO_STATUS_NONAUDIO = 0x20,
AUDIO_STATUS_PROFESSIONAL = 0x40,
- AUDIO_STATUS_LEVEL = 0x80
+ AUDIO_STATUS_LEVEL = 0x80
};
struct {
@@ -85,7 +85,7 @@ struct {
static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
{
if (*CTS == 0)
- *CTS = clock*N/(128*freq)*1000;
+ *CTS = clock * N / (128 * freq) * 1000;
DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
N, *CTS, freq);
}
@@ -131,11 +131,11 @@ static void r600_hdmi_infoframe_checksum(uint8_t packetType,
uint8_t length,
uint8_t *frame)
{
- int i;
- frame[0] = packetType + versionNumber + length;
- for (i = 1; i <= length; i++)
- frame[0] += frame[i];
- frame[0] = 0x100 - frame[0];
+ int i;
+ frame[0] = packetType + versionNumber + length;
+ for (i = 1; i <= length; i++)
+ frame[0] += frame[i];
+ frame[0] = 0x100 - frame[0];
}
/*
@@ -314,6 +314,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
struct radeon_device *rdev = dev->dev_private;
uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+ if (ASIC_IS_DCE4(rdev))
+ return;
+
if (!offset)
return;
@@ -417,90 +420,147 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
}
-/*
- * enable/disable the HDMI engine
- */
-void r600_hdmi_enable(struct drm_encoder *encoder, int enable)
+static int r600_hdmi_find_free_block(struct drm_device *dev)
+{
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_encoder *encoder;
+ struct radeon_encoder *radeon_encoder;
+ bool free_blocks[3] = { true, true, true };
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ radeon_encoder = to_radeon_encoder(encoder);
+ switch (radeon_encoder->hdmi_offset) {
+ case R600_HDMI_BLOCK1:
+ free_blocks[0] = false;
+ break;
+ case R600_HDMI_BLOCK2:
+ free_blocks[1] = false;
+ break;
+ case R600_HDMI_BLOCK3:
+ free_blocks[2] = false;
+ break;
+ }
+ }
+
+ if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) {
+ return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
+ } else if (rdev->family >= CHIP_R600) {
+ if (free_blocks[0])
+ return R600_HDMI_BLOCK1;
+ else if (free_blocks[1])
+ return R600_HDMI_BLOCK2;
+ }
+ return 0;
+}
+
+static void r600_hdmi_assign_block(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- if (!offset)
+ if (!dig) {
+ dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
return;
+ }
- DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset);
-
- /* some version of atombios ignore the enable HDMI flag
- * so enabling/disabling HDMI was moved here for TMDS1+2 */
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
- WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4);
- WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0);
- break;
-
- case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
- WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
- WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
- break;
-
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- /* This part is doubtfull in my opinion */
- WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
- break;
-
- default:
- DRM_ERROR("unknown HDMI output type\n");
- break;
+ if (ASIC_IS_DCE4(rdev)) {
+ /* TODO */
+ } else if (ASIC_IS_DCE3(rdev)) {
+ radeon_encoder->hdmi_offset = dig->dig_encoder ?
+ R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1;
+ if (ASIC_IS_DCE32(rdev))
+ radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
+ R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
+ } else if (rdev->family >= CHIP_R600) {
+ radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
}
}
/*
- * determin at which register offset the HDMI encoder is
+ * enable the HDMI engine
*/
-void r600_hdmi_init(struct drm_encoder *encoder)
+void r600_hdmi_enable(struct drm_encoder *encoder)
{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
- break;
-
- case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
- switch (r600_audio_tmds_index(encoder)) {
- case 0:
- radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
+ if (ASIC_IS_DCE4(rdev))
+ return;
+
+ if (!radeon_encoder->hdmi_offset) {
+ r600_hdmi_assign_block(encoder);
+ if (!radeon_encoder->hdmi_offset) {
+ dev_warn(rdev->dev, "Could not find HDMI block for "
+ "0x%x encoder\n", radeon_encoder->encoder_id);
+ return;
+ }
+ }
+
+ if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
+ WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
+ } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+ int offset = radeon_encoder->hdmi_offset;
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+ WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4);
+ WREG32(offset + R600_HDMI_ENABLE, 0x101);
break;
- case 1:
- radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+ WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4);
+ WREG32(offset + R600_HDMI_ENABLE, 0x105);
break;
default:
- radeon_encoder->hdmi_offset = 0;
+ dev_err(rdev->dev, "Unknown HDMI output type\n");
break;
}
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
- radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
- break;
+ }
+
+ DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+ radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+}
+
+/*
+ * disable the HDMI engine
+ */
+void r600_hdmi_disable(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- radeon_encoder->hdmi_offset = R600_HDMI_DIG;
- break;
+ if (ASIC_IS_DCE4(rdev))
+ return;
- default:
- radeon_encoder->hdmi_offset = 0;
- break;
+ if (!radeon_encoder->hdmi_offset) {
+ dev_err(rdev->dev, "Disabling not enabled HDMI\n");
+ return;
}
- DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n",
- radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+ DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+ radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+
+ if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
+ WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
+ } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+ int offset = radeon_encoder->hdmi_offset;
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+ WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4);
+ WREG32(offset + R600_HDMI_ENABLE, 0);
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+ WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4);
+ WREG32(offset + R600_HDMI_ENABLE, 0);
+ break;
+ default:
+ dev_err(rdev->dev, "Unknown HDMI output type\n");
+ break;
+ }
+ }
- /* TODO: make this configureable */
- radeon_encoder->hdmi_audio_workaround = 0;
+ radeon_encoder->hdmi_offset = 0;
+ radeon_encoder->hdmi_config_offset = 0;
}
diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h
index d0e28ffdeda..7b1d22370f6 100644
--- a/drivers/gpu/drm/radeon/r600_reg.h
+++ b/drivers/gpu/drm/radeon/r600_reg.h
@@ -152,9 +152,9 @@
#define R600_AUDIO_STATUS_BITS 0x73d8
/* HDMI base register addresses */
-#define R600_HDMI_TMDS1 0x7400
-#define R600_HDMI_TMDS2 0x7700
-#define R600_HDMI_DIG 0x7800
+#define R600_HDMI_BLOCK1 0x7400
+#define R600_HDMI_BLOCK2 0x7700
+#define R600_HDMI_BLOCK3 0x7800
/* HDMI registers */
#define R600_HDMI_ENABLE 0x00
@@ -185,4 +185,8 @@
#define R600_HDMI_AUDIO_DEBUG_2 0xe8
#define R600_HDMI_AUDIO_DEBUG_3 0xec
+/* HDMI additional config base register addresses */
+#define R600_HDMI_CONFIG1 0x7600
+#define R600_HDMI_CONFIG2 0x7a00
+
#endif
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 5b2e4d44282..59c1f8793e6 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -77,6 +77,55 @@
#define CB_COLOR0_FRAG 0x280e0
#define CB_COLOR0_MASK 0x28100
+#define SQ_ALU_CONST_CACHE_PS_0 0x28940
+#define SQ_ALU_CONST_CACHE_PS_1 0x28944
+#define SQ_ALU_CONST_CACHE_PS_2 0x28948
+#define SQ_ALU_CONST_CACHE_PS_3 0x2894c
+#define SQ_ALU_CONST_CACHE_PS_4 0x28950
+#define SQ_ALU_CONST_CACHE_PS_5 0x28954
+#define SQ_ALU_CONST_CACHE_PS_6 0x28958
+#define SQ_ALU_CONST_CACHE_PS_7 0x2895c
+#define SQ_ALU_CONST_CACHE_PS_8 0x28960
+#define SQ_ALU_CONST_CACHE_PS_9 0x28964
+#define SQ_ALU_CONST_CACHE_PS_10 0x28968
+#define SQ_ALU_CONST_CACHE_PS_11 0x2896c
+#define SQ_ALU_CONST_CACHE_PS_12 0x28970
+#define SQ_ALU_CONST_CACHE_PS_13 0x28974
+#define SQ_ALU_CONST_CACHE_PS_14 0x28978
+#define SQ_ALU_CONST_CACHE_PS_15 0x2897c
+#define SQ_ALU_CONST_CACHE_VS_0 0x28980
+#define SQ_ALU_CONST_CACHE_VS_1 0x28984
+#define SQ_ALU_CONST_CACHE_VS_2 0x28988
+#define SQ_ALU_CONST_CACHE_VS_3 0x2898c
+#define SQ_ALU_CONST_CACHE_VS_4 0x28990
+#define SQ_ALU_CONST_CACHE_VS_5 0x28994
+#define SQ_ALU_CONST_CACHE_VS_6 0x28998
+#define SQ_ALU_CONST_CACHE_VS_7 0x2899c
+#define SQ_ALU_CONST_CACHE_VS_8 0x289a0
+#define SQ_ALU_CONST_CACHE_VS_9 0x289a4
+#define SQ_ALU_CONST_CACHE_VS_10 0x289a8
+#define SQ_ALU_CONST_CACHE_VS_11 0x289ac
+#define SQ_ALU_CONST_CACHE_VS_12 0x289b0
+#define SQ_ALU_CONST_CACHE_VS_13 0x289b4
+#define SQ_ALU_CONST_CACHE_VS_14 0x289b8
+#define SQ_ALU_CONST_CACHE_VS_15 0x289bc
+#define SQ_ALU_CONST_CACHE_GS_0 0x289c0
+#define SQ_ALU_CONST_CACHE_GS_1 0x289c4
+#define SQ_ALU_CONST_CACHE_GS_2 0x289c8
+#define SQ_ALU_CONST_CACHE_GS_3 0x289cc
+#define SQ_ALU_CONST_CACHE_GS_4 0x289d0
+#define SQ_ALU_CONST_CACHE_GS_5 0x289d4
+#define SQ_ALU_CONST_CACHE_GS_6 0x289d8
+#define SQ_ALU_CONST_CACHE_GS_7 0x289dc
+#define SQ_ALU_CONST_CACHE_GS_8 0x289e0
+#define SQ_ALU_CONST_CACHE_GS_9 0x289e4
+#define SQ_ALU_CONST_CACHE_GS_10 0x289e8
+#define SQ_ALU_CONST_CACHE_GS_11 0x289ec
+#define SQ_ALU_CONST_CACHE_GS_12 0x289f0
+#define SQ_ALU_CONST_CACHE_GS_13 0x289f4
+#define SQ_ALU_CONST_CACHE_GS_14 0x289f8
+#define SQ_ALU_CONST_CACHE_GS_15 0x289fc
+
#define CONFIG_MEMSIZE 0x5428
#define CONFIG_CNTL 0x5424
#define CP_STAT 0x8680
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 829e26e8a4b..034218c3dbb 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -91,6 +91,8 @@ extern int radeon_tv;
extern int radeon_new_pll;
extern int radeon_dynpm;
extern int radeon_audio;
+extern int radeon_disp_priority;
+extern int radeon_hw_i2c;
/*
* Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -168,6 +170,7 @@ struct radeon_clock {
* Power management
*/
int radeon_pm_init(struct radeon_device *rdev);
+void radeon_pm_fini(struct radeon_device *rdev);
void radeon_pm_compute_clocks(struct radeon_device *rdev);
void radeon_combios_get_power_modes(struct radeon_device *rdev);
void radeon_atombios_get_power_modes(struct radeon_device *rdev);
@@ -687,6 +690,7 @@ struct radeon_pm {
bool downclocked;
int active_crtcs;
int req_vblank;
+ bool vblank_sync;
fixed20_12 max_bandwidth;
fixed20_12 igp_sideport_mclk;
fixed20_12 igp_system_mclk;
@@ -697,6 +701,7 @@ struct radeon_pm {
fixed20_12 ht_bandwidth;
fixed20_12 core_bandwidth;
fixed20_12 sclk;
+ fixed20_12 mclk;
fixed20_12 needed_bandwidth;
/* XXX: use a define for num power modes */
struct radeon_power_state power_state[8];
@@ -707,6 +712,7 @@ struct radeon_pm {
struct radeon_power_state *requested_power_state;
struct radeon_pm_clock_info *requested_clock_mode;
struct radeon_power_state *default_power_state;
+ struct radeon_i2c_chan *i2c_bus;
};
@@ -729,8 +735,6 @@ int radeon_debugfs_add_files(struct radeon_device *rdev,
struct drm_info_list *files,
unsigned nfiles);
int radeon_debugfs_fence_init(struct radeon_device *rdev);
-int r100_debugfs_rbbm_init(struct radeon_device *rdev);
-int r100_debugfs_cp_init(struct radeon_device *rdev);
/*
@@ -782,7 +786,7 @@ struct radeon_asic {
int (*set_surface_reg)(struct radeon_device *rdev, int reg,
uint32_t tiling_flags, uint32_t pitch,
uint32_t offset, uint32_t obj_size);
- int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
+ void (*clear_surface_reg)(struct radeon_device *rdev, int reg);
void (*bandwidth_update)(struct radeon_device *rdev);
void (*hpd_init)(struct radeon_device *rdev);
void (*hpd_fini)(struct radeon_device *rdev);
@@ -862,6 +866,12 @@ union radeon_asic_config {
struct rv770_asic rv770;
};
+/*
+ * asic initizalization from radeon_asic.c
+ */
+void radeon_agp_disable(struct radeon_device *rdev);
+int radeon_asic_init(struct radeon_device *rdev);
+
/*
* IOCTL.
@@ -1172,6 +1182,8 @@ extern void radeon_gart_restore(struct radeon_device *rdev);
extern int radeon_modeset_init(struct radeon_device *rdev);
extern void radeon_modeset_fini(struct radeon_device *rdev);
extern bool radeon_card_posted(struct radeon_device *rdev);
+extern void radeon_update_bandwidth_info(struct radeon_device *rdev);
+extern void radeon_update_display_priority(struct radeon_device *rdev);
extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
extern int radeon_clocks_init(struct radeon_device *rdev);
extern void radeon_clocks_fini(struct radeon_device *rdev);
@@ -1188,51 +1200,6 @@ extern int radeon_resume_kms(struct drm_device *dev);
extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
-struct r100_mc_save {
- u32 GENMO_WT;
- u32 CRTC_EXT_CNTL;
- u32 CRTC_GEN_CNTL;
- u32 CRTC2_GEN_CNTL;
- u32 CUR_OFFSET;
- u32 CUR2_OFFSET;
-};
-extern void r100_cp_disable(struct radeon_device *rdev);
-extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
-extern void r100_cp_fini(struct radeon_device *rdev);
-extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
-extern int r100_pci_gart_init(struct radeon_device *rdev);
-extern void r100_pci_gart_fini(struct radeon_device *rdev);
-extern int r100_pci_gart_enable(struct radeon_device *rdev);
-extern void r100_pci_gart_disable(struct radeon_device *rdev);
-extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
-extern int r100_debugfs_mc_info_init(struct radeon_device *rdev);
-extern int r100_gui_wait_for_idle(struct radeon_device *rdev);
-extern void r100_ib_fini(struct radeon_device *rdev);
-extern int r100_ib_init(struct radeon_device *rdev);
-extern void r100_irq_disable(struct radeon_device *rdev);
-extern int r100_irq_set(struct radeon_device *rdev);
-extern void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
-extern void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
-extern void r100_vram_init_sizes(struct radeon_device *rdev);
-extern void r100_wb_disable(struct radeon_device *rdev);
-extern void r100_wb_fini(struct radeon_device *rdev);
-extern int r100_wb_init(struct radeon_device *rdev);
-extern void r100_hdp_reset(struct radeon_device *rdev);
-extern int r100_rb2d_reset(struct radeon_device *rdev);
-extern int r100_cp_reset(struct radeon_device *rdev);
-extern void r100_vga_render_disable(struct radeon_device *rdev);
-extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
- struct radeon_cs_packet *pkt,
- struct radeon_bo *robj);
-extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
- struct radeon_cs_packet *pkt,
- const unsigned *auth, unsigned n,
- radeon_packet0_check_t check);
-extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
- struct radeon_cs_packet *pkt,
- unsigned idx);
-extern void r100_enable_bm(struct radeon_device *rdev);
-extern void r100_set_common_regs(struct radeon_device *rdev);
/* rv200,rv250,rv280 */
extern void r200_set_safe_registers(struct radeon_device *rdev);
@@ -1322,7 +1289,8 @@ extern int r600_audio_tmds_index(struct drm_encoder *encoder);
extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
extern void r600_audio_fini(struct radeon_device *rdev);
extern void r600_hdmi_init(struct drm_encoder *encoder);
-extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable);
+extern void r600_hdmi_enable(struct drm_encoder *encoder);
+extern void r600_hdmi_disable(struct drm_encoder *encoder);
extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
new file mode 100644
index 00000000000..a4b4bc9fa32
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -0,0 +1,772 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ */
+
+#include <linux/console.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
+#include <linux/vgaarb.h>
+#include <linux/vga_switcheroo.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "atom.h"
+
+/*
+ * Registers accessors functions.
+ */
+static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
+{
+ DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
+ BUG_ON(1);
+ return 0;
+}
+
+static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
+{
+ DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
+ reg, v);
+ BUG_ON(1);
+}
+
+static void radeon_register_accessor_init(struct radeon_device *rdev)
+{
+ rdev->mc_rreg = &radeon_invalid_rreg;
+ rdev->mc_wreg = &radeon_invalid_wreg;
+ rdev->pll_rreg = &radeon_invalid_rreg;
+ rdev->pll_wreg = &radeon_invalid_wreg;
+ rdev->pciep_rreg = &radeon_invalid_rreg;
+ rdev->pciep_wreg = &radeon_invalid_wreg;
+
+ /* Don't change order as we are overridding accessor. */
+ if (rdev->family < CHIP_RV515) {
+ rdev->pcie_reg_mask = 0xff;
+ } else {
+ rdev->pcie_reg_mask = 0x7ff;
+ }
+ /* FIXME: not sure here */
+ if (rdev->family <= CHIP_R580) {
+ rdev->pll_rreg = &r100_pll_rreg;
+ rdev->pll_wreg = &r100_pll_wreg;
+ }
+ if (rdev->family >= CHIP_R420) {
+ rdev->mc_rreg = &r420_mc_rreg;
+ rdev->mc_wreg = &r420_mc_wreg;
+ }
+ if (rdev->family >= CHIP_RV515) {
+ rdev->mc_rreg = &rv515_mc_rreg;
+ rdev->mc_wreg = &rv515_mc_wreg;
+ }
+ if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
+ rdev->mc_rreg = &rs400_mc_rreg;
+ rdev->mc_wreg = &rs400_mc_wreg;
+ }
+ if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
+ rdev->mc_rreg = &rs690_mc_rreg;
+ rdev->mc_wreg = &rs690_mc_wreg;
+ }
+ if (rdev->family == CHIP_RS600) {
+ rdev->mc_rreg = &rs600_mc_rreg;
+ rdev->mc_wreg = &rs600_mc_wreg;
+ }
+ if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) {
+ rdev->pciep_rreg = &r600_pciep_rreg;
+ rdev->pciep_wreg = &r600_pciep_wreg;
+ }
+}
+
+
+/* helper to disable agp */
+void radeon_agp_disable(struct radeon_device *rdev)
+{
+ rdev->flags &= ~RADEON_IS_AGP;
+ if (rdev->family >= CHIP_R600) {
+ DRM_INFO("Forcing AGP to PCIE mode\n");
+ rdev->flags |= RADEON_IS_PCIE;
+ } else if (rdev->family >= CHIP_RV515 ||
+ rdev->family == CHIP_RV380 ||
+ rdev->family == CHIP_RV410 ||
+ rdev->family == CHIP_R423) {
+ DRM_INFO("Forcing AGP to PCIE mode\n");
+ rdev->flags |= RADEON_IS_PCIE;
+ rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+ rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
+ } else {
+ DRM_INFO("Forcing AGP to PCI mode\n");
+ rdev->flags |= RADEON_IS_PCI;
+ rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
+ rdev->asic->gart_set_page = &r100_pci_gart_set_page;
+ }
+ rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+}
+
+/*
+ * ASIC
+ */
+static struct radeon_asic r100_asic = {
+ .init = &r100_init,
+ .fini = &r100_fini,
+ .suspend = &r100_suspend,
+ .resume = &r100_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &r100_gpu_reset,
+ .gart_tlb_flush = &r100_pci_gart_tlb_flush,
+ .gart_set_page = &r100_pci_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &r100_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &r100_irq_set,
+ .irq_process = &r100_irq_process,
+ .get_vblank_counter = &r100_get_vblank_counter,
+ .fence_ring_emit = &r100_fence_ring_emit,
+ .cs_parse = &r100_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = NULL,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_legacy_get_engine_clock,
+ .set_engine_clock = &radeon_legacy_set_engine_clock,
+ .get_memory_clock = &radeon_legacy_get_memory_clock,
+ .set_memory_clock = NULL,
+ .get_pcie_lanes = NULL,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = &radeon_legacy_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &r100_bandwidth_update,
+ .hpd_init = &r100_hpd_init,
+ .hpd_fini = &r100_hpd_fini,
+ .hpd_sense = &r100_hpd_sense,
+ .hpd_set_polarity = &r100_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r200_asic = {
+ .init = &r100_init,
+ .fini = &r100_fini,
+ .suspend = &r100_suspend,
+ .resume = &r100_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &r100_gpu_reset,
+ .gart_tlb_flush = &r100_pci_gart_tlb_flush,
+ .gart_set_page = &r100_pci_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &r100_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &r100_irq_set,
+ .irq_process = &r100_irq_process,
+ .get_vblank_counter = &r100_get_vblank_counter,
+ .fence_ring_emit = &r100_fence_ring_emit,
+ .cs_parse = &r100_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_legacy_get_engine_clock,
+ .set_engine_clock = &radeon_legacy_set_engine_clock,
+ .get_memory_clock = &radeon_legacy_get_memory_clock,
+ .set_memory_clock = NULL,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = &radeon_legacy_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &r100_bandwidth_update,
+ .hpd_init = &r100_hpd_init,
+ .hpd_fini = &r100_hpd_fini,
+ .hpd_sense = &r100_hpd_sense,
+ .hpd_set_polarity = &r100_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r300_asic = {
+ .init = &r300_init,
+ .fini = &r300_fini,
+ .suspend = &r300_suspend,
+ .resume = &r300_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &r300_gpu_reset,
+ .gart_tlb_flush = &r100_pci_gart_tlb_flush,
+ .gart_set_page = &r100_pci_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &r300_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &r100_irq_set,
+ .irq_process = &r100_irq_process,
+ .get_vblank_counter = &r100_get_vblank_counter,
+ .fence_ring_emit = &r300_fence_ring_emit,
+ .cs_parse = &r300_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_legacy_get_engine_clock,
+ .set_engine_clock = &radeon_legacy_set_engine_clock,
+ .get_memory_clock = &radeon_legacy_get_memory_clock,
+ .set_memory_clock = NULL,
+ .get_pcie_lanes = &rv370_get_pcie_lanes,
+ .set_pcie_lanes = &rv370_set_pcie_lanes,
+ .set_clock_gating = &radeon_legacy_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &r100_bandwidth_update,
+ .hpd_init = &r100_hpd_init,
+ .hpd_fini = &r100_hpd_fini,
+ .hpd_sense = &r100_hpd_sense,
+ .hpd_set_polarity = &r100_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r300_asic_pcie = {
+ .init = &r300_init,
+ .fini = &r300_fini,
+ .suspend = &r300_suspend,
+ .resume = &r300_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &r300_gpu_reset,
+ .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+ .gart_set_page = &rv370_pcie_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &r300_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &r100_irq_set,
+ .irq_process = &r100_irq_process,
+ .get_vblank_counter = &r100_get_vblank_counter,
+ .fence_ring_emit = &r300_fence_ring_emit,
+ .cs_parse = &r300_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_legacy_get_engine_clock,
+ .set_engine_clock = &radeon_legacy_set_engine_clock,
+ .get_memory_clock = &radeon_legacy_get_memory_clock,
+ .set_memory_clock = NULL,
+ .set_pcie_lanes = &rv370_set_pcie_lanes,
+ .set_clock_gating = &radeon_legacy_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &r100_bandwidth_update,
+ .hpd_init = &r100_hpd_init,
+ .hpd_fini = &r100_hpd_fini,
+ .hpd_sense = &r100_hpd_sense,
+ .hpd_set_polarity = &r100_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r420_asic = {
+ .init = &r420_init,
+ .fini = &r420_fini,
+ .suspend = &r420_suspend,
+ .resume = &r420_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &r300_gpu_reset,
+ .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+ .gart_set_page = &rv370_pcie_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &r300_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &r100_irq_set,
+ .irq_process = &r100_irq_process,
+ .get_vblank_counter = &r100_get_vblank_counter,
+ .fence_ring_emit = &r300_fence_ring_emit,
+ .cs_parse = &r300_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
+ .set_memory_clock = &radeon_atom_set_memory_clock,
+ .get_pcie_lanes = &rv370_get_pcie_lanes,
+ .set_pcie_lanes = &rv370_set_pcie_lanes,
+ .set_clock_gating = &radeon_atom_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &r100_bandwidth_update,
+ .hpd_init = &r100_hpd_init,
+ .hpd_fini = &r100_hpd_fini,
+ .hpd_sense = &r100_hpd_sense,
+ .hpd_set_polarity = &r100_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs400_asic = {
+ .init = &rs400_init,
+ .fini = &rs400_fini,
+ .suspend = &rs400_suspend,
+ .resume = &rs400_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &r300_gpu_reset,
+ .gart_tlb_flush = &rs400_gart_tlb_flush,
+ .gart_set_page = &rs400_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &r300_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &r100_irq_set,
+ .irq_process = &r100_irq_process,
+ .get_vblank_counter = &r100_get_vblank_counter,
+ .fence_ring_emit = &r300_fence_ring_emit,
+ .cs_parse = &r300_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_legacy_get_engine_clock,
+ .set_engine_clock = &radeon_legacy_set_engine_clock,
+ .get_memory_clock = &radeon_legacy_get_memory_clock,
+ .set_memory_clock = NULL,
+ .get_pcie_lanes = NULL,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = &radeon_legacy_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &r100_bandwidth_update,
+ .hpd_init = &r100_hpd_init,
+ .hpd_fini = &r100_hpd_fini,
+ .hpd_sense = &r100_hpd_sense,
+ .hpd_set_polarity = &r100_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs600_asic = {
+ .init = &rs600_init,
+ .fini = &rs600_fini,
+ .suspend = &rs600_suspend,
+ .resume = &rs600_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &r300_gpu_reset,
+ .gart_tlb_flush = &rs600_gart_tlb_flush,
+ .gart_set_page = &rs600_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &r300_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &rs600_irq_set,
+ .irq_process = &rs600_irq_process,
+ .get_vblank_counter = &rs600_get_vblank_counter,
+ .fence_ring_emit = &r300_fence_ring_emit,
+ .cs_parse = &r300_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
+ .set_memory_clock = &radeon_atom_set_memory_clock,
+ .get_pcie_lanes = NULL,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = &radeon_atom_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &rs600_bandwidth_update,
+ .hpd_init = &rs600_hpd_init,
+ .hpd_fini = &rs600_hpd_fini,
+ .hpd_sense = &rs600_hpd_sense,
+ .hpd_set_polarity = &rs600_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs690_asic = {
+ .init = &rs690_init,
+ .fini = &rs690_fini,
+ .suspend = &rs690_suspend,
+ .resume = &rs690_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &r300_gpu_reset,
+ .gart_tlb_flush = &rs400_gart_tlb_flush,
+ .gart_set_page = &rs400_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &r300_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &rs600_irq_set,
+ .irq_process = &rs600_irq_process,
+ .get_vblank_counter = &rs600_get_vblank_counter,
+ .fence_ring_emit = &r300_fence_ring_emit,
+ .cs_parse = &r300_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r200_copy_dma,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
+ .set_memory_clock = &radeon_atom_set_memory_clock,
+ .get_pcie_lanes = NULL,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = &radeon_atom_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &rs690_bandwidth_update,
+ .hpd_init = &rs600_hpd_init,
+ .hpd_fini = &rs600_hpd_fini,
+ .hpd_sense = &rs600_hpd_sense,
+ .hpd_set_polarity = &rs600_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rv515_asic = {
+ .init = &rv515_init,
+ .fini = &rv515_fini,
+ .suspend = &rv515_suspend,
+ .resume = &rv515_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &rv515_gpu_reset,
+ .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+ .gart_set_page = &rv370_pcie_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &rv515_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &rs600_irq_set,
+ .irq_process = &rs600_irq_process,
+ .get_vblank_counter = &rs600_get_vblank_counter,
+ .fence_ring_emit = &r300_fence_ring_emit,
+ .cs_parse = &r300_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
+ .set_memory_clock = &radeon_atom_set_memory_clock,
+ .get_pcie_lanes = &rv370_get_pcie_lanes,
+ .set_pcie_lanes = &rv370_set_pcie_lanes,
+ .set_clock_gating = &radeon_atom_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &rv515_bandwidth_update,
+ .hpd_init = &rs600_hpd_init,
+ .hpd_fini = &rs600_hpd_fini,
+ .hpd_sense = &rs600_hpd_sense,
+ .hpd_set_polarity = &rs600_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r520_asic = {
+ .init = &r520_init,
+ .fini = &rv515_fini,
+ .suspend = &rv515_suspend,
+ .resume = &r520_resume,
+ .vga_set_state = &r100_vga_set_state,
+ .gpu_reset = &rv515_gpu_reset,
+ .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+ .gart_set_page = &rv370_pcie_gart_set_page,
+ .cp_commit = &r100_cp_commit,
+ .ring_start = &rv515_ring_start,
+ .ring_test = &r100_ring_test,
+ .ring_ib_execute = &r100_ring_ib_execute,
+ .irq_set = &rs600_irq_set,
+ .irq_process = &rs600_irq_process,
+ .get_vblank_counter = &rs600_get_vblank_counter,
+ .fence_ring_emit = &r300_fence_ring_emit,
+ .cs_parse = &r300_cs_parse,
+ .copy_blit = &r100_copy_blit,
+ .copy_dma = &r200_copy_dma,
+ .copy = &r100_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
+ .set_memory_clock = &radeon_atom_set_memory_clock,
+ .get_pcie_lanes = &rv370_get_pcie_lanes,
+ .set_pcie_lanes = &rv370_set_pcie_lanes,
+ .set_clock_gating = &radeon_atom_set_clock_gating,
+ .set_surface_reg = r100_set_surface_reg,
+ .clear_surface_reg = r100_clear_surface_reg,
+ .bandwidth_update = &rv515_bandwidth_update,
+ .hpd_init = &rs600_hpd_init,
+ .hpd_fini = &rs600_hpd_fini,
+ .hpd_sense = &rs600_hpd_sense,
+ .hpd_set_polarity = &rs600_hpd_set_polarity,
+ .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r600_asic = {
+ .init = &r600_init,
+ .fini = &r600_fini,
+ .suspend = &r600_suspend,
+ .resume = &r600_resume,
+ .cp_commit = &r600_cp_commit,
+ .vga_set_state = &r600_vga_set_state,
+ .gpu_reset = &r600_gpu_reset,
+ .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+ .gart_set_page = &rs600_gart_set_page,
+ .ring_test = &r600_ring_test,
+ .ring_ib_execute = &r600_ring_ib_execute,
+ .irq_set = &r600_irq_set,
+ .irq_process = &r600_irq_process,
+ .get_vblank_counter = &rs600_get_vblank_counter,
+ .fence_ring_emit = &r600_fence_ring_emit,
+ .cs_parse = &r600_cs_parse,
+ .copy_blit = &r600_copy_blit,
+ .copy_dma = &r600_copy_blit,
+ .copy = &r600_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
+ .set_memory_clock = &radeon_atom_set_memory_clock,
+ .get_pcie_lanes = &rv370_get_pcie_lanes,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = NULL,
+ .set_surface_reg = r600_set_surface_reg,
+ .clear_surface_reg = r600_clear_surface_reg,
+ .bandwidth_update = &rv515_bandwidth_update,
+ .hpd_init = &r600_hpd_init,
+ .hpd_fini = &r600_hpd_fini,
+ .hpd_sense = &r600_hpd_sense,
+ .hpd_set_polarity = &r600_hpd_set_polarity,
+ .ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic rs780_asic = {
+ .init = &r600_init,
+ .fini = &r600_fini,
+ .suspend = &r600_suspend,
+ .resume = &r600_resume,
+ .cp_commit = &r600_cp_commit,
+ .vga_set_state = &r600_vga_set_state,
+ .gpu_reset = &r600_gpu_reset,
+ .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+ .gart_set_page = &rs600_gart_set_page,
+ .ring_test = &r600_ring_test,
+ .ring_ib_execute = &r600_ring_ib_execute,
+ .irq_set = &r600_irq_set,
+ .irq_process = &r600_irq_process,
+ .get_vblank_counter = &rs600_get_vblank_counter,
+ .fence_ring_emit = &r600_fence_ring_emit,
+ .cs_parse = &r600_cs_parse,
+ .copy_blit = &r600_copy_blit,
+ .copy_dma = &r600_copy_blit,
+ .copy = &r600_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = NULL,
+ .set_memory_clock = NULL,
+ .get_pcie_lanes = NULL,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = NULL,
+ .set_surface_reg = r600_set_surface_reg,
+ .clear_surface_reg = r600_clear_surface_reg,
+ .bandwidth_update = &rs690_bandwidth_update,
+ .hpd_init = &r600_hpd_init,
+ .hpd_fini = &r600_hpd_fini,
+ .hpd_sense = &r600_hpd_sense,
+ .hpd_set_polarity = &r600_hpd_set_polarity,
+ .ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic rv770_asic = {
+ .init = &rv770_init,
+ .fini = &rv770_fini,
+ .suspend = &rv770_suspend,
+ .resume = &rv770_resume,
+ .cp_commit = &r600_cp_commit,
+ .gpu_reset = &rv770_gpu_reset,
+ .vga_set_state = &r600_vga_set_state,
+ .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+ .gart_set_page = &rs600_gart_set_page,
+ .ring_test = &r600_ring_test,
+ .ring_ib_execute = &r600_ring_ib_execute,
+ .irq_set = &r600_irq_set,
+ .irq_process = &r600_irq_process,
+ .get_vblank_counter = &rs600_get_vblank_counter,
+ .fence_ring_emit = &r600_fence_ring_emit,
+ .cs_parse = &r600_cs_parse,
+ .copy_blit = &r600_copy_blit,
+ .copy_dma = &r600_copy_blit,
+ .copy = &r600_copy_blit,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
+ .set_memory_clock = &radeon_atom_set_memory_clock,
+ .get_pcie_lanes = &rv370_get_pcie_lanes,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = &radeon_atom_set_clock_gating,
+ .set_surface_reg = r600_set_surface_reg,
+ .clear_surface_reg = r600_clear_surface_reg,
+ .bandwidth_update = &rv515_bandwidth_update,
+ .hpd_init = &r600_hpd_init,
+ .hpd_fini = &r600_hpd_fini,
+ .hpd_sense = &r600_hpd_sense,
+ .hpd_set_polarity = &r600_hpd_set_polarity,
+ .ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic evergreen_asic = {
+ .init = &evergreen_init,
+ .fini = &evergreen_fini,
+ .suspend = &evergreen_suspend,
+ .resume = &evergreen_resume,
+ .cp_commit = NULL,
+ .gpu_reset = &evergreen_gpu_reset,
+ .vga_set_state = &r600_vga_set_state,
+ .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+ .gart_set_page = &rs600_gart_set_page,
+ .ring_test = NULL,
+ .ring_ib_execute = NULL,
+ .irq_set = NULL,
+ .irq_process = NULL,
+ .get_vblank_counter = NULL,
+ .fence_ring_emit = NULL,
+ .cs_parse = NULL,
+ .copy_blit = NULL,
+ .copy_dma = NULL,
+ .copy = NULL,
+ .get_engine_clock = &radeon_atom_get_engine_clock,
+ .set_engine_clock = &radeon_atom_set_engine_clock,
+ .get_memory_clock = &radeon_atom_get_memory_clock,
+ .set_memory_clock = &radeon_atom_set_memory_clock,
+ .set_pcie_lanes = NULL,
+ .set_clock_gating = NULL,
+ .set_surface_reg = r600_set_surface_reg,
+ .clear_surface_reg = r600_clear_surface_reg,
+ .bandwidth_update = &evergreen_bandwidth_update,
+ .hpd_init = &evergreen_hpd_init,
+ .hpd_fini = &evergreen_hpd_fini,
+ .hpd_sense = &evergreen_hpd_sense,
+ .hpd_set_polarity = &evergreen_hpd_set_polarity,
+};
+
+int radeon_asic_init(struct radeon_device *rdev)
+{
+ radeon_register_accessor_init(rdev);
+ switch (rdev->family) {
+ case CHIP_R100:
+ case CHIP_RV100:
+ case CHIP_RS100:
+ case CHIP_RV200:
+ case CHIP_RS200:
+ rdev->asic = &r100_asic;
+ break;
+ case CHIP_R200:
+ case CHIP_RV250:
+ case CHIP_RS300:
+ case CHIP_RV280:
+ rdev->asic = &r200_asic;
+ break;
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_RV350:
+ case CHIP_RV380:
+ if (rdev->flags & RADEON_IS_PCIE)
+ rdev->asic = &r300_asic_pcie;
+ else
+ rdev->asic = &r300_asic;
+ break;
+ case CHIP_R420:
+ case CHIP_R423:
+ case CHIP_RV410:
+ rdev->asic = &r420_asic;
+ break;
+ case CHIP_RS400:
+ case CHIP_RS480:
+ rdev->asic = &rs400_asic;
+ break;
+ case CHIP_RS600:
+ rdev->asic = &rs600_asic;
+ break;
+ case CHIP_RS690:
+ case CHIP_RS740:
+ rdev->asic = &rs690_asic;
+ break;
+ case CHIP_RV515:
+ rdev->asic = &rv515_asic;
+ break;
+ case CHIP_R520:
+ case CHIP_RV530:
+ case CHIP_RV560:
+ case CHIP_RV570:
+ case CHIP_R580:
+ rdev->asic = &r520_asic;
+ break;
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RV670:
+ rdev->asic = &r600_asic;
+ break;
+ case CHIP_RS780:
+ case CHIP_RS880:
+ rdev->asic = &rs780_asic;
+ break;
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ rdev->asic = &rv770_asic;
+ break;
+ case CHIP_CEDAR:
+ case CHIP_REDWOOD:
+ case CHIP_JUNIPER:
+ case CHIP_CYPRESS:
+ case CHIP_HEMLOCK:
+ rdev->asic = &evergreen_asic;
+ break;
+ default:
+ /* FIXME: not supported yet */
+ return -EINVAL;
+ }
+
+ if (rdev->flags & RADEON_IS_IGP) {
+ rdev->asic->get_memory_clock = NULL;
+ rdev->asic->set_memory_clock = NULL;
+ }
+
+ /* set the number of crtcs */
+ if (rdev->flags & RADEON_SINGLE_CRTC)
+ rdev->num_crtc = 1;
+ else {
+ if (ASIC_IS_DCE4(rdev))
+ rdev->num_crtc = 6;
+ else
+ rdev->num_crtc = 2;
+ }
+
+ return 0;
+}
+
+/*
+ * Wrapper around modesetting bits. Move to radeon_clocks.c?
+ */
+int radeon_clocks_init(struct radeon_device *rdev)
+{
+ int r;
+
+ r = radeon_static_clocks_init(rdev->ddev);
+ if (r) {
+ return r;
+ }
+ DRM_INFO("Clocks initialized !\n");
+ return 0;
+}
+
+void radeon_clocks_fini(struct radeon_device *rdev)
+{
+}
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index d3a157b2bcb..a0b8280663d 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -45,10 +45,18 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
/*
* r100,rv100,rs100,rv200,rs200
*/
-extern int r100_init(struct radeon_device *rdev);
-extern void r100_fini(struct radeon_device *rdev);
-extern int r100_suspend(struct radeon_device *rdev);
-extern int r100_resume(struct radeon_device *rdev);
+struct r100_mc_save {
+ u32 GENMO_WT;
+ u32 CRTC_EXT_CNTL;
+ u32 CRTC_GEN_CNTL;
+ u32 CRTC2_GEN_CNTL;
+ u32 CUR_OFFSET;
+ u32 CUR2_OFFSET;
+};
+int r100_init(struct radeon_device *rdev);
+void r100_fini(struct radeon_device *rdev);
+int r100_suspend(struct radeon_device *rdev);
+int r100_resume(struct radeon_device *rdev);
uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
void r100_vga_set_state(struct radeon_device *rdev, bool state);
@@ -73,7 +81,7 @@ int r100_copy_blit(struct radeon_device *rdev,
int r100_set_surface_reg(struct radeon_device *rdev, int reg,
uint32_t tiling_flags, uint32_t pitch,
uint32_t offset, uint32_t obj_size);
-int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
+void r100_clear_surface_reg(struct radeon_device *rdev, int reg);
void r100_bandwidth_update(struct radeon_device *rdev);
void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
int r100_ring_test(struct radeon_device *rdev);
@@ -82,44 +90,42 @@ void r100_hpd_fini(struct radeon_device *rdev);
bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
void r100_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd);
-
-static struct radeon_asic r100_asic = {
- .init = &r100_init,
- .fini = &r100_fini,
- .suspend = &r100_suspend,
- .resume = &r100_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &r100_gpu_reset,
- .gart_tlb_flush = &r100_pci_gart_tlb_flush,
- .gart_set_page = &r100_pci_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &r100_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &r100_irq_set,
- .irq_process = &r100_irq_process,
- .get_vblank_counter = &r100_get_vblank_counter,
- .fence_ring_emit = &r100_fence_ring_emit,
- .cs_parse = &r100_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = NULL,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_legacy_get_engine_clock,
- .set_engine_clock = &radeon_legacy_set_engine_clock,
- .get_memory_clock = &radeon_legacy_get_memory_clock,
- .set_memory_clock = NULL,
- .get_pcie_lanes = NULL,
- .set_pcie_lanes = NULL,
- .set_clock_gating = &radeon_legacy_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &r100_bandwidth_update,
- .hpd_init = &r100_hpd_init,
- .hpd_fini = &r100_hpd_fini,
- .hpd_sense = &r100_hpd_sense,
- .hpd_set_polarity = &r100_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
+int r100_debugfs_rbbm_init(struct radeon_device *rdev);
+int r100_debugfs_cp_init(struct radeon_device *rdev);
+void r100_cp_disable(struct radeon_device *rdev);
+int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
+void r100_cp_fini(struct radeon_device *rdev);
+int r100_pci_gart_init(struct radeon_device *rdev);
+void r100_pci_gart_fini(struct radeon_device *rdev);
+int r100_pci_gart_enable(struct radeon_device *rdev);
+void r100_pci_gart_disable(struct radeon_device *rdev);
+int r100_debugfs_mc_info_init(struct radeon_device *rdev);
+int r100_gui_wait_for_idle(struct radeon_device *rdev);
+void r100_ib_fini(struct radeon_device *rdev);
+int r100_ib_init(struct radeon_device *rdev);
+void r100_irq_disable(struct radeon_device *rdev);
+void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
+void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
+void r100_vram_init_sizes(struct radeon_device *rdev);
+void r100_wb_disable(struct radeon_device *rdev);
+void r100_wb_fini(struct radeon_device *rdev);
+int r100_wb_init(struct radeon_device *rdev);
+void r100_hdp_reset(struct radeon_device *rdev);
+int r100_rb2d_reset(struct radeon_device *rdev);
+int r100_cp_reset(struct radeon_device *rdev);
+void r100_vga_render_disable(struct radeon_device *rdev);
+int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt,
+ struct radeon_bo *robj);
+int r100_cs_parse_packet0(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt,
+ const unsigned *auth, unsigned n,
+ radeon_packet0_check_t check);
+int r100_cs_packet_parse(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt,
+ unsigned idx);
+void r100_enable_bm(struct radeon_device *rdev);
+void r100_set_common_regs(struct radeon_device *rdev);
/*
* r200,rv250,rs300,rv280
@@ -129,43 +135,6 @@ extern int r200_copy_dma(struct radeon_device *rdev,
uint64_t dst_offset,
unsigned num_pages,
struct radeon_fence *fence);
-static struct radeon_asic r200_asic = {
- .init = &r100_init,
- .fini = &r100_fini,
- .suspend = &r100_suspend,
- .resume = &r100_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &r100_gpu_reset,
- .gart_tlb_flush = &r100_pci_gart_tlb_flush,
- .gart_set_page = &r100_pci_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &r100_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &r100_irq_set,
- .irq_process = &r100_irq_process,
- .get_vblank_counter = &r100_get_vblank_counter,
- .fence_ring_emit = &r100_fence_ring_emit,
- .cs_parse = &r100_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_legacy_get_engine_clock,
- .set_engine_clock = &radeon_legacy_set_engine_clock,
- .get_memory_clock = &radeon_legacy_get_memory_clock,
- .set_memory_clock = NULL,
- .set_pcie_lanes = NULL,
- .set_clock_gating = &radeon_legacy_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &r100_bandwidth_update,
- .hpd_init = &r100_hpd_init,
- .hpd_fini = &r100_hpd_fini,
- .hpd_sense = &r100_hpd_sense,
- .hpd_set_polarity = &r100_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
-
/*
* r300,r350,rv350,rv380
@@ -186,82 +155,6 @@ extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v
extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
extern int rv370_get_pcie_lanes(struct radeon_device *rdev);
-static struct radeon_asic r300_asic = {
- .init = &r300_init,
- .fini = &r300_fini,
- .suspend = &r300_suspend,
- .resume = &r300_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &r300_gpu_reset,
- .gart_tlb_flush = &r100_pci_gart_tlb_flush,
- .gart_set_page = &r100_pci_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &r300_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &r100_irq_set,
- .irq_process = &r100_irq_process,
- .get_vblank_counter = &r100_get_vblank_counter,
- .fence_ring_emit = &r300_fence_ring_emit,
- .cs_parse = &r300_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_legacy_get_engine_clock,
- .set_engine_clock = &radeon_legacy_set_engine_clock,
- .get_memory_clock = &radeon_legacy_get_memory_clock,
- .set_memory_clock = NULL,
- .get_pcie_lanes = &rv370_get_pcie_lanes,
- .set_pcie_lanes = &rv370_set_pcie_lanes,
- .set_clock_gating = &radeon_legacy_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &r100_bandwidth_update,
- .hpd_init = &r100_hpd_init,
- .hpd_fini = &r100_hpd_fini,
- .hpd_sense = &r100_hpd_sense,
- .hpd_set_polarity = &r100_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
-
-
-static struct radeon_asic r300_asic_pcie = {
- .init = &r300_init,
- .fini = &r300_fini,
- .suspend = &r300_suspend,
- .resume = &r300_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &r300_gpu_reset,
- .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
- .gart_set_page = &rv370_pcie_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &r300_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &r100_irq_set,
- .irq_process = &r100_irq_process,
- .get_vblank_counter = &r100_get_vblank_counter,
- .fence_ring_emit = &r300_fence_ring_emit,
- .cs_parse = &r300_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_legacy_get_engine_clock,
- .set_engine_clock = &radeon_legacy_set_engine_clock,
- .get_memory_clock = &radeon_legacy_get_memory_clock,
- .set_memory_clock = NULL,
- .set_pcie_lanes = &rv370_set_pcie_lanes,
- .set_clock_gating = &radeon_legacy_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &r100_bandwidth_update,
- .hpd_init = &r100_hpd_init,
- .hpd_fini = &r100_hpd_fini,
- .hpd_sense = &r100_hpd_sense,
- .hpd_set_polarity = &r100_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
-
/*
* r420,r423,rv410
*/
@@ -269,44 +162,6 @@ extern int r420_init(struct radeon_device *rdev);
extern void r420_fini(struct radeon_device *rdev);
extern int r420_suspend(struct radeon_device *rdev);
extern int r420_resume(struct radeon_device *rdev);
-static struct radeon_asic r420_asic = {
- .init = &r420_init,
- .fini = &r420_fini,
- .suspend = &r420_suspend,
- .resume = &r420_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &r300_gpu_reset,
- .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
- .gart_set_page = &rv370_pcie_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &r300_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &r100_irq_set,
- .irq_process = &r100_irq_process,
- .get_vblank_counter = &r100_get_vblank_counter,
- .fence_ring_emit = &r300_fence_ring_emit,
- .cs_parse = &r300_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_atom_get_engine_clock,
- .set_engine_clock = &radeon_atom_set_engine_clock,
- .get_memory_clock = &radeon_atom_get_memory_clock,
- .set_memory_clock = &radeon_atom_set_memory_clock,
- .get_pcie_lanes = &rv370_get_pcie_lanes,
- .set_pcie_lanes = &rv370_set_pcie_lanes,
- .set_clock_gating = &radeon_atom_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &r100_bandwidth_update,
- .hpd_init = &r100_hpd_init,
- .hpd_fini = &r100_hpd_fini,
- .hpd_sense = &r100_hpd_sense,
- .hpd_set_polarity = &r100_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
-
/*
* rs400,rs480
@@ -319,44 +174,6 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev);
int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
-static struct radeon_asic rs400_asic = {
- .init = &rs400_init,
- .fini = &rs400_fini,
- .suspend = &rs400_suspend,
- .resume = &rs400_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &r300_gpu_reset,
- .gart_tlb_flush = &rs400_gart_tlb_flush,
- .gart_set_page = &rs400_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &r300_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &r100_irq_set,
- .irq_process = &r100_irq_process,
- .get_vblank_counter = &r100_get_vblank_counter,
- .fence_ring_emit = &r300_fence_ring_emit,
- .cs_parse = &r300_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_legacy_get_engine_clock,
- .set_engine_clock = &radeon_legacy_set_engine_clock,
- .get_memory_clock = &radeon_legacy_get_memory_clock,
- .set_memory_clock = NULL,
- .get_pcie_lanes = NULL,
- .set_pcie_lanes = NULL,
- .set_clock_gating = &radeon_legacy_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &r100_bandwidth_update,
- .hpd_init = &r100_hpd_init,
- .hpd_fini = &r100_hpd_fini,
- .hpd_sense = &r100_hpd_sense,
- .hpd_set_polarity = &r100_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
-
/*
* rs600.
@@ -379,45 +196,6 @@ bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
void rs600_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd);
-static struct radeon_asic rs600_asic = {
- .init = &rs600_init,
- .fini = &rs600_fini,
- .suspend = &rs600_suspend,
- .resume = &rs600_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &r300_gpu_reset,
- .gart_tlb_flush = &rs600_gart_tlb_flush,
- .gart_set_page = &rs600_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &r300_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &rs600_irq_set,
- .irq_process = &rs600_irq_process,
- .get_vblank_counter = &rs600_get_vblank_counter,
- .fence_ring_emit = &r300_fence_ring_emit,
- .cs_parse = &r300_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_atom_get_engine_clock,
- .set_engine_clock = &radeon_atom_set_engine_clock,
- .get_memory_clock = &radeon_atom_get_memory_clock,
- .set_memory_clock = &radeon_atom_set_memory_clock,
- .get_pcie_lanes = NULL,
- .set_pcie_lanes = NULL,
- .set_clock_gating = &radeon_atom_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &rs600_bandwidth_update,
- .hpd_init = &rs600_hpd_init,
- .hpd_fini = &rs600_hpd_fini,
- .hpd_sense = &rs600_hpd_sense,
- .hpd_set_polarity = &rs600_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
-
-
/*
* rs690,rs740
*/
@@ -428,44 +206,6 @@ int rs690_suspend(struct radeon_device *rdev);
uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
void rs690_bandwidth_update(struct radeon_device *rdev);
-static struct radeon_asic rs690_asic = {
- .init = &rs690_init,
- .fini = &rs690_fini,
- .suspend = &rs690_suspend,
- .resume = &rs690_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &r300_gpu_reset,
- .gart_tlb_flush = &rs400_gart_tlb_flush,
- .gart_set_page = &rs400_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &r300_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &rs600_irq_set,
- .irq_process = &rs600_irq_process,
- .get_vblank_counter = &rs600_get_vblank_counter,
- .fence_ring_emit = &r300_fence_ring_emit,
- .cs_parse = &r300_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r200_copy_dma,
- .get_engine_clock = &radeon_atom_get_engine_clock,
- .set_engine_clock = &radeon_atom_set_engine_clock,
- .get_memory_clock = &radeon_atom_get_memory_clock,
- .set_memory_clock = &radeon_atom_set_memory_clock,
- .get_pcie_lanes = NULL,
- .set_pcie_lanes = NULL,
- .set_clock_gating = &radeon_atom_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &rs690_bandwidth_update,
- .hpd_init = &rs600_hpd_init,
- .hpd_fini = &rs600_hpd_fini,
- .hpd_sense = &rs600_hpd_sense,
- .hpd_set_polarity = &rs600_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
-
/*
* rv515
@@ -481,87 +221,12 @@ void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
void rv515_bandwidth_update(struct radeon_device *rdev);
int rv515_resume(struct radeon_device *rdev);
int rv515_suspend(struct radeon_device *rdev);
-static struct radeon_asic rv515_asic = {
- .init = &rv515_init,
- .fini = &rv515_fini,
- .suspend = &rv515_suspend,
- .resume = &rv515_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &rv515_gpu_reset,
- .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
- .gart_set_page = &rv370_pcie_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &rv515_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &rs600_irq_set,
- .irq_process = &rs600_irq_process,
- .get_vblank_counter = &rs600_get_vblank_counter,
- .fence_ring_emit = &r300_fence_ring_emit,
- .cs_parse = &r300_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_atom_get_engine_clock,
- .set_engine_clock = &radeon_atom_set_engine_clock,
- .get_memory_clock = &radeon_atom_get_memory_clock,
- .set_memory_clock = &radeon_atom_set_memory_clock,
- .get_pcie_lanes = &rv370_get_pcie_lanes,
- .set_pcie_lanes = &rv370_set_pcie_lanes,
- .set_clock_gating = &radeon_atom_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &rv515_bandwidth_update,
- .hpd_init = &rs600_hpd_init,
- .hpd_fini = &rs600_hpd_fini,
- .hpd_sense = &rs600_hpd_sense,
- .hpd_set_polarity = &rs600_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
-
/*
* r520,rv530,rv560,rv570,r580
*/
int r520_init(struct radeon_device *rdev);
int r520_resume(struct radeon_device *rdev);
-static struct radeon_asic r520_asic = {
- .init = &r520_init,
- .fini = &rv515_fini,
- .suspend = &rv515_suspend,
- .resume = &r520_resume,
- .vga_set_state = &r100_vga_set_state,
- .gpu_reset = &rv515_gpu_reset,
- .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
- .gart_set_page = &rv370_pcie_gart_set_page,
- .cp_commit = &r100_cp_commit,
- .ring_start = &rv515_ring_start,
- .ring_test = &r100_ring_test,
- .ring_ib_execute = &r100_ring_ib_execute,
- .irq_set = &rs600_irq_set,
- .irq_process = &rs600_irq_process,
- .get_vblank_counter = &rs600_get_vblank_counter,
- .fence_ring_emit = &r300_fence_ring_emit,
- .cs_parse = &r300_cs_parse,
- .copy_blit = &r100_copy_blit,
- .copy_dma = &r200_copy_dma,
- .copy = &r100_copy_blit,
- .get_engine_clock = &radeon_atom_get_engine_clock,
- .set_engine_clock = &radeon_atom_set_engine_clock,
- .get_memory_clock = &radeon_atom_get_memory_clock,
- .set_memory_clock = &radeon_atom_set_memory_clock,
- .get_pcie_lanes = &rv370_get_pcie_lanes,
- .set_pcie_lanes = &rv370_set_pcie_lanes,
- .set_clock_gating = &radeon_atom_set_clock_gating,
- .set_surface_reg = r100_set_surface_reg,
- .clear_surface_reg = r100_clear_surface_reg,
- .bandwidth_update = &rv515_bandwidth_update,
- .hpd_init = &rs600_hpd_init,
- .hpd_fini = &rs600_hpd_fini,
- .hpd_sense = &rs600_hpd_sense,
- .hpd_set_polarity = &rs600_hpd_set_polarity,
- .ioctl_wait_idle = NULL,
-};
/*
* r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880
@@ -591,7 +256,7 @@ int r600_gpu_reset(struct radeon_device *rdev);
int r600_set_surface_reg(struct radeon_device *rdev, int reg,
uint32_t tiling_flags, uint32_t pitch,
uint32_t offset, uint32_t obj_size);
-int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
+void r600_clear_surface_reg(struct radeon_device *rdev, int reg);
void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
int r600_ring_test(struct radeon_device *rdev);
int r600_copy_blit(struct radeon_device *rdev,
@@ -604,43 +269,6 @@ void r600_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd);
extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo);
-static struct radeon_asic r600_asic = {
- .init = &r600_init,
- .fini = &r600_fini,
- .suspend = &r600_suspend,
- .resume = &r600_resume,
- .cp_commit = &r600_cp_commit,
- .vga_set_state = &r600_vga_set_state,
- .gpu_reset = &r600_gpu_reset,
- .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
- .gart_set_page = &rs600_gart_set_page,
- .ring_test = &r600_ring_test,
- .ring_ib_execute = &r600_ring_ib_execute,
- .irq_set = &r600_irq_set,
- .irq_process = &r600_irq_process,
- .get_vblank_counter = &rs600_get_vblank_counter,
- .fence_ring_emit = &r600_fence_ring_emit,
- .cs_parse = &r600_cs_parse,
- .copy_blit = &r600_copy_blit,
- .copy_dma = &r600_copy_blit,
- .copy = &r600_copy_blit,
- .get_engine_clock = &radeon_atom_get_engine_clock,
- .set_engine_clock = &radeon_atom_set_engine_clock,
- .get_memory_clock = &radeon_atom_get_memory_clock,
- .set_memory_clock = &radeon_atom_set_memory_clock,
- .get_pcie_lanes = &rv370_get_pcie_lanes,
- .set_pcie_lanes = NULL,
- .set_clock_gating = NULL,
- .set_surface_reg = r600_set_surface_reg,
- .clear_surface_reg = r600_clear_surface_reg,
- .bandwidth_update = &rv515_bandwidth_update,
- .hpd_init = &r600_hpd_init,
- .hpd_fini = &r600_hpd_fini,
- .hpd_sense = &r600_hpd_sense,
- .hpd_set_polarity = &r600_hpd_set_polarity,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
-};
-
/*
* rv770,rv730,rv710,rv740
*/
@@ -650,43 +278,6 @@ int rv770_suspend(struct radeon_device *rdev);
int rv770_resume(struct radeon_device *rdev);
int rv770_gpu_reset(struct radeon_device *rdev);
-static struct radeon_asic rv770_asic = {
- .init = &rv770_init,
- .fini = &rv770_fini,
- .suspend = &rv770_suspend,
- .resume = &rv770_resume,
- .cp_commit = &r600_cp_commit,
- .gpu_reset = &rv770_gpu_reset,
- .vga_set_state = &r600_vga_set_state,
- .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
- .gart_set_page = &rs600_gart_set_page,
- .ring_test = &r600_ring_test,
- .ring_ib_execute = &r600_ring_ib_execute,
- .irq_set = &r600_irq_set,
- .irq_process = &r600_irq_process,
- .get_vblank_counter = &rs600_get_vblank_counter,
- .fence_ring_emit = &r600_fence_ring_emit,
- .cs_parse = &r600_cs_parse,
- .copy_blit = &r600_copy_blit,
- .copy_dma = &r600_copy_blit,
- .copy = &r600_copy_blit,
- .get_engine_clock = &radeon_atom_get_engine_clock,
- .set_engine_clock = &radeon_atom_set_engine_clock,
- .get_memory_clock = &radeon_atom_get_memory_clock,
- .set_memory_clock = &radeon_atom_set_memory_clock,
- .get_pcie_lanes = &rv370_get_pcie_lanes,
- .set_pcie_lanes = NULL,
- .set_clock_gating = &radeon_atom_set_clock_gating,
- .set_surface_reg = r600_set_surface_reg,
- .clear_surface_reg = r600_clear_surface_reg,
- .bandwidth_update = &rv515_bandwidth_update,
- .hpd_init = &r600_hpd_init,
- .hpd_fini = &r600_hpd_fini,
- .hpd_sense = &r600_hpd_sense,
- .hpd_set_polarity = &r600_hpd_set_polarity,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
-};
-
/*
* evergreen
*/
@@ -701,40 +292,4 @@ void evergreen_hpd_fini(struct radeon_device *rdev);
bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
void evergreen_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd);
-
-static struct radeon_asic evergreen_asic = {
- .init = &evergreen_init,
- .fini = &evergreen_fini,
- .suspend = &evergreen_suspend,
- .resume = &evergreen_resume,
- .cp_commit = NULL,
- .gpu_reset = &evergreen_gpu_reset,
- .vga_set_state = &r600_vga_set_state,
- .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
- .gart_set_page = &rs600_gart_set_page,
- .ring_test = NULL,
- .ring_ib_execute = NULL,
- .irq_set = NULL,
- .irq_process = NULL,
- .get_vblank_counter = NULL,
- .fence_ring_emit = NULL,
- .cs_parse = NULL,
- .copy_blit = NULL,
- .copy_dma = NULL,
- .copy = NULL,
- .get_engine_clock = &radeon_atom_get_engine_clock,
- .set_engine_clock = &radeon_atom_set_engine_clock,
- .get_memory_clock = &radeon_atom_get_memory_clock,
- .set_memory_clock = &radeon_atom_set_memory_clock,
- .set_pcie_lanes = NULL,
- .set_clock_gating = NULL,
- .set_surface_reg = r600_set_surface_reg,
- .clear_surface_reg = r600_clear_surface_reg,
- .bandwidth_update = &evergreen_bandwidth_update,
- .hpd_init = &evergreen_hpd_init,
- .hpd_fini = &evergreen_hpd_fini,
- .hpd_sense = &evergreen_hpd_sense,
- .hpd_set_polarity = &evergreen_hpd_set_polarity,
-};
-
#endif
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 93783b15c81..5673665ff21 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -69,52 +69,54 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
struct radeon_i2c_bus_rec i2c;
int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
struct _ATOM_GPIO_I2C_INFO *i2c_info;
- uint16_t data_offset;
- int i;
+ uint16_t data_offset, size;
+ int i, num_indices;
memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
i2c.valid = false;
- atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
-
- i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
-
-
- for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
- gpio = &i2c_info->asGPIO_Info[i];
-
- if (gpio->sucI2cId.ucAccess == id) {
- i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
- i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
- i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
- i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
- i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
- i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
- i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
- i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
- i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
- i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
- i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
- i2c.en_data_mask = (1 << gpio->ucDataEnShift);
- i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
- i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
- i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
- i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
-
- if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
- i2c.hw_capable = true;
- else
- i2c.hw_capable = false;
-
- if (gpio->sucI2cId.ucAccess == 0xa0)
- i2c.mm_i2c = true;
- else
- i2c.mm_i2c = false;
-
- i2c.i2c_id = gpio->sucI2cId.ucAccess;
-
- i2c.valid = true;
- break;
+ if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
+ i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
+
+ num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+ sizeof(ATOM_GPIO_I2C_ASSIGMENT);
+
+ for (i = 0; i < num_indices; i++) {
+ gpio = &i2c_info->asGPIO_Info[i];
+
+ if (gpio->sucI2cId.ucAccess == id) {
+ i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+ i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+ i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+ i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+ i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+ i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+ i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+ i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+ i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+ i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+ i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
+ i2c.en_data_mask = (1 << gpio->ucDataEnShift);
+ i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
+ i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
+ i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
+ i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
+
+ if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+ i2c.hw_capable = true;
+ else
+ i2c.hw_capable = false;
+
+ if (gpio->sucI2cId.ucAccess == 0xa0)
+ i2c.mm_i2c = true;
+ else
+ i2c.mm_i2c = false;
+
+ i2c.i2c_id = gpio->sucI2cId.ucAccess;
+
+ i2c.valid = true;
+ break;
+ }
}
}
@@ -135,20 +137,21 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd
memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
gpio.valid = false;
- atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);
+ if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
+ gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
- gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
+ num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+ sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
- num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
-
- for (i = 0; i < num_indices; i++) {
- pin = &gpio_info->asGPIO_Pin[i];
- if (id == pin->ucGPIO_ID) {
- gpio.id = pin->ucGPIO_ID;
- gpio.reg = pin->usGpioPin_AIndex * 4;
- gpio.mask = (1 << pin->ucGpioPinBitShift);
- gpio.valid = true;
- break;
+ for (i = 0; i < num_indices; i++) {
+ pin = &gpio_info->asGPIO_Pin[i];
+ if (id == pin->ucGPIO_ID) {
+ gpio.id = pin->ucGPIO_ID;
+ gpio.reg = pin->usGpioPin_AIndex * 4;
+ gpio.mask = (1 << pin->ucGpioPinBitShift);
+ gpio.valid = true;
+ break;
+ }
}
}
@@ -264,6 +267,8 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) ||
(supported_device == ATOM_DEVICE_DFP2_SUPPORT))
return false;
+ if (supported_device == ATOM_DEVICE_CRT2_SUPPORT)
+ *line_mux = 0x90;
}
/* ASUS HD 3600 XT board lists the DVI port as HDMI */
@@ -395,9 +400,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
struct radeon_gpio_rec gpio;
struct radeon_hpd hpd;
- atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
-
- if (data_offset == 0)
+ if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
return false;
if (crev < 2)
@@ -449,37 +452,43 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
GetIndexIntoMasterTable(DATA,
IntegratedSystemInfo);
- atom_parse_data_header(ctx, index, &size, &frev,
- &crev, &igp_offset);
-
- if (crev >= 2) {
- igp_obj =
- (ATOM_INTEGRATED_SYSTEM_INFO_V2
- *) (ctx->bios + igp_offset);
-
- if (igp_obj) {
- uint32_t slot_config, ct;
-
- if (con_obj_num == 1)
- slot_config =
- igp_obj->
- ulDDISlot1Config;
- else
- slot_config =
- igp_obj->
- ulDDISlot2Config;
-
- ct = (slot_config >> 16) & 0xff;
- connector_type =
- object_connector_convert
- [ct];
- connector_object_id = ct;
- igp_lane_info =
- slot_config & 0xffff;
+ if (atom_parse_data_header(ctx, index, &size, &frev,
+ &crev, &igp_offset)) {
+
+ if (crev >= 2) {
+ igp_obj =
+ (ATOM_INTEGRATED_SYSTEM_INFO_V2
+ *) (ctx->bios + igp_offset);
+
+ if (igp_obj) {
+ uint32_t slot_config, ct;
+
+ if (con_obj_num == 1)
+ slot_config =
+ igp_obj->
+ ulDDISlot1Config;
+ else
+ slot_config =
+ igp_obj->
+ ulDDISlot2Config;
+
+ ct = (slot_config >> 16) & 0xff;
+ connector_type =
+ object_connector_convert
+ [ct];
+ connector_object_id = ct;
+ igp_lane_info =
+ slot_config & 0xffff;
+ } else
+ continue;
} else
continue;
- } else
- continue;
+ } else {
+ igp_lane_info = 0;
+ connector_type =
+ object_connector_convert[con_obj_id];
+ connector_object_id = con_obj_id;
+ }
} else {
igp_lane_info = 0;
connector_type =
@@ -627,20 +636,23 @@ static uint16_t atombios_get_connector_object_id(struct drm_device *dev,
uint8_t frev, crev;
ATOM_XTMDS_INFO *xtmds;
- atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
- xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
+ if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) {
+ xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset);
- if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
- if (connector_type == DRM_MODE_CONNECTOR_DVII)
- return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
- else
- return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
- } else {
- if (connector_type == DRM_MODE_CONNECTOR_DVII)
- return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
- else
- return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
- }
+ if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) {
+ if (connector_type == DRM_MODE_CONNECTOR_DVII)
+ return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
+ else
+ return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
+ } else {
+ if (connector_type == DRM_MODE_CONNECTOR_DVII)
+ return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
+ else
+ return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
+ }
+ } else
+ return supported_devices_connector_object_id_convert
+ [connector_type];
} else {
return supported_devices_connector_object_id_convert
[connector_type];
@@ -672,7 +684,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
int i, j, max_device;
struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
- atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
+ if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
+ return false;
supported_devices =
(union atom_supported_devices *)(ctx->bios + data_offset);
@@ -865,14 +878,11 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
struct radeon_pll *mpll = &rdev->clock.mpll;
uint16_t data_offset;
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
- &crev, &data_offset);
-
- firmware_info =
- (union firmware_info *)(mode_info->atom_context->bios +
- data_offset);
-
- if (firmware_info) {
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ firmware_info =
+ (union firmware_info *)(mode_info->atom_context->bios +
+ data_offset);
/* pixel clocks */
p1pll->reference_freq =
le16_to_cpu(firmware_info->info.usReferenceClock);
@@ -887,6 +897,20 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
p1pll->pll_out_max =
le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
+ if (crev >= 4) {
+ p1pll->lcd_pll_out_min =
+ le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
+ if (p1pll->lcd_pll_out_min == 0)
+ p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+ p1pll->lcd_pll_out_max =
+ le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
+ if (p1pll->lcd_pll_out_max == 0)
+ p1pll->lcd_pll_out_max = p1pll->pll_out_max;
+ } else {
+ p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+ p1pll->lcd_pll_out_max = p1pll->pll_out_max;
+ }
+
if (p1pll->pll_out_min == 0) {
if (ASIC_IS_AVIVO(rdev))
p1pll->pll_out_min = 64800;
@@ -992,13 +1016,10 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev)
u8 frev, crev;
u16 data_offset;
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
- &crev, &data_offset);
-
- igp_info = (union igp_info *)(mode_info->atom_context->bios +
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ igp_info = (union igp_info *)(mode_info->atom_context->bios +
data_offset);
-
- if (igp_info) {
switch (crev) {
case 1:
if (igp_info->info.ucMemoryType & 0xf0)
@@ -1029,14 +1050,12 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
uint16_t maxfreq;
int i;
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
- &crev, &data_offset);
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ tmds_info =
+ (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
+ data_offset);
- tmds_info =
- (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
- data_offset);
-
- if (tmds_info) {
maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
for (i = 0; i < 4; i++) {
tmds->tmds_pll[i].freq =
@@ -1085,13 +1104,11 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct
if (id > ATOM_MAX_SS_ENTRY)
return NULL;
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
- &crev, &data_offset);
-
- ss_info =
- (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ ss_info =
+ (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset);
- if (ss_info) {
ss =
kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL);
@@ -1114,30 +1131,6 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct
return ss;
}
-static void radeon_atom_apply_lvds_quirks(struct drm_device *dev,
- struct radeon_encoder_atom_dig *lvds)
-{
-
- /* Toshiba A300-1BU laptop panel doesn't like new pll divider algo */
- if ((dev->pdev->device == 0x95c4) &&
- (dev->pdev->subsystem_vendor == 0x1179) &&
- (dev->pdev->subsystem_device == 0xff50)) {
- if ((lvds->native_mode.hdisplay == 1280) &&
- (lvds->native_mode.vdisplay == 800))
- lvds->pll_algo = PLL_ALGO_LEGACY;
- }
-
- /* Dell Studio 15 laptop panel doesn't like new pll divider algo */
- if ((dev->pdev->device == 0x95c4) &&
- (dev->pdev->subsystem_vendor == 0x1028) &&
- (dev->pdev->subsystem_device == 0x029f)) {
- if ((lvds->native_mode.hdisplay == 1280) &&
- (lvds->native_mode.vdisplay == 800))
- lvds->pll_algo = PLL_ALGO_LEGACY;
- }
-
-}
-
union lvds_info {
struct _ATOM_LVDS_INFO info;
struct _ATOM_LVDS_INFO_V12 info_12;
@@ -1156,13 +1149,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
uint8_t frev, crev;
struct radeon_encoder_atom_dig *lvds = NULL;
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
- &crev, &data_offset);
-
- lvds_info =
- (union lvds_info *)(mode_info->atom_context->bios + data_offset);
-
- if (lvds_info) {
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ lvds_info =
+ (union lvds_info *)(mode_info->atom_context->bios + data_offset);
lvds =
kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
@@ -1220,9 +1210,6 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
lvds->pll_algo = PLL_ALGO_LEGACY;
}
- /* LVDS quirks */
- radeon_atom_apply_lvds_quirks(dev, lvds);
-
encoder->native_mode = lvds->native_mode;
}
return lvds;
@@ -1241,11 +1228,11 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
uint8_t bg, dac;
struct radeon_encoder_primary_dac *p_dac = NULL;
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
-
- dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ dac_info = (struct _COMPASSIONATE_DATA *)
+ (mode_info->atom_context->bios + data_offset);
- if (dac_info) {
p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);
if (!p_dac)
@@ -1270,7 +1257,9 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
u8 frev, crev;
u16 data_offset, misc;
- atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
+ if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL,
+ &frev, &crev, &data_offset))
+ return false;
switch (crev) {
case 1:
@@ -1362,47 +1351,50 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev)
struct _ATOM_ANALOG_TV_INFO *tv_info;
enum radeon_tv_std tv_std = TV_STD_NTSC;
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
- tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
+ tv_info = (struct _ATOM_ANALOG_TV_INFO *)
+ (mode_info->atom_context->bios + data_offset);
- switch (tv_info->ucTV_BootUpDefaultStandard) {
- case ATOM_TV_NTSC:
- tv_std = TV_STD_NTSC;
- DRM_INFO("Default TV standard: NTSC\n");
- break;
- case ATOM_TV_NTSCJ:
- tv_std = TV_STD_NTSC_J;
- DRM_INFO("Default TV standard: NTSC-J\n");
- break;
- case ATOM_TV_PAL:
- tv_std = TV_STD_PAL;
- DRM_INFO("Default TV standard: PAL\n");
- break;
- case ATOM_TV_PALM:
- tv_std = TV_STD_PAL_M;
- DRM_INFO("Default TV standard: PAL-M\n");
- break;
- case ATOM_TV_PALN:
- tv_std = TV_STD_PAL_N;
- DRM_INFO("Default TV standard: PAL-N\n");
- break;
- case ATOM_TV_PALCN:
- tv_std = TV_STD_PAL_CN;
- DRM_INFO("Default TV standard: PAL-CN\n");
- break;
- case ATOM_TV_PAL60:
- tv_std = TV_STD_PAL_60;
- DRM_INFO("Default TV standard: PAL-60\n");
- break;
- case ATOM_TV_SECAM:
- tv_std = TV_STD_SECAM;
- DRM_INFO("Default TV standard: SECAM\n");
- break;
- default:
- tv_std = TV_STD_NTSC;
- DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
- break;
+ switch (tv_info->ucTV_BootUpDefaultStandard) {
+ case ATOM_TV_NTSC:
+ tv_std = TV_STD_NTSC;
+ DRM_INFO("Default TV standard: NTSC\n");
+ break;
+ case ATOM_TV_NTSCJ:
+ tv_std = TV_STD_NTSC_J;
+ DRM_INFO("Default TV standard: NTSC-J\n");
+ break;
+ case ATOM_TV_PAL:
+ tv_std = TV_STD_PAL;
+ DRM_INFO("Default TV standard: PAL\n");
+ break;
+ case ATOM_TV_PALM:
+ tv_std = TV_STD_PAL_M;
+ DRM_INFO("Default TV standard: PAL-M\n");
+ break;
+ case ATOM_TV_PALN:
+ tv_std = TV_STD_PAL_N;
+ DRM_INFO("Default TV standard: PAL-N\n");
+ break;
+ case ATOM_TV_PALCN:
+ tv_std = TV_STD_PAL_CN;
+ DRM_INFO("Default TV standard: PAL-CN\n");
+ break;
+ case ATOM_TV_PAL60:
+ tv_std = TV_STD_PAL_60;
+ DRM_INFO("Default TV standard: PAL-60\n");
+ break;
+ case ATOM_TV_SECAM:
+ tv_std = TV_STD_SECAM;
+ DRM_INFO("Default TV standard: SECAM\n");
+ break;
+ default:
+ tv_std = TV_STD_NTSC;
+ DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
+ break;
+ }
}
return tv_std;
}
@@ -1420,11 +1412,12 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
uint8_t bg, dac;
struct radeon_encoder_tv_dac *tv_dac = NULL;
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
- dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
+ dac_info = (struct _COMPASSIONATE_DATA *)
+ (mode_info->atom_context->bios + data_offset);
- if (dac_info) {
tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
if (!tv_dac)
@@ -1447,6 +1440,30 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
return tv_dac;
}
+static const char *thermal_controller_names[] = {
+ "NONE",
+ "LM63",
+ "ADM1032",
+ "ADM1030",
+ "MUA6649",
+ "LM64",
+ "F75375",
+ "ASC7512",
+};
+
+static const char *pp_lib_thermal_controller_names[] = {
+ "NONE",
+ "LM63",
+ "ADM1032",
+ "ADM1030",
+ "MUA6649",
+ "LM64",
+ "F75375",
+ "RV6xx",
+ "RV770",
+ "ADT7473",
+};
+
union power_info {
struct _ATOM_POWERPLAY_INFO info;
struct _ATOM_POWERPLAY_INFO_V2 info_2;
@@ -1466,15 +1483,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
struct _ATOM_PPLIB_STATE *power_state;
int num_modes = 0, i, j;
int state_index = 0, mode_index = 0;
-
- atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
-
- power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+ struct radeon_i2c_bus_rec i2c_bus;
rdev->pm.default_power_state = NULL;
- if (power_info) {
+ if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
if (frev < 4) {
+ /* add the i2c bus for thermal/fan chip */
+ if (power_info->info.ucOverdriveThermalController > 0) {
+ DRM_INFO("Possible %s thermal controller at 0x%02x\n",
+ thermal_controller_names[power_info->info.ucOverdriveThermalController],
+ power_info->info.ucOverdriveControllerAddress >> 1);
+ i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine);
+ rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal");
+ }
num_modes = power_info->info.ucNumOfPowerModeEntries;
if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
@@ -1684,6 +1708,24 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
}
}
} else if (frev == 4) {
+ /* add the i2c bus for thermal/fan chip */
+ /* no support for internal controller yet */
+ if (power_info->info_4.sThermalController.ucType > 0) {
+ if ((power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) ||
+ (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV770)) {
+ DRM_INFO("Internal thermal controller %s fan control\n",
+ (power_info->info_4.sThermalController.ucFanParameters &
+ ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+ } else {
+ DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
+ pp_lib_thermal_controller_names[power_info->info_4.sThermalController.ucType],
+ power_info->info_4.sThermalController.ucI2cAddress >> 1,
+ (power_info->info_4.sThermalController.ucFanParameters &
+ ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+ i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info_4.sThermalController.ucI2cLine);
+ rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal");
+ }
+ }
for (i = 0; i < power_info->info_4.ucNumStates; i++) {
mode_index = 0;
power_state = (struct _ATOM_PPLIB_STATE *)
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 3f557c4151e..ed5dfe58f29 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -7,6 +7,7 @@
* ATPX support for both Intel/ATI
*/
#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
#include <linux/pci.h>
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 55724046052..8ad71f70131 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -31,6 +31,7 @@
#include "atom.h"
#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
/*
* BIOS.
*/
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index e9ea38ece37..37db8adb274 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -531,10 +531,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
case CHIP_RS300:
switch (ddc_line) {
case RADEON_GPIO_DVI_DDC:
- /* in theory this should be hw capable,
- * but it doesn't seem to work
- */
- i2c.hw_capable = false;
+ i2c.hw_capable = true;
break;
default:
i2c.hw_capable = false;
@@ -633,6 +630,8 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
p1pll->reference_div = RBIOS16(pll_info + 0x10);
p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
+ p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+ p1pll->lcd_pll_out_max = p1pll->pll_out_max;
if (rev > 9) {
p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
@@ -761,7 +760,9 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
dac = RBIOS8(dac_info + 0x3) & 0xf;
p_dac->ps2_pdac_adj = (bg << 8) | (dac);
}
- found = 1;
+ /* if the values are all zeros, use the table */
+ if (p_dac->ps2_pdac_adj)
+ found = 1;
}
if (!found) /* fallback to defaults */
@@ -896,7 +897,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
bg = RBIOS8(dac_info + 0x10) & 0xf;
dac = RBIOS8(dac_info + 0x11) & 0xf;
tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
- found = 1;
+ /* if the values are all zeros, use the table */
+ if (tv_dac->ps2_tvdac_adj)
+ found = 1;
} else if (rev > 1) {
bg = RBIOS8(dac_info + 0xc) & 0xf;
dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf;
@@ -909,7 +912,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
bg = RBIOS8(dac_info + 0xe) & 0xf;
dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;
tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
- found = 1;
+ /* if the values are all zeros, use the table */
+ if (tv_dac->ps2_tvdac_adj)
+ found = 1;
}
tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
}
@@ -926,7 +931,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
(bg << 16) | (dac << 20);
tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
- found = 1;
+ /* if the values are all zeros, use the table */
+ if (tv_dac->ps2_tvdac_adj)
+ found = 1;
} else {
bg = RBIOS8(dac_info + 0x4) & 0xf;
dac = RBIOS8(dac_info + 0x5) & 0xf;
@@ -934,7 +941,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
(bg << 16) | (dac << 20);
tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
- found = 1;
+ /* if the values are all zeros, use the table */
+ if (tv_dac->ps2_tvdac_adj)
+ found = 1;
}
} else {
DRM_INFO("No TV DAC info found in BIOS\n");
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index ee0083f982d..1331351c517 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -162,12 +162,14 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
{
struct drm_device *dev = connector->dev;
struct drm_connector *conflict;
+ struct radeon_connector *radeon_conflict;
int i;
list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
if (conflict == connector)
continue;
+ radeon_conflict = to_radeon_connector(conflict);
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (conflict->encoder_ids[i] == 0)
break;
@@ -177,6 +179,9 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
if (conflict->status != connector_status_connected)
continue;
+ if (radeon_conflict->use_digital)
+ continue;
+
if (priority == true) {
DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
@@ -287,6 +292,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
if (property == rdev->mode_info.coherent_mode_property) {
struct radeon_encoder_atom_dig *dig;
+ bool new_coherent_mode;
/* need to find digital encoder on connector */
encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
@@ -299,8 +305,11 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
return 0;
dig = radeon_encoder->enc_priv;
- dig->coherent_mode = val ? true : false;
- radeon_property_change_mode(&radeon_encoder->base);
+ new_coherent_mode = val ? true : false;
+ if (dig->coherent_mode != new_coherent_mode) {
+ dig->coherent_mode = new_coherent_mode;
+ radeon_property_change_mode(&radeon_encoder->base);
+ }
}
if (property == rdev->mode_info.tv_std_property) {
@@ -315,7 +324,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
radeon_encoder = to_radeon_encoder(encoder);
if (!radeon_encoder->enc_priv)
return 0;
- if (rdev->is_atom_bios) {
+ if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) {
struct radeon_encoder_atom_dac *dac_int;
dac_int = radeon_encoder->enc_priv;
dac_int->tv_std = val;
@@ -940,7 +949,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)
if (radeon_connector->edid)
kfree(radeon_connector->edid);
if (radeon_dig_connector->dp_i2c_bus)
- radeon_i2c_destroy_dp(radeon_dig_connector->dp_i2c_bus);
+ radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
kfree(radeon_connector->con_priv);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index dc6eba6b96d..2f042a3c0e6 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -417,8 +417,9 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
return -EBUSY;
}
-static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
+static void radeon_init_pipes(struct drm_device *dev)
{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
uint32_t gb_tile_config, gb_pipe_sel = 0;
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
@@ -434,13 +435,19 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+ /* SE cards have 1 pipe */
+ if ((dev->pdev->device == 0x5e4c) ||
+ (dev->pdev->device == 0x5e4f))
+ dev_priv->num_gb_pipes = 1;
} else {
/* R3xx */
- if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 &&
+ dev->pdev->device != 0x4144) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 &&
+ dev->pdev->device != 0x4148)) {
dev_priv->num_gb_pipes = 2;
} else {
- /* R3Vxx */
+ /* RV3xx/R300 AD/R350 AH */
dev_priv->num_gb_pipes = 1;
}
}
@@ -736,7 +743,7 @@ static int radeon_do_engine_reset(struct drm_device * dev)
/* setup the raster pipes */
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
- radeon_init_pipes(dev_priv);
+ radeon_init_pipes(dev);
/* Reset the CP ring */
radeon_do_cp_reset(dev_priv);
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 70ba02ed772..f9b0fe002c0 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -193,9 +193,11 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
radeon_bo_list_fence(&parser->validated, parser->ib->fence);
}
radeon_bo_list_unreserve(&parser->validated);
- for (i = 0; i < parser->nrelocs; i++) {
- if (parser->relocs[i].gobj)
- drm_gem_object_unreference_unlocked(parser->relocs[i].gobj);
+ if (parser->relocs != NULL) {
+ for (i = 0; i < parser->nrelocs; i++) {
+ if (parser->relocs[i].gobj)
+ drm_gem_object_unreference_unlocked(parser->relocs[i].gobj);
+ }
}
kfree(parser->track);
kfree(parser->relocs);
@@ -243,7 +245,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
}
r = radeon_cs_parser_relocs(&parser);
if (r) {
- DRM_ERROR("Failed to parse relocation !\n");
+ if (r != -ERESTARTSYS)
+ DRM_ERROR("Failed to parse relocation %d!\n", r);
radeon_cs_parser_fini(&parser, r);
mutex_unlock(&rdev->cs_mutex);
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index e28e4ed5f72..7b629e30556 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -26,6 +26,7 @@
* Jerome Glisse
*/
#include <linux/console.h>
+#include <linux/slab.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/radeon_drm.h>
@@ -33,9 +34,56 @@
#include <linux/vga_switcheroo.h>
#include "radeon_reg.h"
#include "radeon.h"
-#include "radeon_asic.h"
#include "atom.h"
+static const char radeon_family_name[][16] = {
+ "R100",
+ "RV100",
+ "RS100",
+ "RV200",
+ "RS200",
+ "R200",
+ "RV250",
+ "RS300",
+ "RV280",
+ "R300",
+ "R350",
+ "RV350",
+ "RV380",
+ "R420",
+ "R423",
+ "RV410",
+ "RS400",
+ "RS480",
+ "RS600",
+ "RS690",
+ "RS740",
+ "RV515",
+ "R520",
+ "RV530",
+ "RV560",
+ "RV570",
+ "R580",
+ "R600",
+ "RV610",
+ "RV630",
+ "RV670",
+ "RV620",
+ "RV635",
+ "RS780",
+ "RS880",
+ "RV770",
+ "RV730",
+ "RV710",
+ "RV740",
+ "CEDAR",
+ "REDWOOD",
+ "JUNIPER",
+ "CYPRESS",
+ "HEMLOCK",
+ "LAST",
+};
+
/*
* Clear GPU surface registers.
*/
@@ -242,6 +290,36 @@ bool radeon_card_posted(struct radeon_device *rdev)
}
+void radeon_update_bandwidth_info(struct radeon_device *rdev)
+{
+ fixed20_12 a;
+ u32 sclk, mclk;
+
+ if (rdev->flags & RADEON_IS_IGP) {
+ sclk = radeon_get_engine_clock(rdev);
+ mclk = rdev->clock.default_mclk;
+
+ a.full = rfixed_const(100);
+ rdev->pm.sclk.full = rfixed_const(sclk);
+ rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+ rdev->pm.mclk.full = rfixed_const(mclk);
+ rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a);
+
+ a.full = rfixed_const(16);
+ /* core_bandwidth = sclk(Mhz) * 16 */
+ rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
+ } else {
+ sclk = radeon_get_engine_clock(rdev);
+ mclk = radeon_get_memory_clock(rdev);
+
+ a.full = rfixed_const(100);
+ rdev->pm.sclk.full = rfixed_const(sclk);
+ rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+ rdev->pm.mclk.full = rfixed_const(mclk);
+ rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a);
+ }
+}
+
bool radeon_boot_test_post_card(struct radeon_device *rdev)
{
if (radeon_card_posted(rdev))
@@ -288,181 +366,6 @@ void radeon_dummy_page_fini(struct radeon_device *rdev)
}
-/*
- * Registers accessors functions.
- */
-uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
-{
- DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
- BUG_ON(1);
- return 0;
-}
-
-void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
-{
- DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
- reg, v);
- BUG_ON(1);
-}
-
-void radeon_register_accessor_init(struct radeon_device *rdev)
-{
- rdev->mc_rreg = &radeon_invalid_rreg;
- rdev->mc_wreg = &radeon_invalid_wreg;
- rdev->pll_rreg = &radeon_invalid_rreg;
- rdev->pll_wreg = &radeon_invalid_wreg;
- rdev->pciep_rreg = &radeon_invalid_rreg;
- rdev->pciep_wreg = &radeon_invalid_wreg;
-
- /* Don't change order as we are overridding accessor. */
- if (rdev->family < CHIP_RV515) {
- rdev->pcie_reg_mask = 0xff;
- } else {
- rdev->pcie_reg_mask = 0x7ff;
- }
- /* FIXME: not sure here */
- if (rdev->family <= CHIP_R580) {
- rdev->pll_rreg = &r100_pll_rreg;
- rdev->pll_wreg = &r100_pll_wreg;
- }
- if (rdev->family >= CHIP_R420) {
- rdev->mc_rreg = &r420_mc_rreg;
- rdev->mc_wreg = &r420_mc_wreg;
- }
- if (rdev->family >= CHIP_RV515) {
- rdev->mc_rreg = &rv515_mc_rreg;
- rdev->mc_wreg = &rv515_mc_wreg;
- }
- if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
- rdev->mc_rreg = &rs400_mc_rreg;
- rdev->mc_wreg = &rs400_mc_wreg;
- }
- if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
- rdev->mc_rreg = &rs690_mc_rreg;
- rdev->mc_wreg = &rs690_mc_wreg;
- }
- if (rdev->family == CHIP_RS600) {
- rdev->mc_rreg = &rs600_mc_rreg;
- rdev->mc_wreg = &rs600_mc_wreg;
- }
- if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) {
- rdev->pciep_rreg = &r600_pciep_rreg;
- rdev->pciep_wreg = &r600_pciep_wreg;
- }
-}
-
-
-/*
- * ASIC
- */
-int radeon_asic_init(struct radeon_device *rdev)
-{
- radeon_register_accessor_init(rdev);
- switch (rdev->family) {
- case CHIP_R100:
- case CHIP_RV100:
- case CHIP_RS100:
- case CHIP_RV200:
- case CHIP_RS200:
- rdev->asic = &r100_asic;
- break;
- case CHIP_R200:
- case CHIP_RV250:
- case CHIP_RS300:
- case CHIP_RV280:
- rdev->asic = &r200_asic;
- break;
- case CHIP_R300:
- case CHIP_R350:
- case CHIP_RV350:
- case CHIP_RV380:
- if (rdev->flags & RADEON_IS_PCIE)
- rdev->asic = &r300_asic_pcie;
- else
- rdev->asic = &r300_asic;
- break;
- case CHIP_R420:
- case CHIP_R423:
- case CHIP_RV410:
- rdev->asic = &r420_asic;
- break;
- case CHIP_RS400:
- case CHIP_RS480:
- rdev->asic = &rs400_asic;
- break;
- case CHIP_RS600:
- rdev->asic = &rs600_asic;
- break;
- case CHIP_RS690:
- case CHIP_RS740:
- rdev->asic = &rs690_asic;
- break;
- case CHIP_RV515:
- rdev->asic = &rv515_asic;
- break;
- case CHIP_R520:
- case CHIP_RV530:
- case CHIP_RV560:
- case CHIP_RV570:
- case CHIP_R580:
- rdev->asic = &r520_asic;
- break;
- case CHIP_R600:
- case CHIP_RV610:
- case CHIP_RV630:
- case CHIP_RV620:
- case CHIP_RV635:
- case CHIP_RV670:
- case CHIP_RS780:
- case CHIP_RS880:
- rdev->asic = &r600_asic;
- break;
- case CHIP_RV770:
- case CHIP_RV730:
- case CHIP_RV710:
- case CHIP_RV740:
- rdev->asic = &rv770_asic;
- break;
- case CHIP_CEDAR:
- case CHIP_REDWOOD:
- case CHIP_JUNIPER:
- case CHIP_CYPRESS:
- case CHIP_HEMLOCK:
- rdev->asic = &evergreen_asic;
- break;
- default:
- /* FIXME: not supported yet */
- return -EINVAL;
- }
-
- if (rdev->flags & RADEON_IS_IGP) {
- rdev->asic->get_memory_clock = NULL;
- rdev->asic->set_memory_clock = NULL;
- }
-
- return 0;
-}
-
-
-/*
- * Wrapper around modesetting bits.
- */
-int radeon_clocks_init(struct radeon_device *rdev)
-{
- int r;
-
- r = radeon_static_clocks_init(rdev->ddev);
- if (r) {
- return r;
- }
- DRM_INFO("Clocks initialized !\n");
- return 0;
-}
-
-void radeon_clocks_fini(struct radeon_device *rdev)
-{
-}
-
/* ATOM accessor methods */
static uint32_t cail_pll_read(struct card_info *info, uint32_t reg)
{
@@ -567,29 +470,6 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state)
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
}
-void radeon_agp_disable(struct radeon_device *rdev)
-{
- rdev->flags &= ~RADEON_IS_AGP;
- if (rdev->family >= CHIP_R600) {
- DRM_INFO("Forcing AGP to PCIE mode\n");
- rdev->flags |= RADEON_IS_PCIE;
- } else if (rdev->family >= CHIP_RV515 ||
- rdev->family == CHIP_RV380 ||
- rdev->family == CHIP_RV410 ||
- rdev->family == CHIP_R423) {
- DRM_INFO("Forcing AGP to PCIE mode\n");
- rdev->flags |= RADEON_IS_PCIE;
- rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
- rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
- } else {
- DRM_INFO("Forcing AGP to PCI mode\n");
- rdev->flags |= RADEON_IS_PCI;
- rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
- rdev->asic->gart_set_page = &r100_pci_gart_set_page;
- }
- rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-}
-
void radeon_check_arguments(struct radeon_device *rdev)
{
/* vramlimit must be a power of two */
@@ -694,7 +574,6 @@ int radeon_device_init(struct radeon_device *rdev,
int r;
int dma_bits;
- DRM_INFO("radeon: Initializing kernel modesetting.\n");
rdev->shutdown = false;
rdev->dev = &pdev->dev;
rdev->ddev = ddev;
@@ -706,6 +585,10 @@ int radeon_device_init(struct radeon_device *rdev,
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
rdev->gpu_lockup = false;
rdev->accel_working = false;
+
+ DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
+ radeon_family_name[rdev->family], pdev->vendor, pdev->device);
+
/* mutex initialization are all done here so we
* can recall function without having locking issues */
mutex_init(&rdev->cs_mutex);
@@ -731,6 +614,14 @@ int radeon_device_init(struct radeon_device *rdev,
return r;
radeon_check_arguments(rdev);
+ /* all of the newer IGP chips have an internal gart
+ * However some rs4xx report as AGP, so remove that here.
+ */
+ if ((rdev->family >= CHIP_RS400) &&
+ (rdev->flags & RADEON_IS_IGP)) {
+ rdev->flags &= ~RADEON_IS_AGP;
+ }
+
if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
radeon_agp_disable(rdev);
}
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index ba8d806dcf3..bb1c122cad2 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -86,12 +86,12 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
- WREG32(EVERGREEN_DC_LUT_RW_MODE, radeon_crtc->crtc_id);
- WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK, 0x00000007);
+ WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
+ WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
- WREG32(EVERGREEN_DC_LUT_RW_INDEX, 0);
+ WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
for (i = 0; i < 256; i++) {
- WREG32(EVERGREEN_DC_LUT_30_COLOR,
+ WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
(radeon_crtc->lut_r[i] << 20) |
(radeon_crtc->lut_g[i] << 10) |
(radeon_crtc->lut_b[i] << 0));
@@ -368,10 +368,9 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
if (rdev->bios) {
if (rdev->is_atom_bios) {
- if (rdev->family >= CHIP_R600)
+ ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
+ if (ret == false)
ret = radeon_get_atom_connector_info_from_object_table(dev);
- else
- ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
} else {
ret = radeon_get_legacy_connector_info_from_bios(dev);
if (ret == false)
@@ -469,10 +468,19 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
uint32_t best_error = 0xffffffff;
uint32_t best_vco_diff = 1;
uint32_t post_div;
+ u32 pll_out_min, pll_out_max;
DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
freq = freq * 1000;
+ if (pll->flags & RADEON_PLL_IS_LCD) {
+ pll_out_min = pll->lcd_pll_out_min;
+ pll_out_max = pll->lcd_pll_out_max;
+ } else {
+ pll_out_min = pll->pll_out_min;
+ pll_out_max = pll->pll_out_max;
+ }
+
if (pll->flags & RADEON_PLL_USE_REF_DIV)
min_ref_div = max_ref_div = pll->reference_div;
else {
@@ -536,10 +544,10 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
tmp = (uint64_t)pll->reference_freq * feedback_div;
vco = radeon_div(tmp, ref_div);
- if (vco < pll->pll_out_min) {
+ if (vco < pll_out_min) {
min_feed_div = feedback_div + 1;
continue;
- } else if (vco > pll->pll_out_max) {
+ } else if (vco > pll_out_max) {
max_feed_div = feedback_div;
continue;
}
@@ -675,6 +683,15 @@ calc_fb_ref_div(struct radeon_pll *pll,
{
fixed20_12 ffreq, max_error, error, pll_out, a;
u32 vco;
+ u32 pll_out_min, pll_out_max;
+
+ if (pll->flags & RADEON_PLL_IS_LCD) {
+ pll_out_min = pll->lcd_pll_out_min;
+ pll_out_max = pll->lcd_pll_out_max;
+ } else {
+ pll_out_min = pll->pll_out_min;
+ pll_out_max = pll->pll_out_max;
+ }
ffreq.full = rfixed_const(freq);
/* max_error = ffreq * 0.0025; */
@@ -686,7 +703,7 @@ calc_fb_ref_div(struct radeon_pll *pll,
vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac));
vco = vco / ((*ref_div) * 10);
- if ((vco < pll->pll_out_min) || (vco > pll->pll_out_max))
+ if ((vco < pll_out_min) || (vco > pll_out_max))
continue;
/* pll_out = vco / post_div; */
@@ -714,6 +731,15 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
{
u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0;
u32 best_freq = 0, vco_frequency;
+ u32 pll_out_min, pll_out_max;
+
+ if (pll->flags & RADEON_PLL_IS_LCD) {
+ pll_out_min = pll->lcd_pll_out_min;
+ pll_out_max = pll->lcd_pll_out_max;
+ } else {
+ pll_out_min = pll->pll_out_min;
+ pll_out_max = pll->pll_out_max;
+ }
/* freq = freq / 10; */
do_div(freq, 10);
@@ -724,7 +750,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
goto done;
vco_frequency = freq * post_div;
- if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max))
+ if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
goto done;
if (pll->flags & RADEON_PLL_USE_REF_DIV) {
@@ -749,7 +775,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
continue;
vco_frequency = freq * post_div;
- if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max))
+ if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
continue;
if (pll->flags & RADEON_PLL_USE_REF_DIV) {
ref_div = pll->reference_div;
@@ -945,6 +971,23 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
return 0;
}
+void radeon_update_display_priority(struct radeon_device *rdev)
+{
+ /* adjustment options for the display watermarks */
+ if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) {
+ /* set display priority to high for r3xx, rv515 chips
+ * this avoids flickering due to underflow to the
+ * display controllers during heavy acceleration.
+ */
+ if (ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515))
+ rdev->disp_priority = 2;
+ else
+ rdev->disp_priority = 0;
+ } else
+ rdev->disp_priority = radeon_disp_priority;
+
+}
+
int radeon_modeset_init(struct radeon_device *rdev)
{
int i;
@@ -976,15 +1019,6 @@ int radeon_modeset_init(struct radeon_device *rdev)
radeon_combios_check_hardcoded_edid(rdev);
}
- if (rdev->flags & RADEON_SINGLE_CRTC)
- rdev->num_crtc = 1;
- else {
- if (ASIC_IS_DCE4(rdev))
- rdev->num_crtc = 6;
- else
- rdev->num_crtc = 2;
- }
-
/* allocate crtcs */
for (i = 0; i < rdev->num_crtc; i++) {
radeon_crtc_init(rdev->ddev, i);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 6eec0ece6a6..4b05563d99e 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -42,9 +42,11 @@
* KMS wrapper.
* - 2.0.0 - initial interface
* - 2.1.0 - add square tiling interface
+ * - 2.2.0 - add r6xx/r7xx const buffer support
+ * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs
*/
#define KMS_DRIVER_MAJOR 2
-#define KMS_DRIVER_MINOR 1
+#define KMS_DRIVER_MINOR 3
#define KMS_DRIVER_PATCHLEVEL 0
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
int radeon_driver_unload_kms(struct drm_device *dev);
@@ -91,6 +93,8 @@ int radeon_tv = 1;
int radeon_new_pll = -1;
int radeon_dynpm = -1;
int radeon_audio = 1;
+int radeon_disp_priority = 0;
+int radeon_hw_i2c = 0;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -134,6 +138,12 @@ module_param_named(dynpm, radeon_dynpm, int, 0444);
MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
module_param_named(audio, radeon_audio, int, 0444);
+MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
+module_param_named(disp_priority, radeon_disp_priority, int, 0444);
+
+MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)");
+module_param_named(hw_i2c, radeon_hw_i2c, int, 0444);
+
static int radeon_suspend(struct drm_device *dev, pm_message_t state)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index ec55f2b23c2..448eba89d1e 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -107,9 +107,10 @@
* 1.30- Add support for occlusion queries
* 1.31- Add support for num Z pipes from GET_PARAM
* 1.32- fixes for rv740 setup
+ * 1.33- Add r6xx/r7xx const buffer support
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 32
+#define DRIVER_MINOR 33
#define DRIVER_PATCHLEVEL 0
enum radeon_cp_microcode_version {
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index bc926ea0a53..fed7b808477 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -302,7 +302,7 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
}
if (ASIC_IS_DCE3(rdev) &&
- (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
+ (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
radeon_dp_set_link_config(connector, mode);
}
@@ -317,12 +317,8 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
DAC_ENCODER_CONTROL_PS_ALLOCATION args;
- int index = 0, num = 0;
+ int index = 0;
struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
- enum radeon_tv_std tv_std = TV_STD_NTSC;
-
- if (dac_info->tv_std)
- tv_std = dac_info->tv_std;
memset(&args, 0, sizeof(args));
@@ -330,12 +326,10 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
- num = 1;
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
- num = 2;
break;
}
@@ -346,7 +340,7 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
args.ucDacStandard = ATOM_DAC1_CV;
else {
- switch (tv_std) {
+ switch (dac_info->tv_std) {
case TV_STD_PAL:
case TV_STD_PAL_M:
case TV_STD_SCART_PAL:
@@ -377,10 +371,6 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
TV_ENCODER_CONTROL_PS_ALLOCATION args;
int index = 0;
struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
- enum radeon_tv_std tv_std = TV_STD_NTSC;
-
- if (dac_info->tv_std)
- tv_std = dac_info->tv_std;
memset(&args, 0, sizeof(args));
@@ -391,7 +381,7 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
else {
- switch (tv_std) {
+ switch (dac_info->tv_std) {
case TV_STD_NTSC:
args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
break;
@@ -519,7 +509,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
break;
}
- atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+ return;
switch (frev) {
case 1:
@@ -593,7 +584,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
}
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
- r600_hdmi_enable(encoder, hdmi_detected);
}
int
@@ -708,7 +698,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
struct radeon_connector_atom_dig *dig_connector =
radeon_get_atom_connector_priv_from_encoder(encoder);
union dig_encoder_control args;
- int index = 0, num = 0;
+ int index = 0;
uint8_t frev, crev;
if (!dig || !dig_connector)
@@ -724,9 +714,9 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
else
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
}
- num = dig->dig_encoder + 1;
- atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+ return;
args.v1.ucAction = action;
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -785,7 +775,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
union dig_transmitter_control args;
- int index = 0, num = 0;
+ int index = 0;
uint8_t frev, crev;
bool is_dp = false;
int pll_id = 0;
@@ -814,7 +804,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
}
}
- atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+ return;
args.v1.ucAction = action;
if (action == ATOM_TRANSMITTER_ACTION_INIT) {
@@ -860,15 +851,12 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
args.v3.acConfig.ucTransmitterSel = 0;
- num = 0;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
args.v3.acConfig.ucTransmitterSel = 1;
- num = 1;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
args.v3.acConfig.ucTransmitterSel = 2;
- num = 2;
break;
}
@@ -877,25 +865,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v3.acConfig.fCoherentMode = 1;
+ if (radeon_encoder->pixel_clock > 165000)
+ args.v3.acConfig.fDualLinkConnector = 1;
}
} else if (ASIC_IS_DCE32(rdev)) {
- if (dig->dig_encoder == 1)
- args.v2.acConfig.ucEncoderSel = 1;
+ args.v2.acConfig.ucEncoderSel = dig->dig_encoder;
if (dig_connector->linkb)
args.v2.acConfig.ucLinkSel = 1;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
args.v2.acConfig.ucTransmitterSel = 0;
- num = 0;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
args.v2.acConfig.ucTransmitterSel = 1;
- num = 1;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
args.v2.acConfig.ucTransmitterSel = 2;
- num = 2;
break;
}
@@ -904,6 +890,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v2.acConfig.fCoherentMode = 1;
+ if (radeon_encoder->pixel_clock > 165000)
+ args.v2.acConfig.fDualLinkConnector = 1;
}
} else {
args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
@@ -913,31 +901,25 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- if (rdev->flags & RADEON_IS_IGP) {
- if (radeon_encoder->pixel_clock > 165000) {
- if (dig_connector->igp_lane_info & 0x3)
- args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
- else if (dig_connector->igp_lane_info & 0xc)
- args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
- } else {
- if (dig_connector->igp_lane_info & 0x1)
- args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
- else if (dig_connector->igp_lane_info & 0x2)
- args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
- else if (dig_connector->igp_lane_info & 0x4)
- args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
- else if (dig_connector->igp_lane_info & 0x8)
- args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
- }
+ if ((rdev->flags & RADEON_IS_IGP) &&
+ (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
+ if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
+ if (dig_connector->igp_lane_info & 0x1)
+ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+ else if (dig_connector->igp_lane_info & 0x2)
+ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
+ else if (dig_connector->igp_lane_info & 0x4)
+ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
+ else if (dig_connector->igp_lane_info & 0x8)
+ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
+ } else {
+ if (dig_connector->igp_lane_info & 0x3)
+ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
+ else if (dig_connector->igp_lane_info & 0xc)
+ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
}
- break;
}
- if (radeon_encoder->pixel_clock > 165000)
- args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
-
if (dig_connector->linkb)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
else
@@ -948,6 +930,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+ if (radeon_encoder->pixel_clock > 165000)
+ args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
}
}
@@ -1054,16 +1038,25 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
if (is_dig) {
switch (mode) {
case DRM_MODE_DPMS_ON:
- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
- {
+ if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
dp_link_train(encoder, connector);
+ if (ASIC_IS_DCE4(rdev))
+ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON);
}
+ if (!ASIC_IS_DCE4(rdev))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+ if (!ASIC_IS_DCE4(rdev))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+ if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
+ if (ASIC_IS_DCE4(rdev))
+ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+ }
break;
}
} else {
@@ -1104,7 +1097,8 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
memset(&args, 0, sizeof(args));
- atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+ return;
switch (frev) {
case 1:
@@ -1216,6 +1210,9 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
}
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+ /* update scratch regs with new routing */
+ radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
}
static void
@@ -1326,20 +1323,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
- if (radeon_encoder->active_device &
- (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- if (dig)
- dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
- }
radeon_encoder->pixel_clock = adjusted_mode->clock;
- radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
- atombios_set_encoder_crtc_source(encoder);
-
- if (ASIC_IS_AVIVO(rdev)) {
+ if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
atombios_yuv_setup(encoder, true);
else
@@ -1390,15 +1377,20 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
atombios_dac_setup(encoder, ATOM_ENABLE);
- if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
- atombios_tv_setup(encoder, ATOM_ENABLE);
+ if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+ atombios_tv_setup(encoder, ATOM_ENABLE);
+ else
+ atombios_tv_setup(encoder, ATOM_DISABLE);
+ }
break;
}
atombios_apply_encoder_quirks(encoder, adjusted_mode);
- /* XXX */
- if (!ASIC_IS_DCE4(rdev))
+ if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
+ r600_hdmi_enable(encoder);
r600_hdmi_setmode(encoder, adjusted_mode);
+ }
}
static bool
@@ -1418,7 +1410,8 @@ atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *conn
memset(&args, 0, sizeof(args));
- atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+ return false;
args.sDacload.ucMisc = 0;
@@ -1492,8 +1485,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+ if (radeon_encoder->active_device &
+ (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ if (dig)
+ dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
+ }
+
radeon_atom_output_lock(encoder, true);
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+ /* this is needed for the pll/ss setup to work correctly in some cases */
+ atombios_set_encoder_crtc_source(encoder);
}
static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
@@ -1509,6 +1514,8 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
if (radeon_encoder_is_digital(encoder)) {
+ if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
+ r600_hdmi_disable(encoder);
dig = radeon_encoder->enc_priv;
dig->dig_encoder = -1;
}
@@ -1549,12 +1556,14 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
struct radeon_encoder_atom_dac *
radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
{
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);
if (!dac)
return NULL;
- dac->tv_std = TV_STD_NTSC;
+ dac->tv_std = radeon_atombios_get_tv_info(rdev);
return dac;
}
@@ -1632,6 +1641,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+ radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
@@ -1659,6 +1669,4 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
break;
}
-
- r600_hdmi_init(encoder);
}
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h
index 93c7d5d4191..e329066dcab 100644
--- a/drivers/gpu/drm/radeon/radeon_family.h
+++ b/drivers/gpu/drm/radeon/radeon_family.h
@@ -36,7 +36,7 @@
* Radeon chip families
*/
enum radeon_family {
- CHIP_R100,
+ CHIP_R100 = 0,
CHIP_RV100,
CHIP_RS100,
CHIP_RV200,
@@ -99,4 +99,5 @@ enum radeon_chip_flags {
RADEON_IS_PCI = 0x00800000UL,
RADEON_IS_IGPGART = 0x01000000UL,
};
+
#endif
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 8fccbf29235..9ac57a09784 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -28,6 +28,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/fb.h>
#include "drmP.h"
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 8495d4e32e1..d90f95b405c 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -33,6 +33,7 @@
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/kref.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "radeon_reg.h"
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 4ae50c19589..5def6f5dff3 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -59,6 +59,7 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
return false;
}
+/* bit banging i2c */
static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
{
@@ -181,13 +182,30 @@ static void set_data(void *i2c_priv, int data)
WREG32(rec->en_data_reg, val);
}
+static int pre_xfer(struct i2c_adapter *i2c_adap)
+{
+ struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+
+ radeon_i2c_do_lock(i2c, 1);
+
+ return 0;
+}
+
+static void post_xfer(struct i2c_adapter *i2c_adap)
+{
+ struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+
+ radeon_i2c_do_lock(i2c, 0);
+}
+
+/* hw i2c */
+
static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
{
- struct radeon_pll *spll = &rdev->clock.spll;
u32 sclk = radeon_get_engine_clock(rdev);
u32 prescale = 0;
- u32 n, m;
- u8 loop;
+ u32 nm;
+ u8 n, m, loop;
int i2c_clock;
switch (rdev->family) {
@@ -203,13 +221,15 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
case CHIP_R300:
case CHIP_R350:
case CHIP_RV350:
- n = (spll->reference_freq) / (4 * 6);
+ i2c_clock = 60;
+ nm = (sclk * 10) / (i2c_clock * 4);
for (loop = 1; loop < 255; loop++) {
- if ((loop * (loop - 1)) > n)
+ if ((nm / loop) < loop)
break;
}
- m = loop - 1;
- prescale = m | (loop << 8);
+ n = loop - 1;
+ m = loop - 2;
+ prescale = m | (n << 8);
break;
case CHIP_RV380:
case CHIP_RS400:
@@ -217,7 +237,6 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
case CHIP_R420:
case CHIP_R423:
case CHIP_RV410:
- sclk = radeon_get_engine_clock(rdev);
prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
break;
case CHIP_RS600:
@@ -232,7 +251,6 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
case CHIP_RV570:
case CHIP_R580:
i2c_clock = 50;
- sclk = radeon_get_engine_clock(rdev);
if (rdev->family == CHIP_R520)
prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock));
else
@@ -291,6 +309,7 @@ static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
prescale = radeon_get_i2c_prescale(rdev);
reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) |
+ RADEON_I2C_DRIVE_EN |
RADEON_I2C_START |
RADEON_I2C_STOP |
RADEON_I2C_GO);
@@ -757,26 +776,13 @@ done:
return ret;
}
-static int radeon_sw_i2c_xfer(struct i2c_adapter *i2c_adap,
+static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num)
{
struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
- int ret;
-
- radeon_i2c_do_lock(i2c, 1);
- ret = i2c_transfer(&i2c->algo.radeon.bit_adapter, msgs, num);
- radeon_i2c_do_lock(i2c, 0);
-
- return ret;
-}
-
-static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs, int num)
-{
- struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
struct radeon_device *rdev = i2c->dev->dev_private;
struct radeon_i2c_bus_rec *rec = &i2c->rec;
- int ret;
+ int ret = 0;
switch (rdev->family) {
case CHIP_R100:
@@ -797,16 +803,12 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
case CHIP_RV410:
case CHIP_RS400:
case CHIP_RS480:
- if (rec->hw_capable)
- ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
- else
- ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
+ ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_RS600:
case CHIP_RS690:
case CHIP_RS740:
/* XXX fill in hw i2c implementation */
- ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_RV515:
case CHIP_R520:
@@ -814,20 +816,16 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
case CHIP_RV560:
case CHIP_RV570:
case CHIP_R580:
- if (rec->hw_capable) {
- if (rec->mm_i2c)
- ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
- else
- ret = r500_hw_i2c_xfer(i2c_adap, msgs, num);
- } else
- ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
+ if (rec->mm_i2c)
+ ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
+ else
+ ret = r500_hw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_R600:
case CHIP_RV610:
case CHIP_RV630:
case CHIP_RV670:
/* XXX fill in hw i2c implementation */
- ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_RV620:
case CHIP_RV635:
@@ -838,7 +836,6 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
case CHIP_RV710:
case CHIP_RV740:
/* XXX fill in hw i2c implementation */
- ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
case CHIP_CEDAR:
case CHIP_REDWOOD:
@@ -846,7 +843,6 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
case CHIP_CYPRESS:
case CHIP_HEMLOCK:
/* XXX fill in hw i2c implementation */
- ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
break;
default:
DRM_ERROR("i2c: unhandled radeon chip\n");
@@ -857,20 +853,21 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
return ret;
}
-static u32 radeon_i2c_func(struct i2c_adapter *adap)
+static u32 radeon_hw_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static const struct i2c_algorithm radeon_i2c_algo = {
- .master_xfer = radeon_i2c_xfer,
- .functionality = radeon_i2c_func,
+ .master_xfer = radeon_hw_i2c_xfer,
+ .functionality = radeon_hw_i2c_func,
};
struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name)
{
+ struct radeon_device *rdev = dev->dev_private;
struct radeon_i2c_chan *i2c;
int ret;
@@ -878,37 +875,43 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
if (i2c == NULL)
return NULL;
- /* set the internal bit adapter */
- i2c->algo.radeon.bit_adapter.owner = THIS_MODULE;
- i2c_set_adapdata(&i2c->algo.radeon.bit_adapter, i2c);
- sprintf(i2c->algo.radeon.bit_adapter.name, "Radeon internal i2c bit bus %s", name);
- i2c->algo.radeon.bit_adapter.algo_data = &i2c->algo.radeon.bit_data;
- i2c->algo.radeon.bit_data.setsda = set_data;
- i2c->algo.radeon.bit_data.setscl = set_clock;
- i2c->algo.radeon.bit_data.getsda = get_data;
- i2c->algo.radeon.bit_data.getscl = get_clock;
- i2c->algo.radeon.bit_data.udelay = 20;
- /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
- * make this, 2 jiffies is a lot more reliable */
- i2c->algo.radeon.bit_data.timeout = 2;
- i2c->algo.radeon.bit_data.data = i2c;
- ret = i2c_bit_add_bus(&i2c->algo.radeon.bit_adapter);
- if (ret) {
- DRM_ERROR("Failed to register internal bit i2c %s\n", name);
- goto out_free;
- }
- /* set the radeon i2c adapter */
- i2c->dev = dev;
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
+ i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);
- sprintf(i2c->adapter.name, "Radeon i2c %s", name);
- i2c->adapter.algo_data = &i2c->algo.radeon;
- i2c->adapter.algo = &radeon_i2c_algo;
- ret = i2c_add_adapter(&i2c->adapter);
- if (ret) {
- DRM_ERROR("Failed to register i2c %s\n", name);
- goto out_free;
+ if (rec->mm_i2c ||
+ (rec->hw_capable &&
+ radeon_hw_i2c &&
+ ((rdev->family <= CHIP_RS480) ||
+ ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) {
+ /* set the radeon hw i2c adapter */
+ sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name);
+ i2c->adapter.algo = &radeon_i2c_algo;
+ ret = i2c_add_adapter(&i2c->adapter);
+ if (ret) {
+ DRM_ERROR("Failed to register hw i2c %s\n", name);
+ goto out_free;
+ }
+ } else {
+ /* set the radeon bit adapter */
+ sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name);
+ i2c->adapter.algo_data = &i2c->algo.bit;
+ i2c->algo.bit.pre_xfer = pre_xfer;
+ i2c->algo.bit.post_xfer = post_xfer;
+ i2c->algo.bit.setsda = set_data;
+ i2c->algo.bit.setscl = set_clock;
+ i2c->algo.bit.getsda = get_data;
+ i2c->algo.bit.getscl = get_clock;
+ i2c->algo.bit.udelay = 20;
+ /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
+ * make this, 2 jiffies is a lot more reliable */
+ i2c->algo.bit.timeout = 2;
+ i2c->algo.bit.data = i2c;
+ ret = i2c_bit_add_bus(&i2c->adapter);
+ if (ret) {
+ DRM_ERROR("Failed to register bit i2c %s\n", name);
+ goto out_free;
+ }
}
return i2c;
@@ -953,16 +956,6 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
{
if (!i2c)
return;
- i2c_del_adapter(&i2c->algo.radeon.bit_adapter);
- i2c_del_adapter(&i2c->adapter);
- kfree(i2c);
-}
-
-void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c)
-{
- if (!i2c)
- return;
-
i2c_del_adapter(&i2c->adapter);
kfree(i2c);
}
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 3cfd60fd008..a212041e8b0 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -67,9 +67,10 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
/* Disable *all* interrupts */
rdev->irq.sw_int = false;
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < rdev->num_crtc; i++)
rdev->irq.crtc_vblank_int[i] = false;
- }
+ for (i = 0; i < 6; i++)
+ rdev->irq.hpd[i] = false;
radeon_irq_set(rdev);
/* Clear bits */
radeon_irq_process(rdev);
@@ -95,34 +96,29 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
}
/* Disable *all* interrupts */
rdev->irq.sw_int = false;
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < rdev->num_crtc; i++)
rdev->irq.crtc_vblank_int[i] = false;
+ for (i = 0; i < 6; i++)
rdev->irq.hpd[i] = false;
- }
radeon_irq_set(rdev);
}
int radeon_irq_kms_init(struct radeon_device *rdev)
{
int r = 0;
- int num_crtc = 2;
- if (rdev->flags & RADEON_SINGLE_CRTC)
- num_crtc = 1;
spin_lock_init(&rdev->irq.sw_lock);
- r = drm_vblank_init(rdev->ddev, num_crtc);
+ r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
if (r) {
return r;
}
/* enable msi */
rdev->msi_enabled = 0;
- /* MSIs don't seem to work on my rs780;
- * not sure about rs880 or other rs780s.
- * Needs more investigation.
+ /* MSIs don't seem to work reliably on all IGP
+ * chips. Disable MSI on them for now.
*/
if ((rdev->family >= CHIP_RV380) &&
- (rdev->family != CHIP_RS780) &&
- (rdev->family != CHIP_RS880)) {
+ (!(rdev->flags & RADEON_IS_IGP))) {
int ret = pci_enable_msi(rdev->pdev);
if (!ret) {
rdev->msi_enabled = 1;
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 20ec276e759..c633319f98e 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -31,6 +31,7 @@
#include "radeon_drm.h"
#include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
int radeon_driver_unload_kms(struct drm_device *dev)
{
@@ -164,7 +165,7 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
{
struct radeon_device *rdev = dev->dev_private;
- if (crtc < 0 || crtc > 1) {
+ if (crtc < 0 || crtc >= rdev->num_crtc) {
DRM_ERROR("Invalid crtc %d\n", crtc);
return -EINVAL;
}
@@ -176,7 +177,7 @@ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)
{
struct radeon_device *rdev = dev->dev_private;
- if (crtc < 0 || crtc > 1) {
+ if (crtc < 0 || crtc >= rdev->num_crtc) {
DRM_ERROR("Invalid crtc %d\n", crtc);
return -EINVAL;
}
@@ -190,7 +191,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
{
struct radeon_device *rdev = dev->dev_private;
- if (crtc < 0 || crtc > 1) {
+ if (crtc < 0 || crtc >= rdev->num_crtc) {
DRM_ERROR("Invalid crtc %d\n", crtc);
return;
}
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index df23d6a01d0..88865e38fe3 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -603,6 +603,10 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
? RADEON_CRTC2_INTERLACE_EN
: 0));
+ /* rs4xx chips seem to like to have the crtc enabled when the timing is set */
+ if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480))
+ crtc2_gen_cntl |= RADEON_CRTC2_EN;
+
disp2_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
@@ -630,6 +634,10 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
? RADEON_CRTC_INTERLACE_EN
: 0));
+ /* rs4xx chips seem to like to have the crtc enabled when the timing is set */
+ if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480))
+ crtc_gen_cntl |= RADEON_CRTC_EN;
+
crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
crtc_ext_cntl |= (RADEON_XCRT_CNT_EN |
RADEON_CRTC_VSYNC_DIS |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index cf389ce50a8..2441cca7d77 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -830,8 +830,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
if (rdev->family == CHIP_R420 ||
- rdev->family == CHIP_R423 ||
- rdev->family == CHIP_RV410)
+ rdev->family == CHIP_R423 ||
+ rdev->family == CHIP_RV410)
tv_dac_cntl |= (R420_TV_DAC_RDACPD |
R420_TV_DAC_GDACPD |
R420_TV_DAC_BDACPD |
@@ -907,35 +907,43 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
if (rdev->family != CHIP_R200) {
tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
if (rdev->family == CHIP_R420 ||
- rdev->family == CHIP_R423 ||
- rdev->family == CHIP_RV410) {
+ rdev->family == CHIP_R423 ||
+ rdev->family == CHIP_RV410) {
tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
- RADEON_TV_DAC_BGADJ_MASK |
- R420_TV_DAC_DACADJ_MASK |
- R420_TV_DAC_RDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_BDACPD |
- R420_TV_DAC_TVENABLE);
+ RADEON_TV_DAC_BGADJ_MASK |
+ R420_TV_DAC_DACADJ_MASK |
+ R420_TV_DAC_RDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_BDACPD |
+ R420_TV_DAC_TVENABLE);
} else {
tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
- RADEON_TV_DAC_BGADJ_MASK |
- RADEON_TV_DAC_DACADJ_MASK |
- RADEON_TV_DAC_RDACPD |
- RADEON_TV_DAC_GDACPD |
- RADEON_TV_DAC_BDACPD);
+ RADEON_TV_DAC_BGADJ_MASK |
+ RADEON_TV_DAC_DACADJ_MASK |
+ RADEON_TV_DAC_RDACPD |
+ RADEON_TV_DAC_GDACPD |
+ RADEON_TV_DAC_BDACPD);
}
- /* FIXME TV */
- if (tv_dac) {
- struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
- tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
- RADEON_TV_DAC_NHOLD |
- RADEON_TV_DAC_STD_PS2 |
- tv_dac->ps2_tvdac_adj);
+ tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;
+
+ if (is_tv) {
+ if (tv_dac->tv_std == TV_STD_NTSC ||
+ tv_dac->tv_std == TV_STD_NTSC_J ||
+ tv_dac->tv_std == TV_STD_PAL_M ||
+ tv_dac->tv_std == TV_STD_PAL_60)
+ tv_dac_cntl |= tv_dac->ntsc_tvdac_adj;
+ else
+ tv_dac_cntl |= tv_dac->pal_tvdac_adj;
+
+ if (tv_dac->tv_std == TV_STD_NTSC ||
+ tv_dac->tv_std == TV_STD_NTSC_J)
+ tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+ else
+ tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
} else
- tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
- RADEON_TV_DAC_NHOLD |
- RADEON_TV_DAC_STD_PS2);
+ tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2 |
+ tv_dac->ps2_tvdac_adj);
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
}
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c
index 417684daef4..f2ed27c8055 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c
@@ -57,6 +57,10 @@
#define NTSC_TV_PLL_N_14 693
#define NTSC_TV_PLL_P_14 7
+#define PAL_TV_PLL_M_14 19
+#define PAL_TV_PLL_N_14 353
+#define PAL_TV_PLL_P_14 5
+
#define VERT_LEAD_IN_LINES 2
#define FRAC_BITS 0xe
#define FRAC_MASK 0x3fff
@@ -205,9 +209,24 @@ static const struct radeon_tv_mode_constants available_tv_modes[] = {
630627, /* defRestart */
347, /* crtcPLL_N */
14, /* crtcPLL_M */
- 8, /* crtcPLL_postDiv */
+ 8, /* crtcPLL_postDiv */
1022, /* pixToTV */
},
+ { /* PAL timing for 14 Mhz ref clk */
+ 800, /* horResolution */
+ 600, /* verResolution */
+ TV_STD_PAL, /* standard */
+ 1131, /* horTotal */
+ 742, /* verTotal */
+ 813, /* horStart */
+ 840, /* horSyncStart */
+ 633, /* verSyncStart */
+ 708369, /* defRestart */
+ 211, /* crtcPLL_N */
+ 9, /* crtcPLL_M */
+ 8, /* crtcPLL_postDiv */
+ 759, /* pixToTV */
+ },
};
#define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes)
@@ -242,7 +261,7 @@ static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(stru
if (pll->reference_freq == 2700)
const_ptr = &available_tv_modes[1];
else
- const_ptr = &available_tv_modes[1]; /* FIX ME */
+ const_ptr = &available_tv_modes[3];
}
return const_ptr;
}
@@ -685,9 +704,9 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
n = PAL_TV_PLL_N_27;
p = PAL_TV_PLL_P_27;
} else {
- m = PAL_TV_PLL_M_27;
- n = PAL_TV_PLL_N_27;
- p = PAL_TV_PLL_P_27;
+ m = PAL_TV_PLL_M_14;
+ n = PAL_TV_PLL_N_14;
+ p = PAL_TV_PLL_P_14;
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 1702b820aa4..0b8e32776b1 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -129,6 +129,7 @@ struct radeon_tmds_pll {
#define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10)
#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
#define RADEON_PLL_USE_POST_DIV (1 << 12)
+#define RADEON_PLL_IS_LCD (1 << 13)
/* pll algo */
enum radeon_pll_algo {
@@ -149,6 +150,8 @@ struct radeon_pll {
uint32_t pll_in_max;
uint32_t pll_out_min;
uint32_t pll_out_max;
+ uint32_t lcd_pll_out_min;
+ uint32_t lcd_pll_out_max;
uint32_t best_vco;
/* divider limits */
@@ -170,17 +173,12 @@ struct radeon_pll {
enum radeon_pll_algo algo;
};
-struct i2c_algo_radeon_data {
- struct i2c_adapter bit_adapter;
- struct i2c_algo_bit_data bit_data;
-};
-
struct radeon_i2c_chan {
struct i2c_adapter adapter;
struct drm_device *dev;
union {
+ struct i2c_algo_bit_data bit;
struct i2c_algo_dp_aux_data dp;
- struct i2c_algo_radeon_data radeon;
} algo;
struct radeon_i2c_bus_rec rec;
};
@@ -342,6 +340,7 @@ struct radeon_encoder {
struct drm_display_mode native_mode;
void *enc_priv;
int hdmi_offset;
+ int hdmi_config_offset;
int hdmi_audio_workaround;
int hdmi_buffer_status;
};
@@ -431,7 +430,6 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name);
extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
-extern void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c);
extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index fc9d00ac6b1..122774742bd 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -30,6 +30,7 @@
* Dave Airlie
*/
#include <linux/list.h>
+#include <linux/slab.h>
#include <drm/drmP.h>
#include "radeon_drm.h"
#include "radeon.h"
@@ -185,8 +186,10 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
return 0;
}
radeon_ttm_placement_from_domain(bo, domain);
- /* force to pin into visible video ram */
- bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
+ if (domain == RADEON_GEM_DOMAIN_VRAM) {
+ /* force to pin into visible video ram */
+ bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
+ }
for (i = 0; i < bo->placement.num_placement; i++)
bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index d4d1c39a0e9..a4b57493aa7 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -28,6 +28,7 @@
#define RADEON_RECLOCK_DELAY_MS 200
#define RADEON_WAIT_VBLANK_TIMEOUT 200
+static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
static void radeon_pm_set_clocks_locked(struct radeon_device *rdev);
static void radeon_pm_set_clocks(struct radeon_device *rdev);
static void radeon_pm_idle_work_handler(struct work_struct *work);
@@ -179,6 +180,16 @@ static void radeon_get_power_state(struct radeon_device *rdev,
rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
}
+static inline void radeon_sync_with_vblank(struct radeon_device *rdev)
+{
+ if (rdev->pm.active_crtcs) {
+ rdev->pm.vblank_sync = false;
+ wait_event_timeout(
+ rdev->irq.vblank_queue, rdev->pm.vblank_sync,
+ msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
+ }
+}
+
static void radeon_set_power_state(struct radeon_device *rdev)
{
/* if *_clock_mode are the same, *_power_state are as well */
@@ -189,11 +200,28 @@ static void radeon_set_power_state(struct radeon_device *rdev)
rdev->pm.requested_clock_mode->sclk,
rdev->pm.requested_clock_mode->mclk,
rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
+
/* set pcie lanes */
+ /* TODO */
+
/* set voltage */
+ /* TODO */
+
/* set engine clock */
+ radeon_sync_with_vblank(rdev);
+ radeon_pm_debug_check_in_vbl(rdev, false);
radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk);
+ radeon_pm_debug_check_in_vbl(rdev, true);
+
+#if 0
/* set memory clock */
+ if (rdev->asic->set_memory_clock) {
+ radeon_sync_with_vblank(rdev);
+ radeon_pm_debug_check_in_vbl(rdev, false);
+ radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk);
+ radeon_pm_debug_check_in_vbl(rdev, true);
+ }
+#endif
rdev->pm.current_power_state = rdev->pm.requested_power_state;
rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode;
@@ -229,6 +257,12 @@ int radeon_pm_init(struct radeon_device *rdev)
return 0;
}
+void radeon_pm_fini(struct radeon_device *rdev)
+{
+ if (rdev->pm.i2c_bus)
+ radeon_i2c_destroy(rdev->pm.i2c_bus);
+}
+
void radeon_pm_compute_clocks(struct radeon_device *rdev)
{
struct drm_device *ddev = rdev->ddev;
@@ -245,7 +279,8 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
list_for_each_entry(connector,
&ddev->mode_config.connector_list, head) {
if (connector->encoder &&
- connector->dpms != DRM_MODE_DPMS_OFF) {
+ connector->encoder->crtc &&
+ connector->dpms != DRM_MODE_DPMS_OFF) {
radeon_crtc = to_radeon_crtc(connector->encoder->crtc);
rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
++count;
@@ -333,10 +368,7 @@ static void radeon_pm_set_clocks_locked(struct radeon_device *rdev)
break;
}
- /* check if we are in vblank */
- radeon_pm_debug_check_in_vbl(rdev, false);
radeon_set_power_state(rdev);
- radeon_pm_debug_check_in_vbl(rdev, true);
rdev->pm.planned_action = PM_ACTION_NONE;
}
@@ -353,10 +385,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
rdev->pm.req_vblank |= (1 << 1);
drm_vblank_get(rdev->ddev, 1);
}
- if (rdev->pm.active_crtcs)
- wait_event_interruptible_timeout(
- rdev->irq.vblank_queue, 0,
- msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
+ radeon_pm_set_clocks_locked(rdev);
if (rdev->pm.req_vblank & (1 << 0)) {
rdev->pm.req_vblank &= ~(1 << 0);
drm_vblank_put(rdev->ddev, 0);
@@ -366,7 +395,6 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
drm_vblank_put(rdev->ddev, 1);
}
- radeon_pm_set_clocks_locked(rdev);
mutex_unlock(&rdev->cp.mutex);
}
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
index 5c0dc082d33..eabbc9cf30a 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -346,6 +346,7 @@
# define RADEON_TVPLL_PWRMGT_OFF (1 << 30)
# define RADEON_TVCLK_TURNOFF (1 << 31)
#define RADEON_PLL_PWRMGT_CNTL 0x0015 /* PLL */
+# define RADEON_PM_MODE_SEL (1 << 13)
# define RADEON_TCL_BYPASS_DISABLE (1 << 20)
#define RADEON_CLR_CMP_CLR_3D 0x1a24
#define RADEON_CLR_CMP_CLR_DST 0x15c8
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index e50513a6273..f6e1e8d4d98 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -26,6 +26,7 @@
* Jerome Glisse
*/
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "radeon_drm.h"
#include "radeon_reg.h"
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
index 3c32f840dcd..40ab6d9c373 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -1093,7 +1093,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
/* judging by the first tile offset needed, could possibly
directly address/clear 4x4 tiles instead of 8x2 * 4x4
macro tiles, though would still need clear mask for
- right/bottom if truely 4x4 granularity is desired ? */
+ right/bottom if truly 4x4 granularity is desired ? */
OUT_RING(tileoffset * 16);
/* the number of tiles to clear */
OUT_RING(nrtilesx + 1);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 43c5ab34b63..d031b686308 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -36,6 +36,7 @@
#include <drm/drmP.h>
#include <drm/radeon_drm.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "radeon_reg.h"
#include "radeon.h"
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300
index 19c4663fa9c..1e97b2d129f 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/r300
+++ b/drivers/gpu/drm/radeon/reg_srcs/r300
@@ -125,6 +125,8 @@ r300 0x4f60
0x4000 GB_VAP_RASTER_VTX_FMT_0
0x4004 GB_VAP_RASTER_VTX_FMT_1
0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
0x401C GB_SELECT
0x4020 GB_AA_CONFIG
0x4024 GB_FIFO_SIZE
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420
index 989f7a02083..e958980d00f 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/r420
+++ b/drivers/gpu/drm/radeon/reg_srcs/r420
@@ -125,6 +125,8 @@ r420 0x4f60
0x4000 GB_VAP_RASTER_VTX_FMT_0
0x4004 GB_VAP_RASTER_VTX_FMT_1
0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
0x401C GB_SELECT
0x4020 GB_AA_CONFIG
0x4024 GB_FIFO_SIZE
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600
index 8f414a5f520..af0da4ae3f5 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/r600
+++ b/drivers/gpu/drm/radeon/reg_srcs/r600
@@ -26,20 +26,16 @@ r600 0x9400
0x00028408 VGT_INDX_OFFSET
0x00028AA0 VGT_INSTANCE_STEP_RATE_0
0x00028AA4 VGT_INSTANCE_STEP_RATE_1
-0x000088C0 VGT_LAST_COPY_STATE
0x00028400 VGT_MAX_VTX_INDX
-0x000088D8 VGT_MC_LAT_CNTL
0x00028404 VGT_MIN_VTX_INDX
0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN
0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX
0x00008970 VGT_NUM_INDICES
0x00008974 VGT_NUM_INSTANCES
0x00028A10 VGT_OUTPUT_PATH_CNTL
-0x00028C5C VGT_OUT_DEALLOC_CNTL
0x00028A84 VGT_PRIMITIVEID_EN
0x00008958 VGT_PRIMITIVE_TYPE
0x00028AB4 VGT_REUSE_OFF
-0x00028C58 VGT_VERTEX_REUSE_BLOCK_CNTL
0x00028AB8 VGT_VTX_CNT_EN
0x000088B0 VGT_VTX_VECT_EJECT_REG
0x00028810 PA_CL_CLIP_CNTL
@@ -280,7 +276,6 @@ r600 0x9400
0x00028E00 PA_SU_POLY_OFFSET_FRONT_SCALE
0x00028814 PA_SU_SC_MODE_CNTL
0x00028C08 PA_SU_VTX_CNTL
-0x00008C00 SQ_CONFIG
0x00008C04 SQ_GPR_RESOURCE_MGMT_1
0x00008C08 SQ_GPR_RESOURCE_MGMT_2
0x00008C10 SQ_STACK_RESOURCE_MGMT_1
@@ -320,18 +315,6 @@ r600 0x9400
0x000283FC SQ_VTX_SEMANTIC_31
0x000288E0 SQ_VTX_SEMANTIC_CLEAR
0x0003CFF4 SQ_VTX_START_INST_LOC
-0x0003C000 SQ_TEX_SAMPLER_WORD0_0
-0x0003C004 SQ_TEX_SAMPLER_WORD1_0
-0x0003C008 SQ_TEX_SAMPLER_WORD2_0
-0x00030000 SQ_ALU_CONSTANT0_0
-0x00030004 SQ_ALU_CONSTANT1_0
-0x00030008 SQ_ALU_CONSTANT2_0
-0x0003000C SQ_ALU_CONSTANT3_0
-0x0003E380 SQ_BOOL_CONST_0
-0x0003E384 SQ_BOOL_CONST_1
-0x0003E388 SQ_BOOL_CONST_2
-0x0003E200 SQ_LOOP_CONST_0
-0x0003E200 SQ_LOOP_CONST_DX10_0
0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0
0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1
0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2
@@ -380,54 +363,6 @@ r600 0x9400
0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13
0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14
0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15
-0x000289C0 SQ_ALU_CONST_CACHE_GS_0
-0x000289C4 SQ_ALU_CONST_CACHE_GS_1
-0x000289C8 SQ_ALU_CONST_CACHE_GS_2
-0x000289CC SQ_ALU_CONST_CACHE_GS_3
-0x000289D0 SQ_ALU_CONST_CACHE_GS_4
-0x000289D4 SQ_ALU_CONST_CACHE_GS_5
-0x000289D8 SQ_ALU_CONST_CACHE_GS_6
-0x000289DC SQ_ALU_CONST_CACHE_GS_7
-0x000289E0 SQ_ALU_CONST_CACHE_GS_8
-0x000289E4 SQ_ALU_CONST_CACHE_GS_9
-0x000289E8 SQ_ALU_CONST_CACHE_GS_10
-0x000289EC SQ_ALU_CONST_CACHE_GS_11
-0x000289F0 SQ_ALU_CONST_CACHE_GS_12
-0x000289F4 SQ_ALU_CONST_CACHE_GS_13
-0x000289F8 SQ_ALU_CONST_CACHE_GS_14
-0x000289FC SQ_ALU_CONST_CACHE_GS_15
-0x00028940 SQ_ALU_CONST_CACHE_PS_0
-0x00028944 SQ_ALU_CONST_CACHE_PS_1
-0x00028948 SQ_ALU_CONST_CACHE_PS_2
-0x0002894C SQ_ALU_CONST_CACHE_PS_3
-0x00028950 SQ_ALU_CONST_CACHE_PS_4
-0x00028954 SQ_ALU_CONST_CACHE_PS_5
-0x00028958 SQ_ALU_CONST_CACHE_PS_6
-0x0002895C SQ_ALU_CONST_CACHE_PS_7
-0x00028960 SQ_ALU_CONST_CACHE_PS_8
-0x00028964 SQ_ALU_CONST_CACHE_PS_9
-0x00028968 SQ_ALU_CONST_CACHE_PS_10
-0x0002896C SQ_ALU_CONST_CACHE_PS_11
-0x00028970 SQ_ALU_CONST_CACHE_PS_12
-0x00028974 SQ_ALU_CONST_CACHE_PS_13
-0x00028978 SQ_ALU_CONST_CACHE_PS_14
-0x0002897C SQ_ALU_CONST_CACHE_PS_15
-0x00028980 SQ_ALU_CONST_CACHE_VS_0
-0x00028984 SQ_ALU_CONST_CACHE_VS_1
-0x00028988 SQ_ALU_CONST_CACHE_VS_2
-0x0002898C SQ_ALU_CONST_CACHE_VS_3
-0x00028990 SQ_ALU_CONST_CACHE_VS_4
-0x00028994 SQ_ALU_CONST_CACHE_VS_5
-0x00028998 SQ_ALU_CONST_CACHE_VS_6
-0x0002899C SQ_ALU_CONST_CACHE_VS_7
-0x000289A0 SQ_ALU_CONST_CACHE_VS_8
-0x000289A4 SQ_ALU_CONST_CACHE_VS_9
-0x000289A8 SQ_ALU_CONST_CACHE_VS_10
-0x000289AC SQ_ALU_CONST_CACHE_VS_11
-0x000289B0 SQ_ALU_CONST_CACHE_VS_12
-0x000289B4 SQ_ALU_CONST_CACHE_VS_13
-0x000289B8 SQ_ALU_CONST_CACHE_VS_14
-0x000289BC SQ_ALU_CONST_CACHE_VS_15
0x000288D8 SQ_PGM_CF_OFFSET_ES
0x000288DC SQ_PGM_CF_OFFSET_FS
0x000288D4 SQ_PGM_CF_OFFSET_GS
@@ -494,12 +429,7 @@ r600 0x9400
0x00028438 SX_ALPHA_REF
0x00028410 SX_ALPHA_TEST_CONTROL
0x00028350 SX_MISC
-0x0000A020 SMX_DC_CTL0
-0x0000A024 SMX_DC_CTL1
-0x0000A028 SMX_DC_CTL2
-0x00009608 TC_CNTL
0x00009604 TC_INVALIDATE
-0x00009490 TD_CNTL
0x00009400 TD_FILTER4
0x00009404 TD_FILTER4_1
0x00009408 TD_FILTER4_2
@@ -824,14 +754,9 @@ r600 0x9400
0x00028428 CB_FOG_GREEN
0x00028424 CB_FOG_RED
0x00008040 WAIT_UNTIL
-0x00008950 CC_GC_SHADER_PIPE_CONFIG
-0x00008954 GC_USER_SHADER_PIPE_CONFIG
0x00009714 VC_ENHANCE
0x00009830 DB_DEBUG
0x00009838 DB_WATERMARKS
0x00028D28 DB_SRESULTS_COMPARE_STATE0
0x00028D44 DB_ALPHA_TO_MASK
-0x00009504 TA_CNTL
0x00009700 VC_CNTL
-0x00009718 VC_CONFIG
-0x0000A02C SMX_DC_MC_INTF_CTL
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600
index 6801b865d1c..83e8bc0c2bb 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/rs600
+++ b/drivers/gpu/drm/radeon/reg_srcs/rs600
@@ -125,6 +125,8 @@ rs600 0x6d40
0x4000 GB_VAP_RASTER_VTX_FMT_0
0x4004 GB_VAP_RASTER_VTX_FMT_1
0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
0x401C GB_SELECT
0x4020 GB_AA_CONFIG
0x4024 GB_FIFO_SIZE
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515
index 38abf63bf2c..1e46233985e 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/rv515
+++ b/drivers/gpu/drm/radeon/reg_srcs/rv515
@@ -35,6 +35,7 @@ rv515 0x6d40
0x1DA8 VAP_VPORT_ZSCALE
0x1DAC VAP_VPORT_ZOFFSET
0x2080 VAP_CNTL
+0x208C VAP_INDEX_OFFSET
0x2090 VAP_OUT_VTX_FMT_0
0x2094 VAP_OUT_VTX_FMT_1
0x20B0 VAP_VTE_CNTL
@@ -158,6 +159,8 @@ rv515 0x6d40
0x4000 GB_VAP_RASTER_VTX_FMT_0
0x4004 GB_VAP_RASTER_VTX_FMT_1
0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
0x401C GB_SELECT
0x4020 GB_AA_CONFIG
0x4024 GB_FIFO_SIZE
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index 626d51891ee..1a41cb268b7 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -26,8 +26,10 @@
* Jerome Glisse
*/
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <drm/drmP.h>
#include "radeon.h"
+#include "radeon_asic.h"
#include "rs400d.h"
/* This files gather functions specifics to : rs400,rs480 */
@@ -202,9 +204,9 @@ void rs400_gart_disable(struct radeon_device *rdev)
void rs400_gart_fini(struct radeon_device *rdev)
{
+ radeon_gart_fini(rdev);
rs400_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
- radeon_gart_fini(rdev);
}
int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
@@ -264,6 +266,7 @@ void rs400_mc_init(struct radeon_device *rdev)
base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
radeon_vram_location(rdev, &rdev->mc, base);
radeon_gtt_location(rdev, &rdev->mc);
+ radeon_update_bandwidth_info(rdev);
}
uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -388,6 +391,8 @@ static int rs400_startup(struct radeon_device *rdev)
{
int r;
+ r100_set_common_regs(rdev);
+
rs400_mc_program(rdev);
/* Resume clock */
r300_clock_startup(rdev);
@@ -453,6 +458,7 @@ int rs400_suspend(struct radeon_device *rdev)
void rs400_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r100_cp_fini(rdev);
r100_wb_fini(rdev);
r100_ib_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 47f046b78c6..a81bc7a21e1 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -37,6 +37,7 @@
*/
#include "drmP.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "atom.h"
#include "rs600d.h"
@@ -158,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
- tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1);
+ tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1);
WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
@@ -267,9 +268,9 @@ void rs600_gart_disable(struct radeon_device *rdev)
void rs600_gart_fini(struct radeon_device *rdev)
{
+ radeon_gart_fini(rdev);
rs600_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
- radeon_gart_fini(rdev);
}
#define R600_PTE_VALID (1 << 0)
@@ -392,10 +393,12 @@ int rs600_irq_process(struct radeon_device *rdev)
/* Vertical blank interrupts */
if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) {
drm_handle_vblank(rdev->ddev, 0);
+ rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue);
}
if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) {
drm_handle_vblank(rdev->ddev, 1);
+ rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue);
}
if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) {
@@ -472,13 +475,38 @@ void rs600_mc_init(struct radeon_device *rdev)
rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
base = RREG32_MC(R_000004_MC_FB_LOCATION);
base = G_000004_MC_FB_START(base) << 16;
+ rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
radeon_vram_location(rdev, &rdev->mc, base);
radeon_gtt_location(rdev, &rdev->mc);
+ radeon_update_bandwidth_info(rdev);
}
void rs600_bandwidth_update(struct radeon_device *rdev)
{
- /* FIXME: implement, should this be like rs690 ? */
+ struct drm_display_mode *mode0 = NULL;
+ struct drm_display_mode *mode1 = NULL;
+ u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt;
+ /* FIXME: implement full support */
+
+ radeon_update_display_priority(rdev);
+
+ if (rdev->mode_info.crtcs[0]->base.enabled)
+ mode0 = &rdev->mode_info.crtcs[0]->base.mode;
+ if (rdev->mode_info.crtcs[1]->base.enabled)
+ mode1 = &rdev->mode_info.crtcs[1]->base.mode;
+
+ rs690_line_buffer_adjust(rdev, mode0, mode1);
+
+ if (rdev->disp_priority == 2) {
+ d1mode_priority_a_cnt = RREG32(R_006548_D1MODE_PRIORITY_A_CNT);
+ d2mode_priority_a_cnt = RREG32(R_006D48_D2MODE_PRIORITY_A_CNT);
+ d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+ d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+ WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+ WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+ WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+ WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
+ }
}
uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -598,6 +626,7 @@ int rs600_suspend(struct radeon_device *rdev)
void rs600_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r100_cp_fini(rdev);
r100_wb_fini(rdev);
r100_ib_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h
index c1c8f5885cb..e52d2695510 100644
--- a/drivers/gpu/drm/radeon/rs600d.h
+++ b/drivers/gpu/drm/radeon/rs600d.h
@@ -535,4 +535,57 @@
#define G_00016C_INVALIDATE_L1_TLB(x) (((x) >> 20) & 0x1)
#define C_00016C_INVALIDATE_L1_TLB 0xFFEFFFFF
+#define R_006548_D1MODE_PRIORITY_A_CNT 0x006548
+#define S_006548_D1MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0)
+#define G_006548_D1MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF)
+#define C_006548_D1MODE_PRIORITY_MARK_A 0xFFFF8000
+#define S_006548_D1MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16)
+#define G_006548_D1MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1)
+#define C_006548_D1MODE_PRIORITY_A_OFF 0xFFFEFFFF
+#define S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20)
+#define G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1)
+#define C_006548_D1MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF
+#define S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24)
+#define G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1)
+#define C_006548_D1MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF
+#define R_00654C_D1MODE_PRIORITY_B_CNT 0x00654C
+#define S_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0)
+#define G_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF)
+#define C_00654C_D1MODE_PRIORITY_MARK_B 0xFFFF8000
+#define S_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16)
+#define G_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1)
+#define C_00654C_D1MODE_PRIORITY_B_OFF 0xFFFEFFFF
+#define S_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20)
+#define G_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1)
+#define C_00654C_D1MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF
+#define S_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24)
+#define G_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1)
+#define C_00654C_D1MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF
+#define R_006D48_D2MODE_PRIORITY_A_CNT 0x006D48
+#define S_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0)
+#define G_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF)
+#define C_006D48_D2MODE_PRIORITY_MARK_A 0xFFFF8000
+#define S_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16)
+#define G_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1)
+#define C_006D48_D2MODE_PRIORITY_A_OFF 0xFFFEFFFF
+#define S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20)
+#define G_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1)
+#define C_006D48_D2MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF
+#define S_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24)
+#define G_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1)
+#define C_006D48_D2MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF
+#define R_006D4C_D2MODE_PRIORITY_B_CNT 0x006D4C
+#define S_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0)
+#define G_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF)
+#define C_006D4C_D2MODE_PRIORITY_MARK_B 0xFFFF8000
+#define S_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16)
+#define G_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1)
+#define C_006D4C_D2MODE_PRIORITY_B_OFF 0xFFFEFFFF
+#define S_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20)
+#define G_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1)
+#define C_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF
+#define S_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24)
+#define G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1)
+#define C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF
+
#endif
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 83b9174f76f..bbf3da790fd 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -27,6 +27,7 @@
*/
#include "drmP.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "atom.h"
#include "rs690d.h"
@@ -57,42 +58,57 @@ static void rs690_gpu_init(struct radeon_device *rdev)
}
}
+union igp_info {
+ struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+ struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2;
+};
+
void rs690_pm_info(struct radeon_device *rdev)
{
int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
- struct _ATOM_INTEGRATED_SYSTEM_INFO *info;
- struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *info_v2;
- void *ptr;
+ union igp_info *info;
uint16_t data_offset;
uint8_t frev, crev;
fixed20_12 tmp;
- atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
- &frev, &crev, &data_offset);
- ptr = rdev->mode_info.atom_context->bios + data_offset;
- info = (struct _ATOM_INTEGRATED_SYSTEM_INFO *)ptr;
- info_v2 = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *)ptr;
- /* Get various system informations from bios */
- switch (crev) {
- case 1:
- tmp.full = rfixed_const(100);
- rdev->pm.igp_sideport_mclk.full = rfixed_const(info->ulBootUpMemoryClock);
- rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
- rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->usK8MemoryClock));
- rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->usFSBClock));
- rdev->pm.igp_ht_link_width.full = rfixed_const(info->ucHTLinkWidth);
- break;
- case 2:
- tmp.full = rfixed_const(100);
- rdev->pm.igp_sideport_mclk.full = rfixed_const(info_v2->ulBootUpSidePortClock);
- rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
- rdev->pm.igp_system_mclk.full = rfixed_const(info_v2->ulBootUpUMAClock);
- rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
- rdev->pm.igp_ht_link_clk.full = rfixed_const(info_v2->ulHTLinkFreq);
- rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
- rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info_v2->usMinHTLinkWidth));
- break;
- default:
+ if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset);
+
+ /* Get various system informations from bios */
+ switch (crev) {
+ case 1:
+ tmp.full = rfixed_const(100);
+ rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info.ulBootUpMemoryClock);
+ rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
+ rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->info.usK8MemoryClock));
+ rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->info.usFSBClock));
+ rdev->pm.igp_ht_link_width.full = rfixed_const(info->info.ucHTLinkWidth);
+ break;
+ case 2:
+ tmp.full = rfixed_const(100);
+ rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info_v2.ulBootUpSidePortClock);
+ rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
+ rdev->pm.igp_system_mclk.full = rfixed_const(info->info_v2.ulBootUpUMAClock);
+ rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
+ rdev->pm.igp_ht_link_clk.full = rfixed_const(info->info_v2.ulHTLinkFreq);
+ rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
+ rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth));
+ break;
+ default:
+ tmp.full = rfixed_const(100);
+ /* We assume the slower possible clock ie worst case */
+ /* DDR 333Mhz */
+ rdev->pm.igp_sideport_mclk.full = rfixed_const(333);
+ /* FIXME: system clock ? */
+ rdev->pm.igp_system_mclk.full = rfixed_const(100);
+ rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
+ rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
+ rdev->pm.igp_ht_link_width.full = rfixed_const(8);
+ DRM_ERROR("No integrated system info for your GPU, using safe default\n");
+ break;
+ }
+ } else {
tmp.full = rfixed_const(100);
/* We assume the slower possible clock ie worst case */
/* DDR 333Mhz */
@@ -103,7 +119,6 @@ void rs690_pm_info(struct radeon_device *rdev)
rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
rdev->pm.igp_ht_link_width.full = rfixed_const(8);
DRM_ERROR("No integrated system info for your GPU, using safe default\n");
- break;
}
/* Compute various bandwidth */
/* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4 */
@@ -131,7 +146,6 @@ void rs690_pm_info(struct radeon_device *rdev)
void rs690_mc_init(struct radeon_device *rdev)
{
- fixed20_12 a;
u64 base;
rs400_gart_adjust_size(rdev);
@@ -145,18 +159,10 @@ void rs690_mc_init(struct radeon_device *rdev)
base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
base = G_000100_MC_FB_START(base) << 16;
rs690_pm_info(rdev);
- /* FIXME: we should enforce default clock in case GPU is not in
- * default setup
- */
- a.full = rfixed_const(100);
- rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
- rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
- a.full = rfixed_const(16);
- /* core_bandwidth = sclk(Mhz) * 16 */
- rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
radeon_vram_location(rdev, &rdev->mc, base);
radeon_gtt_location(rdev, &rdev->mc);
+ radeon_update_bandwidth_info(rdev);
}
void rs690_line_buffer_adjust(struct radeon_device *rdev,
@@ -394,10 +400,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
struct drm_display_mode *mode1 = NULL;
struct rs690_watermark wm0;
struct rs690_watermark wm1;
- u32 tmp;
+ u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
fixed20_12 priority_mark02, priority_mark12, fill_rate;
fixed20_12 a, b;
+ radeon_update_display_priority(rdev);
+
if (rdev->mode_info.crtcs[0]->base.enabled)
mode0 = &rdev->mode_info.crtcs[0]->base.mode;
if (rdev->mode_info.crtcs[1]->base.enabled)
@@ -407,7 +415,8 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
* modes if the user specifies HIGH for displaypriority
* option.
*/
- if (rdev->disp_priority == 2) {
+ if ((rdev->disp_priority == 2) &&
+ ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))) {
tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER);
tmp &= C_000104_MC_DISP0R_INIT_LAT;
tmp &= C_000104_MC_DISP1R_INIT_LAT;
@@ -482,10 +491,16 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
priority_mark12.full = 0;
if (wm1.priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1.priority_mark_max.full;
- WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
- WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
- WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
- WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+ d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+ d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+ if (rdev->disp_priority == 2) {
+ d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+ d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+ }
+ WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+ WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+ WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+ WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
} else if (mode0) {
if (rfixed_trunc(wm0.dbpp) > 64)
a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair);
@@ -512,8 +527,11 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
priority_mark02.full = 0;
if (wm0.priority_mark_max.full > priority_mark02.full)
priority_mark02.full = wm0.priority_mark_max.full;
- WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
- WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
+ d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+ if (rdev->disp_priority == 2)
+ d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+ WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+ WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,
S_006D48_D2MODE_PRIORITY_A_OFF(1));
WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT,
@@ -544,12 +562,15 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
priority_mark12.full = 0;
if (wm1.priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1.priority_mark_max.full;
+ d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+ if (rdev->disp_priority == 2)
+ d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
WREG32(R_006548_D1MODE_PRIORITY_A_CNT,
S_006548_D1MODE_PRIORITY_A_OFF(1));
WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,
S_00654C_D1MODE_PRIORITY_B_OFF(1));
- WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
- WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+ WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+ WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
}
}
@@ -657,6 +678,7 @@ int rs690_suspend(struct radeon_device *rdev)
void rs690_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r100_cp_fini(rdev);
r100_wb_fini(rdev);
r100_ib_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/rs690d.h b/drivers/gpu/drm/radeon/rs690d.h
index 62d31e7a897..36e6398a98a 100644
--- a/drivers/gpu/drm/radeon/rs690d.h
+++ b/drivers/gpu/drm/radeon/rs690d.h
@@ -182,6 +182,9 @@
#define S_006548_D1MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16)
#define G_006548_D1MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1)
#define C_006548_D1MODE_PRIORITY_A_OFF 0xFFFEFFFF
+#define S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20)
+#define G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1)
+#define C_006548_D1MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF
#define S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24)
#define G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1)
#define C_006548_D1MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index bea747da123..9035121f4b5 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -26,9 +26,11 @@
* Jerome Glisse
*/
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "rv515d.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "atom.h"
#include "rv515_reg_safe.h"
@@ -279,19 +281,13 @@ static void rv515_vram_get_type(struct radeon_device *rdev)
void rv515_mc_init(struct radeon_device *rdev)
{
- fixed20_12 a;
rv515_vram_get_type(rdev);
r100_vram_init_sizes(rdev);
radeon_vram_location(rdev, &rdev->mc, 0);
if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc);
- /* FIXME: we should enforce default clock in case GPU is not in
- * default setup
- */
- a.full = rfixed_const(100);
- rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
- rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+ radeon_update_bandwidth_info(rdev);
}
uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -539,6 +535,7 @@ void rv515_set_safe_registers(struct radeon_device *rdev)
void rv515_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r100_cp_fini(rdev);
r100_wb_fini(rdev);
r100_ib_fini(rdev);
@@ -1020,7 +1017,7 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
struct drm_display_mode *mode1 = NULL;
struct rv515_watermark wm0;
struct rv515_watermark wm1;
- u32 tmp;
+ u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
fixed20_12 priority_mark02, priority_mark12, fill_rate;
fixed20_12 a, b;
@@ -1088,10 +1085,16 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
priority_mark12.full = 0;
if (wm1.priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1.priority_mark_max.full;
- WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
- WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
- WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
- WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+ d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+ d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+ if (rdev->disp_priority == 2) {
+ d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+ d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+ }
+ WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+ WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+ WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+ WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
} else if (mode0) {
if (rfixed_trunc(wm0.dbpp) > 64)
a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair);
@@ -1118,8 +1121,11 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
priority_mark02.full = 0;
if (wm0.priority_mark_max.full > priority_mark02.full)
priority_mark02.full = wm0.priority_mark_max.full;
- WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
- WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
+ d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+ if (rdev->disp_priority == 2)
+ d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+ WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+ WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
} else {
@@ -1148,10 +1154,13 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
priority_mark12.full = 0;
if (wm1.priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1.priority_mark_max.full;
+ d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+ if (rdev->disp_priority == 2)
+ d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
- WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
- WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+ WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+ WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
}
}
@@ -1161,6 +1170,8 @@ void rv515_bandwidth_update(struct radeon_device *rdev)
struct drm_display_mode *mode0 = NULL;
struct drm_display_mode *mode1 = NULL;
+ radeon_update_display_priority(rdev);
+
if (rdev->mode_info.crtcs[0]->base.enabled)
mode0 = &rdev->mode_info.crtcs[0]->base.mode;
if (rdev->mode_info.crtcs[1]->base.enabled)
@@ -1170,7 +1181,8 @@ void rv515_bandwidth_update(struct radeon_device *rdev)
* modes if the user specifies HIGH for displaypriority
* option.
*/
- if (rdev->disp_priority == 2) {
+ if ((rdev->disp_priority == 2) &&
+ (rdev->family == CHIP_RV515)) {
tmp = RREG32_MC(MC_MISC_LAT_TIMER);
tmp &= ~MC_DISP1R_INIT_LAT_MASK;
tmp &= ~MC_DISP0R_INIT_LAT_MASK;
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 37887dee12a..97958a64df1 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -27,8 +27,10 @@
*/
#include <linux/firmware.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "drmP.h"
#include "radeon.h"
+#include "radeon_asic.h"
#include "radeon_drm.h"
#include "rv770d.h"
#include "atom.h"
@@ -125,9 +127,9 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
void rv770_pcie_gart_fini(struct radeon_device *rdev)
{
+ radeon_gart_fini(rdev);
rv770_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
- radeon_gart_fini(rdev);
}
@@ -647,10 +649,13 @@ static void rv770_gpu_init(struct radeon_device *rdev)
WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+ WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
WREG32(CGTS_SYS_TCC_DISABLE, 0);
WREG32(CGTS_TCC_DISABLE, 0);
+ WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
+ WREG32(CGTS_USER_TCC_DISABLE, 0);
num_qd_pipes =
R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
@@ -864,7 +869,6 @@ static void rv770_gpu_init(struct radeon_device *rdev)
int rv770_mc_init(struct radeon_device *rdev)
{
- fixed20_12 a;
u32 tmp;
int chansize, numchan;
@@ -908,12 +912,8 @@ int rv770_mc_init(struct radeon_device *rdev)
rdev->mc.real_vram_size = rdev->mc.aper_size;
}
r600_vram_gtt_location(rdev, &rdev->mc);
- /* FIXME: we should enforce default clock in case GPU is not in
- * default setup
- */
- a.full = rfixed_const(100);
- rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
- rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+ radeon_update_bandwidth_info(rdev);
+
return 0;
}
@@ -1013,6 +1013,13 @@ int rv770_resume(struct radeon_device *rdev)
DRM_ERROR("radeon: failled testing IB (%d).\n", r);
return r;
}
+
+ r = r600_audio_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "radeon: audio init failed\n");
+ return r;
+ }
+
return r;
}
@@ -1021,6 +1028,7 @@ int rv770_suspend(struct radeon_device *rdev)
{
int r;
+ r600_audio_fini(rdev);
/* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev);
rdev->cp.ready = false;
@@ -1144,11 +1152,19 @@ int rv770_init(struct radeon_device *rdev)
}
}
}
+
+ r = r600_audio_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "radeon: audio init failed\n");
+ return r;
+ }
+
return 0;
}
void rv770_fini(struct radeon_device *rdev)
{
+ radeon_pm_fini(rdev);
r600_blit_fini(rdev);
r600_cp_fini(rdev);
r600_wb_fini(rdev);
diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c
index 4648ed2f014..4bf69c40449 100644
--- a/drivers/gpu/drm/ttm/ttm_agp_backend.c
+++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c
@@ -35,6 +35,7 @@
#include "ttm/ttm_placement.h"
#include <linux/agp_backend.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <asm/agp.h>
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index c7320ce4567..dd47b2a9a79 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -128,7 +128,7 @@ static struct attribute *ttm_bo_global_attrs[] = {
NULL
};
-static struct sysfs_ops ttm_bo_global_ops = {
+static const struct sysfs_ops ttm_bo_global_ops = {
.show = &ttm_bo_global_show
};
@@ -1425,8 +1425,8 @@ int ttm_bo_global_init(struct ttm_global_reference *ref)
atomic_set(&glob->bo_count, 0);
- kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type);
- ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects");
+ ret = kobject_init_and_add(
+ &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects");
if (unlikely(ret != 0))
kobject_put(&glob->kobj);
return ret;
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 5ca37a58a98..d764e82e799 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -33,6 +33,7 @@
#include <linux/io.h>
#include <linux/highmem.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index f5245c02b8f..801b702566e 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -32,6 +32,7 @@
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/slab.h>
#define TTM_MEMORY_ALLOC_RETRIES 4
@@ -152,7 +153,7 @@ static struct attribute *ttm_mem_zone_attrs[] = {
NULL
};
-static struct sysfs_ops ttm_mem_zone_ops = {
+static const struct sysfs_ops ttm_mem_zone_ops = {
.show = &ttm_mem_zone_show,
.store = &ttm_mem_zone_store
};
@@ -260,8 +261,8 @@ static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob,
zone->used_mem = 0;
zone->glob = glob;
glob->zone_kernel = zone;
- kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
- ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+ ret = kobject_init_and_add(
+ &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
if (unlikely(ret != 0)) {
kobject_put(&zone->kobj);
return ret;
@@ -296,8 +297,8 @@ static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob,
zone->used_mem = 0;
zone->glob = glob;
glob->zone_highmem = zone;
- kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
- ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+ ret = kobject_init_and_add(
+ &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
if (unlikely(ret != 0)) {
kobject_put(&zone->kobj);
return ret;
@@ -343,8 +344,8 @@ static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob,
zone->used_mem = 0;
zone->glob = glob;
glob->zone_dma32 = zone;
- kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
- ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+ ret = kobject_init_and_add(
+ &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
if (unlikely(ret != 0)) {
kobject_put(&zone->kobj);
return ret;
@@ -365,10 +366,8 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
glob->swap_queue = create_singlethread_workqueue("ttm_swap");
INIT_WORK(&glob->work, ttm_shrink_work);
init_waitqueue_head(&glob->queue);
- kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type);
- ret = kobject_add(&glob->kobj,
- ttm_get_kobj(),
- "memory_accounting");
+ ret = kobject_init_and_add(
+ &glob->kobj, &ttm_mem_glob_kobj_type, ttm_get_kobj(), "memory_accounting");
if (unlikely(ret != 0)) {
kobject_put(&glob->kobj);
return ret;
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index a759170763b..d5fd5b8faeb 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -28,13 +28,14 @@
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
-#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/file.h>
#include <linux/swap.h>
+#include <linux/slab.h>
#include "drm_cache.h"
+#include "drm_mem_util.h"
#include "ttm/ttm_module.h"
#include "ttm/ttm_bo_driver.h"
#include "ttm/ttm_placement.h"
@@ -43,32 +44,15 @@ static int ttm_tt_swapin(struct ttm_tt *ttm);
/**
* Allocates storage for pointers to the pages that back the ttm.
- *
- * Uses kmalloc if possible. Otherwise falls back to vmalloc.
*/
static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm)
{
- unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
- ttm->pages = NULL;
-
- if (size <= PAGE_SIZE)
- ttm->pages = kzalloc(size, GFP_KERNEL);
-
- if (!ttm->pages) {
- ttm->pages = vmalloc_user(size);
- if (ttm->pages)
- ttm->page_flags |= TTM_PAGE_FLAG_VMALLOC;
- }
+ ttm->pages = drm_calloc_large(ttm->num_pages, sizeof(*ttm->pages));
}
static void ttm_tt_free_page_directory(struct ttm_tt *ttm)
{
- if (ttm->page_flags & TTM_PAGE_FLAG_VMALLOC) {
- vfree(ttm->pages);
- ttm->page_flags &= ~TTM_PAGE_FLAG_VMALLOC;
- } else {
- kfree(ttm->pages);
- }
+ drm_free_large(ttm->pages);
ttm->pages = NULL;
}
diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c
index 327380888b4..4c54f043068 100644
--- a/drivers/gpu/drm/via/via_dmablit.c
+++ b/drivers/gpu/drm/via/via_dmablit.c
@@ -40,6 +40,7 @@
#include "via_dmablit.h"
#include <linux/pagemap.h>
+#include <linux/slab.h>
#define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK)
#define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK)
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c
index 5935b8842e8..34079f251cd 100644
--- a/drivers/gpu/drm/via/via_irq.c
+++ b/drivers/gpu/drm/via/via_irq.c
@@ -150,7 +150,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
cur_irq++;
}
- /* Acknowlege interrupts */
+ /* Acknowledge interrupts */
VIA_WRITE(VIA_REG_INTERRUPT, status);
@@ -165,7 +165,7 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
u32 status;
if (dev_priv) {
- /* Acknowlege interrupts */
+ /* Acknowledge interrupts */
status = VIA_READ(VIA_REG_INTERRUPT);
VIA_WRITE(VIA_REG_INTERRUPT, status |
dev_priv->irq_pending_mask);
diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig
index f20b8bcbef3..30ad13344f7 100644
--- a/drivers/gpu/drm/vmwgfx/Kconfig
+++ b/drivers/gpu/drm/vmwgfx/Kconfig
@@ -1,6 +1,6 @@
config DRM_VMWGFX
tristate "DRM driver for VMware Virtual GPU"
- depends on DRM && PCI
+ depends on DRM && PCI && FB
select FB_DEFERRED_IO
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 8827814d073..441e38c95a8 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -20,6 +20,7 @@
#include <linux/spinlock.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index 2370aefc86b..c31e0be8cce 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index df474c699fb..3a2b223c1da 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -20,6 +20,7 @@
#include <linux/input.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "hid-ids.h"
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index 78286b184ac..bba05d0a898 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -19,6 +19,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "hid-ids.h"
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 368fbb0c4ca..2e2aa759d23 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1357,6 +1357,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
+ { 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_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index cd4ece6fdfb..56f314fbd4f 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -29,6 +29,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/poll.h>
@@ -564,10 +565,10 @@ void hid_debug_event(struct hid_device *hdev, char *buf)
struct hid_debug_list *list;
list_for_each_entry(list, &hdev->debug_list, node) {
- for (i = 0; i <= strlen(buf); i++)
- list->hid_debug_buf[(list->tail + i) % (HID_DEBUG_BUFSIZE - 1)] =
+ for (i = 0; i < strlen(buf); i++)
+ list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] =
buf[i];
- list->tail = (list->tail + i) % (HID_DEBUG_BUFSIZE - 1);
+ list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE;
}
}
EXPORT_SYMBOL_GPL(hid_debug_event);
diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c
index a239d20ad7a..968b04f9b79 100644
--- a/drivers/hid/hid-drff.c
+++ b/drivers/hid/hid-drff.c
@@ -28,6 +28,7 @@
*/
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/hid.h>
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
index 8a11ccddaf2..88dfcf49a5d 100644
--- a/drivers/hid/hid-gaff.c
+++ b/drivers/hid/hid-gaff.c
@@ -28,6 +28,7 @@
*/
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/hid.h>
#include "hid-ids.h"
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index cab13e8c7d2..62416e6baec 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -53,10 +53,13 @@ static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi,
static int gyration_event(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
- struct input_dev *input = field->hidinput->input;
+
+ if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput)
+ return 0;
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK &&
(usage->hid & 0xff) == 0x82) {
+ struct input_dev *input = field->hidinput->input;
input_event(input, usage->type, usage->code, 1);
input_sync(input);
input_event(input, usage->type, usage->code, 0);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 72c05f90553..797e0647035 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -445,6 +445,7 @@
#define USB_VENDOR_ID_UCLOGIC 0x5543
#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
#define USB_VENDOR_ID_VERNIER 0x08f7
#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 79d9edd0bdf..7a0d2e4661a 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -68,22 +68,25 @@ static const struct {
#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
&max, EV_KEY, (c))
-static inline int match_scancode(int code, int scancode)
+static inline int match_scancode(unsigned int code, unsigned int scancode)
{
if (scancode == 0)
return 1;
- return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode);
+
+ return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
}
-static inline int match_keycode(int code, int keycode)
+static inline int match_keycode(unsigned int code, unsigned int keycode)
{
if (keycode == 0)
return 1;
- return (code == keycode);
+
+ return code == keycode;
}
static struct hid_usage *hidinput_find_key(struct hid_device *hid,
- int scancode, int keycode)
+ unsigned int scancode,
+ unsigned int keycode)
{
int i, j, k;
struct hid_report *report;
@@ -105,8 +108,8 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid,
return NULL;
}
-static int hidinput_getkeycode(struct input_dev *dev, int scancode,
- int *keycode)
+static int hidinput_getkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode)
{
struct hid_device *hid = input_get_drvdata(dev);
struct hid_usage *usage;
@@ -119,16 +122,13 @@ static int hidinput_getkeycode(struct input_dev *dev, int scancode,
return -EINVAL;
}
-static int hidinput_setkeycode(struct input_dev *dev, int scancode,
- int keycode)
+static int hidinput_setkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode)
{
struct hid_device *hid = input_get_drvdata(dev);
struct hid_usage *usage;
int old_keycode;
- if (keycode < 0 || keycode > KEY_MAX)
- return -EINVAL;
-
usage = hidinput_find_key(hid, scancode, 0);
if (usage) {
old_keycode = usage->code;
diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c
index 4e6dc6e2652..d888f1e6794 100644
--- a/drivers/hid/hid-lg2ff.c
+++ b/drivers/hid/hid-lg2ff.c
@@ -22,6 +22,7 @@
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/hid.h>
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 4a3a94f2b10..0d471fc2ab8 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -14,6 +14,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "hid-ids.h"
@@ -353,7 +354,7 @@ static int magicmouse_probe(struct hid_device *hdev,
goto err_free;
}
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT);
if (ret) {
dev_err(&hdev->dev, "magicmouse hw start failed\n");
goto err_free;
@@ -409,8 +410,11 @@ err_free:
static void magicmouse_remove(struct hid_device *hdev)
{
+ struct magicmouse_sc *msc = hid_get_drvdata(hdev);
+
hid_hw_stop(hdev);
- kfree(hid_get_drvdata(hdev));
+ input_unregister_device(msc->input);
+ kfree(msc);
}
static const struct hid_device_id magic_mice[] = {
diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c
index c8718168fe4..e91437c1890 100644
--- a/drivers/hid/hid-mosart.c
+++ b/drivers/hid/hid-mosart.c
@@ -16,6 +16,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "usbhid/usbhid.h"
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index 3234c729a89..9b24fc51071 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -16,6 +16,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "hid-ids.h"
@@ -140,6 +141,9 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
nd->reading_mt = 1;
nd->first_contact_confidence = 0;
break;
+ case HID_DG_TIPSWITCH:
+ /* Prevent emission of touch until validated */
+ return 1;
case HID_DG_CONFIDENCE:
nd->confidence = value;
break;
@@ -259,6 +263,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
BTN_TOOL_TRIPLETAP, 0);
input_report_key(input,
BTN_TOOL_QUADTAP, 0);
+ input_report_key(input, BTN_TOUCH, 0);
}
break;
@@ -308,13 +313,20 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
list_for_each_entry(hidinput, &hdev->inputs, list) {
+ if (hidinput->report->maxfield < 1)
+ continue;
+
input = hidinput->input;
switch (hidinput->report->field[0]->application) {
case HID_DG_PEN:
input->name = "N-Trig Pen";
break;
case HID_DG_TOUCHSCREEN:
+ /* These keys are redundant for fingers, clear them
+ * to prevent incorrect identification */
__clear_bit(BTN_TOOL_PEN, input->keybit);
+ __clear_bit(BTN_TOOL_FINGER, input->keybit);
+ __clear_bit(BTN_0, input->keybit);
/*
* A little something special to enable
* two and three finger taps.
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index c6d7dbc935b..9f41e2bd848 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -39,6 +39,7 @@
#define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/hid.h>
diff --git a/drivers/hid/hid-quanta.c b/drivers/hid/hid-quanta.c
index 01dd51c4986..54d3db50605 100644
--- a/drivers/hid/hid-quanta.c
+++ b/drivers/hid/hid-quanta.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
MODULE_DESCRIPTION("Quanta dual-touch panel");
diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c
index 203c438b016..e10a7687ebf 100644
--- a/drivers/hid/hid-sjoy.c
+++ b/drivers/hid/hid-sjoy.c
@@ -27,6 +27,7 @@
/* #define DEBUG */
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/hid.h>
#include "hid-ids.h"
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 9bf00d77d92..7502a4b2fa8 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -19,6 +19,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "hid-ids.h"
diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c
index 2e592a06654..90df886c5e0 100644
--- a/drivers/hid/hid-stantum.c
+++ b/drivers/hid/hid-stantum.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
MODULE_DESCRIPTION("Stantum HID multitouch panels");
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 167ea746fb9..15434c81479 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -29,6 +29,7 @@
#include <linux/hid.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "hid-ids.h"
@@ -251,6 +252,8 @@ static const struct hid_device_id tm_devices[] = {
.driver_data = (unsigned long)ff_rumble },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */
.driver_data = (unsigned long)ff_rumble },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653), /* RGT Force Feedback CLUTCH Raging Wheel */
+ .driver_data = (unsigned long)ff_joystick },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */
.driver_data = (unsigned long)ff_joystick },
{ }
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index 8d3b46f5d14..f7700cf4972 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -21,6 +21,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "hid-ids.h"
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index a79f0d78c6b..b7acceabba8 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -23,6 +23,7 @@
#include <linux/hid.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "hid-ids.h"
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index d04476700b7..6eadf1a9b3c 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -28,6 +28,7 @@
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/major.h>
+#include <linux/slab.h>
#include <linux/hid.h>
#include <linux/mutex.h>
#include <linux/sched.h>
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index e565dbe91d9..ef381d79cfa 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -25,6 +25,7 @@
#define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg)
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/hid.h>
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 7844280897d..1152f9b5fd4 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -16,6 +16,7 @@
*/
#include <linux/hid.h>
+#include <linux/slab.h>
#include "../hid-ids.h"
@@ -60,9 +61,11 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 68cf87749a4..9be8e1754a0 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -170,6 +170,16 @@ config SENSORS_ADM9240
This driver can also be built as a module. If so, the module
will be called adm9240.
+config SENSORS_ADT7411
+ tristate "Analog Devices ADT7411"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for the Analog Devices
+ ADT7411 voltage and temperature monitoring chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called adt7411.
+
config SENSORS_ADT7462
tristate "Analog Devices ADT7462"
depends on I2C && EXPERIMENTAL
@@ -190,20 +200,6 @@ config SENSORS_ADT7470
This driver can also be built as a module. If so, the module
will be called adt7470.
-config SENSORS_ADT7473
- tristate "Analog Devices ADT7473 (DEPRECATED)"
- depends on I2C && EXPERIMENTAL
- select SENSORS_ADT7475
- help
- If you say yes here you get support for the Analog Devices
- ADT7473 temperature monitoring chips.
-
- This driver is deprecated, you should use the adt7475 driver
- instead.
-
- This driver can also be built as a module. If so, the module
- will be called adt7473.
-
config SENSORS_ADT7475
tristate "Analog Devices ADT7473, ADT7475, ADT7476 and ADT7490"
depends on I2C && EXPERIMENTAL
@@ -216,6 +212,19 @@ config SENSORS_ADT7475
This driver can also be build as a module. If so, the module
will be called adt7475.
+config SENSORS_ASC7621
+ tristate "Andigilog aSC7621"
+ depends on HWMON && I2C
+ help
+ If you say yes here you get support for the aSC7621
+ family of SMBus sensors chip found on most Intel X38, X48, X58,
+ 945, 965 and 975 desktop boards. Currently supported chips:
+ aSC7621
+ aSC7621a
+
+ This driver can also be built as a module. If so, the module
+ will be called asc7621.
+
config SENSORS_K8TEMP
tristate "AMD Athlon64/FX or Opteron temperature sensor"
depends on X86 && PCI && EXPERIMENTAL
@@ -563,9 +572,10 @@ config SENSORS_LM90
depends on I2C
help
If you say yes here you get support for National Semiconductor LM90,
- LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim
+ LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, Maxim
MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659,
- MAX6680, MAX6681 and MAX6692 sensor chips.
+ MAX6680, MAX6681 and MAX6692, and Winbond/Nuvoton W83L771AWG/ASG
+ sensor chips.
This driver can also be built as a module. If so, the module
will be called lm90.
@@ -909,7 +919,8 @@ config SENSORS_W83793
select HWMON_VID
help
If you say yes here you get support for the Winbond W83793
- hardware monitoring chip.
+ hardware monitoring chip, including support for the integrated
+ watchdog.
This driver can also be built as a module. If so, the module
will be called w83793.
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 4bc215c0953..4aa1a3d112a 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -29,12 +29,13 @@ obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o
obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o
+obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o
obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o
obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o
-obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o
obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
obj-$(CONFIG_SENSORS_AMS) += ams/
+obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c
index bfda8c80ef2..1e4c21fc1a8 100644
--- a/drivers/hwmon/ad7414.c
+++ b/drivers/hwmon/ad7414.c
@@ -27,6 +27,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
+#include <linux/slab.h>
/* AD7414 registers */
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c
index f97b5b35687..ffc781fec18 100644
--- a/drivers/hwmon/ad7418.c
+++ b/drivers/hwmon/ad7418.c
@@ -20,6 +20,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "lm75.h"
diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c
index 5e9e095f113..fbdc7655303 100644
--- a/drivers/hwmon/adcxx.c
+++ b/drivers/hwmon/adcxx.c
@@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/sysfs.h>
@@ -62,18 +63,23 @@ static ssize_t adcxx_read(struct device *dev,
struct spi_device *spi = to_spi_device(dev);
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adcxx *adc = dev_get_drvdata(&spi->dev);
- u8 tx_buf[2] = { attr->index << 3 }; /* other bits are don't care */
+ u8 tx_buf[2];
u8 rx_buf[2];
int status;
- int value;
+ u32 value;
if (mutex_lock_interruptible(&adc->lock))
return -ERESTARTSYS;
- status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf),
- rx_buf, sizeof(rx_buf));
+ if (adc->channels == 1) {
+ status = spi_read(spi, rx_buf, sizeof(rx_buf));
+ } else {
+ tx_buf[0] = attr->index << 3; /* other bits are don't care */
+ status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf),
+ rx_buf, sizeof(rx_buf));
+ }
if (status < 0) {
- dev_warn(dev, "spi_write_then_read failed with status %d\n",
+ dev_warn(dev, "SPI synch. transfer failed with status %d\n",
status);
goto out;
}
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
new file mode 100644
index 00000000000..4086c7257f9
--- /dev/null
+++ b/drivers/hwmon/adt7411.c
@@ -0,0 +1,367 @@
+/*
+ * Driver for the ADT7411 (I2C/SPI 8 channel 10 bit ADC & temperature-sensor)
+ *
+ * Copyright (C) 2008, 2010 Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * TODO: SPI, support for external temperature sensor
+ * use power-down mode for suspend?, interrupt handling?
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
+
+#define ADT7411_REG_INT_TEMP_VDD_LSB 0x03
+#define ADT7411_REG_EXT_TEMP_AIN14_LSB 0x04
+#define ADT7411_REG_VDD_MSB 0x06
+#define ADT7411_REG_INT_TEMP_MSB 0x07
+#define ADT7411_REG_EXT_TEMP_AIN1_MSB 0x08
+
+#define ADT7411_REG_CFG1 0x18
+#define ADT7411_CFG1_START_MONITOR (1 << 0)
+
+#define ADT7411_REG_CFG2 0x19
+#define ADT7411_CFG2_DISABLE_AVG (1 << 5)
+
+#define ADT7411_REG_CFG3 0x1a
+#define ADT7411_CFG3_ADC_CLK_225 (1 << 0)
+#define ADT7411_CFG3_REF_VDD (1 << 4)
+
+#define ADT7411_REG_DEVICE_ID 0x4d
+#define ADT7411_REG_MANUFACTURER_ID 0x4e
+
+#define ADT7411_DEVICE_ID 0x2
+#define ADT7411_MANUFACTURER_ID 0x41
+
+static const unsigned short normal_i2c[] = { 0x48, 0x4a, 0x4b, I2C_CLIENT_END };
+
+struct adt7411_data {
+ struct mutex device_lock; /* for "atomic" device accesses */
+ struct mutex update_lock;
+ unsigned long next_update;
+ int vref_cached;
+ struct device *hwmon_dev;
+};
+
+/*
+ * When reading a register containing (up to 4) lsb, all associated
+ * msb-registers get locked by the hardware. After _one_ of those msb is read,
+ * _all_ are unlocked. In order to use this locking correctly, reading lsb/msb
+ * is protected here with a mutex, too.
+ */
+static int adt7411_read_10_bit(struct i2c_client *client, u8 lsb_reg,
+ u8 msb_reg, u8 lsb_shift)
+{
+ struct adt7411_data *data = i2c_get_clientdata(client);
+ int val, tmp;
+
+ mutex_lock(&data->device_lock);
+
+ val = i2c_smbus_read_byte_data(client, lsb_reg);
+ if (val < 0)
+ goto exit_unlock;
+
+ tmp = (val >> lsb_shift) & 3;
+ val = i2c_smbus_read_byte_data(client, msb_reg);
+
+ if (val >= 0)
+ val = (val << 2) | tmp;
+
+ exit_unlock:
+ mutex_unlock(&data->device_lock);
+
+ return val;
+}
+
+static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit,
+ bool flag)
+{
+ struct adt7411_data *data = i2c_get_clientdata(client);
+ int ret, val;
+
+ mutex_lock(&data->device_lock);
+
+ ret = i2c_smbus_read_byte_data(client, reg);
+ if (ret < 0)
+ goto exit_unlock;
+
+ if (flag)
+ val = ret | bit;
+ else
+ val = ret & ~bit;
+
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+
+ exit_unlock:
+ mutex_unlock(&data->device_lock);
+ return ret;
+}
+
+static ssize_t adt7411_show_vdd(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
+ ADT7411_REG_VDD_MSB, 2);
+
+ return ret < 0 ? ret : sprintf(buf, "%u\n", ret * 7000 / 1024);
+}
+
+static ssize_t adt7411_show_temp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
+ ADT7411_REG_INT_TEMP_MSB, 0);
+
+ if (val < 0)
+ return val;
+
+ val = val & 0x200 ? val - 0x400 : val; /* 10 bit signed */
+
+ return sprintf(buf, "%d\n", val * 250);
+}
+
+static ssize_t adt7411_show_input(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int nr = to_sensor_dev_attr(attr)->index;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7411_data *data = i2c_get_clientdata(client);
+ int val;
+ u8 lsb_reg, lsb_shift;
+
+ mutex_lock(&data->update_lock);
+ if (time_after_eq(jiffies, data->next_update)) {
+ val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3);
+ if (val < 0)
+ goto exit_unlock;
+
+ if (val & ADT7411_CFG3_REF_VDD) {
+ val = adt7411_read_10_bit(client,
+ ADT7411_REG_INT_TEMP_VDD_LSB,
+ ADT7411_REG_VDD_MSB, 2);
+ if (val < 0)
+ goto exit_unlock;
+
+ data->vref_cached = val * 7000 / 1024;
+ } else {
+ data->vref_cached = 2250;
+ }
+
+ data->next_update = jiffies + HZ;
+ }
+
+ lsb_reg = ADT7411_REG_EXT_TEMP_AIN14_LSB + (nr >> 2);
+ lsb_shift = 2 * (nr & 0x03);
+ val = adt7411_read_10_bit(client, lsb_reg,
+ ADT7411_REG_EXT_TEMP_AIN1_MSB + nr, lsb_shift);
+ if (val < 0)
+ goto exit_unlock;
+
+ val = sprintf(buf, "%u\n", val * data->vref_cached / 1024);
+ exit_unlock:
+ mutex_unlock(&data->update_lock);
+ return val;
+}
+
+static ssize_t adt7411_show_bit(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ int ret = i2c_smbus_read_byte_data(client, attr2->index);
+
+ return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr));
+}
+
+static ssize_t adt7411_set_bit(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct adt7411_data *data = i2c_get_clientdata(client);
+ int ret;
+ unsigned long flag;
+
+ ret = strict_strtoul(buf, 0, &flag);
+ if (ret || flag > 1)
+ return -EINVAL;
+
+ ret = adt7411_modify_bit(client, s_attr2->index, s_attr2->nr, flag);
+
+ /* force update */
+ mutex_lock(&data->update_lock);
+ data->next_update = jiffies;
+ mutex_unlock(&data->update_lock);
+
+ return ret < 0 ? ret : count;
+}
+
+#define ADT7411_BIT_ATTR(__name, __reg, __bit) \
+ SENSOR_DEVICE_ATTR_2(__name, S_IRUGO | S_IWUSR, adt7411_show_bit, \
+ adt7411_set_bit, __bit, __reg)
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, adt7411_show_temp, NULL);
+static DEVICE_ATTR(in0_input, S_IRUGO, adt7411_show_vdd, NULL);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, adt7411_show_input, NULL, 0);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, adt7411_show_input, NULL, 1);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, adt7411_show_input, NULL, 2);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, adt7411_show_input, NULL, 3);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, adt7411_show_input, NULL, 4);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, adt7411_show_input, NULL, 5);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, adt7411_show_input, NULL, 6);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, adt7411_show_input, NULL, 7);
+static ADT7411_BIT_ATTR(no_average, ADT7411_REG_CFG2, ADT7411_CFG2_DISABLE_AVG);
+static ADT7411_BIT_ATTR(fast_sampling, ADT7411_REG_CFG3, ADT7411_CFG3_ADC_CLK_225);
+static ADT7411_BIT_ATTR(adc_ref_vdd, ADT7411_REG_CFG3, ADT7411_CFG3_REF_VDD);
+
+static struct attribute *adt7411_attrs[] = {
+ &dev_attr_temp1_input.attr,
+ &dev_attr_in0_input.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_in2_input.dev_attr.attr,
+ &sensor_dev_attr_in3_input.dev_attr.attr,
+ &sensor_dev_attr_in4_input.dev_attr.attr,
+ &sensor_dev_attr_in5_input.dev_attr.attr,
+ &sensor_dev_attr_in6_input.dev_attr.attr,
+ &sensor_dev_attr_in7_input.dev_attr.attr,
+ &sensor_dev_attr_in8_input.dev_attr.attr,
+ &sensor_dev_attr_no_average.dev_attr.attr,
+ &sensor_dev_attr_fast_sampling.dev_attr.attr,
+ &sensor_dev_attr_adc_ref_vdd.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group adt7411_attr_grp = {
+ .attrs = adt7411_attrs,
+};
+
+static int adt7411_detect(struct i2c_client *client,
+ struct i2c_board_info *info)
+{
+ int val;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID);
+ if (val < 0 || val != ADT7411_MANUFACTURER_ID) {
+ dev_dbg(&client->dev, "Wrong manufacturer ID. Got %d, "
+ "expected %d\n", val, ADT7411_MANUFACTURER_ID);
+ return -ENODEV;
+ }
+
+ val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID);
+ if (val < 0 || val != ADT7411_DEVICE_ID) {
+ dev_dbg(&client->dev, "Wrong device ID. Got %d, "
+ "expected %d\n", val, ADT7411_DEVICE_ID);
+ return -ENODEV;
+ }
+
+ strlcpy(info->type, "adt7411", I2C_NAME_SIZE);
+
+ return 0;
+}
+
+static int __devinit adt7411_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct adt7411_data *data;
+ int ret;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->device_lock);
+ mutex_init(&data->update_lock);
+
+ ret = adt7411_modify_bit(client, ADT7411_REG_CFG1,
+ ADT7411_CFG1_START_MONITOR, 1);
+ if (ret < 0)
+ goto exit_free;
+
+ /* force update on first occasion */
+ data->next_update = jiffies;
+
+ ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp);
+ if (ret)
+ goto exit_free;
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ ret = PTR_ERR(data->hwmon_dev);
+ goto exit_remove;
+ }
+
+ dev_info(&client->dev, "successfully registered\n");
+
+ return 0;
+
+ exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
+ exit_free:
+ i2c_set_clientdata(client, NULL);
+ kfree(data);
+ return ret;
+}
+
+static int __devexit adt7411_remove(struct i2c_client *client)
+{
+ struct adt7411_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
+ i2c_set_clientdata(client, NULL);
+ kfree(data);
+ return 0;
+}
+
+static const struct i2c_device_id adt7411_id[] = {
+ { "adt7411", 0 },
+ { }
+};
+
+static struct i2c_driver adt7411_driver = {
+ .driver = {
+ .name = "adt7411",
+ },
+ .probe = adt7411_probe,
+ .remove = __devexit_p(adt7411_remove),
+ .id_table = adt7411_id,
+ .detect = adt7411_detect,
+ .address_list = normal_i2c,
+ .class = I2C_CLASS_HWMON,
+};
+
+static int __init sensors_adt7411_init(void)
+{
+ return i2c_add_driver(&adt7411_driver);
+}
+module_init(sensors_adt7411_init)
+
+static void __exit sensors_adt7411_exit(void)
+{
+ i2c_del_driver(&adt7411_driver);
+}
+module_exit(sensors_adt7411_exit)
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de> and "
+ "Wolfram Sang <w.sang@pengutronix.de>");
+MODULE_DESCRIPTION("ADT7411 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
index b8156b4893b..2af0c7b6b4e 100644
--- a/drivers/hwmon/adt7462.c
+++ b/drivers/hwmon/adt7462.c
@@ -28,6 +28,7 @@
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/log2.h>
+#include <linux/slab.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 3445ce1cba8..9e775717abb 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -29,6 +29,7 @@
#include <linux/delay.h>
#include <linux/log2.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c
deleted file mode 100644
index 434576f61c8..00000000000
--- a/drivers/hwmon/adt7473.c
+++ /dev/null
@@ -1,1180 +0,0 @@
-/*
- * A hwmon driver for the Analog Devices ADT7473
- * Copyright (C) 2007 IBM
- *
- * Author: Darrick J. Wong <djwong@us.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.
- *
- * This program is distributed in 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/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/log2.h>
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END };
-
-/* ADT7473 registers */
-#define ADT7473_REG_BASE_ADDR 0x20
-
-#define ADT7473_REG_VOLT_BASE_ADDR 0x21
-#define ADT7473_REG_VOLT_MIN_BASE_ADDR 0x46
-
-#define ADT7473_REG_TEMP_BASE_ADDR 0x25
-#define ADT7473_REG_TEMP_LIMITS_BASE_ADDR 0x4E
-#define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67
-#define ADT7473_REG_TEMP_TMAX_BASE_ADDR 0x6A
-
-#define ADT7473_REG_FAN_BASE_ADDR 0x28
-#define ADT7473_REG_FAN_MIN_BASE_ADDR 0x54
-
-#define ADT7473_REG_PWM_BASE_ADDR 0x30
-#define ADT7473_REG_PWM_MIN_BASE_ADDR 0x64
-#define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38
-#define ADT7473_REG_PWM_BHVR_BASE_ADDR 0x5C
-#define ADT7473_PWM_BHVR_MASK 0xE0
-#define ADT7473_PWM_BHVR_SHIFT 5
-
-#define ADT7473_REG_CFG1 0x40
-#define ADT7473_CFG1_START 0x01
-#define ADT7473_CFG1_READY 0x04
-#define ADT7473_REG_CFG2 0x73
-#define ADT7473_REG_CFG3 0x78
-#define ADT7473_REG_CFG4 0x7D
-#define ADT7473_CFG4_MAX_DUTY_AT_OVT 0x08
-#define ADT7473_REG_CFG5 0x7C
-#define ADT7473_CFG5_TEMP_TWOS 0x01
-#define ADT7473_CFG5_TEMP_OFFSET 0x02
-
-#define ADT7473_REG_DEVICE 0x3D
-#define ADT7473_VENDOR 0x41
-#define ADT7473_REG_VENDOR 0x3E
-#define ADT7473_DEVICE 0x73
-#define ADT7473_REG_REVISION 0x3F
-#define ADT7473_REV_68 0x68
-#define ADT7473_REV_69 0x69
-
-#define ADT7473_REG_ALARM1 0x41
-#define ADT7473_VCCP_ALARM 0x02
-#define ADT7473_VCC_ALARM 0x04
-#define ADT7473_R1T_ALARM 0x10
-#define ADT7473_LT_ALARM 0x20
-#define ADT7473_R2T_ALARM 0x40
-#define ADT7473_OOL 0x80
-#define ADT7473_REG_ALARM2 0x42
-#define ADT7473_OVT_ALARM 0x02
-#define ADT7473_FAN1_ALARM 0x04
-#define ADT7473_FAN2_ALARM 0x08
-#define ADT7473_FAN3_ALARM 0x10
-#define ADT7473_FAN4_ALARM 0x20
-#define ADT7473_R1T_SHORT 0x40
-#define ADT7473_R2T_SHORT 0x80
-
-#define ALARM2(x) ((x) << 8)
-
-#define ADT7473_VOLT_COUNT 2
-#define ADT7473_REG_VOLT(x) (ADT7473_REG_VOLT_BASE_ADDR + (x))
-#define ADT7473_REG_VOLT_MIN(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + ((x) * 2))
-#define ADT7473_REG_VOLT_MAX(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + \
- ((x) * 2) + 1)
-
-#define ADT7473_TEMP_COUNT 3
-#define ADT7473_REG_TEMP(x) (ADT7473_REG_TEMP_BASE_ADDR + (x))
-#define ADT7473_REG_TEMP_MIN(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + ((x) * 2))
-#define ADT7473_REG_TEMP_MAX(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + \
- ((x) * 2) + 1)
-#define ADT7473_REG_TEMP_TMIN(x) (ADT7473_REG_TEMP_TMIN_BASE_ADDR + (x))
-#define ADT7473_REG_TEMP_TMAX(x) (ADT7473_REG_TEMP_TMAX_BASE_ADDR + (x))
-
-#define ADT7473_FAN_COUNT 4
-#define ADT7473_REG_FAN(x) (ADT7473_REG_FAN_BASE_ADDR + ((x) * 2))
-#define ADT7473_REG_FAN_MIN(x) (ADT7473_REG_FAN_MIN_BASE_ADDR + ((x) * 2))
-
-#define ADT7473_PWM_COUNT 3
-#define ADT7473_REG_PWM(x) (ADT7473_REG_PWM_BASE_ADDR + (x))
-#define ADT7473_REG_PWM_MAX(x) (ADT7473_REG_PWM_MAX_BASE_ADDR + (x))
-#define ADT7473_REG_PWM_MIN(x) (ADT7473_REG_PWM_MIN_BASE_ADDR + (x))
-#define ADT7473_REG_PWM_BHVR(x) (ADT7473_REG_PWM_BHVR_BASE_ADDR + (x))
-
-/* How often do we reread sensors values? (In jiffies) */
-#define SENSOR_REFRESH_INTERVAL (2 * HZ)
-
-/* How often do we reread sensor limit values? (In jiffies) */
-#define LIMIT_REFRESH_INTERVAL (60 * HZ)
-
-/* datasheet says to divide this number by the fan reading to get fan rpm */
-#define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x))
-#define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM
-#define FAN_PERIOD_INVALID 65535
-#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID)
-
-struct adt7473_data {
- struct device *hwmon_dev;
- struct attribute_group attrs;
- struct mutex lock;
- char sensors_valid;
- char limits_valid;
- unsigned long sensors_last_updated; /* In jiffies */
- unsigned long limits_last_updated; /* In jiffies */
-
- u8 volt[ADT7473_VOLT_COUNT];
- s8 volt_min[ADT7473_VOLT_COUNT];
- s8 volt_max[ADT7473_VOLT_COUNT];
-
- s8 temp[ADT7473_TEMP_COUNT];
- s8 temp_min[ADT7473_TEMP_COUNT];
- s8 temp_max[ADT7473_TEMP_COUNT];
- s8 temp_tmin[ADT7473_TEMP_COUNT];
- /* This is called the !THERM limit in the datasheet */
- s8 temp_tmax[ADT7473_TEMP_COUNT];
-
- u16 fan[ADT7473_FAN_COUNT];
- u16 fan_min[ADT7473_FAN_COUNT];
-
- u8 pwm[ADT7473_PWM_COUNT];
- u8 pwm_max[ADT7473_PWM_COUNT];
- u8 pwm_min[ADT7473_PWM_COUNT];
- u8 pwm_behavior[ADT7473_PWM_COUNT];
-
- u8 temp_twos_complement;
- u8 temp_offset;
-
- u16 alarm;
- u8 max_duty_at_overheat;
-};
-
-static int adt7473_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adt7473_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int adt7473_remove(struct i2c_client *client);
-
-static const struct i2c_device_id adt7473_id[] = {
- { "adt7473", 0 },
- { }
-};
-
-static struct i2c_driver adt7473_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adt7473",
- },
- .probe = adt7473_probe,
- .remove = adt7473_remove,
- .id_table = adt7473_id,
- .detect = adt7473_detect,
- .address_list = normal_i2c,
-};
-
-/*
- * 16-bit registers on the ADT7473 are low-byte first. The data sheet says
- * that the low byte must be read before the high byte.
- */
-static inline int adt7473_read_word_data(struct i2c_client *client, u8 reg)
-{
- u16 foo;
- foo = i2c_smbus_read_byte_data(client, reg);
- foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8);
- return foo;
-}
-
-static inline int adt7473_write_word_data(struct i2c_client *client, u8 reg,
- u16 value)
-{
- return i2c_smbus_write_byte_data(client, reg, value & 0xFF)
- && i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
-}
-
-static void adt7473_init_client(struct i2c_client *client)
-{
- int reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG1);
-
- if (!(reg & ADT7473_CFG1_READY)) {
- dev_err(&client->dev, "Chip not ready.\n");
- } else {
- /* start monitoring */
- i2c_smbus_write_byte_data(client, ADT7473_REG_CFG1,
- reg | ADT7473_CFG1_START);
- }
-}
-
-static struct adt7473_data *adt7473_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- unsigned long local_jiffies = jiffies;
- u8 cfg;
- int i;
-
- mutex_lock(&data->lock);
- if (time_before(local_jiffies, data->sensors_last_updated +
- SENSOR_REFRESH_INTERVAL)
- && data->sensors_valid)
- goto no_sensor_update;
-
- for (i = 0; i < ADT7473_VOLT_COUNT; i++)
- data->volt[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_VOLT(i));
-
- /* Determine temperature encoding */
- cfg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG5);
- data->temp_twos_complement = (cfg & ADT7473_CFG5_TEMP_TWOS);
-
- /*
- * What does this do? it implies a variable temperature sensor
- * offset, but the datasheet doesn't say anything about this bit
- * and other parts of the datasheet imply that "offset64" mode
- * means that you shift temp values by -64 if the above bit was set.
- */
- data->temp_offset = (cfg & ADT7473_CFG5_TEMP_OFFSET);
-
- for (i = 0; i < ADT7473_TEMP_COUNT; i++)
- data->temp[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_TEMP(i));
-
- for (i = 0; i < ADT7473_FAN_COUNT; i++)
- data->fan[i] = adt7473_read_word_data(client,
- ADT7473_REG_FAN(i));
-
- for (i = 0; i < ADT7473_PWM_COUNT; i++)
- data->pwm[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_PWM(i));
-
- data->alarm = i2c_smbus_read_byte_data(client, ADT7473_REG_ALARM1);
- if (data->alarm & ADT7473_OOL)
- data->alarm |= ALARM2(i2c_smbus_read_byte_data(client,
- ADT7473_REG_ALARM2));
-
- data->sensors_last_updated = local_jiffies;
- data->sensors_valid = 1;
-
-no_sensor_update:
- if (time_before(local_jiffies, data->limits_last_updated +
- LIMIT_REFRESH_INTERVAL)
- && data->limits_valid)
- goto out;
-
- for (i = 0; i < ADT7473_VOLT_COUNT; i++) {
- data->volt_min[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_VOLT_MIN(i));
- data->volt_max[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_VOLT_MAX(i));
- }
-
- for (i = 0; i < ADT7473_TEMP_COUNT; i++) {
- data->temp_min[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_TEMP_MIN(i));
- data->temp_max[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_TEMP_MAX(i));
- data->temp_tmin[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_TEMP_TMIN(i));
- data->temp_tmax[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_TEMP_TMAX(i));
- }
-
- for (i = 0; i < ADT7473_FAN_COUNT; i++)
- data->fan_min[i] = adt7473_read_word_data(client,
- ADT7473_REG_FAN_MIN(i));
-
- for (i = 0; i < ADT7473_PWM_COUNT; i++) {
- data->pwm_max[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_PWM_MAX(i));
- data->pwm_min[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_PWM_MIN(i));
- data->pwm_behavior[i] = i2c_smbus_read_byte_data(client,
- ADT7473_REG_PWM_BHVR(i));
- }
-
- i = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
- data->max_duty_at_overheat = !!(i & ADT7473_CFG4_MAX_DUTY_AT_OVT);
-
- data->limits_last_updated = local_jiffies;
- data->limits_valid = 1;
-
-out:
- mutex_unlock(&data->lock);
- return data;
-}
-
-/*
- * Conversions
- */
-
-/* IN are scaled acording to built-in resistors */
-static const int adt7473_scaling[] = { /* .001 Volts */
- 2250, 3300
-};
-#define SCALE(val, from, to) (((val) * (to) + ((from) / 2)) / (from))
-
-static int decode_volt(int volt_index, u8 raw)
-{
- return SCALE(raw, 192, adt7473_scaling[volt_index]);
-}
-
-static u8 encode_volt(int volt_index, int cooked)
-{
- int raw = SCALE(cooked, adt7473_scaling[volt_index], 192);
- return SENSORS_LIMIT(raw, 0, 255);
-}
-
-static ssize_t show_volt_min(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n",
- decode_volt(attr->index, data->volt_min[attr->index]));
-}
-
-static ssize_t set_volt_min(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long volt;
-
- if (strict_strtol(buf, 10, &volt))
- return -EINVAL;
-
- volt = encode_volt(attr->index, volt);
-
- mutex_lock(&data->lock);
- data->volt_min[attr->index] = volt;
- i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MIN(attr->index),
- volt);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_volt_max(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n",
- decode_volt(attr->index, data->volt_max[attr->index]));
-}
-
-static ssize_t set_volt_max(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long volt;
-
- if (strict_strtol(buf, 10, &volt))
- return -EINVAL;
-
- volt = encode_volt(attr->index, volt);
-
- mutex_lock(&data->lock);
- data->volt_max[attr->index] = volt;
- i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MAX(attr->index),
- volt);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_volt(struct device *dev, struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
-
- return sprintf(buf, "%d\n",
- decode_volt(attr->index, data->volt[attr->index]));
-}
-
-/*
- * This chip can report temperature data either as a two's complement
- * number in the range -128 to 127, or as an unsigned number that must
- * be offset by 64.
- */
-static int decode_temp(u8 twos_complement, u8 raw)
-{
- return twos_complement ? (s8)raw : raw - 64;
-}
-
-static u8 encode_temp(u8 twos_complement, int cooked)
-{
- u8 ret = twos_complement ? cooked & 0xFF : cooked + 64;
- return SENSORS_LIMIT(ret, 0, 255);
-}
-
-static ssize_t show_temp_min(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", 1000 * decode_temp(
- data->temp_twos_complement,
- data->temp_min[attr->index]));
-}
-
-static ssize_t set_temp_min(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- temp = DIV_ROUND_CLOSEST(temp, 1000);
- temp = encode_temp(data->temp_twos_complement, temp);
-
- mutex_lock(&data->lock);
- data->temp_min[attr->index] = temp;
- i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MIN(attr->index),
- temp);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_temp_max(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", 1000 * decode_temp(
- data->temp_twos_complement,
- data->temp_max[attr->index]));
-}
-
-static ssize_t set_temp_max(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- temp = DIV_ROUND_CLOSEST(temp, 1000);
- temp = encode_temp(data->temp_twos_complement, temp);
-
- mutex_lock(&data->lock);
- data->temp_max[attr->index] = temp;
- i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MAX(attr->index),
- temp);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", 1000 * decode_temp(
- data->temp_twos_complement,
- data->temp[attr->index]));
-}
-
-static ssize_t show_fan_min(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
-
- if (FAN_DATA_VALID(data->fan_min[attr->index]))
- return sprintf(buf, "%d\n",
- FAN_PERIOD_TO_RPM(data->fan_min[attr->index]));
- else
- return sprintf(buf, "0\n");
-}
-
-static ssize_t set_fan_min(struct device *dev,
- struct device_attribute *devattr,
- const char *buf, size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp) || !temp)
- return -EINVAL;
-
- temp = FAN_RPM_TO_PERIOD(temp);
- temp = SENSORS_LIMIT(temp, 1, 65534);
-
- mutex_lock(&data->lock);
- data->fan_min[attr->index] = temp;
- adt7473_write_word_data(client, ADT7473_REG_FAN_MIN(attr->index), temp);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
-
- if (FAN_DATA_VALID(data->fan[attr->index]))
- return sprintf(buf, "%d\n",
- FAN_PERIOD_TO_RPM(data->fan[attr->index]));
- else
- return sprintf(buf, "0\n");
-}
-
-static ssize_t show_max_duty_at_crit(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", data->max_duty_at_overheat);
-}
-
-static ssize_t set_max_duty_at_crit(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- u8 reg;
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- mutex_lock(&data->lock);
- data->max_duty_at_overheat = !!temp;
- reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
- if (temp)
- reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT;
- else
- reg &= ~ADT7473_CFG4_MAX_DUTY_AT_OVT;
- i2c_smbus_write_byte_data(client, ADT7473_REG_CFG4, reg);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", data->pwm[attr->index]);
-}
-
-static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
- const char *buf, size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- temp = SENSORS_LIMIT(temp, 0, 255);
-
- mutex_lock(&data->lock);
- data->pwm[attr->index] = temp;
- i2c_smbus_write_byte_data(client, ADT7473_REG_PWM(attr->index), temp);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_pwm_max(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", data->pwm_max[attr->index]);
-}
-
-static ssize_t set_pwm_max(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- temp = SENSORS_LIMIT(temp, 0, 255);
-
- mutex_lock(&data->lock);
- data->pwm_max[attr->index] = temp;
- i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MAX(attr->index),
- temp);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_pwm_min(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", data->pwm_min[attr->index]);
-}
-
-static ssize_t set_pwm_min(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- temp = SENSORS_LIMIT(temp, 0, 255);
-
- mutex_lock(&data->lock);
- data->pwm_min[attr->index] = temp;
- i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MIN(attr->index),
- temp);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_temp_tmax(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", 1000 * decode_temp(
- data->temp_twos_complement,
- data->temp_tmax[attr->index]));
-}
-
-static ssize_t set_temp_tmax(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- temp = DIV_ROUND_CLOSEST(temp, 1000);
- temp = encode_temp(data->temp_twos_complement, temp);
-
- mutex_lock(&data->lock);
- data->temp_tmax[attr->index] = temp;
- i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMAX(attr->index),
- temp);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_temp_tmin(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- return sprintf(buf, "%d\n", 1000 * decode_temp(
- data->temp_twos_complement,
- data->temp_tmin[attr->index]));
-}
-
-static ssize_t set_temp_tmin(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- temp = DIV_ROUND_CLOSEST(temp, 1000);
- temp = encode_temp(data->temp_twos_complement, temp);
-
- mutex_lock(&data->lock);
- data->temp_tmin[attr->index] = temp;
- i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMIN(attr->index),
- temp);
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_pwm_enable(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
-
- switch (data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT) {
- case 3:
- return sprintf(buf, "0\n");
- case 7:
- return sprintf(buf, "1\n");
- default:
- return sprintf(buf, "2\n");
- }
-}
-
-static ssize_t set_pwm_enable(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- u8 reg;
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- switch (temp) {
- case 0:
- temp = 3;
- break;
- case 1:
- temp = 7;
- break;
- case 2:
- /* Enter automatic mode with fans off */
- temp = 4;
- break;
- default:
- return -EINVAL;
- }
-
- mutex_lock(&data->lock);
- reg = i2c_smbus_read_byte_data(client,
- ADT7473_REG_PWM_BHVR(attr->index));
- reg = (temp << ADT7473_PWM_BHVR_SHIFT) |
- (reg & ~ADT7473_PWM_BHVR_MASK);
- i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index),
- reg);
- data->pwm_behavior[attr->index] = reg;
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_pwm_auto_temp(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
- int bhvr = data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT;
-
- switch (bhvr) {
- case 3:
- case 4:
- case 7:
- return sprintf(buf, "0\n");
- case 0:
- case 1:
- case 5:
- case 6:
- return sprintf(buf, "%d\n", bhvr + 1);
- case 2:
- return sprintf(buf, "4\n");
- }
- /* shouldn't ever get here */
- BUG();
-}
-
-static ssize_t set_pwm_auto_temp(struct device *dev,
- struct device_attribute *devattr,
- const char *buf,
- size_t count)
-{
- u8 reg;
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7473_data *data = i2c_get_clientdata(client);
- long temp;
-
- if (strict_strtol(buf, 10, &temp))
- return -EINVAL;
-
- switch (temp) {
- case 1:
- case 2:
- case 6:
- case 7:
- temp--;
- break;
- case 0:
- temp = 4;
- break;
- default:
- return -EINVAL;
- }
-
- mutex_lock(&data->lock);
- reg = i2c_smbus_read_byte_data(client,
- ADT7473_REG_PWM_BHVR(attr->index));
- reg = (temp << ADT7473_PWM_BHVR_SHIFT) |
- (reg & ~ADT7473_PWM_BHVR_MASK);
- i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index),
- reg);
- data->pwm_behavior[attr->index] = reg;
- mutex_unlock(&data->lock);
-
- return count;
-}
-
-static ssize_t show_alarm(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct adt7473_data *data = adt7473_update_device(dev);
-
- if (data->alarm & attr->index)
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-
-static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max,
- set_volt_max, 0);
-static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max,
- set_volt_max, 1);
-
-static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min,
- set_volt_min, 0);
-static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min,
- set_volt_min, 1);
-
-static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_volt, NULL, 0);
-static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_volt, NULL, 1);
-
-static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL,
- ADT7473_VCCP_ALARM);
-static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL,
- ADT7473_VCC_ALARM);
-
-static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
- set_temp_max, 0);
-static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
- set_temp_max, 1);
-static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max,
- set_temp_max, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min,
- set_temp_min, 0);
-static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min,
- set_temp_min, 1);
-static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min,
- set_temp_min, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
- ADT7473_R1T_ALARM | ALARM2(ADT7473_R1T_SHORT));
-static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
- ADT7473_LT_ALARM);
-static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
- ADT7473_R2T_ALARM | ALARM2(ADT7473_R2T_SHORT));
-
-static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
- set_fan_min, 0);
-static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
- set_fan_min, 1);
-static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
- set_fan_min, 2);
-static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
- set_fan_min, 3);
-
-static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
-static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
-static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
-static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
-
-static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL,
- ALARM2(ADT7473_FAN1_ALARM));
-static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL,
- ALARM2(ADT7473_FAN2_ALARM));
-static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL,
- ALARM2(ADT7473_FAN3_ALARM));
-static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL,
- ALARM2(ADT7473_FAN4_ALARM));
-
-static SENSOR_DEVICE_ATTR(pwm_use_point2_pwm_at_crit, S_IWUSR | S_IRUGO,
- show_max_duty_at_crit, set_max_duty_at_crit, 0);
-
-static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
-static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
-static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2);
-
-static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
- show_pwm_min, set_pwm_min, 0);
-static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
- show_pwm_min, set_pwm_min, 1);
-static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
- show_pwm_min, set_pwm_min, 2);
-
-static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
- show_pwm_max, set_pwm_max, 0);
-static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
- show_pwm_max, set_pwm_max, 1);
-static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
- show_pwm_max, set_pwm_max, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO,
- show_temp_tmin, set_temp_tmin, 0);
-static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO,
- show_temp_tmin, set_temp_tmin, 1);
-static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO,
- show_temp_tmin, set_temp_tmin, 2);
-
-static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO,
- show_temp_tmax, set_temp_tmax, 0);
-static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
- show_temp_tmax, set_temp_tmax, 1);
-static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO,
- show_temp_tmax, set_temp_tmax, 2);
-
-static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
- set_pwm_enable, 0);
-static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
- set_pwm_enable, 1);
-static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
- set_pwm_enable, 2);
-
-static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO,
- show_pwm_auto_temp, set_pwm_auto_temp, 0);
-static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO,
- show_pwm_auto_temp, set_pwm_auto_temp, 1);
-static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
- show_pwm_auto_temp, set_pwm_auto_temp, 2);
-
-static struct attribute *adt7473_attr[] =
-{
- &sensor_dev_attr_in1_max.dev_attr.attr,
- &sensor_dev_attr_in2_max.dev_attr.attr,
- &sensor_dev_attr_in1_min.dev_attr.attr,
- &sensor_dev_attr_in2_min.dev_attr.attr,
- &sensor_dev_attr_in1_input.dev_attr.attr,
- &sensor_dev_attr_in2_input.dev_attr.attr,
- &sensor_dev_attr_in1_alarm.dev_attr.attr,
- &sensor_dev_attr_in2_alarm.dev_attr.attr,
-
- &sensor_dev_attr_temp1_max.dev_attr.attr,
- &sensor_dev_attr_temp2_max.dev_attr.attr,
- &sensor_dev_attr_temp3_max.dev_attr.attr,
- &sensor_dev_attr_temp1_min.dev_attr.attr,
- &sensor_dev_attr_temp2_min.dev_attr.attr,
- &sensor_dev_attr_temp3_min.dev_attr.attr,
- &sensor_dev_attr_temp1_input.dev_attr.attr,
- &sensor_dev_attr_temp2_input.dev_attr.attr,
- &sensor_dev_attr_temp3_input.dev_attr.attr,
- &sensor_dev_attr_temp1_alarm.dev_attr.attr,
- &sensor_dev_attr_temp2_alarm.dev_attr.attr,
- &sensor_dev_attr_temp3_alarm.dev_attr.attr,
- &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
- &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
- &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr,
- &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
- &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
- &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
-
- &sensor_dev_attr_fan1_min.dev_attr.attr,
- &sensor_dev_attr_fan2_min.dev_attr.attr,
- &sensor_dev_attr_fan3_min.dev_attr.attr,
- &sensor_dev_attr_fan4_min.dev_attr.attr,
- &sensor_dev_attr_fan1_input.dev_attr.attr,
- &sensor_dev_attr_fan2_input.dev_attr.attr,
- &sensor_dev_attr_fan3_input.dev_attr.attr,
- &sensor_dev_attr_fan4_input.dev_attr.attr,
- &sensor_dev_attr_fan1_alarm.dev_attr.attr,
- &sensor_dev_attr_fan2_alarm.dev_attr.attr,
- &sensor_dev_attr_fan3_alarm.dev_attr.attr,
- &sensor_dev_attr_fan4_alarm.dev_attr.attr,
-
- &sensor_dev_attr_pwm_use_point2_pwm_at_crit.dev_attr.attr,
-
- &sensor_dev_attr_pwm1.dev_attr.attr,
- &sensor_dev_attr_pwm2.dev_attr.attr,
- &sensor_dev_attr_pwm3.dev_attr.attr,
- &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
- &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
- &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
- &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
- &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
- &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
-
- &sensor_dev_attr_pwm1_enable.dev_attr.attr,
- &sensor_dev_attr_pwm2_enable.dev_attr.attr,
- &sensor_dev_attr_pwm3_enable.dev_attr.attr,
- &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
- &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
- &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
-
- NULL
-};
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int adt7473_detect(struct i2c_client *client,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
- int vendor, device, revision;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
- if (vendor != ADT7473_VENDOR)
- return -ENODEV;
-
- device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
- if (device != ADT7473_DEVICE)
- return -ENODEV;
-
- revision = i2c_smbus_read_byte_data(client, ADT7473_REG_REVISION);
- if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69)
- return -ENODEV;
-
- strlcpy(info->type, "adt7473", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int adt7473_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adt7473_data *data;
- int err;
-
- data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
-
- i2c_set_clientdata(client, data);
- mutex_init(&data->lock);
-
- dev_info(&client->dev, "%s chip found\n", client->name);
-
- /* Initialize the ADT7473 chip */
- adt7473_init_client(client);
-
- /* Register sysfs hooks */
- data->attrs.attrs = adt7473_attr;
- err = sysfs_create_group(&client->dev.kobj, &data->attrs);
- if (err)
- goto exit_free;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
-exit_free:
- kfree(data);
-exit:
- return err;
-}
-
-static int adt7473_remove(struct i2c_client *client)
-{
- struct adt7473_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
- kfree(data);
- return 0;
-}
-
-static int __init adt7473_init(void)
-{
- pr_notice("The adt7473 driver is deprecated, please use the adt7475 "
- "driver instead\n");
- return i2c_add_driver(&adt7473_driver);
-}
-
-static void __exit adt7473_exit(void)
-{
- i2c_del_driver(&adt7473_driver);
-}
-
-MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
-MODULE_DESCRIPTION("ADT7473 driver");
-MODULE_LICENSE("GPL");
-
-module_init(adt7473_init);
-module_exit(adt7473_exit);
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index c1605b528e8..0f28d91f29d 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -142,6 +142,12 @@ static const char *temperature_sensors_sets[][41] = {
"TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
"TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
NULL },
+/* Set 17: iMac 9,1 */
+ { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
+ "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
+/* Set 18: MacBook Pro 2,2 */
+ { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
+ "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
};
/* List of keys used to read/write fan speeds */
@@ -1350,6 +1356,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
{ .accelerometer = 1, .light = 1, .temperature_set = 15 },
/* MacPro3,1: temperature set 16 */
{ .accelerometer = 0, .light = 0, .temperature_set = 16 },
+/* iMac 9,1: light sensor only, temperature set 17 */
+ { .accelerometer = 0, .light = 0, .temperature_set = 17 },
+/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
+ { .accelerometer = 1, .light = 1, .temperature_set = 18 },
};
/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1375,6 +1385,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
&applesmc_dmi_data[9]},
+ { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
+ &applesmc_dmi_data[18]},
{ applesmc_dmi_match, "Apple MacBook Pro", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
@@ -1415,6 +1429,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
&applesmc_dmi_data[4]},
+ { applesmc_dmi_match, "Apple iMac 9,1", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
+ &applesmc_dmi_data[17]},
{ applesmc_dmi_match, "Apple iMac 8", {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c
new file mode 100644
index 00000000000..7f948105d8a
--- /dev/null
+++ b/drivers/hwmon/asc7621.c
@@ -0,0 +1,1255 @@
+/*
+ * asc7621.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
+ * Copyright (c) 2007, 2010 George Joseph <george.joseph@fairview5.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/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 to scan */
+static unsigned short normal_i2c[] = {
+ 0x2c, 0x2d, 0x2e, I2C_CLIENT_END
+};
+
+enum asc7621_type {
+ asc7621,
+ asc7621a
+};
+
+#define INTERVAL_HIGH (HZ + HZ / 2)
+#define INTERVAL_LOW (1 * 60 * HZ)
+#define PRI_NONE 0
+#define PRI_LOW 1
+#define PRI_HIGH 2
+#define FIRST_CHIP asc7621
+#define LAST_CHIP asc7621a
+
+struct asc7621_chip {
+ char *name;
+ enum asc7621_type chip_type;
+ u8 company_reg;
+ u8 company_id;
+ u8 verstep_reg;
+ u8 verstep_id;
+ unsigned short *addresses;
+};
+
+static struct asc7621_chip asc7621_chips[] = {
+ {
+ .name = "asc7621",
+ .chip_type = asc7621,
+ .company_reg = 0x3e,
+ .company_id = 0x61,
+ .verstep_reg = 0x3f,
+ .verstep_id = 0x6c,
+ .addresses = normal_i2c,
+ },
+ {
+ .name = "asc7621a",
+ .chip_type = asc7621a,
+ .company_reg = 0x3e,
+ .company_id = 0x61,
+ .verstep_reg = 0x3f,
+ .verstep_id = 0x6d,
+ .addresses = normal_i2c,
+ },
+};
+
+/*
+ * Defines the highest register to be used, not the count.
+ * The actual count will probably be smaller because of gaps
+ * in the implementation (unused register locations).
+ * This define will safely set the array size of both the parameter
+ * and data arrays.
+ * This comes from the data sheet register description table.
+ */
+#define LAST_REGISTER 0xff
+
+struct asc7621_data {
+ struct i2c_client client;
+ struct device *class_dev;
+ struct mutex update_lock;
+ int valid; /* !=0 if following fields are valid */
+ unsigned long last_high_reading; /* In jiffies */
+ unsigned long last_low_reading; /* In jiffies */
+ /*
+ * Registers we care about occupy the corresponding index
+ * in the array. Registers we don't care about are left
+ * at 0.
+ */
+ u8 reg[LAST_REGISTER + 1];
+};
+
+/*
+ * Macro to get the parent asc7621_param structure
+ * from a sensor_device_attribute passed into the
+ * show/store functions.
+ */
+#define to_asc7621_param(_sda) \
+ container_of(_sda, struct asc7621_param, sda)
+
+/*
+ * Each parameter to be retrieved needs an asc7621_param structure
+ * allocated. It contains the sensor_device_attribute structure
+ * and the control info needed to retrieve the value from the register map.
+ */
+struct asc7621_param {
+ struct sensor_device_attribute sda;
+ u8 priority;
+ u8 msb[3];
+ u8 lsb[3];
+ u8 mask[3];
+ u8 shift[3];
+};
+
+/*
+ * This is the map that ultimately indicates whether we'll be
+ * retrieving a register value or not, and at what frequency.
+ */
+static u8 asc7621_register_priorities[255];
+
+static struct asc7621_data *asc7621_update_device(struct device *dev);
+
+static inline u8 read_byte(struct i2c_client *client, u8 reg)
+{
+ int res = i2c_smbus_read_byte_data(client, reg);
+ if (res < 0) {
+ dev_err(&client->dev,
+ "Unable to read from register 0x%02x.\n", reg);
+ return 0;
+ };
+ return res & 0xff;
+}
+
+static inline int write_byte(struct i2c_client *client, u8 reg, u8 data)
+{
+ int res = i2c_smbus_write_byte_data(client, reg, data);
+ if (res < 0) {
+ dev_err(&client->dev,
+ "Unable to write value 0x%02x to register 0x%02x.\n",
+ data, reg);
+ };
+ return res;
+}
+
+/*
+ * Data Handlers
+ * Each function handles the formatting, storage
+ * and retrieval of like parameters.
+ */
+
+#define SETUP_SHOW_data_param(d, a) \
+ struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
+ struct asc7621_data *data = asc7621_update_device(d); \
+ struct asc7621_param *param = to_asc7621_param(sda)
+
+#define SETUP_STORE_data_param(d, a) \
+ struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
+ struct i2c_client *client = to_i2c_client(d); \
+ struct asc7621_data *data = i2c_get_clientdata(client); \
+ struct asc7621_param *param = to_asc7621_param(sda)
+
+/*
+ * u8 is just what it sounds like...an unsigned byte with no
+ * special formatting.
+ */
+static ssize_t show_u8(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+
+ return sprintf(buf, "%u\n", data->reg[param->msb[0]]);
+}
+
+static ssize_t store_u8(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ reqval = SENSORS_LIMIT(reqval, 0, 255);
+
+ mutex_lock(&data->update_lock);
+ data->reg[param->msb[0]] = reqval;
+ write_byte(client, param->msb[0], reqval);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/*
+ * Many of the config values occupy only a few bits of a register.
+ */
+static ssize_t show_bitmask(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+
+ return sprintf(buf, "%u\n",
+ (data->reg[param->msb[0]] >> param->
+ shift[0]) & param->mask[0]);
+}
+
+static ssize_t store_bitmask(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval;
+ u8 currval;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ reqval = SENSORS_LIMIT(reqval, 0, param->mask[0]);
+
+ reqval = (reqval & param->mask[0]) << param->shift[0];
+
+ mutex_lock(&data->update_lock);
+ currval = read_byte(client, param->msb[0]);
+ reqval |= (currval & ~(param->mask[0] << param->shift[0]));
+ data->reg[param->msb[0]] = reqval;
+ write_byte(client, param->msb[0], reqval);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/*
+ * 16 bit fan rpm values
+ * reported by the device as the number of 11.111us periods (90khz)
+ * between full fan rotations. Therefore...
+ * RPM = (90000 * 60) / register value
+ */
+static ssize_t show_fan16(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u16 regval;
+
+ mutex_lock(&data->update_lock);
+ regval = (data->reg[param->msb[0]] << 8) | data->reg[param->lsb[0]];
+ mutex_unlock(&data->update_lock);
+
+ return sprintf(buf, "%u\n",
+ (regval == 0 ? -1 : (regval) ==
+ 0xffff ? 0 : 5400000 / regval));
+}
+
+static ssize_t store_fan16(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ reqval =
+ (SENSORS_LIMIT((reqval) <= 0 ? 0 : 5400000 / (reqval), 0, 65534));
+
+ mutex_lock(&data->update_lock);
+ data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
+ data->reg[param->lsb[0]] = reqval & 0xff;
+ write_byte(client, param->msb[0], data->reg[param->msb[0]]);
+ write_byte(client, param->lsb[0], data->reg[param->lsb[0]]);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/*
+ * Voltages are scaled in the device so that the nominal voltage
+ * is 3/4ths of the 0-255 range (i.e. 192).
+ * If all voltages are 'normal' then all voltage registers will
+ * read 0xC0. This doesn't help us if we don't have a point of refernce.
+ * The data sheet however provides us with the full scale value for each
+ * which is stored in in_scaling. The sda->index parameter value provides
+ * the index into in_scaling.
+ *
+ * NOTE: The chip expects the first 2 inputs be 2.5 and 2.25 volts
+ * respectively. That doesn't mean that's what the motherboard provides. :)
+ */
+
+static int asc7621_in_scaling[] = {
+ 3320, 3000, 4380, 6640, 16000
+};
+
+static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u16 regval;
+ u8 nr = sda->index;
+
+ mutex_lock(&data->update_lock);
+ regval = (data->reg[param->msb[0]] * asc7621_in_scaling[nr]) / 256;
+
+ /* The LSB value is a 2-bit scaling of the MSB's LSbit value.
+ * I.E. If the maximim voltage for this input is 6640 millivolts then
+ * a MSB register value of 0 = 0mv and 255 = 6640mv.
+ * A 1 step change therefore represents 25.9mv (6640 / 256).
+ * The extra 2-bits therefore represent increments of 6.48mv.
+ */
+ regval += ((asc7621_in_scaling[nr] / 256) / 4) *
+ (data->reg[param->lsb[0]] >> 6);
+
+ mutex_unlock(&data->update_lock);
+
+ return sprintf(buf, "%u\n", regval);
+}
+
+/* 8 bit voltage values (the mins and maxs) */
+static ssize_t show_in8(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u8 nr = sda->index;
+
+ return sprintf(buf, "%u\n",
+ ((data->reg[param->msb[0]] *
+ asc7621_in_scaling[nr]) / 256));
+}
+
+static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval;
+ u8 nr = sda->index;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ reqval = SENSORS_LIMIT(reqval, 0, asc7621_in_scaling[nr]);
+
+ reqval = (reqval * 255 + 128) / asc7621_in_scaling[nr];
+
+ mutex_lock(&data->update_lock);
+ data->reg[param->msb[0]] = reqval;
+ write_byte(client, param->msb[0], reqval);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t show_temp8(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+
+ return sprintf(buf, "%d\n", ((s8) data->reg[param->msb[0]]) * 1000);
+}
+
+static ssize_t store_temp8(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval;
+ s8 temp;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ reqval = SENSORS_LIMIT(reqval, -127000, 127000);
+
+ temp = reqval / 1000;
+
+ mutex_lock(&data->update_lock);
+ data->reg[param->msb[0]] = temp;
+ write_byte(client, param->msb[0], temp);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/*
+ * Temperatures that occupy 2 bytes always have the whole
+ * number of degrees in the MSB with some part of the LSB
+ * indicating fractional degrees.
+ */
+
+/* mmmmmmmm.llxxxxxx */
+static ssize_t show_temp10(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u8 msb, lsb;
+ int temp;
+
+ mutex_lock(&data->update_lock);
+ msb = data->reg[param->msb[0]];
+ lsb = (data->reg[param->lsb[0]] >> 6) & 0x03;
+ temp = (((s8) msb) * 1000) + (lsb * 250);
+ mutex_unlock(&data->update_lock);
+
+ return sprintf(buf, "%d\n", temp);
+}
+
+/* mmmmmm.ll */
+static ssize_t show_temp62(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u8 regval = data->reg[param->msb[0]];
+ int temp = ((s8) (regval & 0xfc) * 1000) + ((regval & 0x03) * 250);
+
+ return sprintf(buf, "%d\n", temp);
+}
+
+static ssize_t store_temp62(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval, i, f;
+ s8 temp;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ reqval = SENSORS_LIMIT(reqval, -32000, 31750);
+ i = reqval / 1000;
+ f = reqval - (i * 1000);
+ temp = i << 2;
+ temp |= f / 250;
+
+ mutex_lock(&data->update_lock);
+ data->reg[param->msb[0]] = temp;
+ write_byte(client, param->msb[0], temp);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/*
+ * The aSC7621 doesn't provide an "auto_point2". Instead, you
+ * specify the auto_point1 and a range. To keep with the sysfs
+ * hwmon specs, we synthesize the auto_point_2 from them.
+ */
+
+static u32 asc7621_range_map[] = {
+ 2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
+ 13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
+};
+
+static ssize_t show_ap2_temp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ long auto_point1;
+ u8 regval;
+ int temp;
+
+ mutex_lock(&data->update_lock);
+ auto_point1 = ((s8) data->reg[param->msb[1]]) * 1000;
+ regval =
+ ((data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]);
+ temp = auto_point1 + asc7621_range_map[SENSORS_LIMIT(regval, 0, 15)];
+ mutex_unlock(&data->update_lock);
+
+ return sprintf(buf, "%d\n", temp);
+
+}
+
+static ssize_t store_ap2_temp(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval, auto_point1;
+ int i;
+ u8 currval, newval = 0;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ auto_point1 = data->reg[param->msb[1]] * 1000;
+ reqval = SENSORS_LIMIT(reqval, auto_point1 + 2000, auto_point1 + 80000);
+
+ for (i = ARRAY_SIZE(asc7621_range_map) - 1; i >= 0; i--) {
+ if (reqval >= auto_point1 + asc7621_range_map[i]) {
+ newval = i;
+ break;
+ }
+ }
+
+ newval = (newval & param->mask[0]) << param->shift[0];
+ currval = read_byte(client, param->msb[0]);
+ newval |= (currval & ~(param->mask[0] << param->shift[0]));
+ data->reg[param->msb[0]] = newval;
+ write_byte(client, param->msb[0], newval);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t show_pwm_ac(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u8 config, altbit, regval;
+ u8 map[] = {
+ 0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
+ 0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
+ };
+
+ mutex_lock(&data->update_lock);
+ config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+ altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
+ regval = config | (altbit << 3);
+ mutex_unlock(&data->update_lock);
+
+ return sprintf(buf, "%u\n", map[SENSORS_LIMIT(regval, 0, 15)]);
+}
+
+static ssize_t store_pwm_ac(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ unsigned long reqval;
+ u8 currval, config, altbit, newval;
+ u16 map[] = {
+ 0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
+ 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+ 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
+ };
+
+ if (strict_strtoul(buf, 10, &reqval))
+ return -EINVAL;
+
+ if (reqval > 31)
+ return -EINVAL;
+
+ reqval = map[reqval];
+ if (reqval == 0xff)
+ return -EINVAL;
+
+ config = reqval & 0x07;
+ altbit = (reqval >> 3) & 0x01;
+
+ config = (config & param->mask[0]) << param->shift[0];
+ altbit = (altbit & param->mask[1]) << param->shift[1];
+
+ mutex_lock(&data->update_lock);
+ currval = read_byte(client, param->msb[0]);
+ newval = config | (currval & ~(param->mask[0] << param->shift[0]));
+ newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
+ data->reg[param->msb[0]] = newval;
+ write_byte(client, param->msb[0], newval);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t show_pwm_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u8 config, altbit, minoff, val, newval;
+
+ mutex_lock(&data->update_lock);
+ config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+ altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
+ minoff = (data->reg[param->msb[2]] >> param->shift[2]) & param->mask[2];
+ mutex_unlock(&data->update_lock);
+
+ val = config | (altbit << 3);
+ newval = 0;
+
+ if (val == 3 || val >= 10)
+ newval = 255;
+ else if (val == 4)
+ newval = 0;
+ else if (val == 7)
+ newval = 1;
+ else if (minoff == 1)
+ newval = 2;
+ else
+ newval = 3;
+
+ return sprintf(buf, "%u\n", newval);
+}
+
+static ssize_t store_pwm_enable(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval;
+ u8 currval, config, altbit, newval, minoff = 255;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ switch (reqval) {
+ case 0:
+ newval = 0x04;
+ break;
+ case 1:
+ newval = 0x07;
+ break;
+ case 2:
+ newval = 0x00;
+ minoff = 1;
+ break;
+ case 3:
+ newval = 0x00;
+ minoff = 0;
+ break;
+ case 255:
+ newval = 0x03;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ config = newval & 0x07;
+ altbit = (newval >> 3) & 0x01;
+
+ mutex_lock(&data->update_lock);
+ config = (config & param->mask[0]) << param->shift[0];
+ altbit = (altbit & param->mask[1]) << param->shift[1];
+ currval = read_byte(client, param->msb[0]);
+ newval = config | (currval & ~(param->mask[0] << param->shift[0]));
+ newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
+ data->reg[param->msb[0]] = newval;
+ write_byte(client, param->msb[0], newval);
+ if (minoff < 255) {
+ minoff = (minoff & param->mask[2]) << param->shift[2];
+ currval = read_byte(client, param->msb[2]);
+ newval =
+ minoff | (currval & ~(param->mask[2] << param->shift[2]));
+ data->reg[param->msb[2]] = newval;
+ write_byte(client, param->msb[2], newval);
+ }
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static u32 asc7621_pwm_freq_map[] = {
+ 10, 15, 23, 30, 38, 47, 62, 94,
+ 23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
+};
+
+static ssize_t show_pwm_freq(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u8 regval =
+ (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+
+ regval = SENSORS_LIMIT(regval, 0, 15);
+
+ return sprintf(buf, "%u\n", asc7621_pwm_freq_map[regval]);
+}
+
+static ssize_t store_pwm_freq(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ unsigned long reqval;
+ u8 currval, newval = 255;
+ int i;
+
+ if (strict_strtoul(buf, 10, &reqval))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(asc7621_pwm_freq_map); i++) {
+ if (reqval == asc7621_pwm_freq_map[i]) {
+ newval = i;
+ break;
+ }
+ }
+ if (newval == 255)
+ return -EINVAL;
+
+ newval = (newval & param->mask[0]) << param->shift[0];
+
+ mutex_lock(&data->update_lock);
+ currval = read_byte(client, param->msb[0]);
+ newval |= (currval & ~(param->mask[0] << param->shift[0]));
+ data->reg[param->msb[0]] = newval;
+ write_byte(client, param->msb[0], newval);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static u32 asc7621_pwm_auto_spinup_map[] = {
+ 0, 100, 250, 400, 700, 1000, 2000, 4000
+};
+
+static ssize_t show_pwm_ast(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u8 regval =
+ (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+
+ regval = SENSORS_LIMIT(regval, 0, 7);
+
+ return sprintf(buf, "%u\n", asc7621_pwm_auto_spinup_map[regval]);
+
+}
+
+static ssize_t store_pwm_ast(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval;
+ u8 currval, newval = 255;
+ u32 i;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(asc7621_pwm_auto_spinup_map); i++) {
+ if (reqval == asc7621_pwm_auto_spinup_map[i]) {
+ newval = i;
+ break;
+ }
+ }
+ if (newval == 255)
+ return -EINVAL;
+
+ newval = (newval & param->mask[0]) << param->shift[0];
+
+ mutex_lock(&data->update_lock);
+ currval = read_byte(client, param->msb[0]);
+ newval |= (currval & ~(param->mask[0] << param->shift[0]));
+ data->reg[param->msb[0]] = newval;
+ write_byte(client, param->msb[0], newval);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static u32 asc7621_temp_smoothing_time_map[] = {
+ 35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
+};
+
+static ssize_t show_temp_st(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ SETUP_SHOW_data_param(dev, attr);
+ u8 regval =
+ (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
+ regval = SENSORS_LIMIT(regval, 0, 7);
+
+ return sprintf(buf, "%u\n", asc7621_temp_smoothing_time_map[regval]);
+}
+
+static ssize_t store_temp_st(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ SETUP_STORE_data_param(dev, attr);
+ long reqval;
+ u8 currval, newval = 255;
+ u32 i;
+
+ if (strict_strtol(buf, 10, &reqval))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(asc7621_temp_smoothing_time_map); i++) {
+ if (reqval == asc7621_temp_smoothing_time_map[i]) {
+ newval = i;
+ break;
+ }
+ }
+
+ if (newval == 255)
+ return -EINVAL;
+
+ newval = (newval & param->mask[0]) << param->shift[0];
+
+ mutex_lock(&data->update_lock);
+ currval = read_byte(client, param->msb[0]);
+ newval |= (currval & ~(param->mask[0] << param->shift[0]));
+ data->reg[param->msb[0]] = newval;
+ write_byte(client, param->msb[0], newval);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+/*
+ * End of data handlers
+ *
+ * These defines do nothing more than make the table easier
+ * to read when wrapped at column 80.
+ */
+
+/*
+ * Creates a variable length array inititalizer.
+ * VAA(1,3,5,7) would produce {1,3,5,7}
+ */
+#define VAA(args...) {args}
+
+#define PREAD(name, n, pri, rm, rl, m, s, r) \
+ {.sda = SENSOR_ATTR(name, S_IRUGO, show_##r, NULL, n), \
+ .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
+ .shift[0] = s,}
+
+#define PWRITE(name, n, pri, rm, rl, m, s, r) \
+ {.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
+ .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
+ .shift[0] = s,}
+
+/*
+ * PWRITEM assumes that the initializers for the .msb, .lsb, .mask and .shift
+ * were created using the VAA macro.
+ */
+#define PWRITEM(name, n, pri, rm, rl, m, s, r) \
+ {.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
+ .priority = pri, .msb = rm, .lsb = rl, .mask = m, .shift = s,}
+
+static struct asc7621_param asc7621_params[] = {
+ PREAD(in0_input, 0, PRI_HIGH, 0x20, 0x13, 0, 0, in10),
+ PREAD(in1_input, 1, PRI_HIGH, 0x21, 0x18, 0, 0, in10),
+ PREAD(in2_input, 2, PRI_HIGH, 0x22, 0x11, 0, 0, in10),
+ PREAD(in3_input, 3, PRI_HIGH, 0x23, 0x12, 0, 0, in10),
+ PREAD(in4_input, 4, PRI_HIGH, 0x24, 0x14, 0, 0, in10),
+
+ PWRITE(in0_min, 0, PRI_LOW, 0x44, 0, 0, 0, in8),
+ PWRITE(in1_min, 1, PRI_LOW, 0x46, 0, 0, 0, in8),
+ PWRITE(in2_min, 2, PRI_LOW, 0x48, 0, 0, 0, in8),
+ PWRITE(in3_min, 3, PRI_LOW, 0x4a, 0, 0, 0, in8),
+ PWRITE(in4_min, 4, PRI_LOW, 0x4c, 0, 0, 0, in8),
+
+ PWRITE(in0_max, 0, PRI_LOW, 0x45, 0, 0, 0, in8),
+ PWRITE(in1_max, 1, PRI_LOW, 0x47, 0, 0, 0, in8),
+ PWRITE(in2_max, 2, PRI_LOW, 0x49, 0, 0, 0, in8),
+ PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8),
+ PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8),
+
+ PREAD(in0_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 0, bitmask),
+ PREAD(in1_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 1, bitmask),
+ PREAD(in2_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 2, bitmask),
+ PREAD(in3_alarm, 3, PRI_LOW, 0x41, 0, 0x01, 3, bitmask),
+ PREAD(in4_alarm, 4, PRI_LOW, 0x42, 0, 0x01, 0, bitmask),
+
+ PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16),
+ PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16),
+ PREAD(fan3_input, 2, PRI_HIGH, 0x2d, 0x2c, 0, 0, fan16),
+ PREAD(fan4_input, 3, PRI_HIGH, 0x2f, 0x2e, 0, 0, fan16),
+
+ PWRITE(fan1_min, 0, PRI_LOW, 0x55, 0x54, 0, 0, fan16),
+ PWRITE(fan2_min, 1, PRI_LOW, 0x57, 0x56, 0, 0, fan16),
+ PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16),
+ PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16),
+
+ PREAD(fan1_alarm, 0, PRI_LOW, 0x42, 0, 0x01, 0, bitmask),
+ PREAD(fan2_alarm, 1, PRI_LOW, 0x42, 0, 0x01, 1, bitmask),
+ PREAD(fan3_alarm, 2, PRI_LOW, 0x42, 0, 0x01, 2, bitmask),
+ PREAD(fan4_alarm, 3, PRI_LOW, 0x42, 0, 0x01, 3, bitmask),
+
+ PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10),
+ PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10),
+ PREAD(temp3_input, 2, PRI_HIGH, 0x27, 0x16, 0, 0, temp10),
+ PREAD(temp4_input, 3, PRI_HIGH, 0x33, 0x17, 0, 0, temp10),
+ PREAD(temp5_input, 4, PRI_HIGH, 0xf7, 0xf6, 0, 0, temp10),
+ PREAD(temp6_input, 5, PRI_HIGH, 0xf9, 0xf8, 0, 0, temp10),
+ PREAD(temp7_input, 6, PRI_HIGH, 0xfb, 0xfa, 0, 0, temp10),
+ PREAD(temp8_input, 7, PRI_HIGH, 0xfd, 0xfc, 0, 0, temp10),
+
+ PWRITE(temp1_min, 0, PRI_LOW, 0x4e, 0, 0, 0, temp8),
+ PWRITE(temp2_min, 1, PRI_LOW, 0x50, 0, 0, 0, temp8),
+ PWRITE(temp3_min, 2, PRI_LOW, 0x52, 0, 0, 0, temp8),
+ PWRITE(temp4_min, 3, PRI_LOW, 0x34, 0, 0, 0, temp8),
+
+ PWRITE(temp1_max, 0, PRI_LOW, 0x4f, 0, 0, 0, temp8),
+ PWRITE(temp2_max, 1, PRI_LOW, 0x51, 0, 0, 0, temp8),
+ PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8),
+ PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8),
+
+ PREAD(temp1_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 4, bitmask),
+ PREAD(temp2_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 5, bitmask),
+ PREAD(temp3_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 6, bitmask),
+ PREAD(temp4_alarm, 3, PRI_LOW, 0x43, 0, 0x01, 0, bitmask),
+
+ PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask),
+ PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask),
+ PWRITE(temp3_source, 2, PRI_LOW, 0x03, 0, 0x07, 4, bitmask),
+ PWRITE(temp4_source, 3, PRI_LOW, 0x03, 0, 0x07, 0, bitmask),
+
+ PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask),
+ PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask),
+ PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x64, 0, 0x01, 3, bitmask),
+ PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask),
+
+ PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st),
+ PWRITE(temp2_smoothing_time, 1, PRI_LOW, 0x63, 0, 0x07, 4, temp_st),
+ PWRITE(temp3_smoothing_time, 2, PRI_LOW, 0x63, 0, 0x07, 0, temp_st),
+ PWRITE(temp4_smoothing_time, 3, PRI_LOW, 0x3c, 0, 0x07, 0, temp_st),
+
+ PWRITE(temp1_auto_point1_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
+ bitmask),
+ PWRITE(temp2_auto_point1_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
+ bitmask),
+ PWRITE(temp3_auto_point1_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
+ bitmask),
+ PWRITE(temp4_auto_point1_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
+ bitmask),
+
+ PREAD(temp1_auto_point2_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
+ bitmask),
+ PREAD(temp2_auto_point2_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
+ bitmask),
+ PREAD(temp3_auto_point2_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
+ bitmask),
+ PREAD(temp4_auto_point2_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
+ bitmask),
+
+ PWRITE(temp1_auto_point1_temp, 0, PRI_LOW, 0x67, 0, 0, 0, temp8),
+ PWRITE(temp2_auto_point1_temp, 1, PRI_LOW, 0x68, 0, 0, 0, temp8),
+ PWRITE(temp3_auto_point1_temp, 2, PRI_LOW, 0x69, 0, 0, 0, temp8),
+ PWRITE(temp4_auto_point1_temp, 3, PRI_LOW, 0x3b, 0, 0, 0, temp8),
+
+ PWRITEM(temp1_auto_point2_temp, 0, PRI_LOW, VAA(0x5f, 0x67), VAA(0),
+ VAA(0x0f), VAA(4), ap2_temp),
+ PWRITEM(temp2_auto_point2_temp, 1, PRI_LOW, VAA(0x60, 0x68), VAA(0),
+ VAA(0x0f), VAA(4), ap2_temp),
+ PWRITEM(temp3_auto_point2_temp, 2, PRI_LOW, VAA(0x61, 0x69), VAA(0),
+ VAA(0x0f), VAA(4), ap2_temp),
+ PWRITEM(temp4_auto_point2_temp, 3, PRI_LOW, VAA(0x3c, 0x3b), VAA(0),
+ VAA(0x0f), VAA(4), ap2_temp),
+
+ PWRITE(temp1_crit, 0, PRI_LOW, 0x6a, 0, 0, 0, temp8),
+ PWRITE(temp2_crit, 1, PRI_LOW, 0x6b, 0, 0, 0, temp8),
+ PWRITE(temp3_crit, 2, PRI_LOW, 0x6c, 0, 0, 0, temp8),
+ PWRITE(temp4_crit, 3, PRI_LOW, 0x3d, 0, 0, 0, temp8),
+
+ PWRITE(temp5_enable, 4, PRI_LOW, 0x0e, 0, 0x01, 0, bitmask),
+ PWRITE(temp6_enable, 5, PRI_LOW, 0x0e, 0, 0x01, 1, bitmask),
+ PWRITE(temp7_enable, 6, PRI_LOW, 0x0e, 0, 0x01, 2, bitmask),
+ PWRITE(temp8_enable, 7, PRI_LOW, 0x0e, 0, 0x01, 3, bitmask),
+
+ PWRITE(remote1_offset, 0, PRI_LOW, 0x1c, 0, 0, 0, temp62),
+ PWRITE(remote2_offset, 1, PRI_LOW, 0x1d, 0, 0, 0, temp62),
+
+ PWRITE(pwm1, 0, PRI_HIGH, 0x30, 0, 0, 0, u8),
+ PWRITE(pwm2, 1, PRI_HIGH, 0x31, 0, 0, 0, u8),
+ PWRITE(pwm3, 2, PRI_HIGH, 0x32, 0, 0, 0, u8),
+
+ PWRITE(pwm1_invert, 0, PRI_LOW, 0x5c, 0, 0x01, 4, bitmask),
+ PWRITE(pwm2_invert, 1, PRI_LOW, 0x5d, 0, 0x01, 4, bitmask),
+ PWRITE(pwm3_invert, 2, PRI_LOW, 0x5e, 0, 0x01, 4, bitmask),
+
+ PWRITEM(pwm1_enable, 0, PRI_LOW, VAA(0x5c, 0x5c, 0x62), VAA(0, 0, 0),
+ VAA(0x07, 0x01, 0x01), VAA(5, 3, 5), pwm_enable),
+ PWRITEM(pwm2_enable, 1, PRI_LOW, VAA(0x5d, 0x5d, 0x62), VAA(0, 0, 0),
+ VAA(0x07, 0x01, 0x01), VAA(5, 3, 6), pwm_enable),
+ PWRITEM(pwm3_enable, 2, PRI_LOW, VAA(0x5e, 0x5e, 0x62), VAA(0, 0, 0),
+ VAA(0x07, 0x01, 0x01), VAA(5, 3, 7), pwm_enable),
+
+ PWRITEM(pwm1_auto_channels, 0, PRI_LOW, VAA(0x5c, 0x5c), VAA(0, 0),
+ VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
+ PWRITEM(pwm2_auto_channels, 1, PRI_LOW, VAA(0x5d, 0x5d), VAA(0, 0),
+ VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
+ PWRITEM(pwm3_auto_channels, 2, PRI_LOW, VAA(0x5e, 0x5e), VAA(0, 0),
+ VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
+
+ PWRITE(pwm1_auto_point1_pwm, 0, PRI_LOW, 0x64, 0, 0, 0, u8),
+ PWRITE(pwm2_auto_point1_pwm, 1, PRI_LOW, 0x65, 0, 0, 0, u8),
+ PWRITE(pwm3_auto_point1_pwm, 2, PRI_LOW, 0x66, 0, 0, 0, u8),
+
+ PWRITE(pwm1_auto_point2_pwm, 0, PRI_LOW, 0x38, 0, 0, 0, u8),
+ PWRITE(pwm2_auto_point2_pwm, 1, PRI_LOW, 0x39, 0, 0, 0, u8),
+ PWRITE(pwm3_auto_point2_pwm, 2, PRI_LOW, 0x3a, 0, 0, 0, u8),
+
+ PWRITE(pwm1_freq, 0, PRI_LOW, 0x5f, 0, 0x0f, 0, pwm_freq),
+ PWRITE(pwm2_freq, 1, PRI_LOW, 0x60, 0, 0x0f, 0, pwm_freq),
+ PWRITE(pwm3_freq, 2, PRI_LOW, 0x61, 0, 0x0f, 0, pwm_freq),
+
+ PREAD(pwm1_auto_zone_assigned, 0, PRI_LOW, 0, 0, 0x03, 2, bitmask),
+ PREAD(pwm2_auto_zone_assigned, 1, PRI_LOW, 0, 0, 0x03, 4, bitmask),
+ PREAD(pwm3_auto_zone_assigned, 2, PRI_LOW, 0, 0, 0x03, 6, bitmask),
+
+ PWRITE(pwm1_auto_spinup_time, 0, PRI_LOW, 0x5c, 0, 0x07, 0, pwm_ast),
+ PWRITE(pwm2_auto_spinup_time, 1, PRI_LOW, 0x5d, 0, 0x07, 0, pwm_ast),
+ PWRITE(pwm3_auto_spinup_time, 2, PRI_LOW, 0x5e, 0, 0x07, 0, pwm_ast),
+
+ PWRITE(peci_enable, 0, PRI_LOW, 0x40, 0, 0x01, 4, bitmask),
+ PWRITE(peci_avg, 0, PRI_LOW, 0x36, 0, 0x07, 0, bitmask),
+ PWRITE(peci_domain, 0, PRI_LOW, 0x36, 0, 0x01, 3, bitmask),
+ PWRITE(peci_legacy, 0, PRI_LOW, 0x36, 0, 0x01, 4, bitmask),
+ PWRITE(peci_diode, 0, PRI_LOW, 0x0e, 0, 0x07, 4, bitmask),
+ PWRITE(peci_4domain, 0, PRI_LOW, 0x0e, 0, 0x01, 4, bitmask),
+
+};
+
+static struct asc7621_data *asc7621_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct asc7621_data *data = i2c_get_clientdata(client);
+ int i;
+
+/*
+ * The asc7621 chips guarantee consistent reads of multi-byte values
+ * regardless of the order of the reads. No special logic is needed
+ * so we can just read the registers in whatever order they appear
+ * in the asc7621_params array.
+ */
+
+ mutex_lock(&data->update_lock);
+
+ /* Read all the high priority registers */
+
+ if (!data->valid ||
+ time_after(jiffies, data->last_high_reading + INTERVAL_HIGH)) {
+
+ for (i = 0; i < ARRAY_SIZE(asc7621_register_priorities); i++) {
+ if (asc7621_register_priorities[i] == PRI_HIGH) {
+ data->reg[i] =
+ i2c_smbus_read_byte_data(client, i) & 0xff;
+ }
+ }
+ data->last_high_reading = jiffies;
+ }; /* last_reading */
+
+ /* Read all the low priority registers. */
+
+ if (!data->valid ||
+ time_after(jiffies, data->last_low_reading + INTERVAL_LOW)) {
+
+ for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+ if (asc7621_register_priorities[i] == PRI_LOW) {
+ data->reg[i] =
+ i2c_smbus_read_byte_data(client, i) & 0xff;
+ }
+ }
+ data->last_low_reading = jiffies;
+ }; /* last_reading */
+
+ data->valid = 1;
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+/*
+ * Standard detection and initialization below
+ *
+ * Helper function that checks if an address is valid
+ * for a particular chip.
+ */
+
+static inline int valid_address_for_chip(int chip_type, int address)
+{
+ int i;
+
+ for (i = 0; asc7621_chips[chip_type].addresses[i] != I2C_CLIENT_END;
+ i++) {
+ if (asc7621_chips[chip_type].addresses[i] == address)
+ return 1;
+ }
+ return 0;
+}
+
+static void asc7621_init_client(struct i2c_client *client)
+{
+ int value;
+
+ /* Warn if part was not "READY" */
+
+ value = read_byte(client, 0x40);
+
+ if (value & 0x02) {
+ dev_err(&client->dev,
+ "Client (%d,0x%02x) config is locked.\n",
+ i2c_adapter_id(client->adapter), client->addr);
+ };
+ if (!(value & 0x04)) {
+ dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n",
+ i2c_adapter_id(client->adapter), client->addr);
+ };
+
+/*
+ * Start monitoring
+ *
+ * Try to clear LOCK, Set START, save everything else
+ */
+ value = (value & ~0x02) | 0x01;
+ write_byte(client, 0x40, value & 0xff);
+
+}
+
+static int
+asc7621_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct asc7621_data *data;
+ int i, err;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ data = kzalloc(sizeof(struct asc7621_data), GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, data);
+ data->valid = 0;
+ mutex_init(&data->update_lock);
+
+ /* Initialize the asc7621 chip */
+ asc7621_init_client(client);
+
+ /* Create the sysfs entries */
+ for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+ err =
+ device_create_file(&client->dev,
+ &(asc7621_params[i].sda.dev_attr));
+ if (err)
+ goto exit_remove;
+ }
+
+ data->class_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->class_dev)) {
+ err = PTR_ERR(data->class_dev);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+ device_remove_file(&client->dev,
+ &(asc7621_params[i].sda.dev_attr));
+ }
+
+ i2c_set_clientdata(client, NULL);
+ kfree(data);
+ return err;
+}
+
+static int asc7621_detect(struct i2c_client *client,
+ struct i2c_board_info *info)
+{
+ 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;
+
+ for (chip_index = FIRST_CHIP; chip_index <= LAST_CHIP; chip_index++) {
+
+ if (!valid_address_for_chip(chip_index, client->addr))
+ continue;
+
+ company = read_byte(client,
+ asc7621_chips[chip_index].company_reg);
+ verstep = read_byte(client,
+ asc7621_chips[chip_index].verstep_reg);
+
+ 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);
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+static int asc7621_remove(struct i2c_client *client)
+{
+ struct asc7621_data *data = i2c_get_clientdata(client);
+ int i;
+
+ hwmon_device_unregister(data->class_dev);
+
+ for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+ device_remove_file(&client->dev,
+ &(asc7621_params[i].sda.dev_attr));
+ }
+
+ i2c_set_clientdata(client, NULL);
+ kfree(data);
+ return 0;
+}
+
+static const struct i2c_device_id asc7621_id[] = {
+ {"asc7621", asc7621},
+ {"asc7621a", asc7621a},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, asc7621_id);
+
+static struct i2c_driver asc7621_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "asc7621",
+ },
+ .probe = asc7621_probe,
+ .remove = asc7621_remove,
+ .id_table = asc7621_id,
+ .detect = asc7621_detect,
+ .address_list = normal_i2c,
+};
+
+static int __init sm_asc7621_init(void)
+{
+ int i, j;
+/*
+ * Collect all the registers needed into a single array.
+ * This way, if a register isn't actually used for anything,
+ * we don't retrieve it.
+ */
+
+ for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
+ for (j = 0; j < ARRAY_SIZE(asc7621_params[i].msb); j++)
+ asc7621_register_priorities[asc7621_params[i].msb[j]] =
+ asc7621_params[i].priority;
+ for (j = 0; j < ARRAY_SIZE(asc7621_params[i].lsb); j++)
+ asc7621_register_priorities[asc7621_params[i].lsb[j]] =
+ asc7621_params[i].priority;
+ }
+ return i2c_add_driver(&asc7621_driver);
+}
+
+static void __exit sm_asc7621_exit(void)
+{
+ i2c_del_driver(&asc7621_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("George Joseph");
+MODULE_DESCRIPTION("Andigilog aSC7621 and aSC7621a driver");
+
+module_init(sm_asc7621_init);
+module_exit(sm_asc7621_exit);
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index 028284f544e..16c42024072 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -10,6 +10,7 @@
#include <linux/hwmon.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <acpi/acpi.h>
#include <acpi/acpixf.h>
@@ -1168,15 +1169,19 @@ static int atk_create_files(struct atk_data *data)
int err;
list_for_each_entry(s, &data->sensor_list, list) {
+ sysfs_attr_init(&s->input_attr.attr);
err = device_create_file(data->hwmon_dev, &s->input_attr);
if (err)
return err;
+ sysfs_attr_init(&s->label_attr.attr);
err = device_create_file(data->hwmon_dev, &s->label_attr);
if (err)
return err;
+ sysfs_attr_init(&s->limit1_attr.attr);
err = device_create_file(data->hwmon_dev, &s->limit1_attr);
if (err)
return err;
+ sysfs_attr_init(&s->limit2_attr.attr);
err = device_create_file(data->hwmon_dev, &s->limit2_attr);
if (err)
return err;
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
index 94cadc19f0c..33cc143b206 100644
--- a/drivers/hwmon/atxp1.c
+++ b/drivers/hwmon/atxp1.c
@@ -28,6 +28,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
+#include <linux/slab.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 2d7bceeed0b..e9b7fbc5a44 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -228,7 +228,7 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
if (err) {
dev_warn(dev,
"Unable to access MSR 0xEE, for Tjmax, left"
- " at default");
+ " at default\n");
} else if (eax & 0x40000000) {
tjmax = tjmax_ee;
}
@@ -466,7 +466,7 @@ static int __init coretemp_init(void)
family 6 CPU */
if ((c->x86 == 0x6) && (c->x86_model > 0xf))
printk(KERN_WARNING DRVNAME ": Unknown CPU "
- "model %x\n", c->x86_model);
+ "model 0x%x\n", c->x86_model);
continue;
}
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 277398f9c93..bad2cf3ef4a 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -35,6 +35,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/f75375s.h>
+#include <linux/slab.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index fa0728232e7..0627f7a5b9b 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -267,7 +267,7 @@ struct fschmd_data {
struct list_head list; /* member of the watchdog_data_list */
struct kref kref;
struct miscdevice watchdog_miscdev;
- int kind;
+ enum chips kind;
unsigned long watchdog_is_open;
char watchdog_expect_close;
char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
@@ -325,8 +325,7 @@ static ssize_t show_in_value(struct device *dev,
int index = to_sensor_dev_attr(devattr)->index;
struct fschmd_data *data = fschmd_update_device(dev);
- /* fscher / fschrc - 1 as data->kind is an array index, not a chips */
- if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1))
+ if (data->kind == fscher || data->kind >= fschrc)
return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref *
dmi_mult[index]) / 255 + dmi_offset[index]);
else
@@ -492,7 +491,7 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
int val = data->fan_min[index];
/* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
- if (val || data->kind == fscsyl - 1)
+ if (val || data->kind == fscsyl)
val = val / 2 + 128;
return sprintf(buf, "%d\n", val);
@@ -506,7 +505,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
unsigned long v = simple_strtoul(buf, NULL, 10);
/* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
- if (v || data->kind == fscsyl - 1) {
+ if (v || data->kind == fscsyl) {
v = SENSORS_LIMIT(v, 128, 255);
v = (v - 128) * 2 + 1;
}
@@ -1037,7 +1036,7 @@ static int fschmd_detect(struct i2c_client *client,
else
return -ENODEV;
- strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
+ strlcpy(info->type, fschmd_id[kind].name, I2C_NAME_SIZE);
return 0;
}
@@ -1065,6 +1064,7 @@ static int fschmd_probe(struct i2c_client *client,
(where the client is found through a data ptr instead of the
otherway around) */
data->client = client;
+ data->kind = kind;
if (kind == fscpos) {
/* The Poseidon has hardwired temp limits, fill these
@@ -1085,9 +1085,6 @@ static int fschmd_probe(struct i2c_client *client,
}
}
- /* i2c kind goes from 1-6, we want from 0-5 to address arrays */
- data->kind = kind - 1;
-
/* Read in some never changing registers */
data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
data->global_control = i2c_smbus_read_byte_data(client,
diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c
index 19c01a49f6b..09ea12e0a55 100644
--- a/drivers/hwmon/g760a.c
+++ b/drivers/hwmon/g760a.c
@@ -68,7 +68,7 @@ struct g760a_data {
#define PWM_FROM_CNT(cnt) (0xff-(cnt))
#define PWM_TO_CNT(pwm) (0xff-(pwm))
-unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div)
+static inline unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div)
{
return ((val == 0x00) ? 0 : ((clk*30)/(val*div)));
}
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index be475e844c2..c8ab5051667 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -217,6 +217,10 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
AXIS_DMI_MATCH("HDX18", "HP HDX 18", x_inverted),
+ AXIS_DMI_MATCH("HPB432x", "HP ProBook 432", xy_rotated_left),
+ AXIS_DMI_MATCH("HPB442x", "HP ProBook 442", xy_rotated_left),
+ AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted),
+ AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap),
{ NULL, }
/* Laptop models without axis info (yet):
* "NC6910" "HP Compaq 6910"
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index 27d7f72a5f1..e880e2c3871 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -30,6 +30,7 @@
#include <linux/log2.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#define DRVNAME "i5k_amb"
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 405d3fb5d76..eaee546af19 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -29,6 +29,7 @@
#include <linux/kdev_t.h>
#include <linux/spinlock.h>
#include <linux/idr.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/math64.h>
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
index a36363312f2..06d4eafcf76 100644
--- a/drivers/hwmon/ibmpex.c
+++ b/drivers/hwmon/ibmpex.c
@@ -25,6 +25,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#define REFRESH_INTERVAL (2 * HZ)
#define DRVNAME "ibmpex"
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 0ffe84d190b..5be09c048c5 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1,40 +1,40 @@
/*
- it87.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring.
-
- The IT8705F is an LPC-based Super I/O part that contains UARTs, a
- parallel port, an IR port, a MIDI port, a floppy controller, etc., in
- addition to an Environment Controller (Enhanced Hardware Monitor and
- Fan Controller)
-
- This driver supports only the Environment Controller in the IT8705F and
- similar parts. The other devices are supported by different drivers.
-
- Supports: IT8705F Super I/O chip w/LPC interface
- IT8712F Super I/O chip w/LPC interface
- IT8716F Super I/O chip w/LPC interface
- IT8718F Super I/O chip w/LPC interface
- IT8720F Super I/O chip w/LPC interface
- IT8726F Super I/O chip w/LPC interface
- Sis950 A clone of the IT8705F
-
- Copyright (C) 2001 Chris Gauthron
- Copyright (C) 2005-2007 Jean Delvare <khali@linux-fr.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.
-*/
+ * it87.c - Part of lm_sensors, Linux kernel modules for hardware
+ * monitoring.
+ *
+ * The IT8705F is an LPC-based Super I/O part that contains UARTs, a
+ * parallel port, an IR port, a MIDI port, a floppy controller, etc., in
+ * addition to an Environment Controller (Enhanced Hardware Monitor and
+ * Fan Controller)
+ *
+ * This driver supports only the Environment Controller in the IT8705F and
+ * similar parts. The other devices are supported by different drivers.
+ *
+ * Supports: IT8705F Super I/O chip w/LPC interface
+ * IT8712F Super I/O chip w/LPC interface
+ * IT8716F Super I/O chip w/LPC interface
+ * IT8718F Super I/O chip w/LPC interface
+ * IT8720F Super I/O chip w/LPC interface
+ * IT8726F Super I/O chip w/LPC interface
+ * Sis950 A clone of the IT8705F
+ *
+ * Copyright (C) 2001 Chris Gauthron
+ * Copyright (C) 2005-2010 Jean Delvare <khali@linux-fr.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>
@@ -128,6 +128,7 @@ superio_exit(void)
#define IT87_SIO_GPIO5_REG 0x29
#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
#define IT87_SIO_VID_REG 0xfc /* VID value */
+#define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */
/* Update battery voltage after every reading if true */
static int update_vbat;
@@ -187,9 +188,13 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
#define IT87_REG_VIN_ENABLE 0x50
#define IT87_REG_TEMP_ENABLE 0x51
+#define IT87_REG_BEEP_ENABLE 0x5c
#define IT87_REG_CHIPID 0x58
+#define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i))
+#define IT87_REG_AUTO_PWM(nr, i) (0x65 + (nr) * 8 + (i))
+
#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255))
#define IN_FROM_REG(val) ((val) * 16)
@@ -246,6 +251,7 @@ struct it87_sio_data {
/* Values read from Super-I/O config space */
u8 revision;
u8 vid_value;
+ u8 beep_pin;
/* Features skipped based on config or DMI */
u8 skip_vid;
u8 skip_fan;
@@ -279,9 +285,21 @@ struct it87_data {
u8 vid; /* Register encoding, combined */
u8 vrm;
u32 alarms; /* Register encoding, combined */
+ u8 beeps; /* Register encoding */
u8 fan_main_ctrl; /* Register value */
u8 fan_ctl; /* Register value */
- u8 manual_pwm_ctl[3]; /* manual PWM value set by user */
+
+ /* The following 3 arrays correspond to the same registers. The
+ * meaning of bits 6-0 depends on the value of bit 7, and we want
+ * to preserve settings on mode changes, so we have to track all
+ * values separately. */
+ u8 pwm_ctrl[3]; /* Register value */
+ u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */
+ u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */
+
+ /* Automatic fan speed control registers */
+ u8 auto_pwm[3][4]; /* [nr][3] is hard-coded */
+ s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */
};
static inline int has_16bit_fans(const struct it87_data *data)
@@ -296,6 +314,15 @@ static inline int has_16bit_fans(const struct it87_data *data)
|| data->type == it8720;
}
+static inline int has_old_autopwm(const struct it87_data *data)
+{
+ /* The old automatic fan speed control interface is implemented
+ by IT8705F chips up to revision F and IT8712F chips up to
+ revision G. */
+ return (data->type == it87 && data->revision < 0x03)
+ || (data->type == it8712 && data->revision < 0x08);
+}
+
static int it87_probe(struct platform_device *pdev);
static int __devexit it87_remove(struct platform_device *pdev);
@@ -352,7 +379,10 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- unsigned long val = simple_strtoul(buf, NULL, 10);
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val) < 0)
+ return -EINVAL;
mutex_lock(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val);
@@ -368,7 +398,10 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- unsigned long val = simple_strtoul(buf, NULL, 10);
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val) < 0)
+ return -EINVAL;
mutex_lock(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val);
@@ -441,7 +474,10 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- int val = simple_strtol(buf, NULL, 10);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0)
+ return -EINVAL;
mutex_lock(&data->update_lock);
data->temp_high[nr] = TEMP_TO_REG(val);
@@ -456,7 +492,10 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- int val = simple_strtol(buf, NULL, 10);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0)
+ return -EINVAL;
mutex_lock(&data->update_lock);
data->temp_low[nr] = TEMP_TO_REG(val);
@@ -483,8 +522,9 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = it87_update_device(dev);
- u8 reg = data->sensor; /* In case the value is updated while we use it */
-
+ u8 reg = data->sensor; /* In case the value is updated while
+ we use it */
+
if (reg & (1 << nr))
return sprintf(buf, "3\n"); /* thermal diode */
if (reg & (8 << nr))
@@ -498,12 +538,15 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- int val = simple_strtol(buf, NULL, 10);
+ long val;
+ u8 reg;
- mutex_lock(&data->update_lock);
+ if (strict_strtol(buf, 10, &val) < 0)
+ return -EINVAL;
- data->sensor &= ~(1 << nr);
- data->sensor &= ~(8 << nr);
+ reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
+ reg &= ~(1 << nr);
+ reg &= ~(8 << nr);
if (val == 2) { /* backwards compatibility */
dev_warn(dev, "Sensor type 2 is deprecated, please use 4 "
"instead\n");
@@ -511,14 +554,16 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
}
/* 3 = thermal diode; 4 = thermistor; 0 = disabled */
if (val == 3)
- data->sensor |= 1 << nr;
+ reg |= 1 << nr;
else if (val == 4)
- data->sensor |= 8 << nr;
- else if (val != 0) {
- mutex_unlock(&data->update_lock);
+ reg |= 8 << nr;
+ else if (val != 0)
return -EINVAL;
- }
+
+ mutex_lock(&data->update_lock);
+ data->sensor = reg;
it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
+ data->valid = 0; /* Force cache refresh */
mutex_unlock(&data->update_lock);
return count;
}
@@ -531,6 +576,19 @@ show_sensor_offset(2);
show_sensor_offset(3);
/* 3 Fans */
+
+static int pwm_mode(const struct it87_data *data, int nr)
+{
+ int ctrl = data->fan_main_ctrl & (1 << nr);
+
+ if (ctrl == 0) /* Full speed */
+ return 0;
+ if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
+ return 2;
+ else /* Manual mode */
+ return 1;
+}
+
static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -538,7 +596,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr],
+ return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
DIV_FROM_REG(data->fan_div[nr])));
}
static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
@@ -548,8 +606,8 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf,"%d\n",
- FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])));
+ return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+ DIV_FROM_REG(data->fan_div[nr])));
}
static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -560,14 +618,14 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
struct it87_data *data = it87_update_device(dev);
return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
}
-static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr,
- char *buf)
+static ssize_t show_pwm_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf,"%d\n", (data->fan_main_ctrl & (1 << nr)) ? 1 : 0);
+ return sprintf(buf, "%d\n", pwm_mode(data, nr));
}
static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -576,7 +634,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]);
+ return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm_duty[nr]));
}
static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -593,15 +651,24 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- int val = simple_strtol(buf, NULL, 10);
+ long val;
u8 reg;
+ if (strict_strtol(buf, 10, &val) < 0)
+ return -EINVAL;
+
mutex_lock(&data->update_lock);
reg = it87_read_value(data, IT87_REG_FAN_DIV);
switch (nr) {
- case 0: data->fan_div[nr] = reg & 0x07; break;
- case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break;
- case 2: data->fan_div[nr] = (reg & 0x40) ? 3 : 1; break;
+ case 0:
+ data->fan_div[nr] = reg & 0x07;
+ break;
+ case 1:
+ data->fan_div[nr] = (reg >> 3) & 0x07;
+ break;
+ case 2:
+ data->fan_div[nr] = (reg & 0x40) ? 3 : 1;
+ break;
}
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -616,10 +683,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- unsigned long val = simple_strtoul(buf, NULL, 10);
+ unsigned long val;
int min;
u8 old;
+ if (strict_strtoul(buf, 10, &val) < 0)
+ return -EINVAL;
+
mutex_lock(&data->update_lock);
old = it87_read_value(data, IT87_REG_FAN_DIV);
@@ -651,6 +721,32 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
mutex_unlock(&data->update_lock);
return count;
}
+
+/* Returns 0 if OK, -EINVAL otherwise */
+static int check_trip_points(struct device *dev, int nr)
+{
+ const struct it87_data *data = dev_get_drvdata(dev);
+ int i, err = 0;
+
+ if (has_old_autopwm(data)) {
+ for (i = 0; i < 3; i++) {
+ if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
+ err = -EINVAL;
+ }
+ for (i = 0; i < 2; i++) {
+ if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
+ err = -EINVAL;
+ }
+ }
+
+ if (err) {
+ dev_err(dev, "Inconsistent trip points, not switching to "
+ "automatic mode\n");
+ dev_err(dev, "Adjust the trip points and try again\n");
+ }
+ return err;
+}
+
static ssize_t set_pwm_enable(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
@@ -658,7 +754,16 @@ static ssize_t set_pwm_enable(struct device *dev,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- int val = simple_strtol(buf, NULL, 10);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 2)
+ return -EINVAL;
+
+ /* Check trip points before switching to automatic mode */
+ if (val == 2) {
+ if (check_trip_points(dev, nr) < 0)
+ return -EINVAL;
+ }
mutex_lock(&data->update_lock);
@@ -669,16 +774,18 @@ static ssize_t set_pwm_enable(struct device *dev,
it87_write_value(data, IT87_REG_FAN_CTL, tmp | (1 << nr));
/* set on/off mode */
data->fan_main_ctrl &= ~(1 << nr);
- it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
- } else if (val == 1) {
+ it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+ data->fan_main_ctrl);
+ } else {
+ if (val == 1) /* Manual mode */
+ data->pwm_ctrl[nr] = data->pwm_duty[nr];
+ else /* Automatic mode */
+ data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
+ it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
/* set SmartGuardian mode */
data->fan_main_ctrl |= (1 << nr);
- it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
- /* set saved pwm value, clear FAN_CTLX PWM mode bit */
- it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
- } else {
- mutex_unlock(&data->update_lock);
- return -EINVAL;
+ it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+ data->fan_main_ctrl);
}
mutex_unlock(&data->update_lock);
@@ -691,15 +798,19 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- int val = simple_strtol(buf, NULL, 10);
+ long val;
- if (val < 0 || val > 255)
+ if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 255)
return -EINVAL;
mutex_lock(&data->update_lock);
- data->manual_pwm_ctl[nr] = val;
- if (data->fan_main_ctrl & (1 << nr))
- it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
+ data->pwm_duty[nr] = PWM_TO_REG(val);
+ /* If we are in manual mode, write the duty cycle immediately;
+ * otherwise, just store it for later use. */
+ if (!(data->pwm_ctrl[nr] & 0x80)) {
+ data->pwm_ctrl[nr] = data->pwm_duty[nr];
+ it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
+ }
mutex_unlock(&data->update_lock);
return count;
}
@@ -707,9 +818,12 @@ static ssize_t set_pwm_freq(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct it87_data *data = dev_get_drvdata(dev);
- unsigned long val = simple_strtoul(buf, NULL, 10);
+ unsigned long val;
int i;
+ if (strict_strtoul(buf, 10, &val) < 0)
+ return -EINVAL;
+
/* Search for the nearest available frequency */
for (i = 0; i < 7; i++) {
if (val > (pwm_freq[i] + pwm_freq[i+1]) / 2)
@@ -724,6 +838,132 @@ static ssize_t set_pwm_freq(struct device *dev,
return count;
}
+static ssize_t show_pwm_temp_map(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+
+ struct it87_data *data = it87_update_device(dev);
+ int map;
+
+ if (data->pwm_temp_map[nr] < 3)
+ map = 1 << data->pwm_temp_map[nr];
+ else
+ map = 0; /* Should never happen */
+ return sprintf(buf, "%d\n", map);
+}
+static ssize_t set_pwm_temp_map(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+
+ struct it87_data *data = dev_get_drvdata(dev);
+ long val;
+ u8 reg;
+
+ /* This check can go away if we ever support automatic fan speed
+ control on newer chips. */
+ if (!has_old_autopwm(data)) {
+ dev_notice(dev, "Mapping change disabled for safety reasons\n");
+ return -EINVAL;
+ }
+
+ if (strict_strtol(buf, 10, &val) < 0)
+ return -EINVAL;
+
+ switch (val) {
+ case (1 << 0):
+ reg = 0x00;
+ break;
+ case (1 << 1):
+ reg = 0x01;
+ break;
+ case (1 << 2):
+ reg = 0x02;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->update_lock);
+ data->pwm_temp_map[nr] = reg;
+ /* If we are in automatic mode, write the temp mapping immediately;
+ * otherwise, just store it for later use. */
+ if (data->pwm_ctrl[nr] & 0x80) {
+ data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
+ it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
+ }
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t show_auto_pwm(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct it87_data *data = it87_update_device(dev);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int point = sensor_attr->index;
+
+ return sprintf(buf, "%d\n", PWM_FROM_REG(data->auto_pwm[nr][point]));
+}
+
+static ssize_t set_auto_pwm(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct it87_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int point = sensor_attr->index;
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 255)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->auto_pwm[nr][point] = PWM_TO_REG(val);
+ it87_write_value(data, IT87_REG_AUTO_PWM(nr, point),
+ data->auto_pwm[nr][point]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t show_auto_temp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct it87_data *data = it87_update_device(dev);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int point = sensor_attr->index;
+
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->auto_temp[nr][point]));
+}
+
+static ssize_t set_auto_temp(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct it87_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+ int nr = sensor_attr->nr;
+ int point = sensor_attr->index;
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0 || val < -128000 || val > 127000)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->auto_temp[nr][point] = TEMP_TO_REG(val);
+ it87_write_value(data, IT87_REG_AUTO_TEMP(nr, point),
+ data->auto_temp[nr][point]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
#define show_fan_offset(offset) \
static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
@@ -744,7 +984,36 @@ static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm, set_pwm, offset - 1); \
static DEVICE_ATTR(pwm##offset##_freq, \
(offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO), \
- show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL));
+ show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL)); \
+static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels_temp, \
+ S_IRUGO | S_IWUSR, show_pwm_temp_map, set_pwm_temp_map, \
+ offset - 1); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_pwm, \
+ S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \
+ offset - 1, 0); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_pwm, \
+ S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \
+ offset - 1, 1); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_pwm, \
+ S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \
+ offset - 1, 2); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_pwm, \
+ S_IRUGO, show_auto_pwm, NULL, offset - 1, 3); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp, \
+ S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
+ offset - 1, 1); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp_hyst, \
+ S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
+ offset - 1, 0); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_temp, \
+ S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
+ offset - 1, 2); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_temp, \
+ S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
+ offset - 1, 3); \
+static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_temp, \
+ S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
+ offset - 1, 4);
show_pwm_offset(1);
show_pwm_offset(2);
@@ -775,7 +1044,10 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr,
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
struct it87_data *data = dev_get_drvdata(dev);
- int val = simple_strtol(buf, NULL, 10);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0)
+ return -EINVAL;
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN16_TO_REG(val);
@@ -805,7 +1077,8 @@ show_fan16_offset(4);
show_fan16_offset(5);
/* Alarms */
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf, "%u\n", data->alarms);
@@ -836,27 +1109,78 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
-static ssize_t
-show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ int bitnr = to_sensor_dev_attr(attr)->index;
+ struct it87_data *data = it87_update_device(dev);
+ return sprintf(buf, "%u\n", (data->beeps >> bitnr) & 1);
+}
+static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int bitnr = to_sensor_dev_attr(attr)->index;
+ struct it87_data *data = dev_get_drvdata(dev);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) < 0
+ || (val != 0 && val != 1))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
+ if (val)
+ data->beeps |= (1 << bitnr);
+ else
+ data->beeps &= ~(1 << bitnr);
+ it87_write_value(data, IT87_REG_BEEP_ENABLE, data->beeps);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR,
+ show_beep, set_beep, 1);
+static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO, show_beep, NULL, 1);
+/* fanX_beep writability is set later */
+static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
+ show_beep, set_beep, 2);
+static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2);
+
+static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct it87_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", data->vrm);
}
-static ssize_t
-store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct it87_data *data = dev_get_drvdata(dev);
- u32 val;
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val) < 0)
+ return -EINVAL;
- val = simple_strtoul(buf, NULL, 10);
data->vrm = val;
return count;
}
static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-static ssize_t
-show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct it87_data *data = it87_update_device(dev);
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
@@ -931,51 +1255,176 @@ static const struct attribute_group it87_group = {
.attrs = it87_attributes,
};
-static struct attribute *it87_attributes_opt[] = {
+static struct attribute *it87_attributes_beep[] = {
+ &sensor_dev_attr_in0_beep.dev_attr.attr,
+ &sensor_dev_attr_in1_beep.dev_attr.attr,
+ &sensor_dev_attr_in2_beep.dev_attr.attr,
+ &sensor_dev_attr_in3_beep.dev_attr.attr,
+ &sensor_dev_attr_in4_beep.dev_attr.attr,
+ &sensor_dev_attr_in5_beep.dev_attr.attr,
+ &sensor_dev_attr_in6_beep.dev_attr.attr,
+ &sensor_dev_attr_in7_beep.dev_attr.attr,
+
+ &sensor_dev_attr_temp1_beep.dev_attr.attr,
+ &sensor_dev_attr_temp2_beep.dev_attr.attr,
+ &sensor_dev_attr_temp3_beep.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group it87_group_beep = {
+ .attrs = it87_attributes_beep,
+};
+
+static struct attribute *it87_attributes_fan16[5][3+1] = { {
&sensor_dev_attr_fan1_input16.dev_attr.attr,
&sensor_dev_attr_fan1_min16.dev_attr.attr,
+ &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+ NULL
+}, {
&sensor_dev_attr_fan2_input16.dev_attr.attr,
&sensor_dev_attr_fan2_min16.dev_attr.attr,
+ &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+ NULL
+}, {
&sensor_dev_attr_fan3_input16.dev_attr.attr,
&sensor_dev_attr_fan3_min16.dev_attr.attr,
+ &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+ NULL
+}, {
&sensor_dev_attr_fan4_input16.dev_attr.attr,
&sensor_dev_attr_fan4_min16.dev_attr.attr,
+ &sensor_dev_attr_fan4_alarm.dev_attr.attr,
+ NULL
+}, {
&sensor_dev_attr_fan5_input16.dev_attr.attr,
&sensor_dev_attr_fan5_min16.dev_attr.attr,
+ &sensor_dev_attr_fan5_alarm.dev_attr.attr,
+ NULL
+} };
+
+static const struct attribute_group it87_group_fan16[5] = {
+ { .attrs = it87_attributes_fan16[0] },
+ { .attrs = it87_attributes_fan16[1] },
+ { .attrs = it87_attributes_fan16[2] },
+ { .attrs = it87_attributes_fan16[3] },
+ { .attrs = it87_attributes_fan16[4] },
+};
+static struct attribute *it87_attributes_fan[3][4+1] = { {
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan1_min.dev_attr.attr,
&sensor_dev_attr_fan1_div.dev_attr.attr,
+ &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+ NULL
+}, {
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan2_min.dev_attr.attr,
&sensor_dev_attr_fan2_div.dev_attr.attr,
+ &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+ NULL
+}, {
&sensor_dev_attr_fan3_input.dev_attr.attr,
&sensor_dev_attr_fan3_min.dev_attr.attr,
&sensor_dev_attr_fan3_div.dev_attr.attr,
-
- &sensor_dev_attr_fan1_alarm.dev_attr.attr,
- &sensor_dev_attr_fan2_alarm.dev_attr.attr,
&sensor_dev_attr_fan3_alarm.dev_attr.attr,
- &sensor_dev_attr_fan4_alarm.dev_attr.attr,
- &sensor_dev_attr_fan5_alarm.dev_attr.attr,
+ NULL
+} };
+
+static const struct attribute_group it87_group_fan[3] = {
+ { .attrs = it87_attributes_fan[0] },
+ { .attrs = it87_attributes_fan[1] },
+ { .attrs = it87_attributes_fan[2] },
+};
+
+static const struct attribute_group *
+it87_get_fan_group(const struct it87_data *data)
+{
+ return has_16bit_fans(data) ? it87_group_fan16 : it87_group_fan;
+}
+static struct attribute *it87_attributes_pwm[3][4+1] = { {
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
- &sensor_dev_attr_pwm2_enable.dev_attr.attr,
- &sensor_dev_attr_pwm3_enable.dev_attr.attr,
&sensor_dev_attr_pwm1.dev_attr.attr,
- &sensor_dev_attr_pwm2.dev_attr.attr,
- &sensor_dev_attr_pwm3.dev_attr.attr,
&dev_attr_pwm1_freq.attr,
+ &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
+ NULL
+}, {
+ &sensor_dev_attr_pwm2_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm2.dev_attr.attr,
&dev_attr_pwm2_freq.attr,
+ &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
+ NULL
+}, {
+ &sensor_dev_attr_pwm3_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm3.dev_attr.attr,
&dev_attr_pwm3_freq.attr,
+ &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
+ NULL
+} };
+
+static const struct attribute_group it87_group_pwm[3] = {
+ { .attrs = it87_attributes_pwm[0] },
+ { .attrs = it87_attributes_pwm[1] },
+ { .attrs = it87_attributes_pwm[2] },
+};
+static struct attribute *it87_attributes_autopwm[3][9+1] = { {
+ &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point1_temp_hyst.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
+ NULL
+}, {
+ &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point1_temp_hyst.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr,
+ NULL
+}, {
+ &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point4_pwm.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point1_temp_hyst.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
+ &sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr,
+ NULL
+} };
+
+static const struct attribute_group it87_group_autopwm[3] = {
+ { .attrs = it87_attributes_autopwm[0] },
+ { .attrs = it87_attributes_autopwm[1] },
+ { .attrs = it87_attributes_autopwm[2] },
+};
+
+static struct attribute *it87_attributes_fan_beep[] = {
+ &sensor_dev_attr_fan1_beep.dev_attr.attr,
+ &sensor_dev_attr_fan2_beep.dev_attr.attr,
+ &sensor_dev_attr_fan3_beep.dev_attr.attr,
+ &sensor_dev_attr_fan4_beep.dev_attr.attr,
+ &sensor_dev_attr_fan5_beep.dev_attr.attr,
+};
+
+static struct attribute *it87_attributes_vid[] = {
&dev_attr_vrm.attr,
&dev_attr_cpu0_vid.attr,
NULL
};
-static const struct attribute_group it87_group_opt = {
- .attrs = it87_attributes_opt,
+static const struct attribute_group it87_group_vid = {
+ .attrs = it87_attributes_vid,
};
/* SuperIO detection - will change isa_address if a chip is found */
@@ -1035,6 +1484,10 @@ static int __init it87_find(unsigned short *address,
if (sio_data->type == it87) {
/* The IT8705F doesn't have VID pins at all */
sio_data->skip_vid = 1;
+
+ /* The IT8705F has a different LD number for GPIO */
+ superio_select(5);
+ sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
} else {
int reg;
@@ -1068,7 +1521,11 @@ static int __init it87_find(unsigned short *address,
pr_info("it87: in3 is VCC (+5V)\n");
if (reg & (1 << 1))
pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
+
+ sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
}
+ if (sio_data->beep_pin)
+ pr_info("it87: Beeping is supported\n");
/* Disable specific features based on DMI strings */
board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -1093,14 +1550,46 @@ exit:
return err;
}
+static void it87_remove_files(struct device *dev)
+{
+ struct it87_data *data = platform_get_drvdata(pdev);
+ struct it87_sio_data *sio_data = dev->platform_data;
+ const struct attribute_group *fan_group = it87_get_fan_group(data);
+ int i;
+
+ sysfs_remove_group(&dev->kobj, &it87_group);
+ if (sio_data->beep_pin)
+ sysfs_remove_group(&dev->kobj, &it87_group_beep);
+ for (i = 0; i < 5; i++) {
+ if (!(data->has_fan & (1 << i)))
+ continue;
+ sysfs_remove_group(&dev->kobj, &fan_group[i]);
+ if (sio_data->beep_pin)
+ sysfs_remove_file(&dev->kobj,
+ it87_attributes_fan_beep[i]);
+ }
+ for (i = 0; i < 3; i++) {
+ if (sio_data->skip_pwm & (1 << 0))
+ continue;
+ sysfs_remove_group(&dev->kobj, &it87_group_pwm[i]);
+ if (has_old_autopwm(data))
+ sysfs_remove_group(&dev->kobj,
+ &it87_group_autopwm[i]);
+ }
+ if (!sio_data->skip_vid)
+ sysfs_remove_group(&dev->kobj, &it87_group_vid);
+}
+
static int __devinit it87_probe(struct platform_device *pdev)
{
struct it87_data *data;
struct resource *res;
struct device *dev = &pdev->dev;
struct it87_sio_data *sio_data = dev->platform_data;
- int err = 0;
+ const struct attribute_group *fan_group;
+ int err = 0, i;
int enable_pwm_interface;
+ int fan_beep_need_rw;
static const char *names[] = {
"it87",
"it8712",
@@ -1118,7 +1607,8 @@ static int __devinit it87_probe(struct platform_device *pdev)
goto ERROR0;
}
- if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) {
+ data = kzalloc(sizeof(struct it87_data), GFP_KERNEL);
+ if (!data) {
err = -ENOMEM;
goto ERROR1;
}
@@ -1146,120 +1636,60 @@ static int __devinit it87_probe(struct platform_device *pdev)
it87_init_device(pdev);
/* Register sysfs hooks */
- if ((err = sysfs_create_group(&dev->kobj, &it87_group)))
+ err = sysfs_create_group(&dev->kobj, &it87_group);
+ if (err)
goto ERROR2;
+ if (sio_data->beep_pin) {
+ err = sysfs_create_group(&dev->kobj, &it87_group_beep);
+ if (err)
+ goto ERROR4;
+ }
+
/* Do not create fan files for disabled fans */
- if (has_16bit_fans(data)) {
- /* 16-bit tachometers */
- if (data->has_fan & (1 << 0)) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_fan1_input16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan1_min16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan1_alarm.dev_attr)))
- goto ERROR4;
- }
- if (data->has_fan & (1 << 1)) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_fan2_input16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan2_min16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan2_alarm.dev_attr)))
- goto ERROR4;
- }
- if (data->has_fan & (1 << 2)) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_fan3_input16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan3_min16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan3_alarm.dev_attr)))
- goto ERROR4;
- }
- if (data->has_fan & (1 << 3)) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_fan4_input16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan4_min16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan4_alarm.dev_attr)))
- goto ERROR4;
- }
- if (data->has_fan & (1 << 4)) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_fan5_input16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan5_min16.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan5_alarm.dev_attr)))
- goto ERROR4;
- }
- } else {
- /* 8-bit tachometers with clock divider */
- if (data->has_fan & (1 << 0)) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_fan1_input.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan1_min.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan1_div.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan1_alarm.dev_attr)))
- goto ERROR4;
- }
- if (data->has_fan & (1 << 1)) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_fan2_input.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan2_min.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan2_div.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan2_alarm.dev_attr)))
- goto ERROR4;
- }
- if (data->has_fan & (1 << 2)) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_fan3_input.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan3_min.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan3_div.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_fan3_alarm.dev_attr)))
+ fan_group = it87_get_fan_group(data);
+ fan_beep_need_rw = 1;
+ for (i = 0; i < 5; i++) {
+ if (!(data->has_fan & (1 << i)))
+ continue;
+ err = sysfs_create_group(&dev->kobj, &fan_group[i]);
+ if (err)
+ goto ERROR4;
+
+ if (sio_data->beep_pin) {
+ err = sysfs_create_file(&dev->kobj,
+ it87_attributes_fan_beep[i]);
+ if (err)
goto ERROR4;
+ if (!fan_beep_need_rw)
+ continue;
+
+ /* As we have a single beep enable bit for all fans,
+ * only the first enabled fan has a writable attribute
+ * for it. */
+ if (sysfs_chmod_file(&dev->kobj,
+ it87_attributes_fan_beep[i],
+ S_IRUGO | S_IWUSR))
+ dev_dbg(dev, "chmod +w fan%d_beep failed\n",
+ i + 1);
+ fan_beep_need_rw = 0;
}
}
if (enable_pwm_interface) {
- if (!(sio_data->skip_pwm & (1 << 0))) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_pwm1_enable.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_pwm1.dev_attr))
- || (err = device_create_file(dev,
- &dev_attr_pwm1_freq)))
- goto ERROR4;
- }
- if (!(sio_data->skip_pwm & (1 << 1))) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_pwm2_enable.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_pwm2.dev_attr))
- || (err = device_create_file(dev,
- &dev_attr_pwm2_freq)))
+ for (i = 0; i < 3; i++) {
+ if (sio_data->skip_pwm & (1 << i))
+ continue;
+ err = sysfs_create_group(&dev->kobj,
+ &it87_group_pwm[i]);
+ if (err)
goto ERROR4;
- }
- if (!(sio_data->skip_pwm & (1 << 2))) {
- if ((err = device_create_file(dev,
- &sensor_dev_attr_pwm3_enable.dev_attr))
- || (err = device_create_file(dev,
- &sensor_dev_attr_pwm3.dev_attr))
- || (err = device_create_file(dev,
- &dev_attr_pwm3_freq)))
+
+ if (!has_old_autopwm(data))
+ continue;
+ err = sysfs_create_group(&dev->kobj,
+ &it87_group_autopwm[i]);
+ if (err)
goto ERROR4;
}
}
@@ -1268,10 +1698,8 @@ static int __devinit it87_probe(struct platform_device *pdev)
data->vrm = vid_which_vrm();
/* VID reading from Super-I/O config space if available */
data->vid = sio_data->vid_value;
- if ((err = device_create_file(dev,
- &dev_attr_vrm))
- || (err = device_create_file(dev,
- &dev_attr_cpu0_vid)))
+ err = sysfs_create_group(&dev->kobj, &it87_group_vid);
+ if (err)
goto ERROR4;
}
@@ -1284,8 +1712,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
return 0;
ERROR4:
- sysfs_remove_group(&dev->kobj, &it87_group);
- sysfs_remove_group(&dev->kobj, &it87_group_opt);
+ it87_remove_files(dev);
ERROR2:
platform_set_drvdata(pdev, NULL);
kfree(data);
@@ -1300,8 +1727,7 @@ static int __devexit it87_remove(struct platform_device *pdev)
struct it87_data *data = platform_get_drvdata(pdev);
hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&pdev->dev.kobj, &it87_group);
- sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt);
+ it87_remove_files(&pdev->dev);
release_region(data->addr, IT87_EC_EXTENT);
platform_set_drvdata(pdev, NULL);
@@ -1387,15 +1813,18 @@ static void __devinit it87_init_device(struct platform_device *pdev)
int tmp, i;
u8 mask;
- /* initialize to sane defaults:
- * - if the chip is in manual pwm mode, this will be overwritten with
- * the actual settings on the chip (so in this case, initialization
- * is not needed)
- * - if in automatic or on/off mode, we could switch to manual mode,
- * read the registers and set manual_pwm_ctl accordingly, but currently
- * this is not implemented, so we initialize to something sane */
+ /* For each PWM channel:
+ * - If it is in automatic mode, setting to manual mode should set
+ * the fan to full speed by default.
+ * - If it is in manual mode, we need a mapping to temperature
+ * channels to use when later setting to automatic mode later.
+ * Use a 1:1 mapping by default (we are clueless.)
+ * In both cases, the value can (and should) be changed by the user
+ * prior to switching to a different mode. */
for (i = 0; i < 3; i++) {
- data->manual_pwm_ctl[i] = 0xff;
+ data->pwm_temp_map[i] = i;
+ data->pwm_duty[i] = 0x7f; /* Full speed */
+ data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */
}
/* Some chips seem to have default value 0xff for all limit
@@ -1414,14 +1843,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
}
- /* Check if temperature channels are reset manually or by some reason */
- tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE);
- if ((tmp & 0x3f) == 0) {
- /* Temp1,Temp3=thermistor; Temp2=thermal diode */
- tmp = (tmp & 0xc0) | 0x2a;
- it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp);
- }
- data->sensor = tmp;
+ /* Temperature channels are not forcibly enabled, as they can be
+ * set to two different sensor types and we can't guess which one
+ * is correct for a given system. These channels can be enabled at
+ * run-time through the temp{1-3}_type sysfs accessors if needed. */
/* Check if voltage monitors are reset manually or by some reason */
tmp = it87_read_value(data, IT87_REG_VIN_ENABLE);
@@ -1436,7 +1861,8 @@ static void __devinit it87_init_device(struct platform_device *pdev)
if ((data->fan_main_ctrl & mask) == 0) {
/* Enable all fan tachometers */
data->fan_main_ctrl |= mask;
- it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
+ it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+ data->fan_main_ctrl);
}
data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
@@ -1461,30 +1887,32 @@ static void __devinit it87_init_device(struct platform_device *pdev)
/* Fan input pins may be used for alternative functions */
data->has_fan &= ~sio_data->skip_fan;
- /* Set current fan mode registers and the default settings for the
- * other mode registers */
- for (i = 0; i < 3; i++) {
- if (data->fan_main_ctrl & (1 << i)) {
- /* pwm mode */
- tmp = it87_read_value(data, IT87_REG_PWM(i));
- if (tmp & 0x80) {
- /* automatic pwm - not yet implemented, but
- * leave the settings made by the BIOS alone
- * until a change is requested via the sysfs
- * interface */
- } else {
- /* manual pwm */
- data->manual_pwm_ctl[i] = PWM_FROM_REG(tmp);
- }
- }
- }
-
/* Start monitoring */
it87_write_value(data, IT87_REG_CONFIG,
(it87_read_value(data, IT87_REG_CONFIG) & 0x36)
| (update_vbat ? 0x41 : 0x01));
}
+static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
+{
+ data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
+ if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
+ data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+ else /* Manual mode */
+ data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+
+ if (has_old_autopwm(data)) {
+ int i;
+
+ for (i = 0; i < 5 ; i++)
+ data->auto_temp[nr][i] = it87_read_value(data,
+ IT87_REG_AUTO_TEMP(nr, i));
+ for (i = 0; i < 3 ; i++)
+ data->auto_pwm[nr][i] = it87_read_value(data,
+ IT87_REG_AUTO_PWM(nr, i));
+ }
+}
+
static struct it87_data *it87_update_device(struct device *dev)
{
struct it87_data *data = dev_get_drvdata(dev);
@@ -1494,24 +1922,22 @@ static struct it87_data *it87_update_device(struct device *dev)
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
-
if (update_vbat) {
/* Cleared after each update, so reenable. Value
- returned by this read will be previous value */
+ returned by this read will be previous value */
it87_write_value(data, IT87_REG_CONFIG,
- it87_read_value(data, IT87_REG_CONFIG) | 0x40);
+ it87_read_value(data, IT87_REG_CONFIG) | 0x40);
}
for (i = 0; i <= 7; i++) {
data->in[i] =
- it87_read_value(data, IT87_REG_VIN(i));
+ it87_read_value(data, IT87_REG_VIN(i));
data->in_min[i] =
- it87_read_value(data, IT87_REG_VIN_MIN(i));
+ it87_read_value(data, IT87_REG_VIN_MIN(i));
data->in_max[i] =
- it87_read_value(data, IT87_REG_VIN_MAX(i));
+ it87_read_value(data, IT87_REG_VIN_MAX(i));
}
/* in8 (battery) has no limit registers */
- data->in[8] =
- it87_read_value(data, IT87_REG_VIN(8));
+ data->in[8] = it87_read_value(data, IT87_REG_VIN(8));
for (i = 0; i < 5; i++) {
/* Skip disabled fans */
@@ -1519,7 +1945,7 @@ static struct it87_data *it87_update_device(struct device *dev)
continue;
data->fan_min[i] =
- it87_read_value(data, IT87_REG_FAN_MIN[i]);
+ it87_read_value(data, IT87_REG_FAN_MIN[i]);
data->fan[i] = it87_read_value(data,
IT87_REG_FAN[i]);
/* Add high byte if in 16-bit mode */
@@ -1532,11 +1958,11 @@ static struct it87_data *it87_update_device(struct device *dev)
}
for (i = 0; i < 3; i++) {
data->temp[i] =
- it87_read_value(data, IT87_REG_TEMP(i));
+ it87_read_value(data, IT87_REG_TEMP(i));
data->temp_high[i] =
- it87_read_value(data, IT87_REG_TEMP_HIGH(i));
+ it87_read_value(data, IT87_REG_TEMP_HIGH(i));
data->temp_low[i] =
- it87_read_value(data, IT87_REG_TEMP_LOW(i));
+ it87_read_value(data, IT87_REG_TEMP_LOW(i));
}
/* Newer chips don't have clock dividers */
@@ -1551,9 +1977,13 @@ static struct it87_data *it87_update_device(struct device *dev)
it87_read_value(data, IT87_REG_ALARM1) |
(it87_read_value(data, IT87_REG_ALARM2) << 8) |
(it87_read_value(data, IT87_REG_ALARM3) << 16);
+ data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
+
data->fan_main_ctrl = it87_read_value(data,
IT87_REG_FAN_MAIN_CTRL);
data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL);
+ for (i = 0; i < 3; i++)
+ it87_update_pwm_ctrl(data, i);
data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
/* The 8705 does not have VID capability.
@@ -1628,7 +2058,7 @@ exit:
static int __init sm_it87_init(void)
{
int err;
- unsigned short isa_address=0;
+ unsigned short isa_address = 0;
struct it87_sio_data sio_data;
memset(&sio_data, 0, sizeof(struct it87_sio_data));
@@ -1640,7 +2070,7 @@ static int __init sm_it87_init(void)
return err;
err = it87_device_add(isa_address, &sio_data);
- if (err){
+ if (err) {
platform_driver_unregister(&it87_driver);
return err;
}
@@ -1661,7 +2091,8 @@ MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8720F/8726F, SiS950 driver");
module_param(update_vbat, bool, 0);
MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
module_param(fix_pwm_polarity, bool, 0);
-MODULE_PARM_DESC(fix_pwm_polarity, "Force PWM polarity to active high (DANGEROUS)");
+MODULE_PARM_DESC(fix_pwm_polarity,
+ "Force PWM polarity to active high (DANGEROUS)");
MODULE_LICENSE("GPL");
module_init(sm_it87_init);
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index ab8a5d3c769..fd108cfc05c 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -34,6 +34,7 @@
#include <linux/mutex.h>
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#define DRVNAME "lm70"
diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c
index c5f39ba103c..4d1b76bc814 100644
--- a/drivers/hwmon/lm73.c
+++ b/drivers/hwmon/lm73.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 7c9bdc16742..7cc2708871a 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -1,7 +1,7 @@
/*
* lm90.c - Part of lm_sensors, Linux kernel modules for hardware
* monitoring
- * Copyright (C) 2003-2009 Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
*
* Based on the lm83 driver. The LM90 is a sensor chip made by National
* Semiconductor. It reports up to two temperatures (its own plus up to
@@ -93,7 +93,8 @@
static const unsigned short normal_i2c[] = {
0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
-enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646 };
+enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646,
+ w83l771 };
/*
* The LM90 registers
@@ -151,6 +152,7 @@ static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info);
static int lm90_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static void lm90_init_client(struct i2c_client *client);
+static void lm90_alert(struct i2c_client *client, unsigned int flag);
static int lm90_remove(struct i2c_client *client);
static struct lm90_data *lm90_update_device(struct device *dev);
@@ -173,6 +175,7 @@ static const struct i2c_device_id lm90_id[] = {
{ "max6659", max6657 },
{ "max6680", max6680 },
{ "max6681", max6680 },
+ { "w83l771", w83l771 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm90_id);
@@ -184,6 +187,7 @@ static struct i2c_driver lm90_driver = {
},
.probe = lm90_probe,
.remove = lm90_remove,
+ .alert = lm90_alert,
.id_table = lm90_id,
.detect = lm90_detect,
.address_list = normal_i2c,
@@ -201,6 +205,9 @@ struct lm90_data {
int kind;
int flags;
+ u8 config_orig; /* Original configuration register value */
+ u8 alert_alarms; /* Which alarm bits trigger ALERT# */
+
/* registers values */
s8 temp8[4]; /* 0: local low limit
1: local high limit
@@ -758,6 +765,14 @@ static int lm90_detect(struct i2c_client *new_client,
&& reg_convrate <= 0x07) {
name = "max6646";
}
+ } else
+ if (address == 0x4C
+ && man_id == 0x5C) { /* Winbond/Nuvoton */
+ if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */
+ && (reg_config1 & 0x2A) == 0x00
+ && reg_convrate <= 0x08) {
+ name = "w83l771";
+ }
}
if (!name) { /* identification failed */
@@ -794,6 +809,19 @@ static int lm90_probe(struct i2c_client *new_client,
new_client->flags &= ~I2C_CLIENT_PEC;
}
+ /* Different devices have different alarm bits triggering the
+ * ALERT# output */
+ switch (data->kind) {
+ case lm90:
+ case lm99:
+ case lm86:
+ data->alert_alarms = 0x7b;
+ break;
+ default:
+ data->alert_alarms = 0x7c;
+ break;
+ }
+
/* Initialize the LM90 chip */
lm90_init_client(new_client);
@@ -830,7 +858,7 @@ exit:
static void lm90_init_client(struct i2c_client *client)
{
- u8 config, config_orig;
+ u8 config;
struct lm90_data *data = i2c_get_clientdata(client);
/*
@@ -842,7 +870,7 @@ static void lm90_init_client(struct i2c_client *client)
dev_warn(&client->dev, "Initialization failed!\n");
return;
}
- config_orig = config;
+ data->config_orig = config;
/* Check Temperature Range Select */
if (data->kind == adt7461) {
@@ -860,7 +888,7 @@ static void lm90_init_client(struct i2c_client *client)
}
config &= 0xBF; /* run */
- if (config != config_orig) /* Only write if changed */
+ if (config != data->config_orig) /* Only write if changed */
i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
}
@@ -875,10 +903,46 @@ static int lm90_remove(struct i2c_client *client)
device_remove_file(&client->dev,
&sensor_dev_attr_temp2_offset.dev_attr);
+ /* Restore initial configuration */
+ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+ data->config_orig);
+
kfree(data);
return 0;
}
+static void lm90_alert(struct i2c_client *client, unsigned int flag)
+{
+ struct lm90_data *data = i2c_get_clientdata(client);
+ u8 config, alarms;
+
+ lm90_read_reg(client, LM90_REG_R_STATUS, &alarms);
+ if ((alarms & 0x7f) == 0) {
+ dev_info(&client->dev, "Everything OK\n");
+ } else {
+ if (alarms & 0x61)
+ dev_warn(&client->dev,
+ "temp%d out of range, please check!\n", 1);
+ if (alarms & 0x1a)
+ dev_warn(&client->dev,
+ "temp%d out of range, please check!\n", 2);
+ if (alarms & 0x04)
+ dev_warn(&client->dev,
+ "temp%d diode open, please check!\n", 2);
+
+ /* Disable ALERT# output, because these chips don't implement
+ SMBus alert correctly; they should only hold the alert line
+ low briefly. */
+ if ((data->kind == adm1032 || data->kind == adt7461)
+ && (alarms & data->alert_alarms)) {
+ dev_dbg(&client->dev, "Disabling ALERT#\n");
+ lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
+ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+ config | 0x80);
+ }
+ }
+}
+
static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
{
int err;
@@ -966,6 +1030,21 @@ static struct lm90_data *lm90_update_device(struct device *dev)
}
lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
+ /* Re-enable ALERT# output if it was originally enabled and
+ * relevant alarms are all clear */
+ if ((data->config_orig & 0x80) == 0
+ && (data->alarms & data->alert_alarms) == 0) {
+ u8 config;
+
+ lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
+ if (config & 0x80) {
+ dev_dbg(&client->dev, "Re-enabling ALERT#\n");
+ i2c_smbus_write_byte_data(client,
+ LM90_REG_W_CONFIG1,
+ config & ~0x80);
+ }
+ }
+
data->last_updated = jiffies;
data->valid = 1;
}
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
index 9ac497271ad..12a54aa2977 100644
--- a/drivers/hwmon/max1111.c
+++ b/drivers/hwmon/max1111.c
@@ -20,6 +20,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#define MAX1111_TX_BUF_SIZE 1
#define MAX1111_RX_BUF_SIZE 2
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
index 883fa8197da..ce3c7bc8181 100644
--- a/drivers/hwmon/mc13783-adc.c
+++ b/drivers/hwmon/mc13783-adc.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hwmon.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/err.h>
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index 864a371f6eb..a610e7880fb 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -36,6 +36,7 @@
#include <linux/err.h>
#include <linux/sht15.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#define SHT15_MEASURE_TEMP 3
@@ -302,13 +303,13 @@ error_ret:
**/
static inline int sht15_calc_temp(struct sht15_data *data)
{
- int d1 = 0;
+ int d1 = temppoints[0].d1;
int i;
- for (i = 1; i < ARRAY_SIZE(temppoints); i++)
+ for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--)
/* Find pointer to interpolate */
if (data->supply_uV > temppoints[i - 1].vdd) {
- d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+ d1 = (data->supply_uV - temppoints[i - 1].vdd)
* (temppoints[i].d1 - temppoints[i - 1].d1)
/ (temppoints[i].vdd - temppoints[i - 1].vdd)
+ temppoints[i - 1].d1;
@@ -541,7 +542,12 @@ static int __devinit sht15_probe(struct platform_device *pdev)
/* If a regulator is available, query what the supply voltage actually is!*/
data->reg = regulator_get(data->dev, "vcc");
if (!IS_ERR(data->reg)) {
- data->supply_uV = regulator_get_voltage(data->reg);
+ int voltage;
+
+ voltage = regulator_get_voltage(data->reg);
+ if (voltage)
+ data->supply_uV = voltage;
+
regulator_enable(data->reg);
/* setup a notifier block to update this if another device
* causes the voltage to change */
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
index a13b30e8d8d..d14a1af9f55 100644
--- a/drivers/hwmon/tmp401.c
+++ b/drivers/hwmon/tmp401.c
@@ -134,7 +134,7 @@ struct tmp401_data {
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
- int kind;
+ enum chips kind;
/* register values */
u8 status;
@@ -524,7 +524,7 @@ static int tmp401_detect(struct i2c_client *client,
if (reg > 15)
return -ENODEV;
- strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE);
+ strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE);
return 0;
}
@@ -572,8 +572,7 @@ static int tmp401_probe(struct i2c_client *client,
goto exit_remove;
}
- dev_info(&client->dev, "Detected TI %s chip\n",
- names[data->kind - 1]);
+ dev_info(&client->dev, "Detected TI %s chip\n", names[data->kind]);
return 0;
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index 4f7c051e2d7..738c472ece2 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -61,9 +61,9 @@ static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 };
#define TMP423_DEVICE_ID 0x23
static const struct i2c_device_id tmp421_id[] = {
- { "tmp421", tmp421 },
- { "tmp422", tmp422 },
- { "tmp423", tmp423 },
+ { "tmp421", 2 },
+ { "tmp422", 3 },
+ { "tmp423", 4 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tmp421_id);
@@ -73,21 +73,23 @@ struct tmp421_data {
struct mutex update_lock;
char valid;
unsigned long last_updated;
- int kind;
+ int channels;
u8 config;
s16 temp[4];
};
static int temp_from_s16(s16 reg)
{
- int temp = reg;
+ /* Mask out status bits */
+ int temp = reg & ~0xf;
return (temp * 1000 + 128) / 256;
}
static int temp_from_u16(u16 reg)
{
- int temp = reg;
+ /* Mask out status bits */
+ int temp = reg & ~0xf;
/* Add offset for extended temperature range. */
temp -= 64 * 256;
@@ -107,7 +109,7 @@ static struct tmp421_data *tmp421_update_device(struct device *dev)
data->config = i2c_smbus_read_byte_data(client,
TMP421_CONFIG_REG_1);
- for (i = 0; i <= data->kind; i++) {
+ for (i = 0; i < data->channels; i++) {
data->temp[i] = i2c_smbus_read_byte_data(client,
TMP421_TEMP_MSB[i]) << 8;
data->temp[i] |= i2c_smbus_read_byte_data(client,
@@ -166,7 +168,7 @@ static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
devattr = container_of(a, struct device_attribute, attr);
index = to_sensor_dev_attr(devattr)->index;
- if (data->kind > index)
+ if (index < data->channels)
return a->mode;
return 0;
@@ -252,9 +254,9 @@ static int tmp421_detect(struct i2c_client *client,
return -ENODEV;
}
- strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
+ strlcpy(info->type, tmp421_id[kind].name, I2C_NAME_SIZE);
dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
- names[kind - 1], client->addr);
+ names[kind], client->addr);
return 0;
}
@@ -271,7 +273,7 @@ static int tmp421_probe(struct i2c_client *client,
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
- data->kind = id->driver_data;
+ data->channels = id->driver_data;
err = tmp421_init_client(client);
if (err)
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index d47b4c9949c..e6078c9f0e2 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -948,8 +948,7 @@ static int __devinit vt8231_pci_probe(struct pci_dev *dev,
address = val & ~(VT8231_EXTENT - 1);
if (address == 0) {
- dev_err(&dev->dev, "base address not set -\
- upgrade BIOS or use force_addr=0xaddr\n");
+ dev_err(&dev->dev, "base address not set - upgrade BIOS or use force_addr=0xaddr\n");
return -ENODEV;
}
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 9a2022b6749..612807d9715 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -3,6 +3,10 @@
Copyright (C) 2006 Winbond Electronics Corp.
Yuan Mu
Rudolf Marek <r.marek@assembler.cz>
+ Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG.
+ Watchdog driver part
+ (Based partially on fschmd driver,
+ Copyright 2007-2008 by Hans de Goede)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,6 +39,16 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/watchdog.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kref.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+/* Default values */
+#define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
@@ -51,6 +65,18 @@ static int reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
+static int timeout = WATCHDOG_TIMEOUT; /* default timeout in minutes */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+ "Watchdog timeout in minutes. 2<= timeout <=255 (default="
+ __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+ "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
/*
Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved
as ID, Bank Select registers
@@ -72,6 +98,11 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
#define W83793_REG_VID_LATCHB 0x08
#define W83793_REG_VID_CTRL 0x59
+#define W83793_REG_WDT_LOCK 0x01
+#define W83793_REG_WDT_ENABLE 0x02
+#define W83793_REG_WDT_STATUS 0x03
+#define W83793_REG_WDT_TIMEOUT 0x04
+
static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f };
#define TEMP_READ 0
@@ -223,8 +254,37 @@ struct w83793_data {
u8 tolerance[3]; /* Temp tolerance(Smart Fan I/II) */
u8 sf2_pwm[6][7]; /* Smart FanII: Fan duty cycle */
u8 sf2_temp[6][7]; /* Smart FanII: Temp level point */
+
+ /* watchdog */
+ struct i2c_client *client;
+ struct mutex watchdog_lock;
+ struct list_head list; /* member of the watchdog_data_list */
+ struct kref kref;
+ struct miscdevice watchdog_miscdev;
+ unsigned long watchdog_is_open;
+ char watchdog_expect_close;
+ char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
+ unsigned int watchdog_caused_reboot;
+ int watchdog_timeout; /* watchdog timeout in minutes */
};
+/* Somewhat ugly :( global data pointer list with all devices, so that
+ we can find our device data as when using misc_register. There is no
+ other method to get to one's device data from the open file-op and
+ for usage in the reboot notifier callback. */
+static LIST_HEAD(watchdog_data_list);
+
+/* Note this lock not only protect list access, but also data.kref access */
+static DEFINE_MUTEX(watchdog_data_mutex);
+
+/* Release our data struct when we're detached from the i2c client *and* all
+ references to our watchdog device are released */
+static void w83793_release_resources(struct kref *ref)
+{
+ struct w83793_data *data = container_of(ref, struct w83793_data, kref);
+ kfree(data);
+}
+
static u8 w83793_read_value(struct i2c_client *client, u16 reg);
static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value);
static int w83793_probe(struct i2c_client *client,
@@ -1063,14 +1123,349 @@ static void w83793_init_client(struct i2c_client *client)
/* Start monitoring */
w83793_write_value(client, W83793_REG_CONFIG,
w83793_read_value(client, W83793_REG_CONFIG) | 0x01);
+}
+
+/*
+ * Watchdog routines
+ */
+
+static int watchdog_set_timeout(struct w83793_data *data, int timeout)
+{
+ int ret, mtimeout;
+
+ mtimeout = DIV_ROUND_UP(timeout, 60);
+
+ if (mtimeout > 255)
+ return -EINVAL;
+
+ mutex_lock(&data->watchdog_lock);
+ if (!data->client) {
+ ret = -ENODEV;
+ goto leave;
+ }
+
+ data->watchdog_timeout = mtimeout;
+
+ /* Set Timeout value (in Minutes) */
+ w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
+ data->watchdog_timeout);
+
+ ret = mtimeout * 60;
+
+leave:
+ mutex_unlock(&data->watchdog_lock);
+ return ret;
+}
+
+static int watchdog_get_timeout(struct w83793_data *data)
+{
+ int timeout;
+
+ mutex_lock(&data->watchdog_lock);
+ timeout = data->watchdog_timeout * 60;
+ mutex_unlock(&data->watchdog_lock);
+
+ return timeout;
+}
+
+static int watchdog_trigger(struct w83793_data *data)
+{
+ int ret = 0;
+
+ mutex_lock(&data->watchdog_lock);
+ if (!data->client) {
+ ret = -ENODEV;
+ goto leave;
+ }
+
+ /* Set Timeout value (in Minutes) */
+ w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
+ data->watchdog_timeout);
+
+leave:
+ mutex_unlock(&data->watchdog_lock);
+ return ret;
+}
+
+static int watchdog_enable(struct w83793_data *data)
+{
+ int ret = 0;
+
+ mutex_lock(&data->watchdog_lock);
+ if (!data->client) {
+ ret = -ENODEV;
+ goto leave;
+ }
+
+ /* Set initial timeout */
+ w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
+ data->watchdog_timeout);
+
+ /* Enable Soft Watchdog */
+ w83793_write_value(data->client, W83793_REG_WDT_LOCK, 0x55);
+
+leave:
+ mutex_unlock(&data->watchdog_lock);
+ return ret;
+}
+
+static int watchdog_disable(struct w83793_data *data)
+{
+ int ret = 0;
+
+ mutex_lock(&data->watchdog_lock);
+ if (!data->client) {
+ ret = -ENODEV;
+ goto leave;
+ }
+
+ /* Disable Soft Watchdog */
+ w83793_write_value(data->client, W83793_REG_WDT_LOCK, 0xAA);
+
+leave:
+ mutex_unlock(&data->watchdog_lock);
+ return ret;
+}
+
+static int watchdog_open(struct inode *inode, struct file *filp)
+{
+ struct w83793_data *pos, *data = NULL;
+ int watchdog_is_open;
+
+ /* We get called from drivers/char/misc.c with misc_mtx hold, and we
+ call misc_register() from w83793_probe() with watchdog_data_mutex
+ hold, as misc_register() takes the misc_mtx lock, this is a possible
+ deadlock, so we use mutex_trylock here. */
+ if (!mutex_trylock(&watchdog_data_mutex))
+ return -ERESTARTSYS;
+ list_for_each_entry(pos, &watchdog_data_list, list) {
+ if (pos->watchdog_miscdev.minor == iminor(inode)) {
+ data = pos;
+ break;
+ }
+ }
+
+ /* Check, if device is already open */
+ watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open);
+
+ /* Increase data reference counter (if not already done).
+ Note we can never not have found data, so we don't check for this */
+ if (!watchdog_is_open)
+ kref_get(&data->kref);
+
+ mutex_unlock(&watchdog_data_mutex);
+
+ /* Check, if device is already open and possibly issue error */
+ if (watchdog_is_open)
+ return -EBUSY;
+
+ /* Enable Soft Watchdog */
+ watchdog_enable(data);
+
+ /* Store pointer to data into filp's private data */
+ filp->private_data = data;
+
+ return nonseekable_open(inode, filp);
+}
+
+static int watchdog_close(struct inode *inode, struct file *filp)
+{
+ struct w83793_data *data = filp->private_data;
+ if (data->watchdog_expect_close) {
+ watchdog_disable(data);
+ data->watchdog_expect_close = 0;
+ } else {
+ watchdog_trigger(data);
+ dev_crit(&data->client->dev,
+ "unexpected close, not stopping watchdog!\n");
+ }
+
+ clear_bit(0, &data->watchdog_is_open);
+
+ /* Decrease data reference counter */
+ mutex_lock(&watchdog_data_mutex);
+ kref_put(&data->kref, w83793_release_resources);
+ mutex_unlock(&watchdog_data_mutex);
+
+ return 0;
+}
+
+static ssize_t watchdog_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ ssize_t ret;
+ struct w83793_data *data = filp->private_data;
+
+ if (count) {
+ if (!nowayout) {
+ size_t i;
+
+ /* Clear it in case it was set with a previous write */
+ data->watchdog_expect_close = 0;
+
+ for (i = 0; i != count; i++) {
+ char c;
+ if (get_user(c, buf + i))
+ return -EFAULT;
+ if (c == 'V')
+ data->watchdog_expect_close = 1;
+ }
+ }
+ ret = watchdog_trigger(data);
+ if (ret < 0)
+ return ret;
+ }
+ return count;
+}
+
+static int watchdog_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ static struct watchdog_info ident = {
+ .options = WDIOF_KEEPALIVEPING |
+ WDIOF_SETTIMEOUT |
+ WDIOF_CARDRESET,
+ .identity = "w83793 watchdog"
+ };
+
+ int val, ret = 0;
+ struct w83793_data *data = filp->private_data;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (!nowayout)
+ ident.options |= WDIOF_MAGICCLOSE;
+ if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
+ ret = -EFAULT;
+ break;
+
+ case WDIOC_GETSTATUS:
+ val = data->watchdog_caused_reboot ? WDIOF_CARDRESET : 0;
+ ret = put_user(val, (int __user *)arg);
+ break;
+
+ case WDIOC_GETBOOTSTATUS:
+ ret = put_user(0, (int __user *)arg);
+ break;
+
+ case WDIOC_KEEPALIVE:
+ ret = watchdog_trigger(data);
+ break;
+
+ case WDIOC_GETTIMEOUT:
+ val = watchdog_get_timeout(data);
+ ret = put_user(val, (int __user *)arg);
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(val, (int __user *)arg)) {
+ ret = -EFAULT;
+ break;
+ }
+ ret = watchdog_set_timeout(data, val);
+ if (ret > 0)
+ ret = put_user(ret, (int __user *)arg);
+ break;
+
+ case WDIOC_SETOPTIONS:
+ if (get_user(val, (int __user *)arg)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (val & WDIOS_DISABLECARD)
+ ret = watchdog_disable(data);
+ else if (val & WDIOS_ENABLECARD)
+ ret = watchdog_enable(data);
+ else
+ ret = -EINVAL;
+
+ break;
+ default:
+ ret = -ENOTTY;
+ }
+
+ return ret;
+}
+
+static const struct file_operations watchdog_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = watchdog_open,
+ .release = watchdog_close,
+ .write = watchdog_write,
+ .ioctl = watchdog_ioctl,
+};
+
+/*
+ * Notifier for system down
+ */
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
+{
+ struct w83793_data *data = NULL;
+
+ if (code == SYS_DOWN || code == SYS_HALT) {
+
+ /* Disable each registered watchdog */
+ mutex_lock(&watchdog_data_mutex);
+ list_for_each_entry(data, &watchdog_data_list, list) {
+ if (data->watchdog_miscdev.minor)
+ watchdog_disable(data);
+ }
+ mutex_unlock(&watchdog_data_mutex);
+ }
+
+ return NOTIFY_DONE;
}
+/*
+ * The WDT needs to learn about soft shutdowns in order to
+ * turn the timebomb registers off.
+ */
+
+static struct notifier_block watchdog_notifier = {
+ .notifier_call = watchdog_notify_sys,
+};
+
+/*
+ * Init / remove routines
+ */
+
static int w83793_remove(struct i2c_client *client)
{
struct w83793_data *data = i2c_get_clientdata(client);
struct device *dev = &client->dev;
- int i;
+ int i, tmp;
+
+ /* Unregister the watchdog (if registered) */
+ if (data->watchdog_miscdev.minor) {
+ misc_deregister(&data->watchdog_miscdev);
+
+ if (data->watchdog_is_open) {
+ dev_warn(&client->dev,
+ "i2c client detached with watchdog open! "
+ "Stopping watchdog.\n");
+ watchdog_disable(data);
+ }
+
+ mutex_lock(&watchdog_data_mutex);
+ list_del(&data->list);
+ mutex_unlock(&watchdog_data_mutex);
+
+ /* Tell the watchdog code the client is gone */
+ mutex_lock(&data->watchdog_lock);
+ data->client = NULL;
+ mutex_unlock(&data->watchdog_lock);
+ }
+
+ /* Reset Configuration Register to Disable Watch Dog Registers */
+ tmp = w83793_read_value(client, W83793_REG_CONFIG);
+ w83793_write_value(client, W83793_REG_CONFIG, tmp & ~0x04);
+
+ unregister_reboot_notifier(&watchdog_notifier);
hwmon_device_unregister(data->hwmon_dev);
@@ -1099,7 +1494,10 @@ static int w83793_remove(struct i2c_client *client)
if (data->lm75[1] != NULL)
i2c_unregister_device(data->lm75[1]);
- kfree(data);
+ /* Decrease data reference counter */
+ mutex_lock(&watchdog_data_mutex);
+ kref_put(&data->kref, w83793_release_resources);
+ mutex_unlock(&watchdog_data_mutex);
return 0;
}
@@ -1203,6 +1601,7 @@ static int w83793_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
+ const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
struct w83793_data *data;
int i, tmp, val, err;
int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
@@ -1218,6 +1617,14 @@ static int w83793_probe(struct i2c_client *client,
i2c_set_clientdata(client, data);
data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
mutex_init(&data->update_lock);
+ mutex_init(&data->watchdog_lock);
+ INIT_LIST_HEAD(&data->list);
+ kref_init(&data->kref);
+
+ /* Store client pointer in our data struct for watchdog usage
+ (where the client is found through a data ptr instead of the
+ otherway around) */
+ data->client = client;
err = w83793_detect_subclients(client);
if (err)
@@ -1380,8 +1787,77 @@ static int w83793_probe(struct i2c_client *client,
goto exit_remove;
}
+ /* Watchdog initialization */
+
+ /* Register boot notifier */
+ err = register_reboot_notifier(&watchdog_notifier);
+ if (err != 0) {
+ dev_err(&client->dev,
+ "cannot register reboot notifier (err=%d)\n", err);
+ goto exit_devunreg;
+ }
+
+ /* Enable Watchdog registers.
+ Set Configuration Register to Enable Watch Dog Registers
+ (Bit 2) = XXXX, X1XX. */
+ tmp = w83793_read_value(client, W83793_REG_CONFIG);
+ w83793_write_value(client, W83793_REG_CONFIG, tmp | 0x04);
+
+ /* Set the default watchdog timeout */
+ data->watchdog_timeout = timeout;
+
+ /* Check, if last reboot was caused by watchdog */
+ data->watchdog_caused_reboot =
+ w83793_read_value(data->client, W83793_REG_WDT_STATUS) & 0x01;
+
+ /* Disable Soft Watchdog during initialiation */
+ watchdog_disable(data);
+
+ /* We take the data_mutex lock early so that watchdog_open() cannot
+ run when misc_register() has completed, but we've not yet added
+ our data to the watchdog_data_list (and set the default timeout) */
+ mutex_lock(&watchdog_data_mutex);
+ for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) {
+ /* Register our watchdog part */
+ snprintf(data->watchdog_name, sizeof(data->watchdog_name),
+ "watchdog%c", (i == 0) ? '\0' : ('0' + i));
+ data->watchdog_miscdev.name = data->watchdog_name;
+ data->watchdog_miscdev.fops = &watchdog_fops;
+ data->watchdog_miscdev.minor = watchdog_minors[i];
+
+ err = misc_register(&data->watchdog_miscdev);
+ if (err == -EBUSY)
+ continue;
+ if (err) {
+ data->watchdog_miscdev.minor = 0;
+ dev_err(&client->dev,
+ "Registering watchdog chardev: %d\n", err);
+ break;
+ }
+
+ list_add(&data->list, &watchdog_data_list);
+
+ dev_info(&client->dev,
+ "Registered watchdog chardev major 10, minor: %d\n",
+ watchdog_minors[i]);
+ break;
+ }
+ if (i == ARRAY_SIZE(watchdog_minors)) {
+ data->watchdog_miscdev.minor = 0;
+ dev_warn(&client->dev, "Couldn't register watchdog chardev "
+ "(due to no free minor)\n");
+ }
+
+ mutex_unlock(&watchdog_data_mutex);
+
return 0;
+ /* Unregister hwmon device */
+
+exit_devunreg:
+
+ hwmon_device_unregister(data->hwmon_dev);
+
/* Unregister sysfs hooks */
exit_remove:
@@ -1628,7 +2104,7 @@ static void __exit sensors_w83793_exit(void)
i2c_del_driver(&w83793_driver);
}
-MODULE_AUTHOR("Yuan Mu");
+MODULE_AUTHOR("Yuan Mu, Sven Anders");
MODULE_DESCRIPTION("w83793 driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c
index c16e9e74c35..97b1f834a47 100644
--- a/drivers/hwmon/wm831x-hwmon.c
+++ b/drivers/hwmon/wm831x-hwmon.c
@@ -24,6 +24,7 @@
#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/auxadc.h>
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 02ce9cff5fc..d06083fdffb 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -73,7 +73,6 @@ config I2C_SMBUS
source drivers/i2c/algos/Kconfig
source drivers/i2c/busses/Kconfig
-source drivers/i2c/chips/Kconfig
config I2C_DEBUG_CORE
bool "I2C Core debugging messages"
@@ -98,12 +97,4 @@ config I2C_DEBUG_BUS
a problem with I2C support and want to see more of what is going
on.
-config I2C_DEBUG_CHIP
- bool "I2C Chip debugging messages"
- help
- Say Y here if you want the I2C chip drivers to produce a bunch of
- debug messages to the system log. Select this if you are having
- a problem with I2C support and want to see more of what is going
- on.
-
endif # I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index acd0250c16a..a7d9b4be9bb 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o
obj-$(CONFIG_I2C) += i2c-core.o
obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o
obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
-obj-y += busses/ chips/ algos/
+obj-y += algos/ busses/
ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index e25e13980af..a39e6cff86e 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -24,7 +24,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
@@ -522,6 +521,12 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
int i, ret;
unsigned short nak_ok;
+ if (adap->pre_xfer) {
+ ret = adap->pre_xfer(i2c_adap);
+ if (ret < 0)
+ return ret;
+ }
+
bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
i2c_start(adap);
for (i = 0; i < num; i++) {
@@ -570,6 +575,9 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
bailout:
bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
i2c_stop(adap);
+
+ if (adap->post_xfer)
+ adap->post_xfer(i2c_adap);
return ret;
}
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
index 7ce75775ec7..5eebf562ff3 100644
--- a/drivers/i2c/algos/i2c-algo-pcf.c
+++ b/drivers/i2c/algos/i2c-algo-pcf.c
@@ -29,7 +29,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/i2c.h>
@@ -176,7 +175,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
*/
if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
- return -ENXIO; /* definetly not PCF8584 */
+ return -ENXIO; /* definitely not PCF8584 */
}
/* load own address in S0, effective address is (own << 1) */
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 4cc3807bd31..9c6170cd9aa 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -106,6 +106,8 @@ config I2C_I801
config I2C_ISCH
tristate "Intel SCH SMBus 1.0"
depends on PCI
+ select MFD_CORE
+ select LPC_SCH
help
Say Y here if you want to use SMBus controller on the Intel SCH
based systems.
@@ -419,13 +421,12 @@ config I2C_IXP2000
instead.
config I2C_MPC
- tristate "MPC107/824x/85xx/52xx/86xx"
+ tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
depends on PPC32
help
If you say yes to this option, support will be included for the
- built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
- MPC85xx/MPC8641 family processors. The driver may also work on 52xx
- family processors, though interrupts are known not to work.
+ built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,
+ MPC8240, MPC8245, MPC83xx, MPC85xx and MPC8641 family processors.
This driver can also be built as a module. If so, the module
will be called i2c-mpc.
@@ -440,6 +441,13 @@ config I2C_MV64XXX
This driver can also be built as a module. If so, the module
will be called i2c-mv64xxx.
+config I2C_NOMADIK
+ tristate "ST-Ericsson Nomadik/Ux500 I2C Controller"
+ depends on PLAT_NOMADIK
+ help
+ If you say yes to this option, support will be included for the
+ I2C interface from ST-Ericsson's Nomadik and Ux500 architectures.
+
config I2C_OCORES
tristate "OpenCores I2C Controller"
depends on EXPERIMENTAL
@@ -575,6 +583,16 @@ config I2C_OCTEON
This driver can also be built as a module. If so, the module
will be called i2c-octeon.
+config I2C_XILINX
+ tristate "Xilinx I2C Controller"
+ depends on EXPERIMENTAL && HAS_IOMEM
+ help
+ If you say yes to this option, support will be included for the
+ Xilinx I2C controller.
+
+ This driver can also be built as a module. If so, the module
+ will be called xilinx_i2c.
+
comment "External I2C/SMBus adapter drivers"
config I2C_PARPORT
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index c2c4ea1908d..097236f631e 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
+obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
@@ -55,6 +56,7 @@ obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
+obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
# External I2C/SMBus adapter drivers
obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index d0dc970d737..2fbef27b6cd 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -17,6 +17,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#include <asm/io.h>
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index fe3fb567317..f1e14dd590c 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/timer.h>
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index c89687a1083..4523364e672 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -35,6 +35,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c
index 9e18ef97f15..b664ed8bbdb 100644
--- a/drivers/i2c/busses/i2c-designware.c
+++ b/drivers/i2c/busses/i2c-designware.c
@@ -36,6 +36,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
/*
* Registers offset
@@ -497,13 +498,13 @@ static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
int i;
if (abort_source & DW_IC_TX_ABRT_NOACK) {
- for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
+ for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
dev_dbg(dev->dev,
"%s: %s\n", __func__, abort_sources[i]);
return -EREMOTEIO;
}
- for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
+ for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
if (abort_source & DW_IC_TX_ARB_LOST)
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
index 448b4bf35eb..612255614a6 100644
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -29,7 +29,6 @@
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 32104eac8d3..c21077d248a 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -12,6 +12,7 @@
#include <linux/i2c-gpio.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <asm/gpio.h>
diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c
index 87ecace415d..ce87a902c94 100644
--- a/drivers/i2c/busses/i2c-highlander.c
+++ b/drivers/i2c/busses/i2c-highlander.c
@@ -19,6 +19,7 @@
#include <linux/completion.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#define SMCR 0x00
#define SMCR_START (1 << 0)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 9da5b05cdb5..299b918455a 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -416,9 +416,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
data->block[0] = 32; /* max for SMBus block reads */
}
+ /* Experience has shown that the block buffer can only be used for
+ SMBus (not I2C) block transactions, even though the datasheet
+ doesn't mention this limitation. */
if ((i801_features & FEATURE_BLOCK_BUFFER)
- && !(command == I2C_SMBUS_I2C_BLOCK_DATA
- && read_write == I2C_SMBUS_READ)
+ && command != I2C_SMBUS_I2C_BLOCK_DATA
&& i801_set_block_buffer_mode() == 0)
result = i801_block_transaction_by_block(data, read_write,
hwpec);
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 75bf820e7cc..d1ff9408dc1 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -47,6 +47,7 @@
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
@@ -145,10 +146,10 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
"<%s> I2C Interrupted\n", __func__);
return -EINTR;
}
- if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
+ if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
dev_dbg(&i2c_imx->adapter.dev,
"<%s> I2C bus is busy\n", __func__);
- return -EIO;
+ return -ETIMEDOUT;
}
schedule();
}
@@ -443,6 +444,8 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
result = i2c_imx_read(i2c_imx, &msgs[i]);
else
result = i2c_imx_write(i2c_imx, &msgs[i]);
+ if (result)
+ goto fail0;
}
fail0:
@@ -627,7 +630,6 @@ static int __exit i2c_imx_remove(struct platform_device *pdev)
}
static struct platform_driver i2c_imx_driver = {
- .probe = i2c_imx_probe,
.remove = __exit_p(i2c_imx_remove),
.driver = {
.name = DRIVER_NAME,
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
index 69c22f79f23..ddc258edb34 100644
--- a/drivers/i2c/busses/i2c-isch.c
+++ b/drivers/i2c/busses/i2c-isch.c
@@ -27,7 +27,7 @@
*/
#include <linux/module.h>
-#include <linux/pci.h>
+#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/stddef.h>
@@ -46,12 +46,6 @@
#define SMBHSTDAT1 (7 + sch_smba)
#define SMBBLKDAT (0x20 + sch_smba)
-/* count for request_region */
-#define SMBIOSIZE 64
-
-/* PCI Address Constants */
-#define SMBBA_SCH 0x40
-
/* Other settings */
#define MAX_TIMEOUT 500
@@ -63,7 +57,6 @@
#define SCH_BLOCK_DATA 0x05
static unsigned short sch_smba;
-static struct pci_driver sch_driver;
static struct i2c_adapter sch_adapter;
/*
@@ -256,37 +249,23 @@ static struct i2c_adapter sch_adapter = {
.algo = &smbus_algorithm,
};
-static const struct pci_device_id sch_ids[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, sch_ids);
-
-static int __devinit sch_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int __devinit smbus_sch_probe(struct platform_device *dev)
{
+ struct resource *res;
int retval;
- unsigned int smba;
- pci_read_config_dword(dev, SMBBA_SCH, &smba);
- if (!(smba & (1 << 31))) {
- dev_err(&dev->dev, "SMBus I/O space disabled!\n");
- return -ENODEV;
- }
+ res = platform_get_resource(dev, IORESOURCE_IO, 0);
+ if (!res)
+ return -EBUSY;
- sch_smba = (unsigned short)smba;
- if (sch_smba == 0) {
- dev_err(&dev->dev, "SMBus base address uninitialized!\n");
- return -ENODEV;
- }
- if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
- return -ENODEV;
- if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
+ if (!request_region(res->start, resource_size(res), dev->name)) {
dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
sch_smba);
return -EBUSY;
}
+
+ sch_smba = res->start;
+
dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba);
/* set up the sysfs linkage to our parent device */
@@ -298,37 +277,43 @@ static int __devinit sch_probe(struct pci_dev *dev,
retval = i2c_add_adapter(&sch_adapter);
if (retval) {
dev_err(&dev->dev, "Couldn't register adapter!\n");
- release_region(sch_smba, SMBIOSIZE);
+ release_region(res->start, resource_size(res));
sch_smba = 0;
}
return retval;
}
-static void __devexit sch_remove(struct pci_dev *dev)
+static int __devexit smbus_sch_remove(struct platform_device *pdev)
{
+ struct resource *res;
if (sch_smba) {
i2c_del_adapter(&sch_adapter);
- release_region(sch_smba, SMBIOSIZE);
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(res->start, resource_size(res));
sch_smba = 0;
}
+
+ return 0;
}
-static struct pci_driver sch_driver = {
- .name = "isch_smbus",
- .id_table = sch_ids,
- .probe = sch_probe,
- .remove = __devexit_p(sch_remove),
+static struct platform_driver smbus_sch_driver = {
+ .driver = {
+ .name = "isch_smbus",
+ .owner = THIS_MODULE,
+ },
+ .probe = smbus_sch_probe,
+ .remove = __devexit_p(smbus_sch_remove),
};
static int __init i2c_sch_init(void)
{
- return pci_register_driver(&sch_driver);
+ return platform_driver_register(&smbus_sch_driver);
}
static void __exit i2c_sch_exit(void)
{
- pci_unregister_driver(&sch_driver);
+ platform_driver_unregister(&smbus_sch_driver);
}
MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
@@ -337,3 +322,4 @@ MODULE_LICENSE("GPL");
module_init(i2c_sch_init);
module_exit(i2c_sch_exit);
+MODULE_ALIAS("platform:isch_smbus");
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index c016f7a2c5f..5d8aed5ec21 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
+#include <linux/slab.h>
#include <mach/hardware.h> /* Pick up IXP2000-specific bits */
#include <mach/gpio.h>
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index f627001108b..f1321f76378 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/of_i2c.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <linux/fsl_devices.h>
@@ -31,6 +32,9 @@
#define DRV_NAME "mpc-i2c"
+#define MPC_I2C_CLOCK_LEGACY 0
+#define MPC_I2C_CLOCK_PRESERVE (~0U)
+
#define MPC_I2C_FDR 0x04
#define MPC_I2C_CR 0x08
#define MPC_I2C_SR 0x0c
@@ -66,10 +70,9 @@ struct mpc_i2c_divider {
u16 fdr; /* including dfsrr */
};
-struct mpc_i2c_match_data {
- void (*setclock)(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler);
+struct mpc_i2c_data {
+ void (*setup)(struct device_node *node, struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler);
u32 prescaler;
};
@@ -164,8 +167,8 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
return 0;
}
-#ifdef CONFIG_PPC_MPC52xx
-static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
+#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x)
+static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {
{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
{28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
{36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
@@ -186,14 +189,15 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
{10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
};
-int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
+static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
+ int prescaler)
{
const struct mpc_i2c_divider *div = NULL;
unsigned int pvr = mfspr(SPRN_PVR);
u32 divider;
int i;
- if (!clock)
+ if (clock == MPC_I2C_CLOCK_LEGACY)
return -EINVAL;
/* Determine divider value */
@@ -215,12 +219,18 @@ int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
return div ? (int)div->fdr : -EINVAL;
}
-static void mpc_i2c_setclock_52xx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
int ret, fdr;
+ if (clock == MPC_I2C_CLOCK_PRESERVE) {
+ dev_dbg(i2c->dev, "using fdr %d\n",
+ readb(i2c->base + MPC_I2C_FDR));
+ return;
+ }
+
ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
@@ -229,16 +239,52 @@ static void mpc_i2c_setclock_52xx(struct device_node *node,
if (ret >= 0)
dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
}
-#else /* !CONFIG_PPC_MPC52xx */
-static void mpc_i2c_setclock_52xx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
+static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
+{
+}
+#endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
+
+#ifdef CONFIG_PPC_MPC512x
+static void __devinit mpc_i2c_setup_512x(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
+{
+ struct device_node *node_ctrl;
+ void __iomem *ctrl;
+ const u32 *pval;
+ u32 idx;
+
+ /* Enable I2C interrupts for mpc5121 */
+ node_ctrl = of_find_compatible_node(NULL, NULL,
+ "fsl,mpc5121-i2c-ctrl");
+ if (node_ctrl) {
+ ctrl = of_iomap(node_ctrl, 0);
+ if (ctrl) {
+ /* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */
+ pval = of_get_property(node, "reg", NULL);
+ idx = (*pval & 0xff) / 0x20;
+ setbits32(ctrl, 1 << (24 + idx * 2));
+ iounmap(ctrl);
+ }
+ of_node_put(node_ctrl);
+ }
+
+ /* The clock setup for the 52xx works also fine for the 512x */
+ mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
+}
+#else /* CONFIG_PPC_MPC512x */
+static void __devinit mpc_i2c_setup_512x(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
}
-#endif /* CONFIG_PPC_MPC52xx*/
+#endif /* CONFIG_PPC_MPC512x */
#ifdef CONFIG_FSL_SOC
-static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
+static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = {
{160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123},
{288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102},
{416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127},
@@ -258,7 +304,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
{49152, 0x011e}, {61440, 0x011f}
};
-u32 mpc_i2c_get_sec_cfg_8xxx(void)
+static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)
{
struct device_node *node = NULL;
u32 __iomem *reg;
@@ -287,13 +333,14 @@ u32 mpc_i2c_get_sec_cfg_8xxx(void)
return val;
}
-int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
+static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
+ u32 prescaler)
{
const struct mpc_i2c_divider *div = NULL;
u32 divider;
int i;
- if (!clock)
+ if (clock == MPC_I2C_CLOCK_LEGACY)
return -EINVAL;
/* Determine proper divider value */
@@ -320,12 +367,19 @@ int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
return div ? (int)div->fdr : -EINVAL;
}
-static void mpc_i2c_setclock_8xxx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
int ret, fdr;
+ if (clock == MPC_I2C_CLOCK_PRESERVE) {
+ dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n",
+ readb(i2c->base + MPC_I2C_DFSRR),
+ readb(i2c->base + MPC_I2C_FDR));
+ return;
+ }
+
ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
@@ -338,9 +392,9 @@ static void mpc_i2c_setclock_8xxx(struct device_node *node,
}
#else /* !CONFIG_FSL_SOC */
-static void mpc_i2c_setclock_8xxx(struct device_node *node,
- struct mpc_i2c *i2c,
- u32 clock, u32 prescaler)
+static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
}
#endif /* CONFIG_FSL_SOC */
@@ -494,7 +548,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
{
struct mpc_i2c *i2c;
const u32 *prop;
- u32 clock = 0;
+ u32 clock = MPC_I2C_CLOCK_LEGACY;
int result = 0;
int plen;
@@ -523,21 +577,21 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
}
}
- if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
+ if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
+ clock = MPC_I2C_CLOCK_PRESERVE;
+ } else {
prop = of_get_property(op->node, "clock-frequency", &plen);
if (prop && plen == sizeof(u32))
clock = *prop;
+ }
- if (match->data) {
- struct mpc_i2c_match_data *data =
- (struct mpc_i2c_match_data *)match->data;
- data->setclock(op->node, i2c, clock, data->prescaler);
- } else {
- /* Backwards compatibility */
- if (of_get_property(op->node, "dfsrr", NULL))
- mpc_i2c_setclock_8xxx(op->node, i2c,
- clock, 0);
- }
+ if (match->data) {
+ struct mpc_i2c_data *data = match->data;
+ data->setup(op->node, i2c, clock, data->prescaler);
+ } else {
+ /* Backwards compatibility */
+ if (of_get_property(op->node, "dfsrr", NULL))
+ mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
}
dev_set_drvdata(&op->dev, i2c);
@@ -582,47 +636,42 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
return 0;
};
+static struct mpc_i2c_data mpc_i2c_data_512x __devinitdata = {
+ .setup = mpc_i2c_setup_512x,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = {
+ .setup = mpc_i2c_setup_52xx,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8313 __devinitdata = {
+ .setup = mpc_i2c_setup_8xxx,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8543 __devinitdata = {
+ .setup = mpc_i2c_setup_8xxx,
+ .prescaler = 2,
+};
+
+static struct mpc_i2c_data mpc_i2c_data_8544 __devinitdata = {
+ .setup = mpc_i2c_setup_8xxx,
+ .prescaler = 3,
+};
+
static const struct of_device_id mpc_i2c_of_match[] = {
- {.compatible = "mpc5200-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_52xx,
- },
- },
- {.compatible = "fsl,mpc5200b-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_52xx,
- },
- },
- {.compatible = "fsl,mpc5200-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_52xx,
- },
- },
- {.compatible = "fsl,mpc8313-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_8xxx,
- },
- },
- {.compatible = "fsl,mpc8543-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_8xxx,
- .prescaler = 2,
- },
- },
- {.compatible = "fsl,mpc8544-i2c",
- .data = &(struct mpc_i2c_match_data) {
- .setclock = mpc_i2c_setclock_8xxx,
- .prescaler = 3,
- },
+ {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
+ {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
+ {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
+ {.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, },
+ {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
+ {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
+ {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
/* Backward compatibility */
- },
{.compatible = "fsl-i2c", },
{},
};
-
MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
-
/* Structure for a device driver */
static struct of_platform_driver mpc_i2c_driver = {
.match_table = mpc_i2c_of_match,
@@ -655,5 +704,5 @@ module_exit(fsl_i2c_exit);
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
- "MPC824x/85xx/52xx processors");
+ "MPC824x/83xx/85xx/86xx/512x/52xx processors");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index ed387ffa473..3623a449908 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -10,6 +10,7 @@
* or implied.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/i2c.h>
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 4a700587ef1..4a48dd4ef78 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -56,6 +56,7 @@
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#include <asm/io.h>
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
new file mode 100644
index 00000000000..a4f8d33fa38
--- /dev/null
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -0,0 +1,960 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ * Copyright (C) 2009 STMicroelectronics
+ *
+ * I2C master mode controller driver, used in Nomadik 8815
+ * and Ux500 platforms.
+ *
+ * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ * Author: Sachin Verma <sachin.verma@st.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/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/i2c.h>
+
+#define DRIVER_NAME "nmk-i2c"
+
+/* I2C Controller register offsets */
+#define I2C_CR (0x000)
+#define I2C_SCR (0x004)
+#define I2C_HSMCR (0x008)
+#define I2C_MCR (0x00C)
+#define I2C_TFR (0x010)
+#define I2C_SR (0x014)
+#define I2C_RFR (0x018)
+#define I2C_TFTR (0x01C)
+#define I2C_RFTR (0x020)
+#define I2C_DMAR (0x024)
+#define I2C_BRCR (0x028)
+#define I2C_IMSCR (0x02C)
+#define I2C_RISR (0x030)
+#define I2C_MISR (0x034)
+#define I2C_ICR (0x038)
+
+/* Control registers */
+#define I2C_CR_PE (0x1 << 0) /* Peripheral Enable */
+#define I2C_CR_OM (0x3 << 1) /* Operating mode */
+#define I2C_CR_SAM (0x1 << 3) /* Slave addressing mode */
+#define I2C_CR_SM (0x3 << 4) /* Speed mode */
+#define I2C_CR_SGCM (0x1 << 6) /* Slave general call mode */
+#define I2C_CR_FTX (0x1 << 7) /* Flush Transmit */
+#define I2C_CR_FRX (0x1 << 8) /* Flush Receive */
+#define I2C_CR_DMA_TX_EN (0x1 << 9) /* DMA Tx enable */
+#define I2C_CR_DMA_RX_EN (0x1 << 10) /* DMA Rx Enable */
+#define I2C_CR_DMA_SLE (0x1 << 11) /* DMA sync. logic enable */
+#define I2C_CR_LM (0x1 << 12) /* Loopback mode */
+#define I2C_CR_FON (0x3 << 13) /* Filtering on */
+#define I2C_CR_FS (0x3 << 15) /* Force stop enable */
+
+/* Master controller (MCR) register */
+#define I2C_MCR_OP (0x1 << 0) /* Operation */
+#define I2C_MCR_A7 (0x7f << 1) /* 7-bit address */
+#define I2C_MCR_EA10 (0x7 << 8) /* 10-bit Extended address */
+#define I2C_MCR_SB (0x1 << 11) /* Extended address */
+#define I2C_MCR_AM (0x3 << 12) /* Address type */
+#define I2C_MCR_STOP (0x1 << 14) /* Stop condition */
+#define I2C_MCR_LENGTH (0x7ff << 15) /* Transaction length */
+
+/* Status register (SR) */
+#define I2C_SR_OP (0x3 << 0) /* Operation */
+#define I2C_SR_STATUS (0x3 << 2) /* controller status */
+#define I2C_SR_CAUSE (0x7 << 4) /* Abort cause */
+#define I2C_SR_TYPE (0x3 << 7) /* Receive type */
+#define I2C_SR_LENGTH (0x7ff << 9) /* Transfer length */
+
+/* Interrupt mask set/clear (IMSCR) bits */
+#define I2C_IT_TXFE (0x1 << 0)
+#define I2C_IT_TXFNE (0x1 << 1)
+#define I2C_IT_TXFF (0x1 << 2)
+#define I2C_IT_TXFOVR (0x1 << 3)
+#define I2C_IT_RXFE (0x1 << 4)
+#define I2C_IT_RXFNF (0x1 << 5)
+#define I2C_IT_RXFF (0x1 << 6)
+#define I2C_IT_RFSR (0x1 << 16)
+#define I2C_IT_RFSE (0x1 << 17)
+#define I2C_IT_WTSR (0x1 << 18)
+#define I2C_IT_MTD (0x1 << 19)
+#define I2C_IT_STD (0x1 << 20)
+#define I2C_IT_MAL (0x1 << 24)
+#define I2C_IT_BERR (0x1 << 25)
+#define I2C_IT_MTDWS (0x1 << 28)
+
+#define GEN_MASK(val, mask, sb) (((val) << (sb)) & (mask))
+
+/* some bits in ICR are reserved */
+#define I2C_CLEAR_ALL_INTS 0x131f007f
+
+/* first three msb bits are reserved */
+#define IRQ_MASK(mask) (mask & 0x1fffffff)
+
+/* maximum threshold value */
+#define MAX_I2C_FIFO_THRESHOLD 15
+
+enum i2c_status {
+ I2C_NOP,
+ I2C_ON_GOING,
+ I2C_OK,
+ I2C_ABORT
+};
+
+/* operation */
+enum i2c_operation {
+ I2C_NO_OPERATION = 0xff,
+ I2C_WRITE = 0x00,
+ I2C_READ = 0x01
+};
+
+/* controller response timeout in ms */
+#define I2C_TIMEOUT_MS 500
+
+/**
+ * struct i2c_nmk_client - client specific data
+ * @slave_adr: 7-bit slave address
+ * @count: no. bytes to be transfered
+ * @buffer: client data buffer
+ * @xfer_bytes: bytes transfered till now
+ * @operation: current I2C operation
+ */
+struct i2c_nmk_client {
+ unsigned short slave_adr;
+ unsigned long count;
+ unsigned char *buffer;
+ unsigned long xfer_bytes;
+ enum i2c_operation operation;
+};
+
+/**
+ * struct nmk_i2c_dev - private data structure of the controller
+ * @pdev: parent platform device
+ * @adap: corresponding I2C adapter
+ * @irq: interrupt line for the controller
+ * @virtbase: virtual io memory area
+ * @clk: hardware i2c block clock
+ * @cfg: machine provided controller configuration
+ * @cli: holder of client specific data
+ * @stop: stop condition
+ * @xfer_complete: acknowledge completion for a I2C message
+ * @result: controller propogated result
+ */
+struct nmk_i2c_dev {
+ struct platform_device *pdev;
+ struct i2c_adapter adap;
+ int irq;
+ void __iomem *virtbase;
+ struct clk *clk;
+ struct nmk_i2c_controller cfg;
+ struct i2c_nmk_client cli;
+ int stop;
+ struct completion xfer_complete;
+ int result;
+};
+
+/* controller's abort causes */
+static const char *abort_causes[] = {
+ "no ack received after address transmission",
+ "no ack received during data phase",
+ "ack received after xmission of master code",
+ "master lost arbitration",
+ "slave restarts",
+ "slave reset",
+ "overflow, maxsize is 2047 bytes",
+};
+
+static inline void i2c_set_bit(void __iomem *reg, u32 mask)
+{
+ writel(readl(reg) | mask, reg);
+}
+
+static inline void i2c_clr_bit(void __iomem *reg, u32 mask)
+{
+ writel(readl(reg) & ~mask, reg);
+}
+
+/**
+ * flush_i2c_fifo() - This function flushes the I2C FIFO
+ * @dev: private data of I2C Driver
+ *
+ * This function flushes the I2C Tx and Rx FIFOs. It returns
+ * 0 on successful flushing of FIFO
+ */
+static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
+{
+#define LOOP_ATTEMPTS 10
+ int i;
+ unsigned long timeout;
+
+ /*
+ * flush the transmit and receive FIFO. The flushing
+ * operation takes several cycles before to be completed.
+ * On the completion, the I2C internal logic clears these
+ * bits, until then no one must access Tx, Rx FIFO and
+ * should poll on these bits waiting for the completion.
+ */
+ writel((I2C_CR_FTX | I2C_CR_FRX), dev->virtbase + I2C_CR);
+
+ for (i = 0; i < LOOP_ATTEMPTS; i++) {
+ timeout = jiffies + msecs_to_jiffies(I2C_TIMEOUT_MS);
+
+ while (!time_after(jiffies, timeout)) {
+ if ((readl(dev->virtbase + I2C_CR) &
+ (I2C_CR_FTX | I2C_CR_FRX)) == 0)
+ return 0;
+ }
+ }
+
+ dev_err(&dev->pdev->dev, "flushing operation timed out "
+ "giving up after %d attempts", LOOP_ATTEMPTS);
+
+ return -ETIMEDOUT;
+}
+
+/**
+ * disable_all_interrupts() - Disable all interrupts of this I2c Bus
+ * @dev: private data of I2C Driver
+ */
+static void disable_all_interrupts(struct nmk_i2c_dev *dev)
+{
+ u32 mask = IRQ_MASK(0);
+ writel(mask, dev->virtbase + I2C_IMSCR);
+}
+
+/**
+ * clear_all_interrupts() - Clear all interrupts of I2C Controller
+ * @dev: private data of I2C Driver
+ */
+static void clear_all_interrupts(struct nmk_i2c_dev *dev)
+{
+ u32 mask;
+ mask = IRQ_MASK(I2C_CLEAR_ALL_INTS);
+ writel(mask, dev->virtbase + I2C_ICR);
+}
+
+/**
+ * init_hw() - initialize the I2C hardware
+ * @dev: private data of I2C Driver
+ */
+static int init_hw(struct nmk_i2c_dev *dev)
+{
+ int stat;
+
+ stat = flush_i2c_fifo(dev);
+ if (stat)
+ return stat;
+
+ /* disable the controller */
+ i2c_clr_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
+
+ disable_all_interrupts(dev);
+
+ clear_all_interrupts(dev);
+
+ dev->cli.operation = I2C_NO_OPERATION;
+
+ return 0;
+}
+
+/* enable peripheral, master mode operation */
+#define DEFAULT_I2C_REG_CR ((1 << 1) | I2C_CR_PE)
+
+/**
+ * load_i2c_mcr_reg() - load the MCR register
+ * @dev: private data of controller
+ */
+static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev)
+{
+ u32 mcr = 0;
+
+ /* 7-bit address transaction */
+ mcr |= GEN_MASK(1, I2C_MCR_AM, 12);
+ mcr |= GEN_MASK(dev->cli.slave_adr, I2C_MCR_A7, 1);
+
+ /* start byte procedure not applied */
+ mcr |= GEN_MASK(0, I2C_MCR_SB, 11);
+
+ /* check the operation, master read/write? */
+ if (dev->cli.operation == I2C_WRITE)
+ mcr |= GEN_MASK(I2C_WRITE, I2C_MCR_OP, 0);
+ else
+ mcr |= GEN_MASK(I2C_READ, I2C_MCR_OP, 0);
+
+ /* stop or repeated start? */
+ if (dev->stop)
+ mcr |= GEN_MASK(1, I2C_MCR_STOP, 14);
+ else
+ mcr &= ~(GEN_MASK(1, I2C_MCR_STOP, 14));
+
+ mcr |= GEN_MASK(dev->cli.count, I2C_MCR_LENGTH, 15);
+
+ return mcr;
+}
+
+/**
+ * setup_i2c_controller() - setup the controller
+ * @dev: private data of controller
+ */
+static void setup_i2c_controller(struct nmk_i2c_dev *dev)
+{
+ u32 brcr1, brcr2;
+ u32 i2c_clk, div;
+
+ writel(0x0, dev->virtbase + I2C_CR);
+ writel(0x0, dev->virtbase + I2C_HSMCR);
+ writel(0x0, dev->virtbase + I2C_TFTR);
+ writel(0x0, dev->virtbase + I2C_RFTR);
+ writel(0x0, dev->virtbase + I2C_DMAR);
+
+ /*
+ * set the slsu:
+ *
+ * slsu defines the data setup time after SCL clock
+ * stretching in terms of i2c clk cycles. The
+ * needed setup time for the three modes are 250ns,
+ * 100ns, 10ns repectively thus leading to the values
+ * of 14, 6, 2 for a 48 MHz i2c clk.
+ */
+ writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR);
+
+ i2c_clk = clk_get_rate(dev->clk);
+
+ /* fallback to std. mode if machine has not provided it */
+ if (dev->cfg.clk_freq == 0)
+ dev->cfg.clk_freq = 100000;
+
+ /*
+ * The spec says, in case of std. mode the divider is
+ * 2 whereas it is 3 for fast and fastplus mode of
+ * operation. TODO - high speed support.
+ */
+ div = (dev->cfg.clk_freq > 100000) ? 3 : 2;
+
+ /*
+ * generate the mask for baud rate counters. The controller
+ * has two baud rate counters. One is used for High speed
+ * operation, and the other is for std, fast mode, fast mode
+ * plus operation. Currently we do not supprt high speed mode
+ * so set brcr1 to 0.
+ */
+ brcr1 = 0 << 16;
+ brcr2 = (i2c_clk/(dev->cfg.clk_freq * div)) & 0xffff;
+
+ /* set the baud rate counter register */
+ writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
+
+ /*
+ * set the speed mode. Currently we support
+ * only standard and fast mode of operation
+ * TODO - support for fast mode plus (upto 1Mb/s)
+ * and high speed (up to 3.4 Mb/s)
+ */
+ if (dev->cfg.sm > I2C_FREQ_MODE_FAST) {
+ dev_err(&dev->pdev->dev, "do not support this mode "
+ "defaulting to std. mode\n");
+ brcr2 = i2c_clk/(100000 * 2) & 0xffff;
+ writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
+ writel(I2C_FREQ_MODE_STANDARD << 4,
+ dev->virtbase + I2C_CR);
+ }
+ writel(dev->cfg.sm << 4, dev->virtbase + I2C_CR);
+
+ /* set the Tx and Rx FIFO threshold */
+ writel(dev->cfg.tft, dev->virtbase + I2C_TFTR);
+ writel(dev->cfg.rft, dev->virtbase + I2C_RFTR);
+}
+
+/**
+ * read_i2c() - Read from I2C client device
+ * @dev: private data of I2C Driver
+ *
+ * This function reads from i2c client device when controller is in
+ * master mode. There is a completion timeout. If there is no transfer
+ * before timeout error is returned.
+ */
+static int read_i2c(struct nmk_i2c_dev *dev)
+{
+ u32 status = 0;
+ u32 mcr;
+ u32 irq_mask = 0;
+ int timeout;
+
+ mcr = load_i2c_mcr_reg(dev);
+ writel(mcr, dev->virtbase + I2C_MCR);
+
+ /* load the current CR value */
+ writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
+ dev->virtbase + I2C_CR);
+
+ /* enable the controller */
+ i2c_set_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+
+ init_completion(&dev->xfer_complete);
+
+ /* enable interrupts by setting the mask */
+ irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF |
+ I2C_IT_MAL | I2C_IT_BERR);
+
+ if (dev->stop)
+ irq_mask |= I2C_IT_MTD;
+ else
+ irq_mask |= I2C_IT_MTDWS;
+
+ irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
+
+ writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
+ dev->virtbase + I2C_IMSCR);
+
+ timeout = wait_for_completion_interruptible_timeout(
+ &dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
+
+ if (timeout < 0) {
+ dev_err(&dev->pdev->dev,
+ "wait_for_completion_interruptible_timeout"
+ "returned %d waiting for event\n", timeout);
+ status = timeout;
+ }
+
+ if (timeout == 0) {
+ /* controler has timedout, re-init the h/w */
+ dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
+ (void) init_hw(dev);
+ status = -ETIMEDOUT;
+ }
+
+ return status;
+}
+
+/**
+ * write_i2c() - Write data to I2C client.
+ * @dev: private data of I2C Driver
+ *
+ * This function writes data to I2C client
+ */
+static int write_i2c(struct nmk_i2c_dev *dev)
+{
+ u32 status = 0;
+ u32 mcr;
+ u32 irq_mask = 0;
+ int timeout;
+
+ mcr = load_i2c_mcr_reg(dev);
+
+ writel(mcr, dev->virtbase + I2C_MCR);
+
+ /* load the current CR value */
+ writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
+ dev->virtbase + I2C_CR);
+
+ /* enable the controller */
+ i2c_set_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
+
+ init_completion(&dev->xfer_complete);
+
+ /* enable interrupts by settings the masks */
+ irq_mask = (I2C_IT_TXFNE | I2C_IT_TXFOVR |
+ I2C_IT_MAL | I2C_IT_BERR);
+
+ /*
+ * check if we want to transfer a single or multiple bytes, if so
+ * set the MTDWS bit (Master Transaction Done Without Stop)
+ * to start repeated start operation
+ */
+ if (dev->stop)
+ irq_mask |= I2C_IT_MTD;
+ else
+ irq_mask |= I2C_IT_MTDWS;
+
+ irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
+
+ writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
+ dev->virtbase + I2C_IMSCR);
+
+ timeout = wait_for_completion_interruptible_timeout(
+ &dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
+
+ if (timeout < 0) {
+ dev_err(&dev->pdev->dev,
+ "wait_for_completion_interruptible_timeout"
+ "returned %d waiting for event\n", timeout);
+ status = timeout;
+ }
+
+ if (timeout == 0) {
+ /* controler has timedout, re-init the h/w */
+ dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
+ (void) init_hw(dev);
+ status = -ETIMEDOUT;
+ }
+
+ return status;
+}
+
+/**
+ * nmk_i2c_xfer() - I2C transfer function used by kernel framework
+ * @i2c_adap - Adapter pointer to the controller
+ * @msgs[] - Pointer to data to be written.
+ * @num_msgs - Number of messages to be executed
+ *
+ * This is the function called by the generic kernel i2c_transfer()
+ * or i2c_smbus...() API calls. Note that this code is protected by the
+ * semaphore set in the kernel i2c_transfer() function.
+ *
+ * NOTE:
+ * READ TRANSFER : We impose a restriction of the first message to be the
+ * index message for any read transaction.
+ * - a no index is coded as '0',
+ * - 2byte big endian index is coded as '3'
+ * !!! msg[0].buf holds the actual index.
+ * This is compatible with generic messages of smbus emulator
+ * that send a one byte index.
+ * eg. a I2C transation to read 2 bytes from index 0
+ * idx = 0;
+ * msg[0].addr = client->addr;
+ * msg[0].flags = 0x0;
+ * msg[0].len = 1;
+ * msg[0].buf = &idx;
+ *
+ * msg[1].addr = client->addr;
+ * msg[1].flags = I2C_M_RD;
+ * msg[1].len = 2;
+ * msg[1].buf = rd_buff
+ * i2c_transfer(adap, msg, 2);
+ *
+ * WRITE TRANSFER : The I2C standard interface interprets all data as payload.
+ * If you want to emulate an SMBUS write transaction put the
+ * index as first byte(or first and second) in the payload.
+ * eg. a I2C transation to write 2 bytes from index 1
+ * wr_buff[0] = 0x1;
+ * wr_buff[1] = 0x23;
+ * wr_buff[2] = 0x46;
+ * msg[0].flags = 0x0;
+ * msg[0].len = 3;
+ * msg[0].buf = wr_buff;
+ * i2c_transfer(adap, msg, 1);
+ *
+ * To read or write a block of data (multiple bytes) using SMBUS emulation
+ * please use the i2c_smbus_read_i2c_block_data()
+ * or i2c_smbus_write_i2c_block_data() API
+ */
+static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg msgs[], int num_msgs)
+{
+ int status;
+ int i;
+ u32 cause;
+ struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
+
+ status = init_hw(dev);
+ if (status)
+ return status;
+
+ /* setup the i2c controller */
+ setup_i2c_controller(dev);
+
+ for (i = 0; i < num_msgs; i++) {
+ if (unlikely(msgs[i].flags & I2C_M_TEN)) {
+ dev_err(&dev->pdev->dev, "10 bit addressing"
+ "not supported\n");
+ return -EINVAL;
+ }
+ dev->cli.slave_adr = msgs[i].addr;
+ dev->cli.buffer = msgs[i].buf;
+ dev->cli.count = msgs[i].len;
+ dev->stop = (i < (num_msgs - 1)) ? 0 : 1;
+ dev->result = 0;
+
+ if (msgs[i].flags & I2C_M_RD) {
+ /* it is a read operation */
+ dev->cli.operation = I2C_READ;
+ status = read_i2c(dev);
+ } else {
+ /* write operation */
+ dev->cli.operation = I2C_WRITE;
+ status = write_i2c(dev);
+ }
+ if (status || (dev->result)) {
+ /* get the abort cause */
+ cause = (readl(dev->virtbase + I2C_SR) >> 4) & 0x7;
+ dev_err(&dev->pdev->dev, "error during I2C"
+ "message xfer: %d\n", cause);
+ dev_err(&dev->pdev->dev, "%s\n",
+ cause >= ARRAY_SIZE(abort_causes)
+ ? "unknown reason" : abort_causes[cause]);
+ return status;
+ }
+ mdelay(1);
+ }
+ /* return the no. messages processed */
+ if (status)
+ return status;
+ else
+ return num_msgs;
+}
+
+/**
+ * disable_interrupts() - disable the interrupts
+ * @dev: private data of controller
+ */
+static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq)
+{
+ irq = IRQ_MASK(irq);
+ writel(readl(dev->virtbase + I2C_IMSCR) & ~(I2C_CLEAR_ALL_INTS & irq),
+ dev->virtbase + I2C_IMSCR);
+ return 0;
+}
+
+/**
+ * i2c_irq_handler() - interrupt routine
+ * @irq: interrupt number
+ * @arg: data passed to the handler
+ *
+ * This is the interrupt handler for the i2c driver. Currently
+ * it handles the major interrupts like Rx & Tx FIFO management
+ * interrupts, master transaction interrupts, arbitration and
+ * bus error interrupts. The rest of the interrupts are treated as
+ * unhandled.
+ */
+static irqreturn_t i2c_irq_handler(int irq, void *arg)
+{
+ struct nmk_i2c_dev *dev = arg;
+ u32 tft, rft;
+ u32 count;
+ u32 misr;
+ u32 src = 0;
+
+ /* load Tx FIFO and Rx FIFO threshold values */
+ tft = readl(dev->virtbase + I2C_TFTR);
+ rft = readl(dev->virtbase + I2C_RFTR);
+
+ /* read interrupt status register */
+ misr = readl(dev->virtbase + I2C_MISR);
+
+ src = __ffs(misr);
+ switch ((1 << src)) {
+
+ /* Transmit FIFO nearly empty interrupt */
+ case I2C_IT_TXFNE:
+ {
+ if (dev->cli.operation == I2C_READ) {
+ /*
+ * in read operation why do we care for writing?
+ * so disable the Transmit FIFO interrupt
+ */
+ disable_interrupts(dev, I2C_IT_TXFNE);
+ } else {
+ for (count = (MAX_I2C_FIFO_THRESHOLD - tft - 2);
+ (count > 0) &&
+ (dev->cli.count != 0);
+ count--) {
+ /* write to the Tx FIFO */
+ writeb(*dev->cli.buffer,
+ dev->virtbase + I2C_TFR);
+ dev->cli.buffer++;
+ dev->cli.count--;
+ dev->cli.xfer_bytes++;
+ }
+ /*
+ * if done, close the transfer by disabling the
+ * corresponding TXFNE interrupt
+ */
+ if (dev->cli.count == 0)
+ disable_interrupts(dev, I2C_IT_TXFNE);
+ }
+ }
+ break;
+
+ /*
+ * Rx FIFO nearly full interrupt.
+ * This is set when the numer of entries in Rx FIFO is
+ * greater or equal than the threshold value programmed
+ * in RFT
+ */
+ case I2C_IT_RXFNF:
+ for (count = rft; count > 0; count--) {
+ /* Read the Rx FIFO */
+ *dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
+ dev->cli.buffer++;
+ }
+ dev->cli.count -= rft;
+ dev->cli.xfer_bytes += rft;
+ break;
+
+ /* Rx FIFO full */
+ case I2C_IT_RXFF:
+ for (count = MAX_I2C_FIFO_THRESHOLD; count > 0; count--) {
+ *dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
+ dev->cli.buffer++;
+ }
+ dev->cli.count -= MAX_I2C_FIFO_THRESHOLD;
+ dev->cli.xfer_bytes += MAX_I2C_FIFO_THRESHOLD;
+ break;
+
+ /* Master Transaction Done with/without stop */
+ case I2C_IT_MTD:
+ case I2C_IT_MTDWS:
+ if (dev->cli.operation == I2C_READ) {
+ while (!readl(dev->virtbase + I2C_RISR) & I2C_IT_RXFE) {
+ if (dev->cli.count == 0)
+ break;
+ *dev->cli.buffer =
+ readb(dev->virtbase + I2C_RFR);
+ dev->cli.buffer++;
+ dev->cli.count--;
+ dev->cli.xfer_bytes++;
+ }
+ }
+
+ i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MTD);
+ i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MTDWS);
+
+ disable_interrupts(dev,
+ (I2C_IT_TXFNE | I2C_IT_TXFE | I2C_IT_TXFF
+ | I2C_IT_TXFOVR | I2C_IT_RXFNF
+ | I2C_IT_RXFF | I2C_IT_RXFE));
+
+ if (dev->cli.count) {
+ dev->result = -1;
+ dev_err(&dev->pdev->dev, "%lu bytes still remain to be"
+ "xfered\n", dev->cli.count);
+ (void) init_hw(dev);
+ }
+ complete(&dev->xfer_complete);
+
+ break;
+
+ /* Master Arbitration lost interrupt */
+ case I2C_IT_MAL:
+ dev->result = -1;
+ (void) init_hw(dev);
+
+ i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MAL);
+ complete(&dev->xfer_complete);
+
+ break;
+
+ /*
+ * Bus Error interrupt.
+ * This happens when an unexpected start/stop condition occurs
+ * during the transaction.
+ */
+ case I2C_IT_BERR:
+ dev->result = -1;
+ /* get the status */
+ if (((readl(dev->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
+ (void) init_hw(dev);
+
+ i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_BERR);
+ complete(&dev->xfer_complete);
+
+ break;
+
+ /*
+ * Tx FIFO overrun interrupt.
+ * This is set when a write operation in Tx FIFO is performed and
+ * the Tx FIFO is full.
+ */
+ case I2C_IT_TXFOVR:
+ dev->result = -1;
+ (void) init_hw(dev);
+
+ dev_err(&dev->pdev->dev, "Tx Fifo Over run\n");
+ complete(&dev->xfer_complete);
+
+ break;
+
+ /* unhandled interrupts by this driver - TODO*/
+ case I2C_IT_TXFE:
+ case I2C_IT_TXFF:
+ case I2C_IT_RXFE:
+ case I2C_IT_RFSR:
+ case I2C_IT_RFSE:
+ case I2C_IT_WTSR:
+ case I2C_IT_STD:
+ dev_err(&dev->pdev->dev, "unhandled Interrupt\n");
+ break;
+ default:
+ dev_err(&dev->pdev->dev, "spurious Interrupt..\n");
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C
+ | I2C_FUNC_SMBUS_BYTE_DATA
+ | I2C_FUNC_SMBUS_WORD_DATA
+ | I2C_FUNC_SMBUS_I2C_BLOCK;
+}
+
+static const struct i2c_algorithm nmk_i2c_algo = {
+ .master_xfer = nmk_i2c_xfer,
+ .functionality = nmk_i2c_functionality
+};
+
+static int __devinit nmk_i2c_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct resource *res;
+ struct nmk_i2c_controller *pdata =
+ pdev->dev.platform_data;
+ struct nmk_i2c_dev *dev;
+ struct i2c_adapter *adap;
+
+ dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
+ if (!dev) {
+ dev_err(&pdev->dev, "cannot allocate memory\n");
+ ret = -ENOMEM;
+ goto err_no_mem;
+ }
+
+ dev->pdev = pdev;
+ platform_set_drvdata(pdev, dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENOENT;
+ goto err_no_resource;
+ }
+
+ if (request_mem_region(res->start, resource_size(res),
+ DRIVER_NAME "I/O region") == NULL) {
+ ret = -EBUSY;
+ goto err_no_region;
+ }
+
+ dev->virtbase = ioremap(res->start, resource_size(res));
+ if (!dev->virtbase) {
+ ret = -ENOMEM;
+ goto err_no_ioremap;
+ }
+
+ dev->irq = platform_get_irq(pdev, 0);
+ ret = request_irq(dev->irq, i2c_irq_handler, IRQF_DISABLED,
+ DRIVER_NAME, dev);
+ if (ret) {
+ dev_err(&pdev->dev, "cannot claim the irq %d\n", dev->irq);
+ goto err_irq;
+ }
+
+ dev->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(dev->clk)) {
+ dev_err(&pdev->dev, "could not get i2c clock\n");
+ ret = PTR_ERR(dev->clk);
+ goto err_no_clk;
+ }
+
+ clk_enable(dev->clk);
+
+ adap = &dev->adap;
+ adap->dev.parent = &pdev->dev;
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ adap->algo = &nmk_i2c_algo;
+
+ /* fetch the controller id */
+ adap->nr = pdev->id;
+
+ /* fetch the controller configuration from machine */
+ dev->cfg.clk_freq = pdata->clk_freq;
+ dev->cfg.slsu = pdata->slsu;
+ dev->cfg.tft = pdata->tft;
+ dev->cfg.rft = pdata->rft;
+ dev->cfg.sm = pdata->sm;
+
+ i2c_set_adapdata(adap, dev);
+
+ ret = init_hw(dev);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "error in initializing i2c hardware\n");
+ goto err_init_hw;
+ }
+
+ dev_dbg(&pdev->dev, "initialize I2C%d bus on virtual "
+ "base %p\n", pdev->id, dev->virtbase);
+
+ ret = i2c_add_numbered_adapter(adap);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add adapter\n");
+ goto err_add_adap;
+ }
+
+ return 0;
+
+ err_init_hw:
+ clk_disable(dev->clk);
+ err_add_adap:
+ clk_put(dev->clk);
+ err_no_clk:
+ free_irq(dev->irq, dev);
+ err_irq:
+ iounmap(dev->virtbase);
+ err_no_ioremap:
+ release_mem_region(res->start, resource_size(res));
+ err_no_region:
+ platform_set_drvdata(pdev, NULL);
+ err_no_resource:
+ kfree(dev);
+ err_no_mem:
+
+ return ret;
+}
+
+static int __devexit nmk_i2c_remove(struct platform_device *pdev)
+{
+ struct nmk_i2c_dev *dev = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&dev->adap);
+ flush_i2c_fifo(dev);
+ disable_all_interrupts(dev);
+ clear_all_interrupts(dev);
+ /* disable the controller */
+ i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
+ free_irq(dev->irq, dev);
+ iounmap(dev->virtbase);
+ clk_disable(dev->clk);
+ clk_put(dev->clk);
+ platform_set_drvdata(pdev, NULL);
+ kfree(dev);
+
+ return 0;
+}
+
+static struct platform_driver nmk_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ },
+ .probe = nmk_i2c_probe,
+ .remove = __devexit_p(nmk_i2c_remove),
+};
+
+static int __init nmk_i2c_init(void)
+{
+ return platform_driver_register(&nmk_i2c_driver);
+}
+
+static void __exit nmk_i2c_exit(void)
+{
+ platform_driver_unregister(&nmk_i2c_driver);
+}
+
+subsys_initcall(nmk_i2c_init);
+module_exit(nmk_i2c_exit);
+
+MODULE_AUTHOR("Sachin Verma, Srinidhi KASAGAR");
+MODULE_DESCRIPTION("Nomadik/Ux500 I2C driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 0dabe643ec5..b4ed4ca802e 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/i2c-ocores.h>
+#include <linux/slab.h>
#include <asm/io.h>
struct ocores_i2c {
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c
index 60375504fa4..a2481f40ea1 100644
--- a/drivers/i2c/busses/i2c-octeon.c
+++ b/drivers/i2c/busses/i2c-octeon.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/io.h>
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0037e31076b..389ac6032a7 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -37,6 +37,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
/* I2C controller revisions */
#define OMAP_I2C_REV_2 0x20
@@ -49,24 +50,24 @@
#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
#define OMAP_I2C_REV_REG 0x00
-#define OMAP_I2C_IE_REG 0x04
-#define OMAP_I2C_STAT_REG 0x08
-#define OMAP_I2C_IV_REG 0x0c
+#define OMAP_I2C_IE_REG 0x01
+#define OMAP_I2C_STAT_REG 0x02
+#define OMAP_I2C_IV_REG 0x03
/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
-#define OMAP_I2C_WE_REG 0x0c
-#define OMAP_I2C_SYSS_REG 0x10
-#define OMAP_I2C_BUF_REG 0x14
-#define OMAP_I2C_CNT_REG 0x18
-#define OMAP_I2C_DATA_REG 0x1c
-#define OMAP_I2C_SYSC_REG 0x20
-#define OMAP_I2C_CON_REG 0x24
-#define OMAP_I2C_OA_REG 0x28
-#define OMAP_I2C_SA_REG 0x2c
-#define OMAP_I2C_PSC_REG 0x30
-#define OMAP_I2C_SCLL_REG 0x34
-#define OMAP_I2C_SCLH_REG 0x38
-#define OMAP_I2C_SYSTEST_REG 0x3c
-#define OMAP_I2C_BUFSTAT_REG 0x40
+#define OMAP_I2C_WE_REG 0x03
+#define OMAP_I2C_SYSS_REG 0x04
+#define OMAP_I2C_BUF_REG 0x05
+#define OMAP_I2C_CNT_REG 0x06
+#define OMAP_I2C_DATA_REG 0x07
+#define OMAP_I2C_SYSC_REG 0x08
+#define OMAP_I2C_CON_REG 0x09
+#define OMAP_I2C_OA_REG 0x0a
+#define OMAP_I2C_SA_REG 0x0b
+#define OMAP_I2C_PSC_REG 0x0c
+#define OMAP_I2C_SCLL_REG 0x0d
+#define OMAP_I2C_SCLH_REG 0x0e
+#define OMAP_I2C_SYSTEST_REG 0x0f
+#define OMAP_I2C_BUFSTAT_REG 0x10
/* I2C Interrupt Enable Register (OMAP_I2C_IE): */
#define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */
@@ -161,6 +162,7 @@ struct omap_i2c_dev {
struct device *dev;
void __iomem *base; /* virtual */
int irq;
+ int reg_shift; /* bit shift for I2C register addresses */
struct clk *iclk; /* Interface clock */
struct clk *fclk; /* Functional clock */
struct completion cmd_complete;
@@ -189,12 +191,12 @@ struct omap_i2c_dev {
static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
int reg, u16 val)
{
- __raw_writew(val, i2c_dev->base + reg);
+ __raw_writew(val, i2c_dev->base + (reg << i2c_dev->reg_shift));
}
static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
{
- return __raw_readw(i2c_dev->base + reg);
+ return __raw_readw(i2c_dev->base + (reg << i2c_dev->reg_shift));
}
static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
@@ -849,7 +851,7 @@ static const struct i2c_algorithm omap_i2c_algo = {
.functionality = omap_i2c_func,
};
-static int __init
+static int __devinit
omap_i2c_probe(struct platform_device *pdev)
{
struct omap_i2c_dev *dev;
@@ -901,6 +903,11 @@ omap_i2c_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
+ if (cpu_is_omap7xx())
+ dev->reg_shift = 1;
+ else
+ dev->reg_shift = 2;
+
if ((r = omap_i2c_get_clocks(dev)) != 0)
goto err_iounmap;
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 220fca7f23a..846583ed476 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -32,6 +32,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-smbus.h>
+#include <linux/slab.h>
#include "i2c-parport.h"
/* ----- Device list ------------------------------------------------------ */
diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c
index 0d20ff46a51..d3d4a4b43a1 100644
--- a/drivers/i2c/busses/i2c-pasemi.c
+++ b/drivers/i2c/busses/i2c-pasemi.c
@@ -24,6 +24,7 @@
#include <linux/sched.h>
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/io.h>
static struct pci_driver pasemi_smb_driver;
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 2b0bd0b042d..a97e3fec814 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -22,6 +22,7 @@
#include <linux/io.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/i2c.h>
@@ -172,11 +173,8 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
/* We still have something to talk about... */
val = *alg_data->mif.buf++;
- if (alg_data->mif.len == 1) {
+ if (alg_data->mif.len == 1)
val |= stop_bit;
- if (!alg_data->last)
- val |= start_bit;
- }
alg_data->mif.len--;
iowrite32(val, I2C_REG_TX(alg_data));
@@ -253,8 +251,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
if (alg_data->mif.len == 1) {
/* Last byte, do not acknowledge next rcv. */
val |= stop_bit;
- if (!alg_data->last)
- val |= start_bit;
/*
* Enable interrupt RFDAIE (data in Rx fifo),
@@ -643,6 +639,8 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
*/
tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+ if (tmp > 0x3FF)
+ tmp = 0x3FF;
iowrite32(tmp, I2C_REG_CKH(alg_data));
iowrite32(tmp, I2C_REG_CKL(alg_data));
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 1c440a70ec6..b289ec99eeb 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -122,9 +122,14 @@ static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap,
rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len);
if (rc) {
- dev_err(&adap->dev,
- "I2C transfer at 0x%02x failed, size %d, err %d\n",
- addrdir >> 1, size, rc);
+ if (rc == -ENXIO)
+ dev_dbg(&adap->dev,
+ "I2C transfer at 0x%02x failed, size %d, "
+ "err %d\n", addrdir >> 1, size, rc);
+ else
+ dev_err(&adap->dev,
+ "I2C transfer at 0x%02x failed, size %d, "
+ "err %d\n", addrdir >> 1, size, rc);
goto bail;
}
@@ -175,10 +180,16 @@ static int i2c_powermac_master_xfer( struct i2c_adapter *adap,
goto bail;
}
rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
- if (rc < 0)
- dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
- addrdir & 1 ? "read from" : "write to", addrdir >> 1,
- rc);
+ if (rc < 0) {
+ if (rc == -ENXIO)
+ dev_dbg(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
+ addrdir & 1 ? "read from" : "write to",
+ addrdir >> 1, rc);
+ else
+ dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
+ addrdir & 1 ? "read from" : "write to",
+ addrdir >> 1, rc);
+ }
bail:
pmac_i2c_close(bus);
return rc < 0 ? rc : 1;
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 7647a20523a..14d249f5ed3 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -12,7 +12,7 @@
*
* History:
* Apr 2002: Initial version [CS]
- * Jun 2002: Properly seperated algo/adap [FB]
+ * Jun 2002: Properly separated algo/adap [FB]
* Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
* Jan 2003: added limited signal handling [Kai-Uwe Bloem]
* Sep 2004: Major rework to ensure efficient bus handling [RMK]
@@ -33,6 +33,7 @@
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <asm/io.h>
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 1d8c98613fa..d27072b2249 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -34,6 +34,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <asm/io.h>
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c
index 365e0becaf1..388cbdc96db 100644
--- a/drivers/i2c/busses/i2c-scmi.c
+++ b/drivers/i2c/busses/i2c-scmi.c
@@ -33,6 +33,7 @@ struct acpi_smbus_cmi {
u8 cap_info:1;
u8 cap_read:1;
u8 cap_write:1;
+ struct smbus_methods_t *methods;
};
static const struct smbus_methods_t smbus_methods = {
@@ -41,10 +42,19 @@ static const struct smbus_methods_t smbus_methods = {
.mt_sbw = "_SBW",
};
+/* Some IBM BIOSes omit the leading underscore */
+static const struct smbus_methods_t ibm_smbus_methods = {
+ .mt_info = "SBI_",
+ .mt_sbr = "SBR_",
+ .mt_sbw = "SBW_",
+};
+
static const struct acpi_device_id acpi_smbus_cmi_ids[] = {
- {"SMBUS01", 0},
+ {"SMBUS01", (kernel_ulong_t)&smbus_methods},
+ {ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods},
{"", 0}
};
+MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids);
#define ACPI_SMBUS_STATUS_OK 0x00
#define ACPI_SMBUS_STATUS_FAIL 0x07
@@ -150,11 +160,11 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
if (read_write == I2C_SMBUS_READ) {
protocol |= ACPI_SMBUS_PRTCL_READ;
- method = smbus_methods.mt_sbr;
+ method = smbus_cmi->methods->mt_sbr;
input.count = 3;
} else {
protocol |= ACPI_SMBUS_PRTCL_WRITE;
- method = smbus_methods.mt_sbw;
+ method = smbus_cmi->methods->mt_sbw;
input.count = 5;
}
@@ -290,13 +300,13 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
union acpi_object *obj;
acpi_status status;
- if (!strcmp(name, smbus_methods.mt_info)) {
+ if (!strcmp(name, smbus_cmi->methods->mt_info)) {
status = acpi_evaluate_object(smbus_cmi->handle,
- smbus_methods.mt_info,
+ smbus_cmi->methods->mt_info,
NULL, &buffer);
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "Evaluating %s: %i",
- smbus_methods.mt_info, status));
+ smbus_cmi->methods->mt_info, status));
return -EIO;
}
@@ -319,9 +329,9 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
kfree(buffer.pointer);
smbus_cmi->cap_info = 1;
- } else if (!strcmp(name, smbus_methods.mt_sbr))
+ } else if (!strcmp(name, smbus_cmi->methods->mt_sbr))
smbus_cmi->cap_read = 1;
- else if (!strcmp(name, smbus_methods.mt_sbw))
+ else if (!strcmp(name, smbus_cmi->methods->mt_sbw))
smbus_cmi->cap_write = 1;
else
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported CMI method: %s\n",
@@ -349,6 +359,7 @@ static acpi_status acpi_smbus_cmi_query_methods(acpi_handle handle, u32 level,
static int acpi_smbus_cmi_add(struct acpi_device *device)
{
struct acpi_smbus_cmi *smbus_cmi;
+ const struct acpi_device_id *id;
smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL);
if (!smbus_cmi)
@@ -362,6 +373,11 @@ static int acpi_smbus_cmi_add(struct acpi_device *device)
smbus_cmi->cap_read = 0;
smbus_cmi->cap_write = 0;
+ for (id = acpi_smbus_cmi_ids; id->id[0]; id++)
+ if (!strcmp(id->id, acpi_device_hid(device)))
+ smbus_cmi->methods =
+ (struct smbus_methods_t *) id->driver_data;
+
acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index ccc46418ef7..ffb405d7c6f 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -31,6 +31,7 @@
#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
/* Transmit operation: */
/* */
diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c
index 6407f47bda8..78b06107342 100644
--- a/drivers/i2c/busses/i2c-simtec.c
+++ b/drivers/i2c/busses/i2c-simtec.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c
index d2728a28a8d..495be451d32 100644
--- a/drivers/i2c/busses/i2c-stu300.c
+++ b/drivers/i2c/busses/i2c-stu300.c
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
/* the name of this kernel module */
#define NAME "stu300"
@@ -497,7 +498,7 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
int i = 0;
/* Locate the apropriate clock setting */
- while (i < ARRAY_SIZE(stu300_clktable) &&
+ while (i < ARRAY_SIZE(stu300_clktable) - 1 &&
stu300_clktable[i].rate < clkrate)
i++;
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c
index b5b1bbf37d3..d03b04002f0 100644
--- a/drivers/i2c/busses/i2c-tiny-usb.c
+++ b/drivers/i2c/busses/i2c-tiny-usb.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
/* include interfaces to usb layer */
diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c
index 70de8216346..5c473833d94 100644
--- a/drivers/i2c/busses/i2c-versatile.c
+++ b/drivers/i2c/busses/i2c-versatile.c
@@ -14,6 +14,7 @@
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
new file mode 100644
index 00000000000..a9c419e075a
--- /dev/null
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -0,0 +1,826 @@
+/*
+ * i2c-xiic.c
+ * Copyright (c) 2002-2007 Xilinx Inc.
+ * Copyright (c) 2009-2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in 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.
+ *
+ *
+ * This code was implemented by Mocean Laboratories AB when porting linux
+ * to the automotive development board Russellville. The copyright holder
+ * as seen in the header is Intel corporation.
+ * Mocean Laboratories forked off the GNU/Linux platform work into a
+ * separate company called Pelagicore AB, which commited the code to the
+ * kernel.
+ */
+
+/* Supports:
+ * Xilinx IIC
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/i2c-xiic.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define DRIVER_NAME "xiic-i2c"
+
+enum xilinx_i2c_state {
+ STATE_DONE,
+ STATE_ERROR,
+ STATE_START
+};
+
+/**
+ * struct xiic_i2c - Internal representation of the XIIC I2C bus
+ * @base: Memory base of the HW registers
+ * @wait: Wait queue for callers
+ * @adap: Kernel adapter representation
+ * @tx_msg: Messages from above to be sent
+ * @lock: Mutual exclusion
+ * @tx_pos: Current pos in TX message
+ * @nmsgs: Number of messages in tx_msg
+ * @state: See STATE_
+ * @rx_msg: Current RX message
+ * @rx_pos: Position within current RX message
+ */
+struct xiic_i2c {
+ void __iomem *base;
+ wait_queue_head_t wait;
+ struct i2c_adapter adap;
+ struct i2c_msg *tx_msg;
+ spinlock_t lock;
+ unsigned int tx_pos;
+ unsigned int nmsgs;
+ enum xilinx_i2c_state state;
+ struct i2c_msg *rx_msg;
+ int rx_pos;
+};
+
+
+#define XIIC_MSB_OFFSET 0
+#define XIIC_REG_OFFSET (0x100+XIIC_MSB_OFFSET)
+
+/*
+ * Register offsets in bytes from RegisterBase. Three is added to the
+ * base offset to access LSB (IBM style) of the word
+ */
+#define XIIC_CR_REG_OFFSET (0x00+XIIC_REG_OFFSET) /* Control Register */
+#define XIIC_SR_REG_OFFSET (0x04+XIIC_REG_OFFSET) /* Status Register */
+#define XIIC_DTR_REG_OFFSET (0x08+XIIC_REG_OFFSET) /* Data Tx Register */
+#define XIIC_DRR_REG_OFFSET (0x0C+XIIC_REG_OFFSET) /* Data Rx Register */
+#define XIIC_ADR_REG_OFFSET (0x10+XIIC_REG_OFFSET) /* Address Register */
+#define XIIC_TFO_REG_OFFSET (0x14+XIIC_REG_OFFSET) /* Tx FIFO Occupancy */
+#define XIIC_RFO_REG_OFFSET (0x18+XIIC_REG_OFFSET) /* Rx FIFO Occupancy */
+#define XIIC_TBA_REG_OFFSET (0x1C+XIIC_REG_OFFSET) /* 10 Bit Address reg */
+#define XIIC_RFD_REG_OFFSET (0x20+XIIC_REG_OFFSET) /* Rx FIFO Depth reg */
+#define XIIC_GPO_REG_OFFSET (0x24+XIIC_REG_OFFSET) /* Output Register */
+
+/* Control Register masks */
+#define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */
+#define XIIC_CR_TX_FIFO_RESET_MASK 0x02 /* Transmit FIFO reset=1 */
+#define XIIC_CR_MSMS_MASK 0x04 /* Master starts Txing=1 */
+#define XIIC_CR_DIR_IS_TX_MASK 0x08 /* Dir of tx. Txing=1 */
+#define XIIC_CR_NO_ACK_MASK 0x10 /* Tx Ack. NO ack = 1 */
+#define XIIC_CR_REPEATED_START_MASK 0x20 /* Repeated start = 1 */
+#define XIIC_CR_GENERAL_CALL_MASK 0x40 /* Gen Call enabled = 1 */
+
+/* Status Register masks */
+#define XIIC_SR_GEN_CALL_MASK 0x01 /* 1=a mstr issued a GC */
+#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x02 /* 1=when addr as slave */
+#define XIIC_SR_BUS_BUSY_MASK 0x04 /* 1 = bus is busy */
+#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x08 /* 1=Dir: mstr <-- slave */
+#define XIIC_SR_TX_FIFO_FULL_MASK 0x10 /* 1 = Tx FIFO full */
+#define XIIC_SR_RX_FIFO_FULL_MASK 0x20 /* 1 = Rx FIFO full */
+#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x40 /* 1 = Rx FIFO empty */
+#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x80 /* 1 = Tx FIFO empty */
+
+/* Interrupt Status Register masks Interrupt occurs when... */
+#define XIIC_INTR_ARB_LOST_MASK 0x01 /* 1 = arbitration lost */
+#define XIIC_INTR_TX_ERROR_MASK 0x02 /* 1=Tx error/msg complete */
+#define XIIC_INTR_TX_EMPTY_MASK 0x04 /* 1 = Tx FIFO/reg empty */
+#define XIIC_INTR_RX_FULL_MASK 0x08 /* 1=Rx FIFO/reg=OCY level */
+#define XIIC_INTR_BNB_MASK 0x10 /* 1 = Bus not busy */
+#define XIIC_INTR_AAS_MASK 0x20 /* 1 = when addr as slave */
+#define XIIC_INTR_NAAS_MASK 0x40 /* 1 = not addr as slave */
+#define XIIC_INTR_TX_HALF_MASK 0x80 /* 1 = TX FIFO half empty */
+
+/* The following constants specify the depth of the FIFOs */
+#define IIC_RX_FIFO_DEPTH 16 /* Rx fifo capacity */
+#define IIC_TX_FIFO_DEPTH 16 /* Tx fifo capacity */
+
+/* The following constants specify groups of interrupts that are typically
+ * enabled or disables at the same time
+ */
+#define XIIC_TX_INTERRUPTS \
+(XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)
+
+#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
+
+/* The following constants are used with the following macros to specify the
+ * operation, a read or write operation.
+ */
+#define XIIC_READ_OPERATION 1
+#define XIIC_WRITE_OPERATION 0
+
+/*
+ * Tx Fifo upper bit masks.
+ */
+#define XIIC_TX_DYN_START_MASK 0x0100 /* 1 = Set dynamic start */
+#define XIIC_TX_DYN_STOP_MASK 0x0200 /* 1 = Set dynamic stop */
+
+/*
+ * The following constants define the register offsets for the Interrupt
+ * registers. There are some holes in the memory map for reserved addresses
+ * to allow other registers to be added and still match the memory map of the
+ * interrupt controller registers
+ */
+#define XIIC_DGIER_OFFSET 0x1C /* Device Global Interrupt Enable Register */
+#define XIIC_IISR_OFFSET 0x20 /* Interrupt Status Register */
+#define XIIC_IIER_OFFSET 0x28 /* Interrupt Enable Register */
+#define XIIC_RESETR_OFFSET 0x40 /* Reset Register */
+
+#define XIIC_RESET_MASK 0xAUL
+
+/*
+ * The following constant is used for the device global interrupt enable
+ * register, to enable all interrupts for the device, this is the only bit
+ * in the register
+ */
+#define XIIC_GINTR_ENABLE_MASK 0x80000000UL
+
+#define xiic_tx_space(i2c) ((i2c)->tx_msg->len - (i2c)->tx_pos)
+#define xiic_rx_space(i2c) ((i2c)->rx_msg->len - (i2c)->rx_pos)
+
+static void xiic_start_xfer(struct xiic_i2c *i2c);
+static void __xiic_start_xfer(struct xiic_i2c *i2c);
+
+static inline void xiic_setreg8(struct xiic_i2c *i2c, int reg, u8 value)
+{
+ iowrite8(value, i2c->base + reg);
+}
+
+static inline u8 xiic_getreg8(struct xiic_i2c *i2c, int reg)
+{
+ return ioread8(i2c->base + reg);
+}
+
+static inline void xiic_setreg16(struct xiic_i2c *i2c, int reg, u16 value)
+{
+ iowrite16(value, i2c->base + reg);
+}
+
+static inline void xiic_setreg32(struct xiic_i2c *i2c, int reg, int value)
+{
+ iowrite32(value, i2c->base + reg);
+}
+
+static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg)
+{
+ return ioread32(i2c->base + reg);
+}
+
+static inline void xiic_irq_dis(struct xiic_i2c *i2c, u32 mask)
+{
+ u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
+ xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier & ~mask);
+}
+
+static inline void xiic_irq_en(struct xiic_i2c *i2c, u32 mask)
+{
+ u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
+ xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier | mask);
+}
+
+static inline void xiic_irq_clr(struct xiic_i2c *i2c, u32 mask)
+{
+ u32 isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
+ xiic_setreg32(i2c, XIIC_IISR_OFFSET, isr & mask);
+}
+
+static inline void xiic_irq_clr_en(struct xiic_i2c *i2c, u32 mask)
+{
+ xiic_irq_clr(i2c, mask);
+ xiic_irq_en(i2c, mask);
+}
+
+static void xiic_clear_rx_fifo(struct xiic_i2c *i2c)
+{
+ u8 sr;
+ for (sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
+ !(sr & XIIC_SR_RX_FIFO_EMPTY_MASK);
+ sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET))
+ xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
+}
+
+static void xiic_reinit(struct xiic_i2c *i2c)
+{
+ xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
+
+ /* Set receive Fifo depth to maximum (zero based). */
+ xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1);
+
+ /* Reset Tx Fifo. */
+ xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);
+
+ /* Enable IIC Device, remove Tx Fifo reset & disable general call. */
+ xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);
+
+ /* make sure RX fifo is empty */
+ xiic_clear_rx_fifo(i2c);
+
+ /* Enable interrupts */
+ xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+
+ xiic_irq_clr_en(i2c, XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK);
+}
+
+static void xiic_deinit(struct xiic_i2c *i2c)
+{
+ u8 cr;
+
+ xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
+
+ /* Disable IIC Device. */
+ cr = xiic_getreg8(i2c, XIIC_CR_REG_OFFSET);
+ xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, cr & ~XIIC_CR_ENABLE_DEVICE_MASK);
+}
+
+static void xiic_read_rx(struct xiic_i2c *i2c)
+{
+ u8 bytes_in_fifo;
+ int i;
+
+ bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1;
+
+ dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d"
+ ", SR: 0x%x, CR: 0x%x\n",
+ __func__, bytes_in_fifo, xiic_rx_space(i2c),
+ xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
+ xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+
+ if (bytes_in_fifo > xiic_rx_space(i2c))
+ bytes_in_fifo = xiic_rx_space(i2c);
+
+ for (i = 0; i < bytes_in_fifo; i++)
+ i2c->rx_msg->buf[i2c->rx_pos++] =
+ xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
+
+ xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET,
+ (xiic_rx_space(i2c) > IIC_RX_FIFO_DEPTH) ?
+ IIC_RX_FIFO_DEPTH - 1 : xiic_rx_space(i2c) - 1);
+}
+
+static int xiic_tx_fifo_space(struct xiic_i2c *i2c)
+{
+ /* return the actual space left in the FIFO */
+ return IIC_TX_FIFO_DEPTH - xiic_getreg8(i2c, XIIC_TFO_REG_OFFSET) - 1;
+}
+
+static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
+{
+ u8 fifo_space = xiic_tx_fifo_space(i2c);
+ int len = xiic_tx_space(i2c);
+
+ len = (len > fifo_space) ? fifo_space : len;
+
+ dev_dbg(i2c->adap.dev.parent, "%s entry, len: %d, fifo space: %d\n",
+ __func__, len, fifo_space);
+
+ while (len--) {
+ u16 data = i2c->tx_msg->buf[i2c->tx_pos++];
+ if ((xiic_tx_space(i2c) == 0) && (i2c->nmsgs == 1)) {
+ /* last message in transfer -> STOP */
+ data |= XIIC_TX_DYN_STOP_MASK;
+ dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
+
+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
+ } else
+ xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data);
+ }
+}
+
+static void xiic_wakeup(struct xiic_i2c *i2c, int code)
+{
+ i2c->tx_msg = NULL;
+ i2c->rx_msg = NULL;
+ i2c->nmsgs = 0;
+ i2c->state = code;
+ wake_up(&i2c->wait);
+}
+
+static void xiic_process(struct xiic_i2c *i2c)
+{
+ u32 pend, isr, ier;
+ u32 clr = 0;
+
+ /* Get the interrupt Status from the IPIF. There is no clearing of
+ * interrupts in the IPIF. Interrupts must be cleared at the source.
+ * To find which interrupts are pending; AND interrupts pending with
+ * interrupts masked.
+ */
+ isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
+ ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
+ pend = isr & ier;
+
+ dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, "
+ "pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n",
+ __func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
+ i2c->tx_msg, i2c->nmsgs);
+
+ /* Do not processes a devices interrupts if the device has no
+ * interrupts pending
+ */
+ if (!pend)
+ return;
+
+ /* Service requesting interrupt */
+ if ((pend & XIIC_INTR_ARB_LOST_MASK) ||
+ ((pend & XIIC_INTR_TX_ERROR_MASK) &&
+ !(pend & XIIC_INTR_RX_FULL_MASK))) {
+ /* bus arbritration lost, or...
+ * Transmit error _OR_ RX completed
+ * if this happens when RX_FULL is not set
+ * this is probably a TX error
+ */
+
+ dev_dbg(i2c->adap.dev.parent, "%s error\n", __func__);
+
+ /* dynamic mode seem to suffer from problems if we just flushes
+ * fifos and the next message is a TX with len 0 (only addr)
+ * reset the IP instead of just flush fifos
+ */
+ xiic_reinit(i2c);
+
+ if (i2c->tx_msg)
+ xiic_wakeup(i2c, STATE_ERROR);
+
+ } else if (pend & XIIC_INTR_RX_FULL_MASK) {
+ /* Receive register/FIFO is full */
+
+ clr = XIIC_INTR_RX_FULL_MASK;
+ if (!i2c->rx_msg) {
+ dev_dbg(i2c->adap.dev.parent,
+ "%s unexpexted RX IRQ\n", __func__);
+ xiic_clear_rx_fifo(i2c);
+ goto out;
+ }
+
+ xiic_read_rx(i2c);
+ if (xiic_rx_space(i2c) == 0) {
+ /* this is the last part of the message */
+ i2c->rx_msg = NULL;
+
+ /* also clear TX error if there (RX complete) */
+ clr |= (isr & XIIC_INTR_TX_ERROR_MASK);
+
+ dev_dbg(i2c->adap.dev.parent,
+ "%s end of message, nmsgs: %d\n",
+ __func__, i2c->nmsgs);
+
+ /* send next message if this wasn't the last,
+ * otherwise the transfer will be finialise when
+ * receiving the bus not busy interrupt
+ */
+ if (i2c->nmsgs > 1) {
+ i2c->nmsgs--;
+ i2c->tx_msg++;
+ dev_dbg(i2c->adap.dev.parent,
+ "%s will start next...\n", __func__);
+
+ __xiic_start_xfer(i2c);
+ }
+ }
+ } else if (pend & XIIC_INTR_BNB_MASK) {
+ /* IIC bus has transitioned to not busy */
+ clr = XIIC_INTR_BNB_MASK;
+
+ /* The bus is not busy, disable BusNotBusy interrupt */
+ xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK);
+
+ if (!i2c->tx_msg)
+ goto out;
+
+ if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
+ xiic_tx_space(i2c) == 0)
+ xiic_wakeup(i2c, STATE_DONE);
+ else
+ xiic_wakeup(i2c, STATE_ERROR);
+
+ } else if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
+ /* Transmit register/FIFO is empty or ½ empty */
+
+ clr = pend &
+ (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK);
+
+ if (!i2c->tx_msg) {
+ dev_dbg(i2c->adap.dev.parent,
+ "%s unexpexted TX IRQ\n", __func__);
+ goto out;
+ }
+
+ xiic_fill_tx_fifo(i2c);
+
+ /* current message sent and there is space in the fifo */
+ if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) {
+ dev_dbg(i2c->adap.dev.parent,
+ "%s end of message sent, nmsgs: %d\n",
+ __func__, i2c->nmsgs);
+ if (i2c->nmsgs > 1) {
+ i2c->nmsgs--;
+ i2c->tx_msg++;
+ __xiic_start_xfer(i2c);
+ } else {
+ xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
+
+ dev_dbg(i2c->adap.dev.parent,
+ "%s Got TX IRQ but no more to do...\n",
+ __func__);
+ }
+ } else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1))
+ /* current frame is sent and is last,
+ * make sure to disable tx half
+ */
+ xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
+ } else {
+ /* got IRQ which is not acked */
+ dev_err(i2c->adap.dev.parent, "%s Got unexpected IRQ\n",
+ __func__);
+ clr = pend;
+ }
+out:
+ dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
+
+ xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
+}
+
+static int xiic_bus_busy(struct xiic_i2c *i2c)
+{
+ u8 sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
+
+ return (sr & XIIC_SR_BUS_BUSY_MASK) ? -EBUSY : 0;
+}
+
+static int xiic_busy(struct xiic_i2c *i2c)
+{
+ int tries = 3;
+ int err;
+
+ if (i2c->tx_msg)
+ return -EBUSY;
+
+ /* for instance if previous transfer was terminated due to TX error
+ * it might be that the bus is on it's way to become available
+ * give it at most 3 ms to wake
+ */
+ err = xiic_bus_busy(i2c);
+ while (err && tries--) {
+ mdelay(1);
+ err = xiic_bus_busy(i2c);
+ }
+
+ return err;
+}
+
+static void xiic_start_recv(struct xiic_i2c *i2c)
+{
+ u8 rx_watermark;
+ struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg;
+
+ /* Clear and enable Rx full interrupt. */
+ xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK);
+
+ /* we want to get all but last byte, because the TX_ERROR IRQ is used
+ * to inidicate error ACK on the address, and negative ack on the last
+ * received byte, so to not mix them receive all but last.
+ * In the case where there is only one byte to receive
+ * we can check if ERROR and RX full is set at the same time
+ */
+ rx_watermark = msg->len;
+ if (rx_watermark > IIC_RX_FIFO_DEPTH)
+ rx_watermark = IIC_RX_FIFO_DEPTH;
+ xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1);
+
+ if (!(msg->flags & I2C_M_NOSTART))
+ /* write the address */
+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
+ (msg->addr << 1) | XIIC_READ_OPERATION |
+ XIIC_TX_DYN_START_MASK);
+
+ xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
+
+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
+ msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0));
+ if (i2c->nmsgs == 1)
+ /* very last, enable bus not busy as well */
+ xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
+
+ /* the message is tx:ed */
+ i2c->tx_pos = msg->len;
+}
+
+static void xiic_start_send(struct xiic_i2c *i2c)
+{
+ struct i2c_msg *msg = i2c->tx_msg;
+
+ xiic_irq_clr(i2c, XIIC_INTR_TX_ERROR_MASK);
+
+ dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, "
+ "ISR: 0x%x, CR: 0x%x\n",
+ __func__, msg, msg->len, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
+ xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
+
+ if (!(msg->flags & I2C_M_NOSTART)) {
+ /* write the address */
+ u16 data = ((msg->addr << 1) & 0xfe) | XIIC_WRITE_OPERATION |
+ XIIC_TX_DYN_START_MASK;
+ if ((i2c->nmsgs == 1) && msg->len == 0)
+ /* no data and last message -> add STOP */
+ data |= XIIC_TX_DYN_STOP_MASK;
+
+ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
+ }
+
+ xiic_fill_tx_fifo(i2c);
+
+ /* Clear any pending Tx empty, Tx Error and then enable them. */
+ xiic_irq_clr_en(i2c, XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK |
+ XIIC_INTR_BNB_MASK);
+}
+
+static irqreturn_t xiic_isr(int irq, void *dev_id)
+{
+ struct xiic_i2c *i2c = dev_id;
+
+ spin_lock(&i2c->lock);
+ /* disable interrupts globally */
+ xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
+
+ dev_dbg(i2c->adap.dev.parent, "%s entry\n", __func__);
+
+ xiic_process(i2c);
+
+ xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+ spin_unlock(&i2c->lock);
+
+ return IRQ_HANDLED;
+}
+
+static void __xiic_start_xfer(struct xiic_i2c *i2c)
+{
+ int first = 1;
+ int fifo_space = xiic_tx_fifo_space(i2c);
+ dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, fifos space: %d\n",
+ __func__, i2c->tx_msg, fifo_space);
+
+ if (!i2c->tx_msg)
+ return;
+
+ i2c->rx_pos = 0;
+ i2c->tx_pos = 0;
+ i2c->state = STATE_START;
+ while ((fifo_space >= 2) && (first || (i2c->nmsgs > 1))) {
+ if (!first) {
+ i2c->nmsgs--;
+ i2c->tx_msg++;
+ i2c->tx_pos = 0;
+ } else
+ first = 0;
+
+ if (i2c->tx_msg->flags & I2C_M_RD) {
+ /* we dont date putting several reads in the FIFO */
+ xiic_start_recv(i2c);
+ return;
+ } else {
+ xiic_start_send(i2c);
+ if (xiic_tx_space(i2c) != 0) {
+ /* the message could not be completely sent */
+ break;
+ }
+ }
+
+ fifo_space = xiic_tx_fifo_space(i2c);
+ }
+
+ /* there are more messages or the current one could not be completely
+ * put into the FIFO, also enable the half empty interrupt
+ */
+ if (i2c->nmsgs > 1 || xiic_tx_space(i2c))
+ xiic_irq_clr_en(i2c, XIIC_INTR_TX_HALF_MASK);
+
+}
+
+static void xiic_start_xfer(struct xiic_i2c *i2c)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&i2c->lock, flags);
+ xiic_reinit(i2c);
+ /* disable interrupts globally */
+ xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
+ spin_unlock_irqrestore(&i2c->lock, flags);
+
+ __xiic_start_xfer(i2c);
+ xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+}
+
+static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct xiic_i2c *i2c = i2c_get_adapdata(adap);
+ int err;
+
+ dev_dbg(adap->dev.parent, "%s entry SR: 0x%x\n", __func__,
+ xiic_getreg8(i2c, XIIC_SR_REG_OFFSET));
+
+ err = xiic_busy(i2c);
+ if (err)
+ return err;
+
+ i2c->tx_msg = msgs;
+ i2c->nmsgs = num;
+
+ xiic_start_xfer(i2c);
+
+ if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
+ (i2c->state == STATE_DONE), HZ))
+ return (i2c->state == STATE_DONE) ? num : -EIO;
+ else {
+ i2c->tx_msg = NULL;
+ i2c->rx_msg = NULL;
+ i2c->nmsgs = 0;
+ return -ETIMEDOUT;
+ }
+}
+
+static u32 xiic_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm xiic_algorithm = {
+ .master_xfer = xiic_xfer,
+ .functionality = xiic_func,
+};
+
+static struct i2c_adapter xiic_adapter = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
+ .algo = &xiic_algorithm,
+};
+
+
+static int __devinit xiic_i2c_probe(struct platform_device *pdev)
+{
+ struct xiic_i2c *i2c;
+ struct xiic_i2c_platform_data *pdata;
+ struct resource *res;
+ int ret, irq;
+ u8 i;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ goto resource_missing;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ goto resource_missing;
+
+ pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data;
+ if (!pdata)
+ return -EINVAL;
+
+ i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
+ return -ENOMEM;
+
+ if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+ dev_err(&pdev->dev, "Memory region busy\n");
+ ret = -EBUSY;
+ goto request_mem_failed;
+ }
+
+ i2c->base = ioremap(res->start, resource_size(res));
+ if (!i2c->base) {
+ dev_err(&pdev->dev, "Unable to map registers\n");
+ ret = -EIO;
+ goto map_failed;
+ }
+
+ /* hook up driver to tree */
+ platform_set_drvdata(pdev, i2c);
+ i2c->adap = xiic_adapter;
+ i2c_set_adapdata(&i2c->adap, i2c);
+ i2c->adap.dev.parent = &pdev->dev;
+
+ xiic_reinit(i2c);
+
+ spin_lock_init(&i2c->lock);
+ init_waitqueue_head(&i2c->wait);
+ ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot claim IRQ\n");
+ goto request_irq_failed;
+ }
+
+ /* add i2c adapter to i2c tree */
+ ret = i2c_add_adapter(&i2c->adap);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to add adapter\n");
+ goto add_adapter_failed;
+ }
+
+ /* add in known devices to the bus */
+ for (i = 0; i < pdata->num_devices; i++)
+ i2c_new_device(&i2c->adap, pdata->devices + i);
+
+ return 0;
+
+add_adapter_failed:
+ free_irq(irq, i2c);
+request_irq_failed:
+ xiic_deinit(i2c);
+ iounmap(i2c->base);
+map_failed:
+ release_mem_region(res->start, resource_size(res));
+request_mem_failed:
+ kfree(i2c);
+
+ return ret;
+resource_missing:
+ dev_err(&pdev->dev, "IRQ or Memory resource is missing\n");
+ return -ENOENT;
+}
+
+static int __devexit xiic_i2c_remove(struct platform_device* pdev)
+{
+ struct xiic_i2c *i2c = platform_get_drvdata(pdev);
+ struct resource *res;
+
+ /* remove adapter & data */
+ i2c_del_adapter(&i2c->adap);
+
+ xiic_deinit(i2c);
+
+ platform_set_drvdata(pdev, NULL);
+
+ free_irq(platform_get_irq(pdev, 0), i2c);
+
+ iounmap(i2c->base);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ release_mem_region(res->start, resource_size(res));
+
+ kfree(i2c);
+
+ return 0;
+}
+
+
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:"DRIVER_NAME);
+
+static struct platform_driver xiic_i2c_driver = {
+ .probe = xiic_i2c_probe,
+ .remove = __devexit_p(xiic_i2c_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ },
+};
+
+static int __init xiic_i2c_init(void)
+{
+ return platform_driver_register(&xiic_i2c_driver);
+}
+
+static void __exit xiic_i2c_exit(void)
+{
+ platform_driver_unregister(&xiic_i2c_driver);
+}
+
+module_init(xiic_i2c_init);
+module_exit(xiic_i2c_exit);
+
+MODULE_AUTHOR("info@mocean-labs.com");
+MODULE_DESCRIPTION("Xilinx I2C bus driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index cf994bd01d9..684395b6f3e 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/scx200.h>
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
deleted file mode 100644
index ae4539d99be..00000000000
--- a/drivers/i2c/chips/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Miscellaneous I2C chip drivers configuration
-#
-# *** DEPRECATED! Do not add new entries! See Makefile ***
-#
-
-menu "Miscellaneous I2C Chip support"
-
-config SENSORS_TSL2550
- tristate "Taos TSL2550 ambient light sensor"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for the Taos TSL2550
- ambient light sensor.
-
- This driver can also be built as a module. If so, the module
- will be called tsl2550.
-
-endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
deleted file mode 100644
index fe0af0f81f2..00000000000
--- a/drivers/i2c/chips/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Makefile for miscellaneous I2C chip drivers.
-#
-# Do not add new drivers to this directory! It is DEPRECATED.
-#
-# Device drivers are better grouped according to the functionality they
-# implement rather than to the bus they are connected to. In particular:
-# * Hardware monitoring chip drivers go to drivers/hwmon
-# * RTC chip drivers go to drivers/rtc
-# * I/O expander drivers go to drivers/gpio
-#
-
-obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
-
-ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
-
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
deleted file mode 100644
index a0702f36a72..00000000000
--- a/drivers/i2c/chips/tsl2550.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * tsl2550.c - Linux kernel modules for ambient light sensor
- *
- * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
- * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.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.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-#define TSL2550_DRV_NAME "tsl2550"
-#define DRIVER_VERSION "1.2"
-
-/*
- * Defines
- */
-
-#define TSL2550_POWER_DOWN 0x00
-#define TSL2550_POWER_UP 0x03
-#define TSL2550_STANDARD_RANGE 0x18
-#define TSL2550_EXTENDED_RANGE 0x1d
-#define TSL2550_READ_ADC0 0x43
-#define TSL2550_READ_ADC1 0x83
-
-/*
- * Structs
- */
-
-struct tsl2550_data {
- struct i2c_client *client;
- struct mutex update_lock;
-
- unsigned int power_state : 1;
- unsigned int operating_mode : 1;
-};
-
-/*
- * Global data
- */
-
-static const u8 TSL2550_MODE_RANGE[2] = {
- TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
-};
-
-/*
- * Management functions
- */
-
-static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
-
- int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
-
- data->operating_mode = mode;
-
- return ret;
-}
-
-static int tsl2550_set_power_state(struct i2c_client *client, int state)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int ret;
-
- if (state == 0)
- ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
- else {
- ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
-
- /* On power up we should reset operating mode also... */
- tsl2550_set_operating_mode(client, data->operating_mode);
- }
-
- data->power_state = state;
-
- return ret;
-}
-
-static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
-{
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, cmd);
- if (ret < 0)
- return ret;
- if (!(ret & 0x80))
- return -EAGAIN;
- return ret & 0x7f; /* remove the "valid" bit */
-}
-
-/*
- * LUX calculation
- */
-
-#define TSL2550_MAX_LUX 1846
-
-static const u8 ratio_lut[] = {
- 100, 100, 100, 100, 100, 100, 100, 100,
- 100, 100, 100, 100, 100, 100, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 98, 98, 98, 98, 98,
- 98, 98, 97, 97, 97, 97, 97, 96,
- 96, 96, 96, 95, 95, 95, 94, 94,
- 93, 93, 93, 92, 92, 91, 91, 90,
- 89, 89, 88, 87, 87, 86, 85, 84,
- 83, 82, 81, 80, 79, 78, 77, 75,
- 74, 73, 71, 69, 68, 66, 64, 62,
- 60, 58, 56, 54, 52, 49, 47, 44,
- 42, 41, 40, 40, 39, 39, 38, 38,
- 37, 37, 37, 36, 36, 36, 35, 35,
- 35, 35, 34, 34, 34, 34, 33, 33,
- 33, 33, 32, 32, 32, 32, 32, 31,
- 31, 31, 31, 31, 30, 30, 30, 30,
- 30,
-};
-
-static const u16 count_lut[] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 49, 53, 57, 61, 65, 69, 73, 77,
- 81, 85, 89, 93, 97, 101, 105, 109,
- 115, 123, 131, 139, 147, 155, 163, 171,
- 179, 187, 195, 203, 211, 219, 227, 235,
- 247, 263, 279, 295, 311, 327, 343, 359,
- 375, 391, 407, 423, 439, 455, 471, 487,
- 511, 543, 575, 607, 639, 671, 703, 735,
- 767, 799, 831, 863, 895, 927, 959, 991,
- 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
- 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
- 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
- 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
-};
-
-/*
- * This function is described into Taos TSL2550 Designer's Notebook
- * pages 2, 3.
- */
-static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
-{
- unsigned int lux;
-
- /* Look up count from channel values */
- u16 c0 = count_lut[ch0];
- u16 c1 = count_lut[ch1];
-
- /*
- * Calculate ratio.
- * Note: the "128" is a scaling factor
- */
- u8 r = 128;
-
- /* Avoid division by 0 and count 1 cannot be greater than count 0 */
- if (c1 <= c0)
- if (c0) {
- r = c1 * 128 / c0;
-
- /* Calculate LUX */
- lux = ((c0 - c1) * ratio_lut[r]) / 256;
- } else
- lux = 0;
- else
- return -EAGAIN;
-
- /* LUX range check */
- return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
-}
-
-/*
- * SysFS support
- */
-
-static ssize_t tsl2550_show_power_state(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
- return sprintf(buf, "%u\n", data->power_state);
-}
-
-static ssize_t tsl2550_store_power_state(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
- int ret;
-
- if (val < 0 || val > 1)
- return -EINVAL;
-
- mutex_lock(&data->update_lock);
- ret = tsl2550_set_power_state(client, val);
- mutex_unlock(&data->update_lock);
-
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
- tsl2550_show_power_state, tsl2550_store_power_state);
-
-static ssize_t tsl2550_show_operating_mode(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
- return sprintf(buf, "%u\n", data->operating_mode);
-}
-
-static ssize_t tsl2550_store_operating_mode(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
- int ret;
-
- if (val < 0 || val > 1)
- return -EINVAL;
-
- if (data->power_state == 0)
- return -EBUSY;
-
- mutex_lock(&data->update_lock);
- ret = tsl2550_set_operating_mode(client, val);
- mutex_unlock(&data->update_lock);
-
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
- tsl2550_show_operating_mode, tsl2550_store_operating_mode);
-
-static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
- u8 ch0, ch1;
- int ret;
-
- ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
- if (ret < 0)
- return ret;
- ch0 = ret;
-
- ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
- if (ret < 0)
- return ret;
- ch1 = ret;
-
- /* Do the job */
- ret = tsl2550_calculate_lux(ch0, ch1);
- if (ret < 0)
- return ret;
- if (data->operating_mode == 1)
- ret *= 5;
-
- return sprintf(buf, "%d\n", ret);
-}
-
-static ssize_t tsl2550_show_lux1_input(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int ret;
-
- /* No LUX data if not operational */
- if (!data->power_state)
- return -EBUSY;
-
- mutex_lock(&data->update_lock);
- ret = __tsl2550_show_lux(client, buf);
- mutex_unlock(&data->update_lock);
-
- return ret;
-}
-
-static DEVICE_ATTR(lux1_input, S_IRUGO,
- tsl2550_show_lux1_input, NULL);
-
-static struct attribute *tsl2550_attributes[] = {
- &dev_attr_power_state.attr,
- &dev_attr_operating_mode.attr,
- &dev_attr_lux1_input.attr,
- NULL
-};
-
-static const struct attribute_group tsl2550_attr_group = {
- .attrs = tsl2550_attributes,
-};
-
-/*
- * Initialization function
- */
-
-static int tsl2550_init_client(struct i2c_client *client)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int err;
-
- /*
- * Probe the chip. To do so we try to power up the device and then to
- * read back the 0x03 code
- */
- err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
- if (err < 0)
- return err;
- if (err != TSL2550_POWER_UP)
- return -ENODEV;
- data->power_state = 1;
-
- /* Set the default operating mode */
- err = i2c_smbus_write_byte(client,
- TSL2550_MODE_RANGE[data->operating_mode]);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/*
- * I2C init/probing/exit functions
- */
-
-static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct tsl2550_data *data;
- int *opmode, err = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
- | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
- err = -EIO;
- goto exit;
- }
-
- data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
- data->client = client;
- i2c_set_clientdata(client, data);
-
- /* Check platform data */
- opmode = client->dev.platform_data;
- if (opmode) {
- if (*opmode < 0 || *opmode > 1) {
- dev_err(&client->dev, "invalid operating_mode (%d)\n",
- *opmode);
- err = -EINVAL;
- goto exit_kfree;
- }
- data->operating_mode = *opmode;
- } else
- data->operating_mode = 0; /* default mode is standard */
- dev_info(&client->dev, "%s operating mode\n",
- data->operating_mode ? "extended" : "standard");
-
- mutex_init(&data->update_lock);
-
- /* Initialize the TSL2550 chip */
- err = tsl2550_init_client(client);
- if (err)
- goto exit_kfree;
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
- if (err)
- goto exit_kfree;
-
- dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
-
- return 0;
-
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int __devexit tsl2550_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
-
- /* Power down the device */
- tsl2550_set_power_state(client, 0);
-
- kfree(i2c_get_clientdata(client));
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- return tsl2550_set_power_state(client, 0);
-}
-
-static int tsl2550_resume(struct i2c_client *client)
-{
- return tsl2550_set_power_state(client, 1);
-}
-
-#else
-
-#define tsl2550_suspend NULL
-#define tsl2550_resume NULL
-
-#endif /* CONFIG_PM */
-
-static const struct i2c_device_id tsl2550_id[] = {
- { "tsl2550", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tsl2550_id);
-
-static struct i2c_driver tsl2550_driver = {
- .driver = {
- .name = TSL2550_DRV_NAME,
- .owner = THIS_MODULE,
- },
- .suspend = tsl2550_suspend,
- .resume = tsl2550_resume,
- .probe = tsl2550_probe,
- .remove = __devexit_p(tsl2550_remove),
- .id_table = tsl2550_id,
-};
-
-static int __init tsl2550_init(void)
-{
- return i2c_add_driver(&tsl2550_driver);
-}
-
-static void __exit tsl2550_exit(void)
-{
- i2c_del_driver(&tsl2550_driver);
-}
-
-MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
-
-module_init(tsl2550_init);
-module_exit(tsl2550_exit);
diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c
index a26a34a0664..7e6a63b5716 100644
--- a/drivers/i2c/i2c-boardinfo.c
+++ b/drivers/i2c/i2c-boardinfo.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/rwsem.h>
#include "i2c-core.h"
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index 42127822124..a24e0bfe920 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -22,11 +22,11 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
-#include <linux/semaphore.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
+#include <linux/slab.h>
struct i2c_smbus_alert {
unsigned int alert_edge_triggered:1;
@@ -55,7 +55,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)
* Drivers should either disable alerts, or provide at least
* a minimal handler. Lock so client->driver won't change.
*/
- down(&dev->sem);
+ device_lock(dev);
if (client->driver) {
if (client->driver->alert)
client->driver->alert(client, data->flag);
@@ -63,7 +63,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)
dev_warn(&client->dev, "no driver alert()!\n");
} else
dev_dbg(&client->dev, "alert with no driver\n");
- up(&dev->sem);
+ device_unlock(dev);
/* Stop iterating after we find the device */
return -EBUSY;
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index b885c1d548f..45163693f73 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -128,6 +128,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 5cb01e5c323..c26c11905ff 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -12,6 +12,7 @@
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <acpi/acpi.h>
#include <linux/ide.h>
#include <linux/pci.h>
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index eb2181a6a11..f9daffd7d0e 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -7,6 +7,7 @@
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
+#include <linux/gfp.h>
#include <scsi/scsi.h>
@@ -263,8 +264,8 @@ void ide_retry_pc(ide_drive_t *drive)
* of it. The failed command will be retried after sense data
* is acquired.
*/
- blk_requeue_request(failed_rq->q, failed_rq);
drive->hwif->rq = NULL;
+ ide_requeue_and_plug(drive, failed_rq);
if (ide_queue_sense_rq(drive, pc)) {
blk_start_request(failed_rq);
ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq));
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index df3df0041eb..02712bf045c 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/cdrom.h>
+#include <linux/gfp.h>
#include <linux/ide.h>
#include <scsi/scsi.h>
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index ab87e4f7cec..defce2877ee 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -409,6 +409,8 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+ PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x3e520e17),
+ PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -429,6 +431,8 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x9351e59d),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c
index c6935c78757..9e98122f646 100644
--- a/drivers/ide/ide-devsets.c
+++ b/drivers/ide/ide-devsets.c
@@ -1,5 +1,6 @@
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/ide.h>
DEFINE_MUTEX(ide_setting_mtx);
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 60b0590ccc9..f9bbd904eae 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -1,5 +1,6 @@
#include <linux/kernel.h>
#include <linux/ide.h>
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include "ide-disk.h"
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index ee58c88dee5..06b14bc9a1d 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -29,6 +29,7 @@
*/
#include <linux/types.h>
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
@@ -492,6 +493,7 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
if (rq) {
hwif->rq = NULL;
rq->errors = 0;
+ ide_requeue_and_plug(drive, rq);
}
return ret;
}
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index efd90762346..4713bdca20b 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -25,7 +25,6 @@
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/genhd.h>
-#include <linux/slab.h>
#include <linux/cdrom.h>
#include <linux/ide.h>
#include <linux/hdreg.h>
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 753241429c2..c32d83996ae 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -8,6 +8,7 @@
#include <linux/ide.h>
#include <linux/hdreg.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
#define IDE_DISK_MINORS (1 << PARTN_BITS)
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index db96138fefc..172ac921815 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -566,7 +566,7 @@ plug_device_2:
blk_plug_device(q);
}
-static void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
+void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
unsigned long flags;
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 6e7ae2b6cfc..9965ecd5078 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -4,6 +4,7 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/slab.h>
static const struct ide_ioctl_devset ide_ioctl_settings[] = {
{ HDIO_GET_32BIT, HDIO_SET_32BIT, &ide_devset_io_32bit },
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index a914023d6d0..88a380c5a47 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -1,4 +1,5 @@
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/ide.h>
#include <linux/jiffies.h>
#include <linux/blkdev.h>
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index ad7be2669dc..1c08311b0a0 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -1,4 +1,5 @@
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/ide.h>
int generic_ide_suspend(struct device *dev, pm_message_t mesg)
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index fbedd35feb4..4c3d1bfec0c 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -695,14 +695,8 @@ static int ide_probe_port(ide_hwif_t *hwif)
if (irqd)
disable_irq(hwif->irq);
- rc = ide_port_wait_ready(hwif);
- if (rc == -ENODEV) {
- printk(KERN_INFO "%s: no devices on the port\n", hwif->name);
- goto out;
- } else if (rc == -EBUSY)
- printk(KERN_ERR "%s: not ready before the probe\n", hwif->name);
- else
- rc = -ENODEV;
+ if (ide_port_wait_ready(hwif) == -EBUSY)
+ printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
/*
* Second drive should only exist if first drive was found,
@@ -713,7 +707,7 @@ static int ide_probe_port(ide_hwif_t *hwif)
if (drive->dev_flags & IDE_DFLAG_PRESENT)
rc = 0;
}
-out:
+
/*
* Use cached IRQ number. It might be (and is...) changed by probe
* code above
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 017c09540c2..a3133d7b2a0 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -25,6 +25,7 @@
#include <linux/ctype.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/io.h>
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index cc8633cbe13..67fb73559fd 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -428,13 +428,11 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
{
struct request *rq;
int error;
+ int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE;
- rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq = blk_get_request(drive->queue, rw, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
- if (cmd->tf_flags & IDE_TFLAG_WRITE)
- rq->cmd_flags |= REQ_RW;
-
/*
* (ks) We transfer currently only whole sectors.
* This is suffient for now. But, it would be great,
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 16d056939f9..3cb9c4e056f 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -52,7 +52,6 @@
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/genhd.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/ide.h>
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index b2709c73348..2e3169f2acd 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -61,6 +61,7 @@
#include <linux/types.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/init.h>
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 850ee452e9b..159955d16c4 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -33,6 +33,7 @@
#include <linux/adb.h>
#include <linux/pmu.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/io.h>
diff --git a/drivers/ide/rapide.c b/drivers/ide/rapide.c
index 00f54248f41..48d976aad7a 100644
--- a/drivers/ide/rapide.c
+++ b/drivers/ide/rapide.c
@@ -3,7 +3,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/errno.h>
#include <linux/ide.h>
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c
index 134f1fd1386..356b9b504ff 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index e65d010b708..101f4002238 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
@@ -110,7 +111,6 @@ struct via82cxxx_dev
{
struct via_isa_bridge *via_config;
unsigned int via_80w;
- u8 cached_device[2];
};
/**
@@ -403,66 +403,10 @@ static const struct ide_port_ops via_port_ops = {
.cable_detect = via82cxxx_cable_detect,
};
-static void via_write_devctl(ide_hwif_t *hwif, u8 ctl)
-{
- struct via82cxxx_dev *vdev = hwif->host->host_priv;
-
- outb(ctl, hwif->io_ports.ctl_addr);
- outb(vdev->cached_device[hwif->channel], hwif->io_ports.device_addr);
-}
-
-static void __via_dev_select(ide_drive_t *drive, u8 select)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct via82cxxx_dev *vdev = hwif->host->host_priv;
-
- outb(select, hwif->io_ports.device_addr);
- vdev->cached_device[hwif->channel] = select;
-}
-
-static void via_dev_select(ide_drive_t *drive)
-{
- __via_dev_select(drive, drive->select | ATA_DEVICE_OBS);
-}
-
-static void via_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
-
- if (valid & IDE_VALID_FEATURE)
- outb(tf->feature, io_ports->feature_addr);
- if (valid & IDE_VALID_NSECT)
- outb(tf->nsect, io_ports->nsect_addr);
- if (valid & IDE_VALID_LBAL)
- outb(tf->lbal, io_ports->lbal_addr);
- if (valid & IDE_VALID_LBAM)
- outb(tf->lbam, io_ports->lbam_addr);
- if (valid & IDE_VALID_LBAH)
- outb(tf->lbah, io_ports->lbah_addr);
- if (valid & IDE_VALID_DEVICE)
- __via_dev_select(drive, tf->device);
-}
-
-const struct ide_tp_ops via_tp_ops = {
- .exec_command = ide_exec_command,
- .read_status = ide_read_status,
- .read_altstatus = ide_read_altstatus,
- .write_devctl = via_write_devctl,
-
- .dev_select = via_dev_select,
- .tf_load = via_tf_load,
- .tf_read = ide_tf_read,
-
- .input_data = ide_input_data,
- .output_data = ide_output_data,
-};
-
static const struct ide_port_info via82cxxx_chipset __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_via82cxxx,
.enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
- .tp_ops = &via_tp_ops,
.port_ops = &via_port_ops,
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST |
IDE_HFLAG_POST_SET_MODE |
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
index dd253002cd5..15341fc1c68 100644
--- a/drivers/idle/i7300_idle.c
+++ b/drivers/idle/i7300_idle.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/notifier.h>
#include <linux/cpumask.h>
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 8e7e3344c4b..d178699b194 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -10,7 +10,6 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/scatterlist.h>
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 5122b5a8aa2..18350213479 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -19,7 +19,6 @@
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/freezer.h>
-#include <linux/semaphore.h>
#include <asm/atomic.h>
#include "csr.h"
@@ -1397,9 +1396,9 @@ static int update_pdrv(struct device *dev, void *data)
pdrv = container_of(drv, struct hpsb_protocol_driver,
driver);
if (pdrv->update) {
- down(&ud->device.sem);
+ device_lock(&ud->device);
error = pdrv->update(ud);
- up(&ud->device.sem);
+ device_unlock(&ud->device);
}
if (error)
device_release_driver(&ud->device);
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index 9555fd25386..bf47fee7980 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -1452,7 +1452,7 @@ static int __devinit add_card(struct pci_dev *dev,
PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c");
} else {
PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom");
- /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a),
+ /* FIXME: probably we should rewrite the max_rec, max_ROM(1394a),
* generation(1394a) and link_spd(1394a) field and recalculate
* the CRC */
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index c88696a6cf8..4565cb5d3d1 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -56,7 +56,6 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index abbb06996f9..0b926e45afe 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -35,6 +35,7 @@
#include <linux/mutex.h>
#include <linux/inetdevice.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <net/arp.h>
#include <net/neighbour.h>
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 5130fc55b8e..ad63b79afac 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -42,6 +42,7 @@
#include <linux/random.h>
#include <linux/rbtree.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/workqueue.h>
#include <linux/kdev_t.h>
@@ -3597,7 +3598,7 @@ static ssize_t cm_show_counter(struct kobject *obj, struct attribute *attr,
atomic_long_read(&group->counter[cm_attr->index]));
}
-static struct sysfs_ops cm_counter_ops = {
+static const struct sysfs_ops cm_counter_ops = {
.show = cm_show_counter
};
@@ -3693,7 +3694,7 @@ static void cm_add_one(struct ib_device *ib_device)
cm_dev->device = device_create(&cm_class, &ib_device->dev,
MKDEV(0, 0), NULL,
"%s", ib_device->name);
- if (!cm_dev->device) {
+ if (IS_ERR(cm_dev->device)) {
kfree(cm_dev);
return;
}
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 875e34e0b23..6d777069d86 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -40,6 +40,7 @@
#include <linux/random.h>
#include <linux/idr.h>
#include <linux/inetdevice.h>
+#include <linux/slab.h>
#include <net/tcp.h>
#include <net/ipv6.h>
@@ -1683,6 +1684,7 @@ int rdma_set_ib_paths(struct rdma_cm_id *id,
}
memcpy(id->route.path_rec, path_rec, sizeof *path_rec * num_paths);
+ id->route.num_paths = num_paths;
return 0;
err:
cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED);
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 0f89909abce..bfead5bc25f 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -44,6 +44,7 @@
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/completion.h>
+#include <linux/slab.h>
#include <rdma/iw_cm.h>
#include <rdma/ib_addr.h>
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 7522008fda8..1df1194aeba 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -34,6 +34,7 @@
*
*/
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <rdma/ib_cache.h>
#include "mad_priv.h"
@@ -1193,10 +1194,7 @@ static int method_in_use(struct ib_mad_mgmt_method_table **method,
{
int i;
- for (i = find_first_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS);
- i < IB_MGMT_MAX_METHODS;
- i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
- 1+i)) {
+ for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS) {
if ((*method)->agent[i]) {
printk(KERN_ERR PFX "Method %d already in use\n", i);
return -EINVAL;
@@ -1330,13 +1328,9 @@ static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
goto error3;
/* Finally, add in methods being registered */
- for (i = find_first_bit(mad_reg_req->method_mask,
- IB_MGMT_MAX_METHODS);
- i < IB_MGMT_MAX_METHODS;
- i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
- 1+i)) {
+ for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS)
(*method)->agent[i] = agent_priv;
- }
+
return 0;
error3:
@@ -1429,13 +1423,9 @@ check_in_use:
goto error4;
/* Finally, add in methods being registered */
- for (i = find_first_bit(mad_reg_req->method_mask,
- IB_MGMT_MAX_METHODS);
- i < IB_MGMT_MAX_METHODS;
- i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
- 1+i)) {
+ for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS)
(*method)->agent[i] = agent_priv;
- }
+
return 0;
error4:
@@ -2964,6 +2954,9 @@ static void ib_mad_remove_device(struct ib_device *device)
{
int i, num_ports, cur_port;
+ if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
+ return;
+
if (device->node_type == RDMA_NODE_IB_SWITCH) {
num_ports = 1;
cur_port = 0;
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 4e0f2829e0e..f37878c9c06 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -31,6 +31,8 @@
* SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "mad_priv.h"
#include "mad_rmpp.h"
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
index 8d82ba17135..a519801dcfb 100644
--- a/drivers/infiniband/core/multicast.c
+++ b/drivers/infiniband/core/multicast.c
@@ -34,6 +34,7 @@
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/random.h>
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 158a214da2f..f901957abc8 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -79,7 +79,7 @@ static ssize_t port_attr_show(struct kobject *kobj,
return port_attr->show(p, port_attr, buf);
}
-static struct sysfs_ops port_sysfs_ops = {
+static const struct sysfs_ops port_sysfs_ops = {
.show = port_attr_show
};
@@ -461,6 +461,7 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *,
element->attr.attr.mode = S_IRUGO;
element->attr.show = show;
element->index = i;
+ sysfs_attr_init(&element->attr.attr);
tab_attr[i] = &element->attr.attr;
}
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 1b09b735c5a..512b1c43460 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -44,6 +44,7 @@
#include <linux/cdev.h>
#include <linux/idr.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -1336,11 +1337,8 @@ static void ib_ucm_remove_one(struct ib_device *device)
device_unregister(&ucm_dev->dev);
}
-static ssize_t show_abi_version(struct class *class, char *buf)
-{
- return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION);
-}
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+ __stringify(IB_USER_CM_ABI_VERSION));
static int __init ib_ucm_init(void)
{
@@ -1353,7 +1351,7 @@ static int __init ib_ucm_init(void)
goto error1;
}
- ret = class_create_file(&cm_class, &class_attr_abi_version);
+ ret = class_create_file(&cm_class, &class_attr_abi_version.attr);
if (ret) {
printk(KERN_ERR "ucm: couldn't create abi_version attribute\n");
goto error2;
@@ -1367,7 +1365,7 @@ static int __init ib_ucm_init(void)
return 0;
error3:
- class_remove_file(&cm_class, &class_attr_abi_version);
+ class_remove_file(&cm_class, &class_attr_abi_version.attr);
error2:
unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
error1:
@@ -1377,7 +1375,7 @@ error1:
static void __exit ib_ucm_cleanup(void)
{
ib_unregister_client(&ucm_client);
- class_remove_file(&cm_class, &class_attr_abi_version);
+ class_remove_file(&cm_class, &class_attr_abi_version.attr);
unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
if (overflow_maj)
unregister_chrdev_region(overflow_maj, IB_UCM_MAX_DEVICES);
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index b2e16c332d5..46185084121 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -39,6 +39,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/miscdevice.h>
+#include <linux/slab.h>
#include <rdma/rdma_user_cm.h>
#include <rdma/ib_marshall.h>
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 4f906f0614f..415e186eee3 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -37,6 +37,7 @@
#include <linux/sched.h>
#include <linux/hugetlb.h>
#include <linux/dma-attrs.h>
+#include <linux/slab.h>
#include "uverbs.h"
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 02d360cfc2f..e7db054fb1c 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -46,6 +46,7 @@
#include <linux/compat.h>
#include <linux/sched.h>
#include <linux/semaphore.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -965,11 +966,8 @@ static ssize_t show_port(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
-static ssize_t show_abi_version(struct class *class, char *buf)
-{
- return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
-}
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+ __stringify(IB_USER_MAD_ABI_VERSION));
static dev_t overflow_maj;
static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS);
@@ -1194,7 +1192,7 @@ static int __init ib_umad_init(void)
goto out_chrdev;
}
- ret = class_create_file(umad_class, &class_attr_abi_version);
+ ret = class_create_file(umad_class, &class_attr_abi_version.attr);
if (ret) {
printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
goto out_class;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index f71cf138d67..6fcfbeb24a2 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -35,6 +35,7 @@
#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 4fa2e651644..fb352625442 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -44,6 +44,7 @@
#include <linux/file.h>
#include <linux/cdev.h>
#include <linux/anon_inodes.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -691,11 +692,8 @@ static ssize_t show_dev_abi_version(struct device *device,
}
static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
-static ssize_t show_abi_version(struct class *class, char *buf)
-{
- return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION);
-}
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+ __stringify(IB_USER_VERBS_ABI_VERSION));
static dev_t overflow_maj;
static DECLARE_BITMAP(overflow_map, IB_UVERBS_MAX_DEVICES);
@@ -841,7 +839,7 @@ static int __init ib_uverbs_init(void)
goto out_chrdev;
}
- ret = class_create_file(uverbs_class, &class_attr_abi_version);
+ ret = class_create_file(uverbs_class, &class_attr_abi_version.attr);
if (ret) {
printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
goto out_class;
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
index c61fd2b4a55..dc85d777578 100644
--- a/drivers/infiniband/hw/amso1100/c2.c
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -46,6 +46,7 @@
#include <linux/tcp.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/infiniband/hw/amso1100/c2_alloc.c b/drivers/infiniband/hw/amso1100/c2_alloc.c
index e9110163aef..d4f5f5d42e9 100644
--- a/drivers/infiniband/hw/amso1100/c2_alloc.c
+++ b/drivers/infiniband/hw/amso1100/c2_alloc.c
@@ -32,7 +32,6 @@
*/
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/bitmap.h>
#include "c2.h"
diff --git a/drivers/infiniband/hw/amso1100/c2_cm.c b/drivers/infiniband/hw/amso1100/c2_cm.c
index 75b93e9b881..95f58ab1e0b 100644
--- a/drivers/infiniband/hw/amso1100/c2_cm.c
+++ b/drivers/infiniband/hw/amso1100/c2_cm.c
@@ -31,6 +31,8 @@
* SOFTWARE.
*
*/
+#include <linux/slab.h>
+
#include "c2.h"
#include "c2_wr.h"
#include "c2_vq.h"
diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c
index f5c45b194f5..f7b0fc23f41 100644
--- a/drivers/infiniband/hw/amso1100/c2_cq.c
+++ b/drivers/infiniband/hw/amso1100/c2_cq.c
@@ -35,6 +35,8 @@
* SOFTWARE.
*
*/
+#include <linux/gfp.h>
+
#include "c2.h"
#include "c2_vq.h"
#include "c2_status.h"
diff --git a/drivers/infiniband/hw/amso1100/c2_mm.c b/drivers/infiniband/hw/amso1100/c2_mm.c
index b506fe22b4d..119c4f3d979 100644
--- a/drivers/infiniband/hw/amso1100/c2_mm.c
+++ b/drivers/infiniband/hw/amso1100/c2_mm.c
@@ -30,6 +30,8 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "c2.h"
#include "c2_vq.h"
diff --git a/drivers/infiniband/hw/amso1100/c2_pd.c b/drivers/infiniband/hw/amso1100/c2_pd.c
index 00c709926c8..161f2a28535 100644
--- a/drivers/infiniband/hw/amso1100/c2_pd.c
+++ b/drivers/infiniband/hw/amso1100/c2_pd.c
@@ -34,6 +34,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include "c2.h"
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index ad723bd8bf4..c47f618d12e 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -50,6 +50,7 @@
#include <linux/dma-mapping.h>
#include <linux/if_arp.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c
index ad518868df7..d8f4bb8bf42 100644
--- a/drivers/infiniband/hw/amso1100/c2_qp.c
+++ b/drivers/infiniband/hw/amso1100/c2_qp.c
@@ -36,6 +36,7 @@
*/
#include <linux/delay.h>
+#include <linux/gfp.h>
#include "c2.h"
#include "c2_vq.h"
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c
index dd05c483564..78c4bcc6ef6 100644
--- a/drivers/infiniband/hw/amso1100/c2_rnic.c
+++ b/drivers/infiniband/hw/amso1100/c2_rnic.c
@@ -51,6 +51,7 @@
#include <linux/mm.h>
#include <linux/inet.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/route.h>
diff --git a/drivers/infiniband/hw/cxgb3/cxio_dbg.c b/drivers/infiniband/hw/cxgb3/cxio_dbg.c
index a8d24d53f30..8bca6b4ec9a 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_dbg.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_dbg.c
@@ -31,6 +31,7 @@
*/
#ifdef DEBUG
#include <linux/types.h>
+#include <linux/slab.h>
#include "common.h"
#include "cxgb3_ioctl.h"
#include "cxio_hal.h"
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index a28e862f2d6..35f286f1ad1 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -37,6 +37,7 @@
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include "cxio_resource.h"
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index ee1d8b4d454..63f975f3e30 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -189,6 +189,7 @@ static void close_rnic_dev(struct t3cdev *tdev)
list_for_each_entry_safe(dev, tmp, &dev_list, entry) {
if (dev->rdev.t3cdev_p == tdev) {
dev->rdev.flags = CXIO_ERROR_FATAL;
+ synchronize_net();
cancel_delayed_work_sync(&dev->db_drop_task);
list_del(&dev->entry);
iwch_unregister_device(dev);
@@ -217,6 +218,7 @@ static void iwch_event_handler(struct t3cdev *tdev, u32 evt, u32 port_id)
switch (evt) {
case OFFLOAD_STATUS_DOWN: {
rdev->flags = CXIO_ERROR_FATAL;
+ synchronize_net();
event.event = IB_EVENT_DEVICE_FATAL;
dispatch = 1;
break;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index d94388b81a4..4fef0329627 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -31,6 +31,7 @@
*/
#include <linux/module.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/skbuff.h>
#include <linux/timer.h>
diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c
index 743c5d8b880..6afc89e7572 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_ev.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c
@@ -29,7 +29,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/mman.h>
#include <net/sock.h>
#include "iwch_provider.h"
diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c
index e1ec65ebb01..5c36ee2809a 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_mem.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c
@@ -29,6 +29,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <rdma/iw_cm.h>
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 47b35c6608d..19b1c4a62a2 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -42,6 +42,7 @@
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
#include <linux/inetdevice.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index b4d893de365..ae47bfd22bd 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -30,6 +30,7 @@
* SOFTWARE.
*/
#include <linux/sched.h>
+#include <linux/gfp.h>
#include "iwch_provider.h"
#include "iwch.h"
#include "iwch_cm.h"
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c
index 56735ea2fc5..465926319f3 100644
--- a/drivers/infiniband/hw/ehca/ehca_av.c
+++ b/drivers/infiniband/hw/ehca/ehca_av.c
@@ -41,6 +41,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
+
#include "ehca_tools.h"
#include "ehca_iverbs.h"
#include "hcp_if.h"
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 97e4b231cdc..d9b0ebcb67d 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -43,6 +43,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
+
#include "ehca_iverbs.h"
#include "ehca_classes.h"
#include "ehca_irq.h"
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 8b92f85d4dd..73edc366866 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -39,6 +39,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/gfp.h>
+
#include "ehca_tools.h"
#include "ehca_iverbs.h"
#include "hcp_if.h"
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index b2b6fea2b14..07cae552caf 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -41,6 +41,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
+
#include "ehca_classes.h"
#include "ehca_irq.h"
#include "ehca_iverbs.h"
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index 7550a534005..31a68b9c52d 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -40,6 +40,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
#include <rdma/ib_umem.h>
#include "ehca_iverbs.h"
diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c
index 2fe554855fa..351577a6670 100644
--- a/drivers/infiniband/hw/ehca/ehca_pd.c
+++ b/drivers/infiniband/hw/ehca/ehca_pd.c
@@ -38,6 +38,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
+
#include "ehca_tools.h"
#include "ehca_iverbs.h"
diff --git a/drivers/infiniband/hw/ehca/ehca_qes.h b/drivers/infiniband/hw/ehca/ehca_qes.h
index 5d28e3e98a2..90c4efa6758 100644
--- a/drivers/infiniband/hw/ehca/ehca_qes.h
+++ b/drivers/infiniband/hw/ehca/ehca_qes.h
@@ -46,7 +46,7 @@
#include "ehca_tools.h"
-/* virtual scatter gather entry to specify remote adresses with length */
+/* virtual scatter gather entry to specify remote addresses with length */
struct ehca_vsgentry {
u64 vaddr;
u32 lkey;
@@ -148,7 +148,7 @@ struct ehca_wqe {
u32 immediate_data;
union {
struct {
- u64 remote_virtual_adress;
+ u64 remote_virtual_address;
u32 rkey;
u32 reserved;
u64 atomic_1st_op_dma_len;
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index b105f664d3e..47d388ec1cd 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -43,6 +43,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
+
#include "ehca_classes.h"
#include "ehca_tools.h"
#include "ehca_qes.h"
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index e3ec7fdd67b..9a3fbfca9b4 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -269,7 +269,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp,
/* no break is intentional here */
case IB_QPT_RC:
/* TODO: atomic not implemented */
- wqe_p->u.nud.remote_virtual_adress =
+ wqe_p->u.nud.remote_virtual_address =
send_wr->wr.rdma.remote_addr;
wqe_p->u.nud.rkey = send_wr->wr.rdma.rkey;
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index f1565cae8ec..45ee89b65c2 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -40,6 +40,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
+
#include "ehca_classes.h"
#include "ehca_iverbs.h"
#include "ehca_mrmw.h"
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
index 1227c593627..1596e308534 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -38,6 +38,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
+
#include "ehca_tools.h"
#include "ipz_pt_fn.h"
#include "ehca_classes.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c
index d385e4168c9..0416c6c0e12 100644
--- a/drivers/infiniband/hw/ipath/ipath_cq.c
+++ b/drivers/infiniband/hw/ipath/ipath_cq.c
@@ -32,6 +32,7 @@
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index e90a0ea538a..644c2c74e05 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -31,6 +31,7 @@
*/
#include <linux/scatterlist.h>
+#include <linux/gfp.h>
#include <rdma/ib_verbs.h>
#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index d2787fe8030..6302626d17f 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -40,6 +40,7 @@
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
#include <linux/bitmap.h>
+#include <linux/slab.h>
#include "ipath_kernel.h"
#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 73933a41ce8..9c5c66d16a2 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -36,6 +36,7 @@
#include <linux/cdev.h>
#include <linux/swap.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/jiffies.h>
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 100da8542bb..2fca70836da 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -37,6 +37,7 @@
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#include "ipath_kernel.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 077879c0bdb..776938299e4 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -33,6 +33,7 @@
#include <linux/pci.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "ipath_kernel.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_mmap.c b/drivers/infiniband/hw/ipath/ipath_mmap.c
index b28865faf43..e7327422940 100644
--- a/drivers/infiniband/hw/ipath/ipath_mmap.c
+++ b/drivers/infiniband/hw/ipath/ipath_mmap.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/pgtable.h>
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index 9d343b7c2f3..e346d3890a0 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -31,6 +31,8 @@
* SOFTWARE.
*/
+#include <linux/slab.h>
+
#include <rdma/ib_umem.h>
#include <rdma/ib_pack.h>
#include <rdma/ib_smi.h>
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index cb2d3ef2ae1..0857a9c3cd3 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -33,6 +33,7 @@
#include <linux/err.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c
index 4b069859085..98ac18ec977 100644
--- a/drivers/infiniband/hw/ipath/ipath_sdma.c
+++ b/drivers/infiniband/hw/ipath/ipath_sdma.c
@@ -31,6 +31,7 @@
*/
#include <linux/spinlock.h>
+#include <linux/gfp.h>
#include "ipath_kernel.h"
#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
index e3d80ca84c1..386e2c717c5 100644
--- a/drivers/infiniband/hw/ipath/ipath_srq.c
+++ b/drivers/infiniband/hw/ipath/ipath_srq.c
@@ -32,6 +32,7 @@
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index eb7d59abd12..5e86d73eba2 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -33,6 +33,7 @@
#include <linux/mm.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include "ipath_kernel.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 9289ab4b0ae..559f39be0dc 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -34,6 +34,7 @@
#include <rdma/ib_mad.h>
#include <rdma/ib_user_verbs.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/utsname.h>
#include <linux/rculist.h>
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
index 6923e1d986d..6216ea92385 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
@@ -33,6 +33,7 @@
#include <linux/rculist.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
index c75ac9463e2..11a236f8d88 100644
--- a/drivers/infiniband/hw/mlx4/ah.c
+++ b/drivers/infiniband/hw/mlx4/ah.c
@@ -30,6 +30,8 @@
* SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "mlx4_ib.h"
struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index de5263beab4..cc2ddd29ac5 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -33,6 +33,7 @@
#include <linux/mlx4/cq.h>
#include <linux/mlx4/qp.h>
+#include <linux/slab.h>
#include "mlx4_ib.h"
#include "user.h"
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 19e68ab6616..f38d5b11892 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -34,6 +34,7 @@
#include <rdma/ib_smi.h>
#include <linux/mlx4/cmd.h>
+#include <linux/gfp.h>
#include "mlx4_ib.h"
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index e596537ff35..01f2a3f9335 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <rdma/ib_smi.h>
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index 8f3666b20ea..1d27b9a8e2d 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -31,6 +31,8 @@
* SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "mlx4_ib.h"
static u32 convert_access(int acc)
@@ -238,7 +240,7 @@ struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device
mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
size, &mfrpl->map,
GFP_KERNEL);
- if (!mfrpl->ibfrpl.page_list)
+ if (!mfrpl->mapped_page_list)
goto err_free;
WARN_ON(mfrpl->map & 0x3f);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index ae75389937d..5643f4a8ffe 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -32,6 +32,7 @@
*/
#include <linux/log2.h>
+#include <linux/slab.h>
#include <rdma/ib_cache.h>
#include <rdma/ib_pack.h>
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c
index cf8085bcbd6..818b7ecace5 100644
--- a/drivers/infiniband/hw/mlx4/srq.c
+++ b/drivers/infiniband/hw/mlx4/srq.c
@@ -33,6 +33,7 @@
#include <linux/mlx4/qp.h>
#include <linux/mlx4/srq.h>
+#include <linux/slab.h>
#include "mlx4_ib.h"
#include "user.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 8c2ed994d54..3603ae89b60 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -36,6 +36,7 @@
#include <linux/pci.h>
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <rdma/ib_mad.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index d9f4735c2b3..18ee3fa4b88 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -34,6 +34,7 @@
* SOFTWARE.
*/
+#include <linux/gfp.h>
#include <linux/hardirq.h>
#include <linux/sched.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 8c31fa36e95..9388164b605 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -34,6 +34,7 @@
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "mthca_dev.h"
#include "mthca_cmd.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index b01b2898787..5eee6665919 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -37,6 +37,7 @@
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/gfp.h>
#include "mthca_dev.h"
#include "mthca_config_reg.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
index d4c81053e43..515790a606e 100644
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -31,7 +31,7 @@
*/
#include <linux/string.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include "mthca_dev.h"
#include "mthca_cmd.h"
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 1f7d1a29d2a..8c2a83732b5 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -35,6 +35,7 @@
#include <linux/mm.h>
#include <linux/scatterlist.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/page.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index bcf7a401482..f080a784bc7 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -39,6 +39,7 @@
#include <rdma/ib_user_verbs.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include "mthca_dev.h"
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 4272c52e38a..de7b9d7166f 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -44,6 +44,7 @@
#include <linux/init.h>
#include <linux/if_arp.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 2a49ee40b52..986d6f32dde 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -53,6 +53,7 @@
#include <linux/list.h>
#include <linux/threads.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <net/neighbour.h>
#include <net/route.h>
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index ce7f5383357..c36a3f51492 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -39,6 +39,7 @@
#include <linux/tcp.h>
#include <linux/if_vlan.h>
#include <linux/inet_lro.h>
+#include <linux/slab.h>
#include "nes.h"
@@ -1899,9 +1900,14 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
u16 wqe_fragment_index;
u64 wqe_frag;
u32 cqp_head;
+ u32 wqm_cfg0;
unsigned long flags;
int ret;
+ /* clear wqe stall before destroying NIC QP */
+ wqm_cfg0 = nes_read_indexed(nesdev, NES_IDX_WQM_CONFIG0);
+ nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0 & 0xFFFF7FFF);
+
/* Free remaining NIC receive buffers */
while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) {
nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail];
@@ -2020,6 +2026,9 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic)
pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase,
nesvnic->nic_pbase);
+
+ /* restore old wqm_cfg0 value */
+ nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0);
}
/**
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index 9b1e7f869d8..bbbfe9fc5a5 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -160,6 +160,7 @@ enum indexed_regs {
NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004,
NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008,
NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c,
+ NES_IDX_WQM_CONFIG0 = 0x5000,
NES_IDX_WQM_CONFIG1 = 0x5004,
NES_IDX_CM_CONFIG = 0x5100,
NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000,
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index a1d79b6856a..b7c813f4be4 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -40,6 +40,7 @@
#include <linux/if_arp.h>
#include <linux/if_vlan.h>
#include <linux/ethtool.h>
+#include <linux/slab.h>
#include <net/tcp.h>
#include <net/inet_common.h>
@@ -1595,7 +1596,6 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
struct nes_vnic *nesvnic;
struct net_device *netdev;
struct nic_qp_map *curr_qp_map;
- u32 u32temp;
u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index];
netdev = alloc_etherdev(sizeof(struct nes_vnic));
@@ -1707,6 +1707,10 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
((phy_type == NES_PHY_TYPE_PUMA_1G) &&
(((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) ||
((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) {
+ u32 u32temp;
+ u32 link_mask;
+ u32 link_val;
+
u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
(0x200 * (nesdev->mac_index & 1)));
if (phy_type != NES_PHY_TYPE_PUMA_1G) {
@@ -1715,13 +1719,36 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
(0x200 * (nesdev->mac_index & 1)), u32temp);
}
+ /* Check and set linkup here. This is for back to back */
+ /* configuration where second port won't get link interrupt */
+ switch (phy_type) {
+ case NES_PHY_TYPE_PUMA_1G:
+ if (nesdev->mac_index < 2) {
+ link_mask = 0x01010000;
+ link_val = 0x01010000;
+ } else {
+ link_mask = 0x02020000;
+ link_val = 0x02020000;
+ }
+ break;
+ default:
+ link_mask = 0x0f1f0000;
+ link_val = 0x0f0f0000;
+ break;
+ }
+
+ u32temp = nes_read_indexed(nesdev,
+ NES_IDX_PHY_PCS_CONTROL_STATUS0 +
+ (0x200 * (nesdev->mac_index & 1)));
+ if ((u32temp & link_mask) == link_val)
+ nesvnic->linkup = 1;
+
/* clear the MAC interrupt status, assumes direct logical to physical mapping */
u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index));
nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp);
nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp);
nes_init_phy(nesdev);
-
}
return netdev;
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c
index 729d525c5b7..186623d8695 100644
--- a/drivers/infiniband/hw/nes/nes_utils.c
+++ b/drivers/infiniband/hw/nes/nes_utils.c
@@ -38,6 +38,7 @@
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
+#include <linux/slab.h>
#include <linux/crc32.h>
#include <linux/in.h>
#include <linux/ip.h>
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 815725f886c..e54f312e4bd 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -35,6 +35,7 @@
#include <linux/moduleparam.h>
#include <linux/random.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <rdma/ib_verbs.h>
@@ -1323,6 +1324,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp)));
nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp))));
nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM |
+ NES_QPCONTEXT_ORDIRD_AAH |
((((u32)nesadapter->max_irrq_wr) <<
NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK));
if (disable_mpa_crc) {
@@ -2819,11 +2821,10 @@ static int nes_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
attr->cap.max_send_wr = nesqp->hwqp.sq_size;
attr->cap.max_recv_wr = nesqp->hwqp.rq_size;
attr->cap.max_recv_sge = 1;
- if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) {
- init_attr->cap.max_inline_data = 0;
- } else {
- init_attr->cap.max_inline_data = 64;
- }
+ if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA)
+ attr->cap.max_inline_data = 0;
+ else
+ attr->cap.max_inline_data = 64;
init_attr->event_handler = nesqp->ibqp.event_handler;
init_attr->qp_context = nesqp->ibqp.qp_context;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 83a7751c38d..bb1004114de 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -35,6 +35,7 @@
#include <net/icmp.h>
#include <linux/icmpv6.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "ipoib.h"
@@ -708,6 +709,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_cm_tx_buf *tx_req;
u64 addr;
+ int rc;
if (unlikely(skb->len > tx->mtu)) {
ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
@@ -739,9 +741,10 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
tx_req->mapping = addr;
- if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
- addr, skb->len))) {
- ipoib_warn(priv, "post_send failed\n");
+ rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
+ addr, skb->len);
+ if (unlikely(rc)) {
+ ipoib_warn(priv, "post_send failed, error %d\n", rc);
++dev->stats.tx_errors;
ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
@@ -752,6 +755,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
if (++priv->tx_outstanding == ipoib_sendq_size) {
ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
tx->qp->qp_num);
+ if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
+ ipoib_warn(priv, "request notify on send CQ failed\n");
netif_stop_queue(dev);
}
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index 961c585da21..86eae229dc4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -32,6 +32,7 @@
#include <linux/err.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
struct file_operations;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 8c91d9f37ad..ec6b4fbe25e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -529,7 +530,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_tx_buf *tx_req;
- int hlen;
+ int hlen, rc;
void *phead;
if (skb_is_gso(skb)) {
@@ -585,9 +586,10 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
netif_stop_queue(dev);
}
- if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
- address->ah, qpn, tx_req, phead, hlen))) {
- ipoib_warn(priv, "post_send failed\n");
+ rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
+ address->ah, qpn, tx_req, phead, hlen);
+ if (unlikely(rc)) {
+ ipoib_warn(priv, "post_send failed, error %d\n", rc);
++dev->stats.tx_errors;
--priv->tx_outstanding;
ipoib_dma_unmap_tx(priv->ca, tx_req);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index d41ea27be5e..b166bb75753 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -40,6 +40,7 @@
#include <linux/inetdevice.h>
#include <linux/delay.h>
#include <linux/completion.h>
+#include <linux/slab.h>
#include <net/dst.h>
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 68325119f74..049a997caff 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -31,6 +31,8 @@
* SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "ipoib.h"
int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int set_qkey)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index e3bf00d8cd2..d7e9740c724 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -33,7 +33,6 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 71237f8f78f..93399dff0c6 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -56,6 +56,7 @@
#include <linux/net.h>
#include <linux/scatterlist.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <net/sock.h>
@@ -613,7 +614,7 @@ static struct scsi_host_template iscsi_iser_sht = {
.cmd_per_lun = ISER_DEF_CMD_PER_LUN,
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler= iscsi_eh_device_reset,
- .eh_target_reset_handler= iscsi_eh_target_reset,
+ .eh_target_reset_handler = iscsi_eh_recover_target,
.target_alloc = iscsi_target_alloc,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "iscsi_iser",
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 308d17bb514..b89d76b39a1 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -32,6 +32,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "iscsi_iser.h"
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 9f9816baeb9..2ee6c7a68bd 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -515,7 +515,7 @@ 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;
- int i, t, u, v;
+ unsigned int i, t, u, v;
int error;
switch (cmd) {
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index b2f07aa1604..03078c08309 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/sched.h>
+#include <linux/slab.h>
/*
* Check that the effect_id is a valid effect and whether the user
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index f967008f332..1d881c96ba8 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -25,6 +25,7 @@
#define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
+#include <linux/slab.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/mutex.h>
diff --git a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c
index 06ad36ed348..85d6ee09f11 100644
--- a/drivers/input/gameport/lightning.c
+++ b/drivers/input/gameport/lightning.c
@@ -34,7 +34,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gameport.h>
-#include <linux/slab.h>
#define L4_PORT 0x201
#define L4_SELECT_ANALOG 0xa4
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c
index 291d9393d35..10c9b0a845f 100644
--- a/drivers/input/input-polldev.c
+++ b/drivers/input/input-polldev.c
@@ -9,6 +9,7 @@
*/
#include <linux/jiffies.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/input-polldev.h>
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 41168d5f8c1..9c79bd56b51 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/input.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/random.h>
#include <linux/major.h>
#include <linux/proc_fs.h>
@@ -582,7 +583,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)
}
static int input_default_getkeycode(struct input_dev *dev,
- int scancode, int *keycode)
+ unsigned int scancode,
+ unsigned int *keycode)
{
if (!dev->keycodesize)
return -EINVAL;
@@ -596,7 +598,8 @@ static int input_default_getkeycode(struct input_dev *dev,
}
static int input_default_setkeycode(struct input_dev *dev,
- int scancode, int keycode)
+ unsigned int scancode,
+ unsigned int keycode)
{
int old_keycode;
int i;
@@ -654,12 +657,17 @@ static int input_default_setkeycode(struct input_dev *dev,
* This function should be called by anyone interested in retrieving current
* keymap. Presently keyboard and evdev handlers use it.
*/
-int input_get_keycode(struct input_dev *dev, int scancode, int *keycode)
+int input_get_keycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode)
{
- if (scancode < 0)
- return -EINVAL;
+ 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);
- return dev->getkeycode(dev, scancode, keycode);
+ return retval;
}
EXPORT_SYMBOL(input_get_keycode);
@@ -672,16 +680,14 @@ EXPORT_SYMBOL(input_get_keycode);
* This function should be called by anyone needing to update current
* keymap. Presently keyboard and evdev handlers use it.
*/
-int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
+int input_set_keycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode)
{
unsigned long flags;
int old_keycode;
int retval;
- if (scancode < 0)
- return -EINVAL;
-
- if (keycode < 0 || keycode > KEY_MAX)
+ if (keycode > KEY_MAX)
return -EINVAL;
spin_lock_irqsave(&dev->event_lock, flags);
@@ -1881,35 +1887,37 @@ static int input_open_file(struct inode *inode, struct file *file)
const struct file_operations *old_fops, *new_fops = NULL;
int err;
- lock_kernel();
+ err = mutex_lock_interruptible(&input_mutex);
+ if (err)
+ return err;
+
/* No load-on-demand here? */
handler = input_table[iminor(inode) >> 5];
- if (!handler || !(new_fops = fops_get(handler->fops))) {
- err = -ENODEV;
- goto out;
- }
+ if (handler)
+ new_fops = fops_get(handler->fops);
+
+ mutex_unlock(&input_mutex);
/*
* That's _really_ odd. Usually NULL ->open means "nothing special",
* not "no device". Oh, well...
*/
- if (!new_fops->open) {
+ if (!new_fops || !new_fops->open) {
fops_put(new_fops);
err = -ENODEV;
goto out;
}
+
old_fops = file->f_op;
file->f_op = new_fops;
err = new_fops->open(inode, file);
-
if (err) {
fops_put(file->f_op);
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
out:
- unlock_kernel();
return err;
}
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index 52395948475..8e7de5c7754 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -36,6 +36,7 @@
#include <linux/parport.h>
#include <linux/input.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index ae998d99a5a..fbd62abb66f 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -39,6 +39,7 @@
#include <linux/parport.h>
#include <linux/input.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
@@ -819,7 +820,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
int i;
int err;
- if (pad_type < 1 || pad_type > GC_MAX) {
+ if (pad_type < 1 || pad_type >= GC_MAX) {
pr_err("Pad type %d unknown\n", pad_type);
return -EINVAL;
}
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index b6f85986954..d53b9e90023 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c
index a7ba27fb410..3db8006dac3 100644
--- a/drivers/input/keyboard/adp5520-keys.c
+++ b/drivers/input/keyboard/adp5520-keys.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
struct adp5520_keys {
struct input_dev *input;
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c
index b5142d2d511..4771ab172b5 100644
--- a/drivers/input/keyboard/adp5588-keys.c
+++ b/drivers/input/keyboard/adp5588-keys.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/i2c/adp5588.h>
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index fe376a27fe5..7d989603f87 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -34,6 +34,7 @@
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
@@ -162,7 +163,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id)
input_sync(input);
if (bfin_kpad_get_keypressed(bf54x_kpad)) {
- disable_irq(bf54x_kpad->irq);
+ disable_irq_nosync(bf54x_kpad->irq);
bf54x_kpad->lastkey = key;
mod_timer(&bf54x_kpad->timer,
jiffies + bf54x_kpad->keyup_test_jiffies);
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c
index d410d7a52f1..a91ee941b5c 100644
--- a/drivers/input/keyboard/davinci_keyscan.c
+++ b/drivers/input/keyboard/davinci_keyscan.c
@@ -30,6 +30,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <asm/irq.h>
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index bd25a3af166..c8242dd190d 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -25,6 +25,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/ep93xx_keypad.h>
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 2b708aa8555..b8213fd13c3 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -16,6 +16,7 @@
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
+#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index 2ee5b798024..d92c15c39e6 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/timer.h>
/*
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c
index 781fc610286..5fc976dbce0 100644
--- a/drivers/input/keyboard/jornada680_kbd.c
+++ b/drivers/input/keyboard/jornada680_kbd.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/delay.h>
#include <asm/io.h>
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c
index 4e016d82306..2cd3e1d56ea 100644
--- a/drivers/input/keyboard/jornada720_kbd.c
+++ b/drivers/input/keyboard/jornada720_kbd.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <mach/jornada720.h>
#include <mach/hardware.h>
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index 574eda2a495..60ac4684f87 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -31,6 +31,7 @@
#include <linux/input.h>
#include <linux/leds.h>
#include <linux/i2c/lm8323.h>
+#include <linux/slab.h>
/* Commands to send to the chip. */
#define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index 9caed30f3bb..b1ab29861e1 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -192,11 +192,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
{
struct locomokbd *locomokbd = dev_id;
+ u16 r;
+
+ r = locomo_readl(locomokbd->base + LOCOMO_KIC);
+ if ((r & 0x0001) == 0)
+ return IRQ_HANDLED;
+
+ locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
+
/** wait chattering delay **/
udelay(100);
locomokbd_scankeyboard(locomokbd);
-
return IRQ_HANDLED;
}
@@ -210,6 +217,25 @@ static void locomokbd_timer_callback(unsigned long data)
locomokbd_scankeyboard(locomokbd);
}
+static int locomokbd_open(struct input_dev *dev)
+{
+ struct locomokbd *locomokbd = input_get_drvdata(dev);
+ u16 r;
+
+ r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
+ locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+ return 0;
+}
+
+static void locomokbd_close(struct input_dev *dev)
+{
+ struct locomokbd *locomokbd = input_get_drvdata(dev);
+ u16 r;
+
+ r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
+ locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+}
+
static int __devinit locomokbd_probe(struct locomo_dev *dev)
{
struct locomokbd *locomokbd;
@@ -253,6 +279,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev)
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
+ input_dev->open = locomokbd_open;
+ input_dev->close = locomokbd_close;
input_dev->dev.parent = &dev->dev;
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
@@ -261,6 +289,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev)
input_dev->keycodesize = sizeof(locomokbd_keycode[0]);
input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode);
+ input_set_drvdata(input_dev, locomokbd);
+
memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
set_bit(locomokbd->keycode[i], input_dev->keybit);
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index d3c8b61a941..b443e088fd3 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
struct matrix_keypad {
const struct matrix_keypad_platform_data *pdata;
@@ -373,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
input_dev->name = pdev->name;
input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &pdev->dev;
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+ if (!pdata->no_autorepeat)
+ input_dev->evbit[0] |= BIT_MASK(EV_REP);
input_dev->open = matrix_keypad_start;
input_dev->close = matrix_keypad_stop;
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c
index 3b5b948eba3..7fc8185e5c1 100644
--- a/drivers/input/keyboard/max7359_keypad.c
+++ b/drivers/input/keyboard/max7359_keypad.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 1a494d50543..a72e61ddca9 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -34,6 +34,7 @@
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <mach/gpio.h>
#include <plat/keypad.h>
#include <plat/menelaus.h>
diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c
index 78cccddbf55..1f1a5563f60 100644
--- a/drivers/input/keyboard/opencores-kbd.c
+++ b/drivers/input/keyboard/opencores-kbd.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
struct opencores_kbd {
struct input_dev *input;
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index 79cd3e9fdf2..0e53b3bc39a 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -26,6 +26,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c
index 95fbba470e6..b7123a44b6e 100644
--- a/drivers/input/keyboard/pxa930_rotary.c
+++ b/drivers/input/keyboard/pxa930_rotary.c
@@ -13,6 +13,7 @@
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/pxa930_rotary.h>
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index 854e2035cd6..d7dafd9425b 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -22,6 +22,7 @@
#include <linux/bitmap.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
static const struct {
unsigned char kymd, keyout, keyin;
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c
index 42cb3faf733..3910f269cfc 100644
--- a/drivers/input/keyboard/tosakbd.c
+++ b/drivers/input/keyboard/tosakbd.c
@@ -18,6 +18,7 @@
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <mach/gpio.h>
#include <mach/tosa.h>
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c
index 21d6184efa9..7aa59e07b68 100644
--- a/drivers/input/keyboard/twl4030_keypad.c
+++ b/drivers/input/keyboard/twl4030_keypad.c
@@ -32,6 +32,7 @@
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/i2c/twl.h>
+#include <linux/slab.h>
/*
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c
index 6032def0370..4ef764cc493 100644
--- a/drivers/input/keyboard/w90p910_keypad.c
+++ b/drivers/input/keyboard/w90p910_keypad.c
@@ -19,6 +19,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/w90p910_keypad.h>
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c
new file mode 100644
index 00000000000..40dabd8487b
--- /dev/null
+++ b/drivers/input/misc/88pm860x_onkey.c
@@ -0,0 +1,156 @@
+/*
+ * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.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.
+ *
+ * This program is distributed in 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/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
+
+#define PM8607_WAKEUP 0x0b
+
+#define LONG_ONKEY_EN (1 << 1)
+#define ONKEY_STATUS (1 << 0)
+
+struct pm860x_onkey_info {
+ struct input_dev *idev;
+ struct pm860x_chip *chip;
+ struct i2c_client *i2c;
+ struct device *dev;
+ int irq;
+};
+
+/* 88PM860x gives us an interrupt when ONKEY is held */
+static irqreturn_t pm860x_onkey_handler(int irq, void *data)
+{
+ struct pm860x_onkey_info *info = data;
+ int ret;
+
+ ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
+ ret &= ONKEY_STATUS;
+ input_report_key(info->idev, KEY_POWER, ret);
+ input_sync(info->idev);
+
+ /* Enable 8-second long onkey detection */
+ pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN);
+ return IRQ_HANDLED;
+}
+
+static int __devinit pm860x_onkey_probe(struct platform_device *pdev)
+{
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pm860x_onkey_info *info;
+ int irq, ret;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "No IRQ resource!\n");
+ return -EINVAL;
+ }
+
+ info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ info->chip = chip;
+ info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+ info->dev = &pdev->dev;
+ info->irq = irq + chip->irq_base;
+
+ info->idev = input_allocate_device();
+ if (!info->idev) {
+ dev_err(chip->dev, "Failed to allocate input dev\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ info->idev->name = "88pm860x_on";
+ info->idev->phys = "88pm860x_on/input0";
+ info->idev->id.bustype = BUS_I2C;
+ info->idev->dev.parent = &pdev->dev;
+ info->irq = irq;
+ info->idev->evbit[0] = BIT_MASK(EV_KEY);
+ info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
+
+ ret = input_register_device(info->idev);
+ if (ret) {
+ dev_err(chip->dev, "Can't register input device: %d\n", ret);
+ goto out_reg;
+ }
+
+ ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler,
+ IRQF_ONESHOT, "onkey", info);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
+ info->irq, ret);
+ goto out_irq;
+ }
+
+ platform_set_drvdata(pdev, info);
+ return 0;
+
+out_irq:
+ input_unregister_device(info->idev);
+ kfree(info);
+ return ret;
+
+out_reg:
+ input_free_device(info->idev);
+out:
+ kfree(info);
+ return ret;
+}
+
+static int __devexit pm860x_onkey_remove(struct platform_device *pdev)
+{
+ struct pm860x_onkey_info *info = platform_get_drvdata(pdev);
+
+ free_irq(info->irq, info);
+ input_unregister_device(info->idev);
+ kfree(info);
+ return 0;
+}
+
+static struct platform_driver pm860x_onkey_driver = {
+ .driver = {
+ .name = "88pm860x-onkey",
+ .owner = THIS_MODULE,
+ },
+ .probe = pm860x_onkey_probe,
+ .remove = __devexit_p(pm860x_onkey_remove),
+};
+
+static int __init pm860x_onkey_init(void)
+{
+ return platform_driver_register(&pm860x_onkey_driver);
+}
+module_init(pm860x_onkey_init);
+
+static void __exit pm860x_onkey_exit(void)
+{
+ platform_driver_unregister(&pm860x_onkey_driver);
+}
+module_exit(pm860x_onkey_exit);
+
+MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 16ec5233441..23140a3bb8e 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -12,6 +12,16 @@ menuconfig INPUT_MISC
if INPUT_MISC
+config INPUT_88PM860X_ONKEY
+ tristate "88PM860x ONKEY support"
+ depends on MFD_88PM860X
+ help
+ Support the ONKEY of Marvell 88PM860x PMICs as an input device
+ reporting power button status.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 88pm860x_onkey.
+
config INPUT_PCSPKR
tristate "PC Speaker support"
depends on PCSPKR_PLATFORM
@@ -204,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON
To compile this driver as a module, choose M here. The module will
be called twl4030_pwrbutton.
+config INPUT_TWL4030_VIBRA
+ tristate "Support for TWL4030 Vibrator"
+ depends on TWL4030_CORE
+ select TWL4030_CODEC
+ select INPUT_FF_MEMLESS
+ help
+ This option enables support for TWL4030 Vibrator Driver.
+
+ To compile this driver as a module, choose M here. The module will
+ be called twl4030_vibra.
+
config INPUT_UINPUT
tristate "User level driver support"
help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index a8b84854fb7..7e95a5d474d 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,6 +4,7 @@
# Each configuration option enables a list of files.
+obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o
obj-$(CONFIG_INPUT_APANEL) += apanel.o
obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
@@ -25,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
+obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 0501f0e6515..2124b99378b 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -10,6 +10,7 @@
*/
#include <linux/usb/input.h>
+#include <linux/slab.h>
#define DRIVER_DESC "ATI/Philips USB RF remote driver"
#define DRIVER_VERSION "0.3"
@@ -474,10 +475,11 @@ static void ati_remote2_complete_key(struct urb *urb)
}
static int ati_remote2_getkeycode(struct input_dev *idev,
- int scancode, int *keycode)
+ unsigned int scancode, unsigned int *keycode)
{
struct ati_remote2 *ar2 = input_get_drvdata(idev);
- int index, mode;
+ unsigned int mode;
+ int index;
mode = scancode >> 8;
if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -491,10 +493,12 @@ static int ati_remote2_getkeycode(struct input_dev *idev,
return 0;
}
-static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode)
+static int ati_remote2_setkeycode(struct input_dev *idev,
+ unsigned int scancode, unsigned int keycode)
{
struct ati_remote2 *ar2 = input_get_drvdata(idev);
- int index, mode, old_keycode;
+ unsigned int mode, old_keycode;
+ int index;
mode = scancode >> 8;
if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -504,9 +508,6 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc
if (index < 0)
return -EINVAL;
- if (keycode < KEY_RESERVED || keycode > KEY_MAX)
- return -EINVAL;
-
old_keycode = ar2->keycode[mode][index];
ar2->keycode[mode][index] = keycode;
__set_bit(keycode, idev->keybit);
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c
index 61d10177fa8..4f72bdd6941 100644
--- a/drivers/input/misc/bfin_rotary.c
+++ b/drivers/input/misc/bfin_rotary.c
@@ -13,6 +13,7 @@
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <asm/portmux.h>
#include <asm/bfin_rotary.h>
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index ee73d7219c9..fd8407a2963 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -22,6 +22,7 @@
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#define BUTTONS_POLL_INTERVAL 30 /* msec */
#define BUTTONS_COUNT_THRESHOLD 3
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
index 766c06911f4..19af682c24f 100644
--- a/drivers/input/misc/dm355evm_keys.c
+++ b/drivers/input/misc/dm355evm_keys.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/platform_device.h>
diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c
index 7ea969347ca..99335c28625 100644
--- a/drivers/input/misc/pcap_keys.c
+++ b/drivers/input/misc/pcap_keys.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/mfd/ezx-pcap.h>
+#include <linux/slab.h>
struct pcap_keys {
struct pcap_chip *pcap;
diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c
index 008de0c5834..95562735728 100644
--- a/drivers/input/misc/pcf50633-input.c
+++ b/drivers/input/misc/pcf50633-input.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/mfd/pcf50633/core.h>
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index 4ae07935985..1f8e0108962 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/rotary_encoder.h>
+#include <linux/slab.h>
#define DRV_NAME "rotary-encoder"
diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c
index be3a15f5b25..1a80c0dab83 100644
--- a/drivers/input/misc/sgi_btns.c
+++ b/drivers/input/misc/sgi_btns.c
@@ -22,6 +22,7 @@
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#ifdef CONFIG_SGI_IP22
#include <asm/sgi/ioc.h>
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index b064419b90a..0d45422f809 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -9,6 +9,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/of_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
new file mode 100644
index 00000000000..fee9eac8e04
--- /dev/null
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -0,0 +1,298 @@
+/*
+ * twl4030-vibra.c - TWL4030 Vibrator driver
+ *
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Written by Henrik Saari <henrik.saari@nokia.com>
+ * Updates by Felipe Balbi <felipe.balbi@nokia.com>
+ * Input by Jari Vanhala <ext-jari.vanhala@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
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/i2c/twl.h>
+#include <linux/mfd/twl4030-codec.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+
+/* MODULE ID2 */
+#define LEDEN 0x00
+
+/* ForceFeedback */
+#define EFFECT_DIR_180_DEG 0x8000 /* range is 0 - 0xFFFF */
+
+struct vibra_info {
+ struct device *dev;
+ struct input_dev *input_dev;
+
+ struct workqueue_struct *workqueue;
+ struct work_struct play_work;
+
+ bool enabled;
+ int speed;
+ int direction;
+
+ bool coexist;
+};
+
+static void vibra_disable_leds(void)
+{
+ u8 reg;
+
+ /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */
+ twl_i2c_read_u8(TWL4030_MODULE_LED, &reg, LEDEN);
+ reg &= ~0x03;
+ twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg);
+}
+
+/* Powers H-Bridge and enables audio clk */
+static void vibra_enable(struct vibra_info *info)
+{
+ u8 reg;
+
+ twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
+
+ /* turn H-Bridge on */
+ twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+ &reg, TWL4030_REG_VIBRA_CTL);
+ twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+ (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
+
+ twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
+
+ info->enabled = true;
+}
+
+static void vibra_disable(struct vibra_info *info)
+{
+ u8 reg;
+
+ /* Power down H-Bridge */
+ twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+ &reg, TWL4030_REG_VIBRA_CTL);
+ twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+ (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
+
+ twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
+ twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
+
+ info->enabled = false;
+}
+
+static void vibra_play_work(struct work_struct *work)
+{
+ struct vibra_info *info = container_of(work,
+ struct vibra_info, play_work);
+ int dir;
+ int pwm;
+ u8 reg;
+
+ dir = info->direction;
+ pwm = info->speed;
+
+ twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+ &reg, TWL4030_REG_VIBRA_CTL);
+ if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) {
+
+ if (!info->enabled)
+ vibra_enable(info);
+
+ /* set vibra rotation direction */
+ twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+ &reg, TWL4030_REG_VIBRA_CTL);
+ reg = (dir) ? (reg | TWL4030_VIBRA_DIR) :
+ (reg & ~TWL4030_VIBRA_DIR);
+ twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+ reg, TWL4030_REG_VIBRA_CTL);
+
+ /* set PWM, 1 = max, 255 = min */
+ twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+ 256 - pwm, TWL4030_REG_VIBRA_SET);
+ } else {
+ if (info->enabled)
+ vibra_disable(info);
+ }
+}
+
+/*** Input/ForceFeedback ***/
+
+static int vibra_play(struct input_dev *input, void *data,
+ struct ff_effect *effect)
+{
+ struct vibra_info *info = input_get_drvdata(input);
+
+ info->speed = effect->u.rumble.strong_magnitude >> 8;
+ if (!info->speed)
+ info->speed = effect->u.rumble.weak_magnitude >> 9;
+ info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1;
+ queue_work(info->workqueue, &info->play_work);
+ return 0;
+}
+
+static int twl4030_vibra_open(struct input_dev *input)
+{
+ struct vibra_info *info = input_get_drvdata(input);
+
+ info->workqueue = create_singlethread_workqueue("vibra");
+ if (info->workqueue == NULL) {
+ dev_err(&input->dev, "couldn't create workqueue\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void twl4030_vibra_close(struct input_dev *input)
+{
+ struct vibra_info *info = input_get_drvdata(input);
+
+ cancel_work_sync(&info->play_work);
+ INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */
+ destroy_workqueue(info->workqueue);
+ info->workqueue = NULL;
+
+ if (info->enabled)
+ vibra_disable(info);
+}
+
+/*** Module ***/
+#if CONFIG_PM
+static int twl4030_vibra_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct vibra_info *info = platform_get_drvdata(pdev);
+
+ if (info->enabled)
+ vibra_disable(info);
+
+ return 0;
+}
+
+static int twl4030_vibra_resume(struct device *dev)
+{
+ vibra_disable_leds();
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
+ twl4030_vibra_suspend, twl4030_vibra_resume);
+#endif
+
+static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
+{
+ struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data;
+ struct vibra_info *info;
+ int ret;
+
+ if (!pdata) {
+ dev_dbg(&pdev->dev, "platform_data not available\n");
+ return -EINVAL;
+ }
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->dev = &pdev->dev;
+ info->coexist = pdata->coexist;
+ INIT_WORK(&info->play_work, vibra_play_work);
+
+ info->input_dev = input_allocate_device();
+ if (info->input_dev == NULL) {
+ dev_err(&pdev->dev, "couldn't allocate input device\n");
+ ret = -ENOMEM;
+ goto err_kzalloc;
+ }
+
+ input_set_drvdata(info->input_dev, info);
+
+ info->input_dev->name = "twl4030:vibrator";
+ info->input_dev->id.version = 1;
+ info->input_dev->dev.parent = pdev->dev.parent;
+ info->input_dev->open = twl4030_vibra_open;
+ info->input_dev->close = twl4030_vibra_close;
+ __set_bit(FF_RUMBLE, info->input_dev->ffbit);
+
+ ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
+ goto err_ialloc;
+ }
+
+ ret = input_register_device(info->input_dev);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "couldn't register input device\n");
+ goto err_iff;
+ }
+
+ vibra_disable_leds();
+
+ platform_set_drvdata(pdev, info);
+ return 0;
+
+err_iff:
+ input_ff_destroy(info->input_dev);
+err_ialloc:
+ input_free_device(info->input_dev);
+err_kzalloc:
+ kfree(info);
+ return ret;
+}
+
+static int __devexit twl4030_vibra_remove(struct platform_device *pdev)
+{
+ struct vibra_info *info = platform_get_drvdata(pdev);
+
+ /* this also free ff-memless and calls close if needed */
+ input_unregister_device(info->input_dev);
+ kfree(info);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver twl4030_vibra_driver = {
+ .probe = twl4030_vibra_probe,
+ .remove = __devexit_p(twl4030_vibra_remove),
+ .driver = {
+ .name = "twl4030_codec_vibra",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &twl4030_vibra_pm_ops,
+#endif
+ },
+};
+
+static int __init twl4030_vibra_init(void)
+{
+ return platform_driver_register(&twl4030_vibra_driver);
+}
+module_init(twl4030_vibra_init);
+
+static void __exit twl4030_vibra_exit(void)
+{
+ platform_driver_unregister(&twl4030_vibra_driver);
+}
+module_exit(twl4030_vibra_exit);
+
+MODULE_ALIAS("platform:twl4030_codec_vibra");
+
+MODULE_DESCRIPTION("TWL4030 Vibra driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nokia Corporation");
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c
index cbec3dfdd42..64f1de7960c 100644
--- a/drivers/input/misc/winbond-cir.c
+++ b/drivers/input/misc/winbond-cir.c
@@ -56,6 +56,7 @@
#include <linux/io.h>
#include <linux/bitrev.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#define DRVNAME "winbond-cir"
@@ -385,26 +386,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode)
}
static int
-wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+wbcir_getkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode)
{
struct wbcir_data *data = input_get_drvdata(dev);
- *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode);
+ *keycode = wbcir_do_getkeycode(data, scancode);
return 0;
}
static int
-wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode)
+wbcir_setkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode)
{
struct wbcir_data *data = input_get_drvdata(dev);
struct wbcir_keyentry *keyentry;
struct wbcir_keyentry *new_keyentry;
unsigned long flags;
unsigned int old_keycode = KEY_RESERVED;
- u32 scancode = (u32)sscancode;
-
- if (keycode < 0 || keycode > KEY_MAX)
- return -EINVAL;
new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL);
if (!new_keyentry)
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index c0afb71a3a6..04d5a4a3181 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/preempt.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c
index ba4f5dd7c60..c3d7ba5f5b4 100644
--- a/drivers/input/misc/wm831x-on.c
+++ b/drivers/input/misc/wm831x-on.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/input.h>
@@ -97,8 +98,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
wm831x_on->dev->phys = "wm831x_on/input0";
wm831x_on->dev->dev.parent = &pdev->dev;
- ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq,
- IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on);
+ ret = request_threaded_irq(irq, NULL, wm831x_on_irq,
+ IRQF_TRIGGER_RISING, "wm831x_on",
+ wm831x_on);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
goto err_input_dev;
@@ -114,7 +116,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
return 0;
err_irq:
- wm831x_free_irq(wm831x, irq, NULL);
+ free_irq(irq, wm831x_on);
err_input_dev:
input_free_device(wm831x_on->dev);
err:
@@ -127,7 +129,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev)
struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
int irq = platform_get_irq(pdev, 0);
- wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on);
+ free_irq(irq, wm831x_on);
cancel_delayed_work_sync(&wm831x_on->work);
input_unregister_device(wm831x_on->dev);
kfree(wm831x_on);
diff --git a/drivers/input/misc/yealink.h b/drivers/input/misc/yealink.h
index 48af0be9cbd..1e0f5239701 100644
--- a/drivers/input/misc/yealink.h
+++ b/drivers/input/misc/yealink.h
@@ -127,7 +127,7 @@ struct yld_ctl_packet {
* yld_status struct.
*/
-/* LCD, each segment must be driven seperately.
+/* LCD, each segment must be driven separately.
*
* Layout:
*
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index f93c2c0daf1..0d22cb9ce42 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -15,6 +15,7 @@
* the Free Software Foundation.
*/
+#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/libps2.h>
@@ -63,6 +64,9 @@ static const struct alps_model_info alps_model_data[] = {
{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
+ { { 0x73, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, /* HP Pavilion dm3 */
+ { { 0x52, 0x01, 0x14 }, 0xff, 0xff,
+ ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
};
/*
@@ -118,40 +122,27 @@ static void alps_report_buttons(struct psmouse *psmouse,
struct input_dev *dev1, struct input_dev *dev2,
int left, int right, int middle)
{
- struct alps_data *priv = psmouse->private;
- const struct alps_model_info *model = priv->i;
-
- if (model->flags & ALPS_PS2_INTERLEAVED) {
- struct input_dev *dev;
+ struct input_dev *dev;
- /*
- * If shared button has already been reported on the
- * other device (dev2) then this event should be also
- * sent through that device.
- */
- dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
- input_report_key(dev, BTN_LEFT, left);
+ /*
+ * If shared button has already been reported on the
+ * other device (dev2) then this event should be also
+ * sent through that device.
+ */
+ dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
+ input_report_key(dev, BTN_LEFT, left);
- dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
- input_report_key(dev, BTN_RIGHT, right);
+ dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
+ input_report_key(dev, BTN_RIGHT, right);
- dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
- input_report_key(dev, BTN_MIDDLE, middle);
+ dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
+ input_report_key(dev, BTN_MIDDLE, middle);
- /*
- * Sync the _other_ device now, we'll do the first
- * device later once we report the rest of the events.
- */
- input_sync(dev2);
- } else {
- /*
- * For devices with non-interleaved packets we know what
- * device buttons belong to so we can simply report them.
- */
- input_report_key(dev1, BTN_LEFT, left);
- input_report_key(dev1, BTN_RIGHT, right);
- input_report_key(dev1, BTN_MIDDLE, middle);
- }
+ /*
+ * Sync the _other_ device now, we'll do the first
+ * device later once we report the rest of the events.
+ */
+ input_sync(dev2);
}
static void alps_process_packet(struct psmouse *psmouse)
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 908b5b44052..53ec7ddd182 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -205,8 +205,8 @@ struct atp {
bool overflow_warned;
int x_old; /* last reported x/y, */
int y_old; /* used for smoothing */
- signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS];
- signed char xy_old[ATP_XSENSORS + ATP_YSENSORS];
+ u8 xy_cur[ATP_XSENSORS + ATP_YSENSORS];
+ u8 xy_old[ATP_XSENSORS + ATP_YSENSORS];
int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
int idlecount; /* number of empty packets */
struct work_struct work;
@@ -531,7 +531,7 @@ static void atp_complete_geyser_1_2(struct urb *urb)
for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
/* accumulate the change */
- signed char change = dev->xy_old[i] - dev->xy_cur[i];
+ int change = dev->xy_old[i] - dev->xy_cur[i];
dev->xy_acc[i] -= change;
/* prevent down drifting */
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 4f8fe0886b2..b89879bd860 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = {
.disconnect = bcm5974_disconnect,
.suspend = bcm5974_suspend,
.resume = bcm5974_resume,
- .reset_resume = bcm5974_resume,
.id_table = bcm5974_table,
.supports_autosuspend = 1,
};
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index b27684f267b..a138b5da79f 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -11,6 +11,7 @@
*/
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/serio.h>
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index 9169d1591c1..08d66d820d2 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -30,6 +30,7 @@
*/
#define DEBUG
+#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/libps2.h>
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 7c1d7d420ae..c31ad11df6b 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -16,6 +16,7 @@
#include <linux/serio.h>
#include <linux/libps2.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#include "psmouse.h"
#include "lifebook.h"
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c
index 1e827ad0afb..943cfec1566 100644
--- a/drivers/input/mouse/pxa930_trkball.c
+++ b/drivers/input/mouse/pxa930_trkball.c
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/pxa930_trkball.h>
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index 81a6b81cb2f..1242775fee1 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
@@ -26,6 +26,7 @@
#include <linux/libps2.h>
#include <linux/serio.h>
#include <linux/jiffies.h>
+#include <linux/slab.h>
#include "psmouse.h"
#include "sentelic.h"
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index d3f5243fa09..026df601016 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -28,6 +28,7 @@
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/libps2.h>
+#include <linux/slab.h>
#include "psmouse.h"
#include "synaptics.h"
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c
index 9867dfe2a63..8291e7399ff 100644
--- a/drivers/input/mouse/synaptics_i2c.c
+++ b/drivers/input/mouse/synaptics_i2c.c
@@ -17,6 +17,7 @@
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#define DRIVER_NAME "synaptics_i2c"
/* maximum product id is 15 characters */
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 909431c31ab..88121c59c3c 100644
--- a/drivers/input/mouse/touchkit_ps2.c
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -26,7 +26,6 @@
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index 63d4a67830f..0643e49ca60 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -8,6 +8,7 @@
* Trademarks are the property of their respective owners.
*/
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/serio.h>
#include <linux/module.h>
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index a13d80f7da1..f34b22bce4f 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -15,7 +15,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -542,10 +541,8 @@ static int mousedev_open(struct inode *inode, struct file *file)
if (i >= MOUSEDEV_MINORS)
return -ENODEV;
- lock_kernel();
error = mutex_lock_interruptible(&mousedev_table_mutex);
if (error) {
- unlock_kernel();
return error;
}
mousedev = mousedev_table[i];
@@ -554,7 +551,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
mutex_unlock(&mousedev_table_mutex);
if (!mousedev) {
- unlock_kernel();
return -ENODEV;
}
@@ -575,7 +571,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
goto err_free_client;
file->private_data = client;
- unlock_kernel();
return 0;
err_free_client:
@@ -583,7 +578,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
kfree(client);
err_put_mousedev:
put_device(&mousedev->dev);
- unlock_kernel();
return error;
}
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
index 320b7ca48bf..7998560a190 100644
--- a/drivers/input/serio/altera_ps2.c
+++ b/drivers/input/serio/altera_ps2.c
@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#define DRV_NAME "altera_ps2"
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c
index b54452a8c77..6ee8f0ddad5 100644
--- a/drivers/input/serio/at32psif.c
+++ b/drivers/input/serio/at32psif.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
/* PSIF register offsets */
#define PSIF_CR 0x00
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index d1380fc72cc..4a3084695c0 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -35,6 +35,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 06addfa7cc4..3c287dd879d 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/serio.h>
#include <linux/input.h>
#include <linux/interrupt.h>
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index 6cd03ebaf5f..c92f4edfee7 100644
--- a/drivers/input/serio/hil_mlc.c
+++ b/drivers/input/serio/hil_mlc.c
@@ -58,6 +58,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/list.h>
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 2a5982e532f..ead0494721d 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -442,6 +442,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
},
},
{
+ /* Medion Akoya E1222 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
+ },
+ },
+ {
/* Mivvy M310 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
@@ -624,6 +631,9 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
}
+ /* Keyboard ports are always supposed to be wakeup-enabled */
+ device_set_wakeup_enable(&dev->dev, true);
+
i8042_pnp_kbd_devices++;
return 0;
}
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index b54aee7cd9e..6440a8f5568 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -21,6 +21,7 @@
#include <linux/rcupdate.h>
#include <linux/platform_device.h>
#include <linux/i8042.h>
+#include <linux/slab.h>
#include <asm/io.h>
@@ -38,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
static bool i8042_nomux;
module_param_named(nomux, i8042_nomux, bool, 0);
-MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
+MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present.");
static bool i8042_unlock;
module_param_named(unlock, i8042_unlock, bool, 0);
@@ -430,7 +431,7 @@ static bool i8042_filter(unsigned char data, unsigned char str,
}
if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) {
- dbg("Filtered out by platfrom filter\n");
+ dbg("Filtered out by platform filter\n");
return true;
}
@@ -1386,6 +1387,8 @@ static int __init i8042_probe(struct platform_device *dev)
{
int error;
+ i8042_platform_device = dev;
+
error = i8042_controller_selftest();
if (error)
return error;
@@ -1421,6 +1424,7 @@ static int __init i8042_probe(struct platform_device *dev)
i8042_free_aux_ports(); /* in case KBD failed but AUX not */
i8042_free_irqs();
i8042_controller_reset();
+ i8042_platform_device = NULL;
return error;
}
@@ -1430,6 +1434,7 @@ static int __devexit i8042_remove(struct platform_device *dev)
i8042_unregister_ports();
i8042_free_irqs();
i8042_controller_reset();
+ i8042_platform_device = NULL;
return 0;
}
@@ -1448,6 +1453,7 @@ static struct platform_driver i8042_driver = {
static int __init i8042_init(void)
{
+ struct platform_device *pdev;
int err;
dbg_init();
@@ -1460,31 +1466,18 @@ static int __init i8042_init(void)
if (err)
goto err_platform_exit;
- i8042_platform_device = platform_device_alloc("i8042", -1);
- if (!i8042_platform_device) {
- err = -ENOMEM;
+ pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
+ if (IS_ERR(pdev)) {
+ err = PTR_ERR(pdev);
goto err_platform_exit;
}
- err = platform_device_add(i8042_platform_device);
- if (err)
- goto err_free_device;
-
- err = platform_driver_probe(&i8042_driver, i8042_probe);
- if (err)
- goto err_del_device;
-
panic_blink = i8042_panic_blink;
return 0;
- err_del_device:
- platform_device_del(i8042_platform_device);
- err_free_device:
- platform_device_put(i8042_platform_device);
err_platform_exit:
i8042_platform_exit();
-
return err;
}
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index f3876acc3e8..980af94ba9c 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -14,7 +14,6 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/serio.h>
diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
index b089977e0ef..26b45936f9f 100644
--- a/drivers/input/serio/parkbd.c
+++ b/drivers/input/serio/parkbd.c
@@ -46,6 +46,7 @@
#include <linux/module.h>
#include <linux/parport.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/serio.h>
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
index 797314be7af..43494742541 100644
--- a/drivers/input/serio/pcips2.c
+++ b/drivers/input/serio/pcips2.c
@@ -15,6 +15,7 @@
#include <linux/ioport.h>
#include <linux/input.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index e36a0901646..5eb84b3b67f 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -36,6 +36,7 @@
#include <linux/err.h>
#include <linux/bitops.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index ed045c99f84..9da6fbcaaa7 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -34,6 +34,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <mach/hardware.h>
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 27fdaaffbb4..99866485444 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *inode, struct file *file)
struct serio_raw_list *list;
int retval = 0;
- lock_kernel();
retval = mutex_lock_interruptible(&serio_raw_mutex);
if (retval)
- goto out_bkl;
+ return retval;
- if (!(serio_raw = serio_raw_locate(iminor(inode)))) {
+ serio_raw = serio_raw_locate(iminor(inode));
+ if (!serio_raw) {
retval = -ENODEV;
goto out;
}
@@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *inode, struct file *file)
goto out;
}
- if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
+ list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL);
+ if (!list) {
retval = -ENOMEM;
goto out;
}
@@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *inode, struct file *file)
out:
mutex_unlock(&serio_raw_mutex);
-out_bkl:
- unlock_kernel();
return retval;
}
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index 8298e1f6823..f84f8e32e3f 100644
--- a/drivers/input/serio/xilinx_ps2.c
+++ b/drivers/input/serio/xilinx_ps2.c
@@ -19,6 +19,7 @@
#include <linux/serio.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/io.h>
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c
index fbd3987af57..01424834476 100644
--- a/drivers/input/sparse-keymap.c
+++ b/drivers/input/sparse-keymap.c
@@ -15,6 +15,7 @@
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
MODULE_DESCRIPTION("Generic support for sparse keymaps");
@@ -64,36 +65,39 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
static int sparse_keymap_getkeycode(struct input_dev *dev,
- int scancode, int *keycode)
+ unsigned int scancode,
+ unsigned int *keycode)
{
- const struct key_entry *key =
- sparse_keymap_entry_from_scancode(dev, scancode);
+ const struct key_entry *key;
- if (key && key->type == KE_KEY) {
- *keycode = key->keycode;
- return 0;
+ if (dev->keycode) {
+ key = sparse_keymap_entry_from_scancode(dev, scancode);
+ if (key && key->type == KE_KEY) {
+ *keycode = key->keycode;
+ return 0;
+ }
}
return -EINVAL;
}
static int sparse_keymap_setkeycode(struct input_dev *dev,
- int scancode, int keycode)
+ unsigned int scancode,
+ unsigned int keycode)
{
struct key_entry *key;
int old_keycode;
- if (keycode < 0 || keycode > KEY_MAX)
- return -EINVAL;
-
- key = sparse_keymap_entry_from_scancode(dev, scancode);
- if (key && key->type == KE_KEY) {
- old_keycode = key->keycode;
- key->keycode = keycode;
- set_bit(keycode, dev->keybit);
- if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
- clear_bit(old_keycode, dev->keybit);
- return 0;
+ if (dev->keycode) {
+ key = sparse_keymap_entry_from_scancode(dev, scancode);
+ if (key && key->type == KE_KEY) {
+ old_keycode = key->keycode;
+ key->keycode = keycode;
+ set_bit(keycode, dev->keybit);
+ if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
+ clear_bit(old_keycode, dev->keybit);
+ return 0;
+ }
}
return -EINVAL;
@@ -161,7 +165,7 @@ int sparse_keymap_setup(struct input_dev *dev,
return 0;
err_out:
- kfree(keymap);
+ kfree(map);
return error;
}
@@ -173,14 +177,27 @@ EXPORT_SYMBOL(sparse_keymap_setup);
*
* This function is used to free memory allocated by sparse keymap
* in an input device that was set up by sparse_keymap_setup().
+ * NOTE: It is safe to cal this function while input device is
+ * still registered (however the drivers should care not to try to
+ * use freed keymap and thus have to shut off interrups/polling
+ * before freeing the keymap).
*/
void sparse_keymap_free(struct input_dev *dev)
{
+ unsigned long flags;
+
+ /*
+ * Take event lock to prevent racing with input_get_keycode()
+ * and input_set_keycode() if we are called while input device
+ * is still registered.
+ */
+ spin_lock_irqsave(&dev->event_lock, flags);
+
kfree(dev->keycode);
dev->keycode = NULL;
dev->keycodemax = 0;
- dev->getkeycode = NULL;
- dev->setkeycode = NULL;
+
+ spin_unlock_irqrestore(&dev->event_lock, flags);
}
EXPORT_SYMBOL(sparse_keymap_free);
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index 7d005a3616d..4be039d7dca 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -362,7 +362,7 @@ static const int macroKeyEvents[] = {
};
/***********************************************************************
- * Map values to strings and back. Every map shoudl have the following
+ * Map values to strings and back. Every map should have the following
* as its last element: { NULL, AIPTEK_INVALID_VALUE }.
*/
#define AIPTEK_INVALID_VALUE -1
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index a1770e6feee..f46502589e4 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -371,7 +371,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
} else if (pen) {
/* penabled only accepts exact bytes of data */
if (features->type == TABLETPC2FG)
- features->pktlen = WACOM_PKGLEN_PENABLED;
+ features->pktlen = WACOM_PKGLEN_GRAPHIRE;
features->device_type = BTN_TOOL_PEN;
features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
@@ -410,7 +410,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
} else if (pen) {
/* penabled only accepts exact bytes of data */
if (features->type == TABLETPC2FG)
- features->pktlen = WACOM_PKGLEN_PENABLED;
+ features->pktlen = WACOM_PKGLEN_GRAPHIRE;
features->device_type = BTN_TOOL_PEN;
features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
@@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf)
int rv;
mutex_lock(&wacom->lock);
- if (wacom->open) {
+
+ /* switch to wacom mode first */
+ wacom_query_tablet_data(intf, features);
+
+ if (wacom->open)
rv = usb_submit_urb(wacom->irq, GFP_NOIO);
- /* switch to wacom mode if needed */
- if (!wacom_retrieve_hid_descriptor(intf, features))
- wacom_query_tablet_data(intf, features);
- } else
+ else
rv = 0;
+
mutex_unlock(&wacom->lock);
return rv;
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 3d81443e683..4a852d815c6 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1028,7 +1028,7 @@ static const struct wacom_features wacom_features_0x93 =
static const struct wacom_features wacom_features_0x9A =
{ "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC };
static const struct wacom_features wacom_features_0x9F =
- { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC };
+ { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC };
static const struct wacom_features wacom_features_0xE2 =
{ "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG };
static const struct wacom_features wacom_features_0xE3 =
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 8590b1e8ec3..b50cf04e61a 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -17,7 +17,6 @@
#define WACOM_PKGLEN_GRAPHIRE 8
#define WACOM_PKGLEN_BBFUN 9
#define WACOM_PKGLEN_INTUOS 10
-#define WACOM_PKGLEN_PENABLED 8
#define WACOM_PKGLEN_TPC1FG 5
#define WACOM_PKGLEN_TPC2FG 14
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
new file mode 100644
index 00000000000..b3aebc2166b
--- /dev/null
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -0,0 +1,237 @@
+/*
+ * Touchscreen driver for Marvell 88PM860x
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
+
+#define MEAS_LEN (8)
+#define ACCURATE_BIT (12)
+
+/* touch register */
+#define MEAS_EN3 (0x52)
+
+#define MEAS_TSIX_1 (0x8D)
+#define MEAS_TSIX_2 (0x8E)
+#define MEAS_TSIY_1 (0x8F)
+#define MEAS_TSIY_2 (0x90)
+#define MEAS_TSIZ1_1 (0x91)
+#define MEAS_TSIZ1_2 (0x92)
+#define MEAS_TSIZ2_1 (0x93)
+#define MEAS_TSIZ2_2 (0x94)
+
+/* bit definitions of touch */
+#define MEAS_PD_EN (1 << 3)
+#define MEAS_TSIX_EN (1 << 4)
+#define MEAS_TSIY_EN (1 << 5)
+#define MEAS_TSIZ1_EN (1 << 6)
+#define MEAS_TSIZ2_EN (1 << 7)
+
+struct pm860x_touch {
+ struct input_dev *idev;
+ struct i2c_client *i2c;
+ struct pm860x_chip *chip;
+ int irq;
+ int res_x; /* resistor of Xplate */
+};
+
+static irqreturn_t pm860x_touch_handler(int irq, void *data)
+{
+ struct pm860x_touch *touch = data;
+ struct pm860x_chip *chip = touch->chip;
+ unsigned char buf[MEAS_LEN];
+ int x, y, pen_down;
+ int z1, z2, rt = 0;
+ int ret;
+
+ ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf);
+ if (ret < 0)
+ goto out;
+
+ pen_down = buf[1] & (1 << 6);
+ x = ((buf[0] & 0xFF) << 4) | (buf[1] & 0x0F);
+ y = ((buf[2] & 0xFF) << 4) | (buf[3] & 0x0F);
+ z1 = ((buf[4] & 0xFF) << 4) | (buf[5] & 0x0F);
+ z2 = ((buf[6] & 0xFF) << 4) | (buf[7] & 0x0F);
+
+ if (pen_down) {
+ if ((x != 0) && (z1 != 0) && (touch->res_x != 0)) {
+ rt = z2 / z1 - 1;
+ rt = (rt * touch->res_x * x) >> ACCURATE_BIT;
+ dev_dbg(chip->dev, "z1:%d, z2:%d, rt:%d\n",
+ z1, z2, rt);
+ }
+ input_report_abs(touch->idev, ABS_X, x);
+ input_report_abs(touch->idev, ABS_Y, y);
+ input_report_abs(touch->idev, ABS_PRESSURE, rt);
+ input_report_key(touch->idev, BTN_TOUCH, 1);
+ dev_dbg(chip->dev, "pen down at [%d, %d].\n", x, y);
+ } else {
+ input_report_abs(touch->idev, ABS_PRESSURE, 0);
+ input_report_key(touch->idev, BTN_TOUCH, 0);
+ dev_dbg(chip->dev, "pen release\n");
+ }
+ input_sync(touch->idev);
+
+out:
+ return IRQ_HANDLED;
+}
+
+static int pm860x_touch_open(struct input_dev *dev)
+{
+ struct pm860x_touch *touch = input_get_drvdata(dev);
+ int data, ret;
+
+ data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN
+ | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN;
+ ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data);
+ if (ret < 0)
+ goto out;
+ return 0;
+out:
+ return ret;
+}
+
+static void pm860x_touch_close(struct input_dev *dev)
+{
+ struct pm860x_touch *touch = input_get_drvdata(dev);
+ int data;
+
+ data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN
+ | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN;
+ pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
+}
+
+static int __devinit pm860x_touch_probe(struct platform_device *pdev)
+{
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pm860x_platform_data *pm860x_pdata = \
+ pdev->dev.parent->platform_data;
+ struct pm860x_touch_pdata *pdata = NULL;
+ struct pm860x_touch *touch;
+ int irq, ret;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "No IRQ resource!\n");
+ return -EINVAL;
+ }
+
+ if (!pm860x_pdata) {
+ dev_err(&pdev->dev, "platform data is missing\n");
+ return -EINVAL;
+ }
+
+ pdata = pm860x_pdata->touch;
+ if (!pdata) {
+ dev_err(&pdev->dev, "touchscreen data is missing\n");
+ return -EINVAL;
+ }
+
+ touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
+ if (touch == NULL)
+ return -ENOMEM;
+ dev_set_drvdata(&pdev->dev, touch);
+
+ touch->idev = input_allocate_device();
+ if (touch->idev == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate input device!\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ touch->idev->name = "88pm860x-touch";
+ touch->idev->phys = "88pm860x/input0";
+ touch->idev->id.bustype = BUS_I2C;
+ touch->idev->dev.parent = &pdev->dev;
+ touch->idev->open = pm860x_touch_open;
+ touch->idev->close = pm860x_touch_close;
+ touch->chip = chip;
+ touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+ touch->irq = irq + chip->irq_base;
+ touch->res_x = pdata->res_x;
+ input_set_drvdata(touch->idev, touch);
+
+ ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
+ IRQF_ONESHOT, "touch", touch);
+ if (ret < 0)
+ goto out_irq;
+
+ __set_bit(EV_ABS, touch->idev->evbit);
+ __set_bit(ABS_X, touch->idev->absbit);
+ __set_bit(ABS_Y, touch->idev->absbit);
+ __set_bit(ABS_PRESSURE, touch->idev->absbit);
+ __set_bit(EV_SYN, touch->idev->evbit);
+ __set_bit(EV_KEY, touch->idev->evbit);
+ __set_bit(BTN_TOUCH, touch->idev->keybit);
+
+ input_set_abs_params(touch->idev, ABS_X, 0, 1 << ACCURATE_BIT, 0, 0);
+ input_set_abs_params(touch->idev, ABS_Y, 0, 1 << ACCURATE_BIT, 0, 0);
+ input_set_abs_params(touch->idev, ABS_PRESSURE, 0, 1 << ACCURATE_BIT,
+ 0, 0);
+
+ ret = input_register_device(touch->idev);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to register touch!\n");
+ goto out_rg;
+ }
+
+ platform_set_drvdata(pdev, touch);
+ return 0;
+out_rg:
+ free_irq(touch->irq, touch);
+out_irq:
+ input_free_device(touch->idev);
+out:
+ kfree(touch);
+ return ret;
+}
+
+static int __devexit pm860x_touch_remove(struct platform_device *pdev)
+{
+ struct pm860x_touch *touch = platform_get_drvdata(pdev);
+
+ input_unregister_device(touch->idev);
+ free_irq(touch->irq, touch);
+ platform_set_drvdata(pdev, NULL);
+ kfree(touch);
+ return 0;
+}
+
+static struct platform_driver pm860x_touch_driver = {
+ .driver = {
+ .name = "88pm860x-touch",
+ .owner = THIS_MODULE,
+ },
+ .probe = pm860x_touch_probe,
+ .remove = __devexit_p(pm860x_touch_remove),
+};
+
+static int __init pm860x_touch_init(void)
+{
+ return platform_driver_register(&pm860x_touch_driver);
+}
+module_init(pm860x_touch_init);
+
+static void __exit pm860x_touch_exit(void)
+{
+ platform_driver_unregister(&pm860x_touch_driver);
+}
+module_exit(pm860x_touch_exit);
+
+MODULE_DESCRIPTION("Touchscreen driver for Marvell Semiconductor 88PM860x");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:88pm860x-touch");
+
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6457e060ae4..8a8fa4d2d6a 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -11,18 +11,31 @@ menuconfig INPUT_TOUCHSCREEN
if INPUT_TOUCHSCREEN
+config TOUCHSCREEN_88PM860X
+ tristate "Marvell 88PM860x touchscreen"
+ depends on MFD_88PM860X
+ help
+ Say Y here if you have a 88PM860x PMIC and want to enable
+ support for the built-in touchscreen.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called 88pm860x-ts.
+
config TOUCHSCREEN_ADS7846
- tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
+ tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens"
depends on SPI_MASTER
depends on HWMON = n || HWMON
help
Say Y here if you have a touchscreen interface using the
- ADS7846/TSC2046 or ADS7843 controller, and your board-specific
- setup code includes that in its table of SPI devices.
+ ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller,
+ and your board-specific setup code includes that in its
+ table of SPI devices.
If HWMON is selected, and the driver is told the reference voltage
on your board, you will also get hwmon interfaces for the voltage
- (and on ads7846/tsc2046, temperature) sensors of this chip.
+ (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip.
If unsure, say N (but it's safe to say "Y").
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index d61a3b4def9..7fef7d5cca2 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -6,6 +6,7 @@
wm97xx-ts-y := wm97xx-core.o
+obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o
obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c
index eb83939c705..e019d53d1ab 100644
--- a/drivers/input/touchscreen/ad7877.c
+++ b/drivers/input/touchscreen/ad7877.c
@@ -46,7 +46,7 @@
#include <linux/spi/ad7877.h>
#include <asm/irq.h>
-#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50)
+#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(100)
#define MAX_SPI_FREQ_HZ 20000000
#define MAX_12BIT ((1<<12)-1)
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 8b05d8e9754..532279cda0e 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -36,6 +36,7 @@
* TSC2046 is just newer ads7846 silicon.
* Support for ads7843 tested on Atmel at91sam926x-EK.
* Support for ads7845 has only been stubbed in.
+ * Support for Analog Devices AD7873 and AD7843 tested.
*
* IRQ handling needs a workaround because of a shortcoming in handling
* edge triggered IRQs on some platforms like the OMAP1/2. These
@@ -821,6 +822,9 @@ static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
spin_unlock_irq(&ts->lock);
+ if (device_may_wakeup(&ts->spi->dev))
+ enable_irq_wake(ts->spi->irq);
+
return 0;
}
@@ -829,6 +833,9 @@ static int ads7846_resume(struct spi_device *spi)
{
struct ads7846 *ts = dev_get_drvdata(&spi->dev);
+ if (device_may_wakeup(&ts->spi->dev))
+ disable_irq_wake(ts->spi->irq);
+
spin_lock_irq(&ts->lock);
ts->is_suspended = 0;
@@ -984,6 +991,15 @@ static int __devinit ads7846_probe(struct spi_device *spi)
vref = pdata->keep_vref_on;
+ if (ts->model == 7873) {
+ /* The AD7873 is almost identical to the ADS7846
+ * keep VREF off during differential/ratiometric
+ * conversion modes
+ */
+ ts->model = 7846;
+ vref = 0;
+ }
+
/* set up the transfers to read touchscreen state; this assumes we
* use formula #2 for pressure, not #3.
*/
@@ -1191,6 +1207,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
if (err)
goto err_remove_attr_group;
+ device_init_wakeup(&spi->dev, pdata->wakeup);
+
return 0;
err_remove_attr_group:
@@ -1220,6 +1238,8 @@ static int __devexit ads7846_remove(struct spi_device *spi)
{
struct ads7846 *ts = dev_get_drvdata(&spi->dev);
+ device_init_wakeup(&spi->dev, false);
+
ads784x_hwmon_unregister(spi, ts);
input_unregister_device(ts->input);
diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c
index a12242f77e2..fa8e56bd909 100644
--- a/drivers/input/touchscreen/atmel-wm97xx.c
+++ b/drivers/input/touchscreen/atmel-wm97xx.c
@@ -19,6 +19,7 @@
#include <linux/timer.h>
#include <linux/gpio.h>
#include <linux/io.h>
+#include <linux/slab.h>
#define AC97C_ICA 0x10
#define AC97C_CBRHR 0x30
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c
index 3ffd4c4b170..2b72a5923c1 100644
--- a/drivers/input/touchscreen/da9034-ts.c
+++ b/drivers/input/touchscreen/da9034-ts.c
@@ -19,6 +19,7 @@
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/mfd/da903x.h>
+#include <linux/slab.h>
#define DA9034_MANUAL_CTRL 0x50
#define DA9034_LDO_ADC_EN (1 << 4)
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 9029bd3f34e..204b8a1a601 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -33,6 +33,7 @@
#include <linux/timer.h>
#include <linux/gpio.h>
#include <linux/input/eeti_ts.h>
+#include <linux/slab.h>
static int flip_x;
module_param(flip_x, bool, 0644);
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c
index c8b7e8a45c4..4b0a061811f 100644
--- a/drivers/input/touchscreen/jornada720_ts.c
+++ b/drivers/input/touchscreen/jornada720_ts.c
@@ -18,6 +18,7 @@
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/jornada720.h>
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
index be115b3b65e..c5bc62d85bb 100644
--- a/drivers/input/touchscreen/mc13783_ts.c
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/input.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/init.h>
#define MC13783_TS_NAME "mc13783-ts"
@@ -44,7 +45,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data)
{
struct mc13783_ts_priv *priv = data;
- mc13783_ackirq(priv->mc13783, irq);
+ mc13783_irq_ack(priv->mc13783, irq);
/*
* Kick off reading coordinates. Note that if work happens already
@@ -135,7 +136,7 @@ static int mc13783_ts_open(struct input_dev *dev)
mc13783_lock(priv->mc13783);
- mc13783_ackirq(priv->mc13783, MC13783_IRQ_TS);
+ mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS);
ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS,
mc13783_ts_handler, MC13783_TS_NAME, priv);
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c
index 4c28b89757f..ce8ab0269f6 100644
--- a/drivers/input/touchscreen/mcs5000_ts.c
+++ b/drivers/input/touchscreen/mcs5000_ts.c
@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/irq.h>
+#include <linux/slab.h>
/* Registers */
#define MCS5000_TS_STATUS 0x00
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index 141dd584330..defe5dd3627 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/i2c.h>
#include <linux/timer.h>
diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c
index b79097e3028..ea6ef16e59b 100644
--- a/drivers/input/touchscreen/pcap_ts.c
+++ b/drivers/input/touchscreen/pcap_ts.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
index 3755a47d053..98a7d127948 100644
--- a/drivers/input/touchscreen/s3c2410_ts.c
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -26,7 +26,6 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/init.h>
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 89dcbe7b4b0..028a5363eea 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -26,7 +26,6 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/suspend.h>
-#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/ucb1400.h>
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c
index 6ccbdbbf33f..cc18265be1a 100644
--- a/drivers/input/touchscreen/w90p910_ts.c
+++ b/drivers/input/touchscreen/w90p910_ts.c
@@ -16,6 +16,7 @@
#include <linux/clk.h>
#include <linux/input.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
/* ADC controller bit defines */
#define ADC_DELAY 0xf00
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index f944918466e..5109bf3dd85 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -48,6 +48,7 @@
#include <linux/wm97xx.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/slab.h>
#define TS_NAME "wm97xx"
#define WM_CORE_VERSION "1.00"
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index d30436fee47..e14081675bb 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <asm/xen/hypervisor.h>
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c
index f774e12bb64..05ed72c4cf5 100644
--- a/drivers/isdn/act2000/module.c
+++ b/drivers/isdn/act2000/module.c
@@ -16,6 +16,7 @@
#include "act2000_isa.h"
#include "capi.h"
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
static unsigned short act2000_isa_ports[] =
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 8596bd1a4d2..2b83850997c 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/mount.h>
+#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/isdn/capi/capilib.c b/drivers/isdn/capi/capilib.c
index fcaa1241ee7..0b041df2108 100644
--- a/drivers/isdn/capi/capilib.c
+++ b/drivers/isdn/capi/capilib.c
@@ -1,4 +1,5 @@
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/isdn/capilli.h>
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index 26626eead82..03c469e4451 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -18,6 +18,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/isdn/capiutil.h>
+#include <linux/slab.h>
/* from CAPI2.0 DDK AVM Berlin GmbH */
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index ce9b05b9e93..bd00dceacaf 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h>
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 3697c409bec..9f49d906579 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#else
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 77e9fdda059..70cf6bac7a5 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -10,6 +10,7 @@
*/
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 0be15c70c16..47a5ffec55a 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -14,11 +14,6 @@
*/
#include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 6643d6533cc..964a55fb148 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -12,7 +12,6 @@
*/
#include "gigaset.h"
-#include <linux/ctype.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/isdn/capilli.h>
@@ -1301,7 +1300,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
}
/* check parameter: CIP Value */
- if (cmsg->CIPValue > ARRAY_SIZE(cip2bchlc) ||
+ if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) ||
(cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
dev_notice(cs->dev, "%s: unknown CIP value %d\n",
"CONNECT_REQ", cmsg->CIPValue);
@@ -2191,36 +2190,24 @@ static const struct file_operations gigaset_proc_fops = {
.release = single_release,
};
-static struct capi_driver capi_driver_gigaset = {
- .name = "gigaset",
- .revision = "1.0",
-};
-
/**
- * gigaset_isdn_register() - register to LL
+ * gigaset_isdn_regdev() - register device to LL
* @cs: device descriptor structure.
* @isdnid: device name.
*
- * Called by main module to register the device with the LL.
- *
* Return value: 1 for success, 0 for failure
*/
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
{
struct gigaset_capi_ctr *iif;
int rc;
- pr_info("Kernel CAPI interface\n");
-
iif = kmalloc(sizeof(*iif), GFP_KERNEL);
if (!iif) {
pr_err("%s: out of memory\n", __func__);
return 0;
}
- /* register driver with CAPI (ToDo: what for?) */
- register_capi_driver(&capi_driver_gigaset);
-
/* prepare controller structure */
iif->ctr.owner = THIS_MODULE;
iif->ctr.driverdata = cs;
@@ -2241,7 +2228,6 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
rc = attach_capi_ctr(&iif->ctr);
if (rc) {
pr_err("attach_capi_ctr failed (%d)\n", rc);
- unregister_capi_driver(&capi_driver_gigaset);
kfree(iif);
return 0;
}
@@ -2252,17 +2238,36 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
}
/**
- * gigaset_isdn_unregister() - unregister from LL
+ * gigaset_isdn_unregdev() - unregister device from LL
* @cs: device descriptor structure.
- *
- * Called by main module to unregister the device from the LL.
*/
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
{
struct gigaset_capi_ctr *iif = cs->iif;
detach_capi_ctr(&iif->ctr);
kfree(iif);
cs->iif = NULL;
+}
+
+static struct capi_driver capi_driver_gigaset = {
+ .name = "gigaset",
+ .revision = "1.0",
+};
+
+/**
+ * gigaset_isdn_regdrv() - register driver to LL
+ */
+void gigaset_isdn_regdrv(void)
+{
+ pr_info("Kernel CAPI interface\n");
+ register_capi_driver(&capi_driver_gigaset);
+}
+
+/**
+ * gigaset_isdn_unregdrv() - unregister driver from LL
+ */
+void gigaset_isdn_unregdrv(void)
+{
unregister_capi_driver(&capi_driver_gigaset);
}
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 85de3399a2f..f6f45f22192 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -14,7 +14,6 @@
*/
#include "gigaset.h"
-#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -507,7 +506,7 @@ void gigaset_freecs(struct cardstate *cs)
case 2: /* error in initcshw */
/* Deregister from LL */
make_invalid(cs, VALID_ID);
- gigaset_isdn_unregister(cs);
+ gigaset_isdn_unregdev(cs);
/* fall through */
case 1: /* error when registering to LL */
@@ -769,7 +768,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
cs->cmdbytes = 0;
gig_dbg(DEBUG_INIT, "setting up iif");
- if (!gigaset_isdn_register(cs, modulename)) {
+ if (!gigaset_isdn_regdev(cs, modulename)) {
pr_err("error registering ISDN device\n");
goto error;
}
@@ -1205,11 +1204,13 @@ static int __init gigaset_init_module(void)
gigaset_debuglevel = DEBUG_DEFAULT;
pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
+ gigaset_isdn_regdrv();
return 0;
}
static void __exit gigaset_exit_module(void)
{
+ gigaset_isdn_unregdrv();
}
module_init(gigaset_init_module);
diff --git a/drivers/isdn/gigaset/dummyll.c b/drivers/isdn/gigaset/dummyll.c
index 5b27c996af6..bd0b1eaa757 100644
--- a/drivers/isdn/gigaset/dummyll.c
+++ b/drivers/isdn/gigaset/dummyll.c
@@ -57,12 +57,20 @@ void gigaset_isdn_stop(struct cardstate *cs)
{
}
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
{
- pr_info("no ISDN subsystem interface\n");
return 1;
}
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
+{
+}
+
+void gigaset_isdn_regdrv(void)
+{
+ pr_info("no ISDN subsystem interface\n");
+}
+
+void gigaset_isdn_unregdrv(void)
{
}
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index c8f89b78b23..206c380c523 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -1258,14 +1258,10 @@ static void do_action(int action, struct cardstate *cs,
* note that bcs may be NULL if no B channel is free
*/
at_state2->ConState = 700;
- kfree(at_state2->str_var[STR_NMBR]);
- at_state2->str_var[STR_NMBR] = NULL;
- kfree(at_state2->str_var[STR_ZCPN]);
- at_state2->str_var[STR_ZCPN] = NULL;
- kfree(at_state2->str_var[STR_ZBC]);
- at_state2->str_var[STR_ZBC] = NULL;
- kfree(at_state2->str_var[STR_ZHLC]);
- at_state2->str_var[STR_ZHLC] = NULL;
+ for (i = 0; i < STR_NUM; ++i) {
+ kfree(at_state2->str_var[i]);
+ at_state2->str_var[i] = NULL;
+ }
at_state2->int_var[VAR_ZCTP] = -1;
spin_lock_irqsave(&cs->lock, flags);
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 1875ab80b33..05947f9c184 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -20,10 +20,12 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/compiler.h>
#include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/usb.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/ppp_defs.h>
@@ -675,8 +677,10 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size);
*/
/* Called from common.c for setting up/shutting down with the ISDN subsystem */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid);
-void gigaset_isdn_unregister(struct cardstate *cs);
+void gigaset_isdn_regdrv(void);
+void gigaset_isdn_unregdrv(void);
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid);
+void gigaset_isdn_unregdev(struct cardstate *cs);
/* Called from hardware module to indicate completion of an skb */
void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index f0acb9dc9e3..c22e5ace827 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -592,15 +592,13 @@ void gigaset_isdn_stop(struct cardstate *cs)
}
/**
- * gigaset_isdn_register() - register to LL
+ * gigaset_isdn_regdev() - register to LL
* @cs: device descriptor structure.
* @isdnid: device name.
*
- * Called by main module to register the device with the LL.
- *
* Return value: 1 for success, 0 for failure
*/
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
{
isdn_if *iif;
@@ -650,15 +648,29 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
}
/**
- * gigaset_isdn_unregister() - unregister from LL
+ * gigaset_isdn_unregdev() - unregister device from LL
* @cs: device descriptor structure.
- *
- * Called by main module to unregister the device from the LL.
*/
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
{
gig_dbg(DEBUG_CMD, "sending UNLOAD");
gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
kfree(cs->iif);
cs->iif = NULL;
}
+
+/**
+ * gigaset_isdn_regdrv() - register driver to LL
+ */
+void gigaset_isdn_regdrv(void)
+{
+ /* nothing to do */
+}
+
+/**
+ * gigaset_isdn_unregdrv() - unregister driver from LL
+ */
+void gigaset_isdn_unregdrv(void)
+{
+ /* nothing to do */
+}
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index a1bcbc21ff7..c9f28dd40d5 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -13,7 +13,6 @@
#include "gigaset.h"
#include <linux/gigaset_dev.h>
-#include <linux/tty.h>
#include <linux/tty_flip.h>
/*** our ioctls ***/
@@ -628,7 +627,6 @@ void gigaset_if_receive(struct cardstate *cs,
if (tty == NULL)
gig_dbg(DEBUG_IF, "receive on closed device");
else {
- tty_buffer_request_room(tty, len);
tty_insert_flip_string(tty, buffer, len);
tty_flip_buffer_push(tty);
}
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index b69f73a0668..b943efbff44 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -14,7 +14,6 @@
*/
#include "gigaset.h"
-#include <linux/ctype.h>
static ssize_t show_cidmode(struct device *dev,
struct device_attribute *attr, char *buf)
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 168d585d64d..e96c0586886 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -11,11 +11,9 @@
*/
#include "gigaset.h"
-
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
-#include <linux/tty.h>
#include <linux/completion.h>
/* Version Information */
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 9430a2bbb52..76dbb20f306 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -16,10 +16,6 @@
*/
#include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index c38fa0f4c72..2a57da590d7 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -21,6 +21,7 @@
#include <linux/ioport.h>
#include <linux/capi.h>
#include <linux/kernelcapi.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/init.h>
#include <asm/uaccess.h>
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index 124550d0dbf..9c8d7aa053c 100644
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -20,6 +20,7 @@
#include <linux/ioport.h>
#include <linux/capi.h>
#include <linux/kernelcapi.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <linux/init.h>
#include <asm/uaccess.h>
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index de6e6b31181..7715d3242ec 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -22,6 +22,7 @@
#include <linux/capi.h>
#include <linux/kernelcapi.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/netdevice.h>
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
index baeeb3c2a3e..08216b14be1 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -21,6 +21,7 @@
#include <linux/kernelcapi.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h>
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c
index 0f073cd7376..97a20964cfc 100644
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ b/drivers/isdn/hardware/eicon/capimain.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index ae89fb89da6..341ef17c22a 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
for (i = 0; i < w; i++)
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i];
((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
- len = offsetof(T30_INFO, station_id) + 20;
+ len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
w = fax_parms[5].length;
if (w > 20)
w = 20;
@@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
&& (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
&& (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
{
- len = offsetof(T30_INFO, station_id) + 20;
+ len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
if (plci->fax_connect_info_length < len)
{
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
break;
}
ncpi = &m_parms[1];
- len = offsetof(T30_INFO, station_id) + 20;
+ len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
if (plci->fax_connect_info_length < len)
{
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -6830,7 +6830,7 @@ static void nl_ind(PLCI *plci)
if(((T30_INFO *)plci->NL.RBuffer->P)->station_id_len)
{
plci->ncpi_buffer[len] = 20;
- for (i = 0; i < 20; i++)
+ for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i];
}
if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
@@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci)
if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
& ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
{
- i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
+ i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
while (i < plci->NL.RBuffer->length)
plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
}
@@ -8400,7 +8400,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
}
}
/* copy station id to NLC */
- for(i=0; i<20; i++)
+ for(i=0; i < T30_MAX_STATION_ID_LENGTH; i++)
{
if(i<b3_config_parms[2].length)
{
@@ -8411,29 +8411,29 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
((T30_INFO *)&nlc[1])->station_id[i] = ' ';
}
}
- ((T30_INFO *)&nlc[1])->station_id_len = 20;
+ ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
/* copy head line to NLC */
if(b3_config_parms[3].length)
{
- pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20])));
+ pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
if (pos != 0)
{
if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
pos = 0;
else
{
- ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
- ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
+ nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+ nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
len = (byte)b3_config_parms[2].length;
if (len > 20)
len = 20;
if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
{
for (i = 0; i < len; i++)
- ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[2].info)[1+i];
- ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
- ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
+ nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[2].info)[1+i];
+ nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+ nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
}
}
}
@@ -8444,9 +8444,8 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
nlc[0] += (byte)(pos + len);
for (i = 0; i < len; i++)
- ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[3].info)[1+i];
- }
- else
+ nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[3].info)[1+i];
+ } else
((T30_INFO *)&nlc[1])->head_line_len = 0;
plci->nsf_control_bits = 0;
@@ -8473,7 +8472,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
}
len = nlc[0];
- pos = offsetof(T30_INFO, station_id) + 20;
+ pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
if (pos < plci->fax_connect_info_length)
{
for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
@@ -8525,7 +8524,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
}
PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
- len = offsetof(T30_INFO, station_id) + 20;
+ len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
for (i = 0; i < len; i++)
plci->fax_connect_info_buffer[i] = nlc[1+i];
((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0;
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
index 81ac541d40d..d4215369bb5 100644
--- a/drivers/isdn/hardware/mISDN/avmfritz.c
+++ b/drivers/isdn/hardware/mISDN/avmfritz.c
@@ -24,6 +24,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "ipac.h"
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index ad36df9b759..75e71b5d921 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -153,6 +153,7 @@
#define HFC_MULTI_VERSION "2.03"
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
@@ -5265,6 +5266,8 @@ static const struct hm_map hfcm_map[] = {
/*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
HFC_IO_MODE_EMBSD, XHFC_IRQ},
/*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
+/*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+/*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
};
#undef H
@@ -5300,6 +5303,10 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = {
PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
+ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+ 0xb761, 0, 0, H(33)}, /* BN2S PCIe */
+ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+ 0xb762, 0, 0, H(34)}, /* BN4S PCIe */
/* Cards with HFC-8S Chip */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 70e6b0e0112..5940a2c1207 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -48,6 +48,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
+#include <linux/slab.h>
#include "hfc_pci.h"
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index a64bb6c67ba..b3b7e2879ba 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -33,6 +33,7 @@
#include <linux/delay.h>
#include <linux/usb.h>
#include <linux/mISDNhw.h>
+#include <linux/slab.h>
#include "hfcsusb.h"
static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
index 36c6c616a65..f5b3d2b26a0 100644
--- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c
+++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
@@ -42,6 +42,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
+#include <linux/slab.h>
#include "ipac.h"
#define INFINEON_REV "1.0"
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
index 613ba043537..64ecc6f5ffa 100644
--- a/drivers/isdn/hardware/mISDN/mISDNipac.c
+++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -20,6 +20,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mISDNhw.h>
#include "ipac.h"
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
index 09095c74711..38eb31439a7 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -25,6 +25,7 @@
*/
/* #define DEBUG */
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/vmalloc.h>
#include <linux/mISDNhw.h>
@@ -1712,13 +1713,13 @@ mISDNisar_init(struct isar_hw *isar, void *hw)
}
EXPORT_SYMBOL(mISDNisar_init);
-static int isar_mod_init(void)
+static int __init isar_mod_init(void)
{
pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV);
return 0;
}
-static void isar_mod_cleanup(void)
+static void __exit isar_mod_cleanup(void)
{
pr_notice("mISDN: ISAR module unloaded\n");
}
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
index 6c1b164937a..0a3553df065 100644
--- a/drivers/isdn/hardware/mISDN/netjet.c
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -24,6 +24,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
+#include <linux/slab.h>
#include "ipac.h"
#include "iohelper.h"
#include "netjet.h"
diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c
index 7726afdbb40..d097a4e40e2 100644
--- a/drivers/isdn/hardware/mISDN/speedfax.c
+++ b/drivers/isdn/hardware/mISDN/speedfax.c
@@ -23,6 +23,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
index 2952a58c7a6..31f9d71fb22 100644
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -25,6 +25,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mISDNhw.h>
+#include <linux/slab.h>
#include "w6692.h"
#define W6692_REV "2.0"
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index d6fdf1f6675..5d727839787 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -59,6 +59,7 @@
#include "amd7930_fn.h"
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/gfp.h>
static void Amd7930_new_ph(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 14295a155e7..fcf4ed1cb4b 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -17,6 +17,7 @@
#include "isac.h"
#include "isdnl1.h"
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/isapnp.h>
#include <linux/interrupt.h>
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index e5deb15cf40..8d1d63a02b3 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -50,7 +50,7 @@ module_param(isdnprot, int, 0);
handler.
*/
-static int avma1cs_config(struct pcmcia_device *link);
+static int avma1cs_config(struct pcmcia_device *link) __devinit ;
static void avma1cs_release(struct pcmcia_device *link);
/*
@@ -59,7 +59,7 @@ static void avma1cs_release(struct pcmcia_device *link);
needed to manage one actual PCMCIA card.
*/
-static void avma1cs_detach(struct pcmcia_device *p_dev);
+static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ;
/*
@@ -99,7 +99,7 @@ typedef struct local_info_t {
======================================================================*/
-static int avma1cs_probe(struct pcmcia_device *p_dev)
+static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
{
local_info_t *local;
@@ -140,7 +140,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
======================================================================*/
-static void avma1cs_detach(struct pcmcia_device *link)
+static void __devexit avma1cs_detach(struct pcmcia_device *link)
{
dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
avma1cs_release(link);
@@ -174,7 +174,7 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev,
}
-static int avma1cs_config(struct pcmcia_device *link)
+static int __devinit avma1cs_config(struct pcmcia_device *link)
{
local_info_t *dev;
int i;
@@ -282,7 +282,7 @@ static struct pcmcia_driver avma1cs_driver = {
.name = "avma1_cs",
},
.probe = avma1cs_probe,
- .remove = avma1cs_detach,
+ .remove = __devexit_p(avma1cs_detach),
.id_table = avma1cs_ids,
};
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index 475b1a02000..f58ded8f403 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -17,6 +17,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include "hisax.h"
#include <linux/isdn/capicmd.h>
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 4fab18d4d02..544cf4b1cce 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -23,6 +23,7 @@
#include <linux/kernel_stat.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#define HISAX_STATUS_BUFSIZE 4096
/*
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index 23c41fcd864..5d9d338814a 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -19,6 +19,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include "hisax.h"
#include "arcofi.h"
#include "isac.h"
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index c9a30b1c923..c9f2279e21f 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -76,7 +76,7 @@ module_param(protocol, int, 0);
handler.
*/
-static int elsa_cs_config(struct pcmcia_device *link);
+static int elsa_cs_config(struct pcmcia_device *link) __devinit ;
static void elsa_cs_release(struct pcmcia_device *link);
/*
@@ -85,7 +85,7 @@ static void elsa_cs_release(struct pcmcia_device *link);
needed to manage one actual PCMCIA card.
*/
-static void elsa_cs_detach(struct pcmcia_device *p_dev);
+static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit;
/*
A driver needs to provide a dev_node_t structure for each device
@@ -121,7 +121,7 @@ typedef struct local_info_t {
======================================================================*/
-static int elsa_cs_probe(struct pcmcia_device *link)
+static int __devinit elsa_cs_probe(struct pcmcia_device *link)
{
local_info_t *local;
@@ -166,7 +166,7 @@ static int elsa_cs_probe(struct pcmcia_device *link)
======================================================================*/
-static void elsa_cs_detach(struct pcmcia_device *link)
+static void __devexit elsa_cs_detach(struct pcmcia_device *link)
{
local_info_t *info = link->priv;
@@ -210,7 +210,7 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
return -ENODEV;
}
-static int elsa_cs_config(struct pcmcia_device *link)
+static int __devinit elsa_cs_config(struct pcmcia_device *link)
{
local_info_t *dev;
int i;
@@ -327,7 +327,7 @@ static struct pcmcia_driver elsa_cs_driver = {
.name = "elsa_cs",
},
.probe = elsa_cs_probe,
- .remove = elsa_cs_detach,
+ .remove = __devexit_p(elsa_cs_detach),
.id_table = elsa_ids,
.suspend = elsa_suspend,
.resume = elsa_resume,
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
index 1657bba7879..cbda3790a10 100644
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -9,6 +9,7 @@
#include <linux/serial.h>
#include <linux/serial_reg.h>
+#include <linux/slab.h>
#define MAX_MODEM_BUF 256
#define WAKEUP_CHARS (MAX_MODEM_BUF/2)
diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c
index 34fade96a58..732ea633758 100644
--- a/drivers/isdn/hisax/fsm.c
+++ b/drivers/isdn/hisax/fsm.c
@@ -15,6 +15,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include "hisax.h"
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index ab98e135bcb..051b44e2556 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -25,6 +25,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/skbuff.h>
#include <linux/wait.h>
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 8d22f50760e..7250f56a524 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "hisax.h"
#include "hfc_2bds0.h"
#include "isdnl1.h"
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index d0520ad3067..b1f6481e119 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -16,6 +16,7 @@
#include "isac.h"
#include "isdnl1.h"
#include <linux/interrupt.h>
+#include <linux/slab.h>
static inline int
WaitForBusy(struct IsdnCardState *cs)
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index 419f87cad8c..be5faf4aa86 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -17,6 +17,7 @@
#include "isdnl1.h"
#include <linux/interrupt.h>
#include <linux/isapnp.h>
+#include <linux/slab.h>
static const char *hfcsx_revision = "$Revision: 1.12.2.5 $";
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index aaaeaafd86f..ed9527aa5f2 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -39,6 +39,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include "hisax.h"
#include "hisax_if.h"
#include "hfc_usb.h"
diff --git a/drivers/isdn/hisax/hisax_isac.c b/drivers/isdn/hisax/hisax_isac.c
index d0fefcf999c..a8447fa2f47 100644
--- a/drivers/isdn/hisax/hisax_isac.c
+++ b/drivers/isdn/hisax/hisax_isac.c
@@ -21,6 +21,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include "hisax_isac.h"
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c
index c8f9951f791..904b9100df9 100644
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -16,6 +16,7 @@
#include "isac.h"
#include "isdnl1.h"
#include <linux/interrupt.h>
+#include <linux/slab.h>
static char *HSCXVer[] =
{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index c80cbb8a2ef..63057268cc3 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -20,6 +20,7 @@
// #include "arcofi.h"
#include "isdnl1.h"
#include <linux/interrupt.h>
+#include <linux/slab.h>
#define DBUSY_TIMER_VALUE 80
#define ARCOFI_USE 0
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index 00afd553890..751b25f2ff5 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -10,6 +10,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include "hisax_if.h"
#include "hisax.h"
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index a19354d9434..2b66728136d 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -18,6 +18,7 @@
#include "arcofi.h"
#include "isdnl1.h"
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/init.h>
#define DBUSY_TIMER_VALUE 80
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 6bde16c00fb..40b914bded8 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -13,6 +13,7 @@
#include "isar.h"
#include "isdnl1.h"
#include <linux/interrupt.h>
+#include <linux/slab.h>
#define DBG_LOADFIRM 0
#define DUMP_MBOXFRAME 2
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index 9ce6abe05b1..d5eeacf565d 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -19,6 +19,7 @@
*/
#include <linux/init.h>
+#include <linux/gfp.h>
#include "hisax.h"
#include "isdnl1.h"
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
index 7b9496a63b5..0858791978d 100644
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -16,6 +16,7 @@
*/
#include <linux/init.h>
+#include <linux/gfp.h>
#include "hisax.h"
#include "isdnl2.h"
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index 06766022d3a..fd0b643ab74 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -16,6 +16,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include "hisax.h"
#include "isdnl3.h"
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index 70840a710ac..ea8f840871d 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -17,6 +17,7 @@
#include "jade.h"
#include "isdnl1.h"
#include <linux/interrupt.h>
+#include <linux/slab.h>
int
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
index a12fa4d3490..cc6ee2d3988 100644
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -23,6 +23,7 @@
#include "isdnl3.h"
#include "l3dss1.h"
#include <linux/ctype.h>
+#include <linux/slab.h>
extern char *HiSax_getrev(const char *revision);
static const char *dss1_revision = "$Revision: 2.32.2.3 $";
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index 4622d43c7e1..f9584491fe8 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -22,6 +22,7 @@
#include "isdnl3.h"
#include "l3ni1.h"
#include <linux/ctype.h>
+#include <linux/slab.h>
extern char *HiSax_getrev(const char *revision);
static const char *ni1_revision = "$Revision: 2.8.2.3 $";
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index 02c6fbaeccf..5d7f0f2ff9b 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -21,6 +21,7 @@
#include "isdnl1.h"
#include <linux/interrupt.h>
#include <linux/ppp_defs.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include "netjet.h"
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 7836ec3c7f8..71b3ddef03b 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -76,7 +76,7 @@ module_param(protocol, int, 0);
event handler.
*/
-static int sedlbauer_config(struct pcmcia_device *link);
+static int sedlbauer_config(struct pcmcia_device *link) __devinit ;
static void sedlbauer_release(struct pcmcia_device *link);
/*
@@ -85,7 +85,7 @@ static void sedlbauer_release(struct pcmcia_device *link);
needed to manage one actual PCMCIA card.
*/
-static void sedlbauer_detach(struct pcmcia_device *p_dev);
+static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
/*
You'll also need to prototype all the functions that will actually
@@ -129,7 +129,7 @@ typedef struct local_info_t {
======================================================================*/
-static int sedlbauer_probe(struct pcmcia_device *link)
+static int __devinit sedlbauer_probe(struct pcmcia_device *link)
{
local_info_t *local;
@@ -177,7 +177,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
======================================================================*/
-static void sedlbauer_detach(struct pcmcia_device *link)
+static void __devexit sedlbauer_detach(struct pcmcia_device *link)
{
dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
@@ -283,7 +283,7 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
-static int sedlbauer_config(struct pcmcia_device *link)
+static int __devinit sedlbauer_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
win_req_t *req;
@@ -441,7 +441,7 @@ static struct pcmcia_driver sedlbauer_driver = {
.name = "sedlbauer_cs",
},
.probe = sedlbauer_probe,
- .remove = sedlbauer_detach,
+ .remove = __devexit_p(sedlbauer_detach),
.id_table = sedlbauer_ids,
.suspend = sedlbauer_suspend,
.resume = sedlbauer_resume,
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 95b1cdd9795..e56e5af889b 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -11,8 +11,8 @@
*/
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/usb.h>
-#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/bitrev.h>
#include "st5481.h"
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 39e8e49cfd2..b7876b19fe7 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -11,8 +11,8 @@
*/
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/usb.h>
-#include <linux/slab.h>
#include <linux/netdevice.h>
#include "st5481.h"
diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c
index 6e65424f1f0..f4cb178b066 100644
--- a/drivers/isdn/hisax/tei.c
+++ b/drivers/isdn/hisax/tei.c
@@ -17,6 +17,7 @@
#include "hisax.h"
#include "isdnl2.h"
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/random.h>
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index b0c5976cbdb..d010a0da8e1 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -57,7 +57,7 @@ module_param(protocol, int, 0);
handler.
*/
-static int teles_cs_config(struct pcmcia_device *link);
+static int teles_cs_config(struct pcmcia_device *link) __devinit ;
static void teles_cs_release(struct pcmcia_device *link);
/*
@@ -66,7 +66,7 @@ static void teles_cs_release(struct pcmcia_device *link);
needed to manage one actual PCMCIA card.
*/
-static void teles_detach(struct pcmcia_device *p_dev);
+static void teles_detach(struct pcmcia_device *p_dev) __devexit ;
/*
A linked list of "instances" of the teles_cs device. Each actual
@@ -112,7 +112,7 @@ typedef struct local_info_t {
======================================================================*/
-static int teles_probe(struct pcmcia_device *link)
+static int __devinit teles_probe(struct pcmcia_device *link)
{
local_info_t *local;
@@ -156,7 +156,7 @@ static int teles_probe(struct pcmcia_device *link)
======================================================================*/
-static void teles_detach(struct pcmcia_device *link)
+static void __devexit teles_detach(struct pcmcia_device *link)
{
local_info_t *info = link->priv;
@@ -200,7 +200,7 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev,
return -ENODEV;
}
-static int teles_cs_config(struct pcmcia_device *link)
+static int __devinit teles_cs_config(struct pcmcia_device *link)
{
local_info_t *dev;
int i;
@@ -319,7 +319,7 @@ static struct pcmcia_driver teles_cs_driver = {
.name = "teles_cs",
},
.probe = teles_probe,
- .remove = teles_detach,
+ .remove = __devexit_p(teles_detach),
.id_table = teles_ids,
.suspend = teles_suspend,
.resume = teles_resume,
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index 9d6e864023f..e2cfb6f5aa4 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -16,6 +16,7 @@
#include "isdnl1.h"
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/slab.h>
/* table entry in the PCI devices list */
typedef struct {
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index fe874afa4f8..6299b06ae00 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#define VER_DRIVER 0
#define VER_CARDTYPE 1
diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
index be787e16bb7..4f541ef14f9 100644
--- a/drivers/isdn/hysdn/hysdn_boot.c
+++ b/drivers/isdn/hysdn/hysdn_boot.c
@@ -143,7 +143,7 @@ pof_handle_data(hysdn_card * card, int datlen)
(boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
datlen, boot->pof_recoffset);
- if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0))
+ if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
return (boot->last_error); /* error writing data */
if (boot->pof_recoffset + datlen >= boot->pof_reclen)
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 90b35e1a4b7..80966462d6d 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -16,6 +16,7 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <net/net_namespace.h>
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 8bcae28c440..e83f6fda32f 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -14,6 +14,7 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include "hysdn_defs.h"
diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c
index fb350c567c6..861bdf3421f 100644
--- a/drivers/isdn/i4l/isdn_audio.c
+++ b/drivers/isdn/i4l/isdn_audio.c
@@ -12,6 +12,7 @@
*/
#include <linux/isdn.h>
+#include <linux/slab.h>
#include "isdn_audio.h"
#include "isdn_common.h"
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index adb1e8c36b4..70044ee4b22 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/isdn.h>
#include <linux/smp_lock.h>
@@ -1347,7 +1348,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
/*
* isdn net devices manage lots of configuration variables as linked lists.
* Those lists must only be manipulated from user space. Some of the ioctl's
- * service routines access user space and are not atomic. Therefor, ioctl's
+ * service routines access user space and are not atomic. Therefore, ioctl's
* manipulating the lists and ioctl's sleeping while accessing the lists
* are serialized by means of a semaphore.
*/
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 507e13d9a57..8c85d1e88cc 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -23,6 +23,7 @@
*/
#include <linux/isdn.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <net/dst.h>
#include <net/pkt_sched.h>
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 45df6675e8e..f37b8f68d0a 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -12,6 +12,7 @@
#include <linux/isdn.h>
#include <linux/poll.h>
#include <linux/ppp-comp.h>
+#include <linux/slab.h>
#ifdef CONFIG_IPPP_FILTER
#include <linux/filter.h>
#endif
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 2881a66c1aa..fc8454d2eea 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -12,6 +12,7 @@
#undef ISDN_TTY_STAT_DEBUG
#include <linux/isdn.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include "isdn_common.h"
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c
index 8b3efc24316..efcf1f9327e 100644
--- a/drivers/isdn/i4l/isdn_x25iface.c
+++ b/drivers/isdn/i4l/isdn_x25iface.c
@@ -20,6 +20,7 @@
/* #include <linux/isdn.h> */
#include <linux/netdevice.h>
#include <linux/concap.h>
+#include <linux/slab.h>
#include <linux/wanrouter.h>
#include <net/x25device.h>
#include "isdn_x25iface.h"
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index bf7997abc4a..2e847a90bad 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -12,6 +12,7 @@
#include "icn.h"
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/sched.h>
static int portbase = ICN_BASEADDR;
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index a335c85a736..b8a1098b66e 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/sched.h>
#include "isdnloop.h"
diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c
index f1bbc88763b..1fa629b3b94 100644
--- a/drivers/isdn/mISDN/clock.c
+++ b/drivers/isdn/mISDN/clock.c
@@ -33,6 +33,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/spinlock.h>
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
index 21d34be5af6..afeebb00fe0 100644
--- a/drivers/isdn/mISDN/core.c
+++ b/drivers/isdn/mISDN/core.c
@@ -12,6 +12,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/module.h>
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index 9c7c0d1ba55..713ef2b805a 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -124,6 +124,7 @@
/* delay.h is required for hw_lock.h */
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mISDNif.h>
#include <linux/mISDNdsp.h>
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 43ff4d3b046..6f5b5486428 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -154,6 +154,7 @@
*/
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/mISDNif.h>
#include <linux/mISDNdsp.h>
#include <linux/module.h>
@@ -1114,7 +1115,7 @@ static struct Bprotocol DSP = {
.create = dspcreate
};
-static int dsp_init(void)
+static int __init dsp_init(void)
{
int err;
int tics;
@@ -1212,7 +1213,7 @@ static int dsp_init(void)
}
-static void dsp_cleanup(void)
+static void __exit dsp_cleanup(void)
{
mISDN_unregister_Bprotocol(&DSP);
diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
index e9941678edf..621f3100709 100644
--- a/drivers/isdn/mISDN/dsp_pipeline.c
+++ b/drivers/isdn/mISDN/dsp_pipeline.c
@@ -25,6 +25,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/string.h>
#include <linux/mISDNif.h>
diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c
index 1debf53670d..7dbe54ed1de 100644
--- a/drivers/isdn/mISDN/dsp_tones.c
+++ b/drivers/isdn/mISDN/dsp_tones.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/gfp.h>
#include <linux/mISDNif.h>
#include <linux/mISDNdsp.h>
#include "core.h"
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
index e8049be552a..307bd6e8988 100644
--- a/drivers/isdn/mISDN/hwchannel.c
+++ b/drivers/isdn/mISDN/hwchannel.c
@@ -15,6 +15,7 @@
*
*/
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/mISDNhw.h>
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
index f1e8af54dff..22f38e48ac4 100644
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -233,6 +233,7 @@ socket process and create a new one.
#include <linux/inet.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include "core.h"
#include "l1oip.h"
@@ -477,7 +478,7 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n",
__func__, len);
- /* check lenght */
+ /* check length */
if (len < 1+1+2) {
printk(KERN_WARNING "%s: packet error - length %d below "
"4 bytes\n", __func__, len);
@@ -1509,7 +1510,7 @@ l1oip_init(void)
printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
__func__, l1oip_cnt, pri ? "PRI" : "BRI",
bundle ? "bundled IP packet for all B-channels" :
- "seperate IP packets for every B-channel");
+ "separate IP packets for every B-channel");
hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);
if (!hc) {
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
index e826eeb1ece..ac4aa18c632 100644
--- a/drivers/isdn/mISDN/layer1.c
+++ b/drivers/isdn/mISDN/layer1.c
@@ -16,6 +16,7 @@
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mISDNhw.h>
#include "core.h"
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
index e17f0044e0b..c9737178876 100644
--- a/drivers/isdn/mISDN/layer2.c
+++ b/drivers/isdn/mISDN/layer2.c
@@ -16,6 +16,7 @@
*/
#include <linux/mISDNif.h>
+#include <linux/slab.h>
#include "core.h"
#include "fsm.h"
#include "layer2.h"
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index fcfe17a19a6..3232206406b 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -16,6 +16,7 @@
*/
#include <linux/mISDNif.h>
+#include <linux/slab.h>
#include "core.h"
static u_int *debug;
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
index 0d05ec43012..b159bd59e64 100644
--- a/drivers/isdn/mISDN/stack.c
+++ b/drivers/isdn/mISDN/stack.c
@@ -15,6 +15,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/mISDNif.h>
#include <linux/kthread.h>
#include <linux/smp_lock.h>
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index 6d4da609588..34e898fe2f4 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -16,6 +16,7 @@
*/
#include "layer2.h"
#include <linux/random.h>
+#include <linux/slab.h>
#include "core.h"
#define ID_REQUEST 1
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
index 5b7e9bf514f..8785004e85e 100644
--- a/drivers/isdn/mISDN/timerdev.c
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -19,6 +19,7 @@
#include <linux/poll.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c
index 43ecd0f5423..976143b2346 100644
--- a/drivers/isdn/pcbit/callbacks.c
+++ b/drivers/isdn/pcbit/callbacks.c
@@ -19,7 +19,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/skbuff.h>
diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c
index 37e9626cebf..d5920ae22d7 100644
--- a/drivers/isdn/pcbit/edss1.c
+++ b/drivers/isdn/pcbit/edss1.c
@@ -19,7 +19,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/skbuff.h>
diff --git a/drivers/isdn/sc/hardware.h b/drivers/isdn/sc/hardware.h
index 9e6d5302bf8..627324856ea 100644
--- a/drivers/isdn/sc/hardware.h
+++ b/drivers/isdn/sc/hardware.h
@@ -87,7 +87,7 @@
#define BRI_CHANNELS 2 /* Number of B channels */
#define BRI_BASEPG_VAL 0x98
#define BRI_MAGIC 0x60000 /* Magic Number */
-#define BRI_MEMSIZE 0x10000 /* Ammount of RAM (64K) */
+#define BRI_MEMSIZE 0x10000 /* Amount of RAM (64K) */
#define BRI_PARTNO "72-029"
#define BRI_FEATURES ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L3_TRANS;
/*
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 5a0774880d5..ca710ab278e 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -9,6 +9,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "includes.h"
#include "hardware.h"
#include "card.h"
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 8a0e1ec95e4..505eb64c329 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -15,77 +15,86 @@ config LEDS_CLASS
This option enables the led sysfs class in /sys/class/leds. You'll
need this to do anything useful with LEDs. If unsure, say N.
+if LEDS_CLASS
+
comment "LED drivers"
+config LEDS_88PM860X
+ tristate "LED Support for Marvell 88PM860x PMIC"
+ depends on LEDS_CLASS && MFD_88PM860X
+ help
+ This option enables support for on-chip LED drivers found on Marvell
+ Semiconductor 88PM8606 PMIC.
+
config LEDS_ATMEL_PWM
tristate "LED Support using Atmel PWM outputs"
- depends on LEDS_CLASS && ATMEL_PWM
+ depends on ATMEL_PWM
help
This option enables support for LEDs driven using outputs
of the dedicated PWM controller found on newer Atmel SOCs.
config LEDS_LOCOMO
tristate "LED Support for Locomo device"
- depends on LEDS_CLASS && SHARP_LOCOMO
+ depends on SHARP_LOCOMO
help
This option enables support for the LEDs on Sharp Locomo.
Zaurus models SL-5500 and SL-5600.
config LEDS_MIKROTIK_RB532
tristate "LED Support for Mikrotik Routerboard 532"
- depends on LEDS_CLASS && MIKROTIK_RB532
+ depends on MIKROTIK_RB532
help
This option enables support for the so called "User LED" of
Mikrotik's Routerboard 532.
config LEDS_S3C24XX
tristate "LED Support for Samsung S3C24XX GPIO LEDs"
- depends on LEDS_CLASS && ARCH_S3C2410
+ depends on ARCH_S3C2410
help
This option enables support for LEDs connected to GPIO lines
on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
config LEDS_AMS_DELTA
tristate "LED Support for the Amstrad Delta (E3)"
- depends on LEDS_CLASS && MACH_AMS_DELTA
+ depends on MACH_AMS_DELTA
help
This option enables support for the LEDs on Amstrad Delta (E3).
config LEDS_NET48XX
tristate "LED Support for Soekris net48xx series Error LED"
- depends on LEDS_CLASS && SCx200_GPIO
+ depends on SCx200_GPIO
help
This option enables support for the Soekris net4801 and net4826 error
LED.
config LEDS_FSG
tristate "LED Support for the Freecom FSG-3"
- depends on LEDS_CLASS && MACH_FSG
+ depends on MACH_FSG
help
This option enables support for the LEDs on the Freecom FSG-3.
config LEDS_WRAP
tristate "LED Support for the WRAP series LEDs"
- depends on LEDS_CLASS && SCx200_GPIO
+ depends on SCx200_GPIO
help
This option enables support for the PCEngines WRAP programmable LEDs.
config LEDS_ALIX2
tristate "LED Support for ALIX.2 and ALIX.3 series"
- depends on LEDS_CLASS && X86 && EXPERIMENTAL
+ depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
help
This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
You have to set leds-alix2.force=1 for boards with Award BIOS.
config LEDS_H1940
tristate "LED Support for iPAQ H1940 device"
- depends on LEDS_CLASS && ARCH_H1940
+ depends on ARCH_H1940
help
This option enables support for the LEDs on the h1940.
config LEDS_COBALT_QUBE
tristate "LED Support for the Cobalt Qube series front LED"
- depends on LEDS_CLASS && MIPS_COBALT
+ depends on MIPS_COBALT
help
This option enables support for the front LED on Cobalt Qube series
@@ -98,7 +107,7 @@ config LEDS_COBALT_RAQ
config LEDS_SUNFIRE
tristate "LED support for SunFire servers."
- depends on LEDS_CLASS && SPARC64
+ depends on SPARC64
select LEDS_TRIGGERS
help
This option enables support for the Left, Middle, and Right
@@ -106,14 +115,14 @@ config LEDS_SUNFIRE
config LEDS_HP6XX
tristate "LED Support for the HP Jornada 6xx"
- depends on LEDS_CLASS && SH_HP6XX
+ depends on SH_HP6XX
help
This option enables LED support for the handheld
HP Jornada 620/660/680/690.
config LEDS_PCA9532
tristate "LED driver for PCA9532 dimmer"
- depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
+ depends on I2C && INPUT && EXPERIMENTAL
help
This option enables support for NXP pca9532
LED controller. It is generally only useful
@@ -121,7 +130,7 @@ config LEDS_PCA9532
config LEDS_GPIO
tristate "LED Support for GPIO connected LEDs"
- depends on LEDS_CLASS && GENERIC_GPIO
+ depends on GENERIC_GPIO
help
This option enables support for the LEDs connected to GPIO
outputs. To be useful the particular board must have LEDs
@@ -148,7 +157,7 @@ config LEDS_GPIO_OF
config LEDS_LP3944
tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
- depends on LEDS_CLASS && I2C
+ depends on I2C
help
This option enables support for LEDs connected to the National
Semiconductor LP3944 Lighting Management Unit (LMU) also known as
@@ -159,7 +168,7 @@ config LEDS_LP3944
config LEDS_CLEVO_MAIL
tristate "Mail LED on Clevo notebook"
- depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
+ depends on X86 && SERIO_I8042 && DMI
help
This driver makes the mail LED accessible from userspace
programs through the leds subsystem. This LED have three
@@ -189,7 +198,7 @@ config LEDS_CLEVO_MAIL
config LEDS_PCA955X
tristate "LED Support for PCA955x I2C chips"
- depends on LEDS_CLASS && I2C
+ depends on I2C
help
This option enables support for LEDs connected to PCA955x
LED driver chips accessed via the I2C bus. Supported
@@ -197,54 +206,54 @@ config LEDS_PCA955X
config LEDS_WM831X_STATUS
tristate "LED support for status LEDs on WM831x PMICs"
- depends on LEDS_CLASS && MFD_WM831X
+ depends on MFD_WM831X
help
This option enables support for the status LEDs of the WM831x
series of PMICs.
config LEDS_WM8350
tristate "LED Support for WM8350 AudioPlus PMIC"
- depends on LEDS_CLASS && MFD_WM8350
+ depends on MFD_WM8350
help
This option enables support for LEDs driven by the Wolfson
Microelectronics WM8350 AudioPlus PMIC.
config LEDS_DA903X
tristate "LED Support for DA9030/DA9034 PMIC"
- depends on LEDS_CLASS && PMIC_DA903X
+ depends on PMIC_DA903X
help
This option enables support for on-chip LED drivers found
on Dialog Semiconductor DA9030/DA9034 PMICs.
config LEDS_DAC124S085
tristate "LED Support for DAC124S085 SPI DAC"
- depends on LEDS_CLASS && SPI
+ depends on SPI
help
This option enables support for DAC124S085 SPI DAC from NatSemi,
which can be used to control up to four LEDs.
config LEDS_PWM
tristate "PWM driven LED Support"
- depends on LEDS_CLASS && HAVE_PWM
+ depends on HAVE_PWM
help
This option enables support for pwm driven LEDs
config LEDS_REGULATOR
tristate "REGULATOR driven LED support"
- depends on LEDS_CLASS && REGULATOR
+ depends on REGULATOR
help
This option enables support for regulator driven LEDs.
config LEDS_BD2802
tristate "LED driver for BD2802 RGB LED"
- depends on LEDS_CLASS && I2C
+ depends on I2C
help
This option enables support for BD2802GU RGB LED driver chips
accessed via the I2C bus.
config LEDS_INTEL_SS4200
tristate "LED driver for Intel NAS SS4200 series"
- depends on LEDS_CLASS && PCI && DMI
+ depends on PCI && DMI
help
This option enables support for the Intel SS4200 series of
Network Attached Storage servers. You may control the hard
@@ -253,7 +262,7 @@ config LEDS_INTEL_SS4200
config LEDS_LT3593
tristate "LED driver for LT3593 controllers"
- depends on LEDS_CLASS && GENERIC_GPIO
+ depends on GENERIC_GPIO
help
This option enables support for LEDs driven by a Linear Technology
LT3593 controller. This controller uses a special one-wire pulse
@@ -261,7 +270,7 @@ config LEDS_LT3593
config LEDS_ADP5520
tristate "LED Support for ADP5520/ADP5501 PMIC"
- depends on LEDS_CLASS && PMIC_ADP5520
+ depends on PMIC_ADP5520
help
This option enables support for on-chip LED drivers found
on Analog Devices ADP5520/ADP5501 PMICs.
@@ -269,7 +278,12 @@ config LEDS_ADP5520
To compile this driver as a module, choose M here: the module will
be called leds-adp5520.
-comment "LED Triggers"
+config LEDS_DELL_NETBOOKS
+ tristate "External LED on Dell Business Netbooks"
+ depends on X86 && ACPI_WMI
+ help
+ This adds support for the Latitude 2100 and similar
+ notebooks that have an external LED.
config LEDS_TRIGGERS
bool "LED Trigger support"
@@ -278,9 +292,12 @@ config LEDS_TRIGGERS
These triggers allow kernel events to drive the LEDs and can
be configured via sysfs. If unsure, say Y.
+if LEDS_TRIGGERS
+
+comment "LED Triggers"
+
config LEDS_TRIGGER_TIMER
tristate "LED Timer Trigger"
- depends on LEDS_TRIGGERS
help
This allows LEDs to be controlled by a programmable timer
via sysfs. Some LED hardware can be programmed to start
@@ -291,14 +308,13 @@ config LEDS_TRIGGER_TIMER
config LEDS_TRIGGER_IDE_DISK
bool "LED IDE Disk Trigger"
- depends on LEDS_TRIGGERS && IDE_GD_ATA
+ depends on IDE_GD_ATA
help
This allows LEDs to be controlled by IDE disk activity.
If unsure, say Y.
config LEDS_TRIGGER_HEARTBEAT
tristate "LED Heartbeat Trigger"
- depends on LEDS_TRIGGERS
help
This allows LEDs to be controlled by a CPU load average.
The flash frequency is a hyperbolic function of the 1-minute
@@ -307,7 +323,6 @@ config LEDS_TRIGGER_HEARTBEAT
config LEDS_TRIGGER_BACKLIGHT
tristate "LED backlight Trigger"
- depends on LEDS_TRIGGERS
help
This allows LEDs to be controlled as a backlight device: they
turn off and on when the display is blanked and unblanked.
@@ -316,7 +331,6 @@ config LEDS_TRIGGER_BACKLIGHT
config LEDS_TRIGGER_GPIO
tristate "LED GPIO Trigger"
- depends on LEDS_TRIGGERS
depends on GPIOLIB
help
This allows LEDs to be controlled by gpio events. It's good
@@ -329,7 +343,6 @@ config LEDS_TRIGGER_GPIO
config LEDS_TRIGGER_DEFAULT_ON
tristate "LED Default ON Trigger"
- depends on LEDS_TRIGGERS
help
This allows LEDs to be initialised in the ON state.
If unsure, say Y.
@@ -337,4 +350,8 @@ config LEDS_TRIGGER_DEFAULT_ON
comment "iptables trigger is under Netfilter config (LED target)"
depends on LEDS_TRIGGERS
+endif # LEDS_TRIGGERS
+
+endif # LEDS_CLASS
+
endif # NEW_LEDS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 9e63869d7c0..0cd8b995738 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_LEDS_CLASS) += led-class.o
obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
# LED Platform Drivers
+obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
@@ -33,6 +34,7 @@ obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o
obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o
obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o
+obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o
# LED SPI Drivers
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
diff --git a/drivers/leds/dell-led.c b/drivers/leds/dell-led.c
new file mode 100644
index 00000000000..52590296af3
--- /dev/null
+++ b/drivers/leds/dell-led.c
@@ -0,0 +1,201 @@
+/*
+ * dell_led.c - Dell LED Driver
+ *
+ * Copyright (C) 2010 Dell Inc.
+ * Louis Davis <louis_davis@dell.com>
+ * Jim Dailey <jim_dailey@dell.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.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+MODULE_AUTHOR("Louis Davis/Jim Dailey");
+MODULE_DESCRIPTION("Dell LED Control Driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396"
+MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);
+
+/* Error Result Codes: */
+#define INVALID_DEVICE_ID 250
+#define INVALID_PARAMETER 251
+#define INVALID_BUFFER 252
+#define INTERFACE_ERROR 253
+#define UNSUPPORTED_COMMAND 254
+#define UNSPECIFIED_ERROR 255
+
+/* Device ID */
+#define DEVICE_ID_PANEL_BACK 1
+
+/* LED Commands */
+#define CMD_LED_ON 16
+#define CMD_LED_OFF 17
+#define CMD_LED_BLINK 18
+
+struct bios_args {
+ unsigned char length;
+ unsigned char result_code;
+ unsigned char device_id;
+ unsigned char command;
+ unsigned char on_time;
+ unsigned char off_time;
+};
+
+static int dell_led_perform_fn(u8 length,
+ u8 result_code,
+ u8 device_id,
+ u8 command,
+ u8 on_time,
+ u8 off_time)
+{
+ struct bios_args *bios_return;
+ u8 return_code;
+ union acpi_object *obj;
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer input;
+ acpi_status status;
+
+ struct bios_args args;
+ args.length = length;
+ args.result_code = result_code;
+ args.device_id = device_id;
+ args.command = command;
+ args.on_time = on_time;
+ args.off_time = off_time;
+
+ input.length = sizeof(struct bios_args);
+ input.pointer = &args;
+
+ status = wmi_evaluate_method(DELL_LED_BIOS_GUID,
+ 1,
+ 1,
+ &input,
+ &output);
+
+ if (ACPI_FAILURE(status))
+ return status;
+
+ obj = output.pointer;
+
+ if (!obj)
+ return -EINVAL;
+ else if (obj->type != ACPI_TYPE_BUFFER) {
+ kfree(obj);
+ return -EINVAL;
+ }
+
+ bios_return = ((struct bios_args *)obj->buffer.pointer);
+ return_code = bios_return->result_code;
+
+ kfree(obj);
+
+ return return_code;
+}
+
+static int led_on(void)
+{
+ return dell_led_perform_fn(3, /* Length of command */
+ INTERFACE_ERROR, /* Init to INTERFACE_ERROR */
+ DEVICE_ID_PANEL_BACK, /* Device ID */
+ CMD_LED_ON, /* Command */
+ 0, /* not used */
+ 0); /* not used */
+}
+
+static int led_off(void)
+{
+ return dell_led_perform_fn(3, /* Length of command */
+ INTERFACE_ERROR, /* Init to INTERFACE_ERROR */
+ DEVICE_ID_PANEL_BACK, /* Device ID */
+ CMD_LED_OFF, /* Command */
+ 0, /* not used */
+ 0); /* not used */
+}
+
+static int led_blink(unsigned char on_eighths,
+ unsigned char off_eighths)
+{
+ return dell_led_perform_fn(5, /* Length of command */
+ INTERFACE_ERROR, /* Init to INTERFACE_ERROR */
+ DEVICE_ID_PANEL_BACK, /* Device ID */
+ CMD_LED_BLINK, /* Command */
+ on_eighths, /* blink on in eigths of a second */
+ off_eighths); /* blink off in eights of a second */
+}
+
+static void dell_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value == LED_OFF)
+ led_off();
+ else
+ led_on();
+}
+
+static int dell_led_blink(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ unsigned long on_eighths;
+ unsigned long off_eighths;
+
+ /* The Dell LED delay is based on 125ms intervals.
+ Need to round up to next interval. */
+
+ on_eighths = (*delay_on + 124) / 125;
+ if (0 == on_eighths)
+ on_eighths = 1;
+ if (on_eighths > 255)
+ on_eighths = 255;
+ *delay_on = on_eighths * 125;
+
+ off_eighths = (*delay_off + 124) / 125;
+ if (0 == off_eighths)
+ off_eighths = 1;
+ if (off_eighths > 255)
+ off_eighths = 255;
+ *delay_off = off_eighths * 125;
+
+ led_blink(on_eighths, off_eighths);
+
+ return 0;
+}
+
+static struct led_classdev dell_led = {
+ .name = "dell::lid",
+ .brightness = LED_OFF,
+ .max_brightness = 1,
+ .brightness_set = dell_led_set,
+ .blink_set = dell_led_blink,
+ .flags = LED_CORE_SUSPENDRESUME,
+};
+
+static int __init dell_led_init(void)
+{
+ int error = 0;
+
+ if (!wmi_has_guid(DELL_LED_BIOS_GUID))
+ return -ENODEV;
+
+ error = led_off();
+ if (error != 0)
+ return -ENODEV;
+
+ return led_classdev_register(NULL, &dell_led);
+}
+
+static void __exit dell_led_exit(void)
+{
+ led_classdev_unregister(&dell_led);
+
+ led_off();
+}
+
+module_init(dell_led_init);
+module_exit(dell_led_exit);
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 782f95822ea..69e7d86a514 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -72,11 +72,14 @@ static ssize_t led_max_brightness_show(struct device *dev,
return sprintf(buf, "%u\n", led_cdev->max_brightness);
}
-static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
-static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
+static struct device_attribute led_class_attrs[] = {
+ __ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
+ __ATTR(max_brightness, 0644, led_max_brightness_show, NULL),
#ifdef CONFIG_LEDS_TRIGGERS
-static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
+ __ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
#endif
+ __ATTR_NULL,
+};
/**
* led_classdev_suspend - suspend an led_classdev.
@@ -127,18 +130,11 @@ static int led_resume(struct device *dev)
*/
int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
{
- int rc;
-
led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
"%s", led_cdev->name);
if (IS_ERR(led_cdev->dev))
return PTR_ERR(led_cdev->dev);
- /* register the attributes */
- rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
- if (rc)
- goto err_out;
-
#ifdef CONFIG_LEDS_TRIGGERS
init_rwsem(&led_cdev->trigger_lock);
#endif
@@ -150,36 +146,18 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
if (!led_cdev->max_brightness)
led_cdev->max_brightness = LED_FULL;
- rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
- if (rc)
- goto err_out_attr_max;
-
led_update_brightness(led_cdev);
#ifdef CONFIG_LEDS_TRIGGERS
- rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
- if (rc)
- goto err_out_led_list;
-
led_trigger_set_default(led_cdev);
#endif
- printk(KERN_INFO "Registered led device: %s\n",
+ printk(KERN_DEBUG "Registered led device: %s\n",
led_cdev->name);
return 0;
-
-#ifdef CONFIG_LEDS_TRIGGERS
-err_out_led_list:
- device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
-#endif
-err_out_attr_max:
- device_remove_file(led_cdev->dev, &dev_attr_brightness);
- list_del(&led_cdev->node);
-err_out:
- device_unregister(led_cdev->dev);
- return rc;
}
+
EXPORT_SYMBOL_GPL(led_classdev_register);
/**
@@ -190,10 +168,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
*/
void led_classdev_unregister(struct led_classdev *led_cdev)
{
- device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
- device_remove_file(led_cdev->dev, &dev_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS
- device_remove_file(led_cdev->dev, &dev_attr_trigger);
down_write(&led_cdev->trigger_lock);
if (led_cdev->trigger)
led_trigger_set(led_cdev, NULL);
@@ -215,6 +190,7 @@ static int __init leds_init(void)
return PTR_ERR(leds_class);
leds_class->suspend = led_suspend;
leds_class->resume = led_resume;
+ leds_class->dev_attrs = led_class_attrs;
return 0;
}
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index d8ddd9ef899..f1c00db88b5 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -21,6 +21,7 @@
#include <linux/timer.h>
#include <linux/rwsem.h>
#include <linux/leds.h>
+#include <linux/slab.h>
#include "leds.h"
/*
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
new file mode 100644
index 00000000000..16a60c06c96
--- /dev/null
+++ b/drivers/leds/leds-88pm860x.c
@@ -0,0 +1,326 @@
+/*
+ * LED driver for Marvell 88PM860x
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/mfd/88pm860x.h>
+
+#define LED_PWM_SHIFT (3)
+#define LED_PWM_MASK (0x1F)
+#define LED_CURRENT_MASK (0x07 << 5)
+
+#define LED_BLINK_ON_MASK (0x07)
+#define LED_BLINK_PERIOD_MASK (0x0F << 3)
+#define LED_BLINK_MASK (0x7F)
+
+#define LED_BLINK_ON(x) ((x & 0x7) * 66 + 66)
+#define LED_BLINK_PERIOD(x) ((x & 0xF) * 530 + 930)
+#define LED_BLINK_ON_MIN LED_BLINK_ON(0)
+#define LED_BLINK_ON_MAX LED_BLINK_ON(0x7)
+#define LED_BLINK_PERIOD_MIN LED_BLINK_PERIOD(0)
+#define LED_BLINK_PERIOD_MAX LED_BLINK_PERIOD(0xE)
+#define LED_TO_ON(x) ((x - 66) / 66)
+#define LED_TO_PERIOD(x) ((x - 930) / 530)
+
+#define LED1_BLINK_EN (1 << 1)
+#define LED2_BLINK_EN (1 << 2)
+
+enum {
+ SET_BRIGHTNESS,
+ SET_BLINK,
+};
+
+struct pm860x_led {
+ struct led_classdev cdev;
+ struct i2c_client *i2c;
+ struct work_struct work;
+ struct pm860x_chip *chip;
+ struct mutex lock;
+ char name[MFD_NAME_SIZE];
+
+ int port;
+ int iset;
+ int command;
+ int offset;
+ unsigned char brightness;
+ unsigned char current_brightness;
+
+ int blink_data;
+ int blink_time;
+ int blink_on;
+ int blink_off;
+};
+
+/* return offset of color register */
+static inline int __led_off(int port)
+{
+ int ret = -EINVAL;
+
+ switch (port) {
+ case PM8606_LED1_RED:
+ case PM8606_LED1_GREEN:
+ case PM8606_LED1_BLUE:
+ ret = port - PM8606_LED1_RED + PM8606_RGB1B;
+ break;
+ case PM8606_LED2_RED:
+ case PM8606_LED2_GREEN:
+ case PM8606_LED2_BLUE:
+ ret = port - PM8606_LED2_RED + PM8606_RGB2B;
+ break;
+ }
+ return ret;
+}
+
+/* return offset of blink register */
+static inline int __blink_off(int port)
+{
+ int ret = -EINVAL;
+
+ switch (port) {
+ case PM8606_LED1_RED:
+ case PM8606_LED1_GREEN:
+ case PM8606_LED1_BLUE:
+ ret = PM8606_RGB1A;
+ case PM8606_LED2_RED:
+ case PM8606_LED2_GREEN:
+ case PM8606_LED2_BLUE:
+ ret = PM8606_RGB2A;
+ }
+ return ret;
+}
+
+static inline int __blink_ctl_mask(int port)
+{
+ int ret = -EINVAL;
+
+ switch (port) {
+ case PM8606_LED1_RED:
+ case PM8606_LED1_GREEN:
+ case PM8606_LED1_BLUE:
+ ret = LED1_BLINK_EN;
+ break;
+ case PM8606_LED2_RED:
+ case PM8606_LED2_GREEN:
+ case PM8606_LED2_BLUE:
+ ret = LED2_BLINK_EN;
+ break;
+ }
+ return ret;
+}
+
+static int __led_set(struct pm860x_led *led, int command)
+{
+ struct pm860x_chip *chip = led->chip;
+ int mask, ret;
+
+ mutex_lock(&led->lock);
+ switch (command) {
+ case SET_BRIGHTNESS:
+ if ((led->current_brightness == 0) && led->brightness) {
+ if (led->iset) {
+ ret = pm860x_set_bits(led->i2c, led->offset,
+ LED_CURRENT_MASK, led->iset);
+ if (ret < 0)
+ goto out;
+ }
+ } else if (led->brightness == 0) {
+ ret = pm860x_set_bits(led->i2c, led->offset,
+ LED_CURRENT_MASK, 0);
+ if (ret < 0)
+ goto out;
+ }
+ ret = pm860x_set_bits(led->i2c, led->offset, LED_PWM_MASK,
+ led->brightness);
+ if (ret < 0)
+ goto out;
+ led->current_brightness = led->brightness;
+ dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
+ led->offset, led->brightness);
+ break;
+ case SET_BLINK:
+ ret = pm860x_set_bits(led->i2c, led->offset,
+ LED_BLINK_MASK, led->blink_data);
+ if (ret < 0)
+ goto out;
+
+ mask = __blink_ctl_mask(led->port);
+ ret = pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
+ if (ret < 0)
+ goto out;
+ dev_dbg(chip->dev, "LED blink delay on:%dms, delay off:%dms\n",
+ led->blink_on, led->blink_off);
+ break;
+ }
+out:
+ mutex_unlock(&led->lock);
+ return 0;
+}
+
+static void pm860x_led_work(struct work_struct *work)
+{
+ struct pm860x_led *led;
+
+ led = container_of(work, struct pm860x_led, work);
+ __led_set(led, led->command);
+}
+
+static void pm860x_led_set(struct led_classdev *cdev,
+ enum led_brightness value)
+{
+ struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev);
+
+ data->offset = __led_off(data->port);
+ data->brightness = value >> 3;
+ data->command = SET_BRIGHTNESS;
+ schedule_work(&data->work);
+}
+
+static int pm860x_led_blink(struct led_classdev *cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev);
+ int period, on;
+
+ on = *delay_on;
+ if ((on < LED_BLINK_ON_MIN) || (on > LED_BLINK_ON_MAX))
+ return -EINVAL;
+
+ on = LED_TO_ON(on);
+ on = LED_BLINK_ON(on);
+
+ period = on + *delay_off;
+ if ((period < LED_BLINK_PERIOD_MIN) || (period > LED_BLINK_PERIOD_MAX))
+ return -EINVAL;
+ period = LED_TO_PERIOD(period);
+ period = LED_BLINK_PERIOD(period);
+
+ data->offset = __blink_off(data->port);
+ data->blink_on = on;
+ data->blink_off = period - data->blink_on;
+ data->blink_data = (period << 3) | data->blink_on;
+ data->command = SET_BLINK;
+ schedule_work(&data->work);
+
+ return 0;
+}
+
+static int __check_device(struct pm860x_led_pdata *pdata, char *name)
+{
+ struct pm860x_led_pdata *p = pdata;
+ int ret = -EINVAL;
+
+ while (p && p->id) {
+ if ((p->id != PM8606_ID_LED) || (p->flags < 0))
+ break;
+
+ if (!strncmp(name, pm860x_led_name[p->flags],
+ MFD_NAME_SIZE)) {
+ ret = (int)p->flags;
+ break;
+ }
+ p++;
+ }
+ return ret;
+}
+
+static int pm860x_led_probe(struct platform_device *pdev)
+{
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pm860x_platform_data *pm860x_pdata;
+ struct pm860x_led_pdata *pdata;
+ struct pm860x_led *data;
+ struct resource *res;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "No I/O resource!\n");
+ return -EINVAL;
+ }
+
+ if (pdev->dev.parent->platform_data) {
+ pm860x_pdata = pdev->dev.parent->platform_data;
+ pdata = pm860x_pdata->led;
+ } else
+ pdata = NULL;
+
+ data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+ strncpy(data->name, res->name, MFD_NAME_SIZE);
+ dev_set_drvdata(&pdev->dev, data);
+ data->chip = chip;
+ data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
+ data->iset = pdata->iset;
+ data->port = __check_device(pdata, data->name);
+ if (data->port < 0)
+ return -EINVAL;
+
+ data->current_brightness = 0;
+ data->cdev.name = data->name;
+ data->cdev.brightness_set = pm860x_led_set;
+ data->cdev.blink_set = pm860x_led_blink;
+ mutex_init(&data->lock);
+ INIT_WORK(&data->work, pm860x_led_work);
+
+ ret = led_classdev_register(chip->dev, &data->cdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
+ goto out;
+ }
+ return 0;
+out:
+ kfree(data);
+ return ret;
+}
+
+static int pm860x_led_remove(struct platform_device *pdev)
+{
+ struct pm860x_led *data = platform_get_drvdata(pdev);
+
+ led_classdev_unregister(&data->cdev);
+ kfree(data);
+
+ return 0;
+}
+
+static struct platform_driver pm860x_led_driver = {
+ .driver = {
+ .name = "88pm860x-led",
+ .owner = THIS_MODULE,
+ },
+ .probe = pm860x_led_probe,
+ .remove = pm860x_led_remove,
+};
+
+static int __devinit pm860x_led_init(void)
+{
+ return platform_driver_register(&pm860x_led_driver);
+}
+module_init(pm860x_led_init);
+
+static void __devexit pm860x_led_exit(void)
+{
+ platform_driver_unregister(&pm860x_led_driver);
+}
+module_exit(pm860x_led_exit);
+
+MODULE_DESCRIPTION("LED driver for Marvell PM860x");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:88pm860x-led");
diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c
index a8f31590213..7ba4c7b5b97 100644
--- a/drivers/leds/leds-adp5520.c
+++ b/drivers/leds/leds-adp5520.c
@@ -20,6 +20,7 @@
#include <linux/leds.h>
#include <linux/workqueue.h>
#include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
struct adp5520_led {
struct led_classdev cdev;
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 52297c3ab24..c941d906bba 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -3,6 +3,7 @@
#include <linux/leds.h>
#include <linux/io.h>
#include <linux/atmel_pwm.h>
+#include <linux/slab.h>
struct pwmled {
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 779d7f262c0..286b501a357 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/leds.h>
#include <linux/leds-bd2802.h>
+#include <linux/slab.h>
#define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c
index 1f3cc512eff..f28931cf678 100644
--- a/drivers/leds/leds-da903x.c
+++ b/drivers/leds/leds-da903x.c
@@ -19,6 +19,7 @@
#include <linux/leds.h>
#include <linux/workqueue.h>
#include <linux/mfd/da903x.h>
+#include <linux/slab.h>
#define DA9030_LED1_CONTROL 0x20
#define DA9030_LED2_CONTROL 0x21
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
index 2913d76ad3d..31cf0d60a9a 100644
--- a/drivers/leds/leds-dac124s085.c
+++ b/drivers/leds/leds-dac124s085.c
@@ -9,7 +9,6 @@
* LED driver for the DAC124S085 SPI DAC
*/
-#include <linux/gfp.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/mutex.h>
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index e5225d28f39..c6e4b772b75 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <asm/gpio.h>
@@ -211,7 +212,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
struct device_node *np = ofdev->node, *child;
- struct gpio_led led;
struct gpio_led_of_platform_data *pdata;
int count = 0, ret;
@@ -226,8 +226,8 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
if (!pdata)
return -ENOMEM;
- memset(&led, 0, sizeof(led));
for_each_child_of_node(np, child) {
+ struct gpio_led led = {};
enum of_gpio_flags flags;
const char *state;
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c
index 5946208ba26..8d5ecceba18 100644
--- a/drivers/leds/leds-lp3944.c
+++ b/drivers/leds/leds-lp3944.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/leds.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index fee40a84195..2579678f97a 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -23,6 +23,7 @@
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
struct lt3593_led_data {
struct led_classdev cdev;
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index adc561eb59d..6682175fa9f 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/leds.h>
#include <linux/input.h>
#include <linux/mutex.h>
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index 4e2d1a42b48..8ff50f23419 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -48,6 +48,7 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
/* LED select registers determine the source that drives LED outputs */
#define PCA955X_LS_LED_ON 0x0 /* Output LOW */
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 88b1dd091cf..da3fa8dcdf5 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -21,6 +21,7 @@
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/leds_pwm.h>
+#include <linux/slab.h>
struct led_pwm_data {
struct led_classdev cdev;
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c
index 7f00de3ef92..3790816643b 100644
--- a/drivers/leds/leds-regulator.c
+++ b/drivers/leds/leds-regulator.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/leds.h>
#include <linux/leds-regulator.h>
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index aa7acf3b922..a77771dc2e9 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index 97f04984c1c..51477ec7139 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -63,7 +63,7 @@ MODULE_LICENSE("GPL");
/*
* PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
*/
-static struct pci_device_id ich7_lpc_pci_id[] =
+static const struct pci_device_id ich7_lpc_pci_id[] =
{
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },
diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c
index 6b008f0c3f6..ab6d18f5c39 100644
--- a/drivers/leds/leds-sunfire.c
+++ b/drivers/leds/leds-sunfire.c
@@ -9,6 +9,7 @@
#include <linux/leds.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/fhc.h>
#include <asm/upa.h>
diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c
index c586d05e336..ef5c24140a4 100644
--- a/drivers/leds/leds-wm831x-status.c
+++ b/drivers/leds/leds-wm831x-status.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/leds.h>
#include <linux/err.h>
#include <linux/mfd/wm831x/core.h>
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
index 38c6bcb07e6..5aab32ce4f4 100644
--- a/drivers/leds/leds-wm8350.c
+++ b/drivers/leds/leds-wm8350.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/mfd/wm8350/pmic.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
/* Microamps */
static const int isink_cur[] = {
diff --git a/drivers/leds/ledtrig-backlight.c b/drivers/leds/ledtrig-backlight.c
index d3dfcfb417b..f948e57bd9b 100644
--- a/drivers/leds/ledtrig-backlight.c
+++ b/drivers/leds/ledtrig-backlight.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fb.h>
#include <linux/leds.h>
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c
index f5913372d69..991d93be0f4 100644
--- a/drivers/leds/ledtrig-gpio.c
+++ b/drivers/leds/ledtrig-gpio.c
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/leds.h>
+#include <linux/slab.h>
#include "leds.h"
struct gpio_trig_data {
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c
index c1c1ea6f817..759c0bba4a8 100644
--- a/drivers/leds/ledtrig-heartbeat.c
+++ b/drivers/leds/ledtrig-heartbeat.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/leds.h>
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 38b3378be44..82b77bd482f 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -22,6 +22,7 @@
#include <linux/timer.h>
#include <linux/ctype.h>
#include <linux/leds.h>
+#include <linux/slab.h>
#include "leds.h"
struct timer_trig_data {
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 8744d24ac6e..efa202499e3 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -12,6 +12,7 @@
#include <linux/cpu.h>
#include <linux/freezer.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <asm/paravirt.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index bc28745d05a..9136411fadd 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -10,6 +10,7 @@
#include <linux/wait.h>
#include <linux/hrtimer.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <asm/lguest.h>
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index b6200bc39b5..69c84a1d88e 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/virtio_ring.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/paravirt.h>
#include <asm/lguest_hcall.h>
@@ -177,7 +178,7 @@ static void set_status(struct virtio_device *vdev, u8 status)
/* We set the status. */
to_lgdev(vdev)->desc->status = status;
- kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset);
+ hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0);
}
static void lg_set_status(struct virtio_device *vdev, u8 status)
@@ -228,7 +229,7 @@ static void lg_notify(struct virtqueue *vq)
*/
struct lguest_vq_info *lvq = vq->priv;
- kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT);
+ hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0);
}
/* An extern declaration inside a C file is bad form. Don't do it. */
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index bd1632388e4..85b714df8ea 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -10,6 +10,7 @@
#include <linux/sched.h>
#include <linux/eventfd.h>
#include <linux/file.h>
+#include <linux/slab.h>
#include "lg.h"
/*L:056
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index cf94326f1b5..04b22128a47 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -10,6 +10,7 @@
/* Copyright (C) Rusty Russell IBM Corporation 2006.
* GPL v2 and any later version */
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/random.h>
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index fb2b7ef7868..b4eb675a807 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -288,6 +288,18 @@ static int emulate_insn(struct lg_cpu *cpu)
insn = lgread(cpu, physaddr, u8);
/*
+ * Around 2.6.33, the kernel started using an emulation for the
+ * cmpxchg8b instruction in early boot on many configurations. This
+ * code isn't paravirtualized, and it tries to disable interrupts.
+ * Ignore it, which will Mostly Work.
+ */
+ if (insn == 0xfa) {
+ /* "cli", or Clear Interrupt Enable instruction. Skip it. */
+ cpu->regs->eip++;
+ return 1;
+ }
+
+ /*
* 0x66 is an "operand prefix". It means it's using the upper 16 bits
* of the eax register.
*/
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index e943d2a2925..067f9962f49 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -13,6 +13,7 @@
#include <linux/sysctl.h>
#include <linux/input.h>
#include <linux/module.h>
+#include <linux/slab.h>
MODULE_LICENSE("GPL");
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c
index 93fb32038b1..7c54d80c4fb 100644
--- a/drivers/macintosh/rack-meter.c
+++ b/drivers/macintosh/rack-meter.c
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/module.h>
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index f96feeb6b9c..888448cf7f1 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -38,6 +38,7 @@
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/io.h>
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 5738d8bf2d9..b18fa948f3d 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -114,7 +114,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
@@ -948,10 +947,16 @@ static void do_monitor_cpu_combined(void)
printk(KERN_WARNING "Warning ! Temperature way above maximum (%d) !\n",
temp_combi >> 16);
state0->overtemp += CPU_MAX_OVERTEMP / 4;
- } else if (temp_combi > (state0->mpu.tmax << 16))
+ } else if (temp_combi > (state0->mpu.tmax << 16)) {
state0->overtemp++;
- else
+ printk(KERN_WARNING "Temperature %d above max %d. overtemp %d\n",
+ temp_combi >> 16, state0->mpu.tmax, state0->overtemp);
+ } else {
+ if (state0->overtemp)
+ printk(KERN_WARNING "Temperature back down to %d\n",
+ temp_combi >> 16);
state0->overtemp = 0;
+ }
if (state0->overtemp >= CPU_MAX_OVERTEMP)
critical_state = 1;
if (state0->overtemp > 0) {
@@ -1023,10 +1028,16 @@ static void do_monitor_cpu_split(struct cpu_pid_state *state)
" (%d) !\n",
state->index, temp >> 16);
state->overtemp += CPU_MAX_OVERTEMP / 4;
- } else if (temp > (state->mpu.tmax << 16))
+ } else if (temp > (state->mpu.tmax << 16)) {
state->overtemp++;
- else
+ printk(KERN_WARNING "CPU %d temperature %d above max %d. overtemp %d\n",
+ state->index, temp >> 16, state->mpu.tmax, state->overtemp);
+ } else {
+ if (state->overtemp)
+ printk(KERN_WARNING "CPU %d temperature back down to %d\n",
+ state->index, temp >> 16);
state->overtemp = 0;
+ }
if (state->overtemp >= CPU_MAX_OVERTEMP)
critical_state = 1;
if (state->overtemp > 0) {
@@ -1085,10 +1096,16 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state)
" (%d) !\n",
state->index, temp >> 16);
state->overtemp = CPU_MAX_OVERTEMP / 4;
- } else if (temp > (state->mpu.tmax << 16))
+ } else if (temp > (state->mpu.tmax << 16)) {
state->overtemp++;
- else
+ printk(KERN_WARNING "CPU %d temperature %d above max %d. overtemp %d\n",
+ state->index, temp >> 16, state->mpu.tmax, state->overtemp);
+ } else {
+ if (state->overtemp)
+ printk(KERN_WARNING "CPU %d temperature back down to %d\n",
+ state->index, temp >> 16);
state->overtemp = 0;
+ }
if (state->overtemp >= CPU_MAX_OVERTEMP)
critical_state = 1;
if (state->overtemp > 0) {
diff --git a/drivers/macintosh/therm_pm72.h b/drivers/macintosh/therm_pm72.h
index 393cc9df94e..df3680e2a22 100644
--- a/drivers/macintosh/therm_pm72.h
+++ b/drivers/macintosh/therm_pm72.h
@@ -269,7 +269,7 @@ struct slots_pid_state
#define CPU_TEMP_HISTORY_SIZE 2
#define CPU_POWER_HISTORY_SIZE 10
#define CPU_PID_INTERVAL 1
-#define CPU_MAX_OVERTEMP 30
+#define CPU_MAX_OVERTEMP 90
#define CPUA_PUMP_RPM_INDEX 7
#define CPUB_PUMP_RPM_INDEX 8
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 7fb8b4da35a..0839770e4ec 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -34,7 +34,6 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/i2c.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/of_platform.h>
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index 4f3c4479c16..1cec02f6c43 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -144,6 +144,7 @@ void pmu_backlight_set_sleep(int sleep)
void __init pmu_backlight_init()
{
+ struct backlight_properties props;
struct backlight_device *bd;
char name[10];
int level, autosave;
@@ -161,13 +162,15 @@ void __init pmu_backlight_init()
snprintf(name, sizeof(name), "pmubl");
- bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+ bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data,
+ &props);
if (IS_ERR(bd)) {
printk(KERN_ERR "PMU Backlight registration failed\n");
return;
}
uses_pmu_bl = 1;
- bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
level = bd->props.max_brightness;
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index fb9fa614a0e..aeb30d07d5a 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -25,7 +25,6 @@
#include <linux/miscdevice.h>
#include <linux/blkdev.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 437f55c5d18..ce8897933a8 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -25,6 +25,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/kthread.h>
@@ -209,6 +210,7 @@ int wf_register_control(struct wf_control *new_ct)
kref_init(&new_ct->ref);
list_add(&new_ct->link, &wf_controls);
+ sysfs_attr_init(&new_ct->attr.attr);
new_ct->attr.attr.name = new_ct->name;
new_ct->attr.attr.mode = 0644;
new_ct->attr.show = wf_show_control;
@@ -321,6 +323,7 @@ int wf_register_sensor(struct wf_sensor *new_sr)
kref_init(&new_sr->ref);
list_add(&new_sr->link, &wf_sensors);
+ sysfs_attr_init(&new_sr->attr.attr);
new_sr->attr.attr.name = new_sr->name;
new_sr->attr.attr.mode = 0444;
new_sr->attr.show = wf_show_sensor;
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index 6c68b9e5f5c..43137b421f9 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -173,6 +173,7 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
fct->fan_type = pwm_fan;
fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN;
+ sysfs_attr_init(&fct->ctrl.attr.attr);
/* We use the name & location here the same way we do for SMU sensors,
* see the comment in windfarm_smu_sensors.c. The locations are a bit
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index a93637223c8..3bdbb611570 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1160,8 +1160,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
cc->start = tmpll;
- if (dm_get_device(ti, argv[3], cc->start, ti->len,
- dm_table_get_mode(ti->table), &cc->dev)) {
+ if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), &cc->dev)) {
ti->error = "Device lookup failed";
goto bad_device;
}
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index ebe7381f47c..852052880d7 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -156,8 +156,8 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad;
}
- if (dm_get_device(ti, argv[0], dc->start_read, ti->len,
- dm_table_get_mode(ti->table), &dc->dev_read)) {
+ if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
+ &dc->dev_read)) {
ti->error = "Device lookup failed";
goto bad;
}
@@ -177,8 +177,8 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad_dev_read;
}
- if (dm_get_device(ti, argv[3], dc->start_write, ti->len,
- dm_table_get_mode(ti->table), &dc->dev_write)) {
+ if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table),
+ &dc->dev_write)) {
ti->error = "Write device lookup failed";
goto bad_dev_read;
}
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 1d669322b27..d7500e1c26f 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -285,7 +285,8 @@ retry:
up_write(&_hash_lock);
}
-static int dm_hash_rename(uint32_t cookie, const char *old, const char *new)
+static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
+ const char *new)
{
char *new_name, *old_name;
struct hash_cell *hc;
@@ -344,7 +345,8 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new)
dm_table_put(table);
}
- dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie);
+ if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie))
+ *flags |= DM_UEVENT_GENERATED_FLAG;
dm_put(hc->md);
up_write(&_hash_lock);
@@ -736,10 +738,10 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size)
__hash_remove(hc);
up_write(&_hash_lock);
- dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr);
+ if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr))
+ param->flags |= DM_UEVENT_GENERATED_FLAG;
dm_put(md);
- param->data_size = 0;
return 0;
}
@@ -773,7 +775,9 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
return r;
param->data_size = 0;
- return dm_hash_rename(param->event_nr, param->name, new_name);
+
+ return dm_hash_rename(param->event_nr, &param->flags, param->name,
+ new_name);
}
static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
@@ -897,16 +901,17 @@ static int do_resume(struct dm_ioctl *param)
set_disk_ro(dm_disk(md), 1);
}
- if (dm_suspended_md(md))
+ if (dm_suspended_md(md)) {
r = dm_resume(md);
+ if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr))
+ param->flags |= DM_UEVENT_GENERATED_FLAG;
+ }
if (old_map)
dm_table_destroy(old_map);
- if (!r) {
- dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr);
+ if (!r)
r = __dev_status(md, param);
- }
dm_put(md);
return r;
@@ -1476,6 +1481,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
{
/* Always clear this flag */
param->flags &= ~DM_BUFFER_FULL_FLAG;
+ param->flags &= ~DM_UEVENT_GENERATED_FLAG;
/* Ignores parameters */
if (cmd == DM_REMOVE_ALL_CMD ||
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 82f7d6e6b1e..9200dbf2391 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -47,8 +47,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
lc->start = tmp;
- if (dm_get_device(ti, argv[0], lc->start, ti->len,
- dm_table_get_mode(ti->table), &lc->dev)) {
+ if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &lc->dev)) {
ti->error = "dm-linear: Device lookup failed";
goto bad;
}
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index 7ac2c1450d1..1ed0094f064 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -5,6 +5,7 @@
*/
#include <linux/bio.h>
+#include <linux/slab.h>
#include <linux/dm-dirty-log.h>
#include <linux/device-mapper.h>
#include <linux/dm-log-userspace.h>
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
index f1c8cae70b4..075cbcf8a9f 100644
--- a/drivers/md/dm-log-userspace-transfer.c
+++ b/drivers/md/dm-log-userspace-transfer.c
@@ -6,6 +6,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/workqueue.h>
#include <linux/connector.h>
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 7035582786f..5a08be0222d 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -543,8 +543,7 @@ static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
return -EINVAL;
}
- r = dm_get_device(ti, argv[0], 0, 0 /* FIXME */,
- FMODE_READ | FMODE_WRITE, &dev);
+ r = dm_get_device(ti, argv[0], FMODE_READ | FMODE_WRITE, &dev);
if (r)
return r;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index e81345a1d08..826bce7343b 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -69,6 +69,7 @@ struct multipath {
struct list_head priority_groups;
unsigned pg_init_required; /* pg_init needs calling? */
unsigned pg_init_in_progress; /* Only one pg_init allowed at once */
+ wait_queue_head_t pg_init_wait; /* Wait for pg_init completion */
unsigned nr_valid_paths; /* Total number of usable paths */
struct pgpath *current_pgpath;
@@ -95,8 +96,6 @@ struct multipath {
mempool_t *mpio_pool;
struct mutex work_mutex;
-
- unsigned suspended; /* Don't create new I/O internally when set. */
};
/*
@@ -202,6 +201,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti)
m->queue_io = 1;
INIT_WORK(&m->process_queued_ios, process_queued_ios);
INIT_WORK(&m->trigger_event, trigger_event);
+ init_waitqueue_head(&m->pg_init_wait);
mutex_init(&m->work_mutex);
m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
if (!m->mpio_pool) {
@@ -235,6 +235,21 @@ static void free_multipath(struct multipath *m)
* Path selection
*-----------------------------------------------*/
+static void __pg_init_all_paths(struct multipath *m)
+{
+ struct pgpath *pgpath;
+
+ m->pg_init_count++;
+ m->pg_init_required = 0;
+ list_for_each_entry(pgpath, &m->current_pg->pgpaths, list) {
+ /* Skip failed paths */
+ if (!pgpath->is_active)
+ continue;
+ if (queue_work(kmpath_handlerd, &pgpath->activate_path))
+ m->pg_init_in_progress++;
+ }
+}
+
static void __switch_pg(struct multipath *m, struct pgpath *pgpath)
{
m->current_pg = pgpath->pg;
@@ -439,7 +454,7 @@ static void process_queued_ios(struct work_struct *work)
{
struct multipath *m =
container_of(work, struct multipath, process_queued_ios);
- struct pgpath *pgpath = NULL, *tmp;
+ struct pgpath *pgpath = NULL;
unsigned must_queue = 1;
unsigned long flags;
@@ -457,14 +472,9 @@ static void process_queued_ios(struct work_struct *work)
(!pgpath && !m->queue_if_no_path))
must_queue = 0;
- if (m->pg_init_required && !m->pg_init_in_progress && pgpath) {
- m->pg_init_count++;
- m->pg_init_required = 0;
- list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) {
- if (queue_work(kmpath_handlerd, &tmp->activate_path))
- m->pg_init_in_progress++;
- }
- }
+ if (m->pg_init_required && !m->pg_init_in_progress && pgpath)
+ __pg_init_all_paths(m);
+
out:
spin_unlock_irqrestore(&m->lock, flags);
if (!must_queue)
@@ -597,8 +607,8 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
if (!p)
return ERR_PTR(-ENOMEM);
- r = dm_get_device(ti, shift(as), ti->begin, ti->len,
- dm_table_get_mode(ti->table), &p->path.dev);
+ r = dm_get_device(ti, shift(as), dm_table_get_mode(ti->table),
+ &p->path.dev);
if (r) {
ti->error = "error getting device";
goto bad;
@@ -890,9 +900,34 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
return r;
}
-static void flush_multipath_work(void)
+static void multipath_wait_for_pg_init_completion(struct multipath *m)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;
+
+ add_wait_queue(&m->pg_init_wait, &wait);
+
+ while (1) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+
+ spin_lock_irqsave(&m->lock, flags);
+ if (!m->pg_init_in_progress) {
+ spin_unlock_irqrestore(&m->lock, flags);
+ break;
+ }
+ spin_unlock_irqrestore(&m->lock, flags);
+
+ io_schedule();
+ }
+ set_current_state(TASK_RUNNING);
+
+ remove_wait_queue(&m->pg_init_wait, &wait);
+}
+
+static void flush_multipath_work(struct multipath *m)
{
flush_workqueue(kmpath_handlerd);
+ multipath_wait_for_pg_init_completion(m);
flush_workqueue(kmultipathd);
flush_scheduled_work();
}
@@ -901,7 +936,7 @@ static void multipath_dtr(struct dm_target *ti)
{
struct multipath *m = ti->private;
- flush_multipath_work();
+ flush_multipath_work(m);
free_multipath(m);
}
@@ -1128,8 +1163,7 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
static void pg_init_done(void *data, int errors)
{
- struct dm_path *path = data;
- struct pgpath *pgpath = path_to_pgpath(path);
+ struct pgpath *pgpath = data;
struct priority_group *pg = pgpath->pg;
struct multipath *m = pg->m;
unsigned long flags;
@@ -1143,8 +1177,8 @@ static void pg_init_done(void *data, int errors)
errors = 0;
break;
}
- DMERR("Cannot failover device because scsi_dh_%s was not "
- "loaded.", m->hw_handler_name);
+ DMERR("Could not failover the device: Handler scsi_dh_%s "
+ "Error %d.", m->hw_handler_name, errors);
/*
* Fail path for now, so we do not ping pong
*/
@@ -1181,14 +1215,24 @@ static void pg_init_done(void *data, int errors)
m->current_pgpath = NULL;
m->current_pg = NULL;
}
- } else if (!m->pg_init_required) {
- m->queue_io = 0;
+ } else if (!m->pg_init_required)
pg->bypassed = 0;
- }
- m->pg_init_in_progress--;
- if (!m->pg_init_in_progress)
- queue_work(kmultipathd, &m->process_queued_ios);
+ if (--m->pg_init_in_progress)
+ /* Activations of other paths are still on going */
+ goto out;
+
+ if (!m->pg_init_required)
+ m->queue_io = 0;
+
+ queue_work(kmultipathd, &m->process_queued_ios);
+
+ /*
+ * Wake up any thread waiting to suspend.
+ */
+ wake_up(&m->pg_init_wait);
+
+out:
spin_unlock_irqrestore(&m->lock, flags);
}
@@ -1198,7 +1242,7 @@ static void activate_path(struct work_struct *work)
container_of(work, struct pgpath, activate_path);
scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
- pg_init_done, &pgpath->path);
+ pg_init_done, pgpath);
}
/*
@@ -1276,8 +1320,7 @@ static void multipath_postsuspend(struct dm_target *ti)
struct multipath *m = ti->private;
mutex_lock(&m->work_mutex);
- m->suspended = 1;
- flush_multipath_work();
+ flush_multipath_work(m);
mutex_unlock(&m->work_mutex);
}
@@ -1289,10 +1332,6 @@ static void multipath_resume(struct dm_target *ti)
struct multipath *m = (struct multipath *) ti->private;
unsigned long flags;
- mutex_lock(&m->work_mutex);
- m->suspended = 0;
- mutex_unlock(&m->work_mutex);
-
spin_lock_irqsave(&m->lock, flags);
m->queue_if_no_path = m->saved_queue_if_no_path;
spin_unlock_irqrestore(&m->lock, flags);
@@ -1428,11 +1467,6 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
mutex_lock(&m->work_mutex);
- if (m->suspended) {
- r = -EBUSY;
- goto out;
- }
-
if (dm_suspended(ti)) {
r = -EBUSY;
goto out;
@@ -1471,8 +1505,7 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
goto out;
}
- r = dm_get_device(ti, argv[1], ti->begin, ti->len,
- dm_table_get_mode(ti->table), &dev);
+ r = dm_get_device(ti, argv[1], dm_table_get_mode(ti->table), &dev);
if (r) {
DMWARN("message: error getting device %s",
argv[1]);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 6c1046df81f..ddda531723d 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -465,9 +465,17 @@ static void map_region(struct dm_io_region *io, struct mirror *m,
static void hold_bio(struct mirror_set *ms, struct bio *bio)
{
/*
- * If device is suspended, complete the bio.
+ * Lock is required to avoid race condition during suspend
+ * process.
*/
+ spin_lock_irq(&ms->lock);
+
if (atomic_read(&ms->suspend)) {
+ spin_unlock_irq(&ms->lock);
+
+ /*
+ * If device is suspended, complete the bio.
+ */
if (dm_noflush_suspending(ms->ti))
bio_endio(bio, DM_ENDIO_REQUEUE);
else
@@ -478,7 +486,6 @@ static void hold_bio(struct mirror_set *ms, struct bio *bio)
/*
* Hold bio until the suspend is complete.
*/
- spin_lock_irq(&ms->lock);
bio_list_add(&ms->holds, bio);
spin_unlock_irq(&ms->lock);
}
@@ -737,9 +744,12 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
dm_rh_delay(ms->rh, bio);
while ((bio = bio_list_pop(&nosync))) {
- if (unlikely(ms->leg_failure) && errors_handled(ms))
- hold_bio(ms, bio);
- else {
+ if (unlikely(ms->leg_failure) && errors_handled(ms)) {
+ spin_lock_irq(&ms->lock);
+ bio_list_add(&ms->failures, bio);
+ spin_unlock_irq(&ms->lock);
+ wakeup_mirrord(ms);
+ } else {
map_bio(get_default_mirror(ms), bio);
generic_make_request(bio);
}
@@ -917,8 +927,7 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
return -EINVAL;
}
- if (dm_get_device(ti, argv[0], offset, ti->len,
- dm_table_get_mode(ti->table),
+ if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
&ms->mirror[mirror].dev)) {
ti->error = "Device lookup failure";
return -ENXIO;
@@ -1259,6 +1268,20 @@ static void mirror_presuspend(struct dm_target *ti)
atomic_set(&ms->suspend, 1);
/*
+ * Process bios in the hold list to start recovery waiting
+ * for bios in the hold list. After the process, no bio has
+ * a chance to be added in the hold list because ms->suspend
+ * is set.
+ */
+ spin_lock_irq(&ms->lock);
+ holds = ms->holds;
+ bio_list_init(&ms->holds);
+ spin_unlock_irq(&ms->lock);
+
+ while ((bio = bio_list_pop(&holds)))
+ hold_bio(ms, bio);
+
+ /*
* We must finish up all the work that we've
* generated (i.e. recovery work).
*/
@@ -1278,22 +1301,6 @@ static void mirror_presuspend(struct dm_target *ti)
* we know that all of our I/O has been pushed.
*/
flush_workqueue(ms->kmirrord_wq);
-
- /*
- * Now set ms->suspend is set and the workqueue flushed, no more
- * entries can be added to ms->hold list, so process it.
- *
- * Bios can still arrive concurrently with or after this
- * presuspend function, but they cannot join the hold list
- * because ms->suspend is set.
- */
- spin_lock_irq(&ms->lock);
- holds = ms->holds;
- bio_list_init(&ms->holds);
- spin_unlock_irq(&ms->lock);
-
- while ((bio = bio_list_pop(&holds)))
- hold_bio(ms, bio);
}
static void mirror_postsuspend(struct dm_target *ti)
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c
index 168bd38f500..bd5c58b2886 100644
--- a/drivers/md/dm-region-hash.c
+++ b/drivers/md/dm-region-hash.c
@@ -11,6 +11,7 @@
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "dm.h"
diff --git a/drivers/md/dm-service-time.c b/drivers/md/dm-service-time.c
index cfa668f46c4..9c6c2e47ad6 100644
--- a/drivers/md/dm-service-time.c
+++ b/drivers/md/dm-service-time.c
@@ -11,6 +11,8 @@
#include "dm.h"
#include "dm-path-selector.h"
+#include <linux/slab.h>
+
#define DM_MSG_PREFIX "multipath service-time"
#define ST_MIN_IO 1
#define ST_MAX_RELATIVE_THROUGHPUT 100
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index ee8eb283650..54853773510 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -83,10 +83,10 @@ struct dm_snapshot {
/* Whether or not owning mapped_device is suspended */
int suspended;
- mempool_t *pending_pool;
-
atomic_t pending_exceptions_count;
+ mempool_t *pending_pool;
+
struct dm_exception_table pending;
struct dm_exception_table complete;
@@ -96,6 +96,11 @@ struct dm_snapshot {
*/
spinlock_t pe_lock;
+ /* Chunks with outstanding reads */
+ spinlock_t tracked_chunk_lock;
+ mempool_t *tracked_chunk_pool;
+ struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+
/* The on disk metadata handler */
struct dm_exception_store *store;
@@ -105,10 +110,12 @@ struct dm_snapshot {
struct bio_list queued_bios;
struct work_struct queued_bios_work;
- /* Chunks with outstanding reads */
- mempool_t *tracked_chunk_pool;
- spinlock_t tracked_chunk_lock;
- struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+ /* Wait for events based on state_bits */
+ unsigned long state_bits;
+
+ /* Range of chunks currently being merged. */
+ chunk_t first_merging_chunk;
+ int num_merging_chunks;
/*
* The merge operation failed if this flag is set.
@@ -125,13 +132,6 @@ struct dm_snapshot {
*/
int merge_failed;
- /* Wait for events based on state_bits */
- unsigned long state_bits;
-
- /* Range of chunks currently being merged. */
- chunk_t first_merging_chunk;
- int num_merging_chunks;
-
/*
* Incoming bios that overlap with chunks being merged must wait
* for them to be committed.
@@ -1081,8 +1081,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
argv++;
argc--;
- r = dm_get_device(ti, cow_path, 0, 0,
- FMODE_READ | FMODE_WRITE, &s->cow);
+ r = dm_get_device(ti, cow_path, FMODE_READ | FMODE_WRITE, &s->cow);
if (r) {
ti->error = "Cannot get COW device";
goto bad_cow;
@@ -1098,7 +1097,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
argv += args_used;
argc -= args_used;
- r = dm_get_device(ti, origin_path, 0, ti->len, origin_mode, &s->origin);
+ r = dm_get_device(ti, origin_path, origin_mode, &s->origin);
if (r) {
ti->error = "Cannot get origin device";
goto bad_origin;
@@ -2100,8 +2099,7 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
return -EINVAL;
}
- r = dm_get_device(ti, argv[0], 0, ti->len,
- dm_table_get_mode(ti->table), &dev);
+ r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &dev);
if (r) {
ti->error = "Cannot get target device";
return r;
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index bd58703ee8f..e610725db76 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -80,8 +80,7 @@ static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
if (sscanf(argv[1], "%llu", &start) != 1)
return -EINVAL;
- if (dm_get_device(ti, argv[0], start, sc->stripe_width,
- dm_table_get_mode(ti->table),
+ if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
&sc->stripe[stripe].dev))
return -ENXIO;
diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c
index f91b40942e0..84d2b91e4ef 100644
--- a/drivers/md/dm-sysfs.c
+++ b/drivers/md/dm-sysfs.c
@@ -75,7 +75,7 @@ static struct attribute *dm_attrs[] = {
NULL,
};
-static struct sysfs_ops dm_sysfs_ops = {
+static const struct sysfs_ops dm_sysfs_ops = {
.show = dm_attr_show,
};
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 4b22feb01a0..9924ea23032 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -429,8 +429,7 @@ static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
* it's already present.
*/
static int __table_get_device(struct dm_table *t, struct dm_target *ti,
- const char *path, sector_t start, sector_t len,
- fmode_t mode, struct dm_dev **result)
+ const char *path, fmode_t mode, struct dm_dev **result)
{
int r;
dev_t uninitialized_var(dev);
@@ -527,11 +526,10 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
}
EXPORT_SYMBOL_GPL(dm_set_device_limits);
-int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
- sector_t len, fmode_t mode, struct dm_dev **result)
+int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
+ struct dm_dev **result)
{
- return __table_get_device(ti->table, ti, path,
- start, len, mode, result);
+ return __table_get_device(ti->table, ti, path, mode, result);
}
@@ -1231,8 +1229,6 @@ void dm_table_unplug_all(struct dm_table *t)
struct mapped_device *dm_table_get_md(struct dm_table *t)
{
- dm_get(t->md);
-
return t->md;
}
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 04feccf2a99..11dea11dc0b 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -10,7 +10,6 @@
#include <linux/init.h>
#include <linux/kmod.h>
#include <linux/bio.h>
-#include <linux/slab.h>
#define DM_MSG_PREFIX "target"
diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c
index c7c555a8c7b..6b1e3b61b25 100644
--- a/drivers/md/dm-uevent.c
+++ b/drivers/md/dm-uevent.c
@@ -187,7 +187,7 @@ void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) {
DMERR("%s: Invalid event_type %d", __func__, event_type);
- goto out;
+ return;
}
event = dm_build_path_uevent(md, ti,
@@ -195,12 +195,9 @@ void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
_dm_uevent_type_names[event_type].name,
path, nr_valid_paths);
if (IS_ERR(event))
- goto out;
+ return;
dm_uevent_add(md, &event->elist);
-
-out:
- dm_put(md);
}
EXPORT_SYMBOL_GPL(dm_path_uevent);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index aa4e2aa86d4..d21e1284604 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -635,8 +635,10 @@ static void dec_pending(struct dm_io *io, int error)
if (!md->barrier_error && io_error != -EOPNOTSUPP)
md->barrier_error = io_error;
end_io_acct(io);
+ free_io(md, io);
} else {
end_io_acct(io);
+ free_io(md, io);
if (io_error != DM_ENDIO_REQUEUE) {
trace_block_bio_complete(md->queue, bio);
@@ -644,8 +646,6 @@ static void dec_pending(struct dm_io *io, int error)
bio_endio(bio, io_error);
}
}
-
- free_io(md, io);
}
}
@@ -2618,18 +2618,19 @@ out:
/*-----------------------------------------------------------------
* Event notification.
*---------------------------------------------------------------*/
-void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
+int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
unsigned cookie)
{
char udev_cookie[DM_COOKIE_LENGTH];
char *envp[] = { udev_cookie, NULL };
if (!cookie)
- kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
+ return kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
else {
snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u",
DM_COOKIE_ENV_VAR_NAME, cookie);
- kobject_uevent_env(&disk_to_dev(md->disk)->kobj, action, envp);
+ return kobject_uevent_env(&disk_to_dev(md->disk)->kobj,
+ action, envp);
}
}
@@ -2699,23 +2700,13 @@ int dm_suspended_md(struct mapped_device *md)
int dm_suspended(struct dm_target *ti)
{
- struct mapped_device *md = dm_table_get_md(ti->table);
- int r = dm_suspended_md(md);
-
- dm_put(md);
-
- return r;
+ return dm_suspended_md(dm_table_get_md(ti->table));
}
EXPORT_SYMBOL_GPL(dm_suspended);
int dm_noflush_suspending(struct dm_target *ti)
{
- struct mapped_device *md = dm_table_get_md(ti->table);
- int r = __noflush_suspending(md);
-
- dm_put(md);
-
- return r;
+ return __noflush_suspending(dm_table_get_md(ti->table));
}
EXPORT_SYMBOL_GPL(dm_noflush_suspending);
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 8dadaa5bc39..bad1724d486 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -125,8 +125,8 @@ void dm_stripe_exit(void);
int dm_open_count(struct mapped_device *md);
int dm_lock_for_deletion(struct mapped_device *md);
-void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
- unsigned cookie);
+int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
+ unsigned cookie);
int dm_io_init(void);
void dm_io_exit(void);
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 713acd02ab3..8e3850b98cc 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -64,6 +64,7 @@
#define MaxFault 50
#include <linux/blkdev.h>
#include <linux/raid/md_u.h>
+#include <linux/slab.h>
#include "md.h"
#include <linux/seq_file.h>
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index af2d39d603c..09437e95823 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -19,6 +19,7 @@
#include <linux/blkdev.h>
#include <linux/raid/md_u.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "md.h"
#include "linear.h"
@@ -172,12 +173,14 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
/* as we don't honour merge_bvec_fn, we must never risk
- * violating it, so limit ->max_sector to one PAGE, as
- * a one page request is never in violation.
+ * violating it, so limit max_segments to 1 lying within
+ * a single page.
*/
- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
- blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+ blk_queue_max_segments(mddev->queue, 1);
+ blk_queue_segment_boundary(mddev->queue,
+ PAGE_CACHE_SIZE - 1);
+ }
conf->array_sectors += rdev->sectors;
cnt++;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a20a71e5efd..9712b2e97be 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -49,6 +49,7 @@
#include <linux/delay.h>
#include <linux/raid/md_p.h>
#include <linux/raid/md_u.h>
+#include <linux/slab.h>
#include "md.h"
#include "bitmap.h"
@@ -2642,7 +2643,7 @@ static void rdev_free(struct kobject *ko)
mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj);
kfree(rdev);
}
-static struct sysfs_ops rdev_sysfs_ops = {
+static const struct sysfs_ops rdev_sysfs_ops = {
.show = rdev_attr_show,
.store = rdev_attr_store,
};
@@ -4059,7 +4060,7 @@ static void md_free(struct kobject *ko)
kfree(mddev);
}
-static struct sysfs_ops md_sysfs_ops = {
+static const struct sysfs_ops md_sysfs_ops = {
.show = md_attr_show,
.store = md_attr_store,
};
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 4b323f45ad7..789bf535d29 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -22,6 +22,7 @@
#include <linux/blkdev.h>
#include <linux/raid/md_u.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "md.h"
#include "multipath.h"
@@ -301,14 +302,16 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
rdev->data_offset << 9);
/* as we don't honour merge_bvec_fn, we must never risk
- * violating it, so limit ->max_sector to one PAGE, as
- * a one page request is never in violation.
+ * violating it, so limit ->max_segments to one, lying
+ * within a single page.
* (Note: it is very unlikely that a device with
* merge_bvec_fn will be involved in multipath.)
*/
- if (q->merge_bvec_fn &&
- queue_max_sectors(q) > (PAGE_SIZE>>9))
- blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+ if (q->merge_bvec_fn) {
+ blk_queue_max_segments(mddev->queue, 1);
+ blk_queue_segment_boundary(mddev->queue,
+ PAGE_CACHE_SIZE - 1);
+ }
conf->working_disks++;
mddev->degraded--;
@@ -476,9 +479,11 @@ static int multipath_run (mddev_t *mddev)
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, not that we ever expect a device with
* a merge_bvec_fn to be involved in multipath */
- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
- blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+ blk_queue_max_segments(mddev->queue, 1);
+ blk_queue_segment_boundary(mddev->queue,
+ PAGE_CACHE_SIZE - 1);
+ }
if (!test_bit(Faulty, &rdev->flags))
conf->working_disks++;
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index a1f7147b757..c3bec024612 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -20,6 +20,7 @@
#include <linux/blkdev.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "md.h"
#include "raid0.h"
@@ -176,14 +177,15 @@ static int create_strip_zones(mddev_t *mddev)
disk_stack_limits(mddev->gendisk, rdev1->bdev,
rdev1->data_offset << 9);
/* as we don't honour merge_bvec_fn, we must never risk
- * violating it, so limit ->max_sector to one PAGE, as
- * a one page request is never in violation.
+ * violating it, so limit ->max_segments to 1, lying within
+ * a single page.
*/
- if (rdev1->bdev->bd_disk->queue->merge_bvec_fn &&
- queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
- blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
-
+ if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) {
+ blk_queue_max_segments(mddev->queue, 1);
+ blk_queue_segment_boundary(mddev->queue,
+ PAGE_CACHE_SIZE - 1);
+ }
if (!smallest || (rdev1->sectors < smallest->sectors))
smallest = rdev1;
cnt++;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 5a06122abd3..e59b10e66ed 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -31,6 +31,7 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/seq_file.h>
@@ -1152,13 +1153,17 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
- /* as we don't honour merge_bvec_fn, we must never risk
- * violating it, so limit ->max_sector to one PAGE, as
- * a one page request is never in violation.
+ /* as we don't honour merge_bvec_fn, we must
+ * never risk violating it, so limit
+ * ->max_segments to one lying with a single
+ * page, as a one page request is never in
+ * violation.
*/
- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
- blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+ blk_queue_max_segments(mddev->queue, 1);
+ blk_queue_segment_boundary(mddev->queue,
+ PAGE_CACHE_SIZE - 1);
+ }
p->head_position = 0;
rdev->raid_disk = mirror;
@@ -2098,12 +2103,14 @@ static int run(mddev_t *mddev)
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
/* as we don't honour merge_bvec_fn, we must never risk
- * violating it, so limit ->max_sector to one PAGE, as
- * a one page request is never in violation.
+ * violating it, so limit ->max_segments to 1 lying within
+ * a single page, as a one page request is never in violation.
*/
- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
- blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+ blk_queue_max_segments(mddev->queue, 1);
+ blk_queue_segment_boundary(mddev->queue,
+ PAGE_CACHE_SIZE - 1);
+ }
}
mddev->degraded = 0;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 7584f9ab9bc..e2766d8251a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -18,6 +18,7 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/seq_file.h>
@@ -1155,13 +1156,17 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
- /* as we don't honour merge_bvec_fn, we must never risk
- * violating it, so limit ->max_sector to one PAGE, as
- * a one page request is never in violation.
+ /* as we don't honour merge_bvec_fn, we must
+ * never risk violating it, so limit
+ * ->max_segments to one lying with a single
+ * page, as a one page request is never in
+ * violation.
*/
- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
- blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+ blk_queue_max_segments(mddev->queue, 1);
+ blk_queue_segment_boundary(mddev->queue,
+ PAGE_CACHE_SIZE - 1);
+ }
p->head_position = 0;
rdev->raid_disk = mirror;
@@ -2255,12 +2260,14 @@ static int run(mddev_t *mddev)
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
/* as we don't honour merge_bvec_fn, we must never risk
- * violating it, so limit ->max_sector to one PAGE, as
- * a one page request is never in violation.
+ * violating it, so limit max_segments to 1 lying
+ * within a single page.
*/
- if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
- blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+ if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+ blk_queue_max_segments(mddev->queue, 1);
+ blk_queue_segment_boundary(mddev->queue,
+ PAGE_CACHE_SIZE - 1);
+ }
disk->head_position = 0;
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 70ffbd071b2..58ea0ecae7c 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -50,6 +50,7 @@
#include <linux/async.h>
#include <linux/seq_file.h>
#include <linux/cpu.h>
+#include <linux/slab.h>
#include "md.h"
#include "raid5.h"
#include "bitmap.h"
@@ -1649,8 +1650,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
int previous, int *dd_idx,
struct stripe_head *sh)
{
- long stripe;
- unsigned long chunk_number;
+ sector_t stripe, stripe2;
+ sector_t chunk_number;
unsigned int chunk_offset;
int pd_idx, qd_idx;
int ddf_layout = 0;
@@ -1670,18 +1671,13 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
*/
chunk_offset = sector_div(r_sector, sectors_per_chunk);
chunk_number = r_sector;
- BUG_ON(r_sector != chunk_number);
/*
* Compute the stripe number
*/
- stripe = chunk_number / data_disks;
-
- /*
- * Compute the data disk and parity disk indexes inside the stripe
- */
- *dd_idx = chunk_number % data_disks;
-
+ stripe = chunk_number;
+ *dd_idx = sector_div(stripe, data_disks);
+ stripe2 = stripe;
/*
* Select the parity disk based on the user selected algorithm.
*/
@@ -1693,21 +1689,21 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
case 5:
switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
- pd_idx = data_disks - stripe % raid_disks;
+ pd_idx = data_disks - sector_div(stripe2, raid_disks);
if (*dd_idx >= pd_idx)
(*dd_idx)++;
break;
case ALGORITHM_RIGHT_ASYMMETRIC:
- pd_idx = stripe % raid_disks;
+ pd_idx = sector_div(stripe2, raid_disks);
if (*dd_idx >= pd_idx)
(*dd_idx)++;
break;
case ALGORITHM_LEFT_SYMMETRIC:
- pd_idx = data_disks - stripe % raid_disks;
+ pd_idx = data_disks - sector_div(stripe2, raid_disks);
*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
break;
case ALGORITHM_RIGHT_SYMMETRIC:
- pd_idx = stripe % raid_disks;
+ pd_idx = sector_div(stripe2, raid_disks);
*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
break;
case ALGORITHM_PARITY_0:
@@ -1727,7 +1723,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
- pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
qd_idx = pd_idx + 1;
if (pd_idx == raid_disks-1) {
(*dd_idx)++; /* Q D D D P */
@@ -1736,7 +1732,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
(*dd_idx) += 2; /* D D P Q D */
break;
case ALGORITHM_RIGHT_ASYMMETRIC:
- pd_idx = stripe % raid_disks;
+ pd_idx = sector_div(stripe2, raid_disks);
qd_idx = pd_idx + 1;
if (pd_idx == raid_disks-1) {
(*dd_idx)++; /* Q D D D P */
@@ -1745,12 +1741,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
(*dd_idx) += 2; /* D D P Q D */
break;
case ALGORITHM_LEFT_SYMMETRIC:
- pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
qd_idx = (pd_idx + 1) % raid_disks;
*dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
break;
case ALGORITHM_RIGHT_SYMMETRIC:
- pd_idx = stripe % raid_disks;
+ pd_idx = sector_div(stripe2, raid_disks);
qd_idx = (pd_idx + 1) % raid_disks;
*dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
break;
@@ -1769,7 +1765,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
/* Exactly the same as RIGHT_ASYMMETRIC, but or
* of blocks for computing Q is different.
*/
- pd_idx = stripe % raid_disks;
+ pd_idx = sector_div(stripe2, raid_disks);
qd_idx = pd_idx + 1;
if (pd_idx == raid_disks-1) {
(*dd_idx)++; /* Q D D D P */
@@ -1784,7 +1780,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
* D D D P Q rather than
* Q D D D P
*/
- pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+ stripe2 += 1;
+ pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
qd_idx = pd_idx + 1;
if (pd_idx == raid_disks-1) {
(*dd_idx)++; /* Q D D D P */
@@ -1796,7 +1793,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
case ALGORITHM_ROTATING_N_CONTINUE:
/* Same as left_symmetric but Q is before P */
- pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
ddf_layout = 1;
@@ -1804,27 +1801,27 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
case ALGORITHM_LEFT_ASYMMETRIC_6:
/* RAID5 left_asymmetric, with Q on last device */
- pd_idx = data_disks - stripe % (raid_disks-1);
+ pd_idx = data_disks - sector_div(stripe2, raid_disks-1);
if (*dd_idx >= pd_idx)
(*dd_idx)++;
qd_idx = raid_disks - 1;
break;
case ALGORITHM_RIGHT_ASYMMETRIC_6:
- pd_idx = stripe % (raid_disks-1);
+ pd_idx = sector_div(stripe2, raid_disks-1);
if (*dd_idx >= pd_idx)
(*dd_idx)++;
qd_idx = raid_disks - 1;
break;
case ALGORITHM_LEFT_SYMMETRIC_6:
- pd_idx = data_disks - stripe % (raid_disks-1);
+ pd_idx = data_disks - sector_div(stripe2, raid_disks-1);
*dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
qd_idx = raid_disks - 1;
break;
case ALGORITHM_RIGHT_SYMMETRIC_6:
- pd_idx = stripe % (raid_disks-1);
+ pd_idx = sector_div(stripe2, raid_disks-1);
*dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
qd_idx = raid_disks - 1;
break;
@@ -1869,14 +1866,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
: conf->algorithm;
sector_t stripe;
int chunk_offset;
- int chunk_number, dummy1, dd_idx = i;
+ sector_t chunk_number;
+ int dummy1, dd_idx = i;
sector_t r_sector;
struct stripe_head sh2;
chunk_offset = sector_div(new_sector, sectors_per_chunk);
stripe = new_sector;
- BUG_ON(new_sector != stripe);
if (i == sh->pd_idx)
return 0;
@@ -1969,7 +1966,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
}
chunk_number = stripe * data_disks + i;
- r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
+ r_sector = chunk_number * sectors_per_chunk + chunk_offset;
check = raid5_compute_sector(conf, r_sector,
previous, &dummy1, &sh2);
diff --git a/drivers/md/raid6algos.c b/drivers/md/raid6algos.c
index bffc61bff5a..1f8784bfd44 100644
--- a/drivers/md/raid6algos.c
+++ b/drivers/md/raid6algos.c
@@ -17,6 +17,7 @@
*/
#include <linux/raid/pq.h>
+#include <linux/gfp.h>
#ifndef __KERNEL__
#include <sys/mman.h>
#include <stdio.h>
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index 0903f539bf6..bfca26d5182 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -14,6 +14,7 @@
#include <linux/input.h>
+#include <linux/slab.h>
#include <media/ir-common.h>
#define IR_TAB_MIN_SIZE 32
@@ -123,7 +124,7 @@ static int ir_copy_table(struct ir_scancode_table *destin,
* If the key is not found, returns -EINVAL, otherwise, returns 0.
*/
static int ir_getkeycode(struct input_dev *dev,
- int scancode, int *keycode)
+ unsigned int scancode, unsigned int *keycode)
{
int elem;
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
@@ -291,7 +292,7 @@ static int ir_insert_key(struct ir_scancode_table *rc_tab,
* If the key is not found, returns -EINVAL, otherwise, returns 0.
*/
static int ir_setkeycode(struct input_dev *dev,
- int scancode, int keycode)
+ unsigned int scancode, unsigned int keycode)
{
int rc = 0;
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index bf5fbcd8423..e14e6c486b5 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -12,6 +12,7 @@
* GNU General Public License for more details.
*/
+#include <linux/slab.h>
#include <linux/input.h>
#include <linux/device.h>
#include <media/ir-core.h>
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
index 3d03640cf1f..937e4b00d7e 100644
--- a/drivers/media/common/tuners/max2165.c
+++ b/drivers/media/common/tuners/max2165.c
@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/common/tuners/mc44s803.c b/drivers/media/common/tuners/mc44s803.c
index 20c4485ce16..fe5c4b8d83e 100644
--- a/drivers/media/common/tuners/mc44s803.c
+++ b/drivers/media/common/tuners/mc44s803.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c
index c7abe3d8f90..2d0e7689c6a 100644
--- a/drivers/media/common/tuners/mt2060.c
+++ b/drivers/media/common/tuners/mt2060.c
@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c
index 44608ad4e2d..d0e70e10a71 100644
--- a/drivers/media/common/tuners/mt20xx.c
+++ b/drivers/media/common/tuners/mt20xx.c
@@ -6,6 +6,7 @@
*/
#include <linux/delay.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/videodev2.h>
#include "tuner-i2c.h"
#include "mt20xx.h"
diff --git a/drivers/media/common/tuners/mt2131.c b/drivers/media/common/tuners/mt2131.c
index e8d3c48f860..a4f830bb25d 100644
--- a/drivers/media/common/tuners/mt2131.c
+++ b/drivers/media/common/tuners/mt2131.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/common/tuners/mt2266.c b/drivers/media/common/tuners/mt2266.c
index 54b18f94b14..25a8ea342c4 100644
--- a/drivers/media/common/tuners/mt2266.c
+++ b/drivers/media/common/tuners/mt2266.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "mt2266.h"
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c
index 36a7bc7585a..b21b6ea68b2 100644
--- a/drivers/media/common/tuners/tda827x.c
+++ b/drivers/media/common/tuners/tda827x.c
@@ -19,6 +19,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/types.h>
#include <linux/dvb/frontend.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 2833137fa81..c9062ceddc7 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -21,6 +21,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
#include "tuner-i2c.h"
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index a71c100c95d..bf14bd79e2f 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -4,7 +4,6 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c
index 60ed872f3d4..925399dffbe 100644
--- a/drivers/media/common/tuners/tea5761.c
+++ b/drivers/media/common/tuners/tea5761.c
@@ -8,6 +8,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
#include <media/tuner.h>
diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c
index 223a226d20a..36e85d81acb 100644
--- a/drivers/media/common/tuners/tea5767.c
+++ b/drivers/media/common/tuners/tea5767.c
@@ -11,6 +11,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
#include "tuner-i2c.h"
diff --git a/drivers/media/common/tuners/tuner-i2c.h b/drivers/media/common/tuners/tuner-i2c.h
index cb1c7141f0c..18f005634c6 100644
--- a/drivers/media/common/tuners/tuner-i2c.h
+++ b/drivers/media/common/tuners/tuner-i2c.h
@@ -22,6 +22,7 @@
#define __TUNER_I2C_H__
#include <linux/i2c.h>
+#include <linux/slab.h>
struct tuner_i2c_props {
u8 addr;
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index be51c294b37..96d61707f50 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <media/tuner.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "tuner-i2c.h"
#include "tuner-xc2028.h"
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 0e246eaad05..770243c720d 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 383cca378b8..b6d46961a99 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -27,6 +27,7 @@
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <media/ir-common.h>
#include "demux.h"
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index c1379b56dfb..02ebe28f830 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -31,6 +31,7 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/dvb/dmx.h>
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 52e4ce4304e..bf0e6bed28d 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -36,6 +36,7 @@
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/dvb/frontend.h>
@@ -214,14 +215,14 @@ struct dvb_tuner_ops {
int (*get_status)(struct dvb_frontend *fe, u32 *status);
int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
- /** These are provided seperately from set_params in order to facilitate silicon
- * tuners which require sophisticated tuning loops, controlling each parameter seperately. */
+ /** These are provided separately from set_params in order to facilitate silicon
+ * tuners which require sophisticated tuning loops, controlling each parameter separately. */
int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
/*
- * These are provided seperately from set_params in order to facilitate silicon
- * tuners which require sophisticated tuning loops, controlling each parameter seperately.
+ * These are provided separately from set_params in order to facilitate silicon
+ * tuners which require sophisticated tuning loops, controlling each parameter separately.
*/
int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index d7975383d31..74d94e45324 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -22,6 +22,7 @@
*/
#include <linux/hash.h>
+#include <linux/slab.h>
#include "af9015.h"
#include "af9013.h"
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index a7b8405c291..960376da7d5 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -25,6 +25,7 @@
*/
#include <media/tuner.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include "cxusb.h"
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index a03ef7efec9..852fe89539c 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -9,7 +9,7 @@
#include <linux/usb/input.h>
static int dvb_usb_getkeycode(struct input_dev *dev,
- int scancode, int *keycode)
+ unsigned int scancode, unsigned int *keycode)
{
struct dvb_usb_device *d = input_get_drvdata(dev);
@@ -39,7 +39,7 @@ static int dvb_usb_getkeycode(struct input_dev *dev,
}
static int dvb_usb_setkeycode(struct input_dev *dev,
- int scancode, int keycode)
+ unsigned int scancode, unsigned int keycode)
{
struct dvb_usb_device *d = input_get_drvdata(dev);
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
index c3e0ec2dcfc..26333b4f4d3 100644
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -15,6 +15,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c
index 599d66e5843..fcf3828472b 100644
--- a/drivers/media/dvb/firewire/firedtv-rc.c
+++ b/drivers/media/dvb/firewire/firedtv-rc.c
@@ -12,6 +12,7 @@
#include <linux/bitops.h>
#include <linux/input.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/workqueue.h>
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
index 956b80f4979..a1fed0fa8ed 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -23,7 +23,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
#include "au8522.h"
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
index 0d12763603b..d4e466a90e4 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -25,6 +25,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
index 7eac178f57b..65240b7801e 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -25,6 +25,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index fa851601e7d..40a09981027 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -12,6 +12,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
index 0109720353b..0f09fd31cb2 100644
--- a/drivers/media/dvb/frontends/dib7000m.c
+++ b/drivers/media/dvb/frontends/dib7000m.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation, version 2.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 750ae61a20f..85468a45c34 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation, version 2.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include "dvb_math.h"
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index 2aa97dd6a8a..df17b91b325 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation, version 2.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include "dvb_math.h"
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 868b78bfae7..f74cca6dc26 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 6d865d6161d..4d4d0bb5920 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <asm/types.h>
diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c
index 600dad6b41e..f7a40a18777 100644
--- a/drivers/media/dvb/frontends/itd1000.c
+++ b/drivers/media/dvb/frontends/itd1000.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
index e334b5d4e57..45a529b06b9 100644
--- a/drivers/media/dvb/frontends/lgdt3304.c
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -7,6 +7,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
#include "lgdt3304.h"
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
index fde8c59700f..d69c775f864 100644
--- a/drivers/media/dvb/frontends/lgdt3305.c
+++ b/drivers/media/dvb/frontends/lgdt3305.c
@@ -21,6 +21,7 @@
#include <asm/div64.h>
#include <linux/dvb/frontend.h>
+#include <linux/slab.h>
#include "dvb_math.h"
#include "lgdt3305.h"
diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c
index d05f7500e0c..599d1aa519a 100644
--- a/drivers/media/dvb/frontends/mb86a16.c
+++ b/drivers/media/dvb/frontends/mb86a16.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "mb86a16.h"
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
index 3156b64cfc9..0eefff61cc5 100644
--- a/drivers/media/dvb/frontends/s921_module.c
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
#include "s921_module.h"
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index 1570669837e..8e38fcee564 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/dvb/frontend.h>
diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c
index 0e2cb0df144..ed699647050 100644
--- a/drivers/media/dvb/frontends/stb6000.c
+++ b/drivers/media/dvb/frontends/stb6000.c
@@ -20,6 +20,7 @@
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <asm/types.h>
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index 60ee18a94f4..f73c13323e9 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index c52c3357dc5..a3c07fe0e6c 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/dvb/frontend.h>
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
index bef0cc83847..2dca7c8e514 100644
--- a/drivers/media/dvb/frontends/stv6110.c
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -22,6 +22,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
index f931ed07e92..dea4245f077 100644
--- a/drivers/media/dvb/frontends/stv6110x.c
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb/frontends/tda665x.c
index c44fefe92d9..2c1c759a4f4 100644
--- a/drivers/media/dvb/frontends/tda665x.c
+++ b/drivers/media/dvb/frontends/tda665x.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "tda665x.h"
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
index 614afcec05f..1742056a34e 100644
--- a/drivers/media/dvb/frontends/tda8261.c
+++ b/drivers/media/dvb/frontends/tda8261.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "tda8261.h"
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c
index a051554b5e2..06c94800b94 100644
--- a/drivers/media/dvb/frontends/tda826x.c
+++ b/drivers/media/dvb/frontends/tda826x.c
@@ -20,6 +20,7 @@
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <asm/types.h>
diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c
index 1790baee014..bcb95c2ef29 100644
--- a/drivers/media/dvb/frontends/tua6100.c
+++ b/drivers/media/dvb/frontends/tua6100.c
@@ -28,6 +28,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <asm/types.h>
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
index 34c5de491d2..4627f491656 100644
--- a/drivers/media/dvb/frontends/zl10036.c
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/dvb/frontend.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include "zl10036.h"
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index d073c61e3c0..09e9fc78518 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -22,6 +22,7 @@
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c
index 403ce043d00..330216febd7 100644
--- a/drivers/media/dvb/mantis/mantis_ca.c
+++ b/drivers/media/dvb/mantis/mantis_ca.c
@@ -19,6 +19,7 @@
*/
#include <linux/signal.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index 16f1708fd3b..cf4b39ffdaa 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -22,6 +22,7 @@
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index 0150dfe7cfb..645e8b8a713 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/io.h>
#include <asm/div64.h>
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 80d14a065ba..1c798219dc7 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include "demux.h"
#include "dmxdev.h"
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 81e623a90f0..6aded234aa6 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/pci.h>
#include <linux/kthread.h>
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index 4bfd3451b56..0c87a3c3899 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/wait.h>
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 5f3939821ca..b80d09b035a 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include "dmxdev.h"
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c
index 195244a3e69..e57d38b0197 100644
--- a/drivers/media/dvb/siano/smssdio.c
+++ b/drivers/media/dvb/siano/smssdio.c
@@ -33,6 +33,7 @@
*/
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/mmc/card.h>
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 5eac27287d9..a9c27fb69ba 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include "smscoreapi.h"
#include "sms-cards.h"
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index baf3159a3aa..38915591c6e 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -49,6 +49,7 @@
#include <linux/crc32.h>
#include <linux/i2c.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index c7a65b1544a..ac7779c45c5 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -34,6 +34,7 @@
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
+#include <linux/gfp.h>
#include "av7110.h"
#include "av7110_hw.h"
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 000f4d34087..79039674a0e 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -48,6 +48,7 @@
#include <linux/errno.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/io.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index f8213b7c8dd..08f1051979c 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -26,6 +26,7 @@
#include <linux/pci.h>
#include <linux/videodev2.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 44b4dbedb32..4349213b403 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -42,6 +42,7 @@
#include <linux/videodev2.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/io.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 170bbe55478..13554ab13f7 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -27,6 +27,7 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 8e718bfcdad..789d2ec66e1 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -32,6 +32,7 @@
* add RDS support
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h> /* Initdata */
#include <linux/videodev2.h> /* kernel radio structs */
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index 0de457f6e6e..b8bb3ef47df 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -22,6 +22,7 @@
#include <media/v4l2-device.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <media/timb_radio.h>
diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c
index 5db5528a8b2..585680ffbfb 100644
--- a/drivers/media/radio/saa7706h.c
+++ b/drivers/media/radio/saa7706h.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 5466015346a..a5844d08d8b 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -31,6 +31,7 @@
/* kernel includes */
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index 6f60841828d..5ec13e50a9f 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -37,6 +37,7 @@
/* kernel includes */
#include <linux/usb.h>
#include <linux/hid.h>
+#include <linux/slab.h>
#include "radio-si470x.h"
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index 6a0028eb461..ab63dd5b25c 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
index 6e607ff0c16..90cae90277e 100644
--- a/drivers/media/radio/tef6862.c
+++ b/drivers/media/radio/tef6862.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
+#include <linux/slab.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index 97b003449c9..48e89fbf391 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
index cf8c06c85de..f1ba0d742c6 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
index 0826f0dabc1..23e610f6273 100644
--- a/drivers/media/video/adv7180.c
+++ b/drivers/media/video/adv7180.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
+#include <linux/slab.h>
#include <media/v4l2-ioctl.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index df26f2fe44e..41b2930d0ce 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/device.h>
#include <linux/delay.h>
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index 3544a2f12f1..ca342e4c61f 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -20,6 +20,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/mutex.h>
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index b8a4b52e8d4..f1edf1d4afe 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -20,6 +20,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/suspend.h>
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index dc67bc40f36..8c140c01c5e 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -29,6 +29,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/suspend.h>
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index 547e1a93c42..770cb9accf8 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -35,6 +35,7 @@
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index d0b4d4925ff..ae333739250 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index af7e3a5bac9..62ac422bb15 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 12279f6d9bc..716870ae85d 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -4404,7 +4404,7 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input)
/* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning]
*
* The CS16 (available on eBay cheap) is a PCI board with four Fusion
- * 878A chips, a PCI bridge, an Atmel microcontroller, four sync seperator
+ * 878A chips, a PCI bridge, an Atmel microcontroller, four sync separator
* chips, ten eight input analog multiplexors, a not chip and a few
* other components.
*
@@ -4426,7 +4426,7 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input)
*
* There is an ATMEL microcontroller with an 8031 core on board. I have not
* determined what function (if any) it provides. With the microcontroller
- * and sync seperator chips a guess is that it might have to do with video
+ * and sync separator chips a guess is that it might have to do with video
* switching and maybe some digital I/O.
*/
static void tibetCS16_muxsel(struct bttv *btv, unsigned int input)
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index cb46e8fa8aa..f4860f03dfc 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c
index 74c325e594a..fd604d32bbb 100644
--- a/drivers/media/video/bt8xx/bttv-gpio.c
+++ b/drivers/media/video/bt8xx/bttv-gpio.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include "bttvp.h"
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index b320dbd635a..aa153a986ad 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include "bttv.h"
#include "bttvp.h"
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index d16af283637..c24b1c100e1 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index cbbf7e80d2c..be35e696582 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index c431df8248d..f5604c16a09 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/kmod.h>
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 57dc1704b6c..8362db509e2 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 80bca8df9fb..3cc135a98d8 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
index eb41d7ec65b..b5d7cbf4528 100644
--- a/drivers/media/video/cx18/cx18-alsa-main.c
+++ b/drivers/media/video/cx18/cx18-alsa-main.c
@@ -23,6 +23,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 93f0dae0135..7fa589240ff 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -21,6 +21,7 @@
* 02111-1307 USA
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "cx18-driver.h"
#include "cx18-cards.h"
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 23ad6d548dc..b9728e8eee4 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -42,6 +42,7 @@
#include <linux/pagemap.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <linux/dvb/video.h>
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index a5490823500..6bdc0ef1811 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/usb.h>
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index 4a60dfbc347..b24eee115e7 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/vmalloc.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
index 64e025e2bdf..4ea3776b39f 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -20,6 +20,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "cx231xx.h"
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index c5771db3bfc..b473cd8367f 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include "cx231xx.h"
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c
index e97b8023a65..689c5e25776 100644
--- a/drivers/media/video/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/video/cx231xx/cx231xx-vbi.c
@@ -28,6 +28,7 @@
#include <linux/i2c.h>
#include <linux/mm.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index d4f546f11d7..16a73eab672 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -32,6 +32,7 @@
#include <linux/version.h>
#include <linux/mm.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 2ab97ad7b6f..a8ddc227cf8 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -32,6 +32,7 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/cx2341x.h>
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 9c6620f86dc..8e9d990dbe9 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -36,6 +36,7 @@
*/
#include <linux/input.h>
+#include <linux/slab.h>
#include <media/ir-common.h>
#include <media/v4l2-subdev.h>
diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c
index 5b297f0323b..708a8c766d1 100644
--- a/drivers/media/video/cx23885/cx23885-vbi.c
+++ b/drivers/media/video/cx23885/cx23885-vbi.c
@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include "cx23885.h"
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 0e3a98d243c..8d6a55e54ee 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -23,6 +23,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/kdev_t.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/tuner.h>
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
index 2bf57a4527d..ad728d767d6 100644
--- a/drivers/media/video/cx23885/cx23888-ir.c
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -22,6 +22,7 @@
*/
#include <linux/kfifo.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 64b350df78e..33082c96745 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -31,6 +31,7 @@
#include <linux/vmalloc.h>
#include <linux/dma-mapping.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <asm/delay.h>
#include <sound/core.h>
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 6fe30e6c426..e46e1ceef72 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/device.h>
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index eaf0ee7de83..2918a6e38fe 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "cx88.h"
#include "tea5767.h"
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c
index 3e5eaf3fe2a..a94e00a4ac5 100644
--- a/drivers/media/video/cx88/cx88-dsp.c
+++ b/drivers/media/video/cx88/cx88-dsp.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/jiffies.h>
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index de180d4d5a2..6b6abf062c2 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -26,6 +26,7 @@
#include <linux/hrtimer.h>
#include <linux/input.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include "cx88.h"
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 338af77f7f0..6aba7af9160 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -23,6 +23,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index e8316cf7f32..239631568f3 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -39,7 +39,6 @@
#include <linux/errno.h>
#include <linux/freezer.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/signal.h>
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index 0943060682b..d9445b0e7ab 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -3,7 +3,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include "cx88.h"
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
index 20800425c51..794f2932b75 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.c
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -23,6 +23,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
index 0c394cade22..b4cc96dc99e 100644
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -37,6 +37,7 @@
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/videodev2.h>
+#include <linux/gfp.h>
#include <linux/clk.h>
#include <linux/err.h>
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 885cd54499c..7cf042f9b37 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -67,6 +67,7 @@
* - Support for control ioctls
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
index 78130721f57..2e5a7fb2d0c 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -34,6 +34,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/version.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index dfddef7228d..13c3a1b9776 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -30,6 +30,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/version.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <asm/page.h>
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index ecbcefb0873..b0fb0833771 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/usb.h>
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 5a37eccbd7d..a41cc556677 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/vmalloc.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 1b96356b3ab..bcd3c371009 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -20,6 +20,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "em28xx.h"
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 1fb754e2087..20a0001e888 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include "em28xx.h"
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c
index c7dce39823d..7f1c4a2173b 100644
--- a/drivers/media/video/em28xx/em28xx-vbi.c
+++ b/drivers/media/video/em28xx/em28xx-vbi.c
@@ -24,7 +24,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include "em28xx.h"
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index ac2bd935927..0fe20110bfd 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -35,6 +35,7 @@
#include <linux/version.h>
#include <linux/mm.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include "em28xx.h"
#include <media/v4l2-common.h>
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 02c696a22be..8bb242fb79d 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -7,6 +7,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
/* compilation option */
#define GSPCA_DEBUG 1
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index 2019b04f923..84ecd56c647 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -24,6 +24,7 @@
#define MODULE_NAME "jeilinj"
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include "gspca.h"
#include "jpeg.h"
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index fbd91545497..6b3be4fa2c0 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -17,6 +17,7 @@
*/
#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/ov519.c b/drivers/media/video/gspca/ov519.c
index bc4ced6c013..f36e11a0458 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -512,7 +512,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
/*
* The FX2 chip does not give us a zero length read at end of frame.
* It does, however, give a short read at the end of a frame, if
- * neccessary, rather than run two frames together.
+ * necessary, rather than run two frames together.
*
* By choosing the right bulk transfer size, we are guaranteed to always
* get a short read for the last read of each frame. Frame sizes are
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 4a1bc08f82b..38a6e15e096 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -23,6 +23,7 @@
#include <linux/freezer.h>
#include <linux/usb/input.h>
#include <linux/input.h>
+#include <linux/slab.h>
#endif
#include "gspca.h"
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 83d5773d462..1d61b92f6bf 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -22,6 +22,7 @@
#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/sq905.c b/drivers/media/video/gspca/sq905.c
index 1fcaca6a87f..09b3f93fa4d 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -36,6 +36,7 @@
#define MODULE_NAME "sq905"
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include "gspca.h"
MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, "
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index e6466205299..4c70628ca61 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -30,6 +30,7 @@
#define MODULE_NAME "sq905c"
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include "gspca.h"
MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 50986da3d91..7d7814c43f9 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -22,6 +22,7 @@
#define MODULE_NAME "zc3xx"
#include <linux/input.h>
+#include <linux/slab.h>
#include "gspca.h"
#include "jpeg.h"
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index 296330a0e1e..463b81bef6e 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -11,6 +11,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "hdpvr.h"
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index 4a9c8ce0ecb..b59475bfc24 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -18,6 +18,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "ivtv-driver.h"
#include "ivtv-cards.h"
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index e4816da6482..5028e31c564 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -53,6 +53,7 @@
#include <linux/scatterlist.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/byteorder.h>
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index fa6bb85cb4b..de2ff1c6ac3 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -42,6 +42,7 @@
#include <linux/kernel.h>
#include <linux/fb.h>
#include <linux/ivtvfb.h>
+#include <linux/slab.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index fab8e0254bb..94734828053 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -40,6 +40,7 @@
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index d7317e798cc..4491d018eba 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index b421858ccf9..4404e5ef818 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -31,6 +31,7 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/videodev.h>
+#include <linux/gfp.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <asm/uaccess.h>
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 168bca70361..d5a69c5ee5e 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -22,7 +22,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/freezer.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c
index cc85f77a570..72e55be0b4a 100644
--- a/drivers/media/video/mt9v011.c
+++ b/drivers/media/video/mt9v011.c
@@ -6,6 +6,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/delay.h>
#include <asm/div64.h>
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index c167cc3de49..3c8ebfcb742 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -29,6 +29,7 @@
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/time.h>
#include <linux/version.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index 7400eacb4d6..b189fe63394 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -35,6 +35,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
@@ -1735,7 +1736,7 @@ static struct v4l2_int_device omap24xxcam = {
*
*/
-static int __init omap24xxcam_probe(struct platform_device *pdev)
+static int __devinit omap24xxcam_probe(struct platform_device *pdev)
{
struct omap24xxcam_device *cam;
struct resource *mem;
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 0e2184ec994..aaa50f9b8e7 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -12,6 +12,7 @@
*/
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 11a2c26399b..0598bbd3f36 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -25,7 +25,6 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/init.h>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
index 68980e19409..88320900dbd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
@@ -34,7 +34,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/errno.h>
-#include <linux/slab.h>
struct routing_scheme {
const int *def;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 82c13583575..2222da8d0ca 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -36,7 +36,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/errno.h>
-#include <linux/slab.h>
struct routing_scheme_item {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index ae977668c49..e9b11e119f6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -19,7 +19,6 @@
*/
#include <linux/string.h>
-#include <linux/slab.h>
#include "pvrusb2-debugifc.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h"
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
index b7f5c49b1db..8c95793433e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
@@ -20,6 +20,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include "dvbdev.h"
#include "pvrusb2-debug.h"
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
index 299afa4fa96..aeed1c2945f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
@@ -19,6 +19,7 @@
*
*/
+#include <linux/slab.h>
#include "pvrusb2-eeprom.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index 8689ddb5442..eeacd0f6785 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 6c23456e0bd..71f50565f63 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -423,10 +423,12 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
dip = kzalloc(sizeof(*dip),GFP_KERNEL);
if (!dip) return;
+ sysfs_attr_init(&dip->attr_debugcmd.attr);
dip->attr_debugcmd.attr.name = "debugcmd";
dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
dip->attr_debugcmd.show = debugcmd_show;
dip->attr_debugcmd.store = debugcmd_store;
+ sysfs_attr_init(&dip->attr_debuginfo.attr);
dip->attr_debuginfo.attr.name = "debuginfo";
dip->attr_debuginfo.attr.mode = S_IRUGO;
dip->attr_debuginfo.show = debuginfo_show;
@@ -644,6 +646,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
return;
}
+ sysfs_attr_init(&sfp->attr_v4l_minor_number.attr);
sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -658,6 +661,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_minor_number_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr);
sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -672,6 +676,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_radio_minor_number_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_unit_number.attr);
sfp->attr_unit_number.attr.name = "unit_number";
sfp->attr_unit_number.attr.mode = S_IRUGO;
sfp->attr_unit_number.show = unit_number_show;
@@ -685,6 +690,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->unit_number_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_bus_info.attr);
sfp->attr_bus_info.attr.name = "bus_info_str";
sfp->attr_bus_info.attr.mode = S_IRUGO;
sfp->attr_bus_info.show = bus_info_show;
@@ -699,6 +705,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->bus_info_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_hdw_name.attr);
sfp->attr_hdw_name.attr.name = "device_hardware_type";
sfp->attr_hdw_name.attr.mode = S_IRUGO;
sfp->attr_hdw_name.show = hdw_name_show;
@@ -713,6 +720,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->hdw_name_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_hdw_desc.attr);
sfp->attr_hdw_desc.attr.name = "device_hardware_description";
sfp->attr_hdw_desc.attr.mode = S_IRUGO;
sfp->attr_hdw_desc.show = hdw_desc_show;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index cc8ddb2d238..bf1e0fe9f4d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -20,6 +20,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include "pvrusb2-context.h"
#include "pvrusb2-hdw.h"
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 4c96cf48c79..2e205c99eb9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -37,7 +37,6 @@
#include <media/v4l2-common.h>
#include <media/saa7115.h>
#include <linux/errno.h>
-#include <linux/slab.h>
struct routing_scheme {
const int *def;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index 8c1eae05aa0..3ac8d751a5c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -34,7 +34,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/errno.h>
-#include <linux/slab.h>
void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
diff --git a/drivers/media/video/pwc/philips.txt b/drivers/media/video/pwc/philips.txt
index f9f3584281d..d38dd791511 100644
--- a/drivers/media/video/pwc/philips.txt
+++ b/drivers/media/video/pwc/philips.txt
@@ -33,7 +33,7 @@ a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin
contains decompression routines that allow you to use higher image sizes and
framerates; in addition the webcam uses less bandwidth on the USB bus (handy
if you want to run more than 1 camera simultaneously). These routines fall
-under a NDA, and may therefor not be distributed as source; however, its use
+under a NDA, and may therefore not be distributed as source; however, its use
is completely optional.
You can build this code either into your kernel, or as a module. I recommend
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
index 9e2d91f26bf..0c801b8f3ec 100644
--- a/drivers/media/video/pwc/pwc-dec23.c
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -30,6 +30,7 @@
#include <media/pwc-ioctl.h>
#include <linux/string.h>
+#include <linux/slab.h>
/*
* USE_LOOKUP_TABLE_TO_CLAMP
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index bdb4ced5749..62d89b3113a 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -30,7 +30,6 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/poll.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 0902355dfa7..f1b20663295 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -32,6 +32,7 @@
#include <linux/version.h>
#include <linux/mutex.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <asm/errno.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 322ac4eecf0..5ecc30daef2 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -27,6 +27,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index fb742f1ae71..3de914deb8e 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -45,6 +45,7 @@
#include <linux/firmware.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/version.h>
#include <linux/mm.h>
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 5ab6a0f901c..6b3b09ef897 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -43,6 +43,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/videotext.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 12835fb82c9..31ff27df4cb 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -50,6 +50,7 @@
#include <linux/delay.h>
#include <linux/videotext.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 73739d2a63d..4ab4a987c9b 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -24,7 +24,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/suspend.h>
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index ee5bff02a92..ea877a50f52 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -21,7 +21,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 8096dace5f6..da41b6b1e64 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -24,7 +24,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include "saa7134-reg.h"
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 9499000f66b..58a0cdc8414 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include "saa7134-reg.h"
#include "saa7134.h"
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index b9817d74943..2e3f4b412d8 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -24,7 +24,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include "saa7134-reg.h"
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 76b16407b01..3e7d2fd1688 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -25,7 +25,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/freezer.h>
#include <asm/div64.h>
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
index cb0304298a9..e9aa94b807f 100644
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -24,7 +24,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include "saa7134-reg.h"
#include "saa7134.h"
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
index 1d487c15034..3f1262b00cc 100644
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -20,6 +20,7 @@
*/
#include <linux/wait.h>
+#include <linux/slab.h>
#include "saa7164.h"
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
index 9ca5c83d165..5713f3a4b76 100644
--- a/drivers/media/video/saa7164/saa7164-buffer.c
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
+
#include "saa7164.h"
/* The PCI address space for buffer handling looks like this:
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
index ee0af3534ed..270245d275a 100644
--- a/drivers/media/video/saa7164/saa7164-fw.c
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -20,6 +20,7 @@
*/
#include <linux/firmware.h>
+#include <linux/slab.h>
#include "saa7164.h"
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 6818df57116..d521c648e15 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 212baa10829..77db2039291 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index fb88c63188f..6e16b397932 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -27,6 +27,7 @@
#include <linux/moduleparam.h>
#include <linux/time.h>
#include <linux/version.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h
index 4af7382da5c..494957b10ba 100644
--- a/drivers/media/video/sn9c102/sn9c102_sensor.h
+++ b/drivers/media/video/sn9c102/sn9c102_sensor.h
@@ -120,7 +120,7 @@ extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
/*
Write multiple registers with constant values. For example:
sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
- Register adresses must be < 256.
+ Register addresses must be < 256.
*/
#define sn9c102_write_const_regs(sn9c102_device, data...) \
({ static const u8 _valreg[][2] = {data}; \
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 80f6bfa2632..a24174ddec4 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -24,6 +24,7 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <media/soc_camera.h>
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index d381fce3db4..92d22d8931c 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index 1585839bd0b..3021a1e6b7b 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 0446524d354..49dafc5e1e2 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -6,7 +6,7 @@
The tea6420 is a bus controlled audio-matrix with 5 stereo inputs,
4 stereo outputs and gain control for each output.
- It is cascadable, i.e. it can be found at the adresses 0x98
+ It is cascadable, i.e. it can be found at the addresses 0x98
and 0x9a on the i2c-bus.
For detailed informations download the specifications directly
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/video/ths7303.c b/drivers/media/video/ths7303.c
index 21781f8a0e8..61b1dd11836 100644
--- a/drivers/media/video/ths7303.c
+++ b/drivers/media/video/ths7303.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/device.h>
#include <linux/delay.h>
diff --git a/drivers/media/video/tlg2300/pd-alsa.c b/drivers/media/video/tlg2300/pd-alsa.c
index 6f42621ad47..9f8b7da56b6 100644
--- a/drivers/media/video/tlg2300/pd-alsa.c
+++ b/drivers/media/video/tlg2300/pd-alsa.c
@@ -4,10 +4,10 @@
#include <linux/sound.h>
#include <linux/spinlock.h>
#include <linux/soundcard.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/drivers/media/video/tlg2300/pd-dvb.c b/drivers/media/video/tlg2300/pd-dvb.c
index 4133aee568b..ebd9cb5bec7 100644
--- a/drivers/media/video/tlg2300/pd-dvb.c
+++ b/drivers/media/video/tlg2300/pd-dvb.c
@@ -3,6 +3,7 @@
#include <linux/usb.h>
#include <linux/dvb/dmx.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include "vendorcmds.h"
#include <linux/sched.h>
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
index becfba6a304..cf8f18c007e 100644
--- a/drivers/media/video/tlg2300/pd-video.c
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -4,6 +4,7 @@
#include <linux/usb.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-dev.h>
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 07789c64814..9ddb32bc7af 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 26b4e718cd6..e4815a1806e 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -29,6 +29,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 2d38e253f14..908ffb68e92 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -6,6 +6,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/delay.h>
#include <media/v4l2-device.h>
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index 5a878bca02d..4a69bcc738f 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -26,6 +26,7 @@
*/
#include <linux/delay.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/tvp7002.h>
#include <media/v4l2-device.h>
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index a07a3fbb51e..36c0c461d8b 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 6eb0e5b00c3..c5af93b30a2 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index a0addcb0429..562e1d170be 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
+#include <linux/gfp.h>
#include "usbvideo.h"
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index c4d1b96b5ce..fab48ec6c0e 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/usb/input.h>
+#include <linux/slab.h>
#include "usbvideo.h"
#include "quickcam_messenger.h"
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index e0f91e4ab65..f7aae229375 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -26,7 +26,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/timer.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/vmalloc.h>
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 0613922997e..083765238a6 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 3b2e7800d56..6d3850b3716 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index a814820a3f6..86ff8c12ea5 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index 1ca6dff7361..85019bdacdf 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 43152aa5222..7c9ab293349 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -15,6 +15,7 @@
#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 6b0666be370..821a9969b7b 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 4b11257c318..7d59c107f13 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -13,6 +13,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 22c01097e8a..dce4f3aa4af 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -20,6 +20,7 @@
#include <linux/pagemap.h>
#include <linux/dma-mapping.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <media/videobuf-dma-contig.h>
struct videobuf_dma_contig_memory {
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index a56cf0d3a6d..0afb62e63d9 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -19,6 +19,7 @@
#include <linux/fs.h>
#include <linux/kthread.h>
#include <linux/file.h>
+#include <linux/slab.h>
#include <linux/freezer.h>
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index a15d1e7cbed..3eb15f72ac0 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -33,6 +33,7 @@
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/time.h>
#include <linux/version.h>
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index 38e53b303cc..ca8303bd240 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 33205d7537d..77ebcea7c3d 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index dcade619cbd..bf9bf650a31 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -58,6 +58,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/videodev.h>
+#include <linux/slab.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <linux/parport.h>
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index b572ce288e1..a11b99b4226 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index f1f261a3524..5c2ba599c0c 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index be70574870d..bfcd3aef50f 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/i2c.h>
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index b3bf1c44d74..c00fe8253c5 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -16,6 +16,7 @@
#include <linux/idr.h>
#include <linux/fs.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#define DRIVER_NAME "memstick"
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 972b87069d5..8327e248520 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -17,6 +17,7 @@
#include <linux/hdreg.h>
#include <linux/kthread.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/memstick.h>
#define DRIVER_NAME "mspro_block"
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index f4a162a4bec..f2b894cd8b0 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/highmem.h>
#include <linux/memstick.h>
+#include <linux/slab.h>
#define DRIVER_NAME "jmb38x_ms"
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 612ab3c51a6..33f7256055b 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -54,6 +54,7 @@
#include <linux/reboot.h> /* notifier code */
#include <linux/workqueue.h>
#include <linux/sort.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 34f3f36f819..4fa9665cbe9 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -57,6 +57,7 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#define my_VERSION MPT_LINUX_VERSION_COMMON
#define MYNAM "mptlan"
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index c20bbe45da8..76687126b57 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -45,6 +45,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/jiffies.h>
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 4a7d1afcb66..6796597dcee 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -46,6 +46,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/kdev_t.h>
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 69f4257419b..e44365193fd 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -46,6 +46,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/kdev_t.h>
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 2658b1484a2..fc593fbab69 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -51,6 +51,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/i2o.h>
#include <linux/mempool.h>
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 3d5f40cd69d..11073fa3d9f 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -33,6 +33,7 @@
#include <linux/miscdevice.h>
#include <linux/smp_lock.h>
#include <linux/compat.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index 949a648f8e2..07dbeaf9df9 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -40,6 +40,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/i2o.h>
+#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index e5ab6214150..090d2a3a654 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -29,6 +29,7 @@
#include <linux/i2o.h>
#include <linux/delay.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "core.h"
#define OSM_NAME "i2o"
@@ -539,7 +540,7 @@ static int i2o_iop_reset(struct i2o_controller *c)
* which is indeterminate. We need to wait until the IOP has
* rebooted before we can let the system talk to it. We read
* the inbound Free_List until a message is available. If we
- * can't read one in the given ammount of time, we assume the
+ * can't read one in the given amount of time, we assume the
* IOP could not reboot properly.
*/
osm_debug("%s: Reset in progress, waiting for reboot...\n",
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 35ba2ae38b4..73e4658af53 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -29,6 +29,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/i2o.h>
#include "core.h"
diff --git a/drivers/mfd/88pm8607.c b/drivers/mfd/88pm8607.c
deleted file mode 100644
index 7e3f6590799..00000000000
--- a/drivers/mfd/88pm8607.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Base driver for Marvell 88PM8607
- *
- * Copyright (C) 2009 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/88pm8607.h>
-
-
-#define PM8607_REG_RESOURCE(_start, _end) \
-{ \
- .start = PM8607_##_start, \
- .end = PM8607_##_end, \
- .flags = IORESOURCE_IO, \
-}
-
-static struct resource pm8607_regulator_resources[] = {
- PM8607_REG_RESOURCE(BUCK1, BUCK1),
- PM8607_REG_RESOURCE(BUCK2, BUCK2),
- PM8607_REG_RESOURCE(BUCK3, BUCK3),
- PM8607_REG_RESOURCE(LDO1, LDO1),
- PM8607_REG_RESOURCE(LDO2, LDO2),
- PM8607_REG_RESOURCE(LDO3, LDO3),
- PM8607_REG_RESOURCE(LDO4, LDO4),
- PM8607_REG_RESOURCE(LDO5, LDO5),
- PM8607_REG_RESOURCE(LDO6, LDO6),
- PM8607_REG_RESOURCE(LDO7, LDO7),
- PM8607_REG_RESOURCE(LDO8, LDO8),
- PM8607_REG_RESOURCE(LDO9, LDO9),
- PM8607_REG_RESOURCE(LDO10, LDO10),
- PM8607_REG_RESOURCE(LDO12, LDO12),
- PM8607_REG_RESOURCE(LDO14, LDO14),
-};
-
-#define PM8607_REG_DEVS(_name, _id) \
-{ \
- .name = "88pm8607-" #_name, \
- .num_resources = 1, \
- .resources = &pm8607_regulator_resources[PM8607_ID_##_id], \
-}
-
-static struct mfd_cell pm8607_devs[] = {
- PM8607_REG_DEVS(buck1, BUCK1),
- PM8607_REG_DEVS(buck2, BUCK2),
- PM8607_REG_DEVS(buck3, BUCK3),
- PM8607_REG_DEVS(ldo1, LDO1),
- PM8607_REG_DEVS(ldo2, LDO2),
- PM8607_REG_DEVS(ldo3, LDO3),
- PM8607_REG_DEVS(ldo4, LDO4),
- PM8607_REG_DEVS(ldo5, LDO5),
- PM8607_REG_DEVS(ldo6, LDO6),
- PM8607_REG_DEVS(ldo7, LDO7),
- PM8607_REG_DEVS(ldo8, LDO8),
- PM8607_REG_DEVS(ldo9, LDO9),
- PM8607_REG_DEVS(ldo10, LDO10),
- PM8607_REG_DEVS(ldo12, LDO12),
- PM8607_REG_DEVS(ldo14, LDO14),
-};
-
-static inline int pm8607_read_device(struct pm8607_chip *chip,
- int reg, int bytes, void *dest)
-{
- struct i2c_client *i2c = chip->client;
- unsigned char data;
- int ret;
-
- data = (unsigned char)reg;
- ret = i2c_master_send(i2c, &data, 1);
- if (ret < 0)
- return ret;
-
- ret = i2c_master_recv(i2c, dest, bytes);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static inline int pm8607_write_device(struct pm8607_chip *chip,
- int reg, int bytes, void *src)
-{
- struct i2c_client *i2c = chip->client;
- unsigned char buf[bytes + 1];
- int ret;
-
- buf[0] = (unsigned char)reg;
- memcpy(&buf[1], src, bytes);
-
- ret = i2c_master_send(i2c, buf, bytes + 1);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-int pm8607_reg_read(struct pm8607_chip *chip, int reg)
-{
- unsigned char data;
- int ret;
-
- mutex_lock(&chip->io_lock);
- ret = chip->read(chip, reg, 1, &data);
- mutex_unlock(&chip->io_lock);
-
- if (ret < 0)
- return ret;
- else
- return (int)data;
-}
-EXPORT_SYMBOL(pm8607_reg_read);
-
-int pm8607_reg_write(struct pm8607_chip *chip, int reg,
- unsigned char data)
-{
- int ret;
-
- mutex_lock(&chip->io_lock);
- ret = chip->write(chip, reg, 1, &data);
- mutex_unlock(&chip->io_lock);
-
- return ret;
-}
-EXPORT_SYMBOL(pm8607_reg_write);
-
-int pm8607_bulk_read(struct pm8607_chip *chip, int reg,
- int count, unsigned char *buf)
-{
- int ret;
-
- mutex_lock(&chip->io_lock);
- ret = chip->read(chip, reg, count, buf);
- mutex_unlock(&chip->io_lock);
-
- return ret;
-}
-EXPORT_SYMBOL(pm8607_bulk_read);
-
-int pm8607_bulk_write(struct pm8607_chip *chip, int reg,
- int count, unsigned char *buf)
-{
- int ret;
-
- mutex_lock(&chip->io_lock);
- ret = chip->write(chip, reg, count, buf);
- mutex_unlock(&chip->io_lock);
-
- return ret;
-}
-EXPORT_SYMBOL(pm8607_bulk_write);
-
-int pm8607_set_bits(struct pm8607_chip *chip, int reg,
- unsigned char mask, unsigned char data)
-{
- unsigned char value;
- int ret;
-
- mutex_lock(&chip->io_lock);
- ret = chip->read(chip, reg, 1, &value);
- if (ret < 0)
- goto out;
- value &= ~mask;
- value |= data;
- ret = chip->write(chip, reg, 1, &value);
-out:
- mutex_unlock(&chip->io_lock);
- return ret;
-}
-EXPORT_SYMBOL(pm8607_set_bits);
-
-
-static const struct i2c_device_id pm8607_id_table[] = {
- { "88PM8607", 0 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, pm8607_id_table);
-
-
-static int __devinit pm8607_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct pm8607_platform_data *pdata = client->dev.platform_data;
- struct pm8607_chip *chip;
- int i, count;
- int ret;
-
- chip = kzalloc(sizeof(struct pm8607_chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
- chip->client = client;
- chip->dev = &client->dev;
- chip->read = pm8607_read_device;
- chip->write = pm8607_write_device;
- i2c_set_clientdata(client, chip);
-
- mutex_init(&chip->io_lock);
- dev_set_drvdata(chip->dev, chip);
-
- ret = pm8607_reg_read(chip, PM8607_CHIP_ID);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
- goto out;
- }
- if ((ret & CHIP_ID_MASK) == CHIP_ID)
- dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
- ret);
- else {
- dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
- "Chip ID: %02x\n", ret);
- goto out;
- }
- chip->chip_id = ret;
-
- ret = pm8607_reg_read(chip, PM8607_BUCK3);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
- goto out;
- }
- if (ret & PM8607_BUCK3_DOUBLE)
- chip->buck3_double = 1;
-
- ret = pm8607_reg_read(chip, PM8607_MISC1);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
- goto out;
- }
- if (pdata->i2c_port == PI2C_PORT)
- ret |= PM8607_MISC1_PI2C;
- else
- ret &= ~PM8607_MISC1_PI2C;
- ret = pm8607_reg_write(chip, PM8607_MISC1, ret);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to write MISC1 register: %d\n", ret);
- goto out;
- }
-
-
- count = ARRAY_SIZE(pm8607_devs);
- for (i = 0; i < count; i++) {
- ret = mfd_add_devices(chip->dev, i, &pm8607_devs[i],
- 1, NULL, 0);
- if (ret != 0) {
- dev_err(chip->dev, "Failed to add subdevs\n");
- goto out;
- }
- }
-
- return 0;
-
-out:
- i2c_set_clientdata(client, NULL);
- kfree(chip);
- return ret;
-}
-
-static int __devexit pm8607_remove(struct i2c_client *client)
-{
- struct pm8607_chip *chip = i2c_get_clientdata(client);
-
- mfd_remove_devices(chip->dev);
- kfree(chip);
- return 0;
-}
-
-static struct i2c_driver pm8607_driver = {
- .driver = {
- .name = "88PM8607",
- .owner = THIS_MODULE,
- },
- .probe = pm8607_probe,
- .remove = __devexit_p(pm8607_remove),
- .id_table = pm8607_id_table,
-};
-
-static int __init pm8607_init(void)
-{
- int ret;
- ret = i2c_add_driver(&pm8607_driver);
- if (ret != 0)
- pr_err("Failed to register 88PM8607 I2C driver: %d\n", ret);
- return ret;
-}
-subsys_initcall(pm8607_init);
-
-static void __exit pm8607_exit(void)
-{
- i2c_del_driver(&pm8607_driver);
-}
-module_exit(pm8607_exit);
-
-MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM8607");
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
new file mode 100644
index 00000000000..6a14d2b1ccf
--- /dev/null
+++ b/drivers/mfd/88pm860x-core.c
@@ -0,0 +1,740 @@
+/*
+ * Base driver for Marvell 88PM8607
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/88pm860x.h>
+
+#define INT_STATUS_NUM 3
+
+char pm860x_backlight_name[][MFD_NAME_SIZE] = {
+ "backlight-0",
+ "backlight-1",
+ "backlight-2",
+};
+EXPORT_SYMBOL(pm860x_backlight_name);
+
+char pm860x_led_name[][MFD_NAME_SIZE] = {
+ "led0-red",
+ "led0-green",
+ "led0-blue",
+ "led1-red",
+ "led1-green",
+ "led1-blue",
+};
+EXPORT_SYMBOL(pm860x_led_name);
+
+#define PM8606_BACKLIGHT_RESOURCE(_i, _x) \
+{ \
+ .name = pm860x_backlight_name[_i], \
+ .start = PM8606_##_x, \
+ .end = PM8606_##_x, \
+ .flags = IORESOURCE_IO, \
+}
+
+static struct resource backlight_resources[] = {
+ PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT1, WLED1A),
+ PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT2, WLED2A),
+ PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT3, WLED3A),
+};
+
+#define PM8606_BACKLIGHT_DEVS(_i) \
+{ \
+ .name = "88pm860x-backlight", \
+ .num_resources = 1, \
+ .resources = &backlight_resources[_i], \
+ .id = _i, \
+}
+
+static struct mfd_cell backlight_devs[] = {
+ PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT1),
+ PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT2),
+ PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT3),
+};
+
+#define PM8606_LED_RESOURCE(_i, _x) \
+{ \
+ .name = pm860x_led_name[_i], \
+ .start = PM8606_##_x, \
+ .end = PM8606_##_x, \
+ .flags = IORESOURCE_IO, \
+}
+
+static struct resource led_resources[] = {
+ PM8606_LED_RESOURCE(PM8606_LED1_RED, RGB2B),
+ PM8606_LED_RESOURCE(PM8606_LED1_GREEN, RGB2C),
+ PM8606_LED_RESOURCE(PM8606_LED1_BLUE, RGB2D),
+ PM8606_LED_RESOURCE(PM8606_LED2_RED, RGB1B),
+ PM8606_LED_RESOURCE(PM8606_LED2_GREEN, RGB1C),
+ PM8606_LED_RESOURCE(PM8606_LED2_BLUE, RGB1D),
+};
+
+#define PM8606_LED_DEVS(_i) \
+{ \
+ .name = "88pm860x-led", \
+ .num_resources = 1, \
+ .resources = &led_resources[_i], \
+ .id = _i, \
+}
+
+static struct mfd_cell led_devs[] = {
+ PM8606_LED_DEVS(PM8606_LED1_RED),
+ PM8606_LED_DEVS(PM8606_LED1_GREEN),
+ PM8606_LED_DEVS(PM8606_LED1_BLUE),
+ PM8606_LED_DEVS(PM8606_LED2_RED),
+ PM8606_LED_DEVS(PM8606_LED2_GREEN),
+ PM8606_LED_DEVS(PM8606_LED2_BLUE),
+};
+
+static struct resource touch_resources[] = {
+ {
+ .start = PM8607_IRQ_PEN,
+ .end = PM8607_IRQ_PEN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell touch_devs[] = {
+ {
+ .name = "88pm860x-touch",
+ .num_resources = 1,
+ .resources = &touch_resources[0],
+ },
+};
+
+#define PM8607_REG_RESOURCE(_start, _end) \
+{ \
+ .start = PM8607_##_start, \
+ .end = PM8607_##_end, \
+ .flags = IORESOURCE_IO, \
+}
+
+static struct resource power_supply_resources[] = {
+ {
+ .name = "88pm860x-power",
+ .start = PM8607_IRQ_CHG,
+ .end = PM8607_IRQ_CHG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell power_devs[] = {
+ {
+ .name = "88pm860x-power",
+ .num_resources = 1,
+ .resources = &power_supply_resources[0],
+ .id = -1,
+ },
+};
+
+static struct resource onkey_resources[] = {
+ {
+ .name = "88pm860x-onkey",
+ .start = PM8607_IRQ_ONKEY,
+ .end = PM8607_IRQ_ONKEY,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell onkey_devs[] = {
+ {
+ .name = "88pm860x-onkey",
+ .num_resources = 1,
+ .resources = &onkey_resources[0],
+ .id = -1,
+ },
+};
+
+static struct resource regulator_resources[] = {
+ PM8607_REG_RESOURCE(BUCK1, BUCK1),
+ PM8607_REG_RESOURCE(BUCK2, BUCK2),
+ PM8607_REG_RESOURCE(BUCK3, BUCK3),
+ PM8607_REG_RESOURCE(LDO1, LDO1),
+ PM8607_REG_RESOURCE(LDO2, LDO2),
+ PM8607_REG_RESOURCE(LDO3, LDO3),
+ PM8607_REG_RESOURCE(LDO4, LDO4),
+ PM8607_REG_RESOURCE(LDO5, LDO5),
+ PM8607_REG_RESOURCE(LDO6, LDO6),
+ PM8607_REG_RESOURCE(LDO7, LDO7),
+ PM8607_REG_RESOURCE(LDO8, LDO8),
+ PM8607_REG_RESOURCE(LDO9, LDO9),
+ PM8607_REG_RESOURCE(LDO10, LDO10),
+ PM8607_REG_RESOURCE(LDO12, LDO12),
+ PM8607_REG_RESOURCE(LDO14, LDO14),
+};
+
+#define PM8607_REG_DEVS(_name, _id) \
+{ \
+ .name = "88pm8607-" #_name, \
+ .num_resources = 1, \
+ .resources = &regulator_resources[PM8607_ID_##_id], \
+ .id = PM8607_ID_##_id, \
+}
+
+static struct mfd_cell regulator_devs[] = {
+ PM8607_REG_DEVS(buck1, BUCK1),
+ PM8607_REG_DEVS(buck2, BUCK2),
+ PM8607_REG_DEVS(buck3, BUCK3),
+ PM8607_REG_DEVS(ldo1, LDO1),
+ PM8607_REG_DEVS(ldo2, LDO2),
+ PM8607_REG_DEVS(ldo3, LDO3),
+ PM8607_REG_DEVS(ldo4, LDO4),
+ PM8607_REG_DEVS(ldo5, LDO5),
+ PM8607_REG_DEVS(ldo6, LDO6),
+ PM8607_REG_DEVS(ldo7, LDO7),
+ PM8607_REG_DEVS(ldo8, LDO8),
+ PM8607_REG_DEVS(ldo9, LDO9),
+ PM8607_REG_DEVS(ldo10, LDO10),
+ PM8607_REG_DEVS(ldo12, LDO12),
+ PM8607_REG_DEVS(ldo14, LDO14),
+};
+
+struct pm860x_irq_data {
+ int reg;
+ int mask_reg;
+ int enable; /* enable or not */
+ int offs; /* bit offset in mask register */
+};
+
+static struct pm860x_irq_data pm860x_irqs[] = {
+ [PM8607_IRQ_ONKEY] = {
+ .reg = PM8607_INT_STATUS1,
+ .mask_reg = PM8607_INT_MASK_1,
+ .offs = 1 << 0,
+ },
+ [PM8607_IRQ_EXTON] = {
+ .reg = PM8607_INT_STATUS1,
+ .mask_reg = PM8607_INT_MASK_1,
+ .offs = 1 << 1,
+ },
+ [PM8607_IRQ_CHG] = {
+ .reg = PM8607_INT_STATUS1,
+ .mask_reg = PM8607_INT_MASK_1,
+ .offs = 1 << 2,
+ },
+ [PM8607_IRQ_BAT] = {
+ .reg = PM8607_INT_STATUS1,
+ .mask_reg = PM8607_INT_MASK_1,
+ .offs = 1 << 3,
+ },
+ [PM8607_IRQ_RTC] = {
+ .reg = PM8607_INT_STATUS1,
+ .mask_reg = PM8607_INT_MASK_1,
+ .offs = 1 << 4,
+ },
+ [PM8607_IRQ_CC] = {
+ .reg = PM8607_INT_STATUS1,
+ .mask_reg = PM8607_INT_MASK_1,
+ .offs = 1 << 5,
+ },
+ [PM8607_IRQ_VBAT] = {
+ .reg = PM8607_INT_STATUS2,
+ .mask_reg = PM8607_INT_MASK_2,
+ .offs = 1 << 0,
+ },
+ [PM8607_IRQ_VCHG] = {
+ .reg = PM8607_INT_STATUS2,
+ .mask_reg = PM8607_INT_MASK_2,
+ .offs = 1 << 1,
+ },
+ [PM8607_IRQ_VSYS] = {
+ .reg = PM8607_INT_STATUS2,
+ .mask_reg = PM8607_INT_MASK_2,
+ .offs = 1 << 2,
+ },
+ [PM8607_IRQ_TINT] = {
+ .reg = PM8607_INT_STATUS2,
+ .mask_reg = PM8607_INT_MASK_2,
+ .offs = 1 << 3,
+ },
+ [PM8607_IRQ_GPADC0] = {
+ .reg = PM8607_INT_STATUS2,
+ .mask_reg = PM8607_INT_MASK_2,
+ .offs = 1 << 4,
+ },
+ [PM8607_IRQ_GPADC1] = {
+ .reg = PM8607_INT_STATUS2,
+ .mask_reg = PM8607_INT_MASK_2,
+ .offs = 1 << 5,
+ },
+ [PM8607_IRQ_GPADC2] = {
+ .reg = PM8607_INT_STATUS2,
+ .mask_reg = PM8607_INT_MASK_2,
+ .offs = 1 << 6,
+ },
+ [PM8607_IRQ_GPADC3] = {
+ .reg = PM8607_INT_STATUS2,
+ .mask_reg = PM8607_INT_MASK_2,
+ .offs = 1 << 7,
+ },
+ [PM8607_IRQ_AUDIO_SHORT] = {
+ .reg = PM8607_INT_STATUS3,
+ .mask_reg = PM8607_INT_MASK_3,
+ .offs = 1 << 0,
+ },
+ [PM8607_IRQ_PEN] = {
+ .reg = PM8607_INT_STATUS3,
+ .mask_reg = PM8607_INT_MASK_3,
+ .offs = 1 << 1,
+ },
+ [PM8607_IRQ_HEADSET] = {
+ .reg = PM8607_INT_STATUS3,
+ .mask_reg = PM8607_INT_MASK_3,
+ .offs = 1 << 2,
+ },
+ [PM8607_IRQ_HOOK] = {
+ .reg = PM8607_INT_STATUS3,
+ .mask_reg = PM8607_INT_MASK_3,
+ .offs = 1 << 3,
+ },
+ [PM8607_IRQ_MICIN] = {
+ .reg = PM8607_INT_STATUS3,
+ .mask_reg = PM8607_INT_MASK_3,
+ .offs = 1 << 4,
+ },
+ [PM8607_IRQ_CHG_FAIL] = {
+ .reg = PM8607_INT_STATUS3,
+ .mask_reg = PM8607_INT_MASK_3,
+ .offs = 1 << 5,
+ },
+ [PM8607_IRQ_CHG_DONE] = {
+ .reg = PM8607_INT_STATUS3,
+ .mask_reg = PM8607_INT_MASK_3,
+ .offs = 1 << 6,
+ },
+ [PM8607_IRQ_CHG_FAULT] = {
+ .reg = PM8607_INT_STATUS3,
+ .mask_reg = PM8607_INT_MASK_3,
+ .offs = 1 << 7,
+ },
+};
+
+static inline struct pm860x_irq_data *irq_to_pm860x(struct pm860x_chip *chip,
+ int irq)
+{
+ return &pm860x_irqs[irq - chip->irq_base];
+}
+
+static irqreturn_t pm860x_irq(int irq, void *data)
+{
+ struct pm860x_chip *chip = data;
+ struct pm860x_irq_data *irq_data;
+ struct i2c_client *i2c;
+ int read_reg = -1, value = 0;
+ int i;
+
+ i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+ for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
+ irq_data = &pm860x_irqs[i];
+ if (read_reg != irq_data->reg) {
+ read_reg = irq_data->reg;
+ value = pm860x_reg_read(i2c, irq_data->reg);
+ }
+ if (value & irq_data->enable)
+ handle_nested_irq(chip->irq_base + i);
+ }
+ return IRQ_HANDLED;
+}
+
+static void pm860x_irq_lock(unsigned int irq)
+{
+ struct pm860x_chip *chip = get_irq_chip_data(irq);
+
+ mutex_lock(&chip->irq_lock);
+}
+
+static void pm860x_irq_sync_unlock(unsigned int irq)
+{
+ struct pm860x_chip *chip = get_irq_chip_data(irq);
+ struct pm860x_irq_data *irq_data;
+ struct i2c_client *i2c;
+ static unsigned char cached[3] = {0x0, 0x0, 0x0};
+ unsigned char mask[3];
+ int i;
+
+ i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+ /* Load cached value. In initial, all IRQs are masked */
+ for (i = 0; i < 3; i++)
+ mask[i] = cached[i];
+ for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
+ irq_data = &pm860x_irqs[i];
+ switch (irq_data->mask_reg) {
+ case PM8607_INT_MASK_1:
+ mask[0] &= ~irq_data->offs;
+ mask[0] |= irq_data->enable;
+ break;
+ case PM8607_INT_MASK_2:
+ mask[1] &= ~irq_data->offs;
+ mask[1] |= irq_data->enable;
+ break;
+ case PM8607_INT_MASK_3:
+ mask[2] &= ~irq_data->offs;
+ mask[2] |= irq_data->enable;
+ break;
+ default:
+ dev_err(chip->dev, "wrong IRQ\n");
+ break;
+ }
+ }
+ /* update mask into registers */
+ for (i = 0; i < 3; i++) {
+ if (mask[i] != cached[i]) {
+ cached[i] = mask[i];
+ pm860x_reg_write(i2c, PM8607_INT_MASK_1 + i, mask[i]);
+ }
+ }
+
+ mutex_unlock(&chip->irq_lock);
+}
+
+static void pm860x_irq_enable(unsigned int irq)
+{
+ struct pm860x_chip *chip = get_irq_chip_data(irq);
+ pm860x_irqs[irq - chip->irq_base].enable
+ = pm860x_irqs[irq - chip->irq_base].offs;
+}
+
+static void pm860x_irq_disable(unsigned int irq)
+{
+ struct pm860x_chip *chip = get_irq_chip_data(irq);
+ pm860x_irqs[irq - chip->irq_base].enable = 0;
+}
+
+static struct irq_chip pm860x_irq_chip = {
+ .name = "88pm860x",
+ .bus_lock = pm860x_irq_lock,
+ .bus_sync_unlock = pm860x_irq_sync_unlock,
+ .enable = pm860x_irq_enable,
+ .disable = pm860x_irq_disable,
+};
+
+static int __devinit device_gpadc_init(struct pm860x_chip *chip,
+ struct pm860x_platform_data *pdata)
+{
+ struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+ : chip->companion;
+ int use_gpadc = 0, data, ret;
+
+ /* initialize GPADC without activating it */
+
+ if (pdata && pdata->touch) {
+ /* set GPADC MISC1 register */
+ data = 0;
+ data |= (pdata->touch->gpadc_prebias << 1)
+ & PM8607_GPADC_PREBIAS_MASK;
+ data |= (pdata->touch->slot_cycle << 3)
+ & PM8607_GPADC_SLOT_CYCLE_MASK;
+ data |= (pdata->touch->off_scale << 5)
+ & PM8607_GPADC_OFF_SCALE_MASK;
+ data |= (pdata->touch->sw_cal << 7)
+ & PM8607_GPADC_SW_CAL_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
+ if (ret < 0)
+ goto out;
+ }
+ /* set tsi prebias time */
+ if (pdata->touch->tsi_prebias) {
+ data = pdata->touch->tsi_prebias;
+ ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
+ if (ret < 0)
+ goto out;
+ }
+ /* set prebias & prechg time of pen detect */
+ data = 0;
+ data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK;
+ data |= (pdata->touch->pen_prechg << 5)
+ & PM8607_PD_PRECHG_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
+ if (ret < 0)
+ goto out;
+ }
+
+ use_gpadc = 1;
+ }
+
+ /* turn on GPADC */
+ if (use_gpadc) {
+ ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1,
+ PM8607_GPADC_EN, PM8607_GPADC_EN);
+ }
+out:
+ return ret;
+}
+
+static int __devinit device_irq_init(struct pm860x_chip *chip,
+ struct pm860x_platform_data *pdata)
+{
+ struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+ : chip->companion;
+ unsigned char status_buf[INT_STATUS_NUM];
+ unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+ struct irq_desc *desc;
+ int i, data, mask, ret = -EINVAL;
+ int __irq;
+
+ if (!pdata || !pdata->irq_base) {
+ dev_warn(chip->dev, "No interrupt support on IRQ base\n");
+ return -EINVAL;
+ }
+
+ mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
+ | PM8607_B0_MISC1_INT_MASK;
+ data = 0;
+ chip->irq_mode = 0;
+ if (pdata && pdata->irq_mode) {
+ /*
+ * irq_mode defines the way of clearing interrupt. If it's 1,
+ * clear IRQ by write. Otherwise, clear it by read.
+ * This control bit is valid from 88PM8607 B0 steping.
+ */
+ data |= PM8607_B0_MISC1_INT_CLEAR;
+ chip->irq_mode = 1;
+ }
+ ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, mask, data);
+ if (ret < 0)
+ goto out;
+
+ /* mask all IRQs */
+ memset(status_buf, 0, INT_STATUS_NUM);
+ ret = pm860x_bulk_write(i2c, PM8607_INT_MASK_1,
+ INT_STATUS_NUM, status_buf);
+ if (ret < 0)
+ goto out;
+
+ if (chip->irq_mode) {
+ /* clear interrupt status by write */
+ memset(status_buf, 0xFF, INT_STATUS_NUM);
+ ret = pm860x_bulk_write(i2c, PM8607_INT_STATUS1,
+ INT_STATUS_NUM, status_buf);
+ } else {
+ /* clear interrupt status by read */
+ ret = pm860x_bulk_read(i2c, PM8607_INT_STATUS1,
+ INT_STATUS_NUM, status_buf);
+ }
+ if (ret < 0)
+ goto out;
+
+ mutex_init(&chip->irq_lock);
+ chip->irq_base = pdata->irq_base;
+ chip->core_irq = i2c->irq;
+ if (!chip->core_irq)
+ goto out;
+
+ desc = irq_to_desc(chip->core_irq);
+
+ /* register IRQ by genirq */
+ for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
+ __irq = i + chip->irq_base;
+ set_irq_chip_data(__irq, chip);
+ set_irq_chip_and_handler(__irq, &pm860x_irq_chip,
+ handle_edge_irq);
+ set_irq_nested_thread(__irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(__irq, IRQF_VALID);
+#else
+ set_irq_noprobe(__irq);
+#endif
+ }
+
+ ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags,
+ "88pm860x", chip);
+ if (ret) {
+ dev_err(chip->dev, "Failed to request IRQ: %d\n", ret);
+ chip->core_irq = 0;
+ }
+
+ return 0;
+out:
+ chip->core_irq = 0;
+ return ret;
+}
+
+static void __devexit device_irq_exit(struct pm860x_chip *chip)
+{
+ if (chip->core_irq)
+ free_irq(chip->core_irq, chip);
+}
+
+static void __devinit device_8606_init(struct pm860x_chip *chip,
+ struct i2c_client *i2c,
+ struct pm860x_platform_data *pdata)
+{
+ int ret;
+
+ if (pdata && pdata->backlight) {
+ ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
+ ARRAY_SIZE(backlight_devs),
+ &backlight_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add backlight "
+ "subdev\n");
+ goto out_dev;
+ }
+ }
+
+ if (pdata && pdata->led) {
+ ret = mfd_add_devices(chip->dev, 0, &led_devs[0],
+ ARRAY_SIZE(led_devs),
+ &led_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add led "
+ "subdev\n");
+ goto out_dev;
+ }
+ }
+ return;
+out_dev:
+ mfd_remove_devices(chip->dev);
+ device_irq_exit(chip);
+}
+
+static void __devinit device_8607_init(struct pm860x_chip *chip,
+ struct i2c_client *i2c,
+ struct pm860x_platform_data *pdata)
+{
+ int data, ret;
+
+ ret = pm860x_reg_read(i2c, PM8607_CHIP_ID);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
+ goto out;
+ }
+ if ((ret & PM8607_VERSION_MASK) == PM8607_VERSION)
+ dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
+ ret);
+ else {
+ dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
+ "Chip ID: %02x\n", ret);
+ goto out;
+ }
+
+ ret = pm860x_reg_read(i2c, PM8607_BUCK3);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
+ goto out;
+ }
+ if (ret & PM8607_BUCK3_DOUBLE)
+ chip->buck3_double = 1;
+
+ ret = pm860x_reg_read(i2c, PM8607_B0_MISC1);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
+ goto out;
+ }
+
+ if (pdata && (pdata->i2c_port == PI2C_PORT))
+ data = PM8607_B0_MISC1_PI2C;
+ else
+ data = 0;
+ ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, PM8607_B0_MISC1_PI2C, data);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to access MISC1:%d\n", ret);
+ goto out;
+ }
+
+ ret = device_gpadc_init(chip, pdata);
+ if (ret < 0)
+ goto out;
+
+ ret = device_irq_init(chip, pdata);
+ if (ret < 0)
+ goto out;
+
+ ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
+ ARRAY_SIZE(regulator_devs),
+ &regulator_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add regulator subdev\n");
+ goto out_dev;
+ }
+
+ if (pdata && pdata->touch) {
+ ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
+ ARRAY_SIZE(touch_devs),
+ &touch_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add touch "
+ "subdev\n");
+ goto out_dev;
+ }
+ }
+
+ if (pdata && pdata->power) {
+ ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
+ ARRAY_SIZE(power_devs),
+ &power_supply_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add power supply "
+ "subdev\n");
+ goto out_dev;
+ }
+ }
+
+ ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
+ ARRAY_SIZE(onkey_devs),
+ &onkey_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add onkey subdev\n");
+ goto out_dev;
+ }
+
+ return;
+out_dev:
+ mfd_remove_devices(chip->dev);
+ device_irq_exit(chip);
+out:
+ return;
+}
+
+int pm860x_device_init(struct pm860x_chip *chip,
+ struct pm860x_platform_data *pdata)
+{
+ chip->core_irq = 0;
+
+ switch (chip->id) {
+ case CHIP_PM8606:
+ device_8606_init(chip, chip->client, pdata);
+ break;
+ case CHIP_PM8607:
+ device_8607_init(chip, chip->client, pdata);
+ break;
+ }
+
+ if (chip->companion) {
+ switch (chip->id) {
+ case CHIP_PM8607:
+ device_8606_init(chip, chip->companion, pdata);
+ break;
+ case CHIP_PM8606:
+ device_8607_init(chip, chip->companion, pdata);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void pm860x_device_exit(struct pm860x_chip *chip)
+{
+ device_irq_exit(chip);
+ mfd_remove_devices(chip->dev);
+}
+
+MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
new file mode 100644
index 00000000000..4a6e7186334
--- /dev/null
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -0,0 +1,237 @@
+/*
+ * I2C driver for Marvell 88PM860x
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
+
+static inline int pm860x_read_device(struct i2c_client *i2c,
+ int reg, int bytes, void *dest)
+{
+ unsigned char data;
+ int ret;
+
+ data = (unsigned char)reg;
+ ret = i2c_master_send(i2c, &data, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_master_recv(i2c, dest, bytes);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static inline int pm860x_write_device(struct i2c_client *i2c,
+ int reg, int bytes, void *src)
+{
+ unsigned char buf[bytes + 1];
+ int ret;
+
+ buf[0] = (unsigned char)reg;
+ memcpy(&buf[1], src, bytes);
+
+ ret = i2c_master_send(i2c, buf, bytes + 1);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+int pm860x_reg_read(struct i2c_client *i2c, int reg)
+{
+ struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+ unsigned char data;
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = pm860x_read_device(i2c, reg, 1, &data);
+ mutex_unlock(&chip->io_lock);
+
+ if (ret < 0)
+ return ret;
+ else
+ return (int)data;
+}
+EXPORT_SYMBOL(pm860x_reg_read);
+
+int pm860x_reg_write(struct i2c_client *i2c, int reg,
+ unsigned char data)
+{
+ struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = pm860x_write_device(i2c, reg, 1, &data);
+ mutex_unlock(&chip->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(pm860x_reg_write);
+
+int pm860x_bulk_read(struct i2c_client *i2c, int reg,
+ int count, unsigned char *buf)
+{
+ struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = pm860x_read_device(i2c, reg, count, buf);
+ mutex_unlock(&chip->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(pm860x_bulk_read);
+
+int pm860x_bulk_write(struct i2c_client *i2c, int reg,
+ int count, unsigned char *buf)
+{
+ struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = pm860x_write_device(i2c, reg, count, buf);
+ mutex_unlock(&chip->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(pm860x_bulk_write);
+
+int pm860x_set_bits(struct i2c_client *i2c, int reg,
+ unsigned char mask, unsigned char data)
+{
+ struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+ unsigned char value;
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = pm860x_read_device(i2c, reg, 1, &value);
+ if (ret < 0)
+ goto out;
+ value &= ~mask;
+ value |= data;
+ ret = pm860x_write_device(i2c, reg, 1, &value);
+out:
+ mutex_unlock(&chip->io_lock);
+ return ret;
+}
+EXPORT_SYMBOL(pm860x_set_bits);
+
+
+static const struct i2c_device_id pm860x_id_table[] = {
+ { "88PM860x", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
+
+static int verify_addr(struct i2c_client *i2c)
+{
+ unsigned short addr_8607[] = {0x30, 0x34};
+ unsigned short addr_8606[] = {0x10, 0x11};
+ int size, i;
+
+ if (i2c == NULL)
+ return 0;
+ size = ARRAY_SIZE(addr_8606);
+ for (i = 0; i < size; i++) {
+ if (i2c->addr == *(addr_8606 + i))
+ return CHIP_PM8606;
+ }
+ size = ARRAY_SIZE(addr_8607);
+ for (i = 0; i < size; i++) {
+ if (i2c->addr == *(addr_8607 + i))
+ return CHIP_PM8607;
+ }
+ return 0;
+}
+
+static int __devinit pm860x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pm860x_platform_data *pdata = client->dev.platform_data;
+ struct pm860x_chip *chip;
+
+ if (!pdata) {
+ pr_info("No platform data in %s!\n", __func__);
+ return -EINVAL;
+ }
+
+ chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
+ if (chip == NULL)
+ return -ENOMEM;
+
+ chip->id = verify_addr(client);
+ chip->client = client;
+ i2c_set_clientdata(client, chip);
+ chip->dev = &client->dev;
+ mutex_init(&chip->io_lock);
+ dev_set_drvdata(chip->dev, chip);
+
+ /*
+ * Both client and companion client shares same platform driver.
+ * Driver distinguishes them by pdata->companion_addr.
+ * pdata->companion_addr is only assigned if companion chip exists.
+ * At the same time, the companion_addr shouldn't equal to client
+ * address.
+ */
+ if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
+ chip->companion_addr = pdata->companion_addr;
+ chip->companion = i2c_new_dummy(chip->client->adapter,
+ chip->companion_addr);
+ i2c_set_clientdata(chip->companion, chip);
+ }
+
+ pm860x_device_init(chip, pdata);
+ return 0;
+}
+
+static int __devexit pm860x_remove(struct i2c_client *client)
+{
+ struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+ pm860x_device_exit(chip);
+ i2c_unregister_device(chip->companion);
+ i2c_set_clientdata(chip->companion, NULL);
+ i2c_set_clientdata(chip->client, NULL);
+ kfree(chip);
+ return 0;
+}
+
+static struct i2c_driver pm860x_driver = {
+ .driver = {
+ .name = "88PM860x",
+ .owner = THIS_MODULE,
+ },
+ .probe = pm860x_probe,
+ .remove = __devexit_p(pm860x_remove),
+ .id_table = pm860x_id_table,
+};
+
+static int __init pm860x_i2c_init(void)
+{
+ int ret;
+ ret = i2c_add_driver(&pm860x_driver);
+ if (ret != 0)
+ pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
+ return ret;
+}
+subsys_initcall(pm860x_i2c_init);
+
+static void __exit pm860x_i2c_exit(void)
+{
+ i2c_del_driver(&pm860x_driver);
+}
+module_exit(pm860x_i2c_exit);
+
+MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b670d10d5c9..2a5a0b78f84 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -9,6 +9,16 @@ config MFD_CORE
tristate
default n
+config MFD_88PM860X
+ bool "Support Marvell 88PM8606/88PM8607"
+ depends on I2C=y && GENERIC_HARDIRQS
+ select MFD_CORE
+ help
+ This supports for Marvell 88PM8606/88PM8607 Power Management IC.
+ This includes the I2C driver and the core APIs _only_, you have to
+ select individual components like voltage regulators, RTC and
+ battery-charger under the corresponding menus.
+
config MFD_SM501
tristate "Support for Silicon Motion SM501"
---help---
@@ -37,7 +47,7 @@ config MFD_ASIC3
config MFD_SH_MOBILE_SDHI
bool "Support for SuperH Mobile SDHI"
- depends on SUPERH
+ depends on SUPERH || ARCH_SHMOBILE
select MFD_CORE
---help---
This driver supports the SDHI hardware block found in many
@@ -68,6 +78,15 @@ config HTC_PASIC3
HTC Magician devices, respectively. Actual functionality is
handled by the leds-pasic3 and ds1wm drivers.
+config HTC_I2CPLD
+ bool "HTC I2C PLD chip support"
+ depends on I2C=y && GPIOLIB
+ help
+ If you say yes here you get support for the supposed CPLD
+ found on omap850 HTC devices like the HTC Wizard and HTC Herald.
+ This device provides input and output GPIOs through an I2C
+ interface to one or more sub-chips.
+
config UCB1400_CORE
tristate "Philips UCB1400 Core driver"
depends on AC97_BUS
@@ -184,6 +203,16 @@ config PMIC_ADP5520
individual components like LCD backlight, LEDs, GPIOs and Kepad
under the corresponding menus.
+config MFD_MAX8925
+ bool "Maxim Semiconductor MAX8925 PMIC Support"
+ depends on I2C=y && GENERIC_HARDIRQS
+ select MFD_CORE
+ help
+ Say yes here to support for Maxim Semiconductor MAX8925. This is
+ a Power Management IC. This driver provies common support for
+ accessing the device, additional drivers must be enabled in order
+ to use the functionality of the device.
+
config MFD_WM8400
tristate "Support Wolfson Microelectronics WM8400"
select MFD_CORE
@@ -197,7 +226,7 @@ config MFD_WM8400
config MFD_WM831X
bool "Support Wolfson Microelectronics WM831x/2x PMICs"
select MFD_CORE
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
help
Support for the Wolfson Microelecronics WM831x and WM832x PMICs.
This driver provides common support for accessing the device,
@@ -205,7 +234,8 @@ config MFD_WM831X
functionality of the device.
config MFD_WM8350
- tristate
+ bool
+ depends on GENERIC_HARDIRQS
config MFD_WM8350_CONFIG_MODE_0
bool
@@ -256,9 +286,9 @@ config MFD_WM8352_CONFIG_MODE_3
depends on MFD_WM8350
config MFD_WM8350_I2C
- tristate "Support Wolfson Microelectronics WM8350 with I2C"
+ bool "Support Wolfson Microelectronics WM8350 with I2C"
select MFD_WM8350
- depends on I2C
+ depends on I2C=y && GENERIC_HARDIRQS
help
The WM8350 is an integrated audio and power management
subsystem with watchdog and RTC functionality for embedded
@@ -266,6 +296,18 @@ config MFD_WM8350_I2C
I2C as the control interface. Additional options must be
selected to enable support for the functionality of the chip.
+config MFD_WM8994
+ tristate "Support Wolfson Microelectronics WM8994"
+ select MFD_CORE
+ depends on I2C
+ help
+ The WM8994 is a highly integrated hi-fi CODEC designed for
+ smartphone applicatiosn. As well as audio functionality it
+ has on board GPIO and regulator functionality which is
+ supported via the relevant subsystems. This driver provides
+ core support for the WM8994, in order to use the actual
+ functionaltiy of the device other drivers must be enabled.
+
config MFD_PCF50633
tristate "Support for NXP PCF50633"
depends on I2C
@@ -300,8 +342,8 @@ config PCF50633_GPIO
the PCF50633 chip.
config AB3100_CORE
- tristate "ST-Ericsson AB3100 Mixed Signal Circuit core functions"
- depends on I2C
+ bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions"
+ depends on I2C=y
default y if ARCH_U300
help
Select this to enable the AB3100 Mixed Signal IC core
@@ -329,16 +371,6 @@ config EZX_PCAP
This enables the PCAP ASIC present on EZX Phones. This is
needed for MMC, TouchScreen, Sound, USB, etc..
-config MFD_88PM8607
- bool "Support Marvell 88PM8607"
- depends on I2C=y
- select MFD_CORE
- help
- This supports for Marvell 88PM8607 Power Management IC. This includes
- the I2C driver and the core APIs _only_, you have to select
- individual components like voltage regulators, RTC and
- battery-charger under the corresponding menus.
-
config AB4500_CORE
tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip"
depends on SPI
@@ -358,6 +390,15 @@ config MFD_TIMBERDALE
The timberdale FPGA can be found on the Intel Atom development board
for in-vehicle infontainment, called Russellville.
+
+config LPC_SCH
+ tristate "Intel SCH LPC"
+ depends on PCI
+ select MFD_CORE
+ help
+ LPC bridge function of the Intel SCH provides support for
+ System Management Bus and General Purpose I/O.
+
endmenu
menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 78295d6a75f..22715add99a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -2,12 +2,15 @@
# Makefile for multifunction miscellaneous devices
#
+88pm860x-objs := 88pm860x-core.o 88pm860x-i2c.o
+obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
+obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
@@ -22,6 +25,7 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o
wm8350-objs += wm8350-irq.o
obj-$(CONFIG_MFD_WM8350) += wm8350.o
obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
+obj-$(CONFIG_MFD_WM8994) += wm8994-core.o
obj-$(CONFIG_TPS65010) += tps65010.o
obj-$(CONFIG_MENELAUS) += menelaus.o
@@ -47,6 +51,8 @@ endif
obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
obj-$(CONFIG_PMIC_DA903X) += da903x.o
+max8925-objs := max8925-core.o max8925-i2c.o
+obj-$(CONFIG_MFD_MAX8925) += max8925.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o
obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
@@ -55,5 +61,5 @@ obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
obj-$(CONFIG_AB4500_CORE) += ab4500-core.o
obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
-obj-$(CONFIG_MFD_88PM8607) += 88pm8607.o
obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
+obj-$(CONFIG_LPC_SCH) += lpc_sch.o \ No newline at end of file
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index fd42a80e7bf..e4ca5909e42 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2009 ST-Ericsson
+ * Copyright (C) 2007-2010 ST-Ericsson
* License terms: GNU General Public License (GPL) version 2
* Low-level core for exclusive access to the AB3100 IC on the I2C bus
* and some basic chip-configuration.
@@ -10,10 +10,12 @@
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/notifier.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/interrupt.h>
+#include <linux/random.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
@@ -365,18 +367,23 @@ int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100,
}
EXPORT_SYMBOL(ab3100_event_registers_startup_state_get);
-/* Interrupt handling worker */
-static void ab3100_work(struct work_struct *work)
+/*
+ * This is a threaded interrupt handler so we can make some
+ * I2C calls etc.
+ */
+static irqreturn_t ab3100_irq_handler(int irq, void *data)
{
- struct ab3100 *ab3100 = container_of(work, struct ab3100, work);
+ struct ab3100 *ab3100 = data;
u8 event_regs[3];
u32 fatevent;
int err;
+ add_interrupt_randomness(irq);
+
err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
event_regs, 3);
if (err)
- goto err_event_wq;
+ goto err_event;
fatevent = (event_regs[0] << 16) |
(event_regs[1] << 8) |
@@ -398,29 +405,11 @@ static void ab3100_work(struct work_struct *work)
dev_dbg(ab3100->dev,
"IRQ Event: 0x%08x\n", fatevent);
- /* By now the IRQ should be acked and deasserted so enable it again */
- enable_irq(ab3100->i2c_client->irq);
- return;
+ return IRQ_HANDLED;
- err_event_wq:
+ err_event:
dev_dbg(ab3100->dev,
- "error in event workqueue\n");
- /* Enable the IRQ anyway, what choice do we have? */
- enable_irq(ab3100->i2c_client->irq);
- return;
-}
-
-static irqreturn_t ab3100_irq_handler(int irq, void *data)
-{
- struct ab3100 *ab3100 = data;
- /*
- * Disable the IRQ and dispatch a worker to handle the
- * event. Since the chip resides on I2C this is slow
- * stuff and we will re-enable the interrupts once th
- * worker has finished.
- */
- disable_irq_nosync(irq);
- schedule_work(&ab3100->work);
+ "error reading event status\n");
return IRQ_HANDLED;
}
@@ -735,10 +724,7 @@ static struct platform_device ab3100_##devname##_device = { \
.id = -1, \
}
-/*
- * This lists all the subdevices and corresponding register
- * ranges.
- */
+/* This lists all the subdevices */
AB3100_DEVICE(dac, "ab3100-dac");
AB3100_DEVICE(leds, "ab3100-leds");
AB3100_DEVICE(power, "ab3100-power");
@@ -904,12 +890,11 @@ static int __init ab3100_probe(struct i2c_client *client,
if (err)
goto exit_no_setup;
- INIT_WORK(&ab3100->work, ab3100_work);
-
+ err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler,
+ IRQF_ONESHOT, "ab3100-core", ab3100);
/* This real unpredictable IRQ is of course sampled for entropy */
- err = request_irq(client->irq, ab3100_irq_handler,
- IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
- "AB3100 IRQ", ab3100);
+ rand_initialize_irq(client->irq);
+
if (err)
goto exit_no_irq;
diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c
index 0499b2031a2..2d14655fdeb 100644
--- a/drivers/mfd/ab3100-otp.c
+++ b/drivers/mfd/ab3100-otp.c
@@ -9,10 +9,12 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mfd/ab3100.h>
#include <linux/debugfs.h>
+#include <linux/seq_file.h>
/* The OTP registers */
#define AB3100_OTP0 0xb0
@@ -95,11 +97,10 @@ static int __init ab3100_otp_read(struct ab3100_otp *otp)
* This is a simple debugfs human-readable file that dumps out
* the contents of the OTP.
*/
-#ifdef CONFIG_DEBUGFS
-static int show_otp(struct seq_file *s, void *v)
+#ifdef CONFIG_DEBUG_FS
+static int ab3100_show_otp(struct seq_file *s, void *v)
{
struct ab3100_otp *otp = s->private;
- int err;
seq_printf(s, "OTP is %s\n", otp->locked ? "LOCKED" : "UNLOCKED");
seq_printf(s, "OTP clock switch startup is %uHz\n", otp->freq);
@@ -113,7 +114,7 @@ static int show_otp(struct seq_file *s, void *v)
static int ab3100_otp_open(struct inode *inode, struct file *file)
{
- return single_open(file, ab3100_otp_show, inode->i_private);
+ return single_open(file, ab3100_show_otp, inode->i_private);
}
static const struct file_operations ab3100_otp_operations = {
@@ -131,13 +132,14 @@ static int __init ab3100_otp_init_debugfs(struct device *dev,
&ab3100_otp_operations);
if (!otp->debugfs) {
dev_err(dev, "AB3100 debugfs OTP file registration failed!\n");
- return err;
+ return -ENOENT;
}
+ return 0;
}
static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
{
- debugfs_remove_file(otp->debugfs);
+ debugfs_remove(otp->debugfs);
}
#else
/* Compile this out if debugfs not selected */
diff --git a/drivers/mfd/ab4500-core.c b/drivers/mfd/ab4500-core.c
index 1c44c19e073..c275daa3ab1 100644
--- a/drivers/mfd/ab4500-core.c
+++ b/drivers/mfd/ab4500-core.c
@@ -15,6 +15,7 @@
* Interrupt management to be added - TODO.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index b26644772d0..00553286565 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/err.h>
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 95c1e6bd172..7de708d15d7 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -21,6 +21,7 @@
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index e5ffe561739..67181b147ab 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/mfd/da903x.h>
+#include <linux/slab.h>
#define DA9030_CHIP_ID 0x00
#define DA9030_EVENT_A 0x01
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index df405af968f..134c69aa479 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -18,6 +18,7 @@
#include <linux/mfd/ezx-pcap.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#define PCAP_ADC_MAXQ 8
struct pcap_adc_request {
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c
index aa266e1f69b..d3e74f8585e 100644
--- a/drivers/mfd/htc-egpio.c
+++ b/drivers/mfd/htc-egpio.c
@@ -15,6 +15,7 @@
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mfd/htc-egpio.h>
@@ -108,7 +109,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc)
ack_irqs(ei);
/* Process all set pins. */
readval &= ei->irqs_enabled;
- for_each_bit(irqpin, &readval, ei->nirqs) {
+ for_each_set_bit(irqpin, &readval, ei->nirqs) {
/* Run irq handler */
pr_debug("got IRQ %d\n", irqpin);
irq = ei->irq_start + irqpin;
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c
new file mode 100644
index 00000000000..594c9a8e25e
--- /dev/null
+++ b/drivers/mfd/htc-i2cpld.c
@@ -0,0 +1,711 @@
+/*
+ * htc-i2cpld.c
+ * Chip driver for an unknown CPLD chip found on omap850 HTC devices like
+ * the HTC Wizard and HTC Herald.
+ * The cpld is located on the i2c bus and acts as an input/output GPIO
+ * extender.
+ *
+ * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
+ *
+ * Based on work done in the linwizard project
+ * Copyright (C) 2008-2009 Angelo Arrifano <miknix@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/htcpld.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+struct htcpld_chip {
+ spinlock_t lock;
+
+ /* chip info */
+ u8 reset;
+ u8 addr;
+ struct device *dev;
+ struct i2c_client *client;
+
+ /* Output details */
+ u8 cache_out;
+ struct gpio_chip chip_out;
+
+ /* Input details */
+ u8 cache_in;
+ struct gpio_chip chip_in;
+
+ u16 irqs_enabled;
+ uint irq_start;
+ int nirqs;
+
+ /*
+ * Work structure to allow for setting values outside of any
+ * possible interrupt context
+ */
+ struct work_struct set_val_work;
+};
+
+struct htcpld_data {
+ /* irq info */
+ u16 irqs_enabled;
+ uint irq_start;
+ int nirqs;
+ uint chained_irq;
+ unsigned int int_reset_gpio_hi;
+ unsigned int int_reset_gpio_lo;
+
+ /* htcpld info */
+ struct htcpld_chip *chip;
+ unsigned int nchips;
+};
+
+/* There does not appear to be a way to proactively mask interrupts
+ * on the htcpld chip itself. So, we simply ignore interrupts that
+ * aren't desired. */
+static void htcpld_mask(unsigned int irq)
+{
+ struct htcpld_chip *chip = get_irq_chip_data(irq);
+ chip->irqs_enabled &= ~(1 << (irq - chip->irq_start));
+ pr_debug("HTCPLD mask %d %04x\n", irq, chip->irqs_enabled);
+}
+static void htcpld_unmask(unsigned int irq)
+{
+ struct htcpld_chip *chip = get_irq_chip_data(irq);
+ chip->irqs_enabled |= 1 << (irq - chip->irq_start);
+ pr_debug("HTCPLD unmask %d %04x\n", irq, chip->irqs_enabled);
+}
+
+static int htcpld_set_type(unsigned int irq, unsigned int flags)
+{
+ struct irq_desc *d = irq_to_desc(irq);
+
+ if (!d) {
+ pr_err("HTCPLD invalid IRQ: %d\n", irq);
+ return -EINVAL;
+ }
+
+ if (flags & ~IRQ_TYPE_SENSE_MASK)
+ return -EINVAL;
+
+ /* We only allow edge triggering */
+ if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))
+ return -EINVAL;
+
+ d->status &= ~IRQ_TYPE_SENSE_MASK;
+ d->status |= flags;
+
+ return 0;
+}
+
+static struct irq_chip htcpld_muxed_chip = {
+ .name = "htcpld",
+ .mask = htcpld_mask,
+ .unmask = htcpld_unmask,
+ .set_type = htcpld_set_type,
+};
+
+/* To properly dispatch IRQ events, we need to read from the
+ * chip. This is an I2C action that could possibly sleep
+ * (which is bad in interrupt context) -- so we use a threaded
+ * interrupt handler to get around that.
+ */
+static irqreturn_t htcpld_handler(int irq, void *dev)
+{
+ struct htcpld_data *htcpld = dev;
+ unsigned int i;
+ unsigned long flags;
+ int irqpin;
+ struct irq_desc *desc;
+
+ if (!htcpld) {
+ pr_debug("htcpld is null in ISR\n");
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * For each chip, do a read of the chip and trigger any interrupts
+ * desired. The interrupts will be triggered from LSB to MSB (i.e.
+ * bit 0 first, then bit 1, etc.)
+ *
+ * For chips that have no interrupt range specified, just skip 'em.
+ */
+ for (i = 0; i < htcpld->nchips; i++) {
+ struct htcpld_chip *chip = &htcpld->chip[i];
+ struct i2c_client *client;
+ int val;
+ unsigned long uval, old_val;
+
+ if (!chip) {
+ pr_debug("chip %d is null in ISR\n", i);
+ continue;
+ }
+
+ if (chip->nirqs == 0)
+ continue;
+
+ client = chip->client;
+ if (!client) {
+ pr_debug("client %d is null in ISR\n", i);
+ continue;
+ }
+
+ /* Scan the chip */
+ val = i2c_smbus_read_byte_data(client, chip->cache_out);
+ if (val < 0) {
+ /* Throw a warning and skip this chip */
+ dev_warn(chip->dev, "Unable to read from chip: %d\n",
+ val);
+ continue;
+ }
+
+ uval = (unsigned long)val;
+
+ spin_lock_irqsave(&chip->lock, flags);
+
+ /* Save away the old value so we can compare it */
+ old_val = chip->cache_in;
+
+ /* Write the new value */
+ chip->cache_in = uval;
+
+ spin_unlock_irqrestore(&chip->lock, flags);
+
+ /*
+ * For each bit in the data (starting at bit 0), trigger
+ * associated interrupts.
+ */
+ for (irqpin = 0; irqpin < chip->nirqs; irqpin++) {
+ unsigned oldb, newb;
+ int flags;
+
+ irq = chip->irq_start + irqpin;
+ desc = irq_to_desc(irq);
+ flags = desc->status;
+
+ /* Run the IRQ handler, but only if the bit value
+ * changed, and the proper flags are set */
+ oldb = (old_val >> irqpin) & 1;
+ newb = (uval >> irqpin) & 1;
+
+ if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) ||
+ (oldb && !newb &&
+ (flags & IRQ_TYPE_EDGE_FALLING))) {
+ pr_debug("fire IRQ %d\n", irqpin);
+ desc->handle_irq(irq, desc);
+ }
+ }
+ }
+
+ /*
+ * In order to continue receiving interrupts, the int_reset_gpio must
+ * be asserted.
+ */
+ if (htcpld->int_reset_gpio_hi)
+ gpio_set_value(htcpld->int_reset_gpio_hi, 1);
+ if (htcpld->int_reset_gpio_lo)
+ gpio_set_value(htcpld->int_reset_gpio_lo, 0);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * The GPIO set routines can be called from interrupt context, especially if,
+ * for example they're attached to the led-gpio framework and a trigger is
+ * enabled. As such, we declared work above in the htcpld_chip structure,
+ * and that work is scheduled in the set routine. The kernel can then run
+ * the I2C functions, which will sleep, in process context.
+ */
+void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct i2c_client *client;
+ struct htcpld_chip *chip_data;
+ unsigned long flags;
+
+ chip_data = container_of(chip, struct htcpld_chip, chip_out);
+ if (!chip_data)
+ return;
+
+ client = chip_data->client;
+ if (client == NULL)
+ return;
+
+ spin_lock_irqsave(&chip_data->lock, flags);
+ if (val)
+ chip_data->cache_out |= (1 << offset);
+ else
+ chip_data->cache_out &= ~(1 << offset);
+ spin_unlock_irqrestore(&chip_data->lock, flags);
+
+ schedule_work(&(chip_data->set_val_work));
+}
+
+void htcpld_chip_set_ni(struct work_struct *work)
+{
+ struct htcpld_chip *chip_data;
+ struct i2c_client *client;
+
+ chip_data = container_of(work, struct htcpld_chip, set_val_work);
+ client = chip_data->client;
+ i2c_smbus_read_byte_data(client, chip_data->cache_out);
+}
+
+int htcpld_chip_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct htcpld_chip *chip_data;
+ int val = 0;
+ int is_input = 0;
+
+ /* Try out first */
+ chip_data = container_of(chip, struct htcpld_chip, chip_out);
+ if (!chip_data) {
+ /* Try in */
+ is_input = 1;
+ chip_data = container_of(chip, struct htcpld_chip, chip_in);
+ if (!chip_data)
+ return -EINVAL;
+ }
+
+ /* Determine if this is an input or output GPIO */
+ if (!is_input)
+ /* Use the output cache */
+ val = (chip_data->cache_out >> offset) & 1;
+ else
+ /* Use the input cache */
+ val = (chip_data->cache_in >> offset) & 1;
+
+ if (val)
+ return 1;
+ else
+ return 0;
+}
+
+static int htcpld_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ htcpld_chip_set(chip, offset, value);
+ return 0;
+}
+
+static int htcpld_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ /*
+ * No-op: this function can only be called on the input chip.
+ * We do however make sure the offset is within range.
+ */
+ return (offset < chip->ngpio) ? 0 : -EINVAL;
+}
+
+int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct htcpld_chip *chip_data;
+
+ chip_data = container_of(chip, struct htcpld_chip, chip_in);
+
+ if (offset < chip_data->nirqs)
+ return chip_data->irq_start + offset;
+ else
+ return -EINVAL;
+}
+
+void htcpld_chip_reset(struct i2c_client *client)
+{
+ struct htcpld_chip *chip_data = i2c_get_clientdata(client);
+ if (!chip_data)
+ return;
+
+ i2c_smbus_read_byte_data(
+ client, (chip_data->cache_out = chip_data->reset));
+}
+
+static int __devinit htcpld_setup_chip_irq(
+ struct platform_device *pdev,
+ int chip_index)
+{
+ struct htcpld_data *htcpld;
+ struct device *dev = &pdev->dev;
+ struct htcpld_core_platform_data *pdata;
+ struct htcpld_chip *chip;
+ struct htcpld_chip_platform_data *plat_chip_data;
+ unsigned int irq, irq_end;
+ int ret = 0;
+
+ /* Get the platform and driver data */
+ pdata = dev->platform_data;
+ htcpld = platform_get_drvdata(pdev);
+ chip = &htcpld->chip[chip_index];
+ plat_chip_data = &pdata->chip[chip_index];
+
+ /* Setup irq handlers */
+ irq_end = chip->irq_start + chip->nirqs;
+ for (irq = chip->irq_start; irq < irq_end; irq++) {
+ set_irq_chip(irq, &htcpld_muxed_chip);
+ set_irq_chip_data(irq, chip);
+ set_irq_handler(irq, handle_simple_irq);
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+#else
+ set_irq_probe(irq);
+#endif
+ }
+
+ return ret;
+}
+
+static int __devinit htcpld_register_chip_i2c(
+ struct platform_device *pdev,
+ int chip_index)
+{
+ struct htcpld_data *htcpld;
+ struct device *dev = &pdev->dev;
+ struct htcpld_core_platform_data *pdata;
+ struct htcpld_chip *chip;
+ struct htcpld_chip_platform_data *plat_chip_data;
+ struct i2c_adapter *adapter;
+ struct i2c_client *client;
+ struct i2c_board_info info;
+
+ /* Get the platform and driver data */
+ pdata = dev->platform_data;
+ htcpld = platform_get_drvdata(pdev);
+ chip = &htcpld->chip[chip_index];
+ plat_chip_data = &pdata->chip[chip_index];
+
+ adapter = i2c_get_adapter(pdata->i2c_adapter_id);
+ if (adapter == NULL) {
+ /* Eek, no such I2C adapter! Bail out. */
+ dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n",
+ plat_chip_data->addr, pdata->i2c_adapter_id);
+ return -ENODEV;
+ }
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
+ dev_warn(dev, "i2c adapter %d non-functional\n",
+ pdata->i2c_adapter_id);
+ return -EINVAL;
+ }
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = plat_chip_data->addr;
+ strlcpy(info.type, "htcpld-chip", I2C_NAME_SIZE);
+ info.platform_data = chip;
+
+ /* Add the I2C device. This calls the probe() function. */
+ client = i2c_new_device(adapter, &info);
+ if (!client) {
+ /* I2C device registration failed, contineu with the next */
+ dev_warn(dev, "Unable to add I2C device for 0x%x\n",
+ plat_chip_data->addr);
+ return -ENODEV;
+ }
+
+ i2c_set_clientdata(client, chip);
+ snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%d", client->addr);
+ chip->client = client;
+
+ /* Reset the chip */
+ htcpld_chip_reset(client);
+ chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out);
+
+ return 0;
+}
+
+static void __devinit htcpld_unregister_chip_i2c(
+ struct platform_device *pdev,
+ int chip_index)
+{
+ struct htcpld_data *htcpld;
+ struct htcpld_chip *chip;
+
+ /* Get the platform and driver data */
+ htcpld = platform_get_drvdata(pdev);
+ chip = &htcpld->chip[chip_index];
+
+ if (chip->client)
+ i2c_unregister_device(chip->client);
+}
+
+static int __devinit htcpld_register_chip_gpio(
+ struct platform_device *pdev,
+ int chip_index)
+{
+ struct htcpld_data *htcpld;
+ struct device *dev = &pdev->dev;
+ struct htcpld_core_platform_data *pdata;
+ struct htcpld_chip *chip;
+ struct htcpld_chip_platform_data *plat_chip_data;
+ struct gpio_chip *gpio_chip;
+ int ret = 0;
+
+ /* Get the platform and driver data */
+ pdata = dev->platform_data;
+ htcpld = platform_get_drvdata(pdev);
+ chip = &htcpld->chip[chip_index];
+ plat_chip_data = &pdata->chip[chip_index];
+
+ /* Setup the GPIO chips */
+ gpio_chip = &(chip->chip_out);
+ gpio_chip->label = "htcpld-out";
+ gpio_chip->dev = dev;
+ gpio_chip->owner = THIS_MODULE;
+ gpio_chip->get = htcpld_chip_get;
+ gpio_chip->set = htcpld_chip_set;
+ gpio_chip->direction_input = NULL;
+ gpio_chip->direction_output = htcpld_direction_output;
+ gpio_chip->base = plat_chip_data->gpio_out_base;
+ gpio_chip->ngpio = plat_chip_data->num_gpios;
+
+ gpio_chip = &(chip->chip_in);
+ gpio_chip->label = "htcpld-in";
+ gpio_chip->dev = dev;
+ gpio_chip->owner = THIS_MODULE;
+ gpio_chip->get = htcpld_chip_get;
+ gpio_chip->set = NULL;
+ gpio_chip->direction_input = htcpld_direction_input;
+ gpio_chip->direction_output = NULL;
+ gpio_chip->to_irq = htcpld_chip_to_irq;
+ gpio_chip->base = plat_chip_data->gpio_in_base;
+ gpio_chip->ngpio = plat_chip_data->num_gpios;
+
+ /* Add the GPIO chips */
+ ret = gpiochip_add(&(chip->chip_out));
+ if (ret) {
+ dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n",
+ plat_chip_data->addr, ret);
+ return ret;
+ }
+
+ ret = gpiochip_add(&(chip->chip_in));
+ if (ret) {
+ int error;
+
+ dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n",
+ plat_chip_data->addr, ret);
+
+ error = gpiochip_remove(&(chip->chip_out));
+ if (error)
+ dev_warn(dev, "Error while trying to unregister gpio chip: %d\n", error);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devinit htcpld_setup_chips(struct platform_device *pdev)
+{
+ struct htcpld_data *htcpld;
+ struct device *dev = &pdev->dev;
+ struct htcpld_core_platform_data *pdata;
+ int i;
+
+ /* Get the platform and driver data */
+ pdata = dev->platform_data;
+ htcpld = platform_get_drvdata(pdev);
+
+ /* Setup each chip's output GPIOs */
+ htcpld->nchips = pdata->num_chip;
+ htcpld->chip = kzalloc(sizeof(struct htcpld_chip) * htcpld->nchips,
+ GFP_KERNEL);
+ if (!htcpld->chip) {
+ dev_warn(dev, "Unable to allocate memory for chips\n");
+ return -ENOMEM;
+ }
+
+ /* Add the chips as best we can */
+ for (i = 0; i < htcpld->nchips; i++) {
+ int ret;
+
+ /* Setup the HTCPLD chips */
+ htcpld->chip[i].reset = pdata->chip[i].reset;
+ htcpld->chip[i].cache_out = pdata->chip[i].reset;
+ htcpld->chip[i].cache_in = 0;
+ htcpld->chip[i].dev = dev;
+ htcpld->chip[i].irq_start = pdata->chip[i].irq_base;
+ htcpld->chip[i].nirqs = pdata->chip[i].num_irqs;
+
+ INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni);
+ spin_lock_init(&(htcpld->chip[i].lock));
+
+ /* Setup the interrupts for the chip */
+ if (htcpld->chained_irq) {
+ ret = htcpld_setup_chip_irq(pdev, i);
+ if (ret)
+ continue;
+ }
+
+ /* Register the chip with I2C */
+ ret = htcpld_register_chip_i2c(pdev, i);
+ if (ret)
+ continue;
+
+
+ /* Register the chips with the GPIO subsystem */
+ ret = htcpld_register_chip_gpio(pdev, i);
+ if (ret) {
+ /* Unregister the chip from i2c and continue */
+ htcpld_unregister_chip_i2c(pdev, i);
+ continue;
+ }
+
+ dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr);
+ }
+
+ return 0;
+}
+
+static int __devinit htcpld_core_probe(struct platform_device *pdev)
+{
+ struct htcpld_data *htcpld;
+ struct device *dev = &pdev->dev;
+ struct htcpld_core_platform_data *pdata;
+ struct resource *res;
+ int ret = 0;
+
+ if (!dev)
+ return -ENODEV;
+
+ pdata = dev->platform_data;
+ if (!pdata) {
+ dev_warn(dev, "Platform data not found for htcpld core!\n");
+ return -ENXIO;
+ }
+
+ htcpld = kzalloc(sizeof(struct htcpld_data), GFP_KERNEL);
+ if (!htcpld)
+ return -ENOMEM;
+
+ /* Find chained irq */
+ ret = -EINVAL;
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res) {
+ int flags;
+ htcpld->chained_irq = res->start;
+
+ /* Setup the chained interrupt handler */
+ flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;
+ ret = request_threaded_irq(htcpld->chained_irq,
+ NULL, htcpld_handler,
+ flags, pdev->name, htcpld);
+ if (ret) {
+ dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret);
+ goto fail;
+ } else
+ device_init_wakeup(dev, 0);
+ }
+
+ /* Set the driver data */
+ platform_set_drvdata(pdev, htcpld);
+
+ /* Setup the htcpld chips */
+ ret = htcpld_setup_chips(pdev);
+ if (ret)
+ goto fail;
+
+ /* Request the GPIO(s) for the int reset and set them up */
+ if (pdata->int_reset_gpio_hi) {
+ ret = gpio_request(pdata->int_reset_gpio_hi, "htcpld-core");
+ if (ret) {
+ /*
+ * If it failed, that sucks, but we can probably
+ * continue on without it.
+ */
+ dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n");
+ htcpld->int_reset_gpio_hi = 0;
+ } else {
+ htcpld->int_reset_gpio_hi = pdata->int_reset_gpio_hi;
+ gpio_set_value(htcpld->int_reset_gpio_hi, 1);
+ }
+ }
+
+ if (pdata->int_reset_gpio_lo) {
+ ret = gpio_request(pdata->int_reset_gpio_lo, "htcpld-core");
+ if (ret) {
+ /*
+ * If it failed, that sucks, but we can probably
+ * continue on without it.
+ */
+ dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n");
+ htcpld->int_reset_gpio_lo = 0;
+ } else {
+ htcpld->int_reset_gpio_lo = pdata->int_reset_gpio_lo;
+ gpio_set_value(htcpld->int_reset_gpio_lo, 0);
+ }
+ }
+
+ dev_info(dev, "Initialized successfully\n");
+ return 0;
+
+fail:
+ kfree(htcpld);
+ return ret;
+}
+
+/* The I2C Driver -- used internally */
+static const struct i2c_device_id htcpld_chip_id[] = {
+ { "htcpld-chip", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, htcpld_chip_id);
+
+
+static struct i2c_driver htcpld_chip_driver = {
+ .driver = {
+ .name = "htcpld-chip",
+ },
+ .id_table = htcpld_chip_id,
+};
+
+/* The Core Driver */
+static struct platform_driver htcpld_core_driver = {
+ .driver = {
+ .name = "i2c-htcpld",
+ },
+};
+
+static int __init htcpld_core_init(void)
+{
+ int ret;
+
+ /* Register the I2C Chip driver */
+ ret = i2c_add_driver(&htcpld_chip_driver);
+ if (ret)
+ return ret;
+
+ /* Probe for our chips */
+ return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe);
+}
+
+static void __exit htcpld_core_exit(void)
+{
+ i2c_del_driver(&htcpld_chip_driver);
+ platform_driver_unregister(&htcpld_core_driver);
+}
+
+module_init(htcpld_core_init);
+module_exit(htcpld_core_exit);
+
+MODULE_AUTHOR("Cory Maccarrone <darkstar6262@gmail.com>");
+MODULE_DESCRIPTION("I2C HTC PLD Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index cb73051e43d..f04300e05fd 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -19,6 +19,7 @@
#include <linux/mfd/core.h>
#include <linux/mfd/ds1wm.h>
#include <linux/mfd/htc-pasic3.h>
+#include <linux/slab.h>
struct pasic3_data {
void __iomem *mapping;
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
new file mode 100644
index 00000000000..51b2f6065a0
--- /dev/null
+++ b/drivers/mfd/lpc_sch.c
@@ -0,0 +1,133 @@
+/*
+ * lpc_sch.c - LPC interface for Intel Poulsbo SCH
+ *
+ * LPC bridge function of the Intel SCH contains many other
+ * functional units, such as Interrupt controllers, Timers,
+ * Power Management, System Management, GPIO, RTC, and LPC
+ * Configuration Registers.
+ *
+ * Copyright (c) 2010 CompuLab Ltd
+ * Author: Denis Turischev <denis@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/pci.h>
+#include <linux/mfd/core.h>
+
+#define SMBASE 0x40
+#define SMBUS_IO_SIZE 64
+
+#define GPIOBASE 0x44
+#define GPIO_IO_SIZE 64
+
+static struct resource smbus_sch_resource = {
+ .flags = IORESOURCE_IO,
+};
+
+
+static struct resource gpio_sch_resource = {
+ .flags = IORESOURCE_IO,
+};
+
+static struct mfd_cell lpc_sch_cells[] = {
+ {
+ .name = "isch_smbus",
+ .num_resources = 1,
+ .resources = &smbus_sch_resource,
+ },
+ {
+ .name = "sch_gpio",
+ .num_resources = 1,
+ .resources = &gpio_sch_resource,
+ },
+};
+
+static struct pci_device_id lpc_sch_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
+
+static int __devinit lpc_sch_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ unsigned int base_addr_cfg;
+ unsigned short base_addr;
+
+ pci_read_config_dword(dev, SMBASE, &base_addr_cfg);
+ if (!(base_addr_cfg & (1 << 31))) {
+ dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n");
+ return -ENODEV;
+ }
+ base_addr = (unsigned short)base_addr_cfg;
+ if (base_addr == 0) {
+ dev_err(&dev->dev, "I/O space for SMBus uninitialized\n");
+ return -ENODEV;
+ }
+
+ smbus_sch_resource.start = base_addr;
+ smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1;
+
+ pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg);
+ if (!(base_addr_cfg & (1 << 31))) {
+ dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n");
+ return -ENODEV;
+ }
+ base_addr = (unsigned short)base_addr_cfg;
+ if (base_addr == 0) {
+ dev_err(&dev->dev, "I/O space for GPIO uninitialized\n");
+ return -ENODEV;
+ }
+
+ gpio_sch_resource.start = base_addr;
+ gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
+
+ return mfd_add_devices(&dev->dev, -1,
+ lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0);
+}
+
+static void __devexit lpc_sch_remove(struct pci_dev *dev)
+{
+ mfd_remove_devices(&dev->dev);
+}
+
+static struct pci_driver lpc_sch_driver = {
+ .name = "lpc_sch",
+ .id_table = lpc_sch_ids,
+ .probe = lpc_sch_probe,
+ .remove = __devexit_p(lpc_sch_remove),
+};
+
+static int __init lpc_sch_init(void)
+{
+ return pci_register_driver(&lpc_sch_driver);
+}
+
+static void __exit lpc_sch_exit(void)
+{
+ pci_unregister_driver(&lpc_sch_driver);
+}
+
+module_init(lpc_sch_init);
+module_exit(lpc_sch_exit);
+
+MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
+MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
new file mode 100644
index 00000000000..85d63c04749
--- /dev/null
+++ b/drivers/mfd/max8925-core.c
@@ -0,0 +1,656 @@
+/*
+ * Base driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max8925.h>
+
+static struct resource backlight_resources[] = {
+ {
+ .name = "max8925-backlight",
+ .start = MAX8925_WLED_MODE_CNTL,
+ .end = MAX8925_WLED_CNTL,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct mfd_cell backlight_devs[] = {
+ {
+ .name = "max8925-backlight",
+ .num_resources = 1,
+ .resources = &backlight_resources[0],
+ .id = -1,
+ },
+};
+
+static struct resource touch_resources[] = {
+ {
+ .name = "max8925-tsc",
+ .start = MAX8925_TSC_IRQ,
+ .end = MAX8925_ADC_RES_END,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct mfd_cell touch_devs[] = {
+ {
+ .name = "max8925-touch",
+ .num_resources = 1,
+ .resources = &touch_resources[0],
+ .id = -1,
+ },
+};
+
+static struct resource power_supply_resources[] = {
+ {
+ .name = "max8925-power",
+ .start = MAX8925_CHG_IRQ1,
+ .end = MAX8925_CHG_IRQ1_MASK,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct mfd_cell power_devs[] = {
+ {
+ .name = "max8925-power",
+ .num_resources = 1,
+ .resources = &power_supply_resources[0],
+ .id = -1,
+ },
+};
+
+static struct resource rtc_resources[] = {
+ {
+ .name = "max8925-rtc",
+ .start = MAX8925_RTC_IRQ,
+ .end = MAX8925_RTC_IRQ_MASK,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct mfd_cell rtc_devs[] = {
+ {
+ .name = "max8925-rtc",
+ .num_resources = 1,
+ .resources = &rtc_resources[0],
+ .id = -1,
+ },
+};
+
+#define MAX8925_REG_RESOURCE(_start, _end) \
+{ \
+ .start = MAX8925_##_start, \
+ .end = MAX8925_##_end, \
+ .flags = IORESOURCE_IO, \
+}
+
+static struct resource regulator_resources[] = {
+ MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
+ MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
+ MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
+ MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
+ MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
+ MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
+ MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
+ MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
+ MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
+ MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
+ MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
+ MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
+ MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
+ MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
+ MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
+ MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
+ MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
+ MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
+ MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
+ MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
+ MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
+ MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
+ MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
+};
+
+#define MAX8925_REG_DEVS(_id) \
+{ \
+ .name = "max8925-regulator", \
+ .num_resources = 1, \
+ .resources = &regulator_resources[MAX8925_ID_##_id], \
+ .id = MAX8925_ID_##_id, \
+}
+
+static struct mfd_cell regulator_devs[] = {
+ MAX8925_REG_DEVS(SD1),
+ MAX8925_REG_DEVS(SD2),
+ MAX8925_REG_DEVS(SD3),
+ MAX8925_REG_DEVS(LDO1),
+ MAX8925_REG_DEVS(LDO2),
+ MAX8925_REG_DEVS(LDO3),
+ MAX8925_REG_DEVS(LDO4),
+ MAX8925_REG_DEVS(LDO5),
+ MAX8925_REG_DEVS(LDO6),
+ MAX8925_REG_DEVS(LDO7),
+ MAX8925_REG_DEVS(LDO8),
+ MAX8925_REG_DEVS(LDO9),
+ MAX8925_REG_DEVS(LDO10),
+ MAX8925_REG_DEVS(LDO11),
+ MAX8925_REG_DEVS(LDO12),
+ MAX8925_REG_DEVS(LDO13),
+ MAX8925_REG_DEVS(LDO14),
+ MAX8925_REG_DEVS(LDO15),
+ MAX8925_REG_DEVS(LDO16),
+ MAX8925_REG_DEVS(LDO17),
+ MAX8925_REG_DEVS(LDO18),
+ MAX8925_REG_DEVS(LDO19),
+ MAX8925_REG_DEVS(LDO20),
+};
+
+enum {
+ FLAGS_ADC = 1, /* register in ADC component */
+ FLAGS_RTC, /* register in RTC component */
+};
+
+struct max8925_irq_data {
+ int reg;
+ int mask_reg;
+ int enable; /* enable or not */
+ int offs; /* bit offset in mask register */
+ int flags;
+ int tsc_irq;
+};
+
+static struct max8925_irq_data max8925_irqs[] = {
+ [MAX8925_IRQ_VCHG_DC_OVP] = {
+ .reg = MAX8925_CHG_IRQ1,
+ .mask_reg = MAX8925_CHG_IRQ1_MASK,
+ .offs = 1 << 0,
+ },
+ [MAX8925_IRQ_VCHG_DC_F] = {
+ .reg = MAX8925_CHG_IRQ1,
+ .mask_reg = MAX8925_CHG_IRQ1_MASK,
+ .offs = 1 << 1,
+ },
+ [MAX8925_IRQ_VCHG_DC_R] = {
+ .reg = MAX8925_CHG_IRQ1,
+ .mask_reg = MAX8925_CHG_IRQ1_MASK,
+ .offs = 1 << 2,
+ },
+ [MAX8925_IRQ_VCHG_USB_OVP] = {
+ .reg = MAX8925_CHG_IRQ1,
+ .mask_reg = MAX8925_CHG_IRQ1_MASK,
+ .offs = 1 << 3,
+ },
+ [MAX8925_IRQ_VCHG_USB_F] = {
+ .reg = MAX8925_CHG_IRQ1,
+ .mask_reg = MAX8925_CHG_IRQ1_MASK,
+ .offs = 1 << 4,
+ },
+ [MAX8925_IRQ_VCHG_USB_R] = {
+ .reg = MAX8925_CHG_IRQ1,
+ .mask_reg = MAX8925_CHG_IRQ1_MASK,
+ .offs = 1 << 5,
+ },
+ [MAX8925_IRQ_VCHG_THM_OK_R] = {
+ .reg = MAX8925_CHG_IRQ2,
+ .mask_reg = MAX8925_CHG_IRQ2_MASK,
+ .offs = 1 << 0,
+ },
+ [MAX8925_IRQ_VCHG_THM_OK_F] = {
+ .reg = MAX8925_CHG_IRQ2,
+ .mask_reg = MAX8925_CHG_IRQ2_MASK,
+ .offs = 1 << 1,
+ },
+ [MAX8925_IRQ_VCHG_SYSLOW_F] = {
+ .reg = MAX8925_CHG_IRQ2,
+ .mask_reg = MAX8925_CHG_IRQ2_MASK,
+ .offs = 1 << 2,
+ },
+ [MAX8925_IRQ_VCHG_SYSLOW_R] = {
+ .reg = MAX8925_CHG_IRQ2,
+ .mask_reg = MAX8925_CHG_IRQ2_MASK,
+ .offs = 1 << 3,
+ },
+ [MAX8925_IRQ_VCHG_RST] = {
+ .reg = MAX8925_CHG_IRQ2,
+ .mask_reg = MAX8925_CHG_IRQ2_MASK,
+ .offs = 1 << 4,
+ },
+ [MAX8925_IRQ_VCHG_DONE] = {
+ .reg = MAX8925_CHG_IRQ2,
+ .mask_reg = MAX8925_CHG_IRQ2_MASK,
+ .offs = 1 << 5,
+ },
+ [MAX8925_IRQ_VCHG_TOPOFF] = {
+ .reg = MAX8925_CHG_IRQ2,
+ .mask_reg = MAX8925_CHG_IRQ2_MASK,
+ .offs = 1 << 6,
+ },
+ [MAX8925_IRQ_VCHG_TMR_FAULT] = {
+ .reg = MAX8925_CHG_IRQ2,
+ .mask_reg = MAX8925_CHG_IRQ2_MASK,
+ .offs = 1 << 7,
+ },
+ [MAX8925_IRQ_GPM_RSTIN] = {
+ .reg = MAX8925_ON_OFF_IRQ1,
+ .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
+ .offs = 1 << 0,
+ },
+ [MAX8925_IRQ_GPM_MPL] = {
+ .reg = MAX8925_ON_OFF_IRQ1,
+ .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
+ .offs = 1 << 1,
+ },
+ [MAX8925_IRQ_GPM_SW_3SEC] = {
+ .reg = MAX8925_ON_OFF_IRQ1,
+ .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
+ .offs = 1 << 2,
+ },
+ [MAX8925_IRQ_GPM_EXTON_F] = {
+ .reg = MAX8925_ON_OFF_IRQ1,
+ .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
+ .offs = 1 << 3,
+ },
+ [MAX8925_IRQ_GPM_EXTON_R] = {
+ .reg = MAX8925_ON_OFF_IRQ1,
+ .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
+ .offs = 1 << 4,
+ },
+ [MAX8925_IRQ_GPM_SW_1SEC] = {
+ .reg = MAX8925_ON_OFF_IRQ1,
+ .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
+ .offs = 1 << 5,
+ },
+ [MAX8925_IRQ_GPM_SW_F] = {
+ .reg = MAX8925_ON_OFF_IRQ1,
+ .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
+ .offs = 1 << 6,
+ },
+ [MAX8925_IRQ_GPM_SW_R] = {
+ .reg = MAX8925_ON_OFF_IRQ1,
+ .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
+ .offs = 1 << 7,
+ },
+ [MAX8925_IRQ_GPM_SYSCKEN_F] = {
+ .reg = MAX8925_ON_OFF_IRQ2,
+ .mask_reg = MAX8925_ON_OFF_IRQ2_MASK,
+ .offs = 1 << 0,
+ },
+ [MAX8925_IRQ_GPM_SYSCKEN_R] = {
+ .reg = MAX8925_ON_OFF_IRQ2,
+ .mask_reg = MAX8925_ON_OFF_IRQ2_MASK,
+ .offs = 1 << 1,
+ },
+ [MAX8925_IRQ_RTC_ALARM1] = {
+ .reg = MAX8925_RTC_IRQ,
+ .mask_reg = MAX8925_RTC_IRQ_MASK,
+ .offs = 1 << 2,
+ .flags = FLAGS_RTC,
+ },
+ [MAX8925_IRQ_RTC_ALARM0] = {
+ .reg = MAX8925_RTC_IRQ,
+ .mask_reg = MAX8925_RTC_IRQ_MASK,
+ .offs = 1 << 3,
+ .flags = FLAGS_RTC,
+ },
+ [MAX8925_IRQ_TSC_STICK] = {
+ .reg = MAX8925_TSC_IRQ,
+ .mask_reg = MAX8925_TSC_IRQ_MASK,
+ .offs = 1 << 0,
+ .flags = FLAGS_ADC,
+ .tsc_irq = 1,
+ },
+ [MAX8925_IRQ_TSC_NSTICK] = {
+ .reg = MAX8925_TSC_IRQ,
+ .mask_reg = MAX8925_TSC_IRQ_MASK,
+ .offs = 1 << 1,
+ .flags = FLAGS_ADC,
+ .tsc_irq = 1,
+ },
+};
+
+static inline struct max8925_irq_data *irq_to_max8925(struct max8925_chip *chip,
+ int irq)
+{
+ return &max8925_irqs[irq - chip->irq_base];
+}
+
+static irqreturn_t max8925_irq(int irq, void *data)
+{
+ struct max8925_chip *chip = data;
+ struct max8925_irq_data *irq_data;
+ struct i2c_client *i2c;
+ int read_reg = -1, value = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
+ irq_data = &max8925_irqs[i];
+ /* TSC IRQ should be serviced in max8925_tsc_irq() */
+ if (irq_data->tsc_irq)
+ continue;
+ if (irq_data->flags == FLAGS_RTC)
+ i2c = chip->rtc;
+ else if (irq_data->flags == FLAGS_ADC)
+ i2c = chip->adc;
+ else
+ i2c = chip->i2c;
+ if (read_reg != irq_data->reg) {
+ read_reg = irq_data->reg;
+ value = max8925_reg_read(i2c, irq_data->reg);
+ }
+ if (value & irq_data->enable)
+ handle_nested_irq(chip->irq_base + i);
+ }
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t max8925_tsc_irq(int irq, void *data)
+{
+ struct max8925_chip *chip = data;
+ struct max8925_irq_data *irq_data;
+ struct i2c_client *i2c;
+ int read_reg = -1, value = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
+ irq_data = &max8925_irqs[i];
+ /* non TSC IRQ should be serviced in max8925_irq() */
+ if (!irq_data->tsc_irq)
+ continue;
+ if (irq_data->flags == FLAGS_RTC)
+ i2c = chip->rtc;
+ else if (irq_data->flags == FLAGS_ADC)
+ i2c = chip->adc;
+ else
+ i2c = chip->i2c;
+ if (read_reg != irq_data->reg) {
+ read_reg = irq_data->reg;
+ value = max8925_reg_read(i2c, irq_data->reg);
+ }
+ if (value & irq_data->enable)
+ handle_nested_irq(chip->irq_base + i);
+ }
+ return IRQ_HANDLED;
+}
+
+static void max8925_irq_lock(unsigned int irq)
+{
+ struct max8925_chip *chip = get_irq_chip_data(irq);
+
+ mutex_lock(&chip->irq_lock);
+}
+
+static void max8925_irq_sync_unlock(unsigned int irq)
+{
+ struct max8925_chip *chip = get_irq_chip_data(irq);
+ struct max8925_irq_data *irq_data;
+ static unsigned char cache_chg[2] = {0xff, 0xff};
+ static unsigned char cache_on[2] = {0xff, 0xff};
+ static unsigned char cache_rtc = 0xff, cache_tsc = 0xff;
+ unsigned char irq_chg[2], irq_on[2];
+ unsigned char irq_rtc, irq_tsc;
+ int i;
+
+ /* Load cached value. In initial, all IRQs are masked */
+ irq_chg[0] = cache_chg[0];
+ irq_chg[1] = cache_chg[1];
+ irq_on[0] = cache_on[0];
+ irq_on[1] = cache_on[1];
+ irq_rtc = cache_rtc;
+ irq_tsc = cache_tsc;
+ for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
+ irq_data = &max8925_irqs[i];
+ switch (irq_data->mask_reg) {
+ case MAX8925_CHG_IRQ1_MASK:
+ irq_chg[0] &= irq_data->enable;
+ break;
+ case MAX8925_CHG_IRQ2_MASK:
+ irq_chg[1] &= irq_data->enable;
+ break;
+ case MAX8925_ON_OFF_IRQ1_MASK:
+ irq_on[0] &= irq_data->enable;
+ break;
+ case MAX8925_ON_OFF_IRQ2_MASK:
+ irq_on[1] &= irq_data->enable;
+ break;
+ case MAX8925_RTC_IRQ_MASK:
+ irq_rtc &= irq_data->enable;
+ break;
+ case MAX8925_TSC_IRQ_MASK:
+ irq_tsc &= irq_data->enable;
+ break;
+ default:
+ dev_err(chip->dev, "wrong IRQ\n");
+ break;
+ }
+ }
+ /* update mask into registers */
+ if (cache_chg[0] != irq_chg[0]) {
+ cache_chg[0] = irq_chg[0];
+ max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK,
+ irq_chg[0]);
+ }
+ if (cache_chg[1] != irq_chg[1]) {
+ cache_chg[1] = irq_chg[1];
+ max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK,
+ irq_chg[1]);
+ }
+ if (cache_on[0] != irq_on[0]) {
+ cache_on[0] = irq_on[0];
+ max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK,
+ irq_on[0]);
+ }
+ if (cache_on[1] != irq_on[1]) {
+ cache_on[1] = irq_on[1];
+ max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK,
+ irq_on[1]);
+ }
+ if (cache_rtc != irq_rtc) {
+ cache_rtc = irq_rtc;
+ max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, irq_rtc);
+ }
+ if (cache_tsc != irq_tsc) {
+ cache_tsc = irq_tsc;
+ max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, irq_tsc);
+ }
+
+ mutex_unlock(&chip->irq_lock);
+}
+
+static void max8925_irq_enable(unsigned int irq)
+{
+ struct max8925_chip *chip = get_irq_chip_data(irq);
+ max8925_irqs[irq - chip->irq_base].enable
+ = max8925_irqs[irq - chip->irq_base].offs;
+}
+
+static void max8925_irq_disable(unsigned int irq)
+{
+ struct max8925_chip *chip = get_irq_chip_data(irq);
+ max8925_irqs[irq - chip->irq_base].enable = 0;
+}
+
+static struct irq_chip max8925_irq_chip = {
+ .name = "max8925",
+ .bus_lock = max8925_irq_lock,
+ .bus_sync_unlock = max8925_irq_sync_unlock,
+ .enable = max8925_irq_enable,
+ .disable = max8925_irq_disable,
+};
+
+static int max8925_irq_init(struct max8925_chip *chip, int irq,
+ struct max8925_platform_data *pdata)
+{
+ unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+ struct irq_desc *desc;
+ int i, ret;
+ int __irq;
+
+ if (!pdata || !pdata->irq_base) {
+ dev_warn(chip->dev, "No interrupt support on IRQ base\n");
+ return -EINVAL;
+ }
+ /* clear all interrupts */
+ max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1);
+ max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2);
+ max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ1);
+ max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2);
+ max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ);
+ max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
+ /* mask all interrupts */
+ max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0);
+ max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0);
+ max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff);
+ max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, 0xff);
+ max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff);
+ max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff);
+ max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff);
+ max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0xff);
+
+ mutex_init(&chip->irq_lock);
+ chip->core_irq = irq;
+ chip->irq_base = pdata->irq_base;
+ desc = irq_to_desc(chip->core_irq);
+
+ /* register with genirq */
+ for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
+ __irq = i + chip->irq_base;
+ set_irq_chip_data(__irq, chip);
+ set_irq_chip_and_handler(__irq, &max8925_irq_chip,
+ handle_edge_irq);
+ set_irq_nested_thread(__irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(__irq, IRQF_VALID);
+#else
+ set_irq_noprobe(__irq);
+#endif
+ }
+ if (!irq) {
+ dev_warn(chip->dev, "No interrupt support on core IRQ\n");
+ goto tsc_irq;
+ }
+
+ ret = request_threaded_irq(irq, NULL, max8925_irq, flags,
+ "max8925", chip);
+ if (ret) {
+ dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
+ chip->core_irq = 0;
+ }
+tsc_irq:
+ if (!pdata->tsc_irq) {
+ dev_warn(chip->dev, "No interrupt support on TSC IRQ\n");
+ return 0;
+ }
+ chip->tsc_irq = pdata->tsc_irq;
+
+ ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
+ flags, "max8925-tsc", chip);
+ if (ret) {
+ dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
+ chip->tsc_irq = 0;
+ }
+ return 0;
+}
+
+int __devinit max8925_device_init(struct max8925_chip *chip,
+ struct max8925_platform_data *pdata)
+{
+ int ret;
+
+ max8925_irq_init(chip, chip->i2c->irq, pdata);
+
+ if (pdata && (pdata->power || pdata->touch)) {
+ /* enable ADC to control internal reference */
+ max8925_set_bits(chip->i2c, MAX8925_RESET_CNFG, 1, 1);
+ /* enable internal reference for ADC */
+ max8925_set_bits(chip->adc, MAX8925_TSC_CNFG1, 3, 2);
+ /* check for internal reference IRQ */
+ do {
+ ret = max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
+ } while (ret & MAX8925_NREF_OK);
+ /* enaable ADC scheduler, interval is 1 second */
+ max8925_set_bits(chip->adc, MAX8925_ADC_SCHED, 3, 2);
+ }
+
+ /* enable Momentary Power Loss */
+ max8925_set_bits(chip->rtc, MAX8925_MPL_CNTL, 1 << 4, 1 << 4);
+
+ ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
+ ARRAY_SIZE(rtc_devs),
+ &rtc_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add rtc subdev\n");
+ goto out;
+ }
+ if (pdata && pdata->regulator[0]) {
+ ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
+ ARRAY_SIZE(regulator_devs),
+ &regulator_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add regulator subdev\n");
+ goto out_dev;
+ }
+ }
+
+ if (pdata && pdata->backlight) {
+ ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
+ ARRAY_SIZE(backlight_devs),
+ &backlight_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add backlight subdev\n");
+ goto out_dev;
+ }
+ }
+
+ if (pdata && pdata->power) {
+ ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
+ ARRAY_SIZE(power_devs),
+ &power_supply_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add power supply "
+ "subdev\n");
+ goto out_dev;
+ }
+ }
+
+ if (pdata && pdata->touch) {
+ ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
+ ARRAY_SIZE(touch_devs),
+ &touch_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add touch subdev\n");
+ goto out_dev;
+ }
+ }
+
+ return 0;
+out_dev:
+ mfd_remove_devices(chip->dev);
+out:
+ return ret;
+}
+
+void __devexit max8925_device_exit(struct max8925_chip *chip)
+{
+ if (chip->core_irq)
+ free_irq(chip->core_irq, chip);
+ if (chip->tsc_irq)
+ free_irq(chip->tsc_irq, chip);
+ mfd_remove_devices(chip->dev);
+}
+
+
+MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
new file mode 100644
index 00000000000..d9fd8785da4
--- /dev/null
+++ b/drivers/mfd/max8925-i2c.c
@@ -0,0 +1,212 @@
+/*
+ * I2C driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mfd/max8925.h>
+#include <linux/slab.h>
+
+#define RTC_I2C_ADDR 0x68
+#define ADC_I2C_ADDR 0x47
+
+static inline int max8925_read_device(struct i2c_client *i2c,
+ int reg, int bytes, void *dest)
+{
+ int ret;
+
+ if (bytes > 1)
+ ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
+ else {
+ ret = i2c_smbus_read_byte_data(i2c, reg);
+ if (ret < 0)
+ return ret;
+ *(unsigned char *)dest = (unsigned char)ret;
+ }
+ return ret;
+}
+
+static inline int max8925_write_device(struct i2c_client *i2c,
+ int reg, int bytes, void *src)
+{
+ unsigned char buf[bytes + 1];
+ int ret;
+
+ buf[0] = (unsigned char)reg;
+ memcpy(&buf[1], src, bytes);
+
+ ret = i2c_master_send(i2c, buf, bytes + 1);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+int max8925_reg_read(struct i2c_client *i2c, int reg)
+{
+ struct max8925_chip *chip = i2c_get_clientdata(i2c);
+ unsigned char data = 0;
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = max8925_read_device(i2c, reg, 1, &data);
+ mutex_unlock(&chip->io_lock);
+
+ if (ret < 0)
+ return ret;
+ else
+ return (int)data;
+}
+EXPORT_SYMBOL(max8925_reg_read);
+
+int max8925_reg_write(struct i2c_client *i2c, int reg,
+ unsigned char data)
+{
+ struct max8925_chip *chip = i2c_get_clientdata(i2c);
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = max8925_write_device(i2c, reg, 1, &data);
+ mutex_unlock(&chip->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(max8925_reg_write);
+
+int max8925_bulk_read(struct i2c_client *i2c, int reg,
+ int count, unsigned char *buf)
+{
+ struct max8925_chip *chip = i2c_get_clientdata(i2c);
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = max8925_read_device(i2c, reg, count, buf);
+ mutex_unlock(&chip->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(max8925_bulk_read);
+
+int max8925_bulk_write(struct i2c_client *i2c, int reg,
+ int count, unsigned char *buf)
+{
+ struct max8925_chip *chip = i2c_get_clientdata(i2c);
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = max8925_write_device(i2c, reg, count, buf);
+ mutex_unlock(&chip->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(max8925_bulk_write);
+
+int max8925_set_bits(struct i2c_client *i2c, int reg,
+ unsigned char mask, unsigned char data)
+{
+ struct max8925_chip *chip = i2c_get_clientdata(i2c);
+ unsigned char value;
+ int ret;
+
+ mutex_lock(&chip->io_lock);
+ ret = max8925_read_device(i2c, reg, 1, &value);
+ if (ret < 0)
+ goto out;
+ value &= ~mask;
+ value |= data;
+ ret = max8925_write_device(i2c, reg, 1, &value);
+out:
+ mutex_unlock(&chip->io_lock);
+ return ret;
+}
+EXPORT_SYMBOL(max8925_set_bits);
+
+
+static const struct i2c_device_id max8925_id_table[] = {
+ { "max8925", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, max8925_id_table);
+
+static int __devinit max8925_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct max8925_platform_data *pdata = client->dev.platform_data;
+ static struct max8925_chip *chip;
+
+ if (!pdata) {
+ pr_info("%s: platform data is missing\n", __func__);
+ return -EINVAL;
+ }
+
+ chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL);
+ if (chip == NULL)
+ return -ENOMEM;
+ chip->i2c = client;
+ chip->dev = &client->dev;
+ i2c_set_clientdata(client, chip);
+ dev_set_drvdata(chip->dev, chip);
+ mutex_init(&chip->io_lock);
+
+ chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
+ i2c_set_clientdata(chip->rtc, chip);
+
+ chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
+ i2c_set_clientdata(chip->adc, chip);
+
+ max8925_device_init(chip, pdata);
+
+ return 0;
+}
+
+static int __devexit max8925_remove(struct i2c_client *client)
+{
+ struct max8925_chip *chip = i2c_get_clientdata(client);
+
+ max8925_device_exit(chip);
+ i2c_unregister_device(chip->adc);
+ i2c_unregister_device(chip->rtc);
+ i2c_set_clientdata(chip->adc, NULL);
+ i2c_set_clientdata(chip->rtc, NULL);
+ i2c_set_clientdata(chip->i2c, NULL);
+ kfree(chip);
+ return 0;
+}
+
+static struct i2c_driver max8925_driver = {
+ .driver = {
+ .name = "max8925",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8925_probe,
+ .remove = __devexit_p(max8925_remove),
+ .id_table = max8925_id_table,
+};
+
+static int __init max8925_i2c_init(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&max8925_driver);
+ if (ret != 0)
+ pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);
+ return ret;
+}
+subsys_initcall(max8925_i2c_init);
+
+static void __exit max8925_i2c_exit(void)
+{
+ i2c_del_driver(&max8925_driver);
+}
+module_exit(max8925_i2c_exit);
+
+MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/mc13783-core.c b/drivers/mfd/mc13783-core.c
index 735c8a4d164..1f68ecadddc 100644
--- a/drivers/mfd/mc13783-core.c
+++ b/drivers/mfd/mc13783-core.c
@@ -9,6 +9,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/mfd/core.h>
@@ -225,7 +226,7 @@ int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset,
}
EXPORT_SYMBOL(mc13783_reg_rmw);
-int mc13783_mask(struct mc13783 *mc13783, int irq)
+int mc13783_irq_mask(struct mc13783 *mc13783, int irq)
{
int ret;
unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
@@ -245,9 +246,9 @@ int mc13783_mask(struct mc13783 *mc13783, int irq)
return mc13783_reg_write(mc13783, offmask, mask | irqbit);
}
-EXPORT_SYMBOL(mc13783_mask);
+EXPORT_SYMBOL(mc13783_irq_mask);
-int mc13783_unmask(struct mc13783 *mc13783, int irq)
+int mc13783_irq_unmask(struct mc13783 *mc13783, int irq)
{
int ret;
unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
@@ -267,7 +268,53 @@ int mc13783_unmask(struct mc13783 *mc13783, int irq)
return mc13783_reg_write(mc13783, offmask, mask & ~irqbit);
}
-EXPORT_SYMBOL(mc13783_unmask);
+EXPORT_SYMBOL(mc13783_irq_unmask);
+
+int mc13783_irq_status(struct mc13783 *mc13783, int irq,
+ int *enabled, int *pending)
+{
+ int ret;
+ unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
+ unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
+ u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
+
+ if (irq < 0 || irq >= MC13783_NUM_IRQ)
+ return -EINVAL;
+
+ if (enabled) {
+ u32 mask;
+
+ ret = mc13783_reg_read(mc13783, offmask, &mask);
+ if (ret)
+ return ret;
+
+ *enabled = mask & irqbit;
+ }
+
+ if (pending) {
+ u32 stat;
+
+ ret = mc13783_reg_read(mc13783, offstat, &stat);
+ if (ret)
+ return ret;
+
+ *pending = stat & irqbit;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mc13783_irq_status);
+
+int mc13783_irq_ack(struct mc13783 *mc13783, int irq)
+{
+ unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
+ unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
+
+ BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
+
+ return mc13783_reg_write(mc13783, offstat, val);
+}
+EXPORT_SYMBOL(mc13783_irq_ack);
int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
irq_handler_t handler, const char *name, void *dev)
@@ -297,7 +344,7 @@ int mc13783_irq_request(struct mc13783 *mc13783, int irq,
if (ret)
return ret;
- ret = mc13783_unmask(mc13783, irq);
+ ret = mc13783_irq_unmask(mc13783, irq);
if (ret) {
mc13783->irqhandler[irq] = NULL;
mc13783->irqdata[irq] = NULL;
@@ -317,7 +364,7 @@ int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev)
mc13783->irqdata[irq] != dev)
return -EINVAL;
- ret = mc13783_mask(mc13783, irq);
+ ret = mc13783_irq_mask(mc13783, irq);
if (ret)
return ret;
@@ -333,17 +380,6 @@ static inline irqreturn_t mc13783_irqhandler(struct mc13783 *mc13783, int irq)
return mc13783->irqhandler[irq](irq, mc13783->irqdata[irq]);
}
-int mc13783_ackirq(struct mc13783 *mc13783, int irq)
-{
- unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
- unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
-
- BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
-
- return mc13783_reg_write(mc13783, offstat, val);
-}
-EXPORT_SYMBOL(mc13783_ackirq);
-
/*
* returns: number of handled irqs or negative error
* locking: holds mc13783->lock
@@ -422,7 +458,7 @@ static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
{
struct mc13783_adcdone_data *adcdone_data = data;
- mc13783_ackirq(adcdone_data->mc13783, irq);
+ mc13783_irq_ack(adcdone_data->mc13783, irq);
complete_all(&adcdone_data->done);
@@ -486,7 +522,7 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
dev_dbg(&mc13783->spidev->dev, "%s: request irq\n", __func__);
mc13783_irq_request(mc13783, MC13783_IRQ_ADCDONE,
mc13783_handler_adcdone, __func__, &adcdone_data);
- mc13783_ackirq(mc13783, MC13783_IRQ_ADCDONE);
+ mc13783_irq_ack(mc13783, MC13783_IRQ_ADCDONE);
mc13783_reg_write(mc13783, MC13783_REG_ADC_0, adc0);
mc13783_reg_write(mc13783, MC13783_REG_ADC_1, adc1);
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 25842723272..2dab02d9ac8 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mfd/mcp.h>
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 970afa10326..a94b131a18e 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -40,6 +40,7 @@
#include <linux/delay.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
+#include <linux/slab.h>
#include <asm/mach/irq.h>
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index ae15e495e20..8ffbb7a85a7 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -13,7 +13,9 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/acpi.h>
#include <linux/mfd/core.h>
+#include <linux/slab.h>
static int mfd_add_device(struct device *parent, int id,
const struct mfd_cell *cell,
@@ -62,6 +64,10 @@ static int mfd_add_device(struct device *parent, int id,
res[r].start = cell->resources[r].start;
res[r].end = cell->resources[r].end;
}
+
+ ret = acpi_check_resource_conflict(res);
+ if (ret)
+ goto fail_res;
}
platform_device_add_resources(pdev, res, cell->num_resources);
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
index 6d2e8466df1..fe8f922f665 100644
--- a/drivers/mfd/pcf50633-adc.c
+++ b/drivers/mfd/pcf50633-adc.c
@@ -17,6 +17,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 03dcc920070..63a614d696c 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <linux/mfd/pcf50633/core.h>
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
index 03efae8041a..497f91b6138 100644
--- a/drivers/mfd/sh_mobile_sdhi.c
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -20,8 +20,9 @@
#include <linux/kernel.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
-
+#include <linux/mmc/host.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tmio.h>
#include <linux/mfd/sh_mobile_sdhi.h>
@@ -95,9 +96,9 @@ static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
clk_enable(priv->clk);
- /* FIXME: silly const unsigned int hclk */
- *(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);
+ priv->mmc_data.hclk = clk_get_rate(priv->clk);
priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr;
+ priv->mmc_data.capabilities = MMC_CAP_MMC_HIGHSPEED;
memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
priv->cell_mmc.driver_data = &priv->mmc_data;
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 0cc5eeff5ee..bc9275c1213 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/i2c-gpio.h>
+#include <linux/slab.h>
#include <linux/sm501.h>
#include <linux/sm501-regs.h>
@@ -523,7 +524,7 @@ unsigned long sm501_set_clock(struct device *dev,
unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK);
unsigned char reg;
unsigned int pll_reg = 0;
- unsigned long sm501_freq; /* the actual frequency acheived */
+ unsigned long sm501_freq; /* the actual frequency achieved */
struct sm501_clock to;
@@ -533,7 +534,7 @@ unsigned long sm501_set_clock(struct device *dev,
switch (clksrc) {
case SM501_CLOCK_P2XCLK:
- /* This clock is divided in half so to achive the
+ /* This clock is divided in half so to achieve the
* requested frequency the value must be multiplied by
* 2. This clock also has an additional pre divisor */
@@ -562,7 +563,7 @@ unsigned long sm501_set_clock(struct device *dev,
break;
case SM501_CLOCK_V2XCLK:
- /* This clock is divided in half so to achive the
+ /* This clock is divided in half so to achieve the
* requested frequency the value must be multiplied by 2. */
sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2);
@@ -648,7 +649,7 @@ unsigned long sm501_find_clock(struct device *dev,
unsigned long req_freq)
{
struct sm501_devdata *sm = dev_get_drvdata(dev);
- unsigned long sm501_freq; /* the frequency achiveable by the 501 */
+ unsigned long sm501_freq; /* the frequency achieveable by the 501 */
struct sm501_clock to;
switch (clksrc) {
@@ -1440,8 +1441,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev)
platform_set_drvdata(dev, sm);
- sm->regs = ioremap(sm->io_res->start,
- (sm->io_res->end - sm->io_res->start) - 1);
+ sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res));
if (sm->regs == NULL) {
dev_err(&dev->dev, "cannot remap registers\n");
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index bcf4687d4af..da6383a934a 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
@@ -360,7 +361,7 @@ static int t7l66xb_probe(struct platform_device *dev)
if (ret)
goto err_request_scr;
- t7l66xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
+ t7l66xb->scr = ioremap(rscr->start, resource_size(rscr));
if (!t7l66xb->scr) {
ret = -ENOMEM;
goto err_ioremap;
@@ -403,12 +404,12 @@ static int t7l66xb_probe(struct platform_device *dev)
err_ioremap:
release_resource(&t7l66xb->rscr);
err_request_scr:
- kfree(t7l66xb);
clk_put(t7l66xb->clk48m);
err_clk48m_get:
clk_put(t7l66xb->clk32k);
err_clk32k_get:
err_noirq:
+ kfree(t7l66xb);
return ret;
}
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 5c7f04343d5..517f9bcdeaa 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -17,6 +17,7 @@
#include <linux/mfd/core.h>
#include <linux/mfd/tmio.h>
#include <linux/mfd/tc6387xb.h>
+#include <linux/slab.h>
enum {
TC6387XB_CELL_MMC,
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 4bc5a08a2b0..fcf9068810f 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -25,6 +25,7 @@
#include <linux/mfd/tmio.h>
#include <linux/mfd/tc6393xb.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#define SCR_REVID 0x08 /* b Revision ID */
#define SCR_ISR 0x50 /* b Interrupt Status */
@@ -647,7 +648,7 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
if (ret)
goto err_request_scr;
- tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
+ tc6393xb->scr = ioremap(rscr->start, resource_size(rscr));
if (!tc6393xb->scr) {
ret = -ENOMEM;
goto err_ioremap;
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index 1ed44d28380..7f478ec4184 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -25,6 +25,7 @@
#include <linux/pci.h>
#include <linux/msi.h>
#include <linux/mfd/core.h>
+#include <linux/slab.h>
#include <linux/timb_gpio.h>
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 19a930d0624..562cd4935e1 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -58,13 +58,6 @@
#define DRIVER_NAME "twl"
-#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
- defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
-#define twl_has_bci() true
-#else
-#define twl_has_bci() false
-#endif
-
#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
#define twl_has_keypad() true
#else
@@ -130,7 +123,7 @@
#define TWL_NUM_SLAVES 4
#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
- || defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE)
+ || defined(CONFIG_INPUT_TWL4030_PWRBUTTON_MODULE)
#define twl_has_pwrbutton() true
#else
#define twl_has_pwrbutton() false
@@ -205,6 +198,7 @@
/* subchip/slave 3 0x4B - AUDIO */
#define TWL6030_BASEADD_AUDIO 0x0000
#define TWL6030_BASEADD_RSV 0x0000
+#define TWL6030_BASEADD_ZERO 0x0000
/* Few power values */
#define R_CFG_BOOT 0x05
@@ -320,9 +314,11 @@ static struct twl_mapping twl6030_map[] = {
{ SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER },
{ SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE },
{ SUB_CHIP_ID1, TWL6030_BASEADD_PWM },
- { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
- { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
+ { SUB_CHIP_ID0, TWL6030_BASEADD_ZERO },
+ { SUB_CHIP_ID1, TWL6030_BASEADD_ZERO },
+ { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO },
+ { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO },
{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
@@ -588,18 +584,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
struct device *child;
unsigned sub_chip_id;
- if (twl_has_bci() && pdata->bci &&
- !(features & (TPS_SUBSET | TWL5031))) {
- child = add_child(3, "twl4030_bci",
- pdata->bci, sizeof(*pdata->bci),
- false,
- /* irq0 = CHG_PRES, irq1 = BCI */
- pdata->irq_base + BCI_PRES_INTR_OFFSET,
- pdata->irq_base + BCI_INTR_OFFSET);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
if (twl_has_gpio() && pdata->gpio) {
child = add_child(SUB_CHIP_ID1, "twl4030_gpio",
pdata->gpio, sizeof(*pdata->gpio),
@@ -977,6 +961,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
int status;
unsigned i;
struct twl4030_platform_data *pdata = client->dev.platform_data;
+ u8 temp;
if (!pdata) {
dev_dbg(&client->dev, "no platform data?\n");
@@ -1044,6 +1029,18 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
goto fail;
}
+ /* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
+ * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0,
+ * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0.
+ */
+
+ if (twl_class_is_4030()) {
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &temp, REG_GPPUPDCTR1);
+ temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \
+ I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
+ }
+
status = add_children(pdata, id->driver_data);
fail:
if (status < 0)
diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c
index 700b149c1b9..add6f67d803 100644
--- a/drivers/mfd/twl4030-codec.c
+++ b/drivers/mfd/twl4030-codec.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 9df9a5ad38f..202bdd59632 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <linux/i2c/twl.h>
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 0815292fdaf..7efa8789a3a 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -405,7 +405,7 @@ static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
remap &= ~SLEEP_STATE_MASK;
- remap |= rconfig->remap_off << SLEEP_STATE_SHIFT;
+ remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
}
err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
@@ -461,6 +461,56 @@ out:
return err;
}
+int twl4030_remove_script(u8 flags)
+{
+ int err = 0;
+
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1,
+ R_PROTECT_KEY);
+ if (err) {
+ pr_err("twl4030: unable to unlock PROTECT_KEY\n");
+ return err;
+ }
+
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2,
+ R_PROTECT_KEY);
+ if (err) {
+ pr_err("twl4030: unable to unlock PROTECT_KEY\n");
+ return err;
+ }
+
+ if (flags & TWL4030_WRST_SCRIPT) {
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
+ R_SEQ_ADD_WARM);
+ if (err)
+ return err;
+ }
+ if (flags & TWL4030_WAKEUP12_SCRIPT) {
+ if (err)
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
+ R_SEQ_ADD_S2A12);
+ return err;
+ }
+ if (flags & TWL4030_WAKEUP3_SCRIPT) {
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
+ R_SEQ_ADD_S2A3);
+ if (err)
+ return err;
+ }
+ if (flags & TWL4030_SLEEP_SCRIPT) {
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
+ R_SEQ_ADD_A2S);
+ if (err)
+ return err;
+ }
+
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY);
+ if (err)
+ pr_err("TWL4030 Unable to relock registers\n");
+
+ return err;
+}
+
void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
{
int err = 0;
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c
index 85fd9421be9..dbe280153f9 100644
--- a/drivers/mfd/ucb1400_core.c
+++ b/drivers/mfd/ucb1400_core.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/ucb1400.h>
unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 252b74188ec..b281217334e 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -27,6 +27,7 @@
#include <linux/mutex.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/gpio.h>
+#include <linux/semaphore.h>
#include <mach/dma.h>
#include <mach/hardware.h>
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 4b2021af1d9..a3d5728b644 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -18,6 +18,7 @@
#include <linux/bcd.h>
#include <linux/delay.h>
#include <linux/mfd/core.h>
+#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/pdata.h>
@@ -321,7 +322,6 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits);
*/
int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
{
- int tries = 10;
int ret, src;
mutex_lock(&wm831x->auxadc_lock);
@@ -349,13 +349,14 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
goto disable;
}
- do {
- msleep(1);
+ /* Ignore the result to allow us to soldier on without IRQ hookup */
+ wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5));
- ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
- if (ret < 0)
- ret = WM831X_AUX_CVT_ENA;
- } while ((ret & WM831X_AUX_CVT_ENA) && --tries);
+ ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
+ if (ret < 0) {
+ dev_err(wm831x->dev, "AUXADC status read failed: %d\n", ret);
+ goto disable;
+ }
if (ret & WM831X_AUX_CVT_ENA) {
dev_err(wm831x->dev, "Timed out reading AUXADC\n");
@@ -390,6 +391,15 @@ out:
}
EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
+static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
+{
+ struct wm831x *wm831x = irq_data;
+
+ complete(&wm831x->auxadc_done);
+
+ return IRQ_HANDLED;
+}
+
/**
* wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
*
@@ -1411,6 +1421,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
mutex_init(&wm831x->io_lock);
mutex_init(&wm831x->key_lock);
mutex_init(&wm831x->auxadc_lock);
+ init_completion(&wm831x->auxadc_done);
dev_set_drvdata(wm831x->dev, wm831x);
ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
@@ -1449,18 +1460,33 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
case WM8310:
parent = WM8310;
wm831x->num_gpio = 16;
+ if (rev > 0) {
+ wm831x->has_gpio_ena = 1;
+ wm831x->has_cs_sts = 1;
+ }
+
dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
break;
case WM8311:
parent = WM8311;
wm831x->num_gpio = 16;
+ if (rev > 0) {
+ wm831x->has_gpio_ena = 1;
+ wm831x->has_cs_sts = 1;
+ }
+
dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
break;
case WM8312:
parent = WM8312;
wm831x->num_gpio = 16;
+ if (rev > 0) {
+ wm831x->has_gpio_ena = 1;
+ wm831x->has_cs_sts = 1;
+ }
+
dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
break;
@@ -1508,6 +1534,16 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
if (ret != 0)
goto err;
+ if (wm831x->irq_base) {
+ ret = request_threaded_irq(wm831x->irq_base +
+ WM831X_IRQ_AUXADC_DATA,
+ NULL, wm831x_auxadc_irq, 0,
+ "auxadc", wm831x);
+ if (ret < 0)
+ dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
+ ret);
+ }
+
/* The core device is up, instantiate the subdevices. */
switch (parent) {
case WM8310:
@@ -1578,6 +1614,8 @@ static void wm831x_device_exit(struct wm831x *wm831x)
{
wm831x_otp_exit(wm831x);
mfd_remove_devices(wm831x->dev);
+ if (wm831x->irq_base)
+ free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
wm831x_irq_exit(wm831x);
kfree(wm831x);
}
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index 9a970bd6877..e400a3bed06 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/bug.h>
#include <linux/device.h>
#include <linux/delay.h>
@@ -339,7 +340,6 @@ EXPORT_SYMBOL_GPL(wm8350_reg_unlock);
int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
{
u16 reg, result = 0;
- int tries = 5;
if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP)
return -EINVAL;
@@ -363,12 +363,13 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
reg |= 1 << channel | WM8350_AUXADC_POLL;
wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
- do {
- schedule_timeout_interruptible(1);
- reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- } while ((reg & WM8350_AUXADC_POLL) && --tries);
+ /* We ignore the result of the completion and just check for a
+ * conversion result, allowing us to soldier on if the IRQ
+ * infrastructure is not set up for the chip. */
+ wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5));
- if (!tries)
+ reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
+ if (reg & WM8350_AUXADC_POLL)
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
else
result = wm8350_reg_read(wm8350,
@@ -385,6 +386,15 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
}
EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
+static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data)
+{
+ struct wm8350 *wm8350 = irq_data;
+
+ complete(&wm8350->auxadc_done);
+
+ return IRQ_HANDLED;
+}
+
/*
* Cache is always host endian.
*/
@@ -682,11 +692,22 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
}
mutex_init(&wm8350->auxadc_mutex);
+ init_completion(&wm8350->auxadc_done);
ret = wm8350_irq_init(wm8350, irq, pdata);
if (ret < 0)
goto err;
+ if (wm8350->irq_base) {
+ ret = request_threaded_irq(wm8350->irq_base +
+ WM8350_IRQ_AUXADC_DATARDY,
+ NULL, wm8350_auxadc_irq, 0,
+ "auxadc", wm8350);
+ if (ret < 0)
+ dev_warn(wm8350->dev,
+ "Failed to request AUXADC IRQ: %d\n", ret);
+ }
+
if (pdata && pdata->init) {
ret = pdata->init(wm8350);
if (ret != 0) {
@@ -736,6 +757,9 @@ void wm8350_device_exit(struct wm8350 *wm8350)
platform_device_unregister(wm8350->gpio.pdev);
platform_device_unregister(wm8350->codec.pdev);
+ if (wm8350->irq_base)
+ free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350);
+
wm8350_irq_exit(wm8350);
kfree(wm8350->reg_cache);
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c
index 8d8c9321757..65830f57c09 100644
--- a/drivers/mfd/wm8350-i2c.c
+++ b/drivers/mfd/wm8350-i2c.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/mfd/wm8350/core.h>
+#include <linux/slab.h>
static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg,
int bytes, void *dest)
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index 9025f29e270..f56c9adf949 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -18,7 +18,7 @@
#include <linux/bug.h>
#include <linux/device.h>
#include <linux/interrupt.h>
-#include <linux/workqueue.h>
+#include <linux/irq.h>
#include <linux/mfd/wm8350/core.h>
#include <linux/mfd/wm8350/audio.h>
@@ -29,8 +29,6 @@
#include <linux/mfd/wm8350/supply.h>
#include <linux/mfd/wm8350/wdt.h>
-#define WM8350_NUM_IRQ_REGS 7
-
#define WM8350_INT_OFFSET_1 0
#define WM8350_INT_OFFSET_2 1
#define WM8350_POWER_UP_INT_OFFSET 2
@@ -366,19 +364,10 @@ static struct wm8350_irq_data wm8350_irqs[] = {
},
};
-static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
+static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350,
+ int irq)
{
- mutex_lock(&wm8350->irq_mutex);
-
- if (wm8350->irq[irq].handler)
- wm8350->irq[irq].handler(irq, wm8350->irq[irq].data);
- else {
- dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
- irq);
- wm8350_mask_irq(wm8350, irq);
- }
-
- mutex_unlock(&wm8350->irq_mutex);
+ return &wm8350_irqs[irq - wm8350->irq_base];
}
/*
@@ -386,7 +375,9 @@ static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
* interrupts are clear on read the IRQ line will be reasserted and
* the physical IRQ will be handled again if another interrupt is
* asserted while we run - in the normal course of events this is a
- * rare occurrence so we save I2C/SPI reads.
+ * rare occurrence so we save I2C/SPI reads. We're also assuming that
+ * it's rare to get lots of interrupts firing simultaneously so try to
+ * minimise I/O.
*/
static irqreturn_t wm8350_irq(int irq, void *irq_data)
{
@@ -397,7 +388,6 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data)
struct wm8350_irq_data *data;
int i;
- /* TODO: Use block reads to improve performance? */
level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
& ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
@@ -416,93 +406,101 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data)
sub_reg[data->reg] =
wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 +
data->reg);
- sub_reg[data->reg] &=
- ~wm8350_reg_read(wm8350,
- WM8350_INT_STATUS_1_MASK +
- data->reg);
+ sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg];
read_done[data->reg] = 1;
}
if (sub_reg[data->reg] & data->mask)
- wm8350_irq_call_handler(wm8350, i);
+ handle_nested_irq(wm8350->irq_base + i);
}
return IRQ_HANDLED;
}
-int wm8350_register_irq(struct wm8350 *wm8350, int irq,
- irq_handler_t handler, unsigned long flags,
- const char *name, void *data)
+static void wm8350_irq_lock(unsigned int irq)
{
- if (irq < 0 || irq >= WM8350_NUM_IRQ || !handler)
- return -EINVAL;
-
- if (wm8350->irq[irq].handler)
- return -EBUSY;
-
- mutex_lock(&wm8350->irq_mutex);
- wm8350->irq[irq].handler = handler;
- wm8350->irq[irq].data = data;
- mutex_unlock(&wm8350->irq_mutex);
-
- wm8350_unmask_irq(wm8350, irq);
+ struct wm8350 *wm8350 = get_irq_chip_data(irq);
- return 0;
+ mutex_lock(&wm8350->irq_lock);
}
-EXPORT_SYMBOL_GPL(wm8350_register_irq);
-int wm8350_free_irq(struct wm8350 *wm8350, int irq)
+static void wm8350_irq_sync_unlock(unsigned int irq)
{
- if (irq < 0 || irq >= WM8350_NUM_IRQ)
- return -EINVAL;
+ struct wm8350 *wm8350 = get_irq_chip_data(irq);
+ int i;
- wm8350_mask_irq(wm8350, irq);
+ for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
+ /* If there's been a change in the mask write it back
+ * to the hardware. */
+ if (wm8350->irq_masks[i] !=
+ wm8350->reg_cache[WM8350_INT_STATUS_1_MASK + i])
+ WARN_ON(wm8350_reg_write(wm8350,
+ WM8350_INT_STATUS_1_MASK + i,
+ wm8350->irq_masks[i]));
+ }
- mutex_lock(&wm8350->irq_mutex);
- wm8350->irq[irq].handler = NULL;
- mutex_unlock(&wm8350->irq_mutex);
- return 0;
+ mutex_unlock(&wm8350->irq_lock);
}
-EXPORT_SYMBOL_GPL(wm8350_free_irq);
-int wm8350_mask_irq(struct wm8350 *wm8350, int irq)
+static void wm8350_irq_enable(unsigned int irq)
{
- return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK +
- wm8350_irqs[irq].reg,
- wm8350_irqs[irq].mask);
+ struct wm8350 *wm8350 = get_irq_chip_data(irq);
+ struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq);
+
+ wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask;
}
-EXPORT_SYMBOL_GPL(wm8350_mask_irq);
-int wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
+static void wm8350_irq_disable(unsigned int irq)
{
- return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK +
- wm8350_irqs[irq].reg,
- wm8350_irqs[irq].mask);
+ struct wm8350 *wm8350 = get_irq_chip_data(irq);
+ struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq);
+
+ wm8350->irq_masks[irq_data->reg] |= irq_data->mask;
}
-EXPORT_SYMBOL_GPL(wm8350_unmask_irq);
+
+static struct irq_chip wm8350_irq_chip = {
+ .name = "wm8350",
+ .bus_lock = wm8350_irq_lock,
+ .bus_sync_unlock = wm8350_irq_sync_unlock,
+ .disable = wm8350_irq_disable,
+ .enable = wm8350_irq_enable,
+};
int wm8350_irq_init(struct wm8350 *wm8350, int irq,
struct wm8350_platform_data *pdata)
{
- int ret;
+ int ret, cur_irq, i;
int flags = IRQF_ONESHOT;
if (!irq) {
- dev_err(wm8350->dev, "No IRQ configured\n");
- return -EINVAL;
+ dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
+ return 0;
+ }
+
+ if (!pdata || !pdata->irq_base) {
+ dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n");
+ return 0;
}
+ /* Mask top level interrupts */
wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
- wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
- wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
- wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
- wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
- wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
- mutex_init(&wm8350->irq_mutex);
+ /* Mask all individual interrupts by default and cache the
+ * masks. We read the masks back since there are unwritable
+ * bits in the mask registers. */
+ for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
+ wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i,
+ 0xFFFF);
+ wm8350->irq_masks[i] =
+ wm8350_reg_read(wm8350,
+ WM8350_INT_STATUS_1_MASK + i);
+ }
+
+ mutex_init(&wm8350->irq_lock);
wm8350->chip_irq = irq;
+ wm8350->irq_base = pdata->irq_base;
- if (pdata && pdata->irq_high) {
+ if (pdata->irq_high) {
flags |= IRQF_TRIGGER_HIGH;
wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
@@ -514,11 +512,32 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
WM8350_IRQ_POL);
}
+ /* Register with genirq */
+ for (cur_irq = wm8350->irq_base;
+ cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
+ cur_irq++) {
+ set_irq_chip_data(cur_irq, wm8350);
+ set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip,
+ handle_edge_irq);
+ set_irq_nested_thread(cur_irq, 1);
+
+ /* ARM needs us to explicitly flag the IRQ as valid
+ * and will set them noprobe when we do so. */
+#ifdef CONFIG_ARM
+ set_irq_flags(cur_irq, IRQF_VALID);
+#else
+ set_irq_noprobe(cur_irq);
+#endif
+ }
+
ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
"wm8350", wm8350);
if (ret != 0)
dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
+ /* Allow interrupts to fire */
+ wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0);
+
return ret;
}
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index ecfc8bbe89b..865ce013a82 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -18,6 +18,7 @@
#include <linux/mfd/core.h>
#include <linux/mfd/wm8400-private.h>
#include <linux/mfd/wm8400-audio.h>
+#include <linux/slab.h>
static struct {
u16 readable; /* Mask of readable bits */
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
new file mode 100644
index 00000000000..cc524df10aa
--- /dev/null
+++ b/drivers/mfd/wm8994-core.c
@@ -0,0 +1,538 @@
+/*
+ * wm8994-core.c -- Device access for Wolfson WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/wm8994/core.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/wm8994/registers.h>
+
+static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
+ int bytes, void *dest)
+{
+ int ret, i;
+ u16 *buf = dest;
+
+ BUG_ON(bytes % 2);
+ BUG_ON(bytes <= 0);
+
+ ret = wm8994->read_dev(wm8994, reg, bytes, dest);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < bytes / 2; i++) {
+ buf[i] = be16_to_cpu(buf[i]);
+
+ dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n",
+ buf[i], reg + i, reg + i);
+ }
+
+ return 0;
+}
+
+/**
+ * wm8994_reg_read: Read a single WM8994 register.
+ *
+ * @wm8994: Device to read from.
+ * @reg: Register to read.
+ */
+int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
+{
+ unsigned short val;
+ int ret;
+
+ mutex_lock(&wm8994->io_lock);
+
+ ret = wm8994_read(wm8994, reg, 2, &val);
+
+ mutex_unlock(&wm8994->io_lock);
+
+ if (ret < 0)
+ return ret;
+ else
+ return val;
+}
+EXPORT_SYMBOL_GPL(wm8994_reg_read);
+
+/**
+ * wm8994_bulk_read: Read multiple WM8994 registers
+ *
+ * @wm8994: Device to read from
+ * @reg: First register
+ * @count: Number of registers
+ * @buf: Buffer to fill.
+ */
+int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
+ int count, u16 *buf)
+{
+ int ret;
+
+ mutex_lock(&wm8994->io_lock);
+
+ ret = wm8994_read(wm8994, reg, count * 2, buf);
+
+ mutex_unlock(&wm8994->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wm8994_bulk_read);
+
+static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
+ int bytes, void *src)
+{
+ u16 *buf = src;
+ int i;
+
+ BUG_ON(bytes % 2);
+ BUG_ON(bytes <= 0);
+
+ for (i = 0; i < bytes / 2; i++) {
+ dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n",
+ buf[i], reg + i, reg + i);
+
+ buf[i] = cpu_to_be16(buf[i]);
+ }
+
+ return wm8994->write_dev(wm8994, reg, bytes, src);
+}
+
+/**
+ * wm8994_reg_write: Write a single WM8994 register.
+ *
+ * @wm8994: Device to write to.
+ * @reg: Register to write to.
+ * @val: Value to write.
+ */
+int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
+ unsigned short val)
+{
+ int ret;
+
+ mutex_lock(&wm8994->io_lock);
+
+ ret = wm8994_write(wm8994, reg, 2, &val);
+
+ mutex_unlock(&wm8994->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wm8994_reg_write);
+
+/**
+ * wm8994_set_bits: Set the value of a bitfield in a WM8994 register
+ *
+ * @wm8994: Device to write to.
+ * @reg: Register to write to.
+ * @mask: Mask of bits to set.
+ * @val: Value to set (unshifted)
+ */
+int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
+ unsigned short mask, unsigned short val)
+{
+ int ret;
+ u16 r;
+
+ mutex_lock(&wm8994->io_lock);
+
+ ret = wm8994_read(wm8994, reg, 2, &r);
+ if (ret < 0)
+ goto out;
+
+ r &= ~mask;
+ r |= val;
+
+ ret = wm8994_write(wm8994, reg, 2, &r);
+
+out:
+ mutex_unlock(&wm8994->io_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wm8994_set_bits);
+
+static struct mfd_cell wm8994_regulator_devs[] = {
+ { .name = "wm8994-ldo", .id = 1 },
+ { .name = "wm8994-ldo", .id = 2 },
+};
+
+static struct mfd_cell wm8994_devs[] = {
+ { .name = "wm8994-codec" },
+ { .name = "wm8994-gpio" },
+};
+
+/*
+ * Supplies for the main bulk of CODEC; the LDO supplies are ignored
+ * and should be handled via the standard regulator API supply
+ * management.
+ */
+static const char *wm8994_main_supplies[] = {
+ "DBVDD",
+ "DCVDD",
+ "AVDD1",
+ "AVDD2",
+ "CPVDD",
+ "SPKVDD1",
+ "SPKVDD2",
+};
+
+#ifdef CONFIG_PM
+static int wm8994_device_suspend(struct device *dev)
+{
+ struct wm8994 *wm8994 = dev_get_drvdata(dev);
+ int ret;
+
+ /* GPIO configuration state is saved here since we may be configuring
+ * the GPIO alternate functions even if we're not using the gpiolib
+ * driver for them.
+ */
+ ret = wm8994_read(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
+ &wm8994->gpio_regs);
+ if (ret < 0)
+ dev_err(dev, "Failed to save GPIO registers: %d\n", ret);
+
+ /* For similar reasons we also stash the regulator states */
+ ret = wm8994_read(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
+ &wm8994->ldo_regs);
+ if (ret < 0)
+ dev_err(dev, "Failed to save LDO registers: %d\n", ret);
+
+ ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ wm8994->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to disable supplies: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int wm8994_device_resume(struct device *dev)
+{
+ struct wm8994 *wm8994 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
+ wm8994->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
+ &wm8994->ldo_regs);
+ if (ret < 0)
+ dev_err(dev, "Failed to restore LDO registers: %d\n", ret);
+
+ ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
+ &wm8994->gpio_regs);
+ if (ret < 0)
+ dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_REGULATOR
+static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
+{
+ struct wm8994_ldo_pdata *ldo_pdata;
+
+ if (!pdata)
+ return 0;
+
+ ldo_pdata = &pdata->ldo[ldo];
+
+ if (!ldo_pdata->init_data)
+ return 0;
+
+ return ldo_pdata->init_data->num_consumer_supplies != 0;
+}
+#else
+static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
+{
+ return 0;
+}
+#endif
+
+/*
+ * Instantiate the generic non-control parts of the device.
+ */
+static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
+{
+ struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+ int ret, i;
+
+ mutex_init(&wm8994->io_lock);
+ dev_set_drvdata(wm8994->dev, wm8994);
+
+ /* Add the on-chip regulators first for bootstrapping */
+ ret = mfd_add_devices(wm8994->dev, -1,
+ wm8994_regulator_devs,
+ ARRAY_SIZE(wm8994_regulator_devs),
+ NULL, 0);
+ if (ret != 0) {
+ dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
+ goto err;
+ }
+
+ wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
+ ARRAY_SIZE(wm8994_main_supplies),
+ GFP_KERNEL);
+ if (!wm8994->supplies)
+ goto err;
+
+ for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
+ wm8994->supplies[i].supply = wm8994_main_supplies[i];
+
+ ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies),
+ wm8994->supplies);
+ if (ret != 0) {
+ dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
+ goto err_supplies;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
+ wm8994->supplies);
+ if (ret != 0) {
+ dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_get;
+ }
+
+ ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET);
+ if (ret < 0) {
+ dev_err(wm8994->dev, "Failed to read ID register\n");
+ goto err_enable;
+ }
+ if (ret != 0x8994) {
+ dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",
+ ret);
+ ret = -EINVAL;
+ goto err_enable;
+ }
+
+ ret = wm8994_reg_read(wm8994, WM8994_CHIP_REVISION);
+ if (ret < 0) {
+ dev_err(wm8994->dev, "Failed to read revision register: %d\n",
+ ret);
+ goto err_enable;
+ }
+
+ switch (ret) {
+ case 0:
+ case 1:
+ dev_warn(wm8994->dev, "revision %c not fully supported\n",
+ 'A' + ret);
+ break;
+ default:
+ dev_info(wm8994->dev, "revision %c\n", 'A' + ret);
+ break;
+ }
+
+
+ if (pdata) {
+ wm8994->gpio_base = pdata->gpio_base;
+
+ /* GPIO configuration is only applied if it's non-zero */
+ for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
+ if (pdata->gpio_defaults[i]) {
+ wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
+ 0xffff,
+ pdata->gpio_defaults[i]);
+ }
+ }
+ }
+
+ /* In some system designs where the regulators are not in use,
+ * we can achieve a small reduction in leakage currents by
+ * floating LDO outputs. This bit makes no difference if the
+ * LDOs are enabled, it only affects cases where the LDOs were
+ * in operation and are then disabled.
+ */
+ for (i = 0; i < WM8994_NUM_LDO_REGS; i++) {
+ if (wm8994_ldo_in_use(pdata, i))
+ wm8994_set_bits(wm8994, WM8994_LDO_1 + i,
+ WM8994_LDO1_DISCH, WM8994_LDO1_DISCH);
+ else
+ wm8994_set_bits(wm8994, WM8994_LDO_1 + i,
+ WM8994_LDO1_DISCH, 0);
+ }
+
+ ret = mfd_add_devices(wm8994->dev, -1,
+ wm8994_devs, ARRAY_SIZE(wm8994_devs),
+ NULL, 0);
+ if (ret != 0) {
+ dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
+ goto err_enable;
+ }
+
+ return 0;
+
+err_enable:
+ regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ wm8994->supplies);
+err_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+err_supplies:
+ kfree(wm8994->supplies);
+err:
+ mfd_remove_devices(wm8994->dev);
+ kfree(wm8994);
+ return ret;
+}
+
+static void wm8994_device_exit(struct wm8994 *wm8994)
+{
+ mfd_remove_devices(wm8994->dev);
+ regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
+ wm8994->supplies);
+ regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
+ kfree(wm8994->supplies);
+ kfree(wm8994);
+}
+
+static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg,
+ int bytes, void *dest)
+{
+ struct i2c_client *i2c = wm8994->control_data;
+ int ret;
+ u16 r = cpu_to_be16(reg);
+
+ ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
+ if (ret < 0)
+ return ret;
+ if (ret != 2)
+ return -EIO;
+
+ ret = i2c_master_recv(i2c, dest, bytes);
+ if (ret < 0)
+ return ret;
+ if (ret != bytes)
+ return -EIO;
+ return 0;
+}
+
+/* Currently we allocate the write buffer on the stack; this is OK for
+ * small writes - if we need to do large writes this will need to be
+ * revised.
+ */
+static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg,
+ int bytes, void *src)
+{
+ struct i2c_client *i2c = wm8994->control_data;
+ unsigned char msg[bytes + 2];
+ int ret;
+
+ reg = cpu_to_be16(reg);
+ memcpy(&msg[0], &reg, 2);
+ memcpy(&msg[2], src, bytes);
+
+ ret = i2c_master_send(i2c, msg, bytes + 2);
+ if (ret < 0)
+ return ret;
+ if (ret < bytes + 2)
+ return -EIO;
+
+ return 0;
+}
+
+static int wm8994_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8994 *wm8994;
+
+ wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL);
+ if (wm8994 == NULL) {
+ kfree(i2c);
+ return -ENOMEM;
+ }
+
+ i2c_set_clientdata(i2c, wm8994);
+ wm8994->dev = &i2c->dev;
+ wm8994->control_data = i2c;
+ wm8994->read_dev = wm8994_i2c_read_device;
+ wm8994->write_dev = wm8994_i2c_write_device;
+
+ return wm8994_device_init(wm8994, id->driver_data, i2c->irq);
+}
+
+static int wm8994_i2c_remove(struct i2c_client *i2c)
+{
+ struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
+
+ wm8994_device_exit(wm8994);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state)
+{
+ return wm8994_device_suspend(&i2c->dev);
+}
+
+static int wm8994_i2c_resume(struct i2c_client *i2c)
+{
+ return wm8994_device_resume(&i2c->dev);
+}
+#else
+#define wm8994_i2c_suspend NULL
+#define wm8994_i2c_resume NULL
+#endif
+
+static const struct i2c_device_id wm8994_i2c_id[] = {
+ { "wm8994", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
+
+static struct i2c_driver wm8994_i2c_driver = {
+ .driver = {
+ .name = "wm8994",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8994_i2c_probe,
+ .remove = wm8994_i2c_remove,
+ .suspend = wm8994_i2c_suspend,
+ .resume = wm8994_i2c_resume,
+ .id_table = wm8994_i2c_id,
+};
+
+static int __init wm8994_i2c_init(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&wm8994_i2c_driver);
+ if (ret != 0)
+ pr_err("Failed to register wm8994 I2C driver: %d\n", ret);
+
+ return ret;
+}
+module_init(wm8994_i2c_init);
+
+static void __exit wm8994_i2c_exit(void)
+{
+ i2c_del_driver(&wm8994_i2c_driver);
+}
+module_exit(wm8994_i2c_exit);
+
+MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e3551d20464..0d0d625fece 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -212,6 +212,15 @@ config CS5535_MFGPT_DEFAULT_IRQ
want to use a different IRQ by default. This is here for
architectures to set as necessary.
+config CS5535_CLOCK_EVENT_SRC
+ tristate "CS5535/CS5536 high-res timer (MFGPT) events"
+ depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
+ help
+ This driver provides a clock event source based on the MFGPT
+ timer(s) in the CS5535 and CS5536 companion chips.
+ MFGPTs have a better resolution and max interval than the
+ generic PIT, and are suitable for use as high-res timers.
+
config HP_ILO
tristate "Channel interface driver for HP iLO/iLO2 processor"
depends on PCI
@@ -259,6 +268,16 @@ config ISL29003
This driver can also be built as a module. If so, the module
will be called isl29003.
+config SENSORS_TSL2550
+ tristate "Taos TSL2550 ambient light sensor"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get support for the Taos TSL2550
+ ambient light sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called tsl2550.
+
config EP93XX_PWM
tristate "EP93xx PWM support"
depends on ARCH_EP93XX
@@ -292,6 +311,22 @@ config TI_DAC7512
This driver can also be built as a module. If so, the module
will be calles ti_dac7512.
+config VMWARE_BALLOON
+ tristate "VMware Balloon Driver"
+ depends on X86
+ help
+ This is VMware physical memory management driver which acts
+ like a "balloon" that can be inflated to reclaim physical pages
+ by reserving them in the guest and invalidating them in the
+ monitor, freeing up the underlying machine pages so they can
+ be allocated to other guests. The balloon can also be deflated
+ to allow the guest to use more physical memory.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vmware_balloon.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 049ff2482f3..7b6f7eefdf8 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_SGI_GRU) += sgi-gru/
obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o
obj-$(CONFIG_HP_ILO) += hpilo.o
obj-$(CONFIG_ISL29003) += isl29003.o
+obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
obj-$(CONFIG_DS1682) += ds1682.o
obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
@@ -28,3 +29,4 @@ obj-$(CONFIG_C2PORT) += c2port/
obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/
obj-y += eeprom/
obj-y += cb710/
+obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index 558bf3f2c27..4afffe610f9 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -15,6 +15,7 @@
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/atmel-ssc.h>
+#include <linux/slab.h>
/* Serialize access to ssc_list and user count */
static DEFINE_SPINLOCK(user_lock);
diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c
index 6aa5294dfec..0f3fb4f03bd 100644
--- a/drivers/misc/atmel_pwm.c
+++ b/drivers/misc/atmel_pwm.c
@@ -1,6 +1,7 @@
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c
index 05dc8a31f28..3891124001f 100644
--- a/drivers/misc/atmel_tclib.c
+++ b/drivers/misc/atmel_tclib.c
@@ -6,6 +6,7 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
/* Number of bytes to reserve for the iomem resource */
#define ATMEL_TC_IOMEM_SIZE 256
diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c
index b5346b4db91..ed090e77c9c 100644
--- a/drivers/misc/c2port/core.c
+++ b/drivers/misc/c2port/core.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/idr.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/c2port.h>
@@ -912,8 +913,8 @@ struct c2port_device *c2port_device_register(char *name,
c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
"c2port%d", id);
- if (unlikely(!c2dev->dev)) {
- ret = -ENOMEM;
+ if (unlikely(IS_ERR(c2dev->dev))) {
+ ret = PTR_ERR(c2dev->dev);
goto error_device_create;
}
dev_set_drvdata(c2dev->dev, c2dev);
diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c
index b14eab0f2ba..efec4139c3f 100644
--- a/drivers/misc/cb710/core.c
+++ b/drivers/misc/cb710/core.c
@@ -9,11 +9,11 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/idr.h>
#include <linux/cb710.h>
+#include <linux/gfp.h>
static DEFINE_IDA(cb710_ida);
static DEFINE_SPINLOCK(cb710_ida_lock);
diff --git a/drivers/misc/cb710/debug.c b/drivers/misc/cb710/debug.c
index 02358d086e0..fcb3b8e30c5 100644
--- a/drivers/misc/cb710/debug.c
+++ b/drivers/misc/cb710/debug.c
@@ -10,7 +10,6 @@
#include <linux/cb710.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/slab.h>
#define CB710_REG_COUNT 0x80
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c
index 8110460558f..9bec24db4d4 100644
--- a/drivers/misc/cs5535-mfgpt.c
+++ b/drivers/misc/cs5535-mfgpt.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/cs5535.h>
+#include <linux/slab.h>
#define DRV_NAME "cs5535-mfgpt"
#define MFGPT_BAR 2
diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c
index f3ee4a1abb7..9197cfc5501 100644
--- a/drivers/misc/ds1682.c
+++ b/drivers/misc/ds1682.c
@@ -33,7 +33,6 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/string.h>
#include <linux/list.h>
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 2cb2736d65a..db7d0f21b65 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -505,6 +505,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
* Export the EEPROM bytes through sysfs, since that's convenient.
* By default, only root should see the data (maybe passwords etc)
*/
+ sysfs_bin_attr_init(&at24->bin);
at24->bin.attr.name = "eeprom";
at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR;
at24->bin.read = at24_bin_read;
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index d902d81dde3..d194212a41f 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -347,6 +347,7 @@ static int at25_probe(struct spi_device *spi)
* that's sensitive for read and/or write, like ethernet addresses,
* security codes, board-specific manufacturing calibrations, etc.
*/
+ sysfs_bin_attr_init(&at25->bin);
at25->bin.attr.name = "eeprom";
at25->bin.attr.mode = S_IRUSR;
at25->bin.read = at25_bin_read;
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index 1eac626e710..48c84a58163 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
static LIST_HEAD(container_list);
static DEFINE_MUTEX(container_list_lock);
diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c
index ba4694169d7..46b3439673e 100644
--- a/drivers/misc/ep93xx_pwm.c
+++ b/drivers/misc/ep93xx_pwm.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index a92a3a742b4..98ad0120aa9 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -25,6 +25,7 @@
#include <linux/io.h>
#include <linux/wait.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include "hpilo.h"
static struct class *ilo_class;
diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c
index e2031739aa2..5c766b4fb23 100644
--- a/drivers/misc/ibmasm/command.c
+++ b/drivers/misc/ibmasm/command.c
@@ -23,6 +23,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include "ibmasm.h"
#include "lowlevel.h"
diff --git a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c
index 572d41ffc18..76bfda1ffaa 100644
--- a/drivers/misc/ibmasm/event.c
+++ b/drivers/misc/ibmasm/event.c
@@ -23,6 +23,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include "ibmasm.h"
#include "lowlevel.h"
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index aecf40ecb3a..8844a3f4538 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -75,6 +75,7 @@
#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include "ibmasm.h"
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
index dc14b0b9cbf..a234d965243 100644
--- a/drivers/misc/ibmasm/module.c
+++ b/drivers/misc/ibmasm/module.c
@@ -52,6 +52,7 @@
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include "ibmasm.h"
#include "lowlevel.h"
#include "remote.h"
diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c
index 395a4ea64e9..152e9d93eec 100644
--- a/drivers/misc/ics932s401.c
+++ b/drivers/misc/ics932s401.c
@@ -26,6 +26,7 @@
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/log2.h>
+#include <linux/slab.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END };
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index 09dcb699e66..193206602d8 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -30,6 +30,7 @@
#include <linux/pci.h>
#include <linux/ioc4.h>
#include <linux/ktime.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/time.h>
#include <asm/io.h>
diff --git a/drivers/misc/iwmc3200top/debugfs.c b/drivers/misc/iwmc3200top/debugfs.c
index 0c8ea0a1c8a..e9eda471f6e 100644
--- a/drivers/misc/iwmc3200top/debugfs.c
+++ b/drivers/misc/iwmc3200top/debugfs.c
@@ -25,6 +25,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/mmc/sdio_func.h>
diff --git a/drivers/misc/iwmc3200top/fw-download.c b/drivers/misc/iwmc3200top/fw-download.c
index 9dbaeb574e6..e27afde6e99 100644
--- a/drivers/misc/iwmc3200top/fw-download.c
+++ b/drivers/misc/iwmc3200top/fw-download.c
@@ -26,6 +26,7 @@
#include <linux/firmware.h>
#include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "iwmc3200top.h"
diff --git a/drivers/misc/iwmc3200top/log.c b/drivers/misc/iwmc3200top/log.c
index d569279698f..a36a55a49ca 100644
--- a/drivers/misc/iwmc3200top/log.c
+++ b/drivers/misc/iwmc3200top/log.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
#include <linux/ctype.h>
#include "fw-msg.h"
#include "iwmc3200top.h"
diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c
index dd0a3913bf6..c73cef2c3c5 100644
--- a/drivers/misc/iwmc3200top/main.c
+++ b/drivers/misc/iwmc3200top/main.c
@@ -25,6 +25,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
@@ -597,8 +598,6 @@ static void iwmct_remove(struct sdio_func *func)
struct iwmct_work_struct *read_req;
struct iwmct_priv *priv = sdio_get_drvdata(func);
- priv = sdio_get_drvdata(func);
-
LOG_INFO(priv, INIT, "enter\n");
sdio_claim_host(func);
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c
index fcb6ec1af17..72450237a0f 100644
--- a/drivers/misc/kgdbts.c
+++ b/drivers/misc/kgdbts.c
@@ -295,6 +295,10 @@ static int check_and_rewind_pc(char *put_str, char *arg)
/* On x86 a breakpoint stop requires it to be decremented */
if (addr + 1 == kgdbts_regs.ip)
offset = -1;
+#elif defined(CONFIG_SUPERH)
+ /* On SUPERH a breakpoint stop requires it to be decremented */
+ if (addr + 2 == kgdbts_regs.pc)
+ offset = -2;
#endif
if (strcmp(arg, "silent") &&
instruction_pointer(&kgdbts_regs) + offset != addr) {
@@ -305,6 +309,8 @@ static int check_and_rewind_pc(char *put_str, char *arg)
#ifdef CONFIG_X86
/* On x86 adjust the instruction pointer if needed */
kgdbts_regs.ip += offset;
+#elif defined(CONFIG_SUPERH)
+ kgdbts_regs.pc += offset;
#endif
return 0;
}
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index 3648b23d5c9..31a991161f0 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -26,21 +26,9 @@
* It is adapted from the Linux Kernel Dump Test Tool by
* Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
*
- * Usage : insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
- * [cpoint_count={>0}]
+ * Debugfs support added by Simon Kagstrom <simon.kagstrom@netinsight.net>
*
- * recur_count : Recursion level for the stack overflow test. Default is 10.
- *
- * cpoint_name : Crash point where the kernel is to be crashed. It can be
- * one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
- * FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
- * IDE_CORE_CP
- *
- * cpoint_type : Indicates the action to be taken on hitting the crash point.
- * It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW
- *
- * cpoint_count : Indicates the number of times the crash point is to be hit
- * to trigger an action. The default is 10.
+ * See Documentation/fault-injection/provoke-crashes.txt for instructions
*/
#include <linux/kernel.h>
@@ -52,14 +40,14 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/hrtimer.h>
+#include <linux/slab.h>
#include <scsi/scsi_cmnd.h>
+#include <linux/debugfs.h>
#ifdef CONFIG_IDE
#include <linux/ide.h>
#endif
-#define NUM_CPOINTS 8
-#define NUM_CPOINT_TYPES 5
#define DEFAULT_COUNT 10
#define REC_NUM_DEFAULT 10
@@ -72,7 +60,8 @@ enum cname {
MEM_SWAPOUT,
TIMERADD,
SCSI_DISPATCH_CMD,
- IDE_CORE_CP
+ IDE_CORE_CP,
+ DIRECT,
};
enum ctype {
@@ -81,7 +70,11 @@ enum ctype {
BUG,
EXCEPTION,
LOOP,
- OVERFLOW
+ OVERFLOW,
+ CORRUPT_STACK,
+ UNALIGNED_LOAD_STORE_WRITE,
+ OVERWRITE_ALLOCATION,
+ WRITE_AFTER_FREE,
};
static char* cp_name[] = {
@@ -92,7 +85,8 @@ static char* cp_name[] = {
"MEM_SWAPOUT",
"TIMERADD",
"SCSI_DISPATCH_CMD",
- "IDE_CORE_CP"
+ "IDE_CORE_CP",
+ "DIRECT",
};
static char* cp_type[] = {
@@ -100,7 +94,11 @@ static char* cp_type[] = {
"BUG",
"EXCEPTION",
"LOOP",
- "OVERFLOW"
+ "OVERFLOW",
+ "CORRUPT_STACK",
+ "UNALIGNED_LOAD_STORE_WRITE",
+ "OVERWRITE_ALLOCATION",
+ "WRITE_AFTER_FREE",
};
static struct jprobe lkdtm;
@@ -193,34 +191,66 @@ int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file,
}
#endif
+/* Return the crashpoint number or NONE if the name is invalid */
+static enum ctype parse_cp_type(const char *what, size_t count)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cp_type); i++) {
+ if (!strcmp(what, cp_type[i]))
+ return i + 1;
+ }
+
+ return NONE;
+}
+
+static const char *cp_type_to_str(enum ctype type)
+{
+ if (type == NONE || type < 0 || type > ARRAY_SIZE(cp_type))
+ return "None";
+
+ return cp_type[type - 1];
+}
+
+static const char *cp_name_to_str(enum cname name)
+{
+ if (name == INVALID || name < 0 || name > ARRAY_SIZE(cp_name))
+ return "INVALID";
+
+ return cp_name[name - 1];
+}
+
+
static int lkdtm_parse_commandline(void)
{
int i;
- if (cpoint_name == NULL || cpoint_type == NULL ||
- cpoint_count < 1 || recur_count < 1)
+ if (cpoint_count < 1 || recur_count < 1)
return -EINVAL;
- for (i = 0; i < NUM_CPOINTS; ++i) {
+ count = cpoint_count;
+
+ /* No special parameters */
+ if (!cpoint_type && !cpoint_name)
+ return 0;
+
+ /* Neither or both of these need to be set */
+ if (!cpoint_type || !cpoint_name)
+ return -EINVAL;
+
+ cptype = parse_cp_type(cpoint_type, strlen(cpoint_type));
+ if (cptype == NONE)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(cp_name); i++) {
if (!strcmp(cpoint_name, cp_name[i])) {
cpoint = i + 1;
- break;
- }
- }
-
- for (i = 0; i < NUM_CPOINT_TYPES; ++i) {
- if (!strcmp(cpoint_type, cp_type[i])) {
- cptype = i + 1;
- break;
+ return 0;
}
}
- if (cpoint == INVALID || cptype == NONE)
- return -EINVAL;
-
- count = cpoint_count;
-
- return 0;
+ /* Could not find a valid crash point */
+ return -EINVAL;
}
static int recursive_loop(int a)
@@ -235,53 +265,92 @@ static int recursive_loop(int a)
return recursive_loop(a);
}
-void lkdtm_handler(void)
+static void lkdtm_do_action(enum ctype which)
{
- printk(KERN_INFO "lkdtm : Crash point %s of type %s hit\n",
- cpoint_name, cpoint_type);
- --count;
+ switch (which) {
+ case PANIC:
+ panic("dumptest");
+ break;
+ case BUG:
+ BUG();
+ break;
+ case EXCEPTION:
+ *((int *) 0) = 0;
+ break;
+ case LOOP:
+ for (;;)
+ ;
+ break;
+ case OVERFLOW:
+ (void) recursive_loop(0);
+ break;
+ case CORRUPT_STACK: {
+ volatile u32 data[8];
+ volatile u32 *p = data;
+
+ p[12] = 0x12345678;
+ break;
+ }
+ case UNALIGNED_LOAD_STORE_WRITE: {
+ static u8 data[5] __attribute__((aligned(4))) = {1, 2,
+ 3, 4, 5};
+ u32 *p;
+ u32 val = 0x12345678;
+
+ p = (u32 *)(data + 1);
+ if (*p == 0)
+ val = 0x87654321;
+ *p = val;
+ break;
+ }
+ case OVERWRITE_ALLOCATION: {
+ size_t len = 1020;
+ u32 *data = kmalloc(len, GFP_KERNEL);
+
+ data[1024 / sizeof(u32)] = 0x12345678;
+ kfree(data);
+ break;
+ }
+ case WRITE_AFTER_FREE: {
+ size_t len = 1024;
+ u32 *data = kmalloc(len, GFP_KERNEL);
+
+ kfree(data);
+ schedule();
+ memset(data, 0x78, len);
+ break;
+ }
+ case NONE:
+ default:
+ break;
+ }
+
+}
+
+static void lkdtm_handler(void)
+{
+ count--;
+ printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n",
+ cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
if (count == 0) {
- switch (cptype) {
- case NONE:
- break;
- case PANIC:
- printk(KERN_INFO "lkdtm : PANIC\n");
- panic("dumptest");
- break;
- case BUG:
- printk(KERN_INFO "lkdtm : BUG\n");
- BUG();
- break;
- case EXCEPTION:
- printk(KERN_INFO "lkdtm : EXCEPTION\n");
- *((int *) 0) = 0;
- break;
- case LOOP:
- printk(KERN_INFO "lkdtm : LOOP\n");
- for (;;);
- break;
- case OVERFLOW:
- printk(KERN_INFO "lkdtm : OVERFLOW\n");
- (void) recursive_loop(0);
- break;
- default:
- break;
- }
+ lkdtm_do_action(cptype);
count = cpoint_count;
}
}
-static int __init lkdtm_module_init(void)
+static int lkdtm_register_cpoint(enum cname which)
{
int ret;
- if (lkdtm_parse_commandline() == -EINVAL) {
- printk(KERN_INFO "lkdtm : Invalid command\n");
- return -EINVAL;
- }
+ cpoint = INVALID;
+ if (lkdtm.entry != NULL)
+ unregister_jprobe(&lkdtm);
- switch (cpoint) {
+ switch (which) {
+ case DIRECT:
+ lkdtm_do_action(cptype);
+ return 0;
case INT_HARDWARE_ENTRY:
lkdtm.kp.symbol_name = "do_IRQ";
lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
@@ -315,28 +384,268 @@ static int __init lkdtm_module_init(void)
lkdtm.kp.symbol_name = "generic_ide_ioctl";
lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
#else
- printk(KERN_INFO "lkdtm : Crash point not available\n");
+ printk(KERN_INFO "lkdtm: Crash point not available\n");
+ return -EINVAL;
#endif
break;
default:
- printk(KERN_INFO "lkdtm : Invalid Crash Point\n");
- break;
+ printk(KERN_INFO "lkdtm: Invalid Crash Point\n");
+ return -EINVAL;
}
+ cpoint = which;
if ((ret = register_jprobe(&lkdtm)) < 0) {
- printk(KERN_INFO "lkdtm : Couldn't register jprobe\n");
- return ret;
+ printk(KERN_INFO "lkdtm: Couldn't register jprobe\n");
+ cpoint = INVALID;
+ }
+
+ return ret;
+}
+
+static ssize_t do_register_entry(enum cname which, struct file *f,
+ const char __user *user_buf, size_t count, loff_t *off)
+{
+ char *buf;
+ int err;
+
+ if (count >= PAGE_SIZE)
+ return -EINVAL;
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, user_buf, count)) {
+ free_page((unsigned long) buf);
+ return -EFAULT;
+ }
+ /* NULL-terminate and remove enter */
+ buf[count] = '\0';
+ strim(buf);
+
+ cptype = parse_cp_type(buf, count);
+ free_page((unsigned long) buf);
+
+ if (cptype == NONE)
+ return -EINVAL;
+
+ err = lkdtm_register_cpoint(which);
+ if (err < 0)
+ return err;
+
+ *off += count;
+
+ return count;
+}
+
+/* Generic read callback that just prints out the available crash types */
+static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
+ size_t count, loff_t *off)
+{
+ char *buf;
+ int i, n, out;
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
+
+ n = snprintf(buf, PAGE_SIZE, "Available crash types:\n");
+ for (i = 0; i < ARRAY_SIZE(cp_type); i++)
+ n += snprintf(buf + n, PAGE_SIZE - n, "%s\n", cp_type[i]);
+ buf[n] = '\0';
+
+ out = simple_read_from_buffer(user_buf, count, off,
+ buf, n);
+ free_page((unsigned long) buf);
+
+ return out;
+}
+
+static int lkdtm_debugfs_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+
+static ssize_t int_hardware_entry(struct file *f, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ return do_register_entry(INT_HARDWARE_ENTRY, f, buf, count, off);
+}
+
+static ssize_t int_hw_irq_en(struct file *f, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ return do_register_entry(INT_HW_IRQ_EN, f, buf, count, off);
+}
+
+static ssize_t int_tasklet_entry(struct file *f, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ return do_register_entry(INT_TASKLET_ENTRY, f, buf, count, off);
+}
+
+static ssize_t fs_devrw_entry(struct file *f, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ return do_register_entry(FS_DEVRW, f, buf, count, off);
+}
+
+static ssize_t mem_swapout_entry(struct file *f, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ return do_register_entry(MEM_SWAPOUT, f, buf, count, off);
+}
+
+static ssize_t timeradd_entry(struct file *f, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ return do_register_entry(TIMERADD, f, buf, count, off);
+}
+
+static ssize_t scsi_dispatch_cmd_entry(struct file *f,
+ const char __user *buf, size_t count, loff_t *off)
+{
+ return do_register_entry(SCSI_DISPATCH_CMD, f, buf, count, off);
+}
+
+static ssize_t ide_core_cp_entry(struct file *f, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ return do_register_entry(IDE_CORE_CP, f, buf, count, off);
+}
+
+/* Special entry to just crash directly. Available without KPROBEs */
+static ssize_t direct_entry(struct file *f, const char __user *user_buf,
+ size_t count, loff_t *off)
+{
+ enum ctype type;
+ char *buf;
+
+ if (count >= PAGE_SIZE)
+ return -EINVAL;
+ if (count < 1)
+ return -EINVAL;
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ if (copy_from_user(buf, user_buf, count)) {
+ free_page((unsigned long) buf);
+ return -EFAULT;
+ }
+ /* NULL-terminate and remove enter */
+ buf[count] = '\0';
+ strim(buf);
+
+ type = parse_cp_type(buf, count);
+ free_page((unsigned long) buf);
+ if (type == NONE)
+ return -EINVAL;
+
+ printk(KERN_INFO "lkdtm: Performing direct entry %s\n",
+ cp_type_to_str(type));
+ lkdtm_do_action(type);
+ *off += count;
+
+ return count;
+}
+
+struct crash_entry {
+ const char *name;
+ const struct file_operations fops;
+};
+
+static const struct crash_entry crash_entries[] = {
+ {"DIRECT", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = direct_entry} },
+ {"INT_HARDWARE_ENTRY", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = int_hardware_entry} },
+ {"INT_HW_IRQ_EN", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = int_hw_irq_en} },
+ {"INT_TASKLET_ENTRY", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = int_tasklet_entry} },
+ {"FS_DEVRW", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = fs_devrw_entry} },
+ {"MEM_SWAPOUT", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = mem_swapout_entry} },
+ {"TIMERADD", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = timeradd_entry} },
+ {"SCSI_DISPATCH_CMD", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = scsi_dispatch_cmd_entry} },
+ {"IDE_CORE_CP", {.read = lkdtm_debugfs_read,
+ .open = lkdtm_debugfs_open,
+ .write = ide_core_cp_entry} },
+};
+
+static struct dentry *lkdtm_debugfs_root;
+
+static int __init lkdtm_module_init(void)
+{
+ int ret = -EINVAL;
+ int n_debugfs_entries = 1; /* Assume only the direct entry */
+ int i;
+
+ /* Register debugfs interface */
+ lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL);
+ if (!lkdtm_debugfs_root) {
+ printk(KERN_ERR "lkdtm: creating root dir failed\n");
+ return -ENODEV;
+ }
+
+#ifdef CONFIG_KPROBES
+ n_debugfs_entries = ARRAY_SIZE(crash_entries);
+#endif
+
+ for (i = 0; i < n_debugfs_entries; i++) {
+ const struct crash_entry *cur = &crash_entries[i];
+ struct dentry *de;
+
+ de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root,
+ NULL, &cur->fops);
+ if (de == NULL) {
+ printk(KERN_ERR "lkdtm: could not create %s\n",
+ cur->name);
+ goto out_err;
+ }
+ }
+
+ if (lkdtm_parse_commandline() == -EINVAL) {
+ printk(KERN_INFO "lkdtm: Invalid command\n");
+ goto out_err;
+ }
+
+ if (cpoint != INVALID && cptype != NONE) {
+ ret = lkdtm_register_cpoint(cpoint);
+ if (ret < 0) {
+ printk(KERN_INFO "lkdtm: Invalid crash point %d\n",
+ cpoint);
+ goto out_err;
+ }
+ printk(KERN_INFO "lkdtm: Crash point %s of type %s registered\n",
+ cpoint_name, cpoint_type);
+ } else {
+ printk(KERN_INFO "lkdtm: No crash points registered, enable through debugfs\n");
}
- printk(KERN_INFO "lkdtm : Crash point %s of type %s registered\n",
- cpoint_name, cpoint_type);
return 0;
+
+out_err:
+ debugfs_remove_recursive(lkdtm_debugfs_root);
+ return ret;
}
static void __exit lkdtm_module_exit(void)
{
- unregister_jprobe(&lkdtm);
- printk(KERN_INFO "lkdtm : Crash point unregistered\n");
+ debugfs_remove_recursive(lkdtm_debugfs_root);
+
+ unregister_jprobe(&lkdtm);
+ printk(KERN_INFO "lkdtm: Crash point unregistered\n");
}
module_init(lkdtm_module_init);
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 04c27266f56..75ee0d3f6f4 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -21,6 +21,7 @@
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/cdev.h>
+#include <linux/slab.h>
#include <linux/phantom.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
@@ -497,12 +498,7 @@ static struct pci_driver phantom_pci_driver = {
.resume = phantom_resume
};
-static ssize_t phantom_show_version(struct class *cls, char *buf)
-{
- return sprintf(buf, PHANTOM_VERSION "\n");
-}
-
-static CLASS_ATTR(version, 0444, phantom_show_version, NULL);
+static CLASS_ATTR_STRING(version, 0444, PHANTOM_VERSION);
static int __init phantom_init(void)
{
@@ -515,7 +511,7 @@ static int __init phantom_init(void)
printk(KERN_ERR "phantom: can't register phantom class\n");
goto err;
}
- retval = class_create_file(phantom_class, &class_attr_version);
+ retval = class_create_file(phantom_class, &class_attr_version.attr);
if (retval) {
printk(KERN_ERR "phantom: can't create sysfs version file\n");
goto err_class;
@@ -541,7 +537,7 @@ static int __init phantom_init(void)
err_unchr:
unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
err_attr:
- class_remove_file(phantom_class, &class_attr_version);
+ class_remove_file(phantom_class, &class_attr_version.attr);
err_class:
class_destroy(phantom_class);
err:
@@ -554,7 +550,7 @@ static void __exit phantom_exit(void)
unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);
- class_remove_file(phantom_class, &class_attr_version);
+ class_remove_file(phantom_class, &class_attr_version.attr);
class_destroy(phantom_class);
pr_debug("phantom: module successfully removed\n");
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
index 02a77b8b8ee..7a8b9068ea0 100644
--- a/drivers/misc/sgi-gru/grutables.h
+++ b/drivers/misc/sgi-gru/grutables.h
@@ -516,8 +516,7 @@ struct gru_blade_state {
/* Scan all active GRUs in a GRU bitmap */
#define for_each_gru_in_bitmap(gid, map) \
- for ((gid) = find_first_bit((map), GRU_MAX_GRUS); (gid) < GRU_MAX_GRUS;\
- (gid)++, (gid) = find_next_bit((map), GRU_MAX_GRUS, (gid)))
+ for_each_set_bit((gid), (map), GRU_MAX_GRUS)
/* Scan all active GRUs on a specific blade */
#define for_each_gru_on_blade(gru, nid, i) \
@@ -536,23 +535,17 @@ struct gru_blade_state {
/* Scan each CBR whose bit is set in a TFM (or copy of) */
#define for_each_cbr_in_tfm(i, map) \
- for ((i) = find_first_bit(map, GRU_NUM_CBE); \
- (i) < GRU_NUM_CBE; \
- (i)++, (i) = find_next_bit(map, GRU_NUM_CBE, i))
+ for_each_set_bit((i), (map), GRU_NUM_CBE)
/* Scan each CBR in a CBR bitmap. Note: multiple CBRs in an allocation unit */
#define for_each_cbr_in_allocation_map(i, map, k) \
- for ((k) = find_first_bit(map, GRU_CBR_AU); (k) < GRU_CBR_AU; \
- (k) = find_next_bit(map, GRU_CBR_AU, (k) + 1)) \
+ for_each_set_bit((k), (map), GRU_CBR_AU) \
for ((i) = (k)*GRU_CBR_AU_SIZE; \
(i) < ((k) + 1) * GRU_CBR_AU_SIZE; (i)++)
/* Scan each DSR in a DSR bitmap. Note: multiple DSRs in an allocation unit */
#define for_each_dsr_in_allocation_map(i, map, k) \
- for ((k) = find_first_bit((const unsigned long *)map, GRU_DSR_AU);\
- (k) < GRU_DSR_AU; \
- (k) = find_next_bit((const unsigned long *)map, \
- GRU_DSR_AU, (k) + 1)) \
+ for_each_set_bit((k), (const unsigned long *)(map), GRU_DSR_AU) \
for ((i) = (k) * GRU_DSR_AU_CL; \
(i) < ((k) + 1) * GRU_DSR_AU_CL; (i)++)
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 832ed4c88cf..8d082b46426 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -44,6 +44,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/device.h>
#include <linux/delay.h>
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index 9a6268c89fd..d551f09ccb7 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -17,6 +17,7 @@
#include <linux/device.h>
#include <linux/hardirq.h>
+#include <linux/slab.h>
#include "xpc.h"
#include <asm/uv/uv_hub.h>
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index 8b70e03f939..7d71c04fc93 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -14,6 +14,7 @@
*/
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/uncached.h>
#include <asm/sn/mspec.h>
#include <asm/sn/sn_sal.h>
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index 8725d5e8ab0..1f59ee2226c 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <asm/uv/uv_hub.h>
#if defined CONFIG_X86_64
#include <asm/uv/bios.h>
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 16f0abda142..ee5109a3cd9 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -20,6 +20,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -475,7 +476,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->data[0] == 0xff) {
/* we are being asked to broadcast to all partitions */
- for_each_bit(dest_partid, xpnet_broadcast_partitions,
+ for_each_set_bit(dest_partid, xpnet_broadcast_partitions,
xp_max_npartitions) {
xpnet_send(skb, queued_msg, start_addr, end_addr,
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index 98bcba521da..5f6852dff40 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -10,6 +10,7 @@
*/
#include <linux/tifm.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/idr.h>
diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c
new file mode 100644
index 00000000000..483ae5f7f68
--- /dev/null
+++ b/drivers/misc/tsl2550.c
@@ -0,0 +1,473 @@
+/*
+ * tsl2550.c - Linux kernel modules for ambient light sensor
+ *
+ * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
+ * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+#define TSL2550_DRV_NAME "tsl2550"
+#define DRIVER_VERSION "1.2"
+
+/*
+ * Defines
+ */
+
+#define TSL2550_POWER_DOWN 0x00
+#define TSL2550_POWER_UP 0x03
+#define TSL2550_STANDARD_RANGE 0x18
+#define TSL2550_EXTENDED_RANGE 0x1d
+#define TSL2550_READ_ADC0 0x43
+#define TSL2550_READ_ADC1 0x83
+
+/*
+ * Structs
+ */
+
+struct tsl2550_data {
+ struct i2c_client *client;
+ struct mutex update_lock;
+
+ unsigned int power_state:1;
+ unsigned int operating_mode:1;
+};
+
+/*
+ * Global data
+ */
+
+static const u8 TSL2550_MODE_RANGE[2] = {
+ TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
+};
+
+/*
+ * Management functions
+ */
+
+static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
+{
+ struct tsl2550_data *data = i2c_get_clientdata(client);
+
+ int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
+
+ data->operating_mode = mode;
+
+ return ret;
+}
+
+static int tsl2550_set_power_state(struct i2c_client *client, int state)
+{
+ struct tsl2550_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ if (state == 0)
+ ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
+ else {
+ ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
+
+ /* On power up we should reset operating mode also... */
+ tsl2550_set_operating_mode(client, data->operating_mode);
+ }
+
+ data->power_state = state;
+
+ return ret;
+}
+
+static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(client, cmd);
+ if (ret < 0)
+ return ret;
+ if (!(ret & 0x80))
+ return -EAGAIN;
+ return ret & 0x7f; /* remove the "valid" bit */
+}
+
+/*
+ * LUX calculation
+ */
+
+#define TSL2550_MAX_LUX 1846
+
+static const u8 ratio_lut[] = {
+ 100, 100, 100, 100, 100, 100, 100, 100,
+ 100, 100, 100, 100, 100, 100, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 98, 98, 98, 98, 98,
+ 98, 98, 97, 97, 97, 97, 97, 96,
+ 96, 96, 96, 95, 95, 95, 94, 94,
+ 93, 93, 93, 92, 92, 91, 91, 90,
+ 89, 89, 88, 87, 87, 86, 85, 84,
+ 83, 82, 81, 80, 79, 78, 77, 75,
+ 74, 73, 71, 69, 68, 66, 64, 62,
+ 60, 58, 56, 54, 52, 49, 47, 44,
+ 42, 41, 40, 40, 39, 39, 38, 38,
+ 37, 37, 37, 36, 36, 36, 35, 35,
+ 35, 35, 34, 34, 34, 34, 33, 33,
+ 33, 33, 32, 32, 32, 32, 32, 31,
+ 31, 31, 31, 31, 30, 30, 30, 30,
+ 30,
+};
+
+static const u16 count_lut[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46,
+ 49, 53, 57, 61, 65, 69, 73, 77,
+ 81, 85, 89, 93, 97, 101, 105, 109,
+ 115, 123, 131, 139, 147, 155, 163, 171,
+ 179, 187, 195, 203, 211, 219, 227, 235,
+ 247, 263, 279, 295, 311, 327, 343, 359,
+ 375, 391, 407, 423, 439, 455, 471, 487,
+ 511, 543, 575, 607, 639, 671, 703, 735,
+ 767, 799, 831, 863, 895, 927, 959, 991,
+ 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
+ 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
+ 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
+ 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
+};
+
+/*
+ * This function is described into Taos TSL2550 Designer's Notebook
+ * pages 2, 3.
+ */
+static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
+{
+ unsigned int lux;
+
+ /* Look up count from channel values */
+ u16 c0 = count_lut[ch0];
+ u16 c1 = count_lut[ch1];
+
+ /*
+ * Calculate ratio.
+ * Note: the "128" is a scaling factor
+ */
+ u8 r = 128;
+
+ /* Avoid division by 0 and count 1 cannot be greater than count 0 */
+ if (c1 <= c0)
+ if (c0) {
+ r = c1 * 128 / c0;
+
+ /* Calculate LUX */
+ lux = ((c0 - c1) * ratio_lut[r]) / 256;
+ } else
+ lux = 0;
+ else
+ return -EAGAIN;
+
+ /* LUX range check */
+ return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
+}
+
+/*
+ * SysFS support
+ */
+
+static ssize_t tsl2550_show_power_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+ return sprintf(buf, "%u\n", data->power_state);
+}
+
+static ssize_t tsl2550_store_power_state(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct tsl2550_data *data = i2c_get_clientdata(client);
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ int ret;
+
+ if (val < 0 || val > 1)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ ret = tsl2550_set_power_state(client, val);
+ mutex_unlock(&data->update_lock);
+
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+ tsl2550_show_power_state, tsl2550_store_power_state);
+
+static ssize_t tsl2550_show_operating_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+ return sprintf(buf, "%u\n", data->operating_mode);
+}
+
+static ssize_t tsl2550_store_operating_mode(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct tsl2550_data *data = i2c_get_clientdata(client);
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ int ret;
+
+ if (val < 0 || val > 1)
+ return -EINVAL;
+
+ if (data->power_state == 0)
+ return -EBUSY;
+
+ mutex_lock(&data->update_lock);
+ ret = tsl2550_set_operating_mode(client, val);
+ mutex_unlock(&data->update_lock);
+
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
+ tsl2550_show_operating_mode, tsl2550_store_operating_mode);
+
+static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
+{
+ struct tsl2550_data *data = i2c_get_clientdata(client);
+ u8 ch0, ch1;
+ int ret;
+
+ ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
+ if (ret < 0)
+ return ret;
+ ch0 = ret;
+
+ ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
+ if (ret < 0)
+ return ret;
+ ch1 = ret;
+
+ /* Do the job */
+ ret = tsl2550_calculate_lux(ch0, ch1);
+ if (ret < 0)
+ return ret;
+ if (data->operating_mode == 1)
+ ret *= 5;
+
+ return sprintf(buf, "%d\n", ret);
+}
+
+static ssize_t tsl2550_show_lux1_input(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct tsl2550_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ /* No LUX data if not operational */
+ if (!data->power_state)
+ return -EBUSY;
+
+ mutex_lock(&data->update_lock);
+ ret = __tsl2550_show_lux(client, buf);
+ mutex_unlock(&data->update_lock);
+
+ return ret;
+}
+
+static DEVICE_ATTR(lux1_input, S_IRUGO,
+ tsl2550_show_lux1_input, NULL);
+
+static struct attribute *tsl2550_attributes[] = {
+ &dev_attr_power_state.attr,
+ &dev_attr_operating_mode.attr,
+ &dev_attr_lux1_input.attr,
+ NULL
+};
+
+static const struct attribute_group tsl2550_attr_group = {
+ .attrs = tsl2550_attributes,
+};
+
+/*
+ * Initialization function
+ */
+
+static int tsl2550_init_client(struct i2c_client *client)
+{
+ struct tsl2550_data *data = i2c_get_clientdata(client);
+ int err;
+
+ /*
+ * Probe the chip. To do so we try to power up the device and then to
+ * read back the 0x03 code
+ */
+ err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
+ if (err < 0)
+ return err;
+ if (err != TSL2550_POWER_UP)
+ return -ENODEV;
+ data->power_state = 1;
+
+ /* Set the default operating mode */
+ err = i2c_smbus_write_byte(client,
+ TSL2550_MODE_RANGE[data->operating_mode]);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+
+static struct i2c_driver tsl2550_driver;
+static int __devinit tsl2550_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct tsl2550_data *data;
+ int *opmode, err = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
+ | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
+ err = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ data->client = client;
+ i2c_set_clientdata(client, data);
+
+ /* Check platform data */
+ opmode = client->dev.platform_data;
+ if (opmode) {
+ if (*opmode < 0 || *opmode > 1) {
+ dev_err(&client->dev, "invalid operating_mode (%d)\n",
+ *opmode);
+ err = -EINVAL;
+ goto exit_kfree;
+ }
+ data->operating_mode = *opmode;
+ } else
+ data->operating_mode = 0; /* default mode is standard */
+ dev_info(&client->dev, "%s operating mode\n",
+ data->operating_mode ? "extended" : "standard");
+
+ mutex_init(&data->update_lock);
+
+ /* Initialize the TSL2550 chip */
+ err = tsl2550_init_client(client);
+ if (err)
+ goto exit_kfree;
+
+ /* Register sysfs hooks */
+ err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
+ if (err)
+ goto exit_kfree;
+
+ dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
+
+ return 0;
+
+exit_kfree:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int __devexit tsl2550_remove(struct i2c_client *client)
+{
+ sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
+
+ /* Power down the device */
+ tsl2550_set_power_state(client, 0);
+
+ kfree(i2c_get_clientdata(client));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ return tsl2550_set_power_state(client, 0);
+}
+
+static int tsl2550_resume(struct i2c_client *client)
+{
+ return tsl2550_set_power_state(client, 1);
+}
+
+#else
+
+#define tsl2550_suspend NULL
+#define tsl2550_resume NULL
+
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id tsl2550_id[] = {
+ { "tsl2550", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tsl2550_id);
+
+static struct i2c_driver tsl2550_driver = {
+ .driver = {
+ .name = TSL2550_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .suspend = tsl2550_suspend,
+ .resume = tsl2550_resume,
+ .probe = tsl2550_probe,
+ .remove = __devexit_p(tsl2550_remove),
+ .id_table = tsl2550_id,
+};
+
+static int __init tsl2550_init(void)
+{
+ return i2c_add_driver(&tsl2550_driver);
+}
+
+static void __exit tsl2550_exit(void)
+{
+ i2c_del_driver(&tsl2550_driver);
+}
+
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tsl2550_init);
+module_exit(tsl2550_exit);
diff --git a/drivers/misc/vmware_balloon.c b/drivers/misc/vmware_balloon.c
new file mode 100644
index 00000000000..e7161c4e379
--- /dev/null
+++ b/drivers/misc/vmware_balloon.c
@@ -0,0 +1,832 @@
+/*
+ * VMware Balloon driver.
+ *
+ * Copyright (C) 2000-2010, VMware, 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; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT. 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.
+ *
+ * Maintained by: Dmitry Torokhov <dtor@vmware.com>
+ */
+
+/*
+ * This is VMware physical memory management driver for Linux. The driver
+ * acts like a "balloon" that can be inflated to reclaim physical pages by
+ * reserving them in the guest and invalidating them in the monitor,
+ * freeing up the underlying machine pages so they can be allocated to
+ * other guests. The balloon can also be deflated to allow the guest to
+ * use more physical memory. Higher level policies can control the sizes
+ * of balloons in VMs in order to manage physical memory resources.
+ */
+
+//#define DEBUG
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <asm/vmware.h>
+
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver");
+MODULE_VERSION("1.2.1.0-K");
+MODULE_ALIAS("dmi:*:svnVMware*:*");
+MODULE_ALIAS("vmware_vmmemctl");
+MODULE_LICENSE("GPL");
+
+/*
+ * Various constants controlling rate of inflaint/deflating balloon,
+ * measured in pages.
+ */
+
+/*
+ * Rate of allocating memory when there is no memory pressure
+ * (driver performs non-sleeping allocations).
+ */
+#define VMW_BALLOON_NOSLEEP_ALLOC_MAX 16384U
+
+/*
+ * Rates of memory allocaton when guest experiences memory pressure
+ * (driver performs sleeping allocations).
+ */
+#define VMW_BALLOON_RATE_ALLOC_MIN 512U
+#define VMW_BALLOON_RATE_ALLOC_MAX 2048U
+#define VMW_BALLOON_RATE_ALLOC_INC 16U
+
+/*
+ * Rates for releasing pages while deflating balloon.
+ */
+#define VMW_BALLOON_RATE_FREE_MIN 512U
+#define VMW_BALLOON_RATE_FREE_MAX 16384U
+#define VMW_BALLOON_RATE_FREE_INC 16U
+
+/*
+ * When guest is under memory pressure, use a reduced page allocation
+ * rate for next several cycles.
+ */
+#define VMW_BALLOON_SLOW_CYCLES 4
+
+/*
+ * Use __GFP_HIGHMEM to allow pages from HIGHMEM zone. We don't
+ * allow wait (__GFP_WAIT) for NOSLEEP page allocations. Use
+ * __GFP_NOWARN, to suppress page allocation failure warnings.
+ */
+#define VMW_PAGE_ALLOC_NOSLEEP (__GFP_HIGHMEM|__GFP_NOWARN)
+
+/*
+ * Use GFP_HIGHUSER when executing in a separate kernel thread
+ * context and allocation can sleep. This is less stressful to
+ * the guest memory system, since it allows the thread to block
+ * while memory is reclaimed, and won't take pages from emergency
+ * low-memory pools.
+ */
+#define VMW_PAGE_ALLOC_CANSLEEP (GFP_HIGHUSER)
+
+/* Maximum number of page allocations without yielding processor */
+#define VMW_BALLOON_YIELD_THRESHOLD 1024
+
+
+/*
+ * Hypervisor communication port definitions.
+ */
+#define VMW_BALLOON_HV_PORT 0x5670
+#define VMW_BALLOON_HV_MAGIC 0x456c6d6f
+#define VMW_BALLOON_PROTOCOL_VERSION 2
+#define VMW_BALLOON_GUEST_ID 1 /* Linux */
+
+#define VMW_BALLOON_CMD_START 0
+#define VMW_BALLOON_CMD_GET_TARGET 1
+#define VMW_BALLOON_CMD_LOCK 2
+#define VMW_BALLOON_CMD_UNLOCK 3
+#define VMW_BALLOON_CMD_GUEST_ID 4
+
+/* error codes */
+#define VMW_BALLOON_SUCCESS 0
+#define VMW_BALLOON_FAILURE -1
+#define VMW_BALLOON_ERROR_CMD_INVALID 1
+#define VMW_BALLOON_ERROR_PPN_INVALID 2
+#define VMW_BALLOON_ERROR_PPN_LOCKED 3
+#define VMW_BALLOON_ERROR_PPN_UNLOCKED 4
+#define VMW_BALLOON_ERROR_PPN_PINNED 5
+#define VMW_BALLOON_ERROR_PPN_NOTNEEDED 6
+#define VMW_BALLOON_ERROR_RESET 7
+#define VMW_BALLOON_ERROR_BUSY 8
+
+#define VMWARE_BALLOON_CMD(cmd, data, result) \
+({ \
+ unsigned long __stat, __dummy1, __dummy2; \
+ __asm__ __volatile__ ("inl (%%dx)" : \
+ "=a"(__stat), \
+ "=c"(__dummy1), \
+ "=d"(__dummy2), \
+ "=b"(result) : \
+ "0"(VMW_BALLOON_HV_MAGIC), \
+ "1"(VMW_BALLOON_CMD_##cmd), \
+ "2"(VMW_BALLOON_HV_PORT), \
+ "3"(data) : \
+ "memory"); \
+ result &= -1UL; \
+ __stat & -1UL; \
+})
+
+#ifdef CONFIG_DEBUG_FS
+struct vmballoon_stats {
+ unsigned int timer;
+
+ /* allocation statustics */
+ unsigned int alloc;
+ unsigned int alloc_fail;
+ unsigned int sleep_alloc;
+ unsigned int sleep_alloc_fail;
+ unsigned int refused_alloc;
+ unsigned int refused_free;
+ unsigned int free;
+
+ /* monitor operations */
+ unsigned int lock;
+ unsigned int lock_fail;
+ unsigned int unlock;
+ unsigned int unlock_fail;
+ unsigned int target;
+ unsigned int target_fail;
+ unsigned int start;
+ unsigned int start_fail;
+ unsigned int guest_type;
+ unsigned int guest_type_fail;
+};
+
+#define STATS_INC(stat) (stat)++
+#else
+#define STATS_INC(stat)
+#endif
+
+struct vmballoon {
+
+ /* list of reserved physical pages */
+ struct list_head pages;
+
+ /* transient list of non-balloonable pages */
+ struct list_head refused_pages;
+
+ /* balloon size in pages */
+ unsigned int size;
+ unsigned int target;
+
+ /* reset flag */
+ bool reset_required;
+
+ /* adjustment rates (pages per second) */
+ unsigned int rate_alloc;
+ unsigned int rate_free;
+
+ /* slowdown page allocations for next few cycles */
+ unsigned int slow_allocation_cycles;
+
+#ifdef CONFIG_DEBUG_FS
+ /* statistics */
+ struct vmballoon_stats stats;
+
+ /* debugfs file exporting statistics */
+ struct dentry *dbg_entry;
+#endif
+
+ struct sysinfo sysinfo;
+
+ struct delayed_work dwork;
+};
+
+static struct vmballoon balloon;
+static struct workqueue_struct *vmballoon_wq;
+
+/*
+ * Send "start" command to the host, communicating supported version
+ * of the protocol.
+ */
+static bool vmballoon_send_start(struct vmballoon *b)
+{
+ unsigned long status, dummy;
+
+ STATS_INC(b->stats.start);
+
+ status = VMWARE_BALLOON_CMD(START, VMW_BALLOON_PROTOCOL_VERSION, dummy);
+ if (status == VMW_BALLOON_SUCCESS)
+ return true;
+
+ pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+ STATS_INC(b->stats.start_fail);
+ return false;
+}
+
+static bool vmballoon_check_status(struct vmballoon *b, unsigned long status)
+{
+ switch (status) {
+ case VMW_BALLOON_SUCCESS:
+ return true;
+
+ case VMW_BALLOON_ERROR_RESET:
+ b->reset_required = true;
+ /* fall through */
+
+ default:
+ return false;
+ }
+}
+
+/*
+ * Communicate guest type to the host so that it can adjust ballooning
+ * algorithm to the one most appropriate for the guest. This command
+ * is normally issued after sending "start" command and is part of
+ * standard reset sequence.
+ */
+static bool vmballoon_send_guest_id(struct vmballoon *b)
+{
+ unsigned long status, dummy;
+
+ status = VMWARE_BALLOON_CMD(GUEST_ID, VMW_BALLOON_GUEST_ID, dummy);
+
+ STATS_INC(b->stats.guest_type);
+
+ if (vmballoon_check_status(b, status))
+ return true;
+
+ pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+ STATS_INC(b->stats.guest_type_fail);
+ return false;
+}
+
+/*
+ * Retrieve desired balloon size from the host.
+ */
+static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target)
+{
+ unsigned long status;
+ unsigned long target;
+ unsigned long limit;
+ u32 limit32;
+
+ /*
+ * si_meminfo() is cheap. Moreover, we want to provide dynamic
+ * max balloon size later. So let us call si_meminfo() every
+ * iteration.
+ */
+ si_meminfo(&b->sysinfo);
+ limit = b->sysinfo.totalram;
+
+ /* Ensure limit fits in 32-bits */
+ limit32 = (u32)limit;
+ if (limit != limit32)
+ return false;
+
+ /* update stats */
+ STATS_INC(b->stats.target);
+
+ status = VMWARE_BALLOON_CMD(GET_TARGET, limit, target);
+ if (vmballoon_check_status(b, status)) {
+ *new_target = target;
+ return true;
+ }
+
+ pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+ STATS_INC(b->stats.target_fail);
+ return false;
+}
+
+/*
+ * Notify the host about allocated page so that host can use it without
+ * fear that guest will need it. Host may reject some pages, we need to
+ * check the return value and maybe submit a different page.
+ */
+static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn)
+{
+ unsigned long status, dummy;
+ u32 pfn32;
+
+ pfn32 = (u32)pfn;
+ if (pfn32 != pfn)
+ return false;
+
+ STATS_INC(b->stats.lock);
+
+ status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
+ if (vmballoon_check_status(b, status))
+ return true;
+
+ pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
+ STATS_INC(b->stats.lock_fail);
+ return false;
+}
+
+/*
+ * Notify the host that guest intends to release given page back into
+ * the pool of available (to the guest) pages.
+ */
+static bool vmballoon_send_unlock_page(struct vmballoon *b, unsigned long pfn)
+{
+ unsigned long status, dummy;
+ u32 pfn32;
+
+ pfn32 = (u32)pfn;
+ if (pfn32 != pfn)
+ return false;
+
+ STATS_INC(b->stats.unlock);
+
+ status = VMWARE_BALLOON_CMD(UNLOCK, pfn, dummy);
+ if (vmballoon_check_status(b, status))
+ return true;
+
+ pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
+ STATS_INC(b->stats.unlock_fail);
+ return false;
+}
+
+/*
+ * Quickly release all pages allocated for the balloon. This function is
+ * called when host decides to "reset" balloon for one reason or another.
+ * Unlike normal "deflate" we do not (shall not) notify host of the pages
+ * being released.
+ */
+static void vmballoon_pop(struct vmballoon *b)
+{
+ struct page *page, *next;
+ unsigned int count = 0;
+
+ list_for_each_entry_safe(page, next, &b->pages, lru) {
+ list_del(&page->lru);
+ __free_page(page);
+ STATS_INC(b->stats.free);
+ b->size--;
+
+ if (++count >= b->rate_free) {
+ count = 0;
+ cond_resched();
+ }
+ }
+}
+
+/*
+ * Perform standard reset sequence by popping the balloon (in case it
+ * is not empty) and then restarting protocol. This operation normally
+ * happens when host responds with VMW_BALLOON_ERROR_RESET to a command.
+ */
+static void vmballoon_reset(struct vmballoon *b)
+{
+ /* free all pages, skipping monitor unlock */
+ vmballoon_pop(b);
+
+ if (vmballoon_send_start(b)) {
+ b->reset_required = false;
+ if (!vmballoon_send_guest_id(b))
+ pr_err("failed to send guest ID to the host\n");
+ }
+}
+
+/*
+ * Allocate (or reserve) a page for the balloon and notify the host. If host
+ * refuses the page put it on "refuse" list and allocate another one until host
+ * is satisfied. "Refused" pages are released at the end of inflation cycle
+ * (when we allocate b->rate_alloc pages).
+ */
+static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
+{
+ struct page *page;
+ gfp_t flags;
+ bool locked = false;
+
+ do {
+ if (!can_sleep)
+ STATS_INC(b->stats.alloc);
+ else
+ STATS_INC(b->stats.sleep_alloc);
+
+ flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
+ page = alloc_page(flags);
+ if (!page) {
+ if (!can_sleep)
+ STATS_INC(b->stats.alloc_fail);
+ else
+ STATS_INC(b->stats.sleep_alloc_fail);
+ return -ENOMEM;
+ }
+
+ /* inform monitor */
+ locked = vmballoon_send_lock_page(b, page_to_pfn(page));
+ if (!locked) {
+ if (b->reset_required) {
+ __free_page(page);
+ return -EIO;
+ }
+
+ /* place on list of non-balloonable pages, retry allocation */
+ list_add(&page->lru, &b->refused_pages);
+ STATS_INC(b->stats.refused_alloc);
+ }
+ } while (!locked);
+
+ /* track allocated page */
+ list_add(&page->lru, &b->pages);
+
+ /* update balloon size */
+ b->size++;
+
+ return 0;
+}
+
+/*
+ * Release the page allocated for the balloon. Note that we first notify
+ * the host so it can make sure the page will be available for the guest
+ * to use, if needed.
+ */
+static int vmballoon_release_page(struct vmballoon *b, struct page *page)
+{
+ if (!vmballoon_send_unlock_page(b, page_to_pfn(page)))
+ return -EIO;
+
+ list_del(&page->lru);
+
+ /* deallocate page */
+ __free_page(page);
+ STATS_INC(b->stats.free);
+
+ /* update balloon size */
+ b->size--;
+
+ return 0;
+}
+
+/*
+ * Release pages that were allocated while attempting to inflate the
+ * balloon but were refused by the host for one reason or another.
+ */
+static void vmballoon_release_refused_pages(struct vmballoon *b)
+{
+ struct page *page, *next;
+
+ list_for_each_entry_safe(page, next, &b->refused_pages, lru) {
+ list_del(&page->lru);
+ __free_page(page);
+ STATS_INC(b->stats.refused_free);
+ }
+}
+
+/*
+ * Inflate the balloon towards its target size. Note that we try to limit
+ * the rate of allocation to make sure we are not choking the rest of the
+ * system.
+ */
+static void vmballoon_inflate(struct vmballoon *b)
+{
+ unsigned int goal;
+ unsigned int rate;
+ unsigned int i;
+ unsigned int allocations = 0;
+ int error = 0;
+ bool alloc_can_sleep = false;
+
+ pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
+
+ /*
+ * First try NOSLEEP page allocations to inflate balloon.
+ *
+ * If we do not throttle nosleep allocations, we can drain all
+ * free pages in the guest quickly (if the balloon target is high).
+ * As a side-effect, draining free pages helps to inform (force)
+ * the guest to start swapping if balloon target is not met yet,
+ * which is a desired behavior. However, balloon driver can consume
+ * all available CPU cycles if too many pages are allocated in a
+ * second. Therefore, we throttle nosleep allocations even when
+ * the guest is not under memory pressure. OTOH, if we have already
+ * predicted that the guest is under memory pressure, then we
+ * slowdown page allocations considerably.
+ */
+
+ goal = b->target - b->size;
+ /*
+ * Start with no sleep allocation rate which may be higher
+ * than sleeping allocation rate.
+ */
+ rate = b->slow_allocation_cycles ?
+ b->rate_alloc : VMW_BALLOON_NOSLEEP_ALLOC_MAX;
+
+ pr_debug("%s - goal: %d, no-sleep rate: %d, sleep rate: %d\n",
+ __func__, goal, rate, b->rate_alloc);
+
+ for (i = 0; i < goal; i++) {
+
+ error = vmballoon_reserve_page(b, alloc_can_sleep);
+ if (error) {
+ if (error != -ENOMEM) {
+ /*
+ * Not a page allocation failure, stop this
+ * cycle. Maybe we'll get new target from
+ * the host soon.
+ */
+ break;
+ }
+
+ if (alloc_can_sleep) {
+ /*
+ * CANSLEEP page allocation failed, so guest
+ * is under severe memory pressure. Quickly
+ * decrease allocation rate.
+ */
+ b->rate_alloc = max(b->rate_alloc / 2,
+ VMW_BALLOON_RATE_ALLOC_MIN);
+ break;
+ }
+
+ /*
+ * NOSLEEP page allocation failed, so the guest is
+ * under memory pressure. Let us slow down page
+ * allocations for next few cycles so that the guest
+ * gets out of memory pressure. Also, if we already
+ * allocated b->rate_alloc pages, let's pause,
+ * otherwise switch to sleeping allocations.
+ */
+ b->slow_allocation_cycles = VMW_BALLOON_SLOW_CYCLES;
+
+ if (i >= b->rate_alloc)
+ break;
+
+ alloc_can_sleep = true;
+ /* Lower rate for sleeping allocations. */
+ rate = b->rate_alloc;
+ }
+
+ if (++allocations > VMW_BALLOON_YIELD_THRESHOLD) {
+ cond_resched();
+ allocations = 0;
+ }
+
+ if (i >= rate) {
+ /* We allocated enough pages, let's take a break. */
+ break;
+ }
+ }
+
+ /*
+ * We reached our goal without failures so try increasing
+ * allocation rate.
+ */
+ if (error == 0 && i >= b->rate_alloc) {
+ unsigned int mult = i / b->rate_alloc;
+
+ b->rate_alloc =
+ min(b->rate_alloc + mult * VMW_BALLOON_RATE_ALLOC_INC,
+ VMW_BALLOON_RATE_ALLOC_MAX);
+ }
+
+ vmballoon_release_refused_pages(b);
+}
+
+/*
+ * Decrease the size of the balloon allowing guest to use more memory.
+ */
+static void vmballoon_deflate(struct vmballoon *b)
+{
+ struct page *page, *next;
+ unsigned int i = 0;
+ unsigned int goal;
+ int error;
+
+ pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
+
+ /* limit deallocation rate */
+ goal = min(b->size - b->target, b->rate_free);
+
+ pr_debug("%s - goal: %d, rate: %d\n", __func__, goal, b->rate_free);
+
+ /* free pages to reach target */
+ list_for_each_entry_safe(page, next, &b->pages, lru) {
+ error = vmballoon_release_page(b, page);
+ if (error) {
+ /* quickly decrease rate in case of error */
+ b->rate_free = max(b->rate_free / 2,
+ VMW_BALLOON_RATE_FREE_MIN);
+ return;
+ }
+
+ if (++i >= goal)
+ break;
+ }
+
+ /* slowly increase rate if there were no errors */
+ b->rate_free = min(b->rate_free + VMW_BALLOON_RATE_FREE_INC,
+ VMW_BALLOON_RATE_FREE_MAX);
+}
+
+/*
+ * Balloon work function: reset protocol, if needed, get the new size and
+ * adjust balloon as needed. Repeat in 1 sec.
+ */
+static void vmballoon_work(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct vmballoon *b = container_of(dwork, struct vmballoon, dwork);
+ unsigned int target;
+
+ STATS_INC(b->stats.timer);
+
+ if (b->reset_required)
+ vmballoon_reset(b);
+
+ if (b->slow_allocation_cycles > 0)
+ b->slow_allocation_cycles--;
+
+ if (vmballoon_send_get_target(b, &target)) {
+ /* update target, adjust size */
+ b->target = target;
+
+ if (b->size < target)
+ vmballoon_inflate(b);
+ else if (b->size > target)
+ vmballoon_deflate(b);
+ }
+
+ queue_delayed_work(vmballoon_wq, dwork, round_jiffies_relative(HZ));
+}
+
+/*
+ * DEBUGFS Interface
+ */
+#ifdef CONFIG_DEBUG_FS
+
+static int vmballoon_debug_show(struct seq_file *f, void *offset)
+{
+ struct vmballoon *b = f->private;
+ struct vmballoon_stats *stats = &b->stats;
+
+ /* format size info */
+ seq_printf(f,
+ "target: %8d pages\n"
+ "current: %8d pages\n",
+ b->target, b->size);
+
+ /* format rate info */
+ seq_printf(f,
+ "rateNoSleepAlloc: %8d pages/sec\n"
+ "rateSleepAlloc: %8d pages/sec\n"
+ "rateFree: %8d pages/sec\n",
+ VMW_BALLOON_NOSLEEP_ALLOC_MAX,
+ b->rate_alloc, b->rate_free);
+
+ seq_printf(f,
+ "\n"
+ "timer: %8u\n"
+ "start: %8u (%4u failed)\n"
+ "guestType: %8u (%4u failed)\n"
+ "lock: %8u (%4u failed)\n"
+ "unlock: %8u (%4u failed)\n"
+ "target: %8u (%4u failed)\n"
+ "primNoSleepAlloc: %8u (%4u failed)\n"
+ "primCanSleepAlloc: %8u (%4u failed)\n"
+ "primFree: %8u\n"
+ "errAlloc: %8u\n"
+ "errFree: %8u\n",
+ stats->timer,
+ stats->start, stats->start_fail,
+ stats->guest_type, stats->guest_type_fail,
+ stats->lock, stats->lock_fail,
+ stats->unlock, stats->unlock_fail,
+ stats->target, stats->target_fail,
+ stats->alloc, stats->alloc_fail,
+ stats->sleep_alloc, stats->sleep_alloc_fail,
+ stats->free,
+ stats->refused_alloc, stats->refused_free);
+
+ return 0;
+}
+
+static int vmballoon_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, vmballoon_debug_show, inode->i_private);
+}
+
+static const struct file_operations vmballoon_debug_fops = {
+ .owner = THIS_MODULE,
+ .open = vmballoon_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init vmballoon_debugfs_init(struct vmballoon *b)
+{
+ int error;
+
+ b->dbg_entry = debugfs_create_file("vmmemctl", S_IRUGO, NULL, b,
+ &vmballoon_debug_fops);
+ if (IS_ERR(b->dbg_entry)) {
+ error = PTR_ERR(b->dbg_entry);
+ pr_err("failed to create debugfs entry, error: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+
+static void __exit vmballoon_debugfs_exit(struct vmballoon *b)
+{
+ debugfs_remove(b->dbg_entry);
+}
+
+#else
+
+static inline int vmballoon_debugfs_init(struct vmballoon *b)
+{
+ return 0;
+}
+
+static inline void vmballoon_debugfs_exit(struct vmballoon *b)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __init vmballoon_init(void)
+{
+ int error;
+
+ /*
+ * Check if we are running on VMware's hypervisor and bail out
+ * if we are not.
+ */
+ if (!vmware_platform())
+ return -ENODEV;
+
+ vmballoon_wq = create_freezeable_workqueue("vmmemctl");
+ if (!vmballoon_wq) {
+ pr_err("failed to create workqueue\n");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&balloon.pages);
+ INIT_LIST_HEAD(&balloon.refused_pages);
+
+ /* initialize rates */
+ balloon.rate_alloc = VMW_BALLOON_RATE_ALLOC_MAX;
+ balloon.rate_free = VMW_BALLOON_RATE_FREE_MAX;
+
+ INIT_DELAYED_WORK(&balloon.dwork, vmballoon_work);
+
+ /*
+ * Start balloon.
+ */
+ if (!vmballoon_send_start(&balloon)) {
+ pr_err("failed to send start command to the host\n");
+ error = -EIO;
+ goto fail;
+ }
+
+ if (!vmballoon_send_guest_id(&balloon)) {
+ pr_err("failed to send guest ID to the host\n");
+ error = -EIO;
+ goto fail;
+ }
+
+ error = vmballoon_debugfs_init(&balloon);
+ if (error)
+ goto fail;
+
+ queue_delayed_work(vmballoon_wq, &balloon.dwork, 0);
+
+ return 0;
+
+fail:
+ destroy_workqueue(vmballoon_wq);
+ return error;
+}
+module_init(vmballoon_init);
+
+static void __exit vmballoon_exit(void)
+{
+ cancel_delayed_work_sync(&balloon.dwork);
+ destroy_workqueue(vmballoon_wq);
+
+ vmballoon_debugfs_exit(&balloon);
+
+ /*
+ * Deallocate all reserved memory, and reset connection with monitor.
+ * Reset connection before deallocating memory to avoid potential for
+ * additional spurious resets from guest touching deallocated pages.
+ */
+ vmballoon_send_start(&balloon);
+ vmballoon_pop(&balloon);
+}
+module_exit(vmballoon_exit);
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 1f552c6e757..cb9fbc83b09 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/hdreg.h>
#include <linux/kdev_t.h>
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index e7f8027165e..445d7db2277 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -13,6 +13,7 @@
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
+#include <linux/slab.h>
#include <linux/scatterlist.h>
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 381fe032caa..d6ded247d94 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/freezer.h>
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 3fab78ba895..a0716967b7c 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -34,10 +34,10 @@
#include <linux/seq_file.h>
#include <linux/serial_reg.h>
#include <linux/circ_buf.h>
-#include <linux/gfp.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/kfifo.h>
+#include <linux/slab.h>
#include <linux/mmc/core.h>
#include <linux/mmc/card.h>
@@ -575,7 +575,7 @@ static int uart_carrier_raised(struct tty_port *tport)
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
unsigned int ret = sdio_uart_claim_func(port);
- if (ret) /* Missing hardware shoudn't block for carrier */
+ if (ret) /* Missing hardware shouldn't block for carrier */
return 1;
ret = sdio_uart_get_mctrl(port);
sdio_uart_release_func(port);
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index bdb165f9304..49d9dcaeca4 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 30acd526582..3168ebd616b 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1089,6 +1089,7 @@ void mmc_rescan(struct work_struct *work)
mmc_claim_host(host);
mmc_power_up(host);
+ sdio_reset(host);
mmc_go_idle(host);
mmc_send_if_cond(host, host->ocr_avail);
@@ -1151,6 +1152,9 @@ void mmc_stop_host(struct mmc_host *host)
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
+ /* clear pm flags now and let card drivers set them as needed */
+ host->pm_flags = 0;
+
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
if (host->bus_ops->remove)
@@ -1273,12 +1277,13 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
+ host->pm_flags = 0;
err = 0;
}
}
mmc_bus_put(host);
- if (!err)
+ if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
mmc_power_off(host);
return err;
@@ -1296,8 +1301,10 @@ int mmc_resume_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
- mmc_power_up(host);
- mmc_select_voltage(host, host->ocr);
+ if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
+ mmc_power_up(host);
+ mmc_select_voltage(host, host->ocr);
+ }
BUG_ON(!host->bus_ops->resume);
err = host->bus_ops->resume(host);
if (err) {
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 96d10f40fb2..53cb380c098 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -10,6 +10,7 @@
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/mmc/card.h>
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index a268d12f1af..47353909e34 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -16,6 +16,7 @@
#include <linux/idr.h>
#include <linux/pagemap.h>
#include <linux/leds.h>
+#include <linux/slab.h>
#include <linux/mmc/host.h>
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 0eac6c81490..89f7a25b7ac 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -11,6 +11,7 @@
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
@@ -225,7 +226,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
mmc_card_set_blockaddr(card);
}
- switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+ switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
card->ext_csd.hs_max_dtr = 52000000;
break;
@@ -237,7 +238,6 @@ static int mmc_read_ext_csd(struct mmc_card *card)
printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
"support any high-speed modes.\n",
mmc_hostname(card->host));
- goto out;
}
if (card->ext_csd.rev >= 3) {
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index d2cb5c63439..326447c9ede 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -9,6 +9,7 @@
* your option) any later version.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/scatterlist.h>
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index fdd414eded0..5eac21df480 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -11,6 +11,7 @@
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 06b64085a35..2dd4cfe7ca1 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -188,6 +188,40 @@ static int sdio_disable_cd(struct mmc_card *card)
}
/*
+ * Devices that remain active during a system suspend are
+ * put back into 1-bit mode.
+ */
+static int sdio_disable_wide(struct mmc_card *card)
+{
+ int ret;
+ u8 ctrl;
+
+ if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
+ return 0;
+
+ if (card->cccr.low_speed && !card->cccr.wide_bus)
+ return 0;
+
+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
+ if (ret)
+ return ret;
+
+ if (!(ctrl & SDIO_BUS_WIDTH_4BIT))
+ return 0;
+
+ ctrl &= ~SDIO_BUS_WIDTH_4BIT;
+ ctrl |= SDIO_BUS_ASYNC_INT;
+
+ ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
+ if (ret)
+ return ret;
+
+ mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1);
+
+ return 0;
+}
+
+/*
* Test if the card supports high-speed mode and, if so, switch to it.
*/
static int sdio_enable_hs(struct mmc_card *card)
@@ -224,7 +258,7 @@ static int sdio_enable_hs(struct mmc_card *card)
* we're trying to reinitialise.
*/
static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
- struct mmc_card *oldcard)
+ struct mmc_card *oldcard, int powered_resume)
{
struct mmc_card *card;
int err;
@@ -235,9 +269,11 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
/*
* Inform the card of the voltage
*/
- err = mmc_send_io_op_cond(host, host->ocr, &ocr);
- if (err)
- goto err;
+ if (!powered_resume) {
+ err = mmc_send_io_op_cond(host, host->ocr, &ocr);
+ if (err)
+ goto err;
+ }
/*
* For SPI, enable CRC as appropriate.
@@ -262,7 +298,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
/*
* For native busses: set card RCA and quit open drain mode.
*/
- if (!mmc_host_is_spi(host)) {
+ if (!powered_resume && !mmc_host_is_spi(host)) {
err = mmc_send_relative_addr(host, &card->rca);
if (err)
goto remove;
@@ -273,7 +309,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
/*
* Select card, as all following commands rely on that.
*/
- if (!mmc_host_is_spi(host)) {
+ if (!powered_resume && !mmc_host_is_spi(host)) {
err = mmc_select_card(card);
if (err)
goto remove;
@@ -425,6 +461,12 @@ static int mmc_sdio_suspend(struct mmc_host *host)
}
}
+ if (!err && host->pm_flags & MMC_PM_KEEP_POWER) {
+ mmc_claim_host(host);
+ sdio_disable_wide(host->card);
+ mmc_release_host(host);
+ }
+
return err;
}
@@ -437,7 +479,13 @@ static int mmc_sdio_resume(struct mmc_host *host)
/* Basic card reinitialization. */
mmc_claim_host(host);
- err = mmc_sdio_init_card(host, host->ocr, host->card);
+ err = mmc_sdio_init_card(host, host->ocr, host->card,
+ (host->pm_flags & MMC_PM_KEEP_POWER));
+ if (!err)
+ /* We may have switched to 1-bit mode during suspend. */
+ err = sdio_enable_wide(host->card);
+ if (!err && host->sdio_irqs)
+ mmc_signal_sdio_irq(host);
mmc_release_host(host);
/*
@@ -507,7 +555,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
/*
* Detect and init the card.
*/
- err = mmc_sdio_init_card(host, host->ocr, NULL);
+ err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
if (err)
goto err;
card = host->card;
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 9e060c87e64..4a890dcb95a 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 9538389783c..541bdb89e0c 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -14,6 +14,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index f9aa8a7deff..ff27c8c7135 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -189,7 +189,12 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
{
unsigned mval = min(func->card->host->max_seg_size,
func->card->host->max_blk_size);
- mval = min(mval, func->max_blksize);
+
+ if (mmc_blksz_for_byte_mode(func->card))
+ mval = min(mval, func->cur_blksize);
+ else
+ mval = min(mval, func->max_blksize);
+
return min(mval, 512u); /* maximum size for byte mode */
}
@@ -635,3 +640,52 @@ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
*err_ret = ret;
}
EXPORT_SYMBOL_GPL(sdio_f0_writeb);
+
+/**
+ * sdio_get_host_pm_caps - get host power management capabilities
+ * @func: SDIO function attached to host
+ *
+ * Returns a capability bitmask corresponding to power management
+ * features supported by the host controller that the card function
+ * might rely upon during a system suspend. The host doesn't need
+ * to be claimed, nor the function active, for this information to be
+ * obtained.
+ */
+mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
+{
+ BUG_ON(!func);
+ BUG_ON(!func->card);
+
+ return func->card->host->pm_caps;
+}
+EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);
+
+/**
+ * sdio_set_host_pm_flags - set wanted host power management capabilities
+ * @func: SDIO function attached to host
+ *
+ * Set a capability bitmask corresponding to wanted host controller
+ * power management features for the upcoming suspend state.
+ * This must be called, if needed, each time the suspend method of
+ * the function driver is called, and must contain only bits that
+ * were returned by sdio_get_host_pm_caps().
+ * The host doesn't need to be claimed, nor the function active,
+ * for this information to be set.
+ */
+int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
+{
+ struct mmc_host *host;
+
+ BUG_ON(!func);
+ BUG_ON(!func->card);
+
+ host = func->card->host;
+
+ if (flags & ~host->pm_caps)
+ return -EINVAL;
+
+ /* function suspend methods are serialized, hence no lock needed */
+ host->pm_flags |= flags;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index 4eb7825fd1a..dea36d9c22e 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -67,13 +67,13 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
return err;
}
-int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
- unsigned addr, u8 in, u8* out)
+static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn,
+ unsigned addr, u8 in, u8 *out)
{
struct mmc_command cmd;
int err;
- BUG_ON(!card);
+ BUG_ON(!host);
BUG_ON(fn > 7);
/* sanity check */
@@ -90,11 +90,11 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
cmd.arg |= in;
cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
- err = mmc_wait_for_cmd(card->host, &cmd, 0);
+ err = mmc_wait_for_cmd(host, &cmd, 0);
if (err)
return err;
- if (mmc_host_is_spi(card->host)) {
+ if (mmc_host_is_spi(host)) {
/* host driver already reported errors */
} else {
if (cmd.resp[0] & R5_ERROR)
@@ -106,7 +106,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
}
if (out) {
- if (mmc_host_is_spi(card->host))
+ if (mmc_host_is_spi(host))
*out = (cmd.resp[0] >> 8) & 0xFF;
else
*out = cmd.resp[0] & 0xFF;
@@ -115,6 +115,13 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
return 0;
}
+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
+ unsigned addr, u8 in, u8 *out)
+{
+ BUG_ON(!card);
+ return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out);
+}
+
int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)
{
@@ -182,3 +189,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
return 0;
}
+int sdio_reset(struct mmc_host *host)
+{
+ int ret;
+ u8 abort;
+
+ /* SDIO Simplified Specification V2.0, 4.4 Reset for SDIO */
+
+ ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort);
+ if (ret)
+ abort = 0x08;
+ else
+ abort |= 0x08;
+
+ ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL);
+ return ret;
+}
+
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h
index e2e74b0d17d..12a4d3ab174 100644
--- a/drivers/mmc/core/sdio_ops.h
+++ b/drivers/mmc/core/sdio_ops.h
@@ -17,6 +17,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
unsigned addr, u8 in, u8* out);
int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz);
+int sdio_reset(struct mmc_host *host);
#endif
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index ce1d28884e2..2e13b94769f 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -69,20 +69,16 @@ config MMC_SDHCI_PCI
If unsure, say N.
config MMC_RICOH_MMC
- tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)"
+ bool "Ricoh MMC Controller Disabler (EXPERIMENTAL)"
depends on MMC_SDHCI_PCI
help
- This selects the disabler for the Ricoh MMC Controller. This
+ This adds a pci quirk to disable Ricoh MMC Controller. This
proprietary controller is unnecessary because the SDHCI driver
supports MMC cards on the SD controller, but if it is not
disabled, it will steal the MMC cards away - rendering them
- useless. It is safe to select this driver even if you don't
+ useless. It is safe to select this even if you don't
have a Ricoh based card reader.
-
- To compile this driver as a module, choose M here:
- the module will be called ricoh_mmc.
-
If unsure, say Y.
config MMC_SDHCI_OF
@@ -193,6 +189,7 @@ config MMC_AU1X
choice
prompt "Atmel SD/MMC Driver"
+ depends on AVR32 || ARCH_AT91
default MMC_ATMELMCI if AVR32
help
Choose which driver to use for the Atmel MCI Silicon
@@ -368,7 +365,7 @@ config MMC_SDRICOH_CS
config MMC_TMIO
tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
- depends on MFD_TMIO || MFD_ASIC3 || SUPERH
+ depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI
help
This provides support for the SD/MMC cell found in TC6393XB,
T7L66XB and also HTC ASIC3
@@ -399,7 +396,7 @@ config MMC_VIA_SDMMC
config SDH_BFIN
tristate "Blackfin Secure Digital Host support"
- depends on MMC && ((BF54x && !BF544) || (BF51x && !BF512))
+ depends on (BF54x && !BF544) || (BF51x && !BF512)
help
If you say yes here you will get support for the Blackfin on-chip
Secure Digital Host interface. This includes support for MMC and
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 3d253dd4240..f4803977dfc 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -12,7 +12,6 @@ obj-$(CONFIG_MMC_IMX) += imxmmc.o
obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
-obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 63924e0c7ea..a6dd7da3735 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -65,6 +65,7 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/atmel_pdc.h>
+#include <linux/gfp.h>
#include <linux/mmc/host.h>
@@ -78,6 +79,17 @@
#define DRIVER_NAME "at91_mci"
+static inline int at91mci_is_mci1rev2xx(void)
+{
+ return ( cpu_is_at91sam9260()
+ || cpu_is_at91sam9263()
+ || cpu_is_at91cap9()
+ || cpu_is_at91sam9rl()
+ || cpu_is_at91sam9g10()
+ || cpu_is_at91sam9g20()
+ );
+}
+
#define FL_SENT_COMMAND (1 << 0)
#define FL_SENT_STOP (1 << 1)
@@ -88,6 +100,10 @@
#define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg))
#define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg))
+#define MCI_BLKSIZE 512
+#define MCI_MAXBLKSIZE 4095
+#define MCI_BLKATONCE 256
+#define MCI_BUFSIZE (MCI_BLKSIZE * MCI_BLKATONCE)
/*
* Low level type for this driver
@@ -200,8 +216,8 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
size = data->blksz * data->blocks;
len = data->sg_len;
- /* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */
- if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+ /* MCI1 rev2xx Data Write Operation and number of bytes erratum */
+ if (at91mci_is_mci1rev2xx())
if (host->total_length == 12)
memset(dmabuf, 0, 12);
@@ -227,8 +243,10 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
for (index = 0; index < (amount / 4); index++)
*dmabuf++ = swab32(sgbuffer[index]);
} else {
- memcpy(dmabuf, sgbuffer, amount);
- dmabuf += amount;
+ char *tmpv = (char *)dmabuf;
+ memcpy(tmpv, sgbuffer, amount);
+ tmpv += amount;
+ dmabuf = (unsigned *)tmpv;
}
kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
@@ -245,80 +263,14 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
}
/*
- * Prepare a dma read
- */
-static void at91_mci_pre_dma_read(struct at91mci_host *host)
-{
- int i;
- struct scatterlist *sg;
- struct mmc_command *cmd;
- struct mmc_data *data;
-
- pr_debug("pre dma read\n");
-
- cmd = host->cmd;
- if (!cmd) {
- pr_debug("no command\n");
- return;
- }
-
- data = cmd->data;
- if (!data) {
- pr_debug("no data\n");
- return;
- }
-
- for (i = 0; i < 2; i++) {
- /* nothing left to transfer */
- if (host->transfer_index >= data->sg_len) {
- pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index);
- break;
- }
-
- /* Check to see if this needs filling */
- if (i == 0) {
- if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) {
- pr_debug("Transfer active in current\n");
- continue;
- }
- }
- else {
- if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) {
- pr_debug("Transfer active in next\n");
- continue;
- }
- }
-
- /* Setup the next transfer */
- pr_debug("Using transfer index %d\n", host->transfer_index);
-
- sg = &data->sg[host->transfer_index++];
- pr_debug("sg = %p\n", sg);
-
- sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
-
- pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
-
- if (i == 0) {
- at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
- at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
- }
- else {
- at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
- at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
- }
- }
-
- pr_debug("pre dma read done\n");
-}
-
-/*
* Handle after a dma read
*/
static void at91_mci_post_dma_read(struct at91mci_host *host)
{
struct mmc_command *cmd;
struct mmc_data *data;
+ unsigned int len, i, size;
+ unsigned *dmabuf = host->buffer;
pr_debug("post dma read\n");
@@ -334,42 +286,39 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
return;
}
- while (host->in_use_index < host->transfer_index) {
- struct scatterlist *sg;
+ size = data->blksz * data->blocks;
+ len = data->sg_len;
- pr_debug("finishing index %d\n", host->in_use_index);
+ at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
+ at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
- sg = &data->sg[host->in_use_index++];
+ for (i = 0; i < len; i++) {
+ struct scatterlist *sg;
+ int amount;
+ unsigned int *sgbuffer;
- pr_debug("Unmapping page %08X\n", sg->dma_address);
+ sg = &data->sg[i];
- dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);
+ sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+ amount = min(size, sg->length);
+ size -= amount;
if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
- unsigned int *buffer;
int index;
-
- /* Swap the contents of the buffer */
- buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
- pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
-
- for (index = 0; index < (sg->length / 4); index++)
- buffer[index] = swab32(buffer[index]);
-
- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+ for (index = 0; index < (amount / 4); index++)
+ sgbuffer[index] = swab32(*dmabuf++);
+ } else {
+ char *tmpv = (char *)dmabuf;
+ memcpy(sgbuffer, tmpv, amount);
+ tmpv += amount;
+ dmabuf = (unsigned *)tmpv;
}
- flush_dcache_page(sg_page(sg));
-
- data->bytes_xfered += sg->length;
- }
-
- /* Is there another transfer to trigger? */
- if (host->transfer_index < data->sg_len)
- at91_mci_pre_dma_read(host);
- else {
- at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
- at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
+ kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
+ dmac_flush_range((void *)sgbuffer, ((void *)sgbuffer) + amount);
+ data->bytes_xfered += amount;
+ if (size == 0)
+ break;
}
pr_debug("post dma read done\n");
@@ -461,7 +410,7 @@ static void at91_mci_enable(struct at91mci_host *host)
at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
mr = AT91_MCI_PDCMODE | 0x34a;
- if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+ if (at91mci_is_mci1rev2xx())
mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
at91_mci_write(host, AT91_MCI_MR, mr);
@@ -602,10 +551,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
/*
* Handle a read
*/
- host->buffer = NULL;
host->total_length = 0;
- at91_mci_pre_dma_read(host);
+ at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address);
+ at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ?
+ (blocks * block_length) : (blocks * block_length) / 4);
+ at91_mci_write(host, ATMEL_PDC_RNPR, 0);
+ at91_mci_write(host, ATMEL_PDC_RNCR, 0);
+
ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
}
else {
@@ -614,27 +567,15 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
*/
host->total_length = block_length * blocks;
/*
- * AT91SAM926[0/3] Data Write Operation and
+ * MCI1 rev2xx Data Write Operation and
* number of bytes erratum
*/
- if (cpu_is_at91sam9260 () || cpu_is_at91sam9263())
+ if (at91mci_is_mci1rev2xx())
if (host->total_length < 12)
host->total_length = 12;
- host->buffer = kmalloc(host->total_length, GFP_KERNEL);
- if (!host->buffer) {
- pr_debug("Can't alloc tx buffer\n");
- cmd->error = -ENOMEM;
- mmc_request_done(host->mmc, host->request);
- return;
- }
-
at91_mci_sg_to_dma(host, data);
- host->physical_address = dma_map_single(NULL,
- host->buffer, host->total_length,
- DMA_TO_DEVICE);
-
pr_debug("Transmitting %d bytes\n", host->total_length);
at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
@@ -701,14 +642,6 @@ static void at91_mci_completed_command(struct at91mci_host *host, unsigned int s
cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));
- if (host->buffer) {
- dma_unmap_single(NULL,
- host->physical_address, host->total_length,
- DMA_TO_DEVICE);
- kfree(host->buffer);
- host->buffer = NULL;
- }
-
pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n",
status, at91_mci_read(host, AT91_MCI_SR),
cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
@@ -754,7 +687,8 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->request = mrq;
host->flags = 0;
- mod_timer(&host->timer, jiffies + HZ);
+ /* more than 1s timeout needed with slow SD cards */
+ mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000));
at91_mci_process_next(host);
}
@@ -942,7 +876,8 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
pr_debug("****** Resetting SD-card bus width ******\n");
at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
}
- mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+ /* 0.5s needed because of early card detect switch firing */
+ mmc_detect_change(host->mmc, msecs_to_jiffies(500));
}
return IRQ_HANDLED;
}
@@ -1006,24 +941,42 @@ static int __init at91_mci_probe(struct platform_device *pdev)
mmc->f_min = 375000;
mmc->f_max = 25000000;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
- mmc->caps = MMC_CAP_SDIO_IRQ;
+ mmc->caps = 0;
- mmc->max_blk_size = 4095;
- mmc->max_blk_count = mmc->max_req_size;
+ mmc->max_blk_size = MCI_MAXBLKSIZE;
+ mmc->max_blk_count = MCI_BLKATONCE;
+ mmc->max_req_size = MCI_BUFSIZE;
+ mmc->max_phys_segs = MCI_BLKATONCE;
+ mmc->max_hw_segs = MCI_BLKATONCE;
+ mmc->max_seg_size = MCI_BUFSIZE;
host = mmc_priv(mmc);
host->mmc = mmc;
- host->buffer = NULL;
host->bus_mode = 0;
host->board = pdev->dev.platform_data;
if (host->board->wire4) {
- if (cpu_is_at91sam9260() || cpu_is_at91sam9263())
+ if (at91mci_is_mci1rev2xx())
mmc->caps |= MMC_CAP_4_BIT_DATA;
else
dev_warn(&pdev->dev, "4 wire bus mode not supported"
" - using 1 wire\n");
}
+ host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE,
+ &host->physical_address, GFP_KERNEL);
+ if (!host->buffer) {
+ ret = -ENOMEM;
+ dev_err(&pdev->dev, "Can't allocate transmit buffer\n");
+ goto fail5;
+ }
+
+ /* Add SDIO capability when available */
+ if (at91mci_is_mci1rev2xx()) {
+ /* at91mci MCI1 rev2xx sdio interrupt erratum */
+ if (host->board->wire4 || !host->board->slot_b)
+ mmc->caps |= MMC_CAP_SDIO_IRQ;
+ }
+
/*
* Reserve GPIOs ... board init code makes sure these pins are set
* up as GPIOs with the right direction (input, except for vcc)
@@ -1032,7 +985,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
ret = gpio_request(host->board->det_pin, "mmc_detect");
if (ret < 0) {
dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
- goto fail5;
+ goto fail4b;
}
}
if (host->board->wp_pin) {
@@ -1132,6 +1085,10 @@ fail3:
fail4:
if (host->board->det_pin)
gpio_free(host->board->det_pin);
+fail4b:
+ if (host->buffer)
+ dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
+ host->buffer, host->physical_address);
fail5:
mmc_free_host(mmc);
fail6:
@@ -1154,6 +1111,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
host = mmc_priv(mmc);
+ if (host->buffer)
+ dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
+ host->buffer, host->physical_address);
+
if (host->board->det_pin) {
if (device_can_wakeup(&pdev->dev))
free_irq(gpio_to_irq(host->board->det_pin), host);
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 8072128e933..88be37d9e9a 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/mmc/host.h>
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 57b21198828..f5834449400 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -41,6 +41,7 @@
#include <linux/scatterlist.h>
#include <linux/leds.h>
#include <linux/mmc/host.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/mach-au1x00/au1000.h>
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index 3343a57355c..6919e844072 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -17,6 +17,7 @@
#include <linux/dma-mapping.h>
#include <linux/mmc/host.h>
#include <linux/proc_fs.h>
+#include <linux/gfp.h>
#include <asm/cacheflush.h>
#include <asm/dma.h>
@@ -115,7 +116,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
unsigned int length;
unsigned int data_ctl;
unsigned int dma_cfg;
- struct scatterlist *sg;
+ unsigned int cycle_ns, timeout;
dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags);
host->data = data;
@@ -136,8 +137,11 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
data_ctl |= ((ffs(data->blksz) - 1) << 4);
bfin_write_SDH_DATA_CTL(data_ctl);
-
- bfin_write_SDH_DATA_TIMER(0xFFFF);
+ /* the time of a host clock period in ns */
+ cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1)));
+ timeout = data->timeout_ns / cycle_ns;
+ timeout += data->timeout_clks;
+ bfin_write_SDH_DATA_TIMER(timeout);
SSYNC();
if (data->flags & MMC_DATA_READ) {
@@ -151,6 +155,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
#if defined(CONFIG_BF54x)
dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN;
{
+ struct scatterlist *sg;
int i;
for_each_sg(data->sg, sg, host->dma_len, i) {
host->sg_cpu[i].start_addr = sg_dma_address(sg);
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c
index 4e72964a7b4..92a324f7417 100644
--- a/drivers/mmc/host/cb710-mmc.c
+++ b/drivers/mmc/host/cb710-mmc.c
@@ -9,7 +9,6 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include "cb710-mmc.h"
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index dd45e7c3517..3bd0ba294e9 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -73,6 +73,7 @@
/* DAVINCI_MMCCTL definitions */
#define MMCCTL_DATRST (1 << 0)
#define MMCCTL_CMDRST (1 << 1)
+#define MMCCTL_WIDTH_8_BIT (1 << 8)
#define MMCCTL_WIDTH_4_BIT (1 << 2)
#define MMCCTL_DATEG_DISABLED (0 << 6)
#define MMCCTL_DATEG_RISING (1 << 6)
@@ -791,22 +792,42 @@ static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
- unsigned int mmc_pclk = 0;
struct mmc_davinci_host *host = mmc_priv(mmc);
- mmc_pclk = host->mmc_input_clk;
dev_dbg(mmc_dev(host->mmc),
"clock %dHz busmode %d powermode %d Vdd %04x\n",
ios->clock, ios->bus_mode, ios->power_mode,
ios->vdd);
- if (ios->bus_width == MMC_BUS_WIDTH_4) {
- dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
- writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT,
- host->base + DAVINCI_MMCCTL);
- } else {
- dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n");
- writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT,
+
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_8:
+ dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n");
+ writel((readl(host->base + DAVINCI_MMCCTL) &
+ ~MMCCTL_WIDTH_4_BIT) | MMCCTL_WIDTH_8_BIT,
host->base + DAVINCI_MMCCTL);
+ break;
+ case MMC_BUS_WIDTH_4:
+ dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
+ if (host->version == MMC_CTLR_VERSION_2)
+ writel((readl(host->base + DAVINCI_MMCCTL) &
+ ~MMCCTL_WIDTH_8_BIT) | MMCCTL_WIDTH_4_BIT,
+ host->base + DAVINCI_MMCCTL);
+ else
+ writel(readl(host->base + DAVINCI_MMCCTL) |
+ MMCCTL_WIDTH_4_BIT,
+ host->base + DAVINCI_MMCCTL);
+ break;
+ case MMC_BUS_WIDTH_1:
+ dev_dbg(mmc_dev(host->mmc), "Enabling 1 bit mode\n");
+ if (host->version == MMC_CTLR_VERSION_2)
+ writel(readl(host->base + DAVINCI_MMCCTL) &
+ ~(MMCCTL_WIDTH_8_BIT | MMCCTL_WIDTH_4_BIT),
+ host->base + DAVINCI_MMCCTL);
+ else
+ writel(readl(host->base + DAVINCI_MMCCTL) &
+ ~MMCCTL_WIDTH_4_BIT,
+ host->base + DAVINCI_MMCCTL);
+ break;
}
calculate_clk_divider(mmc, ios);
@@ -1189,10 +1210,14 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
/* REVISIT: someday, support IRQ-driven card detection. */
mmc->caps |= MMC_CAP_NEEDS_POLL;
+ mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
- if (!pdata || pdata->wires == 4 || pdata->wires == 0)
+ if (pdata && (pdata->wires == 4 || pdata->wires == 0))
mmc->caps |= MMC_CAP_4_BIT_DATA;
+ if (pdata && (pdata->wires == 8))
+ mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
+
host->version = pdata->version;
mmc->ops = &mmc_davinci_ops;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index d55fe4fb793..ad847a24a67 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -26,6 +26,7 @@
*/
#include <linux/sched.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/bio.h>
#include <linux/dma-mapping.h>
#include <linux/crc7.h>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index b31946e0b4c..04ae884383f 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -33,6 +33,7 @@
#include <linux/debugfs.h>
#include <linux/io.h>
#include <linux/memory.h>
+#include <linux/gfp.h>
#include <asm/cacheflush.h>
#include <asm/div64.h>
@@ -1250,9 +1251,7 @@ msmsdcc_resume(struct platform_device *dev)
if (mmc->card && mmc->card->type != MMC_TYPE_SDIO)
mmc_resume_host(mmc);
- if (host->stat_irq)
- enable_irq(host->stat_irq);
- else if (host->stat_irq)
+ if (host->stat_irq)
enable_irq(host->stat_irq);
}
return 0;
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 60a2b69e54f..2df90412abb 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -4,7 +4,7 @@
* This is a driver for the SDHC controller found in Freescale MX2/MX3
* SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
* Unlike the hardware found on MX1, this hardware just works and does
- * not need all the quirks found in imxmmc.c, hence the seperate driver.
+ * not need all the quirks found in imxmmc.c, hence the separate driver.
*
* Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
* Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
@@ -708,7 +708,7 @@ static int mxcmci_probe(struct platform_device *pdev)
mmc->max_blk_size = 2048;
mmc->max_blk_count = 65535;
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
- mmc->max_seg_size = mmc->max_seg_size;
+ mmc->max_seg_size = mmc->max_req_size;
host = mmc_priv(mmc);
host->base = ioremap(r->start, resource_size(r));
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index 0c7a63c1f12..bb6cc54b558 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index c6d7e8ecadb..84d28040634 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -26,6 +26,7 @@
#include <linux/clk.h>
#include <linux/scatterlist.h>
#include <linux/i2c/tps65010.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 83f0affadca..e9caf694c59 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1179,15 +1179,10 @@ static void omap_hsmmc_detect(struct work_struct *work)
carddetect = -ENOSYS;
}
- if (carddetect) {
+ if (carddetect)
mmc_detect_change(host->mmc, (HZ * 200) / 1000);
- } else {
- mmc_host_enable(host->mmc);
- omap_hsmmc_reset_controller_fsm(host, SRD);
- mmc_host_lazy_disable(host->mmc);
-
+ else
mmc_detect_change(host->mmc, (HZ * 50) / 1000);
- }
}
/*
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 0d783f3e79e..0ed48959b59 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -29,6 +29,7 @@
#include <linux/io.h>
#include <linux/regulator/consumer.h>
#include <linux/gpio.h>
+#include <linux/gfp.h>
#include <asm/sizes.h>
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c
deleted file mode 100644
index f6279051332..00000000000
--- a/drivers/mmc/host/ricoh_mmc.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller.
- *
- * Copyright (C) 2007 Philip Langdale, 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 is a conceptually ridiculous driver, but it is required by the way
- * the Ricoh multi-function chips (R5CXXX) work. These chips implement
- * the four main memory card controllers (SD, MMC, MS, xD) and one or both
- * of cardbus or firewire. It happens that they implement SD and MMC
- * support as separate controllers (and PCI functions). The linux SDHCI
- * driver supports MMC cards but the chip detects MMC cards in hardware
- * and directs them to the MMC controller - so the SDHCI driver never sees
- * them. To get around this, we must disable the useless MMC controller.
- * At that point, the SDHCI controller will start seeing them. As a bonus,
- * a detection event occurs immediately, even if the MMC card is already
- * in the reader.
- *
- * It seems to be the case that the relevant PCI registers to deactivate the
- * MMC controller live on PCI function 0, which might be the cardbus controller
- * or the firewire controller, depending on the particular chip in question. As
- * such, it makes what this driver has to do unavoidably ugly. Such is life.
- */
-
-#include <linux/pci.h>
-
-#define DRIVER_NAME "ricoh-mmc"
-
-static const struct pci_device_id pci_ids[] __devinitdata = {
- {
- .vendor = PCI_VENDOR_ID_RICOH,
- .device = PCI_DEVICE_ID_RICOH_R5C843,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },
- { /* end: all zeroes */ },
-};
-
-MODULE_DEVICE_TABLE(pci, pci_ids);
-
-static int ricoh_mmc_disable(struct pci_dev *fw_dev)
-{
- u8 write_enable;
- u8 write_target;
- u8 disable;
-
- if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
- /* via RL5C476 */
-
- pci_read_config_byte(fw_dev, 0xB7, &disable);
- if (disable & 0x02) {
- printk(KERN_INFO DRIVER_NAME
- ": Controller already disabled. " \
- "Nothing to do.\n");
- return -ENODEV;
- }
-
- pci_read_config_byte(fw_dev, 0x8E, &write_enable);
- pci_write_config_byte(fw_dev, 0x8E, 0xAA);
- pci_read_config_byte(fw_dev, 0x8D, &write_target);
- pci_write_config_byte(fw_dev, 0x8D, 0xB7);
- pci_write_config_byte(fw_dev, 0xB7, disable | 0x02);
- pci_write_config_byte(fw_dev, 0x8E, write_enable);
- pci_write_config_byte(fw_dev, 0x8D, write_target);
- } else {
- /* via R5C832 */
-
- pci_read_config_byte(fw_dev, 0xCB, &disable);
- if (disable & 0x02) {
- printk(KERN_INFO DRIVER_NAME
- ": Controller already disabled. " \
- "Nothing to do.\n");
- return -ENODEV;
- }
-
- pci_read_config_byte(fw_dev, 0xCA, &write_enable);
- pci_write_config_byte(fw_dev, 0xCA, 0x57);
- pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
- pci_write_config_byte(fw_dev, 0xCA, write_enable);
- }
-
- printk(KERN_INFO DRIVER_NAME
- ": Controller is now disabled.\n");
-
- return 0;
-}
-
-static int ricoh_mmc_enable(struct pci_dev *fw_dev)
-{
- u8 write_enable;
- u8 write_target;
- u8 disable;
-
- if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
- /* via RL5C476 */
-
- pci_read_config_byte(fw_dev, 0x8E, &write_enable);
- pci_write_config_byte(fw_dev, 0x8E, 0xAA);
- pci_read_config_byte(fw_dev, 0x8D, &write_target);
- pci_write_config_byte(fw_dev, 0x8D, 0xB7);
- pci_read_config_byte(fw_dev, 0xB7, &disable);
- pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02);
- pci_write_config_byte(fw_dev, 0x8E, write_enable);
- pci_write_config_byte(fw_dev, 0x8D, write_target);
- } else {
- /* via R5C832 */
-
- pci_read_config_byte(fw_dev, 0xCA, &write_enable);
- pci_read_config_byte(fw_dev, 0xCB, &disable);
- pci_write_config_byte(fw_dev, 0xCA, 0x57);
- pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
- pci_write_config_byte(fw_dev, 0xCA, write_enable);
- }
-
- printk(KERN_INFO DRIVER_NAME
- ": Controller is now re-enabled.\n");
-
- return 0;
-}
-
-static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- u8 rev;
- u8 ctrlfound = 0;
-
- struct pci_dev *fw_dev = NULL;
-
- BUG_ON(pdev == NULL);
- BUG_ON(ent == NULL);
-
- pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
-
- printk(KERN_INFO DRIVER_NAME
- ": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n",
- pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
- (int)rev);
-
- while ((fw_dev =
- pci_get_device(PCI_VENDOR_ID_RICOH,
- PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {
- if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
- PCI_FUNC(fw_dev->devfn) == 0 &&
- pdev->bus == fw_dev->bus) {
- if (ricoh_mmc_disable(fw_dev) != 0)
- return -ENODEV;
-
- pci_set_drvdata(pdev, fw_dev);
-
- ++ctrlfound;
- break;
- }
- }
-
- fw_dev = NULL;
-
- while (!ctrlfound &&
- (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH,
- PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
- if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
- PCI_FUNC(fw_dev->devfn) == 0 &&
- pdev->bus == fw_dev->bus) {
- if (ricoh_mmc_disable(fw_dev) != 0)
- return -ENODEV;
-
- pci_set_drvdata(pdev, fw_dev);
-
- ++ctrlfound;
- }
- }
-
- if (!ctrlfound) {
- printk(KERN_WARNING DRIVER_NAME
- ": Main Ricoh function not found. Cannot disable controller.\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
-{
- struct pci_dev *fw_dev = NULL;
-
- fw_dev = pci_get_drvdata(pdev);
- BUG_ON(fw_dev == NULL);
-
- ricoh_mmc_enable(fw_dev);
-
- pci_set_drvdata(pdev, NULL);
-}
-
-static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state)
-{
- struct pci_dev *fw_dev = NULL;
-
- fw_dev = pci_get_drvdata(pdev);
- BUG_ON(fw_dev == NULL);
-
- printk(KERN_INFO DRIVER_NAME ": Suspending.\n");
-
- ricoh_mmc_enable(fw_dev);
-
- return 0;
-}
-
-static int ricoh_mmc_resume_early(struct pci_dev *pdev)
-{
- struct pci_dev *fw_dev = NULL;
-
- fw_dev = pci_get_drvdata(pdev);
- BUG_ON(fw_dev == NULL);
-
- printk(KERN_INFO DRIVER_NAME ": Resuming.\n");
-
- ricoh_mmc_disable(fw_dev);
-
- return 0;
-}
-
-static struct pci_driver ricoh_mmc_driver = {
- .name = DRIVER_NAME,
- .id_table = pci_ids,
- .probe = ricoh_mmc_probe,
- .remove = __devexit_p(ricoh_mmc_remove),
- .suspend_late = ricoh_mmc_suspend_late,
- .resume_early = ricoh_mmc_resume_early,
-};
-
-/*****************************************************************************\
- * *
- * Driver init/exit *
- * *
-\*****************************************************************************/
-
-static int __init ricoh_mmc_drv_init(void)
-{
- printk(KERN_INFO DRIVER_NAME
- ": Ricoh MMC Controller disabling driver\n");
- printk(KERN_INFO DRIVER_NAME ": Copyright(c) Philip Langdale\n");
-
- return pci_register_driver(&ricoh_mmc_driver);
-}
-
-static void __exit ricoh_mmc_drv_exit(void)
-{
- pci_unregister_driver(&ricoh_mmc_driver);
-}
-
-module_init(ricoh_mmc_drv_init);
-module_exit(ricoh_mmc_drv_exit);
-
-MODULE_AUTHOR("Philip Langdale <philipl@alumni.utexas.net>");
-MODULE_DESCRIPTION("Ricoh MMC Controller disabling driver");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index d96e1abf2d6..2fdf7689ae6 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1179,7 +1179,7 @@ static int s3cmci_card_present(struct mmc_host *mmc)
struct s3c24xx_mci_pdata *pdata = host->pdata;
int ret;
- if (pdata->gpio_detect == 0)
+ if (pdata->no_detect)
return -ENOSYS;
ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
@@ -1360,6 +1360,8 @@ static struct mmc_host_ops s3cmci_ops = {
static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
/* This is currently here to avoid a number of if (host->pdata)
* checks. Any zero fields to ensure reasonable defaults are picked. */
+ .no_wprotect = 1,
+ .no_detect = 1,
};
#ifdef CONFIG_CPU_FREQ
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 5c3a1767770..6701af629c3 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -16,6 +16,7 @@
#include <linux/highmem.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/mmc/host.h>
@@ -80,9 +81,6 @@ struct sdhci_pci_chip {
static int ricoh_probe(struct sdhci_pci_chip *chip)
{
- if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
- chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET;
-
if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
@@ -92,7 +90,9 @@ static int ricoh_probe(struct sdhci_pci_chip *chip)
static const struct sdhci_pci_fixes sdhci_ricoh = {
.probe = ricoh_probe,
- .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR,
+ .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
+ SDHCI_QUIRK_FORCE_DMA |
+ SDHCI_QUIRK_CLOCK_BEFORE_RESET,
};
static const struct sdhci_pci_fixes sdhci_ene_712 = {
@@ -501,6 +501,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
{
struct sdhci_pci_chip *chip;
struct sdhci_pci_slot *slot;
+ mmc_pm_flag_t pm_flags = 0;
int i, ret;
chip = pci_get_drvdata(pdev);
@@ -519,6 +520,8 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
sdhci_resume_host(chip->slots[i]->host);
return ret;
}
+
+ pm_flags |= slot->host->mmc->pm_flags;
}
if (chip->fixes && chip->fixes->suspend) {
@@ -531,9 +534,15 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
}
pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ if (pm_flags & MMC_PM_KEEP_POWER) {
+ if (pm_flags & MMC_PM_WAKE_SDIO_IRQ)
+ pci_enable_wake(pdev, PCI_D3hot, 1);
+ pci_set_power_state(pdev, PCI_D3hot);
+ } else {
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ }
return 0;
}
@@ -653,6 +662,8 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
goto unmap;
}
+ host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
+
ret = sdhci_add_host(host);
if (ret)
goto remove;
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 50997d2a63e..2136794c0cf 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/io.h>
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c279fbc4c2e..9d4fdfa685e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -17,6 +17,7 @@
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/leds.h>
@@ -174,20 +175,31 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
}
-static void sdhci_init(struct sdhci_host *host)
+static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
+
+static void sdhci_init(struct sdhci_host *host, int soft)
{
- sdhci_reset(host, SDHCI_RESET_ALL);
+ if (soft)
+ sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
+ else
+ sdhci_reset(host, SDHCI_RESET_ALL);
sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
+
+ if (soft) {
+ /* force clock reconfiguration */
+ host->clock = 0;
+ sdhci_set_ios(host->mmc, &host->mmc->ios);
+ }
}
static void sdhci_reinit(struct sdhci_host *host)
{
- sdhci_init(host);
+ sdhci_init(host, 0);
sdhci_enable_card_detection(host);
}
@@ -376,6 +388,20 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
local_irq_restore(*flags);
}
+static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd)
+{
+ __le32 *dataddr = (__le32 __force *)(desc + 4);
+ __le16 *cmdlen = (__le16 __force *)desc;
+
+ /* SDHCI specification says ADMA descriptors should be 4 byte
+ * aligned, so using 16 or 32bit operations should be safe. */
+
+ cmdlen[0] = cpu_to_le16(cmd);
+ cmdlen[1] = cpu_to_le16(len);
+
+ dataddr[0] = cpu_to_le32(addr);
+}
+
static int sdhci_adma_table_pre(struct sdhci_host *host,
struct mmc_data *data)
{
@@ -443,19 +469,11 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
sdhci_kunmap_atomic(buffer, &flags);
}
- desc[7] = (align_addr >> 24) & 0xff;
- desc[6] = (align_addr >> 16) & 0xff;
- desc[5] = (align_addr >> 8) & 0xff;
- desc[4] = (align_addr >> 0) & 0xff;
+ /* tran, valid */
+ sdhci_set_adma_desc(desc, align_addr, offset, 0x21);
BUG_ON(offset > 65536);
- desc[3] = (offset >> 8) & 0xff;
- desc[2] = (offset >> 0) & 0xff;
-
- desc[1] = 0x00;
- desc[0] = 0x21; /* tran, valid */
-
align += 4;
align_addr += 4;
@@ -465,19 +483,10 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
len -= offset;
}
- desc[7] = (addr >> 24) & 0xff;
- desc[6] = (addr >> 16) & 0xff;
- desc[5] = (addr >> 8) & 0xff;
- desc[4] = (addr >> 0) & 0xff;
-
BUG_ON(len > 65536);
- desc[3] = (len >> 8) & 0xff;
- desc[2] = (len >> 0) & 0xff;
-
- desc[1] = 0x00;
- desc[0] = 0x21; /* tran, valid */
-
+ /* tran, valid */
+ sdhci_set_adma_desc(desc, addr, len, 0x21);
desc += 8;
/*
@@ -490,16 +499,9 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
/*
* Add a terminating entry.
*/
- desc[7] = 0;
- desc[6] = 0;
- desc[5] = 0;
- desc[4] = 0;
- desc[3] = 0;
- desc[2] = 0;
-
- desc[1] = 0x00;
- desc[0] = 0x03; /* nop, end, valid */
+ /* nop, end, valid */
+ sdhci_set_adma_desc(desc, 0, 0, 0x3);
/*
* Resync align buffer as we might have changed it.
@@ -1610,16 +1612,13 @@ int sdhci_resume_host(struct sdhci_host *host)
if (ret)
return ret;
- sdhci_init(host);
+ sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER));
mmiowb();
ret = mmc_resume_host(host->mmc);
- if (ret)
- return ret;
-
sdhci_enable_card_detection(host);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(sdhci_resume_host);
@@ -1874,7 +1873,7 @@ int sdhci_add_host(struct sdhci_host *host)
if (ret)
goto untasklet;
- sdhci_init(host);
+ sdhci_init(host, 0);
#ifdef CONFIG_MMC_DEBUG
sdhci_dumpregs(host);
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index e22c3fa3516..b2b577f6afd 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -323,7 +323,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid)
if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
TMIO_STAT_CARD_REMOVE);
- mmc_detect_change(host->mmc, 0);
+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
}
/* CRC and other errors */
@@ -550,6 +550,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
mmc->ops = &tmio_mmc_ops;
mmc->caps = MMC_CAP_4_BIT_DATA;
+ mmc->caps |= pdata->capabilities;
mmc->f_max = pdata->hclk;
mmc->f_min = mmc->f_max / 512;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
@@ -568,14 +569,14 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
if (ret >= 0)
host->irq = ret;
else
- goto unmap_ctl;
+ goto cell_disable;
disable_mmc_irqs(host, TMIO_MASK_ALL);
ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED |
IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host);
if (ret)
- goto unmap_ctl;
+ goto cell_disable;
mmc_add_host(mmc);
@@ -587,6 +588,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
return 0;
+cell_disable:
+ if (cell->disable)
+ cell->disable(dev);
unmap_ctl:
iounmap(host->ctl);
host_free:
@@ -597,6 +601,7 @@ out:
static int __devexit tmio_mmc_remove(struct platform_device *dev)
{
+ struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
struct mmc_host *mmc = platform_get_drvdata(dev);
platform_set_drvdata(dev, NULL);
@@ -605,6 +610,8 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev)
struct tmio_mmc_host *host = mmc_priv(mmc);
mmc_remove_host(mmc);
free_irq(host->irq, host);
+ if (cell->disable)
+ cell->disable(dev);
iounmap(host->ctl);
mmc_free_host(mmc);
}
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 692dc23363b..dafecfbcd91 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -55,10 +55,8 @@
/* Define some IRQ masks */
/* This is the mask used at reset by the chip */
#define TMIO_MASK_ALL 0x837f031d
-#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \
- TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
-#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \
- TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
+#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND)
+#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND)
#define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 89bf8cd25ca..69efe01eece 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -34,6 +34,7 @@
#include <linux/highmem.h>
#include <linux/mmc/host.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/dma.h>
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 82d1e4de475..4521b1ecce4 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -4,7 +4,7 @@
# Core functionality.
obj-$(CONFIG_MTD) += mtd.o
-mtd-y := mtdcore.o mtdsuper.o mtdbdi.o
+mtd-y := mtdcore.o mtdsuper.o
mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index ca584d0380b..ca584d0380b 100755..100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 1bec5e1ce6a..8db1148dfa4 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -226,7 +226,7 @@ struct unlock_addr {
* exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
* should not be used. The problem is that structures with
* initializers have extra fields initialized to 0. It is _very_
- * desireable to have the unlock address entries for unsupported
+ * desirable to have the unlock address entries for unsupported
* data widths automatically initialized - that means that
* MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
* must go unused.
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 8c295f40d2a..ce6424008ed 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -17,6 +17,7 @@
#include <linux/buffer_head.h>
#include <linux/mutex.h>
#include <linux/mount.h>
+#include <linux/slab.h>
#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
#define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index f3f4768d6e1..81e49a9b017 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/math64.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/mod_devicetable.h>
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index 0a11721f146..fe17054ee2f 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/mtd/mtd.h>
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 8aca5523a33..8aca5523a33 100755..100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
diff --git a/drivers/mtd/internal.h b/drivers/mtd/internal.h
index c658fe7216b..e69de29bb2d 100644
--- a/drivers/mtd/internal.h
+++ b/drivers/mtd/internal.h
@@ -1,17 +0,0 @@
-/* Internal MTD definitions
- *
- * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@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.
- */
-
-/*
- * mtdbdi.c
- */
-extern struct backing_dev_info mtd_bdi_unmappable;
-extern struct backing_dev_info mtd_bdi_ro_mappable;
-extern struct backing_dev_info mtd_bdi_rw_mappable;
diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c
index e22ca49583e..a73ee12aad8 100644
--- a/drivers/mtd/lpddr/lpddr_cmds.c
+++ b/drivers/mtd/lpddr/lpddr_cmds.c
@@ -26,6 +26,7 @@
*/
#include <linux/mtd/pfow.h>
#include <linux/mtd/qinfo.h>
+#include <linux/slab.h>
static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
size_t *retlen, u_char *buf);
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index 237733d094c..19fe92db0c4 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c
index a7c808b577d..c0fd99b0c52 100644
--- a/drivers/mtd/maps/bfin-async-flash.c
+++ b/drivers/mtd/maps/bfin-async-flash.c
@@ -22,6 +22,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <asm/blackfin.h>
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c
index 424f17d6ffd..ddb462bea9b 100644
--- a/drivers/mtd/maps/ck804xrom.c
+++ b/drivers/mtd/maps/ck804xrom.c
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c
index 11a2f57df9c..d12c93dc1aa 100644
--- a/drivers/mtd/maps/esb2rom.c
+++ b/drivers/mtd/maps/esb2rom.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c
index 1ad5caf9fe6..32e89d773b4 100644
--- a/drivers/mtd/maps/gpio-addr-flash.c
+++ b/drivers/mtd/maps/gpio-addr-flash.c
@@ -23,6 +23,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/types.h>
#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); })
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index c32bc28920b..f102bf243a7 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/intel_vr_nor.c b/drivers/mtd/maps/intel_vr_nor.c
index 1e7814ae212..fc1998512eb 100644
--- a/drivers/mtd/maps/intel_vr_nor.c
+++ b/drivers/mtd/maps/intel_vr_nor.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
diff --git a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c
index 2b2e4509321..23fe1786770 100644
--- a/drivers/mtd/maps/octagon-5066.c
+++ b/drivers/mtd/maps/octagon-5066.c
@@ -24,7 +24,6 @@
##################################################################### */
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/drivers/mtd/maps/omap_nor.c
+++ /dev/null
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 61e4eb48bb2..101ee6ead05 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -23,6 +23,7 @@
#include <linux/mtd/concat.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
struct of_flash_list {
struct mtd_info *mtd;
diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c
index c48cad271f5..60c068db452 100644
--- a/drivers/mtd/maps/pismo.c
+++ b/drivers/mtd/maps/pismo.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
@@ -118,7 +119,7 @@ static int __devinit pismo_add_device(struct pismo_data *pismo, int i,
{
struct platform_device *dev;
struct resource res = { };
- phys_addr_t base = region.base;
+ phys_addr_t base = region->base;
int ret;
if (base == ~0)
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index dafb91944e7..76a76be5a7b 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -4,7 +4,7 @@
* http://www.simtec.co.uk/products/SWLINUX/
* Ben Dooks <ben@simtec.co.uk>
*
- * Generic platfrom device based RAM map
+ * Generic platform device based RAM map
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c
index c8fd8da4bc8..acb13fa5001 100644
--- a/drivers/mtd/maps/pmcmsp-flash.c
+++ b/drivers/mtd/maps/pmcmsp-flash.c
@@ -28,6 +28,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index b13f6417b5b..91dc6331053 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c
index 1b1c0b7e11e..04b2781fc62 100644
--- a/drivers/mtd/maps/sbc_gxx.c
+++ b/drivers/mtd/maps/sbc_gxx.c
@@ -45,7 +45,6 @@ separate MTD devices.
// Includes
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index fd7a1017399..fadc4c45b45 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -15,6 +15,7 @@
#include <linux/ioport.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
index 6d452dcdfe3..6adaa6acc19 100644
--- a/drivers/mtd/maps/vmax301.c
+++ b/drivers/mtd/maps/vmax301.c
@@ -16,7 +16,6 @@
##################################################################### */
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/spinlock.h>
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c
index 82afad0ddd7..4afc167731e 100644
--- a/drivers/mtd/maps/vmu-flash.c
+++ b/drivers/mtd/maps/vmu-flash.c
@@ -8,6 +8,7 @@
* GNU General Public Licence
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/maple.h>
diff --git a/drivers/mtd/mtdbdi.c b/drivers/mtd/mtdbdi.c
index 5ca5aed0b22..e69de29bb2d 100644
--- a/drivers/mtd/mtdbdi.c
+++ b/drivers/mtd/mtdbdi.c
@@ -1,43 +0,0 @@
-/* MTD backing device capabilities
- *
- * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@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 <linux/backing-dev.h>
-#include <linux/mtd/mtd.h>
-#include "internal.h"
-
-/*
- * backing device capabilities for non-mappable devices (such as NAND flash)
- * - permits private mappings, copies are taken of the data
- */
-struct backing_dev_info mtd_bdi_unmappable = {
- .capabilities = BDI_CAP_MAP_COPY,
-};
-
-/*
- * backing device capabilities for R/O mappable devices (such as ROM)
- * - permits private mappings, copies are taken of the data
- * - permits non-writable shared mappings
- */
-struct backing_dev_info mtd_bdi_ro_mappable = {
- .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
- BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
-};
-
-/*
- * backing device capabilities for writable mappable devices (such as RAM)
- * - permits private mappings, copies are taken of the data
- * - permits non-writable shared mappings
- */
-struct backing_dev_info mtd_bdi_rw_mappable = {
- .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
- BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
- BDI_CAP_WRITE_MAP),
-};
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index c356c0a30c3..b177e750efc 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -2,12 +2,14 @@
* Core registration and callback routines for MTD
* drivers and users.
*
+ * bdi bits are:
+ * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/major.h>
@@ -17,11 +19,39 @@
#include <linux/init.h>
#include <linux/mtd/compatmac.h>
#include <linux/proc_fs.h>
+#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h>
-#include "internal.h"
#include "mtdcore.h"
+/*
+ * backing device capabilities for non-mappable devices (such as NAND flash)
+ * - permits private mappings, copies are taken of the data
+ */
+struct backing_dev_info mtd_bdi_unmappable = {
+ .capabilities = BDI_CAP_MAP_COPY,
+};
+
+/*
+ * backing device capabilities for R/O mappable devices (such as ROM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_ro_mappable = {
+ .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+ BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
+};
+
+/*
+ * backing device capabilities for writable mappable devices (such as RAM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_rw_mappable = {
+ .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+ BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
+ BDI_CAP_WRITE_MAP),
+};
static int mtd_cls_suspend(struct device *dev, pm_message_t state);
static int mtd_cls_resume(struct device *dev);
@@ -629,20 +659,55 @@ done:
/*====================================================================*/
/* Init code */
+static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name)
+{
+ int ret;
+
+ ret = bdi_init(bdi);
+ if (!ret)
+ ret = bdi_register(bdi, NULL, name);
+
+ if (ret)
+ bdi_destroy(bdi);
+
+ return ret;
+}
+
static int __init init_mtd(void)
{
int ret;
+
ret = class_register(&mtd_class);
+ if (ret)
+ goto err_reg;
+
+ ret = mtd_bdi_init(&mtd_bdi_unmappable, "mtd-unmap");
+ if (ret)
+ goto err_bdi1;
+
+ ret = mtd_bdi_init(&mtd_bdi_ro_mappable, "mtd-romap");
+ if (ret)
+ goto err_bdi2;
+
+ ret = mtd_bdi_init(&mtd_bdi_rw_mappable, "mtd-rwmap");
+ if (ret)
+ goto err_bdi3;
- if (ret) {
- pr_err("Error registering mtd class: %d\n", ret);
- return ret;
- }
#ifdef CONFIG_PROC_FS
if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
proc_mtd->read_proc = mtd_read_proc;
#endif /* CONFIG_PROC_FS */
return 0;
+
+err_bdi3:
+ bdi_destroy(&mtd_bdi_ro_mappable);
+err_bdi2:
+ bdi_destroy(&mtd_bdi_unmappable);
+err_bdi1:
+ class_unregister(&mtd_class);
+err_reg:
+ pr_err("Error registering mtd class or bdi: %d\n", ret);
+ return ret;
}
static void __exit cleanup_mtd(void)
@@ -652,6 +717,9 @@ static void __exit cleanup_mtd(void)
remove_proc_entry( "mtd", NULL);
#endif /* CONFIG_PROC_FS */
class_unregister(&mtd_class);
+ bdi_destroy(&mtd_bdi_unmappable);
+ bdi_destroy(&mtd_bdi_ro_mappable);
+ bdi_destroy(&mtd_bdi_rw_mappable);
}
module_init(init_mtd);
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
index af8b42e0a55..7c003191fca 100644
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -13,6 +13,7 @@
#include <linux/mtd/super.h>
#include <linux/namei.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
/*
* compare superblocks to see if they're equivalent
@@ -44,6 +45,7 @@ static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
sb->s_mtd = mtd;
sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+ sb->s_bdi = mtd->backing_dev_info;
return 0;
}
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index bb646560423..42e5ea49e97 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -444,7 +444,7 @@ config MTD_NAND_FSL_UPM
config MTD_NAND_MXC
tristate "MXC NAND support"
- depends on ARCH_MX2 || ARCH_MX3
+ depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3
help
This enables the driver for the NAND flash controller on the
MXC processors.
@@ -457,7 +457,7 @@ config MTD_NAND_NOMADIK
config MTD_NAND_SH_FLCTL
tristate "Support for NAND on Renesas SuperH FLCTL"
- depends on MTD_NAND && SUPERH
+ depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE)
help
Several Renesas SuperH CPU has FLCTL. This option enables support
for NAND Flash using FLCTL.
diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c
index 087bcd745bb..c997f98eeb3 100644
--- a/drivers/mtd/nand/bcm_umi_nand.c
+++ b/drivers/mtd/nand/bcm_umi_nand.c
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/device.h>
@@ -381,7 +382,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
if (!r)
return -ENXIO;
- /* map physical adress */
+ /* map physical address */
bcm_umi_io_base = ioremap(r->start, r->end - r->start + 1);
if (!bcm_umi_io_base) {
@@ -525,7 +526,7 @@ static int bcm_umi_nand_remove(struct platform_device *pdev)
/* Release resources, unregister device */
nand_release(board_mtd);
- /* unmap physical adress */
+ /* unmap physical address */
iounmap(bcm_umi_io_base);
/* Free the MTD device structure */
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index c828d9ac7bd..e5a9f9ccea6 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/io.h>
#define CAFE_NAND_CTRL1 0x00
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c
index 826cacffcef..6e649527825 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/cmx270_nand.c
@@ -20,6 +20,7 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
#include <linux/gpio.h>
#include <asm/io.h>
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index fe3eba87de4..76e2dc8e62f 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -32,6 +32,7 @@
#include <linux/io.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
#include <mach/nand.h>
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index b126cf88747..47067bc9824 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/rslib.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 071a60cb420..4b96296af32 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -21,6 +21,7 @@
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/fsl_lbc.h>
#define FSL_UPM_WAIT_RUN_PATTERN 0x1
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 45dec5770da..b2900d8406d 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -507,7 +507,7 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
* MXC NANDFC can only perform full page+spare or
* spare-only read/write. When the upper layers
* layers perform a read/write buf operation,
- * we will used the saved column adress to index into
+ * we will used the saved column address to index into
* the full page.
*/
send_addr(host, 0, page_addr == -1);
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 40b5658bdbe..b983cae8c29 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -28,6 +28,7 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/ndfc.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/of_platform.h>
#include <asm/io.h>
diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c
index 66123419f65..1f6f741af5d 100644
--- a/drivers/mtd/nand/nomadik_nand.c
+++ b/drivers/mtd/nand/nomadik_nand.c
@@ -30,6 +30,7 @@
#include <linux/platform_device.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/nand.h>
#include <mach/fsmc.h>
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 26aec008018..7545568fce4 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -17,6 +17,7 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <plat/dma.h>
#include <plat/gpmc.h>
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index f59c07427af..d60fc5719fe 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -60,7 +60,13 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
}
buf64 = (uint64_t *)buf;
while (i < len/8) {
- uint64_t x;
+ /*
+ * Since GCC has no proper constraint (PR 43518)
+ * force x variable to r2/r3 registers as ldrd instruction
+ * requires first register to be even.
+ */
+ register uint64_t x asm ("r2");
+
asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));
buf64[i++] = x;
}
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 1a5a0365c98..5d55152162c 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -21,6 +21,7 @@
#include <linux/mtd/partitions.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <mach/dma.h>
#include <plat/pxa3xx_nand.h>
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 1842df8bdd9..34752fce079 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
index 92c73344a66..fa28f01ae00 100644
--- a/drivers/mtd/nand/tmio_nand.c
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -37,6 +37,7 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
/*--------------------------------------------------------------------------*/
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 62d6a78c4ee..4f0d635674f 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/of.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include <linux/mtd/partitions.h>
int __devinit of_mtd_parse_partitions(struct device *dev,
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 75f38b95811..fd406348fdf 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -34,6 +34,7 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/mach/flash.h>
#include <plat/gpmc.h>
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index f63b1db3ffb..32f0ed33afe 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/delay.h>
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c
index f6e3c8aebd3..8b246061d51 100644
--- a/drivers/mtd/onenand/onenand_sim.c
+++ b/drivers/mtd/onenand/onenand_sim.c
@@ -16,6 +16,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c
index c1f31051784..70d6d7d0d65 100644
--- a/drivers/mtd/tests/mtd_nandecctest.c
+++ b/drivers/mtd/tests/mtd_nandecctest.c
@@ -1,7 +1,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/string.h>
#include <linux/bitops.h>
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index 5813920e79a..dec92ae6111 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -25,6 +25,7 @@
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#define PRINT_PREF KERN_INFO "mtd_oobtest: "
diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c
index ce17cbe918c..921a85df919 100644
--- a/drivers/mtd/tests/mtd_pagetest.c
+++ b/drivers/mtd/tests/mtd_pagetest.c
@@ -25,6 +25,7 @@
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#define PRINT_PREF KERN_INFO "mtd_pagetest: "
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c
index 25c5dd03a83..7107fccbc7d 100644
--- a/drivers/mtd/tests/mtd_readtest.c
+++ b/drivers/mtd/tests/mtd_readtest.c
@@ -24,6 +24,7 @@
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#define PRINT_PREF KERN_INFO "mtd_readtest: "
diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c
index 7fbb51d4eab..56ca62bb96b 100644
--- a/drivers/mtd/tests/mtd_speedtest.c
+++ b/drivers/mtd/tests/mtd_speedtest.c
@@ -24,6 +24,7 @@
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#define PRINT_PREF KERN_INFO "mtd_speedtest: "
diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c
index a99d3cd737d..3854afec56d 100644
--- a/drivers/mtd/tests/mtd_stresstest.c
+++ b/drivers/mtd/tests/mtd_stresstest.c
@@ -24,6 +24,7 @@
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/vmalloc.h>
diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c
index 5b889724268..700237a3d12 100644
--- a/drivers/mtd/tests/mtd_subpagetest.c
+++ b/drivers/mtd/tests/mtd_subpagetest.c
@@ -24,6 +24,7 @@
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#define PRINT_PREF KERN_INFO "mtd_subpagetest: "
diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c
index 631a0ab3a33..5c6c3d24890 100644
--- a/drivers/mtd/tests/mtd_torturetest.c
+++ b/drivers/mtd/tests/mtd_torturetest.c
@@ -28,6 +28,7 @@
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#define PRINT_PREF KERN_INFO "mtd_torturetest: "
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 14cec04c34f..55c726dde94 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -37,12 +37,14 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/stringify.h>
+#include <linux/namei.h>
#include <linux/stat.h>
#include <linux/miscdevice.h>
#include <linux/log2.h>
#include <linux/kthread.h>
#include <linux/reboot.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "ubi.h"
/* Maximum length of the 'mtd=' parameter */
@@ -50,7 +52,8 @@
/**
* struct mtd_dev_param - MTD device parameter description data structure.
- * @name: MTD device name or number string
+ * @name: MTD character device node path, MTD device name, or MTD device number
+ * string
* @vid_hdr_offs: VID header offset
*/
struct mtd_dev_param {
@@ -59,10 +62,10 @@ struct mtd_dev_param {
};
/* Numbers of elements set in the @mtd_dev_param array */
-static int mtd_devs;
+static int __initdata mtd_devs;
/* MTD devices specification parameters */
-static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES];
+static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES];
/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
struct class *ubi_class;
@@ -87,7 +90,8 @@ DEFINE_MUTEX(ubi_devices_mutex);
static DEFINE_SPINLOCK(ubi_devices_lock);
/* "Show" method for files in '/<sysfs>/class/ubi/' */
-static ssize_t ubi_version_show(struct class *class, char *buf)
+static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%d\n", UBI_VERSION);
}
@@ -363,11 +367,13 @@ static void dev_release(struct device *dev)
/**
* ubi_sysfs_init - initialize sysfs for an UBI device.
* @ubi: UBI device description object
+ * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
+ * taken
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
-static int ubi_sysfs_init(struct ubi_device *ubi)
+static int ubi_sysfs_init(struct ubi_device *ubi, int *ref)
{
int err;
@@ -379,6 +385,7 @@ static int ubi_sysfs_init(struct ubi_device *ubi)
if (err)
return err;
+ *ref = 1;
err = device_create_file(&ubi->dev, &dev_eraseblock_size);
if (err)
return err;
@@ -434,7 +441,7 @@ static void ubi_sysfs_close(struct ubi_device *ubi)
}
/**
- * kill_volumes - destroy all volumes.
+ * kill_volumes - destroy all user volumes.
* @ubi: UBI device description object
*/
static void kill_volumes(struct ubi_device *ubi)
@@ -447,36 +454,29 @@ static void kill_volumes(struct ubi_device *ubi)
}
/**
- * free_user_volumes - free all user volumes.
- * @ubi: UBI device description object
- *
- * Normally the volumes are freed at the release function of the volume device
- * objects. However, on error paths the volumes have to be freed before the
- * device objects have been initialized.
- */
-static void free_user_volumes(struct ubi_device *ubi)
-{
- int i;
-
- for (i = 0; i < ubi->vtbl_slots; i++)
- if (ubi->volumes[i]) {
- kfree(ubi->volumes[i]->eba_tbl);
- kfree(ubi->volumes[i]);
- }
-}
-
-/**
* uif_init - initialize user interfaces for an UBI device.
* @ubi: UBI device description object
+ * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
+ * taken, otherwise set to %0
+ *
+ * This function initializes various user interfaces for an UBI device. If the
+ * initialization fails at an early stage, this function frees all the
+ * resources it allocated, returns an error, and @ref is set to %0. However,
+ * if the initialization fails after the UBI device was registered in the
+ * driver core subsystem, this function takes a reference to @ubi->dev, because
+ * otherwise the release function ('dev_release()') would free whole @ubi
+ * object. The @ref argument is set to %1 in this case. The caller has to put
+ * this reference.
*
* This function returns zero in case of success and a negative error code in
- * case of failure. Note, this function destroys all volumes if it fails.
+ * case of failure.
*/
-static int uif_init(struct ubi_device *ubi)
+static int uif_init(struct ubi_device *ubi, int *ref)
{
int i, err;
dev_t dev;
+ *ref = 0;
sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
/*
@@ -504,7 +504,7 @@ static int uif_init(struct ubi_device *ubi)
goto out_unreg;
}
- err = ubi_sysfs_init(ubi);
+ err = ubi_sysfs_init(ubi, ref);
if (err)
goto out_sysfs;
@@ -522,6 +522,8 @@ static int uif_init(struct ubi_device *ubi)
out_volumes:
kill_volumes(ubi);
out_sysfs:
+ if (*ref)
+ get_device(&ubi->dev);
ubi_sysfs_close(ubi);
cdev_del(&ubi->cdev);
out_unreg:
@@ -875,7 +877,7 @@ static int ubi_reboot_notifier(struct notifier_block *n, unsigned long state,
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
{
struct ubi_device *ubi;
- int i, err, do_free = 1;
+ int i, err, ref = 0;
/*
* Check if we already have the same MTD device attached.
@@ -975,9 +977,9 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
goto out_detach;
}
- err = uif_init(ubi);
+ err = uif_init(ubi, &ref);
if (err)
- goto out_nofree;
+ goto out_detach;
ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
if (IS_ERR(ubi->bgt_thread)) {
@@ -1025,12 +1027,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
out_uif:
uif_close(ubi);
-out_nofree:
- do_free = 0;
out_detach:
ubi_wl_close(ubi);
- if (do_free)
- free_user_volumes(ubi);
free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_free:
@@ -1039,7 +1037,10 @@ out_free:
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
vfree(ubi->dbg_peb_buf);
#endif
- kfree(ubi);
+ if (ref)
+ put_device(&ubi->dev);
+ else
+ kfree(ubi);
return err;
}
@@ -1096,7 +1097,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
/*
* Get a reference to the device in order to prevent 'dev_release()'
- * from freeing @ubi object.
+ * from freeing the @ubi object.
*/
get_device(&ubi->dev);
@@ -1116,13 +1117,50 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
}
/**
- * find_mtd_device - open an MTD device by its name or number.
- * @mtd_dev: name or number of the device
+ * open_mtd_by_chdev - open an MTD device by its character device node path.
+ * @mtd_dev: MTD character device node path
+ *
+ * This helper function opens an MTD device by its character node device path.
+ * Returns MTD device description object in case of success and a negative
+ * error code in case of failure.
+ */
+static struct mtd_info * __init open_mtd_by_chdev(const char *mtd_dev)
+{
+ int err, major, minor, mode;
+ struct path path;
+
+ /* Probably this is an MTD character device node path */
+ err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
+ if (err)
+ return ERR_PTR(err);
+
+ /* MTD device number is defined by the major / minor numbers */
+ major = imajor(path.dentry->d_inode);
+ minor = iminor(path.dentry->d_inode);
+ mode = path.dentry->d_inode->i_mode;
+ path_put(&path);
+ if (major != MTD_CHAR_MAJOR || !S_ISCHR(mode))
+ return ERR_PTR(-EINVAL);
+
+ if (minor & 1)
+ /*
+ * Just do not think the "/dev/mtdrX" devices support is need,
+ * so do not support them to avoid doing extra work.
+ */
+ return ERR_PTR(-EINVAL);
+
+ return get_mtd_device(NULL, minor / 2);
+}
+
+/**
+ * open_mtd_device - open MTD device by name, character device path, or number.
+ * @mtd_dev: name, character device node path, or MTD device device number
*
* This function tries to open and MTD device described by @mtd_dev string,
- * which is first treated as an ASCII number, and if it is not true, it is
- * treated as MTD device name. Returns MTD device description object in case of
- * success and a negative error code in case of failure.
+ * which is first treated as ASCII MTD device number, and if it is not true, it
+ * is treated as MTD device name, and if that is also not true, it is treated
+ * as MTD character device node path. Returns MTD device description object in
+ * case of success and a negative error code in case of failure.
*/
static struct mtd_info * __init open_mtd_device(const char *mtd_dev)
{
@@ -1137,6 +1175,9 @@ static struct mtd_info * __init open_mtd_device(const char *mtd_dev)
* MTD device name.
*/
mtd = get_mtd_device_nm(mtd_dev);
+ if (IS_ERR(mtd) && PTR_ERR(mtd) == -ENODEV)
+ /* Probably this is an MTD character device node path */
+ mtd = open_mtd_by_chdev(mtd_dev);
} else
mtd = get_mtd_device(NULL, mtd_num);
@@ -1352,13 +1393,15 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000);
MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: "
- "mtd=<name|num>[,<vid_hdr_offs>].\n"
+ "mtd=<name|num|path>[,<vid_hdr_offs>].\n"
"Multiple \"mtd\" parameters may be specified.\n"
- "MTD devices may be specified by their number or name.\n"
+ "MTD devices may be specified by their number, name, or "
+ "path to the MTD character device node.\n"
"Optional \"vid_hdr_offs\" parameter specifies UBI VID "
- "header position and data starting position to be used "
- "by UBI.\n"
- "Example: mtd=content,1984 mtd=4 - attach MTD device"
+ "header position to be used by UBI.\n"
+ "Example 1: mtd=/dev/mtd0 - attach MTD device "
+ "/dev/mtd0.\n"
+ "Example 2: mtd=content,1984 mtd=4 - attach MTD device "
"with name \"content\" using VID header offset 1984, and "
"MTD device number 4 with default VID header offset.");
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 111ea41c4ec..72ebb3f06b8 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -37,6 +37,7 @@
#include <linux/module.h>
#include <linux/stat.h>
+#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/capability.h>
#include <linux/uaccess.h>
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index f30bcb372c0..17a10712972 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -96,8 +96,11 @@ void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len);
+int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
+ int offset, int len);
#else
#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
+#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0
#endif
#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT
@@ -176,6 +179,7 @@ static inline int ubi_dbg_is_erase_failure(void)
#define ubi_dbg_is_write_failure() 0
#define ubi_dbg_is_erase_failure() 0
#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
+#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0
#endif /* !CONFIG_MTD_UBI_DEBUG */
#endif /* !__UBI_DEBUG_H__ */
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c
index b5e478fa266..9aa81584c8a 100644
--- a/drivers/mtd/ubi/gluebi.c
+++ b/drivers/mtd/ubi/gluebi.c
@@ -31,6 +31,7 @@
#include <linux/err.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/math64.h>
#include <linux/module.h>
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 8aa51e7a6a7..533b1a4b9af 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -88,6 +88,7 @@
#include <linux/crc32.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
@@ -143,7 +144,7 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
err = paranoid_check_not_bad(ubi, pnum);
if (err)
- return err > 0 ? -EINVAL : err;
+ return err;
addr = (loff_t)pnum * ubi->peb_size + offset;
retry:
@@ -236,12 +237,12 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
err = paranoid_check_not_bad(ubi, pnum);
if (err)
- return err > 0 ? -EINVAL : err;
+ return err;
/* The area we are writing to has to contain all 0xFF bytes */
err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
if (err)
- return err > 0 ? -EINVAL : err;
+ return err;
if (offset >= ubi->leb_start) {
/*
@@ -250,10 +251,10 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
*/
err = paranoid_check_peb_ec_hdr(ubi, pnum);
if (err)
- return err > 0 ? -EINVAL : err;
+ return err;
err = paranoid_check_peb_vid_hdr(ubi, pnum);
if (err)
- return err > 0 ? -EINVAL : err;
+ return err;
}
if (ubi_dbg_is_write_failure()) {
@@ -273,6 +274,21 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
} else
ubi_assert(written == len);
+ if (!err) {
+ err = ubi_dbg_check_write(ubi, buf, pnum, offset, len);
+ if (err)
+ return err;
+
+ /*
+ * Since we always write sequentially, the rest of the PEB has
+ * to contain only 0xFF bytes.
+ */
+ offset += len;
+ len = ubi->peb_size - offset;
+ if (len)
+ err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
+ }
+
return err;
}
@@ -348,7 +364,7 @@ retry:
err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size);
if (err)
- return err > 0 ? -EINVAL : err;
+ return err;
if (ubi_dbg_is_erase_failure() && !err) {
dbg_err("cannot erase PEB %d (emulated)", pnum);
@@ -542,7 +558,7 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture)
err = paranoid_check_not_bad(ubi, pnum);
if (err != 0)
- return err > 0 ? -EINVAL : err;
+ return err;
if (ubi->ro_mode) {
ubi_err("read-only mode");
@@ -819,7 +835,7 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum,
err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr);
if (err)
- return -EINVAL;
+ return err;
err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize);
return err;
@@ -1083,7 +1099,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
err = paranoid_check_peb_ec_hdr(ubi, pnum);
if (err)
- return err > 0 ? -EINVAL : err;
+ return err;
vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC);
vid_hdr->version = UBI_VERSION;
@@ -1092,7 +1108,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr);
if (err)
- return -EINVAL;
+ return err;
p = (char *)vid_hdr - ubi->vid_hdr_shift;
err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset,
@@ -1107,8 +1123,8 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
* @ubi: UBI device description object
* @pnum: physical eraseblock number to check
*
- * This function returns zero if the physical eraseblock is good, a positive
- * number if it is bad and a negative error code if an error occurred.
+ * This function returns zero if the physical eraseblock is good, %-EINVAL if
+ * it is bad and a negative error code if an error occurred.
*/
static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
{
@@ -1120,7 +1136,7 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_dbg_dump_stack();
- return err;
+ return err > 0 ? -EINVAL : err;
}
/**
@@ -1130,7 +1146,7 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
* @ec_hdr: the erase counter header to check
*
* This function returns zero if the erase counter header contains valid
- * values, and %1 if not.
+ * values, and %-EINVAL if not.
*/
static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_ec_hdr *ec_hdr)
@@ -1156,7 +1172,7 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
fail:
ubi_dbg_dump_ec_hdr(ec_hdr);
ubi_dbg_dump_stack();
- return 1;
+ return -EINVAL;
}
/**
@@ -1164,8 +1180,8 @@ fail:
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to check
*
- * This function returns zero if the erase counter header is all right, %1 if
- * not, and a negative error code if an error occurred.
+ * This function returns zero if the erase counter header is all right and and
+ * a negative error code if not or if an error occurred.
*/
static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
{
@@ -1188,7 +1204,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_dbg_dump_ec_hdr(ec_hdr);
ubi_dbg_dump_stack();
- err = 1;
+ err = -EINVAL;
goto exit;
}
@@ -1206,7 +1222,7 @@ exit:
* @vid_hdr: the volume identifier header to check
*
* This function returns zero if the volume identifier header is all right, and
- * %1 if not.
+ * %-EINVAL if not.
*/
static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
const struct ubi_vid_hdr *vid_hdr)
@@ -1233,7 +1249,7 @@ fail:
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_dbg_dump_vid_hdr(vid_hdr);
ubi_dbg_dump_stack();
- return 1;
+ return -EINVAL;
}
@@ -1243,7 +1259,7 @@ fail:
* @pnum: the physical eraseblock number to check
*
* This function returns zero if the volume identifier header is all right,
- * %1 if not, and a negative error code if an error occurred.
+ * and a negative error code if not or if an error occurred.
*/
static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
{
@@ -1270,7 +1286,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
ubi_err("paranoid check failed for PEB %d", pnum);
ubi_dbg_dump_vid_hdr(vid_hdr);
ubi_dbg_dump_stack();
- err = 1;
+ err = -EINVAL;
goto exit;
}
@@ -1282,6 +1298,61 @@ exit:
}
/**
+ * ubi_dbg_check_write - make sure write succeeded.
+ * @ubi: UBI device description object
+ * @buf: buffer with data which were written
+ * @pnum: physical eraseblock number the data were written to
+ * @offset: offset within the physical eraseblock the data were written to
+ * @len: how many bytes were written
+ *
+ * This functions reads data which were recently written and compares it with
+ * the original data buffer - the data have to match. Returns zero if the data
+ * match and a negative error code if not or in case of failure.
+ */
+int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
+ int offset, int len)
+{
+ int err, i;
+
+ mutex_lock(&ubi->dbg_buf_mutex);
+ err = ubi_io_read(ubi, ubi->dbg_peb_buf, pnum, offset, len);
+ if (err)
+ goto out_unlock;
+
+ for (i = 0; i < len; i++) {
+ uint8_t c = ((uint8_t *)buf)[i];
+ uint8_t c1 = ((uint8_t *)ubi->dbg_peb_buf)[i];
+ int dump_len;
+
+ if (c == c1)
+ continue;
+
+ ubi_err("paranoid check failed for PEB %d:%d, len %d",
+ pnum, offset, len);
+ ubi_msg("data differ at position %d", i);
+ dump_len = max_t(int, 128, len - i);
+ ubi_msg("hex dump of the original buffer from %d to %d",
+ i, i + dump_len);
+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
+ buf + i, dump_len, 1);
+ ubi_msg("hex dump of the read buffer from %d to %d",
+ i, i + dump_len);
+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
+ ubi->dbg_peb_buf + i, dump_len, 1);
+ ubi_dbg_dump_stack();
+ err = -EINVAL;
+ goto out_unlock;
+ }
+ mutex_unlock(&ubi->dbg_buf_mutex);
+
+ return 0;
+
+out_unlock:
+ mutex_unlock(&ubi->dbg_buf_mutex);
+ return err;
+}
+
+/**
* ubi_dbg_check_all_ff - check that a region of flash is empty.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to check
@@ -1289,8 +1360,8 @@ exit:
* @len: the length of the region to check
*
* This function returns zero if only 0xFF bytes are present at offset
- * @offset of the physical eraseblock @pnum, %1 if not, and a negative error
- * code if an error occurred.
+ * @offset of the physical eraseblock @pnum, and a negative error code if not
+ * or if an error occurred.
*/
int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
{
@@ -1321,7 +1392,7 @@ fail:
ubi_msg("hex dump of the %d-%d region", offset, offset + len);
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
ubi->dbg_peb_buf, len, 1);
- err = 1;
+ err = -EINVAL;
error:
ubi_dbg_dump_stack();
mutex_unlock(&ubi->dbg_buf_mutex);
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index 1361574e2b0..17f287decc3 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/fs.h>
#include <asm/div64.h>
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 90af61a2c3e..dc5f688699d 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -41,6 +41,7 @@
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/crc32.h>
#include <linux/math64.h>
#include "ubi.h"
@@ -974,11 +975,8 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
seb->ec = si->mean_ec;
err = paranoid_check_si(ubi, si);
- if (err) {
- if (err > 0)
- err = -EINVAL;
+ if (err)
goto out_vidh;
- }
ubi_free_vid_hdr(ubi, vidh);
kfree(ech);
@@ -1086,8 +1084,8 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
* @ubi: UBI device description object
* @si: scanning information
*
- * This function returns zero if the scanning information is all right, %1 if
- * not and a negative error code if an error occurred.
+ * This function returns zero if the scanning information is all right, and a
+ * negative error code if not or if an error occurred.
*/
static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si)
{
@@ -1346,7 +1344,7 @@ bad_vid_hdr:
out:
ubi_dbg_dump_stack();
- return 1;
+ return -EINVAL;
}
#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 1af08178def..5176d488651 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -34,6 +34,7 @@
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/notifier.h>
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index ab64cb56df6..e42afab9a9f 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/math64.h>
+#include <linux/slab.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 40044028d68..cd90ff3b76b 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -58,6 +58,7 @@
#include <linux/crc32.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <asm/div64.h>
#include "ubi.h"
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 600c7229d5c..f64ddabd4ac 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -464,7 +464,7 @@ retry:
ubi->peb_size - ubi->vid_hdr_aloffset);
if (err) {
ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum);
- return err > 0 ? -EINVAL : err;
+ return err;
}
return e->pnum;
@@ -513,7 +513,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
dbg_wl("erase PEB %d, old EC %llu", e->pnum, ec);
err = paranoid_check_ec(ubi, e->pnum, e->ec);
- if (err > 0)
+ if (err)
return -EINVAL;
ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
@@ -1572,8 +1572,7 @@ void ubi_wl_close(struct ubi_device *ubi)
* @ec: the erase counter to check
*
* This function returns zero if the erase counter of physical eraseblock @pnum
- * is equivalent to @ec, %1 if not, and a negative error code if an error
- * occurred.
+ * is equivalent to @ec, and a negative error code if not or if an error occurred.
*/
static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec)
{
@@ -1611,8 +1610,8 @@ out_free:
* @e: the wear-leveling entry to check
* @root: the root of the tree
*
- * This function returns zero if @e is in the @root RB-tree and %1 if it is
- * not.
+ * This function returns zero if @e is in the @root RB-tree and %-EINVAL if it
+ * is not.
*/
static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e,
struct rb_root *root)
@@ -1623,7 +1622,7 @@ static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e,
ubi_err("paranoid check failed for PEB %d, EC %d, RB-tree %p ",
e->pnum, e->ec, root);
ubi_dbg_dump_stack();
- return 1;
+ return -EINVAL;
}
/**
@@ -1632,7 +1631,7 @@ static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e,
* @ubi: UBI device description object
* @e: the wear-leveling entry to check
*
- * This function returns zero if @e is in @ubi->pq and %1 if it is not.
+ * This function returns zero if @e is in @ubi->pq and %-EINVAL if it is not.
*/
static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e)
{
@@ -1647,6 +1646,6 @@ static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e)
ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue",
e->pnum, e->ec);
ubi_dbg_dump_stack();
- return 1;
+ return -EINVAL;
}
#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index b6de7b1e2a5..3ea42ff1765 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -117,7 +117,6 @@ static const char version[] =
#include <linux/fcntl.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index 04b5bba1902..29b8d1d63bd 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -102,12 +102,12 @@
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index 77cf0901a44..b32b7a1710b 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -58,7 +58,6 @@ static const char version[] =
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/bitops.h>
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 902435a7646..ab9bb3c5200 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -76,7 +76,6 @@
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 1e898b1c806..2e17837be54 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -65,7 +65,6 @@ static int max_interrupt_work = 20;
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index beed4fa10c6..1719079cc49 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -99,7 +99,6 @@
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/mca-legacy.h>
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index f965431f492..5f92fdbe66e 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -77,7 +77,6 @@ static int vortex_debug = 1;
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/mii.h>
@@ -90,6 +89,7 @@ static int vortex_debug = 1;
#include <linux/eisa.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
+#include <linux/gfp.h>
#include <asm/irq.h> /* For nr_irqs only. */
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/7990.c b/drivers/net/7990.c
index 4e9a5a20b6a..500e135723b 100644
--- a/drivers/net/7990.c
+++ b/drivers/net/7990.c
@@ -26,7 +26,6 @@
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/route.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <asm/irq.h>
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 3d4406b1665..a09e6ce3eaa 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -64,6 +64,7 @@
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
+#include <linux/gfp.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index b4efc913978..f0d23de3296 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -110,6 +110,7 @@
#include <linux/crc32.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/gfp.h>
#include <asm/irq.h>
#define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION
@@ -1943,7 +1944,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
netif_dbg(tp, rx_status, dev, "%s() status %04x, size %04x, cur %04x\n",
__func__, rx_status, rx_size, cur_rx);
#if RTL8139_DEBUG > 2
- print_dump_hex(KERN_DEBUG, "Frame contents: ",
+ print_hex_dump(KERN_DEBUG, "Frame contents: ",
DUMP_PREFIX_OFFSET, 16, 1,
&rx_ring[ring_offset], 70, true);
#endif
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index f94d17d78bb..56e68db4886 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -45,7 +45,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
@@ -53,6 +52,7 @@
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/dma.h>
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7029cd50c45..7b832c727f8 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -907,7 +907,7 @@ config SMC91X
select CRC32
select MII
depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
- MIPS || BLACKFIN || MN10300
+ MIPS || BLACKFIN || MN10300 || COLDFIRE
help
This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it
@@ -2582,6 +2582,31 @@ config CHELSIO_T3
To compile this driver as a module, choose M here: the module
will be called cxgb3.
+config CHELSIO_T4_DEPENDS
+ tristate
+ depends on PCI && INET
+ default y
+
+config CHELSIO_T4
+ tristate "Chelsio Communications T4 Ethernet support"
+ depends on CHELSIO_T4_DEPENDS
+ select FW_LOADER
+ select MDIO
+ help
+ This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
+ adapters.
+
+ For general information about Chelsio and our products, visit
+ our website at <http://www.chelsio.com>.
+
+ For customer support, please visit our customer support page at
+ <http://www.chelsio.com/support.htm>.
+
+ Please send feedback to <linux-bugs@chelsio.com>.
+
+ To compile this driver as a module choose M here; the module
+ will be called cxgb4.
+
config EHEA
tristate "eHEA Ethernet support"
depends on IBMEBUS && INET && SPARSEMEM
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 478886234c2..12b280afdd5 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_IXGB) += ixgb/
obj-$(CONFIG_IP1000) += ipg.o
obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_CHELSIO_T3) += cxgb3/
+obj-$(CONFIG_CHELSIO_T4) += cxgb4/
obj-$(CONFIG_EHEA) += ehea/
obj-$(CONFIG_CAN) += can/
obj-$(CONFIG_BONDING) += bonding/
@@ -272,6 +273,7 @@ obj-$(CONFIG_USB_RTL8150) += usb/
obj-$(CONFIG_USB_HSO) += usb/
obj-$(CONFIG_USB_USBNET) += usb/
obj-$(CONFIG_USB_ZD1201) += usb/
+obj-$(CONFIG_USB_IPHETH) += usb/
obj-y += wireless/
obj-$(CONFIG_NET_TULIP) += tulip/
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index bd4d829eca1..ed5e9742be2 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -46,7 +46,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/crc32.h>
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 4ae750ef1e1..97a3dfd94df 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -67,6 +67,7 @@
#include <linux/highmem.h>
#include <linux/sockios.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
#include <linux/if_vlan.h>
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index b8a59d255b4..8d58f0a8f42 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -73,7 +73,6 @@ Revision History:
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/compiler.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/ioport.h>
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 73b38c204eb..6f8d6206b5c 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -56,7 +56,6 @@ static const char *version =
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
index eb0448b03f4..79636ee3582 100644
--- a/drivers/net/appletalk/ipddp.c
+++ b/drivers/net/appletalk/ipddp.c
@@ -31,6 +31,7 @@
#include <linux/ip.h>
#include <linux/atalk.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/route.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index 8ea4ec705be..6af65b656f3 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -215,7 +215,6 @@ static int dma;
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
@@ -228,6 +227,7 @@ static int dma;
#include <linux/timer.h>
#include <linux/atalk.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/dma.h>
diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
index 8ea9c7545c1..705e6ce2eb9 100644
--- a/drivers/net/arcnet/arc-rawmode.c
+++ b/drivers/net/arcnet/arc-rawmode.c
@@ -25,6 +25,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/if_arp.h>
#include <net/arp.h>
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
index e6afab2455b..9efbbbae47c 100644
--- a/drivers/net/arcnet/arc-rimi.c
+++ b/drivers/net/arcnet/arc-rimi.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/bootmem.h>
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index 66bcbbb6bab..355797f7004 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -27,6 +27,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/if_arp.h>
#include <net/arp.h>
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index db08fc24047..0402da30a4e 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -30,7 +30,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index b68e1eb405f..2c712af6c26 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -31,7 +31,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/init.h>
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 0a74f21409c..c9e459400ff 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -29,7 +29,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
index 28dea518d55..4cb401813b7 100644
--- a/drivers/net/arcnet/com90io.c
+++ b/drivers/net/arcnet/com90io.c
@@ -29,7 +29,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/bootmem.h>
diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
index 112e230cb13..f3b46f71e29 100644
--- a/drivers/net/arcnet/com90xx.c
+++ b/drivers/net/arcnet/com90xx.c
@@ -30,6 +30,7 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/arcdevice.h>
diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c
index 06f8fa2f8f2..f81db4070a5 100644
--- a/drivers/net/arcnet/rfc1051.c
+++ b/drivers/net/arcnet/rfc1051.c
@@ -24,6 +24,7 @@
* **********************
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/if_arp.h>
#include <net/arp.h>
diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c
index 745530651c4..b71431aae08 100644
--- a/drivers/net/arcnet/rfc1201.c
+++ b/drivers/net/arcnet/rfc1201.c
@@ -23,6 +23,7 @@
*
* **********************
*/
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/if_arp.h>
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index 08d8be47dae..fa1a2354f5f 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -40,7 +40,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 8b23d5a175b..aed5b5479b5 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -27,6 +27,7 @@
#include <linux/ethtool.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index bf72d57a0af..6995169d285 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index f52f668c49b..4af235d41fd 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -33,7 +33,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index 6e2ae1d06df..6be8b098b8b 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <mach/npe.h>
#include <mach/qmgr.h>
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 8ca639127db..84f8a8f7380 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -30,6 +30,7 @@
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/irq.h>
@@ -449,11 +450,10 @@ ks8695_rx_irq(int irq, void *dev_id)
}
/**
- * ks8695_rx - Receive packets called by NAPI poll method
+ * ks8695_rx - Receive packets called by NAPI poll method
* @ksp: Private data for the KS8695 Ethernet
- * @budget: The max packets would be receive
+ * @budget: Number of packets allowed to process
*/
-
static int ks8695_rx(struct ks8695_priv *ksp, int budget)
{
struct net_device *ndev = ksp->ndev;
@@ -461,7 +461,6 @@ static int ks8695_rx(struct ks8695_priv *ksp, int budget)
int buff_n;
u32 flags;
int pktlen;
- int last_rx_processed = -1;
int received = 0;
buff_n = ksp->next_rx_desc_read;
@@ -471,6 +470,7 @@ static int ks8695_rx(struct ks8695_priv *ksp, int budget)
cpu_to_le32(RDES_OWN)))) {
rmb();
flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
+
/* Found an SKB which we own, this means we
* received a packet
*/
@@ -533,23 +533,18 @@ rx_failure:
ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
rx_finished:
received++;
- /* And note this as processed so we can start
- * from here next time
- */
- last_rx_processed = buff_n;
buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
- /*And note which RX descriptor we last did */
- if (likely(last_rx_processed != -1))
- ksp->next_rx_desc_read =
- (last_rx_processed + 1) &
- MAX_RX_DESC_MASK;
}
+
+ /* And note which RX descriptor we last did */
+ ksp->next_rx_desc_read = buff_n;
+
/* And refill the buffers */
ks8695_refill_rxbuffers(ksp);
- /* Kick the RX DMA engine, in case it became
- * suspended */
+ /* Kick the RX DMA engine, in case it became suspended */
ks8695_writereg(ksp, KS8695_DRSC, 0);
+
return received;
}
@@ -575,9 +570,9 @@ static int ks8695_poll(struct napi_struct *napi, int budget)
if (work_done < budget) {
unsigned long flags;
spin_lock_irqsave(&ksp->rx_lock, flags);
+ __napi_complete(napi);
/*enable rx interrupt*/
writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
- __napi_complete(napi);
spin_unlock_irqrestore(&ksp->rx_lock, flags);
}
return work_done;
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c
index febd813c916..f7c9ca1dfb1 100644
--- a/drivers/net/arm/w90p910_ether.c
+++ b/drivers/net/arm/w90p910_ether.c
@@ -18,6 +18,7 @@
#include <linux/ethtool.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/gfp.h>
#define DRV_MODULE_NAME "w90p910-emc"
#define DRV_MODULE_VERSION "0.1"
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 309843ab886..10a20fb9ae6 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -47,7 +47,6 @@
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/crc32.h>
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index 280cfff48b4..a8686bfec7a 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -53,7 +53,6 @@ static char version[] = "atarilance.c: v1.3 04/04/96 "
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/bitops.h>
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
index 61a0f2ff11e..32339243d61 100644
--- a/drivers/net/atl1c/atl1c_ethtool.c
+++ b/drivers/net/atl1c/atl1c_ethtool.c
@@ -22,6 +22,7 @@
#include <linux/netdevice.h>
#include <linux/ethtool.h>
+#include <linux/slab.h>
#include "atl1c.h"
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index a76006c1bc6..ffd696ee7c8 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -22,6 +22,7 @@
#include <linux/netdevice.h>
#include <linux/ethtool.h>
+#include <linux/slab.h>
#include "atl1e.h"
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 9ba547069db..0ebd8208f60 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -84,7 +84,7 @@
#define ATLX_DRIVER_VERSION "2.1.3"
MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
- Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
+Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
MODULE_LICENSE("GPL");
MODULE_VERSION(ATLX_DRIVER_VERSION);
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 7061d7108f0..54662f24f9b 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -39,6 +39,7 @@
#include <linux/pci_ids.h>
#include <linux/pm.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/tcp.h>
diff --git a/drivers/net/atlx/atl2.h b/drivers/net/atlx/atl2.h
index d918bbe621e..927e4de6474 100644
--- a/drivers/net/atlx/atl2.h
+++ b/drivers/net/atlx/atl2.h
@@ -442,7 +442,7 @@ struct atl2_hw {
struct atl2_ring_header {
/* pointer to the descriptor ring memory */
void *desc;
- /* physical adress of the descriptor ring */
+ /* physical address of the descriptor ring */
dma_addr_t dma;
/* length of descriptor ring in bytes */
unsigned int size;
diff --git a/drivers/net/atp.c b/drivers/net/atp.c
index 6ad16205dc1..55039d44dc4 100644
--- a/drivers/net/atp.c
+++ b/drivers/net/atp.c
@@ -129,7 +129,6 @@ static int xcvr[NUM_UNITS]; /* The data transfer mode. */
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 1dd4403247c..b718dc60afc 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -25,6 +25,7 @@
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
#include <net/ax88796.h>
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 332c6035628..69d9f3d368a 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/ssb/ssb.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index 8cdcab7655c..17460aba3ba 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index be81fb2d10f..56387b191c9 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -29,6 +29,7 @@
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include "be_hw.h"
@@ -290,11 +291,6 @@ extern const struct ethtool_ops be_ethtool_ops;
#define drvr_stats(adapter) (&adapter->stats.drvr_stats)
-static inline unsigned int be_pci_func(struct be_adapter *adapter)
-{
- return PCI_FUNC(adapter->pdev->devfn);
-}
-
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
#define PAGE_SHIFT_4K 12
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 4b1f80519ca..d0ef4ac987c 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -465,8 +465,6 @@ int be_cmd_eq_create(struct be_adapter *adapter,
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
- AMAP_SET_BITS(struct amap_eq_context, func, req->context,
- be_pci_func(adapter));
AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
/* 4byte eqe*/
AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
@@ -629,7 +627,6 @@ int be_cmd_cq_create(struct be_adapter *adapter,
AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
- AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter));
be_dws_cpu_to_le(ctxt, sizeof(req->context));
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
@@ -676,9 +673,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_MCC_CREATE, sizeof(*req));
- req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+ req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
- AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter));
AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
be_encoded_q_len(mccq->len));
@@ -727,8 +723,6 @@ int be_cmd_txq_create(struct be_adapter *adapter,
AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
be_encoded_q_len(txq->len));
- AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
- be_pci_func(adapter));
AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);
@@ -1470,8 +1464,8 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
- req->params.offset = offset;
- req->params.data_buf_size = 0x4;
+ req->params.offset = cpu_to_le32(offset);
+ req->params.data_buf_size = cpu_to_le32(0x4);
status = be_mcc_notify_wait(adapter);
if (!status)
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 9560d48944a..51e1065e789 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -490,7 +490,7 @@ be_test_ddr_dma(struct be_adapter *adapter)
{
int ret, i;
struct be_dma_mem ddrdma_cmd;
- u64 pattern[2] = {0x5a5a5a5a5a5a5a5a, 0xa5a5a5a5a5a5a5a5};
+ u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL};
ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test);
ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size,
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
index 5ffb149181a..2d4a4b82763 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -114,8 +114,7 @@
#define IMG_TYPE_ISCSI_BACKUP 9
#define IMG_TYPE_FCOE_FW_ACTIVE 10
#define IMG_TYPE_FCOE_FW_BACKUP 11
-#define IMG_TYPE_NCSI_BITFILE 13
-#define IMG_TYPE_NCSI_8051 14
+#define IMG_TYPE_NCSI_FW 13
#define FLASHROM_OPER_FLASH 1
#define FLASHROM_OPER_SAVE 2
@@ -127,6 +126,7 @@
#define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */
#define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */
#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */
+#define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144) /* Max NSCI image sz */
#define FLASH_NCSI_MAGIC (0x16032009)
#define FLASH_NCSI_DISABLED (0)
@@ -144,6 +144,7 @@
#define FLASH_FCoE_BIOS_START_g2 (524288)
#define FLASH_REDBOOT_START_g2 (0)
+#define FLASH_NCSI_START_g3 (15990784)
#define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152)
#define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304)
#define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456)
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index a703ed8e24f..ec6ace80225 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -807,7 +807,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
return;
}
vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
- vid = be16_to_cpu(vid);
+ vid = swab16(vid);
vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid);
} else {
netif_receive_skb(skb);
@@ -884,7 +884,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
napi_gro_frags(&eq_obj->napi);
} else {
vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
- vid = be16_to_cpu(vid);
+ vid = swab16(vid);
if (!adapter->vlan_grp || adapter->vlans_added == 0)
return;
@@ -1382,7 +1382,7 @@ rx_eq_free:
/* There are 8 evt ids per func. Retruns the evt id's bit number */
static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
{
- return eq_id - 8 * be_pci_func(adapter);
+ return eq_id % 8;
}
static irqreturn_t be_intx(int irq, void *dev)
@@ -1855,7 +1855,7 @@ static bool be_flash_redboot(struct be_adapter *adapter,
p += crc_offset;
status = be_cmd_get_flash_crc(adapter, flashed_crc,
- (img_start + image_size - 4));
+ (image_size - 4));
if (status) {
dev_err(&adapter->pdev->dev,
"could not get crc from flash, not flashing redboot\n");
@@ -1880,8 +1880,9 @@ static int be_flash_data(struct be_adapter *adapter,
const u8 *p = fw->data;
struct be_cmd_write_flashrom *req = flash_cmd->va;
struct flash_comp *pflashcomp;
+ int num_comp;
- struct flash_comp gen3_flash_types[8] = {
+ struct flash_comp gen3_flash_types[9] = {
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
FLASH_IMAGE_MAX_SIZE_g3},
{ FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
@@ -1897,7 +1898,9 @@ static int be_flash_data(struct be_adapter *adapter,
{ FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
FLASH_IMAGE_MAX_SIZE_g3},
{ FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
- FLASH_IMAGE_MAX_SIZE_g3}
+ FLASH_IMAGE_MAX_SIZE_g3},
+ { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
+ FLASH_NCSI_IMAGE_MAX_SIZE_g3}
};
struct flash_comp gen2_flash_types[8] = {
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
@@ -1921,11 +1924,16 @@ static int be_flash_data(struct be_adapter *adapter,
if (adapter->generation == BE_GEN3) {
pflashcomp = gen3_flash_types;
filehdr_size = sizeof(struct flash_file_hdr_g3);
+ num_comp = 9;
} else {
pflashcomp = gen2_flash_types;
filehdr_size = sizeof(struct flash_file_hdr_g2);
+ num_comp = 8;
}
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < num_comp; i++) {
+ if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
+ memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
+ continue;
if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
(!be_flash_redboot(adapter, fw->data,
pflashcomp[i].offset, pflashcomp[i].size,
@@ -1983,18 +1991,9 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
struct flash_file_hdr_g3 *fhdr3;
struct image_hdr *img_hdr_ptr = NULL;
struct be_dma_mem flash_cmd;
- int status, i = 0;
+ int status, i = 0, num_imgs = 0;
const u8 *p;
- char fw_ver[FW_VER_LEN];
- char fw_cfg;
- status = be_cmd_get_fw_ver(adapter, fw_ver);
- if (status)
- return status;
-
- fw_cfg = *(fw_ver + 2);
- if (fw_cfg == '0')
- fw_cfg = '1';
strcpy(fw_file, func);
status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
@@ -2018,15 +2017,14 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
if ((adapter->generation == BE_GEN3) &&
(get_ufigen_type(fhdr) == BE_GEN3)) {
fhdr3 = (struct flash_file_hdr_g3 *) fw->data;
- for (i = 0; i < fhdr3->num_imgs; i++) {
+ num_imgs = le32_to_cpu(fhdr3->num_imgs);
+ for (i = 0; i < num_imgs; i++) {
img_hdr_ptr = (struct image_hdr *) (fw->data +
(sizeof(struct flash_file_hdr_g3) +
- i * sizeof(struct image_hdr)));
- if (img_hdr_ptr->imageid == 1) {
- status = be_flash_data(adapter, fw,
- &flash_cmd, fhdr3->num_imgs);
- }
-
+ i * sizeof(struct image_hdr)));
+ if (le32_to_cpu(img_hdr_ptr->imageid) == 1)
+ status = be_flash_data(adapter, fw, &flash_cmd,
+ num_imgs);
}
} else if ((adapter->generation == BE_GEN2) &&
(get_ufigen_type(fhdr) == BE_GEN2)) {
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 119468e7632..598b007f199 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -20,6 +20,7 @@
#include <linux/crc32.h>
#include <linux/bitrev.h>
#include <linux/ethtool.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.h>
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 381887ba677..ac90a3828f6 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -58,8 +58,8 @@
#include "bnx2_fw.h"
#define DRV_MODULE_NAME "bnx2"
-#define DRV_MODULE_VERSION "2.0.8"
-#define DRV_MODULE_RELDATE "Feb 15, 2010"
+#define DRV_MODULE_VERSION "2.0.9"
+#define DRV_MODULE_RELDATE "April 27, 2010"
#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-5.0.0.j6.fw"
#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-5.0.0.j3.fw"
#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-5.0.0.j9.fw"
@@ -246,6 +246,8 @@ static const struct flash_spec flash_5709 = {
MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
+static void bnx2_init_napi(struct bnx2 *bp);
+
static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
{
u32 diff;
@@ -649,9 +651,10 @@ bnx2_napi_enable(struct bnx2 *bp)
}
static void
-bnx2_netif_stop(struct bnx2 *bp)
+bnx2_netif_stop(struct bnx2 *bp, bool stop_cnic)
{
- bnx2_cnic_stop(bp);
+ if (stop_cnic)
+ bnx2_cnic_stop(bp);
if (netif_running(bp->dev)) {
int i;
@@ -669,14 +672,15 @@ bnx2_netif_stop(struct bnx2 *bp)
}
static void
-bnx2_netif_start(struct bnx2 *bp)
+bnx2_netif_start(struct bnx2 *bp, bool start_cnic)
{
if (atomic_dec_and_test(&bp->intr_sem)) {
if (netif_running(bp->dev)) {
netif_tx_wake_all_queues(bp->dev);
bnx2_napi_enable(bp);
bnx2_enable_int(bp);
- bnx2_cnic_start(bp);
+ if (start_cnic)
+ bnx2_cnic_start(bp);
}
}
}
@@ -4757,8 +4761,12 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
rc = bnx2_alloc_bad_rbuf(bp);
}
- if (bp->flags & BNX2_FLAG_USING_MSIX)
+ if (bp->flags & BNX2_FLAG_USING_MSIX) {
bnx2_setup_msix_tbl(bp);
+ /* Prevent MSIX table reads and write from timing out */
+ REG_WR(bp, BNX2_MISC_ECO_HW_CTL,
+ BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN);
+ }
return rc;
}
@@ -6197,6 +6205,7 @@ bnx2_open(struct net_device *dev)
bnx2_disable_int(bp);
bnx2_setup_int_mode(bp, disable_msi);
+ bnx2_init_napi(bp);
bnx2_napi_enable(bp);
rc = bnx2_alloc_mem(bp);
if (rc)
@@ -6270,12 +6279,12 @@ bnx2_reset_task(struct work_struct *work)
return;
}
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
bnx2_init_nic(bp, 1);
atomic_set(&bp->intr_sem, 1);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
rtnl_unlock();
}
@@ -6317,7 +6326,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
struct bnx2 *bp = netdev_priv(dev);
if (netif_running(dev))
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, false);
bp->vlgrp = vlgrp;
@@ -6328,7 +6337,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, false);
}
#endif
@@ -7048,9 +7057,9 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
if (netif_running(bp->dev)) {
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
bnx2_init_nic(bp, 0);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
}
return 0;
@@ -7080,7 +7089,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
/* Reset will erase chipset stats; save them */
bnx2_save_stats(bp);
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
bnx2_free_skbs(bp);
bnx2_free_mem(bp);
@@ -7108,7 +7117,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
bnx2_setup_cnic_irq_info(bp);
mutex_unlock(&bp->cnic_lock);
#endif
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
}
return 0;
}
@@ -7361,7 +7370,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
if (etest->flags & ETH_TEST_FL_OFFLINE) {
int i;
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
bnx2_free_skbs(bp);
@@ -7380,7 +7389,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
bnx2_shutdown_chip(bp);
else {
bnx2_init_nic(bp, 1);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
}
/* wait for link up */
@@ -7643,9 +7652,11 @@ poll_bnx2(struct net_device *dev)
int i;
for (i = 0; i < bp->irq_nvecs; i++) {
- disable_irq(bp->irq_tbl[i].vector);
- bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]);
- enable_irq(bp->irq_tbl[i].vector);
+ struct bnx2_irq *irq = &bp->irq_tbl[i];
+
+ disable_irq(irq->vector);
+ irq->handler(irq->vector, &bp->bnx2_napi[i]);
+ enable_irq(irq->vector);
}
}
#endif
@@ -8207,7 +8218,7 @@ bnx2_init_napi(struct bnx2 *bp)
{
int i;
- for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+ for (i = 0; i < bp->irq_nvecs; i++) {
struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
int (*poll)(struct napi_struct *, int);
@@ -8276,7 +8287,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->ethtool_ops = &bnx2_ethtool_ops;
bp = netdev_priv(dev);
- bnx2_init_napi(bp);
pci_set_drvdata(pdev, dev);
@@ -8373,7 +8383,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
flush_scheduled_work();
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
netif_device_detach(dev);
del_timer_sync(&bp->timer);
bnx2_shutdown_chip(bp);
@@ -8395,7 +8405,7 @@ bnx2_resume(struct pci_dev *pdev)
bnx2_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
bnx2_init_nic(bp, 1);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
return 0;
}
@@ -8422,7 +8432,7 @@ static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
}
if (netif_running(dev)) {
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
del_timer_sync(&bp->timer);
bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
}
@@ -8479,7 +8489,7 @@ static void bnx2_io_resume(struct pci_dev *pdev)
rtnl_lock();
if (netif_running(dev))
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
netif_device_attach(dev);
rtnl_unlock();
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index ed785a30e98..6c042a72d6c 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -893,7 +893,6 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
u16 prod;
u16 cons;
- barrier(); /* Tell compiler that prod and cons can change */
prod = fp->tx_bd_prod;
cons = fp->tx_bd_cons;
@@ -963,7 +962,7 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp)
* start_xmit() will miss it and cause the queue to be stopped
* forever.
*/
- smp_wmb();
+ smp_mb();
/* TBD need a thresh? */
if (unlikely(netif_tx_queue_stopped(txq))) {
@@ -11429,9 +11428,12 @@ static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
netif_tx_stop_queue(txq);
- /* We want bnx2x_tx_int to "see" the updated tx_bd_prod
- if we put Tx into XOFF state. */
+
+ /* paired memory barrier is in bnx2x_tx_int(), we have to keep
+ * ordering of set_bit() in netif_tx_stop_queue() and read of
+ * fp->bd_tx_cons */
smp_mb();
+
fp->eth_q_stats.driver_xoff++;
if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
netif_tx_wake_queue(txq);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 430c02267d7..0075514bf32 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1235,6 +1235,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
write_lock_bh(&bond->curr_slave_lock);
}
}
+
+ /* resend IGMP joins since all were sent on curr_active_slave */
+ if (bond->params.mode == BOND_MODE_ROUNDROBIN) {
+ bond_resend_igmp_join_requests(bond);
+ }
}
/**
@@ -4138,22 +4143,41 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave, *start_at;
int i, slave_no, res = 1;
+ struct iphdr *iph = ip_hdr(skb);
read_lock(&bond->lock);
if (!BOND_IS_OK(bond))
goto out;
-
/*
- * Concurrent TX may collide on rr_tx_counter; we accept that
- * as being rare enough not to justify using an atomic op here
+ * Start with the curr_active_slave that joined the bond as the
+ * default for sending IGMP traffic. For failover purposes one
+ * needs to maintain some consistency for the interface that will
+ * send the join/membership reports. The curr_active_slave found
+ * will send all of this type of traffic.
*/
- slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
+ if ((iph->protocol == IPPROTO_IGMP) &&
+ (skb->protocol == htons(ETH_P_IP))) {
- bond_for_each_slave(bond, slave, i) {
- slave_no--;
- if (slave_no < 0)
- break;
+ read_lock(&bond->curr_slave_lock);
+ slave = bond->curr_active_slave;
+ read_unlock(&bond->curr_slave_lock);
+
+ if (!slave)
+ goto out;
+ } else {
+ /*
+ * Concurrent TX may collide on rr_tx_counter; we accept
+ * that as being rare enough not to justify using an
+ * atomic op here.
+ */
+ slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
+
+ bond_for_each_slave(bond, slave, i) {
+ slave_no--;
+ if (slave_no < 0)
+ break;
+ }
}
start_at = slave;
@@ -4426,6 +4450,14 @@ static const struct net_device_ops bond_netdev_ops = {
.ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
};
+static void bond_destructor(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ if (bond->wq)
+ destroy_workqueue(bond->wq);
+ free_netdev(bond_dev);
+}
+
static void bond_setup(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
@@ -4446,7 +4478,7 @@ static void bond_setup(struct net_device *bond_dev)
bond_dev->ethtool_ops = &bond_ethtool_ops;
bond_set_mode_ops(bond, bond->params.mode);
- bond_dev->destructor = free_netdev;
+ bond_dev->destructor = bond_destructor;
/* Initialize the device options */
bond_dev->tx_queue_len = 0;
@@ -4518,9 +4550,6 @@ static void bond_uninit(struct net_device *bond_dev)
bond_remove_proc_entry(bond);
- if (bond->wq)
- destroy_workqueue(bond->wq);
-
netif_addr_lock_bh(bond_dev);
bond_mc_list_destroy(bond);
netif_addr_unlock_bh(bond_dev);
@@ -4932,8 +4961,8 @@ int bond_create(struct net *net, const char *name)
bond_setup);
if (!bond_dev) {
pr_err("%s: eek! can't alloc netdev!\n", name);
- res = -ENOMEM;
- goto out;
+ rtnl_unlock();
+ return -ENOMEM;
}
dev_net_set(bond_dev, net);
@@ -4942,19 +4971,16 @@ int bond_create(struct net *net, const char *name)
if (!name) {
res = dev_alloc_name(bond_dev, "bond%d");
if (res < 0)
- goto out_netdev;
+ goto out;
}
res = register_netdevice(bond_dev);
- if (res < 0)
- goto out_netdev;
out:
rtnl_unlock();
+ if (res < 0)
+ bond_destructor(bond_dev);
return res;
-out_netdev:
- free_netdev(bond_dev);
- goto out;
}
static int __net_init bond_net_init(struct net *net)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 5acd557cea9..b8bec086daa 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -51,7 +51,9 @@
* "show" function for the bond_masters attribute.
* The class parameter is ignored.
*/
-static ssize_t bonding_show_bonds(struct class *cls, char *buf)
+static ssize_t bonding_show_bonds(struct class *cls,
+ struct class_attribute *attr,
+ char *buf)
{
struct net *net = current->nsproxy->net_ns;
struct bond_net *bn = net_generic(net, bond_net_id);
@@ -98,6 +100,7 @@ static struct net_device *bond_get_by_name(struct net *net, const char *ifname)
*/
static ssize_t bonding_store_bonds(struct class *cls,
+ struct class_attribute *attr,
const char *buffer, size_t count)
{
struct net *net = current->nsproxy->net_ns;
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c
index bf7f9ba2d90..03489864376 100644
--- a/drivers/net/can/bfin_can.c
+++ b/drivers/net/can/bfin_can.c
@@ -22,94 +22,12 @@
#include <linux/can/dev.h>
#include <linux/can/error.h>
+#include <asm/bfin_can.h>
#include <asm/portmux.h>
#define DRV_NAME "bfin_can"
#define BFIN_CAN_TIMEOUT 100
-
-/*
- * transmit and receive channels
- */
-#define TRANSMIT_CHL 24
-#define RECEIVE_STD_CHL 0
-#define RECEIVE_EXT_CHL 4
-#define RECEIVE_RTR_CHL 8
-#define RECEIVE_EXT_RTR_CHL 12
-#define MAX_CHL_NUMBER 32
-
-/*
- * bfin can registers layout
- */
-struct bfin_can_mask_regs {
- u16 aml;
- u16 dummy1;
- u16 amh;
- u16 dummy2;
-};
-
-struct bfin_can_channel_regs {
- u16 data[8];
- u16 dlc;
- u16 dummy1;
- u16 tsv;
- u16 dummy2;
- u16 id0;
- u16 dummy3;
- u16 id1;
- u16 dummy4;
-};
-
-struct bfin_can_regs {
- /*
- * global control and status registers
- */
- u16 mc1; /* offset 0 */
- u16 dummy1;
- u16 md1; /* offset 4 */
- u16 rsv1[13];
- u16 mbtif1; /* offset 0x20 */
- u16 dummy2;
- u16 mbrif1; /* offset 0x24 */
- u16 dummy3;
- u16 mbim1; /* offset 0x28 */
- u16 rsv2[11];
- u16 mc2; /* offset 0x40 */
- u16 dummy4;
- u16 md2; /* offset 0x44 */
- u16 dummy5;
- u16 trs2; /* offset 0x48 */
- u16 rsv3[11];
- u16 mbtif2; /* offset 0x60 */
- u16 dummy6;
- u16 mbrif2; /* offset 0x64 */
- u16 dummy7;
- u16 mbim2; /* offset 0x68 */
- u16 rsv4[11];
- u16 clk; /* offset 0x80 */
- u16 dummy8;
- u16 timing; /* offset 0x84 */
- u16 rsv5[3];
- u16 status; /* offset 0x8c */
- u16 dummy9;
- u16 cec; /* offset 0x90 */
- u16 dummy10;
- u16 gis; /* offset 0x94 */
- u16 dummy11;
- u16 gim; /* offset 0x98 */
- u16 rsv6[3];
- u16 ctrl; /* offset 0xa0 */
- u16 dummy12;
- u16 intr; /* offset 0xa4 */
- u16 rsv7[7];
- u16 esr; /* offset 0xb4 */
- u16 rsv8[37];
-
- /*
- * channel(mailbox) mask and message registers
- */
- struct bfin_can_mask_regs msk[MAX_CHL_NUMBER]; /* offset 0x100 */
- struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */
-};
+#define TX_ECHO_SKB_MAX 1
/*
* bfin can private data
@@ -162,7 +80,7 @@ static int bfin_can_set_bittiming(struct net_device *dev)
if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
timing |= SAM;
- bfin_write16(&reg->clk, clk);
+ bfin_write16(&reg->clock, clk);
bfin_write16(&reg->timing, timing);
dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n",
@@ -184,11 +102,11 @@ static void bfin_can_set_reset_mode(struct net_device *dev)
bfin_write16(&reg->gim, 0);
/* reset can and enter configuration mode */
- bfin_write16(&reg->ctrl, SRS | CCR);
+ bfin_write16(&reg->control, SRS | CCR);
SSYNC();
- bfin_write16(&reg->ctrl, CCR);
+ bfin_write16(&reg->control, CCR);
SSYNC();
- while (!(bfin_read16(&reg->ctrl) & CCA)) {
+ while (!(bfin_read16(&reg->control) & CCA)) {
udelay(10);
if (--timeout == 0) {
dev_err(dev->dev.parent,
@@ -243,7 +161,7 @@ static void bfin_can_set_normal_mode(struct net_device *dev)
/*
* leave configuration mode
*/
- bfin_write16(&reg->ctrl, bfin_read16(&reg->ctrl) & ~CCR);
+ bfin_write16(&reg->control, bfin_read16(&reg->control) & ~CCR);
while (bfin_read16(&reg->status) & CCA) {
udelay(10);
@@ -593,7 +511,7 @@ struct net_device *alloc_bfin_candev(void)
struct net_device *dev;
struct bfin_can_priv *priv;
- dev = alloc_candev(sizeof(*priv));
+ dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
if (!dev)
return NULL;
@@ -725,7 +643,7 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg)
if (netif_running(dev)) {
/* enter sleep mode */
- bfin_write16(&reg->ctrl, bfin_read16(&reg->ctrl) | SMR);
+ bfin_write16(&reg->control, bfin_read16(&reg->control) | SMR);
SSYNC();
while (!(bfin_read16(&reg->intr) & SMACK)) {
udelay(10);
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 904aa369f80..d0f8c7e67e7 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/can.h>
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index f8cc168ec76..b39b108318b 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -73,6 +73,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/uaccess.h>
diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c
index 87300606abb..5f53da0bc40 100644
--- a/drivers/net/can/sja1000/ems_pci.c
+++ b/drivers/net/can/sja1000/ems_pci.c
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/can.h>
#include <linux/can/dev.h>
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index 6b46a6395f8..4aff4070db9 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/can.h>
#include <linux/can/dev.h>
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 11c87840cc0..d800b598ae3 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -876,9 +876,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
return NETDEV_TX_OK;
nomem:
- if (skb)
- dev_kfree_skb(skb);
-
+ dev_kfree_skb(skb);
stats->tx_dropped++;
return NETDEV_TX_OK;
@@ -1008,7 +1006,7 @@ static int ems_usb_probe(struct usb_interface *intf,
netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
if (!netdev) {
- dev_err(netdev->dev.parent, "Couldn't alloc candev\n");
+ dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n");
return -ENOMEM;
}
@@ -1038,20 +1036,20 @@ static int ems_usb_probe(struct usb_interface *intf,
dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->intr_urb) {
- dev_err(netdev->dev.parent, "Couldn't alloc intr URB\n");
+ dev_err(&intf->dev, "Couldn't alloc intr URB\n");
goto cleanup_candev;
}
dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL);
if (!dev->intr_in_buffer) {
- dev_err(netdev->dev.parent, "Couldn't alloc Intr buffer\n");
+ dev_err(&intf->dev, "Couldn't alloc Intr buffer\n");
goto cleanup_intr_urb;
}
dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE +
sizeof(struct ems_cpc_msg), GFP_KERNEL);
if (!dev->tx_msg_buffer) {
- dev_err(netdev->dev.parent, "Couldn't alloc Tx buffer\n");
+ dev_err(&intf->dev, "Couldn't alloc Tx buffer\n");
goto cleanup_intr_in_buffer;
}
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index d124d837ae5..a30b8f480f6 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -48,6 +48,7 @@
#include <linux/if_ether.h>
#include <linux/can.h>
#include <linux/can/dev.h>
+#include <linux/slab.h>
#include <net/rtnetlink.h>
static __initdata const char banner[] =
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 7cbcfb0ade1..9bd155e4111 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -5072,7 +5072,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
INIT_WORK(&cp->reset_task, cas_reset_task);
/* Default link parameters */
- if (link_mode >= 0 && link_mode <= 6)
+ if (link_mode >= 0 && link_mode < 6)
cp->link_cntl = link_modes[link_mode];
else
cp->link_cntl = BMCR_ANENABLE;
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index 2d11afe4531..036b2dfb1d4 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -51,6 +51,7 @@
#include <linux/mdio.h>
#include <linux/crc32.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/pci_ids.h>
diff --git a/drivers/net/chelsio/pm3393.c b/drivers/net/chelsio/pm3393.c
index a6eb30a6e2b..9e631b9d394 100644
--- a/drivers/net/chelsio/pm3393.c
+++ b/drivers/net/chelsio/pm3393.c
@@ -44,6 +44,7 @@
#include "suni1x10gexp_regs.h"
#include <linux/crc32.h>
+#include <linux/slab.h>
#define OFFSET(REG_ADDR) ((REG_ADDR) << 2)
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 71384114a4e..df3a1410696 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -53,6 +53,7 @@
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include "cpl5_cmd.h"
#include "sge.h"
@@ -248,7 +249,7 @@ static void restart_sched(unsigned long);
*
* Interrupts are handled by a single CPU and it is likely that on a MP system
* the application is migrated to another CPU. In that scenario, we try to
- * seperate the RX(in irq context) and TX state in order to decrease memory
+ * separate the RX(in irq context) and TX state in order to decrease memory
* contention.
*/
struct sge {
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 9781942992e..4b451a7c03e 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2334,13 +2334,13 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
struct cnic_local *cp = dev->cnic_priv;
u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
- prefetch(cp->status_blk.bnx2x);
- prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+ if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+ prefetch(cp->status_blk.bnx2x);
+ prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
- if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
tasklet_schedule(&cp->cnic_irq_task);
-
- cnic_chk_pkt_rings(cp);
+ cnic_chk_pkt_rings(cp);
+ }
return 0;
}
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index b85c81f60d1..60777fd90b3 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -28,6 +28,7 @@
#include <linux/delay.h>
#include <linux/netdevice.h>
+#include <linux/if_vlan.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/skbuff.h>
@@ -55,9 +56,9 @@ module_param(dumb_switch, int, 0444);
MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
-#define CPMAC_VERSION "0.5.1"
-/* frame size + 802.1q tag */
-#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4)
+#define CPMAC_VERSION "0.5.2"
+/* frame size + 802.1q tag + FCS size */
+#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
#define CPMAC_QUEUES 8
/* Ethernet registers */
@@ -1136,8 +1137,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
}
if (phy_id == PHY_MAX_ADDR) {
- dev_err(&pdev->dev, "no PHY present\n");
- return -ENODEV;
+ dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n");
+ strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
+ phy_id = pdev->id;
}
dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
@@ -1290,8 +1292,8 @@ void __devexit cpmac_exit(void)
{
platform_driver_unregister(&cpmac_driver);
mdiobus_unregister(cpmac_mii);
- mdiobus_free(cpmac_mii);
iounmap(cpmac_mii->priv);
+ mdiobus_free(cpmac_mii);
}
module_init(cpmac_init);
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index dd24aadb778..61a33914e96 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -18,7 +18,6 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 14624019ce7..4c38491b8ef 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -138,12 +138,12 @@
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -580,7 +580,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
}
#ifdef CONFIG_SH_HICOSH4
- /* truely reset the chip */
+ /* truly reset the chip */
writeword(ioaddr, ADD_PORT, 0x0114);
writeword(ioaddr, DATA_PORT, 0x0040);
#endif
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 5248f9e0b2f..35cd3672915 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -934,7 +934,7 @@ static struct cphy_ops xaui_direct_ops = {
int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
int phy_addr, const struct mdio_ops *mdio_ops)
{
- cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops,
+ cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
"10GBASE-CX4");
return 0;
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 3e453e1d97e..e3f1b856649 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -46,6 +46,7 @@
#include <linux/log2.h>
#include <linux/stringify.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include "common.h"
@@ -438,7 +439,7 @@ static void free_irq_resources(struct adapter *adapter)
static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
unsigned long n)
{
- int attempts = 5;
+ int attempts = 10;
while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) {
if (!--attempts)
@@ -1294,6 +1295,7 @@ static void cxgb_down(struct adapter *adapter)
free_irq_resources(adapter);
quiesce_rx(adapter);
+ t3_sge_stop(adapter);
flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
}
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 9498361119d..c6485b39eb0 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -31,6 +31,7 @@
*/
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/neighbour.h>
#include <linux/notifier.h>
#include <asm/atomic.h>
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c
index ff1611f90e7..2f3ee721c3e 100644
--- a/drivers/net/cxgb3/l2t.c
+++ b/drivers/net/cxgb3/l2t.c
@@ -34,6 +34,7 @@
#include <linux/if.h>
#include <linux/if_vlan.h>
#include <linux/jhash.h>
+#include <linux/slab.h>
#include <net/neighbour.h>
#include "common.h"
#include "t3cdev.h"
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 78e265b484b..07d7e7fab3f 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -36,6 +36,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include "common.h"
#include "regs.h"
@@ -197,13 +198,13 @@ static inline void refill_rspq(struct adapter *adapter,
/**
* need_skb_unmap - does the platform need unmapping of sk_buffs?
*
- * Returns true if the platfrom needs sk_buff unmapping. The compiler
+ * Returns true if the platform needs sk_buff unmapping. The compiler
* optimizes away unecessary code if this returns true.
*/
static inline int need_skb_unmap(void)
{
/*
- * This structure is used to tell if the platfrom needs buffer
+ * This structure is used to tell if the platform needs buffer
* unmapping by checking if DECLARE_PCI_UNMAP_ADDR defines anything.
*/
struct dummy {
diff --git a/drivers/net/cxgb4/Makefile b/drivers/net/cxgb4/Makefile
new file mode 100644
index 00000000000..498667487f5
--- /dev/null
+++ b/drivers/net/cxgb4/Makefile
@@ -0,0 +1,7 @@
+#
+# Chelsio T4 driver
+#
+
+obj-$(CONFIG_CHELSIO_T4) += cxgb4.o
+
+cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o
diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
new file mode 100644
index 00000000000..3d8ff4889b5
--- /dev/null
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -0,0 +1,741 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CXGB4_H__
+#define __CXGB4_H__
+
+#include <linux/bitops.h>
+#include <linux/cache.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include "cxgb4_uld.h"
+#include "t4_hw.h"
+
+#define FW_VERSION_MAJOR 1
+#define FW_VERSION_MINOR 1
+#define FW_VERSION_MICRO 0
+
+enum {
+ MAX_NPORTS = 4, /* max # of ports */
+ SERNUM_LEN = 16, /* Serial # length */
+ EC_LEN = 16, /* E/C length */
+ ID_LEN = 16, /* ID length */
+};
+
+enum {
+ MEM_EDC0,
+ MEM_EDC1,
+ MEM_MC
+};
+
+enum dev_master {
+ MASTER_CANT,
+ MASTER_MAY,
+ MASTER_MUST
+};
+
+enum dev_state {
+ DEV_STATE_UNINIT,
+ DEV_STATE_INIT,
+ DEV_STATE_ERR
+};
+
+enum {
+ PAUSE_RX = 1 << 0,
+ PAUSE_TX = 1 << 1,
+ PAUSE_AUTONEG = 1 << 2
+};
+
+struct port_stats {
+ u64 tx_octets; /* total # of octets in good frames */
+ u64 tx_frames; /* all good frames */
+ u64 tx_bcast_frames; /* all broadcast frames */
+ u64 tx_mcast_frames; /* all multicast frames */
+ u64 tx_ucast_frames; /* all unicast frames */
+ u64 tx_error_frames; /* all error frames */
+
+ u64 tx_frames_64; /* # of Tx frames in a particular range */
+ u64 tx_frames_65_127;
+ u64 tx_frames_128_255;
+ u64 tx_frames_256_511;
+ u64 tx_frames_512_1023;
+ u64 tx_frames_1024_1518;
+ u64 tx_frames_1519_max;
+
+ u64 tx_drop; /* # of dropped Tx frames */
+ u64 tx_pause; /* # of transmitted pause frames */
+ u64 tx_ppp0; /* # of transmitted PPP prio 0 frames */
+ u64 tx_ppp1; /* # of transmitted PPP prio 1 frames */
+ u64 tx_ppp2; /* # of transmitted PPP prio 2 frames */
+ u64 tx_ppp3; /* # of transmitted PPP prio 3 frames */
+ u64 tx_ppp4; /* # of transmitted PPP prio 4 frames */
+ u64 tx_ppp5; /* # of transmitted PPP prio 5 frames */
+ u64 tx_ppp6; /* # of transmitted PPP prio 6 frames */
+ u64 tx_ppp7; /* # of transmitted PPP prio 7 frames */
+
+ u64 rx_octets; /* total # of octets in good frames */
+ u64 rx_frames; /* all good frames */
+ u64 rx_bcast_frames; /* all broadcast frames */
+ u64 rx_mcast_frames; /* all multicast frames */
+ u64 rx_ucast_frames; /* all unicast frames */
+ u64 rx_too_long; /* # of frames exceeding MTU */
+ u64 rx_jabber; /* # of jabber frames */
+ u64 rx_fcs_err; /* # of received frames with bad FCS */
+ u64 rx_len_err; /* # of received frames with length error */
+ u64 rx_symbol_err; /* symbol errors */
+ u64 rx_runt; /* # of short frames */
+
+ u64 rx_frames_64; /* # of Rx frames in a particular range */
+ u64 rx_frames_65_127;
+ u64 rx_frames_128_255;
+ u64 rx_frames_256_511;
+ u64 rx_frames_512_1023;
+ u64 rx_frames_1024_1518;
+ u64 rx_frames_1519_max;
+
+ u64 rx_pause; /* # of received pause frames */
+ u64 rx_ppp0; /* # of received PPP prio 0 frames */
+ u64 rx_ppp1; /* # of received PPP prio 1 frames */
+ u64 rx_ppp2; /* # of received PPP prio 2 frames */
+ u64 rx_ppp3; /* # of received PPP prio 3 frames */
+ u64 rx_ppp4; /* # of received PPP prio 4 frames */
+ u64 rx_ppp5; /* # of received PPP prio 5 frames */
+ u64 rx_ppp6; /* # of received PPP prio 6 frames */
+ u64 rx_ppp7; /* # of received PPP prio 7 frames */
+
+ u64 rx_ovflow0; /* drops due to buffer-group 0 overflows */
+ u64 rx_ovflow1; /* drops due to buffer-group 1 overflows */
+ u64 rx_ovflow2; /* drops due to buffer-group 2 overflows */
+ u64 rx_ovflow3; /* drops due to buffer-group 3 overflows */
+ u64 rx_trunc0; /* buffer-group 0 truncated packets */
+ u64 rx_trunc1; /* buffer-group 1 truncated packets */
+ u64 rx_trunc2; /* buffer-group 2 truncated packets */
+ u64 rx_trunc3; /* buffer-group 3 truncated packets */
+};
+
+struct lb_port_stats {
+ u64 octets;
+ u64 frames;
+ u64 bcast_frames;
+ u64 mcast_frames;
+ u64 ucast_frames;
+ u64 error_frames;
+
+ u64 frames_64;
+ u64 frames_65_127;
+ u64 frames_128_255;
+ u64 frames_256_511;
+ u64 frames_512_1023;
+ u64 frames_1024_1518;
+ u64 frames_1519_max;
+
+ u64 drop;
+
+ u64 ovflow0;
+ u64 ovflow1;
+ u64 ovflow2;
+ u64 ovflow3;
+ u64 trunc0;
+ u64 trunc1;
+ u64 trunc2;
+ u64 trunc3;
+};
+
+struct tp_tcp_stats {
+ u32 tcpOutRsts;
+ u64 tcpInSegs;
+ u64 tcpOutSegs;
+ u64 tcpRetransSegs;
+};
+
+struct tp_err_stats {
+ u32 macInErrs[4];
+ u32 hdrInErrs[4];
+ u32 tcpInErrs[4];
+ u32 tnlCongDrops[4];
+ u32 ofldChanDrops[4];
+ u32 tnlTxDrops[4];
+ u32 ofldVlanDrops[4];
+ u32 tcp6InErrs[4];
+ u32 ofldNoNeigh;
+ u32 ofldCongDefer;
+};
+
+struct tp_params {
+ unsigned int ntxchan; /* # of Tx channels */
+ unsigned int tre; /* log2 of core clocks per TP tick */
+};
+
+struct vpd_params {
+ unsigned int cclk;
+ u8 ec[EC_LEN + 1];
+ u8 sn[SERNUM_LEN + 1];
+ u8 id[ID_LEN + 1];
+};
+
+struct pci_params {
+ unsigned char speed;
+ unsigned char width;
+};
+
+struct adapter_params {
+ struct tp_params tp;
+ struct vpd_params vpd;
+ struct pci_params pci;
+
+ unsigned int fw_vers;
+ unsigned int tp_vers;
+ u8 api_vers[7];
+
+ unsigned short mtus[NMTUS];
+ unsigned short a_wnd[NCCTRL_WIN];
+ unsigned short b_wnd[NCCTRL_WIN];
+
+ unsigned char nports; /* # of ethernet ports */
+ unsigned char portvec;
+ unsigned char rev; /* chip revision */
+ unsigned char offload;
+
+ unsigned int ofldq_wr_cred;
+};
+
+struct trace_params {
+ u32 data[TRACE_LEN / 4];
+ u32 mask[TRACE_LEN / 4];
+ unsigned short snap_len;
+ unsigned short min_len;
+ unsigned char skip_ofst;
+ unsigned char skip_len;
+ unsigned char invert;
+ unsigned char port;
+};
+
+struct link_config {
+ unsigned short supported; /* link capabilities */
+ unsigned short advertising; /* advertised capabilities */
+ unsigned short requested_speed; /* speed user has requested */
+ unsigned short speed; /* actual link speed */
+ unsigned char requested_fc; /* flow control user has requested */
+ unsigned char fc; /* actual link flow control */
+ unsigned char autoneg; /* autonegotiating? */
+ unsigned char link_ok; /* link up? */
+};
+
+#define FW_LEN16(fw_struct) FW_CMD_LEN16(sizeof(fw_struct) / 16)
+
+enum {
+ MAX_ETH_QSETS = 32, /* # of Ethernet Tx/Rx queue sets */
+ MAX_OFLD_QSETS = 16, /* # of offload Tx/Rx queue sets */
+ MAX_CTRL_QUEUES = NCHAN, /* # of control Tx queues */
+ MAX_RDMA_QUEUES = NCHAN, /* # of streaming RDMA Rx queues */
+};
+
+enum {
+ MAX_EGRQ = 128, /* max # of egress queues, including FLs */
+ MAX_INGQ = 64 /* max # of interrupt-capable ingress queues */
+};
+
+struct adapter;
+struct vlan_group;
+struct sge_rspq;
+
+struct port_info {
+ struct adapter *adapter;
+ struct vlan_group *vlan_grp;
+ u16 viid;
+ s16 xact_addr_filt; /* index of exact MAC address filter */
+ u16 rss_size; /* size of VI's RSS table slice */
+ s8 mdio_addr;
+ u8 port_type;
+ u8 mod_type;
+ u8 port_id;
+ u8 tx_chan;
+ u8 lport; /* associated offload logical port */
+ u8 rx_offload; /* CSO, etc */
+ u8 nqsets; /* # of qsets */
+ u8 first_qset; /* index of first qset */
+ struct link_config link_cfg;
+};
+
+/* port_info.rx_offload flags */
+enum {
+ RX_CSO = 1 << 0,
+};
+
+struct dentry;
+struct work_struct;
+
+enum { /* adapter flags */
+ FULL_INIT_DONE = (1 << 0),
+ USING_MSI = (1 << 1),
+ USING_MSIX = (1 << 2),
+ QUEUES_BOUND = (1 << 3),
+ FW_OK = (1 << 4),
+};
+
+struct rx_sw_desc;
+
+struct sge_fl { /* SGE free-buffer queue state */
+ unsigned int avail; /* # of available Rx buffers */
+ unsigned int pend_cred; /* new buffers since last FL DB ring */
+ unsigned int cidx; /* consumer index */
+ unsigned int pidx; /* producer index */
+ unsigned long alloc_failed; /* # of times buffer allocation failed */
+ unsigned long large_alloc_failed;
+ unsigned long starving;
+ /* RO fields */
+ unsigned int cntxt_id; /* SGE context id for the free list */
+ unsigned int size; /* capacity of free list */
+ struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */
+ __be64 *desc; /* address of HW Rx descriptor ring */
+ dma_addr_t addr; /* bus address of HW ring start */
+};
+
+/* A packet gather list */
+struct pkt_gl {
+ skb_frag_t frags[MAX_SKB_FRAGS];
+ void *va; /* virtual address of first byte */
+ unsigned int nfrags; /* # of fragments */
+ unsigned int tot_len; /* total length of fragments */
+};
+
+typedef int (*rspq_handler_t)(struct sge_rspq *q, const __be64 *rsp,
+ const struct pkt_gl *gl);
+
+struct sge_rspq { /* state for an SGE response queue */
+ struct napi_struct napi;
+ const __be64 *cur_desc; /* current descriptor in queue */
+ unsigned int cidx; /* consumer index */
+ u8 gen; /* current generation bit */
+ u8 intr_params; /* interrupt holdoff parameters */
+ u8 next_intr_params; /* holdoff params for next interrupt */
+ u8 pktcnt_idx; /* interrupt packet threshold */
+ u8 uld; /* ULD handling this queue */
+ u8 idx; /* queue index within its group */
+ int offset; /* offset into current Rx buffer */
+ u16 cntxt_id; /* SGE context id for the response q */
+ u16 abs_id; /* absolute SGE id for the response q */
+ __be64 *desc; /* address of HW response ring */
+ dma_addr_t phys_addr; /* physical address of the ring */
+ unsigned int iqe_len; /* entry size */
+ unsigned int size; /* capacity of response queue */
+ struct adapter *adap;
+ struct net_device *netdev; /* associated net device */
+ rspq_handler_t handler;
+};
+
+struct sge_eth_stats { /* Ethernet queue statistics */
+ unsigned long pkts; /* # of ethernet packets */
+ unsigned long lro_pkts; /* # of LRO super packets */
+ unsigned long lro_merged; /* # of wire packets merged by LRO */
+ unsigned long rx_cso; /* # of Rx checksum offloads */
+ unsigned long vlan_ex; /* # of Rx VLAN extractions */
+ unsigned long rx_drops; /* # of packets dropped due to no mem */
+};
+
+struct sge_eth_rxq { /* SW Ethernet Rx queue */
+ struct sge_rspq rspq;
+ struct sge_fl fl;
+ struct sge_eth_stats stats;
+} ____cacheline_aligned_in_smp;
+
+struct sge_ofld_stats { /* offload queue statistics */
+ unsigned long pkts; /* # of packets */
+ unsigned long imm; /* # of immediate-data packets */
+ unsigned long an; /* # of asynchronous notifications */
+ unsigned long nomem; /* # of responses deferred due to no mem */
+};
+
+struct sge_ofld_rxq { /* SW offload Rx queue */
+ struct sge_rspq rspq;
+ struct sge_fl fl;
+ struct sge_ofld_stats stats;
+} ____cacheline_aligned_in_smp;
+
+struct tx_desc {
+ __be64 flit[8];
+};
+
+struct tx_sw_desc;
+
+struct sge_txq {
+ unsigned int in_use; /* # of in-use Tx descriptors */
+ unsigned int size; /* # of descriptors */
+ unsigned int cidx; /* SW consumer index */
+ unsigned int pidx; /* producer index */
+ unsigned long stops; /* # of times q has been stopped */
+ unsigned long restarts; /* # of queue restarts */
+ unsigned int cntxt_id; /* SGE context id for the Tx q */
+ struct tx_desc *desc; /* address of HW Tx descriptor ring */
+ struct tx_sw_desc *sdesc; /* address of SW Tx descriptor ring */
+ struct sge_qstat *stat; /* queue status entry */
+ dma_addr_t phys_addr; /* physical address of the ring */
+};
+
+struct sge_eth_txq { /* state for an SGE Ethernet Tx queue */
+ struct sge_txq q;
+ struct netdev_queue *txq; /* associated netdev TX queue */
+ unsigned long tso; /* # of TSO requests */
+ unsigned long tx_cso; /* # of Tx checksum offloads */
+ unsigned long vlan_ins; /* # of Tx VLAN insertions */
+ unsigned long mapping_err; /* # of I/O MMU packet mapping errors */
+} ____cacheline_aligned_in_smp;
+
+struct sge_ofld_txq { /* state for an SGE offload Tx queue */
+ struct sge_txq q;
+ struct adapter *adap;
+ struct sk_buff_head sendq; /* list of backpressured packets */
+ struct tasklet_struct qresume_tsk; /* restarts the queue */
+ u8 full; /* the Tx ring is full */
+ unsigned long mapping_err; /* # of I/O MMU packet mapping errors */
+} ____cacheline_aligned_in_smp;
+
+struct sge_ctrl_txq { /* state for an SGE control Tx queue */
+ struct sge_txq q;
+ struct adapter *adap;
+ struct sk_buff_head sendq; /* list of backpressured packets */
+ struct tasklet_struct qresume_tsk; /* restarts the queue */
+ u8 full; /* the Tx ring is full */
+} ____cacheline_aligned_in_smp;
+
+struct sge {
+ struct sge_eth_txq ethtxq[MAX_ETH_QSETS];
+ struct sge_ofld_txq ofldtxq[MAX_OFLD_QSETS];
+ struct sge_ctrl_txq ctrlq[MAX_CTRL_QUEUES];
+
+ struct sge_eth_rxq ethrxq[MAX_ETH_QSETS];
+ struct sge_ofld_rxq ofldrxq[MAX_OFLD_QSETS];
+ struct sge_ofld_rxq rdmarxq[MAX_RDMA_QUEUES];
+ struct sge_rspq fw_evtq ____cacheline_aligned_in_smp;
+
+ struct sge_rspq intrq ____cacheline_aligned_in_smp;
+ spinlock_t intrq_lock;
+
+ u16 max_ethqsets; /* # of available Ethernet queue sets */
+ u16 ethqsets; /* # of active Ethernet queue sets */
+ u16 ethtxq_rover; /* Tx queue to clean up next */
+ u16 ofldqsets; /* # of active offload queue sets */
+ u16 rdmaqs; /* # of available RDMA Rx queues */
+ u16 ofld_rxq[MAX_OFLD_QSETS];
+ u16 rdma_rxq[NCHAN];
+ u16 timer_val[SGE_NTIMERS];
+ u8 counter_val[SGE_NCOUNTERS];
+ unsigned int starve_thres;
+ u8 idma_state[2];
+ void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */
+ struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */
+ DECLARE_BITMAP(starving_fl, MAX_EGRQ);
+ DECLARE_BITMAP(txq_maperr, MAX_EGRQ);
+ struct timer_list rx_timer; /* refills starving FLs */
+ struct timer_list tx_timer; /* checks Tx queues */
+};
+
+#define for_each_ethrxq(sge, i) for (i = 0; i < (sge)->ethqsets; i++)
+#define for_each_ofldrxq(sge, i) for (i = 0; i < (sge)->ofldqsets; i++)
+#define for_each_rdmarxq(sge, i) for (i = 0; i < (sge)->rdmaqs; i++)
+
+struct l2t_data;
+
+struct adapter {
+ void __iomem *regs;
+ struct pci_dev *pdev;
+ struct device *pdev_dev;
+ unsigned long registered_device_map;
+ unsigned long open_device_map;
+ unsigned long flags;
+
+ const char *name;
+ int msg_enable;
+
+ struct adapter_params params;
+ struct cxgb4_virt_res vres;
+ unsigned int swintr;
+
+ unsigned int wol;
+
+ struct {
+ unsigned short vec;
+ char desc[14];
+ } msix_info[MAX_INGQ + 1];
+
+ struct sge sge;
+
+ struct net_device *port[MAX_NPORTS];
+ u8 chan_map[NCHAN]; /* channel -> port map */
+
+ struct l2t_data *l2t;
+ void *uld_handle[CXGB4_ULD_MAX];
+ struct list_head list_node;
+
+ struct tid_info tids;
+ void **tid_release_head;
+ spinlock_t tid_release_lock;
+ struct work_struct tid_release_task;
+ bool tid_release_task_busy;
+
+ struct dentry *debugfs_root;
+
+ spinlock_t stats_lock;
+};
+
+static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr)
+{
+ return readl(adap->regs + reg_addr);
+}
+
+static inline void t4_write_reg(struct adapter *adap, u32 reg_addr, u32 val)
+{
+ writel(val, adap->regs + reg_addr);
+}
+
+#ifndef readq
+static inline u64 readq(const volatile void __iomem *addr)
+{
+ return readl(addr) + ((u64)readl(addr + 4) << 32);
+}
+
+static inline void writeq(u64 val, volatile void __iomem *addr)
+{
+ writel(val, addr);
+ writel(val >> 32, addr + 4);
+}
+#endif
+
+static inline u64 t4_read_reg64(struct adapter *adap, u32 reg_addr)
+{
+ return readq(adap->regs + reg_addr);
+}
+
+static inline void t4_write_reg64(struct adapter *adap, u32 reg_addr, u64 val)
+{
+ writeq(val, adap->regs + reg_addr);
+}
+
+/**
+ * netdev2pinfo - return the port_info structure associated with a net_device
+ * @dev: the netdev
+ *
+ * Return the struct port_info associated with a net_device
+ */
+static inline struct port_info *netdev2pinfo(const struct net_device *dev)
+{
+ return netdev_priv(dev);
+}
+
+/**
+ * adap2pinfo - return the port_info of a port
+ * @adap: the adapter
+ * @idx: the port index
+ *
+ * Return the port_info structure for the port of the given index.
+ */
+static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
+{
+ return netdev_priv(adap->port[idx]);
+}
+
+/**
+ * netdev2adap - return the adapter structure associated with a net_device
+ * @dev: the netdev
+ *
+ * Return the struct adapter associated with a net_device
+ */
+static inline struct adapter *netdev2adap(const struct net_device *dev)
+{
+ return netdev2pinfo(dev)->adapter;
+}
+
+void t4_os_portmod_changed(const struct adapter *adap, int port_id);
+void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat);
+
+void *t4_alloc_mem(size_t size);
+void t4_free_mem(void *addr);
+
+void t4_free_sge_resources(struct adapter *adap);
+irq_handler_t t4_intr_handler(struct adapter *adap);
+netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev);
+int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
+ const struct pkt_gl *gl);
+int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb);
+int t4_ofld_send(struct adapter *adap, struct sk_buff *skb);
+int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
+ struct net_device *dev, int intr_idx,
+ struct sge_fl *fl, rspq_handler_t hnd);
+int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
+ struct net_device *dev, struct netdev_queue *netdevq,
+ unsigned int iqid);
+int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
+ struct net_device *dev, unsigned int iqid,
+ unsigned int cmplqid);
+int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
+ struct net_device *dev, unsigned int iqid);
+irqreturn_t t4_sge_intr_msix(int irq, void *cookie);
+void t4_sge_init(struct adapter *adap);
+void t4_sge_start(struct adapter *adap);
+void t4_sge_stop(struct adapter *adap);
+
+#define for_each_port(adapter, iter) \
+ for (iter = 0; iter < (adapter)->params.nports; ++iter)
+
+static inline unsigned int core_ticks_per_usec(const struct adapter *adap)
+{
+ return adap->params.vpd.cclk / 1000;
+}
+
+static inline unsigned int us_to_core_ticks(const struct adapter *adap,
+ unsigned int us)
+{
+ return (us * adap->params.vpd.cclk) / 1000;
+}
+
+void t4_set_reg_field(struct adapter *adap, unsigned int addr, u32 mask,
+ u32 val);
+
+int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
+ void *rpl, bool sleep_ok);
+
+static inline int t4_wr_mbox(struct adapter *adap, int mbox, const void *cmd,
+ int size, void *rpl)
+{
+ return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, true);
+}
+
+static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd,
+ int size, void *rpl)
+{
+ return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, false);
+}
+
+void t4_intr_enable(struct adapter *adapter);
+void t4_intr_disable(struct adapter *adapter);
+void t4_intr_clear(struct adapter *adapter);
+int t4_slow_intr_handler(struct adapter *adapter);
+
+int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
+ struct link_config *lc);
+int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port);
+int t4_seeprom_wp(struct adapter *adapter, bool enable);
+int t4_read_flash(struct adapter *adapter, unsigned int addr,
+ unsigned int nwords, u32 *data, int byte_oriented);
+int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
+int t4_check_fw_version(struct adapter *adapter);
+int t4_prep_adapter(struct adapter *adapter);
+int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
+void t4_fatal_err(struct adapter *adapter);
+void t4_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on);
+int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp,
+ int filter_index, int enable);
+void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp,
+ int filter_index, int *enabled);
+int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
+ int start, int n, const u16 *rspq, unsigned int nrspq);
+int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
+ unsigned int flags);
+int t4_read_rss(struct adapter *adapter, u16 *entries);
+int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity);
+int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
+ u64 *parity);
+
+void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p);
+void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p);
+
+void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log);
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st);
+void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
+ struct tp_tcp_stats *v6);
+void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
+ const unsigned short *alpha, const unsigned short *beta);
+
+void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
+ const u8 *addr);
+int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
+ u64 mask0, u64 mask1, unsigned int crc, bool enable);
+
+int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
+ enum dev_master master, enum dev_state *state);
+int t4_fw_bye(struct adapter *adap, unsigned int mbox);
+int t4_early_init(struct adapter *adap, unsigned int mbox);
+int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset);
+int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int nparams, const u32 *params,
+ u32 *val);
+int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int nparams, const u32 *params,
+ const u32 *val);
+int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
+ unsigned int rxqi, unsigned int rxq, unsigned int tc,
+ unsigned int vi, unsigned int cmask, unsigned int pmask,
+ unsigned int nexact, unsigned int rcaps, unsigned int wxcaps);
+int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
+ unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
+ unsigned int *rss_size);
+int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int viid);
+int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ int mtu, int promisc, int all_multi, int bcast, bool sleep_ok);
+int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
+ unsigned int viid, bool free, unsigned int naddr,
+ const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok);
+int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ int idx, const u8 *addr, bool persist, bool add_smt);
+int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ bool ucast, u64 vec, bool sleep_ok);
+int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ bool rx_en, bool tx_en);
+int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ unsigned int nblinks);
+int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+ unsigned int mmd, unsigned int reg, u16 *valp);
+int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+ unsigned int mmd, unsigned int reg, u16 val);
+int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
+ unsigned int pf, unsigned int vf, unsigned int iqid,
+ unsigned int fl0id, unsigned int fl1id);
+int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int iqtype, unsigned int iqid,
+ unsigned int fl0id, unsigned int fl1id);
+int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int eqid);
+int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int eqid);
+int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int eqid);
+int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
+#endif /* __CXGB4_H__ */
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
new file mode 100644
index 00000000000..a7e30a23d32
--- /dev/null
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -0,0 +1,3388 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitmap.h>
+#include <linux/crc32.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/etherdevice.h>
+#include <linux/firmware.h>
+#include <linux/if_vlan.h>
+#include <linux/init.h>
+#include <linux/log2.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <linux/rtnetlink.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/sockios.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include <net/neighbour.h>
+#include <net/netevent.h>
+#include <asm/uaccess.h>
+
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+#include "l2t.h"
+
+#define DRV_VERSION "1.0.0-ko"
+#define DRV_DESC "Chelsio T4 Network Driver"
+
+/*
+ * Max interrupt hold-off timer value in us. Queues fall back to this value
+ * under extreme memory pressure so it's largish to give the system time to
+ * recover.
+ */
+#define MAX_SGE_TIMERVAL 200U
+
+enum {
+ MEMWIN0_APERTURE = 65536,
+ MEMWIN0_BASE = 0x30000,
+ MEMWIN1_APERTURE = 32768,
+ MEMWIN1_BASE = 0x28000,
+ MEMWIN2_APERTURE = 2048,
+ MEMWIN2_BASE = 0x1b800,
+};
+
+enum {
+ MAX_TXQ_ENTRIES = 16384,
+ MAX_CTRL_TXQ_ENTRIES = 1024,
+ MAX_RSPQ_ENTRIES = 16384,
+ MAX_RX_BUFFERS = 16384,
+ MIN_TXQ_ENTRIES = 32,
+ MIN_CTRL_TXQ_ENTRIES = 32,
+ MIN_RSPQ_ENTRIES = 128,
+ MIN_FL_ENTRIES = 16
+};
+
+#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \
+ NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\
+ NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
+
+#define CH_DEVICE(devid) { PCI_VDEVICE(CHELSIO, devid), 0 }
+
+static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
+ CH_DEVICE(0xa000), /* PE10K */
+ { 0, }
+};
+
+#define FW_FNAME "cxgb4/t4fw.bin"
+
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_AUTHOR("Chelsio Communications");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl);
+MODULE_FIRMWARE(FW_FNAME);
+
+static int dflt_msg_enable = DFLT_MSG_ENABLE;
+
+module_param(dflt_msg_enable, int, 0644);
+MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap");
+
+/*
+ * The driver uses the best interrupt scheme available on a platform in the
+ * order MSI-X, MSI, legacy INTx interrupts. This parameter determines which
+ * of these schemes the driver may consider as follows:
+ *
+ * msi = 2: choose from among all three options
+ * msi = 1: only consider MSI and INTx interrupts
+ * msi = 0: force INTx interrupts
+ */
+static int msi = 2;
+
+module_param(msi, int, 0644);
+MODULE_PARM_DESC(msi, "whether to use INTx (0), MSI (1) or MSI-X (2)");
+
+/*
+ * Queue interrupt hold-off timer values. Queues default to the first of these
+ * upon creation.
+ */
+static unsigned int intr_holdoff[SGE_NTIMERS - 1] = { 5, 10, 20, 50, 100 };
+
+module_param_array(intr_holdoff, uint, NULL, 0644);
+MODULE_PARM_DESC(intr_holdoff, "values for queue interrupt hold-off timers "
+ "0..4 in microseconds");
+
+static unsigned int intr_cnt[SGE_NCOUNTERS - 1] = { 4, 8, 16 };
+
+module_param_array(intr_cnt, uint, NULL, 0644);
+MODULE_PARM_DESC(intr_cnt,
+ "thresholds 1..3 for queue interrupt packet counters");
+
+static int vf_acls;
+
+#ifdef CONFIG_PCI_IOV
+module_param(vf_acls, bool, 0644);
+MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement");
+
+static unsigned int num_vf[4];
+
+module_param_array(num_vf, uint, NULL, 0644);
+MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3");
+#endif
+
+static struct dentry *cxgb4_debugfs_root;
+
+static LIST_HEAD(adapter_list);
+static DEFINE_MUTEX(uld_mutex);
+static struct cxgb4_uld_info ulds[CXGB4_ULD_MAX];
+static const char *uld_str[] = { "RDMA", "iSCSI" };
+
+static void link_report(struct net_device *dev)
+{
+ if (!netif_carrier_ok(dev))
+ netdev_info(dev, "link down\n");
+ else {
+ static const char *fc[] = { "no", "Rx", "Tx", "Tx/Rx" };
+
+ const char *s = "10Mbps";
+ const struct port_info *p = netdev_priv(dev);
+
+ switch (p->link_cfg.speed) {
+ case SPEED_10000:
+ s = "10Gbps";
+ break;
+ case SPEED_1000:
+ s = "1000Mbps";
+ break;
+ case SPEED_100:
+ s = "100Mbps";
+ break;
+ }
+
+ netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s,
+ fc[p->link_cfg.fc]);
+ }
+}
+
+void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
+{
+ struct net_device *dev = adapter->port[port_id];
+
+ /* Skip changes from disabled ports. */
+ if (netif_running(dev) && link_stat != netif_carrier_ok(dev)) {
+ if (link_stat)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
+
+ link_report(dev);
+ }
+}
+
+void t4_os_portmod_changed(const struct adapter *adap, int port_id)
+{
+ static const char *mod_str[] = {
+ NULL, "LR", "SR", "ER", "passive DA", "active DA"
+ };
+
+ const struct net_device *dev = adap->port[port_id];
+ const struct port_info *pi = netdev_priv(dev);
+
+ if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
+ netdev_info(dev, "port module unplugged\n");
+ else
+ netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]);
+}
+
+/*
+ * Configure the exact and hash address filters to handle a port's multicast
+ * and secondary unicast MAC addresses.
+ */
+static int set_addr_filters(const struct net_device *dev, bool sleep)
+{
+ u64 mhash = 0;
+ u64 uhash = 0;
+ bool free = true;
+ u16 filt_idx[7];
+ const u8 *addr[7];
+ int ret, naddr = 0;
+ const struct dev_addr_list *d;
+ const struct netdev_hw_addr *ha;
+ int uc_cnt = netdev_uc_count(dev);
+ const struct port_info *pi = netdev_priv(dev);
+
+ /* first do the secondary unicast addresses */
+ netdev_for_each_uc_addr(ha, dev) {
+ addr[naddr++] = ha->addr;
+ if (--uc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) {
+ ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free,
+ naddr, addr, filt_idx, &uhash, sleep);
+ if (ret < 0)
+ return ret;
+
+ free = false;
+ naddr = 0;
+ }
+ }
+
+ /* next set up the multicast addresses */
+ netdev_for_each_mc_addr(d, dev) {
+ addr[naddr++] = d->dmi_addr;
+ if (naddr >= ARRAY_SIZE(addr) || d->next == NULL) {
+ ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free,
+ naddr, addr, filt_idx, &mhash, sleep);
+ if (ret < 0)
+ return ret;
+
+ free = false;
+ naddr = 0;
+ }
+ }
+
+ return t4_set_addr_hash(pi->adapter, 0, pi->viid, uhash != 0,
+ uhash | mhash, sleep);
+}
+
+/*
+ * Set Rx properties of a port, such as promiscruity, address filters, and MTU.
+ * If @mtu is -1 it is left unchanged.
+ */
+static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok)
+{
+ int ret;
+ struct port_info *pi = netdev_priv(dev);
+
+ ret = set_addr_filters(dev, sleep_ok);
+ if (ret == 0)
+ ret = t4_set_rxmode(pi->adapter, 0, pi->viid, mtu,
+ (dev->flags & IFF_PROMISC) ? 1 : 0,
+ (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1,
+ sleep_ok);
+ return ret;
+}
+
+/**
+ * link_start - enable a port
+ * @dev: the port to enable
+ *
+ * Performs the MAC and PHY actions needed to enable a port.
+ */
+static int link_start(struct net_device *dev)
+{
+ int ret;
+ struct port_info *pi = netdev_priv(dev);
+
+ /*
+ * We do not set address filters and promiscuity here, the stack does
+ * that step explicitly.
+ */
+ ret = t4_set_rxmode(pi->adapter, 0, pi->viid, dev->mtu, -1, -1, -1,
+ true);
+ if (ret == 0) {
+ ret = t4_change_mac(pi->adapter, 0, pi->viid,
+ pi->xact_addr_filt, dev->dev_addr, true,
+ false);
+ if (ret >= 0) {
+ pi->xact_addr_filt = ret;
+ ret = 0;
+ }
+ }
+ if (ret == 0)
+ ret = t4_link_start(pi->adapter, 0, pi->tx_chan, &pi->link_cfg);
+ if (ret == 0)
+ ret = t4_enable_vi(pi->adapter, 0, pi->viid, true, true);
+ return ret;
+}
+
+/*
+ * Response queue handler for the FW event queue.
+ */
+static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
+ const struct pkt_gl *gl)
+{
+ u8 opcode = ((const struct rss_header *)rsp)->opcode;
+
+ rsp++; /* skip RSS header */
+ if (likely(opcode == CPL_SGE_EGR_UPDATE)) {
+ const struct cpl_sge_egr_update *p = (void *)rsp;
+ unsigned int qid = EGR_QID(ntohl(p->opcode_qid));
+ struct sge_txq *txq = q->adap->sge.egr_map[qid];
+
+ txq->restarts++;
+ if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) {
+ struct sge_eth_txq *eq;
+
+ eq = container_of(txq, struct sge_eth_txq, q);
+ netif_tx_wake_queue(eq->txq);
+ } else {
+ struct sge_ofld_txq *oq;
+
+ oq = container_of(txq, struct sge_ofld_txq, q);
+ tasklet_schedule(&oq->qresume_tsk);
+ }
+ } else if (opcode == CPL_FW6_MSG || opcode == CPL_FW4_MSG) {
+ const struct cpl_fw6_msg *p = (void *)rsp;
+
+ if (p->type == 0)
+ t4_handle_fw_rpl(q->adap, p->data);
+ } else if (opcode == CPL_L2T_WRITE_RPL) {
+ const struct cpl_l2t_write_rpl *p = (void *)rsp;
+
+ do_l2t_write_rpl(q->adap, p);
+ } else
+ dev_err(q->adap->pdev_dev,
+ "unexpected CPL %#x on FW event queue\n", opcode);
+ return 0;
+}
+
+/**
+ * uldrx_handler - response queue handler for ULD queues
+ * @q: the response queue that received the packet
+ * @rsp: the response queue descriptor holding the offload message
+ * @gl: the gather list of packet fragments
+ *
+ * Deliver an ingress offload packet to a ULD. All processing is done by
+ * the ULD, we just maintain statistics.
+ */
+static int uldrx_handler(struct sge_rspq *q, const __be64 *rsp,
+ const struct pkt_gl *gl)
+{
+ struct sge_ofld_rxq *rxq = container_of(q, struct sge_ofld_rxq, rspq);
+
+ if (ulds[q->uld].rx_handler(q->adap->uld_handle[q->uld], rsp, gl)) {
+ rxq->stats.nomem++;
+ return -1;
+ }
+ if (gl == NULL)
+ rxq->stats.imm++;
+ else if (gl == CXGB4_MSG_AN)
+ rxq->stats.an++;
+ else
+ rxq->stats.pkts++;
+ return 0;
+}
+
+static void disable_msi(struct adapter *adapter)
+{
+ if (adapter->flags & USING_MSIX) {
+ pci_disable_msix(adapter->pdev);
+ adapter->flags &= ~USING_MSIX;
+ } else if (adapter->flags & USING_MSI) {
+ pci_disable_msi(adapter->pdev);
+ adapter->flags &= ~USING_MSI;
+ }
+}
+
+/*
+ * Interrupt handler for non-data events used with MSI-X.
+ */
+static irqreturn_t t4_nondata_intr(int irq, void *cookie)
+{
+ struct adapter *adap = cookie;
+
+ u32 v = t4_read_reg(adap, MYPF_REG(PL_PF_INT_CAUSE));
+ if (v & PFSW) {
+ adap->swintr = 1;
+ t4_write_reg(adap, MYPF_REG(PL_PF_INT_CAUSE), v);
+ }
+ t4_slow_intr_handler(adap);
+ return IRQ_HANDLED;
+}
+
+/*
+ * Name the MSI-X interrupts.
+ */
+static void name_msix_vecs(struct adapter *adap)
+{
+ int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc) - 1;
+
+ /* non-data interrupts */
+ snprintf(adap->msix_info[0].desc, n, "%s", adap->name);
+ adap->msix_info[0].desc[n] = 0;
+
+ /* FW events */
+ snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", adap->name);
+ adap->msix_info[1].desc[n] = 0;
+
+ /* Ethernet queues */
+ for_each_port(adap, j) {
+ struct net_device *d = adap->port[j];
+ const struct port_info *pi = netdev_priv(d);
+
+ for (i = 0; i < pi->nqsets; i++, msi_idx++) {
+ snprintf(adap->msix_info[msi_idx].desc, n, "%s-Rx%d",
+ d->name, i);
+ adap->msix_info[msi_idx].desc[n] = 0;
+ }
+ }
+
+ /* offload queues */
+ for_each_ofldrxq(&adap->sge, i) {
+ snprintf(adap->msix_info[msi_idx].desc, n, "%s-ofld%d",
+ adap->name, i);
+ adap->msix_info[msi_idx++].desc[n] = 0;
+ }
+ for_each_rdmarxq(&adap->sge, i) {
+ snprintf(adap->msix_info[msi_idx].desc, n, "%s-rdma%d",
+ adap->name, i);
+ adap->msix_info[msi_idx++].desc[n] = 0;
+ }
+}
+
+static int request_msix_queue_irqs(struct adapter *adap)
+{
+ struct sge *s = &adap->sge;
+ int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi = 2;
+
+ err = request_irq(adap->msix_info[1].vec, t4_sge_intr_msix, 0,
+ adap->msix_info[1].desc, &s->fw_evtq);
+ if (err)
+ return err;
+
+ for_each_ethrxq(s, ethqidx) {
+ err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+ adap->msix_info[msi].desc,
+ &s->ethrxq[ethqidx].rspq);
+ if (err)
+ goto unwind;
+ msi++;
+ }
+ for_each_ofldrxq(s, ofldqidx) {
+ err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+ adap->msix_info[msi].desc,
+ &s->ofldrxq[ofldqidx].rspq);
+ if (err)
+ goto unwind;
+ msi++;
+ }
+ for_each_rdmarxq(s, rdmaqidx) {
+ err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+ adap->msix_info[msi].desc,
+ &s->rdmarxq[rdmaqidx].rspq);
+ if (err)
+ goto unwind;
+ msi++;
+ }
+ return 0;
+
+unwind:
+ while (--rdmaqidx >= 0)
+ free_irq(adap->msix_info[--msi].vec,
+ &s->rdmarxq[rdmaqidx].rspq);
+ while (--ofldqidx >= 0)
+ free_irq(adap->msix_info[--msi].vec,
+ &s->ofldrxq[ofldqidx].rspq);
+ while (--ethqidx >= 0)
+ free_irq(adap->msix_info[--msi].vec, &s->ethrxq[ethqidx].rspq);
+ free_irq(adap->msix_info[1].vec, &s->fw_evtq);
+ return err;
+}
+
+static void free_msix_queue_irqs(struct adapter *adap)
+{
+ int i, msi = 2;
+ struct sge *s = &adap->sge;
+
+ free_irq(adap->msix_info[1].vec, &s->fw_evtq);
+ for_each_ethrxq(s, i)
+ free_irq(adap->msix_info[msi++].vec, &s->ethrxq[i].rspq);
+ for_each_ofldrxq(s, i)
+ free_irq(adap->msix_info[msi++].vec, &s->ofldrxq[i].rspq);
+ for_each_rdmarxq(s, i)
+ free_irq(adap->msix_info[msi++].vec, &s->rdmarxq[i].rspq);
+}
+
+/**
+ * setup_rss - configure RSS
+ * @adap: the adapter
+ *
+ * Sets up RSS to distribute packets to multiple receive queues. We
+ * configure the RSS CPU lookup table to distribute to the number of HW
+ * receive queues, and the response queue lookup table to narrow that
+ * down to the response queues actually configured for each port.
+ * We always configure the RSS mapping for all ports since the mapping
+ * table has plenty of entries.
+ */
+static int setup_rss(struct adapter *adap)
+{
+ int i, j, err;
+ u16 rss[MAX_ETH_QSETS];
+
+ for_each_port(adap, i) {
+ const struct port_info *pi = adap2pinfo(adap, i);
+ const struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset];
+
+ for (j = 0; j < pi->nqsets; j++)
+ rss[j] = q[j].rspq.abs_id;
+
+ err = t4_config_rss_range(adap, 0, pi->viid, 0, pi->rss_size,
+ rss, pi->nqsets);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+/*
+ * Wait until all NAPI handlers are descheduled.
+ */
+static void quiesce_rx(struct adapter *adap)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) {
+ struct sge_rspq *q = adap->sge.ingr_map[i];
+
+ if (q && q->handler)
+ napi_disable(&q->napi);
+ }
+}
+
+/*
+ * Enable NAPI scheduling and interrupt generation for all Rx queues.
+ */
+static void enable_rx(struct adapter *adap)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) {
+ struct sge_rspq *q = adap->sge.ingr_map[i];
+
+ if (!q)
+ continue;
+ if (q->handler)
+ napi_enable(&q->napi);
+ /* 0-increment GTS to start the timer and enable interrupts */
+ t4_write_reg(adap, MYPF_REG(SGE_PF_GTS),
+ SEINTARM(q->intr_params) |
+ INGRESSQID(q->cntxt_id));
+ }
+}
+
+/**
+ * setup_sge_queues - configure SGE Tx/Rx/response queues
+ * @adap: the adapter
+ *
+ * Determines how many sets of SGE queues to use and initializes them.
+ * We support multiple queue sets per port if we have MSI-X, otherwise
+ * just one queue set per port.
+ */
+static int setup_sge_queues(struct adapter *adap)
+{
+ int err, msi_idx, i, j;
+ struct sge *s = &adap->sge;
+
+ bitmap_zero(s->starving_fl, MAX_EGRQ);
+ bitmap_zero(s->txq_maperr, MAX_EGRQ);
+
+ if (adap->flags & USING_MSIX)
+ msi_idx = 1; /* vector 0 is for non-queue interrupts */
+ else {
+ err = t4_sge_alloc_rxq(adap, &s->intrq, false, adap->port[0], 0,
+ NULL, NULL);
+ if (err)
+ return err;
+ msi_idx = -((int)s->intrq.abs_id + 1);
+ }
+
+ err = t4_sge_alloc_rxq(adap, &s->fw_evtq, true, adap->port[0],
+ msi_idx, NULL, fwevtq_handler);
+ if (err) {
+freeout: t4_free_sge_resources(adap);
+ return err;
+ }
+
+ for_each_port(adap, i) {
+ struct net_device *dev = adap->port[i];
+ struct port_info *pi = netdev_priv(dev);
+ struct sge_eth_rxq *q = &s->ethrxq[pi->first_qset];
+ struct sge_eth_txq *t = &s->ethtxq[pi->first_qset];
+
+ for (j = 0; j < pi->nqsets; j++, q++) {
+ if (msi_idx > 0)
+ msi_idx++;
+ err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev,
+ msi_idx, &q->fl,
+ t4_ethrx_handler);
+ if (err)
+ goto freeout;
+ q->rspq.idx = j;
+ memset(&q->stats, 0, sizeof(q->stats));
+ }
+ for (j = 0; j < pi->nqsets; j++, t++) {
+ err = t4_sge_alloc_eth_txq(adap, t, dev,
+ netdev_get_tx_queue(dev, j),
+ s->fw_evtq.cntxt_id);
+ if (err)
+ goto freeout;
+ }
+ }
+
+ j = s->ofldqsets / adap->params.nports; /* ofld queues per channel */
+ for_each_ofldrxq(s, i) {
+ struct sge_ofld_rxq *q = &s->ofldrxq[i];
+ struct net_device *dev = adap->port[i / j];
+
+ if (msi_idx > 0)
+ msi_idx++;
+ err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev, msi_idx,
+ &q->fl, uldrx_handler);
+ if (err)
+ goto freeout;
+ memset(&q->stats, 0, sizeof(q->stats));
+ s->ofld_rxq[i] = q->rspq.abs_id;
+ err = t4_sge_alloc_ofld_txq(adap, &s->ofldtxq[i], dev,
+ s->fw_evtq.cntxt_id);
+ if (err)
+ goto freeout;
+ }
+
+ for_each_rdmarxq(s, i) {
+ struct sge_ofld_rxq *q = &s->rdmarxq[i];
+
+ if (msi_idx > 0)
+ msi_idx++;
+ err = t4_sge_alloc_rxq(adap, &q->rspq, false, adap->port[i],
+ msi_idx, &q->fl, uldrx_handler);
+ if (err)
+ goto freeout;
+ memset(&q->stats, 0, sizeof(q->stats));
+ s->rdma_rxq[i] = q->rspq.abs_id;
+ }
+
+ for_each_port(adap, i) {
+ /*
+ * Note that ->rdmarxq[i].rspq.cntxt_id below is 0 if we don't
+ * have RDMA queues, and that's the right value.
+ */
+ err = t4_sge_alloc_ctrl_txq(adap, &s->ctrlq[i], adap->port[i],
+ s->fw_evtq.cntxt_id,
+ s->rdmarxq[i].rspq.cntxt_id);
+ if (err)
+ goto freeout;
+ }
+
+ t4_write_reg(adap, MPS_TRC_RSS_CONTROL,
+ RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) |
+ QUEUENUMBER(s->ethrxq[0].rspq.abs_id));
+ return 0;
+}
+
+/*
+ * Returns 0 if new FW was successfully loaded, a positive errno if a load was
+ * started but failed, and a negative errno if flash load couldn't start.
+ */
+static int upgrade_fw(struct adapter *adap)
+{
+ int ret;
+ u32 vers;
+ const struct fw_hdr *hdr;
+ const struct firmware *fw;
+ struct device *dev = adap->pdev_dev;
+
+ ret = request_firmware(&fw, FW_FNAME, dev);
+ if (ret < 0) {
+ dev_err(dev, "unable to load firmware image " FW_FNAME
+ ", error %d\n", ret);
+ return ret;
+ }
+
+ hdr = (const struct fw_hdr *)fw->data;
+ vers = ntohl(hdr->fw_ver);
+ if (FW_HDR_FW_VER_MAJOR_GET(vers) != FW_VERSION_MAJOR) {
+ ret = -EINVAL; /* wrong major version, won't do */
+ goto out;
+ }
+
+ /*
+ * If the flash FW is unusable or we found something newer, load it.
+ */
+ if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != FW_VERSION_MAJOR ||
+ vers > adap->params.fw_vers) {
+ ret = -t4_load_fw(adap, fw->data, fw->size);
+ if (!ret)
+ dev_info(dev, "firmware upgraded to version %pI4 from "
+ FW_FNAME "\n", &hdr->fw_ver);
+ }
+out: release_firmware(fw);
+ return ret;
+}
+
+/*
+ * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc.
+ * The allocated memory is cleared.
+ */
+void *t4_alloc_mem(size_t size)
+{
+ void *p = kmalloc(size, GFP_KERNEL);
+
+ if (!p)
+ p = vmalloc(size);
+ if (p)
+ memset(p, 0, size);
+ return p;
+}
+
+/*
+ * Free memory allocated through alloc_mem().
+ */
+void t4_free_mem(void *addr)
+{
+ if (is_vmalloc_addr(addr))
+ vfree(addr);
+ else
+ kfree(addr);
+}
+
+static inline int is_offload(const struct adapter *adap)
+{
+ return adap->params.offload;
+}
+
+/*
+ * Implementation of ethtool operations.
+ */
+
+static u32 get_msglevel(struct net_device *dev)
+{
+ return netdev2adap(dev)->msg_enable;
+}
+
+static void set_msglevel(struct net_device *dev, u32 val)
+{
+ netdev2adap(dev)->msg_enable = val;
+}
+
+static char stats_strings[][ETH_GSTRING_LEN] = {
+ "TxOctetsOK ",
+ "TxFramesOK ",
+ "TxBroadcastFrames ",
+ "TxMulticastFrames ",
+ "TxUnicastFrames ",
+ "TxErrorFrames ",
+
+ "TxFrames64 ",
+ "TxFrames65To127 ",
+ "TxFrames128To255 ",
+ "TxFrames256To511 ",
+ "TxFrames512To1023 ",
+ "TxFrames1024To1518 ",
+ "TxFrames1519ToMax ",
+
+ "TxFramesDropped ",
+ "TxPauseFrames ",
+ "TxPPP0Frames ",
+ "TxPPP1Frames ",
+ "TxPPP2Frames ",
+ "TxPPP3Frames ",
+ "TxPPP4Frames ",
+ "TxPPP5Frames ",
+ "TxPPP6Frames ",
+ "TxPPP7Frames ",
+
+ "RxOctetsOK ",
+ "RxFramesOK ",
+ "RxBroadcastFrames ",
+ "RxMulticastFrames ",
+ "RxUnicastFrames ",
+
+ "RxFramesTooLong ",
+ "RxJabberErrors ",
+ "RxFCSErrors ",
+ "RxLengthErrors ",
+ "RxSymbolErrors ",
+ "RxRuntFrames ",
+
+ "RxFrames64 ",
+ "RxFrames65To127 ",
+ "RxFrames128To255 ",
+ "RxFrames256To511 ",
+ "RxFrames512To1023 ",
+ "RxFrames1024To1518 ",
+ "RxFrames1519ToMax ",
+
+ "RxPauseFrames ",
+ "RxPPP0Frames ",
+ "RxPPP1Frames ",
+ "RxPPP2Frames ",
+ "RxPPP3Frames ",
+ "RxPPP4Frames ",
+ "RxPPP5Frames ",
+ "RxPPP6Frames ",
+ "RxPPP7Frames ",
+
+ "RxBG0FramesDropped ",
+ "RxBG1FramesDropped ",
+ "RxBG2FramesDropped ",
+ "RxBG3FramesDropped ",
+ "RxBG0FramesTrunc ",
+ "RxBG1FramesTrunc ",
+ "RxBG2FramesTrunc ",
+ "RxBG3FramesTrunc ",
+
+ "TSO ",
+ "TxCsumOffload ",
+ "RxCsumGood ",
+ "VLANextractions ",
+ "VLANinsertions ",
+};
+
+static int get_sset_count(struct net_device *dev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return ARRAY_SIZE(stats_strings);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+#define T4_REGMAP_SIZE (160 * 1024)
+
+static int get_regs_len(struct net_device *dev)
+{
+ return T4_REGMAP_SIZE;
+}
+
+static int get_eeprom_len(struct net_device *dev)
+{
+ return EEPROMSIZE;
+}
+
+static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+ struct adapter *adapter = netdev2adap(dev);
+
+ strcpy(info->driver, KBUILD_MODNAME);
+ strcpy(info->version, DRV_VERSION);
+ strcpy(info->bus_info, pci_name(adapter->pdev));
+
+ if (!adapter->params.fw_vers)
+ strcpy(info->fw_version, "N/A");
+ else
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%u.%u.%u.%u, TP %u.%u.%u.%u",
+ FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers),
+ FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers),
+ FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers),
+ FW_HDR_FW_VER_BUILD_GET(adapter->params.fw_vers),
+ FW_HDR_FW_VER_MAJOR_GET(adapter->params.tp_vers),
+ FW_HDR_FW_VER_MINOR_GET(adapter->params.tp_vers),
+ FW_HDR_FW_VER_MICRO_GET(adapter->params.tp_vers),
+ FW_HDR_FW_VER_BUILD_GET(adapter->params.tp_vers));
+}
+
+static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+ if (stringset == ETH_SS_STATS)
+ memcpy(data, stats_strings, sizeof(stats_strings));
+}
+
+/*
+ * port stats maintained per queue of the port. They should be in the same
+ * order as in stats_strings above.
+ */
+struct queue_port_stats {
+ u64 tso;
+ u64 tx_csum;
+ u64 rx_csum;
+ u64 vlan_ex;
+ u64 vlan_ins;
+};
+
+static void collect_sge_port_stats(const struct adapter *adap,
+ const struct port_info *p, struct queue_port_stats *s)
+{
+ int i;
+ const struct sge_eth_txq *tx = &adap->sge.ethtxq[p->first_qset];
+ const struct sge_eth_rxq *rx = &adap->sge.ethrxq[p->first_qset];
+
+ memset(s, 0, sizeof(*s));
+ for (i = 0; i < p->nqsets; i++, rx++, tx++) {
+ s->tso += tx->tso;
+ s->tx_csum += tx->tx_cso;
+ s->rx_csum += rx->stats.rx_cso;
+ s->vlan_ex += rx->stats.vlan_ex;
+ s->vlan_ins += tx->vlan_ins;
+ }
+}
+
+static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
+ u64 *data)
+{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
+
+ t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data);
+
+ data += sizeof(struct port_stats) / sizeof(u64);
+ collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data);
+}
+
+/*
+ * Return a version number to identify the type of adapter. The scheme is:
+ * - bits 0..9: chip version
+ * - bits 10..15: chip revision
+ */
+static inline unsigned int mk_adap_vers(const struct adapter *ap)
+{
+ return 4 | (ap->params.rev << 10);
+}
+
+static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start,
+ unsigned int end)
+{
+ u32 *p = buf + start;
+
+ for ( ; start <= end; start += sizeof(u32))
+ *p++ = t4_read_reg(ap, start);
+}
+
+static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *buf)
+{
+ static const unsigned int reg_ranges[] = {
+ 0x1008, 0x1108,
+ 0x1180, 0x11b4,
+ 0x11fc, 0x123c,
+ 0x1300, 0x173c,
+ 0x1800, 0x18fc,
+ 0x3000, 0x30d8,
+ 0x30e0, 0x5924,
+ 0x5960, 0x59d4,
+ 0x5a00, 0x5af8,
+ 0x6000, 0x6098,
+ 0x6100, 0x6150,
+ 0x6200, 0x6208,
+ 0x6240, 0x6248,
+ 0x6280, 0x6338,
+ 0x6370, 0x638c,
+ 0x6400, 0x643c,
+ 0x6500, 0x6524,
+ 0x6a00, 0x6a38,
+ 0x6a60, 0x6a78,
+ 0x6b00, 0x6b84,
+ 0x6bf0, 0x6c84,
+ 0x6cf0, 0x6d84,
+ 0x6df0, 0x6e84,
+ 0x6ef0, 0x6f84,
+ 0x6ff0, 0x7084,
+ 0x70f0, 0x7184,
+ 0x71f0, 0x7284,
+ 0x72f0, 0x7384,
+ 0x73f0, 0x7450,
+ 0x7500, 0x7530,
+ 0x7600, 0x761c,
+ 0x7680, 0x76cc,
+ 0x7700, 0x7798,
+ 0x77c0, 0x77fc,
+ 0x7900, 0x79fc,
+ 0x7b00, 0x7c38,
+ 0x7d00, 0x7efc,
+ 0x8dc0, 0x8e1c,
+ 0x8e30, 0x8e78,
+ 0x8ea0, 0x8f6c,
+ 0x8fc0, 0x9074,
+ 0x90fc, 0x90fc,
+ 0x9400, 0x9458,
+ 0x9600, 0x96bc,
+ 0x9800, 0x9808,
+ 0x9820, 0x983c,
+ 0x9850, 0x9864,
+ 0x9c00, 0x9c6c,
+ 0x9c80, 0x9cec,
+ 0x9d00, 0x9d6c,
+ 0x9d80, 0x9dec,
+ 0x9e00, 0x9e6c,
+ 0x9e80, 0x9eec,
+ 0x9f00, 0x9f6c,
+ 0x9f80, 0x9fec,
+ 0xd004, 0xd03c,
+ 0xdfc0, 0xdfe0,
+ 0xe000, 0xea7c,
+ 0xf000, 0x11190,
+ 0x19040, 0x19124,
+ 0x19150, 0x191b0,
+ 0x191d0, 0x191e8,
+ 0x19238, 0x1924c,
+ 0x193f8, 0x19474,
+ 0x19490, 0x194f8,
+ 0x19800, 0x19f30,
+ 0x1a000, 0x1a06c,
+ 0x1a0b0, 0x1a120,
+ 0x1a128, 0x1a138,
+ 0x1a190, 0x1a1c4,
+ 0x1a1fc, 0x1a1fc,
+ 0x1e040, 0x1e04c,
+ 0x1e240, 0x1e28c,
+ 0x1e2c0, 0x1e2c0,
+ 0x1e2e0, 0x1e2e0,
+ 0x1e300, 0x1e384,
+ 0x1e3c0, 0x1e3c8,
+ 0x1e440, 0x1e44c,
+ 0x1e640, 0x1e68c,
+ 0x1e6c0, 0x1e6c0,
+ 0x1e6e0, 0x1e6e0,
+ 0x1e700, 0x1e784,
+ 0x1e7c0, 0x1e7c8,
+ 0x1e840, 0x1e84c,
+ 0x1ea40, 0x1ea8c,
+ 0x1eac0, 0x1eac0,
+ 0x1eae0, 0x1eae0,
+ 0x1eb00, 0x1eb84,
+ 0x1ebc0, 0x1ebc8,
+ 0x1ec40, 0x1ec4c,
+ 0x1ee40, 0x1ee8c,
+ 0x1eec0, 0x1eec0,
+ 0x1eee0, 0x1eee0,
+ 0x1ef00, 0x1ef84,
+ 0x1efc0, 0x1efc8,
+ 0x1f040, 0x1f04c,
+ 0x1f240, 0x1f28c,
+ 0x1f2c0, 0x1f2c0,
+ 0x1f2e0, 0x1f2e0,
+ 0x1f300, 0x1f384,
+ 0x1f3c0, 0x1f3c8,
+ 0x1f440, 0x1f44c,
+ 0x1f640, 0x1f68c,
+ 0x1f6c0, 0x1f6c0,
+ 0x1f6e0, 0x1f6e0,
+ 0x1f700, 0x1f784,
+ 0x1f7c0, 0x1f7c8,
+ 0x1f840, 0x1f84c,
+ 0x1fa40, 0x1fa8c,
+ 0x1fac0, 0x1fac0,
+ 0x1fae0, 0x1fae0,
+ 0x1fb00, 0x1fb84,
+ 0x1fbc0, 0x1fbc8,
+ 0x1fc40, 0x1fc4c,
+ 0x1fe40, 0x1fe8c,
+ 0x1fec0, 0x1fec0,
+ 0x1fee0, 0x1fee0,
+ 0x1ff00, 0x1ff84,
+ 0x1ffc0, 0x1ffc8,
+ 0x20000, 0x2002c,
+ 0x20100, 0x2013c,
+ 0x20190, 0x201c8,
+ 0x20200, 0x20318,
+ 0x20400, 0x20528,
+ 0x20540, 0x20614,
+ 0x21000, 0x21040,
+ 0x2104c, 0x21060,
+ 0x210c0, 0x210ec,
+ 0x21200, 0x21268,
+ 0x21270, 0x21284,
+ 0x212fc, 0x21388,
+ 0x21400, 0x21404,
+ 0x21500, 0x21518,
+ 0x2152c, 0x2153c,
+ 0x21550, 0x21554,
+ 0x21600, 0x21600,
+ 0x21608, 0x21628,
+ 0x21630, 0x2163c,
+ 0x21700, 0x2171c,
+ 0x21780, 0x2178c,
+ 0x21800, 0x21c38,
+ 0x21c80, 0x21d7c,
+ 0x21e00, 0x21e04,
+ 0x22000, 0x2202c,
+ 0x22100, 0x2213c,
+ 0x22190, 0x221c8,
+ 0x22200, 0x22318,
+ 0x22400, 0x22528,
+ 0x22540, 0x22614,
+ 0x23000, 0x23040,
+ 0x2304c, 0x23060,
+ 0x230c0, 0x230ec,
+ 0x23200, 0x23268,
+ 0x23270, 0x23284,
+ 0x232fc, 0x23388,
+ 0x23400, 0x23404,
+ 0x23500, 0x23518,
+ 0x2352c, 0x2353c,
+ 0x23550, 0x23554,
+ 0x23600, 0x23600,
+ 0x23608, 0x23628,
+ 0x23630, 0x2363c,
+ 0x23700, 0x2371c,
+ 0x23780, 0x2378c,
+ 0x23800, 0x23c38,
+ 0x23c80, 0x23d7c,
+ 0x23e00, 0x23e04,
+ 0x24000, 0x2402c,
+ 0x24100, 0x2413c,
+ 0x24190, 0x241c8,
+ 0x24200, 0x24318,
+ 0x24400, 0x24528,
+ 0x24540, 0x24614,
+ 0x25000, 0x25040,
+ 0x2504c, 0x25060,
+ 0x250c0, 0x250ec,
+ 0x25200, 0x25268,
+ 0x25270, 0x25284,
+ 0x252fc, 0x25388,
+ 0x25400, 0x25404,
+ 0x25500, 0x25518,
+ 0x2552c, 0x2553c,
+ 0x25550, 0x25554,
+ 0x25600, 0x25600,
+ 0x25608, 0x25628,
+ 0x25630, 0x2563c,
+ 0x25700, 0x2571c,
+ 0x25780, 0x2578c,
+ 0x25800, 0x25c38,
+ 0x25c80, 0x25d7c,
+ 0x25e00, 0x25e04,
+ 0x26000, 0x2602c,
+ 0x26100, 0x2613c,
+ 0x26190, 0x261c8,
+ 0x26200, 0x26318,
+ 0x26400, 0x26528,
+ 0x26540, 0x26614,
+ 0x27000, 0x27040,
+ 0x2704c, 0x27060,
+ 0x270c0, 0x270ec,
+ 0x27200, 0x27268,
+ 0x27270, 0x27284,
+ 0x272fc, 0x27388,
+ 0x27400, 0x27404,
+ 0x27500, 0x27518,
+ 0x2752c, 0x2753c,
+ 0x27550, 0x27554,
+ 0x27600, 0x27600,
+ 0x27608, 0x27628,
+ 0x27630, 0x2763c,
+ 0x27700, 0x2771c,
+ 0x27780, 0x2778c,
+ 0x27800, 0x27c38,
+ 0x27c80, 0x27d7c,
+ 0x27e00, 0x27e04
+ };
+
+ int i;
+ struct adapter *ap = netdev2adap(dev);
+
+ regs->version = mk_adap_vers(ap);
+
+ memset(buf, 0, T4_REGMAP_SIZE);
+ for (i = 0; i < ARRAY_SIZE(reg_ranges); i += 2)
+ reg_block_dump(ap, buf, reg_ranges[i], reg_ranges[i + 1]);
+}
+
+static int restart_autoneg(struct net_device *dev)
+{
+ struct port_info *p = netdev_priv(dev);
+
+ if (!netif_running(dev))
+ return -EAGAIN;
+ if (p->link_cfg.autoneg != AUTONEG_ENABLE)
+ return -EINVAL;
+ t4_restart_aneg(p->adapter, 0, p->tx_chan);
+ return 0;
+}
+
+static int identify_port(struct net_device *dev, u32 data)
+{
+ if (data == 0)
+ data = 2; /* default to 2 seconds */
+
+ return t4_identify_port(netdev2adap(dev), 0, netdev2pinfo(dev)->viid,
+ data * 5);
+}
+
+static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps)
+{
+ unsigned int v = 0;
+
+ if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XAUI) {
+ v |= SUPPORTED_TP;
+ if (caps & FW_PORT_CAP_SPEED_100M)
+ v |= SUPPORTED_100baseT_Full;
+ if (caps & FW_PORT_CAP_SPEED_1G)
+ v |= SUPPORTED_1000baseT_Full;
+ if (caps & FW_PORT_CAP_SPEED_10G)
+ v |= SUPPORTED_10000baseT_Full;
+ } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) {
+ v |= SUPPORTED_Backplane;
+ if (caps & FW_PORT_CAP_SPEED_1G)
+ v |= SUPPORTED_1000baseKX_Full;
+ if (caps & FW_PORT_CAP_SPEED_10G)
+ v |= SUPPORTED_10000baseKX4_Full;
+ } else if (type == FW_PORT_TYPE_KR)
+ v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full;
+ else if (type == FW_PORT_TYPE_FIBER)
+ v |= SUPPORTED_FIBRE;
+
+ if (caps & FW_PORT_CAP_ANEG)
+ v |= SUPPORTED_Autoneg;
+ return v;
+}
+
+static unsigned int to_fw_linkcaps(unsigned int caps)
+{
+ unsigned int v = 0;
+
+ if (caps & ADVERTISED_100baseT_Full)
+ v |= FW_PORT_CAP_SPEED_100M;
+ if (caps & ADVERTISED_1000baseT_Full)
+ v |= FW_PORT_CAP_SPEED_1G;
+ if (caps & ADVERTISED_10000baseT_Full)
+ v |= FW_PORT_CAP_SPEED_10G;
+ return v;
+}
+
+static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ const struct port_info *p = netdev_priv(dev);
+
+ if (p->port_type == FW_PORT_TYPE_BT_SGMII ||
+ p->port_type == FW_PORT_TYPE_BT_XAUI)
+ cmd->port = PORT_TP;
+ else if (p->port_type == FW_PORT_TYPE_FIBER)
+ cmd->port = PORT_FIBRE;
+ else if (p->port_type == FW_PORT_TYPE_TWINAX)
+ cmd->port = PORT_DA;
+ else
+ cmd->port = PORT_OTHER;
+
+ if (p->mdio_addr >= 0) {
+ cmd->phy_address = p->mdio_addr;
+ cmd->transceiver = XCVR_EXTERNAL;
+ cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ?
+ MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45;
+ } else {
+ cmd->phy_address = 0; /* not really, but no better option */
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->mdio_support = 0;
+ }
+
+ cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported);
+ cmd->advertising = from_fw_linkcaps(p->port_type,
+ p->link_cfg.advertising);
+ cmd->speed = netif_carrier_ok(dev) ? p->link_cfg.speed : 0;
+ cmd->duplex = DUPLEX_FULL;
+ cmd->autoneg = p->link_cfg.autoneg;
+ cmd->maxtxpkt = 0;
+ cmd->maxrxpkt = 0;
+ return 0;
+}
+
+static unsigned int speed_to_caps(int speed)
+{
+ if (speed == SPEED_100)
+ return FW_PORT_CAP_SPEED_100M;
+ if (speed == SPEED_1000)
+ return FW_PORT_CAP_SPEED_1G;
+ if (speed == SPEED_10000)
+ return FW_PORT_CAP_SPEED_10G;
+ return 0;
+}
+
+static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ unsigned int cap;
+ struct port_info *p = netdev_priv(dev);
+ struct link_config *lc = &p->link_cfg;
+
+ if (cmd->duplex != DUPLEX_FULL) /* only full-duplex supported */
+ return -EINVAL;
+
+ if (!(lc->supported & FW_PORT_CAP_ANEG)) {
+ /*
+ * PHY offers a single speed. See if that's what's
+ * being requested.
+ */
+ if (cmd->autoneg == AUTONEG_DISABLE &&
+ (lc->supported & speed_to_caps(cmd->speed)))
+ return 0;
+ return -EINVAL;
+ }
+
+ if (cmd->autoneg == AUTONEG_DISABLE) {
+ cap = speed_to_caps(cmd->speed);
+
+ if (!(lc->supported & cap) || cmd->speed == SPEED_1000 ||
+ cmd->speed == SPEED_10000)
+ return -EINVAL;
+ lc->requested_speed = cap;
+ lc->advertising = 0;
+ } else {
+ cap = to_fw_linkcaps(cmd->advertising);
+ if (!(lc->supported & cap))
+ return -EINVAL;
+ lc->requested_speed = 0;
+ lc->advertising = cap | FW_PORT_CAP_ANEG;
+ }
+ lc->autoneg = cmd->autoneg;
+
+ if (netif_running(dev))
+ return t4_link_start(p->adapter, 0, p->tx_chan, lc);
+ return 0;
+}
+
+static void get_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *epause)
+{
+ struct port_info *p = netdev_priv(dev);
+
+ epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0;
+ epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0;
+ epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0;
+}
+
+static int set_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *epause)
+{
+ struct port_info *p = netdev_priv(dev);
+ struct link_config *lc = &p->link_cfg;
+
+ if (epause->autoneg == AUTONEG_DISABLE)
+ lc->requested_fc = 0;
+ else if (lc->supported & FW_PORT_CAP_ANEG)
+ lc->requested_fc = PAUSE_AUTONEG;
+ else
+ return -EINVAL;
+
+ if (epause->rx_pause)
+ lc->requested_fc |= PAUSE_RX;
+ if (epause->tx_pause)
+ lc->requested_fc |= PAUSE_TX;
+ if (netif_running(dev))
+ return t4_link_start(p->adapter, 0, p->tx_chan, lc);
+ return 0;
+}
+
+static u32 get_rx_csum(struct net_device *dev)
+{
+ struct port_info *p = netdev_priv(dev);
+
+ return p->rx_offload & RX_CSO;
+}
+
+static int set_rx_csum(struct net_device *dev, u32 data)
+{
+ struct port_info *p = netdev_priv(dev);
+
+ if (data)
+ p->rx_offload |= RX_CSO;
+ else
+ p->rx_offload &= ~RX_CSO;
+ return 0;
+}
+
+static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
+{
+ const struct port_info *pi = netdev_priv(dev);
+ const struct sge *s = &pi->adapter->sge;
+
+ e->rx_max_pending = MAX_RX_BUFFERS;
+ e->rx_mini_max_pending = MAX_RSPQ_ENTRIES;
+ e->rx_jumbo_max_pending = 0;
+ e->tx_max_pending = MAX_TXQ_ENTRIES;
+
+ e->rx_pending = s->ethrxq[pi->first_qset].fl.size - 8;
+ e->rx_mini_pending = s->ethrxq[pi->first_qset].rspq.size;
+ e->rx_jumbo_pending = 0;
+ e->tx_pending = s->ethtxq[pi->first_qset].q.size;
+}
+
+static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
+{
+ int i;
+ const struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
+ struct sge *s = &adapter->sge;
+
+ if (e->rx_pending > MAX_RX_BUFFERS || e->rx_jumbo_pending ||
+ e->tx_pending > MAX_TXQ_ENTRIES ||
+ e->rx_mini_pending > MAX_RSPQ_ENTRIES ||
+ e->rx_mini_pending < MIN_RSPQ_ENTRIES ||
+ e->rx_pending < MIN_FL_ENTRIES || e->tx_pending < MIN_TXQ_ENTRIES)
+ return -EINVAL;
+
+ if (adapter->flags & FULL_INIT_DONE)
+ return -EBUSY;
+
+ for (i = 0; i < pi->nqsets; ++i) {
+ s->ethtxq[pi->first_qset + i].q.size = e->tx_pending;
+ s->ethrxq[pi->first_qset + i].fl.size = e->rx_pending + 8;
+ s->ethrxq[pi->first_qset + i].rspq.size = e->rx_mini_pending;
+ }
+ return 0;
+}
+
+static int closest_timer(const struct sge *s, int time)
+{
+ int i, delta, match = 0, min_delta = INT_MAX;
+
+ for (i = 0; i < ARRAY_SIZE(s->timer_val); i++) {
+ delta = time - s->timer_val[i];
+ if (delta < 0)
+ delta = -delta;
+ if (delta < min_delta) {
+ min_delta = delta;
+ match = i;
+ }
+ }
+ return match;
+}
+
+static int closest_thres(const struct sge *s, int thres)
+{
+ int i, delta, match = 0, min_delta = INT_MAX;
+
+ for (i = 0; i < ARRAY_SIZE(s->counter_val); i++) {
+ delta = thres - s->counter_val[i];
+ if (delta < 0)
+ delta = -delta;
+ if (delta < min_delta) {
+ min_delta = delta;
+ match = i;
+ }
+ }
+ return match;
+}
+
+/*
+ * Return a queue's interrupt hold-off time in us. 0 means no timer.
+ */
+static unsigned int qtimer_val(const struct adapter *adap,
+ const struct sge_rspq *q)
+{
+ unsigned int idx = q->intr_params >> 1;
+
+ return idx < SGE_NTIMERS ? adap->sge.timer_val[idx] : 0;
+}
+
+/**
+ * set_rxq_intr_params - set a queue's interrupt holdoff parameters
+ * @adap: the adapter
+ * @q: the Rx queue
+ * @us: the hold-off time in us, or 0 to disable timer
+ * @cnt: the hold-off packet count, or 0 to disable counter
+ *
+ * Sets an Rx queue's interrupt hold-off time and packet count. At least
+ * one of the two needs to be enabled for the queue to generate interrupts.
+ */
+static int set_rxq_intr_params(struct adapter *adap, struct sge_rspq *q,
+ unsigned int us, unsigned int cnt)
+{
+ if ((us | cnt) == 0)
+ cnt = 1;
+
+ if (cnt) {
+ int err;
+ u32 v, new_idx;
+
+ new_idx = closest_thres(&adap->sge, cnt);
+ if (q->desc && q->pktcnt_idx != new_idx) {
+ /* the queue has already been created, update it */
+ v = FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
+ FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) |
+ FW_PARAMS_PARAM_YZ(q->cntxt_id);
+ err = t4_set_params(adap, 0, 0, 0, 1, &v, &new_idx);
+ if (err)
+ return err;
+ }
+ q->pktcnt_idx = new_idx;
+ }
+
+ us = us == 0 ? 6 : closest_timer(&adap->sge, us);
+ q->intr_params = QINTR_TIMER_IDX(us) | (cnt > 0 ? QINTR_CNT_EN : 0);
+ return 0;
+}
+
+static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
+{
+ const struct port_info *pi = netdev_priv(dev);
+ struct adapter *adap = pi->adapter;
+
+ return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq,
+ c->rx_coalesce_usecs, c->rx_max_coalesced_frames);
+}
+
+static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
+{
+ const struct port_info *pi = netdev_priv(dev);
+ const struct adapter *adap = pi->adapter;
+ const struct sge_rspq *rq = &adap->sge.ethrxq[pi->first_qset].rspq;
+
+ c->rx_coalesce_usecs = qtimer_val(adap, rq);
+ c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ?
+ adap->sge.counter_val[rq->pktcnt_idx] : 0;
+ return 0;
+}
+
+/*
+ * Translate a physical EEPROM address to virtual. The first 1K is accessed
+ * through virtual addresses starting at 31K, the rest is accessed through
+ * virtual addresses starting at 0. This mapping is correct only for PF0.
+ */
+static int eeprom_ptov(unsigned int phys_addr)
+{
+ if (phys_addr < 1024)
+ return phys_addr + (31 << 10);
+ if (phys_addr < EEPROMSIZE)
+ return phys_addr - 1024;
+ return -EINVAL;
+}
+
+/*
+ * The next two routines implement eeprom read/write from physical addresses.
+ * The physical->virtual translation is correct only for PF0.
+ */
+static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
+{
+ int vaddr = eeprom_ptov(phys_addr);
+
+ if (vaddr >= 0)
+ vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v);
+ return vaddr < 0 ? vaddr : 0;
+}
+
+static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v)
+{
+ int vaddr = eeprom_ptov(phys_addr);
+
+ if (vaddr >= 0)
+ vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v);
+ return vaddr < 0 ? vaddr : 0;
+}
+
+#define EEPROM_MAGIC 0x38E2F10C
+
+static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
+ u8 *data)
+{
+ int i, err = 0;
+ struct adapter *adapter = netdev2adap(dev);
+
+ u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ e->magic = EEPROM_MAGIC;
+ for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4)
+ err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]);
+
+ if (!err)
+ memcpy(data, buf + e->offset, e->len);
+ kfree(buf);
+ return err;
+}
+
+static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+ u8 *data)
+{
+ u8 *buf;
+ int err = 0;
+ u32 aligned_offset, aligned_len, *p;
+ struct adapter *adapter = netdev2adap(dev);
+
+ if (eeprom->magic != EEPROM_MAGIC)
+ return -EINVAL;
+
+ aligned_offset = eeprom->offset & ~3;
+ aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3;
+
+ if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) {
+ /*
+ * RMW possibly needed for first or last words.
+ */
+ buf = kmalloc(aligned_len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf);
+ if (!err && aligned_len > 4)
+ err = eeprom_rd_phys(adapter,
+ aligned_offset + aligned_len - 4,
+ (u32 *)&buf[aligned_len - 4]);
+ if (err)
+ goto out;
+ memcpy(buf + (eeprom->offset & 3), data, eeprom->len);
+ } else
+ buf = data;
+
+ err = t4_seeprom_wp(adapter, false);
+ if (err)
+ goto out;
+
+ for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) {
+ err = eeprom_wr_phys(adapter, aligned_offset, *p);
+ aligned_offset += 4;
+ }
+
+ if (!err)
+ err = t4_seeprom_wp(adapter, true);
+out:
+ if (buf != data)
+ kfree(buf);
+ return err;
+}
+
+static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
+{
+ int ret;
+ const struct firmware *fw;
+ struct adapter *adap = netdev2adap(netdev);
+
+ ef->data[sizeof(ef->data) - 1] = '\0';
+ ret = request_firmware(&fw, ef->data, adap->pdev_dev);
+ if (ret < 0)
+ return ret;
+
+ ret = t4_load_fw(adap, fw->data, fw->size);
+ release_firmware(fw);
+ if (!ret)
+ dev_info(adap->pdev_dev, "loaded firmware %s\n", ef->data);
+ return ret;
+}
+
+#define WOL_SUPPORTED (WAKE_BCAST | WAKE_MAGIC)
+#define BCAST_CRC 0xa0ccc1a6
+
+static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ wol->supported = WAKE_BCAST | WAKE_MAGIC;
+ wol->wolopts = netdev2adap(dev)->wol;
+ memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ int err = 0;
+ struct port_info *pi = netdev_priv(dev);
+
+ if (wol->wolopts & ~WOL_SUPPORTED)
+ return -EINVAL;
+ t4_wol_magic_enable(pi->adapter, pi->tx_chan,
+ (wol->wolopts & WAKE_MAGIC) ? dev->dev_addr : NULL);
+ if (wol->wolopts & WAKE_BCAST) {
+ err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0xfe, ~0ULL,
+ ~0ULL, 0, false);
+ if (!err)
+ err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 1,
+ ~6ULL, ~0ULL, BCAST_CRC, true);
+ } else
+ t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0, 0, 0, 0, false);
+ return err;
+}
+
+static int set_tso(struct net_device *dev, u32 value)
+{
+ if (value)
+ dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+ else
+ dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+ return 0;
+}
+
+static struct ethtool_ops cxgb_ethtool_ops = {
+ .get_settings = get_settings,
+ .set_settings = set_settings,
+ .get_drvinfo = get_drvinfo,
+ .get_msglevel = get_msglevel,
+ .set_msglevel = set_msglevel,
+ .get_ringparam = get_sge_param,
+ .set_ringparam = set_sge_param,
+ .get_coalesce = get_coalesce,
+ .set_coalesce = set_coalesce,
+ .get_eeprom_len = get_eeprom_len,
+ .get_eeprom = get_eeprom,
+ .set_eeprom = set_eeprom,
+ .get_pauseparam = get_pauseparam,
+ .set_pauseparam = set_pauseparam,
+ .get_rx_csum = get_rx_csum,
+ .set_rx_csum = set_rx_csum,
+ .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
+ .set_sg = ethtool_op_set_sg,
+ .get_link = ethtool_op_get_link,
+ .get_strings = get_strings,
+ .phys_id = identify_port,
+ .nway_reset = restart_autoneg,
+ .get_sset_count = get_sset_count,
+ .get_ethtool_stats = get_stats,
+ .get_regs_len = get_regs_len,
+ .get_regs = get_regs,
+ .get_wol = get_wol,
+ .set_wol = set_wol,
+ .set_tso = set_tso,
+ .flash_device = set_flash,
+};
+
+/*
+ * debugfs support
+ */
+
+static int mem_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ loff_t pos = *ppos;
+ loff_t avail = file->f_path.dentry->d_inode->i_size;
+ unsigned int mem = (uintptr_t)file->private_data & 3;
+ struct adapter *adap = file->private_data - mem;
+
+ if (pos < 0)
+ return -EINVAL;
+ if (pos >= avail)
+ return 0;
+ if (count > avail - pos)
+ count = avail - pos;
+
+ while (count) {
+ size_t len;
+ int ret, ofst;
+ __be32 data[16];
+
+ if (mem == MEM_MC)
+ ret = t4_mc_read(adap, pos, data, NULL);
+ else
+ ret = t4_edc_read(adap, mem, pos, data, NULL);
+ if (ret)
+ return ret;
+
+ ofst = pos % sizeof(data);
+ len = min(count, sizeof(data) - ofst);
+ if (copy_to_user(buf, (u8 *)data + ofst, len))
+ return -EFAULT;
+
+ buf += len;
+ pos += len;
+ count -= len;
+ }
+ count = pos - *ppos;
+ *ppos = pos;
+ return count;
+}
+
+static const struct file_operations mem_debugfs_fops = {
+ .owner = THIS_MODULE,
+ .open = mem_open,
+ .read = mem_read,
+};
+
+static void __devinit add_debugfs_mem(struct adapter *adap, const char *name,
+ unsigned int idx, unsigned int size_mb)
+{
+ struct dentry *de;
+
+ de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root,
+ (void *)adap + idx, &mem_debugfs_fops);
+ if (de && de->d_inode)
+ de->d_inode->i_size = size_mb << 20;
+}
+
+static int __devinit setup_debugfs(struct adapter *adap)
+{
+ int i;
+
+ if (IS_ERR_OR_NULL(adap->debugfs_root))
+ return -1;
+
+ i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE);
+ if (i & EDRAM0_ENABLE)
+ add_debugfs_mem(adap, "edc0", MEM_EDC0, 5);
+ if (i & EDRAM1_ENABLE)
+ add_debugfs_mem(adap, "edc1", MEM_EDC1, 5);
+ if (i & EXT_MEM_ENABLE)
+ add_debugfs_mem(adap, "mc", MEM_MC,
+ EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR)));
+ if (adap->l2t)
+ debugfs_create_file("l2t", S_IRUSR, adap->debugfs_root, adap,
+ &t4_l2t_fops);
+ return 0;
+}
+
+/*
+ * upper-layer driver support
+ */
+
+/*
+ * Allocate an active-open TID and set it to the supplied value.
+ */
+int cxgb4_alloc_atid(struct tid_info *t, void *data)
+{
+ int atid = -1;
+
+ spin_lock_bh(&t->atid_lock);
+ if (t->afree) {
+ union aopen_entry *p = t->afree;
+
+ atid = p - t->atid_tab;
+ t->afree = p->next;
+ p->data = data;
+ t->atids_in_use++;
+ }
+ spin_unlock_bh(&t->atid_lock);
+ return atid;
+}
+EXPORT_SYMBOL(cxgb4_alloc_atid);
+
+/*
+ * Release an active-open TID.
+ */
+void cxgb4_free_atid(struct tid_info *t, unsigned int atid)
+{
+ union aopen_entry *p = &t->atid_tab[atid];
+
+ spin_lock_bh(&t->atid_lock);
+ p->next = t->afree;
+ t->afree = p;
+ t->atids_in_use--;
+ spin_unlock_bh(&t->atid_lock);
+}
+EXPORT_SYMBOL(cxgb4_free_atid);
+
+/*
+ * Allocate a server TID and set it to the supplied value.
+ */
+int cxgb4_alloc_stid(struct tid_info *t, int family, void *data)
+{
+ int stid;
+
+ spin_lock_bh(&t->stid_lock);
+ if (family == PF_INET) {
+ stid = find_first_zero_bit(t->stid_bmap, t->nstids);
+ if (stid < t->nstids)
+ __set_bit(stid, t->stid_bmap);
+ else
+ stid = -1;
+ } else {
+ stid = bitmap_find_free_region(t->stid_bmap, t->nstids, 2);
+ if (stid < 0)
+ stid = -1;
+ }
+ if (stid >= 0) {
+ t->stid_tab[stid].data = data;
+ stid += t->stid_base;
+ t->stids_in_use++;
+ }
+ spin_unlock_bh(&t->stid_lock);
+ return stid;
+}
+EXPORT_SYMBOL(cxgb4_alloc_stid);
+
+/*
+ * Release a server TID.
+ */
+void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family)
+{
+ stid -= t->stid_base;
+ spin_lock_bh(&t->stid_lock);
+ if (family == PF_INET)
+ __clear_bit(stid, t->stid_bmap);
+ else
+ bitmap_release_region(t->stid_bmap, stid, 2);
+ t->stid_tab[stid].data = NULL;
+ t->stids_in_use--;
+ spin_unlock_bh(&t->stid_lock);
+}
+EXPORT_SYMBOL(cxgb4_free_stid);
+
+/*
+ * Populate a TID_RELEASE WR. Caller must properly size the skb.
+ */
+static void mk_tid_release(struct sk_buff *skb, unsigned int chan,
+ unsigned int tid)
+{
+ struct cpl_tid_release *req;
+
+ set_wr_txq(skb, CPL_PRIORITY_SETUP, chan);
+ req = (struct cpl_tid_release *)__skb_put(skb, sizeof(*req));
+ INIT_TP_WR(req, tid);
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid));
+}
+
+/*
+ * Queue a TID release request and if necessary schedule a work queue to
+ * process it.
+ */
+void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
+ unsigned int tid)
+{
+ void **p = &t->tid_tab[tid];
+ struct adapter *adap = container_of(t, struct adapter, tids);
+
+ spin_lock_bh(&adap->tid_release_lock);
+ *p = adap->tid_release_head;
+ /* Low 2 bits encode the Tx channel number */
+ adap->tid_release_head = (void **)((uintptr_t)p | chan);
+ if (!adap->tid_release_task_busy) {
+ adap->tid_release_task_busy = true;
+ schedule_work(&adap->tid_release_task);
+ }
+ spin_unlock_bh(&adap->tid_release_lock);
+}
+EXPORT_SYMBOL(cxgb4_queue_tid_release);
+
+/*
+ * Process the list of pending TID release requests.
+ */
+static void process_tid_release_list(struct work_struct *work)
+{
+ struct sk_buff *skb;
+ struct adapter *adap;
+
+ adap = container_of(work, struct adapter, tid_release_task);
+
+ spin_lock_bh(&adap->tid_release_lock);
+ while (adap->tid_release_head) {
+ void **p = adap->tid_release_head;
+ unsigned int chan = (uintptr_t)p & 3;
+ p = (void *)p - chan;
+
+ adap->tid_release_head = *p;
+ *p = NULL;
+ spin_unlock_bh(&adap->tid_release_lock);
+
+ while (!(skb = alloc_skb(sizeof(struct cpl_tid_release),
+ GFP_KERNEL)))
+ schedule_timeout_uninterruptible(1);
+
+ mk_tid_release(skb, chan, p - adap->tids.tid_tab);
+ t4_ofld_send(adap, skb);
+ spin_lock_bh(&adap->tid_release_lock);
+ }
+ adap->tid_release_task_busy = false;
+ spin_unlock_bh(&adap->tid_release_lock);
+}
+
+/*
+ * Release a TID and inform HW. If we are unable to allocate the release
+ * message we defer to a work queue.
+ */
+void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid)
+{
+ void *old;
+ struct sk_buff *skb;
+ struct adapter *adap = container_of(t, struct adapter, tids);
+
+ old = t->tid_tab[tid];
+ skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC);
+ if (likely(skb)) {
+ t->tid_tab[tid] = NULL;
+ mk_tid_release(skb, chan, tid);
+ t4_ofld_send(adap, skb);
+ } else
+ cxgb4_queue_tid_release(t, chan, tid);
+ if (old)
+ atomic_dec(&t->tids_in_use);
+}
+EXPORT_SYMBOL(cxgb4_remove_tid);
+
+/*
+ * Allocate and initialize the TID tables. Returns 0 on success.
+ */
+static int tid_init(struct tid_info *t)
+{
+ size_t size;
+ unsigned int natids = t->natids;
+
+ size = t->ntids * sizeof(*t->tid_tab) + natids * sizeof(*t->atid_tab) +
+ t->nstids * sizeof(*t->stid_tab) +
+ BITS_TO_LONGS(t->nstids) * sizeof(long);
+ t->tid_tab = t4_alloc_mem(size);
+ if (!t->tid_tab)
+ return -ENOMEM;
+
+ t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids];
+ t->stid_tab = (struct serv_entry *)&t->atid_tab[natids];
+ t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids];
+ spin_lock_init(&t->stid_lock);
+ spin_lock_init(&t->atid_lock);
+
+ t->stids_in_use = 0;
+ t->afree = NULL;
+ t->atids_in_use = 0;
+ atomic_set(&t->tids_in_use, 0);
+
+ /* Setup the free list for atid_tab and clear the stid bitmap. */
+ if (natids) {
+ while (--natids)
+ t->atid_tab[natids - 1].next = &t->atid_tab[natids];
+ t->afree = t->atid_tab;
+ }
+ bitmap_zero(t->stid_bmap, t->nstids);
+ return 0;
+}
+
+/**
+ * cxgb4_create_server - create an IP server
+ * @dev: the device
+ * @stid: the server TID
+ * @sip: local IP address to bind server to
+ * @sport: the server's TCP port
+ * @queue: queue to direct messages from this server to
+ *
+ * Create an IP server for the given port and address.
+ * Returns <0 on error and one of the %NET_XMIT_* values on success.
+ */
+int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
+ __be32 sip, __be16 sport, unsigned int queue)
+{
+ unsigned int chan;
+ struct sk_buff *skb;
+ struct adapter *adap;
+ struct cpl_pass_open_req *req;
+
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ adap = netdev2adap(dev);
+ req = (struct cpl_pass_open_req *)__skb_put(skb, sizeof(*req));
+ INIT_TP_WR(req, 0);
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, stid));
+ req->local_port = sport;
+ req->peer_port = htons(0);
+ req->local_ip = sip;
+ req->peer_ip = htonl(0);
+ chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+ req->opt0 = cpu_to_be64(TX_CHAN(chan));
+ req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
+ SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
+ return t4_mgmt_tx(adap, skb);
+}
+EXPORT_SYMBOL(cxgb4_create_server);
+
+/**
+ * cxgb4_create_server6 - create an IPv6 server
+ * @dev: the device
+ * @stid: the server TID
+ * @sip: local IPv6 address to bind server to
+ * @sport: the server's TCP port
+ * @queue: queue to direct messages from this server to
+ *
+ * Create an IPv6 server for the given port and address.
+ * Returns <0 on error and one of the %NET_XMIT_* values on success.
+ */
+int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
+ const struct in6_addr *sip, __be16 sport,
+ unsigned int queue)
+{
+ unsigned int chan;
+ struct sk_buff *skb;
+ struct adapter *adap;
+ struct cpl_pass_open_req6 *req;
+
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ adap = netdev2adap(dev);
+ req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req));
+ INIT_TP_WR(req, 0);
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid));
+ req->local_port = sport;
+ req->peer_port = htons(0);
+ req->local_ip_hi = *(__be64 *)(sip->s6_addr);
+ req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8);
+ req->peer_ip_hi = cpu_to_be64(0);
+ req->peer_ip_lo = cpu_to_be64(0);
+ chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+ req->opt0 = cpu_to_be64(TX_CHAN(chan));
+ req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
+ SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
+ return t4_mgmt_tx(adap, skb);
+}
+EXPORT_SYMBOL(cxgb4_create_server6);
+
+/**
+ * cxgb4_best_mtu - find the entry in the MTU table closest to an MTU
+ * @mtus: the HW MTU table
+ * @mtu: the target MTU
+ * @idx: index of selected entry in the MTU table
+ *
+ * Returns the index and the value in the HW MTU table that is closest to
+ * but does not exceed @mtu, unless @mtu is smaller than any value in the
+ * table, in which case that smallest available value is selected.
+ */
+unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
+ unsigned int *idx)
+{
+ unsigned int i = 0;
+
+ while (i < NMTUS - 1 && mtus[i + 1] <= mtu)
+ ++i;
+ if (idx)
+ *idx = i;
+ return mtus[i];
+}
+EXPORT_SYMBOL(cxgb4_best_mtu);
+
+/**
+ * cxgb4_port_chan - get the HW channel of a port
+ * @dev: the net device for the port
+ *
+ * Return the HW Tx channel of the given port.
+ */
+unsigned int cxgb4_port_chan(const struct net_device *dev)
+{
+ return netdev2pinfo(dev)->tx_chan;
+}
+EXPORT_SYMBOL(cxgb4_port_chan);
+
+/**
+ * cxgb4_port_viid - get the VI id of a port
+ * @dev: the net device for the port
+ *
+ * Return the VI id of the given port.
+ */
+unsigned int cxgb4_port_viid(const struct net_device *dev)
+{
+ return netdev2pinfo(dev)->viid;
+}
+EXPORT_SYMBOL(cxgb4_port_viid);
+
+/**
+ * cxgb4_port_idx - get the index of a port
+ * @dev: the net device for the port
+ *
+ * Return the index of the given port.
+ */
+unsigned int cxgb4_port_idx(const struct net_device *dev)
+{
+ return netdev2pinfo(dev)->port_id;
+}
+EXPORT_SYMBOL(cxgb4_port_idx);
+
+/**
+ * cxgb4_netdev_by_hwid - return the net device of a HW port
+ * @pdev: identifies the adapter
+ * @id: the HW port id
+ *
+ * Return the net device associated with the interface with the given HW
+ * id.
+ */
+struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id)
+{
+ const struct adapter *adap = pci_get_drvdata(pdev);
+
+ if (!adap || id >= NCHAN)
+ return NULL;
+ id = adap->chan_map[id];
+ return id < MAX_NPORTS ? adap->port[id] : NULL;
+}
+EXPORT_SYMBOL(cxgb4_netdev_by_hwid);
+
+void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
+ struct tp_tcp_stats *v6)
+{
+ struct adapter *adap = pci_get_drvdata(pdev);
+
+ spin_lock(&adap->stats_lock);
+ t4_tp_get_tcp_stats(adap, v4, v6);
+ spin_unlock(&adap->stats_lock);
+}
+EXPORT_SYMBOL(cxgb4_get_tcp_stats);
+
+void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
+ const unsigned int *pgsz_order)
+{
+ struct adapter *adap = netdev2adap(dev);
+
+ t4_write_reg(adap, ULP_RX_ISCSI_TAGMASK, tag_mask);
+ t4_write_reg(adap, ULP_RX_ISCSI_PSZ, HPZ0(pgsz_order[0]) |
+ HPZ1(pgsz_order[1]) | HPZ2(pgsz_order[2]) |
+ HPZ3(pgsz_order[3]));
+}
+EXPORT_SYMBOL(cxgb4_iscsi_init);
+
+static struct pci_driver cxgb4_driver;
+
+static void check_neigh_update(struct neighbour *neigh)
+{
+ const struct device *parent;
+ const struct net_device *netdev = neigh->dev;
+
+ if (netdev->priv_flags & IFF_802_1Q_VLAN)
+ netdev = vlan_dev_real_dev(netdev);
+ parent = netdev->dev.parent;
+ if (parent && parent->driver == &cxgb4_driver.driver)
+ t4_l2t_update(dev_get_drvdata(parent), neigh);
+}
+
+static int netevent_cb(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ switch (event) {
+ case NETEVENT_NEIGH_UPDATE:
+ check_neigh_update(data);
+ break;
+ case NETEVENT_PMTU_UPDATE:
+ case NETEVENT_REDIRECT:
+ default:
+ break;
+ }
+ return 0;
+}
+
+static bool netevent_registered;
+static struct notifier_block cxgb4_netevent_nb = {
+ .notifier_call = netevent_cb
+};
+
+static void uld_attach(struct adapter *adap, unsigned int uld)
+{
+ void *handle;
+ struct cxgb4_lld_info lli;
+
+ lli.pdev = adap->pdev;
+ lli.l2t = adap->l2t;
+ lli.tids = &adap->tids;
+ lli.ports = adap->port;
+ lli.vr = &adap->vres;
+ lli.mtus = adap->params.mtus;
+ if (uld == CXGB4_ULD_RDMA) {
+ lli.rxq_ids = adap->sge.rdma_rxq;
+ lli.nrxq = adap->sge.rdmaqs;
+ } else if (uld == CXGB4_ULD_ISCSI) {
+ lli.rxq_ids = adap->sge.ofld_rxq;
+ lli.nrxq = adap->sge.ofldqsets;
+ }
+ lli.ntxq = adap->sge.ofldqsets;
+ lli.nchan = adap->params.nports;
+ lli.nports = adap->params.nports;
+ lli.wr_cred = adap->params.ofldq_wr_cred;
+ lli.adapter_type = adap->params.rev;
+ lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2));
+ lli.udb_density = 1 << QUEUESPERPAGEPF0_GET(
+ t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF));
+ lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET(
+ t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF));
+ lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS);
+ lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL);
+ lli.fw_vers = adap->params.fw_vers;
+
+ handle = ulds[uld].add(&lli);
+ if (IS_ERR(handle)) {
+ dev_warn(adap->pdev_dev,
+ "could not attach to the %s driver, error %ld\n",
+ uld_str[uld], PTR_ERR(handle));
+ return;
+ }
+
+ adap->uld_handle[uld] = handle;
+
+ if (!netevent_registered) {
+ register_netevent_notifier(&cxgb4_netevent_nb);
+ netevent_registered = true;
+ }
+}
+
+static void attach_ulds(struct adapter *adap)
+{
+ unsigned int i;
+
+ mutex_lock(&uld_mutex);
+ list_add_tail(&adap->list_node, &adapter_list);
+ for (i = 0; i < CXGB4_ULD_MAX; i++)
+ if (ulds[i].add)
+ uld_attach(adap, i);
+ mutex_unlock(&uld_mutex);
+}
+
+static void detach_ulds(struct adapter *adap)
+{
+ unsigned int i;
+
+ mutex_lock(&uld_mutex);
+ list_del(&adap->list_node);
+ for (i = 0; i < CXGB4_ULD_MAX; i++)
+ if (adap->uld_handle[i]) {
+ ulds[i].state_change(adap->uld_handle[i],
+ CXGB4_STATE_DETACH);
+ adap->uld_handle[i] = NULL;
+ }
+ if (netevent_registered && list_empty(&adapter_list)) {
+ unregister_netevent_notifier(&cxgb4_netevent_nb);
+ netevent_registered = false;
+ }
+ mutex_unlock(&uld_mutex);
+}
+
+static void notify_ulds(struct adapter *adap, enum cxgb4_state new_state)
+{
+ unsigned int i;
+
+ mutex_lock(&uld_mutex);
+ for (i = 0; i < CXGB4_ULD_MAX; i++)
+ if (adap->uld_handle[i])
+ ulds[i].state_change(adap->uld_handle[i], new_state);
+ mutex_unlock(&uld_mutex);
+}
+
+/**
+ * cxgb4_register_uld - register an upper-layer driver
+ * @type: the ULD type
+ * @p: the ULD methods
+ *
+ * Registers an upper-layer driver with this driver and notifies the ULD
+ * about any presently available devices that support its type. Returns
+ * %-EBUSY if a ULD of the same type is already registered.
+ */
+int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p)
+{
+ int ret = 0;
+ struct adapter *adap;
+
+ if (type >= CXGB4_ULD_MAX)
+ return -EINVAL;
+ mutex_lock(&uld_mutex);
+ if (ulds[type].add) {
+ ret = -EBUSY;
+ goto out;
+ }
+ ulds[type] = *p;
+ list_for_each_entry(adap, &adapter_list, list_node)
+ uld_attach(adap, type);
+out: mutex_unlock(&uld_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(cxgb4_register_uld);
+
+/**
+ * cxgb4_unregister_uld - unregister an upper-layer driver
+ * @type: the ULD type
+ *
+ * Unregisters an existing upper-layer driver.
+ */
+int cxgb4_unregister_uld(enum cxgb4_uld type)
+{
+ struct adapter *adap;
+
+ if (type >= CXGB4_ULD_MAX)
+ return -EINVAL;
+ mutex_lock(&uld_mutex);
+ list_for_each_entry(adap, &adapter_list, list_node)
+ adap->uld_handle[type] = NULL;
+ ulds[type].add = NULL;
+ mutex_unlock(&uld_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(cxgb4_unregister_uld);
+
+/**
+ * cxgb_up - enable the adapter
+ * @adap: adapter being enabled
+ *
+ * Called when the first port is enabled, this function performs the
+ * actions necessary to make an adapter operational, such as completing
+ * the initialization of HW modules, and enabling interrupts.
+ *
+ * Must be called with the rtnl lock held.
+ */
+static int cxgb_up(struct adapter *adap)
+{
+ int err = 0;
+
+ if (!(adap->flags & FULL_INIT_DONE)) {
+ err = setup_sge_queues(adap);
+ if (err)
+ goto out;
+ err = setup_rss(adap);
+ if (err) {
+ t4_free_sge_resources(adap);
+ goto out;
+ }
+ if (adap->flags & USING_MSIX)
+ name_msix_vecs(adap);
+ adap->flags |= FULL_INIT_DONE;
+ }
+
+ if (adap->flags & USING_MSIX) {
+ err = request_irq(adap->msix_info[0].vec, t4_nondata_intr, 0,
+ adap->msix_info[0].desc, adap);
+ if (err)
+ goto irq_err;
+
+ err = request_msix_queue_irqs(adap);
+ if (err) {
+ free_irq(adap->msix_info[0].vec, adap);
+ goto irq_err;
+ }
+ } else {
+ err = request_irq(adap->pdev->irq, t4_intr_handler(adap),
+ (adap->flags & USING_MSI) ? 0 : IRQF_SHARED,
+ adap->name, adap);
+ if (err)
+ goto irq_err;
+ }
+ enable_rx(adap);
+ t4_sge_start(adap);
+ t4_intr_enable(adap);
+ notify_ulds(adap, CXGB4_STATE_UP);
+ out:
+ return err;
+ irq_err:
+ dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err);
+ goto out;
+}
+
+static void cxgb_down(struct adapter *adapter)
+{
+ t4_intr_disable(adapter);
+ cancel_work_sync(&adapter->tid_release_task);
+ adapter->tid_release_task_busy = false;
+
+ if (adapter->flags & USING_MSIX) {
+ free_msix_queue_irqs(adapter);
+ free_irq(adapter->msix_info[0].vec, adapter);
+ } else
+ free_irq(adapter->pdev->irq, adapter);
+ quiesce_rx(adapter);
+}
+
+/*
+ * net_device operations
+ */
+static int cxgb_open(struct net_device *dev)
+{
+ int err;
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
+
+ if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
+ return err;
+
+ dev->real_num_tx_queues = pi->nqsets;
+ set_bit(pi->tx_chan, &adapter->open_device_map);
+ link_start(dev);
+ netif_tx_start_all_queues(dev);
+ return 0;
+}
+
+static int cxgb_close(struct net_device *dev)
+{
+ int ret;
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adapter = pi->adapter;
+
+ netif_tx_stop_all_queues(dev);
+ netif_carrier_off(dev);
+ ret = t4_enable_vi(adapter, 0, pi->viid, false, false);
+
+ clear_bit(pi->tx_chan, &adapter->open_device_map);
+
+ if (!adapter->open_device_map)
+ cxgb_down(adapter);
+ return 0;
+}
+
+static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
+{
+ struct port_stats stats;
+ struct port_info *p = netdev_priv(dev);
+ struct adapter *adapter = p->adapter;
+ struct net_device_stats *ns = &dev->stats;
+
+ spin_lock(&adapter->stats_lock);
+ t4_get_port_stats(adapter, p->tx_chan, &stats);
+ spin_unlock(&adapter->stats_lock);
+
+ ns->tx_bytes = stats.tx_octets;
+ ns->tx_packets = stats.tx_frames;
+ ns->rx_bytes = stats.rx_octets;
+ ns->rx_packets = stats.rx_frames;
+ ns->multicast = stats.rx_mcast_frames;
+
+ /* detailed rx_errors */
+ ns->rx_length_errors = stats.rx_jabber + stats.rx_too_long +
+ stats.rx_runt;
+ ns->rx_over_errors = 0;
+ ns->rx_crc_errors = stats.rx_fcs_err;
+ ns->rx_frame_errors = stats.rx_symbol_err;
+ ns->rx_fifo_errors = stats.rx_ovflow0 + stats.rx_ovflow1 +
+ stats.rx_ovflow2 + stats.rx_ovflow3 +
+ stats.rx_trunc0 + stats.rx_trunc1 +
+ stats.rx_trunc2 + stats.rx_trunc3;
+ ns->rx_missed_errors = 0;
+
+ /* detailed tx_errors */
+ ns->tx_aborted_errors = 0;
+ ns->tx_carrier_errors = 0;
+ ns->tx_fifo_errors = 0;
+ ns->tx_heartbeat_errors = 0;
+ ns->tx_window_errors = 0;
+
+ ns->tx_errors = stats.tx_error_frames;
+ ns->rx_errors = stats.rx_symbol_err + stats.rx_fcs_err +
+ ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors;
+ return ns;
+}
+
+static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+ int ret = 0, prtad, devad;
+ struct port_info *pi = netdev_priv(dev);
+ struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data;
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ if (pi->mdio_addr < 0)
+ return -EOPNOTSUPP;
+ data->phy_id = pi->mdio_addr;
+ break;
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ if (mdio_phy_id_is_c45(data->phy_id)) {
+ prtad = mdio_phy_id_prtad(data->phy_id);
+ devad = mdio_phy_id_devad(data->phy_id);
+ } else if (data->phy_id < 32) {
+ prtad = data->phy_id;
+ devad = 0;
+ data->reg_num &= 0x1f;
+ } else
+ return -EINVAL;
+
+ if (cmd == SIOCGMIIREG)
+ ret = t4_mdio_rd(pi->adapter, 0, prtad, devad,
+ data->reg_num, &data->val_out);
+ else
+ ret = t4_mdio_wr(pi->adapter, 0, prtad, devad,
+ data->reg_num, data->val_in);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return ret;
+}
+
+static void cxgb_set_rxmode(struct net_device *dev)
+{
+ /* unfortunately we can't return errors to the stack */
+ set_rxmode(dev, -1, false);
+}
+
+static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
+{
+ int ret;
+ struct port_info *pi = netdev_priv(dev);
+
+ if (new_mtu < 81 || new_mtu > MAX_MTU) /* accommodate SACK */
+ return -EINVAL;
+ ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1,
+ true);
+ if (!ret)
+ dev->mtu = new_mtu;
+ return ret;
+}
+
+static int cxgb_set_mac_addr(struct net_device *dev, void *p)
+{
+ int ret;
+ struct sockaddr *addr = p;
+ struct port_info *pi = netdev_priv(dev);
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
+ ret = t4_change_mac(pi->adapter, 0, pi->viid, pi->xact_addr_filt,
+ addr->sa_data, true, true);
+ if (ret < 0)
+ return ret;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ pi->xact_addr_filt = ret;
+ return 0;
+}
+
+static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+ struct port_info *pi = netdev_priv(dev);
+
+ pi->vlan_grp = grp;
+ t4_set_vlan_accel(pi->adapter, 1 << pi->tx_chan, grp != NULL);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void cxgb_netpoll(struct net_device *dev)
+{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adap = pi->adapter;
+
+ if (adap->flags & USING_MSIX) {
+ int i;
+ struct sge_eth_rxq *rx = &adap->sge.ethrxq[pi->first_qset];
+
+ for (i = pi->nqsets; i; i--, rx++)
+ t4_sge_intr_msix(0, &rx->rspq);
+ } else
+ t4_intr_handler(adap)(0, adap);
+}
+#endif
+
+static const struct net_device_ops cxgb4_netdev_ops = {
+ .ndo_open = cxgb_open,
+ .ndo_stop = cxgb_close,
+ .ndo_start_xmit = t4_eth_xmit,
+ .ndo_get_stats = cxgb_get_stats,
+ .ndo_set_rx_mode = cxgb_set_rxmode,
+ .ndo_set_mac_address = cxgb_set_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = cxgb_ioctl,
+ .ndo_change_mtu = cxgb_change_mtu,
+ .ndo_vlan_rx_register = vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = cxgb_netpoll,
+#endif
+};
+
+void t4_fatal_err(struct adapter *adap)
+{
+ t4_set_reg_field(adap, SGE_CONTROL, GLOBALENABLE, 0);
+ t4_intr_disable(adap);
+ dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n");
+}
+
+static void setup_memwin(struct adapter *adap)
+{
+ u32 bar0;
+
+ bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */
+ t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0),
+ (bar0 + MEMWIN0_BASE) | BIR(0) |
+ WINDOW(ilog2(MEMWIN0_APERTURE) - 10));
+ t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 1),
+ (bar0 + MEMWIN1_BASE) | BIR(0) |
+ WINDOW(ilog2(MEMWIN1_APERTURE) - 10));
+ t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2),
+ (bar0 + MEMWIN2_BASE) | BIR(0) |
+ WINDOW(ilog2(MEMWIN2_APERTURE) - 10));
+}
+
+/*
+ * Max # of ATIDs. The absolute HW max is 16K but we keep it lower.
+ */
+#define MAX_ATIDS 8192U
+
+/*
+ * Phase 0 of initialization: contact FW, obtain config, perform basic init.
+ */
+static int adap_init0(struct adapter *adap)
+{
+ int ret;
+ u32 v, port_vec;
+ enum dev_state state;
+ u32 params[7], val[7];
+ struct fw_caps_config_cmd c;
+
+ ret = t4_check_fw_version(adap);
+ if (ret == -EINVAL || ret > 0) {
+ if (upgrade_fw(adap) >= 0) /* recache FW version */
+ ret = t4_check_fw_version(adap);
+ }
+ if (ret < 0)
+ return ret;
+
+ /* contact FW, request master */
+ ret = t4_fw_hello(adap, 0, 0, MASTER_MUST, &state);
+ if (ret < 0) {
+ dev_err(adap->pdev_dev, "could not connect to FW, error %d\n",
+ ret);
+ return ret;
+ }
+
+ /* reset device */
+ ret = t4_fw_reset(adap, 0, PIORSTMODE | PIORST);
+ if (ret < 0)
+ goto bye;
+
+ /* get device capabilities */
+ memset(&c, 0, sizeof(c));
+ c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+ FW_CMD_REQUEST | FW_CMD_READ);
+ c.retval_len16 = htonl(FW_LEN16(c));
+ ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+ if (ret < 0)
+ goto bye;
+
+ /* select capabilities we'll be using */
+ if (c.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) {
+ if (!vf_acls)
+ c.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM);
+ else
+ c.niccaps = htons(FW_CAPS_CONFIG_NIC_VM);
+ } else if (vf_acls) {
+ dev_err(adap->pdev_dev, "virtualization ACLs not supported");
+ goto bye;
+ }
+ c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+ FW_CMD_REQUEST | FW_CMD_WRITE);
+ ret = t4_wr_mbox(adap, 0, &c, sizeof(c), NULL);
+ if (ret < 0)
+ goto bye;
+
+ ret = t4_config_glbl_rss(adap, 0,
+ FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL,
+ FW_RSS_GLB_CONFIG_CMD_TNLMAPEN |
+ FW_RSS_GLB_CONFIG_CMD_TNLALLLKP);
+ if (ret < 0)
+ goto bye;
+
+ ret = t4_cfg_pfvf(adap, 0, 0, 0, 64, 64, 64, 0, 0, 4, 0xf, 0xf, 16,
+ FW_CMD_CAP_PF, FW_CMD_CAP_PF);
+ if (ret < 0)
+ goto bye;
+
+ for (v = 0; v < SGE_NTIMERS - 1; v++)
+ adap->sge.timer_val[v] = min(intr_holdoff[v], MAX_SGE_TIMERVAL);
+ adap->sge.timer_val[SGE_NTIMERS - 1] = MAX_SGE_TIMERVAL;
+ adap->sge.counter_val[0] = 1;
+ for (v = 1; v < SGE_NCOUNTERS; v++)
+ adap->sge.counter_val[v] = min(intr_cnt[v - 1],
+ THRESHOLD_3_MASK);
+ t4_sge_init(adap);
+
+ /* get basic stuff going */
+ ret = t4_early_init(adap, 0);
+ if (ret < 0)
+ goto bye;
+
+#define FW_PARAM_DEV(param) \
+ (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \
+ FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param))
+
+#define FW_PARAM_PFVF(param) \
+ (FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \
+ FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param))
+
+ params[0] = FW_PARAM_DEV(PORTVEC);
+ params[1] = FW_PARAM_PFVF(L2T_START);
+ params[2] = FW_PARAM_PFVF(L2T_END);
+ params[3] = FW_PARAM_PFVF(FILTER_START);
+ params[4] = FW_PARAM_PFVF(FILTER_END);
+ ret = t4_query_params(adap, 0, 0, 0, 5, params, val);
+ if (ret < 0)
+ goto bye;
+ port_vec = val[0];
+ adap->tids.ftid_base = val[3];
+ adap->tids.nftids = val[4] - val[3] + 1;
+
+ if (c.ofldcaps) {
+ /* query offload-related parameters */
+ params[0] = FW_PARAM_DEV(NTID);
+ params[1] = FW_PARAM_PFVF(SERVER_START);
+ params[2] = FW_PARAM_PFVF(SERVER_END);
+ params[3] = FW_PARAM_PFVF(TDDP_START);
+ params[4] = FW_PARAM_PFVF(TDDP_END);
+ params[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ);
+ ret = t4_query_params(adap, 0, 0, 0, 6, params, val);
+ if (ret < 0)
+ goto bye;
+ adap->tids.ntids = val[0];
+ adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS);
+ adap->tids.stid_base = val[1];
+ adap->tids.nstids = val[2] - val[1] + 1;
+ adap->vres.ddp.start = val[3];
+ adap->vres.ddp.size = val[4] - val[3] + 1;
+ adap->params.ofldq_wr_cred = val[5];
+ adap->params.offload = 1;
+ }
+ if (c.rdmacaps) {
+ params[0] = FW_PARAM_PFVF(STAG_START);
+ params[1] = FW_PARAM_PFVF(STAG_END);
+ params[2] = FW_PARAM_PFVF(RQ_START);
+ params[3] = FW_PARAM_PFVF(RQ_END);
+ params[4] = FW_PARAM_PFVF(PBL_START);
+ params[5] = FW_PARAM_PFVF(PBL_END);
+ ret = t4_query_params(adap, 0, 0, 0, 6, params, val);
+ if (ret < 0)
+ goto bye;
+ adap->vres.stag.start = val[0];
+ adap->vres.stag.size = val[1] - val[0] + 1;
+ adap->vres.rq.start = val[2];
+ adap->vres.rq.size = val[3] - val[2] + 1;
+ adap->vres.pbl.start = val[4];
+ adap->vres.pbl.size = val[5] - val[4] + 1;
+ }
+ if (c.iscsicaps) {
+ params[0] = FW_PARAM_PFVF(ISCSI_START);
+ params[1] = FW_PARAM_PFVF(ISCSI_END);
+ ret = t4_query_params(adap, 0, 0, 0, 2, params, val);
+ if (ret < 0)
+ goto bye;
+ adap->vres.iscsi.start = val[0];
+ adap->vres.iscsi.size = val[1] - val[0] + 1;
+ }
+#undef FW_PARAM_PFVF
+#undef FW_PARAM_DEV
+
+ adap->params.nports = hweight32(port_vec);
+ adap->params.portvec = port_vec;
+ adap->flags |= FW_OK;
+
+ /* These are finalized by FW initialization, load their values now */
+ v = t4_read_reg(adap, TP_TIMER_RESOLUTION);
+ adap->params.tp.tre = TIMERRESOLUTION_GET(v);
+ t4_read_mtu_tbl(adap, adap->params.mtus, NULL);
+ t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd,
+ adap->params.b_wnd);
+
+ /* tweak some settings */
+ t4_write_reg(adap, TP_SHIFT_CNT, 0x64f8849);
+ t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(PAGE_SHIFT - 12));
+ t4_write_reg(adap, TP_PIO_ADDR, TP_INGRESS_CONFIG);
+ v = t4_read_reg(adap, TP_PIO_DATA);
+ t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR);
+ setup_memwin(adap);
+ return 0;
+
+ /*
+ * If a command timed out or failed with EIO FW does not operate within
+ * its spec or something catastrophic happened to HW/FW, stop issuing
+ * commands.
+ */
+bye: if (ret != -ETIMEDOUT && ret != -EIO)
+ t4_fw_bye(adap, 0);
+ return ret;
+}
+
+static inline bool is_10g_port(const struct link_config *lc)
+{
+ return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0;
+}
+
+static inline void init_rspq(struct sge_rspq *q, u8 timer_idx, u8 pkt_cnt_idx,
+ unsigned int size, unsigned int iqe_size)
+{
+ q->intr_params = QINTR_TIMER_IDX(timer_idx) |
+ (pkt_cnt_idx < SGE_NCOUNTERS ? QINTR_CNT_EN : 0);
+ q->pktcnt_idx = pkt_cnt_idx < SGE_NCOUNTERS ? pkt_cnt_idx : 0;
+ q->iqe_len = iqe_size;
+ q->size = size;
+}
+
+/*
+ * Perform default configuration of DMA queues depending on the number and type
+ * of ports we found and the number of available CPUs. Most settings can be
+ * modified by the admin prior to actual use.
+ */
+static void __devinit cfg_queues(struct adapter *adap)
+{
+ struct sge *s = &adap->sge;
+ int i, q10g = 0, n10g = 0, qidx = 0;
+
+ for_each_port(adap, i)
+ n10g += is_10g_port(&adap2pinfo(adap, i)->link_cfg);
+
+ /*
+ * We default to 1 queue per non-10G port and up to # of cores queues
+ * per 10G port.
+ */
+ if (n10g)
+ q10g = (MAX_ETH_QSETS - (adap->params.nports - n10g)) / n10g;
+ if (q10g > num_online_cpus())
+ q10g = num_online_cpus();
+
+ for_each_port(adap, i) {
+ struct port_info *pi = adap2pinfo(adap, i);
+
+ pi->first_qset = qidx;
+ pi->nqsets = is_10g_port(&pi->link_cfg) ? q10g : 1;
+ qidx += pi->nqsets;
+ }
+
+ s->ethqsets = qidx;
+ s->max_ethqsets = qidx; /* MSI-X may lower it later */
+
+ if (is_offload(adap)) {
+ /*
+ * For offload we use 1 queue/channel if all ports are up to 1G,
+ * otherwise we divide all available queues amongst the channels
+ * capped by the number of available cores.
+ */
+ if (n10g) {
+ i = min_t(int, ARRAY_SIZE(s->ofldrxq),
+ num_online_cpus());
+ s->ofldqsets = roundup(i, adap->params.nports);
+ } else
+ s->ofldqsets = adap->params.nports;
+ /* For RDMA one Rx queue per channel suffices */
+ s->rdmaqs = adap->params.nports;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) {
+ struct sge_eth_rxq *r = &s->ethrxq[i];
+
+ init_rspq(&r->rspq, 0, 0, 1024, 64);
+ r->fl.size = 72;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(s->ethtxq); i++)
+ s->ethtxq[i].q.size = 1024;
+
+ for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++)
+ s->ctrlq[i].q.size = 512;
+
+ for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++)
+ s->ofldtxq[i].q.size = 1024;
+
+ for (i = 0; i < ARRAY_SIZE(s->ofldrxq); i++) {
+ struct sge_ofld_rxq *r = &s->ofldrxq[i];
+
+ init_rspq(&r->rspq, 0, 0, 1024, 64);
+ r->rspq.uld = CXGB4_ULD_ISCSI;
+ r->fl.size = 72;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(s->rdmarxq); i++) {
+ struct sge_ofld_rxq *r = &s->rdmarxq[i];
+
+ init_rspq(&r->rspq, 0, 0, 511, 64);
+ r->rspq.uld = CXGB4_ULD_RDMA;
+ r->fl.size = 72;
+ }
+
+ init_rspq(&s->fw_evtq, 6, 0, 512, 64);
+ init_rspq(&s->intrq, 6, 0, 2 * MAX_INGQ, 64);
+}
+
+/*
+ * Reduce the number of Ethernet queues across all ports to at most n.
+ * n provides at least one queue per port.
+ */
+static void __devinit reduce_ethqs(struct adapter *adap, int n)
+{
+ int i;
+ struct port_info *pi;
+
+ while (n < adap->sge.ethqsets)
+ for_each_port(adap, i) {
+ pi = adap2pinfo(adap, i);
+ if (pi->nqsets > 1) {
+ pi->nqsets--;
+ adap->sge.ethqsets--;
+ if (adap->sge.ethqsets <= n)
+ break;
+ }
+ }
+
+ n = 0;
+ for_each_port(adap, i) {
+ pi = adap2pinfo(adap, i);
+ pi->first_qset = n;
+ n += pi->nqsets;
+ }
+}
+
+/* 2 MSI-X vectors needed for the FW queue and non-data interrupts */
+#define EXTRA_VECS 2
+
+static int __devinit enable_msix(struct adapter *adap)
+{
+ int ofld_need = 0;
+ int i, err, want, need;
+ struct sge *s = &adap->sge;
+ unsigned int nchan = adap->params.nports;
+ struct msix_entry entries[MAX_INGQ + 1];
+
+ for (i = 0; i < ARRAY_SIZE(entries); ++i)
+ entries[i].entry = i;
+
+ want = s->max_ethqsets + EXTRA_VECS;
+ if (is_offload(adap)) {
+ want += s->rdmaqs + s->ofldqsets;
+ /* need nchan for each possible ULD */
+ ofld_need = 2 * nchan;
+ }
+ need = adap->params.nports + EXTRA_VECS + ofld_need;
+
+ while ((err = pci_enable_msix(adap->pdev, entries, want)) >= need)
+ want = err;
+
+ if (!err) {
+ /*
+ * Distribute available vectors to the various queue groups.
+ * Every group gets its minimum requirement and NIC gets top
+ * priority for leftovers.
+ */
+ i = want - EXTRA_VECS - ofld_need;
+ if (i < s->max_ethqsets) {
+ s->max_ethqsets = i;
+ if (i < s->ethqsets)
+ reduce_ethqs(adap, i);
+ }
+ if (is_offload(adap)) {
+ i = want - EXTRA_VECS - s->max_ethqsets;
+ i -= ofld_need - nchan;
+ s->ofldqsets = (i / nchan) * nchan; /* round down */
+ }
+ for (i = 0; i < want; ++i)
+ adap->msix_info[i].vec = entries[i].vector;
+ } else if (err > 0)
+ dev_info(adap->pdev_dev,
+ "only %d MSI-X vectors left, not using MSI-X\n", err);
+ return err;
+}
+
+#undef EXTRA_VECS
+
+static void __devinit print_port_info(struct adapter *adap)
+{
+ static const char *base[] = {
+ "R", "KX4", "T", "KX", "T", "KR", "CX4"
+ };
+
+ int i;
+ char buf[80];
+
+ for_each_port(adap, i) {
+ struct net_device *dev = adap->port[i];
+ const struct port_info *pi = netdev_priv(dev);
+ char *bufp = buf;
+
+ if (!test_bit(i, &adap->registered_device_map))
+ continue;
+
+ if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M)
+ bufp += sprintf(bufp, "100/");
+ if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)
+ bufp += sprintf(bufp, "1000/");
+ if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
+ bufp += sprintf(bufp, "10G/");
+ if (bufp != buf)
+ --bufp;
+ sprintf(bufp, "BASE-%s", base[pi->port_type]);
+
+ netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s\n",
+ adap->params.vpd.id, adap->params.rev,
+ buf, is_offload(adap) ? "R" : "",
+ adap->params.pci.width,
+ (adap->flags & USING_MSIX) ? " MSI-X" :
+ (adap->flags & USING_MSI) ? " MSI" : "");
+ if (adap->name == dev->name)
+ netdev_info(dev, "S/N: %s, E/C: %s\n",
+ adap->params.vpd.sn, adap->params.vpd.ec);
+ }
+}
+
+#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | NETIF_F_TSO6 |\
+ NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
+
+static int __devinit init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ int func, i, err;
+ struct port_info *pi;
+ unsigned int highdma = 0;
+ struct adapter *adapter = NULL;
+
+ printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
+
+ err = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (err) {
+ /* Just info, some other driver may have claimed the device. */
+ dev_info(&pdev->dev, "cannot obtain PCI resources\n");
+ return err;
+ }
+
+ /* We control everything through PF 0 */
+ func = PCI_FUNC(pdev->devfn);
+ if (func > 0)
+ goto sriov;
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
+ goto out_release_regions;
+ }
+
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ highdma = NETIF_F_HIGHDMA;
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ if (err) {
+ dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
+ "coherent allocations\n");
+ goto out_disable_device;
+ }
+ } else {
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (err) {
+ dev_err(&pdev->dev, "no usable DMA configuration\n");
+ goto out_disable_device;
+ }
+ }
+
+ pci_enable_pcie_error_reporting(pdev);
+ pci_set_master(pdev);
+ pci_save_state(pdev);
+
+ adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
+ if (!adapter) {
+ err = -ENOMEM;
+ goto out_disable_device;
+ }
+
+ adapter->regs = pci_ioremap_bar(pdev, 0);
+ if (!adapter->regs) {
+ dev_err(&pdev->dev, "cannot map device registers\n");
+ err = -ENOMEM;
+ goto out_free_adapter;
+ }
+
+ adapter->pdev = pdev;
+ adapter->pdev_dev = &pdev->dev;
+ adapter->name = pci_name(pdev);
+ adapter->msg_enable = dflt_msg_enable;
+ memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
+
+ spin_lock_init(&adapter->stats_lock);
+ spin_lock_init(&adapter->tid_release_lock);
+
+ INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
+
+ err = t4_prep_adapter(adapter);
+ if (err)
+ goto out_unmap_bar;
+ err = adap_init0(adapter);
+ if (err)
+ goto out_unmap_bar;
+
+ for_each_port(adapter, i) {
+ struct net_device *netdev;
+
+ netdev = alloc_etherdev_mq(sizeof(struct port_info),
+ MAX_ETH_QSETS);
+ if (!netdev) {
+ err = -ENOMEM;
+ goto out_free_dev;
+ }
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ adapter->port[i] = netdev;
+ pi = netdev_priv(netdev);
+ pi->adapter = adapter;
+ pi->xact_addr_filt = -1;
+ pi->rx_offload = RX_CSO;
+ pi->port_id = i;
+ netif_carrier_off(netdev);
+ netif_tx_stop_all_queues(netdev);
+ netdev->irq = pdev->irq;
+
+ netdev->features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6;
+ netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ netdev->features |= NETIF_F_GRO | highdma;
+ netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ netdev->vlan_features = netdev->features & VLAN_FEAT;
+
+ netdev->netdev_ops = &cxgb4_netdev_ops;
+ SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
+ }
+
+ pci_set_drvdata(pdev, adapter);
+
+ if (adapter->flags & FW_OK) {
+ err = t4_port_init(adapter, 0, 0, 0);
+ if (err)
+ goto out_free_dev;
+ }
+
+ /*
+ * Configure queues and allocate tables now, they can be needed as
+ * soon as the first register_netdev completes.
+ */
+ cfg_queues(adapter);
+
+ adapter->l2t = t4_init_l2t();
+ if (!adapter->l2t) {
+ /* We tolerate a lack of L2T, giving up some functionality */
+ dev_warn(&pdev->dev, "could not allocate L2T, continuing\n");
+ adapter->params.offload = 0;
+ }
+
+ if (is_offload(adapter) && tid_init(&adapter->tids) < 0) {
+ dev_warn(&pdev->dev, "could not allocate TID table, "
+ "continuing\n");
+ adapter->params.offload = 0;
+ }
+
+ /*
+ * The card is now ready to go. If any errors occur during device
+ * registration we do not fail the whole card but rather proceed only
+ * with the ports we manage to register successfully. However we must
+ * register at least one net device.
+ */
+ for_each_port(adapter, i) {
+ err = register_netdev(adapter->port[i]);
+ if (err)
+ dev_warn(&pdev->dev,
+ "cannot register net device %s, skipping\n",
+ adapter->port[i]->name);
+ else {
+ /*
+ * Change the name we use for messages to the name of
+ * the first successfully registered interface.
+ */
+ if (!adapter->registered_device_map)
+ adapter->name = adapter->port[i]->name;
+
+ __set_bit(i, &adapter->registered_device_map);
+ adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i;
+ }
+ }
+ if (!adapter->registered_device_map) {
+ dev_err(&pdev->dev, "could not register any net devices\n");
+ goto out_free_dev;
+ }
+
+ if (cxgb4_debugfs_root) {
+ adapter->debugfs_root = debugfs_create_dir(pci_name(pdev),
+ cxgb4_debugfs_root);
+ setup_debugfs(adapter);
+ }
+
+ /* See what interrupts we'll be using */
+ if (msi > 1 && enable_msix(adapter) == 0)
+ adapter->flags |= USING_MSIX;
+ else if (msi > 0 && pci_enable_msi(pdev) == 0)
+ adapter->flags |= USING_MSI;
+
+ if (is_offload(adapter))
+ attach_ulds(adapter);
+
+ print_port_info(adapter);
+
+sriov:
+#ifdef CONFIG_PCI_IOV
+ if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
+ if (pci_enable_sriov(pdev, num_vf[func]) == 0)
+ dev_info(&pdev->dev,
+ "instantiated %u virtual functions\n",
+ num_vf[func]);
+#endif
+ return 0;
+
+ out_free_dev:
+ t4_free_mem(adapter->tids.tid_tab);
+ t4_free_mem(adapter->l2t);
+ for_each_port(adapter, i)
+ if (adapter->port[i])
+ free_netdev(adapter->port[i]);
+ if (adapter->flags & FW_OK)
+ t4_fw_bye(adapter, 0);
+ out_unmap_bar:
+ iounmap(adapter->regs);
+ out_free_adapter:
+ kfree(adapter);
+ out_disable_device:
+ pci_disable_pcie_error_reporting(pdev);
+ pci_disable_device(pdev);
+ out_release_regions:
+ pci_release_regions(pdev);
+ pci_set_drvdata(pdev, NULL);
+ return err;
+}
+
+static void __devexit remove_one(struct pci_dev *pdev)
+{
+ struct adapter *adapter = pci_get_drvdata(pdev);
+
+ pci_disable_sriov(pdev);
+
+ if (adapter) {
+ int i;
+
+ if (is_offload(adapter))
+ detach_ulds(adapter);
+
+ for_each_port(adapter, i)
+ if (test_bit(i, &adapter->registered_device_map))
+ unregister_netdev(adapter->port[i]);
+
+ if (adapter->debugfs_root)
+ debugfs_remove_recursive(adapter->debugfs_root);
+
+ t4_sge_stop(adapter);
+ t4_free_sge_resources(adapter);
+ t4_free_mem(adapter->l2t);
+ t4_free_mem(adapter->tids.tid_tab);
+ disable_msi(adapter);
+
+ for_each_port(adapter, i)
+ if (adapter->port[i])
+ free_netdev(adapter->port[i]);
+
+ if (adapter->flags & FW_OK)
+ t4_fw_bye(adapter, 0);
+ iounmap(adapter->regs);
+ kfree(adapter);
+ pci_disable_pcie_error_reporting(pdev);
+ pci_disable_device(pdev);
+ pci_release_regions(pdev);
+ pci_set_drvdata(pdev, NULL);
+ } else if (PCI_FUNC(pdev->devfn) > 0)
+ pci_release_regions(pdev);
+}
+
+static struct pci_driver cxgb4_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = cxgb4_pci_tbl,
+ .probe = init_one,
+ .remove = __devexit_p(remove_one),
+};
+
+static int __init cxgb4_init_module(void)
+{
+ int ret;
+
+ /* Debugfs support is optional, just warn if this fails */
+ cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+ if (!cxgb4_debugfs_root)
+ pr_warning("could not create debugfs entry, continuing\n");
+
+ ret = pci_register_driver(&cxgb4_driver);
+ if (ret < 0)
+ debugfs_remove(cxgb4_debugfs_root);
+ return ret;
+}
+
+static void __exit cxgb4_cleanup_module(void)
+{
+ pci_unregister_driver(&cxgb4_driver);
+ debugfs_remove(cxgb4_debugfs_root); /* NULL ok */
+}
+
+module_init(cxgb4_init_module);
+module_exit(cxgb4_cleanup_module);
diff --git a/drivers/net/cxgb4/cxgb4_uld.h b/drivers/net/cxgb4/cxgb4_uld.h
new file mode 100644
index 00000000000..5b98546ac92
--- /dev/null
+++ b/drivers/net/cxgb4/cxgb4_uld.h
@@ -0,0 +1,239 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CXGB4_OFLD_H
+#define __CXGB4_OFLD_H
+
+#include <linux/cache.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <asm/atomic.h>
+
+/* CPL message priority levels */
+enum {
+ CPL_PRIORITY_DATA = 0, /* data messages */
+ CPL_PRIORITY_SETUP = 1, /* connection setup messages */
+ CPL_PRIORITY_TEARDOWN = 0, /* connection teardown messages */
+ CPL_PRIORITY_LISTEN = 1, /* listen start/stop messages */
+ CPL_PRIORITY_ACK = 1, /* RX ACK messages */
+ CPL_PRIORITY_CONTROL = 1 /* control messages */
+};
+
+#define INIT_TP_WR(w, tid) do { \
+ (w)->wr.wr_hi = htonl(FW_WR_OP(FW_TP_WR) | \
+ FW_WR_IMMDLEN(sizeof(*w) - sizeof(w->wr))); \
+ (w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*w), 16)) | \
+ FW_WR_FLOWID(tid)); \
+ (w)->wr.wr_lo = cpu_to_be64(0); \
+} while (0)
+
+#define INIT_TP_WR_CPL(w, cpl, tid) do { \
+ INIT_TP_WR(w, tid); \
+ OPCODE_TID(w) = htonl(MK_OPCODE_TID(cpl, tid)); \
+} while (0)
+
+#define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \
+ (w)->wr.wr_hi = htonl(FW_WR_OP(FW_ULPTX_WR) | FW_WR_ATOMIC(atomic)); \
+ (w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(wrlen, 16)) | \
+ FW_WR_FLOWID(tid)); \
+ (w)->wr.wr_lo = cpu_to_be64(0); \
+} while (0)
+
+/* Special asynchronous notification message */
+#define CXGB4_MSG_AN ((void *)1)
+
+struct serv_entry {
+ void *data;
+};
+
+union aopen_entry {
+ void *data;
+ union aopen_entry *next;
+};
+
+/*
+ * Holds the size, base address, free list start, etc of the TID, server TID,
+ * and active-open TID tables. The tables themselves are allocated dynamically.
+ */
+struct tid_info {
+ void **tid_tab;
+ unsigned int ntids;
+
+ struct serv_entry *stid_tab;
+ unsigned long *stid_bmap;
+ unsigned int nstids;
+ unsigned int stid_base;
+
+ union aopen_entry *atid_tab;
+ unsigned int natids;
+
+ unsigned int nftids;
+ unsigned int ftid_base;
+
+ spinlock_t atid_lock ____cacheline_aligned_in_smp;
+ union aopen_entry *afree;
+ unsigned int atids_in_use;
+
+ spinlock_t stid_lock;
+ unsigned int stids_in_use;
+
+ atomic_t tids_in_use;
+};
+
+static inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
+{
+ return tid < t->ntids ? t->tid_tab[tid] : NULL;
+}
+
+static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
+{
+ return atid < t->natids ? t->atid_tab[atid].data : NULL;
+}
+
+static inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
+{
+ stid -= t->stid_base;
+ return stid < t->nstids ? t->stid_tab[stid].data : NULL;
+}
+
+static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
+ unsigned int tid)
+{
+ t->tid_tab[tid] = data;
+ atomic_inc(&t->tids_in_use);
+}
+
+int cxgb4_alloc_atid(struct tid_info *t, void *data);
+int cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
+void cxgb4_free_atid(struct tid_info *t, unsigned int atid);
+void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
+void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid);
+void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
+ unsigned int tid);
+
+struct in6_addr;
+
+int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
+ __be32 sip, __be16 sport, unsigned int queue);
+int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
+ const struct in6_addr *sip, __be16 sport,
+ unsigned int queue);
+
+static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
+{
+ skb_set_queue_mapping(skb, (queue << 1) | prio);
+}
+
+enum cxgb4_uld {
+ CXGB4_ULD_RDMA,
+ CXGB4_ULD_ISCSI,
+ CXGB4_ULD_MAX
+};
+
+enum cxgb4_state {
+ CXGB4_STATE_UP,
+ CXGB4_STATE_START_RECOVERY,
+ CXGB4_STATE_DOWN,
+ CXGB4_STATE_DETACH
+};
+
+struct pci_dev;
+struct l2t_data;
+struct net_device;
+struct pkt_gl;
+struct tp_tcp_stats;
+
+struct cxgb4_range {
+ unsigned int start;
+ unsigned int size;
+};
+
+struct cxgb4_virt_res { /* virtualized HW resources */
+ struct cxgb4_range ddp;
+ struct cxgb4_range iscsi;
+ struct cxgb4_range stag;
+ struct cxgb4_range rq;
+ struct cxgb4_range pbl;
+};
+
+/*
+ * Block of information the LLD provides to ULDs attaching to a device.
+ */
+struct cxgb4_lld_info {
+ struct pci_dev *pdev; /* associated PCI device */
+ struct l2t_data *l2t; /* L2 table */
+ struct tid_info *tids; /* TID table */
+ struct net_device **ports; /* device ports */
+ const struct cxgb4_virt_res *vr; /* assorted HW resources */
+ const unsigned short *mtus; /* MTU table */
+ const unsigned short *rxq_ids; /* the ULD's Rx queue ids */
+ unsigned short nrxq; /* # of Rx queues */
+ unsigned short ntxq; /* # of Tx queues */
+ unsigned char nchan:4; /* # of channels */
+ unsigned char nports:4; /* # of ports */
+ unsigned char wr_cred; /* WR 16-byte credits */
+ unsigned char adapter_type; /* type of adapter */
+ unsigned char fw_api_ver; /* FW API version */
+ unsigned int fw_vers; /* FW version */
+ unsigned int iscsi_iolen; /* iSCSI max I/O length */
+ unsigned short udb_density; /* # of user DB/page */
+ unsigned short ucq_density; /* # of user CQs/page */
+ void __iomem *gts_reg; /* address of GTS register */
+ void __iomem *db_reg; /* address of kernel doorbell */
+};
+
+struct cxgb4_uld_info {
+ const char *name;
+ void *(*add)(const struct cxgb4_lld_info *p);
+ int (*rx_handler)(void *handle, const __be64 *rsp,
+ const struct pkt_gl *gl);
+ int (*state_change)(void *handle, enum cxgb4_state new_state);
+};
+
+int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
+int cxgb4_unregister_uld(enum cxgb4_uld type);
+int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
+unsigned int cxgb4_port_chan(const struct net_device *dev);
+unsigned int cxgb4_port_viid(const struct net_device *dev);
+unsigned int cxgb4_port_idx(const struct net_device *dev);
+struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id);
+unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
+ unsigned int *idx);
+void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
+ struct tp_tcp_stats *v6);
+void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
+ const unsigned int *pgsz_order);
+struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
+ unsigned int skb_len, unsigned int pull_len);
+#endif /* !__CXGB4_OFLD_H */
diff --git a/drivers/net/cxgb4/l2t.c b/drivers/net/cxgb4/l2t.c
new file mode 100644
index 00000000000..9f96724a133
--- /dev/null
+++ b/drivers/net/cxgb4/l2t.c
@@ -0,0 +1,624 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/if.h>
+#include <linux/if_vlan.h>
+#include <linux/jhash.h>
+#include <net/neighbour.h>
+#include "cxgb4.h"
+#include "l2t.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+
+#define VLAN_NONE 0xfff
+
+/* identifies sync vs async L2T_WRITE_REQs */
+#define F_SYNC_WR (1 << 12)
+
+enum {
+ L2T_STATE_VALID, /* entry is up to date */
+ L2T_STATE_STALE, /* entry may be used but needs revalidation */
+ L2T_STATE_RESOLVING, /* entry needs address resolution */
+ L2T_STATE_SYNC_WRITE, /* synchronous write of entry underway */
+
+ /* when state is one of the below the entry is not hashed */
+ L2T_STATE_SWITCHING, /* entry is being used by a switching filter */
+ L2T_STATE_UNUSED /* entry not in use */
+};
+
+struct l2t_data {
+ rwlock_t lock;
+ atomic_t nfree; /* number of free entries */
+ struct l2t_entry *rover; /* starting point for next allocation */
+ struct l2t_entry l2tab[L2T_SIZE];
+};
+
+static inline unsigned int vlan_prio(const struct l2t_entry *e)
+{
+ return e->vlan >> 13;
+}
+
+static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e)
+{
+ if (atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */
+ atomic_dec(&d->nfree);
+}
+
+/*
+ * To avoid having to check address families we do not allow v4 and v6
+ * neighbors to be on the same hash chain. We keep v4 entries in the first
+ * half of available hash buckets and v6 in the second.
+ */
+enum {
+ L2T_SZ_HALF = L2T_SIZE / 2,
+ L2T_HASH_MASK = L2T_SZ_HALF - 1
+};
+
+static inline unsigned int arp_hash(const u32 *key, int ifindex)
+{
+ return jhash_2words(*key, ifindex, 0) & L2T_HASH_MASK;
+}
+
+static inline unsigned int ipv6_hash(const u32 *key, int ifindex)
+{
+ u32 xor = key[0] ^ key[1] ^ key[2] ^ key[3];
+
+ return L2T_SZ_HALF + (jhash_2words(xor, ifindex, 0) & L2T_HASH_MASK);
+}
+
+static unsigned int addr_hash(const u32 *addr, int addr_len, int ifindex)
+{
+ return addr_len == 4 ? arp_hash(addr, ifindex) :
+ ipv6_hash(addr, ifindex);
+}
+
+/*
+ * Checks if an L2T entry is for the given IP/IPv6 address. It does not check
+ * whether the L2T entry and the address are of the same address family.
+ * Callers ensure an address is only checked against L2T entries of the same
+ * family, something made trivial by the separation of IP and IPv6 hash chains
+ * mentioned above. Returns 0 if there's a match,
+ */
+static int addreq(const struct l2t_entry *e, const u32 *addr)
+{
+ if (e->v6)
+ return (e->addr[0] ^ addr[0]) | (e->addr[1] ^ addr[1]) |
+ (e->addr[2] ^ addr[2]) | (e->addr[3] ^ addr[3]);
+ return e->addr[0] ^ addr[0];
+}
+
+static void neigh_replace(struct l2t_entry *e, struct neighbour *n)
+{
+ neigh_hold(n);
+ if (e->neigh)
+ neigh_release(e->neigh);
+ e->neigh = n;
+}
+
+/*
+ * Write an L2T entry. Must be called with the entry locked.
+ * The write may be synchronous or asynchronous.
+ */
+static int write_l2e(struct adapter *adap, struct l2t_entry *e, int sync)
+{
+ struct sk_buff *skb;
+ struct cpl_l2t_write_req *req;
+
+ skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
+ INIT_TP_WR(req, 0);
+
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ,
+ e->idx | (sync ? F_SYNC_WR : 0) |
+ TID_QID(adap->sge.fw_evtq.abs_id)));
+ req->params = htons(L2T_W_PORT(e->lport) | L2T_W_NOREPLY(!sync));
+ req->l2t_idx = htons(e->idx);
+ req->vlan = htons(e->vlan);
+ if (e->neigh)
+ memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac));
+ memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
+
+ set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
+ t4_ofld_send(adap, skb);
+
+ if (sync && e->state != L2T_STATE_SWITCHING)
+ e->state = L2T_STATE_SYNC_WRITE;
+ return 0;
+}
+
+/*
+ * Send packets waiting in an L2T entry's ARP queue. Must be called with the
+ * entry locked.
+ */
+static void send_pending(struct adapter *adap, struct l2t_entry *e)
+{
+ while (e->arpq_head) {
+ struct sk_buff *skb = e->arpq_head;
+
+ e->arpq_head = skb->next;
+ skb->next = NULL;
+ t4_ofld_send(adap, skb);
+ }
+ e->arpq_tail = NULL;
+}
+
+/*
+ * Process a CPL_L2T_WRITE_RPL. Wake up the ARP queue if it completes a
+ * synchronous L2T_WRITE. Note that the TID in the reply is really the L2T
+ * index it refers to.
+ */
+void do_l2t_write_rpl(struct adapter *adap, const struct cpl_l2t_write_rpl *rpl)
+{
+ unsigned int tid = GET_TID(rpl);
+ unsigned int idx = tid & (L2T_SIZE - 1);
+
+ if (unlikely(rpl->status != CPL_ERR_NONE)) {
+ dev_err(adap->pdev_dev,
+ "Unexpected L2T_WRITE_RPL status %u for entry %u\n",
+ rpl->status, idx);
+ return;
+ }
+
+ if (tid & F_SYNC_WR) {
+ struct l2t_entry *e = &adap->l2t->l2tab[idx];
+
+ spin_lock(&e->lock);
+ if (e->state != L2T_STATE_SWITCHING) {
+ send_pending(adap, e);
+ e->state = (e->neigh->nud_state & NUD_STALE) ?
+ L2T_STATE_STALE : L2T_STATE_VALID;
+ }
+ spin_unlock(&e->lock);
+ }
+}
+
+/*
+ * Add a packet to an L2T entry's queue of packets awaiting resolution.
+ * Must be called with the entry's lock held.
+ */
+static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb)
+{
+ skb->next = NULL;
+ if (e->arpq_head)
+ e->arpq_tail->next = skb;
+ else
+ e->arpq_head = skb;
+ e->arpq_tail = skb;
+}
+
+int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb,
+ struct l2t_entry *e)
+{
+ struct adapter *adap = netdev2adap(dev);
+
+again:
+ switch (e->state) {
+ case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
+ neigh_event_send(e->neigh, NULL);
+ spin_lock_bh(&e->lock);
+ if (e->state == L2T_STATE_STALE)
+ e->state = L2T_STATE_VALID;
+ spin_unlock_bh(&e->lock);
+ case L2T_STATE_VALID: /* fast-path, send the packet on */
+ return t4_ofld_send(adap, skb);
+ case L2T_STATE_RESOLVING:
+ case L2T_STATE_SYNC_WRITE:
+ spin_lock_bh(&e->lock);
+ if (e->state != L2T_STATE_SYNC_WRITE &&
+ e->state != L2T_STATE_RESOLVING) {
+ spin_unlock_bh(&e->lock);
+ goto again;
+ }
+ arpq_enqueue(e, skb);
+ spin_unlock_bh(&e->lock);
+
+ if (e->state == L2T_STATE_RESOLVING &&
+ !neigh_event_send(e->neigh, NULL)) {
+ spin_lock_bh(&e->lock);
+ if (e->state == L2T_STATE_RESOLVING && e->arpq_head)
+ write_l2e(adap, e, 1);
+ spin_unlock_bh(&e->lock);
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(cxgb4_l2t_send);
+
+/*
+ * Allocate a free L2T entry. Must be called with l2t_data.lock held.
+ */
+static struct l2t_entry *alloc_l2e(struct l2t_data *d)
+{
+ struct l2t_entry *end, *e, **p;
+
+ if (!atomic_read(&d->nfree))
+ return NULL;
+
+ /* there's definitely a free entry */
+ for (e = d->rover, end = &d->l2tab[L2T_SIZE]; e != end; ++e)
+ if (atomic_read(&e->refcnt) == 0)
+ goto found;
+
+ for (e = d->l2tab; atomic_read(&e->refcnt); ++e)
+ ;
+found:
+ d->rover = e + 1;
+ atomic_dec(&d->nfree);
+
+ /*
+ * The entry we found may be an inactive entry that is
+ * presently in the hash table. We need to remove it.
+ */
+ if (e->state < L2T_STATE_SWITCHING)
+ for (p = &d->l2tab[e->hash].first; *p; p = &(*p)->next)
+ if (*p == e) {
+ *p = e->next;
+ e->next = NULL;
+ break;
+ }
+
+ e->state = L2T_STATE_UNUSED;
+ return e;
+}
+
+/*
+ * Called when an L2T entry has no more users.
+ */
+static void t4_l2e_free(struct l2t_entry *e)
+{
+ struct l2t_data *d;
+
+ spin_lock_bh(&e->lock);
+ if (atomic_read(&e->refcnt) == 0) { /* hasn't been recycled */
+ if (e->neigh) {
+ neigh_release(e->neigh);
+ e->neigh = NULL;
+ }
+ }
+ spin_unlock_bh(&e->lock);
+
+ d = container_of(e, struct l2t_data, l2tab[e->idx]);
+ atomic_inc(&d->nfree);
+}
+
+void cxgb4_l2t_release(struct l2t_entry *e)
+{
+ if (atomic_dec_and_test(&e->refcnt))
+ t4_l2e_free(e);
+}
+EXPORT_SYMBOL(cxgb4_l2t_release);
+
+/*
+ * Update an L2T entry that was previously used for the same next hop as neigh.
+ * Must be called with softirqs disabled.
+ */
+static void reuse_entry(struct l2t_entry *e, struct neighbour *neigh)
+{
+ unsigned int nud_state;
+
+ spin_lock(&e->lock); /* avoid race with t4_l2t_free */
+ if (neigh != e->neigh)
+ neigh_replace(e, neigh);
+ nud_state = neigh->nud_state;
+ if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac)) ||
+ !(nud_state & NUD_VALID))
+ e->state = L2T_STATE_RESOLVING;
+ else if (nud_state & NUD_CONNECTED)
+ e->state = L2T_STATE_VALID;
+ else
+ e->state = L2T_STATE_STALE;
+ spin_unlock(&e->lock);
+}
+
+struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
+ const struct net_device *physdev,
+ unsigned int priority)
+{
+ u8 lport;
+ u16 vlan;
+ struct l2t_entry *e;
+ int addr_len = neigh->tbl->key_len;
+ u32 *addr = (u32 *)neigh->primary_key;
+ int ifidx = neigh->dev->ifindex;
+ int hash = addr_hash(addr, addr_len, ifidx);
+
+ if (neigh->dev->flags & IFF_LOOPBACK)
+ lport = netdev2pinfo(physdev)->tx_chan + 4;
+ else
+ lport = netdev2pinfo(physdev)->lport;
+
+ if (neigh->dev->priv_flags & IFF_802_1Q_VLAN)
+ vlan = vlan_dev_vlan_id(neigh->dev);
+ else
+ vlan = VLAN_NONE;
+
+ write_lock_bh(&d->lock);
+ for (e = d->l2tab[hash].first; e; e = e->next)
+ if (!addreq(e, addr) && e->ifindex == ifidx &&
+ e->vlan == vlan && e->lport == lport) {
+ l2t_hold(d, e);
+ if (atomic_read(&e->refcnt) == 1)
+ reuse_entry(e, neigh);
+ goto done;
+ }
+
+ /* Need to allocate a new entry */
+ e = alloc_l2e(d);
+ if (e) {
+ spin_lock(&e->lock); /* avoid race with t4_l2t_free */
+ e->state = L2T_STATE_RESOLVING;
+ memcpy(e->addr, addr, addr_len);
+ e->ifindex = ifidx;
+ e->hash = hash;
+ e->lport = lport;
+ e->v6 = addr_len == 16;
+ atomic_set(&e->refcnt, 1);
+ neigh_replace(e, neigh);
+ e->vlan = vlan;
+ e->next = d->l2tab[hash].first;
+ d->l2tab[hash].first = e;
+ spin_unlock(&e->lock);
+ }
+done:
+ write_unlock_bh(&d->lock);
+ return e;
+}
+EXPORT_SYMBOL(cxgb4_l2t_get);
+
+/*
+ * Called when address resolution fails for an L2T entry to handle packets
+ * on the arpq head. If a packet specifies a failure handler it is invoked,
+ * otherwise the packet is sent to the device.
+ */
+static void handle_failed_resolution(struct adapter *adap, struct sk_buff *arpq)
+{
+ while (arpq) {
+ struct sk_buff *skb = arpq;
+ const struct l2t_skb_cb *cb = L2T_SKB_CB(skb);
+
+ arpq = skb->next;
+ skb->next = NULL;
+ if (cb->arp_err_handler)
+ cb->arp_err_handler(cb->handle, skb);
+ else
+ t4_ofld_send(adap, skb);
+ }
+}
+
+/*
+ * Called when the host's neighbor layer makes a change to some entry that is
+ * loaded into the HW L2 table.
+ */
+void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
+{
+ struct l2t_entry *e;
+ struct sk_buff *arpq = NULL;
+ struct l2t_data *d = adap->l2t;
+ int addr_len = neigh->tbl->key_len;
+ u32 *addr = (u32 *) neigh->primary_key;
+ int ifidx = neigh->dev->ifindex;
+ int hash = addr_hash(addr, addr_len, ifidx);
+
+ read_lock_bh(&d->lock);
+ for (e = d->l2tab[hash].first; e; e = e->next)
+ if (!addreq(e, addr) && e->ifindex == ifidx) {
+ spin_lock(&e->lock);
+ if (atomic_read(&e->refcnt))
+ goto found;
+ spin_unlock(&e->lock);
+ break;
+ }
+ read_unlock_bh(&d->lock);
+ return;
+
+ found:
+ read_unlock(&d->lock);
+
+ if (neigh != e->neigh)
+ neigh_replace(e, neigh);
+
+ if (e->state == L2T_STATE_RESOLVING) {
+ if (neigh->nud_state & NUD_FAILED) {
+ arpq = e->arpq_head;
+ e->arpq_head = e->arpq_tail = NULL;
+ } else if ((neigh->nud_state & (NUD_CONNECTED | NUD_STALE)) &&
+ e->arpq_head) {
+ write_l2e(adap, e, 1);
+ }
+ } else {
+ e->state = neigh->nud_state & NUD_CONNECTED ?
+ L2T_STATE_VALID : L2T_STATE_STALE;
+ if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac)))
+ write_l2e(adap, e, 0);
+ }
+
+ spin_unlock_bh(&e->lock);
+
+ if (arpq)
+ handle_failed_resolution(adap, arpq);
+}
+
+/*
+ * Allocate an L2T entry for use by a switching rule. Such entries need to be
+ * explicitly freed and while busy they are not on any hash chain, so normal
+ * address resolution updates do not see them.
+ */
+struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d)
+{
+ struct l2t_entry *e;
+
+ write_lock_bh(&d->lock);
+ e = alloc_l2e(d);
+ if (e) {
+ spin_lock(&e->lock); /* avoid race with t4_l2t_free */
+ e->state = L2T_STATE_SWITCHING;
+ atomic_set(&e->refcnt, 1);
+ spin_unlock(&e->lock);
+ }
+ write_unlock_bh(&d->lock);
+ return e;
+}
+
+/*
+ * Sets/updates the contents of a switching L2T entry that has been allocated
+ * with an earlier call to @t4_l2t_alloc_switching.
+ */
+int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
+ u8 port, u8 *eth_addr)
+{
+ e->vlan = vlan;
+ e->lport = port;
+ memcpy(e->dmac, eth_addr, ETH_ALEN);
+ return write_l2e(adap, e, 0);
+}
+
+struct l2t_data *t4_init_l2t(void)
+{
+ int i;
+ struct l2t_data *d;
+
+ d = t4_alloc_mem(sizeof(*d));
+ if (!d)
+ return NULL;
+
+ d->rover = d->l2tab;
+ atomic_set(&d->nfree, L2T_SIZE);
+ rwlock_init(&d->lock);
+
+ for (i = 0; i < L2T_SIZE; ++i) {
+ d->l2tab[i].idx = i;
+ d->l2tab[i].state = L2T_STATE_UNUSED;
+ spin_lock_init(&d->l2tab[i].lock);
+ atomic_set(&d->l2tab[i].refcnt, 0);
+ }
+ return d;
+}
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static inline void *l2t_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct l2t_entry *l2tab = seq->private;
+
+ return pos >= L2T_SIZE ? NULL : &l2tab[pos];
+}
+
+static void *l2t_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ return *pos ? l2t_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ v = l2t_get_idx(seq, *pos);
+ if (v)
+ ++*pos;
+ return v;
+}
+
+static void l2t_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+static char l2e_state(const struct l2t_entry *e)
+{
+ switch (e->state) {
+ case L2T_STATE_VALID: return 'V';
+ case L2T_STATE_STALE: return 'S';
+ case L2T_STATE_SYNC_WRITE: return 'W';
+ case L2T_STATE_RESOLVING: return e->arpq_head ? 'A' : 'R';
+ case L2T_STATE_SWITCHING: return 'X';
+ default:
+ return 'U';
+ }
+}
+
+static int l2t_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, " Idx IP address "
+ "Ethernet address VLAN/P LP State Users Port\n");
+ else {
+ char ip[60];
+ struct l2t_entry *e = v;
+
+ spin_lock_bh(&e->lock);
+ if (e->state == L2T_STATE_SWITCHING)
+ ip[0] = '\0';
+ else
+ sprintf(ip, e->v6 ? "%pI6c" : "%pI4", e->addr);
+ seq_printf(seq, "%4u %-25s %17pM %4d %u %2u %c %5u %s\n",
+ e->idx, ip, e->dmac,
+ e->vlan & VLAN_VID_MASK, vlan_prio(e), e->lport,
+ l2e_state(e), atomic_read(&e->refcnt),
+ e->neigh ? e->neigh->dev->name : "");
+ spin_unlock_bh(&e->lock);
+ }
+ return 0;
+}
+
+static const struct seq_operations l2t_seq_ops = {
+ .start = l2t_seq_start,
+ .next = l2t_seq_next,
+ .stop = l2t_seq_stop,
+ .show = l2t_seq_show
+};
+
+static int l2t_seq_open(struct inode *inode, struct file *file)
+{
+ int rc = seq_open(file, &l2t_seq_ops);
+
+ if (!rc) {
+ struct adapter *adap = inode->i_private;
+ struct seq_file *seq = file->private_data;
+
+ seq->private = adap->l2t->l2tab;
+ }
+ return rc;
+}
+
+const struct file_operations t4_l2t_fops = {
+ .owner = THIS_MODULE,
+ .open = l2t_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
diff --git a/drivers/net/cxgb4/l2t.h b/drivers/net/cxgb4/l2t.h
new file mode 100644
index 00000000000..643f27ed3cf
--- /dev/null
+++ b/drivers/net/cxgb4/l2t.h
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CXGB4_L2T_H
+#define __CXGB4_L2T_H
+
+#include <linux/spinlock.h>
+#include <linux/if_ether.h>
+#include <asm/atomic.h>
+
+struct adapter;
+struct l2t_data;
+struct neighbour;
+struct net_device;
+struct file_operations;
+struct cpl_l2t_write_rpl;
+
+/*
+ * Each L2T entry plays multiple roles. First of all, it keeps state for the
+ * corresponding entry of the HW L2 table and maintains a queue of offload
+ * packets awaiting address resolution. Second, it is a node of a hash table
+ * chain, where the nodes of the chain are linked together through their next
+ * pointer. Finally, each node is a bucket of a hash table, pointing to the
+ * first element in its chain through its first pointer.
+ */
+struct l2t_entry {
+ u16 state; /* entry state */
+ u16 idx; /* entry index */
+ u32 addr[4]; /* next hop IP or IPv6 address */
+ int ifindex; /* neighbor's net_device's ifindex */
+ struct neighbour *neigh; /* associated neighbour */
+ struct l2t_entry *first; /* start of hash chain */
+ struct l2t_entry *next; /* next l2t_entry on chain */
+ struct sk_buff *arpq_head; /* queue of packets awaiting resolution */
+ struct sk_buff *arpq_tail;
+ spinlock_t lock;
+ atomic_t refcnt; /* entry reference count */
+ u16 hash; /* hash bucket the entry is on */
+ u16 vlan; /* VLAN TCI (id: bits 0-11, prio: 13-15 */
+ u8 v6; /* whether entry is for IPv6 */
+ u8 lport; /* associated offload logical interface */
+ u8 dmac[ETH_ALEN]; /* neighbour's MAC address */
+};
+
+typedef void (*arp_err_handler_t)(void *handle, struct sk_buff *skb);
+
+/*
+ * Callback stored in an skb to handle address resolution failure.
+ */
+struct l2t_skb_cb {
+ void *handle;
+ arp_err_handler_t arp_err_handler;
+};
+
+#define L2T_SKB_CB(skb) ((struct l2t_skb_cb *)(skb)->cb)
+
+static inline void t4_set_arp_err_handler(struct sk_buff *skb, void *handle,
+ arp_err_handler_t handler)
+{
+ L2T_SKB_CB(skb)->handle = handle;
+ L2T_SKB_CB(skb)->arp_err_handler = handler;
+}
+
+void cxgb4_l2t_release(struct l2t_entry *e);
+int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb,
+ struct l2t_entry *e);
+struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
+ const struct net_device *physdev,
+ unsigned int priority);
+
+void t4_l2t_update(struct adapter *adap, struct neighbour *neigh);
+struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d);
+int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
+ u8 port, u8 *eth_addr);
+struct l2t_data *t4_init_l2t(void);
+void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl);
+
+extern const struct file_operations t4_l2t_fops;
+#endif /* __CXGB4_L2T_H */
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c
new file mode 100644
index 00000000000..14adc58e71c
--- /dev/null
+++ b/drivers/net/cxgb4/sge.c
@@ -0,0 +1,2431 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/ip.h>
+#include <linux/dma-mapping.h>
+#include <linux/jiffies.h>
+#include <net/ipv6.h>
+#include <net/tcp.h>
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+
+/*
+ * Rx buffer size. We use largish buffers if possible but settle for single
+ * pages under memory shortage.
+ */
+#if PAGE_SHIFT >= 16
+# define FL_PG_ORDER 0
+#else
+# define FL_PG_ORDER (16 - PAGE_SHIFT)
+#endif
+
+/* RX_PULL_LEN should be <= RX_COPY_THRES */
+#define RX_COPY_THRES 256
+#define RX_PULL_LEN 128
+
+/*
+ * Main body length for sk_buffs used for Rx Ethernet packets with fragments.
+ * Should be >= RX_PULL_LEN but possibly bigger to give pskb_may_pull some room.
+ */
+#define RX_PKT_SKB_LEN 512
+
+/* Ethernet header padding prepended to RX_PKTs */
+#define RX_PKT_PAD 2
+
+/*
+ * Max number of Tx descriptors we clean up at a time. Should be modest as
+ * freeing skbs isn't cheap and it happens while holding locks. We just need
+ * to free packets faster than they arrive, we eventually catch up and keep
+ * the amortized cost reasonable. Must be >= 2 * TXQ_STOP_THRES.
+ */
+#define MAX_TX_RECLAIM 16
+
+/*
+ * Max number of Rx buffers we replenish at a time. Again keep this modest,
+ * allocating buffers isn't cheap either.
+ */
+#define MAX_RX_REFILL 16U
+
+/*
+ * Period of the Rx queue check timer. This timer is infrequent as it has
+ * something to do only when the system experiences severe memory shortage.
+ */
+#define RX_QCHECK_PERIOD (HZ / 2)
+
+/*
+ * Period of the Tx queue check timer.
+ */
+#define TX_QCHECK_PERIOD (HZ / 2)
+
+/*
+ * Max number of Tx descriptors to be reclaimed by the Tx timer.
+ */
+#define MAX_TIMER_TX_RECLAIM 100
+
+/*
+ * Timer index used when backing off due to memory shortage.
+ */
+#define NOMEM_TMR_IDX (SGE_NTIMERS - 1)
+
+/*
+ * An FL with <= FL_STARVE_THRES buffers is starving and a periodic timer will
+ * attempt to refill it.
+ */
+#define FL_STARVE_THRES 4
+
+/*
+ * Suspend an Ethernet Tx queue with fewer available descriptors than this.
+ * This is the same as calc_tx_descs() for a TSO packet with
+ * nr_frags == MAX_SKB_FRAGS.
+ */
+#define ETHTXQ_STOP_THRES \
+ (1 + DIV_ROUND_UP((3 * MAX_SKB_FRAGS) / 2 + (MAX_SKB_FRAGS & 1), 8))
+
+/*
+ * Suspension threshold for non-Ethernet Tx queues. We require enough room
+ * for a full sized WR.
+ */
+#define TXQ_STOP_THRES (SGE_MAX_WR_LEN / sizeof(struct tx_desc))
+
+/*
+ * Max Tx descriptor space we allow for an Ethernet packet to be inlined
+ * into a WR.
+ */
+#define MAX_IMM_TX_PKT_LEN 128
+
+/*
+ * Max size of a WR sent through a control Tx queue.
+ */
+#define MAX_CTRL_WR_LEN SGE_MAX_WR_LEN
+
+enum {
+ /* packet alignment in FL buffers */
+ FL_ALIGN = L1_CACHE_BYTES < 32 ? 32 : L1_CACHE_BYTES,
+ /* egress status entry size */
+ STAT_LEN = L1_CACHE_BYTES > 64 ? 128 : 64
+};
+
+struct tx_sw_desc { /* SW state per Tx descriptor */
+ struct sk_buff *skb;
+ struct ulptx_sgl *sgl;
+};
+
+struct rx_sw_desc { /* SW state per Rx descriptor */
+ struct page *page;
+ dma_addr_t dma_addr;
+};
+
+/*
+ * The low bits of rx_sw_desc.dma_addr have special meaning.
+ */
+enum {
+ RX_LARGE_BUF = 1 << 0, /* buffer is larger than PAGE_SIZE */
+ RX_UNMAPPED_BUF = 1 << 1, /* buffer is not mapped */
+};
+
+static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *d)
+{
+ return d->dma_addr & ~(dma_addr_t)(RX_LARGE_BUF | RX_UNMAPPED_BUF);
+}
+
+static inline bool is_buf_mapped(const struct rx_sw_desc *d)
+{
+ return !(d->dma_addr & RX_UNMAPPED_BUF);
+}
+
+/**
+ * txq_avail - return the number of available slots in a Tx queue
+ * @q: the Tx queue
+ *
+ * Returns the number of descriptors in a Tx queue available to write new
+ * packets.
+ */
+static inline unsigned int txq_avail(const struct sge_txq *q)
+{
+ return q->size - 1 - q->in_use;
+}
+
+/**
+ * fl_cap - return the capacity of a free-buffer list
+ * @fl: the FL
+ *
+ * Returns the capacity of a free-buffer list. The capacity is less than
+ * the size because one descriptor needs to be left unpopulated, otherwise
+ * HW will think the FL is empty.
+ */
+static inline unsigned int fl_cap(const struct sge_fl *fl)
+{
+ return fl->size - 8; /* 1 descriptor = 8 buffers */
+}
+
+static inline bool fl_starving(const struct sge_fl *fl)
+{
+ return fl->avail - fl->pend_cred <= FL_STARVE_THRES;
+}
+
+static int map_skb(struct device *dev, const struct sk_buff *skb,
+ dma_addr_t *addr)
+{
+ const skb_frag_t *fp, *end;
+ const struct skb_shared_info *si;
+
+ *addr = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
+ if (dma_mapping_error(dev, *addr))
+ goto out_err;
+
+ si = skb_shinfo(skb);
+ end = &si->frags[si->nr_frags];
+
+ for (fp = si->frags; fp < end; fp++) {
+ *++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dev, *addr))
+ goto unwind;
+ }
+ return 0;
+
+unwind:
+ while (fp-- > si->frags)
+ dma_unmap_page(dev, *--addr, fp->size, DMA_TO_DEVICE);
+
+ dma_unmap_single(dev, addr[-1], skb_headlen(skb), DMA_TO_DEVICE);
+out_err:
+ return -ENOMEM;
+}
+
+#ifdef CONFIG_NEED_DMA_MAP_STATE
+static void unmap_skb(struct device *dev, const struct sk_buff *skb,
+ const dma_addr_t *addr)
+{
+ const skb_frag_t *fp, *end;
+ const struct skb_shared_info *si;
+
+ dma_unmap_single(dev, *addr++, skb_headlen(skb), DMA_TO_DEVICE);
+
+ si = skb_shinfo(skb);
+ end = &si->frags[si->nr_frags];
+ for (fp = si->frags; fp < end; fp++)
+ dma_unmap_page(dev, *addr++, fp->size, DMA_TO_DEVICE);
+}
+
+/**
+ * deferred_unmap_destructor - unmap a packet when it is freed
+ * @skb: the packet
+ *
+ * This is the packet destructor used for Tx packets that need to remain
+ * mapped until they are freed rather than until their Tx descriptors are
+ * freed.
+ */
+static void deferred_unmap_destructor(struct sk_buff *skb)
+{
+ unmap_skb(skb->dev->dev.parent, skb, (dma_addr_t *)skb->head);
+}
+#endif
+
+static void unmap_sgl(struct device *dev, const struct sk_buff *skb,
+ const struct ulptx_sgl *sgl, const struct sge_txq *q)
+{
+ const struct ulptx_sge_pair *p;
+ unsigned int nfrags = skb_shinfo(skb)->nr_frags;
+
+ if (likely(skb_headlen(skb)))
+ dma_unmap_single(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0),
+ DMA_TO_DEVICE);
+ else {
+ dma_unmap_page(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0),
+ DMA_TO_DEVICE);
+ nfrags--;
+ }
+
+ /*
+ * the complexity below is because of the possibility of a wrap-around
+ * in the middle of an SGL
+ */
+ for (p = sgl->sge; nfrags >= 2; nfrags -= 2) {
+ if (likely((u8 *)(p + 1) <= (u8 *)q->stat)) {
+unmap: dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
+ ntohl(p->len[0]), DMA_TO_DEVICE);
+ dma_unmap_page(dev, be64_to_cpu(p->addr[1]),
+ ntohl(p->len[1]), DMA_TO_DEVICE);
+ p++;
+ } else if ((u8 *)p == (u8 *)q->stat) {
+ p = (const struct ulptx_sge_pair *)q->desc;
+ goto unmap;
+ } else if ((u8 *)p + 8 == (u8 *)q->stat) {
+ const __be64 *addr = (const __be64 *)q->desc;
+
+ dma_unmap_page(dev, be64_to_cpu(addr[0]),
+ ntohl(p->len[0]), DMA_TO_DEVICE);
+ dma_unmap_page(dev, be64_to_cpu(addr[1]),
+ ntohl(p->len[1]), DMA_TO_DEVICE);
+ p = (const struct ulptx_sge_pair *)&addr[2];
+ } else {
+ const __be64 *addr = (const __be64 *)q->desc;
+
+ dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
+ ntohl(p->len[0]), DMA_TO_DEVICE);
+ dma_unmap_page(dev, be64_to_cpu(addr[0]),
+ ntohl(p->len[1]), DMA_TO_DEVICE);
+ p = (const struct ulptx_sge_pair *)&addr[1];
+ }
+ }
+ if (nfrags) {
+ __be64 addr;
+
+ if ((u8 *)p == (u8 *)q->stat)
+ p = (const struct ulptx_sge_pair *)q->desc;
+ addr = (u8 *)p + 16 <= (u8 *)q->stat ? p->addr[0] :
+ *(const __be64 *)q->desc;
+ dma_unmap_page(dev, be64_to_cpu(addr), ntohl(p->len[0]),
+ DMA_TO_DEVICE);
+ }
+}
+
+/**
+ * free_tx_desc - reclaims Tx descriptors and their buffers
+ * @adapter: the adapter
+ * @q: the Tx queue to reclaim descriptors from
+ * @n: the number of descriptors to reclaim
+ * @unmap: whether the buffers should be unmapped for DMA
+ *
+ * Reclaims Tx descriptors from an SGE Tx queue and frees the associated
+ * Tx buffers. Called with the Tx queue lock held.
+ */
+static void free_tx_desc(struct adapter *adap, struct sge_txq *q,
+ unsigned int n, bool unmap)
+{
+ struct tx_sw_desc *d;
+ unsigned int cidx = q->cidx;
+ struct device *dev = adap->pdev_dev;
+
+ d = &q->sdesc[cidx];
+ while (n--) {
+ if (d->skb) { /* an SGL is present */
+ if (unmap)
+ unmap_sgl(dev, d->skb, d->sgl, q);
+ kfree_skb(d->skb);
+ d->skb = NULL;
+ }
+ ++d;
+ if (++cidx == q->size) {
+ cidx = 0;
+ d = q->sdesc;
+ }
+ }
+ q->cidx = cidx;
+}
+
+/*
+ * Return the number of reclaimable descriptors in a Tx queue.
+ */
+static inline int reclaimable(const struct sge_txq *q)
+{
+ int hw_cidx = ntohs(q->stat->cidx);
+ hw_cidx -= q->cidx;
+ return hw_cidx < 0 ? hw_cidx + q->size : hw_cidx;
+}
+
+/**
+ * reclaim_completed_tx - reclaims completed Tx descriptors
+ * @adap: the adapter
+ * @q: the Tx queue to reclaim completed descriptors from
+ * @unmap: whether the buffers should be unmapped for DMA
+ *
+ * Reclaims Tx descriptors that the SGE has indicated it has processed,
+ * and frees the associated buffers if possible. Called with the Tx
+ * queue locked.
+ */
+static inline void reclaim_completed_tx(struct adapter *adap, struct sge_txq *q,
+ bool unmap)
+{
+ int avail = reclaimable(q);
+
+ if (avail) {
+ /*
+ * Limit the amount of clean up work we do at a time to keep
+ * the Tx lock hold time O(1).
+ */
+ if (avail > MAX_TX_RECLAIM)
+ avail = MAX_TX_RECLAIM;
+
+ free_tx_desc(adap, q, avail, unmap);
+ q->in_use -= avail;
+ }
+}
+
+static inline int get_buf_size(const struct rx_sw_desc *d)
+{
+#if FL_PG_ORDER > 0
+ return (d->dma_addr & RX_LARGE_BUF) ? (PAGE_SIZE << FL_PG_ORDER) :
+ PAGE_SIZE;
+#else
+ return PAGE_SIZE;
+#endif
+}
+
+/**
+ * free_rx_bufs - free the Rx buffers on an SGE free list
+ * @adap: the adapter
+ * @q: the SGE free list to free buffers from
+ * @n: how many buffers to free
+ *
+ * Release the next @n buffers on an SGE free-buffer Rx queue. The
+ * buffers must be made inaccessible to HW before calling this function.
+ */
+static void free_rx_bufs(struct adapter *adap, struct sge_fl *q, int n)
+{
+ while (n--) {
+ struct rx_sw_desc *d = &q->sdesc[q->cidx];
+
+ if (is_buf_mapped(d))
+ dma_unmap_page(adap->pdev_dev, get_buf_addr(d),
+ get_buf_size(d), PCI_DMA_FROMDEVICE);
+ put_page(d->page);
+ d->page = NULL;
+ if (++q->cidx == q->size)
+ q->cidx = 0;
+ q->avail--;
+ }
+}
+
+/**
+ * unmap_rx_buf - unmap the current Rx buffer on an SGE free list
+ * @adap: the adapter
+ * @q: the SGE free list
+ *
+ * Unmap the current buffer on an SGE free-buffer Rx queue. The
+ * buffer must be made inaccessible to HW before calling this function.
+ *
+ * This is similar to @free_rx_bufs above but does not free the buffer.
+ * Do note that the FL still loses any further access to the buffer.
+ */
+static void unmap_rx_buf(struct adapter *adap, struct sge_fl *q)
+{
+ struct rx_sw_desc *d = &q->sdesc[q->cidx];
+
+ if (is_buf_mapped(d))
+ dma_unmap_page(adap->pdev_dev, get_buf_addr(d),
+ get_buf_size(d), PCI_DMA_FROMDEVICE);
+ d->page = NULL;
+ if (++q->cidx == q->size)
+ q->cidx = 0;
+ q->avail--;
+}
+
+static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
+{
+ if (q->pend_cred >= 8) {
+ wmb();
+ t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO |
+ QID(q->cntxt_id) | PIDX(q->pend_cred / 8));
+ q->pend_cred &= 7;
+ }
+}
+
+static inline void set_rx_sw_desc(struct rx_sw_desc *sd, struct page *pg,
+ dma_addr_t mapping)
+{
+ sd->page = pg;
+ sd->dma_addr = mapping; /* includes size low bits */
+}
+
+/**
+ * refill_fl - refill an SGE Rx buffer ring
+ * @adap: the adapter
+ * @q: the ring to refill
+ * @n: the number of new buffers to allocate
+ * @gfp: the gfp flags for the allocations
+ *
+ * (Re)populate an SGE free-buffer queue with up to @n new packet buffers,
+ * allocated with the supplied gfp flags. The caller must assure that
+ * @n does not exceed the queue's capacity. If afterwards the queue is
+ * found critically low mark it as starving in the bitmap of starving FLs.
+ *
+ * Returns the number of buffers allocated.
+ */
+static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n,
+ gfp_t gfp)
+{
+ struct page *pg;
+ dma_addr_t mapping;
+ unsigned int cred = q->avail;
+ __be64 *d = &q->desc[q->pidx];
+ struct rx_sw_desc *sd = &q->sdesc[q->pidx];
+
+ gfp |= __GFP_NOWARN; /* failures are expected */
+
+#if FL_PG_ORDER > 0
+ /*
+ * Prefer large buffers
+ */
+ while (n) {
+ pg = alloc_pages(gfp | __GFP_COMP, FL_PG_ORDER);
+ if (unlikely(!pg)) {
+ q->large_alloc_failed++;
+ break; /* fall back to single pages */
+ }
+
+ mapping = dma_map_page(adap->pdev_dev, pg, 0,
+ PAGE_SIZE << FL_PG_ORDER,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) {
+ __free_pages(pg, FL_PG_ORDER);
+ goto out; /* do not try small pages for this error */
+ }
+ mapping |= RX_LARGE_BUF;
+ *d++ = cpu_to_be64(mapping);
+
+ set_rx_sw_desc(sd, pg, mapping);
+ sd++;
+
+ q->avail++;
+ if (++q->pidx == q->size) {
+ q->pidx = 0;
+ sd = q->sdesc;
+ d = q->desc;
+ }
+ n--;
+ }
+#endif
+
+ while (n--) {
+ pg = __netdev_alloc_page(adap->port[0], gfp);
+ if (unlikely(!pg)) {
+ q->alloc_failed++;
+ break;
+ }
+
+ mapping = dma_map_page(adap->pdev_dev, pg, 0, PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) {
+ netdev_free_page(adap->port[0], pg);
+ goto out;
+ }
+ *d++ = cpu_to_be64(mapping);
+
+ set_rx_sw_desc(sd, pg, mapping);
+ sd++;
+
+ q->avail++;
+ if (++q->pidx == q->size) {
+ q->pidx = 0;
+ sd = q->sdesc;
+ d = q->desc;
+ }
+ }
+
+out: cred = q->avail - cred;
+ q->pend_cred += cred;
+ ring_fl_db(adap, q);
+
+ if (unlikely(fl_starving(q))) {
+ smp_wmb();
+ set_bit(q->cntxt_id, adap->sge.starving_fl);
+ }
+
+ return cred;
+}
+
+static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
+{
+ refill_fl(adap, fl, min(MAX_RX_REFILL, fl_cap(fl) - fl->avail),
+ GFP_ATOMIC);
+}
+
+/**
+ * alloc_ring - allocate resources for an SGE descriptor ring
+ * @dev: the PCI device's core device
+ * @nelem: the number of descriptors
+ * @elem_size: the size of each descriptor
+ * @sw_size: the size of the SW state associated with each ring element
+ * @phys: the physical address of the allocated ring
+ * @metadata: address of the array holding the SW state for the ring
+ * @stat_size: extra space in HW ring for status information
+ *
+ * Allocates resources for an SGE descriptor ring, such as Tx queues,
+ * free buffer lists, or response queues. Each SGE ring requires
+ * space for its HW descriptors plus, optionally, space for the SW state
+ * associated with each HW entry (the metadata). The function returns
+ * three values: the virtual address for the HW ring (the return value
+ * of the function), the bus address of the HW ring, and the address
+ * of the SW ring.
+ */
+static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size,
+ size_t sw_size, dma_addr_t *phys, void *metadata,
+ size_t stat_size)
+{
+ size_t len = nelem * elem_size + stat_size;
+ void *s = NULL;
+ void *p = dma_alloc_coherent(dev, len, phys, GFP_KERNEL);
+
+ if (!p)
+ return NULL;
+ if (sw_size) {
+ s = kcalloc(nelem, sw_size, GFP_KERNEL);
+
+ if (!s) {
+ dma_free_coherent(dev, len, p, *phys);
+ return NULL;
+ }
+ }
+ if (metadata)
+ *(void **)metadata = s;
+ memset(p, 0, len);
+ return p;
+}
+
+/**
+ * sgl_len - calculates the size of an SGL of the given capacity
+ * @n: the number of SGL entries
+ *
+ * Calculates the number of flits needed for a scatter/gather list that
+ * can hold the given number of entries.
+ */
+static inline unsigned int sgl_len(unsigned int n)
+{
+ n--;
+ return (3 * n) / 2 + (n & 1) + 2;
+}
+
+/**
+ * flits_to_desc - returns the num of Tx descriptors for the given flits
+ * @n: the number of flits
+ *
+ * Returns the number of Tx descriptors needed for the supplied number
+ * of flits.
+ */
+static inline unsigned int flits_to_desc(unsigned int n)
+{
+ BUG_ON(n > SGE_MAX_WR_LEN / 8);
+ return DIV_ROUND_UP(n, 8);
+}
+
+/**
+ * is_eth_imm - can an Ethernet packet be sent as immediate data?
+ * @skb: the packet
+ *
+ * Returns whether an Ethernet packet is small enough to fit as
+ * immediate data.
+ */
+static inline int is_eth_imm(const struct sk_buff *skb)
+{
+ return skb->len <= MAX_IMM_TX_PKT_LEN - sizeof(struct cpl_tx_pkt);
+}
+
+/**
+ * calc_tx_flits - calculate the number of flits for a packet Tx WR
+ * @skb: the packet
+ *
+ * Returns the number of flits needed for a Tx WR for the given Ethernet
+ * packet, including the needed WR and CPL headers.
+ */
+static inline unsigned int calc_tx_flits(const struct sk_buff *skb)
+{
+ unsigned int flits;
+
+ if (is_eth_imm(skb))
+ return DIV_ROUND_UP(skb->len + sizeof(struct cpl_tx_pkt), 8);
+
+ flits = sgl_len(skb_shinfo(skb)->nr_frags + 1) + 4;
+ if (skb_shinfo(skb)->gso_size)
+ flits += 2;
+ return flits;
+}
+
+/**
+ * calc_tx_descs - calculate the number of Tx descriptors for a packet
+ * @skb: the packet
+ *
+ * Returns the number of Tx descriptors needed for the given Ethernet
+ * packet, including the needed WR and CPL headers.
+ */
+static inline unsigned int calc_tx_descs(const struct sk_buff *skb)
+{
+ return flits_to_desc(calc_tx_flits(skb));
+}
+
+/**
+ * write_sgl - populate a scatter/gather list for a packet
+ * @skb: the packet
+ * @q: the Tx queue we are writing into
+ * @sgl: starting location for writing the SGL
+ * @end: points right after the end of the SGL
+ * @start: start offset into skb main-body data to include in the SGL
+ * @addr: the list of bus addresses for the SGL elements
+ *
+ * Generates a gather list for the buffers that make up a packet.
+ * The caller must provide adequate space for the SGL that will be written.
+ * The SGL includes all of the packet's page fragments and the data in its
+ * main body except for the first @start bytes. @sgl must be 16-byte
+ * aligned and within a Tx descriptor with available space. @end points
+ * right after the end of the SGL but does not account for any potential
+ * wrap around, i.e., @end > @sgl.
+ */
+static void write_sgl(const struct sk_buff *skb, struct sge_txq *q,
+ struct ulptx_sgl *sgl, u64 *end, unsigned int start,
+ const dma_addr_t *addr)
+{
+ unsigned int i, len;
+ struct ulptx_sge_pair *to;
+ const struct skb_shared_info *si = skb_shinfo(skb);
+ unsigned int nfrags = si->nr_frags;
+ struct ulptx_sge_pair buf[MAX_SKB_FRAGS / 2 + 1];
+
+ len = skb_headlen(skb) - start;
+ if (likely(len)) {
+ sgl->len0 = htonl(len);
+ sgl->addr0 = cpu_to_be64(addr[0] + start);
+ nfrags++;
+ } else {
+ sgl->len0 = htonl(si->frags[0].size);
+ sgl->addr0 = cpu_to_be64(addr[1]);
+ }
+
+ sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(nfrags));
+ if (likely(--nfrags == 0))
+ return;
+ /*
+ * Most of the complexity below deals with the possibility we hit the
+ * end of the queue in the middle of writing the SGL. For this case
+ * only we create the SGL in a temporary buffer and then copy it.
+ */
+ to = (u8 *)end > (u8 *)q->stat ? buf : sgl->sge;
+
+ for (i = (nfrags != si->nr_frags); nfrags >= 2; nfrags -= 2, to++) {
+ to->len[0] = cpu_to_be32(si->frags[i].size);
+ to->len[1] = cpu_to_be32(si->frags[++i].size);
+ to->addr[0] = cpu_to_be64(addr[i]);
+ to->addr[1] = cpu_to_be64(addr[++i]);
+ }
+ if (nfrags) {
+ to->len[0] = cpu_to_be32(si->frags[i].size);
+ to->len[1] = cpu_to_be32(0);
+ to->addr[0] = cpu_to_be64(addr[i + 1]);
+ }
+ if (unlikely((u8 *)end > (u8 *)q->stat)) {
+ unsigned int part0 = (u8 *)q->stat - (u8 *)sgl->sge, part1;
+
+ if (likely(part0))
+ memcpy(sgl->sge, buf, part0);
+ part1 = (u8 *)end - (u8 *)q->stat;
+ memcpy(q->desc, (u8 *)buf + part0, part1);
+ end = (void *)q->desc + part1;
+ }
+ if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */
+ *(u64 *)end = 0;
+}
+
+/**
+ * ring_tx_db - check and potentially ring a Tx queue's doorbell
+ * @adap: the adapter
+ * @q: the Tx queue
+ * @n: number of new descriptors to give to HW
+ *
+ * Ring the doorbel for a Tx queue.
+ */
+static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
+{
+ wmb(); /* write descriptors before telling HW */
+ t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
+ QID(q->cntxt_id) | PIDX(n));
+}
+
+/**
+ * inline_tx_skb - inline a packet's data into Tx descriptors
+ * @skb: the packet
+ * @q: the Tx queue where the packet will be inlined
+ * @pos: starting position in the Tx queue where to inline the packet
+ *
+ * Inline a packet's contents directly into Tx descriptors, starting at
+ * the given position within the Tx DMA ring.
+ * Most of the complexity of this operation is dealing with wrap arounds
+ * in the middle of the packet we want to inline.
+ */
+static void inline_tx_skb(const struct sk_buff *skb, const struct sge_txq *q,
+ void *pos)
+{
+ u64 *p;
+ int left = (void *)q->stat - pos;
+
+ if (likely(skb->len <= left)) {
+ if (likely(!skb->data_len))
+ skb_copy_from_linear_data(skb, pos, skb->len);
+ else
+ skb_copy_bits(skb, 0, pos, skb->len);
+ pos += skb->len;
+ } else {
+ skb_copy_bits(skb, 0, pos, left);
+ skb_copy_bits(skb, left, q->desc, skb->len - left);
+ pos = (void *)q->desc + (skb->len - left);
+ }
+
+ /* 0-pad to multiple of 16 */
+ p = PTR_ALIGN(pos, 8);
+ if ((uintptr_t)p & 8)
+ *p = 0;
+}
+
+/*
+ * Figure out what HW csum a packet wants and return the appropriate control
+ * bits.
+ */
+static u64 hwcsum(const struct sk_buff *skb)
+{
+ int csum_type;
+ const struct iphdr *iph = ip_hdr(skb);
+
+ if (iph->version == 4) {
+ if (iph->protocol == IPPROTO_TCP)
+ csum_type = TX_CSUM_TCPIP;
+ else if (iph->protocol == IPPROTO_UDP)
+ csum_type = TX_CSUM_UDPIP;
+ else {
+nocsum: /*
+ * unknown protocol, disable HW csum
+ * and hope a bad packet is detected
+ */
+ return TXPKT_L4CSUM_DIS;
+ }
+ } else {
+ /*
+ * this doesn't work with extension headers
+ */
+ const struct ipv6hdr *ip6h = (const struct ipv6hdr *)iph;
+
+ if (ip6h->nexthdr == IPPROTO_TCP)
+ csum_type = TX_CSUM_TCPIP6;
+ else if (ip6h->nexthdr == IPPROTO_UDP)
+ csum_type = TX_CSUM_UDPIP6;
+ else
+ goto nocsum;
+ }
+
+ if (likely(csum_type >= TX_CSUM_TCPIP))
+ return TXPKT_CSUM_TYPE(csum_type) |
+ TXPKT_IPHDR_LEN(skb_network_header_len(skb)) |
+ TXPKT_ETHHDR_LEN(skb_network_offset(skb) - ETH_HLEN);
+ else {
+ int start = skb_transport_offset(skb);
+
+ return TXPKT_CSUM_TYPE(csum_type) | TXPKT_CSUM_START(start) |
+ TXPKT_CSUM_LOC(start + skb->csum_offset);
+ }
+}
+
+static void eth_txq_stop(struct sge_eth_txq *q)
+{
+ netif_tx_stop_queue(q->txq);
+ q->q.stops++;
+}
+
+static inline void txq_advance(struct sge_txq *q, unsigned int n)
+{
+ q->in_use += n;
+ q->pidx += n;
+ if (q->pidx >= q->size)
+ q->pidx -= q->size;
+}
+
+/**
+ * t4_eth_xmit - add a packet to an Ethernet Tx queue
+ * @skb: the packet
+ * @dev: the egress net device
+ *
+ * Add a packet to an SGE Ethernet Tx queue. Runs with softirqs disabled.
+ */
+netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ u32 wr_mid;
+ u64 cntrl, *end;
+ int qidx, credits;
+ unsigned int flits, ndesc;
+ struct adapter *adap;
+ struct sge_eth_txq *q;
+ const struct port_info *pi;
+ struct fw_eth_tx_pkt_wr *wr;
+ struct cpl_tx_pkt_core *cpl;
+ const struct skb_shared_info *ssi;
+ dma_addr_t addr[MAX_SKB_FRAGS + 1];
+
+ /*
+ * The chip min packet length is 10 octets but play safe and reject
+ * anything shorter than an Ethernet header.
+ */
+ if (unlikely(skb->len < ETH_HLEN)) {
+out_free: dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ pi = netdev_priv(dev);
+ adap = pi->adapter;
+ qidx = skb_get_queue_mapping(skb);
+ q = &adap->sge.ethtxq[qidx + pi->first_qset];
+
+ reclaim_completed_tx(adap, &q->q, true);
+
+ flits = calc_tx_flits(skb);
+ ndesc = flits_to_desc(flits);
+ credits = txq_avail(&q->q) - ndesc;
+
+ if (unlikely(credits < 0)) {
+ eth_txq_stop(q);
+ dev_err(adap->pdev_dev,
+ "%s: Tx ring %u full while queue awake!\n",
+ dev->name, qidx);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (!is_eth_imm(skb) &&
+ unlikely(map_skb(adap->pdev_dev, skb, addr) < 0)) {
+ q->mapping_err++;
+ goto out_free;
+ }
+
+ wr_mid = FW_WR_LEN16(DIV_ROUND_UP(flits, 2));
+ if (unlikely(credits < ETHTXQ_STOP_THRES)) {
+ eth_txq_stop(q);
+ wr_mid |= FW_WR_EQUEQ | FW_WR_EQUIQ;
+ }
+
+ wr = (void *)&q->q.desc[q->q.pidx];
+ wr->equiq_to_len16 = htonl(wr_mid);
+ wr->r3 = cpu_to_be64(0);
+ end = (u64 *)wr + flits;
+
+ ssi = skb_shinfo(skb);
+ if (ssi->gso_size) {
+ struct cpl_tx_pkt_lso *lso = (void *)wr;
+ bool v6 = (ssi->gso_type & SKB_GSO_TCPV6) != 0;
+ int l3hdr_len = skb_network_header_len(skb);
+ int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN;
+
+ wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) |
+ FW_WR_IMMDLEN(sizeof(*lso)));
+ lso->lso_ctrl = htonl(LSO_OPCODE(CPL_TX_PKT_LSO) |
+ LSO_FIRST_SLICE | LSO_LAST_SLICE |
+ LSO_IPV6(v6) |
+ LSO_ETHHDR_LEN(eth_xtra_len / 4) |
+ LSO_IPHDR_LEN(l3hdr_len / 4) |
+ LSO_TCPHDR_LEN(tcp_hdr(skb)->doff));
+ lso->ipid_ofst = htons(0);
+ lso->mss = htons(ssi->gso_size);
+ lso->seqno_offset = htonl(0);
+ lso->len = htonl(skb->len);
+ cpl = (void *)(lso + 1);
+ cntrl = TXPKT_CSUM_TYPE(v6 ? TX_CSUM_TCPIP6 : TX_CSUM_TCPIP) |
+ TXPKT_IPHDR_LEN(l3hdr_len) |
+ TXPKT_ETHHDR_LEN(eth_xtra_len);
+ q->tso++;
+ q->tx_cso += ssi->gso_segs;
+ } else {
+ int len;
+
+ len = is_eth_imm(skb) ? skb->len + sizeof(*cpl) : sizeof(*cpl);
+ wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) |
+ FW_WR_IMMDLEN(len));
+ cpl = (void *)(wr + 1);
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ cntrl = hwcsum(skb) | TXPKT_IPCSUM_DIS;
+ q->tx_cso++;
+ } else
+ cntrl = TXPKT_L4CSUM_DIS | TXPKT_IPCSUM_DIS;
+ }
+
+ if (vlan_tx_tag_present(skb)) {
+ q->vlan_ins++;
+ cntrl |= TXPKT_VLAN_VLD | TXPKT_VLAN(vlan_tx_tag_get(skb));
+ }
+
+ cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) |
+ TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0));
+ cpl->pack = htons(0);
+ cpl->len = htons(skb->len);
+ cpl->ctrl1 = cpu_to_be64(cntrl);
+
+ if (is_eth_imm(skb)) {
+ inline_tx_skb(skb, &q->q, cpl + 1);
+ dev_kfree_skb(skb);
+ } else {
+ int last_desc;
+
+ write_sgl(skb, &q->q, (struct ulptx_sgl *)(cpl + 1), end, 0,
+ addr);
+ skb_orphan(skb);
+
+ last_desc = q->q.pidx + ndesc - 1;
+ if (last_desc >= q->q.size)
+ last_desc -= q->q.size;
+ q->q.sdesc[last_desc].skb = skb;
+ q->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)(cpl + 1);
+ }
+
+ txq_advance(&q->q, ndesc);
+
+ ring_tx_db(adap, &q->q, ndesc);
+ return NETDEV_TX_OK;
+}
+
+/**
+ * reclaim_completed_tx_imm - reclaim completed control-queue Tx descs
+ * @q: the SGE control Tx queue
+ *
+ * This is a variant of reclaim_completed_tx() that is used for Tx queues
+ * that send only immediate data (presently just the control queues) and
+ * thus do not have any sk_buffs to release.
+ */
+static inline void reclaim_completed_tx_imm(struct sge_txq *q)
+{
+ int hw_cidx = ntohs(q->stat->cidx);
+ int reclaim = hw_cidx - q->cidx;
+
+ if (reclaim < 0)
+ reclaim += q->size;
+
+ q->in_use -= reclaim;
+ q->cidx = hw_cidx;
+}
+
+/**
+ * is_imm - check whether a packet can be sent as immediate data
+ * @skb: the packet
+ *
+ * Returns true if a packet can be sent as a WR with immediate data.
+ */
+static inline int is_imm(const struct sk_buff *skb)
+{
+ return skb->len <= MAX_CTRL_WR_LEN;
+}
+
+/**
+ * ctrlq_check_stop - check if a control queue is full and should stop
+ * @q: the queue
+ * @wr: most recent WR written to the queue
+ *
+ * Check if a control queue has become full and should be stopped.
+ * We clean up control queue descriptors very lazily, only when we are out.
+ * If the queue is still full after reclaiming any completed descriptors
+ * we suspend it and have the last WR wake it up.
+ */
+static void ctrlq_check_stop(struct sge_ctrl_txq *q, struct fw_wr_hdr *wr)
+{
+ reclaim_completed_tx_imm(&q->q);
+ if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) {
+ wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ);
+ q->q.stops++;
+ q->full = 1;
+ }
+}
+
+/**
+ * ctrl_xmit - send a packet through an SGE control Tx queue
+ * @q: the control queue
+ * @skb: the packet
+ *
+ * Send a packet through an SGE control Tx queue. Packets sent through
+ * a control queue must fit entirely as immediate data.
+ */
+static int ctrl_xmit(struct sge_ctrl_txq *q, struct sk_buff *skb)
+{
+ unsigned int ndesc;
+ struct fw_wr_hdr *wr;
+
+ if (unlikely(!is_imm(skb))) {
+ WARN_ON(1);
+ dev_kfree_skb(skb);
+ return NET_XMIT_DROP;
+ }
+
+ ndesc = DIV_ROUND_UP(skb->len, sizeof(struct tx_desc));
+ spin_lock(&q->sendq.lock);
+
+ if (unlikely(q->full)) {
+ skb->priority = ndesc; /* save for restart */
+ __skb_queue_tail(&q->sendq, skb);
+ spin_unlock(&q->sendq.lock);
+ return NET_XMIT_CN;
+ }
+
+ wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx];
+ inline_tx_skb(skb, &q->q, wr);
+
+ txq_advance(&q->q, ndesc);
+ if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES))
+ ctrlq_check_stop(q, wr);
+
+ ring_tx_db(q->adap, &q->q, ndesc);
+ spin_unlock(&q->sendq.lock);
+
+ kfree_skb(skb);
+ return NET_XMIT_SUCCESS;
+}
+
+/**
+ * restart_ctrlq - restart a suspended control queue
+ * @data: the control queue to restart
+ *
+ * Resumes transmission on a suspended Tx control queue.
+ */
+static void restart_ctrlq(unsigned long data)
+{
+ struct sk_buff *skb;
+ unsigned int written = 0;
+ struct sge_ctrl_txq *q = (struct sge_ctrl_txq *)data;
+
+ spin_lock(&q->sendq.lock);
+ reclaim_completed_tx_imm(&q->q);
+ BUG_ON(txq_avail(&q->q) < TXQ_STOP_THRES); /* q should be empty */
+
+ while ((skb = __skb_dequeue(&q->sendq)) != NULL) {
+ struct fw_wr_hdr *wr;
+ unsigned int ndesc = skb->priority; /* previously saved */
+
+ /*
+ * Write descriptors and free skbs outside the lock to limit
+ * wait times. q->full is still set so new skbs will be queued.
+ */
+ spin_unlock(&q->sendq.lock);
+
+ wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx];
+ inline_tx_skb(skb, &q->q, wr);
+ kfree_skb(skb);
+
+ written += ndesc;
+ txq_advance(&q->q, ndesc);
+ if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) {
+ unsigned long old = q->q.stops;
+
+ ctrlq_check_stop(q, wr);
+ if (q->q.stops != old) { /* suspended anew */
+ spin_lock(&q->sendq.lock);
+ goto ringdb;
+ }
+ }
+ if (written > 16) {
+ ring_tx_db(q->adap, &q->q, written);
+ written = 0;
+ }
+ spin_lock(&q->sendq.lock);
+ }
+ q->full = 0;
+ringdb: if (written)
+ ring_tx_db(q->adap, &q->q, written);
+ spin_unlock(&q->sendq.lock);
+}
+
+/**
+ * t4_mgmt_tx - send a management message
+ * @adap: the adapter
+ * @skb: the packet containing the management message
+ *
+ * Send a management message through control queue 0.
+ */
+int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
+{
+ int ret;
+
+ local_bh_disable();
+ ret = ctrl_xmit(&adap->sge.ctrlq[0], skb);
+ local_bh_enable();
+ return ret;
+}
+
+/**
+ * is_ofld_imm - check whether a packet can be sent as immediate data
+ * @skb: the packet
+ *
+ * Returns true if a packet can be sent as an offload WR with immediate
+ * data. We currently use the same limit as for Ethernet packets.
+ */
+static inline int is_ofld_imm(const struct sk_buff *skb)
+{
+ return skb->len <= MAX_IMM_TX_PKT_LEN;
+}
+
+/**
+ * calc_tx_flits_ofld - calculate # of flits for an offload packet
+ * @skb: the packet
+ *
+ * Returns the number of flits needed for the given offload packet.
+ * These packets are already fully constructed and no additional headers
+ * will be added.
+ */
+static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb)
+{
+ unsigned int flits, cnt;
+
+ if (is_ofld_imm(skb))
+ return DIV_ROUND_UP(skb->len, 8);
+
+ flits = skb_transport_offset(skb) / 8U; /* headers */
+ cnt = skb_shinfo(skb)->nr_frags;
+ if (skb->tail != skb->transport_header)
+ cnt++;
+ return flits + sgl_len(cnt);
+}
+
+/**
+ * txq_stop_maperr - stop a Tx queue due to I/O MMU exhaustion
+ * @adap: the adapter
+ * @q: the queue to stop
+ *
+ * Mark a Tx queue stopped due to I/O MMU exhaustion and resulting
+ * inability to map packets. A periodic timer attempts to restart
+ * queues so marked.
+ */
+static void txq_stop_maperr(struct sge_ofld_txq *q)
+{
+ q->mapping_err++;
+ q->q.stops++;
+ set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr);
+}
+
+/**
+ * ofldtxq_stop - stop an offload Tx queue that has become full
+ * @q: the queue to stop
+ * @skb: the packet causing the queue to become full
+ *
+ * Stops an offload Tx queue that has become full and modifies the packet
+ * being written to request a wakeup.
+ */
+static void ofldtxq_stop(struct sge_ofld_txq *q, struct sk_buff *skb)
+{
+ struct fw_wr_hdr *wr = (struct fw_wr_hdr *)skb->data;
+
+ wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ);
+ q->q.stops++;
+ q->full = 1;
+}
+
+/**
+ * service_ofldq - restart a suspended offload queue
+ * @q: the offload queue
+ *
+ * Services an offload Tx queue by moving packets from its packet queue
+ * to the HW Tx ring. The function starts and ends with the queue locked.
+ */
+static void service_ofldq(struct sge_ofld_txq *q)
+{
+ u64 *pos;
+ int credits;
+ struct sk_buff *skb;
+ unsigned int written = 0;
+ unsigned int flits, ndesc;
+
+ while ((skb = skb_peek(&q->sendq)) != NULL && !q->full) {
+ /*
+ * We drop the lock but leave skb on sendq, thus retaining
+ * exclusive access to the state of the queue.
+ */
+ spin_unlock(&q->sendq.lock);
+
+ reclaim_completed_tx(q->adap, &q->q, false);
+
+ flits = skb->priority; /* previously saved */
+ ndesc = flits_to_desc(flits);
+ credits = txq_avail(&q->q) - ndesc;
+ BUG_ON(credits < 0);
+ if (unlikely(credits < TXQ_STOP_THRES))
+ ofldtxq_stop(q, skb);
+
+ pos = (u64 *)&q->q.desc[q->q.pidx];
+ if (is_ofld_imm(skb))
+ inline_tx_skb(skb, &q->q, pos);
+ else if (map_skb(q->adap->pdev_dev, skb,
+ (dma_addr_t *)skb->head)) {
+ txq_stop_maperr(q);
+ spin_lock(&q->sendq.lock);
+ break;
+ } else {
+ int last_desc, hdr_len = skb_transport_offset(skb);
+
+ memcpy(pos, skb->data, hdr_len);
+ write_sgl(skb, &q->q, (void *)pos + hdr_len,
+ pos + flits, hdr_len,
+ (dma_addr_t *)skb->head);
+#ifdef CONFIG_NEED_DMA_MAP_STATE
+ skb->dev = q->adap->port[0];
+ skb->destructor = deferred_unmap_destructor;
+#endif
+ last_desc = q->q.pidx + ndesc - 1;
+ if (last_desc >= q->q.size)
+ last_desc -= q->q.size;
+ q->q.sdesc[last_desc].skb = skb;
+ }
+
+ txq_advance(&q->q, ndesc);
+ written += ndesc;
+ if (unlikely(written > 32)) {
+ ring_tx_db(q->adap, &q->q, written);
+ written = 0;
+ }
+
+ spin_lock(&q->sendq.lock);
+ __skb_unlink(skb, &q->sendq);
+ if (is_ofld_imm(skb))
+ kfree_skb(skb);
+ }
+ if (likely(written))
+ ring_tx_db(q->adap, &q->q, written);
+}
+
+/**
+ * ofld_xmit - send a packet through an offload queue
+ * @q: the Tx offload queue
+ * @skb: the packet
+ *
+ * Send an offload packet through an SGE offload queue.
+ */
+static int ofld_xmit(struct sge_ofld_txq *q, struct sk_buff *skb)
+{
+ skb->priority = calc_tx_flits_ofld(skb); /* save for restart */
+ spin_lock(&q->sendq.lock);
+ __skb_queue_tail(&q->sendq, skb);
+ if (q->sendq.qlen == 1)
+ service_ofldq(q);
+ spin_unlock(&q->sendq.lock);
+ return NET_XMIT_SUCCESS;
+}
+
+/**
+ * restart_ofldq - restart a suspended offload queue
+ * @data: the offload queue to restart
+ *
+ * Resumes transmission on a suspended Tx offload queue.
+ */
+static void restart_ofldq(unsigned long data)
+{
+ struct sge_ofld_txq *q = (struct sge_ofld_txq *)data;
+
+ spin_lock(&q->sendq.lock);
+ q->full = 0; /* the queue actually is completely empty now */
+ service_ofldq(q);
+ spin_unlock(&q->sendq.lock);
+}
+
+/**
+ * skb_txq - return the Tx queue an offload packet should use
+ * @skb: the packet
+ *
+ * Returns the Tx queue an offload packet should use as indicated by bits
+ * 1-15 in the packet's queue_mapping.
+ */
+static inline unsigned int skb_txq(const struct sk_buff *skb)
+{
+ return skb->queue_mapping >> 1;
+}
+
+/**
+ * is_ctrl_pkt - return whether an offload packet is a control packet
+ * @skb: the packet
+ *
+ * Returns whether an offload packet should use an OFLD or a CTRL
+ * Tx queue as indicated by bit 0 in the packet's queue_mapping.
+ */
+static inline unsigned int is_ctrl_pkt(const struct sk_buff *skb)
+{
+ return skb->queue_mapping & 1;
+}
+
+static inline int ofld_send(struct adapter *adap, struct sk_buff *skb)
+{
+ unsigned int idx = skb_txq(skb);
+
+ if (unlikely(is_ctrl_pkt(skb)))
+ return ctrl_xmit(&adap->sge.ctrlq[idx], skb);
+ return ofld_xmit(&adap->sge.ofldtxq[idx], skb);
+}
+
+/**
+ * t4_ofld_send - send an offload packet
+ * @adap: the adapter
+ * @skb: the packet
+ *
+ * Sends an offload packet. We use the packet queue_mapping to select the
+ * appropriate Tx queue as follows: bit 0 indicates whether the packet
+ * should be sent as regular or control, bits 1-15 select the queue.
+ */
+int t4_ofld_send(struct adapter *adap, struct sk_buff *skb)
+{
+ int ret;
+
+ local_bh_disable();
+ ret = ofld_send(adap, skb);
+ local_bh_enable();
+ return ret;
+}
+
+/**
+ * cxgb4_ofld_send - send an offload packet
+ * @dev: the net device
+ * @skb: the packet
+ *
+ * Sends an offload packet. This is an exported version of @t4_ofld_send,
+ * intended for ULDs.
+ */
+int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb)
+{
+ return t4_ofld_send(netdev2adap(dev), skb);
+}
+EXPORT_SYMBOL(cxgb4_ofld_send);
+
+static inline void copy_frags(struct skb_shared_info *ssi,
+ const struct pkt_gl *gl, unsigned int offset)
+{
+ unsigned int n;
+
+ /* usually there's just one frag */
+ ssi->frags[0].page = gl->frags[0].page;
+ ssi->frags[0].page_offset = gl->frags[0].page_offset + offset;
+ ssi->frags[0].size = gl->frags[0].size - offset;
+ ssi->nr_frags = gl->nfrags;
+ n = gl->nfrags - 1;
+ if (n)
+ memcpy(&ssi->frags[1], &gl->frags[1], n * sizeof(skb_frag_t));
+
+ /* get a reference to the last page, we don't own it */
+ get_page(gl->frags[n].page);
+}
+
+/**
+ * cxgb4_pktgl_to_skb - build an sk_buff from a packet gather list
+ * @gl: the gather list
+ * @skb_len: size of sk_buff main body if it carries fragments
+ * @pull_len: amount of data to move to the sk_buff's main body
+ *
+ * Builds an sk_buff from the given packet gather list. Returns the
+ * sk_buff or %NULL if sk_buff allocation failed.
+ */
+struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
+ unsigned int skb_len, unsigned int pull_len)
+{
+ struct sk_buff *skb;
+
+ /*
+ * Below we rely on RX_COPY_THRES being less than the smallest Rx buffer
+ * size, which is expected since buffers are at least PAGE_SIZEd.
+ * In this case packets up to RX_COPY_THRES have only one fragment.
+ */
+ if (gl->tot_len <= RX_COPY_THRES) {
+ skb = dev_alloc_skb(gl->tot_len);
+ if (unlikely(!skb))
+ goto out;
+ __skb_put(skb, gl->tot_len);
+ skb_copy_to_linear_data(skb, gl->va, gl->tot_len);
+ } else {
+ skb = dev_alloc_skb(skb_len);
+ if (unlikely(!skb))
+ goto out;
+ __skb_put(skb, pull_len);
+ skb_copy_to_linear_data(skb, gl->va, pull_len);
+
+ copy_frags(skb_shinfo(skb), gl, pull_len);
+ skb->len = gl->tot_len;
+ skb->data_len = skb->len - pull_len;
+ skb->truesize += skb->data_len;
+ }
+out: return skb;
+}
+EXPORT_SYMBOL(cxgb4_pktgl_to_skb);
+
+/**
+ * t4_pktgl_free - free a packet gather list
+ * @gl: the gather list
+ *
+ * Releases the pages of a packet gather list. We do not own the last
+ * page on the list and do not free it.
+ */
+void t4_pktgl_free(const struct pkt_gl *gl)
+{
+ int n;
+ const skb_frag_t *p;
+
+ for (p = gl->frags, n = gl->nfrags - 1; n--; p++)
+ put_page(p->page);
+}
+
+/*
+ * Process an MPS trace packet. Give it an unused protocol number so it won't
+ * be delivered to anyone and send it to the stack for capture.
+ */
+static noinline int handle_trace_pkt(struct adapter *adap,
+ const struct pkt_gl *gl)
+{
+ struct sk_buff *skb;
+ struct cpl_trace_pkt *p;
+
+ skb = cxgb4_pktgl_to_skb(gl, RX_PULL_LEN, RX_PULL_LEN);
+ if (unlikely(!skb)) {
+ t4_pktgl_free(gl);
+ return 0;
+ }
+
+ p = (struct cpl_trace_pkt *)skb->data;
+ __skb_pull(skb, sizeof(*p));
+ skb_reset_mac_header(skb);
+ skb->protocol = htons(0xffff);
+ skb->dev = adap->port[0];
+ netif_receive_skb(skb);
+ return 0;
+}
+
+static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
+ const struct cpl_rx_pkt *pkt)
+{
+ int ret;
+ struct sk_buff *skb;
+
+ skb = napi_get_frags(&rxq->rspq.napi);
+ if (unlikely(!skb)) {
+ t4_pktgl_free(gl);
+ rxq->stats.rx_drops++;
+ return;
+ }
+
+ copy_frags(skb_shinfo(skb), gl, RX_PKT_PAD);
+ skb->len = gl->tot_len - RX_PKT_PAD;
+ skb->data_len = skb->len;
+ skb->truesize += skb->data_len;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb_record_rx_queue(skb, rxq->rspq.idx);
+
+ if (unlikely(pkt->vlan_ex)) {
+ struct port_info *pi = netdev_priv(rxq->rspq.netdev);
+ struct vlan_group *grp = pi->vlan_grp;
+
+ rxq->stats.vlan_ex++;
+ if (likely(grp)) {
+ ret = vlan_gro_frags(&rxq->rspq.napi, grp,
+ ntohs(pkt->vlan));
+ goto stats;
+ }
+ }
+ ret = napi_gro_frags(&rxq->rspq.napi);
+stats: if (ret == GRO_HELD)
+ rxq->stats.lro_pkts++;
+ else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE)
+ rxq->stats.lro_merged++;
+ rxq->stats.pkts++;
+ rxq->stats.rx_cso++;
+}
+
+/**
+ * t4_ethrx_handler - process an ingress ethernet packet
+ * @q: the response queue that received the packet
+ * @rsp: the response queue descriptor holding the RX_PKT message
+ * @si: the gather list of packet fragments
+ *
+ * Process an ingress ethernet packet and deliver it to the stack.
+ */
+int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
+ const struct pkt_gl *si)
+{
+ bool csum_ok;
+ struct sk_buff *skb;
+ struct port_info *pi;
+ const struct cpl_rx_pkt *pkt;
+ struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
+
+ if (unlikely(*(u8 *)rsp == CPL_TRACE_PKT))
+ return handle_trace_pkt(q->adap, si);
+
+ pkt = (void *)&rsp[1];
+ csum_ok = pkt->csum_calc && !pkt->err_vec;
+ if ((pkt->l2info & htonl(RXF_TCP)) &&
+ (q->netdev->features & NETIF_F_GRO) && csum_ok && !pkt->ip_frag) {
+ do_gro(rxq, si, pkt);
+ return 0;
+ }
+
+ skb = cxgb4_pktgl_to_skb(si, RX_PKT_SKB_LEN, RX_PULL_LEN);
+ if (unlikely(!skb)) {
+ t4_pktgl_free(si);
+ rxq->stats.rx_drops++;
+ return 0;
+ }
+
+ __skb_pull(skb, RX_PKT_PAD); /* remove ethernet header padding */
+ skb->protocol = eth_type_trans(skb, q->netdev);
+ skb_record_rx_queue(skb, q->idx);
+ pi = netdev_priv(skb->dev);
+ rxq->stats.pkts++;
+
+ if (csum_ok && (pi->rx_offload & RX_CSO) &&
+ (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) {
+ if (!pkt->ip_frag)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else {
+ __sum16 c = (__force __sum16)pkt->csum;
+ skb->csum = csum_unfold(c);
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ }
+ rxq->stats.rx_cso++;
+ } else
+ skb->ip_summed = CHECKSUM_NONE;
+
+ if (unlikely(pkt->vlan_ex)) {
+ struct vlan_group *grp = pi->vlan_grp;
+
+ rxq->stats.vlan_ex++;
+ if (likely(grp))
+ vlan_hwaccel_receive_skb(skb, grp, ntohs(pkt->vlan));
+ else
+ dev_kfree_skb_any(skb);
+ } else
+ netif_receive_skb(skb);
+
+ return 0;
+}
+
+/**
+ * restore_rx_bufs - put back a packet's Rx buffers
+ * @si: the packet gather list
+ * @q: the SGE free list
+ * @frags: number of FL buffers to restore
+ *
+ * Puts back on an FL the Rx buffers associated with @si. The buffers
+ * have already been unmapped and are left unmapped, we mark them so to
+ * prevent further unmapping attempts.
+ *
+ * This function undoes a series of @unmap_rx_buf calls when we find out
+ * that the current packet can't be processed right away afterall and we
+ * need to come back to it later. This is a very rare event and there's
+ * no effort to make this particularly efficient.
+ */
+static void restore_rx_bufs(const struct pkt_gl *si, struct sge_fl *q,
+ int frags)
+{
+ struct rx_sw_desc *d;
+
+ while (frags--) {
+ if (q->cidx == 0)
+ q->cidx = q->size - 1;
+ else
+ q->cidx--;
+ d = &q->sdesc[q->cidx];
+ d->page = si->frags[frags].page;
+ d->dma_addr |= RX_UNMAPPED_BUF;
+ q->avail++;
+ }
+}
+
+/**
+ * is_new_response - check if a response is newly written
+ * @r: the response descriptor
+ * @q: the response queue
+ *
+ * Returns true if a response descriptor contains a yet unprocessed
+ * response.
+ */
+static inline bool is_new_response(const struct rsp_ctrl *r,
+ const struct sge_rspq *q)
+{
+ return RSPD_GEN(r->type_gen) == q->gen;
+}
+
+/**
+ * rspq_next - advance to the next entry in a response queue
+ * @q: the queue
+ *
+ * Updates the state of a response queue to advance it to the next entry.
+ */
+static inline void rspq_next(struct sge_rspq *q)
+{
+ q->cur_desc = (void *)q->cur_desc + q->iqe_len;
+ if (unlikely(++q->cidx == q->size)) {
+ q->cidx = 0;
+ q->gen ^= 1;
+ q->cur_desc = q->desc;
+ }
+}
+
+/**
+ * process_responses - process responses from an SGE response queue
+ * @q: the ingress queue to process
+ * @budget: how many responses can be processed in this round
+ *
+ * Process responses from an SGE response queue up to the supplied budget.
+ * Responses include received packets as well as control messages from FW
+ * or HW.
+ *
+ * Additionally choose the interrupt holdoff time for the next interrupt
+ * on this queue. If the system is under memory shortage use a fairly
+ * long delay to help recovery.
+ */
+static int process_responses(struct sge_rspq *q, int budget)
+{
+ int ret, rsp_type;
+ int budget_left = budget;
+ const struct rsp_ctrl *rc;
+ struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
+
+ while (likely(budget_left)) {
+ rc = (void *)q->cur_desc + (q->iqe_len - sizeof(*rc));
+ if (!is_new_response(rc, q))
+ break;
+
+ rmb();
+ rsp_type = RSPD_TYPE(rc->type_gen);
+ if (likely(rsp_type == RSP_TYPE_FLBUF)) {
+ skb_frag_t *fp;
+ struct pkt_gl si;
+ const struct rx_sw_desc *rsd;
+ u32 len = ntohl(rc->pldbuflen_qid), bufsz, frags;
+
+ if (len & RSPD_NEWBUF) {
+ if (likely(q->offset > 0)) {
+ free_rx_bufs(q->adap, &rxq->fl, 1);
+ q->offset = 0;
+ }
+ len &= RSPD_LEN;
+ }
+ si.tot_len = len;
+
+ /* gather packet fragments */
+ for (frags = 0, fp = si.frags; ; frags++, fp++) {
+ rsd = &rxq->fl.sdesc[rxq->fl.cidx];
+ bufsz = get_buf_size(rsd);
+ fp->page = rsd->page;
+ fp->page_offset = q->offset;
+ fp->size = min(bufsz, len);
+ len -= fp->size;
+ if (!len)
+ break;
+ unmap_rx_buf(q->adap, &rxq->fl);
+ }
+
+ /*
+ * Last buffer remains mapped so explicitly make it
+ * coherent for CPU access.
+ */
+ dma_sync_single_for_cpu(q->adap->pdev_dev,
+ get_buf_addr(rsd),
+ fp->size, DMA_FROM_DEVICE);
+
+ si.va = page_address(si.frags[0].page) +
+ si.frags[0].page_offset;
+ prefetch(si.va);
+
+ si.nfrags = frags + 1;
+ ret = q->handler(q, q->cur_desc, &si);
+ if (likely(ret == 0))
+ q->offset += ALIGN(fp->size, FL_ALIGN);
+ else
+ restore_rx_bufs(&si, &rxq->fl, frags);
+ } else if (likely(rsp_type == RSP_TYPE_CPL)) {
+ ret = q->handler(q, q->cur_desc, NULL);
+ } else {
+ ret = q->handler(q, (const __be64 *)rc, CXGB4_MSG_AN);
+ }
+
+ if (unlikely(ret)) {
+ /* couldn't process descriptor, back off for recovery */
+ q->next_intr_params = QINTR_TIMER_IDX(NOMEM_TMR_IDX);
+ break;
+ }
+
+ rspq_next(q);
+ budget_left--;
+ }
+
+ if (q->offset >= 0 && rxq->fl.size - rxq->fl.avail >= 16)
+ __refill_fl(q->adap, &rxq->fl);
+ return budget - budget_left;
+}
+
+/**
+ * napi_rx_handler - the NAPI handler for Rx processing
+ * @napi: the napi instance
+ * @budget: how many packets we can process in this round
+ *
+ * Handler for new data events when using NAPI. This does not need any
+ * locking or protection from interrupts as data interrupts are off at
+ * this point and other adapter interrupts do not interfere (the latter
+ * in not a concern at all with MSI-X as non-data interrupts then have
+ * a separate handler).
+ */
+static int napi_rx_handler(struct napi_struct *napi, int budget)
+{
+ unsigned int params;
+ struct sge_rspq *q = container_of(napi, struct sge_rspq, napi);
+ int work_done = process_responses(q, budget);
+
+ if (likely(work_done < budget)) {
+ napi_complete(napi);
+ params = q->next_intr_params;
+ q->next_intr_params = q->intr_params;
+ } else
+ params = QINTR_TIMER_IDX(7);
+
+ t4_write_reg(q->adap, MYPF_REG(SGE_PF_GTS), CIDXINC(work_done) |
+ INGRESSQID((u32)q->cntxt_id) | SEINTARM(params));
+ return work_done;
+}
+
+/*
+ * The MSI-X interrupt handler for an SGE response queue.
+ */
+irqreturn_t t4_sge_intr_msix(int irq, void *cookie)
+{
+ struct sge_rspq *q = cookie;
+
+ napi_schedule(&q->napi);
+ return IRQ_HANDLED;
+}
+
+/*
+ * Process the indirect interrupt entries in the interrupt queue and kick off
+ * NAPI for each queue that has generated an entry.
+ */
+static unsigned int process_intrq(struct adapter *adap)
+{
+ unsigned int credits;
+ const struct rsp_ctrl *rc;
+ struct sge_rspq *q = &adap->sge.intrq;
+
+ spin_lock(&adap->sge.intrq_lock);
+ for (credits = 0; ; credits++) {
+ rc = (void *)q->cur_desc + (q->iqe_len - sizeof(*rc));
+ if (!is_new_response(rc, q))
+ break;
+
+ rmb();
+ if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) {
+ unsigned int qid = ntohl(rc->pldbuflen_qid);
+
+ napi_schedule(&adap->sge.ingr_map[qid]->napi);
+ }
+
+ rspq_next(q);
+ }
+
+ t4_write_reg(adap, MYPF_REG(SGE_PF_GTS), CIDXINC(credits) |
+ INGRESSQID(q->cntxt_id) | SEINTARM(q->intr_params));
+ spin_unlock(&adap->sge.intrq_lock);
+ return credits;
+}
+
+/*
+ * The MSI interrupt handler, which handles data events from SGE response queues
+ * as well as error and other async events as they all use the same MSI vector.
+ */
+static irqreturn_t t4_intr_msi(int irq, void *cookie)
+{
+ struct adapter *adap = cookie;
+
+ t4_slow_intr_handler(adap);
+ process_intrq(adap);
+ return IRQ_HANDLED;
+}
+
+/*
+ * Interrupt handler for legacy INTx interrupts.
+ * Handles data events from SGE response queues as well as error and other
+ * async events as they all use the same interrupt line.
+ */
+static irqreturn_t t4_intr_intx(int irq, void *cookie)
+{
+ struct adapter *adap = cookie;
+
+ t4_write_reg(adap, MYPF_REG(PCIE_PF_CLI), 0);
+ if (t4_slow_intr_handler(adap) | process_intrq(adap))
+ return IRQ_HANDLED;
+ return IRQ_NONE; /* probably shared interrupt */
+}
+
+/**
+ * t4_intr_handler - select the top-level interrupt handler
+ * @adap: the adapter
+ *
+ * Selects the top-level interrupt handler based on the type of interrupts
+ * (MSI-X, MSI, or INTx).
+ */
+irq_handler_t t4_intr_handler(struct adapter *adap)
+{
+ if (adap->flags & USING_MSIX)
+ return t4_sge_intr_msix;
+ if (adap->flags & USING_MSI)
+ return t4_intr_msi;
+ return t4_intr_intx;
+}
+
+static void sge_rx_timer_cb(unsigned long data)
+{
+ unsigned long m;
+ unsigned int i, cnt[2];
+ struct adapter *adap = (struct adapter *)data;
+ struct sge *s = &adap->sge;
+
+ for (i = 0; i < ARRAY_SIZE(s->starving_fl); i++)
+ for (m = s->starving_fl[i]; m; m &= m - 1) {
+ struct sge_eth_rxq *rxq;
+ unsigned int id = __ffs(m) + i * BITS_PER_LONG;
+ struct sge_fl *fl = s->egr_map[id];
+
+ clear_bit(id, s->starving_fl);
+ smp_mb__after_clear_bit();
+
+ if (fl_starving(fl)) {
+ rxq = container_of(fl, struct sge_eth_rxq, fl);
+ if (napi_reschedule(&rxq->rspq.napi))
+ fl->starving++;
+ else
+ set_bit(id, s->starving_fl);
+ }
+ }
+
+ t4_write_reg(adap, SGE_DEBUG_INDEX, 13);
+ cnt[0] = t4_read_reg(adap, SGE_DEBUG_DATA_HIGH);
+ cnt[1] = t4_read_reg(adap, SGE_DEBUG_DATA_LOW);
+
+ for (i = 0; i < 2; i++)
+ if (cnt[i] >= s->starve_thres) {
+ if (s->idma_state[i] || cnt[i] == 0xffffffff)
+ continue;
+ s->idma_state[i] = 1;
+ t4_write_reg(adap, SGE_DEBUG_INDEX, 11);
+ m = t4_read_reg(adap, SGE_DEBUG_DATA_LOW) >> (i * 16);
+ dev_warn(adap->pdev_dev,
+ "SGE idma%u starvation detected for "
+ "queue %lu\n", i, m & 0xffff);
+ } else if (s->idma_state[i])
+ s->idma_state[i] = 0;
+
+ mod_timer(&s->rx_timer, jiffies + RX_QCHECK_PERIOD);
+}
+
+static void sge_tx_timer_cb(unsigned long data)
+{
+ unsigned long m;
+ unsigned int i, budget;
+ struct adapter *adap = (struct adapter *)data;
+ struct sge *s = &adap->sge;
+
+ for (i = 0; i < ARRAY_SIZE(s->txq_maperr); i++)
+ for (m = s->txq_maperr[i]; m; m &= m - 1) {
+ unsigned long id = __ffs(m) + i * BITS_PER_LONG;
+ struct sge_ofld_txq *txq = s->egr_map[id];
+
+ clear_bit(id, s->txq_maperr);
+ tasklet_schedule(&txq->qresume_tsk);
+ }
+
+ budget = MAX_TIMER_TX_RECLAIM;
+ i = s->ethtxq_rover;
+ do {
+ struct sge_eth_txq *q = &s->ethtxq[i];
+
+ if (q->q.in_use &&
+ time_after_eq(jiffies, q->txq->trans_start + HZ / 100) &&
+ __netif_tx_trylock(q->txq)) {
+ int avail = reclaimable(&q->q);
+
+ if (avail) {
+ if (avail > budget)
+ avail = budget;
+
+ free_tx_desc(adap, &q->q, avail, true);
+ q->q.in_use -= avail;
+ budget -= avail;
+ }
+ __netif_tx_unlock(q->txq);
+ }
+
+ if (++i >= s->ethqsets)
+ i = 0;
+ } while (budget && i != s->ethtxq_rover);
+ s->ethtxq_rover = i;
+ mod_timer(&s->tx_timer, jiffies + (budget ? TX_QCHECK_PERIOD : 2));
+}
+
+int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
+ struct net_device *dev, int intr_idx,
+ struct sge_fl *fl, rspq_handler_t hnd)
+{
+ int ret, flsz = 0;
+ struct fw_iq_cmd c;
+ struct port_info *pi = netdev_priv(dev);
+
+ /* Size needs to be multiple of 16, including status entry. */
+ iq->size = roundup(iq->size, 16);
+
+ iq->desc = alloc_ring(adap->pdev_dev, iq->size, iq->iqe_len, 0,
+ &iq->phys_addr, NULL, 0);
+ if (!iq->desc)
+ return -ENOMEM;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_CMD_EXEC |
+ FW_IQ_CMD_PFN(0) | FW_IQ_CMD_VFN(0));
+ c.alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | FW_IQ_CMD_IQSTART(1) |
+ FW_LEN16(c));
+ c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) |
+ FW_IQ_CMD_IQASYNCH(fwevtq) | FW_IQ_CMD_VIID(pi->viid) |
+ FW_IQ_CMD_IQANDST(intr_idx < 0) | FW_IQ_CMD_IQANUD(1) |
+ FW_IQ_CMD_IQANDSTINDEX(intr_idx >= 0 ? intr_idx :
+ -intr_idx - 1));
+ c.iqdroprss_to_iqesize = htons(FW_IQ_CMD_IQPCIECH(pi->tx_chan) |
+ FW_IQ_CMD_IQGTSMODE |
+ FW_IQ_CMD_IQINTCNTTHRESH(iq->pktcnt_idx) |
+ FW_IQ_CMD_IQESIZE(ilog2(iq->iqe_len) - 4));
+ c.iqsize = htons(iq->size);
+ c.iqaddr = cpu_to_be64(iq->phys_addr);
+
+ if (fl) {
+ fl->size = roundup(fl->size, 8);
+ fl->desc = alloc_ring(adap->pdev_dev, fl->size, sizeof(__be64),
+ sizeof(struct rx_sw_desc), &fl->addr,
+ &fl->sdesc, STAT_LEN);
+ if (!fl->desc)
+ goto fl_nomem;
+
+ flsz = fl->size / 8 + STAT_LEN / sizeof(struct tx_desc);
+ c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN |
+ FW_IQ_CMD_FL0PADEN);
+ c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) |
+ FW_IQ_CMD_FL0FBMAX(3));
+ c.fl0size = htons(flsz);
+ c.fl0addr = cpu_to_be64(fl->addr);
+ }
+
+ ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+ if (ret)
+ goto err;
+
+ netif_napi_add(dev, &iq->napi, napi_rx_handler, 64);
+ iq->cur_desc = iq->desc;
+ iq->cidx = 0;
+ iq->gen = 1;
+ iq->next_intr_params = iq->intr_params;
+ iq->cntxt_id = ntohs(c.iqid);
+ iq->abs_id = ntohs(c.physiqid);
+ iq->size--; /* subtract status entry */
+ iq->adap = adap;
+ iq->netdev = dev;
+ iq->handler = hnd;
+
+ /* set offset to -1 to distinguish ingress queues without FL */
+ iq->offset = fl ? 0 : -1;
+
+ adap->sge.ingr_map[iq->cntxt_id] = iq;
+
+ if (fl) {
+ fl->cntxt_id = htons(c.fl0id);
+ fl->avail = fl->pend_cred = 0;
+ fl->pidx = fl->cidx = 0;
+ fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0;
+ adap->sge.egr_map[fl->cntxt_id] = fl;
+ refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL);
+ }
+ return 0;
+
+fl_nomem:
+ ret = -ENOMEM;
+err:
+ if (iq->desc) {
+ dma_free_coherent(adap->pdev_dev, iq->size * iq->iqe_len,
+ iq->desc, iq->phys_addr);
+ iq->desc = NULL;
+ }
+ if (fl && fl->desc) {
+ kfree(fl->sdesc);
+ fl->sdesc = NULL;
+ dma_free_coherent(adap->pdev_dev, flsz * sizeof(struct tx_desc),
+ fl->desc, fl->addr);
+ fl->desc = NULL;
+ }
+ return ret;
+}
+
+static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
+{
+ q->in_use = 0;
+ q->cidx = q->pidx = 0;
+ q->stops = q->restarts = 0;
+ q->stat = (void *)&q->desc[q->size];
+ q->cntxt_id = id;
+ adap->sge.egr_map[id] = q;
+}
+
+int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
+ struct net_device *dev, struct netdev_queue *netdevq,
+ unsigned int iqid)
+{
+ int ret, nentries;
+ struct fw_eq_eth_cmd c;
+ struct port_info *pi = netdev_priv(dev);
+
+ /* Add status entries */
+ nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+ txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size,
+ sizeof(struct tx_desc), sizeof(struct tx_sw_desc),
+ &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN);
+ if (!txq->q.desc)
+ return -ENOMEM;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_CMD_EXEC |
+ FW_EQ_ETH_CMD_PFN(0) | FW_EQ_ETH_CMD_VFN(0));
+ c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC |
+ FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c));
+ c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid));
+ c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) |
+ FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) |
+ FW_EQ_ETH_CMD_IQID(iqid));
+ c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) |
+ FW_EQ_ETH_CMD_FBMAX(3) |
+ FW_EQ_ETH_CMD_CIDXFTHRESH(5) |
+ FW_EQ_ETH_CMD_EQSIZE(nentries));
+ c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+ ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+ if (ret) {
+ kfree(txq->q.sdesc);
+ txq->q.sdesc = NULL;
+ dma_free_coherent(adap->pdev_dev,
+ nentries * sizeof(struct tx_desc),
+ txq->q.desc, txq->q.phys_addr);
+ txq->q.desc = NULL;
+ return ret;
+ }
+
+ init_txq(adap, &txq->q, FW_EQ_ETH_CMD_EQID_GET(ntohl(c.eqid_pkd)));
+ txq->txq = netdevq;
+ txq->tso = txq->tx_cso = txq->vlan_ins = 0;
+ txq->mapping_err = 0;
+ return 0;
+}
+
+int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
+ struct net_device *dev, unsigned int iqid,
+ unsigned int cmplqid)
+{
+ int ret, nentries;
+ struct fw_eq_ctrl_cmd c;
+ struct port_info *pi = netdev_priv(dev);
+
+ /* Add status entries */
+ nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+ txq->q.desc = alloc_ring(adap->pdev_dev, nentries,
+ sizeof(struct tx_desc), 0, &txq->q.phys_addr,
+ NULL, 0);
+ if (!txq->q.desc)
+ return -ENOMEM;
+
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_CMD_EXEC |
+ FW_EQ_CTRL_CMD_PFN(0) | FW_EQ_CTRL_CMD_VFN(0));
+ c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_ALLOC |
+ FW_EQ_CTRL_CMD_EQSTART | FW_LEN16(c));
+ c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_CMPLIQID(cmplqid));
+ c.physeqid_pkd = htonl(0);
+ c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE(2) |
+ FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) |
+ FW_EQ_CTRL_CMD_IQID(iqid));
+ c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) |
+ FW_EQ_CTRL_CMD_FBMAX(3) |
+ FW_EQ_CTRL_CMD_CIDXFTHRESH(5) |
+ FW_EQ_CTRL_CMD_EQSIZE(nentries));
+ c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+ ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+ if (ret) {
+ dma_free_coherent(adap->pdev_dev,
+ nentries * sizeof(struct tx_desc),
+ txq->q.desc, txq->q.phys_addr);
+ txq->q.desc = NULL;
+ return ret;
+ }
+
+ init_txq(adap, &txq->q, FW_EQ_CTRL_CMD_EQID_GET(ntohl(c.cmpliqid_eqid)));
+ txq->adap = adap;
+ skb_queue_head_init(&txq->sendq);
+ tasklet_init(&txq->qresume_tsk, restart_ctrlq, (unsigned long)txq);
+ txq->full = 0;
+ return 0;
+}
+
+int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
+ struct net_device *dev, unsigned int iqid)
+{
+ int ret, nentries;
+ struct fw_eq_ofld_cmd c;
+ struct port_info *pi = netdev_priv(dev);
+
+ /* Add status entries */
+ nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+ txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size,
+ sizeof(struct tx_desc), sizeof(struct tx_sw_desc),
+ &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN);
+ if (!txq->q.desc)
+ return -ENOMEM;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_CMD_EXEC |
+ FW_EQ_OFLD_CMD_PFN(0) | FW_EQ_OFLD_CMD_VFN(0));
+ c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC |
+ FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c));
+ c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) |
+ FW_EQ_OFLD_CMD_PCIECHN(pi->tx_chan) |
+ FW_EQ_OFLD_CMD_IQID(iqid));
+ c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) |
+ FW_EQ_OFLD_CMD_FBMAX(3) |
+ FW_EQ_OFLD_CMD_CIDXFTHRESH(5) |
+ FW_EQ_OFLD_CMD_EQSIZE(nentries));
+ c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+ ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+ if (ret) {
+ kfree(txq->q.sdesc);
+ txq->q.sdesc = NULL;
+ dma_free_coherent(adap->pdev_dev,
+ nentries * sizeof(struct tx_desc),
+ txq->q.desc, txq->q.phys_addr);
+ txq->q.desc = NULL;
+ return ret;
+ }
+
+ init_txq(adap, &txq->q, FW_EQ_OFLD_CMD_EQID_GET(ntohl(c.eqid_pkd)));
+ txq->adap = adap;
+ skb_queue_head_init(&txq->sendq);
+ tasklet_init(&txq->qresume_tsk, restart_ofldq, (unsigned long)txq);
+ txq->full = 0;
+ txq->mapping_err = 0;
+ return 0;
+}
+
+static void free_txq(struct adapter *adap, struct sge_txq *q)
+{
+ dma_free_coherent(adap->pdev_dev,
+ q->size * sizeof(struct tx_desc) + STAT_LEN,
+ q->desc, q->phys_addr);
+ q->cntxt_id = 0;
+ q->sdesc = NULL;
+ q->desc = NULL;
+}
+
+static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
+ struct sge_fl *fl)
+{
+ unsigned int fl_id = fl ? fl->cntxt_id : 0xffff;
+
+ adap->sge.ingr_map[rq->cntxt_id] = NULL;
+ t4_iq_free(adap, 0, 0, 0, FW_IQ_TYPE_FL_INT_CAP, rq->cntxt_id, fl_id,
+ 0xffff);
+ dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len,
+ rq->desc, rq->phys_addr);
+ netif_napi_del(&rq->napi);
+ rq->netdev = NULL;
+ rq->cntxt_id = rq->abs_id = 0;
+ rq->desc = NULL;
+
+ if (fl) {
+ free_rx_bufs(adap, fl, fl->avail);
+ dma_free_coherent(adap->pdev_dev, fl->size * 8 + STAT_LEN,
+ fl->desc, fl->addr);
+ kfree(fl->sdesc);
+ fl->sdesc = NULL;
+ fl->cntxt_id = 0;
+ fl->desc = NULL;
+ }
+}
+
+/**
+ * t4_free_sge_resources - free SGE resources
+ * @adap: the adapter
+ *
+ * Frees resources used by the SGE queue sets.
+ */
+void t4_free_sge_resources(struct adapter *adap)
+{
+ int i;
+ struct sge_eth_rxq *eq = adap->sge.ethrxq;
+ struct sge_eth_txq *etq = adap->sge.ethtxq;
+ struct sge_ofld_rxq *oq = adap->sge.ofldrxq;
+
+ /* clean up Ethernet Tx/Rx queues */
+ for (i = 0; i < adap->sge.ethqsets; i++, eq++, etq++) {
+ if (eq->rspq.desc)
+ free_rspq_fl(adap, &eq->rspq, &eq->fl);
+ if (etq->q.desc) {
+ t4_eth_eq_free(adap, 0, 0, 0, etq->q.cntxt_id);
+ free_tx_desc(adap, &etq->q, etq->q.in_use, true);
+ kfree(etq->q.sdesc);
+ free_txq(adap, &etq->q);
+ }
+ }
+
+ /* clean up RDMA and iSCSI Rx queues */
+ for (i = 0; i < adap->sge.ofldqsets; i++, oq++) {
+ if (oq->rspq.desc)
+ free_rspq_fl(adap, &oq->rspq, &oq->fl);
+ }
+ for (i = 0, oq = adap->sge.rdmarxq; i < adap->sge.rdmaqs; i++, oq++) {
+ if (oq->rspq.desc)
+ free_rspq_fl(adap, &oq->rspq, &oq->fl);
+ }
+
+ /* clean up offload Tx queues */
+ for (i = 0; i < ARRAY_SIZE(adap->sge.ofldtxq); i++) {
+ struct sge_ofld_txq *q = &adap->sge.ofldtxq[i];
+
+ if (q->q.desc) {
+ tasklet_kill(&q->qresume_tsk);
+ t4_ofld_eq_free(adap, 0, 0, 0, q->q.cntxt_id);
+ free_tx_desc(adap, &q->q, q->q.in_use, false);
+ kfree(q->q.sdesc);
+ __skb_queue_purge(&q->sendq);
+ free_txq(adap, &q->q);
+ }
+ }
+
+ /* clean up control Tx queues */
+ for (i = 0; i < ARRAY_SIZE(adap->sge.ctrlq); i++) {
+ struct sge_ctrl_txq *cq = &adap->sge.ctrlq[i];
+
+ if (cq->q.desc) {
+ tasklet_kill(&cq->qresume_tsk);
+ t4_ctrl_eq_free(adap, 0, 0, 0, cq->q.cntxt_id);
+ __skb_queue_purge(&cq->sendq);
+ free_txq(adap, &cq->q);
+ }
+ }
+
+ if (adap->sge.fw_evtq.desc)
+ free_rspq_fl(adap, &adap->sge.fw_evtq, NULL);
+
+ if (adap->sge.intrq.desc)
+ free_rspq_fl(adap, &adap->sge.intrq, NULL);
+
+ /* clear the reverse egress queue map */
+ memset(adap->sge.egr_map, 0, sizeof(adap->sge.egr_map));
+}
+
+void t4_sge_start(struct adapter *adap)
+{
+ adap->sge.ethtxq_rover = 0;
+ mod_timer(&adap->sge.rx_timer, jiffies + RX_QCHECK_PERIOD);
+ mod_timer(&adap->sge.tx_timer, jiffies + TX_QCHECK_PERIOD);
+}
+
+/**
+ * t4_sge_stop - disable SGE operation
+ * @adap: the adapter
+ *
+ * Stop tasklets and timers associated with the DMA engine. Note that
+ * this is effective only if measures have been taken to disable any HW
+ * events that may restart them.
+ */
+void t4_sge_stop(struct adapter *adap)
+{
+ int i;
+ struct sge *s = &adap->sge;
+
+ if (in_interrupt()) /* actions below require waiting */
+ return;
+
+ if (s->rx_timer.function)
+ del_timer_sync(&s->rx_timer);
+ if (s->tx_timer.function)
+ del_timer_sync(&s->tx_timer);
+
+ for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++) {
+ struct sge_ofld_txq *q = &s->ofldtxq[i];
+
+ if (q->q.desc)
+ tasklet_kill(&q->qresume_tsk);
+ }
+ for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++) {
+ struct sge_ctrl_txq *cq = &s->ctrlq[i];
+
+ if (cq->q.desc)
+ tasklet_kill(&cq->qresume_tsk);
+ }
+}
+
+/**
+ * t4_sge_init - initialize SGE
+ * @adap: the adapter
+ *
+ * Performs SGE initialization needed every time after a chip reset.
+ * We do not initialize any of the queues here, instead the driver
+ * top-level must request them individually.
+ */
+void t4_sge_init(struct adapter *adap)
+{
+ struct sge *s = &adap->sge;
+ unsigned int fl_align_log = ilog2(FL_ALIGN);
+
+ t4_set_reg_field(adap, SGE_CONTROL, PKTSHIFT_MASK |
+ INGPADBOUNDARY_MASK | EGRSTATUSPAGESIZE,
+ INGPADBOUNDARY(fl_align_log - 5) | PKTSHIFT(2) |
+ RXPKTCPLMODE |
+ (STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0));
+ t4_set_reg_field(adap, SGE_HOST_PAGE_SIZE, HOSTPAGESIZEPF0_MASK,
+ HOSTPAGESIZEPF0(PAGE_SHIFT - 10));
+ t4_write_reg(adap, SGE_FL_BUFFER_SIZE0, PAGE_SIZE);
+#if FL_PG_ORDER > 0
+ t4_write_reg(adap, SGE_FL_BUFFER_SIZE1, PAGE_SIZE << FL_PG_ORDER);
+#endif
+ t4_write_reg(adap, SGE_INGRESS_RX_THRESHOLD,
+ THRESHOLD_0(s->counter_val[0]) |
+ THRESHOLD_1(s->counter_val[1]) |
+ THRESHOLD_2(s->counter_val[2]) |
+ THRESHOLD_3(s->counter_val[3]));
+ t4_write_reg(adap, SGE_TIMER_VALUE_0_AND_1,
+ TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[0])) |
+ TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[1])));
+ t4_write_reg(adap, SGE_TIMER_VALUE_2_AND_3,
+ TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[2])) |
+ TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[3])));
+ t4_write_reg(adap, SGE_TIMER_VALUE_4_AND_5,
+ TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[4])) |
+ TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[5])));
+ setup_timer(&s->rx_timer, sge_rx_timer_cb, (unsigned long)adap);
+ setup_timer(&s->tx_timer, sge_tx_timer_cb, (unsigned long)adap);
+ s->starve_thres = core_ticks_per_usec(adap) * 1000000; /* 1 s */
+ s->idma_state[0] = s->idma_state[1] = 0;
+ spin_lock_init(&s->intrq_lock);
+}
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
new file mode 100644
index 00000000000..a814a3afe12
--- /dev/null
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -0,0 +1,3131 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4fw_api.h"
+
+/**
+ * t4_wait_op_done_val - wait until an operation is completed
+ * @adapter: the adapter performing the operation
+ * @reg: the register to check for completion
+ * @mask: a single-bit field within @reg that indicates completion
+ * @polarity: the value of the field when the operation is completed
+ * @attempts: number of check iterations
+ * @delay: delay in usecs between iterations
+ * @valp: where to store the value of the register at completion time
+ *
+ * Wait until an operation is completed by checking a bit in a register
+ * up to @attempts times. If @valp is not NULL the value of the register
+ * at the time it indicated completion is stored there. Returns 0 if the
+ * operation completes and -EAGAIN otherwise.
+ */
+int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
+ int polarity, int attempts, int delay, u32 *valp)
+{
+ while (1) {
+ u32 val = t4_read_reg(adapter, reg);
+
+ if (!!(val & mask) == polarity) {
+ if (valp)
+ *valp = val;
+ return 0;
+ }
+ if (--attempts == 0)
+ return -EAGAIN;
+ if (delay)
+ udelay(delay);
+ }
+}
+
+static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask,
+ int polarity, int attempts, int delay)
+{
+ return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts,
+ delay, NULL);
+}
+
+/**
+ * t4_set_reg_field - set a register field to a value
+ * @adapter: the adapter to program
+ * @addr: the register address
+ * @mask: specifies the portion of the register to modify
+ * @val: the new value for the register field
+ *
+ * Sets a register field specified by the supplied mask to the
+ * given value.
+ */
+void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
+ u32 val)
+{
+ u32 v = t4_read_reg(adapter, addr) & ~mask;
+
+ t4_write_reg(adapter, addr, v | val);
+ (void) t4_read_reg(adapter, addr); /* flush */
+}
+
+/**
+ * t4_read_indirect - read indirectly addressed registers
+ * @adap: the adapter
+ * @addr_reg: register holding the indirect address
+ * @data_reg: register holding the value of the indirect register
+ * @vals: where the read register values are stored
+ * @nregs: how many indirect registers to read
+ * @start_idx: index of first indirect register to read
+ *
+ * Reads registers that are accessed indirectly through an address/data
+ * register pair.
+ */
+void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
+ unsigned int data_reg, u32 *vals, unsigned int nregs,
+ unsigned int start_idx)
+{
+ while (nregs--) {
+ t4_write_reg(adap, addr_reg, start_idx);
+ *vals++ = t4_read_reg(adap, data_reg);
+ start_idx++;
+ }
+}
+
+/**
+ * t4_write_indirect - write indirectly addressed registers
+ * @adap: the adapter
+ * @addr_reg: register holding the indirect addresses
+ * @data_reg: register holding the value for the indirect registers
+ * @vals: values to write
+ * @nregs: how many indirect registers to write
+ * @start_idx: address of first indirect register to write
+ *
+ * Writes a sequential block of registers that are accessed indirectly
+ * through an address/data register pair.
+ */
+void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
+ unsigned int data_reg, const u32 *vals,
+ unsigned int nregs, unsigned int start_idx)
+{
+ while (nregs--) {
+ t4_write_reg(adap, addr_reg, start_idx++);
+ t4_write_reg(adap, data_reg, *vals++);
+ }
+}
+
+/*
+ * Get the reply to a mailbox command and store it in @rpl in big-endian order.
+ */
+static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit,
+ u32 mbox_addr)
+{
+ for ( ; nflit; nflit--, mbox_addr += 8)
+ *rpl++ = cpu_to_be64(t4_read_reg64(adap, mbox_addr));
+}
+
+/*
+ * Handle a FW assertion reported in a mailbox.
+ */
+static void fw_asrt(struct adapter *adap, u32 mbox_addr)
+{
+ struct fw_debug_cmd asrt;
+
+ get_mbox_rpl(adap, (__be64 *)&asrt, sizeof(asrt) / 8, mbox_addr);
+ dev_alert(adap->pdev_dev,
+ "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n",
+ asrt.u.assert.filename_0_7, ntohl(asrt.u.assert.line),
+ ntohl(asrt.u.assert.x), ntohl(asrt.u.assert.y));
+}
+
+static void dump_mbox(struct adapter *adap, int mbox, u32 data_reg)
+{
+ dev_err(adap->pdev_dev,
+ "mbox %d: %llx %llx %llx %llx %llx %llx %llx %llx\n", mbox,
+ (unsigned long long)t4_read_reg64(adap, data_reg),
+ (unsigned long long)t4_read_reg64(adap, data_reg + 8),
+ (unsigned long long)t4_read_reg64(adap, data_reg + 16),
+ (unsigned long long)t4_read_reg64(adap, data_reg + 24),
+ (unsigned long long)t4_read_reg64(adap, data_reg + 32),
+ (unsigned long long)t4_read_reg64(adap, data_reg + 40),
+ (unsigned long long)t4_read_reg64(adap, data_reg + 48),
+ (unsigned long long)t4_read_reg64(adap, data_reg + 56));
+}
+
+/**
+ * t4_wr_mbox_meat - send a command to FW through the given mailbox
+ * @adap: the adapter
+ * @mbox: index of the mailbox to use
+ * @cmd: the command to write
+ * @size: command length in bytes
+ * @rpl: where to optionally store the reply
+ * @sleep_ok: if true we may sleep while awaiting command completion
+ *
+ * Sends the given command to FW through the selected mailbox and waits
+ * for the FW to execute the command. If @rpl is not %NULL it is used to
+ * store the FW's reply to the command. The command and its optional
+ * reply are of the same length. FW can take up to %FW_CMD_MAX_TIMEOUT ms
+ * to respond. @sleep_ok determines whether we may sleep while awaiting
+ * the response. If sleeping is allowed we use progressive backoff
+ * otherwise we spin.
+ *
+ * The return value is 0 on success or a negative errno on failure. A
+ * failure can happen either because we are not able to execute the
+ * command or FW executes it but signals an error. In the latter case
+ * the return value is the error code indicated by FW (negated).
+ */
+int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
+ void *rpl, bool sleep_ok)
+{
+ static int delay[] = {
+ 1, 1, 3, 5, 10, 10, 20, 50, 100, 200
+ };
+
+ u32 v;
+ u64 res;
+ int i, ms, delay_idx;
+ const __be64 *p = cmd;
+ u32 data_reg = PF_REG(mbox, CIM_PF_MAILBOX_DATA);
+ u32 ctl_reg = PF_REG(mbox, CIM_PF_MAILBOX_CTRL);
+
+ if ((size & 15) || size > MBOX_LEN)
+ return -EINVAL;
+
+ v = MBOWNER_GET(t4_read_reg(adap, ctl_reg));
+ for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
+ v = MBOWNER_GET(t4_read_reg(adap, ctl_reg));
+
+ if (v != MBOX_OWNER_DRV)
+ return v ? -EBUSY : -ETIMEDOUT;
+
+ for (i = 0; i < size; i += 8)
+ t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p++));
+
+ t4_write_reg(adap, ctl_reg, MBMSGVALID | MBOWNER(MBOX_OWNER_FW));
+ t4_read_reg(adap, ctl_reg); /* flush write */
+
+ delay_idx = 0;
+ ms = delay[0];
+
+ for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) {
+ if (sleep_ok) {
+ ms = delay[delay_idx]; /* last element may repeat */
+ if (delay_idx < ARRAY_SIZE(delay) - 1)
+ delay_idx++;
+ msleep(ms);
+ } else
+ mdelay(ms);
+
+ v = t4_read_reg(adap, ctl_reg);
+ if (MBOWNER_GET(v) == MBOX_OWNER_DRV) {
+ if (!(v & MBMSGVALID)) {
+ t4_write_reg(adap, ctl_reg, 0);
+ continue;
+ }
+
+ res = t4_read_reg64(adap, data_reg);
+ if (FW_CMD_OP_GET(res >> 32) == FW_DEBUG_CMD) {
+ fw_asrt(adap, data_reg);
+ res = FW_CMD_RETVAL(EIO);
+ } else if (rpl)
+ get_mbox_rpl(adap, rpl, size / 8, data_reg);
+
+ if (FW_CMD_RETVAL_GET((int)res))
+ dump_mbox(adap, mbox, data_reg);
+ t4_write_reg(adap, ctl_reg, 0);
+ return -FW_CMD_RETVAL_GET((int)res);
+ }
+ }
+
+ dump_mbox(adap, mbox, data_reg);
+ dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
+ *(const u8 *)cmd, mbox);
+ return -ETIMEDOUT;
+}
+
+/**
+ * t4_mc_read - read from MC through backdoor accesses
+ * @adap: the adapter
+ * @addr: address of first byte requested
+ * @data: 64 bytes of data containing the requested address
+ * @ecc: where to store the corresponding 64-bit ECC word
+ *
+ * Read 64 bytes of data from MC starting at a 64-byte-aligned address
+ * that covers the requested address @addr. If @parity is not %NULL it
+ * is assigned the 64-bit ECC word for the read data.
+ */
+int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *ecc)
+{
+ int i;
+
+ if (t4_read_reg(adap, MC_BIST_CMD) & START_BIST)
+ return -EBUSY;
+ t4_write_reg(adap, MC_BIST_CMD_ADDR, addr & ~0x3fU);
+ t4_write_reg(adap, MC_BIST_CMD_LEN, 64);
+ t4_write_reg(adap, MC_BIST_DATA_PATTERN, 0xc);
+ t4_write_reg(adap, MC_BIST_CMD, BIST_OPCODE(1) | START_BIST |
+ BIST_CMD_GAP(1));
+ i = t4_wait_op_done(adap, MC_BIST_CMD, START_BIST, 0, 10, 1);
+ if (i)
+ return i;
+
+#define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i)
+
+ for (i = 15; i >= 0; i--)
+ *data++ = htonl(t4_read_reg(adap, MC_DATA(i)));
+ if (ecc)
+ *ecc = t4_read_reg64(adap, MC_DATA(16));
+#undef MC_DATA
+ return 0;
+}
+
+/**
+ * t4_edc_read - read from EDC through backdoor accesses
+ * @adap: the adapter
+ * @idx: which EDC to access
+ * @addr: address of first byte requested
+ * @data: 64 bytes of data containing the requested address
+ * @ecc: where to store the corresponding 64-bit ECC word
+ *
+ * Read 64 bytes of data from EDC starting at a 64-byte-aligned address
+ * that covers the requested address @addr. If @parity is not %NULL it
+ * is assigned the 64-bit ECC word for the read data.
+ */
+int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
+{
+ int i;
+
+ idx *= EDC_STRIDE;
+ if (t4_read_reg(adap, EDC_BIST_CMD + idx) & START_BIST)
+ return -EBUSY;
+ t4_write_reg(adap, EDC_BIST_CMD_ADDR + idx, addr & ~0x3fU);
+ t4_write_reg(adap, EDC_BIST_CMD_LEN + idx, 64);
+ t4_write_reg(adap, EDC_BIST_DATA_PATTERN + idx, 0xc);
+ t4_write_reg(adap, EDC_BIST_CMD + idx,
+ BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST);
+ i = t4_wait_op_done(adap, EDC_BIST_CMD + idx, START_BIST, 0, 10, 1);
+ if (i)
+ return i;
+
+#define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx)
+
+ for (i = 15; i >= 0; i--)
+ *data++ = htonl(t4_read_reg(adap, EDC_DATA(i)));
+ if (ecc)
+ *ecc = t4_read_reg64(adap, EDC_DATA(16));
+#undef EDC_DATA
+ return 0;
+}
+
+#define VPD_ENTRY(name, len) \
+ u8 name##_kword[2]; u8 name##_len; u8 name##_data[len]
+
+/*
+ * Partial EEPROM Vital Product Data structure. Includes only the ID and
+ * VPD-R sections.
+ */
+struct t4_vpd {
+ u8 id_tag;
+ u8 id_len[2];
+ u8 id_data[ID_LEN];
+ u8 vpdr_tag;
+ u8 vpdr_len[2];
+ VPD_ENTRY(pn, 16); /* part number */
+ VPD_ENTRY(ec, EC_LEN); /* EC level */
+ VPD_ENTRY(sn, SERNUM_LEN); /* serial number */
+ VPD_ENTRY(na, 12); /* MAC address base */
+ VPD_ENTRY(port_type, 8); /* port types */
+ VPD_ENTRY(gpio, 14); /* GPIO usage */
+ VPD_ENTRY(cclk, 6); /* core clock */
+ VPD_ENTRY(port_addr, 8); /* port MDIO addresses */
+ VPD_ENTRY(rv, 1); /* csum */
+ u32 pad; /* for multiple-of-4 sizing and alignment */
+};
+
+#define EEPROM_STAT_ADDR 0x7bfc
+#define VPD_BASE 0
+
+/**
+ * t4_seeprom_wp - enable/disable EEPROM write protection
+ * @adapter: the adapter
+ * @enable: whether to enable or disable write protection
+ *
+ * Enables or disables write protection on the serial EEPROM.
+ */
+int t4_seeprom_wp(struct adapter *adapter, bool enable)
+{
+ unsigned int v = enable ? 0xc : 0;
+ int ret = pci_write_vpd(adapter->pdev, EEPROM_STAT_ADDR, 4, &v);
+ return ret < 0 ? ret : 0;
+}
+
+/**
+ * get_vpd_params - read VPD parameters from VPD EEPROM
+ * @adapter: adapter to read
+ * @p: where to store the parameters
+ *
+ * Reads card parameters stored in VPD EEPROM.
+ */
+static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
+{
+ int ret;
+ struct t4_vpd vpd;
+ u8 *q = (u8 *)&vpd, csum;
+
+ ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), &vpd);
+ if (ret < 0)
+ return ret;
+
+ for (csum = 0; q <= vpd.rv_data; q++)
+ csum += *q;
+
+ if (csum) {
+ dev_err(adapter->pdev_dev,
+ "corrupted VPD EEPROM, actual csum %u\n", csum);
+ return -EINVAL;
+ }
+
+ p->cclk = simple_strtoul(vpd.cclk_data, NULL, 10);
+ memcpy(p->id, vpd.id_data, sizeof(vpd.id_data));
+ strim(p->id);
+ memcpy(p->ec, vpd.ec_data, sizeof(vpd.ec_data));
+ strim(p->ec);
+ memcpy(p->sn, vpd.sn_data, sizeof(vpd.sn_data));
+ strim(p->sn);
+ return 0;
+}
+
+/* serial flash and firmware constants */
+enum {
+ SF_ATTEMPTS = 10, /* max retries for SF operations */
+
+ /* flash command opcodes */
+ SF_PROG_PAGE = 2, /* program page */
+ SF_WR_DISABLE = 4, /* disable writes */
+ SF_RD_STATUS = 5, /* read status register */
+ SF_WR_ENABLE = 6, /* enable writes */
+ SF_RD_DATA_FAST = 0xb, /* read flash */
+ SF_ERASE_SECTOR = 0xd8, /* erase sector */
+
+ FW_START_SEC = 8, /* first flash sector for FW */
+ FW_END_SEC = 15, /* last flash sector for FW */
+ FW_IMG_START = FW_START_SEC * SF_SEC_SIZE,
+ FW_MAX_SIZE = (FW_END_SEC - FW_START_SEC + 1) * SF_SEC_SIZE,
+};
+
+/**
+ * sf1_read - read data from the serial flash
+ * @adapter: the adapter
+ * @byte_cnt: number of bytes to read
+ * @cont: whether another operation will be chained
+ * @lock: whether to lock SF for PL access only
+ * @valp: where to store the read data
+ *
+ * Reads up to 4 bytes of data from the serial flash. The location of
+ * the read needs to be specified prior to calling this by issuing the
+ * appropriate commands to the serial flash.
+ */
+static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont,
+ int lock, u32 *valp)
+{
+ int ret;
+
+ if (!byte_cnt || byte_cnt > 4)
+ return -EINVAL;
+ if (t4_read_reg(adapter, SF_OP) & BUSY)
+ return -EBUSY;
+ cont = cont ? SF_CONT : 0;
+ lock = lock ? SF_LOCK : 0;
+ t4_write_reg(adapter, SF_OP, lock | cont | BYTECNT(byte_cnt - 1));
+ ret = t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5);
+ if (!ret)
+ *valp = t4_read_reg(adapter, SF_DATA);
+ return ret;
+}
+
+/**
+ * sf1_write - write data to the serial flash
+ * @adapter: the adapter
+ * @byte_cnt: number of bytes to write
+ * @cont: whether another operation will be chained
+ * @lock: whether to lock SF for PL access only
+ * @val: value to write
+ *
+ * Writes up to 4 bytes of data to the serial flash. The location of
+ * the write needs to be specified prior to calling this by issuing the
+ * appropriate commands to the serial flash.
+ */
+static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont,
+ int lock, u32 val)
+{
+ if (!byte_cnt || byte_cnt > 4)
+ return -EINVAL;
+ if (t4_read_reg(adapter, SF_OP) & BUSY)
+ return -EBUSY;
+ cont = cont ? SF_CONT : 0;
+ lock = lock ? SF_LOCK : 0;
+ t4_write_reg(adapter, SF_DATA, val);
+ t4_write_reg(adapter, SF_OP, lock |
+ cont | BYTECNT(byte_cnt - 1) | OP_WR);
+ return t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5);
+}
+
+/**
+ * flash_wait_op - wait for a flash operation to complete
+ * @adapter: the adapter
+ * @attempts: max number of polls of the status register
+ * @delay: delay between polls in ms
+ *
+ * Wait for a flash operation to complete by polling the status register.
+ */
+static int flash_wait_op(struct adapter *adapter, int attempts, int delay)
+{
+ int ret;
+ u32 status;
+
+ while (1) {
+ if ((ret = sf1_write(adapter, 1, 1, 1, SF_RD_STATUS)) != 0 ||
+ (ret = sf1_read(adapter, 1, 0, 1, &status)) != 0)
+ return ret;
+ if (!(status & 1))
+ return 0;
+ if (--attempts == 0)
+ return -EAGAIN;
+ if (delay)
+ msleep(delay);
+ }
+}
+
+/**
+ * t4_read_flash - read words from serial flash
+ * @adapter: the adapter
+ * @addr: the start address for the read
+ * @nwords: how many 32-bit words to read
+ * @data: where to store the read data
+ * @byte_oriented: whether to store data as bytes or as words
+ *
+ * Read the specified number of 32-bit words from the serial flash.
+ * If @byte_oriented is set the read data is stored as a byte array
+ * (i.e., big-endian), otherwise as 32-bit words in the platform's
+ * natural endianess.
+ */
+int t4_read_flash(struct adapter *adapter, unsigned int addr,
+ unsigned int nwords, u32 *data, int byte_oriented)
+{
+ int ret;
+
+ if (addr + nwords * sizeof(u32) > SF_SIZE || (addr & 3))
+ return -EINVAL;
+
+ addr = swab32(addr) | SF_RD_DATA_FAST;
+
+ if ((ret = sf1_write(adapter, 4, 1, 0, addr)) != 0 ||
+ (ret = sf1_read(adapter, 1, 1, 0, data)) != 0)
+ return ret;
+
+ for ( ; nwords; nwords--, data++) {
+ ret = sf1_read(adapter, 4, nwords > 1, nwords == 1, data);
+ if (nwords == 1)
+ t4_write_reg(adapter, SF_OP, 0); /* unlock SF */
+ if (ret)
+ return ret;
+ if (byte_oriented)
+ *data = htonl(*data);
+ }
+ return 0;
+}
+
+/**
+ * t4_write_flash - write up to a page of data to the serial flash
+ * @adapter: the adapter
+ * @addr: the start address to write
+ * @n: length of data to write in bytes
+ * @data: the data to write
+ *
+ * Writes up to a page of data (256 bytes) to the serial flash starting
+ * at the given address. All the data must be written to the same page.
+ */
+static int t4_write_flash(struct adapter *adapter, unsigned int addr,
+ unsigned int n, const u8 *data)
+{
+ int ret;
+ u32 buf[64];
+ unsigned int i, c, left, val, offset = addr & 0xff;
+
+ if (addr >= SF_SIZE || offset + n > SF_PAGE_SIZE)
+ return -EINVAL;
+
+ val = swab32(addr) | SF_PROG_PAGE;
+
+ if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
+ (ret = sf1_write(adapter, 4, 1, 1, val)) != 0)
+ goto unlock;
+
+ for (left = n; left; left -= c) {
+ c = min(left, 4U);
+ for (val = 0, i = 0; i < c; ++i)
+ val = (val << 8) + *data++;
+
+ ret = sf1_write(adapter, c, c != left, 1, val);
+ if (ret)
+ goto unlock;
+ }
+ ret = flash_wait_op(adapter, 5, 1);
+ if (ret)
+ goto unlock;
+
+ t4_write_reg(adapter, SF_OP, 0); /* unlock SF */
+
+ /* Read the page to verify the write succeeded */
+ ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1);
+ if (ret)
+ return ret;
+
+ if (memcmp(data - n, (u8 *)buf + offset, n)) {
+ dev_err(adapter->pdev_dev,
+ "failed to correctly write the flash page at %#x\n",
+ addr);
+ return -EIO;
+ }
+ return 0;
+
+unlock:
+ t4_write_reg(adapter, SF_OP, 0); /* unlock SF */
+ return ret;
+}
+
+/**
+ * get_fw_version - read the firmware version
+ * @adapter: the adapter
+ * @vers: where to place the version
+ *
+ * Reads the FW version from flash.
+ */
+static int get_fw_version(struct adapter *adapter, u32 *vers)
+{
+ return t4_read_flash(adapter,
+ FW_IMG_START + offsetof(struct fw_hdr, fw_ver), 1,
+ vers, 0);
+}
+
+/**
+ * get_tp_version - read the TP microcode version
+ * @adapter: the adapter
+ * @vers: where to place the version
+ *
+ * Reads the TP microcode version from flash.
+ */
+static int get_tp_version(struct adapter *adapter, u32 *vers)
+{
+ return t4_read_flash(adapter, FW_IMG_START + offsetof(struct fw_hdr,
+ tp_microcode_ver),
+ 1, vers, 0);
+}
+
+/**
+ * t4_check_fw_version - check if the FW is compatible with this driver
+ * @adapter: the adapter
+ *
+ * Checks if an adapter's FW is compatible with the driver. Returns 0
+ * if there's exact match, a negative error if the version could not be
+ * read or there's a major version mismatch, and a positive value if the
+ * expected major version is found but there's a minor version mismatch.
+ */
+int t4_check_fw_version(struct adapter *adapter)
+{
+ u32 api_vers[2];
+ int ret, major, minor, micro;
+
+ ret = get_fw_version(adapter, &adapter->params.fw_vers);
+ if (!ret)
+ ret = get_tp_version(adapter, &adapter->params.tp_vers);
+ if (!ret)
+ ret = t4_read_flash(adapter,
+ FW_IMG_START + offsetof(struct fw_hdr, intfver_nic),
+ 2, api_vers, 1);
+ if (ret)
+ return ret;
+
+ major = FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers);
+ minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers);
+ micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers);
+ memcpy(adapter->params.api_vers, api_vers,
+ sizeof(adapter->params.api_vers));
+
+ if (major != FW_VERSION_MAJOR) { /* major mismatch - fail */
+ dev_err(adapter->pdev_dev,
+ "card FW has major version %u, driver wants %u\n",
+ major, FW_VERSION_MAJOR);
+ return -EINVAL;
+ }
+
+ if (minor == FW_VERSION_MINOR && micro == FW_VERSION_MICRO)
+ return 0; /* perfect match */
+
+ /* Minor/micro version mismatch. Report it but often it's OK. */
+ return 1;
+}
+
+/**
+ * t4_flash_erase_sectors - erase a range of flash sectors
+ * @adapter: the adapter
+ * @start: the first sector to erase
+ * @end: the last sector to erase
+ *
+ * Erases the sectors in the given inclusive range.
+ */
+static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end)
+{
+ int ret = 0;
+
+ while (start <= end) {
+ if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
+ (ret = sf1_write(adapter, 4, 0, 1,
+ SF_ERASE_SECTOR | (start << 8))) != 0 ||
+ (ret = flash_wait_op(adapter, 5, 500)) != 0) {
+ dev_err(adapter->pdev_dev,
+ "erase of flash sector %d failed, error %d\n",
+ start, ret);
+ break;
+ }
+ start++;
+ }
+ t4_write_reg(adapter, SF_OP, 0); /* unlock SF */
+ return ret;
+}
+
+/**
+ * t4_load_fw - download firmware
+ * @adap: the adapter
+ * @fw_data: the firmware image to write
+ * @size: image size
+ *
+ * Write the supplied firmware image to the card's serial flash.
+ */
+int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
+{
+ u32 csum;
+ int ret, addr;
+ unsigned int i;
+ u8 first_page[SF_PAGE_SIZE];
+ const u32 *p = (const u32 *)fw_data;
+ const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
+
+ if (!size) {
+ dev_err(adap->pdev_dev, "FW image has no data\n");
+ return -EINVAL;
+ }
+ if (size & 511) {
+ dev_err(adap->pdev_dev,
+ "FW image size not multiple of 512 bytes\n");
+ return -EINVAL;
+ }
+ if (ntohs(hdr->len512) * 512 != size) {
+ dev_err(adap->pdev_dev,
+ "FW image size differs from size in FW header\n");
+ return -EINVAL;
+ }
+ if (size > FW_MAX_SIZE) {
+ dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n",
+ FW_MAX_SIZE);
+ return -EFBIG;
+ }
+
+ for (csum = 0, i = 0; i < size / sizeof(csum); i++)
+ csum += ntohl(p[i]);
+
+ if (csum != 0xffffffff) {
+ dev_err(adap->pdev_dev,
+ "corrupted firmware image, checksum %#x\n", csum);
+ return -EINVAL;
+ }
+
+ i = DIV_ROUND_UP(size, SF_SEC_SIZE); /* # of sectors spanned */
+ ret = t4_flash_erase_sectors(adap, FW_START_SEC, FW_START_SEC + i - 1);
+ if (ret)
+ goto out;
+
+ /*
+ * We write the correct version at the end so the driver can see a bad
+ * version if the FW write fails. Start by writing a copy of the
+ * first page with a bad version.
+ */
+ memcpy(first_page, fw_data, SF_PAGE_SIZE);
+ ((struct fw_hdr *)first_page)->fw_ver = htonl(0xffffffff);
+ ret = t4_write_flash(adap, FW_IMG_START, SF_PAGE_SIZE, first_page);
+ if (ret)
+ goto out;
+
+ addr = FW_IMG_START;
+ for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
+ addr += SF_PAGE_SIZE;
+ fw_data += SF_PAGE_SIZE;
+ ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data);
+ if (ret)
+ goto out;
+ }
+
+ ret = t4_write_flash(adap,
+ FW_IMG_START + offsetof(struct fw_hdr, fw_ver),
+ sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver);
+out:
+ if (ret)
+ dev_err(adap->pdev_dev, "firmware download failed, error %d\n",
+ ret);
+ return ret;
+}
+
+#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
+ FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG)
+
+/**
+ * t4_link_start - apply link configuration to MAC/PHY
+ * @phy: the PHY to setup
+ * @mac: the MAC to setup
+ * @lc: the requested link configuration
+ *
+ * Set up a port's MAC and PHY according to a desired link configuration.
+ * - If the PHY can auto-negotiate first decide what to advertise, then
+ * enable/disable auto-negotiation as desired, and reset.
+ * - If the PHY does not auto-negotiate just reset it.
+ * - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
+ * otherwise do it later based on the outcome of auto-negotiation.
+ */
+int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
+ struct link_config *lc)
+{
+ struct fw_port_cmd c;
+ unsigned int fc = 0, mdi = FW_PORT_MDI(FW_PORT_MDI_AUTO);
+
+ lc->link_ok = 0;
+ if (lc->requested_fc & PAUSE_RX)
+ fc |= FW_PORT_CAP_FC_RX;
+ if (lc->requested_fc & PAUSE_TX)
+ fc |= FW_PORT_CAP_FC_TX;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_PORT_CMD_PORTID(port));
+ c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+ FW_LEN16(c));
+
+ if (!(lc->supported & FW_PORT_CAP_ANEG)) {
+ c.u.l1cfg.rcap = htonl((lc->supported & ADVERT_MASK) | fc);
+ lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
+ } else if (lc->autoneg == AUTONEG_DISABLE) {
+ c.u.l1cfg.rcap = htonl(lc->requested_speed | fc | mdi);
+ lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
+ } else
+ c.u.l1cfg.rcap = htonl(lc->advertising | fc | mdi);
+
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_restart_aneg - restart autonegotiation
+ * @adap: the adapter
+ * @mbox: mbox to use for the FW command
+ * @port: the port id
+ *
+ * Restarts autonegotiation for the selected port.
+ */
+int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
+{
+ struct fw_port_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_PORT_CMD_PORTID(port));
+ c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+ FW_LEN16(c));
+ c.u.l1cfg.rcap = htonl(FW_PORT_CAP_ANEG);
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_set_vlan_accel - configure HW VLAN extraction
+ * @adap: the adapter
+ * @ports: bitmap of adapter ports to operate on
+ * @on: enable (1) or disable (0) HW VLAN extraction
+ *
+ * Enables or disables HW extraction of VLAN tags for the ports specified
+ * by @ports. @ports is a bitmap with the ith bit designating the port
+ * associated with the ith adapter channel.
+ */
+void t4_set_vlan_accel(struct adapter *adap, unsigned int ports, int on)
+{
+ ports <<= VLANEXTENABLE_SHIFT;
+ t4_set_reg_field(adap, TP_OUT_CONFIG, ports, on ? ports : 0);
+}
+
+struct intr_info {
+ unsigned int mask; /* bits to check in interrupt status */
+ const char *msg; /* message to print or NULL */
+ short stat_idx; /* stat counter to increment or -1 */
+ unsigned short fatal; /* whether the condition reported is fatal */
+};
+
+/**
+ * t4_handle_intr_status - table driven interrupt handler
+ * @adapter: the adapter that generated the interrupt
+ * @reg: the interrupt status register to process
+ * @acts: table of interrupt actions
+ *
+ * A table driven interrupt handler that applies a set of masks to an
+ * interrupt status word and performs the corresponding actions if the
+ * interrupts described by the mask have occured. The actions include
+ * optionally emitting a warning or alert message. The table is terminated
+ * by an entry specifying mask 0. Returns the number of fatal interrupt
+ * conditions.
+ */
+static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
+ const struct intr_info *acts)
+{
+ int fatal = 0;
+ unsigned int mask = 0;
+ unsigned int status = t4_read_reg(adapter, reg);
+
+ for ( ; acts->mask; ++acts) {
+ if (!(status & acts->mask))
+ continue;
+ if (acts->fatal) {
+ fatal++;
+ dev_alert(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
+ status & acts->mask);
+ } else if (acts->msg && printk_ratelimit())
+ dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
+ status & acts->mask);
+ mask |= acts->mask;
+ }
+ status &= mask;
+ if (status) /* clear processed interrupts */
+ t4_write_reg(adapter, reg, status);
+ return fatal;
+}
+
+/*
+ * Interrupt handler for the PCIE module.
+ */
+static void pcie_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info sysbus_intr_info[] = {
+ { RNPP, "RXNP array parity error", -1, 1 },
+ { RPCP, "RXPC array parity error", -1, 1 },
+ { RCIP, "RXCIF array parity error", -1, 1 },
+ { RCCP, "Rx completions control array parity error", -1, 1 },
+ { RFTP, "RXFT array parity error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info pcie_port_intr_info[] = {
+ { TPCP, "TXPC array parity error", -1, 1 },
+ { TNPP, "TXNP array parity error", -1, 1 },
+ { TFTP, "TXFT array parity error", -1, 1 },
+ { TCAP, "TXCA array parity error", -1, 1 },
+ { TCIP, "TXCIF array parity error", -1, 1 },
+ { RCAP, "RXCA array parity error", -1, 1 },
+ { OTDD, "outbound request TLP discarded", -1, 1 },
+ { RDPE, "Rx data parity error", -1, 1 },
+ { TDUE, "Tx uncorrectable data error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info pcie_intr_info[] = {
+ { MSIADDRLPERR, "MSI AddrL parity error", -1, 1 },
+ { MSIADDRHPERR, "MSI AddrH parity error", -1, 1 },
+ { MSIDATAPERR, "MSI data parity error", -1, 1 },
+ { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 },
+ { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 },
+ { MSIXDATAPERR, "MSI-X data parity error", -1, 1 },
+ { MSIXDIPERR, "MSI-X DI parity error", -1, 1 },
+ { PIOCPLPERR, "PCI PIO completion FIFO parity error", -1, 1 },
+ { PIOREQPERR, "PCI PIO request FIFO parity error", -1, 1 },
+ { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 },
+ { CCNTPERR, "PCI CMD channel count parity error", -1, 1 },
+ { CREQPERR, "PCI CMD channel request parity error", -1, 1 },
+ { CRSPPERR, "PCI CMD channel response parity error", -1, 1 },
+ { DCNTPERR, "PCI DMA channel count parity error", -1, 1 },
+ { DREQPERR, "PCI DMA channel request parity error", -1, 1 },
+ { DRSPPERR, "PCI DMA channel response parity error", -1, 1 },
+ { HCNTPERR, "PCI HMA channel count parity error", -1, 1 },
+ { HREQPERR, "PCI HMA channel request parity error", -1, 1 },
+ { HRSPPERR, "PCI HMA channel response parity error", -1, 1 },
+ { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 },
+ { FIDPERR, "PCI FID parity error", -1, 1 },
+ { INTXCLRPERR, "PCI INTx clear parity error", -1, 1 },
+ { MATAGPERR, "PCI MA tag parity error", -1, 1 },
+ { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 },
+ { RXCPLPERR, "PCI Rx completion parity error", -1, 1 },
+ { RXWRPERR, "PCI Rx write parity error", -1, 1 },
+ { RPLPERR, "PCI replay buffer parity error", -1, 1 },
+ { PCIESINT, "PCI core secondary fault", -1, 1 },
+ { PCIEPINT, "PCI core primary fault", -1, 1 },
+ { UNXSPLCPLERR, "PCI unexpected split completion error", -1, 0 },
+ { 0 }
+ };
+
+ int fat;
+
+ fat = t4_handle_intr_status(adapter,
+ PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
+ sysbus_intr_info) +
+ t4_handle_intr_status(adapter,
+ PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
+ pcie_port_intr_info) +
+ t4_handle_intr_status(adapter, PCIE_INT_CAUSE, pcie_intr_info);
+ if (fat)
+ t4_fatal_err(adapter);
+}
+
+/*
+ * TP interrupt handler.
+ */
+static void tp_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info tp_intr_info[] = {
+ { 0x3fffffff, "TP parity error", -1, 1 },
+ { FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1 },
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adapter, TP_INT_CAUSE, tp_intr_info))
+ t4_fatal_err(adapter);
+}
+
+/*
+ * SGE interrupt handler.
+ */
+static void sge_intr_handler(struct adapter *adapter)
+{
+ u64 v;
+
+ static struct intr_info sge_intr_info[] = {
+ { ERR_CPL_EXCEED_IQE_SIZE,
+ "SGE received CPL exceeding IQE size", -1, 1 },
+ { ERR_INVALID_CIDX_INC,
+ "SGE GTS CIDX increment too large", -1, 0 },
+ { ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
+ { ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 },
+ { ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
+ "SGE IQID > 1023 received CPL for FL", -1, 0 },
+ { ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1,
+ 0 },
+ { ERR_BAD_DB_PIDX2, "SGE DBP 2 pidx increment too large", -1,
+ 0 },
+ { ERR_BAD_DB_PIDX1, "SGE DBP 1 pidx increment too large", -1,
+ 0 },
+ { ERR_BAD_DB_PIDX0, "SGE DBP 0 pidx increment too large", -1,
+ 0 },
+ { ERR_ING_CTXT_PRIO,
+ "SGE too many priority ingress contexts", -1, 0 },
+ { ERR_EGR_CTXT_PRIO,
+ "SGE too many priority egress contexts", -1, 0 },
+ { INGRESS_SIZE_ERR, "SGE illegal ingress QID", -1, 0 },
+ { EGRESS_SIZE_ERR, "SGE illegal egress QID", -1, 0 },
+ { 0 }
+ };
+
+ v = (u64)t4_read_reg(adapter, SGE_INT_CAUSE1) |
+ ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32);
+ if (v) {
+ dev_alert(adapter->pdev_dev, "SGE parity error (%#llx)\n",
+ (unsigned long long)v);
+ t4_write_reg(adapter, SGE_INT_CAUSE1, v);
+ t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32);
+ }
+
+ if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3, sge_intr_info) ||
+ v != 0)
+ t4_fatal_err(adapter);
+}
+
+/*
+ * CIM interrupt handler.
+ */
+static void cim_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info cim_intr_info[] = {
+ { PREFDROPINT, "CIM control register prefetch drop", -1, 1 },
+ { OBQPARERR, "CIM OBQ parity error", -1, 1 },
+ { IBQPARERR, "CIM IBQ parity error", -1, 1 },
+ { MBUPPARERR, "CIM mailbox uP parity error", -1, 1 },
+ { MBHOSTPARERR, "CIM mailbox host parity error", -1, 1 },
+ { TIEQINPARERRINT, "CIM TIEQ outgoing parity error", -1, 1 },
+ { TIEQOUTPARERRINT, "CIM TIEQ incoming parity error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info cim_upintr_info[] = {
+ { RSVDSPACEINT, "CIM reserved space access", -1, 1 },
+ { ILLTRANSINT, "CIM illegal transaction", -1, 1 },
+ { ILLWRINT, "CIM illegal write", -1, 1 },
+ { ILLRDINT, "CIM illegal read", -1, 1 },
+ { ILLRDBEINT, "CIM illegal read BE", -1, 1 },
+ { ILLWRBEINT, "CIM illegal write BE", -1, 1 },
+ { SGLRDBOOTINT, "CIM single read from boot space", -1, 1 },
+ { SGLWRBOOTINT, "CIM single write to boot space", -1, 1 },
+ { BLKWRBOOTINT, "CIM block write to boot space", -1, 1 },
+ { SGLRDFLASHINT, "CIM single read from flash space", -1, 1 },
+ { SGLWRFLASHINT, "CIM single write to flash space", -1, 1 },
+ { BLKWRFLASHINT, "CIM block write to flash space", -1, 1 },
+ { SGLRDEEPROMINT, "CIM single EEPROM read", -1, 1 },
+ { SGLWREEPROMINT, "CIM single EEPROM write", -1, 1 },
+ { BLKRDEEPROMINT, "CIM block EEPROM read", -1, 1 },
+ { BLKWREEPROMINT, "CIM block EEPROM write", -1, 1 },
+ { SGLRDCTLINT , "CIM single read from CTL space", -1, 1 },
+ { SGLWRCTLINT , "CIM single write to CTL space", -1, 1 },
+ { BLKRDCTLINT , "CIM block read from CTL space", -1, 1 },
+ { BLKWRCTLINT , "CIM block write to CTL space", -1, 1 },
+ { SGLRDPLINT , "CIM single read from PL space", -1, 1 },
+ { SGLWRPLINT , "CIM single write to PL space", -1, 1 },
+ { BLKRDPLINT , "CIM block read from PL space", -1, 1 },
+ { BLKWRPLINT , "CIM block write to PL space", -1, 1 },
+ { REQOVRLOOKUPINT , "CIM request FIFO overwrite", -1, 1 },
+ { RSPOVRLOOKUPINT , "CIM response FIFO overwrite", -1, 1 },
+ { TIMEOUTINT , "CIM PIF timeout", -1, 1 },
+ { TIMEOUTMAINT , "CIM PIF MA timeout", -1, 1 },
+ { 0 }
+ };
+
+ int fat;
+
+ fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE,
+ cim_intr_info) +
+ t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE,
+ cim_upintr_info);
+ if (fat)
+ t4_fatal_err(adapter);
+}
+
+/*
+ * ULP RX interrupt handler.
+ */
+static void ulprx_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info ulprx_intr_info[] = {
+ { 0x7fffff, "ULPRX parity error", -1, 1 },
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adapter, ULP_RX_INT_CAUSE, ulprx_intr_info))
+ t4_fatal_err(adapter);
+}
+
+/*
+ * ULP TX interrupt handler.
+ */
+static void ulptx_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info ulptx_intr_info[] = {
+ { PBL_BOUND_ERR_CH3, "ULPTX channel 3 PBL out of bounds", -1,
+ 0 },
+ { PBL_BOUND_ERR_CH2, "ULPTX channel 2 PBL out of bounds", -1,
+ 0 },
+ { PBL_BOUND_ERR_CH1, "ULPTX channel 1 PBL out of bounds", -1,
+ 0 },
+ { PBL_BOUND_ERR_CH0, "ULPTX channel 0 PBL out of bounds", -1,
+ 0 },
+ { 0xfffffff, "ULPTX parity error", -1, 1 },
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adapter, ULP_TX_INT_CAUSE, ulptx_intr_info))
+ t4_fatal_err(adapter);
+}
+
+/*
+ * PM TX interrupt handler.
+ */
+static void pmtx_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info pmtx_intr_info[] = {
+ { PCMD_LEN_OVFL0, "PMTX channel 0 pcmd too large", -1, 1 },
+ { PCMD_LEN_OVFL1, "PMTX channel 1 pcmd too large", -1, 1 },
+ { PCMD_LEN_OVFL2, "PMTX channel 2 pcmd too large", -1, 1 },
+ { ZERO_C_CMD_ERROR, "PMTX 0-length pcmd", -1, 1 },
+ { PMTX_FRAMING_ERROR, "PMTX framing error", -1, 1 },
+ { OESPI_PAR_ERROR, "PMTX oespi parity error", -1, 1 },
+ { DB_OPTIONS_PAR_ERROR, "PMTX db_options parity error", -1, 1 },
+ { ICSPI_PAR_ERROR, "PMTX icspi parity error", -1, 1 },
+ { C_PCMD_PAR_ERROR, "PMTX c_pcmd parity error", -1, 1},
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adapter, PM_TX_INT_CAUSE, pmtx_intr_info))
+ t4_fatal_err(adapter);
+}
+
+/*
+ * PM RX interrupt handler.
+ */
+static void pmrx_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info pmrx_intr_info[] = {
+ { ZERO_E_CMD_ERROR, "PMRX 0-length pcmd", -1, 1 },
+ { PMRX_FRAMING_ERROR, "PMRX framing error", -1, 1 },
+ { OCSPI_PAR_ERROR, "PMRX ocspi parity error", -1, 1 },
+ { DB_OPTIONS_PAR_ERROR, "PMRX db_options parity error", -1, 1 },
+ { IESPI_PAR_ERROR, "PMRX iespi parity error", -1, 1 },
+ { E_PCMD_PAR_ERROR, "PMRX e_pcmd parity error", -1, 1},
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adapter, PM_RX_INT_CAUSE, pmrx_intr_info))
+ t4_fatal_err(adapter);
+}
+
+/*
+ * CPL switch interrupt handler.
+ */
+static void cplsw_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info cplsw_intr_info[] = {
+ { CIM_OP_MAP_PERR, "CPLSW CIM op_map parity error", -1, 1 },
+ { CIM_OVFL_ERROR, "CPLSW CIM overflow", -1, 1 },
+ { TP_FRAMING_ERROR, "CPLSW TP framing error", -1, 1 },
+ { SGE_FRAMING_ERROR, "CPLSW SGE framing error", -1, 1 },
+ { CIM_FRAMING_ERROR, "CPLSW CIM framing error", -1, 1 },
+ { ZERO_SWITCH_ERROR, "CPLSW no-switch error", -1, 1 },
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adapter, CPL_INTR_CAUSE, cplsw_intr_info))
+ t4_fatal_err(adapter);
+}
+
+/*
+ * LE interrupt handler.
+ */
+static void le_intr_handler(struct adapter *adap)
+{
+ static struct intr_info le_intr_info[] = {
+ { LIPMISS, "LE LIP miss", -1, 0 },
+ { LIP0, "LE 0 LIP error", -1, 0 },
+ { PARITYERR, "LE parity error", -1, 1 },
+ { UNKNOWNCMD, "LE unknown command", -1, 1 },
+ { REQQPARERR, "LE request queue parity error", -1, 1 },
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adap, LE_DB_INT_CAUSE, le_intr_info))
+ t4_fatal_err(adap);
+}
+
+/*
+ * MPS interrupt handler.
+ */
+static void mps_intr_handler(struct adapter *adapter)
+{
+ static struct intr_info mps_rx_intr_info[] = {
+ { 0xffffff, "MPS Rx parity error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info mps_tx_intr_info[] = {
+ { TPFIFO, "MPS Tx TP FIFO parity error", -1, 1 },
+ { NCSIFIFO, "MPS Tx NC-SI FIFO parity error", -1, 1 },
+ { TXDATAFIFO, "MPS Tx data FIFO parity error", -1, 1 },
+ { TXDESCFIFO, "MPS Tx desc FIFO parity error", -1, 1 },
+ { BUBBLE, "MPS Tx underflow", -1, 1 },
+ { SECNTERR, "MPS Tx SOP/EOP error", -1, 1 },
+ { FRMERR, "MPS Tx framing error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info mps_trc_intr_info[] = {
+ { FILTMEM, "MPS TRC filter parity error", -1, 1 },
+ { PKTFIFO, "MPS TRC packet FIFO parity error", -1, 1 },
+ { MISCPERR, "MPS TRC misc parity error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info mps_stat_sram_intr_info[] = {
+ { 0x1fffff, "MPS statistics SRAM parity error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info mps_stat_tx_intr_info[] = {
+ { 0xfffff, "MPS statistics Tx FIFO parity error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info mps_stat_rx_intr_info[] = {
+ { 0xffffff, "MPS statistics Rx FIFO parity error", -1, 1 },
+ { 0 }
+ };
+ static struct intr_info mps_cls_intr_info[] = {
+ { MATCHSRAM, "MPS match SRAM parity error", -1, 1 },
+ { MATCHTCAM, "MPS match TCAM parity error", -1, 1 },
+ { HASHSRAM, "MPS hash SRAM parity error", -1, 1 },
+ { 0 }
+ };
+
+ int fat;
+
+ fat = t4_handle_intr_status(adapter, MPS_RX_PERR_INT_CAUSE,
+ mps_rx_intr_info) +
+ t4_handle_intr_status(adapter, MPS_TX_INT_CAUSE,
+ mps_tx_intr_info) +
+ t4_handle_intr_status(adapter, MPS_TRC_INT_CAUSE,
+ mps_trc_intr_info) +
+ t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_SRAM,
+ mps_stat_sram_intr_info) +
+ t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_TX_FIFO,
+ mps_stat_tx_intr_info) +
+ t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_RX_FIFO,
+ mps_stat_rx_intr_info) +
+ t4_handle_intr_status(adapter, MPS_CLS_INT_CAUSE,
+ mps_cls_intr_info);
+
+ t4_write_reg(adapter, MPS_INT_CAUSE, CLSINT | TRCINT |
+ RXINT | TXINT | STATINT);
+ t4_read_reg(adapter, MPS_INT_CAUSE); /* flush */
+ if (fat)
+ t4_fatal_err(adapter);
+}
+
+#define MEM_INT_MASK (PERR_INT_CAUSE | ECC_CE_INT_CAUSE | ECC_UE_INT_CAUSE)
+
+/*
+ * EDC/MC interrupt handler.
+ */
+static void mem_intr_handler(struct adapter *adapter, int idx)
+{
+ static const char name[3][5] = { "EDC0", "EDC1", "MC" };
+
+ unsigned int addr, cnt_addr, v;
+
+ if (idx <= MEM_EDC1) {
+ addr = EDC_REG(EDC_INT_CAUSE, idx);
+ cnt_addr = EDC_REG(EDC_ECC_STATUS, idx);
+ } else {
+ addr = MC_INT_CAUSE;
+ cnt_addr = MC_ECC_STATUS;
+ }
+
+ v = t4_read_reg(adapter, addr) & MEM_INT_MASK;
+ if (v & PERR_INT_CAUSE)
+ dev_alert(adapter->pdev_dev, "%s FIFO parity error\n",
+ name[idx]);
+ if (v & ECC_CE_INT_CAUSE) {
+ u32 cnt = ECC_CECNT_GET(t4_read_reg(adapter, cnt_addr));
+
+ t4_write_reg(adapter, cnt_addr, ECC_CECNT_MASK);
+ if (printk_ratelimit())
+ dev_warn(adapter->pdev_dev,
+ "%u %s correctable ECC data error%s\n",
+ cnt, name[idx], cnt > 1 ? "s" : "");
+ }
+ if (v & ECC_UE_INT_CAUSE)
+ dev_alert(adapter->pdev_dev,
+ "%s uncorrectable ECC data error\n", name[idx]);
+
+ t4_write_reg(adapter, addr, v);
+ if (v & (PERR_INT_CAUSE | ECC_UE_INT_CAUSE))
+ t4_fatal_err(adapter);
+}
+
+/*
+ * MA interrupt handler.
+ */
+static void ma_intr_handler(struct adapter *adap)
+{
+ u32 v, status = t4_read_reg(adap, MA_INT_CAUSE);
+
+ if (status & MEM_PERR_INT_CAUSE)
+ dev_alert(adap->pdev_dev,
+ "MA parity error, parity status %#x\n",
+ t4_read_reg(adap, MA_PARITY_ERROR_STATUS));
+ if (status & MEM_WRAP_INT_CAUSE) {
+ v = t4_read_reg(adap, MA_INT_WRAP_STATUS);
+ dev_alert(adap->pdev_dev, "MA address wrap-around error by "
+ "client %u to address %#x\n",
+ MEM_WRAP_CLIENT_NUM_GET(v),
+ MEM_WRAP_ADDRESS_GET(v) << 4);
+ }
+ t4_write_reg(adap, MA_INT_CAUSE, status);
+ t4_fatal_err(adap);
+}
+
+/*
+ * SMB interrupt handler.
+ */
+static void smb_intr_handler(struct adapter *adap)
+{
+ static struct intr_info smb_intr_info[] = {
+ { MSTTXFIFOPARINT, "SMB master Tx FIFO parity error", -1, 1 },
+ { MSTRXFIFOPARINT, "SMB master Rx FIFO parity error", -1, 1 },
+ { SLVFIFOPARINT, "SMB slave FIFO parity error", -1, 1 },
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adap, SMB_INT_CAUSE, smb_intr_info))
+ t4_fatal_err(adap);
+}
+
+/*
+ * NC-SI interrupt handler.
+ */
+static void ncsi_intr_handler(struct adapter *adap)
+{
+ static struct intr_info ncsi_intr_info[] = {
+ { CIM_DM_PRTY_ERR, "NC-SI CIM parity error", -1, 1 },
+ { MPS_DM_PRTY_ERR, "NC-SI MPS parity error", -1, 1 },
+ { TXFIFO_PRTY_ERR, "NC-SI Tx FIFO parity error", -1, 1 },
+ { RXFIFO_PRTY_ERR, "NC-SI Rx FIFO parity error", -1, 1 },
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adap, NCSI_INT_CAUSE, ncsi_intr_info))
+ t4_fatal_err(adap);
+}
+
+/*
+ * XGMAC interrupt handler.
+ */
+static void xgmac_intr_handler(struct adapter *adap, int port)
+{
+ u32 v = t4_read_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE));
+
+ v &= TXFIFO_PRTY_ERR | RXFIFO_PRTY_ERR;
+ if (!v)
+ return;
+
+ if (v & TXFIFO_PRTY_ERR)
+ dev_alert(adap->pdev_dev, "XGMAC %d Tx FIFO parity error\n",
+ port);
+ if (v & RXFIFO_PRTY_ERR)
+ dev_alert(adap->pdev_dev, "XGMAC %d Rx FIFO parity error\n",
+ port);
+ t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE), v);
+ t4_fatal_err(adap);
+}
+
+/*
+ * PL interrupt handler.
+ */
+static void pl_intr_handler(struct adapter *adap)
+{
+ static struct intr_info pl_intr_info[] = {
+ { FATALPERR, "T4 fatal parity error", -1, 1 },
+ { PERRVFID, "PL VFID_MAP parity error", -1, 1 },
+ { 0 }
+ };
+
+ if (t4_handle_intr_status(adap, PL_PL_INT_CAUSE, pl_intr_info))
+ t4_fatal_err(adap);
+}
+
+#define PF_INTR_MASK (PFSW | PFCIM)
+#define GLBL_INTR_MASK (CIM | MPS | PL | PCIE | MC | EDC0 | \
+ EDC1 | LE | TP | MA | PM_TX | PM_RX | ULP_RX | \
+ CPL_SWITCH | SGE | ULP_TX)
+
+/**
+ * t4_slow_intr_handler - control path interrupt handler
+ * @adapter: the adapter
+ *
+ * T4 interrupt handler for non-data global interrupt events, e.g., errors.
+ * The designation 'slow' is because it involves register reads, while
+ * data interrupts typically don't involve any MMIOs.
+ */
+int t4_slow_intr_handler(struct adapter *adapter)
+{
+ u32 cause = t4_read_reg(adapter, PL_INT_CAUSE);
+
+ if (!(cause & GLBL_INTR_MASK))
+ return 0;
+ if (cause & CIM)
+ cim_intr_handler(adapter);
+ if (cause & MPS)
+ mps_intr_handler(adapter);
+ if (cause & NCSI)
+ ncsi_intr_handler(adapter);
+ if (cause & PL)
+ pl_intr_handler(adapter);
+ if (cause & SMB)
+ smb_intr_handler(adapter);
+ if (cause & XGMAC0)
+ xgmac_intr_handler(adapter, 0);
+ if (cause & XGMAC1)
+ xgmac_intr_handler(adapter, 1);
+ if (cause & XGMAC_KR0)
+ xgmac_intr_handler(adapter, 2);
+ if (cause & XGMAC_KR1)
+ xgmac_intr_handler(adapter, 3);
+ if (cause & PCIE)
+ pcie_intr_handler(adapter);
+ if (cause & MC)
+ mem_intr_handler(adapter, MEM_MC);
+ if (cause & EDC0)
+ mem_intr_handler(adapter, MEM_EDC0);
+ if (cause & EDC1)
+ mem_intr_handler(adapter, MEM_EDC1);
+ if (cause & LE)
+ le_intr_handler(adapter);
+ if (cause & TP)
+ tp_intr_handler(adapter);
+ if (cause & MA)
+ ma_intr_handler(adapter);
+ if (cause & PM_TX)
+ pmtx_intr_handler(adapter);
+ if (cause & PM_RX)
+ pmrx_intr_handler(adapter);
+ if (cause & ULP_RX)
+ ulprx_intr_handler(adapter);
+ if (cause & CPL_SWITCH)
+ cplsw_intr_handler(adapter);
+ if (cause & SGE)
+ sge_intr_handler(adapter);
+ if (cause & ULP_TX)
+ ulptx_intr_handler(adapter);
+
+ /* Clear the interrupts just processed for which we are the master. */
+ t4_write_reg(adapter, PL_INT_CAUSE, cause & GLBL_INTR_MASK);
+ (void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */
+ return 1;
+}
+
+/**
+ * t4_intr_enable - enable interrupts
+ * @adapter: the adapter whose interrupts should be enabled
+ *
+ * Enable PF-specific interrupts for the calling function and the top-level
+ * interrupt concentrator for global interrupts. Interrupts are already
+ * enabled at each module, here we just enable the roots of the interrupt
+ * hierarchies.
+ *
+ * Note: this function should be called only when the driver manages
+ * non PF-specific interrupts from the various HW modules. Only one PCI
+ * function at a time should be doing this.
+ */
+void t4_intr_enable(struct adapter *adapter)
+{
+ u32 pf = SOURCEPF_GET(t4_read_reg(adapter, PL_WHOAMI));
+
+ t4_write_reg(adapter, SGE_INT_ENABLE3, ERR_CPL_EXCEED_IQE_SIZE |
+ ERR_INVALID_CIDX_INC | ERR_CPL_OPCODE_0 |
+ ERR_DROPPED_DB | ERR_DATA_CPL_ON_HIGH_QID1 |
+ ERR_DATA_CPL_ON_HIGH_QID0 | ERR_BAD_DB_PIDX3 |
+ ERR_BAD_DB_PIDX2 | ERR_BAD_DB_PIDX1 |
+ ERR_BAD_DB_PIDX0 | ERR_ING_CTXT_PRIO |
+ ERR_EGR_CTXT_PRIO | INGRESS_SIZE_ERR |
+ EGRESS_SIZE_ERR);
+ t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), PF_INTR_MASK);
+ t4_set_reg_field(adapter, PL_INT_MAP0, 0, 1 << pf);
+}
+
+/**
+ * t4_intr_disable - disable interrupts
+ * @adapter: the adapter whose interrupts should be disabled
+ *
+ * Disable interrupts. We only disable the top-level interrupt
+ * concentrators. The caller must be a PCI function managing global
+ * interrupts.
+ */
+void t4_intr_disable(struct adapter *adapter)
+{
+ u32 pf = SOURCEPF_GET(t4_read_reg(adapter, PL_WHOAMI));
+
+ t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), 0);
+ t4_set_reg_field(adapter, PL_INT_MAP0, 1 << pf, 0);
+}
+
+/**
+ * t4_intr_clear - clear all interrupts
+ * @adapter: the adapter whose interrupts should be cleared
+ *
+ * Clears all interrupts. The caller must be a PCI function managing
+ * global interrupts.
+ */
+void t4_intr_clear(struct adapter *adapter)
+{
+ static const unsigned int cause_reg[] = {
+ SGE_INT_CAUSE1, SGE_INT_CAUSE2, SGE_INT_CAUSE3,
+ PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
+ PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
+ PCIE_NONFAT_ERR, PCIE_INT_CAUSE,
+ MC_INT_CAUSE,
+ MA_INT_WRAP_STATUS, MA_PARITY_ERROR_STATUS, MA_INT_CAUSE,
+ EDC_INT_CAUSE, EDC_REG(EDC_INT_CAUSE, 1),
+ CIM_HOST_INT_CAUSE, CIM_HOST_UPACC_INT_CAUSE,
+ MYPF_REG(CIM_PF_HOST_INT_CAUSE),
+ TP_INT_CAUSE,
+ ULP_RX_INT_CAUSE, ULP_TX_INT_CAUSE,
+ PM_RX_INT_CAUSE, PM_TX_INT_CAUSE,
+ MPS_RX_PERR_INT_CAUSE,
+ CPL_INTR_CAUSE,
+ MYPF_REG(PL_PF_INT_CAUSE),
+ PL_PL_INT_CAUSE,
+ LE_DB_INT_CAUSE,
+ };
+
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(cause_reg); ++i)
+ t4_write_reg(adapter, cause_reg[i], 0xffffffff);
+
+ t4_write_reg(adapter, PL_INT_CAUSE, GLBL_INTR_MASK);
+ (void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */
+}
+
+/**
+ * hash_mac_addr - return the hash value of a MAC address
+ * @addr: the 48-bit Ethernet MAC address
+ *
+ * Hashes a MAC address according to the hash function used by HW inexact
+ * (hash) address matching.
+ */
+static int hash_mac_addr(const u8 *addr)
+{
+ u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2];
+ u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5];
+ a ^= b;
+ a ^= (a >> 12);
+ a ^= (a >> 6);
+ return a & 0x3f;
+}
+
+/**
+ * t4_config_rss_range - configure a portion of the RSS mapping table
+ * @adapter: the adapter
+ * @mbox: mbox to use for the FW command
+ * @viid: virtual interface whose RSS subtable is to be written
+ * @start: start entry in the table to write
+ * @n: how many table entries to write
+ * @rspq: values for the response queue lookup table
+ * @nrspq: number of values in @rspq
+ *
+ * Programs the selected part of the VI's RSS mapping table with the
+ * provided values. If @nrspq < @n the supplied values are used repeatedly
+ * until the full table range is populated.
+ *
+ * The caller must ensure the values in @rspq are in the range allowed for
+ * @viid.
+ */
+int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
+ int start, int n, const u16 *rspq, unsigned int nrspq)
+{
+ int ret;
+ const u16 *rsp = rspq;
+ const u16 *rsp_end = rspq + nrspq;
+ struct fw_rss_ind_tbl_cmd cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.op_to_viid = htonl(FW_CMD_OP(FW_RSS_IND_TBL_CMD) |
+ FW_CMD_REQUEST | FW_CMD_WRITE |
+ FW_RSS_IND_TBL_CMD_VIID(viid));
+ cmd.retval_len16 = htonl(FW_LEN16(cmd));
+
+ /* each fw_rss_ind_tbl_cmd takes up to 32 entries */
+ while (n > 0) {
+ int nq = min(n, 32);
+ __be32 *qp = &cmd.iq0_to_iq2;
+
+ cmd.niqid = htons(nq);
+ cmd.startidx = htons(start);
+
+ start += nq;
+ n -= nq;
+
+ while (nq > 0) {
+ unsigned int v;
+
+ v = FW_RSS_IND_TBL_CMD_IQ0(*rsp);
+ if (++rsp >= rsp_end)
+ rsp = rspq;
+ v |= FW_RSS_IND_TBL_CMD_IQ1(*rsp);
+ if (++rsp >= rsp_end)
+ rsp = rspq;
+ v |= FW_RSS_IND_TBL_CMD_IQ2(*rsp);
+ if (++rsp >= rsp_end)
+ rsp = rspq;
+
+ *qp++ = htonl(v);
+ nq -= 3;
+ }
+
+ ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+/**
+ * t4_config_glbl_rss - configure the global RSS mode
+ * @adapter: the adapter
+ * @mbox: mbox to use for the FW command
+ * @mode: global RSS mode
+ * @flags: mode-specific flags
+ *
+ * Sets the global RSS mode.
+ */
+int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
+ unsigned int flags)
+{
+ struct fw_rss_glb_config_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_write = htonl(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
+ FW_CMD_REQUEST | FW_CMD_WRITE);
+ c.retval_len16 = htonl(FW_LEN16(c));
+ if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) {
+ c.u.manual.mode_pkd = htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
+ } else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) {
+ c.u.basicvirtual.mode_pkd =
+ htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
+ c.u.basicvirtual.synmapen_to_hashtoeplitz = htonl(flags);
+ } else
+ return -EINVAL;
+ return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
+}
+
+/* Read an RSS table row */
+static int rd_rss_row(struct adapter *adap, int row, u32 *val)
+{
+ t4_write_reg(adap, TP_RSS_LKP_TABLE, 0xfff00000 | row);
+ return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE, LKPTBLROWVLD, 1,
+ 5, 0, val);
+}
+
+/**
+ * t4_read_rss - read the contents of the RSS mapping table
+ * @adapter: the adapter
+ * @map: holds the contents of the RSS mapping table
+ *
+ * Reads the contents of the RSS hash->queue mapping table.
+ */
+int t4_read_rss(struct adapter *adapter, u16 *map)
+{
+ u32 val;
+ int i, ret;
+
+ for (i = 0; i < RSS_NENTRIES / 2; ++i) {
+ ret = rd_rss_row(adapter, i, &val);
+ if (ret)
+ return ret;
+ *map++ = LKPTBLQUEUE0_GET(val);
+ *map++ = LKPTBLQUEUE1_GET(val);
+ }
+ return 0;
+}
+
+/**
+ * t4_tp_get_tcp_stats - read TP's TCP MIB counters
+ * @adap: the adapter
+ * @v4: holds the TCP/IP counter values
+ * @v6: holds the TCP/IPv6 counter values
+ *
+ * Returns the values of TP's TCP/IP and TCP/IPv6 MIB counters.
+ * Either @v4 or @v6 may be %NULL to skip the corresponding stats.
+ */
+void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
+ struct tp_tcp_stats *v6)
+{
+ u32 val[TP_MIB_TCP_RXT_SEG_LO - TP_MIB_TCP_OUT_RST + 1];
+
+#define STAT_IDX(x) ((TP_MIB_TCP_##x) - TP_MIB_TCP_OUT_RST)
+#define STAT(x) val[STAT_IDX(x)]
+#define STAT64(x) (((u64)STAT(x##_HI) << 32) | STAT(x##_LO))
+
+ if (v4) {
+ t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, val,
+ ARRAY_SIZE(val), TP_MIB_TCP_OUT_RST);
+ v4->tcpOutRsts = STAT(OUT_RST);
+ v4->tcpInSegs = STAT64(IN_SEG);
+ v4->tcpOutSegs = STAT64(OUT_SEG);
+ v4->tcpRetransSegs = STAT64(RXT_SEG);
+ }
+ if (v6) {
+ t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, val,
+ ARRAY_SIZE(val), TP_MIB_TCP_V6OUT_RST);
+ v6->tcpOutRsts = STAT(OUT_RST);
+ v6->tcpInSegs = STAT64(IN_SEG);
+ v6->tcpOutSegs = STAT64(OUT_SEG);
+ v6->tcpRetransSegs = STAT64(RXT_SEG);
+ }
+#undef STAT64
+#undef STAT
+#undef STAT_IDX
+}
+
+/**
+ * t4_tp_get_err_stats - read TP's error MIB counters
+ * @adap: the adapter
+ * @st: holds the counter values
+ *
+ * Returns the values of TP's error counters.
+ */
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st)
+{
+ t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->macInErrs,
+ 12, TP_MIB_MAC_IN_ERR_0);
+ t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlCongDrops,
+ 8, TP_MIB_TNL_CNG_DROP_0);
+ t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlTxDrops,
+ 4, TP_MIB_TNL_DROP_0);
+ t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->ofldVlanDrops,
+ 4, TP_MIB_OFD_VLN_DROP_0);
+ t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tcp6InErrs,
+ 4, TP_MIB_TCP_V6IN_ERR_0);
+ t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, &st->ofldNoNeigh,
+ 2, TP_MIB_OFD_ARP_DROP);
+}
+
+/**
+ * t4_read_mtu_tbl - returns the values in the HW path MTU table
+ * @adap: the adapter
+ * @mtus: where to store the MTU values
+ * @mtu_log: where to store the MTU base-2 log (may be %NULL)
+ *
+ * Reads the HW path MTU table.
+ */
+void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log)
+{
+ u32 v;
+ int i;
+
+ for (i = 0; i < NMTUS; ++i) {
+ t4_write_reg(adap, TP_MTU_TABLE,
+ MTUINDEX(0xff) | MTUVALUE(i));
+ v = t4_read_reg(adap, TP_MTU_TABLE);
+ mtus[i] = MTUVALUE_GET(v);
+ if (mtu_log)
+ mtu_log[i] = MTUWIDTH_GET(v);
+ }
+}
+
+/**
+ * init_cong_ctrl - initialize congestion control parameters
+ * @a: the alpha values for congestion control
+ * @b: the beta values for congestion control
+ *
+ * Initialize the congestion control parameters.
+ */
+static void __devinit init_cong_ctrl(unsigned short *a, unsigned short *b)
+{
+ a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1;
+ a[9] = 2;
+ a[10] = 3;
+ a[11] = 4;
+ a[12] = 5;
+ a[13] = 6;
+ a[14] = 7;
+ a[15] = 8;
+ a[16] = 9;
+ a[17] = 10;
+ a[18] = 14;
+ a[19] = 17;
+ a[20] = 21;
+ a[21] = 25;
+ a[22] = 30;
+ a[23] = 35;
+ a[24] = 45;
+ a[25] = 60;
+ a[26] = 80;
+ a[27] = 100;
+ a[28] = 200;
+ a[29] = 300;
+ a[30] = 400;
+ a[31] = 500;
+
+ b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0;
+ b[9] = b[10] = 1;
+ b[11] = b[12] = 2;
+ b[13] = b[14] = b[15] = b[16] = 3;
+ b[17] = b[18] = b[19] = b[20] = b[21] = 4;
+ b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5;
+ b[28] = b[29] = 6;
+ b[30] = b[31] = 7;
+}
+
+/* The minimum additive increment value for the congestion control table */
+#define CC_MIN_INCR 2U
+
+/**
+ * t4_load_mtus - write the MTU and congestion control HW tables
+ * @adap: the adapter
+ * @mtus: the values for the MTU table
+ * @alpha: the values for the congestion control alpha parameter
+ * @beta: the values for the congestion control beta parameter
+ *
+ * Write the HW MTU table with the supplied MTUs and the high-speed
+ * congestion control table with the supplied alpha, beta, and MTUs.
+ * We write the two tables together because the additive increments
+ * depend on the MTUs.
+ */
+void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
+ const unsigned short *alpha, const unsigned short *beta)
+{
+ static const unsigned int avg_pkts[NCCTRL_WIN] = {
+ 2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640,
+ 896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480,
+ 28672, 40960, 57344, 81920, 114688, 163840, 229376
+ };
+
+ unsigned int i, w;
+
+ for (i = 0; i < NMTUS; ++i) {
+ unsigned int mtu = mtus[i];
+ unsigned int log2 = fls(mtu);
+
+ if (!(mtu & ((1 << log2) >> 2))) /* round */
+ log2--;
+ t4_write_reg(adap, TP_MTU_TABLE, MTUINDEX(i) |
+ MTUWIDTH(log2) | MTUVALUE(mtu));
+
+ for (w = 0; w < NCCTRL_WIN; ++w) {
+ unsigned int inc;
+
+ inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w],
+ CC_MIN_INCR);
+
+ t4_write_reg(adap, TP_CCTRL_TABLE, (i << 21) |
+ (w << 16) | (beta[w] << 13) | inc);
+ }
+ }
+}
+
+/**
+ * t4_set_trace_filter - configure one of the tracing filters
+ * @adap: the adapter
+ * @tp: the desired trace filter parameters
+ * @idx: which filter to configure
+ * @enable: whether to enable or disable the filter
+ *
+ * Configures one of the tracing filters available in HW. If @enable is
+ * %0 @tp is not examined and may be %NULL.
+ */
+int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp,
+ int idx, int enable)
+{
+ int i, ofst = idx * 4;
+ u32 data_reg, mask_reg, cfg;
+ u32 multitrc = TRCMULTIFILTER;
+
+ if (!enable) {
+ t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0);
+ goto out;
+ }
+
+ if (tp->port > 11 || tp->invert > 1 || tp->skip_len > 0x1f ||
+ tp->skip_ofst > 0x1f || tp->min_len > 0x1ff ||
+ tp->snap_len > 9600 || (idx && tp->snap_len > 256))
+ return -EINVAL;
+
+ if (tp->snap_len > 256) { /* must be tracer 0 */
+ if ((t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 4) |
+ t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 8) |
+ t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 12)) & TFEN)
+ return -EINVAL; /* other tracers are enabled */
+ multitrc = 0;
+ } else if (idx) {
+ i = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B);
+ if (TFCAPTUREMAX_GET(i) > 256 &&
+ (t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A) & TFEN))
+ return -EINVAL;
+ }
+
+ /* stop the tracer we'll be changing */
+ t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0);
+
+ /* disable tracing globally if running in the wrong single/multi mode */
+ cfg = t4_read_reg(adap, MPS_TRC_CFG);
+ if ((cfg & TRCEN) && multitrc != (cfg & TRCMULTIFILTER)) {
+ t4_write_reg(adap, MPS_TRC_CFG, cfg ^ TRCEN);
+ t4_read_reg(adap, MPS_TRC_CFG); /* flush */
+ msleep(1);
+ if (!(t4_read_reg(adap, MPS_TRC_CFG) & TRCFIFOEMPTY))
+ return -ETIMEDOUT;
+ }
+ /*
+ * At this point either the tracing is enabled and in the right mode or
+ * disabled.
+ */
+
+ idx *= (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH);
+ data_reg = MPS_TRC_FILTER0_MATCH + idx;
+ mask_reg = MPS_TRC_FILTER0_DONT_CARE + idx;
+
+ for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
+ t4_write_reg(adap, data_reg, tp->data[i]);
+ t4_write_reg(adap, mask_reg, ~tp->mask[i]);
+ }
+ t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst,
+ TFCAPTUREMAX(tp->snap_len) |
+ TFMINPKTSIZE(tp->min_len));
+ t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst,
+ TFOFFSET(tp->skip_ofst) | TFLENGTH(tp->skip_len) |
+ TFPORT(tp->port) | TFEN |
+ (tp->invert ? TFINVERTMATCH : 0));
+
+ cfg &= ~TRCMULTIFILTER;
+ t4_write_reg(adap, MPS_TRC_CFG, cfg | TRCEN | multitrc);
+out: t4_read_reg(adap, MPS_TRC_CFG); /* flush */
+ return 0;
+}
+
+/**
+ * t4_get_trace_filter - query one of the tracing filters
+ * @adap: the adapter
+ * @tp: the current trace filter parameters
+ * @idx: which trace filter to query
+ * @enabled: non-zero if the filter is enabled
+ *
+ * Returns the current settings of one of the HW tracing filters.
+ */
+void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
+ int *enabled)
+{
+ u32 ctla, ctlb;
+ int i, ofst = idx * 4;
+ u32 data_reg, mask_reg;
+
+ ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst);
+ ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst);
+
+ *enabled = !!(ctla & TFEN);
+ tp->snap_len = TFCAPTUREMAX_GET(ctlb);
+ tp->min_len = TFMINPKTSIZE_GET(ctlb);
+ tp->skip_ofst = TFOFFSET_GET(ctla);
+ tp->skip_len = TFLENGTH_GET(ctla);
+ tp->invert = !!(ctla & TFINVERTMATCH);
+ tp->port = TFPORT_GET(ctla);
+
+ ofst = (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH) * idx;
+ data_reg = MPS_TRC_FILTER0_MATCH + ofst;
+ mask_reg = MPS_TRC_FILTER0_DONT_CARE + ofst;
+
+ for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
+ tp->mask[i] = ~t4_read_reg(adap, mask_reg);
+ tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i];
+ }
+}
+
+/**
+ * get_mps_bg_map - return the buffer groups associated with a port
+ * @adap: the adapter
+ * @idx: the port index
+ *
+ * Returns a bitmap indicating which MPS buffer groups are associated
+ * with the given port. Bit i is set if buffer group i is used by the
+ * port.
+ */
+static unsigned int get_mps_bg_map(struct adapter *adap, int idx)
+{
+ u32 n = NUMPORTS_GET(t4_read_reg(adap, MPS_CMN_CTL));
+
+ if (n == 0)
+ return idx == 0 ? 0xf : 0;
+ if (n == 1)
+ return idx < 2 ? (3 << (2 * idx)) : 0;
+ return 1 << idx;
+}
+
+/**
+ * t4_get_port_stats - collect port statistics
+ * @adap: the adapter
+ * @idx: the port index
+ * @p: the stats structure to fill
+ *
+ * Collect statistics related to the given port from HW.
+ */
+void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
+{
+ u32 bgmap = get_mps_bg_map(adap, idx);
+
+#define GET_STAT(name) \
+ t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_##name##_L))
+#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
+
+ p->tx_octets = GET_STAT(TX_PORT_BYTES);
+ p->tx_frames = GET_STAT(TX_PORT_FRAMES);
+ p->tx_bcast_frames = GET_STAT(TX_PORT_BCAST);
+ p->tx_mcast_frames = GET_STAT(TX_PORT_MCAST);
+ p->tx_ucast_frames = GET_STAT(TX_PORT_UCAST);
+ p->tx_error_frames = GET_STAT(TX_PORT_ERROR);
+ p->tx_frames_64 = GET_STAT(TX_PORT_64B);
+ p->tx_frames_65_127 = GET_STAT(TX_PORT_65B_127B);
+ p->tx_frames_128_255 = GET_STAT(TX_PORT_128B_255B);
+ p->tx_frames_256_511 = GET_STAT(TX_PORT_256B_511B);
+ p->tx_frames_512_1023 = GET_STAT(TX_PORT_512B_1023B);
+ p->tx_frames_1024_1518 = GET_STAT(TX_PORT_1024B_1518B);
+ p->tx_frames_1519_max = GET_STAT(TX_PORT_1519B_MAX);
+ p->tx_drop = GET_STAT(TX_PORT_DROP);
+ p->tx_pause = GET_STAT(TX_PORT_PAUSE);
+ p->tx_ppp0 = GET_STAT(TX_PORT_PPP0);
+ p->tx_ppp1 = GET_STAT(TX_PORT_PPP1);
+ p->tx_ppp2 = GET_STAT(TX_PORT_PPP2);
+ p->tx_ppp3 = GET_STAT(TX_PORT_PPP3);
+ p->tx_ppp4 = GET_STAT(TX_PORT_PPP4);
+ p->tx_ppp5 = GET_STAT(TX_PORT_PPP5);
+ p->tx_ppp6 = GET_STAT(TX_PORT_PPP6);
+ p->tx_ppp7 = GET_STAT(TX_PORT_PPP7);
+
+ p->rx_octets = GET_STAT(RX_PORT_BYTES);
+ p->rx_frames = GET_STAT(RX_PORT_FRAMES);
+ p->rx_bcast_frames = GET_STAT(RX_PORT_BCAST);
+ p->rx_mcast_frames = GET_STAT(RX_PORT_MCAST);
+ p->rx_ucast_frames = GET_STAT(RX_PORT_UCAST);
+ p->rx_too_long = GET_STAT(RX_PORT_MTU_ERROR);
+ p->rx_jabber = GET_STAT(RX_PORT_MTU_CRC_ERROR);
+ p->rx_fcs_err = GET_STAT(RX_PORT_CRC_ERROR);
+ p->rx_len_err = GET_STAT(RX_PORT_LEN_ERROR);
+ p->rx_symbol_err = GET_STAT(RX_PORT_SYM_ERROR);
+ p->rx_runt = GET_STAT(RX_PORT_LESS_64B);
+ p->rx_frames_64 = GET_STAT(RX_PORT_64B);
+ p->rx_frames_65_127 = GET_STAT(RX_PORT_65B_127B);
+ p->rx_frames_128_255 = GET_STAT(RX_PORT_128B_255B);
+ p->rx_frames_256_511 = GET_STAT(RX_PORT_256B_511B);
+ p->rx_frames_512_1023 = GET_STAT(RX_PORT_512B_1023B);
+ p->rx_frames_1024_1518 = GET_STAT(RX_PORT_1024B_1518B);
+ p->rx_frames_1519_max = GET_STAT(RX_PORT_1519B_MAX);
+ p->rx_pause = GET_STAT(RX_PORT_PAUSE);
+ p->rx_ppp0 = GET_STAT(RX_PORT_PPP0);
+ p->rx_ppp1 = GET_STAT(RX_PORT_PPP1);
+ p->rx_ppp2 = GET_STAT(RX_PORT_PPP2);
+ p->rx_ppp3 = GET_STAT(RX_PORT_PPP3);
+ p->rx_ppp4 = GET_STAT(RX_PORT_PPP4);
+ p->rx_ppp5 = GET_STAT(RX_PORT_PPP5);
+ p->rx_ppp6 = GET_STAT(RX_PORT_PPP6);
+ p->rx_ppp7 = GET_STAT(RX_PORT_PPP7);
+
+ p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0;
+ p->rx_ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_DROP_FRAME) : 0;
+ p->rx_ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_DROP_FRAME) : 0;
+ p->rx_ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_DROP_FRAME) : 0;
+ p->rx_trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_TRUNC_FRAME) : 0;
+ p->rx_trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_TRUNC_FRAME) : 0;
+ p->rx_trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_TRUNC_FRAME) : 0;
+ p->rx_trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_TRUNC_FRAME) : 0;
+
+#undef GET_STAT
+#undef GET_STAT_COM
+}
+
+/**
+ * t4_get_lb_stats - collect loopback port statistics
+ * @adap: the adapter
+ * @idx: the loopback port index
+ * @p: the stats structure to fill
+ *
+ * Return HW statistics for the given loopback port.
+ */
+void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p)
+{
+ u32 bgmap = get_mps_bg_map(adap, idx);
+
+#define GET_STAT(name) \
+ t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L))
+#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
+
+ p->octets = GET_STAT(BYTES);
+ p->frames = GET_STAT(FRAMES);
+ p->bcast_frames = GET_STAT(BCAST);
+ p->mcast_frames = GET_STAT(MCAST);
+ p->ucast_frames = GET_STAT(UCAST);
+ p->error_frames = GET_STAT(ERROR);
+
+ p->frames_64 = GET_STAT(64B);
+ p->frames_65_127 = GET_STAT(65B_127B);
+ p->frames_128_255 = GET_STAT(128B_255B);
+ p->frames_256_511 = GET_STAT(256B_511B);
+ p->frames_512_1023 = GET_STAT(512B_1023B);
+ p->frames_1024_1518 = GET_STAT(1024B_1518B);
+ p->frames_1519_max = GET_STAT(1519B_MAX);
+ p->drop = t4_read_reg(adap, PORT_REG(idx,
+ MPS_PORT_STAT_LB_PORT_DROP_FRAMES));
+
+ p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0;
+ p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0;
+ p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0;
+ p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0;
+ p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0;
+ p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0;
+ p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0;
+ p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0;
+
+#undef GET_STAT
+#undef GET_STAT_COM
+}
+
+/**
+ * t4_wol_magic_enable - enable/disable magic packet WoL
+ * @adap: the adapter
+ * @port: the physical port index
+ * @addr: MAC address expected in magic packets, %NULL to disable
+ *
+ * Enables/disables magic packet wake-on-LAN for the selected port.
+ */
+void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
+ const u8 *addr)
+{
+ if (addr) {
+ t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO),
+ (addr[2] << 24) | (addr[3] << 16) |
+ (addr[4] << 8) | addr[5]);
+ t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI),
+ (addr[0] << 8) | addr[1]);
+ }
+ t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), MAGICEN,
+ addr ? MAGICEN : 0);
+}
+
+/**
+ * t4_wol_pat_enable - enable/disable pattern-based WoL
+ * @adap: the adapter
+ * @port: the physical port index
+ * @map: bitmap of which HW pattern filters to set
+ * @mask0: byte mask for bytes 0-63 of a packet
+ * @mask1: byte mask for bytes 64-127 of a packet
+ * @crc: Ethernet CRC for selected bytes
+ * @enable: enable/disable switch
+ *
+ * Sets the pattern filters indicated in @map to mask out the bytes
+ * specified in @mask0/@mask1 in received packets and compare the CRC of
+ * the resulting packet against @crc. If @enable is %true pattern-based
+ * WoL is enabled, otherwise disabled.
+ */
+int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
+ u64 mask0, u64 mask1, unsigned int crc, bool enable)
+{
+ int i;
+
+ if (!enable) {
+ t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2),
+ PATEN, 0);
+ return 0;
+ }
+ if (map > 0xff)
+ return -EINVAL;
+
+#define EPIO_REG(name) PORT_REG(port, XGMAC_PORT_EPIO_##name)
+
+ t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32);
+ t4_write_reg(adap, EPIO_REG(DATA2), mask1);
+ t4_write_reg(adap, EPIO_REG(DATA3), mask1 >> 32);
+
+ for (i = 0; i < NWOL_PAT; i++, map >>= 1) {
+ if (!(map & 1))
+ continue;
+
+ /* write byte masks */
+ t4_write_reg(adap, EPIO_REG(DATA0), mask0);
+ t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i) | EPIOWR);
+ t4_read_reg(adap, EPIO_REG(OP)); /* flush */
+ if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY)
+ return -ETIMEDOUT;
+
+ /* write CRC */
+ t4_write_reg(adap, EPIO_REG(DATA0), crc);
+ t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i + 32) | EPIOWR);
+ t4_read_reg(adap, EPIO_REG(OP)); /* flush */
+ if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY)
+ return -ETIMEDOUT;
+ }
+#undef EPIO_REG
+
+ t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), 0, PATEN);
+ return 0;
+}
+
+#define INIT_CMD(var, cmd, rd_wr) do { \
+ (var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \
+ FW_CMD_REQUEST | FW_CMD_##rd_wr); \
+ (var).retval_len16 = htonl(FW_LEN16(var)); \
+} while (0)
+
+/**
+ * t4_mdio_rd - read a PHY register through MDIO
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @phy_addr: the PHY address
+ * @mmd: the PHY MMD to access (0 for clause 22 PHYs)
+ * @reg: the register to read
+ * @valp: where to store the value
+ *
+ * Issues a FW command through the given mailbox to read a PHY register.
+ */
+int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+ unsigned int mmd, unsigned int reg, u16 *valp)
+{
+ int ret;
+ struct fw_ldst_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST |
+ FW_CMD_READ | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO));
+ c.cycles_to_len16 = htonl(FW_LEN16(c));
+ c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) |
+ FW_LDST_CMD_MMD(mmd));
+ c.u.mdio.raddr = htons(reg);
+
+ ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+ if (ret == 0)
+ *valp = ntohs(c.u.mdio.rval);
+ return ret;
+}
+
+/**
+ * t4_mdio_wr - write a PHY register through MDIO
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @phy_addr: the PHY address
+ * @mmd: the PHY MMD to access (0 for clause 22 PHYs)
+ * @reg: the register to write
+ * @valp: value to write
+ *
+ * Issues a FW command through the given mailbox to write a PHY register.
+ */
+int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+ unsigned int mmd, unsigned int reg, u16 val)
+{
+ struct fw_ldst_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO));
+ c.cycles_to_len16 = htonl(FW_LEN16(c));
+ c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) |
+ FW_LDST_CMD_MMD(mmd));
+ c.u.mdio.raddr = htons(reg);
+ c.u.mdio.rval = htons(val);
+
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_fw_hello - establish communication with FW
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @evt_mbox: mailbox to receive async FW events
+ * @master: specifies the caller's willingness to be the device master
+ * @state: returns the current device state
+ *
+ * Issues a command to establish communication with FW.
+ */
+int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
+ enum dev_master master, enum dev_state *state)
+{
+ int ret;
+ struct fw_hello_cmd c;
+
+ INIT_CMD(c, HELLO, WRITE);
+ c.err_to_mbasyncnot = htonl(
+ FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) |
+ FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) |
+ FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? mbox : 0xff) |
+ FW_HELLO_CMD_MBASYNCNOT(evt_mbox));
+
+ ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+ if (ret == 0 && state) {
+ u32 v = ntohl(c.err_to_mbasyncnot);
+ if (v & FW_HELLO_CMD_INIT)
+ *state = DEV_STATE_INIT;
+ else if (v & FW_HELLO_CMD_ERR)
+ *state = DEV_STATE_ERR;
+ else
+ *state = DEV_STATE_UNINIT;
+ }
+ return ret;
+}
+
+/**
+ * t4_fw_bye - end communication with FW
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ *
+ * Issues a command to terminate communication with FW.
+ */
+int t4_fw_bye(struct adapter *adap, unsigned int mbox)
+{
+ struct fw_bye_cmd c;
+
+ INIT_CMD(c, BYE, WRITE);
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_init_cmd - ask FW to initialize the device
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ *
+ * Issues a command to FW to partially initialize the device. This
+ * performs initialization that generally doesn't depend on user input.
+ */
+int t4_early_init(struct adapter *adap, unsigned int mbox)
+{
+ struct fw_initialize_cmd c;
+
+ INIT_CMD(c, INITIALIZE, WRITE);
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_fw_reset - issue a reset to FW
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @reset: specifies the type of reset to perform
+ *
+ * Issues a reset command of the specified type to FW.
+ */
+int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset)
+{
+ struct fw_reset_cmd c;
+
+ INIT_CMD(c, RESET, WRITE);
+ c.val = htonl(reset);
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_query_params - query FW or device parameters
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF
+ * @vf: the VF
+ * @nparams: the number of parameters
+ * @params: the parameter names
+ * @val: the parameter values
+ *
+ * Reads the value of FW or device parameters. Up to 7 parameters can be
+ * queried at once.
+ */
+int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int nparams, const u32 *params,
+ u32 *val)
+{
+ int i, ret;
+ struct fw_params_cmd c;
+ __be32 *p = &c.param[0].mnem;
+
+ if (nparams > 7)
+ return -EINVAL;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST |
+ FW_CMD_READ | FW_PARAMS_CMD_PFN(pf) |
+ FW_PARAMS_CMD_VFN(vf));
+ c.retval_len16 = htonl(FW_LEN16(c));
+ for (i = 0; i < nparams; i++, p += 2)
+ *p = htonl(*params++);
+
+ ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+ if (ret == 0)
+ for (i = 0, p = &c.param[0].val; i < nparams; i++, p += 2)
+ *val++ = ntohl(*p);
+ return ret;
+}
+
+/**
+ * t4_set_params - sets FW or device parameters
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF
+ * @vf: the VF
+ * @nparams: the number of parameters
+ * @params: the parameter names
+ * @val: the parameter values
+ *
+ * Sets the value of FW or device parameters. Up to 7 parameters can be
+ * specified at once.
+ */
+int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int nparams, const u32 *params,
+ const u32 *val)
+{
+ struct fw_params_cmd c;
+ __be32 *p = &c.param[0].mnem;
+
+ if (nparams > 7)
+ return -EINVAL;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_PARAMS_CMD_PFN(pf) |
+ FW_PARAMS_CMD_VFN(vf));
+ c.retval_len16 = htonl(FW_LEN16(c));
+ while (nparams--) {
+ *p++ = htonl(*params++);
+ *p++ = htonl(*val++);
+ }
+
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_cfg_pfvf - configure PF/VF resource limits
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF being configured
+ * @vf: the VF being configured
+ * @txq: the max number of egress queues
+ * @txq_eth_ctrl: the max number of egress Ethernet or control queues
+ * @rxqi: the max number of interrupt-capable ingress queues
+ * @rxq: the max number of interruptless ingress queues
+ * @tc: the PCI traffic class
+ * @vi: the max number of virtual interfaces
+ * @cmask: the channel access rights mask for the PF/VF
+ * @pmask: the port access rights mask for the PF/VF
+ * @nexact: the maximum number of exact MPS filters
+ * @rcaps: read capabilities
+ * @wxcaps: write/execute capabilities
+ *
+ * Configures resource limits and capabilities for a physical or virtual
+ * function.
+ */
+int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
+ unsigned int rxqi, unsigned int rxq, unsigned int tc,
+ unsigned int vi, unsigned int cmask, unsigned int pmask,
+ unsigned int nexact, unsigned int rcaps, unsigned int wxcaps)
+{
+ struct fw_pfvf_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_PFVF_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_PFVF_CMD_PFN(pf) |
+ FW_PFVF_CMD_VFN(vf));
+ c.retval_len16 = htonl(FW_LEN16(c));
+ c.niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi) |
+ FW_PFVF_CMD_NIQ(rxq));
+ c.cmask_to_neq = htonl(FW_PFVF_CMD_CMASK(cmask) |
+ FW_PFVF_CMD_PMASK(pmask) |
+ FW_PFVF_CMD_NEQ(txq));
+ c.tc_to_nexactf = htonl(FW_PFVF_CMD_TC(tc) | FW_PFVF_CMD_NVI(vi) |
+ FW_PFVF_CMD_NEXACTF(nexact));
+ c.r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS(rcaps) |
+ FW_PFVF_CMD_WX_CAPS(wxcaps) |
+ FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl));
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_alloc_vi - allocate a virtual interface
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @port: physical port associated with the VI
+ * @pf: the PF owning the VI
+ * @vf: the VF owning the VI
+ * @nmac: number of MAC addresses needed (1 to 5)
+ * @mac: the MAC addresses of the VI
+ * @rss_size: size of RSS table slice associated with this VI
+ *
+ * Allocates a virtual interface for the given physical port. If @mac is
+ * not %NULL it contains the MAC addresses of the VI as assigned by FW.
+ * @mac should be large enough to hold @nmac Ethernet addresses, they are
+ * stored consecutively so the space needed is @nmac * 6 bytes.
+ * Returns a negative error number or the non-negative VI id.
+ */
+int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
+ unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
+ unsigned int *rss_size)
+{
+ int ret;
+ struct fw_vi_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_CMD_EXEC |
+ FW_VI_CMD_PFN(pf) | FW_VI_CMD_VFN(vf));
+ c.alloc_to_len16 = htonl(FW_VI_CMD_ALLOC | FW_LEN16(c));
+ c.portid_pkd = FW_VI_CMD_PORTID(port);
+ c.nmac = nmac - 1;
+
+ ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+ if (ret)
+ return ret;
+
+ if (mac) {
+ memcpy(mac, c.mac, sizeof(c.mac));
+ switch (nmac) {
+ case 5:
+ memcpy(mac + 24, c.nmac3, sizeof(c.nmac3));
+ case 4:
+ memcpy(mac + 18, c.nmac2, sizeof(c.nmac2));
+ case 3:
+ memcpy(mac + 12, c.nmac1, sizeof(c.nmac1));
+ case 2:
+ memcpy(mac + 6, c.nmac0, sizeof(c.nmac0));
+ }
+ }
+ if (rss_size)
+ *rss_size = FW_VI_CMD_RSSSIZE_GET(ntohs(c.rsssize_pkd));
+ return ntohs(c.viid_pkd);
+}
+
+/**
+ * t4_free_vi - free a virtual interface
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF owning the VI
+ * @vf: the VF owning the VI
+ * @viid: virtual interface identifiler
+ *
+ * Free a previously allocated virtual interface.
+ */
+int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int viid)
+{
+ struct fw_vi_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_VI_CMD_PFN(pf) |
+ FW_VI_CMD_VFN(vf));
+ c.alloc_to_len16 = htonl(FW_VI_CMD_FREE | FW_LEN16(c));
+ c.viid_pkd = htons(FW_VI_CMD_VIID(viid));
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+}
+
+/**
+ * t4_set_rxmode - set Rx properties of a virtual interface
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @viid: the VI id
+ * @mtu: the new MTU or -1
+ * @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change
+ * @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change
+ * @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change
+ * @sleep_ok: if true we may sleep while awaiting command completion
+ *
+ * Sets Rx properties of a virtual interface.
+ */
+int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ int mtu, int promisc, int all_multi, int bcast, bool sleep_ok)
+{
+ struct fw_vi_rxmode_cmd c;
+
+ /* convert to FW values */
+ if (mtu < 0)
+ mtu = FW_RXMODE_MTU_NO_CHG;
+ if (promisc < 0)
+ promisc = FW_VI_RXMODE_CMD_PROMISCEN_MASK;
+ if (all_multi < 0)
+ all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK;
+ if (bcast < 0)
+ bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_viid = htonl(FW_CMD_OP(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_VI_RXMODE_CMD_VIID(viid));
+ c.retval_len16 = htonl(FW_LEN16(c));
+ c.mtu_to_broadcasten = htonl(FW_VI_RXMODE_CMD_MTU(mtu) |
+ FW_VI_RXMODE_CMD_PROMISCEN(promisc) |
+ FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) |
+ FW_VI_RXMODE_CMD_BROADCASTEN(bcast));
+ return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
+}
+
+/**
+ * t4_alloc_mac_filt - allocates exact-match filters for MAC addresses
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @viid: the VI id
+ * @free: if true any existing filters for this VI id are first removed
+ * @naddr: the number of MAC addresses to allocate filters for (up to 7)
+ * @addr: the MAC address(es)
+ * @idx: where to store the index of each allocated filter
+ * @hash: pointer to hash address filter bitmap
+ * @sleep_ok: call is allowed to sleep
+ *
+ * Allocates an exact-match filter for each of the supplied addresses and
+ * sets it to the corresponding address. If @idx is not %NULL it should
+ * have at least @naddr entries, each of which will be set to the index of
+ * the filter allocated for the corresponding MAC address. If a filter
+ * could not be allocated for an address its index is set to 0xffff.
+ * If @hash is not %NULL addresses that fail to allocate an exact filter
+ * are hashed and update the hash filter bitmap pointed at by @hash.
+ *
+ * Returns a negative error number or the number of filters allocated.
+ */
+int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
+ unsigned int viid, bool free, unsigned int naddr,
+ const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok)
+{
+ int i, ret;
+ struct fw_vi_mac_cmd c;
+ struct fw_vi_mac_exact *p;
+
+ if (naddr > 7)
+ return -EINVAL;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | (free ? FW_CMD_EXEC : 0) |
+ FW_VI_MAC_CMD_VIID(viid));
+ c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_FREEMACS(free) |
+ FW_CMD_LEN16((naddr + 2) / 2));
+
+ for (i = 0, p = c.u.exact; i < naddr; i++, p++) {
+ p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID |
+ FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
+ memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
+ }
+
+ ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok);
+ if (ret)
+ return ret;
+
+ for (i = 0, p = c.u.exact; i < naddr; i++, p++) {
+ u16 index = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx));
+
+ if (idx)
+ idx[i] = index >= NEXACT_MAC ? 0xffff : index;
+ if (index < NEXACT_MAC)
+ ret++;
+ else if (hash)
+ *hash |= (1 << hash_mac_addr(addr[i]));
+ }
+ return ret;
+}
+
+/**
+ * t4_change_mac - modifies the exact-match filter for a MAC address
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @viid: the VI id
+ * @idx: index of existing filter for old value of MAC address, or -1
+ * @addr: the new MAC address value
+ * @persist: whether a new MAC allocation should be persistent
+ * @add_smt: if true also add the address to the HW SMT
+ *
+ * Modifies an exact-match filter and sets it to the new MAC address.
+ * Note that in general it is not possible to modify the value of a given
+ * filter so the generic way to modify an address filter is to free the one
+ * being used by the old address value and allocate a new filter for the
+ * new address value. @idx can be -1 if the address is a new addition.
+ *
+ * Returns a negative error number or the index of the filter with the new
+ * MAC value.
+ */
+int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ int idx, const u8 *addr, bool persist, bool add_smt)
+{
+ int ret, mode;
+ struct fw_vi_mac_cmd c;
+ struct fw_vi_mac_exact *p = c.u.exact;
+
+ if (idx < 0) /* new allocation */
+ idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC;
+ mode = add_smt ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_VI_MAC_CMD_VIID(viid));
+ c.freemacs_to_len16 = htonl(FW_CMD_LEN16(1));
+ p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID |
+ FW_VI_MAC_CMD_SMAC_RESULT(mode) |
+ FW_VI_MAC_CMD_IDX(idx));
+ memcpy(p->macaddr, addr, sizeof(p->macaddr));
+
+ ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+ if (ret == 0) {
+ ret = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx));
+ if (ret >= NEXACT_MAC)
+ ret = -ENOMEM;
+ }
+ return ret;
+}
+
+/**
+ * t4_set_addr_hash - program the MAC inexact-match hash filter
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @viid: the VI id
+ * @ucast: whether the hash filter should also match unicast addresses
+ * @vec: the value to be written to the hash filter
+ * @sleep_ok: call is allowed to sleep
+ *
+ * Sets the 64-bit inexact-match hash filter for a virtual interface.
+ */
+int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ bool ucast, u64 vec, bool sleep_ok)
+{
+ struct fw_vi_mac_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+ FW_CMD_WRITE | FW_VI_ENABLE_CMD_VIID(viid));
+ c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_HASHVECEN |
+ FW_VI_MAC_CMD_HASHUNIEN(ucast) |
+ FW_CMD_LEN16(1));
+ c.u.hash.hashvec = cpu_to_be64(vec);
+ return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
+}
+
+/**
+ * t4_enable_vi - enable/disable a virtual interface
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @viid: the VI id
+ * @rx_en: 1=enable Rx, 0=disable Rx
+ * @tx_en: 1=enable Tx, 0=disable Tx
+ *
+ * Enables/disables a virtual interface.
+ */
+int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ bool rx_en, bool tx_en)
+{
+ struct fw_vi_enable_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
+ c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN(rx_en) |
+ FW_VI_ENABLE_CMD_EEN(tx_en) | FW_LEN16(c));
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_identify_port - identify a VI's port by blinking its LED
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @viid: the VI id
+ * @nblinks: how many times to blink LED at 2.5 Hz
+ *
+ * Identifies a VI's port by blinking its LED.
+ */
+int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
+ unsigned int nblinks)
+{
+ struct fw_vi_enable_cmd c;
+
+ c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
+ c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c));
+ c.blinkdur = htons(nblinks);
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_iq_start_stop - enable/disable an ingress queue and its FLs
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @start: %true to enable the queues, %false to disable them
+ * @pf: the PF owning the queues
+ * @vf: the VF owning the queues
+ * @iqid: ingress queue id
+ * @fl0id: FL0 queue id or 0xffff if no attached FL0
+ * @fl1id: FL1 queue id or 0xffff if no attached FL1
+ *
+ * Starts or stops an ingress queue and its associated FLs, if any.
+ */
+int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
+ unsigned int pf, unsigned int vf, unsigned int iqid,
+ unsigned int fl0id, unsigned int fl1id)
+{
+ struct fw_iq_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) |
+ FW_IQ_CMD_VFN(vf));
+ c.alloc_to_len16 = htonl(FW_IQ_CMD_IQSTART(start) |
+ FW_IQ_CMD_IQSTOP(!start) | FW_LEN16(c));
+ c.iqid = htons(iqid);
+ c.fl0id = htons(fl0id);
+ c.fl1id = htons(fl1id);
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_iq_free - free an ingress queue and its FLs
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF owning the queues
+ * @vf: the VF owning the queues
+ * @iqtype: the ingress queue type
+ * @iqid: ingress queue id
+ * @fl0id: FL0 queue id or 0xffff if no attached FL0
+ * @fl1id: FL1 queue id or 0xffff if no attached FL1
+ *
+ * Frees an ingress queue and its associated FLs, if any.
+ */
+int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int iqtype, unsigned int iqid,
+ unsigned int fl0id, unsigned int fl1id)
+{
+ struct fw_iq_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) |
+ FW_IQ_CMD_VFN(vf));
+ c.alloc_to_len16 = htonl(FW_IQ_CMD_FREE | FW_LEN16(c));
+ c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iqtype));
+ c.iqid = htons(iqid);
+ c.fl0id = htons(fl0id);
+ c.fl1id = htons(fl1id);
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_eth_eq_free - free an Ethernet egress queue
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF owning the queue
+ * @vf: the VF owning the queue
+ * @eqid: egress queue id
+ *
+ * Frees an Ethernet egress queue.
+ */
+int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int eqid)
+{
+ struct fw_eq_eth_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_EQ_ETH_CMD_PFN(pf) |
+ FW_EQ_ETH_CMD_VFN(vf));
+ c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_FREE | FW_LEN16(c));
+ c.eqid_pkd = htonl(FW_EQ_ETH_CMD_EQID(eqid));
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_ctrl_eq_free - free a control egress queue
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF owning the queue
+ * @vf: the VF owning the queue
+ * @eqid: egress queue id
+ *
+ * Frees a control egress queue.
+ */
+int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int eqid)
+{
+ struct fw_eq_ctrl_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_EQ_CTRL_CMD_PFN(pf) |
+ FW_EQ_CTRL_CMD_VFN(vf));
+ c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_FREE | FW_LEN16(c));
+ c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_EQID(eqid));
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_ofld_eq_free - free an offload egress queue
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF owning the queue
+ * @vf: the VF owning the queue
+ * @eqid: egress queue id
+ *
+ * Frees a control egress queue.
+ */
+int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+ unsigned int vf, unsigned int eqid)
+{
+ struct fw_eq_ofld_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_EQ_OFLD_CMD_PFN(pf) |
+ FW_EQ_OFLD_CMD_VFN(vf));
+ c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE | FW_LEN16(c));
+ c.eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eqid));
+ return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ * t4_handle_fw_rpl - process a FW reply message
+ * @adap: the adapter
+ * @rpl: start of the FW message
+ *
+ * Processes a FW message, such as link state change messages.
+ */
+int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
+{
+ u8 opcode = *(const u8 *)rpl;
+
+ if (opcode == FW_PORT_CMD) { /* link/module state change message */
+ int speed = 0, fc = 0;
+ const struct fw_port_cmd *p = (void *)rpl;
+ int chan = FW_PORT_CMD_PORTID_GET(ntohl(p->op_to_portid));
+ int port = adap->chan_map[chan];
+ struct port_info *pi = adap2pinfo(adap, port);
+ struct link_config *lc = &pi->link_cfg;
+ u32 stat = ntohl(p->u.info.lstatus_to_modtype);
+ int link_ok = (stat & FW_PORT_CMD_LSTATUS) != 0;
+ u32 mod = FW_PORT_CMD_MODTYPE_GET(stat);
+
+ if (stat & FW_PORT_CMD_RXPAUSE)
+ fc |= PAUSE_RX;
+ if (stat & FW_PORT_CMD_TXPAUSE)
+ fc |= PAUSE_TX;
+ if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
+ speed = SPEED_100;
+ else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
+ speed = SPEED_1000;
+ else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
+ speed = SPEED_10000;
+
+ if (link_ok != lc->link_ok || speed != lc->speed ||
+ fc != lc->fc) { /* something changed */
+ lc->link_ok = link_ok;
+ lc->speed = speed;
+ lc->fc = fc;
+ t4_os_link_changed(adap, port, link_ok);
+ }
+ if (mod != pi->mod_type) {
+ pi->mod_type = mod;
+ t4_os_portmod_changed(adap, port);
+ }
+ }
+ return 0;
+}
+
+static void __devinit get_pci_mode(struct adapter *adapter,
+ struct pci_params *p)
+{
+ u16 val;
+ u32 pcie_cap = pci_pcie_cap(adapter->pdev);
+
+ if (pcie_cap) {
+ pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA,
+ &val);
+ p->speed = val & PCI_EXP_LNKSTA_CLS;
+ p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4;
+ }
+}
+
+/**
+ * init_link_config - initialize a link's SW state
+ * @lc: structure holding the link state
+ * @caps: link capabilities
+ *
+ * Initializes the SW state maintained for each link, including the link's
+ * capabilities and default speed/flow-control/autonegotiation settings.
+ */
+static void __devinit init_link_config(struct link_config *lc,
+ unsigned int caps)
+{
+ lc->supported = caps;
+ lc->requested_speed = 0;
+ lc->speed = 0;
+ lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
+ if (lc->supported & FW_PORT_CAP_ANEG) {
+ lc->advertising = lc->supported & ADVERT_MASK;
+ lc->autoneg = AUTONEG_ENABLE;
+ lc->requested_fc |= PAUSE_AUTONEG;
+ } else {
+ lc->advertising = 0;
+ lc->autoneg = AUTONEG_DISABLE;
+ }
+}
+
+static int __devinit wait_dev_ready(struct adapter *adap)
+{
+ if (t4_read_reg(adap, PL_WHOAMI) != 0xffffffff)
+ return 0;
+ msleep(500);
+ return t4_read_reg(adap, PL_WHOAMI) != 0xffffffff ? 0 : -EIO;
+}
+
+/**
+ * t4_prep_adapter - prepare SW and HW for operation
+ * @adapter: the adapter
+ * @reset: if true perform a HW reset
+ *
+ * Initialize adapter SW state for the various HW modules, set initial
+ * values for some adapter tunables, take PHYs out of reset, and
+ * initialize the MDIO interface.
+ */
+int __devinit t4_prep_adapter(struct adapter *adapter)
+{
+ int ret;
+
+ ret = wait_dev_ready(adapter);
+ if (ret < 0)
+ return ret;
+
+ get_pci_mode(adapter, &adapter->params.pci);
+ adapter->params.rev = t4_read_reg(adapter, PL_REV);
+
+ ret = get_vpd_params(adapter, &adapter->params.vpd);
+ if (ret < 0)
+ return ret;
+
+ init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
+
+ /*
+ * Default port for debugging in case we can't reach FW.
+ */
+ adapter->params.nports = 1;
+ adapter->params.portvec = 1;
+ return 0;
+}
+
+int __devinit t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
+{
+ u8 addr[6];
+ int ret, i, j = 0;
+ struct fw_port_cmd c;
+
+ memset(&c, 0, sizeof(c));
+
+ for_each_port(adap, i) {
+ unsigned int rss_size;
+ struct port_info *p = adap2pinfo(adap, i);
+
+ while ((adap->params.portvec & (1 << j)) == 0)
+ j++;
+
+ c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) |
+ FW_CMD_REQUEST | FW_CMD_READ |
+ FW_PORT_CMD_PORTID(j));
+ c.action_to_len16 = htonl(
+ FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) |
+ FW_LEN16(c));
+ ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+ if (ret)
+ return ret;
+
+ ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size);
+ if (ret < 0)
+ return ret;
+
+ p->viid = ret;
+ p->tx_chan = j;
+ p->lport = j;
+ p->rss_size = rss_size;
+ memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
+ memcpy(adap->port[i]->perm_addr, addr, ETH_ALEN);
+
+ ret = ntohl(c.u.info.lstatus_to_modtype);
+ p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ?
+ FW_PORT_CMD_MDIOADDR_GET(ret) : -1;
+ p->port_type = FW_PORT_CMD_PTYPE_GET(ret);
+ p->mod_type = FW_PORT_CMD_MODTYPE_GET(ret);
+
+ init_link_config(&p->link_cfg, ntohs(c.u.info.pcap));
+ j++;
+ }
+ return 0;
+}
diff --git a/drivers/net/cxgb4/t4_hw.h b/drivers/net/cxgb4/t4_hw.h
new file mode 100644
index 00000000000..025623285c9
--- /dev/null
+++ b/drivers/net/cxgb4/t4_hw.h
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __T4_HW_H
+#define __T4_HW_H
+
+#include <linux/types.h>
+
+enum {
+ NCHAN = 4, /* # of HW channels */
+ MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */
+ EEPROMSIZE = 17408, /* Serial EEPROM physical size */
+ EEPROMVSIZE = 32768, /* Serial EEPROM virtual address space size */
+ RSS_NENTRIES = 2048, /* # of entries in RSS mapping table */
+ TCB_SIZE = 128, /* TCB size */
+ NMTUS = 16, /* size of MTU table */
+ NCCTRL_WIN = 32, /* # of congestion control windows */
+ NEXACT_MAC = 336, /* # of exact MAC address filters */
+ L2T_SIZE = 4096, /* # of L2T entries */
+ MBOX_LEN = 64, /* mailbox size in bytes */
+ TRACE_LEN = 112, /* length of trace data and mask */
+ FILTER_OPT_LEN = 36, /* filter tuple width for optional components */
+ NWOL_PAT = 8, /* # of WoL patterns */
+ WOL_PAT_LEN = 128, /* length of WoL patterns */
+};
+
+enum {
+ SF_PAGE_SIZE = 256, /* serial flash page size */
+ SF_SEC_SIZE = 64 * 1024, /* serial flash sector size */
+ SF_SIZE = SF_SEC_SIZE * 16, /* serial flash size */
+};
+
+enum { RSP_TYPE_FLBUF, RSP_TYPE_CPL, RSP_TYPE_INTR }; /* response entry types */
+
+enum { MBOX_OWNER_NONE, MBOX_OWNER_FW, MBOX_OWNER_DRV }; /* mailbox owners */
+
+enum {
+ SGE_MAX_WR_LEN = 512, /* max WR size in bytes */
+ SGE_NTIMERS = 6, /* # of interrupt holdoff timer values */
+ SGE_NCOUNTERS = 4, /* # of interrupt packet counter values */
+};
+
+struct sge_qstat { /* data written to SGE queue status entries */
+ __be32 qid;
+ __be16 cidx;
+ __be16 pidx;
+};
+
+/*
+ * Structure for last 128 bits of response descriptors
+ */
+struct rsp_ctrl {
+ __be32 hdrbuflen_pidx;
+ __be32 pldbuflen_qid;
+ union {
+ u8 type_gen;
+ __be64 last_flit;
+ };
+};
+
+#define RSPD_NEWBUF 0x80000000U
+#define RSPD_LEN 0x7fffffffU
+
+#define RSPD_GEN(x) ((x) >> 7)
+#define RSPD_TYPE(x) (((x) >> 4) & 3)
+
+#define QINTR_CNT_EN 0x1
+#define QINTR_TIMER_IDX(x) ((x) << 1)
+#endif /* __T4_HW_H */
diff --git a/drivers/net/cxgb4/t4_msg.h b/drivers/net/cxgb4/t4_msg.h
new file mode 100644
index 00000000000..fdb11744314
--- /dev/null
+++ b/drivers/net/cxgb4/t4_msg.h
@@ -0,0 +1,664 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __T4_MSG_H
+#define __T4_MSG_H
+
+#include <linux/types.h>
+
+enum {
+ CPL_PASS_OPEN_REQ = 0x1,
+ CPL_PASS_ACCEPT_RPL = 0x2,
+ CPL_ACT_OPEN_REQ = 0x3,
+ CPL_SET_TCB_FIELD = 0x5,
+ CPL_GET_TCB = 0x6,
+ CPL_CLOSE_CON_REQ = 0x8,
+ CPL_CLOSE_LISTSRV_REQ = 0x9,
+ CPL_ABORT_REQ = 0xA,
+ CPL_ABORT_RPL = 0xB,
+ CPL_RX_DATA_ACK = 0xD,
+ CPL_TX_PKT = 0xE,
+ CPL_L2T_WRITE_REQ = 0x12,
+ CPL_TID_RELEASE = 0x1A,
+
+ CPL_CLOSE_LISTSRV_RPL = 0x20,
+ CPL_L2T_WRITE_RPL = 0x23,
+ CPL_PASS_OPEN_RPL = 0x24,
+ CPL_ACT_OPEN_RPL = 0x25,
+ CPL_PEER_CLOSE = 0x26,
+ CPL_ABORT_REQ_RSS = 0x2B,
+ CPL_ABORT_RPL_RSS = 0x2D,
+
+ CPL_CLOSE_CON_RPL = 0x32,
+ CPL_ISCSI_HDR = 0x33,
+ CPL_RDMA_CQE = 0x35,
+ CPL_RDMA_CQE_READ_RSP = 0x36,
+ CPL_RDMA_CQE_ERR = 0x37,
+ CPL_RX_DATA = 0x39,
+ CPL_SET_TCB_RPL = 0x3A,
+ CPL_RX_PKT = 0x3B,
+ CPL_RX_DDP_COMPLETE = 0x3F,
+
+ CPL_ACT_ESTABLISH = 0x40,
+ CPL_PASS_ESTABLISH = 0x41,
+ CPL_RX_DATA_DDP = 0x42,
+ CPL_PASS_ACCEPT_REQ = 0x44,
+
+ CPL_RDMA_READ_REQ = 0x60,
+
+ CPL_PASS_OPEN_REQ6 = 0x81,
+ CPL_ACT_OPEN_REQ6 = 0x83,
+
+ CPL_RDMA_TERMINATE = 0xA2,
+ CPL_RDMA_WRITE = 0xA4,
+ CPL_SGE_EGR_UPDATE = 0xA5,
+
+ CPL_TRACE_PKT = 0xB0,
+
+ CPL_FW4_MSG = 0xC0,
+ CPL_FW4_PLD = 0xC1,
+ CPL_FW4_ACK = 0xC3,
+
+ CPL_FW6_MSG = 0xE0,
+ CPL_FW6_PLD = 0xE1,
+ CPL_TX_PKT_LSO = 0xED,
+ CPL_TX_PKT_XT = 0xEE,
+
+ NUM_CPL_CMDS
+};
+
+enum CPL_error {
+ CPL_ERR_NONE = 0,
+ CPL_ERR_TCAM_FULL = 3,
+ CPL_ERR_BAD_LENGTH = 15,
+ CPL_ERR_BAD_ROUTE = 18,
+ CPL_ERR_CONN_RESET = 20,
+ CPL_ERR_CONN_EXIST_SYNRECV = 21,
+ CPL_ERR_CONN_EXIST = 22,
+ CPL_ERR_ARP_MISS = 23,
+ CPL_ERR_BAD_SYN = 24,
+ CPL_ERR_CONN_TIMEDOUT = 30,
+ CPL_ERR_XMIT_TIMEDOUT = 31,
+ CPL_ERR_PERSIST_TIMEDOUT = 32,
+ CPL_ERR_FINWAIT2_TIMEDOUT = 33,
+ CPL_ERR_KEEPALIVE_TIMEDOUT = 34,
+ CPL_ERR_RTX_NEG_ADVICE = 35,
+ CPL_ERR_PERSIST_NEG_ADVICE = 36,
+ CPL_ERR_ABORT_FAILED = 42,
+ CPL_ERR_IWARP_FLM = 50,
+};
+
+enum {
+ ULP_MODE_NONE = 0,
+ ULP_MODE_ISCSI = 2,
+ ULP_MODE_RDMA = 4,
+ ULP_MODE_FCOE = 6,
+};
+
+enum {
+ ULP_CRC_HEADER = 1 << 0,
+ ULP_CRC_DATA = 1 << 1
+};
+
+enum {
+ CPL_ABORT_SEND_RST = 0,
+ CPL_ABORT_NO_RST,
+};
+
+enum { /* TX_PKT_XT checksum types */
+ TX_CSUM_TCP = 0,
+ TX_CSUM_UDP = 1,
+ TX_CSUM_CRC16 = 4,
+ TX_CSUM_CRC32 = 5,
+ TX_CSUM_CRC32C = 6,
+ TX_CSUM_FCOE = 7,
+ TX_CSUM_TCPIP = 8,
+ TX_CSUM_UDPIP = 9,
+ TX_CSUM_TCPIP6 = 10,
+ TX_CSUM_UDPIP6 = 11,
+ TX_CSUM_IP = 12,
+};
+
+union opcode_tid {
+ __be32 opcode_tid;
+ u8 opcode;
+};
+
+#define CPL_OPCODE(x) ((x) << 24)
+#define MK_OPCODE_TID(opcode, tid) (CPL_OPCODE(opcode) | (tid))
+#define OPCODE_TID(cmd) ((cmd)->ot.opcode_tid)
+#define GET_TID(cmd) (ntohl(OPCODE_TID(cmd)) & 0xFFFFFF)
+
+/* partitioning of TID fields that also carry a queue id */
+#define GET_TID_TID(x) ((x) & 0x3fff)
+#define GET_TID_QID(x) (((x) >> 14) & 0x3ff)
+#define TID_QID(x) ((x) << 14)
+
+struct rss_header {
+ u8 opcode;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 channel:2;
+ u8 filter_hit:1;
+ u8 filter_tid:1;
+ u8 hash_type:2;
+ u8 ipv6:1;
+ u8 send2fw:1;
+#else
+ u8 send2fw:1;
+ u8 ipv6:1;
+ u8 hash_type:2;
+ u8 filter_tid:1;
+ u8 filter_hit:1;
+ u8 channel:2;
+#endif
+ __be16 qid;
+ __be32 hash_val;
+};
+
+struct work_request_hdr {
+ __be32 wr_hi;
+ __be32 wr_mid;
+ __be64 wr_lo;
+};
+
+#define WR_HDR struct work_request_hdr wr
+
+struct cpl_pass_open_req {
+ WR_HDR;
+ union opcode_tid ot;
+ __be16 local_port;
+ __be16 peer_port;
+ __be32 local_ip;
+ __be32 peer_ip;
+ __be64 opt0;
+#define TX_CHAN(x) ((x) << 2)
+#define DELACK(x) ((x) << 5)
+#define ULP_MODE(x) ((x) << 8)
+#define RCV_BUFSIZ(x) ((x) << 12)
+#define DSCP(x) ((x) << 22)
+#define SMAC_SEL(x) ((u64)(x) << 28)
+#define L2T_IDX(x) ((u64)(x) << 36)
+#define NAGLE(x) ((u64)(x) << 49)
+#define WND_SCALE(x) ((u64)(x) << 50)
+#define KEEP_ALIVE(x) ((u64)(x) << 54)
+#define MSS_IDX(x) ((u64)(x) << 60)
+ __be64 opt1;
+#define SYN_RSS_ENABLE (1 << 0)
+#define SYN_RSS_QUEUE(x) ((x) << 2)
+#define CONN_POLICY_ASK (1 << 22)
+};
+
+struct cpl_pass_open_req6 {
+ WR_HDR;
+ union opcode_tid ot;
+ __be16 local_port;
+ __be16 peer_port;
+ __be64 local_ip_hi;
+ __be64 local_ip_lo;
+ __be64 peer_ip_hi;
+ __be64 peer_ip_lo;
+ __be64 opt0;
+ __be64 opt1;
+};
+
+struct cpl_pass_open_rpl {
+ union opcode_tid ot;
+ u8 rsvd[3];
+ u8 status;
+};
+
+struct cpl_pass_accept_rpl {
+ WR_HDR;
+ union opcode_tid ot;
+ __be32 opt2;
+#define RSS_QUEUE(x) ((x) << 0)
+#define RSS_QUEUE_VALID (1 << 10)
+#define RX_COALESCE_VALID(x) ((x) << 11)
+#define RX_COALESCE(x) ((x) << 12)
+#define TX_QUEUE(x) ((x) << 23)
+#define RX_CHANNEL(x) ((x) << 26)
+#define WND_SCALE_EN(x) ((x) << 28)
+#define TSTAMPS_EN(x) ((x) << 29)
+#define SACK_EN(x) ((x) << 30)
+ __be64 opt0;
+};
+
+struct cpl_act_open_req {
+ WR_HDR;
+ union opcode_tid ot;
+ __be16 local_port;
+ __be16 peer_port;
+ __be32 local_ip;
+ __be32 peer_ip;
+ __be64 opt0;
+ __be32 params;
+ __be32 opt2;
+};
+
+struct cpl_act_open_req6 {
+ WR_HDR;
+ union opcode_tid ot;
+ __be16 local_port;
+ __be16 peer_port;
+ __be64 local_ip_hi;
+ __be64 local_ip_lo;
+ __be64 peer_ip_hi;
+ __be64 peer_ip_lo;
+ __be64 opt0;
+ __be32 params;
+ __be32 opt2;
+};
+
+struct cpl_act_open_rpl {
+ union opcode_tid ot;
+ __be32 atid_status;
+#define GET_AOPEN_STATUS(x) ((x) & 0xff)
+#define GET_AOPEN_ATID(x) (((x) >> 8) & 0xffffff)
+};
+
+struct cpl_pass_establish {
+ union opcode_tid ot;
+ __be32 rsvd;
+ __be32 tos_stid;
+#define GET_POPEN_TID(x) ((x) & 0xffffff)
+#define GET_POPEN_TOS(x) (((x) >> 24) & 0xff)
+ __be16 mac_idx;
+ __be16 tcp_opt;
+#define GET_TCPOPT_WSCALE_OK(x) (((x) >> 5) & 1)
+#define GET_TCPOPT_SACK(x) (((x) >> 6) & 1)
+#define GET_TCPOPT_TSTAMP(x) (((x) >> 7) & 1)
+#define GET_TCPOPT_SND_WSCALE(x) (((x) >> 8) & 0xf)
+#define GET_TCPOPT_MSS(x) (((x) >> 12) & 0xf)
+ __be32 snd_isn;
+ __be32 rcv_isn;
+};
+
+struct cpl_act_establish {
+ union opcode_tid ot;
+ __be32 rsvd;
+ __be32 tos_atid;
+ __be16 mac_idx;
+ __be16 tcp_opt;
+ __be32 snd_isn;
+ __be32 rcv_isn;
+};
+
+struct cpl_get_tcb {
+ WR_HDR;
+ union opcode_tid ot;
+ __be16 reply_ctrl;
+#define QUEUENO(x) ((x) << 0)
+#define REPLY_CHAN(x) ((x) << 14)
+#define NO_REPLY(x) ((x) << 15)
+ __be16 cookie;
+};
+
+struct cpl_set_tcb_field {
+ WR_HDR;
+ union opcode_tid ot;
+ __be16 reply_ctrl;
+ __be16 word_cookie;
+#define TCB_WORD(x) ((x) << 0)
+#define TCB_COOKIE(x) ((x) << 5)
+ __be64 mask;
+ __be64 val;
+};
+
+struct cpl_set_tcb_rpl {
+ union opcode_tid ot;
+ __be16 rsvd;
+ u8 cookie;
+ u8 status;
+ __be64 oldval;
+};
+
+struct cpl_close_con_req {
+ WR_HDR;
+ union opcode_tid ot;
+ __be32 rsvd;
+};
+
+struct cpl_close_con_rpl {
+ union opcode_tid ot;
+ u8 rsvd[3];
+ u8 status;
+ __be32 snd_nxt;
+ __be32 rcv_nxt;
+};
+
+struct cpl_close_listsvr_req {
+ WR_HDR;
+ union opcode_tid ot;
+ __be16 reply_ctrl;
+#define LISTSVR_IPV6 (1 << 14)
+ __be16 rsvd;
+};
+
+struct cpl_close_listsvr_rpl {
+ union opcode_tid ot;
+ u8 rsvd[3];
+ u8 status;
+};
+
+struct cpl_abort_req_rss {
+ union opcode_tid ot;
+ u8 rsvd[3];
+ u8 status;
+};
+
+struct cpl_abort_req {
+ WR_HDR;
+ union opcode_tid ot;
+ __be32 rsvd0;
+ u8 rsvd1;
+ u8 cmd;
+ u8 rsvd2[6];
+};
+
+struct cpl_abort_rpl_rss {
+ union opcode_tid ot;
+ u8 rsvd[3];
+ u8 status;
+};
+
+struct cpl_abort_rpl {
+ WR_HDR;
+ union opcode_tid ot;
+ __be32 rsvd0;
+ u8 rsvd1;
+ u8 cmd;
+ u8 rsvd2[6];
+};
+
+struct cpl_peer_close {
+ union opcode_tid ot;
+ __be32 rcv_nxt;
+};
+
+struct cpl_tid_release {
+ WR_HDR;
+ union opcode_tid ot;
+ __be32 rsvd;
+};
+
+struct cpl_tx_pkt_core {
+ __be32 ctrl0;
+#define TXPKT_VF(x) ((x) << 0)
+#define TXPKT_PF(x) ((x) << 8)
+#define TXPKT_VF_VLD (1 << 11)
+#define TXPKT_OVLAN_IDX(x) ((x) << 12)
+#define TXPKT_INTF(x) ((x) << 16)
+#define TXPKT_INS_OVLAN (1 << 21)
+#define TXPKT_OPCODE(x) ((x) << 24)
+ __be16 pack;
+ __be16 len;
+ __be64 ctrl1;
+#define TXPKT_CSUM_END(x) ((x) << 12)
+#define TXPKT_CSUM_START(x) ((x) << 20)
+#define TXPKT_IPHDR_LEN(x) ((u64)(x) << 20)
+#define TXPKT_CSUM_LOC(x) ((u64)(x) << 30)
+#define TXPKT_ETHHDR_LEN(x) ((u64)(x) << 34)
+#define TXPKT_CSUM_TYPE(x) ((u64)(x) << 40)
+#define TXPKT_VLAN(x) ((u64)(x) << 44)
+#define TXPKT_VLAN_VLD (1ULL << 60)
+#define TXPKT_IPCSUM_DIS (1ULL << 62)
+#define TXPKT_L4CSUM_DIS (1ULL << 63)
+};
+
+struct cpl_tx_pkt {
+ WR_HDR;
+ struct cpl_tx_pkt_core c;
+};
+
+#define cpl_tx_pkt_xt cpl_tx_pkt
+
+struct cpl_tx_pkt_lso {
+ WR_HDR;
+ __be32 lso_ctrl;
+#define LSO_TCPHDR_LEN(x) ((x) << 0)
+#define LSO_IPHDR_LEN(x) ((x) << 4)
+#define LSO_ETHHDR_LEN(x) ((x) << 16)
+#define LSO_IPV6(x) ((x) << 20)
+#define LSO_LAST_SLICE (1 << 22)
+#define LSO_FIRST_SLICE (1 << 23)
+#define LSO_OPCODE(x) ((x) << 24)
+ __be16 ipid_ofst;
+ __be16 mss;
+ __be32 seqno_offset;
+ __be32 len;
+ /* encapsulated CPL (TX_PKT, TX_PKT_XT or TX_DATA) follows here */
+};
+
+struct cpl_iscsi_hdr {
+ union opcode_tid ot;
+ __be16 pdu_len_ddp;
+#define ISCSI_PDU_LEN(x) ((x) & 0x7FFF)
+#define ISCSI_DDP (1 << 15)
+ __be16 len;
+ __be32 seq;
+ __be16 urg;
+ u8 rsvd;
+ u8 status;
+};
+
+struct cpl_rx_data {
+ union opcode_tid ot;
+ __be16 rsvd;
+ __be16 len;
+ __be32 seq;
+ __be16 urg;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 dack_mode:2;
+ u8 psh:1;
+ u8 heartbeat:1;
+ u8 ddp_off:1;
+ u8 :3;
+#else
+ u8 :3;
+ u8 ddp_off:1;
+ u8 heartbeat:1;
+ u8 psh:1;
+ u8 dack_mode:2;
+#endif
+ u8 status;
+};
+
+struct cpl_rx_data_ack {
+ WR_HDR;
+ union opcode_tid ot;
+ __be32 credit_dack;
+#define RX_CREDITS(x) ((x) << 0)
+#define RX_FORCE_ACK(x) ((x) << 28)
+};
+
+struct cpl_rx_pkt {
+ u8 opcode;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 iff:4;
+ u8 csum_calc:1;
+ u8 ipmi_pkt:1;
+ u8 vlan_ex:1;
+ u8 ip_frag:1;
+#else
+ u8 ip_frag:1;
+ u8 vlan_ex:1;
+ u8 ipmi_pkt:1;
+ u8 csum_calc:1;
+ u8 iff:4;
+#endif
+ __be16 csum;
+ __be16 vlan;
+ __be16 len;
+ __be32 l2info;
+#define RXF_UDP (1 << 22)
+#define RXF_TCP (1 << 23)
+ __be16 hdr_len;
+ __be16 err_vec;
+};
+
+struct cpl_trace_pkt {
+ u8 opcode;
+ u8 intf;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 runt:4;
+ u8 filter_hit:4;
+ u8 :6;
+ u8 err:1;
+ u8 trunc:1;
+#else
+ u8 filter_hit:4;
+ u8 runt:4;
+ u8 trunc:1;
+ u8 err:1;
+ u8 :6;
+#endif
+ __be16 rsvd;
+ __be16 len;
+ __be64 tstamp;
+};
+
+struct cpl_l2t_write_req {
+ WR_HDR;
+ union opcode_tid ot;
+ __be16 params;
+#define L2T_W_INFO(x) ((x) << 2)
+#define L2T_W_PORT(x) ((x) << 8)
+#define L2T_W_NOREPLY(x) ((x) << 15)
+ __be16 l2t_idx;
+ __be16 vlan;
+ u8 dst_mac[6];
+};
+
+struct cpl_l2t_write_rpl {
+ union opcode_tid ot;
+ u8 status;
+ u8 rsvd[3];
+};
+
+struct cpl_rdma_terminate {
+ union opcode_tid ot;
+ __be16 rsvd;
+ __be16 len;
+};
+
+struct cpl_sge_egr_update {
+ __be32 opcode_qid;
+#define EGR_QID(x) ((x) & 0x1FFFF)
+ __be16 cidx;
+ __be16 pidx;
+};
+
+struct cpl_fw4_pld {
+ u8 opcode;
+ u8 rsvd0[3];
+ u8 type;
+ u8 rsvd1;
+ __be16 len;
+ __be64 data;
+ __be64 rsvd2;
+};
+
+struct cpl_fw6_pld {
+ u8 opcode;
+ u8 rsvd[5];
+ __be16 len;
+ __be64 data[4];
+};
+
+struct cpl_fw4_msg {
+ u8 opcode;
+ u8 type;
+ __be16 rsvd0;
+ __be32 rsvd1;
+ __be64 data[2];
+};
+
+struct cpl_fw4_ack {
+ union opcode_tid ot;
+ u8 credits;
+ u8 rsvd0[2];
+ u8 seq_vld;
+ __be32 snd_nxt;
+ __be32 snd_una;
+ __be64 rsvd1;
+};
+
+struct cpl_fw6_msg {
+ u8 opcode;
+ u8 type;
+ __be16 rsvd0;
+ __be32 rsvd1;
+ __be64 data[4];
+};
+
+enum {
+ ULP_TX_MEM_READ = 2,
+ ULP_TX_MEM_WRITE = 3,
+ ULP_TX_PKT = 4
+};
+
+enum {
+ ULP_TX_SC_NOOP = 0x80,
+ ULP_TX_SC_IMM = 0x81,
+ ULP_TX_SC_DSGL = 0x82,
+ ULP_TX_SC_ISGL = 0x83
+};
+
+struct ulptx_sge_pair {
+ __be32 len[2];
+ __be64 addr[2];
+};
+
+struct ulptx_sgl {
+ __be32 cmd_nsge;
+#define ULPTX_CMD(x) ((x) << 24)
+#define ULPTX_NSGE(x) ((x) << 0)
+ __be32 len0;
+ __be64 addr0;
+ struct ulptx_sge_pair sge[0];
+};
+
+struct ulp_mem_io {
+ WR_HDR;
+ __be32 cmd;
+#define ULP_MEMIO_ORDER(x) ((x) << 23)
+ __be32 len16; /* command length */
+ __be32 dlen; /* data length in 32-byte units */
+#define ULP_MEMIO_DATA_LEN(x) ((x) << 0)
+ __be32 lock_addr;
+#define ULP_MEMIO_ADDR(x) ((x) << 0)
+#define ULP_MEMIO_LOCK(x) ((x) << 31)
+};
+
+#endif /* __T4_MSG_H */
diff --git a/drivers/net/cxgb4/t4_regs.h b/drivers/net/cxgb4/t4_regs.h
new file mode 100644
index 00000000000..5ed56483cbc
--- /dev/null
+++ b/drivers/net/cxgb4/t4_regs.h
@@ -0,0 +1,878 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __T4_REGS_H
+#define __T4_REGS_H
+
+#define MYPF_BASE 0x1b000
+#define MYPF_REG(reg_addr) (MYPF_BASE + (reg_addr))
+
+#define PF0_BASE 0x1e000
+#define PF0_REG(reg_addr) (PF0_BASE + (reg_addr))
+
+#define PF_STRIDE 0x400
+#define PF_BASE(idx) (PF0_BASE + (idx) * PF_STRIDE)
+#define PF_REG(idx, reg) (PF_BASE(idx) + (reg))
+
+#define MYPORT_BASE 0x1c000
+#define MYPORT_REG(reg_addr) (MYPORT_BASE + (reg_addr))
+
+#define PORT0_BASE 0x20000
+#define PORT0_REG(reg_addr) (PORT0_BASE + (reg_addr))
+
+#define PORT_STRIDE 0x2000
+#define PORT_BASE(idx) (PORT0_BASE + (idx) * PORT_STRIDE)
+#define PORT_REG(idx, reg) (PORT_BASE(idx) + (reg))
+
+#define EDC_STRIDE (EDC_1_BASE_ADDR - EDC_0_BASE_ADDR)
+#define EDC_REG(reg, idx) (reg + EDC_STRIDE * idx)
+
+#define PCIE_MEM_ACCESS_REG(reg_addr, idx) ((reg_addr) + (idx) * 8)
+#define PCIE_MAILBOX_REG(reg_addr, idx) ((reg_addr) + (idx) * 8)
+#define MC_BIST_STATUS_REG(reg_addr, idx) ((reg_addr) + (idx) * 4)
+#define EDC_BIST_STATUS_REG(reg_addr, idx) ((reg_addr) + (idx) * 4)
+
+#define SGE_PF_KDOORBELL 0x0
+#define QID_MASK 0xffff8000U
+#define QID_SHIFT 15
+#define QID(x) ((x) << QID_SHIFT)
+#define DBPRIO 0x00004000U
+#define PIDX_MASK 0x00003fffU
+#define PIDX_SHIFT 0
+#define PIDX(x) ((x) << PIDX_SHIFT)
+
+#define SGE_PF_GTS 0x4
+#define INGRESSQID_MASK 0xffff0000U
+#define INGRESSQID_SHIFT 16
+#define INGRESSQID(x) ((x) << INGRESSQID_SHIFT)
+#define TIMERREG_MASK 0x0000e000U
+#define TIMERREG_SHIFT 13
+#define TIMERREG(x) ((x) << TIMERREG_SHIFT)
+#define SEINTARM_MASK 0x00001000U
+#define SEINTARM_SHIFT 12
+#define SEINTARM(x) ((x) << SEINTARM_SHIFT)
+#define CIDXINC_MASK 0x00000fffU
+#define CIDXINC_SHIFT 0
+#define CIDXINC(x) ((x) << CIDXINC_SHIFT)
+
+#define SGE_CONTROL 0x1008
+#define DCASYSTYPE 0x00080000U
+#define RXPKTCPLMODE 0x00040000U
+#define EGRSTATUSPAGESIZE 0x00020000U
+#define PKTSHIFT_MASK 0x00001c00U
+#define PKTSHIFT_SHIFT 10
+#define PKTSHIFT(x) ((x) << PKTSHIFT_SHIFT)
+#define INGPCIEBOUNDARY_MASK 0x00000380U
+#define INGPCIEBOUNDARY_SHIFT 7
+#define INGPCIEBOUNDARY(x) ((x) << INGPCIEBOUNDARY_SHIFT)
+#define INGPADBOUNDARY_MASK 0x00000070U
+#define INGPADBOUNDARY_SHIFT 4
+#define INGPADBOUNDARY(x) ((x) << INGPADBOUNDARY_SHIFT)
+#define EGRPCIEBOUNDARY_MASK 0x0000000eU
+#define EGRPCIEBOUNDARY_SHIFT 1
+#define EGRPCIEBOUNDARY(x) ((x) << EGRPCIEBOUNDARY_SHIFT)
+#define GLOBALENABLE 0x00000001U
+
+#define SGE_HOST_PAGE_SIZE 0x100c
+#define HOSTPAGESIZEPF0_MASK 0x0000000fU
+#define HOSTPAGESIZEPF0_SHIFT 0
+#define HOSTPAGESIZEPF0(x) ((x) << HOSTPAGESIZEPF0_SHIFT)
+
+#define SGE_EGRESS_QUEUES_PER_PAGE_PF 0x1010
+#define QUEUESPERPAGEPF0_MASK 0x0000000fU
+#define QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK)
+
+#define SGE_INT_CAUSE1 0x1024
+#define SGE_INT_CAUSE2 0x1030
+#define SGE_INT_CAUSE3 0x103c
+#define ERR_FLM_DBP 0x80000000U
+#define ERR_FLM_IDMA1 0x40000000U
+#define ERR_FLM_IDMA0 0x20000000U
+#define ERR_FLM_HINT 0x10000000U
+#define ERR_PCIE_ERROR3 0x08000000U
+#define ERR_PCIE_ERROR2 0x04000000U
+#define ERR_PCIE_ERROR1 0x02000000U
+#define ERR_PCIE_ERROR0 0x01000000U
+#define ERR_TIMER_ABOVE_MAX_QID 0x00800000U
+#define ERR_CPL_EXCEED_IQE_SIZE 0x00400000U
+#define ERR_INVALID_CIDX_INC 0x00200000U
+#define ERR_ITP_TIME_PAUSED 0x00100000U
+#define ERR_CPL_OPCODE_0 0x00080000U
+#define ERR_DROPPED_DB 0x00040000U
+#define ERR_DATA_CPL_ON_HIGH_QID1 0x00020000U
+#define ERR_DATA_CPL_ON_HIGH_QID0 0x00010000U
+#define ERR_BAD_DB_PIDX3 0x00008000U
+#define ERR_BAD_DB_PIDX2 0x00004000U
+#define ERR_BAD_DB_PIDX1 0x00002000U
+#define ERR_BAD_DB_PIDX0 0x00001000U
+#define ERR_ING_PCIE_CHAN 0x00000800U
+#define ERR_ING_CTXT_PRIO 0x00000400U
+#define ERR_EGR_CTXT_PRIO 0x00000200U
+#define DBFIFO_HP_INT 0x00000100U
+#define DBFIFO_LP_INT 0x00000080U
+#define REG_ADDRESS_ERR 0x00000040U
+#define INGRESS_SIZE_ERR 0x00000020U
+#define EGRESS_SIZE_ERR 0x00000010U
+#define ERR_INV_CTXT3 0x00000008U
+#define ERR_INV_CTXT2 0x00000004U
+#define ERR_INV_CTXT1 0x00000002U
+#define ERR_INV_CTXT0 0x00000001U
+
+#define SGE_INT_ENABLE3 0x1040
+#define SGE_FL_BUFFER_SIZE0 0x1044
+#define SGE_FL_BUFFER_SIZE1 0x1048
+#define SGE_INGRESS_RX_THRESHOLD 0x10a0
+#define THRESHOLD_0_MASK 0x3f000000U
+#define THRESHOLD_0_SHIFT 24
+#define THRESHOLD_0(x) ((x) << THRESHOLD_0_SHIFT)
+#define THRESHOLD_0_GET(x) (((x) & THRESHOLD_0_MASK) >> THRESHOLD_0_SHIFT)
+#define THRESHOLD_1_MASK 0x003f0000U
+#define THRESHOLD_1_SHIFT 16
+#define THRESHOLD_1(x) ((x) << THRESHOLD_1_SHIFT)
+#define THRESHOLD_1_GET(x) (((x) & THRESHOLD_1_MASK) >> THRESHOLD_1_SHIFT)
+#define THRESHOLD_2_MASK 0x00003f00U
+#define THRESHOLD_2_SHIFT 8
+#define THRESHOLD_2(x) ((x) << THRESHOLD_2_SHIFT)
+#define THRESHOLD_2_GET(x) (((x) & THRESHOLD_2_MASK) >> THRESHOLD_2_SHIFT)
+#define THRESHOLD_3_MASK 0x0000003fU
+#define THRESHOLD_3_SHIFT 0
+#define THRESHOLD_3(x) ((x) << THRESHOLD_3_SHIFT)
+#define THRESHOLD_3_GET(x) (((x) & THRESHOLD_3_MASK) >> THRESHOLD_3_SHIFT)
+
+#define SGE_TIMER_VALUE_0_AND_1 0x10b8
+#define TIMERVALUE0_MASK 0xffff0000U
+#define TIMERVALUE0_SHIFT 16
+#define TIMERVALUE0(x) ((x) << TIMERVALUE0_SHIFT)
+#define TIMERVALUE0_GET(x) (((x) & TIMERVALUE0_MASK) >> TIMERVALUE0_SHIFT)
+#define TIMERVALUE1_MASK 0x0000ffffU
+#define TIMERVALUE1_SHIFT 0
+#define TIMERVALUE1(x) ((x) << TIMERVALUE1_SHIFT)
+#define TIMERVALUE1_GET(x) (((x) & TIMERVALUE1_MASK) >> TIMERVALUE1_SHIFT)
+
+#define SGE_TIMER_VALUE_2_AND_3 0x10bc
+#define SGE_TIMER_VALUE_4_AND_5 0x10c0
+#define SGE_DEBUG_INDEX 0x10cc
+#define SGE_DEBUG_DATA_HIGH 0x10d0
+#define SGE_DEBUG_DATA_LOW 0x10d4
+#define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4
+
+#define PCIE_PF_CLI 0x44
+#define PCIE_INT_CAUSE 0x3004
+#define UNXSPLCPLERR 0x20000000U
+#define PCIEPINT 0x10000000U
+#define PCIESINT 0x08000000U
+#define RPLPERR 0x04000000U
+#define RXWRPERR 0x02000000U
+#define RXCPLPERR 0x01000000U
+#define PIOTAGPERR 0x00800000U
+#define MATAGPERR 0x00400000U
+#define INTXCLRPERR 0x00200000U
+#define FIDPERR 0x00100000U
+#define CFGSNPPERR 0x00080000U
+#define HRSPPERR 0x00040000U
+#define HREQPERR 0x00020000U
+#define HCNTPERR 0x00010000U
+#define DRSPPERR 0x00008000U
+#define DREQPERR 0x00004000U
+#define DCNTPERR 0x00002000U
+#define CRSPPERR 0x00001000U
+#define CREQPERR 0x00000800U
+#define CCNTPERR 0x00000400U
+#define TARTAGPERR 0x00000200U
+#define PIOREQPERR 0x00000100U
+#define PIOCPLPERR 0x00000080U
+#define MSIXDIPERR 0x00000040U
+#define MSIXDATAPERR 0x00000020U
+#define MSIXADDRHPERR 0x00000010U
+#define MSIXADDRLPERR 0x00000008U
+#define MSIDATAPERR 0x00000004U
+#define MSIADDRHPERR 0x00000002U
+#define MSIADDRLPERR 0x00000001U
+
+#define PCIE_NONFAT_ERR 0x3010
+#define PCIE_MEM_ACCESS_BASE_WIN 0x3068
+#define PCIEOFST_MASK 0xfffffc00U
+#define BIR_MASK 0x00000300U
+#define BIR_SHIFT 8
+#define BIR(x) ((x) << BIR_SHIFT)
+#define WINDOW_MASK 0x000000ffU
+#define WINDOW_SHIFT 0
+#define WINDOW(x) ((x) << WINDOW_SHIFT)
+
+#define PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS 0x5908
+#define RNPP 0x80000000U
+#define RPCP 0x20000000U
+#define RCIP 0x08000000U
+#define RCCP 0x04000000U
+#define RFTP 0x00800000U
+#define PTRP 0x00100000U
+
+#define PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS 0x59a4
+#define TPCP 0x40000000U
+#define TNPP 0x20000000U
+#define TFTP 0x10000000U
+#define TCAP 0x08000000U
+#define TCIP 0x04000000U
+#define RCAP 0x02000000U
+#define PLUP 0x00800000U
+#define PLDN 0x00400000U
+#define OTDD 0x00200000U
+#define GTRP 0x00100000U
+#define RDPE 0x00040000U
+#define TDCE 0x00020000U
+#define TDUE 0x00010000U
+
+#define MC_INT_CAUSE 0x7518
+#define ECC_UE_INT_CAUSE 0x00000004U
+#define ECC_CE_INT_CAUSE 0x00000002U
+#define PERR_INT_CAUSE 0x00000001U
+
+#define MC_ECC_STATUS 0x751c
+#define ECC_CECNT_MASK 0xffff0000U
+#define ECC_CECNT_SHIFT 16
+#define ECC_CECNT(x) ((x) << ECC_CECNT_SHIFT)
+#define ECC_CECNT_GET(x) (((x) & ECC_CECNT_MASK) >> ECC_CECNT_SHIFT)
+#define ECC_UECNT_MASK 0x0000ffffU
+#define ECC_UECNT_SHIFT 0
+#define ECC_UECNT(x) ((x) << ECC_UECNT_SHIFT)
+#define ECC_UECNT_GET(x) (((x) & ECC_UECNT_MASK) >> ECC_UECNT_SHIFT)
+
+#define MC_BIST_CMD 0x7600
+#define START_BIST 0x80000000U
+#define BIST_CMD_GAP_MASK 0x0000ff00U
+#define BIST_CMD_GAP_SHIFT 8
+#define BIST_CMD_GAP(x) ((x) << BIST_CMD_GAP_SHIFT)
+#define BIST_OPCODE_MASK 0x00000003U
+#define BIST_OPCODE_SHIFT 0
+#define BIST_OPCODE(x) ((x) << BIST_OPCODE_SHIFT)
+
+#define MC_BIST_CMD_ADDR 0x7604
+#define MC_BIST_CMD_LEN 0x7608
+#define MC_BIST_DATA_PATTERN 0x760c
+#define BIST_DATA_TYPE_MASK 0x0000000fU
+#define BIST_DATA_TYPE_SHIFT 0
+#define BIST_DATA_TYPE(x) ((x) << BIST_DATA_TYPE_SHIFT)
+
+#define MC_BIST_STATUS_RDATA 0x7688
+
+#define MA_EXT_MEMORY_BAR 0x77c8
+#define EXT_MEM_SIZE_MASK 0x00000fffU
+#define EXT_MEM_SIZE_SHIFT 0
+#define EXT_MEM_SIZE_GET(x) (((x) & EXT_MEM_SIZE_MASK) >> EXT_MEM_SIZE_SHIFT)
+
+#define MA_TARGET_MEM_ENABLE 0x77d8
+#define EXT_MEM_ENABLE 0x00000004U
+#define EDRAM1_ENABLE 0x00000002U
+#define EDRAM0_ENABLE 0x00000001U
+
+#define MA_INT_CAUSE 0x77e0
+#define MEM_PERR_INT_CAUSE 0x00000002U
+#define MEM_WRAP_INT_CAUSE 0x00000001U
+
+#define MA_INT_WRAP_STATUS 0x77e4
+#define MEM_WRAP_ADDRESS_MASK 0xfffffff0U
+#define MEM_WRAP_ADDRESS_SHIFT 4
+#define MEM_WRAP_ADDRESS_GET(x) (((x) & MEM_WRAP_ADDRESS_MASK) >> MEM_WRAP_ADDRESS_SHIFT)
+#define MEM_WRAP_CLIENT_NUM_MASK 0x0000000fU
+#define MEM_WRAP_CLIENT_NUM_SHIFT 0
+#define MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT)
+
+#define MA_PARITY_ERROR_STATUS 0x77f4
+
+#define EDC_0_BASE_ADDR 0x7900
+
+#define EDC_BIST_CMD 0x7904
+#define EDC_BIST_CMD_ADDR 0x7908
+#define EDC_BIST_CMD_LEN 0x790c
+#define EDC_BIST_DATA_PATTERN 0x7910
+#define EDC_BIST_STATUS_RDATA 0x7928
+#define EDC_INT_CAUSE 0x7978
+#define ECC_UE_PAR 0x00000020U
+#define ECC_CE_PAR 0x00000010U
+#define PERR_PAR_CAUSE 0x00000008U
+
+#define EDC_ECC_STATUS 0x797c
+
+#define EDC_1_BASE_ADDR 0x7980
+
+#define CIM_PF_MAILBOX_DATA 0x240
+#define CIM_PF_MAILBOX_CTRL 0x280
+#define MBMSGVALID 0x00000008U
+#define MBINTREQ 0x00000004U
+#define MBOWNER_MASK 0x00000003U
+#define MBOWNER_SHIFT 0
+#define MBOWNER(x) ((x) << MBOWNER_SHIFT)
+#define MBOWNER_GET(x) (((x) & MBOWNER_MASK) >> MBOWNER_SHIFT)
+
+#define CIM_PF_HOST_INT_CAUSE 0x28c
+#define MBMSGRDYINT 0x00080000U
+
+#define CIM_HOST_INT_CAUSE 0x7b2c
+#define TIEQOUTPARERRINT 0x00100000U
+#define TIEQINPARERRINT 0x00080000U
+#define MBHOSTPARERR 0x00040000U
+#define MBUPPARERR 0x00020000U
+#define IBQPARERR 0x0001f800U
+#define IBQTP0PARERR 0x00010000U
+#define IBQTP1PARERR 0x00008000U
+#define IBQULPPARERR 0x00004000U
+#define IBQSGELOPARERR 0x00002000U
+#define IBQSGEHIPARERR 0x00001000U
+#define IBQNCSIPARERR 0x00000800U
+#define OBQPARERR 0x000007e0U
+#define OBQULP0PARERR 0x00000400U
+#define OBQULP1PARERR 0x00000200U
+#define OBQULP2PARERR 0x00000100U
+#define OBQULP3PARERR 0x00000080U
+#define OBQSGEPARERR 0x00000040U
+#define OBQNCSIPARERR 0x00000020U
+#define PREFDROPINT 0x00000002U
+#define UPACCNONZERO 0x00000001U
+
+#define CIM_HOST_UPACC_INT_CAUSE 0x7b34
+#define EEPROMWRINT 0x40000000U
+#define TIMEOUTMAINT 0x20000000U
+#define TIMEOUTINT 0x10000000U
+#define RSPOVRLOOKUPINT 0x08000000U
+#define REQOVRLOOKUPINT 0x04000000U
+#define BLKWRPLINT 0x02000000U
+#define BLKRDPLINT 0x01000000U
+#define SGLWRPLINT 0x00800000U
+#define SGLRDPLINT 0x00400000U
+#define BLKWRCTLINT 0x00200000U
+#define BLKRDCTLINT 0x00100000U
+#define SGLWRCTLINT 0x00080000U
+#define SGLRDCTLINT 0x00040000U
+#define BLKWREEPROMINT 0x00020000U
+#define BLKRDEEPROMINT 0x00010000U
+#define SGLWREEPROMINT 0x00008000U
+#define SGLRDEEPROMINT 0x00004000U
+#define BLKWRFLASHINT 0x00002000U
+#define BLKRDFLASHINT 0x00001000U
+#define SGLWRFLASHINT 0x00000800U
+#define SGLRDFLASHINT 0x00000400U
+#define BLKWRBOOTINT 0x00000200U
+#define BLKRDBOOTINT 0x00000100U
+#define SGLWRBOOTINT 0x00000080U
+#define SGLRDBOOTINT 0x00000040U
+#define ILLWRBEINT 0x00000020U
+#define ILLRDBEINT 0x00000010U
+#define ILLRDINT 0x00000008U
+#define ILLWRINT 0x00000004U
+#define ILLTRANSINT 0x00000002U
+#define RSVDSPACEINT 0x00000001U
+
+#define TP_OUT_CONFIG 0x7d04
+#define VLANEXTENABLE_MASK 0x0000f000U
+#define VLANEXTENABLE_SHIFT 12
+
+#define TP_PARA_REG2 0x7d68
+#define MAXRXDATA_MASK 0xffff0000U
+#define MAXRXDATA_SHIFT 16
+#define MAXRXDATA_GET(x) (((x) & MAXRXDATA_MASK) >> MAXRXDATA_SHIFT)
+
+#define TP_TIMER_RESOLUTION 0x7d90
+#define TIMERRESOLUTION_MASK 0x00ff0000U
+#define TIMERRESOLUTION_SHIFT 16
+#define TIMERRESOLUTION_GET(x) (((x) & TIMERRESOLUTION_MASK) >> TIMERRESOLUTION_SHIFT)
+
+#define TP_SHIFT_CNT 0x7dc0
+
+#define TP_CCTRL_TABLE 0x7ddc
+#define TP_MTU_TABLE 0x7de4
+#define MTUINDEX_MASK 0xff000000U
+#define MTUINDEX_SHIFT 24
+#define MTUINDEX(x) ((x) << MTUINDEX_SHIFT)
+#define MTUWIDTH_MASK 0x000f0000U
+#define MTUWIDTH_SHIFT 16
+#define MTUWIDTH(x) ((x) << MTUWIDTH_SHIFT)
+#define MTUWIDTH_GET(x) (((x) & MTUWIDTH_MASK) >> MTUWIDTH_SHIFT)
+#define MTUVALUE_MASK 0x00003fffU
+#define MTUVALUE_SHIFT 0
+#define MTUVALUE(x) ((x) << MTUVALUE_SHIFT)
+#define MTUVALUE_GET(x) (((x) & MTUVALUE_MASK) >> MTUVALUE_SHIFT)
+
+#define TP_RSS_LKP_TABLE 0x7dec
+#define LKPTBLROWVLD 0x80000000U
+#define LKPTBLQUEUE1_MASK 0x000ffc00U
+#define LKPTBLQUEUE1_SHIFT 10
+#define LKPTBLQUEUE1(x) ((x) << LKPTBLQUEUE1_SHIFT)
+#define LKPTBLQUEUE1_GET(x) (((x) & LKPTBLQUEUE1_MASK) >> LKPTBLQUEUE1_SHIFT)
+#define LKPTBLQUEUE0_MASK 0x000003ffU
+#define LKPTBLQUEUE0_SHIFT 0
+#define LKPTBLQUEUE0(x) ((x) << LKPTBLQUEUE0_SHIFT)
+#define LKPTBLQUEUE0_GET(x) (((x) & LKPTBLQUEUE0_MASK) >> LKPTBLQUEUE0_SHIFT)
+
+#define TP_PIO_ADDR 0x7e40
+#define TP_PIO_DATA 0x7e44
+#define TP_MIB_INDEX 0x7e50
+#define TP_MIB_DATA 0x7e54
+#define TP_INT_CAUSE 0x7e74
+#define FLMTXFLSTEMPTY 0x40000000U
+
+#define TP_INGRESS_CONFIG 0x141
+#define VNIC 0x00000800U
+#define CSUM_HAS_PSEUDO_HDR 0x00000400U
+#define RM_OVLAN 0x00000200U
+#define LOOKUPEVERYPKT 0x00000100U
+
+#define TP_MIB_MAC_IN_ERR_0 0x0
+#define TP_MIB_TCP_OUT_RST 0xc
+#define TP_MIB_TCP_IN_SEG_HI 0x10
+#define TP_MIB_TCP_IN_SEG_LO 0x11
+#define TP_MIB_TCP_OUT_SEG_HI 0x12
+#define TP_MIB_TCP_OUT_SEG_LO 0x13
+#define TP_MIB_TCP_RXT_SEG_HI 0x14
+#define TP_MIB_TCP_RXT_SEG_LO 0x15
+#define TP_MIB_TNL_CNG_DROP_0 0x18
+#define TP_MIB_TCP_V6IN_ERR_0 0x28
+#define TP_MIB_TCP_V6OUT_RST 0x2c
+#define TP_MIB_OFD_ARP_DROP 0x36
+#define TP_MIB_TNL_DROP_0 0x44
+#define TP_MIB_OFD_VLN_DROP_0 0x58
+
+#define ULP_TX_INT_CAUSE 0x8dcc
+#define PBL_BOUND_ERR_CH3 0x80000000U
+#define PBL_BOUND_ERR_CH2 0x40000000U
+#define PBL_BOUND_ERR_CH1 0x20000000U
+#define PBL_BOUND_ERR_CH0 0x10000000U
+
+#define PM_RX_INT_CAUSE 0x8fdc
+#define ZERO_E_CMD_ERROR 0x00400000U
+#define PMRX_FRAMING_ERROR 0x003ffff0U
+#define OCSPI_PAR_ERROR 0x00000008U
+#define DB_OPTIONS_PAR_ERROR 0x00000004U
+#define IESPI_PAR_ERROR 0x00000002U
+#define E_PCMD_PAR_ERROR 0x00000001U
+
+#define PM_TX_INT_CAUSE 0x8ffc
+#define PCMD_LEN_OVFL0 0x80000000U
+#define PCMD_LEN_OVFL1 0x40000000U
+#define PCMD_LEN_OVFL2 0x20000000U
+#define ZERO_C_CMD_ERROR 0x10000000U
+#define PMTX_FRAMING_ERROR 0x0ffffff0U
+#define OESPI_PAR_ERROR 0x00000008U
+#define ICSPI_PAR_ERROR 0x00000002U
+#define C_PCMD_PAR_ERROR 0x00000001U
+
+#define MPS_PORT_STAT_TX_PORT_BYTES_L 0x400
+#define MPS_PORT_STAT_TX_PORT_BYTES_H 0x404
+#define MPS_PORT_STAT_TX_PORT_FRAMES_L 0x408
+#define MPS_PORT_STAT_TX_PORT_FRAMES_H 0x40c
+#define MPS_PORT_STAT_TX_PORT_BCAST_L 0x410
+#define MPS_PORT_STAT_TX_PORT_BCAST_H 0x414
+#define MPS_PORT_STAT_TX_PORT_MCAST_L 0x418
+#define MPS_PORT_STAT_TX_PORT_MCAST_H 0x41c
+#define MPS_PORT_STAT_TX_PORT_UCAST_L 0x420
+#define MPS_PORT_STAT_TX_PORT_UCAST_H 0x424
+#define MPS_PORT_STAT_TX_PORT_ERROR_L 0x428
+#define MPS_PORT_STAT_TX_PORT_ERROR_H 0x42c
+#define MPS_PORT_STAT_TX_PORT_64B_L 0x430
+#define MPS_PORT_STAT_TX_PORT_64B_H 0x434
+#define MPS_PORT_STAT_TX_PORT_65B_127B_L 0x438
+#define MPS_PORT_STAT_TX_PORT_65B_127B_H 0x43c
+#define MPS_PORT_STAT_TX_PORT_128B_255B_L 0x440
+#define MPS_PORT_STAT_TX_PORT_128B_255B_H 0x444
+#define MPS_PORT_STAT_TX_PORT_256B_511B_L 0x448
+#define MPS_PORT_STAT_TX_PORT_256B_511B_H 0x44c
+#define MPS_PORT_STAT_TX_PORT_512B_1023B_L 0x450
+#define MPS_PORT_STAT_TX_PORT_512B_1023B_H 0x454
+#define MPS_PORT_STAT_TX_PORT_1024B_1518B_L 0x458
+#define MPS_PORT_STAT_TX_PORT_1024B_1518B_H 0x45c
+#define MPS_PORT_STAT_TX_PORT_1519B_MAX_L 0x460
+#define MPS_PORT_STAT_TX_PORT_1519B_MAX_H 0x464
+#define MPS_PORT_STAT_TX_PORT_DROP_L 0x468
+#define MPS_PORT_STAT_TX_PORT_DROP_H 0x46c
+#define MPS_PORT_STAT_TX_PORT_PAUSE_L 0x470
+#define MPS_PORT_STAT_TX_PORT_PAUSE_H 0x474
+#define MPS_PORT_STAT_TX_PORT_PPP0_L 0x478
+#define MPS_PORT_STAT_TX_PORT_PPP0_H 0x47c
+#define MPS_PORT_STAT_TX_PORT_PPP1_L 0x480
+#define MPS_PORT_STAT_TX_PORT_PPP1_H 0x484
+#define MPS_PORT_STAT_TX_PORT_PPP2_L 0x488
+#define MPS_PORT_STAT_TX_PORT_PPP2_H 0x48c
+#define MPS_PORT_STAT_TX_PORT_PPP3_L 0x490
+#define MPS_PORT_STAT_TX_PORT_PPP3_H 0x494
+#define MPS_PORT_STAT_TX_PORT_PPP4_L 0x498
+#define MPS_PORT_STAT_TX_PORT_PPP4_H 0x49c
+#define MPS_PORT_STAT_TX_PORT_PPP5_L 0x4a0
+#define MPS_PORT_STAT_TX_PORT_PPP5_H 0x4a4
+#define MPS_PORT_STAT_TX_PORT_PPP6_L 0x4a8
+#define MPS_PORT_STAT_TX_PORT_PPP6_H 0x4ac
+#define MPS_PORT_STAT_TX_PORT_PPP7_L 0x4b0
+#define MPS_PORT_STAT_TX_PORT_PPP7_H 0x4b4
+#define MPS_PORT_STAT_LB_PORT_BYTES_L 0x4c0
+#define MPS_PORT_STAT_LB_PORT_BYTES_H 0x4c4
+#define MPS_PORT_STAT_LB_PORT_FRAMES_L 0x4c8
+#define MPS_PORT_STAT_LB_PORT_FRAMES_H 0x4cc
+#define MPS_PORT_STAT_LB_PORT_BCAST_L 0x4d0
+#define MPS_PORT_STAT_LB_PORT_BCAST_H 0x4d4
+#define MPS_PORT_STAT_LB_PORT_MCAST_L 0x4d8
+#define MPS_PORT_STAT_LB_PORT_MCAST_H 0x4dc
+#define MPS_PORT_STAT_LB_PORT_UCAST_L 0x4e0
+#define MPS_PORT_STAT_LB_PORT_UCAST_H 0x4e4
+#define MPS_PORT_STAT_LB_PORT_ERROR_L 0x4e8
+#define MPS_PORT_STAT_LB_PORT_ERROR_H 0x4ec
+#define MPS_PORT_STAT_LB_PORT_64B_L 0x4f0
+#define MPS_PORT_STAT_LB_PORT_64B_H 0x4f4
+#define MPS_PORT_STAT_LB_PORT_65B_127B_L 0x4f8
+#define MPS_PORT_STAT_LB_PORT_65B_127B_H 0x4fc
+#define MPS_PORT_STAT_LB_PORT_128B_255B_L 0x500
+#define MPS_PORT_STAT_LB_PORT_128B_255B_H 0x504
+#define MPS_PORT_STAT_LB_PORT_256B_511B_L 0x508
+#define MPS_PORT_STAT_LB_PORT_256B_511B_H 0x50c
+#define MPS_PORT_STAT_LB_PORT_512B_1023B_L 0x510
+#define MPS_PORT_STAT_LB_PORT_512B_1023B_H 0x514
+#define MPS_PORT_STAT_LB_PORT_1024B_1518B_L 0x518
+#define MPS_PORT_STAT_LB_PORT_1024B_1518B_H 0x51c
+#define MPS_PORT_STAT_LB_PORT_1519B_MAX_L 0x520
+#define MPS_PORT_STAT_LB_PORT_1519B_MAX_H 0x524
+#define MPS_PORT_STAT_LB_PORT_DROP_FRAMES 0x528
+#define MPS_PORT_STAT_RX_PORT_BYTES_L 0x540
+#define MPS_PORT_STAT_RX_PORT_BYTES_H 0x544
+#define MPS_PORT_STAT_RX_PORT_FRAMES_L 0x548
+#define MPS_PORT_STAT_RX_PORT_FRAMES_H 0x54c
+#define MPS_PORT_STAT_RX_PORT_BCAST_L 0x550
+#define MPS_PORT_STAT_RX_PORT_BCAST_H 0x554
+#define MPS_PORT_STAT_RX_PORT_MCAST_L 0x558
+#define MPS_PORT_STAT_RX_PORT_MCAST_H 0x55c
+#define MPS_PORT_STAT_RX_PORT_UCAST_L 0x560
+#define MPS_PORT_STAT_RX_PORT_UCAST_H 0x564
+#define MPS_PORT_STAT_RX_PORT_MTU_ERROR_L 0x568
+#define MPS_PORT_STAT_RX_PORT_MTU_ERROR_H 0x56c
+#define MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_L 0x570
+#define MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_H 0x574
+#define MPS_PORT_STAT_RX_PORT_CRC_ERROR_L 0x578
+#define MPS_PORT_STAT_RX_PORT_CRC_ERROR_H 0x57c
+#define MPS_PORT_STAT_RX_PORT_LEN_ERROR_L 0x580
+#define MPS_PORT_STAT_RX_PORT_LEN_ERROR_H 0x584
+#define MPS_PORT_STAT_RX_PORT_SYM_ERROR_L 0x588
+#define MPS_PORT_STAT_RX_PORT_SYM_ERROR_H 0x58c
+#define MPS_PORT_STAT_RX_PORT_64B_L 0x590
+#define MPS_PORT_STAT_RX_PORT_64B_H 0x594
+#define MPS_PORT_STAT_RX_PORT_65B_127B_L 0x598
+#define MPS_PORT_STAT_RX_PORT_65B_127B_H 0x59c
+#define MPS_PORT_STAT_RX_PORT_128B_255B_L 0x5a0
+#define MPS_PORT_STAT_RX_PORT_128B_255B_H 0x5a4
+#define MPS_PORT_STAT_RX_PORT_256B_511B_L 0x5a8
+#define MPS_PORT_STAT_RX_PORT_256B_511B_H 0x5ac
+#define MPS_PORT_STAT_RX_PORT_512B_1023B_L 0x5b0
+#define MPS_PORT_STAT_RX_PORT_512B_1023B_H 0x5b4
+#define MPS_PORT_STAT_RX_PORT_1024B_1518B_L 0x5b8
+#define MPS_PORT_STAT_RX_PORT_1024B_1518B_H 0x5bc
+#define MPS_PORT_STAT_RX_PORT_1519B_MAX_L 0x5c0
+#define MPS_PORT_STAT_RX_PORT_1519B_MAX_H 0x5c4
+#define MPS_PORT_STAT_RX_PORT_PAUSE_L 0x5c8
+#define MPS_PORT_STAT_RX_PORT_PAUSE_H 0x5cc
+#define MPS_PORT_STAT_RX_PORT_PPP0_L 0x5d0
+#define MPS_PORT_STAT_RX_PORT_PPP0_H 0x5d4
+#define MPS_PORT_STAT_RX_PORT_PPP1_L 0x5d8
+#define MPS_PORT_STAT_RX_PORT_PPP1_H 0x5dc
+#define MPS_PORT_STAT_RX_PORT_PPP2_L 0x5e0
+#define MPS_PORT_STAT_RX_PORT_PPP2_H 0x5e4
+#define MPS_PORT_STAT_RX_PORT_PPP3_L 0x5e8
+#define MPS_PORT_STAT_RX_PORT_PPP3_H 0x5ec
+#define MPS_PORT_STAT_RX_PORT_PPP4_L 0x5f0
+#define MPS_PORT_STAT_RX_PORT_PPP4_H 0x5f4
+#define MPS_PORT_STAT_RX_PORT_PPP5_L 0x5f8
+#define MPS_PORT_STAT_RX_PORT_PPP5_H 0x5fc
+#define MPS_PORT_STAT_RX_PORT_PPP6_L 0x600
+#define MPS_PORT_STAT_RX_PORT_PPP6_H 0x604
+#define MPS_PORT_STAT_RX_PORT_PPP7_L 0x608
+#define MPS_PORT_STAT_RX_PORT_PPP7_H 0x60c
+#define MPS_PORT_STAT_RX_PORT_LESS_64B_L 0x610
+#define MPS_PORT_STAT_RX_PORT_LESS_64B_H 0x614
+#define MPS_CMN_CTL 0x9000
+#define NUMPORTS_MASK 0x00000003U
+#define NUMPORTS_SHIFT 0
+#define NUMPORTS_GET(x) (((x) & NUMPORTS_MASK) >> NUMPORTS_SHIFT)
+
+#define MPS_INT_CAUSE 0x9008
+#define STATINT 0x00000020U
+#define TXINT 0x00000010U
+#define RXINT 0x00000008U
+#define TRCINT 0x00000004U
+#define CLSINT 0x00000002U
+#define PLINT 0x00000001U
+
+#define MPS_TX_INT_CAUSE 0x9408
+#define PORTERR 0x00010000U
+#define FRMERR 0x00008000U
+#define SECNTERR 0x00004000U
+#define BUBBLE 0x00002000U
+#define TXDESCFIFO 0x00001e00U
+#define TXDATAFIFO 0x000001e0U
+#define NCSIFIFO 0x00000010U
+#define TPFIFO 0x0000000fU
+
+#define MPS_STAT_PERR_INT_CAUSE_SRAM 0x9614
+#define MPS_STAT_PERR_INT_CAUSE_TX_FIFO 0x9620
+#define MPS_STAT_PERR_INT_CAUSE_RX_FIFO 0x962c
+
+#define MPS_STAT_RX_BG_0_MAC_DROP_FRAME_L 0x9640
+#define MPS_STAT_RX_BG_0_MAC_DROP_FRAME_H 0x9644
+#define MPS_STAT_RX_BG_1_MAC_DROP_FRAME_L 0x9648
+#define MPS_STAT_RX_BG_1_MAC_DROP_FRAME_H 0x964c
+#define MPS_STAT_RX_BG_2_MAC_DROP_FRAME_L 0x9650
+#define MPS_STAT_RX_BG_2_MAC_DROP_FRAME_H 0x9654
+#define MPS_STAT_RX_BG_3_MAC_DROP_FRAME_L 0x9658
+#define MPS_STAT_RX_BG_3_MAC_DROP_FRAME_H 0x965c
+#define MPS_STAT_RX_BG_0_LB_DROP_FRAME_L 0x9660
+#define MPS_STAT_RX_BG_0_LB_DROP_FRAME_H 0x9664
+#define MPS_STAT_RX_BG_1_LB_DROP_FRAME_L 0x9668
+#define MPS_STAT_RX_BG_1_LB_DROP_FRAME_H 0x966c
+#define MPS_STAT_RX_BG_2_LB_DROP_FRAME_L 0x9670
+#define MPS_STAT_RX_BG_2_LB_DROP_FRAME_H 0x9674
+#define MPS_STAT_RX_BG_3_LB_DROP_FRAME_L 0x9678
+#define MPS_STAT_RX_BG_3_LB_DROP_FRAME_H 0x967c
+#define MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_L 0x9680
+#define MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_H 0x9684
+#define MPS_STAT_RX_BG_1_MAC_TRUNC_FRAME_L 0x9688
+#define MPS_STAT_RX_BG_1_MAC_TRUNC_FRAME_H 0x968c
+#define MPS_STAT_RX_BG_2_MAC_TRUNC_FRAME_L 0x9690
+#define MPS_STAT_RX_BG_2_MAC_TRUNC_FRAME_H 0x9694
+#define MPS_STAT_RX_BG_3_MAC_TRUNC_FRAME_L 0x9698
+#define MPS_STAT_RX_BG_3_MAC_TRUNC_FRAME_H 0x969c
+#define MPS_STAT_RX_BG_0_LB_TRUNC_FRAME_L 0x96a0
+#define MPS_STAT_RX_BG_0_LB_TRUNC_FRAME_H 0x96a4
+#define MPS_STAT_RX_BG_1_LB_TRUNC_FRAME_L 0x96a8
+#define MPS_STAT_RX_BG_1_LB_TRUNC_FRAME_H 0x96ac
+#define MPS_STAT_RX_BG_2_LB_TRUNC_FRAME_L 0x96b0
+#define MPS_STAT_RX_BG_2_LB_TRUNC_FRAME_H 0x96b4
+#define MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_L 0x96b8
+#define MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_H 0x96bc
+#define MPS_TRC_CFG 0x9800
+#define TRCFIFOEMPTY 0x00000010U
+#define TRCIGNOREDROPINPUT 0x00000008U
+#define TRCKEEPDUPLICATES 0x00000004U
+#define TRCEN 0x00000002U
+#define TRCMULTIFILTER 0x00000001U
+
+#define MPS_TRC_RSS_CONTROL 0x9808
+#define RSSCONTROL_MASK 0x00ff0000U
+#define RSSCONTROL_SHIFT 16
+#define RSSCONTROL(x) ((x) << RSSCONTROL_SHIFT)
+#define QUEUENUMBER_MASK 0x0000ffffU
+#define QUEUENUMBER_SHIFT 0
+#define QUEUENUMBER(x) ((x) << QUEUENUMBER_SHIFT)
+
+#define MPS_TRC_FILTER_MATCH_CTL_A 0x9810
+#define TFINVERTMATCH 0x01000000U
+#define TFPKTTOOLARGE 0x00800000U
+#define TFEN 0x00400000U
+#define TFPORT_MASK 0x003c0000U
+#define TFPORT_SHIFT 18
+#define TFPORT(x) ((x) << TFPORT_SHIFT)
+#define TFPORT_GET(x) (((x) & TFPORT_MASK) >> TFPORT_SHIFT)
+#define TFDROP 0x00020000U
+#define TFSOPEOPERR 0x00010000U
+#define TFLENGTH_MASK 0x00001f00U
+#define TFLENGTH_SHIFT 8
+#define TFLENGTH(x) ((x) << TFLENGTH_SHIFT)
+#define TFLENGTH_GET(x) (((x) & TFLENGTH_MASK) >> TFLENGTH_SHIFT)
+#define TFOFFSET_MASK 0x0000001fU
+#define TFOFFSET_SHIFT 0
+#define TFOFFSET(x) ((x) << TFOFFSET_SHIFT)
+#define TFOFFSET_GET(x) (((x) & TFOFFSET_MASK) >> TFOFFSET_SHIFT)
+
+#define MPS_TRC_FILTER_MATCH_CTL_B 0x9820
+#define TFMINPKTSIZE_MASK 0x01ff0000U
+#define TFMINPKTSIZE_SHIFT 16
+#define TFMINPKTSIZE(x) ((x) << TFMINPKTSIZE_SHIFT)
+#define TFMINPKTSIZE_GET(x) (((x) & TFMINPKTSIZE_MASK) >> TFMINPKTSIZE_SHIFT)
+#define TFCAPTUREMAX_MASK 0x00003fffU
+#define TFCAPTUREMAX_SHIFT 0
+#define TFCAPTUREMAX(x) ((x) << TFCAPTUREMAX_SHIFT)
+#define TFCAPTUREMAX_GET(x) (((x) & TFCAPTUREMAX_MASK) >> TFCAPTUREMAX_SHIFT)
+
+#define MPS_TRC_INT_CAUSE 0x985c
+#define MISCPERR 0x00000100U
+#define PKTFIFO 0x000000f0U
+#define FILTMEM 0x0000000fU
+
+#define MPS_TRC_FILTER0_MATCH 0x9c00
+#define MPS_TRC_FILTER0_DONT_CARE 0x9c80
+#define MPS_TRC_FILTER1_MATCH 0x9d00
+#define MPS_CLS_INT_CAUSE 0xd028
+#define PLERRENB 0x00000008U
+#define HASHSRAM 0x00000004U
+#define MATCHTCAM 0x00000002U
+#define MATCHSRAM 0x00000001U
+
+#define MPS_RX_PERR_INT_CAUSE 0x11074
+
+#define CPL_INTR_CAUSE 0x19054
+#define CIM_OP_MAP_PERR 0x00000020U
+#define CIM_OVFL_ERROR 0x00000010U
+#define TP_FRAMING_ERROR 0x00000008U
+#define SGE_FRAMING_ERROR 0x00000004U
+#define CIM_FRAMING_ERROR 0x00000002U
+#define ZERO_SWITCH_ERROR 0x00000001U
+
+#define SMB_INT_CAUSE 0x19090
+#define MSTTXFIFOPARINT 0x00200000U
+#define MSTRXFIFOPARINT 0x00100000U
+#define SLVFIFOPARINT 0x00080000U
+
+#define ULP_RX_INT_CAUSE 0x19158
+#define ULP_RX_ISCSI_TAGMASK 0x19164
+#define ULP_RX_ISCSI_PSZ 0x19168
+#define HPZ3_MASK 0x0f000000U
+#define HPZ3_SHIFT 24
+#define HPZ3(x) ((x) << HPZ3_SHIFT)
+#define HPZ2_MASK 0x000f0000U
+#define HPZ2_SHIFT 16
+#define HPZ2(x) ((x) << HPZ2_SHIFT)
+#define HPZ1_MASK 0x00000f00U
+#define HPZ1_SHIFT 8
+#define HPZ1(x) ((x) << HPZ1_SHIFT)
+#define HPZ0_MASK 0x0000000fU
+#define HPZ0_SHIFT 0
+#define HPZ0(x) ((x) << HPZ0_SHIFT)
+
+#define ULP_RX_TDDP_PSZ 0x19178
+
+#define SF_DATA 0x193f8
+#define SF_OP 0x193fc
+#define BUSY 0x80000000U
+#define SF_LOCK 0x00000010U
+#define SF_CONT 0x00000008U
+#define BYTECNT_MASK 0x00000006U
+#define BYTECNT_SHIFT 1
+#define BYTECNT(x) ((x) << BYTECNT_SHIFT)
+#define OP_WR 0x00000001U
+
+#define PL_PF_INT_CAUSE 0x3c0
+#define PFSW 0x00000008U
+#define PFSGE 0x00000004U
+#define PFCIM 0x00000002U
+#define PFMPS 0x00000001U
+
+#define PL_PF_INT_ENABLE 0x3c4
+#define PL_PF_CTL 0x3c8
+#define SWINT 0x00000001U
+
+#define PL_WHOAMI 0x19400
+#define SOURCEPF_MASK 0x00000700U
+#define SOURCEPF_SHIFT 8
+#define SOURCEPF(x) ((x) << SOURCEPF_SHIFT)
+#define SOURCEPF_GET(x) (((x) & SOURCEPF_MASK) >> SOURCEPF_SHIFT)
+#define ISVF 0x00000080U
+#define VFID_MASK 0x0000007fU
+#define VFID_SHIFT 0
+#define VFID(x) ((x) << VFID_SHIFT)
+#define VFID_GET(x) (((x) & VFID_MASK) >> VFID_SHIFT)
+
+#define PL_INT_CAUSE 0x1940c
+#define ULP_TX 0x08000000U
+#define SGE 0x04000000U
+#define HMA 0x02000000U
+#define CPL_SWITCH 0x01000000U
+#define ULP_RX 0x00800000U
+#define PM_RX 0x00400000U
+#define PM_TX 0x00200000U
+#define MA 0x00100000U
+#define TP 0x00080000U
+#define LE 0x00040000U
+#define EDC1 0x00020000U
+#define EDC0 0x00010000U
+#define MC 0x00008000U
+#define PCIE 0x00004000U
+#define PMU 0x00002000U
+#define XGMAC_KR1 0x00001000U
+#define XGMAC_KR0 0x00000800U
+#define XGMAC1 0x00000400U
+#define XGMAC0 0x00000200U
+#define SMB 0x00000100U
+#define SF 0x00000080U
+#define PL 0x00000040U
+#define NCSI 0x00000020U
+#define MPS 0x00000010U
+#define MI 0x00000008U
+#define DBG 0x00000004U
+#define I2CM 0x00000002U
+#define CIM 0x00000001U
+
+#define PL_INT_MAP0 0x19414
+#define PL_RST 0x19428
+#define PIORST 0x00000002U
+#define PIORSTMODE 0x00000001U
+
+#define PL_PL_INT_CAUSE 0x19430
+#define FATALPERR 0x00000010U
+#define PERRVFID 0x00000001U
+
+#define PL_REV 0x1943c
+
+#define LE_DB_CONFIG 0x19c04
+#define HASHEN 0x00100000U
+
+#define LE_DB_SERVER_INDEX 0x19c18
+#define LE_DB_ACT_CNT_IPV4 0x19c20
+#define LE_DB_ACT_CNT_IPV6 0x19c24
+
+#define LE_DB_INT_CAUSE 0x19c3c
+#define REQQPARERR 0x00010000U
+#define UNKNOWNCMD 0x00008000U
+#define PARITYERR 0x00000040U
+#define LIPMISS 0x00000020U
+#define LIP0 0x00000010U
+
+#define LE_DB_TID_HASHBASE 0x19df8
+
+#define NCSI_INT_CAUSE 0x1a0d8
+#define CIM_DM_PRTY_ERR 0x00000100U
+#define MPS_DM_PRTY_ERR 0x00000080U
+#define TXFIFO_PRTY_ERR 0x00000002U
+#define RXFIFO_PRTY_ERR 0x00000001U
+
+#define XGMAC_PORT_CFG2 0x1018
+#define PATEN 0x00040000U
+#define MAGICEN 0x00020000U
+
+#define XGMAC_PORT_MAGIC_MACID_LO 0x1024
+#define XGMAC_PORT_MAGIC_MACID_HI 0x1028
+
+#define XGMAC_PORT_EPIO_DATA0 0x10c0
+#define XGMAC_PORT_EPIO_DATA1 0x10c4
+#define XGMAC_PORT_EPIO_DATA2 0x10c8
+#define XGMAC_PORT_EPIO_DATA3 0x10cc
+#define XGMAC_PORT_EPIO_OP 0x10d0
+#define EPIOWR 0x00000100U
+#define ADDRESS_MASK 0x000000ffU
+#define ADDRESS_SHIFT 0
+#define ADDRESS(x) ((x) << ADDRESS_SHIFT)
+
+#define XGMAC_PORT_INT_CAUSE 0x10dc
+#endif /* __T4_REGS_H */
diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h
new file mode 100644
index 00000000000..3393d05a388
--- /dev/null
+++ b/drivers/net/cxgb4/t4fw_api.h
@@ -0,0 +1,1580 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2009-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _T4FW_INTERFACE_H_
+#define _T4FW_INTERFACE_H_
+
+#define FW_T4VF_SGE_BASE_ADDR 0x0000
+#define FW_T4VF_MPS_BASE_ADDR 0x0100
+#define FW_T4VF_PL_BASE_ADDR 0x0200
+#define FW_T4VF_MBDATA_BASE_ADDR 0x0240
+#define FW_T4VF_CIM_BASE_ADDR 0x0300
+
+enum fw_wr_opcodes {
+ FW_FILTER_WR = 0x02,
+ FW_ULPTX_WR = 0x04,
+ FW_TP_WR = 0x05,
+ FW_ETH_TX_PKT_WR = 0x08,
+ FW_FLOWC_WR = 0x0a,
+ FW_OFLD_TX_DATA_WR = 0x0b,
+ FW_CMD_WR = 0x10,
+ FW_ETH_TX_PKT_VM_WR = 0x11,
+ FW_RI_RES_WR = 0x0c,
+ FW_RI_INIT_WR = 0x0d,
+ FW_RI_RDMA_WRITE_WR = 0x14,
+ FW_RI_SEND_WR = 0x15,
+ FW_RI_RDMA_READ_WR = 0x16,
+ FW_RI_RECV_WR = 0x17,
+ FW_RI_BIND_MW_WR = 0x18,
+ FW_RI_FR_NSMR_WR = 0x19,
+ FW_RI_INV_LSTAG_WR = 0x1a,
+ FW_LASTC2E_WR = 0x40
+};
+
+struct fw_wr_hdr {
+ __be32 hi;
+ __be32 lo;
+};
+
+#define FW_WR_OP(x) ((x) << 24)
+#define FW_WR_ATOMIC(x) ((x) << 23)
+#define FW_WR_FLUSH(x) ((x) << 22)
+#define FW_WR_COMPL(x) ((x) << 21)
+#define FW_WR_IMMDLEN(x) ((x) << 0)
+
+#define FW_WR_EQUIQ (1U << 31)
+#define FW_WR_EQUEQ (1U << 30)
+#define FW_WR_FLOWID(x) ((x) << 8)
+#define FW_WR_LEN16(x) ((x) << 0)
+
+struct fw_ulptx_wr {
+ __be32 op_to_compl;
+ __be32 flowid_len16;
+ u64 cookie;
+};
+
+struct fw_tp_wr {
+ __be32 op_to_immdlen;
+ __be32 flowid_len16;
+ u64 cookie;
+};
+
+struct fw_eth_tx_pkt_wr {
+ __be32 op_immdlen;
+ __be32 equiq_to_len16;
+ __be64 r3;
+};
+
+enum fw_flowc_mnem {
+ FW_FLOWC_MNEM_PFNVFN, /* PFN [15:8] VFN [7:0] */
+ FW_FLOWC_MNEM_CH,
+ FW_FLOWC_MNEM_PORT,
+ FW_FLOWC_MNEM_IQID,
+ FW_FLOWC_MNEM_SNDNXT,
+ FW_FLOWC_MNEM_RCVNXT,
+ FW_FLOWC_MNEM_SNDBUF,
+ FW_FLOWC_MNEM_MSS,
+};
+
+struct fw_flowc_mnemval {
+ u8 mnemonic;
+ u8 r4[3];
+ __be32 val;
+};
+
+struct fw_flowc_wr {
+ __be32 op_to_nparams;
+#define FW_FLOWC_WR_NPARAMS(x) ((x) << 0)
+ __be32 flowid_len16;
+ struct fw_flowc_mnemval mnemval[0];
+};
+
+struct fw_ofld_tx_data_wr {
+ __be32 op_to_immdlen;
+ __be32 flowid_len16;
+ __be32 plen;
+ __be32 tunnel_to_proxy;
+#define FW_OFLD_TX_DATA_WR_TUNNEL(x) ((x) << 19)
+#define FW_OFLD_TX_DATA_WR_SAVE(x) ((x) << 18)
+#define FW_OFLD_TX_DATA_WR_FLUSH(x) ((x) << 17)
+#define FW_OFLD_TX_DATA_WR_URGENT(x) ((x) << 16)
+#define FW_OFLD_TX_DATA_WR_MORE(x) ((x) << 15)
+#define FW_OFLD_TX_DATA_WR_SHOVE(x) ((x) << 14)
+#define FW_OFLD_TX_DATA_WR_ULPMODE(x) ((x) << 10)
+#define FW_OFLD_TX_DATA_WR_ULPSUBMODE(x) ((x) << 6)
+};
+
+struct fw_cmd_wr {
+ __be32 op_dma;
+#define FW_CMD_WR_DMA (1U << 17)
+ __be32 len16_pkd;
+ __be64 cookie_daddr;
+};
+
+struct fw_eth_tx_pkt_vm_wr {
+ __be32 op_immdlen;
+ __be32 equiq_to_len16;
+ __be32 r3[2];
+ u8 ethmacdst[6];
+ u8 ethmacsrc[6];
+ __be16 ethtype;
+ __be16 vlantci;
+};
+
+#define FW_CMD_MAX_TIMEOUT 3000
+
+enum fw_cmd_opcodes {
+ FW_LDST_CMD = 0x01,
+ FW_RESET_CMD = 0x03,
+ FW_HELLO_CMD = 0x04,
+ FW_BYE_CMD = 0x05,
+ FW_INITIALIZE_CMD = 0x06,
+ FW_CAPS_CONFIG_CMD = 0x07,
+ FW_PARAMS_CMD = 0x08,
+ FW_PFVF_CMD = 0x09,
+ FW_IQ_CMD = 0x10,
+ FW_EQ_MNGT_CMD = 0x11,
+ FW_EQ_ETH_CMD = 0x12,
+ FW_EQ_CTRL_CMD = 0x13,
+ FW_EQ_OFLD_CMD = 0x21,
+ FW_VI_CMD = 0x14,
+ FW_VI_MAC_CMD = 0x15,
+ FW_VI_RXMODE_CMD = 0x16,
+ FW_VI_ENABLE_CMD = 0x17,
+ FW_ACL_MAC_CMD = 0x18,
+ FW_ACL_VLAN_CMD = 0x19,
+ FW_VI_STATS_CMD = 0x1a,
+ FW_PORT_CMD = 0x1b,
+ FW_PORT_STATS_CMD = 0x1c,
+ FW_PORT_LB_STATS_CMD = 0x1d,
+ FW_PORT_TRACE_CMD = 0x1e,
+ FW_PORT_TRACE_MMAP_CMD = 0x1f,
+ FW_RSS_IND_TBL_CMD = 0x20,
+ FW_RSS_GLB_CONFIG_CMD = 0x22,
+ FW_RSS_VI_CONFIG_CMD = 0x23,
+ FW_LASTC2E_CMD = 0x40,
+ FW_ERROR_CMD = 0x80,
+ FW_DEBUG_CMD = 0x81,
+};
+
+enum fw_cmd_cap {
+ FW_CMD_CAP_PF = 0x01,
+ FW_CMD_CAP_DMAQ = 0x02,
+ FW_CMD_CAP_PORT = 0x04,
+ FW_CMD_CAP_PORTPROMISC = 0x08,
+ FW_CMD_CAP_PORTSTATS = 0x10,
+ FW_CMD_CAP_VF = 0x80,
+};
+
+/*
+ * Generic command header flit0
+ */
+struct fw_cmd_hdr {
+ __be32 hi;
+ __be32 lo;
+};
+
+#define FW_CMD_OP(x) ((x) << 24)
+#define FW_CMD_OP_GET(x) (((x) >> 24) & 0xff)
+#define FW_CMD_REQUEST (1U << 23)
+#define FW_CMD_READ (1U << 22)
+#define FW_CMD_WRITE (1U << 21)
+#define FW_CMD_EXEC (1U << 20)
+#define FW_CMD_RAMASK(x) ((x) << 20)
+#define FW_CMD_RETVAL(x) ((x) << 8)
+#define FW_CMD_RETVAL_GET(x) (((x) >> 8) & 0xff)
+#define FW_CMD_LEN16(x) ((x) << 0)
+
+enum fw_ldst_addrspc {
+ FW_LDST_ADDRSPC_FIRMWARE = 0x0001,
+ FW_LDST_ADDRSPC_SGE_EGRC = 0x0008,
+ FW_LDST_ADDRSPC_SGE_INGC = 0x0009,
+ FW_LDST_ADDRSPC_SGE_FLMC = 0x000a,
+ FW_LDST_ADDRSPC_SGE_CONMC = 0x000b,
+ FW_LDST_ADDRSPC_TP_PIO = 0x0010,
+ FW_LDST_ADDRSPC_TP_TM_PIO = 0x0011,
+ FW_LDST_ADDRSPC_TP_MIB = 0x0012,
+ FW_LDST_ADDRSPC_MDIO = 0x0018,
+ FW_LDST_ADDRSPC_MPS = 0x0020,
+ FW_LDST_ADDRSPC_FUNC = 0x0028
+};
+
+enum fw_ldst_mps_fid {
+ FW_LDST_MPS_ATRB,
+ FW_LDST_MPS_RPLC
+};
+
+enum fw_ldst_func_access_ctl {
+ FW_LDST_FUNC_ACC_CTL_VIID,
+ FW_LDST_FUNC_ACC_CTL_FID
+};
+
+enum fw_ldst_func_mod_index {
+ FW_LDST_FUNC_MPS
+};
+
+struct fw_ldst_cmd {
+ __be32 op_to_addrspace;
+#define FW_LDST_CMD_ADDRSPACE(x) ((x) << 0)
+ __be32 cycles_to_len16;
+ union fw_ldst {
+ struct fw_ldst_addrval {
+ __be32 addr;
+ __be32 val;
+ } addrval;
+ struct fw_ldst_idctxt {
+ __be32 physid;
+ __be32 msg_pkd;
+ __be32 ctxt_data7;
+ __be32 ctxt_data6;
+ __be32 ctxt_data5;
+ __be32 ctxt_data4;
+ __be32 ctxt_data3;
+ __be32 ctxt_data2;
+ __be32 ctxt_data1;
+ __be32 ctxt_data0;
+ } idctxt;
+ struct fw_ldst_mdio {
+ __be16 paddr_mmd;
+ __be16 raddr;
+ __be16 vctl;
+ __be16 rval;
+ } mdio;
+ struct fw_ldst_mps {
+ __be16 fid_ctl;
+ __be16 rplcpf_pkd;
+ __be32 rplc127_96;
+ __be32 rplc95_64;
+ __be32 rplc63_32;
+ __be32 rplc31_0;
+ __be32 atrb;
+ __be16 vlan[16];
+ } mps;
+ struct fw_ldst_func {
+ u8 access_ctl;
+ u8 mod_index;
+ __be16 ctl_id;
+ __be32 offset;
+ __be64 data0;
+ __be64 data1;
+ } func;
+ } u;
+};
+
+#define FW_LDST_CMD_MSG(x) ((x) << 31)
+#define FW_LDST_CMD_PADDR(x) ((x) << 8)
+#define FW_LDST_CMD_MMD(x) ((x) << 0)
+#define FW_LDST_CMD_FID(x) ((x) << 15)
+#define FW_LDST_CMD_CTL(x) ((x) << 0)
+#define FW_LDST_CMD_RPLCPF(x) ((x) << 0)
+
+struct fw_reset_cmd {
+ __be32 op_to_write;
+ __be32 retval_len16;
+ __be32 val;
+ __be32 r3;
+};
+
+struct fw_hello_cmd {
+ __be32 op_to_write;
+ __be32 retval_len16;
+ __be32 err_to_mbasyncnot;
+#define FW_HELLO_CMD_ERR (1U << 31)
+#define FW_HELLO_CMD_INIT (1U << 30)
+#define FW_HELLO_CMD_MASTERDIS(x) ((x) << 29)
+#define FW_HELLO_CMD_MASTERFORCE(x) ((x) << 28)
+#define FW_HELLO_CMD_MBMASTER(x) ((x) << 24)
+#define FW_HELLO_CMD_MBASYNCNOT(x) ((x) << 20)
+ __be32 fwrev;
+};
+
+struct fw_bye_cmd {
+ __be32 op_to_write;
+ __be32 retval_len16;
+ __be64 r3;
+};
+
+struct fw_initialize_cmd {
+ __be32 op_to_write;
+ __be32 retval_len16;
+ __be64 r3;
+};
+
+enum fw_caps_config_hm {
+ FW_CAPS_CONFIG_HM_PCIE = 0x00000001,
+ FW_CAPS_CONFIG_HM_PL = 0x00000002,
+ FW_CAPS_CONFIG_HM_SGE = 0x00000004,
+ FW_CAPS_CONFIG_HM_CIM = 0x00000008,
+ FW_CAPS_CONFIG_HM_ULPTX = 0x00000010,
+ FW_CAPS_CONFIG_HM_TP = 0x00000020,
+ FW_CAPS_CONFIG_HM_ULPRX = 0x00000040,
+ FW_CAPS_CONFIG_HM_PMRX = 0x00000080,
+ FW_CAPS_CONFIG_HM_PMTX = 0x00000100,
+ FW_CAPS_CONFIG_HM_MC = 0x00000200,
+ FW_CAPS_CONFIG_HM_LE = 0x00000400,
+ FW_CAPS_CONFIG_HM_MPS = 0x00000800,
+ FW_CAPS_CONFIG_HM_XGMAC = 0x00001000,
+ FW_CAPS_CONFIG_HM_CPLSWITCH = 0x00002000,
+ FW_CAPS_CONFIG_HM_T4DBG = 0x00004000,
+ FW_CAPS_CONFIG_HM_MI = 0x00008000,
+ FW_CAPS_CONFIG_HM_I2CM = 0x00010000,
+ FW_CAPS_CONFIG_HM_NCSI = 0x00020000,
+ FW_CAPS_CONFIG_HM_SMB = 0x00040000,
+ FW_CAPS_CONFIG_HM_MA = 0x00080000,
+ FW_CAPS_CONFIG_HM_EDRAM = 0x00100000,
+ FW_CAPS_CONFIG_HM_PMU = 0x00200000,
+ FW_CAPS_CONFIG_HM_UART = 0x00400000,
+ FW_CAPS_CONFIG_HM_SF = 0x00800000,
+};
+
+enum fw_caps_config_nbm {
+ FW_CAPS_CONFIG_NBM_IPMI = 0x00000001,
+ FW_CAPS_CONFIG_NBM_NCSI = 0x00000002,
+};
+
+enum fw_caps_config_link {
+ FW_CAPS_CONFIG_LINK_PPP = 0x00000001,
+ FW_CAPS_CONFIG_LINK_QFC = 0x00000002,
+ FW_CAPS_CONFIG_LINK_DCBX = 0x00000004,
+};
+
+enum fw_caps_config_switch {
+ FW_CAPS_CONFIG_SWITCH_INGRESS = 0x00000001,
+ FW_CAPS_CONFIG_SWITCH_EGRESS = 0x00000002,
+};
+
+enum fw_caps_config_nic {
+ FW_CAPS_CONFIG_NIC = 0x00000001,
+ FW_CAPS_CONFIG_NIC_VM = 0x00000002,
+};
+
+enum fw_caps_config_ofld {
+ FW_CAPS_CONFIG_OFLD = 0x00000001,
+};
+
+enum fw_caps_config_rdma {
+ FW_CAPS_CONFIG_RDMA_RDDP = 0x00000001,
+ FW_CAPS_CONFIG_RDMA_RDMAC = 0x00000002,
+};
+
+enum fw_caps_config_iscsi {
+ FW_CAPS_CONFIG_ISCSI_INITIATOR_PDU = 0x00000001,
+ FW_CAPS_CONFIG_ISCSI_TARGET_PDU = 0x00000002,
+ FW_CAPS_CONFIG_ISCSI_INITIATOR_CNXOFLD = 0x00000004,
+ FW_CAPS_CONFIG_ISCSI_TARGET_CNXOFLD = 0x00000008,
+};
+
+enum fw_caps_config_fcoe {
+ FW_CAPS_CONFIG_FCOE_INITIATOR = 0x00000001,
+ FW_CAPS_CONFIG_FCOE_TARGET = 0x00000002,
+};
+
+struct fw_caps_config_cmd {
+ __be32 op_to_write;
+ __be32 retval_len16;
+ __be32 r2;
+ __be32 hwmbitmap;
+ __be16 nbmcaps;
+ __be16 linkcaps;
+ __be16 switchcaps;
+ __be16 r3;
+ __be16 niccaps;
+ __be16 ofldcaps;
+ __be16 rdmacaps;
+ __be16 r4;
+ __be16 iscsicaps;
+ __be16 fcoecaps;
+ __be32 r5;
+ __be64 r6;
+};
+
+/*
+ * params command mnemonics
+ */
+enum fw_params_mnem {
+ FW_PARAMS_MNEM_DEV = 1, /* device params */
+ FW_PARAMS_MNEM_PFVF = 2, /* function params */
+ FW_PARAMS_MNEM_REG = 3, /* limited register access */
+ FW_PARAMS_MNEM_DMAQ = 4, /* dma queue params */
+ FW_PARAMS_MNEM_LAST
+};
+
+/*
+ * device parameters
+ */
+enum fw_params_param_dev {
+ FW_PARAMS_PARAM_DEV_CCLK = 0x00, /* chip core clock in khz */
+ FW_PARAMS_PARAM_DEV_PORTVEC = 0x01, /* the port vector */
+ FW_PARAMS_PARAM_DEV_NTID = 0x02, /* reads the number of TIDs
+ * allocated by the device's
+ * Lookup Engine
+ */
+ FW_PARAMS_PARAM_DEV_FLOWC_BUFFIFO_SZ = 0x03,
+ FW_PARAMS_PARAM_DEV_INTVER_NIC = 0x04,
+ FW_PARAMS_PARAM_DEV_INTVER_VNIC = 0x05,
+ FW_PARAMS_PARAM_DEV_INTVER_OFLD = 0x06,
+ FW_PARAMS_PARAM_DEV_INTVER_RI = 0x07,
+ FW_PARAMS_PARAM_DEV_INTVER_ISCSIPDU = 0x08,
+ FW_PARAMS_PARAM_DEV_INTVER_ISCSI = 0x09,
+ FW_PARAMS_PARAM_DEV_INTVER_FCOE = 0x0A
+};
+
+/*
+ * physical and virtual function parameters
+ */
+enum fw_params_param_pfvf {
+ FW_PARAMS_PARAM_PFVF_RWXCAPS = 0x00,
+ FW_PARAMS_PARAM_PFVF_ROUTE_START = 0x01,
+ FW_PARAMS_PARAM_PFVF_ROUTE_END = 0x02,
+ FW_PARAMS_PARAM_PFVF_CLIP_START = 0x03,
+ FW_PARAMS_PARAM_PFVF_CLIP_END = 0x04,
+ FW_PARAMS_PARAM_PFVF_FILTER_START = 0x05,
+ FW_PARAMS_PARAM_PFVF_FILTER_END = 0x06,
+ FW_PARAMS_PARAM_PFVF_SERVER_START = 0x07,
+ FW_PARAMS_PARAM_PFVF_SERVER_END = 0x08,
+ FW_PARAMS_PARAM_PFVF_TDDP_START = 0x09,
+ FW_PARAMS_PARAM_PFVF_TDDP_END = 0x0A,
+ FW_PARAMS_PARAM_PFVF_ISCSI_START = 0x0B,
+ FW_PARAMS_PARAM_PFVF_ISCSI_END = 0x0C,
+ FW_PARAMS_PARAM_PFVF_STAG_START = 0x0D,
+ FW_PARAMS_PARAM_PFVF_STAG_END = 0x0E,
+ FW_PARAMS_PARAM_PFVF_RQ_START = 0x1F,
+ FW_PARAMS_PARAM_PFVF_RQ_END = 0x10,
+ FW_PARAMS_PARAM_PFVF_PBL_START = 0x11,
+ FW_PARAMS_PARAM_PFVF_PBL_END = 0x12,
+ FW_PARAMS_PARAM_PFVF_L2T_START = 0x13,
+ FW_PARAMS_PARAM_PFVF_L2T_END = 0x14,
+ FW_PARAMS_PARAM_PFVF_SCHEDCLASS_ETH = 0x20,
+};
+
+/*
+ * dma queue parameters
+ */
+enum fw_params_param_dmaq {
+ FW_PARAMS_PARAM_DMAQ_IQ_DCAEN_DCACPU = 0x00,
+ FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH = 0x01,
+ FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_MNGT = 0x10,
+ FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_CTRL = 0x11,
+ FW_PARAMS_PARAM_DMAQ_EQ_SCHEDCLASS_ETH = 0x12,
+};
+
+#define FW_PARAMS_MNEM(x) ((x) << 24)
+#define FW_PARAMS_PARAM_X(x) ((x) << 16)
+#define FW_PARAMS_PARAM_Y(x) ((x) << 8)
+#define FW_PARAMS_PARAM_Z(x) ((x) << 0)
+#define FW_PARAMS_PARAM_XYZ(x) ((x) << 0)
+#define FW_PARAMS_PARAM_YZ(x) ((x) << 0)
+
+struct fw_params_cmd {
+ __be32 op_to_vfn;
+ __be32 retval_len16;
+ struct fw_params_param {
+ __be32 mnem;
+ __be32 val;
+ } param[7];
+};
+
+#define FW_PARAMS_CMD_PFN(x) ((x) << 8)
+#define FW_PARAMS_CMD_VFN(x) ((x) << 0)
+
+struct fw_pfvf_cmd {
+ __be32 op_to_vfn;
+ __be32 retval_len16;
+ __be32 niqflint_niq;
+ __be32 cmask_to_neq;
+ __be32 tc_to_nexactf;
+ __be32 r_caps_to_nethctrl;
+ __be16 nricq;
+ __be16 nriqp;
+ __be32 r4;
+};
+
+#define FW_PFVF_CMD_PFN(x) ((x) << 8)
+#define FW_PFVF_CMD_VFN(x) ((x) << 0)
+
+#define FW_PFVF_CMD_NIQFLINT(x) ((x) << 20)
+#define FW_PFVF_CMD_NIQFLINT_GET(x) (((x) >> 20) & 0xfff)
+
+#define FW_PFVF_CMD_NIQ(x) ((x) << 0)
+#define FW_PFVF_CMD_NIQ_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_PFVF_CMD_CMASK(x) ((x) << 24)
+#define FW_PFVF_CMD_CMASK_GET(x) (((x) >> 24) & 0xf)
+
+#define FW_PFVF_CMD_PMASK(x) ((x) << 20)
+#define FW_PFVF_CMD_PMASK_GET(x) (((x) >> 20) & 0xf)
+
+#define FW_PFVF_CMD_NEQ(x) ((x) << 0)
+#define FW_PFVF_CMD_NEQ_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_PFVF_CMD_TC(x) ((x) << 24)
+#define FW_PFVF_CMD_TC_GET(x) (((x) >> 24) & 0xff)
+
+#define FW_PFVF_CMD_NVI(x) ((x) << 16)
+#define FW_PFVF_CMD_NVI_GET(x) (((x) >> 16) & 0xff)
+
+#define FW_PFVF_CMD_NEXACTF(x) ((x) << 0)
+#define FW_PFVF_CMD_NEXACTF_GET(x) (((x) >> 0) & 0xffff)
+
+#define FW_PFVF_CMD_R_CAPS(x) ((x) << 24)
+#define FW_PFVF_CMD_R_CAPS_GET(x) (((x) >> 24) & 0xff)
+
+#define FW_PFVF_CMD_WX_CAPS(x) ((x) << 16)
+#define FW_PFVF_CMD_WX_CAPS_GET(x) (((x) >> 16) & 0xff)
+
+#define FW_PFVF_CMD_NETHCTRL(x) ((x) << 0)
+#define FW_PFVF_CMD_NETHCTRL_GET(x) (((x) >> 0) & 0xffff)
+
+enum fw_iq_type {
+ FW_IQ_TYPE_FL_INT_CAP,
+ FW_IQ_TYPE_NO_FL_INT_CAP
+};
+
+struct fw_iq_cmd {
+ __be32 op_to_vfn;
+ __be32 alloc_to_len16;
+ __be16 physiqid;
+ __be16 iqid;
+ __be16 fl0id;
+ __be16 fl1id;
+ __be32 type_to_iqandstindex;
+ __be16 iqdroprss_to_iqesize;
+ __be16 iqsize;
+ __be64 iqaddr;
+ __be32 iqns_to_fl0congen;
+ __be16 fl0dcaen_to_fl0cidxfthresh;
+ __be16 fl0size;
+ __be64 fl0addr;
+ __be32 fl1cngchmap_to_fl1congen;
+ __be16 fl1dcaen_to_fl1cidxfthresh;
+ __be16 fl1size;
+ __be64 fl1addr;
+};
+
+#define FW_IQ_CMD_PFN(x) ((x) << 8)
+#define FW_IQ_CMD_VFN(x) ((x) << 0)
+
+#define FW_IQ_CMD_ALLOC (1U << 31)
+#define FW_IQ_CMD_FREE (1U << 30)
+#define FW_IQ_CMD_MODIFY (1U << 29)
+#define FW_IQ_CMD_IQSTART(x) ((x) << 28)
+#define FW_IQ_CMD_IQSTOP(x) ((x) << 27)
+
+#define FW_IQ_CMD_TYPE(x) ((x) << 29)
+#define FW_IQ_CMD_IQASYNCH(x) ((x) << 28)
+#define FW_IQ_CMD_VIID(x) ((x) << 16)
+#define FW_IQ_CMD_IQANDST(x) ((x) << 15)
+#define FW_IQ_CMD_IQANUS(x) ((x) << 14)
+#define FW_IQ_CMD_IQANUD(x) ((x) << 12)
+#define FW_IQ_CMD_IQANDSTINDEX(x) ((x) << 0)
+
+#define FW_IQ_CMD_IQDROPRSS (1U << 15)
+#define FW_IQ_CMD_IQGTSMODE (1U << 14)
+#define FW_IQ_CMD_IQPCIECH(x) ((x) << 12)
+#define FW_IQ_CMD_IQDCAEN(x) ((x) << 11)
+#define FW_IQ_CMD_IQDCACPU(x) ((x) << 6)
+#define FW_IQ_CMD_IQINTCNTTHRESH(x) ((x) << 4)
+#define FW_IQ_CMD_IQO (1U << 3)
+#define FW_IQ_CMD_IQCPRIO(x) ((x) << 2)
+#define FW_IQ_CMD_IQESIZE(x) ((x) << 0)
+
+#define FW_IQ_CMD_IQNS(x) ((x) << 31)
+#define FW_IQ_CMD_IQRO(x) ((x) << 30)
+#define FW_IQ_CMD_IQFLINTIQHSEN(x) ((x) << 28)
+#define FW_IQ_CMD_IQFLINTCONGEN(x) ((x) << 27)
+#define FW_IQ_CMD_IQFLINTISCSIC(x) ((x) << 26)
+#define FW_IQ_CMD_FL0CNGCHMAP(x) ((x) << 20)
+#define FW_IQ_CMD_FL0CACHELOCK(x) ((x) << 15)
+#define FW_IQ_CMD_FL0DBP(x) ((x) << 14)
+#define FW_IQ_CMD_FL0DATANS(x) ((x) << 13)
+#define FW_IQ_CMD_FL0DATARO(x) ((x) << 12)
+#define FW_IQ_CMD_FL0CONGCIF(x) ((x) << 11)
+#define FW_IQ_CMD_FL0ONCHIP(x) ((x) << 10)
+#define FW_IQ_CMD_FL0STATUSPGNS(x) ((x) << 9)
+#define FW_IQ_CMD_FL0STATUSPGRO(x) ((x) << 8)
+#define FW_IQ_CMD_FL0FETCHNS(x) ((x) << 7)
+#define FW_IQ_CMD_FL0FETCHRO(x) ((x) << 6)
+#define FW_IQ_CMD_FL0HOSTFCMODE(x) ((x) << 4)
+#define FW_IQ_CMD_FL0CPRIO(x) ((x) << 3)
+#define FW_IQ_CMD_FL0PADEN (1U << 2)
+#define FW_IQ_CMD_FL0PACKEN (1U << 1)
+#define FW_IQ_CMD_FL0CONGEN (1U << 0)
+
+#define FW_IQ_CMD_FL0DCAEN(x) ((x) << 15)
+#define FW_IQ_CMD_FL0DCACPU(x) ((x) << 10)
+#define FW_IQ_CMD_FL0FBMIN(x) ((x) << 7)
+#define FW_IQ_CMD_FL0FBMAX(x) ((x) << 4)
+#define FW_IQ_CMD_FL0CIDXFTHRESHO (1U << 3)
+#define FW_IQ_CMD_FL0CIDXFTHRESH(x) ((x) << 0)
+
+#define FW_IQ_CMD_FL1CNGCHMAP(x) ((x) << 20)
+#define FW_IQ_CMD_FL1CACHELOCK(x) ((x) << 15)
+#define FW_IQ_CMD_FL1DBP(x) ((x) << 14)
+#define FW_IQ_CMD_FL1DATANS(x) ((x) << 13)
+#define FW_IQ_CMD_FL1DATARO(x) ((x) << 12)
+#define FW_IQ_CMD_FL1CONGCIF(x) ((x) << 11)
+#define FW_IQ_CMD_FL1ONCHIP(x) ((x) << 10)
+#define FW_IQ_CMD_FL1STATUSPGNS(x) ((x) << 9)
+#define FW_IQ_CMD_FL1STATUSPGRO(x) ((x) << 8)
+#define FW_IQ_CMD_FL1FETCHNS(x) ((x) << 7)
+#define FW_IQ_CMD_FL1FETCHRO(x) ((x) << 6)
+#define FW_IQ_CMD_FL1HOSTFCMODE(x) ((x) << 4)
+#define FW_IQ_CMD_FL1CPRIO(x) ((x) << 3)
+#define FW_IQ_CMD_FL1PADEN (1U << 2)
+#define FW_IQ_CMD_FL1PACKEN (1U << 1)
+#define FW_IQ_CMD_FL1CONGEN (1U << 0)
+
+#define FW_IQ_CMD_FL1DCAEN(x) ((x) << 15)
+#define FW_IQ_CMD_FL1DCACPU(x) ((x) << 10)
+#define FW_IQ_CMD_FL1FBMIN(x) ((x) << 7)
+#define FW_IQ_CMD_FL1FBMAX(x) ((x) << 4)
+#define FW_IQ_CMD_FL1CIDXFTHRESHO (1U << 3)
+#define FW_IQ_CMD_FL1CIDXFTHRESH(x) ((x) << 0)
+
+struct fw_eq_eth_cmd {
+ __be32 op_to_vfn;
+ __be32 alloc_to_len16;
+ __be32 eqid_pkd;
+ __be32 physeqid_pkd;
+ __be32 fetchszm_to_iqid;
+ __be32 dcaen_to_eqsize;
+ __be64 eqaddr;
+ __be32 viid_pkd;
+ __be32 r8_lo;
+ __be64 r9;
+};
+
+#define FW_EQ_ETH_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_ETH_CMD_VFN(x) ((x) << 0)
+#define FW_EQ_ETH_CMD_ALLOC (1U << 31)
+#define FW_EQ_ETH_CMD_FREE (1U << 30)
+#define FW_EQ_ETH_CMD_MODIFY (1U << 29)
+#define FW_EQ_ETH_CMD_EQSTART (1U << 28)
+#define FW_EQ_ETH_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_ETH_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_ETH_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_ETH_CMD_PHYSEQID(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_FETCHSZM(x) ((x) << 26)
+#define FW_EQ_ETH_CMD_STATUSPGNS(x) ((x) << 25)
+#define FW_EQ_ETH_CMD_STATUSPGRO(x) ((x) << 24)
+#define FW_EQ_ETH_CMD_FETCHNS(x) ((x) << 23)
+#define FW_EQ_ETH_CMD_FETCHRO(x) ((x) << 22)
+#define FW_EQ_ETH_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_ETH_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_ETH_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_ETH_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_ETH_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_ETH_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_ETH_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_ETH_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_ETH_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_VIID(x) ((x) << 16)
+
+struct fw_eq_ctrl_cmd {
+ __be32 op_to_vfn;
+ __be32 alloc_to_len16;
+ __be32 cmpliqid_eqid;
+ __be32 physeqid_pkd;
+ __be32 fetchszm_to_iqid;
+ __be32 dcaen_to_eqsize;
+ __be64 eqaddr;
+};
+
+#define FW_EQ_CTRL_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_CTRL_CMD_VFN(x) ((x) << 0)
+
+#define FW_EQ_CTRL_CMD_ALLOC (1U << 31)
+#define FW_EQ_CTRL_CMD_FREE (1U << 30)
+#define FW_EQ_CTRL_CMD_MODIFY (1U << 29)
+#define FW_EQ_CTRL_CMD_EQSTART (1U << 28)
+#define FW_EQ_CTRL_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_CTRL_CMD_CMPLIQID(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_CTRL_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_CTRL_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_EQ_CTRL_CMD_FETCHSZM (1U << 26)
+#define FW_EQ_CTRL_CMD_STATUSPGNS (1U << 25)
+#define FW_EQ_CTRL_CMD_STATUSPGRO (1U << 24)
+#define FW_EQ_CTRL_CMD_FETCHNS (1U << 23)
+#define FW_EQ_CTRL_CMD_FETCHRO (1U << 22)
+#define FW_EQ_CTRL_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_CTRL_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_CTRL_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_CTRL_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_CTRL_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_CTRL_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_CTRL_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_CTRL_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_CTRL_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_CTRL_CMD_EQSIZE(x) ((x) << 0)
+
+struct fw_eq_ofld_cmd {
+ __be32 op_to_vfn;
+ __be32 alloc_to_len16;
+ __be32 eqid_pkd;
+ __be32 physeqid_pkd;
+ __be32 fetchszm_to_iqid;
+ __be32 dcaen_to_eqsize;
+ __be64 eqaddr;
+};
+
+#define FW_EQ_OFLD_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_OFLD_CMD_VFN(x) ((x) << 0)
+
+#define FW_EQ_OFLD_CMD_ALLOC (1U << 31)
+#define FW_EQ_OFLD_CMD_FREE (1U << 30)
+#define FW_EQ_OFLD_CMD_MODIFY (1U << 29)
+#define FW_EQ_OFLD_CMD_EQSTART (1U << 28)
+#define FW_EQ_OFLD_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_OFLD_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_OFLD_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_OFLD_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_EQ_OFLD_CMD_FETCHSZM(x) ((x) << 26)
+#define FW_EQ_OFLD_CMD_STATUSPGNS(x) ((x) << 25)
+#define FW_EQ_OFLD_CMD_STATUSPGRO(x) ((x) << 24)
+#define FW_EQ_OFLD_CMD_FETCHNS(x) ((x) << 23)
+#define FW_EQ_OFLD_CMD_FETCHRO(x) ((x) << 22)
+#define FW_EQ_OFLD_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_OFLD_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_OFLD_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_OFLD_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_OFLD_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_OFLD_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_OFLD_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_OFLD_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_OFLD_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_OFLD_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_OFLD_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_OFLD_CMD_EQSIZE(x) ((x) << 0)
+
+/*
+ * Macros for VIID parsing:
+ * VIID - [10:8] PFN, [7] VI Valid, [6:0] VI number
+ */
+#define FW_VIID_PFN_GET(x) (((x) >> 8) & 0x7)
+#define FW_VIID_VIVLD_GET(x) (((x) >> 7) & 0x1)
+#define FW_VIID_VIN_GET(x) (((x) >> 0) & 0x7F)
+
+struct fw_vi_cmd {
+ __be32 op_to_vfn;
+ __be32 alloc_to_len16;
+ __be16 viid_pkd;
+ u8 mac[6];
+ u8 portid_pkd;
+ u8 nmac;
+ u8 nmac0[6];
+ __be16 rsssize_pkd;
+ u8 nmac1[6];
+ __be16 r7;
+ u8 nmac2[6];
+ __be16 r8;
+ u8 nmac3[6];
+ __be64 r9;
+ __be64 r10;
+};
+
+#define FW_VI_CMD_PFN(x) ((x) << 8)
+#define FW_VI_CMD_VFN(x) ((x) << 0)
+#define FW_VI_CMD_ALLOC (1U << 31)
+#define FW_VI_CMD_FREE (1U << 30)
+#define FW_VI_CMD_VIID(x) ((x) << 0)
+#define FW_VI_CMD_PORTID(x) ((x) << 4)
+#define FW_VI_CMD_RSSSIZE_GET(x) (((x) >> 0) & 0x7ff)
+
+/* Special VI_MAC command index ids */
+#define FW_VI_MAC_ADD_MAC 0x3FF
+#define FW_VI_MAC_ADD_PERSIST_MAC 0x3FE
+#define FW_VI_MAC_MAC_BASED_FREE 0x3FD
+
+enum fw_vi_mac_smac {
+ FW_VI_MAC_MPS_TCAM_ENTRY,
+ FW_VI_MAC_MPS_TCAM_ONLY,
+ FW_VI_MAC_SMT_ONLY,
+ FW_VI_MAC_SMT_AND_MPSTCAM
+};
+
+enum fw_vi_mac_result {
+ FW_VI_MAC_R_SUCCESS,
+ FW_VI_MAC_R_F_NONEXISTENT_NOMEM,
+ FW_VI_MAC_R_SMAC_FAIL,
+ FW_VI_MAC_R_F_ACL_CHECK
+};
+
+struct fw_vi_mac_cmd {
+ __be32 op_to_viid;
+ __be32 freemacs_to_len16;
+ union fw_vi_mac {
+ struct fw_vi_mac_exact {
+ __be16 valid_to_idx;
+ u8 macaddr[6];
+ } exact[7];
+ struct fw_vi_mac_hash {
+ __be64 hashvec;
+ } hash;
+ } u;
+};
+
+#define FW_VI_MAC_CMD_VIID(x) ((x) << 0)
+#define FW_VI_MAC_CMD_FREEMACS(x) ((x) << 31)
+#define FW_VI_MAC_CMD_HASHVECEN (1U << 23)
+#define FW_VI_MAC_CMD_HASHUNIEN(x) ((x) << 22)
+#define FW_VI_MAC_CMD_VALID (1U << 15)
+#define FW_VI_MAC_CMD_PRIO(x) ((x) << 12)
+#define FW_VI_MAC_CMD_SMAC_RESULT(x) ((x) << 10)
+#define FW_VI_MAC_CMD_SMAC_RESULT_GET(x) (((x) >> 10) & 0x3)
+#define FW_VI_MAC_CMD_IDX(x) ((x) << 0)
+#define FW_VI_MAC_CMD_IDX_GET(x) (((x) >> 0) & 0x3ff)
+
+#define FW_RXMODE_MTU_NO_CHG 65535
+
+struct fw_vi_rxmode_cmd {
+ __be32 op_to_viid;
+ __be32 retval_len16;
+ __be32 mtu_to_broadcasten;
+ __be32 r4_lo;
+};
+
+#define FW_VI_RXMODE_CMD_VIID(x) ((x) << 0)
+#define FW_VI_RXMODE_CMD_MTU(x) ((x) << 16)
+#define FW_VI_RXMODE_CMD_PROMISCEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_PROMISCEN(x) ((x) << 14)
+#define FW_VI_RXMODE_CMD_ALLMULTIEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_ALLMULTIEN(x) ((x) << 12)
+#define FW_VI_RXMODE_CMD_BROADCASTEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_BROADCASTEN(x) ((x) << 10)
+
+struct fw_vi_enable_cmd {
+ __be32 op_to_viid;
+ __be32 ien_to_len16;
+ __be16 blinkdur;
+ __be16 r3;
+ __be32 r4;
+};
+
+#define FW_VI_ENABLE_CMD_VIID(x) ((x) << 0)
+#define FW_VI_ENABLE_CMD_IEN(x) ((x) << 31)
+#define FW_VI_ENABLE_CMD_EEN(x) ((x) << 30)
+#define FW_VI_ENABLE_CMD_LED (1U << 29)
+
+/* VI VF stats offset definitions */
+#define VI_VF_NUM_STATS 16
+enum fw_vi_stats_vf_index {
+ FW_VI_VF_STAT_TX_BCAST_BYTES_IX,
+ FW_VI_VF_STAT_TX_BCAST_FRAMES_IX,
+ FW_VI_VF_STAT_TX_MCAST_BYTES_IX,
+ FW_VI_VF_STAT_TX_MCAST_FRAMES_IX,
+ FW_VI_VF_STAT_TX_UCAST_BYTES_IX,
+ FW_VI_VF_STAT_TX_UCAST_FRAMES_IX,
+ FW_VI_VF_STAT_TX_DROP_FRAMES_IX,
+ FW_VI_VF_STAT_TX_OFLD_BYTES_IX,
+ FW_VI_VF_STAT_TX_OFLD_FRAMES_IX,
+ FW_VI_VF_STAT_RX_BCAST_BYTES_IX,
+ FW_VI_VF_STAT_RX_BCAST_FRAMES_IX,
+ FW_VI_VF_STAT_RX_MCAST_BYTES_IX,
+ FW_VI_VF_STAT_RX_MCAST_FRAMES_IX,
+ FW_VI_VF_STAT_RX_UCAST_BYTES_IX,
+ FW_VI_VF_STAT_RX_UCAST_FRAMES_IX,
+ FW_VI_VF_STAT_RX_ERR_FRAMES_IX
+};
+
+/* VI PF stats offset definitions */
+#define VI_PF_NUM_STATS 17
+enum fw_vi_stats_pf_index {
+ FW_VI_PF_STAT_TX_BCAST_BYTES_IX,
+ FW_VI_PF_STAT_TX_BCAST_FRAMES_IX,
+ FW_VI_PF_STAT_TX_MCAST_BYTES_IX,
+ FW_VI_PF_STAT_TX_MCAST_FRAMES_IX,
+ FW_VI_PF_STAT_TX_UCAST_BYTES_IX,
+ FW_VI_PF_STAT_TX_UCAST_FRAMES_IX,
+ FW_VI_PF_STAT_TX_OFLD_BYTES_IX,
+ FW_VI_PF_STAT_TX_OFLD_FRAMES_IX,
+ FW_VI_PF_STAT_RX_BYTES_IX,
+ FW_VI_PF_STAT_RX_FRAMES_IX,
+ FW_VI_PF_STAT_RX_BCAST_BYTES_IX,
+ FW_VI_PF_STAT_RX_BCAST_FRAMES_IX,
+ FW_VI_PF_STAT_RX_MCAST_BYTES_IX,
+ FW_VI_PF_STAT_RX_MCAST_FRAMES_IX,
+ FW_VI_PF_STAT_RX_UCAST_BYTES_IX,
+ FW_VI_PF_STAT_RX_UCAST_FRAMES_IX,
+ FW_VI_PF_STAT_RX_ERR_FRAMES_IX
+};
+
+struct fw_vi_stats_cmd {
+ __be32 op_to_viid;
+ __be32 retval_len16;
+ union fw_vi_stats {
+ struct fw_vi_stats_ctl {
+ __be16 nstats_ix;
+ __be16 r6;
+ __be32 r7;
+ __be64 stat0;
+ __be64 stat1;
+ __be64 stat2;
+ __be64 stat3;
+ __be64 stat4;
+ __be64 stat5;
+ } ctl;
+ struct fw_vi_stats_pf {
+ __be64 tx_bcast_bytes;
+ __be64 tx_bcast_frames;
+ __be64 tx_mcast_bytes;
+ __be64 tx_mcast_frames;
+ __be64 tx_ucast_bytes;
+ __be64 tx_ucast_frames;
+ __be64 tx_offload_bytes;
+ __be64 tx_offload_frames;
+ __be64 rx_pf_bytes;
+ __be64 rx_pf_frames;
+ __be64 rx_bcast_bytes;
+ __be64 rx_bcast_frames;
+ __be64 rx_mcast_bytes;
+ __be64 rx_mcast_frames;
+ __be64 rx_ucast_bytes;
+ __be64 rx_ucast_frames;
+ __be64 rx_err_frames;
+ } pf;
+ struct fw_vi_stats_vf {
+ __be64 tx_bcast_bytes;
+ __be64 tx_bcast_frames;
+ __be64 tx_mcast_bytes;
+ __be64 tx_mcast_frames;
+ __be64 tx_ucast_bytes;
+ __be64 tx_ucast_frames;
+ __be64 tx_drop_frames;
+ __be64 tx_offload_bytes;
+ __be64 tx_offload_frames;
+ __be64 rx_bcast_bytes;
+ __be64 rx_bcast_frames;
+ __be64 rx_mcast_bytes;
+ __be64 rx_mcast_frames;
+ __be64 rx_ucast_bytes;
+ __be64 rx_ucast_frames;
+ __be64 rx_err_frames;
+ } vf;
+ } u;
+};
+
+#define FW_VI_STATS_CMD_VIID(x) ((x) << 0)
+#define FW_VI_STATS_CMD_NSTATS(x) ((x) << 12)
+#define FW_VI_STATS_CMD_IX(x) ((x) << 0)
+
+struct fw_acl_mac_cmd {
+ __be32 op_to_vfn;
+ __be32 en_to_len16;
+ u8 nmac;
+ u8 r3[7];
+ __be16 r4;
+ u8 macaddr0[6];
+ __be16 r5;
+ u8 macaddr1[6];
+ __be16 r6;
+ u8 macaddr2[6];
+ __be16 r7;
+ u8 macaddr3[6];
+};
+
+#define FW_ACL_MAC_CMD_PFN(x) ((x) << 8)
+#define FW_ACL_MAC_CMD_VFN(x) ((x) << 0)
+#define FW_ACL_MAC_CMD_EN(x) ((x) << 31)
+
+struct fw_acl_vlan_cmd {
+ __be32 op_to_vfn;
+ __be32 en_to_len16;
+ u8 nvlan;
+ u8 dropnovlan_fm;
+ u8 r3_lo[6];
+ __be16 vlanid[16];
+};
+
+#define FW_ACL_VLAN_CMD_PFN(x) ((x) << 8)
+#define FW_ACL_VLAN_CMD_VFN(x) ((x) << 0)
+#define FW_ACL_VLAN_CMD_EN(x) ((x) << 31)
+#define FW_ACL_VLAN_CMD_DROPNOVLAN(x) ((x) << 7)
+#define FW_ACL_VLAN_CMD_FM(x) ((x) << 6)
+
+enum fw_port_cap {
+ FW_PORT_CAP_SPEED_100M = 0x0001,
+ FW_PORT_CAP_SPEED_1G = 0x0002,
+ FW_PORT_CAP_SPEED_2_5G = 0x0004,
+ FW_PORT_CAP_SPEED_10G = 0x0008,
+ FW_PORT_CAP_SPEED_40G = 0x0010,
+ FW_PORT_CAP_SPEED_100G = 0x0020,
+ FW_PORT_CAP_FC_RX = 0x0040,
+ FW_PORT_CAP_FC_TX = 0x0080,
+ FW_PORT_CAP_ANEG = 0x0100,
+ FW_PORT_CAP_MDI_0 = 0x0200,
+ FW_PORT_CAP_MDI_1 = 0x0400,
+ FW_PORT_CAP_BEAN = 0x0800,
+ FW_PORT_CAP_PMA_LPBK = 0x1000,
+ FW_PORT_CAP_PCS_LPBK = 0x2000,
+ FW_PORT_CAP_PHYXS_LPBK = 0x4000,
+ FW_PORT_CAP_FAR_END_LPBK = 0x8000,
+};
+
+enum fw_port_mdi {
+ FW_PORT_MDI_UNCHANGED,
+ FW_PORT_MDI_AUTO,
+ FW_PORT_MDI_F_STRAIGHT,
+ FW_PORT_MDI_F_CROSSOVER
+};
+
+#define FW_PORT_MDI(x) ((x) << 9)
+
+enum fw_port_action {
+ FW_PORT_ACTION_L1_CFG = 0x0001,
+ FW_PORT_ACTION_L2_CFG = 0x0002,
+ FW_PORT_ACTION_GET_PORT_INFO = 0x0003,
+ FW_PORT_ACTION_L2_PPP_CFG = 0x0004,
+ FW_PORT_ACTION_L2_DCB_CFG = 0x0005,
+ FW_PORT_ACTION_LOW_PWR_TO_NORMAL = 0x0010,
+ FW_PORT_ACTION_L1_LOW_PWR_EN = 0x0011,
+ FW_PORT_ACTION_L2_WOL_MODE_EN = 0x0012,
+ FW_PORT_ACTION_LPBK_TO_NORMAL = 0x0020,
+ FW_PORT_ACTION_L1_LPBK = 0x0021,
+ FW_PORT_ACTION_L1_PMA_LPBK = 0x0022,
+ FW_PORT_ACTION_L1_PCS_LPBK = 0x0023,
+ FW_PORT_ACTION_L1_PHYXS_CSIDE_LPBK = 0x0024,
+ FW_PORT_ACTION_L1_PHYXS_ESIDE_LPBK = 0x0025,
+ FW_PORT_ACTION_PHY_RESET = 0x0040,
+ FW_PORT_ACTION_PMA_RESET = 0x0041,
+ FW_PORT_ACTION_PCS_RESET = 0x0042,
+ FW_PORT_ACTION_PHYXS_RESET = 0x0043,
+ FW_PORT_ACTION_DTEXS_REEST = 0x0044,
+ FW_PORT_ACTION_AN_RESET = 0x0045
+};
+
+enum fw_port_l2cfg_ctlbf {
+ FW_PORT_L2_CTLBF_OVLAN0 = 0x01,
+ FW_PORT_L2_CTLBF_OVLAN1 = 0x02,
+ FW_PORT_L2_CTLBF_OVLAN2 = 0x04,
+ FW_PORT_L2_CTLBF_OVLAN3 = 0x08,
+ FW_PORT_L2_CTLBF_IVLAN = 0x10,
+ FW_PORT_L2_CTLBF_TXIPG = 0x20
+};
+
+enum fw_port_dcb_cfg {
+ FW_PORT_DCB_CFG_PG = 0x01,
+ FW_PORT_DCB_CFG_PFC = 0x02,
+ FW_PORT_DCB_CFG_APPL = 0x04
+};
+
+enum fw_port_dcb_cfg_rc {
+ FW_PORT_DCB_CFG_SUCCESS = 0x0,
+ FW_PORT_DCB_CFG_ERROR = 0x1
+};
+
+struct fw_port_cmd {
+ __be32 op_to_portid;
+ __be32 action_to_len16;
+ union fw_port {
+ struct fw_port_l1cfg {
+ __be32 rcap;
+ __be32 r;
+ } l1cfg;
+ struct fw_port_l2cfg {
+ __be16 ctlbf_to_ivlan0;
+ __be16 ivlantype;
+ __be32 txipg_pkd;
+ __be16 ovlan0mask;
+ __be16 ovlan0type;
+ __be16 ovlan1mask;
+ __be16 ovlan1type;
+ __be16 ovlan2mask;
+ __be16 ovlan2type;
+ __be16 ovlan3mask;
+ __be16 ovlan3type;
+ } l2cfg;
+ struct fw_port_info {
+ __be32 lstatus_to_modtype;
+ __be16 pcap;
+ __be16 acap;
+ } info;
+ struct fw_port_ppp {
+ __be32 pppen_to_ncsich;
+ __be32 r11;
+ } ppp;
+ struct fw_port_dcb {
+ __be16 cfg;
+ u8 up_map;
+ u8 sf_cfgrc;
+ __be16 prot_ix;
+ u8 pe7_to_pe0;
+ u8 numTCPFCs;
+ __be32 pgid0_to_pgid7;
+ __be32 numTCs_oui;
+ u8 pgpc[8];
+ } dcb;
+ } u;
+};
+
+#define FW_PORT_CMD_READ (1U << 22)
+
+#define FW_PORT_CMD_PORTID(x) ((x) << 0)
+#define FW_PORT_CMD_PORTID_GET(x) (((x) >> 0) & 0xf)
+
+#define FW_PORT_CMD_ACTION(x) ((x) << 16)
+
+#define FW_PORT_CMD_CTLBF(x) ((x) << 10)
+#define FW_PORT_CMD_OVLAN3(x) ((x) << 7)
+#define FW_PORT_CMD_OVLAN2(x) ((x) << 6)
+#define FW_PORT_CMD_OVLAN1(x) ((x) << 5)
+#define FW_PORT_CMD_OVLAN0(x) ((x) << 4)
+#define FW_PORT_CMD_IVLAN0(x) ((x) << 3)
+
+#define FW_PORT_CMD_TXIPG(x) ((x) << 19)
+
+#define FW_PORT_CMD_LSTATUS (1U << 31)
+#define FW_PORT_CMD_LSPEED(x) ((x) << 24)
+#define FW_PORT_CMD_LSPEED_GET(x) (((x) >> 24) & 0x3f)
+#define FW_PORT_CMD_TXPAUSE (1U << 23)
+#define FW_PORT_CMD_RXPAUSE (1U << 22)
+#define FW_PORT_CMD_MDIOCAP (1U << 21)
+#define FW_PORT_CMD_MDIOADDR_GET(x) (((x) >> 16) & 0x1f)
+#define FW_PORT_CMD_LPTXPAUSE (1U << 15)
+#define FW_PORT_CMD_LPRXPAUSE (1U << 14)
+#define FW_PORT_CMD_PTYPE_MASK 0x1f
+#define FW_PORT_CMD_PTYPE_GET(x) (((x) >> 8) & FW_PORT_CMD_PTYPE_MASK)
+#define FW_PORT_CMD_MODTYPE_MASK 0x1f
+#define FW_PORT_CMD_MODTYPE_GET(x) (((x) >> 0) & FW_PORT_CMD_MODTYPE_MASK)
+
+#define FW_PORT_CMD_PPPEN(x) ((x) << 31)
+#define FW_PORT_CMD_TPSRC(x) ((x) << 28)
+#define FW_PORT_CMD_NCSISRC(x) ((x) << 24)
+
+#define FW_PORT_CMD_CH0(x) ((x) << 20)
+#define FW_PORT_CMD_CH1(x) ((x) << 16)
+#define FW_PORT_CMD_CH2(x) ((x) << 12)
+#define FW_PORT_CMD_CH3(x) ((x) << 8)
+#define FW_PORT_CMD_NCSICH(x) ((x) << 4)
+
+enum fw_port_type {
+ FW_PORT_TYPE_FIBER,
+ FW_PORT_TYPE_KX4,
+ FW_PORT_TYPE_BT_SGMII,
+ FW_PORT_TYPE_KX,
+ FW_PORT_TYPE_BT_XAUI,
+ FW_PORT_TYPE_KR,
+ FW_PORT_TYPE_CX4,
+ FW_PORT_TYPE_TWINAX,
+
+ FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_MASK
+};
+
+enum fw_port_module_type {
+ FW_PORT_MOD_TYPE_NA,
+ FW_PORT_MOD_TYPE_LR,
+ FW_PORT_MOD_TYPE_SR,
+ FW_PORT_MOD_TYPE_ER,
+
+ FW_PORT_MOD_TYPE_NONE = FW_PORT_CMD_MODTYPE_MASK
+};
+
+/* port stats */
+#define FW_NUM_PORT_STATS 50
+#define FW_NUM_PORT_TX_STATS 23
+#define FW_NUM_PORT_RX_STATS 27
+
+enum fw_port_stats_tx_index {
+ FW_STAT_TX_PORT_BYTES_IX,
+ FW_STAT_TX_PORT_FRAMES_IX,
+ FW_STAT_TX_PORT_BCAST_IX,
+ FW_STAT_TX_PORT_MCAST_IX,
+ FW_STAT_TX_PORT_UCAST_IX,
+ FW_STAT_TX_PORT_ERROR_IX,
+ FW_STAT_TX_PORT_64B_IX,
+ FW_STAT_TX_PORT_65B_127B_IX,
+ FW_STAT_TX_PORT_128B_255B_IX,
+ FW_STAT_TX_PORT_256B_511B_IX,
+ FW_STAT_TX_PORT_512B_1023B_IX,
+ FW_STAT_TX_PORT_1024B_1518B_IX,
+ FW_STAT_TX_PORT_1519B_MAX_IX,
+ FW_STAT_TX_PORT_DROP_IX,
+ FW_STAT_TX_PORT_PAUSE_IX,
+ FW_STAT_TX_PORT_PPP0_IX,
+ FW_STAT_TX_PORT_PPP1_IX,
+ FW_STAT_TX_PORT_PPP2_IX,
+ FW_STAT_TX_PORT_PPP3_IX,
+ FW_STAT_TX_PORT_PPP4_IX,
+ FW_STAT_TX_PORT_PPP5_IX,
+ FW_STAT_TX_PORT_PPP6_IX,
+ FW_STAT_TX_PORT_PPP7_IX
+};
+
+enum fw_port_stat_rx_index {
+ FW_STAT_RX_PORT_BYTES_IX,
+ FW_STAT_RX_PORT_FRAMES_IX,
+ FW_STAT_RX_PORT_BCAST_IX,
+ FW_STAT_RX_PORT_MCAST_IX,
+ FW_STAT_RX_PORT_UCAST_IX,
+ FW_STAT_RX_PORT_MTU_ERROR_IX,
+ FW_STAT_RX_PORT_MTU_CRC_ERROR_IX,
+ FW_STAT_RX_PORT_CRC_ERROR_IX,
+ FW_STAT_RX_PORT_LEN_ERROR_IX,
+ FW_STAT_RX_PORT_SYM_ERROR_IX,
+ FW_STAT_RX_PORT_64B_IX,
+ FW_STAT_RX_PORT_65B_127B_IX,
+ FW_STAT_RX_PORT_128B_255B_IX,
+ FW_STAT_RX_PORT_256B_511B_IX,
+ FW_STAT_RX_PORT_512B_1023B_IX,
+ FW_STAT_RX_PORT_1024B_1518B_IX,
+ FW_STAT_RX_PORT_1519B_MAX_IX,
+ FW_STAT_RX_PORT_PAUSE_IX,
+ FW_STAT_RX_PORT_PPP0_IX,
+ FW_STAT_RX_PORT_PPP1_IX,
+ FW_STAT_RX_PORT_PPP2_IX,
+ FW_STAT_RX_PORT_PPP3_IX,
+ FW_STAT_RX_PORT_PPP4_IX,
+ FW_STAT_RX_PORT_PPP5_IX,
+ FW_STAT_RX_PORT_PPP6_IX,
+ FW_STAT_RX_PORT_PPP7_IX,
+ FW_STAT_RX_PORT_LESS_64B_IX
+};
+
+struct fw_port_stats_cmd {
+ __be32 op_to_portid;
+ __be32 retval_len16;
+ union fw_port_stats {
+ struct fw_port_stats_ctl {
+ u8 nstats_bg_bm;
+ u8 tx_ix;
+ __be16 r6;
+ __be32 r7;
+ __be64 stat0;
+ __be64 stat1;
+ __be64 stat2;
+ __be64 stat3;
+ __be64 stat4;
+ __be64 stat5;
+ } ctl;
+ struct fw_port_stats_all {
+ __be64 tx_bytes;
+ __be64 tx_frames;
+ __be64 tx_bcast;
+ __be64 tx_mcast;
+ __be64 tx_ucast;
+ __be64 tx_error;
+ __be64 tx_64b;
+ __be64 tx_65b_127b;
+ __be64 tx_128b_255b;
+ __be64 tx_256b_511b;
+ __be64 tx_512b_1023b;
+ __be64 tx_1024b_1518b;
+ __be64 tx_1519b_max;
+ __be64 tx_drop;
+ __be64 tx_pause;
+ __be64 tx_ppp0;
+ __be64 tx_ppp1;
+ __be64 tx_ppp2;
+ __be64 tx_ppp3;
+ __be64 tx_ppp4;
+ __be64 tx_ppp5;
+ __be64 tx_ppp6;
+ __be64 tx_ppp7;
+ __be64 rx_bytes;
+ __be64 rx_frames;
+ __be64 rx_bcast;
+ __be64 rx_mcast;
+ __be64 rx_ucast;
+ __be64 rx_mtu_error;
+ __be64 rx_mtu_crc_error;
+ __be64 rx_crc_error;
+ __be64 rx_len_error;
+ __be64 rx_sym_error;
+ __be64 rx_64b;
+ __be64 rx_65b_127b;
+ __be64 rx_128b_255b;
+ __be64 rx_256b_511b;
+ __be64 rx_512b_1023b;
+ __be64 rx_1024b_1518b;
+ __be64 rx_1519b_max;
+ __be64 rx_pause;
+ __be64 rx_ppp0;
+ __be64 rx_ppp1;
+ __be64 rx_ppp2;
+ __be64 rx_ppp3;
+ __be64 rx_ppp4;
+ __be64 rx_ppp5;
+ __be64 rx_ppp6;
+ __be64 rx_ppp7;
+ __be64 rx_less_64b;
+ __be64 rx_bg_drop;
+ __be64 rx_bg_trunc;
+ } all;
+ } u;
+};
+
+#define FW_PORT_STATS_CMD_NSTATS(x) ((x) << 4)
+#define FW_PORT_STATS_CMD_BG_BM(x) ((x) << 0)
+#define FW_PORT_STATS_CMD_TX(x) ((x) << 7)
+#define FW_PORT_STATS_CMD_IX(x) ((x) << 0)
+
+/* port loopback stats */
+#define FW_NUM_LB_STATS 16
+enum fw_port_lb_stats_index {
+ FW_STAT_LB_PORT_BYTES_IX,
+ FW_STAT_LB_PORT_FRAMES_IX,
+ FW_STAT_LB_PORT_BCAST_IX,
+ FW_STAT_LB_PORT_MCAST_IX,
+ FW_STAT_LB_PORT_UCAST_IX,
+ FW_STAT_LB_PORT_ERROR_IX,
+ FW_STAT_LB_PORT_64B_IX,
+ FW_STAT_LB_PORT_65B_127B_IX,
+ FW_STAT_LB_PORT_128B_255B_IX,
+ FW_STAT_LB_PORT_256B_511B_IX,
+ FW_STAT_LB_PORT_512B_1023B_IX,
+ FW_STAT_LB_PORT_1024B_1518B_IX,
+ FW_STAT_LB_PORT_1519B_MAX_IX,
+ FW_STAT_LB_PORT_DROP_FRAMES_IX
+};
+
+struct fw_port_lb_stats_cmd {
+ __be32 op_to_lbport;
+ __be32 retval_len16;
+ union fw_port_lb_stats {
+ struct fw_port_lb_stats_ctl {
+ u8 nstats_bg_bm;
+ u8 ix_pkd;
+ __be16 r6;
+ __be32 r7;
+ __be64 stat0;
+ __be64 stat1;
+ __be64 stat2;
+ __be64 stat3;
+ __be64 stat4;
+ __be64 stat5;
+ } ctl;
+ struct fw_port_lb_stats_all {
+ __be64 tx_bytes;
+ __be64 tx_frames;
+ __be64 tx_bcast;
+ __be64 tx_mcast;
+ __be64 tx_ucast;
+ __be64 tx_error;
+ __be64 tx_64b;
+ __be64 tx_65b_127b;
+ __be64 tx_128b_255b;
+ __be64 tx_256b_511b;
+ __be64 tx_512b_1023b;
+ __be64 tx_1024b_1518b;
+ __be64 tx_1519b_max;
+ __be64 rx_lb_drop;
+ __be64 rx_lb_trunc;
+ } all;
+ } u;
+};
+
+#define FW_PORT_LB_STATS_CMD_LBPORT(x) ((x) << 0)
+#define FW_PORT_LB_STATS_CMD_NSTATS(x) ((x) << 4)
+#define FW_PORT_LB_STATS_CMD_BG_BM(x) ((x) << 0)
+#define FW_PORT_LB_STATS_CMD_IX(x) ((x) << 0)
+
+struct fw_rss_ind_tbl_cmd {
+ __be32 op_to_viid;
+#define FW_RSS_IND_TBL_CMD_VIID(x) ((x) << 0)
+ __be32 retval_len16;
+ __be16 niqid;
+ __be16 startidx;
+ __be32 r3;
+ __be32 iq0_to_iq2;
+#define FW_RSS_IND_TBL_CMD_IQ0(x) ((x) << 20)
+#define FW_RSS_IND_TBL_CMD_IQ1(x) ((x) << 10)
+#define FW_RSS_IND_TBL_CMD_IQ2(x) ((x) << 0)
+ __be32 iq3_to_iq5;
+ __be32 iq6_to_iq8;
+ __be32 iq9_to_iq11;
+ __be32 iq12_to_iq14;
+ __be32 iq15_to_iq17;
+ __be32 iq18_to_iq20;
+ __be32 iq21_to_iq23;
+ __be32 iq24_to_iq26;
+ __be32 iq27_to_iq29;
+ __be32 iq30_iq31;
+ __be32 r15_lo;
+};
+
+struct fw_rss_glb_config_cmd {
+ __be32 op_to_write;
+ __be32 retval_len16;
+ union fw_rss_glb_config {
+ struct fw_rss_glb_config_manual {
+ __be32 mode_pkd;
+ __be32 r3;
+ __be64 r4;
+ __be64 r5;
+ } manual;
+ struct fw_rss_glb_config_basicvirtual {
+ __be32 mode_pkd;
+ __be32 synmapen_to_hashtoeplitz;
+#define FW_RSS_GLB_CONFIG_CMD_SYNMAPEN (1U << 8)
+#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6 (1U << 7)
+#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6 (1U << 6)
+#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4 (1U << 5)
+#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4 (1U << 4)
+#define FW_RSS_GLB_CONFIG_CMD_OFDMAPEN (1U << 3)
+#define FW_RSS_GLB_CONFIG_CMD_TNLMAPEN (1U << 2)
+#define FW_RSS_GLB_CONFIG_CMD_TNLALLLKP (1U << 1)
+#define FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ (1U << 0)
+ __be64 r8;
+ __be64 r9;
+ } basicvirtual;
+ } u;
+};
+
+#define FW_RSS_GLB_CONFIG_CMD_MODE(x) ((x) << 28)
+
+#define FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL 0
+#define FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL 1
+
+struct fw_rss_vi_config_cmd {
+ __be32 op_to_viid;
+#define FW_RSS_VI_CONFIG_CMD_VIID(x) ((x) << 0)
+ __be32 retval_len16;
+ union fw_rss_vi_config {
+ struct fw_rss_vi_config_manual {
+ __be64 r3;
+ __be64 r4;
+ __be64 r5;
+ } manual;
+ struct fw_rss_vi_config_basicvirtual {
+ __be32 r6;
+ __be32 defaultq_to_ip4udpen;
+#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ(x) ((x) << 16)
+#define FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN (1U << 4)
+#define FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN (1U << 3)
+#define FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN (1U << 2)
+#define FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN (1U << 1)
+#define FW_RSS_VI_CONFIG_CMD_IP4UDPEN (1U << 0)
+ __be64 r9;
+ __be64 r10;
+ } basicvirtual;
+ } u;
+};
+
+enum fw_error_type {
+ FW_ERROR_TYPE_EXCEPTION = 0x0,
+ FW_ERROR_TYPE_HWMODULE = 0x1,
+ FW_ERROR_TYPE_WR = 0x2,
+ FW_ERROR_TYPE_ACL = 0x3,
+};
+
+struct fw_error_cmd {
+ __be32 op_to_type;
+ __be32 len16_pkd;
+ union fw_error {
+ struct fw_error_exception {
+ __be32 info[6];
+ } exception;
+ struct fw_error_hwmodule {
+ __be32 regaddr;
+ __be32 regval;
+ } hwmodule;
+ struct fw_error_wr {
+ __be16 cidx;
+ __be16 pfn_vfn;
+ __be32 eqid;
+ u8 wrhdr[16];
+ } wr;
+ struct fw_error_acl {
+ __be16 cidx;
+ __be16 pfn_vfn;
+ __be32 eqid;
+ __be16 mv_pkd;
+ u8 val[6];
+ __be64 r4;
+ } acl;
+ } u;
+};
+
+struct fw_debug_cmd {
+ __be32 op_type;
+#define FW_DEBUG_CMD_TYPE_GET(x) ((x) & 0xff)
+ __be32 len16_pkd;
+ union fw_debug {
+ struct fw_debug_assert {
+ __be32 fcid;
+ __be32 line;
+ __be32 x;
+ __be32 y;
+ u8 filename_0_7[8];
+ u8 filename_8_15[8];
+ __be64 r3;
+ } assert;
+ struct fw_debug_prt {
+ __be16 dprtstridx;
+ __be16 r3[3];
+ __be32 dprtstrparam0;
+ __be32 dprtstrparam1;
+ __be32 dprtstrparam2;
+ __be32 dprtstrparam3;
+ } prt;
+ } u;
+};
+
+struct fw_hdr {
+ u8 ver;
+ u8 reserved1;
+ __be16 len512; /* bin length in units of 512-bytes */
+ __be32 fw_ver; /* firmware version */
+ __be32 tp_microcode_ver;
+ u8 intfver_nic;
+ u8 intfver_vnic;
+ u8 intfver_ofld;
+ u8 intfver_ri;
+ u8 intfver_iscsipdu;
+ u8 intfver_iscsi;
+ u8 intfver_fcoe;
+ u8 reserved2;
+ __be32 reserved3[27];
+};
+
+#define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff)
+#define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff)
+#define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff)
+#define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff)
+#endif /* _T4FW_INTERFACE_H_ */
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 1ac9440eb3f..2b8edd2efbf 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -29,10 +29,6 @@
* PHY layer usage
*/
-/** Pending Items in this driver:
- * 1. Use Linux cache infrastcture for DMA'ed memory (dma_xxx functions)
- */
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -504,12 +500,6 @@ static unsigned long mdio_max_freq;
/* Cache macros - Packet buffers would be from skb pool which is cached */
#define EMAC_VIRT_NOCACHE(addr) (addr)
-#define EMAC_CACHE_INVALIDATE(addr, size) \
- dma_cache_maint((void *)addr, size, DMA_FROM_DEVICE)
-#define EMAC_CACHE_WRITEBACK(addr, size) \
- dma_cache_maint((void *)addr, size, DMA_TO_DEVICE)
-#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \
- dma_cache_maint((void *)addr, size, DMA_BIDIRECTIONAL)
/* DM644x does not have BD's in cached memory - so no cache functions */
#define BD_CACHE_INVALIDATE(addr, size)
@@ -1235,6 +1225,10 @@ static void emac_txch_teardown(struct emac_priv *priv, u32 ch)
if (1 == txch->queue_active) {
curr_bd = txch->active_queue_head;
while (curr_bd != NULL) {
+ dma_unmap_single(emac_dev, curr_bd->buff_ptr,
+ curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+ DMA_TO_DEVICE);
+
emac_net_tx_complete(priv, (void __force *)
&curr_bd->buf_token, 1, ch);
if (curr_bd != txch->active_queue_tail)
@@ -1327,6 +1321,11 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
txch->queue_active = 0; /* end of queue */
}
}
+
+ dma_unmap_single(emac_dev, curr_bd->buff_ptr,
+ curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+ DMA_TO_DEVICE);
+
*tx_complete_ptr = (u32) curr_bd->buf_token;
++tx_complete_ptr;
++tx_complete_cnt;
@@ -1387,8 +1386,8 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
txch->bd_pool_head = curr_bd->next;
curr_bd->buf_token = buf_list->buf_token;
- /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
- curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr);
+ curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buf_list->data_ptr,
+ buf_list->length, DMA_TO_DEVICE);
curr_bd->off_b_len = buf_list->length;
curr_bd->h_next = 0;
curr_bd->next = NULL;
@@ -1468,7 +1467,6 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
tx_buf.length = skb->len;
tx_buf.buf_token = (void *)skb;
tx_buf.data_ptr = skb->data;
- EMAC_CACHE_WRITEBACK((unsigned long)skb->data, skb->len);
ndev->trans_start = jiffies;
ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
if (unlikely(ret_code != 0)) {
@@ -1543,7 +1541,6 @@ static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size,
p_skb->dev = ndev;
skb_reserve(p_skb, NET_IP_ALIGN);
*data_token = (void *) p_skb;
- EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size);
return p_skb->data;
}
@@ -1612,8 +1609,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
/* populate the hardware descriptor */
curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
priv);
- /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
- curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
+ curr_bd->buff_ptr = dma_map_single(emac_dev, curr_bd->data_ptr,
+ rxch->buf_size, DMA_FROM_DEVICE);
curr_bd->off_b_len = rxch->buf_size;
curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
@@ -1697,6 +1694,12 @@ static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch)
curr_bd = rxch->active_queue_head;
while (curr_bd) {
if (curr_bd->buf_token) {
+ dma_unmap_single(&priv->ndev->dev,
+ curr_bd->buff_ptr,
+ curr_bd->off_b_len
+ & EMAC_RX_BD_BUF_SIZE,
+ DMA_FROM_DEVICE);
+
dev_kfree_skb_any((struct sk_buff *)\
curr_bd->buf_token);
}
@@ -1871,8 +1874,8 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
/* populate the hardware descriptor */
curr_bd->h_next = 0;
- /* FIXME buff_ptr = dma_map_single(... buffer ...) */
- curr_bd->buff_ptr = virt_to_phys(buffer);
+ curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buffer,
+ rxch->buf_size, DMA_FROM_DEVICE);
curr_bd->off_b_len = rxch->buf_size;
curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
curr_bd->next = NULL;
@@ -1927,7 +1930,6 @@ static int emac_net_rx_cb(struct emac_priv *priv,
p_skb = (struct sk_buff *)net_pkt_list->pkt_token;
/* set length of packet */
skb_put(p_skb, net_pkt_list->pkt_length);
- EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len);
p_skb->protocol = eth_type_trans(p_skb, priv->ndev);
netif_receive_skb(p_skb);
priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
@@ -1990,6 +1992,11 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
rx_buf_obj->buf_token = curr_bd->buf_token;
+
+ dma_unmap_single(&priv->ndev->dev, curr_bd->buff_ptr,
+ curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+ DMA_FROM_DEVICE);
+
curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
curr_pkt->num_bufs = 1;
curr_pkt->pkt_length =
@@ -2385,7 +2392,7 @@ static int emac_dev_open(struct net_device *ndev)
struct emac_priv *priv = netdev_priv(ndev);
netif_carrier_off(ndev);
- for (cnt = 0; cnt <= ETH_ALEN; cnt++)
+ for (cnt = 0; cnt < ETH_ALEN; cnt++)
ndev->dev_addr[cnt] = priv->mac_addr[cnt];
/* Configuration items */
@@ -2658,7 +2665,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
pdata = pdev->dev.platform_data;
if (!pdata) {
- printk(KERN_ERR "DaVinci EMAC: No platfrom data\n");
+ printk(KERN_ERR "DaVinci EMAC: No platform data\n");
return -ENODEV;
}
@@ -2820,31 +2827,37 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev)
return 0;
}
-static
-int davinci_emac_suspend(struct platform_device *pdev, pm_message_t state)
+static int davinci_emac_suspend(struct device *dev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
- if (netif_running(dev))
- emac_dev_stop(dev);
+ if (netif_running(ndev))
+ emac_dev_stop(ndev);
clk_disable(emac_clk);
return 0;
}
-static int davinci_emac_resume(struct platform_device *pdev)
+static int davinci_emac_resume(struct device *dev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
clk_enable(emac_clk);
- if (netif_running(dev))
- emac_dev_open(dev);
+ if (netif_running(ndev))
+ emac_dev_open(ndev);
return 0;
}
+static const struct dev_pm_ops davinci_emac_pm_ops = {
+ .suspend = davinci_emac_suspend,
+ .resume = davinci_emac_resume,
+};
+
/**
* davinci_emac_driver: EMAC platform driver structure
*/
@@ -2852,11 +2865,10 @@ static struct platform_driver davinci_emac_driver = {
.driver = {
.name = "davinci_emac",
.owner = THIS_MODULE,
+ .pm = &davinci_emac_pm_ops,
},
.probe = davinci_emac_probe,
.remove = __devexit_p(davinci_emac_remove),
- .suspend = davinci_emac_suspend,
- .resume = davinci_emac_resume,
};
/**
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 1c67f1138ca..7f9960f718e 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -33,6 +33,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <asm/delay.h>
#include <asm/irq.h>
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index a26ccab057d..791080303db 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -166,6 +166,7 @@
#include <linux/ethtool.h>
#include <linux/string.h>
#include <linux/firmware.h>
+#include <linux/rtnetlink.h>
#include <asm/unaligned.h>
@@ -2265,8 +2266,13 @@ static void e100_tx_timeout_task(struct work_struct *work)
DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
ioread8(&nic->csr->scb.status));
- e100_down(netdev_priv(netdev));
- e100_up(netdev_priv(netdev));
+
+ rtnl_lock();
+ if (netif_running(netdev)) {
+ e100_down(netdev_priv(netdev));
+ e100_up(netdev_priv(netdev));
+ }
+ rtnl_unlock();
}
static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
@@ -2858,7 +2864,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
}
nic->cbs_pool = pci_pool_create(netdev->name,
nic->pdev,
- nic->params.cbs.count * sizeof(struct cb),
+ nic->params.cbs.max * sizeof(struct cb),
sizeof(u32),
0);
DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 9902b33b716..2f29c213185 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -261,7 +261,6 @@ struct e1000_adapter {
/* TX */
struct e1000_tx_ring *tx_ring; /* One per active queue */
unsigned int restart_queue;
- unsigned long tx_queue_len;
u32 txd_cmd;
u32 tx_int_delay;
u32 tx_abs_int_delay;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 8be6faee43e..b15ece26ed8 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -383,8 +383,6 @@ static void e1000_configure(struct e1000_adapter *adapter)
adapter->alloc_rx_buf(adapter, ring,
E1000_DESC_UNUSED(ring));
}
-
- adapter->tx_queue_len = netdev->tx_queue_len;
}
int e1000_up(struct e1000_adapter *adapter)
@@ -503,7 +501,6 @@ void e1000_down(struct e1000_adapter *adapter)
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer);
- netdev->tx_queue_len = adapter->tx_queue_len;
adapter->link_speed = 0;
adapter->link_duplex = 0;
netif_carrier_off(netdev);
@@ -2316,19 +2313,15 @@ static void e1000_watchdog(unsigned long data)
E1000_CTRL_RFCE) ? "RX" : ((ctrl &
E1000_CTRL_TFCE) ? "TX" : "None" )));
- /* tweak tx_queue_len according to speed/duplex
- * and adjust the timeout factor */
- netdev->tx_queue_len = adapter->tx_queue_len;
+ /* adjust timeout factor according to speed/duplex */
adapter->tx_timeout_factor = 1;
switch (adapter->link_speed) {
case SPEED_10:
txb2b = false;
- netdev->tx_queue_len = 10;
adapter->tx_timeout_factor = 16;
break;
case SPEED_100:
txb2b = false;
- netdev->tx_queue_len = 100;
/* maybe add some timeout factor ? */
break;
}
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 3c95acb3a87..90155552ea0 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -336,7 +336,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
static int global_quad_port_a; /* global port a indication */
struct pci_dev *pdev = adapter->pdev;
- u16 eeprom_data = 0;
int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1;
s32 rc;
@@ -387,16 +386,15 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
adapter->flags &= ~FLAG_HAS_WOL;
break;
-
case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ /* Disable ASPM L0s due to hardware errata */
+ e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S);
+
if (pdev->device == E1000_DEV_ID_82573L) {
- if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
- &eeprom_data) < 0)
- break;
- if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) {
- adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
- adapter->max_hw_frame_size = DEFAULT_JUMBO;
- }
+ adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
+ adapter->max_hw_frame_size = DEFAULT_JUMBO;
}
break;
default:
@@ -1346,7 +1344,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
*
* 1) down
* 2) autoneg_progress
- * 3) autoneg_complete (the link sucessfully autonegotiated)
+ * 3) autoneg_complete (the link successfully autonegotiated)
* 4) forced_up (the link has been forced up, it did not autonegotiate)
*
**/
@@ -1792,6 +1790,7 @@ struct e1000_info e1000_82571_info = {
| FLAG_RESET_OVERWRITES_LAA /* errata */
| FLAG_TARC_SPEED_MODE_BIT /* errata */
| FLAG_APME_CHECK_PORT_B,
+ .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */
.pba = 38,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
@@ -1809,6 +1808,7 @@ struct e1000_info e1000_82572_info = {
| FLAG_RX_CSUM_ENABLED
| FLAG_HAS_CTRLEXT_ON_LOAD
| FLAG_TARC_SPEED_MODE_BIT, /* errata */
+ .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */
.pba = 38,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
@@ -1820,13 +1820,11 @@ struct e1000_info e1000_82572_info = {
struct e1000_info e1000_82573_info = {
.mac = e1000_82573,
.flags = FLAG_HAS_HW_VLAN_FILTER
- | FLAG_HAS_JUMBO_FRAMES
| FLAG_HAS_WOL
| FLAG_APME_IN_CTRL3
| FLAG_RX_CSUM_ENABLED
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
- | FLAG_HAS_ERT
| FLAG_HAS_SWSM_ON_LOAD,
.pba = 20,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index db05ec35574..e301e26d689 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -320,6 +320,8 @@
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
/* Header split receive */
+#define E1000_RFCTL_NFSW_DIS 0x00000040
+#define E1000_RFCTL_NFSR_DIS 0x00000080
#define E1000_RFCTL_ACK_DIS 0x00001000
#define E1000_RFCTL_EXTEN 0x00008000
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index c2ec095d216..ee32b9b27a9 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -37,6 +37,7 @@
#include <linux/io.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
+#include <linux/pci-aspm.h>
#include "hw.h"
@@ -279,7 +280,6 @@ struct e1000_adapter {
struct napi_struct napi;
- unsigned long tx_queue_len;
unsigned int restart_queue;
u32 txd_cmd;
@@ -375,7 +375,7 @@ struct e1000_adapter {
struct e1000_info {
enum e1000_mac_type mac;
unsigned int flags;
- unsigned int flags2;
+ unsigned int flags2;
u32 pba;
u32 max_hw_frame_size;
s32 (*get_variants)(struct e1000_adapter *);
@@ -422,6 +422,7 @@ struct e1000_info {
#define FLAG2_CRC_STRIPPING (1 << 0)
#define FLAG2_HAS_PHY_WAKEUP (1 << 1)
#define FLAG2_IS_DISCARDING (1 << 2)
+#define FLAG2_DISABLE_ASPM_L1 (1 << 3)
#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -462,6 +463,7 @@ extern void e1000e_update_stats(struct e1000_adapter *adapter);
extern bool e1000e_has_link(struct e1000_adapter *adapter);
extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
+extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
extern unsigned int copybreak;
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index b33e3cbe9ab..983493f2330 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -31,6 +31,7 @@
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "e1000.h"
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 54d03a0ce3c..8b5e157e9c8 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -2740,6 +2740,16 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
reg &= ~(1 << 31);
ew32(STATUS, reg);
}
+
+ /*
+ * work-around descriptor data corruption issue during nfs v2 udp
+ * traffic, just disable the nfs filtering capability
+ */
+ reg = er32(RFCTL);
+ reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
+ ew32(RFCTL, reg);
+
+ return;
}
/**
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 2425ed11d5c..a8b2c0de27c 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -647,7 +647,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
if (!(rxcw & E1000_RXCW_IV)) {
mac->serdes_has_link = true;
e_dbg("SERDES: Link up - autoneg "
- "completed sucessfully.\n");
+ "completed successfully.\n");
} else {
mac->serdes_has_link = false;
e_dbg("SERDES: Link down - invalid"
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 88d54d3efce..fb8fc7d1b50 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -36,6 +36,7 @@
#include <linux/netdevice.h>
#include <linux/tcp.h>
#include <linux/ipv6.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include <linux/mii.h>
@@ -660,6 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
i = 0;
}
+ if (i == tx_ring->next_to_use)
+ break;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
}
@@ -2289,8 +2292,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
ew32(TCTL, tctl);
e1000e_config_collision_dist(hw);
-
- adapter->tx_queue_len = adapter->netdev->tx_queue_len;
}
/**
@@ -2877,7 +2878,6 @@ void e1000e_down(struct e1000_adapter *adapter)
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer);
- netdev->tx_queue_len = adapter->tx_queue_len;
netif_carrier_off(netdev);
adapter->link_speed = 0;
adapter->link_duplex = 0;
@@ -3588,21 +3588,15 @@ static void e1000_watchdog_task(struct work_struct *work)
"link gets many collisions.\n");
}
- /*
- * tweak tx_queue_len according to speed/duplex
- * and adjust the timeout factor
- */
- netdev->tx_queue_len = adapter->tx_queue_len;
+ /* adjust timeout factor according to speed/duplex */
adapter->tx_timeout_factor = 1;
switch (adapter->link_speed) {
case SPEED_10:
txb2b = 0;
- netdev->tx_queue_len = 10;
adapter->tx_timeout_factor = 16;
break;
case SPEED_100:
txb2b = 0;
- netdev->tx_queue_len = 100;
adapter->tx_timeout_factor = 10;
break;
}
@@ -4289,6 +4283,14 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
}
+ /* 82573 Errata 17 */
+ if (((adapter->hw.mac.type == e1000_82573) ||
+ (adapter->hw.mac.type == e1000_82574)) &&
+ (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
+ adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
+ e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
+ }
+
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
msleep(1);
/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
@@ -4611,29 +4613,39 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
}
}
-static void e1000e_disable_l1aspm(struct pci_dev *pdev)
+#ifdef CONFIG_PCIEASPM
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+ pci_disable_link_state(pdev, state);
+}
+#else
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
int pos;
- u16 val;
+ u16 reg16;
/*
- * 82573 workaround - disable L1 ASPM on mobile chipsets
- *
- * L1 ASPM on various mobile (ich7) chipsets do not behave properly
- * resulting in lost data or garbage information on the pci-e link
- * level. This could result in (false) bad EEPROM checksum errors,
- * long ping times (up to 2s) or even a system freeze/hang.
- *
- * Unfortunately this feature saves about 1W power consumption when
- * active.
+ * Both device and parent should have the same ASPM setting.
+ * Disable ASPM in downstream component first and then upstream.
*/
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
- if (val & 0x2) {
- dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
- val &= ~0x2;
- pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
- }
+ pos = pci_pcie_cap(pdev);
+ pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+ reg16 &= ~state;
+ pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+
+ pos = pci_pcie_cap(pdev->bus->self);
+ pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
+ reg16 &= ~state;
+ pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
+}
+#endif
+void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+ dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
+ (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
+ (state & PCIE_LINK_STATE_L1) ? "L1" : "");
+
+ __e1000e_disable_aspm(pdev, state);
}
#ifdef CONFIG_PM
@@ -4659,7 +4671,8 @@ static int e1000_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_save_state(pdev);
- e1000e_disable_l1aspm(pdev);
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+ e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
err = pci_enable_device_mem(pdev);
if (err) {
@@ -4801,7 +4814,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
int err;
pci_ers_result_t result;
- e1000e_disable_l1aspm(pdev);
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+ e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
@@ -4895,13 +4909,6 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
dev_warn(&adapter->pdev->dev,
"Warning: detected DSPD enabled in EEPROM\n");
}
-
- ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
- if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
- /* ASPM enable */
- dev_warn(&adapter->pdev->dev,
- "Warning: detected ASPM enabled in EEPROM\n");
- }
}
static const struct net_device_ops e1000e_netdev_ops = {
@@ -4950,7 +4957,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
- e1000e_disable_l1aspm(pdev);
+ if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
+ e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
err = pci_enable_device_mem(pdev);
if (err)
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 1b05bdf62c3..27c7bdbfa00 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -137,7 +137,6 @@ static const char version[] =
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 7013dc8a6cb..1a7322b80ea 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -111,7 +111,6 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/mca-legacy.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index b004eaba3d7..809ccc9ff09 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -32,6 +32,7 @@
#include <linux/udp.h>
#include <linux/if.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/if_ether.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 18d405f78c0..a1b4c7e5636 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -27,6 +27,7 @@
*/
#include <linux/mm.h>
+#include <linux/slab.h>
#include "ehea.h"
#include "ehea_phyp.h"
#include "ehea_qmr.h"
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index 3ee32e58c7e..ff27f728fd9 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -18,7 +18,6 @@
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 69b9b70c7da..cf22de71014 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -23,6 +23,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/if_ether.h>
+#include <linux/slab.h>
#include "vnic_resource.h"
#include "vnic_devcmd.h"
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c
index 75583978a5e..e186efaf9da 100644
--- a/drivers/net/enic/vnic_rq.c
+++ b/drivers/net/enic/vnic_rq.c
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "vnic_dev.h"
#include "vnic_rq.h"
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c
index d2e00e51b7b..d5f984357f5 100644
--- a/drivers/net/enic/vnic_wq.c
+++ b/drivers/net/enic/vnic_wq.c
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "vnic_dev.h"
#include "vnic_wq.h"
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 39c271b6be4..7a567201e82 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -73,7 +73,6 @@ static int rx_copybreak;
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/delay.h>
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index f5b96cadeb2..b34a2ddeef4 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -115,6 +115,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/netdevice.h>
#include <net/net_namespace.h>
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index d3abeee3f11..d4e24f08b3b 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -152,7 +152,6 @@ static char *version =
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 209742304e2..a8d92503226 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -18,6 +18,7 @@
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <net/ethoc.h>
static int buffer_size = 0x8000; /* 32 KBytes */
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 9d5ad08a119..d11ae5197f0 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -74,7 +74,6 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 0dbd7219bbd..4a43e56b739 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/crc32.h>
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index ee0f3c6d3f8..7658a082e39 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -14,6 +14,7 @@
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <linux/of_mdio.h>
#include <asm/io.h>
#include <asm/mpc52xx.h>
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index ca05e566202..5c98f7c2242 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -59,6 +59,7 @@
#include <linux/init.h>
#include <linux/if_vlan.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -5898,7 +5899,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
/* Limit the number of tx's outstanding for hw bug */
if (id->driver_data & DEV_NEED_TX_LIMIT) {
np->tx_limit = 1;
- if ((id->driver_data & DEV_NEED_TX_LIMIT2) &&
+ if (((id->driver_data & DEV_NEED_TX_LIMIT2) == DEV_NEED_TX_LIMIT2) &&
pci_dev->revision >= 0xA2)
np->tx_limit = 0;
}
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index cf4f674f9e2..0a973e71876 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -19,7 +19,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -34,6 +33,7 @@
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/of_device.h>
+#include <linux/gfp.h>
#include <asm/immap_cpm2.h>
#include <asm/mpc8260.h>
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index cd2c6cca5f2..ec81f50d591 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -19,7 +19,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -33,6 +32,7 @@
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
+#include <linux/gfp.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index c490a466cae..34d3da751eb 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -19,7 +19,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index d5160edf2fc..3acac5f930c 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -205,8 +205,6 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus)
static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np)
{
struct gfar __iomem *enet_regs;
- u32 __iomem *ioremap_tbipa;
- u64 addr, size;
/*
* This is mildly evil, but so is our hardware for doing this.
@@ -220,9 +218,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct devi
return &enet_regs->tbipa;
} else if (of_device_is_compatible(np, "fsl,etsec2-mdio") ||
of_device_is_compatible(np, "fsl,etsec2-tbi")) {
- addr = of_translate_address(np, of_get_address(np, 1, &size, NULL));
- ioremap_tbipa = ioremap(addr, size);
- return ioremap_tbipa;
+ return of_iomap(np, 1);
} else
return NULL;
}
@@ -279,6 +275,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
u32 __iomem *tbipa;
struct mii_bus *new_bus;
int tbiaddr = -1;
+ const u32 *addrp;
u64 addr = 0, size = 0;
int err = 0;
@@ -297,8 +294,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
new_bus->priv = priv;
fsl_pq_mdio_bus_name(new_bus->id, np);
+ addrp = of_get_address(np, 0, &size, NULL);
+ if (!addrp) {
+ err = -EINVAL;
+ goto err_free_bus;
+ }
+
/* Set the PHY base address */
- addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
+ addr = of_translate_address(np, addrp);
+ if (addr == OF_BAD_ADDR) {
+ err = -EINVAL;
+ goto err_free_bus;
+ }
+
map = ioremap(addr, size);
if (!map) {
err = -ENOMEM;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 6aa526ee909..4e97ca18299 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -549,12 +549,8 @@ static int gfar_parse_group(struct device_node *np,
struct gfar_private *priv, const char *model)
{
u32 *queue_mask;
- u64 addr, size;
-
- addr = of_translate_address(np,
- of_get_address(np, 0, &size, NULL));
- priv->gfargrp[priv->num_grps].regs = ioremap(addr, size);
+ priv->gfargrp[priv->num_grps].regs = of_iomap(np, 0);
if (!priv->gfargrp[priv->num_grps].regs)
return -ENOMEM;
@@ -676,7 +672,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
priv->rx_queue[i] = NULL;
for (i = 0; i < priv->num_tx_queues; i++) {
- priv->tx_queue[i] = (struct gfar_priv_tx_q *)kmalloc(
+ priv->tx_queue[i] = (struct gfar_priv_tx_q *)kzalloc(
sizeof (struct gfar_priv_tx_q), GFP_KERNEL);
if (!priv->tx_queue[i]) {
err = -ENOMEM;
@@ -689,7 +685,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
}
for (i = 0; i < priv->num_rx_queues; i++) {
- priv->rx_queue[i] = (struct gfar_priv_rx_q *)kmalloc(
+ priv->rx_queue[i] = (struct gfar_priv_rx_q *)kzalloc(
sizeof (struct gfar_priv_rx_q), GFP_KERNEL);
if (!priv->rx_queue[i]) {
err = -ENOMEM;
@@ -998,7 +994,7 @@ static int gfar_probe(struct of_device *ofdev,
}
/* Need to reverse the bit maps as bit_map's MSB is q0
- * but, for_each_bit parses from right to left, which
+ * but, for_each_set_bit parses from right to left, which
* basically reverses the queue numbers */
for (i = 0; i< priv->num_grps; i++) {
priv->gfargrp[i].tx_bit_map = reverse_bitmap(
@@ -1011,7 +1007,7 @@ static int gfar_probe(struct of_device *ofdev,
* also assign queues to groups */
for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
priv->gfargrp[grp_idx].num_rx_queues = 0x0;
- for_each_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
+ for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
priv->num_rx_queues) {
priv->gfargrp[grp_idx].num_rx_queues++;
priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
@@ -1019,7 +1015,7 @@ static int gfar_probe(struct of_device *ofdev,
rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
}
priv->gfargrp[grp_idx].num_tx_queues = 0x0;
- for_each_bit (i, &priv->gfargrp[grp_idx].tx_bit_map,
+ for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map,
priv->num_tx_queues) {
priv->gfargrp[grp_idx].num_tx_queues++;
priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
@@ -1120,10 +1116,10 @@ static int gfar_probe(struct of_device *ofdev,
/* provided which set of benchmarks. */
printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
for (i = 0; i < priv->num_rx_queues; i++)
- printk(KERN_INFO "%s: :RX BD ring size for Q[%d]: %d\n",
+ printk(KERN_INFO "%s: RX BD ring size for Q[%d]: %d\n",
dev->name, i, priv->rx_queue[i]->rx_ring_size);
for(i = 0; i < priv->num_tx_queues; i++)
- printk(KERN_INFO "%s:TX BD ring size for Q[%d]: %d\n",
+ printk(KERN_INFO "%s: TX BD ring size for Q[%d]: %d\n",
dev->name, i, priv->tx_queue[i]->tx_ring_size);
return 0;
@@ -1515,9 +1511,9 @@ static void gfar_halt_nodisable(struct net_device *dev)
tempval |= (DMACTRL_GRS | DMACTRL_GTS);
gfar_write(&regs->dmactrl, tempval);
- while (!(gfar_read(&regs->ievent) &
- (IEVENT_GRSC | IEVENT_GTSC)))
- cpu_relax();
+ spin_event_timeout(((gfar_read(&regs->ievent) &
+ (IEVENT_GRSC | IEVENT_GTSC)) ==
+ (IEVENT_GRSC | IEVENT_GTSC)), -1, 0);
}
}
@@ -1638,13 +1634,13 @@ static void free_skb_resources(struct gfar_private *priv)
/* Go through all the buffer descriptors and free their data buffers */
for (i = 0; i < priv->num_tx_queues; i++) {
tx_queue = priv->tx_queue[i];
- if(!tx_queue->tx_skbuff)
+ if(tx_queue->tx_skbuff)
free_skb_tx_queue(tx_queue);
}
for (i = 0; i < priv->num_rx_queues; i++) {
rx_queue = priv->rx_queue[i];
- if(!rx_queue->rx_skbuff)
+ if(rx_queue->rx_skbuff)
free_skb_rx_queue(rx_queue);
}
@@ -1709,7 +1705,7 @@ void gfar_configure_coalescing(struct gfar_private *priv,
if (priv->mode == MQ_MG_MODE) {
baddr = &regs->txic0;
- for_each_bit (i, &tx_mask, priv->num_tx_queues) {
+ for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
if (likely(priv->tx_queue[i]->txcoalescing)) {
gfar_write(baddr + i, 0);
gfar_write(baddr + i, priv->tx_queue[i]->txic);
@@ -1717,7 +1713,7 @@ void gfar_configure_coalescing(struct gfar_private *priv,
}
baddr = &regs->rxic0;
- for_each_bit (i, &rx_mask, priv->num_rx_queues) {
+ for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
if (likely(priv->rx_queue[i]->rxcoalescing)) {
gfar_write(baddr + i, 0);
gfar_write(baddr + i, priv->rx_queue[i]->rxic);
@@ -2021,7 +2017,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
/* setup the TxBD length and buffer pointer for the first BD */
- tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);
@@ -2053,6 +2048,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp_start->lstatus = lstatus;
+ eieio(); /* force lstatus write before tx_skbuff */
+
+ tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
+
/* Update the current skb pointer to the next entry we will use
* (wrapping if necessary) */
tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
@@ -2390,6 +2389,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev)
* as many bytes as needed to align the data properly
*/
skb_reserve(skb, alignamount);
+ GFAR_CB(skb)->alignamount = alignamount;
return skb;
}
@@ -2530,13 +2530,13 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
newskb = skb;
else if (skb) {
/*
- * We need to reset ->data to what it
+ * We need to un-reserve() the skb to what it
* was before gfar_new_skb() re-aligned
* it to an RXBUF_ALIGNMENT boundary
* before we put the skb back on the
* recycle list.
*/
- skb->data = skb->head + NET_SKB_PAD;
+ skb_reserve(skb, -GFAR_CB(skb)->alignamount);
__skb_queue_head(&priv->rx_recycle, skb);
}
} else {
@@ -2607,7 +2607,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
budget_per_queue = left_over_budget/num_queues;
left_over_budget = 0;
- for_each_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
+ for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
if (test_bit(i, &serviced_queues))
continue;
rx_queue = priv->rx_queue[i];
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 3d72dc43dca..17d25e71423 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -566,6 +566,12 @@ struct rxfcb {
u16 vlctl; /* VLAN control word */
};
+struct gianfar_skb_cb {
+ int alignamount;
+};
+
+#define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb))
+
struct rmon_mib
{
u32 tr64; /* 0x.680 - Transmit and Receive 64-byte Frame Counter */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 1010367695e..9bda023c023 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -19,7 +19,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index b98c6c51229..64f4094ac7f 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -24,7 +24,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 2b9c1cbc9ec..3a90430de91 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -34,6 +34,7 @@
#include <linux/mii.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <asm/cacheflush.h>
#include <asm/byteorder.h>
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 373546dd083..5d6f1387959 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -153,7 +153,6 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 689b9bd377a..4b52c767ad0 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -24,6 +24,7 @@
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/timer.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index bdadf3e23c9..14f01d156db 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -61,6 +61,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 9ee76b42668..52b14256e2c 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/sockios.h>
#include <linux/workqueue.h>
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 91c5790c958..b8bdf9d51cd 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -48,7 +48,6 @@
#include <linux/net.h>
#include <linux/in.h>
#include <linux/if.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/bitops.h>
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 7db0a1c3216..66e88bd59ca 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/inet.h>
+#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 35c936175bb..f3a96b84391 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -158,7 +158,6 @@
#include <linux/in.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index b766a69bf0c..4daad8cd56e 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -102,7 +102,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/eisa.h>
#include <linux/pci.h>
diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c
index 3e3528ade25..b6060f7538d 100644
--- a/drivers/net/hplance.c
+++ b/drivers/net/hplance.c
@@ -10,7 +10,6 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
index d496b6f4a47..24724b4ad70 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/hydra.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index fb0ac6d7c04..dd873cc41c2 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -39,6 +39,7 @@
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/io.h>
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h
index 18d56c6c423..b1cbe6fdfc7 100644
--- a/drivers/net/ibm_newemac/core.h
+++ b/drivers/net/ibm_newemac/core.h
@@ -34,6 +34,7 @@
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/dcr.h>
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c
index 2a2fc17b287..5b3d94419fe 100644
--- a/drivers/net/ibm_newemac/mal.c
+++ b/drivers/net/ibm_newemac/mal.c
@@ -26,6 +26,7 @@
*/
#include <linux/delay.h>
+#include <linux/slab.h>
#include "core.h"
#include <asm/dcr-regs.h>
diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c
index 8d76cb89dbd..5b90d34c845 100644
--- a/drivers/net/ibm_newemac/rgmii.c
+++ b/drivers/net/ibm_newemac/rgmii.c
@@ -21,6 +21,7 @@
* option) any later version.
*
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/ethtool.h>
#include <asm/io.h>
diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c
index 17b15412494..1f038f808ab 100644
--- a/drivers/net/ibm_newemac/zmii.c
+++ b/drivers/net/ibm_newemac/zmii.c
@@ -21,6 +21,7 @@
* option) any later version.
*
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/ethtool.h>
#include <asm/io.h>
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index b5d0f4e973f..7d6cf3340c1 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -79,7 +79,6 @@ History:
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/time.h>
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index f2b93796695..cd508a8ee25 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -49,6 +49,7 @@
#include <linux/proc_fs.h>
#include <linux/in.h>
#include <linux/ip.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <asm/hvcall.h>
#include <asm/atomic.h>
@@ -1577,7 +1578,7 @@ static struct attribute * veth_pool_attrs[] = {
NULL,
};
-static struct sysfs_ops veth_pool_ops = {
+static const struct sysfs_ops veth_pool_ops = {
.show = veth_pool_show,
.store = veth_pool_store,
};
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 9d7fa2fb85e..4a32bed77c7 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -30,7 +30,6 @@
*/
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/if_ether.h>
#include "e1000_mac.h"
@@ -94,6 +93,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
case E1000_DEV_ID_82576_FIBER:
case E1000_DEV_ID_82576_SERDES:
case E1000_DEV_ID_82576_QUAD_COPPER:
+ case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
case E1000_DEV_ID_82576_SERDES_QUAD:
mac->type = e1000_82576;
break;
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 448005276b2..82a533f5192 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -41,6 +41,7 @@ struct e1000_hw;
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
+#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526
#define E1000_DEV_ID_82576_NS 0x150A
#define E1000_DEV_ID_82576_NS_SERDES 0x1518
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 2a8a886b37e..be8d010e402 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -1367,7 +1367,8 @@ out:
* igb_enable_mng_pass_thru - Enable processing of ARP's
* @hw: pointer to the HW structure
*
- * Verifies the hardware needs to allow ARPs to be processed by the host.
+ * Verifies the hardware needs to leave interface enabled so that frames can
+ * be directed to and from the management interface.
**/
bool igb_enable_mng_pass_thru(struct e1000_hw *hw)
{
@@ -1380,8 +1381,7 @@ bool igb_enable_mng_pass_thru(struct e1000_hw *hw)
manc = rd32(E1000_MANC);
- if (!(manc & E1000_MANC_RCV_TCO_EN) ||
- !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
+ if (!(manc & E1000_MANC_RCV_TCO_EN))
goto out;
if (hw->mac.arc_subsystem_valid) {
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index a1775705b24..3b772b822a5 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -267,7 +267,6 @@ struct igb_adapter {
/* TX */
struct igb_ring *tx_ring[16];
- unsigned long tx_queue_len;
u32 tx_timeout_count;
/* RX */
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index a4cead12fd9..74303849010 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -35,6 +35,7 @@
#include <linux/if_ether.h>
#include <linux/ethtool.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "igb.h"
@@ -1813,6 +1814,7 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
retval = 0;
break;
case E1000_DEV_ID_82576_QUAD_COPPER:
+ case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
/* quad port adapters only support WoL on port A */
if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
wol->supported = 0;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 583a21c1def..c9baa2aa98c 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -32,6 +32,7 @@
#include <linux/pagemap.h>
#include <linux/netdevice.h>
#include <linux/ipv6.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include <linux/net_tstamp.h>
@@ -72,6 +73,7 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER_ET2), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
@@ -688,7 +690,7 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
/* start with one vector for every rx queue */
numvecs = adapter->num_rx_queues;
- /* if tx handler is seperate add 1 for every tx queue */
+ /* if tx handler is separate add 1 for every tx queue */
if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS))
numvecs += adapter->num_tx_queues;
@@ -1104,9 +1106,6 @@ static void igb_configure(struct igb_adapter *adapter)
struct igb_ring *ring = adapter->rx_ring[i];
igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring));
}
-
-
- adapter->tx_queue_len = netdev->tx_queue_len;
}
/**
@@ -1212,7 +1211,6 @@ void igb_down(struct igb_adapter *adapter)
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer);
- netdev->tx_queue_len = adapter->tx_queue_len;
netif_carrier_off(netdev);
/* record the stats before reset*/
@@ -1614,6 +1612,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
adapter->eeprom_wol = 0;
break;
case E1000_DEV_ID_82576_QUAD_COPPER:
+ case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
/* if quad port adapter, disable WoL on all but port A */
if (global_quad_port_a != 0)
adapter->eeprom_wol = 0;
@@ -3105,17 +3104,13 @@ static void igb_watchdog_task(struct work_struct *work)
((ctrl & E1000_CTRL_RFCE) ? "RX" :
((ctrl & E1000_CTRL_TFCE) ? "TX" : "None")));
- /* tweak tx_queue_len according to speed/duplex and
- * adjust the timeout factor */
- netdev->tx_queue_len = adapter->tx_queue_len;
+ /* adjust timeout factor according to speed/duplex */
adapter->tx_timeout_factor = 1;
switch (adapter->link_speed) {
case SPEED_10:
- netdev->tx_queue_len = 10;
adapter->tx_timeout_factor = 14;
break;
case SPEED_100:
- netdev->tx_queue_len = 100;
/* maybe add some timeout factor ? */
break;
}
@@ -3962,7 +3957,7 @@ void igb_update_stats(struct igb_adapter *adapter)
struct net_device_stats *net_stats = igb_get_stats(adapter->netdev);
struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
- u32 rnbc, reg;
+ u32 reg, mpc;
u16 phy_tmp;
int i;
u64 bytes, packets;
@@ -4020,7 +4015,9 @@ void igb_update_stats(struct igb_adapter *adapter)
adapter->stats.symerrs += rd32(E1000_SYMERRS);
adapter->stats.sec += rd32(E1000_SEC);
- adapter->stats.mpc += rd32(E1000_MPC);
+ mpc = rd32(E1000_MPC);
+ adapter->stats.mpc += mpc;
+ net_stats->rx_fifo_errors += mpc;
adapter->stats.scc += rd32(E1000_SCC);
adapter->stats.ecol += rd32(E1000_ECOL);
adapter->stats.mcc += rd32(E1000_MCC);
@@ -4035,9 +4032,7 @@ void igb_update_stats(struct igb_adapter *adapter)
adapter->stats.gptc += rd32(E1000_GPTC);
adapter->stats.gotc += rd32(E1000_GOTCL);
rd32(E1000_GOTCH); /* clear GOTCL */
- rnbc = rd32(E1000_RNBC);
- adapter->stats.rnbc += rnbc;
- net_stats->rx_fifo_errors += rnbc;
+ adapter->stats.rnbc += rd32(E1000_RNBC);
adapter->stats.ruc += rd32(E1000_RUC);
adapter->stats.rfc += rd32(E1000_RFC);
adapter->stats.rjc += rd32(E1000_RJC);
@@ -5109,7 +5104,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector,
{
struct igb_adapter *adapter = q_vector->adapter;
- if (vlan_tag)
+ if (vlan_tag && adapter->vlgrp)
vlan_gro_receive(&q_vector->napi, adapter->vlgrp,
vlan_tag, skb);
else
diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h
index a1774b29d22..debeee2dc71 100644
--- a/drivers/net/igbvf/igbvf.h
+++ b/drivers/net/igbvf/igbvf.h
@@ -198,7 +198,6 @@ struct igbvf_adapter {
struct igbvf_ring *tx_ring /* One per active queue */
____cacheline_aligned_in_smp;
- unsigned long tx_queue_len;
unsigned int restart_queue;
u32 txd_cmd;
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index a77afd8a14b..1b1edad1eb5 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -35,6 +35,7 @@
#include <linux/netdevice.h>
#include <linux/tcp.h>
#include <linux/ipv6.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include <linux/mii.h>
@@ -1304,8 +1305,6 @@ static void igbvf_configure_tx(struct igbvf_adapter *adapter)
/* enable Report Status bit */
adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS;
-
- adapter->tx_queue_len = adapter->netdev->tx_queue_len;
}
/**
@@ -1524,7 +1523,6 @@ void igbvf_down(struct igbvf_adapter *adapter)
del_timer_sync(&adapter->watchdog_timer);
- netdev->tx_queue_len = adapter->tx_queue_len;
netif_carrier_off(netdev);
/* record the stats before reset*/
@@ -1857,21 +1855,15 @@ static void igbvf_watchdog_task(struct work_struct *work)
&adapter->link_duplex);
igbvf_print_link_info(adapter);
- /*
- * tweak tx_queue_len according to speed/duplex
- * and adjust the timeout factor
- */
- netdev->tx_queue_len = adapter->tx_queue_len;
+ /* adjust timeout factor according to speed/duplex */
adapter->tx_timeout_factor = 1;
switch (adapter->link_speed) {
case SPEED_10:
txb2b = 0;
- netdev->tx_queue_len = 10;
adapter->tx_timeout_factor = 16;
break;
case SPEED_100:
txb2b = 0;
- netdev->tx_queue_len = 100;
/* maybe add some timeout factor ? */
break;
}
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 70871b9b045..8f6197d647c 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -44,6 +44,7 @@
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#ifdef CONFIG_SERIAL_8250
#include <linux/serial_core.h>
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 150415e83f6..639bf9fb027 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -22,6 +22,7 @@
*/
#include <linux/crc32.h>
#include <linux/ethtool.h>
+#include <linux/gfp.h>
#include <linux/mii.h>
#include <linux/mutex.h>
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 12c7b006f76..28992c815cb 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -22,6 +22,7 @@
********************************************************************/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -29,7 +30,6 @@
#include <linux/netdevice.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/serial_reg.h>
diff --git a/drivers/net/irda/bfin_sir.h b/drivers/net/irda/bfin_sir.h
index dac71b1f4f9..b54a6f08db4 100644
--- a/drivers/net/irda/bfin_sir.h
+++ b/drivers/net/irda/bfin_sir.h
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <net/irda/irda.h>
#include <net/irda/wrapper.h>
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index e8e33bb9d87..2c9b3af1661 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1651,6 +1651,8 @@ static int irda_usb_probe(struct usb_interface *intf,
self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *),
GFP_KERNEL);
+ if (!self->rx_urb)
+ goto err_free_net;
for (i = 0; i < self->max_rx_urb; i++) {
self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
@@ -1783,6 +1785,8 @@ err_out_2:
err_out_1:
for (i = 0; i < self->max_rx_urb; i++)
usb_free_urb(self->rx_urb[i]);
+ kfree(self->rx_urb);
+err_free_net:
free_netdev(net);
err_out:
return ret;
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 20f9bc62668..ee1dde52e8f 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/init.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 2413295ebd9..e30cdbb1474 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -43,6 +43,7 @@
********************************************************************/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -50,7 +51,6 @@
#include <linux/netdevice.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 84db145d2b5..1a54f6bb68c 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <net/irda/irda.h>
#include <net/irda/irmod.h>
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index c412e802617..1dcdce0631a 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -331,7 +331,7 @@ static int sa1100_irda_resume(struct platform_device *pdev)
* If we missed a speed change, initialise at the new speed
* directly. It is debatable whether this is actually
* required, but in the interests of continuing from where
- * we left off it is desireable. The converse argument is
+ * we left off it is desirable. The converse argument is
* that we should re-negotiate at 9600 baud again.
*/
if (si->newspeed) {
diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c
index d7c983dc91a..0745581c4b5 100644
--- a/drivers/net/irda/sh_sir.c
+++ b/drivers/net/irda/sh_sir.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda_device.h>
#include <asm/clock.h>
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 4b2a1a9eac2..de91cd14016 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 8f7d0d146f2..6af84d88cd0 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -48,13 +48,13 @@
#include <linux/netdevice.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/serial_reg.h>
#include <linux/dma-mapping.h>
#include <linux/pnp.h>
#include <linux/platform_device.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/dma.h>
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 6533c010cf5..b0a6cd815be 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -45,11 +45,11 @@ F02 Oct/28/02: Add SB device ID for 3147 and 3177.
#include <linux/netdevice.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/dma.h>
diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
index 551810fd297..cb0cb758be6 100644
--- a/drivers/net/irda/w83977af_ir.c
+++ b/drivers/net/irda/w83977af_ir.c
@@ -46,10 +46,10 @@
#include <linux/netdevice.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/dma.h>
@@ -65,7 +65,6 @@
#undef CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */
#define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */
#endif
-#undef CONFIG_USE_INTERNAL_TIMER /* Just cannot make that timer work */
#define CONFIG_USE_W977_PNP /* Currently needed */
#define PIO_MAX_SPEED 115200
@@ -533,25 +532,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
self->tx_buff.len = skb->len;
mtt = irda_get_mtt(skb);
-#ifdef CONFIG_USE_INTERNAL_TIMER
- if (mtt > 50) {
- /* Adjust for timer resolution */
- mtt /= 1000+1;
-
- /* Setup timer */
- switch_bank(iobase, SET4);
- outb(mtt & 0xff, iobase+TMRL);
- outb((mtt >> 8) & 0x0f, iobase+TMRH);
-
- /* Start timer */
- outb(IR_MSL_EN_TMR, iobase+IR_MSL);
- self->io.direction = IO_XMIT;
-
- /* Enable timer interrupt */
- switch_bank(iobase, SET0);
- outb(ICR_ETMRI, iobase+ICR);
- } else {
-#endif
IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
if (mtt)
udelay(mtt);
@@ -560,9 +540,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
switch_bank(iobase, SET0);
outb(ICR_EDMAI, iobase+ICR);
w83977af_dma_write(self, iobase);
-#ifdef CONFIG_USE_INTERNAL_TIMER
- }
-#endif
} else {
self->tx_buff.data = self->tx_buff.head;
self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data,
@@ -876,20 +853,7 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self)
/* Check if we have transferred all data to memory */
switch_bank(iobase, SET0);
if (inb(iobase+USR) & USR_RDR) {
-#ifdef CONFIG_USE_INTERNAL_TIMER
- /* Put this entry back in fifo */
- st_fifo->head--;
- st_fifo->len++;
- st_fifo->entries[st_fifo->head].status = status;
- st_fifo->entries[st_fifo->head].len = len;
-
- /* Restore set register */
- outb(set, iobase+SSR);
-
- return FALSE; /* I'll be back! */
-#else
udelay(80); /* Should be enough!? */
-#endif
}
skb = dev_alloc_skb(len+1);
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 966de5d6952..773c59c8969 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -69,6 +69,7 @@
#include <linux/mm.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>
+#include <linux/slab.h>
#include <asm/abs_addr.h>
#include <asm/iseries/mf.h>
@@ -384,7 +385,7 @@ static struct attribute *veth_cnx_default_attrs[] = {
NULL
};
-static struct sysfs_ops veth_cnx_sysfs_ops = {
+static const struct sysfs_ops veth_cnx_sysfs_ops = {
.show = veth_cnx_attribute_show
};
@@ -441,7 +442,7 @@ static struct attribute *veth_port_default_attrs[] = {
NULL
};
-static struct sysfs_ops veth_port_sysfs_ops = {
+static const struct sysfs_ops veth_port_sysfs_ops = {
.show = veth_port_attribute_show
};
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 19e94ee155a..79c35ae3718 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -204,14 +204,17 @@ enum ixgbe_ring_f_enum {
#define IXGBE_MAX_FDIR_INDICES 64
#ifdef IXGBE_FCOE
#define IXGBE_MAX_FCOE_INDICES 8
+#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES)
+#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES)
+#else
+#define MAX_RX_QUEUES IXGBE_MAX_FDIR_INDICES
+#define MAX_TX_QUEUES IXGBE_MAX_FDIR_INDICES
#endif /* IXGBE_FCOE */
struct ixgbe_ring_feature {
int indices;
int mask;
} ____cacheline_internodealigned_in_smp;
-#define MAX_RX_QUEUES 128
-#define MAX_TX_QUEUES 128
#define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \
? 8 : 1)
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 1f30e163bd9..12fc0e7ba2c 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -39,6 +39,9 @@
#define IXGBE_82599_MC_TBL_SIZE 128
#define IXGBE_82599_VFT_TBL_SIZE 128
+void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
@@ -68,7 +71,15 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
if (hw->phy.multispeed_fiber) {
/* Set up dual speed SFP+ support */
mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
+ mac->ops.disable_tx_laser =
+ &ixgbe_disable_tx_laser_multispeed_fiber;
+ mac->ops.enable_tx_laser =
+ &ixgbe_enable_tx_laser_multispeed_fiber;
+ mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber;
} else {
+ mac->ops.disable_tx_laser = NULL;
+ mac->ops.enable_tx_laser = NULL;
+ mac->ops.flap_tx_laser = NULL;
if ((mac->ops.get_media_type(hw) ==
ixgbe_media_type_backplane) &&
(hw->phy.smart_speed == ixgbe_smart_speed_auto ||
@@ -412,6 +423,67 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
return status;
}
+ /**
+ * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
+ * @hw: pointer to hardware structure
+ *
+ * The base drivers may require better control over SFP+ module
+ * PHY states. This includes selectively shutting down the Tx
+ * laser on the PHY, effectively halting physical link.
+ **/
+void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+ u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+ /* Disable tx laser; allow 100us to go dark per spec */
+ esdp_reg |= IXGBE_ESDP_SDP3;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(100);
+}
+
+/**
+ * ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser
+ * @hw: pointer to hardware structure
+ *
+ * The base drivers may require better control over SFP+ module
+ * PHY states. This includes selectively turning on the Tx
+ * laser on the PHY, effectively starting physical link.
+ **/
+void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+ u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+ /* Enable tx laser; allow 100ms to light up */
+ esdp_reg &= ~IXGBE_ESDP_SDP3;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ IXGBE_WRITE_FLUSH(hw);
+ msleep(100);
+}
+
+/**
+ * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser
+ * @hw: pointer to hardware structure
+ *
+ * When the driver changes the link speeds that it can support,
+ * it sets autotry_restart to true to indicate that we need to
+ * initiate a new autotry session with the link partner. To do
+ * so, we set the speed then disable and re-enable the tx laser, to
+ * alert the link partner that it also needs to restart autotry on its
+ * end. This is consistent with true clause 37 autoneg, which also
+ * involves a loss of signal.
+ **/
+void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+ hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n");
+
+ if (hw->mac.autotry_restart) {
+ ixgbe_disable_tx_laser_multispeed_fiber(hw);
+ ixgbe_enable_tx_laser_multispeed_fiber(hw);
+ hw->mac.autotry_restart = false;
+ }
+}
+
/**
* ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
* @hw: pointer to hardware structure
@@ -440,16 +512,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
speed &= phy_link_speed;
/*
- * When the driver changes the link speeds that it can support,
- * it sets autotry_restart to true to indicate that we need to
- * initiate a new autotry session with the link partner. To do
- * so, we set the speed then disable and re-enable the tx laser, to
- * alert the link partner that it also needs to restart autotry on its
- * end. This is consistent with true clause 37 autoneg, which also
- * involves a loss of signal.
- */
-
- /*
* Try each speed one by one, highest priority first. We do this in
* software because 10gb fiber doesn't support speed autonegotiation.
*/
@@ -466,6 +528,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
/* Set the module link speed */
esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ IXGBE_WRITE_FLUSH(hw);
/* Allow module to change analog characteristics (1G->10G) */
msleep(40);
@@ -478,19 +541,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
return status;
/* Flap the tx laser if it has not already been done */
- if (hw->mac.autotry_restart) {
- /* Disable tx laser; allow 100us to go dark per spec */
- esdp_reg |= IXGBE_ESDP_SDP3;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- udelay(100);
-
- /* Enable tx laser; allow 2ms to light up per spec */
- esdp_reg &= ~IXGBE_ESDP_SDP3;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- msleep(2);
-
- hw->mac.autotry_restart = false;
- }
+ hw->mac.ops.flap_tx_laser(hw);
/*
* Wait for the controller to acquire link. Per IEEE 802.3ap,
@@ -525,6 +576,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
esdp_reg &= ~IXGBE_ESDP_SDP5;
esdp_reg |= IXGBE_ESDP_SDP5_DIR;
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ IXGBE_WRITE_FLUSH(hw);
/* Allow module to change analog characteristics (10G->1G) */
msleep(40);
@@ -537,19 +589,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
return status;
/* Flap the tx laser if it has not already been done */
- if (hw->mac.autotry_restart) {
- /* Disable tx laser; allow 100us to go dark per spec */
- esdp_reg |= IXGBE_ESDP_SDP3;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- udelay(100);
-
- /* Enable tx laser; allow 2ms to light up per spec */
- esdp_reg &= ~IXGBE_ESDP_SDP3;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- msleep(2);
-
- hw->mac.autotry_restart = false;
- }
+ hw->mac.ops.flap_tx_laser(hw);
/* Wait for the link partner to also set speed */
msleep(100);
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 7949a446e4c..8f461d5cee7 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
@@ -1853,6 +1854,26 @@ static void ixgbe_diag_test(struct net_device *netdev,
if (ixgbe_link_test(adapter, &data[4]))
eth_test->flags |= ETH_TEST_FL_FAILED;
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ int i;
+ for (i = 0; i < adapter->num_vfs; i++) {
+ if (adapter->vfinfo[i].clear_to_send) {
+ netdev_warn(netdev, "%s",
+ "offline diagnostic is not "
+ "supported when VFs are "
+ "present\n");
+ data[0] = 1;
+ data[1] = 1;
+ data[2] = 1;
+ data[3] = 1;
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+ clear_bit(__IXGBE_TESTING,
+ &adapter->state);
+ goto skip_ol_tests;
+ }
+ }
+ }
+
if (if_running)
/* indicate we're in test mode */
dev_close(netdev);
@@ -1908,6 +1929,7 @@ skip_loopback:
clear_bit(__IXGBE_TESTING, &adapter->state);
}
+skip_ol_tests:
msleep_interruptible(4 * 1000);
}
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 4123dec0dfb..6493049b663 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -31,6 +31,7 @@
#include "ixgbe_dcb_82599.h"
#endif /* CONFIG_IXGBE_DCB */
#include <linux/if_ether.h>
+#include <linux/gfp.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/fc/fc_fs.h>
@@ -202,6 +203,15 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
addr = sg_dma_address(sg);
len = sg_dma_len(sg);
while (len) {
+ /* max number of buffers allowed in one DDP context */
+ if (j >= IXGBE_BUFFCNT_MAX) {
+ netif_err(adapter, drv, adapter->netdev,
+ "xid=%x:%d,%d,%d:addr=%llx "
+ "not enough descriptors\n",
+ xid, i, j, dmacount, (u64)addr);
+ goto out_noddp_free;
+ }
+
/* get the offset of length of current buffer */
thisoff = addr & ((dma_addr_t)bufflen - 1);
thislen = min((bufflen - thisoff), len);
@@ -227,20 +237,13 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
len -= thislen;
addr += thislen;
j++;
- /* max number of buffers allowed in one DDP context */
- if (j > IXGBE_BUFFCNT_MAX) {
- DPRINTK(DRV, ERR, "xid=%x:%d,%d,%d:addr=%llx "
- "not enough descriptors\n",
- xid, i, j, dmacount, (u64)addr);
- goto out_noddp_free;
- }
}
}
/* only the last buffer may have non-full bufflen */
lastsize = thisoff + thislen;
fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
- fcbuff |= (j << IXGBE_FCBUFF_BUFFCNT_SHIFT);
+ fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
fcbuff |= (IXGBE_FCBUFF_VALID);
@@ -520,6 +523,9 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
/* Enable L2 eth type filter for FCoE */
IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE),
(ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN));
+ /* Enable L2 eth type filter for FIP */
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP),
+ (ETH_P_FIP | IXGBE_ETQF_FILTER_EN));
if (adapter->ring_feature[RING_F_FCOE].indices) {
/* Use multiple rx queues for FCoE by redirection table */
for (i = 0; i < IXGBE_FCRETA_SIZE; i++) {
@@ -530,6 +536,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
}
IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA);
IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
+ fcoe_i = f->mask;
+ fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;
+ fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
+ IXGBE_ETQS_QUEUE_EN |
+ (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
} else {
/* Use single rx queue for FCoE */
fcoe_i = f->mask;
@@ -539,6 +551,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
IXGBE_ETQS_QUEUE_EN |
(fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
}
+ /* send FIP frames to the first FCoE queue */
+ fcoe_i = f->mask;
+ fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
+ IXGBE_ETQS_QUEUE_EN |
+ (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL,
IXGBE_FCRXCTRL_FCOELLI |
@@ -614,9 +632,9 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
netdev->vlan_features |= NETIF_F_FSO;
netdev->vlan_features |= NETIF_F_FCOE_MTU;
netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
- netdev_features_change(netdev);
ixgbe_init_interrupt_scheme(adapter);
+ netdev_features_change(netdev);
if (netif_running(netdev))
netdev->netdev_ops->ndo_open(netdev);
@@ -660,11 +678,11 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
netdev->vlan_features &= ~NETIF_F_FSO;
netdev->vlan_features &= ~NETIF_F_FCOE_MTU;
netdev->fcoe_ddp_xid = 0;
- netdev_features_change(netdev);
ixgbe_cleanup_fcoe(adapter);
-
ixgbe_init_interrupt_scheme(adapter);
+ netdev_features_change(netdev);
+
if (netif_running(netdev))
netdev->netdev_ops->ndo_open(netdev);
rc = 0;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 45e3532b166..6c00ee493a3 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -36,6 +36,7 @@
#include <linux/tcp.h>
#include <linux/pkt_sched.h>
#include <linux/ipv6.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include <linux/ethtool.h>
@@ -935,10 +936,12 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (skb->prev)
skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count));
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
- if (IXGBE_RSC_CB(skb)->dma)
+ if (IXGBE_RSC_CB(skb)->dma) {
pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma,
rx_ring->rx_buf_len,
PCI_DMA_FROMDEVICE);
+ IXGBE_RSC_CB(skb)->dma = 0;
+ }
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
rx_ring->rsc_count += skb_shinfo(skb)->nr_frags;
else
@@ -1050,7 +1053,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
*/
for (v_idx = 0; v_idx < q_vectors; v_idx++) {
q_vector = adapter->q_vector[v_idx];
- /* XXX for_each_bit(...) */
+ /* XXX for_each_set_bit(...) */
r_idx = find_first_bit(q_vector->rxr_idx,
adapter->num_rx_queues);
@@ -2979,6 +2982,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
else
ixgbe_configure_msi_and_legacy(adapter);
+ /* enable the optics */
+ if (hw->phy.multispeed_fiber)
+ hw->mac.ops.enable_tx_laser(hw);
+
clear_bit(__IXGBE_DOWN, &adapter->state);
ixgbe_napi_enable_all(adapter);
@@ -3054,6 +3061,14 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
msleep(1);
ixgbe_down(adapter);
+ /*
+ * If SR-IOV enabled then wait a bit before bringing the adapter
+ * back up to give the VFs time to respond to the reset. The
+ * two second wait is based upon the watchdog timer cycle in
+ * the VF driver.
+ */
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+ msleep(2000);
ixgbe_up(adapter);
clear_bit(__IXGBE_RESETTING, &adapter->state);
}
@@ -3126,10 +3141,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_buffer_info->skb = NULL;
do {
struct sk_buff *this = skb;
- if (IXGBE_RSC_CB(this)->dma)
+ if (IXGBE_RSC_CB(this)->dma) {
pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma,
rx_ring->rx_buf_len,
PCI_DMA_FROMDEVICE);
+ IXGBE_RSC_CB(this)->dma = 0;
+ }
skb = skb->prev;
dev_kfree_skb(this);
} while (skb);
@@ -3230,15 +3247,21 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
/* signal that we are down to the interrupt handler */
set_bit(__IXGBE_DOWN, &adapter->state);
+ /* power down the optics */
+ if (hw->phy.multispeed_fiber)
+ hw->mac.ops.disable_tx_laser(hw);
+
/* disable receive for all VFs and wait one second */
if (adapter->num_vfs) {
- for (i = 0 ; i < adapter->num_vfs; i++)
- adapter->vfinfo[i].clear_to_send = 0;
-
/* ping all the active vfs to let them know we are going down */
ixgbe_ping_all_vfs(adapter);
+
/* Disable all VFTE/VFRE TX/RX */
ixgbe_disable_tx_rx(adapter);
+
+ /* Mark all the VFs as inactive */
+ for (i = 0 ; i < adapter->num_vfs; i++)
+ adapter->vfinfo[i].clear_to_send = 0;
}
/* disable receives */
@@ -5018,6 +5041,7 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work)
autoneg = hw->phy.autoneg_advertised;
if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+ hw->mac.autotry_restart = false;
if (hw->mac.ops.setup_link)
hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -5633,7 +5657,8 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
#ifdef IXGBE_FCOE
if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
- (skb->protocol == htons(ETH_P_FCOE))) {
+ ((skb->protocol == htons(ETH_P_FCOE)) ||
+ (skb->protocol == htons(ETH_P_FIP)))) {
txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
txq += adapter->ring_feature[RING_F_FCOE].mask;
return txq;
@@ -5680,18 +5705,25 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
tx_ring = adapter->tx_ring[skb->queue_mapping];
- if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
- (skb->protocol == htons(ETH_P_FCOE))) {
- tx_flags |= IXGBE_TX_FLAGS_FCOE;
#ifdef IXGBE_FCOE
+ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
#ifdef CONFIG_IXGBE_DCB
- tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
- << IXGBE_TX_FLAGS_VLAN_SHIFT);
- tx_flags |= ((adapter->fcoe.up << 13)
- << IXGBE_TX_FLAGS_VLAN_SHIFT);
-#endif
+ /* for FCoE with DCB, we force the priority to what
+ * was specified by the switch */
+ if ((skb->protocol == htons(ETH_P_FCOE)) ||
+ (skb->protocol == htons(ETH_P_FIP))) {
+ tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
+ << IXGBE_TX_FLAGS_VLAN_SHIFT);
+ tx_flags |= ((adapter->fcoe.up << 13)
+ << IXGBE_TX_FLAGS_VLAN_SHIFT);
+ }
#endif
+ /* flag for FCoE offloads */
+ if (skb->protocol == htons(ETH_P_FCOE))
+ tx_flags |= IXGBE_TX_FLAGS_FCOE;
}
+#endif
+
/* four things can cause us to need a context descriptor */
if (skb_is_gso(skb) ||
(skb->ip_summed == CHECKSUM_PARTIAL) ||
@@ -6046,7 +6078,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
indices += min_t(unsigned int, num_possible_cpus(),
IXGBE_MAX_FCOE_INDICES);
#endif
- indices = min_t(unsigned int, indices, MAX_TX_QUEUES);
netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
if (!netdev) {
err = -ENOMEM;
@@ -6230,6 +6261,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
goto err_eeprom;
}
+ /* power down the optics */
+ if (hw->phy.multispeed_fiber)
+ hw->mac.ops.disable_tx_laser(hw);
+
init_timer(&adapter->watchdog_timer);
adapter->watchdog_timer.function = &ixgbe_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
@@ -6245,9 +6280,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
case IXGBE_DEV_ID_82599_KX4:
adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
IXGBE_WUFC_MC | IXGBE_WUFC_BC);
- /* Enable ACPI wakeup in GRC */
- IXGBE_WRITE_REG(hw, IXGBE_GRC,
- (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME));
break;
default:
adapter->wol = 0;
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 2be90746659..534affcc38c 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1298,6 +1298,7 @@
#define IXGBE_ETQF_FILTER_BCN 1
#define IXGBE_ETQF_FILTER_FCOE 2
#define IXGBE_ETQF_FILTER_1588 3
+#define IXGBE_ETQF_FILTER_FIP 4
/* VLAN Control Bit Masks */
#define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */
#define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */
@@ -2397,6 +2398,9 @@ struct ixgbe_mac_operations {
s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
/* Link */
+ void (*disable_tx_laser)(struct ixgbe_hw *);
+ void (*enable_tx_laser)(struct ixgbe_hw *);
+ void (*flap_tx_laser)(struct ixgbe_hw *);
s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index 399be0c34c3..4680b069b84 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
@@ -46,22 +47,32 @@ struct ixgbe_stats {
int sizeof_stat;
int stat_offset;
int base_stat_offset;
+ int saved_reset_offset;
};
-#define IXGBEVF_STAT(m, b) sizeof(((struct ixgbevf_adapter *)0)->m), \
- offsetof(struct ixgbevf_adapter, m), \
- offsetof(struct ixgbevf_adapter, b)
+#define IXGBEVF_STAT(m, b, r) sizeof(((struct ixgbevf_adapter *)0)->m), \
+ offsetof(struct ixgbevf_adapter, m), \
+ offsetof(struct ixgbevf_adapter, b), \
+ offsetof(struct ixgbevf_adapter, r)
static struct ixgbe_stats ixgbe_gstrings_stats[] = {
- {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc)},
- {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc)},
- {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc)},
- {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc)},
- {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base)},
- {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc)},
- {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base)},
- {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base)},
- {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base)},
- {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base)},
+ {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc,
+ stats.saved_reset_vfgprc)},
+ {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc,
+ stats.saved_reset_vfgptc)},
+ {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc,
+ stats.saved_reset_vfgorc)},
+ {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc,
+ stats.saved_reset_vfgotc)},
+ {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base, zero_base)},
+ {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc,
+ stats.saved_reset_vfmprc)},
+ {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base,
+ zero_base)},
+ {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base,
+ zero_base)},
+ {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base,
+ zero_base)},
+ {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)},
};
#define IXGBE_QUEUE_STATS_LEN 0
@@ -455,10 +466,14 @@ static void ixgbevf_get_ethtool_stats(struct net_device *netdev,
ixgbe_gstrings_stats[i].stat_offset;
char *b = (char *)adapter +
ixgbe_gstrings_stats[i].base_stat_offset;
+ char *r = (char *)adapter +
+ ixgbe_gstrings_stats[i].saved_reset_offset;
data[i] = ((ixgbe_gstrings_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p) -
((ixgbe_gstrings_stats[i].sizeof_stat ==
- sizeof(u64)) ? *(u64 *)b : *(u32 *)b);
+ sizeof(u64)) ? *(u64 *)b : *(u32 *)b) +
+ ((ixgbe_gstrings_stats[i].sizeof_stat ==
+ sizeof(u64)) ? *(u64 *)r : *(u32 *)r);
}
}
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 235b5fd4b8d..0cd6202dfac 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -39,6 +39,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/ipv6.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include <linux/ethtool.h>
@@ -751,7 +752,7 @@ static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
*/
for (v_idx = 0; v_idx < q_vectors; v_idx++) {
q_vector = adapter->q_vector[v_idx];
- /* XXX for_each_bit(...) */
+ /* XXX for_each_set_bit(...) */
r_idx = find_first_bit(q_vector->rxr_idx,
adapter->num_rx_queues);
@@ -965,7 +966,7 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + 10));
+ round_jiffies(jiffies + 1));
return IRQ_HANDLED;
}
@@ -1610,6 +1611,44 @@ static inline void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter,
(adapter->rx_ring[rxr].count - 1));
}
+static void ixgbevf_save_reset_stats(struct ixgbevf_adapter *adapter)
+{
+ /* Only save pre-reset stats if there are some */
+ if (adapter->stats.vfgprc || adapter->stats.vfgptc) {
+ adapter->stats.saved_reset_vfgprc += adapter->stats.vfgprc -
+ adapter->stats.base_vfgprc;
+ adapter->stats.saved_reset_vfgptc += adapter->stats.vfgptc -
+ adapter->stats.base_vfgptc;
+ adapter->stats.saved_reset_vfgorc += adapter->stats.vfgorc -
+ adapter->stats.base_vfgorc;
+ adapter->stats.saved_reset_vfgotc += adapter->stats.vfgotc -
+ adapter->stats.base_vfgotc;
+ adapter->stats.saved_reset_vfmprc += adapter->stats.vfmprc -
+ adapter->stats.base_vfmprc;
+ }
+}
+
+static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC);
+ adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB);
+ adapter->stats.last_vfgorc |=
+ (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32);
+ adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC);
+ adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB);
+ adapter->stats.last_vfgotc |=
+ (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32);
+ adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC);
+
+ adapter->stats.base_vfgprc = adapter->stats.last_vfgprc;
+ adapter->stats.base_vfgorc = adapter->stats.last_vfgorc;
+ adapter->stats.base_vfgptc = adapter->stats.last_vfgptc;
+ adapter->stats.base_vfgotc = adapter->stats.last_vfgotc;
+ adapter->stats.base_vfmprc = adapter->stats.last_vfmprc;
+}
+
static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
@@ -1656,6 +1695,9 @@ static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(netdev);
+ ixgbevf_save_reset_stats(adapter);
+ ixgbevf_init_last_counter_stats(adapter);
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -2228,27 +2270,6 @@ out:
return err;
}
-static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
-
- adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC);
- adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB);
- adapter->stats.last_vfgorc |=
- (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32);
- adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC);
- adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB);
- adapter->stats.last_vfgotc |=
- (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32);
- adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC);
-
- adapter->stats.base_vfgprc = adapter->stats.last_vfgprc;
- adapter->stats.base_vfgorc = adapter->stats.last_vfgorc;
- adapter->stats.base_vfgptc = adapter->stats.last_vfgptc;
- adapter->stats.base_vfgotc = adapter->stats.last_vfgotc;
- adapter->stats.base_vfmprc = adapter->stats.last_vfmprc;
-}
-
#define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter) \
{ \
u32 current_counter = IXGBE_READ_REG(hw, reg); \
@@ -2399,7 +2420,7 @@ static void ixgbevf_watchdog_task(struct work_struct *work)
if (!netif_carrier_ok(netdev)) {
hw_dbg(&adapter->hw, "NIC Link is Up %s, ",
((link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
- "10 Gbps" : "1 Gbps"));
+ "10 Gbps\n" : "1 Gbps\n"));
netif_carrier_on(netdev);
netif_tx_wake_all_queues(netdev);
} else {
@@ -2416,9 +2437,9 @@ static void ixgbevf_watchdog_task(struct work_struct *work)
}
}
-pf_has_reset:
ixgbevf_update_stats(adapter);
+pf_has_reset:
/* Force detection of hung controller every watchdog period */
adapter->detect_tx_hung = true;
@@ -2675,7 +2696,7 @@ static int ixgbevf_open(struct net_device *netdev)
if (hw->adapter_stopped) {
err = IXGBE_ERR_MBX;
printk(KERN_ERR "Unable to start - perhaps the PF"
- "Driver isn't up yet\n");
+ " Driver isn't up yet\n");
goto err_setup_reset;
}
}
@@ -2923,9 +2944,10 @@ static int ixgbevf_tx_map(struct ixgbevf_adapter *adapter,
struct ixgbevf_tx_buffer *tx_buffer_info;
unsigned int len;
unsigned int total = skb->len;
- unsigned int offset = 0, size, count = 0, i;
+ unsigned int offset = 0, size, count = 0;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
+ int i;
i = tx_ring->next_to_use;
@@ -3390,8 +3412,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
/* setup the private structure */
err = ixgbevf_sw_init(adapter);
- ixgbevf_init_last_counter_stats(adapter);
-
#ifdef MAX_SKB_FRAGS
netdev->features = NETIF_F_SG |
NETIF_F_IP_CSUM |
@@ -3449,6 +3469,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
adapter->netdev_registered = true;
+ ixgbevf_init_last_counter_stats(adapter);
+
/* print the MAC address */
hw_dbg(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
netdev->dev_addr[0],
diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h
index 799600e9270..1f31b052d4b 100644
--- a/drivers/net/ixgbevf/vf.h
+++ b/drivers/net/ixgbevf/vf.h
@@ -157,6 +157,12 @@ struct ixgbevf_hw_stats {
u64 vfgorc;
u64 vfgotc;
u64 vfmprc;
+
+ u64 saved_reset_vfgprc;
+ u64 saved_reset_vfgptc;
+ u64 saved_reset_vfgorc;
+ u64 saved_reset_vfgotc;
+ u64 saved_reset_vfmprc;
};
struct ixgbevf_info {
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index e9d9d595e1b..d5932ca3e27 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -15,6 +15,7 @@
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
+#include <linux/gfp.h>
#include <asm/hardware/uengine.h>
#include <asm/io.h>
#include "ixp2400_rx.ucode"
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index f47d4d663b1..3e6aaf9e5ce 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -22,11 +22,11 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fcntl.h>
+#include <linux/gfp.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
@@ -35,6 +35,7 @@
#include <linux/skbuff.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/bootinfo.h>
#include <asm/system.h>
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 0f31497833d..b705ad3a53a 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -37,6 +37,7 @@
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/if_vlan.h>
+#include <linux/slab.h>
#include <net/ip6_checksum.h>
#include "jme.h"
@@ -946,6 +947,8 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
jme->jme_vlan_rx(skb, jme->vlgrp,
le16_to_cpu(rxdesc->descwb.vlan));
NET_STAT(jme).rx_bytes += 4;
+ } else {
+ dev_kfree_skb(skb);
}
} else {
jme->jme_rx(skb);
@@ -2081,12 +2084,45 @@ jme_tx_timeout(struct net_device *netdev)
jme_reset_link(jme);
}
+static inline void jme_pause_rx(struct jme_adapter *jme)
+{
+ atomic_dec(&jme->link_changing);
+
+ jme_set_rx_pcc(jme, PCC_OFF);
+ if (test_bit(JME_FLAG_POLL, &jme->flags)) {
+ JME_NAPI_DISABLE(jme);
+ } else {
+ tasklet_disable(&jme->rxclean_task);
+ tasklet_disable(&jme->rxempty_task);
+ }
+}
+
+static inline void jme_resume_rx(struct jme_adapter *jme)
+{
+ struct dynpcc_info *dpi = &(jme->dpi);
+
+ if (test_bit(JME_FLAG_POLL, &jme->flags)) {
+ JME_NAPI_ENABLE(jme);
+ } else {
+ tasklet_hi_enable(&jme->rxclean_task);
+ tasklet_hi_enable(&jme->rxempty_task);
+ }
+ dpi->cur = PCC_P1;
+ dpi->attempt = PCC_P1;
+ dpi->cnt = 0;
+ jme_set_rx_pcc(jme, PCC_P1);
+
+ atomic_inc(&jme->link_changing);
+}
+
static void
jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
{
struct jme_adapter *jme = netdev_priv(netdev);
+ jme_pause_rx(jme);
jme->vlgrp = grp;
+ jme_resume_rx(jme);
}
static void
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index c19db9146a2..07ad3a45718 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -25,7 +25,7 @@
#define __JME_H_INCLUDED__
#define DRV_NAME "jme"
-#define DRV_VERSION "1.0.5"
+#define DRV_VERSION "1.0.6"
#define PFX DRV_NAME ": "
#define PCI_DEVICE_ID_JMICRON_JMC250 0x0250
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c
index b5219cce12e..9e9f9b34976 100644
--- a/drivers/net/ks8851.c
+++ b/drivers/net/ks8851.c
@@ -407,7 +407,7 @@ static irqreturn_t ks8851_irq(int irq, void *pw)
* @buff: The buffer address
* @len: The length of the data to read
*
- * Issue an RXQ FIFO read command and read the @len ammount of data from
+ * Issue an RXQ FIFO read command and read the @len amount of data from
* the FIFO into the buffer specified by @buff.
*/
static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len)
@@ -722,12 +722,14 @@ static void ks8851_tx_work(struct work_struct *work)
txb = skb_dequeue(&ks->txq);
last = skb_queue_empty(&ks->txq);
- ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
- ks8851_wrpkt(ks, txb, last);
- ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
- ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
+ if (txb != NULL) {
+ ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
+ ks8851_wrpkt(ks, txb, last);
+ ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
+ ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
- ks8851_done_tx(ks, txb);
+ ks8851_done_tx(ks, txb);
+ }
}
mutex_unlock(&ks->lock);
@@ -976,7 +978,6 @@ static void ks8851_set_rx_mode(struct net_device *dev)
crc >>= (32 - 6); /* get top six bits */
rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf));
- mcptr = mcptr->next;
}
rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA;
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
index 84b0e15831f..6354ab3a45a 100644
--- a/drivers/net/ks8851_mll.c
+++ b/drivers/net/ks8851_mll.c
@@ -31,6 +31,7 @@
#include <linux/mii.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#define DRV_NAME "ks8851_mll"
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 7264a3e5c2c..0606a1f359f 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -30,6 +30,7 @@
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/sched.h>
+#include <linux/slab.h>
/* DMA Registers */
@@ -4899,8 +4900,10 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev)
struct sk_buff *org_skb = skb;
skb = dev_alloc_skb(org_skb->len);
- if (!skb)
- return NETDEV_TX_BUSY;
+ if (!skb) {
+ rc = NETDEV_TX_BUSY;
+ goto unlock;
+ }
skb_copy_and_csum_dev(org_skb, skb->data);
org_skb->ip_summed = 0;
skb->len = org_skb->len;
@@ -4914,7 +4917,7 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
rc = NETDEV_TX_BUSY;
}
-
+unlock:
spin_unlock_irq(&hw_priv->hwlock);
return rc;
@@ -6320,7 +6323,7 @@ static int netdev_set_eeprom(struct net_device *dev,
int len;
if (eeprom->magic != EEPROM_MAGIC)
- return 1;
+ return -EINVAL;
len = (eeprom->offset + eeprom->len + 1) / 2;
for (i = eeprom->offset / 2; i < len; i++)
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index b77238dbafb..6eba352c52e 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -74,7 +74,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
index 443c39a3732..973390b82ec 100644
--- a/drivers/net/lib82596.c
+++ b/drivers/net/lib82596.c
@@ -73,7 +73,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
@@ -85,6 +84,7 @@
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/gfp.h>
/* DEBUG flags
*/
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index a18e3485476..ba617e3cf1b 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -49,6 +49,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
+#include <linux/slab.h>
#include "ll_temac.h"
diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c
index da0e462308d..5ae28c975b3 100644
--- a/drivers/net/ll_temac_mdio.c
+++ b/drivers/net/ll_temac_mdio.c
@@ -10,6 +10,7 @@
#include <linux/phy.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/slab.h>
#include <linux/of_mdio.h>
#include "ll_temac.h"
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index a8768672dc5..c8e68fde066 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -28,7 +28,6 @@
#include <linux/ioport.h>
#include <linux/nubus.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
index c292a608f9a..c0876e915ee 100644
--- a/drivers/net/mac89x0.c
+++ b/drivers/net/mac89x0.c
@@ -88,7 +88,6 @@ static char *version =
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/nubus.h>
#include <linux/errno.h>
@@ -98,6 +97,7 @@ static char *version =
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index ab5f0bf6d1a..962c41d0c8d 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -16,6 +16,7 @@
#include <linux/crc32.h>
#include <linux/spinlock.h>
#include <linux/bitrev.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.h>
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c
index 13ba8f4afb7..52e9a51c4c4 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/macmace.c
@@ -30,6 +30,7 @@
#include <linux/bitrev.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/macintosh.h>
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 24109c28810..adb54fe2d82 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -35,11 +35,11 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fcntl.h>
+#include <linux/gfp.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/nubus.h>
@@ -50,6 +50,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/bitrev.h>
+#include <linux/slab.h>
#include <asm/bootinfo.h>
#include <asm/system.h>
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 55ceae09738..abba3cc81f1 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -9,6 +9,7 @@
#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/cdev.h>
diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c
index 65ec77dc31f..23cee7b6af9 100644
--- a/drivers/net/mlx4/cmd.c
+++ b/drivers/net/mlx4/cmd.c
@@ -33,6 +33,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/errno.h>
diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c
index ccfe276943f..7cd34e9c7c7 100644
--- a/drivers/net/mlx4/cq.c
+++ b/drivers/net/mlx4/cq.c
@@ -35,6 +35,7 @@
*/
#include <linux/hardirq.h>
+#include <linux/gfp.h>
#include <linux/mlx4/cmd.h>
#include <linux/mlx4/cq.h>
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 507e11fce9e..cbabf14f95d 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/mlx4/driver.h>
#include <linux/mlx4/device.h>
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index c48b0f4b17b..73c3d20c645 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -35,6 +35,7 @@
#include <linux/tcp.h>
#include <linux/if_vlan.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/mlx4/driver.h>
#include <linux/mlx4/device.h>
diff --git a/drivers/net/mlx4/en_resources.c b/drivers/net/mlx4/en_resources.c
index 16256784a94..0dfb4ec8a9d 100644
--- a/drivers/net/mlx4/en_resources.c
+++ b/drivers/net/mlx4/en_resources.c
@@ -31,6 +31,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mlx4/qp.h>
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 64394647ddd..8e2fcb7103c 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -32,6 +32,7 @@
*/
#include <linux/mlx4/cq.h>
+#include <linux/slab.h>
#include <linux/mlx4/qp.h>
#include <linux/skbuff.h>
#include <linux/if_ether.h>
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 3d1396af946..580968f304e 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -33,6 +33,7 @@
#include <asm/page.h>
#include <linux/mlx4/cq.h>
+#include <linux/slab.h>
#include <linux/mlx4/qp.h>
#include <linux/skbuff.h>
#include <linux/if_vlan.h>
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index bffb7995cb7..7365bf488b8 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -32,6 +32,7 @@
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 04b382fcb8c..57288ca1395 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -34,6 +34,7 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <linux/mlx4/cmd.h>
diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c
index 0e7eb1038f9..55506780275 100644
--- a/drivers/net/mlx4/intf.c
+++ b/drivers/net/mlx4/intf.c
@@ -31,6 +31,8 @@
* SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "mlx4.h"
struct mlx4_device_context {
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 8f6e816a739..e3e0d54a7c8 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -38,6 +38,7 @@
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/mlx4/device.h>
#include <linux/mlx4/doorbell.h>
@@ -1023,6 +1024,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
info->port_attr.attr.mode = S_IRUGO | S_IWUSR;
info->port_attr.show = show_port_type;
info->port_attr.store = set_port_type;
+ sysfs_attr_init(&info->port_attr.attr);
err = device_create_file(&dev->pdev->dev, &info->port_attr);
if (err) {
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index 5ccbce9866f..c4f88b7ef7b 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -32,7 +32,6 @@
*/
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/mlx4/cmd.h>
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index ca7ab8e7b4c..3dc69be4949 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -33,6 +33,7 @@
*/
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/mlx4/cmd.h>
diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c
index ca25b9dc837..5caf0115fa5 100644
--- a/drivers/net/mlx4/profile.c
+++ b/drivers/net/mlx4/profile.c
@@ -32,6 +32,8 @@
* SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "mlx4.h"
#include "fw.h"
diff --git a/drivers/net/mlx4/qp.c b/drivers/net/mlx4/qp.c
index 42ab9fc01d3..ec9350e5f21 100644
--- a/drivers/net/mlx4/qp.c
+++ b/drivers/net/mlx4/qp.c
@@ -33,6 +33,7 @@
* SOFTWARE.
*/
+#include <linux/gfp.h>
#include <linux/mlx4/cmd.h>
#include <linux/mlx4/qp.h>
diff --git a/drivers/net/mlx4/srq.c b/drivers/net/mlx4/srq.c
index 1377d0dc8f1..3b07b80a045 100644
--- a/drivers/net/mlx4/srq.c
+++ b/drivers/net/mlx4/srq.c
@@ -32,6 +32,7 @@
*/
#include <linux/mlx4/cmd.h>
+#include <linux/gfp.h>
#include "mlx4.h"
#include "icm.h"
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index c97b6e4365a..8613a52ddf1 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -54,6 +54,7 @@
#include <linux/io.h>
#include <linux/types.h>
#include <linux/inet_lro.h>
+#include <linux/slab.h>
#include <asm/system.h>
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c
index 93c709d63e2..3a7ad840d5b 100644
--- a/drivers/net/mvme147.c
+++ b/drivers/net/mvme147.c
@@ -10,11 +10,11 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
/* Used for the temporal inet entries and routing */
#include <linux/socket.h>
#include <linux/route.h>
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 676c513e12f..ecde0876a78 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -64,6 +64,7 @@
#include <linux/moduleparam.h>
#include <linux/io.h>
#include <linux/log2.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/ip.h>
#include <net/tcp.h>
@@ -1689,7 +1690,7 @@ myri10ge_set_pauseparam(struct net_device *netdev,
if (pause->tx_pause != mgp->pause)
return myri10ge_change_pause(mgp, pause->tx_pause);
if (pause->rx_pause != mgp->pause)
- return myri10ge_change_pause(mgp, pause->tx_pause);
+ return myri10ge_change_pause(mgp, pause->rx_pause);
if (pause->autoneg != 0)
return -EINVAL;
return 0;
@@ -3687,7 +3688,6 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
if (status != 0) {
dev_err(&mgp->pdev->dev, "failed reset\n");
goto abort_with_fw;
- return;
}
mgp->max_intr_slots = cmd.data0 / sizeof(struct mcp_slot);
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 8b431308535..b72e749afdf 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -14,7 +14,6 @@ static char version[] =
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -26,6 +25,7 @@ static char version[] =
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/firmware.h>
+#include <linux/gfp.h>
#include <net/dst.h>
#include <net/arp.h>
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 992dbfffdb0..f4347f88b6f 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
{"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
{"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
#ifdef CONFIG_MACH_TX49XX
- {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
+ {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
#endif
{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
{NULL,}
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
index a53bb201d3c..ff3c4c81498 100644
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -66,7 +66,6 @@ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.o
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index bf4af5248cb..a361dea3557 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -37,6 +37,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/console.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 144d2e88042..0f703838e21 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -53,8 +53,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 72
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.72"
+#define _NETXEN_NIC_LINUX_SUBVERSION 73
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.73"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 2a8ef5fc966..f26e54716c8 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -669,13 +669,15 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
}
sds_ring->desc_head = (struct status_desc *)addr;
- sds_ring->crb_sts_consumer =
- netxen_get_ioaddr(adapter,
- recv_crb_registers[port].crb_sts_consumer[ring]);
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ sds_ring->crb_sts_consumer =
+ netxen_get_ioaddr(adapter,
+ recv_crb_registers[port].crb_sts_consumer[ring]);
- sds_ring->crb_intr_mask =
- netxen_get_ioaddr(adapter,
- recv_crb_registers[port].sw_int_mask[ring]);
+ sds_ring->crb_intr_mask =
+ netxen_get_ioaddr(adapter,
+ recv_crb_registers[port].sw_int_mask[ring]);
+ }
}
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index a945591298a..b1cf46a0c48 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -23,6 +23,7 @@
*
*/
+#include <linux/slab.h>
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 1c63610ead4..02876f59cbb 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -25,6 +25,7 @@
#include <linux/netdevice.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
@@ -761,7 +762,7 @@ nx_get_bios_version(struct netxen_adapter *adapter)
if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) {
bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
+ NX_UNI_BIOS_VERSION_OFF));
- return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) +
+ return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) +
(bios_ver >> 24);
} else
return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 08780ef1c1f..ce838f7c8b0 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -23,6 +23,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include "netxen_nic_hw.h"
@@ -604,16 +605,14 @@ netxen_cleanup_pci_map(struct netxen_adapter *adapter)
static int
netxen_setup_pci_map(struct netxen_adapter *adapter)
{
- void __iomem *mem_ptr0 = NULL;
- void __iomem *mem_ptr1 = NULL;
- void __iomem *mem_ptr2 = NULL;
void __iomem *db_ptr = NULL;
resource_size_t mem_base, db_base;
- unsigned long mem_len, db_len = 0, pci_len0 = 0;
+ unsigned long mem_len, db_len = 0;
struct pci_dev *pdev = adapter->pdev;
int pci_func = adapter->ahw.pci_func;
+ struct netxen_hardware_context *ahw = &adapter->ahw;
int err = 0;
@@ -630,24 +629,40 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
/* 128 Meg of memory */
if (mem_len == NETXEN_PCI_128MB_SIZE) {
- mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
- mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
+
+ ahw->pci_base0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
+ ahw->pci_base1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
SECOND_PAGE_GROUP_SIZE);
- mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
+ ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
THIRD_PAGE_GROUP_SIZE);
- pci_len0 = FIRST_PAGE_GROUP_SIZE;
+ if (ahw->pci_base0 == NULL || ahw->pci_base1 == NULL ||
+ ahw->pci_base2 == NULL) {
+ dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+ err = -EIO;
+ goto err_out;
+ }
+
+ ahw->pci_len0 = FIRST_PAGE_GROUP_SIZE;
+
} else if (mem_len == NETXEN_PCI_32MB_SIZE) {
- mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
- mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
+
+ ahw->pci_base1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
+ ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
+ if (ahw->pci_base1 == NULL || ahw->pci_base2 == NULL) {
+ dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+ err = -EIO;
+ goto err_out;
+ }
+
} else if (mem_len == NETXEN_PCI_2MB_SIZE) {
- mem_ptr0 = pci_ioremap_bar(pdev, 0);
- if (mem_ptr0 == NULL) {
+ ahw->pci_base0 = pci_ioremap_bar(pdev, 0);
+ if (ahw->pci_base0 == NULL) {
dev_err(&pdev->dev, "failed to map PCI bar 0\n");
return -EIO;
}
- pci_len0 = mem_len;
+ ahw->pci_len0 = mem_len;
} else {
return -EIO;
}
@@ -656,11 +671,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
- adapter->ahw.pci_base0 = mem_ptr0;
- adapter->ahw.pci_len0 = pci_len0;
- adapter->ahw.pci_base1 = mem_ptr1;
- adapter->ahw.pci_base2 = mem_ptr2;
-
if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) {
adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func)));
@@ -1246,8 +1256,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int pci_func_id = PCI_FUNC(pdev->devfn);
uint8_t revision_id;
- if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
- pr_warning("%s: chip revisions between 0x%x-0x%x"
+ if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) {
+ pr_warning("%s: chip revisions between 0x%x-0x%x "
"will not be enabled.\n",
module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1);
return -ENODEV;
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index c16cbfb4061..3892330f244 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -51,7 +51,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index 05c29c2cef2..f7a8f707361 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -109,7 +109,6 @@ static int fifo = 0x8; /* don't change */
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 0678f3106cb..d5cd16bfc90 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -25,6 +25,7 @@
#include <linux/jiffies.h>
#include <linux/crc32.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/io.h>
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 8dd509c09bc..e88e97cd1b1 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -116,6 +116,7 @@
#include <linux/if_vlan.h>
#include <linux/rtnetlink.h>
#include <linux/jiffies.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c
index be368e5cbf7..8aadc8e2ddd 100644
--- a/drivers/net/octeon/octeon_mgmt.c
+++ b/drivers/net/octeon/octeon_mgmt.c
@@ -13,6 +13,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
+#include <linux/slab.h>
#include <linux/phy.h>
#include <linux/spinlock.h>
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index d44d4a208bb..370c147d08a 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dmaengine.h>
#include <linux/delay.h>
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 3d1d3a7b7ed..757f87bb1db 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -781,8 +781,13 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
inw(ioaddr + EL3_STATUS));
spin_lock_irqsave(&lp->window_lock, flags);
+
+ dev->stats.tx_bytes += skb->len;
+
+ /* Put out the doubleword header... */
outw(skb->len, ioaddr + TX_FIFO);
outw(0, ioaddr + TX_FIFO);
+ /* ... and the packet rounded to a doubleword. */
outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2);
dev->trans_start = jiffies;
@@ -1021,8 +1026,6 @@ static void update_stats(struct net_device *dev)
/* BadSSD */ inb(ioaddr + 12);
up = inb(ioaddr + 13);
- dev->stats.tx_bytes += tx + ((up & 0xf0) << 12);
-
EL3WINDOW(1);
}
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 09291e60d30..9f3d593f14e 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 776cad2f571..4c0368de181 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -32,7 +32,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
@@ -1549,6 +1548,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101),
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab),
PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+ PCMCIA_PFC_DEVICE_PROD_ID12(0, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
@@ -1740,7 +1740,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
- PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("Allied Telesis,K.K", "Ethernet LAN Card", 0x2ad62f3c, 0x9fd2f0a2, "cis/LA-PCM.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 5adc662c4bf..ccc553782a0 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -493,13 +493,14 @@ static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
{
struct net_device *dev = priv;
cisparse_t parse;
+ u8 *buf;
if (pcmcia_parse_tuple(tuple, &parse))
return -EINVAL;
- if ((parse.version_1.ns > 3) &&
- (cvt_ascii_address(dev,
- (parse.version_1.str + parse.version_1.ofs[3]))))
+ buf = parse.version_1.str + parse.version_1.ofs[3];
+
+ if ((parse.version_1.ns > 3) && (cvt_ascii_address(dev, buf) == 0))
return 0;
return -EINVAL;
@@ -528,7 +529,7 @@ static int mhz_setup(struct pcmcia_device *link)
len = pcmcia_get_tuple(link, 0x81, &buf);
if (buf && len >= 13) {
buf[12] = '\0';
- if (cvt_ascii_address(dev, buf))
+ if (cvt_ascii_address(dev, buf) == 0)
rc = 0;
}
kfree(buf);
@@ -910,7 +911,7 @@ static int smc91c92_config(struct pcmcia_device *link)
if (i != 0) {
printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n");
- goto config_undo;
+ goto config_failed;
}
smc->duplex = 0;
@@ -998,6 +999,7 @@ config_undo:
unregister_netdev(dev);
config_failed:
smc91c92_release(link);
+ free_netdev(dev);
return -ENODEV;
} /* smc91c92_config */
@@ -1606,9 +1608,12 @@ static void set_rx_mode(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
struct smc_private *smc = netdev_priv(dev);
- u_int multicast_table[ 2 ] = { 0, };
+ unsigned char multicast_table[8];
unsigned long flags;
u_short rx_cfg_setting;
+ int i;
+
+ memset(multicast_table, 0, sizeof(multicast_table));
if (dev->flags & IFF_PROMISC) {
rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
@@ -1620,10 +1625,6 @@ static void set_rx_mode(struct net_device *dev)
netdev_for_each_mc_addr(mc_addr, dev) {
u_int position = ether_crc(6, mc_addr->dmi_addr);
-#ifndef final_version /* Verify multicast address. */
- if ((mc_addr->dmi_addr[0] & 1) == 0)
- continue;
-#endif
multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
}
}
@@ -1633,8 +1634,8 @@ static void set_rx_mode(struct net_device *dev)
/* Load MC table and Rx setting into the chip without interrupts. */
spin_lock_irqsave(&smc->lock, flags);
SMC_SELECT_BANK(3);
- outl(multicast_table[0], ioaddr + MULTICAST0);
- outl(multicast_table[1], ioaddr + MULTICAST4);
+ for (i = 0; i < 8; i++)
+ outb(multicast_table[i], ioaddr + MULTICAST0 + i);
SMC_SELECT_BANK(0);
outw(rx_cfg_setting, ioaddr + RCR);
SMC_SELECT_BANK(2);
@@ -1803,23 +1804,30 @@ static void media_check(u_long arg)
SMC_SELECT_BANK(1);
media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1;
+ SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irqrestore(&smc->lock, flags);
+
/* Check for pending interrupt with watchdog flag set: with
this, we can limp along even if the interrupt is blocked */
if (smc->watchdog++ && ((i>>8) & i)) {
if (!smc->fast_poll)
printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ local_irq_save(flags);
smc_interrupt(dev->irq, dev);
+ local_irq_restore(flags);
smc->fast_poll = HZ;
}
if (smc->fast_poll) {
smc->fast_poll--;
smc->media.expires = jiffies + HZ/100;
add_timer(&smc->media);
- SMC_SELECT_BANK(saved_bank);
- spin_unlock_irqrestore(&smc->lock, flags);
return;
}
+ spin_lock_irqsave(&smc->lock, flags);
+
+ saved_bank = inw(ioaddr + BANK_SELECT);
+
if (smc->cfg & CFG_MII_SELECT) {
if (smc->mii_if.phy_id < 0)
goto reschedule;
@@ -1977,15 +1985,16 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
unsigned int ioaddr = dev->base_addr;
u16 saved_bank = inw(ioaddr + BANK_SELECT);
int ret;
+ unsigned long flags;
- spin_lock_irq(&smc->lock);
+ spin_lock_irqsave(&smc->lock, flags);
SMC_SELECT_BANK(3);
if (smc->cfg & CFG_MII_SELECT)
ret = mii_ethtool_gset(&smc->mii_if, ecmd);
else
ret = smc_netdev_get_ecmd(dev, ecmd);
SMC_SELECT_BANK(saved_bank);
- spin_unlock_irq(&smc->lock);
+ spin_unlock_irqrestore(&smc->lock, flags);
return ret;
}
@@ -1995,15 +2004,16 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
unsigned int ioaddr = dev->base_addr;
u16 saved_bank = inw(ioaddr + BANK_SELECT);
int ret;
+ unsigned long flags;
- spin_lock_irq(&smc->lock);
+ spin_lock_irqsave(&smc->lock, flags);
SMC_SELECT_BANK(3);
if (smc->cfg & CFG_MII_SELECT)
ret = mii_ethtool_sset(&smc->mii_if, ecmd);
else
ret = smc_netdev_set_ecmd(dev, ecmd);
SMC_SELECT_BANK(saved_bank);
- spin_unlock_irq(&smc->lock);
+ spin_unlock_irqrestore(&smc->lock, flags);
return ret;
}
@@ -2013,12 +2023,13 @@ static u32 smc_get_link(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
u16 saved_bank = inw(ioaddr + BANK_SELECT);
u32 ret;
+ unsigned long flags;
- spin_lock_irq(&smc->lock);
+ spin_lock_irqsave(&smc->lock, flags);
SMC_SELECT_BANK(3);
ret = smc_link_ok(dev);
SMC_SELECT_BANK(saved_bank);
- spin_unlock_irq(&smc->lock);
+ spin_unlock_irqrestore(&smc->lock, flags);
return ret;
}
@@ -2055,16 +2066,17 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
int rc = 0;
u16 saved_bank;
unsigned int ioaddr = dev->base_addr;
+ unsigned long flags;
if (!netif_running(dev))
return -EINVAL;
- spin_lock_irq(&smc->lock);
+ spin_lock_irqsave(&smc->lock, flags);
saved_bank = inw(ioaddr + BANK_SELECT);
SMC_SELECT_BANK(3);
rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL);
SMC_SELECT_BANK(saved_bank);
- spin_unlock_irq(&smc->lock);
+ spin_unlock_irqrestore(&smc->lock, flags);
return rc;
}
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
index a1bd599c8a5..92282b31d94 100644
--- a/drivers/net/phy/cicada.c
+++ b/drivers/net/phy/cicada.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index d926168bc78..c722e95853f 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/phy/et1011c.c b/drivers/net/phy/et1011c.c
index b031fa21f1a..7712ebeba9b 100644
--- a/drivers/net/phy/et1011c.c
+++ b/drivers/net/phy/et1011c.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index e7070515d2e..1fa4d73c3cc 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -20,6 +20,7 @@
#include <linux/phy.h>
#include <linux/phy_fixed.h>
#include <linux/err.h>
+#include <linux/slab.h>
#define MII_REGS_NUM 29
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index af3f1f2a9f8..904208b95d4 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -13,7 +13,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index 4cf3324ba16..057ecaacde6 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 65ed385c2ce..64c7fbe0a8e 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 2576055b350..19e70d7e27a 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -19,7 +19,6 @@
#include <linux/module.h>
#include <linux/mdio-bitbang.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <linux/delay.h>
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index 61a4461cbda..a872aea4ed7 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -6,6 +6,7 @@
* Copyright (C) 2009 Cavium Networks
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 0295097d6c4..64be4664cca 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -19,7 +19,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c
index 23062d06723..f6e190f73c3 100644
--- a/drivers/net/phy/qsemi.c
+++ b/drivers/net/phy/qsemi.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index 3327e9fc7b5..9a2103a69e1 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -94,6 +94,7 @@ static const char version[] = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n"
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/if_ether.h>
#include <linux/in.h>
#include <linux/errno.h>
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 6a375ea4947..6c2e8fa0ca3 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -31,6 +31,7 @@
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/jiffies.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/string.h>
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 6d61602208c..6e281bc825e 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -46,6 +46,7 @@
#include <linux/stddef.h>
#include <linux/device.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <net/slhc_vj.h>
#include <asm/atomic.h>
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 3a13cecae3e..52938da1e54 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -44,6 +44,7 @@
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#define PPP_VERSION "2.4.2"
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 9fbb2eba9a0..449a9825200 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -756,6 +756,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
/* Try to dequeue as many skbs from reorder_q as we can. */
pppol2tp_recv_dequeue(session);
+ sock_put(sock);
return 0;
@@ -772,6 +773,7 @@ discard_bad_csum:
UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0);
tunnel->stats.rx_errors++;
kfree_skb(skb);
+ sock_put(sock);
return 0;
@@ -1180,7 +1182,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
/* Calculate UDP checksum if configured to do so */
if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
skb->ip_summed = CHECKSUM_NONE;
- else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
+ else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
+ (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
skb->ip_summed = CHECKSUM_COMPLETE;
csum = skb_checksum(skb, 0, udp_len, 0);
uh->check = csum_tcpudp_magic(inet->inet_saddr,
@@ -1661,6 +1664,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
if (tunnel_sock == NULL)
goto end;
+ sock_hold(tunnel_sock);
tunnel = tunnel_sock->sk_user_data;
} else {
tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index ac806b27c65..d4191ef9cad 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -22,7 +22,6 @@
#include <linux/string.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/net.h>
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index a849f6f23a1..5bf229bb34c 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 2663b2fdc0b..f0be507e532 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index b40a851ec7d..0da94b208db 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -423,6 +423,11 @@ struct qlcnic_adapter_stats {
u64 lro_pkts;
u64 rxbytes;
u64 txbytes;
+ u64 lrobytes;
+ u64 lso_frames;
+ u64 xmit_on;
+ u64 xmit_off;
+ u64 skb_alloc_failure;
};
/*
@@ -1095,11 +1100,11 @@ struct qlcnic_brdinfo {
static const struct qlcnic_brdinfo qlcnic_boards[] = {
{0x1077, 0x8020, 0x1077, 0x203,
- "8200 Series Single Port 10GbE Converged Network Adapter \
- (TCP/IP Networking)"},
+ "8200 Series Single Port 10GbE Converged Network Adapter "
+ "(TCP/IP Networking)"},
{0x1077, 0x8020, 0x1077, 0x207,
- "8200 Series Dual Port 10GbE Converged Network Adapter \
- (TCP/IP Networking)"},
+ "8200 Series Dual Port 10GbE Converged Network Adapter "
+ "(TCP/IP Networking)"},
{0x1077, 0x8020, 0x1077, 0x20b,
"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
{0x1077, 0x8020, 0x1077, 0x20c,
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 8da6ec8c13b..f83e15fe3e1 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -59,6 +59,17 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
{"tx_bytes",
QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
+ {"lrobytes",
+ QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
+ {"lso_frames",
+ QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
+ {"xmit_on",
+ QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
+ {"xmit_off",
+ QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
+ {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
+ QLC_OFF(stats.skb_alloc_failure)},
+
};
#define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats)
@@ -785,6 +796,11 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
}
}
+static u32 qlcnic_get_tx_csum(struct net_device *dev)
+{
+ return dev->features & NETIF_F_IP_CSUM;
+}
+
static u32 qlcnic_get_rx_csum(struct net_device *dev)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
@@ -995,6 +1011,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
.set_ringparam = qlcnic_set_ringparam,
.get_pauseparam = qlcnic_get_pauseparam,
.set_pauseparam = qlcnic_set_pauseparam,
+ .get_tx_csum = qlcnic_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.get_tso = qlcnic_get_tso,
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 99a4d1379d0..e73ba455aa2 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -24,6 +24,7 @@
#include "qlcnic.h"
+#include <linux/slab.h>
#include <net/ip.h>
#define MASK(n) ((1ULL<<(n))-1)
@@ -349,6 +350,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
if (nr_desc >= qlcnic_tx_avail(tx_ring)) {
netif_tx_stop_queue(tx_ring->txq);
__netif_tx_unlock_bh(tx_ring->txq);
+ adapter->stats.xmit_off++;
return -EBUSY;
}
@@ -397,20 +399,16 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
}
-static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter,
- u8 *addr, struct list_head *del_list)
+static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
{
struct list_head *head;
struct qlcnic_mac_list_s *cur;
/* look up if already exists */
- list_for_each(head, del_list) {
+ list_for_each(head, &adapter->mac_list) {
cur = list_entry(head, struct qlcnic_mac_list_s, list);
-
- if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
- list_move_tail(head, &adapter->mac_list);
+ if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
return 0;
- }
}
cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC);
@@ -432,14 +430,12 @@ void qlcnic_set_multi(struct net_device *netdev)
struct dev_mc_list *mc_ptr;
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
u32 mode = VPORT_MISS_MODE_DROP;
- LIST_HEAD(del_list);
- struct list_head *head;
- struct qlcnic_mac_list_s *cur;
- list_splice_tail_init(&adapter->mac_list, &del_list);
+ if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+ return;
- qlcnic_nic_add_mac(adapter, adapter->mac_addr, &del_list);
- qlcnic_nic_add_mac(adapter, bcast_addr, &del_list);
+ qlcnic_nic_add_mac(adapter, adapter->mac_addr);
+ qlcnic_nic_add_mac(adapter, bcast_addr);
if (netdev->flags & IFF_PROMISC) {
mode = VPORT_MISS_MODE_ACCEPT_ALL;
@@ -454,22 +450,12 @@ void qlcnic_set_multi(struct net_device *netdev)
if (!netdev_mc_empty(netdev)) {
netdev_for_each_mc_addr(mc_ptr, netdev) {
- qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr,
- &del_list);
+ qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr);
}
}
send_fw_cmd:
qlcnic_nic_set_promisc(adapter, mode);
- head = &del_list;
- while (!list_empty(head)) {
- cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
-
- qlcnic_sre_macaddr_change(adapter,
- cur->mac_addr, QLCNIC_MAC_DEL);
- list_del(&cur->list);
- kfree(cur);
- }
}
int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index ea00ab4d4fe..9d2c124048f 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -24,6 +24,7 @@
#include <linux/netdevice.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "qlcnic.h"
struct crb_addr_pair {
@@ -568,21 +569,123 @@ struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section)
return NULL;
}
+#define FILEHEADER_SIZE (14 * 4)
+
static int
-qlcnic_set_product_offs(struct qlcnic_adapter *adapter)
+qlcnic_validate_header(struct qlcnic_adapter *adapter)
{
- struct uni_table_desc *ptab_descr;
const u8 *unirom = adapter->fw->data;
- u32 i;
+ struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
+ __le32 fw_file_size = adapter->fw->size;
__le32 entries;
+ __le32 entry_size;
+ __le32 tab_size;
+
+ if (fw_file_size < FILEHEADER_SIZE)
+ return -EINVAL;
+
+ entries = cpu_to_le32(directory->num_entries);
+ entry_size = cpu_to_le32(directory->entry_size);
+ tab_size = cpu_to_le32(directory->findex) + (entries * entry_size);
+
+ if (fw_file_size < tab_size)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int
+qlcnic_validate_bootld(struct qlcnic_adapter *adapter)
+{
+ struct uni_table_desc *tab_desc;
+ struct uni_data_desc *descr;
+ const u8 *unirom = adapter->fw->data;
+ int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
+ QLCNIC_UNI_BOOTLD_IDX_OFF));
+ __le32 offs;
+ __le32 tab_size;
+ __le32 data_size;
+
+ tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_BOOTLD);
+
+ if (!tab_desc)
+ return -EINVAL;
+
+ tab_size = cpu_to_le32(tab_desc->findex) +
+ (cpu_to_le32(tab_desc->entry_size * (idx + 1)));
+
+ if (adapter->fw->size < tab_size)
+ return -EINVAL;
+
+ offs = cpu_to_le32(tab_desc->findex) +
+ (cpu_to_le32(tab_desc->entry_size) * (idx));
+ descr = (struct uni_data_desc *)&unirom[offs];
+
+ data_size = descr->findex + cpu_to_le32(descr->size);
+
+ if (adapter->fw->size < data_size)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int
+qlcnic_validate_fw(struct qlcnic_adapter *adapter)
+{
+ struct uni_table_desc *tab_desc;
+ struct uni_data_desc *descr;
+ const u8 *unirom = adapter->fw->data;
+ int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
+ QLCNIC_UNI_FIRMWARE_IDX_OFF));
+ __le32 offs;
+ __le32 tab_size;
+ __le32 data_size;
+
+ tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_FW);
+
+ if (!tab_desc)
+ return -EINVAL;
+
+ tab_size = cpu_to_le32(tab_desc->findex) +
+ (cpu_to_le32(tab_desc->entry_size * (idx + 1)));
+
+ if (adapter->fw->size < tab_size)
+ return -EINVAL;
+
+ offs = cpu_to_le32(tab_desc->findex) +
+ (cpu_to_le32(tab_desc->entry_size) * (idx));
+ descr = (struct uni_data_desc *)&unirom[offs];
+ data_size = descr->findex + cpu_to_le32(descr->size);
+
+ if (adapter->fw->size < data_size)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int
+qlcnic_validate_product_offs(struct qlcnic_adapter *adapter)
+{
+ struct uni_table_desc *ptab_descr;
+ const u8 *unirom = adapter->fw->data;
int mn_present = qlcnic_has_mn(adapter);
+ __le32 entries;
+ __le32 entry_size;
+ __le32 tab_size;
+ u32 i;
ptab_descr = qlcnic_get_table_desc(unirom,
QLCNIC_UNI_DIR_SECT_PRODUCT_TBL);
- if (ptab_descr == NULL)
- return -1;
+ if (!ptab_descr)
+ return -EINVAL;
entries = cpu_to_le32(ptab_descr->num_entries);
+ entry_size = cpu_to_le32(ptab_descr->entry_size);
+ tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size);
+
+ if (adapter->fw->size < tab_size)
+ return -EINVAL;
+
nomn:
for (i = 0; i < entries; i++) {
@@ -609,7 +712,37 @@ nomn:
mn_present = 0;
goto nomn;
}
- return -1;
+ return -EINVAL;
+}
+
+static int
+qlcnic_validate_unified_romimage(struct qlcnic_adapter *adapter)
+{
+ if (qlcnic_validate_header(adapter)) {
+ dev_err(&adapter->pdev->dev,
+ "unified image: header validation failed\n");
+ return -EINVAL;
+ }
+
+ if (qlcnic_validate_product_offs(adapter)) {
+ dev_err(&adapter->pdev->dev,
+ "unified image: product validation failed\n");
+ return -EINVAL;
+ }
+
+ if (qlcnic_validate_bootld(adapter)) {
+ dev_err(&adapter->pdev->dev,
+ "unified image: bootld validation failed\n");
+ return -EINVAL;
+ }
+
+ if (qlcnic_validate_fw(adapter)) {
+ dev_err(&adapter->pdev->dev,
+ "unified image: firmware validation failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
}
static
@@ -715,7 +848,7 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
+ QLCNIC_UNI_BIOS_VERSION_OFF));
- return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
+ return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
}
int
@@ -858,7 +991,7 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter)
u8 fw_type = adapter->fw_type;
if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) {
- if (qlcnic_set_product_offs(adapter))
+ if (qlcnic_validate_unified_romimage(adapter))
return -EINVAL;
min_size = QLCNIC_UNI_FW_MIN_SIZE;
@@ -1114,8 +1247,10 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
struct pci_dev *pdev = adapter->pdev;
buffer->skb = dev_alloc_skb(rds_ring->skb_size);
- if (!buffer->skb)
+ if (!buffer->skb) {
+ adapter->stats.skb_alloc_failure++;
return -ENOMEM;
+ }
skb = buffer->skb;
@@ -1289,7 +1424,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
netif_receive_skb(skb);
adapter->stats.lro_pkts++;
- adapter->stats.rxbytes += length;
+ adapter->stats.lrobytes += length;
return buffer;
}
@@ -1505,6 +1640,8 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
adapter->diag_cnt++;
dev_kfree_skb_any(skb);
+ adapter->stats.rx_pkts++;
+ adapter->stats.rxbytes += length;
return buffer;
}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 665e8e56b6a..234dab1f998 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -22,6 +22,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
@@ -118,6 +119,7 @@ qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) {
netif_stop_queue(adapter->netdev);
smp_mb();
+ adapter->stats.xmit_off++;
}
}
@@ -1385,6 +1387,7 @@ qlcnic_tso_check(struct net_device *netdev,
int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
struct cmd_desc_type0 *hwdesc;
struct vlan_ethhdr *vh;
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
if (protocol == cpu_to_be16(ETH_P_8021Q)) {
@@ -1494,6 +1497,7 @@ qlcnic_tso_check(struct net_device *netdev,
tx_ring->producer = producer;
barrier();
+ adapter->stats.lso_frames++;
}
static int
@@ -1573,6 +1577,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) {
netif_stop_queue(netdev);
+ adapter->stats.xmit_off++;
return NETDEV_TX_BUSY;
}
@@ -1880,6 +1885,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter)
if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) {
netif_wake_queue(netdev);
adapter->tx_timeo_cnt = 0;
+ adapter->stats.xmit_on++;
}
__netif_tx_unlock(tx_ring->txq);
}
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index ff8550d2ca8..36266462893 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -1,3 +1,5 @@
+#include <linux/slab.h>
+
#include "qlge.h"
/* Read a NIC register from the alternate function. */
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 05b8bde9980..7e09ff4a575 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -7,7 +7,6 @@
#include <linux/dma-mapping.h>
#include <linux/pagemap.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/dmapool.h>
#include <linux/mempool.h>
#include <linux/spinlock.h>
@@ -405,7 +404,7 @@ static int ql_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
u32 wol = 0;
status = ql_mb_wol_mode(qdev, wol);
netif_err(qdev, drv, qdev->ndev, "WOL %s (wol code 0x%x)\n",
- status == 0 ? "cleared sucessfully" : "clear failed",
+ status == 0 ? "cleared successfully" : "clear failed",
wol);
}
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index c26ec5d740f..fd34f266c0a 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3855,7 +3855,7 @@ int ql_wol(struct ql_adapter *qdev)
status = ql_mb_wol_mode(qdev, wol);
netif_err(qdev, drv, qdev->ndev,
"WOL %s (wol code 0x%x) on %s\n",
- (status == 0) ? "Sucessfully set" : "Failed",
+ (status == 0) ? "Successfully set" : "Failed",
wol, qdev->ndev->name);
}
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 15d5373dc8f..0298d8c1dcb 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -29,7 +29,6 @@
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@@ -135,7 +134,7 @@
#define RX_DESC_SIZE (RX_DCNT * sizeof(struct r6040_descriptor))
#define TX_DESC_SIZE (TX_DCNT * sizeof(struct r6040_descriptor))
#define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */
-#define MCAST_MAX 4 /* Max number multicast addresses to filter */
+#define MCAST_MAX 3 /* Max number multicast addresses to filter */
/* Descriptor status */
#define DSC_OWNER_MAC 0x8000 /* MAC is the owner of this descriptor */
@@ -983,9 +982,6 @@ static void r6040_multicast_list(struct net_device *dev)
crc >>= 26;
hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
}
- /* Write the index of the hash table */
- for (i = 0; i < 4; i++)
- iowrite16(hash_table[i] << 14, ioaddr + MCR1);
/* Fill the MAC hash tables with their values */
iowrite16(hash_table[0], ioaddr + MAR0);
iowrite16(hash_table[1], ioaddr + MAR1);
@@ -1001,9 +997,9 @@ static void r6040_multicast_list(struct net_device *dev)
iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
} else {
- iowrite16(0xffff, ioaddr + MID_0L + 8 * i);
- iowrite16(0xffff, ioaddr + MID_0M + 8 * i);
- iowrite16(0xffff, ioaddr + MID_0H + 8 * i);
+ iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
+ iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
+ iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
}
i++;
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index dfc3573c91b..4748c21eb72 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -186,8 +186,13 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
-static int rx_copybreak = 200;
-static int use_dac = -1;
+/*
+ * we set our copybreak very high so that we don't have
+ * to allocate 16k frames all the time (see note in
+ * rtl8169_open()
+ */
+static int rx_copybreak = 16383;
+static int use_dac;
static struct {
u32 msg_enable;
} debug = { -1 };
@@ -511,8 +516,7 @@ MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
module_param(rx_copybreak, int, 0);
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
module_param(use_dac, int, 0);
-MODULE_PARM_DESC(use_dac, "Enable PCI DAC. -1 defaults on for PCI Express only."
-" Unsafe on 32 bit PCI slot.");
+MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
MODULE_LICENSE("GPL");
@@ -2755,6 +2759,7 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
{
iounmap(ioaddr);
pci_release_regions(pdev);
+ pci_clear_mwi(pdev);
pci_disable_device(pdev);
free_netdev(dev);
}
@@ -2821,8 +2826,13 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
spin_lock_irq(&tp->lock);
RTL_W8(Cfg9346, Cfg9346_Unlock);
- RTL_W32(MAC0, low);
+
RTL_W32(MAC4, high);
+ RTL_R32(MAC4);
+
+ RTL_W32(MAC0, low);
+ RTL_R32(MAC0);
+
RTL_W8(Cfg9346, Cfg9346_Lock);
spin_unlock_irq(&tp->lock);
@@ -2974,7 +2984,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
void __iomem *ioaddr;
unsigned int i;
int rc;
- int this_use_dac = use_dac;
if (netif_msg_drv(&debug)) {
printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
@@ -3011,9 +3020,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_free_dev_1;
}
- rc = pci_set_mwi(pdev);
- if (rc < 0)
- goto err_out_disable_2;
+ if (pci_set_mwi(pdev) < 0)
+ netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n");
/* make sure PCI base addr 1 is MMIO */
if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
@@ -3021,7 +3029,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
"region #%d not an MMIO resource, aborting\n",
region);
rc = -ENODEV;
- goto err_out_mwi_3;
+ goto err_out_mwi_2;
}
/* check for weird/broken PCI region reporting */
@@ -3029,35 +3037,26 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_err(tp, probe, dev,
"Invalid PCI region size(s), aborting\n");
rc = -ENODEV;
- goto err_out_mwi_3;
+ goto err_out_mwi_2;
}
rc = pci_request_regions(pdev, MODULENAME);
if (rc < 0) {
netif_err(tp, probe, dev, "could not request regions\n");
- goto err_out_mwi_3;
+ goto err_out_mwi_2;
}
tp->cp_cmd = PCIMulRW | RxChkSum;
- tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (!tp->pcie_cap)
- netif_info(tp, probe, dev, "no PCI Express capability\n");
-
- if (this_use_dac < 0)
- this_use_dac = tp->pcie_cap != 0;
-
if ((sizeof(dma_addr_t) > 4) &&
- this_use_dac &&
- !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
- netif_info(tp, probe, dev, "using 64-bit DMA\n");
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
tp->cp_cmd |= PCIDAC;
dev->features |= NETIF_F_HIGHDMA;
} else {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) {
netif_err(tp, probe, dev, "DMA configuration failed\n");
- goto err_out_free_res_4;
+ goto err_out_free_res_3;
}
}
@@ -3066,9 +3065,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!ioaddr) {
netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n");
rc = -EIO;
- goto err_out_free_res_4;
+ goto err_out_free_res_3;
}
+ tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (!tp->pcie_cap)
+ netif_info(tp, probe, dev, "no PCI Express capability\n");
+
RTL_W16(IntrMask, 0x0000);
/* Soft reset the chip. */
@@ -3104,7 +3107,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (i == ARRAY_SIZE(rtl_chip_info)) {
dev_err(&pdev->dev,
"driver bug, MAC version not found in rtl_chip_info\n");
- goto err_out_msi_5;
+ goto err_out_msi_4;
}
tp->chipset = i;
@@ -3169,7 +3172,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = register_netdev(dev);
if (rc < 0)
- goto err_out_msi_5;
+ goto err_out_msi_4;
pci_set_drvdata(pdev, dev);
@@ -3192,14 +3195,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
out:
return rc;
-err_out_msi_5:
+err_out_msi_4:
rtl_disable_msi(pdev, tp);
iounmap(ioaddr);
-err_out_free_res_4:
+err_out_free_res_3:
pci_release_regions(pdev);
-err_out_mwi_3:
+err_out_mwi_2:
pci_clear_mwi(pdev);
-err_out_disable_2:
pci_disable_device(pdev);
err_out_free_dev_1:
free_netdev(dev);
@@ -3224,9 +3226,13 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
}
static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
- struct net_device *dev)
+ unsigned int mtu)
{
- unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+ unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+
+ if (max_frame != 16383)
+ printk(KERN_WARNING PFX "WARNING! Changing of MTU on this "
+ "NIC may lead to frame reception errors!\n");
tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
}
@@ -3238,7 +3244,17 @@ static int rtl8169_open(struct net_device *dev)
int retval = -ENOMEM;
- rtl8169_set_rxbufsize(tp, dev);
+ /*
+ * Note that we use a magic value here, its wierd I know
+ * its done because, some subset of rtl8169 hardware suffers from
+ * a problem in which frames received that are longer than
+ * the size set in RxMaxSize register return garbage sizes
+ * when received. To avoid this we need to turn off filtering,
+ * which is done by setting a value of 16383 in the RxMaxSize register
+ * and allocating 16k frames to handle the largest possible rx value
+ * thats what the magic math below does.
+ */
+ rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN);
/*
* Rx and Tx desscriptors needs 256 bytes alignment.
@@ -3891,7 +3907,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
rtl8169_down(dev);
- rtl8169_set_rxbufsize(tp, dev);
+ rtl8169_set_rxbufsize(tp, dev->mtu);
ret = rtl8169_init_ring(dev);
if (ret < 0)
@@ -4270,7 +4286,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
tp->cur_tx += frags + 1;
- smp_wmb();
+ wmb();
RTL_W8(TxPoll, NPQ); /* set polling bit */
@@ -4621,7 +4637,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
* until it does.
*/
tp->intr_mask = 0xffff;
- smp_wmb();
+ wmb();
RTL_W16(IntrMask, tp->intr_event);
}
@@ -4754,8 +4770,8 @@ static void rtl_set_rx_mode(struct net_device *dev)
mc_filter[1] = swab32(data);
}
- RTL_W32(MAR0 + 0, mc_filter[0]);
RTL_W32(MAR0 + 4, mc_filter[1]);
+ RTL_W32(MAR0 + 0, mc_filter[0]);
RTL_W32(RxConfig, tmp);
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index ede937ee50c..07eb884ff98 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
+#include <linux/slab.h>
#include <linux/rio_ids.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index 266baf53496..f2e335f0d1b 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -40,6 +40,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <asm/system.h>
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 43bc66aa840..92ae8d3de39 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -79,6 +79,7 @@
#include <linux/tcp.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <net/tcp.h>
#include <asm/system.h>
@@ -923,8 +924,8 @@ static int init_shared_mem(struct s2io_nic *nic)
tmp_v_addr = mac_control->stats_mem;
mac_control->stats_info = (struct stat_block *)tmp_v_addr;
memset(tmp_v_addr, 0, size);
- DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name,
- (unsigned long long)tmp_p_addr);
+ DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n",
+ dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr);
mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
return SUCCESS;
}
@@ -3480,7 +3481,7 @@ static void s2io_reset(struct s2io_nic *sp)
struct swStat *swstats;
DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n",
- __func__, sp->dev->name);
+ __func__, pci_name(sp->pdev));
/* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
@@ -5819,10 +5820,8 @@ static void s2io_vpd_read(struct s2io_nic *nic)
}
}
- if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) {
- memset(nic->product_name, 0, vpd_data[1]);
+ if ((!fail) && (vpd_data[1] < VPD_STRING_LEN))
memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
- }
kfree(vpd_data);
swstats->mem_freed += 256;
}
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
index 9f83a119737..abc8eefdd4b 100644
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -42,7 +42,6 @@ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";
#include <linux/errno.h>
#include <linux/if_cablemodem.h> /* for SIOGCM/SIOSCM stuff */
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
@@ -52,6 +51,7 @@ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";
#include <linux/pnp.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/processor.h>
diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
index fe806bd9b95..374832cca11 100644
--- a/drivers/net/seeq8005.c
+++ b/drivers/net/seeq8005.c
@@ -37,7 +37,6 @@ static const char version[] =
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 88f2fb193ab..649a264d6a8 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -20,6 +20,7 @@
#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/topology.h>
+#include <linux/gfp.h>
#include "net_driver.h"
#include "efx.h"
#include "mdio_10g.h"
@@ -1860,6 +1861,7 @@ out:
}
if (disabled) {
+ dev_close(efx->net_dev);
EFX_ERR(efx, "has been disabled\n");
efx->state = STATE_DISABLED;
} else {
@@ -1883,8 +1885,7 @@ static void efx_reset_work(struct work_struct *data)
}
rtnl_lock();
- if (efx_reset(efx, efx->reset_pending))
- dev_close(efx->net_dev);
+ (void)efx_reset(efx, efx->reset_pending);
rtnl_unlock();
}
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 1b8d83657aa..08278e7302b 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -15,6 +15,7 @@
#include <linux/seq_file.h>
#include <linux/i2c.h>
#include <linux/mii.h>
+#include <linux/slab.h>
#include "net_driver.h"
#include "bitfield.h"
#include "efx.h"
@@ -1319,7 +1320,9 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
- falcon_probe_board(efx, board_rev);
+ rc = falcon_probe_board(efx, board_rev);
+ if (rc)
+ goto fail2;
kfree(nvconfig);
return 0;
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index 5712fddd72f..c7a933a3292 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -728,15 +728,7 @@ static const struct falcon_board_type board_types[] = {
},
};
-static const struct falcon_board_type falcon_dummy_board = {
- .init = efx_port_dummy_op_int,
- .init_phy = efx_port_dummy_op_void,
- .fini = efx_port_dummy_op_void,
- .set_id_led = efx_port_dummy_op_set_id_led,
- .monitor = efx_port_dummy_op_int,
-};
-
-void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
+int falcon_probe_board(struct efx_nic *efx, u16 revision_info)
{
struct falcon_board *board = falcon_board(efx);
u8 type_id = FALCON_BOARD_TYPE(revision_info);
@@ -754,8 +746,9 @@ void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
(efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
? board->type->ref_model : board->type->gen_type,
'A' + board->major, board->minor);
+ return 0;
} else {
EFX_ERR(efx, "unknown board type %d\n", type_id);
- board->type = &falcon_dummy_board;
+ return -ENODEV;
}
}
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c
index 34c22fa986e..2f235469666 100644
--- a/drivers/net/sfc/mcdi_phy.c
+++ b/drivers/net/sfc/mcdi_phy.c
@@ -11,6 +11,7 @@
* Driver for PHY related operations via MCDI.
*/
+#include <linux/slab.h>
#include "efx.h"
#include "phy.h"
#include "mcdi.h"
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c
index 407bbaddfea..f3ac7f30b5e 100644
--- a/drivers/net/sfc/mtd.c
+++ b/drivers/net/sfc/mtd.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/rtnetlink.h>
#define EFX_DRIVER_NAME "sfc_mtd"
diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h
index 9351c0331a4..3166bafdfbe 100644
--- a/drivers/net/sfc/nic.h
+++ b/drivers/net/sfc/nic.h
@@ -156,7 +156,7 @@ extern struct efx_nic_type siena_a0_nic_type;
**************************************************************************
*/
-extern void falcon_probe_board(struct efx_nic *efx, u16 revision_info);
+extern int falcon_probe_board(struct efx_nic *efx, u16 revision_info);
/* TX data path */
extern int efx_nic_probe_tx(struct efx_tx_queue *tx_queue);
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index 1bee62c8300..e077bef08a5 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -10,6 +10,7 @@
* Driver for AMCC QT202x SFP+ and XFP adapters; see www.amcc.com for details
*/
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include "efx.h"
diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h
index 89d606fe924..18a3be42834 100644
--- a/drivers/net/sfc/regs.h
+++ b/drivers/net/sfc/regs.h
@@ -95,7 +95,7 @@
#define FRF_AA_INT_ACK_KER_FIELD_LBN 0
#define FRF_AA_INT_ACK_KER_FIELD_WIDTH 32
-/* INT_ISR0_REG: Function 0 Interrupt Acknowlege Status register */
+/* INT_ISR0_REG: Function 0 Interrupt Acknowledge Status register */
#define FR_BZ_INT_ISR0 0x00000090
#define FRF_BZ_INT_ISR_REG_LBN 0
#define FRF_BZ_INT_ISR_REG_WIDTH 64
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index a97c923b560..e308818b9f5 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -10,6 +10,7 @@
#include <linux/socket.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index cf0139a7d9a..0106b1d9aae 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -18,6 +18,7 @@
#include <linux/in.h>
#include <linux/udp.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include "net_driver.h"
#include "efx.h"
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c
index 1619fb5a64f..e0c46f59d1f 100644
--- a/drivers/net/sfc/siena.c
+++ b/drivers/net/sfc/siena.c
@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "net_driver.h"
#include "bitfield.h"
#include "efx.h"
@@ -455,8 +456,17 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
static void siena_update_nic_stats(struct efx_nic *efx)
{
- while (siena_try_update_nic_stats(efx) == -EAGAIN)
- cpu_relax();
+ int retry;
+
+ /* If we're unlucky enough to read statistics wduring the DMA, wait
+ * up to 10ms for it to finish (typically takes <500us) */
+ for (retry = 0; retry < 100; ++retry) {
+ if (siena_try_update_nic_stats(efx) == 0)
+ return;
+ udelay(100);
+ }
+
+ /* Use the old values instead */
}
static void siena_start_nic_stats(struct efx_nic *efx)
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 10db071bd83..f21efe7bd31 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/rtnetlink.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "efx.h"
#include "mdio_10g.h"
#include "nic.h"
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index a8b70ef6d81..be0e110a1f7 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -13,6 +13,7 @@
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/ipv6.h>
+#include <linux/slab.h>
#include <net/ipv6.h>
#include <linux/if_ether.h>
#include <linux/highmem.h>
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index ed999d31f1f..c8fc896fc46 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -592,8 +593,10 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Setup... */
len = skb->len;
if (len < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
+ if (skb_padto(skb, ETH_ZLEN)) {
+ spin_unlock_irqrestore(&sp->tx_lock, flags);
return NETDEV_TX_OK;
+ }
len = ETH_ZLEN;
}
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 42a35f086a9..6242b85d5d1 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -31,6 +31,7 @@
#include <linux/cache.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
+#include <linux/slab.h>
#include <asm/cacheflush.h>
#include "sh_eth.h"
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 760d9e83a46..b30ce752bbf 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -32,6 +32,7 @@
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#define PHY_MAX_ADDR 32
diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c
index a85efcfd9d0..e8387d25f24 100644
--- a/drivers/net/skfp/ess.c
+++ b/drivers/net/skfp/ess.c
@@ -557,7 +557,7 @@ static void ess_send_alc_req(struct s_smc *smc)
/*
* send never allocation request where the requested payload and
- * overhead is zero or deallocate bandwidht when no bandwidth is
+ * overhead is zero or deallocate bandwidth when no bandwidth is
* parsed
*/
if (!smc->mib.fddiESSPayload) {
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 1921a54ea99..d9016b75abc 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -78,13 +78,13 @@ static const char * const boot_msg =
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/fddidevice.h>
#include <linux/skbuff.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/byteorder.h>
#include <asm/io.h>
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index d0058e5bb6a..50eb70609f2 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -42,6 +42,7 @@
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/mii.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include "skge.h"
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 653bdd76ef4..088c797eb73 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -33,6 +33,7 @@
#include <linux/ethtool.h>
#include <linux/pci.h>
#include <linux/ip.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
@@ -4863,6 +4864,7 @@ static int sky2_resume(struct pci_dev *pdev)
if (!hw)
return 0;
+ rtnl_lock();
err = pci_set_power_state(pdev, PCI_D0);
if (err)
goto out;
@@ -4884,7 +4886,6 @@ static int sky2_resume(struct pci_dev *pdev)
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
napi_enable(&hw->napi);
- rtnl_lock();
for (i = 0; i < hw->ports; i++) {
err = sky2_reattach(hw->dev[i]);
if (err)
diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c
index d640c0f5470..140d63f3caf 100644
--- a/drivers/net/slhc.c
+++ b/drivers/net/slhc.c
@@ -51,6 +51,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index ba5bbc50344..89696156c05 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -83,6 +83,7 @@
#include <linux/compat.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include "slip.h"
#ifdef CONFIG_INET
#include <linux/ip.h>
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 9871a2b61f8..635820d42b1 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -59,7 +59,6 @@ static const char version[] =
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c
index f9a960e7fc1..3f2f7843aa4 100644
--- a/drivers/net/smc9194.c
+++ b/drivers/net/smc9194.c
@@ -64,7 +64,6 @@ static const char version[] =
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/crc32.h>
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index fc1b5a1a358..860339d51d5 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -70,7 +70,6 @@ static const char version[] =
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 54799544bda..8d2772cc42f 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -330,6 +330,48 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#include <unit/smc91111.h>
+#elif defined(CONFIG_ARCH_MSM)
+
+#define SMC_CAN_USE_8BIT 0
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 0
+#define SMC_NOWAIT 1
+
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH
+
+#elif defined(CONFIG_COLDFIRE)
+
+#define SMC_CAN_USE_8BIT 0
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 0
+#define SMC_NOWAIT 1
+
+static inline void mcf_insw(void *a, unsigned char *p, int l)
+{
+ u16 *wp = (u16 *) p;
+ while (l-- > 0)
+ *wp++ = readw(a);
+}
+
+static inline void mcf_outsw(void *a, unsigned char *p, int l)
+{
+ u16 *wp = (u16 *) p;
+ while (l-- > 0)
+ writew(*wp++, a);
+}
+
+#define SMC_inw(a, r) _swapw(readw((a) + (r)))
+#define SMC_outw(v, a, r) writew(_swapw(v), (a) + (r))
+#define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l)
+#define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l)
+
+#define SMC_IRQ_FLAGS (IRQF_DISABLED)
+
#else
/*
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 4fd1d8b3878..cbf520d38ea 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -41,7 +41,6 @@
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/bug.h>
#include <linux/bitops.h>
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 30110a11d73..aafaebf4574 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -26,6 +26,7 @@
#include <linux/if_vlan.h>
#include <linux/dma-mapping.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "smsc9420.h"
@@ -1347,7 +1348,7 @@ static int smsc9420_open(struct net_device *dev)
netif_carrier_off(dev);
- /* disable, mask and acknowlege all interrupts */
+ /* disable, mask and acknowledge all interrupts */
spin_lock_irqsave(&pd->int_lock, flags);
int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_);
smsc9420_reg_write(pd, INT_CFG, int_cfg);
diff --git a/drivers/net/sni_82596.c b/drivers/net/sni_82596.c
index 854ccf2b410..6b2a8881747 100644
--- a/drivers/net/sni_82596.c
+++ b/drivers/net/sni_82596.c
@@ -8,7 +8,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 2f8a8c32021..dd3cb0f2d21 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -31,6 +31,7 @@
#include <linux/if_vlan.h>
#include <linux/in.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/ioport.h>
#include <linux/ip.h>
#include <linux/kernel.h>
@@ -40,7 +41,6 @@
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
@@ -474,7 +474,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
* spider_net_enable_rxchtails - sets RX dmac chain tail addresses
* @card: card structure
*
- * spider_net_enable_rxchtails sets the RX DMAC chain tail adresses in the
+ * spider_net_enable_rxchtails sets the RX DMAC chain tail addresses in the
* chip by writing to the appropriate register. DMA is enabled in
* spider_net_enable_rxdmac.
*/
@@ -1820,7 +1820,7 @@ spider_net_enable_card(struct spider_net_card *card)
spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE);
- /* set chain tail adress for RX chains and
+ /* set chain tail address for RX chains and
* enable DMA */
spider_net_enable_rxchtails(card);
spider_net_enable_rxdmac(card);
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
index fb287649a30..eb63d44748a 100644
--- a/drivers/net/stmmac/Kconfig
+++ b/drivers/net/stmmac/Kconfig
@@ -2,6 +2,7 @@ config STMMAC_ETH
tristate "STMicroelectronics 10/100/1000 Ethernet driver"
select MII
select PHYLIB
+ select CRC32
depends on NETDEVICES && CPU_SUBTYPE_ST40
help
This is the driver for the Ethernet IPs are built around a
diff --git a/drivers/net/stmmac/dwmac100.c b/drivers/net/stmmac/dwmac100.c
index 803b0373d84..4cacca614fc 100644
--- a/drivers/net/stmmac/dwmac100.c
+++ b/drivers/net/stmmac/dwmac100.c
@@ -29,6 +29,7 @@
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/phy.h>
+#include <linux/slab.h>
#include "common.h"
#include "dwmac100.h"
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
index a6538ae4694..5bd95ebfe49 100644
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -27,6 +27,7 @@
*******************************************************************************/
#include <linux/crc32.h>
+#include <linux/slab.h>
#include "dwmac1000.h"
static void dwmac1000_core_init(unsigned long ioaddr)
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index a6733612d64..4111a85ec80 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -44,6 +44,7 @@
#include <linux/phy.h>
#include <linux/if_vlan.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include "stmmac.h"
#define STMMAC_RESOURCE_NAME "stmmaceth"
@@ -1685,7 +1686,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
}
pr_info("done!\n");
- if (!request_mem_region(res->start, (res->end - res->start),
+ if (!request_mem_region(res->start, resource_size(res),
pdev->name)) {
pr_err("%s: ERROR: memory allocation failed"
"cannot get the I/O addr 0x%x\n",
@@ -1694,9 +1695,9 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
goto out;
}
- addr = ioremap(res->start, (res->end - res->start));
+ addr = ioremap(res->start, resource_size(res));
if (!addr) {
- pr_err("%s: ERROR: memory mapping failed \n", __func__);
+ pr_err("%s: ERROR: memory mapping failed\n", __func__);
ret = -ENOMEM;
goto out;
}
@@ -1774,7 +1775,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
out:
if (ret < 0) {
platform_set_drvdata(pdev, NULL);
- release_mem_region(res->start, (res->end - res->start));
+ release_mem_region(res->start, resource_size(res));
if (addr != NULL)
iounmap(addr);
}
@@ -1812,7 +1813,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
iounmap((void *)ndev->base_addr);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, (res->end - res->start));
+ release_mem_region(res->start, resource_size(res));
free_netdev(ndev);
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
index fffe1d037fe..40b2c792971 100644
--- a/drivers/net/stmmac/stmmac_mdio.c
+++ b/drivers/net/stmmac/stmmac_mdio.c
@@ -26,6 +26,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
+#include <linux/slab.h>
#include "stmmac.h"
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
index 2f6a760e5f2..8b28c89a9a7 100644
--- a/drivers/net/sun3_82586.c
+++ b/drivers/net/sun3_82586.c
@@ -33,7 +33,6 @@ static int fifo=0x8; /* don't change */
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/init.h>
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 99998862c22..1694ca5bfb4 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -28,7 +28,6 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/ioport.h>
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index a0bd361d5ec..ed7865a0b5b 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -11,7 +11,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -25,6 +24,7 @@
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/gfp.h>
#include <asm/auxio.h>
#include <asm/byteorder.h>
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index a855934dfc3..8249a394a4e 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -84,7 +84,6 @@ static char *media[MAX_UNITS];
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 4344017bfae..e6880f1c4e8 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -39,7 +39,6 @@
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -58,6 +57,7 @@
#include <linux/bitops.h>
#include <linux/mutex.h>
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -782,7 +782,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
break;
/* When writing back RX descriptor, GEM writes status
- * then buffer address, possibly in seperate transactions.
+ * then buffer address, possibly in separate transactions.
* If we don't wait for the chip to write both, we could
* post a new buffer to this descriptor then have GEM spam
* on the buffer address. We sync on the RX completion
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index d7c73f478ef..0c21653ff9f 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -78,7 +78,6 @@ static char lancestr[] = "LANCE";
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -94,6 +93,7 @@ static char lancestr[] = "LANCE";
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 0c9780217c8..f5493092521 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -1851,7 +1851,7 @@ static void bdx_tx_push_desc(struct bdx_priv *priv, void *data, int size)
* @data - desc's data
* @size - desc's size
*
- * NOTE: this func does check for available space and, if neccessary, waits for
+ * NOTE: this func does check for available space and, if necessary, waits for
* NIC to read existing data before writing new one.
*/
static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size)
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index a19dcf8b6b5..cff98d07cba 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -32,6 +32,7 @@
#include <linux/firmware.h>
#include <asm/byteorder.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
/* Compile Time Switches */
/* start */
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 0fa7688ab48..ecc41cffb47 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5279,7 +5279,7 @@ static void tg3_poll_controller(struct net_device *dev)
struct tg3 *tp = netdev_priv(dev);
for (i = 0; i < tp->irq_cnt; i++)
- tg3_interrupt(tp->napi[i].irq_vec, dev);
+ tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);
}
#endif
@@ -8633,6 +8633,7 @@ static int tg3_test_msi(struct tg3 *tp)
pci_disable_msi(tp->pdev);
tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+ tp->napi[0].irq_vec = tp->pdev->irq;
err = tg3_request_irq(tp, 0);
if (err)
@@ -9776,7 +9777,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
ADVERTISED_Pause |
ADVERTISED_Asym_Pause;
- if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
mask |= ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full;
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 0fb930feea4..7d7f3eef1ab 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -63,6 +63,7 @@
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <net/checksum.h>
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index dd028fee9dc..7a5fbf5a9d7 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -121,6 +121,7 @@
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/checksum.h>
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
index 456f8bff40b..53f631ebb16 100644
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -21,6 +21,7 @@ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n";
#include <linux/module.h>
#include <linux/mca.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index 5401d86a7be..e40560137c4 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -36,7 +36,6 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/time.h>
#include <linux/errno.h>
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 21a01753312..8b508c92241 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -85,7 +85,6 @@ static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, A
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/time.h>
#include <linux/errno.h>
@@ -693,7 +692,7 @@ static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb,
* NOTE: This function should be used whenever the status of any TPL must be
* modified by the driver, because the compiler may otherwise change the
* order of instructions such that writing the TPL status may be executed at
- * an undesireable time. When this function is used, the status is always
+ * an undesirable time. When this function is used, the status is always
* written when the function is called.
*/
static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status)
@@ -2264,7 +2263,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev)
* This function should be used whenever the status of any RPL must be
* modified by the driver, because the compiler may otherwise change the
* order of instructions such that writing the RPL status may be executed
- * at an undesireable time. When this function is used, the status is
+ * at an undesirable time. When this function is used, the status is
* always written when the function is called.
*/
static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status)
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 647cdd1d4e2..5b1fbb3c3b5 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -38,7 +38,6 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/crc32.h>
@@ -48,6 +47,7 @@
#include <linux/rtnetlink.h>
#include <linux/timer.h>
#include <linux/platform_device.h>
+#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index cb429723b2c..19cafc2b418 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -42,6 +42,7 @@
#include <linux/compiler.h>
#include <linux/rtnetlink.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index c4ecb9a9540..09b57193a16 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -450,7 +450,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/eisa.h>
#include <linux/delay.h>
@@ -467,6 +466,7 @@
#include <linux/dma-mapping.h>
#include <linux/moduleparam.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/dma.h>
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 95b38d803e9..9568156dea9 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -74,7 +74,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
index 93f4e8309f8..6002e651b9e 100644
--- a/drivers/net/tulip/eeprom.c
+++ b/drivers/net/tulip/eeprom.c
@@ -13,6 +13,7 @@
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include "tulip.h"
#include <linux/init.h>
#include <asm/unaligned.h>
@@ -143,6 +144,12 @@ static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
void __devinit tulip_parse_eeprom(struct net_device *dev)
{
+ /*
+ dev is not registered at this point, so logging messages can't
+ use dev_<level> or netdev_<level> but dev->name is good via a
+ hack in the caller
+ */
+
/* The last media info list parsed, for multiport boards. */
static struct mediatable *last_mediatable;
static unsigned char *last_ee_data;
@@ -161,15 +168,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev)
if (ee_data[0] == 0xff) {
if (last_mediatable) {
controller_index++;
- dev_info(&dev->dev,
- "Controller %d of multiport board\n",
- controller_index);
+ pr_info("%s: Controller %d of multiport board\n",
+ dev->name, controller_index);
tp->mtable = last_mediatable;
ee_data = last_ee_data;
goto subsequent_board;
} else
- dev_info(&dev->dev,
- "Missing EEPROM, this interface may not work correctly!\n");
+ pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
+ dev->name);
return;
}
/* Do a fix-up based on the vendor half of the station address prefix. */
@@ -181,15 +187,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev)
i++; /* An Accton EN1207, not an outlaw Maxtech. */
memcpy(ee_data + 26, eeprom_fixups[i].newtable,
sizeof(eeprom_fixups[i].newtable));
- dev_info(&dev->dev,
- "Old format EEPROM on '%s' board. Using substitute media control info\n",
- eeprom_fixups[i].name);
+ pr_info("%s: Old format EEPROM on '%s' board. Using substitute media control info\n",
+ dev->name, eeprom_fixups[i].name);
break;
}
}
if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
- dev_info(&dev->dev,
- "Old style EEPROM with no media selection information\n");
+ pr_info("%s: Old style EEPROM with no media selection information\n",
+ dev->name);
return;
}
}
@@ -217,8 +222,8 @@ subsequent_board:
/* there is no phy information, don't even try to build mtable */
if (count == 0) {
if (tulip_debug > 0)
- dev_warn(&dev->dev,
- "no phy info, aborting mtable build\n");
+ pr_warning("%s: no phy info, aborting mtable build\n",
+ dev->name);
return;
}
@@ -234,8 +239,10 @@ subsequent_board:
mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
mtable->csr15dir = mtable->csr15val = 0;
- dev_info(&dev->dev, "EEPROM default media type %s\n",
- media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
+ pr_info("%s: EEPROM default media type %s\n",
+ dev->name,
+ media & 0x0800 ? "Autosense"
+ : medianame[media & MEDIA_MASK]);
for (i = 0; i < count; i++) {
struct medialeaf *leaf = &mtable->mleaf[i];
@@ -298,17 +305,17 @@ subsequent_board:
}
if (tulip_debug > 1 && leaf->media == 11) {
unsigned char *bp = leaf->leafdata;
- dev_info(&dev->dev,
- "MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
- bp[0], bp[1], bp[2 + bp[1]*2],
- bp[5 + bp[2 + bp[1]*2]*2],
- bp[4 + bp[2 + bp[1]*2]*2]);
+ pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
+ dev->name,
+ bp[0], bp[1], bp[2 + bp[1]*2],
+ bp[5 + bp[2 + bp[1]*2]*2],
+ bp[4 + bp[2 + bp[1]*2]*2]);
}
- dev_info(&dev->dev,
- "Index #%d - Media %s (#%d) described by a %s (%d) block\n",
- i, medianame[leaf->media & 15], leaf->media,
- leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
- leaf->type);
+ pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n",
+ dev->name,
+ i, medianame[leaf->media & 15], leaf->media,
+ leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
+ leaf->type);
}
if (new_advertise)
tp->sym_advertise = new_advertise;
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 7f544ef2f5f..3810db9dc2d 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "tulip.h"
#include <linux/init.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 0ab05af237e..a589dd34891 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -25,7 +25,6 @@
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
@@ -851,13 +850,15 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info
if ( !(rdes0 & 0x8000) ||
((db->cr6_data & CR6_PM) && (rxlen>6)) ) {
+ struct sk_buff *new_skb = NULL;
+
skb = rxptr->rx_skb_ptr;
/* Good packet, send to upper layer */
/* Shorst packet used new SKB */
- if ( (rxlen < RX_COPY_SIZE) &&
- ( (skb = dev_alloc_skb(rxlen + 2) )
- != NULL) ) {
+ if ((rxlen < RX_COPY_SIZE) &&
+ (((new_skb = dev_alloc_skb(rxlen + 2)) != NULL))) {
+ skb = new_skb;
/* size less than COPY_SIZE, allocate a rxlen SKB */
skb_reserve(skb, 2); /* 16byte align */
memcpy(skb_put(skb, rxlen),
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 304f43866c4..98dbf6cc1d6 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -114,7 +114,6 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index ce1efa4c0b0..43265207d46 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -387,6 +387,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
+ /* Orphan the skb - required as we might hang on to it
+ * for indefinite time. */
+ skb_orphan(skb);
+
/* Enqueue packet */
skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
dev->trans_start = jiffies;
@@ -1437,7 +1441,7 @@ static int tun_chr_close(struct inode *inode, struct file *file)
__tun_detach(tun);
- /* If desireable, unregister the netdevice. */
+ /* If desirable, unregister the netdevice. */
if (!(tun->flags & TUN_PERSIST)) {
rtnl_lock();
if (dev->reg_state == NETREG_REGISTERED)
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index e3ddcb8f29d..98d818daa77 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -109,7 +109,6 @@ static const int multicast_filter_limit = 32;
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@@ -480,7 +479,7 @@ typhoon_hello(struct typhoon *tp)
typhoon_inc_cmd_index(&ring->lastWrite, 1);
INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
- smp_wmb();
+ wmb();
iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
spin_unlock(&tp->command_lock);
}
@@ -1311,13 +1310,15 @@ typhoon_init_interface(struct typhoon *tp)
tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr);
tp->card_state = Sleeping;
- smp_wmb();
tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
spin_lock_init(&tp->command_lock);
spin_lock_init(&tp->state_lock);
+
+ /* Force the writes to the shared memory area out before continuing. */
+ wmb();
}
static void
@@ -2096,7 +2097,7 @@ typhoon_tx_timeout(struct net_device *dev)
if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) {
netdev_warn(dev, "could not reset in tx timeout\n");
- goto truely_dead;
+ goto truly_dead;
}
/* If we ever start using the Hi ring, it will need cleaning too */
@@ -2105,13 +2106,13 @@ typhoon_tx_timeout(struct net_device *dev)
if(typhoon_start_runtime(tp) < 0) {
netdev_err(dev, "could not start runtime in tx timeout\n");
- goto truely_dead;
+ goto truly_dead;
}
netif_wake_queue(dev);
return;
-truely_dead:
+truly_dead:
/* Reset the hardware, and turn off carrier to avoid more timeouts */
typhoon_reset(tp->ioaddr, NoWait);
netif_carrier_off(dev);
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 23a97518bc1..1b0aef37e49 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -430,7 +430,7 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth,
ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
/* Ethernet frames are defined in Little Endian mode,
- therefor to insert */
+ therefore to insert */
/* the address to the hash (Big Endian mode), we reverse the bytes.*/
set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr);
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 7075f26e97d..6f92e48f02d 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 32d93564a74..5d58abc224f 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -204,6 +204,14 @@ config USB_NET_DM9601
This option adds support for Davicom DM9601 based USB 1.1
10/100 Ethernet adapters.
+config USB_NET_SMSC75XX
+ tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
+ depends on USB_USBNET
+ select CRC32
+ help
+ This option adds support for SMSC LAN95XX based USB 2.0
+ Gigabit Ethernet adapters.
+
config USB_NET_SMSC95XX
tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices"
depends on USB_USBNET
@@ -377,4 +385,26 @@ config USB_CDC_PHONET
cellular modem, as found on most Nokia handsets with the
"PC suite" USB profile.
+config USB_IPHETH
+ tristate "Apple iPhone USB Ethernet driver"
+ default n
+ ---help---
+ Module used to share Internet connection (tethering) from your
+ iPhone (Original, 3G and 3GS) to your system.
+ Note that you need userspace libraries and programs that are needed
+ to pair your device with your system and that understand the iPhone
+ protocol.
+
+ For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
+
+config USB_SIERRA_NET
+ tristate "USB-to-WWAN Driver for Sierra Wireless modems"
+ depends on USB_USBNET
+ default y
+ help
+ Choose this option if you have a Sierra Wireless USB-to-WWAN device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sierra_net.
+
endmenu
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index e17afb78f37..b13a279663b 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_USB_NET_AX8817X) += asix.o
obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o
obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
+obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o
obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o
obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
obj-$(CONFIG_USB_NET_NET1080) += net1080.o
@@ -22,4 +23,6 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
obj-$(CONFIG_USB_USBNET) += usbnet.o
obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
+obj-$(CONFIG_USB_IPHETH) += ipheth.o
+obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 20e34608fa4..35f56fc8280 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -34,6 +34,7 @@
#include <linux/usb.h>
#include <linux/crc32.h>
#include <linux/usb/usbnet.h>
+#include <linux/slab.h>
#define DRIVER_VERSION "14-Jun-2006"
static const char driver_name [] = "asix";
@@ -54,6 +55,7 @@ static const char driver_name [] = "asix";
#define AX_CMD_WRITE_IPG0 0x12
#define AX_CMD_WRITE_IPG1 0x13
#define AX_CMD_READ_NODE_ID 0x13
+#define AX_CMD_WRITE_NODE_ID 0x14
#define AX_CMD_WRITE_IPG2 0x14
#define AX_CMD_WRITE_MULTI_FILTER 0x16
#define AX88172_CMD_READ_NODE_ID 0x17
@@ -165,6 +167,7 @@ static const char driver_name [] = "asix";
/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
struct asix_data {
u8 multi_filter[AX_MCAST_FILTER_SIZE];
+ u8 mac_addr[ETH_ALEN];
u8 phymode;
u8 ledmode;
u8 eeprom_len;
@@ -732,6 +735,30 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
}
+static int asix_set_mac_address(struct net_device *net, void *p)
+{
+ struct usbnet *dev = netdev_priv(net);
+ struct asix_data *data = (struct asix_data *)&dev->data;
+ struct sockaddr *addr = p;
+
+ if (netif_running(net))
+ return -EBUSY;
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
+
+ /* We use the 20 byte dev->data
+ * for our 6 byte mac buffer
+ * to avoid allocating memory that
+ * is tricky to free later */
+ memcpy(data->mac_addr, addr->sa_data, ETH_ALEN);
+ asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
+ data->mac_addr);
+
+ return 0;
+}
+
/* We need to override some ethtool_ops so we require our
own structure so we don't interfere with other usbnet
devices that may be connected at the same time. */
@@ -919,7 +946,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
.ndo_change_mtu = usbnet_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = asix_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = asix_ioctl,
.ndo_set_multicast_list = asix_set_multicast,
@@ -1213,7 +1240,7 @@ static const struct net_device_ops ax88178_netdev_ops = {
.ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = asix_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_multicast_list = asix_set_multicast,
.ndo_do_ioctl = asix_ioctl,
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 96f1ebe0d34..602e123b274 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -36,7 +36,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
@@ -44,6 +43,7 @@
#include <linux/ethtool.h>
#include <linux/crc32.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#undef DEBUG
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c
index 6491c9c00c8..dc9444525b4 100644
--- a/drivers/net/usb/cdc-phonet.c
+++ b/drivers/net/usb/cdc-phonet.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c
index a4a85a6ed86..5f3b97668e6 100644
--- a/drivers/net/usb/cdc_eem.c
+++ b/drivers/net/usb/cdc_eem.c
@@ -30,6 +30,7 @@
#include <linux/crc32.h>
#include <linux/usb/cdc.h>
#include <linux/usb/usbnet.h>
+#include <linux/gfp.h>
/*
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index c8cdb7f30ad..3547cf13d21 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -431,6 +431,7 @@ static const struct driver_info mbm_info = {
.bind = cdc_bind,
.unbind = usbnet_cdc_unbind,
.status = cdc_status,
+ .manage_power = cdc_manage_power,
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 269339769f4..04b281002a7 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -21,6 +21,7 @@
#include <linux/usb.h>
#include <linux/crc32.h>
#include <linux/usb/usbnet.h>
+#include <linux/slab.h>
/* datasheet:
http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf
diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c
index f7ccfad9384..dcd57c37ef7 100644
--- a/drivers/net/usb/gl620a.c
+++ b/drivers/net/usb/gl620a.c
@@ -30,6 +30,7 @@
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/usbnet.h>
+#include <linux/gfp.h>
/*
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 6895f153123..be0cc99e881 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1155,9 +1155,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
{
int result;
-#ifdef CONFIG_HSO_AUTOPM
- usb_mark_last_busy(urb->dev);
-#endif
/* We are done with this URB, resubmit it. Prep the USB to wait for
* another frame */
usb_fill_bulk_urb(urb, serial->parent->usb,
diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c
index 3c228df5706..be02a25da71 100644
--- a/drivers/net/usb/int51x1.c
+++ b/drivers/net/usb/int51x1.c
@@ -29,6 +29,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
+#include <linux/slab.h>
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/usbnet.h>
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
new file mode 100644
index 00000000000..418825d26f9
--- /dev/null
+++ b/drivers/net/usb/ipheth.c
@@ -0,0 +1,569 @@
+/*
+ * ipheth.c - Apple iPhone USB Ethernet driver
+ *
+ * Copyright (c) 2009 Diego Giagio <diego@giagio.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of GIAGIO.COM nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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.
+ *
+ *
+ * Attention: iPhone device must be paired, otherwise it won't respond to our
+ * driver. For more info: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/usb.h>
+#include <linux/workqueue.h>
+
+#define USB_VENDOR_APPLE 0x05ac
+#define USB_PRODUCT_IPHONE 0x1290
+#define USB_PRODUCT_IPHONE_3G 0x1292
+#define USB_PRODUCT_IPHONE_3GS 0x1294
+
+#define IPHETH_USBINTF_CLASS 255
+#define IPHETH_USBINTF_SUBCLASS 253
+#define IPHETH_USBINTF_PROTO 1
+
+#define IPHETH_BUF_SIZE 1516
+#define IPHETH_TX_TIMEOUT (5 * HZ)
+
+#define IPHETH_INTFNUM 2
+#define IPHETH_ALT_INTFNUM 1
+
+#define IPHETH_CTRL_ENDP 0x00
+#define IPHETH_CTRL_BUF_SIZE 0x40
+#define IPHETH_CTRL_TIMEOUT (5 * HZ)
+
+#define IPHETH_CMD_GET_MACADDR 0x00
+#define IPHETH_CMD_CARRIER_CHECK 0x45
+
+#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
+#define IPHETH_CARRIER_ON 0x04
+
+static struct usb_device_id ipheth_table[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(
+ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE,
+ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+ IPHETH_USBINTF_PROTO) },
+ { USB_DEVICE_AND_INTERFACE_INFO(
+ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3G,
+ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+ IPHETH_USBINTF_PROTO) },
+ { USB_DEVICE_AND_INTERFACE_INFO(
+ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS,
+ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+ IPHETH_USBINTF_PROTO) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, ipheth_table);
+
+struct ipheth_device {
+ struct usb_device *udev;
+ struct usb_interface *intf;
+ struct net_device *net;
+ struct sk_buff *tx_skb;
+ struct urb *tx_urb;
+ struct urb *rx_urb;
+ unsigned char *tx_buf;
+ unsigned char *rx_buf;
+ unsigned char *ctrl_buf;
+ u8 bulk_in;
+ u8 bulk_out;
+ struct delayed_work carrier_work;
+};
+
+static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
+
+static int ipheth_alloc_urbs(struct ipheth_device *iphone)
+{
+ struct urb *tx_urb = NULL;
+ struct urb *rx_urb = NULL;
+ u8 *tx_buf = NULL;
+ u8 *rx_buf = NULL;
+
+ tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (tx_urb == NULL)
+ goto error_nomem;
+
+ rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (rx_urb == NULL)
+ goto free_tx_urb;
+
+ tx_buf = usb_buffer_alloc(iphone->udev,
+ IPHETH_BUF_SIZE,
+ GFP_KERNEL,
+ &tx_urb->transfer_dma);
+ if (tx_buf == NULL)
+ goto free_rx_urb;
+
+ rx_buf = usb_buffer_alloc(iphone->udev,
+ IPHETH_BUF_SIZE,
+ GFP_KERNEL,
+ &rx_urb->transfer_dma);
+ if (rx_buf == NULL)
+ goto free_tx_buf;
+
+
+ iphone->tx_urb = tx_urb;
+ iphone->rx_urb = rx_urb;
+ iphone->tx_buf = tx_buf;
+ iphone->rx_buf = rx_buf;
+ return 0;
+
+free_tx_buf:
+ usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
+ tx_urb->transfer_dma);
+free_rx_urb:
+ usb_free_urb(rx_urb);
+free_tx_urb:
+ usb_free_urb(tx_urb);
+error_nomem:
+ return -ENOMEM;
+}
+
+static void ipheth_free_urbs(struct ipheth_device *iphone)
+{
+ usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf,
+ iphone->rx_urb->transfer_dma);
+ usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
+ iphone->tx_urb->transfer_dma);
+ usb_free_urb(iphone->rx_urb);
+ usb_free_urb(iphone->tx_urb);
+}
+
+static void ipheth_kill_urbs(struct ipheth_device *dev)
+{
+ usb_kill_urb(dev->tx_urb);
+ usb_kill_urb(dev->rx_urb);
+}
+
+static void ipheth_rcvbulk_callback(struct urb *urb)
+{
+ struct ipheth_device *dev;
+ struct sk_buff *skb;
+ int status;
+ char *buf;
+ int len;
+
+ dev = urb->context;
+ if (dev == NULL)
+ return;
+
+ status = urb->status;
+ switch (status) {
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ESHUTDOWN:
+ return;
+ case 0:
+ break;
+ default:
+ err("%s: urb status: %d", __func__, urb->status);
+ return;
+ }
+
+ len = urb->actual_length;
+ buf = urb->transfer_buffer;
+
+ skb = dev_alloc_skb(NET_IP_ALIGN + len);
+ if (!skb) {
+ err("%s: dev_alloc_skb: -ENOMEM", __func__);
+ dev->net->stats.rx_dropped++;
+ return;
+ }
+
+ skb_reserve(skb, NET_IP_ALIGN);
+ memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN);
+ skb->dev = dev->net;
+ skb->protocol = eth_type_trans(skb, dev->net);
+
+ dev->net->stats.rx_packets++;
+ dev->net->stats.rx_bytes += len;
+
+ netif_rx(skb);
+ ipheth_rx_submit(dev, GFP_ATOMIC);
+}
+
+static void ipheth_sndbulk_callback(struct urb *urb)
+{
+ struct ipheth_device *dev;
+
+ dev = urb->context;
+ if (dev == NULL)
+ return;
+
+ if (urb->status != 0 &&
+ urb->status != -ENOENT &&
+ urb->status != -ECONNRESET &&
+ urb->status != -ESHUTDOWN)
+ err("%s: urb status: %d", __func__, urb->status);
+
+ dev_kfree_skb_irq(dev->tx_skb);
+ netif_wake_queue(dev->net);
+}
+
+static int ipheth_carrier_set(struct ipheth_device *dev)
+{
+ struct usb_device *udev = dev->udev;
+ int retval;
+
+ retval = usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+ IPHETH_CMD_CARRIER_CHECK, /* request */
+ 0xc0, /* request type */
+ 0x00, /* value */
+ 0x02, /* index */
+ dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,
+ IPHETH_CTRL_TIMEOUT);
+ if (retval < 0) {
+ err("%s: usb_control_msg: %d", __func__, retval);
+ return retval;
+ }
+
+ if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON)
+ netif_carrier_on(dev->net);
+ else
+ netif_carrier_off(dev->net);
+
+ return 0;
+}
+
+static void ipheth_carrier_check_work(struct work_struct *work)
+{
+ struct ipheth_device *dev = container_of(work, struct ipheth_device,
+ carrier_work.work);
+
+ ipheth_carrier_set(dev);
+ schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+}
+
+static int ipheth_get_macaddr(struct ipheth_device *dev)
+{
+ struct usb_device *udev = dev->udev;
+ struct net_device *net = dev->net;
+ int retval;
+
+ retval = usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+ IPHETH_CMD_GET_MACADDR, /* request */
+ 0xc0, /* request type */
+ 0x00, /* value */
+ 0x02, /* index */
+ dev->ctrl_buf,
+ IPHETH_CTRL_BUF_SIZE,
+ IPHETH_CTRL_TIMEOUT);
+ if (retval < 0) {
+ err("%s: usb_control_msg: %d", __func__, retval);
+ } else if (retval < ETH_ALEN) {
+ err("%s: usb_control_msg: short packet: %d bytes",
+ __func__, retval);
+ retval = -EINVAL;
+ } else {
+ memcpy(net->dev_addr, dev->ctrl_buf, ETH_ALEN);
+ retval = 0;
+ }
+
+ return retval;
+}
+
+static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
+{
+ struct usb_device *udev = dev->udev;
+ int retval;
+
+ usb_fill_bulk_urb(dev->rx_urb, udev,
+ usb_rcvbulkpipe(udev, dev->bulk_in),
+ dev->rx_buf, IPHETH_BUF_SIZE,
+ ipheth_rcvbulk_callback,
+ dev);
+ dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ retval = usb_submit_urb(dev->rx_urb, mem_flags);
+ if (retval)
+ err("%s: usb_submit_urb: %d", __func__, retval);
+ return retval;
+}
+
+static int ipheth_open(struct net_device *net)
+{
+ struct ipheth_device *dev = netdev_priv(net);
+ struct usb_device *udev = dev->udev;
+ int retval = 0;
+
+ usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM);
+
+ retval = ipheth_carrier_set(dev);
+ if (retval)
+ return retval;
+
+ retval = ipheth_rx_submit(dev, GFP_KERNEL);
+ if (retval)
+ return retval;
+
+ schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+ netif_start_queue(net);
+ return retval;
+}
+
+static int ipheth_close(struct net_device *net)
+{
+ struct ipheth_device *dev = netdev_priv(net);
+
+ cancel_delayed_work_sync(&dev->carrier_work);
+ netif_stop_queue(net);
+ return 0;
+}
+
+static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
+{
+ struct ipheth_device *dev = netdev_priv(net);
+ struct usb_device *udev = dev->udev;
+ int retval;
+
+ /* Paranoid */
+ if (skb->len > IPHETH_BUF_SIZE) {
+ WARN(1, "%s: skb too large: %d bytes", __func__, skb->len);
+ dev->net->stats.tx_dropped++;
+ dev_kfree_skb_irq(skb);
+ return NETDEV_TX_OK;
+ }
+
+ memcpy(dev->tx_buf, skb->data, skb->len);
+ if (skb->len < IPHETH_BUF_SIZE)
+ memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
+
+ usb_fill_bulk_urb(dev->tx_urb, udev,
+ usb_sndbulkpipe(udev, dev->bulk_out),
+ dev->tx_buf, IPHETH_BUF_SIZE,
+ ipheth_sndbulk_callback,
+ dev);
+ dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
+ if (retval) {
+ err("%s: usb_submit_urb: %d", __func__, retval);
+ dev->net->stats.tx_errors++;
+ dev_kfree_skb_irq(skb);
+ } else {
+ dev->tx_skb = skb;
+
+ dev->net->stats.tx_packets++;
+ dev->net->stats.tx_bytes += skb->len;
+ netif_stop_queue(net);
+ }
+
+ return NETDEV_TX_OK;
+}
+
+static void ipheth_tx_timeout(struct net_device *net)
+{
+ struct ipheth_device *dev = netdev_priv(net);
+
+ err("%s: TX timeout", __func__);
+ dev->net->stats.tx_errors++;
+ usb_unlink_urb(dev->tx_urb);
+}
+
+static struct net_device_stats *ipheth_stats(struct net_device *net)
+{
+ struct ipheth_device *dev = netdev_priv(net);
+ return &dev->net->stats;
+}
+
+static u32 ipheth_ethtool_op_get_link(struct net_device *net)
+{
+ struct ipheth_device *dev = netdev_priv(net);
+ return netif_carrier_ok(dev->net);
+}
+
+static struct ethtool_ops ops = {
+ .get_link = ipheth_ethtool_op_get_link
+};
+
+static const struct net_device_ops ipheth_netdev_ops = {
+ .ndo_open = &ipheth_open,
+ .ndo_stop = &ipheth_close,
+ .ndo_start_xmit = &ipheth_tx,
+ .ndo_tx_timeout = &ipheth_tx_timeout,
+ .ndo_get_stats = &ipheth_stats,
+};
+
+static struct device_type ipheth_type = {
+ .name = "wwan",
+};
+
+static int ipheth_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct usb_host_interface *hintf;
+ struct usb_endpoint_descriptor *endp;
+ struct ipheth_device *dev;
+ struct net_device *netdev;
+ int i;
+ int retval;
+
+ netdev = alloc_etherdev(sizeof(struct ipheth_device));
+ if (!netdev)
+ return -ENOMEM;
+
+ netdev->netdev_ops = &ipheth_netdev_ops;
+ netdev->watchdog_timeo = IPHETH_TX_TIMEOUT;
+ strcpy(netdev->name, "wwan%d");
+
+ dev = netdev_priv(netdev);
+ dev->udev = udev;
+ dev->net = netdev;
+ dev->intf = intf;
+
+ /* Set up endpoints */
+ hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
+ if (hintf == NULL) {
+ retval = -ENODEV;
+ err("Unable to find alternate settings interface");
+ goto err_endpoints;
+ }
+
+ for (i = 0; i < hintf->desc.bNumEndpoints; i++) {
+ endp = &hintf->endpoint[i].desc;
+ if (usb_endpoint_is_bulk_in(endp))
+ dev->bulk_in = endp->bEndpointAddress;
+ else if (usb_endpoint_is_bulk_out(endp))
+ dev->bulk_out = endp->bEndpointAddress;
+ }
+ if (!(dev->bulk_in && dev->bulk_out)) {
+ retval = -ENODEV;
+ err("Unable to find endpoints");
+ goto err_endpoints;
+ }
+
+ dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL);
+ if (dev->ctrl_buf == NULL) {
+ retval = -ENOMEM;
+ goto err_alloc_ctrl_buf;
+ }
+
+ retval = ipheth_get_macaddr(dev);
+ if (retval)
+ goto err_get_macaddr;
+
+ INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
+
+ retval = ipheth_alloc_urbs(dev);
+ if (retval) {
+ err("error allocating urbs: %d", retval);
+ goto err_alloc_urbs;
+ }
+
+ usb_set_intfdata(intf, dev);
+
+ SET_NETDEV_DEV(netdev, &intf->dev);
+ SET_ETHTOOL_OPS(netdev, &ops);
+ SET_NETDEV_DEVTYPE(netdev, &ipheth_type);
+
+ retval = register_netdev(netdev);
+ if (retval) {
+ err("error registering netdev: %d", retval);
+ retval = -EIO;
+ goto err_register_netdev;
+ }
+
+ dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n");
+ return 0;
+
+err_register_netdev:
+ ipheth_free_urbs(dev);
+err_alloc_urbs:
+err_get_macaddr:
+err_alloc_ctrl_buf:
+ kfree(dev->ctrl_buf);
+err_endpoints:
+ free_netdev(netdev);
+ return retval;
+}
+
+static void ipheth_disconnect(struct usb_interface *intf)
+{
+ struct ipheth_device *dev;
+
+ dev = usb_get_intfdata(intf);
+ if (dev != NULL) {
+ unregister_netdev(dev->net);
+ ipheth_kill_urbs(dev);
+ ipheth_free_urbs(dev);
+ kfree(dev->ctrl_buf);
+ free_netdev(dev->net);
+ }
+ usb_set_intfdata(intf, NULL);
+ dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n");
+}
+
+static struct usb_driver ipheth_driver = {
+ .name = "ipheth",
+ .probe = ipheth_probe,
+ .disconnect = ipheth_disconnect,
+ .id_table = ipheth_table,
+};
+
+static int __init ipheth_init(void)
+{
+ int retval;
+
+ retval = usb_register(&ipheth_driver);
+ if (retval) {
+ err("usb_register failed: %d", retval);
+ return retval;
+ }
+ return 0;
+}
+
+static void __exit ipheth_exit(void)
+{
+ usb_deregister(&ipheth_driver);
+}
+
+module_init(ipheth_init);
+module_exit(ipheth_exit);
+
+MODULE_AUTHOR("Diego Giagio <diego@giagio.com>");
+MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 52671ea043a..c4c334d9770 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -145,6 +145,7 @@ static struct usb_device_id usb_klsi_table[] = {
{ USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */
{ USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */
{ USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */
+ { USB_DEVICE(0x07c9, 0xb010) }, /* Allied Telesyn AT-USB10 USB Ethernet Adapter */
{ USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */
{ USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */
{ USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 70978219e98..9f24e3f871e 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -44,6 +44,7 @@
#include <linux/mii.h>
#include <linux/module.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/usbnet.h>
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c
index bdcad45954a..961a8ed38d8 100644
--- a/drivers/net/usb/net1080.c
+++ b/drivers/net/usb/net1080.c
@@ -29,6 +29,7 @@
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/usbnet.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
index 5d02f020073..b90d8766ab7 100644
--- a/drivers/net/usb/pegasus.h
+++ b/drivers/net/usb/pegasus.h
@@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
+ DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
@@ -208,6 +208,8 @@ PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
*/
PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
+ DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
@@ -249,7 +251,7 @@ PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002,
PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
+ DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 4ce331fb1e1..dd8a4adf48c 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -22,6 +22,7 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/cdc.h>
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
new file mode 100644
index 00000000000..a44f9e0ea09
--- /dev/null
+++ b/drivers/net/usb/sierra_net.c
@@ -0,0 +1,1001 @@
+/*
+ * USB-to-WWAN Driver for Sierra Wireless modems
+ *
+ * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer
+ * <linux@sierrawireless.com>
+ *
+ * Portions of this based on the cdc_ether driver by David Brownell (2003-2005)
+ * and Ole Andre Vadla Ravnas (ActiveSync) (2006).
+ *
+ * IMPORTANT DISCLAIMER: This driver is not commercially supported by
+ * Sierra Wireless. Use at your own risk.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define DRIVER_VERSION "v.2.0"
+#define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer"
+#define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems"
+static const char driver_name[] = "sierra_net";
+
+/* if defined debug messages enabled */
+/*#define DEBUG*/
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <asm/unaligned.h>
+#include <linux/usb/usbnet.h>
+
+#define SWI_USB_REQUEST_GET_FW_ATTR 0x06
+#define SWI_GET_FW_ATTR_MASK 0x08
+
+/* atomic counter partially included in MAC address to make sure 2 devices
+ * do not end up with the same MAC - concept breaks in case of > 255 ifaces
+ */
+static atomic_t iface_counter = ATOMIC_INIT(0);
+
+/*
+ * SYNC Timer Delay definition used to set the expiry time
+ */
+#define SIERRA_NET_SYNCDELAY (2*HZ)
+
+/* Max. MTU supported. The modem buffers are limited to 1500 */
+#define SIERRA_NET_MAX_SUPPORTED_MTU 1500
+
+/* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control
+ * message reception ... and thus the max. received packet.
+ * (May be the cause for parse_hip returning -EINVAL)
+ */
+#define SIERRA_NET_USBCTL_BUF_LEN 1024
+
+/* list of interface numbers - used for constructing interface lists */
+struct sierra_net_iface_info {
+ const u32 infolen; /* number of interface numbers on list */
+ const u8 *ifaceinfo; /* pointer to the array holding the numbers */
+};
+
+struct sierra_net_info_data {
+ u16 rx_urb_size;
+ struct sierra_net_iface_info whitelist;
+};
+
+/* Private data structure */
+struct sierra_net_data {
+
+ u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */
+
+ u16 link_up; /* air link up or down */
+ u8 tx_hdr_template[4]; /* part of HIP hdr for tx'd packets */
+
+ u8 sync_msg[4]; /* SYNC message */
+ u8 shdwn_msg[4]; /* Shutdown message */
+
+ /* Backpointer to the container */
+ struct usbnet *usbnet;
+
+ u8 ifnum; /* interface number */
+
+/* Bit masks, must be a power of 2 */
+#define SIERRA_NET_EVENT_RESP_AVAIL 0x01
+#define SIERRA_NET_TIMER_EXPIRY 0x02
+ unsigned long kevent_flags;
+ struct work_struct sierra_net_kevent;
+ struct timer_list sync_timer; /* For retrying SYNC sequence */
+};
+
+struct param {
+ int is_present;
+ union {
+ void *ptr;
+ u32 dword;
+ u16 word;
+ u8 byte;
+ };
+};
+
+/* HIP message type */
+#define SIERRA_NET_HIP_EXTENDEDID 0x7F
+#define SIERRA_NET_HIP_HSYNC_ID 0x60 /* Modem -> host */
+#define SIERRA_NET_HIP_RESTART_ID 0x62 /* Modem -> host */
+#define SIERRA_NET_HIP_MSYNC_ID 0x20 /* Host -> modem */
+#define SIERRA_NET_HIP_SHUTD_ID 0x26 /* Host -> modem */
+
+#define SIERRA_NET_HIP_EXT_IP_IN_ID 0x0202
+#define SIERRA_NET_HIP_EXT_IP_OUT_ID 0x0002
+
+/* 3G UMTS Link Sense Indication definitions */
+#define SIERRA_NET_HIP_LSI_UMTSID 0x78
+
+/* Reverse Channel Grant Indication HIP message */
+#define SIERRA_NET_HIP_RCGI 0x64
+
+/* LSI Protocol types */
+#define SIERRA_NET_PROTOCOL_UMTS 0x01
+/* LSI Coverage */
+#define SIERRA_NET_COVERAGE_NONE 0x00
+#define SIERRA_NET_COVERAGE_NOPACKET 0x01
+
+/* LSI Session */
+#define SIERRA_NET_SESSION_IDLE 0x00
+/* LSI Link types */
+#define SIERRA_NET_AS_LINK_TYPE_IPv4 0x00
+
+struct lsi_umts {
+ u8 protocol;
+ u8 unused1;
+ __be16 length;
+ /* eventually use a union for the rest - assume umts for now */
+ u8 coverage;
+ u8 unused2[41];
+ u8 session_state;
+ u8 unused3[33];
+ u8 link_type;
+ u8 pdp_addr_len; /* NW-supplied PDP address len */
+ u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */
+ u8 unused4[23];
+ u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */
+ u8 dns1_addr[16]; /* NW-supplied 1st DNS address */
+ u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */
+ u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/
+ u8 wins1_addr_len; /* NW-supplied 1st Wins address len */
+ u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/
+ u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */
+ u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */
+ u8 unused5[4];
+ u8 gw_addr_len; /* NW-supplied GW address len */
+ u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */
+ u8 reserved[8];
+} __attribute__ ((packed));
+
+#define SIERRA_NET_LSI_COMMON_LEN 4
+#define SIERRA_NET_LSI_UMTS_LEN (sizeof(struct lsi_umts))
+#define SIERRA_NET_LSI_UMTS_STATUS_LEN \
+ (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
+
+/* Forward definitions */
+static void sierra_sync_timer(unsigned long syncdata);
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu);
+
+/* Our own net device operations structure */
+static const struct net_device_ops sierra_net_device_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = sierra_net_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+/* get private data associated with passed in usbnet device */
+static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
+{
+ return (struct sierra_net_data *)dev->data[0];
+}
+
+/* set private data associated with passed in usbnet device */
+static inline void sierra_net_set_private(struct usbnet *dev,
+ struct sierra_net_data *priv)
+{
+ dev->data[0] = (unsigned long)priv;
+}
+
+/* is packet IPv4 */
+static inline int is_ip(struct sk_buff *skb)
+{
+ return (skb->protocol == cpu_to_be16(ETH_P_IP));
+}
+
+/*
+ * check passed in packet and make sure that:
+ * - it is linear (no scatter/gather)
+ * - it is ethernet (mac_header properly set)
+ */
+static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev)
+{
+ skb_reset_mac_header(skb); /* ethernet header */
+
+ if (skb_is_nonlinear(skb)) {
+ netdev_err(dev->net, "Non linear buffer-dropping\n");
+ return 0;
+ }
+
+ if (!pskb_may_pull(skb, ETH_HLEN))
+ return 0;
+ skb->protocol = eth_hdr(skb)->h_proto;
+
+ return 1;
+}
+
+static const u8 *save16bit(struct param *p, const u8 *datap)
+{
+ p->is_present = 1;
+ p->word = get_unaligned_be16(datap);
+ return datap + sizeof(p->word);
+}
+
+static const u8 *save8bit(struct param *p, const u8 *datap)
+{
+ p->is_present = 1;
+ p->byte = *datap;
+ return datap + sizeof(p->byte);
+}
+
+/*----------------------------------------------------------------------------*
+ * BEGIN HIP *
+ *----------------------------------------------------------------------------*/
+/* HIP header */
+#define SIERRA_NET_HIP_HDR_LEN 4
+/* Extended HIP header */
+#define SIERRA_NET_HIP_EXT_HDR_LEN 6
+
+struct hip_hdr {
+ int hdrlen;
+ struct param payload_len;
+ struct param msgid;
+ struct param msgspecific;
+ struct param extmsgid;
+};
+
+static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh)
+{
+ const u8 *curp = buf;
+ int padded;
+
+ if (buflen < SIERRA_NET_HIP_HDR_LEN)
+ return -EPROTO;
+
+ curp = save16bit(&hh->payload_len, curp);
+ curp = save8bit(&hh->msgid, curp);
+ curp = save8bit(&hh->msgspecific, curp);
+
+ padded = hh->msgid.byte & 0x80;
+ hh->msgid.byte &= 0x7F; /* 7 bits */
+
+ hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID);
+ if (hh->extmsgid.is_present) {
+ if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN)
+ return -EPROTO;
+
+ hh->payload_len.word &= 0x3FFF; /* 14 bits */
+
+ curp = save16bit(&hh->extmsgid, curp);
+ hh->extmsgid.word &= 0x03FF; /* 10 bits */
+
+ hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN;
+ } else {
+ hh->payload_len.word &= 0x07FF; /* 11 bits */
+ hh->hdrlen = SIERRA_NET_HIP_HDR_LEN;
+ }
+
+ if (padded) {
+ hh->hdrlen++;
+ hh->payload_len.word--;
+ }
+
+ /* if real packet shorter than the claimed length */
+ if (buflen < (hh->hdrlen + hh->payload_len.word))
+ return -EINVAL;
+
+ return 0;
+}
+
+static void build_hip(u8 *buf, const u16 payloadlen,
+ struct sierra_net_data *priv)
+{
+ /* the following doesn't have the full functionality. We
+ * currently build only one kind of header, so it is faster this way
+ */
+ put_unaligned_be16(payloadlen, buf);
+ memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template));
+}
+/*----------------------------------------------------------------------------*
+ * END HIP *
+ *----------------------------------------------------------------------------*/
+
+static int sierra_net_send_cmd(struct usbnet *dev,
+ u8 *cmd, int cmdlen, const char * cmd_name)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+ int status;
+
+ status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ USB_CDC_SEND_ENCAPSULATED_COMMAND,
+ USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0,
+ priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT);
+
+ if (status != cmdlen && status != -ENODEV)
+ netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status);
+
+ return status;
+}
+
+static int sierra_net_send_sync(struct usbnet *dev)
+{
+ int status;
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ status = sierra_net_send_cmd(dev, priv->sync_msg,
+ sizeof(priv->sync_msg), "SYNC");
+
+ return status;
+}
+
+static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix)
+{
+ dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix);
+ priv->tx_hdr_template[0] = 0x3F;
+ priv->tx_hdr_template[1] = ctx_ix;
+ *((u16 *)&priv->tx_hdr_template[2]) =
+ cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID);
+}
+
+static inline int sierra_net_is_valid_addrlen(u8 len)
+{
+ return (len == sizeof(struct in_addr));
+}
+
+static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
+{
+ struct lsi_umts *lsi = (struct lsi_umts *)data;
+
+ if (datalen < sizeof(struct lsi_umts)) {
+ netdev_err(dev->net, "%s: Data length %d, exp %Zu\n",
+ __func__, datalen,
+ sizeof(struct lsi_umts));
+ return -1;
+ }
+
+ if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) {
+ netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n",
+ __func__, be16_to_cpu(lsi->length),
+ (u32)SIERRA_NET_LSI_UMTS_STATUS_LEN);
+ return -1;
+ }
+
+ /* Validate the protocol - only support UMTS for now */
+ if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) {
+ netdev_err(dev->net, "Protocol unsupported, 0x%02x\n",
+ lsi->protocol);
+ return -1;
+ }
+
+ /* Validate the link type */
+ if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) {
+ netdev_err(dev->net, "Link type unsupported: 0x%02x\n",
+ lsi->link_type);
+ return -1;
+ }
+
+ /* Validate the coverage */
+ if (lsi->coverage == SIERRA_NET_COVERAGE_NONE
+ || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
+ netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage);
+ return 0;
+ }
+
+ /* Validate the session state */
+ if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
+ netdev_err(dev->net, "Session idle, 0x%02x\n",
+ lsi->session_state);
+ return 0;
+ }
+
+ /* Set link_sense true */
+ return 1;
+}
+
+static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
+ struct hip_hdr *hh)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+ int link_up;
+
+ link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen,
+ hh->payload_len.word);
+ if (link_up < 0) {
+ netdev_err(dev->net, "Invalid LSI\n");
+ return;
+ }
+ if (link_up) {
+ sierra_net_set_ctx_index(priv, hh->msgspecific.byte);
+ priv->link_up = 1;
+ netif_carrier_on(dev->net);
+ } else {
+ priv->link_up = 0;
+ netif_carrier_off(dev->net);
+ }
+}
+
+static void sierra_net_dosync(struct usbnet *dev)
+{
+ int status;
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ /* tell modem we are ready */
+ status = sierra_net_send_sync(dev);
+ if (status < 0)
+ netdev_err(dev->net,
+ "Send SYNC failed, status %d\n", status);
+ status = sierra_net_send_sync(dev);
+ if (status < 0)
+ netdev_err(dev->net,
+ "Send SYNC failed, status %d\n", status);
+
+ /* Now, start a timer and make sure we get the Restart Indication */
+ priv->sync_timer.function = sierra_sync_timer;
+ priv->sync_timer.data = (unsigned long) dev;
+ priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY;
+ add_timer(&priv->sync_timer);
+}
+
+static void sierra_net_kevent(struct work_struct *work)
+{
+ struct sierra_net_data *priv =
+ container_of(work, struct sierra_net_data, sierra_net_kevent);
+ struct usbnet *dev = priv->usbnet;
+ int len;
+ int err;
+ u8 *buf;
+ u8 ifnum;
+
+ if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) {
+ clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags);
+
+ /* Query the modem for the LSI message */
+ buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL);
+ if (!buf) {
+ netdev_err(dev->net,
+ "failed to allocate buf for LS msg\n");
+ return;
+ }
+ ifnum = priv->ifnum;
+ len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+ USB_CDC_GET_ENCAPSULATED_RESPONSE,
+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
+ 0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN,
+ USB_CTRL_SET_TIMEOUT);
+
+ if (len < 0) {
+ netdev_err(dev->net,
+ "usb_control_msg failed, status %d\n", len);
+ } else {
+ struct hip_hdr hh;
+
+ dev_dbg(&dev->udev->dev, "%s: Received status message,"
+ " %04x bytes", __func__, len);
+
+ err = parse_hip(buf, len, &hh);
+ if (err) {
+ netdev_err(dev->net, "%s: Bad packet,"
+ " parse result %d\n", __func__, err);
+ kfree(buf);
+ return;
+ }
+
+ /* Validate packet length */
+ if (len != hh.hdrlen + hh.payload_len.word) {
+ netdev_err(dev->net, "%s: Bad packet, received"
+ " %d, expected %d\n", __func__, len,
+ hh.hdrlen + hh.payload_len.word);
+ kfree(buf);
+ return;
+ }
+
+ /* Switch on received message types */
+ switch (hh.msgid.byte) {
+ case SIERRA_NET_HIP_LSI_UMTSID:
+ dev_dbg(&dev->udev->dev, "LSI for ctx:%d",
+ hh.msgspecific.byte);
+ sierra_net_handle_lsi(dev, buf, &hh);
+ break;
+ case SIERRA_NET_HIP_RESTART_ID:
+ dev_dbg(&dev->udev->dev, "Restart reported: %d,"
+ " stopping sync timer",
+ hh.msgspecific.byte);
+ /* Got sync resp - stop timer & clear mask */
+ del_timer_sync(&priv->sync_timer);
+ clear_bit(SIERRA_NET_TIMER_EXPIRY,
+ &priv->kevent_flags);
+ break;
+ case SIERRA_NET_HIP_HSYNC_ID:
+ dev_dbg(&dev->udev->dev, "SYNC received");
+ err = sierra_net_send_sync(dev);
+ if (err < 0)
+ netdev_err(dev->net,
+ "Send SYNC failed %d\n", err);
+ break;
+ case SIERRA_NET_HIP_EXTENDEDID:
+ netdev_err(dev->net, "Unrecognized HIP msg, "
+ "extmsgid 0x%04x\n", hh.extmsgid.word);
+ break;
+ case SIERRA_NET_HIP_RCGI:
+ /* Ignored */
+ break;
+ default:
+ netdev_err(dev->net, "Unrecognized HIP msg, "
+ "msgid 0x%02x\n", hh.msgid.byte);
+ break;
+ }
+ }
+ kfree(buf);
+ }
+ /* The sync timer bit might be set */
+ if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) {
+ clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags);
+ dev_dbg(&dev->udev->dev, "Deferred sync timer expiry");
+ sierra_net_dosync(priv->usbnet);
+ }
+
+ if (priv->kevent_flags)
+ dev_dbg(&dev->udev->dev, "sierra_net_kevent done, "
+ "kevent_flags = 0x%lx", priv->kevent_flags);
+}
+
+static void sierra_net_defer_kevent(struct usbnet *dev, int work)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ set_bit(work, &priv->kevent_flags);
+ schedule_work(&priv->sierra_net_kevent);
+}
+
+/*
+ * Sync Retransmit Timer Handler. On expiry, kick the work queue
+ */
+void sierra_sync_timer(unsigned long syncdata)
+{
+ struct usbnet *dev = (struct usbnet *)syncdata;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+ /* Kick the tasklet */
+ sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY);
+}
+
+static void sierra_net_status(struct usbnet *dev, struct urb *urb)
+{
+ struct usb_cdc_notification *event;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ if (urb->actual_length < sizeof *event)
+ return;
+
+ /* Add cases to handle other standard notifications. */
+ event = urb->transfer_buffer;
+ switch (event->bNotificationType) {
+ case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+ case USB_CDC_NOTIFY_SPEED_CHANGE:
+ /* USB 305 sends those */
+ break;
+ case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
+ sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL);
+ break;
+ default:
+ netdev_err(dev->net, ": unexpected notification %02x!\n",
+ event->bNotificationType);
+ break;
+ }
+}
+
+static void sierra_net_get_drvinfo(struct net_device *net,
+ struct ethtool_drvinfo *info)
+{
+ /* Inherit standard device info */
+ usbnet_get_drvinfo(net, info);
+ strncpy(info->driver, driver_name, sizeof info->driver);
+ strncpy(info->version, DRIVER_VERSION, sizeof info->version);
+}
+
+static u32 sierra_net_get_link(struct net_device *net)
+{
+ struct usbnet *dev = netdev_priv(net);
+ /* Report link is down whenever the interface is down */
+ return sierra_net_get_private(dev)->link_up && netif_running(net);
+}
+
+static struct ethtool_ops sierra_net_ethtool_ops = {
+ .get_drvinfo = sierra_net_get_drvinfo,
+ .get_link = sierra_net_get_link,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+ .get_settings = usbnet_get_settings,
+ .set_settings = usbnet_set_settings,
+ .nway_reset = usbnet_nway_reset,
+};
+
+/* MTU can not be more than 1500 bytes, enforce it. */
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
+{
+ if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU)
+ return -EINVAL;
+
+ return usbnet_change_mtu(net, new_mtu);
+}
+
+static int is_whitelisted(const u8 ifnum,
+ const struct sierra_net_iface_info *whitelist)
+{
+ if (whitelist) {
+ const u8 *list = whitelist->ifaceinfo;
+ int i;
+
+ for (i = 0; i < whitelist->infolen; i++) {
+ if (list[i] == ifnum)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
+{
+ int result = 0;
+ u16 *attrdata;
+
+ attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL);
+ if (!attrdata)
+ return -ENOMEM;
+
+ result = usb_control_msg(
+ dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ /* _u8 vendor specific request */
+ SWI_USB_REQUEST_GET_FW_ATTR,
+ USB_DIR_IN | USB_TYPE_VENDOR, /* __u8 request type */
+ 0x0000, /* __u16 value not used */
+ 0x0000, /* __u16 index not used */
+ attrdata, /* char *data */
+ sizeof(*attrdata), /* __u16 size */
+ USB_CTRL_SET_TIMEOUT); /* int timeout */
+
+ if (result < 0) {
+ kfree(attrdata);
+ return -EIO;
+ }
+
+ *datap = *attrdata;
+
+ kfree(attrdata);
+ return result;
+}
+
+/*
+ * collects the bulk endpoints, the status endpoint.
+ */
+static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ u8 ifacenum;
+ u8 numendpoints;
+ u16 fwattr = 0;
+ int status;
+ struct ethhdr *eth;
+ struct sierra_net_data *priv;
+ static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
+ 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
+ static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
+ 0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00};
+
+ struct sierra_net_info_data *data =
+ (struct sierra_net_info_data *)dev->driver_info->data;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
+ /* We only accept certain interfaces */
+ if (!is_whitelisted(ifacenum, &data->whitelist)) {
+ dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum);
+ return -ENODEV;
+ }
+ numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
+ /* We have three endpoints, bulk in and out, and a status */
+ if (numendpoints != 3) {
+ dev_err(&dev->udev->dev, "Expected 3 endpoints, found: %d",
+ numendpoints);
+ return -ENODEV;
+ }
+ /* Status endpoint set in usbnet_get_endpoints() */
+ dev->status = NULL;
+ status = usbnet_get_endpoints(dev, intf);
+ if (status < 0) {
+ dev_err(&dev->udev->dev, "Error in usbnet_get_endpoints (%d)",
+ status);
+ return -ENODEV;
+ }
+ /* Initialize sierra private data */
+ priv = kzalloc(sizeof *priv, GFP_KERNEL);
+ if (!priv) {
+ dev_err(&dev->udev->dev, "No memory");
+ return -ENOMEM;
+ }
+
+ priv->usbnet = dev;
+ priv->ifnum = ifacenum;
+ dev->net->netdev_ops = &sierra_net_device_ops;
+
+ /* change MAC addr to include, ifacenum, and to be unique */
+ dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
+ dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
+
+ /* we will have to manufacture ethernet headers, prepare template */
+ eth = (struct ethhdr *)priv->ethr_hdr_tmpl;
+ memcpy(&eth->h_dest, dev->net->dev_addr, ETH_ALEN);
+ eth->h_proto = cpu_to_be16(ETH_P_IP);
+
+ /* prepare shutdown message template */
+ memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg));
+ /* set context index initially to 0 - prepares tx hdr template */
+ sierra_net_set_ctx_index(priv, 0);
+
+ /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
+ dev->rx_urb_size = data->rx_urb_size;
+ if (dev->udev->speed != USB_SPEED_HIGH)
+ dev->rx_urb_size = min_t(size_t, 4096, data->rx_urb_size);
+
+ dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN;
+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+
+ /* Set up the netdev */
+ dev->net->flags |= IFF_NOARP;
+ dev->net->ethtool_ops = &sierra_net_ethtool_ops;
+ netif_carrier_off(dev->net);
+
+ sierra_net_set_private(dev, priv);
+
+ priv->kevent_flags = 0;
+
+ /* Use the shared workqueue */
+ INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent);
+
+ /* Only need to do this once */
+ init_timer(&priv->sync_timer);
+
+ /* verify fw attributes */
+ status = sierra_net_get_fw_attr(dev, &fwattr);
+ dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr);
+
+ /* test whether firmware supports DHCP */
+ if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) {
+ /* found incompatible firmware version */
+ dev_err(&dev->udev->dev, "Incompatible driver and firmware"
+ " versions\n");
+ kfree(priv);
+ return -ENODEV;
+ }
+ /* prepare sync message from template */
+ memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
+
+ return 0;
+}
+
+static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int status;
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ /* Kill the timer then flush the work queue */
+ del_timer_sync(&priv->sync_timer);
+
+ flush_scheduled_work();
+
+ /* tell modem we are going away */
+ status = sierra_net_send_cmd(dev, priv->shdwn_msg,
+ sizeof(priv->shdwn_msg), "Shutdown");
+ if (status < 0)
+ netdev_err(dev->net,
+ "usb_control_msg failed, status %d\n", status);
+
+ sierra_net_set_private(dev, NULL);
+
+ kfree(priv);
+}
+
+static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev,
+ struct sk_buff *skb, int len)
+{
+ struct sk_buff *new_skb;
+
+ /* clone skb */
+ new_skb = skb_clone(skb, GFP_ATOMIC);
+
+ /* remove len bytes from original */
+ skb_pull(skb, len);
+
+ /* trim next packet to it's length */
+ if (new_skb) {
+ skb_trim(new_skb, len);
+ } else {
+ if (netif_msg_rx_err(dev))
+ netdev_err(dev->net, "failed to get skb\n");
+ dev->net->stats.rx_dropped++;
+ }
+
+ return new_skb;
+}
+
+/* ---------------------------- Receive data path ----------------------*/
+static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ int err;
+ struct hip_hdr hh;
+ struct sk_buff *new_skb;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ /* could contain multiple packets */
+ while (likely(skb->len)) {
+ err = parse_hip(skb->data, skb->len, &hh);
+ if (err) {
+ if (netif_msg_rx_err(dev))
+ netdev_err(dev->net, "Invalid HIP header %d\n",
+ err);
+ /* dev->net->stats.rx_errors incremented by caller */
+ dev->net->stats.rx_length_errors++;
+ return 0;
+ }
+
+ /* Validate Extended HIP header */
+ if (!hh.extmsgid.is_present
+ || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) {
+ if (netif_msg_rx_err(dev))
+ netdev_err(dev->net, "HIP/ETH: Invalid pkt\n");
+
+ dev->net->stats.rx_frame_errors++;
+ /* dev->net->stats.rx_errors incremented by caller */;
+ return 0;
+ }
+
+ skb_pull(skb, hh.hdrlen);
+
+ /* We are going to accept this packet, prepare it */
+ memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
+ ETH_HLEN);
+
+ /* Last packet in batch handled by usbnet */
+ if (hh.payload_len.word == skb->len)
+ return 1;
+
+ new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word);
+ if (new_skb)
+ usbnet_skb_return(dev, new_skb);
+
+ } /* while */
+
+ return 0;
+}
+
+/* ---------------------------- Transmit data path ----------------------*/
+struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+ gfp_t flags)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+ u16 len;
+ bool need_tail;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+ if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
+ /* enough head room as is? */
+ if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) {
+ /* Save the Eth/IP length and set up HIP hdr */
+ len = skb->len;
+ skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN);
+ /* Handle ZLP issue */
+ need_tail = ((len + SIERRA_NET_HIP_EXT_HDR_LEN)
+ % dev->maxpacket == 0);
+ if (need_tail) {
+ if (unlikely(skb_tailroom(skb) == 0)) {
+ netdev_err(dev->net, "tx_fixup:"
+ "no room for packet\n");
+ dev_kfree_skb_any(skb);
+ return NULL;
+ } else {
+ skb->data[skb->len] = 0;
+ __skb_put(skb, 1);
+ len = len + 1;
+ }
+ }
+ build_hip(skb->data, len, priv);
+ return skb;
+ } else {
+ /*
+ * compensate in the future if necessary
+ */
+ netdev_err(dev->net, "tx_fixup: no room for HIP\n");
+ } /* headroom */
+ }
+
+ if (!priv->link_up)
+ dev->net->stats.tx_carrier_errors++;
+
+ /* tx_dropped incremented by usbnet */
+
+ /* filter the packet out, release it */
+ dev_kfree_skb_any(skb);
+ return NULL;
+}
+
+static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
+static const struct sierra_net_info_data sierra_net_info_data_68A3 = {
+ .rx_urb_size = 8 * 1024,
+ .whitelist = {
+ .infolen = ARRAY_SIZE(sierra_net_ifnum_list),
+ .ifaceinfo = sierra_net_ifnum_list
+ }
+};
+
+static const struct driver_info sierra_net_info_68A3 = {
+ .description = "Sierra Wireless USB-to-WWAN Modem",
+ .flags = FLAG_WWAN | FLAG_SEND_ZLP,
+ .bind = sierra_net_bind,
+ .unbind = sierra_net_unbind,
+ .status = sierra_net_status,
+ .rx_fixup = sierra_net_rx_fixup,
+ .tx_fixup = sierra_net_tx_fixup,
+ .data = (unsigned long)&sierra_net_info_data_68A3,
+};
+
+static const struct usb_device_id products[] = {
+ {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
+ .driver_info = (unsigned long) &sierra_net_info_68A3},
+
+ {}, /* last item */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+/* We are based on usbnet, so let it handle the USB driver specifics */
+static struct usb_driver sierra_net_driver = {
+ .name = "sierra_net",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+ .no_dynamic_id = 1,
+};
+
+static int __init sierra_net_init(void)
+{
+ BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data)
+ < sizeof(struct cdc_state));
+
+ return usb_register(&sierra_net_driver);
+}
+
+static void __exit sierra_net_exit(void)
+{
+ usb_deregister(&sierra_net_driver);
+}
+
+module_exit(sierra_net_exit);
+module_init(sierra_net_init);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
new file mode 100644
index 00000000000..35b98b1b79e
--- /dev/null
+++ b/drivers/net/usb/smsc75xx.c
@@ -0,0 +1,1289 @@
+ /***************************************************************************
+ *
+ * Copyright (C) 2007-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+#include <linux/slab.h>
+#include "smsc75xx.h"
+
+#define SMSC_CHIPNAME "smsc75xx"
+#define SMSC_DRIVER_VERSION "1.0.0"
+#define HS_USB_PKT_SIZE (512)
+#define FS_USB_PKT_SIZE (64)
+#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
+#define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE)
+#define DEFAULT_BULK_IN_DELAY (0x00002000)
+#define MAX_SINGLE_PACKET_SIZE (9000)
+#define LAN75XX_EEPROM_MAGIC (0x7500)
+#define EEPROM_MAC_OFFSET (0x01)
+#define DEFAULT_TX_CSUM_ENABLE (true)
+#define DEFAULT_RX_CSUM_ENABLE (true)
+#define DEFAULT_TSO_ENABLE (true)
+#define SMSC75XX_INTERNAL_PHY_ID (1)
+#define SMSC75XX_TX_OVERHEAD (8)
+#define MAX_RX_FIFO_SIZE (20 * 1024)
+#define MAX_TX_FIFO_SIZE (12 * 1024)
+#define USB_VENDOR_ID_SMSC (0x0424)
+#define USB_PRODUCT_ID_LAN7500 (0x7500)
+#define USB_PRODUCT_ID_LAN7505 (0x7505)
+
+#define check_warn(ret, fmt, args...) \
+ ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
+
+#define check_warn_return(ret, fmt, args...) \
+ ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } })
+
+#define check_warn_goto_done(ret, fmt, args...) \
+ ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } })
+
+struct smsc75xx_priv {
+ struct usbnet *dev;
+ u32 rfe_ctl;
+ u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN];
+ bool use_rx_csum;
+ struct mutex dataport_mutex;
+ spinlock_t rfe_ctl_lock;
+ struct work_struct set_multicast;
+};
+
+struct usb_context {
+ struct usb_ctrlrequest req;
+ struct usbnet *dev;
+};
+
+static int turbo_mode = true;
+module_param(turbo_mode, bool, 0644);
+MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+
+static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
+ u32 *data)
+{
+ u32 *buf = kmalloc(4, GFP_KERNEL);
+ int ret;
+
+ BUG_ON(!dev);
+
+ if (!buf)
+ return -ENOMEM;
+
+ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+ USB_VENDOR_REQUEST_READ_REGISTER,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 00, index, buf, 4, USB_CTRL_GET_TIMEOUT);
+
+ if (unlikely(ret < 0))
+ netdev_warn(dev->net,
+ "Failed to read register index 0x%08x", index);
+
+ le32_to_cpus(buf);
+ *data = *buf;
+ kfree(buf);
+
+ return ret;
+}
+
+static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
+ u32 data)
+{
+ u32 *buf = kmalloc(4, GFP_KERNEL);
+ int ret;
+
+ BUG_ON(!dev);
+
+ if (!buf)
+ return -ENOMEM;
+
+ *buf = data;
+ cpu_to_le32s(buf);
+
+ ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ USB_VENDOR_REQUEST_WRITE_REGISTER,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 00, index, buf, 4, USB_CTRL_SET_TIMEOUT);
+
+ if (unlikely(ret < 0))
+ netdev_warn(dev->net,
+ "Failed to write register index 0x%08x", index);
+
+ kfree(buf);
+
+ return ret;
+}
+
+/* Loop until the read is completed with timeout
+ * called with phy_mutex held */
+static int smsc75xx_phy_wait_not_busy(struct usbnet *dev)
+{
+ unsigned long start_time = jiffies;
+ u32 val;
+ int ret;
+
+ do {
+ ret = smsc75xx_read_reg(dev, MII_ACCESS, &val);
+ check_warn_return(ret, "Error reading MII_ACCESS");
+
+ if (!(val & MII_ACCESS_BUSY))
+ return 0;
+ } while (!time_after(jiffies, start_time + HZ));
+
+ return -EIO;
+}
+
+static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ u32 val, addr;
+ int ret;
+
+ mutex_lock(&dev->phy_mutex);
+
+ /* confirm MII not busy */
+ ret = smsc75xx_phy_wait_not_busy(dev);
+ check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read");
+
+ /* set the address, index & direction (read from PHY) */
+ phy_id &= dev->mii.phy_id_mask;
+ idx &= dev->mii.reg_num_mask;
+ addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
+ | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
+ | MII_ACCESS_READ;
+ ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
+ check_warn_goto_done(ret, "Error writing MII_ACCESS");
+
+ ret = smsc75xx_phy_wait_not_busy(dev);
+ check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx);
+
+ ret = smsc75xx_read_reg(dev, MII_DATA, &val);
+ check_warn_goto_done(ret, "Error reading MII_DATA");
+
+ ret = (u16)(val & 0xFFFF);
+
+done:
+ mutex_unlock(&dev->phy_mutex);
+ return ret;
+}
+
+static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
+ int regval)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ u32 val, addr;
+ int ret;
+
+ mutex_lock(&dev->phy_mutex);
+
+ /* confirm MII not busy */
+ ret = smsc75xx_phy_wait_not_busy(dev);
+ check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write");
+
+ val = regval;
+ ret = smsc75xx_write_reg(dev, MII_DATA, val);
+ check_warn_goto_done(ret, "Error writing MII_DATA");
+
+ /* set the address, index & direction (write to PHY) */
+ phy_id &= dev->mii.phy_id_mask;
+ idx &= dev->mii.reg_num_mask;
+ addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
+ | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
+ | MII_ACCESS_WRITE;
+ ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
+ check_warn_goto_done(ret, "Error writing MII_ACCESS");
+
+ ret = smsc75xx_phy_wait_not_busy(dev);
+ check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx);
+
+done:
+ mutex_unlock(&dev->phy_mutex);
+}
+
+static int smsc75xx_wait_eeprom(struct usbnet *dev)
+{
+ unsigned long start_time = jiffies;
+ u32 val;
+ int ret;
+
+ do {
+ ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
+ check_warn_return(ret, "Error reading E2P_CMD");
+
+ if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT))
+ break;
+ udelay(40);
+ } while (!time_after(jiffies, start_time + HZ));
+
+ if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) {
+ netdev_warn(dev->net, "EEPROM read operation timeout");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev)
+{
+ unsigned long start_time = jiffies;
+ u32 val;
+ int ret;
+
+ do {
+ ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
+ check_warn_return(ret, "Error reading E2P_CMD");
+
+ if (!(val & E2P_CMD_BUSY))
+ return 0;
+
+ udelay(40);
+ } while (!time_after(jiffies, start_time + HZ));
+
+ netdev_warn(dev->net, "EEPROM is busy");
+ return -EIO;
+}
+
+static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
+ u8 *data)
+{
+ u32 val;
+ int i, ret;
+
+ BUG_ON(!dev);
+ BUG_ON(!data);
+
+ ret = smsc75xx_eeprom_confirm_not_busy(dev);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < length; i++) {
+ val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR);
+ ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+ check_warn_return(ret, "Error writing E2P_CMD");
+
+ ret = smsc75xx_wait_eeprom(dev);
+ if (ret < 0)
+ return ret;
+
+ ret = smsc75xx_read_reg(dev, E2P_DATA, &val);
+ check_warn_return(ret, "Error reading E2P_DATA");
+
+ data[i] = val & 0xFF;
+ offset++;
+ }
+
+ return 0;
+}
+
+static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
+ u8 *data)
+{
+ u32 val;
+ int i, ret;
+
+ BUG_ON(!dev);
+ BUG_ON(!data);
+
+ ret = smsc75xx_eeprom_confirm_not_busy(dev);
+ if (ret)
+ return ret;
+
+ /* Issue write/erase enable command */
+ val = E2P_CMD_BUSY | E2P_CMD_EWEN;
+ ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+ check_warn_return(ret, "Error writing E2P_CMD");
+
+ ret = smsc75xx_wait_eeprom(dev);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < length; i++) {
+
+ /* Fill data register */
+ val = data[i];
+ ret = smsc75xx_write_reg(dev, E2P_DATA, val);
+ check_warn_return(ret, "Error writing E2P_DATA");
+
+ /* Send "write" command */
+ val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR);
+ ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+ check_warn_return(ret, "Error writing E2P_CMD");
+
+ ret = smsc75xx_wait_eeprom(dev);
+ if (ret < 0)
+ return ret;
+
+ offset++;
+ }
+
+ return 0;
+}
+
+static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
+{
+ int i, ret;
+
+ for (i = 0; i < 100; i++) {
+ u32 dp_sel;
+ ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
+ check_warn_return(ret, "Error reading DP_SEL");
+
+ if (dp_sel & DP_SEL_DPRDY)
+ return 0;
+
+ udelay(40);
+ }
+
+ netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out");
+
+ return -EIO;
+}
+
+static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
+ u32 length, u32 *buf)
+{
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ u32 dp_sel;
+ int i, ret;
+
+ mutex_lock(&pdata->dataport_mutex);
+
+ ret = smsc75xx_dataport_wait_not_busy(dev);
+ check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry");
+
+ ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
+ check_warn_goto_done(ret, "Error reading DP_SEL");
+
+ dp_sel &= ~DP_SEL_RSEL;
+ dp_sel |= ram_select;
+ ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel);
+ check_warn_goto_done(ret, "Error writing DP_SEL");
+
+ for (i = 0; i < length; i++) {
+ ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i);
+ check_warn_goto_done(ret, "Error writing DP_ADDR");
+
+ ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]);
+ check_warn_goto_done(ret, "Error writing DP_DATA");
+
+ ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE);
+ check_warn_goto_done(ret, "Error writing DP_CMD");
+
+ ret = smsc75xx_dataport_wait_not_busy(dev);
+ check_warn_goto_done(ret, "smsc75xx_dataport_write timeout");
+ }
+
+done:
+ mutex_unlock(&pdata->dataport_mutex);
+ return ret;
+}
+
+/* returns hash bit number for given MAC address */
+static u32 smsc75xx_hash(char addr[ETH_ALEN])
+{
+ return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff;
+}
+
+static void smsc75xx_deferred_multicast_write(struct work_struct *param)
+{
+ struct smsc75xx_priv *pdata =
+ container_of(param, struct smsc75xx_priv, set_multicast);
+ struct usbnet *dev = pdata->dev;
+ int ret;
+
+ netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x",
+ pdata->rfe_ctl);
+
+ smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN,
+ DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table);
+
+ ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+ check_warn(ret, "Error writing RFE_CRL");
+}
+
+static void smsc75xx_set_multicast(struct net_device *netdev)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+ pdata->rfe_ctl &=
+ ~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF);
+ pdata->rfe_ctl |= RFE_CTL_AB;
+
+ for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++)
+ pdata->multicast_hash_table[i] = 0;
+
+ if (dev->net->flags & IFF_PROMISC) {
+ netif_dbg(dev, drv, dev->net, "promiscuous mode enabled");
+ pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU;
+ } else if (dev->net->flags & IFF_ALLMULTI) {
+ netif_dbg(dev, drv, dev->net, "receive all multicast enabled");
+ pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF;
+ } else if (!netdev_mc_empty(dev->net)) {
+ struct dev_mc_list *mc_list;
+
+ netif_dbg(dev, drv, dev->net, "receive multicast hash filter");
+
+ pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF;
+
+ netdev_for_each_mc_addr(mc_list, netdev) {
+ u32 bitnum = smsc75xx_hash(mc_list->dmi_addr);
+ pdata->multicast_hash_table[bitnum / 32] |=
+ (1 << (bitnum % 32));
+ }
+ } else {
+ netif_dbg(dev, drv, dev->net, "receive own packets only");
+ pdata->rfe_ctl |= RFE_CTL_DPF;
+ }
+
+ spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+
+ /* defer register writes to a sleepable context */
+ schedule_work(&pdata->set_multicast);
+}
+
+static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
+ u16 lcladv, u16 rmtadv)
+{
+ u32 flow = 0, fct_flow = 0;
+ int ret;
+
+ if (duplex == DUPLEX_FULL) {
+ u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
+
+ if (cap & FLOW_CTRL_TX) {
+ flow = (FLOW_TX_FCEN | 0xFFFF);
+ /* set fct_flow thresholds to 20% and 80% */
+ fct_flow = (8 << 8) | 32;
+ }
+
+ if (cap & FLOW_CTRL_RX)
+ flow |= FLOW_RX_FCEN;
+
+ netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s",
+ (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
+ (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
+ } else {
+ netif_dbg(dev, link, dev->net, "half duplex");
+ }
+
+ ret = smsc75xx_write_reg(dev, FLOW, flow);
+ check_warn_return(ret, "Error writing FLOW");
+
+ ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow);
+ check_warn_return(ret, "Error writing FCT_FLOW");
+
+ return 0;
+}
+
+static int smsc75xx_link_reset(struct usbnet *dev)
+{
+ struct mii_if_info *mii = &dev->mii;
+ struct ethtool_cmd ecmd;
+ u16 lcladv, rmtadv;
+ int ret;
+
+ /* clear interrupt status */
+ ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
+ check_warn_return(ret, "Error reading PHY_INT_SRC");
+
+ ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
+ check_warn_return(ret, "Error writing INT_STS");
+
+ mii_check_media(mii, 1, 1);
+ mii_ethtool_gset(&dev->mii, &ecmd);
+ lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
+ rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
+
+ netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x"
+ " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+
+ return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
+}
+
+static void smsc75xx_status(struct usbnet *dev, struct urb *urb)
+{
+ u32 intdata;
+
+ if (urb->actual_length != 4) {
+ netdev_warn(dev->net,
+ "unexpected urb length %d", urb->actual_length);
+ return;
+ }
+
+ memcpy(&intdata, urb->transfer_buffer, 4);
+ le32_to_cpus(&intdata);
+
+ netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata);
+
+ if (intdata & INT_ENP_PHY_INT)
+ usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+ else
+ netdev_warn(dev->net,
+ "unexpected interrupt, intdata=0x%08X", intdata);
+}
+
+/* Enable or disable Rx checksum offload engine */
+static int smsc75xx_set_rx_csum_offload(struct usbnet *dev)
+{
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+ if (pdata->use_rx_csum)
+ pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM;
+ else
+ pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM);
+
+ spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+
+ ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+ check_warn_return(ret, "Error writing RFE_CTL");
+
+ return 0;
+}
+
+static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net)
+{
+ return MAX_EEPROM_SIZE;
+}
+
+static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *ee, u8 *data)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+
+ ee->magic = LAN75XX_EEPROM_MAGIC;
+
+ return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data);
+}
+
+static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *ee, u8 *data)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+
+ if (ee->magic != LAN75XX_EEPROM_MAGIC) {
+ netdev_warn(dev->net,
+ "EEPROM: magic value mismatch: 0x%x", ee->magic);
+ return -EINVAL;
+ }
+
+ return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data);
+}
+
+static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+ return pdata->use_rx_csum;
+}
+
+static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+ pdata->use_rx_csum = !!val;
+
+ return smsc75xx_set_rx_csum_offload(dev);
+}
+
+static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data)
+{
+ if (data)
+ netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+ else
+ netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+ return 0;
+}
+
+static const struct ethtool_ops smsc75xx_ethtool_ops = {
+ .get_link = usbnet_get_link,
+ .nway_reset = usbnet_nway_reset,
+ .get_drvinfo = usbnet_get_drvinfo,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+ .get_settings = usbnet_get_settings,
+ .set_settings = usbnet_set_settings,
+ .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len,
+ .get_eeprom = smsc75xx_ethtool_get_eeprom,
+ .set_eeprom = smsc75xx_ethtool_set_eeprom,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_hw_csum,
+ .get_rx_csum = smsc75xx_ethtool_get_rx_csum,
+ .set_rx_csum = smsc75xx_ethtool_set_rx_csum,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = smsc75xx_ethtool_set_tso,
+};
+
+static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+
+ if (!netif_running(netdev))
+ return -EINVAL;
+
+ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static void smsc75xx_init_mac_address(struct usbnet *dev)
+{
+ /* try reading mac address from EEPROM */
+ if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
+ dev->net->dev_addr) == 0) {
+ if (is_valid_ether_addr(dev->net->dev_addr)) {
+ /* eeprom values are valid so use them */
+ netif_dbg(dev, ifup, dev->net,
+ "MAC address read from EEPROM");
+ return;
+ }
+ }
+
+ /* no eeprom, or eeprom values are invalid. generate random MAC */
+ random_ether_addr(dev->net->dev_addr);
+ netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr");
+}
+
+static int smsc75xx_set_mac_address(struct usbnet *dev)
+{
+ u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 |
+ dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24;
+ u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;
+
+ int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi);
+ check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret);
+
+ ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo);
+ check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret);
+
+ addr_hi |= ADDR_FILTX_FB_VALID;
+ ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi);
+ check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret);
+
+ ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo);
+ check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret);
+
+ return 0;
+}
+
+static int smsc75xx_phy_initialize(struct usbnet *dev)
+{
+ int bmcr, timeout = 0;
+
+ /* Initialize MII structure */
+ dev->mii.dev = dev->net;
+ dev->mii.mdio_read = smsc75xx_mdio_read;
+ dev->mii.mdio_write = smsc75xx_mdio_write;
+ dev->mii.phy_id_mask = 0x1f;
+ dev->mii.reg_num_mask = 0x1f;
+ dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
+
+ /* reset phy and wait for reset to complete */
+ smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+ do {
+ msleep(10);
+ bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
+ check_warn_return(bmcr, "Error reading MII_BMCR");
+ timeout++;
+ } while ((bmcr & MII_BMCR) && (timeout < 100));
+
+ if (timeout >= 100) {
+ netdev_warn(dev->net, "timeout on PHY Reset");
+ return -EIO;
+ }
+
+ smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
+ ADVERTISE_PAUSE_ASYM);
+
+ /* read to clear */
+ smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
+ check_warn_return(bmcr, "Error reading PHY_INT_SRC");
+
+ smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
+ PHY_INT_MASK_DEFAULT);
+ mii_nway_restart(&dev->mii);
+
+ netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
+ return 0;
+}
+
+static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
+{
+ int ret = 0;
+ u32 buf;
+ bool rxenabled;
+
+ ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+ check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
+
+ rxenabled = ((buf & MAC_RX_RXEN) != 0);
+
+ if (rxenabled) {
+ buf &= ~MAC_RX_RXEN;
+ ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+ check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+ }
+
+ /* add 4 to size for FCS */
+ buf &= ~MAC_RX_MAX_SIZE;
+ buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE);
+
+ ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+ check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+
+ if (rxenabled) {
+ buf |= MAC_RX_RXEN;
+ ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+ check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+ }
+
+ return 0;
+}
+
+static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+
+ int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
+ check_warn_return(ret, "Failed to set mac rx frame length");
+
+ return usbnet_change_mtu(netdev, new_mtu);
+}
+
+static int smsc75xx_reset(struct usbnet *dev)
+{
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ u32 buf;
+ int ret = 0, timeout;
+
+ netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset");
+
+ ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+ check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+ buf |= HW_CFG_LRST;
+
+ ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+ check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+ timeout = 0;
+ do {
+ msleep(10);
+ ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+ check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+ timeout++;
+ } while ((buf & HW_CFG_LRST) && (timeout < 100));
+
+ if (timeout >= 100) {
+ netdev_warn(dev->net, "timeout on completion of Lite Reset");
+ return -EIO;
+ }
+
+ netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY");
+
+ ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+ check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
+
+ buf |= PMT_CTL_PHY_RST;
+
+ ret = smsc75xx_write_reg(dev, PMT_CTL, buf);
+ check_warn_return(ret, "Failed to write PMT_CTL: %d", ret);
+
+ timeout = 0;
+ do {
+ msleep(10);
+ ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+ check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
+ timeout++;
+ } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100));
+
+ if (timeout >= 100) {
+ netdev_warn(dev->net, "timeout waiting for PHY Reset");
+ return -EIO;
+ }
+
+ netif_dbg(dev, ifup, dev->net, "PHY reset complete");
+
+ smsc75xx_init_mac_address(dev);
+
+ ret = smsc75xx_set_mac_address(dev);
+ check_warn_return(ret, "Failed to set mac address");
+
+ netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr);
+
+ ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+ check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf);
+
+ buf |= HW_CFG_BIR;
+
+ ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+ check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+ ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+ check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after "
+ "writing HW_CFG_BIR: 0x%08x", buf);
+
+ if (!turbo_mode) {
+ buf = 0;
+ dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
+ } else if (dev->udev->speed == USB_SPEED_HIGH) {
+ buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
+ dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
+ } else {
+ buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
+ dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
+ }
+
+ netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld",
+ (ulong)dev->rx_urb_size);
+
+ ret = smsc75xx_write_reg(dev, BURST_CAP, buf);
+ check_warn_return(ret, "Failed to write BURST_CAP: %d", ret);
+
+ ret = smsc75xx_read_reg(dev, BURST_CAP, &buf);
+ check_warn_return(ret, "Failed to read BURST_CAP: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from BURST_CAP after writing: 0x%08x", buf);
+
+ ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
+ check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret);
+
+ ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf);
+ check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from BULK_IN_DLY after writing: 0x%08x", buf);
+
+ if (turbo_mode) {
+ ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+ check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
+
+ buf |= (HW_CFG_MEF | HW_CFG_BCE);
+
+ ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+ check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+ ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+ check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
+ }
+
+ /* set FIFO sizes */
+ buf = (MAX_RX_FIFO_SIZE - 512) / 512;
+ ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf);
+ check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf);
+
+ buf = (MAX_TX_FIFO_SIZE - 512) / 512;
+ ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf);
+ check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf);
+
+ ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
+ check_warn_return(ret, "Failed to write INT_STS: %d", ret);
+
+ ret = smsc75xx_read_reg(dev, ID_REV, &buf);
+ check_warn_return(ret, "Failed to read ID_REV: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf);
+
+ /* Configure GPIO pins as LED outputs */
+ ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf);
+ check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret);
+
+ buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL);
+ buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL;
+
+ ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf);
+ check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret);
+
+ ret = smsc75xx_write_reg(dev, FLOW, 0);
+ check_warn_return(ret, "Failed to write FLOW: %d", ret);
+
+ ret = smsc75xx_write_reg(dev, FCT_FLOW, 0);
+ check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret);
+
+ /* Don't need rfe_ctl_lock during initialisation */
+ ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+ check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
+
+ pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF;
+
+ ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+ check_warn_return(ret, "Failed to write RFE_CTL: %d", ret);
+
+ ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+ check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl);
+
+ /* Enable or disable checksum offload engines */
+ ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE);
+ ret = smsc75xx_set_rx_csum_offload(dev);
+ check_warn_return(ret, "Failed to set rx csum offload: %d", ret);
+
+ smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE);
+
+ smsc75xx_set_multicast(dev->net);
+
+ ret = smsc75xx_phy_initialize(dev);
+ check_warn_return(ret, "Failed to initialize PHY: %d", ret);
+
+ ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf);
+ check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret);
+
+ /* enable PHY interrupts */
+ buf |= INT_ENP_PHY_INT;
+
+ ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
+ check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
+
+ ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
+ check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
+
+ buf |= MAC_TX_TXEN;
+
+ ret = smsc75xx_write_reg(dev, MAC_TX, buf);
+ check_warn_return(ret, "Failed to write MAC_TX: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf);
+
+ ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf);
+ check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret);
+
+ buf |= FCT_TX_CTL_EN;
+
+ ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf);
+ check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf);
+
+ ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
+ check_warn_return(ret, "Failed to set max rx frame length");
+
+ ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+ check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
+
+ buf |= MAC_RX_RXEN;
+
+ ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+ check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf);
+
+ ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf);
+ check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret);
+
+ buf |= FCT_RX_CTL_EN;
+
+ ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf);
+ check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret);
+
+ netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf);
+
+ netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0");
+ return 0;
+}
+
+static const struct net_device_ops smsc75xx_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = smsc75xx_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = smsc75xx_ioctl,
+ .ndo_set_multicast_list = smsc75xx_set_multicast,
+};
+
+static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct smsc75xx_priv *pdata = NULL;
+ int ret;
+
+ printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
+
+ ret = usbnet_get_endpoints(dev, intf);
+ check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret);
+
+ dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv),
+ GFP_KERNEL);
+
+ pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ if (!pdata) {
+ netdev_warn(dev->net, "Unable to allocate smsc75xx_priv");
+ return -ENOMEM;
+ }
+
+ pdata->dev = dev;
+
+ spin_lock_init(&pdata->rfe_ctl_lock);
+ mutex_init(&pdata->dataport_mutex);
+
+ INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);
+
+ pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+
+ /* We have to advertise SG otherwise TSO cannot be enabled */
+ dev->net->features |= NETIF_F_SG;
+
+ /* Init all registers */
+ ret = smsc75xx_reset(dev);
+
+ dev->net->netdev_ops = &smsc75xx_netdev_ops;
+ dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
+ dev->net->flags |= IFF_MULTICAST;
+ dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
+ return 0;
+}
+
+static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ if (pdata) {
+ netif_dbg(dev, ifdown, dev->net, "free pdata");
+ kfree(pdata);
+ pdata = NULL;
+ dev->data[0] = 0;
+ }
+}
+
+static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a,
+ u32 rx_cmd_b)
+{
+ if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
+ skb->ip_summed = CHECKSUM_NONE;
+ } else {
+ skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT));
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ }
+}
+
+static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+ while (skb->len > 0) {
+ u32 rx_cmd_a, rx_cmd_b, align_count, size;
+ struct sk_buff *ax_skb;
+ unsigned char *packet;
+
+ memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a));
+ le32_to_cpus(&rx_cmd_a);
+ skb_pull(skb, 4);
+
+ memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
+ le32_to_cpus(&rx_cmd_b);
+ skb_pull(skb, 4 + NET_IP_ALIGN);
+
+ packet = skb->data;
+
+ /* get the packet length */
+ size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN;
+ align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
+
+ if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
+ netif_dbg(dev, rx_err, dev->net,
+ "Error rx_cmd_a=0x%08x", rx_cmd_a);
+ dev->net->stats.rx_errors++;
+ dev->net->stats.rx_dropped++;
+
+ if (rx_cmd_a & RX_CMD_A_FCS)
+ dev->net->stats.rx_crc_errors++;
+ else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
+ dev->net->stats.rx_frame_errors++;
+ } else {
+ /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
+ if (unlikely(size > (ETH_FRAME_LEN + 12))) {
+ netif_dbg(dev, rx_err, dev->net,
+ "size err rx_cmd_a=0x%08x", rx_cmd_a);
+ return 0;
+ }
+
+ /* last frame in this batch */
+ if (skb->len == size) {
+ if (pdata->use_rx_csum)
+ smsc75xx_rx_csum_offload(skb, rx_cmd_a,
+ rx_cmd_b);
+ else
+ skb->ip_summed = CHECKSUM_NONE;
+
+ skb_trim(skb, skb->len - 4); /* remove fcs */
+ skb->truesize = size + sizeof(struct sk_buff);
+
+ return 1;
+ }
+
+ ax_skb = skb_clone(skb, GFP_ATOMIC);
+ if (unlikely(!ax_skb)) {
+ netdev_warn(dev->net, "Error allocating skb");
+ return 0;
+ }
+
+ ax_skb->len = size;
+ ax_skb->data = packet;
+ skb_set_tail_pointer(ax_skb, size);
+
+ if (pdata->use_rx_csum)
+ smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a,
+ rx_cmd_b);
+ else
+ ax_skb->ip_summed = CHECKSUM_NONE;
+
+ skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
+ ax_skb->truesize = size + sizeof(struct sk_buff);
+
+ usbnet_skb_return(dev, ax_skb);
+ }
+
+ skb_pull(skb, size);
+
+ /* padding bytes before the next frame starts */
+ if (skb->len)
+ skb_pull(skb, align_count);
+ }
+
+ if (unlikely(skb->len < 0)) {
+ netdev_warn(dev->net, "invalid rx length<0 %d", skb->len);
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev,
+ struct sk_buff *skb, gfp_t flags)
+{
+ u32 tx_cmd_a, tx_cmd_b;
+
+ skb_linearize(skb);
+
+ if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) {
+ struct sk_buff *skb2 =
+ skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags);
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+ if (!skb)
+ return NULL;
+ }
+
+ tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE;
+
+ if (skb_is_gso(skb)) {
+ u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN);
+ tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS;
+
+ tx_cmd_a |= TX_CMD_A_LSO;
+ } else {
+ tx_cmd_b = 0;
+ }
+
+ skb_push(skb, 4);
+ cpu_to_le32s(&tx_cmd_b);
+ memcpy(skb->data, &tx_cmd_b, 4);
+
+ skb_push(skb, 4);
+ cpu_to_le32s(&tx_cmd_a);
+ memcpy(skb->data, &tx_cmd_a, 4);
+
+ return skb;
+}
+
+static const struct driver_info smsc75xx_info = {
+ .description = "smsc75xx USB 2.0 Gigabit Ethernet",
+ .bind = smsc75xx_bind,
+ .unbind = smsc75xx_unbind,
+ .link_reset = smsc75xx_link_reset,
+ .reset = smsc75xx_reset,
+ .rx_fixup = smsc75xx_rx_fixup,
+ .tx_fixup = smsc75xx_tx_fixup,
+ .status = smsc75xx_status,
+ .flags = FLAG_ETHER | FLAG_SEND_ZLP,
+};
+
+static const struct usb_device_id products[] = {
+ {
+ /* SMSC7500 USB Gigabit Ethernet Device */
+ USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500),
+ .driver_info = (unsigned long) &smsc75xx_info,
+ },
+ {
+ /* SMSC7500 USB Gigabit Ethernet Device */
+ USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505),
+ .driver_info = (unsigned long) &smsc75xx_info,
+ },
+ { }, /* END */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver smsc75xx_driver = {
+ .name = SMSC_CHIPNAME,
+ .id_table = products,
+ .probe = usbnet_probe,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+ .disconnect = usbnet_disconnect,
+};
+
+static int __init smsc75xx_init(void)
+{
+ return usb_register(&smsc75xx_driver);
+}
+module_init(smsc75xx_init);
+
+static void __exit smsc75xx_exit(void)
+{
+ usb_deregister(&smsc75xx_driver);
+}
+module_exit(smsc75xx_exit);
+
+MODULE_AUTHOR("Nancy Lin");
+MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
+MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/smsc75xx.h b/drivers/net/usb/smsc75xx.h
new file mode 100644
index 00000000000..16e98c77834
--- /dev/null
+++ b/drivers/net/usb/smsc75xx.h
@@ -0,0 +1,421 @@
+ /***************************************************************************
+ *
+ * Copyright (C) 2007-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *****************************************************************************/
+
+#ifndef _SMSC75XX_H
+#define _SMSC75XX_H
+
+/* Tx command words */
+#define TX_CMD_A_LSO (0x08000000)
+#define TX_CMD_A_IPE (0x04000000)
+#define TX_CMD_A_TPE (0x02000000)
+#define TX_CMD_A_IVTG (0x01000000)
+#define TX_CMD_A_RVTG (0x00800000)
+#define TX_CMD_A_FCS (0x00400000)
+#define TX_CMD_A_LEN (0x000FFFFF)
+
+#define TX_CMD_B_MSS (0x3FFF0000)
+#define TX_CMD_B_MSS_SHIFT (16)
+#define TX_MSS_MIN ((u16)8)
+#define TX_CMD_B_VTAG (0x0000FFFF)
+
+/* Rx command words */
+#define RX_CMD_A_ICE (0x80000000)
+#define RX_CMD_A_TCE (0x40000000)
+#define RX_CMD_A_IPV (0x20000000)
+#define RX_CMD_A_PID (0x18000000)
+#define RX_CMD_A_PID_NIP (0x00000000)
+#define RX_CMD_A_PID_TCP (0x08000000)
+#define RX_CMD_A_PID_UDP (0x10000000)
+#define RX_CMD_A_PID_PP (0x18000000)
+#define RX_CMD_A_PFF (0x04000000)
+#define RX_CMD_A_BAM (0x02000000)
+#define RX_CMD_A_MAM (0x01000000)
+#define RX_CMD_A_FVTG (0x00800000)
+#define RX_CMD_A_RED (0x00400000)
+#define RX_CMD_A_RWT (0x00200000)
+#define RX_CMD_A_RUNT (0x00100000)
+#define RX_CMD_A_LONG (0x00080000)
+#define RX_CMD_A_RXE (0x00040000)
+#define RX_CMD_A_DRB (0x00020000)
+#define RX_CMD_A_FCS (0x00010000)
+#define RX_CMD_A_UAM (0x00008000)
+#define RX_CMD_A_LCSM (0x00004000)
+#define RX_CMD_A_LEN (0x00003FFF)
+
+#define RX_CMD_B_CSUM (0xFFFF0000)
+#define RX_CMD_B_CSUM_SHIFT (16)
+#define RX_CMD_B_VTAG (0x0000FFFF)
+
+/* SCSRs */
+#define ID_REV (0x0000)
+
+#define FPGA_REV (0x0004)
+
+#define BOND_CTL (0x0008)
+
+#define INT_STS (0x000C)
+#define INT_STS_RDFO_INT (0x00400000)
+#define INT_STS_TXE_INT (0x00200000)
+#define INT_STS_MACRTO_INT (0x00100000)
+#define INT_STS_TX_DIS_INT (0x00080000)
+#define INT_STS_RX_DIS_INT (0x00040000)
+#define INT_STS_PHY_INT_ (0x00020000)
+#define INT_STS_MAC_ERR_INT (0x00008000)
+#define INT_STS_TDFU (0x00004000)
+#define INT_STS_TDFO (0x00002000)
+#define INT_STS_GPIOS (0x00000FFF)
+#define INT_STS_CLEAR_ALL (0xFFFFFFFF)
+
+#define HW_CFG (0x0010)
+#define HW_CFG_SMDET_STS (0x00008000)
+#define HW_CFG_SMDET_EN (0x00004000)
+#define HW_CFG_EEM (0x00002000)
+#define HW_CFG_RST_PROTECT (0x00001000)
+#define HW_CFG_PORT_SWAP (0x00000800)
+#define HW_CFG_PHY_BOOST (0x00000600)
+#define HW_CFG_PHY_BOOST_NORMAL (0x00000000)
+#define HW_CFG_PHY_BOOST_4 (0x00002000)
+#define HW_CFG_PHY_BOOST_8 (0x00004000)
+#define HW_CFG_PHY_BOOST_12 (0x00006000)
+#define HW_CFG_LEDB (0x00000100)
+#define HW_CFG_BIR (0x00000080)
+#define HW_CFG_SBP (0x00000040)
+#define HW_CFG_IME (0x00000020)
+#define HW_CFG_MEF (0x00000010)
+#define HW_CFG_ETC (0x00000008)
+#define HW_CFG_BCE (0x00000004)
+#define HW_CFG_LRST (0x00000002)
+#define HW_CFG_SRST (0x00000001)
+
+#define PMT_CTL (0x0014)
+#define PMT_CTL_PHY_PWRUP (0x00000400)
+#define PMT_CTL_RES_CLR_WKP_EN (0x00000100)
+#define PMT_CTL_DEV_RDY (0x00000080)
+#define PMT_CTL_SUS_MODE (0x00000060)
+#define PMT_CTL_SUS_MODE_0 (0x00000000)
+#define PMT_CTL_SUS_MODE_1 (0x00000020)
+#define PMT_CTL_SUS_MODE_2 (0x00000040)
+#define PMT_CTL_SUS_MODE_3 (0x00000060)
+#define PMT_CTL_PHY_RST (0x00000010)
+#define PMT_CTL_WOL_EN (0x00000008)
+#define PMT_CTL_ED_EN (0x00000004)
+#define PMT_CTL_WUPS (0x00000003)
+#define PMT_CTL_WUPS_NO (0x00000000)
+#define PMT_CTL_WUPS_ED (0x00000001)
+#define PMT_CTL_WUPS_WOL (0x00000002)
+#define PMT_CTL_WUPS_MULTI (0x00000003)
+
+#define LED_GPIO_CFG (0x0018)
+#define LED_GPIO_CFG_LED2_FUN_SEL (0x80000000)
+#define LED_GPIO_CFG_LED10_FUN_SEL (0x40000000)
+#define LED_GPIO_CFG_LEDGPIO_EN (0x0000F000)
+#define LED_GPIO_CFG_LEDGPIO_EN_0 (0x00001000)
+#define LED_GPIO_CFG_LEDGPIO_EN_1 (0x00002000)
+#define LED_GPIO_CFG_LEDGPIO_EN_2 (0x00004000)
+#define LED_GPIO_CFG_LEDGPIO_EN_3 (0x00008000)
+#define LED_GPIO_CFG_GPBUF (0x00000F00)
+#define LED_GPIO_CFG_GPBUF_0 (0x00000100)
+#define LED_GPIO_CFG_GPBUF_1 (0x00000200)
+#define LED_GPIO_CFG_GPBUF_2 (0x00000400)
+#define LED_GPIO_CFG_GPBUF_3 (0x00000800)
+#define LED_GPIO_CFG_GPDIR (0x000000F0)
+#define LED_GPIO_CFG_GPDIR_0 (0x00000010)
+#define LED_GPIO_CFG_GPDIR_1 (0x00000020)
+#define LED_GPIO_CFG_GPDIR_2 (0x00000040)
+#define LED_GPIO_CFG_GPDIR_3 (0x00000080)
+#define LED_GPIO_CFG_GPDATA (0x0000000F)
+#define LED_GPIO_CFG_GPDATA_0 (0x00000001)
+#define LED_GPIO_CFG_GPDATA_1 (0x00000002)
+#define LED_GPIO_CFG_GPDATA_2 (0x00000004)
+#define LED_GPIO_CFG_GPDATA_3 (0x00000008)
+
+#define GPIO_CFG (0x001C)
+#define GPIO_CFG_SHIFT (24)
+#define GPIO_CFG_GPEN (0xFF000000)
+#define GPIO_CFG_GPBUF (0x00FF0000)
+#define GPIO_CFG_GPDIR (0x0000FF00)
+#define GPIO_CFG_GPDATA (0x000000FF)
+
+#define GPIO_WAKE (0x0020)
+#define GPIO_WAKE_PHY_LINKUP_EN (0x80000000)
+#define GPIO_WAKE_POL (0x0FFF0000)
+#define GPIO_WAKE_POL_SHIFT (16)
+#define GPIO_WAKE_WK (0x00000FFF)
+
+#define DP_SEL (0x0024)
+#define DP_SEL_DPRDY (0x80000000)
+#define DP_SEL_RSEL (0x0000000F)
+#define DP_SEL_URX (0x00000000)
+#define DP_SEL_VHF (0x00000001)
+#define DP_SEL_VHF_HASH_LEN (16)
+#define DP_SEL_VHF_VLAN_LEN (128)
+#define DP_SEL_LSO_HEAD (0x00000002)
+#define DP_SEL_FCT_RX (0x00000003)
+#define DP_SEL_FCT_TX (0x00000004)
+#define DP_SEL_DESCRIPTOR (0x00000005)
+#define DP_SEL_WOL (0x00000006)
+
+#define DP_CMD (0x0028)
+#define DP_CMD_WRITE (0x01)
+#define DP_CMD_READ (0x00)
+
+#define DP_ADDR (0x002C)
+
+#define DP_DATA (0x0030)
+
+#define BURST_CAP (0x0034)
+#define BURST_CAP_MASK (0x0000000F)
+
+#define INT_EP_CTL (0x0038)
+#define INT_EP_CTL_INTEP_ON (0x80000000)
+#define INT_EP_CTL_RDFO_EN (0x00400000)
+#define INT_EP_CTL_TXE_EN (0x00200000)
+#define INT_EP_CTL_MACROTO_EN (0x00100000)
+#define INT_EP_CTL_TX_DIS_EN (0x00080000)
+#define INT_EP_CTL_RX_DIS_EN (0x00040000)
+#define INT_EP_CTL_PHY_EN_ (0x00020000)
+#define INT_EP_CTL_MAC_ERR_EN (0x00008000)
+#define INT_EP_CTL_TDFU_EN (0x00004000)
+#define INT_EP_CTL_TDFO_EN (0x00002000)
+#define INT_EP_CTL_RX_FIFO_EN (0x00001000)
+#define INT_EP_CTL_GPIOX_EN (0x00000FFF)
+
+#define BULK_IN_DLY (0x003C)
+#define BULK_IN_DLY_MASK (0xFFFF)
+
+#define E2P_CMD (0x0040)
+#define E2P_CMD_BUSY (0x80000000)
+#define E2P_CMD_MASK (0x70000000)
+#define E2P_CMD_READ (0x00000000)
+#define E2P_CMD_EWDS (0x10000000)
+#define E2P_CMD_EWEN (0x20000000)
+#define E2P_CMD_WRITE (0x30000000)
+#define E2P_CMD_WRAL (0x40000000)
+#define E2P_CMD_ERASE (0x50000000)
+#define E2P_CMD_ERAL (0x60000000)
+#define E2P_CMD_RELOAD (0x70000000)
+#define E2P_CMD_TIMEOUT (0x00000400)
+#define E2P_CMD_LOADED (0x00000200)
+#define E2P_CMD_ADDR (0x000001FF)
+
+#define MAX_EEPROM_SIZE (512)
+
+#define E2P_DATA (0x0044)
+#define E2P_DATA_MASK_ (0x000000FF)
+
+#define RFE_CTL (0x0060)
+#define RFE_CTL_TCPUDP_CKM (0x00001000)
+#define RFE_CTL_IP_CKM (0x00000800)
+#define RFE_CTL_AB (0x00000400)
+#define RFE_CTL_AM (0x00000200)
+#define RFE_CTL_AU (0x00000100)
+#define RFE_CTL_VS (0x00000080)
+#define RFE_CTL_UF (0x00000040)
+#define RFE_CTL_VF (0x00000020)
+#define RFE_CTL_SPF (0x00000010)
+#define RFE_CTL_MHF (0x00000008)
+#define RFE_CTL_DHF (0x00000004)
+#define RFE_CTL_DPF (0x00000002)
+#define RFE_CTL_RST_RF (0x00000001)
+
+#define VLAN_TYPE (0x0064)
+#define VLAN_TYPE_MASK (0x0000FFFF)
+
+#define FCT_RX_CTL (0x0090)
+#define FCT_RX_CTL_EN (0x80000000)
+#define FCT_RX_CTL_RST (0x40000000)
+#define FCT_RX_CTL_SBF (0x02000000)
+#define FCT_RX_CTL_OVERFLOW (0x01000000)
+#define FCT_RX_CTL_FRM_DROP (0x00800000)
+#define FCT_RX_CTL_RX_NOT_EMPTY (0x00400000)
+#define FCT_RX_CTL_RX_EMPTY (0x00200000)
+#define FCT_RX_CTL_RX_DISABLED (0x00100000)
+#define FCT_RX_CTL_RXUSED (0x0000FFFF)
+
+#define FCT_TX_CTL (0x0094)
+#define FCT_TX_CTL_EN (0x80000000)
+#define FCT_TX_CTL_RST (0x40000000)
+#define FCT_TX_CTL_TX_NOT_EMPTY (0x00400000)
+#define FCT_TX_CTL_TX_EMPTY (0x00200000)
+#define FCT_TX_CTL_TX_DISABLED (0x00100000)
+#define FCT_TX_CTL_TXUSED (0x0000FFFF)
+
+#define FCT_RX_FIFO_END (0x0098)
+#define FCT_RX_FIFO_END_MASK (0x0000007F)
+
+#define FCT_TX_FIFO_END (0x009C)
+#define FCT_TX_FIFO_END_MASK (0x0000003F)
+
+#define FCT_FLOW (0x00A0)
+#define FCT_FLOW_THRESHOLD_OFF (0x00007F00)
+#define FCT_FLOW_THRESHOLD_OFF_SHIFT (8)
+#define FCT_FLOW_THRESHOLD_ON (0x0000007F)
+
+/* MAC CSRs */
+#define MAC_CR (0x100)
+#define MAC_CR_ADP (0x00002000)
+#define MAC_CR_ADD (0x00001000)
+#define MAC_CR_ASD (0x00000800)
+#define MAC_CR_INT_LOOP (0x00000400)
+#define MAC_CR_BOLMT (0x000000C0)
+#define MAC_CR_FDPX (0x00000008)
+#define MAC_CR_CFG (0x00000006)
+#define MAC_CR_CFG_10 (0x00000000)
+#define MAC_CR_CFG_100 (0x00000002)
+#define MAC_CR_CFG_1000 (0x00000004)
+#define MAC_CR_RST (0x00000001)
+
+#define MAC_RX (0x104)
+#define MAC_RX_MAX_SIZE (0x3FFF0000)
+#define MAC_RX_MAX_SIZE_SHIFT (16)
+#define MAC_RX_FCS_STRIP (0x00000010)
+#define MAC_RX_FSE (0x00000004)
+#define MAC_RX_RXD (0x00000002)
+#define MAC_RX_RXEN (0x00000001)
+
+#define MAC_TX (0x108)
+#define MAC_TX_BFCS (0x00000004)
+#define MAC_TX_TXD (0x00000002)
+#define MAC_TX_TXEN (0x00000001)
+
+#define FLOW (0x10C)
+#define FLOW_FORCE_FC (0x80000000)
+#define FLOW_TX_FCEN (0x40000000)
+#define FLOW_RX_FCEN (0x20000000)
+#define FLOW_FPF (0x10000000)
+#define FLOW_PAUSE_TIME (0x0000FFFF)
+
+#define RAND_SEED (0x110)
+#define RAND_SEED_MASK (0x0000FFFF)
+
+#define ERR_STS (0x114)
+#define ERR_STS_FCS_ERR (0x00000100)
+#define ERR_STS_LFRM_ERR (0x00000080)
+#define ERR_STS_RUNT_ERR (0x00000040)
+#define ERR_STS_COLLISION_ERR (0x00000010)
+#define ERR_STS_ALIGN_ERR (0x00000008)
+#define ERR_STS_URUN_ERR (0x00000004)
+
+#define RX_ADDRH (0x118)
+#define RX_ADDRH_MASK (0x0000FFFF)
+
+#define RX_ADDRL (0x11C)
+
+#define MII_ACCESS (0x120)
+#define MII_ACCESS_PHY_ADDR (0x0000F800)
+#define MII_ACCESS_PHY_ADDR_SHIFT (11)
+#define MII_ACCESS_REG_ADDR (0x000007C0)
+#define MII_ACCESS_REG_ADDR_SHIFT (6)
+#define MII_ACCESS_READ (0x00000000)
+#define MII_ACCESS_WRITE (0x00000002)
+#define MII_ACCESS_BUSY (0x00000001)
+
+#define MII_DATA (0x124)
+#define MII_DATA_MASK (0x0000FFFF)
+
+#define WUCSR (0x140)
+#define WUCSR_PFDA_FR (0x00000080)
+#define WUCSR_WUFR (0x00000040)
+#define WUCSR_MPR (0x00000020)
+#define WUCSR_BCAST_FR (0x00000010)
+#define WUCSR_PFDA_EN (0x00000008)
+#define WUCSR_WUEN (0x00000004)
+#define WUCSR_MPEN (0x00000002)
+#define WUCSR_BCST_EN (0x00000001)
+
+#define WUF_CFGX (0x144)
+#define WUF_CFGX_EN (0x80000000)
+#define WUF_CFGX_ATYPE (0x03000000)
+#define WUF_CFGX_ATYPE_UNICAST (0x00000000)
+#define WUF_CFGX_ATYPE_MULTICAST (0x02000000)
+#define WUF_CFGX_ATYPE_ALL (0x03000000)
+#define WUF_CFGX_PATTERN_OFFSET (0x007F0000)
+#define WUF_CFGX_PATTERN_OFFSET_SHIFT (16)
+#define WUF_CFGX_CRC16 (0x0000FFFF)
+#define WUF_NUM (8)
+
+#define WUF_MASKX (0x170)
+#define WUF_MASKX_AVALID (0x80000000)
+#define WUF_MASKX_ATYPE (0x40000000)
+
+#define ADDR_FILTX (0x300)
+#define ADDR_FILTX_FB_VALID (0x80000000)
+#define ADDR_FILTX_FB_TYPE (0x40000000)
+#define ADDR_FILTX_FB_ADDRHI (0x0000FFFF)
+#define ADDR_FILTX_SB_ADDRLO (0xFFFFFFFF)
+
+#define WUCSR2 (0x500)
+#define WUCSR2_NS_RCD (0x00000040)
+#define WUCSR2_ARP_RCD (0x00000020)
+#define WUCSR2_TCPSYN_RCD (0x00000010)
+#define WUCSR2_NS_OFFLOAD (0x00000004)
+#define WUCSR2_ARP_OFFLOAD (0x00000002)
+#define WUCSR2_TCPSYN_OFFLOAD (0x00000001)
+
+#define WOL_FIFO_STS (0x504)
+
+#define IPV6_ADDRX (0x510)
+
+#define IPV4_ADDRX (0x590)
+
+
+/* Vendor-specific PHY Definitions */
+
+/* Mode Control/Status Register */
+#define PHY_MODE_CTRL_STS (17)
+#define MODE_CTRL_STS_EDPWRDOWN ((u16)0x2000)
+#define MODE_CTRL_STS_ENERGYON ((u16)0x0002)
+
+#define PHY_INT_SRC (29)
+#define PHY_INT_SRC_ENERGY_ON ((u16)0x0080)
+#define PHY_INT_SRC_ANEG_COMP ((u16)0x0040)
+#define PHY_INT_SRC_REMOTE_FAULT ((u16)0x0020)
+#define PHY_INT_SRC_LINK_DOWN ((u16)0x0010)
+
+#define PHY_INT_MASK (30)
+#define PHY_INT_MASK_ENERGY_ON ((u16)0x0080)
+#define PHY_INT_MASK_ANEG_COMP ((u16)0x0040)
+#define PHY_INT_MASK_REMOTE_FAULT ((u16)0x0020)
+#define PHY_INT_MASK_LINK_DOWN ((u16)0x0010)
+#define PHY_INT_MASK_DEFAULT (PHY_INT_MASK_ANEG_COMP | \
+ PHY_INT_MASK_LINK_DOWN)
+
+#define PHY_SPECIAL (31)
+#define PHY_SPECIAL_SPD ((u16)0x001C)
+#define PHY_SPECIAL_SPD_10HALF ((u16)0x0004)
+#define PHY_SPECIAL_SPD_10FULL ((u16)0x0014)
+#define PHY_SPECIAL_SPD_100HALF ((u16)0x0008)
+#define PHY_SPECIAL_SPD_100FULL ((u16)0x0018)
+
+/* USB Vendor Requests */
+#define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0
+#define USB_VENDOR_REQUEST_READ_REGISTER 0xA1
+#define USB_VENDOR_REQUEST_GET_STATS 0xA2
+
+/* Interrupt Endpoint status word bitfields */
+#define INT_ENP_RDFO_INT ((u32)BIT(22))
+#define INT_ENP_TXE_INT ((u32)BIT(21))
+#define INT_ENP_TX_DIS_INT ((u32)BIT(19))
+#define INT_ENP_RX_DIS_INT ((u32)BIT(18))
+#define INT_ENP_PHY_INT ((u32)BIT(17))
+#define INT_ENP_MAC_ERR_INT ((u32)BIT(15))
+#define INT_ENP_RX_FIFO_DATA_INT ((u32)BIT(12))
+
+#endif /* _SMSC75XX_H */
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index df9179a1c93..3135af63d37 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -28,6 +28,7 @@
#include <linux/usb.h>
#include <linux/crc32.h>
#include <linux/usb/usbnet.h>
+#include <linux/slab.h>
#include "smsc95xx.h"
#define SMSC_CHIPNAME "smsc95xx"
@@ -709,6 +710,8 @@ static void smsc95xx_start_rx_path(struct usbnet *dev)
static int smsc95xx_phy_initialize(struct usbnet *dev)
{
+ int bmcr, timeout = 0;
+
/* Initialize MII structure */
dev->mii.dev = dev->net;
dev->mii.mdio_read = smsc95xx_mdio_read;
@@ -717,7 +720,20 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
dev->mii.reg_num_mask = 0x1f;
dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID;
+ /* reset phy and wait for reset to complete */
smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+ do {
+ msleep(10);
+ bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
+ timeout++;
+ } while ((bmcr & MII_BMCR) && (timeout < 100));
+
+ if (timeout >= 100) {
+ netdev_warn(dev->net, "timeout on PHY Reset");
+ return -EIO;
+ }
+
smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
ADVERTISE_PAUSE_ASYM);
@@ -1174,9 +1190,21 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
}
if (csum) {
- u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
- skb_push(skb, 4);
- memcpy(skb->data, &csum_preamble, 4);
+ if (skb->len <= 45) {
+ /* workaround - hardware tx checksum does not work
+ * properly with extremely small packets */
+ long csstart = skb->csum_start - skb_headroom(skb);
+ __wsum calc = csum_partial(skb->data + csstart,
+ skb->len - csstart, 0);
+ *((__sum16 *)(skb->data + csstart
+ + skb->csum_offset)) = csum_fold(calc);
+
+ csum = false;
+ } else {
+ u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
+ skb_push(skb, 4);
+ memcpy(skb->data, &csum_preamble, 4);
+ }
}
skb_push(skb, 4);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 17b6a62d206..7177abc78dc 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -43,6 +43,7 @@
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/usb/usbnet.h>
+#include <linux/slab.h>
#define DRIVER_VERSION "22-Aug-2005"
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index b583d4968ad..f9f0730b53d 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -9,6 +9,7 @@
*/
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 50f881aa393..388751aa66e 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -89,7 +89,6 @@ static const int multicast_filter_limit = 32;
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 3a486f3bad3..bc278d4ee89 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -812,7 +812,7 @@ static void set_mii_flow_control(struct velocity_info *vptr)
case FLOW_CNTL_TX_RX:
MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
- MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+ MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
break;
case FLOW_CNTL_DISABLE:
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 25dc77ccbf5..b0577dd1a42 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -25,6 +25,7 @@
#include <linux/virtio_net.h>
#include <linux/scatterlist.h>
#include <linux/if_vlan.h>
+#include <linux/slab.h>
static int napi_weight = 128;
module_param(napi_weight, int, 0444);
@@ -326,6 +327,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
struct scatterlist sg[2];
int err;
+ sg_init_table(sg, 2);
skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
if (unlikely(!skb))
return -ENOMEM;
@@ -351,6 +353,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
char *p;
int i, err, offset;
+ sg_init_table(sg, MAX_SKB_FRAGS + 2);
/* page in sg[MAX_SKB_FRAGS + 1] is list tail */
for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
first = get_a_page(vi, gfp);
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
index 32a75fa935e..a21a25d218b 100644
--- a/drivers/net/vxge/vxge-config.c
+++ b/drivers/net/vxge/vxge-config.c
@@ -15,6 +15,7 @@
#include <linux/etherdevice.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
+#include <linux/slab.h>
#include "vxge-traffic.h"
#include "vxge-config.h"
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
index e7877df092f..13f5416307f 100644
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -14,6 +14,7 @@
#ifndef VXGE_CONFIG_H
#define VXGE_CONFIG_H
#include <linux/list.h>
+#include <linux/slab.h>
#ifndef VXGE_CACHE_LINE_SIZE
#define VXGE_CACHE_LINE_SIZE 128
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index c6736b97263..aaf374cfd32 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -12,6 +12,7 @@
* Copyright(c) 2002-2009 Neterion Inc.
******************************************************************************/
#include<linux/ethtool.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 46a7c9e689e..ba6d0da78c3 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -43,6 +43,7 @@
#include <linux/if_vlan.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/tcp.h>
#include <net/ip.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index b36bf96eb50..f0bd70fb650 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -811,7 +811,7 @@ static ssize_t cosa_read(struct file *file,
cosa_enable_rx(chan);
spin_lock_irqsave(&cosa->lock, flags);
add_wait_queue(&chan->rxwaitq, &wait);
- while(!chan->rx_status) {
+ while (!chan->rx_status) {
current->state = TASK_INTERRUPTIBLE;
spin_unlock_irqrestore(&cosa->lock, flags);
schedule();
@@ -896,7 +896,7 @@ static ssize_t cosa_write(struct file *file,
spin_lock_irqsave(&cosa->lock, flags);
add_wait_queue(&chan->txwaitq, &wait);
- while(!chan->tx_status) {
+ while (!chan->tx_status) {
current->state = TASK_INTERRUPTIBLE;
spin_unlock_irqrestore(&cosa->lock, flags);
schedule();
@@ -1153,7 +1153,7 @@ static int cosa_ioctl_common(struct cosa_data *cosa,
struct channel_data *channel, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
- switch(cmd) {
+ switch (cmd) {
case COSAIORSET: /* Reset the device */
if (!capable(CAP_NET_ADMIN))
return -EACCES;
@@ -1704,7 +1704,7 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status)
spin_unlock_irqrestore(&cosa->lock, flags);
return;
}
- while(1) {
+ while (1) {
cosa->txchan++;
i++;
if (cosa->txchan >= cosa->nchannels)
@@ -2010,7 +2010,7 @@ again:
static void debug_status_in(struct cosa_data *cosa, int status)
{
char *s;
- switch(status & SR_CMD_FROM_SRP_MASK) {
+ switch (status & SR_CMD_FROM_SRP_MASK) {
case SR_UP_REQUEST:
s = "RX_REQ";
break;
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index f88c07c1319..a4859f7a7cc 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -89,6 +89,7 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/cache.h>
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 40d724a8e02..e087b9a6daa 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -20,6 +20,7 @@
#include <linux/version.h>
#include <linux/pci.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/if.h>
diff --git a/drivers/net/wan/hd64570.c b/drivers/net/wan/hd64570.c
index 80114c93bae..4dde2ea4a18 100644
--- a/drivers/net/wan/hd64570.c
+++ b/drivers/net/wan/hd64570.c
@@ -37,7 +37,6 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>
#include <asm/io.h>
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c
index 84f01373e11..aad9ed45c25 100644
--- a/drivers/net/wan/hd64572.c
+++ b/drivers/net/wan/hd64572.c
@@ -37,7 +37,6 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>
#include <asm/io.h>
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index f1bff98acd1..ee7083fbea5 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -20,7 +20,6 @@
#include <linux/poll.h>
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#undef DEBUG_HARD_HEADER
@@ -141,7 +140,7 @@ static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
data->address != CISCO_UNICAST)
return cpu_to_be16(ETH_P_HDLC);
- switch(data->protocol) {
+ switch (data->protocol) {
case cpu_to_be16(ETH_P_IP):
case cpu_to_be16(ETH_P_IPX):
case cpu_to_be16(ETH_P_IPV6):
@@ -190,7 +189,7 @@ static int cisco_rx(struct sk_buff *skb)
cisco_data = (struct cisco_packet*)(skb->data + sizeof
(struct hdlc_header));
- switch(ntohl (cisco_data->type)) {
+ switch (ntohl (cisco_data->type)) {
case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
in_dev = dev->ip_ptr;
addr = 0;
@@ -245,8 +244,8 @@ static int cisco_rx(struct sk_buff *skb)
dev_kfree_skb_any(skb);
return NET_RX_SUCCESS;
- } /* switch(keepalive type) */
- } /* switch(protocol) */
+ } /* switch (keepalive type) */
+ } /* switch (protocol) */
printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name,
ntohs(data->protocol));
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index b9b9d6b01c0..941f053e650 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -628,9 +628,15 @@ static void ppp_stop(struct net_device *dev)
ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL);
}
+static void ppp_close(struct net_device *dev)
+{
+ ppp_tx_flush();
+}
+
static struct hdlc_proto proto = {
.start = ppp_start,
.stop = ppp_stop,
+ .close = ppp_close,
.type_trans = ppp_type_trans,
.ioctl = ppp_ioctl,
.netif_rx = ppp_rx,
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index 19f51fdd552..5dc153e8a29 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -20,7 +20,6 @@
#include <linux/poll.h>
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index 1b30fcc2414..05c9b0b9623 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/etherdevice.h>
+#include <linux/gfp.h>
#include <linux/hdlc.h>
#include <linux/if_arp.h>
#include <linux/inetdevice.h>
@@ -21,7 +22,6 @@
#include <linux/poll.h>
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index aa9248f8eb1..c7adbb79f7c 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -10,6 +10,7 @@
*/
#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/hdlc.h>
#include <linux/if_arp.h>
#include <linux/inetdevice.h>
@@ -21,7 +22,6 @@
#include <linux/poll.h>
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <net/x25device.h>
static int x25_ioctl(struct net_device *dev, struct ifreq *ifr);
@@ -202,10 +202,10 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
return 0; /* return protocol only, no settable parameters */
case IF_PROTO_X25:
- if(!capable(CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if(dev->flags & IFF_UP)
+ if (dev->flags & IFF_UP)
return -EBUSY;
result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index 74164d29524..48edc5f4dac 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -30,6 +30,7 @@
#include <linux/delay.h>
#include <linux/hdlc.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <asm/irq.h>
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index c705046d861..0c2cdde686a 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <mach/npe.h>
#include <mach/qmgr.h>
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index d1e3c673e9b..98e2f99903d 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -24,6 +24,7 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/net.h>
diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c
index f327674fc93..5920c996fcd 100644
--- a/drivers/net/wan/lmc/lmc_media.c
+++ b/drivers/net/wan/lmc/lmc_media.c
@@ -6,7 +6,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/if_arp.h>
diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
index 044a48175c4..f600075e84a 100644
--- a/drivers/net/wan/lmc/lmc_proto.c
+++ b/drivers/net/wan/lmc/lmc_proto.c
@@ -25,7 +25,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/if_arp.h>
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index f4f1c00d0d2..3f744c64309 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -228,6 +228,7 @@ static char rcsid[] =
#include <linux/etherdevice.h>
#include <linux/spinlock.h>
#include <linux/if.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <asm/io.h>
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 25477b5cde4..cff13a9597c 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -43,7 +43,6 @@
#include <linux/fcntl.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 61249f489e3..e91457d6023 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -23,6 +23,7 @@
#include <linux/hdlc.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <asm/irq.h>
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index b9f520b7db6..80d5c5834a0 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/compat.h>
+#include <linux/slab.h>
#include "x25_asy.h"
#include <net/x25device.h>
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 0be7ec7299d..fbf5e843d48 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -47,6 +47,7 @@
#include <linux/hdlc.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <asm/dma.h>
#include <asm/io.h>
#define RT_LOCK
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index 94494554039..6180772dcc0 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -76,6 +76,7 @@
#include <stdarg.h>
#include "i2400m.h"
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/wimax/i2400m.h>
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 6cead321bc1..94dc83c3969 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -69,6 +69,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/suspend.h>
+#include <linux/slab.h>
#define D_SUBMODULE driver
#include "debug-levels.h"
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c
index e803a7dc650..3f283bff0ff 100644
--- a/drivers/net/wimax/i2400m/fw.c
+++ b/drivers/net/wimax/i2400m/fw.c
@@ -156,6 +156,7 @@
*/
#include <linux/firmware.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "i2400m.h"
@@ -612,7 +613,7 @@ ssize_t i2400m_bm_cmd(struct i2400m *i2400m,
goto error_wait_for_ack;
}
rx_bytes = result;
- /* verify the ack and read more if neccessary [result is the
+ /* verify the ack and read more if necessary [result is the
* final amount of bytes we get in the ack] */
result = __i2400m_bm_ack_verify(i2400m, opcode, ack, ack_size, flags);
if (result < 0)
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 04df9bbe340..820b128705e 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -627,7 +627,7 @@ enum i2400m_bm_cmd_flags {
* @I2400M_BRI_NO_REBOOT: Do not reboot the device and proceed
* directly to wait for a reboot barker from the device.
* @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot
- * rom after reading the MAC adress. This is quite a dirty hack,
+ * rom after reading the MAC address. This is quite a dirty hack,
* if you ask me -- the device requires the bootrom to be
* intialized after reading the MAC address.
*/
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 599aa4eb9ba..b811c2f1f5e 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -73,6 +73,7 @@
* alloc_netdev.
*/
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include "i2400m.h"
diff --git a/drivers/net/wimax/i2400m/op-rfkill.c b/drivers/net/wimax/i2400m/op-rfkill.c
index 43927b5d7ad..035e4cf3e6e 100644
--- a/drivers/net/wimax/i2400m/op-rfkill.c
+++ b/drivers/net/wimax/i2400m/op-rfkill.c
@@ -34,6 +34,7 @@
*/
#include "i2400m.h"
#include <linux/wimax/i2400m.h>
+#include <linux/slab.h>
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index 7ddb173fd4a..fa2e11e5b4b 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -144,6 +144,7 @@
* i2400m_msg_size_check
* wimax_msg
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c
index 8adf6c9b6f8..d619da33f20 100644
--- a/drivers/net/wimax/i2400m/sdio-rx.c
+++ b/drivers/net/wimax/i2400m/sdio-rx.c
@@ -65,6 +65,7 @@
#include <linux/skbuff.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
#include "i2400m-sdio.h"
#define D_SUBMODULE rx
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 76a50ac02eb..7632f80954e 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -48,6 +48,7 @@
* __i2400ms_send_barker()
*/
+#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio.h>
@@ -304,7 +305,7 @@ error_kzalloc:
*
* The device will be fully reset internally, but won't be
* disconnected from the bus (so no reenumeration will
- * happen). Firmware upload will be neccessary.
+ * happen). Firmware upload will be necessary.
*
* The device will send a reboot barker that will trigger the driver
* to reinitialize the state via __i2400m_dev_reset_handle.
@@ -314,7 +315,7 @@ error_kzalloc:
*
* The device will be fully reset internally, disconnected from the
* bus an a reenumeration will happen. Firmware upload will be
- * neccessary. Thus, we don't do any locking or struct
+ * necessary. Thus, we don't do any locking or struct
* reinitialization, as we are going to be fully disconnected and
* reenumerated.
*
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index 54480e8947f..b0cb90624cf 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -244,6 +244,7 @@
* (FIFO empty).
*/
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include "i2400m.h"
diff --git a/drivers/net/wimax/i2400m/usb-fw.c b/drivers/net/wimax/i2400m/usb-fw.c
index ce6b9938fde..b58ec56b86f 100644
--- a/drivers/net/wimax/i2400m/usb-fw.c
+++ b/drivers/net/wimax/i2400m/usb-fw.c
@@ -73,6 +73,7 @@
* i2400m_notif_submit
*/
#include <linux/usb.h>
+#include <linux/gfp.h>
#include "i2400m-usb.h"
diff --git a/drivers/net/wimax/i2400m/usb-notif.c b/drivers/net/wimax/i2400m/usb-notif.c
index f88d1c6e35c..7b6a1d98bd7 100644
--- a/drivers/net/wimax/i2400m/usb-notif.c
+++ b/drivers/net/wimax/i2400m/usb-notif.c
@@ -56,6 +56,7 @@
* i2400mu_rx_kick()
*/
#include <linux/usb.h>
+#include <linux/slab.h>
#include "i2400m-usb.h"
diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c
index ba1b02362df..a26483a812a 100644
--- a/drivers/net/wimax/i2400m/usb-rx.c
+++ b/drivers/net/wimax/i2400m/usb-rx.c
@@ -83,6 +83,7 @@
* i2400mu_rx_release() called from i2400mu_bus_dev_stop()
*/
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "i2400m-usb.h"
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 98f4f8c5fb6..d8c4d6497fd 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -66,6 +66,7 @@
#include "i2400m-usb.h"
#include <linux/wimax/i2400m.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#define D_SUBMODULE usb
@@ -246,7 +247,7 @@ error_kzalloc:
*
* The device will be fully reset internally, but won't be
* disconnected from the USB bus (so no reenumeration will
- * happen). Firmware upload will be neccessary.
+ * happen). Firmware upload will be necessary.
*
* The device will send a reboot barker in the notification endpoint
* that will trigger the driver to reinitialize the state
@@ -257,7 +258,7 @@ error_kzalloc:
*
* The device will be fully reset internally, disconnected from the
* USB bus an a reenumeration will happen. Firmware upload will be
- * neccessary. Thus, we don't do any locking or struct
+ * necessary. Thus, we don't do any locking or struct
* reinitialization, as we are going to be fully disconnected and
* reenumerated.
*
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 547912e6843..ab61d2b558d 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/if.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/etherdevice.h>
#include <linux/pci.h>
#include <linux/delay.h>
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 698d5672a07..dc5018a6d9e 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5255,7 +5255,8 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
WepKeyRid wkr;
int rc;
- WARN_ON(keylen == 0);
+ if (WARN_ON(keylen == 0))
+ return -1;
memset(&wkr, 0, sizeof(wkr));
wkr.len = cpu_to_le16(sizeof(wkr));
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index 8c8ce67971e..dc662b76a1c 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -166,6 +166,7 @@ struct ar9170 {
struct ath_common common;
struct mutex mutex;
enum ar9170_device_state state;
+ bool registered;
unsigned long bad_hw_nagger;
int (*open)(struct ar9170 *);
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 8a964f13036..c5369298099 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -38,6 +38,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/etherdevice.h>
#include <net/mac80211.h>
@@ -394,7 +395,7 @@ static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar)
ieee80211_tx_status_irqsafe(ar->hw, skb);
}
- for_each_bit(i, &queue_bitmap, BITS_PER_BYTE) {
+ for_each_set_bit(i, &queue_bitmap, BITS_PER_BYTE) {
#ifdef AR9170_QUEUE_STOP_DEBUG
printk(KERN_DEBUG "%s: wake queue %d\n",
wiphy_name(ar->hw->wiphy), i);
@@ -2512,7 +2513,7 @@ void *ar9170_alloc(size_t priv_size)
/*
* this buffer is used for rx stream reconstruction.
* Under heavy load this device (or the transport layer?)
- * tends to split the streams into seperate rx descriptors.
+ * tends to split the streams into separate rx descriptors.
*/
skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
@@ -2701,7 +2702,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
wiphy_name(ar->hw->wiphy));
- return err;
+ ar->registered = true;
+ return 0;
err_unreg:
ieee80211_unregister_hw(ar->hw);
@@ -2712,11 +2714,14 @@ err_out:
void ar9170_unregister(struct ar9170 *ar)
{
+ if (ar->registered) {
#ifdef CONFIG_AR9170_LEDS
- ar9170_unregister_leds(ar);
+ ar9170_unregister_leds(ar);
#endif /* CONFIG_AR9170_LEDS */
- kfree_skb(ar->rx_failover);
ieee80211_unregister_hw(ar->hw);
+ }
+
+ kfree_skb(ar->rx_failover);
mutex_destroy(&ar->mutex);
}
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index 0f361186b78..99a6da464bd 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -38,6 +38,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
@@ -94,6 +95,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x04bb, 0x093f) },
/* AVM FRITZ!WLAN USB Stick N */
{ USB_DEVICE(0x057C, 0x8401) },
+ /* NEC WL300NU-G */
+ { USB_DEVICE(0x0409, 0x0249) },
/* AVM FRITZ!WLAN USB Stick N 2.4 */
{ USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
@@ -416,7 +419,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
spin_unlock_irqrestore(&aru->common.cmdlock, flags);
usb_fill_int_urb(urb, aru->udev,
- usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
+ usb_sndintpipe(aru->udev, AR9170_EP_CMD),
aru->common.cmdbuf, plen + 4,
ar9170_usb_tx_urb_complete, NULL, 1);
@@ -582,43 +585,6 @@ static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
return 0;
}
-static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
-{
- int err = 0;
-
- err = request_firmware(&aru->firmware, "ar9170.fw",
- &aru->udev->dev);
- if (!err) {
- aru->init_values = NULL;
- return 0;
- }
-
- if (aru->req_one_stage_fw) {
- dev_err(&aru->udev->dev, "ar9170.fw firmware file "
- "not found and is required for this device\n");
- return -EINVAL;
- }
-
- dev_err(&aru->udev->dev, "ar9170.fw firmware file "
- "not found, trying old firmware...\n");
-
- err = request_firmware(&aru->init_values, "ar9170-1.fw",
- &aru->udev->dev);
- if (err) {
- dev_err(&aru->udev->dev, "file with init values not found.\n");
- return err;
- }
-
- err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
- if (err) {
- release_firmware(aru->init_values);
- dev_err(&aru->udev->dev, "firmware file not found.\n");
- return err;
- }
-
- return err;
-}
-
static int ar9170_usb_reset(struct ar9170_usb *aru)
{
int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
@@ -757,6 +723,103 @@ err_out:
return err;
}
+static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
+{
+ struct device *parent = aru->udev->dev.parent;
+
+ /* unbind anything failed */
+ if (parent)
+ down(&parent->sem);
+ device_release_driver(&aru->udev->dev);
+ if (parent)
+ up(&parent->sem);
+}
+
+static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
+{
+ struct ar9170_usb *aru = context;
+ int err;
+
+ aru->firmware = fw;
+
+ if (!fw) {
+ dev_err(&aru->udev->dev, "firmware file not found.\n");
+ goto err_freefw;
+ }
+
+ err = ar9170_usb_init_device(aru);
+ if (err)
+ goto err_freefw;
+
+ err = ar9170_usb_open(&aru->common);
+ if (err)
+ goto err_unrx;
+
+ err = ar9170_register(&aru->common, &aru->udev->dev);
+
+ ar9170_usb_stop(&aru->common);
+ if (err)
+ goto err_unrx;
+
+ return;
+
+ err_unrx:
+ ar9170_usb_cancel_urbs(aru);
+
+ err_freefw:
+ ar9170_usb_firmware_failed(aru);
+}
+
+static void ar9170_usb_firmware_inits(const struct firmware *fw,
+ void *context)
+{
+ struct ar9170_usb *aru = context;
+ int err;
+
+ if (!fw) {
+ dev_err(&aru->udev->dev, "file with init values not found.\n");
+ ar9170_usb_firmware_failed(aru);
+ return;
+ }
+
+ aru->init_values = fw;
+
+ /* ok so we have the init values -- get code for two-stage */
+
+ err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw",
+ &aru->udev->dev, GFP_KERNEL, aru,
+ ar9170_usb_firmware_finish);
+ if (err)
+ ar9170_usb_firmware_failed(aru);
+}
+
+static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context)
+{
+ struct ar9170_usb *aru = context;
+ int err;
+
+ if (fw) {
+ ar9170_usb_firmware_finish(fw, context);
+ return;
+ }
+
+ if (aru->req_one_stage_fw) {
+ dev_err(&aru->udev->dev, "ar9170.fw firmware file "
+ "not found and is required for this device\n");
+ ar9170_usb_firmware_failed(aru);
+ return;
+ }
+
+ dev_err(&aru->udev->dev, "ar9170.fw firmware file "
+ "not found, trying old firmware...\n");
+
+ err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw",
+ &aru->udev->dev, GFP_KERNEL, aru,
+ ar9170_usb_firmware_inits);
+ if (err)
+ ar9170_usb_firmware_failed(aru);
+}
+
static bool ar9170_requires_one_stage(const struct usb_device_id *id)
{
if (!id->driver_info)
@@ -814,33 +877,9 @@ static int ar9170_usb_probe(struct usb_interface *intf,
if (err)
goto err_freehw;
- err = ar9170_usb_request_firmware(aru);
- if (err)
- goto err_freehw;
-
- err = ar9170_usb_init_device(aru);
- if (err)
- goto err_freefw;
-
- err = ar9170_usb_open(ar);
- if (err)
- goto err_unrx;
-
- err = ar9170_register(ar, &udev->dev);
-
- ar9170_usb_stop(ar);
- if (err)
- goto err_unrx;
-
- return 0;
-
-err_unrx:
- ar9170_usb_cancel_urbs(aru);
-
-err_freefw:
- release_firmware(aru->init_values);
- release_firmware(aru->firmware);
-
+ return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
+ &aru->udev->dev, GFP_KERNEL, aru,
+ ar9170_usb_firmware_step2);
err_freehw:
usb_set_intfdata(intf, NULL);
usb_put_dev(udev);
@@ -860,12 +899,12 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
ar9170_unregister(&aru->common);
ar9170_usb_cancel_urbs(aru);
- release_firmware(aru->init_values);
- release_firmware(aru->firmware);
-
usb_put_dev(aru->udev);
usb_set_intfdata(intf, NULL);
ieee80211_free_hw(aru->common.hw);
+
+ release_firmware(aru->init_values);
+ release_firmware(aru->firmware);
}
#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 42284445b75..dc0786cc263 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -21,6 +21,7 @@
\*************************************/
#include <linux/pci.h>
+#include <linux/slab.h>
#include "ath5k.h"
#include "reg.h"
#include "debug.h"
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 8dce0077b02..3abbe7513ab 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -50,6 +50,7 @@
#include <linux/pci.h>
#include <linux/ethtool.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <net/ieee80211_radiotap.h>
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 6a3f4da7fb4..67665cdc7af 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -21,6 +21,8 @@
* EEPROM access functions and helpers *
\*************************************/
+#include <linux/slab.h>
+
#include "ath5k.h"
#include "reg.h"
#include "debug.h"
@@ -429,8 +431,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
AR5K_EEPROM_READ(o++, val);
- ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
- ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
+ ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
+ ee->ee_q_cal[mode] = val & 0x1f;
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
AR5K_EEPROM_READ(o++, val);
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 72474c0ccaf..68e2bccd90d 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -23,6 +23,7 @@
#define _ATH5K_PHY
#include <linux/delay.h>
+#include <linux/slab.h>
#include "ath5k.h"
#include "reg.h"
@@ -1386,38 +1387,39 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
goto done;
/* Calibration has finished, get the results and re-run */
+
+ /* work around empty results which can apparently happen on 5212 */
for (i = 0; i <= 10; i++) {
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
+ ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+ "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
+ if (i_pwr && q_pwr)
+ break;
}
i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
q_coffd = q_pwr >> 7;
- /* No correction */
- if (i_coffd == 0 || q_coffd == 0)
+ /* protect against divide by 0 and loss of sign bits */
+ if (i_coffd == 0 || q_coffd < 2)
goto done;
- i_coff = ((-iq_corr) / i_coffd);
-
- /* Boundary check */
- if (i_coff > 31)
- i_coff = 31;
- if (i_coff < -32)
- i_coff = -32;
+ i_coff = (-iq_corr) / i_coffd;
+ i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
- q_coff = (((s32)i_pwr / q_coffd) - 128);
+ q_coff = (i_pwr / q_coffd) - 128;
+ q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
- /* Boundary check */
- if (q_coff > 15)
- q_coff = 15;
- if (q_coff < -16)
- q_coff = -16;
+ ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+ "new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
+ i_coff, q_coff, i_coffd, q_coffd);
- /* Commit new I/Q value */
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
- ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
+ /* Commit new I/Q values (set enable bit last to match HAL sources) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
/* Re-enable calibration -if we don't we'll commit
* the same values again and again */
@@ -1873,7 +1875,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
break;
case AR5K_ANTMODE_FIXED_A:
def_ant = 1;
- tx_ant = 0;
+ tx_ant = 1;
use_def_for_tx = true;
update_def_on_tx = false;
use_def_for_rts = true;
@@ -1882,7 +1884,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
break;
case AR5K_ANTMODE_FIXED_B:
def_ant = 2;
- tx_ant = 0;
+ tx_ant = 2;
use_def_for_tx = true;
update_def_on_tx = false;
use_def_for_rts = true;
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 4cb9c5df9f4..1464f89b249 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -2187,6 +2187,7 @@
*/
#define AR5K_PHY_IQ 0x9920 /* Register Address */
#define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */
+#define AR5K_PHY_IQ_CORR_Q_Q_COFF_S 0
#define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */
#define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5
#define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index a35a7db0fc4..cbf28e37984 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -851,12 +851,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
AR5K_INIT_CYCRSSI_THR1);
- /* I/Q correction
- * TODO: Per channel i/q infos ? */
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_CORR_ENABLE |
- (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
- ee->ee_q_cal[ee_mode]);
+ /* I/Q correction (set enable bit last to match HAL sources) */
+ /* TODO: Per channel i/q infos ? */
+ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,
+ ee->ee_i_cal[ee_mode]);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF,
+ ee->ee_q_cal[ee_mode]);
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
+ }
/* Heavy clipping -disable for now */
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
@@ -1379,11 +1382,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_set_sleep_clock(ah, true);
/*
- * Disable beacons and reset the register
+ * Disable beacons and reset the TSF
*/
- AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
- AR5K_BEACON_RESET_TSF);
-
+ AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
+ ath5k_hw_reset_tsf(ah);
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 42d2a506845..081e0085ed4 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "ath9k.h"
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2e767cf22f1..78b571129c9 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -15,6 +15,7 @@
*/
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "hw.h"
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 623c2f88498..3d4d897add6 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "ath9k.h"
static char *dev_info = "ath9k";
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 67ca4e5a601..115e1aeedb5 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1532,8 +1532,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
all_wiphys_idle = ath9k_all_wiphys_idle(sc);
ath9k_set_wiphy_idle(aphy, idle);
- if (!idle && all_wiphys_idle)
- enable_radio = true;
+ enable_radio = (!idle && all_wiphys_idle);
/*
* After we unlock here its possible another wiphy
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index c3b59390fe3..2547b3c4a26 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -39,6 +39,8 @@
* AR9287 - 11n single-band 1x1 MIMO for USB
*/
+#include <linux/slab.h>
+
#include "hw.h"
/**
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index ac34a055c71..244e1c62917 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -15,6 +15,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "ath9k.h"
static const struct ath_rate_table ar5416_11na_ratetable = {
@@ -1323,7 +1325,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
- u32 changed)
+ u32 changed, enum nl80211_channel_type oper_chan_type)
{
struct ath_softc *sc = priv;
struct ath_rate_priv *ath_rc_priv = priv_sta;
@@ -1340,8 +1342,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
return;
- if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
- sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
+ if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
+ oper_chan_type == NL80211_CHAN_HT40PLUS)
oper_cw40 = true;
oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index a43fbf84dab..00c0e21a4af 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/slab.h>
+
#include "ath9k.h"
struct ath9k_vif_iter_data {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 47294f90bbe..294b486bc3e 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1353,25 +1353,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
return htype;
}
-static bool is_pae(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
- __le16 fc;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
-
- if (ieee80211_is_data(fc)) {
- if (ieee80211_is_nullfunc(fc) ||
- /* Port Access Entity (IEEE 802.1X) */
- (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- return true;
- }
- }
-
- return false;
-}
-
static int get_hw_crypto_keytype(struct sk_buff *skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1696,7 +1677,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
goto tx_done;
}
- if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) {
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
/*
* Try aggregation if it's a unicast data frame
* and the destination is HT capable.
@@ -2258,7 +2239,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
if (ATH_TXQ_SETUP(sc, i)) {
txq = &sc->tx.txq[i];
- spin_lock(&txq->axq_lock);
+ spin_lock_bh(&txq->axq_lock);
list_for_each_entry_safe(ac,
ac_tmp, &txq->axq_acq, list) {
@@ -2279,7 +2260,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
}
}
- spin_unlock(&txq->axq_lock);
+ spin_unlock_bh(&txq->axq_lock);
}
}
}
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 04abd1f556b..00489c40be0 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -15,7 +15,6 @@
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
#include "regd.h"
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index be7abf8916a..fa40fdfea71 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -38,6 +38,7 @@
#include <linux/delay.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <asm/div64.h>
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 976104f634a..94e4f1378fc 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -34,6 +34,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
+#include <linux/slab.h>
static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo,
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 1521b1e78d2..9a374ef83a2 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -42,6 +42,7 @@
#include <linux/skbuff.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "b43.h"
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index 984174bc7b0..609e7051e01 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -24,6 +24,7 @@
#include "pcmcia.h"
#include <linux/ssb/ssb.h>
+#include <linux/slab.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index d90217c3a70..b6428ec16dd 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -26,6 +26,8 @@
*/
+#include <linux/slab.h>
+
#include "b43.h"
#include "phy_a.h"
#include "phy_common.h"
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 382826a8da8..29bf34ced86 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -33,6 +33,7 @@
#include "main.h"
#include <linux/bitrev.h>
+#include <linux/slab.h>
static const s8 b43_tssi2dbm_g_table[] = {
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 185219e0a55..c6afe9d9459 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -23,6 +23,8 @@
*/
+#include <linux/slab.h>
+
#include "b43.h"
#include "main.h"
#include "phy_lp.h"
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 795bb1e3345..9c7cd282e46 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -23,6 +23,7 @@
*/
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include "b43.h"
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index a6062c3e89a..aa12273ae71 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -31,6 +31,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
+#include <linux/slab.h>
static u16 generate_cookie(struct b43_pio_txqueue *q,
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c
index 0d3ac64147a..4e56b7bbceb 100644
--- a/drivers/net/wireless/b43/sdio.c
+++ b/drivers/net/wireless/b43/sdio.c
@@ -16,6 +16,7 @@
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
+#include <linux/slab.h>
#include <linux/ssb/ssb.h>
#include "sdio.h"
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 8b9387c6ff3..e91520d0312 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -37,6 +37,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/dst.h>
/* 32bit DMA ops. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 1d070be5a67..bb2dd9329aa 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -40,6 +40,7 @@
#include <linux/sched.h>
#include <linux/skbuff.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <net/dst.h>
#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index aaf227203a9..35033dd342c 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -32,6 +32,7 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include "b43legacy.h"
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index 017c0e9c37e..b033b0ed4ca 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -29,6 +29,7 @@
#include "xmit.h"
#include <linux/delay.h>
+#include <linux/slab.h>
static void tx_start(struct b43legacy_pioqueue *queue)
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 3816df96a66..f4c56121d38 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -1,4 +1,5 @@
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <net/lib80211.h>
#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 90108b698f1..c34a3b7f129 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -1,3 +1,5 @@
+#include <linux/slab.h>
+
#include "hostap_80211.h"
#include "hostap_common.h"
#include "hostap_wlan.h"
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index a2a203c90ba..7e72ac1de49 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/random.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include "hostap_wlan.h"
#include "hostap.h"
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index d19748d90aa..a36501dbbe0 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -3,6 +3,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/if.h>
+#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/timer.h>
#include <linux/skbuff.h>
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
index 4dfb40a84c9..d737091cf6a 100644
--- a/drivers/net/wireless/hostap/hostap_info.c
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -2,6 +2,7 @@
#include <linux/if_arp.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "hostap_wlan.h"
#include "hostap.h"
#include "hostap_ap.h"
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 9419cebca8a..9a082308a9d 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1,5 +1,6 @@
/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/ethtool.h>
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 4d97ae37499..d24dc7dc072 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -9,6 +9,7 @@
#include <linux/if.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index fc04ccdc5be..33e79037770 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -12,6 +12,7 @@
#include <linux/if.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 63c2a7ade5f..8d72e3d1958 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -31,6 +31,7 @@
******************************************************************************/
#include <linux/sched.h>
+#include <linux/slab.h>
#include "ipw2200.h"
@@ -3177,14 +3178,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
int total_nr = 0;
int i;
struct pci_pool *pool;
- u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL];
- dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL];
+ void **virts;
+ dma_addr_t *phys;
IPW_DEBUG_TRACE("<< : \n");
+ virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
+ GFP_KERNEL);
+ if (!virts)
+ return -ENOMEM;
+
+ phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL,
+ GFP_KERNEL);
+ if (!phys) {
+ kfree(virts);
+ return -ENOMEM;
+ }
pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
if (!pool) {
IPW_ERROR("pci_pool_create failed\n");
+ kfree(phys);
+ kfree(virts);
return -ENOMEM;
}
@@ -3254,6 +3268,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
pci_pool_free(pool, virts[i], phys[i]);
pci_pool_destroy(pool);
+ kfree(phys);
+ kfree(virts);
return ret;
}
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index bf45391172f..a6d5e42647e 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -797,7 +797,7 @@ struct libipw_device {
/* Probe / Beacon management */
struct list_head network_free_list;
struct list_head network_list;
- struct libipw_network *networks;
+ struct libipw_network *networks[MAX_NETWORK_COUNT];
int scans;
int scan_age;
diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c
index 65e8c175a4a..c9fe3c99cb0 100644
--- a/drivers/net/wireless/ipw2x00/libipw_geo.c
+++ b/drivers/net/wireless/ipw2x00/libipw_geo.c
@@ -34,7 +34,6 @@
#include <linux/netdevice.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/wireless.h>
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 1ae0b2b02c3..2fa55867bd8 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid;
static int libipw_networks_allocate(struct libipw_device *ieee)
{
- if (ieee->networks)
- return 0;
-
- ieee->networks =
- kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network),
- GFP_KERNEL);
- if (!ieee->networks) {
- printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
- ieee->dev->name);
- return -ENOMEM;
+ int i, j;
+
+ for (i = 0; i < MAX_NETWORK_COUNT; i++) {
+ ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
+ GFP_KERNEL);
+ if (!ieee->networks[i]) {
+ LIBIPW_ERROR("Out of memory allocating beacons\n");
+ for (j = 0; j < i; j++)
+ kfree(ieee->networks[j]);
+ return -ENOMEM;
+ }
}
return 0;
@@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
{
int i;
- if (!ieee->networks)
- return;
-
- for (i = 0; i < MAX_NETWORK_COUNT; i++)
- if (ieee->networks[i].ibss_dfs)
- kfree(ieee->networks[i].ibss_dfs);
-
- kfree(ieee->networks);
- ieee->networks = NULL;
+ for (i = 0; i < MAX_NETWORK_COUNT; i++) {
+ if (ieee->networks[i]->ibss_dfs)
+ kfree(ieee->networks[i]->ibss_dfs);
+ kfree(ieee->networks[i]);
+ }
}
void libipw_networks_age(struct libipw_device *ieee,
@@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee)
INIT_LIST_HEAD(&ieee->network_free_list);
INIT_LIST_HEAD(&ieee->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++)
- list_add_tail(&ieee->networks[i].list,
+ list_add_tail(&ieee->networks[i]->list,
&ieee->network_free_list);
}
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 282b1f7ff1e..39a34da52d5 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -17,6 +17,7 @@
#include <linux/errno.h>
#include <linux/if_arp.h>
#include <linux/in6.h>
+#include <linux/gfp.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/kernel.h>
@@ -24,7 +25,6 @@
#include <linux/netdevice.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/tcp.h>
#include <linux/types.h>
#include <linux/wireless.h>
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c
index 4d89f66f53b..3633c6682e4 100644
--- a/drivers/net/wireless/ipw2x00/libipw_wx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_wx.c
@@ -31,6 +31,7 @@
******************************************************************************/
#include <linux/kmod.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/jiffies.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 47909f94271..902c4d4293e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/wireless.h>
#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 303cc8193ad..0728054a22d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -184,7 +185,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
{
int idx;
- for (idx = 0; idx < IWL_RATE_COUNT; idx++)
+ for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++)
if (iwl3945_rates[idx].plcp == plcp)
return idx;
return -1;
@@ -805,7 +806,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
int sta_id, int tx_id)
{
u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
- u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
+ u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945);
u16 rate_mask;
int rate;
u8 rts_retry_limit;
@@ -2146,7 +2147,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
/* fill in channel group's nominal powers for each rate */
for (rate_index = 0;
- rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) {
+ rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) {
switch (rate_index) {
case IWL_RATE_36M_INDEX_TABLE:
if (i == 0) /* B/G */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 1bd2cd83602..8972166386c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2015,7 +2015,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
"%d index %d\n", scd_ssn , index);
freed = iwl_tx_queue_reclaim(priv, txq_id, index);
- iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+ if (qc)
+ iwl_free_tfds_in_queue(priv, sta_id,
+ tid, freed);
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2042,13 +2044,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
freed = iwl_tx_queue_reclaim(priv, txq_id, index);
if (qc && likely(sta_id != IWL_INVALID_STATION))
- priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+ iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+ else if (sta_id == IWL_INVALID_STATION)
+ IWL_DEBUG_TX_REPLY(priv, "Station not known\n");
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
iwl_wake_queue(priv, txq_id);
}
-
if (qc && likely(sta_id != IWL_INVALID_STATION))
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index c4844adff92..92b3e64fc14 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -259,7 +259,7 @@ static struct iwl_lib_ops iwl6000_lib = {
EEPROM_5000_REG_BAND_3_CHANNELS,
EEPROM_5000_REG_BAND_4_CHANNELS,
EEPROM_5000_REG_BAND_5_CHANNELS,
- EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+ EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_5000_REG_BAND_52_HT40_CHANNELS
},
.verify_signature = iwlcore_eeprom_verify_signature,
@@ -323,7 +323,7 @@ static struct iwl_lib_ops iwl6050_lib = {
EEPROM_5000_REG_BAND_3_CHANNELS,
EEPROM_5000_REG_BAND_4_CHANNELS,
EEPROM_5000_REG_BAND_5_CHANNELS,
- EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+ EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_5000_REG_BAND_52_HT40_CHANNELS
},
.verify_signature = iwlcore_eeprom_verify_signature,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 8bf7c20b9d3..1460116d329 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/wireless.h>
#include <net/mac80211.h>
@@ -345,6 +346,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
!!(rate_n_flags & RATE_MCS_ANT_C_MSK);
}
+/*
+ * Static function to get the expected throughput from an iwl_scale_tbl_info
+ * that wraps a NULL pointer check
+ */
+static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
+{
+ if (tbl->expected_tpt)
+ return tbl->expected_tpt[rs_index];
+ return 0;
+}
+
/**
* rs_collect_tx_data - Update the success/failure sliding window
*
@@ -352,19 +364,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
* at this rate. window->data contains the bitmask of successful
* packets.
*/
-static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
- int scale_index, s32 tpt, int attempts,
- int successes)
+static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
+ int scale_index, int attempts, int successes)
{
struct iwl_rate_scale_data *window = NULL;
static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
- s32 fail_count;
+ s32 fail_count, tpt;
if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
return -EINVAL;
/* Select window for current tx bit rate */
- window = &(windows[scale_index]);
+ window = &(tbl->win[scale_index]);
+
+ /* Get expected throughput */
+ tpt = get_expected_tpt(tbl, scale_index);
/*
* Keep track of only the latest 62 tx frame attempts in this rate's
@@ -738,16 +752,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
(a->is_SGI == b->is_SGI);
}
-/*
- * Static function to get the expected throughput from an iwl_scale_tbl_info
- * that wraps a NULL pointer check
- */
-static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
-{
- if (tbl->expected_tpt)
- return tbl->expected_tpt[rs_index];
- return 0;
-}
/*
* mac80211 sends us Tx status
@@ -764,12 +768,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct iwl_priv *priv = (struct iwl_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl_rate_scale_data *window = NULL;
enum mac80211_rate_control_flags mac_flags;
u32 tx_rate;
struct iwl_scale_tbl_info tbl_type;
- struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
- s32 tpt = 0;
+ struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
@@ -852,7 +854,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
return;
}
- window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
/*
* Updating the frame history depends on whether packets were
@@ -865,8 +866,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
&rs_index);
- tpt = get_expected_tpt(curr_tbl, rs_index);
- rs_collect_tx_data(window, rs_index, tpt,
+ rs_collect_tx_data(curr_tbl, rs_index,
info->status.ampdu_ack_len,
info->status.ampdu_ack_map);
@@ -896,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
* table as active/search.
*/
if (table_type_matches(&tbl_type, curr_tbl))
- tpt = get_expected_tpt(curr_tbl, rs_index);
+ tmp_tbl = curr_tbl;
else if (table_type_matches(&tbl_type, other_tbl))
- tpt = get_expected_tpt(other_tbl, rs_index);
+ tmp_tbl = other_tbl;
else
continue;
-
- /* Constants mean 1 transmission, 0 successes */
- if (i < retries)
- rs_collect_tx_data(window, rs_index, tpt, 1,
- 0);
- else
- rs_collect_tx_data(window, rs_index, tpt, 1,
- legacy_success);
+ rs_collect_tx_data(tmp_tbl, rs_index, 1,
+ i < retries ? 0 : legacy_success);
}
/* Update success/fail counts if not searching for new mode */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 6aeb82b6992..bdff56583e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/sched.h>
@@ -1258,7 +1259,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Ack/clear/reset pending uCode interrupts.
* Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
*/
- iwl_write32(priv, CSR_INT, priv->inta);
+ /* There is a hardware bug in the interrupt mask function that some
+ * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
+ * they are disabled in the CSR_INT_MASK register. Furthermore the
+ * ICT interrupt handling mechanism has another bug that might cause
+ * these unmasked interrupts fail to be detected. We workaround the
+ * hardware bugs here by ACKing all the possible interrupts so that
+ * interrupt coalescing can still be achieved.
+ */
+ iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask);
inta = priv->inta;
@@ -1463,59 +1472,66 @@ static void iwl_nic_start(struct iwl_priv *priv)
}
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
+static int iwl_mac_setup_register(struct iwl_priv *priv);
+
+static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
+{
+ const char *name_pre = priv->cfg->fw_name_pre;
+
+ if (first)
+ priv->fw_index = priv->cfg->ucode_api_max;
+ else
+ priv->fw_index--;
+
+ if (priv->fw_index < priv->cfg->ucode_api_min) {
+ IWL_ERR(priv, "no suitable firmware found!\n");
+ return -ENOENT;
+ }
+
+ sprintf(priv->firmware_name, "%s%d%s",
+ name_pre, priv->fw_index, ".ucode");
+
+ IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n",
+ priv->firmware_name);
+
+ return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
+ &priv->pci_dev->dev, GFP_KERNEL, priv,
+ iwl_ucode_callback);
+}
+
/**
- * iwl_read_ucode - Read uCode images from disk file.
+ * iwl_ucode_callback - callback when firmware was loaded
*
- * Copy into buffers for card to fetch via bus-mastering
+ * If loaded successfully, copies the firmware into buffers
+ * for the card to fetch (via DMA).
*/
-static int iwl_read_ucode(struct iwl_priv *priv)
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
{
+ struct iwl_priv *priv = context;
struct iwl_ucode_header *ucode;
- int ret = -EINVAL, index;
- const struct firmware *ucode_raw;
- const char *name_pre = priv->cfg->fw_name_pre;
const unsigned int api_max = priv->cfg->ucode_api_max;
const unsigned int api_min = priv->cfg->ucode_api_min;
- char buf[25];
u8 *src;
size_t len;
u32 api_ver, build;
u32 inst_size, data_size, init_size, init_data_size, boot_size;
+ int err;
u16 eeprom_ver;
- /* Ask kernel firmware_class module to get the boot firmware off disk.
- * request_firmware() is synchronous, file is in memory on return. */
- for (index = api_max; index >= api_min; index--) {
- sprintf(buf, "%s%d%s", name_pre, index, ".ucode");
- ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
- if (ret < 0) {
- IWL_ERR(priv, "%s firmware file req failed: %d\n",
- buf, ret);
- if (ret == -ENOENT)
- continue;
- else
- goto error;
- } else {
- if (index < api_max)
- IWL_ERR(priv, "Loaded firmware %s, "
- "which is deprecated. "
- "Please use API v%u instead.\n",
- buf, api_max);
-
- IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
- buf, ucode_raw->size);
- break;
- }
+ if (!ucode_raw) {
+ IWL_ERR(priv, "request for firmware file '%s' failed.\n",
+ priv->firmware_name);
+ goto try_again;
}
- if (ret < 0)
- goto error;
+ IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
+ priv->firmware_name, ucode_raw->size);
/* Make sure that we got at least the v1 header! */
if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
IWL_ERR(priv, "File size way too small!\n");
- ret = -EINVAL;
- goto err_release;
+ goto try_again;
}
/* Data from ucode file: header followed by uCode images */
@@ -1540,10 +1556,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
api_max, api_ver);
- priv->ucode_ver = 0;
- ret = -EINVAL;
- goto err_release;
+ goto try_again;
}
+
if (api_ver != api_max)
IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
"got v%u. New firmware can be obtained "
@@ -1585,6 +1600,12 @@ static int iwl_read_ucode(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
boot_size);
+ /*
+ * For any of the failures below (before allocating pci memory)
+ * we will try to load a version with a smaller API -- maybe the
+ * user just got a corrupted version of the latest API.
+ */
+
/* Verify size of file vs. image size info in file's header */
if (ucode_raw->size !=
priv->cfg->ops->ucode->get_header_size(api_ver) +
@@ -1594,41 +1615,35 @@ static int iwl_read_ucode(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv,
"uCode file size %d does not match expected size\n",
(int)ucode_raw->size);
- ret = -EINVAL;
- goto err_release;
+ goto try_again;
}
/* Verify that uCode images will fit in card's SRAM */
if (inst_size > priv->hw_params.max_inst_size) {
IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
inst_size);
- ret = -EINVAL;
- goto err_release;
+ goto try_again;
}
if (data_size > priv->hw_params.max_data_size) {
IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
data_size);
- ret = -EINVAL;
- goto err_release;
+ goto try_again;
}
if (init_size > priv->hw_params.max_inst_size) {
IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
init_size);
- ret = -EINVAL;
- goto err_release;
+ goto try_again;
}
if (init_data_size > priv->hw_params.max_data_size) {
IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
init_data_size);
- ret = -EINVAL;
- goto err_release;
+ goto try_again;
}
if (boot_size > priv->hw_params.max_bsm_size) {
IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
boot_size);
- ret = -EINVAL;
- goto err_release;
+ goto try_again;
}
/* Allocate ucode buffers for card's bus-master loading ... */
@@ -1712,20 +1727,36 @@ static int iwl_read_ucode(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
memcpy(priv->ucode_boot.v_addr, src, len);
+ /**************************************************
+ * This is still part of probe() in a sense...
+ *
+ * 9. Setup and register with mac80211 and debugfs
+ **************************************************/
+ err = iwl_mac_setup_register(priv);
+ if (err)
+ goto out_unbind;
+
+ err = iwl_dbgfs_register(priv, DRV_NAME);
+ if (err)
+ IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
+
/* We have our copies now, allow OS release its copies */
release_firmware(ucode_raw);
- return 0;
+ return;
+
+ try_again:
+ /* try next, if any */
+ if (iwl_request_firmware(priv, false))
+ goto out_unbind;
+ release_firmware(ucode_raw);
+ return;
err_pci_alloc:
IWL_ERR(priv, "failed to allocate pci memory\n");
- ret = -ENOMEM;
iwl_dealloc_ucode_pci(priv);
-
- err_release:
+ out_unbind:
+ device_release_driver(&priv->pci_dev->dev);
release_firmware(ucode_raw);
-
- error:
- return ret;
}
static const char *desc_lookup_text[] = {
@@ -2622,7 +2653,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+ hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS;
/*
@@ -2631,7 +2662,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
*/
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
- hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1;
+ hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
/* we create the 802.11 header and a zero-length SSID element */
hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
@@ -2667,21 +2698,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
-
- /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
- * ucode filename and max sizes are card-specific. */
-
- if (!priv->ucode_code.len) {
- ret = iwl_read_ucode(priv);
- if (ret) {
- IWL_ERR(priv, "Could not read microcode: %d\n", ret);
- mutex_unlock(&priv->mutex);
- return ret;
- }
- }
-
ret = __iwl_up(priv);
-
mutex_unlock(&priv->mutex);
if (ret)
@@ -3314,6 +3331,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
+ cancel_work_sync(&priv->start_internal_scan);
cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->beacon_update);
del_timer_sync(&priv->statistics_periodic);
@@ -3654,17 +3672,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_power_initialize(priv);
iwl_tt_initialize(priv);
- /**************************************************
- * 9. Setup and register with mac80211 and debugfs
- **************************************************/
- err = iwl_mac_setup_register(priv);
+ err = iwl_request_firmware(priv, true);
if (err)
goto out_remove_sysfs;
- err = iwl_dbgfs_register(priv, DRV_NAME);
- if (err)
- IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
-
return 0;
out_remove_sysfs:
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 845831ac053..8b516c5ff0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -60,6 +60,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "iwl-dev.h"
@@ -807,6 +808,18 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
}
}
+ /*
+ * The above algorithm sometimes fails when the ucode
+ * reports 0 for all chains. It's not clear why that
+ * happens to start with, but it is then causing trouble
+ * because this can make us enable more chains than the
+ * hardware really has.
+ *
+ * To be safe, simply mask out any chains that we know
+ * are not on the device.
+ */
+ active_chains &= priv->hw_params.valid_rx_ant;
+
num_tx_chains = 0;
for (i = 0; i < NUM_RX_CHAINS; i++) {
/* loops on all the bits of
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 112149e9b31..049b652bcb5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/etherdevice.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "iwl-eeprom.h"
@@ -307,10 +308,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
- /* Allocate and init all Tx and Command queues */
- ret = iwl_txq_ctx_reset(priv);
- if (ret)
- return ret;
+ /* Allocate or reset and init all Tx and Command queues */
+ if (!priv->txq) {
+ ret = iwl_txq_ctx_alloc(priv);
+ if (ret)
+ return ret;
+ } else
+ iwl_txq_ctx_reset(priv);
set_bit(STATUS_INIT, &priv->status);
@@ -3354,7 +3358,6 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
*/
IWL_DEBUG_INFO(priv, "perform radio reset.\n");
iwl_internal_short_hw_scan(priv);
- return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 4ef7739f9e8..36940a9ec6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
/*****************************************************
* TX
******************************************************/
-int iwl_txq_ctx_reset(struct iwl_priv *priv);
+int iwl_txq_ctx_alloc(struct iwl_priv *priv);
+void iwl_txq_ctx_reset(struct iwl_priv *priv);
void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
@@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id);
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
@@ -503,7 +506,7 @@ void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
-int iwl_internal_short_hw_scan(struct iwl_priv *priv);
+void iwl_internal_short_hw_scan(struct iwl_priv *priv);
int iwl_force_reset(struct iwl_priv *priv, int mode);
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
const u8 *ie, int ie_len, int left);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 7bf44f14679..b6e1b0ebe23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -26,6 +26,7 @@
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/debugfs.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ab891b95804..ef1720a852e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1132,6 +1132,7 @@ struct iwl_priv {
u8 rev_id;
/* uCode images, save to reload in case of failure */
+ int fw_index; /* firmware we're trying to load */
u32 ucode_ver; /* version of ucode, copy of
iwl_ucode.ver */
struct fw_desc ucode_code; /* runtime inst */
@@ -1142,6 +1143,7 @@ struct iwl_priv {
struct fw_desc ucode_boot; /* bootstrap inst */
enum ucode_type ucode_type;
u8 ucode_write_complete; /* the image write is complete */
+ char firmware_name[25];
struct iwl_rxon_time_cmd rxon_timing;
@@ -1294,6 +1296,7 @@ struct iwl_priv {
struct work_struct tt_work;
struct work_struct ct_enter;
struct work_struct ct_exit;
+ struct work_struct start_internal_scan;
struct tasklet_struct irq_tasklet;
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 36580d8d8b8..2ffc2edbf4f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -28,6 +28,8 @@
/* sparse doesn't like tracepoint macros */
#ifndef __CHECKER__
+#include "iwl-dev.h"
+
#define CREATE_TRACE_POINTS
#include "iwl-devtrace.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index ff4d012ce26..ae7319bb3a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -28,7 +28,6 @@
#define __IWLWIFI_DEVICE_TRACE
#include <linux/tracepoint.h>
-#include "iwl-dev.h"
#if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
#undef TRACE_EVENT
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index fd37152abae..fb5bb487f3b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -63,6 +63,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 4e1ba824dc5..8171c701e4e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -203,6 +203,10 @@ struct iwl_eeprom_enhanced_txpwr {
#define EEPROM_5000_REG_BAND_52_HT40_CHANNELS ((0x92)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */
+/* 6000 regulatory - indirect access */
+#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
+
/* 6000 and up regulatory tx power - indirect access */
/* max. elements per section */
#define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS (8)
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index c719baf2585..16eb3ced9b3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -31,6 +31,7 @@
#include <linux/io.h>
+#include "iwl-dev.h"
#include "iwl-debug.h"
#include "iwl-devtrace.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 1a1a9f081cc..548dac2f6a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index df257bc15f4..e5eb339107d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -28,6 +28,7 @@
*****************************************************************************/
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include <asm/unaligned.h>
#include "iwl-eeprom.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index dd9ff2ed645..12e455a4b90 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -25,6 +25,7 @@
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/etherdevice.h>
#include <net/mac80211.h>
@@ -469,6 +470,8 @@ EXPORT_SYMBOL(iwl_init_scan_params);
static int iwl_scan_initiate(struct iwl_priv *priv)
{
+ WARN_ON(!mutex_is_locked(&priv->mutex));
+
IWL_DEBUG_INFO(priv, "Starting scan...\n");
set_bit(STATUS_SCANNING, &priv->status);
priv->is_internal_short_scan = false;
@@ -546,24 +549,31 @@ EXPORT_SYMBOL(iwl_mac_hw_scan);
* internal short scan, this function should only been called while associated.
* It will reset and tune the radio to prevent possible RF related problem
*/
-int iwl_internal_short_hw_scan(struct iwl_priv *priv)
+void iwl_internal_short_hw_scan(struct iwl_priv *priv)
{
- int ret = 0;
+ queue_work(priv->workqueue, &priv->start_internal_scan);
+}
+
+static void iwl_bg_start_internal_scan(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, start_internal_scan);
+
+ mutex_lock(&priv->mutex);
if (!iwl_is_ready_rf(priv)) {
- ret = -EIO;
IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
- goto out;
+ goto unlock;
}
+
if (test_bit(STATUS_SCANNING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
- ret = -EAGAIN;
- goto out;
+ goto unlock;
}
+
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
- ret = -EAGAIN;
- goto out;
+ goto unlock;
}
priv->scan_bands = 0;
@@ -576,9 +586,8 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv)
set_bit(STATUS_SCANNING, &priv->status);
priv->is_internal_short_scan = true;
queue_work(priv->workqueue, &priv->request_scan);
-
-out:
- return ret;
+ unlock:
+ mutex_unlock(&priv->mutex);
}
EXPORT_SYMBOL(iwl_internal_short_hw_scan);
@@ -638,20 +647,9 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
if (left < 0)
return 0;
*pos++ = WLAN_EID_SSID;
- if (!priv->is_internal_short_scan &&
- priv->scan_request->n_ssids) {
- struct cfg80211_ssid *ssid =
- priv->scan_request->ssids;
-
- /* Broadcast if ssid_len is 0 */
- *pos++ = ssid->ssid_len;
- memcpy(pos, ssid->ssid, ssid->ssid_len);
- pos += ssid->ssid_len;
- len += 2 + ssid->ssid_len;
- } else {
- *pos++ = 0;
- len += 2;
- }
+ *pos++ = 0;
+
+ len += 2;
if (WARN_ON(left < ie_len))
return len;
@@ -780,26 +778,20 @@ static void iwl_bg_request_scan(struct work_struct *data)
if (priv->is_internal_short_scan) {
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
} else if (priv->scan_request->n_ssids) {
+ int i, p = 0;
IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
- /*
- * The first SSID to scan is stuffed into the probe request
- * template and the remaining ones are handled through the
- * direct_scan array.
- */
- if (priv->scan_request->n_ssids > 1) {
- int i, p = 0;
- for (i = 1; i < priv->scan_request->n_ssids; i++) {
- if (!priv->scan_request->ssids[i].ssid_len)
- continue;
- scan->direct_scan[p].id = WLAN_EID_SSID;
- scan->direct_scan[p].len =
- priv->scan_request->ssids[i].ssid_len;
- memcpy(scan->direct_scan[p].ssid,
- priv->scan_request->ssids[i].ssid,
- priv->scan_request->ssids[i].ssid_len);
- n_probes++;
- p++;
- }
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ /* always does wildcard anyway */
+ if (!priv->scan_request->ssids[i].ssid_len)
+ continue;
+ scan->direct_scan[p].id = WLAN_EID_SSID;
+ scan->direct_scan[p].len =
+ priv->scan_request->ssids[i].ssid_len;
+ memcpy(scan->direct_scan[p].ssid,
+ priv->scan_request->ssids[i].ssid,
+ priv->scan_request->ssids[i].ssid_len);
+ n_probes++;
+ p++;
}
is_active = true;
} else
@@ -981,6 +973,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+ INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
}
EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1ed5206721e..8dd0c036d54 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -29,6 +29,7 @@
#include <linux/etherdevice.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "iwl-eeprom.h"
#include "iwl-dev.h"
@@ -124,7 +125,7 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
else {
- IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n",
+ IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
priv->stations[sta_id].tid[tid].tfds_in_queue,
freed);
priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
@@ -193,10 +194,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
struct iwl_queue *q = &txq->q;
struct device *dev = &priv->pci_dev->dev;
int i;
+ bool huge = false;
if (q->n_bd == 0)
return;
+ for (; q->read_ptr != q->write_ptr;
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+ /* we have no way to tell if it is a huge cmd ATM */
+ i = get_cmd_index(q, q->read_ptr, 0);
+
+ if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+ huge = true;
+ continue;
+ }
+
+ pci_unmap_single(priv->pci_dev,
+ pci_unmap_addr(&txq->meta[i], mapping),
+ pci_unmap_len(&txq->meta[i], len),
+ PCI_DMA_BIDIRECTIONAL);
+ }
+ if (huge) {
+ i = q->n_window;
+ pci_unmap_single(priv->pci_dev,
+ pci_unmap_addr(&txq->meta[i], mapping),
+ pci_unmap_len(&txq->meta[i], len),
+ PCI_DMA_BIDIRECTIONAL);
+ }
+
/* De-alloc array of command/tx buffers */
for (i = 0; i <= TFD_CMD_SLOTS; i++)
kfree(txq->cmd[i]);
@@ -409,6 +434,26 @@ out_free_arrays:
}
EXPORT_SYMBOL(iwl_tx_queue_init);
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id)
+{
+ int actual_slots = slots_num;
+
+ if (txq_id == IWL_CMD_QUEUE_NUM)
+ actual_slots++;
+
+ memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+
+ txq->need_update = 0;
+
+ /* Initialize queue's high/low-water marks, and head/tail indexes */
+ iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+
+ /* Tell device where to find queue */
+ priv->cfg->ops->lib->txq_init(priv, txq);
+}
+EXPORT_SYMBOL(iwl_tx_queue_reset);
+
/**
* iwl_hw_txq_ctx_free - Free TXQ Context
*
@@ -420,8 +465,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
/* Tx queues */
if (priv->txq) {
- for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
- txq_id++)
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
if (txq_id == IWL_CMD_QUEUE_NUM)
iwl_cmd_queue_free(priv);
else
@@ -437,15 +481,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
/**
- * iwl_txq_ctx_reset - Reset TX queue context
- * Destroys all DMA structures and initialize them again
+ * iwl_txq_ctx_alloc - allocate TX queue context
+ * Allocate all Tx DMA structures and initialize them
*
* @param priv
* @return error code
*/
-int iwl_txq_ctx_reset(struct iwl_priv *priv)
+int iwl_txq_ctx_alloc(struct iwl_priv *priv)
{
- int ret = 0;
+ int ret;
int txq_id, slots_num;
unsigned long flags;
@@ -503,8 +547,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
return ret;
}
+void iwl_txq_ctx_reset(struct iwl_priv *priv)
+{
+ int txq_id, slots_num;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Turn off all Tx DMA fifos */
+ priv->cfg->ops->lib->txq_set_sched(priv, 0);
+
+ /* Tell NIC where to find the "keep warm" buffer */
+ iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* Alloc and init all Tx queues, including the command queue (#4) */
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
+ slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
+ TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+ iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
+ }
+}
+
/**
- * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
+ * iwl_txq_ctx_stop - Stop all Tx DMA channels
*/
void iwl_txq_ctx_stop(struct iwl_priv *priv)
{
@@ -524,9 +591,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
1000);
}
spin_unlock_irqrestore(&priv->lock, flags);
-
- /* Deallocate memory for all Tx queues */
- iwl_hw_txq_ctx_free(priv);
}
EXPORT_SYMBOL(iwl_txq_ctx_stop);
@@ -1049,6 +1113,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
spin_lock_irqsave(&priv->hcmd_lock, flags);
+ /* If this is a huge cmd, mark the huge flag also on the meta.flags
+ * of the _original_ cmd. This is used for DMA mapping clean up.
+ */
+ if (cmd->flags & CMD_SIZE_HUGE) {
+ idx = get_cmd_index(q, q->write_ptr, 0);
+ txq->meta[idx].flags = CMD_SIZE_HUGE;
+ }
+
idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
out_cmd = txq->cmd[idx];
out_meta = &txq->meta[idx];
@@ -1226,6 +1298,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
struct iwl_device_cmd *cmd;
struct iwl_cmd_meta *meta;
+ struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
/* If a Tx command is being handled and it isn't in the actual
* command queue then there a command routing bug has been introduced
@@ -1239,9 +1312,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
return;
}
- cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
- cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
- meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
+ /* If this is a huge cmd, clear the huge flag on the meta.flags
+ * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
+ * the DMA buffer for the scan (huge) command.
+ */
+ if (huge) {
+ cmd_index = get_cmd_index(&txq->q, index, 0);
+ txq->meta[cmd_index].flags = 0;
+ }
+ cmd_index = get_cmd_index(&txq->q, index, huge);
+ cmd = txq->cmd[cmd_index];
+ meta = &txq->meta[cmd_index];
pci_unmap_single(priv->pci_dev,
pci_unmap_addr(meta, mapping),
@@ -1263,6 +1344,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
get_cmd_string(cmd->hdr.cmd));
wake_up_interruptible(&priv->wait_command_queue);
}
+ meta->flags = 0;
}
EXPORT_SYMBOL(iwl_tx_cmd_complete);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 54daa38ecba..b55e4f39a9e 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/sched.h>
@@ -1955,7 +1956,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv,
{
int i;
- for (i = 0; i < IWL_RATE_COUNT; i++) {
+ for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
rates[i].bitrate = iwl3945_rates[i].ieee * 5;
rates[i].hw_value = i; /* Rate scaling will work on indexes */
rates[i].hw_value_short = i;
@@ -3921,7 +3922,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+ hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS;
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 7c4f44a9c3e..a1d45cce0eb 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -27,6 +27,7 @@
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#include <linux/ieee80211.h>
+#include <linux/slab.h>
#include <net/cfg80211.h>
#include "iwm.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 1e41ad0fcad..42df7262f9f 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -41,6 +41,7 @@
#include <linux/etherdevice.h>
#include <linux/ieee80211.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "iwm.h"
#include "bus.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index be992ca41cf..cbb81befdb5 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -21,6 +21,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
@@ -89,7 +90,7 @@ static int iwm_debugfs_dbg_modules_write(void *data, u64 val)
for (i = 0; i < __IWM_DM_NR; i++)
iwm->dbg.dbg_module[i] = 0;
- for_each_bit(bit, &iwm->dbg.dbg_modules, __IWM_DM_NR)
+ for_each_set_bit(bit, &iwm->dbg.dbg_modules, __IWM_DM_NR)
iwm->dbg.dbg_module[bit] = iwm->dbg.dbg_level;
return 0;
diff --git a/drivers/net/wireless/iwmc3200wifi/eeprom.c b/drivers/net/wireless/iwmc3200wifi/eeprom.c
index 8091421ee5e..e80e776b74f 100644
--- a/drivers/net/wireless/iwmc3200wifi/eeprom.c
+++ b/drivers/net/wireless/iwmc3200wifi/eeprom.c
@@ -37,6 +37,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "iwm.h"
#include "umac.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
index d13c8853ee8..229de990379 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.c
+++ b/drivers/net/wireless/iwmc3200wifi/hal.c
@@ -98,6 +98,7 @@
*/
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include "iwm.h"
#include "bus.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h
index a3a79b5e289..a855a99e49b 100644
--- a/drivers/net/wireless/iwmc3200wifi/lmac.h
+++ b/drivers/net/wireless/iwmc3200wifi/lmac.h
@@ -262,7 +262,7 @@ struct iwm_ct_kill_cfg_cmd {
/* Power Management */
#define POWER_TABLE_CMD 0x77
-#define SAVE_RESTORE_ADRESS_CMD 0x78
+#define SAVE_RESTORE_ADDRESS_CMD 0x78
#define REPLY_WATERMARK_CMD 0x79
#define PM_DEBUG_STATISTIC_NOTIFIC 0x7B
#define PD_FLUSH_N_NOTIFICATION 0x7C
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 7f34d6dd3c4..23856d359e1 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -41,6 +41,7 @@
#include <linux/sched.h>
#include <linux/ieee80211.h>
#include <linux/wireless.h>
+#include <linux/slab.h>
#include "iwm.h"
#include "debug.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
index c4c0d23c63e..13a69ebf2a9 100644
--- a/drivers/net/wireless/iwmc3200wifi/netdev.c
+++ b/drivers/net/wireless/iwmc3200wifi/netdev.c
@@ -46,6 +46,7 @@
* -> sdio_disable_func()
*/
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include "iwm.h"
#include "commands.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index ad8f7eabb5a..3257d4fad83 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -44,6 +44,7 @@
#include <linux/ieee80211.h>
#include <linux/if_arp.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
#include "iwm.h"
@@ -1116,7 +1117,7 @@ static int iwm_ntf_stop_resume_tx(struct iwm_priv *iwm, u8 *buf,
return -EINVAL;
}
- for_each_bit(bit, (unsigned long *)&tid_msk, IWM_UMAC_TID_NR) {
+ for_each_set_bit(bit, (unsigned long *)&tid_msk, IWM_UMAC_TID_NR) {
tid_info = &sta_info->tid_info[bit];
mutex_lock(&tid_info->mutex);
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index a7ec7eac913..1eafd6dec3f 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -63,6 +63,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/debugfs.h>
#include <linux/mmc/sdio_ids.h>
diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c
index 55905f02309..f6a02f123f3 100644
--- a/drivers/net/wireless/iwmc3200wifi/tx.c
+++ b/drivers/net/wireless/iwmc3200wifi/tx.c
@@ -64,6 +64,7 @@
* (i.e. half of the max size). [iwm_tx_worker]
*/
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/ieee80211.h>
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index f03d5e4e59c..12a2ef9dace 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -4,6 +4,7 @@
#include <linux/etherdevice.h>
#include <linux/ieee80211.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/lib80211.h>
#include "assoc.h"
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 4396dccd12a..ce7bec402a3 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -6,6 +6,7 @@
*
*/
+#include <linux/slab.h>
#include <net/cfg80211.h>
#include "cfg.h"
@@ -172,6 +173,8 @@ int lbs_cfg_register(struct lbs_private *priv)
if (ret < 0)
lbs_pr_err("cannot register wiphy device\n");
+ priv->wiphy_registered = true;
+
ret = register_netdev(priv->dev);
if (ret)
lbs_pr_err("cannot register network device\n");
@@ -190,9 +193,11 @@ void lbs_cfg_free(struct lbs_private *priv)
if (!wdev)
return;
- if (wdev->wiphy) {
+ if (priv->wiphy_registered)
wiphy_unregister(wdev->wiphy);
+
+ if (wdev->wiphy)
wiphy_free(wdev->wiphy);
- }
+
kfree(wdev);
}
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 82371ef3952..cdb9b9650d7 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -5,6 +5,7 @@
#include <linux/kfifo.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "host.h"
#include "decl.h"
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index e7470442f76..88f7131d66e 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -2,6 +2,7 @@
* This file contains the handling of command
* responses as well as events generated by firmware.
*/
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 587b0cb0088..a48ccaffb28 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -4,6 +4,7 @@
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
#include <net/lib80211.h>
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 6977ee82021..6875e1498bd 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -36,6 +36,7 @@ struct lbs_private {
/* CFG80211 */
struct wireless_dev *wdev;
+ bool wiphy_registered;
/* Mesh */
struct net_device *mesh_dev; /* Virtual device */
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 1f6cb58dd66..6d55439a7b9 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -22,6 +22,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 7a73f625273..7d1a3c6b6ce 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 3ea03f259ee..fe3f08028eb 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -24,6 +24,7 @@
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/semaphore.h>
+#include <linux/slab.h>
#include <linux/spi/libertas_spi.h>
#include <linux/spi/spi.h>
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 65e174595d1..fcea5741ba6 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -5,6 +5,7 @@
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#ifdef CONFIG_OLPC
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 28a1c9d1627..598080414b1 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -13,6 +13,7 @@
#include <linux/kfifo.h>
#include <linux/stddef.h>
#include <linux/ieee80211.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
#include <net/cfg80211.h>
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 2daf8ffdb7e..784dae71470 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -2,6 +2,7 @@
* This file contains the handling of RX in wlan driver.
*/
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include "host.h"
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 220361e69cd..24cd54b3a80 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -4,6 +4,7 @@
* IOCTL handlers as well as command preperation and response routines
* for sending scan commands to the firmware.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 71f88a08e09..9b555884b08 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -2,6 +2,7 @@
* This file contains ioctl functions
*/
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/if.h>
#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c
index 28790e03dc4..b620daf59ef 100644
--- a/drivers/net/wireless/libertas_tf/cmd.c
+++ b/drivers/net/wireless/libertas_tf/cmd.c
@@ -7,6 +7,8 @@
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
+#include <linux/slab.h>
+
#include "libertas_tf.h"
static const struct channel_range channel_ranges[] = {
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index 3691c307e67..8cc9db60c14 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -11,6 +11,7 @@
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#define DRV_NAME "lbtf_usb"
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 6ab30033c26..7945ff5aa33 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -7,6 +7,8 @@
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
+#include <linux/slab.h>
+
#include "libertas_tf.h"
#include "linux/etherdevice.h"
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 6ea77e95277..7cd5f56662f 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -14,6 +14,7 @@
*/
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <net/dst.h>
#include <net/xfrm.h>
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index ac65e13eb0d..12fdcb25fd3 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
@@ -3851,6 +3852,7 @@ MODULE_FIRMWARE("mwl8k/helper_8366.fw");
MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
+ { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
index cfa72962052..5ea0f7cf85b 100644
--- a/drivers/net/wireless/orinoco/fw.c
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -3,6 +3,7 @@
* See copyright notice in main.c
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/device.h>
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index b42634c614b..413e9ab6cab 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -78,6 +78,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h>
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index d2f10e9c216..330d42d4533 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -3,6 +3,7 @@
* See copyright notice in main.c
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ieee80211.h>
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 31ca241f775..fbcc6e1a2e1 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -2,6 +2,7 @@
*
* See copyright notice in main.c
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 8e3818f6832..187e263b045 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -20,6 +20,7 @@
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/sort.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index e7b9e9cb39f..c43a5d461ab 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -17,6 +17,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 4f752a21495..a7cb9eb759a 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -17,6 +17,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index ed4bdffdd63..269fda36283 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index afd26bf0664..c8f09da1f84 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -29,6 +29,7 @@
#include <linux/spi/spi.h>
#include <linux/etherdevice.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include "p54spi.h"
#include "p54spi_eeprom.h"
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index b3c4fbd80d8..743a6c68b29 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
@@ -35,6 +36,7 @@ MODULE_FIRMWARE("isl3887usb");
static struct usb_device_id p54u_table[] __devinitdata = {
/* Version 1 devices (pci chip + net2280) */
{USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
+ {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
{USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
{USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */
{USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index f7f5c793514..a45818ebfdf 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index a3ba3539db0..689d59a13d5 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -19,6 +19,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 872b64783e7..ac99eaaeabc 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -17,6 +17,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/delay.h>
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 69d2f882fd0..adb289723a9 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/system.h>
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
index 87a1734663d..0b27e50fe0d 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.h
+++ b/drivers/net/wireless/prism54/islpci_mgt.h
@@ -22,6 +22,7 @@
#include <linux/wireless.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
/*
* Function definitions
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 1187e6112a6..d66933d70fb 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -17,6 +17,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "prismcompat.h"
#include "islpci_dev.h"
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 84c530aa52f..11865ea2187 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -35,7 +35,6 @@
#include <linux/proc_fs.h>
#include <linux/ptrace.h>
#include <linux/seq_file.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/init.h>
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 9f6d6bf06b8..1de5b22d3ef 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -41,6 +41,7 @@
#include <linux/if_arp.h>
#include <linux/ctype.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
#include <net/cfg80211.h>
#include <linux/usb/usbnet.h>
@@ -1496,51 +1497,67 @@ static void set_multicast_list(struct usbnet *usbdev)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct dev_mc_list *mclist;
- __le32 filter;
- int ret, i, size;
- char *buf;
+ __le32 filter, basefilter;
+ int ret;
+ char *mc_addrs = NULL;
+ int mc_count;
- filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
+ basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED |
+ RNDIS_PACKET_TYPE_BROADCAST;
- netif_addr_lock_bh(usbdev->net);
if (usbdev->net->flags & IFF_PROMISC) {
filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
RNDIS_PACKET_TYPE_ALL_LOCAL;
- } else if (usbdev->net->flags & IFF_ALLMULTI ||
- netdev_mc_count(usbdev->net) > priv->multicast_size) {
+ } else if (usbdev->net->flags & IFF_ALLMULTI) {
+ filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+ }
+
+ if (filter != basefilter)
+ goto set_filter;
+
+ /*
+ * mc_list should be accessed holding the lock, so copy addresses to
+ * local buffer first.
+ */
+ netif_addr_lock_bh(usbdev->net);
+ mc_count = netdev_mc_count(usbdev->net);
+ if (mc_count > priv->multicast_size) {
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
- } else if (!netdev_mc_empty(usbdev->net)) {
- size = min(priv->multicast_size, netdev_mc_count(usbdev->net));
- buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
- if (!buf) {
+ } else if (mc_count) {
+ int i = 0;
+
+ mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC);
+ if (!mc_addrs) {
netdev_warn(usbdev->net,
"couldn't alloc %d bytes of memory\n",
- size * ETH_ALEN);
+ mc_count * ETH_ALEN);
netif_addr_unlock_bh(usbdev->net);
return;
}
- i = 0;
- netdev_for_each_mc_addr(mclist, usbdev->net) {
- if (i == size)
- break;
- memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
- }
+ netdev_for_each_mc_addr(mclist, usbdev->net)
+ memcpy(mc_addrs + i++ * ETH_ALEN,
+ mclist->dmi_addr, ETH_ALEN);
+ }
+ netif_addr_unlock_bh(usbdev->net);
- ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf,
- i * ETH_ALEN);
- if (ret == 0 && i > 0)
+ if (filter != basefilter)
+ goto set_filter;
+
+ if (mc_count) {
+ ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs,
+ mc_count * ETH_ALEN);
+ kfree(mc_addrs);
+ if (ret == 0)
filter |= RNDIS_PACKET_TYPE_MULTICAST;
else
filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
- i, priv->multicast_size, ret);
-
- kfree(buf);
+ mc_count, priv->multicast_size, ret);
}
- netif_addr_unlock_bh(usbdev->net);
+set_filter:
ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
sizeof(filter));
if (ret < 0) {
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index c22b04042d5..5f5204b8289 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
#include "rt2x00.h"
#include "rt2x00pci.h"
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 52bbcf1bd17..2a73f593aab 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
#include "rt2x00.h"
#include "rt2x00pci.h"
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index ee34c137e7c..8ebb705fe10 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -29,6 +29,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "rt2x00.h"
@@ -368,7 +369,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
/*
* The encryption key doesn't fit within the CSR cache,
- * this means we should allocate it seperately and use
+ * this means we should allocate it separately and use
* rt2x00usb_vendor_request() to send the key to the hardware.
*/
reg = KEY_ENTRY(key->hw_key_idx);
@@ -382,7 +383,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
/*
* The driver does not support the IV/EIV generation
* in hardware. However it demands the data to be provided
- * both seperately as well as inside the frame.
+ * both separately as well as inside the frame.
* We already provided the CONFIG_CRYPTO_COPY_IV to rt2x00lib
* to ensure rt2x00lib will not strip the data from the
* frame after the copy, now we must tell mac80211
@@ -1643,6 +1644,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
unsigned int i;
/*
+ * Disable powersaving as default.
+ */
+ rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+ /*
* Initialize all hw fields.
*/
rt2x00dev->hw->flags =
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 18d4d8e4ae6..c015ce9fdd0 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -35,6 +35,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "rt2x00.h"
#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
@@ -812,9 +813,9 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 24,
rt2x00dev->calibration[conf_is_ht40(conf)]);
- rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
- rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+ rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
}
static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index aca8c124f43..91cce2d0f6d 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1225,7 +1225,7 @@ MODULE_LICENSE("GPL");
#ifdef CONFIG_RT2800PCI_SOC
static int rt2800soc_probe(struct platform_device *pdev)
{
- return rt2x00soc_probe(pdev, rt2800pci_ops);
+ return rt2x00soc_probe(pdev, &rt2800pci_ops);
}
static struct platform_driver rt2800soc_driver = {
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 5e4ee2023fc..d27d7d5d850 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -99,7 +99,7 @@ static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
* There are 2 variations of the rt2870 firmware.
* a) size: 4kb
* b) size: 8kb
- * Note that (b) contains 2 seperate firmware blobs of 4k
+ * Note that (b) contains 2 separate firmware blobs of 4k
* within the file. The first blob is the same firmware as (a),
* but the second blob is for the additional chipsets.
*/
@@ -117,7 +117,7 @@ static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
/*
* 8kb firmware files must be checked as if it were
- * 2 seperate firmware files.
+ * 2 separate firmware files.
*/
while (offset < len) {
if (!rt2800usb_check_crc(data + offset, 4096))
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 70c04c282ef..9569fb4e5bc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include "rt2x00.h"
@@ -109,7 +110,7 @@ struct rt2x00debug_intf {
/*
* HW crypto statistics.
- * All statistics are stored seperately per cipher type.
+ * All statistics are stored separately per cipher type.
*/
struct rt2x00debug_crypto crypto_stats[CIPHER_MAX];
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b93731b7990..eda73ba735a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "rt2x00.h"
#include "rt2x00lib.h"
@@ -394,7 +395,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
/*
* Hardware might have stripped the IV/EIV/ICV data,
* in that case it is possible that the data was
- * provided seperately (through hardware descriptor)
+ * provided separately (through hardware descriptor)
* in which case we should reinsert the data into the frame.
*/
if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 047123b766f..cf3f1c0c438 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "rt2x00.h"
#include "rt2x00pci.h"
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 0b4801a1460..a0bd36fc4d2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -24,6 +24,7 @@
Abstract: rt2x00 queue specific routines.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
@@ -497,7 +498,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
/*
* When hardware encryption is supported, and this frame
* is to be encrypted, we should strip the IV/EIV data from
- * the frame so we can provide it to the driver seperately.
+ * the frame so we can provide it to the driver separately.
*/
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c
index 4efdc96010f..fc98063de71 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.c
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.c
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "rt2x00.h"
#include "rt2x00soc.h"
@@ -112,6 +113,7 @@ exit_free_device:
return retval;
}
+EXPORT_SYMBOL_GPL(rt2x00soc_probe);
int rt2x00soc_remove(struct platform_device *pdev)
{
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.h b/drivers/net/wireless/rt2x00/rt2x00soc.h
index 4739edfe2f0..474cbfc1efc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.h
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.h
@@ -26,8 +26,6 @@
#ifndef RT2X00SOC_H
#define RT2X00SOC_H
-#define KSEG1ADDR(__ptr) __ptr
-
/*
* SoC driver handlers.
*/
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 0a751e73aa0..f9a7f8b1741 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/bug.h>
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index e2da928dd9f..432e75f960b 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/eeprom_93cx6.h>
@@ -476,7 +477,7 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
* The driver does not support the IV/EIV generation
* in hardware. However it doesn't support the IV/EIV
* inside the ieee80211 frame either, but requires it
- * to be provided seperately for the descriptor.
+ * to be provided separately for the descriptor.
* rt2x00lib will cut the IV/EIV data out of all frames
* given to us by mac80211, but we must tell mac80211
* to generate the IV/EIV data.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index f39a8ed1784..bb58d797fb7 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "rt2x00.h"
@@ -339,7 +340,7 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
* The driver does not support the IV/EIV generation
* in hardware. However it doesn't support the IV/EIV
* inside the ieee80211 frame either, but requires it
- * to be provided seperately for the descriptor.
+ * to be provided separately for the descriptor.
* rt2x00lib will cut the IV/EIV data out of all frames
* given to us by mac80211, but we must tell mac80211
* to generate the IV/EIV data.
@@ -439,7 +440,7 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
* The driver does not support the IV/EIV generation
* in hardware. However it doesn't support the IV/EIV
* inside the ieee80211 frame either, but requires it
- * to be provided seperately for the descriptor.
+ * to be provided separately for the descriptor.
* rt2x00lib will cut the IV/EIV data out of all frames
* given to us by mac80211, but we must tell mac80211
* to generate the IV/EIV data.
@@ -1661,7 +1662,7 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
/*
* Hardware has stripped IV/EIV data from 802.11 frame during
- * decryption. It has provided the data seperately but rt2x00lib
+ * decryption. It has provided the data separately but rt2x00lib
* should decide if it should be reinserted.
*/
rxdesc->flags |= RX_FLAG_IV_STRIPPED;
@@ -2352,6 +2353,8 @@ static struct usb_device_id rt73usb_device_table[] = {
{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* CEIVA */
+ { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
/* CNet */
{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 2b928ecf47b..2131a442831 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/eeprom_93cx6.h>
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 0fb850e0c65..1d30792973f 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/eeprom_93cx6.h>
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index beff084040b..91891f92807 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -1,6 +1,7 @@
#include "wl1251_acx.h"
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/crc7.h>
#include "wl1251.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 28a80867408..d5ac79aeaa7 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -22,6 +22,7 @@
*/
#include <linux/gpio.h>
+#include <linux/slab.h>
#include "wl1251_reg.h"
#include "wl1251_boot.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
index 0320b478bb3..a37b30cef48 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -1,6 +1,7 @@
#include "wl1251_cmd.h"
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/crc7.h>
#include "wl1251.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
index 0ccba57fb9f..5e4465ac08f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
@@ -24,6 +24,7 @@
#include "wl1251_debugfs.h"
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include "wl1251.h"
#include "wl1251_acx.h"
@@ -466,7 +467,8 @@ out:
void wl1251_debugfs_reset(struct wl1251 *wl)
{
- memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+ if (wl->stats.fw_stats != NULL)
+ memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
wl->stats.retry_count = 0;
wl->stats.excessive_retries = 0;
}
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c
index 5aad56ea715..b538bdd7b32 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ b/drivers/net/wireless/wl12xx/wl1251_init.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "wl1251_init.h"
#include "wl12xx_80211.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 24ae6a360ac..1c8226eee40 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -29,6 +29,7 @@
#include <linux/crc32.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include "wl1251.h"
#include "wl12xx_80211.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index b56732226cc..6f229e0990f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -23,6 +23,7 @@
*/
#include <linux/skbuff.h>
+#include <linux/gfp.h>
#include <net/mac80211.h>
#include "wl1251.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 9cc8c323830..3bfb59bd463 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -23,6 +23,7 @@
#include <linux/irq.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/crc7.h>
#include <linux/spi/spi.h>
#include <linux/spi/wl12xx.h>
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 60f10dce480..308782421fc 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -27,6 +27,7 @@
#include <linux/platform_device.h>
#include <linux/crc7.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include "wl1271.h"
#include "wl12xx_80211.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 2be76ee42bb..02435626306 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -22,6 +22,7 @@
*/
#include <linux/gpio.h>
+#include <linux/slab.h>
#include "wl1271_acx.h"
#include "wl1271_reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 36a64e06f29..e7832f3318e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -26,6 +26,7 @@
#include <linux/crc7.h>
#include <linux/spi/spi.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include "wl1271.h"
#include "wl1271_reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index 8d7588ca68f..3f7ff8d0cf5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -24,6 +24,7 @@
#include "wl1271_debugfs.h"
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include "wl1271.h"
#include "wl1271_acx.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 86c30a86a45..d189e8fe05a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "wl1271_init.h"
#include "wl12xx_80211.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 2a864b24291..65a1aeba241 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -33,6 +33,7 @@
#include <linux/vmalloc.h>
#include <linux/spi/wl12xx.h>
#include <linux/inetdevice.h>
+#include <linux/slab.h>
#include "wl1271.h"
#include "wl12xx_80211.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index 6730f5b96e7..c723d9c7e13 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -21,6 +21,8 @@
*
*/
+#include <linux/gfp.h>
+
#include "wl1271.h"
#include "wl1271_acx.h"
#include "wl1271_reg.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 67a82934f36..053c84aceb4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -25,6 +25,7 @@
#include <linux/platform_device.h>
#include <linux/crc7.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include "wl1271.h"
#include "wl12xx_80211.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
index 3919102e942..5c1c4f565fd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -22,6 +22,7 @@
*/
#include "wl1271_testmode.h"
+#include <linux/slab.h>
#include <net/genetlink.h>
#include "wl1271.h"
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 6917286edca..9d127787464 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 7ca95c414fa..b2af3c549bb 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include "zd_def.h"
#include "zd_chip.h"
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 2d555cc3050..16fa289ad77 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -22,6 +22,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/jiffies.h>
#include <net/ieee80211_radiotap.h>
@@ -350,7 +351,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
first_idx = info->status.rates[0].idx;
ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
retries = &zd_retry_rates[first_idx];
- ZD_ASSERT(0<=retry && retry<=retries->count);
+ ZD_ASSERT(1 <= retry && retry <= retries->count);
info->status.rates[0].idx = retries->rate[0];
info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1);
@@ -360,7 +361,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2);
}
for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) {
- info->status.rates[i].idx = retries->rate[retry-1];
+ info->status.rates[i].idx = retries->rate[retry - 1];
info->status.rates[i].count = 1; // (success ? 1:2);
}
if (i<IEEE80211_TX_MAX_RATES)
@@ -374,7 +375,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
* zd_mac_tx_failed - callback for failed frames
* @dev: the mac80211 wireless device
*
- * This function is called if a frame couldn't be successfully be
+ * This function is called if a frame couldn't be successfully
* transferred. The first frame from the tx queue, will be selected and
* reported as error to the upper layers.
*/
@@ -424,12 +425,10 @@ void zd_mac_tx_failed(struct urb *urb)
first_idx = info->status.rates[0].idx;
ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
retries = &zd_retry_rates[first_idx];
- if (retry < 0 || retry > retries->count) {
+ if (retry <= 0 || retry > retries->count)
continue;
- }
- ZD_ASSERT(0<=retry && retry<=retries->count);
- final_idx = retries->rate[retry-1];
+ final_idx = retries->rate[retry - 1];
final_rate = zd_rates[final_idx].hw_value;
if (final_rate != tx_status->rate) {
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
index 439799b8487..9e74eb1b67d 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
@@ -19,6 +19,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "zd_rf.h"
#include "zd_usb.h"
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 442fc111732..d91ad1a612a 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -24,6 +24,7 @@
#include <linux/firmware.h>
#include <linux/device.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/usb.h>
#include <linux/workqueue.h>
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index a869b45d3d3..d504e2b6025 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -40,6 +40,7 @@
#include <linux/udp.h>
#include <linux/moduleparam.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <xen/xen.h>
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 1a74594224b..1e783ccc306 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -19,6 +19,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
index 389ba9df712..fdba9cb3a59 100644
--- a/drivers/net/xtsonic.c
+++ b/drivers/net/xtsonic.c
@@ -20,11 +20,11 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fcntl.h>
+#include <linux/gfp.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
@@ -33,6 +33,7 @@
#include <linux/skbuff.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/pgtable.h>
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 7d4107f5eeb..ede5b2436f2 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -90,7 +90,6 @@ static int gx_fix;
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index def49d2ec69..dbfef8d70f2 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -88,6 +88,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index f5f75844954..b764ac22d52 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/page.h>
diff --git a/drivers/of/base.c b/drivers/of/base.c
index cb96888d142..b5ad9740d8b 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/proc_fs.h>
struct device_node *allnodes;
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 406757a9d7e..dee4fb56b09 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -376,8 +376,11 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
if (!np->type)
np->type = "<NULL>";
}
- while (tag == OF_DT_BEGIN_NODE) {
- mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+ while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) {
+ if (tag == OF_DT_NOP)
+ *p += 4;
+ else
+ mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
tag = be32_to_cpup((__be32 *)(*p));
}
if (tag != OF_DT_END_NODE) {
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index 24c3606217f..a1b31a4abae 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -15,6 +15,7 @@
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <linux/of_gpio.h>
#include <asm/prom.h>
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 18ecae4a437..b4748337223 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -69,7 +69,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
}
phy = get_phy_device(mdio, be32_to_cpup(addr));
- if (!phy) {
+ if (!phy || IS_ERR(phy)) {
dev_err(&mdio->dev, "error probing PHY at address %i\n",
*addr);
continue;
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index c9e2ae90f19..a9352b2c7ac 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -30,6 +30,7 @@
#include <linux/fs.h>
#include <linux/oprofile.h>
#include <linux/sched.h>
+#include <linux/gfp.h>
#include "oprofile_stats.h"
#include "event_buffer.h"
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 9ca21098b14..6a1ab2512a5 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/led.h>
diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
index 356b8357bcc..f78f6f1aef4 100644
--- a/drivers/parisc/ccio-rm-dma.c
+++ b/drivers/parisc/ccio-rm-dma.c
@@ -38,6 +38,7 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
index 0be1d50645a..caa15313375 100644
--- a/drivers/parisc/eisa_enumerator.c
+++ b/drivers/parisc/eisa_enumerator.c
@@ -460,7 +460,7 @@ static int init_slot(int slot, struct eeprom_eisa_slot_info *es)
slot, id_string);
print_eisa_id(id_string, es->eisa_slot_id);
- printk(" expected %s \n", id_string);
+ printk(" expected %s\n", id_string);
return -1;
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index c4e1f3c3c2f..20a1bce1a03 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -19,7 +19,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <asm/hardware.h>
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index 0bc5d474b16..1062b8ffe24 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -481,7 +481,7 @@ pdcspath_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static struct sysfs_ops pdcspath_attr_ops = {
+static const struct sysfs_ops pdcspath_attr_ops = {
.show = pdcspath_attr_show,
.store = pdcspath_attr_store,
};
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index a35c9c5b89e..f7806d81f1e 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -169,7 +169,7 @@ superio_init(struct pci_dev *pcidev)
/* ...then properly fixup the USB to point at suckyio PIC */
sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
- printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
+ printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)\n",
pci_name(pdev), pdev->irq);
pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog
deleted file mode 100644
index 8565bbbeb6e..00000000000
--- a/drivers/parport/ChangeLog
+++ /dev/null
@@ -1,583 +0,0 @@
-2001-10-11 Tim Waugh <twaugh@redhat.com>
- * parport_pc.c, parport_serial.c: Support for NetMos cards.
- + Patch originally from Michael Reinelt <reinelt@eunet.at>.
-
-2002-04-25 Tim Waugh <twaugh@redhat.com>
-
- * parport_serial.c, parport_pc.c: Move some SIIG cards around.
- Patch from Andrey Panin.
-
-2002-01-20 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_compat_write_block_pio,
- parport_pc_ecp_write_block_pio, parport_pc_ecp_read_block_pio):
- Use the default implementations if the caller wants to use
- O_NONBLOCK.
-
-2002-02-25 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Make sure that priv->ctr_writable includes IntEn
- even if IRQ is given as a parameter.
-
-2002-01-21 Tim Waugh <twaugh@redhat.com>
-
- * daisy.c: Apply patch from Max Vorobiev to make parport_daisy_select
- work for ECP/EPP modes.
-
-2002-01-13 Niels Kristian Bech Jensen <nkbj@image.dk>
-
- * parport_pc.c: Change some occurrences of frob_set_mode to
- ECR_WRITE. This fixes PLIP.
-
-2002-01-04 Tim Waugh <twaugh@redhat.com>
-
- * share.c (parport_claim_or_block): Sleep interruptibly to prevent
- a possible deadlock.
-
-2001-12-07 Damian Gruszka <damian.gruszka@VisionSystems.de>
-
- * parport_pc.c (ECR_WRITE): Define. If there are forbidden bits
- in the ECR register for some chips, this will be a useful place to
- put that knowledge.
- (change_mode): Use ECR_WRITE.
- (parport_pc_restore_state): Likewise.
- (parport_ECPPS2_supported): Likewise.
- (parport_ECPEPP_supported): Likewise.
- (irq_probe_EPP): Likewise.
- (programmable_irq_support): Likewise.
- (programmable_dma_support): Likewise.
- (parport_pc_probe_port): Likewise.
-
- (frob_set_mode): New function. Set the mode bits of the ECR.
- (get_fifo_residue): Use frob_set_mode.
- (parport_pc_ecpepp_read_data): Likewise.
- (parport_pc_ecpepp_write_data): Likewise.
- (parport_pc_ecpepp_read_addr): Likewise.
- (parport_pc_ecpepp_write_addr): Likewise.
- (parport_pc_compat_write_block_pio): Likewise.
- (parport_pc_ecp_write_block_pio): Likewise.
- (parport_ECR_present): Likewise.
- (parport_ECP_supported): Likewise.
- (parport_EPP_supported): Likewise.
- (parport_ECPEPP_supported): Likewise.
- (programmable_irq_support): Likewise.
- (irq_probe_ECP): Likewise.
- (programmable_dma_support): Likewise.
-
- (parport_pc_enable_irq): Only enable interrupts if we know which
- IRQ line they will come from.
- (parport_pc_init_state): Set nErrIntrEn at initialisation.
- (parport_pc_restore_state): Only write writable bits of CTR.
- (parport_irq_probe): If no IRQ is found, take ackIntEn out of the
- writable bit set.
-
-2001-12-07 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_fifo_write_block_pio): Correct typo.
- (parport_pc_init_state): Only set ackIntEn if we know which IRQ
- line the interrupts will come from.
-
-2001-12-07 Tim Waugh <twaugh@redhat.com>
-
- * ieee1284_ops.c (parport_ieee1284_epp_write_addr,
- parport_ieee1284_epp_read_addr): Actually do something useful.
-
-2001-12-07 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (dmaval): Don't use DMA by default. It seems to be
- too buggy at the moment. Use 'dma=auto' to restore the previous
- behaviour.
-
-2001-12-07 Tim Waugh <twaugh@redhat.com>
-
- * daisy.c (DEBUG): Undefine.
-
-2001-12-06 Tim Waugh <twaugh@redhat.com>
-
- * ieee1284_ops.c (parport_ieee1284_ecp_read_data): Mask off
- PARPORT_CONTROL_AUTOFD as well. Bug spotted by Joe
- <joeja@mindspring.com>.
-
-2001-12-03 Rich Liu <Rich.Liu@ite.com.tw>
-
- * parport_pc.c (sio_ite_8872_probe): ITE8873 is a single-port
- serial board, not a serial+parallel.
-
-2001-11-30 Niels Kristian Bech Jensen <nkbj@image.dk>
-
- * parport_pc.c: Fix compiler warning.
-
-2001-11-14 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_pci_probe): Hooks for PCI cards before
- and after probing for ports.
- * parport_serial.c (parport_register): Likewise.
-
-2001-11-12 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (init_module): Warn when parameters are ignored.
-
-2001-11-01 Damian Gruszka <damian.gruszka@VisionSystems.de>
-
- * parport_serial.c (serial_register): Set base_baud before
- calling register_serial.
-
-2001-10-26 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_irq_probe): When ECR programmable IRQ
- support fails, generate interrupts using the FIFO even if we don't
- want to use the FIFO for real data transfers.
- (parport_pc_probe_port): Display the ECR address if we have an
- ECR, not just if we will use the FIFO.
-
-2001-10-24 Dave Strauss <D.Strauss@motorola.com>
-
- * parport_pc.c (parport_pc_compat_write_block_pio,
- parport_pc_ecp_write_block_pio): Allow a few seconds for an ECP
- transfer to finish up.
-
-2001-10-11 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc (sio_ite_8872_probe): New function, submitted by Rich
- Liu from ITE. Cleaned up, removed bogus phys_to_virt calls.
-
-2001-10-24 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Support for AKS AladdinCARD. Patch from
- Aladdin Knowledge Systems (Christian Groessler).
-
-2001-10-24 Tim Waugh <twaugh@redhat.com>
-
- * ieee1284_ops.c (parport_ieee1284_ecp_read_data): Try to minimise
- turnaround time.
-
- * ieee1284.c (parport_poll_peripheral): Try a couple of times
- first without delaying.
-
-2001-10-10 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Support for OX16PCI954 PCI card.
-
-2001-10-10 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Support for OX12PCI840 PCI card (reported by
- mk@daveg.com). Lock-ups diagnosed by Ronnie Arosa (and now we
- just don't trust its ECR).
-
-2001-10-10 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
-
- * parport_pc.c: Support for AVLAB cards.
-
-2001-10-10 Tim Waugh <twaugh@redhat.com>
-
- * ieee1284_ops.c (ecp_forward_to_reverse, ecp_reverse_to_forward):
- Remember to retry direction switch if it fails. Patch from David
- Lambert.
-
-2001-10-08 David C. Hansen <haveblue@us.ibm.com>
-
- * share.c: Make driverlist_lock and parportlist_lock static.
-
-2001-10-08 Philip Blundell <philb@gnu.org>
-
- * parport_pc.c: New modular parameter verbose_logging.
- Make port->modes indicate the modes that we are prepared to use,
- rather than the modes that are available.
-
-2001-10-07 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_probe_port): Fix memory leak spotted by
- Kipp Cannon.
-
-2001-10-07 Tim Waugh <twaugh@redhat.com>
-
- * parport_serial.c: Remove NetMos support, since it causes problems
- for some people.
-
-2001-08-30 Tim Waugh <twaugh@redhat.com>
-
- * parport_serial.c (parport_serial_pci_probe): Clean-up on partial
- registration failure.
-
-2001-08-14 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_init_superio): Allow for more than one
- SuperIO device. Patch from Rich Lio (ITE).
-
-2001-08-11 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Support for Titan Electronics cards.
-
-2001-08-08 Tim Waugh <twaugh@redhat.com>
-
- * share.c (parport_unregister_device): Remove device from wait list
- too.
-
-2001-06-20 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Make 'io_hi=0' work.
-
-2001-05-31 Tim Waugh <twaugh@redhat.com>
-
- * parport_serial.c: New file.
-
-2001-06-05 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_unregister_port): New exported function.
- Do the opposite of parport_pc_probe_port.
- (cleanup_module): Use it.
-
-2001-05-22 Juan Quintela <quintela@mandrakesoft.com>
-
- * parport_amiga.c: Set printk levels.
- * parport_gsc.c: Likewise.
- * parport_mfc3.c: Likewise.
- * parport_pc.c: Likewise.
- * parport_sunbpp.c: Likewise.
- * probe.c: Likewise.
- * share.c: Likewise.
-
-2001-05-10 Fred Barnes <frmb2@ukc.ac.uk>
-
- * parport_pc.c (parport_pc_epp_read_data): added support for
- reading from a w91284pic peripheral, flag is PARPORT_W91284PIC.
-
-2001-05-07 Fred Barnes <frmb2@ukc.ac.uk>
-
- * parport_pc.c (parport_pc_epp_read_data,
- parport_pc_epp_write_data, parport_pc_epp_read_addr,
- parport_pc_epp_write_addr): support for fast reads/writes using
- the PARPORT_EPP_FAST flag.
-
- * ieee1284.c (parport_read, parport_write): added code to handle
- software EPP mode (IEEE1284_MODE_EPPSWE). Added code to allow
- BYTE mode reverse transfers (previously always went for NIBBLE
- mode).
-
- * ieee1284_ops.c (parport_ieee1284_epp_read_data,
- parport_ieee1284_epp_write_data): fixed various polarity problems.
- Also (theoretically) fixed address versions (.._addr), but no
- hardware to test this on.
-
- * parport_pc.h: added parport_dump_state() function for debugging.
- Needs to have DEBUG_PARPORT to be defined for it to be included.
-
-2001-05-03 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Fix the compile problem I introduce from the last
- change.
-
-2001-04-20 Paul Gortmaker <p_gortmaker@yahoo.com>
-
- * parport_pc.c: Cut down the size quite a bit (more than 4k off
- the object, about 1k off the zImage) for the older non-PCI
- machines which are typically resource starved anyway...
-
-2001-03-26 R Horn <rjh@world.std.com>
-
- * parport_pc.c: Some commentary changes.
-
-2001-04-19 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_probe_port): Remove __devinit
- attribute. Export unconditionally.
-
-2001-04-14 Jeff Garzik <jgarzik@pobox.com>
-
- Merged: 2001-03-30 Tim Waugh <twaugh@redhat.com>
-
- * drivers/parport/parport_pc.c: Make Via SuperIO chipsets behave
- like everything else with respect to irq= and dma= parameters.
-
-2001-04-08 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_save_state): Read from the soft copy of
- the control port.
- (parport_pc_restore_state): Update the soft copy of the control
- port.
-
-2001-03-26 Tim Waugh <twaugh@redhat.com>
-
- * share.c (parport_find_number, parport_find_base): Trigger
- a lowlevel driver load if there are no ports yet.
-
-2001-03-26 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_ECP_supported): Remove the IRQ conflict
- check since it seems totally unreliable.
-
-2001-03-02 Tim Waugh <twaugh@redhat.com>
-
- * ieee1284_ops.c (parport_ieee1284_read_nibble): Reset nAutoFd
- on timeout. Matches 2.2.x behaviour.
-
-2001-03-02 Andrew Morton
-
- * parport_pc.c (registered_parport): New static variable.
- (parport_pc_find_ports): Set it when we register PCI driver.
- (init_module): Unregister PCI driver if necessary when we
- fail.
-
-2001-03-02 Tim Waugh <twaugh@redhat.com>
-
- * ieee1284_ops.c (parport_ieee1284_write_compat): Don't use
- down_trylock to reset the IRQ count. Don't even use sema_init,
- because it's not even necessary to reset the count. I can't
- remember why we ever did.
-
-2001-01-04 Peter Osterlund <peter.osterlund@mailbox.swipnet.se>
-
- * ieee1284.c (parport_negotiate): Fix missing printk argument.
-
-2001-01-03 Paul Schleger <Paul.Schleger@t-online.de>
-
- * probe.c (parse_data): Get rid of trailing blanks in values.
- Needed for XEROX XJ8C printer.
-
-2001-01-03 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_probe_port): Say something when probes
- are omitted.
-
-2001-01-03 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (sio_via_686a_probe): Correct dma=255 fix.
-
-2000-11-21 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_ecp_write_block_pio): Fix
- reverse-to-forward logic. Spotted by Roland Kuck
- <rci@cityweb.de>.
-
-2000-09-16 Cesar Eduardo Barros <cesarb@nitnet.com.br>
-
- * parport_pc.c (sio_via_686a_probe): Handle case
- where hardware returns 255 for IRQ or DMA.
-
-2000-07-20 Eddie C. Dost <ecd@skynet.be>
-
- * share.c (attach_driver_chain): attach[i](port) needs to be
- replaced by attach[count](port).
-
-2000-07-20 Eddie C. Dost <ecd@skynet.be>
-
- * daisy.c (add_dev): kmalloc args are in wrong order.
-
-2000-07-12 Tim Waugh <twaugh@redhat.com>
-
- * share.c: Documentation for parport_{get,port}_port,
- parport_find_{number,base}.
-
-2000-07-12 Tim Waugh <twaugh@redhat.com>
-
- * share.c (parport_unregister_device): Remove unneeded locking
- (test cad==dev).
- (parport_claim): Likewise.
- (parport_find_number): New function.
-
-2000-07-12 Tim Waugh <twaugh@redhat.com>
-
- * share.c (parport_register_port): Hold the parportlist_lock while
- looking for a free parport number.
- (parport_register_driver): Make sure that attach can block.
- (attach_driver_chain): Likewise.
-
-2000-07-12 Tim Waugh <twaugh@redhat.com>
-
- * share.c (call_driver_chain): Do reference counting things.
- (parport_get_port): New function.
- (parport_put_port): New function.
- (parport_register_port): Initialise reference count to zero.
- (parport_unregister_port): Check reference count rather than
- driver list to see if we can free the port.
-
-2000-07-12 Tim Waugh <twaugh@redhat.com>
-
- * share.c: Clarifications in doc comments.
-
-2000-07-12 Tim Waugh <twaugh@redhat.com>
-
- * share.c (parport_unregister_port): Fix typo in comment.
-
-2000-07-11 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
-
- * parport_pc.c: Support for the full range of Timedia cards.
-
-2000-07-08 Tim Waugh <twaugh@redhat.com>
-
- * daisy.c: License block comments as part of parportbook.
- * ieee1284.c: Likewise.
- * share.c: Likewise.
-
-2000-06-30 Petr Vandrovec <vandrove@vc.cvut.cz>
-
- * procfs.c (do_hardware_modes): Generated string can be up to 34
- chars long.
-
-2000-06-20 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
-
- * parport_pc.c (parport_pc_compat_write_block_pio): Warn about
- change_mode failures.
- (parport_pc_ecp_write_block_pio): Likewise.
- (parport_pc_ecp_read_block_pio): Likewise.
-
-2000-06-20 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
-
- * parport_pc.c (parport_SPP_supported): Warn more about possibly
- incorrect parameters.
-
-2000-06-15 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_ECP_supported): Set PARPORT_MODE_COMPAT
- for ECP ports, since they can all do hardware accelerated
- compatibility mode (I assume).
-
-2000-06-13 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (cleanup_module): Remark about possible bugs.
-
-2000-06-13 Tim Waugh <twaugh@redhat.com>
-
- * procfs.c: Break 'hardware' out into separate files.
-
-2000-05-28 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
-
- * Fix PCI ID printk for non-superio PCI cards.
-
-2000-05-28 Tim Waugh <twaugh@redhat.com>
-
- * share.c (call_driver_chain): Get the driverlist_lock.
- (parport_register_device): Make sure that port->devices always
- looks consistent.
- (parport_register_driver): Ensure that parport drivers are given
- parameters that are valid for the duration of the callback by
- locking the portlist against changes.
- (parport_unregister_driver): Likewise.
- (parport_claim): Don't overwrite flags.
-
-2000-05-28 Tim Waugh <twaugh@redhat.com>
-
- * daisy.c (assign_addrs): Avoid double-probing daisy-chain devices
- if the first probe succeeds.
-
-2000-05-16 Tim Waugh <twaugh@redhat.com>
-
- * share.c (parport_claim): Fix SMP race.
-
-2000-05-15 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
-
- * parport_pc.c (parport_pc_compat_write_block_pio): Check for
- timeouts.
- (parport_pc_ecp_write_block_pio): Likewise.
- (parport_pc_ecp_read_block_pio): Likewise.
-
-2000-05-02 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
-
- * parport_pc.c: PCI SYBA patch and verbose PCI detection.
-
-2000-05-02 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
-
- * parport_pc.c (decode_smsc): Fix SMSC 665/666 identification.
-
-2000-04-28 Tim Waugh <twaugh@redhat.com>
-
- * ieee1284.c: Short function descriptions can't be multiline.
-
- * daisy.c: Short function descriptions can't be multiline.
-
-2000-04-19 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_fifo_write_block_dma): Make maxlen
- calculation a bit clearer.
-
- * ieee1284.c (parport_negotiate): Turn on data line drivers.
-
- * ieee1284_ops.c (parport_ieee1284_read_byte): Turn off data line
- drivers.
- (parport_ieee1284_write_compat): Turn on data line drivers.
-
- * daisy.c (assign_addrs): Turn on data line drivers.
- (cpp_mux): Likewise.
- (cpp_daisy): Likewise.
-
-2000-04-04 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Add support for another PCI card.
-
-2000-04-04 Tim Waugh <twaugh@redhat.com>
-
- * daisy.c: Documentation in kernel-doc format.
-
- * ieee1284.c: Likewise.
-
- * share.c: Likewise.
-
-2000-04-01 Tim Waugh <twaugh@redhat.com>
-
- * share.c (parport_register_device): Need to hold the module
- reference counts before sleeping.
-
-2000-03-27 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_ecp_read_block_pio): Correct operation
- when peripheral is trying to send data when we stop listening.
-
-2000-03-22 Tim Waugh <twaugh@redhat.com>
-
- * init.c (parport_setup): Fix return value.
-
-2000-03-21 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_pci_probe): Fix return value; call
- pci_enable_device.
-
-2000-03-16 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_ECP_supported): This seems to trigger on
- machines that don't have an IRQ conflict; toned down the warning
- message accordingly.
-
-2000-03-16 Gunther Mayer <gunther.mayer@braunschweig.netsurf.de>
-
- * parport_pc.c (show_parconfig_smsc37c669): Fix typo.
- (decode_winbond): More IDs.
- (winbond_check): Protect against false positives.
- (winbond_check2): Likewise.
- (smsc_check): Likewise.
-
-2000-03-15 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (cleanup_module): Don't call pci_unregister_driver
- if we didn't call pci_register_driver first.
-
-2000-03-13 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (parport_pc_init): Moved from asm/parport.h.
-
- * Config.in: CONFIG_PARPORT_PC_SUPERIO: new option.
-
- * parport_pc.c (show_parconfig_smsc37c669): Make __devinit.
- (show_parconfig_winbond): Likewise.
- (decode_winbond): Likewise.
- (decode_smsc): Likewise.
- (winbond_check): Likewise.
- (winbond_check2): Likewise.
- (smsc_check): Likewise.
- (detect_and_report_winbond): Likewise.
- (detect_and_report_smsc): Likewise.
- (get_superio_dma): Likewise.
- (get_superio_irq): Likewise.
- (parport_pc_find_isa_ports): New function.
- (parport_pc_find_ports): New function.
- (init_module): Make superio a config option, not a parameter.
-
-2000-03-10 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c (decode_winbond): Use correct 83877ATF chip ID.
- (decode_winbond): Fix typo.
-
-2000-03-09 Tim Waugh <twaugh@redhat.com>
-
- * parport_pc.c: Integrate SuperIO PCI probe with normal PCI card
- probe, so that the MODULE_DEVICE_TABLE is complete.
-
diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c
index 3c8f06c3a5a..5bed17f68ef 100644
--- a/drivers/parport/daisy.c
+++ b/drivers/parport/daisy.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/parport.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <asm/current.h>
diff --git a/drivers/parport/parport_ax88796.c b/drivers/parport/parport_ax88796.c
index 6938d2e9f18..2c5ac2bf5c5 100644
--- a/drivers/parport/parport_ax88796.c
+++ b/drivers/parport/parport_ax88796.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c
index 6d58bf895b1..d3d7809af8b 100644
--- a/drivers/parport/parport_ip32.c
+++ b/drivers/parport/parport_ip32.c
@@ -103,6 +103,7 @@
#include <linux/module.h>
#include <linux/parport.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/types.h>
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index c3bb84ac931..40e208d130f 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/parport.h>
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index 0f6550719bc..d763bc9e44c 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -9,6 +9,7 @@
#include <linux/parport.h>
#include <linux/ctype.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
static const struct {
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 3d102dd87c9..0b51857fbaf 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o
obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
obj-$(CONFIG_X86_VISWS) += setup-irq.o
obj-$(CONFIG_MN10300) += setup-bus.o
+obj-$(CONFIG_MICROBLAZE) += setup-bus.o
#
# ACPI Related PCI FW Functions
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index db23200c487..2f646fe1260 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -2,6 +2,7 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/wait.h>
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 712250f5874..628ea20a884 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -14,6 +14,7 @@
#include <linux/ioport.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include "pci.h"
@@ -288,9 +289,9 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
next = dev->bus_list.next;
/* Run device routines with the device locked */
- down(&dev->dev.sem);
+ device_lock(&dev->dev);
retval = cb(dev, userdata);
- up(&dev->dev.sem);
+ device_unlock(&dev->dev);
if (retval)
break;
}
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 83aae474759..33ead97f0c4 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -35,6 +35,7 @@
#include <linux/interrupt.h>
#include <linux/tboot.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#define PREFIX "DMAR: "
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 3c76fc67cf0..45fcc1e96df 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -32,6 +32,7 @@
#include <linux/pci_hotplug.h>
#include <linux/acpi.h>
#include <linux/pci-acpi.h>
+#include <linux/slab.h>
#define MY_NAME "acpi_pcihp"
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index cb2fd01edda..cb23aa2ebf9 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -47,6 +47,7 @@
#include <linux/pci_hotplug.h>
#include <linux/pci-acpi.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include "../pci.h"
#include "acpiphp.h"
@@ -749,6 +750,24 @@ static int acpiphp_bus_trim(acpi_handle handle)
return retval;
}
+static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
+{
+ struct acpiphp_func *func;
+ union acpi_object params[2];
+ struct acpi_object_list arg_list;
+
+ list_for_each_entry(func, &slot->funcs, sibling) {
+ arg_list.count = 2;
+ arg_list.pointer = params;
+ params[0].type = ACPI_TYPE_INTEGER;
+ params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG;
+ params[1].type = ACPI_TYPE_INTEGER;
+ params[1].integer.value = 1;
+ /* _REG is optional, we don't care about if there is failure */
+ acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL);
+ }
+}
+
/**
* enable_device - enable, configure a slot
* @slot: slot to be enabled
@@ -805,6 +824,7 @@ static int __ref enable_device(struct acpiphp_slot *slot)
pci_bus_assign_resources(bus);
acpiphp_sanitize_bus(bus);
acpiphp_set_hpp_values(bus);
+ acpiphp_set_acpi_region(slot);
pci_enable_bridges(bus);
pci_bus_add_devices(bus);
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index aa5df485f8c..6ecbfb27db9 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -26,6 +26,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <acpi/acpi_bus.h>
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index e6089bdb6e5..56215322930 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index 6151389fd90..5317e4d7d96 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include "../pci.h"
struct legacy_slot {
@@ -73,7 +74,7 @@ static void legacy_release(struct kobject *kobj)
}
static struct kobj_type legacy_ktype = {
- .sysfs_ops = &(struct sysfs_ops){
+ .sysfs_ops = &(const struct sysfs_ops){
.store = legacy_store, .show = legacy_show
},
.release = &legacy_release,
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 728b119f71a..6d2eea93298 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -33,7 +33,6 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/pagemap.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/namei.h>
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index b09b083011d..1f4000a5a10 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -26,6 +26,7 @@
#include <linux/acpi.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
+#include <linux/slab.h>
#include "pciehp.h"
#define PCIEHP_DETECT_PCIE (0)
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 920f820edf8..3588ea61b0d 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/pci.h>
#include "pciehp.h"
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 9a7f247e8ac..8f58148be04 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/workqueue.h>
#include "../pci.h"
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 40b48f569b1..0cd42047d89 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -36,6 +36,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/time.h>
+#include <linux/slab.h>
#include "../pci.h"
#include "pciehp.h"
@@ -832,9 +833,8 @@ static inline void dbg_ctrl(struct controller *ctrl)
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
if (!pci_resource_len(pdev, i))
continue;
- ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n",
- i, (unsigned long long)pci_resource_len(pdev, i),
- (unsigned long long)pci_resource_start(pdev, i));
+ ctrl_info(ctrl, " PCI resource [%d] : %pR\n",
+ i, &pdev->resource[i]);
}
ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap);
ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl));
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index 4e3e0382c16..083034710fa 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/string.h>
+#include <linux/vmalloc.h>
#include <asm/pci-bridge.h>
#include <linux/mutex.h>
@@ -430,6 +431,8 @@ int dlpar_remove_slot(char *drc_name)
rc = dlpar_remove_pci_slot(drc_name, dn);
break;
}
+ vm_unmap_aliases();
+
printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
exit:
mutex_unlock(&rpadlpar_mutex);
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index dcaae725fd7..ef7411c660b 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -27,9 +27,9 @@
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
-#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/init.h>
+#include <linux/vmalloc.h>
#include <asm/eeh.h> /* for eeh_add_device() */
#include <asm/rtas.h> /* rtas_call */
#include <asm/pci-bridge.h> /* for pci_controller */
@@ -419,6 +419,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
return -EINVAL;
pcibios_remove_pci_devices(slot->bus);
+ vm_unmap_aliases();
+
slot->state = NOT_CONFIGURED;
return 0;
}
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 8aebe1e9d3d..72d507b6a2a 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -15,6 +15,7 @@
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/mutex.h>
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index a5062297f48..a7bd5048396 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -31,6 +31,7 @@
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/workqueue.h>
#include "shpchp.h"
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 3bba0c0888f..3387fbfb0c5 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/workqueue.h>
#include "../pci.h"
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 737a1c44b07..98abf8b9129 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -10,7 +10,6 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
-#include <linux/gfp.h>
#include <linux/htirq.h>
/* Global ht irq lock.
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 95b849130ad..6ee98a56946 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -1,6 +1,7 @@
#include <linux/interrupt.h>
#include <linux/dmar.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/hpet.h>
#include <linux/pci.h>
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c
index 3e0d7b5dd1b..203508b227b 100644
--- a/drivers/pci/ioapic.c
+++ b/drivers/pci/ioapic.c
@@ -18,6 +18,7 @@
#include <linux/pci.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#include <acpi/acpi_bus.h>
struct ioapic {
@@ -31,9 +32,9 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
acpi_status status;
unsigned long long gsb;
struct ioapic *ioapic;
- u64 addr;
int ret;
char *type;
+ struct resource *res;
handle = DEVICE_ACPI_HANDLE(&dev->dev);
if (!handle)
@@ -69,13 +70,12 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
if (pci_request_region(dev, 0, type))
goto exit_disable;
- addr = pci_resource_start(dev, 0);
- if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base))
+ res = &dev->resource[0];
+ if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base))
goto exit_release;
pci_set_drvdata(dev, ioapic);
- dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr,
- ioapic->gsi_base);
+ dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base);
return 0;
exit_release:
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 3e5ab2bf6a5..ce6a3666b3d 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -9,6 +9,7 @@
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/delay.h>
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f9cf3173b23..77b68eaf021 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -18,6 +18,7 @@
#include <linux/smp.h>
#include <linux/errno.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include "pci.h"
#include "msi.h"
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 807224ec835..fad93983bfe 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -23,6 +23,7 @@
#include <linux/mm.h>
#include <linux/capability.h>
#include <linux/pci-aspm.h>
+#include <linux/slab.h>
#include "pci.h"
static int sysfs_initialized; /* = 0 */
@@ -642,6 +643,7 @@ void pci_create_legacy_files(struct pci_bus *b)
if (!b->legacy_io)
goto kzalloc_err;
+ sysfs_bin_attr_init(b->legacy_io);
b->legacy_io->attr.name = "legacy_io";
b->legacy_io->size = 0xffff;
b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
@@ -655,6 +657,7 @@ void pci_create_legacy_files(struct pci_bus *b)
/* Allocated above after the legacy_io struct */
b->legacy_mem = b->legacy_io + 1;
+ sysfs_bin_attr_init(b->legacy_mem);
b->legacy_mem->attr.name = "legacy_mem";
b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
@@ -800,6 +803,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
if (res_attr) {
char *res_attr_name = (char *)(res_attr + 1);
+ sysfs_bin_attr_init(res_attr);
if (write_combine) {
pdev->res_attr_wc[num] = res_attr;
sprintf(res_attr_name, "resource%d_wc", num);
@@ -972,6 +976,7 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev)
if (!attr)
return -ENOMEM;
+ sysfs_bin_attr_init(attr);
attr->size = dev->vpd->len;
attr->attr.name = "vpd";
attr->attr.mode = S_IRUSR | S_IWUSR;
@@ -1038,6 +1043,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
retval = -ENOMEM;
goto err_resource_files;
}
+ sysfs_bin_attr_init(attr);
attr->size = rom_size;
attr->attr.name = "rom";
attr->attr.mode = S_IRUSR;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5b548aee9cb..37499127c80 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pm.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/string.h>
@@ -303,6 +304,49 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
}
EXPORT_SYMBOL_GPL(pci_find_ext_capability);
+/**
+ * pci_bus_find_ext_capability - find an extended capability
+ * @bus: the PCI bus to query
+ * @devfn: PCI device to query
+ * @cap: capability code
+ *
+ * Like pci_find_ext_capability() but works for pci devices that do not have a
+ * pci_dev structure set up yet.
+ *
+ * Returns the address of the requested capability structure within the
+ * device's PCI configuration space or 0 in case the device does not
+ * support it.
+ */
+int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn,
+ int cap)
+{
+ u32 header;
+ int ttl;
+ int pos = PCI_CFG_SPACE_SIZE;
+
+ /* minimum 8 bytes per capability */
+ ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+ if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
+ return 0;
+ if (header == 0xffffffff || header == 0)
+ return 0;
+
+ while (ttl-- > 0) {
+ if (PCI_EXT_CAP_ID(header) == cap)
+ return pos;
+
+ pos = PCI_EXT_CAP_NEXT(header);
+ if (pos < PCI_CFG_SPACE_SIZE)
+ break;
+
+ if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
+ break;
+ }
+
+ return 0;
+}
+
static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
{
int rc, ttl = PCI_FIND_CAP_TTL;
@@ -635,7 +679,7 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state)
*/
int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
{
- return state > PCI_D0 ?
+ return state >= PCI_D0 ?
pci_platform_power_transition(dev, state) : -EINVAL;
}
EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
@@ -672,10 +716,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
*/
return 0;
- /* Check if we're already there */
- if (dev->current_state == state)
- return 0;
-
__pci_start_power_transition(dev, state);
/* This device is quirked not to be put into D3, so
@@ -1540,8 +1580,10 @@ void pci_pm_init(struct pci_dev *dev)
int pm;
u16 pmc;
+ pm_runtime_forbid(&dev->dev);
device_enable_async_suspend(&dev->dev);
dev->wakeup_prepared = false;
+
dev->pm_cap = 0;
/* find PCI PM capability in list */
@@ -2253,35 +2295,6 @@ void pci_msi_off(struct pci_dev *dev)
}
}
-#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
-/*
- * These can be overridden by arch-specific implementations
- */
-int
-pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (!pci_dma_supported(dev, mask))
- return -EIO;
-
- dev->dma_mask = mask;
- dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask));
-
- return 0;
-}
-
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (!pci_dma_supported(dev, mask))
- return -EIO;
-
- dev->dev.coherent_dma_mask = mask;
- dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask));
-
- return 0;
-}
-#endif
-
#ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE
int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
{
@@ -2443,7 +2456,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
if (!probe) {
pci_block_user_cfg_access(dev);
/* block PM suspend, driver probe, etc. */
- down(&dev->dev.sem);
+ device_lock(&dev->dev);
}
rc = pci_dev_specific_reset(dev, probe);
@@ -2465,7 +2478,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
rc = pci_parent_bus_reset(dev, probe);
done:
if (!probe) {
- up(&dev->dev.sem);
+ device_unlock(&dev->dev);
pci_unblock_user_cfg_access(dev);
}
@@ -2560,18 +2573,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function);
*/
int pcix_get_max_mmrbc(struct pci_dev *dev)
{
- int err, cap;
+ int cap;
u32 stat;
cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!cap)
return -EINVAL;
- err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
- if (err)
+ if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
return -EINVAL;
- return (stat & PCI_X_STATUS_MAX_READ) >> 12;
+ return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21);
}
EXPORT_SYMBOL(pcix_get_max_mmrbc);
@@ -2584,18 +2596,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc);
*/
int pcix_get_mmrbc(struct pci_dev *dev)
{
- int ret, cap;
- u32 cmd;
+ int cap;
+ u16 cmd;
cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!cap)
return -EINVAL;
- ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
- if (!ret)
- ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
+ if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
+ return -EINVAL;
- return ret;
+ return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
}
EXPORT_SYMBOL(pcix_get_mmrbc);
@@ -2610,28 +2621,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc);
*/
int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
{
- int cap, err = -EINVAL;
- u32 stat, cmd, v, o;
+ int cap;
+ u32 stat, v, o;
+ u16 cmd;
if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc))
- goto out;
+ return -EINVAL;
v = ffs(mmrbc) - 10;
cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!cap)
- goto out;
+ return -EINVAL;
- err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
- if (err)
- goto out;
+ if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
+ return -EINVAL;
if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
return -E2BIG;
- err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
- if (err)
- goto out;
+ if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
+ return -EINVAL;
o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
if (o != v) {
@@ -2641,10 +2651,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
cmd &= ~PCI_X_CMD_MAX_READ;
cmd |= v << 2;
- err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd);
+ if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd))
+ return -EIO;
}
-out:
- return err;
+ return 0;
}
EXPORT_SYMBOL(pcix_set_mmrbc);
@@ -3007,7 +3017,6 @@ EXPORT_SYMBOL(pcim_pin_device);
EXPORT_SYMBOL(pci_disable_device);
EXPORT_SYMBOL(pci_find_capability);
EXPORT_SYMBOL(pci_bus_find_capability);
-EXPORT_SYMBOL(pci_register_set_vga_state);
EXPORT_SYMBOL(pci_release_regions);
EXPORT_SYMBOL(pci_request_regions);
EXPORT_SYMBOL(pci_request_regions_exclusive);
@@ -3023,8 +3032,6 @@ EXPORT_SYMBOL(pci_set_mwi);
EXPORT_SYMBOL(pci_try_set_mwi);
EXPORT_SYMBOL(pci_clear_mwi);
EXPORT_SYMBOL_GPL(pci_intx);
-EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_set_consistent_dma_mask);
EXPORT_SYMBOL(pci_assign_resource);
EXPORT_SYMBOL(pci_find_parent_resource);
EXPORT_SYMBOL(pci_select_bars);
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 223052b7356..f8f425b8731 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/stddef.h>
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 21f215f4daa..7a711ee314b 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/pcieport_if.h>
+#include <linux/slab.h>
#include "aerdrv.h"
#include "../../pci.h"
@@ -243,11 +244,17 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
/* Assert Secondary Bus Reset */
pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl);
- p2p_ctrl |= PCI_CB_BRIDGE_CTL_CB_RESET;
+ p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
+ /*
+ * we should send hot reset message for 2ms to allow it time to
+ * propogate to all downstream ports
+ */
+ msleep(2);
+
/* De-assert Secondary Bus Reset */
- p2p_ctrl &= ~PCI_CB_BRIDGE_CTL_CB_RESET;
+ p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
/*
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index c843a799814..aceb04b67b6 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -23,6 +23,7 @@
#include <linux/pm.h>
#include <linux/suspend.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "aerdrv.h"
static int forceload;
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c
index 7b3cbff547e..aac285a16b6 100644
--- a/drivers/pci/pcie/pme/pcie_pme.c
+++ b/drivers/pci/pcie/pme/pcie_pme.c
@@ -14,6 +14,7 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/device.h>
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 127e8f169d9..3debed25e46 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -12,7 +12,6 @@
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/pcieport_if.h>
#include <linux/aer.h>
#include <linux/dmi.h>
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2a943090a3b..c82548afcd5 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -312,7 +312,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
- " bridge window [io %04lx - %04lx] reg reading\n",
+ " bridge window [io %#06lx-%#06lx] (disabled)\n",
base, limit);
}
}
@@ -336,7 +336,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
- " bridge window [mem 0x%08lx - 0x%08lx] reg reading\n",
+ " bridge window [mem %#010lx-%#010lx] (disabled)\n",
base, limit + 0xfffff);
}
}
@@ -387,7 +387,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
} else {
dev_printk(KERN_DEBUG, &dev->dev,
- " bridge window [mem 0x%08lx - %08lx pref] reg reading\n",
+ " bridge window [mem %#010lx-%#010lx pref] (disabled)\n",
base, limit + 0xfffff);
}
}
@@ -673,16 +673,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
u32 buses, i, j = 0;
u16 bctl;
+ u8 primary, secondary, subordinate;
int broken = 0;
pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
+ primary = buses & 0xFF;
+ secondary = (buses >> 8) & 0xFF;
+ subordinate = (buses >> 16) & 0xFF;
- dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n",
- buses & 0xffffff, pass);
+ dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
+ secondary, subordinate, pass);
/* Check if setup is sensible at all */
if (!pass &&
- ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) {
+ (primary != bus->number || secondary <= bus->number)) {
dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
broken = 1;
}
@@ -693,15 +697,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
- if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) {
- unsigned int cmax, busnr;
+ if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
+ !is_cardbus && !broken) {
+ unsigned int cmax;
/*
* Bus already configured by firmware, process it in the first
* pass and just note the configuration.
*/
if (pass)
goto out;
- busnr = (buses >> 8) & 0xFF;
/*
* If we already got to this bus through a different bridge,
@@ -710,13 +714,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
* However, we continue to descend down the hierarchy and
* scan remaining child buses.
*/
- child = pci_find_bus(pci_domain_nr(bus), busnr);
+ child = pci_find_bus(pci_domain_nr(bus), secondary);
if (!child) {
- child = pci_add_new_bus(bus, dev, busnr);
+ child = pci_add_new_bus(bus, dev, secondary);
if (!child)
goto out;
- child->primary = buses & 0xFF;
- child->subordinate = (buses >> 16) & 0xFF;
+ child->primary = primary;
+ child->subordinate = subordinate;
child->bridge_ctl = bctl;
}
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 593bb844b8d..449e890267a 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -6,6 +6,7 @@
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 039e87b7144..27c0e6eb713 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -368,8 +368,9 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
bus_region.end = res->end;
pcibios_bus_to_resource(dev, res, &bus_region);
- pci_claim_resource(dev, nr);
- dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name);
+ if (pci_claim_resource(dev, nr) == 0)
+ dev_info(&dev->dev, "quirk: %pR claimed by %s\n",
+ res, name);
}
}
@@ -1977,11 +1978,25 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
/*
* Disable PCI Bus Parking and PCI Master read caching on CX700
* which causes unspecified timing errors with a VT6212L on the PCI
- * bus leading to USB2.0 packet loss. The defaults are that these
- * features are turned off but some BIOSes turn them on.
+ * bus leading to USB2.0 packet loss.
+ *
+ * This quirk is only enabled if a second (on the external PCI bus)
+ * VT6212L is found -- the CX700 core itself also contains a USB
+ * host controller with the same PCI ID as the VT6212L.
*/
+ /* Count VT6212L instances */
+ struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_8235_USB_2, NULL);
uint8_t b;
+
+ /* p should contain the first (internal) VT6212L -- see if we have
+ an external one by searching again */
+ p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p);
+ if (!p)
+ return;
+ pci_dev_put(p);
+
if (pci_read_config_byte(dev, 0x76, &b) == 0) {
if (b & 0x40) {
/* Turn off PCI Bus Parking */
@@ -2008,7 +2023,7 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
}
}
}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching);
/*
* For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the
@@ -2108,6 +2123,10 @@ 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);
/* Go through the list of Hypertransport capabilities and
* return 1 if a HT MSI capability is found and enabled */
@@ -2533,6 +2552,91 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov);
#endif /* CONFIG_PCI_IOV */
+/*
+ * This is a quirk for the Ricoh MMC controller found as a part of
+ * some mulifunction chips.
+
+ * This is very similiar and based on the ricoh_mmc driver written by
+ * Philip Langdale. Thank you for these magic sequences.
+ *
+ * These chips implement the four main memory card controllers (SD, MMC, MS, xD)
+ * and one or both of cardbus or firewire.
+ *
+ * It happens that they implement SD and MMC
+ * support as separate controllers (and PCI functions). The linux SDHCI
+ * driver supports MMC cards but the chip detects MMC cards in hardware
+ * and directs them to the MMC controller - so the SDHCI driver never sees
+ * them.
+ *
+ * To get around this, we must disable the useless MMC controller.
+ * At that point, the SDHCI controller will start seeing them
+ * It seems to be the case that the relevant PCI registers to deactivate the
+ * MMC controller live on PCI function 0, which might be the cardbus controller
+ * or the firewire controller, depending on the particular chip in question
+ *
+ * This has to be done early, because as soon as we disable the MMC controller
+ * other pci functions shift up one level, e.g. function #2 becomes function
+ * #1, and this will confuse the pci core.
+ */
+
+#ifdef CONFIG_MMC_RICOH_MMC
+static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev)
+{
+ /* disable via cardbus interface */
+ u8 write_enable;
+ u8 write_target;
+ u8 disable;
+
+ /* disable must be done via function #0 */
+ if (PCI_FUNC(dev->devfn))
+ return;
+
+ pci_read_config_byte(dev, 0xB7, &disable);
+ if (disable & 0x02)
+ return;
+
+ pci_read_config_byte(dev, 0x8E, &write_enable);
+ pci_write_config_byte(dev, 0x8E, 0xAA);
+ pci_read_config_byte(dev, 0x8D, &write_target);
+ pci_write_config_byte(dev, 0x8D, 0xB7);
+ pci_write_config_byte(dev, 0xB7, disable | 0x02);
+ pci_write_config_byte(dev, 0x8E, write_enable);
+ pci_write_config_byte(dev, 0x8D, write_target);
+
+ dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n");
+ dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
+
+static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
+{
+ /* disable via firewire interface */
+ u8 write_enable;
+ u8 disable;
+
+ /* disable must be done via function #0 */
+ if (PCI_FUNC(dev->devfn))
+ return;
+
+ pci_read_config_byte(dev, 0xCB, &disable);
+
+ if (disable & 0x02)
+ return;
+
+ pci_read_config_byte(dev, 0xCA, &write_enable);
+ pci_write_config_byte(dev, 0xCA, 0x57);
+ pci_write_config_byte(dev, 0xCB, disable | 0x02);
+ pci_write_config_byte(dev, 0xCA, write_enable);
+
+ dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
+ dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
+#endif /*CONFIG_MMC_RICOH_MMC*/
+
+
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
struct pci_fixup *end)
{
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 4a471dc4f4b..20d03f77228 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -9,6 +9,7 @@
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include "pci.h"
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 7d678bb15ff..17bed18d24a 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -93,8 +93,7 @@ void pci_update_resource(struct pci_dev *dev, int resno)
int pci_claim_resource(struct pci_dev *dev, int resource)
{
struct resource *res = &dev->resource[resource];
- struct resource *root;
- int err;
+ struct resource *root, *conflict;
root = pci_find_parent_resource(dev, res);
if (!root) {
@@ -103,12 +102,15 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
return -EINVAL;
}
- err = request_resource(root, res);
- if (err)
+ conflict = request_resource_conflict(root, res);
+ if (conflict) {
dev_err(&dev->dev,
- "address space collision: %pR already in use\n", res);
+ "address space collision: %pR conflicts with %s %pR\n",
+ res, conflict->name, conflict);
+ return -EBUSY;
+ }
- return err;
+ return 0;
}
EXPORT_SYMBOL(pci_claim_resource);
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 49c9e6c9779..659eaa0fc48 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -6,6 +6,7 @@
*/
#include <linux/kobject.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/err.h>
#include "pci.h"
@@ -29,7 +30,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj,
return attribute->store ? attribute->store(slot, buf, len) : -EIO;
}
-static struct sysfs_ops pci_slot_sysfs_ops = {
+static const struct sysfs_ops pci_slot_sysfs_ops = {
.show = pci_slot_attr_show,
.store = pci_slot_attr_store,
};
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 5d228071ec6..fb33fa42d24 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -15,6 +15,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <pcmcia/ss.h>
@@ -361,7 +362,6 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
struct at91_cf_socket *cf = platform_get_drvdata(pdev);
struct at91_cf_data *board = cf->board;
- pcmcia_socket_dev_suspend(&pdev->dev);
if (device_may_wakeup(&pdev->dev)) {
enable_irq_wake(board->det_pin);
if (board->irq_pin)
@@ -381,7 +381,6 @@ static int at91_cf_resume(struct platform_device *pdev)
disable_irq_wake(board->irq_pin);
}
- pcmcia_socket_dev_resume(&pdev->dev);
return 0;
}
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 171c8a65488..88c4c409878 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -43,6 +43,7 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -510,17 +511,6 @@ static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
return ret;
}
-static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
- pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
-
static struct platform_driver au1x00_pcmcia_driver = {
.driver = {
.name = "au1x00-pcmcia",
@@ -528,8 +518,6 @@ static struct platform_driver au1x00_pcmcia_driver = {
},
.probe = au1x00_drv_pcmcia_probe,
.remove = au1x00_drv_pcmcia_remove,
- .suspend = au1x00_drv_pcmcia_suspend,
- .resume = au1x00_drv_pcmcia_resume,
};
diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c
index bc88a3b19bb..693577e0fef 100644
--- a/drivers/pcmcia/bcm63xx_pcmcia.c
+++ b/drivers/pcmcia/bcm63xx_pcmcia.c
@@ -11,6 +11,7 @@
#include <linux/ioport.h>
#include <linux/timer.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/gpio.h>
diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c
index 2482ce7ac6d..9e84d039de4 100644
--- a/drivers/pcmcia/bfin_cf_pcmcia.c
+++ b/drivers/pcmcia/bfin_cf_pcmcia.c
@@ -31,6 +31,7 @@
#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -300,16 +301,6 @@ static int __devexit bfin_cf_remove(struct platform_device *pdev)
return 0;
}
-static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
- return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int bfin_cf_resume(struct platform_device *pdev)
-{
- return pcmcia_socket_dev_resume(&pdev->dev);
-}
-
static struct platform_driver bfin_cf_driver = {
.driver = {
.name = (char *)driver_name,
@@ -317,8 +308,6 @@ static struct platform_driver bfin_cf_driver = {
},
.probe = bfin_cf_probe,
.remove = __devexit_p(bfin_cf_remove),
- .suspend = bfin_cf_suspend,
- .resume = bfin_cf_resume,
};
static int __init bfin_cf_init(void)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index f230f6543bf..854959cada3 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
if (!s)
return -EINVAL;
+ if (s->functions) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
/* We do not want to validate the CIS cache... */
mutex_lock(&s->ops_mutex);
destroy_cis_cache(s);
@@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
count = 0;
else {
struct pcmcia_socket *s;
- unsigned int chains;
+ unsigned int chains = 1;
if (off + count > size)
count = size - off;
@@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
if (!(s->state & SOCKET_PRESENT))
return -ENODEV;
- if (pccard_validate_cis(s, &chains))
+ if (!s->functions && pccard_validate_cis(s, &chains))
return -EIO;
if (!chains)
return -ENODATA;
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index e679e708db6..75ed866e695 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -76,65 +76,6 @@ DECLARE_RWSEM(pcmcia_socket_list_rwsem);
EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
-/*
- * Low-level PCMCIA socket drivers need to register with the PCCard
- * core using pcmcia_register_socket.
- *
- * socket drivers are expected to use the following callbacks in their
- * .drv struct:
- * - pcmcia_socket_dev_suspend
- * - pcmcia_socket_dev_resume
- * These functions check for the appropriate struct pcmcia_soket arrays,
- * and pass them to the low-level functions pcmcia_{suspend,resume}_socket
- */
-static int socket_early_resume(struct pcmcia_socket *skt);
-static int socket_late_resume(struct pcmcia_socket *skt);
-static int socket_resume(struct pcmcia_socket *skt);
-static int socket_suspend(struct pcmcia_socket *skt);
-
-static void pcmcia_socket_dev_run(struct device *dev,
- int (*cb)(struct pcmcia_socket *))
-{
- struct pcmcia_socket *socket;
-
- down_read(&pcmcia_socket_list_rwsem);
- list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
- if (socket->dev.parent != dev)
- continue;
- mutex_lock(&socket->skt_mutex);
- cb(socket);
- mutex_unlock(&socket->skt_mutex);
- }
- up_read(&pcmcia_socket_list_rwsem);
-}
-
-int pcmcia_socket_dev_suspend(struct device *dev)
-{
- pcmcia_socket_dev_run(dev, socket_suspend);
- return 0;
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
-
-void pcmcia_socket_dev_early_resume(struct device *dev)
-{
- pcmcia_socket_dev_run(dev, socket_early_resume);
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_early_resume);
-
-void pcmcia_socket_dev_late_resume(struct device *dev)
-{
- pcmcia_socket_dev_run(dev, socket_late_resume);
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_late_resume);
-
-int pcmcia_socket_dev_resume(struct device *dev)
-{
- pcmcia_socket_dev_run(dev, socket_resume);
- return 0;
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_resume);
-
-
struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt)
{
struct device *dev = get_device(&skt->dev);
@@ -578,12 +519,18 @@ static int socket_early_resume(struct pcmcia_socket *skt)
static int socket_late_resume(struct pcmcia_socket *skt)
{
+ int ret;
+
mutex_lock(&skt->ops_mutex);
skt->state &= ~SOCKET_SUSPEND;
mutex_unlock(&skt->ops_mutex);
- if (!(skt->state & SOCKET_PRESENT))
- return socket_insert(skt);
+ if (!(skt->state & SOCKET_PRESENT)) {
+ ret = socket_insert(skt);
+ if (ret == -ENODEV)
+ ret = 0;
+ return ret;
+ }
if (skt->resume_status) {
socket_shutdown(skt);
@@ -919,11 +866,66 @@ static void pcmcia_release_socket_class(struct class *data)
}
+#ifdef CONFIG_PM
+
+static int __pcmcia_pm_op(struct device *dev,
+ int (*callback) (struct pcmcia_socket *skt))
+{
+ struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
+ int ret;
+
+ mutex_lock(&s->skt_mutex);
+ ret = callback(s);
+ mutex_unlock(&s->skt_mutex);
+
+ return ret;
+}
+
+static int pcmcia_socket_dev_suspend_noirq(struct device *dev)
+{
+ return __pcmcia_pm_op(dev, socket_suspend);
+}
+
+static int pcmcia_socket_dev_resume_noirq(struct device *dev)
+{
+ return __pcmcia_pm_op(dev, socket_early_resume);
+}
+
+static int pcmcia_socket_dev_resume(struct device *dev)
+{
+ return __pcmcia_pm_op(dev, socket_late_resume);
+}
+
+static const struct dev_pm_ops pcmcia_socket_pm_ops = {
+ /* dev_resume may be called with IRQs enabled */
+ SET_SYSTEM_SLEEP_PM_OPS(NULL,
+ pcmcia_socket_dev_resume)
+
+ /* late suspend must be called with IRQs disabled */
+ .suspend_noirq = pcmcia_socket_dev_suspend_noirq,
+ .freeze_noirq = pcmcia_socket_dev_suspend_noirq,
+ .poweroff_noirq = pcmcia_socket_dev_suspend_noirq,
+
+ /* early resume must be called with IRQs disabled */
+ .resume_noirq = pcmcia_socket_dev_resume_noirq,
+ .thaw_noirq = pcmcia_socket_dev_resume_noirq,
+ .restore_noirq = pcmcia_socket_dev_resume_noirq,
+};
+
+#define PCMCIA_SOCKET_CLASS_PM_OPS (&pcmcia_socket_pm_ops)
+
+#else /* CONFIG_PM */
+
+#define PCMCIA_SOCKET_CLASS_PM_OPS NULL
+
+#endif /* CONFIG_PM */
+
struct class pcmcia_socket_class = {
.name = "pcmcia_socket",
.dev_uevent = pcmcia_socket_uevent,
.dev_release = pcmcia_release_socket,
.class_release = pcmcia_release_socket_class,
+ .pm = PCMCIA_SOCKET_CLASS_PM_OPS,
};
EXPORT_SYMBOL(pcmcia_socket_class);
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
index 9254ab0b29b..2d48196a48c 100644
--- a/drivers/pcmcia/db1xxx_ss.c
+++ b/drivers/pcmcia/db1xxx_ss.c
@@ -26,6 +26,7 @@
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/resource.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <pcmcia/cs_types.h>
@@ -165,8 +166,10 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
IRQF_DISABLED, "pcmcia_insert", sock);
- if (ret)
+ if (ret) {
+ local_irq_restore(flags);
goto out1;
+ }
ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq,
IRQF_DISABLED, "pcmcia_eject", sock);
@@ -558,37 +561,10 @@ static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-static int db1x_pcmcia_suspend(struct device *dev)
-{
- return pcmcia_socket_dev_suspend(dev);
-}
-
-static int db1x_pcmcia_resume(struct device *dev)
-{
- return pcmcia_socket_dev_resume(dev);
-}
-
-static struct dev_pm_ops db1x_pcmcia_pmops = {
- .resume = db1x_pcmcia_resume,
- .suspend = db1x_pcmcia_suspend,
- .thaw = db1x_pcmcia_resume,
- .freeze = db1x_pcmcia_suspend,
-};
-
-#define DB1XXX_SS_PMOPS &db1x_pcmcia_pmops
-
-#else
-
-#define DB1XXX_SS_PMOPS NULL
-
-#endif
-
static struct platform_driver db1x_pcmcia_socket_driver = {
.driver = {
.name = "db1xxx_pcmcia",
.owner = THIS_MODULE,
- .pm = DB1XXX_SS_PMOPS
},
.probe = db1x_pcmcia_socket_probe,
.remove = __devexit_p(db1x_pcmcia_socket_remove),
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 0f98be4450b..508f94a2a78 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -24,6 +24,7 @@
#include <linux/firmware.h>
#include <linux/kref.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
@@ -334,7 +335,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
mutex_lock(&s->ops_mutex);
list_del(&p_dev->socket_device_list);
- p_dev->_removed = 1;
mutex_unlock(&s->ops_mutex);
dev_dbg(&p_dev->dev, "unregistering device\n");
@@ -509,8 +509,12 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
p_dev->device_no = (s->device_count++);
mutex_unlock(&s->ops_mutex);
- /* max of 2 devices per card */
- if (p_dev->device_no >= 2)
+ /* max of 2 PFC devices */
+ if ((p_dev->device_no >= 2) && (function == 0))
+ goto err_free;
+
+ /* max of 4 devices overall */
+ if (p_dev->device_no >= 4)
goto err_free;
p_dev->socket = s;
@@ -649,14 +653,7 @@ static int pcmcia_requery_callback(struct device *dev, void * _data)
static void pcmcia_requery(struct pcmcia_socket *s)
{
- int present, has_pfc;
-
- mutex_lock(&s->ops_mutex);
- present = s->pcmcia_state.present;
- mutex_unlock(&s->ops_mutex);
-
- if (!present)
- return;
+ int has_pfc;
if (s->functions == 0) {
pcmcia_card_add(s);
@@ -682,12 +679,10 @@ static void pcmcia_requery(struct pcmcia_socket *s)
new_funcs = mfc.nfn;
else
new_funcs = 1;
- if (old_funcs > new_funcs) {
+ if (old_funcs != new_funcs) {
+ /* we need to re-start */
pcmcia_card_remove(s, NULL);
pcmcia_card_add(s);
- } else if (new_funcs > old_funcs) {
- s->functions = new_funcs;
- pcmcia_device_add(s, 1);
}
}
@@ -723,6 +718,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
struct pcmcia_socket *s = dev->socket;
const struct firmware *fw;
int ret = -ENOMEM;
+ cistpl_longlink_mfc_t mfc;
+ int old_funcs, new_funcs = 1;
if (!filename)
return -EINVAL;
@@ -745,6 +742,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
goto release;
}
+ /* we need to re-start if the number of functions changed */
+ old_funcs = s->functions;
+ if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
+ &mfc))
+ new_funcs = mfc.nfn;
+
+ if (old_funcs != new_funcs)
+ ret = -EBUSY;
/* update information */
pcmcia_device_query(dev);
@@ -815,11 +820,12 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
- if (dev->device_no != did->device_no)
- return 0;
+ dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n");
mutex_lock(&dev->socket->ops_mutex);
dev->socket->pcmcia_state.has_pfc = 1;
mutex_unlock(&dev->socket->ops_mutex);
+ if (dev->device_no != did->device_no)
+ return 0;
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
@@ -830,7 +836,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
/* if this is a pseudo-multi-function device,
* we need explicit matches */
- if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO)
+ if (dev->socket->pcmcia_state.has_pfc)
return 0;
if (dev->device_no)
return 0;
@@ -853,10 +859,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
dev_dbg(&dev->dev, "device needs a fake CIS\n");
if (!dev->socket->fake_cis)
- pcmcia_load_firmware(dev, did->cisfile);
-
- if (!dev->socket->fake_cis)
- return 0;
+ if (pcmcia_load_firmware(dev, did->cisfile))
+ return 0;
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
@@ -971,9 +975,9 @@ static int runtime_suspend(struct device *dev)
{
int rc;
- down(&dev->sem);
+ device_lock(dev);
rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND);
- up(&dev->sem);
+ device_unlock(dev);
return rc;
}
@@ -981,9 +985,9 @@ static int runtime_resume(struct device *dev)
{
int rc;
- down(&dev->sem);
+ device_lock(dev);
rc = pcmcia_dev_resume(dev);
- up(&dev->sem);
+ device_unlock(dev);
return rc;
}
@@ -1249,9 +1253,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
switch (event) {
case CS_EVENT_CARD_REMOVAL:
- mutex_lock(&s->ops_mutex);
- s->pcmcia_state.present = 0;
- mutex_unlock(&s->ops_mutex);
+ atomic_set(&skt->present, 0);
pcmcia_card_remove(skt, NULL);
handle_event(skt, event);
mutex_lock(&s->ops_mutex);
@@ -1260,9 +1262,9 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
break;
case CS_EVENT_CARD_INSERTION:
+ atomic_set(&skt->present, 1);
mutex_lock(&s->ops_mutex);
s->pcmcia_state.has_pfc = 0;
- s->pcmcia_state.present = 1;
destroy_cis_cache(s); /* to be on the safe side... */
mutex_unlock(&s->ops_mutex);
pcmcia_card_add(skt);
@@ -1302,7 +1304,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
return 0;
} /* ds_event */
-
+/*
+ * NOTE: This is racy. There's no guarantee the card will still be
+ * physically present, even if the call to this function returns
+ * non-NULL. Furthermore, the device driver most likely is unbound
+ * almost immediately, so the timeframe where pcmcia_dev_present
+ * returns NULL is probably really really small.
+ */
struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
{
struct pcmcia_device *p_dev;
@@ -1312,22 +1320,9 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
if (!p_dev)
return NULL;
- mutex_lock(&p_dev->socket->ops_mutex);
- if (!p_dev->socket->pcmcia_state.present)
- goto out;
-
- if (p_dev->socket->pcmcia_state.dead)
- goto out;
+ if (atomic_read(&p_dev->socket->present) != 0)
+ ret = p_dev;
- if (p_dev->_removed)
- goto out;
-
- if (p_dev->suspended)
- goto out;
-
- ret = p_dev;
- out:
- mutex_unlock(&p_dev->socket->ops_mutex);
pcmcia_put_dev(p_dev);
return ret;
}
@@ -1377,6 +1372,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
return ret;
}
+ atomic_set(&socket->present, 0);
+
return 0;
}
@@ -1388,10 +1385,6 @@ static void pcmcia_bus_remove_socket(struct device *dev,
if (!socket)
return;
- mutex_lock(&socket->ops_mutex);
- socket->pcmcia_state.dead = 1;
- mutex_unlock(&socket->ops_mutex);
-
pccard_register_pcmcia(socket, NULL);
/* unregister any unbound devices */
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c
index 89cfddca089..2e59fe947d2 100644
--- a/drivers/pcmcia/electra_cf.c
+++ b/drivers/pcmcia/electra_cf.c
@@ -31,6 +31,7 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index a04f21c8170..3003bb3dfcc 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -39,27 +39,11 @@ static struct pci_device_id i82092aa_pci_ids[] = {
};
MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
-#ifdef CONFIG_PM
-static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int i82092aa_socket_resume (struct pci_dev *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
-#endif
-
static struct pci_driver i82092aa_pci_driver = {
.name = "i82092aa",
.id_table = i82092aa_pci_ids,
.probe = i82092aa_pci_probe,
.remove = __devexit_p(i82092aa_pci_remove),
-#ifdef CONFIG_PM
- .suspend = i82092aa_socket_suspend,
- .resume = i82092aa_socket_resume,
-#endif
};
@@ -133,6 +117,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de
sockets[i].socket.map_size = 0x1000;
sockets[i].socket.irq_mask = 0;
sockets[i].socket.pci_irq = dev->irq;
+ sockets[i].socket.cb_dev = dev;
sockets[i].socket.owner = THIS_MODULE;
sockets[i].number = i;
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index c13fd936051..9e2a15628de 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -40,7 +40,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/timer.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
@@ -1223,16 +1222,7 @@ static int pcic_init(struct pcmcia_socket *s)
return 0;
}
-static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
- pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-static int i82365_drv_pcmcia_resume(struct platform_device *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
static struct pccard_operations pcic_operations = {
.init = pcic_init,
.get_status = pcic_get_status,
@@ -1248,8 +1238,6 @@ static struct platform_driver i82365_driver = {
.name = "i82365",
.owner = THIS_MODULE,
},
- .suspend = i82365_drv_pcmcia_suspend,
- .resume = i82365_drv_pcmcia_resume,
};
static struct platform_device *i82365_device;
diff --git a/drivers/pcmcia/i82365.h b/drivers/pcmcia/i82365.h
index 849ef1b5d68..3f84d7a2dc8 100644
--- a/drivers/pcmcia/i82365.h
+++ b/drivers/pcmcia/i82365.h
@@ -95,6 +95,7 @@
#define I365_CSC_DETECT 0x08
#define I365_CSC_ANY 0x0F
#define I365_CSC_GPI 0x10
+#define I365_CSC_IRQ_MASK 0xF0
/* Flags for I365_ADDRWIN */
#define I365_ENA_IO(map) (0x40 << (map))
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 0ece2cd4a85..7e16ed8eb0a 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/timer.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
@@ -685,16 +684,7 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};
-static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
- pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-static int cfc_drv_pcmcia_resume(struct platform_device *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
/*====================================================================*/
static struct platform_driver pcc_driver = {
@@ -702,8 +692,6 @@ static struct platform_driver pcc_driver = {
.name = "cfc",
.owner = THIS_MODULE,
},
- .suspend = cfc_drv_pcmcia_suspend,
- .resume = cfc_drv_pcmcia_resume,
};
static struct platform_device pcc_device = {
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 72844c5a6d0..6c5c3f910d7 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/timer.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
@@ -663,16 +662,6 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};
-static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
- pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int pcc_drv_pcmcia_resume(struct platform_device *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
/*====================================================================*/
static struct platform_driver pcc_driver = {
@@ -680,8 +669,6 @@ static struct platform_driver pcc_driver = {
.name = "pcc",
.owner = THIS_MODULE,
},
- .suspend = pcc_drv_pcmcia_suspend,
- .resume = pcc_drv_pcmcia_resume,
};
static struct platform_device pcc_device = {
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 61c21591812..41cc954a5ff 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -42,7 +42,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/delay.h>
@@ -1288,21 +1287,6 @@ static int m8xx_remove(struct of_device *ofdev)
return 0;
}
-#ifdef CONFIG_PM
-static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int m8xx_resume(struct platform_device *pdev)
-{
- return pcmcia_socket_dev_resume(&pdev->dev);
-}
-#else
-#define m8xx_suspend NULL
-#define m8xx_resume NULL
-#endif
-
static const struct of_device_id m8xx_pcmcia_match[] = {
{
.type = "pcmcia",
@@ -1318,8 +1302,6 @@ static struct of_platform_driver m8xx_pcmcia_driver = {
.match_table = m8xx_pcmcia_match,
.probe = m8xx_probe,
.remove = m8xx_remove,
- .suspend = m8xx_suspend,
- .resume = m8xx_resume,
};
static int __init m8xx_init(void)
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 3ef99155239..a7cfc7964c7 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <pcmcia/ss.h>
@@ -330,24 +331,12 @@ static int __exit omap_cf_remove(struct platform_device *pdev)
return 0;
}
-static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
- return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int omap_cf_resume(struct platform_device *pdev)
-{
- return pcmcia_socket_dev_resume(&pdev->dev);
-}
-
static struct platform_driver omap_cf_driver = {
.driver = {
.name = (char *) driver_name,
.owner = THIS_MODULE,
},
.remove = __exit_p(omap_cf_remove),
- .suspend = omap_cf_suspend,
- .resume = omap_cf_resume,
};
static int __init omap_cf_init(void)
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 13a7132cf68..104e73d5d86 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -27,6 +27,7 @@
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/workqueue.h>
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index b2df04199a2..7c3d03bb4f3 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -21,6 +21,7 @@
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
@@ -256,6 +257,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
{
struct pcmcia_socket *s;
config_t *c;
+ int ret;
s = p_dev->socket;
@@ -264,13 +266,13 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
if (!(s->state & SOCKET_PRESENT)) {
dev_dbg(&s->dev, "No card present\n");
- mutex_unlock(&s->ops_mutex);
- return -ENODEV;
+ ret = -ENODEV;
+ goto unlock;
}
if (!(c->state & CONFIG_LOCKED)) {
dev_dbg(&s->dev, "Configuration isnt't locked\n");
- mutex_unlock(&s->ops_mutex);
- return -EACCES;
+ ret = -EACCES;
+ goto unlock;
}
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
@@ -286,7 +288,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto unlock;
}
/* We only allow changing Vpp1 and Vpp2 to the same value */
@@ -294,21 +297,21 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
if (mod->Vpp1 != mod->Vpp2) {
dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
- mutex_unlock(&s->ops_mutex);
- return -EINVAL;
+ ret = -EINVAL;
+ goto unlock;
}
s->socket.Vpp = mod->Vpp1;
if (s->ops->set_socket(s, &s->socket)) {
- mutex_unlock(&s->ops_mutex);
dev_printk(KERN_WARNING, &s->dev,
"Unable to set VPP\n");
- return -EIO;
+ ret = -EIO;
+ goto unlock;
}
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
- mutex_unlock(&s->ops_mutex);
- return -EINVAL;
+ ret = -EINVAL;
+ goto unlock;
}
if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
@@ -332,9 +335,11 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
s->ops->set_io_map(s, &io_on);
}
}
+ ret = 0;
+unlock:
mutex_unlock(&s->ops_mutex);
- return 0;
+ return ret;
} /* modify_configuration */
EXPORT_SYMBOL(pcmcia_modify_configuration);
@@ -750,20 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
else
printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
-#ifdef CONFIG_PCMCIA_PROBE
-
-#ifdef IRQ_NOAUTOEN
- /* if the underlying IRQ infrastructure allows for it, only allocate
- * the IRQ, but do not enable it
- */
- if (!(req->Handler))
- type |= IRQ_NOAUTOEN;
-#endif /* IRQ_NOAUTOEN */
-
- if (s->irq.AssignedIRQ != 0) {
- /* If the interrupt is already assigned, it must be the same */
+ /* If the interrupt is already assigned, it must be the same */
+ if (s->irq.AssignedIRQ != 0)
irq = s->irq.AssignedIRQ;
- } else {
+
+#ifdef CONFIG_PCMCIA_PROBE
+ if (!irq) {
int try;
u32 mask = s->irq_mask;
void *data = p_dev; /* something unique to this device */
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 7c204910a77..b61a13663a0 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -9,18 +9,19 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/device.h>
+#include <linux/io.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <asm/system.h>
-#include <asm/io.h>
#include "pd6729.h"
#include "i82365.h"
@@ -222,9 +223,9 @@ static irqreturn_t pd6729_interrupt(int irq, void *dev)
? SS_READY : 0;
}
- if (events) {
+ if (events)
pcmcia_parse_events(&socket[i].socket, events);
- }
+
active |= events;
}
@@ -256,9 +257,8 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value)
status = indirect_read(socket, I365_STATUS);
*value = 0;
- if ((status & I365_CS_DETECT) == I365_CS_DETECT) {
+ if ((status & I365_CS_DETECT) == I365_CS_DETECT)
*value |= SS_DETECT;
- }
/*
* IO cards have a different meaning of bits 0,1
@@ -308,7 +308,7 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
socket->card_irq = state->io_irq;
reg = 0;
- /* The reset bit has "inverse" logic */
+ /* The reset bit has "inverse" logic */
if (!(state->flags & SS_RESET))
reg |= I365_PC_RESET;
if (state->flags & SS_IOCARD)
@@ -380,7 +380,7 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
indirect_write(socket, I365_POWER, reg);
if (irq_mode == 1) {
- /* all interrupts are to be done as PCI interrupts */
+ /* all interrupts are to be done as PCI interrupts */
data = PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ;
} else
data = 0;
@@ -391,9 +391,9 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
/* Enable specific interrupt events */
reg = 0x00;
- if (state->csc_mask & SS_DETECT) {
+ if (state->csc_mask & SS_DETECT)
reg |= I365_CSC_DETECT;
- }
+
if (state->flags & SS_IOCARD) {
if (state->csc_mask & SS_STSCHG)
reg |= I365_CSC_STSCHG;
@@ -450,9 +450,12 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,
ioctl = indirect_read(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map);
- if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
- if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
- if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
+ if (io->flags & MAP_0WS)
+ ioctl |= I365_IOCTL_0WS(map);
+ if (io->flags & MAP_16BIT)
+ ioctl |= I365_IOCTL_16BIT(map);
+ if (io->flags & MAP_AUTOSZ)
+ ioctl |= I365_IOCTL_IOCS16(map);
indirect_write(socket, I365_IOCTL, ioctl);
@@ -497,7 +500,7 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,
/* write the stop address */
- i= (mem->res->end >> 12) & 0x0fff;
+ i = (mem->res->end >> 12) & 0x0fff;
switch (to_cycles(mem->speed)) {
case 0:
break;
@@ -563,7 +566,7 @@ static int pd6729_init(struct pcmcia_socket *sock)
/* the pccard structure and its functions */
static struct pccard_operations pd6729_operations = {
- .init = pd6729_init,
+ .init = pd6729_init,
.get_status = pd6729_get_status,
.set_socket = pd6729_set_socket,
.set_io_map = pd6729_set_io_map,
@@ -578,8 +581,13 @@ static irqreturn_t pd6729_test(int irq, void *dev)
static int pd6729_check_irq(int irq)
{
- if (request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", pd6729_test)
- != 0) return -1;
+ int ret;
+
+ ret = request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x",
+ pd6729_test);
+ if (ret)
+ return -1;
+
free_irq(irq, pd6729_test);
return 0;
}
@@ -591,7 +599,7 @@ static u_int __devinit pd6729_isa_scan(void)
if (irq_mode == 1) {
printk(KERN_INFO "pd6729: PCI card interrupts, "
- "PCI status changes\n");
+ "PCI status changes\n");
return 0;
}
@@ -607,9 +615,10 @@ static u_int __devinit pd6729_isa_scan(void)
if (mask & (1<<i))
printk("%s%d", ((mask & ((1<<i)-1)) ? "," : ""), i);
- if (mask == 0) printk("none!");
-
- printk(" polling status changes.\n");
+ if (mask == 0)
+ printk("none!");
+ else
+ printk(" polling status changes.\n");
return mask;
}
@@ -624,11 +633,16 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
GFP_KERNEL);
- if (!socket)
+ if (!socket) {
+ dev_warn(&dev->dev, "failed to kzalloc socket.\n");
return -ENOMEM;
+ }
- if ((ret = pci_enable_device(dev)))
+ ret = pci_enable_device(dev);
+ if (ret) {
+ dev_warn(&dev->dev, "failed to enable pci_device.\n");
goto err_out_free_mem;
+ }
if (!pci_resource_start(dev, 0)) {
dev_warn(&dev->dev, "refusing to load the driver as the "
@@ -639,7 +653,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "
"on irq %d\n",
(unsigned long long)pci_resource_start(dev, 0), dev->irq);
- /*
+ /*
* Since we have no memory BARs some firmware may not
* have had PCI_COMMAND_MEMORY enabled, yet the device needs it.
*/
@@ -671,6 +685,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
socket[i].socket.map_size = 0x1000;
socket[i].socket.irq_mask = mask;
socket[i].socket.pci_irq = dev->irq;
+ socket[i].socket.cb_dev = dev;
socket[i].socket.owner = THIS_MODULE;
socket[i].number = i;
@@ -684,8 +699,9 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
pci_set_drvdata(dev, socket);
if (irq_mode == 1) {
/* Register the interrupt handler */
- if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
- "pd6729", socket))) {
+ ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
+ "pd6729", socket);
+ if (ret) {
dev_err(&dev->dev, "Failed to register irq %d\n",
dev->irq);
goto err_out_free_res;
@@ -749,18 +765,6 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev)
kfree(socket);
}
-#ifdef CONFIG_PM
-static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int pd6729_socket_resume(struct pci_dev *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
-#endif
-
static struct pci_device_id pd6729_pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_CIRRUS,
@@ -777,10 +781,6 @@ static struct pci_driver pd6729_pci_driver = {
.id_table = pd6729_pci_ids,
.probe = pd6729_pci_probe,
.remove = __devexit_p(pd6729_pci_remove),
-#ifdef CONFIG_PM
- .suspend = pd6729_socket_suspend,
- .resume = pd6729_socket_resume,
-#endif
};
static int pd6729_module_init(void)
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 76e640bccde..df4532e91b1 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -17,6 +17,7 @@
======================================================================*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/ioport.h>
@@ -325,19 +326,13 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
return 0;
}
-static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
-{
- return pcmcia_socket_dev_suspend(dev);
-}
-
static int pxa2xx_drv_pcmcia_resume(struct device *dev)
{
pxa2xx_configure_sockets(dev);
- return pcmcia_socket_dev_resume(dev);
+ return 0;
}
static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = {
- .suspend = pxa2xx_drv_pcmcia_suspend,
.resume = pxa2xx_drv_pcmcia_resume,
};
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 452c83b512c..ffa5f3cae57 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -12,6 +12,7 @@
* (C) 1999 David A. Hinds
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 4663b3fa9f9..a6eb7b59ba9 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
return;
}
for (i = base, most = 0; i < base+num; i += 8) {
- res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+ res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
if (!res)
continue;
hole = inb(i);
@@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
bad = any = 0;
for (i = base; i < base+num; i += 8) {
- res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
- if (!res)
+ res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+ if (!res) {
+ if (!any)
+ printk(" excluding");
+ if (!bad)
+ bad = any = i;
continue;
+ }
for (j = 0; j < 8; j++)
if (inb(i+j) != most)
break;
@@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
}
if (bad) {
if ((num > 16) && (bad == base) && (i == base+num)) {
+ sub_interval(&s_data->io_db, bad, i-bad);
printk(" nothing: probe failed.\n");
return;
} else {
@@ -596,19 +602,17 @@ struct pcmcia_align_data {
struct resource_map *map;
};
-static resource_size_t
-pcmcia_common_align(void *align_data, const struct resource *res,
- resource_size_t size, resource_size_t align)
+static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
+ resource_size_t start)
{
- struct pcmcia_align_data *data = align_data;
- resource_size_t start;
+ resource_size_t ret;
/*
* Ensure that we have the correct start address
*/
- start = (res->start & ~data->mask) + data->offset;
- if (start < res->start)
- start += data->mask + 1;
- return start;
+ ret = (start & ~align_data->mask) + align_data->offset;
+ if (ret < start)
+ ret += align_data->mask + 1;
+ return ret;
}
static resource_size_t
@@ -619,29 +623,28 @@ pcmcia_align(void *align_data, const struct resource *res,
struct resource_map *m;
resource_size_t start;
- start = pcmcia_common_align(data, res, size, align);
+ start = pcmcia_common_align(data, res->start);
for (m = data->map->next; m != data->map; m = m->next) {
- unsigned long start = m->base;
- unsigned long end = m->base + m->num - 1;
+ unsigned long map_start = m->base;
+ unsigned long map_end = m->base + m->num - 1;
/*
* If the lower resources are not available, try aligning
* to this entry of the resource database to see if it'll
* fit here.
*/
- if (res->start < start) {
- start = pcmcia_common_align(data, res, size, align);
- }
+ if (start < map_start)
+ start = pcmcia_common_align(data, map_start);
/*
* If we're above the area which was passed in, there's
* no point proceeding.
*/
- if (res->start >= res->end)
+ if (start >= res->end)
break;
- if ((res->start + size - 1) <= end)
+ if ((start + size - 1) <= map_end)
break;
}
@@ -807,9 +810,18 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
{
struct socket_data *data = s->resource_data;
- unsigned long size = end - start + 1;
+ unsigned long size;
int ret = 0;
+#if defined(CONFIG_X86)
+ /* on x86, avoid anything < 0x100 for it is often used for
+ * legacy platform devices */
+ if (start < 0x100)
+ start = 0x100;
+#endif
+
+ size = end - start + 1;
+
if (end < start)
return -EINVAL;
@@ -867,10 +879,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
if (res == &ioport_resource)
continue;
dev_printk(KERN_INFO, &s->cb_dev->dev,
- "pcmcia: parent PCI bridge I/O "
- "window: 0x%llx - 0x%llx\n",
- (unsigned long long)res->start,
- (unsigned long long)res->end);
+ "pcmcia: parent PCI bridge window: %pR\n",
+ res);
if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
done |= IORESOURCE_IO;
@@ -880,10 +890,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
if (res == &iomem_resource)
continue;
dev_printk(KERN_INFO, &s->cb_dev->dev,
- "pcmcia: parent PCI bridge Memory "
- "window: 0x%llx - 0x%llx\n",
- (unsigned long long)res->start,
- (unsigned long long)res->end);
+ "pcmcia: parent PCI bridge window: %pR\n",
+ res);
if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
done |= IORESOURCE_MEM;
}
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 8db86b90c20..edbd8c47262 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <pcmcia/cs_types.h>
@@ -95,17 +96,6 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
return 0;
}
-static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
- pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
-
static struct platform_driver sa11x0_pcmcia_driver = {
.driver = {
.name = "sa11x0-pcmcia",
@@ -113,8 +103,6 @@ static struct platform_driver sa11x0_pcmcia_driver = {
},
.probe = sa11x0_drv_pcmcia_probe,
.remove = sa11x0_drv_pcmcia_remove,
- .suspend = sa11x0_drv_pcmcia_suspend,
- .resume = sa11x0_drv_pcmcia_resume,
};
/* sa11x0_pcmcia_init()
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index de6bc333d29..59866905ea3 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <pcmcia/ss.h>
@@ -21,11 +22,18 @@
#include "sa1111_generic.h"
+#define IDX_IRQ_S0_READY_NINT (0)
+#define IDX_IRQ_S0_CD_VALID (1)
+#define IDX_IRQ_S0_BVD1_STSCHG (2)
+#define IDX_IRQ_S1_READY_NINT (3)
+#define IDX_IRQ_S1_CD_VALID (4)
+#define IDX_IRQ_S1_BVD1_STSCHG (5)
+
static struct pcmcia_irqs irqs[] = {
- { 0, IRQ_S0_CD_VALID, "SA1111 PCMCIA card detect" },
- { 0, IRQ_S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1" },
- { 1, IRQ_S1_CD_VALID, "SA1111 CF card detect" },
- { 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1" },
+ { 0, NO_IRQ, "SA1111 PCMCIA card detect" },
+ { 0, NO_IRQ, "SA1111 PCMCIA BVD1" },
+ { 1, NO_IRQ, "SA1111 CF card detect" },
+ { 1, NO_IRQ, "SA1111 CF BVD1" },
};
static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
@@ -136,7 +144,9 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
s->soc.ops = ops;
s->soc.socket.owner = ops->owner;
s->soc.socket.dev.parent = &dev->dev;
- s->soc.socket.pci_irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
+ s->soc.socket.pci_irq = s->soc.nr ?
+ dev->irq[IDX_IRQ_S0_READY_NINT] :
+ dev->irq[IDX_IRQ_S1_READY_NINT];
s->dev = dev;
ret = add(&s->soc);
@@ -162,6 +172,12 @@ static int pcmcia_probe(struct sa1111_dev *dev)
base = dev->mapbase;
+ /* Initialize PCMCIA IRQs */
+ irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
+ irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
+ irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
+ irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
+
/*
* Initialise the suspend state.
*/
@@ -198,16 +214,6 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
return 0;
}
-static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int pcmcia_resume(struct sa1111_dev *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
-
static struct sa1111_driver pcmcia_driver = {
.drv = {
.name = "sa1111-pcmcia",
@@ -215,8 +221,6 @@ static struct sa1111_driver pcmcia_driver = {
.devid = SA1111_DEVID_PCMCIA,
.probe = pcmcia_probe,
.remove = __devexit_p(pcmcia_remove),
- .suspend = pcmcia_suspend,
- .resume = pcmcia_resume,
};
static int __init sa1111_drv_pcmcia_init(void)
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index fc9a6527019..fa28d8911b0 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -37,6 +37,7 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <asm/irq.h>
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 08278016e58..80e36bc407d 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -15,7 +15,6 @@
#include <linux/string.h>
#include <linux/major.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 12c49ee135e..56004a1b5bb 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -39,7 +39,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/delay.h>
@@ -348,16 +347,6 @@ static int __init get_tcic_id(void)
return id;
}
-static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
- pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int tcic_drv_pcmcia_resume(struct platform_device *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
/*====================================================================*/
static struct platform_driver tcic_driver = {
@@ -365,8 +354,6 @@ static struct platform_driver tcic_driver = {
.name = "tcic-pcmcia",
.owner = THIS_MODULE,
},
- .suspend = tcic_drv_pcmcia_suspend,
- .resume = tcic_drv_pcmcia_resume,
};
static struct platform_device tcic_device = {
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index aaa70227bfb..9ffa97d0b16 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket)
u8 new, reg = exca_readb(socket, I365_INTCTL);
new = reg & ~I365_INTR_ENA;
- if (socket->cb_irq)
+ if (socket->dev->irq)
new |= I365_INTR_ENA;
if (new != reg)
exca_writeb(socket, I365_INTCTL, new);
@@ -316,14 +316,47 @@ static int ti_override(struct yenta_socket *socket)
return 0;
}
+static void ti113x_use_isa_irq(struct yenta_socket *socket)
+{
+ int isa_irq = -1;
+ u8 intctl;
+ u32 isa_irq_mask = 0;
+
+ if (!isa_probe)
+ return;
+
+ /* get a free isa int */
+ isa_irq_mask = yenta_probe_irq(socket, isa_interrupts);
+ if (!isa_irq_mask)
+ return; /* no useable isa irq found */
+
+ /* choose highest available */
+ for (; isa_irq_mask; isa_irq++)
+ isa_irq_mask >>= 1;
+ socket->cb_irq = isa_irq;
+
+ exca_writeb(socket, I365_CSCINT, (isa_irq << 4));
+
+ intctl = exca_readb(socket, I365_INTCTL);
+ intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK); /* CSC Enable */
+ exca_writeb(socket, I365_INTCTL, intctl);
+
+ dev_info(&socket->dev->dev,
+ "Yenta TI113x: using isa irq %d for CardBus\n", isa_irq);
+}
+
+
static int ti113x_override(struct yenta_socket *socket)
{
u8 cardctl;
cardctl = config_readb(socket, TI113X_CARD_CONTROL);
cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
- if (socket->cb_irq)
+ if (socket->dev->irq)
cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
+ else
+ ti113x_use_isa_irq(socket);
+
config_writeb(socket, TI113X_CARD_CONTROL, cardctl);
return ti_override(socket);
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index c9fcbdc164e..86e4a1a3c64 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -105,6 +105,7 @@ typedef struct vrc4171_socket {
char name[24];
int csc_irq;
int io_irq;
+ spinlock_t lock;
} vrc4171_socket_t;
static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS];
@@ -327,7 +328,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
slot = sock->sock;
socket = &vrc4171_sockets[slot];
- spin_lock_irq(&sock->lock);
+ spin_lock_irq(&socket->lock);
voltage = set_Vcc_value(state->Vcc);
exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage);
@@ -370,7 +371,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
cscint |= I365_CSC_DETECT;
exca_write_byte(slot, I365_CSCINT, cscint);
- spin_unlock_irq(&sock->lock);
+ spin_unlock_irq(&socket->lock);
return 0;
}
@@ -704,24 +705,11 @@ static int __devinit vrc4171_card_setup(char *options)
__setup("vrc4171_card=", vrc4171_card_setup);
-static int vrc4171_card_suspend(struct platform_device *dev,
- pm_message_t state)
-{
- return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int vrc4171_card_resume(struct platform_device *dev)
-{
- return pcmcia_socket_dev_resume(&dev->dev);
-}
-
static struct platform_driver vrc4171_card_driver = {
.driver = {
.name = vrc4171_card_name,
.owner = THIS_MODULE,
},
- .suspend = vrc4171_card_suspend,
- .resume = vrc4171_card_resume,
};
static int __devinit vrc4171_card_init(void)
diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c
index f9009d34254..201ccfa1e97 100644
--- a/drivers/pcmcia/xxs1500_ss.c
+++ b/drivers/pcmcia/xxs1500_ss.c
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/resource.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 967c766f53b..83ace277426 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
@@ -42,6 +43,18 @@ module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444);
MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
"or 'default' (uses recommended behaviour for the detected bridge)");
+/*
+ * Only probe "regular" interrupts, don't
+ * touch dangerous spots like the mouse irq,
+ * because there are mice that apparently
+ * get really confused if they get fondled
+ * too intimately.
+ *
+ * Default to 11, 10, 9, 7, 6, 5, 4, 3.
+ */
+static u32 isa_interrupts = 0x0ef8;
+
+
#define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
/* Don't ask.. */
@@ -54,6 +67,8 @@ MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
*/
#ifdef CONFIG_YENTA_TI
static int yenta_probe_cb_irq(struct yenta_socket *socket);
+static unsigned int yenta_probe_irq(struct yenta_socket *socket,
+ u32 isa_irq_mask);
#endif
@@ -329,8 +344,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
/* ISA interrupt control? */
intr = exca_readb(socket, I365_INTCTL);
intr = (intr & ~0xf);
- if (!socket->cb_irq) {
- intr |= state->io_irq;
+ if (!socket->dev->irq) {
+ intr |= socket->cb_irq ? socket->cb_irq : state->io_irq;
bridge |= CB_BRIDGE_INTR;
}
exca_writeb(socket, I365_INTCTL, intr);
@@ -340,7 +355,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
- if (state->io_irq != socket->cb_irq) {
+ if (state->io_irq != socket->dev->irq) {
reg |= state->io_irq;
bridge |= CB_BRIDGE_INTR;
}
@@ -356,7 +371,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
exca_writeb(socket, I365_POWER, reg);
/* CSC interrupt: no ISA irq for CSC */
- reg = I365_CSC_DETECT;
+ reg = exca_readb(socket, I365_CSCINT);
+ reg &= I365_CSC_IRQ_MASK;
+ reg |= I365_CSC_DETECT;
if (state->flags & SS_IOCARD) {
if (state->csc_mask & SS_STSCHG)
reg |= I365_CSC_STSCHG;
@@ -896,22 +913,12 @@ static struct cardbus_type cardbus_type[] = {
};
-/*
- * Only probe "regular" interrupts, don't
- * touch dangerous spots like the mouse irq,
- * because there are mice that apparently
- * get really confused if they get fondled
- * too intimately.
- *
- * Default to 11, 10, 9, 7, 6, 5, 4, 3.
- */
-static u32 isa_interrupts = 0x0ef8;
-
static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
{
int i;
unsigned long val;
u32 mask;
+ u8 reg;
/*
* Probe for usable interrupts using the force
@@ -919,6 +926,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
*/
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
+ reg = exca_readb(socket, I365_CSCINT);
exca_writeb(socket, I365_CSCINT, 0);
val = probe_irq_on() & isa_irq_mask;
for (i = 1; i < 16; i++) {
@@ -930,7 +938,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
cb_writel(socket, CB_SOCKET_EVENT, -1);
}
cb_writel(socket, CB_SOCKET_MASK, 0);
- exca_writeb(socket, I365_CSCINT, 0);
+ exca_writeb(socket, I365_CSCINT, reg);
mask = probe_irq_mask(val) & 0xffff;
@@ -967,6 +975,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id)
/* probes the PCI interrupt, use only on override functions */
static int yenta_probe_cb_irq(struct yenta_socket *socket)
{
+ u8 reg;
+
if (!socket->cb_irq)
return -1;
@@ -979,7 +989,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
}
/* generate interrupt, wait */
- exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG);
+ reg = exca_readb(socket, I365_CSCINT);
+ exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG);
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
@@ -988,7 +999,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
/* disable interrupts */
cb_writel(socket, CB_SOCKET_MASK, 0);
- exca_writeb(socket, I365_CSCINT, 0);
+ exca_writeb(socket, I365_CSCINT, reg);
cb_writel(socket, CB_SOCKET_EVENT, -1);
exca_readb(socket, I365_CSC);
@@ -1280,12 +1291,9 @@ static int yenta_dev_suspend_noirq(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct yenta_socket *socket = pci_get_drvdata(pdev);
- int ret;
-
- ret = pcmcia_socket_dev_suspend(dev);
if (!socket)
- return ret;
+ return 0;
if (socket->type && socket->type->save_state)
socket->type->save_state(socket);
@@ -1302,7 +1310,7 @@ static int yenta_dev_suspend_noirq(struct device *dev)
*/
/* pci_set_power_state(dev, 3); */
- return ret;
+ return 0;
}
static int yenta_dev_resume_noirq(struct device *dev)
@@ -1326,26 +1334,16 @@ static int yenta_dev_resume_noirq(struct device *dev)
if (socket->type && socket->type->restore_state)
socket->type->restore_state(socket);
- pcmcia_socket_dev_early_resume(dev);
- return 0;
-}
-
-static int yenta_dev_resume(struct device *dev)
-{
- pcmcia_socket_dev_late_resume(dev);
return 0;
}
static const struct dev_pm_ops yenta_pm_ops = {
.suspend_noirq = yenta_dev_suspend_noirq,
.resume_noirq = yenta_dev_resume_noirq,
- .resume = yenta_dev_resume,
.freeze_noirq = yenta_dev_suspend_noirq,
.thaw_noirq = yenta_dev_resume_noirq,
- .thaw = yenta_dev_resume,
.poweroff_noirq = yenta_dev_suspend_noirq,
.restore_noirq = yenta_dev_resume_noirq,
- .restore = yenta_dev_resume,
};
#define YENTA_PM_OPS (&yenta_pm_ops)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index cd2ee6fce1b..6c3320d7505 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -150,6 +150,7 @@ config MSI_LAPTOP
tristate "MSI Laptop Extras"
depends on ACPI
depends on BACKLIGHT_CLASS_DEVICE
+ depends on RFKILL
---help---
This is a driver for laptops built by MSI (MICRO-STAR
INTERNATIONAL):
@@ -384,6 +385,17 @@ config EEEPC_LAPTOP
If you have an Eee PC laptop, say Y or M here.
+config EEEPC_WMI
+ tristate "Eee PC WMI Hotkey Driver (EXPERIMENTAL)"
+ depends on ACPI_WMI
+ depends on INPUT
+ depends on EXPERIMENTAL
+ select INPUT_SPARSEKMAP
+ ---help---
+ Say Y here if you want to support WMI-based hotkeys on Eee PC laptops.
+
+ To compile this driver as a module, choose M here: the module will
+ be called eeepc-wmi.
config ACPI_WMI
tristate "WMI"
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 9cd9fa0a27e..a906490e353 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -4,6 +4,7 @@
#
obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
+obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 226b3e93498..1ea6c434d33 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -36,6 +36,7 @@
#include <linux/rfkill.h>
#include <linux/workqueue.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <acpi/acpi_drivers.h>
@@ -922,9 +923,13 @@ static struct backlight_ops acer_bl_ops = {
static int __devinit acer_backlight_init(struct device *dev)
{
+ struct backlight_properties props;
struct backlight_device *bd;
- bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = max_brightness;
+ bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
+ &props);
if (IS_ERR(bd)) {
printk(ACER_ERR "Could not register Acer backlight device\n");
acer_backlight_device = NULL;
@@ -935,7 +940,6 @@ static int __devinit acer_backlight_init(struct device *dev)
bd->props.power = FB_BLANK_UNBLANK;
bd->props.brightness = read_brightness(bd);
- bd->props.max_brightness = max_brightness;
backlight_update_status(bd);
return 0;
}
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 791fcf32150..efe8f638890 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -49,6 +49,7 @@
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/rfkill.h>
+#include <linux/slab.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
@@ -78,15 +79,15 @@ static uint wapf = 1;
module_param(wapf, uint, 0644);
MODULE_PARM_DESC(wapf, "WAPF value");
-static uint wlan_status = 1;
-static uint bluetooth_status = 1;
+static int wlan_status = 1;
+static int bluetooth_status = 1;
-module_param(wlan_status, uint, 0644);
+module_param(wlan_status, int, 0644);
MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot "
"(0 = disabled, 1 = enabled, -1 = don't do anything). "
"default is 1");
-module_param(bluetooth_status, uint, 0644);
+module_param(bluetooth_status, int, 0644);
MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
"(0 = disabled, 1 = enabled, -1 = don't do anything). "
"default is 1");
@@ -139,7 +140,7 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
/* Backlight */
static acpi_handle lcd_switch_handle;
-static const char *lcd_switch_paths[] = {
+static char *lcd_switch_paths[] = {
"\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */
"\\_SB.PCI0.ISA.EC0._Q10", /* A1x */
"\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */
@@ -153,7 +154,7 @@ static const char *lcd_switch_paths[] = {
#define METHOD_SWITCH_DISPLAY "SDSP"
static acpi_handle display_get_handle;
-static const char *display_get_paths[] = {
+static char *display_get_paths[] = {
/* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */
"\\_SB.PCI0.P0P1.VGA.GETD",
/* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */
@@ -639,12 +640,16 @@ static int asus_backlight_init(struct asus_laptop *asus)
{
struct backlight_device *bd;
struct device *dev = &asus->platform_device->dev;
+ struct backlight_properties props;
if (!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) &&
!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) &&
lcd_switch_handle) {
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 15;
+
bd = backlight_device_register(ASUS_LAPTOP_FILE, dev,
- asus, &asusbl_ops);
+ asus, &asusbl_ops, &props);
if (IS_ERR(bd)) {
pr_err("Could not register asus backlight device\n");
asus->backlight_device = NULL;
@@ -653,7 +658,6 @@ static int asus_backlight_init(struct asus_laptop *asus)
asus->backlight_device = bd;
- bd->props.max_brightness = 15;
bd->props.power = FB_BLANK_UNBLANK;
bd->props.brightness = asus_read_brightness(bd);
backlight_update_status(bd);
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
index 1381430e110..92fd30c9379 100644
--- a/drivers/platform/x86/asus_acpi.c
+++ b/drivers/platform/x86/asus_acpi.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
@@ -1481,6 +1482,7 @@ static void asus_acpi_exit(void)
static int __init asus_acpi_init(void)
{
+ struct backlight_properties props;
int result;
result = acpi_bus_register_driver(&asus_hotk_driver);
@@ -1507,15 +1509,17 @@ static int __init asus_acpi_init(void)
return -ENODEV;
}
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 15;
asus_backlight_device = backlight_device_register("asus", NULL, NULL,
- &asus_backlight_data);
+ &asus_backlight_data,
+ &props);
if (IS_ERR(asus_backlight_device)) {
printk(KERN_ERR "Could not register asus backlight device\n");
asus_backlight_device = NULL;
asus_acpi_exit();
return -ENODEV;
}
- asus_backlight_device->props.max_brightness = 15;
return 0;
}
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c
index 035a7dd65a3..7f9e5ddc949 100644
--- a/drivers/platform/x86/classmate-laptop.c
+++ b/drivers/platform/x86/classmate-laptop.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <acpi/acpi_drivers.h>
#include <linux/backlight.h>
@@ -455,18 +456,22 @@ static int cmpc_bl_update_status(struct backlight_device *bd)
return -1;
}
-static struct backlight_ops cmpc_bl_ops = {
+static const struct backlight_ops cmpc_bl_ops = {
.get_brightness = cmpc_bl_get_brightness,
.update_status = cmpc_bl_update_status
};
static int cmpc_bl_add(struct acpi_device *acpi)
{
+ struct backlight_properties props;
struct backlight_device *bd;
- bd = backlight_device_register("cmpc_bl", &acpi->dev,
- acpi->handle, &cmpc_bl_ops);
- bd->props.max_brightness = 7;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 7;
+ bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle,
+ &cmpc_bl_ops, &props);
+ if (IS_ERR(bd))
+ return PTR_ERR(bd);
dev_set_drvdata(&acpi->dev, bd);
return 0;
}
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
index 2740b40aad9..71ff1545a93 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -291,12 +291,15 @@ static int __init compal_init(void)
/* Register backlight stuff */
if (!acpi_video_backlight_support()) {
- compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
- &compalbl_ops);
+ struct backlight_properties props;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = COMPAL_LCD_LEVEL_MAX - 1;
+ compalbl_device = backlight_device_register("compal-laptop",
+ NULL, NULL,
+ &compalbl_ops,
+ &props);
if (IS_ERR(compalbl_device))
return PTR_ERR(compalbl_device);
-
- compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
}
ret = platform_driver_register(&compal_driver);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index ef614979afe..661e3ac4d5b 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -24,6 +24,7 @@
#include <linux/acpi.h>
#include <linux/mm.h>
#include <linux/i8042.h>
+#include <linux/slab.h>
#include "../../firmware/dcdbas.h"
#define BRIGHTNESS_TOKEN 0x7d
@@ -559,10 +560,14 @@ static int __init dell_init(void)
release_buffer();
if (max_intensity) {
- dell_backlight_device = backlight_device_register(
- "dell_backlight",
- &platform_device->dev, NULL,
- &dell_ops);
+ struct backlight_properties props;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = max_intensity;
+ dell_backlight_device = backlight_device_register("dell_backlight",
+ &platform_device->dev,
+ NULL,
+ &dell_ops,
+ &props);
if (IS_ERR(dell_backlight_device)) {
ret = PTR_ERR(dell_backlight_device);
@@ -570,7 +575,6 @@ static int __init dell_init(void)
goto fail_backlight;
}
- dell_backlight_device->props.max_brightness = max_intensity;
dell_backlight_device->props.brightness =
dell_get_intensity(dell_backlight_device);
backlight_update_status(dell_backlight_device);
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index 1b1dddbd574..66f53c3c35e 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/input.h>
#include <acpi/acpi_drivers.h>
@@ -142,7 +143,7 @@ static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap;
static struct input_dev *dell_wmi_input_dev;
-static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+static struct key_entry *dell_wmi_get_entry_by_scancode(unsigned int code)
{
struct key_entry *key;
@@ -153,7 +154,7 @@ static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
return NULL;
}
-static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+static struct key_entry *dell_wmi_get_entry_by_keycode(unsigned int keycode)
{
struct key_entry *key;
@@ -164,8 +165,8 @@ static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
return NULL;
}
-static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
- int *keycode)
+static int dell_wmi_getkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode)
{
struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
@@ -177,13 +178,11 @@ static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
return -EINVAL;
}
-static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int dell_wmi_setkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode)
{
struct key_entry *key;
- int old_keycode;
-
- if (keycode < 0 || keycode > KEY_MAX)
- return -EINVAL;
+ unsigned int old_keycode;
key = dell_wmi_get_entry_by_scancode(scancode);
if (key && key->type == KE_KEY) {
@@ -218,6 +217,7 @@ static void dell_wmi_notify(u32 value, void *context)
if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
printk(KERN_INFO "dell-wmi: Received unknown WMI event"
" (0x%x)\n", buffer_entry[1]);
+ kfree(obj);
return;
}
@@ -235,7 +235,7 @@ static void dell_wmi_notify(u32 value, void *context)
key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) {
/* Don't report brightness notifications that will also
* come via ACPI */
- return;
+ ;
} else {
input_report_key(dell_wmi_input_dev, key->keycode, 1);
input_sync(dell_wmi_input_dev);
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 9a844caa375..0306174ba87 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -27,6 +27,7 @@
#include <linux/fb.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <linux/uaccess.h>
@@ -168,7 +169,6 @@ struct eeepc_laptop {
struct backlight_device *backlight_device;
struct input_dev *inputdev;
- struct key_entry *keymap;
struct rfkill *wlan_rfkill;
struct rfkill *bluetooth_rfkill;
@@ -1131,18 +1131,20 @@ static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
{
+ struct backlight_properties props;
struct backlight_device *bd;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 15;
bd = backlight_device_register(EEEPC_LAPTOP_FILE,
- &eeepc->platform_device->dev,
- eeepc, &eeepcbl_ops);
+ &eeepc->platform_device->dev, eeepc,
+ &eeepcbl_ops, &props);
if (IS_ERR(bd)) {
pr_err("Could not register eeepc backlight device\n");
eeepc->backlight_device = NULL;
return PTR_ERR(bd);
}
eeepc->backlight_device = bd;
- bd->props.max_brightness = 15;
bd->props.brightness = read_brightness(bd);
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
@@ -1201,8 +1203,8 @@ static int eeepc_input_init(struct eeepc_laptop *eeepc)
static void eeepc_input_exit(struct eeepc_laptop *eeepc)
{
if (eeepc->inputdev) {
+ sparse_keymap_free(eeepc->inputdev);
input_unregister_device(eeepc->inputdev);
- kfree(eeepc->keymap);
}
}
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
new file mode 100644
index 00000000000..b227eb469f4
--- /dev/null
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -0,0 +1,413 @@
+/*
+ * Eee PC WMI hotkey driver
+ *
+ * Copyright(C) 2010 Intel Corporation.
+ *
+ * Portions based on wistron_btns.c:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define EEEPC_WMI_FILE "eeepc-wmi"
+
+MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
+MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
+MODULE_LICENSE("GPL");
+
+#define EEEPC_WMI_EVENT_GUID "ABBC0F72-8EA1-11D1-00A0-C90629100000"
+#define EEEPC_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
+
+MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
+MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
+
+#define NOTIFY_BRNUP_MIN 0x11
+#define NOTIFY_BRNUP_MAX 0x1f
+#define NOTIFY_BRNDOWN_MIN 0x20
+#define NOTIFY_BRNDOWN_MAX 0x2e
+
+#define EEEPC_WMI_METHODID_DEVS 0x53564544
+#define EEEPC_WMI_METHODID_DSTS 0x53544344
+
+#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012
+
+static const struct key_entry eeepc_wmi_keymap[] = {
+ /* Sleep already handled via generic ACPI code */
+ { KE_KEY, 0x5d, { KEY_WLAN } },
+ { KE_KEY, 0x32, { KEY_MUTE } },
+ { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
+ { KE_KEY, 0x30, { KEY_VOLUMEUP } },
+ { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
+ { KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } },
+ { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
+ { KE_END, 0},
+};
+
+struct bios_args {
+ u32 dev_id;
+ u32 ctrl_param;
+};
+
+struct eeepc_wmi {
+ struct input_dev *inputdev;
+ struct backlight_device *backlight_device;
+};
+
+static struct platform_device *platform_device;
+
+static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
+{
+ int err;
+
+ eeepc->inputdev = input_allocate_device();
+ if (!eeepc->inputdev)
+ return -ENOMEM;
+
+ eeepc->inputdev->name = "Eee PC WMI hotkeys";
+ eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
+ eeepc->inputdev->id.bustype = BUS_HOST;
+ eeepc->inputdev->dev.parent = &platform_device->dev;
+
+ err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
+ if (err)
+ goto err_free_dev;
+
+ err = input_register_device(eeepc->inputdev);
+ if (err)
+ goto err_free_keymap;
+
+ return 0;
+
+err_free_keymap:
+ sparse_keymap_free(eeepc->inputdev);
+err_free_dev:
+ input_free_device(eeepc->inputdev);
+ return err;
+}
+
+static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
+{
+ if (eeepc->inputdev) {
+ sparse_keymap_free(eeepc->inputdev);
+ input_unregister_device(eeepc->inputdev);
+ }
+
+ eeepc->inputdev = NULL;
+}
+
+static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *ctrl_param)
+{
+ struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+ u32 tmp;
+
+ status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
+ 1, EEEPC_WMI_METHODID_DSTS, &input, &output);
+
+ if (ACPI_FAILURE(status))
+ return status;
+
+ obj = (union acpi_object *)output.pointer;
+ if (obj && obj->type == ACPI_TYPE_INTEGER)
+ tmp = (u32)obj->integer.value;
+ else
+ tmp = 0;
+
+ if (ctrl_param)
+ *ctrl_param = tmp;
+
+ kfree(obj);
+
+ return status;
+
+}
+
+static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param)
+{
+ struct bios_args args = {
+ .dev_id = dev_id,
+ .ctrl_param = ctrl_param,
+ };
+ struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+ acpi_status status;
+
+ status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
+ 1, EEEPC_WMI_METHODID_DEVS, &input, NULL);
+
+ return status;
+}
+
+static int read_brightness(struct backlight_device *bd)
+{
+ static u32 ctrl_param;
+ acpi_status status;
+
+ status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &ctrl_param);
+
+ if (ACPI_FAILURE(status))
+ return -1;
+ else
+ return ctrl_param & 0xFF;
+}
+
+static int update_bl_status(struct backlight_device *bd)
+{
+
+ static u32 ctrl_param;
+ acpi_status status;
+
+ ctrl_param = bd->props.brightness;
+
+ status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT, ctrl_param);
+
+ if (ACPI_FAILURE(status))
+ return -1;
+ else
+ return 0;
+}
+
+static const struct backlight_ops eeepc_wmi_bl_ops = {
+ .get_brightness = read_brightness,
+ .update_status = update_bl_status,
+};
+
+static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
+{
+ struct backlight_device *bd = eeepc->backlight_device;
+ int old = bd->props.brightness;
+ int new;
+
+ if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+ new = code - NOTIFY_BRNUP_MIN + 1;
+ else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
+ new = code - NOTIFY_BRNDOWN_MIN;
+
+ bd->props.brightness = new;
+ backlight_update_status(bd);
+ backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
+
+ return old;
+}
+
+static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
+{
+ struct backlight_device *bd;
+ struct backlight_properties props;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 15;
+ bd = backlight_device_register(EEEPC_WMI_FILE,
+ &platform_device->dev, eeepc,
+ &eeepc_wmi_bl_ops, &props);
+ if (IS_ERR(bd)) {
+ pr_err("Could not register backlight device\n");
+ return PTR_ERR(bd);
+ }
+
+ eeepc->backlight_device = bd;
+
+ bd->props.brightness = read_brightness(bd);
+ bd->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(bd);
+
+ return 0;
+}
+
+static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
+{
+ if (eeepc->backlight_device)
+ backlight_device_unregister(eeepc->backlight_device);
+
+ eeepc->backlight_device = NULL;
+}
+
+static void eeepc_wmi_notify(u32 value, void *context)
+{
+ struct eeepc_wmi *eeepc = context;
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+ int code;
+ int orig_code;
+
+ status = wmi_get_event_data(value, &response);
+ if (status != AE_OK) {
+ pr_err("bad event status 0x%x\n", status);
+ return;
+ }
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (obj && obj->type == ACPI_TYPE_INTEGER) {
+ code = obj->integer.value;
+ orig_code = code;
+
+ if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+ code = NOTIFY_BRNUP_MIN;
+ else if (code >= NOTIFY_BRNDOWN_MIN &&
+ code <= NOTIFY_BRNDOWN_MAX)
+ code = NOTIFY_BRNDOWN_MIN;
+
+ if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
+ if (!acpi_video_backlight_support())
+ eeepc_wmi_backlight_notify(eeepc, orig_code);
+ }
+
+ if (!sparse_keymap_report_event(eeepc->inputdev,
+ code, 1, true))
+ pr_info("Unknown key %x pressed\n", code);
+ }
+
+ kfree(obj);
+}
+
+static int __devinit eeepc_wmi_platform_probe(struct platform_device *device)
+{
+ struct eeepc_wmi *eeepc;
+ int err;
+ acpi_status status;
+
+ eeepc = platform_get_drvdata(device);
+
+ err = eeepc_wmi_input_init(eeepc);
+ if (err)
+ goto error_input;
+
+ if (!acpi_video_backlight_support()) {
+ err = eeepc_wmi_backlight_init(eeepc);
+ if (err)
+ goto error_backlight;
+ } else
+ pr_info("Backlight controlled by ACPI video driver\n");
+
+ status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
+ eeepc_wmi_notify, eeepc);
+ if (ACPI_FAILURE(status)) {
+ pr_err("Unable to register notify handler - %d\n",
+ status);
+ err = -ENODEV;
+ goto error_wmi;
+ }
+
+ return 0;
+
+error_wmi:
+ eeepc_wmi_backlight_exit(eeepc);
+error_backlight:
+ eeepc_wmi_input_exit(eeepc);
+error_input:
+ return err;
+}
+
+static int __devexit eeepc_wmi_platform_remove(struct platform_device *device)
+{
+ struct eeepc_wmi *eeepc;
+
+ eeepc = platform_get_drvdata(device);
+ wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
+ eeepc_wmi_backlight_exit(eeepc);
+ eeepc_wmi_input_exit(eeepc);
+
+ return 0;
+}
+
+static struct platform_driver platform_driver = {
+ .driver = {
+ .name = EEEPC_WMI_FILE,
+ .owner = THIS_MODULE,
+ },
+ .probe = eeepc_wmi_platform_probe,
+ .remove = __devexit_p(eeepc_wmi_platform_remove),
+};
+
+static int __init eeepc_wmi_init(void)
+{
+ struct eeepc_wmi *eeepc;
+ int err;
+
+ if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
+ !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
+ pr_warning("No known WMI GUID found\n");
+ return -ENODEV;
+ }
+
+ eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
+ if (!eeepc)
+ return -ENOMEM;
+
+ platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
+ if (!platform_device) {
+ pr_warning("Unable to allocate platform device\n");
+ err = -ENOMEM;
+ goto fail_platform;
+ }
+
+ err = platform_device_add(platform_device);
+ if (err) {
+ pr_warning("Unable to add platform device\n");
+ goto put_dev;
+ }
+
+ platform_set_drvdata(platform_device, eeepc);
+
+ err = platform_driver_register(&platform_driver);
+ if (err) {
+ pr_warning("Unable to register platform driver\n");
+ goto del_dev;
+ }
+
+ return 0;
+
+del_dev:
+ platform_device_del(platform_device);
+put_dev:
+ platform_device_put(platform_device);
+fail_platform:
+ kfree(eeepc);
+
+ return err;
+}
+
+static void __exit eeepc_wmi_exit(void)
+{
+ struct eeepc_wmi *eeepc;
+
+ eeepc = platform_get_drvdata(platform_device);
+ platform_driver_unregister(&platform_driver);
+ platform_device_unregister(platform_device);
+ kfree(eeepc);
+}
+
+module_init(eeepc_wmi_init);
+module_exit(eeepc_wmi_exit);
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 5f3320d468f..47b4fd75aa3 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -66,6 +66,7 @@
#include <linux/kfifo.h>
#include <linux/video_output.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
#include <linux/leds.h>
#endif
@@ -1126,16 +1127,20 @@ static int __init fujitsu_init(void)
/* Register backlight stuff */
if (!acpi_video_backlight_support()) {
- fujitsu->bl_device =
- backlight_device_register("fujitsu-laptop", NULL, NULL,
- &fujitsubl_ops);
+ struct backlight_properties props;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ max_brightness = fujitsu->max_brightness;
+ props.max_brightness = max_brightness - 1;
+ fujitsu->bl_device = backlight_device_register("fujitsu-laptop",
+ NULL, NULL,
+ &fujitsubl_ops,
+ &props);
if (IS_ERR(fujitsu->bl_device)) {
ret = PTR_ERR(fujitsu->bl_device);
fujitsu->bl_device = NULL;
goto fail_sysfs_group;
}
- max_brightness = fujitsu->max_brightness;
- fujitsu->bl_device->props.max_brightness = max_brightness - 1;
fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
}
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 3aa57da8b43..51c07a05a7b 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/input.h>
#include <acpi/acpi_drivers.h>
@@ -57,7 +58,7 @@ enum hp_wmi_radio {
HPWMI_WWAN = 2,
};
-static int __init hp_wmi_bios_setup(struct platform_device *device);
+static int __devinit hp_wmi_bios_setup(struct platform_device *device);
static int __exit hp_wmi_bios_remove(struct platform_device *device);
static int hp_wmi_resume_handler(struct device *device);
@@ -278,7 +279,7 @@ static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
-static struct key_entry *hp_wmi_get_entry_by_scancode(int code)
+static struct key_entry *hp_wmi_get_entry_by_scancode(unsigned int code)
{
struct key_entry *key;
@@ -289,7 +290,7 @@ static struct key_entry *hp_wmi_get_entry_by_scancode(int code)
return NULL;
}
-static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode)
+static struct key_entry *hp_wmi_get_entry_by_keycode(unsigned int keycode)
{
struct key_entry *key;
@@ -300,7 +301,8 @@ static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode)
return NULL;
}
-static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int hp_wmi_getkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode)
{
struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode);
@@ -312,13 +314,11 @@ static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode)
return -EINVAL;
}
-static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int hp_wmi_setkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode)
{
struct key_entry *key;
- int old_keycode;
-
- if (keycode < 0 || keycode > KEY_MAX)
- return -EINVAL;
+ unsigned int old_keycode;
key = hp_wmi_get_entry_by_scancode(scancode);
if (key && key->type == KE_KEY) {
@@ -447,7 +447,7 @@ static void cleanup_sysfs(struct platform_device *device)
device_remove_file(&device->dev, &dev_attr_tablet);
}
-static int __init hp_wmi_bios_setup(struct platform_device *device)
+static int __devinit hp_wmi_bios_setup(struct platform_device *device)
{
int err;
int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index f0a90a6bf39..2f795ce2b93 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/pm.h>
@@ -396,6 +397,7 @@ static int intel_menlow_add_one_attribute(char *name, int mode, void *show,
if (!attr)
return -ENOMEM;
+ sysfs_attr_init(&attr->attr.attr); /* That is consistent naming :D */
attr->attr.attr.name = name;
attr->attr.attr.mode = mode;
attr->attr.show = show;
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
index 759763d18e4..996223a7c00 100644
--- a/drivers/platform/x86/msi-laptop.c
+++ b/drivers/platform/x86/msi-laptop.c
@@ -58,6 +58,7 @@
#include <linux/dmi.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
+#include <linux/rfkill.h>
#define MSI_DRIVER_VERSION "0.5"
@@ -66,6 +67,20 @@
#define MSI_EC_COMMAND_WIRELESS 0x10
#define MSI_EC_COMMAND_LCD_LEVEL 0x11
+#define MSI_STANDARD_EC_COMMAND_ADDRESS 0x2e
+#define MSI_STANDARD_EC_BLUETOOTH_MASK (1 << 0)
+#define MSI_STANDARD_EC_WEBCAM_MASK (1 << 1)
+#define MSI_STANDARD_EC_WLAN_MASK (1 << 3)
+#define MSI_STANDARD_EC_3G_MASK (1 << 4)
+
+/* For set SCM load flag to disable BIOS fn key */
+#define MSI_STANDARD_EC_SCM_LOAD_ADDRESS 0x2d
+#define MSI_STANDARD_EC_SCM_LOAD_MASK (1 << 0)
+
+static int msi_laptop_resume(struct platform_device *device);
+
+#define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f
+
static int force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -74,6 +89,23 @@ static int auto_brightness;
module_param(auto_brightness, int, 0);
MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)");
+static bool old_ec_model;
+static int wlan_s, bluetooth_s, threeg_s;
+static int threeg_exists;
+
+/* Some MSI 3G netbook only have one fn key to control Wlan/Bluetooth/3G,
+ * those netbook will load the SCM (windows app) to disable the original
+ * Wlan/Bluetooth control by BIOS when user press fn key, then control
+ * Wlan/Bluetooth/3G by SCM (software control by OS). Without SCM, user
+ * cann't on/off 3G module on those 3G netbook.
+ * On Linux, msi-laptop driver will do the same thing to disable the
+ * original BIOS control, then might need use HAL or other userland
+ * application to do the software control that simulate with SCM.
+ * e.g. MSI N034 netbook
+ */
+static bool load_scm_model;
+static struct rfkill *rfk_wlan, *rfk_bluetooth, *rfk_threeg;
+
/* Hardware access */
static int set_lcd_level(int level)
@@ -130,6 +162,35 @@ static int set_auto_brightness(int enable)
return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1);
}
+static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
+{
+ int status;
+ u8 wdata = 0, rdata;
+ int result;
+
+ if (sscanf(buf, "%i", &status) != 1 || (status < 0 || status > 1))
+ return -EINVAL;
+
+ /* read current device state */
+ result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
+ if (result < 0)
+ return -EINVAL;
+
+ if (!!(rdata & mask) != status) {
+ /* reverse device bit */
+ if (rdata & mask)
+ wdata = rdata & ~mask;
+ else
+ wdata = rdata | mask;
+
+ result = ec_write(MSI_STANDARD_EC_COMMAND_ADDRESS, wdata);
+ if (result < 0)
+ return -EINVAL;
+ }
+
+ return count;
+}
+
static int get_wireless_state(int *wlan, int *bluetooth)
{
u8 wdata = 0, rdata;
@@ -148,6 +209,38 @@ static int get_wireless_state(int *wlan, int *bluetooth)
return 0;
}
+static int get_wireless_state_ec_standard(void)
+{
+ u8 rdata;
+ int result;
+
+ result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
+ if (result < 0)
+ return -1;
+
+ wlan_s = !!(rdata & MSI_STANDARD_EC_WLAN_MASK);
+
+ bluetooth_s = !!(rdata & MSI_STANDARD_EC_BLUETOOTH_MASK);
+
+ threeg_s = !!(rdata & MSI_STANDARD_EC_3G_MASK);
+
+ return 0;
+}
+
+static int get_threeg_exists(void)
+{
+ u8 rdata;
+ int result;
+
+ result = ec_read(MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS, &rdata);
+ if (result < 0)
+ return -1;
+
+ threeg_exists = !!(rdata & MSI_STANDARD_EC_3G_MASK);
+
+ return 0;
+}
+
/* Backlight device stuff */
static int bl_get_brightness(struct backlight_device *b)
@@ -176,26 +269,71 @@ static ssize_t show_wlan(struct device *dev,
int ret, enabled;
- ret = get_wireless_state(&enabled, NULL);
+ if (old_ec_model) {
+ ret = get_wireless_state(&enabled, NULL);
+ } else {
+ ret = get_wireless_state_ec_standard();
+ enabled = wlan_s;
+ }
if (ret < 0)
return ret;
return sprintf(buf, "%i\n", enabled);
}
+static ssize_t store_wlan(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return set_device_state(buf, count, MSI_STANDARD_EC_WLAN_MASK);
+}
+
static ssize_t show_bluetooth(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret, enabled;
- ret = get_wireless_state(NULL, &enabled);
+ if (old_ec_model) {
+ ret = get_wireless_state(NULL, &enabled);
+ } else {
+ ret = get_wireless_state_ec_standard();
+ enabled = bluetooth_s;
+ }
if (ret < 0)
return ret;
return sprintf(buf, "%i\n", enabled);
}
+static ssize_t store_bluetooth(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return set_device_state(buf, count, MSI_STANDARD_EC_BLUETOOTH_MASK);
+}
+
+static ssize_t show_threeg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+ int ret;
+
+ /* old msi ec not support 3G */
+ if (old_ec_model)
+ return -1;
+
+ ret = get_wireless_state_ec_standard();
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%i\n", threeg_s);
+}
+
+static ssize_t store_threeg(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return set_device_state(buf, count, MSI_STANDARD_EC_3G_MASK);
+}
+
static ssize_t show_lcd_level(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -258,6 +396,7 @@ static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness);
static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL);
static DEVICE_ATTR(wlan, 0444, show_wlan, NULL);
+static DEVICE_ATTR(threeg, 0444, show_threeg, NULL);
static struct attribute *msipf_attributes[] = {
&dev_attr_lcd_level.attr,
@@ -275,7 +414,8 @@ static struct platform_driver msipf_driver = {
.driver = {
.name = "msi-laptop-pf",
.owner = THIS_MODULE,
- }
+ },
+ .resume = msi_laptop_resume,
};
static struct platform_device *msipf_device;
@@ -332,6 +472,192 @@ static struct dmi_system_id __initdata msi_dmi_table[] = {
{ }
};
+static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = {
+ {
+ .ident = "MSI N034",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "MICRO-STAR INTERNATIONAL CO., LTD"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MS-N034"),
+ DMI_MATCH(DMI_CHASSIS_VENDOR,
+ "MICRO-STAR INTERNATIONAL CO., LTD")
+ },
+ .callback = dmi_check_cb
+ },
+ { }
+};
+
+static int rfkill_bluetooth_set(void *data, bool blocked)
+{
+ /* Do something with blocked...*/
+ /*
+ * blocked == false is on
+ * blocked == true is off
+ */
+ if (blocked)
+ set_device_state("0", 0, MSI_STANDARD_EC_BLUETOOTH_MASK);
+ else
+ set_device_state("1", 0, MSI_STANDARD_EC_BLUETOOTH_MASK);
+
+ return 0;
+}
+
+static int rfkill_wlan_set(void *data, bool blocked)
+{
+ if (blocked)
+ set_device_state("0", 0, MSI_STANDARD_EC_WLAN_MASK);
+ else
+ set_device_state("1", 0, MSI_STANDARD_EC_WLAN_MASK);
+
+ return 0;
+}
+
+static int rfkill_threeg_set(void *data, bool blocked)
+{
+ if (blocked)
+ set_device_state("0", 0, MSI_STANDARD_EC_3G_MASK);
+ else
+ set_device_state("1", 0, MSI_STANDARD_EC_3G_MASK);
+
+ return 0;
+}
+
+static struct rfkill_ops rfkill_bluetooth_ops = {
+ .set_block = rfkill_bluetooth_set
+};
+
+static struct rfkill_ops rfkill_wlan_ops = {
+ .set_block = rfkill_wlan_set
+};
+
+static struct rfkill_ops rfkill_threeg_ops = {
+ .set_block = rfkill_threeg_set
+};
+
+static void rfkill_cleanup(void)
+{
+ if (rfk_bluetooth) {
+ rfkill_unregister(rfk_bluetooth);
+ rfkill_destroy(rfk_bluetooth);
+ }
+
+ if (rfk_threeg) {
+ rfkill_unregister(rfk_threeg);
+ rfkill_destroy(rfk_threeg);
+ }
+
+ if (rfk_wlan) {
+ rfkill_unregister(rfk_wlan);
+ rfkill_destroy(rfk_wlan);
+ }
+}
+
+static int rfkill_init(struct platform_device *sdev)
+{
+ /* add rfkill */
+ int retval;
+
+ rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev,
+ RFKILL_TYPE_BLUETOOTH,
+ &rfkill_bluetooth_ops, NULL);
+ if (!rfk_bluetooth) {
+ retval = -ENOMEM;
+ goto err_bluetooth;
+ }
+ retval = rfkill_register(rfk_bluetooth);
+ if (retval)
+ goto err_bluetooth;
+
+ rfk_wlan = rfkill_alloc("msi-wlan", &sdev->dev, RFKILL_TYPE_WLAN,
+ &rfkill_wlan_ops, NULL);
+ if (!rfk_wlan) {
+ retval = -ENOMEM;
+ goto err_wlan;
+ }
+ retval = rfkill_register(rfk_wlan);
+ if (retval)
+ goto err_wlan;
+
+ if (threeg_exists) {
+ rfk_threeg = rfkill_alloc("msi-threeg", &sdev->dev,
+ RFKILL_TYPE_WWAN, &rfkill_threeg_ops, NULL);
+ if (!rfk_threeg) {
+ retval = -ENOMEM;
+ goto err_threeg;
+ }
+ retval = rfkill_register(rfk_threeg);
+ if (retval)
+ goto err_threeg;
+ }
+
+ return 0;
+
+err_threeg:
+ rfkill_destroy(rfk_threeg);
+ if (rfk_wlan)
+ rfkill_unregister(rfk_wlan);
+err_wlan:
+ rfkill_destroy(rfk_wlan);
+ if (rfk_bluetooth)
+ rfkill_unregister(rfk_bluetooth);
+err_bluetooth:
+ rfkill_destroy(rfk_bluetooth);
+
+ return retval;
+}
+
+static int msi_laptop_resume(struct platform_device *device)
+{
+ u8 data;
+ int result;
+
+ if (!load_scm_model)
+ return 0;
+
+ /* set load SCM to disable hardware control by fn key */
+ result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data);
+ if (result < 0)
+ return result;
+
+ result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS,
+ data | MSI_STANDARD_EC_SCM_LOAD_MASK);
+ if (result < 0)
+ return result;
+
+ return 0;
+}
+
+static int load_scm_model_init(struct platform_device *sdev)
+{
+ u8 data;
+ int result;
+
+ /* allow userland write sysfs file */
+ dev_attr_bluetooth.store = store_bluetooth;
+ dev_attr_wlan.store = store_wlan;
+ dev_attr_threeg.store = store_threeg;
+ dev_attr_bluetooth.attr.mode |= S_IWUSR;
+ dev_attr_wlan.attr.mode |= S_IWUSR;
+ dev_attr_threeg.attr.mode |= S_IWUSR;
+
+ /* disable hardware control by fn key */
+ result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data);
+ if (result < 0)
+ return result;
+
+ result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS,
+ data | MSI_STANDARD_EC_SCM_LOAD_MASK);
+ if (result < 0)
+ return result;
+
+ /* initial rfkill */
+ result = rfkill_init(sdev);
+ if (result < 0)
+ return result;
+
+ return 0;
+}
+
static int __init msi_init(void)
{
int ret;
@@ -339,8 +665,14 @@ static int __init msi_init(void)
if (acpi_disabled)
return -ENODEV;
- if (!force && !dmi_check_system(msi_dmi_table))
- return -ENODEV;
+ if (force || dmi_check_system(msi_dmi_table))
+ old_ec_model = 1;
+
+ if (!old_ec_model)
+ get_threeg_exists();
+
+ if (!old_ec_model && dmi_check_system(msi_load_scm_models_dmi_table))
+ load_scm_model = 1;
if (auto_brightness < 0 || auto_brightness > 2)
return -EINVAL;
@@ -351,11 +683,14 @@ static int __init msi_init(void)
printk(KERN_INFO "MSI: Brightness ignored, must be controlled "
"by ACPI video driver\n");
} else {
+ struct backlight_properties props;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = MSI_LCD_LEVEL_MAX - 1;
msibl_device = backlight_device_register("msi-laptop-bl", NULL,
- NULL, &msibl_ops);
+ NULL, &msibl_ops,
+ &props);
if (IS_ERR(msibl_device))
return PTR_ERR(msibl_device);
- msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
}
ret = platform_driver_register(&msipf_driver);
@@ -374,10 +709,23 @@ static int __init msi_init(void)
if (ret)
goto fail_platform_device1;
+ if (load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
+ ret = -EINVAL;
+ goto fail_platform_device1;
+ }
+
ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group);
if (ret)
goto fail_platform_device2;
+ if (!old_ec_model) {
+ if (threeg_exists)
+ ret = device_create_file(&msipf_device->dev,
+ &dev_attr_threeg);
+ if (ret)
+ goto fail_platform_device2;
+ }
+
/* Disable automatic brightness control by default because
* this module was probably loaded to do brightness control in
* software. */
@@ -412,10 +760,14 @@ static void __exit msi_cleanup(void)
{
sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
+ if (!old_ec_model && threeg_exists)
+ device_remove_file(&msipf_device->dev, &dev_attr_threeg);
platform_device_unregister(msipf_device);
platform_driver_unregister(&msipf_driver);
backlight_device_unregister(msibl_device);
+ rfkill_cleanup();
+
/* Enable automatic brightness control again */
if (auto_brightness != 2)
set_auto_brightness(1);
@@ -435,3 +787,4 @@ MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO.,LTD:pnMS-1013:pvr0131*:cvnMICRO-STARIN
MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*");
MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
+MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*");
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c
index f5f70d4c691..d1736009636 100644
--- a/drivers/platform/x86/msi-wmi.c
+++ b/drivers/platform/x86/msi-wmi.c
@@ -26,6 +26,7 @@
#include <linux/input/sparse-keymap.h>
#include <linux/acpi.h>
#include <linux/backlight.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
MODULE_DESCRIPTION("MSI laptop WMI hotkeys driver");
@@ -138,7 +139,7 @@ static int bl_set_status(struct backlight_device *bd)
return msi_wmi_set_block(0, backlight_map[bright]);
}
-static struct backlight_ops msi_backlight_ops = {
+static const struct backlight_ops msi_backlight_ops = {
.get_brightness = bl_get,
.update_status = bl_set_status,
};
@@ -249,12 +250,17 @@ static int __init msi_wmi_init(void)
goto err_uninstall_notifier;
if (!acpi_video_backlight_support()) {
- backlight = backlight_device_register(DRV_NAME,
- NULL, NULL, &msi_backlight_ops);
- if (IS_ERR(backlight))
+ struct backlight_properties props;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
+ backlight = backlight_device_register(DRV_NAME, NULL, NULL,
+ &msi_backlight_ops,
+ &props);
+ if (IS_ERR(backlight)) {
+ err = PTR_ERR(backlight);
goto err_free_input;
+ }
- backlight->props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
err = bl_get(NULL);
if (err < 0)
goto err_free_backlight;
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index fe7cf0188ac..2fb9a32926f 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -124,6 +124,7 @@
#include <linux/ctype.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <linux/input.h>
@@ -200,7 +201,7 @@ static struct acpi_driver acpi_pcc_driver = {
};
#define KEYMAP_SIZE 11
-static const int initial_keymap[KEYMAP_SIZE] = {
+static const unsigned int initial_keymap[KEYMAP_SIZE] = {
/* 0 */ KEY_RESERVED,
/* 1 */ KEY_BRIGHTNESSDOWN,
/* 2 */ KEY_BRIGHTNESSUP,
@@ -222,7 +223,7 @@ struct pcc_acpi {
struct acpi_device *device;
struct input_dev *input_dev;
struct backlight_device *backlight;
- int keymap[KEYMAP_SIZE];
+ unsigned int keymap[KEYMAP_SIZE];
};
struct pcc_keyinput {
@@ -352,7 +353,7 @@ static int bl_set_status(struct backlight_device *bd)
return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright);
}
-static struct backlight_ops pcc_backlight_ops = {
+static const struct backlight_ops pcc_backlight_ops = {
.get_brightness = bl_get,
.update_status = bl_set_status,
};
@@ -445,7 +446,8 @@ static struct attribute_group pcc_attr_group = {
/* hotkey input device driver */
-static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int pcc_getkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode)
{
struct pcc_acpi *pcc = input_get_drvdata(dev);
@@ -457,7 +459,7 @@ static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
return 0;
}
-static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
+static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode)
{
int i;
@@ -469,7 +471,8 @@ static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
return 0;
}
-static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int pcc_setkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode)
{
struct pcc_acpi *pcc = input_get_drvdata(dev);
int oldkeycode;
@@ -477,9 +480,6 @@ static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
if (scancode >= ARRAY_SIZE(pcc->keymap))
return -EINVAL;
- if (keycode < 0 || keycode > KEY_MAX)
- return -EINVAL;
-
oldkeycode = pcc->keymap[scancode];
pcc->keymap[scancode] = keycode;
@@ -601,6 +601,7 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device)
static int acpi_pcc_hotkey_add(struct acpi_device *device)
{
+ struct backlight_properties props;
struct pcc_acpi *pcc;
int num_sifr, result;
@@ -638,24 +639,25 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Error installing keyinput handler\n"));
- goto out_sinf;
+ goto out_hotkey;
}
- /* initialize backlight */
- pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
- &pcc_backlight_ops);
- if (IS_ERR(pcc->backlight))
- goto out_input;
-
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Couldn't retrieve BIOS data\n"));
- goto out_backlight;
+ goto out_input;
+ }
+ /* initialize backlight */
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = pcc->sinf[SINF_AC_MAX_BRIGHT];
+ pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
+ &pcc_backlight_ops, &props);
+ if (IS_ERR(pcc->backlight)) {
+ result = PTR_ERR(pcc->backlight);
+ goto out_sinf;
}
/* read the initial brightness setting from the hardware */
- pcc->backlight->props.max_brightness =
- pcc->sinf[SINF_AC_MAX_BRIGHT];
pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT];
/* read the initial sticky key mode from the hardware */
@@ -670,12 +672,12 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
out_backlight:
backlight_device_unregister(pcc->backlight);
+out_sinf:
+ kfree(pcc->sinf);
out_input:
input_unregister_device(pcc->input_dev);
/* no need to input_free_device() since core input API refcount and
* free()s the device */
-out_sinf:
- kfree(pcc->sinf);
out_hotkey:
kfree(pcc);
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 3f71a605a49..1387c5f9c24 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -58,6 +58,7 @@
#include <linux/kfifo.h>
#include <linux/workqueue.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>
@@ -145,7 +146,7 @@ struct sony_laptop_input_s {
struct input_dev *key_dev;
struct kfifo fifo;
spinlock_t fifo_lock;
- struct workqueue_struct *wq;
+ struct timer_list release_key_timer;
};
static struct sony_laptop_input_s sony_laptop_input = {
@@ -299,20 +300,26 @@ static int sony_laptop_input_keycode_map[] = {
};
/* release buttons after a short delay if pressed */
-static void do_sony_laptop_release_key(struct work_struct *work)
+static void do_sony_laptop_release_key(unsigned long unused)
{
struct sony_laptop_keypress kp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sony_laptop_input.fifo_lock, flags);
- while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
- sizeof(kp), &sony_laptop_input.fifo_lock)
- == sizeof(kp)) {
- msleep(10);
+ if (kfifo_out(&sony_laptop_input.fifo,
+ (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) {
input_report_key(kp.dev, kp.key, 0);
input_sync(kp.dev);
}
+
+ /* If there is something in the fifo schedule next release. */
+ if (kfifo_len(&sony_laptop_input.fifo) != 0)
+ mod_timer(&sony_laptop_input.release_key_timer,
+ jiffies + msecs_to_jiffies(10));
+
+ spin_unlock_irqrestore(&sony_laptop_input.fifo_lock, flags);
}
-static DECLARE_WORK(sony_laptop_release_key_work,
- do_sony_laptop_release_key);
/* forward event to the input subsystem */
static void sony_laptop_report_input_event(u8 event)
@@ -366,13 +373,13 @@ static void sony_laptop_report_input_event(u8 event)
/* we emit the scancode so we can always remap the key */
input_event(kp.dev, EV_MSC, MSC_SCAN, event);
input_sync(kp.dev);
- kfifo_in_locked(&sony_laptop_input.fifo,
- (unsigned char *)&kp, sizeof(kp),
- &sony_laptop_input.fifo_lock);
- if (!work_pending(&sony_laptop_release_key_work))
- queue_work(sony_laptop_input.wq,
- &sony_laptop_release_key_work);
+ /* schedule key release */
+ kfifo_in_locked(&sony_laptop_input.fifo,
+ (unsigned char *)&kp, sizeof(kp),
+ &sony_laptop_input.fifo_lock);
+ mod_timer(&sony_laptop_input.release_key_timer,
+ jiffies + msecs_to_jiffies(10));
} else
dprintk("unknown input event %.2x\n", event);
}
@@ -390,27 +397,21 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
/* kfifo */
spin_lock_init(&sony_laptop_input.fifo_lock);
- error =
- kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
+ error = kfifo_alloc(&sony_laptop_input.fifo,
+ SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
if (error) {
printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
goto err_dec_users;
}
- /* init workqueue */
- sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
- if (!sony_laptop_input.wq) {
- printk(KERN_ERR DRV_PFX
- "Unable to create workqueue.\n");
- error = -ENXIO;
- goto err_free_kfifo;
- }
+ setup_timer(&sony_laptop_input.release_key_timer,
+ do_sony_laptop_release_key, 0);
/* input keys */
key_dev = input_allocate_device();
if (!key_dev) {
error = -ENOMEM;
- goto err_destroy_wq;
+ goto err_free_kfifo;
}
key_dev->name = "Sony Vaio Keys";
@@ -419,18 +420,15 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
key_dev->dev.parent = &acpi_device->dev;
/* Initialize the Input Drivers: special keys */
- set_bit(EV_KEY, key_dev->evbit);
- set_bit(EV_MSC, key_dev->evbit);
- set_bit(MSC_SCAN, key_dev->mscbit);
+ input_set_capability(key_dev, EV_MSC, MSC_SCAN);
+
+ __set_bit(EV_KEY, key_dev->evbit);
key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]);
key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map);
key_dev->keycode = &sony_laptop_input_keycode_map;
- for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) {
- if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) {
- set_bit(sony_laptop_input_keycode_map[i],
- key_dev->keybit);
- }
- }
+ for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++)
+ __set_bit(sony_laptop_input_keycode_map[i], key_dev->keybit);
+ __clear_bit(KEY_RESERVED, key_dev->keybit);
error = input_register_device(key_dev);
if (error)
@@ -450,9 +448,8 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
key_dev->dev.parent = &acpi_device->dev;
- jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
- jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
- jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
+ input_set_capability(jog_dev, EV_KEY, BTN_MIDDLE);
+ input_set_capability(jog_dev, EV_REL, REL_WHEEL);
error = input_register_device(jog_dev);
if (error)
@@ -473,9 +470,6 @@ err_unregister_keydev:
err_free_keydev:
input_free_device(key_dev);
-err_destroy_wq:
- destroy_workqueue(sony_laptop_input.wq);
-
err_free_kfifo:
kfifo_free(&sony_laptop_input.fifo);
@@ -486,12 +480,23 @@ err_dec_users:
static void sony_laptop_remove_input(void)
{
- /* cleanup only after the last user has gone */
+ struct sony_laptop_keypress kp = { NULL };
+
+ /* Cleanup only after the last user has gone */
if (!atomic_dec_and_test(&sony_laptop_input.users))
return;
- /* flush workqueue first */
- flush_workqueue(sony_laptop_input.wq);
+ del_timer_sync(&sony_laptop_input.release_key_timer);
+
+ /*
+ * Generate key-up events for remaining keys. Note that we don't
+ * need locking since nobody is adding new events to the kfifo.
+ */
+ while (kfifo_out(&sony_laptop_input.fifo,
+ (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) {
+ input_report_key(kp.dev, kp.key, 0);
+ input_sync(kp.dev);
+ }
/* destroy input devs */
input_unregister_device(sony_laptop_input.key_dev);
@@ -502,7 +507,6 @@ static void sony_laptop_remove_input(void)
sony_laptop_input.jog_dev = NULL;
}
- destroy_workqueue(sony_laptop_input.wq);
kfifo_free(&sony_laptop_input.fifo);
}
@@ -1288,9 +1292,13 @@ static int sony_nc_add(struct acpi_device *device)
"controlled by ACPI video driver\n");
} else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
&handle))) {
+ struct backlight_properties props;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = SONY_MAX_BRIGHTNESS - 1;
sony_backlight_device = backlight_device_register("sony", NULL,
NULL,
- &sony_backlight_ops);
+ &sony_backlight_ops,
+ &props);
if (IS_ERR(sony_backlight_device)) {
printk(KERN_WARNING DRV_PFX "unable to register backlight device\n");
@@ -1299,8 +1307,6 @@ static int sony_nc_add(struct acpi_device *device)
sony_backlight_device->props.brightness =
sony_backlight_get_brightness
(sony_backlight_device);
- sony_backlight_device->props.max_brightness =
- SONY_MAX_BRIGHTNESS - 1;
}
}
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c
index dd33b51c348..1fe0f1feff7 100644
--- a/drivers/platform/x86/tc1100-wmi.c
+++ b/drivers/platform/x86/tc1100-wmi.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <acpi/acpi.h>
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index e7b0c3bcef8..63290b33c87 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -58,6 +58,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/nvram.h>
#include <linux/proc_fs.h>
@@ -1668,7 +1669,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
* Table of recommended minimum BIOS versions
*
* Reasons for listing:
- * 1. Stable BIOS, listed because the unknown ammount of
+ * 1. Stable BIOS, listed because the unknown amount of
* bugs and bad ACPI behaviour on older versions
*
* 2. BIOS or EC fw with known bugs that trigger on Linux
@@ -6170,6 +6171,7 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
static int __init brightness_init(struct ibm_init_struct *iibm)
{
+ struct backlight_properties props;
int b;
unsigned long quirks;
@@ -6259,9 +6261,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
printk(TPACPI_INFO
"detected a 16-level brightness capable ThinkPad\n");
- ibm_backlight_device = backlight_device_register(
- TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
- &ibm_backlight_data);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = (tp_features.bright_16levels) ? 15 : 7;
+ ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,
+ NULL, NULL,
+ &ibm_backlight_data,
+ &props);
if (IS_ERR(ibm_backlight_device)) {
int rc = PTR_ERR(ibm_backlight_device);
ibm_backlight_device = NULL;
@@ -6280,8 +6285,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
"or not on your ThinkPad\n", TPACPI_MAIL);
}
- ibm_backlight_device->props.max_brightness =
- (tp_features.bright_16levels)? 15 : 7;
ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
backlight_update_status(ibm_backlight_device);
@@ -7108,7 +7111,7 @@ static struct ibm_struct volume_driver_data = {
*
* Fan speed changes of any sort (including those caused by the
* disengaged mode) are usually done slowly by the firmware as the
- * maximum ammount of fan duty cycle change per second seems to be
+ * maximum amount of fan duty cycle change per second seems to be
* limited.
*
* Reading is not available if GFAN exists.
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c
index 02f3d4e9e66..ff4b476f195 100644
--- a/drivers/platform/x86/topstar-laptop.c
+++ b/drivers/platform/x86/topstar-laptop.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/input.h>
@@ -46,7 +47,7 @@ static struct tps_key_entry topstar_keymap[] = {
{ }
};
-static struct tps_key_entry *tps_get_key_by_scancode(int code)
+static struct tps_key_entry *tps_get_key_by_scancode(unsigned int code)
{
struct tps_key_entry *key;
@@ -57,7 +58,7 @@ static struct tps_key_entry *tps_get_key_by_scancode(int code)
return NULL;
}
-static struct tps_key_entry *tps_get_key_by_keycode(int code)
+static struct tps_key_entry *tps_get_key_by_keycode(unsigned int code)
{
struct tps_key_entry *key;
@@ -126,7 +127,8 @@ static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state)
return 0;
}
-static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int topstar_getkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode)
{
struct tps_key_entry *key = tps_get_key_by_scancode(scancode);
@@ -137,14 +139,12 @@ static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
return 0;
}
-static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int topstar_setkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode)
{
struct tps_key_entry *key;
int old_keycode;
- if (keycode < 0 || keycode > KEY_MAX)
- return -EINVAL;
-
key = tps_get_key_by_scancode(scancode);
if (!key)
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 405b969734d..37aa1479855 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -47,6 +47,7 @@
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/input.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -745,7 +746,7 @@ static struct backlight_ops toshiba_backlight_data = {
.update_status = set_lcd_status,
};
-static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code)
+static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code)
{
struct key_entry *key;
@@ -756,7 +757,7 @@ static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code)
return NULL;
}
-static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code)
+static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code)
{
struct key_entry *key;
@@ -767,8 +768,8 @@ static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code)
return NULL;
}
-static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode,
- int *keycode)
+static int toshiba_acpi_getkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode)
{
struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
@@ -780,14 +781,11 @@ static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode,
return -EINVAL;
}
-static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode,
- int keycode)
+static int toshiba_acpi_setkeycode(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode)
{
struct key_entry *key;
- int old_keycode;
-
- if (keycode < 0 || keycode > KEY_MAX)
- return -EINVAL;
+ unsigned int old_keycode;
key = toshiba_acpi_get_entry_by_scancode(scancode);
if (key && key->type == KE_KEY) {
@@ -927,6 +925,7 @@ static int __init toshiba_acpi_init(void)
u32 hci_result;
bool bt_present;
int ret = 0;
+ struct backlight_properties props;
if (acpi_disabled)
return -ENODEV;
@@ -977,10 +976,12 @@ static int __init toshiba_acpi_init(void)
}
}
+ props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
toshiba_backlight_device = backlight_device_register("toshiba",
- &toshiba_acpi.p_dev->dev,
- NULL,
- &toshiba_backlight_data);
+ &toshiba_acpi.p_dev->dev,
+ NULL,
+ &toshiba_backlight_data,
+ &props);
if (IS_ERR(toshiba_backlight_device)) {
ret = PTR_ERR(toshiba_backlight_device);
@@ -989,7 +990,6 @@ static int __init toshiba_acpi_init(void)
toshiba_acpi_exit();
return ret;
}
- toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
/* Register rfkill switch for Bluetooth */
if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 09e9918c69c..39ec5b6c2e3 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -33,6 +33,7 @@
#include <linux/device.h>
#include <linux/list.h>
#include <linux/acpi.h>
+#include <linux/slab.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 0b8d14050ef..0bab84ebb15 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -166,6 +166,9 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
resource_size_t start,
resource_size_t end, int flags);
+struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
+ resource_size_t start,
+ resource_size_t end);
extern int pnp_debug;
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 68b0c04987e..cfaf5b73540 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -278,9 +278,12 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
switch (pnp_resource_type(res)) {
case IORESOURCE_IO:
case IORESOURCE_MEM:
- pnp_printf(buffer, " %#llx-%#llx\n",
+ case IORESOURCE_BUS:
+ pnp_printf(buffer, " %#llx-%#llx%s\n",
(unsigned long long) res->start,
- (unsigned long long) res->end);
+ (unsigned long long) res->end,
+ res->flags & IORESOURCE_WINDOW ?
+ " window" : "");
break;
case IORESOURCE_IRQ:
case IORESOURCE_DMA:
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index e851160e14f..918d5f04486 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -37,7 +37,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/isapnp.h>
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 00fd3577b98..0a15664eef1 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/pnp.h>
-#include <linux/slab.h>
#include <linux/bitmap.h>
#include <linux/mutex.h>
#include "base.h"
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 5314bf630bc..f7ff628b7d9 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -21,6 +21,7 @@
#include <linux/acpi.h>
#include <linux/pnp.h>
+#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <acpi/acpi_bus.h>
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 5702b2c8691..35bb44af49b 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -24,6 +24,7 @@
#include <linux/acpi.h>
#include <linux/pci.h>
#include <linux/pnp.h>
+#include <linux/slab.h>
#include "../base.h"
#include "pnpacpi.h"
@@ -177,7 +178,8 @@ static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
}
static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
- u64 len, int io_decode)
+ u64 len, int io_decode,
+ int window)
{
int flags = 0;
u64 end = start + len - 1;
@@ -186,6 +188,8 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
flags |= IORESOURCE_IO_16BIT_ADDR;
if (len == 0 || end >= 0x10003)
flags |= IORESOURCE_DISABLED;
+ if (window)
+ flags |= IORESOURCE_WINDOW;
pnp_add_io_resource(dev, start, end, flags);
}
@@ -247,7 +251,7 @@ static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev,
static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
u64 start, u64 len,
- int write_protect)
+ int write_protect, int window)
{
int flags = 0;
u64 end = start + len - 1;
@@ -256,15 +260,47 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
flags |= IORESOURCE_DISABLED;
if (write_protect == ACPI_READ_WRITE_MEMORY)
flags |= IORESOURCE_MEM_WRITEABLE;
+ if (window)
+ flags |= IORESOURCE_WINDOW;
pnp_add_mem_resource(dev, start, end, flags);
}
+static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
+ u64 start, u64 len)
+{
+ u64 end = start + len - 1;
+
+ pnp_add_bus_resource(dev, start, end);
+}
+
+static u64 addr_space_length(struct pnp_dev *dev, u64 min, u64 max, u64 len)
+{
+ u64 max_len;
+
+ max_len = max - min + 1;
+ if (len <= max_len)
+ return len;
+
+ /*
+ * Per 6.4.3.5, _LEN cannot exceed _MAX - _MIN + 1, but some BIOSes
+ * don't do this correctly, e.g.,
+ * https://bugzilla.kernel.org/show_bug.cgi?id=15480
+ */
+ dev_info(&dev->dev,
+ "resource length %#llx doesn't fit in %#llx-%#llx, trimming\n",
+ (unsigned long long) len, (unsigned long long) min,
+ (unsigned long long) max);
+ return max_len;
+}
+
static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
struct acpi_resource *res)
{
struct acpi_resource_address64 addr, *p = &addr;
acpi_status status;
+ int window;
+ u64 len;
status = acpi_resource_to_address64(res, p);
if (!ACPI_SUCCESS(status)) {
@@ -273,37 +309,39 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
return;
}
- if (p->producer_consumer == ACPI_PRODUCER)
- return;
+ len = addr_space_length(dev, p->minimum, p->maximum, p->address_length);
+ window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
if (p->resource_type == ACPI_MEMORY_RANGE)
- pnpacpi_parse_allocated_memresource(dev,
- p->minimum, p->address_length,
- p->info.mem.write_protect);
+ pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
+ p->info.mem.write_protect, window);
else if (p->resource_type == ACPI_IO_RANGE)
- pnpacpi_parse_allocated_ioresource(dev,
- p->minimum, p->address_length,
+ pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
p->granularity == 0xfff ? ACPI_DECODE_10 :
- ACPI_DECODE_16);
+ ACPI_DECODE_16, window);
+ else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
+ pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
}
static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
struct acpi_resource *res)
{
struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
+ int window;
+ u64 len;
- if (p->producer_consumer == ACPI_PRODUCER)
- return;
+ len = addr_space_length(dev, p->minimum, p->maximum, p->address_length);
+ window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
if (p->resource_type == ACPI_MEMORY_RANGE)
- pnpacpi_parse_allocated_memresource(dev,
- p->minimum, p->address_length,
- p->info.mem.write_protect);
+ pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
+ p->info.mem.write_protect, window);
else if (p->resource_type == ACPI_IO_RANGE)
- pnpacpi_parse_allocated_ioresource(dev,
- p->minimum, p->address_length,
+ pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
p->granularity == 0xfff ? ACPI_DECODE_10 :
- ACPI_DECODE_16);
+ ACPI_DECODE_16, window);
+ else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
+ pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
}
static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
@@ -368,7 +406,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
pnpacpi_parse_allocated_ioresource(dev,
io->minimum,
io->address_length,
- io->io_decode);
+ io->io_decode, 0);
break;
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -380,7 +418,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
pnpacpi_parse_allocated_ioresource(dev,
fixed_io->address,
fixed_io->address_length,
- ACPI_DECODE_10);
+ ACPI_DECODE_10, 0);
break;
case ACPI_RESOURCE_TYPE_VENDOR:
@@ -396,21 +434,21 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
pnpacpi_parse_allocated_memresource(dev,
memory24->minimum,
memory24->address_length,
- memory24->write_protect);
+ memory24->write_protect, 0);
break;
case ACPI_RESOURCE_TYPE_MEMORY32:
memory32 = &res->data.memory32;
pnpacpi_parse_allocated_memresource(dev,
memory32->minimum,
memory32->address_length,
- memory32->write_protect);
+ memory32->write_protect, 0);
break;
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
fixed_memory32 = &res->data.fixed_memory32;
pnpacpi_parse_allocated_memresource(dev,
fixed_memory32->address,
fixed_memory32->address_length,
- fixed_memory32->write_protect);
+ fixed_memory32->write_protect, 0);
break;
case ACPI_RESOURCE_TYPE_ADDRESS16:
case ACPI_RESOURCE_TYPE_ADDRESS32:
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index fc83783c3a9..8591f6ab1b3 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -11,7 +11,6 @@
#include <linux/pnp.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/completion.h>
#include <linux/spinlock.h>
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index a5135ebe5f0..cb1f47bfee9 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -5,7 +5,6 @@
#include <linux/ctype.h>
#include <linux/pnp.h>
#include <linux/string.h>
-#include <linux/slab.h>
#ifdef CONFIG_PCI
#include <linux/pci.h>
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 64d0596bafb..2e54e6a23c7 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -8,6 +8,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
@@ -470,7 +471,8 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
unsigned long pnp_resource_type(struct resource *res)
{
return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
- IORESOURCE_IRQ | IORESOURCE_DMA);
+ IORESOURCE_IRQ | IORESOURCE_DMA |
+ IORESOURCE_BUS);
}
struct resource *pnp_get_resource(struct pnp_dev *dev,
@@ -590,6 +592,30 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
return pnp_res;
}
+struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
+ resource_size_t start,
+ resource_size_t end)
+{
+ struct pnp_resource *pnp_res;
+ struct resource *res;
+
+ pnp_res = pnp_new_resource(dev);
+ if (!pnp_res) {
+ dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n",
+ (unsigned long long) start,
+ (unsigned long long) end);
+ return NULL;
+ }
+
+ res = &pnp_res->res;
+ res->flags = IORESOURCE_BUS;
+ res->start = start;
+ res->end = end;
+
+ pnp_dbg(&dev->dev, " add %pr\n", res);
+ return pnp_res;
+}
+
/*
* Determine whether the specified resource is a possible configuration
* for this device.
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 9585c1c1cc3..f5beb24d036 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -69,8 +69,10 @@ char *pnp_resource_type_name(struct resource *res)
return "irq";
case IORESOURCE_DMA:
return "dma";
+ case IORESOURCE_BUS:
+ return "bus";
}
- return NULL;
+ return "unknown";
}
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index bf146721395..faaa9b4d0d0 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -29,6 +29,13 @@ config APM_POWER
Say Y here to enable support APM status emulation using
battery class devices.
+config MAX8925_POWER
+ tristate "MAX8925 battery charger support"
+ depends on MFD_MAX8925
+ help
+ Say Y here to enable support for the battery charger in the Maxim
+ MAX8925 PMIC.
+
config WM831X_BACKUP
tristate "WM831X backup battery charger support"
depends on MFD_WM831X
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 573597c683b..a2ba7c85c97 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
obj-$(CONFIG_PDA_POWER) += pda_power.o
obj-$(CONFIG_APM_POWER) += apm_power.o
+obj-$(CONFIG_MAX8925_POWER) += max8925_power.o
obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o
obj-$(CONFIG_WM831X_POWER) += wm831x_power.o
obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index bece33ed873..3ec9c6a8896 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -24,6 +24,7 @@
#include <linux/power_supply.h>
#include <linux/idr.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#define DRIVER_VERSION "1.1.0"
diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c
index a2e71f7b27f..d2c793cf676 100644
--- a/drivers/power/da9030_battery.c
+++ b/drivers/power/da9030_battery.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/device.h>
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
index 6f1dba5a519..3bf8d1f622e 100644
--- a/drivers/power/ds2760_battery.c
+++ b/drivers/power/ds2760_battery.c
@@ -24,6 +24,7 @@
#include <linux/jiffies.h>
#include <linux/workqueue.h>
#include <linux/pm.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c
index da14f374cb6..99c89976a90 100644
--- a/drivers/power/ds2782_battery.c
+++ b/drivers/power/ds2782_battery.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/idr.h>
#include <linux/power_supply.h>
+#include <linux/slab.h>
#define DS2782_REG_RARC 0x06 /* Remaining active relative capacity */
diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c
index 87b98bf27ae..f3e22c9fe20 100644
--- a/drivers/power/max17040_battery.c
+++ b/drivers/power/max17040_battery.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/power_supply.h>
#include <linux/max17040_battery.h>
+#include <linux/slab.h>
#define MAX17040_VCELL_MSB 0x02
#define MAX17040_VCELL_LSB 0x03
diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c
new file mode 100644
index 00000000000..8e5aec26086
--- /dev/null
+++ b/drivers/power/max8925_power.c
@@ -0,0 +1,535 @@
+/*
+ * Battery driver for Maxim MAX8925
+ *
+ * Copyright (c) 2009-2010 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/max8925.h>
+
+/* registers in GPM */
+#define MAX8925_OUT5VEN 0x54
+#define MAX8925_OUT3VEN 0x58
+#define MAX8925_CHG_CNTL1 0x7c
+
+/* bits definition */
+#define MAX8925_CHG_STAT_VSYSLOW (1 << 0)
+#define MAX8925_CHG_STAT_MODE_MASK (3 << 2)
+#define MAX8925_CHG_STAT_EN_MASK (1 << 4)
+#define MAX8925_CHG_MBDET (1 << 1)
+#define MAX8925_CHG_AC_RANGE_MASK (3 << 6)
+
+/* registers in ADC */
+#define MAX8925_ADC_RES_CNFG1 0x06
+#define MAX8925_ADC_AVG_CNFG1 0x07
+#define MAX8925_ADC_ACQ_CNFG1 0x08
+#define MAX8925_ADC_ACQ_CNFG2 0x09
+/* 2 bytes registers in below. MSB is 1st, LSB is 2nd. */
+#define MAX8925_ADC_AUX2 0x62
+#define MAX8925_ADC_VCHG 0x64
+#define MAX8925_ADC_VBBATT 0x66
+#define MAX8925_ADC_VMBATT 0x68
+#define MAX8925_ADC_ISNS 0x6a
+#define MAX8925_ADC_THM 0x6c
+#define MAX8925_ADC_TDIE 0x6e
+#define MAX8925_CMD_AUX2 0xc8
+#define MAX8925_CMD_VCHG 0xd0
+#define MAX8925_CMD_VBBATT 0xd8
+#define MAX8925_CMD_VMBATT 0xe0
+#define MAX8925_CMD_ISNS 0xe8
+#define MAX8925_CMD_THM 0xf0
+#define MAX8925_CMD_TDIE 0xf8
+
+enum {
+ MEASURE_AUX2,
+ MEASURE_VCHG,
+ MEASURE_VBBATT,
+ MEASURE_VMBATT,
+ MEASURE_ISNS,
+ MEASURE_THM,
+ MEASURE_TDIE,
+ MEASURE_MAX,
+};
+
+struct max8925_power_info {
+ struct max8925_chip *chip;
+ struct i2c_client *gpm;
+ struct i2c_client *adc;
+
+ struct power_supply ac;
+ struct power_supply usb;
+ struct power_supply battery;
+ int irq_base;
+ unsigned ac_online:1;
+ unsigned usb_online:1;
+ unsigned bat_online:1;
+ unsigned chg_mode:2;
+ unsigned batt_detect:1; /* detecing MB by ID pin */
+ unsigned topoff_threshold:2;
+ unsigned fast_charge:3;
+
+ int (*set_charger) (int);
+};
+
+static int __set_charger(struct max8925_power_info *info, int enable)
+{
+ struct max8925_chip *chip = info->chip;
+ if (enable) {
+ /* enable charger in platform */
+ if (info->set_charger)
+ info->set_charger(1);
+ /* enable charger */
+ max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 0);
+ } else {
+ /* disable charge */
+ max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
+ if (info->set_charger)
+ info->set_charger(0);
+ }
+ dev_dbg(chip->dev, "%s\n", (enable) ? "Enable charger"
+ : "Disable charger");
+ return 0;
+}
+
+static irqreturn_t max8925_charger_handler(int irq, void *data)
+{
+ struct max8925_power_info *info = (struct max8925_power_info *)data;
+ struct max8925_chip *chip = info->chip;
+
+ switch (irq - chip->irq_base) {
+ case MAX8925_IRQ_VCHG_DC_R:
+ info->ac_online = 1;
+ __set_charger(info, 1);
+ dev_dbg(chip->dev, "Adapter inserted\n");
+ break;
+ case MAX8925_IRQ_VCHG_DC_F:
+ info->ac_online = 0;
+ __set_charger(info, 0);
+ dev_dbg(chip->dev, "Adapter is removal\n");
+ break;
+ case MAX8925_IRQ_VCHG_USB_R:
+ info->usb_online = 1;
+ __set_charger(info, 1);
+ dev_dbg(chip->dev, "USB inserted\n");
+ break;
+ case MAX8925_IRQ_VCHG_USB_F:
+ info->usb_online = 0;
+ __set_charger(info, 0);
+ dev_dbg(chip->dev, "USB is removal\n");
+ break;
+ case MAX8925_IRQ_VCHG_THM_OK_F:
+ /* Battery is not ready yet */
+ dev_dbg(chip->dev, "Battery temperature is out of range\n");
+ case MAX8925_IRQ_VCHG_DC_OVP:
+ dev_dbg(chip->dev, "Error detection\n");
+ __set_charger(info, 0);
+ break;
+ case MAX8925_IRQ_VCHG_THM_OK_R:
+ /* Battery is ready now */
+ dev_dbg(chip->dev, "Battery temperature is in range\n");
+ break;
+ case MAX8925_IRQ_VCHG_SYSLOW_R:
+ /* VSYS is low */
+ dev_info(chip->dev, "Sys power is too low\n");
+ break;
+ case MAX8925_IRQ_VCHG_SYSLOW_F:
+ dev_dbg(chip->dev, "Sys power is above low threshold\n");
+ break;
+ case MAX8925_IRQ_VCHG_DONE:
+ __set_charger(info, 0);
+ dev_dbg(chip->dev, "Charging is done\n");
+ break;
+ case MAX8925_IRQ_VCHG_TOPOFF:
+ dev_dbg(chip->dev, "Charging in top-off mode\n");
+ break;
+ case MAX8925_IRQ_VCHG_TMR_FAULT:
+ __set_charger(info, 0);
+ dev_dbg(chip->dev, "Safe timer is expired\n");
+ break;
+ case MAX8925_IRQ_VCHG_RST:
+ __set_charger(info, 0);
+ dev_dbg(chip->dev, "Charger is reset\n");
+ break;
+ }
+ return IRQ_HANDLED;
+}
+
+static int start_measure(struct max8925_power_info *info, int type)
+{
+ unsigned char buf[2] = {0, 0};
+ int meas_reg = 0, ret;
+
+ switch (type) {
+ case MEASURE_VCHG:
+ meas_reg = MAX8925_ADC_VCHG;
+ break;
+ case MEASURE_VBBATT:
+ meas_reg = MAX8925_ADC_VBBATT;
+ break;
+ case MEASURE_VMBATT:
+ meas_reg = MAX8925_ADC_VMBATT;
+ break;
+ case MEASURE_ISNS:
+ meas_reg = MAX8925_ADC_ISNS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ max8925_bulk_read(info->adc, meas_reg, 2, buf);
+ ret = (buf[0] << 4) | (buf[1] >> 4);
+
+ return ret;
+}
+
+static int max8925_ac_get_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = info->ac_online;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ if (info->ac_online) {
+ ret = start_measure(info, MEASURE_VCHG);
+ if (ret >= 0) {
+ val->intval = ret << 1; /* unit is mV */
+ goto out;
+ }
+ }
+ ret = -ENODATA;
+ break;
+ default:
+ ret = -ENODEV;
+ break;
+ }
+out:
+ return ret;
+}
+
+static enum power_supply_property max8925_ac_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+};
+
+static int max8925_usb_get_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = info->usb_online;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ if (info->usb_online) {
+ ret = start_measure(info, MEASURE_VCHG);
+ if (ret >= 0) {
+ val->intval = ret << 1; /* unit is mV */
+ goto out;
+ }
+ }
+ ret = -ENODATA;
+ break;
+ default:
+ ret = -ENODEV;
+ break;
+ }
+out:
+ return ret;
+}
+
+static enum power_supply_property max8925_usb_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+};
+
+static int max8925_bat_get_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
+ long long int tmp = 0;
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = info->bat_online;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ if (info->bat_online) {
+ ret = start_measure(info, MEASURE_VMBATT);
+ if (ret >= 0) {
+ val->intval = ret << 1; /* unit is mV */
+ ret = 0;
+ break;
+ }
+ }
+ ret = -ENODATA;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ if (info->bat_online) {
+ ret = start_measure(info, MEASURE_ISNS);
+ if (ret >= 0) {
+ tmp = (long long int)ret * 6250 / 4096 - 3125;
+ ret = (int)tmp;
+ val->intval = 0;
+ if (ret > 0)
+ val->intval = ret; /* unit is mA */
+ ret = 0;
+ break;
+ }
+ }
+ ret = -ENODATA;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ if (!info->bat_online) {
+ ret = -ENODATA;
+ break;
+ }
+ ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
+ ret = (ret & MAX8925_CHG_STAT_MODE_MASK) >> 2;
+ switch (ret) {
+ case 1:
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
+ break;
+ case 0:
+ case 2:
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+ break;
+ case 3:
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
+ break;
+ }
+ ret = 0;
+ break;
+ case POWER_SUPPLY_PROP_STATUS:
+ if (!info->bat_online) {
+ ret = -ENODATA;
+ break;
+ }
+ ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
+ if (info->usb_online || info->ac_online) {
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ if (ret & MAX8925_CHG_STAT_EN_MASK)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ } else
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ ret = 0;
+ break;
+ default:
+ ret = -ENODEV;
+ break;
+ }
+ return ret;
+}
+
+static enum power_supply_property max8925_battery_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
+ POWER_SUPPLY_PROP_STATUS,
+};
+
+#define REQUEST_IRQ(_irq, _name) \
+do { \
+ ret = request_threaded_irq(chip->irq_base + _irq, NULL, \
+ max8925_charger_handler, \
+ IRQF_ONESHOT, _name, info); \
+ if (ret) \
+ dev_err(chip->dev, "Failed to request IRQ #%d: %d\n", \
+ _irq, ret); \
+} while (0)
+
+static __devinit int max8925_init_charger(struct max8925_chip *chip,
+ struct max8925_power_info *info)
+{
+ int ret;
+
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_DONE, "charger-done");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
+ REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
+
+ info->ac_online = 0;
+ info->usb_online = 0;
+ info->bat_online = 0;
+ ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
+ if (ret >= 0) {
+ /*
+ * If battery detection is enabled, ID pin of battery is
+ * connected to MBDET pin of MAX8925. It could be used to
+ * detect battery presence.
+ * Otherwise, we have to assume that battery is always on.
+ */
+ if (info->batt_detect)
+ info->bat_online = (ret & MAX8925_CHG_MBDET) ? 0 : 1;
+ else
+ info->bat_online = 1;
+ if (ret & MAX8925_CHG_AC_RANGE_MASK)
+ info->ac_online = 1;
+ else
+ info->ac_online = 0;
+ }
+ /* disable charge */
+ max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
+ /* set charging current in charge topoff mode */
+ max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 3 << 5,
+ info->topoff_threshold << 5);
+ /* set charing current in fast charge mode */
+ max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 7, info->fast_charge);
+
+ return 0;
+}
+
+static __devexit int max8925_deinit_charger(struct max8925_power_info *info)
+{
+ struct max8925_chip *chip = info->chip;
+ int irq;
+
+ irq = chip->irq_base + MAX8925_IRQ_VCHG_DC_OVP;
+ for (; irq <= chip->irq_base + MAX8925_IRQ_VCHG_TMR_FAULT; irq++)
+ free_irq(irq, info);
+
+ return 0;
+}
+
+static __devinit int max8925_power_probe(struct platform_device *pdev)
+{
+ struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct max8925_platform_data *max8925_pdata;
+ struct max8925_power_pdata *pdata = NULL;
+ struct max8925_power_info *info;
+ int ret;
+
+ if (pdev->dev.parent->platform_data) {
+ max8925_pdata = pdev->dev.parent->platform_data;
+ pdata = max8925_pdata->power;
+ }
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "platform data isn't assigned to "
+ "power supply\n");
+ return -EINVAL;
+ }
+
+ info = kzalloc(sizeof(struct max8925_power_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ info->chip = chip;
+ info->gpm = chip->i2c;
+ info->adc = chip->adc;
+
+ info->ac.name = "max8925-ac";
+ info->ac.type = POWER_SUPPLY_TYPE_MAINS;
+ info->ac.properties = max8925_ac_props;
+ info->ac.num_properties = ARRAY_SIZE(max8925_ac_props);
+ info->ac.get_property = max8925_ac_get_prop;
+ ret = power_supply_register(&pdev->dev, &info->ac);
+ if (ret)
+ goto out;
+ info->ac.dev->parent = &pdev->dev;
+
+ info->usb.name = "max8925-usb";
+ info->usb.type = POWER_SUPPLY_TYPE_USB;
+ info->usb.properties = max8925_usb_props;
+ info->usb.num_properties = ARRAY_SIZE(max8925_usb_props);
+ info->usb.get_property = max8925_usb_get_prop;
+ ret = power_supply_register(&pdev->dev, &info->usb);
+ if (ret)
+ goto out_usb;
+ info->usb.dev->parent = &pdev->dev;
+
+ info->battery.name = "max8925-battery";
+ info->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+ info->battery.properties = max8925_battery_props;
+ info->battery.num_properties = ARRAY_SIZE(max8925_battery_props);
+ info->battery.get_property = max8925_bat_get_prop;
+ ret = power_supply_register(&pdev->dev, &info->battery);
+ if (ret)
+ goto out_battery;
+ info->battery.dev->parent = &pdev->dev;
+
+ info->batt_detect = pdata->batt_detect;
+ info->topoff_threshold = pdata->topoff_threshold;
+ info->fast_charge = pdata->fast_charge;
+ info->set_charger = pdata->set_charger;
+ dev_set_drvdata(&pdev->dev, info);
+ platform_set_drvdata(pdev, info);
+
+ max8925_init_charger(chip, info);
+ return 0;
+out_battery:
+ power_supply_unregister(&info->battery);
+out_usb:
+ power_supply_unregister(&info->ac);
+out:
+ kfree(info);
+ return ret;
+}
+
+static __devexit int max8925_power_remove(struct platform_device *pdev)
+{
+ struct max8925_power_info *info = platform_get_drvdata(pdev);
+
+ if (info) {
+ power_supply_unregister(&info->ac);
+ power_supply_unregister(&info->usb);
+ power_supply_unregister(&info->battery);
+ max8925_deinit_charger(info);
+ kfree(info);
+ }
+ return 0;
+}
+
+static struct platform_driver max8925_power_driver = {
+ .probe = max8925_power_probe,
+ .remove = __devexit_p(max8925_power_remove),
+ .driver = {
+ .name = "max8925-power",
+ },
+};
+
+static int __init max8925_power_init(void)
+{
+ return platform_driver_register(&max8925_power_driver);
+}
+module_init(max8925_power_init);
+
+static void __exit max8925_power_exit(void)
+{
+ platform_driver_unregister(&max8925_power_driver);
+}
+module_exit(max8925_power_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Power supply driver for MAX8925");
+MODULE_ALIAS("platform:max8925-power");
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index ea3fdfaca90..066f994e6fe 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/device.h>
diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c
index 9c87ad56480..023d24993b8 100644
--- a/drivers/power/pmu_battery.c
+++ b/drivers/power/pmu_battery.c
@@ -14,6 +14,7 @@
#include <linux/power_supply.h>
#include <linux/adb.h>
#include <linux/pmu.h>
+#include <linux/slab.h>
static struct pmu_battery_dev {
struct power_supply bat;
diff --git a/drivers/power/power_supply_leds.c b/drivers/power/power_supply_leds.c
index 2dece40c544..031a554837f 100644
--- a/drivers/power/power_supply_leds.c
+++ b/drivers/power/power_supply_leds.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/power_supply.h>
+#include <linux/slab.h>
#include "power_supply.h"
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index c790e0c77d4..5b6e352ac7c 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -13,6 +13,7 @@
#include <linux/ctype.h>
#include <linux/power_supply.h>
+#include <linux/slab.h>
#include "power_supply.h"
@@ -99,6 +100,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(present),
POWER_SUPPLY_ATTR(online),
POWER_SUPPLY_ATTR(technology),
+ POWER_SUPPLY_ATTR(cycle_count),
POWER_SUPPLY_ATTR(voltage_max),
POWER_SUPPLY_ATTR(voltage_min),
POWER_SUPPLY_ATTR(voltage_max_design),
diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c
index bf4f387a800..0fd130d80f5 100644
--- a/drivers/power/wm831x_backup.c
+++ b/drivers/power/wm831x_backup.c
@@ -12,6 +12,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
+#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/auxadc.h>
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index f85e80b1b40..875c4d0f776 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -12,6 +12,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
+#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/auxadc.h>
diff --git a/drivers/power/wm8350_power.c b/drivers/power/wm8350_power.c
index ad4f071e128..0693902d615 100644
--- a/drivers/power/wm8350_power.c
+++ b/drivers/power/wm8350_power.c
@@ -190,7 +190,7 @@ static irqreturn_t wm8350_charger_handler(int irq, void *data)
struct wm8350_power *power = &wm8350->power;
struct wm8350_charger_policy *policy = power->policy;
- switch (irq) {
+ switch (irq - wm8350->irq_base) {
case WM8350_IRQ_CHG_BAT_FAIL:
dev_err(wm8350->dev, "battery failed\n");
break;
@@ -428,18 +428,18 @@ static void wm8350_init_charger(struct wm8350 *wm8350)
static void free_charger_irq(struct wm8350 *wm8350)
{
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1);
- wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85);
- wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB);
- wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB);
- wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350);
}
static __devinit int wm8350_power_probe(struct platform_device *pdev)
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c
index 23eed356a85..94c70650aaf 100644
--- a/drivers/power/wm97xx_battery.c
+++ b/drivers/power/wm97xx_battery.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/irq.h>
+#include <linux/slab.h>
static DEFINE_MUTEX(bat_lock);
static struct work_struct bat_work;
diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig
index cc2eb8edb51..1afe4e03440 100644
--- a/drivers/pps/Kconfig
+++ b/drivers/pps/Kconfig
@@ -30,4 +30,6 @@ config PPS_DEBUG
messages to the system log. Select this if you are having a
problem with PPS support and want to see more of what is going on.
+source drivers/pps/clients/Kconfig
+
endmenu
diff --git a/drivers/pps/Makefile b/drivers/pps/Makefile
index 19ea582f431..98960ddd318 100644
--- a/drivers/pps/Makefile
+++ b/drivers/pps/Makefile
@@ -4,5 +4,6 @@
pps_core-y := pps.o kapi.o sysfs.o
obj-$(CONFIG_PPS) := pps_core.o
+obj-y += clients/
ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG
diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig
new file mode 100644
index 00000000000..4e801bd7254
--- /dev/null
+++ b/drivers/pps/clients/Kconfig
@@ -0,0 +1,25 @@
+#
+# PPS clients configuration
+#
+
+if PPS
+
+comment "PPS clients support"
+
+config PPS_CLIENT_KTIMER
+ tristate "Kernel timer client (Testing client, use for debug)"
+ help
+ If you say yes here you get support for a PPS debugging client
+ which uses a kernel timer to generate the PPS signal.
+
+ This driver can also be built as a module. If so, the module
+ will be called pps-ktimer.
+
+config PPS_CLIENT_LDISC
+ tristate "PPS line discipline"
+ depends on PPS
+ help
+ If you say yes here you get support for a PPS source connected
+ with the CD (Carrier Detect) pin of your serial port.
+
+endif
diff --git a/drivers/pps/clients/Makefile b/drivers/pps/clients/Makefile
new file mode 100644
index 00000000000..812c9b19b43
--- /dev/null
+++ b/drivers/pps/clients/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for PPS clients.
+#
+
+obj-$(CONFIG_PPS_CLIENT_KTIMER) += pps-ktimer.o
+obj-$(CONFIG_PPS_CLIENT_LDISC) += pps-ldisc.o
+
+ifeq ($(CONFIG_PPS_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/pps/clients/pps-ktimer.c b/drivers/pps/clients/pps-ktimer.c
new file mode 100644
index 00000000000..e7ef5b8186d
--- /dev/null
+++ b/drivers/pps/clients/pps-ktimer.c
@@ -0,0 +1,123 @@
+/*
+ * pps-ktimer.c -- kernel timer test client
+ *
+ *
+ * Copyright (C) 2005-2006 Rodolfo Giometti <giometti@linux.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.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/pps_kernel.h>
+
+/*
+ * Global variables
+ */
+
+static int source;
+static struct timer_list ktimer;
+
+/*
+ * The kernel timer
+ */
+
+static void pps_ktimer_event(unsigned long ptr)
+{
+ struct timespec __ts;
+ struct pps_ktime ts;
+
+ /* First of all we get the time stamp... */
+ getnstimeofday(&__ts);
+
+ pr_info("PPS event at %lu\n", jiffies);
+
+ /* ... and translate it to PPS time data struct */
+ ts.sec = __ts.tv_sec;
+ ts.nsec = __ts.tv_nsec;
+
+ pps_event(source, &ts, PPS_CAPTUREASSERT, NULL);
+
+ mod_timer(&ktimer, jiffies + HZ);
+}
+
+/*
+ * The echo function
+ */
+
+static void pps_ktimer_echo(int source, int event, void *data)
+{
+ pr_info("echo %s %s for source %d\n",
+ event & PPS_CAPTUREASSERT ? "assert" : "",
+ event & PPS_CAPTURECLEAR ? "clear" : "",
+ source);
+}
+
+/*
+ * The PPS info struct
+ */
+
+static struct pps_source_info pps_ktimer_info = {
+ .name = "ktimer",
+ .path = "",
+ .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
+ PPS_ECHOASSERT |
+ PPS_CANWAIT | PPS_TSFMT_TSPEC,
+ .echo = pps_ktimer_echo,
+ .owner = THIS_MODULE,
+};
+
+/*
+ * Module staff
+ */
+
+static void __exit pps_ktimer_exit(void)
+{
+ del_timer_sync(&ktimer);
+ pps_unregister_source(source);
+
+ pr_info("ktimer PPS source unregistered\n");
+}
+
+static int __init pps_ktimer_init(void)
+{
+ int ret;
+
+ ret = pps_register_source(&pps_ktimer_info,
+ PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
+ if (ret < 0) {
+ printk(KERN_ERR "cannot register ktimer source\n");
+ return ret;
+ }
+ source = ret;
+
+ setup_timer(&ktimer, pps_ktimer_event, 0);
+ mod_timer(&ktimer, jiffies + HZ);
+
+ pr_info("ktimer PPS source registered at %d\n", source);
+
+ return 0;
+}
+
+module_init(pps_ktimer_init);
+module_exit(pps_ktimer_exit);
+
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("dummy PPS source by using a kernel timer (just for debug)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c
new file mode 100644
index 00000000000..8e1932d29fd
--- /dev/null
+++ b/drivers/pps/clients/pps-ldisc.c
@@ -0,0 +1,154 @@
+/*
+ * pps-ldisc.c -- PPS line discipline
+ *
+ *
+ * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.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.
+ */
+
+#include <linux/module.h>
+#include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/pps_kernel.h>
+
+#define PPS_TTY_MAGIC 0x0001
+
+static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status,
+ struct timespec *ts)
+{
+ int id = (long)tty->disc_data;
+ struct timespec __ts;
+ struct pps_ktime pps_ts;
+
+ /* First of all we get the time stamp... */
+ getnstimeofday(&__ts);
+
+ /* Does caller give us a timestamp? */
+ if (ts) { /* Yes. Let's use it! */
+ pps_ts.sec = ts->tv_sec;
+ pps_ts.nsec = ts->tv_nsec;
+ } else { /* No. Do it ourself! */
+ pps_ts.sec = __ts.tv_sec;
+ pps_ts.nsec = __ts.tv_nsec;
+ }
+
+ /* Now do the PPS event report */
+ pps_event(id, &pps_ts, status ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR,
+ NULL);
+
+ pr_debug("PPS %s at %lu on source #%d\n",
+ status ? "assert" : "clear", jiffies, id);
+}
+
+static int (*alias_n_tty_open)(struct tty_struct *tty);
+
+static int pps_tty_open(struct tty_struct *tty)
+{
+ struct pps_source_info info;
+ struct tty_driver *drv = tty->driver;
+ int index = tty->index + drv->name_base;
+ int ret;
+
+ info.owner = THIS_MODULE;
+ info.dev = NULL;
+ snprintf(info.name, PPS_MAX_NAME_LEN, "%s%d", drv->driver_name, index);
+ snprintf(info.path, PPS_MAX_NAME_LEN, "/dev/%s%d", drv->name, index);
+ info.mode = PPS_CAPTUREBOTH | \
+ PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \
+ PPS_CANWAIT | PPS_TSFMT_TSPEC;
+
+ ret = pps_register_source(&info, PPS_CAPTUREBOTH | \
+ PPS_OFFSETASSERT | PPS_OFFSETCLEAR);
+ if (ret < 0) {
+ pr_err("cannot register PPS source \"%s\"\n", info.path);
+ return ret;
+ }
+ tty->disc_data = (void *)(long)ret;
+
+ /* Should open N_TTY ldisc too */
+ ret = alias_n_tty_open(tty);
+ if (ret < 0)
+ pps_unregister_source((long)tty->disc_data);
+
+ pr_info("PPS source #%d \"%s\" added\n", ret, info.path);
+
+ return 0;
+}
+
+static void (*alias_n_tty_close)(struct tty_struct *tty);
+
+static void pps_tty_close(struct tty_struct *tty)
+{
+ int id = (long)tty->disc_data;
+
+ pps_unregister_source(id);
+ alias_n_tty_close(tty);
+
+ pr_info("PPS source #%d removed\n", id);
+}
+
+static struct tty_ldisc_ops pps_ldisc_ops;
+
+/*
+ * Module stuff
+ */
+
+static int __init pps_tty_init(void)
+{
+ int err;
+
+ /* Inherit the N_TTY's ops */
+ n_tty_inherit_ops(&pps_ldisc_ops);
+
+ /* Save N_TTY's open()/close() methods */
+ alias_n_tty_open = pps_ldisc_ops.open;
+ alias_n_tty_close = pps_ldisc_ops.close;
+
+ /* Init PPS_TTY data */
+ pps_ldisc_ops.owner = THIS_MODULE;
+ pps_ldisc_ops.magic = PPS_TTY_MAGIC;
+ pps_ldisc_ops.name = "pps_tty";
+ pps_ldisc_ops.dcd_change = pps_tty_dcd_change;
+ pps_ldisc_ops.open = pps_tty_open;
+ pps_ldisc_ops.close = pps_tty_close;
+
+ err = tty_register_ldisc(N_PPS, &pps_ldisc_ops);
+ if (err)
+ pr_err("can't register PPS line discipline\n");
+ else
+ pr_info("PPS line discipline registered\n");
+
+ return err;
+}
+
+static void __exit pps_tty_cleanup(void)
+{
+ int err;
+
+ err = tty_unregister_ldisc(N_PPS);
+ if (err)
+ pr_err("can't unregister PPS line discipline\n");
+ else
+ pr_info("PPS line discipline removed\n");
+}
+
+module_init(pps_tty_init);
+module_exit(pps_tty_cleanup);
+
+MODULE_ALIAS_LDISC(N_PPS);
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("PPS TTY device driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index 2d414e23d39..1aa02db3ff4 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -29,6 +29,7 @@
#include <linux/idr.h>
#include <linux/fs.h>
#include <linux/pps_kernel.h>
+#include <linux/slab.h>
/*
* Global variables
diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c
index fe96793e3f0..8000985d0e8 100644
--- a/drivers/ps3/ps3-lpm.c
+++ b/drivers/ps3/ps3-lpm.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c
index e4ad5ba5d0a..d9fb729535a 100644
--- a/drivers/ps3/ps3-vuart.c
+++ b/drivers/ps3/ps3-vuart.c
@@ -19,6 +19,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 95a689befc8..a409fa050a1 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -24,6 +24,7 @@
#include <linux/notifier.h>
#include <linux/ioctl.h>
#include <linux/fb.h>
+#include <linux/slab.h>
#include <asm/firmware.h>
#include <asm/ps3av.h>
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index 04719551381..5fb83e2ced2 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -11,15 +11,17 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
+#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
-#include <linux/mfd/88pm8607.h>
+#include <linux/mfd/88pm860x.h>
struct pm8607_regulator_info {
struct regulator_desc desc;
- struct pm8607_chip *chip;
+ struct pm860x_chip *chip;
struct regulator_dev *regulator;
+ struct i2c_client *i2c;
int min_uV;
int max_uV;
@@ -46,7 +48,6 @@ static inline int check_range(struct pm8607_regulator_info *info,
static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
- uint8_t chip_id = info->chip->chip_id;
int ret = -EINVAL;
switch (info->desc.id) {
@@ -88,79 +89,29 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
case PM8607_ID_LDO2:
case PM8607_ID_LDO3:
case PM8607_ID_LDO9:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- ret = (index < 3) ? (index * 50000 + 1800000) :
- ((index < 8) ? (index * 50000 + 2550000) :
- -EINVAL);
- break;
- case PM8607_CHIP_B0:
- ret = (index < 3) ? (index * 50000 + 1800000) :
- ((index < 7) ? (index * 50000 + 2550000) :
- 3300000);
- break;
- }
+ ret = (index < 3) ? (index * 50000 + 1800000) :
+ ((index < 7) ? (index * 50000 + 2550000) :
+ 3300000);
break;
case PM8607_ID_LDO4:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- ret = (index < 3) ? (index * 50000 + 1800000) :
- ((index < 8) ? (index * 50000 + 2550000) :
- -EINVAL);
- break;
- case PM8607_CHIP_B0:
- ret = (index < 3) ? (index * 50000 + 1800000) :
- ((index < 6) ? (index * 50000 + 2550000) :
- ((index == 6) ? 2900000 : 3300000));
- break;
- }
+ ret = (index < 3) ? (index * 50000 + 1800000) :
+ ((index < 6) ? (index * 50000 + 2550000) :
+ ((index == 6) ? 2900000 : 3300000));
break;
case PM8607_ID_LDO6:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- ret = (index < 3) ? (index * 50000 + 1800000) :
- ((index < 8) ? (index * 50000 + 2450000) :
- -EINVAL);
- break;
- case PM8607_CHIP_B0:
- ret = (index < 2) ? (index * 50000 + 1800000) :
- ((index < 7) ? (index * 50000 + 2500000) :
- 3300000);
- break;
- }
+ ret = (index < 2) ? (index * 50000 + 1800000) :
+ ((index < 7) ? (index * 50000 + 2500000) :
+ 3300000);
break;
case PM8607_ID_LDO10:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- ret = (index < 3) ? (index * 50000 + 1800000) :
- ((index < 8) ? (index * 50000 + 2550000) :
- 1200000);
- break;
- case PM8607_CHIP_B0:
- ret = (index < 3) ? (index * 50000 + 1800000) :
- ((index < 7) ? (index * 50000 + 2550000) :
- ((index == 7) ? 3300000 : 1200000));
- break;
- }
+ ret = (index < 3) ? (index * 50000 + 1800000) :
+ ((index < 7) ? (index * 50000 + 2550000) :
+ ((index == 7) ? 3300000 : 1200000));
break;
case PM8607_ID_LDO14:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- ret = (index < 3) ? (index * 50000 + 1800000) :
- ((index < 8) ? (index * 50000 + 2550000) :
- -EINVAL);
- break;
- case PM8607_CHIP_B0:
- ret = (index < 2) ? (index * 50000 + 1800000) :
- ((index < 7) ? (index * 50000 + 2600000) :
- 3300000);
- break;
- }
+ ret = (index < 2) ? (index * 50000 + 1800000) :
+ ((index < 7) ? (index * 50000 + 2600000) :
+ 3300000);
break;
}
return ret;
@@ -169,7 +120,6 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
- uint8_t chip_id = info->chip->chip_id;
int val = -ENOENT;
int ret;
@@ -254,161 +204,77 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
case PM8607_ID_LDO2:
case PM8607_ID_LDO3:
case PM8607_ID_LDO9:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */
- if (min_uV <= 1800000)
- val = 0;
- else if (min_uV <= 1900000)
- val = (min_uV - 1750001) / 50000;
- else
- val = 3; /* 2700mV */
- else { /* 2700mV ~ 2900mV / 50mV */
- if (min_uV <= 2900000) {
- val = (min_uV - 2650001) / 50000;
- val += 3;
- } else
- val = -EINVAL;
- }
- break;
- case PM8607_CHIP_B0:
- if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
- if (min_uV <= 1800000)
- val = 0;
- else if (min_uV <= 1900000)
- val = (min_uV - 1750001) / 50000;
- else
- val = 3; /* 2700mV */
- } else { /* 2700mV ~ 2850mV / 50mV */
- if (min_uV <= 2850000) {
- val = (min_uV - 2650001) / 50000;
- val += 3;
- } else if (min_uV <= 3300000)
- val = 7;
- else
- val = -EINVAL;
- }
- break;
+ if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
+ if (min_uV <= 1800000)
+ val = 0;
+ else if (min_uV <= 1900000)
+ val = (min_uV - 1750001) / 50000;
+ else
+ val = 3; /* 2700mV */
+ } else { /* 2700mV ~ 2850mV / 50mV */
+ if (min_uV <= 2850000) {
+ val = (min_uV - 2650001) / 50000;
+ val += 3;
+ } else if (min_uV <= 3300000)
+ val = 7;
+ else
+ val = -EINVAL;
}
break;
case PM8607_ID_LDO4:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */
- if (min_uV <= 1800000)
- val = 0;
- else if (min_uV <= 1900000)
- val = (min_uV - 1750001) / 50000;
- else
- val = 3; /* 2700mV */
- else { /* 2700mV ~ 2900mV / 50mV */
- if (min_uV <= 2900000) {
- val = (min_uV - 2650001) / 50000;
- val += 3;
- } else
- val = -EINVAL;
- }
- break;
- case PM8607_CHIP_B0:
- if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
- if (min_uV <= 1800000)
- val = 0;
- else if (min_uV <= 1900000)
- val = (min_uV - 1750001) / 50000;
- else
- val = 3; /* 2700mV */
- } else { /* 2700mV ~ 2800mV / 50mV */
- if (min_uV <= 2850000) {
- val = (min_uV - 2650001) / 50000;
- val += 3;
- } else if (min_uV <= 2900000)
- val = 6;
- else if (min_uV <= 3300000)
- val = 7;
- else
- val = -EINVAL;
- }
- break;
+ if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
+ if (min_uV <= 1800000)
+ val = 0;
+ else if (min_uV <= 1900000)
+ val = (min_uV - 1750001) / 50000;
+ else
+ val = 3; /* 2700mV */
+ } else { /* 2700mV ~ 2800mV / 50mV */
+ if (min_uV <= 2850000) {
+ val = (min_uV - 2650001) / 50000;
+ val += 3;
+ } else if (min_uV <= 2900000)
+ val = 6;
+ else if (min_uV <= 3300000)
+ val = 7;
+ else
+ val = -EINVAL;
}
break;
case PM8607_ID_LDO6:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- if (min_uV < 2600000) { /* 1800mV ~ 1900mV / 50mV */
- if (min_uV <= 1800000)
- val = 0;
- else if (min_uV <= 1900000)
- val = (min_uV - 1750001) / 50000;
- else
- val = 3; /* 2600mV */
- } else { /* 2600mV ~ 2800mV / 50mV */
- if (min_uV <= 2800000) {
- val = (min_uV - 2550001) / 50000;
- val += 3;
- } else
- val = -EINVAL;
- }
- break;
- case PM8607_CHIP_B0:
- if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */
- if (min_uV <= 1800000)
- val = 0;
- else if (min_uV <= 1850000)
- val = (min_uV - 1750001) / 50000;
- else
- val = 2; /* 2600mV */
- } else { /* 2600mV ~ 2800mV / 50mV */
- if (min_uV <= 2800000) {
- val = (min_uV - 2550001) / 50000;
- val += 2;
- } else if (min_uV <= 3300000)
- val = 7;
- else
- val = -EINVAL;
- }
- break;
+ if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */
+ if (min_uV <= 1800000)
+ val = 0;
+ else if (min_uV <= 1850000)
+ val = (min_uV - 1750001) / 50000;
+ else
+ val = 2; /* 2600mV */
+ } else { /* 2600mV ~ 2800mV / 50mV */
+ if (min_uV <= 2800000) {
+ val = (min_uV - 2550001) / 50000;
+ val += 2;
+ } else if (min_uV <= 3300000)
+ val = 7;
+ else
+ val = -EINVAL;
}
break;
case PM8607_ID_LDO14:
- switch (chip_id) {
- case PM8607_CHIP_A0:
- case PM8607_CHIP_A1:
- if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
- if (min_uV <= 1800000)
- val = 0;
- else if (min_uV <= 1900000)
- val = (min_uV - 1750001) / 50000;
- else
- val = 3; /* 2700mV */
- } else { /* 2700mV ~ 2900mV / 50mV */
- if (min_uV <= 2900000) {
- val = (min_uV - 2650001) / 50000;
- val += 3;
- } else
- val = -EINVAL;
- }
- break;
- case PM8607_CHIP_B0:
- if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */
- if (min_uV <= 1800000)
- val = 0;
- else if (min_uV <= 1850000)
- val = (min_uV - 1750001) / 50000;
- else
- val = 2; /* 2700mV */
- } else { /* 2700mV ~ 2900mV / 50mV */
- if (min_uV <= 2900000) {
- val = (min_uV - 2650001) / 50000;
- val += 2;
- } else if (min_uV <= 3300000)
- val = 7;
- else
- val = -EINVAL;
- }
- break;
+ if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */
+ if (min_uV <= 1800000)
+ val = 0;
+ else if (min_uV <= 1850000)
+ val = (min_uV - 1750001) / 50000;
+ else
+ val = 2; /* 2700mV */
+ } else { /* 2700mV ~ 2900mV / 50mV */
+ if (min_uV <= 2900000) {
+ val = (min_uV - 2650001) / 50000;
+ val += 2;
+ } else if (min_uV <= 3300000)
+ val = 7;
+ else
+ val = -EINVAL;
}
break;
}
@@ -428,7 +294,6 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
- struct pm8607_chip *chip = info->chip;
uint8_t val, mask;
int ret;
@@ -443,13 +308,13 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
val = (uint8_t)(ret << info->vol_shift);
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
- ret = pm8607_set_bits(chip, info->vol_reg, mask, val);
+ ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val);
if (ret)
return ret;
switch (info->desc.id) {
case PM8607_ID_BUCK1:
case PM8607_ID_BUCK3:
- ret = pm8607_set_bits(chip, info->update_reg,
+ ret = pm860x_set_bits(info->i2c, info->update_reg,
1 << info->update_bit,
1 << info->update_bit);
break;
@@ -460,11 +325,10 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
static int pm8607_get_voltage(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
- struct pm8607_chip *chip = info->chip;
uint8_t val, mask;
int ret;
- ret = pm8607_reg_read(chip, info->vol_reg);
+ ret = pm860x_reg_read(info->i2c, info->vol_reg);
if (ret < 0)
return ret;
@@ -477,9 +341,8 @@ static int pm8607_get_voltage(struct regulator_dev *rdev)
static int pm8607_enable(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
- struct pm8607_chip *chip = info->chip;
- return pm8607_set_bits(chip, info->enable_reg,
+ return pm860x_set_bits(info->i2c, info->enable_reg,
1 << info->enable_bit,
1 << info->enable_bit);
}
@@ -487,19 +350,17 @@ static int pm8607_enable(struct regulator_dev *rdev)
static int pm8607_disable(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
- struct pm8607_chip *chip = info->chip;
- return pm8607_set_bits(chip, info->enable_reg,
+ return pm860x_set_bits(info->i2c, info->enable_reg,
1 << info->enable_bit, 0);
}
static int pm8607_is_enabled(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
- struct pm8607_chip *chip = info->chip;
int ret;
- ret = pm8607_reg_read(chip, info->enable_reg);
+ ret = pm860x_reg_read(info->i2c, info->enable_reg);
if (ret < 0)
return ret;
@@ -589,8 +450,8 @@ static inline struct pm8607_regulator_info *find_regulator_info(int id)
static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
{
- struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm8607_platform_data *pdata = chip->dev->platform_data;
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pm860x_platform_data *pdata = chip->dev->platform_data;
struct pm8607_regulator_info *info = NULL;
info = find_regulator_info(pdev->id);
@@ -599,6 +460,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
return -EINVAL;
}
+ info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
info->chip = chip;
info->regulator = regulator_register(&info->desc, &pdev->dev,
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 834b4844182..04f2e085116 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -94,6 +94,12 @@ config REGULATOR_MAX8660
This driver controls a Maxim 8660/8661 voltage output
regulator via I2C bus.
+config REGULATOR_MAX8925
+ tristate "Maxim MAX8925 Power Management IC"
+ depends on MFD_MAX8925
+ help
+ Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC.
+
config REGULATOR_TWL4030
bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
depends on TWL4030_CORE
@@ -191,7 +197,7 @@ config REGULATOR_TPS6507X
config REGULATOR_88PM8607
bool "Marvell 88PM8607 Power regulators"
- depends on MFD_88PM8607=y
+ depends on MFD_88PM860X=y
help
This driver supports 88PM8607 voltage regulator chips.
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index e845b66ad59..4e7feece22d 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
+obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c7bbe30010f..2b4e40d3119 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/suspend.h>
@@ -1038,6 +1039,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
goto overflow_err;
regulator->dev = dev;
+ sysfs_attr_init(&regulator->dev_attr.attr);
regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL);
if (regulator->dev_attr.attr.name == NULL)
goto attr_name_err;
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index d11f7622430..2fe9d99c9f2 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -25,6 +25,7 @@
#include <linux/regulator/fixed.h>
#include <linux/gpio.h>
#include <linux/delay.h>
+#include <linux/slab.h>
struct fixed_voltage_data {
struct regulator_desc desc;
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
index f5532ed7927..671a7d1f1f0 100644
--- a/drivers/regulator/lp3971.c
+++ b/drivers/regulator/lp3971.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/lp3971.h>
+#include <linux/slab.h>
struct lp3971 {
struct device *dev;
@@ -45,7 +46,7 @@ static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
LP3971_BUCK2 -> 4
LP3971_BUCK3 -> 6
*/
-#define BUCK_VOL_CHANGE_SHIFT(x) (((1 << x) & ~0x01) << 1)
+#define BUCK_VOL_CHANGE_SHIFT(x) (((!!x) << 2) | (x & ~0x01))
#define BUCK_VOL_CHANGE_FLAG_GO 0x01
#define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
#define BUCK_VOL_CHANGE_FLAG_MASK 0x03
@@ -187,7 +188,8 @@ static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
return -EINVAL;
return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
- LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), val);
+ LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
+ val << LDO_VOL_CONTR_SHIFT(ldo));
}
static struct regulator_ops lp3971_ldo_ops = {
@@ -439,6 +441,10 @@ static int __devinit setup_regulators(struct lp3971 *lp3971,
lp3971->num_regulators = pdata->num_regulators;
lp3971->rdev = kcalloc(pdata->num_regulators,
sizeof(struct regulator_dev *), GFP_KERNEL);
+ if (!lp3971->rdev) {
+ err = -ENOMEM;
+ goto err_nomem;
+ }
/* Instantiate the regulators */
for (i = 0; i < pdata->num_regulators; i++) {
@@ -461,6 +467,7 @@ error:
regulator_unregister(lp3971->rdev[i]);
kfree(lp3971->rdev);
lp3971->rdev = NULL;
+err_nomem:
return err;
}
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index a49fc952c9a..b3c1afc1688 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
+#include <linux/slab.h>
#include <linux/regulator/max1586.h>
#define MAX1586_V3_MAX_VSEL 31
@@ -243,8 +244,8 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client)
for (i = 0; i <= MAX1586_V6; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
- kfree(rdev);
i2c_set_clientdata(client, NULL);
+ kfree(rdev);
return 0;
}
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index 3ebdf698c64..bfc4c5ffdc9 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -14,6 +14,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
+#include <linux/slab.h>
#include <linux/regulator/max8649.h>
#define MAX8649_DCDC_VMIN 750000 /* uV */
@@ -356,6 +357,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
dev_info(info->dev, "Max8649 regulator device is detected.\n");
return 0;
out:
+ i2c_set_clientdata(client, NULL);
kfree(info);
return ret;
}
@@ -367,9 +369,9 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
if (info) {
if (info->regulator)
regulator_unregister(info->regulator);
+ i2c_set_clientdata(client, NULL);
kfree(info);
}
- i2c_set_clientdata(client, NULL);
return 0;
}
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c
index f12f1bb6213..3790b21879f 100644
--- a/drivers/regulator/max8660.c
+++ b/drivers/regulator/max8660.c
@@ -42,6 +42,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
+#include <linux/slab.h>
#include <linux/regulator/max8660.h>
#define MAX8660_DCDC_MIN_UV 725000
@@ -470,8 +471,8 @@ static int __devexit max8660_remove(struct i2c_client *client)
for (i = 0; i < MAX8660_V_END; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
- kfree(rdev);
i2c_set_clientdata(client, NULL);
+ kfree(rdev);
return 0;
}
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
new file mode 100644
index 00000000000..552cad85ae5
--- /dev/null
+++ b/drivers/regulator/max8925-regulator.c
@@ -0,0 +1,308 @@
+/*
+ * Regulators driver for Maxim max8925
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max8925.h>
+
+#define SD1_DVM_VMIN 850000
+#define SD1_DVM_VMAX 1000000
+#define SD1_DVM_STEP 50000
+#define SD1_DVM_SHIFT 5 /* SDCTL1 bit5 */
+#define SD1_DVM_EN 6 /* SDV1 bit 6 */
+
+struct max8925_regulator_info {
+ struct regulator_desc desc;
+ struct regulator_dev *regulator;
+ struct i2c_client *i2c;
+ struct max8925_chip *chip;
+
+ int min_uV;
+ int max_uV;
+ int step_uV;
+ int vol_reg;
+ int vol_shift;
+ int vol_nbits;
+ int enable_bit;
+ int enable_reg;
+};
+
+static inline int check_range(struct max8925_regulator_info *info,
+ int min_uV, int max_uV)
+{
+ if (min_uV < info->min_uV || min_uV > info->max_uV)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+ return info->min_uV + index * info->step_uV;
+}
+
+static int max8925_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+ unsigned char data, mask;
+
+ if (check_range(info, min_uV, max_uV)) {
+ dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n",
+ min_uV, max_uV);
+ return -EINVAL;
+ }
+ data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
+ data <<= info->vol_shift;
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+
+ return max8925_set_bits(info->i2c, info->vol_reg, mask, data);
+}
+
+static int max8925_get_voltage(struct regulator_dev *rdev)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+ unsigned char data, mask;
+ int ret;
+
+ ret = max8925_reg_read(info->i2c, info->vol_reg);
+ if (ret < 0)
+ return ret;
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ data = (ret & mask) >> info->vol_shift;
+
+ return max8925_list_voltage(rdev, data);
+}
+
+static int max8925_enable(struct regulator_dev *rdev)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+
+ return max8925_set_bits(info->i2c, info->enable_reg,
+ 1 << info->enable_bit,
+ 1 << info->enable_bit);
+}
+
+static int max8925_disable(struct regulator_dev *rdev)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+
+ return max8925_set_bits(info->i2c, info->enable_reg,
+ 1 << info->enable_bit, 0);
+}
+
+static int max8925_is_enabled(struct regulator_dev *rdev)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+ int ret;
+
+ ret = max8925_reg_read(info->i2c, info->enable_reg);
+ if (ret < 0)
+ return ret;
+
+ return ret & (1 << info->enable_bit);
+}
+
+static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+ unsigned char data, mask;
+
+ if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX)
+ return -EINVAL;
+
+ data = (uV - SD1_DVM_VMIN + SD1_DVM_STEP - 1) / SD1_DVM_STEP;
+ data <<= SD1_DVM_SHIFT;
+ mask = 3 << SD1_DVM_SHIFT;
+
+ return max8925_set_bits(info->i2c, info->enable_reg, mask, data);
+}
+
+static int max8925_set_dvm_enable(struct regulator_dev *rdev)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+
+ return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN,
+ 1 << SD1_DVM_EN);
+}
+
+static int max8925_set_dvm_disable(struct regulator_dev *rdev)
+{
+ struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
+
+ return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 0);
+}
+
+static struct regulator_ops max8925_regulator_sdv_ops = {
+ .set_voltage = max8925_set_voltage,
+ .get_voltage = max8925_get_voltage,
+ .enable = max8925_enable,
+ .disable = max8925_disable,
+ .is_enabled = max8925_is_enabled,
+ .set_suspend_voltage = max8925_set_dvm_voltage,
+ .set_suspend_enable = max8925_set_dvm_enable,
+ .set_suspend_disable = max8925_set_dvm_disable,
+};
+
+static struct regulator_ops max8925_regulator_ldo_ops = {
+ .set_voltage = max8925_set_voltage,
+ .get_voltage = max8925_get_voltage,
+ .enable = max8925_enable,
+ .disable = max8925_disable,
+ .is_enabled = max8925_is_enabled,
+};
+
+#define MAX8925_SDV(_id, min, max, step) \
+{ \
+ .desc = { \
+ .name = "SDV" #_id, \
+ .ops = &max8925_regulator_sdv_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MAX8925_ID_SD##_id, \
+ .owner = THIS_MODULE, \
+ }, \
+ .min_uV = min * 1000, \
+ .max_uV = max * 1000, \
+ .step_uV = step * 1000, \
+ .vol_reg = MAX8925_SDV##_id, \
+ .vol_shift = 0, \
+ .vol_nbits = 6, \
+ .enable_reg = MAX8925_SDCTL##_id, \
+ .enable_bit = 0, \
+}
+
+#define MAX8925_LDO(_id, min, max, step) \
+{ \
+ .desc = { \
+ .name = "LDO" #_id, \
+ .ops = &max8925_regulator_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MAX8925_ID_LDO##_id, \
+ .owner = THIS_MODULE, \
+ }, \
+ .min_uV = min * 1000, \
+ .max_uV = max * 1000, \
+ .step_uV = step * 1000, \
+ .vol_reg = MAX8925_LDOVOUT##_id, \
+ .vol_shift = 0, \
+ .vol_nbits = 6, \
+ .enable_reg = MAX8925_LDOCTL##_id, \
+ .enable_bit = 0, \
+}
+
+static struct max8925_regulator_info max8925_regulator_info[] = {
+ MAX8925_SDV(1, 637.5, 1425, 12.5),
+ MAX8925_SDV(2, 650, 2225, 25),
+ MAX8925_SDV(3, 750, 3900, 50),
+
+ MAX8925_LDO(1, 750, 3900, 50),
+ MAX8925_LDO(2, 650, 2250, 25),
+ MAX8925_LDO(3, 650, 2250, 25),
+ MAX8925_LDO(4, 750, 3900, 50),
+ MAX8925_LDO(5, 750, 3900, 50),
+ MAX8925_LDO(6, 750, 3900, 50),
+ MAX8925_LDO(7, 750, 3900, 50),
+ MAX8925_LDO(8, 750, 3900, 50),
+ MAX8925_LDO(9, 750, 3900, 50),
+ MAX8925_LDO(10, 750, 3900, 50),
+ MAX8925_LDO(11, 750, 3900, 50),
+ MAX8925_LDO(12, 750, 3900, 50),
+ MAX8925_LDO(13, 750, 3900, 50),
+ MAX8925_LDO(14, 750, 3900, 50),
+ MAX8925_LDO(15, 750, 3900, 50),
+ MAX8925_LDO(16, 750, 3900, 50),
+ MAX8925_LDO(17, 650, 2250, 25),
+ MAX8925_LDO(18, 650, 2250, 25),
+ MAX8925_LDO(19, 750, 3900, 50),
+ MAX8925_LDO(20, 750, 3900, 50),
+};
+
+static struct max8925_regulator_info * __devinit find_regulator_info(int id)
+{
+ struct max8925_regulator_info *ri;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
+ ri = &max8925_regulator_info[i];
+ if (ri->desc.id == id)
+ return ri;
+ }
+ return NULL;
+}
+
+static int __devinit max8925_regulator_probe(struct platform_device *pdev)
+{
+ struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct max8925_platform_data *pdata = chip->dev->platform_data;
+ struct max8925_regulator_info *ri;
+ struct regulator_dev *rdev;
+
+ ri = find_regulator_info(pdev->id);
+ if (ri == NULL) {
+ dev_err(&pdev->dev, "invalid regulator ID specified\n");
+ return -EINVAL;
+ }
+ ri->i2c = chip->i2c;
+ ri->chip = chip;
+
+ rdev = regulator_register(&ri->desc, &pdev->dev,
+ pdata->regulator[pdev->id], ri);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register regulator %s\n",
+ ri->desc.name);
+ return PTR_ERR(rdev);
+ }
+
+ platform_set_drvdata(pdev, rdev);
+ return 0;
+}
+
+static int __devexit max8925_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+ regulator_unregister(rdev);
+
+ return 0;
+}
+
+static struct platform_driver max8925_regulator_driver = {
+ .driver = {
+ .name = "max8925-regulator",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8925_regulator_probe,
+ .remove = __devexit_p(max8925_regulator_remove),
+};
+
+static int __init max8925_regulator_init(void)
+{
+ return platform_driver_register(&max8925_regulator_driver);
+}
+subsys_initcall(max8925_regulator_init);
+
+static void __exit max8925_regulator_exit(void)
+{
+ platform_driver_unregister(&max8925_regulator_driver);
+}
+module_exit(max8925_regulator_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC");
+MODULE_ALIAS("platform:max8925-regulator");
+
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index f7b81845a19..ad036dd8da1 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -14,6 +14,7 @@
#include <linux/regulator/driver.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/err.h>
@@ -617,9 +618,12 @@ static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
dev_get_platdata(&pdev->dev);
int i;
+ platform_set_drvdata(pdev, NULL);
+
for (i = 0; i < pdata->num_regulators; i++)
regulator_unregister(priv->regulators[i]);
+ kfree(priv);
return 0;
}
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 1f183543bdb..8e2f2098b00 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -24,6 +24,7 @@
#include <linux/regulator/machine.h>
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/slab.h>
/* Register definitions */
#define TPS65023_REG_VERSION 0
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c
index c2a9539acd7..74841abcc9c 100644
--- a/drivers/regulator/tps6507x-regulator.c
+++ b/drivers/regulator/tps6507x-regulator.c
@@ -24,6 +24,7 @@
#include <linux/regulator/machine.h>
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/slab.h>
/* Register definitions */
#define TPS6507X_REG_PPATH1 0X01
diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c
index 44917da4ac9..9d5ba935759 100644
--- a/drivers/regulator/userspace-consumer.c
+++ b/drivers/regulator/userspace-consumer.c
@@ -21,6 +21,7 @@
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/userspace-consumer.h>
+#include <linux/slab.h>
struct userspace_consumer_data {
const char *name;
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index d96cecaac73..69e550f5763 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -15,6 +15,7 @@
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
struct virtual_consumer_data {
struct mutex lock;
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 6e18e56d850..dbfaf5945e4 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -21,6 +21,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/regulator.h>
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index ca0f6b6c384..6c446cd6ad5 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
+#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/regulator.h>
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index d2406c1519a..e686cdb61b9 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
+#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/regulator.h>
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 94227dd6ba7..723cd1fb486 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1453,7 +1453,7 @@ static int wm8350_regulator_remove(struct platform_device *pdev)
struct regulator_dev *rdev = platform_get_drvdata(pdev);
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
- wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq);
+ wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
regulator_unregister(rdev);
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
index 95454a4637b..5a1dc8a24d3 100644
--- a/drivers/regulator/wm8994-regulator.c
+++ b/drivers/regulator/wm8994-regulator.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/registers.h>
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 2bb8a8b7ffa..6a130375943 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -175,6 +175,16 @@ config RTC_DRV_MAX6900
This driver can also be built as a module. If so, the module
will be called rtc-max6900.
+config RTC_DRV_MAX8925
+ tristate "Maxim MAX8925"
+ depends on MFD_MAX8925
+ help
+ If you say yes here you will get support for the
+ RTC of Maxim MAX8925 PMIC.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-max8925.
+
config RTC_DRV_RS5C372
tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A"
help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index b7148afb8f5..44ef194a957 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o
obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_MXC) += rtc-mxc.o
obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
+obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index be5a6b73e60..565562ba6ac 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -15,6 +15,7 @@
#include <linux/rtc.h>
#include <linux/kdev_t.h>
#include <linux/idr.h>
+#include <linux/slab.h>
#include "rtc-core.h"
@@ -226,6 +227,7 @@ static void __exit rtc_exit(void)
{
rtc_dev_exit();
class_destroy(rtc_class);
+ idr_destroy(&rtc_idr);
}
subsys_initcall(rtc_init);
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
index 33c0e98243e..bc90b091f19 100644
--- a/drivers/rtc/hctosys.c
+++ b/drivers/rtc/hctosys.c
@@ -22,48 +22,57 @@
* the best guess is to add 0.5s.
*/
+int rtc_hctosys_ret = -ENODEV;
+
static int __init rtc_hctosys(void)
{
- int err;
+ int err = -ENODEV;
struct rtc_time tm;
+ struct timespec tv = {
+ .tv_nsec = NSEC_PER_SEC >> 1,
+ };
struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
if (rtc == NULL) {
- printk("%s: unable to open rtc device (%s)\n",
+ pr_err("%s: unable to open rtc device (%s)\n",
__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
- return -ENODEV;
+ goto err_open;
}
err = rtc_read_time(rtc, &tm);
- if (err == 0) {
- err = rtc_valid_tm(&tm);
- if (err == 0) {
- struct timespec tv;
+ if (err) {
+ dev_err(rtc->dev.parent,
+ "hctosys: unable to read the hardware clock\n");
+ goto err_read;
- tv.tv_nsec = NSEC_PER_SEC >> 1;
+ }
- rtc_tm_to_time(&tm, &tv.tv_sec);
+ err = rtc_valid_tm(&tm);
+ if (err) {
+ dev_err(rtc->dev.parent,
+ "hctosys: invalid date/time\n");
+ goto err_invalid;
+ }
- do_settimeofday(&tv);
+ rtc_tm_to_time(&tm, &tv.tv_sec);
- dev_info(rtc->dev.parent,
- "setting system clock to "
- "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- (unsigned int) tv.tv_sec);
- }
- else
- dev_err(rtc->dev.parent,
- "hctosys: invalid date/time\n");
- }
- else
- dev_err(rtc->dev.parent,
- "hctosys: unable to read the hardware clock\n");
+ do_settimeofday(&tv);
+ dev_info(rtc->dev.parent,
+ "setting system clock to "
+ "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ (unsigned int) tv.tv_sec);
+
+err_invalid:
+err_read:
rtc_class_close(rtc);
- return 0;
+err_open:
+ rtc_hctosys_ret = err;
+
+ return err;
}
late_initcall(rtc_hctosys);
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c
index 8825695777d..b2752b6e7a2 100644
--- a/drivers/rtc/rtc-at32ap700x.c
+++ b/drivers/rtc/rtc-at32ap700x.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/io.h>
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 86c61f14351..f677e0710ca 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -18,6 +18,7 @@
#include <linux/rtc.h>
#include <linux/interrupt.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include <mach/board.h>
#include <mach/at91_rtt.h>
@@ -161,7 +162,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
if (offset == 0)
return -EILSEQ;
- memset(alrm, 0, sizeof(alrm));
+ memset(alrm, 0, sizeof(*alrm));
if (alarm != ALARM_DISABLED && offset != 0) {
rtc_time_to_tm(offset + alarm, tm);
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
index b11485b9f21..72b2bcc2c22 100644
--- a/drivers/rtc/rtc-bfin.c
+++ b/drivers/rtc/rtc-bfin.c
@@ -51,6 +51,7 @@
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/blackfin.h>
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c
index 280fe48ada0..128270ce355 100644
--- a/drivers/rtc/rtc-bq4802.c
+++ b/drivers/rtc/rtc-bq4802.c
@@ -10,6 +10,7 @@
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
+#include <linux/slab.h>
MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
MODULE_DESCRIPTION("TI BQ4802 RTC driver");
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 03ea530981d..316f484999b 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -14,6 +14,7 @@
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
/*
* Registers in the COH 901 331
@@ -271,12 +272,13 @@ static int coh901331_resume(struct platform_device *pdev)
{
struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev);
- if (device_may_wakeup(&pdev->dev))
+ if (device_may_wakeup(&pdev->dev)) {
disable_irq_wake(rtap->irq);
- else
+ } else {
clk_enable(rtap->clk);
writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
+ }
return 0;
}
#else
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c
index 4aedc705518..45cd8c9f5a3 100644
--- a/drivers/rtc/rtc-ds1216.c
+++ b/drivers/rtc/rtc-ds1216.c
@@ -9,6 +9,7 @@
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <linux/bcd.h>
+#include <linux/slab.h>
#define DRV_VERSION "0.2"
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
index 4fcb16bbff4..bf430f9091e 100644
--- a/drivers/rtc/rtc-ds1286.c
+++ b/drivers/rtc/rtc-ds1286.c
@@ -18,6 +18,7 @@
#include <linux/bcd.h>
#include <linux/ds1286.h>
#include <linux/io.h>
+#include <linux/slab.h>
#define DRV_VERSION "1.0"
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index 9630e7d3314..7836c9cec55 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/bcd.h>
+#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/workqueue.h>
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 5317bbcbc7a..61945734ad0 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -24,6 +24,7 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#define DS1374_REG_TOD0 0x00 /* Time of Day */
#define DS1374_REG_TOD1 0x01
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c
index cdb70505709..26a86d23505 100644
--- a/drivers/rtc/rtc-ds1390.c
+++ b/drivers/rtc/rtc-ds1390.c
@@ -19,6 +19,7 @@
#include <linux/rtc.h>
#include <linux/spi/spi.h>
#include <linux/bcd.h>
+#include <linux/slab.h>
#define DS1390_REG_100THS 0x00
#define DS1390_REG_SECONDS 0x01
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 4166b84cb51..06b8566c453 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -17,6 +17,7 @@
#include <linux/bcd.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/rtc.h>
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index ed1ef7c9cc0..244f9994bcb 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -11,6 +11,7 @@
#include <linux/bcd.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index a1273360a44..2b4b0bc42d6 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -15,6 +15,7 @@
#include <linux/bcd.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/rtc.h>
@@ -184,6 +185,7 @@ static int __devinit ds1742_rtc_probe(struct platform_device *pdev)
pdata->size_nvram = pdata->size - RTC_SIZE;
pdata->ioaddr_rtc = ioaddr + pdata->size_nvram;
+ sysfs_bin_attr_init(&pdata->nvram_attr);
pdata->nvram_attr.attr.name = "nvram";
pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR;
pdata->nvram_attr.read = ds1742_nvram_read;
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 9da02d108b7..11ae64dcbf3 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -13,6 +13,7 @@
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#define EP93XX_RTC_DATA 0x000
#define EP93XX_RTC_MATCH 0x004
@@ -115,6 +116,15 @@ static ssize_t ep93xx_rtc_show_comp_delete(struct device *dev,
}
static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL);
+static struct attribute *ep93xx_rtc_attrs[] = {
+ &dev_attr_comp_preload.attr,
+ &dev_attr_comp_delete.attr,
+ NULL
+};
+
+static const struct attribute_group ep93xx_rtc_sysfs_files = {
+ .attrs = ep93xx_rtc_attrs,
+};
static int __init ep93xx_rtc_probe(struct platform_device *pdev)
{
@@ -123,27 +133,22 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
struct rtc_device *rtc;
int err;
- ep93xx_rtc = kzalloc(sizeof(struct ep93xx_rtc), GFP_KERNEL);
- if (ep93xx_rtc == NULL)
+ ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
+ if (!ep93xx_rtc)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- err = -ENXIO;
- goto fail_free;
- }
+ if (!res)
+ return -ENXIO;
- res = request_mem_region(res->start, resource_size(res), pdev->name);
- if (res == NULL) {
- err = -EBUSY;
- goto fail_free;
- }
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name))
+ return -EBUSY;
- ep93xx_rtc->mmio_base = ioremap(res->start, resource_size(res));
- if (ep93xx_rtc->mmio_base == NULL) {
- err = -ENXIO;
- goto fail;
- }
+ ep93xx_rtc->mmio_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!ep93xx_rtc->mmio_base)
+ return -ENXIO;
pdev->dev.platform_data = ep93xx_rtc;
@@ -151,53 +156,34 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
&pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
err = PTR_ERR(rtc);
- goto fail;
+ goto exit;
}
platform_set_drvdata(pdev, rtc);
- err = device_create_file(&pdev->dev, &dev_attr_comp_preload);
+ err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
if (err)
goto fail;
- err = device_create_file(&pdev->dev, &dev_attr_comp_delete);
- if (err) {
- device_remove_file(&pdev->dev, &dev_attr_comp_preload);
- goto fail;
- }
return 0;
fail:
- if (ep93xx_rtc->mmio_base) {
- iounmap(ep93xx_rtc->mmio_base);
- pdev->dev.platform_data = NULL;
- }
- release_mem_region(res->start, resource_size(res));
-fail_free:
- kfree(ep93xx_rtc);
+ platform_set_drvdata(pdev, NULL);
+ rtc_device_unregister(rtc);
+exit:
+ pdev->dev.platform_data = NULL;
return err;
}
static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
{
struct rtc_device *rtc = platform_get_drvdata(pdev);
- struct ep93xx_rtc *ep93xx_rtc = pdev->dev.platform_data;
- struct resource *res;
-
- /* cleanup sysfs */
- device_remove_file(&pdev->dev, &dev_attr_comp_delete);
- device_remove_file(&pdev->dev, &dev_attr_comp_preload);
+ sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
+ platform_set_drvdata(pdev, NULL);
rtc_device_unregister(rtc);
-
- iounmap(ep93xx_rtc->mmio_base);
pdev->dev.platform_data = NULL;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
- platform_set_drvdata(pdev, NULL);
-
return 0;
}
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c
index 812c6675508..ff6fce61ea4 100644
--- a/drivers/rtc/rtc-fm3130.c
+++ b/drivers/rtc/rtc-fm3130.c
@@ -13,6 +13,7 @@
#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
+#include <linux/slab.h>
#define FM3130_RTC_CONTROL (0x0)
#define FM3130_CAL_CONTROL (0x1)
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
index 8cb5b8959e5..7410875e583 100644
--- a/drivers/rtc/rtc-m48t35.c
+++ b/drivers/rtc/rtc-m48t35.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/bcd.h>
#include <linux/io.h>
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index ede43b84685..365ff3ac234 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -19,6 +19,7 @@
#include <linux/rtc.h>
#include <linux/rtc/m48t59.h>
#include <linux/bcd.h>
+#include <linux/slab.h>
#ifndef NO_IRQ
#define NO_IRQ (-1)
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c
new file mode 100644
index 00000000000..174036dda78
--- /dev/null
+++ b/drivers/rtc/rtc-max8925.c
@@ -0,0 +1,315 @@
+/*
+ * RTC driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/max8925.h>
+
+enum {
+ RTC_SEC = 0,
+ RTC_MIN,
+ RTC_HOUR,
+ RTC_WEEKDAY,
+ RTC_DATE,
+ RTC_MONTH,
+ RTC_YEAR1,
+ RTC_YEAR2,
+};
+
+#define MAX8925_RTC_SEC 0x00
+#define MAX8925_RTC_MIN 0x01
+#define MAX8925_RTC_HOUR 0x02
+#define MAX8925_RTC_WEEKDAY 0x03
+#define MAX8925_RTC_DATE 0x04
+#define MAX8925_RTC_MONTH 0x05
+#define MAX8925_RTC_YEAR1 0x06
+#define MAX8925_RTC_YEAR2 0x07
+#define MAX8925_ALARM0_SEC 0x08
+#define MAX8925_ALARM0_MIN 0x09
+#define MAX8925_ALARM0_HOUR 0x0a
+#define MAX8925_ALARM0_WEEKDAY 0x0b
+#define MAX8925_ALARM0_DATE 0x0c
+#define MAX8925_ALARM0_MON 0x0d
+#define MAX8925_ALARM0_YEAR1 0x0e
+#define MAX8925_ALARM0_YEAR2 0x0f
+#define MAX8925_ALARM1_SEC 0x10
+#define MAX8925_ALARM1_MIN 0x11
+#define MAX8925_ALARM1_HOUR 0x12
+#define MAX8925_ALARM1_WEEKDAY 0x13
+#define MAX8925_ALARM1_DATE 0x14
+#define MAX8925_ALARM1_MON 0x15
+#define MAX8925_ALARM1_YEAR1 0x16
+#define MAX8925_ALARM1_YEAR2 0x17
+#define MAX8925_RTC_CNTL 0x1b
+#define MAX8925_RTC_STATUS 0x20
+
+#define TIME_NUM 8
+#define ALARM_1SEC (1 << 7)
+#define HOUR_12 (1 << 7)
+#define HOUR_AM_PM (1 << 5)
+#define ALARM0_IRQ (1 << 3)
+#define ALARM1_IRQ (1 << 2)
+#define ALARM0_STATUS (1 << 2)
+#define ALARM1_STATUS (1 << 1)
+
+
+struct max8925_rtc_info {
+ struct rtc_device *rtc_dev;
+ struct max8925_chip *chip;
+ struct i2c_client *rtc;
+ struct device *dev;
+};
+
+static irqreturn_t rtc_update_handler(int irq, void *data)
+{
+ struct max8925_rtc_info *info = (struct max8925_rtc_info *)data;
+
+ /* disable ALARM0 except for 1SEC alarm */
+ max8925_set_bits(info->rtc, MAX8925_ALARM0_CNTL, 0x7f, 0);
+ rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
+ return IRQ_HANDLED;
+}
+
+static int tm_calc(struct rtc_time *tm, unsigned char *buf, int len)
+{
+ if (len < TIME_NUM)
+ return -EINVAL;
+ tm->tm_year = (buf[RTC_YEAR2] >> 4) * 1000
+ + (buf[RTC_YEAR2] & 0xf) * 100
+ + (buf[RTC_YEAR1] >> 4) * 10
+ + (buf[RTC_YEAR1] & 0xf);
+ tm->tm_year -= 1900;
+ tm->tm_mon = ((buf[RTC_MONTH] >> 4) & 0x01) * 10
+ + (buf[RTC_MONTH] & 0x0f);
+ tm->tm_mday = ((buf[RTC_DATE] >> 4) & 0x03) * 10
+ + (buf[RTC_DATE] & 0x0f);
+ tm->tm_wday = buf[RTC_WEEKDAY] & 0x07;
+ if (buf[RTC_HOUR] & HOUR_12) {
+ tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x1) * 10
+ + (buf[RTC_HOUR] & 0x0f);
+ if (buf[RTC_HOUR] & HOUR_AM_PM)
+ tm->tm_hour += 12;
+ } else
+ tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x03) * 10
+ + (buf[RTC_HOUR] & 0x0f);
+ tm->tm_min = ((buf[RTC_MIN] >> 4) & 0x7) * 10
+ + (buf[RTC_MIN] & 0x0f);
+ tm->tm_sec = ((buf[RTC_SEC] >> 4) & 0x7) * 10
+ + (buf[RTC_SEC] & 0x0f);
+ return 0;
+}
+
+static int data_calc(unsigned char *buf, struct rtc_time *tm, int len)
+{
+ unsigned char high, low;
+
+ if (len < TIME_NUM)
+ return -EINVAL;
+
+ high = (tm->tm_year + 1900) / 1000;
+ low = (tm->tm_year + 1900) / 100;
+ low = low - high * 10;
+ buf[RTC_YEAR2] = (high << 4) + low;
+ high = (tm->tm_year + 1900) / 10;
+ low = tm->tm_year + 1900;
+ low = low - high * 10;
+ high = high - (high / 10) * 10;
+ buf[RTC_YEAR1] = (high << 4) + low;
+ high = tm->tm_mon / 10;
+ low = tm->tm_mon;
+ low = low - high * 10;
+ buf[RTC_MONTH] = (high << 4) + low;
+ high = tm->tm_mday / 10;
+ low = tm->tm_mday;
+ low = low - high * 10;
+ buf[RTC_DATE] = (high << 4) + low;
+ buf[RTC_WEEKDAY] = tm->tm_wday;
+ high = tm->tm_hour / 10;
+ low = tm->tm_hour;
+ low = low - high * 10;
+ buf[RTC_HOUR] = (high << 4) + low;
+ high = tm->tm_min / 10;
+ low = tm->tm_min;
+ low = low - high * 10;
+ buf[RTC_MIN] = (high << 4) + low;
+ high = tm->tm_sec / 10;
+ low = tm->tm_sec;
+ low = low - high * 10;
+ buf[RTC_SEC] = (high << 4) + low;
+ return 0;
+}
+
+static int max8925_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct max8925_rtc_info *info = dev_get_drvdata(dev);
+ unsigned char buf[TIME_NUM];
+ int ret;
+
+ ret = max8925_bulk_read(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf);
+ if (ret < 0)
+ goto out;
+ ret = tm_calc(tm, buf, TIME_NUM);
+out:
+ return ret;
+}
+
+static int max8925_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct max8925_rtc_info *info = dev_get_drvdata(dev);
+ unsigned char buf[TIME_NUM];
+ int ret;
+
+ ret = data_calc(buf, tm, TIME_NUM);
+ if (ret < 0)
+ goto out;
+ ret = max8925_bulk_write(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf);
+out:
+ return ret;
+}
+
+static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct max8925_rtc_info *info = dev_get_drvdata(dev);
+ unsigned char buf[TIME_NUM];
+ int ret;
+
+ ret = max8925_bulk_read(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
+ if (ret < 0)
+ goto out;
+ ret = tm_calc(&alrm->time, buf, TIME_NUM);
+ if (ret < 0)
+ goto out;
+ ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK);
+ if (ret < 0)
+ goto out;
+ if ((ret & ALARM0_IRQ) == 0)
+ alrm->enabled = 1;
+ else
+ alrm->enabled = 0;
+ ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS);
+ if (ret < 0)
+ goto out;
+ if (ret & ALARM0_STATUS)
+ alrm->pending = 1;
+ else
+ alrm->pending = 0;
+out:
+ return ret;
+}
+
+static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct max8925_rtc_info *info = dev_get_drvdata(dev);
+ unsigned char buf[TIME_NUM];
+ int ret;
+
+ ret = data_calc(buf, &alrm->time, TIME_NUM);
+ if (ret < 0)
+ goto out;
+ ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
+ if (ret < 0)
+ goto out;
+ /* only enable alarm on year/month/day/hour/min/sec */
+ ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
+ if (ret < 0)
+ goto out;
+out:
+ return ret;
+}
+
+static const struct rtc_class_ops max8925_rtc_ops = {
+ .read_time = max8925_rtc_read_time,
+ .set_time = max8925_rtc_set_time,
+ .read_alarm = max8925_rtc_read_alarm,
+ .set_alarm = max8925_rtc_set_alarm,
+};
+
+static int __devinit max8925_rtc_probe(struct platform_device *pdev)
+{
+ struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct max8925_rtc_info *info;
+ int irq, ret;
+
+ info = kzalloc(sizeof(struct max8925_rtc_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ info->chip = chip;
+ info->rtc = chip->rtc;
+ info->dev = &pdev->dev;
+ irq = chip->irq_base + MAX8925_IRQ_RTC_ALARM0;
+
+ ret = request_threaded_irq(irq, NULL, rtc_update_handler,
+ IRQF_ONESHOT, "rtc-alarm0", info);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
+ irq, ret);
+ goto out_irq;
+ }
+
+ info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev,
+ &max8925_rtc_ops, THIS_MODULE);
+ ret = PTR_ERR(info->rtc_dev);
+ if (IS_ERR(info->rtc_dev)) {
+ dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
+ goto out_rtc;
+ }
+
+ dev_set_drvdata(&pdev->dev, info);
+ platform_set_drvdata(pdev, info);
+
+ return 0;
+out_rtc:
+ free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info);
+out_irq:
+ kfree(info);
+ return ret;
+}
+
+static int __devexit max8925_rtc_remove(struct platform_device *pdev)
+{
+ struct max8925_rtc_info *info = platform_get_drvdata(pdev);
+
+ if (info) {
+ free_irq(info->chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info);
+ rtc_device_unregister(info->rtc_dev);
+ kfree(info);
+ }
+ return 0;
+}
+
+static struct platform_driver max8925_rtc_driver = {
+ .driver = {
+ .name = "max8925-rtc",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8925_rtc_probe,
+ .remove = __devexit_p(max8925_rtc_remove),
+};
+
+static int __init max8925_rtc_init(void)
+{
+ return platform_driver_register(&max8925_rtc_driver);
+}
+module_init(max8925_rtc_init);
+
+static void __exit max8925_rtc_exit(void)
+{
+ platform_driver_unregister(&max8925_rtc_driver);
+}
+module_exit(max8925_rtc_exit);
+
+MODULE_DESCRIPTION("Maxim MAX8925 RTC driver");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c
index 850f983c039..675bfb51536 100644
--- a/drivers/rtc/rtc-mc13783.c
+++ b/drivers/rtc/rtc-mc13783.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/rtc.h>
#define DRIVER_NAME "mc13783-rtc"
@@ -28,6 +29,34 @@ struct mc13783_rtc {
int valid;
};
+static int mc13783_rtc_irq_enable_unlocked(struct device *dev,
+ unsigned int enabled, int irq)
+{
+ struct mc13783_rtc *priv = dev_get_drvdata(dev);
+ int (*func)(struct mc13783 *mc13783, int irq);
+
+ if (!priv->valid)
+ return -ENODATA;
+
+ func = enabled ? mc13783_irq_unmask : mc13783_irq_mask;
+ return func(priv->mc13783, irq);
+}
+
+static int mc13783_rtc_irq_enable(struct device *dev,
+ unsigned int enabled, int irq)
+{
+ struct mc13783_rtc *priv = dev_get_drvdata(dev);
+ int ret;
+
+ mc13783_lock(priv->mc13783);
+
+ ret = mc13783_rtc_irq_enable_unlocked(dev, enabled, irq);
+
+ mc13783_unlock(priv->mc13783);
+
+ return ret;
+}
+
static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct mc13783_rtc *priv = dev_get_drvdata(dev);
@@ -78,6 +107,7 @@ static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs)
{
struct mc13783_rtc *priv = dev_get_drvdata(dev);
unsigned int seconds, days;
+ unsigned int alarmseconds;
int ret;
seconds = secs % 86400;
@@ -86,7 +116,22 @@ static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs)
mc13783_lock(priv->mc13783);
/*
- * first write seconds=0 to prevent a day switch between writing days
+ * temporarily invalidate alarm to prevent triggering it when the day is
+ * already updated while the time isn't yet.
+ */
+ ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTODA, &alarmseconds);
+ if (unlikely(ret))
+ goto out;
+
+ if (alarmseconds < 86400) {
+ ret = mc13783_reg_write(priv->mc13783,
+ MC13783_RTCTODA, 0x1ffff);
+ if (unlikely(ret))
+ goto out;
+ }
+
+ /*
+ * write seconds=0 to prevent a day switch between writing days
* and seconds below
*/
ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTOD, 0);
@@ -101,11 +146,19 @@ static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs)
if (unlikely(ret))
goto out;
- ret = mc13783_ackirq(priv->mc13783, MC13783_IRQ_RTCRST);
+ /* restore alarm */
+ if (alarmseconds < 86400) {
+ ret = mc13783_reg_write(priv->mc13783,
+ MC13783_RTCTODA, alarmseconds);
+ if (unlikely(ret))
+ goto out;
+ }
+
+ ret = mc13783_irq_ack(priv->mc13783, MC13783_IRQ_RTCRST);
if (unlikely(ret))
goto out;
- ret = mc13783_unmask(priv->mc13783, MC13783_IRQ_RTCRST);
+ ret = mc13783_irq_unmask(priv->mc13783, MC13783_IRQ_RTCRST);
out:
priv->valid = !ret;
@@ -114,41 +167,139 @@ out:
return ret;
}
-static irqreturn_t mc13783_rtc_update_handler(int irq, void *dev)
+static int mc13783_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
- struct mc13783_rtc *priv = dev;
- struct mc13783 *mc13783 = priv->mc13783;
+ struct mc13783_rtc *priv = dev_get_drvdata(dev);
+ unsigned seconds, days;
+ unsigned long s1970;
+ int enabled, pending;
+ int ret;
- dev_dbg(&priv->rtc->dev, "1HZ\n");
+ mc13783_lock(priv->mc13783);
- rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
+ ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTODA, &seconds);
+ if (unlikely(ret))
+ goto out;
+ if (seconds >= 86400) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ ret = mc13783_reg_read(priv->mc13783, MC13783_RTCDAY, &days);
+ if (unlikely(ret))
+ goto out;
- mc13783_ackirq(mc13783, irq);
+ ret = mc13783_irq_status(priv->mc13783, MC13783_IRQ_TODA,
+ &enabled, &pending);
- return IRQ_HANDLED;
+out:
+ mc13783_unlock(priv->mc13783);
+
+ if (ret)
+ return ret;
+
+ alarm->enabled = enabled;
+ alarm->pending = pending;
+
+ s1970 = days * 86400 + seconds;
+
+ rtc_time_to_tm(s1970, &alarm->time);
+ dev_dbg(dev, "%s: %lu\n", __func__, s1970);
+
+ return 0;
}
-static int mc13783_rtc_update_irq_enable(struct device *dev,
- unsigned int enabled)
+static int mc13783_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct mc13783_rtc *priv = dev_get_drvdata(dev);
- int ret = -ENODATA;
+ unsigned long s1970;
+ unsigned seconds, days;
+ int ret;
mc13783_lock(priv->mc13783);
- if (!priv->valid)
+
+ /* disable alarm to prevent false triggering */
+ ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTODA, 0x1ffff);
+ if (unlikely(ret))
goto out;
- ret = (enabled ? mc13783_unmask : mc13783_mask)(priv->mc13783,
- MC13783_IRQ_1HZ);
+ ret = mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TODA);
+ if (unlikely(ret))
+ goto out;
+
+ ret = rtc_tm_to_time(&alarm->time, &s1970);
+ if (unlikely(ret))
+ goto out;
+
+ dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff",
+ s1970);
+
+ ret = mc13783_rtc_irq_enable_unlocked(dev, alarm->enabled,
+ MC13783_IRQ_TODA);
+ if (unlikely(ret))
+ goto out;
+
+ seconds = s1970 % 86400;
+ days = s1970 / 86400;
+
+ ret = mc13783_reg_write(priv->mc13783, MC13783_RTCDAYA, days);
+ if (unlikely(ret))
+ goto out;
+
+ ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTODA, seconds);
+
out:
mc13783_unlock(priv->mc13783);
return ret;
}
+static irqreturn_t mc13783_rtc_alarm_handler(int irq, void *dev)
+{
+ struct mc13783_rtc *priv = dev;
+ struct mc13783 *mc13783 = priv->mc13783;
+
+ dev_dbg(&priv->rtc->dev, "Alarm\n");
+
+ rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF);
+
+ mc13783_irq_ack(mc13783, irq);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mc13783_rtc_update_handler(int irq, void *dev)
+{
+ struct mc13783_rtc *priv = dev;
+ struct mc13783 *mc13783 = priv->mc13783;
+
+ dev_dbg(&priv->rtc->dev, "1HZ\n");
+
+ rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
+
+ mc13783_irq_ack(mc13783, irq);
+
+ return IRQ_HANDLED;
+}
+
+static int mc13783_rtc_update_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ return mc13783_rtc_irq_enable(dev, enabled, MC13783_IRQ_1HZ);
+}
+
+static int mc13783_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ return mc13783_rtc_irq_enable(dev, enabled, MC13783_IRQ_TODA);
+}
+
static const struct rtc_class_ops mc13783_rtc_ops = {
.read_time = mc13783_rtc_read_time,
.set_mmss = mc13783_rtc_set_mmss,
+ .read_alarm = mc13783_rtc_read_alarm,
+ .set_alarm = mc13783_rtc_set_alarm,
+ .alarm_irq_enable = mc13783_rtc_alarm_irq_enable,
.update_irq_enable = mc13783_rtc_update_irq_enable,
};
@@ -160,7 +311,7 @@ static irqreturn_t mc13783_rtc_reset_handler(int irq, void *dev)
dev_dbg(&priv->rtc->dev, "RTCRST\n");
priv->valid = 0;
- mc13783_mask(mc13783, irq);
+ mc13783_irq_mask(mc13783, irq);
return IRQ_HANDLED;
}
@@ -169,50 +320,64 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
{
int ret;
struct mc13783_rtc *priv;
+ struct mc13783 *mc13783;
+ int rtcrst_pending;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
- platform_set_drvdata(pdev, priv);
+ mc13783 = dev_get_drvdata(pdev->dev.parent);
+ priv->mc13783 = mc13783;
- priv->valid = 1;
+ platform_set_drvdata(pdev, priv);
- mc13783_lock(priv->mc13783);
+ mc13783_lock(mc13783);
- ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_RTCRST,
+ ret = mc13783_irq_request(mc13783, MC13783_IRQ_RTCRST,
mc13783_rtc_reset_handler, DRIVER_NAME, priv);
if (ret)
goto err_reset_irq_request;
- ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_1HZ,
+ ret = mc13783_irq_status(mc13783, MC13783_IRQ_RTCRST,
+ NULL, &rtcrst_pending);
+ if (ret)
+ goto err_reset_irq_status;
+
+ priv->valid = !rtcrst_pending;
+
+ ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_1HZ,
mc13783_rtc_update_handler, DRIVER_NAME, priv);
if (ret)
goto err_update_irq_request;
- mc13783_unlock(priv->mc13783);
+ ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_TODA,
+ mc13783_rtc_alarm_handler, DRIVER_NAME, priv);
+ if (ret)
+ goto err_alarm_irq_request;
priv->rtc = rtc_device_register(pdev->name,
&pdev->dev, &mc13783_rtc_ops, THIS_MODULE);
-
if (IS_ERR(priv->rtc)) {
ret = PTR_ERR(priv->rtc);
- mc13783_lock(priv->mc13783);
+ mc13783_irq_free(mc13783, MC13783_IRQ_TODA, priv);
+err_alarm_irq_request:
- mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
+ mc13783_irq_free(mc13783, MC13783_IRQ_1HZ, priv);
err_update_irq_request:
- mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
-err_reset_irq_request:
+err_reset_irq_status:
- mc13783_unlock(priv->mc13783);
+ mc13783_irq_free(mc13783, MC13783_IRQ_RTCRST, priv);
+err_reset_irq_request:
platform_set_drvdata(pdev, NULL);
kfree(priv);
}
+ mc13783_unlock(mc13783);
+
return ret;
}
@@ -220,10 +385,11 @@ static int __devexit mc13783_rtc_remove(struct platform_device *pdev)
{
struct mc13783_rtc *priv = platform_get_drvdata(pdev);
- rtc_device_unregister(priv->rtc);
-
mc13783_lock(priv->mc13783);
+ rtc_device_unregister(priv->rtc);
+
+ mc13783_irq_free(priv->mc13783, MC13783_IRQ_TODA, priv);
mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
index 4313ca03a96..f0dbf9cb8f9 100644
--- a/drivers/rtc/rtc-mpc5121.c
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -15,6 +15,7 @@
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/io.h>
+#include <linux/slab.h>
struct mpc5121_rtc_regs {
u8 set_time; /* RTC + 0x00 */
diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c
index 5f5968a4892..b2fff0ca49f 100644
--- a/drivers/rtc/rtc-msm6242.c
+++ b/drivers/rtc/rtc-msm6242.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
enum {
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index dc052ce6e63..bcca4729855 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -13,6 +13,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#define RTC_TIME_REG_OFFS 0
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index 6bd5072d4eb..d71fe61db1d 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -12,6 +12,7 @@
#include <linux/io.h>
#include <linux/rtc.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
@@ -383,21 +384,29 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
struct rtc_device *rtc;
struct rtc_plat_data *pdata = NULL;
u32 reg;
- int ret, rate;
+ unsigned long rate;
+ int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
- pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
- pdata->ioaddr = ioremap(res->start, resource_size(res));
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name))
+ return -EBUSY;
+
+ pdata->ioaddr = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
clk = clk_get(&pdev->dev, "ckil");
- if (IS_ERR(clk))
- return PTR_ERR(clk);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ goto exit_free_pdata;
+ }
rate = clk_get_rate(clk);
clk_put(clk);
@@ -409,8 +418,7 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
else if (rate == 38400)
reg = RTC_INPUT_CLK_38400HZ;
else {
- dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n",
- clk_get_rate(clk));
+ dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate);
ret = -EINVAL;
goto exit_free_pdata;
}
@@ -446,8 +454,8 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
pdata->irq = platform_get_irq(pdev, 0);
if (pdata->irq >= 0 &&
- request_irq(pdata->irq, mxc_rtc_interrupt, IRQF_SHARED,
- pdev->name, pdev) < 0) {
+ devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt,
+ IRQF_SHARED, pdev->name, pdev) < 0) {
dev_warn(&pdev->dev, "interrupt not available.\n");
pdata->irq = -1;
}
@@ -455,10 +463,10 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
return 0;
exit_put_clk:
+ clk_disable(pdata->clk);
clk_put(pdata->clk);
exit_free_pdata:
- kfree(pdata);
return ret;
}
@@ -469,12 +477,8 @@ static int __exit mxc_rtc_remove(struct platform_device *pdev)
rtc_device_unregister(pdata->rtc);
- if (pdata->irq >= 0)
- free_irq(pdata->irq, pdev);
-
clk_disable(pdata->clk);
clk_put(pdata->clk);
- kfree(pdata);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c
index bf59c9c586b..a351bd5d817 100644
--- a/drivers/rtc/rtc-nuc900.c
+++ b/drivers/rtc/rtc-nuc900.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/delay.h>
#include <linux/io.h>
diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c
index a99c28992d2..25c0b3fd44f 100644
--- a/drivers/rtc/rtc-pcap.c
+++ b/drivers/rtc/rtc-pcap.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/mfd/ezx-pcap.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
struct pcap_rtc {
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
index e75df9d50e2..71bab0ef544 100644
--- a/drivers/rtc/rtc-pcf2123.c
+++ b/drivers/rtc/rtc-pcf2123.c
@@ -39,6 +39,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/spi/spi.h>
@@ -315,7 +316,7 @@ kfree_exit:
return ret;
}
-static int pcf2123_remove(struct spi_device *spi)
+static int __devexit pcf2123_remove(struct spi_device *spi)
{
struct pcf2123_plat_data *pdata = spi->dev.platform_data;
int i;
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
index 854c3cb365a..16edf94ab42 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 65f346b2fba..1af42b4a6f5 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -17,6 +17,7 @@
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
#define DRV_VERSION "0.4.3"
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
index 457231bb102..bbdb2f02798 100644
--- a/drivers/rtc/rtc-pl030.c
+++ b/drivers/rtc/rtc-pl030.c
@@ -13,6 +13,7 @@
#include <linux/interrupt.h>
#include <linux/amba/bus.h>
#include <linux/io.h>
+#include <linux/slab.h>
#define RTC_DR (0)
#define RTC_MR (4)
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index c256aacfa95..3587d9922f2 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -24,6 +24,7 @@
#include <linux/bcd.h>
#include <linux/delay.h>
#include <linux/version.h>
+#include <linux/slab.h>
/*
* Register definitions
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c
index e6351b743da..e9c6fa03598 100644
--- a/drivers/rtc/rtc-pxa.c
+++ b/drivers/rtc/rtc-pxa.c
@@ -26,6 +26,7 @@
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c
index e1313feb060..a95f733bb15 100644
--- a/drivers/rtc/rtc-rp5c01.c
+++ b/drivers/rtc/rtc-rp5c01.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
enum {
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
index 2099037cb3e..368d0e63cf8 100644
--- a/drivers/rtc/rtc-rs5c348.c
+++ b/drivers/rtc/rtc-rs5c348.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/workqueue.h>
#include <linux/spi/spi.h>
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 2f2c68d476d..90cf0a6ff23 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -13,6 +13,7 @@
#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
+#include <linux/slab.h>
#define DRV_VERSION "0.6"
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index b1a29bcfdf1..b65c82f792d 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -20,6 +20,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/bcd.h>
#include <linux/i2c.h>
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index e0d7b999150..4969b6059c8 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -21,6 +21,7 @@
#include <linux/bcd.h>
#include <linux/clk.h>
#include <linux/log2.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <asm/uaccess.h>
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index e95cc6f8d61..5efbd5990ff 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -26,6 +26,7 @@
#include <linux/io.h>
#include <linux/log2.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <asm/rtc.h>
#define DRV_NAME "sh-rtc"
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index 67700831b5c..875ba099e7a 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -14,6 +14,7 @@
#include <linux/bcd.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c
index d7ce1a5c857..7e7d0c806f2 100644
--- a/drivers/rtc/rtc-stmp3xxx.c
+++ b/drivers/rtc/rtc-stmp3xxx.c
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
#include <mach/platform.h>
#include <mach/stmp3xxx.h>
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 7dd23a6fc82..380083ca572 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -107,8 +107,9 @@ rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr,
char *buf)
{
#ifdef CONFIG_RTC_HCTOSYS_DEVICE
- if (strcmp(dev_name(&to_rtc_device(dev)->dev),
- CONFIG_RTC_HCTOSYS_DEVICE) == 0)
+ if (rtc_hctosys_ret == 0 &&
+ strcmp(dev_name(&to_rtc_device(dev)->dev),
+ CONFIG_RTC_HCTOSYS_DEVICE) == 0)
return sprintf(buf, "1\n");
else
#endif
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index c6a83a2a722..ed1b8682812 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -57,7 +57,7 @@ enum {
REG_RTC_COMP_LSB_REG,
REG_RTC_COMP_MSB_REG,
};
-const static u8 twl4030_rtc_reg_map[] = {
+static const u8 twl4030_rtc_reg_map[] = {
[REG_SECONDS_REG] = 0x00,
[REG_MINUTES_REG] = 0x01,
[REG_HOURS_REG] = 0x02,
@@ -80,7 +80,7 @@ const static u8 twl4030_rtc_reg_map[] = {
[REG_RTC_COMP_LSB_REG] = 0x10,
[REG_RTC_COMP_MSB_REG] = 0x11,
};
-const static u8 twl6030_rtc_reg_map[] = {
+static const u8 twl6030_rtc_reg_map[] = {
[REG_SECONDS_REG] = 0x00,
[REG_MINUTES_REG] = 0x01,
[REG_HOURS_REG] = 0x02,
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c
index 9ee81d8aa7c..20bfc64a15c 100644
--- a/drivers/rtc/rtc-tx4939.c
+++ b/drivers/rtc/rtc-tx4939.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <asm/txx9/tx4939.h>
struct tx4939rtc_plat_data {
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index bed4cab0704..f71c3ce1803 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -28,6 +28,7 @@
#include <linux/rtc-v3020.h>
#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <linux/io.h>
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c
index 000c7e481e5..b16cfe57a48 100644
--- a/drivers/rtc/rtc-wm831x.c
+++ b/drivers/rtc/rtc-wm831x.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/rtc.h>
+#include <linux/slab.h>
#include <linux/bcd.h>
#include <linux/interrupt.h>
#include <linux/ioctl.h>
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index f1e440521c5..3d0dc76b38a 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -307,11 +307,18 @@ static int wm8350_rtc_update_irq_enable(struct device *dev,
{
struct wm8350 *wm8350 = dev_get_drvdata(dev);
+ /* Suppress duplicate changes since genirq nests enable and
+ * disable calls. */
+ if (enabled == wm8350->rtc.update_enabled)
+ return 0;
+
if (enabled)
wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC);
else
wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
+ wm8350->rtc.update_enabled = enabled;
+
return 0;
}
@@ -478,8 +485,8 @@ static int __devexit wm8350_rtc_remove(struct platform_device *pdev)
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
struct wm8350_rtc *wm_rtc = &wm8350->rtc;
- wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC);
- wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM);
+ wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350);
rtc_device_unregister(wm_rtc->rtc);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 4951aa82e9f..acf222f91f5 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -26,6 +26,7 @@
#include <asm/ebcdic.h>
#include <asm/idals.h>
#include <asm/itcw.h>
+#include <asm/diag.h>
/* This is ugly... */
#define PRINTK_HEADER "dasd:"
@@ -1898,7 +1899,8 @@ restart:
/* Process requests that may be recovered */
if (cqr->status == DASD_CQR_NEED_ERP) {
erp_fn = base->discipline->erp_action(cqr);
- erp_fn(cqr);
+ if (IS_ERR(erp_fn(cqr)))
+ continue;
goto restart;
}
@@ -2212,6 +2214,13 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
goto out;
}
+ if ((mode & FMODE_WRITE) &&
+ (test_bit(DASD_FLAG_DEVICE_RO, &base->flags) ||
+ (base->features & DASD_FEATURE_READONLY))) {
+ rc = -EROFS;
+ goto out;
+ }
+
return 0;
out:
@@ -2289,6 +2298,34 @@ dasd_exit(void)
* SECTION: common functions for ccw_driver use
*/
+/*
+ * Is the device read-only?
+ * Note that this function does not report the setting of the
+ * readonly device attribute, but how it is configured in z/VM.
+ */
+int dasd_device_is_ro(struct dasd_device *device)
+{
+ struct ccw_dev_id dev_id;
+ struct diag210 diag_data;
+ int rc;
+
+ if (!MACHINE_IS_VM)
+ return 0;
+ ccw_device_get_id(device->cdev, &dev_id);
+ memset(&diag_data, 0, sizeof(diag_data));
+ diag_data.vrdcdvno = dev_id.devno;
+ diag_data.vrdclen = sizeof(diag_data);
+ rc = diag210(&diag_data);
+ if (rc == 0 || rc == 2) {
+ return diag_data.vrdcvfla & 0x80;
+ } else {
+ DBF_EVENT(DBF_WARNING, "diag210 failed for dev=%04x with rc=%d",
+ dev_id.devno, rc);
+ return 0;
+ }
+}
+EXPORT_SYMBOL_GPL(dasd_device_is_ro);
+
static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
{
struct ccw_device *cdev = data;
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 44796ba4eb9..6632649dd6a 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -10,7 +10,6 @@
#define KMSG_COMPONENT "dasd-eckd"
#include <linux/timer.h>
-#include <linux/slab.h>
#include <asm/idals.h>
#define PRINTK_HEADER "dasd_erp(3990): "
@@ -1045,6 +1044,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
erp->retries = 5;
+ } else if (sense[1] & SNS1_WRITE_INHIBITED) {
+ dev_err(&device->cdev->dev, "An I/O request was rejected"
+ " because writing is inhibited\n");
+ erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
} else {
/* fatal error - set status to FAILED
internal error 09 - Command Reject */
@@ -2283,7 +2286,8 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
if (cqr->cpmode == 1) {
cplength = 0;
- datasize = sizeof(struct tcw) + sizeof(struct tsb);
+ /* TCW needs to be 64 byte aligned, so leave enough room */
+ datasize = 64 + sizeof(struct tcw) + sizeof(struct tsb);
} else {
cplength = 2;
datasize = 0;
@@ -2305,15 +2309,15 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
cqr->retries);
dasd_block_set_timer(device->block, (HZ << 3));
}
- return cqr;
+ return erp;
}
ccw = cqr->cpaddr;
if (cqr->cpmode == 1) {
/* make a shallow copy of the original tcw but set new tsb */
erp->cpmode = 1;
- erp->cpaddr = erp->data;
- tcw = erp->data;
+ erp->cpaddr = PTR_ALIGN(erp->data, 64);
+ tcw = erp->cpaddr;
tsb = (struct tsb *) &tcw[1];
*tcw = *((struct tcw *)cqr->cpaddr);
tcw->tsb = (long)tsb;
@@ -2368,6 +2372,9 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
/* add erp and initialize with default TIC */
erp = dasd_3990_erp_add_erp(cqr);
+ if (IS_ERR(erp))
+ return erp;
+
/* inspect sense, determine specific ERP if possible */
if (erp != cqr) {
@@ -2707,6 +2714,8 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
if (erp == NULL) {
/* no matching erp found - set up erp */
erp = dasd_3990_erp_additional_erp(cqr);
+ if (IS_ERR(erp))
+ return erp;
} else {
/* matching erp found - set all leading erp's to DONE */
erp = dasd_3990_erp_handle_match_erp(cqr, erp);
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 148b1dd2407..8c4814258e9 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -8,6 +8,7 @@
#define KMSG_COMPONENT "dasd-eckd"
#include <linux/list.h>
+#include <linux/slab.h>
#include <asm/ebcdic.h>
#include "dasd_int.h"
#include "dasd_eckd.h"
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index d49766f3b94..eff9c812c5c 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -18,6 +18,7 @@
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/debug.h>
#include <asm/uaccess.h>
@@ -742,6 +743,7 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct dasd_devmap *devmap;
+ struct dasd_device *device;
int val;
char *endp;
@@ -758,12 +760,14 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
devmap->features |= DASD_FEATURE_READONLY;
else
devmap->features &= ~DASD_FEATURE_READONLY;
- if (devmap->device)
- devmap->device->features = devmap->features;
- if (devmap->device && devmap->device->block
- && devmap->device->block->gdp)
- set_disk_ro(devmap->device->block->gdp, val);
+ device = devmap->device;
+ if (device) {
+ device->features = devmap->features;
+ val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
+ }
spin_unlock(&dasd_devmap_lock);
+ if (device && device->block && device->block->gdp)
+ set_disk_ro(device->block->gdp, val);
return count;
}
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 6e14863f5c7..687f323cdc3 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -145,12 +145,10 @@ dasd_diag_erp(struct dasd_device *device)
mdsk_term_io(device);
rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
if (rc == 4) {
- if (!(device->features & DASD_FEATURE_READONLY)) {
+ if (!(test_and_set_bit(DASD_FLAG_DEVICE_RO, &device->flags)))
pr_warning("%s: The access mode of a DIAG device "
"changed to read-only\n",
dev_name(&device->cdev->dev));
- device->features |= DASD_FEATURE_READONLY;
- }
rc = 0;
}
if (rc)
@@ -449,7 +447,7 @@ dasd_diag_check_device(struct dasd_device *device)
rc = -EIO;
} else {
if (rc == 4)
- device->features |= DASD_FEATURE_READONLY;
+ set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
pr_info("%s: New DASD with %ld byte/block, total size %ld "
"KB%s\n", dev_name(&device->cdev->dev),
(unsigned long) block->bp_block,
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 1cca21aafab..0cb23311685 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1089,6 +1089,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
struct dasd_eckd_private *private;
struct dasd_block *block;
int is_known, rc;
+ int readonly;
if (!ccw_device_is_pathgroup(device->cdev)) {
dev_warn(&device->cdev->dev,
@@ -1182,15 +1183,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
else
private->real_cyl = private->rdc_data.no_cyl;
+ readonly = dasd_device_is_ro(device);
+ if (readonly)
+ set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
+
dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
- "with %d cylinders, %d heads, %d sectors\n",
+ "with %d cylinders, %d heads, %d sectors%s\n",
private->rdc_data.dev_type,
private->rdc_data.dev_model,
private->rdc_data.cu_type,
private->rdc_data.cu_model.model,
private->real_cyl,
private->rdc_data.trk_per_cyl,
- private->rdc_data.sec_per_trk);
+ private->rdc_data.sec_per_trk,
+ readonly ? ", read-only device" : "");
return 0;
out_err3:
@@ -2839,8 +2845,13 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
char *psf_data, *rssd_result;
struct dasd_ccw_req *cqr;
struct ccw1 *ccw;
+ char psf0, psf1;
int rc;
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
+ return -EACCES;
+ psf0 = psf1 = 0;
+
/* Copy parms from caller */
rc = -EFAULT;
if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
@@ -2869,12 +2880,8 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
(void __user *)(unsigned long) usrparm.psf_data,
usrparm.psf_data_len))
goto out_free;
-
- /* sanity check on syscall header */
- if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
- rc = -EINVAL;
- goto out_free;
- }
+ psf0 = psf_data[0];
+ psf1 = psf_data[1];
/* setup CCWs for PSF + RSSD */
cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device);
@@ -2925,7 +2932,9 @@ out_free:
kfree(rssd_result);
kfree(psf_data);
out:
- DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc);
+ DBF_DEV_EVENT(DBF_WARNING, device,
+ "Symmetrix ioctl (0x%02x 0x%02x): rc=%d",
+ (int) psf0, (int) psf1, rc);
return rc;
}
@@ -3146,11 +3155,11 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
tsb = NULL;
sense = NULL;
- if (irb->scsw.tm.tcw)
+ if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs == 0x01))
tsb = tcw_get_tsb(
(struct tcw *)(unsigned long)irb->scsw.tm.tcw);
- if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+ if (tsb) {
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" tsb->length %d\n", tsb->length);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 1f3e967aaba..dd88803e489 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -19,6 +19,7 @@
#include <linux/mutex.h>
#include <linux/smp_lock.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 0f152444ac7..37282b90eec 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -124,6 +124,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
struct dasd_fba_private *private;
struct ccw_device *cdev = device->cdev;
int rc;
+ int readonly;
private = (struct dasd_fba_private *) device->private;
if (!private) {
@@ -162,16 +163,21 @@ dasd_fba_check_characteristics(struct dasd_device *device)
return rc;
}
+ readonly = dasd_device_is_ro(device);
+ if (readonly)
+ set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
+
dev_info(&device->cdev->dev,
"New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
- "and %d B/blk\n",
+ "and %d B/blk%s\n",
cdev->id.dev_type,
cdev->id.dev_model,
cdev->id.cu_type,
cdev->id.cu_model,
((private->rdc_data.blk_bdsa *
(private->rdc_data.blk_size >> 9)) >> 11),
- private->rdc_data.blk_size);
+ private->rdc_data.blk_size,
+ readonly ? ", read-only device" : "");
return 0;
}
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 94f92a1247f..30a1ca3d08b 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -70,7 +70,8 @@ int dasd_gendisk_alloc(struct dasd_block *block)
}
len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26));
- if (block->base->features & DASD_FEATURE_READONLY)
+ if (base->features & DASD_FEATURE_READONLY ||
+ test_bit(DASD_FLAG_DEVICE_RO, &base->flags))
set_disk_ro(gdp, 1);
gdp->private_data = block;
gdp->queue = block->request_queue;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index ed73ce55082..a91d4a97d4f 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -436,6 +436,10 @@ struct dasd_block {
#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */
#define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */
+#define DASD_FLAG_DEVICE_RO 6 /* The device itself is read-only. Don't
+ * confuse this with the user specified
+ * read-only feature.
+ */
void dasd_put_device_wake(struct dasd_device *);
@@ -609,6 +613,9 @@ char *dasd_get_sense(struct irb *);
void dasd_device_set_stop_bits(struct dasd_device *, int);
void dasd_device_remove_stop_bits(struct dasd_device *, int);
+int dasd_device_is_ro(struct dasd_device *);
+
+
/* externals in dasd_devmap.c */
extern int dasd_max_devindex;
extern int dasd_probeonly;
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 7039d9cf0fb..1557214944f 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/blkpg.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <asm/compat.h>
#include <asm/ccwdev.h>
#include <asm/cmb.h>
@@ -199,7 +200,8 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp)
if (!argp)
return -EINVAL;
- if (block->base->features & DASD_FEATURE_READONLY)
+ if (block->base->features & DASD_FEATURE_READONLY ||
+ test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
return -EROFS;
if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
return -EFAULT;
@@ -349,7 +351,8 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp)
return -EINVAL;
if (get_user(intval, (int __user *)argp))
return -EFAULT;
-
+ if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
+ return -EROFS;
set_disk_ro(bdev->bd_disk, intval);
return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval);
}
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index f13a0bdd148..2eb02559280 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -14,6 +14,7 @@
#define KMSG_COMPONENT "dasd"
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 118de392af6..c881a14fa5d 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -33,7 +33,6 @@
#include <linux/ctype.h> /* isdigit, isxdigit */
#include <linux/errno.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/hdreg.h> /* HDIO_GETGEO */
@@ -41,6 +40,7 @@
#include <linux/bio.h>
#include <linux/suspend.h>
#include <linux/platform_device.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#define XPRAM_NAME "xpram"
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 6bca81aea39..bb07577e8fd 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/reboot.h>
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 31c59b0d6df..0eabcca3c92 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/smp_lock.h>
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index cee4d4e4242..cb6bffe7141 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/sysrq.h>
#include <linux/consolemap.h>
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index 33e96484d54..2ed3f82e5c3 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <net/iucv/iucv.h>
#include <asm/uaccess.h>
#include <asm/ebcdic.h>
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 668a0579b26..98a49dfda1d 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -20,6 +20,7 @@
#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/ebcdic.h>
#include <asm/io.h>
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 62ddf5202b7..2a4c566456e 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -373,7 +373,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
(unsigned long) rq, 0, 0);
if (rq->rc == 0)
- return; /* Sucessfully restarted. */
+ return; /* Successfully restarted. */
break;
case RAW3270_IO_STOP:
if (!rq)
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index ec88c59842e..f6d72e1f2a3 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -196,7 +196,7 @@ __sclp_start_request(struct sclp_req *req)
req->start_count++;
if (rc == 0) {
- /* Sucessfully started request */
+ /* Successfully started request */
req->status = SCLP_REQ_RUNNING;
sclp_running_state = sclp_running_state_running;
__sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ,
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c
index 740fe405c39..7ad30e72f86 100644
--- a/drivers/s390/char/sclp_async.c
+++ b/drivers/s390/char/sclp_async.c
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/stat.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/kmod.h>
#include <linux/err.h>
@@ -84,6 +85,7 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write,
rc = copy_from_user(buf, buffer, sizeof(buf));
if (rc != 0)
return -EFAULT;
+ buf[sizeof(buf) - 1] = '\0';
if (strict_strtoul(buf, 0, &val) != 0)
return -EINVAL;
if (val != 0 && val != 1)
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index b3beab610da..4b60ede07f0 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -308,6 +308,13 @@ struct assign_storage_sccb {
u16 rn;
} __packed;
+int arch_get_memory_phys_device(unsigned long start_pfn)
+{
+ if (!rzm)
+ return 0;
+ return PFN_PHYS(start_pfn) >> ilog2(rzm);
+}
+
static unsigned long long rn2addr(u16 rn)
{
return (unsigned long long) (rn - 1) * rzm;
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
index ad698d30cb3..ecf45c54f8c 100644
--- a/drivers/s390/char/sclp_con.c
+++ b/drivers/s390/char/sclp_con.c
@@ -14,6 +14,7 @@
#include <linux/termios.h>
#include <linux/err.h>
#include <linux/reboot.h>
+#include <linux/gfp.h>
#include "sclp.h"
#include "sclp_rw.h"
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 434ba04b130..8258d590505 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -13,10 +13,10 @@
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
-#include <linux/slab.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#include "ctrlchar.h"
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 3796ffdb847..5d706e6c946 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/reboot.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include "sclp.h"
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index cb70fa1cf53..c17f35b6136 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/bio.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#define TAPE_DBF_AREA tape_34xx_dbf
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 9821c588661..fc993acf99b 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -12,6 +12,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/bio.h>
#include <asm/ebcdic.h>
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index b2864e3edb6..55343df61ed 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -11,6 +11,8 @@
#define KMSG_COMPONENT "tape"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/slab.h>
+
#include "tape_class.h"
MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 81b094e480e..29c2d73d719 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -20,6 +20,7 @@
#include <linux/spinlock.h> // for locks
#include <linux/vmalloc.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <asm/types.h> // for variable types
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 921dcda7767..5bb59d36a6d 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/compat.h>
#include <asm/cpcmd.h>
#include <asm/debug.h>
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 7dfa5412d5a..e40a1b89286 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/interrupt.h>
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index cc56fc708ba..1de672f2103 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -12,6 +12,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/cdev.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index c974058e48d..e13508c98b1 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -17,6 +17,7 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/watchdog.h>
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 3438658b66b..7217966f7d3 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -13,6 +13,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/debugfs.h>
#include <asm/asm-offsets.h>
@@ -141,33 +142,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
return memcpy_hsa(dest, src, count, TO_KERNEL);
}
-static int memcpy_real(void *dest, unsigned long src, size_t count)
-{
- unsigned long flags;
- int rc = -EFAULT;
- register unsigned long _dest asm("2") = (unsigned long) dest;
- register unsigned long _len1 asm("3") = (unsigned long) count;
- register unsigned long _src asm("4") = src;
- register unsigned long _len2 asm("5") = (unsigned long) count;
-
- if (count == 0)
- return 0;
- flags = __raw_local_irq_stnsm(0xf8UL); /* switch to real mode */
- asm volatile (
- "0: mvcle %1,%2,0x0\n"
- "1: jo 0b\n"
- " lhi %0,0x0\n"
- "2:\n"
- EX_TABLE(1b,2b)
- : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
- "+d" (_len2), "=m" (*((long*)dest))
- : "m" (*((long*)src))
- : "cc", "memory");
- __raw_local_irq_ssm(flags);
-
- return rc;
-}
-
static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
{
static char buf[4096];
@@ -175,7 +149,7 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
while (offs < count) {
size = min(sizeof(buf), count - offs);
- if (memcpy_real(buf, src + offs, size))
+ if (memcpy_real(buf, (void *) src + offs, size))
return -EFAULT;
if (copy_to_user(dest + offs, buf, size))
return -EFAULT;
@@ -663,12 +637,8 @@ static int __init zcore_reipl_init(void)
if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
else
- rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE);
- if (rc) {
- free_page((unsigned long) ipl_block);
- return rc;
- }
- if (csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
+ rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
+ if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
ipib_info.checksum) {
TRACE("Checksum does not match\n");
free_page((unsigned long) ipl_block);
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 7eab9ab9f40..13cb60162e4 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -14,7 +14,6 @@
#include <linux/init.h>
#include <linux/vmalloc.h>
-#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/ctype.h>
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index c268a2e5b7c..1d16189f2f2 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -15,6 +15,7 @@
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <asm/chpid.h>
#include <asm/sclp.h>
#include <asm/crw.h>
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 4038f5b4f14..ce7cb87479f 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(sda_lock);
/**
* chsc_error_from_response() - convert a chsc response to an error
@@ -832,11 +833,10 @@ void __init chsc_free_sei_area(void)
kfree(sei_page);
}
-int __init
-chsc_enable_facility(int operation_code)
+int chsc_enable_facility(int operation_code)
{
int ret;
- struct {
+ static struct {
struct chsc_header request;
u8 reserved1:4;
u8 format:4;
@@ -849,33 +849,32 @@ chsc_enable_facility(int operation_code)
u32 reserved5:4;
u32 format2:4;
u32 reserved6:24;
- } __attribute__ ((packed)) *sda_area;
+ } __attribute__ ((packed, aligned(4096))) sda_area;
- sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA);
- if (!sda_area)
- return -ENOMEM;
- sda_area->request.length = 0x0400;
- sda_area->request.code = 0x0031;
- sda_area->operation_code = operation_code;
+ spin_lock(&sda_lock);
+ memset(&sda_area, 0, sizeof(sda_area));
+ sda_area.request.length = 0x0400;
+ sda_area.request.code = 0x0031;
+ sda_area.operation_code = operation_code;
- ret = chsc(sda_area);
+ ret = chsc(&sda_area);
if (ret > 0) {
ret = (ret == 3) ? -ENODEV : -EBUSY;
goto out;
}
- switch (sda_area->response.code) {
+ switch (sda_area.response.code) {
case 0x0101:
ret = -EOPNOTSUPP;
break;
default:
- ret = chsc_error_from_response(sda_area->response.code);
+ ret = chsc_error_from_response(sda_area.response.code);
}
if (ret != 0)
CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
- operation_code, sda_area->response.code);
+ operation_code, sda_area.response.code);
out:
- free_page((unsigned long)sda_area);
+ spin_unlock(&sda_lock);
return ret;
}
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 852612f5dba..3b6f4adc509 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -7,6 +7,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/uaccess.h>
@@ -123,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch)
* since we don't have a way to clear the subchannel and
* cannot disable it with a request running.
*/
- cc = stsch(sch->schid, &schib);
+ cc = stsch_err(sch->schid, &schib);
if (!cc && scsw_stctl(&schib.scsw))
return -EAGAIN;
return 0;
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index f736cdcf08a..5feea1a371e 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel *sch)
struct schib schib;
int ccode, retry, ret = 0;
- if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
+ if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
return -ENODEV;
for (retry = 0; retry < 5; retry++) {
@@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel *sch)
return ccode;
switch (ccode) {
case 0: /* successful */
- if (stsch(sch->schid, &schib) ||
+ if (stsch_err(sch->schid, &schib) ||
!css_sch_is_valid(&schib))
return -ENODEV;
if (cio_check_config(sch, &schib)) {
@@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *sch)
{
struct schib schib;
- if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
+ if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
return -ENODEV;
memcpy(&sch->schib, &schib, sizeof(schib));
@@ -771,7 +771,7 @@ cio_get_console_sch_no(void)
if (console_irq != -1) {
/* VM provided us with the irq number of the console. */
schid.sch_no = console_irq;
- if (stsch(schid, &console_subchannel.schib) != 0 ||
+ if (stsch_err(schid, &console_subchannel.schib) != 0 ||
(console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) ||
!console_subchannel.schib.pmcw.dnv)
return -1;
@@ -863,10 +863,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
cc = 0;
for (retry=0;retry<3;retry++) {
schib->pmcw.ena = 0;
- cc = msch(schid, schib);
+ cc = msch_err(schid, schib);
if (cc)
return (cc==3?-ENODEV:-EBUSY);
- if (stsch(schid, schib) || !css_sch_is_valid(schib))
+ if (stsch_err(schid, schib) || !css_sch_is_valid(schib))
return -ENODEV;
if (!schib->pmcw.ena)
return 0;
@@ -913,7 +913,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr)
pgm_check_occured = 0;
s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
- rc = stsch(schid, addr);
+ rc = stsch_err(schid, addr);
s390_base_pgm_handler_fn = NULL;
/* The program check handler could have changed pgm_check_occured. */
@@ -950,7 +950,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
/* No default clear strategy */
break;
}
- stsch(schid, &schib);
+ stsch_err(schid, &schib);
__disable_subchannel_easy(schid, &schib);
}
out:
@@ -1086,7 +1086,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
if (!schid.one)
return -ENODEV;
- if (stsch(schid, &schib))
+ if (stsch_err(schid, &schib))
return -ENODEV;
if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
return -ENODEV;
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 2769da54f2b..511649115bd 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -870,15 +870,10 @@ static int __init css_bus_init(void)
/* Try to enable MSS. */
ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
- switch (ret) {
- case 0: /* Success. */
- max_ssid = __MAX_SSID;
- break;
- case -ENOMEM:
- goto out;
- default:
+ if (ret)
max_ssid = 0;
- }
+ else /* Success. */
+ max_ssid = __MAX_SSID;
ret = slow_subchannel_init();
if (ret)
@@ -1048,6 +1043,11 @@ static int __init channel_subsystem_init_sync(void)
}
subsys_initcall_sync(channel_subsystem_init_sync);
+void channel_subsystem_reinit(void)
+{
+ chsc_enable_facility(CHSC_SDA_OC_MSS);
+}
+
#ifdef CONFIG_PROC_FS
static ssize_t cio_settle_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index c6abb75c461..6d229f3523a 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -764,7 +764,7 @@ static void sch_create_and_recog_new_device(struct subchannel *sch)
static void io_subchannel_register(struct ccw_device *cdev)
{
struct subchannel *sch;
- int ret;
+ int ret, adjust_init_count = 1;
unsigned long flags;
sch = to_subchannel(cdev->dev.parent);
@@ -793,6 +793,7 @@ static void io_subchannel_register(struct ccw_device *cdev)
cdev->private->dev_id.ssid,
cdev->private->dev_id.devno);
}
+ adjust_init_count = 0;
goto out;
}
/*
@@ -818,7 +819,7 @@ out:
cdev->private->flags.recog_done = 1;
wake_up(&cdev->private->wait_q);
out_err:
- if (atomic_dec_and_test(&ccw_device_init_count))
+ if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq);
}
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index c56ab94612f..c9b852647f0 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_device *cdev)
sch = to_subchannel(cdev->dev.parent);
private = to_io_private(sch);
orb = &private->orb;
- cc = stsch(sch->schid, &schib);
+ cc = stsch_err(sch->schid, &schib);
printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
"device information:\n", get_clock());
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index c94eb2a0fa2..6ce83f56d53 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -33,7 +33,6 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data,
DBF_HEX(&init_data->input_handler, sizeof(void *));
DBF_HEX(&init_data->output_handler, sizeof(void *));
DBF_HEX(&init_data->int_parm, sizeof(long));
- DBF_HEX(&init_data->flags, sizeof(long));
DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 232ef047ba3..88be7b9ea6e 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <asm/atomic.h>
#include <asm/debug.h>
#include <asm/qdio.h>
@@ -588,10 +589,11 @@ static void qdio_kick_handler(struct qdio_q *q)
if (q->is_input_q) {
qperf_inc(q, inbound_handler);
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
- } else
+ } else {
qperf_inc(q, outbound_handler);
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
start, count);
+ }
q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
q->irq_ptr->int_parm);
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 9942c1031b2..ce5f8910ff8 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -7,6 +7,7 @@
* Jan Glauber <jang@linux.vnet.ibm.com>
*/
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/debug.h>
#include <asm/qdio.h>
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 20836eff88c..91c6028d7b7 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -33,6 +33,7 @@
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include <linux/notifier.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index ba50fe02e57..304caf54997 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -36,6 +36,7 @@
#include <linux/seq_file.h>
#include <linux/compat.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include <linux/hw_random.h>
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index c6fb0aa8950..9c409efa1ec 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -27,6 +27,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/err.h>
#include <asm/atomic.h>
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index e78df3671ca..09e934b295a 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -27,6 +27,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/err.h>
#include <asm/atomic.h>
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index 142f72a2ca5..9dec5c77cff 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/err.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 68f3e6204db..510fab4577d 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index b2fc4fd63f7..4e298bc8949 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>
+#include <linux/slab.h>
#include <linux/virtio_console.h>
#include <linux/interrupt.h>
#include <linux/virtio_ring.h>
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index cb909a5b504..977bb4d4ed1 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -43,6 +43,16 @@ config SMSGIUCV
Select this option if you want to be able to receive SMSG messages
from other VM guest systems.
+config SMSGIUCV_EVENT
+ tristate "Deliver IUCV special messages as uevents (VM only)"
+ depends on SMSGIUCV
+ help
+ Select this option to deliver CP special messages (SMSGs) as
+ uevents. The driver handles only those special messages that
+ start with "APP".
+
+ To compile as a module, choose M. The module name is "smsgiucv_app".
+
config CLAW
tristate "CLAW device support"
depends on CCW && NETDEVICES
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 6cab5a62f99..4dfe8c1092d 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -6,6 +6,7 @@ ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o
obj-$(CONFIG_CTCM) += ctcm.o fsm.o
obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
+obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o
obj-$(CONFIG_LCS) += lcs.o
obj-$(CONFIG_CLAW) += claw.o
qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
diff --git a/drivers/s390/net/ctcm_dbug.c b/drivers/s390/net/ctcm_dbug.c
index 1ca58f15347..d962fd741a2 100644
--- a/drivers/s390/net/ctcm_dbug.c
+++ b/drivers/s390/net/ctcm_dbug.c
@@ -10,7 +10,6 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/sysctl.h>
#include <linux/module.h>
diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c
index 738ad26c74a..2b24550e865 100644
--- a/drivers/s390/net/ctcm_sysfs.c
+++ b/drivers/s390/net/ctcm_sysfs.c
@@ -14,6 +14,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/sysfs.h>
+#include <linux/slab.h>
#include "ctcm_main.h"
/*
diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
index cae48cbc5e9..e5dea67f902 100644
--- a/drivers/s390/net/fsm.c
+++ b/drivers/s390/net/fsm.c
@@ -5,6 +5,7 @@
#include "fsm.h"
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/timer.h>
MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index f6cc46dc050..9b19ea13b4d 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -37,6 +37,7 @@
#include <linux/igmp.h>
#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <net/ip.h>
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index a3ac4456e0b..fcd005aad98 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -763,7 +763,8 @@ static inline int qeth_get_micros(void)
static inline int qeth_get_ip_version(struct sk_buff *skb)
{
- switch (skb->protocol) {
+ struct ethhdr *ehdr = (struct ethhdr *)skb->data;
+ switch (ehdr->h_proto) {
case ETH_P_IPV6:
return 6;
case ETH_P_IP:
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index fa8a519218a..3ba738b2e27 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -20,6 +20,7 @@
#include <linux/tcp.h>
#include <linux/mii.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <asm/ebcdic.h>
#include <asm/io.h>
@@ -537,7 +538,8 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel,
dev_err(&card->gdev->dev,
"The qeth device is not configured "
"for the OSI layer required by z/VM\n");
- qeth_schedule_recovery(card);
+ else
+ qeth_schedule_recovery(card);
goto out;
}
@@ -1113,8 +1115,6 @@ static int qeth_setup_card(struct qeth_card *card)
card->ipato.enabled = 0;
card->ipato.invert4 = 0;
card->ipato.invert6 = 0;
- if (card->info.type == QETH_CARD_TYPE_IQD)
- card->options.checksum_type = NO_CHECKSUMMING;
/* init QDIO stuff */
qeth_init_qdio_info(card);
return 0;
@@ -3805,9 +3805,6 @@ static int qeth_qdio_establish(struct qeth_card *card)
init_data.input_handler = card->discipline.input_handler;
init_data.output_handler = card->discipline.output_handler;
init_data.int_parm = (unsigned long) card;
- init_data.flags = QDIO_INBOUND_0COPY_SBALS |
- QDIO_OUTBOUND_0COPY_SBALS |
- QDIO_USE_OUTBOUND_PCIS;
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 88ae4357136..25dfd5abd19 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -8,6 +8,9 @@
* Frank Blaschka <frank.blaschka@de.ibm.com>
*/
+#define KMSG_COMPONENT "qeth"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
#include <linux/list.h>
#include <linux/rwsem.h>
#include <asm/ebcdic.h>
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 51fde6f2e0b..6a801dc3bf8 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/etherdevice.h>
#include <linux/mii.h>
#include <linux/ip.h>
@@ -1071,11 +1072,9 @@ static int qeth_l2_recover(void *ptr)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
else {
- if (card->dev) {
- rtnl_lock();
- dev_close(card->dev);
- rtnl_unlock();
- }
+ rtnl_lock();
+ dev_close(card->dev);
+ rtnl_unlock();
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n");
}
@@ -1129,11 +1128,9 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
if (card->state == CARD_STATE_RECOVER) {
rc = __qeth_l2_set_online(card->gdev, 1);
if (rc) {
- if (card->dev) {
- rtnl_lock();
- dev_close(card->dev);
- rtnl_unlock();
- }
+ rtnl_lock();
+ dev_close(card->dev);
+ rtnl_unlock();
}
} else
rc = __qeth_l2_set_online(card->gdev, 0);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 5475834ab91..fc6ca1da8b9 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -22,6 +22,7 @@
#include <linux/ipv6.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/arp.h>
@@ -1691,39 +1692,43 @@ qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
cmd = (struct qeth_ipa_cmd *)data;
rc = cmd->hdr.return_code;
- if (rc) {
+ if (rc)
QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
- if (cmd->data.diagass.action == QETH_DIAGS_CMD_TRACE_ENABLE) {
- switch (rc) {
- case IPA_RC_HARDWARE_AUTH_ERROR:
- dev_warn(&card->gdev->dev, "The device is not "
- "authorized to run as a HiperSockets "
- "network traffic analyzer\n");
- break;
- case IPA_RC_TRACE_ALREADY_ACTIVE:
- dev_warn(&card->gdev->dev, "A HiperSockets "
- "network traffic analyzer is already "
- "active in the HiperSockets LAN\n");
- break;
- default:
- break;
- }
- }
- return 0;
- }
-
switch (cmd->data.diagass.action) {
case QETH_DIAGS_CMD_TRACE_QUERY:
break;
case QETH_DIAGS_CMD_TRACE_DISABLE:
- card->info.promisc_mode = SET_PROMISC_MODE_OFF;
- dev_info(&card->gdev->dev, "The HiperSockets network traffic "
- "analyzer is deactivated\n");
+ switch (rc) {
+ case 0:
+ case IPA_RC_INVALID_SUBCMD:
+ card->info.promisc_mode = SET_PROMISC_MODE_OFF;
+ dev_info(&card->gdev->dev, "The HiperSockets network "
+ "traffic analyzer is deactivated\n");
+ break;
+ default:
+ break;
+ }
break;
case QETH_DIAGS_CMD_TRACE_ENABLE:
- card->info.promisc_mode = SET_PROMISC_MODE_ON;
- dev_info(&card->gdev->dev, "The HiperSockets network traffic "
- "analyzer is activated\n");
+ switch (rc) {
+ case 0:
+ card->info.promisc_mode = SET_PROMISC_MODE_ON;
+ dev_info(&card->gdev->dev, "The HiperSockets network "
+ "traffic analyzer is activated\n");
+ break;
+ case IPA_RC_HARDWARE_AUTH_ERROR:
+ dev_warn(&card->gdev->dev, "The device is not "
+ "authorized to run as a HiperSockets network "
+ "traffic analyzer\n");
+ break;
+ case IPA_RC_TRACE_ALREADY_ACTIVE:
+ dev_warn(&card->gdev->dev, "A HiperSockets "
+ "network traffic analyzer is already "
+ "active in the HiperSockets LAN\n");
+ break;
+ default:
+ break;
+ }
break;
default:
QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
@@ -2215,11 +2220,9 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
if (recovery_mode)
qeth_l3_stop(card->dev);
else {
- if (card->dev) {
- rtnl_lock();
- dev_close(card->dev);
- rtnl_unlock();
- }
+ rtnl_lock();
+ dev_close(card->dev);
+ rtnl_unlock();
}
if (!card->use_hard_stop) {
rc = qeth_send_stoplan(card);
@@ -2900,10 +2903,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
int data_offset = -1;
int nr_frags;
- if ((card->info.type == QETH_CARD_TYPE_IQD) &&
- (((skb->protocol != htons(ETH_P_IPV6)) &&
- (skb->protocol != htons(ETH_P_IP))) ||
- card->options.sniffer))
+ if (((card->info.type == QETH_CARD_TYPE_IQD) && (!ipv)) ||
+ card->options.sniffer)
goto tx_drop;
if ((card->state != CARD_STATE_UP) || !card->lan_online) {
@@ -2949,14 +2950,14 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (data_offset < 0)
skb_pull(new_skb, ETH_HLEN);
} else {
- if (new_skb->protocol == htons(ETH_P_IP)) {
+ if (ipv == 4) {
if (card->dev->type == ARPHRD_IEEE802_TR)
skb_pull(new_skb, TR_HLEN);
else
skb_pull(new_skb, ETH_HLEN);
}
- if (new_skb->protocol == ETH_P_IPV6 && card->vlangrp &&
+ if (ipv == 6 && card->vlangrp &&
vlan_tx_tag_present(new_skb)) {
skb_push(new_skb, VLAN_HLEN);
skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4);
@@ -3534,11 +3535,9 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev)
if (card->state == CARD_STATE_RECOVER) {
rc = __qeth_l3_set_online(card->gdev, 1);
if (rc) {
- if (card->dev) {
- rtnl_lock();
- dev_close(card->dev);
- rtnl_unlock();
- }
+ rtnl_lock();
+ dev_close(card->dev);
+ rtnl_unlock();
}
} else
rc = __qeth_l3_set_online(card->gdev, 0);
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index 3f08b11274a..25b3e7aae44 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -8,6 +8,8 @@
* Frank Blaschka <frank.blaschka@de.ibm.com>
*/
+#include <linux/slab.h>
+
#include "qeth_l3.h"
#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 67f2485d237..70491274da1 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <net/iucv/iucv.h>
#include <asm/cpcmd.h>
#include <asm/ebcdic.h>
@@ -31,9 +32,9 @@
struct smsg_callback {
struct list_head list;
- char *prefix;
+ const char *prefix;
int len;
- void (*callback)(char *from, char *str);
+ void (*callback)(const char *from, char *str);
};
MODULE_AUTHOR
@@ -100,8 +101,8 @@ static void smsg_message_pending(struct iucv_path *path,
kfree(buffer);
}
-int smsg_register_callback(char *prefix,
- void (*callback)(char *from, char *str))
+int smsg_register_callback(const char *prefix,
+ void (*callback)(const char *from, char *str))
{
struct smsg_callback *cb;
@@ -117,8 +118,9 @@ int smsg_register_callback(char *prefix,
return 0;
}
-void smsg_unregister_callback(char *prefix,
- void (*callback)(char *from, char *str))
+void smsg_unregister_callback(const char *prefix,
+ void (*callback)(const char *from,
+ char *str))
{
struct smsg_callback *cb, *tmp;
@@ -176,7 +178,7 @@ static const struct dev_pm_ops smsg_pm_ops = {
static struct device_driver smsg_driver = {
.owner = THIS_MODULE,
- .name = "SMSGIUCV",
+ .name = SMSGIUCV_DRV_NAME,
.bus = &iucv_bus,
.pm = &smsg_pm_ops,
};
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h
index 67f5d4f8378..149a1151608 100644
--- a/drivers/s390/net/smsgiucv.h
+++ b/drivers/s390/net/smsgiucv.h
@@ -5,6 +5,10 @@
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*/
-int smsg_register_callback(char *, void (*)(char *, char *));
-void smsg_unregister_callback(char *, void (*)(char *, char *));
+#define SMSGIUCV_DRV_NAME "SMSGIUCV"
+
+int smsg_register_callback(const char *,
+ void (*)(const char *, char *));
+void smsg_unregister_callback(const char *,
+ void (*)(const char *, char *));
diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c
new file mode 100644
index 00000000000..13768879020
--- /dev/null
+++ b/drivers/s390/net/smsgiucv_app.c
@@ -0,0 +1,212 @@
+/*
+ * Deliver z/VM CP special messages (SMSG) as uevents.
+ *
+ * The driver registers for z/VM CP special messages with the
+ * "APP" prefix. Incoming messages are delivered to user space
+ * as uevents.
+ *
+ * Copyright IBM Corp. 2010
+ * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ *
+ */
+#define KMSG_COMPONENT "smsgiucv_app"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <net/iucv/iucv.h>
+#include "smsgiucv.h"
+
+/* prefix used for SMSG registration */
+#define SMSG_PREFIX "APP"
+
+/* SMSG related uevent environment variables */
+#define ENV_SENDER_STR "SMSG_SENDER="
+#define ENV_SENDER_LEN (strlen(ENV_SENDER_STR) + 8 + 1)
+#define ENV_PREFIX_STR "SMSG_ID="
+#define ENV_PREFIX_LEN (strlen(ENV_PREFIX_STR) + \
+ strlen(SMSG_PREFIX) + 1)
+#define ENV_TEXT_STR "SMSG_TEXT="
+#define ENV_TEXT_LEN(msg) (strlen(ENV_TEXT_STR) + strlen((msg)) + 1)
+
+/* z/VM user ID which is permitted to send SMSGs
+ * If the value is undefined or empty (""), special messages are
+ * accepted from any z/VM user ID. */
+static char *sender;
+module_param(sender, charp, 0400);
+MODULE_PARM_DESC(sender, "z/VM user ID from which CP SMSGs are accepted");
+
+/* SMSG device representation */
+static struct device *smsg_app_dev;
+
+/* list element for queuing received messages for delivery */
+struct smsg_app_event {
+ struct list_head list;
+ char *buf;
+ char *envp[4];
+};
+
+/* queue for outgoing uevents */
+static LIST_HEAD(smsg_event_queue);
+static DEFINE_SPINLOCK(smsg_event_queue_lock);
+
+static void smsg_app_event_free(struct smsg_app_event *ev)
+{
+ kfree(ev->buf);
+ kfree(ev);
+}
+
+static struct smsg_app_event *smsg_app_event_alloc(const char *from,
+ const char *msg)
+{
+ struct smsg_app_event *ev;
+
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+ if (!ev)
+ return NULL;
+
+ ev->buf = kzalloc(ENV_SENDER_LEN + ENV_PREFIX_LEN +
+ ENV_TEXT_LEN(msg), GFP_ATOMIC);
+ if (!ev->buf) {
+ kfree(ev);
+ return NULL;
+ }
+
+ /* setting up environment pointers into buf */
+ ev->envp[0] = ev->buf;
+ ev->envp[1] = ev->envp[0] + ENV_SENDER_LEN;
+ ev->envp[2] = ev->envp[1] + ENV_PREFIX_LEN;
+ ev->envp[3] = NULL;
+
+ /* setting up environment: sender, prefix name, and message text */
+ snprintf(ev->envp[0], ENV_SENDER_LEN, ENV_SENDER_STR "%s", from);
+ snprintf(ev->envp[1], ENV_PREFIX_LEN, ENV_PREFIX_STR "%s", SMSG_PREFIX);
+ snprintf(ev->envp[2], ENV_TEXT_LEN(msg), ENV_TEXT_STR "%s", msg);
+
+ return ev;
+}
+
+static void smsg_event_work_fn(struct work_struct *work)
+{
+ LIST_HEAD(event_queue);
+ struct smsg_app_event *p, *n;
+ struct device *dev;
+
+ dev = get_device(smsg_app_dev);
+ if (!dev)
+ return;
+
+ spin_lock_bh(&smsg_event_queue_lock);
+ list_splice_init(&smsg_event_queue, &event_queue);
+ spin_unlock_bh(&smsg_event_queue_lock);
+
+ list_for_each_entry_safe(p, n, &event_queue, list) {
+ list_del(&p->list);
+ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, p->envp);
+ smsg_app_event_free(p);
+ }
+
+ put_device(dev);
+}
+static DECLARE_WORK(smsg_event_work, smsg_event_work_fn);
+
+static void smsg_app_callback(const char *from, char *msg)
+{
+ struct smsg_app_event *se;
+
+ /* check if the originating z/VM user ID matches
+ * the configured sender. */
+ if (sender && strlen(sender) > 0 && strcmp(from, sender) != 0)
+ return;
+
+ /* get start of message text (skip prefix and leading blanks) */
+ msg += strlen(SMSG_PREFIX);
+ while (*msg && isspace(*msg))
+ msg++;
+ if (*msg == '\0')
+ return;
+
+ /* allocate event list element and its environment */
+ se = smsg_app_event_alloc(from, msg);
+ if (!se)
+ return;
+
+ /* queue event and schedule work function */
+ spin_lock(&smsg_event_queue_lock);
+ list_add_tail(&se->list, &smsg_event_queue);
+ spin_unlock(&smsg_event_queue_lock);
+
+ schedule_work(&smsg_event_work);
+ return;
+}
+
+static int __init smsgiucv_app_init(void)
+{
+ struct device_driver *smsgiucv_drv;
+ int rc;
+
+ if (!MACHINE_IS_VM)
+ return -ENODEV;
+
+ smsg_app_dev = kzalloc(sizeof(*smsg_app_dev), GFP_KERNEL);
+ if (!smsg_app_dev)
+ return -ENOMEM;
+
+ smsgiucv_drv = driver_find(SMSGIUCV_DRV_NAME, &iucv_bus);
+ if (!smsgiucv_drv) {
+ kfree(smsg_app_dev);
+ return -ENODEV;
+ }
+
+ rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT);
+ if (rc) {
+ kfree(smsg_app_dev);
+ goto fail_put_driver;
+ }
+ smsg_app_dev->bus = &iucv_bus;
+ smsg_app_dev->parent = iucv_root;
+ smsg_app_dev->release = (void (*)(struct device *)) kfree;
+ smsg_app_dev->driver = smsgiucv_drv;
+ rc = device_register(smsg_app_dev);
+ if (rc) {
+ put_device(smsg_app_dev);
+ goto fail_put_driver;
+ }
+
+ /* register with the smsgiucv device driver */
+ rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback);
+ if (rc) {
+ device_unregister(smsg_app_dev);
+ goto fail_put_driver;
+ }
+
+ rc = 0;
+fail_put_driver:
+ put_driver(smsgiucv_drv);
+ return rc;
+}
+module_init(smsgiucv_app_init);
+
+static void __exit smsgiucv_app_exit(void)
+{
+ /* unregister callback */
+ smsg_unregister_callback(SMSG_PREFIX, smsg_app_callback);
+
+ /* cancel pending work and flush any queued event work */
+ cancel_work_sync(&smsg_event_work);
+ smsg_event_work_fn(&smsg_event_work);
+
+ device_unregister(smsg_app_dev);
+}
+module_exit(smsgiucv_app_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Deliver z/VM CP SMSG as uevents");
+MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 66d6c01fcf3..1e6183a86ce 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -30,6 +30,7 @@
#include <linux/miscdevice.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "zfcp_ext.h"
#include "zfcp_fc.h"
#include "zfcp_reqlist.h"
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index 0eb6eefd2c1..25d9e0ae9c5 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -10,6 +10,7 @@
#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <asm/compat.h>
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 7a149fd85f6..075852f6968 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <asm/debug.h>
#include "zfcp_dbf.h"
#include "zfcp_ext.h"
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 5219670f0c9..2a1cbb74b99 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/types.h>
+#include <linux/slab.h>
#include <scsi/fc/fc_els.h>
#include <scsi/libfc.h>
#include "zfcp_ext.h"
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 6538742b421..b3b1d2f7939 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/blktrace_api.h>
+#include <linux/slab.h>
#include <scsi/fc/fc_els.h>
#include "zfcp_ext.h"
#include "zfcp_fc.h"
@@ -2104,7 +2105,8 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
blktrc.inb_usage = req->qdio_req.qdio_inb_usage;
blktrc.outb_usage = req->qdio_req.qdio_outb_usage;
- if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
+ if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
+ !(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
blktrc.flags |= ZFCP_BLK_LAT_VALID;
blktrc.channel_lat = lat_in->channel_lat * ticks;
blktrc.fabric_lat = lat_in->fabric_lat * ticks;
@@ -2156,9 +2158,8 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
- zfcp_fsf_req_trace(req, scpnt);
-
skip_fsfstatus:
+ zfcp_fsf_req_trace(req, scpnt);
zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
scpnt->host_scribble = NULL;
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 71b97ff77cf..dbfa312a7f5 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -9,6 +9,7 @@
#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/slab.h>
#include "zfcp_ext.h"
#include "zfcp_qdio.h"
@@ -319,8 +320,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
id->input_handler = zfcp_qdio_int_resp;
id->output_handler = zfcp_qdio_int_req;
id->int_parm = (unsigned long) qdio;
- id->flags = QDIO_INBOUND_0COPY_SBALS |
- QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal);
id->output_sbal_addr_array = (void **) (qdio->req_q.sbal);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index c3c4178888a..174b6d57d57 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -10,6 +10,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/types.h>
+#include <linux/slab.h>
#include <scsi/fc/fc_fcp.h>
#include <asm/atomic.h>
#include "zfcp_ext.h"
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index a43035d4bd7..f5f60698dc4 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -9,6 +9,7 @@
#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/slab.h>
#include "zfcp_ext.h"
#define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index 28d86f9df83..b4951eb0358 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -8,6 +8,7 @@
#include <linux/kmod.h>
#include <linux/reboot.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <linux/of_device.h>
#include <asm/oplib.h>
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 4431578d8c4..3e59189f413 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h> /* request_region */
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/of.h>
#include <linux/of_device.h>
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index aa2b60a868b..c6e2eff1940 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -26,6 +26,7 @@
#include <linux/miscdevice.h>
#include <linux/kmod.h>
#include <linux/reboot.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/of.h>
#include <linux/of_device.h>
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 41083472ff4..19f255b97c8 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -7,7 +7,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
-#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index 869a30b49ed..4942050dc5b 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -31,7 +31,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
-#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 84d3bbaa95e..e9788f55ab1 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -91,6 +91,7 @@
#include <linux/time.h>
#include <linux/mutex.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index 4d314d740de..54c5ffb1eaa 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -65,6 +65,7 @@
#include <linux/time.h>
#include <linux/mutex.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index f65a1e92340..5faf903ca8c 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -205,6 +205,7 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/mutex.h>
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 9f4a911a6d8..80dc3ac12cd 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -117,6 +117,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 1ddcf4031d4..fc0b4b81d55 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -42,6 +42,7 @@
#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <scsi/scsicam.h>
#include <asm/dma.h>
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 9191d1ea645..75f2336807c 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1,9 +1,15 @@
menu "SCSI device support"
+config SCSI_MOD
+ tristate
+ default y if SCSI=n || SCSI=y
+ default m if SCSI=m
+
config RAID_ATTRS
tristate "RAID Transport Class"
default n
depends on BLOCK
+ depends on SCSI_MOD
---help---
Provides RAID
diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
index 1cdf09a4779..8647256ad66 100644
--- a/drivers/scsi/NCR_D700.c
+++ b/drivers/scsi/NCR_D700.c
@@ -97,6 +97,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mca.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
diff --git a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c
index a8bbdc2273b..afdbb9addf1 100644
--- a/drivers/scsi/NCR_Q720.c
+++ b/drivers/scsi/NCR_Q720.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mca.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index 208d6df9ed5..dbbc601948e 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -69,7 +69,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
@@ -492,7 +491,7 @@ static void init_alloc_map(struct orc_host * host)
* init_orchid - initialise the host adapter
* @host:host adapter to initialise
*
- * Initialise the controller and if neccessary load the firmware.
+ * Initialise the controller and if necessary load the firmware.
*
* Returns -1 if the initialisation fails.
*/
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 4b38c4750f7..d8fe5b76fee 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -1,5 +1,6 @@
#include <linux/types.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index 6970ce82c4a..c35fc55f1c9 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -1,5 +1,6 @@
#include <linux/types.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/ioport.h>
#include <linux/init.h>
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index e3519fa5a3b..11ae6be8aea 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index f70d9f8e79e..04057ab72a8 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -33,7 +33,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
-#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/completion.h>
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index b6a3c5c187b..622c21c68e6 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -33,7 +33,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
-#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/completion.h>
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 22626abdb63..9201afe6560 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -4781,12 +4781,14 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
if (err) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
fwname, err);
+ asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
return err;
}
if (fw->size < 4) {
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
fw->size, fwname);
release_firmware(fw);
+ asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
return -EINVAL;
}
chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -5110,12 +5112,14 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
if (err) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
fwname, err);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
return err;
}
if (fw->size < 4) {
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
fw->size, fwname);
release_firmware(fw);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
return -EINVAL;
}
chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -5624,12 +5628,14 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
if (err) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
fwname, err);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
return err;
}
if (fw->size < 4) {
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
fw->size, fwname);
release_firmware(fw);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
return -EINVAL;
}
chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -6124,12 +6130,14 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
if (err) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
fwname, err);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
return err;
}
if (fw->size < 4) {
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
fw->size, fwname);
release_firmware(fw);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
return -EINVAL;
}
chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 1e5478abd90..8eab8587ff2 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -254,6 +254,7 @@
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <scsi/scsicam.h>
#include "scsi.h"
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 80594947c6f..2a8cf137f60 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -39,6 +39,7 @@
#include <linux/blkdev.h>
#include <linux/mca.h>
#include <linux/mca-legacy.h>
+#include <linux/slab.h>
#include <asm/dma.h>
#include <asm/system.h>
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index 538135783aa..0107a4cc333 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -50,6 +50,7 @@
#include <linux/device.h>
#include <linux/eisa.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <asm/dma.h>
#include <asm/system.h>
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 1222a7ac698..4c41332a354 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -53,6 +53,7 @@ static struct scsi_transport_template *ahd_linux_transport_template = NULL;
#include <linux/blkdev.h> /* For block_size() */
#include <linux/delay.h> /* For ssleep/msleep */
#include <linux/device.h>
+#include <linux/slab.h>
/*
* Bucket size for counting good commands in between bad ones.
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 8cb05dc8e6a..5e42dac2350 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -129,6 +129,7 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL;
#include <linux/mm.h> /* For fetching system memory size */
#include <linux/blkdev.h> /* For block_size() */
#include <linux/delay.h> /* For ssleep/msleep */
+#include <linux/slab.h>
/*
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
index eb9dc3195fd..81b736c76ff 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.c
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -25,6 +25,7 @@
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/firmware.h>
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 996f7224f90..24ac2315c5c 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -30,6 +30,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c
index ca55013b6ae..c43698b1cb6 100644
--- a/drivers/scsi/aic94xx/aic94xx_scb.c
+++ b/drivers/scsi/aic94xx/aic94xx_scb.c
@@ -24,6 +24,7 @@
*
*/
+#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include "aic94xx.h"
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index 8630a75b287..edb43fda9f3 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -26,6 +26,7 @@
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "aic94xx.h"
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c
index 8f98e33155e..d01dcc62b39 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.c
+++ b/drivers/scsi/aic94xx/aic94xx_seq.c
@@ -27,6 +27,7 @@
*/
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/firmware.h>
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
index 78eb86fc627..0add73bdf2a 100644
--- a/drivers/scsi/aic94xx/aic94xx_tmf.c
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -25,6 +25,7 @@
*/
#include <linux/spinlock.h>
+#include <linux/gfp.h>
#include "aic94xx.h"
#include "aic94xx_sas.h"
#include "aic94xx_hwi.h"
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 47d5d19f8c9..ffbe2192da3 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -58,6 +58,7 @@
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/aer.h>
+#include <linux/slab.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/system.h>
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 4240b05aef6..158ebc3644d 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -651,6 +651,7 @@ static inline void NCR5380_print_phase(struct Scsi_Host *instance)
* interrupt or bottom half.
*/
+#include <linux/gfp.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index b137e561f5b..ab5bdda6903 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -29,6 +29,7 @@
#include <linux/pci.h>
#include <linux/blkdev.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 67098578fba..cda6642c736 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -32,18 +32,11 @@ void be_mcc_notify(struct beiscsi_hba *phba)
unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
{
unsigned int tag = 0;
- unsigned int num = 0;
-mcc_tag_rdy:
if (phba->ctrl.mcc_tag_available) {
tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
phba->ctrl.mcc_numtag[tag] = 0;
- } else {
- udelay(100);
- num++;
- if (num < mcc_timeout)
- goto mcc_tag_rdy;
}
if (tag) {
phba->ctrl.mcc_tag_available--;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 29a3aaf35f9..c3928cb8b04 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -482,7 +482,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
if (!tag) {
SE_DEBUG(DBG_LVL_1,
- "mgmt_invalidate_connection Failed for cid=%d \n",
+ "mgmt_open_connection Failed for cid=%d \n",
beiscsi_ep->ep_cid);
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -701,7 +701,7 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
if (!tag) {
SE_DEBUG(DBG_LVL_1,
"mgmt_invalidate_connection Failed for cid=%d \n",
- beiscsi_ep->ep_cid);
+ beiscsi_ep->ep_cid);
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 7c22616ab14..dd5b105f8f4 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -19,6 +19,7 @@
*/
#include <linux/reboot.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/pci.h>
@@ -58,6 +59,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
return 0;
}
+static int beiscsi_eh_abort(struct scsi_cmnd *sc)
+{
+ struct iscsi_cls_session *cls_session;
+ struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
+ struct beiscsi_io_task *aborted_io_task;
+ struct iscsi_conn *conn;
+ struct beiscsi_conn *beiscsi_conn;
+ struct beiscsi_hba *phba;
+ struct iscsi_session *session;
+ struct invalidate_command_table *inv_tbl;
+ unsigned int cid, tag, num_invalidate;
+
+ cls_session = starget_to_session(scsi_target(sc->device));
+ session = cls_session->dd_data;
+
+ spin_lock_bh(&session->lock);
+ if (!aborted_task || !aborted_task->sc) {
+ /* we raced */
+ spin_unlock_bh(&session->lock);
+ return SUCCESS;
+ }
+
+ aborted_io_task = aborted_task->dd_data;
+ if (!aborted_io_task->scsi_cmnd) {
+ /* raced or invalid command */
+ spin_unlock_bh(&session->lock);
+ return SUCCESS;
+ }
+ spin_unlock_bh(&session->lock);
+ conn = aborted_task->conn;
+ beiscsi_conn = conn->dd_data;
+ phba = beiscsi_conn->phba;
+
+ /* invalidate iocb */
+ cid = beiscsi_conn->beiscsi_conn_cid;
+ inv_tbl = phba->inv_tbl;
+ memset(inv_tbl, 0x0, sizeof(*inv_tbl));
+ inv_tbl->cid = cid;
+ inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
+ num_invalidate = 1;
+ tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+ if (!tag) {
+ shost_printk(KERN_WARNING, phba->shost,
+ "mgmt_invalidate_icds could not be"
+ " submitted\n");
+ return FAILED;
+ } else {
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+ free_mcc_tag(&phba->ctrl, tag);
+ }
+
+ return iscsi_eh_abort(sc);
+}
+
+static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
+{
+ struct iscsi_task *abrt_task;
+ struct beiscsi_io_task *abrt_io_task;
+ struct iscsi_conn *conn;
+ struct beiscsi_conn *beiscsi_conn;
+ struct beiscsi_hba *phba;
+ struct iscsi_session *session;
+ struct iscsi_cls_session *cls_session;
+ struct invalidate_command_table *inv_tbl;
+ unsigned int cid, tag, i, num_invalidate;
+ int rc = FAILED;
+
+ /* invalidate iocbs */
+ cls_session = starget_to_session(scsi_target(sc->device));
+ session = cls_session->dd_data;
+ spin_lock_bh(&session->lock);
+ if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
+ goto unlock;
+
+ conn = session->leadconn;
+ beiscsi_conn = conn->dd_data;
+ phba = beiscsi_conn->phba;
+ cid = beiscsi_conn->beiscsi_conn_cid;
+ inv_tbl = phba->inv_tbl;
+ memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
+ num_invalidate = 0;
+ for (i = 0; i < conn->session->cmds_max; i++) {
+ abrt_task = conn->session->cmds[i];
+ abrt_io_task = abrt_task->dd_data;
+ if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
+ continue;
+
+ if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
+ continue;
+
+ inv_tbl->cid = cid;
+ inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
+ num_invalidate++;
+ inv_tbl++;
+ }
+ spin_unlock_bh(&session->lock);
+ inv_tbl = phba->inv_tbl;
+
+ tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+ if (!tag) {
+ shost_printk(KERN_WARNING, phba->shost,
+ "mgmt_invalidate_icds could not be"
+ " submitted\n");
+ return FAILED;
+ } else {
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+ free_mcc_tag(&phba->ctrl, tag);
+ }
+
+ return iscsi_eh_device_reset(sc);
+unlock:
+ spin_unlock_bh(&session->lock);
+ return rc;
+}
+
/*------------------- PCI Driver operations and data ----------------- */
static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -74,12 +192,12 @@ static struct scsi_host_template beiscsi_sht = {
.name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
.proc_name = DRV_NAME,
.queuecommand = iscsi_queuecommand,
- .eh_abort_handler = iscsi_eh_abort,
.change_queue_depth = iscsi_change_queue_depth,
.slave_configure = beiscsi_slave_configure,
.target_alloc = iscsi_target_alloc,
- .eh_device_reset_handler = iscsi_eh_device_reset,
- .eh_target_reset_handler = iscsi_eh_target_reset,
+ .eh_abort_handler = beiscsi_eh_abort,
+ .eh_device_reset_handler = beiscsi_eh_device_reset,
+ .eh_target_reset_handler = iscsi_eh_session_reset,
.sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
.can_queue = BE2_IO_DEPTH,
.this_id = -1,
@@ -242,7 +360,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
+ BE2_TMFS
+ BE2_NOPOUT_REQ));
phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
- phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;;
+ phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2;
phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
phba->params.num_sge_per_io = BE2_SGE;
phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
@@ -946,14 +1064,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
case HWH_TYPE_IO:
case HWH_TYPE_IO_RD:
if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
- ISCSI_OP_NOOP_OUT) {
+ ISCSI_OP_NOOP_OUT)
be_complete_nopin_resp(beiscsi_conn, task, psol);
- } else
+ else
be_complete_io(beiscsi_conn, task, psol);
break;
case HWH_TYPE_LOGOUT:
- be_complete_logout(beiscsi_conn, task, psol);
+ if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
+ be_complete_logout(beiscsi_conn, task, psol);
+ else
+ be_complete_tmf(beiscsi_conn, task, psol);
+
break;
case HWH_TYPE_LOGIN:
@@ -962,10 +1084,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
"- Solicited path \n");
break;
- case HWH_TYPE_TMF:
- be_complete_tmf(beiscsi_conn, task, psol);
- break;
-
case HWH_TYPE_NOP:
be_complete_nopin_resp(beiscsi_conn, task, psol);
break;
@@ -2052,7 +2170,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
((sizeof(struct iscsi_wrb) *
phba->params.wrbs_per_cxn));
- for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) {
+ for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
pwrb_context = &phwi_ctrlr->wrb_context[index];
if (num_cxn_wrb) {
for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
@@ -3073,14 +3191,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
iowrite32(reg, addr);
- for (i = 0; i <= phba->num_cpus; i++) {
- eq = &phwi_context->be_eq[i].q;
+ if (!phba->msix_enabled) {
+ eq = &phwi_context->be_eq[0].q;
SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+ } else {
+ for (i = 0; i <= phba->num_cpus; i++) {
+ eq = &phwi_context->be_eq[i].q;
+ SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
+ hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+ }
}
- } else
- shost_printk(KERN_WARNING, phba->shost,
- "In hwi_enable_intr, Not Enabled \n");
+ }
return true;
}
@@ -3476,19 +3598,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
static int beiscsi_mtask(struct iscsi_task *task)
{
- struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data;
+ struct beiscsi_io_task *io_task = task->dd_data;
struct iscsi_conn *conn = task->conn;
struct beiscsi_conn *beiscsi_conn = conn->dd_data;
struct beiscsi_hba *phba = beiscsi_conn->phba;
- struct iscsi_session *session;
struct iscsi_wrb *pwrb = NULL;
- struct hwi_controller *phwi_ctrlr;
- struct hwi_wrb_context *pwrb_context;
- struct wrb_handle *pwrb_handle;
unsigned int doorbell = 0;
- unsigned int i, cid;
- struct iscsi_task *aborted_task;
- unsigned int tag;
+ unsigned int cid;
cid = beiscsi_conn->beiscsi_conn_cid;
pwrb = io_task->pwrb_handle->pwrb;
@@ -3499,6 +3615,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
io_task->pwrb_handle->wrb_index);
AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
io_task->psgl_handle->sgl_index);
+
switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
case ISCSI_OP_LOGIN:
AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
@@ -3523,33 +3640,6 @@ static int beiscsi_mtask(struct iscsi_task *task)
hwi_write_buffer(pwrb, task);
break;
case ISCSI_OP_SCSI_TMFUNC:
- session = conn->session;
- i = ((struct iscsi_tm *)task->hdr)->rtt;
- phwi_ctrlr = phba->phwi_ctrlr;
- pwrb_context = &phwi_ctrlr->wrb_context[cid -
- phba->fw_config.iscsi_cid_start];
- pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
- >> 16];
- aborted_task = pwrb_handle->pio_handle;
- if (!aborted_task)
- return 0;
-
- aborted_io_task = aborted_task->dd_data;
- if (!aborted_io_task->scsi_cmnd)
- return 0;
-
- tag = mgmt_invalidate_icds(phba,
- aborted_io_task->psgl_handle->sgl_index,
- cid);
- if (!tag) {
- shost_printk(KERN_WARNING, phba->shost,
- "mgmt_invalidate_icds could not be"
- " submitted\n");
- } else {
- wait_event_interruptible(phba->ctrl.mcc_wait[tag],
- phba->ctrl.mcc_numtag[tag]);
- free_mcc_tag(&phba->ctrl, tag);
- }
AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
INI_TMF_CMD);
AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
@@ -3558,7 +3648,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
case ISCSI_OP_LOGOUT:
AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
- HWH_TYPE_LOGOUT);
+ HWH_TYPE_LOGOUT);
hwi_write_buffer(pwrb, task);
break;
@@ -3584,17 +3674,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
static int beiscsi_task_xmit(struct iscsi_task *task)
{
- struct iscsi_conn *conn = task->conn;
struct beiscsi_io_task *io_task = task->dd_data;
struct scsi_cmnd *sc = task->sc;
- struct beiscsi_conn *beiscsi_conn = conn->dd_data;
struct scatterlist *sg;
int num_sg;
unsigned int writedir = 0, xferlen = 0;
- SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t"
- "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid,
- task, conn, beiscsi_conn);
if (!sc)
return beiscsi_mtask(task);
@@ -3699,7 +3784,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
" Failed in beiscsi_hba_alloc \n");
goto disable_pci;
}
- SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
switch (pcidev->device) {
case BE_DEVICE_ID1:
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index c53a80ab796..87ec21280a3 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -257,6 +257,11 @@ struct hba_parameters {
unsigned int num_sge;
};
+struct invalidate_command_table {
+ unsigned short icd;
+ unsigned short cid;
+} __packed;
+
struct beiscsi_hba {
struct hba_parameters params;
struct hwi_controller *phwi_ctrlr;
@@ -329,6 +334,8 @@ struct beiscsi_hba {
struct work_struct work_cqs; /* The work being queued */
struct be_ctrl_info ctrl;
unsigned int generation;
+ struct invalidate_command_table inv_tbl[128];
+
};
struct beiscsi_session {
@@ -491,8 +498,6 @@ struct hwi_async_entry {
struct list_head data_busy_list;
};
-#define BE_MIN_ASYNC_ENTRIES 128
-
struct hwi_async_pdu_context {
struct {
struct be_bus_address pa_base;
@@ -533,7 +538,7 @@ struct hwi_async_pdu_context {
* This is a varying size list! Do not add anything
* after this entry!!
*/
- struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES];
+ struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2];
};
#define PDUCQE_CODE_MASK 0x0000003F
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 317bcd042ce..e641922f20b 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
}
unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
- unsigned int icd, unsigned int cid)
+ struct invalidate_command_table *inv_tbl,
+ unsigned int num_invalidate, unsigned int cid)
{
struct be_dma_mem nonemb_cmd;
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
struct be_sge *sge;
struct invalidate_commands_params_in *req;
- unsigned int tag = 0;
+ unsigned int i, tag = 0;
spin_lock(&ctrl->mbox_lock);
tag = alloc_mcc_tag(phba);
@@ -168,6 +169,7 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
SE_DEBUG(DBG_LVL_1,
"Failed to allocate memory for"
"mgmt_invalidate_icds \n");
+ spin_unlock(&ctrl->mbox_lock);
return -1;
}
nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
@@ -183,9 +185,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
sizeof(*req));
req->ref_handle = 0;
req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
- req->icd_count = 0;
- req->table[req->icd_count].icd = icd;
- req->table[req->icd_count].cid = cid;
+ for (i = 0; i < num_invalidate; i++) {
+ req->table[i].icd = inv_tbl->icd;
+ req->table[i].cid = inv_tbl->cid;
+ req->icd_count++;
+ inv_tbl++;
+ }
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(nonemb_cmd.size);
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index ecead6a5aa5..3d316b82feb 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
unsigned short cid,
unsigned int upload_flag);
unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
- unsigned int icd, unsigned int cid);
+ struct invalidate_command_table *inv_tbl,
+ unsigned int num_invalidate, unsigned int cid);
struct iscsi_invalidate_connection_params_in {
struct be_cmd_req_hdr hdr;
@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params {
struct iscsi_invalidate_connection_params_out response;
} __packed;
-struct invalidate_command_table {
- unsigned short icd;
- unsigned short cid;
-} __packed;
-
struct invalidate_commands_params_in {
struct be_cmd_req_hdr hdr;
unsigned int ref_handle;
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
index 1d6009490d1..17e06cae71b 100644
--- a/drivers/scsi/bfa/Makefile
+++ b/drivers/scsi/bfa/Makefile
@@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
-bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o
-bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
+bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
+bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
bfa-y += bfa_csdebug.o bfa_sm.o plog.o
-bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
+bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
-ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna
+ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 44e2d1155c5..0c08e185a76 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -385,6 +385,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
}
/**
+ * Clear the saved firmware trace information of an IOC.
+ */
+void
+bfa_debug_fwsave_clear(struct bfa_s *bfa)
+{
+ bfa_ioc_debug_fwsave_clear(&bfa->ioc);
+}
+
+/**
* Fetch firmware trace data.
*
* @param[in] bfa BFA instance
@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
{
return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
}
+
+/**
+ * Reset hw semaphore & usage cnt regs and initialize.
+ */
+void
+bfa_chip_reset(struct bfa_s *bfa)
+{
+ bfa_ioc_ownership_reset(&bfa->ioc);
+ bfa_ioc_pll_init(&bfa->ioc);
+}
#endif
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c
index aef648b55df..c589488db0c 100644
--- a/drivers/scsi/bfa/bfa_fcport.c
+++ b/drivers/scsi/bfa/bfa_fcport.c
@@ -23,40 +23,33 @@
#include <cs/bfa_plog.h>
#include <aen/bfa_aen_port.h>
-BFA_TRC_FILE(HAL, PPORT);
-BFA_MODULE(pport);
-
-#define bfa_pport_callback(__pport, __event) do { \
- if ((__pport)->bfa->fcs) { \
- (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \
- } else { \
- (__pport)->hcb_event = (__event); \
- bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \
- __bfa_cb_port_event, (__pport)); \
- } \
-} while (0)
+BFA_TRC_FILE(HAL, FCPORT);
+BFA_MODULE(fcport);
/*
* The port is considered disabled if corresponding physical port or IOC are
* disabled explicitly
*/
#define BFA_PORT_IS_DISABLED(bfa) \
- ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \
+ ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
(bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
/*
* forward declarations
*/
-static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port);
-static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port);
-static void bfa_pport_update_linkinfo(struct bfa_pport_s *pport);
-static void bfa_pport_reset_linkinfo(struct bfa_pport_s *pport);
-static void bfa_pport_set_wwns(struct bfa_pport_s *port);
-static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete);
-static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete);
-static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
-static void bfa_port_stats_timeout(void *cbarg);
-static void bfa_port_stats_clr_timeout(void *cbarg);
+static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
+static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
+static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
+static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
+static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
+static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
+static void bfa_fcport_callback(struct bfa_fcport_s *fcport,
+ enum bfa_pport_linkstate event);
+static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
+ enum bfa_pport_linkstate event);
+static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
+static void bfa_fcport_stats_get_timeout(void *cbarg);
+static void bfa_fcport_stats_clr_timeout(void *cbarg);
/**
* bfa_pport_private
@@ -65,111 +58,114 @@ static void bfa_port_stats_clr_timeout(void *cbarg);
/**
* BFA port state machine events
*/
-enum bfa_pport_sm_event {
- BFA_PPORT_SM_START = 1, /* start port state machine */
- BFA_PPORT_SM_STOP = 2, /* stop port state machine */
- BFA_PPORT_SM_ENABLE = 3, /* enable port */
- BFA_PPORT_SM_DISABLE = 4, /* disable port state machine */
- BFA_PPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */
- BFA_PPORT_SM_LINKUP = 6, /* firmware linkup event */
- BFA_PPORT_SM_LINKDOWN = 7, /* firmware linkup down */
- BFA_PPORT_SM_QRESUME = 8, /* CQ space available */
- BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */
+enum bfa_fcport_sm_event {
+ BFA_FCPORT_SM_START = 1, /* start port state machine */
+ BFA_FCPORT_SM_STOP = 2, /* stop port state machine */
+ BFA_FCPORT_SM_ENABLE = 3, /* enable port */
+ BFA_FCPORT_SM_DISABLE = 4, /* disable port state machine */
+ BFA_FCPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */
+ BFA_FCPORT_SM_LINKUP = 6, /* firmware linkup event */
+ BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */
+ BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */
+ BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */
};
-static void bfa_pport_sm_uninit(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_enabling(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_linkdown(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_linkup(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_disabling(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_disabled(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_stopped(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
-static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event);
+/**
+ * BFA port link notification state machine events
+ */
+
+enum bfa_fcport_ln_sm_event {
+ BFA_FCPORT_LN_SM_LINKUP = 1, /* linkup event */
+ BFA_FCPORT_LN_SM_LINKDOWN = 2, /* linkdown event */
+ BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */
+};
+
+static void bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+
+static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event);
+static void bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event);
+static void bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event);
+static void bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event);
+static void bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event);
+static void bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event);
+static void bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event);
static struct bfa_sm_table_s hal_pport_sm_table[] = {
- {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
- {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
- {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING},
- {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
- {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP},
- {BFA_SM(bfa_pport_sm_disabling_qwait),
- BFA_PPORT_ST_DISABLING_QWAIT},
- {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING},
- {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED},
- {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED},
- {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
- {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
+ {BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT},
+ {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
+ {BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING},
+ {BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
+ {BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP},
+ {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT},
+ {BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING},
+ {BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED},
+ {BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED},
+ {BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
+ {BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
};
static void
-bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event)
+bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
{
union bfa_aen_data_u aen_data;
- struct bfa_log_mod_s *logmod = pport->bfa->logm;
- wwn_t pwwn = pport->pwwn;
+ struct bfa_log_mod_s *logmod = fcport->bfa->logm;
+ wwn_t pwwn = fcport->pwwn;
char pwwn_ptr[BFA_STRING_32];
- struct bfa_ioc_attr_s ioc_attr;
+ memset(&aen_data, 0, sizeof(aen_data));
wwn2str(pwwn_ptr, pwwn);
- switch (event) {
- case BFA_PORT_AEN_ONLINE:
- bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr);
- break;
- case BFA_PORT_AEN_OFFLINE:
- bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr);
- break;
- case BFA_PORT_AEN_ENABLE:
- bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr);
- break;
- case BFA_PORT_AEN_DISABLE:
- bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr);
- break;
- case BFA_PORT_AEN_DISCONNECT:
- bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr);
- break;
- case BFA_PORT_AEN_QOS_NEG:
- bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr);
- break;
- default:
- break;
- }
+ bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr);
- bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr);
- aen_data.port.ioc_type = ioc_attr.ioc_type;
+ aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
aen_data.port.pwwn = pwwn;
}
static void
-bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_START:
+ case BFA_FCPORT_SM_START:
/**
* Start event after IOC is configured and BFA is started.
*/
- if (bfa_pport_send_enable(pport))
- bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+ if (bfa_fcport_send_enable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
else
- bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
break;
- case BFA_PPORT_SM_ENABLE:
+ case BFA_FCPORT_SM_ENABLE:
/**
* Port is persistently configured to be in enabled state. Do
* not change state. Port enabling is done when START event is
@@ -177,389 +173,412 @@ bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
*/
break;
- case BFA_PPORT_SM_DISABLE:
+ case BFA_FCPORT_SM_DISABLE:
/**
* If a port is persistently configured to be disabled, the
* first event will a port disable request.
*/
- bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
break;
- case BFA_PPORT_SM_HWFAIL:
- bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
break;
default:
- bfa_sm_fault(pport->bfa, event);
+ bfa_sm_fault(fcport->bfa, event);
}
}
static void
-bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event)
+bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_QRESUME:
- bfa_sm_set_state(pport, bfa_pport_sm_enabling);
- bfa_pport_send_enable(pport);
+ case BFA_FCPORT_SM_QRESUME:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
+ bfa_fcport_send_enable(fcport);
break;
- case BFA_PPORT_SM_STOP:
- bfa_reqq_wcancel(&pport->reqq_wait);
- bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+ case BFA_FCPORT_SM_STOP:
+ bfa_reqq_wcancel(&fcport->reqq_wait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
break;
- case BFA_PPORT_SM_ENABLE:
+ case BFA_FCPORT_SM_ENABLE:
/**
* Already enable is in progress.
*/
break;
- case BFA_PPORT_SM_DISABLE:
+ case BFA_FCPORT_SM_DISABLE:
/**
* Just send disable request to firmware when room becomes
* available in request queue.
*/
- bfa_sm_set_state(pport, bfa_pport_sm_disabled);
- bfa_reqq_wcancel(&pport->reqq_wait);
- bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
+ bfa_reqq_wcancel(&fcport->reqq_wait);
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
- bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
break;
- case BFA_PPORT_SM_LINKUP:
- case BFA_PPORT_SM_LINKDOWN:
+ case BFA_FCPORT_SM_LINKUP:
+ case BFA_FCPORT_SM_LINKDOWN:
/**
* Possible to get link events when doing back-to-back
* enable/disables.
*/
break;
- case BFA_PPORT_SM_HWFAIL:
- bfa_reqq_wcancel(&pport->reqq_wait);
- bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_reqq_wcancel(&fcport->reqq_wait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
break;
default:
- bfa_sm_fault(pport->bfa, event);
+ bfa_sm_fault(fcport->bfa, event);
}
}
static void
-bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_FWRSP:
- case BFA_PPORT_SM_LINKDOWN:
- bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
+ case BFA_FCPORT_SM_FWRSP:
+ case BFA_FCPORT_SM_LINKDOWN:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
break;
- case BFA_PPORT_SM_LINKUP:
- bfa_pport_update_linkinfo(pport);
- bfa_sm_set_state(pport, bfa_pport_sm_linkup);
+ case BFA_FCPORT_SM_LINKUP:
+ bfa_fcport_update_linkinfo(fcport);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
- bfa_assert(pport->event_cbfn);
- bfa_pport_callback(pport, BFA_PPORT_LINKUP);
+ bfa_assert(fcport->event_cbfn);
+ bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
break;
- case BFA_PPORT_SM_ENABLE:
+ case BFA_FCPORT_SM_ENABLE:
/**
* Already being enabled.
*/
break;
- case BFA_PPORT_SM_DISABLE:
- if (bfa_pport_send_disable(pport))
- bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+ case BFA_FCPORT_SM_DISABLE:
+ if (bfa_fcport_send_disable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
else
- bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
- bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
- bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
break;
- case BFA_PPORT_SM_STOP:
- bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+ case BFA_FCPORT_SM_STOP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
break;
- case BFA_PPORT_SM_HWFAIL:
- bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
break;
default:
- bfa_sm_fault(pport->bfa, event);
+ bfa_sm_fault(fcport->bfa, event);
}
}
static void
-bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_LINKUP:
- bfa_pport_update_linkinfo(pport);
- bfa_sm_set_state(pport, bfa_pport_sm_linkup);
- bfa_assert(pport->event_cbfn);
- bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+ case BFA_FCPORT_SM_LINKUP:
+ bfa_fcport_update_linkinfo(fcport);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
+ bfa_assert(fcport->event_cbfn);
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
- bfa_pport_callback(pport, BFA_PPORT_LINKUP);
- bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE);
+
+ if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
+
+ bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled);
+ bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed);
+
+ if (pevent->link_state.fcf.fipfailed)
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+ BFA_PL_EID_FIP_FCF_DISC, 0,
+ "FIP FCF Discovery Failed");
+ else
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+ BFA_PL_EID_FIP_FCF_DISC, 0,
+ "FIP FCF Discovered");
+ }
+
+ bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
/**
* If QoS is enabled and it is not online,
* Send a separate event.
*/
- if ((pport->cfg.qos_enabled)
- && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE))
- bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG);
+ if ((fcport->cfg.qos_enabled)
+ && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE))
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
break;
- case BFA_PPORT_SM_LINKDOWN:
+ case BFA_FCPORT_SM_LINKDOWN:
/**
* Possible to get link down event.
*/
break;
- case BFA_PPORT_SM_ENABLE:
+ case BFA_FCPORT_SM_ENABLE:
/**
* Already enabled.
*/
break;
- case BFA_PPORT_SM_DISABLE:
- if (bfa_pport_send_disable(pport))
- bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+ case BFA_FCPORT_SM_DISABLE:
+ if (bfa_fcport_send_disable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
else
- bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
- bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
- bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
break;
- case BFA_PPORT_SM_STOP:
- bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+ case BFA_FCPORT_SM_STOP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
break;
- case BFA_PPORT_SM_HWFAIL:
- bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
break;
default:
- bfa_sm_fault(pport->bfa, event);
+ bfa_sm_fault(fcport->bfa, event);
}
}
static void
-bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_ENABLE:
+ case BFA_FCPORT_SM_ENABLE:
/**
* Already enabled.
*/
break;
- case BFA_PPORT_SM_DISABLE:
- if (bfa_pport_send_disable(pport))
- bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+ case BFA_FCPORT_SM_DISABLE:
+ if (bfa_fcport_send_disable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
else
- bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
- bfa_pport_reset_linkinfo(pport);
- bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
- bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
- bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
- bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
break;
- case BFA_PPORT_SM_LINKDOWN:
- bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
- bfa_pport_reset_linkinfo(pport);
- bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
- bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+ case BFA_FCPORT_SM_LINKDOWN:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
- if (BFA_PORT_IS_DISABLED(pport->bfa))
- bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+ if (BFA_PORT_IS_DISABLED(fcport->bfa))
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
else
- bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
break;
- case BFA_PPORT_SM_STOP:
- bfa_sm_set_state(pport, bfa_pport_sm_stopped);
- bfa_pport_reset_linkinfo(pport);
- if (BFA_PORT_IS_DISABLED(pport->bfa))
- bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+ case BFA_FCPORT_SM_STOP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+ bfa_fcport_reset_linkinfo(fcport);
+ if (BFA_PORT_IS_DISABLED(fcport->bfa))
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
else
- bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
break;
- case BFA_PPORT_SM_HWFAIL:
- bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
- bfa_pport_reset_linkinfo(pport);
- bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
- if (BFA_PORT_IS_DISABLED(pport->bfa))
- bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+ if (BFA_PORT_IS_DISABLED(fcport->bfa))
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
else
- bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
break;
default:
- bfa_sm_fault(pport->bfa, event);
+ bfa_sm_fault(fcport->bfa, event);
}
}
static void
-bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
- enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_QRESUME:
- bfa_sm_set_state(pport, bfa_pport_sm_disabling);
- bfa_pport_send_disable(pport);
+ case BFA_FCPORT_SM_QRESUME:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
+ bfa_fcport_send_disable(fcport);
break;
- case BFA_PPORT_SM_STOP:
- bfa_sm_set_state(pport, bfa_pport_sm_stopped);
- bfa_reqq_wcancel(&pport->reqq_wait);
+ case BFA_FCPORT_SM_STOP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+ bfa_reqq_wcancel(&fcport->reqq_wait);
break;
- case BFA_PPORT_SM_DISABLE:
+ case BFA_FCPORT_SM_DISABLE:
/**
* Already being disabled.
*/
break;
- case BFA_PPORT_SM_LINKUP:
- case BFA_PPORT_SM_LINKDOWN:
+ case BFA_FCPORT_SM_LINKUP:
+ case BFA_FCPORT_SM_LINKDOWN:
/**
* Possible to get link events when doing back-to-back
* enable/disables.
*/
break;
- case BFA_PPORT_SM_HWFAIL:
- bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
- bfa_reqq_wcancel(&pport->reqq_wait);
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
+ bfa_reqq_wcancel(&fcport->reqq_wait);
break;
default:
- bfa_sm_fault(pport->bfa, event);
+ bfa_sm_fault(fcport->bfa, event);
}
}
static void
-bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_FWRSP:
- bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+ case BFA_FCPORT_SM_FWRSP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
break;
- case BFA_PPORT_SM_DISABLE:
+ case BFA_FCPORT_SM_DISABLE:
/**
* Already being disabled.
*/
break;
- case BFA_PPORT_SM_ENABLE:
- if (bfa_pport_send_enable(pport))
- bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+ case BFA_FCPORT_SM_ENABLE:
+ if (bfa_fcport_send_enable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
else
- bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
- bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
- bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
break;
- case BFA_PPORT_SM_STOP:
- bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+ case BFA_FCPORT_SM_STOP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
break;
- case BFA_PPORT_SM_LINKUP:
- case BFA_PPORT_SM_LINKDOWN:
+ case BFA_FCPORT_SM_LINKUP:
+ case BFA_FCPORT_SM_LINKDOWN:
/**
* Possible to get link events when doing back-to-back
* enable/disables.
*/
break;
- case BFA_PPORT_SM_HWFAIL:
- bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
break;
default:
- bfa_sm_fault(pport->bfa, event);
+ bfa_sm_fault(fcport->bfa, event);
}
}
static void
-bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_START:
+ case BFA_FCPORT_SM_START:
/**
* Ignore start event for a port that is disabled.
*/
break;
- case BFA_PPORT_SM_STOP:
- bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+ case BFA_FCPORT_SM_STOP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
break;
- case BFA_PPORT_SM_ENABLE:
- if (bfa_pport_send_enable(pport))
- bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+ case BFA_FCPORT_SM_ENABLE:
+ if (bfa_fcport_send_enable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
else
- bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
- bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
- bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
break;
- case BFA_PPORT_SM_DISABLE:
+ case BFA_FCPORT_SM_DISABLE:
/**
* Already disabled.
*/
break;
- case BFA_PPORT_SM_HWFAIL:
- bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
break;
default:
- bfa_sm_fault(pport->bfa, event);
+ bfa_sm_fault(fcport->bfa, event);
}
}
static void
-bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_START:
- if (bfa_pport_send_enable(pport))
- bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+ case BFA_FCPORT_SM_START:
+ if (bfa_fcport_send_enable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
else
- bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
break;
default:
@@ -574,16 +593,17 @@ bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
* Port is enabled. IOC is down/failed.
*/
static void
-bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_START:
- if (bfa_pport_send_enable(pport))
- bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+ case BFA_FCPORT_SM_START:
+ if (bfa_fcport_send_enable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
else
- bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
break;
default:
@@ -598,17 +618,18 @@ bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
* Port is disabled. IOC is down/failed.
*/
static void
-bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
{
- bfa_trc(pport->bfa, event);
+ bfa_trc(fcport->bfa, event);
switch (event) {
- case BFA_PPORT_SM_START:
- bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+ case BFA_FCPORT_SM_START:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
break;
- case BFA_PPORT_SM_ENABLE:
- bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+ case BFA_FCPORT_SM_ENABLE:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
break;
default:
@@ -619,41 +640,226 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
}
}
+/**
+ * Link state is down
+ */
+static void
+bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event)
+{
+ bfa_trc(ln->fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_LN_SM_LINKUP:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
+ bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
+ break;
+
+ default:
+ bfa_sm_fault(ln->fcport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for down notification
+ */
+static void
+bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event)
+{
+ bfa_trc(ln->fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_LN_SM_LINKUP:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
+ break;
+
+ case BFA_FCPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
+ break;
+
+ default:
+ bfa_sm_fault(ln->fcport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for down notification and there is a pending up
+ */
+static void
+bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event)
+{
+ bfa_trc(ln->fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_LN_SM_LINKDOWN:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+ break;
+
+ case BFA_FCPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
+ bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
+ break;
+
+ default:
+ bfa_sm_fault(ln->fcport->bfa, event);
+ }
+}
+
+/**
+ * Link state is up
+ */
+static void
+bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event)
+{
+ bfa_trc(ln->fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_LN_SM_LINKDOWN:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+ bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+ break;
+ default:
+ bfa_sm_fault(ln->fcport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for up notification
+ */
+static void
+bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event)
+{
+ bfa_trc(ln->fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_LN_SM_LINKDOWN:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
+ break;
+
+ case BFA_FCPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
+ break;
+
+ default:
+ bfa_sm_fault(ln->fcport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for up notification and there is a pending down
+ */
+static void
+bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event)
+{
+ bfa_trc(ln->fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_LN_SM_LINKUP:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
+ break;
+
+ case BFA_FCPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+ bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+ break;
+
+ default:
+ bfa_sm_fault(ln->fcport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for up notification and there are pending down and up
+ */
+static void
+bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
+ enum bfa_fcport_ln_sm_event event)
+{
+ bfa_trc(ln->fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_LN_SM_LINKDOWN:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
+ break;
+
+ case BFA_FCPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
+ bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+ break;
+
+ default:
+ bfa_sm_fault(ln->fcport->bfa, event);
+ }
+}
/**
* bfa_pport_private
*/
static void
-__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
+__bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
{
- struct bfa_pport_s *pport = cbarg;
+ struct bfa_fcport_ln_s *ln = cbarg;
if (complete)
- pport->event_cbfn(pport->event_cbarg, pport->hcb_event);
+ ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
+ else
+ bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
}
-#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
+static void
+bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event)
+{
+ if (fcport->bfa->fcs) {
+ fcport->event_cbfn(fcport->event_cbarg, event);
+ return;
+ }
+
+ switch (event) {
+ case BFA_PPORT_LINKUP:
+ bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
+ break;
+ case BFA_PPORT_LINKDOWN:
+ bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
+ break;
+ default:
+ bfa_assert(0);
+ }
+}
+
+static void
+bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event)
+{
+ ln->ln_event = event;
+ bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln);
+}
+
+#define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
BFA_CACHELINE_SZ))
static void
-bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
+bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
u32 *dm_len)
{
- *dm_len += PPORT_STATS_DMA_SZ;
+ *dm_len += FCPORT_STATS_DMA_SZ;
}
static void
-bfa_pport_qresume(void *cbarg)
+bfa_fcport_qresume(void *cbarg)
{
- struct bfa_pport_s *port = cbarg;
+ struct bfa_fcport_s *fcport = cbarg;
- bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME);
+ bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
}
static void
-bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
+bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
{
u8 *dm_kva;
u64 dm_pa;
@@ -661,12 +867,12 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
dm_kva = bfa_meminfo_dma_virt(meminfo);
dm_pa = bfa_meminfo_dma_phys(meminfo);
- pport->stats_kva = dm_kva;
- pport->stats_pa = dm_pa;
- pport->stats = (union bfa_pport_stats_u *)dm_kva;
+ fcport->stats_kva = dm_kva;
+ fcport->stats_pa = dm_pa;
+ fcport->stats = (union bfa_fcport_stats_u *)dm_kva;
- dm_kva += PPORT_STATS_DMA_SZ;
- dm_pa += PPORT_STATS_DMA_SZ;
+ dm_kva += FCPORT_STATS_DMA_SZ;
+ dm_pa += FCPORT_STATS_DMA_SZ;
bfa_meminfo_dma_virt(meminfo) = dm_kva;
bfa_meminfo_dma_phys(meminfo) = dm_pa;
@@ -676,18 +882,21 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
* Memory initialization.
*/
static void
-bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
+bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
- struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
+ struct bfa_fcport_ln_s *ln = &fcport->ln;
- bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
- pport->bfa = bfa;
+ bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
+ fcport->bfa = bfa;
+ ln->fcport = fcport;
- bfa_pport_mem_claim(pport, meminfo);
+ bfa_fcport_mem_claim(fcport, meminfo);
- bfa_sm_set_state(pport, bfa_pport_sm_uninit);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
+ bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
/**
* initialize and set default configuration
@@ -699,30 +908,30 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
- bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport);
+ bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
}
static void
-bfa_pport_initdone(struct bfa_s *bfa)
+bfa_fcport_initdone(struct bfa_s *bfa)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
/**
* Initialize port attributes from IOC hardware data.
*/
- bfa_pport_set_wwns(pport);
- if (pport->cfg.maxfrsize == 0)
- pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
- pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
- pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
+ bfa_fcport_set_wwns(fcport);
+ if (fcport->cfg.maxfrsize == 0)
+ fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
+ fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
+ fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
- bfa_assert(pport->cfg.maxfrsize);
- bfa_assert(pport->cfg.rx_bbcredit);
- bfa_assert(pport->speed_sup);
+ bfa_assert(fcport->cfg.maxfrsize);
+ bfa_assert(fcport->cfg.rx_bbcredit);
+ bfa_assert(fcport->speed_sup);
}
static void
-bfa_pport_detach(struct bfa_s *bfa)
+bfa_fcport_detach(struct bfa_s *bfa)
{
}
@@ -730,95 +939,97 @@ bfa_pport_detach(struct bfa_s *bfa)
* Called when IOC is ready.
*/
static void
-bfa_pport_start(struct bfa_s *bfa)
+bfa_fcport_start(struct bfa_s *bfa)
{
- bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START);
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
}
/**
* Called before IOC is stopped.
*/
static void
-bfa_pport_stop(struct bfa_s *bfa)
+bfa_fcport_stop(struct bfa_s *bfa)
{
- bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP);
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
}
/**
* Called when IOC failure is detected.
*/
static void
-bfa_pport_iocdisable(struct bfa_s *bfa)
+bfa_fcport_iocdisable(struct bfa_s *bfa)
{
- bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL);
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL);
}
static void
-bfa_pport_update_linkinfo(struct bfa_pport_s *pport)
+bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
{
- struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event;
+ struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
- pport->speed = pevent->link_state.speed;
- pport->topology = pevent->link_state.topology;
+ fcport->speed = pevent->link_state.speed;
+ fcport->topology = pevent->link_state.topology;
- if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP)
- pport->myalpa = pevent->link_state.tl.loop_info.myalpa;
+ if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
+ fcport->myalpa =
+ pevent->link_state.tl.loop_info.myalpa;
/*
* QoS Details
*/
- bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr);
- bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr);
+ bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
+ bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr);
- bfa_trc(pport->bfa, pport->speed);
- bfa_trc(pport->bfa, pport->topology);
+ bfa_trc(fcport->bfa, fcport->speed);
+ bfa_trc(fcport->bfa, fcport->topology);
}
static void
-bfa_pport_reset_linkinfo(struct bfa_pport_s *pport)
+bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
{
- pport->speed = BFA_PPORT_SPEED_UNKNOWN;
- pport->topology = BFA_PPORT_TOPOLOGY_NONE;
+ fcport->speed = BFA_PPORT_SPEED_UNKNOWN;
+ fcport->topology = BFA_PPORT_TOPOLOGY_NONE;
}
/**
* Send port enable message to firmware.
*/
static bfa_boolean_t
-bfa_pport_send_enable(struct bfa_pport_s *port)
+bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
{
- struct bfi_pport_enable_req_s *m;
+ struct bfi_fcport_enable_req_s *m;
/**
* Increment message tag before queue check, so that responses to old
* requests are discarded.
*/
- port->msgtag++;
+ fcport->msgtag++;
/**
* check for room in queue to send request now
*/
- m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+ m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
if (!m) {
- bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
+ bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+ &fcport->reqq_wait);
return BFA_FALSE;
}
- bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ,
- bfa_lpuid(port->bfa));
- m->nwwn = port->nwwn;
- m->pwwn = port->pwwn;
- m->port_cfg = port->cfg;
- m->msgtag = port->msgtag;
- m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize);
- bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa);
- bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo);
- bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi);
+ bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
+ bfa_lpuid(fcport->bfa));
+ m->nwwn = fcport->nwwn;
+ m->pwwn = fcport->pwwn;
+ m->port_cfg = fcport->cfg;
+ m->msgtag = fcport->msgtag;
+ m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
+ bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
+ bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
+ bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
/**
* queue I/O message to firmware
*/
- bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+ bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
return BFA_TRUE;
}
@@ -826,74 +1037,226 @@ bfa_pport_send_enable(struct bfa_pport_s *port)
* Send port disable message to firmware.
*/
static bfa_boolean_t
-bfa_pport_send_disable(struct bfa_pport_s *port)
+bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
{
- bfi_pport_disable_req_t *m;
+ struct bfi_fcport_req_s *m;
/**
* Increment message tag before queue check, so that responses to old
* requests are discarded.
*/
- port->msgtag++;
+ fcport->msgtag++;
/**
* check for room in queue to send request now
*/
- m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+ m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
if (!m) {
- bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
+ bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+ &fcport->reqq_wait);
return BFA_FALSE;
}
- bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ,
- bfa_lpuid(port->bfa));
- m->msgtag = port->msgtag;
+ bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
+ bfa_lpuid(fcport->bfa));
+ m->msgtag = fcport->msgtag;
/**
* queue I/O message to firmware
*/
- bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+ bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
return BFA_TRUE;
}
static void
-bfa_pport_set_wwns(struct bfa_pport_s *port)
+bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
{
- port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc);
- port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc);
+ fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
+ fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
- bfa_trc(port->bfa, port->pwwn);
- bfa_trc(port->bfa, port->nwwn);
+ bfa_trc(fcport->bfa, fcport->pwwn);
+ bfa_trc(fcport->bfa, fcport->nwwn);
}
static void
-bfa_port_send_txcredit(void *port_cbarg)
+bfa_fcport_send_txcredit(void *port_cbarg)
{
- struct bfa_pport_s *port = port_cbarg;
- struct bfi_pport_set_svc_params_req_s *m;
+ struct bfa_fcport_s *fcport = port_cbarg;
+ struct bfi_fcport_set_svc_params_req_s *m;
/**
* check for room in queue to send request now
*/
- m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+ m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
if (!m) {
- bfa_trc(port->bfa, port->cfg.tx_bbcredit);
+ bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
return;
}
- bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ,
- bfa_lpuid(port->bfa));
- m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit);
+ bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
+ bfa_lpuid(fcport->bfa));
+ m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit);
/**
* queue I/O message to firmware
*/
- bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+ bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
}
+static void
+bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
+ struct bfa_qos_stats_s *s)
+{
+ u32 *dip = (u32 *) d;
+ u32 *sip = (u32 *) s;
+ int i;
+
+ /* Now swap the 32 bit fields */
+ for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
+ dip[i] = bfa_os_ntohl(sip[i]);
+}
+static void
+bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
+ struct bfa_fcoe_stats_s *s)
+{
+ u32 *dip = (u32 *) d;
+ u32 *sip = (u32 *) s;
+ int i;
+
+ for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
+ i = i + 2) {
+#ifdef __BIGENDIAN
+ dip[i] = bfa_os_ntohl(sip[i]);
+ dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
+#else
+ dip[i] = bfa_os_ntohl(sip[i + 1]);
+ dip[i + 1] = bfa_os_ntohl(sip[i]);
+#endif
+ }
+}
+
+static void
+__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
+{
+ struct bfa_fcport_s *fcport = cbarg;
+
+ if (complete) {
+ if (fcport->stats_status == BFA_STATUS_OK) {
+
+ /* Swap FC QoS or FCoE stats */
+ if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
+ bfa_fcport_qos_stats_swap(
+ &fcport->stats_ret->fcqos,
+ &fcport->stats->fcqos);
+ else
+ bfa_fcport_fcoe_stats_swap(
+ &fcport->stats_ret->fcoe,
+ &fcport->stats->fcoe);
+ }
+ fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
+ } else {
+ fcport->stats_busy = BFA_FALSE;
+ fcport->stats_status = BFA_STATUS_OK;
+ }
+}
+
+static void
+bfa_fcport_stats_get_timeout(void *cbarg)
+{
+ struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+
+ bfa_trc(fcport->bfa, fcport->stats_qfull);
+
+ if (fcport->stats_qfull) {
+ bfa_reqq_wcancel(&fcport->stats_reqq_wait);
+ fcport->stats_qfull = BFA_FALSE;
+ }
+
+ fcport->stats_status = BFA_STATUS_ETIMER;
+ bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
+ fcport);
+}
+
+static void
+bfa_fcport_send_stats_get(void *cbarg)
+{
+ struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+ struct bfi_fcport_req_s *msg;
+
+ msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
+
+ if (!msg) {
+ fcport->stats_qfull = BFA_TRUE;
+ bfa_reqq_winit(&fcport->stats_reqq_wait,
+ bfa_fcport_send_stats_get, fcport);
+ bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+ &fcport->stats_reqq_wait);
+ return;
+ }
+ fcport->stats_qfull = BFA_FALSE;
+
+ bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+ bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
+ bfa_lpuid(fcport->bfa));
+ bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
+
+static void
+__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
+{
+ struct bfa_fcport_s *fcport = cbarg;
+
+ if (complete) {
+ fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
+ } else {
+ fcport->stats_busy = BFA_FALSE;
+ fcport->stats_status = BFA_STATUS_OK;
+ }
+}
+
+static void
+bfa_fcport_stats_clr_timeout(void *cbarg)
+{
+ struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+
+ bfa_trc(fcport->bfa, fcport->stats_qfull);
+
+ if (fcport->stats_qfull) {
+ bfa_reqq_wcancel(&fcport->stats_reqq_wait);
+ fcport->stats_qfull = BFA_FALSE;
+ }
+
+ fcport->stats_status = BFA_STATUS_ETIMER;
+ bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+ __bfa_cb_fcport_stats_clr, fcport);
+}
+
+static void
+bfa_fcport_send_stats_clear(void *cbarg)
+{
+ struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+ struct bfi_fcport_req_s *msg;
+
+ msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
+
+ if (!msg) {
+ fcport->stats_qfull = BFA_TRUE;
+ bfa_reqq_winit(&fcport->stats_reqq_wait,
+ bfa_fcport_send_stats_clear, fcport);
+ bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+ &fcport->stats_reqq_wait);
+ return;
+ }
+ fcport->stats_qfull = BFA_FALSE;
+
+ bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+ bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
+ bfa_lpuid(fcport->bfa));
+ bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
/**
* bfa_pport_public
@@ -903,32 +1266,32 @@ bfa_port_send_txcredit(void *port_cbarg)
* Firmware message handler.
*/
void
-bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
+bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
- union bfi_pport_i2h_msg_u i2hmsg;
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ union bfi_fcport_i2h_msg_u i2hmsg;
i2hmsg.msg = msg;
- pport->event_arg.i2hmsg = i2hmsg;
+ fcport->event_arg.i2hmsg = i2hmsg;
switch (msg->mhdr.msg_id) {
- case BFI_PPORT_I2H_ENABLE_RSP:
- if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
- bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
+ case BFI_FCPORT_I2H_ENABLE_RSP:
+ if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+ bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
break;
- case BFI_PPORT_I2H_DISABLE_RSP:
- if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
- bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
+ case BFI_FCPORT_I2H_DISABLE_RSP:
+ if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+ bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
break;
- case BFI_PPORT_I2H_EVENT:
+ case BFI_FCPORT_I2H_EVENT:
switch (i2hmsg.event->link_state.linkstate) {
case BFA_PPORT_LINKUP:
- bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP);
+ bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
break;
case BFA_PPORT_LINKDOWN:
- bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN);
+ bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
break;
case BFA_PPORT_TRUNK_LINKDOWN:
/** todo: event notification */
@@ -936,42 +1299,40 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
}
break;
- case BFI_PPORT_I2H_GET_STATS_RSP:
- case BFI_PPORT_I2H_GET_QOS_STATS_RSP:
+ case BFI_FCPORT_I2H_STATS_GET_RSP:
/*
* check for timer pop before processing the rsp
*/
- if (pport->stats_busy == BFA_FALSE
- || pport->stats_status == BFA_STATUS_ETIMER)
+ if (fcport->stats_busy == BFA_FALSE ||
+ fcport->stats_status == BFA_STATUS_ETIMER)
break;
- bfa_timer_stop(&pport->timer);
- pport->stats_status = i2hmsg.getstats_rsp->status;
- bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats,
- pport);
+ bfa_timer_stop(&fcport->timer);
+ fcport->stats_status = i2hmsg.pstatsget_rsp->status;
+ bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+ __bfa_cb_fcport_stats_get, fcport);
break;
- case BFI_PPORT_I2H_CLEAR_STATS_RSP:
- case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP:
+
+ case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
/*
* check for timer pop before processing the rsp
*/
- if (pport->stats_busy == BFA_FALSE
- || pport->stats_status == BFA_STATUS_ETIMER)
+ if (fcport->stats_busy == BFA_FALSE ||
+ fcport->stats_status == BFA_STATUS_ETIMER)
break;
- bfa_timer_stop(&pport->timer);
- pport->stats_status = BFA_STATUS_OK;
- bfa_cb_queue(pport->bfa, &pport->hcb_qe,
- __bfa_cb_port_stats_clr, pport);
+ bfa_timer_stop(&fcport->timer);
+ fcport->stats_status = BFA_STATUS_OK;
+ bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+ __bfa_cb_fcport_stats_clr, fcport);
break;
default:
bfa_assert(0);
+ break;
}
}
-
-
/**
* bfa_pport_api
*/
@@ -980,35 +1341,35 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
* Registered callback for port events.
*/
void
-bfa_pport_event_register(struct bfa_s *bfa,
+bfa_fcport_event_register(struct bfa_s *bfa,
void (*cbfn) (void *cbarg, bfa_pport_event_t event),
void *cbarg)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- pport->event_cbfn = cbfn;
- pport->event_cbarg = cbarg;
+ fcport->event_cbfn = cbfn;
+ fcport->event_cbarg = cbarg;
}
bfa_status_t
-bfa_pport_enable(struct bfa_s *bfa)
+bfa_fcport_enable(struct bfa_s *bfa)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- if (pport->diag_busy)
+ if (fcport->diag_busy)
return BFA_STATUS_DIAG_BUSY;
else if (bfa_sm_cmp_state
- (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
+ (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait))
return BFA_STATUS_DEVBUSY;
- bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
return BFA_STATUS_OK;
}
bfa_status_t
-bfa_pport_disable(struct bfa_s *bfa)
+bfa_fcport_disable(struct bfa_s *bfa)
{
- bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE);
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
return BFA_STATUS_OK;
}
@@ -1016,18 +1377,18 @@ bfa_pport_disable(struct bfa_s *bfa)
* Configure port speed.
*/
bfa_status_t
-bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
+bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, speed);
- if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) {
- bfa_trc(bfa, pport->speed_sup);
+ if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
+ bfa_trc(bfa, fcport->speed_sup);
return BFA_STATUS_UNSUPP_SPEED;
}
- pport->cfg.speed = speed;
+ fcport->cfg.speed = speed;
return BFA_STATUS_OK;
}
@@ -1036,23 +1397,23 @@ bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
* Get current speed.
*/
enum bfa_pport_speed
-bfa_pport_get_speed(struct bfa_s *bfa)
+bfa_fcport_get_speed(struct bfa_s *bfa)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- return port->speed;
+ return fcport->speed;
}
/**
* Configure port topology.
*/
bfa_status_t
-bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
+bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, topology);
- bfa_trc(bfa, pport->cfg.topology);
+ bfa_trc(bfa, fcport->cfg.topology);
switch (topology) {
case BFA_PPORT_TOPOLOGY_P2P:
@@ -1064,7 +1425,7 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
return BFA_STATUS_EINVAL;
}
- pport->cfg.topology = topology;
+ fcport->cfg.topology = topology;
return BFA_STATUS_OK;
}
@@ -1072,64 +1433,64 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
* Get current topology.
*/
enum bfa_pport_topology
-bfa_pport_get_topology(struct bfa_s *bfa)
+bfa_fcport_get_topology(struct bfa_s *bfa)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- return port->topology;
+ return fcport->topology;
}
bfa_status_t
-bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
+bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, alpa);
- bfa_trc(bfa, pport->cfg.cfg_hardalpa);
- bfa_trc(bfa, pport->cfg.hardalpa);
+ bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
+ bfa_trc(bfa, fcport->cfg.hardalpa);
- pport->cfg.cfg_hardalpa = BFA_TRUE;
- pport->cfg.hardalpa = alpa;
+ fcport->cfg.cfg_hardalpa = BFA_TRUE;
+ fcport->cfg.hardalpa = alpa;
return BFA_STATUS_OK;
}
bfa_status_t
-bfa_pport_clr_hardalpa(struct bfa_s *bfa)
+bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- bfa_trc(bfa, pport->cfg.cfg_hardalpa);
- bfa_trc(bfa, pport->cfg.hardalpa);
+ bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
+ bfa_trc(bfa, fcport->cfg.hardalpa);
- pport->cfg.cfg_hardalpa = BFA_FALSE;
+ fcport->cfg.cfg_hardalpa = BFA_FALSE;
return BFA_STATUS_OK;
}
bfa_boolean_t
-bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
+bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- *alpa = port->cfg.hardalpa;
- return port->cfg.cfg_hardalpa;
+ *alpa = fcport->cfg.hardalpa;
+ return fcport->cfg.cfg_hardalpa;
}
u8
-bfa_pport_get_myalpa(struct bfa_s *bfa)
+bfa_fcport_get_myalpa(struct bfa_s *bfa)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- return port->myalpa;
+ return fcport->myalpa;
}
bfa_status_t
-bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
+bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, maxfrsize);
- bfa_trc(bfa, pport->cfg.maxfrsize);
+ bfa_trc(bfa, fcport->cfg.maxfrsize);
/*
* with in range
@@ -1143,41 +1504,41 @@ bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
return BFA_STATUS_INVLD_DFSZ;
- pport->cfg.maxfrsize = maxfrsize;
+ fcport->cfg.maxfrsize = maxfrsize;
return BFA_STATUS_OK;
}
u16
-bfa_pport_get_maxfrsize(struct bfa_s *bfa)
+bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- return port->cfg.maxfrsize;
+ return fcport->cfg.maxfrsize;
}
u32
-bfa_pport_mypid(struct bfa_s *bfa)
+bfa_fcport_mypid(struct bfa_s *bfa)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- return port->mypid;
+ return fcport->mypid;
}
u8
-bfa_pport_get_rx_bbcredit(struct bfa_s *bfa)
+bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- return port->cfg.rx_bbcredit;
+ return fcport->cfg.rx_bbcredit;
}
void
-bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
+bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- port->cfg.tx_bbcredit = (u8) tx_bbcredit;
- bfa_port_send_txcredit(port);
+ fcport->cfg.tx_bbcredit = (u8) tx_bbcredit;
+ bfa_fcport_send_txcredit(fcport);
}
/**
@@ -1185,302 +1546,192 @@ bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
*/
wwn_t
-bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
+bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
if (node)
- return pport->nwwn;
+ return fcport->nwwn;
else
- return pport->pwwn;
+ return fcport->pwwn;
}
void
-bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
+bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
- attr->nwwn = pport->nwwn;
- attr->pwwn = pport->pwwn;
+ attr->nwwn = fcport->nwwn;
+ attr->pwwn = fcport->pwwn;
- bfa_os_memcpy(&attr->pport_cfg, &pport->cfg,
+ bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
sizeof(struct bfa_pport_cfg_s));
/*
* speed attributes
*/
- attr->pport_cfg.speed = pport->cfg.speed;
- attr->speed_supported = pport->speed_sup;
- attr->speed = pport->speed;
+ attr->pport_cfg.speed = fcport->cfg.speed;
+ attr->speed_supported = fcport->speed_sup;
+ attr->speed = fcport->speed;
attr->cos_supported = FC_CLASS_3;
/*
* topology attributes
*/
- attr->pport_cfg.topology = pport->cfg.topology;
- attr->topology = pport->topology;
+ attr->pport_cfg.topology = fcport->cfg.topology;
+ attr->topology = fcport->topology;
/*
* beacon attributes
*/
- attr->beacon = pport->beacon;
- attr->link_e2e_beacon = pport->link_e2e_beacon;
- attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog);
+ attr->beacon = fcport->beacon;
+ attr->link_e2e_beacon = fcport->link_e2e_beacon;
+ attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
- attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm);
- if (bfa_ioc_is_disabled(&pport->bfa->ioc))
+ attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm);
+ if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
attr->port_state = BFA_PPORT_ST_IOCDIS;
- else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc))
+ else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
attr->port_state = BFA_PPORT_ST_FWMISMATCH;
}
-static void
-bfa_port_stats_query(void *cbarg)
-{
- struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
- bfi_pport_get_stats_req_t *msg;
-
- msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
-
- if (!msg) {
- port->stats_qfull = BFA_TRUE;
- bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query,
- port);
- bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
- return;
- }
- port->stats_qfull = BFA_FALSE;
-
- bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t));
- bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ,
- bfa_lpuid(port->bfa));
- bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-
- return;
-}
-
-static void
-bfa_port_stats_clear(void *cbarg)
-{
- struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
- bfi_pport_clear_stats_req_t *msg;
-
- msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+#define BFA_FCPORT_STATS_TOV 1000
- if (!msg) {
- port->stats_qfull = BFA_TRUE;
- bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear,
- port);
- bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
- return;
- }
- port->stats_qfull = BFA_FALSE;
-
- bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t));
- bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ,
- bfa_lpuid(port->bfa));
- bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
- return;
-}
-
-static void
-bfa_port_qos_stats_clear(void *cbarg)
+/**
+ * Fetch port attributes (FCQoS or FCoE).
+ */
+bfa_status_t
+bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+ bfa_cb_pport_t cbfn, void *cbarg)
{
- struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
- bfi_pport_clear_qos_stats_req_t *msg;
-
- msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- if (!msg) {
- port->stats_qfull = BFA_TRUE;
- bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear,
- port);
- bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
- return;
+ if (fcport->stats_busy) {
+ bfa_trc(bfa, fcport->stats_busy);
+ return BFA_STATUS_DEVBUSY;
}
- port->stats_qfull = BFA_FALSE;
- bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t));
- bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ,
- bfa_lpuid(port->bfa));
- bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
- return;
-}
-
-static void
-bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s)
-{
- u32 *dip = (u32 *) d;
- u32 *sip = (u32 *) s;
- int i;
+ fcport->stats_busy = BFA_TRUE;
+ fcport->stats_ret = stats;
+ fcport->stats_cbfn = cbfn;
+ fcport->stats_cbarg = cbarg;
- /*
- * Do 64 bit fields swap first
- */
- for (i = 0;
- i <
- ((sizeof(union bfa_pport_stats_u) -
- sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) {
-#ifdef __BIGENDIAN
- dip[i] = bfa_os_ntohl(sip[i]);
- dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
-#else
- dip[i] = bfa_os_ntohl(sip[i + 1]);
- dip[i + 1] = bfa_os_ntohl(sip[i]);
-#endif
- }
+ bfa_fcport_send_stats_get(fcport);
- /*
- * Now swap the 32 bit fields
- */
- for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i)
- dip[i] = bfa_os_ntohl(sip[i]);
+ bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
+ fcport, BFA_FCPORT_STATS_TOV);
+ return BFA_STATUS_OK;
}
-static void
-__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete)
+/**
+ * Reset port statistics (FCQoS or FCoE).
+ */
+bfa_status_t
+bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
{
- struct bfa_pport_s *port = cbarg;
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- if (complete) {
- port->stats_cbfn(port->stats_cbarg, port->stats_status);
- } else {
- port->stats_busy = BFA_FALSE;
- port->stats_status = BFA_STATUS_OK;
+ if (fcport->stats_busy) {
+ bfa_trc(bfa, fcport->stats_busy);
+ return BFA_STATUS_DEVBUSY;
}
-}
-
-static void
-bfa_port_stats_clr_timeout(void *cbarg)
-{
- struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
- bfa_trc(port->bfa, port->stats_qfull);
+ fcport->stats_busy = BFA_TRUE;
+ fcport->stats_cbfn = cbfn;
+ fcport->stats_cbarg = cbarg;
- if (port->stats_qfull) {
- bfa_reqq_wcancel(&port->stats_reqq_wait);
- port->stats_qfull = BFA_FALSE;
- }
+ bfa_fcport_send_stats_clear(fcport);
- port->stats_status = BFA_STATUS_ETIMER;
- bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port);
+ bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
+ fcport, BFA_FCPORT_STATS_TOV);
+ return BFA_STATUS_OK;
}
-static void
-__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
+/**
+ * Fetch FCQoS port statistics
+ */
+bfa_status_t
+bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+ bfa_cb_pport_t cbfn, void *cbarg)
{
- struct bfa_pport_s *port = cbarg;
+ /* Meaningful only for FC mode */
+ bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
- if (complete) {
- if (port->stats_status == BFA_STATUS_OK)
- bfa_pport_stats_swap(port->stats_ret, port->stats);
- port->stats_cbfn(port->stats_cbarg, port->stats_status);
- } else {
- port->stats_busy = BFA_FALSE;
- port->stats_status = BFA_STATUS_OK;
- }
+ return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
}
-static void
-bfa_port_stats_timeout(void *cbarg)
+/**
+ * Reset FCoE port statistics
+ */
+bfa_status_t
+bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
{
- struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-
- bfa_trc(port->bfa, port->stats_qfull);
+ /* Meaningful only for FC mode */
+ bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
- if (port->stats_qfull) {
- bfa_reqq_wcancel(&port->stats_reqq_wait);
- port->stats_qfull = BFA_FALSE;
- }
-
- port->stats_status = BFA_STATUS_ETIMER;
- bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port);
+ return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
}
-#define BFA_PORT_STATS_TOV 1000
-
/**
- * Fetch port attributes.
+ * Fetch FCQoS port statistics
*/
bfa_status_t
-bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
- bfa_cb_pport_t cbfn, void *cbarg)
+bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+ bfa_cb_pport_t cbfn, void *cbarg)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
- if (port->stats_busy) {
- bfa_trc(bfa, port->stats_busy);
- return BFA_STATUS_DEVBUSY;
- }
-
- port->stats_busy = BFA_TRUE;
- port->stats_ret = stats;
- port->stats_cbfn = cbfn;
- port->stats_cbarg = cbarg;
-
- bfa_port_stats_query(port);
+ /* Meaningful only for FCoE mode */
+ bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
- bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
- BFA_PORT_STATS_TOV);
- return BFA_STATUS_OK;
+ return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
}
+/**
+ * Reset FCoE port statistics
+ */
bfa_status_t
-bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
+bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
- if (port->stats_busy) {
- bfa_trc(bfa, port->stats_busy);
- return BFA_STATUS_DEVBUSY;
- }
-
- port->stats_busy = BFA_TRUE;
- port->stats_cbfn = cbfn;
- port->stats_cbarg = cbarg;
-
- bfa_port_stats_clear(port);
+ /* Meaningful only for FCoE mode */
+ bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
- bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
- BFA_PORT_STATS_TOV);
- return BFA_STATUS_OK;
+ return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
}
bfa_status_t
-bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
+bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, bitmap);
- bfa_trc(bfa, pport->cfg.trunked);
- bfa_trc(bfa, pport->cfg.trunk_ports);
+ bfa_trc(bfa, fcport->cfg.trunked);
+ bfa_trc(bfa, fcport->cfg.trunk_ports);
if (!bitmap || (bitmap & (bitmap - 1)))
return BFA_STATUS_EINVAL;
- pport->cfg.trunked = BFA_TRUE;
- pport->cfg.trunk_ports = bitmap;
+ fcport->cfg.trunked = BFA_TRUE;
+ fcport->cfg.trunk_ports = bitmap;
return BFA_STATUS_OK;
}
void
-bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
+bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- qos_attr->state = bfa_os_ntohl(pport->qos_attr.state);
- qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr);
+ qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state);
+ qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
}
void
-bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
+bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
struct bfa_qos_vc_attr_s *qos_vc_attr)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
- struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr;
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
u32 i = 0;
qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
@@ -1503,119 +1754,89 @@ bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
}
/**
- * Fetch QoS Stats.
- */
-bfa_status_t
-bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
- bfa_cb_pport_t cbfn, void *cbarg)
-{
- /*
- * QoS stats is embedded in port stats
- */
- return bfa_pport_get_stats(bfa, stats, cbfn, cbarg);
-}
-
-bfa_status_t
-bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
-{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
- if (port->stats_busy) {
- bfa_trc(bfa, port->stats_busy);
- return BFA_STATUS_DEVBUSY;
- }
-
- port->stats_busy = BFA_TRUE;
- port->stats_cbfn = cbfn;
- port->stats_cbarg = cbarg;
-
- bfa_port_qos_stats_clear(port);
-
- bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
- BFA_PORT_STATS_TOV);
- return BFA_STATUS_OK;
-}
-
-/**
* Fetch port attributes.
*/
bfa_status_t
-bfa_pport_trunk_disable(struct bfa_s *bfa)
+bfa_fcport_trunk_disable(struct bfa_s *bfa)
{
return BFA_STATUS_OK;
}
bfa_boolean_t
-bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
+bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- *bitmap = port->cfg.trunk_ports;
- return port->cfg.trunked;
+ *bitmap = fcport->cfg.trunk_ports;
+ return fcport->cfg.trunked;
}
bfa_boolean_t
-bfa_pport_is_disabled(struct bfa_s *bfa)
+bfa_fcport_is_disabled(struct bfa_s *bfa)
{
- struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- return bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
+ return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) ==
BFA_PPORT_ST_DISABLED;
}
bfa_boolean_t
-bfa_pport_is_ratelim(struct bfa_s *bfa)
+bfa_fcport_is_ratelim(struct bfa_s *bfa)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
+ return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
}
void
-bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
+bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
bfa_trc(bfa, on_off);
- bfa_trc(bfa, pport->cfg.qos_enabled);
+ bfa_trc(bfa, fcport->cfg.qos_enabled);
+
+ bfa_trc(bfa, ioc_type);
- pport->cfg.qos_enabled = on_off;
+ if (ioc_type == BFA_IOC_TYPE_FC)
+ fcport->cfg.qos_enabled = on_off;
}
void
-bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
+bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, on_off);
- bfa_trc(bfa, pport->cfg.ratelimit);
+ bfa_trc(bfa, fcport->cfg.ratelimit);
- pport->cfg.ratelimit = on_off;
- if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
- pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
+ fcport->cfg.ratelimit = on_off;
+ if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
+ fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
}
/**
* Configure default minimum ratelim speed
*/
bfa_status_t
-bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
+bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, speed);
/*
* Auto and speeds greater than the supported speed, are invalid
*/
- if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) {
- bfa_trc(bfa, pport->speed_sup);
+ if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
+ bfa_trc(bfa, fcport->speed_sup);
return BFA_STATUS_UNSUPP_SPEED;
}
- pport->cfg.trl_def_speed = speed;
+ fcport->cfg.trl_def_speed = speed;
return BFA_STATUS_OK;
}
@@ -1624,45 +1845,45 @@ bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
* Get default minimum ratelim speed
*/
enum bfa_pport_speed
-bfa_pport_get_ratelim_speed(struct bfa_s *bfa)
+bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- bfa_trc(bfa, pport->cfg.trl_def_speed);
- return pport->cfg.trl_def_speed;
+ bfa_trc(bfa, fcport->cfg.trl_def_speed);
+ return fcport->cfg.trl_def_speed;
}
void
-bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status)
+bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, status);
- bfa_trc(bfa, pport->diag_busy);
+ bfa_trc(bfa, fcport->diag_busy);
- pport->diag_busy = status;
+ fcport->diag_busy = status;
}
void
-bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
+bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
bfa_boolean_t link_e2e_beacon)
{
- struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
bfa_trc(bfa, beacon);
bfa_trc(bfa, link_e2e_beacon);
- bfa_trc(bfa, pport->beacon);
- bfa_trc(bfa, pport->link_e2e_beacon);
+ bfa_trc(bfa, fcport->beacon);
+ bfa_trc(bfa, fcport->link_e2e_beacon);
- pport->beacon = beacon;
- pport->link_e2e_beacon = link_e2e_beacon;
+ fcport->beacon = beacon;
+ fcport->link_e2e_beacon = link_e2e_beacon;
}
bfa_boolean_t
-bfa_pport_is_linkup(struct bfa_s *bfa)
+bfa_fcport_is_linkup(struct bfa_s *bfa)
{
- return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup);
+ return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
}
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index 7cb39a306ea..3516172c597 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -36,6 +36,7 @@
* FCS sub-modules
*/
struct bfa_fcs_mod_s {
+ void (*attach) (struct bfa_fcs_s *fcs);
void (*modinit) (struct bfa_fcs_s *fcs);
void (*modexit) (struct bfa_fcs_s *fcs);
};
@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s {
#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
static struct bfa_fcs_mod_s fcs_modules[] = {
- BFA_FCS_MODULE(bfa_fcs_pport),
- BFA_FCS_MODULE(bfa_fcs_uf),
- BFA_FCS_MODULE(bfa_fcs_fabric),
- BFA_FCS_MODULE(bfa_fcs_vport),
- BFA_FCS_MODULE(bfa_fcs_rport),
- BFA_FCS_MODULE(bfa_fcs_fcpim),
+ { bfa_fcs_pport_attach, NULL, NULL },
+ { bfa_fcs_uf_attach, NULL, NULL },
+ { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
+ bfa_fcs_fabric_modexit },
};
/**
@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg)
*/
/**
- * FCS instance initialization.
- *
- * param[in] fcs FCS instance
- * param[in] bfa BFA instance
- * param[in] bfad BFA driver instance
- *
- * return None
+ * fcs attach -- called once to initialize data structures at driver attach time
*/
void
-bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
+bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
bfa_boolean_t min_cfg)
{
int i;
@@ -95,7 +88,24 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
mod = &fcs_modules[i];
- mod->modinit(fcs);
+ if (mod->attach)
+ mod->attach(fcs);
+ }
+}
+
+/**
+ * fcs initialization, called once after bfa initialization is complete
+ */
+void
+bfa_fcs_init(struct bfa_fcs_s *fcs)
+{
+ int i;
+ struct bfa_fcs_mod_s *mod;
+
+ for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
+ mod = &fcs_modules[i];
+ if (mod->modinit)
+ mod->modinit(fcs);
}
}
@@ -127,6 +137,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
}
/**
+ * @brief
+ * FCS FDMI Driver Parameter Initialization
+ *
+ * @param[in] fcs FCS instance
+ * @param[in] fdmi_enable TRUE/FALSE
+ *
+ * @return None
+ */
+void
+bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
+{
+
+ fcs->fdmi_enabled = fdmi_enable;
+
+}
+
+/**
* FCS instance cleanup and exit.
*
* param[in] fcs FCS instance
@@ -143,10 +170,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
for (i = 0; i < nmods; i++) {
- bfa_wc_up(&fcs->wc);
mod = &fcs_modules[i];
- mod->modexit(fcs);
+ if (mod->modexit) {
+ bfa_wc_up(&fcs->wc);
+ mod->modexit(fcs);
+ }
}
bfa_wc_wait(&fcs->wc);
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index c7ab257f10a..7c1251c682d 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
- switch (event) {
- case BFA_LPORT_AEN_ONLINE:
- bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr,
- role_str[role / 2]);
- break;
- case BFA_LPORT_AEN_OFFLINE:
- bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr,
- role_str[role / 2]);
- break;
- case BFA_LPORT_AEN_NEW:
- bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr,
- role_str[role / 2]);
- break;
- case BFA_LPORT_AEN_DELETE:
- bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr,
- role_str[role / 2]);
- break;
- case BFA_LPORT_AEN_DISCONNECT:
- bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr,
- role_str[role / 2]);
- break;
- default:
- break;
- }
+ bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
+ role_str[role/2]);
aen_data.lport.vf_id = port->fabric->vf_id;
aen_data.lport.roles = role;
@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
}
/**
- * Logical port initialization of base or virtual port.
- * Called by fabric for base port or by vport for virtual ports.
+ * Attach time initialization of logical ports.
*/
void
-bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
- u16 vf_id, struct bfa_port_cfg_s *port_cfg,
- struct bfa_fcs_vport_s *vport)
+bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
+ uint16_t vf_id, struct bfa_fcs_vport_s *vport)
{
lport->fcs = fcs;
lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
- bfa_os_assign(lport->port_cfg, *port_cfg);
lport->vport = vport;
lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
bfa_lps_get_tag(lport->fabric->lps);
INIT_LIST_HEAD(&lport->rport_q);
lport->num_rports = 0;
+}
+
+/**
+ * Logical port initialization of base or virtual port.
+ * Called by fabric for base port or by vport for virtual ports.
+ */
- lport->bfad_port =
- bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles,
+void
+bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
+ struct bfa_port_cfg_s *port_cfg)
+{
+ struct bfa_fcs_vport_s *vport = lport->vport;
+
+ bfa_os_assign(lport->port_cfg, *port_cfg);
+
+ lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport,
+ lport->port_cfg.roles,
lport->fabric->vf_drv,
vport ? vport->vport_drv : NULL);
+
bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
}
-
-
/**
* fcs_lport_api
*/
@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
if (port->fabric) {
port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
+ port_attr->authfail =
+ bfa_fcs_fabric_is_auth_failed(port->fabric);
port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
memcpy(port_attr->fabric_ip_addr,
bfa_fcs_port_get_fabric_ipaddr(port),
BFA_FCS_FABRIC_IPADDR_SZ);
- if (port->vport != NULL)
+ if (port->vport != NULL) {
port_attr->port_type = BFA_PPORT_TYPE_VPORT;
+ port_attr->fpma_mac =
+ bfa_lps_get_lp_mac(port->vport->lps);
+ } else
+ port_attr->fpma_mac =
+ bfa_lps_get_lp_mac(port->fabric->lps);
} else {
port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
diff --git a/drivers/scsi/bfa/bfa_fcs_port.c b/drivers/scsi/bfa/bfa_fcs_port.c
index 9c4b24e62de..3c27788cd52 100644
--- a/drivers/scsi/bfa/bfa_fcs_port.c
+++ b/drivers/scsi/bfa/bfa_fcs_port.c
@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
}
void
-bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_pport_attach(struct bfa_fcs_s *fcs)
{
- bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler,
- fcs);
-}
-
-void
-bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
-{
- bfa_fcs_modexit_comp(fcs);
+ bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs);
}
diff --git a/drivers/scsi/bfa/bfa_fcs_uf.c b/drivers/scsi/bfa/bfa_fcs_uf.c
index ad01db6444b..3d57d48bbae 100644
--- a/drivers/scsi/bfa/bfa_fcs_uf.c
+++ b/drivers/scsi/bfa/bfa_fcs_uf.c
@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
}
void
-bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
{
bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
}
-
-void
-bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs)
-{
- bfa_fcs_modexit_comp(fcs);
-}
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index ede1438619e..871a4e28575 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -53,6 +53,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa)
}
void
+bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq)
+{
+}
+
+static void
+bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
+{
+ bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
+ __HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq));
+}
+
+void
bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
{
}
@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
void
bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
{
+ bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
}
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
index 51ae5740e6e..76ceb9a4bf2 100644
--- a/drivers/scsi/bfa/bfa_hw_ct.c
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -85,6 +85,15 @@ bfa_hwct_reginit(struct bfa_s *bfa)
}
void
+bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
+{
+ u32 r32;
+
+ r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
+ bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32);
+}
+
+void
bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
{
u32 r32;
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c
index b36540e4ed7..0eba3f930d5 100644
--- a/drivers/scsi/bfa/bfa_intr.c
+++ b/drivers/scsi/bfa/bfa_intr.c
@@ -15,7 +15,7 @@
* General Public License for more details.
*/
#include <bfa.h>
-#include <bfi/bfi_cbreg.h>
+#include <bfi/bfi_ctreg.h>
#include <bfa_port_priv.h>
#include <bfa_intr_priv.h>
#include <cs/bfa_debug.h>
@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa)
bfa_ioc_mbox_isr(&bfa->ioc);
}
+static void
+bfa_reqq_resume(struct bfa_s *bfa, int qid)
+{
+ struct list_head *waitq, *qe, *qen;
+ struct bfa_reqq_wait_s *wqe;
+
+ waitq = bfa_reqq(bfa, qid);
+ list_for_each_safe(qe, qen, waitq) {
+ /**
+ * Callback only as long as there is room in request queue
+ */
+ if (bfa_reqq_full(bfa, qid))
+ break;
+
+ list_del(qe);
+ wqe = (struct bfa_reqq_wait_s *) qe;
+ wqe->qresume(wqe->cbarg);
+ }
+}
+
void
bfa_msix_all(struct bfa_s *bfa, int vec)
{
@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa)
bfa_msix_install(bfa);
intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
- __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
+ __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS |
+ __HFN_INT_LL_HALT);
if (pci_func == 0)
intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa)
void
bfa_msix_reqq(struct bfa_s *bfa, int qid)
{
- struct list_head *waitq, *qe, *qen;
- struct bfa_reqq_wait_s *wqe;
+ struct list_head *waitq;
qid &= (BFI_IOC_MAX_CQS - 1);
- waitq = bfa_reqq(bfa, qid);
- list_for_each_safe(qe, qen, waitq) {
- /**
- * Callback only as long as there is room in request queue
- */
- if (bfa_reqq_full(bfa, qid))
- break;
+ bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
- list_del(qe);
- wqe = (struct bfa_reqq_wait_s *) qe;
- wqe->qresume(wqe->cbarg);
- }
+ /**
+ * Resume any pending requests in the corresponding reqq.
+ */
+ waitq = bfa_reqq(bfa, qid);
+ if (!list_empty(waitq))
+ bfa_reqq_resume(bfa, qid);
}
void
@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
}
void
-bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
+bfa_msix_rspq(struct bfa_s *bfa, int qid)
{
- struct bfi_msg_s *m;
- u32 pi, ci;
+ struct bfi_msg_s *m;
+ u32 pi, ci;
+ struct list_head *waitq;
- bfa_trc_fp(bfa, rsp_qid);
+ bfa_trc_fp(bfa, qid);
- rsp_qid &= (BFI_IOC_MAX_CQS - 1);
+ qid &= (BFI_IOC_MAX_CQS - 1);
- bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid);
+ bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
- ci = bfa_rspq_ci(bfa, rsp_qid);
- pi = bfa_rspq_pi(bfa, rsp_qid);
+ ci = bfa_rspq_ci(bfa, qid);
+ pi = bfa_rspq_pi(bfa, qid);
bfa_trc_fp(bfa, ci);
bfa_trc_fp(bfa, pi);
if (bfa->rme_process) {
while (ci != pi) {
- m = bfa_rspq_elem(bfa, rsp_qid, ci);
+ m = bfa_rspq_elem(bfa, qid, ci);
bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
bfa_isrs[m->mhdr.msg_class] (bfa, m);
@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
/**
* update CI
*/
- bfa_rspq_ci(bfa, rsp_qid) = pi;
- bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi);
+ bfa_rspq_ci(bfa, qid) = pi;
+ bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
bfa_os_mmiowb();
+
+ /**
+ * Resume any pending requests in the corresponding reqq.
+ */
+ waitq = bfa_reqq(bfa, qid);
+ if (!list_empty(waitq))
+ bfa_reqq_resume(bfa, qid);
}
void
bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
{
- u32 intr;
+ u32 intr, curr_value;
intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
bfa_msix_lpu(bfa);
- if (intr & (__HFN_INT_ERR_EMC |
- __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 |
- __HFN_INT_ERR_PSS))
+ intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
+ __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
+
+ if (intr) {
+ if (intr & __HFN_INT_LL_HALT) {
+ /**
+ * If LL_HALT bit is set then FW Init Halt LL Port
+ * Register needs to be cleared as well so Interrupt
+ * Status Register will be cleared.
+ */
+ curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt);
+ curr_value &= ~__FW_INIT_HALT_P;
+ bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value);
+ }
+
+ if (intr & __HFN_INT_ERR_PSS) {
+ /**
+ * ERR_PSS bit needs to be cleared as well in case
+ * interrups are shared so driver's interrupt handler is
+ * still called eventhough it is already masked out.
+ */
+ curr_value = bfa_reg_read(
+ bfa->ioc.ioc_regs.pss_err_status_reg);
+ curr_value &= __PSS_ERR_STATUS_SET;
+ bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg,
+ curr_value);
+ }
+
+ bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr);
bfa_msix_errint(bfa, intr);
+ }
}
void
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 397d7e9eade..e038bc9769f 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -18,7 +18,7 @@
#include <bfa.h>
#include <bfa_ioc.h>
#include <bfa_fwimg_priv.h>
-#include <bfa_trcmod_priv.h>
+#include <cna/bfa_cna_trcmod.h>
#include <cs/bfa_debug.h>
#include <bfi/bfi_ioc.h>
#include <bfi/bfi_ctreg.h>
@@ -27,18 +27,17 @@
#include <log/bfa_log_hal.h>
#include <defs/bfa_defs_pci.h>
-BFA_TRC_FILE(HAL, IOC);
+BFA_TRC_FILE(CNA, IOC);
/**
* IOC local definitions
*/
#define BFA_IOC_TOV 2000 /* msecs */
-#define BFA_IOC_HB_TOV 1000 /* msecs */
-#define BFA_IOC_HB_FAIL_MAX 4
-#define BFA_IOC_HWINIT_MAX 2
+#define BFA_IOC_HWSEM_TOV 500 /* msecs */
+#define BFA_IOC_HB_TOV 500 /* msecs */
+#define BFA_IOC_HWINIT_MAX 2
#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
-#define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \
- + BFA_IOC_TOV)
+#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV
#define bfa_ioc_timer_start(__ioc) \
bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
@@ -51,12 +50,25 @@ BFA_TRC_FILE(HAL, IOC);
(sizeof(struct bfa_trc_mod_s) - \
BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
-#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
-#define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
-#define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
-#define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
-bfa_boolean_t bfa_auto_recover = BFA_FALSE;
+/**
+ * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
+ */
+
+#define bfa_ioc_firmware_lock(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
+#define bfa_ioc_firmware_unlock(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
+#define bfa_ioc_fwimg_get_chunk(__ioc, __off) \
+ ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off))
+#define bfa_ioc_fwimg_get_size(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc))
+#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
+#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
+#define bfa_ioc_notify_hbfail(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
+
+bfa_boolean_t bfa_auto_recover = BFA_TRUE;
/*
* forward declarations
@@ -64,7 +76,6 @@ bfa_boolean_t bfa_auto_recover = BFA_FALSE;
static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
enum bfa_ioc_aen_event event);
static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
-static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
static void bfa_ioc_timeout(void *ioc);
@@ -77,8 +88,6 @@ static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
-static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
-static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
@@ -508,14 +517,19 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
bfa_trc(ioc, event);
switch (event) {
- case IOC_E_HWERROR:
case IOC_E_FWRSP_DISABLE:
bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
/*
* !!! fall through !!!
*/
case IOC_E_TIMEOUT:
+ bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
break;
@@ -608,15 +622,12 @@ bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
* Mark IOC as failed in hardware and stop firmware.
*/
bfa_ioc_lpu_stop(ioc);
- bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL);
+ bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
- if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
- bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
- /*
- * Wait for halt to take effect
- */
- bfa_reg_read(ioc->ioc_regs.ll_halt);
- }
+ /**
+ * Notify other functions on HB failure.
+ */
+ bfa_ioc_notify_hbfail(ioc);
/**
* Notify driver and common modules registered for notification.
@@ -672,6 +683,12 @@ bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
*/
break;
+ case IOC_E_HWERROR:
+ /*
+ * HB failure notification, ignore.
+ */
+ break;
+
default:
bfa_sm_fault(ioc, event);
}
@@ -700,7 +717,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
}
}
-static void
+void
bfa_ioc_sem_timeout(void *ioc_arg)
{
struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
@@ -708,26 +725,32 @@ bfa_ioc_sem_timeout(void *ioc_arg)
bfa_ioc_hw_sem_get(ioc);
}
-static void
-bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc)
+bfa_boolean_t
+bfa_ioc_sem_get(bfa_os_addr_t sem_reg)
{
- u32 r32;
- int cnt = 0;
-#define BFA_SEM_SPINCNT 1000
+ u32 r32;
+ int cnt = 0;
+#define BFA_SEM_SPINCNT 3000
- do {
- r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg);
+ r32 = bfa_reg_read(sem_reg);
+
+ while (r32 && (cnt < BFA_SEM_SPINCNT)) {
cnt++;
- if (cnt > BFA_SEM_SPINCNT)
- break;
- } while (r32 != 0);
+ bfa_os_udelay(2);
+ r32 = bfa_reg_read(sem_reg);
+ }
+
+ if (r32 == 0)
+ return BFA_TRUE;
+
bfa_assert(cnt < BFA_SEM_SPINCNT);
+ return BFA_FALSE;
}
-static void
-bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc)
+void
+bfa_ioc_sem_release(bfa_os_addr_t sem_reg)
{
- bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1);
+ bfa_reg_write(sem_reg, 1);
}
static void
@@ -737,7 +760,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
/**
* First read to the semaphore register will return 0, subsequent reads
- * will return 1. Semaphore is released by writing 0 to the register
+ * will return 1. Semaphore is released by writing 1 to the register
*/
r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
if (r32 == 0) {
@@ -746,10 +769,10 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
}
bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
- ioc, BFA_IOC_TOV);
+ ioc, BFA_IOC_HWSEM_TOV);
}
-static void
+void
bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
{
bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
@@ -828,7 +851,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
/**
* Get driver and firmware versions.
*/
-static void
+void
bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
{
u32 pgnum, pgoff;
@@ -847,24 +870,10 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
}
}
-static u32 *
-bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
-{
- if (ioc->ctdev)
- return bfi_image_ct_get_chunk(off);
- return bfi_image_cb_get_chunk(off);
-}
-
-static u32
-bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
-{
-return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
-}
-
/**
* Returns TRUE if same.
*/
-static bfa_boolean_t
+bfa_boolean_t
bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
{
struct bfi_ioc_image_hdr_s *drv_fwhdr;
@@ -921,95 +930,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
}
/**
- * Return true if firmware of current driver matches the running firmware.
- */
-static bfa_boolean_t
-bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
-{
- enum bfi_ioc_state ioc_fwstate;
- u32 usecnt;
- struct bfi_ioc_image_hdr_s fwhdr;
-
- /**
- * Firmware match check is relevant only for CNA.
- */
- if (!ioc->cna)
- return BFA_TRUE;
-
- /**
- * If bios boot (flash based) -- do not increment usage count
- */
- if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
- return BFA_TRUE;
-
- bfa_ioc_usage_sem_get(ioc);
- usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
-
- /**
- * If usage count is 0, always return TRUE.
- */
- if (usecnt == 0) {
- bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
- bfa_ioc_usage_sem_release(ioc);
- bfa_trc(ioc, usecnt);
- return BFA_TRUE;
- }
-
- ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
- bfa_trc(ioc, ioc_fwstate);
-
- /**
- * Use count cannot be non-zero and chip in uninitialized state.
- */
- bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
-
- /**
- * Check if another driver with a different firmware is active
- */
- bfa_ioc_fwver_get(ioc, &fwhdr);
- if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
- bfa_ioc_usage_sem_release(ioc);
- bfa_trc(ioc, usecnt);
- return BFA_FALSE;
- }
-
- /**
- * Same firmware version. Increment the reference count.
- */
- usecnt++;
- bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
- bfa_ioc_usage_sem_release(ioc);
- bfa_trc(ioc, usecnt);
- return BFA_TRUE;
-}
-
-static void
-bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
-{
- u32 usecnt;
-
- /**
- * Firmware lock is relevant only for CNA.
- * If bios boot (flash based) -- do not decrement usage count
- */
- if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
- return;
-
- /**
- * decrement usage count
- */
- bfa_ioc_usage_sem_get(ioc);
- usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
- bfa_assert(usecnt > 0);
-
- usecnt--;
- bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
- bfa_trc(ioc, usecnt);
-
- bfa_ioc_usage_sem_release(ioc);
-}
-
-/**
* Conditionally flush any pending message from firmware at start.
*/
static void
@@ -1152,33 +1072,27 @@ bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
static void
bfa_ioc_hb_check(void *cbarg)
{
- struct bfa_ioc_s *ioc = cbarg;
- u32 hb_count;
+ struct bfa_ioc_s *ioc = cbarg;
+ u32 hb_count;
hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
if (ioc->hb_count == hb_count) {
- ioc->hb_fail++;
- } else {
- ioc->hb_count = hb_count;
- ioc->hb_fail = 0;
- }
-
- if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
- bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
- ioc->hb_fail = 0;
+ bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE,
+ hb_count);
bfa_ioc_recover(ioc);
return;
+ } else {
+ ioc->hb_count = hb_count;
}
bfa_ioc_mbox_poll(ioc);
- bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
- BFA_IOC_HB_TOV);
+ bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check,
+ ioc, BFA_IOC_HB_TOV);
}
static void
bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
{
- ioc->hb_fail = 0;
ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
BFA_IOC_HB_TOV);
@@ -1191,112 +1105,6 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
}
/**
- * Host to LPU mailbox message addresses
- */
-static struct {
- u32 hfn_mbox, lpu_mbox, hfn_pgn;
-} iocreg_fnreg[] = {
- {
- HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
- HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
- HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
- HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
-};
-
-/**
- * Host <-> LPU mailbox command/status registers - port 0
- */
-static struct {
- u32 hfn, lpu;
-} iocreg_mbcmd_p0[] = {
- {
- HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
- HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
- HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
- HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
-};
-
-/**
- * Host <-> LPU mailbox command/status registers - port 1
- */
-static struct {
- u32 hfn, lpu;
-} iocreg_mbcmd_p1[] = {
- {
- HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
- HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
- HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
- HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
-};
-
-/**
- * Shared IRQ handling in INTX mode
- */
-static struct {
- u32 isr, msk;
-} iocreg_shirq_next[] = {
- {
- HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
- HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
- HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
-HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
-
-static void
-bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
-{
- bfa_os_addr_t rb;
- int pcifn = bfa_ioc_pcifn(ioc);
-
- rb = bfa_ioc_bar0(ioc);
-
- ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
- ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
- ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
-
- if (ioc->port_id == 0) {
- ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
- ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
- ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
- ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
- ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
- } else {
- ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
- ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
- ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
- ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
- ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
- }
-
- /**
- * Shared IRQ handling in INTX mode
- */
- ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
- ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
-
- /*
- * PSS control registers
- */
- ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
- ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
- ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
-
- /*
- * IOC semaphore registers and serialization
- */
- ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
- ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
- ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
-
- /**
- * sram memory access
- */
- ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
- ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
- if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
- ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
-}
-
-/**
* Initiate a full firmware download.
*/
static void
@@ -1321,9 +1129,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
boot_type = BFI_BOOT_TYPE_FLASH;
fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
- fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
- fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
- bfa_os_swap32(boot_param);
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
pgoff = bfa_ioc_smem_pgoff(ioc, loff);
@@ -1332,17 +1137,17 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
- if (BFA_FLASH_CHUNK_NO(i) != chunkno) {
- chunkno = BFA_FLASH_CHUNK_NO(i);
+ if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
+ chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
fwimg = bfa_ioc_fwimg_get_chunk(ioc,
- BFA_FLASH_CHUNK_ADDR(chunkno));
+ BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
}
/**
* write smem
*/
bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
- fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]);
+ fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
loff += sizeof(u32);
@@ -1358,6 +1163,14 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
bfa_ioc_smem_pgnum(ioc, 0));
+
+ /*
+ * Set boot type and boot param at the end.
+ */
+ bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF,
+ bfa_os_swap32(boot_type));
+ bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_PARAM_OFF,
+ bfa_os_swap32(boot_param));
}
static void
@@ -1440,168 +1253,10 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
}
/**
- * Initialize IOC to port mapping.
- */
-
-#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
-static void
-bfa_ioc_map_port(struct bfa_ioc_s *ioc)
-{
- bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
- u32 r32;
-
- /**
- * For crossbow, port id is same as pci function.
- */
- if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
- ioc->port_id = bfa_ioc_pcifn(ioc);
- return;
- }
-
- /**
- * For catapult, base port id on personality register and IOC type
- */
- r32 = bfa_reg_read(rb + FNC_PERS_REG);
- r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
- ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
-
- bfa_trc(ioc, bfa_ioc_pcifn(ioc));
- bfa_trc(ioc, ioc->port_id);
-}
-
-
-
-/**
* bfa_ioc_public
*/
/**
-* Set interrupt mode for a function: INTX or MSIX
- */
-void
-bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
-{
- bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
- u32 r32, mode;
-
- r32 = bfa_reg_read(rb + FNC_PERS_REG);
- bfa_trc(ioc, r32);
-
- mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
- __F0_INTX_STATUS;
-
- /**
- * If already in desired mode, do not change anything
- */
- if (!msix && mode)
- return;
-
- if (msix)
- mode = __F0_INTX_STATUS_MSIX;
- else
- mode = __F0_INTX_STATUS_INTA;
-
- r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
- r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
- bfa_trc(ioc, r32);
-
- bfa_reg_write(rb + FNC_PERS_REG, r32);
-}
-
-bfa_status_t
-bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
-{
- bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
- u32 pll_sclk, pll_fclk, r32;
-
- if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
- pll_sclk =
- __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
- __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
- __APP_PLL_312_JITLMT0_1(3U) |
- __APP_PLL_312_CNTLMT0_1(1U);
- pll_fclk =
- __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
- __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
- __APP_PLL_425_JITLMT0_1(3U) |
- __APP_PLL_425_CNTLMT0_1(1U);
-
- /**
- * For catapult, choose operational mode FC/FCoE
- */
- if (ioc->fcmode) {
- bfa_reg_write((rb + OP_MODE), 0);
- bfa_reg_write((rb + ETH_MAC_SER_REG),
- __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
- | __APP_EMS_CHANNEL_SEL);
- } else {
- ioc->pllinit = BFA_TRUE;
- bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
- bfa_reg_write((rb + ETH_MAC_SER_REG),
- __APP_EMS_REFCKBUFEN1);
- }
- } else {
- pll_sclk =
- __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
- __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
- __APP_PLL_312_CNTLMT0_1(3U);
- pll_fclk =
- __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
- __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
- __APP_PLL_425_JITLMT0_1(3U) |
- __APP_PLL_425_CNTLMT0_1(3U);
- }
-
- bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
- bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
-
- bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
- bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
- bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
- bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
- bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
- bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-
- bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
- __APP_PLL_312_LOGIC_SOFT_RESET);
- bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
- __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
- bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
- __APP_PLL_425_LOGIC_SOFT_RESET);
- bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
- __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
- bfa_os_udelay(2);
- bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
- __APP_PLL_312_LOGIC_SOFT_RESET);
- bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
- __APP_PLL_425_LOGIC_SOFT_RESET);
-
- bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
- pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
- bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
- pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
-
- /**
- * Wait for PLLs to lock.
- */
- bfa_os_udelay(2000);
- bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
- bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-
- bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
- bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
-
- if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
- bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
- bfa_os_udelay(1000);
- r32 = bfa_reg_read((rb + MBIST_STAT_REG));
- bfa_trc(ioc, r32);
- }
-
- return BFA_STATUS_OK;
-}
-
-/**
* Interface used by diag module to do firmware boot with memory test
* as the entry vector.
*/
@@ -1642,7 +1297,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
void
bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
{
- bfa_auto_recover = BFA_FALSE;
+ bfa_auto_recover = auto_recover;
}
@@ -1764,6 +1419,14 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
ioc->cna = ioc->ctdev && !ioc->fcmode;
+ /**
+ * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
+ */
+ if (ioc->ctdev)
+ bfa_ioc_set_ct_hwif(ioc);
+ else
+ bfa_ioc_set_cb_hwif(ioc);
+
bfa_ioc_map_port(ioc);
bfa_ioc_reg_init(ioc);
}
@@ -1830,7 +1493,6 @@ return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
void
bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
{
- bfa_assert(ioc->auto_recover);
ioc->dbg_fwsave = dbg_fwsave;
ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
}
@@ -1973,7 +1635,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
((__sm) == BFI_IOC_INITING) || \
((__sm) == BFI_IOC_HWINIT) || \
((__sm) == BFI_IOC_DISABLED) || \
- ((__sm) == BFI_IOC_HBFAIL) || \
+ ((__sm) == BFI_IOC_FAIL) || \
((__sm) == BFI_IOC_CFG_DISABLED))
/**
@@ -2017,46 +1679,28 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
struct bfa_adapter_attr_s *ad_attr)
{
struct bfi_ioc_attr_s *ioc_attr;
- char model[BFA_ADAPTER_MODEL_NAME_LEN];
ioc_attr = ioc->attr;
- bfa_os_memcpy((void *)&ad_attr->serial_num,
- (void *)ioc_attr->brcd_serialnum,
- BFA_ADAPTER_SERIAL_NUM_LEN);
-
- bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN);
- bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
- BFA_VERSION_LEN);
- bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
- BFA_ADAPTER_MFG_NAME_LEN);
+
+ bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
+ bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
+ bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
+ bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
sizeof(struct bfa_mfg_vpd_s));
- ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop);
- ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
+ ad_attr->nports = bfa_ioc_get_nports(ioc);
+ ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
- /**
- * model name
- */
- if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
- strcpy(model, "BR-10?0");
- model[5] = '0' + ad_attr->nports;
- } else {
- strcpy(model, "Brocade-??5");
- model[8] =
- '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
- model[9] = '0' + ad_attr->nports;
- }
+ bfa_ioc_get_adapter_model(ioc, ad_attr->model);
+ /* For now, model descr uses same model string */
+ bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
ad_attr->prototype = 1;
else
ad_attr->prototype = 0;
- bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
- bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
- BFA_ADAPTER_MODEL_NAME_LEN);
-
ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
ad_attr->mac = bfa_ioc_get_mac(ioc);
@@ -2064,41 +1708,122 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
ad_attr->asic_rev = ioc_attr->asic_rev;
- ad_attr->hw_ver[0] = 'R';
- ad_attr->hw_ver[1] = 'e';
- ad_attr->hw_ver[2] = 'v';
- ad_attr->hw_ver[3] = '-';
- ad_attr->hw_ver[4] = ioc_attr->asic_rev;
- ad_attr->hw_ver[5] = '\0';
+
+ bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
ad_attr->cna_capable = ioc->cna;
}
+enum bfa_ioc_type_e
+bfa_ioc_get_type(struct bfa_ioc_s *ioc)
+{
+ if (!ioc->ctdev || ioc->fcmode)
+ return BFA_IOC_TYPE_FC;
+ else if (ioc->ioc_mc == BFI_MC_IOCFC)
+ return BFA_IOC_TYPE_FCoE;
+ else if (ioc->ioc_mc == BFI_MC_LL)
+ return BFA_IOC_TYPE_LL;
+ else {
+ bfa_assert(ioc->ioc_mc == BFI_MC_LL);
+ return BFA_IOC_TYPE_LL;
+ }
+}
+
+void
+bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
+{
+ bfa_os_memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
+ bfa_os_memcpy((void *)serial_num,
+ (void *)ioc->attr->brcd_serialnum,
+ BFA_ADAPTER_SERIAL_NUM_LEN);
+}
+
+void
+bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
+{
+ bfa_os_memset((void *)fw_ver, 0, BFA_VERSION_LEN);
+ bfa_os_memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
+}
+
+void
+bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
+{
+ bfa_assert(chip_rev);
+
+ bfa_os_memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
+
+ chip_rev[0] = 'R';
+ chip_rev[1] = 'e';
+ chip_rev[2] = 'v';
+ chip_rev[3] = '-';
+ chip_rev[4] = ioc->attr->asic_rev;
+ chip_rev[5] = '\0';
+}
+
+void
+bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
+{
+ bfa_os_memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
+ bfa_os_memcpy(optrom_ver, ioc->attr->optrom_version,
+ BFA_VERSION_LEN);
+}
+
+void
+bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
+{
+ bfa_os_memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
+ bfa_os_memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+}
+
+void
+bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
+{
+ struct bfi_ioc_attr_s *ioc_attr;
+ u8 nports;
+ u8 max_speed;
+
+ bfa_assert(model);
+ bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
+
+ ioc_attr = ioc->attr;
+
+ nports = bfa_ioc_get_nports(ioc);
+ max_speed = bfa_ioc_speed_sup(ioc);
+
+ /**
+ * model name
+ */
+ if (max_speed == 10) {
+ strcpy(model, "BR-10?0");
+ model[5] = '0' + nports;
+ } else {
+ strcpy(model, "Brocade-??5");
+ model[8] = '0' + max_speed;
+ model[9] = '0' + nports;
+ }
+}
+
+enum bfa_ioc_state
+bfa_ioc_get_state(struct bfa_ioc_s *ioc)
+{
+ return bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+}
+
void
bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
{
bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
- ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+ ioc_attr->state = bfa_ioc_get_state(ioc);
ioc_attr->port_id = ioc->port_id;
- if (!ioc->ctdev)
- ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
- else if (ioc->ioc_mc == BFI_MC_IOCFC)
- ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
- else if (ioc->ioc_mc == BFI_MC_LL)
- ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
+ ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
- ioc_attr->pci_attr.chip_rev[0] = 'R';
- ioc_attr->pci_attr.chip_rev[1] = 'e';
- ioc_attr->pci_attr.chip_rev[2] = 'v';
- ioc_attr->pci_attr.chip_rev[3] = '-';
- ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
- ioc_attr->pci_attr.chip_rev[5] = '\0';
+ bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
}
/**
@@ -2195,29 +1920,6 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
}
/**
- * Return true if interrupt should be claimed.
- */
-bfa_boolean_t
-bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
-{
- u32 isr, msk;
-
- /**
- * Always claim if not catapult.
- */
- if (!ioc->ctdev)
- return BFA_TRUE;
-
- /**
- * FALSE if next device is claiming interrupt.
- * TRUE if next device is not interrupting or not present.
- */
- msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
- isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
- return !(isr & ~msk);
-}
-
-/**
* Send AEN notification
*/
static void
@@ -2226,32 +1928,14 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
union bfa_aen_data_u aen_data;
struct bfa_log_mod_s *logmod = ioc->logm;
s32 inst_num = 0;
- struct bfa_ioc_attr_s ioc_attr;
+ enum bfa_ioc_type_e ioc_type;
- switch (event) {
- case BFA_IOC_AEN_HBGOOD:
- bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num);
- break;
- case BFA_IOC_AEN_HBFAIL:
- bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num);
- break;
- case BFA_IOC_AEN_ENABLE:
- bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num);
- break;
- case BFA_IOC_AEN_DISABLE:
- bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num);
- break;
- case BFA_IOC_AEN_FWMISMATCH:
- bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num);
- break;
- default:
- break;
- }
+ bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, event), inst_num);
memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn));
memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac));
- bfa_ioc_get_attr(ioc, &ioc_attr);
- switch (ioc_attr.ioc_type) {
+ ioc_type = bfa_ioc_get_type(ioc);
+ switch (ioc_type) {
case BFA_IOC_TYPE_FC:
aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
break;
@@ -2263,10 +1947,10 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
break;
default:
- bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC);
+ bfa_assert(ioc_type == BFA_IOC_TYPE_FC);
break;
}
- aen_data.ioc.ioc_type = ioc_attr.ioc_type;
+ aen_data.ioc.ioc_type = ioc_type;
}
/**
@@ -2290,6 +1974,15 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
}
/**
+ * Clear saved firmware trace
+ */
+void
+bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc)
+{
+ ioc->dbg_fwsave_once = BFA_TRUE;
+}
+
+/**
* Retrieve saved firmware trace from a prior IOC failure.
*/
bfa_status_t
@@ -2304,6 +1997,13 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
loff = bfa_ioc_smem_pgoff(ioc, loff);
+
+ /*
+ * Hold semaphore to serialize pll init and fwtrc.
+ */
+ if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg))
+ return BFA_STATUS_FAILED;
+
bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
tlen = *trclen;
@@ -2329,6 +2029,12 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
}
bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
bfa_ioc_smem_pgnum(ioc, 0));
+
+ /*
+ * release semaphore.
+ */
+ bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
bfa_trc(ioc, pgnum);
*trclen = tlen * sizeof(u32);
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 7c30f05ab13..d0804406ea1 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s {
bfa_os_addr_t lpu_mbox_cmd;
bfa_os_addr_t lpu_mbox;
bfa_os_addr_t pss_ctl_reg;
+ bfa_os_addr_t pss_err_status_reg;
bfa_os_addr_t app_pll_fast_ctl_reg;
bfa_os_addr_t app_pll_slow_ctl_reg;
bfa_os_addr_t ioc_sem_reg;
bfa_os_addr_t ioc_usage_sem_reg;
+ bfa_os_addr_t ioc_init_sem_reg;
bfa_os_addr_t ioc_usage_reg;
bfa_os_addr_t host_page_num_fn;
bfa_os_addr_t heartbeat;
bfa_os_addr_t ioc_fwstate;
bfa_os_addr_t ll_halt;
+ bfa_os_addr_t err_set;
bfa_os_addr_t shirq_isr_next;
bfa_os_addr_t shirq_msk_next;
bfa_os_addr_t smem_page_start;
@@ -154,7 +157,6 @@ struct bfa_ioc_s {
struct bfa_timer_s ioc_timer;
struct bfa_timer_s sem_timer;
u32 hb_count;
- u32 hb_fail;
u32 retry_count;
struct list_head hb_notify_q;
void *dbg_fwsave;
@@ -177,6 +179,22 @@ struct bfa_ioc_s {
struct bfi_ioc_attr_s *attr;
struct bfa_ioc_cbfn_s *cbfn;
struct bfa_ioc_mbox_mod_s mbox_mod;
+ struct bfa_ioc_hwif_s *ioc_hwif;
+};
+
+struct bfa_ioc_hwif_s {
+ bfa_status_t (*ioc_pll_init) (struct bfa_ioc_s *ioc);
+ bfa_boolean_t (*ioc_firmware_lock) (struct bfa_ioc_s *ioc);
+ void (*ioc_firmware_unlock) (struct bfa_ioc_s *ioc);
+ u32 * (*ioc_fwimg_get_chunk) (struct bfa_ioc_s *ioc,
+ u32 off);
+ u32 (*ioc_fwimg_get_size) (struct bfa_ioc_s *ioc);
+ void (*ioc_reg_init) (struct bfa_ioc_s *ioc);
+ void (*ioc_map_port) (struct bfa_ioc_s *ioc);
+ void (*ioc_isr_mode_set) (struct bfa_ioc_s *ioc,
+ bfa_boolean_t msix);
+ void (*ioc_notify_hbfail) (struct bfa_ioc_s *ioc);
+ void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc);
};
#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
@@ -191,6 +209,15 @@ struct bfa_ioc_s {
#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit)
#define bfa_ioc_speed_sup(__ioc) \
BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
+#define bfa_ioc_get_nports(__ioc) \
+ BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
+
+#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
+#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
+
+#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
/**
* IOC mailbox interface
@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
/**
* IOC interfaces
*/
+#define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc))
+#define bfa_ioc_isr_mode_set(__ioc, __msix) \
+ ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
+#define bfa_ioc_ownership_reset(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
+
+void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc);
+void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc);
void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
struct bfa_trc_mod_s *trcmod,
@@ -223,13 +258,21 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
-void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
-bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc);
+enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc);
+void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num);
+void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver);
+void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver);
+void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model);
+void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc,
+ char *manufacturer);
+void bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev);
+enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc);
+
void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
struct bfa_adapter_attr_s *ad_attr);
@@ -237,6 +280,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover);
void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
int *trclen);
+void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc);
bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
int *trclen);
u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
@@ -245,6 +289,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
struct bfa_ioc_hbfail_notify_s *notify);
+bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg);
+void bfa_ioc_sem_release(bfa_os_addr_t sem_reg);
+void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
+void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
+ struct bfi_ioc_image_hdr_s *fwhdr);
+bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
+ struct bfi_ioc_image_hdr_s *fwhdr);
/*
* bfa mfg wwn API functions
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
new file mode 100644
index 00000000000..3ce85319f73
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc_cb.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) 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.
+ */
+
+#include <bfa.h>
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cna/bfa_cna_trcmod.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_cbreg.h>
+#include <log/bfa_log_hal.h>
+#include <defs/bfa_defs_pci.h>
+
+BFA_TRC_FILE(CNA, IOC_CB);
+
+/*
+ * forward declarations
+ */
+static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
+static u32 *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
+static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
+static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
+
+struct bfa_ioc_hwif_s hwif_cb = {
+ bfa_ioc_cb_pll_init,
+ bfa_ioc_cb_firmware_lock,
+ bfa_ioc_cb_firmware_unlock,
+ bfa_ioc_cb_fwimg_get_chunk,
+ bfa_ioc_cb_fwimg_get_size,
+ bfa_ioc_cb_reg_init,
+ bfa_ioc_cb_map_port,
+ bfa_ioc_cb_isr_mode_set,
+ bfa_ioc_cb_notify_hbfail,
+ bfa_ioc_cb_ownership_reset,
+};
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
+{
+ ioc->ioc_hwif = &hwif_cb;
+}
+
+static u32 *
+bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+ return bfi_image_cb_get_chunk(off);
+}
+
+static u32
+bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+ return bfi_image_cb_size;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
+{
+ return BFA_TRUE;
+}
+
+static void
+bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
+{
+ bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
+ bfa_reg_read(ioc->ioc_regs.err_set);
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+ { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+ { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
+ { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
+ { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }
+};
+
+static void
+bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
+{
+ bfa_os_addr_t rb;
+ int pcifn = bfa_ioc_pcifn(ioc);
+
+ rb = bfa_ioc_bar0(ioc);
+
+ ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+ ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+ ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+ if (ioc->port_id == 0) {
+ ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+ ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+ } else {
+ ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+ ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+ }
+
+ /**
+ * Host <-> LPU mailbox command/status registers
+ */
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu;
+
+ /*
+ * PSS control registers
+ */
+ ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+ ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+ ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG);
+ ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG);
+
+ /*
+ * IOC semaphore registers and serialization
+ */
+ ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+ ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+
+ /**
+ * sram memory access
+ */
+ ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+ ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
+
+ /*
+ * err set reg : for notification of hb failure
+ */
+ ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+static void
+bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
+{
+ /**
+ * For crossbow, port id is same as pci function.
+ */
+ ioc->port_id = bfa_ioc_pcifn(ioc);
+ bfa_trc(ioc, ioc->port_id);
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+}
+
+static bfa_status_t
+bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc)
+{
+ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
+ u32 pll_sclk, pll_fclk;
+
+ /*
+ * Hold semaphore so that nobody can access the chip during init.
+ */
+ bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+ pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN |
+ __APP_PLL_212_P0_1(3U) |
+ __APP_PLL_212_JITLMT0_1(3U) |
+ __APP_PLL_212_CNTLMT0_1(3U);
+ pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN |
+ __APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) |
+ __APP_PLL_400_JITLMT0_1(3U) |
+ __APP_PLL_400_CNTLMT0_1(3U);
+
+ bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+ bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+ bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+ __APP_PLL_212_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+ __APP_PLL_212_BYPASS |
+ __APP_PLL_212_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+ __APP_PLL_400_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+ __APP_PLL_400_BYPASS |
+ __APP_PLL_400_LOGIC_SOFT_RESET);
+ bfa_os_udelay(2);
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+ __APP_PLL_212_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+ __APP_PLL_400_LOGIC_SOFT_RESET);
+
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+ pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+ pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET);
+
+ /**
+ * Wait for PLLs to lock.
+ */
+ bfa_os_udelay(2000);
+ bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
+
+ /*
+ * release semaphore.
+ */
+ bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+ return BFA_STATUS_OK;
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
+{
+
+ /*
+ * Read the hw sem reg to make sure that it is locked
+ * before we clear it. If it is not locked, writing 1
+ * will lock it instead of clearing it.
+ */
+ bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+ bfa_ioc_hw_sem_release(ioc);
+}
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
new file mode 100644
index 00000000000..20b58ad5f95
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) 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.
+ */
+
+#include <bfa.h>
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cna/bfa_cna_trcmod.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_ctreg.h>
+#include <log/bfa_log_hal.h>
+#include <defs/bfa_defs_pci.h>
+
+BFA_TRC_FILE(CNA, IOC_CT);
+
+/*
+ * forward declarations
+ */
+static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
+static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
+ u32 off);
+static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
+static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
+
+struct bfa_ioc_hwif_s hwif_ct = {
+ bfa_ioc_ct_pll_init,
+ bfa_ioc_ct_firmware_lock,
+ bfa_ioc_ct_firmware_unlock,
+ bfa_ioc_ct_fwimg_get_chunk,
+ bfa_ioc_ct_fwimg_get_size,
+ bfa_ioc_ct_reg_init,
+ bfa_ioc_ct_map_port,
+ bfa_ioc_ct_isr_mode_set,
+ bfa_ioc_ct_notify_hbfail,
+ bfa_ioc_ct_ownership_reset,
+};
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
+{
+ ioc->ioc_hwif = &hwif_ct;
+}
+
+static u32*
+bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+ return bfi_image_ct_get_chunk(off);
+}
+
+static u32
+bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+ return bfi_image_ct_size;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
+{
+ enum bfi_ioc_state ioc_fwstate;
+ u32 usecnt;
+ struct bfi_ioc_image_hdr_s fwhdr;
+
+ /**
+ * Firmware match check is relevant only for CNA.
+ */
+ if (!ioc->cna)
+ return BFA_TRUE;
+
+ /**
+ * If bios boot (flash based) -- do not increment usage count
+ */
+ if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ return BFA_TRUE;
+
+ bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+
+ /**
+ * If usage count is 0, always return TRUE.
+ */
+ if (usecnt == 0) {
+ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
+ bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ bfa_trc(ioc, usecnt);
+ return BFA_TRUE;
+ }
+
+ ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+ bfa_trc(ioc, ioc_fwstate);
+
+ /**
+ * Use count cannot be non-zero and chip in uninitialized state.
+ */
+ bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
+
+ /**
+ * Check if another driver with a different firmware is active
+ */
+ bfa_ioc_fwver_get(ioc, &fwhdr);
+ if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
+ bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ bfa_trc(ioc, usecnt);
+ return BFA_FALSE;
+ }
+
+ /**
+ * Same firmware version. Increment the reference count.
+ */
+ usecnt++;
+ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+ bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ bfa_trc(ioc, usecnt);
+ return BFA_TRUE;
+}
+
+static void
+bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+ u32 usecnt;
+
+ /**
+ * Firmware lock is relevant only for CNA.
+ * If bios boot (flash based) -- do not decrement usage count
+ */
+ if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ return;
+
+ /**
+ * decrement usage count
+ */
+ bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+ bfa_assert(usecnt > 0);
+
+ usecnt--;
+ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+ bfa_trc(ioc, usecnt);
+
+ bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
+{
+ if (ioc->cna) {
+ bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
+ /* Wait for halt to take effect */
+ bfa_reg_read(ioc->ioc_regs.ll_halt);
+ } else {
+ bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
+ bfa_reg_read(ioc->ioc_regs.err_set);
+ }
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+ { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+ { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
+ { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
+ { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 0
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
+ { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
+ { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
+ { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
+ { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 1
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
+ { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
+ { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
+ { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
+ { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+static void
+bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
+{
+ bfa_os_addr_t rb;
+ int pcifn = bfa_ioc_pcifn(ioc);
+
+ rb = bfa_ioc_bar0(ioc);
+
+ ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+ ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+ ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+ if (ioc->port_id == 0) {
+ ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+ ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
+ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
+ } else {
+ ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+ ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
+ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
+ }
+
+ /*
+ * PSS control registers
+ */
+ ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+ ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+ ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
+ ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
+
+ /*
+ * IOC semaphore registers and serialization
+ */
+ ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+ ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
+ ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+ ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
+
+ /**
+ * sram memory access
+ */
+ ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+ ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
+
+ /*
+ * err set reg : for notification of hb failure in fcmode
+ */
+ ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+
+#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
+static void
+bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
+{
+ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
+ u32 r32;
+
+ /**
+ * For catapult, base port id on personality register and IOC type
+ */
+ r32 = bfa_reg_read(rb + FNC_PERS_REG);
+ r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
+ ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
+
+ bfa_trc(ioc, bfa_ioc_pcifn(ioc));
+ bfa_trc(ioc, ioc->port_id);
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
+ u32 r32, mode;
+
+ r32 = bfa_reg_read(rb + FNC_PERS_REG);
+ bfa_trc(ioc, r32);
+
+ mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
+ __F0_INTX_STATUS;
+
+ /**
+ * If already in desired mode, do not change anything
+ */
+ if (!msix && mode)
+ return;
+
+ if (msix)
+ mode = __F0_INTX_STATUS_MSIX;
+ else
+ mode = __F0_INTX_STATUS_INTA;
+
+ r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+ r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+ bfa_trc(ioc, r32);
+
+ bfa_reg_write(rb + FNC_PERS_REG, r32);
+}
+
+static bfa_status_t
+bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
+{
+ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
+ u32 pll_sclk, pll_fclk, r32;
+
+ /*
+ * Hold semaphore so that nobody can access the chip during init.
+ */
+ bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+ pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
+ __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
+ __APP_PLL_312_JITLMT0_1(3U) |
+ __APP_PLL_312_CNTLMT0_1(1U);
+ pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
+ __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
+ __APP_PLL_425_JITLMT0_1(3U) |
+ __APP_PLL_425_CNTLMT0_1(1U);
+
+ /**
+ * For catapult, choose operational mode FC/FCoE
+ */
+ if (ioc->fcmode) {
+ bfa_reg_write((rb + OP_MODE), 0);
+ bfa_reg_write((rb + ETH_MAC_SER_REG),
+ __APP_EMS_CMLCKSEL |
+ __APP_EMS_REFCKBUFEN2 |
+ __APP_EMS_CHANNEL_SEL);
+ } else {
+ ioc->pllinit = BFA_TRUE;
+ bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
+ bfa_reg_write((rb + ETH_MAC_SER_REG),
+ __APP_EMS_REFCKBUFEN1);
+ }
+
+ bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+ bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+ bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+ __APP_PLL_312_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+ __APP_PLL_425_LOGIC_SOFT_RESET);
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+ __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+ __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE);
+
+ /**
+ * Wait for PLLs to lock.
+ */
+ bfa_reg_read(rb + HOSTFN0_INT_MSK);
+ bfa_os_udelay(2000);
+ bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+ bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+ __APP_PLL_312_ENABLE);
+ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+ __APP_PLL_425_ENABLE);
+
+ bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
+ bfa_os_udelay(1000);
+ r32 = bfa_reg_read((rb + MBIST_STAT_REG));
+ bfa_trc(ioc, r32);
+ /*
+ * release semaphore.
+ */
+ bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+ return BFA_STATUS_OK;
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
+{
+
+ if (ioc->cna) {
+ bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
+ bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ }
+
+ /*
+ * Read the hw sem reg to make sure that it is locked
+ * before we clear it. If it is not locked, writing 1
+ * will lock it instead of clearing it.
+ */
+ bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+ bfa_ioc_hw_sem_release(ioc);
+}
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c
index d7ab792a9e5..a76de2669bf 100644
--- a/drivers/scsi/bfa/bfa_iocfc.c
+++ b/drivers/scsi/bfa/bfa_iocfc.c
@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
*/
if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
iocfc->hwif.hw_reginit = bfa_hwct_reginit;
+ iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
@@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
} else {
iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
+ iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
else
bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
- } else
- bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
+ } else {
+ if (bfa->iocfc.cfgdone)
+ bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
+ }
}
static void
@@ -619,8 +623,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
bfa->trcmod, bfa->aen, bfa->logm);
- bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
- bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
/**
* Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
@@ -628,6 +630,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
if (0)
bfa_ioc_set_fcmode(&bfa->ioc);
+ bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
+ bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
+
bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
bfa_iocfc_mem_claim(bfa, cfg, meminfo);
bfa_timer_init(&bfa->timer_mod);
@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa)
{
bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
bfa_ioc_enable(&bfa->ioc);
- bfa_msix_install(bfa);
}
/**
@@ -797,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats,
return BFA_STATUS_DEVBUSY;
}
+ if (!bfa_iocfc_is_operational(bfa)) {
+ bfa_trc(bfa, 0);
+ return BFA_STATUS_IOC_NON_OP;
+ }
+
iocfc->stats_busy = BFA_TRUE;
iocfc->stats_ret = stats;
iocfc->stats_cbfn = cbfn;
@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg)
return BFA_STATUS_DEVBUSY;
}
+ if (!bfa_iocfc_is_operational(bfa)) {
+ bfa_trc(bfa, 0);
+ return BFA_STATUS_IOC_NON_OP;
+ }
+
iocfc->stats_busy = BFA_TRUE;
iocfc->stats_cbfn = cbfn;
iocfc->stats_cbarg = cbarg;
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
index ce9a830a420..fbb4bdc9d60 100644
--- a/drivers/scsi/bfa/bfa_iocfc.h
+++ b/drivers/scsi/bfa/bfa_iocfc.h
@@ -54,6 +54,7 @@ struct bfa_msix_s {
*/
struct bfa_hwif_s {
void (*hw_reginit)(struct bfa_s *bfa);
+ void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
void (*hw_msix_install)(struct bfa_s *bfa);
@@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
void bfa_hwcb_reginit(struct bfa_s *bfa);
+void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwcb_msix_install(struct bfa_s *bfa);
@@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
u32 *nvecs, u32 *maxvec);
void bfa_hwct_reginit(struct bfa_s *bfa);
+void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
void bfa_hwct_msix_install(struct bfa_s *bfa);
diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c
index f81d359b708..5b107abe46e 100644
--- a/drivers/scsi/bfa/bfa_ioim.c
+++ b/drivers/scsi/bfa/bfa_ioim.c
@@ -149,7 +149,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -194,7 +194,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -259,7 +259,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -317,7 +317,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -377,7 +377,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -419,7 +419,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -467,7 +467,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -516,7 +516,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -544,7 +544,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -577,7 +577,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
@@ -605,7 +605,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ioim->bfa, event);
}
}
diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c
index eabf7d38bd0..a914ff25513 100644
--- a/drivers/scsi/bfa/bfa_itnim.c
+++ b/drivers/scsi/bfa/bfa_itnim.c
@@ -144,7 +144,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -175,7 +175,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -212,7 +212,7 @@ bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -247,7 +247,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -275,7 +275,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -317,7 +317,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -348,7 +348,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -385,7 +385,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -413,7 +413,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -442,7 +442,7 @@ bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -470,7 +470,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -502,7 +502,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -538,7 +538,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -559,7 +559,7 @@ bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
@@ -583,7 +583,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->bfa, event);
}
}
diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c
index 9844b45412b..ad06f618909 100644
--- a/drivers/scsi/bfa/bfa_lps.c
+++ b/drivers/scsi/bfa/bfa_lps.c
@@ -18,6 +18,7 @@
#include <bfa.h>
#include <bfi/bfi_lps.h>
#include <cs/bfa_debug.h>
+#include <defs/bfa_defs_pci.h>
BFA_TRC_FILE(HAL, LPS);
BFA_MODULE(lps);
@@ -25,6 +26,12 @@ BFA_MODULE(lps);
#define BFA_LPS_MIN_LPORTS (1)
#define BFA_LPS_MAX_LPORTS (256)
+/*
+ * Maximum Vports supported per physical port or vf.
+ */
+#define BFA_LPS_MAX_VPORTS_SUPP_CB 255
+#define BFA_LPS_MAX_VPORTS_SUPP_CT 190
+
/**
* forward declarations
*/
@@ -49,7 +56,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps);
static void bfa_lps_send_logout(struct bfa_lps_s *lps);
static void bfa_lps_login_comp(struct bfa_lps_s *lps);
static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
-
+static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
/**
* lps_pvt BFA LPS private functions
@@ -62,6 +69,7 @@ enum bfa_lps_event {
BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */
BFA_LPS_SM_DELETE = 5, /* lps delete from user */
BFA_LPS_SM_OFFLINE = 6, /* Link is offline */
+ BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */
};
static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
@@ -91,6 +99,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_sm_set_state(lps, bfa_lps_sm_login);
bfa_lps_send_login(lps);
}
+ if (lps->fdisc)
+ bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+ BFA_PL_EID_LOGIN, 0, "FDISC Request");
+ else
+ bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+ BFA_PL_EID_LOGIN, 0, "FLOGI Request");
break;
case BFA_LPS_SM_LOGOUT:
@@ -101,6 +115,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_lps_free(lps);
break;
+ case BFA_LPS_SM_RX_CVL:
case BFA_LPS_SM_OFFLINE:
break;
@@ -112,7 +127,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(lps->bfa, event);
}
}
@@ -127,10 +142,25 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
switch (event) {
case BFA_LPS_SM_FWRSP:
- if (lps->status == BFA_STATUS_OK)
+ if (lps->status == BFA_STATUS_OK) {
bfa_sm_set_state(lps, bfa_lps_sm_online);
- else
+ if (lps->fdisc)
+ bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+ BFA_PL_EID_LOGIN, 0, "FDISC Accept");
+ else
+ bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+ BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
+ } else {
bfa_sm_set_state(lps, bfa_lps_sm_init);
+ if (lps->fdisc)
+ bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+ BFA_PL_EID_LOGIN, 0,
+ "FDISC Fail (RJT or timeout)");
+ else
+ bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+ BFA_PL_EID_LOGIN, 0,
+ "FLOGI Fail (RJT or timeout)");
+ }
bfa_lps_login_comp(lps);
break;
@@ -139,7 +169,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(lps->bfa, event);
}
}
@@ -162,8 +192,16 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_reqq_wcancel(&lps->wqe);
break;
+ case BFA_LPS_SM_RX_CVL:
+ /*
+ * Login was not even sent out; so when getting out
+ * of this state, it will appear like a login retry
+ * after Clear virtual link
+ */
+ break;
+
default:
- bfa_assert(0);
+ bfa_sm_fault(lps->bfa, event);
}
}
@@ -185,6 +223,17 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_sm_set_state(lps, bfa_lps_sm_logout);
bfa_lps_send_logout(lps);
}
+ bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+ BFA_PL_EID_LOGO, 0, "Logout");
+ break;
+
+ case BFA_LPS_SM_RX_CVL:
+ bfa_sm_set_state(lps, bfa_lps_sm_init);
+
+ /* Let the vport module know about this event */
+ bfa_lps_cvl_event(lps);
+ bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+ BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
break;
case BFA_LPS_SM_OFFLINE:
@@ -193,7 +242,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(lps->bfa, event);
}
}
@@ -217,7 +266,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(lps->bfa, event);
}
}
@@ -242,7 +291,7 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(lps->bfa, event);
}
}
@@ -396,6 +445,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
}
/**
+ * Firmware received a Clear virtual link request (for FCoE)
+ */
+static void
+bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
+{
+ struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
+ struct bfa_lps_s *lps;
+
+ lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag);
+
+ bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
+}
+
+/**
* Space is available in request queue, resume queueing request to firmware.
*/
static void
@@ -531,7 +594,48 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps)
bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
}
+/**
+ * Clear virtual link completion handler for non-fcs
+ */
+static void
+bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
+{
+ struct bfa_lps_s *lps = arg;
+
+ if (!complete)
+ return;
+
+ /* Clear virtual link to base port will result in link down */
+ if (lps->fdisc)
+ bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
+}
+
+/**
+ * Received Clear virtual link event --direct call for fcs,
+ * queue for others
+ */
+static void
+bfa_lps_cvl_event(struct bfa_lps_s *lps)
+{
+ if (!lps->bfa->fcs) {
+ bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
+ lps);
+ return;
+ }
+
+ /* Clear virtual link to base port will result in link down */
+ if (lps->fdisc)
+ bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
+}
+u32
+bfa_lps_get_max_vport(struct bfa_s *bfa)
+{
+ if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT)
+ return BFA_LPS_MAX_VPORTS_SUPP_CT;
+ else
+ return BFA_LPS_MAX_VPORTS_SUPP_CB;
+}
/**
* lps_public BFA LPS public functions
@@ -752,6 +856,14 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
return lps->lsrjt_expl;
}
+/**
+ * Return fpma/spma MAC for lport
+ */
+struct mac_s
+bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
+{
+ return lps->lp_mac;
+}
/**
* LPS firmware message class handler.
@@ -773,6 +885,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
bfa_lps_logout_rsp(bfa, msg.logout_rsp);
break;
+ case BFI_LPS_H2I_CVL_EVENT:
+ bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
+ break;
+
default:
bfa_trc(bfa, m->mhdr.msg_id);
bfa_assert(0);
diff --git a/drivers/scsi/bfa/bfa_module.c b/drivers/scsi/bfa/bfa_module.c
index 32eda8e1ec6..a7fcc80c177 100644
--- a/drivers/scsi/bfa/bfa_module.c
+++ b/drivers/scsi/bfa/bfa_module.c
@@ -24,7 +24,7 @@
*/
struct bfa_module_s *hal_mods[] = {
&hal_mod_sgpg,
- &hal_mod_pport,
+ &hal_mod_fcport,
&hal_mod_fcxp,
&hal_mod_lps,
&hal_mod_uf,
@@ -45,7 +45,7 @@ bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = {
bfa_isr_unhandled, /* BFI_MC_DIAG */
bfa_isr_unhandled, /* BFI_MC_FLASH */
bfa_isr_unhandled, /* BFI_MC_CEE */
- bfa_pport_isr, /* BFI_MC_PORT */
+ bfa_fcport_isr, /* BFI_MC_FCPORT */
bfa_isr_unhandled, /* BFI_MC_IOCFC */
bfa_isr_unhandled, /* BFI_MC_LL */
bfa_uf_isr, /* BFI_MC_UF */
diff --git a/drivers/scsi/bfa/bfa_modules_priv.h b/drivers/scsi/bfa/bfa_modules_priv.h
index 96f70534593..f554c2fad6a 100644
--- a/drivers/scsi/bfa/bfa_modules_priv.h
+++ b/drivers/scsi/bfa/bfa_modules_priv.h
@@ -29,7 +29,7 @@
struct bfa_modules_s {
- struct bfa_pport_s pport; /* physical port module */
+ struct bfa_fcport_s fcport; /* fc port module */
struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */
struct bfa_lps_mod_s lps_mod; /* fcxp module */
struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h
index 51f698a06b6..40e256ec67f 100644
--- a/drivers/scsi/bfa/bfa_port_priv.h
+++ b/drivers/scsi/bfa/bfa_port_priv.h
@@ -23,9 +23,19 @@
#include "bfa_intr_priv.h"
/**
- * BFA physical port data structure
+ * Link notification data structure
*/
-struct bfa_pport_s {
+struct bfa_fcport_ln_s {
+ struct bfa_fcport_s *fcport;
+ bfa_sm_t sm;
+ struct bfa_cb_qe_s ln_qe; /* BFA callback queue elem for ln */
+ enum bfa_pport_linkstate ln_event; /* ln event for callback */
+};
+
+/**
+ * BFA FC port data structure
+ */
+struct bfa_fcport_s {
struct bfa_s *bfa; /* parent BFA instance */
bfa_sm_t sm; /* port state machine */
wwn_t nwwn; /* node wwn of physical port */
@@ -36,6 +46,8 @@ struct bfa_pport_s {
enum bfa_pport_topology topology; /* current topology */
u8 myalpa; /* my ALPA in LOOP topology */
u8 rsvd[3];
+ u32 mypid:24;
+ u32 rsvd_b:8;
struct bfa_pport_cfg_s cfg; /* current port configuration */
struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
@@ -49,42 +61,31 @@ struct bfa_pport_s {
void (*event_cbfn) (void *cbarg,
bfa_pport_event_t event);
union {
- union bfi_pport_i2h_msg_u i2hmsg;
+ union bfi_fcport_i2h_msg_u i2hmsg;
} event_arg;
void *bfad; /* BFA driver handle */
+ struct bfa_fcport_ln_s ln; /* Link Notification */
struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */
- enum bfa_pport_linkstate hcb_event;
- /* link event for callback */
+ struct bfa_timer_s timer; /* timer */
u32 msgtag; /* fimrware msg tag for reply */
u8 *stats_kva;
u64 stats_pa;
- union bfa_pport_stats_u *stats; /* pport stats */
- u32 mypid:24;
- u32 rsvd_b:8;
- struct bfa_timer_s timer; /* timer */
- union bfa_pport_stats_u *stats_ret;
- /* driver stats location */
- bfa_status_t stats_status;
- /* stats/statsclr status */
- bfa_boolean_t stats_busy;
- /* outstanding stats/statsclr */
- bfa_boolean_t stats_qfull;
- bfa_boolean_t diag_busy;
- /* diag busy status */
- bfa_boolean_t beacon;
- /* port beacon status */
- bfa_boolean_t link_e2e_beacon;
- /* link beacon status */
- bfa_cb_pport_t stats_cbfn;
- /* driver callback function */
- void *stats_cbarg;
- /* *!< user callback arg */
+ union bfa_fcport_stats_u *stats;
+ union bfa_fcport_stats_u *stats_ret; /* driver stats location */
+ bfa_status_t stats_status; /* stats/statsclr status */
+ bfa_boolean_t stats_busy; /* outstanding stats/statsclr */
+ bfa_boolean_t stats_qfull;
+ bfa_cb_pport_t stats_cbfn; /* driver callback function */
+ void *stats_cbarg; /* *!< user callback arg */
+ bfa_boolean_t diag_busy; /* diag busy status */
+ bfa_boolean_t beacon; /* port beacon status */
+ bfa_boolean_t link_e2e_beacon; /* link beacon status */
};
-#define BFA_PORT_MOD(__bfa) (&(__bfa)->modules.pport)
+#define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport)
/*
* public functions
*/
-void bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
+void bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
#endif /* __BFA_PORT_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_priv.h b/drivers/scsi/bfa/bfa_priv.h
index 0747a6b26f7..be80fc7e1b0 100644
--- a/drivers/scsi/bfa/bfa_priv.h
+++ b/drivers/scsi/bfa/bfa_priv.h
@@ -101,7 +101,7 @@ extern bfa_boolean_t bfa_auto_recover;
extern struct bfa_module_s hal_mod_flash;
extern struct bfa_module_s hal_mod_fcdiag;
extern struct bfa_module_s hal_mod_sgpg;
-extern struct bfa_module_s hal_mod_pport;
+extern struct bfa_module_s hal_mod_fcport;
extern struct bfa_module_s hal_mod_fcxp;
extern struct bfa_module_s hal_mod_lps;
extern struct bfa_module_s hal_mod_uf;
diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c
index 3e1990a7425..7c509fa244e 100644
--- a/drivers/scsi/bfa/bfa_rport.c
+++ b/drivers/scsi/bfa/bfa_rport.c
@@ -114,7 +114,7 @@ bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_un_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -146,7 +146,7 @@ bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_cr_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -183,7 +183,7 @@ bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_fwc_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -224,7 +224,7 @@ bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_fwc_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -296,7 +296,7 @@ bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_on_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -329,7 +329,7 @@ bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_fwd_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -359,7 +359,7 @@ bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_fwd_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -394,7 +394,7 @@ bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_off_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -421,7 +421,7 @@ bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -446,7 +446,7 @@ bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -477,7 +477,7 @@ bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
default:
bfa_stats(rp, sm_delp_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -512,7 +512,7 @@ bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
default:
bfa_stats(rp, sm_offp_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
@@ -550,7 +550,7 @@ bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
default:
bfa_stats(rp, sm_iocd_unexp);
- bfa_assert(0);
+ bfa_sm_fault(rp->bfa, event);
}
}
diff --git a/drivers/scsi/bfa/bfa_trcmod_priv.h b/drivers/scsi/bfa/bfa_trcmod_priv.h
index b3562dce7e9..a7a82610db8 100644
--- a/drivers/scsi/bfa/bfa_trcmod_priv.h
+++ b/drivers/scsi/bfa/bfa_trcmod_priv.h
@@ -29,38 +29,36 @@
* !!! needed between trace utility and driver version
*/
enum {
- BFA_TRC_HAL_IOC = 1,
- BFA_TRC_HAL_INTR = 2,
- BFA_TRC_HAL_FCXP = 3,
- BFA_TRC_HAL_UF = 4,
- BFA_TRC_HAL_DIAG = 5,
- BFA_TRC_HAL_RPORT = 6,
- BFA_TRC_HAL_FCPIM = 7,
- BFA_TRC_HAL_IOIM = 8,
- BFA_TRC_HAL_TSKIM = 9,
- BFA_TRC_HAL_ITNIM = 10,
- BFA_TRC_HAL_PPORT = 11,
- BFA_TRC_HAL_SGPG = 12,
- BFA_TRC_HAL_FLASH = 13,
- BFA_TRC_HAL_DEBUG = 14,
- BFA_TRC_HAL_WWN = 15,
- BFA_TRC_HAL_FLASH_RAW = 16,
- BFA_TRC_HAL_SBOOT = 17,
- BFA_TRC_HAL_SBOOT_IO = 18,
- BFA_TRC_HAL_SBOOT_INTR = 19,
- BFA_TRC_HAL_SBTEST = 20,
- BFA_TRC_HAL_IPFC = 21,
- BFA_TRC_HAL_IOCFC = 22,
- BFA_TRC_HAL_FCPTM = 23,
- BFA_TRC_HAL_IOTM = 24,
- BFA_TRC_HAL_TSKTM = 25,
- BFA_TRC_HAL_TIN = 26,
- BFA_TRC_HAL_LPS = 27,
- BFA_TRC_HAL_FCDIAG = 28,
- BFA_TRC_HAL_PBIND = 29,
- BFA_TRC_HAL_IOCFC_CT = 30,
- BFA_TRC_HAL_IOCFC_CB = 31,
- BFA_TRC_HAL_IOCFC_Q = 32,
+ BFA_TRC_HAL_INTR = 1,
+ BFA_TRC_HAL_FCXP = 2,
+ BFA_TRC_HAL_UF = 3,
+ BFA_TRC_HAL_RPORT = 4,
+ BFA_TRC_HAL_FCPIM = 5,
+ BFA_TRC_HAL_IOIM = 6,
+ BFA_TRC_HAL_TSKIM = 7,
+ BFA_TRC_HAL_ITNIM = 8,
+ BFA_TRC_HAL_FCPORT = 9,
+ BFA_TRC_HAL_SGPG = 10,
+ BFA_TRC_HAL_FLASH = 11,
+ BFA_TRC_HAL_DEBUG = 12,
+ BFA_TRC_HAL_WWN = 13,
+ BFA_TRC_HAL_FLASH_RAW = 14,
+ BFA_TRC_HAL_SBOOT = 15,
+ BFA_TRC_HAL_SBOOT_IO = 16,
+ BFA_TRC_HAL_SBOOT_INTR = 17,
+ BFA_TRC_HAL_SBTEST = 18,
+ BFA_TRC_HAL_IPFC = 19,
+ BFA_TRC_HAL_IOCFC = 20,
+ BFA_TRC_HAL_FCPTM = 21,
+ BFA_TRC_HAL_IOTM = 22,
+ BFA_TRC_HAL_TSKTM = 23,
+ BFA_TRC_HAL_TIN = 24,
+ BFA_TRC_HAL_LPS = 25,
+ BFA_TRC_HAL_FCDIAG = 26,
+ BFA_TRC_HAL_PBIND = 27,
+ BFA_TRC_HAL_IOCFC_CT = 28,
+ BFA_TRC_HAL_IOCFC_CB = 29,
+ BFA_TRC_HAL_IOCFC_Q = 30,
};
#endif /* __BFA_TRCMOD_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_tskim.c b/drivers/scsi/bfa/bfa_tskim.c
index ff7a4dc0bf3..ad9aaaedd3f 100644
--- a/drivers/scsi/bfa/bfa_tskim.c
+++ b/drivers/scsi/bfa/bfa_tskim.c
@@ -110,7 +110,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(tskim->bfa, event);
}
}
@@ -146,7 +146,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(tskim->bfa, event);
}
}
@@ -178,7 +178,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(tskim->bfa, event);
}
}
@@ -207,7 +207,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(tskim->bfa, event);
}
}
@@ -242,7 +242,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(tskim->bfa, event);
}
}
@@ -277,7 +277,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(tskim->bfa, event);
}
}
@@ -303,7 +303,7 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(tskim->bfa, event);
}
}
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index b52b773d49d..13f5feb308c 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -19,7 +19,9 @@
* bfad.c Linux driver PCI interface module.
*/
+#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/kthread.h>
#include "bfad_drv.h"
#include "bfad_im.h"
#include "bfad_tm.h"
@@ -53,6 +55,7 @@ static int log_level = BFA_LOG_WARNING;
static int ioc_auto_recover = BFA_TRUE;
static int ipfc_enable = BFA_FALSE;
static int ipfc_mtu = -1;
+static int fdmi_enable = BFA_TRUE;
int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
int bfa_linkup_delay = -1;
@@ -74,6 +77,7 @@ module_param(log_level, int, S_IRUGO | S_IWUSR);
module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
+module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
/*
@@ -95,6 +99,8 @@ bfad_fc4_probe(struct bfad_s *bfad)
if (ipfc_enable)
bfad_ipfc_probe(bfad);
+
+ bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
ext:
return rc;
}
@@ -106,6 +112,7 @@ bfad_fc4_probe_undo(struct bfad_s *bfad)
bfad_tm_probe_undo(bfad);
if (ipfc_enable)
bfad_ipfc_probe_undo(bfad);
+ bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
}
static void
@@ -173,9 +180,19 @@ bfa_cb_init(void *drv, bfa_status_t init_status)
{
struct bfad_s *bfad = drv;
- if (init_status == BFA_STATUS_OK)
+ if (init_status == BFA_STATUS_OK) {
bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
+ /* If BFAD_HAL_INIT_FAIL flag is set:
+ * Wake up the kernel thread to start
+ * the bfad operations after HAL init done
+ */
+ if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
+ bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
+ wake_up_process(bfad->bfad_tsk);
+ }
+ }
+
complete(&bfad->comp);
}
@@ -648,7 +665,7 @@ bfad_fcs_port_cfg(struct bfad_s *bfad)
sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
- bfa_pport_get_attr(&bfad->bfa, &attr);
+ bfa_fcport_get_attr(&bfad->bfa, &attr);
port_cfg.nwwn = attr.nwwn;
port_cfg.pwwn = attr.pwwn;
@@ -661,7 +678,6 @@ bfad_drv_init(struct bfad_s *bfad)
bfa_status_t rc;
unsigned long flags;
struct bfa_fcs_driver_info_s driver_info;
- int i;
bfad->cfg_data.rport_del_timeout = rport_del_timeout;
bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
@@ -681,12 +697,7 @@ bfad_drv_init(struct bfad_s *bfad)
bfa_init_log(&bfad->bfa, bfad->logmod);
bfa_init_trc(&bfad->bfa, bfad->trcmod);
bfa_init_aen(&bfad->bfa, bfad->aen);
- INIT_LIST_HEAD(&bfad->file_q);
- INIT_LIST_HEAD(&bfad->file_free_q);
- for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
- bfa_q_qe_init(&bfad->file_buf[i].qe);
- list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
- }
+ memset(bfad->file_map, 0, sizeof(bfad->file_map));
bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
bfa_plog_init(&bfad->plog_buf);
bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
@@ -746,8 +757,16 @@ bfad_drv_init(struct bfad_s *bfad)
bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
- bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
+ bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
+
+ /* Do FCS init only when HAL init is done */
+ if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
+ bfa_fcs_init(&bfad->bfa_fcs);
+ bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
+ }
+
bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
+ bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
@@ -763,12 +782,21 @@ out_hal_mem_alloc_failure:
void
bfad_drv_uninit(struct bfad_s *bfad)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ init_completion(&bfad->comp);
+ bfa_stop(&bfad->bfa);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ wait_for_completion(&bfad->comp);
+
del_timer_sync(&bfad->hal_tmo);
bfa_isr_disable(&bfad->bfa);
bfa_detach(&bfad->bfa);
bfad_remove_intr(bfad);
- bfa_assert(list_empty(&bfad->file_q));
bfad_hal_mem_release(bfad);
+
+ bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
}
void
@@ -859,6 +887,86 @@ bfad_drv_log_level_set(struct bfad_s *bfad)
bfa_log_set_level_all(&bfad->log_data, log_level);
}
+bfa_status_t
+bfad_start_ops(struct bfad_s *bfad)
+{
+ int retval;
+
+ /* PPORT FCS config */
+ bfad_fcs_port_cfg(bfad);
+
+ retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
+ if (retval != BFA_STATUS_OK)
+ goto out_cfg_pport_failure;
+
+ /* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
+ retval = bfad_fc4_probe(bfad);
+ if (retval != BFA_STATUS_OK) {
+ printk(KERN_WARNING "bfad_fc4_probe failed\n");
+ goto out_fc4_probe_failure;
+ }
+
+ bfad_drv_start(bfad);
+
+ /*
+ * If bfa_linkup_delay is set to -1 default; try to retrive the
+ * value using the bfad_os_get_linkup_delay(); else use the
+ * passed in module param value as the bfa_linkup_delay.
+ */
+ if (bfa_linkup_delay < 0) {
+
+ bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
+ bfad_os_rport_online_wait(bfad);
+ bfa_linkup_delay = -1;
+
+ } else {
+ bfad_os_rport_online_wait(bfad);
+ }
+
+ bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
+
+ return BFA_STATUS_OK;
+
+out_fc4_probe_failure:
+ bfad_fc4_probe_undo(bfad);
+ bfad_uncfg_pport(bfad);
+out_cfg_pport_failure:
+ return BFA_STATUS_FAILED;
+}
+
+int
+bfad_worker (void *ptr)
+{
+ struct bfad_s *bfad;
+ unsigned long flags;
+
+ bfad = (struct bfad_s *)ptr;
+
+ while (!kthread_should_stop()) {
+
+ /* Check if the FCS init is done from bfad_drv_init;
+ * if not done do FCS init and set the flag.
+ */
+ if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ bfa_fcs_init(&bfad->bfa_fcs);
+ bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ }
+
+ /* Start the bfad operations after HAL init done */
+ bfad_start_ops(bfad);
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ bfad->bfad_tsk = NULL;
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ break;
+ }
+
+ return 0;
+}
+
/*
* PCI_entry PCI driver entries * {
*/
@@ -871,7 +979,6 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
{
struct bfad_s *bfad;
int error = -ENODEV, retval;
- char buf[16];
/*
* For single port cards - only claim function 0
@@ -902,8 +1009,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
bfa_trc(bfad, bfad_inst);
bfad->logmod = &bfad->log_data;
- sprintf(buf, "%d", bfad_inst);
- bfa_log_init(bfad->logmod, buf, bfa_os_printf);
+ bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf);
bfad_drv_log_level_set(bfad);
@@ -933,57 +1039,39 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
bfad->ref_count = 0;
bfad->pport.bfad = bfad;
+ bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
+ "bfad_worker");
+ if (IS_ERR(bfad->bfad_tsk)) {
+ printk(KERN_INFO "bfad[%d]: Kernel thread"
+ " creation failed!\n",
+ bfad->inst_no);
+ goto out_kthread_create_failure;
+ }
+
retval = bfad_drv_init(bfad);
if (retval != BFA_STATUS_OK)
goto out_drv_init_failure;
if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
+ bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
goto ok;
}
- /*
- * PPORT FCS config
- */
- bfad_fcs_port_cfg(bfad);
-
- retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
+ retval = bfad_start_ops(bfad);
if (retval != BFA_STATUS_OK)
- goto out_cfg_pport_failure;
-
- /*
- * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
- */
- retval = bfad_fc4_probe(bfad);
- if (retval != BFA_STATUS_OK) {
- printk(KERN_WARNING "bfad_fc4_probe failed\n");
- goto out_fc4_probe_failure;
- }
+ goto out_start_ops_failure;
- bfad_drv_start(bfad);
-
- /*
- * If bfa_linkup_delay is set to -1 default; try to retrive the
- * value using the bfad_os_get_linkup_delay(); else use the
- * passed in module param value as the bfa_linkup_delay.
- */
- if (bfa_linkup_delay < 0) {
- bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
- bfad_os_rport_online_wait(bfad);
- bfa_linkup_delay = -1;
- } else {
- bfad_os_rport_online_wait(bfad);
- }
+ kthread_stop(bfad->bfad_tsk);
+ bfad->bfad_tsk = NULL;
- bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
ok:
return 0;
-out_fc4_probe_failure:
- bfad_fc4_probe_undo(bfad);
- bfad_uncfg_pport(bfad);
-out_cfg_pport_failure:
+out_start_ops_failure:
bfad_drv_uninit(bfad);
out_drv_init_failure:
+ kthread_stop(bfad->bfad_tsk);
+out_kthread_create_failure:
mutex_lock(&bfad_mutex);
bfad_inst--;
list_del(&bfad->list_entry);
@@ -1008,6 +1096,11 @@ bfad_pci_remove(struct pci_dev *pdev)
bfa_trc(bfad, bfad->inst_no);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ if (bfad->bfad_tsk != NULL)
+ kthread_stop(bfad->bfad_tsk);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
&& !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
@@ -1024,13 +1117,25 @@ bfad_pci_remove(struct pci_dev *pdev)
goto remove_sysfs;
}
- if (bfad->bfad_flags & BFAD_HAL_START_DONE)
+ if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
bfad_drv_stop(bfad);
+ } else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
+ /* Invoking bfa_stop() before bfa_detach
+ * when HAL and DRV init are success
+ * but HAL start did not occur.
+ */
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ init_completion(&bfad->comp);
+ bfa_stop(&bfad->bfa);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ wait_for_completion(&bfad->comp);
+ }
bfad_remove_intr(bfad);
-
del_timer_sync(&bfad->hal_tmo);
- bfad_fc4_probe_undo(bfad);
+
+ if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
+ bfad_fc4_probe_undo(bfad);
if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
bfad_uncfg_pport(bfad);
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index 9129ae3040f..6a2efdd5ef2 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -19,6 +19,7 @@
* bfa_attr.c Linux driver configuration interface module.
*/
+#include <linux/slab.h>
#include "bfad_drv.h"
#include "bfad_im.h"
#include "bfad_trcmod.h"
@@ -141,7 +142,7 @@ bfad_im_get_host_port_type(struct Scsi_Host *shost)
struct bfad_s *bfad = im_port->bfad;
struct bfa_pport_attr_s attr;
- bfa_pport_get_attr(&bfad->bfa, &attr);
+ bfa_fcport_get_attr(&bfad->bfa, &attr);
switch (attr.port_type) {
case BFA_PPORT_TYPE_NPORT:
@@ -173,7 +174,7 @@ bfad_im_get_host_port_state(struct Scsi_Host *shost)
struct bfad_s *bfad = im_port->bfad;
struct bfa_pport_attr_s attr;
- bfa_pport_get_attr(&bfad->bfa, &attr);
+ bfa_fcport_get_attr(&bfad->bfa, &attr);
switch (attr.port_state) {
case BFA_PPORT_ST_LINKDOWN:
@@ -229,8 +230,10 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
struct bfa_pport_attr_s attr;
+ unsigned long flags;
- bfa_pport_get_attr(&bfad->bfa, &attr);
+ spin_lock_irqsave(shost->host_lock, flags);
+ bfa_fcport_get_attr(&bfad->bfa, &attr);
switch (attr.speed) {
case BFA_PPORT_SPEED_8GBPS:
fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
@@ -248,6 +251,7 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break;
}
+ spin_unlock_irqrestore(shost->host_lock, flags);
}
/**
@@ -285,7 +289,7 @@ bfad_im_get_stats(struct Scsi_Host *shost)
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
memset(hstats, 0, sizeof(struct fc_host_statistics));
- rc = bfa_pport_get_stats(&bfad->bfa,
+ rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa),
(union bfa_pport_stats_u *) hstats,
bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -312,7 +316,8 @@ bfad_im_reset_stats(struct Scsi_Host *shost)
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
- rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp);
+ rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp,
+ &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (rc != BFA_STATUS_OK)
@@ -421,12 +426,10 @@ bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
- struct bfa_ioc_attr_s ioc_attr;
+ char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- ioc_attr.adapter_attr.serial_num);
+ bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
+ return snprintf(buf, PAGE_SIZE, "%s\n", serial_num);
}
static ssize_t
@@ -437,11 +440,10 @@ bfad_im_model_show(struct device *dev, struct device_attribute *attr,
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
- struct bfa_ioc_attr_s ioc_attr;
+ char model[BFA_ADAPTER_MODEL_NAME_LEN];
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
- return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model);
+ bfa_get_adapter_model(&bfad->bfa, model);
+ return snprintf(buf, PAGE_SIZE, "%s\n", model);
}
static ssize_t
@@ -452,12 +454,10 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
- struct bfa_ioc_attr_s ioc_attr;
+ char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- ioc_attr.adapter_attr.model_descr);
+ bfa_get_adapter_model(&bfad->bfa, model_descr);
+ return snprintf(buf, PAGE_SIZE, "%s\n", model_descr);
}
static ssize_t
@@ -482,14 +482,13 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
- struct bfa_ioc_attr_s ioc_attr;
-
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
+ char model[BFA_ADAPTER_MODEL_NAME_LEN];
+ char fw_ver[BFA_VERSION_LEN];
+ bfa_get_adapter_model(&bfad->bfa, model);
+ bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n",
- ioc_attr.adapter_attr.model,
- ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
+ model, fw_ver, BFAD_DRIVER_VERSION);
}
static ssize_t
@@ -500,11 +499,10 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
- struct bfa_ioc_attr_s ioc_attr;
+ char hw_ver[BFA_VERSION_LEN];
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
- return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver);
+ bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
+ return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver);
}
static ssize_t
@@ -522,12 +520,10 @@ bfad_im_optionrom_version_show(struct device *dev,
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
- struct bfa_ioc_attr_s ioc_attr;
+ char optrom_ver[BFA_VERSION_LEN];
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- ioc_attr.adapter_attr.optrom_ver);
+ bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
+ return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver);
}
static ssize_t
@@ -538,11 +534,10 @@ bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
- struct bfa_ioc_attr_s ioc_attr;
+ char fw_ver[BFA_VERSION_LEN];
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
- return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver);
+ bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
+ return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver);
}
static ssize_t
@@ -553,11 +548,9 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
- struct bfa_ioc_attr_s ioc_attr;
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
- return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports);
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ bfa_get_nports(&bfad->bfa));
}
static ssize_t
diff --git a/drivers/scsi/bfa/bfad_attr.h b/drivers/scsi/bfa/bfad_attr.h
index 4d3312da6a8..bf010207650 100644
--- a/drivers/scsi/bfa/bfad_attr.h
+++ b/drivers/scsi/bfa/bfad_attr.h
@@ -17,9 +17,6 @@
#ifndef __BFAD_ATTR_H__
#define __BFAD_ATTR_H__
-/**
- * bfad_attr.h VMware driver configuration interface module.
- */
/**
* FC_transport_template FC transport template
@@ -52,12 +49,6 @@ bfad_im_get_starget_port_name(struct scsi_target *starget);
void
bfad_im_get_host_port_id(struct Scsi_Host *shost);
-/**
- * FC transport template entry, issue a LIP.
- */
-int
-bfad_im_issue_fc_host_lip(struct Scsi_Host *shost);
-
struct Scsi_Host*
bfad_os_starget_to_shost(struct scsi_target *starget);
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
index 172c81e25c1..107848cd3b6 100644
--- a/drivers/scsi/bfa/bfad_drv.h
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -46,7 +46,7 @@
#ifdef BFA_DRIVER_VERSION
#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION
#else
-#define BFAD_DRIVER_VERSION "2.0.0.0"
+#define BFAD_DRIVER_VERSION "2.1.2.1"
#endif
@@ -62,7 +62,9 @@
#define BFAD_HAL_START_DONE 0x00000010
#define BFAD_PORT_ONLINE 0x00000020
#define BFAD_RPORT_ONLINE 0x00000040
-
+#define BFAD_FCS_INIT_DONE 0x00000080
+#define BFAD_HAL_INIT_FAIL 0x00000100
+#define BFAD_FC4_PROBE_DONE 0x00000200
#define BFAD_PORT_DELETE 0x00000001
/*
@@ -137,12 +139,16 @@ struct bfad_cfg_param_s {
u32 binding_method;
};
-#define BFAD_AEN_MAX_APPS 8
-struct bfad_aen_file_s {
- struct list_head qe;
- struct bfad_s *bfad;
- s32 ri;
- s32 app_id;
+union bfad_tmp_buf {
+ /* From struct bfa_adapter_attr_s */
+ char manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
+ char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
+ char model[BFA_ADAPTER_MODEL_NAME_LEN];
+ char fw_ver[BFA_VERSION_LEN];
+ char optrom_ver[BFA_VERSION_LEN];
+
+ /* From struct bfa_ioc_pci_attr_s */
+ u8 chip_rev[BFA_IOC_CHIP_REV_LEN]; /* chip revision */
};
/*
@@ -168,6 +174,7 @@ struct bfad_s {
u32 inst_no; /* BFAD instance number */
u32 bfad_flags;
spinlock_t bfad_lock;
+ struct task_struct *bfad_tsk;
struct bfad_cfg_param_s cfg_data;
struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY];
int nvec;
@@ -183,18 +190,12 @@ struct bfad_s {
struct bfa_log_mod_s *logmod;
struct bfa_aen_s *aen;
struct bfa_aen_s aen_buf;
- struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS];
- struct list_head file_q;
- struct list_head file_free_q;
+ void *file_map[BFA_AEN_MAX_APP];
struct bfa_plog_s plog_buf;
int ref_count;
bfa_boolean_t ipfc_enabled;
+ union bfad_tmp_buf tmp_buf;
struct fc_host_statistics link_stats;
-
- struct kobject *bfa_kobj;
- struct kobject *ioc_kobj;
- struct kobject *pport_kobj;
- struct kobject *lport_kobj;
};
/*
@@ -258,6 +259,7 @@ bfa_status_t bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
struct bfa_port_cfg_s *port_cfg);
bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role);
bfa_status_t bfad_drv_init(struct bfad_s *bfad);
+bfa_status_t bfad_start_ops(struct bfad_s *bfad);
void bfad_drv_start(struct bfad_s *bfad);
void bfad_uncfg_pport(struct bfad_s *bfad);
void bfad_drv_stop(struct bfad_s *bfad);
@@ -279,6 +281,7 @@ void bfad_drv_uninit(struct bfad_s *bfad);
void bfad_drv_log_level_set(struct bfad_s *bfad);
bfa_status_t bfad_fc4_module_init(void);
void bfad_fc4_module_exit(void);
+int bfad_worker (void *ptr);
void bfad_pci_remove(struct pci_dev *pdev);
int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index f788c2a0ab0..78f42aa5736 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -19,6 +19,7 @@
* bfad_im.c Linux driver IM module.
*/
+#include <linux/slab.h>
#include "bfad_drv.h"
#include "bfad_im.h"
#include "bfad_trcmod.h"
@@ -43,11 +44,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
struct bfad_s *bfad = drv;
struct bfad_itnim_data_s *itnim_data;
struct bfad_itnim_s *itnim;
+ u8 host_status = DID_OK;
switch (io_status) {
case BFI_IOIM_STS_OK:
bfa_trc(bfad, scsi_status);
- cmnd->result = ScsiResult(DID_OK, scsi_status);
scsi_set_resid(cmnd, 0);
if (sns_len > 0) {
@@ -56,8 +57,18 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
sns_len = SCSI_SENSE_BUFFERSIZE;
memcpy(cmnd->sense_buffer, sns_info, sns_len);
}
- if (residue > 0)
+ if (residue > 0) {
+ bfa_trc(bfad, residue);
scsi_set_resid(cmnd, residue);
+ if (!sns_len && (scsi_status == SAM_STAT_GOOD) &&
+ (scsi_bufflen(cmnd) - residue) <
+ cmnd->underflow) {
+ bfa_trc(bfad, 0);
+ host_status = DID_ERROR;
+ }
+ }
+ cmnd->result = ScsiResult(host_status, scsi_status);
+
break;
case BFI_IOIM_STS_ABORTED:
@@ -167,17 +178,15 @@ bfad_im_info(struct Scsi_Host *shost)
static char bfa_buf[256];
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) shost->hostdata[0];
- struct bfa_ioc_attr_s ioc_attr;
struct bfad_s *bfad = im_port->bfad;
+ char model[BFA_ADAPTER_MODEL_NAME_LEN];
- memset(&ioc_attr, 0, sizeof(ioc_attr));
- bfa_get_attr(&bfad->bfa, &ioc_attr);
+ bfa_get_adapter_model(&bfad->bfa, model);
memset(bfa_buf, 0, sizeof(bfa_buf));
snprintf(bfa_buf, sizeof(bfa_buf),
- "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
- ioc_attr.adapter_attr.model, bfad->pci_name,
- BFAD_DRIVER_VERSION);
+ "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
+ model, bfad->pci_name, BFAD_DRIVER_VERSION);
return bfa_buf;
}
@@ -501,16 +510,6 @@ void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim)
}
/**
- * Path TOV processing begin notification -- dummy for linux
- */
-void
-bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim)
-{
-}
-
-
-
-/**
* Allocate a Scsi_Host for a port.
*/
int
@@ -931,10 +930,9 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
struct Scsi_Host *host = im_port->shost;
struct bfad_s *bfad = im_port->bfad;
struct bfad_port_s *port = im_port->port;
- union attr {
- struct bfa_pport_attr_s pattr;
- struct bfa_ioc_attr_s ioc_attr;
- } attr;
+ struct bfa_pport_attr_s pattr;
+ char model[BFA_ADAPTER_MODEL_NAME_LEN];
+ char fw_ver[BFA_VERSION_LEN];
fc_host_node_name(host) =
bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port)));
@@ -954,20 +952,18 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
/* For fibre channel services type 0x20 */
fc_host_supported_fc4s(host)[7] = 1;
- memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr));
- bfa_get_attr(&bfad->bfa, &attr.ioc_attr);
+ bfa_get_adapter_model(&bfad->bfa, model);
+ bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s",
- attr.ioc_attr.adapter_attr.model,
- attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
+ model, fw_ver, BFAD_DRIVER_VERSION);
fc_host_supported_speeds(host) = 0;
fc_host_supported_speeds(host) |=
FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
FC_PORTSPEED_1GBIT;
- memset(&attr.pattr, 0, sizeof(attr.pattr));
- bfa_pport_get_attr(&bfad->bfa, &attr.pattr);
- fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize;
+ bfa_fcport_get_attr(&bfad->bfa, &pattr);
+ fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize;
}
static void
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index 189a5b29e21..85ab2da2132 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -23,7 +23,6 @@
#define FCPI_NAME " fcpim"
-void bfad_flags_set(struct bfad_s *bfad, u32 flags);
bfa_status_t bfad_im_module_init(void);
void bfad_im_module_exit(void);
bfa_status_t bfad_im_probe(struct bfad_s *bfad);
@@ -126,7 +125,6 @@ bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad);
void bfad_os_destroy_workq(struct bfad_im_s *im);
void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv);
void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
-void bfad_os_init_work(struct bfad_im_port_s *im_port);
void bfad_os_scsi_host_free(struct bfad_s *bfad,
struct bfad_im_port_s *im_port);
void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim,
@@ -136,9 +134,6 @@ struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id);
int bfad_os_scsi_add_host(struct Scsi_Host *shost,
struct bfad_im_port_s *im_port, struct bfad_s *bfad);
-/*
- * scsi_host_template entries
- */
void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port,
struct bfad_itnim_s *itnim);
diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c
index 7de8832f6fe..2b7dbecbebc 100644
--- a/drivers/scsi/bfa/bfad_intr.c
+++ b/drivers/scsi/bfa/bfad_intr.c
@@ -23,8 +23,10 @@ BFA_TRC_FILE(LDRV, INTR);
/**
* bfa_isr BFA driver interrupt functions
*/
-static int msix_disable;
-module_param(msix_disable, int, S_IRUGO | S_IWUSR);
+static int msix_disable_cb;
+static int msix_disable_ct;
+module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR);
+module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR);
/**
* Line based interrupt handler.
*/
@@ -141,6 +143,7 @@ bfad_setup_intr(struct bfad_s *bfad)
int error = 0;
u32 mask = 0, i, num_bit = 0, max_bit = 0;
struct msix_entry msix_entries[MAX_MSIX_ENTRY];
+ struct pci_dev *pdev = bfad->pcidev;
/* Call BFA to get the msix map for this PCI function. */
bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit);
@@ -148,7 +151,9 @@ bfad_setup_intr(struct bfad_s *bfad)
/* Set up the msix entry table */
bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
- if (!msix_disable) {
+ if ((pdev->device == BFA_PCI_DEVICE_ID_CT && !msix_disable_ct) ||
+ (pdev->device != BFA_PCI_DEVICE_ID_CT && !msix_disable_cb)) {
+
error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
if (error) {
/*
diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c
index a4b5dd44957..8166e9745ec 100644
--- a/drivers/scsi/bfa/fabric.c
+++ b/drivers/scsi/bfa/fabric.c
@@ -37,7 +37,7 @@ BFA_TRC_FILE(FCS, FABRIC);
#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
#define bfa_fcs_fabric_set_opertype(__fabric) do { \
- if (bfa_pport_get_topology((__fabric)->fcs->bfa) \
+ if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \
== BFA_PPORT_TOPOLOGY_P2P) \
(__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \
else \
@@ -136,8 +136,7 @@ bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
case BFA_FCS_FABRIC_SM_CREATE:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
bfa_fcs_fabric_init(fabric);
- bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL,
- &fabric->bport.port_cfg, NULL);
+ bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
break;
case BFA_FCS_FABRIC_SM_LINK_UP:
@@ -161,7 +160,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
switch (event) {
case BFA_FCS_FABRIC_SM_START:
- if (bfa_pport_is_linkup(fabric->fcs->bfa)) {
+ if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
bfa_fcs_fabric_login(fabric);
} else
@@ -225,7 +224,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
switch (event) {
case BFA_FCS_FABRIC_SM_CONT_OP:
- bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+ bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
if (fabric->auth_reqd && fabric->is_auth) {
@@ -252,7 +251,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
case BFA_FCS_FABRIC_SM_NO_FABRIC:
fabric->fab_type = BFA_FCS_FABRIC_N2N;
- bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+ bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
bfa_fcs_fabric_notify_online(fabric);
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
break;
@@ -419,7 +418,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
case BFA_FCS_FABRIC_SM_NO_FABRIC:
bfa_trc(fabric->fcs, fabric->bb_credit);
- bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+ bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
break;
default:
@@ -563,17 +562,15 @@ void
bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
{
struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
- struct bfa_adapter_attr_s adapter_attr;
+ char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
- bfa_os_memset((void *)&adapter_attr, 0,
- sizeof(struct bfa_adapter_attr_s));
- bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr);
+ bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
/*
* Model name/number
*/
- strncpy((char *)&port_cfg->sym_name, adapter_attr.model,
+ strncpy((char *)&port_cfg->sym_name, model,
BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
@@ -719,10 +716,10 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
u8 alpa = 0;
- if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
- alpa = bfa_pport_get_myalpa(bfa);
+ if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
+ alpa = bfa_fcport_get_myalpa(bfa);
- bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa),
+ bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
fabric->stats.flogi_sent++;
@@ -814,10 +811,10 @@ bfa_fcs_fabric_delete_comp(void *cbarg)
*/
/**
- * Module initialization
+ * Attach time initialization
*/
void
-bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
{
struct bfa_fcs_fabric_s *fabric;
@@ -841,7 +838,13 @@ bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
bfa_wc_up(&fabric->wc); /* For the base port */
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
- bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE);
+ bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
+}
+
+void
+bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
+{
+ bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
bfa_trc(fcs, 0);
}
@@ -890,6 +893,12 @@ bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
}
+bfa_boolean_t
+bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric)
+{
+ return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed);
+}
+
enum bfa_pport_type
bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
{
@@ -1165,8 +1174,8 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
bfa_os_hton3b(FC_FABRIC_PORT),
n2n_port->reply_oxid, pcfg->pwwn,
- pcfg->nwwn, bfa_pport_get_maxfrsize(bfa),
- bfa_pport_get_rx_bbcredit(bfa));
+ pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa),
+ bfa_fcport_get_rx_bbcredit(bfa));
bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
@@ -1224,14 +1233,8 @@ bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port,
wwn2str(pwwn_ptr, pwwn);
wwn2str(fwwn_ptr, fwwn);
- switch (event) {
- case BFA_PORT_AEN_FABRIC_NAME_CHANGE:
- bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr,
- fwwn_ptr);
- break;
- default:
- break;
- }
+ bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event),
+ pwwn_ptr, fwwn_ptr);
aen_data.port.pwwn = pwwn;
aen_data.port.fwwn = fwwn;
diff --git a/drivers/scsi/bfa/fcbuild.h b/drivers/scsi/bfa/fcbuild.h
index 8fa7f270ef7..981d98d542b 100644
--- a/drivers/scsi/bfa/fcbuild.h
+++ b/drivers/scsi/bfa/fcbuild.h
@@ -72,6 +72,9 @@ fc_rpsc_operspeed_to_bfa_speed(enum fc_rpsc_op_speed_s speed)
case RPSC_OP_SPEED_8G:
return BFA_PPORT_SPEED_8GBPS;
+ case RPSC_OP_SPEED_10G:
+ return BFA_PPORT_SPEED_10GBPS;
+
default:
return BFA_PPORT_SPEED_UNKNOWN;
}
@@ -97,6 +100,9 @@ fc_bfa_speed_to_rpsc_operspeed(enum bfa_pport_speed op_speed)
case BFA_PPORT_SPEED_8GBPS:
return RPSC_OP_SPEED_8G;
+ case BFA_PPORT_SPEED_10GBPS:
+ return RPSC_OP_SPEED_10G;
+
default:
return RPSC_OP_SPEED_NOT_EST;
}
diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c
index 1f3c06efaa9..8ae4a2cfa85 100644
--- a/drivers/scsi/bfa/fcpim.c
+++ b/drivers/scsi/bfa/fcpim.c
@@ -126,7 +126,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->fcs, event);
}
}
@@ -161,7 +161,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->fcs, event);
}
}
@@ -205,7 +205,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->fcs, event);
}
}
@@ -240,7 +240,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->fcs, event);
}
}
@@ -270,7 +270,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->fcs, event);
}
}
@@ -298,7 +298,7 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->fcs, event);
}
}
@@ -321,7 +321,7 @@ bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->fcs, event);
}
}
@@ -354,7 +354,7 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(itnim->fcs, event);
}
}
@@ -385,19 +385,8 @@ bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
wwn2str(lpwwn_ptr, lpwwn);
wwn2str(rpwwn_ptr, rpwwn);
- switch (event) {
- case BFA_ITNIM_AEN_ONLINE:
- bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr);
- break;
- case BFA_ITNIM_AEN_OFFLINE:
- bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr);
- break;
- case BFA_ITNIM_AEN_DISCONNECT:
- bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
- break;
- default:
- break;
- }
+ bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, event),
+ rpwwn_ptr, lpwwn_ptr);
aen_data.itnim.vf_id = rport->port->fabric->vf_id;
aen_data.itnim.ppwwn =
@@ -689,7 +678,6 @@ bfa_cb_itnim_tov_begin(void *cb_arg)
struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
bfa_trc(itnim->fcs, itnim->rport->pwwn);
- bfa_fcb_itnim_tov_begin(itnim->itnim_drv);
}
/**
@@ -822,22 +810,3 @@ void
bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim)
{
}
-
-/**
- * Module initialization
- */
-void
-bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- * Module cleanup
- */
-void
-bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs)
-{
- bfa_fcs_modexit_comp(fcs);
-}
-
-
diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h
index eee960820f8..244c3f00c50 100644
--- a/drivers/scsi/bfa/fcs_fabric.h
+++ b/drivers/scsi/bfa/fcs_fabric.h
@@ -29,6 +29,7 @@
/*
* fcs friend functions: only between fcs modules
*/
+void bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs);
void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs);
void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs);
void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs);
@@ -46,6 +47,7 @@ void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric,
struct fchs_s *fchs, u16 len);
u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric);
+bfa_boolean_t bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric);
enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric);
void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric);
void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric);
diff --git a/drivers/scsi/bfa/fcs_fcpim.h b/drivers/scsi/bfa/fcs_fcpim.h
index 61e9e2687de..11e6e7bce9f 100644
--- a/drivers/scsi/bfa/fcs_fcpim.h
+++ b/drivers/scsi/bfa/fcs_fcpim.h
@@ -34,11 +34,6 @@ void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim);
void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim);
void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim);
-/*
- * Modudle init/cleanup routines.
- */
-void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs);
void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
u16 len);
#endif /* __FCS_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/fcs_lport.h b/drivers/scsi/bfa/fcs_lport.h
index ae744ba3567..a6508c8ab18 100644
--- a/drivers/scsi/bfa/fcs_lport.h
+++ b/drivers/scsi/bfa/fcs_lport.h
@@ -84,9 +84,10 @@ void bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
* Following routines will be called by Fabric to indicate port
* online/offline to vport.
*/
-void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
- u16 vf_id, struct bfa_port_cfg_s *port_cfg,
- struct bfa_fcs_vport_s *vport);
+void bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
+ uint16_t vf_id, struct bfa_fcs_vport_s *vport);
+void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
+ struct bfa_port_cfg_s *port_cfg);
void bfa_fcs_port_online(struct bfa_fcs_port_s *port);
void bfa_fcs_port_offline(struct bfa_fcs_port_s *port);
void bfa_fcs_port_delete(struct bfa_fcs_port_s *port);
diff --git a/drivers/scsi/bfa/fcs_port.h b/drivers/scsi/bfa/fcs_port.h
index abb65191dd2..408c06a7d16 100644
--- a/drivers/scsi/bfa/fcs_port.h
+++ b/drivers/scsi/bfa/fcs_port.h
@@ -26,7 +26,6 @@
/*
* fcs friend functions: only between fcs modules
*/
-void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs);
+void bfa_fcs_pport_attach(struct bfa_fcs_s *fcs);
#endif /* __FCS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/fcs_rport.h b/drivers/scsi/bfa/fcs_rport.h
index f601e9d7423..9c8d1d29238 100644
--- a/drivers/scsi/bfa/fcs_rport.h
+++ b/drivers/scsi/bfa/fcs_rport.h
@@ -24,9 +24,6 @@
#include <fcs/bfa_fcs_rport.h>
-void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs);
-
void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
u16 len);
void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
diff --git a/drivers/scsi/bfa/fcs_uf.h b/drivers/scsi/bfa/fcs_uf.h
index 96f1bdcb31e..f591072214f 100644
--- a/drivers/scsi/bfa/fcs_uf.h
+++ b/drivers/scsi/bfa/fcs_uf.h
@@ -26,7 +26,6 @@
/*
* fcs friend functions: only between fcs modules
*/
-void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs);
+void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs);
#endif /* __FCS_UF_H__ */
diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h
index 9e80b6a97b7..13c32ebf946 100644
--- a/drivers/scsi/bfa/fcs_vport.h
+++ b/drivers/scsi/bfa/fcs_vport.h
@@ -22,18 +22,10 @@
#include <fcs/bfa_fcs_vport.h>
#include <defs/bfa_defs_pci.h>
-/*
- * Modudle init/cleanup routines.
- */
-
-void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs);
-
void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
-u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs);
#endif /* __FCS_VPORT_H__ */
diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c
index df2a1e54e16..8f17076d1a8 100644
--- a/drivers/scsi/bfa/fdmi.c
+++ b/drivers/scsi/bfa/fdmi.c
@@ -116,6 +116,9 @@ static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
enum port_fdmi_event event);
static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
enum port_fdmi_event event);
+static void bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
+ enum port_fdmi_event event);
+
/**
* Start in offline state - awaiting MS to send start.
*/
@@ -155,7 +158,7 @@ bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -180,7 +183,7 @@ bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -227,7 +230,7 @@ bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -255,7 +258,7 @@ bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -283,7 +286,7 @@ bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -328,7 +331,7 @@ bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -356,7 +359,7 @@ bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -384,7 +387,7 @@ bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -428,7 +431,7 @@ bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -456,7 +459,7 @@ bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
@@ -475,10 +478,24 @@ bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(port->fcs, event);
}
}
+/**
+ * FDMI is disabled state.
+ */
+static void
+bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
+ enum port_fdmi_event event)
+{
+ struct bfa_fcs_port_s *port = fdmi->ms->port;
+
+ bfa_trc(port->fcs, port->port_cfg.pwwn);
+ bfa_trc(port->fcs, event);
+
+ /* No op State. It can only be enabled at Driver Init. */
+}
/**
* RHBA : Register HBA Attributes.
@@ -1097,36 +1114,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
{
struct bfa_fcs_port_s *port = fdmi->ms->port;
struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
- struct bfa_adapter_attr_s adapter_attr;
bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
- bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s));
-
- bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr);
-
- strncpy(hba_attr->manufacturer, adapter_attr.manufacturer,
- sizeof(adapter_attr.manufacturer));
-
- strncpy(hba_attr->serial_num, adapter_attr.serial_num,
- sizeof(adapter_attr.serial_num));
- strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model));
-
- strncpy(hba_attr->model_desc, adapter_attr.model_descr,
- sizeof(hba_attr->model_desc));
-
- strncpy(hba_attr->hw_version, adapter_attr.hw_ver,
- sizeof(hba_attr->hw_version));
+ bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
+ hba_attr->manufacturer);
+ bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
+ hba_attr->serial_num);
+ bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model);
+ bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model_desc);
+ bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, hba_attr->hw_version);
+ bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
+ hba_attr->option_rom_ver);
+ bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, hba_attr->fw_version);
strncpy(hba_attr->driver_version, (char *)driver_info->version,
sizeof(hba_attr->driver_version));
- strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver,
- sizeof(hba_attr->option_rom_ver));
-
- strncpy(hba_attr->fw_version, adapter_attr.fw_ver,
- sizeof(hba_attr->fw_version));
-
strncpy(hba_attr->os_name, driver_info->host_os_name,
sizeof(hba_attr->os_name));
@@ -1158,7 +1162,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
/*
* get pport attributes from hal
*/
- bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+ bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
/*
* get FC4 type Bitmask
@@ -1201,7 +1205,10 @@ bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms)
struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
fdmi->ms = ms;
- bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
+ if (ms->port->fcs->fdmi_enabled)
+ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
+ else
+ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_disabled);
}
void
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen.h b/drivers/scsi/bfa/include/aen/bfa_aen.h
index d9cbc2a783d..6abbab005db 100644
--- a/drivers/scsi/bfa/include/aen/bfa_aen.h
+++ b/drivers/scsi/bfa/include/aen/bfa_aen.h
@@ -18,21 +18,24 @@
#define __BFA_AEN_H__
#include "defs/bfa_defs_aen.h"
+#include "defs/bfa_defs_status.h"
+#include "cs/bfa_debug.h"
-#define BFA_AEN_MAX_ENTRY 512
+#define BFA_AEN_MAX_ENTRY 512
-extern s32 bfa_aen_max_cfg_entry;
+extern int bfa_aen_max_cfg_entry;
struct bfa_aen_s {
void *bfad;
- s32 max_entry;
- s32 write_index;
- s32 read_index;
- u32 bfad_num;
- u32 seq_num;
+ int max_entry;
+ int write_index;
+ int read_index;
+ int bfad_num;
+ int seq_num;
void (*aen_cb_notify)(void *bfad);
void (*gettimeofday)(struct bfa_timeval_s *tv);
- struct bfa_trc_mod_s *trcmod;
- struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
+ struct bfa_trc_mod_s *trcmod;
+ int app_ri[BFA_AEN_MAX_APP]; /* For multiclient support */
+ struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
};
@@ -45,48 +48,49 @@ bfa_aen_set_max_cfg_entry(int max_entry)
bfa_aen_max_cfg_entry = max_entry;
}
-static inline s32
+static inline int
bfa_aen_get_max_cfg_entry(void)
{
return bfa_aen_max_cfg_entry;
}
-static inline s32
+static inline int
bfa_aen_get_meminfo(void)
{
return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry();
}
-static inline s32
+static inline int
bfa_aen_get_wi(struct bfa_aen_s *aen)
{
return aen->write_index;
}
-static inline s32
+static inline int
bfa_aen_get_ri(struct bfa_aen_s *aen)
{
return aen->read_index;
}
-static inline s32
-bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index)
+static inline int
+bfa_aen_fetch_count(struct bfa_aen_s *aen, enum bfa_aen_app app_id)
{
- return ((aen->write_index + aen->max_entry) - read_index)
+ bfa_assert((app_id < BFA_AEN_MAX_APP) && (app_id >= bfa_aen_app_bcu));
+ return ((aen->write_index + aen->max_entry) - aen->app_ri[app_id])
% aen->max_entry;
}
-s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
- void *bfad, u32 inst_id, void (*aen_cb_notify)(void *),
+int bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
+ void *bfad, int bfad_num, void (*aen_cb_notify)(void *),
void (*gettimeofday)(struct bfa_timeval_s *));
-s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
+void bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
int aen_type, union bfa_aen_data_u *aen_data);
-s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry,
- s32 entry_space, s32 rii, s32 *ri_arr,
- s32 ri_arr_cnt);
+bfa_status_t bfa_aen_fetch(struct bfa_aen_s *aen,
+ struct bfa_aen_entry_s *aen_entry,
+ int entry_req, enum bfa_aen_app app_id, int *entry_ret);
-s32 bfa_aen_get_inst(struct bfa_aen_s *aen);
+int bfa_aen_get_inst(struct bfa_aen_s *aen);
#endif /* __BFA_AEN_H__ */
diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h
index d4bc0d9fa42..1f5966cfbd1 100644
--- a/drivers/scsi/bfa/include/bfa.h
+++ b/drivers/scsi/bfa/include/bfa.h
@@ -106,6 +106,26 @@ struct bfa_sge_s {
bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats)
#define bfa_ioc_clear_stats(__bfa) \
bfa_ioc_clr_stats(&(__bfa)->ioc)
+#define bfa_get_nports(__bfa) \
+ bfa_ioc_get_nports(&(__bfa)->ioc)
+#define bfa_get_adapter_manufacturer(__bfa, __manufacturer) \
+ bfa_ioc_get_adapter_manufacturer(&(__bfa)->ioc, __manufacturer)
+#define bfa_get_adapter_model(__bfa, __model) \
+ bfa_ioc_get_adapter_model(&(__bfa)->ioc, __model)
+#define bfa_get_adapter_serial_num(__bfa, __serial_num) \
+ bfa_ioc_get_adapter_serial_num(&(__bfa)->ioc, __serial_num)
+#define bfa_get_adapter_fw_ver(__bfa, __fw_ver) \
+ bfa_ioc_get_adapter_fw_ver(&(__bfa)->ioc, __fw_ver)
+#define bfa_get_adapter_optrom_ver(__bfa, __optrom_ver) \
+ bfa_ioc_get_adapter_optrom_ver(&(__bfa)->ioc, __optrom_ver)
+#define bfa_get_pci_chip_rev(__bfa, __chip_rev) \
+ bfa_ioc_get_pci_chip_rev(&(__bfa)->ioc, __chip_rev)
+#define bfa_get_ioc_state(__bfa) \
+ bfa_ioc_get_state(&(__bfa)->ioc)
+#define bfa_get_type(__bfa) \
+ bfa_ioc_get_type(&(__bfa)->ioc)
+#define bfa_get_mac(__bfa) \
+ bfa_ioc_get_mac(&(__bfa)->ioc)
/*
* bfa API functions
@@ -161,6 +181,7 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
void bfa_iocfc_enable(struct bfa_s *bfa);
void bfa_iocfc_disable(struct bfa_s *bfa);
void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
+void bfa_chip_reset(struct bfa_s *bfa);
void bfa_cb_ioc_disable(void *bfad);
void bfa_timer_tick(struct bfa_s *bfa);
#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \
@@ -171,6 +192,7 @@ void bfa_timer_tick(struct bfa_s *bfa);
*/
bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen);
bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen);
+void bfa_debug_fwsave_clear(struct bfa_s *bfa);
#include "bfa_priv.h"
diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h
index 268d956bad8..1349b99a3c6 100644
--- a/drivers/scsi/bfa/include/bfa_svc.h
+++ b/drivers/scsi/bfa/include/bfa_svc.h
@@ -26,6 +26,7 @@ struct bfa_fcxp_s;
#include <defs/bfa_defs_pport.h>
#include <defs/bfa_defs_rport.h>
#include <defs/bfa_defs_qos.h>
+#include <defs/bfa_defs_fcport.h>
#include <cs/bfa_sm.h>
#include <bfa.h>
@@ -35,7 +36,7 @@ struct bfa_fcxp_s;
struct bfa_rport_info_s {
u16 max_frmsz; /* max rcv pdu size */
u32 pid:24, /* remote port ID */
- lp_tag:8;
+ lp_tag:8; /* tag */
u32 local_pid:24, /* local port ID */
cisc:8; /* CIRO supported */
u8 fc_class; /* supported FC classes. enum fc_cos */
@@ -54,7 +55,7 @@ struct bfa_rport_s {
void *rport_drv; /* fcs/driver rport object */
u16 fw_handle; /* firmware rport handle */
u16 rport_tag; /* BFA rport tag */
- struct bfa_rport_info_s rport_info; /* rport info from *fcs/driver */
+ struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */
struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */
@@ -101,7 +102,7 @@ struct bfa_uf_buf_s {
struct bfa_uf_s {
struct list_head qe; /* queue element */
struct bfa_s *bfa; /* bfa instance */
- u16 uf_tag; /* identifying tag f/w messages */
+ u16 uf_tag; /* identifying tag fw msgs */
u16 vf_id;
u16 src_rport_handle;
u16 rsvd;
@@ -127,7 +128,7 @@ struct bfa_lps_s {
u8 reqq; /* lport request queue */
u8 alpa; /* ALPA for loop topologies */
u32 lp_pid; /* lport port ID */
- bfa_boolean_t fdisc; /* send FDISC instead of FLOGI*/
+ bfa_boolean_t fdisc; /* send FDISC instead of FLOGI */
bfa_boolean_t auth_en; /* enable authentication */
bfa_boolean_t auth_req; /* authentication required */
bfa_boolean_t npiv_en; /* NPIV is allowed by peer */
@@ -151,60 +152,69 @@ struct bfa_lps_s {
bfa_eproto_status_t ext_status;
};
+#define BFA_FCPORT(_bfa) (&((_bfa)->modules.port))
+
/*
* bfa pport API functions
*/
-bfa_status_t bfa_pport_enable(struct bfa_s *bfa);
-bfa_status_t bfa_pport_disable(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa,
+bfa_status_t bfa_fcport_enable(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_disable(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_speed(struct bfa_s *bfa,
enum bfa_pport_speed speed);
-enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa,
+enum bfa_pport_speed bfa_fcport_get_speed(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa,
enum bfa_pport_topology topo);
-enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
-bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
-u8 bfa_pport_get_myalpa(struct bfa_s *bfa);
-bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
-u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa);
-u32 bfa_pport_mypid(struct bfa_s *bfa);
-u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa);
-bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
-bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa);
-bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
-void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
-wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
-bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa,
- union bfa_pport_stats_u *stats,
- bfa_cb_pport_t cbfn, void *cbarg);
-bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
- void *cbarg);
-void bfa_pport_event_register(struct bfa_s *bfa,
+enum bfa_pport_topology bfa_fcport_get_topology(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
+bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
+u8 bfa_fcport_get_myalpa(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_clr_hardalpa(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
+u16 bfa_fcport_get_maxfrsize(struct bfa_s *bfa);
+u32 bfa_fcport_mypid(struct bfa_s *bfa);
+u8 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
+bfa_status_t bfa_fcport_trunk_disable(struct bfa_s *bfa);
+bfa_boolean_t bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
+void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
+wwn_t bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
+void bfa_fcport_event_register(struct bfa_s *bfa,
void (*event_cbfn) (void *cbarg,
bfa_pport_event_t event), void *event_cbarg);
-bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa);
-void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
-void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
-bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa,
+bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
+void bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
+void bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
+bfa_status_t bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa,
enum bfa_pport_speed speed);
-enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa);
+enum bfa_pport_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
-void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
-void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status);
-void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
+void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
+void bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status);
+void bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
bfa_boolean_t link_e2e_beacon);
void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event);
-void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr);
-void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
+void bfa_fcport_qos_get_attr(struct bfa_s *bfa,
+ struct bfa_qos_attr_s *qos_attr);
+void bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
struct bfa_qos_vc_attr_s *qos_vc_attr);
-bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa,
- union bfa_pport_stats_u *stats,
+bfa_status_t bfa_fcport_get_qos_stats(struct bfa_s *bfa,
+ union bfa_fcport_stats_u *stats,
bfa_cb_pport_t cbfn, void *cbarg);
-bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
void *cbarg);
-bfa_boolean_t bfa_pport_is_ratelim(struct bfa_s *bfa);
-bfa_boolean_t bfa_pport_is_linkup(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_get_fcoe_stats(struct bfa_s *bfa,
+ union bfa_fcport_stats_u *stats,
+ bfa_cb_pport_t cbfn, void *cbarg);
+bfa_status_t bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+ void *cbarg);
+
+bfa_boolean_t bfa_fcport_is_ratelim(struct bfa_s *bfa);
+bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa,
+ union bfa_fcport_stats_u *stats,
+ bfa_cb_pport_t cbfn, void *cbarg);
+bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+ void *cbarg);
/*
* bfa rport API functions
@@ -293,6 +303,7 @@ void bfa_uf_free(struct bfa_uf_s *uf);
* bfa lport service api
*/
+u32 bfa_lps_get_max_vport(struct bfa_s *bfa);
struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa);
void bfa_lps_delete(struct bfa_lps_s *lps);
void bfa_lps_discard(struct bfa_lps_s *lps);
@@ -315,10 +326,12 @@ wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps);
wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps);
u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps);
u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps);
+mac_t bfa_lps_get_lp_mac(struct bfa_lps_s *lps);
void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
+void bfa_cb_lps_cvl_event(void *bfad, void *uarg);
#endif /* __BFA_SVC_H__ */
diff --git a/drivers/scsi/bfa/include/bfa_timer.h b/drivers/scsi/bfa/include/bfa_timer.h
index e407103fa56..f7108744822 100644
--- a/drivers/scsi/bfa/include/bfa_timer.h
+++ b/drivers/scsi/bfa/include/bfa_timer.h
@@ -41,7 +41,7 @@ struct bfa_timer_mod_s {
struct list_head timer_q;
};
-#define BFA_TIMER_FREQ 500 /**< specified in millisecs */
+#define BFA_TIMER_FREQ 200 /**< specified in millisecs */
void bfa_timer_beat(struct bfa_timer_mod_s *mod);
void bfa_timer_init(struct bfa_timer_mod_s *mod);
diff --git a/drivers/scsi/bfa/include/bfi/bfi.h b/drivers/scsi/bfa/include/bfi/bfi.h
index 7042c18e542..a550e80cabd 100644
--- a/drivers/scsi/bfa/include/bfi/bfi.h
+++ b/drivers/scsi/bfa/include/bfi/bfi.h
@@ -143,8 +143,8 @@ enum bfi_mclass {
BFI_MC_IOC = 1, /* IO Controller (IOC) */
BFI_MC_DIAG = 2, /* Diagnostic Msgs */
BFI_MC_FLASH = 3, /* Flash message class */
- BFI_MC_CEE = 4,
- BFI_MC_FC_PORT = 5, /* FC port */
+ BFI_MC_CEE = 4, /* CEE */
+ BFI_MC_FCPORT = 5, /* FC port */
BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */
BFI_MC_LL = 7, /* Link Layer */
BFI_MC_UF = 8, /* Unsolicited frame receive */
diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
index b3bb52b565b..a51ee61ddb1 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
@@ -177,7 +177,21 @@
#define __PSS_LMEM_INIT_EN 0x00000100
#define __PSS_LPU1_RESET 0x00000002
#define __PSS_LPU0_RESET 0x00000001
-
+#define PSS_ERR_STATUS_REG 0x00018810
+#define __PSS_LMEM1_CORR_ERR 0x00000800
+#define __PSS_LMEM0_CORR_ERR 0x00000400
+#define __PSS_LMEM1_UNCORR_ERR 0x00000200
+#define __PSS_LMEM0_UNCORR_ERR 0x00000100
+#define __PSS_BAL_PERR 0x00000080
+#define __PSS_DIP_IF_ERR 0x00000040
+#define __PSS_IOH_IF_ERR 0x00000020
+#define __PSS_TDS_IF_ERR 0x00000010
+#define __PSS_RDS_IF_ERR 0x00000008
+#define __PSS_SGM_IF_ERR 0x00000004
+#define __PSS_LPU1_RAM_ERR 0x00000002
+#define __PSS_LPU0_RAM_ERR 0x00000001
+#define ERR_SET_REG 0x00018818
+#define __PSS_ERR_STATUS_SET 0x00000fff
/*
* These definitions are either in error/missing in spec. Its auto-generated
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
index d3caa58c0a0..57a8497105a 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
@@ -430,6 +430,31 @@ enum {
#define __PSS_LMEM_INIT_EN 0x00000100
#define __PSS_LPU1_RESET 0x00000002
#define __PSS_LPU0_RESET 0x00000001
+#define PSS_ERR_STATUS_REG 0x00018810
+#define __PSS_LPU1_TCM_READ_ERR 0x00200000
+#define __PSS_LPU0_TCM_READ_ERR 0x00100000
+#define __PSS_LMEM5_CORR_ERR 0x00080000
+#define __PSS_LMEM4_CORR_ERR 0x00040000
+#define __PSS_LMEM3_CORR_ERR 0x00020000
+#define __PSS_LMEM2_CORR_ERR 0x00010000
+#define __PSS_LMEM1_CORR_ERR 0x00008000
+#define __PSS_LMEM0_CORR_ERR 0x00004000
+#define __PSS_LMEM5_UNCORR_ERR 0x00002000
+#define __PSS_LMEM4_UNCORR_ERR 0x00001000
+#define __PSS_LMEM3_UNCORR_ERR 0x00000800
+#define __PSS_LMEM2_UNCORR_ERR 0x00000400
+#define __PSS_LMEM1_UNCORR_ERR 0x00000200
+#define __PSS_LMEM0_UNCORR_ERR 0x00000100
+#define __PSS_BAL_PERR 0x00000080
+#define __PSS_DIP_IF_ERR 0x00000040
+#define __PSS_IOH_IF_ERR 0x00000020
+#define __PSS_TDS_IF_ERR 0x00000010
+#define __PSS_RDS_IF_ERR 0x00000008
+#define __PSS_SGM_IF_ERR 0x00000004
+#define __PSS_LPU1_RAM_ERR 0x00000002
+#define __PSS_LPU0_RAM_ERR 0x00000001
+#define ERR_SET_REG 0x00018818
+#define __PSS_ERR_STATUS_SET 0x003fffff
#define HQM_QSET0_RXQ_DRBL_P0 0x00038000
#define __RXQ0_ADD_VECTORS_P 0x80000000
#define __RXQ0_STOP_P 0x40000000
@@ -589,6 +614,7 @@ enum {
#define __HFN_INT_MBOX_LPU1 0x00200000U
#define __HFN_INT_MBOX1_LPU0 0x00400000U
#define __HFN_INT_MBOX1_LPU1 0x00800000U
+#define __HFN_INT_LL_HALT 0x01000000U
#define __HFN_INT_CPE_MASK 0x000000ffU
#define __HFN_INT_RME_MASK 0x0000ff00U
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
index 96ef0567065..a0158aac002 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ioc.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
@@ -123,7 +123,7 @@ enum bfi_ioc_state {
BFI_IOC_DISABLING = 5, /* IOC is being disabled */
BFI_IOC_DISABLED = 6, /* IOC is disabled */
BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */
- BFI_IOC_HBFAIL = 8, /* IOC heart-beat failure */
+ BFI_IOC_FAIL = 8, /* IOC heart-beat failure */
BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */
};
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h
index c59d47badb4..7ed31bbb869 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_lps.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h
@@ -30,6 +30,7 @@ enum bfi_lps_h2i_msgs {
enum bfi_lps_i2h_msgs {
BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1),
BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2),
+ BFI_LPS_H2I_CVL_EVENT = BFA_I2HM(3),
};
struct bfi_lps_login_req_s {
@@ -77,6 +78,12 @@ struct bfi_lps_logout_rsp_s {
u8 rsvd[2];
};
+struct bfi_lps_cvl_event_s {
+ struct bfi_mhdr_s mh; /* common msg header */
+ u8 lp_tag;
+ u8 rsvd[3];
+};
+
union bfi_lps_h2i_msg_u {
struct bfi_mhdr_s *msg;
struct bfi_lps_login_req_s *login_req;
@@ -87,6 +94,7 @@ union bfi_lps_i2h_msg_u {
struct bfi_msg_s *msg;
struct bfi_lps_login_rsp_s *login_rsp;
struct bfi_lps_logout_rsp_s *logout_rsp;
+ struct bfi_lps_cvl_event_s *cvl_event;
};
#pragma pack()
diff --git a/drivers/scsi/bfa/include/bfi/bfi_pport.h b/drivers/scsi/bfa/include/bfi/bfi_pport.h
index c96d246851a..50dcf45c747 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_pport.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_pport.h
@@ -22,163 +22,97 @@
#pragma pack(1)
-enum bfi_pport_h2i {
- BFI_PPORT_H2I_ENABLE_REQ = (1),
- BFI_PPORT_H2I_DISABLE_REQ = (2),
- BFI_PPORT_H2I_GET_STATS_REQ = (3),
- BFI_PPORT_H2I_CLEAR_STATS_REQ = (4),
- BFI_PPORT_H2I_SET_SVC_PARAMS_REQ = (5),
- BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ = (6),
- BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ = (7),
- BFI_PPORT_H2I_GET_QOS_STATS_REQ = (8),
- BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ = (9),
+enum bfi_fcport_h2i {
+ BFI_FCPORT_H2I_ENABLE_REQ = (1),
+ BFI_FCPORT_H2I_DISABLE_REQ = (2),
+ BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ = (3),
+ BFI_FCPORT_H2I_STATS_GET_REQ = (4),
+ BFI_FCPORT_H2I_STATS_CLEAR_REQ = (5),
};
-enum bfi_pport_i2h {
- BFI_PPORT_I2H_ENABLE_RSP = BFA_I2HM(1),
- BFI_PPORT_I2H_DISABLE_RSP = BFA_I2HM(2),
- BFI_PPORT_I2H_GET_STATS_RSP = BFA_I2HM(3),
- BFI_PPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4),
- BFI_PPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(5),
- BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP = BFA_I2HM(6),
- BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP = BFA_I2HM(7),
- BFI_PPORT_I2H_EVENT = BFA_I2HM(8),
- BFI_PPORT_I2H_GET_QOS_STATS_RSP = BFA_I2HM(9),
- BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP = BFA_I2HM(10),
+enum bfi_fcport_i2h {
+ BFI_FCPORT_I2H_ENABLE_RSP = BFA_I2HM(1),
+ BFI_FCPORT_I2H_DISABLE_RSP = BFA_I2HM(2),
+ BFI_FCPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(3),
+ BFI_FCPORT_I2H_STATS_GET_RSP = BFA_I2HM(4),
+ BFI_FCPORT_I2H_STATS_CLEAR_RSP = BFA_I2HM(5),
+ BFI_FCPORT_I2H_EVENT = BFA_I2HM(6),
};
/**
* Generic REQ type
*/
-struct bfi_pport_generic_req_s {
+struct bfi_fcport_req_s {
struct bfi_mhdr_s mh; /* msg header */
- u32 msgtag; /* msgtag for reply */
+ u32 msgtag; /* msgtag for reply */
};
/**
* Generic RSP type
*/
-struct bfi_pport_generic_rsp_s {
+struct bfi_fcport_rsp_s {
struct bfi_mhdr_s mh; /* common msg header */
- u8 status; /* port enable status */
- u8 rsvd[3];
- u32 msgtag; /* msgtag for reply */
+ u8 status; /* port enable status */
+ u8 rsvd[3];
+ u32 msgtag; /* msgtag for reply */
};
/**
- * BFI_PPORT_H2I_ENABLE_REQ
+ * BFI_FCPORT_H2I_ENABLE_REQ
*/
-struct bfi_pport_enable_req_s {
+struct bfi_fcport_enable_req_s {
struct bfi_mhdr_s mh; /* msg header */
- u32 rsvd1;
- wwn_t nwwn; /* node wwn of physical port */
- wwn_t pwwn; /* port wwn of physical port */
- struct bfa_pport_cfg_s port_cfg; /* port configuration */
- union bfi_addr_u stats_dma_addr; /* DMA address for stats */
- u32 msgtag; /* msgtag for reply */
- u32 rsvd2;
+ u32 rsvd1;
+ wwn_t nwwn; /* node wwn of physical port */
+ wwn_t pwwn; /* port wwn of physical port */
+ struct bfa_pport_cfg_s port_cfg; /* port configuration */
+ union bfi_addr_u stats_dma_addr; /* DMA address for stats */
+ u32 msgtag; /* msgtag for reply */
+ u32 rsvd2;
};
/**
- * BFI_PPORT_I2H_ENABLE_RSP
+ * BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ
*/
-#define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_DISABLE_REQ
- */
-#define bfi_pport_disable_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_DISABLE_RSP
- */
-#define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_GET_STATS_REQ
- */
-#define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_GET_STATS_RSP
- */
-#define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_STATS_REQ
- */
-#define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_CLEAR_STATS_RSP
- */
-#define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_GET_QOS_STATS_REQ
- */
-#define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_H2I_GET_QOS_STATS_RSP
- */
-#define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ
- */
-#define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP
- */
-#define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ
- */
-struct bfi_pport_set_svc_params_req_s {
+struct bfi_fcport_set_svc_params_req_s {
struct bfi_mhdr_s mh; /* msg header */
- u16 tx_bbcredit; /* Tx credits */
- u16 rsvd;
+ u16 tx_bbcredit; /* Tx credits */
+ u16 rsvd;
};
/**
- * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP
- */
-
-/**
- * BFI_PPORT_I2H_EVENT
+ * BFI_FCPORT_I2H_EVENT
*/
-struct bfi_pport_event_s {
+struct bfi_fcport_event_s {
struct bfi_mhdr_s mh; /* common msg header */
struct bfa_pport_link_s link_state;
};
-union bfi_pport_h2i_msg_u {
+/**
+ * fcport H2I message
+ */
+union bfi_fcport_h2i_msg_u {
struct bfi_mhdr_s *mhdr;
- struct bfi_pport_enable_req_s *penable;
- struct bfi_pport_generic_req_s *pdisable;
- struct bfi_pport_generic_req_s *pgetstats;
- struct bfi_pport_generic_req_s *pclearstats;
- struct bfi_pport_set_svc_params_req_s *psetsvcparams;
- struct bfi_pport_get_qos_stats_req_s *pgetqosstats;
- struct bfi_pport_generic_req_s *pclearqosstats;
+ struct bfi_fcport_enable_req_s *penable;
+ struct bfi_fcport_req_s *pdisable;
+ struct bfi_fcport_set_svc_params_req_s *psetsvcparams;
+ struct bfi_fcport_req_s *pstatsget;
+ struct bfi_fcport_req_s *pstatsclear;
};
-union bfi_pport_i2h_msg_u {
+/**
+ * fcport I2H message
+ */
+union bfi_fcport_i2h_msg_u {
struct bfi_msg_s *msg;
- struct bfi_pport_generic_rsp_s *enable_rsp;
- struct bfi_pport_disable_rsp_s *disable_rsp;
- struct bfi_pport_generic_rsp_s *getstats_rsp;
- struct bfi_pport_clear_stats_rsp_s *clearstats_rsp;
- struct bfi_pport_set_svc_params_rsp_s *setsvcparasm_rsp;
- struct bfi_pport_get_qos_stats_rsp_s *getqosstats_rsp;
- struct bfi_pport_clear_qos_stats_rsp_s *clearqosstats_rsp;
- struct bfi_pport_event_s *event;
+ struct bfi_fcport_rsp_s *penable_rsp;
+ struct bfi_fcport_rsp_s *pdisable_rsp;
+ struct bfi_fcport_rsp_s *psetsvcparams_rsp;
+ struct bfi_fcport_rsp_s *pstatsget_rsp;
+ struct bfi_fcport_rsp_s *pstatsclear_rsp;
+ struct bfi_fcport_event_s *event;
};
#pragma pack()
#endif /* __BFI_PPORT_H__ */
-
diff --git a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
index 43ba7064e81..a75a1f3be31 100644
--- a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
+++ b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
@@ -31,6 +31,10 @@
enum {
BFA_TRC_CNA_CEE = 1,
BFA_TRC_CNA_PORT = 2,
+ BFA_TRC_CNA_IOC = 3,
+ BFA_TRC_CNA_DIAG = 4,
+ BFA_TRC_CNA_IOC_CB = 5,
+ BFA_TRC_CNA_IOC_CT = 6,
};
#endif /* __BFA_CNA_TRCMOD_H__ */
diff --git a/drivers/scsi/bfa/include/cs/bfa_log.h b/drivers/scsi/bfa/include/cs/bfa_log.h
index 761cbe22130..bc334e0a93f 100644
--- a/drivers/scsi/bfa/include/cs/bfa_log.h
+++ b/drivers/scsi/bfa/include/cs/bfa_log.h
@@ -157,7 +157,7 @@ typedef void (*bfa_log_cb_t)(struct bfa_log_mod_s *log_mod, u32 msg_id,
struct bfa_log_mod_s {
- char instance_info[16]; /* instance info */
+ char instance_info[BFA_STRING_32]; /* instance info */
int log_level[BFA_LOG_MODULE_ID_MAX + 1];
/* log level for modules */
bfa_log_cb_t cbfn; /* callback function */
diff --git a/drivers/scsi/bfa/include/cs/bfa_plog.h b/drivers/scsi/bfa/include/cs/bfa_plog.h
index 670f86e5fc6..f5bef63b587 100644
--- a/drivers/scsi/bfa/include/cs/bfa_plog.h
+++ b/drivers/scsi/bfa/include/cs/bfa_plog.h
@@ -80,7 +80,8 @@ enum bfa_plog_mid {
BFA_PL_MID_HAL_FCXP = 4,
BFA_PL_MID_HAL_UF = 5,
BFA_PL_MID_FCS = 6,
- BFA_PL_MID_MAX = 7
+ BFA_PL_MID_LPS = 7,
+ BFA_PL_MID_MAX = 8
};
#define BFA_PL_MID_STRLEN 8
@@ -118,7 +119,11 @@ enum bfa_plog_eid {
BFA_PL_EID_RSCN = 17,
BFA_PL_EID_DEBUG = 18,
BFA_PL_EID_MISC = 19,
- BFA_PL_EID_MAX = 20
+ BFA_PL_EID_FIP_FCF_DISC = 20,
+ BFA_PL_EID_FIP_FCF_CVL = 21,
+ BFA_PL_EID_LOGIN = 22,
+ BFA_PL_EID_LOGO = 23,
+ BFA_PL_EID_MAX = 24
};
#define BFA_PL_ENAME_STRLEN 8
diff --git a/drivers/scsi/bfa/include/cs/bfa_sm.h b/drivers/scsi/bfa/include/cs/bfa_sm.h
index b0a92baf665..11fba9082f0 100644
--- a/drivers/scsi/bfa/include/cs/bfa_sm.h
+++ b/drivers/scsi/bfa/include/cs/bfa_sm.h
@@ -23,6 +23,14 @@
#define __BFA_SM_H__
typedef void (*bfa_sm_t)(void *sm, int event);
+/**
+ * oc - object class eg. bfa_ioc
+ * st - state, eg. reset
+ * otype - object type, eg. struct bfa_ioc_s
+ * etype - object type, eg. enum ioc_event
+ */
+#define bfa_sm_state_decl(oc, st, otype, etype) \
+ static void oc ## _sm_ ## st(otype * fsm, etype event)
#define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state))
#define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event)))
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
index 4c81a613db3..35244698fcd 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
@@ -30,6 +30,16 @@
#include <defs/bfa_defs_audit.h>
#include <defs/bfa_defs_ethport.h>
+#define BFA_AEN_MAX_APP 5
+
+enum bfa_aen_app {
+ bfa_aen_app_bcu = 0, /* No thread for bcu */
+ bfa_aen_app_hcm = 1,
+ bfa_aen_app_cim = 2,
+ bfa_aen_app_snia = 3,
+ bfa_aen_app_test = 4, /* To be removed after unit test */
+};
+
enum bfa_aen_category {
BFA_AEN_CAT_ADAPTER = 1,
BFA_AEN_CAT_PORT = 2,
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
index dd19c83aba5..45df3282091 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
@@ -23,6 +23,7 @@
#define PRIVATE_KEY 19009
#define KEY_LEN 32399
#define BFA_AUTH_SECRET_STRING_LEN 256
+#define BFA_AUTH_FAIL_NO_PASSWORD 0xFE
#define BFA_AUTH_FAIL_TIMEOUT 0xFF
/**
@@ -41,6 +42,27 @@ enum bfa_auth_status {
BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */
};
+enum bfa_auth_rej_code {
+ BFA_AUTH_RJT_CODE_AUTH_FAILURE = 1, /* auth failure */
+ BFA_AUTH_RJT_CODE_LOGICAL_ERR = 2, /* logical error */
+};
+
+/**
+ * Authentication reject codes
+ */
+enum bfa_auth_rej_code_exp {
+ BFA_AUTH_MECH_NOT_USABLE = 1, /* auth. mechanism not usable */
+ BFA_AUTH_DH_GROUP_NOT_USABLE = 2, /* DH Group not usable */
+ BFA_AUTH_HASH_FUNC_NOT_USABLE = 3, /* hash Function not usable */
+ BFA_AUTH_AUTH_XACT_STARTED = 4, /* auth xact started */
+ BFA_AUTH_AUTH_FAILED = 5, /* auth failed */
+ BFA_AUTH_INCORRECT_PLD = 6, /* incorrect payload */
+ BFA_AUTH_INCORRECT_PROTO_MSG = 7, /* incorrect proto msg */
+ BFA_AUTH_RESTART_AUTH_PROTO = 8, /* restart auth protocol */
+ BFA_AUTH_AUTH_CONCAT_NOT_SUPP = 9, /* auth concat not supported */
+ BFA_AUTH_PROTO_VER_NOT_SUPP = 10,/* proto version not supported */
+};
+
struct auth_proto_stats_s {
u32 auth_rjts;
u32 auth_negs;
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
index 520a22f52dd..b0ac9ac15c5 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
@@ -28,10 +28,6 @@
#define BFA_CEE_LLDP_MAX_STRING_LEN (128)
-
-/* FIXME: this is coming from the protocol spec. Can the host & apps share the
- protocol .h files ?
- */
#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001
#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002
#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004
@@ -94,9 +90,10 @@ struct bfa_cee_dcbx_cfg_s {
/* CEE status */
/* Making this to tri-state for the benefit of port list command */
enum bfa_cee_status_e {
- CEE_PHY_DOWN = 0,
- CEE_PHY_UP = 1,
- CEE_UP = 2,
+ CEE_UP = 0,
+ CEE_PHY_UP = 1,
+ CEE_LOOPBACK = 2,
+ CEE_PHY_DOWN = 3,
};
/* CEE Query */
@@ -107,7 +104,8 @@ struct bfa_cee_attr_s {
struct bfa_cee_dcbx_cfg_s dcbx_remote;
mac_t src_mac;
u8 link_speed;
- u8 filler[3];
+ u8 nw_priority;
+ u8 filler[2];
};
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
index 57049805762..50382dd2ab4 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
@@ -21,6 +21,7 @@
/**
* Driver statistics
*/
+struct bfa_driver_stats_s {
u16 tm_io_abort;
u16 tm_io_abort_comp;
u16 tm_lun_reset;
@@ -34,7 +35,7 @@
u64 output_req;
u64 input_words;
u64 output_words;
-} bfa_driver_stats_t;
+};
#endif /* __BFA_DEFS_DRIVER_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
index 79f9b3e146f..b4fa0923aa8 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
@@ -19,6 +19,7 @@
#define __BFA_DEFS_ETHPORT_H__
#include <defs/bfa_defs_status.h>
+#include <defs/bfa_defs_port.h>
#include <protocol/types.h>
#include <cna/pstats/phyport_defs.h>
#include <cna/pstats/ethport_defs.h>
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
new file mode 100644
index 00000000000..a07ef4a3cd7
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * bfa_defs_fcport.h
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) 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.
+ */
+#ifndef __BFA_DEFS_FCPORT_H__
+#define __BFA_DEFS_FCPORT_H__
+
+#include <defs/bfa_defs_types.h>
+#include <protocol/types.h>
+
+#pragma pack(1)
+
+/**
+ * FCoE statistics
+ */
+struct bfa_fcoe_stats_s {
+ u64 secs_reset; /* Seconds since stats reset */
+ u64 cee_linkups; /* CEE link up */
+ u64 cee_linkdns; /* CEE link down */
+ u64 fip_linkups; /* FIP link up */
+ u64 fip_linkdns; /* FIP link down */
+ u64 fip_fails; /* FIP failures */
+ u64 mac_invalids; /* Invalid mac assignments */
+ u64 vlan_req; /* Vlan requests */
+ u64 vlan_notify; /* Vlan notifications */
+ u64 vlan_err; /* Vlan notification errors */
+ u64 vlan_timeouts; /* Vlan request timeouts */
+ u64 vlan_invalids; /* Vlan invalids */
+ u64 disc_req; /* Discovery requests */
+ u64 disc_rsp; /* Discovery responses */
+ u64 disc_err; /* Discovery error frames */
+ u64 disc_unsol; /* Discovery unsolicited */
+ u64 disc_timeouts; /* Discovery timeouts */
+ u64 disc_fcf_unavail; /* Discovery FCF not avail */
+ u64 linksvc_unsupp; /* FIP link service req unsupp. */
+ u64 linksvc_err; /* FIP link service req errors */
+ u64 logo_req; /* FIP logo */
+ u64 clrvlink_req; /* Clear virtual link requests */
+ u64 op_unsupp; /* FIP operation unsupp. */
+ u64 untagged; /* FIP untagged frames */
+ u64 txf_ucast; /* Tx FCoE unicast frames */
+ u64 txf_ucast_vlan; /* Tx FCoE unicast vlan frames */
+ u64 txf_ucast_octets; /* Tx FCoE unicast octets */
+ u64 txf_mcast; /* Tx FCoE mutlicast frames */
+ u64 txf_mcast_vlan; /* Tx FCoE mutlicast vlan frames */
+ u64 txf_mcast_octets; /* Tx FCoE multicast octets */
+ u64 txf_bcast; /* Tx FCoE broadcast frames */
+ u64 txf_bcast_vlan; /* Tx FCoE broadcast vlan frames */
+ u64 txf_bcast_octets; /* Tx FCoE broadcast octets */
+ u64 txf_timeout; /* Tx timeouts */
+ u64 txf_parity_errors; /* Transmit parity err */
+ u64 txf_fid_parity_errors; /* Transmit FID parity err */
+ u64 tx_pause; /* Tx pause frames */
+ u64 tx_zero_pause; /* Tx zero pause frames */
+ u64 tx_first_pause; /* Tx first pause frames */
+ u64 rx_pause; /* Rx pause frames */
+ u64 rx_zero_pause; /* Rx zero pause frames */
+ u64 rx_first_pause; /* Rx first pause frames */
+ u64 rxf_ucast_octets; /* Rx unicast octets */
+ u64 rxf_ucast; /* Rx unicast frames */
+ u64 rxf_ucast_vlan; /* Rx unicast vlan frames */
+ u64 rxf_mcast_octets; /* Rx multicast octets */
+ u64 rxf_mcast; /* Rx multicast frames */
+ u64 rxf_mcast_vlan; /* Rx multicast vlan frames */
+ u64 rxf_bcast_octets; /* Rx broadcast octests */
+ u64 rxf_bcast; /* Rx broadcast frames */
+ u64 rxf_bcast_vlan; /* Rx broadcast vlan frames */
+};
+
+/**
+ * QoS or FCoE stats (fcport stats excluding physical FC port stats)
+ */
+union bfa_fcport_stats_u {
+ struct bfa_qos_stats_s fcqos;
+ struct bfa_fcoe_stats_s fcoe;
+};
+
+#pragma pack()
+
+#endif /* __BFA_DEFS_FCPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
deleted file mode 100644
index 9ccf53bef65..00000000000
--- a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) 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.
- */
-
-#ifndef __BFA_DEFS_IM_COMMON_H__
-#define __BFA_DEFS_IM_COMMON_H__
-
-#define BFA_ADAPTER_NAME_LEN 256
-#define BFA_ADAPTER_GUID_LEN 256
-#define RESERVED_VLAN_NAME L"PORT VLAN"
-#define PASSTHRU_VLAN_NAME L"PASSTHRU VLAN"
-
- u64 tx_pkt_cnt;
- u64 rx_pkt_cnt;
- u32 duration;
- u8 status;
-} bfa_im_stats_t, *pbfa_im_stats_t;
-
-#endif /* __BFA_DEFS_IM_COMMON_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
deleted file mode 100644
index a486a7eb81d..00000000000
--- a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) 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.
- */
-
-#ifndef __BFA_DEFS_IM_TEAM_H__
-#define __BFA_DEFS_IM_TEAM_H__
-
-#include <protocol/types.h>
-
-#define BFA_TEAM_MAX_PORTS 8
-#define BFA_TEAM_NAME_LEN 256
-#define BFA_MAX_NUM_TEAMS 16
-#define BFA_TEAM_INVALID_DELAY -1
-
- BFA_LACP_RATE_SLOW = 1,
- BFA_LACP_RATE_FAST
-} bfa_im_lacp_rate_t;
-
- BFA_TEAM_MODE_FAIL_OVER = 1,
- BFA_TEAM_MODE_FAIL_BACK,
- BFA_TEAM_MODE_LACP,
- BFA_TEAM_MODE_NONE
-} bfa_im_team_mode_t;
-
- BFA_XMIT_POLICY_L2 = 1,
- BFA_XMIT_POLICY_L3_L4
-} bfa_im_xmit_policy_t;
-
- bfa_im_team_mode_t team_mode;
- bfa_im_lacp_rate_t lacp_rate;
- bfa_im_xmit_policy_t xmit_policy;
- int delay;
- wchar_t primary[BFA_ADAPTER_NAME_LEN];
- wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN];
- mac_t mac;
- u16 num_ports;
- u16 num_vlans;
- u16 vlan_list[BFA_MAX_VLANS_PER_PORT];
- wchar_t team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN];
- wchar_t ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN];
-} bfa_im_team_attr_t;
-
- wchar_t team_name[BFA_TEAM_NAME_LEN];
- bfa_im_xmit_policy_t xmit_policy;
- int delay;
- wchar_t primary[BFA_ADAPTER_NAME_LEN];
- wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN];
-} bfa_im_team_edit_t, *pbfa_im_team_edit_t;
-
- wchar_t team_name[BFA_TEAM_NAME_LEN];
- bfa_im_team_mode_t team_mode;
- mac_t mac;
-} bfa_im_team_info_t;
-
- bfa_im_team_info_t team_info[BFA_MAX_NUM_TEAMS];
- u16 num_teams;
-} bfa_im_team_list_t, *pbfa_im_team_list_t;
-
-#endif /* __BFA_DEFS_IM_TEAM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
index b1d532da3a9..8d8e6a96653 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
@@ -126,6 +126,7 @@ struct bfa_ioc_attr_s {
struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */
struct bfa_ioc_pci_attr_s pci_attr;
u8 port_id; /* port number */
+ u8 rsvd[7]; /*!< 64bit align */
};
/**
@@ -143,8 +144,8 @@ enum bfa_ioc_aen_event {
* BFA IOC level event data, now just a place holder
*/
struct bfa_ioc_aen_data_s {
- enum bfa_ioc_type_e ioc_type;
wwn_t pwwn;
+ s16 ioc_type;
mac_t mac;
};
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
index d76bcbd9820..c290fb13d2d 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
@@ -26,6 +26,8 @@
#define BFA_IOCFC_INTR_DELAY 1125
#define BFA_IOCFC_INTR_LATENCY 225
+#define BFA_IOCFCOE_INTR_DELAY 25
+#define BFA_IOCFCOE_INTR_LATENCY 5
/**
* Interrupt coalescing configuration.
@@ -50,7 +52,7 @@ struct bfa_iocfc_fwcfg_s {
u16 num_fcxp_reqs; /* unassisted FC exchanges */
u16 num_uf_bufs; /* unsolicited recv buffers */
u8 num_cqs;
- u8 rsvd;
+ u8 rsvd[5];
};
struct bfa_iocfc_drvcfg_s {
@@ -224,18 +226,24 @@ struct bfa_fw_port_physm_stats_s {
struct bfa_fw_fip_stats_s {
+ u32 vlan_req; /* vlan discovery requests */
+ u32 vlan_notify; /* vlan notifications */
+ u32 vlan_err; /* vlan response error */
+ u32 vlan_timeouts; /* vlan disvoery timeouts */
+ u32 vlan_invalids; /* invalid vlan in discovery advert. */
u32 disc_req; /* Discovery solicit requests */
u32 disc_rsp; /* Discovery solicit response */
u32 disc_err; /* Discovery advt. parse errors */
u32 disc_unsol; /* Discovery unsolicited */
u32 disc_timeouts; /* Discovery timeouts */
+ u32 disc_fcf_unavail; /* Discovery FCF Not Avail. */
u32 linksvc_unsupp; /* Unsupported link service req */
u32 linksvc_err; /* Parse error in link service req */
u32 logo_req; /* Number of FIP logos received */
u32 clrvlink_req; /* Clear virtual link req */
u32 op_unsupp; /* Unsupported FIP operation */
u32 untagged; /* Untagged frames (ignored) */
- u32 rsvd;
+ u32 invalid_version; /*!< Invalid FIP version */
};
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
index 7359f82aacf..0952a139c47 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
@@ -59,8 +59,8 @@ enum bfa_lport_aen_event {
*/
struct bfa_lport_aen_data_s {
u16 vf_id; /* vf_id of this logical port */
- u16 rsvd;
- enum bfa_port_role roles; /* Logical port mode,IM/TM/IP etc */
+ s16 roles; /* Logical port mode,IM/TM/IP etc */
+ u32 rsvd;
wwn_t ppwwn; /* WWN of its physical port */
wwn_t lpwwn; /* WWN of this logical port */
};
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
index 13fd4ab6aae..c5bd9c36ad4 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
@@ -22,7 +22,47 @@
/**
* Manufacturing block version
*/
-#define BFA_MFG_VERSION 1
+#define BFA_MFG_VERSION 2
+
+/**
+ * Manufacturing block encrypted version
+ */
+#define BFA_MFG_ENC_VER 2
+
+/**
+ * Manufacturing block version 1 length
+ */
+#define BFA_MFG_VER1_LEN 128
+
+/**
+ * Manufacturing block header length
+ */
+#define BFA_MFG_HDR_LEN 4
+
+/**
+ * Checksum size
+ */
+#define BFA_MFG_CHKSUM_SIZE 16
+
+/**
+ * Manufacturing block encrypted version
+ */
+#define BFA_MFG_ENC_VER 2
+
+/**
+ * Manufacturing block version 1 length
+ */
+#define BFA_MFG_VER1_LEN 128
+
+/**
+ * Manufacturing block header length
+ */
+#define BFA_MFG_HDR_LEN 4
+
+/**
+ * Checksum size
+ */
+#define BFA_MFG_CHKSUM_SIZE 16
/**
* Manufacturing block format
@@ -30,29 +70,74 @@
#define BFA_MFG_SERIALNUM_SIZE 11
#define BFA_MFG_PARTNUM_SIZE 14
#define BFA_MFG_SUPPLIER_ID_SIZE 10
-#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20
-#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20
-#define BFA_MFG_SUPPLIER_REVISION_SIZE 4
+#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20
+#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20
+#define BFA_MFG_SUPPLIER_REVISION_SIZE 4
#define STRSZ(_n) (((_n) + 4) & ~3)
/**
+ * Manufacturing card type
+ */
+enum {
+ BFA_MFG_TYPE_CB_MAX = 825, /* Crossbow card type max */
+ BFA_MFG_TYPE_FC8P2 = 825, /* 8G 2port FC card */
+ BFA_MFG_TYPE_FC8P1 = 815, /* 8G 1port FC card */
+ BFA_MFG_TYPE_FC4P2 = 425, /* 4G 2port FC card */
+ BFA_MFG_TYPE_FC4P1 = 415, /* 4G 1port FC card */
+ BFA_MFG_TYPE_CNA10P2 = 1020, /* 10G 2port CNA card */
+ BFA_MFG_TYPE_CNA10P1 = 1010, /* 10G 1port CNA card */
+};
+
+#pragma pack(1)
+
+/**
+ * Card type to port number conversion
+ */
+#define bfa_mfg_type2port_num(card_type) (((card_type) / 10) % 10)
+
+
+/**
+ * All numerical fields are in big-endian format.
+ */
+struct bfa_mfg_block_s {
+};
+
+/**
* VPD data length
*/
-#define BFA_MFG_VPD_LEN 256
+#define BFA_MFG_VPD_LEN 512
+
+#define BFA_MFG_VPD_PCI_HDR_OFF 137
+#define BFA_MFG_VPD_PCI_VER_MASK 0x07 /* version mask 3 bits */
+#define BFA_MFG_VPD_PCI_VDR_MASK 0xf8 /* vendor mask 5 bits */
+
+/**
+ * VPD vendor tag
+ */
+enum {
+ BFA_MFG_VPD_UNKNOWN = 0, /* vendor unknown */
+ BFA_MFG_VPD_IBM = 1, /* vendor IBM */
+ BFA_MFG_VPD_HP = 2, /* vendor HP */
+ BFA_MFG_VPD_DELL = 3, /* vendor DELL */
+ BFA_MFG_VPD_PCI_IBM = 0x08, /* PCI VPD IBM */
+ BFA_MFG_VPD_PCI_HP = 0x10, /* PCI VPD HP */
+ BFA_MFG_VPD_PCI_DELL = 0x20, /* PCI VPD DELL */
+ BFA_MFG_VPD_PCI_BRCD = 0xf8, /* PCI VPD Brocade */
+};
/**
* All numerical fields are in big-endian format.
*/
struct bfa_mfg_vpd_s {
- u8 version; /* vpd data version */
- u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */
- u8 chksum; /* u8 checksum */
- u8 vendor; /* vendor */
- u8 len; /* vpd data length excluding header */
- u8 rsv;
- u8 data[BFA_MFG_VPD_LEN]; /* vpd data */
+ u8 version; /* vpd data version */
+ u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */
+ u8 chksum; /* u8 checksum */
+ u8 vendor; /* vendor */
+ u8 len; /* vpd data length excluding header */
+ u8 rsv;
+ u8 data[BFA_MFG_VPD_LEN]; /* vpd data */
};
-#pragma pack(1)
+#pragma pack()
#endif /* __BFA_DEFS_MFG_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
index de0696c81bc..501bc9739d9 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_port.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
@@ -185,6 +185,8 @@ struct bfa_port_attr_s {
wwn_t fabric_name; /* attached switch's nwwn */
u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached
* fabric's ip addr */
+ struct mac_s fpma_mac; /* Lport's FPMA Mac address */
+ u16 authfail; /* auth failed state */
};
/**
@@ -232,14 +234,15 @@ enum bfa_port_aen_sfp_pom {
};
struct bfa_port_aen_data_s {
- enum bfa_ioc_type_e ioc_type;
- wwn_t pwwn; /* WWN of the physical port */
- wwn_t fwwn; /* WWN of the fabric port */
- mac_t mac; /* MAC addres of the ethernet port,
- * applicable to CNA port only */
- int phy_port_num; /*! For SFP related events */
- enum bfa_port_aen_sfp_pom level; /* Only transitions will
- * be informed */
+ wwn_t pwwn; /* WWN of the physical port */
+ wwn_t fwwn; /* WWN of the fabric port */
+ s32 phy_port_num; /*! For SFP related events */
+ s16 ioc_type;
+ s16 level; /* Only transitions will
+ * be informed */
+ struct mac_s mac; /* MAC address of the ethernet port,
+ * applicable to CNA port only */
+ s16 rsvd;
};
#endif /* __BFA_DEFS_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
index bf320412ee2..26e5cc78095 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
@@ -232,7 +232,7 @@ struct bfa_pport_attr_s {
u32 pid; /* port ID */
enum bfa_pport_type port_type; /* current topology */
u32 loopback; /* external loopback */
- u32 rsvd1;
+ u32 authfail; /* auth fail state */
u32 rsvd2; /* padding for 64 bit */
};
@@ -240,73 +240,79 @@ struct bfa_pport_attr_s {
* FC Port statistics.
*/
struct bfa_pport_fc_stats_s {
- u64 secs_reset; /* seconds since stats is reset */
- u64 tx_frames; /* transmitted frames */
- u64 tx_words; /* transmitted words */
- u64 rx_frames; /* received frames */
- u64 rx_words; /* received words */
- u64 lip_count; /* LIPs seen */
- u64 nos_count; /* NOS count */
- u64 error_frames; /* errored frames (sent?) */
- u64 dropped_frames; /* dropped frames */
- u64 link_failures; /* link failure count */
- u64 loss_of_syncs; /* loss of sync count */
- u64 loss_of_signals;/* loss of signal count */
- u64 primseq_errs; /* primitive sequence protocol */
- u64 bad_os_count; /* invalid ordered set */
- u64 err_enc_out; /* Encoding error outside frame */
- u64 invalid_crcs; /* frames received with invalid CRC*/
- u64 undersized_frm; /* undersized frames */
- u64 oversized_frm; /* oversized frames */
- u64 bad_eof_frm; /* frames with bad EOF */
- struct bfa_qos_stats_s qos_stats; /* QoS statistics */
+ u64 secs_reset; /* Seconds since stats is reset */
+ u64 tx_frames; /* Tx frames */
+ u64 tx_words; /* Tx words */
+ u64 tx_lip; /* TX LIP */
+ u64 tx_nos; /* Tx NOS */
+ u64 tx_ols; /* Tx OLS */
+ u64 tx_lr; /* Tx LR */
+ u64 tx_lrr; /* Tx LRR */
+ u64 rx_frames; /* Rx frames */
+ u64 rx_words; /* Rx words */
+ u64 lip_count; /* Rx LIP */
+ u64 nos_count; /* Rx NOS */
+ u64 ols_count; /* Rx OLS */
+ u64 lr_count; /* Rx LR */
+ u64 lrr_count; /* Rx LRR */
+ u64 invalid_crcs; /* Rx CRC err frames */
+ u64 invalid_crc_gd_eof; /* Rx CRC err good EOF frames */
+ u64 undersized_frm; /* Rx undersized frames */
+ u64 oversized_frm; /* Rx oversized frames */
+ u64 bad_eof_frm; /* Rx frames with bad EOF */
+ u64 error_frames; /* Errored frames */
+ u64 dropped_frames; /* Dropped frames */
+ u64 link_failures; /* Link Failure (LF) count */
+ u64 loss_of_syncs; /* Loss of sync count */
+ u64 loss_of_signals;/* Loss of signal count */
+ u64 primseq_errs; /* Primitive sequence protocol err. */
+ u64 bad_os_count; /* Invalid ordered sets */
+ u64 err_enc_out; /* Encoding err nonframe_8b10b */
+ u64 err_enc; /* Encoding err frame_8b10b */
};
/**
* Eth Port statistics.
*/
struct bfa_pport_eth_stats_s {
- u64 secs_reset; /* seconds since stats is reset */
- u64 frame_64; /* both rx and tx counter */
- u64 frame_65_127; /* both rx and tx counter */
- u64 frame_128_255; /* both rx and tx counter */
- u64 frame_256_511; /* both rx and tx counter */
- u64 frame_512_1023; /* both rx and tx counter */
- u64 frame_1024_1518; /* both rx and tx counter */
- u64 frame_1519_1522; /* both rx and tx counter */
-
- u64 tx_bytes;
- u64 tx_packets;
- u64 tx_mcast_packets;
- u64 tx_bcast_packets;
- u64 tx_control_frame;
- u64 tx_drop;
- u64 tx_jabber;
- u64 tx_fcs_error;
- u64 tx_fragments;
-
- u64 rx_bytes;
- u64 rx_packets;
- u64 rx_mcast_packets;
- u64 rx_bcast_packets;
- u64 rx_control_frames;
- u64 rx_unknown_opcode;
- u64 rx_drop;
- u64 rx_jabber;
- u64 rx_fcs_error;
- u64 rx_alignment_error;
- u64 rx_frame_length_error;
- u64 rx_code_error;
- u64 rx_fragments;
-
- u64 rx_pause; /* BPC */
- u64 rx_zero_pause; /* BPC Pause cancellation */
- u64 tx_pause; /* BPC */
- u64 tx_zero_pause; /* BPC Pause cancellation */
- u64 rx_fcoe_pause; /* BPC */
- u64 rx_fcoe_zero_pause; /* BPC Pause cancellation */
- u64 tx_fcoe_pause; /* BPC */
- u64 tx_fcoe_zero_pause; /* BPC Pause cancellation */
+ u64 secs_reset; /* Seconds since stats is reset */
+ u64 frame_64; /* Frames 64 bytes */
+ u64 frame_65_127; /* Frames 65-127 bytes */
+ u64 frame_128_255; /* Frames 128-255 bytes */
+ u64 frame_256_511; /* Frames 256-511 bytes */
+ u64 frame_512_1023; /* Frames 512-1023 bytes */
+ u64 frame_1024_1518; /* Frames 1024-1518 bytes */
+ u64 frame_1519_1522; /* Frames 1519-1522 bytes */
+ u64 tx_bytes; /* Tx bytes */
+ u64 tx_packets; /* Tx packets */
+ u64 tx_mcast_packets; /* Tx multicast packets */
+ u64 tx_bcast_packets; /* Tx broadcast packets */
+ u64 tx_control_frame; /* Tx control frame */
+ u64 tx_drop; /* Tx drops */
+ u64 tx_jabber; /* Tx jabber */
+ u64 tx_fcs_error; /* Tx FCS error */
+ u64 tx_fragments; /* Tx fragments */
+ u64 rx_bytes; /* Rx bytes */
+ u64 rx_packets; /* Rx packets */
+ u64 rx_mcast_packets; /* Rx multicast packets */
+ u64 rx_bcast_packets; /* Rx broadcast packets */
+ u64 rx_control_frames; /* Rx control frames */
+ u64 rx_unknown_opcode; /* Rx unknown opcode */
+ u64 rx_drop; /* Rx drops */
+ u64 rx_jabber; /* Rx jabber */
+ u64 rx_fcs_error; /* Rx FCS errors */
+ u64 rx_alignment_error; /* Rx alignment errors */
+ u64 rx_frame_length_error; /* Rx frame len errors */
+ u64 rx_code_error; /* Rx code errors */
+ u64 rx_fragments; /* Rx fragments */
+ u64 rx_pause; /* Rx pause */
+ u64 rx_zero_pause; /* Rx zero pause */
+ u64 tx_pause; /* Tx pause */
+ u64 tx_zero_pause; /* Tx zero pause */
+ u64 rx_fcoe_pause; /* Rx fcoe pause */
+ u64 rx_fcoe_zero_pause; /* Rx FCoE zero pause */
+ u64 tx_fcoe_pause; /* Tx FCoE pause */
+ u64 tx_fcoe_zero_pause; /* Tx FCoE zero pause */
};
/**
@@ -333,8 +339,7 @@ struct bfa_pport_fcpmap_s {
};
/**
- * Port RNID info.
- */
+ * Port RNI */
struct bfa_pport_rnid_s {
wwn_t wwn;
u32 unittype;
@@ -347,6 +352,23 @@ struct bfa_pport_rnid_s {
u16 topologydiscoveryflags;
};
+struct bfa_fcport_fcf_s {
+ wwn_t name; /* FCF name */
+ wwn_t fabric_name; /* Fabric Name */
+ u8 fipenabled; /* FIP enabled or not */
+ u8 fipfailed; /* FIP failed or not */
+ u8 resv[2];
+ u8 pri; /* FCF priority */
+ u8 version; /* FIP version used */
+ u8 available; /* Available for login */
+ u8 fka_disabled; /* FKA is disabled */
+ u8 maxsz_verified; /* FCoE max size verified */
+ u8 fc_map[3]; /* FC map */
+ u16 vlan; /* FCoE vlan tag/priority */
+ u32 fka_adv_per; /* FIP ka advert. period */
+ struct mac_s mac; /* FCF mac */
+};
+
/**
* Link state information
*/
@@ -378,6 +400,7 @@ struct bfa_pport_link_s {
struct fc_alpabm_s alpabm; /* alpa bitmap */
} loop_info;
} tl;
+ struct bfa_fcport_fcf_s fcf; /*!< FCF information (for FCoE) */
};
#endif /* __BFA_DEFS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
index cdceaeb9f4b..4374494bd56 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_status.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
@@ -180,8 +180,8 @@ enum bfa_status {
BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part
* of another team */
BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured.
- * Delete all VLANs before
- * creating team */
+ * Delete all VLANs to become
+ * part of the team */
BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured
* for adapters */
BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds
@@ -213,7 +213,7 @@ enum bfa_status {
* loaded */
BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */
BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */
- BFA_STATUS_NO_DRIVER = 133, /* Storage/Ethernet driver not loaded */
+ BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed or loaded */
BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */
BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */
BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */
@@ -228,8 +228,7 @@ enum bfa_status {
BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem
* handle Failed. Please try
* after some time */
- BFA_STATUS_IM_NOT_BOUND = 143, /* Brocade 10G Ethernet Service is not
- * Enabled on this port */
+ BFA_STATUS_IM_NOT_BOUND = 143, /* IM driver is not active */
BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient
* permissions to execute the BCU
* application */
@@ -242,6 +241,14 @@ enum bfa_status {
* failed */
BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation
* failed */
+ BFA_STATUS_IM_PORT_IN_TEAM = 150, /* Port is already part of the
+ * team */
+ BFA_STATUS_IM_VLAN_NOT_FOUND = 151, /* VLAN ID doesn't exists */
+ BFA_STATUS_IM_TEAM_NOT_FOUND = 152, /* Teaming configuration doesn't
+ * exists */
+ BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /* Given settings are not
+ * allowed for the current
+ * Teaming mode */
BFA_STATUS_MAX_VAL /* Unknown error code */
};
#define bfa_status_t enum bfa_status
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
index a6c70aee0aa..52585d3dd89 100644
--- a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
@@ -70,7 +70,6 @@ void bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv);
*/
void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv);
-void bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv);
void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv);
#endif /* __BFAD_FCB_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
index 627669c6554..f2fd35fdee2 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
@@ -49,6 +49,7 @@ struct bfa_fcs_s {
struct bfa_trc_mod_s *trcmod; /* tracing module */
struct bfa_aen_s *aen; /* aen component */
bfa_boolean_t vf_enabled; /* VF mode is enabled */
+ bfa_boolean_t fdmi_enabled; /*!< FDMI is enabled */
bfa_boolean_t min_cfg; /* min cfg enabled/disabled */
u16 port_vfid; /* port default VF ID */
struct bfa_fcs_driver_info_s driver_info;
@@ -60,10 +61,12 @@ struct bfa_fcs_s {
/*
* bfa fcs API functions
*/
-void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
+void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
bfa_boolean_t min_cfg);
+void bfa_fcs_init(struct bfa_fcs_s *fcs);
void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
struct bfa_fcs_driver_info_s *driver_info);
+void bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable);
void bfa_fcs_exit(struct bfa_fcs_s *fcs);
void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod);
void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod);
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
index 967ceb0eb07..ceaefd3060f 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
@@ -34,14 +34,6 @@ struct bfa_fcs_s;
struct bfa_fcs_fabric_s;
/*
-* @todo : need to move to a global config file.
- * Maximum Vports supported per physical port or vf.
- */
-#define BFA_FCS_MAX_VPORTS_SUPP_CB 255
-#define BFA_FCS_MAX_VPORTS_SUPP_CT 191
-
-/*
-* @todo : need to move to a global config file.
* Maximum Rports supported per port (physical/logical).
*/
#define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */
diff --git a/drivers/scsi/bfa/include/log/bfa_log_hal.h b/drivers/scsi/bfa/include/log/bfa_log_hal.h
index 0412aea2ec3..5f8f5e30b9e 100644
--- a/drivers/scsi/bfa/include/log/bfa_log_hal.h
+++ b/drivers/scsi/bfa/include/log/bfa_log_hal.h
@@ -27,4 +27,10 @@
(((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3)
#define BFA_LOG_HAL_SM_ASSERT \
(((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4)
+#define BFA_LOG_HAL_DRIVER_ERROR \
+ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 5)
+#define BFA_LOG_HAL_DRIVER_CONFIG_ERROR \
+ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 6)
+#define BFA_LOG_HAL_MBOX_ERROR \
+ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 7)
#endif
diff --git a/drivers/scsi/bfa/include/log/bfa_log_linux.h b/drivers/scsi/bfa/include/log/bfa_log_linux.h
index 317c0547ee1..bd451db4c30 100644
--- a/drivers/scsi/bfa/include/log/bfa_log_linux.h
+++ b/drivers/scsi/bfa/include/log/bfa_log_linux.h
@@ -41,4 +41,20 @@
(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10)
#define BFA_LOG_LINUX_SCSI_ABORT_COMP \
(((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11)
+#define BFA_LOG_LINUX_DRIVER_CONFIG_ERROR \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 12)
+#define BFA_LOG_LINUX_BNA_STATE_MACHINE \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 13)
+#define BFA_LOG_LINUX_IOC_ERROR \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 14)
+#define BFA_LOG_LINUX_RESOURCE_ALLOC_ERROR \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 15)
+#define BFA_LOG_LINUX_RING_BUFFER_ERROR \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 16)
+#define BFA_LOG_LINUX_DRIVER_ERROR \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 17)
+#define BFA_LOG_LINUX_DRIVER_DIAG \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 18)
+#define BFA_LOG_LINUX_DRIVER_AEN \
+ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 19)
#endif
diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h
index 14969eecf6a..8d1038035a7 100644
--- a/drivers/scsi/bfa/include/protocol/fc.h
+++ b/drivers/scsi/bfa/include/protocol/fc.h
@@ -50,6 +50,11 @@ struct fchs_s {
u32 ro; /* relative offset */
};
+
+#define FC_SOF_LEN 4
+#define FC_EOF_LEN 4
+#define FC_CRC_LEN 4
+
/*
* Fibre Channel BB_E Header Structure
*/
diff --git a/drivers/scsi/bfa/include/protocol/pcifw.h b/drivers/scsi/bfa/include/protocol/pcifw.h
deleted file mode 100644
index 6830dc3ee58..00000000000
--- a/drivers/scsi/bfa/include/protocol/pcifw.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) 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.
- */
-
-/**
- * pcifw.h PCI FW related headers
- */
-
-#ifndef __PCIFW_H__
-#define __PCIFW_H__
-
-#pragma pack(1)
-
-struct pnp_hdr_s{
- u32 signature; /* "$PnP" */
- u8 rev; /* Struct revision */
- u8 len; /* Header structure len in multiples
- * of 16 bytes */
- u16 off; /* Offset to next header 00 if none */
- u8 rsvd; /* Reserved byte */
- u8 cksum; /* 8-bit checksum for this header */
- u32 pnp_dev_id; /* PnP Device Id */
- u16 mfstr; /* Pointer to manufacturer string */
- u16 prstr; /* Pointer to product string */
- u8 devtype[3]; /* Device Type Code */
- u8 devind; /* Device Indicator */
- u16 bcventr; /* Bootstrap entry vector */
- u16 rsvd2; /* Reserved */
- u16 sriv; /* Static resource information vector */
-};
-
-struct pci_3_0_ds_s{
- u32 sig; /* Signature "PCIR" */
- u16 vendid; /* Vendor ID */
- u16 devid; /* Device ID */
- u16 devlistoff; /* Device List Offset */
- u16 len; /* PCI Data Structure Length */
- u8 rev; /* PCI Data Structure Revision */
- u8 clcode[3]; /* Class Code */
- u16 imglen; /* Code image length in multiples of
- * 512 bytes */
- u16 coderev; /* Revision level of code/data */
- u8 codetype; /* Code type 0x00 - BIOS */
- u8 indr; /* Last image indicator */
- u16 mrtimglen; /* Max Run Time Image Length */
- u16 cuoff; /* Config Utility Code Header Offset */
- u16 dmtfclp; /* DMTF CLP entry point offset */
-};
-
-struct pci_optrom_hdr_s{
- u16 sig; /* Signature 0x55AA */
- u8 len; /* Option ROM length in units of 512 bytes */
- u8 inivec[3]; /* Initialization vector */
- u8 rsvd[16]; /* Reserved field */
- u16 verptr; /* Pointer to version string - private */
- u16 pcids; /* Pointer to PCI data structure */
- u16 pnphdr; /* Pointer to PnP expansion header */
-};
-
-#pragma pack()
-
-#endif
diff --git a/drivers/scsi/bfa/loop.c b/drivers/scsi/bfa/loop.c
index f7c7f4f3c64..f6342efb6a9 100644
--- a/drivers/scsi/bfa/loop.c
+++ b/drivers/scsi/bfa/loop.c
@@ -162,7 +162,7 @@ bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa)
len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
bfa_fcs_port_get_fcid(port), 0,
port->port_cfg.pwwn, port->port_cfg.nwwn,
- bfa_pport_get_maxfrsize(port->fcs->bfa));
+ bfa_fcport_get_maxfrsize(port->fcs->bfa));
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs,
diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c
index 1e06792cd4c..d3907d184e2 100644
--- a/drivers/scsi/bfa/lport_api.c
+++ b/drivers/scsi/bfa/lport_api.c
@@ -156,7 +156,7 @@ bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
/*
* Get Physical port's current speed
*/
- bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+ bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
pport_speed = pport_attr.speed;
bfa_trc(fcs, pport_speed);
@@ -235,7 +235,8 @@ bfa_fcs_port_get_info(struct bfa_fcs_port_s *port,
port_info->port_wwn = bfa_fcs_port_get_pwwn(port);
port_info->node_wwn = bfa_fcs_port_get_nwwn(port);
- port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs);
+ port_info->max_vports_supp =
+ bfa_lps_get_max_vport(port->fcs->bfa);
port_info->num_vports_inuse =
bfa_fcs_fabric_vport_count(port->fabric);
port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c
index c96b3ca007a..5e8c8dee6c9 100644
--- a/drivers/scsi/bfa/ms.c
+++ b/drivers/scsi/bfa/ms.c
@@ -118,7 +118,7 @@ bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -141,7 +141,7 @@ bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -190,7 +190,7 @@ bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -216,7 +216,7 @@ bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -230,10 +230,6 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
switch (event) {
case MSSM_EVENT_PORT_OFFLINE:
bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
- /*
- * now invoke MS related sub-modules
- */
- bfa_fcs_port_fdmi_offline(ms);
break;
case MSSM_EVENT_PORT_FABRIC_RSCN:
@@ -243,7 +239,7 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -266,7 +262,7 @@ bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -304,7 +300,7 @@ bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -330,7 +326,7 @@ bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -466,7 +462,7 @@ bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -502,7 +498,7 @@ bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -528,7 +524,7 @@ bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ms->port->fcs, event);
}
}
@@ -637,7 +633,7 @@ bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_os_hton3b(FC_MGMT_SERVER),
bfa_fcs_port_get_fcid(port), 0,
port->port_cfg.pwwn, port->port_cfg.nwwn,
- bfa_pport_get_maxfrsize(port->fcs->bfa));
+ bfa_fcport_get_maxfrsize(port->fcs->bfa));
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
@@ -735,6 +731,7 @@ bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port)
ms->port = port;
bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
+ bfa_fcs_port_fdmi_offline(ms);
}
void
diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c
index 2f8b880060b..d20dd7e1574 100644
--- a/drivers/scsi/bfa/ns.c
+++ b/drivers/scsi/bfa/ns.c
@@ -164,7 +164,7 @@ bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -187,7 +187,7 @@ bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -221,7 +221,7 @@ bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -247,7 +247,7 @@ bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -270,7 +270,7 @@ bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -304,7 +304,7 @@ bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -330,7 +330,7 @@ bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -353,7 +353,7 @@ bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -390,7 +390,7 @@ bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -413,7 +413,7 @@ bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -436,7 +436,7 @@ bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -494,7 +494,7 @@ bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -517,7 +517,7 @@ bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
static void
@@ -539,7 +539,7 @@ bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -575,7 +575,7 @@ bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -598,7 +598,7 @@ bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -626,7 +626,7 @@ bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(ns->port->fcs, event);
}
}
@@ -660,7 +660,7 @@ bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_os_hton3b(FC_NAME_SERVER),
bfa_fcs_port_get_fcid(port), 0,
port->port_cfg.pwwn, port->port_cfg.nwwn,
- bfa_pport_get_maxfrsize(port->fcs->bfa));
+ bfa_fcport_get_maxfrsize(port->fcs->bfa));
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c
index 9cf58bb138d..7b096f2e383 100644
--- a/drivers/scsi/bfa/rport.c
+++ b/drivers/scsi/bfa/rport.c
@@ -19,6 +19,7 @@
* rport.c Remote port implementation.
*/
+#include <linux/slab.h>
#include <bfa.h>
#include <bfa_svc.h>
#include "fcbuild.h"
@@ -224,7 +225,7 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -276,7 +277,7 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -332,7 +333,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -406,7 +407,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -481,7 +482,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -534,7 +535,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -589,7 +590,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -646,7 +647,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -704,7 +705,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -754,7 +755,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -816,7 +817,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -846,7 +847,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -869,7 +870,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -905,7 +906,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -925,10 +926,17 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_HCB_OFFLINE:
case RPSM_EVENT_ADDRESS_CHANGE:
if (bfa_fcs_port_is_online(rport->port)) {
- bfa_sm_set_state(rport,
- bfa_fcs_rport_sm_nsdisc_sending);
- rport->ns_retries = 0;
- bfa_fcs_rport_send_gidpn(rport, NULL);
+ if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_nsdisc_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_gidpn(rport, NULL);
+ } else {
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_plogi_sending);
+ rport->plogi_retries = 0;
+ bfa_fcs_rport_send_plogi(rport, NULL);
+ }
} else {
rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
@@ -951,7 +959,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -1011,7 +1019,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -1038,7 +1046,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -1073,7 +1081,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -1132,7 +1140,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -1188,7 +1196,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -1249,7 +1257,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -1334,7 +1342,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -1366,7 +1374,7 @@ bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
bfa_fcs_port_get_fcid(port), 0,
port->port_cfg.pwwn, port->port_cfg.nwwn,
- bfa_pport_get_maxfrsize(port->fcs->bfa));
+ bfa_fcport_get_maxfrsize(port->fcs->bfa));
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
@@ -1478,7 +1486,7 @@ bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
bfa_fcs_port_get_fcid(port), rport->reply_oxid,
port->port_cfg.pwwn, port->port_cfg.nwwn,
- bfa_pport_get_maxfrsize(port->fcs->bfa));
+ bfa_fcport_get_maxfrsize(port->fcs->bfa));
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
@@ -1813,7 +1821,7 @@ bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
/*
* get curent speed from pport attributes from BFA
*/
- bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+ bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
@@ -2032,13 +2040,10 @@ bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
switch (event) {
case BFA_RPORT_AEN_ONLINE:
- bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr);
- break;
case BFA_RPORT_AEN_OFFLINE:
- bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr);
- break;
case BFA_RPORT_AEN_DISCONNECT:
- bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
+ bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, event),
+ rpwwn_ptr, lpwwn_ptr);
break;
case BFA_RPORT_AEN_QOS_PRIO:
aen_data.rport.priv.qos = data->priv.qos;
@@ -2164,7 +2169,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
bfa_trc(port->fcs, port->fabric->bb_credit);
port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred);
- bfa_pport_set_tx_bbcredit(port->fcs->bfa,
+ bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
port->fabric->bb_credit);
}
@@ -2575,23 +2580,6 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
}
/**
- * Module initialization
- */
-void
-bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- * Module cleanup
- */
-void
-bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs)
-{
- bfa_fcs_modexit_comp(fcs);
-}
-
-/**
* Return state of rport.
*/
int
diff --git a/drivers/scsi/bfa/rport_api.c b/drivers/scsi/bfa/rport_api.c
index 3dae1774181..a441f41d2a6 100644
--- a/drivers/scsi/bfa/rport_api.c
+++ b/drivers/scsi/bfa/rport_api.c
@@ -102,7 +102,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
rport_attr->qos_attr = qos_attr;
rport_attr->trl_enforced = BFA_FALSE;
- if (bfa_pport_is_ratelim(port->fcs->bfa)) {
+ if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) ||
(rport->rpf.rpsc_speed <
bfa_fcs_port_get_rport_max_speed(port)))
diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c
index e1932c885ac..ae7bba67ae2 100644
--- a/drivers/scsi/bfa/rport_ftrs.c
+++ b/drivers/scsi/bfa/rport_ftrs.c
@@ -91,7 +91,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -114,7 +114,7 @@ bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -160,7 +160,7 @@ bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -186,7 +186,7 @@ bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -206,7 +206,7 @@ bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
@@ -229,7 +229,7 @@ bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(rport->fcs, event);
}
}
/**
diff --git a/drivers/scsi/bfa/scn.c b/drivers/scsi/bfa/scn.c
index bd4771ff62c..8fe09ba88a9 100644
--- a/drivers/scsi/bfa/scn.c
+++ b/drivers/scsi/bfa/scn.c
@@ -90,7 +90,7 @@ bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(scn->port->fcs, event);
}
}
@@ -109,7 +109,7 @@ bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(scn->port->fcs, event);
}
}
@@ -137,7 +137,7 @@ bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(scn->port->fcs, event);
}
}
@@ -157,7 +157,7 @@ bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(scn->port->fcs, event);
}
}
@@ -171,7 +171,7 @@ bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(scn->port->fcs, event);
}
}
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c
index e90f1e38c32..27cd619a227 100644
--- a/drivers/scsi/bfa/vport.c
+++ b/drivers/scsi/bfa/vport.c
@@ -122,7 +122,7 @@ bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -165,7 +165,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -202,7 +202,7 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -249,7 +249,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -283,7 +283,7 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -310,7 +310,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -339,7 +339,7 @@ bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -387,7 +387,7 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -419,7 +419,7 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
break;
default:
- bfa_assert(0);
+ bfa_sm_fault(__vport_fcs(vport), event);
}
}
@@ -447,22 +447,8 @@ bfa_fcs_vport_aen_post(bfa_fcs_lport_t *port, enum bfa_lport_aen_event event)
bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
- switch (event) {
- case BFA_LPORT_AEN_NPIV_DUP_WWN:
- bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr,
- role_str[role / 2]);
- break;
- case BFA_LPORT_AEN_NPIV_FABRIC_MAX:
- bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr,
- role_str[role / 2]);
- break;
- case BFA_LPORT_AEN_NPIV_UNKNOWN:
- bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr,
- role_str[role / 2]);
- break;
- default:
- break;
- }
+ bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
+ role_str[role/2]);
aen_data.lport.vf_id = port->fabric->vf_id;
aen_data.lport.roles = role;
@@ -478,7 +464,7 @@ static void
bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
{
bfa_lps_fdisc(vport->lps, vport,
- bfa_pport_get_maxfrsize(__vport_bfa(vport)),
+ bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
__vport_pwwn(vport), __vport_nwwn(vport));
vport->vport_stats.fdisc_sent++;
}
@@ -617,38 +603,6 @@ bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
}
/**
- * Module initialization
- */
-void
-bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- * Module cleanup
- */
-void
-bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs)
-{
- bfa_fcs_modexit_comp(fcs);
-}
-
-u32
-bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs)
-{
- struct bfa_ioc_attr_s ioc_attr;
-
- bfa_get_attr(fcs->bfa, &ioc_attr);
-
- if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT)
- return BFA_FCS_MAX_VPORTS_SUPP_CT;
- else
- return BFA_FCS_MAX_VPORTS_SUPP_CB;
-}
-
-
-
-/**
* fcs_vport_api Virtual port API
*/
@@ -684,7 +638,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
return BFA_STATUS_VPORT_EXISTS;
if (bfa_fcs_fabric_vport_count(&fcs->fabric) ==
- bfa_fcs_vport_get_max(fcs))
+ bfa_lps_get_max_vport(fcs->bfa))
return BFA_STATUS_VPORT_MAX;
vport->lps = bfa_lps_alloc(fcs->bfa);
@@ -694,7 +648,8 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
vport->vport_drv = vport_drv;
bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
- bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport);
+ bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
+ bfa_fcs_lport_init(&vport->lport, vport_cfg);
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
@@ -888,4 +843,15 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
}
+/**
+ * Received clear virtual link
+ */
+void
+bfa_cb_lps_cvl_event(void *bfad, void *uarg)
+{
+ struct bfa_fcs_vport_s *vport = uarg;
+ /* Send an Offline followed by an ONLINE */
+ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
+ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
+}
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index 6cf9dc37d78..6b624e767d3 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -362,6 +362,7 @@ struct bnx2i_hba {
u32 num_ccell;
int ofld_conns_active;
+ wait_queue_head_t eh_wait;
int max_active_conns;
struct iscsi_cid_queue cid_que;
@@ -381,6 +382,7 @@ struct bnx2i_hba {
spinlock_t lock; /* protects hba structure access */
struct mutex net_dev_lock;/* sync net device access */
+ int hba_shutdown_tmo;
/*
* PCI related info.
*/
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 1af578dec27..18352ff8210 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -11,6 +11,7 @@
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
*/
+#include <linux/gfp.h>
#include <scsi/scsi_tcq.h>
#include <scsi/libiscsi.h>
#include "bnx2i.h"
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index 6d8172e781c..5d9296c599f 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -177,11 +177,22 @@ void bnx2i_stop(void *handle)
struct bnx2i_hba *hba = handle;
/* check if cleanup happened in GOING_DOWN context */
- clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN,
&hba->adapter_state))
iscsi_host_for_each_session(hba->shost,
bnx2i_drop_session);
+
+ /* Wait for all endpoints to be torn down, Chip will be reset once
+ * control returns to network driver. So it is required to cleanup and
+ * release all connection resources before returning from this routine.
+ */
+ wait_event_interruptible_timeout(hba->eh_wait,
+ (hba->ofld_conns_active == 0),
+ hba->hba_shutdown_tmo);
+ /* This flag should be cleared last so that ep_disconnect() gracefully
+ * cleans up connection context
+ */
+ clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
}
/**
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 1c4d1215769..fa68ab34b99 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -12,6 +12,7 @@
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
*/
+#include <linux/slab.h>
#include <scsi/scsi_tcq.h>
#include <scsi/libiscsi.h>
#include "bnx2i.h"
@@ -819,6 +820,11 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic)
spin_lock_init(&hba->lock);
mutex_init(&hba->net_dev_lock);
+ init_waitqueue_head(&hba->eh_wait);
+ if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
+ hba->hba_shutdown_tmo = 240 * HZ;
+ else /* 5706/5708/5709 */
+ hba->hba_shutdown_tmo = 30 * HZ;
if (iscsi_host_add(shost, &hba->pcidev->dev))
goto free_dump_mem;
@@ -1657,8 +1663,8 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
*/
hba = bnx2i_check_route(dst_addr);
- if (!hba) {
- rc = -ENOMEM;
+ if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) {
+ rc = -EINVAL;
goto check_busy;
}
@@ -1803,7 +1809,7 @@ static int bnx2i_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
(bnx2i_ep->state ==
EP_STATE_CONNECT_COMPL)),
msecs_to_jiffies(timeout_ms));
- if (!rc || (bnx2i_ep->state == EP_STATE_OFLD_FAILED))
+ if (bnx2i_ep->state == EP_STATE_OFLD_FAILED)
rc = -1;
if (rc > 0)
@@ -1956,6 +1962,8 @@ return_bnx2i_ep:
if (!hba->ofld_conns_active)
bnx2i_unreg_dev_all();
+
+ wake_up_interruptible(&hba->eh_wait);
}
@@ -1989,7 +1997,7 @@ static struct scsi_host_template bnx2i_host_template = {
.queuecommand = iscsi_queuecommand,
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler = iscsi_eh_device_reset,
- .eh_target_reset_handler = iscsi_eh_target_reset,
+ .eh_target_reset_handler = iscsi_eh_recover_target,
.change_queue_depth = iscsi_change_queue_depth,
.can_queue = 1024,
.max_sectors = 127,
diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c
index 5799cb5cba6..d40ea2f5be1 100644
--- a/drivers/scsi/bvme6000_scsi.c
+++ b/drivers/scsi/bvme6000_scsi.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <asm/bvme6000hw.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index fe11c1d4b31..4799d439120 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -23,6 +23,7 @@
#include <linux/mutex.h>
#include <linux/idr.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
index 344fd53b995..b58d9134ac1 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
@@ -10,6 +10,7 @@
* Written by: Karen Xie (kxie@chelsio.com)
*/
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/scatterlist.h>
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
index 87dd56b422b..6761b329124 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
@@ -13,6 +13,7 @@
#ifndef __CXGB3I_ULP2_DDP_H__
#define __CXGB3I_ULP2_DDP_H__
+#include <linux/slab.h>
#include <linux/vmalloc.h>
/**
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index 412853c6537..7b686abaae6 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -12,6 +12,7 @@
*/
#include <linux/inet.h>
+#include <linux/slab.h>
#include <linux/crypto.h>
#include <linux/if_vlan.h>
#include <net/dst.h>
@@ -915,7 +916,7 @@ static struct scsi_host_template cxgb3i_host_template = {
.cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler = iscsi_eh_device_reset,
- .eh_target_reset_handler = iscsi_eh_target_reset,
+ .eh_target_reset_handler = iscsi_eh_recover_target,
.target_alloc = iscsi_target_alloc,
.use_clustering = DISABLE_CLUSTERING,
.this_id = -1,
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c
index 3e08c430ff2..a175be9c496 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c
@@ -13,6 +13,7 @@
*/
#include <linux/if_vlan.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include "cxgb3_defs.h"
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
index 9c38539557f..dc5e3e77a35 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
@@ -12,6 +12,7 @@
* Written by: Karen Xie (kxie@chelsio.com)
*/
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/crypto.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 6c59c02c1ed..bd977be7544 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -57,6 +57,7 @@
#include <linux/pci.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <scsi/scsi.h>
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
index e19a1a55270..6fae3d285ae 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -21,6 +21,7 @@
* Mike Anderson <andmike@linux.vnet.ibm.com>
*/
+#include <linux/slab.h>
#include <scsi/scsi_dh.h>
#include "../scsi_priv.h"
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index bc9e94f5915..1a970a76b1b 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_dh.h>
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index 61966750bd6..e8a0bc3efd4 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -20,6 +20,7 @@
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_dh.h>
@@ -272,7 +273,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
int len = 0;
rq = blk_get_request(sdev->request_queue,
- (cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO);
+ (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO);
if (!rq) {
sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed");
return NULL;
@@ -286,14 +287,17 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
len = sizeof(short_trespass);
rq->cmd_flags |= REQ_RW;
rq->cmd[1] = 0x10;
+ rq->cmd[4] = len;
break;
case MODE_SELECT_10:
len = sizeof(long_trespass);
rq->cmd_flags |= REQ_RW;
rq->cmd[1] = 0x10;
+ rq->cmd[8] = len;
break;
case INQUIRY:
len = CLARIION_BUFFER_SIZE;
+ rq->cmd[4] = len;
memset(buffer, 0, len);
break;
default:
@@ -301,7 +305,6 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
break;
}
- rq->cmd[4] = len;
rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 857fdd6032b..e3916641e62 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -21,6 +21,7 @@
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_eh.h>
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 1a660191a90..5b683e42954 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -23,6 +23,7 @@
#include <scsi/scsi_eh.h>
#include <scsi/scsi_dh.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#define RDAC_NAME "rdac"
#define RDAC_RETRY_COUNT 5
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 496764349c4..0435d044c9d 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -188,7 +188,8 @@ MODULE_DEVICE_TABLE(pci,dptids);
static int adpt_detect(struct scsi_host_template* sht)
{
struct pci_dev *pDev = NULL;
- adpt_hba* pHba;
+ adpt_hba *pHba;
+ adpt_hba *next;
PINFO("Detecting Adaptec I2O RAID controllers...\n");
@@ -206,7 +207,8 @@ static int adpt_detect(struct scsi_host_template* sht)
}
/* In INIT state, Activate IOPs */
- for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ for (pHba = hba_chain; pHba; pHba = next) {
+ next = pHba->next;
// Activate does get status , init outbound, and get hrt
if (adpt_i2o_activate_hba(pHba) < 0) {
adpt_i2o_delete_hba(pHba);
@@ -243,7 +245,8 @@ rebuild_sys_tab:
PDEBUG("HBA's in OPERATIONAL state\n");
printk("dpti: If you have a lot of devices this could take a few minutes.\n");
- for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ for (pHba = hba_chain; pHba; pHba = next) {
+ next = pHba->next;
printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
if (adpt_i2o_lct_get(pHba) < 0){
adpt_i2o_delete_hba(pHba);
@@ -263,7 +266,8 @@ rebuild_sys_tab:
adpt_sysfs_class = NULL;
}
- for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ for (pHba = hba_chain; pHba; pHba = next) {
+ next = pHba->next;
if (adpt_scsi_host_alloc(pHba, sht) < 0){
adpt_i2o_delete_hba(pHba);
continue;
@@ -1229,11 +1233,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
}
}
pci_dev_put(pHba->pDev);
- kfree(pHba);
-
if (adpt_sysfs_class)
device_destroy(adpt_sysfs_class,
MKDEV(DPTI_I2O_MAJOR, pHba->unit));
+ kfree(pHba);
if(hba_count <= 0){
unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index 3c5abf7cd76..d1c31378f6d 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -490,6 +490,7 @@
#include <linux/ctype.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/dma.h>
#include <asm/io.h>
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
index 152dd15db27..60886c19065 100644
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -50,7 +50,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/in.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 2f47ae7cce9..f01b9b44e8a 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -26,6 +26,7 @@
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/fs.h>
#include <linux/sysfs.h>
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 511cb6b371e..3440da48d16 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -31,6 +31,7 @@
#include <linux/if_vlan.h>
#include <linux/errno.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <net/rtnetlink.h>
#include <scsi/fc/fc_els.h>
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index 85bd54c77b5..2ad95aa8f58 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -88,6 +88,7 @@
#include <linux/delay.h>
#include <linux/mca.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <scsi/scsicam.h>
#include <linux/mca-legacy.h>
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 32eef66114c..e296bcc57d5 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -279,6 +279,7 @@
#include <linux/stat.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <scsi/scsicam.h>
#include <asm/system.h>
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index 54f8d0e5407..5259888fbfb 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -17,6 +17,7 @@
*/
#include <linux/errno.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 507e26c1c29..97b212570bc 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/mempool.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pci.h>
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 65a39b0f6dc..3cc47c6e1ad 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -26,6 +26,7 @@
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
diff --git a/drivers/scsi/fnic/vnic_dev.c b/drivers/scsi/fnic/vnic_dev.c
index 56677064508..db710148d15 100644
--- a/drivers/scsi/fnic/vnic_dev.c
+++ b/drivers/scsi/fnic/vnic_dev.c
@@ -22,6 +22,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/if_ether.h>
+#include <linux/slab.h>
#include "vnic_resource.h"
#include "vnic_devcmd.h"
#include "vnic_dev.h"
diff --git a/drivers/scsi/fnic/vnic_rq.c b/drivers/scsi/fnic/vnic_rq.c
index bedd0d28563..fd2068f5ae1 100644
--- a/drivers/scsi/fnic/vnic_rq.c
+++ b/drivers/scsi/fnic/vnic_rq.c
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "vnic_dev.h"
#include "vnic_rq.h"
diff --git a/drivers/scsi/fnic/vnic_wq.c b/drivers/scsi/fnic/vnic_wq.c
index 1f9ea790d13..a414135460d 100644
--- a/drivers/scsi/fnic/vnic_wq.c
+++ b/drivers/scsi/fnic/vnic_wq.c
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "vnic_dev.h"
#include "vnic_wq.h"
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index ba3c94c9c25..35a4b3073ec 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -121,6 +121,7 @@
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#ifdef GDTH_RTC
#include <linux/mc146818rtc.h>
diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
index ffb2b21992b..0572b9bf4bd 100644
--- a/drivers/scsi/gdth_proc.c
+++ b/drivers/scsi/gdth_proc.c
@@ -3,6 +3,7 @@
*/
#include <linux/completion.h>
+#include <linux/slab.h>
int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length,
int inout)
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index 5d1bf7e3d24..48f406850c6 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -1,5 +1,6 @@
#include <linux/types.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 09dbcb847b7..6660fa92ffa 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/string.h>
#include <linux/mm.h>
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 03697ba9425..183d3a43c28 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -43,6 +43,7 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
#include <linux/cciss_ioctl.h>
#include <linux/string.h>
#include <linux/bitmap.h>
@@ -52,7 +53,7 @@
#include "hpsa.h"
/* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
-#define HPSA_DRIVER_VERSION "2.0.1-3"
+#define HPSA_DRIVER_VERSION "2.0.2-1"
#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
/* How long to wait (in milliseconds) for board to go into simple mode */
@@ -134,6 +135,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
static void hpsa_scan_start(struct Scsi_Host *);
static int hpsa_scan_finished(struct Scsi_Host *sh,
unsigned long elapsed_time);
+static int hpsa_change_queue_depth(struct scsi_device *sdev,
+ int qdepth, int reason);
static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
static int hpsa_slave_alloc(struct scsi_device *sdev);
@@ -182,8 +185,8 @@ static struct scsi_host_template hpsa_driver_template = {
.queuecommand = hpsa_scsi_queue_command,
.scan_start = hpsa_scan_start,
.scan_finished = hpsa_scan_finished,
+ .change_queue_depth = hpsa_change_queue_depth,
.this_id = -1,
- .sg_tablesize = MAXSGENTRIES,
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = hpsa_eh_device_reset_handler,
.ioctl = hpsa_ioctl,
@@ -208,133 +211,6 @@ static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh)
return (struct ctlr_info *) *priv;
}
-static struct task_struct *hpsa_scan_thread;
-static DEFINE_MUTEX(hpsa_scan_mutex);
-static LIST_HEAD(hpsa_scan_q);
-static int hpsa_scan_func(void *data);
-
-/**
- * add_to_scan_list() - add controller to rescan queue
- * @h: Pointer to the controller.
- *
- * Adds the controller to the rescan queue if not already on the queue.
- *
- * returns 1 if added to the queue, 0 if skipped (could be on the
- * queue already, or the controller could be initializing or shutting
- * down).
- **/
-static int add_to_scan_list(struct ctlr_info *h)
-{
- struct ctlr_info *test_h;
- int found = 0;
- int ret = 0;
-
- if (h->busy_initializing)
- return 0;
-
- /*
- * If we don't get the lock, it means the driver is unloading
- * and there's no point in scheduling a new scan.
- */
- if (!mutex_trylock(&h->busy_shutting_down))
- return 0;
-
- mutex_lock(&hpsa_scan_mutex);
- list_for_each_entry(test_h, &hpsa_scan_q, scan_list) {
- if (test_h == h) {
- found = 1;
- break;
- }
- }
- if (!found && !h->busy_scanning) {
- INIT_COMPLETION(h->scan_wait);
- list_add_tail(&h->scan_list, &hpsa_scan_q);
- ret = 1;
- }
- mutex_unlock(&hpsa_scan_mutex);
- mutex_unlock(&h->busy_shutting_down);
-
- return ret;
-}
-
-/**
- * remove_from_scan_list() - remove controller from rescan queue
- * @h: Pointer to the controller.
- *
- * Removes the controller from the rescan queue if present. Blocks if
- * the controller is currently conducting a rescan. The controller
- * can be in one of three states:
- * 1. Doesn't need a scan
- * 2. On the scan list, but not scanning yet (we remove it)
- * 3. Busy scanning (and not on the list). In this case we want to wait for
- * the scan to complete to make sure the scanning thread for this
- * controller is completely idle.
- **/
-static void remove_from_scan_list(struct ctlr_info *h)
-{
- struct ctlr_info *test_h, *tmp_h;
-
- mutex_lock(&hpsa_scan_mutex);
- list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) {
- if (test_h == h) { /* state 2. */
- list_del(&h->scan_list);
- complete_all(&h->scan_wait);
- mutex_unlock(&hpsa_scan_mutex);
- return;
- }
- }
- if (h->busy_scanning) { /* state 3. */
- mutex_unlock(&hpsa_scan_mutex);
- wait_for_completion(&h->scan_wait);
- } else { /* state 1, nothing to do. */
- mutex_unlock(&hpsa_scan_mutex);
- }
-}
-
-/* hpsa_scan_func() - kernel thread used to rescan controllers
- * @data: Ignored.
- *
- * A kernel thread used scan for drive topology changes on
- * controllers. The thread processes only one controller at a time
- * using a queue. Controllers are added to the queue using
- * add_to_scan_list() and removed from the queue either after done
- * processing or using remove_from_scan_list().
- *
- * returns 0.
- **/
-static int hpsa_scan_func(__attribute__((unused)) void *data)
-{
- struct ctlr_info *h;
- int host_no;
-
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- if (kthread_should_stop())
- break;
-
- while (1) {
- mutex_lock(&hpsa_scan_mutex);
- if (list_empty(&hpsa_scan_q)) {
- mutex_unlock(&hpsa_scan_mutex);
- break;
- }
- h = list_entry(hpsa_scan_q.next, struct ctlr_info,
- scan_list);
- list_del(&h->scan_list);
- h->busy_scanning = 1;
- mutex_unlock(&hpsa_scan_mutex);
- host_no = h->scsi_host ? h->scsi_host->host_no : -1;
- hpsa_scan_start(h->scsi_host);
- complete_all(&h->scan_wait);
- mutex_lock(&hpsa_scan_mutex);
- h->busy_scanning = 0;
- mutex_unlock(&hpsa_scan_mutex);
- }
- }
- return 0;
-}
-
static int check_for_unit_attention(struct ctlr_info *h,
struct CommandList *c)
{
@@ -352,21 +228,8 @@ static int check_for_unit_attention(struct ctlr_info *h,
break;
case REPORT_LUNS_CHANGED:
dev_warn(&h->pdev->dev, "hpsa%d: report LUN data "
- "changed\n", h->ctlr);
+ "changed, action required\n", h->ctlr);
/*
- * Here, we could call add_to_scan_list and wake up the scan thread,
- * except that it's quite likely that we will get more than one
- * REPORT_LUNS_CHANGED condition in quick succession, which means
- * that those which occur after the first one will likely happen
- * *during* the hpsa_scan_thread's rescan. And the rescan code is not
- * robust enough to restart in the middle, undoing what it has already
- * done, and it's not clear that it's even possible to do this, since
- * part of what it does is notify the SCSI mid layer, which starts
- * doing it's own i/o to read partition tables and so on, and the
- * driver doesn't have visibility to know what might need undoing.
- * In any event, if possible, it is horribly complicated to get right
- * so we just don't do it for now.
- *
* Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
*/
break;
@@ -393,10 +256,7 @@ static ssize_t host_store_rescan(struct device *dev,
struct ctlr_info *h;
struct Scsi_Host *shost = class_to_shost(dev);
h = shost_to_hba(shost);
- if (add_to_scan_list(h)) {
- wake_up_process(hpsa_scan_thread);
- wait_for_completion_interruptible(&h->scan_wait);
- }
+ hpsa_scan_start(h->scsi_host);
return count;
}
@@ -983,6 +843,76 @@ static void hpsa_scsi_setup(struct ctlr_info *h)
spin_lock_init(&h->devlock);
}
+static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
+{
+ int i;
+
+ if (!h->cmd_sg_list)
+ return;
+ for (i = 0; i < h->nr_cmds; i++) {
+ kfree(h->cmd_sg_list[i]);
+ h->cmd_sg_list[i] = NULL;
+ }
+ kfree(h->cmd_sg_list);
+ h->cmd_sg_list = NULL;
+}
+
+static int hpsa_allocate_sg_chain_blocks(struct ctlr_info *h)
+{
+ int i;
+
+ if (h->chainsize <= 0)
+ return 0;
+
+ h->cmd_sg_list = kzalloc(sizeof(*h->cmd_sg_list) * h->nr_cmds,
+ GFP_KERNEL);
+ if (!h->cmd_sg_list)
+ return -ENOMEM;
+ for (i = 0; i < h->nr_cmds; i++) {
+ h->cmd_sg_list[i] = kmalloc(sizeof(*h->cmd_sg_list[i]) *
+ h->chainsize, GFP_KERNEL);
+ if (!h->cmd_sg_list[i])
+ goto clean;
+ }
+ return 0;
+
+clean:
+ hpsa_free_sg_chain_blocks(h);
+ return -ENOMEM;
+}
+
+static void hpsa_map_sg_chain_block(struct ctlr_info *h,
+ struct CommandList *c)
+{
+ struct SGDescriptor *chain_sg, *chain_block;
+ u64 temp64;
+
+ chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
+ chain_block = h->cmd_sg_list[c->cmdindex];
+ chain_sg->Ext = HPSA_SG_CHAIN;
+ chain_sg->Len = sizeof(*chain_sg) *
+ (c->Header.SGTotal - h->max_cmd_sg_entries);
+ temp64 = pci_map_single(h->pdev, chain_block, chain_sg->Len,
+ PCI_DMA_TODEVICE);
+ chain_sg->Addr.lower = (u32) (temp64 & 0x0FFFFFFFFULL);
+ chain_sg->Addr.upper = (u32) ((temp64 >> 32) & 0x0FFFFFFFFULL);
+}
+
+static void hpsa_unmap_sg_chain_block(struct ctlr_info *h,
+ struct CommandList *c)
+{
+ struct SGDescriptor *chain_sg;
+ union u64bit temp64;
+
+ if (c->Header.SGTotal <= h->max_cmd_sg_entries)
+ return;
+
+ chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
+ temp64.val32.lower = chain_sg->Addr.lower;
+ temp64.val32.upper = chain_sg->Addr.upper;
+ pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
+}
+
static void complete_scsi_command(struct CommandList *cp,
int timeout, u32 tag)
{
@@ -999,10 +929,12 @@ static void complete_scsi_command(struct CommandList *cp,
h = cp->h;
scsi_dma_unmap(cmd); /* undo the DMA mappings */
+ if (cp->Header.SGTotal > h->max_cmd_sg_entries)
+ hpsa_unmap_sg_chain_block(h, cp);
cmd->result = (DID_OK << 16); /* host byte */
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
- cmd->result |= (ei->ScsiStatus << 1);
+ cmd->result |= ei->ScsiStatus;
/* copy the sense data whether we need to or not. */
memcpy(cmd->sense_buffer, ei->SenseInfo,
@@ -1203,6 +1135,7 @@ static int hpsa_scsi_detect(struct ctlr_info *h)
sh->max_id = HPSA_MAX_LUN;
sh->can_queue = h->nr_cmds;
sh->cmd_per_lun = h->nr_cmds;
+ sh->sg_tablesize = h->maxsgentries;
h->scsi_host = sh;
sh->hostdata[0] = (unsigned long) h;
sh->irq = h->intr[PERF_MODE_INT];
@@ -1382,7 +1315,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr)
if (c == NULL) { /* trouble... */
dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
- return -1;
+ return -ENOMEM;
}
fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG);
@@ -1904,16 +1837,17 @@ out:
* dma mapping and fills in the scatter gather entries of the
* hpsa command, cp.
*/
-static int hpsa_scatter_gather(struct pci_dev *pdev,
+static int hpsa_scatter_gather(struct ctlr_info *h,
struct CommandList *cp,
struct scsi_cmnd *cmd)
{
unsigned int len;
struct scatterlist *sg;
u64 addr64;
- int use_sg, i;
+ int use_sg, i, sg_index, chained;
+ struct SGDescriptor *curr_sg;
- BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
+ BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
use_sg = scsi_dma_map(cmd);
if (use_sg < 0)
@@ -1922,15 +1856,33 @@ static int hpsa_scatter_gather(struct pci_dev *pdev,
if (!use_sg)
goto sglist_finished;
+ curr_sg = cp->SG;
+ chained = 0;
+ sg_index = 0;
scsi_for_each_sg(cmd, sg, use_sg, i) {
+ if (i == h->max_cmd_sg_entries - 1 &&
+ use_sg > h->max_cmd_sg_entries) {
+ chained = 1;
+ curr_sg = h->cmd_sg_list[cp->cmdindex];
+ sg_index = 0;
+ }
addr64 = (u64) sg_dma_address(sg);
len = sg_dma_len(sg);
- cp->SG[i].Addr.lower =
- (u32) (addr64 & (u64) 0x00000000FFFFFFFF);
- cp->SG[i].Addr.upper =
- (u32) ((addr64 >> 32) & (u64) 0x00000000FFFFFFFF);
- cp->SG[i].Len = len;
- cp->SG[i].Ext = 0; /* we are not chaining */
+ curr_sg->Addr.lower = (u32) (addr64 & 0x0FFFFFFFFULL);
+ curr_sg->Addr.upper = (u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
+ curr_sg->Len = len;
+ curr_sg->Ext = 0; /* we are not chaining */
+ curr_sg++;
+ }
+
+ if (use_sg + chained > h->maxSG)
+ h->maxSG = use_sg + chained;
+
+ if (chained) {
+ cp->Header.SGList = h->max_cmd_sg_entries;
+ cp->Header.SGTotal = (u16) (use_sg + 1);
+ hpsa_map_sg_chain_block(h, cp);
+ return 0;
}
sglist_finished:
@@ -2026,7 +1978,7 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
break;
}
- if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */
+ if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */
cmd_free(h, c);
return SCSI_MLQUEUE_HOST_BUSY;
}
@@ -2077,6 +2029,23 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
return finished;
}
+static int hpsa_change_queue_depth(struct scsi_device *sdev,
+ int qdepth, int reason)
+{
+ struct ctlr_info *h = sdev_to_hba(sdev);
+
+ if (reason != SCSI_QDEPTH_DEFAULT)
+ return -ENOTSUPP;
+
+ if (qdepth < 1)
+ qdepth = 1;
+ else
+ if (qdepth > h->nr_cmds)
+ qdepth = h->nr_cmds;
+ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+ return sdev->queue_depth;
+}
+
static void hpsa_unregister_scsi(struct ctlr_info *h)
{
/* we are being forcibly unloaded, and may not refuse. */
@@ -2961,7 +2930,7 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
return IRQ_HANDLED;
}
-/* Send a message CDB to the firmwart. */
+/* Send a message CDB to the firmware. */
static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
unsigned char type)
{
@@ -3296,7 +3265,7 @@ default_int_mode:
h->intr[PERF_MODE_INT] = pdev->irq;
}
-static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
+static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
{
ushort subsystem_vendor_id, subsystem_device_id, command;
u32 board_id, scratchpad = 0;
@@ -3405,6 +3374,23 @@ static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
h->board_id = board_id;
h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+ h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements));
+
+ /*
+ * Limit in-command s/g elements to 32 save dma'able memory.
+ * Howvever spec says if 0, use 31
+ */
+
+ h->max_cmd_sg_entries = 31;
+ if (h->maxsgentries > 512) {
+ h->max_cmd_sg_entries = 32;
+ h->chainsize = h->maxsgentries - h->max_cmd_sg_entries + 1;
+ h->maxsgentries--; /* save one for chain pointer */
+ } else {
+ h->maxsgentries = 31; /* default to traditional values */
+ h->chainsize = 0;
+ }
+
h->product_name = products[prod_index].product_name;
h->access = *(products[prod_index].access);
/* Allow room for some ioctls */
@@ -3532,8 +3518,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
h->busy_initializing = 1;
INIT_HLIST_HEAD(&h->cmpQ);
INIT_HLIST_HEAD(&h->reqQ);
- mutex_init(&h->busy_shutting_down);
- init_completion(&h->scan_wait);
rc = hpsa_pci_init(h, pdev);
if (rc != 0)
goto clean1;
@@ -3587,6 +3571,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
rc = -ENOMEM;
goto clean4;
}
+ if (hpsa_allocate_sg_chain_blocks(h))
+ goto clean4;
spin_lock_init(&h->lock);
spin_lock_init(&h->scan_lock);
init_waitqueue_head(&h->scan_wait_queue);
@@ -3609,6 +3595,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
return 1;
clean4:
+ hpsa_free_sg_chain_blocks(h);
kfree(h->cmd_pool_bits);
if (h->cmd_pool)
pci_free_consistent(h->pdev,
@@ -3681,11 +3668,10 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
return;
}
h = pci_get_drvdata(pdev);
- mutex_lock(&h->busy_shutting_down);
- remove_from_scan_list(h);
hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */
hpsa_shutdown(pdev);
iounmap(h->vaddr);
+ hpsa_free_sg_chain_blocks(h);
pci_free_consistent(h->pdev,
h->nr_cmds * sizeof(struct CommandList),
h->cmd_pool, h->cmd_pool_dhandle);
@@ -3703,7 +3689,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
*/
pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
- mutex_unlock(&h->busy_shutting_down);
kfree(h);
}
@@ -3857,23 +3842,12 @@ clean_up:
*/
static int __init hpsa_init(void)
{
- int err;
- /* Start the scan thread */
- hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan");
- if (IS_ERR(hpsa_scan_thread)) {
- err = PTR_ERR(hpsa_scan_thread);
- return -ENODEV;
- }
- err = pci_register_driver(&hpsa_pci_driver);
- if (err)
- kthread_stop(hpsa_scan_thread);
- return err;
+ return pci_register_driver(&hpsa_pci_driver);
}
static void __exit hpsa_cleanup(void)
{
pci_unregister_driver(&hpsa_pci_driver);
- kthread_stop(hpsa_scan_thread);
}
module_init(hpsa_init);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index a0502b3ac17..1bb5233b09a 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -83,6 +83,10 @@ struct ctlr_info {
unsigned int maxQsinceinit;
unsigned int maxSG;
spinlock_t lock;
+ int maxsgentries;
+ u8 max_cmd_sg_entries;
+ int chainsize;
+ struct SGDescriptor **cmd_sg_list;
/* pointers to command and error info pool */
struct CommandList *cmd_pool;
@@ -97,9 +101,6 @@ struct ctlr_info {
int scan_finished;
spinlock_t scan_lock;
wait_queue_head_t scan_wait_queue;
- struct mutex busy_shutting_down;
- struct list_head scan_list;
- struct completion scan_wait;
struct Scsi_Host *scsi_host;
spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 3e0abdf7668..56fb9827681 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -23,7 +23,8 @@
/* general boundary defintions */
#define SENSEINFOBYTES 32 /* may vary between hbas */
-#define MAXSGENTRIES 31
+#define MAXSGENTRIES 32
+#define HPSA_SG_CHAIN 0x80000000
#define MAXREPLYQS 256
/* Command Status value */
@@ -305,20 +306,23 @@ struct CommandList {
int cmd_type;
long cmdindex;
struct hlist_node list;
- struct CommandList *prev;
- struct CommandList *next;
struct request *rq;
struct completion *waiting;
- int retry_count;
void *scsi_cmd;
/* on 64 bit architectures, to get this to be 32-byte-aligned
- * it so happens we need no padding, on 32 bit systems,
- * we need 8 bytes of padding. This does that.
+ * it so happens we need PAD_64 bytes of padding, on 32 bit systems,
+ * we need PAD_32 bytes of padding (see below). This does that.
+ * If it happens that 64 bit and 32 bit systems need different
+ * padding, PAD_32 and PAD_64 can be set independently, and.
+ * the code below will do the right thing.
*/
-#define COMMANDLIST_PAD ((8 - sizeof(long))/4 * 8)
+#define IS_32_BIT ((8 - sizeof(long))/4)
+#define IS_64_BIT (!IS_32_BIT)
+#define PAD_32 (4)
+#define PAD_64 (4)
+#define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
u8 pad[COMMANDLIST_PAD];
-
};
/* Configuration Table Structure */
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 4f0556571f8..645f7cdf21a 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/div64.h>
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 732f6d35b4a..c2eea711a5c 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -28,7 +28,9 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/pm.h>
#include <linux/stringify.h>
#include <asm/firmware.h>
#include <asm/irq.h>
@@ -4736,6 +4738,27 @@ static int ibmvfc_remove(struct vio_dev *vdev)
}
/**
+ * ibmvfc_resume - Resume from suspend
+ * @dev: device struct
+ *
+ * We may have lost an interrupt across suspend/resume, so kick the
+ * interrupt handler
+ *
+ */
+static int ibmvfc_resume(struct device *dev)
+{
+ unsigned long flags;
+ struct ibmvfc_host *vhost = dev_get_drvdata(dev);
+ struct vio_dev *vdev = to_vio_dev(dev);
+
+ spin_lock_irqsave(vhost->host->host_lock, flags);
+ vio_disable_interrupts(vdev);
+ tasklet_schedule(&vhost->tasklet);
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+ return 0;
+}
+
+/**
* ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver
* @vdev: vio device struct
*
@@ -4755,6 +4778,10 @@ static struct vio_device_id ibmvfc_device_table[] __devinitdata = {
};
MODULE_DEVICE_TABLE(vio, ibmvfc_device_table);
+static struct dev_pm_ops ibmvfc_pm_ops = {
+ .resume = ibmvfc_resume
+};
+
static struct vio_driver ibmvfc_driver = {
.id_table = ibmvfc_device_table,
.probe = ibmvfc_probe,
@@ -4763,6 +4790,7 @@ static struct vio_driver ibmvfc_driver = {
.driver = {
.name = IBMVFC_NAME,
.owner = THIS_MODULE,
+ .pm = &ibmvfc_pm_ops,
}
};
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index e3a18e0ef27..88bad0e81bd 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -70,7 +70,9 @@
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/pm.h>
#include <asm/firmware.h>
#include <asm/vio.h>
#include <scsi/scsi.h>
@@ -321,16 +323,6 @@ static void set_srp_direction(struct scsi_cmnd *cmd,
srp_cmd->buf_fmt = fmt;
}
-static void unmap_sg_list(int num_entries,
- struct device *dev,
- struct srp_direct_buf *md)
-{
- int i;
-
- for (i = 0; i < num_entries; ++i)
- dma_unmap_single(dev, md[i].va, md[i].len, DMA_BIDIRECTIONAL);
-}
-
/**
* unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format
* @cmd: srp_cmd whose additional_data member will be unmapped
@@ -348,24 +340,9 @@ static void unmap_cmd_data(struct srp_cmd *cmd,
if (out_fmt == SRP_NO_DATA_DESC && in_fmt == SRP_NO_DATA_DESC)
return;
- else if (out_fmt == SRP_DATA_DESC_DIRECT ||
- in_fmt == SRP_DATA_DESC_DIRECT) {
- struct srp_direct_buf *data =
- (struct srp_direct_buf *) cmd->add_data;
- dma_unmap_single(dev, data->va, data->len, DMA_BIDIRECTIONAL);
- } else {
- struct srp_indirect_buf *indirect =
- (struct srp_indirect_buf *) cmd->add_data;
- int num_mapped = indirect->table_desc.len /
- sizeof(struct srp_direct_buf);
-
- if (num_mapped <= MAX_INDIRECT_BUFS) {
- unmap_sg_list(num_mapped, dev, &indirect->desc_list[0]);
- return;
- }
- unmap_sg_list(num_mapped, dev, evt_struct->ext_list);
- }
+ if (evt_struct->cmnd)
+ scsi_dma_unmap(evt_struct->cmnd);
}
static int map_sg_list(struct scsi_cmnd *cmd, int nseg,
@@ -1991,6 +1968,19 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
}
/**
+ * ibmvscsi_resume: Resume from suspend
+ * @dev: device struct
+ *
+ * We may have lost an interrupt across suspend/resume, so kick the
+ * interrupt handler
+ */
+static int ibmvscsi_resume(struct device *dev)
+{
+ struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev);
+ return ibmvscsi_ops->resume(hostdata);
+}
+
+/**
* ibmvscsi_device_table: Used by vio.c to match devices in the device tree we
* support.
*/
@@ -2000,6 +1990,10 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = {
};
MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
+static struct dev_pm_ops ibmvscsi_pm_ops = {
+ .resume = ibmvscsi_resume
+};
+
static struct vio_driver ibmvscsi_driver = {
.id_table = ibmvscsi_device_table,
.probe = ibmvscsi_probe,
@@ -2008,6 +2002,7 @@ static struct vio_driver ibmvscsi_driver = {
.driver = {
.name = "ibmvscsi",
.owner = THIS_MODULE,
+ .pm = &ibmvscsi_pm_ops,
}
};
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
index 76425303def..9cb7c6a773e 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -120,6 +120,7 @@ struct ibmvscsi_ops {
struct ibmvscsi_host_data *hostdata);
int (*send_crq)(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2);
+ int (*resume) (struct ibmvscsi_host_data *hostdata);
};
extern struct ibmvscsi_ops iseriesvscsi_ops;
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c
index d5eaf972710..e2056d517e9 100644
--- a/drivers/scsi/ibmvscsi/ibmvstgt.c
+++ b/drivers/scsi/ibmvscsi/ibmvstgt.c
@@ -23,6 +23,7 @@
*/
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_srp.h>
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c
index 0775fdee5fa..f4776451a75 100644
--- a/drivers/scsi/ibmvscsi/iseries_vscsi.c
+++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c
@@ -158,10 +158,16 @@ static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
0);
}
+static int iseriesvscsi_resume(struct ibmvscsi_host_data *hostdata)
+{
+ return 0;
+}
+
struct ibmvscsi_ops iseriesvscsi_ops = {
.init_crq_queue = iseriesvscsi_init_crq_queue,
.release_crq_queue = iseriesvscsi_release_crq_queue,
.reset_crq_queue = iseriesvscsi_reset_crq_queue,
.reenable_crq_queue = iseriesvscsi_reenable_crq_queue,
.send_crq = iseriesvscsi_send_crq,
+ .resume = iseriesvscsi_resume,
};
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 462a8574dad..a864ccc0a34 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -32,6 +32,7 @@
#include <asm/iommu.h>
#include <asm/hvcall.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <linux/interrupt.h>
#include "ibmvscsi.h"
@@ -334,10 +335,23 @@ static int rpavscsi_reenable_crq_queue(struct crq_queue *queue,
return rc;
}
+/**
+ * rpavscsi_resume: - resume after suspend
+ * @hostdata: ibmvscsi_host_data of host
+ *
+ */
+static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata)
+{
+ vio_disable_interrupts(to_vio_dev(hostdata->dev));
+ tasklet_schedule(&hostdata->srp_task);
+ return 0;
+}
+
struct ibmvscsi_ops rpavscsi_ops = {
.init_crq_queue = rpavscsi_init_crq_queue,
.release_crq_queue = rpavscsi_release_crq_queue,
.reset_crq_queue = rpavscsi_reset_crq_queue,
.reenable_crq_queue = rpavscsi_reenable_crq_queue,
.send_crq = rpavscsi_send_crq,
+ .resume = rpavscsi_resume,
};
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index c2a9a13d788..4734ab0b3ff 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -15,6 +15,7 @@
#include <linux/parport.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <scsi/scsi.h>
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index 89a59484be0..a7714160fbc 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -531,7 +531,7 @@ static void initio_read_eeprom(unsigned long base)
* initio_stop_bm - stop bus master
* @host: InitIO we are stopping
*
- * Stop any pending DMA operation, aborting the DMA if neccessary
+ * Stop any pending DMA operation, aborting the DMA if necessary
*/
static void initio_stop_bm(struct initio_host * host)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 032f0d0e6cb..520461b9bc0 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -59,6 +59,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/pci.h>
@@ -72,6 +73,8 @@
#include <linux/moduleparam.h>
#include <linux/libata.h>
#include <linux/hdreg.h>
+#include <linux/reboot.h>
+#include <linux/stringify.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/processor.h>
@@ -91,8 +94,8 @@ static unsigned int ipr_max_speed = 1;
static int ipr_testmode = 0;
static unsigned int ipr_fastfail = 0;
static unsigned int ipr_transop_timeout = 0;
-static unsigned int ipr_enable_cache = 1;
static unsigned int ipr_debug = 0;
+static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS;
static unsigned int ipr_dual_ioa_raid = 1;
static DEFINE_SPINLOCK(ipr_driver_lock);
@@ -104,13 +107,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
{
.set_interrupt_mask_reg = 0x0022C,
.clr_interrupt_mask_reg = 0x00230,
+ .clr_interrupt_mask_reg32 = 0x00230,
.sense_interrupt_mask_reg = 0x0022C,
+ .sense_interrupt_mask_reg32 = 0x0022C,
.clr_interrupt_reg = 0x00228,
+ .clr_interrupt_reg32 = 0x00228,
.sense_interrupt_reg = 0x00224,
+ .sense_interrupt_reg32 = 0x00224,
.ioarrin_reg = 0x00404,
.sense_uproc_interrupt_reg = 0x00214,
+ .sense_uproc_interrupt_reg32 = 0x00214,
.set_uproc_interrupt_reg = 0x00214,
- .clr_uproc_interrupt_reg = 0x00218
+ .set_uproc_interrupt_reg32 = 0x00214,
+ .clr_uproc_interrupt_reg = 0x00218,
+ .clr_uproc_interrupt_reg32 = 0x00218
}
},
{ /* Snipe and Scamp */
@@ -119,25 +129,59 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
{
.set_interrupt_mask_reg = 0x00288,
.clr_interrupt_mask_reg = 0x0028C,
+ .clr_interrupt_mask_reg32 = 0x0028C,
.sense_interrupt_mask_reg = 0x00288,
+ .sense_interrupt_mask_reg32 = 0x00288,
.clr_interrupt_reg = 0x00284,
+ .clr_interrupt_reg32 = 0x00284,
.sense_interrupt_reg = 0x00280,
+ .sense_interrupt_reg32 = 0x00280,
.ioarrin_reg = 0x00504,
.sense_uproc_interrupt_reg = 0x00290,
+ .sense_uproc_interrupt_reg32 = 0x00290,
.set_uproc_interrupt_reg = 0x00290,
- .clr_uproc_interrupt_reg = 0x00294
+ .set_uproc_interrupt_reg32 = 0x00290,
+ .clr_uproc_interrupt_reg = 0x00294,
+ .clr_uproc_interrupt_reg32 = 0x00294
+ }
+ },
+ { /* CRoC */
+ .mailbox = 0x00040,
+ .cache_line_size = 0x20,
+ {
+ .set_interrupt_mask_reg = 0x00010,
+ .clr_interrupt_mask_reg = 0x00018,
+ .clr_interrupt_mask_reg32 = 0x0001C,
+ .sense_interrupt_mask_reg = 0x00010,
+ .sense_interrupt_mask_reg32 = 0x00014,
+ .clr_interrupt_reg = 0x00008,
+ .clr_interrupt_reg32 = 0x0000C,
+ .sense_interrupt_reg = 0x00000,
+ .sense_interrupt_reg32 = 0x00004,
+ .ioarrin_reg = 0x00070,
+ .sense_uproc_interrupt_reg = 0x00020,
+ .sense_uproc_interrupt_reg32 = 0x00024,
+ .set_uproc_interrupt_reg = 0x00020,
+ .set_uproc_interrupt_reg32 = 0x00024,
+ .clr_uproc_interrupt_reg = 0x00028,
+ .clr_uproc_interrupt_reg32 = 0x0002C,
+ .init_feedback_reg = 0x0005C,
+ .dump_addr_reg = 0x00064,
+ .dump_data_reg = 0x00068
}
},
};
static const struct ipr_chip_t ipr_chip[] = {
- { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] },
- { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] }
+ { 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] }
};
static int ipr_max_bus_speeds [] = {
@@ -156,12 +200,13 @@ module_param_named(fastfail, ipr_fastfail, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries");
module_param_named(transop_timeout, ipr_transop_timeout, int, 0);
MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)");
-module_param_named(enable_cache, ipr_enable_cache, int, 0);
-MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)");
module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)");
module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0);
MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)");
+module_param_named(max_devs, ipr_max_devs, int, 0);
+MODULE_PARM_DESC(max_devs, "Specify the maximum number of physical devices. "
+ "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]");
MODULE_LICENSE("GPL");
MODULE_VERSION(IPR_DRIVER_VERSION);
@@ -180,6 +225,20 @@ struct ipr_error_table_t ipr_error_table[] = {
"FFFE: Soft device bus error recovered by the IOA"},
{0x01088100, 0, IPR_DEFAULT_LOG_LEVEL,
"4101: Soft device bus fabric error"},
+ {0x01100100, 0, IPR_DEFAULT_LOG_LEVEL,
+ "FFFC: Logical block guard error recovered by the device"},
+ {0x01100300, 0, IPR_DEFAULT_LOG_LEVEL,
+ "FFFC: Logical block reference tag error recovered by the device"},
+ {0x01108300, 0, IPR_DEFAULT_LOG_LEVEL,
+ "4171: Recovered scatter list tag / sequence number error"},
+ {0x01109000, 0, IPR_DEFAULT_LOG_LEVEL,
+ "FF3D: Recovered logical block CRC error on IOA to Host transfer"},
+ {0x01109200, 0, IPR_DEFAULT_LOG_LEVEL,
+ "4171: Recovered logical block sequence number error on IOA to Host transfer"},
+ {0x0110A000, 0, IPR_DEFAULT_LOG_LEVEL,
+ "FFFD: Recovered logical block reference tag error detected by the IOA"},
+ {0x0110A100, 0, IPR_DEFAULT_LOG_LEVEL,
+ "FFFD: Logical block guard error recovered by the IOA"},
{0x01170600, 0, IPR_DEFAULT_LOG_LEVEL,
"FFF9: Device sector reassign successful"},
{0x01170900, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -236,12 +295,28 @@ struct ipr_error_table_t ipr_error_table[] = {
"3120: SCSI bus is not operational"},
{0x04088100, 0, IPR_DEFAULT_LOG_LEVEL,
"4100: Hard device bus fabric error"},
+ {0x04100100, 0, IPR_DEFAULT_LOG_LEVEL,
+ "310C: Logical block guard error detected by the device"},
+ {0x04100300, 0, IPR_DEFAULT_LOG_LEVEL,
+ "310C: Logical block reference tag error detected by the device"},
+ {0x04108300, 1, IPR_DEFAULT_LOG_LEVEL,
+ "4170: Scatter list tag / sequence number error"},
+ {0x04109000, 1, IPR_DEFAULT_LOG_LEVEL,
+ "8150: Logical block CRC error on IOA to Host transfer"},
+ {0x04109200, 1, IPR_DEFAULT_LOG_LEVEL,
+ "4170: Logical block sequence number error on IOA to Host transfer"},
+ {0x0410A000, 0, IPR_DEFAULT_LOG_LEVEL,
+ "310D: Logical block reference tag error detected by the IOA"},
+ {0x0410A100, 0, IPR_DEFAULT_LOG_LEVEL,
+ "310D: Logical block guard error detected by the IOA"},
{0x04118000, 0, IPR_DEFAULT_LOG_LEVEL,
"9000: IOA reserved area data check"},
{0x04118100, 0, IPR_DEFAULT_LOG_LEVEL,
"9001: IOA reserved area invalid data pattern"},
{0x04118200, 0, IPR_DEFAULT_LOG_LEVEL,
"9002: IOA reserved area LRC error"},
+ {0x04118300, 1, IPR_DEFAULT_LOG_LEVEL,
+ "Hardware Error, IOA metadata access error"},
{0x04320000, 0, IPR_DEFAULT_LOG_LEVEL,
"102E: Out of alternate sectors for disk storage"},
{0x04330000, 1, IPR_DEFAULT_LOG_LEVEL,
@@ -306,6 +381,8 @@ struct ipr_error_table_t ipr_error_table[] = {
"Illegal request, commands not allowed to this device"},
{0x05258100, 0, 0,
"Illegal request, command not allowed to a secondary adapter"},
+ {0x05258200, 0, 0,
+ "Illegal request, command not allowed to a non-optimized resource"},
{0x05260000, 0, 0,
"Illegal request, invalid field in parameter list"},
{0x05260100, 0, 0,
@@ -468,7 +545,10 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
trace_entry->time = jiffies;
trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
trace_entry->type = type;
- trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command;
+ if (ipr_cmd->ioa_cfg->sis64)
+ trace_entry->ata_op_code = ipr_cmd->i.ata_ioadl.regs.command;
+ else
+ trace_entry->ata_op_code = ipr_cmd->ioarcb.u.add_data.u.regs.command;
trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff;
trace_entry->res_handle = ipr_cmd->ioarcb.res_handle;
trace_entry->u.add_data = add_data;
@@ -488,16 +568,23 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
- dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr);
+ dma_addr_t dma_addr = ipr_cmd->dma_addr;
memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
- ioarcb->write_data_transfer_length = 0;
+ ioarcb->data_transfer_length = 0;
ioarcb->read_data_transfer_length = 0;
- ioarcb->write_ioadl_len = 0;
+ ioarcb->ioadl_len = 0;
ioarcb->read_ioadl_len = 0;
- ioarcb->write_ioadl_addr =
- cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
- ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+
+ if (ipr_cmd->ioa_cfg->sis64)
+ ioarcb->u.sis64_addr_data.data_ioadl_addr =
+ cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+ else {
+ ioarcb->write_ioadl_addr =
+ cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+ ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+ }
+
ioasa->ioasc = 0;
ioasa->residual_data_len = 0;
ioasa->u.gata.status = 0;
@@ -562,10 +649,15 @@ static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg,
ioa_cfg->allow_interrupts = 0;
/* Set interrupt mask to stop all new interrupts */
- writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
+ if (ioa_cfg->sis64)
+ writeq(~0, ioa_cfg->regs.set_interrupt_mask_reg);
+ else
+ writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
/* Clear any pending interrupts */
- writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg);
+ if (ioa_cfg->sis64)
+ writel(~0, ioa_cfg->regs.clr_interrupt_reg);
+ writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg32);
int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
}
@@ -693,6 +785,35 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg)
}
/**
+ * ipr_send_command - Send driver initiated requests.
+ * @ipr_cmd: ipr command struct
+ *
+ * This function sends a command to the adapter using the correct write call.
+ * In the case of sis64, calculate the ioarcb size required. Then or in the
+ * appropriate bits.
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_send_command(struct ipr_cmnd *ipr_cmd)
+{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+ dma_addr_t send_dma_addr = ipr_cmd->dma_addr;
+
+ if (ioa_cfg->sis64) {
+ /* The default size is 256 bytes */
+ send_dma_addr |= 0x1;
+
+ /* If the number of ioadls * size of ioadl > 128 bytes,
+ then use a 512 byte ioarcb */
+ if (ipr_cmd->dma_use_sg * sizeof(struct ipr_ioadl64_desc) > 128 )
+ send_dma_addr |= 0x4;
+ writeq(send_dma_addr, ioa_cfg->regs.ioarrin_reg);
+ } else
+ writel(send_dma_addr, ioa_cfg->regs.ioarrin_reg);
+}
+
+/**
* ipr_do_req - Send driver initiated requests.
* @ipr_cmd: ipr command struct
* @done: done function
@@ -724,8 +845,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd,
ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0);
mb();
- writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
- ioa_cfg->regs.ioarrin_reg);
+
+ ipr_send_command(ipr_cmd);
}
/**
@@ -747,6 +868,51 @@ static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd)
}
/**
+ * ipr_init_ioadl - initialize the ioadl for the correct SIS type
+ * @ipr_cmd: ipr command struct
+ * @dma_addr: dma address
+ * @len: transfer length
+ * @flags: ioadl flag value
+ *
+ * This function initializes an ioadl in the case where there is only a single
+ * descriptor.
+ *
+ * Return value:
+ * nothing
+ **/
+static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr,
+ u32 len, int flags)
+{
+ struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
+ struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+
+ ipr_cmd->dma_use_sg = 1;
+
+ if (ipr_cmd->ioa_cfg->sis64) {
+ ioadl64->flags = cpu_to_be32(flags);
+ ioadl64->data_len = cpu_to_be32(len);
+ ioadl64->address = cpu_to_be64(dma_addr);
+
+ ipr_cmd->ioarcb.ioadl_len =
+ cpu_to_be32(sizeof(struct ipr_ioadl64_desc));
+ ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len);
+ } else {
+ ioadl->flags_and_data_len = cpu_to_be32(flags | len);
+ ioadl->address = cpu_to_be32(dma_addr);
+
+ if (flags == IPR_IOADL_FLAGS_READ_LAST) {
+ ipr_cmd->ioarcb.read_ioadl_len =
+ cpu_to_be32(sizeof(struct ipr_ioadl_desc));
+ ipr_cmd->ioarcb.read_data_transfer_length = cpu_to_be32(len);
+ } else {
+ ipr_cmd->ioarcb.ioadl_len =
+ cpu_to_be32(sizeof(struct ipr_ioadl_desc));
+ ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len);
+ }
+ }
+}
+
+/**
* ipr_send_blocking_cmd - Send command and sleep on its completion.
* @ipr_cmd: ipr command struct
* @timeout_func: function to invoke if command times out
@@ -803,11 +969,8 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff;
ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff;
- ioarcb->read_data_transfer_length = cpu_to_be32(sizeof(hostrcb->hcam));
- ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
- ipr_cmd->ioadl[0].flags_and_data_len =
- cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(hostrcb->hcam));
- ipr_cmd->ioadl[0].address = cpu_to_be32(hostrcb->hostrcb_dma);
+ ipr_init_ioadl(ipr_cmd, hostrcb->hostrcb_dma,
+ sizeof(hostrcb->hcam), IPR_IOADL_FLAGS_READ_LAST);
if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE)
ipr_cmd->done = ipr_process_ccn;
@@ -817,22 +980,54 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR);
mb();
- writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
- ioa_cfg->regs.ioarrin_reg);
+
+ ipr_send_command(ipr_cmd);
} else {
list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q);
}
}
/**
+ * ipr_update_ata_class - Update the ata class in the resource entry
+ * @res: resource entry struct
+ * @proto: cfgte device bus protocol value
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_update_ata_class(struct ipr_resource_entry *res, unsigned int proto)
+{
+ switch(proto) {
+ case IPR_PROTO_SATA:
+ case IPR_PROTO_SAS_STP:
+ res->ata_class = ATA_DEV_ATA;
+ break;
+ case IPR_PROTO_SATA_ATAPI:
+ case IPR_PROTO_SAS_STP_ATAPI:
+ res->ata_class = ATA_DEV_ATAPI;
+ break;
+ default:
+ res->ata_class = ATA_DEV_UNKNOWN;
+ break;
+ };
+}
+
+/**
* ipr_init_res_entry - Initialize a resource entry struct.
* @res: resource entry struct
+ * @cfgtew: config table entry wrapper struct
*
* Return value:
* none
**/
-static void ipr_init_res_entry(struct ipr_resource_entry *res)
+static void ipr_init_res_entry(struct ipr_resource_entry *res,
+ struct ipr_config_table_entry_wrapper *cfgtew)
{
+ int found = 0;
+ unsigned int proto;
+ struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg;
+ struct ipr_resource_entry *gscsi_res = NULL;
+
res->needs_sync_complete = 0;
res->in_erp = 0;
res->add_to_ml = 0;
@@ -840,6 +1035,205 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res)
res->resetting_device = 0;
res->sdev = NULL;
res->sata_port = NULL;
+
+ if (ioa_cfg->sis64) {
+ proto = cfgtew->u.cfgte64->proto;
+ res->res_flags = cfgtew->u.cfgte64->res_flags;
+ res->qmodel = IPR_QUEUEING_MODEL64(res);
+ res->type = cfgtew->u.cfgte64->res_type & 0x0f;
+
+ memcpy(res->res_path, &cfgtew->u.cfgte64->res_path,
+ sizeof(res->res_path));
+
+ res->bus = 0;
+ res->lun = scsilun_to_int(&res->dev_lun);
+
+ if (res->type == IPR_RES_TYPE_GENERIC_SCSI) {
+ list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) {
+ if (gscsi_res->dev_id == cfgtew->u.cfgte64->dev_id) {
+ found = 1;
+ res->target = gscsi_res->target;
+ break;
+ }
+ }
+ if (!found) {
+ res->target = find_first_zero_bit(ioa_cfg->target_ids,
+ ioa_cfg->max_devs_supported);
+ set_bit(res->target, ioa_cfg->target_ids);
+ }
+
+ memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
+ sizeof(res->dev_lun.scsi_lun));
+ } else if (res->type == IPR_RES_TYPE_IOAFP) {
+ res->bus = IPR_IOAFP_VIRTUAL_BUS;
+ res->target = 0;
+ } else if (res->type == IPR_RES_TYPE_ARRAY) {
+ res->bus = IPR_ARRAY_VIRTUAL_BUS;
+ res->target = find_first_zero_bit(ioa_cfg->array_ids,
+ ioa_cfg->max_devs_supported);
+ set_bit(res->target, ioa_cfg->array_ids);
+ } else if (res->type == IPR_RES_TYPE_VOLUME_SET) {
+ res->bus = IPR_VSET_VIRTUAL_BUS;
+ res->target = find_first_zero_bit(ioa_cfg->vset_ids,
+ ioa_cfg->max_devs_supported);
+ set_bit(res->target, ioa_cfg->vset_ids);
+ } else {
+ res->target = find_first_zero_bit(ioa_cfg->target_ids,
+ ioa_cfg->max_devs_supported);
+ set_bit(res->target, ioa_cfg->target_ids);
+ }
+ } else {
+ proto = cfgtew->u.cfgte->proto;
+ res->qmodel = IPR_QUEUEING_MODEL(res);
+ res->flags = cfgtew->u.cfgte->flags;
+ if (res->flags & IPR_IS_IOA_RESOURCE)
+ res->type = IPR_RES_TYPE_IOAFP;
+ else
+ res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f;
+
+ res->bus = cfgtew->u.cfgte->res_addr.bus;
+ res->target = cfgtew->u.cfgte->res_addr.target;
+ res->lun = cfgtew->u.cfgte->res_addr.lun;
+ }
+
+ ipr_update_ata_class(res, proto);
+}
+
+/**
+ * ipr_is_same_device - Determine if two devices are the same.
+ * @res: resource entry struct
+ * @cfgtew: config table entry wrapper struct
+ *
+ * Return value:
+ * 1 if the devices are the same / 0 otherwise
+ **/
+static int ipr_is_same_device(struct ipr_resource_entry *res,
+ struct ipr_config_table_entry_wrapper *cfgtew)
+{
+ if (res->ioa_cfg->sis64) {
+ if (!memcmp(&res->dev_id, &cfgtew->u.cfgte64->dev_id,
+ sizeof(cfgtew->u.cfgte64->dev_id)) &&
+ !memcmp(&res->lun, &cfgtew->u.cfgte64->lun,
+ sizeof(cfgtew->u.cfgte64->lun))) {
+ return 1;
+ }
+ } else {
+ if (res->bus == cfgtew->u.cfgte->res_addr.bus &&
+ res->target == cfgtew->u.cfgte->res_addr.target &&
+ res->lun == cfgtew->u.cfgte->res_addr.lun)
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * ipr_format_resource_path - Format the resource path for printing.
+ * @res_path: resource path
+ * @buf: buffer
+ *
+ * Return value:
+ * pointer to buffer
+ **/
+static char *ipr_format_resource_path(u8 *res_path, char *buffer)
+{
+ int i;
+
+ sprintf(buffer, "%02X", res_path[0]);
+ for (i=1; res_path[i] != 0xff; i++)
+ sprintf(buffer, "%s-%02X", buffer, res_path[i]);
+
+ return buffer;
+}
+
+/**
+ * ipr_update_res_entry - Update the resource entry.
+ * @res: resource entry struct
+ * @cfgtew: config table entry wrapper struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_update_res_entry(struct ipr_resource_entry *res,
+ struct ipr_config_table_entry_wrapper *cfgtew)
+{
+ char buffer[IPR_MAX_RES_PATH_LENGTH];
+ unsigned int proto;
+ int new_path = 0;
+
+ if (res->ioa_cfg->sis64) {
+ res->flags = cfgtew->u.cfgte64->flags;
+ res->res_flags = cfgtew->u.cfgte64->res_flags;
+ res->type = cfgtew->u.cfgte64->res_type & 0x0f;
+
+ memcpy(&res->std_inq_data, &cfgtew->u.cfgte64->std_inq_data,
+ sizeof(struct ipr_std_inq_data));
+
+ res->qmodel = IPR_QUEUEING_MODEL64(res);
+ proto = cfgtew->u.cfgte64->proto;
+ res->res_handle = cfgtew->u.cfgte64->res_handle;
+ res->dev_id = cfgtew->u.cfgte64->dev_id;
+
+ memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
+ sizeof(res->dev_lun.scsi_lun));
+
+ if (memcmp(res->res_path, &cfgtew->u.cfgte64->res_path,
+ sizeof(res->res_path))) {
+ memcpy(res->res_path, &cfgtew->u.cfgte64->res_path,
+ sizeof(res->res_path));
+ new_path = 1;
+ }
+
+ if (res->sdev && new_path)
+ sdev_printk(KERN_INFO, res->sdev, "Resource path: %s\n",
+ ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+ } else {
+ res->flags = cfgtew->u.cfgte->flags;
+ if (res->flags & IPR_IS_IOA_RESOURCE)
+ res->type = IPR_RES_TYPE_IOAFP;
+ else
+ res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f;
+
+ memcpy(&res->std_inq_data, &cfgtew->u.cfgte->std_inq_data,
+ sizeof(struct ipr_std_inq_data));
+
+ res->qmodel = IPR_QUEUEING_MODEL(res);
+ proto = cfgtew->u.cfgte->proto;
+ res->res_handle = cfgtew->u.cfgte->res_handle;
+ }
+
+ ipr_update_ata_class(res, proto);
+}
+
+/**
+ * ipr_clear_res_target - Clear the bit in the bit map representing the target
+ * for the resource.
+ * @res: resource entry struct
+ * @cfgtew: config table entry wrapper struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_clear_res_target(struct ipr_resource_entry *res)
+{
+ struct ipr_resource_entry *gscsi_res = NULL;
+ struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg;
+
+ if (!ioa_cfg->sis64)
+ return;
+
+ if (res->bus == IPR_ARRAY_VIRTUAL_BUS)
+ clear_bit(res->target, ioa_cfg->array_ids);
+ else if (res->bus == IPR_VSET_VIRTUAL_BUS)
+ clear_bit(res->target, ioa_cfg->vset_ids);
+ else if (res->bus == 0 && res->type == IPR_RES_TYPE_GENERIC_SCSI) {
+ list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue)
+ if (gscsi_res->dev_id == res->dev_id && gscsi_res != res)
+ return;
+ clear_bit(res->target, ioa_cfg->target_ids);
+
+ } else if (res->bus == 0)
+ clear_bit(res->target, ioa_cfg->target_ids);
}
/**
@@ -851,17 +1245,24 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res)
* none
**/
static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
- struct ipr_hostrcb *hostrcb)
+ struct ipr_hostrcb *hostrcb)
{
struct ipr_resource_entry *res = NULL;
- struct ipr_config_table_entry *cfgte;
+ struct ipr_config_table_entry_wrapper cfgtew;
+ __be32 cc_res_handle;
+
u32 is_ndn = 1;
- cfgte = &hostrcb->hcam.u.ccn.cfgte;
+ if (ioa_cfg->sis64) {
+ cfgtew.u.cfgte64 = &hostrcb->hcam.u.ccn.u.cfgte64;
+ cc_res_handle = cfgtew.u.cfgte64->res_handle;
+ } else {
+ cfgtew.u.cfgte = &hostrcb->hcam.u.ccn.u.cfgte;
+ cc_res_handle = cfgtew.u.cfgte->res_handle;
+ }
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
- if (!memcmp(&res->cfgte.res_addr, &cfgte->res_addr,
- sizeof(cfgte->res_addr))) {
+ if (res->res_handle == cc_res_handle) {
is_ndn = 0;
break;
}
@@ -879,20 +1280,22 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
struct ipr_resource_entry, queue);
list_del(&res->queue);
- ipr_init_res_entry(res);
+ ipr_init_res_entry(res, &cfgtew);
list_add_tail(&res->queue, &ioa_cfg->used_res_q);
}
- memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry));
+ ipr_update_res_entry(res, &cfgtew);
if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) {
if (res->sdev) {
res->del_from_ml = 1;
- res->cfgte.res_handle = IPR_INVALID_RES_HANDLE;
+ res->res_handle = IPR_INVALID_RES_HANDLE;
if (ioa_cfg->allow_ml_add_del)
schedule_work(&ioa_cfg->work_q);
- } else
+ } else {
+ ipr_clear_res_target(res);
list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+ }
} else if (!res->sdev) {
res->add_to_ml = 1;
if (ioa_cfg->allow_ml_add_del)
@@ -1044,8 +1447,12 @@ static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd)
static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg,
struct ipr_hostrcb *hostrcb)
{
- struct ipr_hostrcb_type_12_error *error =
- &hostrcb->hcam.u.error.u.type_12_error;
+ struct ipr_hostrcb_type_12_error *error;
+
+ if (ioa_cfg->sis64)
+ error = &hostrcb->hcam.u.error64.u.type_12_error;
+ else
+ error = &hostrcb->hcam.u.error.u.type_12_error;
ipr_err("-----Current Configuration-----\n");
ipr_err("Cache Directory Card Information:\n");
@@ -1138,6 +1545,48 @@ static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg,
}
/**
+ * ipr_log_sis64_config_error - Log a device error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ int errors_logged, i;
+ struct ipr_hostrcb64_device_data_entry_enhanced *dev_entry;
+ struct ipr_hostrcb_type_23_error *error;
+ char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+ error = &hostrcb->hcam.u.error64.u.type_23_error;
+ errors_logged = be32_to_cpu(error->errors_logged);
+
+ ipr_err("Device Errors Detected/Logged: %d/%d\n",
+ be32_to_cpu(error->errors_detected), errors_logged);
+
+ dev_entry = error->dev;
+
+ for (i = 0; i < errors_logged; i++, dev_entry++) {
+ ipr_err_separator;
+
+ ipr_err("Device %d : %s", i + 1,
+ ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0]));
+ ipr_log_ext_vpd(&dev_entry->vpd);
+
+ ipr_err("-----New Device Information-----\n");
+ ipr_log_ext_vpd(&dev_entry->new_vpd);
+
+ ipr_err("Cache Directory Card Information:\n");
+ ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd);
+
+ ipr_err("Adapter Card Information:\n");
+ ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd);
+ }
+}
+
+/**
* ipr_log_config_error - Log a configuration error.
* @ioa_cfg: ioa config struct
* @hostrcb: hostrcb struct
@@ -1331,7 +1780,11 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
{
struct ipr_hostrcb_type_17_error *error;
- error = &hostrcb->hcam.u.error.u.type_17_error;
+ if (ioa_cfg->sis64)
+ error = &hostrcb->hcam.u.error64.u.type_17_error;
+ else
+ error = &hostrcb->hcam.u.error.u.type_17_error;
+
error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
strim(error->failure_reason);
@@ -1438,6 +1891,42 @@ static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb,
fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
}
+/**
+ * ipr_log64_fabric_path - Log a fabric path error
+ * @hostrcb: hostrcb struct
+ * @fabric: fabric descriptor
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb,
+ struct ipr_hostrcb64_fabric_desc *fabric)
+{
+ int i, j;
+ u8 path_state = fabric->path_state;
+ u8 active = path_state & IPR_PATH_ACTIVE_MASK;
+ u8 state = path_state & IPR_PATH_STATE_MASK;
+ char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+ for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) {
+ if (path_active_desc[i].active != active)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) {
+ if (path_state_desc[j].state != state)
+ continue;
+
+ ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n",
+ path_active_desc[i].desc, path_state_desc[j].desc,
+ ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
+ return;
+ }
+ }
+
+ ipr_err("Path state=%02X Resource Path=%s\n", path_state,
+ ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
+}
+
static const struct {
u8 type;
char *desc;
@@ -1547,6 +2036,49 @@ static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb,
}
/**
+ * ipr_log64_path_elem - Log a fabric path element.
+ * @hostrcb: hostrcb struct
+ * @cfg: fabric path element struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb,
+ struct ipr_hostrcb64_config_element *cfg)
+{
+ int i, j;
+ u8 desc_id = cfg->descriptor_id & IPR_DESCRIPTOR_MASK;
+ u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK;
+ u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK;
+ char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+ if (type == IPR_PATH_CFG_NOT_EXIST || desc_id != IPR_DESCRIPTOR_SIS64)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) {
+ if (path_type_desc[i].type != type)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) {
+ if (path_status_desc[j].status != status)
+ continue;
+
+ ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n",
+ path_status_desc[j].desc, path_type_desc[i].desc,
+ ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
+ link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+ be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+ return;
+ }
+ }
+ ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s "
+ "WWN=%08X%08X\n", cfg->type_status,
+ ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
+ link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+ be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+}
+
+/**
* ipr_log_fabric_error - Log a fabric error.
* @ioa_cfg: ioa config struct
* @hostrcb: hostrcb struct
@@ -1584,6 +2116,96 @@ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
}
/**
+ * ipr_log_sis64_array_error - Log a sis64 array error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ int i, num_entries;
+ struct ipr_hostrcb_type_24_error *error;
+ struct ipr_hostrcb64_array_data_entry *array_entry;
+ char buffer[IPR_MAX_RES_PATH_LENGTH];
+ const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' };
+
+ error = &hostrcb->hcam.u.error64.u.type_24_error;
+
+ ipr_err_separator;
+
+ ipr_err("RAID %s Array Configuration: %s\n",
+ error->protection_level,
+ ipr_format_resource_path(&error->last_res_path[0], &buffer[0]));
+
+ ipr_err_separator;
+
+ array_entry = error->array_member;
+ num_entries = min_t(u32, be32_to_cpu(error->num_entries),
+ sizeof(error->array_member));
+
+ for (i = 0; i < num_entries; i++, array_entry++) {
+
+ if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
+ continue;
+
+ if (error->exposed_mode_adn == i)
+ ipr_err("Exposed Array Member %d:\n", i);
+ else
+ ipr_err("Array Member %d:\n", i);
+
+ ipr_err("Array Member %d:\n", i);
+ ipr_log_ext_vpd(&array_entry->vpd);
+ ipr_err("Current Location: %s",
+ ipr_format_resource_path(&array_entry->res_path[0], &buffer[0]));
+ ipr_err("Expected Location: %s",
+ ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0]));
+
+ ipr_err_separator;
+ }
+}
+
+/**
+ * ipr_log_sis64_fabric_error - Log a sis64 fabric error.
+ * @ioa_cfg: ioa config struct
+ * @hostrcb: hostrcb struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_hostrcb *hostrcb)
+{
+ struct ipr_hostrcb_type_30_error *error;
+ struct ipr_hostrcb64_fabric_desc *fabric;
+ struct ipr_hostrcb64_config_element *cfg;
+ int i, add_len;
+
+ error = &hostrcb->hcam.u.error64.u.type_30_error;
+
+ error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
+ ipr_hcam_err(hostrcb, "%s\n", error->failure_reason);
+
+ add_len = be32_to_cpu(hostrcb->hcam.length) -
+ (offsetof(struct ipr_hostrcb64_error, u) +
+ offsetof(struct ipr_hostrcb_type_30_error, desc));
+
+ for (i = 0, fabric = error->desc; i < error->num_entries; i++) {
+ ipr_log64_fabric_path(hostrcb, fabric);
+ for_each_fabric_cfg(fabric, cfg)
+ ipr_log64_path_elem(hostrcb, cfg);
+
+ add_len -= be16_to_cpu(fabric->length);
+ fabric = (struct ipr_hostrcb64_fabric_desc *)
+ ((unsigned long)fabric + be16_to_cpu(fabric->length));
+ }
+
+ ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len);
+}
+
+/**
* ipr_log_generic_error - Log an adapter error.
* @ioa_cfg: ioa config struct
* @hostrcb: hostrcb struct
@@ -1642,13 +2264,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST)
dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n");
- ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+ if (ioa_cfg->sis64)
+ ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
+ else
+ ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
- if (ioasc == IPR_IOASC_BUS_WAS_RESET ||
- ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) {
+ if (!ioa_cfg->sis64 && (ioasc == IPR_IOASC_BUS_WAS_RESET ||
+ ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER)) {
/* Tell the midlayer we had a bus reset so it will handle the UA properly */
scsi_report_bus_reset(ioa_cfg->host,
- hostrcb->hcam.u.error.failing_dev_res_addr.bus);
+ hostrcb->hcam.u.error.fd_res_addr.bus);
}
error_index = ipr_get_error(ioasc);
@@ -1696,6 +2321,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
case IPR_HOST_RCB_OVERLAY_ID_20:
ipr_log_fabric_error(ioa_cfg, hostrcb);
break;
+ case IPR_HOST_RCB_OVERLAY_ID_23:
+ ipr_log_sis64_config_error(ioa_cfg, hostrcb);
+ break;
+ case IPR_HOST_RCB_OVERLAY_ID_24:
+ case IPR_HOST_RCB_OVERLAY_ID_26:
+ ipr_log_sis64_array_error(ioa_cfg, hostrcb);
+ break;
+ case IPR_HOST_RCB_OVERLAY_ID_30:
+ ipr_log_sis64_fabric_error(ioa_cfg, hostrcb);
+ break;
case IPR_HOST_RCB_OVERLAY_ID_1:
case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
default:
@@ -1720,7 +2355,12 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd)
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
- u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+ u32 fd_ioasc;
+
+ if (ioa_cfg->sis64)
+ fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
+ else
+ fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
list_del(&hostrcb->queue);
list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
@@ -1845,12 +2485,14 @@ static const struct ipr_ses_table_entry *
ipr_find_ses_entry(struct ipr_resource_entry *res)
{
int i, j, matches;
+ struct ipr_std_inq_vpids *vpids;
const struct ipr_ses_table_entry *ste = ipr_ses_table;
for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) {
for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) {
if (ste->compare_product_id_byte[j] == 'X') {
- if (res->cfgte.std_inq_data.vpids.product_id[j] == ste->product_id[j])
+ vpids = &res->std_inq_data.vpids;
+ if (vpids->product_id[j] == ste->product_id[j])
matches++;
else
break;
@@ -1885,10 +2527,10 @@ static u32 ipr_get_max_scsi_speed(struct ipr_ioa_cfg *ioa_cfg, u8 bus, u8 bus_wi
/* Loop through each config table entry in the config table buffer */
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
- if (!(IPR_IS_SES_DEVICE(res->cfgte.std_inq_data)))
+ if (!(IPR_IS_SES_DEVICE(res->std_inq_data)))
continue;
- if (bus != res->cfgte.res_addr.bus)
+ if (bus != res->bus)
continue;
if (!(ste = ipr_find_ses_entry(res)))
@@ -1934,6 +2576,31 @@ static int ipr_wait_iodbg_ack(struct ipr_ioa_cfg *ioa_cfg, int max_delay)
}
/**
+ * ipr_get_sis64_dump_data_section - Dump IOA memory
+ * @ioa_cfg: ioa config struct
+ * @start_addr: adapter address to dump
+ * @dest: destination kernel buffer
+ * @length_in_words: length to dump in 4 byte words
+ *
+ * Return value:
+ * 0 on success
+ **/
+static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg,
+ u32 start_addr,
+ __be32 *dest, u32 length_in_words)
+{
+ int i;
+
+ for (i = 0; i < length_in_words; i++) {
+ writel(start_addr+(i*4), ioa_cfg->regs.dump_addr_reg);
+ *dest = cpu_to_be32(readl(ioa_cfg->regs.dump_data_reg));
+ dest++;
+ }
+
+ return 0;
+}
+
+/**
* ipr_get_ldump_data_section - Dump IOA memory
* @ioa_cfg: ioa config struct
* @start_addr: adapter address to dump
@@ -1950,9 +2617,13 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
volatile u32 temp_pcii_reg;
int i, delay = 0;
+ if (ioa_cfg->sis64)
+ return ipr_get_sis64_dump_data_section(ioa_cfg, start_addr,
+ dest, length_in_words);
+
/* Write IOA interrupt reg starting LDUMP state */
writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT),
- ioa_cfg->regs.set_uproc_interrupt_reg);
+ ioa_cfg->regs.set_uproc_interrupt_reg32);
/* Wait for IO debug acknowledge */
if (ipr_wait_iodbg_ack(ioa_cfg,
@@ -1971,7 +2642,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
/* Signal address valid - clear IOA Reset alert */
writel(IPR_UPROCI_RESET_ALERT,
- ioa_cfg->regs.clr_uproc_interrupt_reg);
+ ioa_cfg->regs.clr_uproc_interrupt_reg32);
for (i = 0; i < length_in_words; i++) {
/* Wait for IO debug acknowledge */
@@ -1996,10 +2667,10 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
/* Signal end of block transfer. Set reset alert then clear IO debug ack */
writel(IPR_UPROCI_RESET_ALERT,
- ioa_cfg->regs.set_uproc_interrupt_reg);
+ ioa_cfg->regs.set_uproc_interrupt_reg32);
writel(IPR_UPROCI_IO_DEBUG_ALERT,
- ioa_cfg->regs.clr_uproc_interrupt_reg);
+ ioa_cfg->regs.clr_uproc_interrupt_reg32);
/* Signal dump data received - Clear IO debug Ack */
writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE,
@@ -2008,7 +2679,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
/* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */
while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) {
temp_pcii_reg =
- readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+ readl(ioa_cfg->regs.sense_uproc_interrupt_reg32);
if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT))
return 0;
@@ -2207,6 +2878,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
u32 num_entries, start_off, end_off;
u32 bytes_to_copy, bytes_copied, rc;
struct ipr_sdt *sdt;
+ int valid = 1;
int i;
ENTER;
@@ -2220,7 +2892,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
start_addr = readl(ioa_cfg->ioa_mailbox);
- if (!ipr_sdt_is_fmt2(start_addr)) {
+ if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) {
dev_err(&ioa_cfg->pdev->dev,
"Invalid dump table format: %lx\n", start_addr);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -2249,7 +2921,6 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
/* IOA Dump entry */
ipr_init_dump_entry_hdr(&ioa_dump->hdr);
- ioa_dump->format = IPR_SDT_FMT2;
ioa_dump->hdr.len = 0;
ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY;
ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID;
@@ -2264,7 +2935,8 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
sizeof(struct ipr_sdt) / sizeof(__be32));
/* Smart Dump table is ready to use and the first entry is valid */
- if (rc || (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE)) {
+ if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
+ (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
dev_err(&ioa_cfg->pdev->dev,
"Dump of IOA failed. Dump table not valid: %d, %X.\n",
rc, be32_to_cpu(sdt->hdr.state));
@@ -2288,12 +2960,19 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
}
if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) {
- sdt_word = be32_to_cpu(sdt->entry[i].bar_str_offset);
- start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
- end_off = be32_to_cpu(sdt->entry[i].end_offset);
-
- if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) {
- bytes_to_copy = end_off - start_off;
+ sdt_word = be32_to_cpu(sdt->entry[i].start_token);
+ if (ioa_cfg->sis64)
+ bytes_to_copy = be32_to_cpu(sdt->entry[i].end_token);
+ else {
+ start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
+ end_off = be32_to_cpu(sdt->entry[i].end_token);
+
+ if (ipr_sdt_is_fmt2(sdt_word) && sdt_word)
+ bytes_to_copy = end_off - start_off;
+ else
+ valid = 0;
+ }
+ if (valid) {
if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) {
sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY;
continue;
@@ -2422,9 +3101,9 @@ restart:
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
if (res->add_to_ml) {
- bus = res->cfgte.res_addr.bus;
- target = res->cfgte.res_addr.target;
- lun = res->cfgte.res_addr.lun;
+ bus = res->bus;
+ target = res->target;
+ lun = res->lun;
res->add_to_ml = 0;
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
scsi_add_device(ioa_cfg->host, bus, target, lun);
@@ -2478,105 +3157,6 @@ static struct bin_attribute ipr_trace_attr = {
};
#endif
-static const struct {
- enum ipr_cache_state state;
- char *name;
-} cache_state [] = {
- { CACHE_NONE, "none" },
- { CACHE_DISABLED, "disabled" },
- { CACHE_ENABLED, "enabled" }
-};
-
-/**
- * ipr_show_write_caching - Show the write caching attribute
- * @dev: device struct
- * @buf: buffer
- *
- * Return value:
- * number of bytes printed to buffer
- **/
-static ssize_t ipr_show_write_caching(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct Scsi_Host *shost = class_to_shost(dev);
- struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
- unsigned long lock_flags = 0;
- int i, len = 0;
-
- spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
- for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
- if (cache_state[i].state == ioa_cfg->cache_state) {
- len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name);
- break;
- }
- }
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- return len;
-}
-
-
-/**
- * ipr_store_write_caching - Enable/disable adapter write cache
- * @dev: device struct
- * @buf: buffer
- * @count: buffer size
- *
- * This function will enable/disable adapter write cache.
- *
- * Return value:
- * count on success / other on failure
- **/
-static ssize_t ipr_store_write_caching(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct Scsi_Host *shost = class_to_shost(dev);
- struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
- unsigned long lock_flags = 0;
- enum ipr_cache_state new_state = CACHE_INVALID;
- int i;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- if (ioa_cfg->cache_state == CACHE_NONE)
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
- if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) {
- new_state = cache_state[i].state;
- break;
- }
- }
-
- if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED)
- return -EINVAL;
-
- spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
- if (ioa_cfg->cache_state == new_state) {
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- return count;
- }
-
- ioa_cfg->cache_state = new_state;
- dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n",
- new_state == CACHE_ENABLED ? "Enabling" : "Disabling");
- if (!ioa_cfg->in_reset_reload)
- ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
-
- return count;
-}
-
-static struct device_attribute ipr_ioa_cache_attr = {
- .attr = {
- .name = "write_cache",
- .mode = S_IRUGO | S_IWUSR,
- },
- .show = ipr_show_write_caching,
- .store = ipr_store_write_caching
-};
-
/**
* ipr_show_fw_version - Show the firmware version
* @dev: class device struct
@@ -2976,6 +3556,37 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
}
/**
+ * ipr_build_ucode_ioadl64 - Build a microcode download IOADL
+ * @ipr_cmd: ipr command struct
+ * @sglist: scatter/gather list
+ *
+ * Builds a microcode download IOA data list (IOADL).
+ *
+ **/
+static void ipr_build_ucode_ioadl64(struct ipr_cmnd *ipr_cmd,
+ struct ipr_sglist *sglist)
+{
+ struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+ struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+ struct scatterlist *scatterlist = sglist->scatterlist;
+ int i;
+
+ ipr_cmd->dma_use_sg = sglist->num_dma_sg;
+ ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+ ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len);
+
+ ioarcb->ioadl_len =
+ cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg);
+ for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
+ ioadl64[i].flags = cpu_to_be32(IPR_IOADL_FLAGS_WRITE);
+ ioadl64[i].data_len = cpu_to_be32(sg_dma_len(&scatterlist[i]));
+ ioadl64[i].address = cpu_to_be64(sg_dma_address(&scatterlist[i]));
+ }
+
+ ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+}
+
+/**
* ipr_build_ucode_ioadl - Build a microcode download IOADL
* @ipr_cmd: ipr command struct
* @sglist: scatter/gather list
@@ -2987,14 +3598,15 @@ static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd,
struct ipr_sglist *sglist)
{
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
- struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+ struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
struct scatterlist *scatterlist = sglist->scatterlist;
int i;
ipr_cmd->dma_use_sg = sglist->num_dma_sg;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
- ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len);
- ioarcb->write_ioadl_len =
+ ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len);
+
+ ioarcb->ioadl_len =
cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
@@ -3146,7 +3758,6 @@ static struct device_attribute *ipr_ioa_attrs[] = {
&ipr_ioa_state_attr,
&ipr_ioa_reset_attr,
&ipr_update_fw_attr,
- &ipr_ioa_cache_attr,
NULL,
};
@@ -3450,7 +4061,7 @@ static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribu
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
res = (struct ipr_resource_entry *)sdev->hostdata;
if (res)
- len = snprintf(buf, PAGE_SIZE, "%08X\n", res->cfgte.res_handle);
+ len = snprintf(buf, PAGE_SIZE, "%08X\n", res->res_handle);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
return len;
}
@@ -3463,8 +4074,43 @@ static struct device_attribute ipr_adapter_handle_attr = {
.show = ipr_show_adapter_handle
};
+/**
+ * ipr_show_resource_path - Show the resource path for this device.
+ * @dev: device struct
+ * @buf: buffer
+ *
+ * Return value:
+ * number of bytes printed to buffer
+ **/
+static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
+ struct ipr_resource_entry *res;
+ unsigned long lock_flags = 0;
+ ssize_t len = -ENXIO;
+ char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ res = (struct ipr_resource_entry *)sdev->hostdata;
+ if (res)
+ len = snprintf(buf, PAGE_SIZE, "%s\n",
+ ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return len;
+}
+
+static struct device_attribute ipr_resource_path_attr = {
+ .attr = {
+ .name = "resource_path",
+ .mode = S_IRUSR,
+ },
+ .show = ipr_show_resource_path
+};
+
static struct device_attribute *ipr_dev_attrs[] = {
&ipr_adapter_handle_attr,
+ &ipr_resource_path_attr,
NULL,
};
@@ -3517,9 +4163,9 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget)
struct ipr_resource_entry *res;
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
- if ((res->cfgte.res_addr.bus == starget->channel) &&
- (res->cfgte.res_addr.target == starget->id) &&
- (res->cfgte.res_addr.lun == 0)) {
+ if ((res->bus == starget->channel) &&
+ (res->target == starget->id) &&
+ (res->lun == 0)) {
return res;
}
}
@@ -3589,6 +4235,17 @@ static int ipr_target_alloc(struct scsi_target *starget)
static void ipr_target_destroy(struct scsi_target *starget)
{
struct ipr_sata_port *sata_port = starget->hostdata;
+ struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
+
+ if (ioa_cfg->sis64) {
+ if (starget->channel == IPR_ARRAY_VIRTUAL_BUS)
+ clear_bit(starget->id, ioa_cfg->array_ids);
+ else if (starget->channel == IPR_VSET_VIRTUAL_BUS)
+ clear_bit(starget->id, ioa_cfg->vset_ids);
+ else if (starget->channel == 0)
+ clear_bit(starget->id, ioa_cfg->target_ids);
+ }
if (sata_port) {
starget->hostdata = NULL;
@@ -3610,9 +4267,9 @@ static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev)
struct ipr_resource_entry *res;
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
- if ((res->cfgte.res_addr.bus == sdev->channel) &&
- (res->cfgte.res_addr.target == sdev->id) &&
- (res->cfgte.res_addr.lun == sdev->lun))
+ if ((res->bus == sdev->channel) &&
+ (res->target == sdev->id) &&
+ (res->lun == sdev->lun))
return res;
}
@@ -3661,6 +4318,7 @@ static int ipr_slave_configure(struct scsi_device *sdev)
struct ipr_resource_entry *res;
struct ata_port *ap = NULL;
unsigned long lock_flags = 0;
+ char buffer[IPR_MAX_RES_PATH_LENGTH];
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
res = sdev->hostdata;
@@ -3687,6 +4345,9 @@ static int ipr_slave_configure(struct scsi_device *sdev)
ata_sas_slave_configure(sdev, ap);
} else
scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+ if (ioa_cfg->sis64)
+ sdev_printk(KERN_INFO, sdev, "Resource path: %s\n",
+ ipr_format_resource_path(&res->res_path[0], &buffer[0]));
return 0;
}
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -3828,14 +4489,19 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
ioarcb = &ipr_cmd->ioarcb;
cmd_pkt = &ioarcb->cmd_pkt;
- regs = &ioarcb->add_data.u.regs;
- ioarcb->res_handle = res->cfgte.res_handle;
+ if (ipr_cmd->ioa_cfg->sis64) {
+ regs = &ipr_cmd->i.ata_ioadl.regs;
+ ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb));
+ } else
+ regs = &ioarcb->u.add_data.u.regs;
+
+ ioarcb->res_handle = res->res_handle;
cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
if (ipr_is_gata(res)) {
cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET;
- ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags));
+ ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(regs->flags));
regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
}
@@ -3880,19 +4546,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes,
res = sata_port->res;
if (res) {
rc = ipr_device_reset(ioa_cfg, res);
- switch(res->cfgte.proto) {
- case IPR_PROTO_SATA:
- case IPR_PROTO_SAS_STP:
- *classes = ATA_DEV_ATA;
- break;
- case IPR_PROTO_SATA_ATAPI:
- case IPR_PROTO_SAS_STP_ATAPI:
- *classes = ATA_DEV_ATAPI;
- break;
- default:
- *classes = ATA_DEV_UNKNOWN;
- break;
- };
+ *classes = res->ata_class;
}
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -3937,7 +4591,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
return FAILED;
list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
- if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+ if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
if (ipr_cmd->scsi_cmd)
ipr_cmd->done = ipr_scsi_eh_done;
if (ipr_cmd->qc)
@@ -3959,7 +4613,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
spin_lock_irq(scsi_cmd->device->host->host_lock);
list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
- if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+ if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
rc = -EIO;
break;
}
@@ -3998,13 +4652,13 @@ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd)
struct ipr_resource_entry *res;
ENTER;
- list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
- if (!memcmp(&res->cfgte.res_handle, &ipr_cmd->ioarcb.res_handle,
- sizeof(res->cfgte.res_handle))) {
- scsi_report_bus_reset(ioa_cfg->host, res->cfgte.res_addr.bus);
- break;
+ if (!ioa_cfg->sis64)
+ list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+ if (res->res_handle == ipr_cmd->ioarcb.res_handle) {
+ scsi_report_bus_reset(ioa_cfg->host, res->bus);
+ break;
+ }
}
- }
/*
* If abort has not completed, indicate the reset has, else call the
@@ -4102,7 +4756,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
return SUCCESS;
ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
- ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
+ ipr_cmd->ioarcb.res_handle = res->res_handle;
cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS;
@@ -4239,11 +4893,29 @@ static irqreturn_t ipr_isr(int irq, void *devp)
return IRQ_NONE;
}
- int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
- int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+ int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
- /* If an interrupt on the adapter did not occur, ignore it */
+ /* If an interrupt on the adapter did not occur, ignore it.
+ * Or in the case of SIS 64, check for a stage change interrupt.
+ */
if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) {
+ if (ioa_cfg->sis64) {
+ int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+ if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) {
+
+ /* clear stage change */
+ writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+ list_del(&ioa_cfg->reset_cmd->queue);
+ del_timer(&ioa_cfg->reset_cmd->timer);
+ ipr_reset_ioa_job(ioa_cfg->reset_cmd);
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return IRQ_HANDLED;
+ }
+ }
+
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
return IRQ_NONE;
}
@@ -4286,8 +4958,8 @@ static irqreturn_t ipr_isr(int irq, void *devp)
if (ipr_cmd != NULL) {
/* Clear the PCI interrupt */
do {
- writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg);
- int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+ writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
} while (int_reg & IPR_PCII_HRRQ_UPDATED &&
num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
@@ -4309,6 +4981,53 @@ static irqreturn_t ipr_isr(int irq, void *devp)
}
/**
+ * ipr_build_ioadl64 - Build a scatter/gather list and map the buffer
+ * @ioa_cfg: ioa config struct
+ * @ipr_cmd: ipr command struct
+ *
+ * Return value:
+ * 0 on success / -1 on failure
+ **/
+static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg,
+ struct ipr_cmnd *ipr_cmd)
+{
+ int i, nseg;
+ struct scatterlist *sg;
+ u32 length;
+ u32 ioadl_flags = 0;
+ struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
+ struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+ struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+
+ length = scsi_bufflen(scsi_cmd);
+ if (!length)
+ return 0;
+
+ nseg = scsi_dma_map(scsi_cmd);
+ if (nseg < 0) {
+ dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
+ return -1;
+ }
+
+ ipr_cmd->dma_use_sg = nseg;
+
+ if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
+ ioadl_flags = IPR_IOADL_FLAGS_WRITE;
+ ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+ } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE)
+ ioadl_flags = IPR_IOADL_FLAGS_READ;
+
+ scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) {
+ ioadl64[i].flags = cpu_to_be32(ioadl_flags);
+ ioadl64[i].data_len = cpu_to_be32(sg_dma_len(sg));
+ ioadl64[i].address = cpu_to_be64(sg_dma_address(sg));
+ }
+
+ ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+ return 0;
+}
+
+/**
* ipr_build_ioadl - Build a scatter/gather list and map the buffer
* @ioa_cfg: ioa config struct
* @ipr_cmd: ipr command struct
@@ -4325,7 +5044,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
u32 ioadl_flags = 0;
struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
- struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+ struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
length = scsi_bufflen(scsi_cmd);
if (!length)
@@ -4342,8 +5061,8 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
ioadl_flags = IPR_IOADL_FLAGS_WRITE;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
- ioarcb->write_data_transfer_length = cpu_to_be32(length);
- ioarcb->write_ioadl_len =
+ ioarcb->data_transfer_length = cpu_to_be32(length);
+ ioarcb->ioadl_len =
cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
} else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
ioadl_flags = IPR_IOADL_FLAGS_READ;
@@ -4352,11 +5071,10 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
}
- if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) {
- ioadl = ioarcb->add_data.u.ioadl;
- ioarcb->write_ioadl_addr =
- cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
- offsetof(struct ipr_ioarcb, add_data));
+ if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->u.add_data.u.ioadl)) {
+ ioadl = ioarcb->u.add_data.u.ioadl;
+ ioarcb->write_ioadl_addr = cpu_to_be32((ipr_cmd->dma_addr) +
+ offsetof(struct ipr_ioarcb, u.add_data));
ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
}
@@ -4446,18 +5164,24 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
- dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr);
+ dma_addr_t dma_addr = ipr_cmd->dma_addr;
memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
- ioarcb->write_data_transfer_length = 0;
+ ioarcb->data_transfer_length = 0;
ioarcb->read_data_transfer_length = 0;
- ioarcb->write_ioadl_len = 0;
+ ioarcb->ioadl_len = 0;
ioarcb->read_ioadl_len = 0;
ioasa->ioasc = 0;
ioasa->residual_data_len = 0;
- ioarcb->write_ioadl_addr =
- cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
- ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+
+ if (ipr_cmd->ioa_cfg->sis64)
+ ioarcb->u.sis64_addr_data.data_ioadl_addr =
+ cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+ else {
+ ioarcb->write_ioadl_addr =
+ cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+ ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+ }
}
/**
@@ -4489,15 +5213,8 @@ static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd)
cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ);
- ipr_cmd->ioadl[0].flags_and_data_len =
- cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | SCSI_SENSE_BUFFERSIZE);
- ipr_cmd->ioadl[0].address =
- cpu_to_be32(ipr_cmd->sense_buffer_dma);
-
- ipr_cmd->ioarcb.read_ioadl_len =
- cpu_to_be32(sizeof(struct ipr_ioadl_desc));
- ipr_cmd->ioarcb.read_data_transfer_length =
- cpu_to_be32(SCSI_SENSE_BUFFERSIZE);
+ ipr_init_ioadl(ipr_cmd, ipr_cmd->sense_buffer_dma,
+ SCSI_SENSE_BUFFERSIZE, IPR_IOADL_FLAGS_READ_LAST);
ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout,
IPR_REQUEST_SENSE_TIMEOUT * 2);
@@ -4893,9 +5610,9 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len);
ipr_cmd->scsi_cmd = scsi_cmd;
- ioarcb->res_handle = res->cfgte.res_handle;
+ ioarcb->res_handle = res->res_handle;
ipr_cmd->done = ipr_scsi_done;
- ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));
+ ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
if (scsi_cmd->underflow == 0)
@@ -4916,13 +5633,16 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
(!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
- if (likely(rc == 0))
- rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
+ if (likely(rc == 0)) {
+ if (ioa_cfg->sis64)
+ rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd);
+ else
+ rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
+ }
if (likely(rc == 0)) {
mb();
- writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
- ioa_cfg->regs.ioarrin_reg);
+ ipr_send_command(ipr_cmd);
} else {
list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
return SCSI_MLQUEUE_HOST_BUSY;
@@ -5035,20 +5755,9 @@ static void ipr_ata_phy_reset(struct ata_port *ap)
goto out_unlock;
}
- switch(res->cfgte.proto) {
- case IPR_PROTO_SATA:
- case IPR_PROTO_SAS_STP:
- ap->link.device[0].class = ATA_DEV_ATA;
- break;
- case IPR_PROTO_SATA_ATAPI:
- case IPR_PROTO_SAS_STP_ATAPI:
- ap->link.device[0].class = ATA_DEV_ATAPI;
- break;
- default:
- ap->link.device[0].class = ATA_DEV_UNKNOWN;
+ ap->link.device[0].class = res->ata_class;
+ if (ap->link.device[0].class == ATA_DEV_UNKNOWN)
ata_port_disable(ap);
- break;
- };
out_unlock:
spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
@@ -5134,8 +5843,7 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)
- scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus,
- res->cfgte.res_addr.target);
+ scsi_report_device_reset(ioa_cfg->host, res->bus, res->target);
if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status);
@@ -5146,6 +5854,52 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
}
/**
+ * ipr_build_ata_ioadl64 - Build an ATA scatter/gather list
+ * @ipr_cmd: ipr command struct
+ * @qc: ATA queued command
+ *
+ **/
+static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd,
+ struct ata_queued_cmd *qc)
+{
+ u32 ioadl_flags = 0;
+ struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+ struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+ struct ipr_ioadl64_desc *last_ioadl64 = NULL;
+ int len = qc->nbytes;
+ struct scatterlist *sg;
+ unsigned int si;
+ dma_addr_t dma_addr = ipr_cmd->dma_addr;
+
+ if (len == 0)
+ return;
+
+ if (qc->dma_dir == DMA_TO_DEVICE) {
+ ioadl_flags = IPR_IOADL_FLAGS_WRITE;
+ ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+ } else if (qc->dma_dir == DMA_FROM_DEVICE)
+ ioadl_flags = IPR_IOADL_FLAGS_READ;
+
+ ioarcb->data_transfer_length = cpu_to_be32(len);
+ ioarcb->ioadl_len =
+ cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg);
+ ioarcb->u.sis64_addr_data.data_ioadl_addr =
+ cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl));
+
+ for_each_sg(qc->sg, sg, qc->n_elem, si) {
+ ioadl64->flags = cpu_to_be32(ioadl_flags);
+ ioadl64->data_len = cpu_to_be32(sg_dma_len(sg));
+ ioadl64->address = cpu_to_be64(sg_dma_address(sg));
+
+ last_ioadl64 = ioadl64;
+ ioadl64++;
+ }
+
+ if (likely(last_ioadl64))
+ last_ioadl64->flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+}
+
+/**
* ipr_build_ata_ioadl - Build an ATA scatter/gather list
* @ipr_cmd: ipr command struct
* @qc: ATA queued command
@@ -5156,7 +5910,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
{
u32 ioadl_flags = 0;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
- struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+ struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
struct ipr_ioadl_desc *last_ioadl = NULL;
int len = qc->nbytes;
struct scatterlist *sg;
@@ -5168,8 +5922,8 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
if (qc->dma_dir == DMA_TO_DEVICE) {
ioadl_flags = IPR_IOADL_FLAGS_WRITE;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
- ioarcb->write_data_transfer_length = cpu_to_be32(len);
- ioarcb->write_ioadl_len =
+ ioarcb->data_transfer_length = cpu_to_be32(len);
+ ioarcb->ioadl_len =
cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
} else if (qc->dma_dir == DMA_FROM_DEVICE) {
ioadl_flags = IPR_IOADL_FLAGS_READ;
@@ -5212,25 +5966,34 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
ioarcb = &ipr_cmd->ioarcb;
- regs = &ioarcb->add_data.u.regs;
- memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data));
- ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs));
+ if (ioa_cfg->sis64) {
+ regs = &ipr_cmd->i.ata_ioadl.regs;
+ ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb));
+ } else
+ regs = &ioarcb->u.add_data.u.regs;
+
+ memset(regs, 0, sizeof(*regs));
+ ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(*regs));
list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
ipr_cmd->qc = qc;
ipr_cmd->done = ipr_sata_done;
- ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
+ ipr_cmd->ioarcb.res_handle = res->res_handle;
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
ipr_cmd->dma_use_sg = qc->n_elem;
- ipr_build_ata_ioadl(ipr_cmd, qc);
+ if (ioa_cfg->sis64)
+ ipr_build_ata_ioadl64(ipr_cmd, qc);
+ else
+ ipr_build_ata_ioadl(ipr_cmd, qc);
+
regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
ipr_copy_sata_tf(regs, &qc->tf);
memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN);
- ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));
+ ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
switch (qc->tf.protocol) {
case ATA_PROT_NODATA:
@@ -5257,8 +6020,9 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
}
mb();
- writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr),
- ioa_cfg->regs.ioarrin_reg);
+
+ ipr_send_command(ipr_cmd);
+
return 0;
}
@@ -5459,7 +6223,7 @@ static void ipr_set_sup_dev_dflt(struct ipr_supported_device *supported_dev,
* ipr_set_supported_devs - Send Set Supported Devices for a device
* @ipr_cmd: ipr command struct
*
- * This function send a Set Supported Devices to the adapter
+ * This function sends a Set Supported Devices to the adapter
*
* Return value:
* IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
@@ -5468,7 +6232,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev;
- struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
struct ipr_resource_entry *res = ipr_cmd->u.res;
@@ -5479,28 +6242,28 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
continue;
ipr_cmd->u.res = res;
- ipr_set_sup_dev_dflt(supp_dev, &res->cfgte.std_inq_data.vpids);
+ ipr_set_sup_dev_dflt(supp_dev, &res->std_inq_data.vpids);
ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES;
+ ioarcb->cmd_pkt.cdb[1] = IPR_SET_ALL_SUPPORTED_DEVICES;
ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff;
ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff;
- ioadl->flags_and_data_len = cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST |
- sizeof(struct ipr_supported_device));
- ioadl->address = cpu_to_be32(ioa_cfg->vpd_cbs_dma +
- offsetof(struct ipr_misc_cbs, supp_dev));
- ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
- ioarcb->write_data_transfer_length =
- cpu_to_be32(sizeof(struct ipr_supported_device));
+ ipr_init_ioadl(ipr_cmd,
+ ioa_cfg->vpd_cbs_dma +
+ offsetof(struct ipr_misc_cbs, supp_dev),
+ sizeof(struct ipr_supported_device),
+ IPR_IOADL_FLAGS_WRITE_LAST);
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
IPR_SET_SUP_DEVICE_TIMEOUT);
- ipr_cmd->job_step = ipr_set_supported_devs;
+ if (!ioa_cfg->sis64)
+ ipr_cmd->job_step = ipr_set_supported_devs;
return IPR_RC_JOB_RETURN;
}
@@ -5508,36 +6271,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
}
/**
- * ipr_setup_write_cache - Disable write cache if needed
- * @ipr_cmd: ipr command struct
- *
- * This function sets up adapters write cache to desired setting
- *
- * Return value:
- * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
- **/
-static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd)
-{
- struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
-
- ipr_cmd->job_step = ipr_set_supported_devs;
- ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
- struct ipr_resource_entry, queue);
-
- if (ioa_cfg->cache_state != CACHE_DISABLED)
- return IPR_RC_JOB_CONTINUE;
-
- ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
- ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
- ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
- ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
-
- ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
-
- return IPR_RC_JOB_RETURN;
-}
-
-/**
* ipr_get_mode_page - Locate specified mode page
* @mode_pages: mode page buffer
* @page_code: page code to find
@@ -5695,10 +6428,9 @@ static void ipr_modify_ioafp_mode_page_28(struct ipr_ioa_cfg *ioa_cfg,
* none
**/
static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd,
- __be32 res_handle, u8 parm, u32 dma_addr,
- u8 xfer_len)
+ __be32 res_handle, u8 parm,
+ dma_addr_t dma_addr, u8 xfer_len)
{
- struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
ioarcb->res_handle = res_handle;
@@ -5708,11 +6440,7 @@ static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd,
ioarcb->cmd_pkt.cdb[1] = parm;
ioarcb->cmd_pkt.cdb[4] = xfer_len;
- ioadl->flags_and_data_len =
- cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | xfer_len);
- ioadl->address = cpu_to_be32(dma_addr);
- ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
- ioarcb->write_data_transfer_length = cpu_to_be32(xfer_len);
+ ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_WRITE_LAST);
}
/**
@@ -5742,7 +6470,9 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
length);
- ipr_cmd->job_step = ipr_setup_write_cache;
+ ipr_cmd->job_step = ipr_set_supported_devs;
+ ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
+ struct ipr_resource_entry, queue);
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
LEAVE;
@@ -5762,9 +6492,8 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
**/
static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
__be32 res_handle,
- u8 parm, u32 dma_addr, u8 xfer_len)
+ u8 parm, dma_addr_t dma_addr, u8 xfer_len)
{
- struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
ioarcb->res_handle = res_handle;
@@ -5773,11 +6502,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
ioarcb->cmd_pkt.cdb[4] = xfer_len;
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB;
- ioadl->flags_and_data_len =
- cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len);
- ioadl->address = cpu_to_be32(dma_addr);
- ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
- ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len);
+ ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST);
}
/**
@@ -5815,10 +6540,13 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd)
**/
static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd)
{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) {
- ipr_cmd->job_step = ipr_setup_write_cache;
+ ipr_cmd->job_step = ipr_set_supported_devs;
+ ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
+ struct ipr_resource_entry, queue);
return IPR_RC_JOB_CONTINUE;
}
@@ -5958,24 +6686,36 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_resource_entry *res, *temp;
- struct ipr_config_table_entry *cfgte;
- int found, i;
+ struct ipr_config_table_entry_wrapper cfgtew;
+ int entries, found, flag, i;
LIST_HEAD(old_res);
ENTER;
- if (ioa_cfg->cfg_table->hdr.flags & IPR_UCODE_DOWNLOAD_REQ)
+ if (ioa_cfg->sis64)
+ flag = ioa_cfg->u.cfg_table64->hdr64.flags;
+ else
+ flag = ioa_cfg->u.cfg_table->hdr.flags;
+
+ if (flag & IPR_UCODE_DOWNLOAD_REQ)
dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n");
list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue)
list_move_tail(&res->queue, &old_res);
- for (i = 0; i < ioa_cfg->cfg_table->hdr.num_entries; i++) {
- cfgte = &ioa_cfg->cfg_table->dev[i];
+ if (ioa_cfg->sis64)
+ entries = ioa_cfg->u.cfg_table64->hdr64.num_entries;
+ else
+ entries = ioa_cfg->u.cfg_table->hdr.num_entries;
+
+ for (i = 0; i < entries; i++) {
+ if (ioa_cfg->sis64)
+ cfgtew.u.cfgte64 = &ioa_cfg->u.cfg_table64->dev[i];
+ else
+ cfgtew.u.cfgte = &ioa_cfg->u.cfg_table->dev[i];
found = 0;
list_for_each_entry_safe(res, temp, &old_res, queue) {
- if (!memcmp(&res->cfgte.res_addr,
- &cfgte->res_addr, sizeof(cfgte->res_addr))) {
+ if (ipr_is_same_device(res, &cfgtew)) {
list_move_tail(&res->queue, &ioa_cfg->used_res_q);
found = 1;
break;
@@ -5992,24 +6732,27 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd)
res = list_entry(ioa_cfg->free_res_q.next,
struct ipr_resource_entry, queue);
list_move_tail(&res->queue, &ioa_cfg->used_res_q);
- ipr_init_res_entry(res);
+ ipr_init_res_entry(res, &cfgtew);
res->add_to_ml = 1;
}
if (found)
- memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry));
+ ipr_update_res_entry(res, &cfgtew);
}
list_for_each_entry_safe(res, temp, &old_res, queue) {
if (res->sdev) {
res->del_from_ml = 1;
- res->cfgte.res_handle = IPR_INVALID_RES_HANDLE;
+ res->res_handle = IPR_INVALID_RES_HANDLE;
list_move_tail(&res->queue, &ioa_cfg->used_res_q);
- } else {
- list_move_tail(&res->queue, &ioa_cfg->free_res_q);
}
}
+ list_for_each_entry_safe(res, temp, &old_res, queue) {
+ ipr_clear_res_target(res);
+ list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+ }
+
if (ioa_cfg->dual_raid && ipr_dual_ioa_raid)
ipr_cmd->job_step = ipr_ioafp_mode_sense_page24;
else
@@ -6033,7 +6776,6 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
- struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data;
struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap;
@@ -6047,16 +6789,11 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG;
- ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_config_table) >> 8) & 0xff;
- ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_config_table) & 0xff;
+ ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff;
+ ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff;
- ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
- ioarcb->read_data_transfer_length =
- cpu_to_be32(sizeof(struct ipr_config_table));
-
- ioadl->address = cpu_to_be32(ioa_cfg->cfg_table_dma);
- ioadl->flags_and_data_len =
- cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(struct ipr_config_table));
+ ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, ioa_cfg->cfg_table_size,
+ IPR_IOADL_FLAGS_READ_LAST);
ipr_cmd->job_step = ipr_init_res_table;
@@ -6076,10 +6813,9 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
* none
**/
static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
- u32 dma_addr, u8 xfer_len)
+ dma_addr_t dma_addr, u8 xfer_len)
{
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
- struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
ENTER;
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB;
@@ -6090,12 +6826,7 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
ioarcb->cmd_pkt.cdb[2] = page;
ioarcb->cmd_pkt.cdb[4] = xfer_len;
- ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
- ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len);
-
- ioadl->address = cpu_to_be32(dma_addr);
- ioadl->flags_and_data_len =
- cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len);
+ ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST);
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
LEAVE;
@@ -6166,13 +6897,9 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd)
static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
- struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data;
ENTER;
- if (!ipr_inquiry_page_supported(page0, 1))
- ioa_cfg->cache_state = CACHE_NONE;
-
ipr_cmd->job_step = ipr_ioafp_cap_inquiry;
ipr_ioafp_inquiry(ipr_cmd, 1, 3,
@@ -6240,7 +6967,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd)
}
/**
- * ipr_ioafp_indentify_hrrq - Send Identify Host RRQ.
+ * ipr_ioafp_identify_hrrq - Send Identify Host RRQ.
* @ipr_cmd: ipr command struct
*
* This function send an Identify Host Request Response Queue
@@ -6249,7 +6976,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd)
* Return value:
* IPR_RC_JOB_RETURN
**/
-static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd)
+static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
@@ -6261,19 +6988,32 @@ static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd)
ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
+ if (ioa_cfg->sis64)
+ ioarcb->cmd_pkt.cdb[1] = 0x1;
ioarcb->cmd_pkt.cdb[2] =
- ((u32) ioa_cfg->host_rrq_dma >> 24) & 0xff;
+ ((u64) ioa_cfg->host_rrq_dma >> 24) & 0xff;
ioarcb->cmd_pkt.cdb[3] =
- ((u32) ioa_cfg->host_rrq_dma >> 16) & 0xff;
+ ((u64) ioa_cfg->host_rrq_dma >> 16) & 0xff;
ioarcb->cmd_pkt.cdb[4] =
- ((u32) ioa_cfg->host_rrq_dma >> 8) & 0xff;
+ ((u64) ioa_cfg->host_rrq_dma >> 8) & 0xff;
ioarcb->cmd_pkt.cdb[5] =
- ((u32) ioa_cfg->host_rrq_dma) & 0xff;
+ ((u64) ioa_cfg->host_rrq_dma) & 0xff;
ioarcb->cmd_pkt.cdb[7] =
((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff;
ioarcb->cmd_pkt.cdb[8] =
(sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff;
+ if (ioa_cfg->sis64) {
+ ioarcb->cmd_pkt.cdb[10] =
+ ((u64) ioa_cfg->host_rrq_dma >> 56) & 0xff;
+ ioarcb->cmd_pkt.cdb[11] =
+ ((u64) ioa_cfg->host_rrq_dma >> 48) & 0xff;
+ ioarcb->cmd_pkt.cdb[12] =
+ ((u64) ioa_cfg->host_rrq_dma >> 40) & 0xff;
+ ioarcb->cmd_pkt.cdb[13] =
+ ((u64) ioa_cfg->host_rrq_dma >> 32) & 0xff;
+ }
+
ipr_cmd->job_step = ipr_ioafp_std_inquiry;
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
@@ -6354,7 +7094,58 @@ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg)
ioa_cfg->toggle_bit = 1;
/* Zero out config table */
- memset(ioa_cfg->cfg_table, 0, sizeof(struct ipr_config_table));
+ memset(ioa_cfg->u.cfg_table, 0, ioa_cfg->cfg_table_size);
+}
+
+/**
+ * ipr_reset_next_stage - Process IPL stage change based on feedback register.
+ * @ipr_cmd: ipr command struct
+ *
+ * Return value:
+ * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd)
+{
+ unsigned long stage, stage_time;
+ u32 feedback;
+ volatile u32 int_reg;
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+ u64 maskval = 0;
+
+ feedback = readl(ioa_cfg->regs.init_feedback_reg);
+ stage = feedback & IPR_IPL_INIT_STAGE_MASK;
+ stage_time = feedback & IPR_IPL_INIT_STAGE_TIME_MASK;
+
+ ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time);
+
+ /* sanity check the stage_time value */
+ if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME)
+ stage_time = IPR_IPL_INIT_MIN_STAGE_TIME;
+ else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT)
+ stage_time = IPR_LONG_OPERATIONAL_TIMEOUT;
+
+ if (stage == IPR_IPL_INIT_STAGE_UNKNOWN) {
+ writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.set_interrupt_mask_reg);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+ stage_time = ioa_cfg->transop_timeout;
+ ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
+ } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) {
+ ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
+ maskval = IPR_PCII_IPL_STAGE_CHANGE;
+ maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
+ writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+ return IPR_RC_JOB_CONTINUE;
+ }
+
+ ipr_cmd->timer.data = (unsigned long) ipr_cmd;
+ ipr_cmd->timer.expires = jiffies + stage_time * HZ;
+ ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout;
+ ipr_cmd->done = ipr_reset_ioa_job;
+ add_timer(&ipr_cmd->timer);
+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
+
+ return IPR_RC_JOB_RETURN;
}
/**
@@ -6373,7 +7164,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd)
volatile u32 int_reg;
ENTER;
- ipr_cmd->job_step = ipr_ioafp_indentify_hrrq;
+ ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
ipr_init_ioa_mem(ioa_cfg);
ioa_cfg->allow_interrupts = 1;
@@ -6381,19 +7172,27 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd)
if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED),
- ioa_cfg->regs.clr_interrupt_mask_reg);
+ ioa_cfg->regs.clr_interrupt_mask_reg32);
int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
return IPR_RC_JOB_CONTINUE;
}
/* Enable destructive diagnostics on IOA */
- writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg);
+ writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32);
+
+ writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32);
+ if (ioa_cfg->sis64)
+ writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg);
- writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg);
int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n");
+ if (ioa_cfg->sis64) {
+ ipr_cmd->job_step = ipr_reset_next_stage;
+ return IPR_RC_JOB_CONTINUE;
+ }
+
ipr_cmd->timer.data = (unsigned long) ipr_cmd;
ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ);
ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout;
@@ -6463,7 +7262,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
mailbox = readl(ioa_cfg->ioa_mailbox);
- if (!ipr_sdt_is_fmt2(mailbox)) {
+ if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(mailbox)) {
ipr_unit_check_no_data(ioa_cfg);
return;
}
@@ -6472,15 +7271,20 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt,
(sizeof(struct ipr_uc_sdt)) / sizeof(__be32));
- if (rc || (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE) ||
- !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY)) {
+ if (rc || !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY) ||
+ ((be32_to_cpu(sdt.hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
+ (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
ipr_unit_check_no_data(ioa_cfg);
return;
}
/* Find length of the first sdt entry (UC buffer) */
- length = (be32_to_cpu(sdt.entry[0].end_offset) -
- be32_to_cpu(sdt.entry[0].bar_str_offset)) & IPR_FMT2_MBX_ADDR_MASK;
+ if (be32_to_cpu(sdt.hdr.state) == IPR_FMT3_SDT_READY_TO_USE)
+ length = be32_to_cpu(sdt.entry[0].end_token);
+ else
+ length = (be32_to_cpu(sdt.entry[0].end_token) -
+ be32_to_cpu(sdt.entry[0].start_token)) &
+ IPR_FMT2_MBX_ADDR_MASK;
hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next,
struct ipr_hostrcb, queue);
@@ -6488,13 +7292,13 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam));
rc = ipr_get_ldump_data_section(ioa_cfg,
- be32_to_cpu(sdt.entry[0].bar_str_offset),
+ be32_to_cpu(sdt.entry[0].start_token),
(__be32 *)&hostrcb->hcam,
min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32));
if (!rc) {
ipr_handle_log_data(ioa_cfg, hostrcb);
- ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+ ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED &&
ioa_cfg->sdt_state == GET_DUMP)
ioa_cfg->sdt_state = WAIT_FOR_DUMP;
@@ -6722,7 +7526,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd)
if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) {
ipr_mask_and_clear_interrupts(ioa_cfg, ~0);
- writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg);
+ writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32);
ipr_cmd->job_step = ipr_reset_wait_to_start_bist;
} else {
ipr_cmd->job_step = ioa_cfg->reset;
@@ -6785,7 +7589,10 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd)
ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8;
ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff;
- ipr_build_ucode_ioadl(ipr_cmd, sglist);
+ if (ioa_cfg->sis64)
+ ipr_build_ucode_ioadl64(ipr_cmd, sglist);
+ else
+ ipr_build_ucode_ioadl(ipr_cmd, sglist);
ipr_cmd->job_step = ipr_reset_ucode_download_done;
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
@@ -7154,8 +7961,8 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
ipr_free_cmd_blks(ioa_cfg);
pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS,
ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma);
- pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_config_table),
- ioa_cfg->cfg_table,
+ pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size,
+ ioa_cfg->u.cfg_table,
ioa_cfg->cfg_table_dma);
for (i = 0; i < IPR_NUM_HCAMS; i++) {
@@ -7209,7 +8016,7 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
int i;
ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev,
- sizeof(struct ipr_cmnd), 8, 0);
+ sizeof(struct ipr_cmnd), 16, 0);
if (!ioa_cfg->ipr_cmd_pool)
return -ENOMEM;
@@ -7227,13 +8034,25 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr;
ioarcb = &ipr_cmd->ioarcb;
- ioarcb->ioarcb_host_pci_addr = cpu_to_be32(dma_addr);
+ ipr_cmd->dma_addr = dma_addr;
+ if (ioa_cfg->sis64)
+ ioarcb->a.ioarcb_host_pci_addr64 = cpu_to_be64(dma_addr);
+ else
+ ioarcb->a.ioarcb_host_pci_addr = cpu_to_be32(dma_addr);
+
ioarcb->host_response_handle = cpu_to_be32(i << 2);
- ioarcb->write_ioadl_addr =
- cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
- ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
- ioarcb->ioasa_host_pci_addr =
- cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+ if (ioa_cfg->sis64) {
+ ioarcb->u.sis64_addr_data.data_ioadl_addr =
+ cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+ ioarcb->u.sis64_addr_data.ioasa_host_pci_addr =
+ cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+ } else {
+ ioarcb->write_ioadl_addr =
+ cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+ ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+ ioarcb->ioasa_host_pci_addr =
+ cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+ }
ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa));
ipr_cmd->cmd_index = i;
ipr_cmd->ioa_cfg = ioa_cfg;
@@ -7260,13 +8079,24 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
ENTER;
ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) *
- IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL);
+ ioa_cfg->max_devs_supported, GFP_KERNEL);
if (!ioa_cfg->res_entries)
goto out;
- for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++)
+ if (ioa_cfg->sis64) {
+ ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) *
+ BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+ ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) *
+ BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+ ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) *
+ BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+ }
+
+ for (i = 0; i < ioa_cfg->max_devs_supported; i++) {
list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q);
+ ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
+ }
ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev,
sizeof(struct ipr_misc_cbs),
@@ -7285,11 +8115,11 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
if (!ioa_cfg->host_rrq)
goto out_ipr_free_cmd_blocks;
- ioa_cfg->cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
- sizeof(struct ipr_config_table),
- &ioa_cfg->cfg_table_dma);
+ ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
+ ioa_cfg->cfg_table_size,
+ &ioa_cfg->cfg_table_dma);
- if (!ioa_cfg->cfg_table)
+ if (!ioa_cfg->u.cfg_table)
goto out_free_host_rrq;
for (i = 0; i < IPR_NUM_HCAMS; i++) {
@@ -7323,8 +8153,9 @@ out_free_hostrcb_dma:
ioa_cfg->hostrcb[i],
ioa_cfg->hostrcb_dma[i]);
}
- pci_free_consistent(pdev, sizeof(struct ipr_config_table),
- ioa_cfg->cfg_table, ioa_cfg->cfg_table_dma);
+ pci_free_consistent(pdev, ioa_cfg->cfg_table_size,
+ ioa_cfg->u.cfg_table,
+ ioa_cfg->cfg_table_dma);
out_free_host_rrq:
pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS,
ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma);
@@ -7399,15 +8230,21 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
init_waitqueue_head(&ioa_cfg->reset_wait_q);
init_waitqueue_head(&ioa_cfg->msi_wait_q);
ioa_cfg->sdt_state = INACTIVE;
- if (ipr_enable_cache)
- ioa_cfg->cache_state = CACHE_ENABLED;
- else
- ioa_cfg->cache_state = CACHE_DISABLED;
ipr_initialize_bus_attr(ioa_cfg);
+ ioa_cfg->max_devs_supported = ipr_max_devs;
- host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS;
- host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET;
+ if (ioa_cfg->sis64) {
+ host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS;
+ host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET;
+ if (ipr_max_devs > IPR_MAX_SIS64_DEVS)
+ ioa_cfg->max_devs_supported = IPR_MAX_SIS64_DEVS;
+ } else {
+ host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS;
+ host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET;
+ if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS)
+ ioa_cfg->max_devs_supported = IPR_MAX_PHYSICAL_DEVS;
+ }
host->max_channel = IPR_MAX_BUS_TO_SCAN;
host->unique_id = host->host_no;
host->max_cmd_len = IPR_MAX_CDB_LEN;
@@ -7419,13 +8256,26 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg;
t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg;
+ t->clr_interrupt_mask_reg32 = base + p->clr_interrupt_mask_reg32;
t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg;
+ t->sense_interrupt_mask_reg32 = base + p->sense_interrupt_mask_reg32;
t->clr_interrupt_reg = base + p->clr_interrupt_reg;
+ t->clr_interrupt_reg32 = base + p->clr_interrupt_reg32;
t->sense_interrupt_reg = base + p->sense_interrupt_reg;
+ t->sense_interrupt_reg32 = base + p->sense_interrupt_reg32;
t->ioarrin_reg = base + p->ioarrin_reg;
t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg;
+ t->sense_uproc_interrupt_reg32 = base + p->sense_uproc_interrupt_reg32;
t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg;
+ t->set_uproc_interrupt_reg32 = base + p->set_uproc_interrupt_reg32;
t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg;
+ t->clr_uproc_interrupt_reg32 = base + p->clr_uproc_interrupt_reg32;
+
+ if (ioa_cfg->sis64) {
+ t->init_feedback_reg = base + p->init_feedback_reg;
+ t->dump_addr_reg = base + p->dump_addr_reg;
+ t->dump_data_reg = base + p->dump_data_reg;
+ }
}
/**
@@ -7497,7 +8347,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg,
init_waitqueue_head(&ioa_cfg->msi_wait_q);
ioa_cfg->msi_received = 0;
ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
- writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg);
+ writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32);
int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -7508,7 +8358,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg,
} else if (ipr_debug)
dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq);
- writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg);
+ writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32);
int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ);
ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
@@ -7578,6 +8428,8 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
goto out_scsi_host_put;
}
+ /* set SIS 32 or SIS 64 */
+ ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0;
ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg;
if (ipr_transop_timeout)
@@ -7615,7 +8467,16 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
pci_set_master(pdev);
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (ioa_cfg->sis64) {
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+ if (rc < 0) {
+ dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n");
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ }
+
+ } else
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+
if (rc < 0) {
dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
goto cleanup_nomem;
@@ -7657,6 +8518,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg)))
goto cleanup_nomem;
+ if (ioa_cfg->sis64)
+ ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr64)
+ + ((sizeof(struct ipr_config_table_entry64)
+ * ioa_cfg->max_devs_supported)));
+ else
+ ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr)
+ + ((sizeof(struct ipr_config_table_entry)
+ * ioa_cfg->max_devs_supported)));
+
rc = ipr_alloc_mem(ioa_cfg);
if (rc < 0) {
dev_err(&pdev->dev,
@@ -7668,9 +8538,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
* If HRRQ updated interrupt is not masked, or reset alert is set,
* the card is in an unknown state and needs a hard reset
*/
- mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
- interrupts = readl(ioa_cfg->regs.sense_interrupt_reg);
- uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+ mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
+ interrupts = readl(ioa_cfg->regs.sense_interrupt_reg32);
+ uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32);
if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
ioa_cfg->needs_hard_reset = 1;
if (interrupts & IPR_PCII_ERROR_INTERRUPTS)
@@ -7958,9 +8828,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0,
IPR_USE_LONG_TRANSOP_TIMEOUT },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0,
- IPR_USE_LONG_TRANSOP_TIMEOUT },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0,
@@ -7975,9 +8842,22 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0,
IPR_USE_LONG_TRANSOP_TIMEOUT },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0,
- IPR_USE_LONG_TRANSOP_TIMEOUT },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B5, 0, 0, 0 },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B1, 0, 0, 0 },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C6, 0, 0, 0 },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, 0 },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57CE, 0, 0, 0 },
{ }
};
MODULE_DEVICE_TABLE(pci, ipr_pci_table);
@@ -7997,6 +8877,61 @@ static struct pci_driver ipr_driver = {
};
/**
+ * ipr_halt_done - Shutdown prepare completion
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_halt_done(struct ipr_cmnd *ipr_cmd)
+{
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+}
+
+/**
+ * ipr_halt - Issue shutdown prepare to all adapters
+ *
+ * Return value:
+ * NOTIFY_OK on success / NOTIFY_DONE on failure
+ **/
+static int ipr_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+ struct ipr_cmnd *ipr_cmd;
+ struct ipr_ioa_cfg *ioa_cfg;
+ unsigned long flags = 0;
+
+ if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
+ return NOTIFY_DONE;
+
+ spin_lock(&ipr_driver_lock);
+
+ list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) {
+ spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+ if (!ioa_cfg->allow_cmds) {
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+ continue;
+ }
+
+ ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
+ ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
+ ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
+ ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
+ ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
+
+ ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+ }
+ spin_unlock(&ipr_driver_lock);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block ipr_notifier = {
+ ipr_halt, NULL, 0
+};
+
+/**
* ipr_init - Module entry point
*
* Return value:
@@ -8007,6 +8942,7 @@ static int __init ipr_init(void)
ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
+ register_reboot_notifier(&ipr_notifier);
return pci_register_driver(&ipr_driver);
}
@@ -8020,6 +8956,7 @@ static int __init ipr_init(void)
**/
static void __exit ipr_exit(void)
{
+ unregister_reboot_notifier(&ipr_notifier);
pci_unregister_driver(&ipr_driver);
}
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 19bbcf39f0c..4c267b5e0b9 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -37,8 +37,8 @@
/*
* Literals
*/
-#define IPR_DRIVER_VERSION "2.4.3"
-#define IPR_DRIVER_DATE "(June 10, 2009)"
+#define IPR_DRIVER_VERSION "2.5.0"
+#define IPR_DRIVER_DATE "(February 11, 2010)"
/*
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -55,7 +55,9 @@
#define IPR_NUM_BASE_CMD_BLKS 100
#define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339
-#define PCI_DEVICE_ID_IBM_SCAMP_E 0x034A
+
+#define PCI_DEVICE_ID_IBM_CROC_FPGA_E2 0x033D
+#define PCI_DEVICE_ID_IBM_CROC_ASIC_E2 0x034A
#define IPR_SUBS_DEV_ID_2780 0x0264
#define IPR_SUBS_DEV_ID_5702 0x0266
@@ -70,15 +72,24 @@
#define IPR_SUBS_DEV_ID_572A 0x02C1
#define IPR_SUBS_DEV_ID_572B 0x02C2
#define IPR_SUBS_DEV_ID_572F 0x02C3
-#define IPR_SUBS_DEV_ID_574D 0x030B
#define IPR_SUBS_DEV_ID_574E 0x030A
#define IPR_SUBS_DEV_ID_575B 0x030D
#define IPR_SUBS_DEV_ID_575C 0x0338
-#define IPR_SUBS_DEV_ID_575D 0x033E
#define IPR_SUBS_DEV_ID_57B3 0x033A
#define IPR_SUBS_DEV_ID_57B7 0x0360
#define IPR_SUBS_DEV_ID_57B8 0x02C2
+#define IPR_SUBS_DEV_ID_57B4 0x033B
+#define IPR_SUBS_DEV_ID_57B2 0x035F
+#define IPR_SUBS_DEV_ID_57C6 0x0357
+
+#define IPR_SUBS_DEV_ID_57B5 0x033C
+#define IPR_SUBS_DEV_ID_57CE 0x035E
+#define IPR_SUBS_DEV_ID_57B1 0x0355
+
+#define IPR_SUBS_DEV_ID_574D 0x0356
+#define IPR_SUBS_DEV_ID_575D 0x035D
+
#define IPR_NAME "ipr"
/*
@@ -118,6 +129,10 @@
#define IPR_NUM_LOG_HCAMS 2
#define IPR_NUM_CFG_CHG_HCAMS 2
#define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS)
+
+#define IPR_MAX_SIS64_TARGETS_PER_BUS 1024
+#define IPR_MAX_SIS64_LUNS_PER_TARGET 0xffffffff
+
#define IPR_MAX_NUM_TARGETS_PER_BUS 256
#define IPR_MAX_NUM_LUNS_PER_TARGET 256
#define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8
@@ -132,13 +147,15 @@
/* We need resources for HCAMS, IOA reset, IOA bringdown, and ERP */
#define IPR_NUM_INTERNAL_CMD_BLKS (IPR_NUM_HCAMS + \
- ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 3)
+ ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 4)
#define IPR_MAX_COMMANDS IPR_NUM_BASE_CMD_BLKS
#define IPR_NUM_CMD_BLKS (IPR_NUM_BASE_CMD_BLKS + \
IPR_NUM_INTERNAL_CMD_BLKS)
#define IPR_MAX_PHYSICAL_DEVS 192
+#define IPR_DEFAULT_SIS64_DEVS 1024
+#define IPR_MAX_SIS64_DEVS 4096
#define IPR_MAX_SGLIST 64
#define IPR_IOA_MAX_SECTORS 32767
@@ -173,6 +190,7 @@
#define IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE 0x01
#define IPR_HCAM_CDB_OP_CODE_LOG_DATA 0x02
#define IPR_SET_SUPPORTED_DEVICES 0xFB
+#define IPR_SET_ALL_SUPPORTED_DEVICES 0x80
#define IPR_IOA_SHUTDOWN 0xF7
#define IPR_WR_BUF_DOWNLOAD_AND_SAVE 0x05
@@ -221,9 +239,17 @@
#define IPR_SDT_FMT2_BAR5_SEL 0x5
#define IPR_SDT_FMT2_EXP_ROM_SEL 0x8
#define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2
+#define IPR_FMT3_SDT_READY_TO_USE 0xC4D4E3F3
#define IPR_DOORBELL 0x82800000
#define IPR_RUNTIME_RESET 0x40000000
+#define IPR_IPL_INIT_MIN_STAGE_TIME 5
+#define IPR_IPL_INIT_STAGE_UNKNOWN 0x0
+#define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000
+#define IPR_IPL_INIT_STAGE_MASK 0xff000000
+#define IPR_IPL_INIT_STAGE_TIME_MASK 0x0000ffff
+#define IPR_PCII_IPL_STAGE_CHANGE (0x80000000 >> 0)
+
#define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0)
#define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3)
#define IPR_PCII_IOA_UNIT_CHECKED (0x80000000 >> 4)
@@ -318,27 +344,27 @@ struct ipr_std_inq_data {
u8 serial_num[IPR_SERIAL_NUM_LEN];
}__attribute__ ((packed));
+#define IPR_RES_TYPE_AF_DASD 0x00
+#define IPR_RES_TYPE_GENERIC_SCSI 0x01
+#define IPR_RES_TYPE_VOLUME_SET 0x02
+#define IPR_RES_TYPE_REMOTE_AF_DASD 0x03
+#define IPR_RES_TYPE_GENERIC_ATA 0x04
+#define IPR_RES_TYPE_ARRAY 0x05
+#define IPR_RES_TYPE_IOAFP 0xff
+
struct ipr_config_table_entry {
u8 proto;
#define IPR_PROTO_SATA 0x02
#define IPR_PROTO_SATA_ATAPI 0x03
#define IPR_PROTO_SAS_STP 0x06
-#define IPR_PROTO_SAS_STP_ATAPI 0x07
+#define IPR_PROTO_SAS_STP_ATAPI 0x07
u8 array_id;
u8 flags;
-#define IPR_IS_IOA_RESOURCE 0x80
-#define IPR_IS_ARRAY_MEMBER 0x20
-#define IPR_IS_HOT_SPARE 0x10
-
+#define IPR_IS_IOA_RESOURCE 0x80
u8 rsvd_subtype;
-#define IPR_RES_SUBTYPE(res) (((res)->cfgte.rsvd_subtype) & 0x0f)
-#define IPR_SUBTYPE_AF_DASD 0
-#define IPR_SUBTYPE_GENERIC_SCSI 1
-#define IPR_SUBTYPE_VOLUME_SET 2
-#define IPR_SUBTYPE_GENERIC_ATA 4
-
-#define IPR_QUEUEING_MODEL(res) ((((res)->cfgte.flags) & 0x70) >> 4)
-#define IPR_QUEUE_FROZEN_MODEL 0
+
+#define IPR_QUEUEING_MODEL(res) ((((res)->flags) & 0x70) >> 4)
+#define IPR_QUEUE_FROZEN_MODEL 0
#define IPR_QUEUE_NACA_MODEL 1
struct ipr_res_addr res_addr;
@@ -347,6 +373,28 @@ struct ipr_config_table_entry {
struct ipr_std_inq_data std_inq_data;
}__attribute__ ((packed, aligned (4)));
+struct ipr_config_table_entry64 {
+ u8 res_type;
+ u8 proto;
+ u8 vset_num;
+ u8 array_id;
+ __be16 flags;
+ __be16 res_flags;
+#define IPR_QUEUEING_MODEL64(res) ((((res)->res_flags) & 0x7000) >> 12)
+ __be32 res_handle;
+ u8 dev_id_type;
+ u8 reserved[3];
+ __be64 dev_id;
+ __be64 lun;
+ __be64 lun_wwn[2];
+#define IPR_MAX_RES_PATH_LENGTH 24
+ __be64 res_path;
+ struct ipr_std_inq_data std_inq_data;
+ u8 reserved2[4];
+ __be64 reserved3[2]; // description text
+ u8 reserved4[8];
+}__attribute__ ((packed, aligned (8)));
+
struct ipr_config_table_hdr {
u8 num_entries;
u8 flags;
@@ -354,13 +402,35 @@ struct ipr_config_table_hdr {
__be16 reserved;
}__attribute__((packed, aligned (4)));
+struct ipr_config_table_hdr64 {
+ __be16 num_entries;
+ __be16 reserved;
+ u8 flags;
+ u8 reserved2[11];
+}__attribute__((packed, aligned (4)));
+
struct ipr_config_table {
struct ipr_config_table_hdr hdr;
- struct ipr_config_table_entry dev[IPR_MAX_PHYSICAL_DEVS];
+ struct ipr_config_table_entry dev[0];
}__attribute__((packed, aligned (4)));
+struct ipr_config_table64 {
+ struct ipr_config_table_hdr64 hdr64;
+ struct ipr_config_table_entry64 dev[0];
+}__attribute__((packed, aligned (8)));
+
+struct ipr_config_table_entry_wrapper {
+ union {
+ struct ipr_config_table_entry *cfgte;
+ struct ipr_config_table_entry64 *cfgte64;
+ } u;
+};
+
struct ipr_hostrcb_cfg_ch_not {
- struct ipr_config_table_entry cfgte;
+ union {
+ struct ipr_config_table_entry cfgte;
+ struct ipr_config_table_entry64 cfgte64;
+ } u;
u8 reserved[936];
}__attribute__((packed, aligned (4)));
@@ -381,7 +451,7 @@ struct ipr_cmd_pkt {
#define IPR_RQTYPE_HCAM 0x02
#define IPR_RQTYPE_ATA_PASSTHRU 0x04
- u8 luntar_luntrn;
+ u8 reserved2;
u8 flags_hi;
#define IPR_FLAGS_HI_WRITE_NOT_READ 0x80
@@ -403,7 +473,7 @@ struct ipr_cmd_pkt {
__be16 timeout;
}__attribute__ ((packed, aligned(4)));
-struct ipr_ioarcb_ata_regs {
+struct ipr_ioarcb_ata_regs { /* 22 bytes */
u8 flags;
#define IPR_ATA_FLAG_PACKET_CMD 0x80
#define IPR_ATA_FLAG_XFER_TYPE_DMA 0x40
@@ -442,28 +512,49 @@ struct ipr_ioadl_desc {
__be32 address;
}__attribute__((packed, aligned (8)));
+struct ipr_ioadl64_desc {
+ __be32 flags;
+ __be32 data_len;
+ __be64 address;
+}__attribute__((packed, aligned (16)));
+
+struct ipr_ata64_ioadl {
+ struct ipr_ioarcb_ata_regs regs;
+ u16 reserved[5];
+ struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES];
+}__attribute__((packed, aligned (16)));
+
struct ipr_ioarcb_add_data {
union {
struct ipr_ioarcb_ata_regs regs;
struct ipr_ioadl_desc ioadl[5];
__be32 add_cmd_parms[10];
- }u;
-}__attribute__ ((packed, aligned(4)));
+ } u;
+}__attribute__ ((packed, aligned (4)));
+
+struct ipr_ioarcb_sis64_add_addr_ecb {
+ __be64 ioasa_host_pci_addr;
+ __be64 data_ioadl_addr;
+ __be64 reserved;
+ __be32 ext_control_buf[4];
+}__attribute__((packed, aligned (8)));
/* IOA Request Control Block 128 bytes */
struct ipr_ioarcb {
- __be32 ioarcb_host_pci_addr;
- __be32 reserved;
+ union {
+ __be32 ioarcb_host_pci_addr;
+ __be64 ioarcb_host_pci_addr64;
+ } a;
__be32 res_handle;
__be32 host_response_handle;
__be32 reserved1;
__be32 reserved2;
__be32 reserved3;
- __be32 write_data_transfer_length;
+ __be32 data_transfer_length;
__be32 read_data_transfer_length;
__be32 write_ioadl_addr;
- __be32 write_ioadl_len;
+ __be32 ioadl_len;
__be32 read_ioadl_addr;
__be32 read_ioadl_len;
@@ -473,8 +564,14 @@ struct ipr_ioarcb {
struct ipr_cmd_pkt cmd_pkt;
- __be32 add_cmd_parms_len;
- struct ipr_ioarcb_add_data add_data;
+ __be16 add_cmd_parms_offset;
+ __be16 add_cmd_parms_len;
+
+ union {
+ struct ipr_ioarcb_add_data add_data;
+ struct ipr_ioarcb_sis64_add_addr_ecb sis64_addr_data;
+ } u;
+
}__attribute__((packed, aligned (4)));
struct ipr_ioasa_vset {
@@ -676,12 +773,29 @@ struct ipr_hostrcb_device_data_entry_enhanced {
struct ipr_ext_vpd cfc_last_with_dev_vpd;
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb64_device_data_entry_enhanced {
+ struct ipr_ext_vpd vpd;
+ u8 ccin[4];
+ u8 res_path[8];
+ struct ipr_ext_vpd new_vpd;
+ u8 new_ccin[4];
+ struct ipr_ext_vpd ioa_last_with_dev_vpd;
+ struct ipr_ext_vpd cfc_last_with_dev_vpd;
+}__attribute__((packed, aligned (4)));
+
struct ipr_hostrcb_array_data_entry {
struct ipr_vpd vpd;
struct ipr_res_addr expected_dev_res_addr;
struct ipr_res_addr dev_res_addr;
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb64_array_data_entry {
+ struct ipr_ext_vpd vpd;
+ u8 ccin[4];
+ u8 expected_res_path[8];
+ u8 res_path[8];
+}__attribute__((packed, aligned (4)));
+
struct ipr_hostrcb_array_data_entry_enhanced {
struct ipr_ext_vpd vpd;
u8 ccin[4];
@@ -733,6 +847,14 @@ struct ipr_hostrcb_type_13_error {
struct ipr_hostrcb_device_data_entry_enhanced dev[3];
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb_type_23_error {
+ struct ipr_ext_vpd ioa_vpd;
+ struct ipr_ext_vpd cfc_vpd;
+ __be32 errors_detected;
+ __be32 errors_logged;
+ struct ipr_hostrcb64_device_data_entry_enhanced dev[3];
+}__attribute__((packed, aligned (4)));
+
struct ipr_hostrcb_type_04_error {
struct ipr_vpd ioa_vpd;
struct ipr_vpd cfc_vpd;
@@ -760,6 +882,22 @@ struct ipr_hostrcb_type_14_error {
struct ipr_hostrcb_array_data_entry_enhanced array_member[18];
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb_type_24_error {
+ struct ipr_ext_vpd ioa_vpd;
+ struct ipr_ext_vpd cfc_vpd;
+ u8 reserved[2];
+ u8 exposed_mode_adn;
+#define IPR_INVALID_ARRAY_DEV_NUM 0xff
+ u8 array_id;
+ u8 last_res_path[8];
+ u8 protection_level[8];
+ struct ipr_ext_vpd array_vpd;
+ u8 description[16];
+ u8 reserved2[3];
+ u8 num_entries;
+ struct ipr_hostrcb64_array_data_entry array_member[32];
+}__attribute__((packed, aligned (4)));
+
struct ipr_hostrcb_type_07_error {
u8 failure_reason[64];
struct ipr_vpd vpd;
@@ -797,6 +935,22 @@ struct ipr_hostrcb_config_element {
__be32 wwid[2];
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb64_config_element {
+ __be16 length;
+ u8 descriptor_id;
+#define IPR_DESCRIPTOR_MASK 0xC0
+#define IPR_DESCRIPTOR_SIS64 0x00
+
+ u8 reserved;
+ u8 type_status;
+
+ u8 reserved2[2];
+ u8 link_rate;
+
+ u8 res_path[8];
+ __be32 wwid[2];
+}__attribute__((packed, aligned (8)));
+
struct ipr_hostrcb_fabric_desc {
__be16 length;
u8 ioa_port;
@@ -818,6 +972,20 @@ struct ipr_hostrcb_fabric_desc {
struct ipr_hostrcb_config_element elem[1];
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb64_fabric_desc {
+ __be16 length;
+ u8 descriptor_id;
+
+ u8 reserved;
+ u8 path_state;
+
+ u8 reserved2[2];
+ u8 res_path[8];
+ u8 reserved3[6];
+ __be16 num_entries;
+ struct ipr_hostrcb64_config_element elem[1];
+}__attribute__((packed, aligned (8)));
+
#define for_each_fabric_cfg(fabric, cfg) \
for (cfg = (fabric)->elem; \
cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \
@@ -830,10 +998,17 @@ struct ipr_hostrcb_type_20_error {
struct ipr_hostrcb_fabric_desc desc[1];
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb_type_30_error {
+ u8 failure_reason[64];
+ u8 reserved[3];
+ u8 num_entries;
+ struct ipr_hostrcb64_fabric_desc desc[1];
+}__attribute__((packed, aligned (4)));
+
struct ipr_hostrcb_error {
- __be32 failing_dev_ioasc;
- struct ipr_res_addr failing_dev_res_addr;
- __be32 failing_dev_res_handle;
+ __be32 fd_ioasc;
+ struct ipr_res_addr fd_res_addr;
+ __be32 fd_res_handle;
__be32 prc;
union {
struct ipr_hostrcb_type_ff_error type_ff_error;
@@ -850,6 +1025,26 @@ struct ipr_hostrcb_error {
} u;
}__attribute__((packed, aligned (4)));
+struct ipr_hostrcb64_error {
+ __be32 fd_ioasc;
+ __be32 ioa_fw_level;
+ __be32 fd_res_handle;
+ __be32 prc;
+ __be64 fd_dev_id;
+ __be64 fd_lun;
+ u8 fd_res_path[8];
+ __be64 time_stamp;
+ u8 reserved[2];
+ union {
+ struct ipr_hostrcb_type_ff_error type_ff_error;
+ struct ipr_hostrcb_type_12_error type_12_error;
+ struct ipr_hostrcb_type_17_error type_17_error;
+ struct ipr_hostrcb_type_23_error type_23_error;
+ struct ipr_hostrcb_type_24_error type_24_error;
+ struct ipr_hostrcb_type_30_error type_30_error;
+ } u;
+}__attribute__((packed, aligned (8)));
+
struct ipr_hostrcb_raw {
__be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)];
}__attribute__((packed, aligned (4)));
@@ -887,7 +1082,11 @@ struct ipr_hcam {
#define IPR_HOST_RCB_OVERLAY_ID_16 0x16
#define IPR_HOST_RCB_OVERLAY_ID_17 0x17
#define IPR_HOST_RCB_OVERLAY_ID_20 0x20
-#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF
+#define IPR_HOST_RCB_OVERLAY_ID_23 0x23
+#define IPR_HOST_RCB_OVERLAY_ID_24 0x24
+#define IPR_HOST_RCB_OVERLAY_ID_26 0x26
+#define IPR_HOST_RCB_OVERLAY_ID_30 0x30
+#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF
u8 reserved1[3];
__be32 ilid;
@@ -897,6 +1096,7 @@ struct ipr_hcam {
union {
struct ipr_hostrcb_error error;
+ struct ipr_hostrcb64_error error64;
struct ipr_hostrcb_cfg_ch_not ccn;
struct ipr_hostrcb_raw raw;
} u;
@@ -907,14 +1107,14 @@ struct ipr_hostrcb {
dma_addr_t hostrcb_dma;
struct list_head queue;
struct ipr_ioa_cfg *ioa_cfg;
+ char rp_buffer[IPR_MAX_RES_PATH_LENGTH];
};
/* IPR smart dump table structures */
struct ipr_sdt_entry {
- __be32 bar_str_offset;
- __be32 end_offset;
- u8 entry_byte;
- u8 reserved[3];
+ __be32 start_token;
+ __be32 end_token;
+ u8 reserved[4];
u8 flags;
#define IPR_SDT_ENDIAN 0x80
@@ -960,28 +1160,48 @@ struct ipr_sata_port {
};
struct ipr_resource_entry {
- struct ipr_config_table_entry cfgte;
u8 needs_sync_complete:1;
u8 in_erp:1;
u8 add_to_ml:1;
u8 del_from_ml:1;
u8 resetting_device:1;
+ u32 bus; /* AKA channel */
+ u32 target; /* AKA id */
+ u32 lun;
+#define IPR_ARRAY_VIRTUAL_BUS 0x1
+#define IPR_VSET_VIRTUAL_BUS 0x2
+#define IPR_IOAFP_VIRTUAL_BUS 0x3
+
+#define IPR_GET_RES_PHYS_LOC(res) \
+ (((res)->bus << 24) | ((res)->target << 8) | (res)->lun)
+
+ u8 ata_class;
+
+ u8 flags;
+ __be16 res_flags;
+
+ __be32 type;
+
+ u8 qmodel;
+ struct ipr_std_inq_data std_inq_data;
+
+ __be32 res_handle;
+ __be64 dev_id;
+ struct scsi_lun dev_lun;
+ u8 res_path[8];
+
+ struct ipr_ioa_cfg *ioa_cfg;
struct scsi_device *sdev;
struct ipr_sata_port *sata_port;
struct list_head queue;
-};
+}; /* struct ipr_resource_entry */
struct ipr_resource_hdr {
u16 num_entries;
u16 reserved;
};
-struct ipr_resource_table {
- struct ipr_resource_hdr hdr;
- struct ipr_resource_entry dev[IPR_MAX_PHYSICAL_DEVS];
-};
-
struct ipr_misc_cbs {
struct ipr_ioa_vpd ioa_vpd;
struct ipr_inquiry_page0 page0_data;
@@ -994,27 +1214,51 @@ struct ipr_misc_cbs {
struct ipr_interrupt_offsets {
unsigned long set_interrupt_mask_reg;
unsigned long clr_interrupt_mask_reg;
+ unsigned long clr_interrupt_mask_reg32;
unsigned long sense_interrupt_mask_reg;
+ unsigned long sense_interrupt_mask_reg32;
unsigned long clr_interrupt_reg;
+ unsigned long clr_interrupt_reg32;
unsigned long sense_interrupt_reg;
+ unsigned long sense_interrupt_reg32;
unsigned long ioarrin_reg;
unsigned long sense_uproc_interrupt_reg;
+ unsigned long sense_uproc_interrupt_reg32;
unsigned long set_uproc_interrupt_reg;
+ unsigned long set_uproc_interrupt_reg32;
unsigned long clr_uproc_interrupt_reg;
+ unsigned long clr_uproc_interrupt_reg32;
+
+ unsigned long init_feedback_reg;
+
+ unsigned long dump_addr_reg;
+ unsigned long dump_data_reg;
};
struct ipr_interrupts {
void __iomem *set_interrupt_mask_reg;
void __iomem *clr_interrupt_mask_reg;
+ void __iomem *clr_interrupt_mask_reg32;
void __iomem *sense_interrupt_mask_reg;
+ void __iomem *sense_interrupt_mask_reg32;
void __iomem *clr_interrupt_reg;
+ void __iomem *clr_interrupt_reg32;
void __iomem *sense_interrupt_reg;
+ void __iomem *sense_interrupt_reg32;
void __iomem *ioarrin_reg;
void __iomem *sense_uproc_interrupt_reg;
+ void __iomem *sense_uproc_interrupt_reg32;
void __iomem *set_uproc_interrupt_reg;
+ void __iomem *set_uproc_interrupt_reg32;
void __iomem *clr_uproc_interrupt_reg;
+ void __iomem *clr_uproc_interrupt_reg32;
+
+ void __iomem *init_feedback_reg;
+
+ void __iomem *dump_addr_reg;
+ void __iomem *dump_data_reg;
};
struct ipr_chip_cfg_t {
@@ -1029,6 +1273,9 @@ struct ipr_chip_t {
u16 intr_type;
#define IPR_USE_LSI 0x00
#define IPR_USE_MSI 0x01
+ u16 sis_type;
+#define IPR_SIS32 0x00
+#define IPR_SIS64 0x01
const struct ipr_chip_cfg_t *cfg;
};
@@ -1073,13 +1320,6 @@ enum ipr_sdt_state {
DUMP_OBTAINED
};
-enum ipr_cache_state {
- CACHE_NONE,
- CACHE_DISABLED,
- CACHE_ENABLED,
- CACHE_INVALID
-};
-
/* Per-controller data */
struct ipr_ioa_cfg {
char eye_catcher[8];
@@ -1099,10 +1339,17 @@ struct ipr_ioa_cfg {
u8 dual_raid:1;
u8 needs_warm_reset:1;
u8 msi_received:1;
+ u8 sis64:1;
u8 revid;
- enum ipr_cache_state cache_state;
+ /*
+ * Bitmaps for SIS64 generated target values
+ */
+ unsigned long *target_ids;
+ unsigned long *array_ids;
+ unsigned long *vset_ids;
+
u16 type; /* CCIN of the card */
u8 log_level;
@@ -1133,8 +1380,13 @@ struct ipr_ioa_cfg {
char cfg_table_start[8];
#define IPR_CFG_TBL_START "cfg"
- struct ipr_config_table *cfg_table;
+ union {
+ struct ipr_config_table *cfg_table;
+ struct ipr_config_table64 *cfg_table64;
+ } u;
dma_addr_t cfg_table_dma;
+ u32 cfg_table_size;
+ u32 max_devs_supported;
char resource_table_label[8];
#define IPR_RES_TABLE_LABEL "res_tbl"
@@ -1202,13 +1454,17 @@ struct ipr_ioa_cfg {
char ipr_cmd_label[8];
#define IPR_CMD_LABEL "ipr_cmd"
struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS];
- u32 ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS];
-};
+ dma_addr_t ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS];
+}; /* struct ipr_ioa_cfg */
struct ipr_cmnd {
struct ipr_ioarcb ioarcb;
+ union {
+ struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
+ struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES];
+ struct ipr_ata64_ioadl ata_ioadl;
+ } i;
struct ipr_ioasa ioasa;
- struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
struct list_head queue;
struct scsi_cmnd *scsi_cmd;
struct ata_queued_cmd *qc;
@@ -1221,7 +1477,7 @@ struct ipr_cmnd {
u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
dma_addr_t sense_buffer_dma;
unsigned short dma_use_sg;
- dma_addr_t dma_handle;
+ dma_addr_t dma_addr;
struct ipr_cmnd *sibling;
union {
enum ipr_shutdown_type shutdown_type;
@@ -1314,8 +1570,6 @@ struct ipr_ioa_dump {
u32 next_page_index;
u32 page_offset;
u32 format;
-#define IPR_SDT_FMT2 2
-#define IPR_SDT_UNKNOWN 3
}__attribute__((packed, aligned (4)));
struct ipr_dump {
@@ -1377,6 +1631,13 @@ struct ipr_ucode_image_header {
#define ipr_info(...) printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)
#define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__))
+#define ipr_res_printk(level, ioa_cfg, bus, target, lun, fmt, ...) \
+ printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \
+ bus, target, lun, ##__VA_ARGS__)
+
+#define ipr_res_err(ioa_cfg, res, fmt, ...) \
+ ipr_res_printk(KERN_ERR, ioa_cfg, (res)->bus, (res)->target, (res)->lun, fmt, ##__VA_ARGS__)
+
#define ipr_ra_printk(level, ioa_cfg, ra, fmt, ...) \
printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \
(ra).bus, (ra).target, (ra).lun, ##__VA_ARGS__)
@@ -1384,9 +1645,6 @@ struct ipr_ucode_image_header {
#define ipr_ra_err(ioa_cfg, ra, fmt, ...) \
ipr_ra_printk(KERN_ERR, ioa_cfg, ra, fmt, ##__VA_ARGS__)
-#define ipr_res_err(ioa_cfg, res, fmt, ...) \
- ipr_ra_err(ioa_cfg, (res)->cfgte.res_addr, fmt, ##__VA_ARGS__)
-
#define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \
{ \
if ((res).bus >= IPR_MAX_NUM_BUSES) { \
@@ -1399,14 +1657,21 @@ struct ipr_ucode_image_header {
}
#define ipr_hcam_err(hostrcb, fmt, ...) \
-{ \
- if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) { \
- ipr_ra_err((hostrcb)->ioa_cfg, \
- (hostrcb)->hcam.u.error.failing_dev_res_addr, \
- fmt, ##__VA_ARGS__); \
- } else { \
- dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__); \
- } \
+{ \
+ if (ipr_is_device(hostrcb)) { \
+ if ((hostrcb)->ioa_cfg->sis64) { \
+ printk(KERN_ERR IPR_NAME ": %s: " fmt, \
+ ipr_format_resource_path(&hostrcb->hcam.u.error64.fd_res_path[0], \
+ &hostrcb->rp_buffer[0]), \
+ __VA_ARGS__); \
+ } else { \
+ ipr_ra_err((hostrcb)->ioa_cfg, \
+ (hostrcb)->hcam.u.error.fd_res_addr, \
+ fmt, __VA_ARGS__); \
+ } \
+ } else { \
+ dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, __VA_ARGS__); \
+ } \
}
#define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\
@@ -1432,7 +1697,7 @@ ipr_err("----------------------------------------------------------\n")
**/
static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res)
{
- return (res->cfgte.flags & IPR_IS_IOA_RESOURCE) ? 1 : 0;
+ return res->type == IPR_RES_TYPE_IOAFP;
}
/**
@@ -1444,12 +1709,8 @@ static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res)
**/
static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res)
{
- if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) &&
- !ipr_is_ioa_resource(res) &&
- IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_AF_DASD)
- return 1;
- else
- return 0;
+ return res->type == IPR_RES_TYPE_AF_DASD ||
+ res->type == IPR_RES_TYPE_REMOTE_AF_DASD;
}
/**
@@ -1461,12 +1722,7 @@ static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res)
**/
static inline int ipr_is_vset_device(struct ipr_resource_entry *res)
{
- if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) &&
- !ipr_is_ioa_resource(res) &&
- IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_VOLUME_SET)
- return 1;
- else
- return 0;
+ return res->type == IPR_RES_TYPE_VOLUME_SET;
}
/**
@@ -1478,11 +1734,7 @@ static inline int ipr_is_vset_device(struct ipr_resource_entry *res)
**/
static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
{
- if (!ipr_is_ioa_resource(res) &&
- IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_SCSI)
- return 1;
- else
- return 0;
+ return res->type == IPR_RES_TYPE_GENERIC_SCSI;
}
/**
@@ -1495,7 +1747,7 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res)
{
if (ipr_is_af_dasd_device(res) ||
- (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data)))
+ (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->std_inq_data)))
return 1;
else
return 0;
@@ -1510,11 +1762,7 @@ static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res)
**/
static inline int ipr_is_gata(struct ipr_resource_entry *res)
{
- if (!ipr_is_ioa_resource(res) &&
- IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_ATA)
- return 1;
- else
- return 0;
+ return res->type == IPR_RES_TYPE_GENERIC_ATA;
}
/**
@@ -1526,24 +1774,35 @@ static inline int ipr_is_gata(struct ipr_resource_entry *res)
**/
static inline int ipr_is_naca_model(struct ipr_resource_entry *res)
{
- if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL)
+ if (ipr_is_gscsi(res) && res->qmodel == IPR_QUEUE_NACA_MODEL)
return 1;
return 0;
}
/**
- * ipr_is_device - Determine if resource address is that of a device
- * @res_addr: resource address struct
+ * ipr_is_device - Determine if the hostrcb structure is related to a device
+ * @hostrcb: host resource control blocks struct
*
* Return value:
* 1 if AF / 0 if not AF
**/
-static inline int ipr_is_device(struct ipr_res_addr *res_addr)
+static inline int ipr_is_device(struct ipr_hostrcb *hostrcb)
{
- if ((res_addr->bus < IPR_MAX_NUM_BUSES) &&
- (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1)))
- return 1;
-
+ struct ipr_res_addr *res_addr;
+ u8 *res_path;
+
+ if (hostrcb->ioa_cfg->sis64) {
+ res_path = &hostrcb->hcam.u.error64.fd_res_path[0];
+ if ((res_path[0] == 0x00 || res_path[0] == 0x80 ||
+ res_path[0] == 0x81) && res_path[2] != 0xFF)
+ return 1;
+ } else {
+ res_addr = &hostrcb->hcam.u.error.fd_res_addr;
+
+ if ((res_addr->bus < IPR_MAX_NUM_BUSES) &&
+ (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1)))
+ return 1;
+ }
return 0;
}
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 8a89ba90058..02143af7c1a 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -28,6 +28,7 @@
#include <linux/types.h>
#include <linux/inet.h>
+#include <linux/slab.h>
#include <linux/file.h>
#include <linux/blkdev.h>
#include <linux/crypto.h>
@@ -598,7 +599,7 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock);
- if (sock->sk->sk_sleep && waitqueue_active(sock->sk->sk_sleep)) {
+ if (sock->sk->sk_sleep) {
sock->sk->sk_err = EIO;
wake_up_interruptible(sock->sk->sk_sleep);
}
@@ -874,7 +875,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
.cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler= iscsi_eh_device_reset,
- .eh_target_reset_handler= iscsi_eh_target_reset,
+ .eh_target_reset_handler = iscsi_eh_recover_target,
.use_clustering = DISABLE_CLUSTERING,
.slave_alloc = iscsi_sw_tcp_slave_alloc,
.slave_configure = iscsi_sw_tcp_slave_configure,
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
index b2d481dd375..08e26d4e373 100644
--- a/drivers/scsi/jazz_esp.c
+++ b/drivers/scsi/jazz_esp.c
@@ -4,6 +4,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index b3d31315ac3..23880f8fe7e 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -40,6 +40,7 @@
#include <linux/blkdev.h>
#include <linux/ioport.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/page.h>
#include <asm/pgtable.h>
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index 9b0a5192a96..1087a7f18e8 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -33,6 +33,7 @@
*/
#include <linux/timer.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <asm/unaligned.h>
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 7f4364770e4..e5df0d4db67 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -24,7 +24,7 @@
*/
#include <linux/timer.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <scsi/fc/fc_fc2.h>
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 6fde2fabfd9..17396c708b0 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -27,6 +27,7 @@
#include <linux/scatterlist.h>
#include <linux/err.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi.h>
@@ -48,7 +49,7 @@ struct kmem_cache *scsi_pkt_cachep;
#define FC_SRB_CMD_SENT (1 << 0) /* cmd has been sent */
#define FC_SRB_RCV_STATUS (1 << 1) /* response has arrived */
#define FC_SRB_ABORT_PENDING (1 << 2) /* cmd abort sent to device */
-#define FC_SRB_ABORTED (1 << 3) /* abort acknowleged */
+#define FC_SRB_ABORTED (1 << 3) /* abort acknowledged */
#define FC_SRB_DISCONTIG (1 << 4) /* non-sequential data recvd */
#define FC_SRB_COMPL (1 << 5) /* fc_io_compl has been run */
#define FC_SRB_FCP_PROCESSING_TMO (1 << 6) /* timer function processing */
@@ -519,7 +520,7 @@ crc_err:
*
* Called after receiving a Transfer Ready data descriptor.
* If the LLD is capable of sequence offload then send down the
- * seq_blen ammount of data in single frame, otherwise send
+ * seq_blen amount of data in single frame, otherwise send
* multiple frames of the maximum frame payload supported by
* the target port.
*/
diff --git a/drivers/scsi/libfc/fc_frame.c b/drivers/scsi/libfc/fc_frame.c
index 6da01c61696..981329a17c4 100644
--- a/drivers/scsi/libfc/fc_frame.c
+++ b/drivers/scsi/libfc/fc_frame.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/crc32.h>
+#include <linux/gfp.h>
#include <scsi/fc_frame.h>
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 7ec8ce75007..d126ecfff70 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -88,6 +88,7 @@
*/
#include <linux/timer.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include <scsi/fc/fc_gs.h>
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 97923bb0776..b37d0ff28b3 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -47,6 +47,7 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/rcupdate.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 703eb6a8879..6d5ae4474bb 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -25,6 +25,7 @@
#include <linux/kfifo.h>
#include <linux/delay.h>
#include <linux/log2.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include <net/tcp.h>
#include <scsi/scsi_cmnd.h>
@@ -2338,7 +2339,7 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
* This function will wait for a relogin, session termination from
* userspace, or a recovery/replacement timeout.
*/
-static int iscsi_eh_session_reset(struct scsi_cmnd *sc)
+int iscsi_eh_session_reset(struct scsi_cmnd *sc)
{
struct iscsi_cls_session *cls_session;
struct iscsi_session *session;
@@ -2389,6 +2390,7 @@ failed:
mutex_unlock(&session->eh_mutex);
return SUCCESS;
}
+EXPORT_SYMBOL_GPL(iscsi_eh_session_reset);
static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
{
@@ -2403,8 +2405,7 @@ static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
* iscsi_eh_target_reset - reset target
* @sc: scsi command
*
- * This will attempt to send a warm target reset. If that fails
- * then we will drop the session and attempt ERL0 recovery.
+ * This will attempt to send a warm target reset.
*/
int iscsi_eh_target_reset(struct scsi_cmnd *sc)
{
@@ -2476,12 +2477,27 @@ done:
ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname,
rc == SUCCESS ? "SUCCESS" : "FAILED");
mutex_unlock(&session->eh_mutex);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
+
+/**
+ * iscsi_eh_recover_target - reset target and possibly the session
+ * @sc: scsi command
+ *
+ * This will attempt to send a warm target reset. If that fails,
+ * we will escalate to ERL0 session recovery.
+ */
+int iscsi_eh_recover_target(struct scsi_cmnd *sc)
+{
+ int rc;
+ rc = iscsi_eh_target_reset(sc);
if (rc == FAILED)
rc = iscsi_eh_session_reset(sc);
return rc;
}
-EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
+EXPORT_SYMBOL_GPL(iscsi_eh_recover_target);
/*
* Pre-allocate a pool of @max items of @item_size. By default, the pool
@@ -3072,14 +3088,15 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
session->state = ISCSI_STATE_TERMINATE;
else if (conn->stop_stage != STOP_CONN_RECOVER)
session->state = ISCSI_STATE_IN_RECOVERY;
+
+ old_stop_stage = conn->stop_stage;
+ conn->stop_stage = flag;
spin_unlock_bh(&session->lock);
del_timer_sync(&conn->transport_timer);
iscsi_suspend_tx(conn);
spin_lock_bh(&session->lock);
- old_stop_stage = conn->stop_stage;
- conn->stop_stage = flag;
conn->c_stage = ISCSI_CONN_STOPPED;
spin_unlock_bh(&session->lock);
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index 4ad87fd74dd..5c92620292f 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/inet.h>
+#include <linux/slab.h>
#include <linux/file.h>
#include <linux/blkdev.h>
#include <linux/crypto.h>
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index e1550117069..b00efd19aad 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -22,6 +22,7 @@
*/
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <scsi/sas_ata.h>
#include "sas_internal.h"
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index facc5bfcf7d..f5831930df9 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -23,6 +23,7 @@
*/
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_eh.h>
#include "sas_internal.h"
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 33cf988c8c8..c65af02dcfe 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -24,6 +24,7 @@
#include <linux/scatterlist.h>
#include <linux/blkdev.h>
+#include <linux/slab.h>
#include "sas_internal.h"
diff --git a/drivers/scsi/libsas/sas_host_smp.c b/drivers/scsi/libsas/sas_host_smp.c
index 1bc3b756799..04ad8dd1a74 100644
--- a/drivers/scsi/libsas/sas_host_smp.c
+++ b/drivers/scsi/libsas/sas_host_smp.c
@@ -10,6 +10,7 @@
*/
#include <linux/scatterlist.h>
#include <linux/blkdev.h>
+#include <linux/slab.h>
#include "sas_internal.h"
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index 9cd5abe9e71..2dc55343f67 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -24,6 +24,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/spinlock.h>
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 14b13196b22..2660e1b4569 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -44,6 +44,7 @@
#include <linux/err.h>
#include <linux/blkdev.h>
#include <linux/freezer.h>
+#include <linux/gfp.h>
#include <linux/scatterlist.h>
#include <linux/libata.h>
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
index 22775165bf6..ff6a28ce9b6 100644
--- a/drivers/scsi/libsrp.c
+++ b/drivers/scsi/libsrp.c
@@ -19,6 +19,7 @@
* 02110-1301 USA
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/kfifo.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 84b696463a5..565e16dd74f 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -37,6 +37,9 @@ struct lpfc_sli2_slim;
the NameServer before giving up. */
#define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */
#define LPFC_DEFAULT_SG_SEG_CNT 64 /* sg element count per scsi cmnd */
+#define LPFC_DEFAULT_MENLO_SG_SEG_CNT 128 /* sg element count per scsi
+ cmnd for menlo needs nearly twice as for firmware
+ downloads using bsg */
#define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */
#define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */
#define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/
@@ -509,7 +512,6 @@ struct lpfc_hba {
int (*lpfc_hba_down_link)
(struct lpfc_hba *);
-
/* SLI4 specific HBA data structure */
struct lpfc_sli4_hba sli4_hba;
@@ -623,6 +625,9 @@ struct lpfc_hba {
uint32_t cfg_log_verbose;
uint32_t cfg_aer_support;
uint32_t cfg_suppress_link_up;
+#define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */
+#define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */
+#define LPFC_DELAY_INIT_LINK_INDEFINITELY 2 /* wait, manual intervention */
lpfc_vpd_t vpd; /* vital product data */
@@ -804,6 +809,9 @@ struct lpfc_hba {
struct list_head ct_ev_waiters;
struct unsol_rcv_ct_ctx ct_ctx[64];
uint32_t ctx_idx;
+
+ uint8_t menlo_flag; /* menlo generic flags */
+#define HBA_MENLO_SUPPORT 0x1 /* HBA supports menlo commands */
};
static inline struct Scsi_Host *
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index c992e8328f9..1849e33e68f 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -24,6 +24,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/aer.h>
+#include <linux/gfp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
@@ -1939,7 +1940,9 @@ static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO,
# 0x2 = never bring up link
# Default value is 0.
*/
-LPFC_ATTR_R(suppress_link_up, 0, 0, 2, "Suppress Link Up at initialization");
+LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
+ LPFC_DELAY_INIT_LINK_INDEFINITELY,
+ "Suppress Link Up at initialization");
/*
# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
@@ -1966,8 +1969,7 @@ lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
{
struct Scsi_Host *shost = class_to_shost(dev);
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
- int val = 0;
- val = vport->cfg_devloss_tmo;
+
return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
}
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index f3f1bf1a0a7..d62b3e46792 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/mempool.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <scsi/scsi.h>
@@ -83,15 +84,28 @@ struct lpfc_bsg_mbox {
struct fc_bsg_job *set_job;
};
+#define MENLO_DID 0x0000FC0E
+
+struct lpfc_bsg_menlo {
+ struct lpfc_iocbq *cmdiocbq;
+ struct lpfc_iocbq *rspiocbq;
+ struct lpfc_dmabuf *bmp;
+
+ /* job waiting for this iocb to finish */
+ struct fc_bsg_job *set_job;
+};
+
#define TYPE_EVT 1
#define TYPE_IOCB 2
#define TYPE_MBOX 3
+#define TYPE_MENLO 4
struct bsg_job_data {
uint32_t type;
union {
struct lpfc_bsg_event *evt;
struct lpfc_bsg_iocb iocb;
struct lpfc_bsg_mbox mbox;
+ struct lpfc_bsg_menlo menlo;
} context_un;
};
@@ -419,7 +433,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
dd_data = cmdiocbq->context1;
/* normal completion and timeout crossed paths, already done */
if (!dd_data) {
- spin_unlock_irqrestore(&phba->hbalock, flags);
+ spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
return;
}
@@ -1182,7 +1196,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
dd_data = cmdiocbq->context1;
/* normal completion and timeout crossed paths, already done */
if (!dd_data) {
- spin_unlock_irqrestore(&phba->hbalock, flags);
+ spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
return;
}
@@ -2456,6 +2470,18 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
case MBX_PORT_IOV_CONTROL:
break;
case MBX_SET_VARIABLE:
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "1226 mbox: set_variable 0x%x, 0x%x\n",
+ mb->un.varWords[0],
+ mb->un.varWords[1]);
+ if ((mb->un.varWords[0] == SETVAR_MLOMNT)
+ && (mb->un.varWords[1] == 1)) {
+ phba->wait_4_mlo_maint_flg = 1;
+ } else if (mb->un.varWords[0] == SETVAR_MLORST) {
+ phba->link_flag &= ~LS_LOOPBACK_MODE;
+ phba->fc_topology = TOPOLOGY_PT_PT;
+ }
+ break;
case MBX_RUN_BIU_DIAG64:
case MBX_READ_EVENT_LOG:
case MBX_READ_SPARM64:
@@ -2638,6 +2664,297 @@ job_error:
}
/**
+ * lpfc_bsg_menlo_cmd_cmp - lpfc_menlo_cmd completion handler
+ * @phba: Pointer to HBA context object.
+ * @cmdiocbq: Pointer to command iocb.
+ * @rspiocbq: Pointer to response iocb.
+ *
+ * This function is the completion handler for iocbs issued using
+ * lpfc_menlo_cmd function. This function is called by the
+ * ring event handler function without any lock held. This function
+ * can be called from both worker thread context and interrupt
+ * context. This function also can be called from another thread which
+ * cleans up the SLI layer objects.
+ * This function copies the contents of the response iocb to the
+ * response iocb memory object provided by the caller of
+ * lpfc_sli_issue_iocb_wait and then wakes up the thread which
+ * sleeps for the iocb completion.
+ **/
+static void
+lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
+ struct lpfc_iocbq *cmdiocbq,
+ struct lpfc_iocbq *rspiocbq)
+{
+ struct bsg_job_data *dd_data;
+ struct fc_bsg_job *job;
+ IOCB_t *rsp;
+ struct lpfc_dmabuf *bmp;
+ struct lpfc_bsg_menlo *menlo;
+ unsigned long flags;
+ struct menlo_response *menlo_resp;
+ int rc = 0;
+
+ spin_lock_irqsave(&phba->ct_ev_lock, flags);
+ dd_data = cmdiocbq->context1;
+ if (!dd_data) {
+ spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+ return;
+ }
+
+ menlo = &dd_data->context_un.menlo;
+ job = menlo->set_job;
+ job->dd_data = NULL; /* so timeout handler does not reply */
+
+ spin_lock_irqsave(&phba->hbalock, flags);
+ cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
+ if (cmdiocbq->context2 && rspiocbq)
+ memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
+ &rspiocbq->iocb, sizeof(IOCB_t));
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+
+ bmp = menlo->bmp;
+ rspiocbq = menlo->rspiocbq;
+ rsp = &rspiocbq->iocb;
+
+ pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+ job->request_payload.sg_cnt, DMA_TO_DEVICE);
+ pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+ job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+ /* always return the xri, this would be used in the case
+ * of a menlo download to allow the data to be sent as a continuation
+ * of the exchange.
+ */
+ menlo_resp = (struct menlo_response *)
+ job->reply->reply_data.vendor_reply.vendor_rsp;
+ menlo_resp->xri = rsp->ulpContext;
+ if (rsp->ulpStatus) {
+ if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+ switch (rsp->un.ulpWord[4] & 0xff) {
+ case IOERR_SEQUENCE_TIMEOUT:
+ rc = -ETIMEDOUT;
+ break;
+ case IOERR_INVALID_RPI:
+ rc = -EFAULT;
+ break;
+ default:
+ rc = -EACCES;
+ break;
+ }
+ } else
+ rc = -EACCES;
+ } else
+ job->reply->reply_payload_rcv_len =
+ rsp->un.genreq64.bdl.bdeSize;
+
+ lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+ lpfc_sli_release_iocbq(phba, rspiocbq);
+ lpfc_sli_release_iocbq(phba, cmdiocbq);
+ kfree(bmp);
+ kfree(dd_data);
+ /* make error code available to userspace */
+ job->reply->result = rc;
+ /* complete the job back to userspace */
+ job->job_done(job);
+ spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+ return;
+}
+
+/**
+ * lpfc_menlo_cmd - send an ioctl for menlo hardware
+ * @job: fc_bsg_job to handle
+ *
+ * This function issues a gen request 64 CR ioctl for all menlo cmd requests,
+ * all the command completions will return the xri for the command.
+ * For menlo data requests a gen request 64 CX is used to continue the exchange
+ * supplied in the menlo request header xri field.
+ **/
+static int
+lpfc_menlo_cmd(struct fc_bsg_job *job)
+{
+ struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+ struct lpfc_hba *phba = vport->phba;
+ struct lpfc_iocbq *cmdiocbq, *rspiocbq;
+ IOCB_t *cmd, *rsp;
+ int rc = 0;
+ struct menlo_command *menlo_cmd;
+ struct menlo_response *menlo_resp;
+ struct lpfc_dmabuf *bmp = NULL;
+ int request_nseg;
+ int reply_nseg;
+ struct scatterlist *sgel = NULL;
+ int numbde;
+ dma_addr_t busaddr;
+ struct bsg_job_data *dd_data;
+ struct ulp_bde64 *bpl = NULL;
+
+ /* in case no data is returned return just the return code */
+ job->reply->reply_payload_rcv_len = 0;
+
+ if (job->request_len <
+ sizeof(struct fc_bsg_request) +
+ sizeof(struct menlo_command)) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+ "2784 Received MENLO_CMD request below "
+ "minimum size\n");
+ rc = -ERANGE;
+ goto no_dd_data;
+ }
+
+ if (job->reply_len <
+ sizeof(struct fc_bsg_request) + sizeof(struct menlo_response)) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+ "2785 Received MENLO_CMD reply below "
+ "minimum size\n");
+ rc = -ERANGE;
+ goto no_dd_data;
+ }
+
+ if (!(phba->menlo_flag & HBA_MENLO_SUPPORT)) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+ "2786 Adapter does not support menlo "
+ "commands\n");
+ rc = -EPERM;
+ goto no_dd_data;
+ }
+
+ menlo_cmd = (struct menlo_command *)
+ job->request->rqst_data.h_vendor.vendor_cmd;
+
+ menlo_resp = (struct menlo_response *)
+ job->reply->reply_data.vendor_reply.vendor_rsp;
+
+ /* allocate our bsg tracking structure */
+ dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+ if (!dd_data) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+ "2787 Failed allocation of dd_data\n");
+ rc = -ENOMEM;
+ goto no_dd_data;
+ }
+
+ bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+ if (!bmp) {
+ rc = -ENOMEM;
+ goto free_dd;
+ }
+
+ cmdiocbq = lpfc_sli_get_iocbq(phba);
+ if (!cmdiocbq) {
+ rc = -ENOMEM;
+ goto free_bmp;
+ }
+
+ rspiocbq = lpfc_sli_get_iocbq(phba);
+ if (!rspiocbq) {
+ rc = -ENOMEM;
+ goto free_cmdiocbq;
+ }
+
+ rsp = &rspiocbq->iocb;
+
+ bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
+ if (!bmp->virt) {
+ rc = -ENOMEM;
+ goto free_rspiocbq;
+ }
+
+ INIT_LIST_HEAD(&bmp->list);
+ bpl = (struct ulp_bde64 *) bmp->virt;
+ request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
+ job->request_payload.sg_cnt, DMA_TO_DEVICE);
+ for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
+ busaddr = sg_dma_address(sgel);
+ bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ bpl->tus.f.bdeSize = sg_dma_len(sgel);
+ bpl->tus.w = cpu_to_le32(bpl->tus.w);
+ bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+ bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+ bpl++;
+ }
+
+ reply_nseg = pci_map_sg(phba->pcidev, job->reply_payload.sg_list,
+ job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+ for_each_sg(job->reply_payload.sg_list, sgel, reply_nseg, numbde) {
+ busaddr = sg_dma_address(sgel);
+ bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
+ bpl->tus.f.bdeSize = sg_dma_len(sgel);
+ bpl->tus.w = cpu_to_le32(bpl->tus.w);
+ bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+ bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+ bpl++;
+ }
+
+ cmd = &cmdiocbq->iocb;
+ cmd->un.genreq64.bdl.ulpIoTag32 = 0;
+ cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
+ cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
+ cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+ cmd->un.genreq64.bdl.bdeSize =
+ (request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
+ cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
+ cmd->un.genreq64.w5.hcsw.Dfctl = 0;
+ cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CMD;
+ cmd->un.genreq64.w5.hcsw.Type = MENLO_TRANSPORT_TYPE; /* 0xfe */
+ cmd->ulpBdeCount = 1;
+ cmd->ulpClass = CLASS3;
+ cmd->ulpOwner = OWN_CHIP;
+ cmd->ulpLe = 1; /* Limited Edition */
+ cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
+ cmdiocbq->vport = phba->pport;
+ /* We want the firmware to timeout before we do */
+ cmd->ulpTimeout = MENLO_TIMEOUT - 5;
+ cmdiocbq->context3 = bmp;
+ cmdiocbq->context2 = rspiocbq;
+ cmdiocbq->iocb_cmpl = lpfc_bsg_menlo_cmd_cmp;
+ cmdiocbq->context1 = dd_data;
+ cmdiocbq->context2 = rspiocbq;
+ if (menlo_cmd->cmd == LPFC_BSG_VENDOR_MENLO_CMD) {
+ cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
+ cmd->ulpPU = MENLO_PU; /* 3 */
+ cmd->un.ulpWord[4] = MENLO_DID; /* 0x0000FC0E */
+ cmd->ulpContext = MENLO_CONTEXT; /* 0 */
+ } else {
+ cmd->ulpCommand = CMD_GEN_REQUEST64_CX;
+ cmd->ulpPU = 1;
+ cmd->un.ulpWord[4] = 0;
+ cmd->ulpContext = menlo_cmd->xri;
+ }
+
+ dd_data->type = TYPE_MENLO;
+ dd_data->context_un.menlo.cmdiocbq = cmdiocbq;
+ dd_data->context_un.menlo.rspiocbq = rspiocbq;
+ dd_data->context_un.menlo.set_job = job;
+ dd_data->context_un.menlo.bmp = bmp;
+
+ rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq,
+ MENLO_TIMEOUT - 5);
+ if (rc == IOCB_SUCCESS)
+ return 0; /* done for now */
+
+ /* iocb failed so cleanup */
+ pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+ job->request_payload.sg_cnt, DMA_TO_DEVICE);
+ pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+ job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+ lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+
+free_rspiocbq:
+ lpfc_sli_release_iocbq(phba, rspiocbq);
+free_cmdiocbq:
+ lpfc_sli_release_iocbq(phba, cmdiocbq);
+free_bmp:
+ kfree(bmp);
+free_dd:
+ kfree(dd_data);
+no_dd_data:
+ /* make error code available to userspace */
+ job->reply->result = rc;
+ job->dd_data = NULL;
+ return rc;
+}
+/**
* lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
* @job: fc_bsg_job to handle
**/
@@ -2669,6 +2986,10 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
case LPFC_BSG_VENDOR_MBOX:
rc = lpfc_bsg_mbox_cmd(job);
break;
+ case LPFC_BSG_VENDOR_MENLO_CMD:
+ case LPFC_BSG_VENDOR_MENLO_DATA:
+ rc = lpfc_menlo_cmd(job);
+ break;
default:
rc = -EINVAL;
job->reply->reply_payload_rcv_len = 0;
@@ -2728,6 +3049,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
struct lpfc_bsg_event *evt;
struct lpfc_bsg_iocb *iocb;
struct lpfc_bsg_mbox *mbox;
+ struct lpfc_bsg_menlo *menlo;
struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
struct bsg_job_data *dd_data;
unsigned long flags;
@@ -2775,6 +3097,17 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
job->job_done(job);
break;
+ case TYPE_MENLO:
+ menlo = &dd_data->context_un.menlo;
+ cmdiocb = menlo->cmdiocbq;
+ /* hint to completion handler that the job timed out */
+ job->reply->result = -EAGAIN;
+ spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+ /* this will call our completion handler */
+ spin_lock_irq(&phba->hbalock);
+ lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb);
+ spin_unlock_irq(&phba->hbalock);
+ break;
default:
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
break;
diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h
index 6c8f87e39b9..5bc630819b9 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.h
+++ b/drivers/scsi/lpfc/lpfc_bsg.h
@@ -31,6 +31,8 @@
#define LPFC_BSG_VENDOR_DIAG_TEST 5
#define LPFC_BSG_VENDOR_GET_MGMT_REV 6
#define LPFC_BSG_VENDOR_MBOX 7
+#define LPFC_BSG_VENDOR_MENLO_CMD 8
+#define LPFC_BSG_VENDOR_MENLO_DATA 9
struct set_ct_event {
uint32_t command;
@@ -96,3 +98,13 @@ struct dfc_mbox_req {
uint8_t mbOffset;
};
+/* Used for menlo command or menlo data. The xri is only used for menlo data */
+struct menlo_command {
+ uint32_t cmd;
+ uint32_t xri;
+};
+
+struct menlo_response {
+ uint32_t xri; /* return the xri of the iocb exchange */
+};
+
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 6f0fb51eb46..5087c4211b4 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -63,6 +63,7 @@ void lpfc_linkdown_port(struct lpfc_vport *);
void lpfc_port_link_failure(struct lpfc_vport *);
void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
void lpfc_retry_pport_discovery(struct lpfc_hba *);
void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -221,6 +222,10 @@ void lpfc_unregister_fcf_rescan(struct lpfc_hba *);
void lpfc_unregister_unused_fcf(struct lpfc_hba *);
int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *);
void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *);
+void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *);
+uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *);
+int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t);
+void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t);
int lpfc_mem_alloc(struct lpfc_hba *, int align);
void lpfc_mem_free(struct lpfc_hba *);
@@ -385,7 +390,7 @@ void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t);
int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
void lpfc_start_fdiscs(struct lpfc_hba *phba);
struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t);
-
+struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t);
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
#define HBA_EVENT_RSCN 5
#define HBA_EVENT_LINK_UP 2
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index c7e921973f6..463b74902ac 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -25,6 +25,7 @@
#include <linux/blkdev.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/utsname.h>
#include <scsi/scsi.h>
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 391584183d8..a80d938fafc 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -24,6 +24,7 @@
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/ctype.h>
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 08b6634cb99..5fbdb22c189 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -21,6 +21,7 @@
/* See Fibre Channel protocol T11 FC-LS for details */
#include <linux/blkdev.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <scsi/scsi.h>
@@ -771,6 +772,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp = cmdiocb->context1;
struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
struct serv_parm *sp;
+ uint16_t fcf_index;
int rc;
/* Check to see if link went down during discovery */
@@ -788,6 +790,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
vport->port_state);
if (irsp->ulpStatus) {
+ /*
+ * In case of FIP mode, perform round robin FCF failover
+ * due to new FCF discovery
+ */
+ if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
+ (phba->fcf.fcf_flag & FCF_DISCOVERY)) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
+ "2611 FLOGI failed on registered "
+ "FCF record fcf_index:%d, trying "
+ "to perform round robin failover\n",
+ phba->fcf.current_rec.fcf_indx);
+ fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
+ if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
+ /*
+ * Exhausted the eligible FCF record list,
+ * fail through to retry FLOGI on current
+ * FCF record.
+ */
+ lpfc_printf_log(phba, KERN_WARNING,
+ LOG_FIP | LOG_ELS,
+ "2760 FLOGI exhausted FCF "
+ "round robin failover list, "
+ "retry FLOGI on the current "
+ "registered FCF index:%d\n",
+ phba->fcf.current_rec.fcf_indx);
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+ spin_unlock_irq(&phba->hbalock);
+ } else {
+ rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
+ fcf_index);
+ if (rc) {
+ lpfc_printf_log(phba, KERN_WARNING,
+ LOG_FIP | LOG_ELS,
+ "2761 FLOGI round "
+ "robin FCF failover "
+ "read FCF failed "
+ "rc:x%x, fcf_index:"
+ "%d\n", rc,
+ phba->fcf.current_rec.fcf_indx);
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+ spin_unlock_irq(&phba->hbalock);
+ } else
+ goto out;
+ }
+ }
+
/* Check for retry */
if (lpfc_els_retry(phba, cmdiocb, rspiocb))
goto out;
@@ -806,9 +856,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
}
/* FLOGI failure */
- lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
- "0100 FLOGI failure Data: x%x x%x "
- "x%x\n",
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n",
irsp->ulpStatus, irsp->un.ulpWord[4],
irsp->ulpTimeout);
goto flogifail;
@@ -842,8 +891,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
else
rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
- if (!rc)
+ if (!rc) {
+ /* Mark the FCF discovery process done */
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS,
+ "2769 FLOGI successful on FCF record: "
+ "current_fcf_index:x%x, terminate FCF "
+ "round robin failover process\n",
+ phba->fcf.current_rec.fcf_indx);
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+ spin_unlock_irq(&phba->hbalock);
goto out;
+ }
}
flogifail:
@@ -981,7 +1040,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
* function returns, it does not guarantee all the IOCBs are actually aborted.
*
* Return code
- * 0 - Sucessfully issued abort iocb on all outstanding flogis (Always 0)
+ * 0 - Successfully issued abort iocb on all outstanding flogis (Always 0)
**/
int
lpfc_els_abort_flogi(struct lpfc_hba *phba)
@@ -1409,6 +1468,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
goto out;
}
/* PLOGI failed */
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "2753 PLOGI failure DID:%06X Status:x%x/x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus,
+ irsp->un.ulpWord[4]);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (lpfc_error_lost_link(irsp))
rc = NLP_STE_FREED_NODE;
@@ -1577,6 +1640,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
goto out;
}
/* PRLI failed */
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "2754 PRLI failure DID:%06X Status:x%x/x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus,
+ irsp->un.ulpWord[4]);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (lpfc_error_lost_link(irsp))
goto out;
@@ -1860,6 +1927,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
goto out;
}
/* ADISC failed */
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus,
+ irsp->un.ulpWord[4]);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (!lpfc_error_lost_link(irsp))
lpfc_disc_state_machine(vport, ndlp, cmdiocb,
@@ -2009,6 +2080,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* ELS command is being retried */
goto out;
/* LOGO failed */
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus,
+ irsp->un.ulpWord[4]);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (lpfc_error_lost_link(irsp))
goto out;
@@ -3129,7 +3204,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
(*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
/* A LS_RJT associated with Default RPI cleanup has its own
- * seperate code path.
+ * separate code path.
*/
if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
ls_rjt = 1;
@@ -5989,7 +6064,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
if (phba->sli_rev < LPFC_SLI_REV4)
lpfc_issue_fabric_reglogin(vport);
else {
- lpfc_start_fdiscs(phba);
+ /*
+ * If the physical port is instantiated using
+ * FDISC, do not start vport discovery.
+ */
+ if (vport->port_state != LPFC_FDISC)
+ lpfc_start_fdiscs(phba);
lpfc_do_scr_ns_plogi(phba, vport);
}
} else
@@ -6055,21 +6135,18 @@ mbox_err_exit:
}
/**
- * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
+ * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer
* @phba: pointer to lpfc hba data structure.
*
- * This routine abort all pending discovery commands and
- * start a timer to retry FLOGI for the physical port
- * discovery.
+ * This routine cancels the retry delay timers to all the vports.
**/
void
-lpfc_retry_pport_discovery(struct lpfc_hba *phba)
+lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
{
struct lpfc_vport **vports;
struct lpfc_nodelist *ndlp;
- struct Scsi_Host *shost;
- int i;
uint32_t link_state;
+ int i;
/* Treat this failure as linkdown for all vports */
link_state = phba->link_state;
@@ -6087,13 +6164,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba)
}
lpfc_destroy_vport_work_array(phba, vports);
}
+}
+
+/**
+ * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine abort all pending discovery commands and
+ * start a timer to retry FLOGI for the physical port
+ * discovery.
+ **/
+void
+lpfc_retry_pport_discovery(struct lpfc_hba *phba)
+{
+ struct lpfc_nodelist *ndlp;
+ struct Scsi_Host *shost;
+
+ /* Cancel the all vports retry delay retry timers */
+ lpfc_cancel_all_vport_retry_delay_timer(phba);
/* If fabric require FLOGI, then re-instantiate physical login */
ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
if (!ndlp)
return;
-
shost = lpfc_shost_from_vport(phba->pport);
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
spin_lock_irq(shost->host_lock);
@@ -6219,7 +6313,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_mbx_unreg_vpi(vport);
spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
- vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
spin_unlock_irq(shost->host_lock);
}
@@ -6797,21 +6892,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
unsigned long iflag = 0;
- spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag);
+ spin_lock_irqsave(&phba->hbalock, iflag);
+ spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
list_for_each_entry_safe(sglq_entry, sglq_next,
&phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
if (sglq_entry->sli4_xritag == xri) {
list_del(&sglq_entry->list);
- spin_unlock_irqrestore(
- &phba->sli4_hba.abts_sgl_list_lock,
- iflag);
- spin_lock_irqsave(&phba->hbalock, iflag);
-
list_add_tail(&sglq_entry->list,
&phba->sli4_hba.lpfc_sgl_list);
+ sglq_entry->state = SGL_FREED;
+ spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
spin_unlock_irqrestore(&phba->hbalock, iflag);
return;
}
}
- spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag);
+ spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
+ sglq_entry = __lpfc_get_active_sglq(phba, xri);
+ if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
+ spin_unlock_irqrestore(&phba->hbalock, iflag);
+ return;
+ }
+ sglq_entry->state = SGL_XRI_ABORTED;
+ spin_unlock_irqrestore(&phba->hbalock, iflag);
+ return;
}
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 2359d0bfb73..e1466eec56b 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -20,6 +20,7 @@
*******************************************************************/
#include <linux/blkdev.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/kthread.h>
#include <linux/interrupt.h>
@@ -1481,8 +1482,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
int
lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
{
- LPFC_MBOXQ_t *mbox;
- int rc;
/*
* If the Link is up and no FCoE events while in the
* FCF discovery, no need to restart FCF discovery.
@@ -1491,86 +1490,70 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
(phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
return 0;
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+ "2768 Pending link or FCF event during current "
+ "handling of the previous event: link_state:x%x, "
+ "evt_tag_at_scan:x%x, evt_tag_current:x%x\n",
+ phba->link_state, phba->fcoe_eventtag_at_fcf_scan,
+ phba->fcoe_eventtag);
+
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_AVAILABLE;
spin_unlock_irq(&phba->hbalock);
- if (phba->link_state >= LPFC_LINK_UP)
- lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
- else {
+ if (phba->link_state >= LPFC_LINK_UP) {
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+ "2780 Restart FCF table scan due to "
+ "pending FCF event:evt_tag_at_scan:x%x, "
+ "evt_tag_current:x%x\n",
+ phba->fcoe_eventtag_at_fcf_scan,
+ phba->fcoe_eventtag);
+ lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
+ } else {
/*
* Do not continue FCF discovery and clear FCF_DISC_INPROGRESS
* flag
*/
spin_lock_irq(&phba->hbalock);
phba->hba_flag &= ~FCF_DISC_INPROGRESS;
- phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
+ phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY);
spin_unlock_irq(&phba->hbalock);
}
+ /* Unregister the currently registered FCF if required */
if (unreg_fcf) {
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_REGISTERED;
spin_unlock_irq(&phba->hbalock);
- mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mbox) {
- lpfc_printf_log(phba, KERN_ERR,
- LOG_DISCOVERY|LOG_MBOX,
- "2610 UNREG_FCFI mbox allocation failed\n");
- return 1;
- }
- lpfc_unreg_fcfi(mbox, phba->fcf.fcfi);
- mbox->vport = phba->pport;
- mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl;
- rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
- if (rc == MBX_NOT_FINISHED) {
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
- "2611 UNREG_FCFI issue mbox failed\n");
- mempool_free(mbox, phba->mbox_mem_pool);
- }
+ lpfc_sli4_unregister_fcf(phba);
}
-
return 1;
}
/**
- * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox.
+ * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command
* @phba: pointer to lpfc hba data structure.
* @mboxq: pointer to mailbox object.
+ * @next_fcf_index: pointer to holder of next fcf index.
*
- * This function iterate through all the fcf records available in
- * HBA and choose the optimal FCF record for discovery. After finding
- * the FCF for discovery it register the FCF record and kick start
- * discovery.
- * If FCF_IN_USE flag is set in currently used FCF, the routine try to
- * use a FCF record which match fabric name and mac address of the
- * currently used FCF record.
- * If the driver support only one FCF, it will try to use the FCF record
- * used by BOOT_BIOS.
+ * This routine parses the non-embedded fcf mailbox command by performing the
+ * necessarily error checking, non-embedded read FCF record mailbox command
+ * SGE parsing, and endianness swapping.
+ *
+ * Returns the pointer to the new FCF record in the non-embedded mailbox
+ * command DMA memory if successfully, other NULL.
*/
-void
-lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+static struct fcf_record *
+lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
+ uint16_t *next_fcf_index)
{
void *virt_addr;
dma_addr_t phys_addr;
- uint8_t *bytep;
struct lpfc_mbx_sge sge;
struct lpfc_mbx_read_fcf_tbl *read_fcf;
uint32_t shdr_status, shdr_add_status;
union lpfc_sli4_cfg_shdr *shdr;
struct fcf_record *new_fcf_record;
- uint32_t boot_flag, addr_mode;
- uint32_t next_fcf_index;
- struct lpfc_fcf_rec *fcf_rec = NULL;
- unsigned long iflags;
- uint16_t vlan_id;
- int rc;
-
- /* If there is pending FCoE event restart FCF table scan */
- if (lpfc_check_pending_fcoe_event(phba, 0)) {
- lpfc_sli4_mbox_cmd_free(phba, mboxq);
- return;
- }
/* Get the first SGE entry from the non-embedded DMA memory. This
* routine only uses a single SGE.
@@ -1581,59 +1564,183 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
"2524 Failed to get the non-embedded SGE "
"virtual address\n");
- goto out;
+ return NULL;
}
virt_addr = mboxq->sge_array->addr[0];
shdr = (union lpfc_sli4_cfg_shdr *)virt_addr;
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
- shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
- &shdr->response);
- /*
- * The FCF Record was read and there is no reason for the driver
- * to maintain the FCF record data or memory. Instead, just need
- * to book keeping the FCFIs can be used.
- */
+ shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
if (shdr_status || shdr_add_status) {
- if (shdr_status == STATUS_FCF_TABLE_EMPTY) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ if (shdr_status == STATUS_FCF_TABLE_EMPTY)
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
"2726 READ_FCF_RECORD Indicates empty "
"FCF table.\n");
- } else {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ else
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
"2521 READ_FCF_RECORD mailbox failed "
- "with status x%x add_status x%x, mbx\n",
- shdr_status, shdr_add_status);
- }
- goto out;
+ "with status x%x add_status x%x, "
+ "mbx\n", shdr_status, shdr_add_status);
+ return NULL;
}
- /* Interpreting the returned information of FCF records */
+
+ /* Interpreting the returned information of the FCF record */
read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
lpfc_sli_pcimem_bcopy(read_fcf, read_fcf,
sizeof(struct lpfc_mbx_read_fcf_tbl));
- next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf);
-
+ *next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf);
new_fcf_record = (struct fcf_record *)(virt_addr +
sizeof(struct lpfc_mbx_read_fcf_tbl));
lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record,
sizeof(struct fcf_record));
- bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr);
+ return new_fcf_record;
+}
+
+/**
+ * lpfc_sli4_log_fcf_record_info - Log the information of a fcf record
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_record: pointer to the fcf record.
+ * @vlan_id: the lowest vlan identifier associated to this fcf record.
+ * @next_fcf_index: the index to the next fcf record in hba's fcf table.
+ *
+ * This routine logs the detailed FCF record if the LOG_FIP loggin is
+ * enabled.
+ **/
+static void
+lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba,
+ struct fcf_record *fcf_record,
+ uint16_t vlan_id,
+ uint16_t next_fcf_index)
+{
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+ "2764 READ_FCF_RECORD:\n"
+ "\tFCF_Index : x%x\n"
+ "\tFCF_Avail : x%x\n"
+ "\tFCF_Valid : x%x\n"
+ "\tFIP_Priority : x%x\n"
+ "\tMAC_Provider : x%x\n"
+ "\tLowest VLANID : x%x\n"
+ "\tFCF_MAC Addr : x%x:%x:%x:%x:%x:%x\n"
+ "\tFabric_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n"
+ "\tSwitch_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n"
+ "\tNext_FCF_Index: x%x\n",
+ bf_get(lpfc_fcf_record_fcf_index, fcf_record),
+ bf_get(lpfc_fcf_record_fcf_avail, fcf_record),
+ bf_get(lpfc_fcf_record_fcf_valid, fcf_record),
+ fcf_record->fip_priority,
+ bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record),
+ vlan_id,
+ bf_get(lpfc_fcf_record_mac_0, fcf_record),
+ bf_get(lpfc_fcf_record_mac_1, fcf_record),
+ bf_get(lpfc_fcf_record_mac_2, fcf_record),
+ bf_get(lpfc_fcf_record_mac_3, fcf_record),
+ bf_get(lpfc_fcf_record_mac_4, fcf_record),
+ bf_get(lpfc_fcf_record_mac_5, fcf_record),
+ bf_get(lpfc_fcf_record_fab_name_0, fcf_record),
+ bf_get(lpfc_fcf_record_fab_name_1, fcf_record),
+ bf_get(lpfc_fcf_record_fab_name_2, fcf_record),
+ bf_get(lpfc_fcf_record_fab_name_3, fcf_record),
+ bf_get(lpfc_fcf_record_fab_name_4, fcf_record),
+ bf_get(lpfc_fcf_record_fab_name_5, fcf_record),
+ bf_get(lpfc_fcf_record_fab_name_6, fcf_record),
+ bf_get(lpfc_fcf_record_fab_name_7, fcf_record),
+ bf_get(lpfc_fcf_record_switch_name_0, fcf_record),
+ bf_get(lpfc_fcf_record_switch_name_1, fcf_record),
+ bf_get(lpfc_fcf_record_switch_name_2, fcf_record),
+ bf_get(lpfc_fcf_record_switch_name_3, fcf_record),
+ bf_get(lpfc_fcf_record_switch_name_4, fcf_record),
+ bf_get(lpfc_fcf_record_switch_name_5, fcf_record),
+ bf_get(lpfc_fcf_record_switch_name_6, fcf_record),
+ bf_get(lpfc_fcf_record_switch_name_7, fcf_record),
+ next_fcf_index);
+}
+
+/**
+ * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This function iterates through all the fcf records available in
+ * HBA and chooses the optimal FCF record for discovery. After finding
+ * the FCF for discovery it registers the FCF record and kicks start
+ * discovery.
+ * If FCF_IN_USE flag is set in currently used FCF, the routine tries to
+ * use an FCF record which matches fabric name and mac address of the
+ * currently used FCF record.
+ * If the driver supports only one FCF, it will try to use the FCF record
+ * used by BOOT_BIOS.
+ */
+void
+lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+ struct fcf_record *new_fcf_record;
+ uint32_t boot_flag, addr_mode;
+ uint16_t fcf_index, next_fcf_index;
+ struct lpfc_fcf_rec *fcf_rec = NULL;
+ uint16_t vlan_id;
+ int rc;
+
+ /* If there is pending FCoE event restart FCF table scan */
+ if (lpfc_check_pending_fcoe_event(phba, 0)) {
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
+ return;
+ }
+
+ /* Parse the FCF record from the non-embedded mailbox command */
+ new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+ &next_fcf_index);
+ if (!new_fcf_record) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+ "2765 Mailbox command READ_FCF_RECORD "
+ "failed to retrieve a FCF record.\n");
+ /* Let next new FCF event trigger fast failover */
+ spin_lock_irq(&phba->hbalock);
+ phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+ spin_unlock_irq(&phba->hbalock);
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
+ return;
+ }
+
+ /* Check the FCF record against the connection list */
rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
&addr_mode, &vlan_id);
+
+ /* Log the FCF record information if turned on */
+ lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+ next_fcf_index);
+
/*
* If the fcf record does not match with connect list entries
- * read the next entry.
+ * read the next entry; otherwise, this is an eligible FCF
+ * record for round robin FCF failover.
*/
- if (!rc)
+ if (!rc) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+ "2781 FCF record fcf_index:x%x failed FCF "
+ "connection list check, fcf_avail:x%x, "
+ "fcf_valid:x%x\n",
+ bf_get(lpfc_fcf_record_fcf_index,
+ new_fcf_record),
+ bf_get(lpfc_fcf_record_fcf_avail,
+ new_fcf_record),
+ bf_get(lpfc_fcf_record_fcf_valid,
+ new_fcf_record));
goto read_next_fcf;
+ } else {
+ fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
+ rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index);
+ if (rc)
+ goto read_next_fcf;
+ }
+
/*
* If this is not the first FCF discovery of the HBA, use last
* FCF record for the discovery. The condition that a rescan
* matches the in-use FCF record: fabric name, switch name, mac
* address, and vlan_id.
*/
- spin_lock_irqsave(&phba->hbalock, iflags);
+ spin_lock_irq(&phba->hbalock);
if (phba->fcf.fcf_flag & FCF_IN_USE) {
if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name,
new_fcf_record) &&
@@ -1649,8 +1756,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
__lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
else if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
/* If in fast failover, mark it's completed */
- phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV |
+ FCF_DISCOVERY);
+ spin_unlock_irq(&phba->hbalock);
goto out;
}
/*
@@ -1661,7 +1769,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
* next candidate.
*/
if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irq(&phba->hbalock);
goto read_next_fcf;
}
}
@@ -1669,14 +1777,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
* Update on failover FCF record only if it's in FCF fast-failover
* period; otherwise, update on current FCF record.
*/
- if (phba->fcf.fcf_flag & FCF_REDISC_FOV) {
- /* Fast FCF failover only to the same fabric name */
- if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name,
- new_fcf_record))
- fcf_rec = &phba->fcf.failover_rec;
- else
- goto read_next_fcf;
- } else
+ if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
+ fcf_rec = &phba->fcf.failover_rec;
+ else
fcf_rec = &phba->fcf.current_rec;
if (phba->fcf.fcf_flag & FCF_AVAILABLE) {
@@ -1689,7 +1792,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
/* Choose this FCF record */
__lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
addr_mode, vlan_id, BOOT_ENABLE);
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irq(&phba->hbalock);
goto read_next_fcf;
}
/*
@@ -1698,20 +1801,19 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
* the next FCF record.
*/
if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) {
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irq(&phba->hbalock);
goto read_next_fcf;
}
/*
* If the new hba FCF record has lower priority value
* than the driver FCF record, use the new record.
*/
- if (lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record) &&
- (new_fcf_record->fip_priority < fcf_rec->priority)) {
+ if (new_fcf_record->fip_priority < fcf_rec->priority) {
/* Choose this FCF record */
__lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
addr_mode, vlan_id, 0);
}
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irq(&phba->hbalock);
goto read_next_fcf;
}
/*
@@ -1724,7 +1826,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
BOOT_ENABLE : 0));
phba->fcf.fcf_flag |= FCF_AVAILABLE;
}
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irq(&phba->hbalock);
goto read_next_fcf;
read_next_fcf:
@@ -1740,9 +1842,22 @@ read_next_fcf:
* FCF scan inprogress, and do nothing
*/
if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) {
- spin_lock_irqsave(&phba->hbalock, iflags);
+ lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+ "2782 No suitable FCF record "
+ "found during this round of "
+ "post FCF rediscovery scan: "
+ "fcf_evt_tag:x%x, fcf_index: "
+ "x%x\n",
+ phba->fcoe_eventtag_at_fcf_scan,
+ bf_get(lpfc_fcf_record_fcf_index,
+ new_fcf_record));
+ /*
+ * Let next new FCF event trigger fast
+ * failover
+ */
+ spin_lock_irq(&phba->hbalock);
phba->hba_flag &= ~FCF_DISC_INPROGRESS;
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irq(&phba->hbalock);
return;
}
/*
@@ -1754,16 +1869,23 @@ read_next_fcf:
* record.
*/
- /* unregister the current in-use FCF record */
+ /* Unregister the current in-use FCF record */
lpfc_unregister_fcf(phba);
- /* replace in-use record with the new record */
+
+ /* Replace in-use record with the new record */
memcpy(&phba->fcf.current_rec,
&phba->fcf.failover_rec,
sizeof(struct lpfc_fcf_rec));
/* mark the FCF fast failover completed */
- spin_lock_irqsave(&phba->hbalock, iflags);
+ spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irq(&phba->hbalock);
+ /*
+ * Set up the initial registered FCF index for FLOGI
+ * round robin FCF failover.
+ */
+ phba->fcf.fcf_rr_init_indx =
+ phba->fcf.failover_rec.fcf_indx;
/* Register to the new FCF record */
lpfc_register_fcf(phba);
} else {
@@ -1776,13 +1898,25 @@ read_next_fcf:
return;
/*
* Otherwise, initial scan or post linkdown rescan,
- * register with the best fit FCF record found so
- * far through the scanning process.
+ * register with the best FCF record found so far
+ * through the FCF scanning process.
+ */
+
+ /* mark the initial FCF discovery completed */
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+ spin_unlock_irq(&phba->hbalock);
+ /*
+ * Set up the initial registered FCF index for FLOGI
+ * round robin FCF failover
*/
+ phba->fcf.fcf_rr_init_indx =
+ phba->fcf.current_rec.fcf_indx;
+ /* Register to the new FCF record */
lpfc_register_fcf(phba);
}
} else
- lpfc_sli4_read_fcf_record(phba, next_fcf_index);
+ lpfc_sli4_fcf_scan_read_fcf_rec(phba, next_fcf_index);
return;
out:
@@ -1793,6 +1927,141 @@ out:
}
/**
+ * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf round robin read_fcf mbox cmpl hdler
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This is the callback function for FLOGI failure round robin FCF failover
+ * read FCF record mailbox command from the eligible FCF record bmask for
+ * performing the failover. If the FCF read back is not valid/available, it
+ * fails through to retrying FLOGI to the currently registered FCF again.
+ * Otherwise, if the FCF read back is valid and available, it will set the
+ * newly read FCF record to the failover FCF record, unregister currently
+ * registered FCF record, copy the failover FCF record to the current
+ * FCF record, and then register the current FCF record before proceeding
+ * to trying FLOGI on the new failover FCF.
+ */
+void
+lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+ struct fcf_record *new_fcf_record;
+ uint32_t boot_flag, addr_mode;
+ uint16_t next_fcf_index;
+ uint16_t current_fcf_index;
+ uint16_t vlan_id;
+
+ /* If link state is not up, stop the round robin failover process */
+ if (phba->link_state < LPFC_LINK_UP) {
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+ spin_unlock_irq(&phba->hbalock);
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
+ return;
+ }
+
+ /* Parse the FCF record from the non-embedded mailbox command */
+ new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+ &next_fcf_index);
+ if (!new_fcf_record) {
+ lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+ "2766 Mailbox command READ_FCF_RECORD "
+ "failed to retrieve a FCF record.\n");
+ goto out;
+ }
+
+ /* Get the needed parameters from FCF record */
+ lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
+ &addr_mode, &vlan_id);
+
+ /* Log the FCF record information if turned on */
+ lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+ next_fcf_index);
+
+ /* Upload new FCF record to the failover FCF record */
+ spin_lock_irq(&phba->hbalock);
+ __lpfc_update_fcf_record(phba, &phba->fcf.failover_rec,
+ new_fcf_record, addr_mode, vlan_id,
+ (boot_flag ? BOOT_ENABLE : 0));
+ spin_unlock_irq(&phba->hbalock);
+
+ current_fcf_index = phba->fcf.current_rec.fcf_indx;
+
+ /* Unregister the current in-use FCF record */
+ lpfc_unregister_fcf(phba);
+
+ /* Replace in-use record with the new record */
+ memcpy(&phba->fcf.current_rec, &phba->fcf.failover_rec,
+ sizeof(struct lpfc_fcf_rec));
+
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+ "2783 FLOGI round robin FCF failover from FCF "
+ "(index:x%x) to FCF (index:x%x).\n",
+ current_fcf_index,
+ bf_get(lpfc_fcf_record_fcf_index, new_fcf_record));
+
+out:
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
+ lpfc_register_fcf(phba);
+}
+
+/**
+ * lpfc_mbx_cmpl_read_fcf_rec - read fcf completion handler.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This is the callback function of read FCF record mailbox command for
+ * updating the eligible FCF bmask for FLOGI failure round robin FCF
+ * failover when a new FCF event happened. If the FCF read back is
+ * valid/available and it passes the connection list check, it updates
+ * the bmask for the eligible FCF record for round robin failover.
+ */
+void
+lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+ struct fcf_record *new_fcf_record;
+ uint32_t boot_flag, addr_mode;
+ uint16_t fcf_index, next_fcf_index;
+ uint16_t vlan_id;
+ int rc;
+
+ /* If link state is not up, no need to proceed */
+ if (phba->link_state < LPFC_LINK_UP)
+ goto out;
+
+ /* If FCF discovery period is over, no need to proceed */
+ if (phba->fcf.fcf_flag & FCF_DISCOVERY)
+ goto out;
+
+ /* Parse the FCF record from the non-embedded mailbox command */
+ new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+ &next_fcf_index);
+ if (!new_fcf_record) {
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+ "2767 Mailbox command READ_FCF_RECORD "
+ "failed to retrieve a FCF record.\n");
+ goto out;
+ }
+
+ /* Check the connection list for eligibility */
+ rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
+ &addr_mode, &vlan_id);
+
+ /* Log the FCF record information if turned on */
+ lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+ next_fcf_index);
+
+ if (!rc)
+ goto out;
+
+ /* Update the eligible FCF record index bmask */
+ fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
+ rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index);
+
+out:
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
+}
+
+/**
* lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command.
* @phba: pointer to lpfc hba data structure.
* @mboxq: pointer to mailbox data structure.
@@ -2024,8 +2293,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
int rc;
struct fcf_record *fcf_record;
- sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-
spin_lock_irq(&phba->hbalock);
switch (la->UlnkSpeed) {
case LA_1GHZ_LINK:
@@ -2117,18 +2384,24 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
spin_unlock_irq(&phba->hbalock);
lpfc_linkup(phba);
- if (sparam_mbox) {
- lpfc_read_sparam(phba, sparam_mbox, 0);
- sparam_mbox->vport = vport;
- sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
- rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
- if (rc == MBX_NOT_FINISHED) {
- mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
- lpfc_mbuf_free(phba, mp->virt, mp->phys);
- kfree(mp);
- mempool_free(sparam_mbox, phba->mbox_mem_pool);
- goto out;
- }
+ sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!sparam_mbox)
+ goto out;
+
+ rc = lpfc_read_sparam(phba, sparam_mbox, 0);
+ if (rc) {
+ mempool_free(sparam_mbox, phba->mbox_mem_pool);
+ goto out;
+ }
+ sparam_mbox->vport = vport;
+ sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
+ rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED) {
+ mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ mempool_free(sparam_mbox, phba->mbox_mem_pool);
+ goto out;
}
if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) {
@@ -2186,10 +2459,20 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
spin_unlock_irq(&phba->hbalock);
return;
}
+ /* This is the initial FCF discovery scan */
+ phba->fcf.fcf_flag |= FCF_INIT_DISC;
spin_unlock_irq(&phba->hbalock);
- rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
- if (rc)
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+ "2778 Start FCF table scan at linkup\n");
+
+ rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
+ LPFC_FCOE_FCF_GET_FIRST);
+ if (rc) {
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+ spin_unlock_irq(&phba->hbalock);
goto out;
+ }
}
return;
@@ -3379,8 +3662,12 @@ lpfc_unreg_hba_rpis(struct lpfc_hba *phba)
shost = lpfc_shost_from_vport(vports[i]);
spin_lock_irq(shost->host_lock);
list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) {
- if (ndlp->nlp_flag & NLP_RPI_VALID)
+ if (ndlp->nlp_flag & NLP_RPI_VALID) {
+ /* The mempool_alloc might sleep */
+ spin_unlock_irq(shost->host_lock);
lpfc_unreg_rpi(vports[i], ndlp);
+ spin_lock_irq(shost->host_lock);
+ }
}
spin_unlock_irq(shost->host_lock);
}
@@ -4756,6 +5043,7 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
return;
/* Reset HBA FCF states after successful unregister FCF */
phba->fcf.fcf_flag = 0;
+ phba->fcf.current_rec.flag = 0;
/*
* If driver is not unloading, check if there is any other
@@ -4765,13 +5053,21 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
(phba->link_state < LPFC_LINK_UP))
return;
- rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+ /* This is considered as the initial FCF discovery scan */
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag |= FCF_INIT_DISC;
+ spin_unlock_irq(&phba->hbalock);
+ rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
- if (rc)
+ if (rc) {
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+ spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
"2553 lpfc_unregister_unused_fcf failed "
"to read FCF record HBA state x%x\n",
phba->pport->port_state);
+ }
}
/**
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index d29ac7c317d..774663e8e1f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -29,6 +29,7 @@
#include <linux/spinlock.h>
#include <linux/ctype.h>
#include <linux/aer.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
@@ -350,7 +351,12 @@ lpfc_config_port_post(struct lpfc_hba *phba)
mb = &pmb->u.mb;
/* Get login parameters for NID. */
- lpfc_read_sparam(phba, pmb, 0);
+ rc = lpfc_read_sparam(phba, pmb, 0);
+ if (rc) {
+ mempool_free(pmb, phba->mbox_mem_pool);
+ return -ENOMEM;
+ }
+
pmb->vport = vport;
if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -359,7 +365,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
mb->mbxCommand, mb->mbxStatus);
phba->link_state = LPFC_HBA_ERROR;
mp = (struct lpfc_dmabuf *) pmb->context1;
- mempool_free( pmb, phba->mbox_mem_pool);
+ mempool_free(pmb, phba->mbox_mem_pool);
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
return -EIO;
@@ -544,7 +550,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
mempool_free(pmb, phba->mbox_mem_pool);
return -EIO;
}
- } else if (phba->cfg_suppress_link_up == 0) {
+ } else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) {
lpfc_init_link(phba, pmb, phba->cfg_topology,
phba->cfg_link_speed);
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -571,6 +577,11 @@ lpfc_config_port_post(struct lpfc_hba *phba)
}
/* MBOX buffer will be freed in mbox compl */
pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!pmb) {
+ phba->link_state = LPFC_HBA_ERROR;
+ return -ENOMEM;
+ }
+
lpfc_config_async(phba, pmb, LPFC_ELS_RING);
pmb->mbox_cmpl = lpfc_config_async_cmpl;
pmb->vport = phba->pport;
@@ -588,6 +599,11 @@ lpfc_config_port_post(struct lpfc_hba *phba)
/* Get Option rom version */
pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!pmb) {
+ phba->link_state = LPFC_HBA_ERROR;
+ return -ENOMEM;
+ }
+
lpfc_dump_wakeup_param(phba, pmb);
pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
pmb->vport = phba->pport;
@@ -652,7 +668,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba)
mempool_free(pmb, phba->mbox_mem_pool);
return -EIO;
}
- phba->cfg_suppress_link_up = 0;
+ phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK;
return 0;
}
@@ -807,6 +823,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
LIST_HEAD(aborts);
int ret;
unsigned long iflag = 0;
+ struct lpfc_sglq *sglq_entry = NULL;
+
ret = lpfc_hba_down_post_s3(phba);
if (ret)
return ret;
@@ -822,6 +840,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
* list.
*/
spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
+ list_for_each_entry(sglq_entry,
+ &phba->sli4_hba.lpfc_abts_els_sgl_list, list)
+ sglq_entry->state = SGL_FREED;
+
list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list,
&phba->sli4_hba.lpfc_sgl_list);
spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
@@ -2178,8 +2200,10 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
void
__lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
{
- /* Clear pending FCF rediscovery wait timer */
- phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;
+ /* Clear pending FCF rediscovery wait and failover in progress flags */
+ phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND |
+ FCF_DEAD_DISC |
+ FCF_ACVL_DISC);
/* Now, try to stop the timer */
del_timer(&phba->fcf.redisc_wait);
}
@@ -2576,6 +2600,14 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
init_timer(&vport->els_tmofunc);
vport->els_tmofunc.function = lpfc_els_timeout;
vport->els_tmofunc.data = (unsigned long)vport;
+ if (phba->pcidev->device == PCI_DEVICE_ID_HORNET) {
+ phba->menlo_flag |= HBA_MENLO_SUPPORT;
+ /* check for menlo minimum sg count */
+ if (phba->cfg_sg_seg_cnt < LPFC_DEFAULT_MENLO_SG_SEG_CNT) {
+ phba->cfg_sg_seg_cnt = LPFC_DEFAULT_MENLO_SG_SEG_CNT;
+ shost->sg_tablesize = phba->cfg_sg_seg_cnt;
+ }
+ }
error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
if (error)
@@ -2912,6 +2944,9 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
/* FCF rediscovery event to worker thread */
phba->fcf.fcf_flag |= FCF_REDISC_EVT;
spin_unlock_irq(&phba->hbalock);
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+ "2776 FCF rediscover wait timer expired, post "
+ "a worker thread event for FCF table scan\n");
/* wake up worker thread */
lpfc_worker_wake_up(phba);
}
@@ -3183,6 +3218,68 @@ out_free_pmb:
}
/**
+ * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport
+ * @vport: pointer to vport data structure.
+ *
+ * This routine is to perform Clear Virtual Link (CVL) on a vport in
+ * response to a CVL event.
+ *
+ * Return the pointer to the ndlp with the vport if successful, otherwise
+ * return NULL.
+ **/
+static struct lpfc_nodelist *
+lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
+{
+ struct lpfc_nodelist *ndlp;
+ struct Scsi_Host *shost;
+ struct lpfc_hba *phba;
+
+ if (!vport)
+ return NULL;
+ ndlp = lpfc_findnode_did(vport, Fabric_DID);
+ if (!ndlp)
+ return NULL;
+ phba = vport->phba;
+ if (!phba)
+ return NULL;
+ if (phba->pport->port_state <= LPFC_FLOGI)
+ return NULL;
+ /* If virtual link is not yet instantiated ignore CVL */
+ if (vport->port_state <= LPFC_FDISC)
+ return NULL;
+ shost = lpfc_shost_from_vport(vport);
+ if (!shost)
+ return NULL;
+ lpfc_linkdown_port(vport);
+ lpfc_cleanup_pending_mbox(vport);
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag |= FC_VPORT_CVL_RCVD;
+ spin_unlock_irq(shost->host_lock);
+
+ return ndlp;
+}
+
+/**
+ * lpfc_sli4_perform_all_vport_cvl - Perform clear virtual link on all vports
+ * @vport: pointer to lpfc hba data structure.
+ *
+ * This routine is to perform Clear Virtual Link (CVL) on all vports in
+ * response to a FCF dead event.
+ **/
+static void
+lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
+{
+ struct lpfc_vport **vports;
+ int i;
+
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports)
+ for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
+ lpfc_sli4_perform_vport_cvl(vports[i]);
+ lpfc_destroy_vport_work_array(phba, vports);
+}
+
+/**
* lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event
* @phba: pointer to lpfc hba data structure.
* @acqe_link: pointer to the async fcoe completion queue entry.
@@ -3198,7 +3295,6 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
struct lpfc_vport *vport;
struct lpfc_nodelist *ndlp;
struct Scsi_Host *shost;
- uint32_t link_state;
int active_vlink_present;
struct lpfc_vport **vports;
int i;
@@ -3208,10 +3304,11 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
switch (event_type) {
case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD:
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "2546 New FCF found index 0x%x tag 0x%x\n",
- acqe_fcoe->index,
- acqe_fcoe->event_tag);
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+ "2546 New FCF found/FCF parameter modified event: "
+ "evt_tag:x%x, fcf_index:x%x\n",
+ acqe_fcoe->event_tag, acqe_fcoe->index);
+
spin_lock_irq(&phba->hbalock);
if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) ||
(phba->hba_flag & FCF_DISC_INPROGRESS)) {
@@ -3222,6 +3319,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
spin_unlock_irq(&phba->hbalock);
break;
}
+
if (phba->fcf.fcf_flag & FCF_REDISC_EVT) {
/*
* If fast FCF failover rescan event is pending,
@@ -3232,12 +3330,33 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
}
spin_unlock_irq(&phba->hbalock);
- /* Read the FCF table and re-discover SAN. */
- rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+ if ((phba->fcf.fcf_flag & FCF_DISCOVERY) &&
+ !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
+ /*
+ * During period of FCF discovery, read the FCF
+ * table record indexed by the event to update
+ * FCF round robin failover eligible FCF bmask.
+ */
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
+ LOG_DISCOVERY,
+ "2779 Read new FCF record with "
+ "fcf_index:x%x for updating FCF "
+ "round robin failover bmask\n",
+ acqe_fcoe->index);
+ rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
+ }
+
+ /* Otherwise, scan the entire FCF table and re-discover SAN */
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+ "2770 Start FCF table scan due to new FCF "
+ "event: evt_tag:x%x, fcf_index:x%x\n",
+ acqe_fcoe->event_tag, acqe_fcoe->index);
+ rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
+ LPFC_FCOE_FCF_GET_FIRST);
if (rc)
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "2547 Read FCF record failed 0x%x\n",
- rc);
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+ "2547 Issue FCF scan read FCF mailbox "
+ "command failed 0x%x\n", rc);
break;
case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
@@ -3248,47 +3367,63 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
break;
case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
"2549 FCF disconnected from network index 0x%x"
" tag 0x%x\n", acqe_fcoe->index,
acqe_fcoe->event_tag);
/* If the event is not for currently used fcf do nothing */
if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index)
break;
- /*
- * Currently, driver support only one FCF - so treat this as
- * a link down, but save the link state because we don't want
- * it to be changed to Link Down unless it is already down.
+ /* We request port to rediscover the entire FCF table for
+ * a fast recovery from case that the current FCF record
+ * is no longer valid if we are not in the middle of FCF
+ * failover process already.
*/
- link_state = phba->link_state;
- lpfc_linkdown(phba);
- phba->link_state = link_state;
- /* Unregister FCF if no devices connected to it */
- lpfc_unregister_unused_fcf(phba);
+ spin_lock_irq(&phba->hbalock);
+ if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
+ spin_unlock_irq(&phba->hbalock);
+ /* Update FLOGI FCF failover eligible FCF bmask */
+ lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index);
+ break;
+ }
+ /* Mark the fast failover process in progress */
+ phba->fcf.fcf_flag |= FCF_DEAD_DISC;
+ spin_unlock_irq(&phba->hbalock);
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+ "2771 Start FCF fast failover process due to "
+ "FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
+ "\n", acqe_fcoe->event_tag, acqe_fcoe->index);
+ rc = lpfc_sli4_redisc_fcf_table(phba);
+ if (rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
+ LOG_DISCOVERY,
+ "2772 Issue FCF rediscover mabilbox "
+ "command failed, fail through to FCF "
+ "dead event\n");
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
+ spin_unlock_irq(&phba->hbalock);
+ /*
+ * Last resort will fail over by treating this
+ * as a link down to FCF registration.
+ */
+ lpfc_sli4_fcf_dead_failthrough(phba);
+ } else
+ /* Handling fast FCF failover to a DEAD FCF event
+ * is considered equalivant to receiving CVL to all
+ * vports.
+ */
+ lpfc_sli4_perform_all_vport_cvl(phba);
break;
case LPFC_FCOE_EVENT_TYPE_CVL:
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
"2718 Clear Virtual Link Received for VPI 0x%x"
" tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
vport = lpfc_find_vport_by_vpid(phba,
acqe_fcoe->index - phba->vpi_base);
- if (!vport)
- break;
- ndlp = lpfc_findnode_did(vport, Fabric_DID);
+ ndlp = lpfc_sli4_perform_vport_cvl(vport);
if (!ndlp)
break;
- shost = lpfc_shost_from_vport(vport);
- if (phba->pport->port_state <= LPFC_FLOGI)
- break;
- /* If virtual link is not yet instantiated ignore CVL */
- if (vport->port_state <= LPFC_FDISC)
- break;
-
- lpfc_linkdown_port(vport);
- lpfc_cleanup_pending_mbox(vport);
- spin_lock_irq(shost->host_lock);
- vport->fc_flag |= FC_VPORT_CVL_RCVD;
- spin_unlock_irq(shost->host_lock);
active_vlink_present = 0;
vports = lpfc_create_vport_work_array(phba);
@@ -3311,6 +3446,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
* re-instantiate the Vlink using FDISC.
*/
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
+ shost = lpfc_shost_from_vport(vport);
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_DELAY_TMO;
spin_unlock_irq(shost->host_lock);
@@ -3321,15 +3457,38 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
* Otherwise, we request port to rediscover
* the entire FCF table for a fast recovery
* from possible case that the current FCF
- * is no longer valid.
+ * is no longer valid if we are not already
+ * in the FCF failover process.
*/
+ spin_lock_irq(&phba->hbalock);
+ if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
+ spin_unlock_irq(&phba->hbalock);
+ break;
+ }
+ /* Mark the fast failover process in progress */
+ phba->fcf.fcf_flag |= FCF_ACVL_DISC;
+ spin_unlock_irq(&phba->hbalock);
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
+ LOG_DISCOVERY,
+ "2773 Start FCF fast failover due "
+ "to CVL event: evt_tag:x%x\n",
+ acqe_fcoe->event_tag);
rc = lpfc_sli4_redisc_fcf_table(phba);
- if (rc)
+ if (rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
+ LOG_DISCOVERY,
+ "2774 Issue FCF rediscover "
+ "mabilbox command failed, "
+ "through to CVL event\n");
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
+ spin_unlock_irq(&phba->hbalock);
/*
* Last resort will be re-try on the
* the current registered FCF entry.
*/
lpfc_retry_pport_discovery(phba);
+ }
}
break;
default:
@@ -3426,11 +3585,14 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba)
spin_unlock_irq(&phba->hbalock);
/* Scan FCF table from the first entry to re-discover SAN */
- rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+ "2777 Start FCF table scan after FCF "
+ "rediscovery quiescent period over\n");
+ rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
if (rc)
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "2747 Post FCF rediscovery read FCF record "
- "failed 0x%x\n", rc);
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+ "2747 Issue FCF scan read FCF mailbox "
+ "command failed 0x%x\n", rc);
}
/**
@@ -3722,6 +3884,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size;
uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
struct lpfc_mqe *mqe;
+ int longs;
/* Before proceed, wait for POST done and device ready */
rc = lpfc_sli4_post_status_check(phba);
@@ -3898,13 +4061,24 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
goto out_free_active_sgl;
}
+ /* Allocate eligible FCF bmask memory for FCF round robin failover */
+ longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG;
+ phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long),
+ GFP_KERNEL);
+ if (!phba->fcf.fcf_rr_bmask) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2759 Failed allocate memory for FCF round "
+ "robin failover bmask\n");
+ goto out_remove_rpi_hdrs;
+ }
+
phba->sli4_hba.fcp_eq_hdl = kzalloc((sizeof(struct lpfc_fcp_eq_hdl) *
phba->cfg_fcp_eq_count), GFP_KERNEL);
if (!phba->sli4_hba.fcp_eq_hdl) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2572 Failed allocate memory for fast-path "
"per-EQ handle array\n");
- goto out_remove_rpi_hdrs;
+ goto out_free_fcf_rr_bmask;
}
phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) *
@@ -3957,6 +4131,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
out_free_fcp_eq_hdl:
kfree(phba->sli4_hba.fcp_eq_hdl);
+out_free_fcf_rr_bmask:
+ kfree(phba->fcf.fcf_rr_bmask);
out_remove_rpi_hdrs:
lpfc_sli4_remove_rpi_hdrs(phba);
out_free_active_sgl:
@@ -4002,6 +4178,9 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba)
lpfc_sli4_remove_rpi_hdrs(phba);
lpfc_sli4_remove_rpis(phba);
+ /* Free eligible FCF index bmask */
+ kfree(phba->fcf.fcf_rr_bmask);
+
/* Free the ELS sgl list */
lpfc_free_active_sgl(phba);
lpfc_free_sgl_list(phba);
@@ -4397,6 +4576,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba)
/* The list order is used by later block SGL registraton */
spin_lock_irq(&phba->hbalock);
+ sglq_entry->state = SGL_FREED;
list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list);
phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry;
phba->sli4_hba.total_sglq_bufs++;
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
index 954ba57970a..bb59e927312 100644
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -35,6 +35,7 @@
#define LOG_VPORT 0x00004000 /* NPIV events */
#define LOF_SECURITY 0x00008000 /* Security events */
#define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */
+#define LOG_FIP 0x00020000 /* FIP events */
#define LOG_ALL_MSG 0xffffffff /* LOG all messages */
#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 6c4dce1a30c..72e6adb0643 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -21,6 +21,7 @@
#include <linux/blkdev.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <scsi/scsi_device.h>
@@ -1748,7 +1749,7 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
}
/**
- * lpfc_sli4_mbx_read_fcf_record - Allocate and construct read fcf mbox cmd
+ * lpfc_sli4_mbx_read_fcf_rec - Allocate and construct read fcf mbox cmd
* @phba: pointer to lpfc hba data structure.
* @fcf_index: index to fcf table.
*
@@ -1759,9 +1760,9 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
* NULL.
**/
int
-lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *phba,
- struct lpfcMboxq *mboxq,
- uint16_t fcf_index)
+lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba,
+ struct lpfcMboxq *mboxq,
+ uint16_t fcf_index)
{
void *virt_addr;
dma_addr_t phys_addr;
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index a1b6db6016d..8f879e477e9 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -20,6 +20,7 @@
*******************************************************************/
#include <linux/mempool.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index d20ae6b3b3c..e331204a4d5 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -21,6 +21,7 @@
#include <linux/blkdev.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <scsi/scsi.h>
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 7f21b47db79..dccdb822328 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -19,6 +19,7 @@
* included with this package. *
*******************************************************************/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <asm/unaligned.h>
@@ -620,23 +621,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
struct lpfc_scsi_buf *psb, *next_psb;
unsigned long iflag = 0;
+ struct lpfc_iocbq *iocbq;
+ int i;
- spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag);
+ spin_lock_irqsave(&phba->hbalock, iflag);
+ spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock);
list_for_each_entry_safe(psb, next_psb,
&phba->sli4_hba.lpfc_abts_scsi_buf_list, list) {
if (psb->cur_iocbq.sli4_xritag == xri) {
list_del(&psb->list);
psb->exch_busy = 0;
psb->status = IOSTAT_SUCCESS;
- spin_unlock_irqrestore(
- &phba->sli4_hba.abts_scsi_buf_list_lock,
- iflag);
+ spin_unlock(
+ &phba->sli4_hba.abts_scsi_buf_list_lock);
+ spin_unlock_irqrestore(&phba->hbalock, iflag);
lpfc_release_scsi_buf_s4(phba, psb);
return;
}
}
- spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock,
- iflag);
+ spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock);
+ for (i = 1; i <= phba->sli.last_iotag; i++) {
+ iocbq = phba->sli.iocbq_lookup[i];
+
+ if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
+ (iocbq->iocb_flag & LPFC_IO_LIBDFC))
+ continue;
+ if (iocbq->sli4_xritag != xri)
+ continue;
+ psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
+ psb->exch_busy = 0;
+ spin_unlock_irqrestore(&phba->hbalock, iflag);
+ return;
+
+ }
+ spin_unlock_irqrestore(&phba->hbalock, iflag);
}
/**
@@ -1006,6 +1024,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
struct scatterlist *sgel = NULL;
struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
+ struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq;
IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde;
dma_addr_t physaddr;
@@ -1056,6 +1075,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
physaddr = sg_dma_address(sgel);
if (phba->sli_rev == 3 &&
!(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
+ !(iocbq->iocb_flag & DSS_SECURITY_OP) &&
nseg <= LPFC_EXT_DATA_BDE_COUNT) {
data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
data_bde->tus.f.bdeSize = sg_dma_len(sgel);
@@ -1082,7 +1102,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
* explicitly reinitialized since all iocb memory resources are reused.
*/
if (phba->sli_rev == 3 &&
- !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) {
+ !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
+ !(iocbq->iocb_flag & DSS_SECURITY_OP)) {
if (num_bde > LPFC_EXT_DATA_BDE_COUNT) {
/*
* The extended IOCB format can only fit 3 BDE or a BPL.
@@ -1107,6 +1128,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
} else {
iocb_cmd->un.fcpi64.bdl.bdeSize =
((num_bde + 2) * sizeof(struct ulp_bde64));
+ iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
}
fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd));
@@ -1575,7 +1597,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba,
case LPFC_PG_TYPE_NO_DIF:
num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl,
datasegcnt);
- /* we shoud have 2 or more entries in buffer list */
+ /* we should have 2 or more entries in buffer list */
if (num_bde < 2)
goto err;
break;
@@ -1612,7 +1634,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba,
num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl,
datasegcnt, protsegcnt);
- /* we shoud have 3 or more entries in buffer list */
+ /* we should have 3 or more entries in buffer list */
if (num_bde < 3)
goto err;
break;
@@ -2079,8 +2101,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
if (resp_info & RSP_LEN_VALID) {
rsplen = be32_to_cpu(fcprsp->rspRspLen);
- if ((rsplen != 0 && rsplen != 4 && rsplen != 8) ||
- (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
+ if (rsplen != 0 && rsplen != 4 && rsplen != 8) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
"2719 Invalid response length: "
"tgt x%x lun x%x cmnd x%x rsplen x%x\n",
@@ -2090,6 +2111,17 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
host_status = DID_ERROR;
goto out;
}
+ if (fcprsp->rspInfo3 != RSP_NO_FAILURE) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "2757 Protocol failure detected during "
+ "processing of FCP I/O op: "
+ "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n",
+ cmnd->device->id,
+ cmnd->device->lun, cmnd->cmnd[0],
+ fcprsp->rspInfo3);
+ host_status = DID_ERROR;
+ goto out;
+ }
}
if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 35e3b96d4e0..049fb9a17b3 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -23,6 +23,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -494,7 +495,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
*
* Returns sglq ponter = success, NULL = Failure.
**/
-static struct lpfc_sglq *
+struct lpfc_sglq *
__lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
{
uint16_t adj_xri;
@@ -526,6 +527,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba)
return NULL;
adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base;
phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
+ sglq->state = SGL_ALLOCATED;
return sglq;
}
@@ -580,15 +582,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
else
sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag);
if (sglq) {
- if (iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) {
+ if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) &&
+ (sglq->state != SGL_XRI_ABORTED)) {
spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock,
iflag);
list_add(&sglq->list,
&phba->sli4_hba.lpfc_abts_els_sgl_list);
spin_unlock_irqrestore(
&phba->sli4_hba.abts_sgl_list_lock, iflag);
- } else
+ } else {
+ sglq->state = SGL_FREED;
list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list);
+ }
}
@@ -2258,41 +2263,56 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
spin_unlock_irqrestore(&phba->hbalock,
iflag);
}
- if ((phba->sli_rev == LPFC_SLI_REV4) &&
- (saveq->iocb_flag & LPFC_EXCHANGE_BUSY)) {
- /* Set cmdiocb flag for the exchange
- * busy so sgl (xri) will not be
- * released until the abort xri is
- * received from hba, clear the
- * LPFC_DRIVER_ABORTED bit in case
- * it was driver initiated abort.
- */
- spin_lock_irqsave(&phba->hbalock,
- iflag);
- cmdiocbp->iocb_flag &=
- ~LPFC_DRIVER_ABORTED;
- cmdiocbp->iocb_flag |=
- LPFC_EXCHANGE_BUSY;
- spin_unlock_irqrestore(&phba->hbalock,
- iflag);
- cmdiocbp->iocb.ulpStatus =
- IOSTAT_LOCAL_REJECT;
- cmdiocbp->iocb.un.ulpWord[4] =
- IOERR_ABORT_REQUESTED;
- /*
- * For SLI4, irsiocb contains NO_XRI
- * in sli_xritag, it shall not affect
- * releasing sgl (xri) process.
- */
- saveq->iocb.ulpStatus =
- IOSTAT_LOCAL_REJECT;
- saveq->iocb.un.ulpWord[4] =
- IOERR_SLI_ABORTED;
- spin_lock_irqsave(&phba->hbalock,
- iflag);
- saveq->iocb_flag |= LPFC_DELAY_MEM_FREE;
- spin_unlock_irqrestore(&phba->hbalock,
- iflag);
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+ if (saveq->iocb_flag &
+ LPFC_EXCHANGE_BUSY) {
+ /* Set cmdiocb flag for the
+ * exchange busy so sgl (xri)
+ * will not be released until
+ * the abort xri is received
+ * from hba.
+ */
+ spin_lock_irqsave(
+ &phba->hbalock, iflag);
+ cmdiocbp->iocb_flag |=
+ LPFC_EXCHANGE_BUSY;
+ spin_unlock_irqrestore(
+ &phba->hbalock, iflag);
+ }
+ if (cmdiocbp->iocb_flag &
+ LPFC_DRIVER_ABORTED) {
+ /*
+ * Clear LPFC_DRIVER_ABORTED
+ * bit in case it was driver
+ * initiated abort.
+ */
+ spin_lock_irqsave(
+ &phba->hbalock, iflag);
+ cmdiocbp->iocb_flag &=
+ ~LPFC_DRIVER_ABORTED;
+ spin_unlock_irqrestore(
+ &phba->hbalock, iflag);
+ cmdiocbp->iocb.ulpStatus =
+ IOSTAT_LOCAL_REJECT;
+ cmdiocbp->iocb.un.ulpWord[4] =
+ IOERR_ABORT_REQUESTED;
+ /*
+ * For SLI4, irsiocb contains
+ * NO_XRI in sli_xritag, it
+ * shall not affect releasing
+ * sgl (xri) process.
+ */
+ saveq->iocb.ulpStatus =
+ IOSTAT_LOCAL_REJECT;
+ saveq->iocb.un.ulpWord[4] =
+ IOERR_SLI_ABORTED;
+ spin_lock_irqsave(
+ &phba->hbalock, iflag);
+ saveq->iocb_flag |=
+ LPFC_DELAY_MEM_FREE;
+ spin_unlock_irqrestore(
+ &phba->hbalock, iflag);
+ }
}
}
(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
@@ -2515,14 +2535,16 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
&rspiocbq);
- if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
- spin_unlock_irqrestore(&phba->hbalock,
- iflag);
- (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
- &rspiocbq);
- spin_lock_irqsave(&phba->hbalock,
- iflag);
- }
+ if (unlikely(!cmdiocbq))
+ break;
+ if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED)
+ cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED;
+ if (cmdiocbq->iocb_cmpl) {
+ spin_unlock_irqrestore(&phba->hbalock, iflag);
+ (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+ &rspiocbq);
+ spin_lock_irqsave(&phba->hbalock, iflag);
+ }
break;
case LPFC_UNSOL_IOCB:
spin_unlock_irqrestore(&phba->hbalock, iflag);
@@ -3091,6 +3113,12 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask)
/* Check to see if any errors occurred during init */
if ((status & HS_FFERM) || (i >= 20)) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2751 Adapter failed to restart, "
+ "status reg x%x, FW Data: A8 x%x AC x%x\n",
+ status,
+ readl(phba->MBslimaddr + 0xa8),
+ readl(phba->MBslimaddr + 0xac));
phba->link_state = LPFC_HBA_ERROR;
retval = 1;
}
@@ -3278,6 +3306,9 @@ lpfc_sli_brdkill(struct lpfc_hba *phba)
if (retval != MBX_SUCCESS) {
if (retval != MBX_BUSY)
mempool_free(pmb, phba->mbox_mem_pool);
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ "2752 KILL_BOARD command failed retval %d\n",
+ retval);
spin_lock_irq(&phba->hbalock);
phba->link_flag &= ~LS_IGNORE_ERATT;
spin_unlock_irq(&phba->hbalock);
@@ -4035,7 +4066,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
lpfc_sli_hba_setup_error:
phba->link_state = LPFC_HBA_ERROR;
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0445 Firmware initialization failed\n");
return rc;
}
@@ -4388,7 +4419,13 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
spin_unlock_irq(&phba->hbalock);
/* Read the port's service parameters. */
- lpfc_read_sparam(phba, mboxq, vport->vpi);
+ rc = lpfc_read_sparam(phba, mboxq, vport->vpi);
+ if (rc) {
+ phba->link_state = LPFC_HBA_ERROR;
+ rc = -ENOMEM;
+ goto out_free_vpd;
+ }
+
mboxq->vport = vport;
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
mp = (struct lpfc_dmabuf *) mboxq->context1;
@@ -4483,6 +4520,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
/* Post receive buffers to the device */
lpfc_sli4_rb_setup(phba);
+ /* Reset HBA FCF states after HBA reset */
+ phba->fcf.fcf_flag = 0;
+ phba->fcf.current_rec.flag = 0;
+
/* Start the ELS watchdog timer */
mod_timer(&vport->els_tmofunc,
jiffies + HZ * (phba->fc_ratov * 2));
@@ -7436,6 +7477,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
{
wait_queue_head_t *pdone_q;
unsigned long iflags;
+ struct lpfc_scsi_buf *lpfc_cmd;
spin_lock_irqsave(&phba->hbalock, iflags);
cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
@@ -7443,6 +7485,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
&rspiocbq->iocb, sizeof(IOCB_t));
+ /* Set the exchange busy flag for task management commands */
+ if ((cmdiocbq->iocb_flag & LPFC_IO_FCP) &&
+ !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) {
+ lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf,
+ cur_iocbq);
+ lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY;
+ }
+
pdone_q = cmdiocbq->context_un.wait_queue;
if (pdone_q)
wake_up(pdone_q);
@@ -9061,6 +9111,12 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba,
/* Fake the irspiocb and copy necessary response information */
lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe);
+ if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) {
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED;
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ }
+
/* Pass the cmd_iocb and the rsp state to the upper layer */
(cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq);
}
@@ -11941,15 +11997,19 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba,
}
/**
- * lpfc_sli4_read_fcf_record - Read the driver's default FCF Record.
+ * lpfc_sli4_fcf_scan_read_fcf_rec - Read hba fcf record for fcf scan.
* @phba: pointer to lpfc hba data structure.
* @fcf_index: FCF table entry offset.
*
- * This routine is invoked to read up to @fcf_num of FCF record from the
- * device starting with the given @fcf_index.
+ * This routine is invoked to scan the entire FCF table by reading FCF
+ * record and processing it one at a time starting from the @fcf_index
+ * for initial FCF discovery or fast FCF failover rediscovery.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
**/
int
-lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
+lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
{
int rc = 0, error;
LPFC_MBOXQ_t *mboxq;
@@ -11961,17 +12021,17 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
"2000 Failed to allocate mbox for "
"READ_FCF cmd\n");
error = -ENOMEM;
- goto fail_fcfscan;
+ goto fail_fcf_scan;
}
/* Construct the read FCF record mailbox command */
- rc = lpfc_sli4_mbx_read_fcf_record(phba, mboxq, fcf_index);
+ rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
if (rc) {
error = -EINVAL;
- goto fail_fcfscan;
+ goto fail_fcf_scan;
}
/* Issue the mailbox command asynchronously */
mboxq->vport = phba->pport;
- mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record;
+ mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec;
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED)
error = -EIO;
@@ -11979,9 +12039,13 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
spin_lock_irq(&phba->hbalock);
phba->hba_flag |= FCF_DISC_INPROGRESS;
spin_unlock_irq(&phba->hbalock);
+ /* Reset FCF round robin index bmask for new scan */
+ if (fcf_index == LPFC_FCOE_FCF_GET_FIRST)
+ memset(phba->fcf.fcf_rr_bmask, 0,
+ sizeof(*phba->fcf.fcf_rr_bmask));
error = 0;
}
-fail_fcfscan:
+fail_fcf_scan:
if (error) {
if (mboxq)
lpfc_sli4_mbox_cmd_free(phba, mboxq);
@@ -11994,6 +12058,181 @@ fail_fcfscan:
}
/**
+ * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf.
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_index: FCF table entry offset.
+ *
+ * This routine is invoked to read an FCF record indicated by @fcf_index
+ * and to use it for FLOGI round robin FCF failover.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
+ **/
+int
+lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+ int rc = 0, error;
+ LPFC_MBOXQ_t *mboxq;
+
+ mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!mboxq) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
+ "2763 Failed to allocate mbox for "
+ "READ_FCF cmd\n");
+ error = -ENOMEM;
+ goto fail_fcf_read;
+ }
+ /* Construct the read FCF record mailbox command */
+ rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
+ if (rc) {
+ error = -EINVAL;
+ goto fail_fcf_read;
+ }
+ /* Issue the mailbox command asynchronously */
+ mboxq->vport = phba->pport;
+ mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_rr_read_fcf_rec;
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED)
+ error = -EIO;
+ else
+ error = 0;
+
+fail_fcf_read:
+ if (error && mboxq)
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
+ return error;
+}
+
+/**
+ * lpfc_sli4_read_fcf_rec - Read hba fcf record for update eligible fcf bmask.
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_index: FCF table entry offset.
+ *
+ * This routine is invoked to read an FCF record indicated by @fcf_index to
+ * determine whether it's eligible for FLOGI round robin failover list.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
+ **/
+int
+lpfc_sli4_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+ int rc = 0, error;
+ LPFC_MBOXQ_t *mboxq;
+
+ mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (!mboxq) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
+ "2758 Failed to allocate mbox for "
+ "READ_FCF cmd\n");
+ error = -ENOMEM;
+ goto fail_fcf_read;
+ }
+ /* Construct the read FCF record mailbox command */
+ rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
+ if (rc) {
+ error = -EINVAL;
+ goto fail_fcf_read;
+ }
+ /* Issue the mailbox command asynchronously */
+ mboxq->vport = phba->pport;
+ mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_rec;
+ rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
+ if (rc == MBX_NOT_FINISHED)
+ error = -EIO;
+ else
+ error = 0;
+
+fail_fcf_read:
+ if (error && mboxq)
+ lpfc_sli4_mbox_cmd_free(phba, mboxq);
+ return error;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is to get the next eligible FCF record index in a round
+ * robin fashion. If the next eligible FCF record index equals to the
+ * initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
+ * shall be returned, otherwise, the next eligible FCF record's index
+ * shall be returned.
+ **/
+uint16_t
+lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
+{
+ uint16_t next_fcf_index;
+
+ /* Search from the currently registered FCF index */
+ next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
+ LPFC_SLI4_FCF_TBL_INDX_MAX,
+ phba->fcf.current_rec.fcf_indx);
+ /* Wrap around condition on phba->fcf.fcf_rr_bmask */
+ if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX)
+ next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
+ LPFC_SLI4_FCF_TBL_INDX_MAX, 0);
+ /* Round robin failover stop condition */
+ if (next_fcf_index == phba->fcf.fcf_rr_init_indx)
+ return LPFC_FCOE_FCF_NEXT_NONE;
+
+ return next_fcf_index;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_index_set - Set bmask with eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine sets the FCF record index in to the eligible bmask for
+ * round robin failover search. It checks to make sure that the index
+ * does not go beyond the range of the driver allocated bmask dimension
+ * before setting the bit.
+ *
+ * Returns 0 if the index bit successfully set, otherwise, it returns
+ * -EINVAL.
+ **/
+int
+lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+ if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+ "2610 HBA FCF index reached driver's "
+ "book keeping dimension: fcf_index:%d, "
+ "driver_bmask_max:%d\n",
+ fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
+ return -EINVAL;
+ }
+ /* Set the eligible FCF record index bmask */
+ set_bit(fcf_index, phba->fcf.fcf_rr_bmask);
+
+ return 0;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_index_set - Clear bmask from eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine clears the FCF record index from the eligible bmask for
+ * round robin failover search. It checks to make sure that the index
+ * does not go beyond the range of the driver allocated bmask dimension
+ * before clearing the bit.
+ **/
+void
+lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+ if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+ "2762 HBA FCF index goes beyond driver's "
+ "book keeping dimension: fcf_index:%d, "
+ "driver_bmask_max:%d\n",
+ fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
+ return;
+ }
+ /* Clear the eligible FCF record index bmask */
+ clear_bit(fcf_index, phba->fcf.fcf_rr_bmask);
+}
+
+/**
* lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table
* @phba: pointer to lpfc hba data structure.
*
@@ -12014,21 +12253,40 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
&redisc_fcf->header.cfg_shdr.response);
if (shdr_status || shdr_add_status) {
- lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+ lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
"2746 Requesting for FCF rediscovery failed "
"status x%x add_status x%x\n",
shdr_status, shdr_add_status);
- /*
- * Request failed, last resort to re-try current
- * registered FCF entry
- */
- lpfc_retry_pport_discovery(phba);
- } else
+ if (phba->fcf.fcf_flag & FCF_ACVL_DISC) {
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
+ spin_unlock_irq(&phba->hbalock);
+ /*
+ * CVL event triggered FCF rediscover request failed,
+ * last resort to re-try current registered FCF entry.
+ */
+ lpfc_retry_pport_discovery(phba);
+ } else {
+ spin_lock_irq(&phba->hbalock);
+ phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
+ spin_unlock_irq(&phba->hbalock);
+ /*
+ * DEAD FCF event triggered FCF rediscover request
+ * failed, last resort to fail over as a link down
+ * to FCF registration.
+ */
+ lpfc_sli4_fcf_dead_failthrough(phba);
+ }
+ } else {
+ lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+ "2775 Start FCF rediscovery quiescent period "
+ "wait timer before scaning FCF table\n");
/*
* Start FCF rediscovery wait timer for pending FCF
* before rescan FCF record table.
*/
lpfc_fcf_redisc_wait_start_timer(phba);
+ }
mempool_free(mbox, phba->mbox_mem_pool);
}
@@ -12047,6 +12305,9 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba)
struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf;
int rc, length;
+ /* Cancel retry delay timers to all vports before FCF rediscover */
+ lpfc_cancel_all_vport_retry_delay_timer(phba);
+
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -12078,6 +12339,31 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba)
}
/**
+ * lpfc_sli4_fcf_dead_failthrough - Failthrough routine to fcf dead event
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This function is the failover routine as a last resort to the FCF DEAD
+ * event when driver failed to perform fast FCF failover.
+ **/
+void
+lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *phba)
+{
+ uint32_t link_state;
+
+ /*
+ * Last resort as FCF DEAD event failover will treat this as
+ * a link down, but save the link state because we don't want
+ * it to be changed to Link Down unless it is already down.
+ */
+ link_state = phba->link_state;
+ lpfc_linkdown(phba);
+ phba->link_state = link_state;
+
+ /* Unregister FCF if no devices connected to it */
+ lpfc_unregister_unused_fcf(phba);
+}
+
+/**
* lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled.
* @phba: pointer to lpfc hba data structure.
*
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index dfcf5437d1f..b4a639c4761 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -62,6 +62,7 @@ struct lpfc_iocbq {
#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */
#define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */
#define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */
+#define DSS_SECURITY_OP 0x100 /* security IO */
#define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */
#define LPFC_FIP_ELS_ID_SHIFT 14
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 86308836600..4a35e7b9bc5 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -153,15 +153,27 @@ struct lpfc_fcf {
#define FCF_REGISTERED 0x02 /* FCF registered with FW */
#define FCF_SCAN_DONE 0x04 /* FCF table scan done */
#define FCF_IN_USE 0x08 /* Atleast one discovery completed */
-#define FCF_REDISC_PEND 0x10 /* FCF rediscovery pending */
-#define FCF_REDISC_EVT 0x20 /* FCF rediscovery event to worker thread */
-#define FCF_REDISC_FOV 0x40 /* Post FCF rediscovery fast failover */
+#define FCF_INIT_DISC 0x10 /* Initial FCF discovery */
+#define FCF_DEAD_DISC 0x20 /* FCF DEAD fast FCF failover discovery */
+#define FCF_ACVL_DISC 0x40 /* All CVL fast FCF failover discovery */
+#define FCF_DISCOVERY (FCF_INIT_DISC | FCF_DEAD_DISC | FCF_ACVL_DISC)
+#define FCF_REDISC_PEND 0x80 /* FCF rediscovery pending */
+#define FCF_REDISC_EVT 0x100 /* FCF rediscovery event to worker thread */
+#define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */
uint32_t addr_mode;
+ uint16_t fcf_rr_init_indx;
struct lpfc_fcf_rec current_rec;
struct lpfc_fcf_rec failover_rec;
struct timer_list redisc_wait;
+ unsigned long *fcf_rr_bmask; /* Eligible FCF indexes for RR failover */
};
+/*
+ * Maximum FCF table index, it is for driver internal book keeping, it
+ * just needs to be no less than the supported HBA's FCF table size.
+ */
+#define LPFC_SLI4_FCF_TBL_INDX_MAX 32
+
#define LPFC_REGION23_SIGNATURE "RG23"
#define LPFC_REGION23_VERSION 1
#define LPFC_REGION23_LAST_REC 0xff
@@ -431,11 +443,18 @@ enum lpfc_sge_type {
SCSI_BUFF_TYPE
};
+enum lpfc_sgl_state {
+ SGL_FREED,
+ SGL_ALLOCATED,
+ SGL_XRI_ABORTED
+};
+
struct lpfc_sglq {
/* lpfc_sglqs are used in double linked lists */
struct list_head list;
struct list_head clist;
enum lpfc_sge_type buff_type; /* is this a scsi sgl */
+ enum lpfc_sgl_state state;
uint16_t iotag; /* pre-assigned IO tag */
uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */
struct sli4_sge *sgl; /* pre-assigned SGL */
@@ -463,8 +482,8 @@ void lpfc_sli4_mbox_cmd_free(struct lpfc_hba *, struct lpfcMboxq *);
void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t);
void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t,
struct lpfc_mbx_sge *);
-int lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *, struct lpfcMboxq *,
- uint16_t);
+int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *,
+ uint16_t);
void lpfc_sli4_hba_reset(struct lpfc_hba *);
struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t,
@@ -523,8 +542,13 @@ int lpfc_sli4_init_vpi(struct lpfc_hba *, uint16_t);
uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool);
uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool);
void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t);
-int lpfc_sli4_read_fcf_record(struct lpfc_hba *, uint16_t);
-void lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_read_fcf_rec(struct lpfc_hba *, uint16_t);
+void lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_sli4_unregister_fcf(struct lpfc_hba *);
int lpfc_sli4_post_status_check(struct lpfc_hba *);
uint8_t lpfc_sli4_mbox_opcode_get(struct lpfc_hba *, struct lpfcMboxq *);
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index ac276aa46fb..013deec5dae 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
-#define LPFC_DRIVER_VERSION "8.3.9"
+#define LPFC_DRIVER_VERSION "8.3.10"
#define LPFC_DRIVER_NAME "lpfc"
#define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp"
#define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp"
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index dc86e873102..ffd575c379f 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <scsi/scsi.h>
@@ -123,7 +124,12 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport)
}
mb = &pmb->u.mb;
- lpfc_read_sparam(phba, pmb, vport->vpi);
+ rc = lpfc_read_sparam(phba, pmb, vport->vpi);
+ if (rc) {
+ mempool_free(pmb, phba->mbox_mem_pool);
+ return -ENOMEM;
+ }
+
/*
* Grab buffer pointer and clear context1 so we can use
* lpfc_sli_issue_box_wait
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index 4a90eaf7cb6..3893337e3dd 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/nubus.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <asm/dma.h>
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 49eb0612d5a..4bf7edca9e6 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -47,6 +47,7 @@
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <scsi/scsicam.h>
#include "scsi.h"
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 7f977967b88..a7810a106b3 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -70,6 +70,7 @@
* For history of changes, see Documentation/ChangeLog.megaraid
*/
+#include <linux/slab.h>
#include "megaraid_mbox.h"
static int megaraid_init(void);
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index f680561d2c6..36e0b7d05c1 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -15,6 +15,7 @@
* Common management module
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include "megaraid_mm.h"
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 409648f5845..99e4478c3f3 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -35,6 +35,7 @@
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/uio.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/compat.h>
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 11aa917629a..a1c97e88068 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -23,7 +23,6 @@
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 411c27d7f78..cf44b355bc9 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -51,6 +51,7 @@
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "mpt2sas_base.h"
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index c7ec3f17478..be171ed682e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -53,6 +53,7 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/raid_class.h>
+#include <linux/slab.h>
#include "mpt2sas_base.h"
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 789f9ee7f00..bd7ca2b49f8 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -49,6 +49,7 @@
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c
index b5fbfd6ce87..39f554f5f26 100644
--- a/drivers/scsi/mvme16x_scsi.c
+++ b/drivers/scsi/mvme16x_scsi.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <asm/mvme16xhw.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h
index aa2270af1ba..885858bcc40 100644
--- a/drivers/scsi/mvsas/mv_sas.h
+++ b/drivers/scsi/mvsas/mv_sas.h
@@ -36,6 +36,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <scsi/libsas.h>
#include <scsi/scsi_tcq.h>
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index a2d56982830..d013a2aa2fd 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -98,6 +98,7 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 2c98a6ee973..4c1e5454520 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -26,7 +26,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/ioport.h>
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 24223473f57..ee4b6914667 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -39,6 +39,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
+
#include <scsi/osd_initiator.h>
#include <scsi/osd_sec.h>
#include <scsi/osd_attributes.h>
@@ -1433,6 +1435,10 @@ int osd_finalize_request(struct osd_request *or,
cdbh->command_specific_options |= or->attributes_mode;
if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
ret = _osd_req_finalize_attr_page(or);
+ if (ret) {
+ OSD_DEBUG("_osd_req_finalize_attr_page failed\n");
+ return ret;
+ }
} else {
/* TODO: I think that for the GET_ATTR command these 2 should
* be reversed to keep them in execution order (for embeded
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index 0a90702b3d7..ffdd9fdb999 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -50,6 +50,7 @@
#include <linux/idr.h>
#include <linux/major.h>
#include <linux/file.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_driver.h>
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index acb835837ee..b219118f8bd 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -38,6 +38,7 @@ static const char * osst_version = "0.99.4";
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index c2341af587a..02124645487 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1717,6 +1717,7 @@ static int nsp_cs_config(struct pcmcia_device *link)
cfg_mem->data = data;
ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem);
+ if (ret)
goto cs_failed;
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index 7db28cd4944..8c61a4fe1db 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -187,7 +187,7 @@
#define S_IO BIT(1) /* Input/Output line from SCSI bus */
#define S_CD BIT(2) /* Command/Data line from SCSI bus */
#define S_BUSY BIT(3) /* Busy line from SCSI bus */
-#define S_ACK BIT(4) /* Acknowlege line from SCSI bus */
+#define S_ACK BIT(4) /* Acknowledge line from SCSI bus */
#define S_REQUEST BIT(5) /* Request line from SCSI bus */
#define S_SELECT BIT(6) /* */
#define S_ATN BIT(7) /* */
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 14b13acae6d..45bc197bc22 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -38,6 +38,7 @@
*
*/
#include <linux/firmware.h>
+#include <linux/slab.h>
#include "pm8001_sas.h"
#include "pm8001_ctl.h"
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 9b44c6f1b10..909c00ec044 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -37,6 +37,7 @@
* POSSIBILITY OF SUCH DAMAGES.
*
*/
+ #include <linux/slab.h>
#include "pm8001_sas.h"
#include "pm8001_hwi.h"
#include "pm8001_chips.h"
@@ -2924,7 +2925,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
break;
default:
PM8001_MSG_DBG(pm8001_ha,
- pm8001_printk("unkown device type(%x)\n", deviceType));
+ pm8001_printk("unknown device type(%x)\n", deviceType));
break;
}
phy->phy_type |= PORT_TYPE_SAS;
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index f80c1da8f6c..f8c86b28f03 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -38,6 +38,7 @@
*
*/
+#include <linux/slab.h>
#include "pm8001_sas.h"
#include "pm8001_chips.h"
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 7f9c83a7639..bff4f5139b9 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -38,6 +38,7 @@
*
*/
+#include <linux/slab.h>
#include "pm8001_sas.h"
/**
@@ -600,7 +601,7 @@ static void pm8001_free_dev(struct pm8001_device *pm8001_dev)
* by the command "OPC_INB_REG_DEV", after that the HBA will assign a
* device ID(according to device's sas address) and returned it to LLDD. From
* now on, we communicate with HBA FW with the device ID which HBA assigned
- * rather than sas address. it is the neccessary step for our HBA but it is
+ * rather than sas address. it is the necessary step for our HBA but it is
* the optional for other HBA driver.
*/
static int pm8001_dev_found_notify(struct domain_device *dev)
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 9b1c1433c26..53aefffbaea 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -41,6 +41,7 @@
#include <linux/hdreg.h>
#include <linux/version.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/irq.h>
#include <asm/processor.h>
#include <linux/libata.h>
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index 92f89d50850..b8ad07c3449 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -938,7 +938,7 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = {
/*
* pmcraid_ioctl_header - definition of header structure that preceeds all the
- * buffers given as ioctl arguements.
+ * buffers given as ioctl arguments.
*
* .signature : always ASCII string, "PMCRAID"
* .reserved : not used
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 8aa0bd987e2..7bc2d796e40 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/parport.h>
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index db90caf43f4..92ffbb51049 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -20,6 +20,7 @@
#include <linux/cdrom.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 49ac4148493..b8166ecfd0e 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -17,9 +17,11 @@
* General Public License for more details.
*
******************************************************************************/
-#define QLA1280_VERSION "3.27"
+#define QLA1280_VERSION "3.27.1"
/*****************************************************************************
Revision History:
+ Rev 3.27.1, February 8, 2010, Michael Reed
+ - Retain firmware image for error recovery.
Rev 3.27, February 10, 2009, Michael Reed
- General code cleanup.
- Improve error recovery.
@@ -346,7 +348,6 @@
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
-#include <linux/slab.h>
#include <linux/pci_ids.h>
#include <linux/interrupt.h>
#include <linux/init.h>
@@ -538,9 +539,9 @@ __setup("qla1280=", qla1280_setup);
/*****************************************/
struct qla_boards {
- unsigned char name[9]; /* Board ID String */
+ char *name; /* Board ID String */
int numPorts; /* Number of SCSI ports */
- char *fwname; /* firmware name */
+ int fw_index; /* index into qla1280_fw_tbl for firmware */
};
/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
@@ -561,15 +562,30 @@ static struct pci_device_id qla1280_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
+DEFINE_MUTEX(qla1280_firmware_mutex);
+
+struct qla_fw {
+ char *fwname;
+ const struct firmware *fw;
+};
+
+#define QL_NUM_FW_IMAGES 3
+
+struct qla_fw qla1280_fw_tbl[QL_NUM_FW_IMAGES] = {
+ {"qlogic/1040.bin", NULL}, /* image 0 */
+ {"qlogic/1280.bin", NULL}, /* image 1 */
+ {"qlogic/12160.bin", NULL}, /* image 2 */
+};
+
+/* NOTE: Order of boards in this table must match order in qla1280_pci_tbl */
static struct qla_boards ql1280_board_tbl[] = {
- /* Name , Number of ports, FW details */
- {"QLA12160", 2, "qlogic/12160.bin"},
- {"QLA1040", 1, "qlogic/1040.bin"},
- {"QLA1080", 1, "qlogic/1280.bin"},
- {"QLA1240", 2, "qlogic/1280.bin"},
- {"QLA1280", 2, "qlogic/1280.bin"},
- {"QLA10160", 1, "qlogic/12160.bin"},
- {" ", 0, " "},
+ {.name = "QLA12160", .numPorts = 2, .fw_index = 2},
+ {.name = "QLA1040" , .numPorts = 1, .fw_index = 0},
+ {.name = "QLA1080" , .numPorts = 1, .fw_index = 1},
+ {.name = "QLA1240" , .numPorts = 2, .fw_index = 1},
+ {.name = "QLA1280" , .numPorts = 2, .fw_index = 1},
+ {.name = "QLA10160", .numPorts = 1, .fw_index = 2},
+ {.name = " ", .numPorts = 0, .fw_index = -1},
};
static int qla1280_verbose = 1;
@@ -1512,6 +1528,63 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
}
/*
+ * qla1280_request_firmware
+ * Acquire firmware for chip. Retain in memory
+ * for error recovery.
+ *
+ * Input:
+ * ha = adapter block pointer.
+ *
+ * Returns:
+ * Pointer to firmware image or an error code
+ * cast to pointer via ERR_PTR().
+ */
+static const struct firmware *
+qla1280_request_firmware(struct scsi_qla_host *ha)
+{
+ const struct firmware *fw;
+ int err;
+ int index;
+ char *fwname;
+
+ spin_unlock_irq(ha->host->host_lock);
+ mutex_lock(&qla1280_firmware_mutex);
+
+ index = ql1280_board_tbl[ha->devnum].fw_index;
+ fw = qla1280_fw_tbl[index].fw;
+ if (fw)
+ goto out;
+
+ fwname = qla1280_fw_tbl[index].fwname;
+ err = request_firmware(&fw, fwname, &ha->pdev->dev);
+
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ fw = ERR_PTR(err);
+ goto unlock;
+ }
+ if ((fw->size % 2) || (fw->size < 6)) {
+ printk(KERN_ERR "Invalid firmware length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ fw = ERR_PTR(-EINVAL);
+ goto unlock;
+ }
+
+ qla1280_fw_tbl[index].fw = fw;
+
+ out:
+ ha->fwver1 = fw->data[0];
+ ha->fwver2 = fw->data[1];
+ ha->fwver3 = fw->data[2];
+ unlock:
+ mutex_unlock(&qla1280_firmware_mutex);
+ spin_lock_irq(ha->host->host_lock);
+ return fw;
+}
+
+/*
* Chip diagnostics
* Test chip for proper operation.
*
@@ -1634,30 +1707,18 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
static int
qla1280_load_firmware_pio(struct scsi_qla_host *ha)
{
+ /* enter with host_lock acquired */
+
const struct firmware *fw;
const __le16 *fw_data;
uint16_t risc_address, risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT], i;
- int err;
+ int err = 0;
+
+ fw = qla1280_request_firmware(ha);
+ if (IS_ERR(fw))
+ return PTR_ERR(fw);
- spin_unlock_irq(ha->host->host_lock);
- err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
- &ha->pdev->dev);
- spin_lock_irq(ha->host->host_lock);
- if (err) {
- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
- ql1280_board_tbl[ha->devnum].fwname, err);
- return err;
- }
- if ((fw->size % 2) || (fw->size < 6)) {
- printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
- fw->size, ql1280_board_tbl[ha->devnum].fwname);
- err = -EINVAL;
- goto out;
- }
- ha->fwver1 = fw->data[0];
- ha->fwver2 = fw->data[1];
- ha->fwver3 = fw->data[2];
fw_data = (const __le16 *)&fw->data[0];
ha->fwstart = __le16_to_cpu(fw_data[2]);
@@ -1675,11 +1736,10 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha)
if (err) {
printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
ha->host_no);
- goto out;
+ break;
}
}
-out:
- release_firmware(fw);
+
return err;
}
@@ -1687,6 +1747,7 @@ out:
static int
qla1280_load_firmware_dma(struct scsi_qla_host *ha)
{
+ /* enter with host_lock acquired */
const struct firmware *fw;
const __le16 *fw_data;
uint16_t risc_address, risc_code_size;
@@ -1701,24 +1762,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
return -ENOMEM;
#endif
- spin_unlock_irq(ha->host->host_lock);
- err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
- &ha->pdev->dev);
- spin_lock_irq(ha->host->host_lock);
- if (err) {
- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
- ql1280_board_tbl[ha->devnum].fwname, err);
- return err;
- }
- if ((fw->size % 2) || (fw->size < 6)) {
- printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
- fw->size, ql1280_board_tbl[ha->devnum].fwname);
- err = -EINVAL;
- goto out;
- }
- ha->fwver1 = fw->data[0];
- ha->fwver2 = fw->data[1];
- ha->fwver3 = fw->data[2];
+ fw = qla1280_request_firmware(ha);
+ if (IS_ERR(fw))
+ return PTR_ERR(fw);
+
fw_data = (const __le16 *)&fw->data[0];
ha->fwstart = __le16_to_cpu(fw_data[2]);
@@ -1803,7 +1850,6 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
#if DUMP_IT_BACK
pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
#endif
- release_firmware(fw);
return err;
}
@@ -1842,6 +1888,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
static int
qla1280_load_firmware(struct scsi_qla_host *ha)
{
+ /* enter with host_lock taken */
int err;
err = qla1280_chip_diag(ha);
@@ -4420,7 +4467,16 @@ qla1280_init(void)
static void __exit
qla1280_exit(void)
{
+ int i;
+
pci_unregister_driver(&qla1280_pci_driver);
+ /* release any allocated firmware images */
+ for (i = 0; i < QL_NUM_FW_IMAGES; i++) {
+ if (qla1280_fw_tbl[i].fw) {
+ release_firmware(qla1280_fw_tbl[i].fw);
+ qla1280_fw_tbl[i].fw = NULL;
+ }
+ }
}
module_init(qla1280_init);
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 90d1e062ec4..1c7ef55966f 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -8,6 +8,7 @@
#include <linux/kthread.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/delay.h>
static int qla24xx_vport_disable(struct fc_vport *, bool);
@@ -1274,7 +1275,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
int rval = QLA_FUNCTION_FAILED;
uint16_t state[5];
- if (!vha->hw->flags.eeh_busy)
+ if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
+ test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+ DEBUG2_3_11(printk("%s(%ld): isp reset in progress.\n",
+ __func__, vha->host_no));
+ else if (!vha->hw->flags.eeh_busy)
rval = qla2x00_get_firmware_state(vha, state);
if (rval != QLA_SUCCESS)
memset(state, -1, sizeof(state));
@@ -2388,6 +2393,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
return 0;
done:
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (bsg_job->request->msgcode == FC_BSG_HST_CT)
kfree(sp->fcport);
kfree(sp->ctx);
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index cebf4f1bb7d..42c5587cc50 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1592,10 +1592,22 @@ struct nvram_81xx {
/* Offset 384. */
uint8_t reserved_21[16];
- uint16_t reserved_22[8];
+ uint16_t reserved_22[3];
+
+ /*
+ * BIT 0 = Extended BB credits for LR
+ * BIT 1 = Virtual Fabric Enable
+ * BIT 2 = Enhanced Features Unused
+ * BIT 3-7 = Enhanced Features Reserved
+ */
+ /* Enhanced Features */
+ uint8_t enhanced_features;
+
+ uint8_t reserved_23;
+ uint16_t reserved_24[4];
/* Offset 416. */
- uint16_t reserved_23[32];
+ uint16_t reserved_25[32];
/* Offset 480. */
uint8_t model_name[16];
@@ -1603,7 +1615,7 @@ struct nvram_81xx {
/* Offset 496. */
uint16_t feature_mask_l;
uint16_t feature_mask_h;
- uint16_t reserved_24[2];
+ uint16_t reserved_26[2];
uint16_t subsystem_vendor_id;
uint16_t subsystem_device_id;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a67b2bafb88..4229bb483c5 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -8,6 +8,7 @@
#include "qla_gbl.h"
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "qla_devtbl.h"
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index ab90329ff2e..db539b0c3da 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -7,6 +7,7 @@
#include "qla_def.h"
#include <linux/delay.h>
+#include <linux/slab.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_bsg_fc.h>
@@ -620,11 +621,10 @@ skip_rio:
* vp_idx does not match
* Event is not global, vp_idx does not match
*/
- if ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff)
- || (mb[1] != 0xffff)) {
- if (vha->vp_idx != (mb[3] & 0xff))
- break;
- }
+ if (IS_QLA2XXX_MIDTYPE(ha) &&
+ ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff) ||
+ (mb[1] != 0xffff)) && vha->vp_idx != (mb[3] & 0xff))
+ break;
/* Global event -- port logout or port unavailable. */
if (mb[1] == 0xffff && mb[2] == 0x7) {
@@ -2272,30 +2272,28 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
/* If possible, enable MSI-X. */
if (!IS_QLA2432(ha) && !IS_QLA2532(ha) &&
- !IS_QLA8432(ha) && !IS_QLA8001(ha))
- goto skip_msix;
+ !IS_QLA8432(ha) && !IS_QLA8001(ha))
+ goto skip_msi;
+
+ if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
+ (ha->pdev->subsystem_device == 0x7040 ||
+ ha->pdev->subsystem_device == 0x7041 ||
+ ha->pdev->subsystem_device == 0x1705)) {
+ DEBUG2(qla_printk(KERN_WARNING, ha,
+ "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X,0x%X).\n",
+ ha->pdev->subsystem_vendor,
+ ha->pdev->subsystem_device));
+ goto skip_msi;
+ }
if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX ||
!QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
DEBUG2(qla_printk(KERN_WARNING, ha,
"MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
ha->pdev->revision, ha->fw_attributes));
-
goto skip_msix;
}
- if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
- (ha->pdev->subsystem_device == 0x7040 ||
- ha->pdev->subsystem_device == 0x7041 ||
- ha->pdev->subsystem_device == 0x1705)) {
- DEBUG2(qla_printk(KERN_WARNING, ha,
- "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X, 0x%X).\n",
- ha->pdev->subsystem_vendor,
- ha->pdev->subsystem_device));
-
- goto skip_msi;
- }
-
ret = qla24xx_enable_msix(ha, rsp);
if (!ret) {
DEBUG2(qla_printk(KERN_INFO, ha,
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 6e53bdbb1da..42eb7ffd594 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -7,6 +7,7 @@
#include "qla_def.h"
#include <linux/delay.h>
+#include <linux/gfp.h>
/*
@@ -339,6 +340,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
return rval;
}
+#define EXTENDED_BB_CREDITS BIT_0
/*
* qla2x00_execute_fw
* Start adapter firmware.
@@ -371,7 +373,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
mcp->mb[1] = MSW(risc_addr);
mcp->mb[2] = LSW(risc_addr);
mcp->mb[3] = 0;
- mcp->mb[4] = 0;
+ if (IS_QLA81XX(ha)) {
+ struct nvram_81xx *nv = ha->nvram;
+ mcp->mb[4] = (nv->enhanced_features &
+ EXTENDED_BB_CREDITS);
+ } else
+ mcp->mb[4] = 0;
mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
mcp->in_mb |= MBX_1;
} else {
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index ff17dee2861..8220e7b9799 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -9,6 +9,7 @@
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <scsi/scsi_tcq.h>
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 46720b23028..48c37e38ed0 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -12,6 +12,7 @@
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/kobject.h>
+#include <linux/slab.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
@@ -1676,9 +1677,11 @@ skip_pio:
/* Determine queue resources */
ha->max_req_queues = ha->max_rsp_queues = 1;
- if ((ql2xmaxqueues <= 1 || ql2xmultique_tag < 1) &&
+ if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) ||
+ (ql2xmaxqueues > 1 && ql2xmultique_tag) ||
(!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
goto mqiobase_exit;
+
ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
pci_resource_len(ha->pdev, 3));
if (ha->mqiobase) {
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 371dc895972..8b3de4e54c2 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -7,6 +7,7 @@
#include "qla_def.h"
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 8d2fc2fa7a6..109068df933 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.02-k1"
+#define QLA2XXX_VERSION "8.03.02-k2"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
#define QLA_DRIVER_PATCH_VER 2
-#define QLA_DRIVER_BETA_VER 1
+#define QLA_DRIVER_BETA_VER 2
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 09d6d4b76f3..caeb7d10ae0 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -467,7 +467,7 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
if (conn_err_detail)
*conn_err_detail = mbox_sts[5];
if (tcp_source_port_num)
- *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
+ *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16);
if (connection_id)
*connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
status = QLA_SUCCESS;
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 83c8b5e4fc8..2ccad36bee9 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -5,6 +5,7 @@
* See LICENSE.qla4xxx for copyright and licensing details.
*/
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index fa34b92850a..aa406497eeb 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -16,7 +16,7 @@
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/blkdev.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
@@ -738,7 +738,7 @@ static int __devinit qpti_register_irq(struct qlogicpti *qpti)
* sanely maintain.
*/
if (request_irq(qpti->irq, qpti_intr,
- IRQF_SHARED, "Qlogic/PTI", qpti))
+ IRQF_SHARED, "QlogicPTI", qpti))
goto fail;
printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq);
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index bd88349b852..2c146b44d95 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -63,6 +63,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev)
* emulated RAID devices, so start with SCSI */
struct raid_internal *i = ac_to_raid_internal(cont);
+#if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE)
if (scsi_is_sdev_device(dev)) {
struct scsi_device *sdev = to_scsi_device(dev);
@@ -71,6 +72,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev)
return i->f->is_raid(dev);
}
+#endif
/* FIXME: look at other subsystems too */
return 0;
}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 0b575c87100..3e10c306de9 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/timer.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/genhd.h>
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 37af178b2d1..43fad4c09be 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -6,6 +6,7 @@
#include <linux/moduleparam.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_devinfo.h>
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 08ed506e605..d45c69ca573 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/gfp.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/kernel.h>
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
index 0fd6ae6911a..d53e6503c6d 100644
--- a/drivers/scsi/scsi_netlink.c
+++ b/drivers/scsi/scsi_netlink.c
@@ -22,6 +22,7 @@
#include <linux/jiffies.h>
#include <linux/security.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/netlink.h>
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
index 77fbddb507f..c99da926fda 100644
--- a/drivers/scsi/scsi_proc.c
+++ b/drivers/scsi/scsi_proc.c
@@ -20,12 +20,12 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/errno.h>
#include <linux/blkdev.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <scsi/scsi.h>
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 4bc8b77a2ef..38518b08807 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -33,6 +33,7 @@
#include <linux/kthread.h>
#include <linux/spinlock.h>
#include <linux/async.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 19ec9e2d3f3..429c9b73e3e 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -7,6 +7,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/device.h>
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
index 0e9533f7aab..a87e21c35ef 100644
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -20,6 +20,7 @@
* 02110-1301 USA
*/
#include <linux/miscdevice.h>
+#include <linux/gfp.h>
#include <linux/file.h>
#include <linux/smp_lock.h>
#include <net/tcp.h>
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 10303272ba4..66241dd525a 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -23,6 +23,7 @@
#include <linux/hash.h>
#include <linux/module.h>
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 79660ee3e21..6cfffc88022 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -27,6 +27,7 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
@@ -1232,6 +1233,15 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr,
{
struct fc_vport *vport = transport_class_to_vport(dev);
struct Scsi_Host *shost = vport_to_shost(vport);
+ unsigned long flags;
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ return -EBUSY;
+ }
+ vport->flags |= FC_VPORT_DELETING;
+ spin_unlock_irqrestore(shost->host_lock, flags);
fc_queue_work(shost, &vport->vport_delete_work);
return count;
@@ -1821,6 +1831,9 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr,
list_for_each_entry(vport, &fc_host->vports, peers) {
if ((vport->channel == 0) &&
(vport->port_name == wwpn) && (vport->node_name == wwnn)) {
+ if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
+ break;
+ vport->flags |= FC_VPORT_DELETING;
match = 1;
break;
}
@@ -3370,18 +3383,6 @@ fc_vport_terminate(struct fc_vport *vport)
unsigned long flags;
int stat;
- spin_lock_irqsave(shost->host_lock, flags);
- if (vport->flags & FC_VPORT_CREATING) {
- spin_unlock_irqrestore(shost->host_lock, flags);
- return -EBUSY;
- }
- if (vport->flags & (FC_VPORT_DEL)) {
- spin_unlock_irqrestore(shost->host_lock, flags);
- return -EALREADY;
- }
- vport->flags |= FC_VPORT_DELETING;
- spin_unlock_irqrestore(shost->host_lock, flags);
-
if (i->f->vport_delete)
stat = i->f->vport_delete(vport);
else
@@ -3852,7 +3853,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
req->errors = -ENXIO;
spin_unlock_irq(q->queue_lock);
- blk_end_request(req, -ENXIO, blk_rq_bytes(req));
+ blk_end_request_all(req, -ENXIO);
spin_lock_irq(q->queue_lock);
continue;
}
@@ -3862,7 +3863,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
ret = fc_req_to_bsgjob(shost, rport, req);
if (ret) {
req->errors = ret;
- blk_end_request(req, ret, blk_rq_bytes(req));
+ blk_end_request_all(req, ret);
spin_lock_irq(q->queue_lock);
continue;
}
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index ea3892e7e0f..1e6d4793542 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -22,6 +22,7 @@
*/
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <net/tcp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index c25bd9a34e0..8a172d4f456 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -25,6 +25,7 @@
#include <linux/blkdev.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include "scsi_priv.h"
#include <scsi/scsi_device.h>
diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c
index 3f21bc65e8c..6803b1e26ec 100644
--- a/drivers/scsi/scsicam.c
+++ b/drivers/scsi/scsicam.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/genhd.h>
#include <linux/kernel.h>
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 1dd4d840769..8b827f37b03 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -49,6 +49,7 @@
#include <linux/mutex.h>
#include <linux/string_helpers.h>
#include <linux/async.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
@@ -1948,7 +1949,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
{
struct request_queue *q = sdkp->disk->queue;
unsigned int sector_sz = sdkp->device->sector_size;
- const int vpd_len = 32;
+ const int vpd_len = 64;
unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL);
if (!buffer ||
@@ -1998,7 +1999,7 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
{
unsigned char *buffer;
u16 rot;
- const int vpd_len = 32;
+ const int vpd_len = 64;
buffer = kmalloc(vpd_len, GFP_KERNEL);
@@ -2111,7 +2112,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
* which is followed by sdaaa.
*
* This is basically 26 base counting with one extra 'nil' entry
- * at the beggining from the second digit on and can be
+ * at the beginning from the second digit on and can be
* determined using similar method as 26 base conversion with the
* index shifted -1 after each digit is computed.
*
@@ -2185,7 +2186,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
gd->driverfs_dev = &sdp->sdev_gendev;
- gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
+ gd->flags = GENHD_FL_EXT_DEVT;
if (sdp->removable)
gd->flags |= GENHD_FL_REMOVABLE;
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 1d7a8780e00..7f5a6a86f82 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -21,6 +21,7 @@
**-----------------------------------------------------------------------------
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/enclosure.h>
@@ -595,8 +596,6 @@ static int ses_intf_add(struct device *cdev,
ses_dev->page10_len = len;
buf = NULL;
}
- kfree(hdr_buf);
-
scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
if (!scomp)
goto err_free;
@@ -608,6 +607,8 @@ static int ses_intf_add(struct device *cdev,
goto err_free;
}
+ kfree(hdr_buf);
+
edev->scratch = ses_dev;
for (i = 0; i < components; i++)
edev->component[i].scratch = scomp + i;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index c996d98636f..dee1c96288d 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -38,6 +38,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#include <linux/errno.h>
#include <linux/mtio.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index 0807b260268..fef0e3c75b1 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -226,7 +226,7 @@ static struct scsi_host_template sgiwd93_template = {
.use_clustering = DISABLE_CLUSTERING,
};
-static int __init sgiwd93_probe(struct platform_device *pdev)
+static int __devinit sgiwd93_probe(struct platform_device *pdev)
{
struct sgiwd93_platform_data *pd = pdev->dev.platform_data;
unsigned char *wdregs = pd->wdregs;
diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c
index 6dc8b846c11..8ac6ce792b6 100644
--- a/drivers/scsi/sim710.c
+++ b/drivers/scsi/sim710.c
@@ -27,6 +27,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/device.h>
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c
index 37b3359e863..9acc2b2a360 100644
--- a/drivers/scsi/sni_53c710.c
+++ b/drivers/scsi/sni_53c710.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/blkdev.h>
@@ -64,7 +65,7 @@ static struct scsi_host_template snirm710_template = {
.module = THIS_MODULE,
};
-static int __init snirm710_probe(struct platform_device *dev)
+static int __devinit snirm710_probe(struct platform_device *dev)
{
unsigned long base;
struct NCR_700_Host_Parameters *hostdata;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index d6f340f48a3..0a90abc7f14 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -44,6 +44,7 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <scsi/scsi.h>
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 291236e6e43..cbb38c5197f 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -7,6 +7,7 @@
#include <linux/blkpg.h>
#include <linux/cdrom.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
index 4ad3e017213..92cc2efb25d 100644
--- a/drivers/scsi/sr_vendor.c
+++ b/drivers/scsi/sr_vendor.c
@@ -39,6 +39,7 @@
#include <linux/string.h>
#include <linux/bcd.h>
#include <linux/blkdev.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index f67d1a159aa..3ea1a713ef2 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -27,6 +27,7 @@ static const char *verstr = "20081215";
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/mtio.h>
#include <linux/cdrom.h>
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index fd7b15be764..9c73dbda3bb 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -17,6 +17,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/time.h>
#include <linux/pci.h>
#include <linux/blkdev.h>
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 75da6e58ce5..b5838d547c6 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -645,6 +645,7 @@ __inline__ void NCR5380_print_phase(struct Scsi_Host *instance) { };
* interrupt or bottom half.
*/
+#include <linux/gfp.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
index 34a99620e5b..0621037f027 100644
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -4,6 +4,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/module.h>
diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c
index 3d73aad4bc8..fc23d273fb1 100644
--- a/drivers/scsi/sun_esp.c
+++ b/drivers/scsi/sun_esp.c
@@ -12,6 +12,7 @@
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/gfp.h>
#include <asm/irq.h>
#include <asm/io.h>
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 9a4273445c0..27866b0adfe 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -233,6 +233,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <scsi/scsi.h>
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index 26e8e0e6b8d..5d9fdeeb231 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -420,6 +420,7 @@
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <asm/dma.h>
#include <asm/irq.h>
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index e4ac5829b63..26894459c37 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 2f6e9d8eaf7..333580bf37c 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -171,7 +171,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>
#include <linux/proc_fs.h>
@@ -1588,7 +1587,7 @@ static int wd7000_host_reset(struct scsi_cmnd *SCpnt)
{
Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
- spin_unlock_irq(SCpnt->device->host->host_lock);
+ spin_lock_irq(SCpnt->device->host->host_lock);
if (wd7000_adapter_reset(host) < 0) {
spin_unlock_irq(SCpnt->device->host->host_lock);
diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c
index 64d40a2d4d4..105449c15fa 100644
--- a/drivers/scsi/zorro7xx.c
+++ b/drivers/scsi/zorro7xx.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/zorro.h>
+#include <linux/slab.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index ae0251ef6f4..78ed24bb6a3 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -35,6 +35,7 @@
#include <linux/pm.h>
#include <linux/bitops.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 7c4ebe6ee18..2b1ea3d4c4f 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -38,6 +38,7 @@
#include <linux/serial_8250.h>
#include <linux/nmi.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -2408,6 +2409,21 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
}
static void
+serial8250_set_ldisc(struct uart_port *port)
+{
+ int line = port->line;
+
+ if (line >= port->state->port.tty->driver->num)
+ return;
+
+ if (port->state->port.tty->ldisc->ops->num == N_PPS) {
+ port->flags |= UPF_HARDPPS_CD;
+ serial8250_enable_ms(port);
+ } else
+ port->flags &= ~UPF_HARDPPS_CD;
+}
+
+static void
serial8250_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
@@ -2628,6 +2644,7 @@ static struct uart_ops serial8250_pops = {
.startup = serial8250_startup,
.shutdown = serial8250_shutdown,
.set_termios = serial8250_set_termios,
+ .set_ldisc = serial8250_set_ldisc,
.pm = serial8250_pm,
.type = serial8250_type,
.release_port = serial8250_release_port,
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 33149d982e8..d8c0ffbfa6e 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/serial_core.h>
#include <linux/signal.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <asm/hardware.h>
diff --git a/drivers/serial/8250_hp300.c b/drivers/serial/8250_hp300.c
index 0e1410f2c03..c13438c9301 100644
--- a/drivers/serial/8250_hp300.c
+++ b/drivers/serial/8250_hp300.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/dio.h>
#include <linux/console.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include "8250.h"
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 24485cc62ff..4822cb50cd0 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -348,6 +348,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "FUJ02E6", 0 },
/* Fujitsu Wacom 2FGT Tablet PC device */
{ "FUJ02E7", 0 },
+ /* Fujitsu Wacom 1FGT Tablet PC device */
+ { "FUJ02E9", 0 },
/*
* LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
* disguise)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 746e07033dc..f55c49475a8 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -447,7 +447,7 @@ config SERIAL_CLPS711X_CONSOLE
config SERIAL_SAMSUNG
tristate "Samsung SoC serial support"
- depends on ARM && PLAT_S3C
+ depends on ARM && PLAT_SAMSUNG
select SERIAL_CORE
help
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
@@ -455,11 +455,18 @@ config SERIAL_SAMSUNG
provide all of these ports, depending on how the serial port
pins are configured.
+config SERIAL_SAMSUNG_UARTS_4
+ bool
+ depends on ARM && PLAT_SAMSUNG
+ default y if CPU_S3C2443
+ help
+ Internal node for the common case of 4 Samsung compatible UARTs
+
config SERIAL_SAMSUNG_UARTS
int
- depends on ARM && PLAT_S3C
+ depends on ARM && PLAT_SAMSUNG
default 2 if ARCH_S3C2400
- default 4 if ARCH_S5PC1XX || ARCH_S3C64XX || CPU_S3C2443
+ default 4 if SERIAL_SAMSUNG_UARTS_4
default 3
help
Select the number of available UART ports for the Samsung S3C
@@ -526,20 +533,30 @@ config SERIAL_S3C24A0
Serial port support for the Samsung S3C24A0 SoC
config SERIAL_S3C6400
- tristate "Samsung S3C6400/S3C6410 Serial port support"
- depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410)
+ tristate "Samsung S3C6400/S3C6410/S5P6440 Seria port support"
+ depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440)
+ select SERIAL_SAMSUNG_UARTS_4
default y
help
- Serial port support for the Samsung S3C6400 and S3C6410
+ Serial port support for the Samsung S3C6400, S3C6410 and S5P6440
SoCs
config SERIAL_S5PC100
tristate "Samsung S5PC100 Serial port support"
depends on SERIAL_SAMSUNG && CPU_S5PC100
+ select SERIAL_SAMSUNG_UARTS_4
default y
help
Serial port support for the Samsung S5PC100 SoCs
+config SERIAL_S5PV210
+ tristate "Samsung S5PV210 Serial port support"
+ depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442)
+ select SERIAL_SAMSUNG_UARTS_4 if CPU_S5PV210
+ default y
+ help
+ Serial port support for Samsung's S5P Family of SoC's
+
config SERIAL_MAX3100
tristate "MAX3100 support"
depends on SPI
@@ -996,7 +1013,7 @@ config SERIAL_IP22_ZILOG_CONSOLE
config SERIAL_SH_SCI
tristate "SuperH SCI(F) serial port support"
- depends on HAVE_CLK && (SUPERH || H8300)
+ depends on HAVE_CLK && (SUPERH || H8300 || ARCH_SHMOBILE)
select SERIAL_CORE
config SERIAL_SH_SCI_NR_UARTS
@@ -1009,6 +1026,10 @@ config SERIAL_SH_SCI_CONSOLE
depends on SERIAL_SH_SCI=y
select SERIAL_CORE_CONSOLE
+config SERIAL_SH_SCI_DMA
+ bool "DMA support"
+ depends on SERIAL_SH_SCI && SH_DMAE && EXPERIMENTAL
+
config SERIAL_PNX8XXX
bool "Enable PNX8XXX SoCs' UART Support"
depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 5548fe7df61..6aa4723b74e 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o
+obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
obj-$(CONFIG_SERIAL_MUX) += mux.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 429a8ae8693..b09a638d051 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -47,6 +47,7 @@
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <asm/io.h>
@@ -471,6 +472,20 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
spin_unlock_irqrestore(&uap->port.lock, flags);
}
+static void pl010_set_ldisc(struct uart_port *port)
+{
+ int line = port->line;
+
+ if (line >= port->state->port.tty->driver->num)
+ return;
+
+ if (port->state->port.tty->ldisc->ops->num == N_PPS) {
+ port->flags |= UPF_HARDPPS_CD;
+ pl010_enable_ms(port);
+ } else
+ port->flags &= ~UPF_HARDPPS_CD;
+}
+
static const char *pl010_type(struct uart_port *port)
{
return port->type == PORT_AMBA ? "AMBA" : NULL;
@@ -531,6 +546,7 @@ static struct uart_ops amba_pl010_pops = {
.startup = pl010_startup,
.shutdown = pl010_shutdown,
.set_termios = pl010_set_termios,
+ .set_ldisc = pl010_set_ldisc,
.type = pl010_type,
.release_port = pl010_release_port,
.request_port = pl010_request_port,
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index ce6c35333ff..743ebf5f16d 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -47,6 +47,7 @@
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/sizes.h>
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index fcf273e3f48..96f7e7484fe 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/ioport.h>
+#include <linux/gfp.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/console.h>
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index 7c72888fbf9..c88f8ad3ff8 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 1b94c56ec23..3fc1d66e32c 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/tty.h>
+#include <linux/gfp.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/serial.h>
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index a9802e76b5f..814ac006393 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/console.h>
@@ -61,7 +62,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
void __iomem *pram;
unsigned long offset;
struct resource res;
- unsigned long len;
+ resource_size_t len;
/* Don't remap parameter RAM if it has already been initialized
* during console setup.
@@ -74,7 +75,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
if (of_address_to_resource(np, 1, &res))
return NULL;
- len = 1 + res.end - res.start;
+ len = resource_size(&res);
pram = ioremap(res.start, len);
if (!pram)
return NULL;
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index d00fcf8e6c7..4315b23590b 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -46,6 +46,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/rational.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -440,7 +441,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
temp = readl(sport->port.membase + USR2);
if (temp & USR2_BRCD) {
- writel(temp | USR2_BRCD, sport->port.membase + USR2);
+ writel(USR2_BRCD, sport->port.membase + USR2);
if (uart_handle_break(&sport->port))
continue;
}
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index 23ba6b40b3a..f164ba4eba0 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -20,6 +20,7 @@
#include <linux/pci.h>
#include <linux/serial_core.h>
#include <linux/ioc3.h>
+#include <linux/slab.h>
/*
* Interesting things about the ioc3
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 836d9ab4f72..8ad28fc6492 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -22,6 +22,7 @@
#include <linux/pci.h>
#include <linux/ioc4.h>
#include <linux/serial_core.h>
+#include <linux/slab.h>
/*
* interesting things about the ioc4
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index 12cb5e446a4..eaf54501411 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -26,6 +26,7 @@
***********************************************************************/
#include <linux/moduleparam.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "jsm.h"
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 5673ca9dfdc..7a4a914ecff 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -30,6 +30,7 @@
#include <linux/serial_reg.h>
#include <linux/delay.h> /* For udelay */
#include <linux/pci.h>
+#include <linux/slab.h>
#include "jsm.h"
diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c
index 3c30c56aa2e..3351c3bd59e 100644
--- a/drivers/serial/max3100.c
+++ b/drivers/serial/max3100.c
@@ -41,6 +41,7 @@
#define MAX_MAX3100 4
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index 7bb5fee639e..b5aaef965f2 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -263,6 +263,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
}
spin_lock_irqsave(&port->lock, flags);
+ uart_update_timeout(port, termios->c_cflag, baud);
writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR);
@@ -379,6 +380,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data)
static void mcf_config_port(struct uart_port *port, int flags)
{
port->type = PORT_MCF;
+ port->fifosize = MCFUART_TXFIFOSIZE;
/* Clear mask, so no surprise interrupts. */
writeb(0, port->membase + MCFUART_UIMR);
@@ -424,7 +426,7 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
/*
* Define the basic serial functions we support.
*/
-static struct uart_ops mcf_uart_ops = {
+static const struct uart_ops mcf_uart_ops = {
.tx_empty = mcf_tx_empty,
.get_mctrl = mcf_get_mctrl,
.set_mctrl = mcf_set_mctrl,
@@ -443,7 +445,7 @@ static struct uart_ops mcf_uart_ops = {
.verify_port = mcf_verify_port,
};
-static struct mcf_uart mcf_ports[3];
+static struct mcf_uart mcf_ports[4];
#define MCF_MAXPORTS ARRAY_SIZE(mcf_ports)
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 3119fddaedb..a176ab4bd65 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -29,39 +29,6 @@
* kind, whether express or implied.
*/
-/* Platform device Usage :
- *
- * Since PSCs can have multiple function, the correct driver for each one
- * is selected by calling mpc52xx_match_psc_function(...). The function
- * handled by this driver is "uart".
- *
- * The driver init all necessary registers to place the PSC in uart mode without
- * DCD. However, the pin multiplexing aren't changed and should be set either
- * by the bootloader or in the platform init code.
- *
- * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2,
- * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and
- * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly
- * fpr the console code : without this 1:1 mapping, at early boot time, when we
- * are parsing the kernel args console=ttyPSC?, we wouldn't know which PSC it
- * will be mapped to.
- */
-
-/* OF Platform device Usage :
- *
- * This driver is only used for PSCs configured in uart mode. The device
- * tree will have a node for each PSC with "mpc52xx-psc-uart" in the compatible
- * list.
- *
- * By default, PSC devices are enumerated in the order they are found. However
- * a particular PSC number can be forces by adding 'device_no = <port#>'
- * to the device node.
- *
- * The driver init all necessary registers to place the PSC in uart mode without
- * DCD. However, the pin multiplexing aren't changed and should be set either
- * by the bootloader or in the platform init code.
- */
-
#undef DEBUG
#include <linux/device.h>
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index b5496c28e60..55e113a0be0 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -70,6 +70,7 @@
#include <linux/dma-mapping.h>
#include <linux/mv643xx.h>
#include <linux/platform_device.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 7571aaa138b..9711e06a837 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/console.h>
-#include <linux/slab.h>
#include <linux/delay.h> /* for udelay */
#include <linux/device.h>
#include <asm/io.h>
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index cdf172eda2e..4abfebdb0fc 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/of_platform.h>
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index f020de1cdd5..700e10833bf 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -54,7 +54,6 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/console.h>
-#include <linux/slab.h>
#include <linux/adb.h>
#include <linux/pmu.h>
#include <linux/bitops.h>
@@ -753,8 +752,10 @@ static void pmz_break_ctl(struct uart_port *port, int break_state)
uap->curregs[R5] = new_reg;
/* NOTE: Not subject to 'transmitter active' rule. */
- if (ZS_IS_ASLEEP(uap))
+ if (ZS_IS_ASLEEP(uap)) {
+ spin_unlock_irqrestore(&port->lock, flags);
return;
+ }
write_zsreg(uap, R5, uap->curregs[R5]);
}
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 56ee082157a..1102a39b44f 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -44,6 +44,7 @@
#include <linux/serial_core.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
struct uart_pxa_port {
struct uart_port port;
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c
index ce75e28e36e..1700b1a2fb7 100644
--- a/drivers/serial/s3c2412.c
+++ b/drivers/serial/s3c2412.c
@@ -102,6 +102,7 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = {
.name = "Samsung S3C2412 UART",
.type = PORT_S3C2412,
.fifosize = 64,
+ .has_divslot = 1,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
diff --git a/drivers/serial/s5pv210.c b/drivers/serial/s5pv210.c
new file mode 100644
index 00000000000..8dc03837617
--- /dev/null
+++ b/drivers/serial/s5pv210.c
@@ -0,0 +1,154 @@
+/* linux/drivers/serial/s5pv210.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on drivers/serial/s3c6400.c
+ *
+ * Driver for Samsung S5PV210 SoC UARTs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <plat/regs-serial.h>
+#include "samsung.h"
+
+static int s5pv210_serial_setsource(struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clk)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+ if (strcmp(clk->name, "pclk") == 0)
+ ucon &= ~S5PV210_UCON_CLKMASK;
+ else if (strcmp(clk->name, "uclk1") == 0)
+ ucon |= S5PV210_UCON_CLKMASK;
+ else {
+ printk(KERN_ERR "unknown clock source %s\n", clk->name);
+ return -EINVAL;
+ }
+
+ wr_regl(port, S3C2410_UCON, ucon);
+ return 0;
+}
+
+
+static int s5pv210_serial_getsource(struct uart_port *port,
+ struct s3c24xx_uart_clksrc *clk)
+{
+ u32 ucon = rd_regl(port, S3C2410_UCON);
+
+ clk->divisor = 1;
+
+ switch (ucon & S5PV210_UCON_CLKMASK) {
+ case S5PV210_UCON_PCLK:
+ clk->name = "pclk";
+ break;
+ case S5PV210_UCON_UCLK:
+ clk->name = "uclk1";
+ break;
+ }
+
+ return 0;
+}
+
+static int s5pv210_serial_resetport(struct uart_port *port,
+ struct s3c2410_uartcfg *cfg)
+{
+ unsigned long ucon = rd_regl(port, S3C2410_UCON);
+
+ ucon &= S5PV210_UCON_CLKMASK;
+ wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
+ wr_regl(port, S3C2410_ULCON, cfg->ulcon);
+
+ /* reset both fifos */
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
+ wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+
+ return 0;
+}
+
+#define S5PV210_UART_DEFAULT_INFO(fifo_size) \
+ .name = "Samsung S5PV210 UART0", \
+ .type = PORT_S3C6400, \
+ .fifosize = fifo_size, \
+ .has_divslot = 1, \
+ .rx_fifomask = S5PV210_UFSTAT_RXMASK, \
+ .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
+ .rx_fifofull = S5PV210_UFSTAT_RXFULL, \
+ .tx_fifofull = S5PV210_UFSTAT_TXFULL, \
+ .tx_fifomask = S5PV210_UFSTAT_TXMASK, \
+ .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \
+ .get_clksrc = s5pv210_serial_getsource, \
+ .set_clksrc = s5pv210_serial_setsource, \
+ .reset_port = s5pv210_serial_resetport
+
+static struct s3c24xx_uart_info s5p_port_fifo256 = {
+ S5PV210_UART_DEFAULT_INFO(256),
+};
+
+static struct s3c24xx_uart_info s5p_port_fifo64 = {
+ S5PV210_UART_DEFAULT_INFO(64),
+};
+
+static struct s3c24xx_uart_info s5p_port_fifo16 = {
+ S5PV210_UART_DEFAULT_INFO(16),
+};
+
+static struct s3c24xx_uart_info *s5p_uart_inf[] = {
+ [0] = &s5p_port_fifo256,
+ [1] = &s5p_port_fifo64,
+ [2] = &s5p_port_fifo16,
+ [3] = &s5p_port_fifo16,
+};
+
+/* device management */
+static int s5p_serial_probe(struct platform_device *pdev)
+{
+ return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]);
+}
+
+static struct platform_driver s5p_serial_drv = {
+ .probe = s5p_serial_probe,
+ .remove = __devexit_p(s3c24xx_serial_remove),
+ .driver = {
+ .name = "s5pv210-uart",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init s5pv210_serial_console_init(void)
+{
+ return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf);
+}
+
+console_initcall(s5pv210_serial_console_init);
+
+static int __init s5p_serial_init(void)
+{
+ return s3c24xx_serial_init(&s5p_serial_drv, *s5p_uart_inf);
+}
+
+static void __exit s5p_serial_exit(void)
+{
+ platform_driver_unregister(&s5p_serial_drv);
+}
+
+module_init(s5p_serial_init);
+module_exit(s5p_serial_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s5pv210-uart");
+MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support");
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 52e3df113ec..a9d6c5626a0 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -1271,7 +1271,7 @@ s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
unsigned long ufstat, utrstat;
if (ufcon & S3C2410_UFCON_FIFOMODE) {
- /* fifo mode - check ammount of data in fifo registers... */
+ /* fifo mode - check amount of data in fifo registers... */
ufstat = rd_regl(port, S3C2410_UFSTAT);
return (ufstat & info->tx_fifofull) ? 0 : 1;
@@ -1374,7 +1374,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
* data.
*/
-static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info)
+static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info)
{
struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
struct platform_device **platdev_ptr;
@@ -1385,7 +1385,7 @@ static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info)
platdev_ptr = s3c24xx_uart_devs;
for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) {
- s3c24xx_serial_init_port(ptr, info, *platdev_ptr);
+ s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr);
}
return 0;
@@ -1451,7 +1451,7 @@ static struct console s3c24xx_serial_console = {
};
int s3c24xx_serial_initconsole(struct platform_driver *drv,
- struct s3c24xx_uart_info *info)
+ struct s3c24xx_uart_info **info)
{
struct platform_device *dev = s3c24xx_uart_devs[0];
diff --git a/drivers/serial/samsung.h b/drivers/serial/samsung.h
index 1fb22343df4..0ac06a07d25 100644
--- a/drivers/serial/samsung.h
+++ b/drivers/serial/samsung.h
@@ -75,19 +75,24 @@ extern int s3c24xx_serial_probe(struct platform_device *dev,
extern int __devexit s3c24xx_serial_remove(struct platform_device *dev);
extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
- struct s3c24xx_uart_info *uart);
+ struct s3c24xx_uart_info **uart);
extern int s3c24xx_serial_init(struct platform_driver *drv,
struct s3c24xx_uart_info *info);
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
-#define s3c24xx_console_init(__drv, __inf) \
-static int __init s3c_serial_console_init(void) \
-{ \
- return s3c24xx_serial_initconsole(__drv, __inf); \
-} \
- \
+#define s3c24xx_console_init(__drv, __inf) \
+static int __init s3c_serial_console_init(void) \
+{ \
+ struct s3c24xx_uart_info *uinfo[CONFIG_SERIAL_SAMSUNG_UARTS]; \
+ int i; \
+ \
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) \
+ uinfo[i] = __inf; \
+ return s3c24xx_serial_initconsole(__drv, uinfo); \
+} \
+ \
console_initcall(s3c_serial_console_init)
#else
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index e91db4b3801..8cfa5b12ea7 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -105,6 +105,10 @@ struct serial_cfg_mem {
* manfid 0x0160, 0x0104
* This card appears to have a 14.7456MHz clock.
*/
+/* Generic Modem: MD55x (GPRS/EDGE) have
+ * Elan VPU16551 UART with 14.7456MHz oscillator
+ * manfid 0x015D, 0x4C45
+ */
static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
{
port->uartclk = 14745600;
@@ -196,6 +200,11 @@ static const struct serial_quirk quirks[] = {
.multi = -1,
.setup = quirk_setup_brainboxes_0104,
}, {
+ .manfid = 0x015D,
+ .prodid = 0x4C45,
+ .multi = -1,
+ .setup = quirk_setup_brainboxes_0104,
+ }, {
.manfid = MANFID_IBM,
.prodid = ~0,
.multi = -1,
@@ -745,6 +754,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+ PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index 2e71bbc04da..b1962025b1a 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -650,6 +650,7 @@ static struct console ks8695_console = {
static int __init ks8695_console_init(void)
{
+ add_preferred_console(SERIAL_KS8695_DEVNAME, 0, NULL);
register_console(&ks8695_console);
return 0;
}
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 42f3333c4ad..8eb094c1f61 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -48,6 +48,9 @@
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/list.h>
+#include <linux/dmaengine.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
#ifdef CONFIG_SUPERH
#include <asm/sh_bios.h>
@@ -84,6 +87,27 @@ struct sci_port {
struct clk *dclk;
struct list_head node;
+ struct dma_chan *chan_tx;
+ struct dma_chan *chan_rx;
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+ struct device *dma_dev;
+ enum sh_dmae_slave_chan_id slave_tx;
+ enum sh_dmae_slave_chan_id slave_rx;
+ struct dma_async_tx_descriptor *desc_tx;
+ struct dma_async_tx_descriptor *desc_rx[2];
+ dma_cookie_t cookie_tx;
+ dma_cookie_t cookie_rx[2];
+ dma_cookie_t active_rx;
+ struct scatterlist sg_tx;
+ unsigned int sg_len_tx;
+ struct scatterlist sg_rx[2];
+ size_t buf_len_rx;
+ struct sh_dmae_slave param_tx;
+ struct sh_dmae_slave param_rx;
+ struct work_struct work_tx;
+ struct work_struct work_rx;
+ struct timer_list rx_timer;
+#endif
};
struct sh_sci_priv {
@@ -269,29 +293,44 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785) || \
defined(CONFIG_CPU_SUBTYPE_SH7786)
-static inline int scif_txroom(struct uart_port *port)
+static int scif_txfill(struct uart_port *port)
+{
+ return sci_in(port, SCTFDR) & 0xff;
+}
+
+static int scif_txroom(struct uart_port *port)
{
- return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
+ return SCIF_TXROOM_MAX - scif_txfill(port);
}
-static inline int scif_rxroom(struct uart_port *port)
+static int scif_rxfill(struct uart_port *port)
{
return sci_in(port, SCRFDR) & 0xff;
}
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
-static inline int scif_txroom(struct uart_port *port)
+static int scif_txfill(struct uart_port *port)
{
- if ((port->mapbase == 0xffe00000) ||
- (port->mapbase == 0xffe08000)) {
+ if (port->mapbase == 0xffe00000 ||
+ port->mapbase == 0xffe08000)
/* SCIF0/1*/
- return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
- } else {
+ return sci_in(port, SCTFDR) & 0xff;
+ else
/* SCIF2 */
- return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
- }
+ return sci_in(port, SCFDR) >> 8;
}
-static inline int scif_rxroom(struct uart_port *port)
+static int scif_txroom(struct uart_port *port)
+{
+ if (port->mapbase == 0xffe00000 ||
+ port->mapbase == 0xffe08000)
+ /* SCIF0/1*/
+ return SCIF_TXROOM_MAX - scif_txfill(port);
+ else
+ /* SCIF2 */
+ return SCIF2_TXROOM_MAX - scif_txfill(port);
+}
+
+static int scif_rxfill(struct uart_port *port)
{
if ((port->mapbase == 0xffe00000) ||
(port->mapbase == 0xffe08000)) {
@@ -303,23 +342,33 @@ static inline int scif_rxroom(struct uart_port *port)
}
}
#else
-static inline int scif_txroom(struct uart_port *port)
+static int scif_txfill(struct uart_port *port)
+{
+ return sci_in(port, SCFDR) >> 8;
+}
+
+static int scif_txroom(struct uart_port *port)
{
- return SCIF_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
+ return SCIF_TXROOM_MAX - scif_txfill(port);
}
-static inline int scif_rxroom(struct uart_port *port)
+static int scif_rxfill(struct uart_port *port)
{
return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
}
#endif
-static inline int sci_txroom(struct uart_port *port)
+static int sci_txfill(struct uart_port *port)
+{
+ return !(sci_in(port, SCxSR) & SCI_TDRE);
+}
+
+static int sci_txroom(struct uart_port *port)
{
- return (sci_in(port, SCxSR) & SCI_TDRE) != 0;
+ return !sci_txfill(port);
}
-static inline int sci_rxroom(struct uart_port *port)
+static int sci_rxfill(struct uart_port *port)
{
return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
}
@@ -406,9 +455,9 @@ static inline void sci_receive_chars(struct uart_port *port)
while (1) {
if (port->type == PORT_SCI)
- count = sci_rxroom(port);
+ count = sci_rxfill(port);
else
- count = scif_rxroom(port);
+ count = scif_rxfill(port);
/* Don't copy more bytes than there is room for in the buffer */
count = tty_buffer_request_room(tty, count);
@@ -453,10 +502,10 @@ static inline void sci_receive_chars(struct uart_port *port)
}
/* Store data and status */
- if (status&SCxSR_FER(port)) {
+ if (status & SCxSR_FER(port)) {
flag = TTY_FRAME;
dev_notice(port->dev, "frame error\n");
- } else if (status&SCxSR_PER(port)) {
+ } else if (status & SCxSR_PER(port)) {
flag = TTY_PARITY;
dev_notice(port->dev, "parity error\n");
} else
@@ -618,13 +667,39 @@ static inline int sci_handle_breaks(struct uart_port *port)
return copied;
}
-static irqreturn_t sci_rx_interrupt(int irq, void *port)
+static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
{
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+ struct uart_port *port = ptr;
+ struct sci_port *s = to_sci_port(port);
+
+ if (s->chan_rx) {
+ unsigned long tout;
+ u16 scr = sci_in(port, SCSCR);
+ u16 ssr = sci_in(port, SCxSR);
+
+ /* Disable future Rx interrupts */
+ sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE);
+ /* Clear current interrupt */
+ sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
+ /* Calculate delay for 1.5 DMA buffers */
+ tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 /
+ port->fifosize / 2;
+ dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n",
+ tout * 1000 / HZ);
+ if (tout < 2)
+ tout = 2;
+ mod_timer(&s->rx_timer, jiffies + tout);
+
+ return IRQ_HANDLED;
+ }
+#endif
+
/* I think sci_receive_chars has to be called irrespective
* of whether the I_IXOFF is set, otherwise, how is the interrupt
* to be disabled?
*/
- sci_receive_chars(port);
+ sci_receive_chars(ptr);
return IRQ_HANDLED;
}
@@ -680,6 +755,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
{
unsigned short ssr_status, scr_status, err_enabled;
struct uart_port *port = ptr;
+ struct sci_port *s = to_sci_port(port);
irqreturn_t ret = IRQ_NONE;
ssr_status = sci_in(port, SCxSR);
@@ -687,10 +763,15 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE);
/* Tx Interrupt */
- if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE))
+ if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE) &&
+ !s->chan_tx)
ret = sci_tx_interrupt(irq, ptr);
- /* Rx Interrupt */
- if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE))
+ /*
+ * Rx Interrupt: if we're using DMA, the DMA controller clears RDF /
+ * DR flags
+ */
+ if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) &&
+ (scr_status & SCI_CTRL_FLAGS_RIE))
ret = sci_rx_interrupt(irq, ptr);
/* Error Interrupt */
if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
@@ -800,7 +881,9 @@ static void sci_free_irq(struct sci_port *port)
static unsigned int sci_tx_empty(struct uart_port *port)
{
unsigned short status = sci_in(port, SCxSR);
- return status & SCxSR_TEND(port) ? TIOCSER_TEMT : 0;
+ unsigned short in_tx_fifo = scif_txfill(port);
+
+ return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
}
static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
@@ -812,16 +895,297 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
static unsigned int sci_get_mctrl(struct uart_port *port)
{
- /* This routine is used for geting signals of: DTR, DCD, DSR, RI,
+ /* This routine is used for getting signals of: DTR, DCD, DSR, RI,
and CTS/RTS */
return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR;
}
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+static void sci_dma_tx_complete(void *arg)
+{
+ struct sci_port *s = arg;
+ struct uart_port *port = &s->port;
+ struct circ_buf *xmit = &port->state->xmit;
+ unsigned long flags;
+
+ dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ xmit->tail += s->sg_tx.length;
+ xmit->tail &= UART_XMIT_SIZE - 1;
+
+ port->icount.tx += s->sg_tx.length;
+
+ async_tx_ack(s->desc_tx);
+ s->cookie_tx = -EINVAL;
+ s->desc_tx = NULL;
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (uart_circ_chars_pending(xmit))
+ schedule_work(&s->work_tx);
+}
+
+/* Locking: called with port lock held */
+static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty,
+ size_t count)
+{
+ struct uart_port *port = &s->port;
+ int i, active, room;
+
+ room = tty_buffer_request_room(tty, count);
+
+ if (s->active_rx == s->cookie_rx[0]) {
+ active = 0;
+ } else if (s->active_rx == s->cookie_rx[1]) {
+ active = 1;
+ } else {
+ dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
+ return 0;
+ }
+
+ if (room < count)
+ dev_warn(port->dev, "Rx overrun: dropping %u bytes\n",
+ count - room);
+ if (!room)
+ return room;
+
+ for (i = 0; i < room; i++)
+ tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i],
+ TTY_NORMAL);
+
+ port->icount.rx += room;
+
+ return room;
+}
+
+static void sci_dma_rx_complete(void *arg)
+{
+ struct sci_port *s = arg;
+ struct uart_port *port = &s->port;
+ struct tty_struct *tty = port->state->port.tty;
+ unsigned long flags;
+ int count;
+
+ dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ count = sci_dma_rx_push(s, tty, s->buf_len_rx);
+
+ mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5));
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ if (count)
+ tty_flip_buffer_push(tty);
+
+ schedule_work(&s->work_rx);
+}
+
+static void sci_start_rx(struct uart_port *port);
+static void sci_start_tx(struct uart_port *port);
+
+static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
+{
+ struct dma_chan *chan = s->chan_rx;
+ struct uart_port *port = &s->port;
+
+ s->chan_rx = NULL;
+ s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
+ dma_release_channel(chan);
+ dma_free_coherent(port->dev, s->buf_len_rx * 2,
+ sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
+ if (enable_pio)
+ sci_start_rx(port);
+}
+
+static void sci_tx_dma_release(struct sci_port *s, bool enable_pio)
+{
+ struct dma_chan *chan = s->chan_tx;
+ struct uart_port *port = &s->port;
+
+ s->chan_tx = NULL;
+ s->cookie_tx = -EINVAL;
+ dma_release_channel(chan);
+ if (enable_pio)
+ sci_start_tx(port);
+}
+
+static void sci_submit_rx(struct sci_port *s)
+{
+ struct dma_chan *chan = s->chan_rx;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ struct scatterlist *sg = &s->sg_rx[i];
+ struct dma_async_tx_descriptor *desc;
+
+ desc = chan->device->device_prep_slave_sg(chan,
+ sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT);
+
+ if (desc) {
+ s->desc_rx[i] = desc;
+ desc->callback = sci_dma_rx_complete;
+ desc->callback_param = s;
+ s->cookie_rx[i] = desc->tx_submit(desc);
+ }
+
+ if (!desc || s->cookie_rx[i] < 0) {
+ if (i) {
+ async_tx_ack(s->desc_rx[0]);
+ s->cookie_rx[0] = -EINVAL;
+ }
+ if (desc) {
+ async_tx_ack(desc);
+ s->cookie_rx[i] = -EINVAL;
+ }
+ dev_warn(s->port.dev,
+ "failed to re-start DMA, using PIO\n");
+ sci_rx_dma_release(s, true);
+ return;
+ }
+ }
+
+ s->active_rx = s->cookie_rx[0];
+
+ dma_async_issue_pending(chan);
+}
+
+static void work_fn_rx(struct work_struct *work)
+{
+ struct sci_port *s = container_of(work, struct sci_port, work_rx);
+ struct uart_port *port = &s->port;
+ struct dma_async_tx_descriptor *desc;
+ int new;
+
+ if (s->active_rx == s->cookie_rx[0]) {
+ new = 0;
+ } else if (s->active_rx == s->cookie_rx[1]) {
+ new = 1;
+ } else {
+ dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
+ return;
+ }
+ desc = s->desc_rx[new];
+
+ if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) !=
+ DMA_SUCCESS) {
+ /* Handle incomplete DMA receive */
+ struct tty_struct *tty = port->state->port.tty;
+ struct dma_chan *chan = s->chan_rx;
+ struct sh_desc *sh_desc = container_of(desc, struct sh_desc,
+ async_tx);
+ unsigned long flags;
+ int count;
+
+ chan->device->device_terminate_all(chan);
+ dev_dbg(port->dev, "Read %u bytes with cookie %d\n",
+ sh_desc->partial, sh_desc->cookie);
+
+ spin_lock_irqsave(&port->lock, flags);
+ count = sci_dma_rx_push(s, tty, sh_desc->partial);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ if (count)
+ tty_flip_buffer_push(tty);
+
+ sci_submit_rx(s);
+
+ return;
+ }
+
+ s->cookie_rx[new] = desc->tx_submit(desc);
+ if (s->cookie_rx[new] < 0) {
+ dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
+ sci_rx_dma_release(s, true);
+ return;
+ }
+
+ dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__,
+ s->cookie_rx[new], new);
+
+ s->active_rx = s->cookie_rx[!new];
+}
+
+static void work_fn_tx(struct work_struct *work)
+{
+ struct sci_port *s = container_of(work, struct sci_port, work_tx);
+ struct dma_async_tx_descriptor *desc;
+ struct dma_chan *chan = s->chan_tx;
+ struct uart_port *port = &s->port;
+ struct circ_buf *xmit = &port->state->xmit;
+ struct scatterlist *sg = &s->sg_tx;
+
+ /*
+ * DMA is idle now.
+ * Port xmit buffer is already mapped, and it is one page... Just adjust
+ * offsets and lengths. Since it is a circular buffer, we have to
+ * transmit till the end, and then the rest. Take the port lock to get a
+ * consistent xmit buffer state.
+ */
+ spin_lock_irq(&port->lock);
+ sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
+ sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
+ sg->offset;
+ sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
+ CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
+ sg->dma_length = sg->length;
+ spin_unlock_irq(&port->lock);
+
+ BUG_ON(!sg->length);
+
+ desc = chan->device->device_prep_slave_sg(chan,
+ sg, s->sg_len_tx, DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ /* switch to PIO */
+ sci_tx_dma_release(s, true);
+ return;
+ }
+
+ dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE);
+
+ spin_lock_irq(&port->lock);
+ s->desc_tx = desc;
+ desc->callback = sci_dma_tx_complete;
+ desc->callback_param = s;
+ spin_unlock_irq(&port->lock);
+ s->cookie_tx = desc->tx_submit(desc);
+ if (s->cookie_tx < 0) {
+ dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n");
+ /* switch to PIO */
+ sci_tx_dma_release(s, true);
+ return;
+ }
+
+ dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__,
+ xmit->buf, xmit->tail, xmit->head, s->cookie_tx);
+
+ dma_async_issue_pending(chan);
+}
+#endif
+
static void sci_start_tx(struct uart_port *port)
{
unsigned short ctrl;
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+ struct sci_port *s = to_sci_port(port);
+
+ if (s->chan_tx) {
+ if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0)
+ schedule_work(&s->work_tx);
+
+ return;
+ }
+#endif
+
/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
ctrl = sci_in(port, SCSCR);
ctrl |= SCI_CTRL_FLAGS_TIE;
@@ -838,13 +1202,12 @@ static void sci_stop_tx(struct uart_port *port)
sci_out(port, SCSCR, ctrl);
}
-static void sci_start_rx(struct uart_port *port, unsigned int tty_start)
+static void sci_start_rx(struct uart_port *port)
{
- unsigned short ctrl;
+ unsigned short ctrl = SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE;
/* Set RIE (Receive Interrupt Enable) bit in SCSCR */
- ctrl = sci_in(port, SCSCR);
- ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE;
+ ctrl |= sci_in(port, SCSCR);
sci_out(port, SCSCR, ctrl);
}
@@ -868,16 +1231,154 @@ static void sci_break_ctl(struct uart_port *port, int break_state)
/* Nothing here yet .. */
}
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+static bool filter(struct dma_chan *chan, void *slave)
+{
+ struct sh_dmae_slave *param = slave;
+
+ dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__,
+ param->slave_id);
+
+ if (param->dma_dev == chan->device->dev) {
+ chan->private = param;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void rx_timer_fn(unsigned long arg)
+{
+ struct sci_port *s = (struct sci_port *)arg;
+ struct uart_port *port = &s->port;
+
+ u16 scr = sci_in(port, SCSCR);
+ sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE);
+ dev_dbg(port->dev, "DMA Rx timed out\n");
+ schedule_work(&s->work_rx);
+}
+
+static void sci_request_dma(struct uart_port *port)
+{
+ struct sci_port *s = to_sci_port(port);
+ struct sh_dmae_slave *param;
+ struct dma_chan *chan;
+ dma_cap_mask_t mask;
+ int nent;
+
+ dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__,
+ port->line, s->dma_dev);
+
+ if (!s->dma_dev)
+ return;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ param = &s->param_tx;
+
+ /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */
+ param->slave_id = s->slave_tx;
+ param->dma_dev = s->dma_dev;
+
+ s->cookie_tx = -EINVAL;
+ chan = dma_request_channel(mask, filter, param);
+ dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan);
+ if (chan) {
+ s->chan_tx = chan;
+ sg_init_table(&s->sg_tx, 1);
+ /* UART circular tx buffer is an aligned page. */
+ BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK);
+ sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
+ UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK);
+ nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
+ if (!nent)
+ sci_tx_dma_release(s, false);
+ else
+ dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__,
+ sg_dma_len(&s->sg_tx),
+ port->state->xmit.buf, sg_dma_address(&s->sg_tx));
+
+ s->sg_len_tx = nent;
+
+ INIT_WORK(&s->work_tx, work_fn_tx);
+ }
+
+ param = &s->param_rx;
+
+ /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */
+ param->slave_id = s->slave_rx;
+ param->dma_dev = s->dma_dev;
+
+ chan = dma_request_channel(mask, filter, param);
+ dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
+ if (chan) {
+ dma_addr_t dma[2];
+ void *buf[2];
+ int i;
+
+ s->chan_rx = chan;
+
+ s->buf_len_rx = 2 * max(16, (int)port->fifosize);
+ buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2,
+ &dma[0], GFP_KERNEL);
+
+ if (!buf[0]) {
+ dev_warn(port->dev,
+ "failed to allocate dma buffer, using PIO\n");
+ sci_rx_dma_release(s, true);
+ return;
+ }
+
+ buf[1] = buf[0] + s->buf_len_rx;
+ dma[1] = dma[0] + s->buf_len_rx;
+
+ for (i = 0; i < 2; i++) {
+ struct scatterlist *sg = &s->sg_rx[i];
+
+ sg_init_table(sg, 1);
+ sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
+ (int)buf[i] & ~PAGE_MASK);
+ sg->dma_address = dma[i];
+ sg->dma_length = sg->length;
+ }
+
+ INIT_WORK(&s->work_rx, work_fn_rx);
+ setup_timer(&s->rx_timer, rx_timer_fn, (unsigned long)s);
+
+ sci_submit_rx(s);
+ }
+}
+
+static void sci_free_dma(struct uart_port *port)
+{
+ struct sci_port *s = to_sci_port(port);
+
+ if (!s->dma_dev)
+ return;
+
+ if (s->chan_tx)
+ sci_tx_dma_release(s, false);
+ if (s->chan_rx)
+ sci_rx_dma_release(s, false);
+}
+#endif
+
static int sci_startup(struct uart_port *port)
{
struct sci_port *s = to_sci_port(port);
+ dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
if (s->enable)
s->enable(port);
sci_request_irq(s);
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+ sci_request_dma(port);
+#endif
sci_start_tx(port);
- sci_start_rx(port, 1);
+ sci_start_rx(port);
return 0;
}
@@ -886,8 +1387,13 @@ static void sci_shutdown(struct uart_port *port)
{
struct sci_port *s = to_sci_port(port);
+ dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
sci_stop_rx(port);
sci_stop_tx(port);
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+ sci_free_dma(port);
+#endif
sci_free_irq(s);
if (s->disable)
@@ -937,6 +1443,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
sci_out(port, SCSMR, smr_val);
+ dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
+ SCSCR_INIT(port));
+
if (t > 0) {
if (t >= 256) {
sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
@@ -954,7 +1463,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
sci_out(port, SCSCR, SCSCR_INIT(port));
if ((termios->c_cflag & CREAD) != 0)
- sci_start_rx(port, 0);
+ sci_start_rx(port);
}
static const char *sci_type(struct uart_port *port)
@@ -1049,19 +1558,21 @@ static void __devinit sci_init_single(struct platform_device *dev,
unsigned int index,
struct plat_sci_port *p)
{
- sci_port->port.ops = &sci_uart_ops;
- sci_port->port.iotype = UPIO_MEM;
- sci_port->port.line = index;
+ struct uart_port *port = &sci_port->port;
+
+ port->ops = &sci_uart_ops;
+ port->iotype = UPIO_MEM;
+ port->line = index;
switch (p->type) {
case PORT_SCIFA:
- sci_port->port.fifosize = 64;
+ port->fifosize = 64;
break;
case PORT_SCIF:
- sci_port->port.fifosize = 16;
+ port->fifosize = 16;
break;
default:
- sci_port->port.fifosize = 1;
+ port->fifosize = 1;
break;
}
@@ -1070,19 +1581,28 @@ static void __devinit sci_init_single(struct platform_device *dev,
sci_port->dclk = clk_get(&dev->dev, "peripheral_clk");
sci_port->enable = sci_clk_enable;
sci_port->disable = sci_clk_disable;
- sci_port->port.dev = &dev->dev;
+ port->dev = &dev->dev;
}
sci_port->break_timer.data = (unsigned long)sci_port;
sci_port->break_timer.function = sci_break_timer;
init_timer(&sci_port->break_timer);
- sci_port->port.mapbase = p->mapbase;
- sci_port->port.membase = p->membase;
+ port->mapbase = p->mapbase;
+ port->membase = p->membase;
- sci_port->port.irq = p->irqs[SCIx_TXI_IRQ];
- sci_port->port.flags = p->flags;
- sci_port->type = sci_port->port.type = p->type;
+ port->irq = p->irqs[SCIx_TXI_IRQ];
+ port->flags = p->flags;
+ sci_port->type = port->type = p->type;
+
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+ sci_port->dma_dev = p->dma_dev;
+ sci_port->slave_tx = p->dma_slave_tx;
+ sci_port->slave_rx = p->dma_slave_rx;
+
+ dev_dbg(port->dev, "%s: DMA device %p, tx %d, rx %d\n", __func__,
+ p->dma_dev, p->dma_slave_tx, p->dma_slave_rx);
+#endif
memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
}
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index f7d2589926d..f70c49f915f 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -30,7 +30,10 @@
*/
# define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0
#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
+ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH7367) || \
+ defined(CONFIG_ARCH_SH7377) || \
+ defined(CONFIG_ARCH_SH7372)
# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
# define PORT_PTCR 0xA405011EUL
# define PORT_PVCR 0xA4050122UL
@@ -93,7 +96,9 @@
# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
# define SCIF_ORER 0x0001 /* overrun error bit */
-# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCSCR_INIT(port) ((port)->type == PORT_SCIFA ? \
+ 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \
+ 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ )
#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
# define SCSPTR2 0xffe80020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
@@ -196,6 +201,8 @@
defined(CONFIG_CPU_SUBTYPE_SH7786) || \
defined(CONFIG_CPU_SUBTYPE_SHX3)
#define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define SCI_CTRL_FLAGS_REIE ((port)->type == PORT_SCIFA ? 0 : 8)
#else
#define SCI_CTRL_FLAGS_REIE 0
#endif
@@ -228,7 +235,10 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
+ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH7367) || \
+ defined(CONFIG_ARCH_SH7377) || \
+ defined(CONFIG_ARCH_SH7372)
# define SCIF_ORER 0x0200
# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
# define SCIF_RFDC_MASK 0x007f
@@ -261,7 +271,10 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
+ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH7367) || \
+ defined(CONFIG_ARCH_SH7377) || \
+ defined(CONFIG_ARCH_SH7372)
# define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc)
# define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73)
# define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf)
@@ -356,7 +369,10 @@
SCI_OUT(sci_size, sci_offset, value); \
}
-#ifdef CONFIG_CPU_SH3
+#if defined(CONFIG_CPU_SH3) || \
+ defined(CONFIG_ARCH_SH7367) || \
+ defined(CONFIG_ARCH_SH7377) || \
+ defined(CONFIG_ARCH_SH7372)
#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
@@ -366,7 +382,10 @@
CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
+ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH7367) || \
+ defined(CONFIG_ARCH_SH7377) || \
+ defined(CONFIG_ARCH_SH7372)
#define SCIF_FNS(name, scif_offset, scif_size) \
CPU_SCIF_FNS(name, scif_offset, scif_size)
#else
@@ -401,7 +420,10 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
+ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH7367) || \
+ defined(CONFIG_ARCH_SH7377) || \
+ defined(CONFIG_ARCH_SH7372)
SCIF_FNS(SCSMR, 0x00, 16)
SCIF_FNS(SCBRR, 0x04, 8)
@@ -413,7 +435,7 @@ SCIF_FNS(SCFCR, 0x18, 16)
SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCxTDR, 0x20, 8)
SCIF_FNS(SCxRDR, 0x24, 8)
-SCIF_FNS(SCLSR, 0x24, 16)
+SCIF_FNS(SCLSR, 0x00, 0)
#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
defined(CONFIG_CPU_SUBTYPE_SH7724)
SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
@@ -583,7 +605,10 @@ static inline int sci_rxd_in(struct uart_port *port)
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
+ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_ARCH_SH7367) || \
+ defined(CONFIG_ARCH_SH7377) || \
+ defined(CONFIG_ARCH_SH7372)
#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
defined(CONFIG_CPU_SUBTYPE_SH7724)
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index d514e28d075..d2e0321049e 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -474,7 +474,7 @@ static void sunsab_stop_rx(struct uart_port *port)
{
struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
- up->interrupt_mask0 |= SAB82532_ISR0_TCD;
+ up->interrupt_mask0 |= SAB82532_IMR0_TCD;
writeb(up->interrupt_mask1, &up->regs->w.imr0);
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 170d3d68c8f..01f7731e59b 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -29,6 +29,7 @@
#include <linux/serial.h>
#include <linux/sysrq.h>
#include <linux/console.h>
+#include <linux/slab.h>
#ifdef CONFIG_SERIO
#include <linux/serio.h>
#endif
@@ -1453,8 +1454,10 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) {
err = sunsu_kbd_ms_init(up);
if (err) {
+ of_iounmap(&op->resource[0],
+ up->port.membase, up->reg_size);
kfree(up);
- goto out_unmap;
+ return err;
}
dev_set_drvdata(&op->dev, up);
diff --git a/drivers/serial/timbuart.c b/drivers/serial/timbuart.c
index 7bf10264a6a..786ba85c170 100644
--- a/drivers/serial/timbuart.c
+++ b/drivers/serial/timbuart.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
#include "timbuart.h"
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index ab2ab3c8183..f0a6c61b17f 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -19,7 +19,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <asm/io.h>
-#if defined(CONFIG_OF)
+#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE))
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
@@ -581,7 +581,7 @@ static struct platform_driver ulite_platform_driver = {
/* ---------------------------------------------------------------------
* OF bus bindings
*/
-#if defined(CONFIG_OF)
+#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE))
static int __devinit
ulite_of_probe(struct of_device *op, const struct of_device_id *match)
{
@@ -631,11 +631,11 @@ static inline void __exit ulite_of_unregister(void)
{
of_unregister_platform_driver(&ulite_of_driver);
}
-#else /* CONFIG_OF */
-/* CONFIG_OF not enabled; do nothing helpers */
+#else /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */
+/* Appropriate config not enabled; do nothing helpers */
static inline int __init ulite_of_register(void) { return 0; }
static inline void __exit ulite_of_unregister(void) { }
-#endif /* CONFIG_OF */
+#endif /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */
/* ---------------------------------------------------------------------
* Module setup/teardown
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 465f2fae102..074904912f6 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/serial.h>
+#include <linux/slab.h>
#include <linux/serial_core.h>
#include <linux/io.h>
#include <linux/of_platform.h>
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 3a5a17db947..94ad6bd86a0 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -2,7 +2,7 @@
* Shared interrupt handling code for IPR and INTC2 types of IRQs.
*
* Copyright (C) 2007, 2008 Magnus Damm
- * Copyright (C) 2009 Paul Mundt
+ * Copyright (C) 2009, 2010 Paul Mundt
*
* Based on intc2.c and ipr.c
*
@@ -20,12 +20,14 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/sh_intc.h>
#include <linux/sysdev.h>
#include <linux/list.h>
#include <linux/topology.h>
#include <linux/bitmap.h>
+#include <linux/cpumask.h>
#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -234,6 +236,10 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle)
unsigned int cpu;
for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
+#ifdef CONFIG_SMP
+ if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
+ continue;
+#endif
addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
[_INTC_FN(handle)], irq);
@@ -253,6 +259,10 @@ static void intc_disable(unsigned int irq)
unsigned int cpu;
for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
+#ifdef CONFIG_SMP
+ if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
+ continue;
+#endif
addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\
[_INTC_FN(handle)], irq);
@@ -301,6 +311,23 @@ static int intc_set_wake(unsigned int irq, unsigned int on)
return 0; /* allow wakeup, but setup hardware in intc_suspend() */
}
+#ifdef CONFIG_SMP
+/*
+ * This is held with the irq desc lock held, so we don't require any
+ * additional locking here at the intc desc level. The affinity mask is
+ * later tested in the enable/disable paths.
+ */
+static int intc_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+ if (!cpumask_intersects(cpumask, cpu_online_mask))
+ return -1;
+
+ cpumask_copy(irq_to_desc(irq)->affinity, cpumask);
+
+ return 0;
+}
+#endif
+
static void intc_mask_ack(unsigned int irq)
{
struct intc_desc_int *d = get_intc_desc(irq);
@@ -762,6 +789,10 @@ static void __init intc_register_irq(struct intc_desc *desc,
if (desc->hw.ack_regs)
ack_handle[irq] = intc_ack_data(desc, d, enum_id);
+
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
+#endif
}
static unsigned int __init save_reg(struct intc_desc_int *d,
@@ -843,6 +874,9 @@ void __init register_intc_controller(struct intc_desc *desc)
d->chip.shutdown = intc_disable;
d->chip.set_type = intc_set_sense;
d->chip.set_wake = intc_set_wake;
+#ifdef CONFIG_SMP
+ d->chip.set_affinity = intc_set_affinity;
+#endif
if (hw->ack_regs) {
for (i = 0; i < hw->nr_ack_regs; i++)
@@ -1024,8 +1058,12 @@ unsigned int create_irq_nr(unsigned int irq_want, int node)
out_unlock:
spin_unlock_irqrestore(&vector_lock, flags);
- if (irq > 0)
+ if (irq > 0) {
dynamic_irq_init(irq);
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
+#endif
+ }
return irq;
}
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
index 66802a4390c..b3b33fa26ac 100644
--- a/drivers/sn/ioc3.c
+++ b/drivers/sn/ioc3.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/ioc3.h>
#include <linux/rwsem.h>
+#include <linux/slab.h>
#define IOC3_PCI_SIZE 0x100000
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index 9aeb6811310..e9aeee16d92 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -44,6 +44,7 @@
#include <linux/amba/bus.h>
#include <linux/amba/pl022.h>
#include <linux/io.h>
+#include <linux/slab.h>
/*
* This macro is used to define some register default values.
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index d21c24eaf0a..c4e04428992 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -18,6 +18,7 @@
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <mach/board.h>
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c
index ba8ac4f599d..3c9ade69643 100644
--- a/drivers/spi/au1550_spi.c
+++ b/drivers/spi/au1550_spi.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/platform_device.h>
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 225ab60b02c..95afb6b7739 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -27,6 +27,7 @@
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
+#include <linux/slab.h>
#include <mach/spi.h>
#include <mach/edma.h>
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
index 8ed38f1d6c1..d256cb00604 100644
--- a/drivers/spi/dw_spi.c
+++ b/drivers/spi/dw_spi.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/spi/dw_spi.h>
#include <linux/spi/spi.h>
diff --git a/drivers/spi/dw_spi_mmio.c b/drivers/spi/dw_spi_mmio.c
index e35b45ac517..db35bd9c1b2 100644
--- a/drivers/spi/dw_spi_mmio.c
+++ b/drivers/spi/dw_spi_mmio.c
@@ -11,6 +11,7 @@
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/spi/dw_spi.h>
#include <linux/spi/spi.h>
diff --git a/drivers/spi/dw_spi_pci.c b/drivers/spi/dw_spi_pci.c
index 1f0735f9cc7..1f52755dc87 100644
--- a/drivers/spi/dw_spi_pci.c
+++ b/drivers/spi/dw_spi_pci.c
@@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/spi/dw_spi.h>
#include <linux/spi/spi.h>
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 04747868d6c..77d4cc88ede 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/fsl_devices.h>
+#include <linux/slab.h>
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c
index 6eab46537a0..cd68f1ce5cc 100644
--- a/drivers/spi/mpc52xx_spi.c
+++ b/drivers/spi/mpc52xx_spi.c
@@ -21,6 +21,7 @@
#include <linux/of_spi.h>
#include <linux/io.h>
#include <linux/of_gpio.h>
+#include <linux/slab.h>
#include <asm/time.h>
#include <asm/mpc52xx.h>
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 715c518b1b6..e0de0d0eede 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -32,6 +32,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
@@ -203,6 +204,7 @@ static inline void mcspi_write_chconf0(const struct spi_device *spi, u32 val)
cs->chconf0 = val;
mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, val);
+ mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0);
}
static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
@@ -531,7 +533,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
goto out;
}
#ifdef VERBOSE
- dev_dbg(&spi->dev, "write-%d %04x\n",
+ dev_dbg(&spi->dev, "write-%d %08x\n",
word_len, *tx);
#endif
__raw_writel(*tx++, tx_reg);
@@ -549,7 +551,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
mcspi_write_chconf0(spi, l);
*rx++ = __raw_readl(rx_reg);
#ifdef VERBOSE
- dev_dbg(&spi->dev, "read-%d %04x\n",
+ dev_dbg(&spi->dev, "read-%d %08x\n",
word_len, *(rx - 1));
#endif
}
@@ -578,6 +580,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
struct spi_master *spi_cntrl;
u32 l = 0, div = 0;
u8 word_len = spi->bits_per_word;
+ u32 speed_hz = spi->max_speed_hz;
mcspi = spi_master_get_devdata(spi->master);
spi_cntrl = mcspi->master;
@@ -587,9 +590,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
cs->word_len = word_len;
- if (spi->max_speed_hz) {
+ if (t && t->speed_hz)
+ speed_hz = t->speed_hz;
+
+ if (speed_hz) {
while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div))
- > spi->max_speed_hz)
+ > speed_hz)
div++;
} else
div = 15;
@@ -751,11 +757,13 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)
mcspi = spi_master_get_devdata(spi->master);
mcspi_dma = &mcspi->dma_channels[spi->chip_select];
- /* Unlink controller state from context save list */
- cs = spi->controller_state;
- list_del(&cs->node);
+ if (spi->controller_state) {
+ /* Unlink controller state from context save list */
+ cs = spi->controller_state;
+ list_del(&cs->node);
- kfree(spi->controller_state);
+ kfree(spi->controller_state);
+ }
if (mcspi_dma->dma_rx_channel != -1) {
omap_free_dma(mcspi_dma->dma_rx_channel);
diff --git a/drivers/spi/omap_spi_100k.c b/drivers/spi/omap_spi_100k.c
index 5355d90d1be..24668b30a52 100644
--- a/drivers/spi/omap_spi_100k.c
+++ b/drivers/spi/omap_spi_100k.c
@@ -33,6 +33,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index 6c3a8557db2..160d3266205 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -41,6 +41,7 @@
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index c2f707e5ce7..36828358a4d 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -29,6 +29,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index b76f2468a84..b3a1f9259b6 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/cache.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
@@ -40,7 +41,7 @@ static void spidev_release(struct device *dev)
spi->master->cleanup(spi);
spi_master_put(spi->master);
- kfree(dev);
+ kfree(spi);
}
static ssize_t
@@ -256,6 +257,7 @@ int spi_add_device(struct spi_device *spi)
{
static DEFINE_MUTEX(spi_add_lock);
struct device *dev = spi->master->dev.parent;
+ struct device *d;
int status;
/* Chipselects are numbered 0..max; validate. */
@@ -277,10 +279,11 @@ int spi_add_device(struct spi_device *spi)
*/
mutex_lock(&spi_add_lock);
- if (bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev))
- != NULL) {
+ d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
+ if (d != NULL) {
dev_err(dev, "chipselect %d already in use\n",
spi->chip_select);
+ put_device(d);
status = -EBUSY;
goto done;
}
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 1d41058bbab..10a6dc3d37a 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index f1db395dd88..5265330a528 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 0ddbbe45e83..7972e907747 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/types.h>
diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c
index 4f0cc9d457e..14d05231650 100644
--- a/drivers/spi/spi_mpc8xxx.c
+++ b/drivers/spi/spi_mpc8xxx.c
@@ -39,6 +39,7 @@
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/of_spi.h>
+#include <linux/slab.h>
#include <sysdev/fsl_soc.h>
#include <asm/cpm.h>
diff --git a/drivers/spi/spi_nuc900.c b/drivers/spi/spi_nuc900.c
index b319f9bf9b9..dff63be0d0a 100644
--- a/drivers/spi/spi_nuc900.c
+++ b/drivers/spi/spi_nuc900.c
@@ -21,6 +21,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c
index 6d8d4026a07..7cb5ff37f6e 100644
--- a/drivers/spi/spi_ppc4xx.c
+++ b/drivers/spi/spi_ppc4xx.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/of_platform.h>
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index c010733877a..151a95e4065 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -21,6 +21,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
@@ -275,7 +276,7 @@ static inline u32 ack_bit(unsigned int irq)
* Claim the FIQ handler (only one can be active at any one time) and
* then setup the correct transfer code for this transfer.
*
- * This call updates all the necessary state information if sucessful,
+ * This call updates all the necessary state information if successful,
* so the caller does not need to do anything more than start the transfer
* as normal, since the IRQ will have been re-routed to the FIQ handler.
*/
diff --git a/drivers/spi/tle62x0.c b/drivers/spi/tle62x0.c
index bf9540f5fb9..a3938958147 100644
--- a/drivers/spi/tle62x0.c
+++ b/drivers/spi/tle62x0.c
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/tle62x0.h>
diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c
index ed34a8d419c..748d33a76d2 100644
--- a/drivers/spi/xilinx_spi_of.c
+++ b/drivers/spi/xilinx_spi_of.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
diff --git a/drivers/ssb/driver_gige.c b/drivers/ssb/driver_gige.c
index 172f90407b9..5ba92a2719a 100644
--- a/drivers/ssb/driver_gige.c
+++ b/drivers/ssb/driver_gige.c
@@ -12,6 +12,7 @@
#include <linux/ssb/ssb_driver_gige.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
+#include <linux/slab.h>
/*
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index f1dcd7969a5..0e8d3522461 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore_controller = {
.pci_ops = &ssb_pcicore_pciops,
.io_resource = &ssb_pcicore_io_resource,
.mem_resource = &ssb_pcicore_mem_resource,
- .mem_offset = 0x24000000,
};
-static u32 ssb_pcicore_pcibus_iobase = 0x100;
-static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
-
/* This function is called when doing a pci_enable_device().
* We must first check if the device is a device on the PCI-core bridge. */
int ssb_pcicore_plat_dev_init(struct pci_dev *d)
{
- struct resource *res;
- int pos, size;
- u32 *base;
-
if (d->bus->ops != &ssb_pcicore_pciops) {
/* This is not a device on the PCI-core bridge. */
return -ENODEV;
@@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d)
ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
pci_name(d));
- /* Fix up resource bases */
- for (pos = 0; pos < 6; pos++) {
- res = &d->resource[pos];
- if (res->flags & IORESOURCE_IO)
- base = &ssb_pcicore_pcibus_iobase;
- else
- base = &ssb_pcicore_pcibus_membase;
- res->flags |= IORESOURCE_PCI_FIXED;
- if (res->end) {
- size = res->end - res->start + 1;
- if (*base & (size - 1))
- *base = (*base + size) & ~(size - 1);
- res->start = *base;
- res->end = res->start + size - 1;
- *base += size;
- pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
- }
- /* Fix up PCI bridge BAR0 only */
- if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
- break;
- }
/* Fix up interrupt lines */
d->irq = ssb_mips_irq(extpci_core->dev) + 2;
pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 03dfd27c4bf..80ff7d9e60d 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -18,6 +18,7 @@
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 9e50896233a..a8dbb06623c 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -17,6 +17,7 @@
#include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_regs.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c
index 26737a010c6..6536a041d90 100644
--- a/drivers/ssb/pcihost_wrapper.c
+++ b/drivers/ssb/pcihost_wrapper.c
@@ -12,6 +12,7 @@
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/ssb/ssb.h>
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
index d0e6762fec5..f2f920fef10 100644
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -14,6 +14,7 @@
#include "ssb_private.h"
#include <linux/ctype.h>
+#include <linux/slab.h>
static const struct ssb_sprom *fallback_sprom;
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index fc2e963e65e..7696a664f8a 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -71,8 +71,6 @@ source "drivers/staging/asus_oled/Kconfig"
source "drivers/staging/panel/Kconfig"
-source "drivers/staging/altpciechdma/Kconfig"
-
source "drivers/staging/rtl8187se/Kconfig"
source "drivers/staging/rtl8192su/Kconfig"
@@ -81,20 +79,14 @@ source "drivers/staging/rtl8192u/Kconfig"
source "drivers/staging/rtl8192e/Kconfig"
-source "drivers/staging/mimio/Kconfig"
-
source "drivers/staging/frontier/Kconfig"
source "drivers/staging/dream/Kconfig"
source "drivers/staging/pohmelfs/Kconfig"
-source "drivers/staging/b3dfg/Kconfig"
-
source "drivers/staging/phison/Kconfig"
-source "drivers/staging/p9auth/Kconfig"
-
source "drivers/staging/line6/Kconfig"
source "drivers/gpu/drm/vmwgfx/Kconfig"
@@ -117,7 +109,7 @@ source "drivers/staging/hv/Kconfig"
source "drivers/staging/vme/Kconfig"
-source "drivers/staging/rar/Kconfig"
+source "drivers/staging/rar_register/Kconfig"
source "drivers/staging/sep/Kconfig"
@@ -143,5 +135,9 @@ source "drivers/staging/netwave/Kconfig"
source "drivers/staging/sm7xx/Kconfig"
+source "drivers/staging/dt3155/Kconfig"
+
+source "drivers/staging/crystalhd/Kconfig"
+
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index b5e67b889f6..ea2e70e2fed 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -18,18 +18,14 @@ obj-$(CONFIG_RT2870) += rt2870/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/
-obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/
obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192SU) += rtl8192su/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
-obj-$(CONFIG_INPUT_MIMIO) += mimio/
obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_DREAM) += dream/
obj-$(CONFIG_POHMELFS) += pohmelfs/
-obj-$(CONFIG_B3DFG) += b3dfg/
obj-$(CONFIG_IDE_PHISON) += phison/
-obj-$(CONFIG_PLAN9AUTH) += p9auth/
obj-$(CONFIG_LINE6_USB) += line6/
obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/
@@ -39,7 +35,7 @@ obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_FB_UDL) += udlfb/
obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_VME_BUS) += vme/
-obj-$(CONFIG_RAR_REGISTER) += rar/
+obj-$(CONFIG_RAR_REGISTER) += rar_register/
obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_RAMZSWAP) += ramzswap/
@@ -53,3 +49,5 @@ obj-$(CONFIG_WAVELAN) += wavelan/
obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/
obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/
obj-$(CONFIG_FB_SM7XX) += sm7xx/
+obj-$(CONFIG_DT3155) += dt3155/
+obj-$(CONFIG_CRYSTALHD) += crystalhd/
diff --git a/drivers/staging/altpciechdma/Kconfig b/drivers/staging/altpciechdma/Kconfig
deleted file mode 100644
index 0f4bf92cbbf..00000000000
--- a/drivers/staging/altpciechdma/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config ALTERA_PCIE_CHDMA
- tristate "Altera PCI Express Chaining DMA driver"
- depends on PCI
- default N
- ---help---
- A reference driver that exercises the Chaining DMA logic reference
- design generated along the Altera FPGA PCI Express soft or hard core,
- only if instantiated using the MegaWizard, not the SOPC builder, of
- Quartus 8.1.
-
diff --git a/drivers/staging/altpciechdma/Makefile b/drivers/staging/altpciechdma/Makefile
deleted file mode 100644
index c08c8437f4d..00000000000
--- a/drivers/staging/altpciechdma/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma.o
-
diff --git a/drivers/staging/altpciechdma/TODO b/drivers/staging/altpciechdma/TODO
deleted file mode 100644
index 12c945fd61e..00000000000
--- a/drivers/staging/altpciechdma/TODO
+++ /dev/null
@@ -1,15 +0,0 @@
-DONE:
- - functionality similar to logic testbench
-
-TODO:
- - checkpatch.pl cleanups.
- - keep state of DMA engines.
- - keep data structure that keeps state of each transfer.
- - interrupt handler should iterate over outstanding descriptor tables.
- - complete userspace cdev to read/write using the DMA engines.
- - split off the DMA support functions in a module, re-usable by custom
- drivers.
-
-Please coordinate work with, and send patches to
-Leon Woestenberg <leon@sidebranch.com>
-
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
deleted file mode 100644
index 2f07dd4563a..00000000000
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ /dev/null
@@ -1,1182 +0,0 @@
-/**
- * Driver for Altera PCIe core chaining DMA reference design.
- *
- * Copyright (C) 2008 Leon Woestenberg <leon.woestenberg@axon.tv>
- * Copyright (C) 2008 Nickolas Heppermann <heppermannwdt@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * Rationale: This driver exercises the chaining DMA read and write engine
- * in the reference design. It is meant as a complementary reference
- * driver that can be used for testing early designs as well as a basis to
- * write your custom driver.
- *
- * Status: Test results from Leon Woestenberg <leon.woestenberg@axon.tv>:
- *
- * Sendero Board w/ Cyclone II EP2C35F672C6N, PX1011A PCIe x1 PHY on a
- * Dell Precision 370 PC, x86, kernel 2.6.20 from Ubuntu 7.04.
- *
- * Sendero Board w/ Cyclone II EP2C35F672C6N, PX1011A PCIe x1 PHY on a
- * Freescale MPC8313E-RDB board, PowerPC, 2.6.24 w/ Freescale patches.
- *
- * Driver tests passed with PCIe Compiler 8.1. With PCIe 8.0 the DMA
- * loopback test had reproducable compare errors. I assume a change
- * in the compiler or reference design, but could not find evidence nor
- * documentation on a change or fix in that direction.
- *
- * The reference design does not have readable locations and thus a
- * dummy read, used to flush PCI posted writes, cannot be performed.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/cdev.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-
-
-/* by default do not build the character device interface */
-/* XXX It is non-functional yet */
-#ifndef ALTPCIECHDMA_CDEV
-# define ALTPCIECHDMA_CDEV 0
-#endif
-
-/* build the character device interface? */
-#if ALTPCIECHDMA_CDEV
-# define MAX_CHDMA_SIZE (8 * 1024 * 1024)
-# include "mapper_user_to_sg.h"
-#endif
-
-/** driver name, mimicks Altera naming of the reference design */
-#define DRV_NAME "altpciechdma"
-/** number of BARs on the device */
-#define APE_BAR_NUM (6)
-/** BAR number where the RCSLAVE memory sits */
-#define APE_BAR_RCSLAVE (0)
-/** BAR number where the Descriptor Header sits */
-#define APE_BAR_HEADER (2)
-
-/** maximum size in bytes of the descriptor table, chdma logic limit */
-#define APE_CHDMA_TABLE_SIZE (4096)
-/* single transfer must not exceed 255 table entries. worst case this can be
- * achieved by 255 scattered pages, with only a single byte in the head and
- * tail pages. 253 * PAGE_SIZE is a safe upper bound for the transfer size.
- */
-#define APE_CHDMA_MAX_TRANSFER_LEN (253 * PAGE_SIZE)
-
-/**
- * Specifies those BARs to be mapped and the length of each mapping.
- *
- * Zero (0) means do not map, otherwise specifies the BAR lengths to be mapped.
- * If the actual BAR length is less, this is considered an error; then
- * reconfigure your PCIe core.
- *
- * @see ug_pci_express 8.0, table 7-2 at page 7-13.
- */
-static const unsigned long bar_min_len[APE_BAR_NUM] =
- { 32768, 0, 256, 0, 32768, 0 };
-
-/**
- * Descriptor Header, controls the DMA read engine or write engine.
- *
- * The descriptor header is the main data structure for starting DMA transfers.
- *
- * It sits in End Point (FPGA) memory BAR[2] for 32-bit or BAR[3:2] for 64-bit.
- * It references a descriptor table which exists in Root Complex (PC) memory.
- * Writing the rclast field starts the DMA operation, thus all other structures
- * and fields must be setup before doing so.
- *
- * @see ug_pci_express 8.0, tables 7-3, 7-4 and 7-5 at page 7-14.
- * @note This header must be written in four 32-bit (PCI DWORD) writes.
- */
-struct ape_chdma_header {
- /**
- * w0 consists of two 16-bit fields:
- * lsb u16 number; number of descriptors in ape_chdma_table
- * msb u16 control; global control flags
- */
- u32 w0;
- /* bus address to ape_chdma_table in Root Complex memory */
- u32 bdt_addr_h;
- u32 bdt_addr_l;
- /**
- * w3 consists of two 16-bit fields:
- * - lsb u16 rclast; last descriptor number available in Root Complex
- * - zero (0) means the first descriptor is ready,
- * - one (1) means two descriptors are ready, etc.
- * - msb u16 reserved;
- *
- * @note writing to this memory location starts the DMA operation!
- */
- u32 w3;
-} __attribute__ ((packed));
-
-/**
- * Descriptor Entry, describing a (non-scattered) single memory block transfer.
- *
- * There is one descriptor for each memory block involved in the transfer, a
- * block being a contiguous address range on the bus.
- *
- * Multiple descriptors are chained by means of the ape_chdma_table data
- * structure.
- *
- * @see ug_pci_express 8.0, tables 7-6, 7-7 and 7-8 at page 7-14 and page 7-15.
- */
-struct ape_chdma_desc {
- /**
- * w0 consists of two 16-bit fields:
- * number of DWORDS to transfer
- * - lsb u16 length;
- * global control
- * - msb u16 control;
- */
- u32 w0;
- /* address of memory in the End Point */
- u32 ep_addr;
- /* bus address of source or destination memory in the Root Complex */
- u32 rc_addr_h;
- u32 rc_addr_l;
-} __attribute__ ((packed));
-
-/**
- * Descriptor Table, an array of descriptors describing a chained transfer.
- *
- * An array of descriptors, preceded by workspace for the End Point.
- * It exists in Root Complex memory.
- *
- * The End Point can update its last completed descriptor number in the
- * eplast field if requested by setting the EPLAST_ENA bit either
- * globally in the header's or locally in any descriptor's control field.
- *
- * @note this structure may not exceed 4096 bytes. This results in a
- * maximum of 4096 / (4 * 4) - 1 = 255 descriptors per chained transfer.
- *
- * @see ug_pci_express 8.0, tables 7-9, 7-10 and 7-11 at page 7-17 and page 7-18.
- */
-struct ape_chdma_table {
- /* workspace 0x00-0x0b, reserved */
- u32 reserved1[3];
- /* workspace 0x0c-0x0f, last descriptor handled by End Point */
- u32 w3;
- /* the actual array of descriptors
- * 0x10-0x1f, 0x20-0x2f, ... 0xff0-0xfff (255 entries)
- */
- struct ape_chdma_desc desc[255];
-} __attribute__ ((packed));
-
-/**
- * Altera PCI Express ('ape') board specific book keeping data
- *
- * Keeps state of the PCIe core and the Chaining DMA controller
- * application.
- */
-struct ape_dev {
- /** the kernel pci device data structure provided by probe() */
- struct pci_dev *pci_dev;
- /**
- * kernel virtual address of the mapped BAR memory and IO regions of
- * the End Point. Used by map_bars()/unmap_bars().
- */
- void * __iomem bar[APE_BAR_NUM];
- /** kernel virtual address for Descriptor Table in Root Complex memory */
- struct ape_chdma_table *table_virt;
- /**
- * bus address for the Descriptor Table in Root Complex memory, in
- * CPU-native endianess
- */
- dma_addr_t table_bus;
- /* if the device regions could not be allocated, assume and remember it
- * is in use by another driver; this driver must not disable the device.
- */
- int in_use;
- /* whether this driver enabled msi for the device */
- int msi_enabled;
- /* whether this driver could obtain the regions */
- int got_regions;
- /* irq line successfully requested by this driver, -1 otherwise */
- int irq_line;
- /* board revision */
- u8 revision;
- /* interrupt count, incremented by the interrupt handler */
- int irq_count;
-#if ALTPCIECHDMA_CDEV
- /* character device */
- dev_t cdevno;
- struct cdev cdev;
- /* user space scatter gather mapper */
- struct sg_mapping_t *sgm;
-#endif
-};
-
-/**
- * Using the subsystem vendor id and subsystem id, it is possible to
- * distinguish between different cards bases around the same
- * (third-party) logic core.
- *
- * Default Altera vendor and device ID's, and some (non-reserved)
- * ID's are now used here that are used amongst the testers/developers.
- */
-static const struct pci_device_id ids[] = {
- { PCI_DEVICE(0x1172, 0xE001), },
- { PCI_DEVICE(0x2071, 0x2071), },
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, ids);
-
-#if ALTPCIECHDMA_CDEV
-/* prototypes for character device */
-static int sg_init(struct ape_dev *ape);
-static void sg_exit(struct ape_dev *ape);
-#endif
-
-/**
- * altpciechdma_isr() - Interrupt handler
- *
- */
-static irqreturn_t altpciechdma_isr(int irq, void *dev_id)
-{
- struct ape_dev *ape = (struct ape_dev *)dev_id;
- if (!ape)
- return IRQ_NONE;
- ape->irq_count++;
- return IRQ_HANDLED;
-}
-
-static int __devinit scan_bars(struct ape_dev *ape, struct pci_dev *dev)
-{
- int i;
- for (i = 0; i < APE_BAR_NUM; i++) {
- unsigned long bar_start = pci_resource_start(dev, i);
- if (bar_start) {
- unsigned long bar_end = pci_resource_end(dev, i);
- unsigned long bar_flags = pci_resource_flags(dev, i);
- printk(KERN_DEBUG "BAR%d 0x%08lx-0x%08lx flags 0x%08lx\n",
- i, bar_start, bar_end, bar_flags);
- }
- }
- return 0;
-}
-
-/**
- * Unmap the BAR regions that had been mapped earlier using map_bars()
- */
-static void unmap_bars(struct ape_dev *ape, struct pci_dev *dev)
-{
- int i;
- for (i = 0; i < APE_BAR_NUM; i++) {
- /* is this BAR mapped? */
- if (ape->bar[i]) {
- /* unmap BAR */
- pci_iounmap(dev, ape->bar[i]);
- ape->bar[i] = NULL;
- }
- }
-}
-
-/**
- * Map the device memory regions into kernel virtual address space after
- * verifying their sizes respect the minimum sizes needed, given by the
- * bar_min_len[] array.
- */
-static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
-{
- int rc;
- int i;
- /* iterate through all the BARs */
- for (i = 0; i < APE_BAR_NUM; i++) {
- unsigned long bar_start = pci_resource_start(dev, i);
- unsigned long bar_end = pci_resource_end(dev, i);
- unsigned long bar_length = bar_end - bar_start + 1;
- ape->bar[i] = NULL;
- /* do not map, and skip, BARs with length 0 */
- if (!bar_min_len[i])
- continue;
- /* do not map BARs with address 0 */
- if (!bar_start || !bar_end) {
- printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
- rc = -1;
- goto fail;
- }
- bar_length = bar_end - bar_start + 1;
- /* BAR length is less than driver requires? */
- if (bar_length < bar_min_len[i]) {
- printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
- "requires at least %lu bytes\n",
- i, bar_length, bar_min_len[i]);
- rc = -1;
- goto fail;
- }
- /* map the device memory or IO region into kernel virtual
- * address space */
- ape->bar[i] = pci_iomap(dev, i, bar_min_len[i]);
- if (!ape->bar[i]) {
- printk(KERN_DEBUG "Could not map BAR #%d.\n", i);
- rc = -1;
- goto fail;
- }
- printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
- ape->bar[i], bar_min_len[i], bar_length);
- }
- /* successfully mapped all required BAR regions */
- rc = 0;
- goto success;
-fail:
- /* unmap any BARs that we did map */
- unmap_bars(ape, dev);
-success:
- return rc;
-}
-
-#if 0 /* not yet implemented fully FIXME add opcode */
-static void __devinit rcslave_test(struct ape_dev *ape, struct pci_dev *dev)
-{
- u32 *rcslave_mem = (u32 *)ape->bar[APE_BAR_RCSLAVE];
- u32 result = 0;
- /** this number is assumed to be different each time this test runs */
- u32 seed = (u32)jiffies;
- u32 value = seed;
- int i;
-
- /* write loop */
- value = seed;
- for (i = 1024; i < 32768 / 4 ; i++) {
- printk(KERN_DEBUG "Writing 0x%08x to 0x%p.\n",
- (u32)value, (void *)rcslave_mem + i);
- iowrite32(value, rcslave_mem + i);
- value++;
- }
- /* read-back loop */
- value = seed;
- for (i = 1024; i < 32768 / 4; i++) {
- result = ioread32(rcslave_mem + i);
- if (result != value) {
- printk(KERN_DEBUG "Wrote 0x%08x to 0x%p, but read back 0x%08x.\n",
- (u32)value, (void *)rcslave_mem + i, (u32)result);
- break;
- }
- value++;
- }
-}
-#endif
-
-/* obtain the 32 most significant (high) bits of a 32-bit or 64-bit address */
-#define pci_dma_h(addr) ((addr >> 16) >> 16)
-/* obtain the 32 least significant (low) bits of a 32-bit or 64-bit address */
-#define pci_dma_l(addr) (addr & 0xffffffffUL)
-
-/* ape_fill_chdma_desc() - Fill a Altera PCI Express Chaining DMA descriptor
- *
- * @desc pointer to descriptor to be filled
- * @addr root complex address
- * @ep_addr end point address
- * @len number of bytes, must be a multiple of 4.
- */
-static inline void ape_chdma_desc_set(struct ape_chdma_desc *desc, dma_addr_t addr, u32 ep_addr, int len)
-{
- BUG_ON(len & 3);
- desc->w0 = cpu_to_le32(len / 4);
- desc->ep_addr = cpu_to_le32(ep_addr);
- desc->rc_addr_h = cpu_to_le32(pci_dma_h(addr));
- desc->rc_addr_l = cpu_to_le32(pci_dma_l(addr));
-}
-
-#if ALTPCIECHDMA_CDEV
-/*
- * ape_sg_to_chdma_table() - Create a device descriptor table from a scatterlist.
- *
- * The scatterlist must have been mapped by pci_map_sg(sgm->sgl).
- *
- * @sgl scatterlist.
- * @nents Number of entries in the scatterlist.
- * @first Start index in the scatterlist sgm->sgl.
- * @ep_addr End Point address for the scatter/gather transfer.
- * @desc pointer to first descriptor
- *
- * Returns Number of entries in the table on success, -1 on error.
- */
-static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first, struct ape_chdma_desc *desc, u32 ep_addr)
-{
- int i = first, j = 0;
- /* inspect first entry */
- dma_addr_t addr = sg_dma_address(&sgl[i]);
- unsigned int len = sg_dma_len(&sgl[i]);
- /* contiguous block */
- dma_addr_t cont_addr = addr;
- unsigned int cont_len = len;
- /* iterate over remaining entries */
- for (; j < 25 && i < nents - 1; i++) {
- /* bus address of next entry i + 1 */
- dma_addr_t next = sg_dma_address(&sgl[i + 1]);
- /* length of this entry i */
- len = sg_dma_len(&sgl[i]);
- printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
- (unsigned long long)addr, len);
- /* entry i + 1 is non-contiguous with entry i? */
- if (next != addr + len) {
- /* TODO create entry here (we could overwrite i) */
- printk(KERN_DEBUG "%4d: cont_addr=0x%Lx cont_len=0x%08x\n", j,
- (unsigned long long)cont_addr, cont_len);
- /* set descriptor for contiguous transfer */
- ape_chdma_desc_set(&desc[j], cont_addr, ep_addr, cont_len);
- /* next end point memory address */
- ep_addr += cont_len;
- /* start new contiguous block */
- cont_addr = next;
- cont_len = 0;
- j++;
- }
- /* add entry i + 1 to current contiguous block */
- cont_len += len;
- /* goto entry i + 1 */
- addr = next;
- }
- /* TODO create entry here (we could overwrite i) */
- printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
- (unsigned long long)addr, len);
- printk(KERN_DEBUG "%4d: cont_addr=0x%Lx length=0x%08x\n", j,
- (unsigned long long)cont_addr, cont_len);
- j++;
- return j;
-}
-#endif
-
-/* compare buffers */
-static inline int compare(u32 *p, u32 *q, int len)
-{
- int result = -1;
- int fail = 0;
- int i;
- for (i = 0; i < len / 4; i++) {
- if (*p == *q) {
- /* every so many u32 words, show equals */
- if ((i & 255) == 0)
- printk(KERN_DEBUG "[%p] = 0x%08x [%p] = 0x%08x\n", p, *p, q, *q);
- } else {
- fail++;
- /* show the first few miscompares */
- if (fail < 10)
- printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
- /* but stop after a while */
- else if (fail == 10)
- printk(KERN_DEBUG "---more errors follow! not printed---\n");
- else
- /* stop compare after this many errors */
- break;
- }
- p++;
- q++;
- }
- if (!fail)
- result = 0;
- return result;
-}
-
-/* dma_test() - Perform DMA loop back test to end point and back to root complex.
- *
- * Allocate a cache-coherent buffer in host memory, consisting of four pages.
- *
- * Fill the four memory pages such that each 32-bit word contains its own address.
- *
- * Now perform a loop back test, have the end point device copy the first buffer
- * half to end point memory, then have it copy back into the second half.
- *
- * Create a descriptor table to copy the first buffer half into End Point
- * memory. Instruct the End Point to do a DMA read using that table.
- *
- * Create a descriptor table to copy End Point memory to the second buffer
- * half. Instruct the End Point to do a DMA write using that table.
- *
- * Compare results, fail or pass.
- *
- */
-static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
-{
- /* test result; guilty until proven innocent */
- int result = -1;
- /* the DMA read header sits at address 0x00 of the DMA engine BAR */
- struct ape_chdma_header *write_header = (struct ape_chdma_header *)ape->bar[APE_BAR_HEADER];
- /* the write DMA header sits after the read header at address 0x10 */
- struct ape_chdma_header *read_header = write_header + 1;
- /* virtual address of the allocated buffer */
- u8 *buffer_virt = 0;
- /* bus address of the allocated buffer */
- dma_addr_t buffer_bus = 0;
- int i, n = 0, irq_count;
-
- /* temporary value used to construct 32-bit data words */
- u32 w;
-
- printk(KERN_DEBUG "bar_tests(), PAGE_SIZE = 0x%0x\n", (int)PAGE_SIZE);
- printk(KERN_DEBUG "write_header = 0x%p.\n", write_header);
- printk(KERN_DEBUG "read_header = 0x%p.\n", read_header);
- printk(KERN_DEBUG "&write_header->w3 = 0x%p\n", &write_header->w3);
- printk(KERN_DEBUG "&read_header->w3 = 0x%p\n", &read_header->w3);
- printk(KERN_DEBUG "ape->table_virt = 0x%p.\n", ape->table_virt);
-
- if (!write_header || !read_header || !ape->table_virt)
- goto fail;
-
- /* allocate and map coherently-cached memory for a DMA-able buffer */
- /* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
- buffer_virt = (u8 *)pci_alloc_consistent(dev, PAGE_SIZE * 4, &buffer_bus);
- if (!buffer_virt) {
- printk(KERN_DEBUG "Could not allocate coherent DMA buffer.\n");
- goto fail;
- }
- printk(KERN_DEBUG "Allocated cache-coherent DMA buffer (virtual address = %p, bus address = 0x%016llx).\n",
- buffer_virt, (u64)buffer_bus);
-
- /* fill first half of buffer with its virtual address as data */
- for (i = 0; i < 4 * PAGE_SIZE; i += 4)
-#if 0
- *(u32 *)(buffer_virt + i) = i / PAGE_SIZE + 1;
-#else
- *(u32 *)(buffer_virt + i) = (u32)(unsigned long)(buffer_virt + i);
-#endif
-#if 0
- compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192);
-#endif
-
-#if 0
- /* fill second half of buffer with zeroes */
- for (i = 2 * PAGE_SIZE; i < 4 * PAGE_SIZE; i += 4)
- *(u32 *)(buffer_virt + i) = 0;
-#endif
-
- /* invalidate EPLAST, outside 0-255, 0xFADE is from the testbench */
- ape->table_virt->w3 = cpu_to_le32(0x0000FADE);
-
- /* fill in first descriptor */
- n = 0;
- /* read 8192 bytes from RC buffer to EP address 4096 */
- ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus, 4096, 2 * PAGE_SIZE);
-#if 1
- for (i = 0; i < 255; i++)
- ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus, 4096, 2 * PAGE_SIZE);
- /* index of last descriptor */
- n = i - 1;
-#endif
-#if 0
- /* fill in next descriptor */
- n++;
- /* read 1024 bytes from RC buffer to EP address 4096 + 1024 */
- ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 1024, 4096 + 1024, 1024);
-#endif
-
-#if 1
- /* enable MSI after the last descriptor is completed */
- if (ape->msi_enabled)
- ape->table_virt->desc[n].w0 |= cpu_to_le32(1UL << 16)/*local MSI*/;
-#endif
-#if 0
- /* dump descriptor table for debugging */
- printk(KERN_DEBUG "Descriptor Table (Read, in Root Complex Memory, # = %d)\n", n + 1);
- for (i = 0; i < 4 + (n + 1) * 4; i += 4) {
- u32 *p = (u32 *)ape->table_virt;
- p += i;
- printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (LEN=0x%x)\n", (u32)p, (u32)p & 15, *p, 4 * le32_to_cpu(*p));
- p++;
- printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (EPA=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
- p++;
- printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCH=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
- p++;
- printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCL=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
- }
-#endif
- /* set available number of descriptors in table */
- w = (u32)(n + 1);
- w |= (1UL << 18)/*global EPLAST_EN*/;
-#if 0
- if (ape->msi_enabled)
- w |= (1UL << 17)/*global MSI*/;
-#endif
- printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", w, (void *)&read_header->w0);
- iowrite32(w, &read_header->w0);
-
- /* write table address (higher 32-bits) */
- printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)((ape->table_bus >> 16) >> 16), (void *)&read_header->bdt_addr_h);
- iowrite32(pci_dma_h(ape->table_bus), &read_header->bdt_addr_h);
-
- /* write table address (lower 32-bits) */
- printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)(ape->table_bus & 0xffffffffUL), (void *)&read_header->bdt_addr_l);
- iowrite32(pci_dma_l(ape->table_bus), &read_header->bdt_addr_l);
-
- /* memory write barrier */
- wmb();
- printk(KERN_DEBUG "Flush posted writes\n");
- /** FIXME Add dummy read to flush posted writes but need a readable location! */
-#if 0
- (void)ioread32();
-#endif
-
- /* remember IRQ count before the transfer */
- irq_count = ape->irq_count;
- /* write number of descriptors - this starts the DMA */
- printk(KERN_DEBUG "\nStart DMA read\n");
- printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)n, (void *)&read_header->w3);
- iowrite32(n, &read_header->w3);
- printk(KERN_DEBUG "EPLAST = %lu\n", le32_to_cpu(*(u32 *)&ape->table_virt->w3) & 0xffffUL);
-
- /** memory write barrier */
- wmb();
- /* dummy read to flush posted writes */
- /* FIXME Need a readable location! */
-#if 0
- (void)ioread32();
-#endif
- printk(KERN_DEBUG "POLL FOR READ:\n");
- /* poll for chain completion, 1000 times 1 millisecond */
- for (i = 0; i < 100; i++) {
- volatile u32 *p = &ape->table_virt->w3;
- u32 eplast = le32_to_cpu(*p) & 0xffffUL;
- printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
- if (eplast == n) {
- printk(KERN_DEBUG "DONE\n");
- /* print IRQ count before the transfer */
- printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
- break;
- }
- udelay(100);
- }
-
- /* invalidate EPLAST, outside 0-255, 0xFADE is from the testbench */
- ape->table_virt->w3 = cpu_to_le32(0x0000FADE);
-
- /* setup first descriptor */
- n = 0;
- ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
-#if 1
- for (i = 0; i < 255; i++)
- ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
-
- /* index of last descriptor */
- n = i - 1;
-#endif
-#if 1 /* test variable, make a module option later */
- if (ape->msi_enabled)
- ape->table_virt->desc[n].w0 |= cpu_to_le32(1UL << 16)/*local MSI*/;
-#endif
-#if 0
- /* dump descriptor table for debugging */
- printk(KERN_DEBUG "Descriptor Table (Write, in Root Complex Memory, # = %d)\n", n + 1);
- for (i = 0; i < 4 + (n + 1) * 4; i += 4) {
- u32 *p = (u32 *)ape->table_virt;
- p += i;
- printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (LEN=0x%x)\n", (u32)p, (u32)p & 15, *p, 4 * le32_to_cpu(*p));
- p++;
- printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (EPA=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
- p++;
- printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCH=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
- p++;
- printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCL=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
- }
-#endif
-
- /* set number of available descriptors in the table */
- w = (u32)(n + 1);
- /* enable updates of eplast for each descriptor completion */
- w |= (u32)(1UL << 18)/*global EPLAST_EN*/;
-#if 0 /* test variable, make a module option later */
- /* enable MSI for each descriptor completion */
- if (ape->msi_enabled)
- w |= (1UL << 17)/*global MSI*/;
-#endif
- iowrite32(w, &write_header->w0);
- iowrite32(pci_dma_h(ape->table_bus), &write_header->bdt_addr_h);
- iowrite32(pci_dma_l(ape->table_bus), &write_header->bdt_addr_l);
-
- /** memory write barrier and flush posted writes */
- wmb();
- /* dummy read to flush posted writes */
- /* FIXME Need a readable location! */
-#if 0
- (void)ioread32();
-#endif
- irq_count = ape->irq_count;
-
- printk(KERN_DEBUG "\nStart DMA write\n");
- iowrite32(n, &write_header->w3);
-
- /** memory write barrier */
- wmb();
- /** dummy read to flush posted writes */
- /* (void) ioread32(); */
-
- printk(KERN_DEBUG "POLL FOR WRITE:\n");
- /* poll for completion, 1000 times 1 millisecond */
- for (i = 0; i < 100; i++) {
- volatile u32 *p = &ape->table_virt->w3;
- u32 eplast = le32_to_cpu(*p) & 0xffffUL;
- printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
- if (eplast == n) {
- printk(KERN_DEBUG "DONE\n");
- /* print IRQ count before the transfer */
- printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
- break;
- }
- udelay(100);
- }
- /* soft-reset DMA write engine */
- iowrite32(0x0000ffffUL, &write_header->w0);
- /* soft-reset DMA read engine */
- iowrite32(0x0000ffffUL, &read_header->w0);
-
- /** memory write barrier */
- wmb();
- /* dummy read to flush posted writes */
- /* FIXME Need a readable location! */
-#if 0
- (void)ioread32();
-#endif
- /* compare first half of buffer with second half, should be identical */
- result = compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192);
- printk(KERN_DEBUG "DMA loop back test %s.\n", result ? "FAILED" : "PASSED");
-
- pci_free_consistent(dev, 4 * PAGE_SIZE, buffer_virt, buffer_bus);
-fail:
- printk(KERN_DEBUG "bar_tests() end, result %d\n", result);
- return result;
-}
-
-/* Called when the PCI sub system thinks we can control the given device.
- * Inspect if we can support the device and if so take control of it.
- *
- * Return 0 when we have taken control of the given device.
- *
- * - allocate board specific bookkeeping
- * - allocate coherently-mapped memory for the descriptor table
- * - enable the board
- * - verify board revision
- * - request regions
- * - query DMA mask
- * - obtain and request irq
- * - map regions into kernel address space
- */
-static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- int rc = 0;
- struct ape_dev *ape = NULL;
- u8 irq_pin, irq_line;
- printk(KERN_DEBUG "probe(dev = 0x%p, pciid = 0x%p)\n", dev, id);
-
- /* allocate memory for per-board book keeping */
- ape = kzalloc(sizeof(struct ape_dev), GFP_KERNEL);
- if (!ape) {
- printk(KERN_DEBUG "Could not kzalloc()ate memory.\n");
- goto err_ape;
- }
- ape->pci_dev = dev;
- dev_set_drvdata(&dev->dev, ape);
- printk(KERN_DEBUG "probe() ape = 0x%p\n", ape);
-
- printk(KERN_DEBUG "sizeof(struct ape_chdma_table) = %d.\n",
- (int)sizeof(struct ape_chdma_table));
- /* the reference design has a size restriction on the table size */
- BUG_ON(sizeof(struct ape_chdma_table) > APE_CHDMA_TABLE_SIZE);
-
- /* allocate and map coherently-cached memory for a descriptor table */
- /* @see LDD3 page 446 */
- ape->table_virt = (struct ape_chdma_table *)pci_alloc_consistent(dev,
- APE_CHDMA_TABLE_SIZE, &ape->table_bus);
- /* could not allocate table? */
- if (!ape->table_virt) {
- printk(KERN_DEBUG "Could not dma_alloc()ate_coherent memory.\n");
- goto err_table;
- }
-
- printk(KERN_DEBUG "table_virt = %p, table_bus = 0x%16llx.\n",
- ape->table_virt, (u64)ape->table_bus);
-
- /* enable device */
- rc = pci_enable_device(dev);
- if (rc) {
- printk(KERN_DEBUG "pci_enable_device() failed\n");
- goto err_enable;
- }
-
- /* enable bus master capability on device */
- pci_set_master(dev);
- /* enable message signaled interrupts */
- rc = pci_enable_msi(dev);
- /* could not use MSI? */
- if (rc) {
- /* resort to legacy interrupts */
- printk(KERN_DEBUG "Could not enable MSI interrupting.\n");
- ape->msi_enabled = 0;
- /* MSI enabled, remember for cleanup */
- } else {
- printk(KERN_DEBUG "Enabled MSI interrupting.\n");
- ape->msi_enabled = 1;
- }
-
- pci_read_config_byte(dev, PCI_REVISION_ID, &ape->revision);
-#if 0 /* example */
- /* (for example) this driver does not support revision 0x42 */
- if (ape->revision == 0x42) {
- printk(KERN_DEBUG "Revision 0x42 is not supported by this driver.\n");
- rc = -ENODEV;
- goto err_rev;
- }
-#endif
- /** XXX check for native or legacy PCIe endpoint? */
-
- rc = pci_request_regions(dev, DRV_NAME);
- /* could not request all regions? */
- if (rc) {
- /* assume device is in use (and do not disable it later!) */
- ape->in_use = 1;
- goto err_regions;
- }
- ape->got_regions = 1;
-
-#if 1 /* @todo For now, disable 64-bit, because I do not understand the implications (DAC!) */
- /* query for DMA transfer */
- /* @see Documentation/PCI/PCI-DMA-mapping.txt */
- if (!pci_set_dma_mask(dev, DMA_BIT_MASK(64))) {
- pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
- /* use 64-bit DMA */
- printk(KERN_DEBUG "Using a 64-bit DMA mask.\n");
- } else
-#endif
- if (!pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
- printk(KERN_DEBUG "Could not set 64-bit DMA mask.\n");
- pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32));
- /* use 32-bit DMA */
- printk(KERN_DEBUG "Using a 32-bit DMA mask.\n");
- } else {
- printk(KERN_DEBUG "No suitable DMA possible.\n");
- /** @todo Choose proper error return code */
- rc = -1;
- goto err_mask;
- }
-
- rc = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
- /* could not read? */
- if (rc)
- goto err_irq;
- printk(KERN_DEBUG "IRQ pin #%d (0=none, 1=INTA#...4=INTD#).\n", irq_pin);
-
- /* @see LDD3, page 318 */
- rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_line);
- /* could not read? */
- if (rc) {
- printk(KERN_DEBUG "Could not query PCI_INTERRUPT_LINE, error %d\n", rc);
- goto err_irq;
- }
- printk(KERN_DEBUG "IRQ line #%d.\n", irq_line);
-#if 1
- irq_line = dev->irq;
- /* @see LDD3, page 259 */
- rc = request_irq(irq_line, altpciechdma_isr, IRQF_SHARED, DRV_NAME, (void *)ape);
- if (rc) {
- printk(KERN_DEBUG "Could not request IRQ #%d, error %d\n", irq_line, rc);
- ape->irq_line = -1;
- goto err_irq;
- }
- /* remember which irq we allocated */
- ape->irq_line = (int)irq_line;
- printk(KERN_DEBUG "Succesfully requested IRQ #%d with dev_id 0x%p\n", irq_line, ape);
-#endif
- /* show BARs */
- scan_bars(ape, dev);
- /* map BARs */
- rc = map_bars(ape, dev);
- if (rc)
- goto err_map;
-#if ALTPCIECHDMA_CDEV
- /* initialize character device */
- rc = sg_init(ape);
- if (rc)
- goto err_cdev;
-#endif
- /* perform DMA engines loop back test */
- rc = dma_test(ape, dev);
- (void)rc;
- /* successfully took the device */
- rc = 0;
- printk(KERN_DEBUG "probe() successful.\n");
- goto end;
-#if ALTPCIECHDMA_CDEV
-err_cdev:
- /* unmap the BARs */
- unmap_bars(ape, dev);
-#endif
-err_map:
- /* free allocated irq */
- if (ape->irq_line >= 0)
- free_irq(ape->irq_line, (void *)ape);
-err_irq:
- if (ape->msi_enabled)
- pci_disable_msi(dev);
- /* disable the device iff it is not in use */
- if (!ape->in_use)
- pci_disable_device(dev);
- if (ape->got_regions)
- pci_release_regions(dev);
-err_mask:
-err_regions:
-/*err_rev:*/
-/* clean up everything before device enable() */
-err_enable:
- if (ape->table_virt)
- pci_free_consistent(dev, APE_CHDMA_TABLE_SIZE, ape->table_virt, ape->table_bus);
-/* clean up everything before allocating descriptor table */
-err_table:
- if (ape)
- kfree(ape);
-err_ape:
-end:
- return rc;
-}
-
-static void __devexit remove(struct pci_dev *dev)
-{
- struct ape_dev *ape = dev_get_drvdata(&dev->dev);
-
- printk(KERN_DEBUG "remove(0x%p)\n", dev);
- printk(KERN_DEBUG "remove(dev = 0x%p) where ape = 0x%p\n", dev, ape);
-
- /* remove character device */
-#if ALTPCIECHDMA_CDEV
- sg_exit(ape);
-#endif
-
- if (ape->table_virt)
- pci_free_consistent(dev, APE_CHDMA_TABLE_SIZE, ape->table_virt, ape->table_bus);
-
- /* free IRQ
- * @see LDD3 page 279
- */
- if (ape->irq_line >= 0) {
- printk(KERN_DEBUG "Freeing IRQ #%d for dev_id 0x%08lx.\n",
- ape->irq_line, (unsigned long)ape);
- free_irq(ape->irq_line, (void *)ape);
- }
- /* MSI was enabled? */
- if (ape->msi_enabled) {
- /* Disable MSI @see Documentation/MSI-HOWTO.txt */
- pci_disable_msi(dev);
- ape->msi_enabled = 0;
- }
- /* unmap the BARs */
- unmap_bars(ape, dev);
- if (!ape->in_use)
- pci_disable_device(dev);
- if (ape->got_regions)
- /* to be called after device disable */
- pci_release_regions(dev);
-}
-
-#if ALTPCIECHDMA_CDEV
-
-/*
- * Called when the device goes from unused to used.
- */
-static int sg_open(struct inode *inode, struct file *file)
-{
- struct ape_dev *ape;
- printk(KERN_DEBUG DRV_NAME "_open()\n");
- /* pointer to containing data structure of the character device inode */
- ape = container_of(inode->i_cdev, struct ape_dev, cdev);
- /* create a reference to our device state in the opened file */
- file->private_data = ape;
- /* create virtual memory mapper */
- ape->sgm = sg_create_mapper(MAX_CHDMA_SIZE);
- return 0;
-}
-
-/*
- * Called when the device goes from used to unused.
- */
-static int sg_close(struct inode *inode, struct file *file)
-{
- /* fetch device specific data stored earlier during open */
- struct ape_dev *ape = (struct ape_dev *)file->private_data;
- printk(KERN_DEBUG DRV_NAME "_close()\n");
- /* destroy virtual memory mapper */
- sg_destroy_mapper(ape->sgm);
- return 0;
-}
-
-static ssize_t sg_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
-{
- /* fetch device specific data stored earlier during open */
- struct ape_dev *ape = (struct ape_dev *)file->private_data;
- (void)ape;
- printk(KERN_DEBUG DRV_NAME "_read(buf=0x%p, count=%lld, pos=%llu)\n", buf, (s64)count, (u64)*pos);
- return count;
-}
-
-/* sg_write() - Write to the device
- *
- * @buf userspace buffer
- * @count number of bytes in the userspace buffer
- *
- * Iterate over the userspace buffer, taking at most 255 * PAGE_SIZE bytes for
- * each DMA transfer.
- * For each transfer, get the user pages, build a sglist, map, build a
- * descriptor table. submit the transfer. wait for the interrupt handler
- * to wake us on completion.
- */
-static ssize_t sg_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
-{
- int hwnents, tents;
- size_t transfer_len, remaining = count, done = 0;
- u64 transfer_addr = (u64)buf;
- /* fetch device specific data stored earlier during open */
- struct ape_dev *ape = (struct ape_dev *)file->private_data;
- printk(KERN_DEBUG DRV_NAME "_write(buf=0x%p, count=%lld, pos=%llu)\n",
- buf, (s64)count, (u64)*pos);
- /* TODO transfer boundaries at PAGE_SIZE granularity */
- while (remaining > 0) {
- /* limit DMA transfer size */
- transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN) ? remaining :
- APE_CHDMA_MAX_TRANSFER_LEN;
- /* get all user space buffer pages and create a scattergather list */
- sgm_map_user_pages(ape->sgm, transfer_addr, transfer_len, 0/*read from userspace*/);
- printk(KERN_DEBUG DRV_NAME "mapped_pages=%d\n", ape->sgm->mapped_pages);
- /* map all entries in the scattergather list */
- hwnents = pci_map_sg(ape->pci_dev, ape->sgm->sgl, ape->sgm->mapped_pages, DMA_TO_DEVICE);
- printk(KERN_DEBUG DRV_NAME "hwnents=%d\n", hwnents);
- /* build device descriptor tables and submit them to the DMA engine */
- tents = ape_sg_to_chdma_table(ape->sgm->sgl, hwnents, 0, &ape->table_virt->desc[0], 4096);
- printk(KERN_DEBUG DRV_NAME "tents=%d\n", hwnents);
-#if 0
- while (tables) {
- /* TODO build table */
- /* TODO submit table to the device */
- /* if engine stopped and unfinished work then start engine */
- }
- put ourselves on wait queue
-#endif
-
- dma_unmap_sg(NULL, ape->sgm->sgl, ape->sgm->mapped_pages, DMA_TO_DEVICE);
- /* dirty and free the pages */
- sgm_unmap_user_pages(ape->sgm, 1/*dirtied*/);
- /* book keeping */
- transfer_addr += transfer_len;
- remaining -= transfer_len;
- done += transfer_len;
- }
- return done;
-}
-
-/*
- * character device file operations
- */
-static const struct file_operations sg_fops = {
- .owner = THIS_MODULE,
- .open = sg_open,
- .release = sg_close,
- .read = sg_read,
- .write = sg_write,
-};
-
-/* sg_init() - Initialize character device
- *
- * XXX Should ideally be tied to the device, on device probe, not module init.
- */
-static int sg_init(struct ape_dev *ape)
-{
- int rc;
- printk(KERN_DEBUG DRV_NAME " sg_init()\n");
- /* allocate a dynamically allocated character device node */
- rc = alloc_chrdev_region(&ape->cdevno, 0/*requested minor*/, 1/*count*/, DRV_NAME);
- /* allocation failed? */
- if (rc < 0) {
- printk("alloc_chrdev_region() = %d\n", rc);
- goto fail_alloc;
- }
- /* couple the device file operations to the character device */
- cdev_init(&ape->cdev, &sg_fops);
- ape->cdev.owner = THIS_MODULE;
- /* bring character device live */
- rc = cdev_add(&ape->cdev, ape->cdevno, 1/*count*/);
- if (rc < 0) {
- printk("cdev_add() = %d\n", rc);
- goto fail_add;
- }
- printk(KERN_DEBUG "altpciechdma = %d:%d\n", MAJOR(ape->cdevno), MINOR(ape->cdevno));
- return 0;
-fail_add:
- /* free the dynamically allocated character device node */
- unregister_chrdev_region(ape->cdevno, 1/*count*/);
-fail_alloc:
- return -1;
-}
-
-/* sg_exit() - Cleanup character device
- *
- * XXX Should ideally be tied to the device, on device remove, not module exit.
- */
-
-static void sg_exit(struct ape_dev *ape)
-{
- printk(KERN_DEBUG DRV_NAME " sg_exit()\n");
- /* remove the character device */
- cdev_del(&ape->cdev);
- /* free the dynamically allocated character device node */
- unregister_chrdev_region(ape->cdevno, 1/*count*/);
-}
-
-#endif /* ALTPCIECHDMA_CDEV */
-
-/* used to register the driver with the PCI kernel sub system
- * @see LDD3 page 311
- */
-static struct pci_driver pci_driver = {
- .name = DRV_NAME,
- .id_table = ids,
- .probe = probe,
- .remove = __devexit_p(remove),
- /* resume, suspend are optional */
-};
-
-/**
- * alterapciechdma_init() - Module initialization, registers devices.
- */
-static int __init alterapciechdma_init(void)
-{
- int rc = 0;
- printk(KERN_DEBUG DRV_NAME " init(), built at " __DATE__ " " __TIME__ "\n");
- /* register this driver with the PCI bus driver */
- rc = pci_register_driver(&pci_driver);
- if (rc < 0)
- return rc;
- return 0;
-}
-
-/**
- * alterapciechdma_init() - Module cleanup, unregisters devices.
- */
-static void __exit alterapciechdma_exit(void)
-{
- printk(KERN_DEBUG DRV_NAME " exit(), built at " __DATE__ " " __TIME__ "\n");
- /* unregister this driver from the PCI bus driver */
- pci_unregister_driver(&pci_driver);
-}
-
-MODULE_LICENSE("GPL");
-
-module_init(alterapciechdma_init);
-module_exit(alterapciechdma_exit);
-
diff --git a/drivers/staging/arlan/Makefile b/drivers/staging/arlan/Makefile
index 9e58e5fae7b..5a84d4402f2 100644
--- a/drivers/staging/arlan/Makefile
+++ b/drivers/staging/arlan/Makefile
@@ -1,3 +1,3 @@
-obj-$(CONFIG_ARLAN) += arlan.o
+obj-$(CONFIG_ARLAN) += arlan.o
arlan-objs := arlan-main.o arlan-proc.o
diff --git a/drivers/staging/arlan/arlan.h b/drivers/staging/arlan/arlan.h
index fb3ad51a1ca..ffcd3ea048a 100644
--- a/drivers/staging/arlan/arlan.h
+++ b/drivers/staging/arlan/arlan.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1997 Cullen Jennings
- * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500
+ * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500
* GNU General Public License applies
*/
@@ -20,14 +20,14 @@
#include <linux/init.h>
#include <linux/bitops.h>
#include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-//#define ARLAN_DEBUGGING 1
+/* #define ARLAN_DEBUGGING 1 */
#define ARLAN_PROC_INTERFACE
#define MAX_ARLANS 4 /* not more than 4 ! */
@@ -51,8 +51,8 @@ extern int arlan_debug;
extern int arlan_entry_debug;
extern int arlan_exit_debug;
extern int testMemory;
-extern int arlan_command(struct net_device * dev, int command);
-
+extern int arlan_command(struct net_device *dev, int command);
+
#define SIDUNKNOWN -1
#define radioNodeIdUNKNOWN -1
#define irqUNKNOWN 0
@@ -65,22 +65,21 @@ extern int arlan_command(struct net_device * dev, int command);
#define registrationModeUNKNOWN -1
-#define IFDEBUG( L ) if ( (L) & arlan_debug )
-#define ARLAN_FAKE_HDR_LEN 12
+#define IFDEBUG(L) if ((L) & arlan_debug)
+#define ARLAN_FAKE_HDR_LEN 12
#ifdef ARLAN_DEBUGGING
#define DEBUG 1
#define ARLAN_ENTRY_EXIT_DEBUGGING 1
- #define ARLAN_DEBUG(a,b) printk(KERN_DEBUG a, b)
+ #define ARLAN_DEBUG(a, b) printk(KERN_DEBUG a, b)
#else
- #define ARLAN_DEBUG(a,b)
+ #define ARLAN_DEBUG(a, b)
#endif
#define ARLAN_SHMEM_SIZE 0x2000
-struct arlan_shmem
-{
- /* Header Signature */
+struct arlan_shmem {
+ /* Header Signature */
volatile char textRegion[48];
volatile u_char resetFlag;
volatile u_char diagnosticInfo;
@@ -91,10 +90,10 @@ struct arlan_shmem
volatile u_char hardwareType;
volatile u_char majorHardwareVersion;
volatile u_char minorHardwareVersion;
- volatile u_char radioModule;// shows EEPROM, can be overridden at 0x111
- volatile u_char defaultChannelSet; // shows EEProm, can be overriiden at 0x10A
+ volatile u_char radioModule;/* shows EEPROM, can be overridden at 0x111 */
+ volatile u_char defaultChannelSet; /* shows EEProm, can be overriiden at 0x10A */
volatile u_char _2[47];
-
+
/* Control/Status Block - 0x0080 */
volatile u_char interruptInProgress; /* not used by lancpu */
volatile u_char cntrlRegImage; /* not used by lancpu */
@@ -113,7 +112,7 @@ struct arlan_shmem
volatile u_char rxQuality;
volatile u_char scrambled;
volatile u_char _4[1];
-
+
/* Transmit Status - 0x00b0 */
volatile u_char txStatus;
volatile u_char txAckQuality;
@@ -151,7 +150,7 @@ struct arlan_shmem
volatile u_short routerId;
volatile u_char _10[9];
volatile u_char txAttenuation;
- volatile u_char systemId[4];
+ volatile u_char systemId[4];
volatile u_short globalChecksum;
volatile u_char _11[4];
volatile u_short maxDatagramSize;
@@ -207,19 +206,19 @@ struct arlan_shmem
volatile u_char hostcpuLock;
volatile u_char lancpuLock;
volatile u_char resetTime[18];
-
+
volatile u_char numDatagramsTransmitted[4];
volatile u_char numReTransmissions[4];
volatile u_char numFramesDiscarded[4];
volatile u_char numDatagramsReceived[4];
volatile u_char numDuplicateReceivedFrames[4];
volatile u_char numDatagramsDiscarded[4];
-
+
volatile u_short maxNumReTransmitDatagram;
volatile u_short maxNumReTransmitFrames;
volatile u_short maxNumConsecutiveDuplicateFrames;
/* misaligned here so we have to go to characters */
-
+
volatile u_char numBytesTransmitted[4];
volatile u_char numBytesReceived[4];
volatile u_char numCRCErrors[4];
@@ -259,7 +258,7 @@ struct arlan_conf_stru {
int channelNumber;
int scramblingDisable;
int txAttenuation;
- int systemId;
+ int systemId;
int maxDatagramSize;
int maxFrameSize;
int maxRetries;
@@ -316,8 +315,7 @@ struct arlan_conf_stru {
extern struct arlan_conf_stru arlan_conf[MAX_ARLANS];
-struct TxParam
-{
+struct TxParam {
volatile short offset;
volatile short length;
volatile u_char dest[6];
@@ -330,12 +328,12 @@ struct TxParam
#define TX_RING_SIZE 2
/* Information that need to be kept for each board. */
struct arlan_private {
- struct arlan_shmem __iomem * card;
- struct arlan_shmem * conf;
+ struct arlan_shmem __iomem *card;
+ struct arlan_shmem *conf;
- struct arlan_conf_stru * Conf;
+ struct arlan_conf_stru *Conf;
int bad;
- int reset;
+ int reset;
unsigned long lastReset;
struct timer_list timer;
struct timer_list tx_delay_timer;
@@ -407,38 +405,38 @@ struct arlan_private {
#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer)
#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer)
-
-#define READSHM(to,from,atype) {\
+
+#define READSHM(to, from, atype) {\
atype tmp;\
- memcpy_fromio(&(tmp),&(from),sizeof(atype));\
+ memcpy_fromio(&(tmp), &(from), sizeof(atype));\
to = tmp;\
}
-#define READSHMEM(from,atype)\
+#define READSHMEM(from, atype)\
atype from; \
READSHM(from, arlan->from, atype);
-#define WRITESHM(to,from,atype) \
+#define WRITESHM(to, from, atype) \
{ atype tmpSHM = from;\
- memcpy_toio(&(to),&tmpSHM,sizeof(atype));\
+ memcpy_toio(&(to), &tmpSHM, sizeof(atype));\
}
-#define DEBUGSHM(levelSHM,stringSHM,stuff,atype) \
+#define DEBUGSHM(levelSHM, stringSHM, stuff, atype) \
{ atype tmpSHM; \
- memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\
- IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\
+ memcpy_fromio(&tmpSHM, &(stuff), sizeof(atype));\
+ IFDEBUG(levelSHM) printk(stringSHM, tmpSHM);\
}
#define WRITESHMB(to, val) \
- writeb(val,&(to))
+ writeb(val, &(to))
#define READSHMB(to) \
readb(&(to))
#define WRITESHMS(to, val) \
- writew(val,&(to))
+ writew(val, &(to))
#define READSHMS(to) \
readw(&(to))
#define WRITESHMI(to, val) \
- writel(val,&(to))
+ writel(val, &(to))
#define READSHMI(to) \
readl(&(to))
@@ -447,51 +445,51 @@ struct arlan_private {
#define registrationBad(dev)\
- ( ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \
- ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0) )
+ (( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \
+ ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0))
#define readControlRegister(dev)\
- READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
+ READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
-#define writeControlRegister(dev, v){\
- WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage ,((v) &0xF) );\
- WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister ,(v) );}
+#define writeControlRegister(dev, v) {\
+ WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage, ((v) & 0xF));\
+ WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister, (v)); }
#define arlan_interrupt_lancpu(dev) {\
int cr; \
\
cr = readControlRegister(dev);\
- if (cr & ARLAN_CHANNEL_ATTENTION){ \
+ if (cr & ARLAN_CHANNEL_ATTENTION) { \
writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\
- }else \
+ } else \
writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\
}
-#define clearChannelAttention(dev){ \
- writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);}
+#define clearChannelAttention(dev) { \
+ writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION); }
#define setHardwareReset(dev) {\
- writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);}
+ writeControlRegister(dev, readControlRegister(dev) | ARLAN_RESET); }
#define clearHardwareReset(dev) {\
- writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);}
-#define setInterruptEnable(dev){\
- writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ;}
-#define clearInterruptEnable(dev){\
- writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ;}
-#define setClearInterrupt(dev){\
- writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ;}
-#define clearClearInterrupt(dev){\
- writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);}
-#define setPowerOff(dev){\
- writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
- writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
-#define setPowerOn(dev){\
- writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER)); }
-#define arlan_lock_card_access(dev){\
- writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
-#define arlan_unlock_card_access(dev){\
- writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); }
+ writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_RESET); }
+#define setInterruptEnable(dev) {\
+ writeControlRegister(dev, readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ; }
+#define clearInterruptEnable(dev) {\
+ writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ; }
+#define setClearInterrupt(dev) {\
+ writeControlRegister(dev, readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ; }
+#define clearClearInterrupt(dev) {\
+ writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT); }
+#define setPowerOff(dev) {\
+ writeControlRegister(dev, readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
+ writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
+#define setPowerOn(dev) {\
+ writeControlRegister(dev, readControlRegister(dev) & ~(ARLAN_POWER)); }
+#define arlan_lock_card_access(dev) {\
+ writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
+#define arlan_unlock_card_access(dev) {\
+ writeControlRegister(dev, readControlRegister(dev) | ARLAN_ACCESS); }
@@ -525,7 +523,6 @@ struct arlan_private {
| ARLAN_COMMAND_RESET)
-
#define ARLAN_DEBUG_CHAIN_LOCKS 0x00001
#define ARLAN_DEBUG_RESET 0x00002
#define ARLAN_DEBUG_TIMING 0x00004
@@ -536,4 +533,3 @@ struct arlan_private {
#define ARLAN_DEBUG_INTERRUPT 0x00080
#define ARLAN_DEBUG_STARTUP 0x00100
#define ARLAN_DEBUG_SHUTDOWN 0x00200
-
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 43c57b7688a..7ebecc92c61 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -52,6 +52,10 @@
#define ASUS_OLED_DISP_HEIGHT 32
#define ASUS_OLED_PACKET_BUF_SIZE 256
+#define USB_VENDOR_ID_ASUS 0x0b05
+#define USB_DEVICE_ID_ASUS_LCM 0x1726
+#define USB_DEVICE_ID_ASUS_LCM2 0x175b
+
MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
MODULE_LICENSE("GPL");
@@ -83,18 +87,20 @@ struct oled_dev_desc_str {
};
/* table of devices that work with this driver */
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
/* Asus G1/G2 (and variants)*/
- { USB_DEVICE(0x0b05, 0x1726) },
+ { USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM) },
/* Asus G50V (and possibly others - G70? G71?)*/
- { USB_DEVICE(0x0b05, 0x175b) },
+ { USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2) },
{ },
};
/* parameters of specific devices */
static struct oled_dev_desc_str oled_dev_desc_table[] = {
- { 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" },
- { 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" },
+ { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, 128, PACK_MODE_G1,
+ "G1/G2" },
+ { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2, 256, PACK_MODE_G50,
+ "G50" },
{ },
};
@@ -424,6 +430,11 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev,
kfree(odev->buf);
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
+ if (odev->buf == NULL) {
+ odev->buf_size = 0;
+ printk(ASUS_OLED_ERROR "Out of memory!\n");
+ return -ENOMEM;
+ }
memset(odev->buf, 0xff, odev->buf_size);
@@ -759,13 +770,8 @@ static struct usb_driver oled_driver = {
.id_table = id_table,
};
-static ssize_t version_show(struct class *dev, char *buf)
-{
- return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n",
- ASUS_OLED_VERSION);
-}
-
-static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+static CLASS_ATTR_STRING(version, S_IRUGO,
+ ASUS_OLED_UNDERSCORE_NAME " " ASUS_OLED_VERSION);
static int __init asus_oled_init(void)
{
@@ -777,7 +783,7 @@ static int __init asus_oled_init(void)
return PTR_ERR(oled_class);
}
- retval = class_create_file(oled_class, &class_attr_version);
+ retval = class_create_file(oled_class, &class_attr_version.attr);
if (retval) {
err("Error creating class version file");
goto error;
@@ -799,7 +805,7 @@ error:
static void __exit asus_oled_exit(void)
{
- class_remove_file(oled_class, &class_attr_version);
+ class_remove_file(oled_class, &class_attr_version.attr);
class_destroy(oled_class);
usb_deregister(&oled_driver);
diff --git a/drivers/staging/b3dfg/Kconfig b/drivers/staging/b3dfg/Kconfig
deleted file mode 100644
index 9e6573cf97d..00000000000
--- a/drivers/staging/b3dfg/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config B3DFG
- tristate "Brontes 3d Frame Framegrabber"
- depends on PCI
- default n
- ---help---
- This driver provides support for the Brontes 3d Framegrabber
- PCI card.
-
- To compile this driver as a module, choose M here. The module
- will be called b3dfg.
diff --git a/drivers/staging/b3dfg/Makefile b/drivers/staging/b3dfg/Makefile
deleted file mode 100644
index 91f439ffc17..00000000000
--- a/drivers/staging/b3dfg/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_B3DFG) += b3dfg.o
diff --git a/drivers/staging/b3dfg/TODO b/drivers/staging/b3dfg/TODO
deleted file mode 100644
index f5a9298b9ac..00000000000
--- a/drivers/staging/b3dfg/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-
- - queue/wait buffer presents filltime results for each frame?
- - counting of dropped frames
- - review endianness
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
deleted file mode 100644
index 4a43c51c172..00000000000
--- a/drivers/staging/b3dfg/b3dfg.c
+++ /dev/null
@@ -1,1100 +0,0 @@
- /*
- * Brontes PCI frame grabber driver
- *
- * Copyright (C) 2008 3M Company
- * Contact: Justin Bronder <jsbronder@brontes3d.com>
- * Original Authors: Daniel Drake <ddrake@brontes3d.com>
- * Duane Griffin <duaneg@dghda.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/device.h>
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/ioctl.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <linux/cdev.h>
-#include <linux/list.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/uaccess.h>
-#include <linux/sched.h>
-
-static unsigned int b3dfg_nbuf = 2;
-
-module_param_named(buffer_count, b3dfg_nbuf, uint, 0444);
-
-MODULE_PARM_DESC(buffer_count, "Number of buffers (min 2, default 2)");
-
-MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>");
-MODULE_DESCRIPTION("Brontes frame grabber driver");
-MODULE_LICENSE("GPL");
-
-#define DRIVER_NAME "b3dfg"
-#define B3DFG_MAX_DEVS 4
-#define B3DFG_FRAMES_PER_BUFFER 3
-
-#define B3DFG_BAR_REGS 0
-#define B3DFG_REGS_LENGTH 0x10000
-
-#define B3DFG_IOC_MAGIC 0xb3 /* dfg :-) */
-#define B3DFG_IOCGFRMSZ _IOR(B3DFG_IOC_MAGIC, 1, int)
-#define B3DFG_IOCTNUMBUFS _IO(B3DFG_IOC_MAGIC, 2)
-#define B3DFG_IOCTTRANS _IO(B3DFG_IOC_MAGIC, 3)
-#define B3DFG_IOCTQUEUEBUF _IO(B3DFG_IOC_MAGIC, 4)
-#define B3DFG_IOCTPOLLBUF _IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll)
-#define B3DFG_IOCTWAITBUF _IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait)
-#define B3DFG_IOCGWANDSTAT _IOR(B3DFG_IOC_MAGIC, 7, int)
-
-enum {
- /* number of 4kb pages per frame */
- B3D_REG_FRM_SIZE = 0x0,
-
- /* bit 0: set to enable interrupts
- * bit 1: set to enable cable status change interrupts */
- B3D_REG_HW_CTRL = 0x4,
-
- /* bit 0-1 - 1-based ID of next pending frame transfer (0 = none)
- * bit 2 indicates the previous DMA transfer has completed
- * bit 3 indicates wand cable status change
- * bit 8:15 - counter of number of discarded triplets */
- B3D_REG_DMA_STS = 0x8,
-
- /* bit 0: wand status (1 = present, 0 = disconnected) */
- B3D_REG_WAND_STS = 0xc,
-
- /* bus address for DMA transfers. lower 2 bits must be zero because DMA
- * works with 32 bit word size. */
- B3D_REG_EC220_DMA_ADDR = 0x8000,
-
- /* bit 20:0 - number of 32 bit words to be transferred
- * bit 21:31 - reserved */
- B3D_REG_EC220_TRF_SIZE = 0x8004,
-
- /* bit 0 - error bit
- * bit 1 - interrupt bit (set to generate interrupt at end of transfer)
- * bit 2 - start bit (set to start transfer)
- * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE
- * bit 4:31 - reserved */
- B3D_REG_EC220_DMA_STS = 0x8008,
-};
-
-enum b3dfg_buffer_state {
- B3DFG_BUFFER_POLLED = 0,
- B3DFG_BUFFER_PENDING,
- B3DFG_BUFFER_POPULATED,
-};
-
-struct b3dfg_buffer {
- unsigned char *frame[B3DFG_FRAMES_PER_BUFFER];
- struct list_head list;
- u8 state;
-};
-
-struct b3dfg_dev {
-
- /* no protection needed: all finalized at initialization time */
- struct pci_dev *pdev;
- struct cdev chardev;
- struct device *dev;
- void __iomem *regs;
- unsigned int frame_size;
-
- /*
- * Protects buffer state, including buffer_queue, triplet_ready,
- * cur_dma_frame_idx & cur_dma_frame_addr.
- */
- spinlock_t buffer_lock;
- struct b3dfg_buffer *buffers;
- struct list_head buffer_queue;
-
- /* Last frame in triplet transferred (-1 if none). */
- int cur_dma_frame_idx;
-
- /* Current frame's address for DMA. */
- dma_addr_t cur_dma_frame_addr;
-
- /*
- * Protects cstate_tstamp.
- * Nests inside buffer_lock.
- */
- spinlock_t cstate_lock;
- unsigned long cstate_tstamp;
-
- /*
- * Protects triplets_dropped.
- * Nests inside buffers_lock.
- */
- spinlock_t triplets_dropped_lock;
- unsigned int triplets_dropped;
-
- wait_queue_head_t buffer_waitqueue;
-
- unsigned int transmission_enabled:1;
- unsigned int triplet_ready:1;
-};
-
-static u8 b3dfg_devices[B3DFG_MAX_DEVS];
-
-static struct class *b3dfg_class;
-static dev_t b3dfg_devt;
-
-static const struct pci_device_id b3dfg_ids[] __devinitdata = {
- { PCI_DEVICE(0x0b3d, 0x0001) },
- { },
-};
-
-MODULE_DEVICE_TABLE(pci, b3dfg_ids);
-
-/***** user-visible types *****/
-
-struct b3dfg_poll {
- int buffer_idx;
- unsigned int triplets_dropped;
-};
-
-struct b3dfg_wait {
- int buffer_idx;
- unsigned int timeout;
- unsigned int triplets_dropped;
-};
-
-/**** register I/O ****/
-
-static u32 b3dfg_read32(struct b3dfg_dev *fgdev, u16 reg)
-{
- return ioread32(fgdev->regs + reg);
-}
-
-static void b3dfg_write32(struct b3dfg_dev *fgdev, u16 reg, u32 value)
-{
- iowrite32(value, fgdev->regs + reg);
-}
-
-/**** buffer management ****/
-
-/*
- * Program EC220 for transfer of a specific frame.
- * Called with buffer_lock held.
- */
-static int setup_frame_transfer(struct b3dfg_dev *fgdev,
- struct b3dfg_buffer *buf, int frame)
-{
- unsigned char *frm_addr;
- dma_addr_t frm_addr_dma;
- unsigned int frm_size = fgdev->frame_size;
-
- frm_addr = buf->frame[frame];
- frm_addr_dma = pci_map_single(fgdev->pdev, frm_addr,
- frm_size, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(fgdev->pdev, frm_addr_dma))
- return -ENOMEM;
-
- fgdev->cur_dma_frame_addr = frm_addr_dma;
- fgdev->cur_dma_frame_idx = frame;
-
- b3dfg_write32(fgdev, B3D_REG_EC220_DMA_ADDR,
- cpu_to_le32(frm_addr_dma));
- b3dfg_write32(fgdev, B3D_REG_EC220_TRF_SIZE,
- cpu_to_le32(frm_size >> 2));
- b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0xf);
-
- return 0;
-}
-
-/* Caller should hold buffer lock */
-static void dequeue_all_buffers(struct b3dfg_dev *fgdev)
-{
- int i;
- for (i = 0; i < b3dfg_nbuf; i++) {
- struct b3dfg_buffer *buf = &fgdev->buffers[i];
- buf->state = B3DFG_BUFFER_POLLED;
- list_del_init(&buf->list);
- }
-}
-
-/* queue a buffer to receive data */
-static int queue_buffer(struct b3dfg_dev *fgdev, int bufidx)
-{
- struct device *dev = &fgdev->pdev->dev;
- struct b3dfg_buffer *buf;
- unsigned long flags;
- int r = 0;
-
- spin_lock_irqsave(&fgdev->buffer_lock, flags);
- if (bufidx < 0 || bufidx >= b3dfg_nbuf) {
- dev_dbg(dev, "Invalid buffer index, %d\n", bufidx);
- r = -ENOENT;
- goto out;
- }
- buf = &fgdev->buffers[bufidx];
-
- if (unlikely(buf->state == B3DFG_BUFFER_PENDING)) {
- dev_dbg(dev, "buffer %d is already queued\n", bufidx);
- r = -EINVAL;
- goto out;
- }
-
- buf->state = B3DFG_BUFFER_PENDING;
- list_add_tail(&buf->list, &fgdev->buffer_queue);
-
- if (fgdev->transmission_enabled && fgdev->triplet_ready) {
- dev_dbg(dev, "triplet is ready, pushing immediately\n");
- fgdev->triplet_ready = 0;
- r = setup_frame_transfer(fgdev, buf, 0);
- if (r)
- dev_err(dev, "unable to map DMA buffer\n");
- }
-
-out:
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
- return r;
-}
-
-/* non-blocking buffer poll. returns 1 if data is present in the buffer,
- * 0 otherwise */
-static int poll_buffer(struct b3dfg_dev *fgdev, void __user *arg)
-{
- struct device *dev = &fgdev->pdev->dev;
- struct b3dfg_poll p;
- struct b3dfg_buffer *buf;
- unsigned long flags;
- int r = 1;
- int arg_out = 0;
-
- if (copy_from_user(&p, arg, sizeof(p)))
- return -EFAULT;
-
- if (unlikely(!fgdev->transmission_enabled)) {
- dev_dbg(dev, "cannot poll, transmission disabled\n");
- return -EINVAL;
- }
-
- if (p.buffer_idx < 0 || p.buffer_idx >= b3dfg_nbuf)
- return -ENOENT;
-
- buf = &fgdev->buffers[p.buffer_idx];
-
- spin_lock_irqsave(&fgdev->buffer_lock, flags);
-
- if (likely(buf->state == B3DFG_BUFFER_POPULATED)) {
- arg_out = 1;
- buf->state = B3DFG_BUFFER_POLLED;
-
- /* IRQs already disabled by spin_lock_irqsave above. */
- spin_lock(&fgdev->triplets_dropped_lock);
- p.triplets_dropped = fgdev->triplets_dropped;
- fgdev->triplets_dropped = 0;
- spin_unlock(&fgdev->triplets_dropped_lock);
- } else {
- r = 0;
- }
-
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
- if (arg_out && copy_to_user(arg, &p, sizeof(p)))
- r = -EFAULT;
-
- return r;
-}
-
-static unsigned long get_cstate_change(struct b3dfg_dev *fgdev)
-{
- unsigned long flags, when;
-
- spin_lock_irqsave(&fgdev->cstate_lock, flags);
- when = fgdev->cstate_tstamp;
- spin_unlock_irqrestore(&fgdev->cstate_lock, flags);
- return when;
-}
-
-static int is_event_ready(struct b3dfg_dev *fgdev, struct b3dfg_buffer *buf,
- unsigned long when)
-{
- int result;
- unsigned long flags;
-
- spin_lock_irqsave(&fgdev->buffer_lock, flags);
- spin_lock(&fgdev->cstate_lock);
- result = (!fgdev->transmission_enabled ||
- buf->state == B3DFG_BUFFER_POPULATED ||
- when != fgdev->cstate_tstamp);
- spin_unlock(&fgdev->cstate_lock);
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
- return result;
-}
-
-/* sleep until a specific buffer becomes populated */
-static int wait_buffer(struct b3dfg_dev *fgdev, void __user *arg)
-{
- struct device *dev = &fgdev->pdev->dev;
- struct b3dfg_wait w;
- struct b3dfg_buffer *buf;
- unsigned long flags, when;
- int r;
-
- if (copy_from_user(&w, arg, sizeof(w)))
- return -EFAULT;
-
- if (!fgdev->transmission_enabled) {
- dev_dbg(dev, "cannot wait, transmission disabled\n");
- return -EINVAL;
- }
-
- if (w.buffer_idx < 0 || w.buffer_idx >= b3dfg_nbuf)
- return -ENOENT;
-
- buf = &fgdev->buffers[w.buffer_idx];
-
- spin_lock_irqsave(&fgdev->buffer_lock, flags);
-
- if (buf->state == B3DFG_BUFFER_POPULATED) {
- r = w.timeout;
- goto out_triplets_dropped;
- }
-
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
- when = get_cstate_change(fgdev);
- if (w.timeout > 0) {
- r = wait_event_interruptible_timeout(fgdev->buffer_waitqueue,
- is_event_ready(fgdev, buf, when),
- (w.timeout * HZ) / 1000);
-
- if (unlikely(r < 0))
- goto out;
-
- w.timeout = r * 1000 / HZ;
- } else {
- r = wait_event_interruptible(fgdev->buffer_waitqueue,
- is_event_ready(fgdev, buf, when));
-
- if (unlikely(r)) {
- r = -ERESTARTSYS;
- goto out;
- }
- }
-
- /* TODO: Inform the user via field(s) in w? */
- if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) {
- r = -EINVAL;
- goto out;
- }
-
- spin_lock_irqsave(&fgdev->buffer_lock, flags);
-
- if (buf->state != B3DFG_BUFFER_POPULATED) {
- r = -ETIMEDOUT;
- goto out_unlock;
- }
-
- buf->state = B3DFG_BUFFER_POLLED;
-
-out_triplets_dropped:
-
- /* IRQs already disabled by spin_lock_irqsave above. */
- spin_lock(&fgdev->triplets_dropped_lock);
- w.triplets_dropped = fgdev->triplets_dropped;
- fgdev->triplets_dropped = 0;
- spin_unlock(&fgdev->triplets_dropped_lock);
-
-out_unlock:
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
- if (copy_to_user(arg, &w, sizeof(w)))
- r = -EFAULT;
-out:
- return r;
-}
-
-/* mmap page fault handler */
-static int b3dfg_vma_fault(struct vm_area_struct *vma,
- struct vm_fault *vmf)
-{
- struct b3dfg_dev *fgdev = vma->vm_file->private_data;
- unsigned long off = vmf->pgoff << PAGE_SHIFT;
- unsigned int frame_size = fgdev->frame_size;
- unsigned int buf_size = frame_size * B3DFG_FRAMES_PER_BUFFER;
- unsigned char *addr;
-
- /* determine which buffer the offset lies within */
- unsigned int buf_idx = off / buf_size;
- /* and the offset into the buffer */
- unsigned int buf_off = off % buf_size;
-
- /* determine which frame inside the buffer the offset lies in */
- unsigned int frm_idx = buf_off / frame_size;
- /* and the offset into the frame */
- unsigned int frm_off = buf_off % frame_size;
-
- if (unlikely(buf_idx >= b3dfg_nbuf))
- return VM_FAULT_SIGBUS;
-
- addr = fgdev->buffers[buf_idx].frame[frm_idx] + frm_off;
- vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
- virt_to_phys(addr) >> PAGE_SHIFT);
-
- return VM_FAULT_NOPAGE;
-}
-
-static struct vm_operations_struct b3dfg_vm_ops = {
- .fault = b3dfg_vma_fault,
-};
-
-static int get_wand_status(struct b3dfg_dev *fgdev, int __user *arg)
-{
- u32 wndstat = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
- dev_dbg(&fgdev->pdev->dev, "wand status %x\n", wndstat);
- return __put_user(wndstat & 0x1, arg);
-}
-
-static int enable_transmission(struct b3dfg_dev *fgdev)
-{
- unsigned long flags;
- struct device *dev = &fgdev->pdev->dev;
-
- dev_dbg(dev, "enable transmission\n");
-
- /* check the cable is plugged in. */
- if (!b3dfg_read32(fgdev, B3D_REG_WAND_STS)) {
- dev_dbg(dev, "cannot start transmission without wand\n");
- return -EINVAL;
- }
-
- spin_lock_irqsave(&fgdev->buffer_lock, flags);
-
- /* Handle racing enable_transmission calls. */
- if (fgdev->transmission_enabled) {
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
- goto out;
- }
-
- spin_lock(&fgdev->triplets_dropped_lock);
- fgdev->triplets_dropped = 0;
- spin_unlock(&fgdev->triplets_dropped_lock);
-
- fgdev->triplet_ready = 0;
- fgdev->cur_dma_frame_idx = -1;
- fgdev->transmission_enabled = 1;
-
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
- /* Enable DMA and cable status interrupts. */
- b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0x03);
-
-out:
- return 0;
-}
-
-static void disable_transmission(struct b3dfg_dev *fgdev)
-{
- struct device *dev = &fgdev->pdev->dev;
- unsigned long flags;
- u32 tmp;
-
- dev_dbg(dev, "disable transmission\n");
-
- /* guarantee that no more interrupts will be serviced */
- spin_lock_irqsave(&fgdev->buffer_lock, flags);
- fgdev->transmission_enabled = 0;
-
- b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
-
- /* FIXME: temporary debugging only. if the board stops transmitting,
- * hitting ctrl+c and seeing this message is useful for determining
- * the state of the board. */
- tmp = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
- dev_dbg(dev, "DMA_STS reads %x after TX stopped\n", tmp);
-
- dequeue_all_buffers(fgdev);
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
- wake_up_interruptible(&fgdev->buffer_waitqueue);
-}
-
-static int set_transmission(struct b3dfg_dev *fgdev, int enabled)
-{
- int res = 0;
-
- if (enabled && !fgdev->transmission_enabled)
- res = enable_transmission(fgdev);
- else if (!enabled && fgdev->transmission_enabled)
- disable_transmission(fgdev);
-
- return res;
-}
-
-/* Called in interrupt context. */
-static void handle_cstate_unplug(struct b3dfg_dev *fgdev)
-{
- /* Disable all interrupts. */
- b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
-
- /* Stop transmission. */
- spin_lock(&fgdev->buffer_lock);
- fgdev->transmission_enabled = 0;
-
- fgdev->cur_dma_frame_idx = -1;
- fgdev->triplet_ready = 0;
- if (fgdev->cur_dma_frame_addr) {
- pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
- fgdev->frame_size, PCI_DMA_FROMDEVICE);
- fgdev->cur_dma_frame_addr = 0;
- }
- dequeue_all_buffers(fgdev);
- spin_unlock(&fgdev->buffer_lock);
-}
-
-/* Called in interrupt context. */
-static void handle_cstate_change(struct b3dfg_dev *fgdev)
-{
- u32 cstate = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
- unsigned long when;
- struct device *dev = &fgdev->pdev->dev;
-
- dev_dbg(dev, "cable state change: %u\n", cstate);
-
- /*
- * When the wand is unplugged we reset our state. The hardware will
- * have done the same internally.
- *
- * Note we should never see a cable *plugged* event, as interrupts
- * should only be enabled when transmitting, which requires the cable
- * to be plugged. If we do see one it probably means the cable has been
- * unplugged and re-plugged very rapidly. Possibly because it has a
- * broken wire and is momentarily losing contact.
- *
- * TODO: At the moment if you plug in the cable then enable transmission
- * the hardware will raise a couple of spurious interrupts, so
- * just ignore them for now.
- *
- * Once the hardware is fixed we should complain and treat it as an
- * unplug. Or at least track how frequently it is happening and do
- * so if too many come in.
- */
- if (cstate) {
- dev_warn(dev, "ignoring unexpected plug event\n");
- return;
- }
- handle_cstate_unplug(fgdev);
-
- /*
- * Record cable state change timestamp & wake anyone waiting
- * on a cable state change. Be paranoid about ensuring events
- * are not missed if we somehow get two interrupts in a jiffy.
- */
- spin_lock(&fgdev->cstate_lock);
- when = jiffies_64;
- if (when <= fgdev->cstate_tstamp)
- when = fgdev->cstate_tstamp + 1;
- fgdev->cstate_tstamp = when;
- wake_up_interruptible(&fgdev->buffer_waitqueue);
- spin_unlock(&fgdev->cstate_lock);
-}
-
-/* Called with buffer_lock held. */
-static void transfer_complete(struct b3dfg_dev *fgdev)
-{
- struct b3dfg_buffer *buf;
- struct device *dev = &fgdev->pdev->dev;
-
- pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
- fgdev->frame_size, PCI_DMA_FROMDEVICE);
- fgdev->cur_dma_frame_addr = 0;
-
- buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
-
- dev_dbg(dev, "handle frame completion\n");
- if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
-
- /* last frame of that triplet completed */
- dev_dbg(dev, "triplet completed\n");
- buf->state = B3DFG_BUFFER_POPULATED;
- list_del_init(&buf->list);
- wake_up_interruptible(&fgdev->buffer_waitqueue);
- }
-}
-
-/*
- * Called with buffer_lock held.
- *
- * Note that idx is the (1-based) *next* frame to be transferred, while
- * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or
- * -1 if none). Thus there should be a difference of 2 between them.
- */
-static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
-{
- struct b3dfg_buffer *buf;
- struct device *dev = &fgdev->pdev->dev;
- bool need_ack = 1;
-
- dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx);
-
- buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
- if (idx == fgdev->cur_dma_frame_idx + 2) {
- if (setup_frame_transfer(fgdev, buf, idx - 1))
- dev_err(dev, "unable to map DMA buffer\n");
- need_ack = 0;
- } else {
- dev_err(dev, "frame mismatch, got %d, expected %d\n",
- idx, fgdev->cur_dma_frame_idx + 2);
-
- /* FIXME: handle dropped triplets here */
- }
-
- return need_ack;
-}
-
-static irqreturn_t b3dfg_intr(int irq, void *dev_id)
-{
- struct b3dfg_dev *fgdev = dev_id;
- struct device *dev = &fgdev->pdev->dev;
- u32 sts;
- u8 dropped;
- bool need_ack = 1;
- irqreturn_t res = IRQ_HANDLED;
-
- sts = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
- if (unlikely(sts == 0)) {
- dev_warn(dev, "ignore interrupt, DMA status is 0\n");
- res = IRQ_NONE;
- goto out;
- }
-
- if (unlikely(!fgdev->transmission_enabled)) {
- dev_warn(dev, "ignore interrupt, TX disabled\n");
- res = IRQ_HANDLED;
- goto out;
- }
-
- /* Handle dropped frames, as reported by the hardware. */
- dropped = (sts >> 8) & 0xff;
- dev_dbg(dev, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n",
- sts, dropped, !!(sts & 0x4), sts & 0x3);
- if (unlikely(dropped > 0)) {
- spin_lock(&fgdev->triplets_dropped_lock);
- fgdev->triplets_dropped += dropped;
- spin_unlock(&fgdev->triplets_dropped_lock);
- }
-
- /* Handle a cable state change (i.e. the wand being unplugged). */
- if (sts & 0x08) {
- handle_cstate_change(fgdev);
- goto out;
- }
-
- spin_lock(&fgdev->buffer_lock);
- if (unlikely(list_empty(&fgdev->buffer_queue))) {
-
- /* FIXME need more sanity checking here */
- dev_info(dev, "buffer not ready for next transfer\n");
- fgdev->triplet_ready = 1;
- goto out_unlock;
- }
-
- /* Has a frame transfer been completed? */
- if (sts & 0x4) {
- u32 dma_status = b3dfg_read32(fgdev, B3D_REG_EC220_DMA_STS);
-
- /* Check for DMA errors reported by the hardware. */
- if (unlikely(dma_status & 0x1)) {
- dev_err(dev, "EC220 error: %08x\n", dma_status);
-
- /* FIXME flesh out error handling */
- goto out_unlock;
- }
-
- /* Sanity check, we should have a frame index at this point. */
- if (unlikely(fgdev->cur_dma_frame_idx == -1)) {
- dev_err(dev, "completed but no last idx?\n");
-
- /* FIXME flesh out error handling */
- goto out_unlock;
- }
-
- transfer_complete(fgdev);
- }
-
- /* Is there another frame transfer pending? */
- if (sts & 0x3)
- need_ack = setup_next_frame_transfer(fgdev, sts & 0x3);
- else
- fgdev->cur_dma_frame_idx = -1;
-
-out_unlock:
- spin_unlock(&fgdev->buffer_lock);
-out:
- if (need_ack) {
- dev_dbg(dev, "acknowledging interrupt\n");
- b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0x0b);
- }
- return res;
-}
-
-static int b3dfg_open(struct inode *inode, struct file *filp)
-{
- struct b3dfg_dev *fgdev =
- container_of(inode->i_cdev, struct b3dfg_dev, chardev);
-
- dev_dbg(&fgdev->pdev->dev, "open\n");
- filp->private_data = fgdev;
- return 0;
-}
-
-static int b3dfg_release(struct inode *inode, struct file *filp)
-{
- struct b3dfg_dev *fgdev = filp->private_data;
- dev_dbg(&fgdev->pdev->dev, "release\n");
- disable_transmission(fgdev);
- return 0;
-}
-
-static long b3dfg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- struct b3dfg_dev *fgdev = filp->private_data;
-
- switch (cmd) {
- case B3DFG_IOCGFRMSZ:
- return __put_user(fgdev->frame_size, (int __user *) arg);
- case B3DFG_IOCGWANDSTAT:
- return get_wand_status(fgdev, (int __user *) arg);
- case B3DFG_IOCTTRANS:
- return set_transmission(fgdev, (int) arg);
- case B3DFG_IOCTQUEUEBUF:
- return queue_buffer(fgdev, (int) arg);
- case B3DFG_IOCTPOLLBUF:
- return poll_buffer(fgdev, (void __user *) arg);
- case B3DFG_IOCTWAITBUF:
- return wait_buffer(fgdev, (void __user *) arg);
- default:
- dev_dbg(&fgdev->pdev->dev, "unrecognised ioctl %x\n", cmd);
- return -EINVAL;
- }
-}
-
-static unsigned int b3dfg_poll(struct file *filp, poll_table *poll_table)
-{
- struct b3dfg_dev *fgdev = filp->private_data;
- unsigned long flags, when;
- int i;
- int r = 0;
-
- when = get_cstate_change(fgdev);
- poll_wait(filp, &fgdev->buffer_waitqueue, poll_table);
-
- spin_lock_irqsave(&fgdev->buffer_lock, flags);
- for (i = 0; i < b3dfg_nbuf; i++) {
- if (fgdev->buffers[i].state == B3DFG_BUFFER_POPULATED) {
- r = POLLIN | POLLRDNORM;
- break;
- }
- }
- spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
-
- /* TODO: Confirm this is how we want to communicate the change. */
- if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev))
- r = POLLERR;
-
- return r;
-}
-
-static int b3dfg_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct b3dfg_dev *fgdev = filp->private_data;
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long vsize = vma->vm_end - vma->vm_start;
- unsigned long bufdatalen = b3dfg_nbuf * fgdev->frame_size * 3;
- unsigned long psize = bufdatalen - offset;
- int r = 0;
-
- if (vsize <= psize) {
- vma->vm_flags |= VM_IO | VM_RESERVED | VM_CAN_NONLINEAR |
- VM_PFNMAP;
- vma->vm_ops = &b3dfg_vm_ops;
- } else {
- r = -EINVAL;
- }
-
- return r;
-}
-
-static struct file_operations b3dfg_fops = {
- .owner = THIS_MODULE,
- .open = b3dfg_open,
- .release = b3dfg_release,
- .unlocked_ioctl = b3dfg_ioctl,
- .poll = b3dfg_poll,
- .mmap = b3dfg_mmap,
-};
-
-static void free_all_frame_buffers(struct b3dfg_dev *fgdev)
-{
- int i, j;
- for (i = 0; i < b3dfg_nbuf; i++)
- for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++)
- kfree(fgdev->buffers[i].frame[j]);
- kfree(fgdev->buffers);
-}
-
-/* initialize device and any data structures. called before any interrupts
- * are enabled. */
-static int b3dfg_init_dev(struct b3dfg_dev *fgdev)
-{
- int i, j;
- u32 frm_size = b3dfg_read32(fgdev, B3D_REG_FRM_SIZE);
-
- /* Disable interrupts. In abnormal circumstances (e.g. after a crash)
- * the board may still be transmitting from the previous session. If we
- * ensure that interrupts are disabled before we later enable them, we
- * are sure to capture a triplet from the start, rather than starting
- * from frame 2 or 3. Disabling interrupts causes the FG to throw away
- * all buffered data and stop buffering more until interrupts are
- * enabled again.
- */
- b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
-
- fgdev->frame_size = frm_size * 4096;
- fgdev->buffers = kzalloc(sizeof(struct b3dfg_buffer) * b3dfg_nbuf,
- GFP_KERNEL);
- if (!fgdev->buffers)
- goto err_no_buf;
- for (i = 0; i < b3dfg_nbuf; i++) {
- struct b3dfg_buffer *buf = &fgdev->buffers[i];
- for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) {
- buf->frame[j] = kmalloc(fgdev->frame_size, GFP_KERNEL);
- if (!buf->frame[j])
- goto err_no_mem;
- }
- INIT_LIST_HEAD(&buf->list);
- }
-
- INIT_LIST_HEAD(&fgdev->buffer_queue);
- init_waitqueue_head(&fgdev->buffer_waitqueue);
- spin_lock_init(&fgdev->buffer_lock);
- spin_lock_init(&fgdev->cstate_lock);
- spin_lock_init(&fgdev->triplets_dropped_lock);
- return 0;
-
-err_no_mem:
- free_all_frame_buffers(fgdev);
-err_no_buf:
- return -ENOMEM;
-}
-
-/* find next free minor number, returns -1 if none are availabile */
-static int get_free_minor(void)
-{
- int i;
- for (i = 0; i < B3DFG_MAX_DEVS; i++) {
- if (b3dfg_devices[i] == 0)
- return i;
- }
- return -1;
-}
-
-static int __devinit b3dfg_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- struct b3dfg_dev *fgdev = kzalloc(sizeof(*fgdev), GFP_KERNEL);
- int r = 0;
- int minor = get_free_minor();
- dev_t devno = MKDEV(MAJOR(b3dfg_devt), minor);
- unsigned long res_len;
- resource_size_t res_base;
-
- if (fgdev == NULL)
- return -ENOMEM;
-
- if (minor < 0) {
- dev_err(&pdev->dev, "too many devices found!\n");
- r = -EIO;
- goto err_free;
- }
-
- b3dfg_devices[minor] = 1;
- dev_info(&pdev->dev, "probe device with IRQ %d\n", pdev->irq);
-
- cdev_init(&fgdev->chardev, &b3dfg_fops);
- fgdev->chardev.owner = THIS_MODULE;
-
- r = cdev_add(&fgdev->chardev, devno, 1);
- if (r) {
- dev_err(&pdev->dev, "cannot add char device\n");
- goto err_release_minor;
- }
-
- fgdev->dev = device_create(
- b3dfg_class,
- &pdev->dev,
- devno,
- dev_get_drvdata(&pdev->dev),
- DRIVER_NAME "%d", minor);
-
- if (IS_ERR(fgdev->dev)) {
- dev_err(&pdev->dev, "cannot create device\n");
- r = PTR_ERR(fgdev->dev);
- goto err_del_cdev;
- }
-
- r = pci_enable_device(pdev);
- if (r) {
- dev_err(&pdev->dev, "cannot enable PCI device\n");
- goto err_dev_unreg;
- }
-
- res_len = pci_resource_len(pdev, B3DFG_BAR_REGS);
- if (res_len != B3DFG_REGS_LENGTH) {
- dev_err(&pdev->dev, "invalid register resource size\n");
- r = -EIO;
- goto err_disable;
- }
-
- if (pci_resource_flags(pdev, B3DFG_BAR_REGS)
- != (IORESOURCE_MEM | IORESOURCE_SIZEALIGN)) {
- dev_err(&pdev->dev, "invalid resource flags\n");
- r = -EIO;
- goto err_disable;
- }
- r = pci_request_regions(pdev, DRIVER_NAME);
- if (r) {
- dev_err(&pdev->dev, "cannot obtain PCI resources\n");
- goto err_disable;
- }
-
- pci_set_master(pdev);
-
- r = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (r) {
- dev_err(&pdev->dev, "no usable DMA configuration\n");
- goto err_free_res;
- }
-
- res_base = pci_resource_start(pdev, B3DFG_BAR_REGS);
- fgdev->regs = ioremap_nocache(res_base, res_len);
- if (!fgdev->regs) {
- dev_err(&pdev->dev, "regs ioremap failed\n");
- r = -EIO;
- goto err_free_res;
- }
-
- fgdev->pdev = pdev;
- pci_set_drvdata(pdev, fgdev);
- r = b3dfg_init_dev(fgdev);
- if (r < 0) {
- dev_err(&pdev->dev, "failed to initalize device\n");
- goto err_unmap;
- }
-
- r = request_irq(pdev->irq, b3dfg_intr, IRQF_SHARED, DRIVER_NAME, fgdev);
- if (r) {
- dev_err(&pdev->dev, "couldn't request irq %d\n", pdev->irq);
- goto err_free_bufs;
- }
-
- return 0;
-
-err_free_bufs:
- free_all_frame_buffers(fgdev);
-err_unmap:
- iounmap(fgdev->regs);
-err_free_res:
- pci_release_regions(pdev);
-err_disable:
- pci_disable_device(pdev);
-err_dev_unreg:
- device_destroy(b3dfg_class, devno);
-err_del_cdev:
- cdev_del(&fgdev->chardev);
-err_release_minor:
- b3dfg_devices[minor] = 0;
-err_free:
- kfree(fgdev);
- return r;
-}
-
-static void __devexit b3dfg_remove(struct pci_dev *pdev)
-{
- struct b3dfg_dev *fgdev = pci_get_drvdata(pdev);
- unsigned int minor = MINOR(fgdev->chardev.dev);
-
- dev_dbg(&pdev->dev, "remove\n");
-
- free_irq(pdev->irq, fgdev);
- iounmap(fgdev->regs);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- device_destroy(b3dfg_class, MKDEV(MAJOR(b3dfg_devt), minor));
- cdev_del(&fgdev->chardev);
- free_all_frame_buffers(fgdev);
- kfree(fgdev);
- b3dfg_devices[minor] = 0;
-}
-
-static struct pci_driver b3dfg_driver = {
- .name = DRIVER_NAME,
- .id_table = b3dfg_ids,
- .probe = b3dfg_probe,
- .remove = __devexit_p(b3dfg_remove),
-};
-
-static int __init b3dfg_module_init(void)
-{
- int r;
-
- if (b3dfg_nbuf < 2) {
- printk(KERN_ERR DRIVER_NAME
- ": buffer_count is out of range (must be >= 2)");
- return -EINVAL;
- }
-
- printk(KERN_INFO DRIVER_NAME ": loaded\n");
-
- b3dfg_class = class_create(THIS_MODULE, DRIVER_NAME);
- if (IS_ERR(b3dfg_class))
- return PTR_ERR(b3dfg_class);
-
- r = alloc_chrdev_region(&b3dfg_devt, 0, B3DFG_MAX_DEVS, DRIVER_NAME);
- if (r)
- goto err1;
-
- r = pci_register_driver(&b3dfg_driver);
- if (r)
- goto err2;
-
- return r;
-
-err2:
- unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
-err1:
- class_destroy(b3dfg_class);
- return r;
-}
-
-static void __exit b3dfg_module_exit(void)
-{
- printk(KERN_INFO DRIVER_NAME ": unloaded\n");
- pci_unregister_driver(&b3dfg_driver);
- unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
- class_destroy(b3dfg_class);
-}
-
-module_init(b3dfg_module_init);
-module_exit(b3dfg_module_exit);
diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig
index 1d74dabf951..1e7e0a8dbc8 100644
--- a/drivers/staging/batman-adv/Kconfig
+++ b/drivers/staging/batman-adv/Kconfig
@@ -4,7 +4,7 @@
config BATMAN_ADV
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
- depends on PROC_FS && PACKET
+ depends on PROC_FS && NET
default n
---help---
@@ -14,10 +14,10 @@ config BATMAN_ADV
http://www.open-mesh.org/ for more information and user space
tools.
-config BATMAN_DEBUG
+config BATMAN_ADV_DEBUG
bool "B.A.T.M.A.N. debugging"
depends on BATMAN_ADV != n
- help
+ ---help---
This is an option for use by developers; most people should
say N here. This enables compilation of support for
diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile
index 02da87134fc..42b4e637026 100644
--- a/drivers/staging/batman-adv/Makefile
+++ b/drivers/staging/batman-adv/Makefile
@@ -19,4 +19,4 @@
#
obj-m += batman-adv.o
-batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o log.o
+batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o
diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README
index 3aaf393ebaa..7d666ad0435 100644
--- a/drivers/staging/batman-adv/README
+++ b/drivers/staging/batman-adv/README
@@ -1,4 +1,4 @@
-[state: 07-11-2009]
+[state: 06-01-2010]
BATMAN-ADV
----------
@@ -15,19 +15,6 @@ above B.A.T.M.A.N. Advanced, prominent examples are: IPv4, IPv6, DHCP, IPX.
This is batman-advanced implemented as Linux kernel driver. It does not depend
on any network (other) driver, and can be used on wifi as well as ethernet,
vpn, etc ... (anything with ethernet-style layer 2).
-It compiles against and should work with Linux 2.6.20 - 2.6.31. Supporting older
-versions is not planned, but it's probably easy to backport it. If you work on a
-backport, feel free to contact us. :-)
-
-COMPILE
--------
-To compile against your currently installed kernel, just type:
-
-# make
-
-if you want to compile against some other kernel, use:
-
-# make KERNELPATH=/path/to/kernel
USAGE
-----
@@ -73,16 +60,9 @@ When configured as server, you can get a topology snapshot of your mesh:
# cat /proc/net/batman-adv/vis
-This output format is a graphviz formatted text file which can be
-processed with graphviz-tools like dot.
-The labels are similar/compatible to the ETX metric, 1.0 means perfect
-connection (100%), 2.0 means 50%, 3.0 means 33% and so on.
-
-Alternatively, a JSON output format is available. The format can be set
-using by writing either "dot_draw" or "json" into the vis_format file.
-"dot_draw" is selected by default.
-
-echo "json" > /proc/net/batman-adv/vis_format
+The output is in a generic raw format. Use the batctl tool (See below)
+to convert this to other formats more suitable for graphing, eg
+graphviz dot, or JSON data-interchange format.
In very mobile scenarios, you might want to adjust the originator
interval to a lower value. This will make the mesh more responsive to
@@ -96,15 +76,59 @@ To deactivate batman, do:
# echo "" > /proc/net/batman-adv/interfaces
+LOGGING/DEBUGGING
+-----------------
+
+All error messages, warnings and information messages are sent to the
+kernel log. Depending on your operating system distribution this can be
+read in one of a number of ways. Try using the commands: dmesg,
+logread, or looking in the files /var/log/kern.log or
+/var/log/syslog. All batman-adv messages are prefixed with
+"batman-adv:" So to see just these messages try
+
+dmesg | grep batman-adv
+
+When investigating problems with your mesh network it is sometimes
+necessary to see more detail debug messages. This must be enabled when
+compiling the batman-adv module. Use "make menuconfig" and enable the
+option "B.A.T.M.A.N. debugging".
+
+The additional debug output is by default disabled. It can be enabled
+either at kernel module load time or during run time. To enable debug
+output at module load time, add the module parameter debug=<value>.
+<value> can take one of four values.
+
+0 - All debug output disabled
+1 - Enable messages related to routing / flooding / broadcasting
+2 - Enable route or hna added / changed / deleted
+3 - Enable all messages
+
+e.g.
+
+modprobe batman-adv debug=2
+
+will load the module and enable debug messages for when routes or HNAs
+change.
+
+The debug output can also be changed at runtime using the file
+/sys/module/batman-adv/parameters/debug. e.g.
+
+echo 2 > /sys/module/batman-adv/parameters/debug
+
+enables debug messages for when routes or HNAs
+
+The debug output is sent to the kernel logs. So try dmesg, logread etc
+to see the debug messages.
+
BATCTL
------
-B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts partici-
-pating in the virtual switch are completely transparent for all proto-
-cols above layer 2. Therefore the common diagnosis tools do not work as
-expected. To overcome these problems batctl was created. At the moment
-the batctl contains ping, traceroute, tcpdump and interfaces to the
-kernel module settings.
+B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts
+participating in the virtual switch are completely transparent for all
+protocols above layer 2. Therefore the common diagnosis tools do not
+work as expected. To overcome these problems batctl was created. At
+the moment the batctl contains ping, traceroute, tcpdump and
+interfaces to the kernel module settings.
For more information, please see the manpage (man batctl).
diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO
index ea6dcf94d66..2f15136b18e 100644
--- a/drivers/staging/batman-adv/TODO
+++ b/drivers/staging/batman-adv/TODO
@@ -17,30 +17,6 @@
-> transtable_global (read-only) [outputs the global translation table]
-> transtable_local (read-only) [outputs the local translation table]
-=> vis "raw" data output
-* the raw format shall replace dot draw / json to offer a neutral that can
-* be converted
-* the format (comma seperated entries):
--> "mac" -> mac address of an originator (each line begins with it)
--> "TQ mac value" -> src mac's link quality towards mac address
--> "HNA mac" -> HNA announced by source mac
--> "PRIMARY" -> this is a primary interface
--> "SEC mac" -> secondary mac address of source (requires preceeding
--> PRIMARY)
-
-=> logging
-* the log level LOG_TYPE_CRIT, LOG_TYPE_WARN & LOG_TYPE_NOTICE will be
-* unified to use printk
-* LOG_TYPE_BATMAN & LOG_TYPE_ROUTES will also use printk but only after the
-* internal debug level has been raised
-* the internal debug level can be modified using a module parameter (debug)
-* or at run time via /sys/module/batman-adv/parameters/debug
-* make use of printk %pM support instead of converting mac addresses
-* manually
-
-=> strip out all backward compatibility support to older kernels
- (only found in compat.h)
-
=> fix checkpatch.pl errors
Please send all patches to:
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c
index 9c6e681f6fb..7917322a7e2 100644
--- a/drivers/staging/batman-adv/aggregation.c
+++ b/drivers/staging/batman-adv/aggregation.c
@@ -96,6 +96,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
int own_packet)
{
struct forw_packet *forw_packet_aggr;
+ unsigned long flags;
forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
if (!forw_packet_aggr)
@@ -115,6 +116,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
packet_buff,
forw_packet_aggr->packet_len);
+ forw_packet_aggr->skb = NULL;
forw_packet_aggr->own = own_packet;
forw_packet_aggr->if_incoming = if_incoming;
forw_packet_aggr->num_packets = 0;
@@ -126,9 +128,9 @@ static void new_aggregated_packet(unsigned char *packet_buff,
forw_packet_aggr->direct_link_flags |= 1;
/* add new packet to packet list */
- spin_lock(&forw_bat_list_lock);
+ spin_lock_irqsave(&forw_bat_list_lock, flags);
hlist_add_head(&forw_packet_aggr->list, &forw_bat_list);
- spin_unlock(&forw_bat_list_lock);
+ spin_unlock_irqrestore(&forw_bat_list_lock, flags);
/* start timer for this packet */
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
@@ -168,9 +170,10 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
struct batman_packet *batman_packet =
(struct batman_packet *)packet_buff;
bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
+ unsigned long flags;
/* find position for the packet in the forward queue */
- spin_lock(&forw_bat_list_lock);
+ spin_lock_irqsave(&forw_bat_list_lock, flags);
/* own packets are not to be aggregated */
if ((atomic_read(&aggregation_enabled)) && (!own_packet)) {
hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list,
@@ -191,7 +194,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
* suitable aggregation packet found */
if (forw_packet_aggr == NULL) {
/* the following section can run without the lock */
- spin_unlock(&forw_bat_list_lock);
+ spin_unlock_irqrestore(&forw_bat_list_lock, flags);
new_aggregated_packet(packet_buff, packet_len,
send_time, direct_link,
if_incoming, own_packet);
@@ -199,7 +202,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
aggregate(forw_packet_aggr,
packet_buff, packet_len,
direct_link);
- spin_unlock(&forw_bat_list_lock);
+ spin_unlock_irqrestore(&forw_bat_list_lock, flags);
}
}
diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c
index 3c67f5f42b2..212eef93afe 100644
--- a/drivers/staging/batman-adv/bitarray.c
+++ b/drivers/staging/batman-adv/bitarray.c
@@ -21,7 +21,6 @@
#include "main.h"
#include "bitarray.h"
-#include "log.h"
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
@@ -80,8 +79,8 @@ void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
* from.
*
* left is high, right is low: FEDC BA98 7654 3210
- * ^^ ^^
- * vvvv
+ * ^^ ^^
+ * vvvv
* ^^^^ = from, vvvvv =to, we'd have word_num==1 and
* word_offset==WORD_BIT_SIZE/2 ????? in this example.
* (=24 bits)
@@ -133,13 +132,13 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
(seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) {
if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
- debug_log(LOG_TYPE_BATMAN,
- "We missed a lot of packets (%i) !\n",
- seq_num_diff-1);
+ bat_dbg(DBG_BATMAN,
+ "We missed a lot of packets (%i) !\n",
+ seq_num_diff-1);
if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
- debug_log(LOG_TYPE_BATMAN,
- "Other host probably restarted !\n");
+ bat_dbg(DBG_BATMAN,
+ "Other host probably restarted !\n");
for (i = 0; i < NUM_WORDS; i++)
seq_bits[i] = 0;
diff --git a/drivers/staging/batman-adv/compat.h b/drivers/staging/batman-adv/compat.h
deleted file mode 100644
index f4e0a4564ba..00000000000
--- a/drivers/staging/batman-adv/compat.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This program 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.
- *
- * This program is distributed in 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
- *
- *
- * This file contains macros for maintaining compatibility with older versions
- * of the Linux kernel.
- */
-
-#include <linux/version.h> /* LINUX_VERSION_CODE */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
-
-#define skb_set_network_header(_skb, _offset) \
- do { (_skb)->nh.raw = (_skb)->data + (_offset); } while (0)
-
-#define skb_reset_mac_header(_skb) \
- do { (_skb)->mac.raw = (_skb)->data; } while (0)
-
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) */
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
-
-#define device_create(_cls, _parent, _devt, _device, _fmt) \
- class_device_create(_cls, _parent, _devt, _device, _fmt)
-
-#define device_destroy(_cls, _device) \
- class_device_destroy(_cls, _device)
-
-#else
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
-
-#define device_create(_cls, _parent, _devt, _device, _fmt) \
- device_create_drvdata(_cls, _parent, _devt, _device, _fmt)
-
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) */
-
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
-
-#define cancel_delayed_work_sync(wq) cancel_rearming_delayed_work(wq)
-
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
-#define strict_strtoul(cp, base, res) \
- ({ \
- int ret = 0; \
- char *endp; \
- *res = simple_strtoul(cp, &endp, base); \
- if (cp == endp) \
- ret = -EINVAL; \
- ret; \
-})
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c
index 1e7d1f88674..2f61500186f 100644
--- a/drivers/staging/batman-adv/device.c
+++ b/drivers/staging/batman-adv/device.c
@@ -19,14 +19,14 @@
*
*/
+#include <linux/device.h>
+#include <linux/slab.h>
#include "main.h"
#include "device.h"
-#include "log.h"
#include "send.h"
#include "types.h"
#include "hash.h"
-
-#include "compat.h"
+#include "hard-interface.h"
static struct class *batman_class;
@@ -60,7 +60,7 @@ int bat_device_setup(void)
/* register our device - kernel assigns a free major number */
tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
if (tmp_major < 0) {
- debug_log(LOG_TYPE_WARN, "Registering the character device failed with %d\n",
+ printk(KERN_ERR "batman-adv:Registering the character device failed with %d\n",
tmp_major);
return 0;
}
@@ -68,7 +68,7 @@ int bat_device_setup(void)
batman_class = class_create(THIS_MODULE, "batman-adv");
if (IS_ERR(batman_class)) {
- debug_log(LOG_TYPE_WARN, "Could not register class 'batman-adv' \n");
+ printk(KERN_ERR "batman-adv:Could not register class 'batman-adv' \n");
return 0;
}
@@ -111,7 +111,7 @@ int bat_device_open(struct inode *inode, struct file *file)
}
if (device_client_hash[i] != device_client) {
- debug_log(LOG_TYPE_WARN, "Error - can't add another packet client: maximum number of clients reached \n");
+ printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached \n");
kfree(device_client);
return -EXFULL;
}
@@ -119,7 +119,7 @@ int bat_device_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&device_client->queue_list);
device_client->queue_len = 0;
device_client->index = i;
- device_client->lock = __SPIN_LOCK_UNLOCKED(device_client->lock);
+ spin_lock_init(&device_client->lock);
init_waitqueue_head(&device_client->queue_wait);
file->private_data = device_client;
@@ -134,8 +134,9 @@ int bat_device_release(struct inode *inode, struct file *file)
(struct device_client *)file->private_data;
struct device_packet *device_packet;
struct list_head *list_pos, *list_pos_tmp;
+ unsigned long flags;
- spin_lock(&device_client->lock);
+ spin_lock_irqsave(&device_client->lock, flags);
/* for all packets in the queue ... */
list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) {
@@ -147,7 +148,7 @@ int bat_device_release(struct inode *inode, struct file *file)
}
device_client_hash[device_client->index] = NULL;
- spin_unlock(&device_client->lock);
+ spin_unlock_irqrestore(&device_client->lock, flags);
kfree(device_client);
dec_module_count();
@@ -162,6 +163,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
(struct device_client *)file->private_data;
struct device_packet *device_packet;
int error;
+ unsigned long flags;
if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0))
return -EAGAIN;
@@ -178,14 +180,14 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
if (error)
return error;
- spin_lock(&device_client->lock);
+ spin_lock_irqsave(&device_client->lock, flags);
device_packet = list_first_entry(&device_client->queue_list,
struct device_packet, list);
list_del(&device_packet->list);
device_client->queue_len--;
- spin_unlock(&device_client->lock);
+ spin_unlock_irqrestore(&device_client->lock, flags);
error = __copy_to_user(buf, &device_packet->icmp_packet,
sizeof(struct icmp_packet));
@@ -206,9 +208,11 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
struct icmp_packet icmp_packet;
struct orig_node *orig_node;
struct batman_if *batman_if;
+ uint8_t dstaddr[ETH_ALEN];
+ unsigned long flags;
if (len < sizeof(struct icmp_packet)) {
- debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: invalid packet size\n");
+ bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: invalid packet size\n");
return -EINVAL;
}
@@ -219,12 +223,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
return -EFAULT;
if (icmp_packet.packet_type != BAT_ICMP) {
- debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
+ bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
return -EINVAL;
}
if (icmp_packet.msg_type != ECHO_REQUEST) {
- debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
+ bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
return -EINVAL;
}
@@ -240,7 +244,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
if (atomic_read(&module_state) != MODULE_ACTIVE)
goto dst_unreach;
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
if (!orig_node)
@@ -250,9 +254,15 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
goto unlock;
batman_if = orig_node->batman_if;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
if (!batman_if)
- goto unlock;
+ goto dst_unreach;
+
+ if (batman_if->if_active != IF_ACTIVE)
+ goto dst_unreach;
memcpy(icmp_packet.orig,
batman_if->net_dev->dev_addr,
@@ -260,13 +270,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
send_raw_packet((unsigned char *)&icmp_packet,
sizeof(struct icmp_packet),
- batman_if, orig_node->router->addr);
+ batman_if, dstaddr);
- spin_unlock(&orig_hash_lock);
goto out;
unlock:
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
dst_unreach:
icmp_packet.msg_type = DESTINATION_UNREACHABLE;
bat_device_add_packet(device_client, &icmp_packet);
@@ -291,6 +300,7 @@ void bat_device_add_packet(struct device_client *device_client,
struct icmp_packet *icmp_packet)
{
struct device_packet *device_packet;
+ unsigned long flags;
device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL);
@@ -301,12 +311,12 @@ void bat_device_add_packet(struct device_client *device_client,
memcpy(&device_packet->icmp_packet, icmp_packet,
sizeof(struct icmp_packet));
- spin_lock(&device_client->lock);
+ spin_lock_irqsave(&device_client->lock, flags);
/* while waiting for the lock the device_client could have been
* deleted */
if (!device_client_hash[icmp_packet->uid]) {
- spin_unlock(&device_client->lock);
+ spin_unlock_irqrestore(&device_client->lock, flags);
kfree(device_packet);
return;
}
@@ -323,7 +333,7 @@ void bat_device_add_packet(struct device_client *device_client,
device_client->queue_len--;
}
- spin_unlock(&device_client->lock);
+ spin_unlock_irqrestore(&device_client->lock, flags);
wake_up(&device_client->queue_wait);
}
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index 5ea35da5ee7..befd4883951 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -21,13 +21,11 @@
#include "main.h"
#include "hard-interface.h"
-#include "log.h"
#include "soft-interface.h"
#include "send.h"
#include "translation-table.h"
#include "routing.h"
#include "hash.h"
-#include "compat.h"
#define MIN(x, y) ((x) < (y) ? (x) : (y))
@@ -75,7 +73,6 @@ int hardif_min_mtu(void)
static void check_known_mac_addr(uint8_t *addr)
{
struct batman_if *batman_if;
- char mac_string[ETH_STR_LEN];
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
@@ -86,10 +83,9 @@ static void check_known_mac_addr(uint8_t *addr)
if (!compare_orig(batman_if->net_dev->dev_addr, addr))
continue;
- addr_to_string(mac_string, addr);
- debug_log(LOG_TYPE_WARN, "The newly added mac address (%s) already exists on: %s\n",
- mac_string, batman_if->dev);
- debug_log(LOG_TYPE_WARN, "It is strongly recommended to keep mac addresses unique to avoid problems!\n");
+ printk(KERN_WARNING "batman-adv:The newly added mac address (%pM) already exists on: %s\n",
+ addr, batman_if->dev);
+ printk(KERN_WARNING "batman-adv:It is strongly recommended to keep mac addresses unique to avoid problems!\n");
}
rcu_read_unlock();
}
@@ -154,9 +150,6 @@ void hardif_deactivate_interface(struct batman_if *batman_if)
if (batman_if->if_active != IF_ACTIVE)
return;
- if (batman_if->raw_sock)
- sock_release(batman_if->raw_sock);
-
/**
* batman_if->net_dev has been acquired by dev_get_by_name() in
* proc_interfaces_write() and has to be unreferenced.
@@ -165,22 +158,16 @@ void hardif_deactivate_interface(struct batman_if *batman_if)
if (batman_if->net_dev)
dev_put(batman_if->net_dev);
- batman_if->raw_sock = NULL;
- batman_if->net_dev = NULL;
-
batman_if->if_active = IF_INACTIVE;
active_ifs--;
- debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n",
- batman_if->dev);
+ printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
+ batman_if->dev);
}
/* (re)activate given interface. */
static void hardif_activate_interface(struct batman_if *batman_if)
{
- struct sockaddr_ll bind_addr;
- int retval;
-
if (batman_if->if_active != IF_INACTIVE)
return;
@@ -192,35 +179,8 @@ static void hardif_activate_interface(struct batman_if *batman_if)
if (!batman_if->net_dev)
goto dev_err;
- retval = sock_create_kern(PF_PACKET, SOCK_RAW,
- __constant_htons(ETH_P_BATMAN),
- &batman_if->raw_sock);
-
- if (retval < 0) {
- debug_log(LOG_TYPE_WARN, "Can't create raw socket: %i\n",
- retval);
- goto sock_err;
- }
-
- bind_addr.sll_family = AF_PACKET;
- bind_addr.sll_ifindex = batman_if->net_dev->ifindex;
- bind_addr.sll_protocol = 0; /* is set by the kernel */
-
- retval = kernel_bind(batman_if->raw_sock,
- (struct sockaddr *)&bind_addr, sizeof(bind_addr));
-
- if (retval < 0) {
- debug_log(LOG_TYPE_WARN, "Can't create bind raw socket: %i\n",
- retval);
- goto bind_err;
- }
-
check_known_mac_addr(batman_if->net_dev->dev_addr);
- batman_if->raw_sock->sk->sk_user_data =
- batman_if->raw_sock->sk->sk_data_ready;
- batman_if->raw_sock->sk->sk_data_ready = batman_data_ready;
-
addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
@@ -235,17 +195,12 @@ static void hardif_activate_interface(struct batman_if *batman_if)
if (batman_if->if_num == 0)
set_main_if_addr(batman_if->net_dev->dev_addr);
- debug_log(LOG_TYPE_NOTICE, "Interface activated: %s\n",
- batman_if->dev);
+ printk(KERN_INFO "batman-adv:Interface activated: %s\n",
+ batman_if->dev);
return;
-bind_err:
- sock_release(batman_if->raw_sock);
-sock_err:
- dev_put(batman_if->net_dev);
dev_err:
- batman_if->raw_sock = NULL;
batman_if->net_dev = NULL;
}
@@ -290,7 +245,7 @@ static int resize_orig(struct orig_node *orig_node, int if_num)
data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS,
GFP_ATOMIC);
if (!data_ptr) {
- debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
+ printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
return -1;
}
@@ -301,7 +256,7 @@ static int resize_orig(struct orig_node *orig_node, int if_num)
data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC);
if (!data_ptr) {
- debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
+ printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
return -1;
}
@@ -319,16 +274,16 @@ int hardif_add_interface(char *dev, int if_num)
struct batman_if *batman_if;
struct batman_packet *batman_packet;
struct orig_node *orig_node;
- struct hash_it_t *hashit = NULL;
+ unsigned long flags;
+ HASHIT(hashit);
batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);
if (!batman_if) {
- debug_log(LOG_TYPE_WARN, "Can't add interface (%s): out of memory\n", dev);
+ printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", dev);
return -1;
}
- batman_if->raw_sock = NULL;
batman_if->net_dev = NULL;
if ((if_num == 0) && (num_hna > 0))
@@ -339,7 +294,7 @@ int hardif_add_interface(char *dev, int if_num)
batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL);
if (!batman_if->packet_buff) {
- debug_log(LOG_TYPE_WARN, "Can't add interface packet (%s): out of memory\n", dev);
+ printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", dev);
goto out;
}
@@ -348,7 +303,7 @@ int hardif_add_interface(char *dev, int if_num)
batman_if->if_active = IF_INACTIVE;
INIT_RCU_HEAD(&batman_if->rcu);
- debug_log(LOG_TYPE_NOTICE, "Adding interface: %s\n", dev);
+ printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev);
avail_ifs++;
INIT_LIST_HEAD(&batman_if->list);
@@ -376,20 +331,20 @@ int hardif_add_interface(char *dev, int if_num)
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
- orig_node = hashit->bucket->data;
+ while (hash_iterate(orig_hash, &hashit)) {
+ orig_node = hashit.bucket->data;
if (resize_orig(orig_node, if_num) == -1) {
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
goto out;
}
}
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
if (!hardif_is_interface_up(batman_if->dev))
- debug_log(LOG_TYPE_WARN, "Not using interface %s (retrying later): interface not active\n", batman_if->dev);
+ printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev);
else
hardif_activate_interface(batman_if);
@@ -400,8 +355,7 @@ int hardif_add_interface(char *dev, int if_num)
return 1;
out:
- if (batman_if->packet_buff)
- kfree(batman_if->packet_buff);
+ kfree(batman_if->packet_buff);
kfree(batman_if);
kfree(dev);
return -1;
@@ -413,7 +367,7 @@ char hardif_get_active_if_num(void)
}
static int hard_if_event(struct notifier_block *this,
- unsigned long event, void *ptr)
+ unsigned long event, void *ptr)
{
struct net_device *dev = (struct net_device *)ptr;
struct batman_if *batman_if = get_batman_if_by_name(dev->name);
@@ -436,7 +390,6 @@ static int hard_if_event(struct notifier_block *this,
break;
/* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */
default:
- /* debug_log(LOG_TYPE_CRIT, "hard_if_event: %s %i\n", dev->name, event); */
break;
};
@@ -446,6 +399,122 @@ out:
return NOTIFY_DONE;
}
+/* find batman interface by netdev. assumes rcu_read_lock on */
+static struct batman_if *find_batman_if(struct net_device *dev)
+{
+ struct batman_if *batman_if;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->net_dev == dev) {
+ rcu_read_unlock();
+ return batman_if;
+ }
+ }
+ rcu_read_unlock();
+ return NULL;
+}
+
+
+/* receive a packet with the batman ethertype coming on a hard
+ * interface */
+int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *ptype, struct net_device *orig_dev)
+{
+ struct batman_packet *batman_packet;
+ struct batman_if *batman_if;
+ struct net_device_stats *stats;
+ int ret;
+
+ skb = skb_share_check(skb, GFP_ATOMIC);
+
+ /* skb was released by skb_share_check() */
+ if (!skb)
+ goto err_out;
+
+ if (atomic_read(&module_state) != MODULE_ACTIVE)
+ goto err_free;
+
+ /* packet should hold at least type and version */
+ if (unlikely(skb_headlen(skb) < 2))
+ goto err_free;
+
+ /* expect a valid ethernet header here. */
+ if (unlikely(skb->mac_len != sizeof(struct ethhdr)
+ || !skb_mac_header(skb)))
+ goto err_free;
+
+ batman_if = find_batman_if(skb->dev);
+ if (!batman_if)
+ goto err_free;
+
+ /* discard frames on not active interfaces */
+ if (batman_if->if_active != IF_ACTIVE)
+ goto err_free;
+
+ stats = (struct net_device_stats *)dev_get_stats(skb->dev);
+ if (stats) {
+ stats->rx_packets++;
+ stats->rx_bytes += skb->len;
+ }
+
+ batman_packet = (struct batman_packet *)skb->data;
+
+ if (batman_packet->version != COMPAT_VERSION) {
+ bat_dbg(DBG_BATMAN,
+ "Drop packet: incompatible batman version (%i)\n",
+ batman_packet->version);
+ goto err_free;
+ }
+
+ /* all receive handlers return whether they received or reused
+ * the supplied skb. if not, we have to free the skb. */
+
+ switch (batman_packet->packet_type) {
+ /* batman originator packet */
+ case BAT_PACKET:
+ ret = recv_bat_packet(skb, batman_if);
+ break;
+
+ /* batman icmp packet */
+ case BAT_ICMP:
+ ret = recv_icmp_packet(skb);
+ break;
+
+ /* unicast packet */
+ case BAT_UNICAST:
+ ret = recv_unicast_packet(skb);
+ break;
+
+ /* broadcast packet */
+ case BAT_BCAST:
+ ret = recv_bcast_packet(skb);
+ break;
+
+ /* vis packet */
+ case BAT_VIS:
+ ret = recv_vis_packet(skb);
+ break;
+ default:
+ ret = NET_RX_DROP;
+ }
+
+ if (ret == NET_RX_DROP)
+ kfree_skb(skb);
+
+ /* return NET_RX_SUCCESS in any case as we
+ * most probably dropped the packet for
+ * routing-logical reasons. */
+
+ return NET_RX_SUCCESS;
+
+err_free:
+ kfree_skb(skb);
+err_out:
+ return NET_RX_DROP;
+}
+
+
struct notifier_block hard_if_notifier = {
- .notifier_call = hard_if_event,
+ .notifier_call = hard_if_event,
};
diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h
index 742358c00c0..97c6ecb9e08 100644
--- a/drivers/staging/batman-adv/hard-interface.h
+++ b/drivers/staging/batman-adv/hard-interface.h
@@ -32,5 +32,9 @@ void hardif_deactivate_interface(struct batman_if *batman_if);
char hardif_get_active_if_num(void);
void hardif_check_interfaces_status(void);
void hardif_check_interfaces_status_wq(struct work_struct *work);
+int batman_skb_recv(struct sk_buff *skb,
+ struct net_device *dev,
+ struct packet_type *ptype,
+ struct net_device *orig_dev);
int hardif_min_mtu(void);
void update_min_mtu(void);
diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c
index 61cb4a20ebc..5a2018de3ff 100644
--- a/drivers/staging/batman-adv/hash.c
+++ b/drivers/staging/batman-adv/hash.c
@@ -64,24 +64,18 @@ void hash_destroy(struct hashtable_t *hash)
kfree(hash);
}
-/* iterate though the hash. first element is selected with iter_in NULL. use
- * the returned iterator to access the elements until hash_it_t returns NULL. */
+/* iterate though the hash. First element is selected if an iterator
+ * initialized with HASHIT() is supplied as iter. Use the returned
+ * (or supplied) iterator to access the elements until hash_iterate returns
+ * NULL. */
+
struct hash_it_t *hash_iterate(struct hashtable_t *hash,
- struct hash_it_t *iter_in)
+ struct hash_it_t *iter)
{
- struct hash_it_t *iter;
-
if (!hash)
return NULL;
-
- if (iter_in == NULL) {
- iter = kmalloc(sizeof(struct hash_it_t), GFP_ATOMIC);
- iter->index = -1;
- iter->bucket = NULL;
- iter->prev_bucket = NULL;
- } else {
- iter = iter_in;
- }
+ if (!iter)
+ return NULL;
/* sanity checks first (if our bucket got deleted in the last
* iteration): */
@@ -139,7 +133,6 @@ struct hash_it_t *hash_iterate(struct hashtable_t *hash,
}
/* nothing to iterate over anymore */
- kfree(iter);
return NULL;
}
diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h
index bb60f082be6..a70d6d6e1c7 100644
--- a/drivers/staging/batman-adv/hash.h
+++ b/drivers/staging/batman-adv/hash.h
@@ -21,6 +21,11 @@
#ifndef _BATMAN_HASH_H
#define _BATMAN_HASH_H
+#define HASHIT(name) struct hash_it_t name = { \
+ .index = -1, .bucket = NULL, \
+ .prev_bucket = NULL, \
+ .first_bucket = NULL }
+
typedef int (*hashdata_compare_cb)(void *, void *);
typedef int (*hashdata_choose_cb)(void *, int);
diff --git a/drivers/staging/batman-adv/log.c b/drivers/staging/batman-adv/log.c
deleted file mode 100644
index f37c7f01a9f..00000000000
--- a/drivers/staging/batman-adv/log.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This program 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.
- *
- * This program is distributed in 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 "main.h"
-#include "log.h"
-
-#define LOG_BUF_MASK (log_buf_len-1)
-#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
-
-static char log_buf[LOG_BUF_LEN];
-static int log_buf_len = LOG_BUF_LEN;
-static unsigned long log_start;
-static unsigned long log_end;
-uint8_t log_level;
-
-static DEFINE_SPINLOCK(logbuf_lock);
-
-const struct file_operations proc_log_operations = {
- .open = log_open,
- .release = log_release,
- .read = log_read,
- .write = log_write,
- .poll = log_poll,
-};
-
-static DECLARE_WAIT_QUEUE_HEAD(log_wait);
-
-static void emit_log_char(char c)
-{
- LOG_BUF(log_end) = c;
- log_end++;
-
- if (log_end - log_start > log_buf_len)
- log_start = log_end - log_buf_len;
-}
-
-static int fdebug_log(char *fmt, ...)
-{
- int printed_len;
- char *p;
- va_list args;
- static char debug_log_buf[256];
- unsigned long flags;
-
- spin_lock_irqsave(&logbuf_lock, flags);
- va_start(args, fmt);
- printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt,
- args);
- va_end(args);
-
- for (p = debug_log_buf; *p != 0; p++)
- emit_log_char(*p);
-
- spin_unlock_irqrestore(&logbuf_lock, flags);
-
- wake_up(&log_wait);
-
- return 0;
-}
-
-int debug_log(int type, char *fmt, ...)
-{
- va_list args;
- int retval = 0;
- char tmp_log_buf[256];
-
- /* only critical information get into the official kernel log */
- if (type == LOG_TYPE_CRIT) {
- va_start(args, fmt);
- vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
- printk(KERN_ERR "batman-adv: %s", tmp_log_buf);
- va_end(args);
- }
-
- if ((type == LOG_TYPE_CRIT) || (log_level & type)) {
- va_start(args, fmt);
- vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
- fdebug_log("[%10u] %s", (jiffies / HZ), tmp_log_buf);
- va_end(args);
- }
-
- return retval;
-}
-
-int log_open(struct inode *inode, struct file *file)
-{
- inc_module_count();
- return 0;
-}
-
-int log_release(struct inode *inode, struct file *file)
-{
- dec_module_count();
- return 0;
-}
-
-ssize_t log_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
-{
- int error, i = 0;
- char c;
- unsigned long flags;
-
- if ((file->f_flags & O_NONBLOCK) && !(log_end - log_start))
- return -EAGAIN;
-
- if ((!buf) || (count < 0))
- return -EINVAL;
-
- if (count == 0)
- return 0;
-
- if (!access_ok(VERIFY_WRITE, buf, count))
- return -EFAULT;
-
- error = wait_event_interruptible(log_wait, (log_start - log_end));
-
- if (error)
- return error;
-
- spin_lock_irqsave(&logbuf_lock, flags);
-
- while ((!error) && (log_start != log_end) && (i < count)) {
- c = LOG_BUF(log_start);
-
- log_start++;
-
- spin_unlock_irqrestore(&logbuf_lock, flags);
-
- error = __put_user(c, buf);
-
- spin_lock_irqsave(&logbuf_lock, flags);
-
- buf++;
- i++;
-
- }
-
- spin_unlock_irqrestore(&logbuf_lock, flags);
-
- if (!error)
- return i;
-
- return error;
-}
-
-ssize_t log_write(struct file *file, const char __user *buf, size_t count,
- loff_t *ppos)
-{
- return count;
-}
-
-unsigned int log_poll(struct file *file, poll_table *wait)
-{
- poll_wait(file, &log_wait, wait);
-
- if (log_end - log_start)
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
diff --git a/drivers/staging/batman-adv/log.h b/drivers/staging/batman-adv/log.h
deleted file mode 100644
index 780e3abb48f..00000000000
--- a/drivers/staging/batman-adv/log.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This program 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.
- *
- * This program is distributed in 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
- *
- */
-
-extern const struct file_operations proc_log_operations;
-extern uint8_t log_level;
-
-int debug_log(int type, char *fmt, ...);
-int log_open(struct inode *inode, struct file *file);
-int log_release(struct inode *inode, struct file *file);
-ssize_t log_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos);
-ssize_t log_write(struct file *file, const char __user *buf, size_t count,
- loff_t *ppos);
-unsigned int log_poll(struct file *file, poll_table *wait);
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c
index bb89bfc5dda..2e0b482e710 100644
--- a/drivers/staging/batman-adv/main.c
+++ b/drivers/staging/batman-adv/main.c
@@ -21,9 +21,9 @@
#include "main.h"
#include "proc.h"
-#include "log.h"
#include "routing.h"
#include "send.h"
+#include "originator.h"
#include "soft-interface.h"
#include "device.h"
#include "translation-table.h"
@@ -31,7 +31,6 @@
#include "types.h"
#include "vis.h"
#include "hash.h"
-#include "compat.h"
struct list_head if_list;
struct hlist_head forw_bat_list;
@@ -44,19 +43,34 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t originator_interval;
atomic_t vis_interval;
+atomic_t vis_mode;
atomic_t aggregation_enabled;
int16_t num_hna;
int16_t num_ifs;
struct net_device *soft_device;
-static struct task_struct *kthread_task;
-
unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
atomic_t module_state;
+static struct packet_type batman_adv_packet_type __read_mostly = {
+ .type = __constant_htons(ETH_P_BATMAN),
+ .func = batman_skb_recv,
+};
+
struct workqueue_struct *bat_event_workqueue;
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+int debug;
+
+module_param(debug, int, 0644);
+
+int bat_debug_type(int type)
+{
+ return debug & type;
+}
+#endif
+
int init_module(void)
{
int retval;
@@ -70,6 +84,7 @@ int init_module(void)
atomic_set(&originator_interval, 1000);
atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
* for debugging now. */
+ atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
atomic_set(&aggregation_enabled, 1);
/* the name should not be longer than 10 chars - see
@@ -90,21 +105,22 @@ int init_module(void)
interface_setup);
if (!soft_device) {
- debug_log(LOG_TYPE_CRIT, "Unable to allocate the batman interface\n");
+ printk(KERN_ERR "batman-adv:Unable to allocate the batman interface\n");
goto end;
}
retval = register_netdev(soft_device);
if (retval < 0) {
- debug_log(LOG_TYPE_CRIT, "Unable to register the batman interface: %i\n", retval);
+ printk(KERN_ERR "batman-adv:Unable to register the batman interface: %i\n", retval);
goto free_soft_device;
}
register_netdevice_notifier(&hard_if_notifier);
+ dev_add_pack(&batman_adv_packet_type);
- debug_log(LOG_TYPE_CRIT, "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
- SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
+ printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
+ SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
return 0;
@@ -124,6 +140,8 @@ void cleanup_module(void)
soft_device = NULL;
}
+ dev_remove_pack(&batman_adv_packet_type);
+
unregister_netdevice_notifier(&hard_if_notifier);
cleanup_procfs();
@@ -151,22 +169,12 @@ void activate_module(void)
if (vis_init() < 1)
goto err;
- /* (re)start kernel thread for packet processing */
- if (!kthread_task) {
- kthread_task = kthread_run(packet_recv_thread, NULL, "batman-adv");
-
- if (IS_ERR(kthread_task)) {
- debug_log(LOG_TYPE_CRIT, "Unable to start packet receive thread\n");
- kthread_task = NULL;
- }
- }
-
update_min_mtu();
atomic_set(&module_state, MODULE_ACTIVE);
goto end;
err:
- debug_log(LOG_TYPE_CRIT, "Unable to allocate memory for mesh information structures: out of mem ?\n");
+ printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n");
shutdown_module();
end:
return;
@@ -182,14 +190,7 @@ void shutdown_module(void)
vis_quit();
- /* deactivate kernel thread for packet processing (if running) */
- if (kthread_task) {
- atomic_set(&exit_cond, 1);
- wake_up_interruptible(&thread_wait);
- kthread_stop(kthread_task);
-
- kthread_task = NULL;
- }
+ /* TODO: unregister BATMAN pack */
originator_free();
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h
index facb6b79ee5..2e9bb891a5d 100644
--- a/drivers/staging/batman-adv/main.h
+++ b/drivers/staging/batman-adv/main.h
@@ -33,16 +33,16 @@
#define TQ_MAX_VALUE 255
#define JITTER 20
-#define TTL 50 /* Time To Live of broadcast messages */
-#define MAX_ADDR 16 /* number of interfaces which can be added to
+#define TTL 50 /* Time To Live of broadcast messages */
+#define MAX_ADDR 16 /* number of interfaces which can be added to
* batman. */
-#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no
+#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no
* valid packet comes in -> TODO: check
* influence on TQ_LOCAL_WINDOW_SIZE */
#define LOCAL_HNA_TIMEOUT 3600000
-#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
+#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
* messages in squence numbers (should be a
* multiple of our word size) */
#define TQ_GLOBAL_WINDOW_SIZE 5
@@ -69,24 +69,27 @@
/*
- * Logging
+ * Debug Messages
*/
-#define LOG_TYPE_CRIT 0 /* highest priority for fatal errors such as
- * blocked sockets / failed packet delivery /
- * programming errors */
-#define LOG_TYPE_WARN 1 /* warnings for small errors like wrong user
- * input / damaged packets / etc */
-#define LOG_TYPE_NOTICE 2 /* notice information for new interfaces /
- * changed settings / new originators / etc */
-#define LOG_TYPE_BATMAN 4 /* all messages related to routing / flooding /
- * broadcasting / etc */
-#define LOG_TYPE_ROUTES 8 /* route or hna added / changed / deleted */
-#define LOG_TYPE_CRIT_NAME "critical"
-#define LOG_TYPE_WARN_NAME "warnings"
-#define LOG_TYPE_NOTICE_NAME "notices"
-#define LOG_TYPE_BATMAN_NAME "batman"
-#define LOG_TYPE_ROUTES_NAME "routes"
+#define DBG_BATMAN 1 /* all messages related to routing / flooding /
+ * broadcasting / etc */
+#define DBG_ROUTES 2 /* route or hna added / changed / deleted */
+
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+extern int debug;
+
+extern int bat_debug_type(int type);
+#define bat_dbg(type, fmt, arg...) do { \
+ if (bat_debug_type(type)) \
+ printk(KERN_DEBUG "batman-adv:" fmt, ## arg); \
+ } \
+ while (0)
+#else /* !CONFIG_BATMAN_ADV_DEBUG */
+#define bat_dbg(type, fmt, arg...) do { \
+ } \
+ while (0)
+#endif
/*
* Vis
@@ -106,6 +109,7 @@
#include <linux/kthread.h> /* kernel threads */
#include <linux/pkt_sched.h> /* schedule types */
#include <linux/workqueue.h> /* workqueue */
+#include <linux/slab.h>
#include <net/sock.h> /* struct sock */
#include <linux/jiffies.h>
#include "types.h"
@@ -127,6 +131,7 @@ extern spinlock_t forw_bcast_list_lock;
extern atomic_t originator_interval;
extern atomic_t vis_interval;
+extern atomic_t vis_mode;
extern atomic_t aggregation_enabled;
extern int16_t num_hna;
extern int16_t num_ifs;
@@ -147,5 +152,3 @@ int choose_orig(void *data, int32_t size);
int is_my_mac(uint8_t *addr);
int is_bcast(uint8_t *addr);
int is_mcast(uint8_t *addr);
-
-
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c
new file mode 100644
index 00000000000..29c241119a3
--- /dev/null
+++ b/drivers/staging/batman-adv/originator.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * This program 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.
+ *
+ * This program is distributed in 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
+ *
+ */
+
+/* increase the reference counter for this originator */
+
+#include "main.h"
+#include "originator.h"
+#include "hash.h"
+#include "translation-table.h"
+#include "routing.h"
+
+static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
+
+static void start_purge_timer(void)
+{
+ queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
+}
+
+int originator_init(void)
+{
+ unsigned long flags;
+ if (orig_hash)
+ return 1;
+
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ orig_hash = hash_new(128, compare_orig, choose_orig);
+
+ if (!orig_hash)
+ goto err;
+
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+ start_purge_timer();
+ return 1;
+
+err:
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+ return 0;
+}
+
+void originator_free(void)
+{
+ unsigned long flags;
+
+ if (!orig_hash)
+ return;
+
+ cancel_delayed_work_sync(&purge_orig_wq);
+
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ hash_delete(orig_hash, free_orig_node);
+ orig_hash = NULL;
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+}
+
+struct neigh_node *
+create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
+ uint8_t *neigh, struct batman_if *if_incoming)
+{
+ struct neigh_node *neigh_node;
+
+ bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n");
+
+ neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
+ if (!neigh_node)
+ return NULL;
+
+ INIT_LIST_HEAD(&neigh_node->list);
+
+ memcpy(neigh_node->addr, neigh, ETH_ALEN);
+ neigh_node->orig_node = orig_neigh_node;
+ neigh_node->if_incoming = if_incoming;
+
+ list_add_tail(&neigh_node->list, &orig_node->neigh_list);
+ return neigh_node;
+}
+
+void free_orig_node(void *data)
+{
+ struct list_head *list_pos, *list_pos_tmp;
+ struct neigh_node *neigh_node;
+ struct orig_node *orig_node = (struct orig_node *)data;
+
+ /* for all neighbors towards this originator ... */
+ list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
+ neigh_node = list_entry(list_pos, struct neigh_node, list);
+
+ list_del(list_pos);
+ kfree(neigh_node);
+ }
+
+ hna_global_del_orig(orig_node, "originator timed out");
+
+ kfree(orig_node->bcast_own);
+ kfree(orig_node->bcast_own_sum);
+ kfree(orig_node);
+}
+
+/* this function finds or creates an originator entry for the given
+ * address if it does not exits */
+struct orig_node *get_orig_node(uint8_t *addr)
+{
+ struct orig_node *orig_node;
+ struct hashtable_t *swaphash;
+ int size;
+
+ orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
+
+ if (orig_node != NULL)
+ return orig_node;
+
+ bat_dbg(DBG_BATMAN, "Creating new originator: %pM \n", addr);
+
+ orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
+ if (!orig_node)
+ return NULL;
+
+ INIT_LIST_HEAD(&orig_node->neigh_list);
+
+ memcpy(orig_node->orig, addr, ETH_ALEN);
+ orig_node->router = NULL;
+ orig_node->batman_if = NULL;
+ orig_node->hna_buff = NULL;
+
+ size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS;
+
+ orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
+ if (!orig_node->bcast_own)
+ goto free_orig_node;
+
+ size = num_ifs * sizeof(uint8_t);
+ orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
+ if (!orig_node->bcast_own_sum)
+ goto free_bcast_own;
+
+ if (hash_add(orig_hash, orig_node) < 0)
+ goto free_bcast_own_sum;
+
+ if (orig_hash->elements * 4 > orig_hash->size) {
+ swaphash = hash_resize(orig_hash, orig_hash->size * 2);
+
+ if (swaphash == NULL)
+ printk(KERN_ERR
+ "batman-adv:Couldn't resize orig hash table \n");
+ else
+ orig_hash = swaphash;
+ }
+
+ return orig_node;
+free_bcast_own_sum:
+ kfree(orig_node->bcast_own_sum);
+free_bcast_own:
+ kfree(orig_node->bcast_own);
+free_orig_node:
+ kfree(orig_node);
+ return NULL;
+}
+
+static bool purge_orig_neighbors(struct orig_node *orig_node,
+ struct neigh_node **best_neigh_node)
+{
+ struct list_head *list_pos, *list_pos_tmp;
+ struct neigh_node *neigh_node;
+ bool neigh_purged = false;
+
+ *best_neigh_node = NULL;
+
+
+ /* for all neighbors towards this originator ... */
+ list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
+ neigh_node = list_entry(list_pos, struct neigh_node, list);
+
+ if (time_after(jiffies,
+ (neigh_node->last_valid +
+ ((PURGE_TIMEOUT * HZ) / 1000)))) {
+
+ bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ));
+
+ neigh_purged = true;
+ list_del(list_pos);
+ kfree(neigh_node);
+ } else {
+ if ((*best_neigh_node == NULL) ||
+ (neigh_node->tq_avg > (*best_neigh_node)->tq_avg))
+ *best_neigh_node = neigh_node;
+ }
+ }
+ return neigh_purged;
+}
+
+
+static bool purge_orig_node(struct orig_node *orig_node)
+{
+ struct neigh_node *best_neigh_node;
+
+ if (time_after(jiffies,
+ (orig_node->last_valid +
+ ((2 * PURGE_TIMEOUT * HZ) / 1000)))) {
+
+ bat_dbg(DBG_BATMAN,
+ "Originator timeout: originator %pM, last_valid %lu\n",
+ orig_node->orig, (orig_node->last_valid / HZ));
+ return true;
+ } else {
+ if (purge_orig_neighbors(orig_node, &best_neigh_node))
+ update_routes(orig_node, best_neigh_node,
+ orig_node->hna_buff,
+ orig_node->hna_buff_len);
+ }
+ return false;
+}
+
+void purge_orig(struct work_struct *work)
+{
+ HASHIT(hashit);
+ struct orig_node *orig_node;
+ unsigned long flags;
+
+ spin_lock_irqsave(&orig_hash_lock, flags);
+
+ /* for all origins... */
+ while (hash_iterate(orig_hash, &hashit)) {
+ orig_node = hashit.bucket->data;
+ if (purge_orig_node(orig_node)) {
+ hash_remove_bucket(orig_hash, &hashit);
+ free_orig_node(orig_node);
+ }
+ }
+
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ start_purge_timer();
+}
+
+
diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h
new file mode 100644
index 00000000000..6ef7a054a0a
--- /dev/null
+++ b/drivers/staging/batman-adv/originator.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * This program 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.
+ *
+ * This program is distributed in 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
+ *
+ */
+
+int originator_init(void);
+void free_orig_node(void *data);
+void originator_free(void);
+void purge_orig(struct work_struct *work);
+struct orig_node *orig_find(char *mac);
+struct orig_node *get_orig_node(uint8_t *addr);
+struct neigh_node *
+create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
+ uint8_t *neigh, struct batman_if *if_incoming);
+
diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h
index 5627ca32601..ad006ce8b13 100644
--- a/drivers/staging/batman-adv/packet.h
+++ b/drivers/staging/batman-adv/packet.h
@@ -90,7 +90,7 @@ struct vis_packet {
uint8_t entries; /* number of entries behind this struct */
uint8_t ttl; /* TTL */
uint8_t vis_orig[6]; /* originator that informs about its
- * neighbours */
+ * neighbors */
uint8_t target_orig[6]; /* who should receive this packet */
uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
} __attribute__((packed));
diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c
index aac3df7f13f..7de60e84bc9 100644
--- a/drivers/staging/batman-adv/proc.c
+++ b/drivers/staging/batman-adv/proc.c
@@ -21,23 +21,18 @@
#include "main.h"
#include "proc.h"
-#include "log.h"
#include "routing.h"
#include "translation-table.h"
#include "hard-interface.h"
#include "types.h"
#include "hash.h"
#include "vis.h"
-#include "compat.h"
-
-static uint8_t vis_format = DOT_DRAW;
static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file;
-static struct proc_dir_entry *proc_log_file, *proc_log_level_file;
static struct proc_dir_entry *proc_transt_local_file;
static struct proc_dir_entry *proc_transt_global_file;
-static struct proc_dir_entry *proc_vis_file, *proc_vis_format_file;
+static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file;
static struct proc_dir_entry *proc_aggr_file;
static int proc_interfaces_read(struct seq_file *seq, void *offset)
@@ -68,7 +63,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
size_t count, loff_t *data)
{
char *if_string, *colon_ptr = NULL, *cr_ptr = NULL;
- int not_copied = 0, if_num = 0;
+ int not_copied = 0, if_num = 0, add_success;
struct batman_if *batman_if = NULL;
if_string = kmalloc(count, GFP_KERNEL);
@@ -77,8 +72,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
return -ENOMEM;
if (count > IFNAMSIZ - 1) {
- debug_log(LOG_TYPE_WARN,
- "Can't add interface: device name is too long\n");
+ printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n");
goto end;
}
@@ -105,7 +99,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
if (strncmp(batman_if->dev, if_string, count) == 0) {
- debug_log(LOG_TYPE_WARN, "Given interface is already active: %s\n", if_string);
+ printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string);
rcu_read_unlock();
goto end;
@@ -115,22 +109,17 @@ static ssize_t proc_interfaces_write(struct file *instance,
}
rcu_read_unlock();
- hardif_add_interface(if_string, if_num);
+ add_success = hardif_add_interface(if_string, if_num);
+ if (add_success < 0)
+ goto end;
+
+ num_ifs = if_num + 1;
if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
(hardif_get_active_if_num() > 0))
activate_module();
- rcu_read_lock();
- if (list_empty(&if_list)) {
- rcu_read_unlock();
- goto end;
- }
- rcu_read_unlock();
-
- num_ifs = if_num + 1;
return count;
-
end:
kfree(if_string);
return count;
@@ -162,20 +151,18 @@ static ssize_t proc_orig_interval_write(struct file *file,
retval = strict_strtoul(interval_string, 10, &originator_interval_tmp);
if (retval) {
- debug_log(LOG_TYPE_WARN, "New originator interval invalid\n");
+ printk(KERN_ERR "batman-adv:New originator interval invalid\n");
goto end;
}
if (originator_interval_tmp <= JITTER * 2) {
- debug_log(LOG_TYPE_WARN,
- "New originator interval too small: %i (min: %i)\n",
- originator_interval_tmp, JITTER * 2);
+ printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n",
+ originator_interval_tmp, JITTER * 2);
goto end;
}
- debug_log(LOG_TYPE_NOTICE,
- "Changing originator interval from: %i to: %i\n",
- atomic_read(&originator_interval), originator_interval_tmp);
+ printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n",
+ atomic_read(&originator_interval), originator_interval_tmp);
atomic_set(&originator_interval, originator_interval_tmp);
@@ -191,11 +178,12 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file)
static int proc_originators_read(struct seq_file *seq, void *offset)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
struct orig_node *orig_node;
struct neigh_node *neigh_node;
int batman_count = 0;
char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
+ unsigned long flags;
rcu_read_lock();
if (list_empty(&if_list)) {
@@ -218,11 +206,11 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
((struct batman_if *)if_list.next)->addr_str);
rcu_read_unlock();
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
+ while (hash_iterate(orig_hash, &hashit)) {
- orig_node = hashit->bucket->data;
+ orig_node = hashit.bucket->data;
if (!orig_node->router)
continue;
@@ -249,7 +237,7 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
}
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
if (batman_count == 0)
seq_printf(seq, "No batman nodes in range ... \n");
@@ -263,84 +251,6 @@ static int proc_originators_open(struct inode *inode, struct file *file)
return single_open(file, proc_originators_read, NULL);
}
-static int proc_log_level_read(struct seq_file *seq, void *offset)
-{
-
- seq_printf(seq, "[x] %s (%d)\n", LOG_TYPE_CRIT_NAME, LOG_TYPE_CRIT);
- seq_printf(seq, "[%c] %s (%d)\n",
- (LOG_TYPE_WARN & log_level) ? 'x' : ' ',
- LOG_TYPE_WARN_NAME, LOG_TYPE_WARN);
- seq_printf(seq, "[%c] %s (%d)\n",
- (LOG_TYPE_NOTICE & log_level) ? 'x' : ' ',
- LOG_TYPE_NOTICE_NAME, LOG_TYPE_NOTICE);
- seq_printf(seq, "[%c] %s (%d)\n",
- (LOG_TYPE_BATMAN & log_level) ? 'x' : ' ',
- LOG_TYPE_BATMAN_NAME, LOG_TYPE_BATMAN);
- seq_printf(seq, "[%c] %s (%d)\n",
- (LOG_TYPE_ROUTES & log_level) ? 'x' : ' ',
- LOG_TYPE_ROUTES_NAME, LOG_TYPE_ROUTES);
- return 0;
-}
-
-static int proc_log_level_open(struct inode *inode, struct file *file)
-{
- return single_open(file, proc_log_level_read, NULL);
-}
-
-static ssize_t proc_log_level_write(struct file *instance,
- const char __user *userbuffer,
- size_t count, loff_t *data)
-{
- char *log_level_string, *tokptr, *cp;
- int finished, not_copied = 0;
- unsigned long log_level_tmp = 0;
-
- log_level_string = kmalloc(count, GFP_KERNEL);
-
- if (!log_level_string)
- return -ENOMEM;
-
- not_copied = copy_from_user(log_level_string, userbuffer, count);
- log_level_string[count - not_copied - 1] = 0;
-
- if (strict_strtoul(log_level_string, 10, &log_level_tmp) < 0) {
- /* was not a number, doing textual parsing */
- log_level_tmp = 0;
- tokptr = log_level_string;
-
- for (cp = log_level_string, finished = 0; !finished; cp++) {
- switch (*cp) {
- case 0:
- finished = 1;
- case ' ':
- case '\n':
- case '\t':
- *cp = 0;
- /* compare */
- if (strcmp(tokptr, LOG_TYPE_WARN_NAME) == 0)
- log_level_tmp |= LOG_TYPE_WARN;
- if (strcmp(tokptr, LOG_TYPE_NOTICE_NAME) == 0)
- log_level_tmp |= LOG_TYPE_NOTICE;
- if (strcmp(tokptr, LOG_TYPE_BATMAN_NAME) == 0)
- log_level_tmp |= LOG_TYPE_BATMAN;
- if (strcmp(tokptr, LOG_TYPE_ROUTES_NAME) == 0)
- log_level_tmp |= LOG_TYPE_ROUTES;
- tokptr = cp + 1;
- break;
- default:
- ;
- }
- }
- }
-
- debug_log(LOG_TYPE_CRIT, "Changing log_level from: %i to: %i\n",
- log_level, log_level_tmp);
- log_level = log_level_tmp;
-
- kfree(log_level_string);
- return count;
-}
-
static int proc_transt_local_read(struct seq_file *seq, void *offset)
{
char *buf;
@@ -405,172 +315,8 @@ static int proc_transt_global_open(struct inode *inode, struct file *file)
return single_open(file, proc_transt_global_read, NULL);
}
-/* insert interface to the list of interfaces of one originator */
-
-static void proc_vis_insert_interface(const uint8_t *interface,
- struct vis_if_list **if_entry,
- bool primary)
-{
- /* Did we get an empty list? (then insert imediately) */
- if(*if_entry == NULL) {
- *if_entry = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
- if (*if_entry == NULL)
- return;
-
- (*if_entry)->primary = primary;
- (*if_entry)->next = NULL;
- memcpy((*if_entry)->addr, interface, ETH_ALEN);
- } else {
- struct vis_if_list *head_if_entry = *if_entry;
- /* Do we already have this interface in our list? */
- while (!compare_orig((*if_entry)->addr, (void *)interface)) {
-
- /* Or did we reach the end (then append the interface) */
- if ((*if_entry)->next == NULL) {
- (*if_entry)->next = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
- if ((*if_entry)->next == NULL)
- return;
-
- memcpy((*if_entry)->next->addr, interface, ETH_ALEN);
- (*if_entry)->next->primary = primary;
- (*if_entry)->next->next = NULL;
- break;
- }
- *if_entry = (*if_entry)->next;
- }
- /* Rewind the list to its head */
- *if_entry = head_if_entry;
- }
-}
-/* read an entry */
-
-static void proc_vis_read_entry(struct seq_file *seq,
- struct vis_info_entry *entry,
- struct vis_if_list **if_entry,
- uint8_t *vis_orig,
- uint8_t current_format,
- uint8_t first_line)
-{
- char from[40];
- char to[40];
- int int_part, frac_part;
-
- addr_to_string(to, entry->dest);
- if (entry->quality == 0) {
-#ifndef VIS_SUBCLUSTERS_DISABLED
- proc_vis_insert_interface(vis_orig, if_entry, true);
-#endif /* VIS_SUBCLUSTERS_DISABLED */
- addr_to_string(from, vis_orig);
- if (current_format == DOT_DRAW) {
- seq_printf(seq, "\t\"%s\" -> \"%s\" [label=\"HNA\"]\n",
- from, to);
- } else {
- seq_printf(seq,
- "%s\t{ router : \"%s\", gateway : \"%s\", label : \"HNA\" }",
- (first_line ? "" : ",\n"), from, to);
- }
- } else {
-#ifndef VIS_SUBCLUSTERS_DISABLED
- proc_vis_insert_interface(entry->src, if_entry, compare_orig(entry->src, vis_orig));
-#endif /* VIS_SUBCLUSTERS_DISABLED */
- addr_to_string(from, entry->src);
-
- /* kernel has no printf-support for %f? it'd be better to return
- * this in float. */
-
- int_part = TQ_MAX_VALUE / entry->quality;
- frac_part = 1000 * TQ_MAX_VALUE / entry->quality - int_part * 1000;
-
- if (current_format == DOT_DRAW) {
- seq_printf(seq,
- "\t\"%s\" -> \"%s\" [label=\"%d.%d\"]\n",
- from, to, int_part, frac_part);
- } else {
- seq_printf(seq,
- "%s\t{ router : \"%s\", neighbour : \"%s\", label : %d.%d }",
- (first_line ? "" : ",\n"), from, to, int_part, frac_part);
- }
- }
-}
-
-
-static int proc_vis_read(struct seq_file *seq, void *offset)
-{
- struct hash_it_t *hashit = NULL;
- struct vis_info *info;
- struct vis_info_entry *entries;
- struct vis_if_list *if_entries = NULL;
- int i;
- uint8_t current_format, first_line = 1;
-#ifndef VIS_SUBCLUSTERS_DISABLED
- char tmp_addr_str[ETH_STR_LEN];
- struct vis_if_list *tmp_if_next;
-#endif /* VIS_SUBCLUSTERS_DISABLED */
-
- current_format = vis_format;
-
- rcu_read_lock();
- if (list_empty(&if_list) || (!is_vis_server())) {
- rcu_read_unlock();
- if (current_format == DOT_DRAW)
- seq_printf(seq, "digraph {\n}\n");
- goto end;
- }
-
- rcu_read_unlock();
-
- if (current_format == DOT_DRAW)
- seq_printf(seq, "digraph {\n");
-
- spin_lock(&vis_hash_lock);
- while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
- info = hashit->bucket->data;
- entries = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
-
- for (i = 0; i < info->packet.entries; i++) {
- proc_vis_read_entry(seq, &entries[i], &if_entries,
- info->packet.vis_orig,
- current_format, first_line);
- if (first_line)
- first_line = 0;
- }
-
-#ifndef VIS_SUBCLUSTERS_DISABLED
- /* Generate subgraphs from the collected items */
- if (current_format == DOT_DRAW) {
-
- addr_to_string(tmp_addr_str, info->packet.vis_orig);
- seq_printf(seq, "\tsubgraph \"cluster_%s\" {\n", tmp_addr_str);
- while (if_entries != NULL) {
-
- addr_to_string(tmp_addr_str, if_entries->addr);
- if (if_entries->primary)
- seq_printf(seq, "\t\t\"%s\" [peripheries=2]\n", tmp_addr_str);
- else
- seq_printf(seq, "\t\t\"%s\"\n", tmp_addr_str);
-
- /* ... and empty the list while doing this */
- tmp_if_next = if_entries->next;
- kfree(if_entries);
- if_entries = tmp_if_next;
- }
- seq_printf(seq, "\t}\n");
- }
-#endif /* VIS_SUBCLUSTERS_DISABLED */
- }
- spin_unlock(&vis_hash_lock);
-
- if (current_format == DOT_DRAW)
- seq_printf(seq, "}\n");
- else
- seq_printf(seq, "\n");
-end:
- return 0;
-}
-
/* setting the mode of the vis server by the user */
-static ssize_t proc_vis_write(struct file *file, const char __user * buffer,
+static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer,
size_t count, loff_t *ppos)
{
char *vis_mode_string;
@@ -584,72 +330,84 @@ static ssize_t proc_vis_write(struct file *file, const char __user * buffer,
not_copied = copy_from_user(vis_mode_string, buffer, count);
vis_mode_string[count - not_copied - 1] = 0;
- if (strcmp(vis_mode_string, "client") == 0) {
- debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to client\n");
- vis_set_mode(VIS_TYPE_CLIENT_UPDATE);
- } else if (strcmp(vis_mode_string, "server") == 0) {
- debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to server\n");
- vis_set_mode(VIS_TYPE_SERVER_SYNC);
+ if ((strcmp(vis_mode_string, "client") == 0) ||
+ (strcmp(vis_mode_string, "disabled") == 0)) {
+ printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n");
+ atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
+ } else if ((strcmp(vis_mode_string, "server") == 0) ||
+ (strcmp(vis_mode_string, "enabled") == 0)) {
+ printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n");
+ atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC);
} else
- debug_log(LOG_TYPE_WARN, "Unknown VIS mode: %s\n",
- vis_mode_string);
+ printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n",
+ vis_mode_string);
kfree(vis_mode_string);
return count;
}
-static int proc_vis_open(struct inode *inode, struct file *file)
+static int proc_vis_srv_read(struct seq_file *seq, void *offset)
{
- return single_open(file, proc_vis_read, NULL);
-}
+ int vis_server = atomic_read(&vis_mode);
+
+ seq_printf(seq, "[%c] client mode (server disabled) \n",
+ (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
+ seq_printf(seq, "[%c] server mode (server enabled) \n",
+ (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
-static int proc_vis_format_read(struct seq_file *seq, void *offset)
-{
- uint8_t current_format = vis_format;
-
- seq_printf(seq, "[%c] %s\n",
- (current_format == DOT_DRAW) ? 'x' : ' ',
- VIS_FORMAT_DD_NAME);
- seq_printf(seq, "[%c] %s\n",
- (current_format == JSON) ? 'x' : ' ',
- VIS_FORMAT_JSON_NAME);
return 0;
}
-static int proc_vis_format_open(struct inode *inode, struct file *file)
+static int proc_vis_srv_open(struct inode *inode, struct file *file)
{
- return single_open(file, proc_vis_format_read, NULL);
+ return single_open(file, proc_vis_srv_read, NULL);
}
-static ssize_t proc_vis_format_write(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *ppos)
+static int proc_vis_data_read(struct seq_file *seq, void *offset)
{
- char *vis_format_string;
- int not_copied = 0;
+ HASHIT(hashit);
+ struct vis_info *info;
+ struct vis_info_entry *entries;
+ HLIST_HEAD(vis_if_list);
+ int i;
+ char tmp_addr_str[ETH_STR_LEN];
+ unsigned long flags;
+ int vis_server = atomic_read(&vis_mode);
+
+ rcu_read_lock();
+ if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
+ rcu_read_unlock();
+ goto end;
+ }
- vis_format_string = kmalloc(count, GFP_KERNEL);
+ rcu_read_unlock();
- if (!vis_format_string)
- return -ENOMEM;
+ spin_lock_irqsave(&vis_hash_lock, flags);
+ while (hash_iterate(vis_hash, &hashit)) {
+ info = hashit.bucket->data;
+ entries = (struct vis_info_entry *)
+ ((char *)info + sizeof(struct vis_info));
+ addr_to_string(tmp_addr_str, info->packet.vis_orig);
+ seq_printf(seq, "%s,", tmp_addr_str);
- not_copied = copy_from_user(vis_format_string, buffer, count);
- vis_format_string[count - not_copied - 1] = 0;
-
- if (strcmp(vis_format_string, VIS_FORMAT_DD_NAME) == 0) {
- debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
- VIS_FORMAT_DD_NAME);
- vis_format = DOT_DRAW;
- } else if (strcmp(vis_format_string, VIS_FORMAT_JSON_NAME) == 0) {
- debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
- VIS_FORMAT_JSON_NAME);
- vis_format = JSON;
- } else
- debug_log(LOG_TYPE_WARN, "Unknown VIS output format: %s\n",
- vis_format_string);
+ for (i = 0; i < info->packet.entries; i++) {
+ proc_vis_read_entry(seq, &entries[i], &vis_if_list,
+ info->packet.vis_orig);
+ }
- kfree(vis_format_string);
- return count;
+ /* add primary/secondary records */
+ proc_vis_read_prim_sec(seq, &vis_if_list);
+ seq_printf(seq, "\n");
+ }
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+
+end:
+ return 0;
+}
+
+static int proc_vis_data_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_vis_data_read, NULL);
}
static int proc_aggr_read(struct seq_file *seq, void *offset)
@@ -665,6 +423,7 @@ static ssize_t proc_aggr_write(struct file *file, const char __user *buffer,
char *aggr_string;
int not_copied = 0;
unsigned long aggregation_enabled_tmp;
+ int retval;
aggr_string = kmalloc(count, GFP_KERNEL);
@@ -674,22 +433,21 @@ static ssize_t proc_aggr_write(struct file *file, const char __user *buffer,
not_copied = copy_from_user(aggr_string, buffer, count);
aggr_string[count - not_copied - 1] = 0;
- strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
+ retval = strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
- if ((aggregation_enabled_tmp != 0) && (aggregation_enabled_tmp != 1)) {
- debug_log(LOG_TYPE_WARN, "Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
- goto end;
+ if (retval || aggregation_enabled_tmp > 1) {
+ printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
+ } else {
+ printk(KERN_INFO "batman-adv:Changing aggregation from: %s (%i) to: %s (%li)\n",
+ (atomic_read(&aggregation_enabled) == 1 ?
+ "enabled" : "disabled"),
+ atomic_read(&aggregation_enabled),
+ (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
+ aggregation_enabled_tmp);
+ atomic_set(&aggregation_enabled,
+ (unsigned)aggregation_enabled_tmp);
}
- debug_log(LOG_TYPE_NOTICE, "Changing aggregation from: %s (%i) to: %s (%li)\n",
- (atomic_read(&aggregation_enabled) == 1 ?
- "enabled" : "disabled"),
- atomic_read(&aggregation_enabled),
- (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
- aggregation_enabled_tmp);
-
- atomic_set(&aggregation_enabled, (unsigned)aggregation_enabled_tmp);
-end:
kfree(aggr_string);
return count;
}
@@ -715,20 +473,20 @@ static const struct file_operations proc_aggr_fops = {
.release = single_release,
};
-static const struct file_operations proc_vis_format_fops = {
+static const struct file_operations proc_vis_srv_fops = {
.owner = THIS_MODULE,
- .open = proc_vis_format_open,
+ .open = proc_vis_srv_open,
.read = seq_read,
- .write = proc_vis_format_write,
+ .write = proc_vis_srv_write,
.llseek = seq_lseek,
.release = single_release,
};
-static const struct file_operations proc_vis_fops = {
+static const struct file_operations proc_vis_data_fops = {
.owner = THIS_MODULE,
- .open = proc_vis_open,
+ .open = proc_vis_data_open,
.read = seq_read,
- .write = proc_vis_write,
+ .write = proc_dummy_write,
.llseek = seq_lseek,
.release = single_release,
};
@@ -760,15 +518,6 @@ static const struct file_operations proc_transt_global_fops = {
.release = single_release,
};
-static const struct file_operations proc_log_level_fops = {
- .owner = THIS_MODULE,
- .open = proc_log_level_open,
- .read = seq_read,
- .write = proc_log_level_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
static const struct file_operations proc_interfaces_fops = {
.owner = THIS_MODULE,
.open = proc_interfaces_open,
@@ -795,12 +544,6 @@ void cleanup_procfs(void)
if (proc_transt_local_file)
remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir);
- if (proc_log_file)
- remove_proc_entry(PROC_FILE_LOG, proc_batman_dir);
-
- if (proc_log_level_file)
- remove_proc_entry(PROC_FILE_LOG_LEVEL, proc_batman_dir);
-
if (proc_originators_file)
remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir);
@@ -810,11 +553,11 @@ void cleanup_procfs(void)
if (proc_interface_file)
remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
- if (proc_vis_file)
- remove_proc_entry(PROC_FILE_VIS, proc_batman_dir);
+ if (proc_vis_data_file)
+ remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir);
- if (proc_vis_format_file)
- remove_proc_entry(PROC_FILE_VIS_FORMAT, proc_batman_dir);
+ if (proc_vis_srv_file)
+ remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir);
if (proc_aggr_file)
remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir);
@@ -862,17 +605,6 @@ int setup_procfs(void)
return -EFAULT;
}
- proc_log_level_file = create_proc_entry(PROC_FILE_LOG_LEVEL,
- S_IWUSR | S_IRUGO,
- proc_batman_dir);
- if (proc_log_level_file) {
- proc_log_level_file->proc_fops = &proc_log_level_fops;
- } else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_LOG_LEVEL);
- cleanup_procfs();
- return -EFAULT;
- }
-
proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS,
S_IRUGO, proc_batman_dir);
if (proc_originators_file) {
@@ -883,16 +615,6 @@ int setup_procfs(void)
return -EFAULT;
}
- proc_log_file = create_proc_entry(PROC_FILE_LOG,
- S_IRUGO, proc_batman_dir);
- if (proc_log_file) {
- proc_log_file->proc_fops = &proc_log_operations;
- } else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_FILE_LOG, PROC_FILE_GATEWAYS);
- cleanup_procfs();
- return -EFAULT;
- }
-
proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL,
S_IRUGO, proc_batman_dir);
if (proc_transt_local_file) {
@@ -913,23 +635,23 @@ int setup_procfs(void)
return -EFAULT;
}
- proc_vis_file = create_proc_entry(PROC_FILE_VIS, S_IWUSR | S_IRUGO,
- proc_batman_dir);
- if (proc_vis_file) {
- proc_vis_file->proc_fops = &proc_vis_fops;
+ proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV,
+ S_IWUSR | S_IRUGO,
+ proc_batman_dir);
+ if (proc_vis_srv_file) {
+ proc_vis_srv_file->proc_fops = &proc_vis_srv_fops;
} else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS);
+ printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_SRV);
cleanup_procfs();
return -EFAULT;
}
- proc_vis_format_file = create_proc_entry(PROC_FILE_VIS_FORMAT,
- S_IWUSR | S_IRUGO,
- proc_batman_dir);
- if (proc_vis_format_file) {
- proc_vis_format_file->proc_fops = &proc_vis_format_fops;
+ proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO,
+ proc_batman_dir);
+ if (proc_vis_data_file) {
+ proc_vis_data_file->proc_fops = &proc_vis_data_fops;
} else {
- printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_FORMAT);
+ printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_DATA);
cleanup_procfs();
return -EFAULT;
}
@@ -946,5 +668,3 @@ int setup_procfs(void)
return 0;
}
-
-
diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h
index 16d3efdebe5..cd690e0f3e4 100644
--- a/drivers/staging/batman-adv/proc.h
+++ b/drivers/staging/batman-adv/proc.h
@@ -31,19 +31,10 @@
#define PROC_FILE_LOG_LEVEL "log_level"
#define PROC_FILE_TRANST_LOCAL "transtable_local"
#define PROC_FILE_TRANST_GLOBAL "transtable_global"
-#define PROC_FILE_VIS "vis"
-#define PROC_FILE_VIS_FORMAT "vis_format"
+#define PROC_FILE_VIS_SRV "vis_server"
+#define PROC_FILE_VIS_DATA "vis_data"
#define PROC_FILE_AGGR "aggregate_ogm"
void cleanup_procfs(void);
int setup_procfs(void);
-/* While scanning for vis-entries of a particular vis-originator
- * this list collects its interfaces to create a subgraph/cluster
- * out of them later
- */
-struct vis_if_list {
- uint8_t addr[ETH_ALEN];
- bool primary;
- struct vis_if_list *next;
-};
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c
index 4a14c363ac2..d89048beebe 100644
--- a/drivers/staging/batman-adv/routing.c
+++ b/drivers/staging/batman-adv/routing.c
@@ -19,304 +19,226 @@
*
*/
-
-
-
-
#include "main.h"
#include "routing.h"
-#include "log.h"
#include "send.h"
+#include "hash.h"
#include "soft-interface.h"
#include "hard-interface.h"
#include "device.h"
#include "translation-table.h"
+#include "originator.h"
#include "types.h"
-#include "hash.h"
#include "ring_buffer.h"
#include "vis.h"
#include "aggregation.h"
-#include "compat.h"
-
-
DECLARE_WAIT_QUEUE_HEAD(thread_wait);
-static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
-
-static atomic_t data_ready_cond;
-atomic_t exit_cond;
-
-static void start_purge_timer(void)
-{
- queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
-}
-
-int originator_init(void)
-{
- if (orig_hash)
- return 1;
-
- spin_lock(&orig_hash_lock);
- orig_hash = hash_new(128, compare_orig, choose_orig);
-
- if (!orig_hash)
- goto err;
-
- spin_unlock(&orig_hash_lock);
- start_purge_timer();
- return 1;
-
-err:
- spin_unlock(&orig_hash_lock);
- return 0;
-}
-
-void originator_free(void)
-{
- if (!orig_hash)
- return;
-
- cancel_delayed_work_sync(&purge_orig_wq);
-
- spin_lock(&orig_hash_lock);
- hash_delete(orig_hash, free_orig_node);
- orig_hash = NULL;
- spin_unlock(&orig_hash_lock);
-}
-static struct neigh_node *create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming)
+void slide_own_bcast_window(struct batman_if *batman_if)
{
- struct neigh_node *neigh_node;
+ HASHIT(hashit);
+ struct orig_node *orig_node;
+ TYPE_OF_WORD *word;
+ unsigned long flags;
- debug_log(LOG_TYPE_BATMAN, "Creating new last-hop neighbour of originator\n");
+ spin_lock_irqsave(&orig_hash_lock, flags);
- neigh_node = kmalloc(sizeof(struct neigh_node), GFP_ATOMIC);
- memset(neigh_node, 0, sizeof(struct neigh_node));
- INIT_LIST_HEAD(&neigh_node->list);
+ while (hash_iterate(orig_hash, &hashit)) {
+ orig_node = hashit.bucket->data;
+ word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]);
- memcpy(neigh_node->addr, neigh, ETH_ALEN);
- neigh_node->orig_node = orig_neigh_node;
- neigh_node->if_incoming = if_incoming;
+ bit_get_packet(word, 1, 0);
+ orig_node->bcast_own_sum[batman_if->if_num] =
+ bit_packet_count(word);
+ }
- list_add_tail(&neigh_node->list, &orig_node->neigh_list);
- return neigh_node;
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
}
-void free_orig_node(void *data)
+static void update_HNA(struct orig_node *orig_node,
+ unsigned char *hna_buff, int hna_buff_len)
{
- struct list_head *list_pos, *list_pos_tmp;
- struct neigh_node *neigh_node;
- struct orig_node *orig_node = (struct orig_node *)data;
+ if ((hna_buff_len != orig_node->hna_buff_len) ||
+ ((hna_buff_len > 0) &&
+ (orig_node->hna_buff_len > 0) &&
+ (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
- /* for all neighbours towards this originator ... */
- list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
- neigh_node = list_entry(list_pos, struct neigh_node, list);
+ if (orig_node->hna_buff_len > 0)
+ hna_global_del_orig(orig_node,
+ "originator changed hna");
- list_del(list_pos);
- kfree(neigh_node);
+ if ((hna_buff_len > 0) && (hna_buff != NULL))
+ hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
}
-
- hna_global_del_orig(orig_node, "originator timed out");
-
- kfree(orig_node->bcast_own);
- kfree(orig_node->bcast_own_sum);
- kfree(orig_node);
}
-/* this function finds or creates an originator entry for the given address if it does not exits */
-static struct orig_node *get_orig_node(uint8_t *addr)
+static void update_route(struct orig_node *orig_node,
+ struct neigh_node *neigh_node,
+ unsigned char *hna_buff, int hna_buff_len)
{
- struct orig_node *orig_node;
- struct hashtable_t *swaphash;
- char orig_str[ETH_STR_LEN];
-
- orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
-
- if (orig_node != NULL)
- return orig_node;
-
- addr_to_string(orig_str, addr);
- debug_log(LOG_TYPE_BATMAN, "Creating new originator: %s \n", orig_str);
-
- orig_node = kmalloc(sizeof(struct orig_node), GFP_ATOMIC);
- memset(orig_node, 0, sizeof(struct orig_node));
- INIT_LIST_HEAD(&orig_node->neigh_list);
-
- memcpy(orig_node->orig, addr, ETH_ALEN);
- orig_node->router = NULL;
- orig_node->batman_if = NULL;
- orig_node->hna_buff = NULL;
+ /* route deleted */
+ if ((orig_node->router != NULL) && (neigh_node == NULL)) {
- orig_node->bcast_own = kmalloc(num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS, GFP_ATOMIC);
- memset(orig_node->bcast_own, 0, num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS);
+ bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n",
+ orig_node->orig);
+ hna_global_del_orig(orig_node, "originator timed out");
- orig_node->bcast_own_sum = kmalloc(num_ifs * sizeof(uint8_t), GFP_ATOMIC);
- memset(orig_node->bcast_own_sum, 0, num_ifs * sizeof(uint8_t));
-
- hash_add(orig_hash, orig_node);
+ /* route added */
+ } else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
- if (orig_hash->elements * 4 > orig_hash->size) {
- swaphash = hash_resize(orig_hash, orig_hash->size * 2);
+ bat_dbg(DBG_ROUTES,
+ "Adding route towards: %pM (via %pM)\n",
+ orig_node->orig, neigh_node->addr);
+ hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
- if (swaphash == NULL)
- debug_log(LOG_TYPE_CRIT, "Couldn't resize orig hash table \n");
- else
- orig_hash = swaphash;
+ /* route changed */
+ } else {
+ bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr);
}
- return orig_node;
-}
-
-void slide_own_bcast_window(struct batman_if *batman_if)
-{
- struct hash_it_t *hashit = NULL;
- struct orig_node *orig_node;
-
- spin_lock(&orig_hash_lock);
-
- while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
- orig_node = hashit->bucket->data;
-
- bit_get_packet((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]), 1, 0);
- orig_node->bcast_own_sum[batman_if->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]));
- }
+ if (neigh_node != NULL)
+ orig_node->batman_if = neigh_node->if_incoming;
+ else
+ orig_node->batman_if = NULL;
- spin_unlock(&orig_hash_lock);
+ orig_node->router = neigh_node;
}
-static void update_routes(struct orig_node *orig_node, struct neigh_node *neigh_node, unsigned char *hna_buff, int hna_buff_len)
+
+void update_routes(struct orig_node *orig_node,
+ struct neigh_node *neigh_node,
+ unsigned char *hna_buff, int hna_buff_len)
{
- char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
if (orig_node == NULL)
return;
- if (orig_node->router != neigh_node) {
- addr_to_string(orig_str, orig_node->orig);
-
- /* route deleted */
- if ((orig_node->router != NULL) && (neigh_node == NULL)) {
-
- debug_log(LOG_TYPE_ROUTES, "Deleting route towards: %s\n", orig_str);
- hna_global_del_orig(orig_node, "originator timed out");
-
- /* route added */
- } else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
-
- addr_to_string(neigh_str, neigh_node->addr);
- debug_log(LOG_TYPE_ROUTES, "Adding route towards: %s (via %s)\n", orig_str, neigh_str);
- hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
-
- /* route changed */
- } else {
-
- addr_to_string(neigh_str, neigh_node->addr);
- addr_to_string(router_str, orig_node->router->addr);
- debug_log(LOG_TYPE_ROUTES, "Changing route towards: %s (now via %s - was via %s)\n", orig_str, neigh_str, router_str);
-
- }
-
- if (neigh_node != NULL)
- orig_node->batman_if = neigh_node->if_incoming;
- else
- orig_node->batman_if = NULL;
-
- orig_node->router = neigh_node;
-
+ if (orig_node->router != neigh_node)
+ update_route(orig_node, neigh_node, hna_buff, hna_buff_len);
/* may be just HNA changed */
- } else {
-
- if ((hna_buff_len != orig_node->hna_buff_len) || ((hna_buff_len > 0) && (orig_node->hna_buff_len > 0) && (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
-
- if (orig_node->hna_buff_len > 0)
- hna_global_del_orig(orig_node, "originator changed hna");
-
- if ((hna_buff_len > 0) && (hna_buff != NULL))
- hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
-
- }
-
- }
+ else
+ update_HNA(orig_node, hna_buff, hna_buff_len);
}
-static int isBidirectionalNeigh(struct orig_node *orig_node, struct orig_node *orig_neigh_node, struct batman_packet *batman_packet, struct batman_if *if_incoming)
+static int isBidirectionalNeigh(struct orig_node *orig_node,
+ struct orig_node *orig_neigh_node,
+ struct batman_packet *batman_packet,
+ struct batman_if *if_incoming)
{
struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
- char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN];
unsigned char total_count;
- addr_to_string(orig_str, orig_node->orig);
- addr_to_string(neigh_str, orig_neigh_node->orig);
-
if (orig_node == orig_neigh_node) {
- list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
+ list_for_each_entry(tmp_neigh_node,
+ &orig_node->neigh_list,
+ list) {
- if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming))
+ if (compare_orig(tmp_neigh_node->addr,
+ orig_neigh_node->orig) &&
+ (tmp_neigh_node->if_incoming == if_incoming))
neigh_node = tmp_neigh_node;
}
- if (neigh_node == NULL)
- neigh_node = create_neighbor(orig_node, orig_neigh_node, orig_neigh_node->orig, if_incoming);
+ if (!neigh_node)
+ neigh_node = create_neighbor(orig_node,
+ orig_neigh_node,
+ orig_neigh_node->orig,
+ if_incoming);
+ /* create_neighbor failed, return 0 */
+ if (!neigh_node)
+ return 0;
neigh_node->last_valid = jiffies;
} else {
/* find packet count of corresponding one hop neighbor */
- list_for_each_entry(tmp_neigh_node, &orig_neigh_node->neigh_list, list) {
+ list_for_each_entry(tmp_neigh_node,
+ &orig_neigh_node->neigh_list, list) {
- if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming))
+ if (compare_orig(tmp_neigh_node->addr,
+ orig_neigh_node->orig) &&
+ (tmp_neigh_node->if_incoming == if_incoming))
neigh_node = tmp_neigh_node;
}
- if (neigh_node == NULL)
- neigh_node = create_neighbor(orig_neigh_node, orig_neigh_node, orig_neigh_node->orig, if_incoming);
+ if (!neigh_node)
+ neigh_node = create_neighbor(orig_neigh_node,
+ orig_neigh_node,
+ orig_neigh_node->orig,
+ if_incoming);
+ /* create_neighbor failed, return 0 */
+ if (!neigh_node)
+ return 0;
}
orig_node->last_valid = jiffies;
/* pay attention to not get a value bigger than 100 % */
- total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > neigh_node->real_packet_count ? neigh_node->real_packet_count : orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
+ total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] >
+ neigh_node->real_packet_count ?
+ neigh_node->real_packet_count :
+ orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
/* if we have too few packets (too less data) we set tq_own to zero */
/* if we receive too few packets it is not considered bidirectional */
- if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
+ if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
+ (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
orig_neigh_node->tq_own = 0;
else
- /* neigh_node->real_packet_count is never zero as we only purge old information when getting new information */
- orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / neigh_node->real_packet_count;
+ /* neigh_node->real_packet_count is never zero as we
+ * only purge old information when getting new
+ * information */
+ orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) /
+ neigh_node->real_packet_count;
/*
- * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE
- * this does affect the nearly-symmetric links only a little,
- * but punishes asymmetric links more.
- * this will give a value between 0 and TQ_MAX_VALUE
+ * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
+ * affect the nearly-symmetric links only a little, but
+ * punishes asymmetric links more. This will give a value
+ * between 0 and TQ_MAX_VALUE
*/
- orig_neigh_node->tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE *
- (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
- (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
- (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) /
- (TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE);
-
- batman_packet->tq = ((batman_packet->tq * orig_neigh_node->tq_own * orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE * TQ_MAX_VALUE));
-
- debug_log(LOG_TYPE_BATMAN, "bidirectional: orig = %-15s neigh = %-15s => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n",
- orig_str, neigh_str, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq);
-
- /* if link has the minimum required transmission quality consider it bidirectional */
+ orig_neigh_node->tq_asym_penalty =
+ TQ_MAX_VALUE -
+ (TQ_MAX_VALUE *
+ (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
+ (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
+ (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) /
+ (TQ_LOCAL_WINDOW_SIZE *
+ TQ_LOCAL_WINDOW_SIZE *
+ TQ_LOCAL_WINDOW_SIZE);
+
+ batman_packet->tq = ((batman_packet->tq *
+ orig_neigh_node->tq_own *
+ orig_neigh_node->tq_asym_penalty) /
+ (TQ_MAX_VALUE * TQ_MAX_VALUE));
+
+ bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n",
+ orig_node->orig, orig_neigh_node->orig, total_count,
+ neigh_node->real_packet_count, orig_neigh_node->tq_own,
+ orig_neigh_node->tq_asym_penalty, batman_packet->tq);
+
+ /* if link has the minimum required transmission quality
+ * consider it bidirectional */
if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
return 1;
return 0;
}
-static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming, unsigned char *hna_buff, int hna_buff_len, char is_duplicate)
+static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
+ struct batman_packet *batman_packet,
+ struct batman_if *if_incoming,
+ unsigned char *hna_buff, int hna_buff_len,
+ char is_duplicate)
{
struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
int tmp_hna_buff_len;
- debug_log(LOG_TYPE_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n");
+ bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n");
list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
- if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) {
+ if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
+ (tmp_neigh_node->if_incoming == if_incoming)) {
neigh_node = tmp_neigh_node;
continue;
}
@@ -324,19 +246,34 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru
if (is_duplicate)
continue;
- ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0);
- tmp_neigh_node->tq_avg = ring_buffer_avg(tmp_neigh_node->tq_recv);
+ ring_buffer_set(tmp_neigh_node->tq_recv,
+ &tmp_neigh_node->tq_index, 0);
+ tmp_neigh_node->tq_avg =
+ ring_buffer_avg(tmp_neigh_node->tq_recv);
}
- if (neigh_node == NULL)
- neigh_node = create_neighbor(orig_node, get_orig_node(ethhdr->h_source), ethhdr->h_source, if_incoming);
- else
- debug_log(LOG_TYPE_BATMAN, "Updating existing last-hop neighbour of originator\n");
+ if (!neigh_node) {
+ struct orig_node *orig_tmp;
+
+ orig_tmp = get_orig_node(ethhdr->h_source);
+ if (!orig_tmp)
+ return;
+
+ neigh_node = create_neighbor(orig_node,
+ orig_tmp,
+ ethhdr->h_source, if_incoming);
+ if (!neigh_node)
+ return;
+ } else
+ bat_dbg(DBG_BATMAN,
+ "Updating existing last-hop neighbor of originator\n");
orig_node->flags = batman_packet->flags;
neigh_node->last_valid = jiffies;
- ring_buffer_set(neigh_node->tq_recv, &neigh_node->tq_index, batman_packet->tq);
+ ring_buffer_set(neigh_node->tq_recv,
+ &neigh_node->tq_index,
+ batman_packet->tq);
neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
if (!is_duplicate) {
@@ -344,9 +281,11 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru
neigh_node->last_ttl = batman_packet->ttl;
}
- tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? batman_packet->num_hna * ETH_ALEN : hna_buff_len);
+ tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
+ batman_packet->num_hna * ETH_ALEN : hna_buff_len);
- /* if this neighbor already is our next hop there is nothing to change */
+ /* if this neighbor already is our next hop there is nothing
+ * to change */
if (orig_node->router == neigh_node)
goto update_hna;
@@ -355,11 +294,12 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru
(orig_node->router->tq_avg > neigh_node->tq_avg))
goto update_hna;
- /* if the TQ is the same and the link not more symetric we won't consider it either */
+ /* if the TQ is the same and the link not more symetric we
+ * won't consider it either */
if ((orig_node->router) &&
((neigh_node->tq_avg == orig_node->router->tq_avg) &&
- (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] >=
- neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
+ (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num]
+ >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
goto update_hna;
update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len);
@@ -367,60 +307,72 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru
update_hna:
update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len);
- return;
}
-static char count_real_packets(struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming)
+static char count_real_packets(struct ethhdr *ethhdr,
+ struct batman_packet *batman_packet,
+ struct batman_if *if_incoming)
{
struct orig_node *orig_node;
struct neigh_node *tmp_neigh_node;
char is_duplicate = 0;
-
+ uint16_t seq_diff;
orig_node = get_orig_node(batman_packet->orig);
if (orig_node == NULL)
return 0;
-
list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
if (!is_duplicate)
- is_duplicate = get_bit_status(tmp_neigh_node->real_bits, orig_node->last_real_seqno, batman_packet->seqno);
-
- if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming))
- bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 1);
+ is_duplicate =
+ get_bit_status(tmp_neigh_node->real_bits,
+ orig_node->last_real_seqno,
+ batman_packet->seqno);
+ seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
+ if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
+ (tmp_neigh_node->if_incoming == if_incoming))
+ bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 1);
else
- bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 0);
+ bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 0);
- tmp_neigh_node->real_packet_count = bit_packet_count(tmp_neigh_node->real_bits);
+ tmp_neigh_node->real_packet_count =
+ bit_packet_count(tmp_neigh_node->real_bits);
}
if (!is_duplicate) {
- debug_log(LOG_TYPE_BATMAN, "updating last_seqno: old %d, new %d \n", orig_node->last_real_seqno, batman_packet->seqno);
+ bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d \n",
+ orig_node->last_real_seqno, batman_packet->seqno);
orig_node->last_real_seqno = batman_packet->seqno;
}
return is_duplicate;
}
-void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming)
+void receive_bat_packet(struct ethhdr *ethhdr,
+ struct batman_packet *batman_packet,
+ unsigned char *hna_buff, int hna_buff_len,
+ struct batman_if *if_incoming)
{
struct batman_if *batman_if;
struct orig_node *orig_neigh_node, *orig_node;
- char orig_str[ETH_STR_LEN], prev_sender_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN];
char has_directlink_flag;
- char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0, is_broadcast = 0, is_bidirectional, is_single_hop_neigh, is_duplicate;
+ char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
+ char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
+ char is_duplicate;
unsigned short if_incoming_seqno;
- /* Silently drop when the batman packet is actually not a correct packet.
+ /* Silently drop when the batman packet is actually not a
+ * correct packet.
*
* This might happen if a packet is padded (e.g. Ethernet has a
* minimum frame length of 64 byte) and the aggregation interprets
* it as an additional length.
*
- * TODO: A more sane solution would be to have a bit in the batman_packet
- * to detect whether the packet is the last packet in an aggregation.
- * Here we expect that the padding is always zero (or not 0x01)
+ * TODO: A more sane solution would be to have a bit in the
+ * batman_packet to detect whether the packet is the last
+ * packet in an aggregation. Here we expect that the padding
+ * is always zero (or not 0x01)
*/
if (batman_packet->packet_type != BAT_PACKET)
return;
@@ -428,27 +380,31 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack
/* could be changed by schedule_own_packet() */
if_incoming_seqno = atomic_read(&if_incoming->seqno);
- addr_to_string(orig_str, batman_packet->orig);
- addr_to_string(prev_sender_str, batman_packet->prev_sender);
- addr_to_string(neigh_str, ethhdr->h_source);
-
has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
- is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0);
+ is_single_hop_neigh = (compare_orig(ethhdr->h_source,
+ batman_packet->orig) ? 1 : 0);
- debug_log(LOG_TYPE_BATMAN, "Received BATMAN packet via NB: %s, IF: %s [%s] (from OG: %s, via prev OG: %s, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n", neigh_str, if_incoming->dev, if_incoming->addr_str, orig_str, prev_sender_str, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, batman_packet->version, has_directlink_flag);
+ bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n",
+ ethhdr->h_source, if_incoming->dev, if_incoming->addr_str,
+ batman_packet->orig, batman_packet->prev_sender,
+ batman_packet->seqno, batman_packet->tq, batman_packet->ttl,
+ batman_packet->version, has_directlink_flag);
list_for_each_entry_rcu(batman_if, &if_list, list) {
if (batman_if->if_active != IF_ACTIVE)
continue;
- if (compare_orig(ethhdr->h_source, batman_if->net_dev->dev_addr))
+ if (compare_orig(ethhdr->h_source,
+ batman_if->net_dev->dev_addr))
is_my_addr = 1;
- if (compare_orig(batman_packet->orig, batman_if->net_dev->dev_addr))
+ if (compare_orig(batman_packet->orig,
+ batman_if->net_dev->dev_addr))
is_my_orig = 1;
- if (compare_orig(batman_packet->prev_sender, batman_if->net_dev->dev_addr))
+ if (compare_orig(batman_packet->prev_sender,
+ batman_if->net_dev->dev_addr))
is_my_oldorig = 1;
if (compare_orig(ethhdr->h_source, broadcastAddr))
@@ -456,44 +412,61 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack
}
if (batman_packet->version != COMPAT_VERSION) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version);
+ bat_dbg(DBG_BATMAN,
+ "Drop packet: incompatible batman version (%i)\n",
+ batman_packet->version);
return;
}
if (is_my_addr) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: received my own broadcast (sender: %s) \n", neigh_str);
+ bat_dbg(DBG_BATMAN,
+ "Drop packet: received my own broadcast (sender: %pM)\n",
+ ethhdr->h_source);
return;
}
if (is_broadcast) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %s) \n", neigh_str);
+ bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM) \n", ethhdr->h_source);
return;
}
if (is_my_orig) {
+ TYPE_OF_WORD *word;
+ int offset;
+
orig_neigh_node = get_orig_node(ethhdr->h_source);
- /* neighbour has to indicate direct link and it has to come via the corresponding interface */
- /* if received seqno equals last send seqno save new seqno for bidirectional check */
- if (has_directlink_flag && compare_orig(if_incoming->net_dev->dev_addr, batman_packet->orig) &&
- (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
- bit_mark((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS]), 0);
- orig_neigh_node->bcast_own_sum[if_incoming->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS]));
+ if (!orig_neigh_node)
+ return;
+
+ /* neighbor has to indicate direct link and it has to
+ * come via the corresponding interface */
+ /* if received seqno equals last send seqno save new
+ * seqno for bidirectional check */
+ if (has_directlink_flag &&
+ compare_orig(if_incoming->net_dev->dev_addr,
+ batman_packet->orig) &&
+ (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
+ offset = if_incoming->if_num * NUM_WORDS;
+ word = &(orig_neigh_node->bcast_own[offset]);
+ bit_mark(word, 0);
+ orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
+ bit_packet_count(word);
}
- debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet from myself (via neighbour) \n");
+ bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor) \n");
return;
}
if (batman_packet->tq == 0) {
count_real_packets(ethhdr, batman_packet, if_incoming);
- debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet with tq equal 0 \n");
+ bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0 \n");
return;
}
if (is_my_oldorig) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %s) \n", neigh_str);
+ bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM) \n", ethhdr->h_source);
return;
}
@@ -504,507 +477,502 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack
return;
/* avoid temporary routing loops */
- if ((orig_node->router) && (orig_node->router->orig_node->router) &&
- (compare_orig(orig_node->router->addr, batman_packet->prev_sender)) &&
+ if ((orig_node->router) &&
+ (orig_node->router->orig_node->router) &&
+ (compare_orig(orig_node->router->addr,
+ batman_packet->prev_sender)) &&
!(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
- (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %s) \n", neigh_str);
+ (compare_orig(orig_node->router->addr,
+ orig_node->router->orig_node->router->addr))) {
+ bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM) \n", ethhdr->h_source);
return;
}
- /* if sender is a direct neighbor the sender mac equals originator mac */
- orig_neigh_node = (is_single_hop_neigh ? orig_node : get_orig_node(ethhdr->h_source));
+ /* if sender is a direct neighbor the sender mac equals
+ * originator mac */
+ orig_neigh_node = (is_single_hop_neigh ?
+ orig_node : get_orig_node(ethhdr->h_source));
if (orig_neigh_node == NULL)
return;
- /* drop packet if sender is not a direct neighbor and if we don't route towards it */
- if (!is_single_hop_neigh && (orig_neigh_node->router == NULL)) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: OGM via unknown neighbor! \n");
+ /* drop packet if sender is not a direct neighbor and if we
+ * don't route towards it */
+ if (!is_single_hop_neigh &&
+ (orig_neigh_node->router == NULL)) {
+ bat_dbg(DBG_BATMAN, "Drop packet: OGM via unknown neighbor!\n");
return;
}
- is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node, batman_packet, if_incoming);
+ is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node,
+ batman_packet, if_incoming);
- /* update ranking if it is not a duplicate or has the same seqno and similar ttl as the non-duplicate */
- if (is_bidirectional && (!is_duplicate ||
- ((orig_node->last_real_seqno == batman_packet->seqno) &&
- (orig_node->last_ttl - 3 <= batman_packet->ttl))))
- update_orig(orig_node, ethhdr, batman_packet, if_incoming, hna_buff, hna_buff_len, is_duplicate);
+ /* update ranking if it is not a duplicate or has the same
+ * seqno and similar ttl as the non-duplicate */
+ if (is_bidirectional &&
+ (!is_duplicate ||
+ ((orig_node->last_real_seqno == batman_packet->seqno) &&
+ (orig_node->last_ttl - 3 <= batman_packet->ttl))))
+ update_orig(orig_node, ethhdr, batman_packet,
+ if_incoming, hna_buff, hna_buff_len, is_duplicate);
- /* is single hop (direct) neighbour */
+ /* is single hop (direct) neighbor */
if (is_single_hop_neigh) {
/* mark direct link on incoming interface */
- schedule_forward_packet(orig_node, ethhdr, batman_packet, 1, hna_buff_len, if_incoming);
+ schedule_forward_packet(orig_node, ethhdr, batman_packet,
+ 1, hna_buff_len, if_incoming);
- debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast neighbour packet with direct link flag \n");
+ bat_dbg(DBG_BATMAN, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
return;
}
/* multihop originator */
if (!is_bidirectional) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: not received via bidirectional link\n");
+ bat_dbg(DBG_BATMAN,
+ "Drop packet: not received via bidirectional link\n");
return;
}
if (is_duplicate) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: duplicate packet received\n");
+ bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n");
return;
}
- debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast originator packet \n");
- schedule_forward_packet(orig_node, ethhdr, batman_packet, 0, hna_buff_len, if_incoming);
+ bat_dbg(DBG_BATMAN,
+ "Forwarding packet: rebroadcast originator packet\n");
+ schedule_forward_packet(orig_node, ethhdr, batman_packet,
+ 0, hna_buff_len, if_incoming);
}
-void purge_orig(struct work_struct *work)
+int recv_bat_packet(struct sk_buff *skb,
+ struct batman_if *batman_if)
{
- struct list_head *list_pos, *list_pos_tmp;
- struct hash_it_t *hashit = NULL;
- struct orig_node *orig_node;
- struct neigh_node *neigh_node, *best_neigh_node;
- char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], neigh_purged;
-
- spin_lock(&orig_hash_lock);
-
- /* for all origins... */
- while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
-
- orig_node = hashit->bucket->data;
- addr_to_string(orig_str, orig_node->orig);
-
- if (time_after(jiffies, orig_node->last_valid + ((2 * PURGE_TIMEOUT * HZ) / 1000))) {
-
- debug_log(LOG_TYPE_BATMAN, "Originator timeout: originator %s, last_valid %u \n", orig_str, (orig_node->last_valid / HZ));
-
- hash_remove_bucket(orig_hash, hashit);
- free_orig_node(orig_node);
-
- } else {
-
- best_neigh_node = NULL;
- neigh_purged = 0;
-
- /* for all neighbours towards this originator ... */
- list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
- neigh_node = list_entry(list_pos, struct neigh_node, list);
-
- if (time_after(jiffies, neigh_node->last_valid + ((PURGE_TIMEOUT * HZ) / 1000))) {
-
- addr_to_string(neigh_str, neigh_node->addr);
- debug_log(LOG_TYPE_BATMAN, "Neighbour timeout: originator %s, neighbour: %s, last_valid %u \n", orig_str, neigh_str, (neigh_node->last_valid / HZ));
-
- neigh_purged = 1;
- list_del(list_pos);
- kfree(neigh_node);
-
- } else {
-
- if ((best_neigh_node == NULL) || (neigh_node->tq_avg > best_neigh_node->tq_avg))
- best_neigh_node = neigh_node;
-
- }
-
- }
+ struct ethhdr *ethhdr;
+ unsigned long flags;
+
+ /* drop packet if it has not necessary minimum size */
+ if (skb_headlen(skb) < sizeof(struct batman_packet))
+ return NET_RX_DROP;
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* packet with broadcast indication but unicast recipient */
+ if (!is_bcast(ethhdr->h_dest))
+ return NET_RX_DROP;
+
+ /* packet with broadcast sender address */
+ if (is_bcast(ethhdr->h_source))
+ return NET_RX_DROP;
+
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ /* TODO: we use headlen instead of "length", because
+ * only this data is paged in. */
+ /* TODO: is another skb_copy needed here? there will be
+ * written on the data, but nobody (?) should further use
+ * this data */
+ receive_aggr_bat_packet(ethhdr,
+ skb->data,
+ skb_headlen(skb),
+ batman_if);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ kfree_skb(skb);
+ return NET_RX_SUCCESS;
+}
- if (neigh_purged)
- update_routes(orig_node, best_neigh_node, orig_node->hna_buff, orig_node->hna_buff_len);
+static int recv_my_icmp_packet(struct sk_buff *skb)
+{
+ struct orig_node *orig_node;
+ struct icmp_packet *icmp_packet;
+ struct ethhdr *ethhdr;
+ struct sk_buff *skb_old;
+ struct batman_if *batman_if;
+ int ret;
+ unsigned long flags;
+ uint8_t dstaddr[ETH_ALEN];
- }
+ icmp_packet = (struct icmp_packet *) skb->data;
+ ethhdr = (struct ethhdr *) skb_mac_header(skb);
+ /* add data to device queue */
+ if (icmp_packet->msg_type != ECHO_REQUEST) {
+ bat_device_receive_packet(icmp_packet);
+ return NET_RX_DROP;
}
- spin_unlock(&orig_hash_lock);
+ /* answer echo request (ping) */
+ /* get routing information */
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)hash_find(orig_hash,
+ icmp_packet->orig));
+ ret = NET_RX_DROP;
+
+ if ((orig_node != NULL) &&
+ (orig_node->batman_if != NULL) &&
+ (orig_node->router != NULL)) {
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+ batman_if = orig_node->batman_if;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ /* create a copy of the skb, if needed, to modify it. */
+ skb_old = NULL;
+ if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+ skb_old = skb;
+ skb = skb_copy(skb, GFP_ATOMIC);
+ if (!skb)
+ return NET_RX_DROP;
+ icmp_packet = (struct icmp_packet *) skb->data;
+ kfree_skb(skb_old);
+ }
- start_purge_timer();
-}
+ memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+ memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
+ icmp_packet->msg_type = ECHO_REPLY;
+ icmp_packet->ttl = TTL;
-static int receive_raw_packet(struct socket *raw_sock, unsigned char *packet_buff, int packet_buff_len)
-{
- struct kvec iov;
- struct msghdr msg;
+ send_skb_packet(skb, batman_if, dstaddr);
+ ret = NET_RX_SUCCESS;
- iov.iov_base = packet_buff;
- iov.iov_len = packet_buff_len;
+ } else
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
- msg.msg_flags = MSG_DONTWAIT; /* non-blocking */
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_control = NULL;
-
- return kernel_recvmsg(raw_sock, &msg, &iov, 1, packet_buff_len, MSG_DONTWAIT);
+ return ret;
}
-int packet_recv_thread(void *data)
+static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
{
- struct batman_if *batman_if;
- struct ethhdr *ethhdr;
- struct batman_packet *batman_packet;
- struct unicast_packet *unicast_packet;
- struct bcast_packet *bcast_packet;
- struct icmp_packet *icmp_packet;
- struct vis_packet *vis_packet;
struct orig_node *orig_node;
- unsigned char *packet_buff, src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN];
- int vis_info_len;
- int result;
-
- atomic_set(&data_ready_cond, 0);
- atomic_set(&exit_cond, 0);
- packet_buff = kmalloc(PACKBUFF_SIZE, GFP_KERNEL);
- if (!packet_buff) {
- debug_log(LOG_TYPE_CRIT, "Could allocate memory for the packet buffer. :(\n");
- return -1;
+ struct icmp_packet *icmp_packet;
+ struct ethhdr *ethhdr;
+ struct sk_buff *skb_old;
+ struct batman_if *batman_if;
+ int ret;
+ unsigned long flags;
+ uint8_t dstaddr[ETH_ALEN];
+
+ icmp_packet = (struct icmp_packet *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* send TTL exceeded if packet is an echo request (traceroute) */
+ if (icmp_packet->msg_type != ECHO_REQUEST) {
+ printk(KERN_WARNING "batman-adv:Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
+ icmp_packet->orig, icmp_packet->dst);
+ return NET_RX_DROP;
}
- while ((!kthread_should_stop()) && (!atomic_read(&exit_cond))) {
-
- wait_event_interruptible(thread_wait, (atomic_read(&data_ready_cond) || atomic_read(&exit_cond)));
-
- atomic_set(&data_ready_cond, 0);
-
- if (kthread_should_stop() || atomic_read(&exit_cond))
- break;
-
- /* we only want to safely traverse the list, hard-interfaces
- * won't be deleted anyway as long as this thread runs. */
-
- rcu_read_lock();
- list_for_each_entry_rcu(batman_if, &if_list, list) {
- rcu_read_unlock();
-
- result = -1;
-
- while (1) {
- if (batman_if->if_active != IF_ACTIVE) {
- if (batman_if->if_active != IF_TO_BE_ACTIVATED)
- debug_log(LOG_TYPE_NOTICE,
- "Could not read from deactivated interface %s!\n",
- batman_if->dev);
-
- if (batman_if->raw_sock)
- receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE);
- result = 0;
- break;
- }
-
- result = receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE);
- if (result <= 0)
- break;
-
- if (result < sizeof(struct ethhdr) + 2)
- continue;
-
- ethhdr = (struct ethhdr *)packet_buff;
- batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ethhdr));
-
- if (batman_packet->version != COMPAT_VERSION) {
- debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version);
- continue;
- }
-
- switch (batman_packet->packet_type) {
- /* batman originator packet */
- case BAT_PACKET:
- /* packet with broadcast indication but unicast recipient */
- if (!is_bcast(ethhdr->h_dest))
- continue;
-
- /* packet with broadcast sender address */
- if (is_bcast(ethhdr->h_source))
- continue;
-
- /* drop packet if it has not at least one batman packet as payload */
- if (result < sizeof(struct ethhdr) + sizeof(struct batman_packet))
- continue;
-
- spin_lock(&orig_hash_lock);
- receive_aggr_bat_packet(ethhdr,
- packet_buff + sizeof(struct ethhdr),
- result - sizeof(struct ethhdr),
- batman_if);
- spin_unlock(&orig_hash_lock);
-
- break;
-
- /* batman icmp packet */
- case BAT_ICMP:
- /* packet with unicast indication but broadcast recipient */
- if (is_bcast(ethhdr->h_dest))
- continue;
-
- /* packet with broadcast sender address */
- if (is_bcast(ethhdr->h_source))
- continue;
-
- /* not for me */
- if (!is_my_mac(ethhdr->h_dest))
- continue;
-
- /* drop packet if it has not necessary minimum size */
- if (result < sizeof(struct ethhdr) + sizeof(struct icmp_packet))
- continue;
-
- icmp_packet = (struct icmp_packet *)(packet_buff + sizeof(struct ethhdr));
-
- /* packet for me */
- if (is_my_mac(icmp_packet->dst)) {
-
- /* add data to device queue */
- if (icmp_packet->msg_type != ECHO_REQUEST) {
- bat_device_receive_packet(icmp_packet);
- continue;
- }
-
- /* answer echo request (ping) */
- /* get routing information */
- spin_lock(&orig_hash_lock);
- orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig));
-
- if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
-
- memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
- icmp_packet->msg_type = ECHO_REPLY;
- icmp_packet->ttl = TTL;
-
- send_raw_packet(packet_buff + sizeof(struct ethhdr),
- result - sizeof(struct ethhdr),
- orig_node->batman_if,
- orig_node->router->addr);
-
- }
-
- spin_unlock(&orig_hash_lock);
- continue;
-
- }
-
- /* TTL exceeded */
- if (icmp_packet->ttl < 2) {
-
- addr_to_string(src_str, icmp_packet->orig);
- addr_to_string(dst_str, icmp_packet->dst);
-
- debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
-
- /* send TTL exceeded if packet is an echo request (traceroute) */
- if (icmp_packet->msg_type != ECHO_REQUEST)
- continue;
-
- /* get routing information */
- spin_lock(&orig_hash_lock);
- orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig));
-
- if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
-
- memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
- icmp_packet->msg_type = TTL_EXCEEDED;
- icmp_packet->ttl = TTL;
-
- send_raw_packet(packet_buff + sizeof(struct ethhdr),
- result - sizeof(struct ethhdr),
- orig_node->batman_if,
- orig_node->router->addr);
+ /* get routing information */
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)
+ hash_find(orig_hash, icmp_packet->orig));
+ ret = NET_RX_DROP;
+
+ if ((orig_node != NULL) &&
+ (orig_node->batman_if != NULL) &&
+ (orig_node->router != NULL)) {
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+ batman_if = orig_node->batman_if;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+ skb_old = skb;
+ skb = skb_copy(skb, GFP_ATOMIC);
+ if (!skb)
+ return NET_RX_DROP;
+ icmp_packet = (struct icmp_packet *) skb->data;
+ kfree_skb(skb_old);
+ }
- }
+ memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+ memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
+ icmp_packet->msg_type = TTL_EXCEEDED;
+ icmp_packet->ttl = TTL;
- spin_unlock(&orig_hash_lock);
- continue;
+ send_skb_packet(skb, batman_if, dstaddr);
+ ret = NET_RX_SUCCESS;
- }
+ } else
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
- /* get routing information */
- spin_lock(&orig_hash_lock);
- orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->dst));
+ return ret;
+}
- if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
- /* decrement ttl */
- icmp_packet->ttl--;
+int recv_icmp_packet(struct sk_buff *skb)
+{
+ struct icmp_packet *icmp_packet;
+ struct ethhdr *ethhdr;
+ struct orig_node *orig_node;
+ struct sk_buff *skb_old;
+ struct batman_if *batman_if;
+ int hdr_size = sizeof(struct icmp_packet);
+ int ret;
+ unsigned long flags;
+ uint8_t dstaddr[ETH_ALEN];
+
+ /* drop packet if it has not necessary minimum size */
+ if (skb_headlen(skb) < hdr_size)
+ return NET_RX_DROP;
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+ /* packet with unicast indication but broadcast recipient */
+ if (is_bcast(ethhdr->h_dest))
+ return NET_RX_DROP;
+
+ /* packet with broadcast sender address */
+ if (is_bcast(ethhdr->h_source))
+ return NET_RX_DROP;
+
+ /* not for me */
+ if (!is_my_mac(ethhdr->h_dest))
+ return NET_RX_DROP;
+
+ icmp_packet = (struct icmp_packet *) skb->data;
+
+ /* packet for me */
+ if (is_my_mac(icmp_packet->dst))
+ return recv_my_icmp_packet(skb);
+
+ /* TTL exceeded */
+ if (icmp_packet->ttl < 2)
+ return recv_icmp_ttl_exceeded(skb);
+
+ ret = NET_RX_DROP;
+
+ /* get routing information */
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)
+ hash_find(orig_hash, icmp_packet->dst));
+
+ if ((orig_node != NULL) &&
+ (orig_node->batman_if != NULL) &&
+ (orig_node->router != NULL)) {
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+ batman_if = orig_node->batman_if;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
+ skb_old = skb;
+ skb = skb_copy(skb, GFP_ATOMIC);
+ if (!skb)
+ return NET_RX_DROP;
+ icmp_packet = (struct icmp_packet *) skb->data;
+ kfree_skb(skb_old);
+ }
- /* route it */
- send_raw_packet(packet_buff + sizeof(struct ethhdr),
- result - sizeof(struct ethhdr),
- orig_node->batman_if,
- orig_node->router->addr);
- }
+ /* decrement ttl */
+ icmp_packet->ttl--;
- spin_unlock(&orig_hash_lock);
- break;
+ /* route it */
+ send_skb_packet(skb, batman_if, dstaddr);
+ ret = NET_RX_SUCCESS;
- /* unicast packet */
- case BAT_UNICAST:
- /* packet with unicast indication but broadcast recipient */
- if (is_bcast(ethhdr->h_dest))
- continue;
+ } else
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
- /* packet with broadcast sender address */
- if (is_bcast(ethhdr->h_source))
- continue;
+ return ret;
+}
- /* not for me */
- if (!is_my_mac(ethhdr->h_dest))
- continue;
+int recv_unicast_packet(struct sk_buff *skb)
+{
+ struct unicast_packet *unicast_packet;
+ struct orig_node *orig_node;
+ struct ethhdr *ethhdr;
+ struct batman_if *batman_if;
+ struct sk_buff *skb_old;
+ uint8_t dstaddr[ETH_ALEN];
+ int hdr_size = sizeof(struct unicast_packet);
+ int ret;
+ unsigned long flags;
- /* drop packet if it has not necessary minimum size */
- if (result < sizeof(struct ethhdr) + sizeof(struct unicast_packet))
- continue;
+ /* drop packet if it has not necessary minimum size */
+ if (skb_headlen(skb) < hdr_size)
+ return NET_RX_DROP;
- unicast_packet = (struct unicast_packet *)(packet_buff + sizeof(struct ethhdr));
+ ethhdr = (struct ethhdr *) skb_mac_header(skb);
- /* packet for me */
- if (is_my_mac(unicast_packet->dest)) {
+ /* packet with unicast indication but broadcast recipient */
+ if (is_bcast(ethhdr->h_dest))
+ return NET_RX_DROP;
- interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct unicast_packet), result - sizeof(struct ethhdr) - sizeof(struct unicast_packet));
- continue;
+ /* packet with broadcast sender address */
+ if (is_bcast(ethhdr->h_source))
+ return NET_RX_DROP;
- }
+ /* not for me */
+ if (!is_my_mac(ethhdr->h_dest))
+ return NET_RX_DROP;
- /* TTL exceeded */
- if (unicast_packet->ttl < 2) {
- addr_to_string(src_str, ((struct ethhdr *)(unicast_packet + 1))->h_source);
- addr_to_string(dst_str, unicast_packet->dest);
+ unicast_packet = (struct unicast_packet *) skb->data;
- debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
- continue;
- }
+ /* packet for me */
+ if (is_my_mac(unicast_packet->dest)) {
+ interface_rx(skb, hdr_size);
+ return NET_RX_SUCCESS;
+ }
- /* get routing information */
- spin_lock(&orig_hash_lock);
- orig_node = ((struct orig_node *)hash_find(orig_hash, unicast_packet->dest));
+ /* TTL exceeded */
+ if (unicast_packet->ttl < 2) {
+ printk(KERN_WARNING "batman-adv:Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n",
+ ethhdr->h_source, unicast_packet->dest);
+ return NET_RX_DROP;
+ }
- if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
- /* decrement ttl */
- unicast_packet->ttl--;
+ ret = NET_RX_DROP;
+ /* get routing information */
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)
+ hash_find(orig_hash, unicast_packet->dest));
+
+ if ((orig_node != NULL) &&
+ (orig_node->batman_if != NULL) &&
+ (orig_node->router != NULL)) {
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+ batman_if = orig_node->batman_if;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ /* create a copy of the skb, if needed, to modify it. */
+ if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
+ skb_old = skb;
+ skb = skb_copy(skb, GFP_ATOMIC);
+ if (!skb)
+ return NET_RX_DROP;
+ unicast_packet = (struct unicast_packet *) skb->data;
+ kfree_skb(skb_old);
+ }
+ /* decrement ttl */
+ unicast_packet->ttl--;
- /* route it */
- send_raw_packet(packet_buff + sizeof(struct ethhdr),
- result - sizeof(struct ethhdr),
- orig_node->batman_if,
- orig_node->router->addr);
- }
+ /* route it */
+ send_skb_packet(skb, batman_if, dstaddr);
+ ret = NET_RX_SUCCESS;
- spin_unlock(&orig_hash_lock);
- break;
+ } else
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
- /* broadcast packet */
- case BAT_BCAST:
- /* packet with broadcast indication but unicast recipient */
- if (!is_bcast(ethhdr->h_dest))
- continue;
+ return ret;
+}
- /* packet with broadcast sender address */
- if (is_bcast(ethhdr->h_source))
- continue;
- /* drop packet if it has not necessary minimum size */
- if (result < sizeof(struct ethhdr) + sizeof(struct bcast_packet))
- continue;
+int recv_bcast_packet(struct sk_buff *skb)
+{
+ struct orig_node *orig_node;
+ struct bcast_packet *bcast_packet;
+ struct ethhdr *ethhdr;
+ int hdr_size = sizeof(struct bcast_packet);
+ unsigned long flags;
- /* ignore broadcasts sent by myself */
- if (is_my_mac(ethhdr->h_source))
- continue;
+ /* drop packet if it has not necessary minimum size */
+ if (skb_headlen(skb) < hdr_size)
+ return NET_RX_DROP;
- bcast_packet = (struct bcast_packet *)(packet_buff + sizeof(struct ethhdr));
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
- /* ignore broadcasts originated by myself */
- if (is_my_mac(bcast_packet->orig))
- continue;
+ /* packet with broadcast indication but unicast recipient */
+ if (!is_bcast(ethhdr->h_dest))
+ return NET_RX_DROP;
- spin_lock(&orig_hash_lock);
- orig_node = ((struct orig_node *)hash_find(orig_hash, bcast_packet->orig));
+ /* packet with broadcast sender address */
+ if (is_bcast(ethhdr->h_source))
+ return NET_RX_DROP;
- if (orig_node == NULL) {
- spin_unlock(&orig_hash_lock);
- continue;
- }
+ /* ignore broadcasts sent by myself */
+ if (is_my_mac(ethhdr->h_source))
+ return NET_RX_DROP;
- /* check flood history */
- if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno, ntohs(bcast_packet->seqno))) {
- spin_unlock(&orig_hash_lock);
- continue;
- }
+ bcast_packet = (struct bcast_packet *) skb->data;
- /* mark broadcast in flood history */
- if (bit_get_packet(orig_node->bcast_bits, ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno, 1))
- orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
+ /* ignore broadcasts originated by myself */
+ if (is_my_mac(bcast_packet->orig))
+ return NET_RX_DROP;
- spin_unlock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)
+ hash_find(orig_hash, bcast_packet->orig));
- /* broadcast for me */
- interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct bcast_packet), result - sizeof(struct ethhdr) - sizeof(struct bcast_packet));
+ if (orig_node == NULL) {
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+ return NET_RX_DROP;
+ }
- /* rebroadcast packet */
- add_bcast_packet_to_list(packet_buff + sizeof(struct ethhdr),
- result - sizeof(struct ethhdr));
+ /* check flood history */
+ if (get_bit_status(orig_node->bcast_bits,
+ orig_node->last_bcast_seqno,
+ ntohs(bcast_packet->seqno))) {
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+ return NET_RX_DROP;
+ }
- break;
+ /* mark broadcast in flood history */
+ if (bit_get_packet(orig_node->bcast_bits,
+ ntohs(bcast_packet->seqno) -
+ orig_node->last_bcast_seqno, 1))
+ orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
- /* vis packet */
- case BAT_VIS:
- /* drop if too short. */
- if (result < sizeof(struct ethhdr) + sizeof(struct vis_packet))
- continue;
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
- /* not for me */
- if (!is_my_mac(ethhdr->h_dest))
- continue;
+ /* rebroadcast packet */
+ add_bcast_packet_to_list(skb);
- vis_packet = (struct vis_packet *)(packet_buff + sizeof(struct ethhdr));
- vis_info_len = result - sizeof(struct ethhdr) - sizeof(struct vis_packet);
+ /* broadcast for me */
+ interface_rx(skb, hdr_size);
- /* ignore own packets */
- if (is_my_mac(vis_packet->vis_orig))
- continue;
+ return NET_RX_SUCCESS;
+}
- if (is_my_mac(vis_packet->sender_orig))
- continue;
+int recv_vis_packet(struct sk_buff *skb)
+{
+ struct vis_packet *vis_packet;
+ struct ethhdr *ethhdr;
+ int hdr_size = sizeof(struct vis_packet);
- switch (vis_packet->vis_type) {
- case VIS_TYPE_SERVER_SYNC:
- receive_server_sync_packet(vis_packet, vis_info_len);
- break;
+ if (skb_headlen(skb) < hdr_size)
+ return NET_RX_DROP;
- case VIS_TYPE_CLIENT_UPDATE:
- receive_client_update_packet(vis_packet, vis_info_len);
- break;
+ vis_packet = (struct vis_packet *) skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
- default: /* ignore unknown packet */
- break;
- }
+ /* not for me */
+ if (!is_my_mac(ethhdr->h_dest))
+ return NET_RX_DROP;
- break;
- }
+ /* ignore own packets */
+ if (is_my_mac(vis_packet->vis_orig))
+ return NET_RX_DROP;
- }
+ if (is_my_mac(vis_packet->sender_orig))
+ return NET_RX_DROP;
- if ((result < 0) && (result != -EAGAIN))
- debug_log(LOG_TYPE_CRIT, "Could not receive packet from interface %s: %i\n", batman_if->dev, result);
+ switch (vis_packet->vis_type) {
+ case VIS_TYPE_SERVER_SYNC:
+ /* TODO: handle fragmented skbs properly */
+ receive_server_sync_packet(vis_packet, skb_headlen(skb));
+ break;
- /* lock for the next iteration */
- rcu_read_lock();
- }
- rcu_read_unlock();
+ case VIS_TYPE_CLIENT_UPDATE:
+ /* TODO: handle fragmented skbs properly */
+ receive_client_update_packet(vis_packet, skb_headlen(skb));
+ break;
+ default: /* ignore unknown packet */
+ break;
}
- kfree(packet_buff);
-
- /* do not exit until kthread_stop() is actually called, otherwise it will wait for us
- * forever. */
- while (!kthread_should_stop())
- schedule();
-
- return 0;
-}
-
-void batman_data_ready(struct sock *sk, int len)
-{
- void (*data_ready)(struct sock *, int) = sk->sk_user_data;
-
- data_ready(sk, len);
- atomic_set(&data_ready_cond, 1);
- wake_up_interruptible(&thread_wait);
+ /* We take a copy of the data in the packet, so we should
+ always free the skbuf. */
+ return NET_RX_DROP;
}
-
diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h
index 0123ea86deb..939b8d4f733 100644
--- a/drivers/staging/batman-adv/routing.h
+++ b/drivers/staging/batman-adv/routing.h
@@ -22,13 +22,18 @@
#include "types.h"
extern wait_queue_head_t thread_wait;
-extern atomic_t exit_cond;
-int originator_init(void);
-void free_orig_node(void *data);
-void originator_free(void);
void slide_own_bcast_window(struct batman_if *batman_if);
-void batman_data_ready(struct sock *sk, int len);
-void purge_orig(struct work_struct *work);
-int packet_recv_thread(void *data);
-void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming);
+void receive_bat_packet(struct ethhdr *ethhdr,
+ struct batman_packet *batman_packet,
+ unsigned char *hna_buff, int hna_buff_len,
+ struct batman_if *if_incoming);
+void update_routes(struct orig_node *orig_node,
+ struct neigh_node *neigh_node,
+ unsigned char *hna_buff, int hna_buff_len);
+int recv_icmp_packet(struct sk_buff *skb);
+int recv_unicast_packet(struct sk_buff *skb);
+int recv_bcast_packet(struct sk_buff *skb);
+int recv_vis_packet(struct sk_buff *skb);
+int recv_bat_packet(struct sk_buff *skb,
+ struct batman_if *batman_if);
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c
index eb617508cca..2a9fac8c240 100644
--- a/drivers/staging/batman-adv/send.c
+++ b/drivers/staging/batman-adv/send.c
@@ -21,16 +21,14 @@
#include "main.h"
#include "send.h"
-#include "log.h"
#include "routing.h"
#include "translation-table.h"
+#include "soft-interface.h"
#include "hard-interface.h"
#include "types.h"
#include "vis.h"
#include "aggregation.h"
-#include "compat.h"
-
/* apply hop penalty for a normal link */
static uint8_t hop_penalty(const uint8_t tq)
{
@@ -59,51 +57,69 @@ static unsigned long forward_send_time(void)
return send_time;
}
-/* sends a raw packet. */
-void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
- struct batman_if *batman_if, uint8_t *dst_addr)
+/* send out an already prepared packet to the given address via the
+ * specified batman interface */
+int send_skb_packet(struct sk_buff *skb,
+ struct batman_if *batman_if,
+ uint8_t *dst_addr)
{
struct ethhdr *ethhdr;
- struct sk_buff *skb;
- int retval;
- char *data;
if (batman_if->if_active != IF_ACTIVE)
- return;
+ goto send_skb_err;
+
+ if (unlikely(!batman_if->net_dev))
+ goto send_skb_err;
if (!(batman_if->net_dev->flags & IFF_UP)) {
- debug_log(LOG_TYPE_WARN,
- "Interface %s is not up - can't send packet via that interface (IF_TO_BE_DEACTIVATED was here) !\n",
- batman_if->dev);
- return;
+ printk(KERN_WARNING
+ "batman-adv:Interface %s is not up - can't send packet via that interface!\n",
+ batman_if->dev);
+ goto send_skb_err;
}
- skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
- if (!skb)
- return;
- data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
+ /* push to the ethernet header. */
+ if (my_skb_push(skb, sizeof(struct ethhdr)) < 0)
+ goto send_skb_err;
- memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
+ skb_reset_mac_header(skb);
- ethhdr = (struct ethhdr *) data;
+ ethhdr = (struct ethhdr *) skb_mac_header(skb);
memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN);
memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
- skb_reset_mac_header(skb);
skb_set_network_header(skb, ETH_HLEN);
skb->priority = TC_PRIO_CONTROL;
skb->protocol = __constant_htons(ETH_P_BATMAN);
+
skb->dev = batman_if->net_dev;
/* dev_queue_xmit() returns a negative result on error. However on
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
* (which is > 0). This will not be treated as an error. */
- retval = dev_queue_xmit(skb);
- if (retval < 0)
- debug_log(LOG_TYPE_CRIT,
- "Can't write to raw socket (IF_TO_BE_DEACTIVATED was here): %i\n",
- retval);
+
+ return dev_queue_xmit(skb);
+send_skb_err:
+ kfree_skb(skb);
+ return NET_XMIT_DROP;
+}
+
+/* sends a raw packet. */
+void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
+ struct batman_if *batman_if, uint8_t *dst_addr)
+{
+ struct sk_buff *skb;
+ char *data;
+
+ skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
+ if (!skb)
+ return;
+ data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
+ memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
+ /* pull back to the batman "network header" */
+ skb_pull(skb, sizeof(struct ethhdr));
+ send_skb_packet(skb, batman_if, dst_addr);
}
/* Send a packet to a given interface */
@@ -114,7 +130,6 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
uint8_t packet_num;
int16_t buff_pos;
struct batman_packet *batman_packet;
- char orig_str[ETH_STR_LEN];
if (batman_if->if_active != IF_ACTIVE)
return;
@@ -136,19 +151,18 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
else
batman_packet->flags &= ~DIRECTLINK;
- addr_to_string(orig_str, batman_packet->orig);
fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
"Sending own" :
"Forwarding"));
- debug_log(LOG_TYPE_BATMAN,
- "%s %spacket (originator %s, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
- fwd_str,
- (packet_num > 0 ? "aggregated " : ""),
- orig_str, ntohs(batman_packet->seqno),
- batman_packet->tq, batman_packet->ttl,
- (batman_packet->flags & DIRECTLINK ?
- "on" : "off"),
- batman_if->dev, batman_if->addr_str);
+ bat_dbg(DBG_BATMAN,
+ "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
+ fwd_str,
+ (packet_num > 0 ? "aggregated " : ""),
+ batman_packet->orig, ntohs(batman_packet->seqno),
+ batman_packet->tq, batman_packet->ttl,
+ (batman_packet->flags & DIRECTLINK ?
+ "on" : "off"),
+ batman_if->dev, batman_if->addr_str);
buff_pos += sizeof(struct batman_packet) +
(batman_packet->num_hna * ETH_ALEN);
@@ -168,32 +182,28 @@ static void send_packet(struct forw_packet *forw_packet)
struct batman_if *batman_if;
struct batman_packet *batman_packet =
(struct batman_packet *)(forw_packet->packet_buff);
- char orig_str[ETH_STR_LEN];
unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) {
- debug_log(LOG_TYPE_CRIT,
- "Error - can't forward packet: incoming iface not specified\n");
+ printk(KERN_ERR "batman-adv: Error - can't forward packet: incoming iface not specified\n");
return;
}
if (forw_packet->if_incoming->if_active != IF_ACTIVE)
return;
- addr_to_string(orig_str, batman_packet->orig);
-
/* multihomed peer assumed */
/* non-primary OGMs are only broadcasted on their interface */
if ((directlink && (batman_packet->ttl == 1)) ||
(forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
/* FIXME: what about aggregated packets ? */
- debug_log(LOG_TYPE_BATMAN,
- "%s packet (originator %s, seqno %d, TTL %d) on interface %s [%s]\n",
- (forw_packet->own ? "Sending own" : "Forwarding"),
- orig_str, ntohs(batman_packet->seqno),
- batman_packet->ttl, forw_packet->if_incoming->dev,
- forw_packet->if_incoming->addr_str);
+ bat_dbg(DBG_BATMAN,
+ "%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%s]\n",
+ (forw_packet->own ? "Sending own" : "Forwarding"),
+ batman_packet->orig, ntohs(batman_packet->seqno),
+ batman_packet->ttl, forw_packet->if_incoming->dev,
+ forw_packet->if_incoming->addr_str);
send_raw_packet(forw_packet->packet_buff,
forw_packet->packet_len,
@@ -238,6 +248,7 @@ void schedule_own_packet(struct batman_if *batman_if)
{
unsigned long send_time;
struct batman_packet *batman_packet;
+ int vis_server = atomic_read(&vis_mode);
/**
* the interface gets activated here to avoid race conditions between
@@ -262,7 +273,7 @@ void schedule_own_packet(struct batman_if *batman_if)
/* change sequence number to network order */
batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
- if (is_vis_server())
+ if (vis_server == VIS_TYPE_SERVER_SYNC)
batman_packet->flags = VIS_SERVER;
else
batman_packet->flags = 0;
@@ -286,7 +297,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
unsigned long send_time;
if (batman_packet->ttl <= 1) {
- debug_log(LOG_TYPE_BATMAN, "ttl exceeded \n");
+ bat_dbg(DBG_BATMAN, "ttl exceeded \n");
return;
}
@@ -314,9 +325,9 @@ void schedule_forward_packet(struct orig_node *orig_node,
/* apply hop penalty */
batman_packet->tq = hop_penalty(batman_packet->tq);
- debug_log(LOG_TYPE_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n",
- in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
- batman_packet->ttl);
+ bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n",
+ in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
+ batman_packet->ttl);
batman_packet->seqno = htons(batman_packet->seqno);
@@ -333,6 +344,8 @@ void schedule_forward_packet(struct orig_node *orig_node,
static void forw_packet_free(struct forw_packet *forw_packet)
{
+ if (forw_packet->skb)
+ kfree_skb(forw_packet->skb);
kfree(forw_packet->packet_buff);
kfree(forw_packet);
}
@@ -340,12 +353,13 @@ static void forw_packet_free(struct forw_packet *forw_packet)
static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
unsigned long send_time)
{
+ unsigned long flags;
INIT_HLIST_NODE(&forw_packet->list);
/* add new packet to packet list */
- spin_lock(&forw_bcast_list_lock);
+ spin_lock_irqsave(&forw_bcast_list_lock, flags);
hlist_add_head(&forw_packet->list, &forw_bcast_list);
- spin_unlock(&forw_bcast_list_lock);
+ spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
/* start timer for this packet */
INIT_DELAYED_WORK(&forw_packet->delayed_work,
@@ -354,7 +368,7 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
send_time);
}
-void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len)
+void add_bcast_packet_to_list(struct sk_buff *skb)
{
struct forw_packet *forw_packet;
@@ -362,14 +376,16 @@ void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len)
if (!forw_packet)
return;
- forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC);
- if (!forw_packet->packet_buff) {
+ skb = skb_copy(skb, GFP_ATOMIC);
+ if (!skb) {
kfree(forw_packet);
return;
}
- forw_packet->packet_len = packet_len;
- memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len);
+ skb_reset_mac_header(skb);
+
+ forw_packet->skb = skb;
+ forw_packet->packet_buff = NULL;
/* how often did we send the bcast packet ? */
forw_packet->num_packets = 0;
@@ -384,16 +400,20 @@ void send_outstanding_bcast_packet(struct work_struct *work)
container_of(work, struct delayed_work, work);
struct forw_packet *forw_packet =
container_of(delayed_work, struct forw_packet, delayed_work);
+ unsigned long flags;
+ struct sk_buff *skb1;
- spin_lock(&forw_bcast_list_lock);
+ spin_lock_irqsave(&forw_bcast_list_lock, flags);
hlist_del(&forw_packet->list);
- spin_unlock(&forw_bcast_list_lock);
+ spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
/* rebroadcast packet */
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
- send_raw_packet(forw_packet->packet_buff,
- forw_packet->packet_len,
+ /* send a copy of the saved skb */
+ skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
+ if (skb1)
+ send_skb_packet(skb1,
batman_if, broadcastAddr);
}
rcu_read_unlock();
@@ -415,10 +435,11 @@ void send_outstanding_bat_packet(struct work_struct *work)
container_of(work, struct delayed_work, work);
struct forw_packet *forw_packet =
container_of(delayed_work, struct forw_packet, delayed_work);
+ unsigned long flags;
- spin_lock(&forw_bat_list_lock);
+ spin_lock_irqsave(&forw_bat_list_lock, flags);
hlist_del(&forw_packet->list);
- spin_unlock(&forw_bat_list_lock);
+ spin_unlock_irqrestore(&forw_bat_list_lock, flags);
send_packet(forw_packet);
@@ -438,38 +459,39 @@ void purge_outstanding_packets(void)
{
struct forw_packet *forw_packet;
struct hlist_node *tmp_node, *safe_tmp_node;
+ unsigned long flags;
- debug_log(LOG_TYPE_BATMAN, "purge_outstanding_packets()\n");
+ bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
/* free bcast list */
- spin_lock(&forw_bcast_list_lock);
+ spin_lock_irqsave(&forw_bcast_list_lock, flags);
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
&forw_bcast_list, list) {
- spin_unlock(&forw_bcast_list_lock);
+ spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
/**
* send_outstanding_bcast_packet() will lock the list to
* delete the item from the list
*/
cancel_delayed_work_sync(&forw_packet->delayed_work);
- spin_lock(&forw_bcast_list_lock);
+ spin_lock_irqsave(&forw_bcast_list_lock, flags);
}
- spin_unlock(&forw_bcast_list_lock);
+ spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
/* free batman packet list */
- spin_lock(&forw_bat_list_lock);
+ spin_lock_irqsave(&forw_bat_list_lock, flags);
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
&forw_bat_list, list) {
- spin_unlock(&forw_bat_list_lock);
+ spin_unlock_irqrestore(&forw_bat_list_lock, flags);
/**
* send_outstanding_bat_packet() will lock the list to
* delete the item from the list
*/
cancel_delayed_work_sync(&forw_packet->delayed_work);
- spin_lock(&forw_bat_list_lock);
+ spin_lock_irqsave(&forw_bat_list_lock, flags);
}
- spin_unlock(&forw_bat_list_lock);
+ spin_unlock_irqrestore(&forw_bat_list_lock, flags);
}
diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h
index 59d500917a3..5fc6f3417cb 100644
--- a/drivers/staging/batman-adv/send.h
+++ b/drivers/staging/batman-adv/send.h
@@ -22,6 +22,9 @@
#include "types.h"
void send_own_packet_work(struct work_struct *work);
+int send_skb_packet(struct sk_buff *skb,
+ struct batman_if *batman_if,
+ uint8_t *dst_addr);
void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
struct batman_if *batman_if, uint8_t *dst_addr);
void schedule_own_packet(struct batman_if *batman_if);
@@ -30,7 +33,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
struct batman_packet *batman_packet,
uint8_t directlink, int hna_buff_len,
struct batman_if *if_outgoing);
-void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len);
+void add_bcast_packet_to_list(struct sk_buff *skb);
void send_outstanding_bcast_packet(struct work_struct *work);
void send_outstanding_bat_packet(struct work_struct *work);
void purge_outstanding_packets(void);
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c
index d543f50b647..0e2307f3cb9 100644
--- a/drivers/staging/batman-adv/soft-interface.c
+++ b/drivers/staging/batman-adv/soft-interface.c
@@ -24,18 +24,16 @@
#include "hard-interface.h"
#include "send.h"
#include "translation-table.h"
-#include "log.h"
#include "types.h"
#include "hash.h"
+#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
-#include "compat.h"
static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
* broadcast storms */
static int32_t skb_packets;
static int32_t skb_bad_packets;
-static int32_t lock_dropped;
unsigned char mainIfAddr[ETH_ALEN];
static unsigned char mainIfAddr_default[ETH_ALEN];
@@ -68,12 +66,12 @@ int main_if_was_up(void)
return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0);
}
-static int my_skb_push(struct sk_buff *skb, unsigned int len)
+int my_skb_push(struct sk_buff *skb, unsigned int len)
{
int result = 0;
skb_packets++;
- if (skb->data - len < skb->head) {
+ if (skb_headroom(skb) < len) {
skb_bad_packets++;
result = pskb_expand_head(skb, len, 0, GFP_ATOMIC);
@@ -122,7 +120,7 @@ void interface_setup(struct net_device *dev)
/* generate random address */
random_ether_addr(dev_addr);
- memcpy(dev->dev_addr, dev_addr, sizeof(dev->dev_addr));
+ memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
@@ -147,9 +145,18 @@ struct net_device_stats *interface_stats(struct net_device *dev)
return &priv->stats;
}
-int interface_set_mac_addr(struct net_device *dev, void *addr)
+int interface_set_mac_addr(struct net_device *dev, void *p)
{
- return -EBUSY;
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ hna_local_remove(dev->dev_addr, "mac address changed");
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ hna_local_add(dev->dev_addr);
+
+ return 0;
}
int interface_change_mtu(struct net_device *dev, int new_mtu)
@@ -170,7 +177,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
struct orig_node *orig_node;
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct bat_priv *priv = netdev_priv(dev);
+ struct batman_if *batman_if;
+ uint8_t dstaddr[6];
int data_len = skb->len;
+ unsigned long flags;
if (atomic_read(&module_state) != MODULE_ACTIVE)
goto dropped;
@@ -186,7 +196,6 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
goto dropped;
bcast_packet = (struct bcast_packet *)skb->data;
-
bcast_packet->version = COMPAT_VERSION;
/* batman packet type: broadcast */
@@ -195,27 +204,21 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
/* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh */
memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
+
/* set broadcast sequence number */
bcast_packet->seqno = htons(bcast_seqno);
bcast_seqno++;
/* broadcast packet */
- add_bcast_packet_to_list(skb->data, skb->len);
+ add_bcast_packet_to_list(skb);
+ /* a copy is stored in the bcast list, therefore removing
+ * the original skb. */
+ kfree_skb(skb);
/* unicast packet */
} else {
-
- /* simply spin_lock()ing can deadlock when the lock is already
- * hold. */
- /* TODO: defer the work in a working queue instead of
- * dropping */
- if (!spin_trylock(&orig_hash_lock)) {
- lock_dropped++;
- debug_log(LOG_TYPE_NOTICE, "%d packets dropped because lock was hold\n", lock_dropped);
- goto dropped;
- }
-
+ spin_lock_irqsave(&orig_hash_lock, flags);
/* get routing information */
orig_node = ((struct orig_node *)hash_find(orig_hash,
ethhdr->h_dest));
@@ -244,14 +247,17 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
if (orig_node->batman_if->if_active != IF_ACTIVE)
goto unlock;
- send_raw_packet(skb->data, skb->len,
- orig_node->batman_if,
- orig_node->router->addr);
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+
+ batman_if = orig_node->batman_if;
+ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ send_skb_packet(skb, batman_if, dstaddr);
} else {
goto unlock;
}
-
- spin_unlock(&orig_hash_lock);
}
priv->stats.tx_packets++;
@@ -259,42 +265,44 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
goto end;
unlock:
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
dropped:
priv->stats.tx_dropped++;
end:
- kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
-void interface_rx(struct net_device *dev, void *packet, int packet_len)
+void interface_rx(struct sk_buff *skb, int hdr_size)
{
- struct sk_buff *skb;
+ struct net_device *dev = soft_device;
struct bat_priv *priv = netdev_priv(dev);
- skb = dev_alloc_skb(packet_len);
-
- if (!skb) {
- priv->stats.rx_dropped++;
- goto out;
+ /* check if enough space is available for pulling, and pull */
+ if (!pskb_may_pull(skb, hdr_size)) {
+ kfree_skb(skb);
+ return;
}
+ skb_pull_rcsum(skb, hdr_size);
+/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
- memcpy(skb_put(skb, packet_len), packet, packet_len);
-
- /* Write metadata, and then pass to the receive level */
skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ /* should not be neccesary anymore as we use skb_pull_rcsum()
+ * TODO: please verify this and remove this TODO
+ * -- Dec 21st 2009, Simon Wunderlich */
+
+/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/
+
+ /* TODO: set skb->pkt_type to PACKET_BROADCAST, PACKET_MULTICAST,
+ * PACKET_OTHERHOST or PACKET_HOST */
priv->stats.rx_packets++;
- priv->stats.rx_bytes += packet_len;
+ priv->stats.rx_bytes += skb->len;
dev->last_rx = jiffies;
netif_rx(skb);
-
-out:
- return;
}
/* ethtool */
@@ -330,7 +338,6 @@ static u32 bat_get_msglevel(struct net_device *dev)
static void bat_set_msglevel(struct net_device *dev, u32 value)
{
- return;
}
static u32 bat_get_link(struct net_device *dev)
diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h
index 515e276ef53..c0cad8134b2 100644
--- a/drivers/staging/batman-adv/soft-interface.h
+++ b/drivers/staging/batman-adv/soft-interface.h
@@ -28,6 +28,7 @@ struct net_device_stats *interface_stats(struct net_device *dev);
int interface_set_mac_addr(struct net_device *dev, void *addr);
int interface_change_mtu(struct net_device *dev, int new_mtu);
int interface_tx(struct sk_buff *skb, struct net_device *dev);
-void interface_rx(struct net_device *dev, void *packet, int packet_len);
+void interface_rx(struct sk_buff *skb, int hdr_size);
+int my_skb_push(struct sk_buff *skb, unsigned int len);
extern unsigned char mainIfAddr[];
diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c
index c2190e177c5..d56f6654de0 100644
--- a/drivers/staging/batman-adv/translation-table.c
+++ b/drivers/staging/batman-adv/translation-table.c
@@ -21,11 +21,9 @@
#include "main.h"
#include "translation-table.h"
-#include "log.h"
#include "soft-interface.h"
#include "types.h"
#include "hash.h"
-#include "compat.h"
struct hashtable_t *hna_local_hash;
static struct hashtable_t *hna_global_hash;
@@ -62,7 +60,6 @@ void hna_local_add(uint8_t *addr)
struct hna_local_entry *hna_local_entry;
struct hna_global_entry *hna_global_entry;
struct hashtable_t *swaphash;
- char hna_str[ETH_STR_LEN];
unsigned long flags;
spin_lock_irqsave(&hna_local_hash_lock, flags);
@@ -75,19 +72,17 @@ void hna_local_add(uint8_t *addr)
return;
}
- addr_to_string(hna_str, addr);
-
/* only announce as many hosts as possible in the batman-packet and
space in batman_packet->num_hna That also should give a limit to
MAC-flooding. */
if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
(num_hna + 1 > 255)) {
- debug_log(LOG_TYPE_ROUTES, "Can't add new local hna entry (%s): number of local hna entries exceeds packet size \n", hna_str);
+ bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size \n", addr);
return;
}
- debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n",
- hna_str);
+ bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM \n",
+ addr);
hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
if (!hna_local_entry)
@@ -113,7 +108,7 @@ void hna_local_add(uint8_t *addr)
hna_local_hash->size * 2);
if (swaphash == NULL)
- debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n");
+ printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table \n");
else
hna_local_hash = swaphash;
}
@@ -135,18 +130,18 @@ void hna_local_add(uint8_t *addr)
int hna_local_fill_buffer(unsigned char *buff, int buff_len)
{
struct hna_local_entry *hna_local_entry;
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
int i = 0;
unsigned long flags;
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+ while (hash_iterate(hna_local_hash, &hashit)) {
if (buff_len < (i + 1) * ETH_ALEN)
break;
- hna_local_entry = hashit->bucket->data;
+ hna_local_entry = hashit.bucket->data;
memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);
i++;
@@ -164,18 +159,18 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len)
int hna_local_fill_buffer_text(unsigned char *buff, int buff_len)
{
struct hna_local_entry *hna_local_entry;
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
int bytes_written = 0;
unsigned long flags;
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+ while (hash_iterate(hna_local_hash, &hashit)) {
if (buff_len < bytes_written + ETH_STR_LEN + 4)
break;
- hna_local_entry = hashit->bucket->data;
+ hna_local_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4,
" * %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -202,27 +197,39 @@ static void _hna_local_del(void *data)
static void hna_local_del(struct hna_local_entry *hna_local_entry,
char *message)
{
- char hna_str[ETH_STR_LEN];
-
- addr_to_string(hna_str, hna_local_entry->addr);
- debug_log(LOG_TYPE_ROUTES, "Deleting local hna entry (%s): %s \n",
- hna_str, message);
+ bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s \n",
+ hna_local_entry->addr, message);
hash_remove(hna_local_hash, hna_local_entry->addr);
_hna_local_del(hna_local_entry);
}
+void hna_local_remove(uint8_t *addr, char *message)
+{
+ struct hna_local_entry *hna_local_entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hna_local_hash_lock, flags);
+
+ hna_local_entry = (struct hna_local_entry *)
+ hash_find(hna_local_hash, addr);
+ if (hna_local_entry)
+ hna_local_del(hna_local_entry, message);
+
+ spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+}
+
void hna_local_purge(struct work_struct *work)
{
struct hna_local_entry *hna_local_entry;
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
unsigned long flags;
unsigned long timeout;
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
- hna_local_entry = hashit->bucket->data;
+ while (hash_iterate(hna_local_hash, &hashit)) {
+ hna_local_entry = hashit.bucket->data;
timeout = hna_local_entry->last_seen +
((LOCAL_HNA_TIMEOUT / 1000) * HZ);
@@ -264,13 +271,10 @@ void hna_global_add_orig(struct orig_node *orig_node,
struct hna_global_entry *hna_global_entry;
struct hna_local_entry *hna_local_entry;
struct hashtable_t *swaphash;
- char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
int hna_buff_count = 0;
unsigned long flags;
unsigned char *hna_ptr;
- addr_to_string(orig_str, orig_node->orig);
-
while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
spin_lock_irqsave(&hna_global_hash_lock, flags);
@@ -290,8 +294,9 @@ void hna_global_add_orig(struct orig_node *orig_node,
memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
- addr_to_string(hna_str, hna_global_entry->addr);
- debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str);
+ bat_dbg(DBG_ROUTES,
+ "Creating new global hna entry: %pM (via %pM)\n",
+ hna_global_entry->addr, orig_node->orig);
spin_lock_irqsave(&hna_global_hash_lock, flags);
hash_add(hna_global_hash, hna_global_entry);
@@ -316,14 +321,16 @@ void hna_global_add_orig(struct orig_node *orig_node,
hna_buff_count++;
}
- orig_node->hna_buff_len = hna_buff_len;
+ /* initialize, and overwrite if malloc succeeds */
+ orig_node->hna_buff = NULL;
+ orig_node->hna_buff_len = 0;
- if (orig_node->hna_buff_len > 0) {
- orig_node->hna_buff = kmalloc(orig_node->hna_buff_len,
- GFP_ATOMIC);
- memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len);
- } else {
- orig_node->hna_buff = NULL;
+ if (hna_buff_len > 0) {
+ orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
+ if (orig_node->hna_buff) {
+ memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
+ orig_node->hna_buff_len = hna_buff_len;
+ }
}
spin_lock_irqsave(&hna_global_hash_lock, flags);
@@ -333,7 +340,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
hna_global_hash->size * 2);
if (swaphash == NULL)
- debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n");
+ printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table \n");
else
hna_global_hash = swaphash;
}
@@ -344,17 +351,17 @@ void hna_global_add_orig(struct orig_node *orig_node,
int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
{
struct hna_global_entry *hna_global_entry;
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
int bytes_written = 0;
unsigned long flags;
spin_lock_irqsave(&hna_global_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_global_hash, hashit))) {
+ while (hash_iterate(hna_global_hash, &hashit)) {
if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10)
break;
- hna_global_entry = hashit->bucket->data;
+ hna_global_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written,
(2 * ETH_STR_LEN) + 10,
@@ -381,12 +388,9 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
char *message)
{
- char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
-
- addr_to_string(orig_str, hna_global_entry->orig_node->orig);
- addr_to_string(hna_str, hna_global_entry->addr);
-
- debug_log(LOG_TYPE_ROUTES, "Deleting global hna entry %s (via %s): %s \n", hna_str, orig_str, message);
+ bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s \n",
+ hna_global_entry->addr, hna_global_entry->orig_node->orig,
+ message);
hash_remove(hna_global_hash, hna_global_entry->addr);
kfree(hna_global_entry);
diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h
index f7da8112931..281125b729f 100644
--- a/drivers/staging/batman-adv/translation-table.h
+++ b/drivers/staging/batman-adv/translation-table.h
@@ -23,6 +23,7 @@
int hna_local_init(void);
void hna_local_add(uint8_t *addr);
+void hna_local_remove(uint8_t *addr, char *message);
int hna_local_fill_buffer(unsigned char *buff, int buff_len);
int hna_local_fill_buffer_text(unsigned char *buff, int buff_len);
void hna_local_purge(struct work_struct *work);
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h
index 3a0ef0c38c9..dec1b54031b 100644
--- a/drivers/staging/batman-adv/types.h
+++ b/drivers/staging/batman-adv/types.h
@@ -39,7 +39,6 @@ struct batman_if {
char if_active;
char addr_str[ETH_STR_LEN];
struct net_device *net_dev;
- struct socket *raw_sock;
atomic_t seqno;
unsigned char *packet_buff;
int packet_len;
@@ -75,7 +74,7 @@ struct neigh_node {
uint8_t tq_index;
uint8_t tq_avg;
uint8_t last_ttl;
- unsigned long last_valid; /* when last packet via this neighbour was received */
+ unsigned long last_valid; /* when last packet via this neighbor was received */
TYPE_OF_WORD real_bits[NUM_WORDS];
struct orig_node *orig_node;
struct batman_if *if_incoming;
@@ -113,6 +112,7 @@ struct forw_packet { /* structure for forw_list maintaining packet
struct hlist_node list;
unsigned long send_time;
uint8_t own;
+ struct sk_buff *skb;
unsigned char *packet_buff;
uint16_t packet_len;
uint32_t direct_link_flags;
@@ -121,4 +121,14 @@ struct forw_packet { /* structure for forw_list maintaining packet
struct batman_if *if_incoming;
};
+/* While scanning for vis-entries of a particular vis-originator
+ * this list collects its interfaces to create a subgraph/cluster
+ * out of them later
+ */
+struct if_list_entry {
+ uint8_t addr[ETH_ALEN];
+ bool primary;
+ struct hlist_node list;
+};
+
#endif
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c
index f6c9acb289e..fedec1bb309 100644
--- a/drivers/staging/batman-adv/vis.c
+++ b/drivers/staging/batman-adv/vis.c
@@ -23,11 +23,9 @@
#include "send.h"
#include "translation-table.h"
#include "vis.h"
-#include "log.h"
#include "soft-interface.h"
#include "hard-interface.h"
#include "hash.h"
-#include "compat.h"
struct hashtable_t *vis_hash;
DEFINE_SPINLOCK(vis_hash_lock);
@@ -50,39 +48,6 @@ static void free_info(void *data)
kfree(info);
}
-/* set the mode of the visualization to client or server */
-void vis_set_mode(int mode)
-{
- spin_lock(&vis_hash_lock);
-
- if (my_vis_info != NULL)
- my_vis_info->packet.vis_type = mode;
-
- spin_unlock(&vis_hash_lock);
-}
-
-/* is_vis_server(), locked outside */
-static int is_vis_server_locked(void)
-{
- if (my_vis_info != NULL)
- if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC)
- return 1;
-
- return 0;
-}
-
-/* get the current set mode */
-int is_vis_server(void)
-{
- int ret = 0;
-
- spin_lock(&vis_hash_lock);
- ret = is_vis_server_locked();
- spin_unlock(&vis_hash_lock);
-
- return ret;
-}
-
/* Compare two vis packets, used by the hashing algorithm */
static int vis_info_cmp(void *data1, void *data2)
{
@@ -115,6 +80,68 @@ static int vis_info_choose(void *data, int size)
return hash % size;
}
+/* insert interface to the list of interfaces of one originator, if it
+ * does not already exist in the list */
+static void proc_vis_insert_interface(const uint8_t *interface,
+ struct hlist_head *if_list,
+ bool primary)
+{
+ struct if_list_entry *entry;
+ struct hlist_node *pos;
+
+ hlist_for_each_entry(entry, pos, if_list, list) {
+ if (compare_orig(entry->addr, (void *)interface))
+ return;
+ }
+
+ /* its a new address, add it to the list */
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return;
+ memcpy(entry->addr, interface, ETH_ALEN);
+ entry->primary = primary;
+ hlist_add_head(&entry->list, if_list);
+}
+
+void proc_vis_read_prim_sec(struct seq_file *seq,
+ struct hlist_head *if_list)
+{
+ struct if_list_entry *entry;
+ struct hlist_node *pos, *n;
+ char tmp_addr_str[ETH_STR_LEN];
+
+ hlist_for_each_entry_safe(entry, pos, n, if_list, list) {
+ if (entry->primary) {
+ seq_printf(seq, "PRIMARY, ");
+ } else {
+ addr_to_string(tmp_addr_str, entry->addr);
+ seq_printf(seq, "SEC %s, ", tmp_addr_str);
+ }
+
+ hlist_del(&entry->list);
+ kfree(entry);
+ }
+}
+
+/* read an entry */
+void proc_vis_read_entry(struct seq_file *seq,
+ struct vis_info_entry *entry,
+ struct hlist_head *if_list,
+ uint8_t *vis_orig)
+{
+ char to[40];
+
+ addr_to_string(to, entry->dest);
+ if (entry->quality == 0) {
+ proc_vis_insert_interface(vis_orig, if_list, true);
+ seq_printf(seq, "HNA %s, ", to);
+ } else {
+ proc_vis_insert_interface(entry->src, if_list,
+ compare_orig(entry->src, vis_orig));
+ seq_printf(seq, "TQ %s %d, ", to, entry->quality);
+ }
+}
+
/* tries to add one entry to the receive list. */
static void recv_list_add(struct list_head *recv_list, char *mac)
{
@@ -208,21 +235,23 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
{
struct vis_info *info;
int is_new;
+ unsigned long flags;
+ int vis_server = atomic_read(&vis_mode);
- spin_lock(&vis_hash_lock);
+ spin_lock_irqsave(&vis_hash_lock, flags);
info = add_packet(vis_packet, vis_info_len, &is_new);
if (info == NULL)
goto end;
/* only if we are server ourselves and packet is newer than the one in
* hash.*/
- if (is_vis_server_locked() && is_new) {
+ if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) {
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
if (list_empty(&info->send_list))
list_add_tail(&info->send_list, &send_list);
}
end:
- spin_unlock(&vis_hash_lock);
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
}
/* handle an incoming client update packet and schedule forward if needed. */
@@ -231,12 +260,14 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
{
struct vis_info *info;
int is_new;
+ unsigned long flags;
+ int vis_server = atomic_read(&vis_mode);
/* clients shall not broadcast. */
if (is_bcast(vis_packet->target_orig))
return;
- spin_lock(&vis_hash_lock);
+ spin_lock_irqsave(&vis_hash_lock, flags);
info = add_packet(vis_packet, vis_info_len, &is_new);
if (info == NULL)
goto end;
@@ -244,7 +275,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
/* send only if we're the target server or ... */
- if (is_vis_server_locked() &&
+ if (vis_server == VIS_TYPE_SERVER_SYNC &&
is_my_mac(info->packet.target_orig) &&
is_new) {
info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
@@ -258,7 +289,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
list_add_tail(&info->send_list, &send_list);
}
end:
- spin_unlock(&vis_hash_lock);
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
}
/* Walk the originators and find the VIS server with the best tq. Set the packet
@@ -267,12 +298,12 @@ end:
* Must be called with the originator hash locked */
static int find_best_vis_server(struct vis_info *info)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
struct orig_node *orig_node;
int best_tq = -1;
- while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
- orig_node = hashit->bucket->data;
+ while (hash_iterate(orig_hash, &hashit)) {
+ orig_node = hashit.bucket->data;
if ((orig_node != NULL) &&
(orig_node->router != NULL) &&
(orig_node->flags & VIS_SERVER) &&
@@ -298,7 +329,8 @@ static bool vis_packet_full(struct vis_info *info)
* returns 0 on success, -1 if no packet could be generated */
static int generate_vis_packet(void)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit_local);
+ HASHIT(hashit_global);
struct orig_node *orig_node;
struct vis_info *info = (struct vis_info *)my_vis_info;
struct vis_info_entry *entry, *entry_array;
@@ -307,27 +339,27 @@ static int generate_vis_packet(void)
unsigned long flags;
info->first_seen = jiffies;
+ info->packet.vis_type = atomic_read(&vis_mode);
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
info->packet.ttl = TTL;
info->packet.seqno++;
info->packet.entries = 0;
- if (!is_vis_server_locked()) {
+ if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
best_tq = find_best_vis_server(info);
if (best_tq < 0) {
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return -1;
}
}
- hashit = NULL;
entry_array = (struct vis_info_entry *)
((char *)info + sizeof(struct vis_info));
- while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
- orig_node = hashit->bucket->data;
+ while (hash_iterate(orig_hash, &hashit_global)) {
+ orig_node = hashit_global.bucket->data;
if (orig_node->router != NULL
&& compare_orig(orig_node->router->addr, orig_node->orig)
&& orig_node->batman_if
@@ -342,18 +374,17 @@ static int generate_vis_packet(void)
info->packet.entries++;
if (vis_packet_full(info)) {
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return 0;
}
}
}
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
- hashit = NULL;
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
- hna_local_entry = hashit->bucket->data;
+ while (hash_iterate(hna_local_hash, &hashit_local)) {
+ hna_local_entry = hashit_local.bucket->data;
entry = &entry_array[info->packet.entries];
memset(entry->src, 0, ETH_ALEN);
memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
@@ -371,16 +402,16 @@ static int generate_vis_packet(void)
static void purge_vis_packets(void)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
struct vis_info *info;
- while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
- info = hashit->bucket->data;
+ while (hash_iterate(vis_hash, &hashit)) {
+ info = hashit.bucket->data;
if (info == my_vis_info) /* never purge own data. */
continue;
if (time_after(jiffies,
- info->first_seen + (VIS_TIMEOUT/1000)*HZ)) {
- hash_remove_bucket(vis_hash, hashit);
+ info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
+ hash_remove_bucket(vis_hash, &hashit);
free_info(info);
}
}
@@ -388,14 +419,15 @@ static void purge_vis_packets(void)
static void broadcast_vis_packet(struct vis_info *info, int packet_length)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
struct orig_node *orig_node;
+ unsigned long flags;
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
/* send to all routers in range. */
- while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
- orig_node = hashit->bucket->data;
+ while (hash_iterate(orig_hash, &hashit)) {
+ orig_node = hashit.bucket->data;
/* if it's a vis server and reachable, send it. */
if (orig_node &&
@@ -418,14 +450,15 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
}
}
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
}
static void unicast_vis_packet(struct vis_info *info, int packet_length)
{
struct orig_node *orig_node;
+ unsigned long flags;
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
orig_node = ((struct orig_node *)
hash_find(orig_hash, info->packet.target_orig));
@@ -436,7 +469,7 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length)
orig_node->batman_if,
orig_node->router->addr);
}
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
}
/* only send one vis packet. called from send_vis_packets() */
@@ -445,8 +478,7 @@ static void send_vis_packet(struct vis_info *info)
int packet_length;
if (info->packet.ttl < 2) {
- debug_log(LOG_TYPE_NOTICE,
- "Error - can't send vis packet: ttl exceeded\n");
+ printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n");
return;
}
@@ -467,8 +499,9 @@ static void send_vis_packet(struct vis_info *info)
static void send_vis_packets(struct work_struct *work)
{
struct vis_info *info, *temp;
+ unsigned long flags;
- spin_lock(&vis_hash_lock);
+ spin_lock_irqsave(&vis_hash_lock, flags);
purge_vis_packets();
if (generate_vis_packet() == 0)
@@ -479,7 +512,7 @@ static void send_vis_packets(struct work_struct *work)
list_del_init(&info->send_list);
send_vis_packet(info);
}
- spin_unlock(&vis_hash_lock);
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
start_vis_timer();
}
static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
@@ -488,20 +521,21 @@ static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
* initialized (e.g. bat0 is initialized, interfaces have been added) */
int vis_init(void)
{
+ unsigned long flags;
if (vis_hash)
return 1;
- spin_lock(&vis_hash_lock);
+ spin_lock_irqsave(&vis_hash_lock, flags);
vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
if (!vis_hash) {
- debug_log(LOG_TYPE_CRIT, "Can't initialize vis_hash\n");
+ printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n");
goto err;
}
my_vis_info = kmalloc(1000, GFP_ATOMIC);
if (!my_vis_info) {
- debug_log(LOG_TYPE_CRIT, "Can't initialize vis packet\n");
+ printk(KERN_ERR "batman-adv:Can't initialize vis packet\n");
goto err;
}
@@ -511,7 +545,6 @@ int vis_init(void)
INIT_LIST_HEAD(&my_vis_info->send_list);
my_vis_info->packet.version = COMPAT_VERSION;
my_vis_info->packet.packet_type = BAT_VIS;
- my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE;
my_vis_info->packet.ttl = TTL;
my_vis_info->packet.seqno = 0;
my_vis_info->packet.entries = 0;
@@ -522,19 +555,19 @@ int vis_init(void)
memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
if (hash_add(vis_hash, my_vis_info) < 0) {
- debug_log(LOG_TYPE_CRIT,
- "Can't add own vis packet into hash\n");
+ printk(KERN_ERR
+ "batman-adv:Can't add own vis packet into hash\n");
free_info(my_vis_info); /* not in hash, need to remove it
* manually. */
goto err;
}
- spin_unlock(&vis_hash_lock);
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
start_vis_timer();
return 1;
err:
- spin_unlock(&vis_hash_lock);
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
vis_quit();
return 0;
}
@@ -542,23 +575,23 @@ err:
/* shutdown vis-server */
void vis_quit(void)
{
+ unsigned long flags;
if (!vis_hash)
return;
cancel_delayed_work_sync(&vis_timer_wq);
- spin_lock(&vis_hash_lock);
+ spin_lock_irqsave(&vis_hash_lock, flags);
/* properly remove, kill timers ... */
hash_delete(vis_hash, free_info);
vis_hash = NULL;
my_vis_info = NULL;
- spin_unlock(&vis_hash_lock);
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
}
/* schedule packets for (re)transmission */
static void start_vis_timer(void)
{
queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
- (atomic_read(&vis_interval)/1000) * HZ);
+ (atomic_read(&vis_interval) * HZ) / 1000);
}
-
diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h
index 276fabab4e8..0cdafde0ec3 100644
--- a/drivers/staging/batman-adv/vis.h
+++ b/drivers/staging/batman-adv/vis.h
@@ -45,16 +45,15 @@ struct recvlist_node {
uint8_t mac[ETH_ALEN];
};
-enum vis_formats {
- DOT_DRAW,
- JSON,
-};
-
extern struct hashtable_t *vis_hash;
extern spinlock_t vis_hash_lock;
-void vis_set_mode(int mode);
-int is_vis_server(void);
+void proc_vis_read_entry(struct seq_file *seq,
+ struct vis_info_entry *entry,
+ struct hlist_head *if_list,
+ uint8_t *vis_orig);
+void proc_vis_read_prim_sec(struct seq_file *seq,
+ struct hlist_head *if_list);
void receive_server_sync_packet(struct vis_packet *vis_packet,
int vis_info_len);
void receive_client_update_packet(struct vis_packet *vis_packet,
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index a9fdcda5db7..581aa5fee2e 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -26,7 +26,6 @@
#define __NO_VERSION__
#include "comedi.h"
-#include <linux/smp_lock.h>
#include <linux/uaccess.h>
#include "comedi_compat32.h"
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 8117748ad5a..aca96747e5e 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -63,7 +63,7 @@ module_param(comedi_debug, int, 0644);
int comedi_autoconfig = 1;
module_param(comedi_autoconfig, bool, 0444);
-int comedi_num_legacy_minors = 0;
+int comedi_num_legacy_minors;
module_param(comedi_num_legacy_minors, int, 0444);
static DEFINE_SPINLOCK(comedi_file_info_table_lock);
@@ -1510,7 +1510,7 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait)
}
static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
- loff_t * offset)
+ loff_t *offset)
{
struct comedi_subdevice *s;
struct comedi_async *async;
@@ -1612,7 +1612,7 @@ done:
}
static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
- loff_t * offset)
+ loff_t *offset)
{
struct comedi_subdevice *s;
struct comedi_async *async;
@@ -2004,12 +2004,10 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
if (async->cb_mask & s->async->events) {
if (comedi_get_subdevice_runflags(s) & SRF_USER) {
wake_up_interruptible(&async->wait_head);
- if (s->subdev_flags & SDF_CMD_READ) {
+ if (s->subdev_flags & SDF_CMD_READ)
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
- }
- if (s->subdev_flags & SDF_CMD_WRITE) {
+ if (s->subdev_flags & SDF_CMD_WRITE)
kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
- }
} else {
if (async->cb_func)
async->cb_func(s->async->events, async->cb_arg);
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index c2a632d31c6..44d6b62c230 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -44,7 +44,7 @@
#include <linux/cdev.h>
#include <linux/dma-mapping.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/system.h>
static int postconfig(struct comedi_device *dev);
@@ -99,11 +99,10 @@ static void cleanup_device(struct comedi_device *dev)
static void __comedi_device_detach(struct comedi_device *dev)
{
dev->attached = 0;
- if (dev->driver) {
+ if (dev->driver)
dev->driver->detach(dev);
- } else {
+ else
printk("BUG: dev->driver=NULL in comedi_device_detach()\n");
- }
cleanup_device(dev);
}
@@ -380,9 +379,8 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
if (ret < 0)
return ret;
- if (insn->insn == INSN_READ) {
+ if (insn->insn == INSN_READ)
data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1;
- }
return 1;
}
@@ -429,9 +427,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
/* if no change is required, do nothing */
- if (async->prealloc_buf && async->prealloc_bufsz == new_size) {
+ if (async->prealloc_buf && async->prealloc_bufsz == new_size)
return 0;
- }
+
/* deallocate old buffer */
if (async->prealloc_buf) {
vunmap(async->prealloc_buf);
@@ -494,9 +492,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
(void *)
get_zeroed_page(GFP_KERNEL);
}
- if (async->buf_page_list[i].virt_addr == NULL) {
+ if (async->buf_page_list[i].virt_addr == NULL)
break;
- }
+
mem_map_reserve(virt_to_page
(async->buf_page_list[i].
virt_addr));
@@ -619,9 +617,9 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async,
{
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
- if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) {
+ if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0)
nbytes = free_end - async->buf_write_alloc_count;
- }
+
async->buf_write_alloc_count += nbytes;
/* barrier insures the read of buf_read_count above occurs before
we write data to the write-alloc'ed buffer space */
@@ -635,9 +633,9 @@ unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
{
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
- if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) {
+ if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0)
nbytes = 0;
- }
+
async->buf_write_alloc_count += nbytes;
/* barrier insures the read of buf_read_count above occurs before
we write data to the write-alloc'ed buffer space */
@@ -657,9 +655,9 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
async->buf_write_count += nbytes;
async->buf_write_ptr += nbytes;
comedi_buf_munge(async, async->buf_write_count - async->munge_count);
- if (async->buf_write_ptr >= async->prealloc_bufsz) {
+ if (async->buf_write_ptr >= async->prealloc_bufsz)
async->buf_write_ptr %= async->prealloc_bufsz;
- }
+
return nbytes;
}
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index 10f488f0e5e..2d54993ffb1 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -81,6 +81,7 @@ I/O port base address can be found in the output of 'lspci -v'.
#include "../comedidev.h"
#include <linux/ioport.h>
+#include <linux/slab.h>
#define _8255_SIZE 4
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
index 0af12fd2a40..fbc26a027de 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
index f3e47e5791d..a6898e4bbb6 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
index a15c952c0fa..0e498e9eb08 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
index 0fc2285c9ef..204d7987700 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
index 138a84f572c..148ce6f67f0 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
index a445dab50ea..6360de59e0e 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
index 7e125447579..344df946219 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
index d3d78d37de5..de6f7724689 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
index 6e9e7ed4dba..97c10aaa691 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
@@ -173,11 +173,10 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
} while (dw_eeprom_busy == EEPROM_BUSY);
/* Select the upper address part */
- if (i_Counter == 0) {
+ if (i_Counter == 0)
b_ReadLowByte = pb_ReadByte[0];
- } else {
+ else
b_ReadHighByte = pb_ReadByte[0];
- }
/* Sleep */
msleep(1);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index a56535fbcd3..6625fdc8e90 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
@@ -50,7 +50,6 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/delay.h>
@@ -58,6 +57,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
#include <linux/timex.h>
#include <linux/timer.h>
#include <linux/pci.h>
+#include <linux/gfp.h>
#include "../../comedidev.h"
#include <asm/io.h>
#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
index 3ab27cf0fac..caeb6fd2d9b 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.h
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -77,8 +77,8 @@ struct addi_board {
int i_NbrAoChannel; /* num of D/A chans */
int i_AiMaxdata; /* resolution of A/D */
int i_AoMaxdata; /* resolution of D/A */
- const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */
- const struct comedi_lrange *pr_AoRangelist; /* rangelist for D/A */
+ const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */
+ const struct comedi_lrange *pr_AoRangelist; /* rangelist for D/A */
int i_NbrDiChannel; /* Number of DI channels */
int i_NbrDoChannel; /* Number of DO channels */
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
index 69b427390e5..bea329f44d8 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
index 47517a938ec..d7d768ee7c2 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
index 016721efdbf..791297266fc 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
index 723a97bab44..fe06789699f 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
@@ -54,7 +54,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
#include "hwdrv_apci1032.h"
#include <linux/delay.h>
/* Global variables */
-unsigned int ui_InterruptStatus = 0;
+unsigned int ui_InterruptStatus;
/*
+----------------------------------------------------------------------------+
@@ -108,9 +108,9 @@ int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde
ui_TmpValue =
inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
} /* if (data[1] == ADDIDATA_OR) */
- else {
+ else
outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
- } /* else if(data[1] == ADDIDATA_OR) */
+ /* else if(data[1] == ADDIDATA_OR) */
} /* if( data[0] == ADDIDATA_ENABLE) */
else {
ul_Command1 = ul_Command1 & 0xFFFF0000;
@@ -221,9 +221,9 @@ int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub
} /* switch(ui_NoOfChannels) */
} /* if(data[1]==0) */
else {
- if (data[1] == 1) {
+ if (data[1] == 1)
*data = ui_InterruptStatus;
- } /* if(data[1]==1) */
+ /* if(data[1]==1) */
} /* else if(data[1]==0) */
return insn->n;
}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
index 36b929ffecb..d5e06ad6acc 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
index 866eb8d7582..7948c41f60f 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index 3ae663bc754..4413279c880 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
index 988e3fc2b85..8bc88adfbb5 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
index d348cd5687a..89783b1eb0b 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
index ec817082d17..2d325163c16 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
index aa159dccc36..e01889c3c4f 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
index 172fba8dbfe..f93ddd4eb06 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
@@ -45,7 +45,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
*/
#include "hwdrv_apci3120.h"
-static unsigned int ui_Temp = 0;
+static unsigned int ui_Temp;
/* FUNCTION DEFINITIONS */
@@ -98,25 +98,22 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su
devpriv->b_InterruptMode = APCI3120_EOS_MODE;
- if (data[1]) {
+ if (data[1])
devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
- } else
+ else
devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
/* Copy channel list and Range List to devpriv */
devpriv->ui_AiNbrofChannels = data[3];
- for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) {
+ for (i = 0; i < devpriv->ui_AiNbrofChannels; i++)
devpriv->ui_AiChannelList[i] = data[4 + i];
- }
- } else /* EOC */
- {
+ } else { /* EOC */
devpriv->b_InterruptMode = APCI3120_EOC_MODE;
- if (data[1]) {
+ if (data[1])
devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
- } else {
+ else
devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
- }
}
return insn->n;
@@ -166,13 +163,9 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd
devpriv->us_OutputRegister = 0;
/* devpriv->b_DigitalOutputRegister=0; */
- if (insn->unused[0] == 222) /* second insn read */
- {
-
- for (i = 0; i < insn->n; i++) {
+ if (insn->unused[0] == 222) { /* second insn read */
+ for (i = 0; i < insn->n; i++)
data[i] = devpriv->ui_AiReadData[i];
- }
-
} else {
devpriv->tsk_Current = current; /* Save the current process task structure */
/*
@@ -519,9 +512,8 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
/* step 2: make sure trigger sources are unique and mutually compatible */
- if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
err++;
- }
if (cmd->scan_begin_src != TRIG_TIMER &&
cmd->scan_begin_src != TRIG_FOLLOW)
@@ -548,16 +540,14 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
err++;
}
- if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */
- {
+ if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */
if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
err++;
}
}
- if (cmd->convert_src == TRIG_TIMER) /* Test Acquisition timing */
- {
+ if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */
if (cmd->scan_begin_src == TRIG_TIMER) {
if ((cmd->convert_arg)
&& (cmd->convert_arg <
@@ -653,11 +643,10 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde
/* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
- if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_src == TRIG_COUNT)
devpriv->ui_AiNbrofScans = cmd->stop_arg;
- } else {
+ else
devpriv->ui_AiNbrofScans = 0;
- }
devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */
devpriv->ui_AiTimer1 = 0;
@@ -849,9 +838,8 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
}
/*** EL241003 End ******************************************************************************/
- if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
+ if (devpriv->b_ExttrigEnable == APCI3120_ENABLE)
i_APCI3120_ExttrigEnable(dev); /* activate EXT trigger */
- }
switch (mode) {
case 1:
/* init timer0 in mode 2 */
@@ -1049,12 +1037,10 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
dmalen1 = 4;
}
} else { /* isn't output buff smaller that our DMA buff? */
- if (dmalen0 > (devpriv->ui_AiDataLength)) {
+ if (dmalen0 > (devpriv->ui_AiDataLength))
dmalen0 = devpriv->ui_AiDataLength;
- }
- if (dmalen1 > (devpriv->ui_AiDataLength)) {
+ if (dmalen1 > (devpriv->ui_AiDataLength))
dmalen1 = devpriv->ui_AiDataLength;
- }
}
devpriv->ui_DmaBufferUsesize[0] = dmalen0;
devpriv->ui_DmaBufferUsesize[1] = dmalen1;
@@ -1356,11 +1342,10 @@ int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevi
/* store range list to card */
us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */
- if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) {
+ if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES)
us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */
- } else {
+ else
us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */
- }
gain = CR_RANGE(chanlist[i]); /* get gain number */
us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */
@@ -1514,8 +1499,7 @@ void v_APCI3120_Interrupt(int irq, void *d)
/* Check If EOS interrupt */
if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) {
- if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) /* enable this in without DMA ??? */
- {
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* enable this in without DMA ??? */
if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
ui_Check = 0;
@@ -1966,8 +1950,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
APCI3120_DISABLE_EOS_INT;
outb(devpriv->b_ModeSelectRegister,
devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
- if (data[0] == APCI3120_TIMER) /* initialize timer */
- {
+ if (data[0] == APCI3120_TIMER) { /* initialize timer */
/* devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister |
* APCI3120_ENABLE_TIMER_INT; */
@@ -2006,8 +1989,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
/* timer2 in Timer mode enabled */
devpriv->b_Timer2Mode = APCI3120_TIMER;
- } else /* Initialize Watch dog */
- {
+ } else { /* Initialize Watch dog */
/* Set the Timer 2 in mode 5(Watchdog) */
@@ -2092,8 +2074,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
return -EINVAL;
}
- if (data[0] == 2) /* write new value */
- {
+ if (data[0] == 2) { /* write new value */
if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
comedi_error(dev,
"write :timer2 not configured in TIMER MODE");
@@ -2113,13 +2094,11 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
/* Reset FC_TIMER BIT */
inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
- if (devpriv->b_Timer2Mode == APCI3120_TIMER) /* start timer */
- {
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */
/* Enable Timer */
devpriv->b_ModeSelectRegister =
devpriv->b_ModeSelectRegister & 0x0B;
- } else /* start watch dog */
- {
+ } else { /* start watch dog */
/* Enable WatchDog */
devpriv->b_ModeSelectRegister =
(devpriv->
@@ -2146,8 +2125,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
outb(devpriv->b_ModeSelectRegister,
devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
- if (devpriv->b_Timer2Mode == APCI3120_TIMER) /* start timer */
- {
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */
/* For Timer mode is Gate2 must be activated **timer started */
devpriv->us_OutputRegister =
devpriv->
@@ -2299,8 +2277,7 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice
/* combining both words */
data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16));
- } else /* Read watch dog status */
- {
+ } else { /* Read watch dog status */
us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS);
us_StatusValue =
@@ -2441,10 +2418,9 @@ int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
devpriv->b_DigitalOutputRegister = 0;
}
- if (!devpriv->b_OutputMemoryStatus) {
+ if (!devpriv->b_OutputMemoryStatus)
ui_Temp = 0;
-
- } /* if(!devpriv->b_OutputMemoryStatus ) */
+ /* if(!devpriv->b_OutputMemoryStatus ) */
return insn->n;
}
@@ -2504,23 +2480,23 @@ int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev,
/*
+----------------------------------------------------------------------------+
-| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
-|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
-| |
+| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
+|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
+----------------------------------------------------------------------------+
-| Task : Write digiatl output |
-| |
+| Task : Write digiatl output |
+| |
+----------------------------------------------------------------------------+
-| Input Parameters : struct comedi_device *dev |
-| struct comedi_subdevice *s |
-| struct comedi_insn *insn |
-| unsigned int *data |
- data[0] Value to be written
- data[1] :1 Set digital o/p ON
- data[1] 2 Set digital o/p OFF with memory ON
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+ data[0] Value to be written
+ data[1] :1 Set digital o/p ON
+ data[1] 2 Set digital o/p OFF with memory ON
+----------------------------------------------------------------------------+
-| Return Value : |
-| |
+| Return Value : |
+| |
+----------------------------------------------------------------------------+
*/
@@ -2615,8 +2591,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
ui_Channel = CR_CHAN(insn->chanspec);
/* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */
- if (ui_Range) /* if 1 then unipolar */
- {
+ if (ui_Range) { /* if 1 then unipolar */
if (data[0] != 0)
data[0] =
@@ -2627,8 +2602,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
13) | 8192);
- } else /* if 0 then bipolar */
- {
+ } else { /* if 0 then bipolar */
data[0] =
((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) |
data[0]);
@@ -2639,8 +2613,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
* out put n values at the given channel. printk("\nwaiting for
* DA_READY BIT");
*/
- do /* Waiting of DA_READY BIT */
- {
+ do { /* Waiting of DA_READY BIT */
us_TmpValue =
((unsigned short) inw(devpriv->iobase +
APCI3120_RD_STATUS)) & 0x0001;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index 98c23872e37..560c848f625 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
index 7b38d177394..4ed441a1adc 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
index 1d1e5fc2ea9..3692326d474 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
@@ -1206,7 +1206,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
if (b_Channel < 8) {
/*****************************************************************************/
- /* Read port 0 (first digital output port) and set/reset the selcted channel */
+ /* Read port 0 (first digital output port) and set/reset the selected channel */
/*****************************************************************************/
dw_Status = inl(devpriv->iobase + 80);
@@ -1228,7 +1228,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
== 0xFF) {
/*****************************************************************************/
- /* Read port 2 (first digital output port) and set/reset the selcted channel */
+ /* Read port 2 (first digital output port) and set/reset the selected channel */
/*****************************************************************************/
dw_Status = inl(devpriv->iobase + 112);
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 791ea8334e1..944f20ae5a6 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -66,6 +66,7 @@ Configuration options:
#include "../pci_ids.h"
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/interrupt.h>
#include "amcc_s5933.h"
@@ -88,9 +89,9 @@ Configuration options:
#define IORANGE_9118 64 /* I hope */
#define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */
-#define PCI9118_CNT0 0x00 /* R/W: 8254 couter 0 */
-#define PCI9118_CNT1 0x04 /* R/W: 8254 couter 0 */
-#define PCI9118_CNT2 0x08 /* R/W: 8254 couter 0 */
+#define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */
+#define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
+#define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
#define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
#define PCI9118_AD_DATA 0x10 /* R: A/D data */
#define PCI9118_DA1 0x10 /* W: D/A registers */
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
index c5ed8bb9760..f3ba645bf63 100644
--- a/drivers/staging/comedi/drivers/adq12b.c
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -42,23 +42,23 @@ If you do not specify any options, they will default to
option 1: I/O base address. The following table is provided as a help
of the hardware jumpers.
- address jumper JADR
- 0x300 1 (factory default)
- 0x320 2
- 0x340 3
- 0x360 4
- 0x380 5
- 0x3A0 6
+ address jumper JADR
+ 0x300 1 (factory default)
+ 0x320 2
+ 0x340 3
+ 0x360 4
+ 0x380 5
+ 0x3A0 6
option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar
- selection comedi_config option JUB
- bipolar 0 2-3 (factory default)
- unipolar 1 1-2
+ selection comedi_config option JUB
+ bipolar 0 2-3 (factory default)
+ unipolar 1 1-2
option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential
- selection comedi_config option JCHA JCHB
+ selection comedi_config option JCHA JCHB
single-ended 0 1-2 1-2 (factory default)
differential 1 2-3 2-3
@@ -140,7 +140,7 @@ static const struct adq12b_board adq12b_boards[] = {
.ai_bits = 12,
.di_chans = 8,
.do_chans = 5
- }*/
+ }*/
};
#define thisboard ((const struct adq12b_board *)dev->board_ptr)
@@ -164,14 +164,15 @@ struct adq12b_private {
static int adq12b_attach(struct comedi_device *dev,
struct comedi_devconfig *it);
static int adq12b_detach(struct comedi_device *dev);
+
static struct comedi_driver driver_adq12b = {
-driver_name:"adq12b",
-module:THIS_MODULE,
-attach:adq12b_attach,
-detach:adq12b_detach,
-board_name:&adq12b_boards[0].name,
-offset:sizeof(struct adq12b_board),
-num_names:ARRAY_SIZE(adq12b_boards),
+ .driver_name = "adq12b",
+ .module = THIS_MODULE,
+ .attach = adq12b_attach,
+ .detach = adq12b_detach,
+ .board_name = &adq12b_boards[0].name,
+ .offset = sizeof(struct adq12b_board),
+ .num_names = ARRAY_SIZE(adq12b_boards),
};
static int adq12b_ai_rinsn(struct comedi_device *dev,
@@ -200,15 +201,16 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unipolar = it->options[1];
differential = it->options[2];
- printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n",
- dev->minor, iobase, (unipolar == 1) ? "unipolar" : "bipolar",
+ printk(KERN_INFO "comedi%d: adq12b called with options base=0x%03lx, "
+ "%s and %s\n", dev->minor, iobase,
+ (unipolar == 1) ? "unipolar" : "bipolar",
(differential == 1) ? "differential" : "single-ended");
/* if no address was specified, try the default 0x300 */
if (iobase == 0) {
- printk
- ("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n",
- dev->minor);
+ printk(KERN_WARNING "comedi%d: adq12b warning: I/O base "
+ "address not specified. Trying the default 0x300.\n",
+ dev->minor);
iobase = 0x300;
}
@@ -259,11 +261,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->n_chan = thisboard->ai_se_chans;
}
- if (unipolar) {
+ if (unipolar)
s->range_table = &range_adq12b_ai_unipolar;
- } else {
+ else
s->range_table = &range_adq12b_ai_bipolar;
- }
s->maxdata = (1 << thisboard->ai_bits) - 1;
@@ -289,7 +290,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->range_table = &range_digital;
s->insn_bits = adq12b_do_insn_bits;
- printk("attached\n");
+ printk(KERN_INFO "attached\n");
return 0;
}
@@ -309,7 +310,7 @@ static int adq12b_detach(struct comedi_device *dev)
kfree(devpriv);
- printk("comedi%d: adq12b: removed\n", dev->minor);
+ printk(KERN_INFO "comedi%d: adq12b: removed\n", dev->minor);
return 0;
}
@@ -344,17 +345,18 @@ static int adq12b_ai_rinsn(struct comedi_device *dev,
/* wait for end of convertion */
i = 0;
do {
-/* udelay(1); */
+ /* udelay(1); */
status = inb(dev->iobase + ADQ12B_STINR);
status = status & ADQ12B_EOC;
} while (status == 0 && ++i < TIMEOUT);
-/* } while (++i < 10); */
+ /* } while (++i < 10); */
/* read data */
hi = inb(dev->iobase + ADQ12B_ADHIG);
lo = inb(dev->iobase + ADQ12B_ADLOW);
- /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status, hi, lo); */
+ /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n",
+ channel, range, status, hi, lo); */
data[n] = (hi << 8) | lo;
}
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index 951e57949f7..394d2ea19c2 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -84,9 +84,9 @@ Configuration options:
#define PCI171x_DAREF 14 /* W: D/A reference control */
#define PCI171x_DI 16 /* R: digi inputs */
#define PCI171x_DO 16 /* R: digi inputs */
-#define PCI171x_CNT0 24 /* R/W: 8254 couter 0 */
-#define PCI171x_CNT1 26 /* R/W: 8254 couter 1 */
-#define PCI171x_CNT2 28 /* R/W: 8254 couter 2 */
+#define PCI171x_CNT0 24 /* R/W: 8254 counter 0 */
+#define PCI171x_CNT1 26 /* R/W: 8254 counter 1 */
+#define PCI171x_CNT2 28 /* R/W: 8254 counter 2 */
#define PCI171x_CNTCTRL 30 /* W: 8254 counter control */
/* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */
@@ -724,6 +724,7 @@ static int move_block_from_fifo(struct comedi_device *dev,
devpriv->ai_act_scan++;
}
}
+ s->async->cur_chan = j;
DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
return 0;
}
@@ -1034,14 +1035,6 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
}
}
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->chanlist_len > this_board->n_aichan) {
- cmd->chanlist_len = this_board->n_aichan;
- err++;
- }
if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len;
err++;
@@ -1230,6 +1223,12 @@ static void setup_channel_list(struct comedi_device *dev,
DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
devpriv->act_chanlist[i]);
}
+#ifdef PCI171x_PARANOIDCHECK
+ for ( ; i < n_chan; i++) { /* store remainder of channel list */
+ devpriv->act_chanlist[i] =
+ (CR_CHAN(chanlist[i]) << 12) & 0xf000;
+ }
+#endif
devpriv->ai_et_MuxVal =
CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index 3857fd566d2..4baef9ff932 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -98,7 +98,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
int iobase;
struct comedi_subdevice *s;
- printk("comedi%d: aio_iiro_16: ", dev->minor);
+ printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor);
dev->board_name = thisboard->name;
@@ -140,7 +140,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
static int aio_iiro_16_detach(struct comedi_device *dev)
{
- printk("comedi%d: aio_iiro_16: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: aio_iiro_16: remove\n", dev->minor);
if (dev->iobase)
release_region(dev->iobase, AIO_IIRO_16_SIZE);
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index 69ab2813dd2..92bcc205dd4 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -48,8 +48,8 @@ Passing a zero for an option is the same as leaving it unspecified.
SUBDEVICES
- PC218E PC212E PC215E/PCI215
- ------------- ------------- -------------
+ PC218E PC212E PC215E/PCI215
+ ------------- ------------- -------------
Subdevices 7 6 5
0 CTR-X1 PPI-X PPI-X
1 CTR-X2 CTR-Y1 PPI-Y
@@ -59,8 +59,8 @@ SUBDEVICES
5 CTR-Z2 INTERRUPT
6 INTERRUPT
- PC214E PC272E/PCI272
- ------------- -------------
+ PC214E PC272E/PCI272
+ ------------- -------------
Subdevices 4 4
0 PPI-X PPI-X
1 PPI-Y PPI-Y
@@ -96,8 +96,8 @@ instructions are supported:
0 to 7 as follows:
0. CLK n, the counter channel's dedicated CLK input from the SK1
- connector. (N.B. for other values, the counter channel's CLKn
- pin on the SK1 connector is an output!)
+ connector. (N.B. for other values, the counter channel's CLKn
+ pin on the SK1 connector is an output!)
1. Internal 10 MHz clock.
2. Internal 1 MHz clock.
3. Internal 100 kHz clock.
@@ -105,8 +105,8 @@ instructions are supported:
5. Internal 1 kHz clock.
6. OUT n-1, the output of counter channel n-1 (see note 1 below).
7. Ext Clock, the counter chip's dedicated Ext Clock input from
- the SK1 connector. This pin is shared by all three counter
- channels on the chip.
+ the SK1 connector. This pin is shared by all three counter
+ channels on the chip.
INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
clock source in data[1]. For internal clock sources, data[2] is set
@@ -120,10 +120,10 @@ instructions are supported:
0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
1. GND (internal 0V d.c.), i.e. gate permanently disabled.
2. GAT n, the counter channel's dedicated GAT input from the SK1
- connector. (N.B. for other values, the counter channel's GATn
- pin on the SK1 connector is an output!)
+ connector. (N.B. for other values, the counter channel's GATn
+ pin on the SK1 connector is an output!)
3. /OUT n-2, the inverted output of counter channel n-2 (see note
- 2 below).
+ 2 below).
4. Reserved.
5. Reserved.
6. Reserved.
@@ -153,8 +153,8 @@ below.
INTERRUPT SOURCES
- PC218E PC212E PC215E/PCI215
- ------------- ------------- -------------
+ PC218E PC212E PC215E/PCI215
+ ------------- ------------- -------------
Sources 6 6 6
0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
1 CTR-X2-OUT PPI-X-C3 PPI-X-C3
@@ -163,8 +163,8 @@ INTERRUPT SOURCES
4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
- PC214E PC272E/PCI272
- ------------- -------------
+ PC214E PC272E/PCI272
+ ------------- -------------
Sources 1 6
0 JUMPER-J5 PPI-X-C0
1 PPI-X-C3
@@ -206,6 +206,7 @@ order they appear in the channel list.
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
@@ -435,11 +436,13 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_table);
* Useful for shorthand access to the particular board structure
*/
#define thisboard ((const struct dio200_board *)dev->board_ptr)
-#define thislayout (&dio200_layouts[((struct dio200_board *)dev->board_ptr)->layout])
+#define thislayout (&dio200_layouts[((struct dio200_board *) \
+ dev->board_ptr)->layout])
/* this structure is for data unique to this hardware driver. If
several hardware drivers keep similar information in this structure,
- feel free to suggest moving the variable to the struct comedi_device struct. */
+ feel free to suggest moving the variable to the struct comedi_device struct.
+ */
struct dio200_private {
#ifdef CONFIG_COMEDI_PCI
struct pci_dev *pci_dev; /* PCI device */
@@ -603,9 +606,8 @@ static void dio200_stop_intr(struct comedi_device *dev,
subpriv->active = 0;
subpriv->enabled_isns = 0;
- if (subpriv->has_int_sce) {
+ if (subpriv->has_int_sce)
outb(0, subpriv->iobase);
- }
}
/*
@@ -629,16 +631,14 @@ static int dio200_start_intr(struct comedi_device *dev,
/* Determine interrupt sources to enable. */
isn_bits = 0;
if (cmd->chanlist) {
- for (n = 0; n < cmd->chanlist_len; n++) {
+ for (n = 0; n < cmd->chanlist_len; n++)
isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
- }
}
isn_bits &= subpriv->valid_isns;
/* Enable interrupt sources. */
subpriv->enabled_isns = isn_bits;
- if (subpriv->has_int_sce) {
+ if (subpriv->has_int_sce)
outb(isn_bits, subpriv->iobase);
- }
}
return retval;
@@ -662,14 +662,13 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
spin_lock_irqsave(&subpriv->spinlock, flags);
s->async->inttrig = 0;
- if (subpriv->active) {
+ if (subpriv->active)
event = dio200_start_intr(dev, s);
- }
+
spin_unlock_irqrestore(&subpriv->spinlock, flags);
- if (event) {
+ if (event)
comedi_event(dev, s);
- }
return 1;
}
@@ -726,9 +725,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
* Reenable them NOW to minimize the time they are disabled.
*/
cur_enabled = subpriv->enabled_isns;
- if (subpriv->has_int_sce) {
+ if (subpriv->has_int_sce)
outb(cur_enabled, subpriv->iobase);
- }
if (subpriv->active) {
/*
@@ -747,9 +745,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
len = s->async->cmd.chanlist_len;
for (n = 0; n < len; n++) {
ch = CR_CHAN(s->async->cmd.chanlist[n]);
- if (triggered & (1U << ch)) {
+ if (triggered & (1U << ch))
val |= (1U << n);
- }
}
/* Write the scan to the buffer. */
if (comedi_buf_put(s->async, val)) {
@@ -781,9 +778,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
}
spin_unlock_irqrestore(&subpriv->spinlock, flags);
- if (oldevents != s->async->events) {
+ if (oldevents != s->async->events)
comedi_event(dev, s);
- }
return (triggered != 0);
}
@@ -798,9 +794,9 @@ static int dio200_subdev_intr_cancel(struct comedi_device *dev,
unsigned long flags;
spin_lock_irqsave(&subpriv->spinlock, flags);
- if (subpriv->active) {
+ if (subpriv->active)
dio200_stop_intr(dev, s);
- }
+
spin_unlock_irqrestore(&subpriv->spinlock, flags);
return 0;
@@ -846,7 +842,8 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev,
if (err)
return 1;
- /* step 2: make sure trigger sources are unique and mutually compatible */
+ /* step 2: make sure trigger sources are unique and mutually
+ compatible */
/* these tests are true if more than one _src bit is set */
if ((cmd->start_src & (cmd->start_src - 1)) != 0)
@@ -952,9 +949,8 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev,
}
spin_unlock_irqrestore(&subpriv->spinlock, flags);
- if (event) {
+ if (event)
comedi_event(dev, s);
- }
return 0;
}
@@ -980,9 +976,8 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
subpriv->valid_isns = valid_isns;
spin_lock_init(&subpriv->spinlock);
- if (has_int_sce) {
+ if (has_int_sce)
outb(0, subpriv->iobase); /* Disable interrupt sources. */
- }
s->private = subpriv;
s->type = COMEDI_SUBD_DI;
@@ -1013,10 +1008,7 @@ dio200_subdev_intr_cleanup(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct dio200_subdev_intr *subpriv = s->private;
-
- if (subpriv) {
- kfree(subpriv);
- }
+ kfree(subpriv);
}
/*
@@ -1027,9 +1019,8 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
struct comedi_device *dev = d;
int handled;
- if (!dev->attached) {
+ if (!dev->attached)
return IRQ_NONE;
- }
if (devpriv->intr_sd >= 0) {
handled = dio200_handle_read_intr(dev,
@@ -1266,10 +1257,7 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct dio200_subdev_intr *subpriv = s->private;
-
- if (subpriv) {
- kfree(subpriv);
- }
+ kfree(subpriv);
}
/*
@@ -1348,9 +1336,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
#endif
{
ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
- if (ret < 0) {
+ if (ret < 0)
return ret;
- }
}
dev->iobase = iobase;
@@ -1371,17 +1358,17 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
ret = dio200_subdev_8254_init(dev, s, iobase,
layout->sdinfo[n],
layout->has_clk_gat_sce);
- if (ret < 0) {
+ if (ret < 0)
return ret;
- }
+
break;
case sd_8255:
/* digital i/o subdevice (8255) */
ret = subdev_8255_init(dev, s, 0,
iobase + layout->sdinfo[n]);
- if (ret < 0) {
+ if (ret < 0)
return ret;
- }
+
break;
case sd_intr:
/* 'INTERRUPT' subdevice */
@@ -1392,9 +1379,9 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
layout->sdinfo[n],
layout->
has_int_sce);
- if (ret < 0) {
+ if (ret < 0)
return ret;
- }
+
devpriv->intr_sd = n;
} else {
s->type = COMEDI_SUBD_UNUSED;
@@ -1407,9 +1394,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
sdx = devpriv->intr_sd;
- if (sdx >= 0 && sdx < dev->n_subdevices) {
+ if (sdx >= 0 && sdx < dev->n_subdevices)
dev->read_subdev = &dev->subdevices[sdx];
- }
dev->board_name = thisboard->name;
@@ -1434,11 +1420,10 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
printk("(pci %s) ", pci_name(pci_dev));
#endif
}
- if (irq) {
+ if (irq)
printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
- } else {
+ else
printk("(no irq) ");
- }
printk("attached\n");
@@ -1461,9 +1446,8 @@ static int dio200_detach(struct comedi_device *dev)
printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
DIO200_DRIVER_NAME);
- if (dev->irq) {
+ if (dev->irq)
free_irq(dev->irq, dev);
- }
if (dev->subdevices) {
layout = thislayout;
for (n = 0; n < dev->n_subdevices; n++) {
@@ -1486,22 +1470,19 @@ static int dio200_detach(struct comedi_device *dev)
if (devpriv) {
#ifdef CONFIG_COMEDI_PCI
if (devpriv->pci_dev) {
- if (dev->iobase) {
+ if (dev->iobase)
comedi_pci_disable(devpriv->pci_dev);
- }
pci_dev_put(devpriv->pci_dev);
} else
#endif
{
- if (dev->iobase) {
+ if (dev->iobase)
release_region(dev->iobase, DIO200_IO_SIZE);
- }
}
}
- if (dev->board_name) {
+ if (dev->board_name)
printk(KERN_INFO "comedi%d: %s removed\n",
dev->minor, dev->board_name);
- }
return 0;
}
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
index 1032a8110d6..a307d68d79c 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -78,18 +78,18 @@ unused.
*/
/* Disable interrupt, also clear any interrupt there */
#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \
- | PLX9052_INTCSR_LI1POL_HIGH \
- | PLX9052_INTCSR_LI2POL_HIGH \
- | PLX9052_INTCSR_PCIENAB_DISABLED \
- | PLX9052_INTCSR_LI1SEL_EDGE \
- | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
+ | PLX9052_INTCSR_LI1POL_HIGH \
+ | PLX9052_INTCSR_LI2POL_HIGH \
+ | PLX9052_INTCSR_PCIENAB_DISABLED \
+ | PLX9052_INTCSR_LI1SEL_EDGE \
+ | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
/* Enable interrupt, also clear any interrupt there. */
#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \
- | PLX9052_INTCSR_LI1POL_HIGH \
- | PLX9052_INTCSR_LI2POL_HIGH \
- | PLX9052_INTCSR_PCIENAB_ENABLED \
- | PLX9052_INTCSR_LI1SEL_EDGE \
- | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
+ | PLX9052_INTCSR_LI1POL_HIGH \
+ | PLX9052_INTCSR_LI2POL_HIGH \
+ | PLX9052_INTCSR_PCIENAB_ENABLED \
+ | PLX9052_INTCSR_LI1SEL_EDGE \
+ | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
/*
* Board descriptions for Amplicon PC36AT and PCI236.
@@ -150,12 +150,13 @@ MODULE_DEVICE_TABLE(pci, pc236_pci_table);
/* this structure is for data unique to this hardware driver. If
several hardware drivers keep similar information in this structure,
- feel free to suggest moving the variable to the struct comedi_device struct. */
+ feel free to suggest moving the variable to the struct comedi_device struct.
+ */
struct pc236_private {
#ifdef CONFIG_COMEDI_PCI
/* PCI device */
struct pci_dev *pci_dev;
- unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
+ unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
#endif
int enable_irq;
};
@@ -345,9 +346,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
#endif
{
ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
- if (ret < 0) {
+ if (ret < 0)
return ret;
- }
}
dev->iobase = iobase;
@@ -399,11 +399,10 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
printk("(pci %s) ", pci_name(pci_dev));
#endif
}
- if (irq) {
+ if (irq)
printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
- } else {
+ else
printk("(no irq) ");
- }
printk("attached\n");
@@ -422,27 +421,24 @@ static int pc236_detach(struct comedi_device *dev)
{
printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
PC236_DRIVER_NAME);
- if (devpriv) {
+ if (devpriv)
pc236_intr_disable(dev);
- }
+
if (dev->irq)
free_irq(dev->irq, dev);
- if (dev->subdevices) {
+ if (dev->subdevices)
subdev_8255_cleanup(dev, dev->subdevices + 0);
- }
if (devpriv) {
#ifdef CONFIG_COMEDI_PCI
if (devpriv->pci_dev) {
- if (dev->iobase) {
+ if (dev->iobase)
comedi_pci_disable(devpriv->pci_dev);
- }
pci_dev_put(devpriv->pci_dev);
} else
#endif
{
- if (dev->iobase) {
+ if (dev->iobase)
release_region(dev->iobase, PC236_IO_SIZE);
- }
}
}
if (dev->board_name) {
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index d9836879355..c54cca8b256 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -104,6 +104,7 @@ Caveats:
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
@@ -1536,20 +1537,12 @@ static int pci224_detach(struct comedi_device *dev)
s = dev->subdevices + 0;
/* AO subdevice */
- if (s->range_table_list) {
- kfree(s->range_table_list);
- }
+ kfree(s->range_table_list);
}
if (devpriv) {
- if (devpriv->ao_readback) {
- kfree(devpriv->ao_readback);
- }
- if (devpriv->ao_scan_vals) {
- kfree(devpriv->ao_scan_vals);
- }
- if (devpriv->ao_scan_order) {
- kfree(devpriv->ao_scan_order);
- }
+ kfree(devpriv->ao_readback);
+ kfree(devpriv->ao_scan_vals);
+ kfree(devpriv->ao_scan_order);
if (devpriv->pci_dev) {
if (dev->iobase) {
comedi_pci_disable(devpriv->pci_dev);
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
index abb0532182b..fb0d5fa7176 100644
--- a/drivers/staging/comedi/drivers/c6xdigio.c
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -45,7 +45,7 @@ http://robot0.ge.uiuc.edu/~spong/mecha/
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/timer.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/pnp.h>
#include "../comedidev.h"
@@ -220,11 +220,11 @@ static int C6X_encInput(unsigned long baseAddr, unsigned channel)
/* printk("Inside C6X_encInput\n"); */
enc.value = 0;
- if (channel == 0) {
+ if (channel == 0)
ppcmd = 0x48;
- } else {
+ else
ppcmd = 0x50;
- }
+
WriteByteToHwPort(baseAddr, ppcmd);
tmp = ReadByteFromHwPort(baseAddr + 1);
while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
@@ -391,9 +391,8 @@ static int c6xdigio_ei_insn_read(struct comedi_device *dev,
int n;
int chan = CR_CHAN(insn->chanspec);
- for (n = 0; n < insn->n; n++) {
+ for (n = 0; n < insn->n; n++)
data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff);
- }
return n;
}
@@ -420,9 +419,9 @@ static void board_init(struct comedi_device *dev)
static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
/* Standard LPT Printer Port */
- {.id = "PNP0400",.driver_data = 0},
+ {.id = "PNP0400", .driver_data = 0},
/* ECP Printer Port */
- {.id = "PNP0401",.driver_data = 0},
+ {.id = "PNP0401", .driver_data = 0},
{}
};
@@ -452,15 +451,14 @@ static int c6xdigio_attach(struct comedi_device *dev,
if (result < 0)
return result;
- /* Make sure that PnP ports gets activated */
+ /* Make sure that PnP ports get activated */
pnp_register_driver(&c6xdigio_pnp_driver);
irq = it->options[1];
- if (irq > 0) {
+ if (irq > 0)
printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
- } else if (irq == 0) {
+ else if (irq == 0)
printk("comedi%d: no irq\n", dev->minor);
- }
s = dev->subdevices + 0;
/* pwm output subdevice */
@@ -483,19 +481,19 @@ static int c6xdigio_attach(struct comedi_device *dev,
s->maxdata = 0xffffff;
s->range_table = &range_unknown;
- /* s = dev->subdevices + 2; */
+ /* s = dev->subdevices + 2; */
/* pwm output subdevice */
- /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */
- /* s->subdev_flags = SDF_WRITEABLE; */
- /* s->n_chan = 1; */
- /* s->trig[0] = c6xdigio_ei_init; */
- /* s->insn_read = c6xdigio_ei_init_insn_read; */
- /* s->insn_write = c6xdigio_ei_init_insn_write; */
- /* s->maxdata = 0xFFFF; // Really just a don't care */
- /* s->range_table = &range_unknown; // Not sure what to put here */
-
- /* I will call this init anyway but more than likely the DSP board will not be connect */
- /* when device driver is loaded. */
+ /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */
+ /* s->subdev_flags = SDF_WRITEABLE; */
+ /* s->n_chan = 1; */
+ /* s->trig[0] = c6xdigio_ei_init; */
+ /* s->insn_read = c6xdigio_ei_init_insn_read; */
+ /* s->insn_write = c6xdigio_ei_init_insn_write; */
+ /* s->maxdata = 0xFFFF; // Really just a don't care */
+ /* s->range_table = &range_unknown; // Not sure what to put here */
+
+ /* I will call this init anyway but more than likely the DSP board */
+ /* will not be connected when device driver is loaded. */
board_init(dev);
return 0;
@@ -503,16 +501,17 @@ static int c6xdigio_attach(struct comedi_device *dev,
static int c6xdigio_detach(struct comedi_device *dev)
{
-/* board_halt(dev); may not need this */
+ /* board_halt(dev); may not need this */
printk("comedi%d: c6xdigio: remove\n", dev->minor);
- if (dev->iobase) {
+ if (dev->iobase)
release_region(dev->iobase, C6XDIGIO_SIZE);
- }
- if (dev->irq) {
+
+ /* Not using IRQ so I am not sure if I need this */
+ if (dev->irq)
free_irq(dev->irq, dev);
- } /* Not using IRQ so I am not sure if I need this */
+
pnp_unregister_driver(&c6xdigio_pnp_driver);
return 0;
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index bc375e73abc..5632991760a 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -32,6 +32,7 @@ Status: experimental
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include <linux/delay.h>
#include <linux/pci.h>
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index f3e66c440a3..434591de37c 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -518,7 +518,7 @@ static int trimpot_7376_write(struct comedi_device *dev, uint8_t value);
static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
uint8_t value);
static int nvram_read(struct comedi_device *dev, unsigned int address,
- uint8_t * data);
+ uint8_t *data);
static inline unsigned int cal_enable_bits(struct comedi_device *dev)
{
@@ -760,9 +760,8 @@ static int cb_pcidas_detach(struct comedi_device *dev)
if (dev->subdevices)
subdev_8255_cleanup(dev, dev->subdevices + 2);
if (devpriv && devpriv->pci_dev) {
- if (devpriv->s5933_config) {
+ if (devpriv->s5933_config)
comedi_pci_disable(devpriv->pci_dev);
- }
pci_dev_put(devpriv->pci_dev);
}
@@ -1248,9 +1247,8 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev,
cmd->flags & TRIG_ROUND_MASK);
/* set number of conversions */
- if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_src == TRIG_COUNT)
devpriv->count = cmd->chanlist_len * cmd->stop_arg;
- }
/* enable interrupts */
spin_lock_irqsave(&dev->spinlock, flags);
devpriv->adc_fifo_bits |= INTE;
@@ -1449,9 +1447,8 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
devpriv->ao_divisor2, 2);
}
/* set number of conversions */
- if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_src == TRIG_COUNT)
devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
- }
/* set pacer source */
spin_lock_irqsave(&dev->spinlock, flags);
switch (cmd->scan_begin_src) {
@@ -1494,9 +1491,8 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
num_points * sizeof(short));
num_points = num_bytes / sizeof(short);
- if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_src == TRIG_COUNT)
devpriv->ao_count -= num_points;
- }
/* write data to board's fifo */
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
@@ -1534,9 +1530,8 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
static const int timeout = 10000;
unsigned long flags;
- if (dev->attached == 0) {
+ if (dev->attached == 0)
return IRQ_NONE;
- }
async = s->async;
async->events = 0;
@@ -1558,15 +1553,13 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
status = inw(devpriv->control_status + INT_ADCFIFO);
#ifdef CB_PCIDAS_DEBUG
- if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) {
+ if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0)
comedi_error(dev, "spurious interrupt");
- }
#endif
/* check for analog output interrupt */
- if (status & (DAHFI | DAEMI)) {
+ if (status & (DAHFI | DAEMI))
handle_ao_interrupt(dev, status);
- }
/* check for analog input interrupts */
/* if fifo half-full */
if (status & ADHFI) {
@@ -1675,9 +1668,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
num_points * sizeof(short));
num_points = num_bytes / sizeof(short);
- if (async->cmd.stop_src == TRIG_COUNT) {
+ if (async->cmd.stop_src == TRIG_COUNT)
devpriv->ao_count -= num_points;
- }
/* write data to board's fifo */
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
num_points);
@@ -1852,7 +1844,7 @@ static int wait_for_nvram_ready(unsigned long s5933_base_addr)
}
static int nvram_read(struct comedi_device *dev, unsigned int address,
- uint8_t * data)
+ uint8_t *data)
{
unsigned long iobase = devpriv->s5933_config;
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 782357732ee..81829d6fd28 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -410,9 +410,8 @@ static int cb_pcidda_detach(struct comedi_device *dev)
*/
if (devpriv) {
if (devpriv->pci_dev) {
- if (devpriv->dac) {
+ if (devpriv->dac)
comedi_pci_disable(devpriv->pci_dev);
- }
pci_dev_put(devpriv->pci_dev);
}
}
@@ -677,9 +676,8 @@ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
for (i = 1; i <= value_width; i++) {
/* read bits most significant bit first */
- if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) {
+ if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
value |= 1 << (value_width - i);
- }
}
return value;
@@ -716,9 +714,8 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
/* send serial output stream to eeprom */
cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
/* deactivate caldacs (one caldac for every two channels) */
- for (i = 0; i < max_num_caldacs; i++) {
+ for (i = 0; i < max_num_caldacs; i++)
cal2_bits |= DESELECT_CALDAC_BIT(i);
- }
outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
/* tell eeprom we want to read */
@@ -756,9 +753,8 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev,
*/
cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
/* deactivate caldacs (one caldac for every two channels) */
- for (i = 0; i < max_num_caldacs; i++) {
+ for (i = 0; i < max_num_caldacs; i++)
cal2_bits |= DESELECT_CALDAC_BIT(i);
- }
/* activate the caldac we want */
cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
index 7daad0a17fb..38ccd105fa3 100644
--- a/drivers/staging/comedi/drivers/cb_pcidio.c
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -283,17 +283,15 @@ static int pcidio_detach(struct comedi_device *dev)
printk("comedi%d: cb_pcidio: remove\n", dev->minor);
if (devpriv) {
if (devpriv->pci_dev) {
- if (devpriv->dio_reg_base) {
+ if (devpriv->dio_reg_base)
comedi_pci_disable(devpriv->pci_dev);
- }
pci_dev_put(devpriv->pci_dev);
}
}
if (dev->subdevices) {
int i;
- for (i = 0; i < thisboard->n_8255; i++) {
+ for (i = 0; i < thisboard->n_8255; i++)
subdev_8255_cleanup(dev, dev->subdevices + i);
- }
}
return 0;
}
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index cbbca05acb9..2e61727fc9a 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -330,11 +330,10 @@ found:
s = dev->subdevices + 2;
/* digital i/o subdevice */
- if (thisboard->has_dio) {
+ if (thisboard->has_dio)
subdev_8255_init(dev, s, NULL, devpriv->BADR4);
- } else {
+ else
s->type = COMEDI_SUBD_UNUSED;
- }
printk("attached\n");
@@ -365,9 +364,8 @@ static int cb_pcimdas_detach(struct comedi_device *dev)
free_irq(dev->irq, dev);
if (devpriv) {
if (devpriv->pci_dev) {
- if (devpriv->BADR0) {
+ if (devpriv->BADR0)
comedi_pci_disable(devpriv->pci_dev);
- }
pci_dev_put(devpriv->pci_dev);
}
}
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
index 980fa0aacf9..e32a31763d5 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdda.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -284,11 +284,10 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->n_chan = thisboard->ao_chans;
s->maxdata = figure_out_maxdata(thisboard->ao_bits);
/* this is hard-coded here */
- if (it->options[2]) {
+ if (it->options[2])
s->range_table = &range_bipolar10;
- } else {
+ else
s->range_table = &range_bipolar5;
- }
s->insn_write = &ao_winsn;
s->insn_read = &ao_rinsn;
@@ -337,9 +336,8 @@ static int detach(struct comedi_device *dev)
}
if (devpriv->pci_dev) {
- if (devpriv->registers) {
+ if (devpriv->registers)
comedi_pci_disable(devpriv->pci_dev);
- }
pci_dev_put(devpriv->pci_dev);
}
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index cf39a24ddd4..41311d99473 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -90,6 +90,7 @@ Configuration Options:
#include "../comedilib.h"
#include "../comedidev.h"
#include <linux/string.h>
+#include <linux/slab.h>
/* The maxiumum number of channels per subdevice. */
#define MAX_CHANS 256
@@ -417,7 +418,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
int sdev = -1, nchans, tmp;
struct BondedDevice *bdev = NULL;
- if (minor < 0 || minor > COMEDI_NUM_BOARD_MINORS) {
+ if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) {
ERROR("Minor %d is invalid!\n", minor);
return 0;
}
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
index b16d652f776..9511814e641 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -173,9 +173,8 @@ static int contec_detach(struct comedi_device *dev)
printk("comedi%d: contec: remove\n", dev->minor);
if (devpriv && devpriv->pci_dev) {
- if (dev->iobase) {
+ if (dev->iobase)
comedi_pci_disable(devpriv->pci_dev);
- }
pci_dev_put(devpriv->pci_dev);
}
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index 9b945e5fdd3..9164ce158dc 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -34,7 +34,7 @@ This is the PCMCIA-specific support split off from the
das08 driver.
Options (for pcm-das08):
- NONE
+ NONE
Command support does not exist, but could be added for this board.
*/
@@ -43,6 +43,7 @@ Command support does not exist, but could be added for this board.
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "das08.h"
@@ -52,7 +53,7 @@ Command support does not exist, but could be added for this board.
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
-static struct pcmcia_device *cur_dev = NULL;
+static struct pcmcia_device *cur_dev;
#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index 10a87e6a809..f2aadda9b24 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -79,6 +79,7 @@ Computer boards manuals also available from their website www.measurementcomputi
*/
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <asm/dma.h>
#include "../comedidev.h"
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index 6ea59cc6b2b..3c3e0455c7c 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -101,6 +101,7 @@ TODO:
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include <linux/ioport.h>
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
index 92487f58fd8..a404a183191 100644
--- a/drivers/staging/comedi/drivers/das6402.c
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -45,7 +45,7 @@ This driver has suffered bitrot.
#define DAS6402_SIZE 16
-#define N_WORDS 3000*64
+#define N_WORDS (3000*64)
#define STOP 0
#define START 1
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index ecb97cdbce2..aadc4971c90 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -399,9 +399,8 @@ static irqreturn_t das800_interrupt(int irq, void *d)
} else {
fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */
}
- if (fifo_empty) {
+ if (fifo_empty)
break;
- }
/* strip off extraneous bits for 12 bit cards */
if (thisboard->resolution == 12)
dataPoint = (dataPoint >> 4) & 0xfff;
@@ -457,9 +456,8 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int board;
printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
- if (irq) {
+ if (irq)
printk(", irq %u", irq);
- }
printk("\n");
/* allocate and initialize dev->private */
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 9db9a467c8f..d5cbd515c37 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -1048,11 +1048,10 @@ static int dmm32at_dio_insn_config(struct comedi_device *dev,
* value COMEDI_INPUT or COMEDI_OUTPUT. */
/* if output clear the bit, otherwise set it */
- if (data[0] == COMEDI_OUTPUT) {
+ if (data[0] == COMEDI_OUTPUT)
devpriv->dio_config &= ~chanbit;
- } else {
+ else
devpriv->dio_config |= chanbit;
- }
/* get access to the DIO regs */
dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
/* set the DIO's to the new configuration setting */
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
index 7b9af5d755e..3f365aee482 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -18,10 +18,10 @@ Configuration options:
[1] - unused
[2] - A/D reference 0=differential, 1=single-ended
[3] - A/D range
- 0 = [-10,10]
+ 0 = [-10, 10]
1 = [0,10]
[4] - D/A 0 range
- 0 = [-10,10]
+ 0 = [-10, 10]
1 = [-5,5]
2 = [-2.5,2.5]
3 = [0,10]
@@ -279,9 +279,8 @@ static int dt2801_readdata(struct comedi_device *dev, int *data)
do {
stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) {
+ if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY))
return stat;
- }
if (stat & DT_S_DATA_OUT_READY) {
*data = inb_p(dev->iobase + DT2801_DATA);
return 0;
@@ -315,9 +314,8 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data)
do {
stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & DT_S_COMPOSITE_ERROR) {
+ if (stat & DT_S_COMPOSITE_ERROR)
return stat;
- }
if (!(stat & DT_S_DATA_IN_FULL)) {
outb_p(data & 0xff, dev->iobase + DT2801_DATA);
return 0;
@@ -354,18 +352,15 @@ static int dt2801_wait_for_ready(struct comedi_device *dev)
int stat;
stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & DT_S_READY) {
+ if (stat & DT_S_READY)
return 0;
- }
do {
stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & DT_S_COMPOSITE_ERROR) {
+ if (stat & DT_S_COMPOSITE_ERROR)
return stat;
- }
- if (stat & DT_S_READY) {
+ if (stat & DT_S_READY)
return 0;
- }
} while (--timeout > 0);
return -ETIME;
@@ -382,9 +377,8 @@ static int dt2801_writecmd(struct comedi_device *dev, int command)
printk
("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
}
- if (!(stat & DT_S_READY)) {
+ if (!(stat & DT_S_READY))
printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
- }
outb_p(command, dev->iobase + DT2801_CMD);
return 0;
@@ -418,9 +412,8 @@ static int dt2801_reset(struct comedi_device *dev)
if (stat & DT_S_READY)
break;
} while (timeout--);
- if (!timeout) {
+ if (!timeout)
printk("dt2801: timeout 1 status=0x%02x\n", stat);
- }
/* printk("dt2801: reading dummy\n"); */
/* dt2801_readdata(dev,&board_code); */
@@ -436,9 +429,8 @@ static int dt2801_reset(struct comedi_device *dev)
if (stat & DT_S_READY)
break;
} while (timeout--);
- if (!timeout) {
+ if (!timeout)
printk("dt2801: timeout 2 status=0x%02x\n", stat);
- }
DPRINTK("dt2801: reading code\n");
dt2801_readdata(dev, &board_code);
@@ -623,11 +615,10 @@ static int dt2801_detach(struct comedi_device *dev)
static int dt2801_error(struct comedi_device *dev, int stat)
{
if (stat < 0) {
- if (stat == -ETIME) {
+ if (stat == -ETIME)
printk("dt2801: timeout\n");
- } else {
+ else
printk("dt2801: error %d\n", stat);
- }
return stat;
}
printk("dt2801: error status 0x%02x, resetting...\n", stat);
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
index d1db93c043a..d1a4f782243 100644
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -34,19 +34,19 @@ Configuration options:
[0] - I/O port base base address
[1] - IRQ (unused)
[2] - Voltage unipolar/bipolar configuration
- 0 == unipolar 5V (0V -- +5V)
- 1 == bipolar 5V (-5V -- +5V)
+ 0 == unipolar 5V (0V -- +5V)
+ 1 == bipolar 5V (-5V -- +5V)
[3] - Current offset configuration
- 0 == disabled (0mA -- +32mAV)
- 1 == enabled (+4mA -- +20mAV)
+ 0 == disabled (0mA -- +32mAV)
+ 1 == enabled (+4mA -- +20mAV)
[4] - Firmware program configuration
- 0 == program 1 (see manual table 5-4)
- 1 == program 2 (see manual table 5-4)
- 2 == program 3 (see manual table 5-4)
- 3 == program 4 (see manual table 5-4)
+ 0 == program 1 (see manual table 5-4)
+ 1 == program 2 (see manual table 5-4)
+ 2 == program 3 (see manual table 5-4)
+ 3 == program 4 (see manual table 5-4)
[5] - Analog output 0 range configuration
- 0 == voltage
- 1 == current
+ 0 == voltage
+ 1 == current
[6] - Analog output 1 range configuration (same options)
[7] - Analog output 2 range configuration (same options)
[8] - Analog output 3 range configuration (same options)
@@ -61,17 +61,11 @@ Configuration options:
#include <linux/ioport.h>
#include <linux/delay.h>
-static const struct comedi_lrange range_dt2815_ao_32_current = { 1, {
- RANGE_mA(0,
- 32)
- }
-};
+static const struct comedi_lrange
+ range_dt2815_ao_32_current = {1, {RANGE_mA(0, 32)} };
-static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
- RANGE_mA(4,
- 20)
- }
-};
+static const struct comedi_lrange
+ range_dt2815_ao_20_current = {1, {RANGE_mA(4, 20)} };
#define DT2815_SIZE 2
@@ -118,9 +112,8 @@ static int dt2815_ao_insn_read(struct comedi_device *dev,
int i;
int chan = CR_CHAN(insn->chanspec);
- for (i = 0; i < insn->n; i++) {
+ for (i = 0; i < insn->n; i++)
data[i] = devpriv->ao_readback[chan];
- }
return i;
}
@@ -139,9 +132,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
status = dt2815_wait_for_status(dev, 0x00);
if (status != 0) {
- printk
- ("dt2815: failed to write low byte on %d reason %x\n",
- chan, status);
+ printk(KERN_WARNING "dt2815: failed to write low byte "
+ "on %d reason %x\n", chan, status);
return -EBUSY;
}
@@ -149,9 +141,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
status = dt2815_wait_for_status(dev, 0x10);
if (status != 0x10) {
- printk
- ("dt2815: failed to write high byte on %d reason %x\n",
- chan, status);
+ printk(KERN_WARNING "dt2815: failed to write high byte "
+ "on %d reason %x\n", chan, status);
return -EBUSY;
}
devpriv->ao_readback[chan] = data[i];
@@ -163,24 +154,24 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
options[0] Board base address
options[1] IRQ (not applicable)
options[2] Voltage unipolar/bipolar configuration
- 0 == unipolar 5V (0V -- +5V)
- 1 == bipolar 5V (-5V -- +5V)
+ 0 == unipolar 5V (0V -- +5V)
+ 1 == bipolar 5V (-5V -- +5V)
options[3] Current offset configuration
- 0 == disabled (0mA -- +32mAV)
- 1 == enabled (+4mA -- +20mAV)
+ 0 == disabled (0mA -- +32mAV)
+ 1 == enabled (+4mA -- +20mAV)
options[4] Firmware program configuration
- 0 == program 1 (see manual table 5-4)
- 1 == program 2 (see manual table 5-4)
- 2 == program 3 (see manual table 5-4)
- 3 == program 4 (see manual table 5-4)
+ 0 == program 1 (see manual table 5-4)
+ 1 == program 2 (see manual table 5-4)
+ 2 == program 3 (see manual table 5-4)
+ 3 == program 4 (see manual table 5-4)
options[5] Analog output 0 range configuration
- 0 == voltage
- 1 == current
+ 0 == voltage
+ 1 == current
options[6] Analog output 1 range configuration
...
options[12] Analog output 7 range configuration
- 0 == voltage
- 1 == current
+ 0 == voltage
+ 1 == current
*/
static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -191,9 +182,9 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned long iobase;
iobase = it->options[0];
- printk("comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
+ printk(KERN_INFO "comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
- printk("I/O port conflict\n");
+ printk(KERN_WARNING "I/O port conflict\n");
return -EIO;
}
@@ -236,19 +227,17 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned int program;
program = (it->options[4] & 0x3) << 3 | 0x7;
outb(program, dev->iobase + DT2815_DATA);
- printk(", program: 0x%x (@t=%d)\n", program, i);
+ printk(KERN_INFO ", program: 0x%x (@t=%d)\n",
+ program, i);
break;
} else if (status != 0x00) {
- printk("dt2815: unexpected status 0x%x (@t=%d)\n",
- status, i);
- if (status & 0x60) {
+ printk(KERN_WARNING "dt2815: unexpected status 0x%x "
+ "(@t=%d)\n", status, i);
+ if (status & 0x60)
outb(0x00, dev->iobase + DT2815_STATUS);
- }
}
}
- printk("\n");
-
return 0;
}
@@ -260,7 +249,7 @@ static void dt2815_free_resources(struct comedi_device *dev)
static int dt2815_detach(struct comedi_device *dev)
{
- printk("comedi%d: dt2815: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: dt2815: remove\n", dev->minor);
dt2815_free_resources(dev);
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index 99ca294b1ec..e548763cf2f 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -58,6 +58,7 @@ Notes:
#include "../comedidev.h"
+#include <linux/gfp.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <asm/dma.h>
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 312f4f282bd..96caae36279 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -264,7 +264,7 @@ struct dt9812_usb_cmd {
static DECLARE_MUTEX(dt9812_mutex);
-static struct usb_device_id dt9812_table[] = {
+static const struct usb_device_id dt9812_table[] = {
{USB_DEVICE(0x0867, 0x9812)},
{} /* Terminating entry */
};
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
index 8fca1804335..a10a2b070a2 100644
--- a/drivers/staging/comedi/drivers/fl512.c
+++ b/drivers/staging/comedi/drivers/fl512.c
@@ -76,14 +76,14 @@ static int fl512_ai_insn(struct comedi_device *dev,
unsigned long iobase = dev->iobase;
for (n = 0; n < insn->n; n++) { /* sample n times on selected channel */
- /* XXX probably can move next step out of for() loop -- will make
- * AI a little bit faster. */
+ /* XXX probably can move next step out of for() loop -- will
+ * make AI a little bit faster. */
outb(chan, iobase + 2); /* select chan */
outb(0, iobase + 3); /* start conversion */
/* XXX should test "done" flag instead of delay */
udelay(30); /* sleep 30 usec */
lo_byte = inb(iobase + 2); /* low 8 byte */
- hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */
+ hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */
data[n] = lo_byte + (hi_byte << 8);
}
return n;
@@ -101,8 +101,10 @@ static int fl512_ao_insn(struct comedi_device *dev,
unsigned long iobase = dev->iobase; /* get base address */
for (n = 0; n < insn->n; n++) { /* write n data set */
- outb(data[n] & 0x0ff, iobase + 4 + 2 * chan); /* write low byte */
- outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan); /* write high byte */
+ /* write low byte */
+ outb(data[n] & 0x0ff, iobase + 4 + 2 * chan);
+ /* write high byte */
+ outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan);
inb(iobase + 4 + 2 * chan); /* trig */
devpriv->ao_readback[chan] = data[n];
@@ -121,9 +123,8 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
int n;
int chan = CR_CHAN(insn->chanspec);
- for (n = 0; n < insn->n; n++) {
+ for (n = 0; n < insn->n; n++)
data[n] = devpriv->ao_readback[chan];
- }
return n;
}
@@ -134,13 +135,15 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
unsigned long iobase;
- struct comedi_subdevice *s; /* pointer to the subdevice:
- Analog in, Analog out, ( not made ->and Digital IO) */
+
+ /* pointer to the subdevice: Analog in, Analog out,
+ (not made ->and Digital IO) */
+ struct comedi_subdevice *s;
iobase = it->options[0];
- printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase);
+ printk(KERN_INFO "comedi:%d fl512: 0x%04lx", dev->minor, iobase);
if (!request_region(iobase, FL512_SIZE, "fl512")) {
- printk(" I/O port conflict\n");
+ printk(KERN_WARNING " I/O port conflict\n");
return -EIO;
}
dev->iobase = iobase;
@@ -149,7 +152,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -ENOMEM;
#if DEBUG
- printk("malloc ok\n");
+ printk(KERN_DEBUG "malloc ok\n");
#endif
if (alloc_subdevices(dev, 2) < 0)
@@ -160,24 +163,37 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
*/
/* Analog indput */
s = dev->subdevices + 0;
- s->type = COMEDI_SUBD_AI; /* define subdevice as Analog In */
- s->subdev_flags = SDF_READABLE | SDF_GROUND; /* you can read it from userspace */
- s->n_chan = 16; /* Number of Analog input channels */
- s->maxdata = 0x0fff; /* accept only 12 bits of data */
- s->range_table = &range_fl512; /* device use one of the ranges */
- s->insn_read = fl512_ai_insn; /* function to call when read AD */
- printk("comedi: fl512: subdevice 0 initialized\n");
+ /* define subdevice as Analog In */
+ s->type = COMEDI_SUBD_AI;
+ /* you can read it from userspace */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ /* Number of Analog input channels */
+ s->n_chan = 16;
+ /* accept only 12 bits of data */
+ s->maxdata = 0x0fff;
+ /* device use one of the ranges */
+ s->range_table = &range_fl512;
+ /* function to call when read AD */
+ s->insn_read = fl512_ai_insn;
+ printk(KERN_INFO "comedi: fl512: subdevice 0 initialized\n");
/* Analog output */
s = dev->subdevices + 1;
- s->type = COMEDI_SUBD_AO; /* define subdevice as Analog OUT */
- s->subdev_flags = SDF_WRITABLE; /* you can write it from userspace */
- s->n_chan = 2; /* Number of Analog output channels */
- s->maxdata = 0x0fff; /* accept only 12 bits of data */
- s->range_table = &range_fl512; /* device use one of the ranges */
- s->insn_write = fl512_ao_insn; /* function to call when write DA */
- s->insn_read = fl512_ao_insn_readback; /* function to call when reading DA */
- printk("comedi: fl512: subdevice 1 initialized\n");
+ /* define subdevice as Analog OUT */
+ s->type = COMEDI_SUBD_AO;
+ /* you can write it from userspace */
+ s->subdev_flags = SDF_WRITABLE;
+ /* Number of Analog output channels */
+ s->n_chan = 2;
+ /* accept only 12 bits of data */
+ s->maxdata = 0x0fff;
+ /* device use one of the ranges */
+ s->range_table = &range_fl512;
+ /* function to call when write DA */
+ s->insn_write = fl512_ao_insn;
+ /* function to call when reading DA */
+ s->insn_read = fl512_ao_insn_readback;
+ printk(KERN_INFO "comedi: fl512: subdevice 1 initialized\n");
return 1;
}
@@ -186,6 +202,6 @@ static int fl512_detach(struct comedi_device *dev)
{
if (dev->iobase)
release_region(dev->iobase, FL512_SIZE);
- printk("comedi%d: fl512: dummy i detach\n", dev->minor);
+ printk(KERN_INFO "comedi%d: fl512: dummy i detach\n", dev->minor);
return 0;
}
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index bd397840dcb..d330b188684 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -46,6 +46,7 @@ Devices: [JR3] PCI force sensor board (jr3_pci)
#include <linux/ctype.h>
#include <linux/firmware.h>
#include <linux/jiffies.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include "comedi_pci.h"
#include "jr3_pci.h"
@@ -954,6 +955,8 @@ out:
return result;
}
+MODULE_FIRMWARE("comedi/jr3pci.idm");
+
static int jr3_pci_detach(struct comedi_device *dev)
{
int i;
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
index cb4da2ae842..12e72c82815 100644
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -284,7 +284,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev,
outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
/* printk("Channel %d: \n", insn->chanspec); */
if (!insn->n) {
- printk("MPC624: Warning, no data to aquire\n");
+ printk("MPC624: Warning, no data to acquire\n");
return 0;
}
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index bbf75eb6d7f..9a4fffe5655 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -26,12 +26,13 @@
/*
Driver: ni_65xx
Description: National Instruments 65xx static dio boards
-Author: Jon Grierson <jd@renko.co.uk>, Frank Mori Hess <fmhess@users.sourceforge.net>
+Author: Jon Grierson <jd@renko.co.uk>,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
Status: testing
-Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511,
- PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515,
- PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521,
- PCI-6528, PXI-6528
+Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510,
+ PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514,
+ PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519,
+ PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528
Updated: Wed Oct 18 08:59:11 EDT 2006
Based on the PCI-6527 driver by ds.
@@ -51,6 +52,7 @@ except maybe the 6514.
#define DEBUG 1
#define DEBUG_FLAGS
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include "mite.h"
@@ -418,9 +420,10 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
return -EINVAL;
base_bitfield_channel = CR_CHAN(insn->chanspec);
for (j = 0; j < max_ports_per_bitfield; ++j) {
- const unsigned port_offset = ni_65xx_port_by_channel(base_bitfield_channel) + j;
+ const unsigned port_offset =
+ ni_65xx_port_by_channel(base_bitfield_channel) + j;
const unsigned port =
- sprivate(s)->base_port + port_offset;
+ sprivate(s)->base_port + port_offset;
unsigned base_port_channel;
unsigned port_mask, port_data, port_read_bits;
int bitshift;
@@ -463,11 +466,11 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
* subdevice.) */
port_read_bits ^= 0xFF;
}
- if (bitshift > 0) {
+ if (bitshift > 0)
port_read_bits <<= bitshift;
- } else {
+ else
port_read_bits >>= -bitshift;
- }
+
read_bits |= port_read_bits;
}
data[1] = read_bits;
@@ -532,7 +535,8 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
if (err)
return 1;
- /* step 2: make sure trigger sources are unique and mutually compatible */
+ /* step 2: make sure trigger sources are unique and mutually
+ compatible */
if (err)
return 2;
@@ -652,7 +656,7 @@ static int ni_65xx_attach(struct comedi_device *dev,
unsigned i;
int ret;
- printk("comedi%d: ni_65xx:", dev->minor);
+ printk(KERN_INFO "comedi%d: ni_65xx:", dev->minor);
ret = alloc_private(dev, sizeof(struct ni_65xx_private));
if (ret < 0)
@@ -664,15 +668,15 @@ static int ni_65xx_attach(struct comedi_device *dev,
ret = mite_setup(private(dev)->mite);
if (ret < 0) {
- printk("error setting up mite\n");
+ printk(KERN_WARNING "error setting up mite\n");
return ret;
}
dev->board_name = board(dev)->name;
dev->irq = mite_irq(private(dev)->mite);
- printk(" %s", dev->board_name);
+ printk(KERN_INFO " %s", dev->board_name);
- printk(" ID=0x%02x",
+ printk(KERN_INFO " ID=0x%02x",
readb(private(dev)->mite->daq_io_addr + ID_Register));
ret = alloc_subdevices(dev, 4);
@@ -773,7 +777,7 @@ static int ni_65xx_attach(struct comedi_device *dev,
"ni_65xx", dev);
if (ret < 0) {
dev->irq = 0;
- printk(" irq not available");
+ printk(KERN_WARNING " irq not available");
}
printk("\n");
@@ -790,21 +794,17 @@ static int ni_65xx_detach(struct comedi_device *dev)
Master_Interrupt_Control);
}
- if (dev->irq) {
+ if (dev->irq)
free_irq(dev->irq, dev);
- }
if (private(dev)) {
unsigned i;
for (i = 0; i < dev->n_subdevices; ++i) {
- if (dev->subdevices[i].private) {
- kfree(dev->subdevices[i].private);
- dev->subdevices[i].private = NULL;
- }
+ kfree(dev->subdevices[i].private);
+ dev->subdevices[i].private = NULL;
}
- if (private(dev)->mite) {
+ if (private(dev)->mite)
mite_unsetup(private(dev)->mite);
- }
}
return 0;
}
@@ -830,7 +830,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot)
}
}
}
- printk("no device found\n");
+ printk(KERN_WARNING "no device found\n");
mite_list_devices();
return -EIO;
}
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
index 404d3c516ed..017630fb242 100644
--- a/drivers/staging/comedi/drivers/ni_660x.c
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -52,7 +52,8 @@ enum ni_660x_constants {
};
#define NUM_PFI_CHANNELS 40
-/* really there are only up to 3 dma channels, but the register layout allows for 4 */
+/* really there are only up to 3 dma channels, but the register layout allows
+for 4 */
#define MAX_DMA_CHANNEL 4
/* See Register-Level Programmer Manual page 3.1 */
@@ -198,7 +199,7 @@ struct NI_660xRegisterData {
const char *name; /* Register Name */
int offset; /* Offset from base address from GPCT chip */
enum ni_660x_register_direction direction;
- enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
+ enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
};
static const struct NI_660xRegisterData registerData[NumRegisters] = {
@@ -382,8 +383,8 @@ enum global_interrupt_config_register_bits {
};
/* Offset of the GPCT chips from the base-adress of the card */
-static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; /* First chip is at base-address +
- 0x00, etc. */
+/* First chip is at base-address + 0x00, etc. */
+static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };
/* Board description*/
struct ni_660x_board {
@@ -691,13 +692,13 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
ni_660x_register = G0StatusRegister;
break;
case NITIO_G1_Status_Reg:
- ni_660x_register = G0StatusRegister;
+ ni_660x_register = G1StatusRegister;
break;
case NITIO_G2_Status_Reg:
- ni_660x_register = G0StatusRegister;
+ ni_660x_register = G2StatusRegister;
break;
case NITIO_G3_Status_Reg:
- ni_660x_register = G0StatusRegister;
+ ni_660x_register = G3StatusRegister;
break;
case NITIO_G0_Interrupt_Enable_Reg:
ni_660x_register = G0InterruptEnable;
@@ -712,7 +713,7 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
ni_660x_register = G3InterruptEnable;
break;
default:
- printk("%s: unhandled register 0x%x in switch.\n",
+ printk(KERN_WARNING "%s: unhandled register 0x%x in switch.\n",
__func__, reg);
BUG();
return 0;
@@ -737,7 +738,7 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
writel(bits, write_address);
break;
default:
- printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+ printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
__FILE__, __func__, reg);
BUG();
break;
@@ -760,7 +761,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
return readl(read_address);
break;
default:
- printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+ printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
__FILE__, __func__, reg);
BUG();
break;
@@ -993,9 +994,9 @@ static int ni_660x_allocate_private(struct comedi_device *dev)
spin_lock_init(&private(dev)->mite_channel_lock);
spin_lock_init(&private(dev)->interrupt_lock);
spin_lock_init(&private(dev)->soft_reg_copy_lock);
- for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+ for (i = 0; i < NUM_PFI_CHANNELS; ++i)
private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
- }
+
return 0;
}
@@ -1008,9 +1009,8 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
for (j = 0; j < counters_per_chip; ++j) {
private(dev)->mite_rings[i][j] =
mite_alloc_ring(private(dev)->mite);
- if (private(dev)->mite_rings[i][j] == NULL) {
+ if (private(dev)->mite_rings[i][j] == NULL)
return -ENOMEM;
- }
}
}
return 0;
@@ -1022,9 +1022,8 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev)
unsigned j;
for (i = 0; i < board(dev)->n_chips; ++i) {
- for (j = 0; j < counters_per_chip; ++j) {
+ for (j = 0; j < counters_per_chip; ++j)
mite_free_ring(private(dev)->mite_rings[i][j]);
- }
}
}
@@ -1036,7 +1035,7 @@ static int ni_660x_attach(struct comedi_device *dev,
unsigned i;
unsigned global_interrupt_config_bits;
- printk("comedi%d: ni_660x: ", dev->minor);
+ printk(KERN_INFO "comedi%d: ni_660x: ", dev->minor);
ret = ni_660x_allocate_private(dev);
if (ret < 0)
@@ -1049,7 +1048,7 @@ static int ni_660x_attach(struct comedi_device *dev,
ret = mite_setup2(private(dev)->mite, 1);
if (ret < 0) {
- printk("error setting up mite\n");
+ printk(KERN_WARNING "error setting up mite\n");
return ret;
}
comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
@@ -1057,7 +1056,7 @@ static int ni_660x_attach(struct comedi_device *dev,
if (ret < 0)
return ret;
- printk(" %s ", dev->board_name);
+ printk(KERN_INFO " %s ", dev->board_name);
dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
@@ -1078,15 +1077,16 @@ static int ni_660x_attach(struct comedi_device *dev,
s->insn_bits = ni_660x_dio_insn_bits;
s->insn_config = ni_660x_dio_insn_config;
s->io_bits = 0; /* all bits default to input */
- /* we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg */
+ /* we use the ioconfig registers to control dio direction, so zero
+ output enables in stc dio control reg */
ni_660x_write_register(dev, 0, 0, STCDIOControl);
private(dev)->counter_dev = ni_gpct_device_construct(dev,
- &ni_gpct_write_register,
- &ni_gpct_read_register,
- ni_gpct_variant_660x,
- ni_660x_num_counters
- (dev));
+ &ni_gpct_write_register,
+ &ni_gpct_read_register,
+ ni_gpct_variant_660x,
+ ni_660x_num_counters
+ (dev));
if (private(dev)->counter_dev == NULL)
return -ENOMEM;
for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
@@ -1118,12 +1118,12 @@ static int ni_660x_attach(struct comedi_device *dev,
s->type = COMEDI_SUBD_UNUSED;
}
}
- for (i = 0; i < board(dev)->n_chips; ++i) {
+ for (i = 0; i < board(dev)->n_chips; ++i)
init_tio_chip(dev, i);
- }
- for (i = 0; i < ni_660x_num_counters(dev); ++i) {
+
+ for (i = 0; i < ni_660x_num_counters(dev); ++i)
ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
- }
+
for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
if (i < min_counter_pfi_chan)
ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
@@ -1134,13 +1134,13 @@ static int ni_660x_attach(struct comedi_device *dev,
}
/* to be safe, set counterswap bits on tio chips after all the counter
outputs have been set to high impedance mode */
- for (i = 0; i < board(dev)->n_chips; ++i) {
+ for (i = 0; i < board(dev)->n_chips; ++i)
set_tio_counterswap(dev, i);
- }
+
ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt,
IRQF_SHARED, "ni_660x", dev);
if (ret < 0) {
- printk(" irq not available\n");
+ printk(KERN_WARNING " irq not available\n");
return ret;
}
dev->irq = mite_irq(private(dev)->mite);
@@ -1149,13 +1149,13 @@ static int ni_660x_attach(struct comedi_device *dev,
global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
ni_660x_write_register(dev, 0, global_interrupt_config_bits,
GlobalInterruptConfigRegister);
- printk("attached\n");
+ printk(KERN_INFO "attached\n");
return 0;
}
static int ni_660x_detach(struct comedi_device *dev)
{
- printk("comedi%d: ni_660x: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: ni_660x: remove\n", dev->minor);
/* Free irq */
if (dev->irq)
@@ -1193,9 +1193,8 @@ static void init_tio_chip(struct comedi_device *dev, int chipset)
private(dev)->
dma_configuration_soft_copies[chipset],
DMAConfigRegister);
- for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+ for (i = 0; i < NUM_PFI_CHANNELS; ++i)
ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
- }
}
static int
@@ -1234,7 +1233,7 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
}
}
}
- printk("no device found\n");
+ printk(KERN_WARNING "no device found\n");
mite_list_devices();
return -EIO;
}
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index 9b43547e80a..68221bfba5d 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -42,6 +42,7 @@ Commands are not supported.
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include "mite.h"
@@ -93,7 +94,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = {
{
PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- /* { PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
+ /*{ PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },*/
{
0}
};
@@ -151,7 +152,7 @@ static int ni_670x_attach(struct comedi_device *dev,
int ret;
int i;
- printk("comedi%d: ni_670x: ", dev->minor);
+ printk(KERN_INFO "comedi%d: ni_670x: ", dev->minor);
ret = alloc_private(dev, sizeof(struct ni_670x_private));
if (ret < 0)
@@ -163,12 +164,12 @@ static int ni_670x_attach(struct comedi_device *dev,
ret = mite_setup(devpriv->mite);
if (ret < 0) {
- printk("error setting up mite\n");
+ printk(KERN_WARNING "error setting up mite\n");
return ret;
}
dev->board_name = thisboard->name;
dev->irq = mite_irq(devpriv->mite);
- printk(" %s", dev->board_name);
+ printk(KERN_INFO " %s", dev->board_name);
if (alloc_subdevices(dev, 2) < 0)
return -ENOMEM;
@@ -207,21 +208,22 @@ static int ni_670x_attach(struct comedi_device *dev,
s->insn_bits = ni_670x_dio_insn_bits;
s->insn_config = ni_670x_dio_insn_config;
- writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET); /* Config of misc registers */
- writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET); /* Config of ao registers */
+ /* Config of misc registers */
+ writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET);
+ /* Config of ao registers */
+ writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET);
- printk("attached\n");
+ printk(KERN_INFO "attached\n");
return 1;
}
static int ni_670x_detach(struct comedi_device *dev)
{
- printk("comedi%d: ni_670x: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: ni_670x: remove\n", dev->minor);
+
+ kfree(dev->subdevices[0].range_table_list);
- if (dev->subdevices[0].range_table_list) {
- kfree(dev->subdevices[0].range_table_list);
- }
if (dev->private && devpriv->mite)
mite_unsetup(devpriv->mite);
@@ -250,8 +252,11 @@ static int ni_670x_ao_winsn(struct comedi_device *dev,
vch(15) : 30 | ich(31) : 31 */
for (i = 0; i < insn->n; i++) {
- writel(((chan & 15) << 1) | ((chan & 16) >> 4), devpriv->mite->daq_io_addr + AO_CHAN_OFFSET); /* First write in channel register which channel to use */
- writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET); /* write channel value */
+ /* First write in channel register which channel to use */
+ writel(((chan & 15) << 1) | ((chan & 16) >> 4),
+ devpriv->mite->daq_io_addr + AO_CHAN_OFFSET);
+ /* write channel value */
+ writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET);
devpriv->ao_readback[chan] = data[i];
}
@@ -344,7 +349,7 @@ static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot)
}
}
}
- printk("no device found\n");
+ printk(KERN_INFO "no device found\n");
mite_list_devices();
return -EIO;
}
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index dd75dfb3430..9bff34cf06d 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -65,6 +65,7 @@ TRIG_WAKE_EOS
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include <linux/ioport.h>
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index 8ead31164d5..003d00b595b 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -329,11 +329,11 @@ static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr)
}
static struct pnp_device_id device_ids[] = {
- {.id = "NIC1900",.driver_data = 0},
- {.id = "NIC2400",.driver_data = 0},
- {.id = "NIC2500",.driver_data = 0},
- {.id = "NIC2600",.driver_data = 0},
- {.id = "NIC2700",.driver_data = 0},
+ {.id = "NIC1900", .driver_data = 0},
+ {.id = "NIC2400", .driver_data = 0},
+ {.id = "NIC2500", .driver_data = 0},
+ {.id = "NIC2600", .driver_data = 0},
+ {.id = "NIC2700", .driver_data = 0},
{.id = ""}
};
@@ -362,9 +362,9 @@ static int ni_atmio_detach(struct comedi_device *dev)
if (dev->iobase)
release_region(dev->iobase, NI_SIZE);
- if (dev->irq) {
+ if (dev->irq)
free_irq(dev->irq, dev);
- }
+
if (devpriv->isapnp_dev)
pnp_device_detach(devpriv->isapnp_dev);
@@ -387,8 +387,8 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
if (pnp_device_attach(isapnp_dev) < 0) {
printk
- ("ni_atmio: %s found but already active, skipping.\n",
- ni_boards[i].name);
+ ("ni_atmio: %s found but already active, skipping.\n",
+ ni_boards[i].name);
continue;
}
if (pnp_activate_dev(isapnp_dev) < 0) {
@@ -496,9 +496,9 @@ static int ni_atmio_attach(struct comedi_device *dev,
/* generic E series stuff in ni_mio_common.c */
ret = ni_E_init(dev, it);
- if (ret < 0) {
+ if (ret < 0)
return ret;
- }
+
return 0;
}
@@ -509,16 +509,16 @@ static int ni_getboardtype(struct comedi_device *dev)
int i;
for (i = 0; i < n_ni_boards; i++) {
- if (ni_boards[i].device_id == device_id) {
+ if (ni_boards[i].device_id == device_id)
return i;
- }
+
}
- if (device_id == 255) {
+ if (device_id == 255)
printk(" can't find board\n");
- } else if (device_id == 0) {
+ else if (device_id == 0)
printk(" EEPROM read error (?) or device not found\n");
- } else {
+ else
printk(" unknown device ID %d -- contact author\n", device_id);
- }
+
return -1;
}
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index ef5e1183d47..7ea64538e05 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -42,6 +42,7 @@ IRQ is assigned but not used.
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include <linux/ioport.h>
@@ -76,13 +77,15 @@ struct dio700_board {
static const struct dio700_board dio700_boards[] = {
{
.name = "daqcard-700",
- .device_id = 0x4743, /* 0x10b is manufacturer id, 0x4743 is device id */
+ /* 0x10b is manufacturer id, 0x4743 is device id */
+ .device_id = 0x4743,
.bustype = pcmcia_bustype,
.have_dio = 1,
},
{
.name = "ni_daq_700",
- .device_id = 0x4743, /* 0x10b is manufacturer id, 0x4743 is device id */
+ /* 0x10b is manufacturer id, 0x4743 is device id */
+ .device_id = 0x4743,
.bustype = pcmcia_bustype,
.have_dio = 1,
},
@@ -309,11 +312,11 @@ int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s,
return -ENOMEM;
CALLBACK_ARG = arg;
- if (cb == NULL) {
+ if (cb == NULL)
CALLBACK_FUNC = subdev_700_cb;
- } else {
+ else
CALLBACK_FUNC = cb;
- }
+
s->insn_bits = subdev_700_insn;
s->insn_config = subdev_700_insn_config;
@@ -345,12 +348,10 @@ int subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
{
- if (s->private) {
- if (subdevpriv->have_irq) {
- }
+ if (s->private)
+ if (subdevpriv->have_irq)
- kfree(s->private);
- }
+ kfree(s->private);
}
EXPORT_SYMBOL(subdev_700_init);
@@ -390,9 +391,9 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it)
printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor,
thisboard->name, iobase);
#ifdef incomplete
- if (irq) {
+ if (irq)
printk(", irq %u", irq);
- }
+
#endif
printk("\n");
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index 9017be3a92f..ddc312b5d20 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -41,6 +41,7 @@ the PCMCIA interface.
#undef LABPC_DEBUG
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include <linux/ioport.h>
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index dc3f398cb3e..558e525fed3 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -77,6 +77,7 @@ NI manuals:
/* #define LABPC_DEBUG enable debugging messages */
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include <linux/delay.h>
@@ -90,8 +91,10 @@ NI manuals:
#define DRV_NAME "ni_labpc"
-#define LABPC_SIZE 32 /* size of io region used by board */
-#define LABPC_TIMER_BASE 500 /* 2 MHz master clock */
+/* size of io region used by board */
+#define LABPC_SIZE 32
+/* 2 MHz master clock */
+#define LABPC_TIMER_BASE 500
/* Registers for the lab-pc+ */
@@ -99,69 +102,110 @@ NI manuals:
#define COMMAND1_REG 0x0
#define ADC_GAIN_MASK (0x7 << 4)
#define ADC_CHAN_BITS(x) ((x) & 0x7)
-#define ADC_SCAN_EN_BIT 0x80 /* enables multi channel scans */
+/* enables multi channel scans */
+#define ADC_SCAN_EN_BIT 0x80
#define COMMAND2_REG 0x1
-#define PRETRIG_BIT 0x1 /* enable pretriggering (used in conjunction with SWTRIG) */
-#define HWTRIG_BIT 0x2 /* enable paced conversions on external trigger */
-#define SWTRIG_BIT 0x4 /* enable paced conversions */
-#define CASCADE_BIT 0x8 /* use two cascaded counters for pacing */
+/* enable pretriggering (used in conjunction with SWTRIG) */
+#define PRETRIG_BIT 0x1
+/* enable paced conversions on external trigger */
+#define HWTRIG_BIT 0x2
+/* enable paced conversions */
+#define SWTRIG_BIT 0x4
+/* use two cascaded counters for pacing */
+#define CASCADE_BIT 0x8
#define DAC_PACED_BIT(channel) (0x40 << ((channel) & 0x1))
#define COMMAND3_REG 0x2
-#define DMA_EN_BIT 0x1 /* enable dma transfers */
-#define DIO_INTR_EN_BIT 0x2 /* enable interrupts for 8255 */
-#define DMATC_INTR_EN_BIT 0x4 /* enable dma terminal count interrupt */
-#define TIMER_INTR_EN_BIT 0x8 /* enable timer interrupt */
-#define ERR_INTR_EN_BIT 0x10 /* enable error interrupt */
-#define ADC_FNE_INTR_EN_BIT 0x20 /* enable fifo not empty interrupt */
+/* enable dma transfers */
+#define DMA_EN_BIT 0x1
+/* enable interrupts for 8255 */
+#define DIO_INTR_EN_BIT 0x2
+/* enable dma terminal count interrupt */
+#define DMATC_INTR_EN_BIT 0x4
+/* enable timer interrupt */
+#define TIMER_INTR_EN_BIT 0x8
+/* enable error interrupt */
+#define ERR_INTR_EN_BIT 0x10
+/* enable fifo not empty interrupt */
+#define ADC_FNE_INTR_EN_BIT 0x20
#define ADC_CONVERT_REG 0x3
#define DAC_LSB_REG(channel) (0x4 + 2 * ((channel) & 0x1))
#define DAC_MSB_REG(channel) (0x5 + 2 * ((channel) & 0x1))
#define ADC_CLEAR_REG 0x8
#define DMATC_CLEAR_REG 0xa
#define TIMER_CLEAR_REG 0xc
-#define COMMAND6_REG 0xe /* 1200 boards only */
-#define ADC_COMMON_BIT 0x1 /* select ground or common-mode reference */
-#define ADC_UNIP_BIT 0x2 /* adc unipolar */
-#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1)) /* dac unipolar */
-#define ADC_FHF_INTR_EN_BIT 0x20 /* enable fifo half full interrupt */
-#define A1_INTR_EN_BIT 0x40 /* enable interrupt on end of hardware count */
-#define ADC_SCAN_UP_BIT 0x80 /* scan up from channel zero instead of down to zero */
+/* 1200 boards only */
+#define COMMAND6_REG 0xe
+/* select ground or common-mode reference */
+#define ADC_COMMON_BIT 0x1
+/* adc unipolar */
+#define ADC_UNIP_BIT 0x2
+/* dac unipolar */
+#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1))
+/* enable fifo half full interrupt */
+#define ADC_FHF_INTR_EN_BIT 0x20
+/* enable interrupt on end of hardware count */
+#define A1_INTR_EN_BIT 0x40
+/* scan up from channel zero instead of down to zero */
+#define ADC_SCAN_UP_BIT 0x80
#define COMMAND4_REG 0xf
-#define INTERVAL_SCAN_EN_BIT 0x1 /* enables 'interval' scanning */
-#define EXT_SCAN_EN_BIT 0x2 /* enables external signal on counter b1 output to trigger scan */
-#define EXT_CONVERT_OUT_BIT 0x4 /* chooses direction (output or input) for EXTCONV* line */
-#define ADC_DIFF_BIT 0x8 /* chooses differential inputs for adc (in conjunction with board jumper) */
+/* enables 'interval' scanning */
+#define INTERVAL_SCAN_EN_BIT 0x1
+/* enables external signal on counter b1 output to trigger scan */
+#define EXT_SCAN_EN_BIT 0x2
+/* chooses direction (output or input) for EXTCONV* line */
+#define EXT_CONVERT_OUT_BIT 0x4
+/* chooses differential inputs for adc (in conjunction with board jumper) */
+#define ADC_DIFF_BIT 0x8
#define EXT_CONVERT_DISABLE_BIT 0x10
-#define COMMAND5_REG 0x1c /* 1200 boards only, calibration stuff */
-#define EEPROM_WRITE_UNPROTECT_BIT 0x4 /* enable eeprom for write */
-#define DITHER_EN_BIT 0x8 /* enable dithering */
-#define CALDAC_LOAD_BIT 0x10 /* load calibration dac */
-#define SCLOCK_BIT 0x20 /* serial clock - rising edge writes, falling edge reads */
-#define SDATA_BIT 0x40 /* serial data bit for writing to eeprom or calibration dacs */
-#define EEPROM_EN_BIT 0x80 /* enable eeprom for read/write */
+/* 1200 boards only, calibration stuff */
+#define COMMAND5_REG 0x1c
+/* enable eeprom for write */
+#define EEPROM_WRITE_UNPROTECT_BIT 0x4
+/* enable dithering */
+#define DITHER_EN_BIT 0x8
+/* load calibration dac */
+#define CALDAC_LOAD_BIT 0x10
+/* serial clock - rising edge writes, falling edge reads */
+#define SCLOCK_BIT 0x20
+/* serial data bit for writing to eeprom or calibration dacs */
+#define SDATA_BIT 0x40
+/* enable eeprom for read/write */
+#define EEPROM_EN_BIT 0x80
#define INTERVAL_COUNT_REG 0x1e
#define INTERVAL_LOAD_REG 0x1f
#define INTERVAL_LOAD_BITS 0x1
/* read-only registers */
#define STATUS1_REG 0x0
-#define DATA_AVAIL_BIT 0x1 /* data is available in fifo */
-#define OVERRUN_BIT 0x2 /* overrun has occurred */
-#define OVERFLOW_BIT 0x4 /* fifo overflow */
-#define TIMER_BIT 0x8 /* timer interrupt has occured */
-#define DMATC_BIT 0x10 /* dma terminal count has occured */
-#define EXT_TRIG_BIT 0x40 /* external trigger has occured */
-#define STATUS2_REG 0x1d /* 1200 boards only */
-#define EEPROM_OUT_BIT 0x1 /* programmable eeprom serial output */
-#define A1_TC_BIT 0x2 /* counter A1 terminal count */
-#define FNHF_BIT 0x4 /* fifo not half full */
+/* data is available in fifo */
+#define DATA_AVAIL_BIT 0x1
+/* overrun has occurred */
+#define OVERRUN_BIT 0x2
+/* fifo overflow */
+#define OVERFLOW_BIT 0x4
+/* timer interrupt has occured */
+#define TIMER_BIT 0x8
+/* dma terminal count has occured */
+#define DMATC_BIT 0x10
+/* external trigger has occured */
+#define EXT_TRIG_BIT 0x40
+/* 1200 boards only */
+#define STATUS2_REG 0x1d
+/* programmable eeprom serial output */
+#define EEPROM_OUT_BIT 0x1
+/* counter A1 terminal count */
+#define A1_TC_BIT 0x2
+/* fifo not half full */
+#define FNHF_BIT 0x4
#define ADC_FIFO_REG 0xa
#define DIO_BASE_REG 0x10
#define COUNTER_A_BASE_REG 0x14
#define COUNTER_A_CONTROL_REG (COUNTER_A_BASE_REG + 0x3)
-#define INIT_A0_BITS 0x14 /* check modes put conversion pacer output in harmless state (a0 mode 2) */
-#define INIT_A1_BITS 0x70 /* put hardware conversion counter output in harmless state (a1 mode 0) */
+/* check modes put conversion pacer output in harmless state (a0 mode 2) */
+#define INIT_A0_BITS 0x14
+/* put hardware conversion counter output in harmless state (a1 mode 0) */
+#define INIT_A1_BITS 0x70
#define COUNTER_B_BASE_REG 0x18
static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it);
@@ -423,7 +467,7 @@ static const struct labpc_board_struct labpc_boards[] = {
.ai_scan_up = 1,
.memory_mapped_io = 1,
},
- /* dummy entry so pci board works when comedi_config is passed driver name */
+/* dummy entry so pci board works when comedi_config is passed driver name */
{
.name = DRV_NAME,
.bustype = pci_bustype,
@@ -436,8 +480,10 @@ static const struct labpc_board_struct labpc_boards[] = {
*/
#define thisboard ((struct labpc_board_struct *)dev->board_ptr)
-static const int dma_buffer_size = 0xff00; /* size in bytes of dma buffer */
-static const int sample_size = 2; /* 2 bytes per sample */
+/* size in bytes of dma buffer */
+static const int dma_buffer_size = 0xff00;
+/* 2 bytes per sample */
+static const int sample_size = 2;
#define devpriv ((struct labpc_private *)dev->private)
@@ -483,12 +529,10 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name,
iobase);
- if (irq) {
+ if (irq)
printk(", irq %u", irq);
- }
- if (dma_chan) {
+ if (dma_chan)
printk(", dma %u", dma_chan);
- }
printk("\n");
if (iobase == 0) {
@@ -513,7 +557,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
devpriv->read_byte = labpc_inb;
devpriv->write_byte = labpc_outb;
}
- /* initialize board's command registers */
+ /* initialize board's command registers */
devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
@@ -538,12 +582,12 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
}
dev->irq = irq;
- /* grab dma channel */
+ /* grab dma channel */
if (dma_chan > 3) {
printk(" invalid dma channel %u\n", dma_chan);
return -EINVAL;
} else if (dma_chan) {
- /* allocate dma buffer */
+ /* allocate dma buffer */
devpriv->dma_buffer =
kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
if (devpriv->dma_buffer == NULL) {
@@ -575,7 +619,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ;
s->n_chan = 8;
s->len_chanlist = 8;
- s->maxdata = (1 << 12) - 1; /* 12 bit resolution */
+ s->maxdata = (1 << 12) - 1; /* 12 bit resolution */
s->range_table = thisboard->ai_range_table;
s->do_cmd = labpc_ai_cmd;
s->do_cmdtest = labpc_ai_cmdtest;
@@ -585,8 +629,11 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
/* analog output */
s = dev->subdevices + 1;
if (thisboard->has_ao) {
-/* Could provide command support, except it only has a one sample
- * hardware buffer for analog output and no underrun flag. */
+ /*
+ * Could provide command support, except it only has a
+ * one sample hardware buffer for analog output and no
+ * underrun flag.
+ */
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
s->n_chan = NUM_AO_CHAN;
@@ -608,7 +655,8 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
/* 8255 dio */
s = dev->subdevices + 2;
- /* if board uses io memory we have to give a custom callback function to the 8255 driver */
+ /* if board uses io memory we have to give a custom callback
+ * function to the 8255 driver */
if (thisboard->memory_mapped_io)
subdev_8255_init(dev, s, labpc_dio_mem_callback,
(unsigned long)(dev->iobase + DIO_BASE_REG));
@@ -640,14 +688,12 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
s->insn_read = labpc_eeprom_read_insn;
s->insn_write = labpc_eeprom_write_insn;
- for (i = 0; i < EEPROM_SIZE; i++) {
+ for (i = 0; i < EEPROM_SIZE; i++)
devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
- }
#ifdef LABPC_DEBUG
printk(" eeprom:");
- for (i = 0; i < EEPROM_SIZE; i++) {
+ for (i = 0; i < EEPROM_SIZE; i++)
printk(" %i:0x%x ", i, devpriv->eeprom_data[i]);
- }
printk("\n");
#endif
} else
@@ -669,7 +715,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (alloc_private(dev, sizeof(struct labpc_private)) < 0)
return -ENOMEM;
- /* get base address, irq etc. based on bustype */
+ /* get base address, irq etc. based on bustype */
switch (thisboard->bustype) {
case isa_bustype:
iobase = it->options[0];
@@ -679,9 +725,8 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
case pci_bustype:
#ifdef CONFIG_COMEDI_PCI
retval = labpc_find_device(dev, it->options[0], it->options[1]);
- if (retval < 0) {
+ if (retval < 0)
return retval;
- }
retval = mite_setup(devpriv->mite);
if (retval < 0)
return retval;
@@ -715,7 +760,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
for (mite = mite_devices; mite; mite = mite->next) {
if (mite->used)
continue;
- /* if bus/slot are specified then make sure we have the right bus/slot */
+/* if bus/slot are specified then make sure we have the right bus/slot */
if (bus || slot) {
if (bus != mite->pcidev->bus->number
|| slot != PCI_SLOT(mite->pcidev->devfn))
@@ -726,7 +771,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
continue;
if (mite_device_id(mite) == labpc_boards[i].device_id) {
devpriv->mite = mite;
- /* fixup board pointer, in case we were using the dummy "ni_labpc" entry */
+/* fixup board pointer, in case we were using the dummy "ni_labpc" entry */
dev->board_ptr = &labpc_boards[i];
return 0;
}
@@ -994,7 +1039,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
err++;
- /* can't have external stop and start triggers at once */
+ /* can't have external stop and start triggers at once */
if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
err++;
@@ -1008,9 +1053,9 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
err++;
}
- if (!cmd->chanlist_len) {
+ if (!cmd->chanlist_len)
err++;
- }
+
if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len;
err++;
@@ -1022,7 +1067,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
err++;
}
}
- /* make sure scan timing is not too fast */
+ /* make sure scan timing is not too fast */
if (cmd->scan_begin_src == TRIG_TIMER) {
if (cmd->convert_src == TRIG_TIMER &&
cmd->scan_begin_arg <
@@ -1038,7 +1083,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
err++;
}
}
- /* stop source */
+ /* stop source */
switch (cmd->stop_src) {
case TRIG_COUNT:
if (!cmd->stop_arg) {
@@ -1095,7 +1140,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
range = CR_RANGE(cmd->chanlist[0]);
aref = CR_AREF(cmd->chanlist[0]);
- /* make sure board is disabled before setting up aquisition */
+ /* make sure board is disabled before setting up aquisition */
spin_lock_irqsave(&dev->spinlock, flags);
devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
@@ -1105,9 +1150,9 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
/* initialize software conversion count */
- if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_src == TRIG_COUNT)
devpriv->count = cmd->stop_arg * cmd->chanlist_len;
- }
+
/* setup hardware conversion counter */
if (cmd->stop_src == TRIG_EXT) {
/* load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0 */
@@ -1176,17 +1221,18 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
else
channel = CR_CHAN(cmd->chanlist[0]);
- /* munge channel bits for differential / scan disabled mode */
+ /* munge channel bits for differential / scan disabled mode */
if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF)
channel *= 2;
devpriv->command1_bits |= ADC_CHAN_BITS(channel);
devpriv->command1_bits |= thisboard->ai_range_code[range];
devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
- /* manual says to set scan enable bit on second pass */
+ /* manual says to set scan enable bit on second pass */
if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP ||
labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) {
devpriv->command1_bits |= ADC_SCAN_EN_BIT;
- /* need a brief delay before enabling scan, or scan list will get screwed when you switch
+ /* need a brief delay before enabling scan, or scan
+ * list will get screwed when you switch
* between scan up to scan down mode - dunno why */
udelay(1);
devpriv->write_byte(devpriv->command1_bits,
@@ -1338,7 +1384,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
cmd = &async->cmd;
async->events = 0;
- /* read board status */
+ /* read board status */
devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
if (thisboard->register_layout == labpc_1200_layout)
devpriv->status2_bits =
@@ -1352,7 +1398,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
}
if (devpriv->status1_bits & OVERRUN_BIT) {
- /* clear error interrupt */
+ /* clear error interrupt */
devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
comedi_event(dev, s);
@@ -1361,7 +1407,10 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
}
if (devpriv->current_transfer == isa_dma_transfer) {
- /* if a dma terminal count of external stop trigger has occurred */
+ /*
+ * if a dma terminal count of external stop trigger
+ * has occurred
+ */
if (devpriv->status1_bits & DMATC_BIT ||
(thisboard->register_layout == labpc_1200_layout
&& devpriv->status2_bits & A1_TC_BIT)) {
@@ -1479,9 +1528,9 @@ static void labpc_drain_dma(struct comedi_device *dev)
}
/* write data to comedi buffer */
- for (i = 0; i < num_points; i++) {
+ for (i = 0; i < num_points; i++)
cfc_write_to_buffer(s, devpriv->dma_buffer[i]);
- }
+
if (async->cmd.stop_src == TRIG_COUNT)
devpriv->count -= num_points;
@@ -1503,7 +1552,7 @@ static void handle_isa_dma(struct comedi_device *dev)
devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
}
-/* makes sure all data aquired by board is transfered to comedi (used
+/* makes sure all data acquired by board is transfered to comedi (used
* when aquisition is terminated by stop_src == TRIG_EXT). */
static void labpc_drain_dregs(struct comedi_device *dev)
{
@@ -1537,41 +1586,41 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
chan = CR_CHAN(insn->chanspec);
range = CR_RANGE(insn->chanspec);
devpriv->command1_bits |= thisboard->ai_range_code[range];
- /* munge channel bits for differential/scan disabled mode */
+ /* munge channel bits for differential/scan disabled mode */
if (CR_AREF(insn->chanspec) == AREF_DIFF)
chan *= 2;
devpriv->command1_bits |= ADC_CHAN_BITS(chan);
devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
- /* setup command6 register for 1200 boards */
+ /* setup command6 register for 1200 boards */
if (thisboard->register_layout == labpc_1200_layout) {
/* reference inputs to ground or common? */
if (CR_AREF(insn->chanspec) != AREF_GROUND)
devpriv->command6_bits |= ADC_COMMON_BIT;
else
devpriv->command6_bits &= ~ADC_COMMON_BIT;
- /* bipolar or unipolar range? */
+ /* bipolar or unipolar range? */
if (thisboard->ai_range_is_unipolar[range])
devpriv->command6_bits |= ADC_UNIP_BIT;
else
devpriv->command6_bits &= ~ADC_UNIP_BIT;
- /* don't interrupt on fifo half full */
+ /* don't interrupt on fifo half full */
devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
- /* don't enable interrupt on counter a1 terminal count? */
+ /* don't enable interrupt on counter a1 terminal count? */
devpriv->command6_bits &= ~A1_INTR_EN_BIT;
- /* write to register */
+ /* write to register */
devpriv->write_byte(devpriv->command6_bits,
dev->iobase + COMMAND6_REG);
}
- /* setup command4 register */
+ /* setup command4 register */
devpriv->command4_bits = 0;
devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
- /* single-ended/differential */
+ /* single-ended/differential */
if (CR_AREF(insn->chanspec) == AREF_DIFF)
devpriv->command4_bits |= ADC_DIFF_BIT;
devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
- /* initialize pacer counter output to make sure it doesn't cause any problems */
+ /* initialize pacer counter output to make sure it doesn't cause any problems */
devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG);
labpc_clear_adc_fifo(dev);
@@ -1608,7 +1657,7 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
channel = CR_CHAN(insn->chanspec);
- /* turn off pacing of analog output channel */
+ /* turn off pacing of analog output channel */
/* note: hardware bug in daqcard-1200 means pacing cannot
* be independently enabled/disabled for its the two channels */
spin_lock_irqsave(&dev->spinlock, flags);
@@ -1616,7 +1665,7 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
- /* set range */
+ /* set range */
if (thisboard->register_layout == labpc_1200_layout) {
range = CR_RANGE(insn->chanspec);
if (range & AO_RANGE_IS_UNIPOLAR)
@@ -1627,13 +1676,13 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
devpriv->write_byte(devpriv->command6_bits,
dev->iobase + COMMAND6_REG);
}
- /* send data */
+ /* send data */
lsb = data[0] & 0xff;
msb = (data[0] >> 8) & 0xff;
devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
- /* remember value for readback */
+ /* remember value for readback */
devpriv->ao_value[channel] = data[0];
return 1;
@@ -1705,14 +1754,14 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
if (cmd.convert_src == TRIG_TIMER)
freq = 1000000000 / cmd.convert_arg;
- /* return some default value */
+ /* return some default value */
else
freq = 0xffffffff;
- /* make buffer fill in no more than 1/3 second */
+ /* make buffer fill in no more than 1/3 second */
size = (freq / 3) * sample_size;
- /* set a minimum and maximum size allowed */
+ /* set a minimum and maximum size allowed */
if (size > dma_buffer_size)
size = dma_buffer_size - dma_buffer_size % sample_size;
else if (size < sample_size)
@@ -1724,13 +1773,21 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
/* figures out what counter values to use based on command */
static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
{
- const int max_counter_value = 0x10000; /* max value for 16 bit counter in mode 2 */
- const int min_counter_value = 2; /* min value for 16 bit counter in mode 2 */
+ /* max value for 16 bit counter in mode 2 */
+ const int max_counter_value = 0x10000;
+ /* min value for 16 bit counter in mode 2 */
+ const int min_counter_value = 2;
unsigned int base_period;
- /* if both convert and scan triggers are TRIG_TIMER, then they both rely on counter b0 */
+ /*
+ * if both convert and scan triggers are TRIG_TIMER, then they
+ * both rely on counter b0
+ */
if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) {
- /* pick the lowest b0 divisor value we can (for maximum input clock speed on convert and scan counters) */
+ /*
+ * pick the lowest b0 divisor value we can (for maximum input
+ * clock speed on convert and scan counters)
+ */
devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) /
(LABPC_TIMER_BASE * max_counter_value) + 1;
if (devpriv->divisor_b0 < min_counter_value)
@@ -1780,7 +1837,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
base_period * devpriv->divisor_a0);
labpc_set_ai_scan_period(cmd,
base_period * devpriv->divisor_b1);
- /* if only one TRIG_TIMER is used, we can employ the generic cascaded timing functions */
+ /*
+ * if only one TRIG_TIMER is used, we can employ the generic
+ * cascaded timing functions
+ */
} else if (labpc_ai_scan_period(cmd)) {
unsigned int scan_period;
@@ -1864,9 +1924,8 @@ static unsigned int labpc_serial_in(struct comedi_device *dev)
udelay(1);
devpriv->status2_bits =
devpriv->read_byte(dev->iobase + STATUS2_REG);
- if (devpriv->status2_bits & EEPROM_OUT_BIT) {
+ if (devpriv->status2_bits & EEPROM_OUT_BIT)
value |= 1 << (value_width - i);
- }
}
return value;
@@ -1876,8 +1935,10 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
unsigned int address)
{
unsigned int value;
- const int read_instruction = 0x3; /* bits to tell eeprom to expect a read */
- const int write_length = 8; /* 8 bit write lengths to eeprom */
+ /* bits to tell eeprom to expect a read */
+ const int read_instruction = 0x3;
+ /* 8 bit write lengths to eeprom */
+ const int write_length = 8;
/* enable read/write to eeprom */
devpriv->command5_bits &= ~EEPROM_EN_BIT;
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index 0b963bb3328..8ad1055a5cc 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -64,6 +64,7 @@ NI manuals:
#include "../comedidev.h"
#include <linux/delay.h>
+#include <linux/slab.h>
#include "8253.h"
#include "8255.h"
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index d6d49c3bbf1..bd16f913af2 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -3795,7 +3795,7 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
#endif
int retval = 0;
unsigned i;
- const unsigned timeout = 100;
+ const unsigned timeout = 1000;
s->async->inttrig = NULL;
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 2d88a5be65f..9d337516409 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -1,8 +1,8 @@
/*
comedi/drivers/ni_pcidio.c
driver for National Instruments PCI-DIO-96/PCI-6508
- National Instruments PCI-DIO-32HS
- National Instruments PCI-6503
+ National Instruments PCI-DIO-32HS
+ National Instruments PCI-6503
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
@@ -518,7 +518,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
ni_pcidio_print_status(status);
/* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */
- /* printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096)); */
+ /* printk("buf[4096]=%08x\n",
+ *(unsigned int *)(async->prealloc_buf+4096)); */
spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
if (devpriv->di_mite_chan)
@@ -526,7 +527,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
#ifdef MITE_DEBUG
mite_print_chsr(m_status);
#endif
- /* printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN)); */
+ /* printk("mite_bytes_transferred: %d\n",
+ mite_bytes_transferred(mite,DI_DMA_CHAN)); */
+
/* mite_dump_regs(mite); */
if (m_status & CHSR_INT) {
if (m_status & CHSR_LINKC) {
@@ -565,7 +568,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
DPRINTK("too much work in interrupt\n");
writeb(0x00,
devpriv->mite->daq_io_addr +
- Master_DMA_And_Interrupt_Control);
+ Master_DMA_And_Interrupt_Control
+ );
goto out;
}
AuxData =
@@ -579,8 +583,10 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
flags = readb(devpriv->mite->daq_io_addr +
Group_1_Flags);
}
- /* DPRINTK("buf_int_count: %d\n",async->buf_int_count); */
- /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status); */
+ /* DPRINTK("buf_int_count: %d\n",
+ async->buf_int_count); */
+ /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",
+ IntEn,flags,status); */
/* ni_pcidio_print_flags(flags); */
/* ni_pcidio_print_status(status); */
async->events |= COMEDI_CB_BLOCK;
@@ -627,8 +633,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
status = readb(devpriv->mite->daq_io_addr +
Interrupt_And_Window_Status);
- /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n", */
- /* IntEn,flags,status); */
+ /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,"
+ "status=0x%02x\n", IntEn, flags, status); */
/* ni_pcidio_print_flags(flags); */
/* ni_pcidio_print_status(status); */
}
@@ -655,11 +661,10 @@ static void ni_pcidio_print_flags(unsigned int flags)
{
int i;
- printk("group_1_flags:");
+ printk(KERN_INFO "group_1_flags:");
for (i = 7; i >= 0; i--) {
- if (flags & (1 << i)) {
+ if (flags & (1 << i))
printk(" %s", flags_strings[i]);
- }
}
printk("\n");
}
@@ -673,11 +678,10 @@ static void ni_pcidio_print_status(unsigned int flags)
{
int i;
- printk("group_status:");
+ printk(KERN_INFO "group_status:");
for (i = 7; i >= 0; i--) {
- if (flags & (1 << i)) {
+ if (flags & (1 << i))
printk(" %s", status_strings[i]);
- }
}
printk("\n");
}
@@ -793,7 +797,8 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
if (err)
return 1;
- /* step 2: make sure trigger sources are unique and mutually compatible */
+ /* step 2: make sure trigger sources are unique and mutually
+ compatible */
/* note that mutual compatibility is not an issue here */
if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
@@ -974,7 +979,8 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* clear and enable interrupts */
writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
- /* writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
+ /* writeb(ClearExpired,
+ devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
writeb(0x03,
@@ -1052,7 +1058,7 @@ static int ni_pcidio_change(struct comedi_device *dev,
}
static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
- u8 * data, int data_len)
+ u8 *data, int data_len)
{
static const int timeout = 1000;
int i, j;
@@ -1066,9 +1072,8 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
udelay(1);
}
if (i == timeout) {
- printk
- ("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n",
- fpga_index);
+ printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
+ "waiting for status 0x2\n", fpga_index);
return -EIO;
}
writew(0x80 | fpga_index,
@@ -1079,9 +1084,8 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
udelay(1);
}
if (i == timeout) {
- printk
- ("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n",
- fpga_index);
+ printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
+ "waiting for status 0x3\n", fpga_index);
return -EIO;
}
for (j = 0; j + 1 < data_len;) {
@@ -1174,9 +1178,10 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int n_subdevices;
unsigned int irq;
- printk("comedi%d: nidio:", dev->minor);
+ printk(KERN_INFO "comedi%d: nidio:", dev->minor);
- if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0)
+ ret = alloc_private(dev, sizeof(struct nidio96_private));
+ if (ret < 0)
return ret;
spin_lock_init(&devpriv->mite_channel_lock);
@@ -1186,7 +1191,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
ret = mite_setup(devpriv->mite);
if (ret < 0) {
- printk("error setting up mite\n");
+ printk(KERN_WARNING "error setting up mite\n");
return ret;
}
comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
@@ -1196,18 +1201,19 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->board_name = this_board->name;
irq = mite_irq(devpriv->mite);
- printk(" %s", dev->board_name);
+ printk(KERN_INFO " %s", dev->board_name);
if (this_board->uses_firmware) {
ret = pci_6534_upload_firmware(dev, it->options);
if (ret < 0)
return ret;
}
- if (!this_board->is_diodaq) {
+ if (!this_board->is_diodaq)
n_subdevices = this_board->n_8255;
- } else {
+ else
n_subdevices = 1;
- }
- if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+
+ ret = alloc_subdevices(dev, n_subdevices);
+ if (ret < 0)
return ret;
if (!this_board->is_diodaq) {
@@ -1220,7 +1226,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
} else {
- printk(" rev=%d",
+ printk(KERN_INFO " rev=%d",
readb(devpriv->mite->daq_io_addr + Chip_Version));
s = dev->subdevices + 0;
@@ -1253,9 +1259,9 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
"ni_pcidio", dev);
- if (ret < 0) {
- printk(" irq not available");
- }
+ if (ret < 0)
+ printk(KERN_WARNING " irq not available");
+
dev->irq = irq;
}
@@ -1269,9 +1275,8 @@ static int nidio_detach(struct comedi_device *dev)
int i;
if (this_board && !this_board->is_diodaq) {
- for (i = 0; i < this_board->n_8255; i++) {
+ for (i = 0; i < this_board->n_8255; i++)
subdev_8255_cleanup(dev, dev->subdevices + i);
- }
}
if (dev->irq)
@@ -1310,7 +1315,7 @@ static int nidio_find_device(struct comedi_device *dev, int bus, int slot)
}
}
}
- printk("no device found\n");
+ printk(KERN_WARNING "no device found\n");
mite_list_devices();
return -EIO;
}
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index 4914784f699..a499f7070f7 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -207,11 +207,10 @@ static irqreturn_t pcl711_interrupt(int irq, void *d)
/* FIXME! Nothing else sets ntrig! */
if (!(--devpriv->ntrig)) {
- if (this_board->is_8112) {
+ if (this_board->is_8112)
outb(1, dev->iobase + PCL711_MODE);
- } else {
+ else
outb(0, dev->iobase + PCL711_MODE);
- }
s->async->events |= COMEDI_CB_EOA;
}
@@ -232,15 +231,15 @@ static void pcl711_set_changain(struct comedi_device *dev, int chan)
/*
* Set the correct channel. The two channel banks are switched
* using the mask value.
- * NB: To use differential channels, you should use mask = 0x30,
- * but I haven't written the support for this yet. /JJ
+ * NB: To use differential channels, you should use
+ * mask = 0x30, but I haven't written the support for this
+ * yet. /JJ
*/
- if (chan_register >= 8) {
+ if (chan_register >= 8)
chan_register = 0x20 | (chan_register & 0x7);
- } else {
+ else
chan_register |= 0x10;
- }
} else {
outb(chan_register, dev->iobase + PCL711_MUX);
}
@@ -256,15 +255,13 @@ static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
for (n = 0; n < insn->n; n++) {
/*
- * Write the correct mode (software polling) and start polling by writing
- * to the trigger register
+ * Write the correct mode (software polling) and start polling
+ * by writing to the trigger register
*/
outb(1, dev->iobase + PCL711_MODE);
- if (this_board->is_8112) {
- } else {
+ if (!this_board->is_8112)
outb(0, dev->iobase + PCL711_SOFTTRIG);
- }
i = PCL711_TIMEOUT;
while (--i) {
@@ -462,9 +459,8 @@ static int pcl711_ao_insn_read(struct comedi_device *dev,
int n;
int chan = CR_CHAN(insn->chanspec);
- for (n = 0; n < insn->n; n++) {
+ for (n = 0; n < insn->n; n++)
data[n] = devpriv->ao_readback[chan];
- }
return n;
@@ -619,9 +615,8 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
this is the "base value" for the mode register, which is
used for the irq on the PCL711
*/
- if (this_board->is_pcl711b) {
+ if (this_board->is_pcl711b)
devpriv->mode = (dev->irq << 4);
- }
/* clear DAC */
outb(0, dev->iobase + PCL711_DA0_LO);
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
index df1f4ef1461..0f103c32806 100644
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -17,7 +17,7 @@
[0] - IO Base
[1] - IRQ (0=disable IRQ) IRQ isn't supported at this time!
[2] -number of DIO:
- 0, 144: 144 DIO configuration
+ 0, 144: 144 DIO configuration
1, 96: 96 DIO configuration
*/
/*
@@ -137,8 +137,8 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
iorange = this_board->io_range;
if ((this_board->can_have96) && ((it->options[1] == 1)
|| (it->options[1] == 96)))
- iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */
- printk("comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
+ iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */
+ printk(KERN_INFO "comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
this_board->name, iobase);
if (!request_region(iobase, iorange, "pcl724")) {
printk("I/O port conflict\n");
@@ -155,16 +155,16 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
irq = it->options[1];
if (irq) { /* we want to use IRQ */
if (((1 << irq) & this_board->IRQbits) == 0) {
- printk
- (", IRQ %u is out of allowed range, DISABLING IT",
- irq);
+ printk(KERN_WARNING
+ ", IRQ %u is out of allowed range, "
+ "DISABLING IT", irq);
irq = 0; /* Bad IRQ */
} else {
if (request_irq
(irq, interrupt_pcl724, 0, "pcl724", dev)) {
- printk
- (", unable to allocate IRQ %u, DISABLING IT",
- irq);
+ printk(KERN_WARNING
+ ", unable to allocate IRQ %u, "
+ "DISABLING IT", irq);
irq = 0; /* Can't use IRQ */
} else {
printk(", irq=%u", irq);
@@ -207,16 +207,14 @@ static int pcl724_detach(struct comedi_device *dev)
{
int i;
-/* printk("comedi%d: pcl724: remove\n",dev->minor); */
+ /* printk("comedi%d: pcl724: remove\n",dev->minor); */
- for (i = 0; i < dev->n_subdevices; i++) {
+ for (i = 0; i < dev->n_subdevices; i++)
subdev_8255_cleanup(dev, dev->subdevices + i);
- }
#ifdef PCL724_IRQ
- if (dev->irq) {
+ if (dev->irq)
free_irq(dev->irq, dev);
- }
#endif
release_region(dev->iobase, this_board->io_range);
diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c
index 1da4941fce4..60261f4ba5b 100644
--- a/drivers/staging/comedi/drivers/pcl725.c
+++ b/drivers/staging/comedi/drivers/pcl725.c
@@ -66,7 +66,7 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned long iobase;
iobase = it->options[0];
- printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
+ printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
if (!request_region(iobase, PCL725_SIZE, "pcl725")) {
printk("I/O port conflict\n");
return -EIO;
@@ -96,14 +96,14 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->insn_bits = pcl725_di_insn;
s->range_table = &range_digital;
- printk("\n");
+ printk(KERN_INFO "\n");
return 0;
}
static int pcl725_detach(struct comedi_device *dev)
{
- printk("comedi%d: pcl725: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: pcl725: remove\n", dev->minor);
if (dev->iobase)
release_region(dev->iobase, PCL725_SIZE);
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
index c9859c90c15..e5e7bed21de 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -99,7 +99,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
iobase = it->options[0];
iorange = this_board->io_range;
- printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
+ printk(KERN_INFO "comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
this_board->name, iobase);
if (!request_region(iobase, iorange, "pcl730")) {
printk("I/O port conflict\n");
@@ -152,14 +152,14 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->range_table = &range_digital;
s->private = (void *)PCL730_DIO_LO;
- printk("\n");
+ printk(KERN_INFO "\n");
return 0;
}
static int pcl730_detach(struct comedi_device *dev)
{
- printk("comedi%d: pcl730: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: pcl730: remove\n", dev->minor);
if (dev->iobase)
release_region(dev->iobase, this_board->io_range);
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index 0a5bc3d6da8..1ddc19c705a 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -108,6 +108,7 @@ Options for ACL-8113, ISO-813:
*/
#include <linux/interrupt.h>
+#include <linux/gfp.h>
#include "../comedidev.h"
#include <linux/delay.h>
@@ -955,6 +956,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
unsigned int mask, timeout;
struct comedi_device *dev = d;
struct comedi_subdevice *s = dev->subdevices + 0;
+ unsigned int next_chan;
s->async->events = 0;
@@ -993,9 +995,18 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
((inb(dev->iobase + PCL812_AD_HI) << 8) |
inb(dev->iobase + PCL812_AD_LO)) & mask);
+ /* Set up next channel. Added by abbotti 2010-01-20, but untested. */
+ next_chan = s->async->cur_chan + 1;
+ if (next_chan >= devpriv->ai_n_chan)
+ next_chan = 0;
+ if (devpriv->ai_chanlist[s->async->cur_chan] !=
+ devpriv->ai_chanlist[next_chan])
+ setup_range_channel(dev, s, devpriv->ai_chanlist[next_chan], 0);
+
outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
- if (s->async->cur_chan == 0) { /* one scan done */
+ s->async->cur_chan = next_chan;
+ if (next_chan == 0) { /* one scan done */
devpriv->ai_act_scan++;
if (!(devpriv->ai_neverending))
if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
@@ -1021,7 +1032,9 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
for (i = len; i; i--) {
comedi_buf_put(s->async, ptr[bufptr++]); /* get one sample */
- if (s->async->cur_chan == 0) {
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
devpriv->ai_act_scan++;
if (!devpriv->ai_neverending)
if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 852fe2458fd..71c2a3aa379 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -36,6 +36,7 @@ Configuration Options:
#include <linux/ioport.h>
#include <linux/mc146818rtc.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <asm/dma.h>
@@ -202,6 +203,7 @@ struct pcl816_private {
unsigned int ai_act_chanlist[16]; /* MUX setting for actual AI operations */
unsigned int ai_act_chanlist_len; /* how long is actual MUX list */
unsigned int ai_act_chanlist_pos; /* actual position in MUX list */
+ unsigned int ai_n_chan; /* how many channels per scan */
unsigned int ai_poll_ptr; /* how many sampes transfer poll */
struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */
#ifdef unused
@@ -213,9 +215,12 @@ struct pcl816_private {
/*
==============================================================================
*/
-static int check_and_setup_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chanlist, int chanlen);
+static int check_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int *chanlist, unsigned int chanlen);
+static void setup_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int *chanlist, unsigned int seglen);
static int pcl816_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s);
static void start_pacer(struct comedi_device *dev, int mode,
@@ -320,7 +325,9 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len)
devpriv->ai_act_chanlist_pos = 0;
- if (s->async->cur_chan == 0) {
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
devpriv->ai_act_scan++;
}
@@ -353,6 +360,11 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
if (++devpriv->ai_act_chanlist_pos >=
devpriv->ai_act_chanlist_len) {
devpriv->ai_act_chanlist_pos = 0;
+ }
+
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
devpriv->ai_act_scan++;
}
@@ -558,14 +570,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
}
}
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->chanlist_len > this_board->n_aichan) {
- cmd->chanlist_len = this_board->n_aichan;
- err++;
- }
if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len;
err++;
@@ -603,6 +607,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
return 4;
}
+ /* step 5: complain about special chanlist considerations */
+
+ if (cmd->chanlist) {
+ if (!check_channel_list(dev, s, cmd->chanlist,
+ cmd->chanlist_len))
+ return 5; /* incorrect channels list */
+ }
+
return 0;
}
@@ -610,6 +622,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int seglen;
if (cmd->start_src != TRIG_NOW)
return -EINVAL;
@@ -642,11 +655,13 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
start_pacer(dev, -1, 0, 0); /* stop pacer */
- if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
- cmd->chanlist_len))
+ seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
+ if (seglen < 1)
return -EINVAL;
+ setup_channel_list(dev, s, cmd->chanlist, seglen);
udelay(1);
+ devpriv->ai_n_chan = cmd->chanlist_len;
devpriv->ai_act_scan = 0;
s->async->cur_chan = 0;
devpriv->irq_blocked = 1;
@@ -871,12 +886,12 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
/*
==============================================================================
Check if channel list from user is builded correctly
- If it's ok, then program scan/gain logic
+ If it's ok, then return non-zero length of repeated segment of channel list
*/
static int
-check_and_setup_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int *chanlist,
- int chanlen)
+check_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int *chanlist,
+ unsigned int chanlen)
{
unsigned int chansegment[16];
unsigned int i, nowmustbechan, seglen, segpos;
@@ -930,6 +945,20 @@ check_and_setup_channel_list(struct comedi_device *dev,
seglen = 1;
}
+ return seglen; /* we can serve this with MUX logic */
+}
+
+/*
+==============================================================================
+ Program scan/gain logic with channel list.
+*/
+static void
+setup_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int *chanlist,
+ unsigned int seglen)
+{
+ unsigned int i;
+
devpriv->ai_act_chanlist_len = seglen;
devpriv->ai_act_chanlist_pos = 0;
@@ -942,8 +971,6 @@ check_and_setup_channel_list(struct comedi_device *dev,
udelay(1);
outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */
-
- return 1; /* we can serve this with MUX logic */
}
#ifdef unused
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index d0481013a83..9d6aa393ef1 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -102,6 +102,7 @@ A word or two about DMA. Driver support DMA operations at two ways:
#include <linux/ioport.h>
#include <linux/mc146818rtc.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
#include <asm/dma.h>
@@ -557,8 +558,14 @@ conv_finish:
comedi_event(dev, s);
return IRQ_HANDLED;
}
- if (s->async->cur_chan == 0) {
+ devpriv->act_chanlist_pos++;
+ if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+ devpriv->act_chanlist_pos = 0;
+ }
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
/* printk("E"); */
+ s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}
@@ -627,9 +634,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
devpriv->act_chanlist_pos++;
if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
- devpriv->ai_act_scan--;
devpriv->act_chanlist_pos = 0;
}
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
+ devpriv->ai_act_scan--;
+ }
if (!devpriv->neverending_ai)
if (devpriv->ai_act_scan == 0) { /* all data sampled */
@@ -717,7 +728,14 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); /* get one sample */
bufptr &= (devpriv->dmasamplsize - 1);
- if (s->async->cur_chan == 0) {
+ devpriv->act_chanlist_pos++;
+ if (devpriv->act_chanlist_pos >=
+ devpriv->act_chanlist_len) {
+ devpriv->act_chanlist_pos = 0;
+ }
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}
@@ -796,7 +814,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); /* get one sample */
- if (s->async->cur_chan == 0) {
+ devpriv->act_chanlist_pos++;
+ if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+ devpriv->act_chanlist_pos = 0;
+ }
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}
@@ -1369,14 +1393,6 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
}
}
- if (!cmd->chanlist_len) {
- cmd->chanlist_len = 1;
- err++;
- }
- if (cmd->chanlist_len > s->n_chan) {
- cmd->chanlist_len = s->n_chan;
- err++;
- }
if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len;
err++;
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
index 52811824b05..ed610307923 100644
--- a/drivers/staging/comedi/drivers/pcm3724.c
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -121,25 +121,22 @@ static int compute_buffer(int config, int devno, struct comedi_subdevice *s)
{
/* 1 in io_bits indicates output */
if (s->io_bits & 0x0000ff) {
- if (devno == 0) {
+ if (devno == 0)
config |= BUF_A0;
- } else {
+ else
config |= BUF_A1;
- }
}
if (s->io_bits & 0x00ff00) {
- if (devno == 0) {
+ if (devno == 0)
config |= BUF_B0;
- } else {
+ else
config |= BUF_B1;
- }
}
if (s->io_bits & 0xff0000) {
- if (devno == 0) {
+ if (devno == 0)
config |= BUF_C0;
- } else {
+ else
config |= BUF_C1;
- }
}
return config;
}
@@ -155,26 +152,27 @@ static void do_3724_config(struct comedi_device *dev,
buffer_config = 0;
/* 1 in io_bits indicates output, 1 in config indicates input */
- if (!(s->io_bits & 0x0000ff)) {
+ if (!(s->io_bits & 0x0000ff))
config |= CR_A_IO;
- }
- if (!(s->io_bits & 0x00ff00)) {
+
+ if (!(s->io_bits & 0x00ff00))
config |= CR_B_IO;
- }
- if (!(s->io_bits & 0xff0000)) {
+
+ if (!(s->io_bits & 0xff0000))
config |= CR_C_IO;
- }
buffer_config = compute_buffer(0, 0, dev->subdevices);
buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1);
- if (s == dev->subdevices) {
+ if (s == dev->subdevices)
port_8255_cfg = dev->iobase + _8255_CR;
- } else {
+ else
port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR;
- }
+
outb(buffer_config, dev->iobase + 8); /* update buffer register */
- /* printk("pcm3724 buffer_config (%lx) %d, %x\n", dev->iobase + _8255_CR, chanspec, buffer_config); */
+ /* printk("pcm3724 buffer_config (%lx) %d, %x\n",
+ dev->iobase + _8255_CR, chanspec, buffer_config); */
+
outb(config, port_8255_cfg);
}
@@ -189,29 +187,29 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s,
priv = (struct priv_pcm3724 *)(dev->private);
mask = 1 << CR_CHAN(chanspec);
- if (s == dev->subdevices) { /* subdev 0 */
+ if (s == dev->subdevices) /* subdev 0 */
priv->dio_1 |= mask;
- } else { /* subdev 1 */
+ else /* subdev 1 */
priv->dio_2 |= mask;
- }
- if (priv->dio_1 & 0xff0000) {
+
+ if (priv->dio_1 & 0xff0000)
gatecfg |= GATE_C0;
- }
- if (priv->dio_1 & 0xff00) {
+
+ if (priv->dio_1 & 0xff00)
gatecfg |= GATE_B0;
- }
- if (priv->dio_1 & 0xff) {
+
+ if (priv->dio_1 & 0xff)
gatecfg |= GATE_A0;
- }
- if (priv->dio_2 & 0xff0000) {
+
+ if (priv->dio_2 & 0xff0000)
gatecfg |= GATE_C1;
- }
- if (priv->dio_2 & 0xff00) {
+
+ if (priv->dio_2 & 0xff00)
gatecfg |= GATE_B1;
- }
- if (priv->dio_2 & 0xff) {
+
+ if (priv->dio_2 & 0xff)
gatecfg |= GATE_A1;
- }
+
/* printk("gate control %x\n", gatecfg); */
outb(gatecfg, dev->iobase + 9);
}
@@ -225,15 +223,14 @@ static int subdev_3724_insn_config(struct comedi_device *dev,
unsigned int bits;
mask = 1 << CR_CHAN(insn->chanspec);
- if (mask & 0x0000ff) {
+ if (mask & 0x0000ff)
bits = 0x0000ff;
- } else if (mask & 0x00ff00) {
+ else if (mask & 0x00ff00)
bits = 0x00ff00;
- } else if (mask & 0x0f0000) {
+ else if (mask & 0x0f0000)
bits = 0x0f0000;
- } else {
+ else
bits = 0xf00000;
- }
switch (data[0]) {
case INSN_CONFIG_DIO_INPUT:
@@ -272,7 +269,7 @@ static int pcm3724_attach(struct comedi_device *dev,
((struct priv_pcm3724 *)(dev->private))->dio_1 = 0;
((struct priv_pcm3724 *)(dev->private))->dio_2 = 0;
- printk("comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
+ printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
this_board->name, iobase);
if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
printk("I/O port conflict\n");
@@ -281,7 +278,7 @@ static int pcm3724_attach(struct comedi_device *dev,
dev->iobase = iobase;
dev->board_name = this_board->name;
- printk("\n");
+ printk(KERN_INFO "\n");
n_subdevices = this_board->numofports;
@@ -302,13 +299,11 @@ static int pcm3724_detach(struct comedi_device *dev)
int i;
if (dev->subdevices) {
- for (i = 0; i < dev->n_subdevices; i++) {
+ for (i = 0; i < dev->n_subdevices; i++)
subdev_8255_cleanup(dev, dev->subdevices + i);
- }
}
- if (dev->iobase) {
+ if (dev->iobase)
release_region(dev->iobase, this_board->io_range);
- }
return 0;
}
diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c
index 9e4adbd89dd..22b7aae63ad 100644
--- a/drivers/staging/comedi/drivers/pcm3730.c
+++ b/drivers/staging/comedi/drivers/pcm3730.c
@@ -73,7 +73,7 @@ static int pcm3730_attach(struct comedi_device *dev,
unsigned long iobase;
iobase = it->options[0];
- printk("comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
+ printk(KERN_INFO "comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
printk("I/O port conflict\n");
return -EIO;
@@ -140,14 +140,14 @@ static int pcm3730_attach(struct comedi_device *dev,
s->range_table = &range_digital;
s->private = (void *)PCM3730_DIC;
- printk("\n");
+ printk(KERN_INFO "\n");
return 0;
}
static int pcm3730_detach(struct comedi_device *dev)
{
- printk("comedi%d: pcm3730: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: pcm3730: remove\n", dev->minor);
if (dev->iobase)
release_region(dev->iobase, PCM3730_SIZE);
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
index acac6709081..fab8092bd7a 100644
--- a/drivers/staging/comedi/drivers/pcmad.c
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -34,11 +34,11 @@ Configuration options:
[0] - I/O port base
[1] - unused
[2] - Analog input reference
- 0 = single ended
- 1 = differential
+ 0 = single ended
+ 1 = differential
[3] - Analog input encoding (must match jumpers)
- 0 = straight binary
- 1 = two's complement
+ 0 = straight binary
+ 1 = two's complement
*/
#include <linux/interrupt.h>
@@ -113,9 +113,8 @@ static int pcmad_ai_insn_read(struct comedi_device *dev,
data[n] = inb(dev->iobase + PCMAD_LSB);
data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8);
- if (devpriv->twos_comp) {
+ if (devpriv->twos_comp)
data[n] ^= (1 << (this_board->n_ai_bits - 1));
- }
}
return n;
@@ -135,11 +134,12 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned long iobase;
iobase = it->options[0];
- printk("comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
+ printk(KERN_INFO "comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
if (!request_region(iobase, PCMAD_SIZE, "pcmad")) {
- printk("I/O port conflict\n");
+ printk(KERN_CONT "I/O port conflict\n");
return -EIO;
}
+ printk(KERN_CONT "\n");
dev->iobase = iobase;
ret = alloc_subdevices(dev, 1);
@@ -166,11 +166,11 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static int pcmad_detach(struct comedi_device *dev)
{
- printk("comedi%d: pcmad: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: pcmad: remove\n", dev->minor);
- if (dev->irq) {
+ if (dev->irq)
free_irq(dev->irq, dev);
- }
+
if (dev->iobase)
release_region(dev->iobase, PCMAD_SIZE);
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index 35ba93989a3..025a52e8981 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -77,6 +77,7 @@ Configuration Options:
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include "pcm_common.h"
#include <linux/pci.h> /* for PCI devices */
@@ -550,7 +551,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (irq[0]) {
printk("irq: %u ", irq[0]);
- if (irq[1] && thisboard->dio_num_asics == 2)
+ if (thisboard->dio_num_asics == 2 && irq[1])
printk("second ASIC irq: %u ", irq[1]);
} else {
printk("(IRQ mode disabled) ");
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index c1ae20ffb37..5af4c8448a3 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -76,6 +76,7 @@ Configuration Options:
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
#include "pcm_common.h"
diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c
index d23e588d063..1ebc356ce40 100644
--- a/drivers/staging/comedi/drivers/poc.c
+++ b/drivers/staging/comedi/drivers/poc.c
@@ -122,22 +122,21 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned int iosize;
iobase = it->options[0];
- printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
+ printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
this_board->name, iobase);
dev->board_name = this_board->name;
if (iobase == 0) {
- printk("io base address required\n");
+ printk(KERN_ERR "io base address required\n");
return -EINVAL;
}
iosize = this_board->iosize;
/* check if io addresses are available */
if (!request_region(iobase, iosize, "dac02")) {
- printk
- ("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
- iobase, iobase + iosize - 1);
+ printk(KERN_ERR "I/O port conflict: failed to allocate ports "
+ "0x%lx to 0x%lx\n", iobase, iobase + iosize - 1);
return -EIO;
}
dev->iobase = iobase;
@@ -156,9 +155,8 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->insn_write = this_board->winsn;
s->insn_read = this_board->rinsn;
s->insn_bits = this_board->insnbits;
- if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) {
+ if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO)
s->subdev_flags = SDF_WRITABLE;
- }
return 0;
}
@@ -169,7 +167,7 @@ static int poc_detach(struct comedi_device *dev)
if (dev->iobase)
release_region(dev->iobase, this_board->iosize);
- printk("comedi%d: dac02: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: dac02: remove\n", dev->minor);
return 0;
}
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index 2c9d05bd288..028ed6f89c4 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -32,22 +32,22 @@ Configuration options:
[0] - I/O port base address
[1] - IRQ
[2] - A/D reference
- 0 = differential
- 1 = pseudodifferential (common)
- 2 = single-ended
+ 0 = differential
+ 1 = pseudodifferential (common)
+ 2 = single-ended
[3] - A/D range
- 0 = [-10,10]
- 1 = [-5,5]
- 2 = [0,10]
+ 0 = [-10,10]
+ 1 = [-5,5]
+ 2 = [0,10]
[4] - A/D encoding
- 0 = two's complement
- 1 = straight binary
+ 0 = two's complement
+ 1 = straight binary
[5] - DAC 0 range
- 0 = [-10,10]
- 1 = [0,10]
+ 0 = [-10,10]
+ 1 = [0,10]
[6] - DAC 0 encoding
- 0 = two's complement
- 1 = straight binary
+ 0 = two's complement
+ 1 = straight binary
[7] - DAC 1 range (same as DAC 0)
[8] - DAC 1 encoding (same as DAC 0)
*/
@@ -225,7 +225,7 @@ static int rti800_ai_insn_read(struct comedi_device *dev,
for (t = RTI800_TIMEOUT; t; t--) {
status = inb(dev->iobase + RTI800_CSR);
if (status & RTI800_OVERRUN) {
- printk("rti800: a/d overrun\n");
+ printk(KERN_WARNING "rti800: a/d overrun\n");
outb(0, dev->iobase + RTI800_CLRFLAGS);
return -EIO;
}
@@ -234,15 +234,14 @@ static int rti800_ai_insn_read(struct comedi_device *dev,
udelay(1);
}
if (t == 0) {
- printk("rti800: timeout\n");
+ printk(KERN_WARNING "rti800: timeout\n");
return -ETIME;
}
data[i] = inb(dev->iobase + RTI800_ADCLO);
data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8;
- if (devpriv->adc_coding == adc_2comp) {
+ if (devpriv->adc_coding == adc_2comp)
data[i] ^= 0x800;
- }
}
return i;
@@ -271,9 +270,9 @@ static int rti800_ao_insn_write(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
devpriv->ao_readback[chan] = d = data[i];
- if (devpriv->dac0_coding == dac_2comp) {
+ if (devpriv->dac0_coding == dac_2comp)
d ^= 0x800;
- }
+
outb(d & 0xff,
dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
outb(d >> 8,
@@ -315,15 +314,15 @@ static int rti800_do_insn_bits(struct comedi_device *dev,
options[0] - I/O port
options[1] - irq
options[2] - a/d mux
- 0=differential, 1=pseudodiff, 2=single
+ 0=differential, 1=pseudodiff, 2=single
options[3] - a/d range
- 0=bipolar10, 1=bipolar5, 2=unipolar10
+ 0=bipolar10, 1=bipolar5, 2=unipolar10
options[4] - a/d coding
- 0=2's comp, 1=straight binary
+ 0=2's comp, 1=straight binary
options[5] - dac0 range
- 0=bipolar10, 1=unipolar10
+ 0=bipolar10, 1=unipolar10
options[6] - dac0 coding
- 0=2's comp, 1=straight binary
+ 0=2's comp, 1=straight binary
options[7] - dac1 range
options[8] - dac1 coding
*/
@@ -336,15 +335,15 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
iobase = it->options[0];
- printk("comedi%d: rti800: 0x%04lx ", dev->minor, iobase);
+ printk(KERN_INFO "comedi%d: rti800: 0x%04lx\n", dev->minor, iobase);
if (!request_region(iobase, RTI800_SIZE, "rti800")) {
- printk("I/O port conflict\n");
+ printk(KERN_WARNING "I/O port conflict\n");
return -EIO;
}
dev->iobase = iobase;
#ifdef DEBUG
- printk("fingerprint=%x,%x,%x,%x,%x ",
+ printk(KERN_DEBUG "fingerprint=%x,%x,%x,%x,%x ",
inb(dev->iobase + 0),
inb(dev->iobase + 1),
inb(dev->iobase + 2),
@@ -357,15 +356,15 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
irq = it->options[1];
if (irq) {
- printk("( irq = %u )", irq);
+ printk(KERN_INFO "( irq = %u )\n", irq);
ret = request_irq(irq, rti800_interrupt, 0, "rti800", dev);
if (ret < 0) {
- printk(" Failed to allocate IRQ\n");
+ printk(KERN_WARNING " Failed to allocate IRQ\n");
return ret;
}
dev->irq = irq;
} else {
- printk("( no irq )");
+ printk(KERN_INFO "( no irq )\n");
}
dev->board_name = this_board->name;
@@ -461,14 +460,12 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->type = COMEDI_SUBD_TIMER;
#endif
- printk("\n");
-
return 0;
}
static int rti800_detach(struct comedi_device *dev)
{
- printk("comedi%d: rti800: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: rti800: remove\n", dev->minor);
if (dev->iobase)
release_region(dev->iobase, RTI800_SIZE);
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
index 2f75c737ea1..2157edcf799 100644
--- a/drivers/staging/comedi/drivers/rti802.c
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -106,9 +106,9 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned long iobase;
iobase = it->options[0];
- printk("comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
+ printk(KERN_INFO "comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
if (!request_region(iobase, RTI802_SIZE, "rti802")) {
- printk("I/O port conflict\n");
+ printk(KERN_WARNING "I/O port conflict\n");
return -EIO;
}
dev->iobase = iobase;
@@ -138,14 +138,12 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
? &range_unipolar10 : &range_bipolar10;
}
- printk("\n");
-
return 0;
}
static int rti802_detach(struct comedi_device *dev)
{
- printk("comedi%d: rti802: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: rti802: remove\n", dev->minor);
if (dev->iobase)
release_region(dev->iobase, RTI802_SIZE);
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index fdd7ab954d8..a3cc93362ec 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -140,7 +140,7 @@ struct s626_private {
short allocatedBuf;
uint8_t ai_cmd_running; /* ai_cmd is running */
uint8_t ai_continous; /* continous aquisition */
- int ai_sample_count; /* number of samples to aquire */
+ int ai_sample_count; /* number of samples to acquire */
unsigned int ai_sample_timer;
/* time between samples in units of the timer */
int ai_convert_count; /* conversion counter */
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index db37dcdd98b..0792617ebc3 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -36,6 +36,7 @@ Status: in development
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/termios.h>
#include <asm/ioctls.h>
@@ -397,7 +398,7 @@ static void serial_2002_open(struct comedi_device *dev)
char port[20];
sprintf(port, "/dev/ttyS%d", devpriv->port);
- devpriv->tty = filp_open(port, 0, O_RDWR);
+ devpriv->tty = filp_open(port, O_RDWR, 0);
if (IS_ERR(devpriv->tty)) {
printk("serial_2002: file open error = %ld\n",
PTR_ERR(devpriv->tty));
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
index 4918fbfab5e..17c92a57b0d 100644
--- a/drivers/staging/comedi/drivers/ssv_dnp.c
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -300,11 +300,11 @@ static int dnp_dio_insn_config(struct comedi_device *dev,
/* read 'old' direction of the port and set bits (out=1, in=0) */
register_buffer = inb(CSCDR);
- if (data[0] == COMEDI_OUTPUT) {
+ if (data[0] == COMEDI_OUTPUT)
register_buffer |= (1 << chan);
- } else {
+ else
register_buffer &= ~(1 << chan);
- }
+
outb(register_buffer, CSCDR);
return 1;
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
index 75a9a62e1a7..be1d83df0de 100644
--- a/drivers/staging/comedi/drivers/unioxx5.c
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -44,6 +44,7 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5),
#include "../comedidev.h"
#include <linux/ioport.h>
+#include <linux/slab.h>
#define DRIVER_NAME "unioxx5"
#define UNIOXX5_SIZE 0x10
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 9a1b559c4b0..8942ae45708 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -95,7 +95,6 @@ sampling rate. If you sample two channels you get 4kHz and so on.
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/fcntl.h>
#include <linux/compiler.h>
#include <linux/firmware.h>
@@ -289,7 +288,7 @@ struct usbduxsub {
/* continous aquisition */
short int ai_continous;
short int ao_continous;
- /* number of samples to aquire */
+ /* number of samples to acquire */
int ai_sample_count;
int ao_sample_count;
/* time between samples in units of the timer */
@@ -2833,7 +2832,7 @@ static struct comedi_driver driver_usbdux = {
};
/* Table with the USB-devices: just now only testing IDs */
-static struct usb_device_id usbduxsub_table[] = {
+static const struct usb_device_id usbduxsub_table[] = {
{USB_DEVICE(0x13d8, 0x0001)},
{USB_DEVICE(0x13d8, 0x0002)},
{} /* Terminating entry */
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 2e675cce7db..e89b8181253 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -44,7 +44,6 @@
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/fcntl.h>
#include <linux/compiler.h>
#include "comedi_fc.h"
@@ -182,7 +181,7 @@ struct usbduxfastsub_s {
context */
short int ai_cmd_running; /* asynchronous command is running */
short int ai_continous; /* continous aquisition */
- long int ai_sample_count; /* number of samples to aquire */
+ long int ai_sample_count; /* number of samples to acquire */
uint8_t *dux_commands; /* commands */
int ignore; /* counter which ignores the first
buffers */
@@ -1769,7 +1768,7 @@ static struct comedi_driver driver_usbduxfast = {
/*
* Table with the USB-devices: just now only testing IDs
*/
-static struct usb_device_id usbduxfastsub_table[] = {
+static const struct usb_device_id usbduxfastsub_table[] = {
/* { USB_DEVICE(0x4b4, 0x8613) }, testing */
{USB_DEVICE(0x13d8, 0x0010)}, /* real ID */
{USB_DEVICE(0x13d8, 0x0011)}, /* real ID */
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index c34a0b9141e..6479c38d027 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -75,7 +75,7 @@ enum {
DEVICE_VMK8061
};
-static struct usb_device_id vmk80xx_id_table[] = {
+static const struct usb_device_id vmk80xx_id_table[] = {
{USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055},
{USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055},
{USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055},
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 6552ef6d829..288fef4fcbc 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -31,7 +31,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <asm/io.h>
#include "../comedi.h"
diff --git a/drivers/staging/comedi/kcomedilib/ksyms.c b/drivers/staging/comedi/kcomedilib/ksyms.c
index 19293d1f998..8bf4471ce6c 100644
--- a/drivers/staging/comedi/kcomedilib/ksyms.c
+++ b/drivers/staging/comedi/kcomedilib/ksyms.c
@@ -34,7 +34,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/mm.h>
-#include <linux/slab.h>
/* functions specific to kcomedilib */
diff --git a/drivers/staging/crystalhd/Kconfig b/drivers/staging/crystalhd/Kconfig
new file mode 100644
index 00000000000..56b414bca1a
--- /dev/null
+++ b/drivers/staging/crystalhd/Kconfig
@@ -0,0 +1,6 @@
+config CRYSTALHD
+ tristate "Broadcom Crystal HD video decoder support"
+ depends on PCI
+ default n
+ help
+ Support for the Broadcom Crystal HD video decoder chipset
diff --git a/drivers/staging/crystalhd/Makefile b/drivers/staging/crystalhd/Makefile
new file mode 100644
index 00000000000..e2af0ce2e79
--- /dev/null
+++ b/drivers/staging/crystalhd/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_CRYSTALHD) += crystalhd.o
+
+crystalhd-objs := crystalhd_cmds.o \
+ crystalhd_hw.o \
+ crystalhd_lnx.o \
+ crystalhd_misc.o
diff --git a/drivers/staging/crystalhd/TODO b/drivers/staging/crystalhd/TODO
new file mode 100644
index 00000000000..69be5d0cb80
--- /dev/null
+++ b/drivers/staging/crystalhd/TODO
@@ -0,0 +1,16 @@
+- Testing
+- Cleanup return codes
+- Cleanup typedefs
+- Cleanup all WIN* references
+- Allocate an Accelerator device class specific Major number,
+ since we don't have any other open sourced accelerators, it is the only
+ one in that category for now.
+ A somewhat similar device is the DXR2/3
+
+Please send patches to:
+Greg Kroah-Hartman <greg@kroah.com>
+Naren Sankar <nsankar@broadcom.com>
+Jarod Wilson <jarod@wilsonet.com>
+Scott Davilla <davilla@4pi.com>
+Manu Abraham <abraham.manu@gmail.com>
+
diff --git a/drivers/staging/crystalhd/bc_dts_defs.h b/drivers/staging/crystalhd/bc_dts_defs.h
new file mode 100644
index 00000000000..c34cc07127b
--- /dev/null
+++ b/drivers/staging/crystalhd/bc_dts_defs.h
@@ -0,0 +1,498 @@
+/********************************************************************
+ * Copyright(c) 2006-2009 Broadcom Corporation.
+ *
+ * Name: bc_dts_defs.h
+ *
+ * Description: Common definitions for all components. Only types
+ * is allowed to be included from this file.
+ *
+ * AU
+ *
+ * HISTORY:
+ *
+ ********************************************************************
+ * This header is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 2.1 of the License.
+ *
+ * This header is distributed in 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 Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header. If not, see <http://www.gnu.org/licenses/>.
+ *******************************************************************/
+
+#ifndef _BC_DTS_DEFS_H_
+#define _BC_DTS_DEFS_H_
+
+#include "bc_dts_types.h"
+
+/* BIT Mask */
+#define BC_BIT(_x) (1 << (_x))
+
+typedef enum _BC_STATUS {
+ BC_STS_SUCCESS = 0,
+ BC_STS_INV_ARG = 1,
+ BC_STS_BUSY = 2,
+ BC_STS_NOT_IMPL = 3,
+ BC_STS_PGM_QUIT = 4,
+ BC_STS_NO_ACCESS = 5,
+ BC_STS_INSUFF_RES = 6,
+ BC_STS_IO_ERROR = 7,
+ BC_STS_NO_DATA = 8,
+ BC_STS_VER_MISMATCH = 9,
+ BC_STS_TIMEOUT = 10,
+ BC_STS_FW_CMD_ERR = 11,
+ BC_STS_DEC_NOT_OPEN = 12,
+ BC_STS_ERR_USAGE = 13,
+ BC_STS_IO_USER_ABORT = 14,
+ BC_STS_IO_XFR_ERROR = 15,
+ BC_STS_DEC_NOT_STARTED = 16,
+ BC_STS_FWHEX_NOT_FOUND = 17,
+ BC_STS_FMT_CHANGE = 18,
+ BC_STS_HIF_ACCESS = 19,
+ BC_STS_CMD_CANCELLED = 20,
+ BC_STS_FW_AUTH_FAILED = 21,
+ BC_STS_BOOTLOADER_FAILED = 22,
+ BC_STS_CERT_VERIFY_ERROR = 23,
+ BC_STS_DEC_EXIST_OPEN = 24,
+ BC_STS_PENDING = 25,
+ BC_STS_CLK_NOCHG = 26,
+
+ /* Must be the last one.*/
+ BC_STS_ERROR = -1
+} BC_STATUS;
+
+/*------------------------------------------------------*
+ * Registry Key Definitions *
+ *------------------------------------------------------*/
+#define BC_REG_KEY_MAIN_PATH "Software\\Broadcom\\MediaPC\\70010"
+#define BC_REG_KEY_FWPATH "FirmwareFilePath"
+#define BC_REG_KEY_SEC_OPT "DbgOptions"
+
+/*
+ * Options:
+ *
+ * b[5] = Enable RSA KEY in EEPROM Support
+ * b[6] = Enable Old PIB scheme. (0 = Use PIB with video scheme)
+ *
+ * b[12] = Enable send message to NotifyIcon
+ *
+ */
+
+typedef enum _BC_SW_OPTIONS {
+ BC_OPT_DOSER_OUT_ENCRYPT = BC_BIT(3),
+ BC_OPT_LINK_OUT_ENCRYPT = BC_BIT(29),
+} BC_SW_OPTIONS;
+
+typedef struct _BC_REG_CONFIG{
+ uint32_t DbgOptions;
+} BC_REG_CONFIG;
+
+#if defined(__KERNEL__) || defined(__LINUX_USER__)
+#else
+/* Align data structures */
+#define ALIGN(x) __declspec(align(x))
+#endif
+
+/* mode
+ * b[0]..b[7] = _DtsDeviceOpenMode
+ * b[8] = Load new FW
+ * b[9] = Load file play back FW
+ * b[10] = Disk format (0 for HD DVD and 1 for BLU ray)
+ * b[11]-b[15] = default output resolution
+ * b[16] = Skip TX CPB Buffer Check
+ * b[17] = Adaptive Output Encrypt/Scramble Scheme
+ * b[18]-b[31] = reserved for future use
+ */
+
+/* To allow multiple apps to open the device. */
+enum _DtsDeviceOpenMode {
+ DTS_PLAYBACK_MODE = 0,
+ DTS_DIAG_MODE,
+ DTS_MONITOR_MODE,
+ DTS_HWINIT_MODE
+};
+
+/* To enable the filter to selectively enable/disable fixes or erratas */
+enum _DtsDeviceFixMode {
+ DTS_LOAD_NEW_FW = BC_BIT(8),
+ DTS_LOAD_FILE_PLAY_FW = BC_BIT(9),
+ DTS_DISK_FMT_BD = BC_BIT(10),
+ /* b[11]-b[15] : Default output resolution */
+ DTS_SKIP_TX_CHK_CPB = BC_BIT(16),
+ DTS_ADAPTIVE_OUTPUT_PER = BC_BIT(17),
+ DTS_INTELLIMAP = BC_BIT(18),
+ /* b[19]-b[21] : select clock frequency */
+ DTS_PLAYBACK_DROP_RPT_MODE = BC_BIT(22)
+};
+
+#define DTS_DFLT_RESOLUTION(x) (x<<11)
+
+#define DTS_DFLT_CLOCK(x) (x<<19)
+
+/* F/W File Version corresponding to S/W Releases */
+enum _FW_FILE_VER {
+ /* S/W release: 02.04.02 F/W release 2.12.2.0 */
+ BC_FW_VER_020402 = ((12<<16) | (2<<8) | (0))
+};
+
+/*------------------------------------------------------*
+ * Stream Types for DtsOpenDecoder() *
+ *------------------------------------------------------*/
+enum _DtsOpenDecStreamTypes {
+ BC_STREAM_TYPE_ES = 0,
+ BC_STREAM_TYPE_PES = 1,
+ BC_STREAM_TYPE_TS = 2,
+ BC_STREAM_TYPE_ES_TSTAMP = 6,
+};
+
+/*------------------------------------------------------*
+ * Video Algorithms for DtsSetVideoParams() *
+ *------------------------------------------------------*/
+enum _DtsSetVideoParamsAlgo {
+ BC_VID_ALGO_H264 = 0,
+ BC_VID_ALGO_MPEG2 = 1,
+ BC_VID_ALGO_VC1 = 4,
+ BC_VID_ALGO_VC1MP = 7,
+};
+
+/*------------------------------------------------------*
+ * MPEG Extension to the PPB *
+ *------------------------------------------------------*/
+#define BC_MPEG_VALID_PANSCAN (1)
+
+typedef struct _BC_PIB_EXT_MPEG {
+ uint32_t valid;
+ /* Always valid, defaults to picture size if no
+ * sequence display extension in the stream. */
+ uint32_t display_horizontal_size;
+ uint32_t display_vertical_size;
+
+ /* MPEG_VALID_PANSCAN
+ * Offsets are a copy values from the MPEG stream. */
+ uint32_t offset_count;
+ int32_t horizontal_offset[3];
+ int32_t vertical_offset[3];
+
+} BC_PIB_EXT_MPEG;
+
+/*------------------------------------------------------*
+ * H.264 Extension to the PPB *
+ *------------------------------------------------------*/
+/* Bit definitions for 'other.h264.valid' field */
+#define H264_VALID_PANSCAN (1)
+#define H264_VALID_SPS_CROP (2)
+#define H264_VALID_VUI (4)
+
+typedef struct _BC_PIB_EXT_H264 {
+ /* 'valid' specifies which fields (or sets of
+ * fields) below are valid. If the corresponding
+ * bit in 'valid' is NOT set then that field(s)
+ * is (are) not initialized. */
+ uint32_t valid;
+
+ /* H264_VALID_PANSCAN */
+ uint32_t pan_scan_count;
+ int32_t pan_scan_left[3];
+ int32_t pan_scan_right[3];
+ int32_t pan_scan_top[3];
+ int32_t pan_scan_bottom[3];
+
+ /* H264_VALID_SPS_CROP */
+ int32_t sps_crop_left;
+ int32_t sps_crop_right;
+ int32_t sps_crop_top;
+ int32_t sps_crop_bottom;
+
+ /* H264_VALID_VUI */
+ uint32_t chroma_top;
+ uint32_t chroma_bottom;
+
+} BC_PIB_EXT_H264;
+
+/*------------------------------------------------------*
+ * VC1 Extension to the PPB *
+ *------------------------------------------------------*/
+#define VC1_VALID_PANSCAN (1)
+
+typedef struct _BC_PIB_EXT_VC1 {
+ uint32_t valid;
+
+ /* Always valid, defaults to picture size if no
+ * sequence display extension in the stream. */
+ uint32_t display_horizontal_size;
+ uint32_t display_vertical_size;
+
+ /* VC1 pan scan windows */
+ uint32_t num_panscan_windows;
+ int32_t ps_horiz_offset[4];
+ int32_t ps_vert_offset[4];
+ int32_t ps_width[4];
+ int32_t ps_height[4];
+
+} BC_PIB_EXT_VC1;
+
+
+/*------------------------------------------------------*
+ * Picture Information Block *
+ *------------------------------------------------------*/
+#if defined(_WIN32) || defined(_WIN64) || defined(__LINUX_USER__)
+/* Values for 'pulldown' field. '0' means no pulldown information
+ * was present for this picture. */
+enum {
+ vdecNoPulldownInfo = 0,
+ vdecTop = 1,
+ vdecBottom = 2,
+ vdecTopBottom = 3,
+ vdecBottomTop = 4,
+ vdecTopBottomTop = 5,
+ vdecBottomTopBottom = 6,
+ vdecFrame_X2 = 7,
+ vdecFrame_X3 = 8,
+ vdecFrame_X1 = 9,
+ vdecFrame_X4 = 10,
+};
+
+/* Values for the 'frame_rate' field. */
+enum {
+ vdecFrameRateUnknown = 0,
+ vdecFrameRate23_97,
+ vdecFrameRate24,
+ vdecFrameRate25,
+ vdecFrameRate29_97,
+ vdecFrameRate30,
+ vdecFrameRate50,
+ vdecFrameRate59_94,
+ vdecFrameRate60,
+};
+
+/* Values for the 'aspect_ratio' field. */
+enum {
+ vdecAspectRatioUnknown = 0,
+ vdecAspectRatioSquare,
+ vdecAspectRatio12_11,
+ vdecAspectRatio10_11,
+ vdecAspectRatio16_11,
+ vdecAspectRatio40_33,
+ vdecAspectRatio24_11,
+ vdecAspectRatio20_11,
+ vdecAspectRatio32_11,
+ vdecAspectRatio80_33,
+ vdecAspectRatio18_11,
+ vdecAspectRatio15_11,
+ vdecAspectRatio64_33,
+ vdecAspectRatio160_99,
+ vdecAspectRatio4_3,
+ vdecAspectRatio16_9,
+ vdecAspectRatio221_1,
+ vdecAspectRatioOther = 255,
+};
+
+/* Values for the 'colour_primaries' field. */
+enum {
+ vdecColourPrimariesUnknown = 0,
+ vdecColourPrimariesBT709,
+ vdecColourPrimariesUnspecified,
+ vdecColourPrimariesReserved,
+ vdecColourPrimariesBT470_2M = 4,
+ vdecColourPrimariesBT470_2BG,
+ vdecColourPrimariesSMPTE170M,
+ vdecColourPrimariesSMPTE240M,
+ vdecColourPrimariesGenericFilm,
+};
+
+enum {
+ vdecRESOLUTION_CUSTOM = 0x00000000, /* custom */
+ vdecRESOLUTION_480i = 0x00000001, /* 480i */
+ vdecRESOLUTION_1080i = 0x00000002, /* 1080i (1920x1080, 60i) */
+ vdecRESOLUTION_NTSC = 0x00000003, /* NTSC (720x483, 60i) */
+ vdecRESOLUTION_480p = 0x00000004, /* 480p (720x480, 60p) */
+ vdecRESOLUTION_720p = 0x00000005, /* 720p (1280x720, 60p) */
+ vdecRESOLUTION_PAL1 = 0x00000006, /* PAL_1 (720x576, 50i) */
+ vdecRESOLUTION_1080i25 = 0x00000007, /* 1080i25 (1920x1080, 50i) */
+ vdecRESOLUTION_720p50 = 0x00000008, /* 720p50 (1280x720, 50p) */
+ vdecRESOLUTION_576p = 0x00000009, /* 576p (720x576, 50p) */
+ vdecRESOLUTION_1080i29_97 = 0x0000000A, /* 1080i (1920x1080, 59.94i) */
+ vdecRESOLUTION_720p59_94 = 0x0000000B, /* 720p (1280x720, 59.94p) */
+ vdecRESOLUTION_SD_DVD = 0x0000000C, /* SD DVD (720x483, 60i) */
+ vdecRESOLUTION_480p656 = 0x0000000D, /* 480p (720x480, 60p), output bus width 8 bit, clock 74.25MHz */
+ vdecRESOLUTION_1080p23_976 = 0x0000000E, /* 1080p23_976 (1920x1080, 23.976p) */
+ vdecRESOLUTION_720p23_976 = 0x0000000F, /* 720p23_976 (1280x720p, 23.976p) */
+ vdecRESOLUTION_240p29_97 = 0x00000010, /* 240p (1440x240, 29.97p ) */
+ vdecRESOLUTION_240p30 = 0x00000011, /* 240p (1440x240, 30p) */
+ vdecRESOLUTION_288p25 = 0x00000012, /* 288p (1440x288p, 25p) */
+ vdecRESOLUTION_1080p29_97 = 0x00000013, /* 1080p29_97 (1920x1080, 29.97p) */
+ vdecRESOLUTION_1080p30 = 0x00000014, /* 1080p30 (1920x1080, 30p) */
+ vdecRESOLUTION_1080p24 = 0x00000015, /* 1080p24 (1920x1080, 24p) */
+ vdecRESOLUTION_1080p25 = 0x00000016, /* 1080p25 (1920x1080, 25p) */
+ vdecRESOLUTION_720p24 = 0x00000017, /* 720p24 (1280x720, 25p) */
+ vdecRESOLUTION_720p29_97 = 0x00000018, /* 720p29.97 (1280x720, 29.97p) */
+ vdecRESOLUTION_480p23_976 = 0x00000019, /* 480p23.976 (720*480, 23.976) */
+ vdecRESOLUTION_480p29_97 = 0x0000001A, /* 480p29.976 (720*480, 29.97p) */
+ vdecRESOLUTION_576p25 = 0x0000001B, /* 576p25 (720*576, 25p) */
+ /* For Zero Frame Rate */
+ vdecRESOLUTION_480p0 = 0x0000001C, /* 480p (720x480, 0p) */
+ vdecRESOLUTION_480i0 = 0x0000001D, /* 480i (720x480, 0i) */
+ vdecRESOLUTION_576p0 = 0x0000001E, /* 576p (720x576, 0p) */
+ vdecRESOLUTION_720p0 = 0x0000001F, /* 720p (1280x720, 0p) */
+ vdecRESOLUTION_1080p0 = 0x00000020, /* 1080p (1920x1080, 0p) */
+ vdecRESOLUTION_1080i0 = 0x00000021, /* 1080i (1920x1080, 0i) */
+};
+
+/* Bit definitions for 'flags' field */
+#define VDEC_FLAG_EOS (0x0004)
+
+#define VDEC_FLAG_FRAME (0x0000)
+#define VDEC_FLAG_FIELDPAIR (0x0008)
+#define VDEC_FLAG_TOPFIELD (0x0010)
+#define VDEC_FLAG_BOTTOMFIELD (0x0018)
+
+#define VDEC_FLAG_PROGRESSIVE_SRC (0x0000)
+#define VDEC_FLAG_INTERLACED_SRC (0x0020)
+#define VDEC_FLAG_UNKNOWN_SRC (0x0040)
+
+#define VDEC_FLAG_BOTTOM_FIRST (0x0080)
+#define VDEC_FLAG_LAST_PICTURE (0x0100)
+
+#define VDEC_FLAG_PICTURE_META_DATA_PRESENT (0x40000)
+
+#endif /* _WIN32 || _WIN64 */
+
+enum _BC_OUTPUT_FORMAT {
+ MODE420 = 0x0,
+ MODE422_YUY2 = 0x1,
+ MODE422_UYVY = 0x2,
+};
+
+typedef struct _BC_PIC_INFO_BLOCK {
+ /* Common fields. */
+ uint64_t timeStamp; /* Timestamp */
+ uint32_t picture_number; /* Ordinal display number */
+ uint32_t width; /* pixels */
+ uint32_t height; /* pixels */
+ uint32_t chroma_format; /* 0x420, 0x422 or 0x444 */
+ uint32_t pulldown;
+ uint32_t flags;
+ uint32_t frame_rate;
+ uint32_t aspect_ratio;
+ uint32_t colour_primaries;
+ uint32_t picture_meta_payload;
+ uint32_t sess_num;
+ uint32_t ycom;
+ uint32_t custom_aspect_ratio_width_height;
+ uint32_t n_drop; /* number of non-reference frames remaining to be dropped */
+
+ /* Protocol-specific extensions. */
+ union {
+ BC_PIB_EXT_H264 h264;
+ BC_PIB_EXT_MPEG mpeg;
+ BC_PIB_EXT_VC1 vc1;
+ } other;
+
+} BC_PIC_INFO_BLOCK, *PBC_PIC_INFO_BLOCK;
+
+/*------------------------------------------------------*
+ * ProcOut Info *
+ *------------------------------------------------------*/
+/* Optional flags for ProcOut Interface.*/
+enum _POUT_OPTIONAL_IN_FLAGS_{
+ /* Flags from App to Device */
+ BC_POUT_FLAGS_YV12 = 0x01, /* Copy Data in YV12 format */
+ BC_POUT_FLAGS_STRIDE = 0x02, /* Stride size is valid. */
+ BC_POUT_FLAGS_SIZE = 0x04, /* Take size information from Application */
+ BC_POUT_FLAGS_INTERLACED = 0x08, /* copy only half the bytes */
+ BC_POUT_FLAGS_INTERLEAVED = 0x10, /* interleaved frame */
+
+ /* Flags from Device to APP */
+ BC_POUT_FLAGS_FMT_CHANGE = 0x10000, /* Data is not VALID when this flag is set */
+ BC_POUT_FLAGS_PIB_VALID = 0x20000, /* PIB Information valid */
+ BC_POUT_FLAGS_ENCRYPTED = 0x40000, /* Data is encrypted. */
+ BC_POUT_FLAGS_FLD_BOT = 0x80000, /* Bottom Field data */
+};
+
+#if defined(__KERNEL__) || defined(__LINUX_USER__)
+typedef BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut);
+#else
+typedef BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, struct _BC_DTS_PROC_OUT *pOut);
+#endif
+
+/* Line 21 Closed Caption */
+/* User Data */
+#define MAX_UD_SIZE 1792 /* 1920 - 128 */
+
+typedef struct _BC_DTS_PROC_OUT {
+ uint8_t *Ybuff; /* Caller Supplied buffer for Y data */
+ uint32_t YbuffSz; /* Caller Supplied Y buffer size */
+ uint32_t YBuffDoneSz; /* Transferred Y datasize */
+
+ uint8_t *UVbuff; /* Caller Supplied buffer for UV data */
+ uint32_t UVbuffSz; /* Caller Supplied UV buffer size */
+ uint32_t UVBuffDoneSz; /* Transferred UV data size */
+
+ uint32_t StrideSz; /* Caller supplied Stride Size */
+ uint32_t PoutFlags; /* Call IN Flags */
+
+ uint32_t discCnt; /* Picture discontinuity count */
+
+ BC_PIC_INFO_BLOCK PicInfo; /* Picture Information Block Data */
+
+ /* Line 21 Closed Caption */
+ /* User Data */
+ uint32_t UserDataSz;
+ uint8_t UserData[MAX_UD_SIZE];
+
+ void *hnd;
+ dts_pout_callback AppCallBack;
+ uint8_t DropFrames;
+ uint8_t b422Mode; /* Picture output Mode */
+ uint8_t bPibEnc; /* PIB encrypted */
+ uint8_t bRevertScramble;
+
+} BC_DTS_PROC_OUT;
+
+typedef struct _BC_DTS_STATUS {
+ uint8_t ReadyListCount; /* Number of frames in ready list (reported by driver) */
+ uint8_t FreeListCount; /* Number of frame buffers free. (reported by driver) */
+ uint8_t PowerStateChange; /* Number of active state power transitions (reported by driver) */
+ uint8_t reserved_[1];
+
+ uint32_t FramesDropped; /* Number of frames dropped. (reported by DIL) */
+ uint32_t FramesCaptured; /* Number of frames captured. (reported by DIL) */
+ uint32_t FramesRepeated; /* Number of frames repeated. (reported by DIL) */
+
+ uint32_t InputCount; /* Times compressed video has been sent to the HW.
+ * i.e. Successful DtsProcInput() calls (reported by DIL) */
+ uint64_t InputTotalSize; /* Amount of compressed video that has been sent to the HW.
+ * (reported by DIL) */
+ uint32_t InputBusyCount; /* Times compressed video has attempted to be sent to the HW
+ * but the input FIFO was full. (reported by DIL) */
+
+ uint32_t PIBMissCount; /* Amount of times a PIB is invalid. (reported by DIL) */
+
+ uint32_t cpbEmptySize; /* supported only for H.264, specifically changed for
+ * Adobe. Report size of CPB buffer available.
+ * Reported by DIL */
+ uint64_t NextTimeStamp; /* TimeStamp of the next picture that will be returned
+ * by a call to ProcOutput. Added for Adobe. Reported
+ * back from the driver */
+ uint8_t reserved__[16];
+
+} BC_DTS_STATUS;
+
+#define BC_SWAP32(_v) \
+ ((((_v) & 0xFF000000)>>24)| \
+ (((_v) & 0x00FF0000)>>8)| \
+ (((_v) & 0x0000FF00)<<8)| \
+ (((_v) & 0x000000FF)<<24))
+
+#define WM_AGENT_TRAYICON_DECODER_OPEN 10001
+#define WM_AGENT_TRAYICON_DECODER_CLOSE 10002
+#define WM_AGENT_TRAYICON_DECODER_START 10003
+#define WM_AGENT_TRAYICON_DECODER_STOP 10004
+#define WM_AGENT_TRAYICON_DECODER_RUN 10005
+#define WM_AGENT_TRAYICON_DECODER_PAUSE 10006
+
+
+#endif /* _BC_DTS_DEFS_H_ */
diff --git a/drivers/staging/crystalhd/bc_dts_glob_lnx.h b/drivers/staging/crystalhd/bc_dts_glob_lnx.h
new file mode 100644
index 00000000000..b3125e3e037
--- /dev/null
+++ b/drivers/staging/crystalhd/bc_dts_glob_lnx.h
@@ -0,0 +1,299 @@
+/********************************************************************
+ * Copyright(c) 2006-2009 Broadcom Corporation.
+ *
+ * Name: bc_dts_glob_lnx.h
+ *
+ * Description: Wrapper to Windows dts_glob.h for Link-Linux usage.
+ * The idea is to define additional Linux related defs
+ * in this file to avoid changes to existing Windows
+ * glob file.
+ *
+ * AU
+ *
+ * HISTORY:
+ *
+ ********************************************************************
+ * This header is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 2.1 of the License.
+ *
+ * This header is distributed in 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 Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header. If not, see <http://www.gnu.org/licenses/>.
+ *******************************************************************/
+
+#ifndef _BC_DTS_GLOB_LNX_H_
+#define _BC_DTS_GLOB_LNX_H_
+
+#ifdef __LINUX_USER__
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#include <sys/time.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include <asm/param.h>
+#include <linux/ioctl.h>
+#include <sys/select.h>
+
+#define DRVIFLIB_INT_API
+
+#endif
+
+#include "bc_dts_defs.h"
+#include "bcm_70012_regs.h" /* Link Register defs */
+
+#define CRYSTALHD_API_NAME "crystalhd"
+#define CRYSTALHD_API_DEV_NAME "/dev/crystalhd"
+
+/*
+ * These are SW stack tunable parameters shared
+ * between the driver and the application.
+ */
+enum _BC_DTS_GLOBALS {
+ BC_MAX_FW_CMD_BUFF_SZ = 0x40, /* FW passthrough cmd/rsp buffer size */
+ PCI_CFG_SIZE = 256, /* PCI config size buffer */
+ BC_IOCTL_DATA_POOL_SIZE = 8, /* BC_IOCTL_DATA Pool size */
+ BC_LINK_MAX_OPENS = 3, /* Maximum simultaneous opens*/
+ BC_LINK_MAX_SGLS = 1024, /* Maximum SG elements 4M/4K */
+ BC_TX_LIST_CNT = 2, /* Max Tx DMA Rings */
+ BC_RX_LIST_CNT = 8, /* Max Rx DMA Rings*/
+ BC_PROC_OUTPUT_TIMEOUT = 3000, /* Milliseconds */
+ BC_INFIFO_THRESHOLD = 0x10000,
+};
+
+typedef struct _BC_CMD_REG_ACC {
+ uint32_t Offset;
+ uint32_t Value;
+} BC_CMD_REG_ACC;
+
+typedef struct _BC_CMD_DEV_MEM {
+ uint32_t StartOff;
+ uint32_t NumDwords;
+ uint32_t Rsrd;
+} BC_CMD_DEV_MEM;
+
+/* FW Passthrough command structure */
+enum _bc_fw_cmd_flags {
+ BC_FW_CMD_FLAGS_NONE = 0,
+ BC_FW_CMD_PIB_QS = 0x01,
+};
+
+typedef struct _BC_FW_CMD {
+ uint32_t cmd[BC_MAX_FW_CMD_BUFF_SZ];
+ uint32_t rsp[BC_MAX_FW_CMD_BUFF_SZ];
+ uint32_t flags;
+ uint32_t add_data;
+} BC_FW_CMD, *PBC_FW_CMD;
+
+typedef struct _BC_HW_TYPE {
+ uint16_t PciDevId;
+ uint16_t PciVenId;
+ uint8_t HwRev;
+ uint8_t Align[3];
+} BC_HW_TYPE;
+
+typedef struct _BC_PCI_CFG {
+ uint32_t Size;
+ uint32_t Offset;
+ uint8_t pci_cfg_space[PCI_CFG_SIZE];
+} BC_PCI_CFG;
+
+typedef struct _BC_VERSION_INFO_ {
+ uint8_t DriverMajor;
+ uint8_t DriverMinor;
+ uint16_t DriverRevision;
+} BC_VERSION_INFO;
+
+typedef struct _BC_START_RX_CAP_ {
+ uint32_t Rsrd;
+ uint32_t StartDeliveryThsh;
+ uint32_t PauseThsh;
+ uint32_t ResumeThsh;
+} BC_START_RX_CAP;
+
+typedef struct _BC_FLUSH_RX_CAP_ {
+ uint32_t Rsrd;
+ uint32_t bDiscardOnly;
+} BC_FLUSH_RX_CAP;
+
+typedef struct _BC_DTS_STATS {
+ uint8_t drvRLL;
+ uint8_t drvFLL;
+ uint8_t eosDetected;
+ uint8_t pwr_state_change;
+
+ /* Stats from App */
+ uint32_t opFrameDropped;
+ uint32_t opFrameCaptured;
+ uint32_t ipSampleCnt;
+ uint64_t ipTotalSize;
+ uint32_t reptdFrames;
+ uint32_t pauseCount;
+ uint32_t pibMisses;
+ uint32_t discCounter;
+
+ /* Stats from Driver */
+ uint32_t TxFifoBsyCnt;
+ uint32_t intCount;
+ uint32_t DrvIgnIntrCnt;
+ uint32_t DrvTotalFrmDropped;
+ uint32_t DrvTotalHWErrs;
+ uint32_t DrvTotalPIBFlushCnt;
+ uint32_t DrvTotalFrmCaptured;
+ uint32_t DrvPIBMisses;
+ uint32_t DrvPauseTime;
+ uint32_t DrvRepeatedFrms;
+ uint32_t res1[13];
+
+} BC_DTS_STATS;
+
+typedef struct _BC_PROC_INPUT_ {
+ uint8_t *pDmaBuff;
+ uint32_t BuffSz;
+ uint8_t Mapped;
+ uint8_t Encrypted;
+ uint8_t Rsrd[2];
+ uint32_t DramOffset; /* For debug use only */
+} BC_PROC_INPUT, *PBC_PROC_INPUT;
+
+typedef struct _BC_DEC_YUV_BUFFS {
+ uint32_t b422Mode;
+ uint8_t *YuvBuff;
+ uint32_t YuvBuffSz;
+ uint32_t UVbuffOffset;
+ uint32_t YBuffDoneSz;
+ uint32_t UVBuffDoneSz;
+ uint32_t RefCnt;
+} BC_DEC_YUV_BUFFS;
+
+enum _DECOUT_COMPLETION_FLAGS{
+ COMP_FLAG_NO_INFO = 0x00,
+ COMP_FLAG_FMT_CHANGE = 0x01,
+ COMP_FLAG_PIB_VALID = 0x02,
+ COMP_FLAG_DATA_VALID = 0x04,
+ COMP_FLAG_DATA_ENC = 0x08,
+ COMP_FLAG_DATA_BOT = 0x10,
+};
+
+typedef struct _BC_DEC_OUT_BUFF{
+ BC_DEC_YUV_BUFFS OutPutBuffs;
+ BC_PIC_INFO_BLOCK PibInfo;
+ uint32_t Flags;
+ uint32_t BadFrCnt;
+} BC_DEC_OUT_BUFF;
+
+typedef struct _BC_NOTIFY_MODE {
+ uint32_t Mode;
+ uint32_t Rsvr[3];
+} BC_NOTIFY_MODE;
+
+typedef struct _BC_CLOCK {
+ uint32_t clk;
+ uint32_t Rsvr[3];
+} BC_CLOCK;
+
+typedef struct _BC_IOCTL_DATA {
+ BC_STATUS RetSts;
+ uint32_t IoctlDataSz;
+ uint32_t Timeout;
+ union {
+ BC_CMD_REG_ACC regAcc;
+ BC_CMD_DEV_MEM devMem;
+ BC_FW_CMD fwCmd;
+ BC_HW_TYPE hwType;
+ BC_PCI_CFG pciCfg;
+ BC_VERSION_INFO VerInfo;
+ BC_PROC_INPUT ProcInput;
+ BC_DEC_YUV_BUFFS RxBuffs;
+ BC_DEC_OUT_BUFF DecOutData;
+ BC_START_RX_CAP RxCap;
+ BC_FLUSH_RX_CAP FlushRxCap;
+ BC_DTS_STATS drvStat;
+ BC_NOTIFY_MODE NotifyMode;
+ BC_CLOCK clockValue;
+ } u;
+ struct _BC_IOCTL_DATA *next;
+} BC_IOCTL_DATA;
+
+typedef enum _BC_DRV_CMD{
+ DRV_CMD_VERSION = 0, /* Get SW version */
+ DRV_CMD_GET_HWTYPE, /* Get HW version and type Dozer/Tank */
+ DRV_CMD_REG_RD, /* Read Device Register */
+ DRV_CMD_REG_WR, /* Write Device Register */
+ DRV_CMD_FPGA_RD, /* Read FPGA Register */
+ DRV_CMD_FPGA_WR, /* Wrtie FPGA Reister */
+ DRV_CMD_MEM_RD, /* Read Device Memory */
+ DRV_CMD_MEM_WR, /* Write Device Memory */
+ DRV_CMD_RD_PCI_CFG, /* Read PCI Config Space */
+ DRV_CMD_WR_PCI_CFG, /* Write the PCI Configuration Space*/
+ DRV_CMD_FW_DOWNLOAD, /* Download Firmware */
+ DRV_ISSUE_FW_CMD, /* Issue FW Cmd (pass through mode) */
+ DRV_CMD_PROC_INPUT, /* Process Input Sample */
+ DRV_CMD_ADD_RXBUFFS, /* Add Rx side buffers to driver pool */
+ DRV_CMD_FETCH_RXBUFF, /* Get Rx DMAed buffer */
+ DRV_CMD_START_RX_CAP, /* Start Rx Buffer Capture */
+ DRV_CMD_FLUSH_RX_CAP, /* Stop the capture for now...we will enhance this later*/
+ DRV_CMD_GET_DRV_STAT, /* Get Driver Internal Statistics */
+ DRV_CMD_RST_DRV_STAT, /* Reset Driver Internal Statistics */
+ DRV_CMD_NOTIFY_MODE, /* Notify the Mode to driver in which the application is Operating*/
+ DRV_CMD_CHANGE_CLOCK, /* Change the core clock to either save power or improve performance */
+
+ /* MUST be the last one.. */
+ DRV_CMD_END, /* End of the List.. */
+} BC_DRV_CMD;
+
+#define BC_IOC_BASE 'b'
+#define BC_IOC_VOID _IOC_NONE
+#define BC_IOC_IOWR(nr, type) _IOWR(BC_IOC_BASE, nr, type)
+#define BC_IOCTL_MB BC_IOCTL_DATA
+
+#define BCM_IOC_GET_VERSION BC_IOC_IOWR(DRV_CMD_VERSION, BC_IOCTL_MB)
+#define BCM_IOC_GET_HWTYPE BC_IOC_IOWR(DRV_CMD_GET_HWTYPE, BC_IOCTL_MB)
+#define BCM_IOC_REG_RD BC_IOC_IOWR(DRV_CMD_REG_RD, BC_IOCTL_MB)
+#define BCM_IOC_REG_WR BC_IOC_IOWR(DRV_CMD_REG_WR, BC_IOCTL_MB)
+#define BCM_IOC_MEM_RD BC_IOC_IOWR(DRV_CMD_MEM_RD, BC_IOCTL_MB)
+#define BCM_IOC_MEM_WR BC_IOC_IOWR(DRV_CMD_MEM_WR, BC_IOCTL_MB)
+#define BCM_IOC_FPGA_RD BC_IOC_IOWR(DRV_CMD_FPGA_RD, BC_IOCTL_MB)
+#define BCM_IOC_FPGA_WR BC_IOC_IOWR(DRV_CMD_FPGA_WR, BC_IOCTL_MB)
+#define BCM_IOC_RD_PCI_CFG BC_IOC_IOWR(DRV_CMD_RD_PCI_CFG, BC_IOCTL_MB)
+#define BCM_IOC_WR_PCI_CFG BC_IOC_IOWR(DRV_CMD_WR_PCI_CFG, BC_IOCTL_MB)
+#define BCM_IOC_PROC_INPUT BC_IOC_IOWR(DRV_CMD_PROC_INPUT, BC_IOCTL_MB)
+#define BCM_IOC_ADD_RXBUFFS BC_IOC_IOWR(DRV_CMD_ADD_RXBUFFS, BC_IOCTL_MB)
+#define BCM_IOC_FETCH_RXBUFF BC_IOC_IOWR(DRV_CMD_FETCH_RXBUFF, BC_IOCTL_MB)
+#define BCM_IOC_FW_CMD BC_IOC_IOWR(DRV_ISSUE_FW_CMD, BC_IOCTL_MB)
+#define BCM_IOC_START_RX_CAP BC_IOC_IOWR(DRV_CMD_START_RX_CAP, BC_IOCTL_MB)
+#define BCM_IOC_FLUSH_RX_CAP BC_IOC_IOWR(DRV_CMD_FLUSH_RX_CAP, BC_IOCTL_MB)
+#define BCM_IOC_GET_DRV_STAT BC_IOC_IOWR(DRV_CMD_GET_DRV_STAT, BC_IOCTL_MB)
+#define BCM_IOC_RST_DRV_STAT BC_IOC_IOWR(DRV_CMD_RST_DRV_STAT, BC_IOCTL_MB)
+#define BCM_IOC_NOTIFY_MODE BC_IOC_IOWR(DRV_CMD_NOTIFY_MODE, BC_IOCTL_MB)
+#define BCM_IOC_FW_DOWNLOAD BC_IOC_IOWR(DRV_CMD_FW_DOWNLOAD, BC_IOCTL_MB)
+#define BCM_IOC_CHG_CLK BC_IOC_IOWR(DRV_CMD_CHANGE_CLOCK, BC_IOCTL_MB)
+#define BCM_IOC_END BC_IOC_VOID
+
+/* Wrapper for main IOCTL data */
+typedef struct _crystalhd_ioctl_data {
+ BC_IOCTL_DATA udata; /* IOCTL from App..*/
+ uint32_t u_id; /* Driver specific user ID */
+ uint32_t cmd; /* Cmd ID for driver's use. */
+ void *add_cdata; /* Additional command specific data..*/
+ uint32_t add_cdata_sz; /* Additional command specific data size */
+ struct _crystalhd_ioctl_data *next; /* List/Fifo management */
+} crystalhd_ioctl_data;
+
+
+enum _crystalhd_kmod_ver{
+ crystalhd_kmod_major = 0,
+ crystalhd_kmod_minor = 9,
+ crystalhd_kmod_rev = 27,
+};
+
+#endif
diff --git a/drivers/staging/crystalhd/bc_dts_types.h b/drivers/staging/crystalhd/bc_dts_types.h
new file mode 100644
index 00000000000..ac0c8171738
--- /dev/null
+++ b/drivers/staging/crystalhd/bc_dts_types.h
@@ -0,0 +1,121 @@
+/********************************************************************
+ * Copyright(c) 2006-2009 Broadcom Corporation.
+ *
+ * Name: bc_dts_types.h
+ *
+ * Description: Data types
+ *
+ * AU
+ *
+ * HISTORY:
+ *
+ ********************************************************************
+ * This header is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 2.1 of the License.
+ *
+ * This header is distributed in 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 Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header. If not, see <http://www.gnu.org/licenses/>.
+ *******************************************************************/
+
+#ifndef _BC_DTS_TYPES_H_
+#define _BC_DTS_TYPES_H_
+
+#ifdef __LINUX_USER__ // Don't include these for KERNEL..
+#include <stdint.h>
+#endif
+
+#if defined(_WIN64) || defined(_WIN32)
+typedef uint32_t U32;
+typedef int32_t S32;
+typedef uint16_t U16;
+typedef int16_t S16;
+typedef unsigned char U8;
+typedef char S8;
+#endif
+
+#ifndef PVOID
+typedef void *PVOID;
+#endif
+
+#ifndef BOOL
+typedef int BOOL;
+#endif
+
+#ifdef WIN32
+ typedef unsigned __int64 U64;
+#elif defined(_WIN64)
+ typedef uint64_t U64;
+#endif
+
+#ifdef _WIN64
+#if !(defined(POINTER_32))
+#define POINTER_32 __ptr32
+#endif
+#else /* _WIN32 */
+#define POINTER_32
+#endif
+
+#if defined(__KERNEL__) || defined(__LINUX_USER__)
+
+#ifdef __LINUX_USER__ /* Don't include these for KERNEL */
+typedef uint32_t ULONG;
+typedef int32_t LONG;
+typedef void *HANDLE;
+#ifndef VOID
+typedef void VOID;
+#endif
+typedef void *LPVOID;
+typedef uint32_t DWORD;
+typedef uint32_t UINT32;
+typedef uint32_t *LPDWORD;
+typedef unsigned char *PUCHAR;
+
+#ifndef TRUE
+ #define TRUE 1
+#endif
+
+#ifndef FALSE
+ #define FALSE 0
+#endif
+
+#define TEXT
+
+#else
+
+/* For Kernel usage.. */
+typedef bool bc_bool_t;
+#endif
+
+#else
+
+#ifndef uint64_t
+typedef struct _uint64_t {
+ uint32_t low_dw;
+ uint32_t hi_dw;
+} uint64_t;
+#endif
+
+#ifndef int32_t
+typedef signed long int32_t;
+#endif
+
+#ifndef uint32_t
+typedef unsigned long uint32_t;
+#endif
+
+#ifndef uint16_t
+typedef unsigned short uint16_t;
+#endif
+
+#ifndef uint8_t
+typedef unsigned char uint8_t;
+#endif
+#endif
+
+#endif
+
diff --git a/drivers/staging/crystalhd/bcm_70012_regs.h b/drivers/staging/crystalhd/bcm_70012_regs.h
new file mode 100644
index 00000000000..6922f54e432
--- /dev/null
+++ b/drivers/staging/crystalhd/bcm_70012_regs.h
@@ -0,0 +1,757 @@
+/***************************************************************************
+ * Copyright (c) 1999-2009, Broadcom Corporation.
+ *
+ * Name: bcm_70012_regs.h
+ *
+ * Description: BCM70012 registers
+ *
+ ********************************************************************
+ * This header is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 2.1 of the License.
+ *
+ * This header is distributed in 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 Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this header. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************************************************/
+
+#ifndef MACFILE_H__
+#define MACFILE_H__
+
+/**
+ * m = memory, c = core, r = register, f = field, d = data.
+ */
+#if !defined(GET_FIELD) && !defined(SET_FIELD)
+#define BRCM_ALIGN(c,r,f) c##_##r##_##f##_ALIGN
+#define BRCM_BITS(c,r,f) c##_##r##_##f##_BITS
+#define BRCM_MASK(c,r,f) c##_##r##_##f##_MASK
+#define BRCM_SHIFT(c,r,f) c##_##r##_##f##_SHIFT
+
+#define GET_FIELD(m,c,r,f) \
+ ((((m) & BRCM_MASK(c,r,f)) >> BRCM_SHIFT(c,r,f)) << BRCM_ALIGN(c,r,f))
+
+#define SET_FIELD(m,c,r,f,d) \
+ ((m) = (((m) & ~BRCM_MASK(c,r,f)) | ((((d) >> BRCM_ALIGN(c,r,f)) << \
+ BRCM_SHIFT(c,r,f)) & BRCM_MASK(c,r,f))) \
+ )
+
+#define SET_TYPE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##d)
+#define SET_NAME_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##r##_##f##_##d)
+#define SET_VALUE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,d)
+
+#endif /* GET & SET */
+
+/****************************************************************************
+ * Core Enums.
+ ***************************************************************************/
+/****************************************************************************
+ * Enums: AES_RGR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define AES_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
+#define AES_RGR_BRIDGE_RESET_CTRL_ASSERT 1
+
+/****************************************************************************
+ * Enums: CCE_RGR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define CCE_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
+#define CCE_RGR_BRIDGE_RESET_CTRL_ASSERT 1
+
+/****************************************************************************
+ * Enums: DBU_RGR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define DBU_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
+#define DBU_RGR_BRIDGE_RESET_CTRL_ASSERT 1
+
+/****************************************************************************
+ * Enums: DCI_RGR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define DCI_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
+#define DCI_RGR_BRIDGE_RESET_CTRL_ASSERT 1
+
+/****************************************************************************
+ * Enums: GISB_ARBITER_DEASSERT_ASSERT
+ ***************************************************************************/
+#define GISB_ARBITER_DEASSERT_ASSERT_DEASSERT 0
+#define GISB_ARBITER_DEASSERT_ASSERT_ASSERT 1
+
+/****************************************************************************
+ * Enums: GISB_ARBITER_UNMASK_MASK
+ ***************************************************************************/
+#define GISB_ARBITER_UNMASK_MASK_UNMASK 0
+#define GISB_ARBITER_UNMASK_MASK_MASK 1
+
+/****************************************************************************
+ * Enums: GISB_ARBITER_DISABLE_ENABLE
+ ***************************************************************************/
+#define GISB_ARBITER_DISABLE_ENABLE_DISABLE 0
+#define GISB_ARBITER_DISABLE_ENABLE_ENABLE 1
+
+/****************************************************************************
+ * Enums: I2C_GR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define I2C_GR_BRIDGE_RESET_CTRL_DEASSERT 0
+#define I2C_GR_BRIDGE_RESET_CTRL_ASSERT 1
+
+/****************************************************************************
+ * Enums: MISC_GR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define MISC_GR_BRIDGE_RESET_CTRL_DEASSERT 0
+#define MISC_GR_BRIDGE_RESET_CTRL_ASSERT 1
+
+/****************************************************************************
+ * Enums: OTP_GR_BRIDGE_RESET_CTRL
+ ***************************************************************************/
+#define OTP_GR_BRIDGE_RESET_CTRL_DEASSERT 0
+#define OTP_GR_BRIDGE_RESET_CTRL_ASSERT 1
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_PCIE_CFG
+ ***************************************************************************/
+#define PCIE_CFG_DEVICE_VENDOR_ID 0x00000000 /* DEVICE_VENDOR_ID Register */
+#define PCIE_CFG_STATUS_COMMAND 0x00000004 /* STATUS_COMMAND Register */
+#define PCIE_CFG_PCI_CLASSCODE_AND_REVISION_ID 0x00000008 /* PCI_CLASSCODE_AND_REVISION_ID Register */
+#define PCIE_CFG_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE 0x0000000c /* BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE Register */
+#define PCIE_CFG_BASE_ADDRESS_1 0x00000010 /* BASE_ADDRESS_1 Register */
+#define PCIE_CFG_BASE_ADDRESS_2 0x00000014 /* BASE_ADDRESS_2 Register */
+#define PCIE_CFG_BASE_ADDRESS_3 0x00000018 /* BASE_ADDRESS_3 Register */
+#define PCIE_CFG_BASE_ADDRESS_4 0x0000001c /* BASE_ADDRESS_4 Register */
+#define PCIE_CFG_CARDBUS_CIS_POINTER 0x00000028 /* CARDBUS_CIS_POINTER Register */
+#define PCIE_CFG_SUBSYSTEM_DEVICE_VENDOR_ID 0x0000002c /* SUBSYSTEM_DEVICE_VENDOR_ID Register */
+#define PCIE_CFG_EXPANSION_ROM_BASE_ADDRESS 0x00000030 /* EXPANSION_ROM_BASE_ADDRESS Register */
+#define PCIE_CFG_CAPABILITIES_POINTER 0x00000034 /* CAPABILITIES_POINTER Register */
+#define PCIE_CFG_INTERRUPT 0x0000003c /* INTERRUPT Register */
+#define PCIE_CFG_VPD_CAPABILITIES 0x00000040 /* VPD_CAPABILITIES Register */
+#define PCIE_CFG_VPD_DATA 0x00000044 /* VPD_DATA Register */
+#define PCIE_CFG_POWER_MANAGEMENT_CAPABILITY 0x00000048 /* POWER_MANAGEMENT_CAPABILITY Register */
+#define PCIE_CFG_POWER_MANAGEMENT_CONTROL_STATUS 0x0000004c /* POWER_MANAGEMENT_CONTROL_STATUS Register */
+#define PCIE_CFG_MSI_CAPABILITY_HEADER 0x00000050 /* MSI_CAPABILITY_HEADER Register */
+#define PCIE_CFG_MSI_LOWER_ADDRESS 0x00000054 /* MSI_LOWER_ADDRESS Register */
+#define PCIE_CFG_MSI_UPPER_ADDRESS_REGISTER 0x00000058 /* MSI_UPPER_ADDRESS_REGISTER Register */
+#define PCIE_CFG_MSI_DATA 0x0000005c /* MSI_DATA Register */
+#define PCIE_CFG_BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER 0x00000060 /* BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER Register */
+#define PCIE_CFG_RESET_COUNTERS_INITIAL_VALUES 0x00000064 /* RESET_COUNTERS_INITIAL_VALUES Register */
+#define PCIE_CFG_MISCELLANEOUS_HOST_CONTROL 0x00000068 /* MISCELLANEOUS_HOST_CONTROL Register */
+#define PCIE_CFG_SPARE 0x0000006c /* SPARE Register */
+#define PCIE_CFG_PCI_STATE 0x00000070 /* PCI_STATE Register */
+#define PCIE_CFG_CLOCK_CONTROL 0x00000074 /* CLOCK_CONTROL Register */
+#define PCIE_CFG_REGISTER_BASE 0x00000078 /* REGISTER_BASE Register */
+#define PCIE_CFG_MEMORY_BASE 0x0000007c /* MEMORY_BASE Register */
+#define PCIE_CFG_REGISTER_DATA 0x00000080 /* REGISTER_DATA Register */
+#define PCIE_CFG_MEMORY_DATA 0x00000084 /* MEMORY_DATA Register */
+#define PCIE_CFG_EXPANSION_ROM_BAR_SIZE 0x00000088 /* EXPANSION_ROM_BAR_SIZE Register */
+#define PCIE_CFG_EXPANSION_ROM_ADDRESS 0x0000008c /* EXPANSION_ROM_ADDRESS Register */
+#define PCIE_CFG_EXPANSION_ROM_DATA 0x00000090 /* EXPANSION_ROM_DATA Register */
+#define PCIE_CFG_VPD_INTERFACE 0x00000094 /* VPD_INTERFACE Register */
+#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER 0x00000098 /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER Register */
+#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER 0x0000009c /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER Register */
+#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER 0x000000a0 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER Register */
+#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER 0x000000a4 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER Register */
+#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER 0x000000a8 /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER Register */
+#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER 0x000000ac /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER Register */
+#define PCIE_CFG_INT_MAILBOX_UPPER 0x000000b0 /* INT_MAILBOX_UPPER Register */
+#define PCIE_CFG_INT_MAILBOX_LOWER 0x000000b4 /* INT_MAILBOX_LOWER Register */
+#define PCIE_CFG_PRODUCT_ID_AND_ASIC_REVISION 0x000000bc /* PRODUCT_ID_AND_ASIC_REVISION Register */
+#define PCIE_CFG_FUNCTION_EVENT 0x000000c0 /* FUNCTION_EVENT Register */
+#define PCIE_CFG_FUNCTION_EVENT_MASK 0x000000c4 /* FUNCTION_EVENT_MASK Register */
+#define PCIE_CFG_FUNCTION_PRESENT 0x000000c8 /* FUNCTION_PRESENT Register */
+#define PCIE_CFG_PCIE_CAPABILITIES 0x000000cc /* PCIE_CAPABILITIES Register */
+#define PCIE_CFG_DEVICE_CAPABILITIES 0x000000d0 /* DEVICE_CAPABILITIES Register */
+#define PCIE_CFG_DEVICE_STATUS_CONTROL 0x000000d4 /* DEVICE_STATUS_CONTROL Register */
+#define PCIE_CFG_LINK_CAPABILITY 0x000000d8 /* LINK_CAPABILITY Register */
+#define PCIE_CFG_LINK_STATUS_CONTROL 0x000000dc /* LINK_STATUS_CONTROL Register */
+#define PCIE_CFG_DEVICE_CAPABILITIES_2 0x000000f0 /* DEVICE_CAPABILITIES_2 Register */
+#define PCIE_CFG_DEVICE_STATUS_CONTROL_2 0x000000f4 /* DEVICE_STATUS_CONTROL_2 Register */
+#define PCIE_CFG_LINK_CAPABILITIES_2 0x000000f8 /* LINK_CAPABILITIES_2 Register */
+#define PCIE_CFG_LINK_STATUS_CONTROL_2 0x000000fc /* LINK_STATUS_CONTROL_2 Register */
+#define PCIE_CFG_ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER 0x00000100 /* ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER Register */
+#define PCIE_CFG_UNCORRECTABLE_ERROR_STATUS 0x00000104 /* UNCORRECTABLE_ERROR_STATUS Register */
+#define PCIE_CFG_UNCORRECTABLE_ERROR_MASK 0x00000108 /* UNCORRECTABLE_ERROR_MASK Register */
+#define PCIE_CFG_UNCORRECTABLE_ERROR_SEVERITY 0x0000010c /* UNCORRECTABLE_ERROR_SEVERITY Register */
+#define PCIE_CFG_CORRECTABLE_ERROR_STATUS 0x00000110 /* CORRECTABLE_ERROR_STATUS Register */
+#define PCIE_CFG_CORRECTABLE_ERROR_MASK 0x00000114 /* CORRECTABLE_ERROR_MASK Register */
+#define PCIE_CFG_ADVANCED_ERROR_CAPABILITIES_AND_CONTROL 0x00000118 /* ADVANCED_ERROR_CAPABILITIES_AND_CONTROL Register */
+#define PCIE_CFG_HEADER_LOG_1 0x0000011c /* HEADER_LOG_1 Register */
+#define PCIE_CFG_HEADER_LOG_2 0x00000120 /* HEADER_LOG_2 Register */
+#define PCIE_CFG_HEADER_LOG_3 0x00000124 /* HEADER_LOG_3 Register */
+#define PCIE_CFG_HEADER_LOG_4 0x00000128 /* HEADER_LOG_4 Register */
+#define PCIE_CFG_VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER 0x0000013c /* VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER Register */
+#define PCIE_CFG_PORT_VC_CAPABILITY 0x00000140 /* PORT_VC_CAPABILITY Register */
+#define PCIE_CFG_PORT_VC_CAPABILITY_2 0x00000144 /* PORT_VC_CAPABILITY_2 Register */
+#define PCIE_CFG_PORT_VC_STATUS_CONTROL 0x00000148 /* PORT_VC_STATUS_CONTROL Register */
+#define PCIE_CFG_VC_RESOURCE_CAPABILITY 0x0000014c /* VC_RESOURCE_CAPABILITY Register */
+#define PCIE_CFG_VC_RESOURCE_CONTROL 0x00000150 /* VC_RESOURCE_CONTROL Register */
+#define PCIE_CFG_VC_RESOURCE_STATUS 0x00000154 /* VC_RESOURCE_STATUS Register */
+#define PCIE_CFG_DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER 0x00000160 /* DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER Register */
+#define PCIE_CFG_DEVICE_SERIAL_NO_LOWER_DW 0x00000164 /* DEVICE_SERIAL_NO_LOWER_DW Register */
+#define PCIE_CFG_DEVICE_SERIAL_NO_UPPER_DW 0x00000168 /* DEVICE_SERIAL_NO_UPPER_DW Register */
+#define PCIE_CFG_POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER 0x0000016c /* POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER Register */
+#define PCIE_CFG_POWER_BUDGETING_DATA_SELECT 0x00000170 /* POWER_BUDGETING_DATA_SELECT Register */
+#define PCIE_CFG_POWER_BUDGETING_DATA 0x00000174 /* POWER_BUDGETING_DATA Register */
+#define PCIE_CFG_POWER_BUDGETING_CAPABILITY 0x00000178 /* POWER_BUDGETING_CAPABILITY Register */
+#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_2_1 0x0000017c /* FIRMWARE_POWER_BUDGETING_2_1 Register */
+#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_4_3 0x00000180 /* FIRMWARE_POWER_BUDGETING_4_3 Register */
+#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_6_5 0x00000184 /* FIRMWARE_POWER_BUDGETING_6_5 Register */
+#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_8_7 0x00000188 /* FIRMWARE_POWER_BUDGETING_8_7 Register */
+#define PCIE_CFG_PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING 0x0000018c /* PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING Register */
+
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_PCIE_TL
+ ***************************************************************************/
+#define PCIE_TL_TL_CONTROL 0x00000400 /* TL_CONTROL Register */
+#define PCIE_TL_TRANSACTION_CONFIGURATION 0x00000404 /* TRANSACTION_CONFIGURATION Register */
+
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_PCIE_DLL
+ ***************************************************************************/
+#define PCIE_DLL_DATA_LINK_CONTROL 0x00000500 /* DATA_LINK_CONTROL Register */
+#define PCIE_DLL_DATA_LINK_STATUS 0x00000504 /* DATA_LINK_STATUS Register */
+
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_INTR
+ ***************************************************************************/
+#define INTR_INTR_STATUS 0x00000700 /* Interrupt Status Register */
+#define INTR_INTR_SET 0x00000704 /* Interrupt Set Register */
+#define INTR_INTR_CLR_REG 0x00000708 /* Interrupt Clear Register */
+#define INTR_INTR_MSK_STS_REG 0x0000070c /* Interrupt Mask Status Register */
+#define INTR_INTR_MSK_SET_REG 0x00000710 /* Interrupt Mask Set Register */
+#define INTR_INTR_MSK_CLR_REG 0x00000714 /* Interrupt Mask Clear Register */
+#define INTR_EOI_CTRL 0x00000720 /* End of interrupt control register */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_MISC1
+ ***************************************************************************/
+#define MISC1_TX_FIRST_DESC_L_ADDR_LIST0 0x00000c00 /* Tx DMA Descriptor List0 First Descriptor lower Address */
+#define MISC1_TX_FIRST_DESC_U_ADDR_LIST0 0x00000c04 /* Tx DMA Descriptor List0 First Descriptor Upper Address */
+#define MISC1_TX_FIRST_DESC_L_ADDR_LIST1 0x00000c08 /* Tx DMA Descriptor List1 First Descriptor Lower Address */
+#define MISC1_TX_FIRST_DESC_U_ADDR_LIST1 0x00000c0c /* Tx DMA Descriptor List1 First Descriptor Upper Address */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS 0x00000c10 /* Tx DMA Software Descriptor List Control and Status */
+#define MISC1_TX_DMA_ERROR_STATUS 0x00000c18 /* Tx DMA Engine Error Status */
+#define MISC1_TX_DMA_LIST0_CUR_DESC_L_ADDR 0x00000c1c /* Tx DMA List0 Current Descriptor Lower Address */
+#define MISC1_TX_DMA_LIST0_CUR_DESC_U_ADDR 0x00000c20 /* Tx DMA List0 Current Descriptor Upper Address */
+#define MISC1_TX_DMA_LIST0_CUR_BYTE_CNT_REM 0x00000c24 /* Tx DMA List0 Current Descriptor Upper Address */
+#define MISC1_TX_DMA_LIST1_CUR_DESC_L_ADDR 0x00000c28 /* Tx DMA List1 Current Descriptor Lower Address */
+#define MISC1_TX_DMA_LIST1_CUR_DESC_U_ADDR 0x00000c2c /* Tx DMA List1 Current Descriptor Upper Address */
+#define MISC1_TX_DMA_LIST1_CUR_BYTE_CNT_REM 0x00000c30 /* Tx DMA List1 Current Descriptor Upper Address */
+#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c34 /* Y Rx Descriptor List0 First Descriptor Lower Address */
+#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c38 /* Y Rx Descriptor List0 First Descriptor Upper Address */
+#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c3c /* Y Rx Descriptor List1 First Descriptor Lower Address */
+#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c40 /* Y Rx Descriptor List1 First Descriptor Upper Address */
+#define MISC1_Y_RX_SW_DESC_LIST_CTRL_STS 0x00000c44 /* Y Rx Software Descriptor List Control and Status */
+#define MISC1_Y_RX_ERROR_STATUS 0x00000c4c /* Y Rx Engine Error Status */
+#define MISC1_Y_RX_LIST0_CUR_DESC_L_ADDR 0x00000c50 /* Y Rx List0 Current Descriptor Lower Address */
+#define MISC1_Y_RX_LIST0_CUR_DESC_U_ADDR 0x00000c54 /* Y Rx List0 Current Descriptor Upper Address */
+#define MISC1_Y_RX_LIST0_CUR_BYTE_CNT 0x00000c58 /* Y Rx List0 Current Descriptor Byte Count */
+#define MISC1_Y_RX_LIST1_CUR_DESC_L_ADDR 0x00000c5c /* Y Rx List1 Current Descriptor Lower address */
+#define MISC1_Y_RX_LIST1_CUR_DESC_U_ADDR 0x00000c60 /* Y Rx List1 Current Descriptor Upper address */
+#define MISC1_Y_RX_LIST1_CUR_BYTE_CNT 0x00000c64 /* Y Rx List1 Current Descriptor Byte Count */
+#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c68 /* UV Rx Descriptor List0 First Descriptor lower Address */
+#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c6c /* UV Rx Descriptor List0 First Descriptor Upper Address */
+#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c70 /* UV Rx Descriptor List1 First Descriptor Lower Address */
+#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c74 /* UV Rx Descriptor List1 First Descriptor Upper Address */
+#define MISC1_UV_RX_SW_DESC_LIST_CTRL_STS 0x00000c78 /* UV Rx Software Descriptor List Control and Status */
+#define MISC1_UV_RX_ERROR_STATUS 0x00000c7c /* UV Rx Engine Error Status */
+#define MISC1_UV_RX_LIST0_CUR_DESC_L_ADDR 0x00000c80 /* UV Rx List0 Current Descriptor Lower Address */
+#define MISC1_UV_RX_LIST0_CUR_DESC_U_ADDR 0x00000c84 /* UV Rx List0 Current Descriptor Upper Address */
+#define MISC1_UV_RX_LIST0_CUR_BYTE_CNT 0x00000c88 /* UV Rx List0 Current Descriptor Byte Count */
+#define MISC1_UV_RX_LIST1_CUR_DESC_L_ADDR 0x00000c8c /* UV Rx List1 Current Descriptor Lower Address */
+#define MISC1_UV_RX_LIST1_CUR_DESC_U_ADDR 0x00000c90 /* UV Rx List1 Current Descriptor Upper Address */
+#define MISC1_UV_RX_LIST1_CUR_BYTE_CNT 0x00000c94 /* UV Rx List1 Current Descriptor Byte Count */
+#define MISC1_DMA_DEBUG_OPTIONS_REG 0x00000c98 /* DMA Debug Options Register */
+#define MISC1_READ_CHANNEL_ERROR_STATUS 0x00000c9c /* Read Channel Error Status */
+#define MISC1_PCIE_DMA_CTRL 0x00000ca0 /* PCIE DMA Control Register */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_MISC2
+ ***************************************************************************/
+#define MISC2_GLOBAL_CTRL 0x00000d00 /* Global Control Register */
+#define MISC2_INTERNAL_STATUS 0x00000d04 /* Internal Status Register */
+#define MISC2_INTERNAL_STATUS_MUX_CTRL 0x00000d08 /* Internal Debug Mux Control */
+#define MISC2_DEBUG_FIFO_LENGTH 0x00000d0c /* Debug FIFO Length */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_MISC3
+ ***************************************************************************/
+#define MISC3_RESET_CTRL 0x00000e00 /* Reset Control Register */
+#define MISC3_BIST_CTRL 0x00000e04 /* BIST Control Register */
+#define MISC3_BIST_STATUS 0x00000e08 /* BIST Status Register */
+#define MISC3_RX_CHECKSUM 0x00000e0c /* Receive Checksum */
+#define MISC3_TX_CHECKSUM 0x00000e10 /* Transmit Checksum */
+#define MISC3_ECO_CTRL_CORE 0x00000e14 /* ECO Core Reset Control Register */
+#define MISC3_CSI_TEST_CTRL 0x00000e18 /* CSI Test Control Register */
+#define MISC3_HD_DVI_TEST_CTRL 0x00000e1c /* HD DVI Test Control Register */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_MISC_PERST
+ ***************************************************************************/
+#define MISC_PERST_ECO_CTRL_PERST 0x00000e80 /* ECO PCIE Reset Control Register */
+#define MISC_PERST_DECODER_CTRL 0x00000e84 /* Decoder Control Register */
+#define MISC_PERST_CCE_STATUS 0x00000e88 /* Config Copy Engine Status */
+#define MISC_PERST_PCIE_DEBUG 0x00000e8c /* PCIE Debug Control Register */
+#define MISC_PERST_PCIE_DEBUG_STATUS 0x00000e90 /* PCIE Debug Status Register */
+#define MISC_PERST_VREG_CTRL 0x00000e94 /* Voltage Regulator Control Register */
+#define MISC_PERST_MEM_CTRL 0x00000e98 /* Memory Control Register */
+#define MISC_PERST_CLOCK_CTRL 0x00000e9c /* Clock Control Register */
+
+
+/****************************************************************************
+ * BCM70012_MISC_TOP_GISB_ARBITER
+ ***************************************************************************/
+#define GISB_ARBITER_REVISION 0x00000f00 /* GISB ARBITER REVISION */
+#define GISB_ARBITER_SCRATCH 0x00000f04 /* GISB ARBITER Scratch Register */
+#define GISB_ARBITER_REQ_MASK 0x00000f08 /* GISB ARBITER Master Request Mask Register */
+#define GISB_ARBITER_TIMER 0x00000f0c /* GISB ARBITER Timer Value Register */
+
+
+/****************************************************************************
+ * BCM70012_OTP_TOP_OTP
+ ***************************************************************************/
+#define OTP_CONFIG_INFO 0x00001400 /* OTP Configuration Register */
+#define OTP_CMD 0x00001404 /* OTP Command Register */
+#define OTP_STATUS 0x00001408 /* OTP Status Register */
+#define OTP_CONTENT_MISC 0x0000140c /* Content : Miscellaneous Register */
+#define OTP_CONTENT_AES_0 0x00001410 /* Content : AES Key 0 Register */
+#define OTP_CONTENT_AES_1 0x00001414 /* Content : AES Key 1 Register */
+#define OTP_CONTENT_AES_2 0x00001418 /* Content : AES Key 2 Register */
+#define OTP_CONTENT_AES_3 0x0000141c /* Content : AES Key 3 Register */
+#define OTP_CONTENT_SHA_0 0x00001420 /* Content : SHA Key 0 Register */
+#define OTP_CONTENT_SHA_1 0x00001424 /* Content : SHA Key 1 Register */
+#define OTP_CONTENT_SHA_2 0x00001428 /* Content : SHA Key 2 Register */
+#define OTP_CONTENT_SHA_3 0x0000142c /* Content : SHA Key 3 Register */
+#define OTP_CONTENT_SHA_4 0x00001430 /* Content : SHA Key 4 Register */
+#define OTP_CONTENT_SHA_5 0x00001434 /* Content : SHA Key 5 Register */
+#define OTP_CONTENT_SHA_6 0x00001438 /* Content : SHA Key 6 Register */
+#define OTP_CONTENT_SHA_7 0x0000143c /* Content : SHA Key 7 Register */
+#define OTP_CONTENT_CHECKSUM 0x00001440 /* Content : Checksum Register */
+#define OTP_PROG_CTRL 0x00001444 /* Programming Control Register */
+#define OTP_PROG_STATUS 0x00001448 /* Programming Status Register */
+#define OTP_PROG_PULSE 0x0000144c /* Program Pulse Width Register */
+#define OTP_VERIFY_PULSE 0x00001450 /* Verify Pulse Width Register */
+#define OTP_PROG_MASK 0x00001454 /* Program Mask Register */
+#define OTP_DATA_INPUT 0x00001458 /* Data Input Register */
+#define OTP_DATA_OUTPUT 0x0000145c /* Data Output Register */
+
+
+/****************************************************************************
+ * BCM70012_AES_TOP_AES
+ ***************************************************************************/
+#define AES_CONFIG_INFO 0x00001800 /* AES Configuration Information Register */
+#define AES_CMD 0x00001804 /* AES Command Register */
+#define AES_STATUS 0x00001808 /* AES Status Register */
+#define AES_EEPROM_CONFIG 0x0000180c /* AES EEPROM Configuration Register */
+#define AES_EEPROM_DATA_0 0x00001810 /* AES EEPROM Data Register 0 */
+#define AES_EEPROM_DATA_1 0x00001814 /* AES EEPROM Data Register 1 */
+#define AES_EEPROM_DATA_2 0x00001818 /* AES EEPROM Data Register 2 */
+#define AES_EEPROM_DATA_3 0x0000181c /* AES EEPROM Data Register 3 */
+
+
+/****************************************************************************
+ * BCM70012_DCI_TOP_DCI
+ ***************************************************************************/
+#define DCI_CMD 0x00001c00 /* DCI Command Register */
+#define DCI_STATUS 0x00001c04 /* DCI Status Register */
+#define DCI_DRAM_BASE_ADDR 0x00001c08 /* DRAM Base Address Register */
+#define DCI_FIRMWARE_ADDR 0x00001c0c /* Firmware Address Register */
+#define DCI_FIRMWARE_DATA 0x00001c10 /* Firmware Data Register */
+#define DCI_SIGNATURE_DATA_0 0x00001c14 /* Signature Data Register 0 */
+#define DCI_SIGNATURE_DATA_1 0x00001c18 /* Signature Data Register 1 */
+#define DCI_SIGNATURE_DATA_2 0x00001c1c /* Signature Data Register 2 */
+#define DCI_SIGNATURE_DATA_3 0x00001c20 /* Signature Data Register 3 */
+#define DCI_SIGNATURE_DATA_4 0x00001c24 /* Signature Data Register 4 */
+#define DCI_SIGNATURE_DATA_5 0x00001c28 /* Signature Data Register 5 */
+#define DCI_SIGNATURE_DATA_6 0x00001c2c /* Signature Data Register 6 */
+#define DCI_SIGNATURE_DATA_7 0x00001c30 /* Signature Data Register 7 */
+
+
+/****************************************************************************
+ * BCM70012_TGT_TOP_INTR
+ ***************************************************************************/
+/****************************************************************************
+ * INTR :: INTR_STATUS
+ ***************************************************************************/
+/* INTR :: INTR_STATUS :: reserved0 [31:26] */
+#define INTR_INTR_STATUS_reserved0_MASK 0xfc000000
+#define INTR_INTR_STATUS_reserved0_ALIGN 0
+#define INTR_INTR_STATUS_reserved0_BITS 6
+#define INTR_INTR_STATUS_reserved0_SHIFT 26
+
+/* INTR :: INTR_STATUS :: PCIE_TGT_CA_ATTN [25:25] */
+#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_MASK 0x02000000
+#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_ALIGN 0
+#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_BITS 1
+#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_SHIFT 25
+
+/* INTR :: INTR_STATUS :: PCIE_TGT_UR_ATTN [24:24] */
+#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_MASK 0x01000000
+#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_ALIGN 0
+#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_BITS 1
+#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_SHIFT 24
+
+/* INTR :: INTR_STATUS :: reserved1 [23:14] */
+#define INTR_INTR_STATUS_reserved1_MASK 0x00ffc000
+#define INTR_INTR_STATUS_reserved1_ALIGN 0
+#define INTR_INTR_STATUS_reserved1_BITS 10
+#define INTR_INTR_STATUS_reserved1_SHIFT 14
+
+/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_ERR_INTR [13:13] */
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK 0x00002000
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_BITS 1
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_SHIFT 13
+
+/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_DONE_INTR [12:12] */
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK 0x00001000
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_BITS 1
+#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_SHIFT 12
+
+/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_ERR_INTR [11:11] */
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK 0x00000800
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_BITS 1
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_SHIFT 11
+
+/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_DONE_INTR [10:10] */
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK 0x00000400
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_BITS 1
+#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_SHIFT 10
+
+/* INTR :: INTR_STATUS :: L1_TX_DMA_ERR_INTR [09:09] */
+#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK 0x00000200
+#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_BITS 1
+#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_SHIFT 9
+
+/* INTR :: INTR_STATUS :: L1_TX_DMA_DONE_INTR [08:08] */
+#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK 0x00000100
+#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_BITS 1
+#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_SHIFT 8
+
+/* INTR :: INTR_STATUS :: reserved2 [07:06] */
+#define INTR_INTR_STATUS_reserved2_MASK 0x000000c0
+#define INTR_INTR_STATUS_reserved2_ALIGN 0
+#define INTR_INTR_STATUS_reserved2_BITS 2
+#define INTR_INTR_STATUS_reserved2_SHIFT 6
+
+/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_ERR_INTR [05:05] */
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK 0x00000020
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_BITS 1
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_SHIFT 5
+
+/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_DONE_INTR [04:04] */
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK 0x00000010
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_BITS 1
+#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_SHIFT 4
+
+/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_ERR_INTR [03:03] */
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK 0x00000008
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_BITS 1
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_SHIFT 3
+
+/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_DONE_INTR [02:02] */
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK 0x00000004
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_BITS 1
+#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_SHIFT 2
+
+/* INTR :: INTR_STATUS :: L0_TX_DMA_ERR_INTR [01:01] */
+#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK 0x00000002
+#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_BITS 1
+#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_SHIFT 1
+
+/* INTR :: INTR_STATUS :: L0_TX_DMA_DONE_INTR [00:00] */
+#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK 0x00000001
+#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_ALIGN 0
+#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_BITS 1
+#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_SHIFT 0
+
+
+/****************************************************************************
+ * MISC1 :: TX_SW_DESC_LIST_CTRL_STS
+ ***************************************************************************/
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: reserved0 [31:04] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_MASK 0xfffffff0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_ALIGN 0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_BITS 28
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_SHIFT 4
+
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DMA_DATA_SERV_PTR [03:03] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_MASK 0x00000008
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_ALIGN 0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_BITS 1
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_SHIFT 3
+
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DESC_SERV_PTR [02:02] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_MASK 0x00000004
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_ALIGN 0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_BITS 1
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_SHIFT 2
+
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_HALT_ON_ERROR [01:01] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_MASK 0x00000002
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_ALIGN 0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_BITS 1
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_SHIFT 1
+
+/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_RUN_STOP [00:00] */
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK 0x00000001
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_ALIGN 0
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_BITS 1
+#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_SHIFT 0
+
+
+/****************************************************************************
+ * MISC1 :: TX_DMA_ERROR_STATUS
+ ***************************************************************************/
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved0 [31:10] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved0_MASK 0xfffffc00
+#define MISC1_TX_DMA_ERROR_STATUS_reserved0_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved0_BITS 22
+#define MISC1_TX_DMA_ERROR_STATUS_reserved0_SHIFT 10
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DESC_TX_ABORT_ERRORS [09:09] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved1 [08:08] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved1_MASK 0x00000100
+#define MISC1_TX_DMA_ERROR_STATUS_reserved1_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved1_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_reserved1_SHIFT 8
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DESC_TX_ABORT_ERRORS [07:07] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved2 [06:06] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved2_MASK 0x00000040
+#define MISC1_TX_DMA_ERROR_STATUS_reserved2_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved2_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_reserved2_SHIFT 6
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DMA_DATA_TX_ABORT_ERRORS [05:05] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000020
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_SHIFT 5
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_FIFO_FULL_ERRORS [04:04] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_SHIFT 4
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved3 [03:03] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved3_MASK 0x00000008
+#define MISC1_TX_DMA_ERROR_STATUS_reserved3_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved3_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_reserved3_SHIFT 3
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DMA_DATA_TX_ABORT_ERRORS [02:02] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000004
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_SHIFT 2
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_FIFO_FULL_ERRORS [01:01] */
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_SHIFT 1
+
+/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved4 [00:00] */
+#define MISC1_TX_DMA_ERROR_STATUS_reserved4_MASK 0x00000001
+#define MISC1_TX_DMA_ERROR_STATUS_reserved4_ALIGN 0
+#define MISC1_TX_DMA_ERROR_STATUS_reserved4_BITS 1
+#define MISC1_TX_DMA_ERROR_STATUS_reserved4_SHIFT 0
+
+
+/****************************************************************************
+ * MISC1 :: Y_RX_ERROR_STATUS
+ ***************************************************************************/
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved0 [31:14] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved0_MASK 0xffffc000
+#define MISC1_Y_RX_ERROR_STATUS_reserved0_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_reserved0_BITS 18
+#define MISC1_Y_RX_ERROR_STATUS_reserved0_SHIFT 14
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK 0x00002000
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT 13
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK 0x00001000
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT 12
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK 0x00000800
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT 11
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK 0x00000400
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT 10
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved1 [08:08] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved1_MASK 0x00000100
+#define MISC1_Y_RX_ERROR_STATUS_reserved1_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_reserved1_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_reserved1_SHIFT 8
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved2 [06:05] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved2_MASK 0x00000060
+#define MISC1_Y_RX_ERROR_STATUS_reserved2_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_reserved2_BITS 2
+#define MISC1_Y_RX_ERROR_STATUS_reserved2_SHIFT 5
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT 4
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved3 [03:02] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved3_MASK 0x0000000c
+#define MISC1_Y_RX_ERROR_STATUS_reserved3_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_reserved3_BITS 2
+#define MISC1_Y_RX_ERROR_STATUS_reserved3_SHIFT 2
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT 1
+
+/* MISC1 :: Y_RX_ERROR_STATUS :: reserved4 [00:00] */
+#define MISC1_Y_RX_ERROR_STATUS_reserved4_MASK 0x00000001
+#define MISC1_Y_RX_ERROR_STATUS_reserved4_ALIGN 0
+#define MISC1_Y_RX_ERROR_STATUS_reserved4_BITS 1
+#define MISC1_Y_RX_ERROR_STATUS_reserved4_SHIFT 0
+
+
+/****************************************************************************
+ * MISC1 :: UV_RX_ERROR_STATUS
+ ***************************************************************************/
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved0 [31:14] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved0_MASK 0xffffc000
+#define MISC1_UV_RX_ERROR_STATUS_reserved0_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_reserved0_BITS 18
+#define MISC1_UV_RX_ERROR_STATUS_reserved0_SHIFT 14
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK 0x00002000
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT 13
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK 0x00001000
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT 12
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK 0x00000800
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT 11
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK 0x00000400
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT 10
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved1 [08:08] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved1_MASK 0x00000100
+#define MISC1_UV_RX_ERROR_STATUS_reserved1_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_reserved1_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_reserved1_SHIFT 8
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved2 [06:05] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved2_MASK 0x00000060
+#define MISC1_UV_RX_ERROR_STATUS_reserved2_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_reserved2_BITS 2
+#define MISC1_UV_RX_ERROR_STATUS_reserved2_SHIFT 5
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT 4
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved3 [03:02] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved3_MASK 0x0000000c
+#define MISC1_UV_RX_ERROR_STATUS_reserved3_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_reserved3_BITS 2
+#define MISC1_UV_RX_ERROR_STATUS_reserved3_SHIFT 2
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT 1
+
+/* MISC1 :: UV_RX_ERROR_STATUS :: reserved4 [00:00] */
+#define MISC1_UV_RX_ERROR_STATUS_reserved4_MASK 0x00000001
+#define MISC1_UV_RX_ERROR_STATUS_reserved4_ALIGN 0
+#define MISC1_UV_RX_ERROR_STATUS_reserved4_BITS 1
+#define MISC1_UV_RX_ERROR_STATUS_reserved4_SHIFT 0
+
+/****************************************************************************
+ * Datatype Definitions.
+ ***************************************************************************/
+#endif /* #ifndef MACFILE_H__ */
+
+/* End of File */
+
diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c
new file mode 100644
index 00000000000..26145a8d0f7
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_cmds.c
@@ -0,0 +1,1058 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_cmds . c
+ *
+ * Description:
+ * BCM70010 Linux driver user command interfaces.
+ *
+ * HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#include "crystalhd_cmds.h"
+#include "crystalhd_hw.h"
+
+static struct crystalhd_user *bc_cproc_get_uid(struct crystalhd_cmd *ctx)
+{
+ struct crystalhd_user *user = NULL;
+ int i;
+
+ for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+ if (!ctx->user[i].in_use) {
+ user = &ctx->user[i];
+ break;
+ }
+ }
+
+ return user;
+}
+
+static int bc_cproc_get_user_count(struct crystalhd_cmd *ctx)
+{
+ int i, count = 0;
+
+ for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+ if (ctx->user[i].in_use)
+ count++;
+ }
+
+ return count;
+}
+
+static void bc_cproc_mark_pwr_state(struct crystalhd_cmd *ctx)
+{
+ int i;
+
+ for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+ if (!ctx->user[i].in_use)
+ continue;
+ if (ctx->user[i].mode == DTS_DIAG_MODE ||
+ ctx->user[i].mode == DTS_PLAYBACK_MODE) {
+ ctx->pwr_state_change = 1;
+ break;
+ }
+ }
+}
+
+static BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ int rc = 0, i = 0;
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (ctx->user[idata->u_id].mode != DTS_MODE_INV) {
+ BCMLOG_ERR("Close the handle first..\n");
+ return BC_STS_ERR_USAGE;
+ }
+ if (idata->udata.u.NotifyMode.Mode == DTS_MONITOR_MODE) {
+ ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
+ return BC_STS_SUCCESS;
+ }
+ if (ctx->state != BC_LINK_INVALID) {
+ BCMLOG_ERR("Link invalid state %d \n", ctx->state);
+ return BC_STS_ERR_USAGE;
+ }
+ /* Check for duplicate playback sessions..*/
+ for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+ if (ctx->user[i].mode == DTS_DIAG_MODE ||
+ ctx->user[i].mode == DTS_PLAYBACK_MODE) {
+ BCMLOG_ERR("multiple playback sessions are not "
+ "supported..\n");
+ return BC_STS_ERR_USAGE;
+ }
+ }
+ ctx->cin_wait_exit = 0;
+ ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
+ /* Setup mmap pool for uaddr sgl mapping..*/
+ rc = crystalhd_create_dio_pool(ctx->adp, BC_LINK_MAX_SGLS);
+ if (rc)
+ return BC_STS_ERROR;
+
+ /* Setup Hardware DMA rings */
+ return crystalhd_hw_setup_dma_rings(&ctx->hw_ctx);
+}
+
+static BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+ idata->udata.u.VerInfo.DriverMajor = crystalhd_kmod_major;
+ idata->udata.u.VerInfo.DriverMinor = crystalhd_kmod_minor;
+ idata->udata.u.VerInfo.DriverRevision = crystalhd_kmod_rev;
+ return BC_STS_SUCCESS;
+}
+
+
+static BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
+{
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ crystalhd_pci_cfg_rd(ctx->adp, 0, 2,
+ (uint32_t *)&idata->udata.u.hwType.PciVenId);
+ crystalhd_pci_cfg_rd(ctx->adp, 2, 2,
+ (uint32_t *)&idata->udata.u.hwType.PciDevId);
+ crystalhd_pci_cfg_rd(ctx->adp, 8, 1,
+ (uint32_t *)&idata->udata.u.hwType.HwRev);
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ if (!ctx || !idata)
+ return BC_STS_INV_ARG;
+ idata->udata.u.regAcc.Value = bc_dec_reg_rd(ctx->adp,
+ idata->udata.u.regAcc.Offset);
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ if (!ctx || !idata)
+ return BC_STS_INV_ARG;
+
+ bc_dec_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
+ idata->udata.u.regAcc.Value);
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ if (!ctx || !idata)
+ return BC_STS_INV_ARG;
+
+ idata->udata.u.regAcc.Value = crystalhd_reg_rd(ctx->adp,
+ idata->udata.u.regAcc.Offset);
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ if (!ctx || !idata)
+ return BC_STS_INV_ARG;
+
+ crystalhd_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
+ idata->udata.u.regAcc.Value);
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!ctx || !idata || !idata->add_cdata)
+ return BC_STS_INV_ARG;
+
+ if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
+ BCMLOG_ERR("insufficient buffer\n");
+ return BC_STS_INV_ARG;
+ }
+ sts = crystalhd_mem_rd(ctx->adp, idata->udata.u.devMem.StartOff,
+ idata->udata.u.devMem.NumDwords,
+ (uint32_t *)idata->add_cdata);
+ return sts;
+
+}
+
+static BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!ctx || !idata || !idata->add_cdata)
+ return BC_STS_INV_ARG;
+
+ if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
+ BCMLOG_ERR("insufficient buffer\n");
+ return BC_STS_INV_ARG;
+ }
+
+ sts = crystalhd_mem_wr(ctx->adp, idata->udata.u.devMem.StartOff,
+ idata->udata.u.devMem.NumDwords,
+ (uint32_t *)idata->add_cdata);
+ return sts;
+}
+
+static BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ uint32_t ix, cnt, off, len;
+ BC_STATUS sts = BC_STS_SUCCESS;
+ uint32_t *temp;
+
+ if (!ctx || !idata)
+ return BC_STS_INV_ARG;
+
+ temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
+ off = idata->udata.u.pciCfg.Offset;
+ len = idata->udata.u.pciCfg.Size;
+
+ if (len <= 4)
+ return crystalhd_pci_cfg_rd(ctx->adp, off, len, temp);
+
+ /* Truncate to dword alignment..*/
+ len = 4;
+ cnt = idata->udata.u.pciCfg.Size / len;
+ for (ix = 0; ix < cnt; ix++) {
+ sts = crystalhd_pci_cfg_rd(ctx->adp, off, len, &temp[ix]);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("config read : %d\n", sts);
+ return sts;
+ }
+ off += len;
+ }
+
+ return sts;
+}
+
+static BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ uint32_t ix, cnt, off, len;
+ BC_STATUS sts = BC_STS_SUCCESS;
+ uint32_t *temp;
+
+ if (!ctx || !idata)
+ return BC_STS_INV_ARG;
+
+ temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
+ off = idata->udata.u.pciCfg.Offset;
+ len = idata->udata.u.pciCfg.Size;
+
+ if (len <= 4)
+ return crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[0]);
+
+ /* Truncate to dword alignment..*/
+ len = 4;
+ cnt = idata->udata.u.pciCfg.Size / len;
+ for (ix = 0; ix < cnt; ix++) {
+ sts = crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[ix]);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("config write : %d\n", sts);
+ return sts;
+ }
+ off += len;
+ }
+
+ return sts;
+}
+
+static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (ctx->state != BC_LINK_INVALID) {
+ BCMLOG_ERR("Link invalid state %d \n", ctx->state);
+ return BC_STS_ERR_USAGE;
+ }
+
+ sts = crystalhd_download_fw(ctx->adp, (uint8_t *)idata->add_cdata,
+ idata->add_cdata_sz);
+
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts);
+ } else
+ ctx->state |= BC_LINK_INIT;
+
+ return sts;
+}
+
+/*
+ * We use the FW_CMD interface to sync up playback state with application
+ * and firmware. This function will perform the required pre and post
+ * processing of the Firmware commands.
+ *
+ * Pause -
+ * Disable capture after decoder pause.
+ * Resume -
+ * First enable capture and issue decoder resume command.
+ * Flush -
+ * Abort pending input transfers and issue decoder flush command.
+ *
+ */
+static BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
+{
+ BC_STATUS sts;
+ uint32_t *cmd;
+
+ if (!(ctx->state & BC_LINK_INIT)) {
+ BCMLOG_ERR("Link invalid state %d \n", ctx->state);
+ return BC_STS_ERR_USAGE;
+ }
+
+ cmd = idata->udata.u.fwCmd.cmd;
+
+ /* Pre-Process */
+ if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
+ if (!cmd[3]) {
+ ctx->state &= ~BC_LINK_PAUSED;
+ crystalhd_hw_unpause(&ctx->hw_ctx);
+ }
+ } else if (cmd[0] == eCMD_C011_DEC_CHAN_FLUSH) {
+ BCMLOG(BCMLOG_INFO, "Flush issued\n");
+ if (cmd[3])
+ ctx->cin_wait_exit = 1;
+ }
+
+ sts = crystalhd_do_fw_cmd(&ctx->hw_ctx, &idata->udata.u.fwCmd);
+
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG(BCMLOG_INFO, "fw cmd %x failed\n", cmd[0]);
+ return sts;
+ }
+
+ /* Post-Process */
+ if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
+ if (cmd[3]) {
+ ctx->state |= BC_LINK_PAUSED;
+ crystalhd_hw_pause(&ctx->hw_ctx);
+ }
+ }
+
+ return sts;
+}
+
+static void bc_proc_in_completion(crystalhd_dio_req *dio_hnd,
+ wait_queue_head_t *event, BC_STATUS sts)
+{
+ if (!dio_hnd || !event) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return;
+ }
+ if (sts == BC_STS_IO_USER_ABORT)
+ return;
+
+ dio_hnd->uinfo.comp_sts = sts;
+ dio_hnd->uinfo.ev_sts = 1;
+ crystalhd_set_event(event);
+}
+
+static BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx)
+{
+ wait_queue_head_t sleep_ev;
+ int rc = 0;
+
+ if (ctx->state & BC_LINK_SUSPEND)
+ return BC_STS_IO_USER_ABORT;
+
+ if (ctx->cin_wait_exit) {
+ ctx->cin_wait_exit = 0;
+ return BC_STS_CMD_CANCELLED;
+ }
+ crystalhd_create_event(&sleep_ev);
+ crystalhd_wait_on_event(&sleep_ev, 0, 100, rc, 0);
+ if (rc == -EINTR)
+ return BC_STS_IO_USER_ABORT;
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata,
+ crystalhd_dio_req *dio)
+{
+ uint32_t tx_listid = 0;
+ BC_STATUS sts = BC_STS_SUCCESS;
+ wait_queue_head_t event;
+ int rc = 0;
+
+ if (!ctx || !idata || !dio) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ crystalhd_create_event(&event);
+
+ ctx->tx_list_id = 0;
+ /* msleep_interruptible(2000); */
+ sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio, bc_proc_in_completion,
+ &event, &tx_listid,
+ idata->udata.u.ProcInput.Encrypted);
+
+ while (sts == BC_STS_BUSY) {
+ sts = bc_cproc_codein_sleep(ctx);
+ if (sts != BC_STS_SUCCESS)
+ break;
+ sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio,
+ bc_proc_in_completion,
+ &event, &tx_listid,
+ idata->udata.u.ProcInput.Encrypted);
+ }
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG(BCMLOG_DBG, "_hw_txdma returning sts:%d\n", sts);
+ return sts;
+ }
+ if (ctx->cin_wait_exit)
+ ctx->cin_wait_exit = 0;
+
+ ctx->tx_list_id = tx_listid;
+
+ /* _post() succeeded.. wait for the completion. */
+ crystalhd_wait_on_event(&event, (dio->uinfo.ev_sts), 3000, rc, 0);
+ ctx->tx_list_id = 0;
+ if (!rc) {
+ return dio->uinfo.comp_sts;
+ } else if (rc == -EBUSY) {
+ BCMLOG(BCMLOG_DBG, "_tx_post() T/O \n");
+ sts = BC_STS_TIMEOUT;
+ } else if (rc == -EINTR) {
+ BCMLOG(BCMLOG_DBG, "Tx Wait Signal int.\n");
+ sts = BC_STS_IO_USER_ABORT;
+ } else {
+ sts = BC_STS_IO_ERROR;
+ }
+
+ /* We are cancelling the IO from the same context as the _post().
+ * so no need to wait on the event again.. the return itself
+ * ensures the release of our resources.
+ */
+ crystalhd_hw_cancel_tx(&ctx->hw_ctx, tx_listid);
+
+ return sts;
+}
+
+/* Helper function to check on user buffers */
+static BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz,
+ uint32_t uv_off, bool en_422)
+{
+ if (!ubuff || !ub_sz) {
+ BCMLOG_ERR("%s->Invalid Arg %p %x\n",
+ ((pin) ? "TX" : "RX"), ubuff, ub_sz);
+ return BC_STS_INV_ARG;
+ }
+
+ /* Check for alignment */
+ if (((uintptr_t)ubuff) & 0x03) {
+ BCMLOG_ERR("%s-->Un-aligned address not implemented yet.. %p \n",
+ ((pin) ? "TX" : "RX"), ubuff);
+ return BC_STS_NOT_IMPL;
+ }
+ if (pin)
+ return BC_STS_SUCCESS;
+
+ if (!en_422 && !uv_off) {
+ BCMLOG_ERR("Need UV offset for 420 mode.\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (en_422 && uv_off) {
+ BCMLOG_ERR("UV offset in 422 mode ??\n");
+ return BC_STS_INV_ARG;
+ }
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
+{
+ void *ubuff;
+ uint32_t ub_sz;
+ crystalhd_dio_req *dio_hnd = NULL;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ ubuff = idata->udata.u.ProcInput.pDmaBuff;
+ ub_sz = idata->udata.u.ProcInput.BuffSz;
+
+ sts = bc_cproc_check_inbuffs(1, ubuff, ub_sz, 0, 0);
+ if (sts != BC_STS_SUCCESS)
+ return sts;
+
+ sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, 0, 0, 1, &dio_hnd);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("dio map - %d \n", sts);
+ return sts;
+ }
+
+ if (!dio_hnd)
+ return BC_STS_ERROR;
+
+ sts = bc_cproc_hw_txdma(ctx, idata, dio_hnd);
+
+ crystalhd_unmap_dio(ctx->adp, dio_hnd);
+
+ return sts;
+}
+
+static BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ void *ubuff;
+ uint32_t ub_sz, uv_off;
+ bool en_422;
+ crystalhd_dio_req *dio_hnd = NULL;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ ubuff = idata->udata.u.RxBuffs.YuvBuff;
+ ub_sz = idata->udata.u.RxBuffs.YuvBuffSz;
+ uv_off = idata->udata.u.RxBuffs.UVbuffOffset;
+ en_422 = idata->udata.u.RxBuffs.b422Mode;
+
+ sts = bc_cproc_check_inbuffs(0, ubuff, ub_sz, uv_off, en_422);
+ if (sts != BC_STS_SUCCESS)
+ return sts;
+
+ sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, uv_off,
+ en_422, 0, &dio_hnd);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("dio map - %d \n", sts);
+ return sts;
+ }
+
+ if (!dio_hnd)
+ return BC_STS_ERROR;
+
+ sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio_hnd, (ctx->state == BC_LINK_READY));
+ if ((sts != BC_STS_SUCCESS) && (sts != BC_STS_BUSY)) {
+ crystalhd_unmap_dio(ctx->adp, dio_hnd);
+ return sts;
+ }
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx,
+ crystalhd_dio_req *dio)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio, 0);
+ if (sts != BC_STS_SUCCESS)
+ return sts;
+
+ ctx->state |= BC_LINK_FMT_CHG;
+ if (ctx->state == BC_LINK_READY)
+ sts = crystalhd_hw_start_capture(&ctx->hw_ctx);
+
+ return sts;
+}
+
+static BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ crystalhd_dio_req *dio = NULL;
+ BC_STATUS sts = BC_STS_SUCCESS;
+ BC_DEC_OUT_BUFF *frame;
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (!(ctx->state & BC_LINK_CAP_EN)) {
+ BCMLOG(BCMLOG_DBG, "Capture not enabled..%x\n", ctx->state);
+ return BC_STS_ERR_USAGE;
+ }
+
+ frame = &idata->udata.u.DecOutData;
+
+ sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
+ if (sts != BC_STS_SUCCESS)
+ return (ctx->state & BC_LINK_SUSPEND) ? BC_STS_IO_USER_ABORT : sts;
+
+ frame->Flags = dio->uinfo.comp_flags;
+
+ if (frame->Flags & COMP_FLAG_FMT_CHANGE)
+ return bc_cproc_fmt_change(ctx, dio);
+
+ frame->OutPutBuffs.YuvBuff = dio->uinfo.xfr_buff;
+ frame->OutPutBuffs.YuvBuffSz = dio->uinfo.xfr_len;
+ frame->OutPutBuffs.UVbuffOffset = dio->uinfo.uv_offset;
+ frame->OutPutBuffs.b422Mode = dio->uinfo.b422mode;
+
+ frame->OutPutBuffs.YBuffDoneSz = dio->uinfo.y_done_sz;
+ frame->OutPutBuffs.UVBuffDoneSz = dio->uinfo.uv_done_sz;
+
+ crystalhd_unmap_dio(ctx->adp, dio);
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ ctx->state |= BC_LINK_CAP_EN;
+ if (ctx->state == BC_LINK_READY)
+ return crystalhd_hw_start_capture(&ctx->hw_ctx);
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ crystalhd_dio_req *dio = NULL;
+ BC_STATUS sts = BC_STS_SUCCESS;
+ BC_DEC_OUT_BUFF *frame;
+ uint32_t count;
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (!(ctx->state & BC_LINK_CAP_EN))
+ return BC_STS_ERR_USAGE;
+
+ /* We should ack flush even when we are in paused/suspend state */
+ if (!(ctx->state & BC_LINK_READY))
+ return crystalhd_hw_stop_capture(&ctx->hw_ctx);
+
+ ctx->state &= ~(BC_LINK_CAP_EN|BC_LINK_FMT_CHG);
+
+ frame = &idata->udata.u.DecOutData;
+ for (count = 0; count < BC_RX_LIST_CNT; count++) {
+
+ sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
+ if (sts != BC_STS_SUCCESS)
+ break;
+
+ crystalhd_unmap_dio(ctx->adp, dio);
+ }
+
+ return crystalhd_hw_stop_capture(&ctx->hw_ctx);
+}
+
+static BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ BC_DTS_STATS *stats;
+ struct crystalhd_hw_stats hw_stats;
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ crystalhd_hw_stats(&ctx->hw_ctx, &hw_stats);
+
+ stats = &idata->udata.u.drvStat;
+ stats->drvRLL = hw_stats.rdyq_count;
+ stats->drvFLL = hw_stats.freeq_count;
+ stats->DrvTotalFrmDropped = hw_stats.rx_errors;
+ stats->DrvTotalHWErrs = hw_stats.rx_errors + hw_stats.tx_errors;
+ stats->intCount = hw_stats.num_interrupts;
+ stats->DrvIgnIntrCnt = hw_stats.num_interrupts -
+ hw_stats.dev_interrupts;
+ stats->TxFifoBsyCnt = hw_stats.cin_busy;
+ stats->pauseCount = hw_stats.pause_cnt;
+
+ if (ctx->pwr_state_change)
+ stats->pwr_state_change = 1;
+ if (ctx->state & BC_LINK_PAUSED)
+ stats->DrvPauseTime = 1;
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ crystalhd_hw_stats(&ctx->hw_ctx, NULL);
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx,
+ crystalhd_ioctl_data *idata)
+{
+ BC_CLOCK *clock;
+ uint32_t oldClk;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ clock = &idata->udata.u.clockValue;
+ oldClk = ctx->hw_ctx.core_clock_mhz;
+ ctx->hw_ctx.core_clock_mhz = clock->clk;
+
+ if (ctx->state & BC_LINK_READY) {
+ sts = crystalhd_hw_set_core_clock(&ctx->hw_ctx);
+ if (sts == BC_STS_CLK_NOCHG)
+ ctx->hw_ctx.core_clock_mhz = oldClk;
+ }
+
+ clock->clk = ctx->hw_ctx.core_clock_mhz;
+
+ return sts;
+}
+
+/*=============== Cmd Proc Table.. ======================================*/
+static const crystalhd_cmd_tbl_t g_crystalhd_cproc_tbl[] = {
+ { BCM_IOC_GET_VERSION, bc_cproc_get_version, 0},
+ { BCM_IOC_GET_HWTYPE, bc_cproc_get_hwtype, 0},
+ { BCM_IOC_REG_RD, bc_cproc_reg_rd, 0},
+ { BCM_IOC_REG_WR, bc_cproc_reg_wr, 0},
+ { BCM_IOC_FPGA_RD, bc_cproc_link_reg_rd, 0},
+ { BCM_IOC_FPGA_WR, bc_cproc_link_reg_wr, 0},
+ { BCM_IOC_MEM_RD, bc_cproc_mem_rd, 0},
+ { BCM_IOC_MEM_WR, bc_cproc_mem_wr, 0},
+ { BCM_IOC_RD_PCI_CFG, bc_cproc_cfg_rd, 0},
+ { BCM_IOC_WR_PCI_CFG, bc_cproc_cfg_wr, 1},
+ { BCM_IOC_FW_DOWNLOAD, bc_cproc_download_fw, 1},
+ { BCM_IOC_FW_CMD, bc_cproc_do_fw_cmd, 1},
+ { BCM_IOC_PROC_INPUT, bc_cproc_proc_input, 1},
+ { BCM_IOC_ADD_RXBUFFS, bc_cproc_add_cap_buff, 1},
+ { BCM_IOC_FETCH_RXBUFF, bc_cproc_fetch_frame, 1},
+ { BCM_IOC_START_RX_CAP, bc_cproc_start_capture, 1},
+ { BCM_IOC_FLUSH_RX_CAP, bc_cproc_flush_cap_buffs, 1},
+ { BCM_IOC_GET_DRV_STAT, bc_cproc_get_stats, 0},
+ { BCM_IOC_RST_DRV_STAT, bc_cproc_reset_stats, 0},
+ { BCM_IOC_NOTIFY_MODE, bc_cproc_notify_mode, 0},
+ { BCM_IOC_CHG_CLK, bc_cproc_chg_clk, 0},
+ { BCM_IOC_END, NULL},
+};
+
+/*=============== Cmd Proc Functions.. ===================================*/
+
+/**
+ * crystalhd_suspend - Power management suspend request.
+ * @ctx: Command layer context.
+ * @idata: Iodata - required for internal use.
+ *
+ * Return:
+ * status
+ *
+ * 1. Set the state to Suspend.
+ * 2. Flush the Rx Buffers it will unmap all the buffers and
+ * stop the RxDMA engine.
+ * 3. Cancel The TX Io and Stop Dma Engine.
+ * 4. Put the DDR in to deep sleep.
+ * 5. Stop the hardware putting it in to Reset State.
+ *
+ * Current gstreamer frame work does not provide any power management
+ * related notification to user mode decoder plug-in. As a work-around
+ * we pass on the power mangement notification to our plug-in by completing
+ * all outstanding requests with BC_STS_IO_USER_ABORT return code.
+ */
+BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!ctx || !idata) {
+ BCMLOG_ERR("Invalid Parameters\n");
+ return BC_STS_ERROR;
+ }
+
+ if (ctx->state & BC_LINK_SUSPEND)
+ return BC_STS_SUCCESS;
+
+ if (ctx->state == BC_LINK_INVALID) {
+ BCMLOG(BCMLOG_DBG, "Nothing To Do Suspend Success\n");
+ return BC_STS_SUCCESS;
+ }
+
+ ctx->state |= BC_LINK_SUSPEND;
+
+ bc_cproc_mark_pwr_state(ctx);
+
+ if (ctx->state & BC_LINK_CAP_EN) {
+ sts = bc_cproc_flush_cap_buffs(ctx, idata);
+ if (sts != BC_STS_SUCCESS)
+ return sts;
+ }
+
+ if (ctx->tx_list_id) {
+ sts = crystalhd_hw_cancel_tx(&ctx->hw_ctx, ctx->tx_list_id);
+ if (sts != BC_STS_SUCCESS)
+ return sts;
+ }
+
+ sts = crystalhd_hw_suspend(&ctx->hw_ctx);
+ if (sts != BC_STS_SUCCESS)
+ return sts;
+
+ BCMLOG(BCMLOG_DBG, "BCM70012 suspend success\n");
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_resume - Resume frame capture.
+ * @ctx: Command layer contextx.
+ *
+ * Return:
+ * status
+ *
+ *
+ * Resume frame capture.
+ *
+ * PM_Resume can't resume the playback state back to pre-suspend state
+ * because we don't keep video clip related information within driver.
+ * To get back to the pre-suspend state App will re-open the device and
+ * start a new playback session from the pre-suspend clip position.
+ *
+ */
+BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx)
+{
+ BCMLOG(BCMLOG_DBG, "crystalhd_resume Success %x\n", ctx->state);
+
+ bc_cproc_mark_pwr_state(ctx);
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_user_open - Create application handle.
+ * @ctx: Command layer contextx.
+ * @user_ctx: User ID context.
+ *
+ * Return:
+ * status
+ *
+ * Creates an application specific UID and allocates
+ * application specific resources. HW layer initialization
+ * is done for the first open request.
+ */
+BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
+ struct crystalhd_user **user_ctx)
+{
+ struct crystalhd_user *uc;
+
+ if (!ctx || !user_ctx) {
+ BCMLOG_ERR("Invalid arg..\n");
+ return BC_STS_INV_ARG;
+ }
+
+ uc = bc_cproc_get_uid(ctx);
+ if (!uc) {
+ BCMLOG(BCMLOG_INFO, "No free user context...\n");
+ return BC_STS_BUSY;
+ }
+
+ BCMLOG(BCMLOG_INFO, "Opening new user[%x] handle\n", uc->uid);
+
+ crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
+
+ uc->in_use = 1;
+
+ *user_ctx = uc;
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_user_close - Close application handle.
+ * @ctx: Command layer contextx.
+ * @uc: User ID context.
+ *
+ * Return:
+ * status
+ *
+ * Closer aplication handle and release app specific
+ * resources.
+ */
+BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc)
+{
+ uint32_t mode = uc->mode;
+
+ ctx->user[uc->uid].mode = DTS_MODE_INV;
+ ctx->user[uc->uid].in_use = 0;
+ ctx->cin_wait_exit = 1;
+ ctx->pwr_state_change = 0;
+
+ BCMLOG(BCMLOG_INFO, "Closing user[%x] handle\n", uc->uid);
+
+ if ((mode == DTS_DIAG_MODE) || (mode == DTS_PLAYBACK_MODE)) {
+ crystalhd_hw_free_dma_rings(&ctx->hw_ctx);
+ crystalhd_destroy_dio_pool(ctx->adp);
+ } else if (bc_cproc_get_user_count(ctx)) {
+ return BC_STS_SUCCESS;
+ }
+
+ crystalhd_hw_close(&ctx->hw_ctx);
+
+ ctx->state = BC_LINK_INVALID;
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_setup_cmd_context - Setup Command layer resources.
+ * @ctx: Command layer contextx.
+ * @adp: Adapter context
+ *
+ * Return:
+ * status
+ *
+ * Called at the time of driver load.
+ */
+BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
+ struct crystalhd_adp *adp)
+{
+ int i = 0;
+
+ if (!ctx || !adp) {
+ BCMLOG_ERR("Invalid arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (ctx->adp)
+ BCMLOG(BCMLOG_DBG, "Resetting Cmd context delete missing..\n");
+
+ ctx->adp = adp;
+ for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
+ ctx->user[i].uid = i;
+ ctx->user[i].in_use = 0;
+ ctx->user[i].mode = DTS_MODE_INV;
+ }
+
+ /*Open and Close the Hardware to put it in to sleep state*/
+ crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
+ crystalhd_hw_close(&ctx->hw_ctx);
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_delete_cmd_context - Release Command layer resources.
+ * @ctx: Command layer contextx.
+ *
+ * Return:
+ * status
+ *
+ * Called at the time of driver un-load.
+ */
+BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
+{
+ BCMLOG(BCMLOG_DBG, "Deleting Command context..\n");
+
+ ctx->adp = NULL;
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_get_cmd_proc - Cproc table lookup.
+ * @ctx: Command layer contextx.
+ * @cmd: IOCTL command code.
+ * @uc: User ID context.
+ *
+ * Return:
+ * command proc function pointer
+ *
+ * This function checks the process context, application's
+ * mode of operation and returns the function pointer
+ * from the cproc table.
+ */
+crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
+ struct crystalhd_user *uc)
+{
+ crystalhd_cmd_proc cproc = NULL;
+ unsigned int i, tbl_sz;
+
+ if (!ctx) {
+ BCMLOG_ERR("Invalid arg.. Cmd[%d]\n", cmd);
+ return NULL;
+ }
+
+ if ((cmd != BCM_IOC_GET_DRV_STAT) && (ctx->state & BC_LINK_SUSPEND)) {
+ BCMLOG_ERR("Invalid State [suspend Set].. Cmd[%d]\n", cmd);
+ return NULL;
+ }
+
+ tbl_sz = sizeof(g_crystalhd_cproc_tbl) / sizeof(crystalhd_cmd_tbl_t);
+ for (i = 0; i < tbl_sz; i++) {
+ if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) {
+ if ((uc->mode == DTS_MONITOR_MODE) &&
+ (g_crystalhd_cproc_tbl[i].block_mon)) {
+ BCMLOG(BCMLOG_INFO, "Blocking cmd %d \n", cmd);
+ break;
+ }
+ cproc = g_crystalhd_cproc_tbl[i].cmd_proc;
+ break;
+ }
+ }
+
+ return cproc;
+}
+
+/**
+ * crystalhd_cmd_interrupt - ISR entry point
+ * @ctx: Command layer contextx.
+ *
+ * Return:
+ * TRUE: If interrupt from bcm70012 device.
+ *
+ *
+ * ISR entry point from OS layer.
+ */
+bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx)
+{
+ if (!ctx) {
+ BCMLOG_ERR("Invalid arg..\n");
+ return 0;
+ }
+
+ return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx);
+}
diff --git a/drivers/staging/crystalhd/crystalhd_cmds.h b/drivers/staging/crystalhd/crystalhd_cmds.h
new file mode 100644
index 00000000000..6b290aed8e0
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_cmds.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_cmds . h
+ *
+ * Description:
+ * BCM70010 Linux driver user command interfaces.
+ *
+ * HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_CMDS_H_
+#define _CRYSTALHD_CMDS_H_
+
+/*
+ * NOTE:: This is the main interface file between the Linux layer
+ * and the harware layer. This file will use the definitions
+ * from _dts_glob and dts_defs etc.. which are defined for
+ * windows.
+ */
+#include "crystalhd_misc.h"
+#include "crystalhd_hw.h"
+
+enum _crystalhd_state{
+ BC_LINK_INVALID = 0x00,
+ BC_LINK_INIT = 0x01,
+ BC_LINK_CAP_EN = 0x02,
+ BC_LINK_FMT_CHG = 0x04,
+ BC_LINK_SUSPEND = 0x10,
+ BC_LINK_PAUSED = 0x20,
+ BC_LINK_READY = (BC_LINK_INIT | BC_LINK_CAP_EN | BC_LINK_FMT_CHG),
+};
+
+struct crystalhd_user {
+ uint32_t uid;
+ uint32_t in_use;
+ uint32_t mode;
+};
+
+#define DTS_MODE_INV (-1)
+
+struct crystalhd_cmd {
+ uint32_t state;
+ struct crystalhd_adp *adp;
+ struct crystalhd_user user[BC_LINK_MAX_OPENS];
+
+ spinlock_t ctx_lock;
+ uint32_t tx_list_id;
+ uint32_t cin_wait_exit;
+ uint32_t pwr_state_change;
+ struct crystalhd_hw hw_ctx;
+};
+
+typedef BC_STATUS (*crystalhd_cmd_proc)(struct crystalhd_cmd *, crystalhd_ioctl_data *);
+
+typedef struct _crystalhd_cmd_tbl {
+ uint32_t cmd_id;
+ const crystalhd_cmd_proc cmd_proc;
+ uint32_t block_mon;
+} crystalhd_cmd_tbl_t;
+
+
+BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata);
+BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx);
+crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
+ struct crystalhd_user *uc);
+BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, struct crystalhd_user **user_ctx);
+BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc);
+BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, struct crystalhd_adp *adp);
+BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx);
+bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx);
+
+#endif
diff --git a/drivers/staging/crystalhd/crystalhd_fw_if.h b/drivers/staging/crystalhd/crystalhd_fw_if.h
new file mode 100644
index 00000000000..261cd19a0ee
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_fw_if.h
@@ -0,0 +1,369 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_fw_if . h
+ *
+ * Description:
+ * BCM70012 Firmware interface definitions.
+ *
+ * HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_FW_IF_H_
+#define _CRYSTALHD_FW_IF_H_
+
+/* TBD: Pull in only required defs into this file.. */
+
+
+
+/* User Data Header */
+typedef struct user_data {
+ struct user_data *next;
+ uint32_t type;
+ uint32_t size;
+} UD_HDR;
+
+
+
+/*------------------------------------------------------*
+ * MPEG Extension to the PPB *
+ *------------------------------------------------------*/
+typedef struct {
+ uint32_t to_be_defined;
+ uint32_t valid;
+
+ /* Always valid, defaults to picture size if no
+ sequence display extension in the stream. */
+ uint32_t display_horizontal_size;
+ uint32_t display_vertical_size;
+
+ /* MPEG_VALID_PANSCAN
+ Offsets are a copy values from the MPEG stream. */
+ uint32_t offset_count;
+ int32_t horizontal_offset[3];
+ int32_t vertical_offset[3];
+
+ /* MPEG_VALID_USERDATA
+ User data is in the form of a linked list. */
+ int32_t userDataSize;
+ UD_HDR *userData;
+
+} PPB_MPEG;
+
+
+/*------------------------------------------------------*
+ * VC1 Extension to the PPB *
+ *------------------------------------------------------*/
+typedef struct {
+ uint32_t to_be_defined;
+ uint32_t valid;
+
+ /* Always valid, defaults to picture size if no
+ sequence display extension in the stream. */
+ uint32_t display_horizontal_size;
+ uint32_t display_vertical_size;
+
+ /* VC1 pan scan windows */
+ uint32_t num_panscan_windows;
+ int32_t ps_horiz_offset[4];
+ int32_t ps_vert_offset[4];
+ int32_t ps_width[4];
+ int32_t ps_height[4];
+
+ /* VC1_VALID_USERDATA
+ User data is in the form of a linked list. */
+ int32_t userDataSize;
+ UD_HDR *userData;
+
+} PPB_VC1;
+
+/*------------------------------------------------------*
+ * H.264 Extension to the PPB *
+ *------------------------------------------------------*/
+
+/**
+ * @brief Film grain SEI message.
+ *
+ * Content of the film grain SEI message.
+ */
+
+/* maximum number of model-values as for Thomson spec(standard says 5) */
+#define MAX_FGT_MODEL_VALUE (3)
+
+/* maximum number of intervals(as many as 256 intervals?) */
+#define MAX_FGT_VALUE_INTERVAL (256)
+
+typedef struct FGT_SEI {
+ struct FGT_SEI *next;
+ unsigned char model_values[3][MAX_FGT_VALUE_INTERVAL][MAX_FGT_MODEL_VALUE];
+ unsigned char upper_bound[3][MAX_FGT_VALUE_INTERVAL];
+ unsigned char lower_bound[3][MAX_FGT_VALUE_INTERVAL];
+
+ unsigned char cancel_flag; /* Cancel flag: 1 no film grain. */
+ unsigned char model_id; /* Model id. */
+
+ /* +unused SE based on Thomson spec */
+ unsigned char color_desc_flag; /* Separate color descrition flag. */
+ unsigned char bit_depth_luma; /* Bit depth luma minus 8. */
+ unsigned char bit_depth_chroma; /* Bit depth chroma minus 8. */
+ unsigned char full_range_flag; /* Full range flag. */
+ unsigned char color_primaries; /* Color primaries. */
+ unsigned char transfer_charact; /* Transfer characteristics. */
+ unsigned char matrix_coeff; /*< Matrix coefficients. */
+ /* -unused SE based on Thomson spec */
+
+ unsigned char blending_mode_id; /* Blending mode. */
+ unsigned char log2_scale_factor; /* Log2 scale factor (2-7). */
+ unsigned char comp_flag[3]; /* Components [0,2] parameters present flag. */
+ unsigned char num_intervals_minus1[3]; /* Number of intensity level intervals. */
+ unsigned char num_model_values[3]; /* Number of model values. */
+ uint16_t repetition_period; /* Repetition period (0-16384) */
+
+} FGT_SEI;
+
+typedef struct {
+ /* 'valid' specifies which fields (or sets of
+ * fields) below are valid. If the corresponding
+ * bit in 'valid' is NOT set then that field(s)
+ * is (are) not initialized. */
+ uint32_t valid;
+
+ int32_t poc_top; /* POC for Top Field/Frame */
+ int32_t poc_bottom; /* POC for Bottom Field */
+ uint32_t idr_pic_id;
+
+ /* H264_VALID_PANSCAN */
+ uint32_t pan_scan_count;
+ int32_t pan_scan_left[3];
+ int32_t pan_scan_right[3];
+ int32_t pan_scan_top[3];
+ int32_t pan_scan_bottom[3];
+
+ /* H264_VALID_CT_TYPE */
+ uint32_t ct_type_count;
+ uint32_t ct_type[3];
+
+ /* H264_VALID_SPS_CROP */
+ int32_t sps_crop_left;
+ int32_t sps_crop_right;
+ int32_t sps_crop_top;
+ int32_t sps_crop_bottom;
+
+ /* H264_VALID_VUI */
+ uint32_t chroma_top;
+ uint32_t chroma_bottom;
+
+ /* H264_VALID_USER */
+ uint32_t user_data_size;
+ UD_HDR *user_data;
+
+ /* H264 VALID FGT */
+ FGT_SEI *pfgt;
+
+} PPB_H264;
+
+typedef struct {
+ /* Common fields. */
+ uint32_t picture_number; /* Ordinal display number */
+ uint32_t video_buffer; /* Video (picbuf) number */
+ uint32_t video_address; /* Address of picbuf Y */
+ uint32_t video_address_uv; /* Address of picbuf UV */
+ uint32_t video_stripe; /* Picbuf stripe */
+ uint32_t video_width; /* Picbuf width */
+ uint32_t video_height; /* Picbuf height */
+
+ uint32_t channel_id; /* Decoder channel ID */
+ uint32_t status; /* reserved */
+ uint32_t width; /* pixels */
+ uint32_t height; /* pixels */
+ uint32_t chroma_format; /* see above */
+ uint32_t pulldown; /* see above */
+ uint32_t flags; /* see above */
+ uint32_t pts; /* 32 LSBs of PTS */
+ uint32_t protocol; /* protocolXXX (above) */
+
+ uint32_t frame_rate; /* see above */
+ uint32_t matrix_coeff; /* see above */
+ uint32_t aspect_ratio; /* see above */
+ uint32_t colour_primaries; /* see above */
+ uint32_t transfer_char; /* see above */
+ uint32_t pcr_offset; /* 45kHz if PCR type; else 27MHz */
+ uint32_t n_drop; /* Number of pictures to be dropped */
+
+ uint32_t custom_aspect_ratio_width_height;
+ /* upper 16-bits is Y and lower 16-bits is X */
+
+ uint32_t picture_tag; /* Indexing tag from BUD packets */
+ uint32_t picture_done_payload;
+ uint32_t picture_meta_payload;
+ uint32_t reserved[1];
+
+ /* Protocol-specific extensions. */
+ union {
+ PPB_H264 h264;
+ PPB_MPEG mpeg;
+ PPB_VC1 vc1;
+ } other;
+
+} PPB;
+
+typedef struct {
+ uint32_t bFormatChange;
+ uint32_t resolution;
+ uint32_t channelId;
+ uint32_t ppbPtr;
+ int32_t ptsStcOffset;
+ uint32_t zeroPanscanValid;
+ uint32_t dramOutBufAddr;
+ uint32_t yComponent;
+ PPB ppb;
+
+} C011_PIB;
+
+
+
+typedef struct {
+ uint32_t command;
+ uint32_t sequence;
+ uint32_t status;
+ uint32_t picBuf;
+ uint32_t picRelBuf;
+ uint32_t picInfoDeliveryQ;
+ uint32_t picInfoReleaseQ;
+ uint32_t channelStatus;
+ uint32_t userDataDeliveryQ;
+ uint32_t userDataReleaseQ;
+ uint32_t transportStreamCaptureAddr;
+ uint32_t asyncEventQ;
+
+} DecRspChannelStartVideo;
+
+#define eCMD_C011_CMD_BASE (0x73763000)
+
+/* host commands */
+typedef enum {
+ eCMD_TS_GET_NEXT_PIC = 0x7376F100, /* debug get next picture */
+ eCMD_TS_GET_LAST_PIC = 0x7376F102, /* debug get last pic status */
+ eCMD_TS_READ_WRITE_MEM = 0x7376F104, /* debug read write memory */
+
+ /* New API commands */
+ /* General commands */
+ eCMD_C011_INIT = eCMD_C011_CMD_BASE + 0x01,
+ eCMD_C011_RESET = eCMD_C011_CMD_BASE + 0x02,
+ eCMD_C011_SELF_TEST = eCMD_C011_CMD_BASE + 0x03,
+ eCMD_C011_GET_VERSION = eCMD_C011_CMD_BASE + 0x04,
+ eCMD_C011_GPIO = eCMD_C011_CMD_BASE + 0x05,
+ eCMD_C011_DEBUG_SETUP = eCMD_C011_CMD_BASE + 0x06,
+
+ /* Decoding commands */
+ eCMD_C011_DEC_CHAN_OPEN = eCMD_C011_CMD_BASE + 0x100,
+ eCMD_C011_DEC_CHAN_CLOSE = eCMD_C011_CMD_BASE + 0x101,
+ eCMD_C011_DEC_CHAN_ACTIVATE = eCMD_C011_CMD_BASE + 0x102,
+ eCMD_C011_DEC_CHAN_STATUS = eCMD_C011_CMD_BASE + 0x103,
+ eCMD_C011_DEC_CHAN_FLUSH = eCMD_C011_CMD_BASE + 0x104,
+ eCMD_C011_DEC_CHAN_TRICK_PLAY = eCMD_C011_CMD_BASE + 0x105,
+ eCMD_C011_DEC_CHAN_TS_PIDS = eCMD_C011_CMD_BASE + 0x106,
+ eCMD_C011_DEC_CHAN_PS_STREAM_ID = eCMD_C011_CMD_BASE + 0x107,
+ eCMD_C011_DEC_CHAN_INPUT_PARAMS = eCMD_C011_CMD_BASE + 0x108,
+ eCMD_C011_DEC_CHAN_VIDEO_OUTPUT = eCMD_C011_CMD_BASE + 0x109,
+ eCMD_C011_DEC_CHAN_OUTPUT_FORMAT = eCMD_C011_CMD_BASE + 0x10A,
+ eCMD_C011_DEC_CHAN_SCALING_FILTERS = eCMD_C011_CMD_BASE + 0x10B,
+ eCMD_C011_DEC_CHAN_OSD_MODE = eCMD_C011_CMD_BASE + 0x10D,
+ eCMD_C011_DEC_CHAN_DROP = eCMD_C011_CMD_BASE + 0x10E,
+ eCMD_C011_DEC_CHAN_RELEASE = eCMD_C011_CMD_BASE + 0x10F,
+ eCMD_C011_DEC_CHAN_STREAM_SETTINGS = eCMD_C011_CMD_BASE + 0x110,
+ eCMD_C011_DEC_CHAN_PAUSE_OUTPUT = eCMD_C011_CMD_BASE + 0x111,
+ eCMD_C011_DEC_CHAN_CHANGE = eCMD_C011_CMD_BASE + 0x112,
+ eCMD_C011_DEC_CHAN_SET_STC = eCMD_C011_CMD_BASE + 0x113,
+ eCMD_C011_DEC_CHAN_SET_PTS = eCMD_C011_CMD_BASE + 0x114,
+ eCMD_C011_DEC_CHAN_CC_MODE = eCMD_C011_CMD_BASE + 0x115,
+ eCMD_C011_DEC_CREATE_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x116,
+ eCMD_C011_DEC_COPY_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x117,
+ eCMD_C011_DEC_DELETE_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x118,
+ eCMD_C011_DEC_CHAN_SET_DECYPTION = eCMD_C011_CMD_BASE + 0x119,
+ eCMD_C011_DEC_CHAN_START_VIDEO = eCMD_C011_CMD_BASE + 0x11A,
+ eCMD_C011_DEC_CHAN_STOP_VIDEO = eCMD_C011_CMD_BASE + 0x11B,
+ eCMD_C011_DEC_CHAN_PIC_CAPTURE = eCMD_C011_CMD_BASE + 0x11C,
+ eCMD_C011_DEC_CHAN_PAUSE = eCMD_C011_CMD_BASE + 0x11D,
+ eCMD_C011_DEC_CHAN_PAUSE_STATE = eCMD_C011_CMD_BASE + 0x11E,
+ eCMD_C011_DEC_CHAN_SET_SLOWM_RATE = eCMD_C011_CMD_BASE + 0x11F,
+ eCMD_C011_DEC_CHAN_GET_SLOWM_RATE = eCMD_C011_CMD_BASE + 0x120,
+ eCMD_C011_DEC_CHAN_SET_FF_RATE = eCMD_C011_CMD_BASE + 0x121,
+ eCMD_C011_DEC_CHAN_GET_FF_RATE = eCMD_C011_CMD_BASE + 0x122,
+ eCMD_C011_DEC_CHAN_FRAME_ADVANCE = eCMD_C011_CMD_BASE + 0x123,
+ eCMD_C011_DEC_CHAN_SET_SKIP_PIC_MODE = eCMD_C011_CMD_BASE + 0x124,
+ eCMD_C011_DEC_CHAN_GET_SKIP_PIC_MODE = eCMD_C011_CMD_BASE + 0x125,
+ eCMD_C011_DEC_CHAN_FILL_PIC_BUF = eCMD_C011_CMD_BASE + 0x126,
+ eCMD_C011_DEC_CHAN_SET_CONTINUITY_CHECK = eCMD_C011_CMD_BASE + 0x127,
+ eCMD_C011_DEC_CHAN_GET_CONTINUITY_CHECK = eCMD_C011_CMD_BASE + 0x128,
+ eCMD_C011_DEC_CHAN_SET_BRCM_TRICK_MODE = eCMD_C011_CMD_BASE + 0x129,
+ eCMD_C011_DEC_CHAN_GET_BRCM_TRICK_MODE = eCMD_C011_CMD_BASE + 0x12A,
+ eCMD_C011_DEC_CHAN_REVERSE_FIELD_STATUS = eCMD_C011_CMD_BASE + 0x12B,
+ eCMD_C011_DEC_CHAN_I_PICTURE_FOUND = eCMD_C011_CMD_BASE + 0x12C,
+ eCMD_C011_DEC_CHAN_SET_PARAMETER = eCMD_C011_CMD_BASE + 0x12D,
+ eCMD_C011_DEC_CHAN_SET_USER_DATA_MODE = eCMD_C011_CMD_BASE + 0x12E,
+ eCMD_C011_DEC_CHAN_SET_PAUSE_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x12F,
+ eCMD_C011_DEC_CHAN_SET_SLOW_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x130,
+ eCMD_C011_DEC_CHAN_SET_FF_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x131,
+ eCMD_C011_DEC_CHAN_SET_DISPLAY_TIMING_MODE = eCMD_C011_CMD_BASE + 0x132,
+ eCMD_C011_DEC_CHAN_SET_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x133,
+ eCMD_C011_DEC_CHAN_GET_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x134,
+ eCMD_C011_DEC_CHAN_SET_REVERSE_FIELD = eCMD_C011_CMD_BASE + 0x135,
+ eCMD_C011_DEC_CHAN_STREAM_OPEN = eCMD_C011_CMD_BASE + 0x136,
+ eCMD_C011_DEC_CHAN_SET_PCR_PID = eCMD_C011_CMD_BASE + 0x137,
+ eCMD_C011_DEC_CHAN_SET_VID_PID = eCMD_C011_CMD_BASE + 0x138,
+ eCMD_C011_DEC_CHAN_SET_PAN_SCAN_MODE = eCMD_C011_CMD_BASE + 0x139,
+ eCMD_C011_DEC_CHAN_START_DISPLAY_AT_PTS = eCMD_C011_CMD_BASE + 0x140,
+ eCMD_C011_DEC_CHAN_STOP_DISPLAY_AT_PTS = eCMD_C011_CMD_BASE + 0x141,
+ eCMD_C011_DEC_CHAN_SET_DISPLAY_ORDER = eCMD_C011_CMD_BASE + 0x142,
+ eCMD_C011_DEC_CHAN_GET_DISPLAY_ORDER = eCMD_C011_CMD_BASE + 0x143,
+ eCMD_C011_DEC_CHAN_SET_HOST_TRICK_MODE = eCMD_C011_CMD_BASE + 0x144,
+ eCMD_C011_DEC_CHAN_SET_OPERATION_MODE = eCMD_C011_CMD_BASE + 0x145,
+ eCMD_C011_DEC_CHAN_DISPLAY_PAUSE_UNTO_PTS = eCMD_C011_CMD_BASE + 0x146,
+ eCMD_C011_DEC_CHAN_SET_PTS_STC_DIFF_THRESHOLD = eCMD_C011_CMD_BASE + 0x147,
+ eCMD_C011_DEC_CHAN_SEND_COMPRESSED_BUF = eCMD_C011_CMD_BASE + 0x148,
+ eCMD_C011_DEC_CHAN_SET_CLIPPING = eCMD_C011_CMD_BASE + 0x149,
+ eCMD_C011_DEC_CHAN_SET_PARAMETERS_FOR_HARD_RESET_INTERRUPT_TO_HOST
+ = eCMD_C011_CMD_BASE + 0x150,
+
+ /* Decoder RevD commands */
+ eCMD_C011_DEC_CHAN_SET_CSC = eCMD_C011_CMD_BASE + 0x180, /* color space conversion */
+ eCMD_C011_DEC_CHAN_SET_RANGE_REMAP = eCMD_C011_CMD_BASE + 0x181,
+ eCMD_C011_DEC_CHAN_SET_FGT = eCMD_C011_CMD_BASE + 0x182,
+ /* Note: 0x183 not implemented yet in Rev D main */
+ eCMD_C011_DEC_CHAN_SET_LASTPICTURE_PADDING = eCMD_C011_CMD_BASE + 0x183,
+
+ /* Decoder 7412 commands (7412-only) */
+ eCMD_C011_DEC_CHAN_SET_CONTENT_KEY = eCMD_C011_CMD_BASE + 0x190,
+ eCMD_C011_DEC_CHAN_SET_SESSION_KEY = eCMD_C011_CMD_BASE + 0x191,
+ eCMD_C011_DEC_CHAN_FMT_CHANGE_ACK = eCMD_C011_CMD_BASE + 0x192,
+
+ eCMD_C011_DEC_CHAN_CUSTOM_VIDOUT = eCMD_C011_CMD_BASE + 0x1FF,
+
+ /* Encoding commands */
+ eCMD_C011_ENC_CHAN_OPEN = eCMD_C011_CMD_BASE + 0x200,
+ eCMD_C011_ENC_CHAN_CLOSE = eCMD_C011_CMD_BASE + 0x201,
+ eCMD_C011_ENC_CHAN_ACTIVATE = eCMD_C011_CMD_BASE + 0x202,
+ eCMD_C011_ENC_CHAN_CONTROL = eCMD_C011_CMD_BASE + 0x203,
+ eCMD_C011_ENC_CHAN_STATISTICS = eCMD_C011_CMD_BASE + 0x204,
+
+ eNOTIFY_C011_ENC_CHAN_EVENT = eCMD_C011_CMD_BASE + 0x210,
+
+} eC011_TS_CMD;
+
+#endif
diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c
new file mode 100644
index 00000000000..c438c489aa9
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_hw.c
@@ -0,0 +1,2396 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_hw . c
+ *
+ * Description:
+ * BCM70010 Linux driver HW layer.
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "crystalhd_hw.h"
+
+/* Functions internal to this file */
+
+static void crystalhd_enable_uarts(struct crystalhd_adp *adp)
+{
+ bc_dec_reg_wr(adp, UartSelectA, BSVS_UART_STREAM);
+ bc_dec_reg_wr(adp, UartSelectB, BSVS_UART_DEC_OUTER);
+}
+
+
+static void crystalhd_start_dram(struct crystalhd_adp *adp)
+{
+ bc_dec_reg_wr(adp, SDRAM_PARAM, ((40 / 5 - 1) << 0) |
+ /* tras (40ns tras)/(5ns period) -1 ((15/5 - 1) << 4) | // trcd */
+ ((15 / 5 - 1) << 7) | /* trp */
+ ((10 / 5 - 1) << 10) | /* trrd */
+ ((15 / 5 + 1) << 12) | /* twr */
+ ((2 + 1) << 16) | /* twtr */
+ ((70 / 5 - 2) << 19) | /* trfc */
+ (0 << 23));
+
+ bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0);
+ bc_dec_reg_wr(adp, SDRAM_EXT_MODE, 2);
+ bc_dec_reg_wr(adp, SDRAM_MODE, 0x132);
+ bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0);
+ bc_dec_reg_wr(adp, SDRAM_REFRESH, 0);
+ bc_dec_reg_wr(adp, SDRAM_REFRESH, 0);
+ bc_dec_reg_wr(adp, SDRAM_MODE, 0x32);
+ /* setting the refresh rate here */
+ bc_dec_reg_wr(adp, SDRAM_REF_PARAM, ((1 << 12) | 96));
+}
+
+
+static bool crystalhd_bring_out_of_rst(struct crystalhd_adp *adp)
+{
+ link_misc_perst_deco_ctrl rst_deco_cntrl;
+ link_misc_perst_clk_ctrl rst_clk_cntrl;
+ uint32_t temp;
+
+ /*
+ * Link clocks: MISC_PERST_CLOCK_CTRL Clear PLL power down bit,
+ * delay to allow PLL to lock Clear alternate clock, stop clock bits
+ */
+ rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
+ rst_clk_cntrl.pll_pwr_dn = 0;
+ crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
+ msleep_interruptible(50);
+
+ rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
+ rst_clk_cntrl.stop_core_clk = 0;
+ rst_clk_cntrl.sel_alt_clk = 0;
+
+ crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
+ msleep_interruptible(50);
+
+ /*
+ * Bus Arbiter Timeout: GISB_ARBITER_TIMER
+ * Set internal bus arbiter timeout to 40us based on core clock speed
+ * (63MHz * 40us = 0x9D8)
+ */
+ crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x9D8);
+
+ /*
+ * Decoder clocks: MISC_PERST_DECODER_CTRL
+ * Enable clocks while 7412 reset is asserted, delay
+ * De-assert 7412 reset
+ */
+ rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+ rst_deco_cntrl.stop_bcm_7412_clk = 0;
+ rst_deco_cntrl.bcm7412_rst = 1;
+ crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+ msleep_interruptible(10);
+
+ rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+ rst_deco_cntrl.bcm7412_rst = 0;
+ crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+ msleep_interruptible(50);
+
+ /* Disable OTP_CONTENT_MISC to 0 to disable all secure modes */
+ crystalhd_reg_wr(adp, OTP_CONTENT_MISC, 0);
+
+ /* Clear bit 29 of 0x404 */
+ temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION);
+ temp &= ~BC_BIT(29);
+ crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp);
+
+ /* 2.5V regulator must be set to 2.6 volts (+6%) */
+ /* FIXME: jarod: what's the point of this reg read? */
+ temp = crystalhd_reg_rd(adp, MISC_PERST_VREG_CTRL);
+ crystalhd_reg_wr(adp, MISC_PERST_VREG_CTRL, 0xF3);
+
+ return true;
+}
+
+static bool crystalhd_put_in_reset(struct crystalhd_adp *adp)
+{
+ link_misc_perst_deco_ctrl rst_deco_cntrl;
+ link_misc_perst_clk_ctrl rst_clk_cntrl;
+ uint32_t temp;
+
+ /*
+ * Decoder clocks: MISC_PERST_DECODER_CTRL
+ * Assert 7412 reset, delay
+ * Assert 7412 stop clock
+ */
+ rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+ rst_deco_cntrl.stop_bcm_7412_clk = 1;
+ crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+ msleep_interruptible(50);
+
+ /* Bus Arbiter Timeout: GISB_ARBITER_TIMER
+ * Set internal bus arbiter timeout to 40us based on core clock speed
+ * (6.75MHZ * 40us = 0x10E)
+ */
+ crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x10E);
+
+ /* Link clocks: MISC_PERST_CLOCK_CTRL
+ * Stop core clk, delay
+ * Set alternate clk, delay, set PLL power down
+ */
+ rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
+ rst_clk_cntrl.stop_core_clk = 1;
+ rst_clk_cntrl.sel_alt_clk = 1;
+ crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
+ msleep_interruptible(50);
+
+ rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
+ rst_clk_cntrl.pll_pwr_dn = 1;
+ crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
+
+ /*
+ * Read and restore the Transaction Configuration Register
+ * after core reset
+ */
+ temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION);
+
+ /*
+ * Link core soft reset: MISC3_RESET_CTRL
+ * - Write BIT[0]=1 and read it back for core reset to take place
+ */
+ crystalhd_reg_wr(adp, MISC3_RESET_CTRL, 1);
+ rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC3_RESET_CTRL);
+ msleep_interruptible(50);
+
+ /* restore the transaction configuration register */
+ crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp);
+
+ return true;
+}
+
+static void crystalhd_disable_interrupts(struct crystalhd_adp *adp)
+{
+ intr_mask_reg intr_mask;
+ intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG);
+ intr_mask.mask_pcie_err = 1;
+ intr_mask.mask_pcie_rbusmast_err = 1;
+ intr_mask.mask_pcie_rgr_bridge = 1;
+ intr_mask.mask_rx_done = 1;
+ intr_mask.mask_rx_err = 1;
+ intr_mask.mask_tx_done = 1;
+ intr_mask.mask_tx_err = 1;
+ crystalhd_reg_wr(adp, INTR_INTR_MSK_SET_REG, intr_mask.whole_reg);
+
+ return;
+}
+
+static void crystalhd_enable_interrupts(struct crystalhd_adp *adp)
+{
+ intr_mask_reg intr_mask;
+ intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG);
+ intr_mask.mask_pcie_err = 1;
+ intr_mask.mask_pcie_rbusmast_err = 1;
+ intr_mask.mask_pcie_rgr_bridge = 1;
+ intr_mask.mask_rx_done = 1;
+ intr_mask.mask_rx_err = 1;
+ intr_mask.mask_tx_done = 1;
+ intr_mask.mask_tx_err = 1;
+ crystalhd_reg_wr(adp, INTR_INTR_MSK_CLR_REG, intr_mask.whole_reg);
+
+ return;
+}
+
+static void crystalhd_clear_errors(struct crystalhd_adp *adp)
+{
+ uint32_t reg;
+
+ /* FIXME: jarod: wouldn't we want to write a 0 to the reg? Or does the write clear the bits specified? */
+ reg = crystalhd_reg_rd(adp, MISC1_Y_RX_ERROR_STATUS);
+ if (reg)
+ crystalhd_reg_wr(adp, MISC1_Y_RX_ERROR_STATUS, reg);
+
+ reg = crystalhd_reg_rd(adp, MISC1_UV_RX_ERROR_STATUS);
+ if (reg)
+ crystalhd_reg_wr(adp, MISC1_UV_RX_ERROR_STATUS, reg);
+
+ reg = crystalhd_reg_rd(adp, MISC1_TX_DMA_ERROR_STATUS);
+ if (reg)
+ crystalhd_reg_wr(adp, MISC1_TX_DMA_ERROR_STATUS, reg);
+}
+
+static void crystalhd_clear_interrupts(struct crystalhd_adp *adp)
+{
+ uint32_t intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS);
+
+ if (intr_sts) {
+ crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts);
+
+ /* Write End Of Interrupt for PCIE */
+ crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1);
+ }
+}
+
+static void crystalhd_soft_rst(struct crystalhd_adp *adp)
+{
+ uint32_t val;
+
+ /* Assert c011 soft reset*/
+ bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000001);
+ msleep_interruptible(50);
+
+ /* Release c011 soft reset*/
+ bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000000);
+
+ /* Disable Stuffing..*/
+ val = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL);
+ val |= BC_BIT(8);
+ crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, val);
+}
+
+static bool crystalhd_load_firmware_config(struct crystalhd_adp *adp)
+{
+ uint32_t i = 0, reg;
+
+ crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (BC_DRAM_FW_CFG_ADDR >> 19));
+
+ crystalhd_reg_wr(adp, AES_CMD, 0);
+ crystalhd_reg_wr(adp, AES_CONFIG_INFO, (BC_DRAM_FW_CFG_ADDR & 0x7FFFF));
+ crystalhd_reg_wr(adp, AES_CMD, 0x1);
+
+ /* FIXME: jarod: I've seen this fail, and introducing extra delays helps... */
+ for (i = 0; i < 100; ++i) {
+ reg = crystalhd_reg_rd(adp, AES_STATUS);
+ if (reg & 0x1)
+ return true;
+ msleep_interruptible(10);
+ }
+
+ return false;
+}
+
+
+static bool crystalhd_start_device(struct crystalhd_adp *adp)
+{
+ uint32_t dbg_options, glb_cntrl = 0, reg_pwrmgmt = 0;
+
+ BCMLOG(BCMLOG_INFO, "Starting BCM70012 Device\n");
+
+ reg_pwrmgmt = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL);
+ reg_pwrmgmt &= ~ASPM_L1_ENABLE;
+
+ crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg_pwrmgmt);
+
+ if (!crystalhd_bring_out_of_rst(adp)) {
+ BCMLOG_ERR("Failed To Bring Link Out Of Reset\n");
+ return false;
+ }
+
+ crystalhd_disable_interrupts(adp);
+
+ crystalhd_clear_errors(adp);
+
+ crystalhd_clear_interrupts(adp);
+
+ crystalhd_enable_interrupts(adp);
+
+ /* Enable the option for getting the total no. of DWORDS
+ * that have been transfered by the RXDMA engine
+ */
+ dbg_options = crystalhd_reg_rd(adp, MISC1_DMA_DEBUG_OPTIONS_REG);
+ dbg_options |= 0x10;
+ crystalhd_reg_wr(adp, MISC1_DMA_DEBUG_OPTIONS_REG, dbg_options);
+
+ /* Enable PCI Global Control options */
+ glb_cntrl = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL);
+ glb_cntrl |= 0x100;
+ glb_cntrl |= 0x8000;
+ crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, glb_cntrl);
+
+ crystalhd_enable_interrupts(adp);
+
+ crystalhd_soft_rst(adp);
+ crystalhd_start_dram(adp);
+ crystalhd_enable_uarts(adp);
+
+ return true;
+}
+
+static bool crystalhd_stop_device(struct crystalhd_adp *adp)
+{
+ uint32_t reg;
+
+ BCMLOG(BCMLOG_INFO, "Stopping BCM70012 Device\n");
+ /* Clear and disable interrupts */
+ crystalhd_disable_interrupts(adp);
+ crystalhd_clear_errors(adp);
+ crystalhd_clear_interrupts(adp);
+
+ if (!crystalhd_put_in_reset(adp))
+ BCMLOG_ERR("Failed to Put Link To Reset State\n");
+
+ reg = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL);
+ reg |= ASPM_L1_ENABLE;
+ crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg);
+
+ /* Set PCI Clk Req */
+ reg = crystalhd_reg_rd(adp, PCIE_CLK_REQ_REG);
+ reg |= PCI_CLK_REQ_ENABLE;
+ crystalhd_reg_wr(adp, PCIE_CLK_REQ_REG, reg);
+
+ return true;
+}
+
+static crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(struct crystalhd_hw *hw)
+{
+ unsigned long flags = 0;
+ crystalhd_rx_dma_pkt *temp = NULL;
+
+ if (!hw)
+ return NULL;
+
+ spin_lock_irqsave(&hw->lock, flags);
+ temp = hw->rx_pkt_pool_head;
+ if (temp) {
+ hw->rx_pkt_pool_head = hw->rx_pkt_pool_head->next;
+ temp->dio_req = NULL;
+ temp->pkt_tag = 0;
+ temp->flags = 0;
+ }
+ spin_unlock_irqrestore(&hw->lock, flags);
+
+ return temp;
+}
+
+static void crystalhd_hw_free_rx_pkt(struct crystalhd_hw *hw,
+ crystalhd_rx_dma_pkt *pkt)
+{
+ unsigned long flags = 0;
+
+ if (!hw || !pkt)
+ return;
+
+ spin_lock_irqsave(&hw->lock, flags);
+ pkt->next = hw->rx_pkt_pool_head;
+ hw->rx_pkt_pool_head = pkt;
+ spin_unlock_irqrestore(&hw->lock, flags);
+}
+
+/*
+ * Call back from TX - IOQ deletion.
+ *
+ * This routine will release the TX DMA rings allocated
+ * druing setup_dma rings interface.
+ *
+ * Memory is allocated per DMA ring basis. This is just
+ * a place holder to be able to create the dio queues.
+ */
+static void crystalhd_tx_desc_rel_call_back(void *context, void *data)
+{
+}
+
+/*
+ * Rx Packet release callback..
+ *
+ * Release All user mapped capture buffers and Our DMA packets
+ * back to our free pool. The actual cleanup of the DMA
+ * ring descriptors happen during dma ring release.
+ */
+static void crystalhd_rx_pkt_rel_call_back(void *context, void *data)
+{
+ struct crystalhd_hw *hw = (struct crystalhd_hw *)context;
+ crystalhd_rx_dma_pkt *pkt = (crystalhd_rx_dma_pkt *)data;
+
+ if (!pkt || !hw) {
+ BCMLOG_ERR("Invalid arg - %p %p\n", hw, pkt);
+ return;
+ }
+
+ if (pkt->dio_req)
+ crystalhd_unmap_dio(hw->adp, pkt->dio_req);
+ else
+ BCMLOG_ERR("Missing dio_req: 0x%x\n", pkt->pkt_tag);
+
+ crystalhd_hw_free_rx_pkt(hw, pkt);
+}
+
+#define crystalhd_hw_delete_ioq(adp, q) \
+ if (q) { \
+ crystalhd_delete_dioq(adp, q); \
+ q = NULL; \
+ }
+
+static void crystalhd_hw_delete_ioqs(struct crystalhd_hw *hw)
+{
+ if (!hw)
+ return;
+
+ BCMLOG(BCMLOG_DBG, "Deleting IOQs \n");
+ crystalhd_hw_delete_ioq(hw->adp, hw->tx_actq);
+ crystalhd_hw_delete_ioq(hw->adp, hw->tx_freeq);
+ crystalhd_hw_delete_ioq(hw->adp, hw->rx_actq);
+ crystalhd_hw_delete_ioq(hw->adp, hw->rx_freeq);
+ crystalhd_hw_delete_ioq(hw->adp, hw->rx_rdyq);
+}
+
+#define crystalhd_hw_create_ioq(sts, hw, q, cb) \
+do { \
+ sts = crystalhd_create_dioq(hw->adp, &q, cb, hw); \
+ if (sts != BC_STS_SUCCESS) \
+ goto hw_create_ioq_err; \
+} while (0)
+
+/*
+ * Create IOQs..
+ *
+ * TX - Active & Free
+ * RX - Active, Ready and Free.
+ */
+static BC_STATUS crystalhd_hw_create_ioqs(struct crystalhd_hw *hw)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!hw) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ crystalhd_hw_create_ioq(sts, hw, hw->tx_freeq,
+ crystalhd_tx_desc_rel_call_back);
+ crystalhd_hw_create_ioq(sts, hw, hw->tx_actq,
+ crystalhd_tx_desc_rel_call_back);
+
+ crystalhd_hw_create_ioq(sts, hw, hw->rx_freeq,
+ crystalhd_rx_pkt_rel_call_back);
+ crystalhd_hw_create_ioq(sts, hw, hw->rx_rdyq,
+ crystalhd_rx_pkt_rel_call_back);
+ crystalhd_hw_create_ioq(sts, hw, hw->rx_actq,
+ crystalhd_rx_pkt_rel_call_back);
+
+ return sts;
+
+hw_create_ioq_err:
+ crystalhd_hw_delete_ioqs(hw);
+
+ return sts;
+}
+
+
+static bool crystalhd_code_in_full(struct crystalhd_adp *adp, uint32_t needed_sz,
+ bool b_188_byte_pkts, uint8_t flags)
+{
+ uint32_t base, end, writep, readp;
+ uint32_t cpbSize, cpbFullness, fifoSize;
+
+ if (flags & 0x02) { /* ASF Bit is set */
+ base = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Base);
+ end = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2End);
+ writep = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Wrptr);
+ readp = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Rdptr);
+ } else if (b_188_byte_pkts) { /*Encrypted 188 byte packets*/
+ base = bc_dec_reg_rd(adp, REG_Dec_TsUser0Base);
+ end = bc_dec_reg_rd(adp, REG_Dec_TsUser0End);
+ writep = bc_dec_reg_rd(adp, REG_Dec_TsUser0Wrptr);
+ readp = bc_dec_reg_rd(adp, REG_Dec_TsUser0Rdptr);
+ } else {
+ base = bc_dec_reg_rd(adp, REG_DecCA_RegCinBase);
+ end = bc_dec_reg_rd(adp, REG_DecCA_RegCinEnd);
+ writep = bc_dec_reg_rd(adp, REG_DecCA_RegCinWrPtr);
+ readp = bc_dec_reg_rd(adp, REG_DecCA_RegCinRdPtr);
+ }
+
+ cpbSize = end - base;
+ if (writep >= readp)
+ cpbFullness = writep - readp;
+ else
+ cpbFullness = (end - base) - (readp - writep);
+
+ fifoSize = cpbSize - cpbFullness;
+
+ if (fifoSize < BC_INFIFO_THRESHOLD)
+ return true;
+
+ if (needed_sz > (fifoSize - BC_INFIFO_THRESHOLD))
+ return true;
+
+ return false;
+}
+
+static BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw,
+ uint32_t list_id, BC_STATUS cs)
+{
+ tx_dma_pkt *tx_req;
+
+ if (!hw || !list_id) {
+ BCMLOG_ERR("Invalid Arg..\n");
+ return BC_STS_INV_ARG;
+ }
+
+ hw->pwr_lock--;
+
+ tx_req = (tx_dma_pkt *)crystalhd_dioq_find_and_fetch(hw->tx_actq, list_id);
+ if (!tx_req) {
+ if (cs != BC_STS_IO_USER_ABORT)
+ BCMLOG_ERR("Find and Fetch Did not find req\n");
+ return BC_STS_NO_DATA;
+ }
+
+ if (tx_req->call_back) {
+ tx_req->call_back(tx_req->dio_req, tx_req->cb_event, cs);
+ tx_req->dio_req = NULL;
+ tx_req->cb_event = NULL;
+ tx_req->call_back = NULL;
+ } else {
+ BCMLOG(BCMLOG_DBG, "Missing Tx Callback - %X\n",
+ tx_req->list_tag);
+ }
+
+ /* Now put back the tx_list back in FreeQ */
+ tx_req->list_tag = 0;
+
+ return crystalhd_dioq_add(hw->tx_freeq, tx_req, false, 0);
+}
+
+static bool crystalhd_tx_list0_handler(struct crystalhd_hw *hw, uint32_t err_sts)
+{
+ uint32_t err_mask, tmp;
+ unsigned long flags = 0;
+
+ err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK |
+ MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK |
+ MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK;
+
+ if (!(err_sts & err_mask))
+ return false;
+
+ BCMLOG_ERR("Error on Tx-L0 %x \n", err_sts);
+
+ tmp = err_mask;
+
+ if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK)
+ tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK;
+
+ if (tmp) {
+ spin_lock_irqsave(&hw->lock, flags);
+ /* reset list index.*/
+ hw->tx_list_post_index = 0;
+ spin_unlock_irqrestore(&hw->lock, flags);
+ }
+
+ tmp = err_sts & err_mask;
+ crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp);
+
+ return true;
+}
+
+static bool crystalhd_tx_list1_handler(struct crystalhd_hw *hw, uint32_t err_sts)
+{
+ uint32_t err_mask, tmp;
+ unsigned long flags = 0;
+
+ err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK |
+ MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK |
+ MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK;
+
+ if (!(err_sts & err_mask))
+ return false;
+
+ BCMLOG_ERR("Error on Tx-L1 %x \n", err_sts);
+
+ tmp = err_mask;
+
+ if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK)
+ tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK;
+
+ if (tmp) {
+ spin_lock_irqsave(&hw->lock, flags);
+ /* reset list index.*/
+ hw->tx_list_post_index = 0;
+ spin_unlock_irqrestore(&hw->lock, flags);
+ }
+
+ tmp = err_sts & err_mask;
+ crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp);
+
+ return true;
+}
+
+static void crystalhd_tx_isr(struct crystalhd_hw *hw, uint32_t int_sts)
+{
+ uint32_t err_sts;
+
+ if (int_sts & INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK)
+ crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
+ BC_STS_SUCCESS);
+
+ if (int_sts & INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK)
+ crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1,
+ BC_STS_SUCCESS);
+
+ if (!(int_sts & (INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK |
+ INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK))) {
+ /* No error mask set.. */
+ return;
+ }
+
+ /* Handle Tx errors. */
+ err_sts = crystalhd_reg_rd(hw->adp, MISC1_TX_DMA_ERROR_STATUS);
+
+ if (crystalhd_tx_list0_handler(hw, err_sts))
+ crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
+ BC_STS_ERROR);
+
+ if (crystalhd_tx_list1_handler(hw, err_sts))
+ crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1,
+ BC_STS_ERROR);
+
+ hw->stats.tx_errors++;
+}
+
+static void crystalhd_hw_dump_desc(pdma_descriptor p_dma_desc,
+ uint32_t ul_desc_index, uint32_t cnt)
+{
+ uint32_t ix, ll = 0;
+
+ if (!p_dma_desc || !cnt)
+ return;
+
+ /* FIXME: jarod: perhaps a modparam desc_debug to enable this, rather than
+ * setting ll (log level, I presume) to non-zero? */
+ if (!ll)
+ return;
+
+ for (ix = ul_desc_index; ix < (ul_desc_index + cnt); ix++) {
+ BCMLOG(ll, "%s[%d] Buff[%x:%x] Next:[%x:%x] XferSz:%x Intr:%x,Last:%x\n",
+ ((p_dma_desc[ul_desc_index].dma_dir) ? "TDesc" : "RDesc"),
+ ul_desc_index,
+ p_dma_desc[ul_desc_index].buff_addr_high,
+ p_dma_desc[ul_desc_index].buff_addr_low,
+ p_dma_desc[ul_desc_index].next_desc_addr_high,
+ p_dma_desc[ul_desc_index].next_desc_addr_low,
+ p_dma_desc[ul_desc_index].xfer_size,
+ p_dma_desc[ul_desc_index].intr_enable,
+ p_dma_desc[ul_desc_index].last_rec_indicator);
+ }
+
+}
+
+static BC_STATUS crystalhd_hw_fill_desc(crystalhd_dio_req *ioreq,
+ dma_descriptor *desc,
+ dma_addr_t desc_paddr_base,
+ uint32_t sg_cnt, uint32_t sg_st_ix,
+ uint32_t sg_st_off, uint32_t xfr_sz)
+{
+ uint32_t count = 0, ix = 0, sg_ix = 0, len = 0, last_desc_ix = 0;
+ dma_addr_t desc_phy_addr = desc_paddr_base;
+ addr_64 addr_temp;
+
+ if (!ioreq || !desc || !desc_paddr_base || !xfr_sz ||
+ (!sg_cnt && !ioreq->uinfo.dir_tx)) {
+ BCMLOG_ERR("Invalid Args\n");
+ return BC_STS_INV_ARG;
+ }
+
+ for (ix = 0; ix < sg_cnt; ix++) {
+
+ /* Setup SGLE index. */
+ sg_ix = ix + sg_st_ix;
+
+ /* Get SGLE length */
+ len = crystalhd_get_sgle_len(ioreq, sg_ix);
+ if (len % 4) {
+ BCMLOG_ERR(" len in sg %d %d %d\n", len, sg_ix, sg_cnt);
+ return BC_STS_NOT_IMPL;
+ }
+ /* Setup DMA desc with Phy addr & Length at current index. */
+ addr_temp.full_addr = crystalhd_get_sgle_paddr(ioreq, sg_ix);
+ if (sg_ix == sg_st_ix) {
+ addr_temp.full_addr += sg_st_off;
+ len -= sg_st_off;
+ }
+ memset(&desc[ix], 0, sizeof(desc[ix]));
+ desc[ix].buff_addr_low = addr_temp.low_part;
+ desc[ix].buff_addr_high = addr_temp.high_part;
+ desc[ix].dma_dir = ioreq->uinfo.dir_tx;
+
+ /* Chain DMA descriptor. */
+ addr_temp.full_addr = desc_phy_addr + sizeof(dma_descriptor);
+ desc[ix].next_desc_addr_low = addr_temp.low_part;
+ desc[ix].next_desc_addr_high = addr_temp.high_part;
+
+ if ((count + len) > xfr_sz)
+ len = xfr_sz - count;
+
+ /* Debug.. */
+ if ((!len) || (len > crystalhd_get_sgle_len(ioreq, sg_ix))) {
+ BCMLOG_ERR("inv-len(%x) Ix(%d) count:%x xfr_sz:%x sg_cnt:%d\n",
+ len, ix, count, xfr_sz, sg_cnt);
+ return BC_STS_ERROR;
+ }
+ /* Length expects Multiple of 4 */
+ desc[ix].xfer_size = (len / 4);
+
+ crystalhd_hw_dump_desc(desc, ix, 1);
+
+ count += len;
+ desc_phy_addr += sizeof(dma_descriptor);
+ }
+
+ last_desc_ix = ix - 1;
+
+ if (ioreq->fb_size) {
+ memset(&desc[ix], 0, sizeof(desc[ix]));
+ addr_temp.full_addr = ioreq->fb_pa;
+ desc[ix].buff_addr_low = addr_temp.low_part;
+ desc[ix].buff_addr_high = addr_temp.high_part;
+ desc[ix].dma_dir = ioreq->uinfo.dir_tx;
+ desc[ix].xfer_size = 1;
+ desc[ix].fill_bytes = 4 - ioreq->fb_size;
+ count += ioreq->fb_size;
+ last_desc_ix++;
+ }
+
+ /* setup last descriptor..*/
+ desc[last_desc_ix].last_rec_indicator = 1;
+ desc[last_desc_ix].next_desc_addr_low = 0;
+ desc[last_desc_ix].next_desc_addr_high = 0;
+ desc[last_desc_ix].intr_enable = 1;
+
+ crystalhd_hw_dump_desc(desc, last_desc_ix, 1);
+
+ if (count != xfr_sz) {
+ BCMLOG_ERR("interal error sz curr:%x exp:%x\n", count, xfr_sz);
+ return BC_STS_ERROR;
+ }
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS crystalhd_xlat_sgl_to_dma_desc(crystalhd_dio_req *ioreq,
+ pdma_desc_mem pdesc_mem,
+ uint32_t *uv_desc_index)
+{
+ dma_descriptor *desc = NULL;
+ dma_addr_t desc_paddr_base = 0;
+ uint32_t sg_cnt = 0, sg_st_ix = 0, sg_st_off = 0;
+ uint32_t xfr_sz = 0;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ /* Check params.. */
+ if (!ioreq || !pdesc_mem || !uv_desc_index) {
+ BCMLOG_ERR("Invalid Args\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (!pdesc_mem->sz || !pdesc_mem->pdma_desc_start ||
+ !ioreq->sg || (!ioreq->sg_cnt && !ioreq->uinfo.dir_tx)) {
+ BCMLOG_ERR("Invalid Args\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if ((ioreq->uinfo.dir_tx) && (ioreq->uinfo.uv_offset)) {
+ BCMLOG_ERR("UV offset for TX??\n");
+ return BC_STS_INV_ARG;
+
+ }
+
+ desc = pdesc_mem->pdma_desc_start;
+ desc_paddr_base = pdesc_mem->phy_addr;
+
+ if (ioreq->uinfo.dir_tx || (ioreq->uinfo.uv_offset == 0)) {
+ sg_cnt = ioreq->sg_cnt;
+ xfr_sz = ioreq->uinfo.xfr_len;
+ } else {
+ sg_cnt = ioreq->uinfo.uv_sg_ix + 1;
+ xfr_sz = ioreq->uinfo.uv_offset;
+ }
+
+ sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt,
+ sg_st_ix, sg_st_off, xfr_sz);
+
+ if ((sts != BC_STS_SUCCESS) || !ioreq->uinfo.uv_offset)
+ return sts;
+
+ /* Prepare for UV mapping.. */
+ desc = &pdesc_mem->pdma_desc_start[sg_cnt];
+ desc_paddr_base = pdesc_mem->phy_addr +
+ (sg_cnt * sizeof(dma_descriptor));
+
+ /* Done with desc addr.. now update sg stuff.*/
+ sg_cnt = ioreq->sg_cnt - ioreq->uinfo.uv_sg_ix;
+ xfr_sz = ioreq->uinfo.xfr_len - ioreq->uinfo.uv_offset;
+ sg_st_ix = ioreq->uinfo.uv_sg_ix;
+ sg_st_off = ioreq->uinfo.uv_sg_off;
+
+ sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt,
+ sg_st_ix, sg_st_off, xfr_sz);
+ if (sts != BC_STS_SUCCESS)
+ return sts;
+
+ *uv_desc_index = sg_st_ix;
+
+ return sts;
+}
+
+static void crystalhd_start_tx_dma_engine(struct crystalhd_hw *hw)
+{
+ uint32_t dma_cntrl;
+
+ dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS);
+ if (!(dma_cntrl & DMA_START_BIT)) {
+ dma_cntrl |= DMA_START_BIT;
+ crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS,
+ dma_cntrl);
+ }
+
+ return;
+}
+
+/* _CHECK_THIS_
+ *
+ * Verify if the Stop generates a completion interrupt or not.
+ * if it does not generate an interrupt, then add polling here.
+ */
+static BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw)
+{
+ uint32_t dma_cntrl, cnt = 30;
+ uint32_t l1 = 1, l2 = 1;
+ unsigned long flags = 0;
+
+ dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS);
+
+ BCMLOG(BCMLOG_DBG, "Stopping TX DMA Engine..\n");
+
+ /* FIXME: jarod: invert dma_ctrl and check bit? or are there missing parens? */
+ if (!dma_cntrl & DMA_START_BIT) {
+ BCMLOG(BCMLOG_DBG, "Already Stopped\n");
+ return BC_STS_SUCCESS;
+ }
+
+ crystalhd_disable_interrupts(hw->adp);
+
+ /* Issue stop to HW */
+ /* This bit when set gave problems. Please check*/
+ dma_cntrl &= ~DMA_START_BIT;
+ crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+
+ BCMLOG(BCMLOG_DBG, "Cleared the DMA Start bit\n");
+
+ /* Poll for 3seconds (30 * 100ms) on both the lists..*/
+ while ((l1 || l2) && cnt) {
+
+ if (l1) {
+ l1 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST0);
+ l1 &= DMA_START_BIT;
+ }
+
+ if (l2) {
+ l2 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST1);
+ l2 &= DMA_START_BIT;
+ }
+
+ msleep_interruptible(100);
+
+ cnt--;
+ }
+
+ if (!cnt) {
+ BCMLOG_ERR("Failed to stop TX DMA.. l1 %d, l2 %d\n", l1, l2);
+ crystalhd_enable_interrupts(hw->adp);
+ return BC_STS_ERROR;
+ }
+
+ spin_lock_irqsave(&hw->lock, flags);
+ hw->tx_list_post_index = 0;
+ spin_unlock_irqrestore(&hw->lock, flags);
+ BCMLOG(BCMLOG_DBG, "stopped TX DMA..\n");
+ crystalhd_enable_interrupts(hw->adp);
+
+ return BC_STS_SUCCESS;
+}
+
+static uint32_t crystalhd_get_pib_avail_cnt(struct crystalhd_hw *hw)
+{
+ /*
+ * Position of the PIB Entries can be found at
+ * 0th and the 1st location of the Circular list.
+ */
+ uint32_t Q_addr;
+ uint32_t pib_cnt, r_offset, w_offset;
+
+ Q_addr = hw->pib_del_Q_addr;
+
+ /* Get the Read Pointer */
+ crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
+
+ /* Get the Write Pointer */
+ crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
+
+ if (r_offset == w_offset)
+ return 0; /* Queue is empty */
+
+ if (w_offset > r_offset)
+ pib_cnt = w_offset - r_offset;
+ else
+ pib_cnt = (w_offset + MAX_PIB_Q_DEPTH) -
+ (r_offset + MIN_PIB_Q_DEPTH);
+
+ if (pib_cnt > MAX_PIB_Q_DEPTH) {
+ BCMLOG_ERR("Invalid PIB Count (%u)\n", pib_cnt);
+ return 0;
+ }
+
+ return pib_cnt;
+}
+
+static uint32_t crystalhd_get_addr_from_pib_Q(struct crystalhd_hw *hw)
+{
+ uint32_t Q_addr;
+ uint32_t addr_entry, r_offset, w_offset;
+
+ Q_addr = hw->pib_del_Q_addr;
+
+ /* Get the Read Pointer 0Th Location is Read Pointer */
+ crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
+
+ /* Get the Write Pointer 1st Location is Write pointer */
+ crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
+
+ /* Queue is empty */
+ if (r_offset == w_offset)
+ return 0;
+
+ if ((r_offset < MIN_PIB_Q_DEPTH) || (r_offset >= MAX_PIB_Q_DEPTH))
+ return 0;
+
+ /* Get the Actual Address of the PIB */
+ crystalhd_mem_rd(hw->adp, Q_addr + (r_offset * sizeof(uint32_t)),
+ 1, &addr_entry);
+
+ /* Increment the Read Pointer */
+ r_offset++;
+
+ if (MAX_PIB_Q_DEPTH == r_offset)
+ r_offset = MIN_PIB_Q_DEPTH;
+
+ /* Write back the read pointer to It's Location */
+ crystalhd_mem_wr(hw->adp, Q_addr, 1, &r_offset);
+
+ return addr_entry;
+}
+
+static bool crystalhd_rel_addr_to_pib_Q(struct crystalhd_hw *hw, uint32_t addr_to_rel)
+{
+ uint32_t Q_addr;
+ uint32_t r_offset, w_offset, n_offset;
+
+ Q_addr = hw->pib_rel_Q_addr;
+
+ /* Get the Read Pointer */
+ crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
+
+ /* Get the Write Pointer */
+ crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
+
+ if ((r_offset < MIN_PIB_Q_DEPTH) ||
+ (r_offset >= MAX_PIB_Q_DEPTH))
+ return false;
+
+ n_offset = w_offset + 1;
+
+ if (MAX_PIB_Q_DEPTH == n_offset)
+ n_offset = MIN_PIB_Q_DEPTH;
+
+ if (r_offset == n_offset)
+ return false; /* should never happen */
+
+ /* Write the DRAM ADDR to the Queue at Next Offset */
+ crystalhd_mem_wr(hw->adp, Q_addr + (w_offset * sizeof(uint32_t)),
+ 1, &addr_to_rel);
+
+ /* Put the New value of the write pointer in Queue */
+ crystalhd_mem_wr(hw->adp, Q_addr + sizeof(uint32_t), 1, &n_offset);
+
+ return true;
+}
+
+static void cpy_pib_to_app(C011_PIB *src_pib, BC_PIC_INFO_BLOCK *dst_pib)
+{
+ if (!src_pib || !dst_pib) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return;
+ }
+
+ dst_pib->timeStamp = 0;
+ dst_pib->picture_number = src_pib->ppb.picture_number;
+ dst_pib->width = src_pib->ppb.width;
+ dst_pib->height = src_pib->ppb.height;
+ dst_pib->chroma_format = src_pib->ppb.chroma_format;
+ dst_pib->pulldown = src_pib->ppb.pulldown;
+ dst_pib->flags = src_pib->ppb.flags;
+ dst_pib->sess_num = src_pib->ptsStcOffset;
+ dst_pib->aspect_ratio = src_pib->ppb.aspect_ratio;
+ dst_pib->colour_primaries = src_pib->ppb.colour_primaries;
+ dst_pib->picture_meta_payload = src_pib->ppb.picture_meta_payload;
+ dst_pib->frame_rate = src_pib->resolution ;
+ return;
+}
+
+static void crystalhd_hw_proc_pib(struct crystalhd_hw *hw)
+{
+ unsigned int cnt;
+ C011_PIB src_pib;
+ uint32_t pib_addr, pib_cnt;
+ BC_PIC_INFO_BLOCK *AppPib;
+ crystalhd_rx_dma_pkt *rx_pkt = NULL;
+
+ pib_cnt = crystalhd_get_pib_avail_cnt(hw);
+
+ if (!pib_cnt)
+ return;
+
+ for (cnt = 0; cnt < pib_cnt; cnt++) {
+
+ pib_addr = crystalhd_get_addr_from_pib_Q(hw);
+ crystalhd_mem_rd(hw->adp, pib_addr, sizeof(C011_PIB) / 4,
+ (uint32_t *)&src_pib);
+
+ if (src_pib.bFormatChange) {
+ rx_pkt = (crystalhd_rx_dma_pkt *)crystalhd_dioq_fetch(hw->rx_freeq);
+ if (!rx_pkt)
+ return;
+ rx_pkt->flags = 0;
+ rx_pkt->flags |= COMP_FLAG_PIB_VALID | COMP_FLAG_FMT_CHANGE;
+ AppPib = &rx_pkt->pib;
+ cpy_pib_to_app(&src_pib, AppPib);
+
+ BCMLOG(BCMLOG_DBG,
+ "App PIB:%x %x %x %x %x %x %x %x %x %x\n",
+ rx_pkt->pib.picture_number,
+ rx_pkt->pib.aspect_ratio,
+ rx_pkt->pib.chroma_format,
+ rx_pkt->pib.colour_primaries,
+ rx_pkt->pib.frame_rate,
+ rx_pkt->pib.height,
+ rx_pkt->pib.height,
+ rx_pkt->pib.n_drop,
+ rx_pkt->pib.pulldown,
+ rx_pkt->pib.ycom);
+
+ crystalhd_dioq_add(hw->rx_rdyq, (void *)rx_pkt, true, rx_pkt->pkt_tag);
+
+ }
+
+ crystalhd_rel_addr_to_pib_Q(hw, pib_addr);
+ }
+}
+
+static void crystalhd_start_rx_dma_engine(struct crystalhd_hw *hw)
+{
+ uint32_t dma_cntrl;
+
+ dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+ if (!(dma_cntrl & DMA_START_BIT)) {
+ dma_cntrl |= DMA_START_BIT;
+ crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+ }
+
+ dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+ if (!(dma_cntrl & DMA_START_BIT)) {
+ dma_cntrl |= DMA_START_BIT;
+ crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+ }
+
+ return;
+}
+
+static void crystalhd_stop_rx_dma_engine(struct crystalhd_hw *hw)
+{
+ uint32_t dma_cntrl = 0, count = 30;
+ uint32_t l0y = 1, l0uv = 1, l1y = 1, l1uv = 1;
+
+ dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+ if ((dma_cntrl & DMA_START_BIT)) {
+ dma_cntrl &= ~DMA_START_BIT;
+ crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+ }
+
+ dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+ if ((dma_cntrl & DMA_START_BIT)) {
+ dma_cntrl &= ~DMA_START_BIT;
+ crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+ }
+
+ /* Poll for 3seconds (30 * 100ms) on both the lists..*/
+ while ((l0y || l0uv || l1y || l1uv) && count) {
+
+ if (l0y) {
+ l0y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0);
+ l0y &= DMA_START_BIT;
+ if (!l0y) {
+ hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
+ }
+ }
+
+ if (l1y) {
+ l1y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1);
+ l1y &= DMA_START_BIT;
+ if (!l1y) {
+ hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
+ }
+ }
+
+ if (l0uv) {
+ l0uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0);
+ l0uv &= DMA_START_BIT;
+ if (!l0uv) {
+ hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
+ }
+ }
+
+ if (l1uv) {
+ l1uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1);
+ l1uv &= DMA_START_BIT;
+ if (!l1uv) {
+ hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
+ }
+ }
+ msleep_interruptible(100);
+ count--;
+ }
+
+ hw->rx_list_post_index = 0;
+
+ BCMLOG(BCMLOG_SSTEP, "Capture Stop: %d List0:Sts:%x List1:Sts:%x\n",
+ count, hw->rx_list_sts[0], hw->rx_list_sts[1]);
+}
+
+static BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw, crystalhd_rx_dma_pkt *rx_pkt)
+{
+ uint32_t y_low_addr_reg, y_high_addr_reg;
+ uint32_t uv_low_addr_reg, uv_high_addr_reg;
+ addr_64 desc_addr;
+ unsigned long flags;
+
+ if (!hw || !rx_pkt) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (hw->rx_list_post_index >= DMA_ENGINE_CNT) {
+ BCMLOG_ERR("List Out Of bounds %x\n", hw->rx_list_post_index);
+ return BC_STS_INV_ARG;
+ }
+
+ spin_lock_irqsave(&hw->rx_lock, flags);
+ /* FIXME: jarod: sts_free is an enum for 0, in crystalhd_hw.h... yuk... */
+ if (sts_free != hw->rx_list_sts[hw->rx_list_post_index]) {
+ spin_unlock_irqrestore(&hw->rx_lock, flags);
+ return BC_STS_BUSY;
+ }
+
+ if (!hw->rx_list_post_index) {
+ y_low_addr_reg = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0;
+ y_high_addr_reg = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0;
+ uv_low_addr_reg = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0;
+ uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0;
+ } else {
+ y_low_addr_reg = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1;
+ y_high_addr_reg = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1;
+ uv_low_addr_reg = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1;
+ uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1;
+ }
+ rx_pkt->pkt_tag = hw->rx_pkt_tag_seed + hw->rx_list_post_index;
+ hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_y_intr;
+ if (rx_pkt->uv_phy_addr)
+ hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_uv_intr;
+ hw->rx_list_post_index = (hw->rx_list_post_index + 1) % DMA_ENGINE_CNT;
+ spin_unlock_irqrestore(&hw->rx_lock, flags);
+
+ crystalhd_dioq_add(hw->rx_actq, (void *)rx_pkt, false, rx_pkt->pkt_tag);
+
+ crystalhd_start_rx_dma_engine(hw);
+ /* Program the Y descriptor */
+ desc_addr.full_addr = rx_pkt->desc_mem.phy_addr;
+ crystalhd_reg_wr(hw->adp, y_high_addr_reg, desc_addr.high_part);
+ crystalhd_reg_wr(hw->adp, y_low_addr_reg, desc_addr.low_part | 0x01);
+
+ if (rx_pkt->uv_phy_addr) {
+ /* Program the UV descriptor */
+ desc_addr.full_addr = rx_pkt->uv_phy_addr;
+ crystalhd_reg_wr(hw->adp, uv_high_addr_reg, desc_addr.high_part);
+ crystalhd_reg_wr(hw->adp, uv_low_addr_reg, desc_addr.low_part | 0x01);
+ }
+
+ return BC_STS_SUCCESS;
+}
+
+static BC_STATUS crystalhd_hw_post_cap_buff(struct crystalhd_hw *hw,
+ crystalhd_rx_dma_pkt *rx_pkt)
+{
+ BC_STATUS sts = crystalhd_hw_prog_rxdma(hw, rx_pkt);
+
+ if (sts == BC_STS_BUSY)
+ crystalhd_dioq_add(hw->rx_freeq, (void *)rx_pkt,
+ false, rx_pkt->pkt_tag);
+
+ return sts;
+}
+
+static void crystalhd_get_dnsz(struct crystalhd_hw *hw, uint32_t list_index,
+ uint32_t *y_dw_dnsz, uint32_t *uv_dw_dnsz)
+{
+ uint32_t y_dn_sz_reg, uv_dn_sz_reg;
+
+ if (!list_index) {
+ y_dn_sz_reg = MISC1_Y_RX_LIST0_CUR_BYTE_CNT;
+ uv_dn_sz_reg = MISC1_UV_RX_LIST0_CUR_BYTE_CNT;
+ } else {
+ y_dn_sz_reg = MISC1_Y_RX_LIST1_CUR_BYTE_CNT;
+ uv_dn_sz_reg = MISC1_UV_RX_LIST1_CUR_BYTE_CNT;
+ }
+
+ *y_dw_dnsz = crystalhd_reg_rd(hw->adp, y_dn_sz_reg);
+ *uv_dw_dnsz = crystalhd_reg_rd(hw->adp, uv_dn_sz_reg);
+}
+
+/*
+ * This function should be called only after making sure that the two DMA
+ * lists are free. This function does not check if DMA's are active, before
+ * turning off the DMA.
+ */
+static void crystalhd_hw_finalize_pause(struct crystalhd_hw *hw)
+{
+ uint32_t dma_cntrl, aspm;
+
+ hw->stop_pending = 0;
+
+ dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+ if (dma_cntrl & DMA_START_BIT) {
+ dma_cntrl &= ~DMA_START_BIT;
+ crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+ }
+
+ dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+ if (dma_cntrl & DMA_START_BIT) {
+ dma_cntrl &= ~DMA_START_BIT;
+ crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+ }
+ hw->rx_list_post_index = 0;
+
+ aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL);
+ aspm |= ASPM_L1_ENABLE;
+ /* NAREN BCMLOG(BCMLOG_INFO, "aspm on\n"); */
+ crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
+}
+
+static BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw, uint32_t list_index,
+ BC_STATUS comp_sts)
+{
+ crystalhd_rx_dma_pkt *rx_pkt = NULL;
+ uint32_t y_dw_dnsz, uv_dw_dnsz;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ if (!hw || list_index >= DMA_ENGINE_CNT) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ rx_pkt = crystalhd_dioq_find_and_fetch(hw->rx_actq,
+ hw->rx_pkt_tag_seed + list_index);
+ if (!rx_pkt) {
+ BCMLOG_ERR("Act-Q:PostIx:%x L0Sts:%x L1Sts:%x current L:%x tag:%x comp:%x\n",
+ hw->rx_list_post_index, hw->rx_list_sts[0],
+ hw->rx_list_sts[1], list_index,
+ hw->rx_pkt_tag_seed + list_index, comp_sts);
+ return BC_STS_INV_ARG;
+ }
+
+ if (comp_sts == BC_STS_SUCCESS) {
+ crystalhd_get_dnsz(hw, list_index, &y_dw_dnsz, &uv_dw_dnsz);
+ rx_pkt->dio_req->uinfo.y_done_sz = y_dw_dnsz;
+ rx_pkt->flags = COMP_FLAG_DATA_VALID;
+ if (rx_pkt->uv_phy_addr)
+ rx_pkt->dio_req->uinfo.uv_done_sz = uv_dw_dnsz;
+ crystalhd_dioq_add(hw->rx_rdyq, rx_pkt, true,
+ hw->rx_pkt_tag_seed + list_index);
+ return sts;
+ }
+
+ /* Check if we can post this DIO again. */
+ return crystalhd_hw_post_cap_buff(hw, rx_pkt);
+}
+
+static bool crystalhd_rx_list0_handler(struct crystalhd_hw *hw, uint32_t int_sts,
+ uint32_t y_err_sts, uint32_t uv_err_sts)
+{
+ uint32_t tmp;
+ list_sts tmp_lsts;
+
+ if (!(y_err_sts & GET_Y0_ERR_MSK) && !(uv_err_sts & GET_UV0_ERR_MSK))
+ return false;
+
+ tmp_lsts = hw->rx_list_sts[0];
+
+ /* Y0 - DMA */
+ tmp = y_err_sts & GET_Y0_ERR_MSK;
+ if (int_sts & INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
+ hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
+
+ if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) {
+ hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
+ tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
+ }
+
+ if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
+ hw->rx_list_sts[0] &= ~rx_y_mask;
+ hw->rx_list_sts[0] |= rx_y_error;
+ tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
+ }
+
+ if (tmp) {
+ hw->rx_list_sts[0] &= ~rx_y_mask;
+ hw->rx_list_sts[0] |= rx_y_error;
+ hw->rx_list_post_index = 0;
+ }
+
+ /* UV0 - DMA */
+ tmp = uv_err_sts & GET_UV0_ERR_MSK;
+ if (int_sts & INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK)
+ hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
+
+ if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) {
+ hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
+ tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
+ }
+
+ if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
+ hw->rx_list_sts[0] &= ~rx_uv_mask;
+ hw->rx_list_sts[0] |= rx_uv_error;
+ tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
+ }
+
+ if (tmp) {
+ hw->rx_list_sts[0] &= ~rx_uv_mask;
+ hw->rx_list_sts[0] |= rx_uv_error;
+ hw->rx_list_post_index = 0;
+ }
+
+ if (y_err_sts & GET_Y0_ERR_MSK) {
+ tmp = y_err_sts & GET_Y0_ERR_MSK;
+ crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp);
+ }
+
+ if (uv_err_sts & GET_UV0_ERR_MSK) {
+ tmp = uv_err_sts & GET_UV0_ERR_MSK;
+ crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp);
+ }
+
+ return (tmp_lsts != hw->rx_list_sts[0]);
+}
+
+static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw, uint32_t int_sts,
+ uint32_t y_err_sts, uint32_t uv_err_sts)
+{
+ uint32_t tmp;
+ list_sts tmp_lsts;
+
+ if (!(y_err_sts & GET_Y1_ERR_MSK) && !(uv_err_sts & GET_UV1_ERR_MSK))
+ return false;
+
+ tmp_lsts = hw->rx_list_sts[1];
+
+ /* Y1 - DMA */
+ tmp = y_err_sts & GET_Y1_ERR_MSK;
+ if (int_sts & INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK)
+ hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
+
+ if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) {
+ hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
+ tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK;
+ }
+
+ if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) {
+ /* Add retry-support..*/
+ hw->rx_list_sts[1] &= ~rx_y_mask;
+ hw->rx_list_sts[1] |= rx_y_error;
+ tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK;
+ }
+
+ if (tmp) {
+ hw->rx_list_sts[1] &= ~rx_y_mask;
+ hw->rx_list_sts[1] |= rx_y_error;
+ hw->rx_list_post_index = 0;
+ }
+
+ /* UV1 - DMA */
+ tmp = uv_err_sts & GET_UV1_ERR_MSK;
+ if (int_sts & INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK) {
+ hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
+ }
+
+ if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) {
+ hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
+ tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK;
+ }
+
+ if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) {
+ /* Add retry-support*/
+ hw->rx_list_sts[1] &= ~rx_uv_mask;
+ hw->rx_list_sts[1] |= rx_uv_error;
+ tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK;
+ }
+
+ if (tmp) {
+ hw->rx_list_sts[1] &= ~rx_uv_mask;
+ hw->rx_list_sts[1] |= rx_uv_error;
+ hw->rx_list_post_index = 0;
+ }
+
+ if (y_err_sts & GET_Y1_ERR_MSK) {
+ tmp = y_err_sts & GET_Y1_ERR_MSK;
+ crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp);
+ }
+
+ if (uv_err_sts & GET_UV1_ERR_MSK) {
+ tmp = uv_err_sts & GET_UV1_ERR_MSK;
+ crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp);
+ }
+
+ return (tmp_lsts != hw->rx_list_sts[1]);
+}
+
+
+static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts)
+{
+ unsigned long flags;
+ uint32_t i, list_avail = 0;
+ BC_STATUS comp_sts = BC_STS_NO_DATA;
+ uint32_t y_err_sts, uv_err_sts, y_dn_sz = 0, uv_dn_sz = 0;
+ bool ret = 0;
+
+ if (!hw) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return;
+ }
+
+ if (!(intr_sts & GET_RX_INTR_MASK))
+ return;
+
+ y_err_sts = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_ERROR_STATUS);
+ uv_err_sts = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_ERROR_STATUS);
+
+ for (i = 0; i < DMA_ENGINE_CNT; i++) {
+ /* Update States..*/
+ spin_lock_irqsave(&hw->rx_lock, flags);
+ if (i == 0)
+ ret = crystalhd_rx_list0_handler(hw, intr_sts, y_err_sts, uv_err_sts);
+ else
+ ret = crystalhd_rx_list1_handler(hw, intr_sts, y_err_sts, uv_err_sts);
+ if (ret) {
+ switch (hw->rx_list_sts[i]) {
+ case sts_free:
+ comp_sts = BC_STS_SUCCESS;
+ list_avail = 1;
+ break;
+ case rx_y_error:
+ case rx_uv_error:
+ case rx_sts_error:
+ /* We got error on both or Y or uv. */
+ hw->stats.rx_errors++;
+ crystalhd_get_dnsz(hw, i, &y_dn_sz, &uv_dn_sz);
+ /* FIXME: jarod: this is where my mini pci-e card is tripping up */
+ BCMLOG(BCMLOG_DBG, "list_index:%x rx[%d] Y:%x "
+ "UV:%x Int:%x YDnSz:%x UVDnSz:%x\n",
+ i, hw->stats.rx_errors, y_err_sts,
+ uv_err_sts, intr_sts, y_dn_sz, uv_dn_sz);
+ hw->rx_list_sts[i] = sts_free;
+ comp_sts = BC_STS_ERROR;
+ break;
+ default:
+ /* Wait for completion..*/
+ comp_sts = BC_STS_NO_DATA;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&hw->rx_lock, flags);
+
+ /* handle completion...*/
+ if (comp_sts != BC_STS_NO_DATA) {
+ crystalhd_rx_pkt_done(hw, i, comp_sts);
+ comp_sts = BC_STS_NO_DATA;
+ }
+ }
+
+ if (list_avail) {
+ if (hw->stop_pending) {
+ if ((hw->rx_list_sts[0] == sts_free) &&
+ (hw->rx_list_sts[1] == sts_free))
+ crystalhd_hw_finalize_pause(hw);
+ } else {
+ crystalhd_hw_start_capture(hw);
+ }
+ }
+}
+
+static BC_STATUS crystalhd_fw_cmd_post_proc(struct crystalhd_hw *hw,
+ BC_FW_CMD *fw_cmd)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+ DecRspChannelStartVideo *st_rsp = NULL;
+
+ switch (fw_cmd->cmd[0]) {
+ case eCMD_C011_DEC_CHAN_START_VIDEO:
+ st_rsp = (DecRspChannelStartVideo *)fw_cmd->rsp;
+ hw->pib_del_Q_addr = st_rsp->picInfoDeliveryQ;
+ hw->pib_rel_Q_addr = st_rsp->picInfoReleaseQ;
+ BCMLOG(BCMLOG_DBG, "DelQAddr:%x RelQAddr:%x\n",
+ hw->pib_del_Q_addr, hw->pib_rel_Q_addr);
+ break;
+ case eCMD_C011_INIT:
+ if (!(crystalhd_load_firmware_config(hw->adp))) {
+ BCMLOG_ERR("Invalid Params.\n");
+ sts = BC_STS_FW_AUTH_FAILED;
+ }
+ break;
+ default:
+ break;
+ }
+ return sts;
+}
+
+static BC_STATUS crystalhd_put_ddr2sleep(struct crystalhd_hw *hw)
+{
+ uint32_t reg;
+ link_misc_perst_decoder_ctrl rst_cntrl_reg;
+
+ /* Pulse reset pin of 7412 (MISC_PERST_DECODER_CTRL) */
+ rst_cntrl_reg.whole_reg = crystalhd_reg_rd(hw->adp, MISC_PERST_DECODER_CTRL);
+
+ rst_cntrl_reg.bcm_7412_rst = 1;
+ crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg);
+ msleep_interruptible(50);
+
+ rst_cntrl_reg.bcm_7412_rst = 0;
+ crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg);
+
+ /* Close all banks, put DDR in idle */
+ bc_dec_reg_wr(hw->adp, SDRAM_PRECHARGE, 0);
+
+ /* Set bit 25 (drop CKE pin of DDR) */
+ reg = bc_dec_reg_rd(hw->adp, SDRAM_PARAM);
+ reg |= 0x02000000;
+ bc_dec_reg_wr(hw->adp, SDRAM_PARAM, reg);
+
+ /* Reset the audio block */
+ bc_dec_reg_wr(hw->adp, AUD_DSP_MISC_SOFT_RESET, 0x1);
+
+ /* Power down Raptor PLL */
+ reg = bc_dec_reg_rd(hw->adp, DecHt_PllCCtl);
+ reg |= 0x00008000;
+ bc_dec_reg_wr(hw->adp, DecHt_PllCCtl, reg);
+
+ /* Power down all Audio PLL */
+ bc_dec_reg_wr(hw->adp, AIO_MISC_PLL_RESET, 0x1);
+
+ /* Power down video clock (75MHz) */
+ reg = bc_dec_reg_rd(hw->adp, DecHt_PllECtl);
+ reg |= 0x00008000;
+ bc_dec_reg_wr(hw->adp, DecHt_PllECtl, reg);
+
+ /* Power down video clock (75MHz) */
+ reg = bc_dec_reg_rd(hw->adp, DecHt_PllDCtl);
+ reg |= 0x00008000;
+ bc_dec_reg_wr(hw->adp, DecHt_PllDCtl, reg);
+
+ /* Power down core clock (200MHz) */
+ reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
+ reg |= 0x00008000;
+ bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg);
+
+ /* Power down core clock (200MHz) */
+ reg = bc_dec_reg_rd(hw->adp, DecHt_PllBCtl);
+ reg |= 0x00008000;
+ bc_dec_reg_wr(hw->adp, DecHt_PllBCtl, reg);
+
+ return BC_STS_SUCCESS;
+}
+
+/************************************************
+**
+*************************************************/
+
+BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_t sz)
+{
+ uint32_t reg_data, cnt, *temp_buff;
+ uint32_t fw_sig_len = 36;
+ uint32_t dram_offset = BC_FWIMG_ST_ADDR, sig_reg;
+
+ BCMLOG_ENTER;
+
+ if (!adp || !buffer || !sz) {
+ BCMLOG_ERR("Invalid Params.\n");
+ return BC_STS_INV_ARG;
+ }
+
+ reg_data = crystalhd_reg_rd(adp, OTP_CMD);
+ if (!(reg_data & 0x02)) {
+ BCMLOG_ERR("Invalid hw config.. otp not programmed\n");
+ return BC_STS_ERROR;
+ }
+
+ reg_data = 0;
+ crystalhd_reg_wr(adp, DCI_CMD, 0);
+ reg_data |= BC_BIT(0);
+ crystalhd_reg_wr(adp, DCI_CMD, reg_data);
+
+ reg_data = 0;
+ cnt = 1000;
+ msleep_interruptible(10);
+
+ while (reg_data != BC_BIT(4)) {
+ reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
+ reg_data &= BC_BIT(4);
+ if (--cnt == 0) {
+ BCMLOG_ERR("Firmware Download RDY Timeout.\n");
+ return BC_STS_TIMEOUT;
+ }
+ }
+
+ msleep_interruptible(10);
+ /* Load the FW to the FW_ADDR field in the DCI_FIRMWARE_ADDR */
+ crystalhd_reg_wr(adp, DCI_FIRMWARE_ADDR, dram_offset);
+ temp_buff = (uint32_t *)buffer;
+ for (cnt = 0; cnt < (sz - fw_sig_len); cnt += 4) {
+ crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (dram_offset >> 19));
+ crystalhd_reg_wr(adp, DCI_FIRMWARE_DATA, *temp_buff);
+ dram_offset += 4;
+ temp_buff++;
+ }
+ msleep_interruptible(10);
+
+ temp_buff++;
+
+ sig_reg = (uint32_t)DCI_SIGNATURE_DATA_7;
+ for (cnt = 0; cnt < 8; cnt++) {
+ uint32_t swapped_data = *temp_buff;
+ swapped_data = bswap_32_1(swapped_data);
+ crystalhd_reg_wr(adp, sig_reg, swapped_data);
+ sig_reg -= 4;
+ temp_buff++;
+ }
+ msleep_interruptible(10);
+
+ reg_data = 0;
+ reg_data |= BC_BIT(1);
+ crystalhd_reg_wr(adp, DCI_CMD, reg_data);
+ msleep_interruptible(10);
+
+ reg_data = 0;
+ reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
+
+ if ((reg_data & BC_BIT(9)) == BC_BIT(9)) {
+ cnt = 1000;
+ while ((reg_data & BC_BIT(0)) != BC_BIT(0)) {
+ reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
+ reg_data &= BC_BIT(0);
+ if (!(--cnt))
+ break;
+ msleep_interruptible(10);
+ }
+ reg_data = 0;
+ reg_data = crystalhd_reg_rd(adp, DCI_CMD);
+ reg_data |= BC_BIT(4);
+ crystalhd_reg_wr(adp, DCI_CMD, reg_data);
+
+ } else {
+ BCMLOG_ERR("F/w Signature mismatch\n");
+ return BC_STS_FW_AUTH_FAILED;
+ }
+
+ BCMLOG(BCMLOG_INFO, "Firmware Downloaded Successfully\n");
+ return BC_STS_SUCCESS;;
+}
+
+BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd)
+{
+ uint32_t cnt = 0, cmd_res_addr;
+ uint32_t *cmd_buff, *res_buff;
+ wait_queue_head_t fw_cmd_event;
+ int rc = 0;
+ BC_STATUS sts;
+
+ crystalhd_create_event(&fw_cmd_event);
+
+ BCMLOG_ENTER;
+
+ if (!hw || !fw_cmd) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ cmd_buff = fw_cmd->cmd;
+ res_buff = fw_cmd->rsp;
+
+ if (!cmd_buff || !res_buff) {
+ BCMLOG_ERR("Invalid Parameters for F/W Command \n");
+ return BC_STS_INV_ARG;
+ }
+
+ hw->pwr_lock++;
+
+ hw->fwcmd_evt_sts = 0;
+ hw->pfw_cmd_event = &fw_cmd_event;
+
+ /*Write the command to the memory*/
+ crystalhd_mem_wr(hw->adp, TS_Host2CpuSnd, FW_CMD_BUFF_SZ, cmd_buff);
+
+ /*Memory Read for memory arbitrator flush*/
+ crystalhd_mem_rd(hw->adp, TS_Host2CpuSnd, 1, &cnt);
+
+ /* Write the command address to mailbox */
+ bc_dec_reg_wr(hw->adp, Hst2CpuMbx1, TS_Host2CpuSnd);
+ msleep_interruptible(50);
+
+ crystalhd_wait_on_event(&fw_cmd_event, hw->fwcmd_evt_sts, 20000, rc, 0);
+
+ if (!rc) {
+ sts = BC_STS_SUCCESS;
+ } else if (rc == -EBUSY) {
+ BCMLOG_ERR("Firmware command T/O\n");
+ sts = BC_STS_TIMEOUT;
+ } else if (rc == -EINTR) {
+ BCMLOG(BCMLOG_DBG, "FwCmd Wait Signal int.\n");
+ sts = BC_STS_IO_USER_ABORT;
+ } else {
+ BCMLOG_ERR("FwCmd IO Error.\n");
+ sts = BC_STS_IO_ERROR;
+ }
+
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("FwCmd Failed.\n");
+ hw->pwr_lock--;
+ return sts;
+ }
+
+ /*Get the Responce Address*/
+ cmd_res_addr = bc_dec_reg_rd(hw->adp, Cpu2HstMbx1);
+
+ /*Read the Response*/
+ crystalhd_mem_rd(hw->adp, cmd_res_addr, FW_CMD_BUFF_SZ, res_buff);
+
+ hw->pwr_lock--;
+
+ if (res_buff[2] != C011_RET_SUCCESS) {
+ BCMLOG_ERR("res_buff[2] != C011_RET_SUCCESS\n");
+ return BC_STS_FW_CMD_ERR;
+ }
+
+ sts = crystalhd_fw_cmd_post_proc(hw, fw_cmd);
+ if (sts != BC_STS_SUCCESS)
+ BCMLOG_ERR("crystalhd_fw_cmd_post_proc Failed.\n");
+
+ return sts;
+}
+
+bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
+{
+ uint32_t intr_sts = 0;
+ uint32_t deco_intr = 0;
+ bool rc = 0;
+
+ if (!adp || !hw->dev_started)
+ return rc;
+
+ hw->stats.num_interrupts++;
+ hw->pwr_lock++;
+
+ deco_intr = bc_dec_reg_rd(adp, Stream2Host_Intr_Sts);
+ intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS);
+
+ if (intr_sts) {
+ /* let system know we processed interrupt..*/
+ rc = 1;
+ hw->stats.dev_interrupts++;
+ }
+
+ if (deco_intr && (deco_intr != 0xdeaddead)) {
+
+ if (deco_intr & 0x80000000) {
+ /*Set the Event and the status flag*/
+ if (hw->pfw_cmd_event) {
+ hw->fwcmd_evt_sts = 1;
+ crystalhd_set_event(hw->pfw_cmd_event);
+ }
+ }
+
+ if (deco_intr & BC_BIT(1))
+ crystalhd_hw_proc_pib(hw);
+
+ bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, deco_intr);
+ /* FIXME: jarod: No udelay? might this be the real reason mini pci-e cards were stalling out? */
+ bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, 0);
+ rc = 1;
+ }
+
+ /* Rx interrupts */
+ crystalhd_rx_isr(hw, intr_sts);
+
+ /* Tx interrupts*/
+ crystalhd_tx_isr(hw, intr_sts);
+
+ /* Clear interrupts */
+ if (rc) {
+ if (intr_sts)
+ crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts);
+
+ crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1);
+ }
+
+ hw->pwr_lock--;
+
+ return rc;
+}
+
+BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp)
+{
+ if (!hw || !adp) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (hw->dev_started)
+ return BC_STS_SUCCESS;
+
+ memset(hw, 0, sizeof(struct crystalhd_hw));
+
+ hw->adp = adp;
+ spin_lock_init(&hw->lock);
+ spin_lock_init(&hw->rx_lock);
+ /* FIXME: jarod: what are these magic numbers?!? */
+ hw->tx_ioq_tag_seed = 0x70023070;
+ hw->rx_pkt_tag_seed = 0x70029070;
+
+ hw->stop_pending = 0;
+ crystalhd_start_device(hw->adp);
+ hw->dev_started = true;
+
+ /* set initial core clock */
+ hw->core_clock_mhz = CLOCK_PRESET;
+ hw->prev_n = 0;
+ hw->pwr_lock = 0;
+ crystalhd_hw_set_core_clock(hw);
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw)
+{
+ if (!hw) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ if (!hw->dev_started)
+ return BC_STS_SUCCESS;
+
+ /* Stop and DDR sleep will happen in here */
+ crystalhd_hw_suspend(hw);
+ hw->dev_started = false;
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw)
+{
+ unsigned int i;
+ void *mem;
+ size_t mem_len;
+ dma_addr_t phy_addr;
+ BC_STATUS sts = BC_STS_SUCCESS;
+ crystalhd_rx_dma_pkt *rpkt;
+
+ if (!hw || !hw->adp) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ sts = crystalhd_hw_create_ioqs(hw);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("Failed to create IOQs..\n");
+ return sts;
+ }
+
+ mem_len = BC_LINK_MAX_SGLS * sizeof(dma_descriptor);
+
+ for (i = 0; i < BC_TX_LIST_CNT; i++) {
+ mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr);
+ if (mem) {
+ memset(mem, 0, mem_len);
+ } else {
+ BCMLOG_ERR("Insufficient Memory For TX\n");
+ crystalhd_hw_free_dma_rings(hw);
+ return BC_STS_INSUFF_RES;
+ }
+ /* rx_pkt_pool -- static memory allocation */
+ hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = mem;
+ hw->tx_pkt_pool[i].desc_mem.phy_addr = phy_addr;
+ hw->tx_pkt_pool[i].desc_mem.sz = BC_LINK_MAX_SGLS *
+ sizeof(dma_descriptor);
+ hw->tx_pkt_pool[i].list_tag = 0;
+
+ /* Add TX dma requests to Free Queue..*/
+ sts = crystalhd_dioq_add(hw->tx_freeq,
+ &hw->tx_pkt_pool[i], false, 0);
+ if (sts != BC_STS_SUCCESS) {
+ crystalhd_hw_free_dma_rings(hw);
+ return sts;
+ }
+ }
+
+ for (i = 0; i < BC_RX_LIST_CNT; i++) {
+ rpkt = kzalloc(sizeof(*rpkt), GFP_KERNEL);
+ if (!rpkt) {
+ BCMLOG_ERR("Insufficient Memory For RX\n");
+ crystalhd_hw_free_dma_rings(hw);
+ return BC_STS_INSUFF_RES;
+ }
+
+ mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr);
+ if (mem) {
+ memset(mem, 0, mem_len);
+ } else {
+ BCMLOG_ERR("Insufficient Memory For RX\n");
+ crystalhd_hw_free_dma_rings(hw);
+ return BC_STS_INSUFF_RES;
+ }
+ rpkt->desc_mem.pdma_desc_start = mem;
+ rpkt->desc_mem.phy_addr = phy_addr;
+ rpkt->desc_mem.sz = BC_LINK_MAX_SGLS * sizeof(dma_descriptor);
+ rpkt->pkt_tag = hw->rx_pkt_tag_seed + i;
+ crystalhd_hw_free_rx_pkt(hw, rpkt);
+ }
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *hw)
+{
+ unsigned int i;
+ crystalhd_rx_dma_pkt *rpkt = NULL;
+
+ if (!hw || !hw->adp) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ /* Delete all IOQs.. */
+ crystalhd_hw_delete_ioqs(hw);
+
+ for (i = 0; i < BC_TX_LIST_CNT; i++) {
+ if (hw->tx_pkt_pool[i].desc_mem.pdma_desc_start) {
+ bc_kern_dma_free(hw->adp,
+ hw->tx_pkt_pool[i].desc_mem.sz,
+ hw->tx_pkt_pool[i].desc_mem.pdma_desc_start,
+ hw->tx_pkt_pool[i].desc_mem.phy_addr);
+
+ hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = NULL;
+ }
+ }
+
+ BCMLOG(BCMLOG_DBG, "Releasing RX Pkt pool\n");
+ do {
+ rpkt = crystalhd_hw_alloc_rx_pkt(hw);
+ if (!rpkt)
+ break;
+ bc_kern_dma_free(hw->adp, rpkt->desc_mem.sz,
+ rpkt->desc_mem.pdma_desc_start,
+ rpkt->desc_mem.phy_addr);
+ kfree(rpkt);
+ } while (rpkt);
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq,
+ hw_comp_callback call_back,
+ wait_queue_head_t *cb_event, uint32_t *list_id,
+ uint8_t data_flags)
+{
+ tx_dma_pkt *tx_dma_packet = NULL;
+ uint32_t first_desc_u_addr, first_desc_l_addr;
+ uint32_t low_addr, high_addr;
+ addr_64 desc_addr;
+ BC_STATUS sts, add_sts;
+ uint32_t dummy_index = 0;
+ unsigned long flags;
+ bool rc;
+
+ if (!hw || !ioreq || !call_back || !cb_event || !list_id) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ /*
+ * Since we hit code in busy condition very frequently,
+ * we will check the code in status first before
+ * checking the availability of free elem.
+ *
+ * This will avoid the Q fetch/add in normal condition.
+ */
+ rc = crystalhd_code_in_full(hw->adp, ioreq->uinfo.xfr_len,
+ false, data_flags);
+ if (rc) {
+ hw->stats.cin_busy++;
+ return BC_STS_BUSY;
+ }
+
+ /* Get a list from TxFreeQ */
+ tx_dma_packet = (tx_dma_pkt *)crystalhd_dioq_fetch(hw->tx_freeq);
+ if (!tx_dma_packet) {
+ BCMLOG_ERR("No empty elements..\n");
+ return BC_STS_ERR_USAGE;
+ }
+
+ sts = crystalhd_xlat_sgl_to_dma_desc(ioreq,
+ &tx_dma_packet->desc_mem,
+ &dummy_index);
+ if (sts != BC_STS_SUCCESS) {
+ add_sts = crystalhd_dioq_add(hw->tx_freeq, tx_dma_packet,
+ false, 0);
+ if (add_sts != BC_STS_SUCCESS)
+ BCMLOG_ERR("double fault..\n");
+
+ return sts;
+ }
+
+ hw->pwr_lock++;
+
+ desc_addr.full_addr = tx_dma_packet->desc_mem.phy_addr;
+ low_addr = desc_addr.low_part;
+ high_addr = desc_addr.high_part;
+
+ tx_dma_packet->call_back = call_back;
+ tx_dma_packet->cb_event = cb_event;
+ tx_dma_packet->dio_req = ioreq;
+
+ spin_lock_irqsave(&hw->lock, flags);
+
+ if (hw->tx_list_post_index == 0) {
+ first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST0;
+ first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST0;
+ } else {
+ first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST1;
+ first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST1;
+ }
+
+ *list_id = tx_dma_packet->list_tag = hw->tx_ioq_tag_seed +
+ hw->tx_list_post_index;
+
+ hw->tx_list_post_index = (hw->tx_list_post_index + 1) % DMA_ENGINE_CNT;
+
+ spin_unlock_irqrestore(&hw->lock, flags);
+
+
+ /* Insert in Active Q..*/
+ crystalhd_dioq_add(hw->tx_actq, tx_dma_packet, false,
+ tx_dma_packet->list_tag);
+
+ /*
+ * Interrupt will come as soon as you write
+ * the valid bit. So be ready for that. All
+ * the initialization should happen before that.
+ */
+ crystalhd_start_tx_dma_engine(hw);
+ crystalhd_reg_wr(hw->adp, first_desc_u_addr, desc_addr.high_part);
+
+ crystalhd_reg_wr(hw->adp, first_desc_l_addr, desc_addr.low_part | 0x01);
+ /* Be sure we set the valid bit ^^^^ */
+
+ return BC_STS_SUCCESS;
+}
+
+/*
+ * This is a force cancel and we are racing with ISR.
+ *
+ * Will try to remove the req from ActQ before ISR gets it.
+ * If ISR gets it first then the completion happens in the
+ * normal path and we will return _STS_NO_DATA from here.
+ *
+ * FIX_ME: Not Tested the actual condition..
+ */
+BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id)
+{
+ if (!hw || !list_id) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ crystalhd_stop_tx_dma_engine(hw);
+ crystalhd_hw_tx_req_complete(hw, list_id, BC_STS_IO_USER_ABORT);
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
+ crystalhd_dio_req *ioreq, bool en_post)
+{
+ crystalhd_rx_dma_pkt *rpkt;
+ uint32_t tag, uv_desc_ix = 0;
+ BC_STATUS sts;
+
+ if (!hw || !ioreq) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ rpkt = crystalhd_hw_alloc_rx_pkt(hw);
+ if (!rpkt) {
+ BCMLOG_ERR("Insufficient resources\n");
+ return BC_STS_INSUFF_RES;
+ }
+
+ rpkt->dio_req = ioreq;
+ tag = rpkt->pkt_tag;
+
+ sts = crystalhd_xlat_sgl_to_dma_desc(ioreq, &rpkt->desc_mem, &uv_desc_ix);
+ if (sts != BC_STS_SUCCESS)
+ return sts;
+
+ rpkt->uv_phy_addr = 0;
+
+ /* Store the address of UV in the rx packet for post*/
+ if (uv_desc_ix)
+ rpkt->uv_phy_addr = rpkt->desc_mem.phy_addr +
+ (sizeof(dma_descriptor) * (uv_desc_ix + 1));
+
+ if (en_post)
+ sts = crystalhd_hw_post_cap_buff(hw, rpkt);
+ else
+ sts = crystalhd_dioq_add(hw->rx_freeq, rpkt, false, tag);
+
+ return sts;
+}
+
+BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
+ BC_PIC_INFO_BLOCK *pib,
+ crystalhd_dio_req **ioreq)
+{
+ crystalhd_rx_dma_pkt *rpkt;
+ uint32_t timeout = BC_PROC_OUTPUT_TIMEOUT / 1000;
+ uint32_t sig_pending = 0;
+
+
+ if (!hw || !ioreq || !pib) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ rpkt = crystalhd_dioq_fetch_wait(hw->rx_rdyq, timeout, &sig_pending);
+ if (!rpkt) {
+ if (sig_pending) {
+ BCMLOG(BCMLOG_INFO, "wait on frame time out %d\n", sig_pending);
+ return BC_STS_IO_USER_ABORT;
+ } else {
+ return BC_STS_TIMEOUT;
+ }
+ }
+
+ rpkt->dio_req->uinfo.comp_flags = rpkt->flags;
+
+ if (rpkt->flags & COMP_FLAG_PIB_VALID)
+ memcpy(pib, &rpkt->pib, sizeof(*pib));
+
+ *ioreq = rpkt->dio_req;
+
+ crystalhd_hw_free_rx_pkt(hw, rpkt);
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw)
+{
+ crystalhd_rx_dma_pkt *rx_pkt;
+ BC_STATUS sts;
+ uint32_t i;
+
+ if (!hw) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ /* This is start of capture.. Post to both the lists.. */
+ for (i = 0; i < DMA_ENGINE_CNT; i++) {
+ rx_pkt = crystalhd_dioq_fetch(hw->rx_freeq);
+ if (!rx_pkt)
+ return BC_STS_NO_DATA;
+ sts = crystalhd_hw_post_cap_buff(hw, rx_pkt);
+ if (BC_STS_SUCCESS != sts)
+ break;
+
+ }
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw)
+{
+ void *temp = NULL;
+
+ if (!hw) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ crystalhd_stop_rx_dma_engine(hw);
+
+ do {
+ temp = crystalhd_dioq_fetch(hw->rx_freeq);
+ if (temp)
+ crystalhd_rx_pkt_rel_call_back(hw, temp);
+ } while (temp);
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw)
+{
+ hw->stats.pause_cnt++;
+ hw->stop_pending = 1;
+
+ if ((hw->rx_list_sts[0] == sts_free) &&
+ (hw->rx_list_sts[1] == sts_free))
+ crystalhd_hw_finalize_pause(hw);
+
+ return BC_STS_SUCCESS;
+}
+
+BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw)
+{
+ BC_STATUS sts;
+ uint32_t aspm;
+
+ hw->stop_pending = 0;
+
+ aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL);
+ aspm &= ~ASPM_L1_ENABLE;
+/* NAREN BCMLOG(BCMLOG_INFO, "aspm off\n"); */
+ crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
+
+ sts = crystalhd_hw_start_capture(hw);
+ return sts;
+}
+
+BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw)
+{
+ BC_STATUS sts;
+
+ if (!hw) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ sts = crystalhd_put_ddr2sleep(hw);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("Failed to Put DDR To Sleep!!\n");
+ return BC_STS_ERROR;
+ }
+
+ if (!crystalhd_stop_device(hw->adp)) {
+ BCMLOG_ERR("Failed to Stop Device!!\n");
+ return BC_STS_ERROR;
+ }
+
+ return BC_STS_SUCCESS;
+}
+
+void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats)
+{
+ if (!hw) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return;
+ }
+
+ /* if called w/NULL stats, its a req to zero out the stats */
+ if (!stats) {
+ memset(&hw->stats, 0, sizeof(hw->stats));
+ return;
+ }
+
+ hw->stats.freeq_count = crystalhd_dioq_count(hw->rx_freeq);
+ hw->stats.rdyq_count = crystalhd_dioq_count(hw->rx_rdyq);
+ memcpy(stats, &hw->stats, sizeof(*stats));
+}
+
+BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *hw)
+{
+ uint32_t reg, n, i;
+ uint32_t vco_mg, refresh_reg;
+
+ if (!hw) {
+ BCMLOG_ERR("Invalid Arguments\n");
+ return BC_STS_INV_ARG;
+ }
+
+ /* FIXME: jarod: wha? */
+ /*n = (hw->core_clock_mhz * 3) / 20 + 1; */
+ n = hw->core_clock_mhz/5;
+
+ if (n == hw->prev_n)
+ return BC_STS_CLK_NOCHG;
+
+ if (hw->pwr_lock > 0) {
+ /* BCMLOG(BCMLOG_INFO,"pwr_lock is %u\n", hw->pwr_lock) */
+ return BC_STS_CLK_NOCHG;
+ }
+
+ i = n * 27;
+ if (i < 560)
+ vco_mg = 0;
+ else if (i < 900)
+ vco_mg = 1;
+ else if (i < 1030)
+ vco_mg = 2;
+ else
+ vco_mg = 3;
+
+ reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
+
+ reg &= 0xFFFFCFC0;
+ reg |= n;
+ reg |= vco_mg << 12;
+
+ BCMLOG(BCMLOG_INFO, "clock is moving to %d with n %d with vco_mg %d\n",
+ hw->core_clock_mhz, n, vco_mg);
+
+ /* Change the DRAM refresh rate to accomodate the new frequency */
+ /* refresh reg = ((refresh_rate * clock_rate)/16) - 1; rounding up*/
+ refresh_reg = (7 * hw->core_clock_mhz / 16);
+ bc_dec_reg_wr(hw->adp, SDRAM_REF_PARAM, ((1 << 12) | refresh_reg));
+
+ bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg);
+
+ i = 0;
+
+ for (i = 0; i < 10; i++) {
+ reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
+
+ if (reg & 0x00020000) {
+ hw->prev_n = n;
+ /* FIXME: jarod: outputting a random "C" is... confusing... */
+ BCMLOG(BCMLOG_INFO, "C");
+ return BC_STS_SUCCESS;
+ } else {
+ msleep_interruptible(10);
+ }
+ }
+ BCMLOG(BCMLOG_INFO, "clk change failed\n");
+ return BC_STS_CLK_NOCHG;
+}
diff --git a/drivers/staging/crystalhd/crystalhd_hw.h b/drivers/staging/crystalhd/crystalhd_hw.h
new file mode 100644
index 00000000000..1c6318e912a
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_hw.h
@@ -0,0 +1,398 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_hw . h
+ *
+ * Description:
+ * BCM70012 Linux driver hardware layer.
+ *
+ * HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_HW_H_
+#define _CRYSTALHD_HW_H_
+
+#include "crystalhd_misc.h"
+#include "crystalhd_fw_if.h"
+
+/* HW constants..*/
+#define DMA_ENGINE_CNT 2
+#define MAX_PIB_Q_DEPTH 64
+#define MIN_PIB_Q_DEPTH 2
+#define WR_POINTER_OFF 4
+
+#define ASPM_L1_ENABLE (BC_BIT(27))
+
+/*************************************************
+ 7412 Decoder Registers.
+**************************************************/
+#define FW_CMD_BUFF_SZ 64
+#define TS_Host2CpuSnd 0x00000100
+#define Hst2CpuMbx1 0x00100F00
+#define Cpu2HstMbx1 0x00100F04
+#define MbxStat1 0x00100F08
+#define Stream2Host_Intr_Sts 0x00100F24
+#define C011_RET_SUCCESS 0x0 /* Reutrn status of firmware command. */
+
+/* TS input status register */
+#define TS_StreamAFIFOStatus 0x0010044C
+#define TS_StreamBFIFOStatus 0x0010084C
+
+/*UART Selection definitions*/
+#define UartSelectA 0x00100300
+#define UartSelectB 0x00100304
+
+#define BSVS_UART_DEC_NONE 0x00
+#define BSVS_UART_DEC_OUTER 0x01
+#define BSVS_UART_DEC_INNER 0x02
+#define BSVS_UART_STREAM 0x03
+
+/* Code-In fifo */
+#define REG_DecCA_RegCinCTL 0xa00
+#define REG_DecCA_RegCinBase 0xa0c
+#define REG_DecCA_RegCinEnd 0xa10
+#define REG_DecCA_RegCinWrPtr 0xa04
+#define REG_DecCA_RegCinRdPtr 0xa08
+
+#define REG_Dec_TsUser0Base 0x100864
+#define REG_Dec_TsUser0Rdptr 0x100868
+#define REG_Dec_TsUser0Wrptr 0x10086C
+#define REG_Dec_TsUser0End 0x100874
+
+/* ASF Case ...*/
+#define REG_Dec_TsAudCDB2Base 0x10036c
+#define REG_Dec_TsAudCDB2Rdptr 0x100378
+#define REG_Dec_TsAudCDB2Wrptr 0x100374
+#define REG_Dec_TsAudCDB2End 0x100370
+
+/* DRAM bringup Registers */
+#define SDRAM_PARAM 0x00040804
+#define SDRAM_PRECHARGE 0x000408B0
+#define SDRAM_EXT_MODE 0x000408A4
+#define SDRAM_MODE 0x000408A0
+#define SDRAM_REFRESH 0x00040890
+#define SDRAM_REF_PARAM 0x00040808
+
+#define DecHt_PllACtl 0x34000C
+#define DecHt_PllBCtl 0x340010
+#define DecHt_PllCCtl 0x340014
+#define DecHt_PllDCtl 0x340034
+#define DecHt_PllECtl 0x340038
+#define AUD_DSP_MISC_SOFT_RESET 0x00240104
+#define AIO_MISC_PLL_RESET 0x0026000C
+#define PCIE_CLK_REQ_REG 0xDC
+#define PCI_CLK_REQ_ENABLE (BC_BIT(8))
+
+/*************************************************
+ F/W Copy engine definitions..
+**************************************************/
+#define BC_FWIMG_ST_ADDR 0x00000000
+/* FIXME: jarod: there's a kernel function that'll do this for us... */
+#define rotr32_1(x, n) (((x) >> n) | ((x) << (32 - n)))
+#define bswap_32_1(x) ((rotr32_1((x), 24) & 0x00ff00ff) | (rotr32_1((x), 8) & 0xff00ff00))
+
+#define DecHt_HostSwReset 0x340000
+#define BC_DRAM_FW_CFG_ADDR 0x001c2000
+
+typedef union _addr_64_ {
+ struct {
+ uint32_t low_part;
+ uint32_t high_part;
+ };
+
+ uint64_t full_addr;
+
+} addr_64;
+
+typedef union _intr_mask_reg_ {
+ struct {
+ uint32_t mask_tx_done:1;
+ uint32_t mask_tx_err:1;
+ uint32_t mask_rx_done:1;
+ uint32_t mask_rx_err:1;
+ uint32_t mask_pcie_err:1;
+ uint32_t mask_pcie_rbusmast_err:1;
+ uint32_t mask_pcie_rgr_bridge:1;
+ uint32_t reserved:25;
+ };
+
+ uint32_t whole_reg;
+
+} intr_mask_reg;
+
+typedef union _link_misc_perst_deco_ctrl_ {
+ struct {
+ uint32_t bcm7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/
+ uint32_t reserved0:3; /* Reserved.No Effect*/
+ uint32_t stop_bcm_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
+ uint32_t reserved1:27; /* Reseved. No Effect*/
+ };
+
+ uint32_t whole_reg;
+
+} link_misc_perst_deco_ctrl;
+
+typedef union _link_misc_perst_clk_ctrl_ {
+ struct {
+ uint32_t sel_alt_clk:1; /* When set, selects a 6.75MHz clock as the source of core_clk */
+ uint32_t stop_core_clk:1; /* When set, stops the branch of core_clk that is not needed for low power operation */
+ uint32_t pll_pwr_dn:1; /* When set, powers down the main PLL. The alternate clock bit should be set
+ to select an alternate clock before setting this bit.*/
+ uint32_t reserved0:5; /* Reserved */
+ uint32_t pll_mult:8; /* This setting controls the multiplier for the PLL. */
+ uint32_t pll_div:4; /* This setting controls the divider for the PLL. */
+ uint32_t reserved1:12; /* Reserved */
+ };
+
+ uint32_t whole_reg;
+
+} link_misc_perst_clk_ctrl;
+
+
+typedef union _link_misc_perst_decoder_ctrl_ {
+ struct {
+ uint32_t bcm_7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/
+ uint32_t res0:3; /* Reserved.No Effect*/
+ uint32_t stop_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
+ uint32_t res1:27; /* Reseved. No Effect */
+ };
+
+ uint32_t whole_reg;
+
+} link_misc_perst_decoder_ctrl;
+
+
+typedef union _desc_low_addr_reg_ {
+ struct {
+ uint32_t list_valid:1;
+ uint32_t reserved:4;
+ uint32_t low_addr:27;
+ };
+
+ uint32_t whole_reg;
+
+} desc_low_addr_reg;
+
+typedef struct _dma_descriptor_ { /* 8 32-bit values */
+ /* 0th u32 */
+ uint32_t sdram_buff_addr:28; /* bits 0-27: SDRAM Address */
+ uint32_t res0:4; /* bits 28-31: Reserved */
+
+ /* 1st u32 */
+ uint32_t buff_addr_low; /* 1 buffer address low */
+ uint32_t buff_addr_high; /* 2 buffer address high */
+
+ /* 3rd u32 */
+ uint32_t res2:2; /* 0-1 - Reserved */
+ uint32_t xfer_size:23; /* 2-24 = Xfer size in words */
+ uint32_t res3:6; /* 25-30 reserved */
+ uint32_t intr_enable:1; /* 31 - Interrupt After this desc */
+
+ /* 4th u32 */
+ uint32_t endian_xlat_align:2; /* 0-1 Endian Translation */
+ uint32_t next_desc_cont:1; /* 2 - Next desc is in contig memory */
+ uint32_t res4:25; /* 3 - 27 Reserved bits */
+ uint32_t fill_bytes:2; /* 28-29 Bits Fill Bytes */
+ uint32_t dma_dir:1; /* 30 bit DMA Direction */
+ uint32_t last_rec_indicator:1; /* 31 bit Last Record Indicator */
+
+ /* 5th u32 */
+ uint32_t next_desc_addr_low; /* 32-bits Next Desc Addr lower */
+
+ /* 6th u32 */
+ uint32_t next_desc_addr_high; /* 32-bits Next Desc Addr Higher */
+
+ /* 7th u32 */
+ uint32_t res8; /* Last 32bits reserved */
+
+} dma_descriptor, *pdma_descriptor;
+
+/*
+ * We will allocate the memory in 4K pages
+ * the linked list will be a list of 32 byte descriptors.
+ * The virtual address will determine what should be freed.
+ */
+typedef struct _dma_desc_mem_ {
+ pdma_descriptor pdma_desc_start; /* 32-bytes for dma descriptor. should be first element */
+ dma_addr_t phy_addr; /* physical address of each DMA desc */
+ uint32_t sz;
+ struct _dma_desc_mem_ *Next; /* points to Next Descriptor in chain */
+
+} dma_desc_mem, *pdma_desc_mem;
+
+
+
+typedef enum _list_sts_ {
+ sts_free = 0,
+
+ /* RX-Y Bits 0:7 */
+ rx_waiting_y_intr = 0x00000001,
+ rx_y_error = 0x00000004,
+
+ /* RX-UV Bits 8:16 */
+ rx_waiting_uv_intr = 0x0000100,
+ rx_uv_error = 0x0000400,
+
+ rx_sts_waiting = (rx_waiting_y_intr|rx_waiting_uv_intr),
+ rx_sts_error = (rx_y_error|rx_uv_error),
+
+ rx_y_mask = 0x000000FF,
+ rx_uv_mask = 0x0000FF00,
+
+} list_sts;
+
+typedef struct _tx_dma_pkt_ {
+ dma_desc_mem desc_mem;
+ hw_comp_callback call_back;
+ crystalhd_dio_req *dio_req;
+ wait_queue_head_t *cb_event;
+ uint32_t list_tag;
+
+} tx_dma_pkt;
+
+typedef struct _crystalhd_rx_dma_pkt {
+ dma_desc_mem desc_mem;
+ crystalhd_dio_req *dio_req;
+ uint32_t pkt_tag;
+ uint32_t flags;
+ BC_PIC_INFO_BLOCK pib;
+ dma_addr_t uv_phy_addr;
+ struct _crystalhd_rx_dma_pkt *next;
+
+} crystalhd_rx_dma_pkt;
+
+struct crystalhd_hw_stats{
+ uint32_t rx_errors;
+ uint32_t tx_errors;
+ uint32_t freeq_count;
+ uint32_t rdyq_count;
+ uint32_t num_interrupts;
+ uint32_t dev_interrupts;
+ uint32_t cin_busy;
+ uint32_t pause_cnt;
+};
+
+struct crystalhd_hw {
+ tx_dma_pkt tx_pkt_pool[DMA_ENGINE_CNT];
+ spinlock_t lock;
+
+ uint32_t tx_ioq_tag_seed;
+ uint32_t tx_list_post_index;
+
+ crystalhd_rx_dma_pkt *rx_pkt_pool_head;
+ uint32_t rx_pkt_tag_seed;
+
+ bool dev_started;
+ void *adp;
+
+ wait_queue_head_t *pfw_cmd_event;
+ int fwcmd_evt_sts;
+
+ uint32_t pib_del_Q_addr;
+ uint32_t pib_rel_Q_addr;
+
+ crystalhd_dioq_t *tx_freeq;
+ crystalhd_dioq_t *tx_actq;
+
+ /* Rx DMA Engine Specific Locks */
+ spinlock_t rx_lock;
+ uint32_t rx_list_post_index;
+ list_sts rx_list_sts[DMA_ENGINE_CNT];
+ crystalhd_dioq_t *rx_rdyq;
+ crystalhd_dioq_t *rx_freeq;
+ crystalhd_dioq_t *rx_actq;
+ uint32_t stop_pending;
+
+ /* HW counters.. */
+ struct crystalhd_hw_stats stats;
+
+ /* Core clock in MHz */
+ uint32_t core_clock_mhz;
+ uint32_t prev_n;
+ uint32_t pwr_lock;
+};
+
+/* Clock defines for power control */
+#define CLOCK_PRESET 175
+
+/* DMA engine register BIT mask wrappers.. */
+#define DMA_START_BIT MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK
+
+#define GET_RX_INTR_MASK (INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK | \
+ INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK | \
+ INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK | \
+ INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK | \
+ INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK | \
+ INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK | \
+ INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK | \
+ INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
+
+#define GET_Y0_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
+
+#define GET_UV0_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
+
+#define GET_Y1_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \
+ MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
+
+#define GET_UV1_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \
+ MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
+
+
+/**** API Exposed to the other layers ****/
+BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp,
+ void *buffer, uint32_t sz);
+BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd);
+bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_open(struct crystalhd_hw *, struct crystalhd_adp *);
+BC_STATUS crystalhd_hw_close(struct crystalhd_hw *);
+BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *);
+BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *);
+
+
+BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq,
+ hw_comp_callback call_back,
+ wait_queue_head_t *cb_event,
+ uint32_t *list_id, uint8_t data_flags);
+
+BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id);
+BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
+ crystalhd_dio_req *ioreq, bool en_post);
+BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
+ BC_PIC_INFO_BLOCK *pib,
+ crystalhd_dio_req **ioreq);
+BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw);
+BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw);
+void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats);
+
+/* API to program the core clock on the decoder */
+BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *);
+
+#endif
diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c
new file mode 100644
index 00000000000..54bad652c0c
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_lnx.c
@@ -0,0 +1,766 @@
+/***************************************************************************
+ BCM70010 Linux driver
+ Copyright (c) 2005-2009, Broadcom Corporation.
+
+ This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+***************************************************************************/
+
+#include <linux/version.h>
+#include <linux/slab.h>
+
+#include "crystalhd_lnx.h"
+
+static struct class *crystalhd_class;
+
+static struct crystalhd_adp *g_adp_info;
+
+static irqreturn_t chd_dec_isr(int irq, void *arg)
+{
+ struct crystalhd_adp *adp = (struct crystalhd_adp *) arg;
+ int rc = 0;
+ if (adp)
+ rc = crystalhd_cmd_interrupt(&adp->cmds);
+
+ return IRQ_RETVAL(rc);
+}
+
+static int chd_dec_enable_int(struct crystalhd_adp *adp)
+{
+ int rc = 0;
+
+ if (!adp || !adp->pdev) {
+ BCMLOG_ERR("Invalid arg!!\n");
+ return -EINVAL;
+ }
+
+ if (adp->pdev->msi_enabled)
+ adp->msi = 1;
+ else
+ adp->msi = pci_enable_msi(adp->pdev);
+
+ rc = request_irq(adp->pdev->irq, chd_dec_isr, IRQF_SHARED,
+ adp->name, (void *)adp);
+ if (rc) {
+ BCMLOG_ERR("Interrupt request failed.. \n");
+ pci_disable_msi(adp->pdev);
+ }
+
+ return rc;
+}
+
+static int chd_dec_disable_int(struct crystalhd_adp *adp)
+{
+ if (!adp || !adp->pdev) {
+ BCMLOG_ERR("Invalid arg!!\n");
+ return -EINVAL;
+ }
+
+ free_irq(adp->pdev->irq, adp);
+
+ if (adp->msi)
+ pci_disable_msi(adp->pdev);
+
+ return 0;
+}
+
+crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr)
+{
+ unsigned long flags = 0;
+ crystalhd_ioctl_data *temp;
+
+ if (!adp)
+ return NULL;
+
+ spin_lock_irqsave(&adp->lock, flags);
+
+ temp = adp->idata_free_head;
+ if (temp) {
+ adp->idata_free_head = adp->idata_free_head->next;
+ memset(temp, 0, sizeof(*temp));
+ }
+
+ spin_unlock_irqrestore(&adp->lock, flags);
+ return temp;
+}
+
+void chd_dec_free_iodata(struct crystalhd_adp *adp, crystalhd_ioctl_data *iodata,
+ bool isr)
+{
+ unsigned long flags = 0;
+
+ if (!adp || !iodata)
+ return;
+
+ spin_lock_irqsave(&adp->lock, flags);
+ iodata->next = adp->idata_free_head;
+ adp->idata_free_head = iodata;
+ spin_unlock_irqrestore(&adp->lock, flags);
+}
+
+static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int set)
+{
+ int rc;
+
+ if (!ud || !dr) {
+ BCMLOG_ERR("Invalid arg \n");
+ return -EINVAL;
+ }
+
+ if (set)
+ rc = copy_to_user((void *)ud, dr, size);
+ else
+ rc = copy_from_user(dr, (void *)ud, size);
+
+ if (rc) {
+ BCMLOG_ERR("Invalid args for command \n");
+ rc = -EFAULT;
+ }
+
+ return rc;
+}
+
+static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, crystalhd_ioctl_data *io,
+ uint32_t m_sz, unsigned long ua)
+{
+ unsigned long ua_off;
+ int rc = 0;
+
+ if (!adp || !io || !ua || !m_sz) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return -EINVAL;
+ }
+
+ io->add_cdata = vmalloc(m_sz);
+ if (!io->add_cdata) {
+ BCMLOG_ERR("kalloc fail for sz:%x\n", m_sz);
+ return -ENOMEM;
+ }
+
+ io->add_cdata_sz = m_sz;
+ ua_off = ua + sizeof(io->udata);
+ rc = crystalhd_user_data(ua_off, io->add_cdata, io->add_cdata_sz, 0);
+ if (rc) {
+ BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n",
+ io->add_cdata_sz, (unsigned int)ua_off);
+ if (io->add_cdata) {
+ kfree(io->add_cdata);
+ io->add_cdata = NULL;
+ }
+ return -ENODATA;
+ }
+
+ return rc;
+}
+
+static int chd_dec_release_cdata(struct crystalhd_adp *adp,
+ crystalhd_ioctl_data *io, unsigned long ua)
+{
+ unsigned long ua_off;
+ int rc;
+
+ if (!adp || !io || !ua) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return -EINVAL;
+ }
+
+ if (io->cmd != BCM_IOC_FW_DOWNLOAD) {
+ ua_off = ua + sizeof(io->udata);
+ rc = crystalhd_user_data(ua_off, io->add_cdata,
+ io->add_cdata_sz, 1);
+ if (rc) {
+ BCMLOG_ERR("failed to push add_cdata sz:%x ua_off:%x\n",
+ io->add_cdata_sz, (unsigned int)ua_off);
+ return -ENODATA;
+ }
+ }
+
+ if (io->add_cdata) {
+ vfree(io->add_cdata);
+ io->add_cdata = NULL;
+ }
+
+ return 0;
+}
+
+static int chd_dec_proc_user_data(struct crystalhd_adp *adp,
+ crystalhd_ioctl_data *io,
+ unsigned long ua, int set)
+{
+ int rc;
+ uint32_t m_sz = 0;
+
+ if (!adp || !io || !ua) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return -EINVAL;
+ }
+
+ rc = crystalhd_user_data(ua, &io->udata, sizeof(io->udata), set);
+ if (rc) {
+ BCMLOG_ERR("failed to %s iodata \n", (set ? "set" : "get"));
+ return rc;
+ }
+
+ switch (io->cmd) {
+ case BCM_IOC_MEM_RD:
+ case BCM_IOC_MEM_WR:
+ case BCM_IOC_FW_DOWNLOAD:
+ m_sz = io->udata.u.devMem.NumDwords * 4;
+ if (set)
+ rc = chd_dec_release_cdata(adp, io, ua);
+ else
+ rc = chd_dec_fetch_cdata(adp, io, m_sz, ua);
+ break;
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua,
+ uint32_t uid, uint32_t cmd, crystalhd_cmd_proc func)
+{
+ int rc;
+ crystalhd_ioctl_data *temp;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ temp = chd_dec_alloc_iodata(adp, 0);
+ if (!temp) {
+ BCMLOG_ERR("Failed to get iodata..\n");
+ return -EINVAL;
+ }
+
+ temp->u_id = uid;
+ temp->cmd = cmd;
+
+ rc = chd_dec_proc_user_data(adp, temp, ua, 0);
+ if (!rc) {
+ sts = func(&adp->cmds, temp);
+ if (sts == BC_STS_PENDING)
+ sts = BC_STS_NOT_IMPL;
+ temp->udata.RetSts = sts;
+ rc = chd_dec_proc_user_data(adp, temp, ua, 1);
+ }
+
+ if (temp) {
+ chd_dec_free_iodata(adp, temp, 0);
+ temp = NULL;
+ }
+
+ return rc;
+}
+
+/* API interfaces */
+static int chd_dec_ioctl(struct inode *in, struct file *fd,
+ unsigned int cmd, unsigned long ua)
+{
+ struct crystalhd_adp *adp = chd_get_adp();
+ crystalhd_cmd_proc cproc;
+ struct crystalhd_user *uc;
+
+ if (!adp || !fd) {
+ BCMLOG_ERR("Invalid adp\n");
+ return -EINVAL;
+ }
+
+ uc = (struct crystalhd_user *)fd->private_data;
+ if (!uc) {
+ BCMLOG_ERR("Failed to get uc\n");
+ return -ENODATA;
+ }
+
+ cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc);
+ if (!cproc) {
+ BCMLOG_ERR("Unhandled command: %d\n", cmd);
+ return -EINVAL;
+ }
+
+ return chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc);
+}
+
+static int chd_dec_open(struct inode *in, struct file *fd)
+{
+ struct crystalhd_adp *adp = chd_get_adp();
+ int rc = 0;
+ BC_STATUS sts = BC_STS_SUCCESS;
+ struct crystalhd_user *uc = NULL;
+
+ BCMLOG_ENTER;
+ if (!adp) {
+ BCMLOG_ERR("Invalid adp\n");
+ return -EINVAL;
+ }
+
+ if (adp->cfg_users >= BC_LINK_MAX_OPENS) {
+ BCMLOG(BCMLOG_INFO, "Already in use.%d\n", adp->cfg_users);
+ return -EBUSY;
+ }
+
+ sts = crystalhd_user_open(&adp->cmds, &uc);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("cmd_user_open - %d \n", sts);
+ rc = -EBUSY;
+ }
+
+ adp->cfg_users++;
+
+ fd->private_data = uc;
+
+ return rc;
+}
+
+static int chd_dec_close(struct inode *in, struct file *fd)
+{
+ struct crystalhd_adp *adp = chd_get_adp();
+ struct crystalhd_user *uc;
+
+ BCMLOG_ENTER;
+ if (!adp) {
+ BCMLOG_ERR("Invalid adp \n");
+ return -EINVAL;
+ }
+
+ uc = (struct crystalhd_user *)fd->private_data;
+ if (!uc) {
+ BCMLOG_ERR("Failed to get uc\n");
+ return -ENODATA;
+ }
+
+ crystalhd_user_close(&adp->cmds, uc);
+
+ adp->cfg_users--;
+
+ return 0;
+}
+
+static const struct file_operations chd_dec_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = chd_dec_ioctl,
+ .open = chd_dec_open,
+ .release = chd_dec_close,
+};
+
+static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp)
+{
+ crystalhd_ioctl_data *temp;
+ struct device *dev;
+ int rc = -ENODEV, i = 0;
+
+ if (!adp)
+ goto fail;
+
+ adp->chd_dec_major = register_chrdev(0, CRYSTALHD_API_NAME,
+ &chd_dec_fops);
+ if (adp->chd_dec_major < 0) {
+ BCMLOG_ERR("Failed to create config dev\n");
+ rc = adp->chd_dec_major;
+ goto fail;
+ }
+
+ /* register crystalhd class */
+ crystalhd_class = class_create(THIS_MODULE, "crystalhd");
+ if (IS_ERR(crystalhd_class)) {
+ BCMLOG_ERR("failed to create class\n");
+ goto fail;
+ }
+
+ dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0),
+ NULL, "crystalhd");
+ if (!dev) {
+ BCMLOG_ERR("failed to create device\n");
+ goto device_create_fail;
+ }
+
+ rc = crystalhd_create_elem_pool(adp, BC_LINK_ELEM_POOL_SZ);
+ if (rc) {
+ BCMLOG_ERR("failed to create device\n");
+ goto elem_pool_fail;
+ }
+
+ /* Allocate general purpose ioctl pool. */
+ for (i = 0; i < CHD_IODATA_POOL_SZ; i++) {
+ /* FIXME: jarod: why atomic? */
+ temp = kzalloc(sizeof(crystalhd_ioctl_data), GFP_ATOMIC);
+ if (!temp) {
+ BCMLOG_ERR("ioctl data pool kzalloc failed\n");
+ rc = -ENOMEM;
+ goto kzalloc_fail;
+ }
+ /* Add to global pool.. */
+ chd_dec_free_iodata(adp, temp, 0);
+ }
+
+ return 0;
+
+kzalloc_fail:
+ crystalhd_delete_elem_pool(adp);
+elem_pool_fail:
+ device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
+device_create_fail:
+ class_destroy(crystalhd_class);
+fail:
+ return rc;
+}
+
+static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp)
+{
+ crystalhd_ioctl_data *temp = NULL;
+ if (!adp)
+ return;
+
+ if (adp->chd_dec_major > 0) {
+ /* unregister crystalhd class */
+ device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
+ unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME);
+ BCMLOG(BCMLOG_INFO, "released api device - %d\n",
+ adp->chd_dec_major);
+ class_destroy(crystalhd_class);
+ }
+ adp->chd_dec_major = 0;
+
+ /* Clear iodata pool.. */
+ do {
+ temp = chd_dec_alloc_iodata(adp, 0);
+ if (temp)
+ kfree(temp);
+ } while (temp);
+
+ crystalhd_delete_elem_pool(adp);
+}
+
+static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
+{
+ int rc;
+ unsigned long bar2 = pci_resource_start(pinfo->pdev, 2);
+ uint32_t mem_len = pci_resource_len(pinfo->pdev, 2);
+ unsigned long bar0 = pci_resource_start(pinfo->pdev, 0);
+ uint32_t i2o_len = pci_resource_len(pinfo->pdev, 0);
+
+ BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x bar0:0x%lx-0x%08x\n",
+ bar2, mem_len, bar0, i2o_len);
+
+ rc = check_mem_region(bar2, mem_len);
+ if (rc) {
+ BCMLOG_ERR("No valid mem region...\n");
+ return -ENOMEM;
+ }
+
+ pinfo->addr = ioremap_nocache(bar2, mem_len);
+ if (!pinfo->addr) {
+ BCMLOG_ERR("Failed to remap mem region...\n");
+ return -ENOMEM;
+ }
+
+ pinfo->pci_mem_start = bar2;
+ pinfo->pci_mem_len = mem_len;
+
+ rc = check_mem_region(bar0, i2o_len);
+ if (rc) {
+ BCMLOG_ERR("No valid mem region...\n");
+ return -ENOMEM;
+ }
+
+ pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len);
+ if (!pinfo->i2o_addr) {
+ BCMLOG_ERR("Failed to remap mem region...\n");
+ return -ENOMEM;
+ }
+
+ pinfo->pci_i2o_start = bar0;
+ pinfo->pci_i2o_len = i2o_len;
+
+ rc = pci_request_regions(pinfo->pdev, pinfo->name);
+ if (rc < 0) {
+ BCMLOG_ERR("Region request failed: %d\n", rc);
+ return rc;
+ }
+
+ BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx i2o_addr:0x%08lx\n",
+ (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr);
+
+ return 0;
+}
+
+static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo)
+{
+ if (!pinfo)
+ return;
+
+ if (pinfo->addr)
+ iounmap(pinfo->addr);
+
+ if (pinfo->i2o_addr)
+ iounmap(pinfo->i2o_addr);
+
+ pci_release_regions(pinfo->pdev);
+}
+
+
+static void __devexit chd_dec_pci_remove(struct pci_dev *pdev)
+{
+ struct crystalhd_adp *pinfo;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ BCMLOG_ENTER;
+
+ pinfo = (struct crystalhd_adp *) pci_get_drvdata(pdev);
+ if (!pinfo) {
+ BCMLOG_ERR("could not get adp\n");
+ return;
+ }
+
+ sts = crystalhd_delete_cmd_context(&pinfo->cmds);
+ if (sts != BC_STS_SUCCESS)
+ BCMLOG_ERR("cmd delete :%d \n", sts);
+
+ chd_dec_release_chdev(pinfo);
+
+ chd_dec_disable_int(pinfo);
+
+ chd_pci_release_mem(pinfo);
+ pci_disable_device(pinfo->pdev);
+
+ kfree(pinfo);
+ g_adp_info = NULL;
+}
+
+static int __devinit chd_dec_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *entry)
+{
+ struct crystalhd_adp *pinfo;
+ int rc;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ BCMLOG(BCMLOG_DBG, "PCI_INFO: Vendor:0x%04x Device:0x%04x "
+ "s_vendor:0x%04x s_device: 0x%04x\n",
+ pdev->vendor, pdev->device, pdev->subsystem_vendor,
+ pdev->subsystem_device);
+
+ /* FIXME: jarod: why atomic? */
+ pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_ATOMIC);
+ if (!pinfo) {
+ BCMLOG_ERR("Failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ pinfo->pdev = pdev;
+
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ BCMLOG_ERR("Failed to enable PCI device\n");
+ return rc;
+ }
+
+ snprintf(pinfo->name, 31, "crystalhd_pci_e:%d:%d:%d",
+ pdev->bus->number, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn));
+
+ rc = chd_pci_reserve_mem(pinfo);
+ if (rc) {
+ BCMLOG_ERR("Failed to setup memory regions.\n");
+ return -ENOMEM;
+ }
+
+ pinfo->present = 1;
+ pinfo->drv_data = entry->driver_data;
+
+ /* Setup adapter level lock.. */
+ spin_lock_init(&pinfo->lock);
+
+ /* setup api stuff.. */
+ chd_dec_init_chdev(pinfo);
+ rc = chd_dec_enable_int(pinfo);
+ if (rc) {
+ BCMLOG_ERR("_enable_int err:%d \n", rc);
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+
+ /* Set dma mask... */
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ pinfo->dmabits = 64;
+ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ pinfo->dmabits = 32;
+ } else {
+ BCMLOG_ERR("Unabled to setup DMA %d\n", rc);
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+
+ sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("cmd setup :%d \n", sts);
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+
+ pci_set_master(pdev);
+
+ pci_set_drvdata(pdev, pinfo);
+
+ g_adp_info = pinfo;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct crystalhd_adp *adp;
+ crystalhd_ioctl_data *temp;
+ BC_STATUS sts = BC_STS_SUCCESS;
+
+ adp = (struct crystalhd_adp *)pci_get_drvdata(pdev);
+ if (!adp) {
+ BCMLOG_ERR("could not get adp\n");
+ return -ENODEV;
+ }
+
+ temp = chd_dec_alloc_iodata(adp, false);
+ if (!temp) {
+ BCMLOG_ERR("could not get ioctl data\n");
+ return -ENODEV;
+ }
+
+ sts = crystalhd_suspend(&adp->cmds, temp);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("BCM70012 Suspend %d\n", sts);
+ return -ENODEV;
+ }
+
+ chd_dec_free_iodata(adp, temp, false);
+ chd_dec_disable_int(adp);
+ pci_save_state(pdev);
+
+ /* Disable IO/bus master/irq router */
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ return 0;
+}
+
+int chd_dec_pci_resume(struct pci_dev *pdev)
+{
+ struct crystalhd_adp *adp;
+ BC_STATUS sts = BC_STS_SUCCESS;
+ int rc;
+
+ adp = (struct crystalhd_adp *)pci_get_drvdata(pdev);
+ if (!adp) {
+ BCMLOG_ERR("could not get adp\n");
+ return -ENODEV;
+ }
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ /* device's irq possibly is changed, driver should take care */
+ if (pci_enable_device(pdev)) {
+ BCMLOG_ERR("Failed to enable PCI device\n");
+ return 1;
+ }
+
+ pci_set_master(pdev);
+
+ rc = chd_dec_enable_int(adp);
+ if (rc) {
+ BCMLOG_ERR("_enable_int err:%d \n", rc);
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+
+ sts = crystalhd_resume(&adp->cmds);
+ if (sts != BC_STS_SUCCESS) {
+ BCMLOG_ERR("BCM70012 Resume %d\n", sts);
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+#endif
+
+static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = {
+ { PCI_VDEVICE(BROADCOM, 0x1612), 8 },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table);
+
+static struct pci_driver bc_chd_70012_driver = {
+ .name = "Broadcom 70012 Decoder",
+ .probe = chd_dec_pci_probe,
+ .remove = __devexit_p(chd_dec_pci_remove),
+ .id_table = chd_dec_pci_id_table,
+#ifdef CONFIG_PM
+ .suspend = chd_dec_pci_suspend,
+ .resume = chd_dec_pci_resume
+#endif
+};
+
+void chd_set_log_level(struct crystalhd_adp *adp, char *arg)
+{
+ if ((!arg) || (strlen(arg) < 3))
+ g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA;
+ else if (!strncmp(arg, "sstep", 5))
+ g_linklog_level = BCMLOG_INFO | BCMLOG_DATA | BCMLOG_DBG |
+ BCMLOG_SSTEP | BCMLOG_ERROR;
+ else if (!strncmp(arg, "info", 4))
+ g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO;
+ else if (!strncmp(arg, "debug", 5))
+ g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO |
+ BCMLOG_DBG;
+ else if (!strncmp(arg, "pball", 5))
+ g_linklog_level = 0xFFFFFFFF & ~(BCMLOG_SPINLOCK);
+ else if (!strncmp(arg, "silent", 6))
+ g_linklog_level = 0;
+ else
+ g_linklog_level = 0;
+}
+
+struct crystalhd_adp *chd_get_adp(void)
+{
+ return g_adp_info;
+}
+
+static int __init chd_dec_module_init(void)
+{
+ int rc;
+
+ chd_set_log_level(NULL, "debug");
+ BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d \n",
+ crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev);
+
+ rc = pci_register_driver(&bc_chd_70012_driver);
+
+ if (rc < 0)
+ BCMLOG_ERR("Could not find any devices. err:%d \n", rc);
+
+ return rc;
+}
+module_init(chd_dec_module_init);
+
+static void __exit chd_dec_module_cleanup(void)
+{
+ BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d \n",
+ crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev);
+
+ pci_unregister_driver(&bc_chd_70012_driver);
+}
+module_exit(chd_dec_module_cleanup);
+
+MODULE_AUTHOR("Naren Sankar <nsankar@broadcom.com>");
+MODULE_AUTHOR("Prasad Bolisetty <prasadb@broadcom.com>");
+MODULE_DESCRIPTION(CRYSTAL_HD_NAME);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("bcm70012");
diff --git a/drivers/staging/crystalhd/crystalhd_lnx.h b/drivers/staging/crystalhd/crystalhd_lnx.h
new file mode 100644
index 00000000000..d338ae97a4c
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_lnx.h
@@ -0,0 +1,96 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_lnx . c
+ *
+ * Description:
+ * BCM70012 Linux driver
+ *
+ * HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_LNX_H_
+#define _CRYSTALHD_LNX_H_
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/vmalloc.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include "crystalhd_cmds.h"
+
+#define CRYSTAL_HD_NAME "Broadcom Crystal HD Decoder (BCM70012) Driver"
+
+
+/* OS specific PCI information structure and adapter information. */
+struct crystalhd_adp {
+ /* Hardware borad/PCI specifics */
+ char name[32];
+ struct pci_dev *pdev;
+
+ unsigned long pci_mem_start;
+ uint32_t pci_mem_len;
+ void *addr;
+
+ unsigned long pci_i2o_start;
+ uint32_t pci_i2o_len;
+ void *i2o_addr;
+
+ unsigned int drv_data;
+ unsigned int dmabits; /* 32 | 64 */
+ unsigned int registered;
+ unsigned int present;
+ unsigned int msi;
+
+ spinlock_t lock;
+
+ /* API Related */
+ unsigned int chd_dec_major;
+ unsigned int cfg_users;
+
+ crystalhd_ioctl_data *idata_free_head; /* ioctl data pool */
+ crystalhd_elem_t *elem_pool_head; /* Queue element pool */
+
+ struct crystalhd_cmd cmds;
+
+ crystalhd_dio_req *ua_map_free_head;
+ struct pci_pool *fill_byte_pool;
+};
+
+
+struct crystalhd_adp *chd_get_adp(void);
+void chd_set_log_level(struct crystalhd_adp *adp, char *arg);
+
+#endif
+
diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c
new file mode 100644
index 00000000000..73593b078b3
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_misc.c
@@ -0,0 +1,1032 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_misc . c
+ *
+ * Description:
+ * BCM70012 Linux driver misc routines.
+ *
+ * HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#include <linux/slab.h>
+
+#include "crystalhd_misc.h"
+#include "crystalhd_lnx.h"
+
+uint32_t g_linklog_level;
+
+static inline uint32_t crystalhd_dram_rd(struct crystalhd_adp *adp, uint32_t mem_off)
+{
+ crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
+ return bc_dec_reg_rd(adp, (0x00380000 | (mem_off & 0x0007FFFF)));
+}
+
+static inline void crystalhd_dram_wr(struct crystalhd_adp *adp, uint32_t mem_off, uint32_t val)
+{
+ crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
+ bc_dec_reg_wr(adp, (0x00380000 | (mem_off & 0x0007FFFF)), val);
+}
+
+static inline BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp, uint32_t start_off, uint32_t cnt)
+{
+ return BC_STS_SUCCESS;
+}
+
+static crystalhd_dio_req *crystalhd_alloc_dio(struct crystalhd_adp *adp)
+{
+ unsigned long flags = 0;
+ crystalhd_dio_req *temp = NULL;
+
+ if (!adp) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return temp;
+ }
+
+ spin_lock_irqsave(&adp->lock, flags);
+ temp = adp->ua_map_free_head;
+ if (temp)
+ adp->ua_map_free_head = adp->ua_map_free_head->next;
+ spin_unlock_irqrestore(&adp->lock, flags);
+
+ return temp;
+}
+
+static void crystalhd_free_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio)
+{
+ unsigned long flags = 0;
+
+ if (!adp || !dio)
+ return;
+ spin_lock_irqsave(&adp->lock, flags);
+ dio->sig = crystalhd_dio_inv;
+ dio->page_cnt = 0;
+ dio->fb_size = 0;
+ memset(&dio->uinfo, 0, sizeof(dio->uinfo));
+ dio->next = adp->ua_map_free_head;
+ adp->ua_map_free_head = dio;
+ spin_unlock_irqrestore(&adp->lock, flags);
+}
+
+static crystalhd_elem_t *crystalhd_alloc_elem(struct crystalhd_adp *adp)
+{
+ unsigned long flags = 0;
+ crystalhd_elem_t *temp = NULL;
+
+ if (!adp)
+ return temp;
+ spin_lock_irqsave(&adp->lock, flags);
+ temp = adp->elem_pool_head;
+ if (temp) {
+ adp->elem_pool_head = adp->elem_pool_head->flink;
+ memset(temp, 0, sizeof(*temp));
+ }
+ spin_unlock_irqrestore(&adp->lock, flags);
+
+ return temp;
+}
+static void crystalhd_free_elem(struct crystalhd_adp *adp, crystalhd_elem_t *elem)
+{
+ unsigned long flags = 0;
+
+ if (!adp || !elem)
+ return;
+ spin_lock_irqsave(&adp->lock, flags);
+ elem->flink = adp->elem_pool_head;
+ adp->elem_pool_head = elem;
+ spin_unlock_irqrestore(&adp->lock, flags);
+}
+
+static inline void crystalhd_set_sg(struct scatterlist *sg, struct page *page,
+ unsigned int len, unsigned int offset)
+{
+ sg_set_page(sg, page, len, offset);
+#ifdef CONFIG_X86_64
+ sg->dma_length = len;
+#endif
+}
+
+static inline void crystalhd_init_sg(struct scatterlist *sg, unsigned int entries)
+{
+ /* http://lkml.org/lkml/2007/11/27/68 */
+ sg_init_table(sg, entries);
+}
+
+/*========================== Extern ========================================*/
+/**
+ * bc_dec_reg_rd - Read 7412's device register.
+ * @adp: Adapter instance
+ * @reg_off: Register offset.
+ *
+ * Return:
+ * 32bit value read
+ *
+ * 7412's device register read routine. This interface use
+ * 7412's device access range mapped from BAR-2 (4M) of PCIe
+ * configuration space.
+ */
+uint32_t bc_dec_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off)
+{
+ if (!adp || (reg_off > adp->pci_mem_len)) {
+ BCMLOG_ERR("dec_rd_reg_off outof range: 0x%08x\n", reg_off);
+ return 0;
+ }
+
+ return readl(adp->addr + reg_off);
+}
+
+/**
+ * bc_dec_reg_wr - Write 7412's device register
+ * @adp: Adapter instance
+ * @reg_off: Register offset.
+ * @val: Dword value to be written.
+ *
+ * Return:
+ * none.
+ *
+ * 7412's device register write routine. This interface use
+ * 7412's device access range mapped from BAR-2 (4M) of PCIe
+ * configuration space.
+ */
+void bc_dec_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val)
+{
+ if (!adp || (reg_off > adp->pci_mem_len)) {
+ BCMLOG_ERR("dec_wr_reg_off outof range: 0x%08x\n", reg_off);
+ return;
+ }
+ writel(val, adp->addr + reg_off);
+ udelay(8);
+}
+
+/**
+ * crystalhd_reg_rd - Read Link's device register.
+ * @adp: Adapter instance
+ * @reg_off: Register offset.
+ *
+ * Return:
+ * 32bit value read
+ *
+ * Link device register read routine. This interface use
+ * Link's device access range mapped from BAR-1 (64K) of PCIe
+ * configuration space.
+ *
+ */
+uint32_t crystalhd_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off)
+{
+ if (!adp || (reg_off > adp->pci_i2o_len)) {
+ BCMLOG_ERR("link_rd_reg_off outof range: 0x%08x\n", reg_off);
+ return 0;
+ }
+ return readl(adp->i2o_addr + reg_off);
+}
+
+/**
+ * crystalhd_reg_wr - Write Link's device register
+ * @adp: Adapter instance
+ * @reg_off: Register offset.
+ * @val: Dword value to be written.
+ *
+ * Return:
+ * none.
+ *
+ * Link device register write routine. This interface use
+ * Link's device access range mapped from BAR-1 (64K) of PCIe
+ * configuration space.
+ *
+ */
+void crystalhd_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val)
+{
+ if (!adp || (reg_off > adp->pci_i2o_len)) {
+ BCMLOG_ERR("link_wr_reg_off outof range: 0x%08x\n", reg_off);
+ return;
+ }
+ writel(val, adp->i2o_addr + reg_off);
+}
+
+/**
+ * crystalhd_mem_rd - Read data from 7412's DRAM area.
+ * @adp: Adapter instance
+ * @start_off: Start offset.
+ * @dw_cnt: Count in dwords.
+ * @rd_buff: Buffer to copy the data from dram.
+ *
+ * Return:
+ * Status.
+ *
+ * 7412's Dram read routine.
+ */
+BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off,
+ uint32_t dw_cnt, uint32_t *rd_buff)
+{
+ uint32_t ix = 0;
+
+ if (!adp || !rd_buff ||
+ (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) {
+ BCMLOG_ERR("Invalid arg \n");
+ return BC_STS_INV_ARG;
+ }
+ for (ix = 0; ix < dw_cnt; ix++)
+ rd_buff[ix] = crystalhd_dram_rd(adp, (start_off + (ix * 4)));
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_mem_wr - Write data to 7412's DRAM area.
+ * @adp: Adapter instance
+ * @start_off: Start offset.
+ * @dw_cnt: Count in dwords.
+ * @wr_buff: Data Buffer to be written.
+ *
+ * Return:
+ * Status.
+ *
+ * 7412's Dram write routine.
+ */
+BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off,
+ uint32_t dw_cnt, uint32_t *wr_buff)
+{
+ uint32_t ix = 0;
+
+ if (!adp || !wr_buff ||
+ (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) {
+ BCMLOG_ERR("Invalid arg \n");
+ return BC_STS_INV_ARG;
+ }
+
+ for (ix = 0; ix < dw_cnt; ix++)
+ crystalhd_dram_wr(adp, (start_off + (ix * 4)), wr_buff[ix]);
+
+ return BC_STS_SUCCESS;
+}
+/**
+ * crystalhd_pci_cfg_rd - PCIe config read
+ * @adp: Adapter instance
+ * @off: PCI config space offset.
+ * @len: Size -- Byte, Word & dword.
+ * @val: Value read
+ *
+ * Return:
+ * Status.
+ *
+ * Get value from Link's PCIe config space.
+ */
+BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off,
+ uint32_t len, uint32_t *val)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+ int rc = 0;
+
+ if (!adp || !val) {
+ BCMLOG_ERR("Invalid arg \n");
+ return BC_STS_INV_ARG;
+ }
+
+ switch (len) {
+ case 1:
+ rc = pci_read_config_byte(adp->pdev, off, (u8 *)val);
+ break;
+ case 2:
+ rc = pci_read_config_word(adp->pdev, off, (u16 *)val);
+ break;
+ case 4:
+ rc = pci_read_config_dword(adp->pdev, off, (u32 *)val);
+ break;
+ default:
+ rc = -EINVAL;
+ sts = BC_STS_INV_ARG;
+ BCMLOG_ERR("Invalid len:%d\n", len);
+ };
+
+ if (rc && (sts == BC_STS_SUCCESS))
+ sts = BC_STS_ERROR;
+
+ return sts;
+}
+
+/**
+ * crystalhd_pci_cfg_wr - PCIe config write
+ * @adp: Adapter instance
+ * @off: PCI config space offset.
+ * @len: Size -- Byte, Word & dword.
+ * @val: Value to be written
+ *
+ * Return:
+ * Status.
+ *
+ * Set value to Link's PCIe config space.
+ */
+BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *adp, uint32_t off,
+ uint32_t len, uint32_t val)
+{
+ BC_STATUS sts = BC_STS_SUCCESS;
+ int rc = 0;
+
+ if (!adp || !val) {
+ BCMLOG_ERR("Invalid arg \n");
+ return BC_STS_INV_ARG;
+ }
+
+ switch (len) {
+ case 1:
+ rc = pci_write_config_byte(adp->pdev, off, (u8)val);
+ break;
+ case 2:
+ rc = pci_write_config_word(adp->pdev, off, (u16)val);
+ break;
+ case 4:
+ rc = pci_write_config_dword(adp->pdev, off, val);
+ break;
+ default:
+ rc = -EINVAL;
+ sts = BC_STS_INV_ARG;
+ BCMLOG_ERR("Invalid len:%d\n", len);
+ };
+
+ if (rc && (sts == BC_STS_SUCCESS))
+ sts = BC_STS_ERROR;
+
+ return sts;
+}
+
+/**
+ * bc_kern_dma_alloc - Allocate memory for Dma rings
+ * @adp: Adapter instance
+ * @sz: Size of the memory to allocate.
+ * @phy_addr: Physical address of the memory allocated.
+ * Typedef to system's dma_addr_t (u64)
+ *
+ * Return:
+ * Pointer to allocated memory..
+ *
+ * Wrapper to Linux kernel interface.
+ *
+ */
+void *bc_kern_dma_alloc(struct crystalhd_adp *adp, uint32_t sz,
+ dma_addr_t *phy_addr)
+{
+ void *temp = NULL;
+
+ if (!adp || !sz || !phy_addr) {
+ BCMLOG_ERR("Invalide Arg..\n");
+ return temp;
+ }
+
+ temp = pci_alloc_consistent(adp->pdev, sz, phy_addr);
+ if (temp)
+ memset(temp, 0, sz);
+
+ return temp;
+}
+
+/**
+ * bc_kern_dma_free - Release Dma ring memory.
+ * @adp: Adapter instance
+ * @sz: Size of the memory to allocate.
+ * @ka: Kernel virtual address returned during _dio_alloc()
+ * @phy_addr: Physical address of the memory allocated.
+ * Typedef to system's dma_addr_t (u64)
+ *
+ * Return:
+ * none.
+ */
+void bc_kern_dma_free(struct crystalhd_adp *adp, uint32_t sz, void *ka,
+ dma_addr_t phy_addr)
+{
+ if (!adp || !ka || !sz || !phy_addr) {
+ BCMLOG_ERR("Invalide Arg..\n");
+ return;
+ }
+
+ pci_free_consistent(adp->pdev, sz, ka, phy_addr);
+}
+
+/**
+ * crystalhd_create_dioq - Create Generic DIO queue
+ * @adp: Adapter instance
+ * @dioq_hnd: Handle to the dio queue created
+ * @cb : Optional - Call back To free the element.
+ * @cbctx: Context to pass to callback.
+ *
+ * Return:
+ * status
+ *
+ * Initialize Generic DIO queue to hold any data. Callback
+ * will be used to free elements while deleting the queue.
+ */
+BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp,
+ crystalhd_dioq_t **dioq_hnd,
+ crystalhd_data_free_cb cb, void *cbctx)
+{
+ crystalhd_dioq_t *dioq = NULL;
+
+ if (!adp || !dioq_hnd) {
+ BCMLOG_ERR("Invalid arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ dioq = kzalloc(sizeof(*dioq), GFP_KERNEL);
+ if (!dioq)
+ return BC_STS_INSUFF_RES;
+
+ spin_lock_init(&dioq->lock);
+ dioq->sig = BC_LINK_DIOQ_SIG;
+ dioq->head = (crystalhd_elem_t *)&dioq->head;
+ dioq->tail = (crystalhd_elem_t *)&dioq->head;
+ crystalhd_create_event(&dioq->event);
+ dioq->adp = adp;
+ dioq->data_rel_cb = cb;
+ dioq->cb_context = cbctx;
+ *dioq_hnd = dioq;
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_delete_dioq - Delete Generic DIO queue
+ * @adp: Adapter instance
+ * @dioq: DIOQ instance..
+ *
+ * Return:
+ * None.
+ *
+ * Release Generic DIO queue. This function will remove
+ * all the entries from the Queue and will release data
+ * by calling the call back provided during creation.
+ *
+ */
+void crystalhd_delete_dioq(struct crystalhd_adp *adp, crystalhd_dioq_t *dioq)
+{
+ void *temp;
+
+ if (!dioq || (dioq->sig != BC_LINK_DIOQ_SIG))
+ return;
+
+ do {
+ temp = crystalhd_dioq_fetch(dioq);
+ if (temp && dioq->data_rel_cb)
+ dioq->data_rel_cb(dioq->cb_context, temp);
+ } while (temp);
+ dioq->sig = 0;
+ kfree(dioq);
+}
+
+/**
+ * crystalhd_dioq_add - Add new DIO request element.
+ * @ioq: DIO queue instance
+ * @t: DIO request to be added.
+ * @wake: True - Wake up suspended process.
+ * @tag: Special tag to assign - For search and get.
+ *
+ * Return:
+ * Status.
+ *
+ * Insert new element to Q tail.
+ */
+BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data,
+ bool wake, uint32_t tag)
+{
+ unsigned long flags = 0;
+ crystalhd_elem_t *tmp;
+
+ if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !data) {
+ BCMLOG_ERR("Invalid arg!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ tmp = crystalhd_alloc_elem(ioq->adp);
+ if (!tmp) {
+ BCMLOG_ERR("No free elements.\n");
+ return BC_STS_INSUFF_RES;
+ }
+
+ tmp->data = data;
+ tmp->tag = tag;
+ spin_lock_irqsave(&ioq->lock, flags);
+ tmp->flink = (crystalhd_elem_t *)&ioq->head;
+ tmp->blink = ioq->tail;
+ tmp->flink->blink = tmp;
+ tmp->blink->flink = tmp;
+ ioq->count++;
+ spin_unlock_irqrestore(&ioq->lock, flags);
+
+ if (wake)
+ crystalhd_set_event(&ioq->event);
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_dioq_fetch - Fetch element from head.
+ * @ioq: DIO queue instance
+ *
+ * Return:
+ * data element from the head..
+ *
+ * Remove an element from Queue.
+ */
+void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq)
+{
+ unsigned long flags = 0;
+ crystalhd_elem_t *tmp;
+ crystalhd_elem_t *ret = NULL;
+ void *data = NULL;
+
+ if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) {
+ BCMLOG_ERR("Invalid arg!!\n");
+ return data;
+ }
+
+ spin_lock_irqsave(&ioq->lock, flags);
+ tmp = ioq->head;
+ if (tmp != (crystalhd_elem_t *)&ioq->head) {
+ ret = tmp;
+ tmp->flink->blink = tmp->blink;
+ tmp->blink->flink = tmp->flink;
+ ioq->count--;
+ }
+ spin_unlock_irqrestore(&ioq->lock, flags);
+ if (ret) {
+ data = ret->data;
+ crystalhd_free_elem(ioq->adp, ret);
+ }
+
+ return data;
+}
+/**
+ * crystalhd_dioq_find_and_fetch - Search the tag and Fetch element
+ * @ioq: DIO queue instance
+ * @tag: Tag to search for.
+ *
+ * Return:
+ * element from the head..
+ *
+ * Search TAG and remove the element.
+ */
+void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag)
+{
+ unsigned long flags = 0;
+ crystalhd_elem_t *tmp;
+ crystalhd_elem_t *ret = NULL;
+ void *data = NULL;
+
+ if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) {
+ BCMLOG_ERR("Invalid arg!!\n");
+ return data;
+ }
+
+ spin_lock_irqsave(&ioq->lock, flags);
+ tmp = ioq->head;
+ while (tmp != (crystalhd_elem_t *)&ioq->head) {
+ if (tmp->tag == tag) {
+ ret = tmp;
+ tmp->flink->blink = tmp->blink;
+ tmp->blink->flink = tmp->flink;
+ ioq->count--;
+ break;
+ }
+ tmp = tmp->flink;
+ }
+ spin_unlock_irqrestore(&ioq->lock, flags);
+
+ if (ret) {
+ data = ret->data;
+ crystalhd_free_elem(ioq->adp, ret);
+ }
+
+ return data;
+}
+
+/**
+ * crystalhd_dioq_fetch_wait - Fetch element from Head.
+ * @ioq: DIO queue instance
+ * @to_secs: Wait timeout in seconds..
+ *
+ * Return:
+ * element from the head..
+ *
+ * Return element from head if Q is not empty. Wait for new element
+ * if Q is empty for Timeout seconds.
+ */
+void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs,
+ uint32_t *sig_pend)
+{
+ unsigned long flags = 0;
+ int rc = 0, count;
+ void *tmp = NULL;
+
+ if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !to_secs || !sig_pend) {
+ BCMLOG_ERR("Invalid arg!!\n");
+ return tmp;
+ }
+
+ count = to_secs;
+ spin_lock_irqsave(&ioq->lock, flags);
+ while ((ioq->count == 0) && count) {
+ spin_unlock_irqrestore(&ioq->lock, flags);
+
+ crystalhd_wait_on_event(&ioq->event, (ioq->count > 0), 1000, rc, 0);
+ if (rc == 0) {
+ goto out;
+ } else if (rc == -EINTR) {
+ BCMLOG(BCMLOG_INFO, "Cancelling fetch wait\n");
+ *sig_pend = 1;
+ return tmp;
+ }
+ spin_lock_irqsave(&ioq->lock, flags);
+ count--;
+ }
+ spin_unlock_irqrestore(&ioq->lock, flags);
+
+out:
+ return crystalhd_dioq_fetch(ioq);
+}
+
+/**
+ * crystalhd_map_dio - Map user address for DMA
+ * @adp: Adapter instance
+ * @ubuff: User buffer to map.
+ * @ubuff_sz: User buffer size.
+ * @uv_offset: UV buffer offset.
+ * @en_422mode: TRUE:422 FALSE:420 Capture mode.
+ * @dir_tx: TRUE for Tx (To device from host)
+ * @dio_hnd: Handle to mapped DIO request.
+ *
+ * Return:
+ * Status.
+ *
+ * This routine maps user address and lock pages for DMA.
+ *
+ */
+BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff,
+ uint32_t ubuff_sz, uint32_t uv_offset,
+ bool en_422mode, bool dir_tx,
+ crystalhd_dio_req **dio_hnd)
+{
+ crystalhd_dio_req *dio;
+ /* FIXME: jarod: should some of these unsigned longs be uint32_t or uintptr_t? */
+ unsigned long start = 0, end = 0, uaddr = 0, count = 0;
+ unsigned long spsz = 0, uv_start = 0;
+ int i = 0, rw = 0, res = 0, nr_pages = 0, skip_fb_sg = 0;
+
+ if (!adp || !ubuff || !ubuff_sz || !dio_hnd) {
+ BCMLOG_ERR("Invalid arg \n");
+ return BC_STS_INV_ARG;
+ }
+ /* Compute pages */
+ uaddr = (unsigned long)ubuff;
+ count = (unsigned long)ubuff_sz;
+ end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ start = uaddr >> PAGE_SHIFT;
+ nr_pages = end - start;
+
+ if (!count || ((uaddr + count) < uaddr)) {
+ BCMLOG_ERR("User addr overflow!!\n");
+ return BC_STS_INV_ARG;
+ }
+
+ dio = crystalhd_alloc_dio(adp);
+ if (!dio) {
+ BCMLOG_ERR("dio pool empty..\n");
+ return BC_STS_INSUFF_RES;
+ }
+
+ if (dir_tx) {
+ rw = WRITE;
+ dio->direction = DMA_TO_DEVICE;
+ } else {
+ rw = READ;
+ dio->direction = DMA_FROM_DEVICE;
+ }
+
+ if (nr_pages > dio->max_pages) {
+ BCMLOG_ERR("max_pages(%d) exceeded(%d)!!\n",
+ dio->max_pages, nr_pages);
+ crystalhd_unmap_dio(adp, dio);
+ return BC_STS_INSUFF_RES;
+ }
+
+ if (uv_offset) {
+ uv_start = (uaddr + (unsigned long)uv_offset) >> PAGE_SHIFT;
+ dio->uinfo.uv_sg_ix = uv_start - start;
+ dio->uinfo.uv_sg_off = ((uaddr + (unsigned long)uv_offset) & ~PAGE_MASK);
+ }
+
+ dio->fb_size = ubuff_sz & 0x03;
+ if (dio->fb_size) {
+ res = copy_from_user(dio->fb_va,
+ (void *)(uaddr + count - dio->fb_size),
+ dio->fb_size);
+ if (res) {
+ BCMLOG_ERR("failed %d to copy %u fill bytes from %p\n",
+ res, dio->fb_size,
+ (void *)(uaddr + count-dio->fb_size));
+ crystalhd_unmap_dio(adp, dio);
+ return BC_STS_INSUFF_RES;
+ }
+ }
+
+ down_read(&current->mm->mmap_sem);
+ res = get_user_pages(current, current->mm, uaddr, nr_pages, rw == READ,
+ 0, dio->pages, NULL);
+ up_read(&current->mm->mmap_sem);
+
+ /* Save for release..*/
+ dio->sig = crystalhd_dio_locked;
+ if (res < nr_pages) {
+ BCMLOG_ERR("get pages failed: %d-%d\n", nr_pages, res);
+ dio->page_cnt = res;
+ crystalhd_unmap_dio(adp, dio);
+ return BC_STS_ERROR;
+ }
+
+ dio->page_cnt = nr_pages;
+ /* Get scatter/gather */
+ crystalhd_init_sg(dio->sg, dio->page_cnt);
+ crystalhd_set_sg(&dio->sg[0], dio->pages[0], 0, uaddr & ~PAGE_MASK);
+ if (nr_pages > 1) {
+ dio->sg[0].length = PAGE_SIZE - dio->sg[0].offset;
+
+#ifdef CONFIG_X86_64
+ dio->sg[0].dma_length = dio->sg[0].length;
+#endif
+ count -= dio->sg[0].length;
+ for (i = 1; i < nr_pages; i++) {
+ if (count < 4) {
+ spsz = count;
+ skip_fb_sg = 1;
+ } else {
+ spsz = (count < PAGE_SIZE) ?
+ (count & ~0x03) : PAGE_SIZE;
+ }
+ crystalhd_set_sg(&dio->sg[i], dio->pages[i], spsz, 0);
+ count -= spsz;
+ }
+ } else {
+ if (count < 4) {
+ dio->sg[0].length = count;
+ skip_fb_sg = 1;
+ } else {
+ dio->sg[0].length = count - dio->fb_size;
+ }
+#ifdef CONFIG_X86_64
+ dio->sg[0].dma_length = dio->sg[0].length;
+#endif
+ }
+ dio->sg_cnt = pci_map_sg(adp->pdev, dio->sg,
+ dio->page_cnt, dio->direction);
+ if (dio->sg_cnt <= 0) {
+ BCMLOG_ERR("sg map %d-%d \n", dio->sg_cnt, dio->page_cnt);
+ crystalhd_unmap_dio(adp, dio);
+ return BC_STS_ERROR;
+ }
+ if (dio->sg_cnt && skip_fb_sg)
+ dio->sg_cnt -= 1;
+ dio->sig = crystalhd_dio_sg_mapped;
+ /* Fill in User info.. */
+ dio->uinfo.xfr_len = ubuff_sz;
+ dio->uinfo.xfr_buff = ubuff;
+ dio->uinfo.uv_offset = uv_offset;
+ dio->uinfo.b422mode = en_422mode;
+ dio->uinfo.dir_tx = dir_tx;
+
+ *dio_hnd = dio;
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_unmap_sgl - Release mapped resources
+ * @adp: Adapter instance
+ * @dio: DIO request instance
+ *
+ * Return:
+ * Status.
+ *
+ * This routine is to unmap the user buffer pages.
+ */
+BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio)
+{
+ struct page *page = NULL;
+ int j = 0;
+
+ if (!adp || !dio) {
+ BCMLOG_ERR("Invalid arg \n");
+ return BC_STS_INV_ARG;
+ }
+
+ if ((dio->page_cnt > 0) && (dio->sig != crystalhd_dio_inv)) {
+ for (j = 0; j < dio->page_cnt; j++) {
+ page = dio->pages[j];
+ if (page) {
+ if (!PageReserved(page) &&
+ (dio->direction == DMA_FROM_DEVICE))
+ SetPageDirty(page);
+ page_cache_release(page);
+ }
+ }
+ }
+ if (dio->sig == crystalhd_dio_sg_mapped)
+ pci_unmap_sg(adp->pdev, dio->sg, dio->page_cnt, dio->direction);
+
+ crystalhd_free_dio(adp, dio);
+
+ return BC_STS_SUCCESS;
+}
+
+/**
+ * crystalhd_create_dio_pool - Allocate mem pool for DIO management.
+ * @adp: Adapter instance
+ * @max_pages: Max pages for size calculation.
+ *
+ * Return:
+ * system error.
+ *
+ * This routine creates a memory pool to hold dio context for
+ * for HW Direct IO operation.
+ */
+int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages)
+{
+ uint32_t asz = 0, i = 0;
+ uint8_t *temp;
+ crystalhd_dio_req *dio;
+
+ if (!adp || !max_pages) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return -EINVAL;
+ }
+
+ /* Get dma memory for fill byte handling..*/
+ adp->fill_byte_pool = pci_pool_create("crystalhd_fbyte",
+ adp->pdev, 8, 8, 0);
+ if (!adp->fill_byte_pool) {
+ BCMLOG_ERR("failed to create fill byte pool\n");
+ return -ENOMEM;
+ }
+
+ /* Get the max size from user based on 420/422 modes */
+ asz = (sizeof(*dio->pages) * max_pages) +
+ (sizeof(*dio->sg) * max_pages) + sizeof(*dio);
+
+ BCMLOG(BCMLOG_DBG, "Initializing Dio pool %d %d %x %p\n",
+ BC_LINK_SG_POOL_SZ, max_pages, asz, adp->fill_byte_pool);
+
+ for (i = 0; i < BC_LINK_SG_POOL_SZ; i++) {
+ temp = (uint8_t *)kzalloc(asz, GFP_KERNEL);
+ if ((temp) == NULL) {
+ BCMLOG_ERR("Failed to alloc %d mem\n", asz);
+ return -ENOMEM;
+ }
+
+ dio = (crystalhd_dio_req *)temp;
+ temp += sizeof(*dio);
+ dio->pages = (struct page **)temp;
+ temp += (sizeof(*dio->pages) * max_pages);
+ dio->sg = (struct scatterlist *)temp;
+ dio->max_pages = max_pages;
+ dio->fb_va = pci_pool_alloc(adp->fill_byte_pool, GFP_KERNEL,
+ &dio->fb_pa);
+ if (!dio->fb_va) {
+ BCMLOG_ERR("fill byte alloc failed.\n");
+ return -ENOMEM;
+ }
+
+ crystalhd_free_dio(adp, dio);
+ }
+
+ return 0;
+}
+
+/**
+ * crystalhd_destroy_dio_pool - Release DIO mem pool.
+ * @adp: Adapter instance
+ *
+ * Return:
+ * none.
+ *
+ * This routine releases dio memory pool during close.
+ */
+void crystalhd_destroy_dio_pool(struct crystalhd_adp *adp)
+{
+ crystalhd_dio_req *dio;
+ int count = 0;
+
+ if (!adp) {
+ BCMLOG_ERR("Invalid Arg!!\n");
+ return;
+ }
+
+ do {
+ dio = crystalhd_alloc_dio(adp);
+ if (dio) {
+ if (dio->fb_va)
+ pci_pool_free(adp->fill_byte_pool,
+ dio->fb_va, dio->fb_pa);
+ count++;
+ kfree(dio);
+ }
+ } while (dio);
+
+ if (adp->fill_byte_pool) {
+ pci_pool_destroy(adp->fill_byte_pool);
+ adp->fill_byte_pool = NULL;
+ }
+
+ BCMLOG(BCMLOG_DBG, "Released dio pool %d \n", count);
+}
+
+/**
+ * crystalhd_create_elem_pool - List element pool creation.
+ * @adp: Adapter instance
+ * @pool_size: Number of elements in the pool.
+ *
+ * Return:
+ * 0 - success, <0 error
+ *
+ * Create general purpose list element pool to hold pending,
+ * and active requests.
+ */
+int __devinit crystalhd_create_elem_pool(struct crystalhd_adp *adp,
+ uint32_t pool_size)
+{
+ uint32_t i;
+ crystalhd_elem_t *temp;
+
+ if (!adp || !pool_size)
+ return -EINVAL;
+
+ for (i = 0; i < pool_size; i++) {
+ temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+ if (!temp) {
+ BCMLOG_ERR("kalloc failed \n");
+ return -ENOMEM;
+ }
+ crystalhd_free_elem(adp, temp);
+ }
+ BCMLOG(BCMLOG_DBG, "allocated %d elem\n", pool_size);
+ return 0;
+}
+
+/**
+ * crystalhd_delete_elem_pool - List element pool deletion.
+ * @adp: Adapter instance
+ *
+ * Return:
+ * none
+ *
+ * Delete general purpose list element pool.
+ */
+void crystalhd_delete_elem_pool(struct crystalhd_adp *adp)
+{
+ crystalhd_elem_t *temp;
+ int dbg_cnt = 0;
+
+ if (!adp)
+ return;
+
+ do {
+ temp = crystalhd_alloc_elem(adp);
+ if (temp) {
+ kfree(temp);
+ dbg_cnt++;
+ }
+ } while (temp);
+
+ BCMLOG(BCMLOG_DBG, "released %d elem\n", dbg_cnt);
+}
+
+/*================ Debug support routines.. ================================*/
+void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount)
+{
+ uint32_t i, k = 1;
+
+ for (i = 0; i < dwcount; i++) {
+ if (k == 1)
+ BCMLOG(BCMLOG_DATA, "0x%08X : ", off);
+
+ BCMLOG(BCMLOG_DATA, " 0x%08X ", *((uint32_t *)buff));
+
+ buff += sizeof(uint32_t);
+ off += sizeof(uint32_t);
+ k++;
+ if ((i == dwcount - 1) || (k > 4)) {
+ BCMLOG(BCMLOG_DATA, "\n");
+ k = 1;
+ }
+ }
+}
diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h
new file mode 100644
index 00000000000..a2aa6ad7fc8
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_misc.h
@@ -0,0 +1,229 @@
+/***************************************************************************
+ * Copyright (c) 2005-2009, Broadcom Corporation.
+ *
+ * Name: crystalhd_misc . h
+ *
+ * Description:
+ * BCM70012 Linux driver general purpose routines.
+ * Includes reg/mem read and write routines.
+ *
+ * HISTORY:
+ *
+ **********************************************************************
+ * This file is part of the crystalhd device driver.
+ *
+ * This driver is free software; 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 driver is distributed in 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 driver. If not, see <http://www.gnu.org/licenses/>.
+ **********************************************************************/
+
+#ifndef _CRYSTALHD_MISC_H_
+#define _CRYSTALHD_MISC_H_
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/ioctl.h>
+#include <linux/dma-mapping.h>
+#include <linux/version.h>
+#include <linux/sched.h>
+#include <asm/system.h>
+#include "bc_dts_glob_lnx.h"
+
+/* Global log level variable defined in crystal_misc.c file */
+extern uint32_t g_linklog_level;
+
+/* Global element pool for all Queue management.
+ * TX: Active = BC_TX_LIST_CNT, Free = BC_TX_LIST_CNT.
+ * RX: Free = BC_RX_LIST_CNT, Active = 2
+ * FW-CMD: 4
+ */
+#define BC_LINK_ELEM_POOL_SZ ((BC_TX_LIST_CNT * 2) + BC_RX_LIST_CNT + 2 + 4)
+
+/* Driver's IODATA pool count */
+#define CHD_IODATA_POOL_SZ (BC_IOCTL_DATA_POOL_SIZE * BC_LINK_MAX_OPENS)
+
+/* Scatter Gather memory pool size for Tx and Rx */
+#define BC_LINK_SG_POOL_SZ (BC_TX_LIST_CNT + BC_RX_LIST_CNT)
+
+enum _crystalhd_dio_sig {
+ crystalhd_dio_inv = 0,
+ crystalhd_dio_locked,
+ crystalhd_dio_sg_mapped,
+};
+
+struct crystalhd_dio_user_info {
+ void *xfr_buff;
+ uint32_t xfr_len;
+ uint32_t uv_offset;
+ bool dir_tx;
+
+ uint32_t uv_sg_ix;
+ uint32_t uv_sg_off;
+ int comp_sts;
+ int ev_sts;
+ uint32_t y_done_sz;
+ uint32_t uv_done_sz;
+ uint32_t comp_flags;
+ bool b422mode;
+};
+
+typedef struct _crystalhd_dio_req {
+ uint32_t sig;
+ uint32_t max_pages;
+ struct page **pages;
+ struct scatterlist *sg;
+ int sg_cnt;
+ int page_cnt;
+ int direction;
+ struct crystalhd_dio_user_info uinfo;
+ void *fb_va;
+ uint32_t fb_size;
+ dma_addr_t fb_pa;
+ struct _crystalhd_dio_req *next;
+} crystalhd_dio_req;
+
+#define BC_LINK_DIOQ_SIG (0x09223280)
+
+typedef struct _crystalhd_elem_s {
+ struct _crystalhd_elem_s *flink;
+ struct _crystalhd_elem_s *blink;
+ void *data;
+ uint32_t tag;
+} crystalhd_elem_t;
+
+typedef void (*crystalhd_data_free_cb)(void *context, void *data);
+
+typedef struct _crystalhd_dioq_s {
+ uint32_t sig;
+ struct crystalhd_adp *adp;
+ crystalhd_elem_t *head;
+ crystalhd_elem_t *tail;
+ uint32_t count;
+ spinlock_t lock;
+ wait_queue_head_t event;
+ crystalhd_data_free_cb data_rel_cb;
+ void *cb_context;
+} crystalhd_dioq_t;
+
+typedef void (*hw_comp_callback)(crystalhd_dio_req *,
+ wait_queue_head_t *event, BC_STATUS sts);
+
+/*========= Decoder (7412) register access routines.================= */
+uint32_t bc_dec_reg_rd(struct crystalhd_adp *, uint32_t);
+void bc_dec_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
+
+/*========= Link (70012) register access routines.. =================*/
+uint32_t crystalhd_reg_rd(struct crystalhd_adp *, uint32_t);
+void crystalhd_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
+
+/*========= Decoder (7412) memory access routines..=================*/
+BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
+BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
+
+/*==========Link (70012) PCIe Config access routines.================*/
+BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
+BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t);
+
+/*========= Linux Kernel Interface routines. ======================= */
+void *bc_kern_dma_alloc(struct crystalhd_adp *, uint32_t, dma_addr_t *);
+void bc_kern_dma_free(struct crystalhd_adp *, uint32_t,
+ void *, dma_addr_t);
+#define crystalhd_create_event(_ev) init_waitqueue_head(_ev)
+#define crystalhd_set_event(_ev) wake_up_interruptible(_ev)
+#define crystalhd_wait_on_event(ev, condition, timeout, ret, nosig) \
+do { \
+ DECLARE_WAITQUEUE(entry, current); \
+ unsigned long end = jiffies + ((timeout * HZ) / 1000); \
+ ret = 0; \
+ add_wait_queue(ev, &entry); \
+ for (;;) { \
+ __set_current_state(TASK_INTERRUPTIBLE); \
+ if (condition) { \
+ break; \
+ } \
+ if (time_after_eq(jiffies, end)) { \
+ ret = -EBUSY; \
+ break; \
+ } \
+ schedule_timeout((HZ / 100 > 1) ? HZ / 100 : 1); \
+ if (!nosig && signal_pending(current)) { \
+ ret = -EINTR; \
+ break; \
+ } \
+ } \
+ __set_current_state(TASK_RUNNING); \
+ remove_wait_queue(ev, &entry); \
+} while (0)
+
+/*================ Direct IO mapping routines ==================*/
+extern int crystalhd_create_dio_pool(struct crystalhd_adp *, uint32_t);
+extern void crystalhd_destroy_dio_pool(struct crystalhd_adp *);
+extern BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *, uint32_t,
+ uint32_t, bool, bool, crystalhd_dio_req**);
+
+extern BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *, crystalhd_dio_req*);
+#define crystalhd_get_sgle_paddr(_dio, _ix) (cpu_to_le64(sg_dma_address(&_dio->sg[_ix])))
+#define crystalhd_get_sgle_len(_dio, _ix) (cpu_to_le32(sg_dma_len(&_dio->sg[_ix])))
+
+/*================ General Purpose Queues ==================*/
+extern BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *, crystalhd_dioq_t **, crystalhd_data_free_cb , void *);
+extern void crystalhd_delete_dioq(struct crystalhd_adp *, crystalhd_dioq_t *);
+extern BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, bool wake, uint32_t tag);
+extern void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq);
+extern void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag);
+extern void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs, uint32_t *sig_pend);
+
+#define crystalhd_dioq_count(_ioq) ((_ioq) ? _ioq->count : 0)
+
+extern int crystalhd_create_elem_pool(struct crystalhd_adp *, uint32_t);
+extern void crystalhd_delete_elem_pool(struct crystalhd_adp *);
+
+
+/*================ Debug routines/macros .. ================================*/
+extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount);
+
+enum _chd_log_levels {
+ BCMLOG_ERROR = 0x80000000, /* Don't disable this option */
+ BCMLOG_DATA = 0x40000000, /* Data, enable by default */
+ BCMLOG_SPINLOCK = 0x20000000, /* Spcial case for Spin locks*/
+
+ /* Following are allowed only in debug mode */
+ BCMLOG_INFO = 0x00000001, /* Generic informational */
+ BCMLOG_DBG = 0x00000002, /* First level Debug info */
+ BCMLOG_SSTEP = 0x00000004, /* Stepping information */
+ BCMLOG_ENTER_LEAVE = 0x00000008, /* stack tracking */
+};
+
+#define BCMLOG_ENTER \
+if (g_linklog_level & BCMLOG_ENTER_LEAVE) { \
+ printk("Entered %s\n", __func__); \
+}
+
+#define BCMLOG_LEAVE \
+if (g_linklog_level & BCMLOG_ENTER_LEAVE) { \
+ printk("Leaving %s\n", __func__); \
+}
+
+#define BCMLOG(trace, fmt, args...) \
+if (g_linklog_level & trace) { \
+ printk(fmt, ##args); \
+}
+
+#define BCMLOG_ERR(fmt, args...) \
+do { \
+ if (g_linklog_level & BCMLOG_ERROR) { \
+ printk("*ERR*:%s:%d: "fmt, __FILE__, __LINE__, ##args); \
+ } \
+} while (0);
+
+#endif
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
index e0eef12759e..061add30ba8 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -27,6 +27,7 @@
#include <linux/vmalloc.h>
#include <linux/dma-mapping.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <asm/delay.h>
#include <sound/core.h>
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
index ddddf651266..11c56bdb0ce 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.c
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -32,6 +32,7 @@
#include <linux/file.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
index 89c8fe2997f..e76451c309f 100644
--- a/drivers/staging/cx25821/cx25821-audups11.c
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -21,6 +21,8 @@
* 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)
@@ -343,10 +345,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctl)
{
struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
+ struct cx25821_dev *dev;
int err;
if (fh) {
+ dev = fh->dev;
err = v4l2_prio_check(&dev->prio, &fh->prio);
if (0 != err)
return err;
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index 67f689de4da..9e9b8c3c931 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -22,6 +22,7 @@
*/
#include <linux/i2c.h>
+#include <linux/slab.h>
#include "cx25821.h"
#include "cx25821-sram.h"
#include "cx25821-video.h"
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
index 1eb079b3d42..d6016200d69 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -795,10 +795,8 @@ int medusa_video_init(struct cx25821_dev *dev)
value &= 0xFFFFFFDF;
ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
- if (ret_val < 0) {
- mutex_unlock(&dev->lock);
+ if (ret_val < 0)
return -EINVAL;
- }
mutex_unlock(&dev->lock);
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
index c8905e0ac50..cc51618cffa 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -31,6 +31,7 @@
#include <linux/syscalls.h>
#include <linux/file.h>
#include <linux/fcntl.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
index 3d7dd3f6654..6d48a1e26d1 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -31,6 +31,7 @@
#include <linux/syscalls.h>
#include <linux/file.h>
#include <linux/fcntl.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index c7c14c7698a..8cd3986d2e5 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -876,7 +876,7 @@ int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
dprintk(1, "%s()\n", __func__);
n = i->index;
- if (n > 2)
+ if (n >= 2)
return -EINVAL;
if (0 == INPUT(n)->type)
@@ -963,10 +963,11 @@ int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
{
struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
+ struct cx25821_dev *dev;
int err;
if (fh) {
+ dev = fh->dev;
err = v4l2_prio_check(&dev->prio, &fh->prio);
if (0 != err)
return err;
diff --git a/drivers/staging/dream/camera/Kconfig b/drivers/staging/dream/camera/Kconfig
index 0a3e903b336..bfb6d241d80 100644
--- a/drivers/staging/dream/camera/Kconfig
+++ b/drivers/staging/dream/camera/Kconfig
@@ -15,7 +15,7 @@ config MSM_CAMERA_DEBUG
config MSM_CAMERA_FLASH
bool "Qualcomm MSM camera flash support"
- depends on MSM_CAMERA
+ depends on MSM_CAMERA && BROKEN
---help---
Enable support for LED flash for msm camera
diff --git a/drivers/staging/dream/camera/Makefile b/drivers/staging/dream/camera/Makefile
index 4429ae5fcaf..db228d7d113 100644
--- a/drivers/staging/dream/camera/Makefile
+++ b/drivers/staging/dream/camera/Makefile
@@ -1,3 +1,4 @@
+EXTRA_CFLAGS=-Idrivers/staging/dream/include
obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o
diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c
index 7d938772eac..81bd71fd816 100644
--- a/drivers/staging/dream/camera/msm_camera.c
+++ b/drivers/staging/dream/camera/msm_camera.c
@@ -2,7 +2,7 @@
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
*/
-//FIXME: most allocations need not be GFP_ATOMIC
+/* FIXME: most allocations need not be GFP_ATOMIC */
/* FIXME: management of mutexes */
/* FIXME: msm_pmem_region_lookup return values */
/* FIXME: way too many copy to/from user */
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <mach/board.h>
@@ -76,14 +77,14 @@ static LIST_HEAD(msm_sensors);
list_del_init(&qcmd->list); \
kfree(qcmd); \
}; \
-} while(0)
+} while (0)
#define MSM_DRAIN_QUEUE(sync, name) do { \
unsigned long flags; \
spin_lock_irqsave(&(sync)->name##_lock, flags); \
MSM_DRAIN_QUEUE_NOSYNC(sync, name); \
spin_unlock_irqrestore(&(sync)->name##_lock, flags); \
-} while(0)
+} while (0)
static int check_overlap(struct hlist_head *ptype,
unsigned long paddr,
@@ -361,7 +362,7 @@ static int __msm_get_frame(struct msm_sync *sync,
if (!frame->buffer) {
pr_err("%s: cannot get frame, invalid lookup address "
"y=%x cbcr=%x offset=%d\n",
- __FUNCTION__,
+ __func__,
pphy->y_phy,
pphy->cbcr_phy,
frame->y_off);
@@ -455,7 +456,7 @@ static int msm_disable_vfe(struct msm_sync *sync, void __user *arg)
return rc;
}
-static struct msm_queue_cmd* __msm_control(struct msm_sync *sync,
+static struct msm_queue_cmd *__msm_control(struct msm_sync *sync,
struct msm_control_device_queue *queue,
struct msm_queue_cmd *qcmd,
int timeout)
@@ -592,8 +593,7 @@ end:
* a result of a successful completion, we are freeing the qcmd that
* we dequeued from queue->ctrl_status_q.
*/
- if (qcmd)
- kfree(qcmd);
+ kfree(qcmd);
CDBG("msm_control: end rc = %d\n", rc);
return rc;
@@ -670,7 +670,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg)
&(stats.fd));
if (!stats.buffer) {
pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
- __FUNCTION__);
+ __func__);
rc = -EINVAL;
goto failure;
}
@@ -718,8 +718,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg)
buf.fmain.buffer =
(unsigned long)region.vaddr;
buf.fmain.fd = region.fd;
- }
- else {
+ } else {
pr_err("%s: pmem lookup failed\n",
__func__);
rc = -EINVAL;
@@ -796,8 +795,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg)
}
failure:
- if (qcmd)
- kfree(qcmd);
+ kfree(qcmd);
CDBG("msm_get_stats: %d\n", rc);
return rc;
@@ -838,8 +836,8 @@ static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm,
kfree(qcmd);
goto end;
}
- }
- else ctrlcmd->value = NULL;
+ } else
+ ctrlcmd->value = NULL;
end:
CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc);
@@ -869,14 +867,14 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
return -EFAULT;
}
- switch(cfgcmd.cmd_type) {
+ switch (cfgcmd.cmd_type) {
case CMD_STATS_ENABLE:
axi_data.bufnum1 =
msm_pmem_region_lookup(&sync->stats,
MSM_PMEM_AEC_AWB, &region[0],
NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
- pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+ pr_err("%s: pmem region lookup error\n", __func__);
return -EINVAL;
}
axi_data.region = &region[0];
@@ -888,7 +886,7 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
MSM_PMEM_AF, &region[0],
NUM_AF_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
- pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+ pr_err("%s: pmem region lookup error\n", __func__);
return -EINVAL;
}
axi_data.region = &region[0];
@@ -899,7 +897,7 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
break;
default:
pr_err("%s: unknown command type %d\n",
- __FUNCTION__, cfgcmd.cmd_type);
+ __func__, cfgcmd.cmd_type);
return -EINVAL;
}
@@ -928,7 +926,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
msm_pmem_region_lookup(&sync->frame, pmem_type,
&region[0], 8);
if (!axi_data.bufnum1) {
- pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+ pr_err("%s: pmem region lookup error\n", __func__);
return -EINVAL;
}
break;
@@ -939,7 +937,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
msm_pmem_region_lookup(&sync->frame, pmem_type,
&region[0], 8);
if (!axi_data.bufnum2) {
- pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+ pr_err("%s: pmem region lookup error\n", __func__);
return -EINVAL;
}
break;
@@ -950,7 +948,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
msm_pmem_region_lookup(&sync->frame, pmem_type,
&region[0], 8);
if (!axi_data.bufnum1) {
- pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+ pr_err("%s: pmem region lookup error\n", __func__);
return -EINVAL;
}
@@ -959,7 +957,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
msm_pmem_region_lookup(&sync->frame, pmem_type,
&region[axi_data.bufnum1], 8);
if (!axi_data.bufnum2) {
- pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+ pr_err("%s: pmem region lookup error\n", __func__);
return -EINVAL;
}
break;
@@ -970,7 +968,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
msm_pmem_region_lookup(&sync->frame, pmem_type,
&region[0], 8);
if (!axi_data.bufnum2) {
- pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+ pr_err("%s: pmem region lookup error\n", __func__);
return -EINVAL;
}
break;
@@ -981,7 +979,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
default:
pr_err("%s: unknown command type %d\n",
- __FUNCTION__, cfgcmd->cmd_type);
+ __func__, cfgcmd->cmd_type);
return -EINVAL;
}
@@ -1047,7 +1045,7 @@ static int __msm_put_frame_buf(struct msm_sync *sync,
rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
} else {
pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
- __FUNCTION__);
+ __func__);
rc = -EINVAL;
}
@@ -1131,7 +1129,7 @@ static int msm_stats_axi_cfg(struct msm_sync *sync,
break;
default:
pr_err("%s: unknown command type %d\n",
- __FUNCTION__, cfgcmd->cmd_type);
+ __func__, cfgcmd->cmd_type);
return -EINVAL;
}
@@ -1140,7 +1138,7 @@ static int msm_stats_axi_cfg(struct msm_sync *sync,
msm_pmem_region_lookup(&sync->stats, pmem_type,
&region[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
if (!axi_data.bufnum1) {
- pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+ pr_err("%s: pmem region lookup error\n", __func__);
return -EINVAL;
}
axi_data.region = &region[0];
@@ -1177,7 +1175,7 @@ static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg)
cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
else {
pr_err("%s: invalid buf type %d\n",
- __FUNCTION__,
+ __func__,
buf.type);
rc = -EINVAL;
goto put_done;
@@ -1223,7 +1221,7 @@ static int msm_axi_config(struct msm_sync *sync, void __user *arg)
default:
pr_err("%s: unknown command type %d\n",
- __FUNCTION__,
+ __func__,
cfgcmd.cmd_type);
return -EINVAL;
}
@@ -1622,7 +1620,8 @@ static int msm_release_control(struct inode *node, struct file *filep)
int rc;
struct msm_control_device *ctrl_pmsm = filep->private_data;
struct msm_device *pmsm = ctrl_pmsm->pmsm;
- printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
+ printk(KERN_INFO "msm_camera: RELEASE %s\n",
+ filep->f_path.dentry->d_name.name);
rc = __msm_release(pmsm->sync);
if (!rc) {
MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q);
@@ -1636,7 +1635,8 @@ static int msm_release_frame(struct inode *node, struct file *filep)
{
int rc;
struct msm_device *pmsm = filep->private_data;
- printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
+ printk(KERN_INFO "msm_camera: RELEASE %s\n",
+ filep->f_path.dentry->d_name.name);
rc = __msm_release(pmsm->sync);
if (!rc) {
MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q);
@@ -1720,7 +1720,7 @@ static void msm_vfe_sync(struct msm_vfe_resp *vdata,
qcmd->type = qtype;
if (qtype == MSM_CAM_Q_VFE_MSG) {
- switch(vdata->type) {
+ switch (vdata->type) {
case VFE_MSG_OUTPUT1:
case VFE_MSG_OUTPUT2:
qcmd_frame =
@@ -1885,8 +1885,10 @@ static int msm_open_control(struct inode *inode, struct file *filep)
return -ENOMEM;
rc = msm_open_common(inode, filep, 0);
- if (rc < 0)
+ if (rc < 0) {
+ kfree(ctrl_pmsm);
return rc;
+ }
ctrl_pmsm->pmsm = filep->private_data;
filep->private_data = ctrl_pmsm;
@@ -1929,7 +1931,7 @@ static int __msm_v4l2_control(struct msm_sync *sync,
memcpy(out->value, ctrl->value, ctrl->length);
end:
- if (rcmd) kfree(rcmd);
+ kfree(rcmd);
CDBG("__msm_v4l2_control: end rc = %d\n", rc);
return rc;
}
diff --git a/drivers/staging/dream/camera/msm_v4l2.c b/drivers/staging/dream/camera/msm_v4l2.c
index 6a7d46cf11e..c276f2f7583 100644
--- a/drivers/staging/dream/camera/msm_v4l2.c
+++ b/drivers/staging/dream/camera/msm_v4l2.c
@@ -12,6 +12,7 @@
#include <linux/spinlock.h>
#include <linux/videodev2.h>
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <media/v4l2-dev.h>
#include <media/msm_camera.h>
#include <mach/camera.h>
diff --git a/drivers/staging/dream/camera/msm_vfe7x.c b/drivers/staging/dream/camera/msm_vfe7x.c
index 33ab3ac6ac5..198656ac3de 100644
--- a/drivers/staging/dream/camera/msm_vfe7x.c
+++ b/drivers/staging/dream/camera/msm_vfe7x.c
@@ -7,6 +7,7 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/android_pmem.h>
+#include <linux/slab.h>
#include <mach/msm_adsp.h>
#include <linux/delay.h>
#include <linux/wait.h>
@@ -255,8 +256,7 @@ static int vfe_7x_init(struct msm_vfe_callback *presp,
extlen = sizeof(struct vfe_frame_extra);
- extdata =
- kmalloc(sizeof(extlen), GFP_ATOMIC);
+ extdata = kmalloc(extlen, GFP_ATOMIC);
if (!extdata) {
rc = -ENOMEM;
goto init_fail;
diff --git a/drivers/staging/dream/camera/msm_vfe8x.c b/drivers/staging/dream/camera/msm_vfe8x.c
index 03de6ec2eb4..e61fdba6283 100644
--- a/drivers/staging/dream/camera/msm_vfe8x.c
+++ b/drivers/staging/dream/camera/msm_vfe8x.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
*/
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <mach/irqs.h>
diff --git a/drivers/staging/dream/camera/mt9d112.c b/drivers/staging/dream/camera/mt9d112.c
index 4f938f9dfc4..e6f2d512461 100644
--- a/drivers/staging/dream/camera/mt9d112.c
+++ b/drivers/staging/dream/camera/mt9d112.c
@@ -3,6 +3,7 @@
*/
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/uaccess.h>
diff --git a/drivers/staging/dream/camera/mt9p012_fox.c b/drivers/staging/dream/camera/mt9p012_fox.c
index 70119d5e0ab..791bd6c4061 100644
--- a/drivers/staging/dream/camera/mt9p012_fox.c
+++ b/drivers/staging/dream/camera/mt9p012_fox.c
@@ -4,6 +4,7 @@
#include <linux/delay.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
diff --git a/drivers/staging/dream/camera/mt9t013.c b/drivers/staging/dream/camera/mt9t013.c
index 88229f2663b..8fd7727ba23 100644
--- a/drivers/staging/dream/camera/mt9t013.c
+++ b/drivers/staging/dream/camera/mt9t013.c
@@ -4,6 +4,7 @@
#include <linux/delay.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
diff --git a/drivers/staging/dream/camera/s5k3e2fx.c b/drivers/staging/dream/camera/s5k3e2fx.c
index edba19889b0..1459903a339 100644
--- a/drivers/staging/dream/camera/s5k3e2fx.c
+++ b/drivers/staging/dream/camera/s5k3e2fx.c
@@ -3,6 +3,7 @@
*/
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/uaccess.h>
@@ -743,12 +744,12 @@ static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data)
}
/* initialize AF */
- if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
- 0x3146, 0x3A)) < 0)
+ rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3146, 0x3A);
+ if (rc < 0)
goto init_fail1;
- if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
- 0x3130, 0x03)) < 0)
+ rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3130, 0x03);
+ if (rc < 0)
goto init_fail1;
goto init_done;
@@ -814,20 +815,20 @@ static uint16_t s5k3e2fx_get_prev_lines_pf(void)
static uint16_t s5k3e2fx_get_prev_pixels_pl(void)
{
- return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
- s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p);
+ return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
+ s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
}
static uint16_t s5k3e2fx_get_pict_lines_pf(void)
{
- return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
- s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l);
+ return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
+ s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
}
static uint16_t s5k3e2fx_get_pict_pixels_pl(void)
{
- return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
- s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p);
+ return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
+ s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
}
static uint32_t s5k3e2fx_get_pict_max_exp_lc(void)
@@ -1093,14 +1094,10 @@ static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps)
actual_step = step_direction * (int16_t)num_steps;
pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos;
- gain = actual_step * 0x400 / 5;
+ gain = ((actual_step << 10) / 5) >> 10;
- for (i = 0; i <= 4; i++) {
- if (actual_step >= 0)
- s_move[i] = ((((i+1)*gain+0x200) - (i*gain+0x200))/0x400);
- else
- s_move[i] = ((((i+1)*gain-0x200) - (i*gain-0x200))/0x400);
- }
+ for (i = 0; i <= 4; i++)
+ s_move[i] = gain;
/* Ring Damping Code */
for (i = 0; i <= 4; i++) {
diff --git a/drivers/staging/dream/gpio_axis.c b/drivers/staging/dream/gpio_axis.c
index c801172aa9e..eb54724b1d3 100644
--- a/drivers/staging/dream/gpio_axis.c
+++ b/drivers/staging/dream/gpio_axis.c
@@ -14,6 +14,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/gpio_event.h>
#include <linux/interrupt.h>
diff --git a/drivers/staging/dream/gpio_event.c b/drivers/staging/dream/gpio_event.c
index e60e2c0db9c..97a511d11f4 100644
--- a/drivers/staging/dream/gpio_event.c
+++ b/drivers/staging/dream/gpio_event.c
@@ -14,6 +14,7 @@
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/gpio_event.h>
diff --git a/drivers/staging/dream/gpio_input.c b/drivers/staging/dream/gpio_input.c
index 0638ec43601..ca29e5eb070 100644
--- a/drivers/staging/dream/gpio_input.c
+++ b/drivers/staging/dream/gpio_input.c
@@ -19,6 +19,7 @@
#include <linux/hrtimer.h>
#include <linux/input.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
enum {
DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */
diff --git a/drivers/staging/dream/gpio_matrix.c b/drivers/staging/dream/gpio_matrix.c
index 796de4faf85..b377ee1f5a5 100644
--- a/drivers/staging/dream/gpio_matrix.c
+++ b/drivers/staging/dream/gpio_matrix.c
@@ -14,6 +14,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/gpio_event.h>
#include <linux/hrtimer.h>
diff --git a/drivers/staging/dream/include/linux/android_pmem.h b/drivers/staging/dream/include/linux/android_pmem.h
new file mode 100644
index 00000000000..2fc05d7d335
--- /dev/null
+++ b/drivers/staging/dream/include/linux/android_pmem.h
@@ -0,0 +1,80 @@
+/* drivers/staging/dream/include/linux/android_pmem.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _ANDROID_PMEM_H_
+#define _ANDROID_PMEM_H_
+
+#define PMEM_IOCTL_MAGIC 'p'
+#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
+#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
+#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
+#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
+/* This ioctl will allocate pmem space, backing the file, it will fail
+ * if the file already has an allocation, pass it the len as the argument
+ * to the ioctl */
+#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
+/* This will connect a one pmem file to another, pass the file that is already
+ * backed in memory as the argument to the ioctl
+ */
+#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
+/* Returns the total size of the pmem region it is sent to as a pmem_region
+ * struct (with offset set to 0).
+ */
+#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
+/* Revokes gpu registers and resets the gpu. Pass a pointer to the
+ * start of the mapped gpu regs (the vaddr returned by mmap) as the argument.
+ */
+#define HW3D_REVOKE_GPU _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
+#define HW3D_GRANT_GPU _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int)
+#define HW3D_WAIT_FOR_INTERRUPT _IOW(PMEM_IOCTL_MAGIC, 10, unsigned int)
+
+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
+ unsigned long *end, struct file **filp);
+int get_pmem_user_addr(struct file *file, unsigned long *start,
+ unsigned long *end);
+void put_pmem_file(struct file* file);
+void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
+
+struct android_pmem_platform_data
+{
+ const char* name;
+ /* starting physical address of memory region */
+ unsigned long start;
+ /* size of memory region */
+ unsigned long size;
+ /* set to indicate the region should not be managed with an allocator */
+ unsigned no_allocator;
+ /* set to indicate maps of this region should be cached, if a mix of
+ * cached and uncached is desired, set this and open the device with
+ * O_SYNC to get an uncached region */
+ unsigned cached;
+ /* The MSM7k has bits to enable a write buffer in the bus controller*/
+ unsigned buffered;
+};
+
+struct pmem_region {
+ unsigned long offset;
+ unsigned long len;
+};
+
+int pmem_setup(struct android_pmem_platform_data *pdata,
+ long (*ioctl)(struct file *, unsigned int, unsigned long),
+ int (*release)(struct inode *, struct file *));
+
+int pmem_remap(struct pmem_region *region, struct file *file,
+ unsigned operation);
+
+#endif //_ANDROID_PPP_H_
+
diff --git a/drivers/staging/dream/include/linux/gpio_event.h b/drivers/staging/dream/include/linux/gpio_event.h
new file mode 100644
index 00000000000..ffc5da392ad
--- /dev/null
+++ b/drivers/staging/dream/include/linux/gpio_event.h
@@ -0,0 +1,154 @@
+/* drivers/staging/dream/include/linux/gpio_event.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_GPIO_EVENT_H
+#define _LINUX_GPIO_EVENT_H
+
+#include <linux/input.h>
+
+enum {
+ GPIO_EVENT_FUNC_UNINIT = 0x0,
+ GPIO_EVENT_FUNC_INIT = 0x1,
+ GPIO_EVENT_FUNC_SUSPEND = 0x2,
+ GPIO_EVENT_FUNC_RESUME = 0x3,
+};
+struct gpio_event_info {
+ int (*func)(struct input_dev *input_dev,
+ struct gpio_event_info *info,
+ void **data, int func);
+ int (*event)(struct input_dev *input_dev,
+ struct gpio_event_info *info,
+ void **data, unsigned int type,
+ unsigned int code, int value); /* out events */
+};
+
+struct gpio_event_platform_data {
+ const char *name;
+ struct gpio_event_info **info;
+ size_t info_count;
+ int (*power)(const struct gpio_event_platform_data *pdata, bool on);
+};
+
+#define GPIO_EVENT_DEV_NAME "gpio-event"
+
+/* Key matrix */
+
+enum gpio_event_matrix_flags {
+ /* unset: drive active output low, set: drive active output high */
+ GPIOKPF_ACTIVE_HIGH = 1U << 0,
+ GPIOKPF_DEBOUNCE = 1U << 1,
+ GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2,
+ GPIOKPF_REMOVE_PHANTOM_KEYS = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS |
+ GPIOKPF_DEBOUNCE,
+ GPIOKPF_DRIVE_INACTIVE = 1U << 3,
+ GPIOKPF_LEVEL_TRIGGERED_IRQ = 1U << 4,
+ GPIOKPF_PRINT_UNMAPPED_KEYS = 1U << 16,
+ GPIOKPF_PRINT_MAPPED_KEYS = 1U << 17,
+ GPIOKPF_PRINT_PHANTOM_KEYS = 1U << 18,
+};
+
+extern int gpio_event_matrix_func(struct input_dev *input_dev,
+ struct gpio_event_info *info, void **data, int func);
+struct gpio_event_matrix_info {
+ /* initialize to gpio_event_matrix_func */
+ struct gpio_event_info info;
+ /* size must be ninputs * noutputs */
+ const unsigned short *keymap;
+ unsigned int *input_gpios;
+ unsigned int *output_gpios;
+ unsigned int ninputs;
+ unsigned int noutputs;
+ /* time to wait before reading inputs after driving each output */
+ ktime_t settle_time;
+ /* time to wait before scanning the keypad a second time */
+ ktime_t debounce_delay;
+ ktime_t poll_time;
+ unsigned flags;
+};
+
+/* Directly connected inputs and outputs */
+
+enum gpio_event_direct_flags {
+ GPIOEDF_ACTIVE_HIGH = 1U << 0,
+/* GPIOEDF_USE_DOWN_IRQ = 1U << 1, */
+/* GPIOEDF_USE_IRQ = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */
+ GPIOEDF_PRINT_KEYS = 1U << 8,
+ GPIOEDF_PRINT_KEY_DEBOUNCE = 1U << 9,
+};
+
+struct gpio_event_direct_entry {
+ uint32_t gpio:23;
+ uint32_t code:9;
+};
+
+/* inputs */
+extern int gpio_event_input_func(struct input_dev *input_dev,
+ struct gpio_event_info *info, void **data, int func);
+struct gpio_event_input_info {
+ /* initialize to gpio_event_input_func */
+ struct gpio_event_info info;
+ ktime_t debounce_time;
+ ktime_t poll_time;
+ uint16_t flags;
+ uint16_t type;
+ const struct gpio_event_direct_entry *keymap;
+ size_t keymap_size;
+};
+
+/* outputs */
+extern int gpio_event_output_func(struct input_dev *input_dev,
+ struct gpio_event_info *info, void **data, int func);
+extern int gpio_event_output_event(struct input_dev *input_dev,
+ struct gpio_event_info *info, void **data,
+ unsigned int type, unsigned int code, int value);
+struct gpio_event_output_info {
+ /* initialize to gpio_event_output_func and gpio_event_output_event */
+ struct gpio_event_info info;
+ uint16_t flags;
+ uint16_t type;
+ const struct gpio_event_direct_entry *keymap;
+ size_t keymap_size;
+};
+
+
+/* axes */
+
+enum gpio_event_axis_flags {
+ GPIOEAF_PRINT_UNKNOWN_DIRECTION = 1U << 16,
+ GPIOEAF_PRINT_RAW = 1U << 17,
+ GPIOEAF_PRINT_EVENT = 1U << 18,
+};
+
+extern int gpio_event_axis_func(struct input_dev *input_dev,
+ struct gpio_event_info *info, void **data, int func);
+struct gpio_event_axis_info {
+ /* initialize to gpio_event_axis_func */
+ struct gpio_event_info info;
+ uint8_t count;
+ uint8_t type; /* EV_REL or EV_ABS */
+ uint16_t code;
+ uint16_t decoded_size;
+ uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in);
+ uint32_t *gpio;
+ uint32_t flags;
+};
+#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map
+#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map
+uint16_t gpio_axis_4bit_gray_map(
+ struct gpio_event_axis_info *info, uint16_t in);
+uint16_t gpio_axis_5bit_singletrack_map(
+ struct gpio_event_axis_info *info, uint16_t in);
+
+#endif
diff --git a/drivers/staging/dream/include/linux/msm_adsp.h b/drivers/staging/dream/include/linux/msm_adsp.h
new file mode 100644
index 00000000000..e775f3e94f1
--- /dev/null
+++ b/drivers/staging/dream/include/linux/msm_adsp.h
@@ -0,0 +1,84 @@
+/* drivers/staging/dream/include/linux/msm_adsp.h
+ *
+ * Copyright (c) QUALCOMM Incorporated
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Iliyan Malchev <ibm@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.
+ *
+ */
+#ifndef __LINUX_MSM_ADSP_H
+#define __LINUX_MSM_ADSP_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define ADSP_IOCTL_MAGIC 'q'
+
+/* ADSP_IOCTL_WRITE_COMMAND */
+struct adsp_command_t {
+ uint16_t queue;
+ uint32_t len; /* bytes */
+ uint8_t *data;
+};
+
+/* ADSP_IOCTL_GET_EVENT */
+struct adsp_event_t {
+ uint16_t type; /* 1 == event (RPC), 0 == message (adsp) */
+ uint32_t timeout_ms; /* -1 for infinite, 0 for immediate return */
+ uint16_t msg_id;
+ uint16_t flags; /* 1 == 16--bit event, 0 == 32-bit event */
+ uint32_t len; /* size in, number of bytes out */
+ uint8_t *data;
+};
+
+#define ADSP_IOCTL_ENABLE \
+ _IOR(ADSP_IOCTL_MAGIC, 1, unsigned)
+
+#define ADSP_IOCTL_DISABLE \
+ _IOR(ADSP_IOCTL_MAGIC, 2, unsigned)
+
+#define ADSP_IOCTL_DISABLE_ACK \
+ _IOR(ADSP_IOCTL_MAGIC, 3, unsigned)
+
+#define ADSP_IOCTL_WRITE_COMMAND \
+ _IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *)
+
+#define ADSP_IOCTL_GET_EVENT \
+ _IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *)
+
+#define ADSP_IOCTL_SET_CLKRATE \
+ _IOR(ADSP_IOCTL_MAGIC, 6, unsigned)
+
+#define ADSP_IOCTL_DISABLE_EVENT_RSP \
+ _IOR(ADSP_IOCTL_MAGIC, 10, unsigned)
+
+struct adsp_pmem_info {
+ int fd;
+ void *vaddr;
+};
+
+#define ADSP_IOCTL_REGISTER_PMEM \
+ _IOW(ADSP_IOCTL_MAGIC, 13, unsigned)
+
+#define ADSP_IOCTL_UNREGISTER_PMEM \
+ _IOW(ADSP_IOCTL_MAGIC, 14, unsigned)
+
+/* Cause any further GET_EVENT ioctls to fail (-ENODEV)
+ * until the device is closed and reopened. Useful for
+ * terminating event dispatch threads
+ */
+#define ADSP_IOCTL_ABORT_EVENT_READ \
+ _IOW(ADSP_IOCTL_MAGIC, 15, unsigned)
+
+#define ADSP_IOCTL_LINK_TASK \
+ _IOW(ADSP_IOCTL_MAGIC, 16, unsigned)
+
+#endif
diff --git a/drivers/staging/dream/include/linux/msm_audio.h b/drivers/staging/dream/include/linux/msm_audio.h
new file mode 100644
index 00000000000..cfbdaa0d98b
--- /dev/null
+++ b/drivers/staging/dream/include/linux/msm_audio.h
@@ -0,0 +1,115 @@
+/* drivers/staging/dream/include/linux/msm_audio.h
+ *
+ * Copyright (C) 2008 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 __LINUX_MSM_AUDIO_H
+#define __LINUX_MSM_AUDIO_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/sizes.h>
+
+/* PCM Audio */
+
+#define AUDIO_IOCTL_MAGIC 'a'
+
+#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
+#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
+#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
+#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
+#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
+#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
+#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
+#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
+#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
+#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
+#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
+#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
+#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
+#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
+#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
+#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
+#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned)
+#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned)
+#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned)
+
+#define AUDIO_MAX_COMMON_IOCTL_NUM 100
+
+#define AUDIO_MAX_COMMON_IOCTL_NUM 100
+
+struct msm_audio_config {
+ uint32_t buffer_size;
+ uint32_t buffer_count;
+ uint32_t channel_count;
+ uint32_t sample_rate;
+ uint32_t type;
+ uint32_t unused[3];
+};
+
+struct msm_audio_stats {
+ uint32_t byte_count;
+ uint32_t sample_count;
+ uint32_t unused[2];
+};
+
+/* Audio routing */
+
+#define SND_IOCTL_MAGIC 's'
+
+#define SND_MUTE_UNMUTED 0
+#define SND_MUTE_MUTED 1
+
+struct msm_snd_device_config {
+ uint32_t device;
+ uint32_t ear_mute;
+ uint32_t mic_mute;
+};
+
+#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
+
+#define SND_METHOD_VOICE 0
+
+struct msm_snd_volume_config {
+ uint32_t device;
+ uint32_t method;
+ uint32_t volume;
+};
+
+#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
+
+/* Returns the number of SND endpoints supported. */
+
+#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
+
+struct msm_snd_endpoint {
+ int id; /* input and output */
+ char name[64]; /* output only */
+};
+
+/* Takes an index between 0 and one less than the number returned by
+ * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a
+ * SND endpoint. On input, the .id field contains the number of the
+ * endpoint, and on exit it contains the SND index, while .name contains
+ * the description of the endpoint.
+ */
+
+#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
+
+struct msm_audio_pcm_config {
+ uint32_t pcm_feedback; /* 0 - disable > 0 - enable */
+ uint32_t buffer_count; /* Number of buffers to allocate */
+ uint32_t buffer_size; /* Size of buffer for capturing of
+ PCM samples */
+};
+#endif
diff --git a/drivers/staging/dream/include/linux/msm_rpcrouter.h b/drivers/staging/dream/include/linux/msm_rpcrouter.h
new file mode 100644
index 00000000000..64845fb481f
--- /dev/null
+++ b/drivers/staging/dream/include/linux/msm_rpcrouter.h
@@ -0,0 +1,47 @@
+/* drivers/staging/dream/include/linux/msm_rpcrouter.h
+ *
+ * Copyright (c) QUALCOMM Incorporated
+ * Copyright (C) 2007 Google, Inc.
+ * Author: San Mehat <san@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.
+ *
+ */
+#ifndef __LINUX_MSM_RPCROUTER_H
+#define __LINUX_MSM_RPCROUTER_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define RPC_ROUTER_VERSION_V1 0x00010000
+
+struct rpcrouter_ioctl_server_args {
+ uint32_t prog;
+ uint32_t vers;
+};
+
+#define RPC_ROUTER_IOCTL_MAGIC (0xC1)
+
+#define RPC_ROUTER_IOCTL_GET_VERSION \
+ _IOR(RPC_ROUTER_IOCTL_MAGIC, 0, unsigned int)
+
+#define RPC_ROUTER_IOCTL_GET_MTU \
+ _IOR(RPC_ROUTER_IOCTL_MAGIC, 1, unsigned int)
+
+#define RPC_ROUTER_IOCTL_REGISTER_SERVER \
+ _IOWR(RPC_ROUTER_IOCTL_MAGIC, 2, unsigned int)
+
+#define RPC_ROUTER_IOCTL_UNREGISTER_SERVER \
+ _IOWR(RPC_ROUTER_IOCTL_MAGIC, 3, unsigned int)
+
+#define RPC_ROUTER_IOCTL_GET_MINOR_VERSION \
+ _IOW(RPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
+
+#endif
diff --git a/drivers/staging/dream/include/linux/wakelock.h b/drivers/staging/dream/include/linux/wakelock.h
new file mode 100644
index 00000000000..93c31a4d1ca
--- /dev/null
+++ b/drivers/staging/dream/include/linux/wakelock.h
@@ -0,0 +1,91 @@
+/* drivers/staging/dream/include/linux/wakelock.h
+ *
+ * Copyright (C) 2007-2008 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 _LINUX_WAKELOCK_H
+#define _LINUX_WAKELOCK_H
+
+#include <linux/list.h>
+#include <linux/ktime.h>
+
+/* A wake_lock prevents the system from entering suspend or other low power
+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
+ * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
+ * states that cause large interrupt latencies or that disable a set of
+ * interrupts will not entered from idle until the wake_locks are released.
+ */
+
+enum {
+ WAKE_LOCK_SUSPEND, /* Prevent suspend */
+ WAKE_LOCK_IDLE, /* Prevent low power idle */
+ WAKE_LOCK_TYPE_COUNT
+};
+
+struct wake_lock {
+#ifdef CONFIG_HAS_WAKELOCK
+ struct list_head link;
+ int flags;
+ const char *name;
+ unsigned long expires;
+#ifdef CONFIG_WAKELOCK_STAT
+ struct {
+ int count;
+ int expire_count;
+ int wakeup_count;
+ ktime_t total_time;
+ ktime_t prevent_suspend_time;
+ ktime_t max_time;
+ ktime_t last_time;
+ } stat;
+#endif
+#endif
+};
+
+#ifdef CONFIG_HAS_WAKELOCK
+
+void wake_lock_init(struct wake_lock *lock, int type, const char *name);
+void wake_lock_destroy(struct wake_lock *lock);
+void wake_lock(struct wake_lock *lock);
+void wake_lock_timeout(struct wake_lock *lock, long timeout);
+void wake_unlock(struct wake_lock *lock);
+
+/* wake_lock_active returns a non-zero value if the wake_lock is currently
+ * locked. If the wake_lock has a timeout, it does not check the timeout
+ * but if the timeout had aready been checked it will return 0.
+ */
+int wake_lock_active(struct wake_lock *lock);
+
+/* has_wake_lock returns 0 if no wake locks of the specified type are active,
+ * and non-zero if one or more wake locks are held. Specifically it returns
+ * -1 if one or more wake locks with no timeout are active or the
+ * number of jiffies until all active wake locks time out.
+ */
+long has_wake_lock(int type);
+
+#else
+
+static inline void wake_lock_init(struct wake_lock *lock, int type,
+ const char *name) {}
+static inline void wake_lock_destroy(struct wake_lock *lock) {}
+static inline void wake_lock(struct wake_lock *lock) {}
+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {}
+static inline void wake_unlock(struct wake_lock *lock) {}
+
+static inline int wake_lock_active(struct wake_lock *lock) { return 0; }
+static inline long has_wake_lock(int type) { return 0; }
+
+#endif
+
+#endif
+
diff --git a/drivers/staging/dream/include/mach/camera.h b/drivers/staging/dream/include/mach/camera.h
new file mode 100644
index 00000000000..c20f0423abd
--- /dev/null
+++ b/drivers/staging/dream/include/mach/camera.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#ifndef __ASM__ARCH_CAMERA_H
+#define __ASM__ARCH_CAMERA_H
+
+#include <linux/list.h>
+#include <linux/poll.h>
+#include <linux/cdev.h>
+#include <linux/platform_device.h>
+#include "linux/types.h"
+
+#include <mach/board.h>
+#include <media/msm_camera.h>
+
+#ifdef CONFIG_MSM_CAMERA_DEBUG
+#define CDBG(fmt, args...) printk(KERN_INFO "msm_camera: " fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+#define MSM_CAMERA_MSG 0
+#define MSM_CAMERA_EVT 1
+#define NUM_WB_EXP_NEUTRAL_REGION_LINES 4
+#define NUM_WB_EXP_STAT_OUTPUT_BUFFERS 3
+#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
+#define NUM_AF_STAT_OUTPUT_BUFFERS 3
+
+enum msm_queue {
+ MSM_CAM_Q_CTRL, /* control command or control command status */
+ MSM_CAM_Q_VFE_EVT, /* adsp event */
+ MSM_CAM_Q_VFE_MSG, /* adsp message */
+ MSM_CAM_Q_V4L2_REQ, /* v4l2 request */
+};
+
+enum vfe_resp_msg {
+ VFE_EVENT,
+ VFE_MSG_GENERAL,
+ VFE_MSG_SNAPSHOT,
+ VFE_MSG_OUTPUT1,
+ VFE_MSG_OUTPUT2,
+ VFE_MSG_STATS_AF,
+ VFE_MSG_STATS_WE,
+};
+
+struct msm_vfe_phy_info {
+ uint32_t sbuf_phy;
+ uint32_t y_phy;
+ uint32_t cbcr_phy;
+};
+
+struct msm_vfe_resp {
+ enum vfe_resp_msg type;
+ struct msm_vfe_evt_msg evt_msg;
+ struct msm_vfe_phy_info phy;
+ void *extdata;
+ int32_t extlen;
+};
+
+struct msm_vfe_callback {
+ void (*vfe_resp)(struct msm_vfe_resp *,
+ enum msm_queue, void *syncdata);
+ void* (*vfe_alloc)(int, void *syncdata);
+};
+
+struct msm_camvfe_fn {
+ int (*vfe_init)(struct msm_vfe_callback *, struct platform_device *);
+ int (*vfe_enable)(struct camera_enable_cmd *);
+ int (*vfe_config)(struct msm_vfe_cfg_cmd *, void *);
+ int (*vfe_disable)(struct camera_enable_cmd *,
+ struct platform_device *dev);
+ void (*vfe_release)(struct platform_device *);
+};
+
+struct msm_sensor_ctrl {
+ int (*s_init)(const struct msm_camera_sensor_info *);
+ int (*s_release)(void);
+ int (*s_config)(void __user *);
+};
+
+struct msm_sync {
+ /* These two queues are accessed from a process context only. */
+ struct hlist_head frame; /* most-frequently accessed */
+ struct hlist_head stats;
+
+ /* The message queue is used by the control thread to send commands
+ * to the config thread, and also by the DSP to send messages to the
+ * config thread. Thus it is the only queue that is accessed from
+ * both interrupt and process context.
+ */
+ spinlock_t msg_event_q_lock;
+ struct list_head msg_event_q;
+ wait_queue_head_t msg_event_wait;
+
+ /* This queue contains preview frames. It is accessed by the DSP (in
+ * in interrupt context, and by the frame thread.
+ */
+ spinlock_t prev_frame_q_lock;
+ struct list_head prev_frame_q;
+ wait_queue_head_t prev_frame_wait;
+ int unblock_poll_frame;
+
+ /* This queue contains snapshot frames. It is accessed by the DSP (in
+ * interrupt context, and by the control thread.
+ */
+ spinlock_t pict_frame_q_lock;
+ struct list_head pict_frame_q;
+ wait_queue_head_t pict_frame_wait;
+
+ struct msm_camera_sensor_info *sdata;
+ struct msm_camvfe_fn vfefn;
+ struct msm_sensor_ctrl sctrl;
+ struct platform_device *pdev;
+ uint8_t opencnt;
+ void *cropinfo;
+ int croplen;
+ unsigned pict_pp;
+
+ const char *apps_id;
+
+ struct mutex lock;
+ struct list_head list;
+};
+
+#define MSM_APPS_ID_V4L2 "msm_v4l2"
+#define MSM_APPS_ID_PROP "msm_qct"
+
+struct msm_device {
+ struct msm_sync *sync; /* most-frequently accessed */
+ struct device *device;
+ struct cdev cdev;
+ /* opened is meaningful only for the config and frame nodes,
+ * which may be opened only once.
+ */
+ atomic_t opened;
+};
+
+struct msm_control_device_queue {
+ spinlock_t ctrl_status_q_lock;
+ struct list_head ctrl_status_q;
+ wait_queue_head_t ctrl_status_wait;
+};
+
+struct msm_control_device {
+ struct msm_device *pmsm;
+
+ /* This queue used by the config thread to send responses back to the
+ * control thread. It is accessed only from a process context.
+ */
+ struct msm_control_device_queue ctrl_q;
+};
+
+/* this structure is used in kernel */
+struct msm_queue_cmd {
+ struct list_head list;
+ enum msm_queue type;
+ void *command;
+};
+
+struct register_address_value_pair {
+ uint16_t register_address;
+ uint16_t register_value;
+};
+
+struct msm_pmem_region {
+ struct hlist_node list;
+ int type;
+ void *vaddr;
+ unsigned long paddr;
+ unsigned long len;
+ struct file *file;
+ uint32_t y_off;
+ uint32_t cbcr_off;
+ int fd;
+ uint8_t active;
+};
+
+struct axidata {
+ uint32_t bufnum1;
+ uint32_t bufnum2;
+ struct msm_pmem_region *region;
+};
+
+#ifdef CONFIG_MSM_CAMERA_FLASH
+int msm_camera_flash_set_led_state(unsigned led_state);
+#else
+static inline int msm_camera_flash_set_led_state(unsigned led_state)
+{
+ return -ENOTSUPP;
+}
+#endif
+
+/* Below functions are added for V4L2 kernel APIs */
+struct msm_v4l2_driver {
+ struct msm_sync *sync;
+ int (*open)(struct msm_sync *, const char *apps_id);
+ int (*release)(struct msm_sync *);
+ int (*ctrl)(struct msm_sync *, struct msm_ctrl_cmd *);
+ int (*reg_pmem)(struct msm_sync *, struct msm_pmem_info *);
+ int (*get_frame) (struct msm_sync *, struct msm_frame *);
+ int (*put_frame) (struct msm_sync *, struct msm_frame *);
+ int (*get_pict) (struct msm_sync *, struct msm_ctrl_cmd *);
+ unsigned int (*drv_poll) (struct msm_sync *, struct file *,
+ struct poll_table_struct *);
+};
+
+int msm_v4l2_register(struct msm_v4l2_driver *);
+int msm_v4l2_unregister(struct msm_v4l2_driver *);
+
+void msm_camvfe_init(void);
+int msm_camvfe_check(void *);
+void msm_camvfe_fn_init(struct msm_camvfe_fn *, void *);
+int msm_camera_drv_start(struct platform_device *dev,
+ int (*sensor_probe)(const struct msm_camera_sensor_info *,
+ struct msm_sensor_ctrl *));
+
+enum msm_camio_clk_type {
+ CAMIO_VFE_MDC_CLK,
+ CAMIO_MDC_CLK,
+ CAMIO_VFE_CLK,
+ CAMIO_VFE_AXI_CLK,
+
+ CAMIO_MAX_CLK
+};
+
+enum msm_camio_clk_src_type {
+ MSM_CAMIO_CLK_SRC_INTERNAL,
+ MSM_CAMIO_CLK_SRC_EXTERNAL,
+ MSM_CAMIO_CLK_SRC_MAX
+};
+
+enum msm_s_test_mode {
+ S_TEST_OFF,
+ S_TEST_1,
+ S_TEST_2,
+ S_TEST_3
+};
+
+enum msm_s_resolution {
+ S_QTR_SIZE,
+ S_FULL_SIZE,
+ S_INVALID_SIZE
+};
+
+enum msm_s_reg_update {
+ /* Sensor egisters that need to be updated during initialization */
+ S_REG_INIT,
+ /* Sensor egisters that needs periodic I2C writes */
+ S_UPDATE_PERIODIC,
+ /* All the sensor Registers will be updated */
+ S_UPDATE_ALL,
+ /* Not valid update */
+ S_UPDATE_INVALID
+};
+
+enum msm_s_setting {
+ S_RES_PREVIEW,
+ S_RES_CAPTURE
+};
+
+int msm_camio_enable(struct platform_device *dev);
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clk);
+int msm_camio_clk_disable(enum msm_camio_clk_type clk);
+int msm_camio_clk_config(uint32_t freq);
+void msm_camio_clk_rate_set(int rate);
+void msm_camio_clk_axi_rate_set(int rate);
+
+void msm_camio_camif_pad_reg_reset(void);
+void msm_camio_camif_pad_reg_reset_2(void);
+
+void msm_camio_vfe_blk_reset(void);
+
+void msm_camio_clk_sel(enum msm_camio_clk_src_type);
+void msm_camio_disable(struct platform_device *);
+int msm_camio_probe_on(struct platform_device *);
+int msm_camio_probe_off(struct platform_device *);
+#endif
diff --git a/drivers/staging/dream/include/mach/msm_adsp.h b/drivers/staging/dream/include/mach/msm_adsp.h
new file mode 100644
index 00000000000..a081683328a
--- /dev/null
+++ b/drivers/staging/dream/include/mach/msm_adsp.h
@@ -0,0 +1,112 @@
+/* include/asm-arm/arch-msm/msm_adsp.h
+ *
+ * Copyright (C) 2008 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 __ASM__ARCH_MSM_ADSP_H
+#define __ASM__ARCH_MSM_ADSP_H
+
+struct msm_adsp_module;
+
+struct msm_adsp_ops {
+ /* event is called from interrupt context when a message
+ * arrives from the DSP. Use the provided function pointer
+ * to copy the message into a local buffer. Do NOT call
+ * it multiple times.
+ */
+ void (*event)(void *driver_data, unsigned id, size_t len,
+ void (*getevent)(void *ptr, size_t len));
+};
+
+/* Get, Put, Enable, and Disable are synchronous and must only
+ * be called from thread context. Enable and Disable will block
+ * up to one second in the event of a fatal DSP error but are
+ * much faster otherwise.
+ */
+int msm_adsp_get(const char *name, struct msm_adsp_module **module,
+ struct msm_adsp_ops *ops, void *driver_data);
+void msm_adsp_put(struct msm_adsp_module *module);
+int msm_adsp_enable(struct msm_adsp_module *module);
+int msm_adsp_disable(struct msm_adsp_module *module);
+int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate);
+
+/* Write is safe to call from interrupt context.
+ */
+int msm_adsp_write(struct msm_adsp_module *module,
+ unsigned queue_id,
+ void *data, size_t len);
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+/* Command Queue Indexes */
+#define QDSP_lpmCommandQueue 0
+#define QDSP_mpuAfeQueue 1
+#define QDSP_mpuGraphicsCmdQueue 2
+#define QDSP_mpuModmathCmdQueue 3
+#define QDSP_mpuVDecCmdQueue 4
+#define QDSP_mpuVDecPktQueue 5
+#define QDSP_mpuVEncCmdQueue 6
+#define QDSP_rxMpuDecCmdQueue 7
+#define QDSP_rxMpuDecPktQueue 8
+#define QDSP_txMpuEncQueue 9
+#define QDSP_uPAudPPCmd1Queue 10
+#define QDSP_uPAudPPCmd2Queue 11
+#define QDSP_uPAudPPCmd3Queue 12
+#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
+#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
+#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
+#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
+#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
+#define QDSP_uPAudPreProcCmdQueue 18
+#define QDSP_uPAudRecBitStreamQueue 19
+#define QDSP_uPAudRecCmdQueue 20
+#define QDSP_uPDiagQueue 21
+#define QDSP_uPJpegActionCmdQueue 22
+#define QDSP_uPJpegCfgCmdQueue 23
+#define QDSP_uPVocProcQueue 24
+#define QDSP_vfeCommandQueue 25
+#define QDSP_vfeCommandScaleQueue 26
+#define QDSP_vfeCommandTableQueue 27
+#define QDSP_MAX_NUM_QUEUES 28
+#else
+/* Command Queue Indexes */
+#define QDSP_lpmCommandQueue 0
+#define QDSP_mpuAfeQueue 1
+#define QDSP_mpuGraphicsCmdQueue 2
+#define QDSP_mpuModmathCmdQueue 3
+#define QDSP_mpuVDecCmdQueue 4
+#define QDSP_mpuVDecPktQueue 5
+#define QDSP_mpuVEncCmdQueue 6
+#define QDSP_rxMpuDecCmdQueue 7
+#define QDSP_rxMpuDecPktQueue 8
+#define QDSP_txMpuEncQueue 9
+#define QDSP_uPAudPPCmd1Queue 10
+#define QDSP_uPAudPPCmd2Queue 11
+#define QDSP_uPAudPPCmd3Queue 12
+#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
+#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
+#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
+#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
+#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
+#define QDSP_uPAudPreProcCmdQueue 18
+#define QDSP_uPAudRecBitStreamQueue 19
+#define QDSP_uPAudRecCmdQueue 20
+#define QDSP_uPJpegActionCmdQueue 21
+#define QDSP_uPJpegCfgCmdQueue 22
+#define QDSP_uPVocProcQueue 23
+#define QDSP_vfeCommandQueue 24
+#define QDSP_vfeCommandScaleQueue 25
+#define QDSP_vfeCommandTableQueue 26
+#define QDSP_QUEUE_MAX 26
+#endif
+
+#endif
diff --git a/drivers/staging/dream/include/mach/msm_rpcrouter.h b/drivers/staging/dream/include/mach/msm_rpcrouter.h
new file mode 100644
index 00000000000..9724ece1c97
--- /dev/null
+++ b/drivers/staging/dream/include/mach/msm_rpcrouter.h
@@ -0,0 +1,179 @@
+/** include/asm-arm/arch-msm/msm_rpcrouter.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2009 QUALCOMM Incorporated
+ * Author: San Mehat <san@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.
+ *
+ */
+
+#ifndef __ASM__ARCH_MSM_RPCROUTER_H
+#define __ASM__ARCH_MSM_RPCROUTER_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+/* RPC API version structure
+ * Version bit 31 : 1->hashkey versioning,
+ * 0->major-minor (backward compatible) versioning
+ * hashkey versioning:
+ * Version bits 31-0 hashkey
+ * major-minor (backward compatible) versioning
+ * Version bits 30-28 reserved (no match)
+ * Version bits 27-16 major (must match)
+ * Version bits 15-0 minor (greater or equal)
+ */
+#define RPC_VERSION_MODE_MASK 0x80000000
+#define RPC_VERSION_MAJOR_MASK 0x0fff0000
+#define RPC_VERSION_MAJOR_OFFSET 16
+#define RPC_VERSION_MINOR_MASK 0x0000ffff
+
+#define MSM_RPC_VERS(major, minor) \
+ ((uint32_t)((((major) << RPC_VERSION_MAJOR_OFFSET) & \
+ RPC_VERSION_MAJOR_MASK) | \
+ ((minor) & RPC_VERSION_MINOR_MASK)))
+#define MSM_RPC_GET_MAJOR(vers) (((vers) & RPC_VERSION_MAJOR_MASK) >> \
+ RPC_VERSION_MAJOR_OFFSET)
+#define MSM_RPC_GET_MINOR(vers) ((vers) & RPC_VERSION_MINOR_MASK)
+#else
+#define MSM_RPC_VERS(major, minor) (major)
+#define MSM_RPC_GET_MAJOR(vers) (vers)
+#define MSM_RPC_GET_MINOR(vers) 0
+#endif
+
+struct msm_rpc_endpoint;
+
+struct rpcsvr_platform_device
+{
+ struct platform_device base;
+ uint32_t prog;
+ uint32_t vers;
+};
+
+#define RPC_DATA_IN 0
+/*
+ * Structures for sending / receiving direct RPC requests
+ * XXX: Any cred/verif lengths > 0 not supported
+ */
+
+struct rpc_request_hdr
+{
+ uint32_t xid;
+ uint32_t type; /* 0 */
+ uint32_t rpc_vers; /* 2 */
+ uint32_t prog;
+ uint32_t vers;
+ uint32_t procedure;
+ uint32_t cred_flavor;
+ uint32_t cred_length;
+ uint32_t verf_flavor;
+ uint32_t verf_length;
+};
+
+typedef struct
+{
+ uint32_t low;
+ uint32_t high;
+} rpc_reply_progmismatch_data;
+
+typedef struct
+{
+} rpc_denied_reply_hdr;
+
+typedef struct
+{
+ uint32_t verf_flavor;
+ uint32_t verf_length;
+ uint32_t accept_stat;
+#define RPC_ACCEPTSTAT_SUCCESS 0
+#define RPC_ACCEPTSTAT_PROG_UNAVAIL 1
+#define RPC_ACCEPTSTAT_PROG_MISMATCH 2
+#define RPC_ACCEPTSTAT_PROC_UNAVAIL 3
+#define RPC_ACCEPTSTAT_GARBAGE_ARGS 4
+#define RPC_ACCEPTSTAT_SYSTEM_ERR 5
+#define RPC_ACCEPTSTAT_PROG_LOCKED 6
+ /*
+ * Following data is dependant on accept_stat
+ * If ACCEPTSTAT == PROG_MISMATCH then there is a
+ * 'rpc_reply_progmismatch_data' structure following the header.
+ * Otherwise the data is procedure specific
+ */
+} rpc_accepted_reply_hdr;
+
+struct rpc_reply_hdr
+{
+ uint32_t xid;
+ uint32_t type;
+ uint32_t reply_stat;
+#define RPCMSG_REPLYSTAT_ACCEPTED 0
+#define RPCMSG_REPLYSTAT_DENIED 1
+ union {
+ rpc_accepted_reply_hdr acc_hdr;
+ rpc_denied_reply_hdr dny_hdr;
+ } data;
+};
+
+/* flags for msm_rpc_connect() */
+#define MSM_RPC_UNINTERRUPTIBLE 0x0001
+
+/* use IS_ERR() to check for failure */
+struct msm_rpc_endpoint *msm_rpc_open(void);
+/* Connect with the specified server version */
+struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags);
+uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept);
+/* check if server version can handle client requested version */
+int msm_rpc_is_compatible_version(uint32_t server_version,
+ uint32_t client_version);
+
+int msm_rpc_close(struct msm_rpc_endpoint *ept);
+int msm_rpc_write(struct msm_rpc_endpoint *ept,
+ void *data, int len);
+int msm_rpc_read(struct msm_rpc_endpoint *ept,
+ void **data, unsigned len, long timeout);
+void msm_rpc_setup_req(struct rpc_request_hdr *hdr,
+ uint32_t prog, uint32_t vers, uint32_t proc);
+int msm_rpc_register_server(struct msm_rpc_endpoint *ept,
+ uint32_t prog, uint32_t vers);
+int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept,
+ uint32_t prog, uint32_t vers);
+
+/* simple blocking rpc call
+ *
+ * request is mandatory and must have a rpc_request_hdr
+ * at the start. The header will be filled out for you.
+ *
+ * reply provides a buffer for replies of reply_max_size
+ */
+int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc,
+ void *request, int request_size,
+ void *reply, int reply_max_size,
+ long timeout);
+int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc,
+ void *request, int request_size,
+ long timeout);
+
+struct msm_rpc_server
+{
+ struct list_head list;
+ uint32_t flags;
+
+ uint32_t prog;
+ uint32_t vers;
+
+ int (*rpc_call)(struct msm_rpc_server *server,
+ struct rpc_request_hdr *req, unsigned len);
+};
+
+int msm_rpc_create_server(struct msm_rpc_server *server);
+
+#endif
diff --git a/drivers/staging/dream/include/mach/msm_smd.h b/drivers/staging/dream/include/mach/msm_smd.h
new file mode 100644
index 00000000000..bdf7731ab68
--- /dev/null
+++ b/drivers/staging/dream/include/mach/msm_smd.h
@@ -0,0 +1,107 @@
+/* linux/include/asm-arm/arch-msm/msm_smd.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@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 __ASM_ARCH_MSM_SMD_H
+#define __ASM_ARCH_MSM_SMD_H
+
+typedef struct smd_channel smd_channel_t;
+
+/* warning: notify() may be called before open returns */
+int smd_open(const char *name, smd_channel_t **ch, void *priv,
+ void (*notify)(void *priv, unsigned event));
+
+#define SMD_EVENT_DATA 1
+#define SMD_EVENT_OPEN 2
+#define SMD_EVENT_CLOSE 3
+
+int smd_close(smd_channel_t *ch);
+
+/* passing a null pointer for data reads and discards */
+int smd_read(smd_channel_t *ch, void *data, int len);
+
+/* Write to stream channels may do a partial write and return
+** the length actually written.
+** Write to packet channels will never do a partial write --
+** it will return the requested length written or an error.
+*/
+int smd_write(smd_channel_t *ch, const void *data, int len);
+
+int smd_write_avail(smd_channel_t *ch);
+int smd_read_avail(smd_channel_t *ch);
+
+/* Returns the total size of the current packet being read.
+** Returns 0 if no packets available or a stream channel.
+*/
+int smd_cur_packet_size(smd_channel_t *ch);
+
+/* used for tty unthrottling and the like -- causes the notify()
+** callback to be called from the same lock context as is used
+** when it is called from channel updates
+*/
+void smd_kick(smd_channel_t *ch);
+
+
+#if 0
+/* these are interruptable waits which will block you until the specified
+** number of bytes are readable or writable.
+*/
+int smd_wait_until_readable(smd_channel_t *ch, int bytes);
+int smd_wait_until_writable(smd_channel_t *ch, int bytes);
+#endif
+
+typedef enum
+{
+ SMD_PORT_DS = 0,
+ SMD_PORT_DIAG,
+ SMD_PORT_RPC_CALL,
+ SMD_PORT_RPC_REPLY,
+ SMD_PORT_BT,
+ SMD_PORT_CONTROL,
+ SMD_PORT_MEMCPY_SPARE1,
+ SMD_PORT_DATA1,
+ SMD_PORT_DATA2,
+ SMD_PORT_DATA3,
+ SMD_PORT_DATA4,
+ SMD_PORT_DATA5,
+ SMD_PORT_DATA6,
+ SMD_PORT_DATA7,
+ SMD_PORT_DATA8,
+ SMD_PORT_DATA9,
+ SMD_PORT_DATA10,
+ SMD_PORT_DATA11,
+ SMD_PORT_DATA12,
+ SMD_PORT_DATA13,
+ SMD_PORT_DATA14,
+ SMD_PORT_DATA15,
+ SMD_PORT_DATA16,
+ SMD_PORT_DATA17,
+ SMD_PORT_DATA18,
+ SMD_PORT_DATA19,
+ SMD_PORT_DATA20,
+ SMD_PORT_GPS_NMEA,
+ SMD_PORT_BRIDGE_1,
+ SMD_PORT_BRIDGE_2,
+ SMD_PORT_BRIDGE_3,
+ SMD_PORT_BRIDGE_4,
+ SMD_PORT_BRIDGE_5,
+ SMD_PORT_LOOPBACK,
+ SMD_PORT_CS_APPS_MODEM,
+ SMD_PORT_CS_APPS_DSP,
+ SMD_PORT_CS_MODEM_DSP,
+ SMD_NUM_PORTS,
+} smd_port_id_type;
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h
new file mode 100644
index 00000000000..0b6a31259bb
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h
@@ -0,0 +1,94 @@
+#ifndef QDSP5AUDPLAYCMDI_H
+#define QDSP5AUDPLAYCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ Q D S P 5 A U D I O P L A Y T A S K C O M M A N D S
+
+GENERAL DESCRIPTION
+ Command Interface for AUDPLAYTASK on QDSP5
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+
+ audplay_cmd_dec_data_avail
+ Send buffer to AUDPLAY task
+
+
+Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $
+
+===========================================================================*/
+
+#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL 0x0000
+#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN \
+ sizeof(audplay_cmd_bitstream_data_avail)
+
+/* Type specification of dec_data_avail message sent to AUDPLAYTASK
+*/
+typedef struct {
+ /*command ID*/
+ unsigned int cmd_id;
+
+ /* Decoder ID for which message is being sent */
+ unsigned int decoder_id;
+
+ /* Start address of data in ARM global memory */
+ unsigned int buf_ptr;
+
+ /* Number of 16-bit words of bit-stream data contiguously available at the
+ * above-mentioned address. */
+ unsigned int buf_size;
+
+ /* Partition number used by audPlayTask to communicate with DSP's RTOS
+ * kernel */
+ unsigned int partition_number;
+} __attribute__((packed)) audplay_cmd_bitstream_data_avail;
+
+#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003
+#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \
+ sizeof(struct audplay_cmd_hpcm_buf_cfg)
+
+struct audplay_cmd_hpcm_buf_cfg {
+ unsigned int cmd_id;
+ unsigned int hostpcm_config;
+ unsigned int feedback_frequency;
+ unsigned int byte_swap;
+ unsigned int max_buffers;
+ unsigned int partition_number;
+} __attribute__((packed));
+
+#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004
+#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \
+ sizeof(struct audplay_cmd_buffer_update)
+
+struct audplay_cmd_buffer_refresh {
+ unsigned int cmd_id;
+ unsigned int num_buffers;
+ unsigned int buf_read_count;
+ unsigned int buf0_address;
+ unsigned int buf0_length;
+ unsigned int buf1_address;
+ unsigned int buf1_length;
+} __attribute__((packed));
+#endif /* QDSP5AUDPLAYCMD_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h
new file mode 100644
index 00000000000..c63034b8bf1
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h
@@ -0,0 +1,70 @@
+#ifndef QDSP5AUDPLAYMSG_H
+#define QDSP5AUDPLAYMSG_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ Q D S P 5 A U D I O P L A Y T A S K M S G
+
+GENERAL DESCRIPTION
+ Message sent by AUDPLAY task
+
+REFERENCES
+ None
+
+
+Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $
+
+===========================================================================*/
+#define AUDPLAY_MSG_DEC_NEEDS_DATA 0x0001
+#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN \
+ sizeof(audplay_msg_dec_needs_data)
+
+typedef struct{
+ /* reserved*/
+ unsigned int dec_id;
+
+ /* The read pointer offset of external memory until which the
+ * bitstream has been DMAed in. */
+ unsigned int adecDataReadPtrOffset;
+
+ /* The buffer size of external memory. */
+ unsigned int adecDataBufSize;
+
+ unsigned int bitstream_free_len;
+ unsigned int bitstream_write_ptr;
+ unsigned int bitstarem_buf_start;
+ unsigned int bitstream_buf_len;
+} __attribute__((packed)) audplay_msg_dec_needs_data;
+
+#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004
+#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \
+ sizeof(struct audplay_msg_buffer_update)
+
+struct audplay_msg_buffer_update {
+ unsigned int buffer_write_count;
+ unsigned int num_of_buffer;
+ unsigned int buf0_address;
+ unsigned int buf0_length;
+ unsigned int buf1_address;
+ unsigned int buf1_length;
+} __attribute__((packed));
+#endif /* QDSP5AUDPLAYMSG_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h
new file mode 100644
index 00000000000..8bee9c62980
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h
@@ -0,0 +1,914 @@
+#ifndef QDSP5AUDPPCMDI_H
+#define QDSP5AUDPPCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ A U D I O P O S T P R O C E S S I N G I N T E R N A L C O M M A N D S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by AUDPP Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $
+
+===========================================================================*/
+
+/*
+ * ARM to AUDPPTASK Commands
+ *
+ * ARM uses three command queues to communicate with AUDPPTASK
+ * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands
+ * Location : MEMA
+ * Buffer Size : 6 words
+ * No of buffers in a queue : 20 for gaming audio and 5 for other images
+ * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier
+ * Location : MEMA
+ * Buffer Size : 23
+ * No of buffers in a queue : 2
+ * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands
+ * Location : MEMA
+ * Buffer Size : 145
+ * No of buffers in a queue : 3
+ */
+
+/*
+ * Commands Related to uPAudPPCmd1Queue
+ */
+
+/*
+ * Command Structure to enable or disable the active decoders
+ */
+
+#define AUDPP_CMD_CFG_DEC_TYPE 0x0001
+#define AUDPP_CMD_CFG_DEC_TYPE_LEN sizeof(audpp_cmd_cfg_dec_type)
+
+/* Enable the decoder */
+#define AUDPP_CMD_DEC_TYPE_M 0x000F
+
+#define AUDPP_CMD_ENA_DEC_V 0x4000
+#define AUDPP_CMD_DIS_DEC_V 0x0000
+#define AUDPP_CMD_DEC_STATE_M 0x4000
+
+#define AUDPP_CMD_UPDATDE_CFG_DEC 0x8000
+#define AUDPP_CMD_DONT_UPDATE_CFG_DEC 0x0000
+
+
+/* Type specification of cmd_cfg_dec */
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short dec0_cfg;
+ unsigned short dec1_cfg;
+ unsigned short dec2_cfg;
+ unsigned short dec3_cfg;
+ unsigned short dec4_cfg;
+} __attribute__((packed)) audpp_cmd_cfg_dec_type;
+
+/*
+ * Command Structure to Pause , Resume and flushes the selected audio decoders
+ */
+
+#define AUDPP_CMD_DEC_CTRL 0x0002
+#define AUDPP_CMD_DEC_CTRL_LEN sizeof(audpp_cmd_dec_ctrl)
+
+/* Decoder control commands for pause, resume and flush */
+#define AUDPP_CMD_FLUSH_V 0x2000
+
+#define AUDPP_CMD_PAUSE_V 0x4000
+#define AUDPP_CMD_RESUME_V 0x0000
+
+#define AUDPP_CMD_UPDATE_V 0x8000
+#define AUDPP_CMD_IGNORE_V 0x0000
+
+
+/* Type Spec for decoder control command*/
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short dec0_ctrl;
+ unsigned short dec1_ctrl;
+ unsigned short dec2_ctrl;
+ unsigned short dec3_ctrl;
+ unsigned short dec4_ctrl;
+} __attribute__((packed)) audpp_cmd_dec_ctrl;
+
+/*
+ * Command Structure to Configure the AVSync FeedBack Mechanism
+ */
+
+#define AUDPP_CMD_AVSYNC 0x0003
+#define AUDPP_CMD_AVSYNC_LEN sizeof(audpp_cmd_avsync)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short object_number;
+ unsigned short interrupt_interval_lsw;
+ unsigned short interrupt_interval_msw;
+} __attribute__((packed)) audpp_cmd_avsync;
+
+/*
+ * Command Structure to enable or disable(sleep) the AUDPPTASK
+ */
+
+#define AUDPP_CMD_CFG 0x0004
+#define AUDPP_CMD_CFG_LEN sizeof(audpp_cmd_cfg)
+
+#define AUDPP_CMD_CFG_SLEEP 0x0000
+#define AUDPP_CMD_CFG_ENABLE 0xFFFF
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short cfg;
+} __attribute__((packed)) audpp_cmd_cfg;
+
+/*
+ * Command Structure to Inject or drop the specified no of samples
+ */
+
+#define AUDPP_CMD_ADJUST_SAMP 0x0005
+#define AUDPP_CMD_ADJUST_SAMP_LEN sizeof(audpp_cmd_adjust_samp)
+
+#define AUDPP_CMD_SAMP_DROP -1
+#define AUDPP_CMD_SAMP_INSERT 0x0001
+
+#define AUDPP_CMD_NUM_SAMPLES 0x0001
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short object_no;
+ signed short sample_insert_or_drop;
+ unsigned short num_samples;
+} __attribute__((packed)) audpp_cmd_adjust_samp;
+
+/*
+ * Command Structure to Configure AVSync Feedback Mechanism
+ */
+
+#define AUDPP_CMD_AVSYNC_CMD_2 0x0006
+#define AUDPP_CMD_AVSYNC_CMD_2_LEN sizeof(audpp_cmd_avsync_cmd_2)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short object_number;
+ unsigned short interrupt_interval_lsw;
+ unsigned short interrupt_interval_msw;
+ unsigned short sample_counter_dlsw;
+ unsigned short sample_counter_dmsw;
+ unsigned short sample_counter_msw;
+ unsigned short byte_counter_dlsw;
+ unsigned short byte_counter_dmsw;
+ unsigned short byte_counter_msw;
+} __attribute__((packed)) audpp_cmd_avsync_cmd_2;
+
+/*
+ * Command Structure to Configure AVSync Feedback Mechanism
+ */
+
+#define AUDPP_CMD_AVSYNC_CMD_3 0x0007
+#define AUDPP_CMD_AVSYNC_CMD_3_LEN sizeof(audpp_cmd_avsync_cmd_3)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short object_number;
+ unsigned short interrupt_interval_lsw;
+ unsigned short interrupt_interval_msw;
+ unsigned short sample_counter_dlsw;
+ unsigned short sample_counter_dmsw;
+ unsigned short sample_counter_msw;
+ unsigned short byte_counter_dlsw;
+ unsigned short byte_counter_dmsw;
+ unsigned short byte_counter_msw;
+} __attribute__((packed)) audpp_cmd_avsync_cmd_3;
+
+#define AUDPP_CMD_ROUTING_MODE 0x0008
+#define AUDPP_CMD_ROUTING_MODE_LEN \
+sizeof(struct audpp_cmd_routing_mode)
+
+struct audpp_cmd_routing_mode {
+ unsigned short cmd_id;
+ unsigned short object_number;
+ unsigned short routing_mode;
+} __attribute__((packed));
+
+/*
+ * Commands Related to uPAudPPCmd2Queue
+ */
+
+/*
+ * Command Structure to configure Per decoder Parameters (Common)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS 0x0000
+#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN \
+ sizeof(audpp_cmd_cfg_adec_params_common)
+
+#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM 0x4000
+#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM 0x0000
+
+#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM 0x8000
+#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM 0x0000
+
+/* Sampling frequency*/
+#define AUDPP_CMD_SAMP_RATE_96000 0x0000
+#define AUDPP_CMD_SAMP_RATE_88200 0x0001
+#define AUDPP_CMD_SAMP_RATE_64000 0x0002
+#define AUDPP_CMD_SAMP_RATE_48000 0x0003
+#define AUDPP_CMD_SAMP_RATE_44100 0x0004
+#define AUDPP_CMD_SAMP_RATE_32000 0x0005
+#define AUDPP_CMD_SAMP_RATE_24000 0x0006
+#define AUDPP_CMD_SAMP_RATE_22050 0x0007
+#define AUDPP_CMD_SAMP_RATE_16000 0x0008
+#define AUDPP_CMD_SAMP_RATE_12000 0x0009
+#define AUDPP_CMD_SAMP_RATE_11025 0x000A
+#define AUDPP_CMD_SAMP_RATE_8000 0x000B
+
+
+/*
+ * Type specification of cmd_adec_cfg sent to all decoder
+ */
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short length;
+ unsigned short dec_id;
+ unsigned short status_msg_flag;
+ unsigned short decoder_frame_counter_msg_period;
+ unsigned short input_sampling_frequency;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_common;
+
+/*
+ * Command Structure to configure Per decoder Parameters (Wav)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN \
+ sizeof(audpp_cmd_cfg_adec_params_wav)
+
+
+#define AUDPP_CMD_WAV_STEREO_CFG_MONO 0x0001
+#define AUDPP_CMD_WAV_STEREO_CFG_STEREO 0x0002
+
+#define AUDPP_CMD_WAV_PCM_WIDTH_8 0x0000
+#define AUDPP_CMD_WAV_PCM_WIDTH_16 0x0001
+#define AUDPP_CMD_WAV_PCM_WIDTH_32 0x0002
+
+typedef struct {
+ audpp_cmd_cfg_adec_params_common common;
+ unsigned short stereo_cfg;
+ unsigned short pcm_width;
+ unsigned short sign;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav;
+
+/*
+ * Command Structure to configure Per decoder Parameters (ADPCM)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN \
+ sizeof(audpp_cmd_cfg_adec_params_adpcm)
+
+
+#define AUDPP_CMD_ADPCM_STEREO_CFG_MONO 0x0001
+#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO 0x0002
+
+typedef struct {
+ audpp_cmd_cfg_adec_params_common common;
+ unsigned short stereo_cfg;
+ unsigned short block_size;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm;
+
+/*
+ * Command Structure to configure Per decoder Parameters (MP3)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN \
+ sizeof(audpp_cmd_cfg_adec_params_mp3)
+
+typedef struct {
+ audpp_cmd_cfg_adec_params_common common;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3;
+
+
+/*
+ * Command Structure to configure Per decoder Parameters (AAC)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN \
+ sizeof(audpp_cmd_cfg_adec_params_aac)
+
+
+#define AUDPP_CMD_AAC_FORMAT_ADTS -1
+#define AUDPP_CMD_AAC_FORMAT_RAW 0x0000
+#define AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW 0x0001
+#define AUDPP_CMD_AAC_FORMAT_LOAS 0x0002
+
+#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC 0x0002
+#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP 0x0004
+#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC 0x0011
+
+#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON 0x0001
+#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF 0x0000
+
+#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON 0x0001
+#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF 0x0000
+
+typedef struct {
+ audpp_cmd_cfg_adec_params_common common;
+ signed short format;
+ unsigned short audio_object;
+ unsigned short ep_config;
+ unsigned short aac_section_data_resilience_flag;
+ unsigned short aac_scalefactor_data_resilience_flag;
+ unsigned short aac_spectral_data_resilience_flag;
+ unsigned short sbr_on_flag;
+ unsigned short sbr_ps_on_flag;
+ unsigned short dual_mono_mode;
+ unsigned short channel_configuration;
+} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac;
+
+/*
+ * Command Structure to configure Per decoder Parameters (V13K)
+ */
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN \
+ sizeof(struct audpp_cmd_cfg_adec_params_v13k)
+
+
+#define AUDPP_CMD_STEREO_CFG_MONO 0x0001
+#define AUDPP_CMD_STEREO_CFG_STEREO 0x0002
+
+struct audpp_cmd_cfg_adec_params_v13k {
+ audpp_cmd_cfg_adec_params_common common;
+ unsigned short stereo_cfg;
+} __attribute__((packed));
+
+#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \
+ sizeof(struct audpp_cmd_cfg_adec_params_evrc)
+
+struct audpp_cmd_cfg_adec_params_evrc {
+ audpp_cmd_cfg_adec_params_common common;
+ unsigned short stereo_cfg;
+} __attribute__ ((packed));
+
+/*
+ * Command Structure to configure the HOST PCM interface
+ */
+
+#define AUDPP_CMD_PCM_INTF 0x0001
+#define AUDPP_CMD_PCM_INTF_2 0x0002
+#define AUDPP_CMD_PCM_INTF_LEN sizeof(audpp_cmd_pcm_intf)
+
+#define AUDPP_CMD_PCM_INTF_MONO_V 0x0001
+#define AUDPP_CMD_PCM_INTF_STEREO_V 0x0002
+
+/* These two values differentiate the two types of commands that could be issued
+ * Interface configuration command and Buffer update command */
+
+#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V 0x0000
+#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V -1
+
+#define AUDPP_CMD_PCM_INTF_RX_ENA_M 0x000F
+#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V 0x0008
+#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V 0x0004
+
+/* These flags control the enabling and disabling of the interface together
+ * with host interface bit mask. */
+
+#define AUDPP_CMD_PCM_INTF_ENA_V -1
+#define AUDPP_CMD_PCM_INTF_DIS_V 0x0000
+
+
+#define AUDPP_CMD_PCM_INTF_FULL_DUPLEX 0x0
+#define AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP 0x1
+
+
+#define AUDPP_CMD_PCM_INTF_OBJECT_NUM 0x5
+#define AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM 0x6
+
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short object_num;
+ signed short config;
+ unsigned short intf_type;
+
+ /* DSP -> ARM Configuration */
+ unsigned short read_buf1LSW;
+ unsigned short read_buf1MSW;
+ unsigned short read_buf1_len;
+
+ unsigned short read_buf2LSW;
+ unsigned short read_buf2MSW;
+ unsigned short read_buf2_len;
+ /* 0:HOST_PCM_INTF disable
+ ** 0xFFFF: HOST_PCM_INTF enable
+ */
+ signed short dsp_to_arm_flag;
+ unsigned short partition_number;
+
+ /* ARM -> DSP Configuration */
+ unsigned short write_buf1LSW;
+ unsigned short write_buf1MSW;
+ unsigned short write_buf1_len;
+
+ unsigned short write_buf2LSW;
+ unsigned short write_buf2MSW;
+ unsigned short write_buf2_len;
+
+ /* 0:HOST_PCM_INTF disable
+ ** 0xFFFF: HOST_PCM_INTF enable
+ */
+ signed short arm_to_rx_flag;
+ unsigned short weight_decoder_to_rx;
+ unsigned short weight_arm_to_rx;
+
+ unsigned short partition_number_arm_to_dsp;
+ unsigned short sample_rate;
+ unsigned short channel_mode;
+} __attribute__((packed)) audpp_cmd_pcm_intf;
+
+/*
+ ** BUFFER UPDATE COMMAND
+ */
+#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \
+ sizeof(audpp_cmd_pcm_intf_send_buffer)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short host_pcm_object;
+ /* set config = 0xFFFF for configuration*/
+ signed short config;
+ unsigned short intf_type;
+ unsigned short dsp_to_arm_buf_id;
+ unsigned short arm_to_dsp_buf_id;
+ unsigned short arm_to_dsp_buf_len;
+} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer;
+
+
+/*
+ * Commands Related to uPAudPPCmd3Queue
+ */
+
+/*
+ * Command Structure to configure post processing params (Commmon)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS 0x0000
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN \
+ sizeof(audpp_cmd_cfg_object_params_common)
+
+#define AUDPP_CMD_OBJ0_UPDATE 0x8000
+#define AUDPP_CMD_OBJ0_DONT_UPDATE 0x0000
+
+#define AUDPP_CMD_OBJ1_UPDATE 0x8000
+#define AUDPP_CMD_OBJ1_DONT_UPDATE 0x0000
+
+#define AUDPP_CMD_OBJ2_UPDATE 0x8000
+#define AUDPP_CMD_OBJ2_DONT_UPDATE 0x0000
+
+#define AUDPP_CMD_OBJ3_UPDATE 0x8000
+#define AUDPP_CMD_OBJ3_DONT_UPDATE 0x0000
+
+#define AUDPP_CMD_OBJ4_UPDATE 0x8000
+#define AUDPP_CMD_OBJ4_DONT_UPDATE 0x0000
+
+#define AUDPP_CMD_HPCM_UPDATE 0x8000
+#define AUDPP_CMD_HPCM_DONT_UPDATE 0x0000
+
+#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000
+#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short obj0_cfg;
+ unsigned short obj1_cfg;
+ unsigned short obj2_cfg;
+ unsigned short obj3_cfg;
+ unsigned short obj4_cfg;
+ unsigned short host_pcm_obj_cfg;
+ unsigned short comman_cfg;
+ unsigned short command_type;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_common;
+
+/*
+ * Command Structure to configure post processing params (Volume)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \
+ sizeof(audpp_cmd_cfg_object_params_volume)
+
+typedef struct {
+ audpp_cmd_cfg_object_params_common common;
+ unsigned short volume;
+ unsigned short pan;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_volume;
+
+/*
+ * Command Structure to configure post processing params (PCM Filter) --DOUBT
+ */
+
+typedef struct {
+ unsigned short numerator_b0_filter_lsw;
+ unsigned short numerator_b0_filter_msw;
+ unsigned short numerator_b1_filter_lsw;
+ unsigned short numerator_b1_filter_msw;
+ unsigned short numerator_b2_filter_lsw;
+ unsigned short numerator_b2_filter_msw;
+} __attribute__((packed)) numerator;
+
+typedef struct {
+ unsigned short denominator_a0_filter_lsw;
+ unsigned short denominator_a0_filter_msw;
+ unsigned short denominator_a1_filter_lsw;
+ unsigned short denominator_a1_filter_msw;
+} __attribute__((packed)) denominator;
+
+typedef struct {
+ unsigned short shift_factor_0;
+} __attribute__((packed)) shift_factor;
+
+typedef struct {
+ unsigned short pan_filter_0;
+} __attribute__((packed)) pan;
+
+typedef struct {
+ numerator numerator_filter;
+ denominator denominator_filter;
+ shift_factor shift_factor_filter;
+ pan pan_filter;
+} __attribute__((packed)) filter_1;
+
+typedef struct {
+ numerator numerator_filter[2];
+ denominator denominator_filter[2];
+ shift_factor shift_factor_filter[2];
+ pan pan_filter[2];
+} __attribute__((packed)) filter_2;
+
+typedef struct {
+ numerator numerator_filter[3];
+ denominator denominator_filter[3];
+ shift_factor shift_factor_filter[3];
+ pan pan_filter[3];
+} __attribute__((packed)) filter_3;
+
+typedef struct {
+ numerator numerator_filter[4];
+ denominator denominator_filter[4];
+ shift_factor shift_factor_filter[4];
+ pan pan_filter[4];
+} __attribute__((packed)) filter_4;
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \
+ sizeof(audpp_cmd_cfg_object_params_pcm)
+
+
+typedef struct {
+ audpp_cmd_cfg_object_params_common common;
+ unsigned short active_flag;
+ unsigned short num_bands;
+ union {
+ filter_1 filter_1_params;
+ filter_2 filter_2_params;
+ filter_3 filter_3_params;
+ filter_4 filter_4_params;
+ } __attribute__((packed)) params_filter;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm;
+
+
+/*
+ * Command Structure to configure post processing parameters (equalizer)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \
+ sizeof(audpp_cmd_cfg_object_params_eqalizer)
+
+typedef struct {
+ unsigned short numerator_coeff_0_lsw;
+ unsigned short numerator_coeff_0_msw;
+ unsigned short numerator_coeff_1_lsw;
+ unsigned short numerator_coeff_1_msw;
+ unsigned short numerator_coeff_2_lsw;
+ unsigned short numerator_coeff_2_msw;
+} __attribute__((packed)) eq_numerator;
+
+typedef struct {
+ unsigned short denominator_coeff_0_lsw;
+ unsigned short denominator_coeff_0_msw;
+ unsigned short denominator_coeff_1_lsw;
+ unsigned short denominator_coeff_1_msw;
+} __attribute__((packed)) eq_denominator;
+
+typedef struct {
+ unsigned short shift_factor;
+} __attribute__((packed)) eq_shiftfactor;
+
+typedef struct {
+ eq_numerator numerator;
+ eq_denominator denominator;
+ eq_shiftfactor shiftfactor;
+} __attribute__((packed)) eq_coeff_1;
+
+typedef struct {
+ eq_numerator numerator[2];
+ eq_denominator denominator[2];
+ eq_shiftfactor shiftfactor[2];
+} __attribute__((packed)) eq_coeff_2;
+
+typedef struct {
+ eq_numerator numerator[3];
+ eq_denominator denominator[3];
+ eq_shiftfactor shiftfactor[3];
+} __attribute__((packed)) eq_coeff_3;
+
+typedef struct {
+ eq_numerator numerator[4];
+ eq_denominator denominator[4];
+ eq_shiftfactor shiftfactor[4];
+} __attribute__((packed)) eq_coeff_4;
+
+typedef struct {
+ eq_numerator numerator[5];
+ eq_denominator denominator[5];
+ eq_shiftfactor shiftfactor[5];
+} __attribute__((packed)) eq_coeff_5;
+
+typedef struct {
+ eq_numerator numerator[6];
+ eq_denominator denominator[6];
+ eq_shiftfactor shiftfactor[6];
+} __attribute__((packed)) eq_coeff_6;
+
+typedef struct {
+ eq_numerator numerator[7];
+ eq_denominator denominator[7];
+ eq_shiftfactor shiftfactor[7];
+} __attribute__((packed)) eq_coeff_7;
+
+typedef struct {
+ eq_numerator numerator[8];
+ eq_denominator denominator[8];
+ eq_shiftfactor shiftfactor[8];
+} __attribute__((packed)) eq_coeff_8;
+
+typedef struct {
+ eq_numerator numerator[9];
+ eq_denominator denominator[9];
+ eq_shiftfactor shiftfactor[9];
+} __attribute__((packed)) eq_coeff_9;
+
+typedef struct {
+ eq_numerator numerator[10];
+ eq_denominator denominator[10];
+ eq_shiftfactor shiftfactor[10];
+} __attribute__((packed)) eq_coeff_10;
+
+typedef struct {
+ eq_numerator numerator[11];
+ eq_denominator denominator[11];
+ eq_shiftfactor shiftfactor[11];
+} __attribute__((packed)) eq_coeff_11;
+
+typedef struct {
+ eq_numerator numerator[12];
+ eq_denominator denominator[12];
+ eq_shiftfactor shiftfactor[12];
+} __attribute__((packed)) eq_coeff_12;
+
+
+typedef struct {
+ audpp_cmd_cfg_object_params_common common;
+ unsigned short eq_flag;
+ unsigned short num_bands;
+ union {
+ eq_coeff_1 eq_coeffs_1;
+ eq_coeff_2 eq_coeffs_2;
+ eq_coeff_3 eq_coeffs_3;
+ eq_coeff_4 eq_coeffs_4;
+ eq_coeff_5 eq_coeffs_5;
+ eq_coeff_6 eq_coeffs_6;
+ eq_coeff_7 eq_coeffs_7;
+ eq_coeff_8 eq_coeffs_8;
+ eq_coeff_9 eq_coeffs_9;
+ eq_coeff_10 eq_coeffs_10;
+ eq_coeff_11 eq_coeffs_11;
+ eq_coeff_12 eq_coeffs_12;
+ } __attribute__((packed)) eq_coeff;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer;
+
+
+/*
+ * Command Structure to configure post processing parameters (ADRC)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \
+ sizeof(audpp_cmd_cfg_object_params_adrc)
+
+
+#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000
+#define AUDPP_CMD_ADRC_FLAG_ENA -1
+
+typedef struct {
+ audpp_cmd_cfg_object_params_common common;
+ signed short adrc_flag;
+ unsigned short compression_th;
+ unsigned short compression_slope;
+ unsigned short rms_time;
+ unsigned short attack_const_lsw;
+ unsigned short attack_const_msw;
+ unsigned short release_const_lsw;
+ unsigned short release_const_msw;
+ unsigned short adrc_system_delay;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_adrc;
+
+/*
+ * Command Structure to configure post processing parameters(Spectrum Analizer)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \
+ sizeof(audpp_cmd_cfg_object_params_spectram)
+
+
+typedef struct {
+ audpp_cmd_cfg_object_params_common common;
+ unsigned short sample_interval;
+ unsigned short num_coeff;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram;
+
+/*
+ * Command Structure to configure post processing parameters (QConcert)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \
+ sizeof(audpp_cmd_cfg_object_params_qconcert)
+
+
+#define AUDPP_CMD_QCON_ENA_FLAG_ENA -1
+#define AUDPP_CMD_QCON_ENA_FLAG_DIS 0x0000
+
+#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE -1
+#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT 0x0000
+#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE 0x0001
+#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002
+
+#define AUDPP_CMD_QCON_GAIN_UNIT 0x7FFF
+#define AUDPP_CMD_QCON_GAIN_SIX_DB 0x4027
+
+
+#define AUDPP_CMD_QCON_EXPANSION_MAX 0x7FFF
+
+
+typedef struct {
+ audpp_cmd_cfg_object_params_common common;
+ signed short enable_flag;
+ signed short output_mode;
+ signed short gain;
+ signed short expansion;
+ signed short delay;
+ unsigned short stages_per_mode;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert;
+
+/*
+ * Command Structure to configure post processing parameters (Side Chain)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \
+ sizeof(audpp_cmd_cfg_object_params_sidechain)
+
+
+#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS 0x0000
+#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA -1
+
+typedef struct {
+ audpp_cmd_cfg_object_params_common common;
+ signed short active_flag;
+ unsigned short num_bands;
+ union {
+ filter_1 filter_1_params;
+ filter_2 filter_2_params;
+ filter_3 filter_3_params;
+ filter_4 filter_4_params;
+ } __attribute__((packed)) params_filter;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain;
+
+
+/*
+ * Command Structure to configure post processing parameters (QAFX)
+ */
+
+#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \
+ sizeof(audpp_cmd_cfg_object_params_qafx)
+
+#define AUDPP_CMD_QAFX_ENA_DISA 0x0000
+#define AUDPP_CMD_QAFX_ENA_ENA_CFG -1
+#define AUDPP_CMD_QAFX_ENA_DIS_CFG 0x0001
+
+#define AUDPP_CMD_QAFX_CMD_TYPE_ENV 0x0100
+#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ 0x0010
+#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY 0x1000
+
+#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE 0x0100
+#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS 0x0101
+#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI 0x0102
+#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL 0X0103
+#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES 0x0107
+
+#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ 0x0010
+#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL 0x0011
+#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST 0x0012
+#define AUDPP_CMD_QAFX_CMDS_OBJ_POS 0x0013
+#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL 0x0014
+
+
+typedef struct {
+ audpp_cmd_cfg_object_params_common common;
+ signed short enable;
+ unsigned short command_type;
+ unsigned short num_commands;
+ unsigned short commands;
+} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx;
+
+/*
+ * Command Structure to enable , disable or configure the reverberation effect
+ * (Common)
+ */
+
+#define AUDPP_CMD_REVERB_CONFIG 0x0001
+#define AUDPP_CMD_REVERB_CONFIG_COMMON_LEN \
+ sizeof(audpp_cmd_reverb_config_common)
+
+#define AUDPP_CMD_ENA_ENA 0xFFFF
+#define AUDPP_CMD_ENA_DIS 0x0000
+#define AUDPP_CMD_ENA_CFG 0x0001
+
+#define AUDPP_CMD_CMD_TYPE_ENV 0x0104
+#define AUDPP_CMD_CMD_TYPE_OBJ 0x0015
+#define AUDPP_CMD_CMD_TYPE_QUERY 0x1000
+
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short enable;
+ unsigned short cmd_type;
+} __attribute__((packed)) audpp_cmd_reverb_config_common;
+
+/*
+ * Command Structure to enable , disable or configure the reverberation effect
+ * (ENV-0x0104)
+ */
+
+#define AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN \
+ sizeof(audpp_cmd_reverb_config_env_104)
+
+typedef struct {
+ audpp_cmd_reverb_config_common common;
+ unsigned short env_gain;
+ unsigned short decay_msw;
+ unsigned short decay_lsw;
+ unsigned short decay_timeratio_msw;
+ unsigned short decay_timeratio_lsw;
+ unsigned short delay_time;
+ unsigned short reverb_gain;
+ unsigned short reverb_delay;
+} __attribute__((packed)) audpp_cmd_reverb_config_env_104;
+
+/*
+ * Command Structure to enable , disable or configure the reverberation effect
+ * (ENV-0x0015)
+ */
+
+#define AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN \
+ sizeof(audpp_cmd_reverb_config_env_15)
+
+typedef struct {
+ audpp_cmd_reverb_config_common common;
+ unsigned short object_num;
+ unsigned short absolute_gain;
+} __attribute__((packed)) audpp_cmd_reverb_config_env_15;
+
+
+#endif /* QDSP5AUDPPCMDI_H */
+
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h
new file mode 100644
index 00000000000..44fea224001
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h
@@ -0,0 +1,318 @@
+#ifndef QDSP5AUDPPMSG_H
+#define QDSP5AUDPPMSG_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G
+
+GENERAL DESCRIPTION
+ Messages sent by AUDPPTASK to ARM
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+ $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $
+
+===========================================================================*/
+
+/*
+ * AUDPPTASK uses audPPuPRlist to send messages to the ARM
+ * Location : MEMA
+ * Buffer Size : 45
+ * No of Buffers in a queue : 5 for gaming audio and 1 for other images
+ */
+
+/*
+ * MSG to Informs the ARM os Success/Failure of bringing up the decoder
+ */
+
+#define AUDPP_MSG_STATUS_MSG 0x0001
+#define AUDPP_MSG_STATUS_MSG_LEN \
+ sizeof(audpp_msg_status_msg)
+
+#define AUDPP_MSG_STATUS_SLEEP 0x0000
+#define AUDPP_MSG__STATUS_INIT 0x0001
+#define AUDPP_MSG_MSG_STATUS_CFG 0x0002
+#define AUDPP_MSG_STATUS_PLAY 0x0003
+
+#define AUDPP_MSG_REASON_MIPS 0x0000
+#define AUDPP_MSG_REASON_MEM 0x0001
+
+typedef struct{
+ unsigned short dec_id;
+ unsigned short status;
+ unsigned short reason;
+} __attribute__((packed)) audpp_msg_status_msg;
+
+/*
+ * MSG to communicate the spectrum analyzer output bands to the ARM
+ */
+#define AUDPP_MSG_SPA_BANDS 0x0002
+#define AUDPP_MSG_SPA_BANDS_LEN \
+ sizeof(audpp_msg_spa_bands)
+
+typedef struct {
+ unsigned short current_object;
+ unsigned short spa_band_1;
+ unsigned short spa_band_2;
+ unsigned short spa_band_3;
+ unsigned short spa_band_4;
+ unsigned short spa_band_5;
+ unsigned short spa_band_6;
+ unsigned short spa_band_7;
+ unsigned short spa_band_8;
+ unsigned short spa_band_9;
+ unsigned short spa_band_10;
+ unsigned short spa_band_11;
+ unsigned short spa_band_12;
+ unsigned short spa_band_13;
+ unsigned short spa_band_14;
+ unsigned short spa_band_15;
+ unsigned short spa_band_16;
+ unsigned short spa_band_17;
+ unsigned short spa_band_18;
+ unsigned short spa_band_19;
+ unsigned short spa_band_20;
+ unsigned short spa_band_21;
+ unsigned short spa_band_22;
+ unsigned short spa_band_23;
+ unsigned short spa_band_24;
+ unsigned short spa_band_25;
+ unsigned short spa_band_26;
+ unsigned short spa_band_27;
+ unsigned short spa_band_28;
+ unsigned short spa_band_29;
+ unsigned short spa_band_30;
+ unsigned short spa_band_31;
+ unsigned short spa_band_32;
+} __attribute__((packed)) audpp_msg_spa_bands;
+
+/*
+ * MSG to communicate the PCM I/O buffer status to ARM
+ */
+#define AUDPP_MSG_HOST_PCM_INTF_MSG 0x0003
+#define AUDPP_MSG_HOST_PCM_INTF_MSG_LEN \
+ sizeof(audpp_msg_host_pcm_intf_msg)
+
+#define AUDPP_MSG_HOSTPCM_ID_TX_ARM 0x0000
+#define AUDPP_MSG_HOSTPCM_ID_ARM_TX 0x0001
+#define AUDPP_MSG_HOSTPCM_ID_RX_ARM 0x0002
+#define AUDPP_MSG_HOSTPCM_ID_ARM_RX 0x0003
+
+#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000
+#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001
+#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002
+#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003
+#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004
+#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005
+#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006
+#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007
+#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008
+#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009
+#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A
+#define AUDPP_MSG_SAMP_FREQ_INDX_8000 0x000B
+
+#define AUDPP_MSG_CHANNEL_MODE_MONO 0x0001
+#define AUDPP_MSG_CHANNEL_MODE_STEREO 0x0002
+
+typedef struct{
+ unsigned short obj_num;
+ unsigned short numbers_of_samples;
+ unsigned short host_pcm_id;
+ unsigned short buf_indx;
+ unsigned short samp_freq_indx;
+ unsigned short channel_mode;
+} __attribute__((packed)) audpp_msg_host_pcm_intf_msg;
+
+
+/*
+ * MSG to communicate 3D position of the source and listener , source volume
+ * source rolloff, source orientation
+ */
+
+#define AUDPP_MSG_QAFX_POS 0x0004
+#define AUDPP_MSG_QAFX_POS_LEN \
+ sizeof(audpp_msg_qafx_pos)
+
+typedef struct {
+ unsigned short current_object;
+ unsigned short x_pos_lis_msw;
+ unsigned short x_pos_lis_lsw;
+ unsigned short y_pos_lis_msw;
+ unsigned short y_pos_lis_lsw;
+ unsigned short z_pos_lis_msw;
+ unsigned short z_pos_lis_lsw;
+ unsigned short x_fwd_msw;
+ unsigned short x_fwd_lsw;
+ unsigned short y_fwd_msw;
+ unsigned short y_fwd_lsw;
+ unsigned short z_fwd_msw;
+ unsigned short z_fwd_lsw;
+ unsigned short x_up_msw;
+ unsigned short x_up_lsw;
+ unsigned short y_up_msw;
+ unsigned short y_up_lsw;
+ unsigned short z_up_msw;
+ unsigned short z_up_lsw;
+ unsigned short x_vel_lis_msw;
+ unsigned short x_vel_lis_lsw;
+ unsigned short y_vel_lis_msw;
+ unsigned short y_vel_lis_lsw;
+ unsigned short z_vel_lis_msw;
+ unsigned short z_vel_lis_lsw;
+ unsigned short threed_enable_flag;
+ unsigned short volume;
+ unsigned short x_pos_source_msw;
+ unsigned short x_pos_source_lsw;
+ unsigned short y_pos_source_msw;
+ unsigned short y_pos_source_lsw;
+ unsigned short z_pos_source_msw;
+ unsigned short z_pos_source_lsw;
+ unsigned short max_dist_0_msw;
+ unsigned short max_dist_0_lsw;
+ unsigned short min_dist_0_msw;
+ unsigned short min_dist_0_lsw;
+ unsigned short roll_off_factor;
+ unsigned short mute_after_max_flag;
+ unsigned short x_vel_source_msw;
+ unsigned short x_vel_source_lsw;
+ unsigned short y_vel_source_msw;
+ unsigned short y_vel_source_lsw;
+ unsigned short z_vel_source_msw;
+ unsigned short z_vel_source_lsw;
+} __attribute__((packed)) audpp_msg_qafx_pos;
+
+/*
+ * MSG to provide AVSYNC feedback from DSP to ARM
+ */
+
+#define AUDPP_MSG_AVSYNC_MSG 0x0005
+#define AUDPP_MSG_AVSYNC_MSG_LEN \
+ sizeof(audpp_msg_avsync_msg)
+
+typedef struct {
+ unsigned short active_flag;
+ unsigned short num_samples_counter0_HSW;
+ unsigned short num_samples_counter0_MSW;
+ unsigned short num_samples_counter0_LSW;
+ unsigned short num_bytes_counter0_HSW;
+ unsigned short num_bytes_counter0_MSW;
+ unsigned short num_bytes_counter0_LSW;
+ unsigned short samp_freq_obj_0;
+ unsigned short samp_freq_obj_1;
+ unsigned short samp_freq_obj_2;
+ unsigned short samp_freq_obj_3;
+ unsigned short samp_freq_obj_4;
+ unsigned short samp_freq_obj_5;
+ unsigned short samp_freq_obj_6;
+ unsigned short samp_freq_obj_7;
+ unsigned short samp_freq_obj_8;
+ unsigned short samp_freq_obj_9;
+ unsigned short samp_freq_obj_10;
+ unsigned short samp_freq_obj_11;
+ unsigned short samp_freq_obj_12;
+ unsigned short samp_freq_obj_13;
+ unsigned short samp_freq_obj_14;
+ unsigned short samp_freq_obj_15;
+ unsigned short num_samples_counter4_HSW;
+ unsigned short num_samples_counter4_MSW;
+ unsigned short num_samples_counter4_LSW;
+ unsigned short num_bytes_counter4_HSW;
+ unsigned short num_bytes_counter4_MSW;
+ unsigned short num_bytes_counter4_LSW;
+} __attribute__((packed)) audpp_msg_avsync_msg;
+
+/*
+ * MSG to provide PCM DMA Missed feedback from the DSP to ARM
+ */
+
+#define AUDPP_MSG_PCMDMAMISSED 0x0006
+#define AUDPP_MSG_PCMDMAMISSED_LEN \
+ sizeof(audpp_msg_pcmdmamissed);
+
+typedef struct{
+ /*
+ ** Bit 0 0 = PCM DMA not missed for object 0
+ ** 1 = PCM DMA missed for object0
+ ** Bit 1 0 = PCM DMA not missed for object 1
+ ** 1 = PCM DMA missed for object1
+ ** Bit 2 0 = PCM DMA not missed for object 2
+ ** 1 = PCM DMA missed for object2
+ ** Bit 3 0 = PCM DMA not missed for object 3
+ ** 1 = PCM DMA missed for object3
+ ** Bit 4 0 = PCM DMA not missed for object 4
+ ** 1 = PCM DMA missed for object4
+ */
+ unsigned short pcmdmamissed;
+} __attribute__((packed)) audpp_msg_pcmdmamissed;
+
+/*
+ * MSG to AUDPP enable or disable feedback form DSP to ARM
+ */
+
+#define AUDPP_MSG_CFG_MSG 0x0007
+#define AUDPP_MSG_CFG_MSG_LEN \
+ sizeof(audpp_msg_cfg_msg)
+
+#define AUDPP_MSG_ENA_ENA 0xFFFF
+#define AUDPP_MSG_ENA_DIS 0x0000
+
+typedef struct{
+ /* Enabled - 0xffff
+ ** Disabled - 0
+ */
+ unsigned short enabled;
+} __attribute__((packed)) audpp_msg_cfg_msg;
+
+/*
+ * MSG to communicate the reverb per object volume
+ */
+
+#define AUDPP_MSG_QREVERB_VOLUME 0x0008
+#define AUDPP_MSG_QREVERB_VOLUME_LEN \
+ sizeof(audpp_msg_qreverb_volume)
+
+
+typedef struct {
+ unsigned short obj_0_gain;
+ unsigned short obj_1_gain;
+ unsigned short obj_2_gain;
+ unsigned short obj_3_gain;
+ unsigned short obj_4_gain;
+ unsigned short hpcm_obj_volume;
+} __attribute__((packed)) audpp_msg_qreverb_volume;
+
+#define AUDPP_MSG_ROUTING_ACK 0x0009
+#define AUDPP_MSG_ROUTING_ACK_LEN \
+ sizeof(struct audpp_msg_routing_ack)
+
+struct audpp_msg_routing_ack {
+ unsigned short dec_id;
+ unsigned short routing_mode;
+} __attribute__((packed));
+
+#define AUDPP_MSG_FLUSH_ACK 0x000A
+
+#endif /* QDSP5AUDPPMSG_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h
new file mode 100644
index 00000000000..06d33d57158
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h
@@ -0,0 +1,256 @@
+#ifndef QDSP5AUDPREPROCCMDI_H
+#define QDSP5AUDPREPROCCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by AUDPREPROC Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $
+
+===========================================================================*/
+
+/*
+ * AUDIOPREPROC COMMANDS:
+ * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK
+ * Location : MEMB
+ * Buffer size : 51
+ * Number of buffers in a queue : 3
+ */
+
+/*
+ * Command to configure the parameters of AGC
+ */
+
+#define AUDPREPROC_CMD_CFG_AGC_PARAMS 0x0000
+#define AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN \
+ sizeof(audpreproc_cmd_cfg_agc_params)
+
+#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE 0x0009
+#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH 0x000A
+#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE 0x000B
+#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH 0x000C
+#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG 0x000D
+#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN 0x000E
+#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG 0x000F
+
+#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA -1
+#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS 0x0000
+
+#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN -1
+#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN 0x0000
+
+#define AUDPREPROC_CMD_PARAM_MASK_RMS_TAY 0x0004
+#define AUDPREPROC_CMD_PARAM_MASK_RELEASEK 0x0005
+#define AUDPREPROC_CMD_PARAM_MASK_DELAY 0x0006
+#define AUDPREPROC_CMD_PARAM_MASK_ATTACKK 0x0007
+#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0008
+#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0009
+#define AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 0x000A
+#define AUDPREPROC_CMD_PARAM_MASK_AIG_MIN 0x000B
+#define AUDPREPROC_CMD_PARAM_MASK_AIG_MAX 0x000C
+#define AUDPREPROC_CMD_PARAM_MASK_LEAK_UP 0x000D
+#define AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN 0x000E
+#define AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK 0x000F
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short tx_agc_param_mask;
+ unsigned short tx_agc_enable_flag;
+ unsigned short static_gain;
+ signed short adaptive_gain_flag;
+ unsigned short expander_th;
+ unsigned short expander_slope;
+ unsigned short compressor_th;
+ unsigned short compressor_slope;
+ unsigned short param_mask;
+ unsigned short aig_attackk;
+ unsigned short aig_leak_down;
+ unsigned short aig_leak_up;
+ unsigned short aig_max;
+ unsigned short aig_min;
+ unsigned short aig_releasek;
+ unsigned short aig_leakrate_fast;
+ unsigned short aig_leakrate_slow;
+ unsigned short attackk_msw;
+ unsigned short attackk_lsw;
+ unsigned short delay;
+ unsigned short releasek_msw;
+ unsigned short releasek_lsw;
+ unsigned short rms_tav;
+} __attribute__((packed)) audpreproc_cmd_cfg_agc_params;
+
+
+/*
+ * Command to configure the params of Advanved AGC
+ */
+
+#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2 0x0001
+#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN \
+ sizeof(audpreproc_cmd_cfg_agc_params_2)
+
+#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA -1;
+#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS 0x0000;
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short agc_param_mask;
+ signed short tx_agc_enable_flag;
+ unsigned short comp_static_gain;
+ unsigned short exp_th;
+ unsigned short exp_slope;
+ unsigned short comp_th;
+ unsigned short comp_slope;
+ unsigned short comp_rms_tav;
+ unsigned short comp_samp_mask;
+ unsigned short comp_attackk_msw;
+ unsigned short comp_attackk_lsw;
+ unsigned short comp_releasek_msw;
+ unsigned short comp_releasek_lsw;
+ unsigned short comp_delay;
+ unsigned short comp_makeup_gain;
+} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2;
+
+/*
+ * Command to configure params for ns
+ */
+
+#define AUDPREPROC_CMD_CFG_NS_PARAMS 0x0002
+#define AUDPREPROC_CMD_CFG_NS_PARAMS_LEN \
+ sizeof(audpreproc_cmd_cfg_ns_params)
+
+#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA 0x0001
+#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA 0x0002
+#define AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA 0x0004
+#define AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA 0x0008
+#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS 0x0000
+
+#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA 0x0010
+#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA 0x0020
+#define AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA 0x0040
+#define AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA 0x0080
+#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA 0x0100
+#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA 0x0200
+#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA 0x0400
+#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA 0x0800
+#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS 0x0000
+#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA 0x1000
+#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS 0x0000
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short ec_mode_new;
+ unsigned short dens_gamma_n;
+ unsigned short dens_nfe_block_size;
+ unsigned short dens_limit_ns;
+ unsigned short dens_limit_ns_d;
+ unsigned short wb_gamma_e;
+ unsigned short wb_gamma_n;
+} __attribute__((packed)) audpreproc_cmd_cfg_ns_params;
+
+/*
+ * Command to configure parameters for IIR tuning filter
+ */
+
+#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS 0x0003
+#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \
+ sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params)
+
+#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS 0x0000
+#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA 0x0001
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short active_flag;
+ unsigned short num_bands;
+ unsigned short numerator_coeff_b0_filter0_lsw;
+ unsigned short numerator_coeff_b0_filter0_msw;
+ unsigned short numerator_coeff_b1_filter0_lsw;
+ unsigned short numerator_coeff_b1_filter0_msw;
+ unsigned short numerator_coeff_b2_filter0_lsw;
+ unsigned short numerator_coeff_b2_filter0_msw;
+ unsigned short numerator_coeff_b0_filter1_lsw;
+ unsigned short numerator_coeff_b0_filter1_msw;
+ unsigned short numerator_coeff_b1_filter1_lsw;
+ unsigned short numerator_coeff_b1_filter1_msw;
+ unsigned short numerator_coeff_b2_filter1_lsw;
+ unsigned short numerator_coeff_b2_filter1_msw;
+ unsigned short numerator_coeff_b0_filter2_lsw;
+ unsigned short numerator_coeff_b0_filter2_msw;
+ unsigned short numerator_coeff_b1_filter2_lsw;
+ unsigned short numerator_coeff_b1_filter2_msw;
+ unsigned short numerator_coeff_b2_filter2_lsw;
+ unsigned short numerator_coeff_b2_filter2_msw;
+ unsigned short numerator_coeff_b0_filter3_lsw;
+ unsigned short numerator_coeff_b0_filter3_msw;
+ unsigned short numerator_coeff_b1_filter3_lsw;
+ unsigned short numerator_coeff_b1_filter3_msw;
+ unsigned short numerator_coeff_b2_filter3_lsw;
+ unsigned short numerator_coeff_b2_filter3_msw;
+ unsigned short denominator_coeff_a0_filter0_lsw;
+ unsigned short denominator_coeff_a0_filter0_msw;
+ unsigned short denominator_coeff_a1_filter0_lsw;
+ unsigned short denominator_coeff_a1_filter0_msw;
+ unsigned short denominator_coeff_a0_filter1_lsw;
+ unsigned short denominator_coeff_a0_filter1_msw;
+ unsigned short denominator_coeff_a1_filter1_lsw;
+ unsigned short denominator_coeff_a1_filter1_msw;
+ unsigned short denominator_coeff_a0_filter2_lsw;
+ unsigned short denominator_coeff_a0_filter2_msw;
+ unsigned short denominator_coeff_a1_filter2_lsw;
+ unsigned short denominator_coeff_a1_filter2_msw;
+ unsigned short denominator_coeff_a0_filter3_lsw;
+ unsigned short denominator_coeff_a0_filter3_msw;
+ unsigned short denominator_coeff_a1_filter3_lsw;
+ unsigned short denominator_coeff_a1_filter3_msw;
+
+ unsigned short shift_factor_filter0;
+ unsigned short shift_factor_filter1;
+ unsigned short shift_factor_filter2;
+ unsigned short shift_factor_filter3;
+
+ unsigned short channel_selected0;
+ unsigned short channel_selected1;
+ unsigned short channel_selected2;
+ unsigned short channel_selected3;
+} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params;
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h
new file mode 100644
index 00000000000..f40e41e7673
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h
@@ -0,0 +1,85 @@
+#ifndef QDSP5AUDPREPROCMSG_H
+#define QDSP5AUDPREPROCMSG_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ A U D I O P R E P R O C E S S I N G M E S S A G E S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of messages
+ that are rcvd by AUDPREPROC Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+ $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $
+
+===========================================================================*/
+
+/*
+ * ADSPREPROCTASK Messages
+ * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM
+ * Location : MEMA
+ * Message Length : 2
+ */
+
+/*
+ * Message to indicate particular feature has been enabled or disabled
+ */
+
+
+#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG 0x0000
+#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN \
+ sizeof(audpreproc_msg_cmd_cfg_done_msg)
+
+#define AUDPREPROC_MSG_TYPE_AGC 0x0000
+#define AUDPREPROC_MSG_TYPE_NOISE_REDUCTION 0x0001
+#define AUDPREPROC_MSG_TYPE_IIR_FILTER 0x0002
+
+
+#define AUDPREPROC_MSG_STATUS_FLAG_ENA -1
+#define AUDPREPROC_MSG_STATUS_FLAG_DIS 0x0000
+
+typedef struct {
+ unsigned short type;
+ signed short status_flag;
+} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg;
+
+
+/*
+ * Message to indicate particular feature has selected for wrong samp freq
+ */
+
+#define AUDPREPROC_MSG_ERROR_MSG_ID 0x0001
+#define AUDPREPROC_MSG_ERROR_MSG_ID_LEN \
+ sizeof(audpreproc_msg_error_msg_id)
+
+#define AUDPREPROC_MSG_ERR_INDEX_NS 0x0000
+
+typedef struct {
+ unsigned short err_index;
+} __attribute__((packed)) audpreproc_msg_error_msg_id;
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h
new file mode 100644
index 00000000000..d03ee024ae9
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h
@@ -0,0 +1,176 @@
+#ifndef QDSP5AUDRECCMDI_H
+#define QDSP5AUDRECCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ A U D I O R E C O R D I N T E R N A L C O M M A N D S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by AUDREC Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+ $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $
+
+============================================================================*/
+
+/*
+ * AUDRECTASK COMMANDS
+ * ARM uses 2 queues to communicate with the AUDRECTASK
+ * 1.uPAudRecCmdQueue
+ * Location :MEMC
+ * Buffer Size : 8
+ * No of Buffers in a queue : 3
+ * 2.audRecUpBitStreamQueue
+ * Location : MEMC
+ * Buffer Size : 4
+ * No of buffers in a queue : 2
+ */
+
+/*
+ * Commands on uPAudRecCmdQueue
+ */
+
+/*
+ * Command to initiate and terminate the audio recording section
+ */
+
+#define AUDREC_CMD_CFG 0x0000
+#define AUDREC_CMD_CFG_LEN sizeof(audrec_cmd_cfg)
+
+#define AUDREC_CMD_TYPE_0_INDEX_WAV 0x0000
+#define AUDREC_CMD_TYPE_0_INDEX_AAC 0x0001
+
+#define AUDREC_CMD_TYPE_0_ENA 0x4000
+#define AUDREC_CMD_TYPE_0_DIS 0x0000
+
+#define AUDREC_CMD_TYPE_0_NOUPDATE 0x0000
+#define AUDREC_CMD_TYPE_0_UPDATE 0x8000
+
+#define AUDREC_CMD_TYPE_1_INDEX_SBC 0x0002
+
+#define AUDREC_CMD_TYPE_1_ENA 0x4000
+#define AUDREC_CMD_TYPE_1_DIS 0x0000
+
+#define AUDREC_CMD_TYPE_1_NOUPDATE 0x0000
+#define AUDREC_CMD_TYPE_1_UPDATE 0x8000
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short type_0;
+ unsigned short type_1;
+} __attribute__((packed)) audrec_cmd_cfg;
+
+
+/*
+ * Command to configure the recording parameters for RecType0(AAC/WAV) encoder
+ */
+
+#define AUDREC_CMD_AREC0PARAM_CFG 0x0001
+#define AUDREC_CMD_AREC0PARAM_CFG_LEN \
+ sizeof(audrec_cmd_arec0param_cfg)
+
+#define AUDREC_CMD_SAMP_RATE_INDX_8000 0x000B
+#define AUDREC_CMD_SAMP_RATE_INDX_11025 0x000A
+#define AUDREC_CMD_SAMP_RATE_INDX_12000 0x0009
+#define AUDREC_CMD_SAMP_RATE_INDX_16000 0x0008
+#define AUDREC_CMD_SAMP_RATE_INDX_22050 0x0007
+#define AUDREC_CMD_SAMP_RATE_INDX_24000 0x0006
+#define AUDREC_CMD_SAMP_RATE_INDX_32000 0x0005
+#define AUDREC_CMD_SAMP_RATE_INDX_44100 0x0004
+#define AUDREC_CMD_SAMP_RATE_INDX_48000 0x0003
+
+#define AUDREC_CMD_STEREO_MODE_MONO 0x0000
+#define AUDREC_CMD_STEREO_MODE_STEREO 0x0001
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short ptr_to_extpkt_buffer_msw;
+ unsigned short ptr_to_extpkt_buffer_lsw;
+ unsigned short buf_len;
+ unsigned short samp_rate_index;
+ unsigned short stereo_mode;
+ unsigned short rec_quality;
+} __attribute__((packed)) audrec_cmd_arec0param_cfg;
+
+/*
+ * Command to configure the recording parameters for RecType1(SBC) encoder
+ */
+
+#define AUDREC_CMD_AREC1PARAM_CFG 0x0002
+#define AUDREC_CMD_AREC1PARAM_CFG_LEN \
+ sizeof(audrec_cmd_arec1param_cfg)
+
+#define AUDREC_CMD_PARAM_BUF_BLOCKS_4 0x0000
+#define AUDREC_CMD_PARAM_BUF_BLOCKS_8 0x0001
+#define AUDREC_CMD_PARAM_BUF_BLOCKS_12 0x0002
+#define AUDREC_CMD_PARAM_BUF_BLOCKS_16 0x0003
+
+#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8 0x0010
+#define AUDREC_CMD_PARAM_BUF_MODE_MONO 0x0000
+#define AUDREC_CMD_PARAM_BUF_MODE_DUAL 0x0040
+#define AUDREC_CMD_PARAM_BUF_MODE_STEREO 0x0050
+#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO 0x0060
+#define AUDREC_CMD_PARAM_BUF_LOUDNESS 0x0000
+#define AUDREC_CMD_PARAM_BUF_SNR 0x0100
+#define AUDREC_CMD_PARAM_BUF_BASIC_VER 0x0000
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short ptr_to_extpkt_buffer_msw;
+ unsigned short ptr_to_extpkt_buffer_lsw;
+ unsigned short buf_len;
+ unsigned short param_buf;
+ unsigned short bit_rate_0;
+ unsigned short bit_rate_1;
+} __attribute__((packed)) audrec_cmd_arec1param_cfg;
+
+
+/*
+ * Commands on audRecUpBitStreamQueue
+ */
+
+/*
+ * Command to indicate the current packet read count
+ */
+
+#define AUDREC_CMD_PACKET_EXT_PTR 0x0000
+#define AUDREC_CMD_PACKET_EXT_PTR_LEN \
+ sizeof(audrec_cmd_packet_ext_ptr)
+
+#define AUDREC_CMD_TYPE_0 0x0000
+#define AUDREC_CMD_TYPE_1 0x0001
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short type;
+ unsigned short curr_rec_count_msw;
+ unsigned short curr_rec_count_lsw;
+} __attribute__((packed)) audrec_cmd_packet_ext_ptr;
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h
new file mode 100644
index 00000000000..bb6eb5093cf
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h
@@ -0,0 +1,127 @@
+#ifndef QDSP5AUDRECMSGI_H
+#define QDSP5AUDRECMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ A U D I O R E C O R D M E S S A G E S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of messages
+ that are sent by AUDREC Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+ $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $
+
+============================================================================*/
+
+/*
+ * AUDRECTASK MESSAGES
+ * AUDRECTASK uses audRecUpRlist to communicate with ARM
+ * Location : MEMC
+ * Buffer size : 4
+ * No of buffers in a queue : 2
+ */
+
+/*
+ * Message to notify that config command is done
+ */
+
+#define AUDREC_MSG_CMD_CFG_DONE_MSG 0x0002
+#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN \
+ sizeof(audrec_msg_cmd_cfg_done_msg)
+
+
+#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA 0x4000
+#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS 0x0000
+
+#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE 0x0000
+#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE 0x8000
+
+#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA 0x4000
+#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS 0x0000
+
+#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE 0x0000
+#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE 0x8000
+
+typedef struct {
+ unsigned short type_0;
+ unsigned short type_1;
+} __attribute__((packed))audrec_msg_cmd_cfg_done_msg;
+
+
+/*
+ * Message to notify arec0/1 cfg done and recording params revd by task
+ */
+
+#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG 0x0003
+#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN \
+ sizeof(audrec_msg_cmd_arec_param_cfg_done_msg)
+
+#define AUDREC_MSG_AREC_PARAM_TYPE_0 0x0000
+#define AUDREC_MSG_AREC_PARAM_TYPE_1 0x0001
+
+typedef struct {
+ unsigned short type;
+} __attribute__((packed))audrec_msg_cmd_arec_param_cfg_done_msg;
+
+
+/*
+ * Message to notify no more buffers are available in ext mem to DME
+ */
+
+#define AUDREC_MSG_FATAL_ERR_MSG 0x0004
+#define AUDREC_MSG_FATAL_ERR_MSG_LEN \
+ sizeof(audrec_msg_fatal_err_msg)
+
+#define AUDREC_MSG_FATAL_ERR_TYPE_0 0x0000
+#define AUDREC_MSG_FATAL_ERR_TYPE_1 0x0001
+
+typedef struct {
+ unsigned short type;
+} __attribute__((packed))audrec_msg_fatal_err_msg;
+
+/*
+ * Message to notify DME deliverd the encoded pkt to ext pkt buffer
+ */
+
+#define AUDREC_MSG_PACKET_READY_MSG 0x0005
+#define AUDREC_MSG_PACKET_READY_MSG_LEN \
+ sizeof(audrec_msg_packet_ready_msg)
+
+#define AUDREC_MSG_PACKET_READY_TYPE_0 0x0000
+#define AUDREC_MSG_PACKET_READY_TYPE_1 0x0001
+
+typedef struct {
+ unsigned short type;
+ unsigned short pkt_counter_msw;
+ unsigned short pkt_counter_lsw;
+ unsigned short pkt_read_cnt_msw;
+ unsigned short pkt_read_cnt_lsw;
+} __attribute__((packed))audrec_msg_packet_ready_msg;
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h
new file mode 100644
index 00000000000..574ad6bbcad
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h
@@ -0,0 +1,376 @@
+#ifndef QDSP5VIDJPEGCMDI_H
+#define QDSP5VIDJPEGCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ J P E G I N T E R N A L C O M M A N D S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by JPEG Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+when who what, where, why
+-------- --- ----------------------------------------------------------
+06/09/08 sv initial version
+===========================================================================*/
+
+/*
+ * ARM to JPEG configuration commands are passed through the
+ * uPJpegCfgCmdQueue
+ */
+
+/*
+ * Command to configure JPEG Encoder
+ */
+
+#define JPEG_CMD_ENC_CFG 0x0000
+#define JPEG_CMD_ENC_CFG_LEN sizeof(jpeg_cmd_enc_cfg)
+
+#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0 0x0000
+#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90 0x0100
+#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180 0x0200
+#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270 0x0300
+#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M 0x0003
+#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2 0x0000
+#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1 0x0001
+#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2 0x0002
+
+#define JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M 0x0000FFFF
+#define JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M 0xFFFF0000
+#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA 0x0001
+#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS 0x0000
+
+#define JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M 0xFFFF
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int process_cfg;
+ unsigned int ip_size_cfg;
+ unsigned int op_size_cfg;
+ unsigned int frag_cfg;
+ unsigned int frag_cfg_part[16];
+
+ unsigned int part_num;
+
+ unsigned int op_buf_0_cfg_part1;
+ unsigned int op_buf_0_cfg_part2;
+ unsigned int op_buf_1_cfg_part1;
+ unsigned int op_buf_1_cfg_part2;
+
+ unsigned int luma_qunt_table[32];
+ unsigned int chroma_qunt_table[32];
+
+ unsigned int upsamp_ip_size_cfg;
+ unsigned int upsamp_ip_frame_off;
+ unsigned int upsamp_pp_filter_coeff[64];
+} __attribute__((packed)) jpeg_cmd_enc_cfg;
+
+/*
+ * Command to configure JPEG Decoder
+ */
+
+#define JPEG_CMD_DEC_CFG 0x0001
+#define JPEG_CMD_DEC_CFG_LEN sizeof(jpeg_cmd_dec_cfg)
+
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_M 0x0001
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2 0x0000
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1 0x0001
+
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8 0x000000
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4 0x010000
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2 0x020000
+#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1 0x030000
+
+#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL 0x0000
+#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL 0x0001
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int img_dimension_cfg;
+ unsigned int op_data_format;
+ unsigned int restart_interval;
+ unsigned int ip_buf_partition_num;
+ unsigned int ip_stream_buf_cfg_part1;
+ unsigned int ip_stream_buf_cfg_part2;
+ unsigned int ip_stream_buf_cfg_part3;
+ unsigned int op_stream_buf_0_cfg_part1;
+ unsigned int op_stream_buf_0_cfg_part2;
+ unsigned int op_stream_buf_0_cfg_part3;
+ unsigned int op_stream_buf_1_cfg_part1;
+ unsigned int op_stream_buf_1_cfg_part2;
+ unsigned int op_stream_buf_1_cfg_part3;
+ unsigned int luma_qunt_table_0_3;
+ unsigned int luma_qunt_table_4_7;
+ unsigned int luma_qunt_table_8_11;
+ unsigned int luma_qunt_table_12_15;
+ unsigned int luma_qunt_table_16_19;
+ unsigned int luma_qunt_table_20_23;
+ unsigned int luma_qunt_table_24_27;
+ unsigned int luma_qunt_table_28_31;
+ unsigned int luma_qunt_table_32_35;
+ unsigned int luma_qunt_table_36_39;
+ unsigned int luma_qunt_table_40_43;
+ unsigned int luma_qunt_table_44_47;
+ unsigned int luma_qunt_table_48_51;
+ unsigned int luma_qunt_table_52_55;
+ unsigned int luma_qunt_table_56_59;
+ unsigned int luma_qunt_table_60_63;
+ unsigned int chroma_qunt_table_0_3;
+ unsigned int chroma_qunt_table_4_7;
+ unsigned int chroma_qunt_table_8_11;
+ unsigned int chroma_qunt_table_12_15;
+ unsigned int chroma_qunt_table_16_19;
+ unsigned int chroma_qunt_table_20_23;
+ unsigned int chroma_qunt_table_24_27;
+ unsigned int chroma_qunt_table_28_31;
+ unsigned int chroma_qunt_table_32_35;
+ unsigned int chroma_qunt_table_36_39;
+ unsigned int chroma_qunt_table_40_43;
+ unsigned int chroma_qunt_table_44_47;
+ unsigned int chroma_qunt_table_48_51;
+ unsigned int chroma_qunt_table_52_55;
+ unsigned int chroma_qunt_table_56_59;
+ unsigned int chroma_qunt_table_60_63;
+ unsigned int luma_dc_hm_code_cnt_table_0_3;
+ unsigned int luma_dc_hm_code_cnt_table_4_7;
+ unsigned int luma_dc_hm_code_cnt_table_8_11;
+ unsigned int luma_dc_hm_code_cnt_table_12_15;
+ unsigned int luma_dc_hm_code_val_table_0_3;
+ unsigned int luma_dc_hm_code_val_table_4_7;
+ unsigned int luma_dc_hm_code_val_table_8_11;
+ unsigned int chroma_dc_hm_code_cnt_table_0_3;
+ unsigned int chroma_dc_hm_code_cnt_table_4_7;
+ unsigned int chroma_dc_hm_code_cnt_table_8_11;
+ unsigned int chroma_dc_hm_code_cnt_table_12_15;
+ unsigned int chroma_dc_hm_code_val_table_0_3;
+ unsigned int chroma_dc_hm_code_val_table_4_7;
+ unsigned int chroma_dc_hm_code_val_table_8_11;
+ unsigned int luma_ac_hm_code_cnt_table_0_3;
+ unsigned int luma_ac_hm_code_cnt_table_4_7;
+ unsigned int luma_ac_hm_code_cnt_table_8_11;
+ unsigned int luma_ac_hm_code_cnt_table_12_15;
+ unsigned int luma_ac_hm_code_val_table_0_3;
+ unsigned int luma_ac_hm_code_val_table_4_7;
+ unsigned int luma_ac_hm_code_val_table_8_11;
+ unsigned int luma_ac_hm_code_val_table_12_15;
+ unsigned int luma_ac_hm_code_val_table_16_19;
+ unsigned int luma_ac_hm_code_val_table_20_23;
+ unsigned int luma_ac_hm_code_val_table_24_27;
+ unsigned int luma_ac_hm_code_val_table_28_31;
+ unsigned int luma_ac_hm_code_val_table_32_35;
+ unsigned int luma_ac_hm_code_val_table_36_39;
+ unsigned int luma_ac_hm_code_val_table_40_43;
+ unsigned int luma_ac_hm_code_val_table_44_47;
+ unsigned int luma_ac_hm_code_val_table_48_51;
+ unsigned int luma_ac_hm_code_val_table_52_55;
+ unsigned int luma_ac_hm_code_val_table_56_59;
+ unsigned int luma_ac_hm_code_val_table_60_63;
+ unsigned int luma_ac_hm_code_val_table_64_67;
+ unsigned int luma_ac_hm_code_val_table_68_71;
+ unsigned int luma_ac_hm_code_val_table_72_75;
+ unsigned int luma_ac_hm_code_val_table_76_79;
+ unsigned int luma_ac_hm_code_val_table_80_83;
+ unsigned int luma_ac_hm_code_val_table_84_87;
+ unsigned int luma_ac_hm_code_val_table_88_91;
+ unsigned int luma_ac_hm_code_val_table_92_95;
+ unsigned int luma_ac_hm_code_val_table_96_99;
+ unsigned int luma_ac_hm_code_val_table_100_103;
+ unsigned int luma_ac_hm_code_val_table_104_107;
+ unsigned int luma_ac_hm_code_val_table_108_111;
+ unsigned int luma_ac_hm_code_val_table_112_115;
+ unsigned int luma_ac_hm_code_val_table_116_119;
+ unsigned int luma_ac_hm_code_val_table_120_123;
+ unsigned int luma_ac_hm_code_val_table_124_127;
+ unsigned int luma_ac_hm_code_val_table_128_131;
+ unsigned int luma_ac_hm_code_val_table_132_135;
+ unsigned int luma_ac_hm_code_val_table_136_139;
+ unsigned int luma_ac_hm_code_val_table_140_143;
+ unsigned int luma_ac_hm_code_val_table_144_147;
+ unsigned int luma_ac_hm_code_val_table_148_151;
+ unsigned int luma_ac_hm_code_val_table_152_155;
+ unsigned int luma_ac_hm_code_val_table_156_159;
+ unsigned int luma_ac_hm_code_val_table_160_161;
+ unsigned int chroma_ac_hm_code_cnt_table_0_3;
+ unsigned int chroma_ac_hm_code_cnt_table_4_7;
+ unsigned int chroma_ac_hm_code_cnt_table_8_11;
+ unsigned int chroma_ac_hm_code_cnt_table_12_15;
+ unsigned int chroma_ac_hm_code_val_table_0_3;
+ unsigned int chroma_ac_hm_code_val_table_4_7;
+ unsigned int chroma_ac_hm_code_val_table_8_11;
+ unsigned int chroma_ac_hm_code_val_table_12_15;
+ unsigned int chroma_ac_hm_code_val_table_16_19;
+ unsigned int chroma_ac_hm_code_val_table_20_23;
+ unsigned int chroma_ac_hm_code_val_table_24_27;
+ unsigned int chroma_ac_hm_code_val_table_28_31;
+ unsigned int chroma_ac_hm_code_val_table_32_35;
+ unsigned int chroma_ac_hm_code_val_table_36_39;
+ unsigned int chroma_ac_hm_code_val_table_40_43;
+ unsigned int chroma_ac_hm_code_val_table_44_47;
+ unsigned int chroma_ac_hm_code_val_table_48_51;
+ unsigned int chroma_ac_hm_code_val_table_52_55;
+ unsigned int chroma_ac_hm_code_val_table_56_59;
+ unsigned int chroma_ac_hm_code_val_table_60_63;
+ unsigned int chroma_ac_hm_code_val_table_64_67;
+ unsigned int chroma_ac_hm_code_val_table_68_71;
+ unsigned int chroma_ac_hm_code_val_table_72_75;
+ unsigned int chroma_ac_hm_code_val_table_76_79;
+ unsigned int chroma_ac_hm_code_val_table_80_83;
+ unsigned int chroma_ac_hm_code_val_table_84_87;
+ unsigned int chroma_ac_hm_code_val_table_88_91;
+ unsigned int chroma_ac_hm_code_val_table_92_95;
+ unsigned int chroma_ac_hm_code_val_table_96_99;
+ unsigned int chroma_ac_hm_code_val_table_100_103;
+ unsigned int chroma_ac_hm_code_val_table_104_107;
+ unsigned int chroma_ac_hm_code_val_table_108_111;
+ unsigned int chroma_ac_hm_code_val_table_112_115;
+ unsigned int chroma_ac_hm_code_val_table_116_119;
+ unsigned int chroma_ac_hm_code_val_table_120_123;
+ unsigned int chroma_ac_hm_code_val_table_124_127;
+ unsigned int chroma_ac_hm_code_val_table_128_131;
+ unsigned int chroma_ac_hm_code_val_table_132_135;
+ unsigned int chroma_ac_hm_code_val_table_136_139;
+ unsigned int chroma_ac_hm_code_val_table_140_143;
+ unsigned int chroma_ac_hm_code_val_table_144_147;
+ unsigned int chroma_ac_hm_code_val_table_148_151;
+ unsigned int chroma_ac_hm_code_val_table_152_155;
+ unsigned int chroma_ac_hm_code_val_table_156_159;
+ unsigned int chroma_ac_hm_code_val_table_160_161;
+} __attribute__((packed)) jpeg_cmd_dec_cfg;
+
+
+/*
+ * ARM to JPEG configuration commands are passed through the
+ * uPJpegActionCmdQueue
+ */
+
+/*
+ * Command to start the encode process
+ */
+
+#define JPEG_CMD_ENC_ENCODE 0x0000
+#define JPEG_CMD_ENC_ENCODE_LEN sizeof(jpeg_cmd_enc_encode)
+
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) jpeg_cmd_enc_encode;
+
+
+/*
+ * Command to transition from current state of encoder to IDLE state
+ */
+
+#define JPEG_CMD_ENC_IDLE 0x0001
+#define JPEG_CMD_ENC_IDLE_LEN sizeof(jpeg_cmd_enc_idle)
+
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) jpeg_cmd_enc_idle;
+
+
+/*
+ * Command to inform the encoder that another buffer is ready
+ */
+
+#define JPEG_CMD_ENC_OP_CONSUMED 0x0002
+#define JPEG_CMD_ENC_OP_CONSUMED_LEN sizeof(jpeg_cmd_enc_op_consumed)
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int op_buf_addr;
+ unsigned int op_buf_size;
+} __attribute__((packed)) jpeg_cmd_enc_op_consumed;
+
+
+/*
+ * Command to start the decoding process
+ */
+
+#define JPEG_CMD_DEC_DECODE 0x0003
+#define JPEG_CMD_DEC_DECODE_LEN sizeof(jpeg_cmd_dec_decode)
+
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) jpeg_cmd_dec_decode;
+
+
+/*
+ * Command to transition from the current state of decoder to IDLE
+ */
+
+#define JPEG_CMD_DEC_IDLE 0x0004
+#define JPEG_CMD_DEC_IDLE_LEN sizeof(jpeg_cmd_dec_idle)
+
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) jpeg_cmd_dec_idle;
+
+
+/*
+ * Command to inform that an op buffer is ready for use
+ */
+
+#define JPEG_CMD_DEC_OP_CONSUMED 0x0005
+#define JPEG_CMD_DEC_OP_CONSUMED_LEN sizeof(jpeg_cmd_dec_op_consumed)
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int luma_op_buf_addr;
+ unsigned int luma_op_buf_size;
+ unsigned int chroma_op_buf_addr;
+} __attribute__((packed)) jpeg_cmd_dec_op_consumed;
+
+
+/*
+ * Command to pass a new ip buffer to the jpeg decoder
+ */
+
+#define JPEG_CMD_DEC_IP 0x0006
+#define JPEG_CMD_DEC_IP_LEN sizeof(jpeg_cmd_dec_ip_len)
+
+#define JPEG_CMD_EOI_INDICATOR_NOT_END 0x0000
+#define JPEG_CMD_EOI_INDICATOR_END 0x0001
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int ip_buf_addr;
+ unsigned int ip_buf_size;
+ unsigned int eoi_indicator;
+} __attribute__((packed)) jpeg_cmd_dec_ip;
+
+
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h
new file mode 100644
index 00000000000..d11aa3fbccb
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h
@@ -0,0 +1,177 @@
+#ifndef QDSP5VIDJPEGMSGI_H
+#define QDSP5VIDJPEGMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ J P E G I N T E R N A L M E S S A G E S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of messages
+ that are sent by JPEG Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when who what, where, why
+-------- --- ----------------------------------------------------------
+05/10/08 sv initial version
+===========================================================================*/
+
+/*
+ * Messages from JPEG task to ARM through jpeguPMsgQueue
+ */
+
+/*
+ * Message is ACK for CMD_JPEGE_ENCODE cmd
+ */
+
+#define JPEG_MSG_ENC_ENCODE_ACK 0x0000
+#define JPEG_MSG_ENC_ENCODE_ACK_LEN \
+ sizeof(jpeg_msg_enc_encode_ack)
+
+typedef struct {
+} __attribute__((packed)) jpeg_msg_enc_encode_ack;
+
+
+/*
+ * Message informs the up when op buffer is ready for consumption and
+ * when encoding is complete or errors
+ */
+
+#define JPEG_MSG_ENC_OP_PRODUCED 0x0001
+#define JPEG_MSG_ENC_OP_PRODUCED_LEN \
+ sizeof(jpeg_msg_enc_op_produced)
+
+#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS 0x0000
+#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE 0x0001
+#define JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR 0x10000
+
+typedef struct {
+ unsigned int op_buf_addr;
+ unsigned int op_buf_size;
+ unsigned int op_buf_status;
+} __attribute__((packed)) jpeg_msg_enc_op_produced;
+
+
+/*
+ * Message to ack CMD_JPEGE_IDLE
+ */
+
+#define JPEG_MSG_ENC_IDLE_ACK 0x0002
+#define JPEG_MSG_ENC_IDLE_ACK_LEN sizeof(jpeg_msg_enc_idle_ack)
+
+
+typedef struct {
+} __attribute__ ((packed)) jpeg_msg_enc_idle_ack;
+
+
+/*
+ * Message to indicate the illegal command
+ */
+
+#define JPEG_MSG_ENC_ILLEGAL_COMMAND 0x0003
+#define JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN \
+ sizeof(jpeg_msg_enc_illegal_command)
+
+typedef struct {
+ unsigned int status;
+} __attribute__((packed)) jpeg_msg_enc_illegal_command;
+
+
+/*
+ * Message to ACK CMD_JPEGD_DECODE
+ */
+
+#define JPEG_MSG_DEC_DECODE_ACK 0x0004
+#define JPEG_MSG_DEC_DECODE_ACK_LEN \
+ sizeof(jpeg_msg_dec_decode_ack)
+
+
+typedef struct {
+} __attribute__((packed)) jpeg_msg_dec_decode_ack;
+
+
+/*
+ * Message to inform up that an op buffer is ready for consumption and when
+ * decoding is complete or an error occurs
+ */
+
+#define JPEG_MSG_DEC_OP_PRODUCED 0x0005
+#define JPEG_MSG_DEC_OP_PRODUCED_LEN \
+ sizeof(jpeg_msg_dec_op_produced)
+
+#define JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS 0x0000
+#define JPEG_MSG_DEC_OP_BUF_STATUS_DONE 0x0001
+
+typedef struct {
+ unsigned int luma_op_buf_addr;
+ unsigned int chroma_op_buf_addr;
+ unsigned int num_mcus;
+ unsigned int op_buf_status;
+} __attribute__((packed)) jpeg_msg_dec_op_produced;
+
+/*
+ * Message to ack CMD_JPEGD_IDLE cmd
+ */
+
+#define JPEG_MSG_DEC_IDLE_ACK 0x0006
+#define JPEG_MSG_DEC_IDLE_ACK_LEN sizeof(jpeg_msg_dec_idle_ack)
+
+
+typedef struct {
+} __attribute__((packed)) jpeg_msg_dec_idle_ack;
+
+
+/*
+ * Message to indicate illegal cmd was received
+ */
+
+#define JPEG_MSG_DEC_ILLEGAL_COMMAND 0x0007
+#define JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN \
+ sizeof(jpeg_msg_dec_illegal_command)
+
+
+typedef struct {
+ unsigned int status;
+} __attribute__((packed)) jpeg_msg_dec_illegal_command;
+
+/*
+ * Message to request up for the next segment of ip bit stream
+ */
+
+#define JPEG_MSG_DEC_IP_REQUEST 0x0008
+#define JPEG_MSG_DEC_IP_REQUEST_LEN \
+ sizeof(jpeg_msg_dec_ip_request)
+
+
+typedef struct {
+} __attribute__((packed)) jpeg_msg_dec_ip_request;
+
+
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h
new file mode 100644
index 00000000000..6c76e2c20cf
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h
@@ -0,0 +1,82 @@
+#ifndef QDSP5LPMCMDI_H
+#define QDSP5LPMCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ L P M I N T E R N A L C O M M A N D S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by LPM Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when who what, where, why
+-------- --- ----------------------------------------------------------
+06/12/08 sv initial version
+===========================================================================*/
+
+
+/*
+ * Command to start LPM processing based on the config params
+ */
+
+#define LPM_CMD_START 0x0000
+#define LPM_CMD_START_LEN sizeof(lpm_cmd_start)
+
+#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0 0x00000000
+#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1 0x00010000
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int ip_data_cfg_part1;
+ unsigned int ip_data_cfg_part2;
+ unsigned int ip_data_cfg_part3;
+ unsigned int ip_data_cfg_part4;
+ unsigned int op_data_cfg_part1;
+ unsigned int op_data_cfg_part2;
+ unsigned int op_data_cfg_part3;
+ unsigned int spatial_filter_part[32];
+} __attribute__((packed)) lpm_cmd_start;
+
+
+
+/*
+ * Command to stop LPM processing
+ */
+
+#define LPM_CMD_IDLE 0x0001
+#define LPM_CMD_IDLE_LEN sizeof(lpm_cmd_idle)
+
+typedef struct {
+ unsigned int cmd_id;
+} __attribute__((packed)) lpm_cmd_idle;
+
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h
new file mode 100644
index 00000000000..3d1039d6ba4
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h
@@ -0,0 +1,80 @@
+#ifndef QDSP5LPMMSGI_H
+#define QDSP5LPMMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ L P M I N T E R N A L M E S S A G E S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by LPM Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when who what, where, why
+-------- --- ----------------------------------------------------------
+06/12/08 sv initial version
+===========================================================================*/
+
+/*
+ * Message to acknowledge CMD_LPM_IDLE command
+ */
+
+#define LPM_MSG_IDLE_ACK 0x0000
+#define LPM_MSG_IDLE_ACK_LEN sizeof(lpm_msg_idle_ack)
+
+typedef struct {
+} __attribute__((packed)) lpm_msg_idle_ack;
+
+
+/*
+ * Message to acknowledge CMD_LPM_START command
+ */
+
+
+#define LPM_MSG_START_ACK 0x0001
+#define LPM_MSG_START_ACK_LEN sizeof(lpm_msg_start_ack)
+
+
+typedef struct {
+} __attribute__((packed)) lpm_msg_start_ack;
+
+
+/*
+ * Message to notify the ARM that LPM processing is complete
+ */
+
+#define LPM_MSG_DONE 0x0002
+#define LPM_MSG_DONE_LEN sizeof(lpm_msg_done)
+
+typedef struct {
+} __attribute__((packed)) lpm_msg_done;
+
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h
new file mode 100644
index 00000000000..3a32ee99c6e
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h
@@ -0,0 +1,235 @@
+#ifndef QDSP5VIDDECCMDI_H
+#define QDSP5VIDDECCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ V I D E O D E C O D E R I N T E R N A L C O M M A N D S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by VIDDEC Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when who what, where, why
+-------- --- ----------------------------------------------------------
+05/10/08 ac initial version
+===========================================================================*/
+
+
+/*
+ * Command to inform VIDDEC that new subframe packet is ready
+ */
+
+#define VIDDEC_CMD_SUBFRAME_PKT 0x0000
+#define VIDDEC_CMD_SUBFRAME_PKT_LEN \
+ sizeof(viddec_cmd_subframe_pkt)
+
+#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM 0x0000
+#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA 0x0001
+
+#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI 0x0000
+#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST 0x0001
+#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST 0x0002
+#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST 0x0003
+
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4 0x0000
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0 0x0001
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_264 0x0002
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3 0x0003
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_RV9 0x0004
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9 0x0005
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB 0x0006
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE 0x0007
+#define VIDDEC_CMD_CODEC_SELECTION_WORD_VLD 0x0008
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short packet_seq_number;
+ unsigned short codec_instance_id;
+ unsigned short subframe_packet_size_high;
+ unsigned short subframe_packet_size_low;
+ unsigned short subframe_packet_high;
+ unsigned short subframe_packet_low;
+ unsigned short subframe_packet_partition;
+ unsigned short statistics_packet_size_high;
+ unsigned short statistics_packet_size_low;
+ unsigned short statistics_packet_high;
+ unsigned short statistics_packet_low;
+ unsigned short statistics_partition;
+ unsigned short subframe_info_1;
+ unsigned short subframe_info_0;
+ unsigned short codec_selection_word;
+ unsigned short num_mbs;
+} __attribute__((packed)) viddec_cmd_subframe_pkt;
+
+
+/*
+ * Command to inform VIDDEC task that post processing is required for the frame
+ */
+
+#define VIDDEC_CMD_PP_ENABLE 0x0001
+#define VIDDEC_CMD_PP_ENABLE_LEN \
+ sizeof(viddec_cmd_pp_enable)
+
+#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM 0x0000
+#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA 0x0001
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short packet_seq_num;
+ unsigned short codec_instance_id;
+ unsigned short postproc_info_0;
+ unsigned short codec_selection_word;
+ unsigned short pp_output_addr_high;
+ unsigned short pp_output_addr_low;
+ unsigned short postproc_info_1;
+ unsigned short load_sharing_packet_size_high;
+ unsigned short load_sharing_packet_size_low;
+ unsigned short load_sharing_packet_high;
+ unsigned short load_sharing_packet_low;
+ unsigned short load_sharing_partition;
+ unsigned short pp_param_0;
+ unsigned short pp_param_1;
+ unsigned short pp_param_2;
+ unsigned short pp_param_3;
+} __attribute__((packed)) viddec_cmd_pp_enable;
+
+
+/*
+ * FRAME Header Packet : It is at the start of new frame
+ */
+
+#define VIDDEC_CMD_FRAME_HEADER_PACKET 0x0002
+#define VIDDEC_CMD_FRAME_HEADER_PACKET_LEN \
+ sizeof(viddec_cmd_frame_header_packet)
+
+#define VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP 0x0000
+#define VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK 0x0800
+
+typedef struct {
+ unsigned short packet_id;
+ unsigned short x_dimension;
+ unsigned short y_dimension;
+ unsigned short line_width;
+ unsigned short frame_info_0;
+ unsigned short frame_buffer_0_high;
+ unsigned short frame_buffer_0_low;
+ unsigned short frame_buffer_1_high;
+ unsigned short frame_buffer_1_low;
+ unsigned short frame_buffer_2_high;
+ unsigned short frame_buffer_2_low;
+ unsigned short frame_buffer_3_high;
+ unsigned short frame_buffer_3_low;
+ unsigned short frame_buffer_4_high;
+ unsigned short frame_buffer_4_low;
+ unsigned short frame_buffer_5_high;
+ unsigned short frame_buffer_5_low;
+ unsigned short frame_buffer_6_high;
+ unsigned short frame_buffer_6_low;
+ unsigned short frame_buffer_7_high;
+ unsigned short frame_buffer_7_low;
+ unsigned short frame_buffer_8_high;
+ unsigned short frame_buffer_8_low;
+ unsigned short frame_buffer_9_high;
+ unsigned short frame_buffer_9_low;
+ unsigned short frame_buffer_10_high;
+ unsigned short frame_buffer_10_low;
+ unsigned short frame_buffer_11_high;
+ unsigned short frame_buffer_11_low;
+ unsigned short frame_buffer_12_high;
+ unsigned short frame_buffer_12_low;
+ unsigned short frame_buffer_13_high;
+ unsigned short frame_buffer_13_low;
+ unsigned short frame_buffer_14_high;
+ unsigned short frame_buffer_14_low;
+ unsigned short frame_buffer_15_high;
+ unsigned short frame_buffer_15_low;
+ unsigned short output_frame_buffer_high;
+ unsigned short output_frame_buffer_low;
+ unsigned short end_of_packet_marker;
+} __attribute__((packed)) viddec_cmd_frame_header_packet;
+
+
+/*
+ * SLICE HEADER PACKET
+ * I-Slice and P-Slice
+ */
+
+#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE 0x0003
+#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN \
+ sizeof(viddec_cmd_slice_header_pkt_islice)
+
+#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE 0x0000
+#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE 0x0100
+#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE 0x0200
+#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE 0x0300
+#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE 0x0400
+#define VIDDEC_CMD_ISLICE_INFO_1_NOPADDING 0x0000
+#define VIDDEC_CMD_ISLICE_INFO_1_PADDING 0x0800
+
+#define VIDDEC_CMD_ISLICE_EOP_MARKER 0x7FFF
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short packet_id;
+ unsigned short slice_info_0;
+ unsigned short slice_info_1;
+ unsigned short slice_info_2;
+ unsigned short num_bytes_in_rbsp_high;
+ unsigned short num_bytes_in_rbsp_low;
+ unsigned short num_bytes_in_rbsp_consumed;
+ unsigned short end_of_packet_marker;
+} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice;
+
+
+#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE 0x0003
+#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN \
+ sizeof(viddec_cmd_slice_header_pkt_pslice)
+
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short packet_id;
+ unsigned short slice_info_0;
+ unsigned short slice_info_1;
+ unsigned short slice_info_2;
+ unsigned short slice_info_3;
+ unsigned short refidx_l0_map_tab_info_0;
+ unsigned short refidx_l0_map_tab_info_1;
+ unsigned short refidx_l0_map_tab_info_2;
+ unsigned short refidx_l0_map_tab_info_3;
+ unsigned short num_bytes_in_rbsp_high;
+ unsigned short num_bytes_in_rbsp_low;
+ unsigned short num_bytes_in_rbsp_consumed;
+ unsigned short end_of_packet_marker;
+} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice;
+
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h
new file mode 100644
index 00000000000..c1744c1644d
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h
@@ -0,0 +1,107 @@
+#ifndef QDSP5VIDDECMSGI_H
+#define QDSP5VIDDECMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ V I D E O D E C O D E R I N T E R N A L M E S S A G E S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of messages
+ that are sent by VIDDEC Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when who what, where, why
+-------- --- ----------------------------------------------------------
+05/10/08 ac initial version
+===========================================================================*/
+
+/*
+ * Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK
+ */
+
+#define VIDDEC_MSG_SUBF_DONE 0x0000
+#define VIDDEC_MSG_SUBF_DONE_LEN \
+ sizeof(viddec_msg_subf_done)
+
+typedef struct {
+ unsigned short packet_seq_number;
+ unsigned short codec_instance_id;
+} __attribute__((packed)) viddec_msg_subf_done;
+
+
+/*
+ * Message to inform ARM one frame has been decoded
+ */
+
+#define VIDDEC_MSG_FRAME_DONE 0x0001
+#define VIDDEC_MSG_FRAME_DONE_LEN \
+ sizeof(viddec_msg_frame_done)
+
+typedef struct {
+ unsigned short packet_seq_number;
+ unsigned short codec_instance_id;
+} __attribute__((packed)) viddec_msg_frame_done;
+
+
+/*
+ * Message to inform ARM that post processing frame has been decoded
+ */
+
+#define VIDDEC_MSG_PP_ENABLE_CMD_DONE 0x0002
+#define VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN \
+ sizeof(viddec_msg_pp_enable_cmd_done)
+
+typedef struct {
+ unsigned short packet_seq_number;
+ unsigned short codec_instance_id;
+} __attribute__((packed)) viddec_msg_pp_enable_cmd_done;
+
+
+/*
+ * Message to inform ARM that one post processing frame has been decoded
+ */
+
+
+#define VIDDEC_MSG_PP_FRAME_DONE 0x0003
+#define VIDDEC_MSG_PP_FRAME_DONE_LEN \
+ sizeof(viddec_msg_pp_frame_done)
+
+#define VIDDEC_MSG_DISP_WORTHY_DISP 0x0000
+#define VIDDEC_MSG_DISP_WORTHY_DISP_NONE 0xFFFF
+
+
+typedef struct {
+ unsigned short packet_seq_number;
+ unsigned short codec_instance_id;
+ unsigned short display_worthy;
+} __attribute__((packed)) viddec_msg_pp_frame_done;
+
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h
new file mode 100644
index 00000000000..819544d186d
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h
@@ -0,0 +1,212 @@
+#ifndef QDSP5VIDENCCMDI_H
+#define QDSP5VIDENCCMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ V I D E O E N C O D E R I N T E R N A L C O M M A N D S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by VIDENC Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 2008 by QUALCOMM, Incorporated.
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+Revision History:
+
+when who what, where, why
+-------- --- ----------------------------------------------------------
+09/25/08 umeshp initial version
+===========================================================================*/
+
+ #define VIDENC_CMD_CFG 0x0000
+ #define VIDENC_CMD_ACTIVE 0x0001
+ #define VIDENC_CMD_IDLE 0x0002
+ #define VIDENC_CMD_FRAME_START 0x0003
+ #define VIDENC_CMD_STATUS_QUERY 0x0004
+ #define VIDENC_CMD_RC_CFG 0x0005
+ #define VIDENC_CMD_DIS_CFG 0x0006
+ #define VIDENC_CMD_DIS 0x0007
+ #define VIDENC_CMD_INTRA_REFRESH 0x0008
+ #define VIDENC_CMD_DIGITAL_ZOOM 0x0009
+
+
+/*
+ * Command to pass the frame message information to VIDENC
+ */
+
+
+#define VIDENC_CMD_FRAME_START_LEN \
+ sizeof(videnc_cmd_frame_start)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short frame_info;
+ unsigned short frame_rho_budget_word_high;
+ unsigned short frame_rho_budget_word_low;
+ unsigned short input_luma_addr_high;
+ unsigned short input_luma_addr_low;
+ unsigned short input_chroma_addr_high;
+ unsigned short input_chroma_addr_low;
+ unsigned short ref_vop_buf_ptr_high;
+ unsigned short ref_vop_buf_ptr_low;
+ unsigned short enc_pkt_buf_ptr_high;
+ unsigned short enc_pkt_buf_ptr_low;
+ unsigned short enc_pkt_buf_size_high;
+ unsigned short enc_pkt_buf_size_low;
+ unsigned short unfilt_recon_vop_buf_ptr_high;
+ unsigned short unfilt_recon_vop_buf_ptr_low;
+ unsigned short filt_recon_vop_buf_ptr_high;
+ unsigned short filt_recon_vop_buf_ptr_low;
+} __attribute__((packed)) videnc_cmd_frame_start;
+
+/*
+ * Command to pass the frame-level digital stabilization parameters to VIDENC
+ */
+
+
+#define VIDENC_CMD_DIS_LEN \
+ sizeof(videnc_cmd_dis)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short vfe_out_prev_luma_addr_high;
+ unsigned short vfe_out_prev_luma_addr_low;
+ unsigned short stabilization_info;
+} __attribute__((packed)) videnc_cmd_dis;
+
+/*
+ * Command to pass the codec related parameters to VIDENC
+ */
+
+
+#define VIDENC_CMD_CFG_LEN \
+ sizeof(videnc_cmd_cfg)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short cfg_info_0;
+ unsigned short cfg_info_1;
+ unsigned short four_mv_threshold;
+ unsigned short ise_fse_mv_cost_fac;
+ unsigned short venc_frame_dim;
+ unsigned short venc_DM_partition;
+} __attribute__((packed)) videnc_cmd_cfg;
+
+/*
+ * Command to start the video encoding
+ */
+
+
+#define VIDENC_CMD_ACTIVE_LEN \
+ sizeof(videnc_cmd_active)
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) videnc_cmd_active;
+
+/*
+ * Command to stop the video encoding
+ */
+
+
+#define VIDENC_CMD_IDLE_LEN \
+ sizeof(videnc_cmd_idle)
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) videnc_cmd_idle;
+
+/*
+ * Command to query staus of VIDENC
+ */
+
+
+#define VIDENC_CMD_STATUS_QUERY_LEN \
+ sizeof(videnc_cmd_status_query)
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) videnc_cmd_status_query;
+
+/*
+ * Command to set rate control for a frame
+ */
+
+
+#define VIDENC_CMD_RC_CFG_LEN \
+ sizeof(videnc_cmd_rc_cfg)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short max_frame_qp_delta;
+ unsigned short max_min_frame_qp;
+} __attribute__((packed)) videnc_cmd_rc_cfg;
+
+/*
+ * Command to set intra-refreshing
+ */
+
+
+#define VIDENC_CMD_INTRA_REFRESH_LEN \
+ sizeof(videnc_cmd_intra_refresh)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short num_mb_refresh;
+ unsigned short mb_index[15];
+} __attribute__((packed)) videnc_cmd_intra_refresh;
+
+/*
+ * Command to pass digital zoom information to the VIDENC
+ */
+#define VIDENC_CMD_DIGITAL_ZOOM_LEN \
+ sizeof(videnc_cmd_digital_zoom)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short digital_zoom_en;
+ unsigned short luma_frame_shift_X;
+ unsigned short luma_frame_shift_Y;
+ unsigned short up_ip_luma_rows;
+ unsigned short up_ip_luma_cols;
+ unsigned short up_ip_chroma_rows;
+ unsigned short up_ip_chroma_cols;
+ unsigned short luma_ph_incr_V_low;
+ unsigned short luma_ph_incr_V_high;
+ unsigned short luma_ph_incr_H_low;
+ unsigned short luma_ph_incr_H_high;
+ unsigned short chroma_ph_incr_V_low;
+ unsigned short chroma_ph_incr_V_high;
+ unsigned short chroma_ph_incr_H_low;
+ unsigned short chroma_ph_incr_H_high;
+} __attribute__((packed)) videnc_cmd_digital_zoom;
+
+/*
+ * Command to configure digital stabilization parameters
+ */
+
+#define VIDENC_CMD_DIS_CFG_LEN \
+ sizeof(videnc_cmd_dis_cfg)
+
+typedef struct {
+ unsigned short cmd_id;
+ unsigned short image_stab_subf_start_row_col;
+ unsigned short image_stab_subf_dim;
+ unsigned short image_stab_info_0;
+} __attribute__((packed)) videnc_cmd_dis_cfg;
+
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h
new file mode 100644
index 00000000000..55e8fc2269f
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h
@@ -0,0 +1,910 @@
+#ifndef QDSP5VFECMDI_H
+#define QDSP5VFECMDI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ V F E I N T E R N A L C O M M A N D S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are accepted by VFE Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when who what, where, why
+-------- --- ----------------------------------------------------------
+06/12/08 sv initial version
+===========================================================================*/
+
+/******************************************************************************
+ * Commands through vfeCommandScaleQueue
+ *****************************************************************************/
+
+/*
+ * Command to program scaler for op1 . max op of scaler is VGA
+ */
+
+
+#define VFE_CMD_SCALE_OP1_CFG 0x0000
+#define VFE_CMD_SCALE_OP1_CFG_LEN \
+ sizeof(vfe_cmd_scale_op1_cfg)
+
+#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD 0x0000
+#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED 0x0001
+#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA 0x0002
+#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA 0x0004
+#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA 0x0008
+#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA 0x0010
+#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD 0x0000
+#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED 0x0020
+#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA 0x0040
+#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA 0x0080
+
+#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000
+#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int scale_op1_sel;
+ unsigned int y_scaler_cfg_part1;
+ unsigned int y_scaler_cfg_part2;
+ unsigned int cbcr_scaler_cfg_part1;
+ unsigned int cbcr_scaler_cfg_part2;
+ unsigned int cbcr_scaler_cfg_part3;
+ unsigned int pp_y_scaler_cfg_part1;
+ unsigned int pp_y_scaler_cfg_part2;
+ unsigned int y_scaler_v_coeff_bank_part1[16];
+ unsigned int y_scaler_v_coeff_bank_part2[16];
+ unsigned int y_scaler_h_coeff_bank_part1[16];
+ unsigned int y_scaler_h_coeff_bank_part2[16];
+} __attribute__((packed)) vfe_cmd_scale_op1_cfg;
+
+
+/*
+ * Command to program scaler for op2
+ */
+
+#define VFE_CMD_SCALE_OP2_CFG 0x0001
+#define VFE_CMD_SCALE_OP2_CFG_LEN \
+ sizeof(vfe_cmd_scale_op2_cfg)
+
+#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD 0x0000
+#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED 0x0001
+#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA 0x0002
+#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA 0x0004
+#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA 0x0008
+#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA 0x0010
+#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD 0x0000
+#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED 0x0020
+#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA 0x0040
+#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS 0x0000
+#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA 0x0080
+
+#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000
+#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int scale_op2_sel;
+ unsigned int y_scaler_cfg_part1;
+ unsigned int y_scaler_cfg_part2;
+ unsigned int cbcr_scaler_cfg_part1;
+ unsigned int cbcr_scaler_cfg_part2;
+ unsigned int cbcr_scaler_cfg_part3;
+ unsigned int pp_y_scaler_cfg_part1;
+ unsigned int pp_y_scaler_cfg_part2;
+ unsigned int y_scaler_v_coeff_bank_part1[16];
+ unsigned int y_scaler_v_coeff_bank_part2[16];
+ unsigned int y_scaler_h_coeff_bank_part1[16];
+ unsigned int y_scaler_h_coeff_bank_part2[16];
+} __attribute__((packed)) vfe_cmd_scale_op2_cfg;
+
+
+/******************************************************************************
+ * Commands through vfeCommandTableQueue
+ *****************************************************************************/
+
+/*
+ * Command to program the AXI ip paths
+ */
+
+#define VFE_CMD_AXI_IP_CFG 0x0000
+#define VFE_CMD_AXI_IP_CFG_LEN sizeof(vfe_cmd_axi_ip_cfg)
+
+#define VFE_CMD_IP_SEL_IP_FORMAT_8 0x0000
+#define VFE_CMD_IP_SEL_IP_FORMAT_10 0x0001
+#define VFE_CMD_IP_SEL_IP_FORMAT_12 0x0002
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int ip_sel;
+ unsigned int ip_cfg_part1;
+ unsigned int ip_cfg_part2;
+ unsigned int ip_unpack_cfg_part[6];
+ unsigned int ip_buf_addr[8];
+} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg;
+
+
+/*
+ * Command to program axi op paths
+ */
+
+#define VFE_CMD_AXI_OP_CFG 0x0001
+#define VFE_CMD_AXI_OP_CFG_LEN sizeof(vfe_cmd_axi_op_cfg)
+
+#define VFE_CMD_OP_SEL_OP1 0x0000
+#define VFE_CMD_OP_SEL_OP2 0x0001
+#define VFE_CMD_OP_SEL_OP1_OP2 0x0002
+#define VFE_CMD_OP_SEL_CTOA 0x0003
+#define VFE_CMD_OP_SEL_CTOA_OP1 0x0004
+#define VFE_CMD_OP_SEL_CTOA_OP2 0x0005
+#define VFE_CMD_OP_SEL_OP_FORMAT_8 0x0000
+#define VFE_CMD_OP_SEL_OP_FORMAT_10 0x0008
+#define VFE_CMD_OP_SEL_OP_FORMAT_12 0x0010
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int op_sel;
+ unsigned int op1_y_cfg_part1;
+ unsigned int op1_y_cfg_part2;
+ unsigned int op1_cbcr_cfg_part1;
+ unsigned int op1_cbcr_cfg_part2;
+ unsigned int op2_y_cfg_part1;
+ unsigned int op2_y_cfg_part2;
+ unsigned int op2_cbcr_cfg_part1;
+ unsigned int op2_cbcr_cfg_part2;
+ unsigned int op1_buf1_addr[16];
+ unsigned int op2_buf1_addr[16];
+} __attribute__((packed)) vfe_cmd_axi_op_cfg;
+
+
+
+
+/*
+ * Command to program the roll off correction module
+ */
+
+#define VFE_CMD_ROLLOFF_CFG 0x0002
+#define VFE_CMD_ROLLOFF_CFG_LEN \
+ sizeof(vfe_cmd_rolloff_cfg)
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int correction_opt_center_pos;
+ unsigned int radius_square_entry[32];
+ unsigned int red_table_entry[32];
+ unsigned int green_table_entry[32];
+ unsigned int blue_table_entry[32];
+} __attribute__((packed)) vfe_cmd_rolloff_cfg;
+
+/*
+ * Command to program RGB gamma table
+ */
+
+#define VFE_CMD_RGB_GAMMA_CFG 0x0003
+#define VFE_CMD_RGB_GAMMA_CFG_LEN \
+ sizeof(vfe_cmd_rgb_gamma_cfg)
+
+#define VFE_CMD_RGB_GAMMA_SEL_LINEAR 0x0000
+#define VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR 0x0001
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int rgb_gamma_sel;
+ unsigned int rgb_gamma_entry[256];
+} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg;
+
+
+/*
+ * Command to program luma gamma table for the noise reduction path
+ */
+
+#define VFE_CMD_Y_GAMMA_CFG 0x0004
+#define VFE_CMD_Y_GAMMA_CFG_LEN \
+ sizeof(vfe_cmd_y_gamma_cfg)
+
+#define VFE_CMD_Y_GAMMA_SEL_LINEAR 0x0000
+#define VFE_CMD_Y_GAMMA_SEL_PW_LINEAR 0x0001
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int y_gamma_sel;
+ unsigned int y_gamma_entry[256];
+} __attribute__((packed)) vfe_cmd_y_gamma_cfg;
+
+
+
+/******************************************************************************
+ * Commands through vfeCommandQueue
+ *****************************************************************************/
+
+/*
+ * Command to reset the VFE to a known good state.All previously programmed
+ * Params will be lost
+ */
+
+
+#define VFE_CMD_RESET 0x0000
+#define VFE_CMD_RESET_LEN sizeof(vfe_cmd_reset)
+
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) vfe_cmd_reset;
+
+
+/*
+ * Command to start VFE processing based on the config params
+ */
+
+
+#define VFE_CMD_START 0x0001
+#define VFE_CMD_START_LEN sizeof(vfe_cmd_start)
+
+#define VFE_CMD_STARTUP_PARAMS_SRC_CAMIF 0x0000
+#define VFE_CMD_STARTUP_PARAMS_SRC_AXI 0x0001
+#define VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS 0x0000
+#define VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT 0x0002
+
+#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS 0x0000
+#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA 0x0001
+#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS 0x0000
+#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA 0x0002
+#define VFE_CMD_IMAGE_PL_WHITE_BAL_DIS 0x0000
+#define VFE_CMD_IMAGE_PL_WHITE_BAL_ENA 0x0004
+#define VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS 0x0000
+#define VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA 0x0008
+#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS 0x0000
+#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA 0x0010
+#define VFE_CMD_IMAGE_PL_ADP_FILTER_DIS 0x0000
+#define VFE_CMD_IMAGE_PL_ADP_FILTER_ENA 0x0020
+#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS 0x0000
+#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA 0x0040
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int startup_params;
+ unsigned int image_pipeline;
+ unsigned int frame_dimension;
+} __attribute__((packed)) vfe_cmd_start;
+
+
+/*
+ * Command to halt all processing
+ */
+
+#define VFE_CMD_STOP 0x0002
+#define VFE_CMD_STOP_LEN sizeof(vfe_cmd_stop)
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) vfe_cmd_stop;
+
+
+/*
+ * Command to commit the params that have been programmed to take
+ * effect on the next frame
+ */
+
+#define VFE_CMD_UPDATE 0x0003
+#define VFE_CMD_UPDATE_LEN sizeof(vfe_cmd_update)
+
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) vfe_cmd_update;
+
+
+/*
+ * Command to program CAMIF module
+ */
+
+#define VFE_CMD_CAMIF_CFG 0x0004
+#define VFE_CMD_CAMIF_CFG_LEN sizeof(vfe_cmd_camif_cfg)
+
+#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH 0x0000
+#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW 0x0002
+#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH 0x0000
+#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW 0x0004
+#define VFE_CMD_CFG_SYNC_MODE_APS 0x0000
+#define VFE_CMD_CFG_SYNC_MODE_EFS 0X0008
+#define VFE_CMD_CFG_SYNC_MODE_ELS 0x0010
+#define VFE_CMD_CFG_SYNC_MODE_RVD 0x0018
+#define VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS 0x0000
+#define VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA 0x0020
+#define VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS 0x0000
+#define VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA 0x0080
+#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS 0x0000
+#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA 0x0800
+
+#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16 0x0000
+#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12 0x0010
+
+#define VFE_CMD_EPOCH_IRQ_1_DIS 0x0000
+#define VFE_CMD_EPOCH_IRQ_1_ENA 0x4000
+#define VFE_CMD_EPOCH_IRQ_2_DIS 0x0000
+#define VFE_CMD_EPOCH_IRQ_2_ENA 0x8000
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int cfg;
+ unsigned int efs_cfg;
+ unsigned int frame_cfg;
+ unsigned int window_width_cfg;
+ unsigned int window_height_cfg;
+ unsigned int subsamp1_cfg;
+ unsigned int subsamp2_cfg;
+ unsigned int epoch_irq;
+} __attribute__((packed)) vfe_cmd_camif_cfg;
+
+
+
+/*
+ * Command to program the black level module
+ */
+
+#define VFE_CMD_BLACK_LVL_CFG 0x0005
+#define VFE_CMD_BLACK_LVL_CFG_LEN sizeof(vfe_cmd_black_lvl_cfg)
+
+#define VFE_CMD_BL_SEL_MANUAL 0x0000
+#define VFE_CMD_BL_SEL_AUTO 0x0001
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int black_lvl_sel;
+ unsigned int cfg_part[3];
+} __attribute__((packed)) vfe_cmd_black_lvl_cfg;
+
+
+/*
+ * Command to program the active region by cropping the region of interest
+ */
+
+#define VFE_CMD_ACTIVE_REGION_CFG 0x0006
+#define VFE_CMD_ACTIVE_REGION_CFG_LEN \
+ sizeof(vfe_cmd_active_region_cfg)
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int cfg_part1;
+ unsigned int cfg_part2;
+} __attribute__((packed)) vfe_cmd_active_region_cfg;
+
+
+
+/*
+ * Command to program the defective pixel correction(DPC) ,
+ * adaptive bayer filter (ABF) and demosaic modules
+ */
+
+#define VFE_CMD_DEMOSAIC_CFG 0x0007
+#define VFE_CMD_DEMOSAIC_CFG_LEN sizeof(vfe_cmd_demosaic_cfg)
+
+#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS 0x0000
+#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA 0x0001
+#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS 0x0000
+#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA 0x0002
+#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF 0x0000
+#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON 0x0004
+#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1 0x00000000
+#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2 0x10000000
+#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4 0x20000000
+#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8 0x30000000
+#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2 0x50000000
+#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4 0x60000000
+#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8 0x70000000
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int demosaic_part1;
+ unsigned int demosaic_part2;
+ unsigned int demosaic_part3;
+ unsigned int demosaic_part4;
+ unsigned int demosaic_part5;
+} __attribute__((packed)) vfe_cmd_demosaic_cfg;
+
+
+/*
+ * Command to program the ip format
+ */
+
+#define VFE_CMD_IP_FORMAT_CFG 0x0008
+#define VFE_CMD_IP_FORMAT_CFG_LEN \
+ sizeof(vfe_cmd_ip_format_cfg)
+
+#define VFE_CMD_IP_FORMAT_SEL_RGRG 0x0000
+#define VFE_CMD_IP_FORMAT_SEL_GRGR 0x0001
+#define VFE_CMD_IP_FORMAT_SEL_BGBG 0x0002
+#define VFE_CMD_IP_FORMAT_SEL_GBGB 0x0003
+#define VFE_CMD_IP_FORMAT_SEL_YCBYCR 0x0004
+#define VFE_CMD_IP_FORMAT_SEL_YCRYCB 0x0005
+#define VFE_CMD_IP_FORMAT_SEL_CBYCRY 0x0006
+#define VFE_CMD_IP_FORMAT_SEL_CRYCBY 0x0007
+#define VFE_CMD_IP_FORMAT_SEL_NO_CHROMA 0x0000
+#define VFE_CMD_IP_FORMAT_SEL_CHROMA 0x0008
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int ip_format_sel;
+ unsigned int balance_gains_part1;
+ unsigned int balance_gains_part2;
+} __attribute__((packed)) vfe_cmd_ip_format_cfg;
+
+
+
+/*
+ * Command to program max and min allowed op values
+ */
+
+#define VFE_CMD_OP_CLAMP_CFG 0x0009
+#define VFE_CMD_OP_CLAMP_CFG_LEN \
+ sizeof(vfe_cmd_op_clamp_cfg)
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int op_clamp_max;
+ unsigned int op_clamp_min;
+} __attribute__((packed)) vfe_cmd_op_clamp_cfg;
+
+
+/*
+ * Command to program chroma sub sample module
+ */
+
+#define VFE_CMD_CHROMA_SUBSAMPLE_CFG 0x000A
+#define VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN \
+ sizeof(vfe_cmd_chroma_subsample_cfg)
+
+#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS 0x0000
+#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS 0x0001
+#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS 0x0000
+#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS 0x0002
+#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS 0x0000
+#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA 0x0004
+#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS 0x0000
+#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA 0x0008
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int chroma_subsamp_sel;
+} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg;
+
+
+/*
+ * Command to program the white balance module
+ */
+
+#define VFE_CMD_WHITE_BALANCE_CFG 0x000B
+#define VFE_CMD_WHITE_BALANCE_CFG_LEN \
+ sizeof(vfe_cmd_white_balance_cfg)
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int white_balance_gains;
+} __attribute__((packed)) vfe_cmd_white_balance_cfg;
+
+
+/*
+ * Command to program the color processing module
+ */
+
+#define VFE_CMD_COLOR_PROCESS_CFG 0x000C
+#define VFE_CMD_COLOR_PROCESS_CFG_LEN \
+ sizeof(vfe_cmd_color_process_cfg)
+
+#define VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS 0x0000
+#define VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS 0x0001
+#define VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS 0x0002
+#define VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS 0x0003
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int color_correction_part1;
+ unsigned int color_correction_part2;
+ unsigned int color_correction_part3;
+ unsigned int color_correction_part4;
+ unsigned int color_correction_part5;
+ unsigned int color_correction_part6;
+ unsigned int color_correction_part7;
+ unsigned int chroma_enhance_part1;
+ unsigned int chroma_enhance_part2;
+ unsigned int chroma_enhance_part3;
+ unsigned int chroma_enhance_part4;
+ unsigned int chroma_enhance_part5;
+ unsigned int luma_calc_part1;
+ unsigned int luma_calc_part2;
+} __attribute__((packed)) vfe_cmd_color_process_cfg;
+
+
+/*
+ * Command to program adaptive filter module
+ */
+
+#define VFE_CMD_ADP_FILTER_CFG 0x000D
+#define VFE_CMD_ADP_FILTER_CFG_LEN \
+ sizeof(vfe_cmd_adp_filter_cfg)
+
+#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS 0x0000
+#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA 0x0001
+#define VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE 0x0000
+#define VFE_CMD_ASF_CFG_PART_SINGLE_FILTER 0x0002
+#define VFE_CMD_ASF_CFG_PART_DUAL_FILTER 0x0004
+#define VFE_CMD_ASF_CFG_PART_SHARP_MODE 0x0007
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int asf_cfg_part[7];
+} __attribute__((packed)) vfe_cmd_adp_filter_cfg;
+
+
+/*
+ * Command to program for frame skip pattern for op1 and op2
+ */
+
+#define VFE_CMD_FRAME_SKIP_CFG 0x000E
+#define VFE_CMD_FRAME_SKIP_CFG_LEN \
+ sizeof(vfe_cmd_frame_skip_cfg)
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int frame_skip_pattern_op1;
+ unsigned int frame_skip_pattern_op2;
+} __attribute__((packed)) vfe_cmd_frame_skip_cfg;
+
+
+/*
+ * Command to program field-of-view crop for digital zoom
+ */
+
+#define VFE_CMD_FOV_CROP 0x000F
+#define VFE_CMD_FOV_CROP_LEN sizeof(vfe_cmd_fov_crop)
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int fov_crop_part1;
+ unsigned int fov_crop_part2;
+} __attribute__((packed)) vfe_cmd_fov_crop;
+
+
+
+/*
+ * Command to program auto focus(AF) statistics module
+ */
+
+#define VFE_CMD_STATS_AUTOFOCUS_CFG 0x0010
+#define VFE_CMD_STATS_AUTOFOCUS_CFG_LEN \
+ sizeof(vfe_cmd_stats_autofocus_cfg)
+
+#define VFE_CMD_AF_STATS_SEL_STATS_DIS 0x0000
+#define VFE_CMD_AF_STATS_SEL_STATS_ENA 0x0001
+#define VFE_CMD_AF_STATS_SEL_PRI_FIXED 0x0000
+#define VFE_CMD_AF_STATS_SEL_PRI_VAR 0x0002
+#define VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM 0x00000000
+#define VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX 0x00200000
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int af_stats_sel;
+ unsigned int af_stats_cfg_part[8];
+ unsigned int af_stats_op_buf_hdr;
+ unsigned int af_stats_op_buf[3];
+} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg;
+
+
+/*
+ * Command to program White balance(wb) and exposure (exp)
+ * statistics module
+ */
+
+#define VFE_CMD_STATS_WB_EXP_CFG 0x0011
+#define VFE_CMD_STATS_WB_EXP_CFG_LEN \
+ sizeof(vfe_cmd_stats_wb_exp_cfg)
+
+#define VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS 0x0000
+#define VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA 0x0001
+#define VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED 0x0000
+#define VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR 0x0002
+
+#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8 0x0000
+#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16 0x0001
+#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8 0x0000
+#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4 0x0002
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int wb_exp_stats_sel;
+ unsigned int wb_exp_stats_cfg_part1;
+ unsigned int wb_exp_stats_cfg_part2;
+ unsigned int wb_exp_stats_cfg_part3;
+ unsigned int wb_exp_stats_cfg_part4;
+ unsigned int wb_exp_stats_op_buf_hdr;
+ unsigned int wb_exp_stats_op_buf[3];
+} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg;
+
+
+/*
+ * Command to program histogram(hg) stats module
+ */
+
+#define VFE_CMD_STATS_HG_CFG 0x0012
+#define VFE_CMD_STATS_HG_CFG_LEN \
+ sizeof(vfe_cmd_stats_hg_cfg)
+
+#define VFE_CMD_HG_STATS_SEL_PRI_FIXED 0x0000
+#define VFE_CMD_HG_STATS_SEL_PRI_VAR 0x0002
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int hg_stats_sel;
+ unsigned int hg_stats_cfg_part1;
+ unsigned int hg_stats_cfg_part2;
+ unsigned int hg_stats_op_buf_hdr;
+ unsigned int hg_stats_op_buf;
+} __attribute__((packed)) vfe_cmd_stats_hg_cfg;
+
+
+/*
+ * Command to acknowledge last MSG_VFE_OP1 message
+ */
+
+#define VFE_CMD_OP1_ACK 0x0013
+#define VFE_CMD_OP1_ACK_LEN sizeof(vfe_cmd_op1_ack)
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int op1_buf_y_addr;
+ unsigned int op1_buf_cbcr_addr;
+} __attribute__((packed)) vfe_cmd_op1_ack;
+
+
+
+/*
+ * Command to acknowledge last MSG_VFE_OP2 message
+ */
+
+#define VFE_CMD_OP2_ACK 0x0014
+#define VFE_CMD_OP2_ACK_LEN sizeof(vfe_cmd_op2_ack)
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int op2_buf_y_addr;
+ unsigned int op2_buf_cbcr_addr;
+} __attribute__((packed)) vfe_cmd_op2_ack;
+
+
+
+/*
+ * Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg
+ */
+
+#define VFE_CMD_STATS_AF_ACK 0x0015
+#define VFE_CMD_STATS_AF_ACK_LEN sizeof(vfe_cmd_stats_af_ack)
+
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int af_stats_op_buf;
+} __attribute__((packed)) vfe_cmd_stats_af_ack;
+
+
+/*
+ * Command to acknowledge MSG_VFE_STATS_WB_EXP msg
+ */
+
+#define VFE_CMD_STATS_WB_EXP_ACK 0x0016
+#define VFE_CMD_STATS_WB_EXP_ACK_LEN sizeof(vfe_cmd_stats_wb_exp_ack)
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int wb_exp_stats_op_buf;
+} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack;
+
+
+/*
+ * Command to acknowledge MSG_VFE_EPOCH1 message
+ */
+
+#define VFE_CMD_EPOCH1_ACK 0x0017
+#define VFE_CMD_EPOCH1_ACK_LEN sizeof(vfe_cmd_epoch1_ack)
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) vfe_cmd_epoch1_ack;
+
+
+/*
+ * Command to acknowledge MSG_VFE_EPOCH2 message
+ */
+
+#define VFE_CMD_EPOCH2_ACK 0x0018
+#define VFE_CMD_EPOCH2_ACK_LEN sizeof(vfe_cmd_epoch2_ack)
+
+typedef struct {
+ unsigned short cmd_id;
+} __attribute__((packed)) vfe_cmd_epoch2_ack;
+
+
+
+/*
+ * Command to configure, enable or disable synchronous timer1
+ */
+
+#define VFE_CMD_SYNC_TIMER1_CFG 0x0019
+#define VFE_CMD_SYNC_TIMER1_CFG_LEN \
+ sizeof(vfe_cmd_sync_timer1_cfg)
+
+#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS 0x0000
+#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA 0x0001
+#define VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH 0x0000
+#define VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW 0x0002
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int sync_t1_cfg_part1;
+ unsigned int sync_t1_h_sync_countdown;
+ unsigned int sync_t1_pclk_countdown;
+ unsigned int sync_t1_duration;
+} __attribute__((packed)) vfe_cmd_sync_timer1_cfg;
+
+
+/*
+ * Command to configure, enable or disable synchronous timer1
+ */
+
+#define VFE_CMD_SYNC_TIMER2_CFG 0x001A
+#define VFE_CMD_SYNC_TIMER2_CFG_LEN \
+ sizeof(vfe_cmd_sync_timer2_cfg)
+
+#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS 0x0000
+#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA 0x0001
+#define VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH 0x0000
+#define VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW 0x0002
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int sync_t2_cfg_part1;
+ unsigned int sync_t2_h_sync_countdown;
+ unsigned int sync_t2_pclk_countdown;
+ unsigned int sync_t2_duration;
+} __attribute__((packed)) vfe_cmd_sync_timer2_cfg;
+
+
+/*
+ * Command to configure and start asynchronous timer1
+ */
+
+#define VFE_CMD_ASYNC_TIMER1_START 0x001B
+#define VFE_CMD_ASYNC_TIMER1_START_LEN \
+ sizeof(vfe_cmd_async_timer1_start)
+
+#define VFE_CMD_ASYNC_T1_POLARITY_A_HIGH 0x0000
+#define VFE_CMD_ASYNC_T1_POLARITY_A_LOW 0x0001
+#define VFE_CMD_ASYNC_T1_POLARITY_B_HIGH 0x0000
+#define VFE_CMD_ASYNC_T1_POLARITY_B_LOW 0x0002
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int async_t1a_cfg;
+ unsigned int async_t1b_cfg;
+ unsigned int async_t1_polarity;
+} __attribute__((packed)) vfe_cmd_async_timer1_start;
+
+
+/*
+ * Command to configure and start asynchronous timer2
+ */
+
+#define VFE_CMD_ASYNC_TIMER2_START 0x001C
+#define VFE_CMD_ASYNC_TIMER2_START_LEN \
+ sizeof(vfe_cmd_async_timer2_start)
+
+#define VFE_CMD_ASYNC_T2_POLARITY_A_HIGH 0x0000
+#define VFE_CMD_ASYNC_T2_POLARITY_A_LOW 0x0001
+#define VFE_CMD_ASYNC_T2_POLARITY_B_HIGH 0x0000
+#define VFE_CMD_ASYNC_T2_POLARITY_B_LOW 0x0002
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int async_t2a_cfg;
+ unsigned int async_t2b_cfg;
+ unsigned int async_t2_polarity;
+} __attribute__((packed)) vfe_cmd_async_timer2_start;
+
+
+/*
+ * Command to program partial configurations of auto focus(af)
+ */
+
+#define VFE_CMD_STATS_AF_UPDATE 0x001D
+#define VFE_CMD_STATS_AF_UPDATE_LEN \
+ sizeof(vfe_cmd_stats_af_update)
+
+#define VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE 0x00000000
+#define VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI 0x80000000
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int af_update_part1;
+ unsigned int af_update_part2;
+} __attribute__((packed)) vfe_cmd_stats_af_update;
+
+
+/*
+ * Command to program partial cfg of wb and exp
+ */
+
+#define VFE_CMD_STATS_WB_EXP_UPDATE 0x001E
+#define VFE_CMD_STATS_WB_EXP_UPDATE_LEN \
+ sizeof(vfe_cmd_stats_wb_exp_update)
+
+#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8 0x0000
+#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16 0x0001
+#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8 0x0000
+#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4 0x0002
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int wb_exp_update_part1;
+ unsigned int wb_exp_update_part2;
+ unsigned int wb_exp_update_part3;
+ unsigned int wb_exp_update_part4;
+} __attribute__((packed)) vfe_cmd_stats_wb_exp_update;
+
+
+
+/*
+ * Command to re program the CAMIF FRAME CONFIG settings
+ */
+
+#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG 0x001F
+#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN \
+ sizeof(vfe_cmd_update_camif_frame_cfg)
+
+typedef struct {
+ unsigned int cmd_id;
+ unsigned int camif_frame_cfg;
+} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg;
+
+
+#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h
new file mode 100644
index 00000000000..0053cfb65ba
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h
@@ -0,0 +1,290 @@
+#ifndef QDSP5VFEMSGI_H
+#define QDSP5VFEMSGI_H
+
+/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+
+ V F E I N T E R N A L M E S S A G E S
+
+GENERAL DESCRIPTION
+ This file contains defintions of format blocks of commands
+ that are sent by VFE Task
+
+REFERENCES
+ None
+
+EXTERNALIZED FUNCTIONS
+ None
+
+Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
+
+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.
+
+*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+This section contains comments describing changes made to this file.
+Notice that changes are listed in reverse chronological order.
+
+$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
+Revision History:
+
+when who what, where, why
+-------- --- ----------------------------------------------------------
+06/12/08 sv initial version
+===========================================================================*/
+
+
+/*
+ * Message to acknowledge CMD_VFE_REST command
+ */
+
+#define VFE_MSG_RESET_ACK 0x0000
+#define VFE_MSG_RESET_ACK_LEN sizeof(vfe_msg_reset_ack)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_reset_ack;
+
+
+/*
+ * Message to acknowledge CMD_VFE_START command
+ */
+
+#define VFE_MSG_START_ACK 0x0001
+#define VFE_MSG_START_ACK_LEN sizeof(vfe_msg_start_ack)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_start_ack;
+
+/*
+ * Message to acknowledge CMD_VFE_STOP command
+ */
+
+#define VFE_MSG_STOP_ACK 0x0002
+#define VFE_MSG_STOP_ACK_LEN sizeof(vfe_msg_stop_ack)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_stop_ack;
+
+
+/*
+ * Message to acknowledge CMD_VFE_UPDATE command
+ */
+
+#define VFE_MSG_UPDATE_ACK 0x0003
+#define VFE_MSG_UPDATE_ACK_LEN sizeof(vfe_msg_update_ack)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_update_ack;
+
+
+/*
+ * Message to notify the ARM that snapshot processing is complete
+ * and that the VFE is now STATE_VFE_IDLE
+ */
+
+#define VFE_MSG_SNAPSHOT_DONE 0x0004
+#define VFE_MSG_SNAPSHOT_DONE_LEN \
+ sizeof(vfe_msg_snapshot_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_snapshot_done;
+
+
+
+/*
+ * Message to notify ARM that illegal cmd was received and
+ * system is in the IDLE state
+ */
+
+#define VFE_MSG_ILLEGAL_CMD 0x0005
+#define VFE_MSG_ILLEGAL_CMD_LEN \
+ sizeof(vfe_msg_illegal_cmd)
+
+typedef struct {
+ unsigned int status;
+} __attribute__((packed)) vfe_msg_illegal_cmd;
+
+
+/*
+ * Message to notify ARM that op1 buf is full and ready
+ */
+
+#define VFE_MSG_OP1 0x0006
+#define VFE_MSG_OP1_LEN sizeof(vfe_msg_op1)
+
+typedef struct {
+ unsigned int op1_buf_y_addr;
+ unsigned int op1_buf_cbcr_addr;
+ unsigned int black_level_even_col;
+ unsigned int black_level_odd_col;
+ unsigned int defect_pixels_detected;
+ unsigned int asf_max_edge;
+} __attribute__((packed)) vfe_msg_op1;
+
+
+/*
+ * Message to notify ARM that op2 buf is full and ready
+ */
+
+#define VFE_MSG_OP2 0x0007
+#define VFE_MSG_OP2_LEN sizeof(vfe_msg_op2)
+
+typedef struct {
+ unsigned int op2_buf_y_addr;
+ unsigned int op2_buf_cbcr_addr;
+ unsigned int black_level_even_col;
+ unsigned int black_level_odd_col;
+ unsigned int defect_pixels_detected;
+ unsigned int asf_max_edge;
+} __attribute__((packed)) vfe_msg_op2;
+
+
+/*
+ * Message to notify ARM that autofocus(af) stats are ready
+ */
+
+#define VFE_MSG_STATS_AF 0x0008
+#define VFE_MSG_STATS_AF_LEN sizeof(vfe_msg_stats_af)
+
+typedef struct {
+ unsigned int af_stats_op_buffer;
+} __attribute__((packed)) vfe_msg_stats_af;
+
+
+/*
+ * Message to notify ARM that white balance(wb) and exposure (exp)
+ * stats are ready
+ */
+
+#define VFE_MSG_STATS_WB_EXP 0x0009
+#define VFE_MSG_STATS_WB_EXP_LEN \
+ sizeof(vfe_msg_stats_wb_exp)
+
+typedef struct {
+ unsigned int wb_exp_stats_op_buf;
+} __attribute__((packed)) vfe_msg_stats_wb_exp;
+
+
+/*
+ * Message to notify the ARM that histogram(hg) stats are ready
+ */
+
+#define VFE_MSG_STATS_HG 0x000A
+#define VFE_MSG_STATS_HG_LEN sizeof(vfe_msg_stats_hg)
+
+typedef struct {
+ unsigned int hg_stats_op_buf;
+} __attribute__((packed)) vfe_msg_stats_hg;
+
+
+/*
+ * Message to notify the ARM that epoch1 event occurred in the CAMIF
+ */
+
+#define VFE_MSG_EPOCH1 0x000B
+#define VFE_MSG_EPOCH1_LEN sizeof(vfe_msg_epoch1)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_epoch1;
+
+
+/*
+ * Message to notify the ARM that epoch2 event occurred in the CAMIF
+ */
+
+#define VFE_MSG_EPOCH2 0x000C
+#define VFE_MSG_EPOCH2_LEN sizeof(vfe_msg_epoch2)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_epoch2;
+
+
+/*
+ * Message to notify the ARM that sync timer1 op is completed
+ */
+
+#define VFE_MSG_SYNC_T1_DONE 0x000D
+#define VFE_MSG_SYNC_T1_DONE_LEN sizeof(vfe_msg_sync_t1_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_sync_t1_done;
+
+
+/*
+ * Message to notify the ARM that sync timer2 op is completed
+ */
+
+#define VFE_MSG_SYNC_T2_DONE 0x000E
+#define VFE_MSG_SYNC_T2_DONE_LEN sizeof(vfe_msg_sync_t2_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_sync_t2_done;
+
+
+/*
+ * Message to notify the ARM that async t1 operation completed
+ */
+
+#define VFE_MSG_ASYNC_T1_DONE 0x000F
+#define VFE_MSG_ASYNC_T1_DONE_LEN sizeof(vfe_msg_async_t1_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_async_t1_done;
+
+
+
+/*
+ * Message to notify the ARM that async t2 operation completed
+ */
+
+#define VFE_MSG_ASYNC_T2_DONE 0x0010
+#define VFE_MSG_ASYNC_T2_DONE_LEN sizeof(vfe_msg_async_t2_done)
+
+typedef struct {
+} __attribute__((packed)) vfe_msg_async_t2_done;
+
+
+
+/*
+ * Message to notify the ARM that an error has occurred
+ */
+
+#define VFE_MSG_ERROR 0x0011
+#define VFE_MSG_ERROR_LEN sizeof(vfe_msg_error)
+
+#define VFE_MSG_ERR_COND_NO_CAMIF_ERR 0x0000
+#define VFE_MSG_ERR_COND_CAMIF_ERR 0x0001
+#define VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF 0x0000
+#define VFE_MSG_ERR_COND_OP1_Y_BUS_OF 0x0002
+#define VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF 0x0000
+#define VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF 0x0004
+#define VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF 0x0000
+#define VFE_MSG_ERR_COND_OP2_Y_BUS_OF 0x0008
+#define VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF 0x0000
+#define VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF 0x0010
+#define VFE_MSG_ERR_COND_AF_NO_BUS_OF 0x0000
+#define VFE_MSG_ERR_COND_AF_BUS_OF 0x0020
+#define VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF 0x0000
+#define VFE_MSG_ERR_COND_WB_EXP_BUS_OF 0x0040
+#define VFE_MSG_ERR_COND_NO_AXI_ERR 0x0000
+#define VFE_MSG_ERR_COND_AXI_ERR 0x0080
+
+#define VFE_MSG_CAMIF_STS_IDLE 0x0000
+#define VFE_MSG_CAMIF_STS_CAPTURE_DATA 0x0001
+
+typedef struct {
+ unsigned int err_cond;
+ unsigned int camif_sts;
+} __attribute__((packed)) vfe_msg_error;
+
+
+#endif
diff --git a/drivers/staging/dream/include/media/msm_camera.h b/drivers/staging/dream/include/media/msm_camera.h
new file mode 100644
index 00000000000..09812d62cc1
--- /dev/null
+++ b/drivers/staging/dream/include/media/msm_camera.h
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+#ifndef __LINUX_MSM_CAMERA_H
+#define __LINUX_MSM_CAMERA_H
+
+#include <linux/types.h>
+#include <asm/sizes.h>
+#include <linux/ioctl.h>
+
+#define MSM_CAM_IOCTL_MAGIC 'm'
+
+#define MSM_CAM_IOCTL_GET_SENSOR_INFO \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *)
+
+#define MSM_CAM_IOCTL_REGISTER_PMEM \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *)
+
+#define MSM_CAM_IOCTL_UNREGISTER_PMEM \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned)
+
+#define MSM_CAM_IOCTL_CTRL_COMMAND \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *)
+
+#define MSM_CAM_IOCTL_CONFIG_VFE \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *)
+
+#define MSM_CAM_IOCTL_GET_STATS \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *)
+
+#define MSM_CAM_IOCTL_GETFRAME \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *)
+
+#define MSM_CAM_IOCTL_ENABLE_VFE \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_CTRL_CMD_DONE \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *)
+
+#define MSM_CAM_IOCTL_CONFIG_CMD \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *)
+
+#define MSM_CAM_IOCTL_DISABLE_VFE \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_PAD_REG_RESET2 \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_VFE_APPS_RESET \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *)
+
+#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *)
+
+#define MSM_CAM_IOCTL_AXI_CONFIG \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *)
+
+#define MSM_CAM_IOCTL_GET_PICTURE \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_camera_ctrl_cmd *)
+
+#define MSM_CAM_IOCTL_SET_CROP \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *)
+
+#define MSM_CAM_IOCTL_PICT_PP \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *)
+
+#define MSM_CAM_IOCTL_PICT_PP_DONE \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *)
+
+#define MSM_CAM_IOCTL_SENSOR_IO_CFG \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *)
+
+#define MSM_CAMERA_LED_OFF 0
+#define MSM_CAMERA_LED_LOW 1
+#define MSM_CAMERA_LED_HIGH 2
+
+#define MSM_CAM_IOCTL_FLASH_LED_CFG \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *)
+
+#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \
+ _IO(MSM_CAM_IOCTL_MAGIC, 23)
+
+#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *)
+
+#define MAX_SENSOR_NUM 3
+#define MAX_SENSOR_NAME 32
+
+#define MSM_CAM_CTRL_CMD_DONE 0
+#define MSM_CAM_SENSOR_VFE_CMD 1
+
+/*****************************************************
+ * structure
+ *****************************************************/
+
+/* define five type of structures for userspace <==> kernel
+ * space communication:
+ * command 1 - 2 are from userspace ==> kernel
+ * command 3 - 4 are from kernel ==> userspace
+ *
+ * 1. control command: control command(from control thread),
+ * control status (from config thread);
+ */
+struct msm_ctrl_cmd {
+ uint16_t type;
+ uint16_t length;
+ void *value;
+ uint16_t status;
+ uint32_t timeout_ms;
+ int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */
+};
+
+struct msm_vfe_evt_msg {
+ unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */
+ unsigned short msg_id;
+ unsigned int len; /* size in, number of bytes out */
+ void *data;
+};
+
+#define MSM_CAM_RESP_CTRL 0
+#define MSM_CAM_RESP_STAT_EVT_MSG 1
+#define MSM_CAM_RESP_V4L2 2
+#define MSM_CAM_RESP_MAX 3
+
+/* this one is used to send ctrl/status up to config thread */
+struct msm_stats_event_ctrl {
+ /* 0 - ctrl_cmd from control thread,
+ * 1 - stats/event kernel,
+ * 2 - V4L control or read request */
+ int resptype;
+ int timeout_ms;
+ struct msm_ctrl_cmd ctrl_cmd;
+ /* struct vfe_event_t stats_event; */
+ struct msm_vfe_evt_msg stats_event;
+};
+
+/* 2. config command: config command(from config thread); */
+struct msm_camera_cfg_cmd {
+ /* what to config:
+ * 1 - sensor config, 2 - vfe config */
+ uint16_t cfg_type;
+
+ /* sensor config type */
+ uint16_t cmd_type;
+ uint16_t queue;
+ uint16_t length;
+ void *value;
+};
+
+#define CMD_GENERAL 0
+#define CMD_AXI_CFG_OUT1 1
+#define CMD_AXI_CFG_SNAP_O1_AND_O2 2
+#define CMD_AXI_CFG_OUT2 3
+#define CMD_PICT_T_AXI_CFG 4
+#define CMD_PICT_M_AXI_CFG 5
+#define CMD_RAW_PICT_AXI_CFG 6
+#define CMD_STATS_AXI_CFG 7
+#define CMD_STATS_AF_AXI_CFG 8
+#define CMD_FRAME_BUF_RELEASE 9
+#define CMD_PREV_BUF_CFG 10
+#define CMD_SNAP_BUF_RELEASE 11
+#define CMD_SNAP_BUF_CFG 12
+#define CMD_STATS_DISABLE 13
+#define CMD_STATS_ENABLE 14
+#define CMD_STATS_AF_ENABLE 15
+#define CMD_STATS_BUF_RELEASE 16
+#define CMD_STATS_AF_BUF_RELEASE 17
+#define UPDATE_STATS_INVALID 18
+
+/* vfe config command: config command(from config thread)*/
+struct msm_vfe_cfg_cmd {
+ int cmd_type;
+ uint16_t length;
+ void *value;
+};
+
+#define MAX_CAMERA_ENABLE_NAME_LEN 32
+struct camera_enable_cmd {
+ char name[MAX_CAMERA_ENABLE_NAME_LEN];
+};
+
+#define MSM_PMEM_OUTPUT1 0
+#define MSM_PMEM_OUTPUT2 1
+#define MSM_PMEM_OUTPUT1_OUTPUT2 2
+#define MSM_PMEM_THUMBAIL 3
+#define MSM_PMEM_MAINIMG 4
+#define MSM_PMEM_RAW_MAINIMG 5
+#define MSM_PMEM_AEC_AWB 6
+#define MSM_PMEM_AF 7
+#define MSM_PMEM_MAX 8
+
+#define FRAME_PREVIEW_OUTPUT1 0
+#define FRAME_PREVIEW_OUTPUT2 1
+#define FRAME_SNAPSHOT 2
+#define FRAME_THUMBAIL 3
+#define FRAME_RAW_SNAPSHOT 4
+#define FRAME_MAX 5
+
+struct msm_pmem_info {
+ int type;
+ int fd;
+ void *vaddr;
+ uint32_t y_off;
+ uint32_t cbcr_off;
+ uint8_t active;
+};
+
+struct outputCfg {
+ uint32_t height;
+ uint32_t width;
+
+ uint32_t window_height_firstline;
+ uint32_t window_height_lastline;
+};
+
+#define OUTPUT_1 0
+#define OUTPUT_2 1
+#define OUTPUT_1_AND_2 2
+#define CAMIF_TO_AXI_VIA_OUTPUT_2 3
+#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 4
+#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 5
+#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
+
+#define MSM_FRAME_PREV_1 0
+#define MSM_FRAME_PREV_2 1
+#define MSM_FRAME_ENC 2
+
+struct msm_frame {
+ int path;
+ unsigned long buffer;
+ uint32_t y_off;
+ uint32_t cbcr_off;
+ int fd;
+
+ void *cropinfo;
+ int croplen;
+};
+
+#define STAT_AEAW 0
+#define STAT_AF 1
+#define STAT_MAX 2
+
+struct msm_stats_buf {
+ int type;
+ unsigned long buffer;
+ int fd;
+};
+
+#define MSM_V4L2_VID_CAP_TYPE 0
+#define MSM_V4L2_STREAM_ON 1
+#define MSM_V4L2_STREAM_OFF 2
+#define MSM_V4L2_SNAPSHOT 3
+#define MSM_V4L2_QUERY_CTRL 4
+#define MSM_V4L2_GET_CTRL 5
+#define MSM_V4L2_SET_CTRL 6
+#define MSM_V4L2_QUERY 7
+#define MSM_V4L2_MAX 8
+
+struct crop_info {
+ void *info;
+ int len;
+};
+
+struct msm_postproc {
+ int ftnum;
+ struct msm_frame fthumnail;
+ int fmnum;
+ struct msm_frame fmain;
+};
+
+struct msm_snapshot_pp_status {
+ void *status;
+};
+
+#define CFG_SET_MODE 0
+#define CFG_SET_EFFECT 1
+#define CFG_START 2
+#define CFG_PWR_UP 3
+#define CFG_PWR_DOWN 4
+#define CFG_WRITE_EXPOSURE_GAIN 5
+#define CFG_SET_DEFAULT_FOCUS 6
+#define CFG_MOVE_FOCUS 7
+#define CFG_REGISTER_TO_REAL_GAIN 8
+#define CFG_REAL_TO_REGISTER_GAIN 9
+#define CFG_SET_FPS 10
+#define CFG_SET_PICT_FPS 11
+#define CFG_SET_BRIGHTNESS 12
+#define CFG_SET_CONTRAST 13
+#define CFG_SET_ZOOM 14
+#define CFG_SET_EXPOSURE_MODE 15
+#define CFG_SET_WB 16
+#define CFG_SET_ANTIBANDING 17
+#define CFG_SET_EXP_GAIN 18
+#define CFG_SET_PICT_EXP_GAIN 19
+#define CFG_SET_LENS_SHADING 20
+#define CFG_GET_PICT_FPS 21
+#define CFG_GET_PREV_L_PF 22
+#define CFG_GET_PREV_P_PL 23
+#define CFG_GET_PICT_L_PF 24
+#define CFG_GET_PICT_P_PL 25
+#define CFG_GET_AF_MAX_STEPS 26
+#define CFG_GET_PICT_MAX_EXP_LC 27
+#define CFG_MAX 28
+
+#define MOVE_NEAR 0
+#define MOVE_FAR 1
+
+#define SENSOR_PREVIEW_MODE 0
+#define SENSOR_SNAPSHOT_MODE 1
+#define SENSOR_RAW_SNAPSHOT_MODE 2
+
+#define SENSOR_QTR_SIZE 0
+#define SENSOR_FULL_SIZE 1
+#define SENSOR_INVALID_SIZE 2
+
+#define CAMERA_EFFECT_OFF 0
+#define CAMERA_EFFECT_MONO 1
+#define CAMERA_EFFECT_NEGATIVE 2
+#define CAMERA_EFFECT_SOLARIZE 3
+#define CAMERA_EFFECT_PASTEL 4
+#define CAMERA_EFFECT_MOSAIC 5
+#define CAMERA_EFFECT_RESIZE 6
+#define CAMERA_EFFECT_SEPIA 7
+#define CAMERA_EFFECT_POSTERIZE 8
+#define CAMERA_EFFECT_WHITEBOARD 9
+#define CAMERA_EFFECT_BLACKBOARD 10
+#define CAMERA_EFFECT_AQUA 11
+#define CAMERA_EFFECT_MAX 12
+
+struct sensor_pict_fps {
+ uint16_t prevfps;
+ uint16_t pictfps;
+};
+
+struct exp_gain_cfg {
+ uint16_t gain;
+ uint32_t line;
+};
+
+struct focus_cfg {
+ int32_t steps;
+ int dir;
+};
+
+struct fps_cfg {
+ uint16_t f_mult;
+ uint16_t fps_div;
+ uint32_t pict_fps_div;
+};
+
+struct sensor_cfg_data {
+ int cfgtype;
+ int mode;
+ int rs;
+ uint8_t max_steps;
+
+ union {
+ int8_t effect;
+ uint8_t lens_shading;
+ uint16_t prevl_pf;
+ uint16_t prevp_pl;
+ uint16_t pictl_pf;
+ uint16_t pictp_pl;
+ uint32_t pict_max_exp_lc;
+ uint16_t p_fps;
+ struct sensor_pict_fps gfps;
+ struct exp_gain_cfg exp_gain;
+ struct focus_cfg focus;
+ struct fps_cfg fps;
+ } cfg;
+};
+
+#define GET_NAME 0
+#define GET_PREVIEW_LINE_PER_FRAME 1
+#define GET_PREVIEW_PIXELS_PER_LINE 2
+#define GET_SNAPSHOT_LINE_PER_FRAME 3
+#define GET_SNAPSHOT_PIXELS_PER_LINE 4
+#define GET_SNAPSHOT_FPS 5
+#define GET_SNAPSHOT_MAX_EP_LINE_CNT 6
+
+struct msm_camsensor_info {
+ char name[MAX_SENSOR_NAME];
+ uint8_t flash_enabled;
+};
+#endif /* __LINUX_MSM_CAMERA_H */
diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c
index def64681234..6edfdd4ef80 100644
--- a/drivers/staging/dream/pmem.c
+++ b/drivers/staging/dream/pmem.c
@@ -23,6 +23,7 @@
#include <linux/android_pmem.h>
#include <linux/mempolicy.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
@@ -37,17 +38,17 @@
* the file should not be released until put_pmem_file is called */
#define PMEM_FLAGS_BUSY 0x1
/* indicates that this is a suballocation of a larger master range */
-#define PMEM_FLAGS_CONNECTED 0x1 << 1
+#define PMEM_FLAGS_CONNECTED ( 0x1 << 1 )
/* indicates this is a master and not a sub allocation and that it is mmaped */
-#define PMEM_FLAGS_MASTERMAP 0x1 << 2
+#define PMEM_FLAGS_MASTERMAP ( 0x1 << 2 )
/* submap and unsubmap flags indicate:
* 00: subregion has never been mmaped
* 10: subregion has been mmaped, reference to the mm was taken
* 11: subretion has ben released, refernece to the mm still held
* 01: subretion has been released, reference to the mm has been released
*/
-#define PMEM_FLAGS_SUBMAP 0x1 << 3
-#define PMEM_FLAGS_UNSUBMAP 0x1 << 4
+#define PMEM_FLAGS_SUBMAP ( 0x1 << 3 )
+#define PMEM_FLAGS_UNSUBMAP ( 0x1 << 4 )
struct pmem_data {
@@ -91,7 +92,7 @@ struct pmem_region_node {
#define PMEM_DEBUG_MSGS 0
#if PMEM_DEBUG_MSGS
-#define DLOG(fmt,args...) \
+#define DLOG(fmt, args...) \
do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
##args); } \
while (0)
@@ -152,7 +153,7 @@ struct pmem_info {
static struct pmem_info pmem[PMEM_MAX_DEVICES];
static int id_count;
-#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated)
+#define PMEM_IS_FREE(id, index) ( !(pmem[id].bitmap[index].allocated) )
#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
@@ -708,9 +709,8 @@ int get_pmem_addr(struct file *file, unsigned long *start,
struct pmem_data *data;
int id;
- if (!is_pmem_file(file) || !has_allocation(file)) {
+ if (!is_pmem_file(file) || !has_allocation(file))
return -1;
- }
data = (struct pmem_data *)file->private_data;
if (data->index == -1) {
@@ -789,9 +789,8 @@ void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
struct list_head *elt;
void *flush_start, *flush_end;
- if (!is_pmem_file(file) || !has_allocation(file)) {
+ if (!is_pmem_file(file) || !has_allocation(file))
return;
- }
id = get_id(file);
data = (struct pmem_data *)file->private_data;
@@ -833,7 +832,7 @@ static int pmem_connect(unsigned long connect, struct file *file)
src_file = fget_light(connect, &put_needed);
DLOG("connect %p to %p\n", file, src_file);
if (!src_file) {
- printk("pmem: src file not found!\n");
+ printk(KERN_INFO "pmem: src file not found!\n");
ret = -EINVAL;
goto err_no_file;
}
@@ -846,7 +845,7 @@ static int pmem_connect(unsigned long connect, struct file *file)
src_data = (struct pmem_data *)src_file->private_data;
if (has_allocation(file) && (data->index != src_data->index)) {
- printk("pmem: file is already mapped but doesn't match this"
+ printk(KERN_INFO "pmem: file is already mapped but doesn't match this"
" src_file!\n");
ret = -EINVAL;
goto err_bad_file;
@@ -885,7 +884,7 @@ lock_mm:
mm = get_task_mm(data->task);
if (!mm) {
#if PMEM_DEBUG
- printk("pmem: can't remap task is gone!\n");
+ printk(KERN_DEBUG "pmem: can't remap task is gone!\n");
#endif
up_read(&data->sem);
return -1;
@@ -936,7 +935,7 @@ int pmem_remap(struct pmem_region *region, struct file *file,
if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
!PMEM_IS_PAGE_ALIGNED(region->len))) {
#if PMEM_DEBUG
- printk("pmem: request for unaligned pmem suballocation "
+ printk(KERN_DEBUG "pmem: request for unaligned pmem suballocation "
"%lx %lx\n", region->offset, region->len);
#endif
return -EINVAL;
diff --git a/drivers/staging/dream/qdsp5/Makefile b/drivers/staging/dream/qdsp5/Makefile
index 991d4a7e157..beedaaff5cc 100644
--- a/drivers/staging/dream/qdsp5/Makefile
+++ b/drivers/staging/dream/qdsp5/Makefile
@@ -1,3 +1,4 @@
+EXTRA_CFLAGS=-Idrivers/staging/dream/include
obj-y += adsp.o
ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y)
obj-y += adsp_info.o
diff --git a/drivers/staging/dream/qdsp5/adsp.c b/drivers/staging/dream/qdsp5/adsp.c
index 9069535fcaf..f1e9d81674e 100644
--- a/drivers/staging/dream/qdsp5/adsp.c
+++ b/drivers/staging/dream/qdsp5/adsp.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
diff --git a/drivers/staging/dream/qdsp5/adsp_driver.c b/drivers/staging/dream/qdsp5/adsp_driver.c
index e55a0db53a9..8197765aae1 100644
--- a/drivers/staging/dream/qdsp5/adsp_driver.c
+++ b/drivers/staging/dream/qdsp5/adsp_driver.c
@@ -19,6 +19,7 @@
#include <linux/list.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include "adsp.h"
diff --git a/drivers/staging/dream/qdsp5/audio_aac.c b/drivers/staging/dream/qdsp5/audio_aac.c
index ad2390f32a4..a373f352238 100644
--- a/drivers/staging/dream/qdsp5/audio_aac.c
+++ b/drivers/staging/dream/qdsp5/audio_aac.c
@@ -24,6 +24,7 @@
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
diff --git a/drivers/staging/dream/qdsp5/audio_amrnb.c b/drivers/staging/dream/qdsp5/audio_amrnb.c
index cd818a526f8..07b79d5836e 100644
--- a/drivers/staging/dream/qdsp5/audio_amrnb.c
+++ b/drivers/staging/dream/qdsp5/audio_amrnb.c
@@ -32,6 +32,7 @@
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
diff --git a/drivers/staging/dream/qdsp5/audio_evrc.c b/drivers/staging/dream/qdsp5/audio_evrc.c
index 4b43e183f9e..ad989ee8769 100644
--- a/drivers/staging/dream/qdsp5/audio_evrc.c
+++ b/drivers/staging/dream/qdsp5/audio_evrc.c
@@ -27,6 +27,7 @@
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <asm/atomic.h>
#include <asm/ioctls.h>
diff --git a/drivers/staging/dream/qdsp5/audio_in.c b/drivers/staging/dream/qdsp5/audio_in.c
index 3d950a24589..6ae48e72d14 100644
--- a/drivers/staging/dream/qdsp5/audio_in.c
+++ b/drivers/staging/dream/qdsp5/audio_in.c
@@ -23,6 +23,7 @@
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
diff --git a/drivers/staging/dream/qdsp5/audio_mp3.c b/drivers/staging/dream/qdsp5/audio_mp3.c
index b95574f699f..530e1f35eed 100644
--- a/drivers/staging/dream/qdsp5/audio_mp3.c
+++ b/drivers/staging/dream/qdsp5/audio_mp3.c
@@ -23,6 +23,7 @@
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <linux/delay.h>
@@ -650,8 +651,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
&audio->read_phys,
GFP_KERNEL);
if (!audio->read_data) {
- pr_err("audio_mp3: malloc pcm \
- buf failed\n");
+ pr_err("audio_mp3: malloc pcm buf failed\n");
rc = -1;
} else {
uint8_t index;
diff --git a/drivers/staging/dream/qdsp5/audio_out.c b/drivers/staging/dream/qdsp5/audio_out.c
index df87ca337b9..fe7809dd440 100644
--- a/drivers/staging/dream/qdsp5/audio_out.c
+++ b/drivers/staging/dream/qdsp5/audio_out.c
@@ -26,6 +26,7 @@
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/wakelock.h>
+#include <linux/gfp.h>
#include <linux/msm_audio.h>
diff --git a/drivers/staging/dream/qdsp5/audio_qcelp.c b/drivers/staging/dream/qdsp5/audio_qcelp.c
index f0f50e36805..effa96f34fd 100644
--- a/drivers/staging/dream/qdsp5/audio_qcelp.c
+++ b/drivers/staging/dream/qdsp5/audio_qcelp.c
@@ -29,6 +29,7 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <asm/ioctls.h>
#include <mach/msm_adsp.h>
diff --git a/drivers/staging/dream/qdsp5/audmgr.c b/drivers/staging/dream/qdsp5/audmgr.c
index 1ad8b82c257..427ae6c0bea 100644
--- a/drivers/staging/dream/qdsp5/audmgr.c
+++ b/drivers/staging/dream/qdsp5/audmgr.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/wait.h>
diff --git a/drivers/staging/dream/smd/Makefile b/drivers/staging/dream/smd/Makefile
index 892c7414bbe..1c87618366a 100644
--- a/drivers/staging/dream/smd/Makefile
+++ b/drivers/staging/dream/smd/Makefile
@@ -1,3 +1,4 @@
+EXTRA_CFLAGS=-Idrivers/staging/dream/include
obj-$(CONFIG_MSM_SMD) += smd.o smd_tty.o smd_qmi.o
obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter.o
obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o
diff --git a/drivers/staging/dream/smd/smd_rpcrouter.c b/drivers/staging/dream/smd/smd_rpcrouter.c
index 5ac2cd4a597..8744a6e499c 100644
--- a/drivers/staging/dream/smd/smd_rpcrouter.c
+++ b/drivers/staging/dream/smd/smd_rpcrouter.c
@@ -33,13 +33,12 @@
#include <linux/err.h>
#include <linux/sched.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
-#include <asm/byteorder.h>
-
#include <mach/msm_smd.h>
#include "smd_rpcrouter.h"
diff --git a/drivers/staging/dream/smd/smd_rpcrouter_device.c b/drivers/staging/dream/smd/smd_rpcrouter_device.c
index cd3910bcc4e..e9c28eddce3 100644
--- a/drivers/staging/dream/smd/smd_rpcrouter_device.c
+++ b/drivers/staging/dream/smd/smd_rpcrouter_device.c
@@ -29,6 +29,7 @@
#include <linux/poll.h>
#include <linux/platform_device.h>
#include <linux/msm_rpcrouter.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
diff --git a/drivers/staging/dream/smd/smd_rpcrouter_servers.c b/drivers/staging/dream/smd/smd_rpcrouter_servers.c
index 2597bbbc6f5..1b152abb278 100644
--- a/drivers/staging/dream/smd/smd_rpcrouter_servers.c
+++ b/drivers/staging/dream/smd/smd_rpcrouter_servers.c
@@ -27,6 +27,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/wakelock.h>
+#include <linux/slab.h>
#include <linux/msm_rpcrouter.h>
#include <linux/uaccess.h>
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c
index 4de6bc91759..d2ca116a1c2 100644
--- a/drivers/staging/dream/synaptics_i2c_rmi.c
+++ b/drivers/staging/dream/synaptics_i2c_rmi.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
diff --git a/drivers/staging/dt3155/Kconfig b/drivers/staging/dt3155/Kconfig
new file mode 100644
index 00000000000..4a3293c721b
--- /dev/null
+++ b/drivers/staging/dt3155/Kconfig
@@ -0,0 +1,4 @@
+config DT3155
+ tristate "DT3155 Digitizer support"
+ depends on PCI
+
diff --git a/drivers/staging/dt3155/Makefile b/drivers/staging/dt3155/Makefile
new file mode 100644
index 00000000000..136f21fdbbe
--- /dev/null
+++ b/drivers/staging/dt3155/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_DT3155) += dt3155.o
+dt3155-objs := \
+ dt3155_drv.o \
+ dt3155_isr.o \
+ dt3155_io.o \
+ allocator.o
diff --git a/drivers/staging/dt3155/TODO b/drivers/staging/dt3155/TODO
new file mode 100644
index 00000000000..3baa3b6294c
--- /dev/null
+++ b/drivers/staging/dt3155/TODO
@@ -0,0 +1,10 @@
+TODO:
+ - fix checkpatch.pl issues
+ - remove old kernel support, it is not needed
+ - convert to proper PCI device API
+ - fix sparse warnings
+ - audit for correct subsystem interaction
+ - review review review!
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com>
+and Scott Smedley <ss@aao.gov.au>
diff --git a/drivers/staging/dt3155/allocator.README b/drivers/staging/dt3155/allocator.README
new file mode 100644
index 00000000000..05700b6c926
--- /dev/null
+++ b/drivers/staging/dt3155/allocator.README
@@ -0,0 +1,98 @@
+
+The allocator shown here exploits high memory. This document explains
+how a user can deal with drivers uses this allocator and how a
+programmer can link in the module.
+
+The module is being used by my pxc and pxdrv device drivers (as well as
+other ones), available from ftp.systemy.it/pub/develop and
+ftp.linux.it/pub/People/Rubini
+
+ User's manual
+ =============
+
+
+One of the most compelling problems with any DMA-capable device is the
+allocation of a suitable memory buffer. The "allocator" module tries
+to deal with the problem in a clean way. The module is able to use
+high memory (above the one used in normal operation) for DMA
+allocation.
+
+To prevent the kernel for using high memory, so that it remains
+available for DMA, you should pass a command line argument to the
+kernel. Command line arguments can be passed to Lilo, to Loadlin or
+to whichever loader you are using (unless it's very poor in design).
+For Lilo, either use "append=" in /etc/lilo.conf or add commandline
+arguments to the interactive prompt. For example, I have a 32MB box
+and reserve two megs for DMA:
+
+In lilo.conf:
+ image = /zImage
+ label = linux
+ append = "mem=30M"
+
+Or, interactively:
+ LILO: linux mem=30M
+
+Once the kernel is booted with the right command-line argument, any
+driver linked with the allocator module will be able to get
+DMA-capable memory without much trouble (unless the various drivers
+need more memory than available).
+
+The module implements an alloc/free mechanism, so that it can serve
+multiple drivers at the same time. Note however that the allocator
+uses all of high memory and assumes to be the only piece of software
+using such memory.
+
+
+ Programmer's manual
+ ===================
+
+The allocator, as released, is designed to be linked to a device
+driver. In this case, the driver must call allocator_init() before
+using the allocator and must call allocator_cleanup() before
+unloading. This is usually done from within init_module() and
+cleanup_module(). If the allocator is linked to a driver, it won't be
+possible for several drivers to allocate high DMA memory, as explained
+above.
+
+It is possible, on the other hand, to compile the module as a standalone
+module, so that several modules can rely on the allocator for they DMA
+buffers. To compile the allocator as a standalone module, do the
+following in this directory (or provide a suitable Makefile, or edit
+the source code):
+
+ make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h"
+
+The previous commandline tells to include <linux/module.h> in the
+first place, and to rename the init and cleanup function to the ones
+needed for module loading and unloading. Drivers using a standalone
+allocator won't need to call allocator_init() nor allocator_cleanup().
+
+The allocator exports the following functions (declared in allocator.h):
+
+ unsigned long allocator_allocate_dma (unsigned long kilobytes,
+ int priority);
+
+ This function returns a physical address, over high_memory,
+ which corresponds to an area of at least "kilobytes" kilobytes.
+ The area will be owned by the module calling the function.
+ The returned address can be passed to device boards, to instruct
+ their DMA controllers, via phys_to_bus(). The address can be used
+ by C code after vremap()/ioremap(). The "priority" argument should
+ be GFP_KERNEL or GFP_ATOMIC, according to the context of the
+ caller; it is used to call kmalloc(), as the allocator must keep
+ track of any region it gives away. In case of error the function
+ returns 0, and the caller is expected to issue a -ENOMEM error.
+
+
+ void allocator_free_dma (unsigned long address);
+
+ This function is the reverse of the previous one. If a driver
+ doesn't free the DMA memory it allocated, the allocator will
+ consider such memory as busy. Note, however, that
+ allocator_cleanup() calls kfree() on every region it reclaimed,
+ so that a driver with the allocator linked in can avoid calling
+ allocator_free_dma() at unload time.
+
+
+
diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c
new file mode 100644
index 00000000000..db382ef9021
--- /dev/null
+++ b/drivers/staging/dt3155/allocator.c
@@ -0,0 +1,296 @@
+/*
+ * allocator.c -- allocate after high_memory, if available
+ *
+ * NOTE: this is different from my previous allocator, the one that
+ * assembles pages, which revealed itself both slow and unreliable.
+ *
+ * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini)
+ *
+ * This program is free software; 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.
+ *
+
+-- Changes --
+
+ Date Programmer Description of changes made
+ -------------------------------------------------------------------
+ 02-Aug-2002 NJC allocator now steps in 1MB increments, rather
+ than doubling its size each time.
+ Also, allocator_init(u32 *) now returns
+ (in the first arg) the size of the free
+ space. This is no longer consistent with
+ using the allocator as a module, and some changes
+ may be necessary for that purpose. This was
+ designed to work with the DT3155 driver, in
+ stand alone mode only!!!
+ 26-Oct-2009 SS Port to 2.6.30 kernel.
+ */
+
+
+#ifndef __KERNEL__
+# define __KERNEL__
+#endif
+#ifndef MODULE
+# define MODULE
+#endif
+
+#include <linux/version.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mm.h> /* PAGE_ALIGN() */
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <asm/page.h>
+
+/*#define ALL_DEBUG*/
+#define ALL_MSG "allocator: "
+
+#undef PDEBUG /* undef it, just in case */
+#ifdef ALL_DEBUG
+# define __static
+# define DUMP_LIST() dump_list()
+# ifdef __KERNEL__
+ /* This one if debugging is on, and kernel space */
+# define PDEBUG(fmt, args...) printk(KERN_DEBUG ALL_MSG fmt, ## args)
+# else
+ /* This one for user space */
+# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
+# endif
+#else
+# define PDEBUG(fmt, args...) /* not debugging: nothing */
+# define DUMP_LIST()
+# define __static static
+#endif
+
+#undef PDEBUGG
+#define PDEBUGG(fmt, args...)
+/*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/
+
+
+int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable */
+int allocator_step = 1; /* This is the step size in MB */
+int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */
+
+static unsigned long allocator_buffer; /* physical address */
+static unsigned long allocator_buffer_size; /* kilobytes */
+
+/*
+ * The allocator keeps a list of DMA areas, so multiple devices
+ * can coexist. The list is kept sorted by address
+ */
+
+struct allocator_struct {
+ unsigned long address;
+ unsigned long size;
+ struct allocator_struct *next;
+};
+
+struct allocator_struct *allocator_list;
+
+
+#ifdef ALL_DEBUG
+static int dump_list(void)
+{
+ struct allocator_struct *ptr;
+
+ PDEBUG("Current list:\n");
+ for (ptr = allocator_list; ptr; ptr = ptr->next)
+ PDEBUG("0x%08lx (size %likB)\n", ptr->address, ptr->size>>10);
+ return 0;
+}
+#endif
+
+/* ========================================================================
+ * This function is the actual allocator.
+ *
+ * If space is available in high memory (as detected at load time), that
+ * one is returned. The return value is a physical address (i.e., it can
+ * be used straight ahead for DMA, but needs remapping for program use).
+ */
+
+unsigned long allocator_allocate_dma(unsigned long kilobytes, int prio)
+{
+ struct allocator_struct *ptr = allocator_list, *newptr;
+ unsigned long bytes = kilobytes << 10;
+
+ /* check if high memory is available */
+ if (!allocator_buffer)
+ return 0;
+
+ /* Round it to a multiple of the pagesize */
+ bytes = PAGE_ALIGN(bytes);
+ PDEBUG("request for %li bytes\n", bytes);
+
+ while (ptr && ptr->next) {
+ if (ptr->next->address - (ptr->address + ptr->size) >= bytes)
+ break; /* enough space */
+ ptr = ptr->next;
+ }
+ if (!ptr->next) {
+ DUMP_LIST();
+ PDEBUG("alloc failed\n");
+ return 0; /* end of list */
+ }
+ newptr = kmalloc(sizeof(struct allocator_struct), prio);
+ if (!newptr)
+ return 0;
+
+ /* ok, now stick it after ptr */
+ newptr->address = ptr->address + ptr->size;
+ newptr->size = bytes;
+ newptr->next = ptr->next;
+ ptr->next = newptr;
+
+ DUMP_LIST();
+ PDEBUG("returning 0x%08lx\n", newptr->address);
+ return newptr->address;
+}
+
+int allocator_free_dma(unsigned long address)
+{
+ struct allocator_struct *ptr = allocator_list, *prev;
+
+ while (ptr && ptr->next) {
+ if (ptr->next->address == address)
+ break;
+ ptr = ptr->next;
+ }
+ /* the one being freed is ptr->next */
+ prev = ptr; ptr = ptr->next;
+
+ if (!ptr) {
+ printk(KERN_ERR ALL_MSG
+ "free_dma(0x%08lx) but add. not allocated\n",
+ ptr->address);
+ return -EINVAL;
+ }
+ PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size,
+ ptr->next->address);
+ prev->next = ptr->next;
+ kfree(ptr);
+
+ /* dump_list(); */
+ return 0;
+}
+
+/* ========================================================================
+ * Init and cleanup
+ *
+ * On cleanup everything is released. If the list is not empty, that a
+ * problem of our clients
+ */
+int allocator_init(u32 *allocator_max)
+{
+ /* check how much free memory is there */
+ void *remapped;
+ unsigned long max;
+ unsigned long trial_size = allocator_himem<<20;
+ unsigned long last_trial = 0;
+ unsigned long step = allocator_step<<20;
+ unsigned long i = 0;
+ struct allocator_struct *head, *tail;
+ char test_string[] = "0123456789abcde"; /* 16 bytes */
+
+ PDEBUGG("himem = %i\n", allocator_himem);
+ if (allocator_himem < 0) /* don't even try */
+ return -EINVAL;
+
+ if (!trial_size)
+ trial_size = 1<<20; /* not specified: try one meg */
+
+ while (1) {
+ remapped = ioremap(__pa(high_memory), trial_size);
+ if (!remapped) {
+ PDEBUGG("%li megs failed!\n", trial_size>>20);
+ break;
+ }
+ PDEBUGG("Trying %li megs (at %p, %p)\n", trial_size>>20,
+ (void *)__pa(high_memory), remapped);
+ for (i = last_trial; i < trial_size; i += 16) {
+ strcpy((char *)(remapped)+i, test_string);
+ if (strcmp((char *)(remapped)+i, test_string))
+ break;
+ }
+ iounmap((void *)remapped);
+ schedule();
+ last_trial = trial_size;
+ if (i == trial_size)
+ trial_size += step; /* increment, if all went well */
+ else {
+ PDEBUGG("%li megs copy test failed!\n", trial_size>>20);
+ break;
+ }
+ if (!allocator_probe)
+ break;
+ }
+ PDEBUG("%li megs (%li k, %li b)\n", i>>20, i>>10, i);
+ allocator_buffer_size = i>>10; /* kilobytes */
+ allocator_buffer = __pa(high_memory);
+ if (!allocator_buffer_size) {
+ printk(KERN_WARNING ALL_MSG "no free high memory to use\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * to simplify things, always have two cells in the list:
+ * the first and the last. This avoids some conditionals and
+ * extra code when allocating and deallocating: we only play
+ * in the middle of the list
+ */
+ head = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL);
+ if (!head)
+ return -ENOMEM;
+ tail = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL);
+ if (!tail) {
+ kfree(head);
+ return -ENOMEM;
+ }
+
+ max = allocator_buffer_size<<10;
+
+ head->size = tail->size = 0;
+ head->address = allocator_buffer;
+ tail->address = allocator_buffer + max;
+ head->next = tail;
+ tail->next = NULL;
+ allocator_list = head;
+
+ /* Back to the user code, in KB */
+ *allocator_max = allocator_buffer_size;
+
+ return 0; /* ok, ready */
+}
+
+void allocator_cleanup(void)
+{
+ struct allocator_struct *ptr, *next;
+
+ for (ptr = allocator_list; ptr; ptr = next) {
+ next = ptr->next;
+ PDEBUG("freeing list: 0x%08lx\n", ptr->address);
+ kfree(ptr);
+ }
+
+ allocator_buffer = 0;
+ allocator_buffer_size = 0;
+ allocator_list = NULL;
+}
+
+
diff --git a/drivers/staging/dt3155/allocator.h b/drivers/staging/dt3155/allocator.h
new file mode 100644
index 00000000000..bdf3268ca52
--- /dev/null
+++ b/drivers/staging/dt3155/allocator.h
@@ -0,0 +1,28 @@
+/*
+ * allocator.h -- prototypes for allocating high memory
+ *
+ * NOTE: this is different from my previous allocator, the one that
+ * assembles pages, which revealed itself both slow and unreliable.
+ *
+ * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini)
+ *
+ * This program is free software; 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.
+ *
+ */
+
+void allocator_free_dma(unsigned long address);
+unsigned long allocator_allocate_dma(unsigned long kilobytes, int priority);
+int allocator_init(u32 *);
+void allocator_cleanup(void);
diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h
new file mode 100644
index 00000000000..1bf786364ee
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155.h
@@ -0,0 +1,171 @@
+/*
+
+Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+ Jason Lapenta, Scott Smedley
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; 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.
+
+The DT3155 Device Driver is distributed in 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 the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+-- Changes --
+
+ Date Programmer Description of changes made
+ -------------------------------------------------------------------
+ 03-Jul-2000 JML n/a
+ 10-Oct-2001 SS port to 2.4 kernel.
+ 24-Jul-2002 SS remove unused code & added GPL licence.
+ 05-Aug-2005 SS port to 2.6 kernel; make CCIR mode default.
+
+*/
+
+#ifndef _DT3155_INC
+#define _DT3155_INC
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/time.h> /* struct timeval */
+#else
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+
+#define TRUE 1
+#define FALSE 0
+
+/* Uncomment this for 50Hz CCIR */
+#define CCIR 1
+
+/* Can be 1 or 2 */
+#define MAXBOARDS 1
+
+#define BOARD_MAX_BUFFS 3
+#define MAXBUFFERS (BOARD_MAX_BUFFS*MAXBOARDS)
+
+#define PCI_PAGE_SIZE (1 << 12)
+
+#ifdef CCIR
+#define DT3155_MAX_ROWS 576
+#define DT3155_MAX_COLS 768
+#define FORMAT50HZ TRUE
+#else
+#define DT3155_MAX_ROWS 480
+#define DT3155_MAX_COLS 640
+#define FORMAT50HZ FALSE
+#endif
+
+/* Configuration structure */
+struct dt3155_config_s {
+ u32 acq_mode;
+ u32 cols, rows;
+ u32 continuous;
+};
+
+
+/* hold data for each frame */
+typedef struct {
+ u32 addr; /* address of the buffer with the frame */
+ u32 tag; /* unique number for the frame */
+ struct timeval time; /* time that capture took place */
+} frame_info_t;
+
+/*
+ * Structure for interrupt and buffer handling.
+ * This is the setup for 1 card
+ */
+struct dt3155_fbuffer_s {
+ int nbuffers;
+
+ frame_info_t frame_info[BOARD_MAX_BUFFS];
+
+ int empty_buffers[BOARD_MAX_BUFFS]; /* indexes empty frames */
+ int empty_len; /* Number of empty buffers */
+ /* Zero means empty */
+
+ int active_buf; /* Where data is currently dma'ing */
+ int locked_buf; /* Buffers used by user */
+
+ int ready_que[BOARD_MAX_BUFFS];
+ u32 ready_head; /* The most recent buffer located here */
+ u32 ready_len; /* The number of ready buffers */
+
+ int even_happened;
+ int even_stopped;
+
+ int stop_acquire; /* Flag to stop interrupts */
+ u32 frame_count; /* Counter for frames acquired by this card */
+};
+
+
+
+#define DT3155_MODE_FRAME 1
+#define DT3155_MODE_FIELD 2
+
+#define DT3155_SNAP 1
+#define DT3155_ACQ 2
+
+/* There is one status structure for each card. */
+typedef struct dt3155_status_s {
+ int fixed_mode; /* if 1, we are in fixed frame mode */
+ u32 reg_addr; /* Register address for a single card */
+ u32 mem_addr; /* Buffer start addr for this card */
+ u32 mem_size; /* This is the amount of mem available */
+ u32 irq; /* this card's irq */
+ struct dt3155_config_s config; /* configuration struct */
+ struct dt3155_fbuffer_s fbuffer; /* frame buffer state struct */
+ u32 state; /* this card's state */
+ u32 device_installed; /* Flag if installed. 1=installed */
+} dt3155_status_t;
+
+/* Reference to global status structure */
+extern struct dt3155_status_s dt3155_status[MAXBOARDS];
+
+#define DT3155_STATE_IDLE 0x00
+#define DT3155_STATE_FRAME 0x01
+#define DT3155_STATE_FLD 0x02
+#define DT3155_STATE_STOP 0x100
+#define DT3155_STATE_ERROR 0x200
+#define DT3155_STATE_MODE 0x0ff
+
+#define DT3155_IOC_MAGIC '!'
+
+#define DT3155_SET_CONFIG _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config_s)
+#define DT3155_GET_CONFIG _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status_s)
+#define DT3155_STOP _IO(DT3155_IOC_MAGIC, 3)
+#define DT3155_START _IO(DT3155_IOC_MAGIC, 4)
+#define DT3155_FLUSH _IO(DT3155_IOC_MAGIC, 5)
+#define DT3155_IOC_MAXNR 5
+
+/* Error codes */
+
+#define DT_ERR_NO_BUFFERS 0x10000 /* not used but it might be one day */
+#define DT_ERR_CORRUPT 0x20000
+#define DT_ERR_OVERRUN 0x30000
+#define DT_ERR_I2C_TIMEOUT 0x40000
+#define DT_ERR_MASK 0xff0000/* not used but it might be one day */
+
+/* User code will probably want to declare one of these for each card */
+typedef struct dt3155_read_s {
+ u32 offset;
+ u32 frame_seq;
+ u32 state;
+
+ frame_info_t frame_info;
+} dt3155_read_t;
+
+#endif /* _DT3155_inc */
diff --git a/drivers/staging/dt3155/dt3155.sysvinit b/drivers/staging/dt3155/dt3155.sysvinit
new file mode 100644
index 00000000000..92ec0939cb7
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155.sysvinit
@@ -0,0 +1,60 @@
+#! /bin/sh
+#
+# Module load/unload script for use with SysV-style /etc/init.d/ systems.
+# On a Debian system, copy this to /etc/init.d/dt3155 and then run
+# /usr/sbin/update-rc.d dt3155 defaults 55
+# to create the appropriate /etc/rc?.d/[SK]55dt3155 start/stop links.
+# (The "55" is arbitrary but is what I use to load this rather late.)
+#
+# Andy Dougherty Feb 22 2000 doughera@lafayette.edu
+# Dept. of Physics
+# Lafayette College, Easton PA 18042
+#
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+
+# Edit to point to your local copy.
+FILE=/usr/local/lib/modules/dt3155/dt3155.o
+NAME="dt3155"
+DESC="dt3155 Frame Grabber module"
+DEV="dt3155"
+
+if test ! -f $FILE; then
+ echo "Unable to locate $FILE"
+ exit 0
+fi
+
+set -e
+
+case "$1" in
+ start)
+ echo -n "Loading $DESC "
+ if /sbin/insmod -v -f $FILE; then
+ major=`grep $DEV /proc/devices | awk "{print \\$1}"`
+ rm -f /dev/dt3155?
+ mknod /dev/dt3155a c $major 0
+ mknod /dev/dt3155b c $major 1
+ chmod go+rw /dev/dt3155?
+ echo
+ else
+ echo "$FILE not loaded."
+ fi
+ ;;
+ stop)
+ echo -n "Unloading $DESC: "
+ if /sbin/rmmod $NAME ; then
+ echo
+ else
+ echo "$DEV not removed"
+ exit 0
+ fi
+ rm -f /dev/dt3155?
+ ;;
+ *)
+ echo "Usage: /etc/init.d/$NAME {start|stop}"
+ exit 1
+ ;;
+esac
+
+exit 0
+
diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c
new file mode 100644
index 00000000000..7ac2c6d8e9a
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_drv.c
@@ -0,0 +1,1087 @@
+/*
+
+Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+ Jason Lapenta, Scott Smedley, Greg Sharp
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; 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.
+
+The DT3155 Device Driver is distributed in 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 the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+-- Changes --
+
+ Date Programmer Description of changes made
+ -------------------------------------------------------------------
+ 03-Jul-2000 JML n/a
+ 10-Oct-2001 SS port to 2.4 kernel
+ 02-Apr-2002 SS Mods to use allocator as a standalone module;
+ Merged John Roll's changes (john@cfa.harvard.edu)
+ to make work with multiple boards.
+ 02-Jul-2002 SS Merged James Rose's chages (rosejr@purdue.edu) to:
+ * fix successive interrupt-driven captures
+ * add select/poll support.
+ 10-Jul-2002 GCS Add error check when ndevices > MAXBOARDS.
+ 02-Aug-2002 GCS Fix field mode so that odd (lower) field is stored
+ in lower half of buffer.
+ 05-Aug-2005 SS port to 2.6 kernel.
+ 26-Oct-2009 SS port to 2.6.30 kernel.
+
+-- Notes --
+
+** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system.
+ * using allocator.c and allocator.h from o'reilly book (alessandro rubini)
+ ftp://ftp.systemy.it/pub/develop (see README.allocator)
+
+ + might want to get rid of MAXboards for allocating initial buffer.
+ confusing and not necessary
+
+ + in cleanup_module the MOD_IN_USE looks like it is check after it should
+
+ * GFP_DMA should not be set with a PCI system (pg 291)
+
+ - NJC why are only two buffers allowed? (see isr, approx line 358)
+
+*/
+
+extern void printques(int);
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "dt3155.h"
+#include "dt3155_drv.h"
+#include "dt3155_isr.h"
+#include "dt3155_io.h"
+#include "allocator.h"
+
+
+MODULE_LICENSE("GPL");
+
+/* Error variable. Zero means no error. */
+int dt3155_errno = 0;
+
+#ifndef PCI_DEVICE_ID_INTEL_7116
+#define PCI_DEVICE_ID_INTEL_7116 0x1223
+#endif
+
+#define DT3155_VENDORID PCI_VENDOR_ID_INTEL
+#define DT3155_DEVICEID PCI_DEVICE_ID_INTEL_7116
+#define MAXPCI 16
+
+#ifdef DT_DEBUG
+#define DT_3155_DEBUG_MSG(x,y) printk(x,y)
+#else
+#define DT_3155_DEBUG_MSG(x,y)
+#endif
+
+/* wait queue for interrupts */
+wait_queue_head_t dt3155_read_wait_queue[ MAXBOARDS ];
+
+#define DT_3155_SUCCESS 0
+#define DT_3155_FAILURE -EIO
+
+/* set to dynamicaly allocate, but it is tunable: */
+/* insmod DT_3155 dt3155 dt3155_major=XX */
+int dt3155_major = 0;
+
+/* The minor numbers are 0 and 1 ... they are not tunable.
+ * They are used as the indices for the structure vectors,
+ * and register address vectors
+ */
+
+/* Global structures and variables */
+
+/* Status of each device */
+struct dt3155_status_s dt3155_status[ MAXBOARDS ];
+
+/* kernel logical address of the board */
+u8 *dt3155_lbase[ MAXBOARDS ] = { NULL
+#if MAXBOARDS == 2
+ , NULL
+#endif
+};
+/* DT3155 registers */
+u8 *dt3155_bbase = NULL; /* kernel logical address of the *
+ * buffer region */
+u32 dt3155_dev_open[ MAXBOARDS ] = {0
+#if MAXBOARDS == 2
+ , 0
+#endif
+};
+
+u32 ndevices = 0;
+u32 unique_tag = 0;;
+
+
+/*
+ * Stops interrupt generation right away and resets the status
+ * to idle. I don't know why this works and the other way doesn't.
+ * (James Rose)
+ */
+static void quick_stop (int minor)
+{
+ // TODO: scott was here
+#if 1
+ ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
+ /* disable interrupts */
+ int_csr_r.fld.FLD_END_EVE_EN = 0;
+ int_csr_r.fld.FLD_END_ODD_EN = 0;
+ WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
+
+ dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff);
+ /* mark the system stopped: */
+ dt3155_status[ minor ].state |= DT3155_STATE_IDLE;
+ dt3155_fbuffer[ minor ]->stop_acquire = 0;
+ dt3155_fbuffer[ minor ]->even_stopped = 0;
+#else
+ dt3155_status[minor].state |= DT3155_STATE_STOP;
+ dt3155_status[minor].fbuffer.stop_acquire = 1;
+#endif
+
+}
+
+
+/*****************************************************
+ * dt3155_isr() Interrupt service routien
+ *
+ * - looks like this isr supports IRQ sharing (or could) JML
+ * - Assumes irq's are disabled, via SA_INTERRUPT flag
+ * being set in request_irq() call from init_module()
+ *****************************************************/
+static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs )
+{
+ int minor = -1;
+ int index;
+ unsigned long flags;
+ u32 buffer_addr;
+
+ /* find out who issued the interrupt */
+ for ( index = 0; index < ndevices; index++ ) {
+ if( dev_id == (void*) &dt3155_status[ index ])
+ {
+ minor = index;
+ break;
+ }
+ }
+
+ /* hopefully we should not get here */
+ if ( minor < 0 || minor >= MAXBOARDS ) {
+ printk(KERN_ERR "dt3155_isr called with invalid dev_id\n");
+ return;
+ }
+
+ /* Check for corruption and set a flag if so */
+ ReadMReg( (dt3155_lbase[ minor ] + CSR1), csr1_r.reg );
+
+ if ( (csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD) )
+ {
+ /* TODO: this should probably stop acquisition */
+ /* and set some flags so that dt3155_read */
+ /* returns an error next time it is called */
+ dt3155_errno = DT_ERR_CORRUPT;
+ printk("dt3155: corrupt field\n");
+ return;
+ }
+
+ ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
+
+ /* Handle the even field ... */
+ if (int_csr_r.fld.FLD_END_EVE)
+ {
+ if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
+ DT3155_STATE_FLD )
+ {
+ dt3155_fbuffer[ minor ]->frame_count++;
+ }
+
+ ReadI2C(dt3155_lbase[ minor ], EVEN_CSR, &i2c_even_csr.reg);
+
+ /* Clear the interrupt? */
+ int_csr_r.fld.FLD_END_EVE = 1;
+
+ /* disable the interrupt if last field */
+ if (dt3155_fbuffer[ minor ]->stop_acquire)
+ {
+ printk("dt3155: even stopped.\n");
+ dt3155_fbuffer[ minor ]->even_stopped = 1;
+ if (i2c_even_csr.fld.SNGL_EVE)
+ {
+ int_csr_r.fld.FLD_END_EVE_EN = 0;
+ }
+ else
+ {
+ i2c_even_csr.fld.SNGL_EVE = 1;
+ }
+ }
+
+ WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
+
+ /* Set up next DMA if we are doing FIELDS */
+ if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE ) ==
+ DT3155_STATE_FLD)
+ {
+ /* GCS (Aug 2, 2002) -- In field mode, dma the odd field
+ into the lower half of the buffer */
+ const u32 stride = dt3155_status[ minor ].config.cols;
+ buffer_addr = dt3155_fbuffer[ minor ]->
+ frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr
+ + (DT3155_MAX_ROWS / 2) * stride;
+ local_save_flags(flags);
+ local_irq_disable();
+ wake_up_interruptible( &dt3155_read_wait_queue[ minor ] );
+
+ /* Set up the DMA address for the next field */
+ local_irq_restore(flags);
+ WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr);
+ }
+
+ /* Check for errors. */
+ i2c_even_csr.fld.DONE_EVE = 1;
+ if ( i2c_even_csr.fld.ERROR_EVE )
+ dt3155_errno = DT_ERR_OVERRUN;
+
+ WriteI2C( dt3155_lbase[ minor ], EVEN_CSR, i2c_even_csr.reg );
+
+ /* Note that we actually saw an even field meaning */
+ /* that subsequent odd field complete the frame */
+ dt3155_fbuffer[ minor ]->even_happened = 1;
+
+ /* recording the time that the even field finished, this should be */
+ /* about time in the middle of the frame */
+ do_gettimeofday( &(dt3155_fbuffer[ minor ]->
+ frame_info[ dt3155_fbuffer[ minor ]->
+ active_buf ].time) );
+ return;
+ }
+
+ /* ... now handle the odd field */
+ if ( int_csr_r.fld.FLD_END_ODD )
+ {
+ ReadI2C( dt3155_lbase[ minor ], ODD_CSR, &i2c_odd_csr.reg );
+
+ /* Clear the interrupt? */
+ int_csr_r.fld.FLD_END_ODD = 1;
+
+ if (dt3155_fbuffer[ minor ]->even_happened ||
+ (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
+ DT3155_STATE_FLD)
+ {
+ dt3155_fbuffer[ minor ]->frame_count++;
+ }
+
+ if ( dt3155_fbuffer[ minor ]->stop_acquire &&
+ dt3155_fbuffer[ minor ]->even_stopped )
+ {
+ printk(KERN_DEBUG "dt3155: stopping odd..\n");
+ if ( i2c_odd_csr.fld.SNGL_ODD )
+ {
+ /* disable interrupts */
+ int_csr_r.fld.FLD_END_ODD_EN = 0;
+ dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff);
+
+ /* mark the system stopped: */
+ dt3155_status[ minor ].state |= DT3155_STATE_IDLE;
+ dt3155_fbuffer[ minor ]->stop_acquire = 0;
+ dt3155_fbuffer[ minor ]->even_stopped = 0;
+
+ printk(KERN_DEBUG "dt3155: state is now %x\n",
+ dt3155_status[minor].state);
+ }
+ else
+ {
+ i2c_odd_csr.fld.SNGL_ODD = 1;
+ }
+ }
+
+ WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
+
+ /* if the odd field has been acquired, then */
+ /* change the next dma location for both fields */
+ /* and wake up the process if sleeping */
+ if ( dt3155_fbuffer[ minor ]->even_happened ||
+ (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
+ DT3155_STATE_FLD )
+ {
+
+ local_save_flags(flags);
+ local_irq_disable();
+
+#ifdef DEBUG_QUES_B
+ printques( minor );
+#endif
+ if ( dt3155_fbuffer[ minor ]->nbuffers > 2 )
+ {
+ if ( !are_empty_buffers( minor ) )
+ {
+ /* The number of active + locked buffers is
+ * at most 2, and since there are none empty, there
+ * must be at least nbuffers-2 ready buffers.
+ * This is where we 'drop frames', oldest first. */
+ push_empty( pop_ready( minor ), minor );
+ }
+
+ /* The ready_que can't be full, since we know
+ * there is one active buffer right now, so it's safe
+ * to push the active buf on the ready_que. */
+ push_ready( minor, dt3155_fbuffer[ minor ]->active_buf );
+ /* There's at least 1 empty -- make it active */
+ dt3155_fbuffer[ minor ]->active_buf = pop_empty( minor );
+ dt3155_fbuffer[ minor ]->
+ frame_info[ dt3155_fbuffer[ minor ]->
+ active_buf ].tag = ++unique_tag;
+ }
+ else /* nbuffers == 2, special case */
+ { /* There is 1 active buffer.
+ * If there is a locked buffer, keep the active buffer
+ * the same -- that means we drop a frame.
+ */
+ if ( dt3155_fbuffer[ minor ]->locked_buf < 0 )
+ {
+ push_ready( minor,
+ dt3155_fbuffer[ minor ]->active_buf );
+ if (are_empty_buffers( minor ) )
+ {
+ dt3155_fbuffer[ minor ]->active_buf =
+ pop_empty( minor );
+ }
+ else
+ { /* no empty or locked buffers, so use a readybuf */
+ dt3155_fbuffer[ minor ]->active_buf =
+ pop_ready( minor );
+ }
+ }
+ }
+
+#ifdef DEBUG_QUES_B
+ printques( minor );
+#endif
+
+ dt3155_fbuffer[ minor ]->even_happened = 0;
+
+ wake_up_interruptible( &dt3155_read_wait_queue[ minor ] );
+
+ local_irq_restore(flags);
+ }
+
+
+ /* Set up the DMA address for the next frame/field */
+ buffer_addr = dt3155_fbuffer[ minor ]->
+ frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr;
+ if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
+ DT3155_STATE_FLD )
+ {
+ WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr);
+ }
+ else
+ {
+ WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr);
+
+ WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr
+ + dt3155_status[ minor ].config.cols);
+ }
+
+ /* Do error checking */
+ i2c_odd_csr.fld.DONE_ODD = 1;
+ if ( i2c_odd_csr.fld.ERROR_ODD )
+ dt3155_errno = DT_ERR_OVERRUN;
+
+ WriteI2C(dt3155_lbase[ minor ], ODD_CSR, i2c_odd_csr.reg );
+
+ return;
+ }
+ /* If we get here, the Odd Field wasn't it either... */
+ printk( "neither even nor odd. shared perhaps?\n");
+}
+
+/*****************************************************
+ * init_isr(int minor)
+ * turns on interupt generation for the card
+ * designated by "minor".
+ * It is called *only* from inside ioctl().
+ *****************************************************/
+static void dt3155_init_isr(int minor)
+{
+ const u32 stride = dt3155_status[ minor ].config.cols;
+
+ switch (dt3155_status[ minor ].state & DT3155_STATE_MODE)
+ {
+ case DT3155_STATE_FLD:
+ {
+ even_dma_start_r = dt3155_status[ minor ].
+ fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr;
+ even_dma_stride_r = 0;
+ odd_dma_stride_r = 0;
+
+ WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START),
+ even_dma_start_r);
+ WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE),
+ even_dma_stride_r);
+ WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE),
+ odd_dma_stride_r);
+ break;
+ }
+
+ case DT3155_STATE_FRAME:
+ default:
+ {
+ even_dma_start_r = dt3155_status[ minor ].
+ fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr;
+ odd_dma_start_r = even_dma_start_r + stride;
+ even_dma_stride_r = stride;
+ odd_dma_stride_r = stride;
+
+ WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START),
+ even_dma_start_r);
+ WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START),
+ odd_dma_start_r);
+ WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE),
+ even_dma_stride_r);
+ WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE),
+ odd_dma_stride_r);
+ break;
+ }
+ }
+
+ /* 50/60 Hz should be set before this point but let's make sure it is */
+ /* right anyway */
+
+ ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg);
+ i2c_csr2.fld.HZ50 = FORMAT50HZ;
+ WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg);
+
+ /* enable busmaster chip, clear flags */
+
+ /*
+ * TODO:
+ * shouldn't we be concered with continuous values of
+ * DT3155_SNAP & DT3155_ACQ here? (SS)
+ */
+
+ csr1_r.reg = 0;
+ csr1_r.fld.CAP_CONT_EVE = 1; /* use continuous capture bits to */
+ csr1_r.fld.CAP_CONT_ODD = 1; /* enable */
+ csr1_r.fld.FLD_DN_EVE = 1; /* writing a 1 clears flags */
+ csr1_r.fld.FLD_DN_ODD = 1;
+ csr1_r.fld.SRST = 1; /* reset - must be 1 */
+ csr1_r.fld.FIFO_EN = 1; /* fifo control - must be 1 */
+ csr1_r.fld.FLD_CRPT_EVE = 1; /* writing a 1 clears flags */
+ csr1_r.fld.FLD_CRPT_ODD = 1;
+
+ WriteMReg((dt3155_lbase[ minor ] + CSR1),csr1_r.reg);
+
+ /* Enable interrupts at the end of each field */
+
+ int_csr_r.reg = 0;
+ int_csr_r.fld.FLD_END_EVE_EN = 1;
+ int_csr_r.fld.FLD_END_ODD_EN = 1;
+ int_csr_r.fld.FLD_START_EN = 0;
+
+ WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
+
+ /* start internal BUSY bits */
+
+ ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg);
+ i2c_csr2.fld.BUSY_ODD = 1;
+ i2c_csr2.fld.BUSY_EVE = 1;
+ WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg);
+
+ /* Now its up to the interrupt routine!! */
+
+ return;
+}
+
+
+/*****************************************************
+ * ioctl()
+ *
+ *****************************************************/
+static int dt3155_ioctl(struct inode *inode,
+ struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */
+
+ if ( minor >= MAXBOARDS || minor < 0 )
+ return -ENODEV;
+
+ /* make sure it is valid command */
+ if (_IOC_NR(cmd) > DT3155_IOC_MAXNR)
+ {
+ printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
+ printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
+ (unsigned int)DT3155_GET_CONFIG,
+ (unsigned int)DT3155_SET_CONFIG,
+ (unsigned int)DT3155_START,
+ (unsigned int)DT3155_STOP,
+ (unsigned int)DT3155_FLUSH);
+ return -EINVAL;
+ }
+
+ switch (cmd)
+ {
+ case DT3155_SET_CONFIG:
+ {
+ if (dt3155_status[minor].state != DT3155_STATE_IDLE)
+ return -EBUSY;
+
+ {
+ struct dt3155_config_s tmp;
+ if (copy_from_user((void *)&tmp, (void *) arg, sizeof(tmp)))
+ return -EFAULT;
+ /* check for valid settings */
+ if (tmp.rows > DT3155_MAX_ROWS ||
+ tmp.cols > DT3155_MAX_COLS ||
+ (tmp.acq_mode != DT3155_MODE_FRAME &&
+ tmp.acq_mode != DT3155_MODE_FIELD) ||
+ (tmp.continuous != DT3155_SNAP &&
+ tmp.continuous != DT3155_ACQ))
+ {
+ return -EINVAL;
+ }
+ dt3155_status[minor].config = tmp;
+ }
+ return 0;
+ }
+ case DT3155_GET_CONFIG:
+ {
+ if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
+ sizeof(dt3155_status_t) ))
+ return -EFAULT;
+ return 0;
+ }
+ case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */
+ {
+ if (dt3155_status[minor].state != DT3155_STATE_IDLE)
+ return -EBUSY;
+ return dt3155_flush(minor);
+ }
+ case DT3155_STOP:
+ {
+ if (dt3155_status[minor].state & DT3155_STATE_STOP ||
+ dt3155_status[minor].fbuffer.stop_acquire)
+ return -EBUSY;
+
+ if (dt3155_status[minor].state == DT3155_STATE_IDLE)
+ return 0;
+
+ quick_stop(minor);
+ if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
+ sizeof(dt3155_status_t)))
+ return -EFAULT;
+ return 0;
+ }
+ case DT3155_START:
+ {
+ if (dt3155_status[minor].state != DT3155_STATE_IDLE)
+ return -EBUSY;
+
+ dt3155_status[minor].fbuffer.stop_acquire = 0;
+ dt3155_status[minor].fbuffer.frame_count = 0;
+
+ /* Set the MODE in the status -- we default to FRAME */
+ if (dt3155_status[minor].config.acq_mode == DT3155_MODE_FIELD)
+ {
+ dt3155_status[minor].state = DT3155_STATE_FLD;
+ }
+ else
+ {
+ dt3155_status[minor].state = DT3155_STATE_FRAME;
+ }
+
+ dt3155_init_isr(minor);
+ if (copy_to_user( (void *) arg, (void *) &dt3155_status[minor],
+ sizeof(dt3155_status_t)))
+ return -EFAULT;
+ return 0;
+ }
+ default:
+ {
+ printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
+ printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
+ (unsigned int)DT3155_GET_CONFIG,
+ (unsigned int)DT3155_SET_CONFIG,
+ DT3155_START, DT3155_STOP, DT3155_FLUSH);
+ return -ENOSYS;
+ }
+ }
+ return -ENOSYS;
+}
+
+/*****************************************************
+ * mmap()
+ *
+ * only allow the user to mmap the registers and buffer
+ * It is quite possible that this is broken, since the
+ * addition of of the capacity for two cards!!!!!!!!
+ * It *looks* like it should work but since I'm not
+ * sure how to use it, I'm not actually sure. (NJC? ditto by SS)
+ *****************************************************/
+static int dt3155_mmap (struct file * file, struct vm_area_struct * vma)
+{
+ /* which device are we mmapping? */
+ int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ unsigned long offset;
+ offset = vma->vm_pgoff << PAGE_SHIFT;
+
+ if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
+ vma->vm_flags |= VM_IO;
+
+ /* Don't try to swap out physical pages.. */
+ vma->vm_flags |= VM_RESERVED;
+
+ /* they are mapping the registers or the buffer */
+ if ((offset == dt3155_status[minor].reg_addr &&
+ vma->vm_end - vma->vm_start == PCI_PAGE_SIZE) ||
+ (offset == dt3155_status[minor].mem_addr &&
+ vma->vm_end - vma->vm_start == dt3155_status[minor].mem_size))
+ {
+ if (remap_pfn_range(vma,
+ vma->vm_start,
+ offset >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ printk("DT3155: remap_page_range() failed.\n");
+ return -EAGAIN;
+ }
+ }
+ else
+ {
+ printk("DT3155: dt3155_mmap() bad call.\n");
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+
+/*****************************************************
+ * open()
+ *
+ * Our special open code.
+ * MOD_INC_USE_COUNT make sure that the driver memory is not freed
+ * while the device is in use.
+ *****************************************************/
+static int dt3155_open( struct inode* inode, struct file* filep)
+{
+ int minor = MINOR(inode->i_rdev); /* what device are we opening? */
+ if (dt3155_dev_open[ minor ]) {
+ printk ("DT3155: Already opened by another process.\n");
+ return -EBUSY;
+ }
+
+ if (dt3155_status[ minor ].device_installed==0)
+ {
+ printk("DT3155 Open Error: No such device dt3155 minor number %d\n",
+ minor);
+ return -EIO;
+ }
+
+ if (dt3155_status[ minor ].state != DT3155_STATE_IDLE) {
+ printk ("DT3155: Not in idle state (state = %x)\n",
+ dt3155_status[ minor ].state);
+ return -EBUSY;
+ }
+
+ printk("DT3155: Device opened.\n");
+
+ dt3155_dev_open[ minor ] = 1 ;
+
+ dt3155_flush( minor );
+
+ /* Disable ALL interrupts */
+ int_csr_r.reg = 0;
+ WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
+
+ init_waitqueue_head(&(dt3155_read_wait_queue[minor]));
+
+ return 0;
+}
+
+
+/*****************************************************
+ * close()
+ *
+ * Now decrement the use count.
+ *
+ *****************************************************/
+static int dt3155_close( struct inode *inode, struct file *filep)
+{
+ int minor;
+
+ minor = MINOR(inode->i_rdev); /* which device are we closing */
+ if (!dt3155_dev_open[ minor ])
+ {
+ printk("DT3155: attempt to CLOSE a not OPEN device\n");
+ }
+ else
+ {
+ dt3155_dev_open[ minor ] = 0;
+
+ if (dt3155_status[ minor ].state != DT3155_STATE_IDLE)
+ {
+ quick_stop(minor);
+ }
+ }
+ return 0;
+}
+
+/*****************************************************
+ * read()
+ *
+ *****************************************************/
+static ssize_t dt3155_read(struct file *filep, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ /* which device are we reading from? */
+ int minor = MINOR(filep->f_dentry->d_inode->i_rdev);
+ u32 offset;
+ int frame_index;
+ frame_info_t *frame_info_p;
+
+ /* TODO: this should check the error flag and */
+ /* return an error on hardware failures */
+ if (count != sizeof(dt3155_read_t))
+ {
+ printk("DT3155 ERROR (NJC): count is not right\n");
+ return -EINVAL;
+ }
+
+
+ /* Hack here -- I'm going to allow reading even when idle.
+ * this is so that the frames can be read after STOP has
+ * been called. Leaving it here, commented out, as a reminder
+ * for a short while to make sure there are no problems.
+ * Note that if the driver is not opened in non_blocking mode,
+ * and the device is idle, then it could sit here forever! */
+
+ /* if (dt3155_status[minor].state == DT3155_STATE_IDLE)*/
+ /* return -EBUSY;*/
+
+ /* non-blocking reads should return if no data */
+ if (filep->f_flags & O_NDELAY)
+ {
+ if ((frame_index = dt3155_get_ready_buffer(minor)) < 0) {
+ /*printk( "dt3155: no buffers available (?)\n");*/
+ /* printques(minor); */
+ return -EAGAIN;
+ }
+ }
+ else
+ {
+ /*
+ * sleep till data arrives , or we get interrupted.
+ * Note that wait_event_interruptible() does not actually
+ * sleep/wait if it's condition evaluates to true upon entry.
+ */
+ wait_event_interruptible(dt3155_read_wait_queue[minor],
+ (frame_index = dt3155_get_ready_buffer(minor))
+ >= 0);
+
+ if (frame_index < 0)
+ {
+ printk ("DT3155: read: interrupted\n");
+ quick_stop (minor);
+ printques(minor);
+ return -EINTR;
+ }
+ }
+
+ frame_info_p = &dt3155_status[minor].fbuffer.frame_info[frame_index];
+
+ /* make this an offset */
+ offset = frame_info_p->addr - dt3155_status[minor].mem_addr;
+
+ put_user(offset, (unsigned int *) buf);
+ buf += sizeof(u32);
+ put_user( dt3155_status[minor].fbuffer.frame_count, (unsigned int *) buf);
+ buf += sizeof(u32);
+ put_user(dt3155_status[minor].state, (unsigned int *) buf);
+ buf += sizeof(u32);
+ if (copy_to_user(buf, frame_info_p, sizeof(frame_info_t)))
+ return -EFAULT;
+
+ return sizeof(dt3155_read_t);
+}
+
+static unsigned int dt3155_poll (struct file * filp, poll_table *wait)
+{
+ int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
+
+ if (!is_ready_buf_empty(minor))
+ return POLLIN | POLLRDNORM;
+
+ poll_wait (filp, &dt3155_read_wait_queue[minor], wait);
+
+ return 0;
+}
+
+
+/*****************************************************
+ * file operations supported by DT3155 driver
+ * needed by init_module
+ * register_chrdev
+ *****************************************************/
+static struct file_operations dt3155_fops = {
+ read: dt3155_read,
+ ioctl: dt3155_ioctl,
+ mmap: dt3155_mmap,
+ poll: dt3155_poll,
+ open: dt3155_open,
+ release: dt3155_close
+};
+
+
+/*****************************************************
+ * find_PCI();
+ *
+ * PCI has been totally reworked in 2.1..
+ *****************************************************/
+static int find_PCI (void)
+{
+ struct pci_dev *pci_dev = NULL;
+ int error, pci_index = 0;
+ unsigned short rev_device;
+ unsigned long base;
+ unsigned char irq;
+
+ while ((pci_dev = pci_get_device
+ (DT3155_VENDORID, DT3155_DEVICEID, pci_dev)) != NULL)
+ {
+ pci_index ++;
+
+ /* Is it really there? */
+ if ((error =
+ pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device)))
+ continue;
+
+ /* Found a board */
+ DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index);
+
+ /* Make sure the driver was compiled with enough buffers to handle
+ this many boards */
+ if (pci_index > MAXBOARDS) {
+ printk("DT3155: ERROR - found %d devices, but driver only configured "
+ "for %d devices\n"
+ "DT3155: Please change MAXBOARDS in dt3155.h\n",
+ pci_index, MAXBOARDS);
+ goto err;
+ }
+
+ /* Now, just go out and make sure that this/these device(s) is/are
+ actually mapped into the kernel address space */
+ if ((error = pci_read_config_dword( pci_dev, PCI_BASE_ADDRESS_0,
+ (u32 *) &base)))
+ {
+ printk("DT3155: Was not able to find device \n");
+ goto err;
+ }
+
+ DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base);
+ dt3155_status[pci_index-1].reg_addr = base;
+
+ /* Remap the base address to a logical address through which we
+ * can access it. */
+ dt3155_lbase[ pci_index - 1 ] = ioremap(base,PCI_PAGE_SIZE);
+ dt3155_status[ pci_index - 1 ].reg_addr = base;
+ DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n",
+ dt3155_lbase[pci_index-1]);
+ if ( !dt3155_lbase[pci_index-1] )
+ {
+ printk("DT3155: Unable to remap control registers\n");
+ goto err;
+ }
+
+ if ( (error = pci_read_config_byte( pci_dev, PCI_INTERRUPT_LINE, &irq)) )
+ {
+ printk("DT3155: Was not able to find device \n");
+ goto err;
+ }
+
+ DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq);
+ dt3155_status[ pci_index-1 ].irq = irq;
+ /* Set flag: kth device found! */
+ dt3155_status[ pci_index-1 ].device_installed = 1;
+ printk("DT3155: Installing device %d w/irq %d and address %p\n",
+ pci_index,
+ dt3155_status[pci_index-1].irq,
+ dt3155_lbase[pci_index-1]);
+
+ }
+ ndevices = pci_index;
+
+ return DT_3155_SUCCESS;
+
+err:
+ pci_dev_put(pci_dev);
+ return DT_3155_FAILURE;
+}
+
+u32 allocatorAddr = 0;
+
+/*****************************************************
+ * init_module()
+ *****************************************************/
+int init_module(void)
+{
+ int index;
+ int rcode = 0;
+ char *devname[ MAXBOARDS ];
+
+ devname[ 0 ] = "dt3155a";
+#if MAXBOARDS == 2
+ devname[ 1 ] = "dt3155b";
+#endif
+
+ printk("DT3155: Loading module...\n");
+
+ /* Register the device driver */
+ rcode = register_chrdev( dt3155_major, "dt3155", &dt3155_fops );
+ if( rcode < 0 )
+ {
+ printk( KERN_INFO "DT3155: register_chrdev failed \n");
+ return rcode;
+ }
+
+ if( dt3155_major == 0 )
+ dt3155_major = rcode; /* dynamic */
+
+
+ /* init the status variables. */
+ /* DMA memory is taken care of in setup_buffers() */
+ for ( index = 0; index < MAXBOARDS; index++ )
+ {
+ dt3155_status[ index ].config.acq_mode = DT3155_MODE_FRAME;
+ dt3155_status[ index ].config.continuous = DT3155_ACQ;
+ dt3155_status[ index ].config.cols = DT3155_MAX_COLS;
+ dt3155_status[ index ].config.rows = DT3155_MAX_ROWS;
+ dt3155_status[ index ].state = DT3155_STATE_IDLE;
+
+ /* find_PCI() will check if devices are installed; */
+ /* first assume they're not: */
+ dt3155_status[ index ].mem_addr = 0;
+ dt3155_status[ index ].mem_size = 0;
+ dt3155_status[ index ].state = DT3155_STATE_IDLE;
+ dt3155_status[ index ].device_installed = 0;
+ }
+
+ /* Now let's find the hardware. find_PCI() will set ndevices to the
+ * number of cards found in this machine. */
+ {
+ if ( (rcode = find_PCI()) != DT_3155_SUCCESS )
+ {
+ printk("DT3155 error: find_PCI() failed to find dt3155 board(s)\n");
+ unregister_chrdev( dt3155_major, "dt3155" );
+ return rcode;
+ }
+ }
+
+ /* Ok, time to setup the frame buffers */
+ if( (rcode = dt3155_setup_buffers(&allocatorAddr)) < 0 )
+ {
+ printk("DT3155: Error: setting up buffer not large enough.");
+ unregister_chrdev( dt3155_major, "dt3155" );
+ return rcode;
+ }
+
+ /* If we are this far, then there is enough RAM */
+ /* for the buffers: Print the configuration. */
+ for( index = 0; index < ndevices; index++ )
+ {
+ printk("DT3155: Device = %d; acq_mode = %d; "
+ "continuous = %d; cols = %d; rows = %d;\n",
+ index ,
+ dt3155_status[ index ].config.acq_mode,
+ dt3155_status[ index ].config.continuous,
+ dt3155_status[ index ].config.cols,
+ dt3155_status[ index ].config.rows);
+ printk("DT3155: m_addr = 0x%x; m_size = %ld; "
+ "state = %d; device_installed = %d\n",
+ dt3155_status[ index ].mem_addr,
+ (long int)dt3155_status[ index ].mem_size,
+ dt3155_status[ index ].state,
+ dt3155_status[ index ].device_installed);
+ }
+
+ /* Disable ALL interrupts */
+ int_csr_r.reg = 0;
+ for( index = 0; index < ndevices; index++ )
+ {
+ WriteMReg( (dt3155_lbase[ index ] + INT_CSR), int_csr_r.reg );
+ if( dt3155_status[ index ].device_installed )
+ {
+ /*
+ * This driver *looks* like it can handle sharing interrupts,
+ * but I can't actually test myself. I've had reports that it
+ * DOES work so I'll enable it for now. This comment will remain
+ * as a reminder in case any problems arise. (SS)
+ */
+ /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */
+ rcode = request_irq( dt3155_status[ index ].irq, (void *)dt3155_isr,
+ IRQF_SHARED | IRQF_DISABLED, devname[ index ],
+ (void*) &dt3155_status[index]);
+ if( rcode < 0 )
+ {
+ printk("DT3155: minor %d request_irq failed for IRQ %d\n",
+ index, dt3155_status[index].irq);
+ unregister_chrdev( dt3155_major, "dt3155" );
+ return rcode;
+ }
+ }
+ }
+
+ printk("DT3155: finished loading\n");
+
+ return 0;
+}
+
+/*****************************************************
+ * cleanup_module(void)
+ *
+ *****************************************************/
+void cleanup_module(void)
+{
+ int index;
+
+ printk("DT3155: cleanup_module called\n");
+
+ /* removed DMA allocated with the allocator */
+#ifdef STANDALONE_ALLOCATOR
+ if (allocatorAddr != 0)
+ allocator_free_dma(allocatorAddr);
+#else
+ allocator_cleanup();
+#endif
+
+ unregister_chrdev( dt3155_major, "dt3155" );
+
+ for( index = 0; index < ndevices; index++ )
+ {
+ if( dt3155_status[ index ].device_installed == 1 )
+ {
+ printk( "DT3155: Freeing irq %d for device %d\n",
+ dt3155_status[ index ].irq, index );
+ free_irq( dt3155_status[ index ].irq, (void*)&dt3155_status[index] );
+ }
+ }
+}
+
diff --git a/drivers/staging/dt3155/dt3155_drv.h b/drivers/staging/dt3155/dt3155_drv.h
new file mode 100644
index 00000000000..95e68c3388a
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_drv.h
@@ -0,0 +1,45 @@
+/*
+
+Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+ Scott Smedley
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; 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.
+
+The DT3155 Device Driver is distributed in 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 the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+*/
+
+#ifndef DT3155_DRV_INC
+#define DT3155_DRV_INC
+
+/* kernel logical address of the frame grabbers */
+extern u8 *dt3155_lbase[MAXBOARDS];
+
+/* kernel logical address of ram buffer */
+extern u8 *dt3155_bbase;
+
+#ifdef __KERNEL__
+#include <linux/wait.h>
+
+/* wait queue for reads */
+extern wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS];
+#endif
+
+/* number of devices */
+extern u32 ndevices;
+
+extern int dt3155_errno;
+
+#endif
diff --git a/drivers/staging/dt3155/dt3155_io.c b/drivers/staging/dt3155/dt3155_io.c
new file mode 100644
index 00000000000..6b9c68501a6
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_io.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+ * Jason Lapenta, Scott Smedley
+ *
+ * This file is part of the DT3155 Device Driver.
+ *
+ * The DT3155 Device Driver is free software; 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.
+ *
+ * The DT3155 Device Driver is distributed in 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.
+ */
+
+/*
+ * This file provides some basic register io routines. It is modified from
+ * demo code provided by Data Translations.
+ */
+
+#include <linux/delay.h>
+#include "dt3155.h"
+#include "dt3155_io.h"
+#include "dt3155_drv.h"
+
+
+/****** local copies of board's 32 bit registers ******/
+u32 even_dma_start_r; /* bit 0 should always be 0 */
+u32 odd_dma_start_r; /* .. */
+u32 even_dma_stride_r; /* bits 0&1 should always be 0 */
+u32 odd_dma_stride_r; /* .. */
+u32 even_pixel_fmt_r;
+u32 odd_pixel_fmt_r;
+
+FIFO_TRIGGER_R fifo_trigger_r;
+XFER_MODE_R xfer_mode_r;
+CSR1_R csr1_r;
+RETRY_WAIT_CNT_R retry_wait_cnt_r;
+INT_CSR_R int_csr_r;
+
+u32 even_fld_mask_r;
+u32 odd_fld_mask_r;
+
+MASK_LENGTH_R mask_length_r;
+FIFO_FLAG_CNT_R fifo_flag_cnt_r;
+IIC_CLK_DUR_R iic_clk_dur_r;
+IIC_CSR1_R iic_csr1_r;
+IIC_CSR2_R iic_csr2_r;
+DMA_UPPER_LMT_R even_dma_upper_lmt_r;
+DMA_UPPER_LMT_R odd_dma_upper_lmt_r;
+
+
+
+/******** local copies of board's 8 bit I2C registers ******/
+I2C_CSR2 i2c_csr2;
+I2C_EVEN_CSR i2c_even_csr;
+I2C_ODD_CSR i2c_odd_csr;
+I2C_CONFIG i2c_config;
+u8 i2c_dt_id;
+u8 i2c_x_clip_start;
+u8 i2c_y_clip_start;
+u8 i2c_x_clip_end;
+u8 i2c_y_clip_end;
+u8 i2c_ad_addr;
+u8 i2c_ad_lut;
+I2C_AD_CMD i2c_ad_cmd;
+u8 i2c_dig_out;
+u8 i2c_pm_lut_addr;
+u8 i2c_pm_lut_data;
+
+/*
+ * wait_ibsyclr()
+ *
+ * This function handles read/write timing and r/w timeout error
+ *
+ * Returns TRUE if NEW_CYCLE clears
+ * Returns FALSE if NEW_CYCLE doesn't clear in roughly 3 msecs, otherwise
+ * returns 0
+ */
+static int wait_ibsyclr(u8 *lpReg)
+{
+ /* wait 100 microseconds */
+ udelay(100L);
+ /* __delay(loops_per_sec/10000); */
+ if (iic_csr2_r.fld.NEW_CYCLE) {
+ /* if NEW_CYCLE didn't clear */
+ /* TIMEOUT ERROR */
+ dt3155_errno = DT_ERR_I2C_TIMEOUT;
+ return FALSE;
+ } else
+ return TRUE; /* no error */
+}
+
+/*
+ * WriteI2C()
+ *
+ * This function handles writing to 8-bit DT3155 registers
+ *
+ * 1st parameter is pointer to 32-bit register base address
+ * 2nd parameter is reg. index;
+ * 3rd is value to be written
+ *
+ * Returns TRUE - Successful completion
+ * FALSE - Timeout error - cycle did not complete!
+ */
+int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal)
+{
+ int writestat; /* status for return */
+
+ /* read 32 bit IIC_CSR2 register data into union */
+
+ ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
+
+ /* for write operation */
+ iic_csr2_r.fld.DIR_RD = 0;
+ /* I2C address of I2C register: */
+ iic_csr2_r.fld.DIR_ADDR = wIregIndex;
+ /* 8 bit data to be written to I2C reg */
+ iic_csr2_r.fld.DIR_WR_DATA = byVal;
+ /* will start a direct I2C cycle: */
+ iic_csr2_r.fld.NEW_CYCLE = 1;
+
+ /* xfer union data into 32 bit IIC_CSR2 register */
+ WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
+
+ /* wait for IIC cycle to finish */
+ writestat = wait_ibsyclr(lpReg);
+ return writestat;
+}
+
+/*
+ * ReadI2C()
+ *
+ * This function handles reading from 8-bit DT3155 registers
+ *
+ * 1st parameter is pointer to 32-bit register base address
+ * 2nd parameter is reg. index;
+ * 3rd is adrs of value to be read
+ *
+ * Returns TRUE - Successful completion
+ * FALSE - Timeout error - cycle did not complete!
+ */
+int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal)
+{
+ int writestat; /* status for return */
+
+ /* read 32 bit IIC_CSR2 register data into union */
+ ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
+
+ /* for read operation */
+ iic_csr2_r.fld.DIR_RD = 1;
+
+ /* I2C address of I2C register: */
+ iic_csr2_r.fld.DIR_ADDR = wIregIndex;
+
+ /* will start a direct I2C cycle: */
+ iic_csr2_r.fld.NEW_CYCLE = 1;
+
+ /* xfer union's data into 32 bit IIC_CSR2 register */
+ WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
+
+ /* wait for IIC cycle to finish */
+ writestat = wait_ibsyclr(lpReg);
+
+ /* Next 2 commands read 32 bit IIC_CSR1 register's data into union */
+ /* first read data is in IIC_CSR1 */
+ ReadMReg((lpReg + IIC_CSR1), iic_csr1_r.reg);
+
+ /* now get data u8 out of register */
+ *byVal = (u8) iic_csr1_r.fld.RD_DATA;
+
+ return writestat;
+}
diff --git a/drivers/staging/dt3155/dt3155_io.h b/drivers/staging/dt3155/dt3155_io.h
new file mode 100644
index 00000000000..d1a25100169
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_io.h
@@ -0,0 +1,358 @@
+/*
+
+Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+ Jason Lapenta, Scott Smedley
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; 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.
+
+The DT3155 Device Driver is distributed in 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 the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+
+-- Changes --
+
+ Date Programmer Description of changes made
+ -------------------------------------------------------------------
+ 24-Jul-2002 SS GPL licence.
+
+*/
+
+/* This code is a modified version of examples provided by Data Translations.*/
+
+#ifndef DT3155_IO_INC
+#define DT3155_IO_INC
+
+/* macros to access registers */
+
+#define WriteMReg(Address, Data) (*((u32 *)(Address)) = Data)
+#define ReadMReg(Address, Data) (Data = *((u32 *)(Address)))
+
+/***************** 32 bit register globals **************/
+
+/* offsets for 32-bit memory mapped registers */
+
+#define EVEN_DMA_START 0x000
+#define ODD_DMA_START 0x00C
+#define EVEN_DMA_STRIDE 0x018
+#define ODD_DMA_STRIDE 0x024
+#define EVEN_PIXEL_FMT 0x030
+#define ODD_PIXEL_FMT 0x034
+#define FIFO_TRIGGER 0x038
+#define XFER_MODE 0x03C
+#define CSR1 0x040
+#define RETRY_WAIT_CNT 0x044
+#define INT_CSR 0x048
+#define EVEN_FLD_MASK 0x04C
+#define ODD_FLD_MASK 0x050
+#define MASK_LENGTH 0x054
+#define FIFO_FLAG_CNT 0x058
+#define IIC_CLK_DUR 0x05C
+#define IIC_CSR1 0x060
+#define IIC_CSR2 0x064
+#define EVEN_DMA_UPPR_LMT 0x08C
+#define ODD_DMA_UPPR_LMT 0x090
+
+#define CLK_DUR_VAL 0x01010101
+
+
+
+/******** Assignments and Typedefs for 32 bit Memory Mapped Registers ********/
+
+typedef union fifo_trigger_tag {
+ u32 reg;
+ struct {
+ u32 PACKED:6;
+ u32 :9;
+ u32 PLANER:7;
+ u32 :9;
+ } fld;
+} FIFO_TRIGGER_R;
+
+typedef union xfer_mode_tag {
+ u32 reg;
+ struct {
+ u32 :2;
+ u32 FIELD_TOGGLE:1;
+ u32 :5;
+ u32 :2;
+ u32 :22;
+ } fld;
+} XFER_MODE_R;
+
+typedef union csr1_tag {
+ u32 reg;
+ struct {
+ u32 CAP_CONT_EVE:1;
+ u32 CAP_CONT_ODD:1;
+ u32 CAP_SNGL_EVE:1;
+ u32 CAP_SNGL_ODD:1;
+ u32 FLD_DN_EVE :1;
+ u32 FLD_DN_ODD :1;
+ u32 SRST :1;
+ u32 FIFO_EN :1;
+ u32 FLD_CRPT_EVE:1;
+ u32 FLD_CRPT_ODD:1;
+ u32 ADDR_ERR_EVE:1;
+ u32 ADDR_ERR_ODD:1;
+ u32 CRPT_DIS :1;
+ u32 RANGE_EN :1;
+ u32 :16;
+ } fld;
+} CSR1_R;
+
+typedef union retry_wait_cnt_tag {
+ u32 reg;
+ struct {
+ u32 RTRY_WAIT_CNT:8;
+ u32 :24;
+ } fld;
+} RETRY_WAIT_CNT_R;
+
+typedef union int_csr_tag {
+ u32 reg;
+ struct {
+ u32 FLD_END_EVE :1;
+ u32 FLD_END_ODD :1;
+ u32 FLD_START :1;
+ u32 :5;
+ u32 FLD_END_EVE_EN:1;
+ u32 FLD_END_ODD_EN:1;
+ u32 FLD_START_EN :1;
+ u32 :21;
+ } fld;
+} INT_CSR_R;
+
+typedef union mask_length_tag {
+ u32 reg;
+ struct {
+ u32 MASK_LEN_EVE:5;
+ u32 :11;
+ u32 MASK_LEN_ODD:5;
+ u32 :11;
+ } fld;
+} MASK_LENGTH_R;
+
+typedef union fifo_flag_cnt_tag {
+ u32 reg;
+ struct {
+ u32 AF_COUNT:7;
+ u32 :9;
+ u32 AE_COUNT:7;
+ u32 :9;
+ } fld;
+} FIFO_FLAG_CNT_R;
+
+typedef union iic_clk_dur {
+ u32 reg;
+ struct {
+ u32 PHASE_1:8;
+ u32 PHASE_2:8;
+ u32 PHASE_3:8;
+ u32 PHASE_4:8;
+ } fld;
+} IIC_CLK_DUR_R;
+
+typedef union iic_csr1_tag {
+ u32 reg;
+ struct {
+ u32 AUTO_EN :1;
+ u32 BYPASS :1;
+ u32 SDA_OUT :1;
+ u32 SCL_OUT :1;
+ u32 :4;
+ u32 AUTO_ABORT :1;
+ u32 DIRECT_ABORT:1;
+ u32 SDA_IN :1;
+ u32 SCL_IN :1;
+ u32 :4;
+ u32 AUTO_ADDR :8;
+ u32 RD_DATA :8;
+ } fld;
+} IIC_CSR1_R;
+
+/**********************************
+ * iic_csr2_tag
+ */
+typedef union iic_csr2_tag {
+ u32 reg;
+ struct {
+ u32 DIR_WR_DATA :8;
+ u32 DIR_SUB_ADDR:8;
+ u32 DIR_RD :1;
+ u32 DIR_ADDR :7;
+ u32 NEW_CYCLE :1;
+ u32 :7;
+ } fld;
+} IIC_CSR2_R;
+
+/* use for both EVEN and ODD DMA UPPER LIMITS */
+
+/*
+ * dma_upper_lmt_tag
+ */
+typedef union dma_upper_lmt_tag {
+ u32 reg;
+ struct {
+ u32 DMA_UPPER_LMT_VAL:24;
+ u32 :8;
+ } fld;
+} DMA_UPPER_LMT_R;
+
+
+/*
+ * Global declarations of local copies of boards' 32 bit registers
+ */
+extern u32 even_dma_start_r; /* bit 0 should always be 0 */
+extern u32 odd_dma_start_r; /* .. */
+extern u32 even_dma_stride_r; /* bits 0&1 should always be 0 */
+extern u32 odd_dma_stride_r; /* .. */
+extern u32 even_pixel_fmt_r;
+extern u32 odd_pixel_fmt_r;
+
+extern FIFO_TRIGGER_R fifo_trigger_r;
+extern XFER_MODE_R xfer_mode_r;
+extern CSR1_R csr1_r;
+extern RETRY_WAIT_CNT_R retry_wait_cnt_r;
+extern INT_CSR_R int_csr_r;
+
+extern u32 even_fld_mask_r;
+extern u32 odd_fld_mask_r;
+
+extern MASK_LENGTH_R mask_length_r;
+extern FIFO_FLAG_CNT_R fifo_flag_cnt_r;
+extern IIC_CLK_DUR_R iic_clk_dur_r;
+extern IIC_CSR1_R iic_csr1_r;
+extern IIC_CSR2_R iic_csr2_r;
+extern DMA_UPPER_LMT_R even_dma_upper_lmt_r;
+extern DMA_UPPER_LMT_R odd_dma_upper_lmt_r;
+
+
+
+/***************** 8 bit I2C register globals ***********/
+#define CSR2 0x010 /* indices of 8-bit I2C mapped reg's*/
+#define EVEN_CSR 0x011
+#define ODD_CSR 0x012
+#define CONFIG 0x013
+#define DT_ID 0x01F
+#define X_CLIP_START 0x020
+#define Y_CLIP_START 0x022
+#define X_CLIP_END 0x024
+#define Y_CLIP_END 0x026
+#define AD_ADDR 0x030
+#define AD_LUT 0x031
+#define AD_CMD 0x032
+#define DIG_OUT 0x040
+#define PM_LUT_ADDR 0x050
+#define PM_LUT_DATA 0x051
+
+
+/******** Assignments and Typedefs for 8 bit I2C Registers********************/
+
+typedef union i2c_csr2_tag {
+ u8 reg;
+ struct {
+ u8 CHROM_FIL:1;
+ u8 SYNC_SNTL:1;
+ u8 HZ50:1;
+ u8 SYNC_PRESENT:1;
+ u8 BUSY_EVE:1;
+ u8 BUSY_ODD:1;
+ u8 DISP_PASS:1;
+ } fld;
+} I2C_CSR2;
+
+typedef union i2c_even_csr_tag {
+ u8 reg;
+ struct {
+ u8 DONE_EVE :1;
+ u8 SNGL_EVE :1;
+ u8 ERROR_EVE:1;
+ u8 :5;
+ } fld;
+} I2C_EVEN_CSR;
+
+typedef union i2c_odd_csr_tag {
+ u8 reg;
+ struct {
+ u8 DONE_ODD:1;
+ u8 SNGL_ODD:1;
+ u8 ERROR_ODD:1;
+ u8 :5;
+ } fld;
+} I2C_ODD_CSR;
+
+typedef union i2c_config_tag {
+ u8 reg;
+ struct {
+ u8 ACQ_MODE:2;
+ u8 EXT_TRIG_EN:1;
+ u8 EXT_TRIG_POL:1;
+ u8 H_SCALE:1;
+ u8 CLIP:1;
+ u8 PM_LUT_SEL:1;
+ u8 PM_LUT_PGM:1;
+ } fld;
+} I2C_CONFIG;
+
+
+typedef union i2c_ad_cmd_tag {
+ /* bits can have 3 different meanings depending on value of AD_ADDR */
+ u8 reg;
+ /* Bt252 Command Register if AD_ADDR = 00h */
+ struct {
+ u8 :2;
+ u8 SYNC_LVL_SEL:2;
+ u8 SYNC_CNL_SEL:2;
+ u8 DIGITIZE_CNL_SEL1:2;
+ } bt252_command;
+
+ /* Bt252 IOUT0 register if AD_ADDR = 01h */
+ struct {
+ u8 IOUT_DATA:8;
+ } bt252_iout0;
+
+ /* BT252 IOUT1 register if AD_ADDR = 02h */
+ struct {
+ u8 IOUT_DATA:8;
+ } bt252_iout1;
+} I2C_AD_CMD;
+
+
+/***** Global declarations of local copies of boards' 8 bit I2C registers ***/
+
+extern I2C_CSR2 i2c_csr2;
+extern I2C_EVEN_CSR i2c_even_csr;
+extern I2C_ODD_CSR i2c_odd_csr;
+extern I2C_CONFIG i2c_config;
+extern u8 i2c_dt_id;
+extern u8 i2c_x_clip_start;
+extern u8 i2c_y_clip_start;
+extern u8 i2c_x_clip_end;
+extern u8 i2c_y_clip_end;
+extern u8 i2c_ad_addr;
+extern u8 i2c_ad_lut;
+extern I2C_AD_CMD i2c_ad_cmd;
+extern u8 i2c_dig_out;
+extern u8 i2c_pm_lut_addr;
+extern u8 i2c_pm_lut_data;
+
+/* Functions for Global use */
+
+/* access 8-bit IIC registers */
+
+extern int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal);
+extern int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal);
+
+#endif
diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c
new file mode 100644
index 00000000000..09d7d9b8272
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_isr.c
@@ -0,0 +1,516 @@
+/*
+
+Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+ Jason Lapenta, Scott Smedley, Greg Sharp
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; 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.
+
+The DT3155 Device Driver is distributed in 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 the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+ File: dt3155_isr.c
+Purpose: Buffer management routines, and other routines for the ISR
+ (the actual isr is in dt3155_drv.c)
+
+-- Changes --
+
+ Date Programmer Description of changes made
+ -------------------------------------------------------------------
+ 03-Jul-2000 JML n/a
+ 02-Apr-2002 SS Mods to make work with separate allocator
+ module; Merged John Roll's mods to make work with
+ multiple boards.
+ 10-Jul-2002 GCS Complete rewrite of setup_buffers to disallow
+ buffers which span a 4MB boundary.
+ 24-Jul-2002 SS GPL licence.
+ 30-Jul-2002 NJC Added support for buffer loop.
+ 31-Jul-2002 NJC Complete rewrite of buffer management
+ 02-Aug-2002 NJC Including slab.h instead of malloc.h (no warning).
+ Also, allocator_init() now returns allocator_max
+ so cleaned up allocate_buffers() accordingly.
+ 08-Aug-2005 SS port to 2.6 kernel.
+
+*/
+
+#include <asm/system.h>
+#include <linux/gfp.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+
+#include "dt3155.h"
+#include "dt3155_drv.h"
+#include "dt3155_io.h"
+#include "dt3155_isr.h"
+#include "allocator.h"
+
+#define FOUR_MB (0x0400000) /* Can't DMA accross a 4MB boundary!*/
+#define UPPER_10_BITS (0x3FF<<22) /* Can't DMA accross a 4MB boundary!*/
+
+
+/* Pointer into global structure for handling buffers */
+struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS] = {NULL
+#if MAXBOARDS == 2
+ , NULL
+#endif
+};
+
+/******************************************************************************
+ * Simple array based que struct
+ *
+ * Some handy functions using the buffering structure.
+ *****************************************************************************/
+
+
+/***************************
+ * are_empty_buffers
+ * m is minor # of device
+ ***************************/
+inline bool are_empty_buffers( int m )
+{
+ return ( dt3155_fbuffer[ m ]->empty_len );
+}
+
+/**************************
+ * push_empty
+ * m is minor # of device
+ *
+ * This is slightly confusing. The number empty_len is the literal #
+ * of empty buffers. After calling, empty_len-1 is the index into the
+ * empty buffer stack. So, if empty_len == 1, there is one empty buffer,
+ * given by dt3155_fbuffer[m]->empty_buffers[0].
+ * empty_buffers should never fill up, though this is not checked.
+ **************************/
+inline void push_empty( int index, int m )
+{
+ dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ] = index;
+ dt3155_fbuffer[m]->empty_len++;
+}
+
+/**************************
+ * pop_empty( m )
+ * m is minor # of device
+ **************************/
+inline int pop_empty( int m )
+{
+ dt3155_fbuffer[m]->empty_len--;
+ return dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ];
+}
+
+/*************************
+ * is_ready_buf_empty( m )
+ * m is minor # of device
+ *************************/
+inline bool is_ready_buf_empty( int m )
+{
+ return ((dt3155_fbuffer[ m ]->ready_len) == 0);
+}
+
+/*************************
+ * is_ready_buf_full( m )
+ * m is minor # of device
+ * this should *never* be true if there are any active, locked or empty
+ * buffers, since it corresponds to nbuffers ready buffers!!
+ * 7/31/02: total rewrite. --NJC
+ *************************/
+inline bool is_ready_buf_full( int m )
+{
+ return ( dt3155_fbuffer[ m ]->ready_len == dt3155_fbuffer[ m ]->nbuffers );
+}
+
+/*****************************************************
+ * push_ready( m, buffer )
+ * m is minor # of device
+ *
+ *****************************************************/
+inline void push_ready( int m, int index )
+{
+ int head = dt3155_fbuffer[m]->ready_head;
+
+ dt3155_fbuffer[ m ]->ready_que[ head ] = index;
+ dt3155_fbuffer[ m ]->ready_head = ( (head + 1) %
+ (dt3155_fbuffer[ m ]->nbuffers) );
+ dt3155_fbuffer[ m ]->ready_len++;
+
+}
+
+/*****************************************************
+ * get_tail()
+ * m is minor # of device
+ *
+ * Simply comptutes the tail given the head and the length.
+ *****************************************************/
+static inline int get_tail( int m )
+{
+ return ((dt3155_fbuffer[ m ]->ready_head -
+ dt3155_fbuffer[ m ]->ready_len +
+ dt3155_fbuffer[ m ]->nbuffers)%
+ (dt3155_fbuffer[ m ]->nbuffers));
+}
+
+
+
+/*****************************************************
+ * pop_ready()
+ * m is minor # of device
+ *
+ * This assumes that there is a ready buffer ready... should
+ * be checked (e.g. with is_ready_buf_empty() prior to call.
+ *****************************************************/
+inline int pop_ready( int m )
+{
+ int tail;
+ tail = get_tail(m);
+ dt3155_fbuffer[ m ]->ready_len--;
+ return dt3155_fbuffer[ m ]->ready_que[ tail ];
+}
+
+
+/*****************************************************
+ * printques
+ * m is minor # of device
+ *****************************************************/
+inline void printques( int m )
+{
+ int head = dt3155_fbuffer[ m ]->ready_head;
+ int tail;
+ int num = dt3155_fbuffer[ m ]->nbuffers;
+ int frame_index;
+ int index;
+
+ tail = get_tail(m);
+
+ printk("\n R:");
+ for ( index = tail; index != head; index++, index = index % (num) )
+ {
+ frame_index = dt3155_fbuffer[ m ]->ready_que[ index ];
+ printk(" %d ", frame_index );
+ }
+
+ printk("\n E:");
+ for ( index = 0; index < dt3155_fbuffer[ m ]->empty_len; index++ )
+ {
+ frame_index = dt3155_fbuffer[ m ]->empty_buffers[ index ];
+ printk(" %d ", frame_index );
+ }
+
+ frame_index = dt3155_fbuffer[ m ]->active_buf;
+ printk("\n A: %d", frame_index);
+
+ frame_index = dt3155_fbuffer[ m ]->locked_buf;
+ printk("\n L: %d \n", frame_index );
+
+}
+
+/*****************************************************
+ * adjust_4MB
+ *
+ * If a buffer intersects the 4MB boundary, push
+ * the start address up to the beginning of the
+ * next 4MB chunk (assuming bufsize < 4MB).
+ *****************************************************/
+u32 adjust_4MB (u32 buf_addr, u32 bufsize) {
+ if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS))
+ return (buf_addr+bufsize) & UPPER_10_BITS;
+ else
+ return buf_addr;
+}
+
+
+/*****************************************************
+ * allocate_buffers
+ *
+ * Try to allocate enough memory for all requested
+ * buffers. If there is not enough free space
+ * try for less memory.
+ *****************************************************/
+void allocate_buffers (u32 *buf_addr, u32* total_size_kbs,
+ u32 bufsize)
+{
+ /* Compute the minimum amount of memory guaranteed to hold all
+ MAXBUFFERS such that no buffer crosses the 4MB boundary.
+ Store this value in the variable "full_size" */
+
+ u32 allocator_max;
+ u32 bufs_per_chunk = (FOUR_MB / bufsize);
+ u32 filled_chunks = (MAXBUFFERS-1) / bufs_per_chunk;
+ u32 leftover_bufs = MAXBUFFERS - filled_chunks * bufs_per_chunk;
+
+ u32 full_size = bufsize /* possibly unusable part of 1st chunk */
+ + filled_chunks * FOUR_MB /* max # of completely filled 4mb chunks */
+ + leftover_bufs * bufsize; /* these buffs will be in a partly filled
+ chunk at beginning or end */
+
+ u32 full_size_kbs = 1 + (full_size-1) / 1024;
+ u32 min_size_kbs = 2*ndevices*bufsize / 1024;
+ u32 size_kbs;
+
+ /* Now, try to allocate full_size. If this fails, keep trying for
+ less & less memory until it succeeds. */
+#ifndef STANDALONE_ALLOCATOR
+ /* initialize the allocator */
+ allocator_init(&allocator_max);
+#endif
+ size_kbs = full_size_kbs;
+ *buf_addr = 0;
+ printk("DT3155: We would like to get: %d KB\n", full_size_kbs);
+ printk("DT3155: ...but need at least: %d KB\n", min_size_kbs);
+ printk("DT3155: ...the allocator has: %d KB\n", allocator_max);
+ size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max);
+ if (size_kbs > min_size_kbs) {
+ if ((*buf_addr = allocator_allocate_dma (size_kbs, GFP_KERNEL)) != 0) {
+ printk("DT3155: Managed to allocate: %d KB\n", size_kbs);
+ *total_size_kbs = size_kbs;
+ return;
+ }
+ }
+ /* If we got here, the allocation failed */
+ printk ("DT3155: Allocator failed!\n");
+ *buf_addr = 0;
+ *total_size_kbs = 0;
+ return;
+
+}
+
+
+/*****************************************************
+ * dt3155_setup_buffers
+ *
+ * setup_buffers just puts the buffering system into
+ * a consistent state before the start of interrupts
+ *
+ * JML : it looks like all the buffers need to be
+ * continuous. So I'm going to try and allocate one
+ * continuous buffer.
+ *
+ * GCS : Fix DMA problems when buffer spans
+ * 4MB boundary. Also, add error checking. This
+ * function will return -ENOMEM when not enough memory.
+ *****************************************************/
+u32 dt3155_setup_buffers(u32 *allocatorAddr)
+
+{
+ u32 index;
+ u32 rambuff_addr; /* start of allocation */
+ u32 rambuff_size; /* total size allocated to driver */
+ u32 rambuff_acm; /* accumlator, keep track of how much
+ is left after being split up*/
+ u32 rambuff_end; /* end of rambuff */
+ u32 numbufs; /* number of useful buffers allocated (per device) */
+ u32 bufsize = DT3155_MAX_ROWS * DT3155_MAX_COLS;
+ int m; /* minor # of device, looped for all devs */
+
+ /* zero the fbuffer status and address structure */
+ for ( m = 0; m < ndevices; m++)
+ {
+ dt3155_fbuffer[ m ] = &(dt3155_status[ m ].fbuffer);
+
+ /* Make sure the buffering variables are consistent */
+ {
+ u8 *ptr = (u8 *) dt3155_fbuffer[ m ];
+ for( index = 0; index < sizeof(struct dt3155_fbuffer_s); index++)
+ *(ptr++)=0;
+ }
+ }
+
+ /* allocate a large contiguous chunk of RAM */
+ allocate_buffers (&rambuff_addr, &rambuff_size, bufsize);
+ printk("DT3155: mem info\n");
+ printk(" - rambuf_addr = 0x%x \n", rambuff_addr);
+ printk(" - length (kb) = %u \n", rambuff_size);
+ if( rambuff_addr == 0 )
+ {
+ printk( KERN_INFO
+ "DT3155: Error setup_buffers() allocator dma failed \n" );
+ return -ENOMEM;
+ }
+ *allocatorAddr = rambuff_addr;
+ rambuff_end = rambuff_addr + 1024 * rambuff_size;
+
+ /* after allocation, we need to count how many useful buffers there
+ are so we can give an equal number to each device */
+ rambuff_acm = rambuff_addr;
+ for ( index = 0; index < MAXBUFFERS; index++) {
+ rambuff_acm = adjust_4MB (rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/
+ if (rambuff_acm + bufsize > rambuff_end)
+ break;
+ rambuff_acm += bufsize;
+ }
+ /* Following line is OK, will waste buffers if index
+ * not evenly divisible by ndevices -NJC*/
+ numbufs = index / ndevices;
+ printk(" - numbufs = %u\n", numbufs);
+ if (numbufs < 2) {
+ printk( KERN_INFO
+ "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n" );
+ return -ENOMEM;
+ }
+
+ /* now that we have board memory we spit it up */
+ /* between the boards and the buffers */
+ rambuff_acm = rambuff_addr;
+ for ( m = 0; m < ndevices; m ++)
+ {
+ rambuff_acm = adjust_4MB (rambuff_acm, bufsize);
+
+ /* Save the start of this boards buffer space (for mmap). */
+ dt3155_status[ m ].mem_addr = rambuff_acm;
+
+ for (index = 0; index < numbufs; index++)
+ {
+ rambuff_acm = adjust_4MB (rambuff_acm, bufsize);
+ if (rambuff_acm + bufsize > rambuff_end) {
+ /* Should never happen */
+ printk ("DT3155 PROGRAM ERROR (GCS)\n"
+ "Error distributing allocated buffers\n");
+ return -ENOMEM;
+ }
+
+ dt3155_fbuffer[ m ]->frame_info[ index ].addr = rambuff_acm;
+ push_empty( index, m );
+ /* printk(" - Buffer : %lx\n",
+ * dt3155_fbuffer[ m ]->frame_info[ index ].addr );
+ */
+ dt3155_fbuffer[ m ]->nbuffers += 1;
+ rambuff_acm += bufsize;
+ }
+
+ /* Make sure there is an active buffer there. */
+ dt3155_fbuffer[ m ]->active_buf = pop_empty( m );
+ dt3155_fbuffer[ m ]->even_happened = 0;
+ dt3155_fbuffer[ m ]->even_stopped = 0;
+
+ /* make sure there is no locked_buf JML 2/28/00 */
+ dt3155_fbuffer[ m ]->locked_buf = -1;
+
+ dt3155_status[ m ].mem_size =
+ rambuff_acm - dt3155_status[ m ].mem_addr;
+
+ /* setup the ready queue */
+ dt3155_fbuffer[ m ]->ready_head = 0;
+ dt3155_fbuffer[ m ]->ready_len = 0;
+ printk("Available buffers for device %d: %d\n",
+ m, dt3155_fbuffer[ m ]->nbuffers);
+ }
+
+ return 1;
+}
+
+/*****************************************************
+ * internal_release_locked_buffer
+ *
+ * The internal function for releasing a locked buffer.
+ * It assumes interrupts are turned off.
+ *
+ * m is minor number of device
+ *****************************************************/
+static inline void internal_release_locked_buffer( int m )
+{
+ /* Pointer into global structure for handling buffers */
+ if ( dt3155_fbuffer[ m ]->locked_buf >= 0 )
+ {
+ push_empty( dt3155_fbuffer[ m ]->locked_buf, m );
+ dt3155_fbuffer[ m ]->locked_buf = -1;
+ }
+}
+
+
+/*****************************************************
+ * dt3155_release_locked_buffer()
+ * m is minor # of device
+ *
+ * The user function of the above.
+ *
+ *****************************************************/
+inline void dt3155_release_locked_buffer( int m )
+{
+ unsigned long int flags;
+ local_save_flags(flags);
+ local_irq_disable();
+ internal_release_locked_buffer(m);
+ local_irq_restore(flags);
+}
+
+
+/*****************************************************
+ * dt3155_flush()
+ * m is minor # of device
+ *
+ *****************************************************/
+inline int dt3155_flush( int m )
+{
+ int index;
+ unsigned long int flags;
+ local_save_flags(flags);
+ local_irq_disable();
+
+ internal_release_locked_buffer( m );
+ dt3155_fbuffer[ m ]->empty_len = 0;
+
+ for ( index = 0; index < dt3155_fbuffer[ m ]->nbuffers; index++ )
+ push_empty( index, m );
+
+ /* Make sure there is an active buffer there. */
+ dt3155_fbuffer[ m ]->active_buf = pop_empty( m );
+
+ dt3155_fbuffer[ m ]->even_happened = 0;
+ dt3155_fbuffer[ m ]->even_stopped = 0;
+
+ /* setup the ready queue */
+ dt3155_fbuffer[ m ]->ready_head = 0;
+ dt3155_fbuffer[ m ]->ready_len = 0;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+/*****************************************************
+ * dt3155_get_ready_buffer()
+ * m is minor # of device
+ *
+ * get_ready_buffer will grab the next chunk of data
+ * if it is already there, otherwise it returns 0.
+ * If the user has a buffer locked it will unlock
+ * that buffer before returning the new one.
+ *****************************************************/
+inline int dt3155_get_ready_buffer( int m )
+{
+ int frame_index;
+ unsigned long int flags;
+ local_save_flags(flags);
+ local_irq_disable();
+
+#ifdef DEBUG_QUES_A
+ printques( m );
+#endif
+
+ internal_release_locked_buffer( m );
+
+ if (is_ready_buf_empty( m ))
+ frame_index = -1;
+ else
+ {
+ frame_index = pop_ready( m );
+ dt3155_fbuffer[ m ]->locked_buf = frame_index;
+ }
+
+#ifdef DEBUG_QUES_B
+ printques( m );
+#endif
+
+ local_irq_restore(flags);
+
+ return frame_index;
+}
diff --git a/drivers/staging/dt3155/dt3155_isr.h b/drivers/staging/dt3155/dt3155_isr.h
new file mode 100644
index 00000000000..7595cb16c98
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_isr.h
@@ -0,0 +1,77 @@
+/*
+
+Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
+ Jason Lapenta, Scott Smedley
+
+This file is part of the DT3155 Device Driver.
+
+The DT3155 Device Driver is free software; 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.
+
+The DT3155 Device Driver is distributed in 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 the DT3155 Device Driver; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111-1307 USA
+
+
+-- Changes --
+
+ Date Programmer Description of changes made
+ -------------------------------------------------------------------
+ 03-Jul-2000 JML n/a
+ 24-Jul-2002 SS GPL licence.
+ 26-Oct-2009 SS Porting to 2.6.30 kernel.
+
+-- notes --
+
+*/
+
+#ifndef DT3155_ISR_H
+#define DT3155_ISR_H
+
+extern struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS];
+
+/* User functions for buffering */
+/* Initialize the buffering system. This should */
+/* be called prior to enabling interrupts */
+
+u32 dt3155_setup_buffers(u32 *allocatorAddr);
+
+/* Get the next frame of data if it is ready. Returns */
+/* zero if no data is ready. If there is data but */
+/* the user has a locked buffer, it will unlock that */
+/* buffer and return it to the free list. */
+
+int dt3155_get_ready_buffer(int minor);
+
+/* Return a locked buffer to the free list */
+
+void dt3155_release_locked_buffer(int minor);
+
+/* Flush the buffer system */
+int dt3155_flush(int minor);
+
+/**********************************
+ * Simple array based que struct
+ **********************************/
+
+bool are_empty_buffers(int minor);
+void push_empty(int index, int minor);
+
+int pop_empty(int minor);
+
+bool is_ready_buf_empty(int minor);
+bool is_ready_buf_full(int minor);
+
+void push_ready(int minor, int index);
+int pop_ready(int minor);
+
+
+#endif
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h
index e715e4dcb52..ea746ba41fa 100644
--- a/drivers/staging/et131x/et1310_address_map.h
+++ b/drivers/staging/et131x/et1310_address_map.h
@@ -149,7 +149,7 @@
* GLOBAL Module of JAGCore Address Mapping
* Located at address 0x0000
*/
-typedef struct _GLOBAL_t { /* Location: */
+struct global_regs { /* Location: */
u32 txq_start_addr; /* 0x0000 */
u32 txq_end_addr; /* 0x0004 */
u32 rxq_start_addr; /* 0x0008 */
@@ -165,9 +165,7 @@ typedef struct _GLOBAL_t { /* Location: */
u32 msi_config; /* 0x0030 */
u32 loopback; /* 0x0034 */
u32 watchdog_timer; /* 0x0038 */
-} GLOBAL_t, *PGLOBAL_t;
-
-/* END OF GLOBAL REGISTER ADDRESS MAP */
+};
/* START OF TXDMA REGISTER ADDRESS MAP */
@@ -255,7 +253,7 @@ extern inline void add_12bit(u32 *v, int n)
* Tx DMA Module of JAGCore Address Mapping
* Located at address 0x1000
*/
-typedef struct _TXDMA_t { /* Location: */
+struct txdma_regs { /* Location: */
u32 csr; /* 0x1000 */
u32 pr_base_hi; /* 0x1004 */
u32 pr_base_lo; /* 0x1008 */
@@ -282,7 +280,7 @@ typedef struct _TXDMA_t { /* Location: */
u32 DroppedTLPCount; /* 0x105c */
u32 NewServiceComplete; /* 0x1060 */
u32 EthernetPacketCount; /* 0x1064 */
-} TXDMA_t, *PTXDMA_t;
+};
/* END OF TXDMA REGISTER ADDRESS MAP */
@@ -292,45 +290,25 @@ typedef struct _TXDMA_t { /* Location: */
/*
* structure for control status reg in rxdma address map
* Located at address 0x2000
+ *
+ * CSR
+ * 0: halt
+ * 1-3: tc
+ * 4: fbr_big_endian
+ * 5: psr_big_endian
+ * 6: pkt_big_endian
+ * 7: dma_big_endian
+ * 8-9: fbr0_size
+ * 10: fbr0_enable
+ * 11-12: fbr1_size
+ * 13: fbr1_enable
+ * 14: unused
+ * 15: pkt_drop_disable
+ * 16: pkt_done_flush
+ * 17: halt_status
+ * 18-31: unused
*/
-typedef union _RXDMA_CSR_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 unused2:14; /* bits 18-31 */
- u32 halt_status:1; /* bit 17 */
- u32 pkt_done_flush:1; /* bit 16 */
- u32 pkt_drop_disable:1; /* bit 15 */
- u32 unused1:1; /* bit 14 */
- u32 fbr1_enable:1; /* bit 13 */
- u32 fbr1_size:2; /* bits 11-12 */
- u32 fbr0_enable:1; /* bit 10 */
- u32 fbr0_size:2; /* bits 8-9 */
- u32 dma_big_endian:1; /* bit 7 */
- u32 pkt_big_endian:1; /* bit 6 */
- u32 psr_big_endian:1; /* bit 5 */
- u32 fbr_big_endian:1; /* bit 4 */
- u32 tc:3; /* bits 1-3 */
- u32 halt:1; /* bit 0 */
-#else
- u32 halt:1; /* bit 0 */
- u32 tc:3; /* bits 1-3 */
- u32 fbr_big_endian:1; /* bit 4 */
- u32 psr_big_endian:1; /* bit 5 */
- u32 pkt_big_endian:1; /* bit 6 */
- u32 dma_big_endian:1; /* bit 7 */
- u32 fbr0_size:2; /* bits 8-9 */
- u32 fbr0_enable:1; /* bit 10 */
- u32 fbr1_size:2; /* bits 11-12 */
- u32 fbr1_enable:1; /* bit 13 */
- u32 unused1:1; /* bit 14 */
- u32 pkt_drop_disable:1; /* bit 15 */
- u32 pkt_done_flush:1; /* bit 16 */
- u32 halt_status:1; /* bit 17 */
- u32 unused2:14; /* bits 18-31 */
-#endif
- } bits;
-} RXDMA_CSR_t, *PRXDMA_CSR_t;
+
/*
* structure for dma writeback lo reg in rxdma address map
@@ -451,18 +429,6 @@ typedef union _RXDMA_CSR_t {
* 31-10: unused
* 9-0: fbr ndesc
*/
-typedef union _RXDMA_FBR_NUM_DES_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 unused:22; /* bits 10-31 */
- u32 fbr_ndesc:10; /* bits 0-9 */
-#else
- u32 fbr_ndesc:10; /* bits 0-9 */
- u32 unused:22; /* bits 10-31 */
-#endif
- } bits;
-} RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t;
/*
* structure for free buffer ring 0 available offset reg in rxdma address map
@@ -532,8 +498,8 @@ typedef union _RXDMA_FBR_NUM_DES_t {
* Rx DMA Module of JAGCore Address Mapping
* Located at address 0x2000
*/
-typedef struct _RXDMA_t { /* Location: */
- RXDMA_CSR_t csr; /* 0x2000 */
+struct rxdma_regs { /* Location: */
+ u32 csr; /* 0x2000 */
u32 dma_wb_base_lo; /* 0x2004 */
u32 dma_wb_base_hi; /* 0x2008 */
u32 num_pkt_done; /* 0x200C */
@@ -562,7 +528,7 @@ typedef struct _RXDMA_t { /* Location: */
u32 fbr1_full_offset; /* 0x2068 */
u32 fbr1_rd_index; /* 0x206C */
u32 fbr1_min_des; /* 0x2070 */
-} RXDMA_t, *PRXDMA_t;
+};
/* END OF RXDMA REGISTER ADDRESS MAP */
@@ -572,33 +538,18 @@ typedef struct _RXDMA_t { /* Location: */
/*
* structure for control reg in txmac address map
* located at address 0x3000
+ *
+ * bits
+ * 31-8: unused
+ * 7: cklseg_disable
+ * 6: ckbcnt_disable
+ * 5: cksegnum
+ * 4: async_disable
+ * 3: fc_disable
+ * 2: mcif_disable
+ * 1: mif_disable
+ * 0: txmac_en
*/
-typedef union _TXMAC_CTL_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 unused:24; /* bits 8-31 */
- u32 cklseg_diable:1; /* bit 7 */
- u32 ckbcnt_disable:1; /* bit 6 */
- u32 cksegnum:1; /* bit 5 */
- u32 async_disable:1; /* bit 4 */
- u32 fc_disable:1; /* bit 3 */
- u32 mcif_disable:1; /* bit 2 */
- u32 mif_disable:1; /* bit 1 */
- u32 txmac_en:1; /* bit 0 */
-#else
- u32 txmac_en:1; /* bit 0 */
- u32 mif_disable:1; /* bit 1 mac interface */
- u32 mcif_disable:1; /* bit 2 mem. contr. interface */
- u32 fc_disable:1; /* bit 3 */
- u32 async_disable:1; /* bit 4 */
- u32 cksegnum:1; /* bit 5 */
- u32 ckbcnt_disable:1; /* bit 6 */
- u32 cklseg_diable:1; /* bit 7 */
- u32 unused:24; /* bits 8-31 */
-#endif
- } bits;
-} TXMAC_CTL_t, *PTXMAC_CTL_t;
/*
* structure for shadow pointer reg in txmac address map
@@ -612,23 +563,12 @@ typedef union _TXMAC_CTL_t {
/*
* structure for error count reg in txmac address map
* located at address 0x3008
+ *
+ * 31-12: unused
+ * 11-8: reserved
+ * 7-4: txq_underrun
+ * 3-0: fifo_underrun
*/
-typedef union _TXMAC_ERR_CNT_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 unused:20; /* bits 12-31 */
- u32 reserved:4; /* bits 8-11 */
- u32 txq_underrun:4; /* bits 4-7 */
- u32 fifo_underrun:4; /* bits 0-3 */
-#else
- u32 fifo_underrun:4; /* bits 0-3 */
- u32 txq_underrun:4; /* bits 4-7 */
- u32 reserved:4; /* bits 8-11 */
- u32 unused:20; /* bits 12-31 */
-#endif
- } bits;
-} TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t;
/*
* structure for max fill reg in txmac address map
@@ -657,64 +597,32 @@ typedef union _TXMAC_ERR_CNT_t {
/*
* structure for error reg in txmac address map
* located at address 0x3018
+ *
+ * 31-9: unused
+ * 8: fifo_underrun
+ * 7-6: unused
+ * 5: ctrl2_err
+ * 4: txq_underrun
+ * 3: bcnt_err
+ * 2: lseg_err
+ * 1: segnum_err
+ * 0: seg0_err
*/
-typedef union _TXMAC_ERR_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 unused2:23; /* bits 9-31 */
- u32 fifo_underrun:1; /* bit 8 */
- u32 unused1:2; /* bits 6-7 */
- u32 ctrl2_err:1; /* bit 5 */
- u32 txq_underrun:1; /* bit 4 */
- u32 bcnt_err:1; /* bit 3 */
- u32 lseg_err:1; /* bit 2 */
- u32 segnum_err:1; /* bit 1 */
- u32 seg0_err:1; /* bit 0 */
-#else
- u32 seg0_err:1; /* bit 0 */
- u32 segnum_err:1; /* bit 1 */
- u32 lseg_err:1; /* bit 2 */
- u32 bcnt_err:1; /* bit 3 */
- u32 txq_underrun:1; /* bit 4 */
- u32 ctrl2_err:1; /* bit 5 */
- u32 unused1:2; /* bits 6-7 */
- u32 fifo_underrun:1; /* bit 8 */
- u32 unused2:23; /* bits 9-31 */
-#endif
- } bits;
-} TXMAC_ERR_t, *PTXMAC_ERR_t;
/*
* structure for error interrupt reg in txmac address map
* located at address 0x301C
+ *
+ * 31-9: unused
+ * 8: fifo_underrun
+ * 7-6: unused
+ * 5: ctrl2_err
+ * 4: txq_underrun
+ * 3: bcnt_err
+ * 2: lseg_err
+ * 1: segnum_err
+ * 0: seg0_err
*/
-typedef union _TXMAC_ERR_INT_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 unused2:23; /* bits 9-31 */
- u32 fifo_underrun:1; /* bit 8 */
- u32 unused1:2; /* bits 6-7 */
- u32 ctrl2_err:1; /* bit 5 */
- u32 txq_underrun:1; /* bit 4 */
- u32 bcnt_err:1; /* bit 3 */
- u32 lseg_err:1; /* bit 2 */
- u32 segnum_err:1; /* bit 1 */
- u32 seg0_err:1; /* bit 0 */
-#else
- u32 seg0_err:1; /* bit 0 */
- u32 segnum_err:1; /* bit 1 */
- u32 lseg_err:1; /* bit 2 */
- u32 bcnt_err:1; /* bit 3 */
- u32 txq_underrun:1; /* bit 4 */
- u32 ctrl2_err:1; /* bit 5 */
- u32 unused1:2; /* bits 6-7 */
- u32 fifo_underrun:1; /* bit 8 */
- u32 unused2:23; /* bits 9-31 */
-#endif
- } bits;
-} TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t;
/*
* structure for error interrupt reg in txmac address map
@@ -728,17 +636,17 @@ typedef union _TXMAC_ERR_INT_t {
/*
* Tx MAC Module of JAGCore Address Mapping
*/
-typedef struct _TXMAC_t { /* Location: */
- TXMAC_CTL_t ctl; /* 0x3000 */
+struct txmac_regs { /* Location: */
+ u32 ctl; /* 0x3000 */
u32 shadow_ptr; /* 0x3004 */
- TXMAC_ERR_CNT_t err_cnt; /* 0x3008 */
+ u32 err_cnt; /* 0x3008 */
u32 max_fill; /* 0x300C */
u32 cf_param; /* 0x3010 */
u32 tx_test; /* 0x3014 */
- TXMAC_ERR_t err; /* 0x3018 */
- TXMAC_ERR_INT_t err_int; /* 0x301C */
+ u32 err; /* 0x3018 */
+ u32 err_int; /* 0x301C */
u32 bp_ctrl; /* 0x3020 */
-} TXMAC_t, *PTXMAC_t;
+};
/* END OF TXMAC REGISTER ADDRESS MAP */
@@ -747,106 +655,47 @@ typedef struct _TXMAC_t { /* Location: */
/*
* structure for rxmac control reg in rxmac address map
* located at address 0x4000
+ *
+ * 31-7: reserved
+ * 6: rxmac_int_disable
+ * 5: async_disable
+ * 4: mif_disable
+ * 3: wol_disable
+ * 2: pkt_filter_disable
+ * 1: mcif_disable
+ * 0: rxmac_en
*/
-typedef union _RXMAC_CTRL_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserved:25; /* bits 7-31 */
- u32 rxmac_int_disable:1; /* bit 6 */
- u32 async_disable:1; /* bit 5 */
- u32 mif_disable:1; /* bit 4 */
- u32 wol_disable:1; /* bit 3 */
- u32 pkt_filter_disable:1; /* bit 2 */
- u32 mcif_disable:1; /* bit 1 */
- u32 rxmac_en:1; /* bit 0 */
-#else
- u32 rxmac_en:1; /* bit 0 */
- u32 mcif_disable:1; /* bit 1 */
- u32 pkt_filter_disable:1; /* bit 2 */
- u32 wol_disable:1; /* bit 3 */
- u32 mif_disable:1; /* bit 4 */
- u32 async_disable:1; /* bit 5 */
- u32 rxmac_int_disable:1; /* bit 6 */
- u32 reserved:25; /* bits 7-31 */
-#endif
- } bits;
-} RXMAC_CTRL_t, *PRXMAC_CTRL_t;
/*
* structure for Wake On Lan Control and CRC 0 reg in rxmac address map
* located at address 0x4004
+ * 31-16: crc
+ * 15-12: reserved
+ * 11: ignore_pp
+ * 10: ignore_mp
+ * 9: clr_intr
+ * 8: ignore_link_chg
+ * 7: ignore_uni
+ * 6: ignore_multi
+ * 5: ignore_broad
+ * 4-0: valid_crc 4-0
*/
-typedef union _RXMAC_WOL_CTL_CRC0_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 crc0:16; /* bits 16-31 */
- u32 reserve:4; /* bits 12-15 */
- u32 ignore_pp:1; /* bit 11 */
- u32 ignore_mp:1; /* bit 10 */
- u32 clr_intr:1; /* bit 9 */
- u32 ignore_link_chg:1; /* bit 8 */
- u32 ignore_uni:1; /* bit 7 */
- u32 ignore_multi:1; /* bit 6 */
- u32 ignore_broad:1; /* bit 5 */
- u32 valid_crc4:1; /* bit 4 */
- u32 valid_crc3:1; /* bit 3 */
- u32 valid_crc2:1; /* bit 2 */
- u32 valid_crc1:1; /* bit 1 */
- u32 valid_crc0:1; /* bit 0 */
-#else
- u32 valid_crc0:1; /* bit 0 */
- u32 valid_crc1:1; /* bit 1 */
- u32 valid_crc2:1; /* bit 2 */
- u32 valid_crc3:1; /* bit 3 */
- u32 valid_crc4:1; /* bit 4 */
- u32 ignore_broad:1; /* bit 5 */
- u32 ignore_multi:1; /* bit 6 */
- u32 ignore_uni:1; /* bit 7 */
- u32 ignore_link_chg:1; /* bit 8 */
- u32 clr_intr:1; /* bit 9 */
- u32 ignore_mp:1; /* bit 10 */
- u32 ignore_pp:1; /* bit 11 */
- u32 reserve:4; /* bits 12-15 */
- u32 crc0:16; /* bits 16-31 */
-#endif
- } bits;
-} RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t;
/*
* structure for CRC 1 and CRC 2 reg in rxmac address map
* located at address 0x4008
+ *
+ * 31-16: crc2
+ * 15-0: crc1
*/
-typedef union _RXMAC_WOL_CRC12_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 crc2:16; /* bits 16-31 */
- u32 crc1:16; /* bits 0-15 */
-#else
- u32 crc1:16; /* bits 0-15 */
- u32 crc2:16; /* bits 16-31 */
-#endif
- } bits;
-} RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t;
/*
* structure for CRC 3 and CRC 4 reg in rxmac address map
* located at address 0x400C
+ *
+ * 31-16: crc4
+ * 15-0: crc3
*/
-typedef union _RXMAC_WOL_CRC34_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 crc4:16; /* bits 16-31 */
- u32 crc3:16; /* bits 0-15 */
-#else
- u32 crc3:16; /* bits 0-15 */
- u32 crc4:16; /* bits 16-31 */
-#endif
- } bits;
-} RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t;
/*
* structure for Wake On Lan Source Address Lo reg in rxmac address map
@@ -966,164 +815,84 @@ typedef union _RXMAC_UNI_PF_ADDR3_t {
/*
* structure for Packet Filter Control reg in rxmac address map
* located at address 0x4084
+ *
+ * 31-23: unused
+ * 22-16: min_pkt_size
+ * 15-4: unused
+ * 3: filter_frag_en
+ * 2: filter_uni_en
+ * 1: filter_multi_en
+ * 0: filter_broad_en
*/
-typedef union _RXMAC_PF_CTRL_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 unused2:9; /* bits 23-31 */
- u32 min_pkt_size:7; /* bits 16-22 */
- u32 unused1:12; /* bits 4-15 */
- u32 filter_frag_en:1; /* bit 3 */
- u32 filter_uni_en:1; /* bit 2 */
- u32 filter_multi_en:1; /* bit 1 */
- u32 filter_broad_en:1; /* bit 0 */
-#else
- u32 filter_broad_en:1; /* bit 0 */
- u32 filter_multi_en:1; /* bit 1 */
- u32 filter_uni_en:1; /* bit 2 */
- u32 filter_frag_en:1; /* bit 3 */
- u32 unused1:12; /* bits 4-15 */
- u32 min_pkt_size:7; /* bits 16-22 */
- u32 unused2:9; /* bits 23-31 */
-#endif
- } bits;
-} RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t;
/*
* structure for Memory Controller Interface Control Max Segment reg in rxmac
* address map. Located at address 0x4088
+ *
+ * 31-10: reserved
+ * 9-2: max_size
+ * 1: fc_en
+ * 0: seg_en
*/
-typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserved:22; /* bits 10-31 */
- u32 max_size:8; /* bits 2-9 */
- u32 fc_en:1; /* bit 1 */
- u32 seg_en:1; /* bit 0 */
-#else
- u32 seg_en:1; /* bit 0 */
- u32 fc_en:1; /* bit 1 */
- u32 max_size:8; /* bits 2-9 */
- u32 reserved:22; /* bits 10-31 */
-#endif
- } bits;
-} RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t;
/*
* structure for Memory Controller Interface Water Mark reg in rxmac address
* map. Located at address 0x408C
+ *
+ * 31-26: unused
+ * 25-16: mark_hi
+ * 15-10: unused
+ * 9-0: mark_lo
*/
-typedef union _RXMAC_MCIF_WATER_MARK_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserved2:6; /* bits 26-31 */
- u32 mark_hi:10; /* bits 16-25 */
- u32 reserved1:6; /* bits 10-15 */
- u32 mark_lo:10; /* bits 0-9 */
-#else
- u32 mark_lo:10; /* bits 0-9 */
- u32 reserved1:6; /* bits 10-15 */
- u32 mark_hi:10; /* bits 16-25 */
- u32 reserved2:6; /* bits 26-31 */
-#endif
- } bits;
-} RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t;
/*
* structure for Rx Queue Dialog reg in rxmac address map.
* located at address 0x4090
+ *
+ * 31-26: reserved
+ * 25-16: rd_ptr
+ * 15-10: reserved
+ * 9-0: wr_ptr
*/
-typedef union _RXMAC_RXQ_DIAG_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserved2:6; /* bits 26-31 */
- u32 rd_ptr:10; /* bits 16-25 */
- u32 reserved1:6; /* bits 10-15 */
- u32 wr_ptr:10; /* bits 0-9 */
-#else
- u32 wr_ptr:10; /* bits 0-9 */
- u32 reserved1:6; /* bits 10-15 */
- u32 rd_ptr:10; /* bits 16-25 */
- u32 reserved2:6; /* bits 26-31 */
-#endif
- } bits;
-} RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t;
/*
* structure for space availiable reg in rxmac address map.
* located at address 0x4094
+ *
+ * 31-17: reserved
+ * 16: space_avail_en
+ * 15-10: reserved
+ * 9-0: space_avail
*/
-typedef union _RXMAC_SPACE_AVAIL_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserved2:15; /* bits 17-31 */
- u32 space_avail_en:1; /* bit 16 */
- u32 reserved1:6; /* bits 10-15 */
- u32 space_avail:10; /* bits 0-9 */
-#else
- u32 space_avail:10; /* bits 0-9 */
- u32 reserved1:6; /* bits 10-15 */
- u32 space_avail_en:1; /* bit 16 */
- u32 reserved2:15; /* bits 17-31 */
-#endif
- } bits;
-} RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t;
/*
* structure for management interface reg in rxmac address map.
* located at address 0x4098
+ *
+ * 31-18: reserved
+ * 17: drop_pkt_en
+ * 16-0: drop_pkt_mask
*/
-typedef union _RXMAC_MIF_CTL_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserve:14; /* bits 18-31 */
- u32 drop_pkt_en:1; /* bit 17 */
- u32 drop_pkt_mask:17; /* bits 0-16 */
-#else
- u32 drop_pkt_mask:17; /* bits 0-16 */
- u32 drop_pkt_en:1; /* bit 17 */
- u32 reserve:14; /* bits 18-31 */
-#endif
- } bits;
-} RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t;
/*
* structure for Error reg in rxmac address map.
* located at address 0x409C
+ *
+ * 31-4: unused
+ * 3: mif
+ * 2: async
+ * 1: pkt_filter
+ * 0: mcif
*/
-typedef union _RXMAC_ERROR_REG_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserve:28; /* bits 4-31 */
- u32 mif:1; /* bit 3 */
- u32 async:1; /* bit 2 */
- u32 pkt_filter:1; /* bit 1 */
- u32 mcif:1; /* bit 0 */
-#else
- u32 mcif:1; /* bit 0 */
- u32 pkt_filter:1; /* bit 1 */
- u32 async:1; /* bit 2 */
- u32 mif:1; /* bit 3 */
- u32 reserve:28; /* bits 4-31 */
-#endif
- } bits;
-} RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t;
/*
* Rx MAC Module of JAGCore Address Mapping
*/
typedef struct _RXMAC_t { /* Location: */
- RXMAC_CTRL_t ctrl; /* 0x4000 */
- RXMAC_WOL_CTL_CRC0_t crc0; /* 0x4004 */
- RXMAC_WOL_CRC12_t crc12; /* 0x4008 */
- RXMAC_WOL_CRC34_t crc34; /* 0x400C */
+ u32 ctrl; /* 0x4000 */
+ u32 crc0; /* 0x4004 */
+ u32 crc12; /* 0x4008 */
+ u32 crc34; /* 0x400C */
RXMAC_WOL_SA_LO_t sa_lo; /* 0x4010 */
RXMAC_WOL_SA_HI_t sa_hi; /* 0x4014 */
u32 mask0_word0; /* 0x4018 */
@@ -1153,17 +922,17 @@ typedef struct _RXMAC_t { /* Location: */
u32 multi_hash2; /* 0x4078 */
u32 multi_hash3; /* 0x407C */
u32 multi_hash4; /* 0x4080 */
- RXMAC_PF_CTRL_t pf_ctrl; /* 0x4084 */
- RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; /* 0x4088 */
- RXMAC_MCIF_WATER_MARK_t mcif_water_mark; /* 0x408C */
- RXMAC_RXQ_DIAG_t rxq_diag; /* 0x4090 */
- RXMAC_SPACE_AVAIL_t space_avail; /* 0x4094 */
-
- RXMAC_MIF_CTL_t mif_ctrl; /* 0x4098 */
- RXMAC_ERROR_REG_t err_reg; /* 0x409C */
+ u32 pf_ctrl; /* 0x4084 */
+ u32 mcif_ctrl_max_seg; /* 0x4088 */
+ u32 mcif_water_mark; /* 0x408C */
+ u32 rxq_diag; /* 0x4090 */
+ u32 space_avail; /* 0x4094 */
+
+ u32 mif_ctrl; /* 0x4098 */
+ u32 err_reg; /* 0x409C */
} RXMAC_t, *PRXMAC_t;
-/* END OF TXMAC REGISTER ADDRESS MAP */
+/* END OF RXMAC REGISTER ADDRESS MAP */
/* START OF MAC REGISTER ADDRESS MAP */
@@ -1337,37 +1106,19 @@ typedef struct _RXMAC_t { /* Location: */
/*
* structure for Interface Status reg in mac address map.
* located at address 0x503C
+ *
+ * 31-10: reserved
+ * 9: excess_defer
+ * 8: clash
+ * 7: phy_jabber
+ * 6: phy_link_ok
+ * 5: phy_full_duplex
+ * 4: phy_speed
+ * 3: pe100x_link_fail
+ * 2: pe10t_loss_carrier
+ * 1: pe10t_sqe_error
+ * 0: pe10t_jabber
*/
-typedef union _MAC_IF_STAT_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserved:22; /* bits 10-31 */
- u32 excess_defer:1; /* bit 9 */
- u32 clash:1; /* bit 8 */
- u32 phy_jabber:1; /* bit 7 */
- u32 phy_link_ok:1; /* bit 6 */
- u32 phy_full_duplex:1; /* bit 5 */
- u32 phy_speed:1; /* bit 4 */
- u32 pe100x_link_fail:1; /* bit 3 */
- u32 pe10t_loss_carrie:1; /* bit 2 */
- u32 pe10t_sqe_error:1; /* bit 1 */
- u32 pe10t_jabber:1; /* bit 0 */
-#else
- u32 pe10t_jabber:1; /* bit 0 */
- u32 pe10t_sqe_error:1; /* bit 1 */
- u32 pe10t_loss_carrie:1; /* bit 2 */
- u32 pe100x_link_fail:1; /* bit 3 */
- u32 phy_speed:1; /* bit 4 */
- u32 phy_full_duplex:1; /* bit 5 */
- u32 phy_link_ok:1; /* bit 6 */
- u32 phy_jabber:1; /* bit 7 */
- u32 clash:1; /* bit 8 */
- u32 excess_defer:1; /* bit 9 */
- u32 reserved:22; /* bits 10-31 */
-#endif
- } bits;
-} MAC_IF_STAT_t, *PMAC_IF_STAT_t;
/*
* structure for Mac Station Address, Part 1 reg in mac address map.
@@ -1428,7 +1179,7 @@ typedef struct _MAC_t { /* Location: */
u32 mii_mgmt_stat; /* 0x5030 */
u32 mii_mgmt_indicator; /* 0x5034 */
u32 if_ctrl; /* 0x5038 */
- MAC_IF_STAT_t if_stat; /* 0x503C */
+ u32 if_stat; /* 0x503C */
MAC_STATION_ADDR1_t station_addr_1; /* 0x5040 */
MAC_STATION_ADDR2_t station_addr_2; /* 0x5044 */
} MAC_t, *PMAC_t;
@@ -1498,8 +1249,9 @@ typedef struct _MAC_t { /* Location: */
/*
* MAC STATS Module of JAGCore Address Mapping
*/
-typedef struct _MAC_STAT_t { /* Location: */
- u32 pad[32]; /* 0x6000 - 607C */
+struct macstat_regs
+{ /* Location: */
+ u32 pad[32]; /* 0x6000 - 607C */
/* Tx/Rx 0-64 Byte Frame Counter */
u32 TR64; /* 0x6080 */
@@ -1644,7 +1396,7 @@ typedef struct _MAC_STAT_t { /* Location: */
/* Carry Register Two Mask Register */
u32 Carry2M; /* 0x613C */
-} MAC_STAT_t, *PMAC_STAT_t;
+};
/* END OF MAC STAT REGISTER ADDRESS MAP */
@@ -1682,70 +1434,49 @@ typedef struct _MAC_STAT_t { /* Location: */
/*
* Memory Control Module of JAGCore Address Mapping
*/
-typedef struct _MMC_t { /* Location: */
+struct mmc_regs { /* Location: */
u32 mmc_ctrl; /* 0x7000 */
u32 sram_access; /* 0x7004 */
u32 sram_word1; /* 0x7008 */
u32 sram_word2; /* 0x700C */
u32 sram_word3; /* 0x7010 */
u32 sram_word4; /* 0x7014 */
-} MMC_t, *PMMC_t;
+};
/* END OF MMC REGISTER ADDRESS MAP */
-/* START OF EXP ROM REGISTER ADDRESS MAP */
-
-/*
- * Expansion ROM Module of JAGCore Address Mapping
- */
-
-/* Take this out until it is not empty */
-#if 0
-typedef struct _EXP_ROM_t {
-
-} EXP_ROM_t, *PEXP_ROM_t;
-#endif
-
-/* END OF EXP ROM REGISTER ADDRESS MAP */
-
-
/*
* JAGCore Address Mapping
*/
typedef struct _ADDRESS_MAP_t {
- GLOBAL_t global;
+ struct global_regs global;
/* unused section of global address map */
- u8 unused_global[4096 - sizeof(GLOBAL_t)];
- TXDMA_t txdma;
+ u8 unused_global[4096 - sizeof(struct global_regs)];
+ struct txdma_regs txdma;
/* unused section of txdma address map */
- u8 unused_txdma[4096 - sizeof(TXDMA_t)];
- RXDMA_t rxdma;
+ u8 unused_txdma[4096 - sizeof(struct txdma_regs)];
+ struct rxdma_regs rxdma;
/* unused section of rxdma address map */
- u8 unused_rxdma[4096 - sizeof(RXDMA_t)];
- TXMAC_t txmac;
+ u8 unused_rxdma[4096 - sizeof(struct rxdma_regs)];
+ struct txmac_regs txmac;
/* unused section of txmac address map */
- u8 unused_txmac[4096 - sizeof(TXMAC_t)];
+ u8 unused_txmac[4096 - sizeof(struct txmac_regs)];
RXMAC_t rxmac;
/* unused section of rxmac address map */
u8 unused_rxmac[4096 - sizeof(RXMAC_t)];
MAC_t mac;
/* unused section of mac address map */
u8 unused_mac[4096 - sizeof(MAC_t)];
- MAC_STAT_t macStat;
+ struct macstat_regs macstat;
/* unused section of mac stat address map */
- u8 unused_mac_stat[4096 - sizeof(MAC_STAT_t)];
- MMC_t mmc;
+ u8 unused_mac_stat[4096 - sizeof(struct macstat_regs)];
+ struct mmc_regs mmc;
/* unused section of mmc address map */
- u8 unused_mmc[4096 - sizeof(MMC_t)];
+ u8 unused_mmc[4096 - sizeof(struct mmc_regs)];
/* unused section of address map */
u8 unused_[1015808];
-/* Take this out until it is not empty */
-#if 0
- EXP_ROM_t exp_rom;
-#endif
-
u8 unused_exp_rom[4096]; /* MGS-size TBD */
u8 unused__[524288]; /* unused section of address map */
} ADDRESS_MAP_t, *PADDRESS_MAP_t;
diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c
index bcca1f86f51..e4d095b0b52 100644
--- a/drivers/staging/et131x/et1310_eeprom.c
+++ b/drivers/staging/et131x/et1310_eeprom.c
@@ -66,7 +66,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -84,17 +83,42 @@
#include <linux/ioport.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_eeprom.h"
-
#include "et131x_adapter.h"
-#include "et131x_initpci.h"
-#include "et131x_isr.h"
-
-#include "et1310_tx.h"
+#include "et131x.h"
+/*
+ * EEPROM Defines
+ */
+/* LBCIF Register Groups (addressed via 32-bit offsets) */
+#define LBCIF_DWORD0_GROUP 0xAC
+#define LBCIF_DWORD1_GROUP 0xB0
+
+/* LBCIF Registers (addressed via 8-bit offsets) */
+#define LBCIF_ADDRESS_REGISTER 0xAC
+#define LBCIF_DATA_REGISTER 0xB0
+#define LBCIF_CONTROL_REGISTER 0xB1
+#define LBCIF_STATUS_REGISTER 0xB2
+
+/* LBCIF Control Register Bits */
+#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01
+#define LBCIF_CONTROL_PAGE_WRITE 0x02
+#define LBCIF_CONTROL_EEPROM_RELOAD 0x08
+#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20
+#define LBCIF_CONTROL_I2C_WRITE 0x40
+#define LBCIF_CONTROL_LBCIF_ENABLE 0x80
+
+/* LBCIF Status Register Bits */
+#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01
+#define LBCIF_STATUS_I2C_IDLE 0x02
+#define LBCIF_STATUS_ACK_ERROR 0x04
+#define LBCIF_STATUS_GENERAL_ERROR 0x08
+#define LBCIF_STATUS_CHECKSUM_ERROR 0x40
+#define LBCIF_STATUS_EEPROM_PRESENT 0x80
+
+/* Miscellaneous Constraints */
+#define MAX_NUM_REGISTER_POLLS 1000
+#define MAX_NUM_WRITE_RETRIES 2
static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status)
{
diff --git a/drivers/staging/et131x/et1310_eeprom.h b/drivers/staging/et131x/et1310_eeprom.h
deleted file mode 100644
index 6a6c6a632a8..00000000000
--- a/drivers/staging/et131x/et1310_eeprom.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- * http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_eeprom.h - Defines, structs, enums, prototypes, etc. used for EEPROM
- * access routines
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software. Using this
- * software indicates your acceptance of these terms and conditions. If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- * well as in the documentation and/or other materials provided with the
- * distribution.
- *
- * . 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 Agere Systems Inc. nor the names of the contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET1310_EEPROM_H__
-#define __ET1310_EEPROM_H__
-
-#include "et1310_address_map.h"
-
-/*
- * EEPROM Defines
- */
-
-/* LBCIF Register Groups (addressed via 32-bit offsets) */
-#define LBCIF_DWORD0_GROUP 0xAC
-#define LBCIF_DWORD1_GROUP 0xB0
-
-/* LBCIF Registers (addressed via 8-bit offsets) */
-#define LBCIF_ADDRESS_REGISTER 0xAC
-#define LBCIF_DATA_REGISTER 0xB0
-#define LBCIF_CONTROL_REGISTER 0xB1
-#define LBCIF_STATUS_REGISTER 0xB2
-
-/* LBCIF Control Register Bits */
-#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01
-#define LBCIF_CONTROL_PAGE_WRITE 0x02
-#define LBCIF_CONTROL_EEPROM_RELOAD 0x08
-#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20
-#define LBCIF_CONTROL_I2C_WRITE 0x40
-#define LBCIF_CONTROL_LBCIF_ENABLE 0x80
-
-/* LBCIF Status Register Bits */
-#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01
-#define LBCIF_STATUS_I2C_IDLE 0x02
-#define LBCIF_STATUS_ACK_ERROR 0x04
-#define LBCIF_STATUS_GENERAL_ERROR 0x08
-#define LBCIF_STATUS_CHECKSUM_ERROR 0x40
-#define LBCIF_STATUS_EEPROM_PRESENT 0x80
-
-/* Miscellaneous Constraints */
-#define MAX_NUM_REGISTER_POLLS 1000
-#define MAX_NUM_WRITE_RETRIES 2
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-int et131x_init_eeprom(struct et131x_adapter *etdev);
-
-#endif /* _ET1310_EEPROM_H_ */
diff --git a/drivers/staging/et131x/et1310_jagcore.h b/drivers/staging/et131x/et1310_jagcore.h
deleted file mode 100644
index 0807a01d88a..00000000000
--- a/drivers/staging/et131x/et1310_jagcore.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- * http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_jagcore.h - Defines, structs, enums, prototypes, etc. pertaining to
- * the JAGCore
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software. Using this
- * software indicates your acceptance of these terms and conditions. If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- * well as in the documentation and/or other materials provided with the
- * distribution.
- *
- * . 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 Agere Systems Inc. nor the names of the contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET1310_JAGCORE_H__
-#define __ET1310_JAGCORE_H__
-
-#include "et1310_address_map.h"
-
-
-#define INTERNAL_MEM_SIZE 0x400 /* 1024 of internal memory */
-#define INTERNAL_MEM_RX_OFFSET 0x1FF /* 50% Tx, 50% Rx */
-
-/*
- * For interrupts, normal running is:
- * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt,
- * watchdog_interrupt & txdma_xfer_done
- *
- * In both cases, when flow control is enabled for either Tx or bi-direction,
- * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the
- * buffer rings are running low.
- */
-#define INT_MASK_DISABLE 0xffffffff
-
-/* NOTE: Masking out MAC_STAT Interrupt for now...
- * #define INT_MASK_ENABLE 0xfff6bf17
- * #define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7
- */
-#define INT_MASK_ENABLE 0xfffebf17
-#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-void ConfigGlobalRegs(struct et131x_adapter *pAdapter);
-void ConfigMMCRegs(struct et131x_adapter *pAdapter);
-void et131x_enable_interrupts(struct et131x_adapter *adapter);
-void et131x_disable_interrupts(struct et131x_adapter *adapter);
-
-#endif /* __ET1310_JAGCORE_H__ */
diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c
index b8a1f203731..16fa13d4821 100644
--- a/drivers/staging/et131x/et1310_mac.c
+++ b/drivers/staging/et131x/et1310_mac.c
@@ -65,7 +65,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -85,12 +84,19 @@
#include <linux/crc32.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_mac.h"
-
#include "et131x_adapter.h"
-#include "et131x_initpci.h"
+#include "et131x.h"
+
+
+#define COUNTER_WRAP_28_BIT 0x10000000
+#define COUNTER_WRAP_22_BIT 0x400000
+#define COUNTER_WRAP_16_BIT 0x10000
+#define COUNTER_WRAP_12_BIT 0x1000
+
+#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1)
+#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1)
+#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1)
+#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1)
/**
* ConfigMacRegs1 - Initialize the first part of MAC regs
@@ -163,9 +169,9 @@ void ConfigMACRegs2(struct et131x_adapter *etdev)
u32 cfg1;
u32 cfg2;
u32 ifctrl;
- TXMAC_CTL_t ctl;
+ u32 ctl;
- ctl.value = readl(&etdev->regs->txmac.ctl.value);
+ ctl = readl(&etdev->regs->txmac.ctl);
cfg1 = readl(&pMac->cfg1);
cfg2 = readl(&pMac->cfg2);
ifctrl = readl(&pMac->if_ctrl);
@@ -219,9 +225,8 @@ void ConfigMACRegs2(struct et131x_adapter *etdev)
}
/* Enable TXMAC */
- ctl.bits.txmac_en = 0x1;
- ctl.bits.fc_disable = 0x1;
- writel(ctl.value, &etdev->regs->txmac.ctl.value);
+ ctl |= 0x09; /* TX mac enable, FC disable */
+ writel(ctl, &etdev->regs->txmac.ctl);
/* Ready to start the RXDMA/TXDMA engine */
if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) {
@@ -235,15 +240,15 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
struct _RXMAC_t __iomem *pRxMac = &etdev->regs->rxmac;
RXMAC_WOL_SA_LO_t sa_lo;
RXMAC_WOL_SA_HI_t sa_hi;
- RXMAC_PF_CTRL_t pf_ctrl = { 0 };
+ u32 pf_ctrl = 0;
/* Disable the MAC while it is being configured (also disable WOL) */
- writel(0x8, &pRxMac->ctrl.value);
+ writel(0x8, &pRxMac->ctrl);
/* Initialize WOL to disabled. */
- writel(0, &pRxMac->crc0.value);
- writel(0, &pRxMac->crc12.value);
- writel(0, &pRxMac->crc34.value);
+ writel(0, &pRxMac->crc0);
+ writel(0, &pRxMac->crc12);
+ writel(0, &pRxMac->crc34);
/* We need to set the WOL mask0 - mask4 next. We initialize it to
* its default Values of 0x00000000 because there are not WOL masks
@@ -286,12 +291,12 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
writel(sa_hi.value, &pRxMac->sa_hi.value);
/* Disable all Packet Filtering */
- writel(0, &pRxMac->pf_ctrl.value);
+ writel(0, &pRxMac->pf_ctrl);
/* Let's initialize the Unicast Packet filtering address */
if (etdev->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) {
SetupDeviceForUnicast(etdev);
- pf_ctrl.bits.filter_uni_en = 1;
+ pf_ctrl |= 4; /* Unicast filter */
} else {
writel(0, &pRxMac->uni_pf_addr1.value);
writel(0, &pRxMac->uni_pf_addr2.value);
@@ -299,20 +304,16 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
}
/* Let's initialize the Multicast hash */
- if (etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
- pf_ctrl.bits.filter_multi_en = 0;
- } else {
- pf_ctrl.bits.filter_multi_en = 1;
+ if (!(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
+ pf_ctrl |= 2; /* Multicast filter */
SetupDeviceForMulticast(etdev);
}
/* Runt packet filtering. Didn't work in version A silicon. */
- pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4;
- pf_ctrl.bits.filter_frag_en = 1;
-
- if (etdev->RegistryJumboPacket > 8192) {
- RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg;
+ pf_ctrl |= (NIC_MIN_PACKET_SIZE + 4) << 16;
+ pf_ctrl |= 8; /* Fragment filter */
+ if (etdev->RegistryJumboPacket > 8192)
/* In order to transmit jumbo packets greater than 8k, the
* FIFO between RxMAC and RxDMA needs to be reduced in size
* to (16k - Jumbo packet size). In order to implement this,
@@ -320,25 +321,21 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
* packets down into segments which are (max_size * 16). In
* this case we selected 256 bytes, since this is the size of
* the PCI-Express TLP's that the 1310 uses.
+ *
+ * seg_en on, fc_en off, size 0x10
*/
- mcif_ctrl_max_seg.bits.seg_en = 0x1;
- mcif_ctrl_max_seg.bits.fc_en = 0x0;
- mcif_ctrl_max_seg.bits.max_size = 0x10;
-
- writel(mcif_ctrl_max_seg.value,
- &pRxMac->mcif_ctrl_max_seg.value);
- } else {
- writel(0, &pRxMac->mcif_ctrl_max_seg.value);
- }
+ writel(0x41, &pRxMac->mcif_ctrl_max_seg);
+ else
+ writel(0, &pRxMac->mcif_ctrl_max_seg);
/* Initialize the MCIF water marks */
- writel(0, &pRxMac->mcif_water_mark.value);
+ writel(0, &pRxMac->mcif_water_mark);
/* Initialize the MIF control */
- writel(0, &pRxMac->mif_ctrl.value);
+ writel(0, &pRxMac->mif_ctrl);
/* Initialize the Space Available Register */
- writel(0, &pRxMac->space_avail.value);
+ writel(0, &pRxMac->space_avail);
/* Initialize the the mif_ctrl register
* bit 3: Receive code error. One or more nibbles were signaled as
@@ -354,9 +351,9 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
* bit 17: Drop packet enable
*/
if (etdev->linkspeed == TRUEPHY_SPEED_100MBPS)
- writel(0x30038, &pRxMac->mif_ctrl.value);
+ writel(0x30038, &pRxMac->mif_ctrl);
else
- writel(0x30030, &pRxMac->mif_ctrl.value);
+ writel(0x30030, &pRxMac->mif_ctrl);
/* Finally we initialize RxMac to be enabled & WOL disabled. Packet
* filter is always enabled since it is where the runt packets are
@@ -364,28 +361,28 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
* dropping doesn't work, so it is disabled in the pf_ctrl register,
* but we still leave the packet filter on.
*/
- writel(pf_ctrl.value, &pRxMac->pf_ctrl.value);
- writel(0x9, &pRxMac->ctrl.value);
+ writel(pf_ctrl, &pRxMac->pf_ctrl);
+ writel(0x9, &pRxMac->ctrl);
}
void ConfigTxMacRegs(struct et131x_adapter *etdev)
{
- struct _TXMAC_t __iomem *pTxMac = &etdev->regs->txmac;
+ struct txmac_regs *txmac = &etdev->regs->txmac;
/* We need to update the Control Frame Parameters
* cfpt - control frame pause timer set to 64 (0x40)
* cfep - control frame extended pause timer set to 0x0
*/
if (etdev->FlowControl == None)
- writel(0, &pTxMac->cf_param);
+ writel(0, &txmac->cf_param);
else
- writel(0x40, &pTxMac->cf_param);
+ writel(0x40, &txmac->cf_param);
}
void ConfigMacStatRegs(struct et131x_adapter *etdev)
{
- struct _MAC_STAT_t __iomem *macstat =
- &etdev->regs->macStat;
+ struct macstat_regs __iomem *macstat =
+ &etdev->regs->macstat;
/* Next we need to initialize all the MAC_STAT registers to zero on
* the device.
@@ -456,8 +453,8 @@ void ConfigFlowControl(struct et131x_adapter *etdev)
void UpdateMacStatHostCounters(struct et131x_adapter *etdev)
{
struct _ce_stats_t *stats = &etdev->Stats;
- struct _MAC_STAT_t __iomem *macstat =
- &etdev->regs->macStat;
+ struct macstat_regs __iomem *macstat =
+ &etdev->regs->macstat;
stats->collisions += readl(&macstat->TNcl);
stats->first_collision += readl(&macstat->TScl);
@@ -493,11 +490,11 @@ void HandleMacStatInterrupt(struct et131x_adapter *etdev)
/* Read the interrupt bits from the register(s). These are Clear On
* Write.
*/
- Carry1 = readl(&etdev->regs->macStat.Carry1);
- Carry2 = readl(&etdev->regs->macStat.Carry2);
+ Carry1 = readl(&etdev->regs->macstat.Carry1);
+ Carry2 = readl(&etdev->regs->macstat.Carry2);
- writel(Carry1, &etdev->regs->macStat.Carry1);
- writel(Carry2, &etdev->regs->macStat.Carry2);
+ writel(Carry1, &etdev->regs->macstat.Carry1);
+ writel(Carry2, &etdev->regs->macstat.Carry2);
/* We need to do update the host copy of all the MAC_STAT counters.
* For each counter, check it's overflow bit. If the overflow bit is
diff --git a/drivers/staging/et131x/et1310_mac.h b/drivers/staging/et131x/et1310_mac.h
deleted file mode 100644
index 2c385959453..00000000000
--- a/drivers/staging/et131x/et1310_mac.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- * http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_mac.h - Defines, structs, enums, prototypes, etc. pertaining to the
- * MAC.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software. Using this
- * software indicates your acceptance of these terms and conditions. If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- * well as in the documentation and/or other materials provided with the
- * distribution.
- *
- * . 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 Agere Systems Inc. nor the names of the contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 _ET1310_MAC_H_
-#define _ET1310_MAC_H_
-
-
-#include "et1310_address_map.h"
-
-
-#define COUNTER_WRAP_28_BIT 0x10000000
-#define COUNTER_WRAP_22_BIT 0x400000
-#define COUNTER_WRAP_16_BIT 0x10000
-#define COUNTER_WRAP_12_BIT 0x1000
-
-#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1)
-#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1)
-#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1)
-#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1)
-
-#define UPDATE_COUNTER(HostCnt, DevCnt) \
- HostCnt = HostCnt + DevCnt;
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-void ConfigMACRegs1(struct et131x_adapter *adapter);
-void ConfigMACRegs2(struct et131x_adapter *adapter);
-void ConfigRxMacRegs(struct et131x_adapter *adapter);
-void ConfigTxMacRegs(struct et131x_adapter *adapter);
-void ConfigMacStatRegs(struct et131x_adapter *adapter);
-void ConfigFlowControl(struct et131x_adapter *adapter);
-void UpdateMacStatHostCounters(struct et131x_adapter *adapter);
-void HandleMacStatInterrupt(struct et131x_adapter *adapter);
-void SetupDeviceForMulticast(struct et131x_adapter *adapter);
-void SetupDeviceForUnicast(struct et131x_adapter *adapter);
-
-#endif /* _ET1310_MAC_H_ */
diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c
index 6ecad619f77..34cd5d1b586 100644
--- a/drivers/staging/et131x/et1310_phy.c
+++ b/drivers/staging/et131x/et1310_phy.c
@@ -66,7 +66,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -85,17 +84,14 @@
#include <linux/random.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
#include "et131x_adapter.h"
-#include "et131x_netdev.h"
-#include "et131x_initpci.h"
#include "et1310_address_map.h"
#include "et1310_tx.h"
#include "et1310_rx.h"
-#include "et1310_mac.h"
+
+#include "et131x.h"
/* Prototypes for functions with local scope */
static void et131x_xcvr_init(struct et131x_adapter *etdev);
diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h
index 758b9b25171..47907ba7601 100644
--- a/drivers/staging/et131x/et1310_phy.h
+++ b/drivers/staging/et131x/et1310_phy.h
@@ -736,32 +736,8 @@ typedef union _MI_LCR2_t {
/* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
/* Prototypes for ET1310_phy.c */
-int et131x_xcvr_find(struct et131x_adapter *adapter);
-void et131x_setphy_normal(struct et131x_adapter *adapter);
-
-/* static inline function does not work because et131x_adapter is not always
- * defined
- */
-int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr,
- u8 xcvrReg, u16 *value);
-#define MiRead(adapter, xcvrReg, value) \
- PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value))
-
-int32_t MiWrite(struct et131x_adapter *adapter,
- u8 xcvReg, u16 value);
-void et131x_Mii_check(struct et131x_adapter *pAdapter,
- MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints);
-
-/* This last is not strictly required (the driver could call the TPAL
- * version instead), but this sets the adapter up correctly, and calls the
- * access routine indirectly. This protects the driver from changes in TPAL.
- */
-void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
-
/* Defines for PHY access routines */
/* Define bit operation flags */
@@ -843,14 +819,4 @@ void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
/* #define TRU_VMI_LINK_CONTROL_REGISTER 29 */
/* #define TRU_VMI_TIMING_CONTROL_REGISTER */
-/* Prototypes for PHY access routines */
-void ET1310_PhyInit(struct et131x_adapter *adapter);
-void ET1310_PhyReset(struct et131x_adapter *adapter);
-void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down);
-void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter,
- u16 duplex);
-void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
- u16 action,
- u16 regnum, u16 bitnum, u8 *value);
-
#endif /* _ET1310_PHY_H_ */
diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c
index 7d077235929..c64bb2c6d0d 100644
--- a/drivers/staging/et131x/et1310_pm.c
+++ b/drivers/staging/et131x/et1310_pm.c
@@ -65,7 +65,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -83,13 +82,9 @@
#include <linux/ioport.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_mac.h"
#include "et1310_rx.h"
-
#include "et131x_adapter.h"
-#include "et131x_initpci.h"
+#include "et131x.h"
/**
* EnablePhyComa - called when network cable is unplugged
diff --git a/drivers/staging/et131x/et1310_pm.h b/drivers/staging/et131x/et1310_pm.h
deleted file mode 100644
index 295f3ab132f..00000000000
--- a/drivers/staging/et131x/et1310_pm.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- * http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_pm.h - Defines, structs, enums, prototypes, etc. pertaining to power
- * management.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software. Using this
- * software indicates your acceptance of these terms and conditions. If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- * well as in the documentation and/or other materials provided with the
- * distribution.
- *
- * . 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 Agere Systems Inc. nor the names of the contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 _ET1310_PM_H_
-#define _ET1310_PM_H_
-
-#include "et1310_address_map.h"
-
-typedef struct _MP_POWER_MGMT {
- /* variable putting the phy into coma mode when boot up with no cable
- * plugged in after 5 seconds
- */
- u8 TransPhyComaModeOnBoot;
-
- /* Next two used to save power information at power down. This
- * information will be used during power up to set up parts of Power
- * Management in JAGCore
- */
- u16 PowerDownSpeed;
- u8 PowerDownDuplex;
-} MP_POWER_MGMT, *PMP_POWER_MGMT;
-
-/* Forward declaration of the private adapter structure
- */
-struct et131x_adapter;
-
-void EnablePhyComa(struct et131x_adapter *adapter);
-void DisablePhyComa(struct et131x_adapter *adapter);
-
-#endif /* _ET1310_PM_H_ */
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index 81c1a7478ad..54686e2ace6 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -84,14 +84,9 @@
#include <linux/ioport.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-
#include "et131x_adapter.h"
-#include "et131x_initpci.h"
-
#include "et1310_rx.h"
-
+#include "et131x.h"
void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd);
@@ -109,17 +104,16 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
u32 i, j;
u32 bufsize;
u32 pktStatRingSize, FBRChunkSize;
- RX_RING_t *rx_ring;
+ struct rx_ring *rx_ring;
/* Setup some convenience pointers */
- rx_ring = (RX_RING_t *) &adapter->RxRing;
+ rx_ring = &adapter->rx_ring;
/* Alloc memory for the lookup table */
#ifdef USE_FBR0
- rx_ring->Fbr[0] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL);
+ rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
#endif
-
- rx_ring->Fbr[1] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL);
+ rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
/* The first thing we will do is configure the sizes of the buffer
* rings. These will change based on jumbo packet support. Larger
@@ -163,14 +157,14 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
}
#ifdef USE_FBR0
- adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr0NumEntries +
- adapter->RxRing.Fbr1NumEntries;
+ adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr0NumEntries +
+ adapter->rx_ring.Fbr1NumEntries;
#else
- adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr1NumEntries;
+ adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr1NumEntries;
#endif
/* Allocate an area of memory for Free Buffer Ring 1 */
- bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff;
+ bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) + 0xfff;
rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev,
bufsize,
&rx_ring->pFbr1RingPa);
@@ -194,12 +188,12 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
&rx_ring->Fbr1Realpa,
&rx_ring->Fbr1offset, 0x0FFF);
- rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa +
+ rx_ring->pFbr1RingVa = (void *)((u8 *) rx_ring->pFbr1RingVa +
rx_ring->Fbr1offset);
#ifdef USE_FBR0
/* Allocate an area of memory for Free Buffer Ring 0 */
- bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff;
+ bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) + 0xfff;
rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev,
bufsize,
&rx_ring->pFbr0RingPa);
@@ -223,7 +217,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
&rx_ring->Fbr0Realpa,
&rx_ring->Fbr0offset, 0x0FFF);
- rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa +
+ rx_ring->pFbr0RingVa = (void *)((u8 *) rx_ring->pFbr0RingVa +
rx_ring->Fbr0offset);
#endif
@@ -270,23 +264,23 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
/* Save the Virtual address of this index for quick
* access later
*/
- rx_ring->Fbr[1]->Va[index] =
- (uint8_t *) rx_ring->Fbr1MemVa[i] +
+ rx_ring->fbr[1]->virt[index] =
+ (u8 *) rx_ring->Fbr1MemVa[i] +
(j * rx_ring->Fbr1BufferSize) + Fbr1Offset;
/* now store the physical address in the descriptor
* so the device can access it
*/
- rx_ring->Fbr[1]->PAHigh[index] =
+ rx_ring->fbr[1]->bus_high[index] =
(u32) (Fbr1TempPa >> 32);
- rx_ring->Fbr[1]->PALow[index] = (u32) Fbr1TempPa;
+ rx_ring->fbr[1]->bus_low[index] = (u32) Fbr1TempPa;
Fbr1TempPa += rx_ring->Fbr1BufferSize;
- rx_ring->Fbr[1]->Buffer1[index] =
- rx_ring->Fbr[1]->Va[index];
- rx_ring->Fbr[1]->Buffer2[index] =
- rx_ring->Fbr[1]->Va[index] - 4;
+ rx_ring->fbr[1]->buffer1[index] =
+ rx_ring->fbr[1]->virt[index];
+ rx_ring->fbr[1]->buffer2[index] =
+ rx_ring->fbr[1]->virt[index] - 4;
}
}
@@ -319,27 +313,27 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
for (j = 0; j < FBR_CHUNKS; j++) {
u32 index = (i * FBR_CHUNKS) + j;
- rx_ring->Fbr[0]->Va[index] =
- (uint8_t *) rx_ring->Fbr0MemVa[i] +
+ rx_ring->fbr[0]->virt[index] =
+ (u8 *) rx_ring->Fbr0MemVa[i] +
(j * rx_ring->Fbr0BufferSize) + Fbr0Offset;
- rx_ring->Fbr[0]->PAHigh[index] =
+ rx_ring->fbr[0]->bus_high[index] =
(u32) (Fbr0TempPa >> 32);
- rx_ring->Fbr[0]->PALow[index] = (u32) Fbr0TempPa;
+ rx_ring->fbr[0]->bus_low[index] = (u32) Fbr0TempPa;
Fbr0TempPa += rx_ring->Fbr0BufferSize;
- rx_ring->Fbr[0]->Buffer1[index] =
- rx_ring->Fbr[0]->Va[index];
- rx_ring->Fbr[0]->Buffer2[index] =
- rx_ring->Fbr[0]->Va[index] - 4;
+ rx_ring->fbr[0]->buffer1[index] =
+ rx_ring->fbr[0]->virt[index];
+ rx_ring->fbr[0]->buffer2[index] =
+ rx_ring->fbr[0]->virt[index] - 4;
}
}
#endif
/* Allocate an area of memory for FIFO of Packet Status ring entries */
pktStatRingSize =
- sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries;
+ sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries;
rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev,
pktStatRingSize,
@@ -360,16 +354,16 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
*/
/* Allocate an area of memory for writeback of status information */
- rx_ring->pRxStatusVa = pci_alloc_consistent(adapter->pdev,
- sizeof(RX_STATUS_BLOCK_t),
- &rx_ring->pRxStatusPa);
- if (!rx_ring->pRxStatusVa) {
+ rx_ring->rx_status_block = pci_alloc_consistent(adapter->pdev,
+ sizeof(struct rx_status_block),
+ &rx_ring->rx_status_bus);
+ if (!rx_ring->rx_status_block) {
dev_err(&adapter->pdev->dev,
"Cannot alloc memory for Status Block\n");
return -ENOMEM;
}
rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD;
- printk("PRS %lx\n", (unsigned long)rx_ring->pRxStatusPa);
+ printk("PRS %lx\n", (unsigned long)rx_ring->rx_status_bus);
/* Recv
* pci_pool_create initializes a lookaside list. After successful
@@ -403,10 +397,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
u32 bufsize;
u32 pktStatRingSize;
PMP_RFD rfd;
- RX_RING_t *rx_ring;
+ struct rx_ring *rx_ring;
/* Setup some convenience pointers */
- rx_ring = (RX_RING_t *) &adapter->RxRing;
+ rx_ring = &adapter->rx_ring;
/* Free RFDs and associated packet descriptors */
WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd);
@@ -417,7 +411,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
list_del(&rfd->list_node);
rfd->Packet = NULL;
- kmem_cache_free(adapter->RxRing.RecvLookaside, rfd);
+ kmem_cache_free(adapter->rx_ring.RecvLookaside, rfd);
}
/* Free Free Buffer Ring 1 */
@@ -447,15 +441,14 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
}
/* Now the FIFO itself */
- rx_ring->pFbr1RingVa = (void *)((uint8_t *)
+ rx_ring->pFbr1RingVa = (void *)((u8 *)
rx_ring->pFbr1RingVa - rx_ring->Fbr1offset);
- bufsize =
- (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff;
+ bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries)
+ + 0xfff;
- pci_free_consistent(adapter->pdev,
- bufsize,
- rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa);
+ pci_free_consistent(adapter->pdev, bufsize,
+ rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa);
rx_ring->pFbr1RingVa = NULL;
}
@@ -481,11 +474,11 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
}
/* Now the FIFO itself */
- rx_ring->pFbr0RingVa = (void *)((uint8_t *)
+ rx_ring->pFbr0RingVa = (void *)((u8 *)
rx_ring->pFbr0RingVa - rx_ring->Fbr0offset);
- bufsize =
- (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff;
+ bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries)
+ + 0xfff;
pci_free_consistent(adapter->pdev,
bufsize,
@@ -498,7 +491,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
/* Free Packet Status Ring */
if (rx_ring->pPSRingVa) {
pktStatRingSize =
- sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries;
+ sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries;
pci_free_consistent(adapter->pdev, pktStatRingSize,
rx_ring->pPSRingVa, rx_ring->pPSRingPa);
@@ -507,12 +500,11 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
}
/* Free area of memory for the writeback of status information */
- if (rx_ring->pRxStatusVa) {
+ if (rx_ring->rx_status_block) {
pci_free_consistent(adapter->pdev,
- sizeof(RX_STATUS_BLOCK_t),
- rx_ring->pRxStatusVa, rx_ring->pRxStatusPa);
-
- rx_ring->pRxStatusVa = NULL;
+ sizeof(struct rx_status_block),
+ rx_ring->rx_status_block, rx_ring->rx_status_bus);
+ rx_ring->rx_status_block = NULL;
}
/* Free receive buffer pool */
@@ -527,10 +519,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
/* Free the FBR Lookup Table */
#ifdef USE_FBR0
- kfree(rx_ring->Fbr[0]);
+ kfree(rx_ring->fbr[0]);
#endif
- kfree(rx_ring->Fbr[1]);
+ kfree(rx_ring->fbr[1]);
/* Reset Counters */
rx_ring->nReadyRecv = 0;
@@ -548,10 +540,10 @@ int et131x_init_recv(struct et131x_adapter *adapter)
PMP_RFD rfd = NULL;
u32 rfdct;
u32 numrfd = 0;
- RX_RING_t *rx_ring = NULL;
+ struct rx_ring *rx_ring;
/* Setup some convenience pointers */
- rx_ring = (RX_RING_t *) &adapter->RxRing;
+ rx_ring = &adapter->rx_ring;
/* Setup each RFD */
for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) {
@@ -594,9 +586,9 @@ int et131x_init_recv(struct et131x_adapter *adapter)
*/
void ConfigRxDmaRegs(struct et131x_adapter *etdev)
{
- struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma;
- struct _rx_ring_t *rx_local = &etdev->RxRing;
- PFBR_DESC_t fbr_entry;
+ struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma;
+ struct rx_ring *rx_local = &etdev->rx_ring;
+ struct fbr_desc *fbr_entry;
u32 entry;
u32 psr_num_des;
unsigned long flags;
@@ -611,11 +603,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev)
* are ever returned, make sure the high part is retrieved here
* before storing the adjusted address.
*/
- writel((u32) ((u64)rx_local->pRxStatusPa >> 32),
+ writel((u32) ((u64)rx_local->rx_status_bus >> 32),
&rx_dma->dma_wb_base_hi);
- writel((u32) rx_local->pRxStatusPa, &rx_dma->dma_wb_base_lo);
+ writel((u32) rx_local->rx_status_bus, &rx_dma->dma_wb_base_lo);
- memset(rx_local->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t));
+ memset(rx_local->rx_status_block, 0, sizeof(struct rx_status_block));
/* Set the address and parameters of the packet status ring into the
* 1310's registers
@@ -636,11 +628,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev)
rx_local->local_psr_full = 0;
/* Now's the best time to initialize FBR1 contents */
- fbr_entry = (PFBR_DESC_t) rx_local->pFbr1RingVa;
+ fbr_entry = (struct fbr_desc *) rx_local->pFbr1RingVa;
for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) {
- fbr_entry->addr_hi = rx_local->Fbr[1]->PAHigh[entry];
- fbr_entry->addr_lo = rx_local->Fbr[1]->PALow[entry];
- fbr_entry->word2.bits.bi = entry;
+ fbr_entry->addr_hi = rx_local->fbr[1]->bus_high[entry];
+ fbr_entry->addr_lo = rx_local->fbr[1]->bus_low[entry];
+ fbr_entry->word2 = entry;
fbr_entry++;
}
@@ -661,11 +653,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev)
#ifdef USE_FBR0
/* Now's the best time to initialize FBR0 contents */
- fbr_entry = (PFBR_DESC_t) rx_local->pFbr0RingVa;
+ fbr_entry = (struct fbr_desc *) rx_local->pFbr0RingVa;
for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) {
- fbr_entry->addr_hi = rx_local->Fbr[0]->PAHigh[entry];
- fbr_entry->addr_lo = rx_local->Fbr[0]->PALow[entry];
- fbr_entry->word2.bits.bi = entry;
+ fbr_entry->addr_hi = rx_local->fbr[0]->bus_high[entry];
+ fbr_entry->addr_lo = rx_local->fbr[0]->bus_low[entry];
+ fbr_entry->word2 = entry;
fbr_entry++;
}
@@ -721,18 +713,17 @@ void SetRxDmaTimer(struct et131x_adapter *etdev)
*/
void et131x_rx_dma_disable(struct et131x_adapter *etdev)
{
- RXDMA_CSR_t csr;
-
+ u32 csr;
/* Setup the receive dma configuration register */
- writel(0x00002001, &etdev->regs->rxdma.csr.value);
- csr.value = readl(&etdev->regs->rxdma.csr.value);
- if (csr.bits.halt_status != 1) {
+ writel(0x00002001, &etdev->regs->rxdma.csr);
+ csr = readl(&etdev->regs->rxdma.csr);
+ if ((csr & 0x00020000) != 1) { /* Check halt status (bit 17) */
udelay(5);
- csr.value = readl(&etdev->regs->rxdma.csr.value);
- if (csr.bits.halt_status != 1)
+ csr = readl(&etdev->regs->rxdma.csr);
+ if ((csr & 0x00020000) != 1)
dev_err(&etdev->pdev->dev,
- "RX Dma failed to enter halt state. CSR 0x%08x\n",
- csr.value);
+ "RX Dma failed to enter halt state. CSR 0x%08x\n",
+ csr);
}
}
@@ -743,34 +734,33 @@ void et131x_rx_dma_disable(struct et131x_adapter *etdev)
void et131x_rx_dma_enable(struct et131x_adapter *etdev)
{
/* Setup the receive dma configuration register for normal operation */
- RXDMA_CSR_t csr = { 0 };
-
- csr.bits.fbr1_enable = 1;
- if (etdev->RxRing.Fbr1BufferSize == 4096)
- csr.bits.fbr1_size = 1;
- else if (etdev->RxRing.Fbr1BufferSize == 8192)
- csr.bits.fbr1_size = 2;
- else if (etdev->RxRing.Fbr1BufferSize == 16384)
- csr.bits.fbr1_size = 3;
+ u32 csr = 0x2000; /* FBR1 enable */
+
+ if (etdev->rx_ring.Fbr1BufferSize == 4096)
+ csr |= 0x0800;
+ else if (etdev->rx_ring.Fbr1BufferSize == 8192)
+ csr |= 0x1000;
+ else if (etdev->rx_ring.Fbr1BufferSize == 16384)
+ csr |= 0x1800;
#ifdef USE_FBR0
- csr.bits.fbr0_enable = 1;
- if (etdev->RxRing.Fbr0BufferSize == 256)
- csr.bits.fbr0_size = 1;
- else if (etdev->RxRing.Fbr0BufferSize == 512)
- csr.bits.fbr0_size = 2;
- else if (etdev->RxRing.Fbr0BufferSize == 1024)
- csr.bits.fbr0_size = 3;
+ csr |= 0x0400; /* FBR0 enable */
+ if (etdev->rx_ring.Fbr0BufferSize == 256)
+ csr |= 0x0100;
+ else if (etdev->rx_ring.Fbr0BufferSize == 512)
+ csr |= 0x0200;
+ else if (etdev->rx_ring.Fbr0BufferSize == 1024)
+ csr |= 0x0300;
#endif
- writel(csr.value, &etdev->regs->rxdma.csr.value);
+ writel(csr, &etdev->regs->rxdma.csr);
- csr.value = readl(&etdev->regs->rxdma.csr.value);
- if (csr.bits.halt_status != 0) {
+ csr = readl(&etdev->regs->rxdma.csr);
+ if ((csr & 0x00020000) != 0) {
udelay(5);
- csr.value = readl(&etdev->regs->rxdma.csr.value);
- if (csr.bits.halt_status != 0) {
+ csr = readl(&etdev->regs->rxdma.csr);
+ if ((csr & 0x00020000) != 0) {
dev_err(&etdev->pdev->dev,
"RX Dma failed to exit halt state. CSR 0x%08x\n",
- csr.value);
+ csr);
}
}
}
@@ -788,46 +778,44 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev)
*/
PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
{
- struct _rx_ring_t *rx_local = &etdev->RxRing;
- PRX_STATUS_BLOCK_t status;
- PPKT_STAT_DESC_t psr;
+ struct rx_ring *rx_local = &etdev->rx_ring;
+ struct rx_status_block *status;
+ struct pkt_stat_desc *psr;
PMP_RFD rfd;
u32 i;
- uint8_t *buf;
+ u8 *buf;
unsigned long flags;
struct list_head *element;
- uint8_t rindex;
- uint16_t bindex;
+ u8 rindex;
+ u16 bindex;
u32 len;
- PKT_STAT_DESC_WORD0_t Word0;
+ u32 word0;
+ u32 word1;
/* RX Status block is written by the DMA engine prior to every
* interrupt. It contains the next to be used entry in the Packet
* Status Ring, and also the two Free Buffer rings.
*/
- status = (PRX_STATUS_BLOCK_t) rx_local->pRxStatusVa;
+ status = rx_local->rx_status_block;
+ word1 = status->Word1 >> 16; /* Get the useful bits */
- /* FIXME: tidy later when conversions complete */
- if (status->Word1.bits.PSRoffset ==
- (rx_local->local_psr_full & 0xFFF) &&
- status->Word1.bits.PSRwrap ==
- ((rx_local->local_psr_full >> 12) & 1)) {
+ /* Check the PSR and wrap bits do not match */
+ if ((word1 & 0x1FFF) == (rx_local->local_psr_full & 0x1FFF))
/* Looks like this ring is not updated yet */
return NULL;
- }
/* The packet status ring indicates that data is available. */
- psr = (PPKT_STAT_DESC_t) (rx_local->pPSRingVa) +
+ psr = (struct pkt_stat_desc *) (rx_local->pPSRingVa) +
(rx_local->local_psr_full & 0xFFF);
/* Grab any information that is required once the PSR is
* advanced, since we can no longer rely on the memory being
* accurate
*/
- len = psr->word1.bits.length;
- rindex = (uint8_t) psr->word1.bits.ri;
- bindex = (uint16_t) psr->word1.bits.bi;
- Word0 = psr->word0;
+ len = psr->word1 & 0xFFFF;
+ rindex = (psr->word1 >> 26) & 0x03;
+ bindex = (psr->word1 >> 16) & 0x3FF;
+ word0 = psr->word0;
/* Indicate that we have used this PSR entry. */
/* FIXME wrap 12 */
@@ -842,9 +830,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
&etdev->regs->rxdma.psr_full_offset);
#ifndef USE_FBR0
- if (rindex != 1) {
+ if (rindex != 1)
return NULL;
- }
#endif
#ifdef USE_FBR0
@@ -899,7 +886,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
if (len) {
if (etdev->ReplicaPhyLoopbk == 1) {
- buf = rx_local->Fbr[rindex]->Va[bindex];
+ buf = rx_local->fbr[rindex]->virt[bindex];
if (memcmp(&buf[6], &etdev->CurrentAddress[0],
ETH_ALEN) == 0) {
@@ -911,8 +898,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
}
/* Determine if this is a multicast packet coming in */
- if ((Word0.value & ALCATEL_MULTICAST_PKT) &&
- !(Word0.value & ALCATEL_BROADCAST_PKT)) {
+ if ((word0 & ALCATEL_MULTICAST_PKT) &&
+ !(word0 & ALCATEL_BROADCAST_PKT)) {
/* Promiscuous mode and Multicast mode are
* not mutually exclusive as was first
* thought. I guess Promiscuous is just
@@ -923,8 +910,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST)
&& !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS)
&& !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
- buf = rx_local->Fbr[rindex]->
- Va[bindex];
+ buf = rx_local->fbr[rindex]->
+ virt[bindex];
/* Loop through our list to see if the
* destination address of this packet
@@ -963,7 +950,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
if (len > 0)
etdev->Stats.multircv++;
- } else if (Word0.value & ALCATEL_BROADCAST_PKT)
+ } else if (word0 & ALCATEL_BROADCAST_PKT)
etdev->Stats.brdcstrcv++;
else
/* Not sure what this counter measures in
@@ -990,7 +977,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
etdev->net_stats.rx_bytes += rfd->PacketSize;
memcpy(skb_put(skb, rfd->PacketSize),
- rx_local->Fbr[rindex]->Va[bindex],
+ rx_local->fbr[rindex]->virt[bindex],
rfd->PacketSize);
skb->dev = etdev->netdev;
@@ -1014,7 +1001,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
*/
void et131x_reset_recv(struct et131x_adapter *etdev)
{
- WARN_ON(list_empty(&etdev->RxRing.RecvList));
+ WARN_ON(list_empty(&etdev->rx_ring.RecvList));
}
@@ -1032,8 +1019,8 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
/* Process up to available RFD's */
while (count < NUM_PACKETS_HANDLED) {
- if (list_empty(&etdev->RxRing.RecvList)) {
- WARN_ON(etdev->RxRing.nReadyRecv != 0);
+ if (list_empty(&etdev->rx_ring.RecvList)) {
+ WARN_ON(etdev->rx_ring.nReadyRecv != 0);
done = false;
break;
}
@@ -1058,7 +1045,7 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
etdev->Stats.ipackets++;
/* Set the status on the packet, either resources or success */
- if (etdev->RxRing.nReadyRecv < RFD_LOW_WATER_MARK) {
+ if (etdev->rx_ring.nReadyRecv < RFD_LOW_WATER_MARK) {
dev_warn(&etdev->pdev->dev,
"RFD's are running out\n");
}
@@ -1066,12 +1053,12 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
}
if (count == NUM_PACKETS_HANDLED || !done) {
- etdev->RxRing.UnfinishedReceives = true;
+ etdev->rx_ring.UnfinishedReceives = true;
writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO,
&etdev->regs->global.watchdog_timer);
} else
/* Watchdog timer will disable itself if appropriate. */
- etdev->RxRing.UnfinishedReceives = false;
+ etdev->rx_ring.UnfinishedReceives = false;
}
static inline u32 bump_fbr(u32 *fbr, u32 limit)
@@ -1099,10 +1086,10 @@ static inline u32 bump_fbr(u32 *fbr, u32 limit)
*/
void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
{
- struct _rx_ring_t *rx_local = &etdev->RxRing;
- struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma;
- uint16_t bi = rfd->bufferindex;
- uint8_t ri = rfd->ringindex;
+ struct rx_ring *rx_local = &etdev->rx_ring;
+ struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma;
+ u16 bi = rfd->bufferindex;
+ u8 ri = rfd->ringindex;
unsigned long flags;
/* We don't use any of the OOB data besides status. Otherwise, we
@@ -1116,17 +1103,17 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
spin_lock_irqsave(&etdev->FbrLock, flags);
if (ri == 1) {
- PFBR_DESC_t next =
- (PFBR_DESC_t) (rx_local->pFbr1RingVa) +
- INDEX10(rx_local->local_Fbr1_full);
+ struct fbr_desc *next =
+ (struct fbr_desc *) (rx_local->pFbr1RingVa) +
+ INDEX10(rx_local->local_Fbr1_full);
/* Handle the Free Buffer Ring advancement here. Write
* the PA / Buffer Index for the returned buffer into
* the oldest (next to be freed)FBR entry
*/
- next->addr_hi = rx_local->Fbr[1]->PAHigh[bi];
- next->addr_lo = rx_local->Fbr[1]->PALow[bi];
- next->word2.value = bi;
+ next->addr_hi = rx_local->fbr[1]->bus_high[bi];
+ next->addr_lo = rx_local->fbr[1]->bus_low[bi];
+ next->word2 = bi;
writel(bump_fbr(&rx_local->local_Fbr1_full,
rx_local->Fbr1NumEntries - 1),
@@ -1134,17 +1121,17 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
}
#ifdef USE_FBR0
else {
- PFBR_DESC_t next =
- (PFBR_DESC_t) rx_local->pFbr0RingVa +
- INDEX10(rx_local->local_Fbr0_full);
+ struct fbr_desc *next = (struct fbr_desc *)
+ rx_local->pFbr0RingVa +
+ INDEX10(rx_local->local_Fbr0_full);
/* Handle the Free Buffer Ring advancement here. Write
* the PA / Buffer Index for the returned buffer into
* the oldest (next to be freed) FBR entry
*/
- next->addr_hi = rx_local->Fbr[0]->PAHigh[bi];
- next->addr_lo = rx_local->Fbr[0]->PALow[bi];
- next->word2.value = bi;
+ next->addr_hi = rx_local->fbr[0]->bus_high[bi];
+ next->addr_lo = rx_local->fbr[0]->bus_low[bi];
+ next->word2 = bi;
writel(bump_fbr(&rx_local->local_Fbr0_full,
rx_local->Fbr0NumEntries - 1),
diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h
index 69514593612..ca84a9146d6 100644
--- a/drivers/staging/et131x/et1310_rx.h
+++ b/drivers/staging/et131x/et1310_rx.h
@@ -91,120 +91,60 @@
#define ALCATEL_BROADCAST_PKT 0x02000000
/* typedefs for Free Buffer Descriptors */
-typedef union _FBR_WORD2_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 reserved:22; /* bits 10-31 */
- u32 bi:10; /* bits 0-9(Buffer Index) */
-#else
- u32 bi:10; /* bits 0-9(Buffer Index) */
- u32 reserved:22; /* bit 10-31 */
-#endif
- } bits;
-} FBR_WORD2_t, *PFBR_WORD2_t;
-
-typedef struct _FBR_DESC_t {
+struct fbr_desc
+{
u32 addr_lo;
u32 addr_hi;
- FBR_WORD2_t word2;
-} FBR_DESC_t, *PFBR_DESC_t;
-
-/* Typedefs for Packet Status Ring Descriptors */
-typedef union _PKT_STAT_DESC_WORD0_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- /* top 16 bits are from the Alcatel Status Word as enumerated in */
- /* PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) */
-#if 0
- u32 asw_trunc:1; /* bit 31(Rx frame truncated) */
-#endif
- u32 asw_long_evt:1; /* bit 31(Rx long event) */
- u32 asw_VLAN_tag:1; /* bit 30(VLAN tag detected) */
- u32 asw_unsupported_op:1; /* bit 29(unsupported OP code) */
- u32 asw_pause_frame:1; /* bit 28(is a pause frame) */
- u32 asw_control_frame:1; /* bit 27(is a control frame) */
- u32 asw_dribble_nibble:1; /* bit 26(spurious bits after EOP) */
- u32 asw_broadcast:1; /* bit 25(has a broadcast address) */
- u32 asw_multicast:1; /* bit 24(has a multicast address) */
- u32 asw_OK:1; /* bit 23(valid CRC + no code error) */
- u32 asw_too_long:1; /* bit 22(frame length > 1518 bytes) */
- u32 asw_len_chk_err:1; /* bit 21(frame length field incorrect) */
- u32 asw_CRC_err:1; /* bit 20(CRC error) */
- u32 asw_code_err:1; /* bit 19(one or more nibbles signalled as errors) */
- u32 asw_false_carrier_event:1; /* bit 18(bad carrier since last good packet) */
- u32 asw_RX_DV_event:1; /* bit 17(short receive event detected) */
- u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */
- u32 unused:5; /* bits 11-15 */
- u32 vp:1; /* bit 10(VLAN Packet) */
- u32 jp:1; /* bit 9(Jumbo Packet) */
- u32 ft:1; /* bit 8(Frame Truncated) */
- u32 drop:1; /* bit 7(Drop packet) */
- u32 rxmac_error:1; /* bit 6(RXMAC Error Indicator) */
- u32 wol:1; /* bit 5(WOL Event) */
- u32 tcpp:1; /* bit 4(TCP checksum pass) */
- u32 tcpa:1; /* bit 3(TCP checksum assist) */
- u32 ipp:1; /* bit 2(IP checksum pass) */
- u32 ipa:1; /* bit 1(IP checksum assist) */
- u32 hp:1; /* bit 0(hash pass) */
-#else
- u32 hp:1; /* bit 0(hash pass) */
- u32 ipa:1; /* bit 1(IP checksum assist) */
- u32 ipp:1; /* bit 2(IP checksum pass) */
- u32 tcpa:1; /* bit 3(TCP checksum assist) */
- u32 tcpp:1; /* bit 4(TCP checksum pass) */
- u32 wol:1; /* bit 5(WOL Event) */
- u32 rxmac_error:1; /* bit 6(RXMAC Error Indicator) */
- u32 drop:1; /* bit 7(Drop packet) */
- u32 ft:1; /* bit 8(Frame Truncated) */
- u32 jp:1; /* bit 9(Jumbo Packet) */
- u32 vp:1; /* bit 10(VLAN Packet) */
- u32 unused:5; /* bits 11-15 */
- u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */
- u32 asw_RX_DV_event:1; /* bit 17(short receive event detected) */
- u32 asw_false_carrier_event:1; /* bit 18(bad carrier since last good packet) */
- u32 asw_code_err:1; /* bit 19(one or more nibbles signalled as errors) */
- u32 asw_CRC_err:1; /* bit 20(CRC error) */
- u32 asw_len_chk_err:1; /* bit 21(frame length field incorrect) */
- u32 asw_too_long:1; /* bit 22(frame length > 1518 bytes) */
- u32 asw_OK:1; /* bit 23(valid CRC + no code error) */
- u32 asw_multicast:1; /* bit 24(has a multicast address) */
- u32 asw_broadcast:1; /* bit 25(has a broadcast address) */
- u32 asw_dribble_nibble:1; /* bit 26(spurious bits after EOP) */
- u32 asw_control_frame:1; /* bit 27(is a control frame) */
- u32 asw_pause_frame:1; /* bit 28(is a pause frame) */
- u32 asw_unsupported_op:1; /* bit 29(unsupported OP code) */
- u32 asw_VLAN_tag:1; /* bit 30(VLAN tag detected) */
- u32 asw_long_evt:1; /* bit 31(Rx long event) */
-#if 0
- u32 asw_trunc:1; /* bit 31(Rx frame truncated) */
-#endif
-#endif
- } bits;
-} PKT_STAT_DESC_WORD0_t, *PPKT_STAT_WORD0_t;
+ u32 word2; /* Bits 10-31 reserved, 0-9 descriptor */
+};
-typedef union _PKT_STAT_DESC_WORD1_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 unused:4; /* bits 28-31 */
- u32 ri:2; /* bits 26-27(Ring Index) */
- u32 bi:10; /* bits 16-25(Buffer Index) */
- u32 length:16; /* bit 0-15(length in bytes) */
-#else
- u32 length:16; /* bit 0-15(length in bytes) */
- u32 bi:10; /* bits 16-25(Buffer Index) */
- u32 ri:2; /* bits 26-27(Ring Index) */
- u32 unused:4; /* bits 28-31 */
-#endif
- } bits;
-} PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t;
+/* Packet Status Ring Descriptors
+ *
+ * Word 0:
+ *
+ * top 16 bits are from the Alcatel Status Word as enumerated in
+ * PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2)
+ *
+ * 0: hp hash pass
+ * 1: ipa IP checksum assist
+ * 2: ipp IP checksum pass
+ * 3: tcpa TCP checksum assist
+ * 4: tcpp TCP checksum pass
+ * 5: wol WOL Event
+ * 6: rxmac_error RXMAC Error Indicator
+ * 7: drop Drop packet
+ * 8: ft Frame Truncated
+ * 9: jp Jumbo Packet
+ * 10: vp VLAN Packet
+ * 11-15: unused
+ * 16: asw_prev_pkt_dropped e.g. IFG too small on previous
+ * 17: asw_RX_DV_event short receive event detected
+ * 18: asw_false_carrier_event bad carrier since last good packet
+ * 19: asw_code_err one or more nibbles signalled as errors
+ * 20: asw_CRC_err CRC error
+ * 21: asw_len_chk_err frame length field incorrect
+ * 22: asw_too_long frame length > 1518 bytes
+ * 23: asw_OK valid CRC + no code error
+ * 24: asw_multicast has a multicast address
+ * 25: asw_broadcast has a broadcast address
+ * 26: asw_dribble_nibble spurious bits after EOP
+ * 27: asw_control_frame is a control frame
+ * 28: asw_pause_frame is a pause frame
+ * 29: asw_unsupported_op unsupported OP code
+ * 30: asw_VLAN_tag VLAN tag detected
+ * 31: asw_long_evt Rx long event
+ *
+ * Word 1:
+ * 0-15: length length in bytes
+ * 16-25: bi Buffer Index
+ * 26-27: ri Ring Index
+ * 28-31: reserved
+ */
-typedef struct _PKT_STAT_DESC_t {
- PKT_STAT_DESC_WORD0_t word0;
- PKT_STAT_DESC_WORD1_t word1;
-} PKT_STAT_DESC_t, *PPKT_STAT_DESC_t;
+struct pkt_stat_desc {
+ u32 word0;
+ u32 word1;
+};
/* Typedefs for the RX DMA status word */
@@ -223,59 +163,38 @@ typedef struct _PKT_STAT_DESC_t {
* RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine
* that get copied out to memory by the ET-1310. Word 3 is a 32 bit word
* which contains the Packet Status Ring available offset.
+ *
+ * bit 0-15 reserved
+ * bit 16-27 PSRoffset
+ * bit 28 PSRwrap
+ * bit 29-31 unused
*/
-#define RXSTAT1_OFFSET 16
-#define RXSTAT1_MASK 0xFFF
-#define RXSTAT1_WRAP 0x10000000
-
-typedef union _rxstat_word1_t {
- u32 value;
- struct {
-#ifdef _BIT_FIELDS_HTOL
- u32 PSRunused:3; /* bits 29-31 */
- u32 PSRwrap:1; /* bit 28 */
- u32 PSRoffset:12; /* bits 16-27 */
- u32 reserved:16; /* bits 0-15 */
-#else
- u32 reserved:16; /* bits 0-15 */
- u32 PSRoffset:12; /* bits 16-27 */
- u32 PSRwrap:1; /* bit 28 */
- u32 PSRunused:3; /* bits 29-31 */
-#endif
- } bits;
-} RXSTAT_WORD1_t, *PRXSTAT_WORD1_t;
-
/*
- * RX_STATUS_BLOCK_t is sructure representing the status of the Rx DMA engine
- * it sits in free memory, and is pointed to by 0x101c / 0x1020
+ * struct rx_status_block is a structure representing the status of the Rx
+ * DMA engine it sits in free memory, and is pointed to by 0x101c / 0x1020
*/
-typedef struct _rx_status_block_t {
+struct rx_status_block {
u32 Word0;
- RXSTAT_WORD1_t Word1;
-} RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t;
+ u32 Word1;
+};
/*
* Structure for look-up table holding free buffer ring pointers
*/
-typedef struct _FbrLookupTable {
- void *Va[MAX_DESC_PER_RING_RX];
- void *Buffer1[MAX_DESC_PER_RING_RX];
- void *Buffer2[MAX_DESC_PER_RING_RX];
- u32 PAHigh[MAX_DESC_PER_RING_RX];
- u32 PALow[MAX_DESC_PER_RING_RX];
-} FBRLOOKUPTABLE, *PFBRLOOKUPTABLE;
-
-typedef enum {
- ONE_PACKET_INTERRUPT,
- FOUR_PACKET_INTERRUPT
-} eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t;
+struct fbr_lookup {
+ void *virt[MAX_DESC_PER_RING_RX];
+ void *buffer1[MAX_DESC_PER_RING_RX];
+ void *buffer2[MAX_DESC_PER_RING_RX];
+ u32 bus_high[MAX_DESC_PER_RING_RX];
+ u32 bus_low[MAX_DESC_PER_RING_RX];
+};
/*
- * RX_RING_t is sructure representing the adaptor's local reference(s) to the
- * rings
+ * struct rx_ring is the ssructure representing the adaptor's local
+ * reference(s) to the rings
*/
-typedef struct _rx_ring_t {
+struct rx_ring {
#ifdef USE_FBR0
void *pFbr0RingVa;
dma_addr_t pFbr0RingPa;
@@ -293,7 +212,7 @@ typedef struct _rx_ring_t {
dma_addr_t Fbr1MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
uint64_t Fbr1Realpa;
uint64_t Fbr1offset;
- FBRLOOKUPTABLE *Fbr[2];
+ struct fbr_lookup *fbr[2]; /* One per ring */
u32 local_Fbr1_full;
u32 Fbr1NumEntries;
u32 Fbr1BufferSize;
@@ -303,8 +222,8 @@ typedef struct _rx_ring_t {
u32 local_psr_full;
u32 PsrNumEntries;
- void *pRxStatusVa;
- dma_addr_t pRxStatusPa;
+ struct rx_status_block *rx_status_block;
+ dma_addr_t rx_status_bus;
struct list_head RecvBufferPool;
@@ -320,30 +239,6 @@ typedef struct _rx_ring_t {
/* lookaside lists */
struct kmem_cache *RecvLookaside;
-} RX_RING_t, *PRX_RING_t;
-
-/* Forward reference of RFD */
-struct _MP_RFD;
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-/* PROTOTYPES for Initialization */
-int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter);
-void et131x_rx_dma_memory_free(struct et131x_adapter *adapter);
-int et131x_rfd_resources_alloc(struct et131x_adapter *adapter,
- struct _MP_RFD *pMpRfd);
-void et131x_rfd_resources_free(struct et131x_adapter *adapter,
- struct _MP_RFD *pMpRfd);
-int et131x_init_recv(struct et131x_adapter *adapter);
-
-void ConfigRxDmaRegs(struct et131x_adapter *adapter);
-void SetRxDmaTimer(struct et131x_adapter *adapter);
-void et131x_rx_dma_disable(struct et131x_adapter *adapter);
-void et131x_rx_dma_enable(struct et131x_adapter *adapter);
-
-void et131x_reset_recv(struct et131x_adapter *adapter);
-
-void et131x_handle_recv_interrupt(struct et131x_adapter *adapter);
+};
#endif /* __ET1310_RX_H__ */
diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c
index 977e8b34e7a..b6ff20f47de 100644
--- a/drivers/staging/et131x/et1310_tx.c
+++ b/drivers/staging/et131x/et1310_tx.c
@@ -84,15 +84,9 @@
#include <linux/ioport.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-
#include "et131x_adapter.h"
-#include "et131x_initpci.h"
-#include "et131x_isr.h"
-
#include "et1310_tx.h"
-
+#include "et131x.h"
static inline void et131x_free_send_packet(struct et131x_adapter *etdev,
struct tcb *tcb);
@@ -200,7 +194,7 @@ void et131x_tx_dma_memory_free(struct et131x_adapter *adapter)
*/
void ConfigTxDmaRegs(struct et131x_adapter *etdev)
{
- struct _TXDMA_t __iomem *txdma = &etdev->regs->txdma;
+ struct txdma_regs __iomem *txdma = &etdev->regs->txdma;
/* Load the hardware with the start of the transmit descriptor ring. */
writel((u32) ((u64)etdev->tx_ring.tx_desc_ring_pa >> 32),
diff --git a/drivers/staging/et131x/et1310_tx.h b/drivers/staging/et131x/et1310_tx.h
index 4f0ea81978f..82d06e9870d 100644
--- a/drivers/staging/et131x/et1310_tx.h
+++ b/drivers/staging/et131x/et1310_tx.h
@@ -147,18 +147,4 @@ struct tx_ring {
int since_irq;
};
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-/* PROTOTYPES for et1310_tx.c */
-int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter);
-void et131x_tx_dma_memory_free(struct et131x_adapter *adapter);
-void ConfigTxDmaRegs(struct et131x_adapter *adapter);
-void et131x_init_send(struct et131x_adapter *adapter);
-void et131x_tx_dma_disable(struct et131x_adapter *adapter);
-void et131x_tx_dma_enable(struct et131x_adapter *adapter);
-void et131x_handle_send_interrupt(struct et131x_adapter *adapter);
-void et131x_free_busy_send_packets(struct et131x_adapter *adapter);
-int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev);
-
#endif /* __ET1310_TX_H__ */
diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h
new file mode 100644
index 00000000000..a8abfe6ca81
--- /dev/null
+++ b/drivers/staging/et131x/et131x.h
@@ -0,0 +1,153 @@
+/*
+ * Merged from files
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, 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 as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . 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 Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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.
+ *
+ */
+
+/* et131x_eeprom.c */
+int et131x_init_eeprom(struct et131x_adapter *etdev);
+
+/* et131x_initpci.c */
+void ConfigGlobalRegs(struct et131x_adapter *pAdapter);
+void ConfigMMCRegs(struct et131x_adapter *pAdapter);
+void et131x_enable_interrupts(struct et131x_adapter *adapter);
+void et131x_disable_interrupts(struct et131x_adapter *adapter);
+void et131x_align_allocated_memory(struct et131x_adapter *adapter,
+ u64 *phys_addr,
+ u64 *offset, u64 mask);
+
+int et131x_adapter_setup(struct et131x_adapter *adapter);
+int et131x_adapter_memory_alloc(struct et131x_adapter *adapter);
+void et131x_adapter_memory_free(struct et131x_adapter *adapter);
+void et131x_hwaddr_init(struct et131x_adapter *adapter);
+void et131x_soft_reset(struct et131x_adapter *adapter);
+
+/* et131x_isr.c */
+irqreturn_t et131x_isr(int irq, void *dev_id);
+void et131x_isr_handler(struct work_struct *work);
+
+/* et1310_mac.c */
+void ConfigMACRegs1(struct et131x_adapter *adapter);
+void ConfigMACRegs2(struct et131x_adapter *adapter);
+void ConfigRxMacRegs(struct et131x_adapter *adapter);
+void ConfigTxMacRegs(struct et131x_adapter *adapter);
+void ConfigMacStatRegs(struct et131x_adapter *adapter);
+void ConfigFlowControl(struct et131x_adapter *adapter);
+void UpdateMacStatHostCounters(struct et131x_adapter *adapter);
+void HandleMacStatInterrupt(struct et131x_adapter *adapter);
+void SetupDeviceForMulticast(struct et131x_adapter *adapter);
+void SetupDeviceForUnicast(struct et131x_adapter *adapter);
+
+/* et131x_netdev.c */
+struct net_device *et131x_device_alloc(void);
+
+/* et131x_pm.c */
+void EnablePhyComa(struct et131x_adapter *adapter);
+void DisablePhyComa(struct et131x_adapter *adapter);
+
+/* et131x_phy.c */
+void ET1310_PhyInit(struct et131x_adapter *adapter);
+void ET1310_PhyReset(struct et131x_adapter *adapter);
+void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down);
+void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter,
+ u16 duplex);
+void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
+ u16 action,
+ u16 regnum, u16 bitnum, u8 *value);
+
+int et131x_xcvr_find(struct et131x_adapter *adapter);
+void et131x_setphy_normal(struct et131x_adapter *adapter);
+
+/* static inline function does not work because et131x_adapter is not always
+ * defined
+ */
+int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr,
+ u8 xcvrReg, u16 *value);
+#define MiRead(adapter, xcvrReg, value) \
+ PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value))
+
+int32_t MiWrite(struct et131x_adapter *adapter,
+ u8 xcvReg, u16 value);
+void et131x_Mii_check(struct et131x_adapter *pAdapter,
+ MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints);
+
+/* This last is not strictly required (the driver could call the TPAL
+ * version instead), but this sets the adapter up correctly, and calls the
+ * access routine indirectly. This protects the driver from changes in TPAL.
+ */
+void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
+
+
+/* et1310_rx.c */
+int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter);
+void et131x_rx_dma_memory_free(struct et131x_adapter *adapter);
+int et131x_rfd_resources_alloc(struct et131x_adapter *adapter,
+ struct _MP_RFD *pMpRfd);
+void et131x_rfd_resources_free(struct et131x_adapter *adapter,
+ struct _MP_RFD *pMpRfd);
+int et131x_init_recv(struct et131x_adapter *adapter);
+
+void ConfigRxDmaRegs(struct et131x_adapter *adapter);
+void SetRxDmaTimer(struct et131x_adapter *adapter);
+void et131x_rx_dma_disable(struct et131x_adapter *adapter);
+void et131x_rx_dma_enable(struct et131x_adapter *adapter);
+
+void et131x_reset_recv(struct et131x_adapter *adapter);
+
+void et131x_handle_recv_interrupt(struct et131x_adapter *adapter);
+
+/* et131x_tx.c */
+int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter);
+void et131x_tx_dma_memory_free(struct et131x_adapter *adapter);
+void ConfigTxDmaRegs(struct et131x_adapter *adapter);
+void et131x_init_send(struct et131x_adapter *adapter);
+void et131x_tx_dma_disable(struct et131x_adapter *adapter);
+void et131x_tx_dma_enable(struct et131x_adapter *adapter);
+void et131x_handle_send_interrupt(struct et131x_adapter *adapter);
+void et131x_free_busy_send_packets(struct et131x_adapter *adapter);
+int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev);
+
diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h
index 3f7f37a56b6..64a678fcb60 100644
--- a/drivers/staging/et131x/et131x_adapter.h
+++ b/drivers/staging/et131x/et131x_adapter.h
@@ -77,38 +77,11 @@
*/
#define NUM_TRAFFIC_CLASSES 1
-/*
- * There are three ways of counting errors - if there are more than X errors
- * in Y packets (represented by the "SAMPLE" macros), if there are more than
- * N errors in a S mSec time period (the "PERIOD" macros), or if there are
- * consecutive packets with errors (CONSEC_ERRORED_THRESH). This last covers
- * for "Bursty" errors, and the errored packets may well not be contiguous,
- * but several errors where the packet counter has changed by less than a
- * small amount will cause this count to increment.
- */
-#define TX_PACKETS_IN_SAMPLE 10000
-#define TX_MAX_ERRORS_IN_SAMPLE 50
-
#define TX_ERROR_PERIOD 1000
-#define TX_MAX_ERRORS_IN_PERIOD 10
-
-#define LINK_DETECTION_TIMER 5000
-
-#define TX_CONSEC_RANGE 5
-#define TX_CONSEC_ERRORED_THRESH 10
#define LO_MARK_PERCENT_FOR_PSR 15
#define LO_MARK_PERCENT_FOR_RX 15
-/* Counters for error rate monitoring */
-typedef struct _MP_ERR_COUNTERS {
- u32 PktCountTxPackets;
- u32 PktCountTxErrors;
- u32 TimerBasedTxErrors;
- u32 PktCountLastError;
- u32 ErredConsecPackets;
-} MP_ERR_COUNTERS, *PMP_ERR_COUNTERS;
-
/* RFD (Receive Frame Descriptor) */
typedef struct _MP_RFD {
struct list_head list_node;
@@ -174,6 +147,20 @@ typedef struct _ce_stats_t {
u32 InterruptStatus;
} CE_STATS_t, *PCE_STATS_t;
+typedef struct _MP_POWER_MGMT {
+ /* variable putting the phy into coma mode when boot up with no cable
+ * plugged in after 5 seconds
+ */
+ u8 TransPhyComaModeOnBoot;
+
+ /* Next two used to save power information at power down. This
+ * information will be used during power up to set up parts of Power
+ * Management in JAGCore
+ */
+ u16 PowerDownSpeed;
+ u8 PowerDownDuplex;
+} MP_POWER_MGMT, *PMP_POWER_MGMT;
+
/* The private adapter structure */
struct et131x_adapter {
struct net_device *netdev;
@@ -248,7 +235,7 @@ struct et131x_adapter {
struct tx_ring tx_ring;
/* Rx Memory Variables */
- RX_RING_t RxRing;
+ struct rx_ring rx_ring;
/* Loopback specifics */
u8 ReplicaPhyLoopbk; /* Replica Enable */
diff --git a/drivers/staging/et131x/et131x_config.h b/drivers/staging/et131x/et131x_config.h
deleted file mode 100644
index 642c0f6dd6f..00000000000
--- a/drivers/staging/et131x/et131x_config.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- * http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_config.h - Defines, structs, enums, prototypes, etc. to support
- * et131x_config.c
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software. Using this
- * software indicates your acceptance of these terms and conditions. If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- * well as in the documentation and/or other materials provided with the
- * distribution.
- *
- * . 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 Agere Systems Inc. nor the names of the contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET131X_CONFIG_H__
-#define __ET131X_CONFIG_H__
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-void et131x_config_parse(struct et131x_adapter *adapter);
-
-#endif /* __ET131X_CONFIG_H__ */
diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c
index 0892b6a538d..1dd5fa5b888 100644
--- a/drivers/staging/et131x/et131x_initpci.c
+++ b/drivers/staging/et131x/et131x_initpci.c
@@ -68,7 +68,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -87,20 +86,16 @@
#include <linux/random.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
#include "et131x_adapter.h"
-#include "et131x_netdev.h"
-#include "et131x_config.h"
-#include "et131x_isr.h"
#include "et1310_address_map.h"
#include "et1310_tx.h"
#include "et1310_rx.h"
-#include "et1310_mac.h"
-#include "et1310_eeprom.h"
+#include "et131x.h"
+#define INTERNAL_MEM_SIZE 0x400 /* 1024 of internal memory */
+#define INTERNAL_MEM_RX_OFFSET 0x1FF /* 50% Tx, 50% Rx */
/* Defines for Parameter Default/Min/Max vaules */
#define PARM_SPEED_DUPLEX_MIN 0
@@ -327,7 +322,7 @@ void et131x_link_detection_handler(unsigned long data)
*/
void ConfigGlobalRegs(struct et131x_adapter *etdev)
{
- struct _GLOBAL_t __iomem *regs = &etdev->regs->global;
+ struct global_regs __iomem *regs = &etdev->regs->global;
writel(0, &regs->rxq_start_addr);
writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
diff --git a/drivers/staging/et131x/et131x_initpci.h b/drivers/staging/et131x/et131x_initpci.h
deleted file mode 100644
index 7269569a874..00000000000
--- a/drivers/staging/et131x/et131x_initpci.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- * http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_initpci.h - Header which includes common data and function prototypes
- * related to the driver's PCI (and PCI Express) information.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software. Using this
- * software indicates your acceptance of these terms and conditions. If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- * well as in the documentation and/or other materials provided with the
- * distribution.
- *
- * . 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 Agere Systems Inc. nor the names of the contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET131X_INITPCI_H__
-#define __ET131X_INITPCI_H__
-
-/* Function Prototypes */
-void et131x_align_allocated_memory(struct et131x_adapter *adapter,
- u64 *phys_addr,
- u64 *offset, u64 mask);
-
-int et131x_adapter_setup(struct et131x_adapter *adapter);
-int et131x_adapter_memory_alloc(struct et131x_adapter *adapter);
-void et131x_adapter_memory_free(struct et131x_adapter *adapter);
-void et131x_hwaddr_init(struct et131x_adapter *adapter);
-void et131x_soft_reset(struct et131x_adapter *adapter);
-
-#endif /* __ET131X_INITPCI_H__ */
diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c
index f6d452dd14e..cb7f6775ce0 100644
--- a/drivers/staging/et131x/et131x_isr.c
+++ b/drivers/staging/et131x/et131x_isr.c
@@ -66,7 +66,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -85,11 +84,27 @@
#include <linux/ioport.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_mac.h"
-
#include "et131x_adapter.h"
+#include "et131x.h"
+
+/*
+ * For interrupts, normal running is:
+ * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt,
+ * watchdog_interrupt & txdma_xfer_done
+ *
+ * In both cases, when flow control is enabled for either Tx or bi-direction,
+ * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the
+ * buffer rings are running low.
+ */
+#define INT_MASK_DISABLE 0xffffffff
+
+/* NOTE: Masking out MAC_STAT Interrupt for now...
+ * #define INT_MASK_ENABLE 0xfff6bf17
+ * #define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7
+ */
+#define INT_MASK_ENABLE 0xfffebf17
+#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7
+
/**
* et131x_enable_interrupts - enable interrupt
@@ -185,7 +200,7 @@ irqreturn_t et131x_isr(int irq, void *dev_id)
if (++tcb->stale > 1)
status |= ET_INTR_TXDMA_ISR;
- if (adapter->RxRing.UnfinishedReceives)
+ if (adapter->rx_ring.UnfinishedReceives)
status |= ET_INTR_RXDMA_XFR_DONE;
else if (tcb == NULL)
writel(0, &adapter->regs->global.watchdog_timer);
@@ -390,7 +405,7 @@ void et131x_isr_handler(struct work_struct *work)
/* Let's move on to the TxMac */
if (status & ET_INTR_TXMAC) {
- u32 err = readl(&iomem->txmac.err.value);
+ u32 err = readl(&iomem->txmac.err);
/*
* When any of the errors occur and TXMAC generates
@@ -425,12 +440,12 @@ void et131x_isr_handler(struct work_struct *work)
dev_warn(&etdev->pdev->dev,
"RXMAC interrupt, error 0x%08x. Requesting reset\n",
- readl(&iomem->rxmac.err_reg.value));
+ readl(&iomem->rxmac.err_reg));
dev_warn(&etdev->pdev->dev,
"Enable 0x%08x, Diag 0x%08x\n",
- readl(&iomem->rxmac.ctrl.value),
- readl(&iomem->rxmac.rxq_diag.value));
+ readl(&iomem->rxmac.ctrl),
+ readl(&iomem->rxmac.rxq_diag));
/*
* If we are debugging, we want to see this error,
diff --git a/drivers/staging/et131x/et131x_isr.h b/drivers/staging/et131x/et131x_isr.h
deleted file mode 100644
index 906d57727e2..00000000000
--- a/drivers/staging/et131x/et131x_isr.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- * http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_isr.h - Defines, structs, enums, prototypes, etc. pertaining to the
- * ISR processing code.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software. Using this
- * software indicates your acceptance of these terms and conditions. If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- * well as in the documentation and/or other materials provided with the
- * distribution.
- *
- * . 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 Agere Systems Inc. nor the names of the contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET131X_ISR_H__
-#define __ET131X_ISR_H__
-
-irqreturn_t et131x_isr(int irq, void *dev_id);
-void et131x_isr_handler(struct work_struct *work);
-
-#endif /* __ET131X_ISR_H__ */
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c
index edb78ae9e59..ab047f2ff72 100644
--- a/drivers/staging/et131x/et131x_netdev.c
+++ b/drivers/staging/et131x/et131x_netdev.c
@@ -65,7 +65,6 @@
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -85,14 +84,9 @@
#include <linux/ioport.h>
#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-#include "et1310_mac.h"
#include "et1310_tx.h"
-
#include "et131x_adapter.h"
-#include "et131x_isr.h"
-#include "et131x_initpci.h"
+#include "et131x.h"
struct net_device_stats *et131x_stats(struct net_device *netdev);
int et131x_open(struct net_device *netdev);
@@ -339,66 +333,64 @@ int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd)
* et131x_set_packet_filter - Configures the Rx Packet filtering on the device
* @adapter: pointer to our private adapter structure
*
+ * FIXME: lot of dups with MAC code
+ *
* Returns 0 on success, errno on failure
*/
int et131x_set_packet_filter(struct et131x_adapter *adapter)
{
int status = 0;
uint32_t filter = adapter->PacketFilter;
- RXMAC_CTRL_t ctrl;
- RXMAC_PF_CTRL_t pf_ctrl;
+ u32 ctrl;
+ u32 pf_ctrl;
- ctrl.value = readl(&adapter->regs->rxmac.ctrl.value);
- pf_ctrl.value = readl(&adapter->regs->rxmac.pf_ctrl.value);
+ ctrl = readl(&adapter->regs->rxmac.ctrl);
+ pf_ctrl = readl(&adapter->regs->rxmac.pf_ctrl);
/* Default to disabled packet filtering. Enable it in the individual
* case statements that require the device to filter something
*/
- ctrl.bits.pkt_filter_disable = 1;
+ ctrl |= 0x04;
/* Set us to be in promiscuous mode so we receive everything, this
* is also true when we get a packet filter of 0
*/
- if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0) {
- pf_ctrl.bits.filter_broad_en = 0;
- pf_ctrl.bits.filter_multi_en = 0;
- pf_ctrl.bits.filter_uni_en = 0;
- } else {
+ if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0)
+ pf_ctrl &= ~7; /* Clear filter bits */
+ else {
/*
* Set us up with Multicast packet filtering. Three cases are
* possible - (1) we have a multi-cast list, (2) we receive ALL
* multicast entries or (3) we receive none.
*/
- if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
- pf_ctrl.bits.filter_multi_en = 0;
- } else {
+ if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST)
+ pf_ctrl &= ~2; /* Multicast filter bit */
+ else {
SetupDeviceForMulticast(adapter);
- pf_ctrl.bits.filter_multi_en = 1;
- ctrl.bits.pkt_filter_disable = 0;
+ pf_ctrl |= 2;
+ ctrl &= ~0x04;
}
/* Set us up with Unicast packet filtering */
if (filter & ET131X_PACKET_TYPE_DIRECTED) {
SetupDeviceForUnicast(adapter);
- pf_ctrl.bits.filter_uni_en = 1;
- ctrl.bits.pkt_filter_disable = 0;
+ pf_ctrl |= 4;
+ ctrl &= ~0x04;
}
/* Set us up with Broadcast packet filtering */
if (filter & ET131X_PACKET_TYPE_BROADCAST) {
- pf_ctrl.bits.filter_broad_en = 1;
- ctrl.bits.pkt_filter_disable = 0;
- } else {
- pf_ctrl.bits.filter_broad_en = 0;
- }
+ pf_ctrl |= 1; /* Broadcast filter bit */
+ ctrl &= ~0x04;
+ } else
+ pf_ctrl &= ~1;
/* Setup the receive mac configuration registers - Packet
* Filter control + the enable / disable for packet filter
* in the control reg.
*/
- writel(pf_ctrl.value,
- &adapter->regs->rxmac.pf_ctrl.value);
- writel(ctrl.value, &adapter->regs->rxmac.ctrl.value);
+ writel(pf_ctrl, &adapter->regs->rxmac.pf_ctrl);
+ writel(ctrl, &adapter->regs->rxmac.ctrl);
}
return status;
}
@@ -675,12 +667,8 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac)
memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len);
- printk(KERN_INFO
- "%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n",
- netdev->name,
- netdev->dev_addr[0], netdev->dev_addr[1],
- netdev->dev_addr[2], netdev->dev_addr[3],
- netdev->dev_addr[4], netdev->dev_addr[5]);
+ printk(KERN_INFO "%s: Setting MAC address to %pM\n",
+ netdev->name, netdev->dev_addr);
/* Free Rx DMA memory */
et131x_adapter_memory_free(adapter);
diff --git a/drivers/staging/et131x/et131x_netdev.h b/drivers/staging/et131x/et131x_netdev.h
deleted file mode 100644
index 1eb4a922c01..00000000000
--- a/drivers/staging/et131x/et131x_netdev.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- * http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_netdev.h - Defines, structs, enums, prototypes, etc. related to the
- * driver's net_device support.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software. Using this
- * software indicates your acceptance of these terms and conditions. If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, 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 as comments in the code as
- * well as in the documentation and/or other materials provided with the
- * distribution.
- *
- * . 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 Agere Systems Inc. nor the names of the contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 __ET131X_NETDEV_H__
-#define __ET131X_NETDEV_H__
-
-struct net_device *et131x_device_alloc(void);
-
-#endif /* __ET131X_NETDEV_H__ */
diff --git a/drivers/staging/et131x/et131x_version.h b/drivers/staging/et131x/et131x_version.h
index 568f6c8c34f..2aa9bda44ac 100644
--- a/drivers/staging/et131x/et131x_version.h
+++ b/drivers/staging/et131x/et131x_version.h
@@ -62,20 +62,13 @@
#define DRIVER_LICENSE "Dual BSD/GPL"
#define DRIVER_DEVICE_STRING "ET1310"
#define DRIVER_NAME "et131x"
-#define DRIVER_MAJOR_VERSION 1
-#define DRIVER_MINOR_VERSION 2
-#define DRIVER_PATCH_VERSION 3
-#define DRIVER_VERSION_STRING "1.2.3"
+#define DRIVER_VERSION_STRING "1.2.3-lk"
#define DRIVER_VENDOR "Agere Systems, http://www.agere.com"
#define DRIVER_DESC "10/100/1000 Base-T Ethernet Driver"
-#define STRUCT_MODULE "net" /* blux: missed by the kernel */
-
#define DRIVER_INFO DRIVER_DESC " for the "\
DRIVER_DEVICE_STRING ", v" \
DRIVER_VERSION_STRING " by " \
DRIVER_VENDOR
-#define DRIVER_NAME_EXT "et131x.ko"
-
#endif /* __ET131X_VERSION_H__ */
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
index 15aed87fe1b..a50a21518a8 100644
--- a/drivers/staging/frontier/alphatrack.c
+++ b/drivers/staging/frontier/alphatrack.c
@@ -58,7 +58,7 @@
#endif
/* table of devices that work with this driver */
-static struct usb_device_id usb_alphatrack_table[] = {
+static const struct usb_device_id usb_alphatrack_table[] = {
{USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
{} /* Terminating entry */
};
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index ef8fcc8c67b..2f03f43f3a2 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -55,7 +55,7 @@
#endif
/* table of devices that work with this driver */
-static struct usb_device_id usb_tranzport_table[] = {
+static const struct usb_device_id usb_tranzport_table[] = {
{USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
{} /* Terminating entry */
};
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index fb1345ffb85..372a7c6791c 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -29,6 +29,7 @@
#include <linux/firmware.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <linux/videodev2.h>
#include <media/tuner.h>
@@ -128,6 +129,8 @@ static int go7007_load_encoder(struct go7007 *go)
return rv;
}
+MODULE_FIRMWARE("go7007fw.bin");
+
/*
* Boot the encoder and register the I2C adapter if requested. Do the
* minimum initialization necessary, since the board-specific code may
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c
index a8bb264e007..ee622ff1707 100644
--- a/drivers/staging/go7007/go7007-fw.c
+++ b/drivers/staging/go7007/go7007-fw.c
@@ -31,6 +31,7 @@
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "go7007-priv.h"
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index 1e89dc04ec2..ee278f64a16 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -444,7 +444,9 @@ static struct go7007_usb_board board_sensoray_2250 = {
},
};
-static struct usb_device_id go7007_usb_id_table[] = {
+MODULE_FIRMWARE("go7007tv.bin");
+
+static const struct usb_device_id go7007_usb_id_table[] = {
{
.match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 3af79242313..723c1a64d87 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -21,6 +21,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/unistd.h>
#include <linux/time.h>
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index c324f6ea002..93f26048e3b 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -20,6 +20,7 @@
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-i2c-drv.h>
@@ -667,7 +668,7 @@ static int s2250_remove(struct i2c_client *client)
return 0;
}
-static struct i2c_device_id s2250_id[] = {
+static const struct i2c_device_id s2250_id[] = {
{ "s2250", 0 },
{ }
};
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
index c152ab9be2f..7547a8f7734 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <dvb-usb.h>
@@ -139,7 +140,7 @@ failed2:
static void s2250loader_disconnect(struct usb_interface *interface)
{
- pdevice_extension_t s = usb_get_intfdata(interface);
+ pdevice_extension_t s;
printk(KERN_INFO "s2250: disconnect\n");
lock_kernel();
s = usb_get_intfdata(interface);
@@ -148,7 +149,7 @@ static void s2250loader_disconnect(struct usb_interface *interface)
unlock_kernel();
}
-static struct usb_device_id s2250loader_ids[] = {
+static const struct usb_device_id s2250loader_ids[] = {
{USB_DEVICE(0x1943, 0xa250)},
{} /* Terminating entry */
};
diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c
index 665bbf59d02..b25d7d2090e 100644
--- a/drivers/staging/go7007/saa7134-go7007.c
+++ b/drivers/staging/go7007/saa7134-go7007.c
@@ -84,6 +84,7 @@ static struct go7007_board_info board_voyager = {
},
},
};
+MODULE_FIRMWARE("go7007tv.bin");
/********************* Driver for GPIO HPI interface *********************/
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
index 03c4dfc138a..deac938d850 100644
--- a/drivers/staging/go7007/snd-go7007.c
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -28,6 +28,7 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c
index 04d6d3a498a..4f0cbdde276 100644
--- a/drivers/staging/go7007/wis-ov7640.c
+++ b/drivers/staging/go7007/wis-ov7640.c
@@ -77,7 +77,7 @@ static int wis_ov7640_remove(struct i2c_client *client)
return 0;
}
-static struct i2c_device_id wis_ov7640_id[] = {
+static const struct i2c_device_id wis_ov7640_id[] = {
{ "wis_ov7640", 0 },
{ }
};
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c
index 9ab893bd204..5c12b4d3845 100644
--- a/drivers/staging/go7007/wis-saa7113.c
+++ b/drivers/staging/go7007/wis-saa7113.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include "wis-i2c.h"
@@ -304,7 +305,7 @@ static int wis_saa7113_remove(struct i2c_client *client)
return 0;
}
-static struct i2c_device_id wis_saa7113_id[] = {
+static const struct i2c_device_id wis_saa7113_id[] = {
{ "wis_saa7113", 0 },
{ }
};
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c
index 8687ad2de76..73f2283a880 100644
--- a/drivers/staging/go7007/wis-saa7115.c
+++ b/drivers/staging/go7007/wis-saa7115.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include "wis-i2c.h"
@@ -437,7 +438,7 @@ static int wis_saa7115_remove(struct i2c_client *client)
return 0;
}
-static struct i2c_device_id wis_saa7115_id[] = {
+static const struct i2c_device_id wis_saa7115_id[] = {
{ "wis_saa7115", 0 },
{ }
};
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c
index 086896cec49..b1013291190 100644
--- a/drivers/staging/go7007/wis-sony-tuner.c
+++ b/drivers/staging/go7007/wis-sony-tuner.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
+#include <linux/slab.h>
#include <media/tuner.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
@@ -688,7 +689,7 @@ static int wis_sony_tuner_remove(struct i2c_client *client)
return 0;
}
-static struct i2c_device_id wis_sony_tuner_id[] = {
+static const struct i2c_device_id wis_sony_tuner_id[] = {
{ "wis_sony_tuner", 0 },
{ }
};
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c
index e15794a2a0a..315268d130d 100644
--- a/drivers/staging/go7007/wis-tw2804.c
+++ b/drivers/staging/go7007/wis-tw2804.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include "wis-i2c.h"
@@ -327,7 +328,7 @@ static int wis_tw2804_remove(struct i2c_client *client)
return 0;
}
-static struct i2c_device_id wis_tw2804_id[] = {
+static const struct i2c_device_id wis_tw2804_id[] = {
{ "wis_tw2804", 0 },
{ }
};
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
index 506dca6e942..3ac6f785c4a 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include "wis-i2c.h"
@@ -309,7 +310,7 @@ static int wis_tw9903_remove(struct i2c_client *client)
return 0;
}
-static struct i2c_device_id wis_tw9903_id[] = {
+static const struct i2c_device_id wis_tw9903_id[] = {
{ "wis_tw9903", 0 },
{ }
};
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c
index 739c7ae8913..5c4eb49d735 100644
--- a/drivers/staging/go7007/wis-uda1342.c
+++ b/drivers/staging/go7007/wis-uda1342.c
@@ -82,7 +82,7 @@ static int wis_uda1342_remove(struct i2c_client *client)
return 0;
}
-static struct i2c_device_id wis_uda1342_id[] = {
+static const struct i2c_device_id wis_uda1342_id[] = {
{ "wis_uda1342", 0 },
{ }
};
diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c
index 746370e8211..e69e9ee704a 100644
--- a/drivers/staging/hv/Channel.c
+++ b/drivers/staging/hv/Channel.c
@@ -20,6 +20,7 @@
*/
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include "osd.h"
#include "logging.h"
#include "VmbusPrivate.h"
@@ -991,9 +992,8 @@ void VmbusChannelOnTimer(unsigned long data)
{
struct vmbus_channel *channel = (struct vmbus_channel *)data;
- if (channel->OnChannelCallback) {
+ if (channel->OnChannelCallback)
channel->OnChannelCallback(channel->ChannelCallbackContext);
- }
}
/**
diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c
index ef38467ed4e..5f92c2102ab 100644
--- a/drivers/staging/hv/ChannelMgmt.c
+++ b/drivers/staging/hv/ChannelMgmt.c
@@ -20,6 +20,7 @@
*/
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include "osd.h"
#include "logging.h"
diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c
index 43c2e685501..e0ea9cf90f0 100644
--- a/drivers/staging/hv/Connection.c
+++ b/drivers/staging/hv/Connection.c
@@ -22,6 +22,7 @@
*/
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "osd.h"
#include "logging.h"
diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c
index c2809f2a2ce..3a1112d29ae 100644
--- a/drivers/staging/hv/Hv.c
+++ b/drivers/staging/hv/Hv.c
@@ -21,6 +21,7 @@
*/
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "osd.h"
#include "logging.h"
@@ -208,50 +209,51 @@ int HvInit(void)
/* HvQueryHypervisorFeatures(maxLeaf); */
/*
- * Determine if we are running on xenlinux (ie x2v shim) or native
- * linux
+ * We only support running on top of Hyper-V
*/
rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId);
- if (gHvContext.GuestId == 0) {
- /* Write our OS info */
- wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
- gHvContext.GuestId = HV_LINUX_GUEST_ID;
+
+ if (gHvContext.GuestId != 0) {
+ DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
+ gHvContext.GuestId);
+ goto Cleanup;
}
+ /* Write our OS info */
+ wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
+ gHvContext.GuestId = HV_LINUX_GUEST_ID;
+
/* See if the hypercall page is already set */
rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
- if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
- /* Allocate the hypercall page memory */
- /* virtAddr = osd_PageAlloc(1); */
- virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
-
- if (!virtAddr) {
- DPRINT_ERR(VMBUS,
- "unable to allocate hypercall page!!");
- goto Cleanup;
- }
- hypercallMsr.Enable = 1;
- /* hypercallMsr.GuestPhysicalAddress =
- * virt_to_phys(virtAddr) >> PAGE_SHIFT; */
- hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
- wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+ /*
+ * Allocate the hypercall page memory
+ * virtAddr = osd_PageAlloc(1);
+ */
+ virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
- /* Confirm that hypercall page did get setup. */
- hypercallMsr.AsUINT64 = 0;
- rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
- if (!hypercallMsr.Enable) {
- DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
- goto Cleanup;
- }
+ if (!virtAddr) {
+ DPRINT_ERR(VMBUS,
+ "unable to allocate hypercall page!!");
+ goto Cleanup;
+ }
- gHvContext.HypercallPage = virtAddr;
- } else {
- DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
- gHvContext.GuestId);
+ hypercallMsr.Enable = 1;
+
+ hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
+ wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+
+ /* Confirm that hypercall page did get setup. */
+ hypercallMsr.AsUINT64 = 0;
+ rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+
+ if (!hypercallMsr.Enable) {
+ DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
goto Cleanup;
}
+ gHvContext.HypercallPage = virtAddr;
+
DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx",
gHvContext.HypercallPage,
(u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT);
@@ -273,8 +275,6 @@ int HvInit(void)
gHvContext.SignalEventParam->FlagNumber = 0;
gHvContext.SignalEventParam->RsvdZ = 0;
- /* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */
-
DPRINT_EXIT(VMBUS);
return ret;
@@ -306,22 +306,19 @@ void HvCleanup(void)
DPRINT_ENTER(VMBUS);
if (gHvContext.SignalEventBuffer) {
+ kfree(gHvContext.SignalEventBuffer);
gHvContext.SignalEventBuffer = NULL;
gHvContext.SignalEventParam = NULL;
- kfree(gHvContext.SignalEventBuffer);
}
- if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
- if (gHvContext.HypercallPage) {
- hypercallMsr.AsUINT64 = 0;
- wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
- vfree(gHvContext.HypercallPage);
- gHvContext.HypercallPage = NULL;
- }
+ if (gHvContext.HypercallPage) {
+ hypercallMsr.AsUINT64 = 0;
+ wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+ vfree(gHvContext.HypercallPage);
+ gHvContext.HypercallPage = NULL;
}
DPRINT_EXIT(VMBUS);
-
}
/**
@@ -393,7 +390,7 @@ void HvSynicInit(void *irqarg)
union hv_synic_siefp siefp;
union hv_synic_sint sharedSint;
union hv_synic_scontrol sctrl;
- u64 guestID;
+
u32 irqVector = *((u32 *)(irqarg));
int cpu = smp_processor_id();
@@ -409,71 +406,41 @@ void HvSynicInit(void *irqarg)
DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
- /* TODO: Handle SMP */
- if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID) {
- DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since "
- "it is already set.");
-
- rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
- rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
-
- DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx",
- simp.AsUINT64, siefp.AsUINT64);
-
- /*
- * Determine if we are running on xenlinux (ie x2v shim) or
- * native linux
- */
- rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
- if (guestID == HV_LINUX_GUEST_ID) {
- gHvContext.synICMessagePage[cpu] =
- phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
- gHvContext.synICEventPage[cpu] =
- phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
- } else {
- DPRINT_ERR(VMBUS, "unknown guest id!!");
- goto Cleanup;
- }
- DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p",
- gHvContext.synICMessagePage[cpu],
- gHvContext.synICEventPage[cpu]);
- } else {
- gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
- if (gHvContext.synICMessagePage[cpu] == NULL) {
- DPRINT_ERR(VMBUS,
- "unable to allocate SYNIC message page!!");
- goto Cleanup;
- }
+ gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
- gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
- if (gHvContext.synICEventPage[cpu] == NULL) {
- DPRINT_ERR(VMBUS,
- "unable to allocate SYNIC event page!!");
- goto Cleanup;
- }
+ if (gHvContext.synICMessagePage[cpu] == NULL) {
+ DPRINT_ERR(VMBUS,
+ "unable to allocate SYNIC message page!!");
+ goto Cleanup;
+ }
+
+ gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
- /* Setup the Synic's message page */
- rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
- simp.SimpEnabled = 1;
- simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
- >> PAGE_SHIFT;
+ if (gHvContext.synICEventPage[cpu] == NULL) {
+ DPRINT_ERR(VMBUS,
+ "unable to allocate SYNIC event page!!");
+ goto Cleanup;
+ }
- DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx",
- simp.AsUINT64);
+ /* Setup the Synic's message page */
+ rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+ simp.SimpEnabled = 1;
+ simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
+ >> PAGE_SHIFT;
- wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+ DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64);
- /* Setup the Synic's event page */
- rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
- siefp.SiefpEnabled = 1;
- siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
- >> PAGE_SHIFT;
+ wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
- DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx",
- siefp.AsUINT64);
+ /* Setup the Synic's event page */
+ rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+ siefp.SiefpEnabled = 1;
+ siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
+ >> PAGE_SHIFT;
- wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
- }
+ DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64);
+
+ wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
/* Setup the interception SINT. */
/* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
@@ -505,13 +472,11 @@ void HvSynicInit(void *irqarg)
return;
Cleanup:
- if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
- if (gHvContext.synICEventPage[cpu])
- osd_PageFree(gHvContext.synICEventPage[cpu], 1);
+ if (gHvContext.synICEventPage[cpu])
+ osd_PageFree(gHvContext.synICEventPage[cpu], 1);
- if (gHvContext.synICMessagePage[cpu])
- osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
- }
+ if (gHvContext.synICMessagePage[cpu])
+ osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
DPRINT_EXIT(VMBUS);
return;
@@ -542,27 +507,20 @@ void HvSynicCleanup(void *arg)
/* Disable the interrupt */
wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
- /*
- * Disable and free the resources only if we are running as
- * native linux since in xenlinux, we are sharing the
- * resources with the x2v shim
- */
- if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
- rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
- simp.SimpEnabled = 0;
- simp.BaseSimpGpa = 0;
+ rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+ simp.SimpEnabled = 0;
+ simp.BaseSimpGpa = 0;
- wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+ wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
- rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
- siefp.SiefpEnabled = 0;
- siefp.BaseSiefpGpa = 0;
+ rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+ siefp.SiefpEnabled = 0;
+ siefp.BaseSiefpGpa = 0;
- wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+ wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
- osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
- osd_PageFree(gHvContext.synICEventPage[cpu], 1);
- }
+ osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
+ osd_PageFree(gHvContext.synICEventPage[cpu], 1);
DPRINT_EXIT(VMBUS);
}
diff --git a/drivers/staging/hv/Hv.h b/drivers/staging/hv/Hv.h
index fce4b5cdac3..41f5ebb86e1 100644
--- a/drivers/staging/hv/Hv.h
+++ b/drivers/staging/hv/Hv.h
@@ -41,11 +41,6 @@ enum {
#define HV_PRESENT_BIT 0x80000000
-#define HV_XENLINUX_GUEST_ID_LO 0x00000000
-#define HV_XENLINUX_GUEST_ID_HI 0x0B00B135
-#define HV_XENLINUX_GUEST_ID (((u64)HV_XENLINUX_GUEST_ID_HI << 32) \
- | HV_XENLINUX_GUEST_ID_LO)
-
#define HV_LINUX_GUEST_ID_LO 0x00000000
#define HV_LINUX_GUEST_ID_HI 0xB16B00B5
#define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \
@@ -102,8 +97,9 @@ struct hv_input_signal_event_buffer {
};
struct hv_context {
- /* XenLinux or native Linux. If XenLinux, the hypercall and synic pages
- * has already been initialized */
+ /* We only support running on top of Hyper-V
+ * So at this point this really can only contain the Hyper-V ID
+ */
u64 GuestId;
void *HypercallPage;
diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c
index 1c717f9a554..e4bf8229750 100644
--- a/drivers/staging/hv/NetVsc.c
+++ b/drivers/staging/hv/NetVsc.c
@@ -22,6 +22,7 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include "osd.h"
#include "logging.h"
#include "NetVsc.h"
diff --git a/drivers/staging/hv/NetVscApi.h b/drivers/staging/hv/NetVscApi.h
index 1ce2b74a34a..95d7a32b12f 100644
--- a/drivers/staging/hv/NetVscApi.h
+++ b/drivers/staging/hv/NetVscApi.h
@@ -105,8 +105,6 @@ struct netvsc_driver {
void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status);
/* Specific to this driver */
- int (*OnOpen)(struct hv_device *dev);
- int (*OnClose)(struct hv_device *dev);
int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet);
void *Context;
@@ -119,5 +117,7 @@ struct netvsc_device_info {
/* Interface */
int NetVscInitialize(struct hv_driver *drv);
+int RndisFilterOnOpen(struct hv_device *Device);
+int RndisFilterOnClose(struct hv_device *Device);
#endif /* _NETVSC_API_H_ */
diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c
index f69ae33a91e..80b8a2c7784 100644
--- a/drivers/staging/hv/RingBuffer.c
+++ b/drivers/staging/hv/RingBuffer.c
@@ -48,7 +48,7 @@ Description:
static inline void
GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write)
{
- u32 read_loc,write_loc;
+ u32 read_loc, write_loc;
/* Capture the read/write indices before they changed */
read_loc = rbi->RingBuffer->ReadIndex;
@@ -68,7 +68,7 @@ Description:
--*/
static inline u32
-GetNextWriteLocation(RING_BUFFER_INFO* RingInfo)
+GetNextWriteLocation(RING_BUFFER_INFO *RingInfo)
{
u32 next = RingInfo->RingBuffer->WriteIndex;
@@ -87,7 +87,7 @@ Description:
--*/
static inline void
-SetNextWriteLocation(RING_BUFFER_INFO* RingInfo, u32 NextWriteLocation)
+SetNextWriteLocation(RING_BUFFER_INFO *RingInfo, u32 NextWriteLocation)
{
RingInfo->RingBuffer->WriteIndex = NextWriteLocation;
}
@@ -102,7 +102,7 @@ Description:
--*/
static inline u32
-GetNextReadLocation(RING_BUFFER_INFO* RingInfo)
+GetNextReadLocation(RING_BUFFER_INFO *RingInfo)
{
u32 next = RingInfo->RingBuffer->ReadIndex;
@@ -122,7 +122,7 @@ Description:
--*/
static inline u32
-GetNextReadLocationWithOffset(RING_BUFFER_INFO* RingInfo, u32 Offset)
+GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset)
{
u32 next = RingInfo->RingBuffer->ReadIndex;
@@ -143,7 +143,7 @@ Description:
--*/
static inline void
-SetNextReadLocation(RING_BUFFER_INFO* RingInfo, u32 NextReadLocation)
+SetNextReadLocation(RING_BUFFER_INFO *RingInfo, u32 NextReadLocation)
{
RingInfo->RingBuffer->ReadIndex = NextReadLocation;
}
@@ -159,7 +159,7 @@ Description:
--*/
static inline void *
-GetRingBuffer(RING_BUFFER_INFO* RingInfo)
+GetRingBuffer(RING_BUFFER_INFO *RingInfo)
{
return (void *)RingInfo->RingBuffer->Buffer;
}
@@ -175,7 +175,7 @@ Description:
--*/
static inline u32
-GetRingBufferSize(RING_BUFFER_INFO* RingInfo)
+GetRingBufferSize(RING_BUFFER_INFO *RingInfo)
{
return RingInfo->RingDataSize;
}
@@ -190,9 +190,10 @@ Description:
--*/
static inline u64
-GetRingBufferIndices(RING_BUFFER_INFO* RingInfo)
+GetRingBufferIndices(RING_BUFFER_INFO *RingInfo)
{
- return ((u64)RingInfo->RingBuffer->WriteIndex << 32) || RingInfo->RingBuffer->ReadIndex;
+ return ((u64)RingInfo->RingBuffer->WriteIndex << 32)
+ || RingInfo->RingBuffer->ReadIndex;
}
@@ -210,9 +211,14 @@ void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix)
u32 bytesAvailToWrite;
u32 bytesAvailToRead;
- GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+ GetRingBufferAvailBytes(RingInfo,
+ &bytesAvailToRead,
+ &bytesAvailToWrite);
- DPRINT(VMBUS, DEBUG_RING_LVL, "%s <<ringinfo %p buffer %p avail write %u avail read %u read idx %u write idx %u>>",
+ DPRINT(VMBUS,
+ DEBUG_RING_LVL,
+ "%s <<ringinfo %p buffer %p avail write %u "
+ "avail read %u read idx %u write idx %u>>",
Prefix,
RingInfo,
RingInfo->RingBuffer->Buffer,
@@ -229,13 +235,13 @@ static u32
CopyToRingBuffer(
RING_BUFFER_INFO *RingInfo,
u32 StartWriteOffset,
- void * Src,
+ void *Src,
u32 SrcLen);
static u32
CopyFromRingBuffer(
RING_BUFFER_INFO *RingInfo,
- void * Dest,
+ void *Dest,
u32 DestLen,
u32 StartReadOffset);
@@ -256,15 +262,15 @@ void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo,
u32 bytesAvailToWrite;
u32 bytesAvailToRead;
- if (RingInfo->RingBuffer)
- {
- GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+ if (RingInfo->RingBuffer) {
+ GetRingBufferAvailBytes(RingInfo,
+ &bytesAvailToRead,
+ &bytesAvailToWrite);
DebugInfo->BytesAvailToRead = bytesAvailToRead;
DebugInfo->BytesAvailToWrite = bytesAvailToWrite;
DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex;
DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex;
-
DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask;
}
}
@@ -299,7 +305,7 @@ int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen)
memset(RingInfo, 0, sizeof(RING_BUFFER_INFO));
- RingInfo->RingBuffer = (RING_BUFFER*)Buffer;
+ RingInfo->RingBuffer = (RING_BUFFER *)Buffer;
RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0;
RingInfo->RingSize = BufferLen;
@@ -319,7 +325,7 @@ Description:
Cleanup the ring buffer
--*/
-void RingBufferCleanup(RING_BUFFER_INFO* RingInfo)
+void RingBufferCleanup(RING_BUFFER_INFO *RingInfo)
{
}
@@ -335,14 +341,14 @@ Description:
int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
struct scatterlist *sglist, u32 sgcount)
{
- int i=0;
+ int i = 0;
u32 byteAvailToWrite;
u32 byteAvailToRead;
- u32 totalBytesToWrite=0;
+ u32 totalBytesToWrite = 0;
struct scatterlist *sg;
volatile u32 nextWriteLocation;
- u64 prevIndices=0;
+ u64 prevIndices = 0;
unsigned long flags;
DPRINT_ENTER(VMBUS);
@@ -356,17 +362,23 @@ int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
spin_lock_irqsave(&OutRingInfo->ring_lock, flags);
- GetRingBufferAvailBytes(OutRingInfo, &byteAvailToRead, &byteAvailToWrite);
+ GetRingBufferAvailBytes(OutRingInfo,
+ &byteAvailToRead,
+ &byteAvailToWrite);
DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite);
/* DumpRingInfo(OutRingInfo, "BEFORE "); */
- /* If there is only room for the packet, assume it is full. Otherwise, the next time around, we think the ring buffer */
+ /* If there is only room for the packet, assume it is full. */
+ /* Otherwise, the next time around, we think the ring buffer */
/* is empty since the read index == write index */
- if (byteAvailToWrite <= totalBytesToWrite)
- {
- DPRINT_DBG(VMBUS, "No more space left on outbound ring buffer (needed %u, avail %u)", totalBytesToWrite, byteAvailToWrite);
+ if (byteAvailToWrite <= totalBytesToWrite) {
+ DPRINT_DBG(VMBUS,
+ "No more space left on outbound ring buffer "
+ "(needed %u, avail %u)",
+ totalBytesToWrite,
+ byteAvailToWrite);
spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
@@ -423,17 +435,22 @@ int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen)
{
u32 bytesAvailToWrite;
u32 bytesAvailToRead;
- u32 nextReadLocation=0;
+ u32 nextReadLocation = 0;
unsigned long flags;
spin_lock_irqsave(&InRingInfo->ring_lock, flags);
- GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+ GetRingBufferAvailBytes(InRingInfo,
+ &bytesAvailToRead,
+ &bytesAvailToWrite);
/* Make sure there is something to read */
- if (bytesAvailToRead < BufferLen )
- {
- /* DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen); */
+ if (bytesAvailToRead < BufferLen) {
+ /* DPRINT_DBG(VMBUS,
+ "got callback but not enough to read "
+ "<avail to read %d read size %d>!!",
+ bytesAvailToRead,
+ BufferLen); */
spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
@@ -444,9 +461,9 @@ int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen)
nextReadLocation = GetNextReadLocation(InRingInfo);
nextReadLocation = CopyFromRingBuffer(InRingInfo,
- Buffer,
- BufferLen,
- nextReadLocation);
+ Buffer,
+ BufferLen,
+ nextReadLocation);
spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
@@ -468,24 +485,29 @@ int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer,
{
u32 bytesAvailToWrite;
u32 bytesAvailToRead;
- u32 nextReadLocation=0;
- u64 prevIndices=0;
+ u32 nextReadLocation = 0;
+ u64 prevIndices = 0;
unsigned long flags;
ASSERT(BufferLen > 0);
spin_lock_irqsave(&InRingInfo->ring_lock, flags);
- GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+ GetRingBufferAvailBytes(InRingInfo,
+ &bytesAvailToRead,
+ &bytesAvailToWrite);
DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen);
/* DumpRingInfo(InRingInfo, "BEFORE "); */
/* Make sure there is something to read */
- if (bytesAvailToRead < BufferLen )
- {
- DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen);
+ if (bytesAvailToRead < BufferLen) {
+ DPRINT_DBG(VMBUS,
+ "got callback but not enough to read "
+ "<avail to read %d read size %d>!!",
+ bytesAvailToRead,
+ BufferLen);
spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
@@ -495,17 +517,18 @@ int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer,
nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset);
nextReadLocation = CopyFromRingBuffer(InRingInfo,
- Buffer,
- BufferLen,
- nextReadLocation);
+ Buffer,
+ BufferLen,
+ nextReadLocation);
nextReadLocation = CopyFromRingBuffer(InRingInfo,
- &prevIndices,
- sizeof(u64),
- nextReadLocation);
+ &prevIndices,
+ sizeof(u64),
+ nextReadLocation);
/* Make sure all reads are done before we update the read index since */
- /* the writer may start writing to the read area once the read index is updated */
+ /* the writer may start writing to the read area once the read index */
+ /*is updated */
mb();
/* Update the read index */
@@ -533,25 +556,22 @@ static u32
CopyToRingBuffer(
RING_BUFFER_INFO *RingInfo,
u32 StartWriteOffset,
- void * Src,
+ void *Src,
u32 SrcLen)
{
- void * ringBuffer=GetRingBuffer(RingInfo);
- u32 ringBufferSize=GetRingBufferSize(RingInfo);
+ void *ringBuffer = GetRingBuffer(RingInfo);
+ u32 ringBufferSize = GetRingBufferSize(RingInfo);
u32 fragLen;
- if (SrcLen > ringBufferSize - StartWriteOffset) /* wrap-around detected! */
- {
+ /* wrap-around detected! */
+ if (SrcLen > ringBufferSize - StartWriteOffset) {
DPRINT_DBG(VMBUS, "wrap-around detected!");
fragLen = ringBufferSize - StartWriteOffset;
memcpy(ringBuffer + StartWriteOffset, Src, fragLen);
memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen);
- }
- else
- {
+ } else
memcpy(ringBuffer + StartWriteOffset, Src, SrcLen);
- }
StartWriteOffset += SrcLen;
StartWriteOffset %= ringBufferSize;
@@ -573,28 +593,27 @@ Description:
static u32
CopyFromRingBuffer(
RING_BUFFER_INFO *RingInfo,
- void * Dest,
+ void *Dest,
u32 DestLen,
u32 StartReadOffset)
{
- void * ringBuffer=GetRingBuffer(RingInfo);
- u32 ringBufferSize=GetRingBufferSize(RingInfo);
+ void *ringBuffer = GetRingBuffer(RingInfo);
+ u32 ringBufferSize = GetRingBufferSize(RingInfo);
u32 fragLen;
- if (DestLen > ringBufferSize - StartReadOffset) /* wrap-around detected at the src */
- {
+ /* wrap-around detected at the src */
+ if (DestLen > ringBufferSize - StartReadOffset) {
DPRINT_DBG(VMBUS, "src wrap-around detected!");
fragLen = ringBufferSize - StartReadOffset;
memcpy(Dest, ringBuffer + StartReadOffset, fragLen);
memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen);
- }
- else
- {
+ } else
+
memcpy(Dest, ringBuffer + StartReadOffset, DestLen);
- }
+
StartReadOffset += DestLen;
StartReadOffset %= ringBufferSize;
diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c
index 26d79975387..6704f64c93f 100644
--- a/drivers/staging/hv/RndisFilter.c
+++ b/drivers/staging/hv/RndisFilter.c
@@ -20,6 +20,7 @@
*/
#include <linux/kernel.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include "osd.h"
#include "logging.h"
@@ -85,10 +86,6 @@ static int RndisFilterOnDeviceRemove(struct hv_device *Device);
static void RndisFilterOnCleanup(struct hv_driver *Driver);
-static int RndisFilterOnOpen(struct hv_device *Device);
-
-static int RndisFilterOnClose(struct hv_device *Device);
-
static int RndisFilterOnSend(struct hv_device *Device,
struct hv_netvsc_packet *Packet);
@@ -654,8 +651,6 @@ int RndisFilterInit(struct netvsc_driver *Driver)
Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
Driver->Base.OnCleanup = RndisFilterOnCleanup;
Driver->OnSend = RndisFilterOnSend;
- Driver->OnOpen = RndisFilterOnOpen;
- Driver->OnClose = RndisFilterOnClose;
/* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */
Driver->OnReceiveCallback = RndisFilterOnReceive;
@@ -756,6 +751,7 @@ static int RndisFilterOpenDevice(struct rndis_device *Device)
ret = RndisFilterSetPacketFilter(Device,
NDIS_PACKET_TYPE_BROADCAST |
+ NDIS_PACKET_TYPE_ALL_MULTICAST |
NDIS_PACKET_TYPE_DIRECTED);
if (ret == 0)
Device->State = RNDIS_DEV_DATAINITIALIZED;
@@ -888,7 +884,7 @@ static void RndisFilterOnCleanup(struct hv_driver *Driver)
DPRINT_EXIT(NETVSC);
}
-static int RndisFilterOnOpen(struct hv_device *Device)
+int RndisFilterOnOpen(struct hv_device *Device)
{
int ret;
struct netvsc_device *netDevice = Device->Extension;
@@ -903,7 +899,7 @@ static int RndisFilterOnOpen(struct hv_device *Device)
return ret;
}
-static int RndisFilterOnClose(struct hv_device *Device)
+int RndisFilterOnClose(struct hv_device *Device)
{
int ret;
struct netvsc_device *netDevice = Device->Extension;
diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c
index 2f7c425896f..e426a23ca53 100644
--- a/drivers/staging/hv/StorVsc.c
+++ b/drivers/staging/hv/StorVsc.c
@@ -20,6 +20,7 @@
*/
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include "osd.h"
@@ -625,7 +626,7 @@ static int StorVscOnDeviceRemove(struct hv_device *Device)
return 0;
}
-static int StorVscOnHostReset(struct hv_device *Device)
+int StorVscOnHostReset(struct hv_device *Device)
{
struct storvsc_device *storDevice;
struct storvsc_request_extension *request;
@@ -842,7 +843,6 @@ int StorVscInitialize(struct hv_driver *Driver)
storDriver->Base.OnCleanup = StorVscOnCleanup;
storDriver->OnIORequest = StorVscOnIORequest;
- storDriver->OnHostReset = StorVscOnHostReset;
DPRINT_EXIT(STORVSC);
diff --git a/drivers/staging/hv/StorVscApi.h b/drivers/staging/hv/StorVscApi.h
index 69c14066c47..126a8588edb 100644
--- a/drivers/staging/hv/StorVscApi.h
+++ b/drivers/staging/hv/StorVscApi.h
@@ -91,13 +91,9 @@ struct storvsc_driver_object {
/* Maximum # of requests in flight per channel/device */
u32 MaxOutstandingRequestsPerChannel;
- /* Set by the caller to allow us to re-enumerate the bus on the host */
- void (*OnHostRescan)(struct hv_device *Device);
-
/* Specific to this driver */
int (*OnIORequest)(struct hv_device *Device,
struct hv_storvsc_request *Request);
- int (*OnHostReset)(struct hv_device *Device);
};
struct storvsc_device_info {
@@ -108,6 +104,7 @@ struct storvsc_device_info {
/* Interface */
int StorVscInitialize(struct hv_driver *driver);
+int StorVscOnHostReset(struct hv_device *Device);
int BlkVscInitialize(struct hv_driver *driver);
#endif /* _STORVSC_API_H_ */
diff --git a/drivers/staging/hv/VersionInfo.h b/drivers/staging/hv/VersionInfo.h
index 9c3641d99ed..10d7b19a485 100644
--- a/drivers/staging/hv/VersionInfo.h
+++ b/drivers/staging/hv/VersionInfo.h
@@ -24,8 +24,24 @@
#ifndef __HV_VERSION_INFO
#define __HV_VERSION_INFO
-static const char VersionDate[] = __DATE__;
-static const char VersionTime[] = __TIME__;
-static const char VersionDesc[] = "Version 2.0";
+/*
+ * We use the same version numbering for all Hyper-V modules.
+ *
+ * Definition of versioning is as follows;
+ *
+ * Major Number Changes for these scenarios;
+ * 1. When a new version of Windows Hyper-V
+ * is released.
+ * 2. A Major change has occurred in the
+ * Linux IC's.
+ * (For example the merge for the first time
+ * into the kernel) Every time the Major Number
+ * changes, the Revision number is reset to 0.
+ * Minor Number Changes when new functionality is added
+ * to the Linux IC's that is not a bug fix.
+ *
+ */
+#define HV_DRV_VERSION "3.0"
+
#endif
diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c
index 35a023e9f9d..2f84bf7c0a9 100644
--- a/drivers/staging/hv/Vmbus.c
+++ b/drivers/staging/hv/Vmbus.c
@@ -21,6 +21,7 @@
*/
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include "osd.h"
#include "logging.h"
#include "VersionInfo.h"
@@ -273,10 +274,8 @@ int VmbusInitialize(struct hv_driver *drv)
DPRINT_ENTER(VMBUS);
- DPRINT_INFO(VMBUS, "+++++++ Build Date=%s %s +++++++",
- VersionDate, VersionTime);
- DPRINT_INFO(VMBUS, "+++++++ Build Description=%s +++++++",
- VersionDesc);
+ DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++",
+ HV_DRV_VERSION);
DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++",
VMBUS_REVISION_NUMBER);
DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++",
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
index 45d908114d1..8f1fda3256a 100644
--- a/drivers/staging/hv/blkvsc_drv.c
+++ b/drivers/staging/hv/blkvsc_drv.c
@@ -25,12 +25,14 @@
#include <linux/major.h>
#include <linux/delay.h>
#include <linux/hdreg.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_dbg.h>
#include "osd.h"
#include "logging.h"
+#include "VersionInfo.h"
#include "vmbus.h"
#include "StorVscApi.h"
@@ -92,7 +94,7 @@ struct blkvsc_request {
/* Per device structure */
struct block_device_context {
/* point back to our device context */
- struct device_context *device_ctx;
+ struct vm_device *device_ctx;
struct kmem_cache *request_pool;
spinlock_t lock;
struct gendisk *gd;
@@ -254,7 +256,7 @@ static int blkvsc_probe(struct device *device)
(struct blkvsc_driver_context *)driver_ctx;
struct storvsc_driver_object *storvsc_drv_obj =
&blkvsc_drv_ctx->drv_obj;
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
struct hv_device *device_obj = &device_ctx->device_obj;
struct block_device_context *blkdev = NULL;
@@ -742,7 +744,7 @@ static int blkvsc_remove(struct device *device)
(struct blkvsc_driver_context *)driver_ctx;
struct storvsc_driver_object *storvsc_drv_obj =
&blkvsc_drv_ctx->drv_obj;
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
struct hv_device *device_obj = &device_ctx->device_obj;
struct block_device_context *blkdev = dev_get_drvdata(device);
unsigned long flags;
@@ -862,7 +864,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
void (*request_completion)(struct hv_storvsc_request *))
{
struct block_device_context *blkdev = blkvsc_req->dev;
- struct device_context *device_ctx = blkdev->device_ctx;
+ struct vm_device *device_ctx = blkdev->device_ctx;
struct driver_context *driver_ctx =
driver_to_driver_context(device_ctx->device.driver);
struct blkvsc_driver_context *blkvsc_drv_ctx =
@@ -1504,6 +1506,7 @@ static void __exit blkvsc_exit(void)
}
MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
module_param(blkvsc_ringbuffer_size, int, S_IRUGO);
module_init(blkvsc_init);
module_exit(blkvsc_exit);
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index 0d7459e2d03..ab27d9a4446 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -29,20 +29,20 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <net/route.h>
#include <net/sock.h>
#include <net/pkt_sched.h>
#include "osd.h"
#include "logging.h"
+#include "VersionInfo.h"
#include "vmbus.h"
#include "NetVscApi.h"
-MODULE_LICENSE("GPL");
-
struct net_device_context {
/* point back to our device context */
- struct device_context *device_ctx;
+ struct vm_device *device_ctx;
struct net_device_stats stats;
};
@@ -72,11 +72,6 @@ static void netvsc_set_multicast_list(struct net_device *net)
static int netvsc_open(struct net_device *net)
{
struct net_device_context *net_device_ctx = netdev_priv(net);
- struct driver_context *driver_ctx =
- driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
- struct netvsc_driver_context *net_drv_ctx =
- (struct netvsc_driver_context *)driver_ctx;
- struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
int ret = 0;
@@ -87,7 +82,7 @@ static int netvsc_open(struct net_device *net)
sizeof(struct net_device_stats));
/* Open up the device */
- ret = net_drv_obj->OnOpen(device_obj);
+ ret = RndisFilterOnOpen(device_obj);
if (ret != 0) {
DPRINT_ERR(NETVSC_DRV,
"unable to open device (ret %d).", ret);
@@ -106,11 +101,6 @@ static int netvsc_open(struct net_device *net)
static int netvsc_close(struct net_device *net)
{
struct net_device_context *net_device_ctx = netdev_priv(net);
- struct driver_context *driver_ctx =
- driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
- struct netvsc_driver_context *net_drv_ctx =
- (struct netvsc_driver_context *)driver_ctx;
- struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
int ret;
@@ -118,7 +108,7 @@ static int netvsc_close(struct net_device *net)
netif_stop_queue(net);
- ret = net_drv_obj->OnClose(device_obj);
+ ret = RndisFilterOnClose(device_obj);
if (ret != 0)
DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret);
@@ -282,7 +272,7 @@ retry_send:
static void netvsc_linkstatus_callback(struct hv_device *device_obj,
unsigned int status)
{
- struct device_context *device_ctx = to_device_context(device_obj);
+ struct vm_device *device_ctx = to_vm_device(device_obj);
struct net_device *net = dev_get_drvdata(&device_ctx->device);
DPRINT_ENTER(NETVSC_DRV);
@@ -309,7 +299,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj,
static int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet)
{
- struct device_context *device_ctx = to_device_context(device_obj);
+ struct vm_device *device_ctx = to_vm_device(device_obj);
struct net_device *net = dev_get_drvdata(&device_ctx->device);
struct net_device_context *net_device_ctx;
struct sk_buff *skb;
@@ -401,7 +391,7 @@ static int netvsc_probe(struct device *device)
struct netvsc_driver_context *net_drv_ctx =
(struct netvsc_driver_context *)driver_ctx;
struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
struct hv_device *device_obj = &device_ctx->device_obj;
struct net_device *net = NULL;
struct net_device_context *net_device_ctx;
@@ -413,8 +403,7 @@ static int netvsc_probe(struct device *device)
if (!net_drv_obj->Base.OnDeviceAdd)
return -1;
- net = alloc_netdev(sizeof(struct net_device_context), "seth%d",
- ether_setup);
+ net = alloc_etherdev(sizeof(struct net_device_context));
if (!net)
return -1;
@@ -473,7 +462,7 @@ static int netvsc_remove(struct device *device)
struct netvsc_driver_context *net_drv_ctx =
(struct netvsc_driver_context *)driver_ctx;
struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
struct net_device *net = dev_get_drvdata(&device_ctx->device);
struct hv_device *device_obj = &device_ctx->device_obj;
int ret;
@@ -613,6 +602,8 @@ static void __exit netvsc_exit(void)
DPRINT_EXIT(NETVSC_DRV);
}
+MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
module_param(netvsc_ringbuffer_size, int, S_IRUGO);
module_init(netvsc_init);
diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c
index 3a4793a0fd0..9aea3106729 100644
--- a/drivers/staging/hv/osd.c
+++ b/drivers/staging/hv/osd.c
@@ -40,6 +40,7 @@
#include <linux/time.h>
#include <linux/io.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include "osd.h"
struct osd_callback_struct {
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index d49dc21d4cb..8a58272b803 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -19,6 +19,7 @@
* Hank Janssen <hjanssen@microsoft.com>
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/blkdev.h>
@@ -32,6 +33,7 @@
#include <scsi/scsi_dbg.h>
#include "osd.h"
#include "logging.h"
+#include "VersionInfo.h"
#include "vmbus.h"
#include "StorVscApi.h"
@@ -39,10 +41,8 @@
struct host_device_context {
/* must be 1st field
* FIXME this is a bug */
- struct work_struct host_rescan_work;
-
/* point back to our device context */
- struct device_context *device_ctx;
+ struct vm_device *device_ctx;
struct kmem_cache *request_pool;
unsigned int port;
unsigned char path;
@@ -77,8 +77,6 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
static int storvsc_device_alloc(struct scsi_device *);
static int storvsc_device_configure(struct scsi_device *);
static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd);
-static void storvsc_host_rescan_callback(struct work_struct *work);
-static void storvsc_host_rescan(struct hv_device *device_obj);
static int storvsc_remove(struct device *dev);
static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
@@ -94,8 +92,6 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
struct scatterlist *bounce_sgl,
unsigned int orig_sgl_count);
-static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[],
- unsigned int *lun_count);
static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int *info);
@@ -148,7 +144,6 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface);
storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size;
- storvsc_drv_obj->OnHostRescan = storvsc_host_rescan;
/* Callback to client driver to complete the initialization */
drv_init(&storvsc_drv_obj->Base);
@@ -240,7 +235,7 @@ static int storvsc_probe(struct device *device)
(struct storvsc_driver_context *)driver_ctx;
struct storvsc_driver_object *storvsc_drv_obj =
&storvsc_drv_ctx->drv_obj;
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
struct hv_device *device_obj = &device_ctx->device_obj;
struct Scsi_Host *host;
struct host_device_context *host_device_ctx;
@@ -266,9 +261,6 @@ static int storvsc_probe(struct device *device)
host_device_ctx->port = host->host_no;
host_device_ctx->device_ctx = device_ctx;
- INIT_WORK(&host_device_ctx->host_rescan_work,
- storvsc_host_rescan_callback);
-
host_device_ctx->request_pool =
kmem_cache_create(dev_name(&device_ctx->device),
sizeof(struct storvsc_cmd_request) +
@@ -339,7 +331,7 @@ static int storvsc_remove(struct device *device)
(struct storvsc_driver_context *)driver_ctx;
struct storvsc_driver_object *storvsc_drv_obj =
&storvsc_drv_ctx->drv_obj;
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
struct hv_device *device_obj = &device_ctx->device_obj;
struct Scsi_Host *host = dev_get_drvdata(device);
struct host_device_context *host_device_ctx =
@@ -640,7 +632,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
int ret;
struct host_device_context *host_device_ctx =
(struct host_device_context *)scmnd->device->host->hostdata;
- struct device_context *device_ctx = host_device_ctx->device_ctx;
+ struct vm_device *device_ctx = host_device_ctx->device_ctx;
struct driver_context *driver_ctx =
driver_to_driver_context(device_ctx->device.driver);
struct storvsc_driver_context *storvsc_drv_ctx =
@@ -879,14 +871,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
int ret;
struct host_device_context *host_device_ctx =
(struct host_device_context *)scmnd->device->host->hostdata;
- struct device_context *device_ctx = host_device_ctx->device_ctx;
- struct driver_context *driver_ctx =
- driver_to_driver_context(device_ctx->device.driver);
- struct storvsc_driver_context *storvsc_drv_ctx =
- (struct storvsc_driver_context *)driver_ctx;
-
- struct storvsc_driver_object *storvsc_drv_obj =
- &storvsc_drv_ctx->drv_obj;
+ struct vm_device *device_ctx = host_device_ctx->device_ctx;
DPRINT_ENTER(STORVSC_DRV);
@@ -894,8 +879,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
scmnd->device, &device_ctx->device_obj);
/* Invokes the vsc to reset the host/bus */
- ASSERT(storvsc_drv_obj->OnHostReset);
- ret = storvsc_drv_obj->OnHostReset(&device_ctx->device_obj);
+ ret = StorVscOnHostReset(&device_ctx->device_obj);
if (ret != 0) {
DPRINT_EXIT(STORVSC_DRV);
return ret;
@@ -909,201 +893,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
return ret;
}
-/**
- * storvsc_host_rescan - Rescan the scsi HBA
- */
-static void storvsc_host_rescan_callback(struct work_struct *work)
-{
- struct hv_device *device_obj =
- &((struct host_device_context *)work)->device_ctx->device_obj;
- struct device_context *device_ctx = to_device_context(device_obj);
- struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device);
- struct scsi_device *sdev;
- struct host_device_context *host_device_ctx;
- struct scsi_device **sdevs_remove_list;
- unsigned int sdevs_count = 0;
- unsigned int found;
- unsigned int i;
- unsigned int lun_count = 0;
- unsigned int *lun_list;
-
- DPRINT_ENTER(STORVSC_DRV);
-
- host_device_ctx = (struct host_device_context *)host->hostdata;
- lun_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET, sizeof(unsigned int),
- GFP_ATOMIC);
- if (!lun_list) {
- DPRINT_ERR(STORVSC_DRV, "unable to allocate lun list");
- return;
- }
-
- sdevs_remove_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET,
- sizeof(void *), GFP_ATOMIC);
- if (!sdevs_remove_list) {
- kfree(lun_list);
- DPRINT_ERR(STORVSC_DRV, "unable to allocate lun remove list");
- return;
- }
-
- DPRINT_INFO(STORVSC_DRV, "rescanning host for new scsi devices...");
-
- /* Rescan for new device */
- scsi_scan_target(&host->shost_gendev, host_device_ctx->path,
- host_device_ctx->target, SCAN_WILD_CARD, 1);
-
- DPRINT_INFO(STORVSC_DRV, "rescanning host for removed scsi device...");
-
- /* Use the 1st device to send the report luns cmd */
- shost_for_each_device(sdev, host) {
- lun_count = STORVSC_MAX_LUNS_PER_TARGET;
- storvsc_report_luns(sdev, lun_list, &lun_count);
-
- DPRINT_INFO(STORVSC_DRV,
- "report luns on scsi device (%p) found %u luns ",
- sdev, lun_count);
- DPRINT_INFO(STORVSC_DRV,
- "existing luns on scsi device (%p) host (%d)",
- sdev, host->host_no);
-
- scsi_device_put(sdev);
- break;
- }
-
- for (i = 0; i < lun_count; i++)
- DPRINT_INFO(STORVSC_DRV, "%d) lun %u", i, lun_list[i]);
-
- /* Rescan for devices that may have been removed.
- * We do not have to worry that new devices may have been added since
- * this callback is serialized by the workqueue ie add/remove are done
- * here.
- */
- shost_for_each_device(sdev, host) {
- /* See if this device is still here */
- found = 0;
- for (i = 0; i < lun_count; i++) {
- if (sdev->lun == lun_list[i]) {
- found = 1;
- break;
- }
- }
- if (!found) {
- DPRINT_INFO(STORVSC_DRV, "lun (%u) does not exists",
- sdev->lun);
- sdevs_remove_list[sdevs_count++] = sdev;
- }
- }
-
- /* Now remove the devices */
- for (i = 0; i < sdevs_count; i++) {
- DPRINT_INFO(STORVSC_DRV,
- "removing scsi device (%p) lun (%u)...",
- sdevs_remove_list[i], sdevs_remove_list[i]->lun);
-
- /* make sure it is not removed from underneath us */
- if (!scsi_device_get(sdevs_remove_list[i])) {
- scsi_remove_device(sdevs_remove_list[i]);
- scsi_device_put(sdevs_remove_list[i]);
- }
- }
-
- DPRINT_INFO(STORVSC_DRV, "rescan completed on dev obj (%p) "
- "target (%u) bus (%u)", device_obj,
- host_device_ctx->target, host_device_ctx->path);
-
- kfree(lun_list);
- kfree(sdevs_remove_list);
-
- DPRINT_EXIT(STORVSC_DRV);
-}
-
-static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[],
- unsigned int *lun_count)
-{
- int i, j;
- unsigned int lun = 0;
- unsigned int num_luns;
- int result;
- unsigned char *data;
- struct scsi_sense_hdr sshdr;
- unsigned char cmd[16] = {0};
- /* Add 1 to cover the report_lun header */
- unsigned int report_len = 8 * (STORVSC_MAX_LUNS_PER_TARGET+1);
- unsigned long long *report_luns;
- const unsigned int in_lun_count = *lun_count;
-
- *lun_count = 0;
-
- report_luns = kzalloc(report_len, GFP_ATOMIC);
- if (!report_luns)
- return -ENOMEM;
-
- cmd[0] = REPORT_LUNS;
-
- /* cmd length */
- *(unsigned int *)&cmd[6] = cpu_to_be32(report_len);
-
- result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE,
- (unsigned char *)report_luns, report_len,
- &sshdr, 30 * HZ, 3, NULL);
- if (result != 0) {
- kfree(report_luns);
- return -EBUSY;
- }
-
- /* get the length from the first four bytes */
- report_len = be32_to_cpu(*(unsigned int *)&report_luns[0]);
-
- num_luns = (report_len / sizeof(unsigned long long));
- if (num_luns > in_lun_count) {
- kfree(report_luns);
- return -EINVAL;
- }
-
- *lun_count = num_luns;
-
- DPRINT_DBG(STORVSC_DRV,
- "report luns on scsi device (%p) found %u luns ",
- sdev, num_luns);
-
- /* lun id starts at 1 */
- for (i = 1; i < num_luns + 1; i++) {
- lun = 0;
- data = (unsigned char *)&report_luns[i];
- for (j = 0; j < sizeof(lun); j += 2) {
- lun = lun | (((data[j] << 8) | data[j + 1]) <<
- (j * 8));
- }
-
- luns[i-1] = lun;
- }
-
- kfree(report_luns);
- return 0;
-}
-
-static void storvsc_host_rescan(struct hv_device *device_obj)
-{
- struct device_context *device_ctx = to_device_context(device_obj);
- struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device);
- struct host_device_context *host_device_ctx;
-
- DPRINT_ENTER(STORVSC_DRV);
-
- host_device_ctx = (struct host_device_context *)host->hostdata;
-
- DPRINT_INFO(STORVSC_DRV, "initiating rescan on dev obj (%p) "
- "target (%u) bus (%u)...", device_obj,
- host_device_ctx->target, host_device_ctx->path);
-
- /*
- * We need to queue this since the scanning may block and the caller
- * may be in an intr context
- */
- /* scsi_queue_work(host, &host_device_ctx->host_rescan_work); */
- schedule_work(&host_device_ctx->host_rescan_work);
- DPRINT_EXIT(STORVSC_DRV);
-}
-
static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
sector_t capacity, int *info)
{
@@ -1203,6 +992,7 @@ static void __exit storvsc_exit(void)
}
MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
module_param(storvsc_ringbuffer_size, int, S_IRUGO);
module_init(storvsc_init);
module_exit(storvsc_exit);
diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h
index ae0a896eb39..6404b8424be 100644
--- a/drivers/staging/hv/vmbus.h
+++ b/drivers/staging/hv/vmbus.h
@@ -43,23 +43,23 @@ struct driver_context {
void (*shutdown)(struct device *);
};
-struct device_context {
+struct vm_device {
struct work_struct probe_failed_work_item;
struct hv_guid class_id;
struct hv_guid device_id;
int probe_error;
- struct device device;
struct hv_device device_obj;
+ struct device device;
};
-static inline struct device_context *to_device_context(struct hv_device *d)
+static inline struct vm_device *to_vm_device(struct hv_device *d)
{
- return container_of(d, struct device_context, device_obj);
+ return container_of(d, struct vm_device, device_obj);
}
-static inline struct device_context *device_to_device_context(struct device *d)
+static inline struct vm_device *device_to_vm_device(struct device *d)
{
- return container_of(d, struct device_context, device);
+ return container_of(d, struct vm_device, device);
}
static inline struct driver_context *driver_to_driver_context(struct device_driver *d)
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 894eecfc63c..3397ef08e0a 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -24,6 +24,10 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/sysctl.h>
+#include <linux/pci.h>
+#include <linux/dmi.h>
+#include <linux/slab.h>
+#include "VersionInfo.h"
#include "osd.h"
#include "logging.h"
#include "vmbus.h"
@@ -47,7 +51,7 @@ struct vmbus_driver_context {
struct tasklet_struct event_dpc;
/* The bus root device */
- struct device_context device_ctx;
+ struct vm_device device_ctx;
};
static int vmbus_match(struct device *device, struct device_driver *driver);
@@ -135,7 +139,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
struct device_attribute *dev_attr,
char *buf)
{
- struct device_context *device_ctx = device_to_device_context(dev);
+ struct vm_device *device_ctx = device_to_vm_device(dev);
struct hv_device_info device_info;
memset(&device_info, 0, sizeof(struct hv_device_info));
@@ -245,7 +249,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
{
struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
- struct device_context *dev_ctx = &g_vmbus_drv.device_ctx;
+ struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
int ret;
unsigned int vector;
@@ -307,7 +311,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
/* Call to bus driver to add the root device */
- memset(dev_ctx, 0, sizeof(struct device_context));
+ memset(dev_ctx, 0, sizeof(struct vm_device));
ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
if (ret != 0) {
@@ -368,7 +372,7 @@ static void vmbus_bus_exit(void)
struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
- struct device_context *dev_ctx = &g_vmbus_drv.device_ctx;
+ struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
DPRINT_ENTER(VMBUS_DRV);
@@ -471,13 +475,13 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
struct hv_guid *instance,
void *context)
{
- struct device_context *child_device_ctx;
+ struct vm_device *child_device_ctx;
struct hv_device *child_device_obj;
DPRINT_ENTER(VMBUS_DRV);
/* Allocate the new child device */
- child_device_ctx = kzalloc(sizeof(struct device_context), GFP_KERNEL);
+ child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL);
if (!child_device_ctx) {
DPRINT_ERR(VMBUS_DRV,
"unable to allocate device_context for child device");
@@ -526,10 +530,10 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
struct hv_device *child_device_obj)
{
int ret = 0;
- struct device_context *root_device_ctx =
- to_device_context(root_device_obj);
- struct device_context *child_device_ctx =
- to_device_context(child_device_obj);
+ struct vm_device *root_device_ctx =
+ to_vm_device(root_device_obj);
+ struct vm_device *child_device_ctx =
+ to_vm_device(child_device_obj);
static atomic_t device_num = ATOMIC_INIT(0);
DPRINT_ENTER(VMBUS_DRV);
@@ -572,7 +576,7 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
*/
static void vmbus_child_device_unregister(struct hv_device *device_obj)
{
- struct device_context *device_ctx = to_device_context(device_obj);
+ struct vm_device *device_ctx = to_vm_device(device_obj);
DPRINT_ENTER(VMBUS_DRV);
@@ -610,7 +614,7 @@ static void vmbus_child_device_destroy(struct hv_device *device_obj)
*/
static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
{
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
int ret;
DPRINT_ENTER(VMBUS_DRV);
@@ -687,7 +691,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
{
int match = 0;
struct driver_context *driver_ctx = driver_to_driver_context(driver);
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
DPRINT_ENTER(VMBUS_DRV);
@@ -724,7 +728,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
*/
static void vmbus_probe_failed_cb(struct work_struct *context)
{
- struct device_context *device_ctx = (struct device_context *)context;
+ struct vm_device *device_ctx = (struct vm_device *)context;
DPRINT_ENTER(VMBUS_DRV);
@@ -746,8 +750,8 @@ static int vmbus_probe(struct device *child_device)
int ret = 0;
struct driver_context *driver_ctx =
driver_to_driver_context(child_device->driver);
- struct device_context *device_ctx =
- device_to_device_context(child_device);
+ struct vm_device *device_ctx =
+ device_to_vm_device(child_device);
DPRINT_ENTER(VMBUS_DRV);
@@ -871,7 +875,7 @@ static void vmbus_bus_release(struct device *device)
*/
static void vmbus_device_release(struct device *device)
{
- struct device_context *device_ctx = device_to_device_context(device);
+ struct vm_device *device_ctx = device_to_vm_device(device);
DPRINT_ENTER(VMBUS_DRV);
@@ -946,6 +950,19 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
}
}
+static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = {
+ {
+ .ident = "Hyper-V",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+ DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
+ },
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table);
+
static int __init vmbus_init(void)
{
int ret = 0;
@@ -957,6 +974,9 @@ static int __init vmbus_init(void)
vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
/* Todo: it is used for loglevel, to be ported to new kernel. */
+ if (!dmi_check_system(microsoft_hv_dmi_table))
+ return -ENODEV;
+
ret = vmbus_bus_init(VmbusInitialize);
DPRINT_EXIT(VMBUS_DRV);
@@ -973,7 +993,20 @@ static void __exit vmbus_exit(void)
return;
}
+/*
+ * We use a PCI table to determine if we should autoload this driver This is
+ * needed by distro tools to determine if the hyperv drivers should be
+ * installed and/or configured. We don't do anything else with the table, but
+ * it needs to be present.
+ */
+const static struct pci_device_id microsoft_hv_pci_table[] = {
+ { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
+
MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
module_param(vmbus_irq, int, S_IRUGO);
module_param(vmbus_loglevel, int, S_IRUGO);
diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c
index 33d16b6f7b5..db2dd537ffb 100644
--- a/drivers/staging/iio/accel/kxsd9.c
+++ b/drivers/staging/iio/accel/kxsd9.c
@@ -25,6 +25,7 @@
#include <linux/sysfs.h>
#include <linux/rtc.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "../iio.h"
#include "../sysfs.h"
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index f008837e5a1..82e43588e8a 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/list.h>
@@ -617,7 +618,7 @@ static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info,
static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
{
struct iio_work_cont *wc
- = container_of(work_s, struct iio_work_cont, ws_nocheck);
+ = container_of(work_s, struct iio_work_cont, ws);
struct lis3l02dq_state *st = wc->st;
u8 t;
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index a6b7c72a86f..a4d97ea0df3 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -8,6 +8,7 @@
#include <linux/spi/spi.h>
#include <linux/sysfs.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include "../iio.h"
#include "../sysfs.h"
@@ -492,6 +493,9 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
struct lis3l02dq_state *state = indio_dev->dev_data;
state->trig = iio_allocate_trigger();
+ if (!state->trig)
+ return -ENOMEM;
+
state->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
if (!state->trig->name) {
ret = -ENOMEM;
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index cedcaa2b3d1..1c229869a22 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -14,6 +14,7 @@
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/sysfs.h>
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index d5ea237793a..40cbab2a659 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -13,6 +13,7 @@
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/sysfs.h>
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 9703881cb3f..773f1d1d9c6 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -33,6 +33,7 @@
#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include "../iio.h"
#include "../sysfs.h"
@@ -556,6 +557,7 @@ error_put_reg:
if (!IS_ERR(st->reg))
regulator_put(st->reg);
error_free_st:
+ i2c_set_clientdata(client, NULL);
kfree(st);
error_ret:
@@ -573,6 +575,7 @@ static int max1363_remove(struct i2c_client *client)
regulator_disable(st->reg);
regulator_put(st->reg);
}
+ i2c_set_clientdata(client, NULL);
kfree(st);
return 0;
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index a953eac6fd6..f94fe2d38a9 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -12,6 +12,7 @@
#include <linux/gpio.h>
#include <linux/workqueue.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/sysfs.h>
#include <linux/list.h>
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 768f44894d0..1d77082c853 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -21,6 +21,7 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/cdev.h>
+#include <linux/slab.h>
#include "iio.h"
#include "trigger_consumer.h"
@@ -79,11 +80,14 @@ EXPORT_SYMBOL(__iio_change_event);
/* Does anyone care? */
mutex_lock(&ev_int->event_list_lock);
if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) {
- if (ev_int->current_events == ev_int->max_events)
+ if (ev_int->current_events == ev_int->max_events) {
+ mutex_unlock(&ev_int->event_list_lock);
return 0;
+ }
ev = kmalloc(sizeof(*ev), GFP_KERNEL);
if (ev == NULL) {
ret = -ENOMEM;
+ mutex_unlock(&ev_int->event_list_lock);
goto error_ret;
}
ev->ev.id = ev_code;
@@ -115,7 +119,7 @@ int iio_push_event(struct iio_dev *dev_info,
EXPORT_SYMBOL(iio_push_event);
/* Generic interrupt line interrupt handler */
-irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
+static irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
{
struct iio_interrupt *int_info = _int_info;
struct iio_dev *dev_info = int_info->dev_info;
@@ -249,10 +253,10 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
}
EXPORT_SYMBOL(iio_remove_event_from_list);
-ssize_t iio_event_chrdev_read(struct file *filep,
- char *buf,
- size_t count,
- loff_t *f_ps)
+static ssize_t iio_event_chrdev_read(struct file *filep,
+ char __user *buf,
+ size_t count,
+ loff_t *f_ps)
{
struct iio_event_interface *ev_int = filep->private_data;
struct iio_detected_event_list *el;
@@ -289,16 +293,16 @@ ssize_t iio_event_chrdev_read(struct file *filep,
mutex_unlock(&ev_int->event_list_lock);
/*
* Possible concurency issue if an update of this event is on its way
- * through. May lead to new even being removed whilst the reported event
- * was the unescalated event. In typical use case this is not a problem
- * as userspace will say read half the buffer due to a 50% full event
- * which would make the correct 100% full incorrect anyway.
+ * through. May lead to new event being removed whilst the reported
+ * event was the unescalated event. In typical use case this is not a
+ * problem as userspace will say read half the buffer due to a 50%
+ * full event which would make the correct 100% full incorrect anyway.
*/
- spin_lock(&el->shared_pointer->lock);
- if (el->shared_pointer)
+ if (el->shared_pointer) {
+ spin_lock(&el->shared_pointer->lock);
(el->shared_pointer->ev_p) = NULL;
- spin_unlock(&el->shared_pointer->lock);
-
+ spin_unlock(&el->shared_pointer->lock);
+ }
kfree(el);
return len;
@@ -310,7 +314,7 @@ error_ret:
return ret;
}
-int iio_event_chrdev_release(struct inode *inode, struct file *filep)
+static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
{
struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
struct iio_event_interface *ev_int = hand->private;
@@ -332,7 +336,7 @@ int iio_event_chrdev_release(struct inode *inode, struct file *filep)
return 0;
}
-int iio_event_chrdev_open(struct inode *inode, struct file *filep)
+static int iio_event_chrdev_open(struct inode *inode, struct file *filep)
{
struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
struct iio_event_interface *ev_int = hand->private;
@@ -533,6 +537,7 @@ static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
}
+/* Return a negative errno on failure */
int iio_get_new_idr_val(struct idr *this_idr)
{
int ret;
@@ -656,7 +661,7 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
for (i = 0; i < dev_info->num_interrupt_lines; i++) {
dev_info->event_interfaces[i].owner = dev_info->driver_module;
ret = iio_get_new_idr_val(&iio_event_idr);
- if (ret)
+ if (ret < 0)
goto error_free_setup_ev_ints;
else
dev_info->event_interfaces[i].id = ret;
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index ebe5cccb403..e53e214bfeb 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/idr.h>
+#include <linux/slab.h>
#include "iio.h"
#include "ring_generic.h"
diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index 693ebc48597..35ec80ba444 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -14,6 +14,7 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include "iio.h"
#include "trigger.h"
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 78b9432c810..8770a00e365 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -34,6 +34,7 @@
#include <linux/pm.h>
#include <linux/hwmon.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include "../iio.h"
#include "tsl2563.h"
@@ -681,6 +682,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
fail2:
iio_device_unregister(chip->indio_dev);
fail1:
+ i2c_set_clientdata(client, NULL);
kfree(chip);
return err;
}
@@ -691,6 +693,7 @@ static int tsl2563_remove(struct i2c_client *client)
iio_device_unregister(chip->indio_dev);
+ i2c_set_clientdata(client, NULL);
kfree(chip);
return 0;
}
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 93b91b28a02..09044adf732 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -146,8 +146,7 @@ static inline void __iio_init_ring_buffer(struct iio_ring_buffer *ring,
ring->length = length;
ring->loopcount = 0;
ring->shared_ev_pointer.ev_p = 0;
- ring->shared_ev_pointer.lock =
- __SPIN_LOCK_UNLOCKED(ring->shared_ev_pointer->loc);
+ spin_lock_init(&ring->shared_ev_pointer.lock);
}
/**
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 359ff9208f3..cf22c091668 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -7,8 +7,8 @@
* the Free Software Foundation.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
-#include <linux/device.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/workqueue.h>
@@ -21,7 +21,7 @@ static inline int __iio_init_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
return -EINVAL;
__iio_init_ring_buffer(&ring->buf, bytes_per_datum, length);
- ring->use_lock = __SPIN_LOCK_UNLOCKED((ring)->use_lock);
+ spin_lock_init(&ring->use_lock);
ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL);
ring->read_p = 0;
ring->write_p = 0;
@@ -293,7 +293,7 @@ again:
return -EAGAIN;
memcpy(data, last_written_p_copy, ring->buf.bpd);
- if (unlikely(ring->last_written_p >= last_written_p_copy))
+ if (unlikely(ring->last_written_p != last_written_p_copy))
goto again;
iio_unmark_sw_rb_in_use(&ring->buf);
diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c
index 539e4169a02..0c3bad3187f 100644
--- a/drivers/staging/iio/trigger/iio-trig-gpio.c
+++ b/drivers/staging/iio/trigger/iio-trig-gpio.c
@@ -21,6 +21,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include "../iio.h"
#include "../trigger.h"
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index e310dc00985..4295bbc7b50 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/rtc.h>
#include "../iio.h"
#include "../trigger.h"
diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h
index a02d70b0d24..9d52d963777 100644
--- a/drivers/staging/iio/trigger_consumer.h
+++ b/drivers/staging/iio/trigger_consumer.h
@@ -27,7 +27,7 @@ int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info);
* iio_device_register_trigger_consumer() - set up an iio_dev to use triggers
* @dev_info: iio_dev associated with the device that will consume the trigger
**/
-int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
+static int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
{
return 0;
};
@@ -36,7 +36,7 @@ int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
* iio_device_unregister_trigger_consumer() - reverse the registration process
* @dev_info: iio_dev associated with the device that consumed the trigger
**/
-int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
+static int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
{
return 0;
};
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
index fd4890de8db..ca092247f36 100644
--- a/drivers/staging/line6/capture.c
+++ b/drivers/staging/line6/capture.c
@@ -11,6 +11,8 @@
#include "driver.h"
+#include <linux/slab.h>
+
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index e4078a92d39..258555417bc 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "audio.h"
@@ -33,7 +34,7 @@
/* table of devices that work with this driver */
-static struct usb_device_id line6_id_table[] = {
+static const struct usb_device_id line6_id_table[] = {
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c
index decbaa971b6..bb8c9da5803 100644
--- a/drivers/staging/line6/dumprequest.c
+++ b/drivers/staging/line6/dumprequest.c
@@ -10,6 +10,9 @@
*/
#include "driver.h"
+
+#include <linux/slab.h>
+
#include "dumprequest.h"
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
index 6ef4455d87d..32b6ca75cad 100644
--- a/drivers/staging/line6/midi.c
+++ b/drivers/staging/line6/midi.c
@@ -12,6 +12,7 @@
#include "driver.h"
#include <linux/usb.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index dd98121eb80..fbe4b083eac 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -11,6 +11,8 @@
#include "driver.h"
+#include <linux/slab.h>
+
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
index 3431f5cd285..fbcd6e150aa 100644
--- a/drivers/staging/line6/playback.c
+++ b/drivers/staging/line6/playback.c
@@ -11,6 +11,8 @@
#include "driver.h"
+#include <linux/slab.h>
+
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
index 685c529950e..4983f2b51cf 100644
--- a/drivers/staging/line6/pod.c
+++ b/drivers/staging/line6/pod.c
@@ -11,6 +11,8 @@
#include "driver.h"
+#include <linux/slab.h>
+
#include "audio.h"
#include "capture.h"
#include "control.h"
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
index 48d834b0fa1..28eb89983f3 100644
--- a/drivers/staging/line6/variax.c
+++ b/drivers/staging/line6/variax.c
@@ -11,6 +11,8 @@
#include "driver.h"
+#include <linux/slab.h>
+
#include "audio.h"
#include "control.h"
#include "variax.h"
@@ -254,7 +256,7 @@ static ssize_t variax_set_active(struct device *dev,
if (ret)
return ret;
- variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1: 0;
+ variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1 : 0;
line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
sizeof(variax_activate));
return count;
diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig
deleted file mode 100644
index 505dcb27579..00000000000
--- a/drivers/staging/mimio/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config INPUT_MIMIO
- tristate "Mimio Xi interactive whiteboard support"
- depends on USB && INPUT
- default N
- help
- Say Y here if you want to use a Mimio Xi interactive
- whiteboard device.
-
- To compile this driver as a module, choose M here: the
- module will be called mimio.
diff --git a/drivers/staging/mimio/Makefile b/drivers/staging/mimio/Makefile
deleted file mode 100644
index 77807ee0450..00000000000
--- a/drivers/staging/mimio/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_INPUT_MIMIO) += mimio.o
diff --git a/drivers/staging/mimio/mimio.c b/drivers/staging/mimio/mimio.c
deleted file mode 100644
index 1ba8103f500..00000000000
--- a/drivers/staging/mimio/mimio.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * Hardware event => input event mapping:
- *
- *
- *
- input.h:#define BTN_TOOL_PEN 0x140 black
- input.h:#define BTN_TOOL_RUBBER 0x141 blue
- input.h:#define BTN_TOOL_BRUSH 0x142 green
- input.h:#define BTN_TOOL_PENCIL 0x143 red
- input.h:#define BTN_TOOL_AIRBRUSH 0x144 eraser
- input.h:#define BTN_TOOL_FINGER 0x145 small eraser
- input.h:#define BTN_TOOL_MOUSE 0x146 mimio interactive
- input.h:#define BTN_TOOL_LENS 0x147 mimio interactive but1
- input.h:#define LOCALBTN_TOOL_EXTRA1 0x14a mimio interactive but2 == BTN_TOUCH
- input.h:#define LOCALBTN_TOOL_EXTRA2 0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS
- input.h:#define LOCALBTN_TOOL_EXTRA3 0x14c unused == BTN_STYLUS2
- input.h:#define BTN_TOOL_DOUBLETAP 0x14d unused
- input.h:#define BTN_TOOL_TRIPLETAP 0x14e unused
- *
- * MIMIO_EV_PENDOWN(MIMIO_PEN_K) => EV_KEY BIT(BTN_TOOL_PEN)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_B) => EV_KEY BIT(BTN_TOOL_RUBBER)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_G) => EV_KEY BIT(BTN_TOOL_BRUSH)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_R) => EV_KEY BIT(BTN_TOOL_PENCIL)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_E) => EV_KEY BIT(BTN_TOOL_AIRBRUSH)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_ES) => EV_KEY BIT(BTN_TOOL_FINGER)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_I) => EV_KEY BIT(BTN_TOOL_MOUSE)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_IL) => EV_KEY BIT(BTN_TOOL_LENS)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_IR) => EV_KEY BIT(BTN_TOOL_DOUBLETAP)
- * MIMIO_EV_PENDOWN(MIMIO_PEN_EX) => EV_KEY BIT(BTN_TOOL_TRIPLETAP)
- * MIMIO_EV_PENDATA => EV_ABS BIT(ABS_X), BIT(ABS_Y)
- * MIMIO_EV_MEMRESET => EV_KEY BIT(BTN_0)
- * MIMIO_EV_ACC(ACC_NEWPAGE) => EV_KEY BIT(BTN_1)
- * MIMIO_EV_ACC(ACC_TAGPAGE) => EV_KEY BIT(BTN_2)
- * MIMIO_EV_ACC(ACC_PRINTPAGE) => EV_KEY BIT(BTN_3)
- * MIMIO_EV_ACC(ACC_MAXIMIZE) => EV_KEY BIT(BTN_4)
- * MIMIO_EV_ACC(ACC_FINDCTLPNL) => EV_KEY BIT(BTN_5)
- *
- *
- * open issues:
- * - cold-load of data captured when mimio in standalone mode not yet
- * supported; need to snoop Win32 box to see datastream for this.
- * - mimio mouse not yet supported; need to snoop Win32 box to see the
- * datastream for this.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-
-#define DRIVER_VERSION "v0.031"
-#define DRIVER_AUTHOR "mwilder@cs.nmsu.edu"
-#define DRIVER_DESC "USB mimio-xi driver"
-
-enum {UPVALUE, DOWNVALUE, MOVEVALUE};
-
-#define MIMIO_XRANGE_MAX 9600
-#define MIMIO_YRANGE_MAX 4800
-
-#define LOCALBTN_TOOL_EXTRA1 BTN_TOUCH
-#define LOCALBTN_TOOL_EXTRA2 BTN_STYLUS
-#define LOCALBTN_TOOL_EXTRA3 BTN_STYLUS2
-
-#define MIMIO_VENDOR_ID 0x08d3
-#define MIMIO_PRODUCT_ID 0x0001
-#define MIMIO_MAXPAYLOAD (8)
-#define MIMIO_MAXNAMELEN (64)
-#define MIMIO_TXWAIT (1)
-#define MIMIO_TXDONE (2)
-
-#define MIMIO_EV_PENDOWN (0x22)
-#define MIMIO_EV_PENDATA (0x24)
-#define MIMIO_EV_PENUP (0x51)
-#define MIMIO_EV_MEMRESET (0x45)
-#define MIMIO_EV_ACC (0xb2)
-
-#define MIMIO_PEN_K (1) /* black pen */
-#define MIMIO_PEN_B (2) /* blue pen */
-#define MIMIO_PEN_G (3) /* green pen */
-#define MIMIO_PEN_R (4) /* red pen */
-/* 5, 6, 7, 8 are extra pens */
-#define MIMIO_PEN_E (9) /* big eraser */
-#define MIMIO_PEN_ES (10) /* lil eraser */
-#define MIMIO_PENJUMP_START (10)
-#define MIMIO_PENJUMP (6)
-#define MIMIO_PEN_I (17) /* mimio interactive */
-#define MIMIO_PEN_IL (18) /* mimio interactive button 1 */
-#define MIMIO_PEN_IR (19) /* mimio interactive button 2 */
-
-#define MIMIO_PEN_MAX (MIMIO_PEN_IR)
-
-#define ACC_DONE (0)
-#define ACC_NEWPAGE (1)
-#define ACC_TAGPAGE (2)
-#define ACC_PRINTPAGE (4)
-#define ACC_MAXIMIZE (8)
-#define ACC_FINDCTLPNL (16)
-
-#define isvalidtxsize(n) ((n) > 0 && (n) <= MIMIO_MAXPAYLOAD)
-
-
-struct pktbuf {
- unsigned char instr;
- unsigned char buf[16];
- unsigned char *p;
- unsigned char *q;
-};
-
-struct usbintendpt {
- dma_addr_t dma;
- struct urb *urb;
- unsigned char *buf;
- struct usb_endpoint_descriptor *desc;
-};
-
-struct mimio {
- struct input_dev *idev;
- struct usb_device *udev;
- struct usb_interface *uifc;
- int open;
- int present;
- int greeted;
- int txflags;
- char phys[MIMIO_MAXNAMELEN];
- struct usbintendpt in;
- struct usbintendpt out;
- struct pktbuf pktbuf;
- unsigned char minor;
- wait_queue_head_t waitq;
- spinlock_t txlock;
- void (*rxhandler)(struct mimio *, unsigned char *, unsigned int);
- int last_pen_down;
-};
-
-static void mimio_close(struct input_dev *);
-static void mimio_dealloc(struct mimio *);
-static void mimio_disconnect(struct usb_interface *);
-static int mimio_greet(struct mimio *);
-static void mimio_irq_in(struct urb *);
-static void mimio_irq_out(struct urb *);
-static int mimio_open(struct input_dev *);
-static int mimio_probe(struct usb_interface *, const struct usb_device_id *);
-static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int);
-static int mimio_tx(struct mimio *, const char *, int);
-
-static char mimio_name[] = "VirtualInk mimio-Xi";
-static struct usb_device_id mimio_table [] = {
- { USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) },
- { USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, mimio_table);
-
-static struct usb_driver mimio_driver = {
- .name = "mimio",
- .probe = mimio_probe,
- .disconnect = mimio_disconnect,
- .id_table = mimio_table,
-};
-
-static DECLARE_MUTEX(disconnect_sem);
-
-static void mimio_close(struct input_dev *idev)
-{
- struct mimio *mimio;
-
- mimio = input_get_drvdata(idev);
- if (!mimio) {
- dev_err(&idev->dev, "null mimio attached to input device\n");
- return;
- }
-
- if (mimio->open <= 0)
- dev_err(&idev->dev, "mimio not open.\n");
- else
- mimio->open--;
-
- if (mimio->present == 0 && mimio->open == 0)
- mimio_dealloc(mimio);
-}
-
-static void mimio_dealloc(struct mimio *mimio)
-{
- if (mimio == NULL)
- return;
-
- usb_kill_urb(mimio->in.urb);
-
- usb_kill_urb(mimio->out.urb);
-
- if (mimio->idev) {
- input_unregister_device(mimio->idev);
- if (mimio->idev->grab)
- input_close_device(mimio->idev->grab);
- else
- dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL"
- " -- didn't call input_close_device\n");
- }
-
- usb_free_urb(mimio->in.urb);
-
- usb_free_urb(mimio->out.urb);
-
- if (mimio->in.buf) {
- usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf,
- mimio->in.dma);
- }
-
- if (mimio->out.buf)
- usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf,
- mimio->out.dma);
-
- if (mimio->idev)
- input_free_device(mimio->idev);
-
- kfree(mimio);
-}
-
-static void mimio_disconnect(struct usb_interface *ifc)
-{
- struct mimio *mimio;
-
- down(&disconnect_sem);
-
- mimio = usb_get_intfdata(ifc);
- usb_set_intfdata(ifc, NULL);
- dev_dbg(&mimio->idev->dev, "disconnect\n");
-
- if (mimio) {
- mimio->present = 0;
-
- if (mimio->open <= 0)
- mimio_dealloc(mimio);
- }
-
- up(&disconnect_sem);
-}
-
-static int mimio_greet(struct mimio *mimio)
-{
- const struct grtpkt {
- int nbytes;
- unsigned delay;
- char data[8];
- } grtpkts[] = {
- { 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } },
- { 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } },
- { 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } },
- { 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } },
- { 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } },
- { 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } },
- { 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } },
- { 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } },
- { 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } },
- { 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } },
- { 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } },
- { 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
- };
- int rslt;
- const struct grtpkt *pkt;
-
- for (pkt = grtpkts; pkt->nbytes; pkt++) {
- rslt = mimio_tx(mimio, pkt->data, pkt->nbytes);
- if (rslt)
- return rslt;
- if (pkt->delay)
- msleep(pkt->delay);
- }
-
- return 0;
-}
-
-static void mimio_irq_in(struct urb *urb)
-{
- int rslt;
- char *data;
- const char *reason = "going down";
- struct mimio *mimio;
-
- mimio = urb->context;
-
- if (mimio == NULL)
- /* paranoia */
- return;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ETIMEDOUT:
- reason = "timeout -- unplugged?";
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- dev_dbg(&mimio->idev->dev, "%s.\n", reason);
- return;
- default:
- dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n",
- urb->status);
- goto exit;
- }
- data = mimio->in.buf;
-
- if (mimio->rxhandler)
- mimio->rxhandler(mimio, data, urb->actual_length);
-exit:
- /*
- * Keep listening to device on same urb.
- */
- rslt = usb_submit_urb(urb, GFP_ATOMIC);
- if (rslt)
- dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
- rslt);
-}
-
-static void mimio_irq_out(struct urb *urb)
-{
- unsigned long flags;
- struct mimio *mimio;
-
- mimio = urb->context;
-
- if (urb->status)
- dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status);
-
- spin_lock_irqsave(&mimio->txlock, flags);
- mimio->txflags |= MIMIO_TXDONE;
- spin_unlock_irqrestore(&mimio->txlock, flags);
- wmb();
- wake_up(&mimio->waitq);
-}
-
-static int mimio_open(struct input_dev *idev)
-{
- int rslt;
- struct mimio *mimio;
-
- rslt = 0;
- down(&disconnect_sem);
- mimio = input_get_drvdata(idev);
- dev_dbg(&idev->dev, "mimio_open\n");
-
- if (mimio == NULL) {
- dev_err(&idev->dev, "null mimio.\n");
- rslt = -ENODEV;
- goto exit;
- }
-
- if (mimio->open++)
- goto exit;
-
- if (mimio->present && !mimio->greeted) {
- struct urb *urb = mimio->in.urb;
- mimio->in.urb->dev = mimio->udev;
- rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
- if (rslt) {
- dev_err(&idev->dev, "usb_submit_urb failure "
- "(res = %d: %s). Not greeting.\n",
- rslt,
- (!urb ? "urb is NULL" :
- (urb->hcpriv ? "urb->hcpriv is non-NULL" :
- (!urb->complete ? "urb is not complete" :
- (urb->number_of_packets <= 0 ? "urb has no packets" :
- (urb->interval <= 0 ? "urb interval too small" :
- "urb interval too large or some other error"))))));
- rslt = -EIO;
- goto exit;
- }
- rslt = mimio_greet(mimio);
- if (rslt == 0) {
- dev_dbg(&idev->dev, "Mimio greeted OK.\n");
- mimio->greeted = 1;
- } else {
- dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n",
- rslt);
- }
- }
-
-exit:
- up(&disconnect_sem);
- return rslt;
-}
-
-static int mimio_probe(struct usb_interface *ifc,
- const struct usb_device_id *id)
-{
- char path[64];
- int pipe, maxp;
- struct mimio *mimio;
- struct usb_device *udev;
- struct usb_host_interface *hostifc;
- struct input_dev *input_dev;
- int res = 0;
- int i;
-
- udev = interface_to_usbdev(ifc);
-
- mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL);
- if (!mimio)
- return -ENOMEM;
-
- input_dev = input_allocate_device();
- if (!input_dev) {
- mimio_dealloc(mimio);
- return -ENOMEM;
- }
-
- mimio->uifc = ifc;
- mimio->udev = udev;
- mimio->pktbuf.p = mimio->pktbuf.buf;
- mimio->pktbuf.q = mimio->pktbuf.buf;
- /* init_input_dev(mimio->idev); */
- mimio->idev = input_dev;
- init_waitqueue_head(&mimio->waitq);
- spin_lock_init(&mimio->txlock);
- hostifc = ifc->cur_altsetting;
-
- if (hostifc->desc.bNumEndpoints != 2) {
- dev_err(&udev->dev, "Unexpected endpoint count: %d.\n",
- hostifc->desc.bNumEndpoints);
- mimio_dealloc(mimio);
- return -ENODEV;
- }
-
- mimio->in.desc = &(hostifc->endpoint[0].desc);
- mimio->out.desc = &(hostifc->endpoint[1].desc);
-
- mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
- &mimio->in.dma);
- mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
- &mimio->out.dma);
-
- if (mimio->in.buf == NULL || mimio->out.buf == NULL) {
- dev_err(&udev->dev, "usb_buffer_alloc failure.\n");
- mimio_dealloc(mimio);
- return -ENOMEM;
- }
-
- mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL);
- mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL);
-
- if (mimio->in.urb == NULL || mimio->out.urb == NULL) {
- dev_err(&udev->dev, "usb_alloc_urb failure.\n");
- mimio_dealloc(mimio);
- return -ENOMEM;
- }
-
- /*
- * Build the input urb.
- */
- pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress);
- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- if (maxp > MIMIO_MAXPAYLOAD)
- maxp = MIMIO_MAXPAYLOAD;
- usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp,
- mimio_irq_in, mimio, mimio->in.desc->bInterval);
- mimio->in.urb->transfer_dma = mimio->in.dma;
- mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /*
- * Build the output urb.
- */
- pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress);
- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- if (maxp > MIMIO_MAXPAYLOAD)
- maxp = MIMIO_MAXPAYLOAD;
- usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp,
- mimio_irq_out, mimio, mimio->out.desc->bInterval);
- mimio->out.urb->transfer_dma = mimio->out.dma;
- mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /*
- * Build input device info
- */
- usb_make_path(udev, path, 64);
- snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path);
- input_set_drvdata(input_dev, mimio);
- /* input_dev->dev = &ifc->dev; */
- input_dev->open = mimio_open;
- input_dev->close = mimio_close;
- input_dev->name = mimio_name;
- input_dev->phys = mimio->phys;
- input_dev->dev.parent = &ifc->dev;
-
- input_dev->id.bustype = BUS_USB;
- input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor);
- input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct);
- input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice);
-
- input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
- for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i)
- set_bit(i, input_dev->keybit);
-
- input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) |
- BIT_MASK(BTN_1) |
- BIT_MASK(BTN_2) |
- BIT_MASK(BTN_3) |
- BIT_MASK(BTN_4) |
- BIT_MASK(BTN_5);
- /* input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */
- input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
- input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0);
- input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
-
-#if 0
- input_dev->absmin[ABS_X] = 0;
- input_dev->absmin[ABS_Y] = 0;
- input_dev->absmax[ABS_X] = 9600;
- input_dev->absmax[ABS_Y] = 4800;
- input_dev->absfuzz[ABS_X] = 0;
- input_dev->absfuzz[ABS_Y] = 0;
- input_dev->absflat[ABS_X] = 0;
- input_dev->absflat[ABS_Y] = 0;
-#endif
-
-#if 0
- /* this will just reduce the precision */
- input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */
- input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */
-#endif
-
- /*
- * Register the input device.
- */
- res = input_register_device(mimio->idev);
- if (res) {
- dev_err(&udev->dev, "input_register_device failure (%d)\n",
- res);
- mimio_dealloc(mimio);
- return -EIO;
- }
- dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n",
- input_dev->name, input_dev->phys, res);
-
- usb_set_intfdata(ifc, mimio);
- mimio->present = 1;
-
- /*
- * Submit the input urb to the usb subsystem.
- */
- mimio->in.urb->dev = mimio->udev;
- res = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
- if (res) {
- dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n",
- res);
- mimio_dealloc(mimio);
- return -EIO;
- }
-
- /*
- * Attempt to greet the mimio after giving
- * it some post-init settling time.
- *
- * note: sometimes this sleep interval isn't
- * long enough to permit the device to re-init
- * after a hot-swap; maybe need to bump it up.
- *
- * As it is, this probably breaks module unloading support!
- */
- msleep(1024);
-
- res = mimio_greet(mimio);
- if (res == 0) {
- dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n");
- mimio->greeted = 1;
- mimio->rxhandler = mimio_rx_handler;
- } else {
- dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res);
- }
-
- return 0;
-}
-
-static int handle_mimio_rx_penupdown(struct mimio *mimio,
- int down,
- const char *const instr[],
- const int instr_ofst[])
-{
- int penid, x;
- if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3))
- return 1; /* partial pkt */
-
- if (down) {
- x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
- *(mimio->pktbuf.p + 2);
- if (x != *(mimio->pktbuf.p + 3)) {
- dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n",
- down ? "DOWN":"UP");
- /* skip this event data */
- mimio->pktbuf.p += 4;
- /* decode any remaining events */
- return 0;
- }
- penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2);
- if (penid > MIMIO_PEN_MAX) {
- dev_dbg(&mimio->idev->dev,
- "Unmapped penID (not in [0, %d]): %d\n",
- MIMIO_PEN_MAX, (int)mimio->pktbuf.instr);
- penid = mimio->pktbuf.instr = 0;
- }
- mimio->last_pen_down = penid;
- } else {
- penid = mimio->last_pen_down;
- }
- dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid],
- instr_ofst[penid], penid, down ? "down" : "up");
-
- if (instr_ofst[penid] >= 0) {
- int code = BTN_TOOL_PEN + instr_ofst[penid];
- int value = down ? DOWNVALUE : UPVALUE;
- if (code > KEY_MAX)
- dev_dbg(&mimio->idev->dev, "input_event will ignore "
- "-- code (%d) > KEY_MAX\n", code);
- if (!test_bit(code, mimio->idev->keybit))
- dev_dbg(&mimio->idev->dev, "input_event will ignore "
- "-- bit for code (%d) not enabled\n", code);
- if (!!test_bit(code, mimio->idev->key) == value)
- dev_dbg(&mimio->idev->dev, "input_event will ignore "
- "-- bit for code (%d) already set to %d\n",
- code, value);
- if (value != DOWNVALUE) {
- /* input_regs(mimio->idev, regs); */
- input_report_key(mimio->idev, code, value);
- input_sync(mimio->idev);
- } else {
- /* wait until we get some coordinates */
- }
- } else {
- dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 "
- "- not sending\n", penid, instr_ofst[penid]);
- }
- mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */
- return 0;
-}
-
-/*
- * Stay tuned for partial-packet excitement.
- *
- * This routine buffers data packets received from the mimio device
- * in the mimio's data space. This buffering is necessary because
- * the mimio's in endpoint can serve us partial packets of data, and
- * we want the driver to support the servicing of multiple mimios.
- * Empirical evidence gathered so far suggests that the method of
- * buffering packet data in the mimio's data space works. Previous
- * versions of this driver did not buffer packet data in each mimio's
- * data-space, and were therefore not able to service multiple mimios.
- * Note that since the caller of this routine is running in interrupt
- * context, care needs to be taken to ensure that this routine does not
- * become bloated, and it may be that another spinlock is needed in each
- * mimio to guard the buffered packet data properly.
- */
-static void mimio_rx_handler(struct mimio *mimio,
- unsigned char *data,
- unsigned int nbytes)
-{
- struct device *dev = &mimio->idev->dev;
- unsigned int x;
- unsigned int y;
- static const char * const instr[] = {
- "?0",
- "black pen", "blue pen", "green pen", "red pen",
- "brown pen", "orange pen", "purple pen", "yellow pen",
- "big eraser", "lil eraser",
- "?11", "?12", "?13", "?14", "?15", "?16",
- "mimio interactive", "interactive button1",
- "interactive button2"
- };
-
- /* Mimio Interactive gives:
- * down: [0x22 0x01 0x11 0x32 0x24]
- * b1 : [0x22 0x01 0x12 0x31 0x24]
- * b2 : [0x22 0x01 0x13 0x30 0x24]
- */
- static const int instr_ofst[] = {
- -1,
- 0, 1, 2, 3,
- 9, 9, 9, 9,
- 4, 5,
- -1, -1, -1, -1, -1, -1,
- 6, 7, 8,
- };
-
- memcpy(mimio->pktbuf.q, data, nbytes);
- mimio->pktbuf.q += nbytes;
-
- while (mimio->pktbuf.p < mimio->pktbuf.q) {
- int t = *mimio->pktbuf.p;
- switch (t) {
- case MIMIO_EV_PENUP:
- case MIMIO_EV_PENDOWN:
- if (handle_mimio_rx_penupdown(mimio,
- t == MIMIO_EV_PENDOWN,
- instr, instr_ofst))
- return; /* partial packet */
- break;
-
- case MIMIO_EV_PENDATA:
- if (mimio->pktbuf.q - mimio->pktbuf.p < 6)
- /* partial pkt */
- return;
- x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
- *(mimio->pktbuf.p + 2) ^
- *(mimio->pktbuf.p + 3) ^
- *(mimio->pktbuf.p + 4);
- if (x != *(mimio->pktbuf.p + 5)) {
- dev_dbg(dev, "EV_PENDATA: bad xsum.\n");
- mimio->pktbuf.p += 6; /* skip this event data */
- break; /* decode any remaining events */
- }
- x = *(mimio->pktbuf.p + 1);
- x <<= 8;
- x |= *(mimio->pktbuf.p + 2);
- y = *(mimio->pktbuf.p + 3);
- y <<= 8;
- y |= *(mimio->pktbuf.p + 4);
- dev_dbg(dev, "coord: (%d, %d)\n", x, y);
- if (instr_ofst[mimio->pktbuf.instr] >= 0) {
- int code = BTN_TOOL_PEN +
- instr_ofst[mimio->last_pen_down];
-#if 0
- /* Utter hack to ensure we get forwarded _AND_
- * so we can identify when a complete signal is
- * received */
- mimio->idev->abs[ABS_Y] = -1;
- mimio->idev->abs[ABS_X] = -1;
-#endif
- /* input_regs(mimio->idev, regs); */
- input_report_abs(mimio->idev, ABS_X, x);
- input_report_abs(mimio->idev, ABS_Y, y);
- /* fake a penup */
- change_bit(code, mimio->idev->key);
- input_report_key(mimio->idev,
- code,
- DOWNVALUE);
- /* always sync here */
- mimio->idev->sync = 0;
- input_sync(mimio->idev);
- }
- mimio->pktbuf.p += 6;
- break;
- case MIMIO_EV_MEMRESET:
- if (mimio->pktbuf.q - mimio->pktbuf.p < 7)
- /* partial pkt */
- return;
- dev_dbg(dev, "mem-reset.\n");
- /* input_regs(mimio->idev, regs); */
- input_event(mimio->idev, EV_KEY, BTN_0, 1);
- input_event(mimio->idev, EV_KEY, BTN_0, 0);
- input_sync(mimio->idev);
- mimio->pktbuf.p += 7;
- break;
- case MIMIO_EV_ACC:
- if (mimio->pktbuf.q - mimio->pktbuf.p < 4)
- /* partial pkt */
- return;
- x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
- *(mimio->pktbuf.p + 2);
- if (x != *(mimio->pktbuf.p + 3)) {
- dev_dbg(dev, "EV_ACC: bad xsum.\n");
- mimio->pktbuf.p += 4; /* skip this event data */
- break; /* decode any remaining events */
- }
- switch (*(mimio->pktbuf.p + 2)) {
- case ACC_NEWPAGE:
- dev_dbg(&mimio->idev->dev, "new-page.\n");
- /* input_regs(mimio->idev, regs); */
- input_event(mimio->idev, EV_KEY, BTN_1, 1);
- input_event(mimio->idev, EV_KEY, BTN_1, 0);
- input_sync(mimio->idev);
- break;
- case ACC_TAGPAGE:
- dev_dbg(&mimio->idev->dev, "tag-page.\n");
- /* input_regs(mimio->idev, regs); */
- input_event(mimio->idev, EV_KEY, BTN_2, 1);
- input_event(mimio->idev, EV_KEY, BTN_2, 0);
- input_sync(mimio->idev);
- break;
- case ACC_PRINTPAGE:
- dev_dbg(&mimio->idev->dev, "print-page.\n");
- /* input_regs(mimio->idev, regs);*/
- input_event(mimio->idev, EV_KEY, BTN_3, 1);
- input_event(mimio->idev, EV_KEY, BTN_3, 0);
- input_sync(mimio->idev);
- break;
- case ACC_MAXIMIZE:
- dev_dbg(&mimio->idev->dev,
- "maximize-window.\n");
- /* input_regs(mimio->idev, regs); */
- input_event(mimio->idev, EV_KEY, BTN_4, 1);
- input_event(mimio->idev, EV_KEY, BTN_4, 0);
- input_sync(mimio->idev);
- break;
- case ACC_FINDCTLPNL:
- dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n");
- /* input_regs(mimio->idev, regs); */
- input_event(mimio->idev, EV_KEY, BTN_5, 1);
- input_event(mimio->idev, EV_KEY, BTN_5, 0);
- input_sync(mimio->idev);
- break;
- case ACC_DONE:
- dev_dbg(&mimio->idev->dev, "acc-done.\n");
- /* no event is dispatched to the input
- * subsystem for this device event.
- */
- break;
- default:
- dev_dbg(dev, "unknown acc event.\n");
- break;
- }
- mimio->pktbuf.p += 4;
- break;
- default:
- mimio->pktbuf.p++;
- break;
- }
- }
-
- /*
- * No partial event was received, so reset mimio's pktbuf ptrs.
- */
- mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf;
-}
-
-static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes)
-{
- int rslt;
- int timeout;
- unsigned long flags;
- DECLARE_WAITQUEUE(wait, current);
-
- if (!(isvalidtxsize(nbytes))) {
- dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n",
- nbytes);
- return -EINVAL;
- }
-
- /*
- * Init the out urb and copy the data to send.
- */
- mimio->out.urb->dev = mimio->udev;
- mimio->out.urb->transfer_buffer_length = nbytes;
- memcpy(mimio->out.urb->transfer_buffer, buf, nbytes);
-
- /*
- * Send the data.
- */
- spin_lock_irqsave(&mimio->txlock, flags);
- mimio->txflags = MIMIO_TXWAIT;
- rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC);
- spin_unlock_irqrestore(&mimio->txlock, flags);
- dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt);
-
- if (rslt) {
- dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
- rslt);
- return rslt;
- }
-
- /*
- * Wait for completion to be signalled (the mimio_irq_out
- * completion routine will or MIMIO_TXDONE in with txflags).
- */
- timeout = HZ;
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&mimio->waitq, &wait);
-
- while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) {
- timeout = schedule_timeout(timeout);
- rmb();
- }
-
- if ((mimio->txflags & MIMIO_TXDONE) == 0)
- dev_dbg(&mimio->idev->dev, "tx timed out.\n");
-
- /*
- * Now that completion has been signalled,
- * unlink the urb so that it can be recycled.
- */
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&mimio->waitq, &wait);
- usb_unlink_urb(mimio->out.urb);
-
- return rslt;
-}
-
-static int __init mimio_init(void)
-{
- int rslt;
-
- rslt = usb_register(&mimio_driver);
- if (rslt != 0) {
- err("%s: usb_register failure: %d", __func__, rslt);
- return rslt;
- }
-
- printk(KERN_INFO KBUILD_MODNAME ":"
- DRIVER_DESC " " DRIVER_VERSION "\n");
- return rslt;
-}
-
-static void __exit mimio_exit(void)
-{
- usb_deregister(&mimio_driver);
-}
-
-module_init(mimio_init);
-module_exit(mimio_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/netwave/netwave_cs.c b/drivers/staging/netwave/netwave_cs.c
index e936717d1f4..3875a722d12 100644
--- a/drivers/staging/netwave/netwave_cs.c
+++ b/drivers/staging/netwave/netwave_cs.c
@@ -46,7 +46,6 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
diff --git a/drivers/staging/octeon/ethernet-mem.c b/drivers/staging/octeon/ethernet-mem.c
index 00cc91df6b4..635bb86cdcf 100644
--- a/drivers/staging/octeon/ethernet-mem.c
+++ b/drivers/staging/octeon/ethernet-mem.c
@@ -26,6 +26,7 @@
**********************************************************************/
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <asm/octeon/octeon.h>
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 4a2161f70c7..e50a17d8070 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -30,6 +30,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/phy.h>
+#include <linux/slab.h>
#include <net/dst.h>
diff --git a/drivers/staging/otus/80211core/cagg.c b/drivers/staging/otus/80211core/cagg.c
index dbd0a5f0fcd..f9514c06c14 100644
--- a/drivers/staging/otus/80211core/cagg.c
+++ b/drivers/staging/otus/80211core/cagg.c
@@ -1832,14 +1832,12 @@ u16_t zfAggRxClear(zdev_t* dev, u32_t time)
struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
{
- u16_t dst0, src[3], ac, aid, fragOff;
- u8_t up;
+ u16_t dst0, src[3], aid;
u16_t offset = 0;
u16_t seq_no;
u16_t frameType;
u16_t frameCtrl;
u16_t frameSubtype;
- u32_t tcp_seq;
//struct aggSta *agg_sta;
#if ZM_AGG_FPGA_REORDERING
struct agg_tid_rx *tid_rx;
@@ -1864,13 +1862,17 @@ struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
return NULL;
}
#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
- tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
- tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
- tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
- tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
+ {
+ u32_t tcp_seq;
+
+ tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
+ tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
+ tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
+ tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
+ ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq);
+ }
#endif
- ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq);
dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
diff --git a/drivers/staging/otus/80211core/ccmd.c b/drivers/staging/otus/80211core/ccmd.c
index 8da28eee7fb..3e3d9b500f6 100644
--- a/drivers/staging/otus/80211core/ccmd.c
+++ b/drivers/staging/otus/80211core/ccmd.c
@@ -1659,7 +1659,7 @@ void zfiWlanSetPacketTypePromiscuous(zdev_t *dev, u32_t setValue)
if (setValue) {
/* write register for sniffer mode */
zfHpSetSnifferMode(dev, 1);
- zm_msg0_mm(ZM_LV_1, "enalbe sniffer mode");
+ zm_msg0_mm(ZM_LV_1, "enable sniffer mode");
} else {
zfHpSetSnifferMode(dev, 0);
zm_msg0_mm(ZM_LV_0, "disalbe sniffer mode");
diff --git a/drivers/staging/otus/80211core/cfunc.c b/drivers/staging/otus/80211core/cfunc.c
index d7c49d7523d..e0a9f383c75 100644
--- a/drivers/staging/otus/80211core/cfunc.c
+++ b/drivers/staging/otus/80211core/cfunc.c
@@ -1194,8 +1194,6 @@ u16_t zfFindMinimumUtilizationChannelIndex(zdev_t* dev, u16_t* array, u16_t coun
u8_t i;
u16_t tempMinIndex, tempMinValue;
- zmw_get_wlan_dev(dev);
-
i = 1;
tempMinIndex = 0;
tempMinValue = array[tempMinIndex];
diff --git a/drivers/staging/otus/80211core/cmm.c b/drivers/staging/otus/80211core/cmm.c
index a6c1b41ba84..484e753df35 100644
--- a/drivers/staging/otus/80211core/cmm.c
+++ b/drivers/staging/otus/80211core/cmm.c
@@ -346,8 +346,6 @@ u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type)
u8_t super_feature;
u8_t ouiSuperG[6] = {0x00,0x03,0x7f,0x01, 0x01, 0x00};
- zmw_get_wlan_dev(dev);
-
/* Get offset of first element */
subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
if ((offset = zgElementOffsetTable[subType]) == 0xff)
@@ -411,8 +409,6 @@ u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type)
u8_t id;
u8_t ouixr[6] = {0x00,0x03,0x7f,0x03, 0x01, 0x00};
- zmw_get_wlan_dev(dev);
-
/* Get offset of first element */
subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
if ((offset = zgElementOffsetTable[subType]) == 0xff)
diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c
index a11d559167b..c3fd47529c1 100644
--- a/drivers/staging/otus/80211core/cmmsta.c
+++ b/drivers/staging/otus/80211core/cmmsta.c
@@ -2808,7 +2808,7 @@ void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src)
zmw_get_wlan_dev(dev);
/* check mode : AP/IBSS */
- if ((wd->wlanMode != ZM_MODE_AP) || (wd->wlanMode != ZM_MODE_IBSS))
+ if ((wd->wlanMode != ZM_MODE_AP) && (wd->wlanMode != ZM_MODE_IBSS))
{
zm_msg0_mm(ZM_LV_3, "Ignore probe req");
return;
@@ -4848,8 +4848,6 @@ u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset)
u8_t MaxTxPower;
u8_t MinTxPower;
- zmw_get_wlan_dev(dev);
-
/* Element ID */
zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY);
@@ -5276,7 +5274,6 @@ u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf)
u8_t da0;
//u16_t sa[3];
u16_t ret;
- u16_t i;
//u8_t sa0;
zmw_get_wlan_dev(dev);
@@ -5738,8 +5735,6 @@ u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isH
u8_t weightOfN40BelowThr = 16;
u8_t weightOfN40UpThr = 32;
- zmw_get_wlan_dev(dev);
-
if( isBMode == 0 )
return (signalStrength + weightOfB); // pure b mode , do not add the weight value for this AP !
else
diff --git a/drivers/staging/otus/80211core/cpsmgr.c b/drivers/staging/otus/80211core/cpsmgr.c
index cf73caca8e5..98e1f0cc072 100644
--- a/drivers/staging/otus/80211core/cpsmgr.c
+++ b/drivers/staging/otus/80211core/cpsmgr.c
@@ -381,8 +381,6 @@ static void zfPowerSavingMgrSleepIfIdle(zdev_t *dev)
static void zfPowerSavingMgrDisconnectMain(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
#ifdef ZM_ENABLE_DISCONNECT_PS
switch(wd->sta.psMgr.state)
{
diff --git a/drivers/staging/otus/80211core/cscanmgr.c b/drivers/staging/otus/80211core/cscanmgr.c
index b32835c8759..be7d8ebe82b 100644
--- a/drivers/staging/otus/80211core/cscanmgr.c
+++ b/drivers/staging/otus/80211core/cscanmgr.c
@@ -289,8 +289,6 @@ static void zfScanMgrEventSetFreqCompleteCb(zdev_t* dev)
static void zfScanMgrEventScanCompleteCb(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
{
zfSendNullData(dev, 0);
diff --git a/drivers/staging/otus/80211core/ctkip.c b/drivers/staging/otus/80211core/ctkip.c
index be42f7aaa37..ca0740227be 100644
--- a/drivers/staging/otus/80211core/ctkip.c
+++ b/drivers/staging/otus/80211core/ctkip.c
@@ -255,7 +255,8 @@ void zfTkipInit(u8_t* key, u8_t* ta, struct zsTkipSeed* pSeed, u8_t* initIv)
zfMemoryCopy(pSeed->ta, ta, 6);
zfMemoryCopy(pSeed->tk, key, 16);
- iv16 = *initIv++;
+ iv16 = *initIv;
+ initIv++;
iv16 += *initIv<<8;
initIv++;
@@ -264,7 +265,7 @@ void zfTkipInit(u8_t* key, u8_t* ta, struct zsTkipSeed* pSeed, u8_t* initIv)
for(i=0; i<4; i++) // initiv is little endian
{
iv32 += *initIv<<(i*8);
- *initIv++;
+ initIv++;
}
pSeed->iv32 = iv32+1; // Force Recalculating on Tkip Phase1
diff --git a/drivers/staging/otus/80211core/ctxrx.c b/drivers/staging/otus/80211core/ctxrx.c
index ac54d5a636b..4e7f4bd86f4 100644
--- a/drivers/staging/otus/80211core/ctxrx.c
+++ b/drivers/staging/otus/80211core/ctxrx.c
@@ -536,8 +536,7 @@ void zfProtRspSim(zdev_t* dev, zbuf_t* buf)
zm_msg2_rx(ZM_LV_2, "ip1=", dip[1]);
//ARP request to 192.168.1.15
- if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01));
- {
+ if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01)) {
zm_msg0_rx(ZM_LV_2, "ARP");
/* ARP response */
zmw_rx_buf_writeh(dev, buf, 20, 0x0200);
@@ -883,7 +882,6 @@ zlError:
/************************************************************************/
u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t flag)
{
- u16_t err;
//u16_t addrTblSize;
//struct zsAddrTbl addrTbl;
u16_t removeLen;
@@ -905,7 +903,6 @@ u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t fla
u8_t qosType, keyIdx = 0;
u16_t fragOff;
u16_t newFlag;
- struct zsMicVar* pMicKey;
u8_t tkipFrameOffset = 0;
zmw_get_wlan_dev(dev);
@@ -1693,8 +1690,6 @@ void zfShowTxEAPOL(zdev_t* dev, zbuf_t* buf, u16_t offset)
u16_t packetLen, keyInfo, keyLen, keyDataLen, length, Op_Code;
u32_t replayCounterH, replayCounterL, vendorId, VendorType;
- zmw_get_wlan_dev(dev);
-
zm_debug_msg1("EAPOL Packet size = ", zfwBufGetSize(dev, buf));
/* EAPOL packet type */
@@ -2437,7 +2432,6 @@ void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo)
u16_t IvOffset;
u8_t keyLen = 5;
u8_t iv[3];
- u8_t *wepKey;
u8_t keyIdx;
IvOffset = offset + ZM_SIZE_OF_WLAN_DATA_HEADER;
diff --git a/drivers/staging/otus/80211core/ledmgr.c b/drivers/staging/otus/80211core/ledmgr.c
index 1e104a928ca..eafce0b1204 100644
--- a/drivers/staging/otus/80211core/ledmgr.c
+++ b/drivers/staging/otus/80211core/ledmgr.c
@@ -187,7 +187,6 @@ void zfLedCtrlType2_scan(zdev_t* dev);
void zfLedCtrlType2(zdev_t* dev)
{
- u32_t ton, toff, tmp, period;
u16_t OperateLED;
zmw_get_wlan_dev(dev);
diff --git a/drivers/staging/otus/80211core/pub_zfi.h b/drivers/staging/otus/80211core/pub_zfi.h
index b7b7f455f35..5202e5a645d 100644
--- a/drivers/staging/otus/80211core/pub_zfi.h
+++ b/drivers/staging/otus/80211core/pub_zfi.h
@@ -814,7 +814,6 @@ extern void zfiRxPerformanceReg(zdev_t* dev, u32_t reg, u32_t rsp);
#define ZM_PERFORMANCE_RX_AMSDU(dev, buf, len)
#define ZM_PERFORMANCE_RX_FLUSH(dev)
#define ZM_PERFORMANCE_RX_CLEAR(dev)
-#define ZM_SEQ_DEBUG
#define ZM_PERFORMANCE_RX_REORDER(dev)
#endif
/***** End of section 3 *****/
diff --git a/drivers/staging/otus/Kconfig b/drivers/staging/otus/Kconfig
index f6cc2625e34..e9181340bef 100644
--- a/drivers/staging/otus/Kconfig
+++ b/drivers/staging/otus/Kconfig
@@ -1,6 +1,8 @@
config OTUS
tristate "Atheros OTUS 802.11n USB wireless support"
depends on USB && WLAN && MAC80211
+ select WIRELESS_EXT
+ select WEXT_PRIV
default N
---help---
Enable support for Atheros 802.11n USB hardware:
diff --git a/drivers/staging/otus/apdbg.c b/drivers/staging/otus/apdbg.c
index 0eb93f19958..b59028e7e33 100644
--- a/drivers/staging/otus/apdbg.c
+++ b/drivers/staging/otus/apdbg.c
@@ -90,8 +90,27 @@ struct zdap_ioctl {
#endif
-char hex(char);
-unsigned char asctohex(char *str);
+static char hex(char v)
+{
+ if (isdigit(v))
+ return v - '0';
+ else if (isxdigit(v))
+ return tolower(v) - 'a' + 10;
+ else
+ return 0;
+}
+
+static unsigned char asctohex(char *str)
+{
+ unsigned char value;
+
+ value = hex(*str) & 0x0f;
+ value = value << 4;
+ str++;
+ value |= hex(*str) & 0x0f;
+
+ return value;
+}
char *prgname;
@@ -109,10 +128,10 @@ int set_ioctl(int sock, struct ifreq *req)
int read_reg(int sock, struct ifreq *req)
{
- struct zdap_ioctl *zdreq = 0;
+ struct zdap_ioctl *zdreq = NULL;
if (!set_ioctl(sock, req))
- return -1;
+ return -1;
/*
* zdreq = (struct zdap_ioctl *)req->ifr_data;
@@ -125,7 +144,7 @@ int read_reg(int sock, struct ifreq *req)
int read_mem(int sock, struct ifreq *req)
{
- struct zdap_ioctl *zdreq = 0;
+ struct zdap_ioctl *zdreq = NULL;
int i;
if (!set_ioctl(sock, req))
@@ -368,7 +387,7 @@ int main(int argc, char **argv)
zdreq.addr = addr;
zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE;
- } else {
+ } else {
fprintf(stderr, "error action\n");
exit(1);
}
@@ -380,25 +399,3 @@ fail:
exit(0);
}
-unsigned char asctohex(char *str)
-{
- unsigned char value;
-
- value = hex(*str) & 0x0f;
- value = value << 4;
- str++;
- value |= hex(*str) & 0x0f;
-
- return value;
-}
-
-char hex(char v)
-{
- if (isdigit(v))
- return v - '0';
- else if (isxdigit(v))
- return tolower(v) - 'a' + 10;
- else
- return 0;
-}
-
diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c
index 94f9cbbbdef..8dff5b97dfe 100644
--- a/drivers/staging/otus/hal/hpmain.c
+++ b/drivers/staging/otus/hal/hpmain.c
@@ -1316,7 +1316,6 @@ void zfHpSetFrequencyEx(zdev_t* dev, u32_t frequency, u8_t bw40,
u8_t extOffset, u8_t initRF)
{
u32_t cmd[9];
- u32_t cmdB[3];
u16_t ret;
u8_t old_band;
u8_t new_band;
@@ -3434,7 +3433,6 @@ void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset)
/* Write PHY regs 672-703 */
for (i=0; i<128; i+=4)
{
- u32_t regAddr = 0x9800 + (672 * 4);
u32_t val;
val = ((u32_t)vpd_chain1[i+3]<<24) |
@@ -3485,7 +3483,6 @@ void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset)
/* Write PHY regs 672-703 + 0x1000 */
for (i=0; i<128; i+=4)
{
- u32_t regAddr = 0x9800 + (672 * 4) + 0x1000;
u32_t val;
val = ((u32_t)vpd_chain3[i+3]<<24) |
@@ -4584,7 +4581,6 @@ void zfHpSetRollCallTable(zdev_t* dev)
void zfHpSetTTSIFSTime(zdev_t* dev, u8_t sifs_time)
{
u32_t reg_value = 0;
- zmw_get_wlan_dev(dev);
sifs_time &= 0x3f;
reg_value = 0x14400b | (((u32_t)sifs_time)<<24);
diff --git a/drivers/staging/otus/hal/hpreg.c b/drivers/staging/otus/hal/hpreg.c
index d9894fe5f4e..178777c09db 100644
--- a/drivers/staging/otus/hal/hpreg.c
+++ b/drivers/staging/otus/hal/hpreg.c
@@ -786,45 +786,6 @@ enum {
WT1_5760_5800,
};
-static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
- { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5130_5210 */
- { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5250_5330 */
- { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5370_5490 */
- { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5530_5650 */
-
- { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5150_5190 */
- { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5230_5310 */
- { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5350_5470 */
- { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5510_5670 */
-
- { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5200_5240 */
- { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5200_5240 */
- { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5210_5210 */
- { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5210_5210 */
-
- { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5280_5280 */
- { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T2_5280_5280 */
- { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5250_5250 */
- { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5290_5290 */
- { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5250_5290 */
- { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T2_5250_5290 */
-
- { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5540_5660 */
- { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5760_5800 */
- { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5760_5800 */
-
- { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5765_5805 */
-
- /*
- * Below are the WWR frequencies
- */
-
- { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5210_5250 */
- { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5290_5290 */
- { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5540_5660 */
- { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* WT1_5760_5800 */
-};
-
/*
* 2GHz 11b channel tags
*/
@@ -864,45 +825,6 @@ enum {
W2_2484_2484,
};
-static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
- { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2312_2372 */
- { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F2_2312_2372 */
-
- { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2412_2472 */
- { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0}, /* F2_2412_2472 */
- { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F3_2412_2472 */
-
- { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2412_2462 */
- { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0}, /* F2_2412_2462 */
- { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2432_2442 */
-
- { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2457_2472 */
-
- { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0, 0}, /* F1_2467_2472 */
-
- { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2484_2484 */
- { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0, 0}, /* F2_2484_2484 */
-
- { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2512_2732 */
-
- /*
- * WWR have powers opened up to 20dBm. Limits should often come from CTL/Max powers
- */
-
- { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2312_2372 */
- { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2412_2412 */
- { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2417_2432 */
- { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2437_2442 */
- { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2447_2457 */
- { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2462_2462 */
- { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2467_2467 */
- { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2467_2467 */
- { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2472_2472 */
- { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2472_2472 */
- { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2484_2484 */
- { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2484_2484 */
-};
-
/*
* 2GHz 11g channel tags
@@ -984,16 +906,6 @@ enum {
T1_2512_2732
};
-static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
- { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2312_2372 */
- { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2437_2437 */
- { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_2437_2437 */
- { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* T3_2437_2437 */
- { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2512_2732 */
-};
-
-
-
/*
* 2GHz 11n frequency tags
*/
@@ -1005,15 +917,6 @@ enum {
NG_DEMO_ALL_CHANNELS,
};
-static REG_DMN_FREQ_BAND regDmn2Ghz11ngFreq[] = {
- { 2422, 2452, 20, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG1_2422_2452 */
- { 2422, 2452, 27, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG2_2422_2452 */
- { 2422, 2452, 30, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG3_2422_2452 */
-
- { 2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG_DEMO_ALL_CHANNELS */
-};
-
-
/*
* 5GHz 11n frequency tags
*/
@@ -1050,42 +953,6 @@ enum {
NA_DEMO_ALL_CHANNELS,
};
-static REG_DMN_FREQ_BAND regDmn5Ghz11naFreq[] = {
- /*
- * ToDo: This table needs to be completely populated with 5GHz 11n properties
- */
- { 5190, 5230, 15, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5190_5230 */
- { 5190, 5230, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA2_5190_5230 */
- { 5190, 5230, 18, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA3_5190_5230 */
- { 5190, 5230, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA4_5190_5230 */
- { 5190, 5230, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA5_5190_5230 */
-
- { 5270, 5270, 23, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5270_5270 */
-
- { 5270, 5310, 18, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5270_5310 */
- { 5270, 5310, 20, 0, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1}, /* NA2_5270_5310 */
- { 5270, 5310, 23, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA3_5270_5310 */
- { 5270, 5310, 30, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA4_5270_5310 */
-
- { 5310, 5310, 17, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5310_5310 */
-
- { 5510, 5630, 30, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5510_5630 */
-
- { 5510, 5670, 20, 6, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1}, /* NA1_5510_5670 */
- { 5510, 5670, 27, 0, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA2_5510_5670 */
- { 5510, 5670, 30, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 1}, /* NA3_5510_5670 */
-
- { 5755, 5795, 17, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5755_5795 */
- { 5755, 5795, 20, 6, 40, 40, DFS_ETSI, NO_PSCAN, 0, 0}, /* NA2_5755_5795 */
- { 5755, 5795, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA3_5755_5795 */
- { 5755, 5795, 30, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA4_5755_5795 */
- { 5755, 5795, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA5_5755_5795 */
-
- { 5795, 5795, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5795_5795 */
-
- { 4920, 6100, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA_DEMO_ALL_CHANNELS */
-};
-
typedef struct regDomain {
u16_t regDmnEnum; /* value from EnumRd table */
u8_t conformanceTestLimit;
diff --git a/drivers/staging/otus/hal/hprw.c b/drivers/staging/otus/hal/hprw.c
index d9fad47d5d5..4dbd5fb44b0 100644
--- a/drivers/staging/otus/hal/hprw.c
+++ b/drivers/staging/otus/hal/hprw.c
@@ -282,7 +282,6 @@ void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen)
else if (src == ZM_OID_FLASH_READ)
{
u32_t datalen;
- u16_t i;
datalen = (rsp[0] & 255);
diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c
index 6808e69fb35..84be4b2cd69 100644
--- a/drivers/staging/otus/ioctl.c
+++ b/drivers/staging/otus/ioctl.c
@@ -23,6 +23,7 @@
/* Platform dependent. */
/* */
/************************************************************************/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/if_arp.h>
#include <linux/uaccess.h>
@@ -866,15 +867,15 @@ int usbdrvwext_giwscan(struct net_device *dev,
char *current_ev = extra;
char *end_buf;
int i;
- /* struct zsBssList BssList; */
- struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
- GFP_KERNEL);
/* BssList = wd->sta.pBssList; */
/* zmw_get_wlan_dev(dev); */
if (macp->DeviceOpened != 1)
return 0;
+ /* struct zsBssList BssList; */
+ struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
+ GFP_KERNEL);
if (data->length == 0)
end_buf = extra + IW_SCAN_MAX_DATA;
else
@@ -930,7 +931,7 @@ int usbdrvwext_siwessid(struct net_device *dev,
return -EINVAL;
if (essid->flags == 1) {
- if (essid->length > (IW_ESSID_MAX_SIZE + 1))
+ if (essid->length > IW_ESSID_MAX_SIZE)
return -E2BIG;
if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
@@ -2227,7 +2228,8 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
case ZD_CMD_SCAN_REQ:
printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
break;
- case ZD_CMD_SET_GENERIC_ELEMENT:
+ case ZD_CMD_SET_GENERIC_ELEMENT: {
+ u8_t len, *wpaie;
printk(KERN_ERR "usbdrv_wpa_ioctl:"
" ZD_CMD_SET_GENERIC_ELEMENT\n");
@@ -2250,8 +2252,8 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
/* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
* zdparm->u.generic_elem.len);
*/
- u8_t len = zdparm->u.generic_elem.len;
- u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;
+ len = zdparm->u.generic_elem.len;
+ wpaie = zdparm->u.generic_elem.data;
printk(KERN_ERR "wd->ap.wpaLen : % d\n", len);
@@ -2273,6 +2275,7 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
* #endif
*/
break;
+ }
/* #ifdef ZM_HOSTAPD_SUPPORT */
case ZD_CMD_GET_TSC:
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c
index b0adbc8b2dc..0ce65b5b945 100644
--- a/drivers/staging/otus/usbdrv.c
+++ b/drivers/staging/otus/usbdrv.c
@@ -38,6 +38,7 @@
#include "linux/netlink.h"
#include "linux/rtnetlink.h"
+#include "linux/slab.h"
#include <net/iw_handler.h>
@@ -829,7 +830,7 @@ int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId)
{
/* Allocate net device structure */
vap[vapId].dev = alloc_etherdev(0);
- printk("Register vap dev=%x\n", (u32_t)vap[vapId].dev);
+ printk("Register vap dev=%p\n", vap[vapId].dev);
if(vap[vapId].dev == NULL) {
printk("alloc_etherdev fail\n");
@@ -883,7 +884,7 @@ int zfLnxUnregisterVapDev(struct net_device* parentDev, u16_t vapId)
printk("Unregister VAP dev : %s\n", vap[vapId].dev->name);
if(vap[vapId].dev != NULL) {
- printk("Unregister vap dev=%x\n", (u32_t)vap[vapId].dev);
+ printk("Unregister vap dev=%p\n", vap[vapId].dev);
//
//unregister_netdevice(wds[wdsId].dev);
unregister_netdev(vap[vapId].dev);
diff --git a/drivers/staging/otus/usbdrv.h b/drivers/staging/otus/usbdrv.h
index 330d1b95cb8..7e66c2d72a6 100644
--- a/drivers/staging/otus/usbdrv.h
+++ b/drivers/staging/otus/usbdrv.h
@@ -38,6 +38,7 @@
#include <linux/uaccess.h>
#include <linux/wireless.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include "zdcompat.h"
diff --git a/drivers/staging/otus/wrap_mem.c b/drivers/staging/otus/wrap_mem.c
index 47cbce1346a..b0037568e87 100644
--- a/drivers/staging/otus/wrap_mem.c
+++ b/drivers/staging/otus/wrap_mem.c
@@ -27,6 +27,7 @@
#include "usbdrv.h"
#include <linux/netlink.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
/* Memory management */
diff --git a/drivers/staging/otus/wrap_pkt.c b/drivers/staging/otus/wrap_pkt.c
index 75bb952fd0a..5ecf38e355a 100644
--- a/drivers/staging/otus/wrap_pkt.c
+++ b/drivers/staging/otus/wrap_pkt.c
@@ -28,6 +28,7 @@
#include "usbdrv.h"
#include <linux/netlink.h>
+#include <linux/gfp.h>
#include <net/iw_handler.h>
@@ -58,7 +59,7 @@ void zfLnxRecv80211(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo)
skb1 = skb_copy(buf, GFP_ATOMIC);
if (skb1 != NULL) {
skb1->dev = dev;
- skb1->mac_header = skb1->data;
+ skb_reset_mac_header(skb1);
skb1->ip_summed = CHECKSUM_NONE;
skb1->pkt_type = PACKET_OTHERHOST;
/* ETH_P_80211_RAW */
@@ -85,13 +86,7 @@ void zfLnxRecvEth(zdev_t *dev, zbuf_t *buf, u16_t port)
/* new_buf = dev_alloc_skb(2048); */
new_buf = dev_alloc_skb(buf->len);
-#ifdef NET_SKBUFF_DATA_USES_OFFSET
- new_buf->tail = 0;
- new_buf->len = 0;
-#else
- new_buf->tail = new_buf->data;
- new_buf->len = 0;
-#endif
+ skb_reset_tail_pointer(new_buf);
skb_put(new_buf, buf->len);
memcpy(new_buf->data, buf->data, buf->len);
diff --git a/drivers/staging/otus/wrap_usb.c b/drivers/staging/otus/wrap_usb.c
index 6b336ede886..93459cadc47 100644
--- a/drivers/staging/otus/wrap_usb.c
+++ b/drivers/staging/otus/wrap_usb.c
@@ -28,6 +28,7 @@
#include "usbdrv.h"
#include <linux/netlink.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
extern void zfLnxInitUsbTxQ(zdev_t *dev);
diff --git a/drivers/staging/otus/wwrap.c b/drivers/staging/otus/wwrap.c
index 53d2a45d55f..a74f7eea56e 100644
--- a/drivers/staging/otus/wwrap.c
+++ b/drivers/staging/otus/wwrap.c
@@ -26,6 +26,7 @@
#include "usbdrv.h"
#include <linux/netlink.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo);
diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c
index 2a6d937ba5e..bb89d85a4c7 100644
--- a/drivers/staging/otus/zdusb.c
+++ b/drivers/staging/otus/zdusb.c
@@ -29,6 +29,7 @@
#endif
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "usbdrv.h"
@@ -45,7 +46,7 @@ MODULE_LICENSE("Dual BSD/GPL");
static const char driver_name[] = "Otus";
/* table of devices that work with this driver */
-static struct usb_device_id zd1221_ids [] = {
+static const struct usb_device_id zd1221_ids[] = {
{ USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) },
{ USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) },
{ USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) },
diff --git a/drivers/staging/p9auth/Kconfig b/drivers/staging/p9auth/Kconfig
deleted file mode 100644
index d1c66d26202..00000000000
--- a/drivers/staging/p9auth/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config PLAN9AUTH
- tristate "Plan 9 style capability device implementation"
- default n
- depends on CRYPTO
- help
- This module implements the Plan 9 style capability device.
-
- To compile this driver as a module, choose
- M here: the module will be called p9auth.
diff --git a/drivers/staging/p9auth/Makefile b/drivers/staging/p9auth/Makefile
deleted file mode 100644
index 3ebf6ff0eef..00000000000
--- a/drivers/staging/p9auth/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_PLAN9AUTH) += p9auth.o
diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c
deleted file mode 100644
index db796262121..00000000000
--- a/drivers/staging/p9auth/p9auth.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Plan 9 style capability device implementation for the Linux Kernel
- *
- * Copyright 2008, 2009 Ashwin Ganti <ashwin.ganti@gmail.com>
- *
- * Released under the GPLv2
- *
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/cdev.h>
-#include <linux/uaccess.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/crypto.h>
-#include <linux/highmem.h>
-#include <linux/scatterlist.h>
-#include <linux/sched.h>
-#include <linux/cred.h>
-
-#ifndef CAP_MAJOR
-#define CAP_MAJOR 0
-#endif
-
-#ifndef CAP_NR_DEVS
-#define CAP_NR_DEVS 2 /* caphash and capuse */
-#endif
-
-#ifndef CAP_NODE_SIZE
-#define CAP_NODE_SIZE 20
-#endif
-
-#define MAX_DIGEST_SIZE 20
-
-struct cap_node {
- char data[CAP_NODE_SIZE];
- struct list_head list;
-};
-
-struct cap_dev {
- struct cap_node *head;
- int node_size;
- unsigned long size;
- struct semaphore sem;
- struct cdev cdev;
-};
-
-static int cap_major = CAP_MAJOR;
-static int cap_minor;
-static int cap_nr_devs = CAP_NR_DEVS;
-static int cap_node_size = CAP_NODE_SIZE;
-
-module_param(cap_major, int, S_IRUGO);
-module_param(cap_minor, int, S_IRUGO);
-module_param(cap_nr_devs, int, S_IRUGO);
-
-MODULE_AUTHOR("Ashwin Ganti");
-MODULE_LICENSE("GPL");
-
-static struct cap_dev *cap_devices;
-
-static void hexdump(unsigned char *buf, unsigned int len)
-{
- while (len--)
- printk("%02x", *buf++);
- printk("\n");
-}
-
-static char *cap_hash(char *plain_text, unsigned int plain_text_size,
- char *key, unsigned int key_size)
-{
- struct scatterlist sg;
- char *result;
- struct crypto_hash *tfm;
- struct hash_desc desc;
- int ret;
-
- tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm)) {
- printk(KERN_ERR
- "failed to load transform for hmac(sha1): %ld\n",
- PTR_ERR(tfm));
- return NULL;
- }
-
- desc.tfm = tfm;
- desc.flags = 0;
-
- result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
- if (!result) {
- printk(KERN_ERR "out of memory!\n");
- goto out;
- }
-
- sg_set_buf(&sg, plain_text, plain_text_size);
-
- ret = crypto_hash_setkey(tfm, key, key_size);
- if (ret) {
- printk(KERN_ERR "setkey() failed ret=%d\n", ret);
- kfree(result);
- result = NULL;
- goto out;
- }
-
- ret = crypto_hash_digest(&desc, &sg, plain_text_size, result);
- if (ret) {
- printk(KERN_ERR "digest () failed ret=%d\n", ret);
- kfree(result);
- result = NULL;
- goto out;
- }
-
- printk(KERN_DEBUG "crypto hash digest size %d\n",
- crypto_hash_digestsize(tfm));
- hexdump(result, MAX_DIGEST_SIZE);
-
-out:
- crypto_free_hash(tfm);
- return result;
-}
-
-static int cap_trim(struct cap_dev *dev)
-{
- struct cap_node *tmp;
- struct list_head *pos, *q;
- if (dev->head != NULL) {
- list_for_each_safe(pos, q, &(dev->head->list)) {
- tmp = list_entry(pos, struct cap_node, list);
- list_del(pos);
- kfree(tmp);
- }
- }
- return 0;
-}
-
-static int cap_open(struct inode *inode, struct file *filp)
-{
- struct cap_dev *dev;
- dev = container_of(inode->i_cdev, struct cap_dev, cdev);
- filp->private_data = dev;
-
- /* trim to 0 the length of the device if open was write-only */
- if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
- if (down_interruptible(&dev->sem))
- return -ERESTARTSYS;
- cap_trim(dev);
- up(&dev->sem);
- }
- /* initialise the head if it is NULL */
- if (dev->head == NULL) {
- dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
- INIT_LIST_HEAD(&(dev->head->list));
- }
- return 0;
-}
-
-static int cap_release(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-static ssize_t cap_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *f_pos)
-{
- struct cap_node *node_ptr, *tmp;
- struct list_head *pos;
- struct cap_dev *dev = filp->private_data;
- ssize_t retval = -ENOMEM;
- struct cred *new;
- int len, target_int, source_int, flag = 0;
- char *user_buf, *user_buf_running, *source_user, *target_user,
- *rand_str, *hash_str, *result;
-
- if (down_interruptible(&dev->sem))
- return -ERESTARTSYS;
-
- user_buf_running = NULL;
- hash_str = NULL;
- node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
- user_buf = kzalloc(count+1, GFP_KERNEL);
- if (!node_ptr || !user_buf)
- goto out;
-
- if (copy_from_user(user_buf, buf, count)) {
- retval = -EFAULT;
- goto out;
- }
-
- /*
- * If the minor number is 0 ( /dev/caphash ) then simply add the
- * hashed capability supplied by the user to the list of hashes
- */
- if (0 == iminor(filp->f_dentry->d_inode)) {
- if (count > CAP_NODE_SIZE) {
- retval = -EINVAL;
- goto out;
- }
- printk(KERN_INFO "Capability being written to /dev/caphash : \n");
- hexdump(user_buf, count);
- memcpy(node_ptr->data, user_buf, count);
- list_add(&(node_ptr->list), &(dev->head->list));
- node_ptr = NULL;
- } else {
- char *tmpu;
- if (!cap_devices[0].head ||
- list_empty(&(cap_devices[0].head->list))) {
- retval = -EINVAL;
- goto out;
- }
- /*
- * break the supplied string into tokens with @ as the
- * delimiter If the string is "user1@user2@randomstring" we
- * need to split it and hash 'user1@user2' using 'randomstring'
- * as the key.
- */
- tmpu = user_buf_running = kstrdup(user_buf, GFP_KERNEL);
- source_user = strsep(&tmpu, "@");
- target_user = strsep(&tmpu, "@");
- rand_str = tmpu;
- if (!source_user || !target_user || !rand_str) {
- retval = -EINVAL;
- goto out;
- }
-
- /* hash the string user1@user2 with rand_str as the key */
- len = strlen(source_user) + strlen(target_user) + 1;
- /* src, @, len, \0 */
- hash_str = kzalloc(len+1, GFP_KERNEL);
- strcat(hash_str, source_user);
- strcat(hash_str, "@");
- strcat(hash_str, target_user);
-
- printk(KERN_ALERT "the source user is %s \n", source_user);
- printk(KERN_ALERT "the target user is %s \n", target_user);
-
- result = cap_hash(hash_str, len, rand_str, strlen(rand_str));
- if (NULL == result) {
- retval = -EFAULT;
- goto out;
- }
- memcpy(node_ptr->data, result, CAP_NODE_SIZE); /* why? */
- /* Change the process's uid if the hash is present in the
- * list of hashes
- */
- list_for_each(pos, &(cap_devices->head->list)) {
- /*
- * Change the user id of the process if the hashes
- * match
- */
- if (0 ==
- memcmp(result,
- list_entry(pos, struct cap_node,
- list)->data,
- CAP_NODE_SIZE)) {
- target_int = (unsigned int)
- simple_strtol(target_user, NULL, 0);
- source_int = (unsigned int)
- simple_strtol(source_user, NULL, 0);
- flag = 1;
-
- /*
- * Check whether the process writing to capuse
- * is actually owned by the source owner
- */
- if (source_int != current_uid()) {
- printk(KERN_ALERT
- "Process is not owned by the source user of the capability.\n");
- retval = -EFAULT;
- goto out;
- }
- /*
- * What all id's need to be changed here? uid,
- * euid, fsid, savedids ?? Currently I am
- * changing the effective user id since most of
- * the authorisation decisions are based on it
- */
- new = prepare_creds();
- if (!new) {
- retval = -ENOMEM;
- goto out;
- }
- new->uid = (uid_t) target_int;
- new->euid = (uid_t) target_int;
- retval = commit_creds(new);
- if (retval)
- goto out;
-
- /*
- * Remove the capability from the list and
- * break
- */
- tmp = list_entry(pos, struct cap_node, list);
- list_del(pos);
- kfree(tmp);
- break;
- }
- }
- if (0 == flag) {
- /*
- * The capability is not present in the list of the
- * hashes stored, hence return failure
- */
- printk(KERN_ALERT
- "Invalid capabiliy written to /dev/capuse \n");
- retval = -EFAULT;
- goto out;
- }
- }
- *f_pos += count;
- retval = count;
- /* update the size */
- if (dev->size < *f_pos)
- dev->size = *f_pos;
-
-out:
- kfree(node_ptr);
- kfree(user_buf);
- kfree(user_buf_running);
- kfree(hash_str);
- up(&dev->sem);
- return retval;
-}
-
-static const struct file_operations cap_fops = {
- .owner = THIS_MODULE,
- .write = cap_write,
- .open = cap_open,
- .release = cap_release,
-};
-
-/* no __exit here because it can be called by the init function */
-static void cap_cleanup_module(void)
-{
- int i;
- dev_t devno = MKDEV(cap_major, cap_minor);
- if (cap_devices) {
- for (i = 0; i < cap_nr_devs; i++) {
- cap_trim(cap_devices + i);
- cdev_del(&cap_devices[i].cdev);
- }
- kfree(cap_devices);
- }
- unregister_chrdev_region(devno, cap_nr_devs);
-
-}
-
-static void cap_setup_cdev(struct cap_dev *dev, int index)
-{
- int err, devno = MKDEV(cap_major, cap_minor + index);
- cdev_init(&dev->cdev, &cap_fops);
- dev->cdev.owner = THIS_MODULE;
- dev->cdev.ops = &cap_fops;
- err = cdev_add(&dev->cdev, devno, 1);
- if (err)
- printk(KERN_NOTICE "Error %d adding cap%d", err, index);
-}
-
-static int __init cap_init_module(void)
-{
- int result, i;
- dev_t dev = 0;
-
- if (cap_major) {
- dev = MKDEV(cap_major, cap_minor);
- result = register_chrdev_region(dev, cap_nr_devs, "cap");
- } else {
- result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs,
- "cap");
- cap_major = MAJOR(dev);
- }
-
- if (result < 0) {
- printk(KERN_WARNING "cap: can't get major %d\n",
- cap_major);
- return result;
- }
-
- cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev),
- GFP_KERNEL);
- if (!cap_devices) {
- result = -ENOMEM;
- goto fail;
- }
-
- /* Initialize each device. */
- for (i = 0; i < cap_nr_devs; i++) {
- cap_devices[i].node_size = cap_node_size;
- init_MUTEX(&cap_devices[i].sem);
- cap_setup_cdev(&cap_devices[i], i);
- }
-
- return 0;
-
-fail:
- cap_cleanup_module();
- return result;
-}
-
-module_init(cap_init_module);
-module_exit(cap_cleanup_module);
-
-
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 95c93e82cce..377884f3480 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -41,7 +41,6 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c
index fcba78d2163..0c495eacb75 100644
--- a/drivers/staging/phison/phison.c
+++ b/drivers/staging/phison/phison.c
@@ -69,7 +69,7 @@ static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ret;
}
-static struct pci_device_id phison_pci_tbl[] = {
+static const struct pci_device_id phison_pci_tbl[] = {
{ PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
{ 0, },
diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c
index 9095158fb1b..f940a34c1a0 100644
--- a/drivers/staging/poch/poch.c
+++ b/drivers/staging/poch/poch.c
@@ -21,6 +21,7 @@
#include <linux/ioctl.h>
#include <linux/io.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "poch.h"
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
index 5d04bf5b021..eed0e5545a5 100644
--- a/drivers/staging/pohmelfs/config.c
+++ b/drivers/staging/pohmelfs/config.c
@@ -20,6 +20,7 @@
#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include "netfs.h"
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
index aacd25bfb0c..79819f07bfb 100644
--- a/drivers/staging/pohmelfs/dir.c
+++ b/drivers/staging/pohmelfs/dir.c
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/jhash.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
#include "netfs.h"
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index f69b7783027..63275529ff5 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -36,6 +36,7 @@
#define POHMELFS_MAGIC_NUM 0x504f482e
static struct kmem_cache *pohmelfs_inode_cache;
+static atomic_t psb_bdi_num = ATOMIC_INIT(0);
/*
* Removes inode from all trees, drops local name cache and removes all queued
@@ -322,7 +323,7 @@ int pohmelfs_write_create_inode(struct pohmelfs_inode *pi)
t = netfs_trans_alloc(psb, err + 1, 0, 0);
if (!t) {
err = -ENOMEM;
- goto err_out_put;
+ goto err_out_exit;
}
t->complete = pohmelfs_write_inode_complete;
t->private = igrab(inode);
@@ -395,7 +396,8 @@ int pohmelfs_remove_child(struct pohmelfs_inode *pi, struct pohmelfs_name *n)
/*
* Writeback for given inode.
*/
-static int pohmelfs_write_inode(struct inode *inode, int sync)
+static int pohmelfs_write_inode(struct inode *inode,
+ struct writeback_control *wbc)
{
struct pohmelfs_inode *pi = POHMELFS_I(inode);
@@ -969,7 +971,7 @@ int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
(attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
- err = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+ err = dquot_transfer(inode, attr);
if (err)
goto err_out_exit;
}
@@ -1331,6 +1333,8 @@ static void pohmelfs_put_super(struct super_block *sb)
pohmelfs_crypto_exit(psb);
pohmelfs_state_exit(psb);
+ bdi_destroy(&psb->bdi);
+
kfree(psb);
sb->s_fs_info = NULL;
}
@@ -1767,8 +1771,7 @@ static int pohmelfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
seq_printf(m, "%u ", ctl->idx);
if (ctl->addr.sa_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
- /* seq_printf(m, "%pi4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port)); */
- seq_printf(m, "%u.%u.%u.%u:%u", NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ seq_printf(m, "%pI4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port));
} else if (ctl->addr.sa_family == AF_INET6) {
struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port));
@@ -1815,11 +1818,22 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
if (!psb)
goto err_out_exit;
+ err = bdi_init(&psb->bdi);
+ if (err)
+ goto err_out_free_sb;
+
+ err = bdi_register(&psb->bdi, NULL, "pfs-%d", atomic_inc_return(&psb_bdi_num));
+ if (err) {
+ bdi_destroy(&psb->bdi);
+ goto err_out_free_sb;
+ }
+
sb->s_fs_info = psb;
sb->s_op = &pohmelfs_sb_ops;
sb->s_magic = POHMELFS_MAGIC_NUM;
sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_blocksize = PAGE_SIZE;
+ sb->s_bdi = &psb->bdi;
psb->sb = sb;
@@ -1863,11 +1877,11 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
err = pohmelfs_parse_options((char *) data, psb, 0);
if (err)
- goto err_out_free_sb;
+ goto err_out_free_bdi;
err = pohmelfs_copy_crypto(psb);
if (err)
- goto err_out_free_sb;
+ goto err_out_free_bdi;
err = pohmelfs_state_init(psb);
if (err)
@@ -1916,6 +1930,8 @@ err_out_state_exit:
err_out_free_strings:
kfree(psb->cipher_string);
kfree(psb->hash_string);
+err_out_free_bdi:
+ bdi_destroy(&psb->bdi);
err_out_free_sb:
kfree(psb);
err_out_exit:
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c
index 22fef18cae9..6710114cd42 100644
--- a/drivers/staging/pohmelfs/lock.c
+++ b/drivers/staging/pohmelfs/lock.c
@@ -17,7 +17,6 @@
#include <linux/backing-dev.h>
#include <linux/fs.h>
#include <linux/fsnotify.h>
-#include <linux/slab.h>
#include <linux/mempool.h>
#include "netfs.h"
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
index af7f262e68c..4a86f0b1ea8 100644
--- a/drivers/staging/pohmelfs/net.c
+++ b/drivers/staging/pohmelfs/net.c
@@ -20,6 +20,7 @@
#include <linux/kthread.h>
#include <linux/pagemap.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/syscalls.h>
#include <linux/vmalloc.h>
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
index 623a07d29de..01cba006e07 100644
--- a/drivers/staging/pohmelfs/netfs.h
+++ b/drivers/staging/pohmelfs/netfs.h
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/connector.h>
+#include <linux/backing-dev.h>
#define POHMELFS_CN_IDX 5
#define POHMELFS_CN_VAL 0
@@ -624,6 +625,8 @@ struct pohmelfs_sb {
struct super_block *sb;
+ struct backing_dev_info bdi;
+
/*
* Algorithm strings.
*/
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c
index 3bad888ced1..cdc4dd50d63 100644
--- a/drivers/staging/pohmelfs/path_entry.c
+++ b/drivers/staging/pohmelfs/path_entry.c
@@ -14,7 +14,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/ktime.h>
#include <linux/fs_struct.h>
diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c
index f7726f1d364..1561f74a413 100644
--- a/drivers/staging/quatech_usb2/quatech_usb2.c
+++ b/drivers/staging/quatech_usb2/quatech_usb2.c
@@ -116,7 +116,7 @@ static int debug;
#define FOURTHCHAR ((unsigned char *)(urb->transfer_buffer))[i + 3]
#define FIFTHCHAR ((unsigned char *)(urb->transfer_buffer))[i + 4]
-static struct usb_device_id quausb2_id_table[] = {
+static const struct usb_device_id quausb2_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)},
diff --git a/drivers/staging/ramzswap/Kconfig b/drivers/staging/ramzswap/Kconfig
index 24e25691fae..127b3c6c959 100644
--- a/drivers/staging/ramzswap/Kconfig
+++ b/drivers/staging/ramzswap/Kconfig
@@ -5,7 +5,7 @@ config RAMZSWAP
select LZO_DECOMPRESS
default n
help
- Creates virtual block devices which can be used (only) as a swap
+ Creates virtual block devices which can (only) be used as swap
disks. Pages swapped to these disks are compressed and stored in
memory itself.
diff --git a/drivers/staging/ramzswap/ramzswap.txt b/drivers/staging/ramzswap/ramzswap.txt
index e9f1619505a..9694acfeb43 100644
--- a/drivers/staging/ramzswap/ramzswap.txt
+++ b/drivers/staging/ramzswap/ramzswap.txt
@@ -5,9 +5,9 @@ Project home: http://compcache.googlecode.com/
* Introduction
-It creates RAM based block devices which can be used (only) as swap disks.
-Pages swapped to these devices are compressed and stored in memory itself.
-See project home for use cases, performance numbers and a lot more.
+The ramzswap module creates RAM based block devices which can (only) be used as
+swap disks. Pages swapped to these devices are compressed and stored in memory
+itself. See project home for use cases, performance numbers and a lot more.
Individual ramzswap devices are configured and initialized using rzscontrol
userspace utility as shown in examples below. See rzscontrol man page for more
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index 989fac5b01b..ee5eb12b928 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -1,7 +1,7 @@
/*
* Compressed RAM based swap device
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
@@ -23,13 +23,12 @@
#include <linux/device.h>
#include <linux/genhd.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <linux/lzo.h>
-#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/swap.h>
#include <linux/swapops.h>
#include <linux/vmalloc.h>
-#include <linux/version.h>
#include "ramzswap_drv.h"
@@ -222,7 +221,7 @@ out:
return ret;
}
-void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
+static void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
struct ramzswap_ioctl_stats *s)
{
strncpy(s->backing_swap_name, rzs->backing_swap_name,
@@ -240,7 +239,8 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
mem_used = xv_get_total_size_bytes(rzs->mem_pool)
+ (rs->pages_expand << PAGE_SHIFT);
- succ_writes = rs->num_writes - rs->failed_writes;
+ succ_writes = rzs_stat64_read(rzs, &rs->num_writes) -
+ rzs_stat64_read(rzs, &rs->failed_writes);
if (succ_writes && rs->pages_stored) {
good_compress_perc = rs->good_compress * 100
@@ -249,11 +249,12 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
/ rs->pages_stored;
}
- s->num_reads = rs->num_reads;
- s->num_writes = rs->num_writes;
- s->failed_reads = rs->failed_reads;
- s->failed_writes = rs->failed_writes;
- s->invalid_io = rs->invalid_io;
+ s->num_reads = rzs_stat64_read(rzs, &rs->num_reads);
+ s->num_writes = rzs_stat64_read(rzs, &rs->num_writes);
+ s->failed_reads = rzs_stat64_read(rzs, &rs->failed_reads);
+ s->failed_writes = rzs_stat64_read(rzs, &rs->failed_writes);
+ s->invalid_io = rzs_stat64_read(rzs, &rs->invalid_io);
+ s->notify_free = rzs_stat64_read(rzs, &rs->notify_free);
s->pages_zero = rs->pages_zero;
s->good_compress_pct = good_compress_perc;
@@ -265,8 +266,8 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
s->compr_data_size = rs->compr_size;
s->mem_used_total = mem_used;
- s->bdev_num_reads = rs->bdev_num_reads;
- s->bdev_num_writes = rs->bdev_num_writes;
+ s->bdev_num_reads = rzs_stat64_read(rzs, &rs->bdev_num_reads);
+ s->bdev_num_writes = rzs_stat64_read(rzs, &rs->bdev_num_writes);
}
#endif /* CONFIG_RAMZSWAP_STATS */
}
@@ -502,6 +503,14 @@ static int setup_backing_swap(struct ramzswap *rzs)
goto bad_param;
}
disksize = i_size_read(inode);
+ /*
+ * Can happen if user gives an extended partition as
+ * backing swap or simply a bad disk.
+ */
+ if (!disksize) {
+ pr_err("Error reading backing swap size.\n");
+ goto bad_param;
+ }
} else if (S_ISREG(inode->i_mode)) {
bdev = inode->i_sb->s_bdev;
if (IS_SWAPFILE(inode)) {
@@ -519,7 +528,6 @@ static int setup_backing_swap(struct ramzswap *rzs)
rzs->swap_file = swap_file;
rzs->backing_swap = bdev;
rzs->disksize = disksize;
- BUG_ON(!rzs->disksize);
return 0;
@@ -537,7 +545,7 @@ out:
* Map logical page number 'pagenum' to physical page number
* on backing swap device. For block device, this is a nop.
*/
-u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum)
+static u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum)
{
u32 skip_pages, entries_per_page;
size_t delta, se_offset, skipped;
@@ -593,9 +601,13 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
u32 offset = rzs->table[index].offset;
if (unlikely(!page)) {
+ /*
+ * No memory is allocated for zero filled pages.
+ * Simply clear zero page flag.
+ */
if (rzs_test_flag(rzs, index, RZS_ZERO)) {
rzs_clear_flag(rzs, index, RZS_ZERO);
- stat_dec(rzs->stats.pages_zero);
+ rzs_stat_dec(&rzs->stats.pages_zero);
}
return;
}
@@ -604,7 +616,7 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
clen = PAGE_SIZE;
__free_page(page);
rzs_clear_flag(rzs, index, RZS_UNCOMPRESSED);
- stat_dec(rzs->stats.pages_expand);
+ rzs_stat_dec(&rzs->stats.pages_expand);
goto out;
}
@@ -614,11 +626,11 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
xv_free(rzs->mem_pool, page, offset);
if (clen <= PAGE_SIZE / 2)
- stat_dec(rzs->stats.good_compress);
+ rzs_stat_dec(&rzs->stats.good_compress);
out:
rzs->stats.compr_size -= clen;
- stat_dec(rzs->stats.pages_stored);
+ rzs_stat_dec(&rzs->stats.pages_stored);
rzs->table[index].page = NULL;
rzs->table[index].offset = 0;
@@ -664,7 +676,6 @@ static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio)
return 0;
}
-
/*
* Called when request page is not present in ramzswap.
* Its either in backing swap device (if present) or
@@ -680,8 +691,8 @@ static int handle_ramzswap_fault(struct ramzswap *rzs, struct bio *bio)
*/
if (rzs->backing_swap) {
u32 pagenum;
- stat_dec(rzs->stats.num_reads);
- stat_inc(rzs->stats.bdev_num_reads);
+ rzs_stat64_dec(rzs, &rzs->stats.num_reads);
+ rzs_stat64_inc(rzs, &rzs->stats.bdev_num_reads);
bio->bi_bdev = rzs->backing_swap;
/*
@@ -719,7 +730,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
struct zobj_header *zheader;
unsigned char *user_mem, *cmem;
- stat_inc(rzs->stats.num_reads);
+ rzs_stat64_inc(rzs, &rzs->stats.num_reads);
page = bio->bi_io_vec[0].bv_page;
index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
@@ -731,7 +742,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
if (!rzs->table[index].page)
return handle_ramzswap_fault(rzs, bio);
- /* Page is stored uncompressed since its incompressible */
+ /* Page is stored uncompressed since it's incompressible */
if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
return handle_uncompressed_page(rzs, bio);
@@ -753,7 +764,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
if (unlikely(ret != LZO_E_OK)) {
pr_err("Decompression failed! err=%d, page=%u\n",
ret, index);
- stat_inc(rzs->stats.failed_reads);
+ rzs_stat64_inc(rzs, &rzs->stats.failed_reads);
goto out;
}
@@ -777,7 +788,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
struct page *page, *page_store;
unsigned char *user_mem, *cmem, *src;
- stat_inc(rzs->stats.num_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.num_writes);
page = bio->bi_io_vec[0].bv_page;
index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
@@ -789,25 +800,16 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
* is no longer referenced by any process. So, its now safe
* to free the memory that was allocated for this page.
*/
- if (rzs->table[index].page)
+ if (rzs->table[index].page || rzs_test_flag(rzs, index, RZS_ZERO))
ramzswap_free_page(rzs, index);
- /*
- * No memory ia allocated for zero filled pages.
- * Simply clear zero page flag.
- */
- if (rzs_test_flag(rzs, index, RZS_ZERO)) {
- stat_dec(rzs->stats.pages_zero);
- rzs_clear_flag(rzs, index, RZS_ZERO);
- }
-
mutex_lock(&rzs->lock);
user_mem = kmap_atomic(page, KM_USER0);
if (page_zero_filled(user_mem)) {
kunmap_atomic(user_mem, KM_USER0);
mutex_unlock(&rzs->lock);
- stat_inc(rzs->stats.pages_zero);
+ rzs_stat_inc(&rzs->stats.pages_zero);
rzs_set_flag(rzs, index, RZS_ZERO);
set_bit(BIO_UPTODATE, &bio->bi_flags);
@@ -831,7 +833,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
if (unlikely(ret != LZO_E_OK)) {
mutex_unlock(&rzs->lock);
pr_err("Compression failed! err=%d\n", ret);
- stat_inc(rzs->stats.failed_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
goto out;
}
@@ -854,13 +856,13 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
mutex_unlock(&rzs->lock);
pr_info("Error allocating memory for incompressible "
"page: %u\n", index);
- stat_inc(rzs->stats.failed_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
goto out;
}
offset = 0;
rzs_set_flag(rzs, index, RZS_UNCOMPRESSED);
- stat_inc(rzs->stats.pages_expand);
+ rzs_stat_inc(&rzs->stats.pages_expand);
rzs->table[index].page = page_store;
src = kmap_atomic(page, KM_USER0);
goto memstore;
@@ -872,7 +874,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
mutex_unlock(&rzs->lock);
pr_info("Error allocating memory for compressed "
"page: %u, size=%zu\n", index, clen);
- stat_inc(rzs->stats.failed_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
if (rzs->backing_swap)
fwd_write_request = 1;
goto out;
@@ -901,9 +903,9 @@ memstore:
/* Update stats */
rzs->stats.compr_size += clen;
- stat_inc(rzs->stats.pages_stored);
+ rzs_stat_inc(&rzs->stats.pages_stored);
if (clen <= PAGE_SIZE / 2)
- stat_inc(rzs->stats.good_compress);
+ rzs_stat_inc(&rzs->stats.good_compress);
mutex_unlock(&rzs->lock);
@@ -913,7 +915,7 @@ memstore:
out:
if (fwd_write_request) {
- stat_inc(rzs->stats.bdev_num_writes);
+ rzs_stat64_inc(rzs, &rzs->stats.bdev_num_writes);
bio->bi_bdev = rzs->backing_swap;
#if 0
/*
@@ -941,7 +943,6 @@ out:
return 0;
}
-
/*
* Check if request is within bounds and page aligned.
*/
@@ -975,7 +976,7 @@ static int ramzswap_make_request(struct request_queue *queue, struct bio *bio)
}
if (!valid_swap_request(rzs, bio)) {
- stat_inc(rzs->stats.invalid_io);
+ rzs_stat64_inc(rzs, &rzs->stats.invalid_io);
bio_io_error(bio);
return 0;
}
@@ -1000,6 +1001,9 @@ static void reset_device(struct ramzswap *rzs)
unsigned entries_per_page;
unsigned long num_table_pages, entry = 0;
+ /* Do not accept any new I/O request */
+ rzs->init_done = 0;
+
if (rzs->backing_swap && !rzs->num_extents)
is_backing_blkdev = 1;
@@ -1066,6 +1070,7 @@ static void reset_device(struct ramzswap *rzs)
bd_release(rzs->backing_swap);
filp_close(rzs->swap_file, NULL);
rzs->backing_swap = NULL;
+ memset(rzs->backing_swap_name, 0, MAX_SWAP_NAME_LEN);
}
/* Reset stats */
@@ -1073,9 +1078,6 @@ static void reset_device(struct ramzswap *rzs)
rzs->disksize = 0;
rzs->memlimit = 0;
-
- /* Back to uninitialized state */
- rzs->init_done = 0;
}
static int ramzswap_ioctl_init_device(struct ramzswap *rzs)
@@ -1276,6 +1278,11 @@ static int ramzswap_ioctl(struct block_device *bdev, fmode_t mode,
ret = -EBUSY;
goto out;
}
+
+ /* Make sure all pending I/O is finished */
+ if (bdev)
+ fsync_bdev(bdev);
+
ret = ramzswap_ioctl_reset_device(rzs);
break;
@@ -1293,16 +1300,20 @@ static struct block_device_operations ramzswap_devops = {
.owner = THIS_MODULE,
};
-static void create_device(struct ramzswap *rzs, int device_id)
+static int create_device(struct ramzswap *rzs, int device_id)
{
+ int ret = 0;
+
mutex_init(&rzs->lock);
+ spin_lock_init(&rzs->stat64_lock);
INIT_LIST_HEAD(&rzs->backing_swap_extent_list);
rzs->queue = blk_alloc_queue(GFP_KERNEL);
if (!rzs->queue) {
pr_err("Error allocating disk queue for device %d\n",
device_id);
- return;
+ ret = -ENOMEM;
+ goto out;
}
blk_queue_make_request(rzs->queue, ramzswap_make_request);
@@ -1314,7 +1325,8 @@ static void create_device(struct ramzswap *rzs, int device_id)
blk_cleanup_queue(rzs->queue);
pr_warning("Error allocating disk structure for device %d\n",
device_id);
- return;
+ ret = -ENOMEM;
+ goto out;
}
rzs->disk->major = ramzswap_major;
@@ -1329,9 +1341,16 @@ static void create_device(struct ramzswap *rzs, int device_id)
* or set equal to backing swap device (if provided)
*/
set_capacity(rzs->disk, 0);
+
+ blk_queue_physical_block_size(rzs->disk->queue, PAGE_SIZE);
+ blk_queue_logical_block_size(rzs->disk->queue, PAGE_SIZE);
+
add_disk(rzs->disk);
rzs->init_done = 0;
+
+out:
+ return ret;
}
static void destroy_device(struct ramzswap *rzs)
@@ -1347,18 +1366,20 @@ static void destroy_device(struct ramzswap *rzs)
static int __init ramzswap_init(void)
{
- int i, ret;
+ int ret, dev_id;
if (num_devices > max_num_devices) {
pr_warning("Invalid value for num_devices: %u\n",
num_devices);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
ramzswap_major = register_blkdev(0, "ramzswap");
if (ramzswap_major <= 0) {
pr_warning("Unable to get major number\n");
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
if (!num_devices) {
@@ -1371,15 +1392,23 @@ static int __init ramzswap_init(void)
devices = kzalloc(num_devices * sizeof(struct ramzswap), GFP_KERNEL);
if (!devices) {
ret = -ENOMEM;
- goto out;
+ goto unregister;
}
- for (i = 0; i < num_devices; i++)
- create_device(&devices[i], i);
+ for (dev_id = 0; dev_id < num_devices; dev_id++) {
+ ret = create_device(&devices[dev_id], dev_id);
+ if (ret)
+ goto free_devices;
+ }
return 0;
-out:
+
+free_devices:
+ while (dev_id)
+ destroy_device(&devices[--dev_id]);
+unregister:
unregister_blkdev(ramzswap_major, "ramzswap");
+out:
return ret;
}
diff --git a/drivers/staging/ramzswap/ramzswap_drv.h b/drivers/staging/ramzswap/ramzswap_drv.h
index a6ea240935b..c7e0e767c22 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.h
+++ b/drivers/staging/ramzswap/ramzswap_drv.h
@@ -1,7 +1,7 @@
/*
* Compressed RAM based swap device
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
@@ -15,6 +15,9 @@
#ifndef _RAMZSWAP_DRV_H_
#define _RAMZSWAP_DRV_H_
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+
#include "ramzswap_ioctl.h"
#include "xvmalloc.h"
@@ -71,15 +74,6 @@ static const unsigned max_zpage_size_nobdev = PAGE_SIZE / 4 * 3;
#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT)
#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT)
-/* Debugging and Stats */
-#if defined(CONFIG_RAMZSWAP_STATS)
-#define stat_inc(stat) ((stat)++)
-#define stat_dec(stat) ((stat)--)
-#else
-#define stat_inc(x)
-#define stat_dec(x)
-#endif
-
/* Flags for ramzswap pages (table[page_no].flags) */
enum rzs_pageflags {
/* Page is stored uncompressed */
@@ -102,7 +96,7 @@ struct table {
u16 offset;
u8 count; /* object ref count (not yet used) */
u8 flags;
-} __attribute__((aligned(4)));;
+} __attribute__((aligned(4)));
/*
* Swap extent information in case backing swap is a regular
@@ -121,9 +115,10 @@ struct ramzswap_stats {
#if defined(CONFIG_RAMZSWAP_STATS)
u64 num_reads; /* failed + successful */
u64 num_writes; /* --do-- */
- u64 failed_reads; /* can happen when memory is too low */
- u64 failed_writes; /* should NEVER! happen */
+ u64 failed_reads; /* should NEVER! happen */
+ u64 failed_writes; /* can happen when memory is too low */
u64 invalid_io; /* non-swap I/O requests */
+ u64 notify_free; /* no. of swap slot free notifications */
u32 pages_zero; /* no. of zero filled pages */
u32 pages_stored; /* no. of pages currently stored */
u32 good_compress; /* % of pages with compression ratio<=50% */
@@ -138,6 +133,7 @@ struct ramzswap {
void *compress_workmem;
void *compress_buffer;
struct table *table;
+ spinlock_t stat64_lock; /* protect 64-bit stats */
struct mutex lock;
struct request_queue *queue;
struct gendisk *disk;
@@ -167,5 +163,48 @@ struct ramzswap {
/*-- */
-#endif
+/* Debugging and Stats */
+#if defined(CONFIG_RAMZSWAP_STATS)
+static void rzs_stat_inc(u32 *v)
+{
+ *v = *v + 1;
+}
+
+static void rzs_stat_dec(u32 *v)
+{
+ *v = *v - 1;
+}
+
+static void rzs_stat64_inc(struct ramzswap *rzs, u64 *v)
+{
+ spin_lock(&rzs->stat64_lock);
+ *v = *v + 1;
+ spin_unlock(&rzs->stat64_lock);
+}
+
+static void rzs_stat64_dec(struct ramzswap *rzs, u64 *v)
+{
+ spin_lock(&rzs->stat64_lock);
+ *v = *v - 1;
+ spin_unlock(&rzs->stat64_lock);
+}
+
+static u64 rzs_stat64_read(struct ramzswap *rzs, u64 *v)
+{
+ u64 val;
+
+ spin_lock(&rzs->stat64_lock);
+ val = *v;
+ spin_unlock(&rzs->stat64_lock);
+
+ return val;
+}
+#else
+#define rzs_stat_inc(v)
+#define rzs_stat_dec(v)
+#define rzs_stat64_inc(r, v)
+#define rzs_stat64_dec(r, v)
+#define rzs_stat64_read(r, v)
+#endif /* CONFIG_RAMZSWAP_STATS */
+#endif
diff --git a/drivers/staging/ramzswap/ramzswap_ioctl.h b/drivers/staging/ramzswap/ramzswap_ioctl.h
index c713a09af58..d26076d41bd 100644
--- a/drivers/staging/ramzswap/ramzswap_ioctl.h
+++ b/drivers/staging/ramzswap/ramzswap_ioctl.h
@@ -1,7 +1,7 @@
/*
* Compressed RAM based swap device
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
@@ -24,9 +24,10 @@ struct ramzswap_ioctl_stats {
* size (if present) */
u64 num_reads; /* failed + successful */
u64 num_writes; /* --do-- */
- u64 failed_reads; /* can happen when memory is too low */
- u64 failed_writes; /* should NEVER! happen */
+ u64 failed_reads; /* should NEVER! happen */
+ u64 failed_writes; /* can happen when memory is too low */
u64 invalid_io; /* non-swap I/O requests */
+ u64 notify_free; /* no. of swap slot free notifications */
u32 pages_zero; /* no. of zero filled pages */
u32 good_compress_pct; /* no. of pages with compression ratio<=50% */
u32 pages_expand_pct; /* no. of incompressible pages */
diff --git a/drivers/staging/ramzswap/xvmalloc.c b/drivers/staging/ramzswap/xvmalloc.c
index b3e986c3314..3fdbb8ada82 100644
--- a/drivers/staging/ramzswap/xvmalloc.c
+++ b/drivers/staging/ramzswap/xvmalloc.c
@@ -1,7 +1,7 @@
/*
* xvmalloc memory allocator
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
@@ -273,7 +273,7 @@ static void remove_block(struct xv_pool *pool, struct page *page, u32 offset,
}
/*
- * Allocate a page and add it freelist of given pool.
+ * Allocate a page and add it to freelist of given pool.
*/
static int grow_pool(struct xv_pool *pool, gfp_t flags)
{
diff --git a/drivers/staging/ramzswap/xvmalloc.h b/drivers/staging/ramzswap/xvmalloc.h
index 010c6fe5e17..5b1a81aa5fa 100644
--- a/drivers/staging/ramzswap/xvmalloc.h
+++ b/drivers/staging/ramzswap/xvmalloc.h
@@ -1,7 +1,7 @@
/*
* xvmalloc memory allocator
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
diff --git a/drivers/staging/ramzswap/xvmalloc_int.h b/drivers/staging/ramzswap/xvmalloc_int.h
index 03c1a652a3a..e23ed5c8b8e 100644
--- a/drivers/staging/ramzswap/xvmalloc_int.h
+++ b/drivers/staging/ramzswap/xvmalloc_int.h
@@ -1,7 +1,7 @@
/*
* xvmalloc memory allocator
*
- * Copyright (C) 2008, 2009 Nitin Gupta
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
*
* This code is released using a dual license strategy: BSD/GPL
* You can choose the licence that better fits your requirements.
@@ -62,7 +62,7 @@ struct link_free {
struct block_header {
union {
- /* This common header must be ALIGN bytes */
+ /* This common header must be XV_ALIGN bytes */
u8 common[XV_ALIGN];
struct {
u16 size;
diff --git a/drivers/staging/rar/Kconfig b/drivers/staging/rar/Kconfig
deleted file mode 100644
index 17f8bf3bb41..00000000000
--- a/drivers/staging/rar/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# RAR device configuration
-#
-
-menu "RAR Register Driver"
-#
-# Restricted Access Register Manager
-#
-config RAR_REGISTER
- tristate "Restricted Access Region Register Driver"
- default n
- ---help---
- This driver allows other kernel drivers access to the
- contents of the restricted access region control
- registers.
-
-endmenu
diff --git a/drivers/staging/rar/Makefile b/drivers/staging/rar/Makefile
deleted file mode 100644
index 5422ed04ccf..00000000000
--- a/drivers/staging/rar/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-EXTRA_CFLAGS += -DLITTLE__ENDIAN
-obj-$(CONFIG_RAR_REGISTER) += rar_driver.o
diff --git a/drivers/staging/rar/rar_driver.c b/drivers/staging/rar/rar_driver.c
deleted file mode 100644
index d85d1890e81..00000000000
--- a/drivers/staging/rar/rar_driver.c
+++ /dev/null
@@ -1,444 +0,0 @@
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/kdev_t.h>
-#include <linux/semaphore.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/ioctl.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/pagemap.h>
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/sched.h>
-#include "rar_driver.h"
-
-/* The following defines are for the IPC process to retrieve RAR in */
-
-/* === Lincroft Message Bus Interface === */
-/* Message Control Register */
-#define LNC_MCR_OFFSET 0xD0
-
-/* Message Data Register */
-#define LNC_MDR_OFFSET 0xD4
-
-/* Message Opcodes */
-#define LNC_MESSAGE_READ_OPCODE 0xD0
-#define LNC_MESSAGE_WRITE_OPCODE 0xE0
-
-/* Message Write Byte Enables */
-#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
-
-/* B-unit Port */
-#define LNC_BUNIT_PORT 0x3
-
-/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
-#define LNC_BRAR0L 0x10
-#define LNC_BRAR0H 0x11
-#define LNC_BRAR1L 0x12
-#define LNC_BRAR1H 0x13
-
-/* Reserved for SeP */
-#define LNC_BRAR2L 0x14
-#define LNC_BRAR2H 0x15
-
-
-/* This structure is only used during module initialization. */
-struct RAR_offsets {
- int low; /* Register offset for low RAR physical address. */
- int high; /* Register offset for high RAR physical address. */
-};
-
-struct pci_dev *rar_dev;
-static uint32_t registered;
-
-/* Moorestown supports three restricted access regions. */
-#define MRST_NUM_RAR 3
-
-struct RAR_address_struct rar_addr[MRST_NUM_RAR];
-
-/* prototype for init */
-static int __init rar_init_handler(void);
-static void __exit rar_exit_handler(void);
-
-/*
- function that is activated on the successfull probe of the RAR device
-*/
-static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-
-static struct pci_device_id rar_pci_id_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) },
- { 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
-
-/* field for registering driver to PCI device */
-static struct pci_driver rar_pci_driver = {
- .name = "rar_driver",
- .id_table = rar_pci_id_tbl,
- .probe = rar_probe
-};
-
-/* This function is used to retrieved RAR info using the IPC message
- bus interface */
-static int memrar_get_rar_addr(struct pci_dev* pdev,
- int offset,
- u32 *addr)
-{
- /*
- * ======== The Lincroft Message Bus Interface ========
- * Lincroft registers may be obtained from the PCI
- * (the Host Bridge) using the Lincroft Message Bus
- * Interface. That message bus interface is generally
- * comprised of two registers: a control register (MCR, 0xDO)
- * and a data register (MDR, 0xD4).
- *
- * The MCR (message control register) format is the following:
- * 1. [31:24]: Opcode
- * 2. [23:16]: Port
- * 3. [15:8]: Register Offset
- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
- * to 1)
- * 5. [3:0]: reserved
- *
- * Read (0xD0) and write (0xE0) opcodes are written to the
- * control register when reading and writing to Lincroft
- * registers, respectively.
- *
- * We're interested in registers found in the Lincroft
- * B-unit. The B-unit port is 0x3.
- *
- * The six B-unit RAR register offsets we use are listed
- * earlier in this file.
- *
- * Lastly writing to the MCR register requires the "Byte
- * enables" bits to be set to 1. This may be achieved by
- * writing 0xF at bit 4.
- *
- * The MDR (message data register) format is the following:
- * 1. [31:0]: Read/Write Data
- *
- * Data being read from this register is only available after
- * writing the appropriate control message to the MCR
- * register.
- *
- * Data being written to this register must be written before
- * writing the appropriate control message to the MCR
- * register.
- */
-
- int result = 0; /* result */
- /* Construct control message */
- u32 const message =
- (LNC_MESSAGE_READ_OPCODE << 24)
- | (LNC_BUNIT_PORT << 16)
- | (offset << 8)
- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
-
- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
-
- if (addr == 0)
- return -EINVAL;
-
- /* Send the control message */
- result = pci_write_config_dword(pdev,
- LNC_MCR_OFFSET,
- message);
-
- printk(KERN_WARNING "rar- result from send ctl register is %x\n"
- ,result);
-
- if (!result)
- result = pci_read_config_dword(pdev,
- LNC_MDR_OFFSET,
- addr);
-
- printk(KERN_WARNING "rar- result from read data register is %x\n",
- result);
-
- printk(KERN_WARNING "rar- value read from data register is %x\n",
- *addr);
-
- if (result)
- return -1;
- else
- return 0;
-}
-
-static int memrar_set_rar_addr(struct pci_dev* pdev,
- int offset,
- u32 addr)
-{
- /*
- * ======== The Lincroft Message Bus Interface ========
- * Lincroft registers may be obtained from the PCI
- * (the Host Bridge) using the Lincroft Message Bus
- * Interface. That message bus interface is generally
- * comprised of two registers: a control register (MCR, 0xDO)
- * and a data register (MDR, 0xD4).
- *
- * The MCR (message control register) format is the following:
- * 1. [31:24]: Opcode
- * 2. [23:16]: Port
- * 3. [15:8]: Register Offset
- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
- * to 1)
- * 5. [3:0]: reserved
- *
- * Read (0xD0) and write (0xE0) opcodes are written to the
- * control register when reading and writing to Lincroft
- * registers, respectively.
- *
- * We're interested in registers found in the Lincroft
- * B-unit. The B-unit port is 0x3.
- *
- * The six B-unit RAR register offsets we use are listed
- * earlier in this file.
- *
- * Lastly writing to the MCR register requires the "Byte
- * enables" bits to be set to 1. This may be achieved by
- * writing 0xF at bit 4.
- *
- * The MDR (message data register) format is the following:
- * 1. [31:0]: Read/Write Data
- *
- * Data being read from this register is only available after
- * writing the appropriate control message to the MCR
- * register.
- *
- * Data being written to this register must be written before
- * writing the appropriate control message to the MCR
- * register.
- */
-
- int result = 0; /* result */
-
- /* Construct control message */
- u32 const message =
- (LNC_MESSAGE_WRITE_OPCODE << 24)
- | (LNC_BUNIT_PORT << 16)
- | (offset << 8)
- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
-
- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
-
- if (addr == 0)
- return -EINVAL;
-
- /* Send the control message */
- result = pci_write_config_dword(pdev,
- LNC_MDR_OFFSET,
- addr);
-
- printk(KERN_WARNING "rar- result from send ctl register is %x\n"
- ,result);
-
- if (!result)
- result = pci_write_config_dword(pdev,
- LNC_MCR_OFFSET,
- message);
-
- printk(KERN_WARNING "rar- result from write data register is %x\n",
- result);
-
- printk(KERN_WARNING "rar- value read to data register is %x\n",
- addr);
-
- if (result)
- return -1;
- else
- return 0;
-}
-
-/*
-
- * Initialize RAR parameters, such as physical addresses, etc.
-
- */
-static int memrar_init_rar_params(struct pci_dev *pdev)
-{
- struct RAR_offsets const offsets[] = {
- { LNC_BRAR0L, LNC_BRAR0H },
- { LNC_BRAR1L, LNC_BRAR1H },
- { LNC_BRAR2L, LNC_BRAR2H }
- };
-
- size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]);
- struct RAR_offsets const *end = offsets + num_offsets;
- struct RAR_offsets const *i;
- unsigned int n = 0;
- int result = 0;
-
- /* Retrieve RAR start and end physical addresses. */
-
- /*
- * Access the RAR registers through the Lincroft Message Bus
- * Interface on PCI device: 00:00.0 Host bridge.
- */
-
- /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */
-
- if (pdev == NULL)
- return -ENODEV;
-
- for (i = offsets; i != end; ++i, ++n) {
- if (memrar_get_rar_addr (pdev,
- (*i).low,
- &(rar_addr[n].low)) != 0
- || memrar_get_rar_addr (pdev,
- (*i).high,
- &(rar_addr[n].high)) != 0) {
- result = -1;
- break;
- }
- }
-
- /* Done accessing the device. */
- /* pci_dev_put(pdev); */
-
- if (result == 0) {
- if(1) {
- size_t z;
- for (z = 0; z != MRST_NUM_RAR; ++z) {
- printk(KERN_WARNING "rar - BRAR[%Zd] physical address low\n"
- "\tlow: 0x%08x\n"
- "\thigh: 0x%08x\n",
- z,
- rar_addr[z].low,
- rar_addr[z].high);
- }
- }
- }
-
- return result;
-}
-
-/*
- function that is activated on the successfull probe of the RAR device
-*/
-static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- /* error */
- int error;
-
- /*------------------------
- CODE
- ---------------------------*/
-
- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
- "Rar pci probe starting\n");
- error = 0;
-
- /* enable the device */
- error = pci_enable_device(pdev);
- if (error) {
- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
- "error enabling pci device\n");
- goto end_function;
- }
-
- rar_dev = pdev;
- registered = 1;
-
- /* Initialize the RAR parameters, which have to be retrieved */
- /* via the message bus service */
- error=memrar_init_rar_params(rar_dev);
-
- if (error) {
- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
- "error getting RAR addresses device\n");
- registered = 0;
- goto end_function;
- }
-
-end_function:
-
- return error;
-}
-
-/*
- this function registers th driver to
- the device subsystem( either PCI, USB, etc)
-*/
-static int __init rar_init_handler(void)
-{
- return pci_register_driver(&rar_pci_driver);
-}
-
-static void __exit rar_exit_handler(void)
-{
- pci_unregister_driver(&rar_pci_driver);
-}
-
-module_init(rar_init_handler);
-module_exit(rar_exit_handler);
-
-MODULE_LICENSE("GPL");
-
-
-/* The get_rar_address function is used by other device drivers
- * to obtain RAR address information on a RAR. It takes two
- * parameter:
- *
- * int rar_index
- * The rar_index is an index to the rar for which you wish to retrieve
- * the address information.
- * Values can be 0,1, or 2.
- *
- * struct RAR_address_struct is a pointer to a place to which the function
- * can return the address structure for the RAR.
- *
- * The function returns a 0 upon success or a -1 if there is no RAR
- * facility on this system.
- */
-int get_rar_address(int rar_index,struct RAR_address_struct *addresses)
-{
- if (registered && (rar_index < 3) && (rar_index >= 0)) {
- *addresses=rar_addr[rar_index];
- /* strip off lock bit information */
- addresses->low = addresses->low & 0xfffffff0;
- addresses->high = addresses->high & 0xfffffff0;
- return 0;
- }
-
- else {
- return -ENODEV;
- }
-}
-
-
-EXPORT_SYMBOL(get_rar_address);
-
-/* The lock_rar function is ued by other device drivers to lock an RAR.
- * once an RAR is locked, it stays locked until the next system reboot.
- * The function takes one parameter:
- *
- * int rar_index
- * The rar_index is an index to the rar that you want to lock.
- * Values can be 0,1, or 2.
- *
- * The function returns a 0 upon success or a -1 if there is no RAR
- * facility on this system.
- */
-int lock_rar(int rar_index)
-{
- u32 working_addr;
- int result;
-if (registered && (rar_index < 3) && (rar_index >= 0)) {
- /* first make sure that lock bits are clear (this does lock) */
- working_addr=rar_addr[rar_index].low & 0xfffffff0;
-
- /* now send that value to the register using the IPC */
- result=memrar_set_rar_addr(rar_dev,rar_index,working_addr);
- return result;
- }
-
-else {
- return -ENODEV;
- }
-}
diff --git a/drivers/staging/rar/rar_driver.h b/drivers/staging/rar/rar_driver.h
deleted file mode 100644
index 3690f984ff5..00000000000
--- a/drivers/staging/rar/rar_driver.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* === RAR Physical Addresses === */
-struct RAR_address_struct {
- u32 low;
- u32 high;
-};
-
-/* The get_rar_address function is used by other device drivers
- * to obtain RAR address information on a RAR. It takes two
- * parameter:
- *
- * int rar_index
- * The rar_index is an index to the rar for which you wish to retrieve
- * the address information.
- * Values can be 0,1, or 2.
- *
- * struct RAR_address_struct is a pointer to a place to which the function
- * can return the address structure for the RAR.
- *
- * The function returns a 0 upon success or a -1 if there is no RAR
- * facility on this system.
- */
-int get_rar_address(int rar_index,struct RAR_address_struct *addresses);
-
-
-/* The lock_rar function is ued by other device drivers to lock an RAR.
- * once an RAR is locked, it stays locked until the next system reboot.
- * The function takes one parameter:
- *
- * int rar_index
- * The rar_index is an index to the rar that you want to lock.
- * Values can be 0,1, or 2.
- *
- * The function returns a 0 upon success or a -1 if there is no RAR
- * facility on this system.
- */
-int lock_rar(int rar_index);
-
-
-/* DEBUG LEVEL MASKS */
-#define RAR_DEBUG_LEVEL_BASIC 0x1
-
-#define RAR_DEBUG_LEVEL_REGISTERS 0x2
-
-#define RAR_DEBUG_LEVEL_EXTENDED 0x4
-
-#define DEBUG_LEVEL 0x7
-
-/* FUNCTIONAL MACROS */
-
-/* debug macro without paramaters */
-#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \
-do \
-{ \
- if(DEBUG_LEVEL) \
- { \
- printk(KERN_WARNING info); \
- } \
-}while(0)
-
-/* debug macro with 1 paramater */
-#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \
-do \
-{ \
- if(DEBUG_LEVEL) \
- { \
- printk(KERN_WARNING info , param1); \
- } \
-}while(0)
-
-/* debug macro with 2 paramaters */
-#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \
-do \
-{ \
- if(DEBUG_LEVEL) \
- { \
- printk(KERN_WARNING info , param1, param2); \
- } \
-}while(0)
-
-/* debug macro with 3 paramaters */
-#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \
-do \
-{ \
- if(DEBUG_LEVEL) \
- { \
- printk(KERN_WARNING info , param1, param2 , param3); \
- } \
-}while(0)
-
-/* debug macro with 4 paramaters */
-#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \
-do \
-{ \
- if(DEBUG_LEVEL) \
- { \
- printk(KERN_WARNING info , param1, param2 , param3 , param4); \
- } \
-}while(0)
-
diff --git a/drivers/staging/rar_register/Kconfig b/drivers/staging/rar_register/Kconfig
new file mode 100644
index 00000000000..3f73839643e
--- /dev/null
+++ b/drivers/staging/rar_register/Kconfig
@@ -0,0 +1,30 @@
+#
+# RAR device configuration
+#
+
+menu "RAR Register Driver"
+#
+# Restricted Access Register Manager
+#
+config RAR_REGISTER
+ tristate "Restricted Access Region Register Driver"
+ default n
+ ---help---
+ This driver allows other kernel drivers access to the
+ contents of the restricted access region control
+ registers.
+
+ The restricted access region control registers
+ (rar_registers) are used to pass address and
+ locking information on restricted access regions
+ to other drivers that use restricted access regions
+
+ The restricted access regions are regions of memory
+ on the Intel MID Platform that are not accessible to
+ the x86 processor, but are accessible to dedicated
+ processors on board peripheral devices.
+
+ The purpose of the restricted access regions is to
+ protect sensitive data from compromise by unauthorized
+ programs running on the x86 processor.
+endmenu
diff --git a/drivers/staging/rar_register/Makefile b/drivers/staging/rar_register/Makefile
new file mode 100644
index 00000000000..d5954ccc16c
--- /dev/null
+++ b/drivers/staging/rar_register/Makefile
@@ -0,0 +1,2 @@
+EXTRA_CFLAGS += -DLITTLE__ENDIAN
+obj-$(CONFIG_RAR_REGISTER) += rar_register.o
diff --git a/drivers/staging/rar_register/rar_register.c b/drivers/staging/rar_register/rar_register.c
new file mode 100644
index 00000000000..bfc0e31f1a6
--- /dev/null
+++ b/drivers/staging/rar_register/rar_register.c
@@ -0,0 +1,615 @@
+/*
+ * rar_register.c - An Intel Restricted Access Region register driver
+ *
+ * Copyright(c) 2009 Intel 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; 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.
+ *
+ * -------------------------------------------------------------------
+ * 20091204 Mark Allyn <mark.a.allyn@intel.com>
+ * Ossama Othman <ossama.othman@intel.com>
+ * Cleanup per feedback from Alan Cox and Arjan Van De Ven
+ *
+ * 20090806 Ossama Othman <ossama.othman@intel.com>
+ * Return zero high address if upper 22 bits is zero.
+ * Cleaned up checkpatch errors.
+ * Clarified that driver is dealing with bus addresses.
+ *
+ * 20090702 Ossama Othman <ossama.othman@intel.com>
+ * Removed unnecessary include directives
+ * Cleaned up spinlocks.
+ * Cleaned up logging.
+ * Improved invalid parameter checks.
+ * Fixed and simplified RAR address retrieval and RAR locking
+ * code.
+ *
+ * 20090626 Mark Allyn <mark.a.allyn@intel.com>
+ * Initial publish
+ */
+
+#define DEBUG 1
+
+#include "rar_register.h"
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+/* === Lincroft Message Bus Interface === */
+/* Message Control Register */
+#define LNC_MCR_OFFSET 0xD0
+
+/* Maximum number of clients (other drivers using this driver) */
+#define MAX_RAR_CLIENTS 10
+
+/* Message Data Register */
+#define LNC_MDR_OFFSET 0xD4
+
+/* Message Opcodes */
+#define LNC_MESSAGE_READ_OPCODE 0xD0
+#define LNC_MESSAGE_WRITE_OPCODE 0xE0
+
+/* Message Write Byte Enables */
+#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
+
+/* B-unit Port */
+#define LNC_BUNIT_PORT 0x3
+
+/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
+#define LNC_BRAR0L 0x10
+#define LNC_BRAR0H 0x11
+#define LNC_BRAR1L 0x12
+#define LNC_BRAR1H 0x13
+
+/* Reserved for SeP */
+#define LNC_BRAR2L 0x14
+#define LNC_BRAR2H 0x15
+
+/* Moorestown supports three restricted access regions. */
+#define MRST_NUM_RAR 3
+
+
+/* RAR Bus Address Range */
+struct RAR_address_range {
+ dma_addr_t low;
+ dma_addr_t high;
+};
+
+/* Structure containing low and high RAR register offsets. */
+struct RAR_offsets {
+ u32 low; /* Register offset for low RAR bus address. */
+ u32 high; /* Register offset for high RAR bus address. */
+};
+
+struct client {
+ int (*client_callback)(void *client_data);
+ void *customer_data;
+ int client_called;
+ };
+
+static DEFINE_MUTEX(rar_mutex);
+static DEFINE_MUTEX(lnc_reg_mutex);
+
+struct RAR_device {
+ struct RAR_offsets const rar_offsets[MRST_NUM_RAR];
+ struct RAR_address_range rar_addr[MRST_NUM_RAR];
+ struct pci_dev *rar_dev;
+ bool registered;
+ };
+
+/* this platform has only one rar_device for 3 rar regions */
+static struct RAR_device my_rar_device = {
+ .rar_offsets = {
+ [0].low = LNC_BRAR0L,
+ [0].high = LNC_BRAR0H,
+ [1].low = LNC_BRAR1L,
+ [1].high = LNC_BRAR1H,
+ [2].low = LNC_BRAR2L,
+ [2].high = LNC_BRAR2H
+ }
+};
+
+/* this data is for handling requests from other drivers which arrive
+ * prior to this driver initializing
+ */
+
+static struct client clients[MAX_RAR_CLIENTS];
+static int num_clients;
+
+/*
+ * This function is used to retrieved RAR info using the Lincroft
+ * message bus interface.
+ */
+static int retrieve_rar_addr(struct pci_dev *pdev,
+ int offset,
+ dma_addr_t *addr)
+{
+ /*
+ * ======== The Lincroft Message Bus Interface ========
+ * Lincroft registers may be obtained from the PCI
+ * (the Host Bridge) using the Lincroft Message Bus
+ * Interface. That message bus interface is generally
+ * comprised of two registers: a control register (MCR, 0xDO)
+ * and a data register (MDR, 0xD4).
+ *
+ * The MCR (message control register) format is the following:
+ * 1. [31:24]: Opcode
+ * 2. [23:16]: Port
+ * 3. [15:8]: Register Offset
+ * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
+ * to 1)
+ * 5. [3:0]: reserved
+ *
+ * Read (0xD0) and write (0xE0) opcodes are written to the
+ * control register when reading and writing to Lincroft
+ * registers, respectively.
+ *
+ * We're interested in registers found in the Lincroft
+ * B-unit. The B-unit port is 0x3.
+ *
+ * The six B-unit RAR register offsets we use are listed
+ * earlier in this file.
+ *
+ * Lastly writing to the MCR register requires the "Byte
+ * enables" bits to be set to 1. This may be achieved by
+ * writing 0xF at bit 4.
+ *
+ * The MDR (message data register) format is the following:
+ * 1. [31:0]: Read/Write Data
+ *
+ * Data being read from this register is only available after
+ * writing the appropriate control message to the MCR
+ * register.
+ *
+ * Data being written to this register must be written before
+ * writing the appropriate control message to the MCR
+ * register.
+ */
+
+ int result;
+
+ /* Construct control message */
+ u32 const message =
+ (LNC_MESSAGE_READ_OPCODE << 24)
+ | (LNC_BUNIT_PORT << 16)
+ | (offset << 8)
+ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
+
+ dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset);
+
+ if (addr == 0) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ /*
+ * We synchronize access to the Lincroft MCR and MDR registers
+ * until BOTH the command is issued through the MCR register
+ * and the corresponding data is read from the MDR register.
+ * Otherwise a race condition would exist between accesses to
+ * both registers.
+ */
+
+ mutex_lock(&lnc_reg_mutex);
+
+ /* Send the control message */
+ result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
+
+ dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", result);
+
+ if (!result) {
+ result = pci_read_config_dword(pdev, LNC_MDR_OFFSET,
+ (u32 *)addr);
+ dev_dbg(&pdev->dev,
+ "Result from read data register is %x\n", result);
+
+ dev_dbg(&pdev->dev,
+ "Value read from data register is %lx\n",
+ (unsigned long)*addr);
+ }
+
+ mutex_unlock(&lnc_reg_mutex);
+
+ return result;
+}
+
+static int set_rar_address(struct pci_dev *pdev,
+ int offset,
+ dma_addr_t addr)
+{
+ /*
+ * Data being written to this register must be written before
+ * writing the appropriate control message to the MCR
+ * register.
+ * @note See rar_get_address() for a description of the
+ * message bus interface being used here.
+ */
+
+ int result = 0;
+
+ /* Construct control message */
+ u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24)
+ | (LNC_BUNIT_PORT << 16)
+ | (offset << 8)
+ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
+
+ if (addr == 0) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ dev_dbg(&pdev->dev, "Offset for 'set' LNC MSG is %x\n", offset);
+
+ /*
+ * We synchronize access to the Lincroft MCR and MDR registers
+ * until BOTH the command is issued through the MCR register
+ * and the corresponding data is read from the MDR register.
+ * Otherwise a race condition would exist between accesses to
+ * both registers.
+ */
+
+ mutex_lock(&lnc_reg_mutex);
+
+ /* Send the control message */
+ result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr);
+
+ dev_dbg(&pdev->dev, "Result from write data register is %x\n", result);
+
+ if (!result) {
+ dev_dbg(&pdev->dev,
+ "Value written to data register is %lx\n",
+ (unsigned long)addr);
+
+ result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
+
+ dev_dbg(&pdev->dev, "Result from send ctl register is %x\n",
+ result);
+ }
+
+ mutex_unlock(&lnc_reg_mutex);
+
+ return result;
+}
+
+/*
+* Initialize RAR parameters, such as bus addresses, etc.
+*/
+static int init_rar_params(struct pci_dev *pdev)
+{
+ unsigned int i;
+ int result = 0;
+
+ /* Retrieve RAR start and end bus addresses.
+ * Access the RAR registers through the Lincroft Message Bus
+ * Interface on PCI device: 00:00.0 Host bridge.
+ */
+
+ for (i = 0; i < MRST_NUM_RAR; ++i) {
+ struct RAR_offsets const *offset =
+ &my_rar_device.rar_offsets[i];
+ struct RAR_address_range *addr = &my_rar_device.rar_addr[i];
+
+ if ((retrieve_rar_addr(pdev, offset->low, &addr->low) != 0)
+ || (retrieve_rar_addr(pdev, offset->high, &addr->high) != 0)) {
+ result = -1;
+ break;
+ }
+
+ /*
+ * Only the upper 22 bits of the RAR addresses are
+ * stored in their corresponding RAR registers so we
+ * must set the lower 10 bits accordingly.
+
+ * The low address has its lower 10 bits cleared, and
+ * the high address has all its lower 10 bits set,
+ * e.g.:
+ * low = 0x2ffffc00
+ */
+
+ addr->low &= (dma_addr_t)0xfffffc00u;
+
+ /*
+ * Set bits 9:0 on uppser address if bits 31:10 are non
+ * zero; otherwize clear all bits
+ */
+
+ if ((addr->high & 0xfffffc00u) == 0)
+ addr->high = 0;
+ else
+ addr->high |= 0x3ffu;
+ }
+ /* Done accessing the device. */
+
+ if (result == 0) {
+ int z;
+ for (z = 0; z != MRST_NUM_RAR; ++z) {
+ /*
+ * "BRAR" refers to the RAR registers in the
+ * Lincroft B-unit.
+ */
+ dev_info(&pdev->dev, "BRAR[%u] bus address range = "
+ "[%lx, %lx]\n", z,
+ (unsigned long)my_rar_device.rar_addr[z].low,
+ (unsigned long)my_rar_device.rar_addr[z].high);
+ }
+ }
+
+ return result;
+}
+
+/*
+ * The rar_get_address function is used by other device drivers
+ * to obtain RAR address information on a RAR. It takes three
+ * parameters:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar for which you wish to retrieve
+ * the address information.
+ * Values can be 0,1, or 2.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int rar_get_address(int rar_index,
+ dma_addr_t *start_address,
+ dma_addr_t *end_address)
+{
+ int result = -ENODEV;
+
+ if (my_rar_device.registered) {
+ if (start_address == 0 || end_address == 0
+ || rar_index >= MRST_NUM_RAR || rar_index < 0) {
+ result = -EINVAL;
+ } else {
+ *start_address =
+ my_rar_device.rar_addr[rar_index].low;
+ *end_address =
+ my_rar_device.rar_addr[rar_index].high;
+
+ result = 0;
+ }
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(rar_get_address);
+
+/*
+ * The rar_lock function is ued by other device drivers to lock an RAR.
+ * once an RAR is locked, it stays locked until the next system reboot.
+ * The function takes one parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar that you want to lock.
+ * Values can be 0,1, or 2.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int rar_lock(int rar_index)
+{
+ int result = -ENODEV;
+
+ if (rar_index >= MRST_NUM_RAR || rar_index < 0) {
+ result = -EINVAL;
+ return result;
+ }
+
+ dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex locking\n");
+ mutex_lock(&rar_mutex);
+
+ if (my_rar_device.registered) {
+
+ dma_addr_t low = my_rar_device.rar_addr[rar_index].low &
+ 0xfffffc00u;
+
+ dma_addr_t high = my_rar_device.rar_addr[rar_index].high &
+ 0xfffffc00u;
+
+ /*
+ * Only allow I/O from the graphics and Langwell;
+ * Not from the x96 processor
+ */
+ if (rar_index == (int)RAR_TYPE_VIDEO) {
+ low |= 0x00000009;
+ high |= 0x00000015;
+ }
+
+ else if (rar_index == (int)RAR_TYPE_AUDIO) {
+ /* Only allow I/O from Langwell; nothing from x86 */
+ low |= 0x00000008;
+ high |= 0x00000018;
+ }
+
+ else
+ /* Read-only from all agents */
+ high |= 0x00000018;
+
+ /*
+ * Now program the register using the Lincroft message
+ * bus interface.
+ */
+ result = set_rar_address(my_rar_device.rar_dev,
+ my_rar_device.rar_offsets[rar_index].low,
+ low);
+
+ if (result == 0)
+ result = set_rar_address(
+ my_rar_device.rar_dev,
+ my_rar_device.rar_offsets[rar_index].high,
+ high);
+ }
+
+ dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex unlocking\n");
+ mutex_unlock(&rar_mutex);
+ return result;
+}
+EXPORT_SYMBOL(rar_lock);
+
+/* The register_rar function is to used by other device drivers
+ * to ensure that this driver is ready. As we cannot be sure of
+ * the compile/execute order of dirvers in ther kernel, it is
+ * best to give this driver a callback function to call when
+ * it is ready to give out addresses. The callback function
+ * would have those steps that continue the initialization of
+ * a driver that do require a valid RAR address. One of those
+ * steps would be to call rar_get_address()
+ * This function return 0 on success an -1 on failure.
+*/
+int register_rar(int (*callback)(void *yourparameter), void *yourparameter)
+{
+
+ int result = -ENODEV;
+
+ if (callback == NULL)
+ return -EINVAL;
+
+ mutex_lock(&rar_mutex);
+
+ if (my_rar_device.registered) {
+
+ mutex_unlock(&rar_mutex);
+ /*
+ * if the driver already registered, then we can simply
+ * call the callback right now
+ */
+
+ return (*callback)(yourparameter);
+ }
+
+ if (num_clients < MRST_NUM_RAR) {
+
+ clients[num_clients].client_callback = callback;
+ clients[num_clients].customer_data = yourparameter;
+ num_clients += 1;
+ result = 0;
+ }
+
+ mutex_unlock(&rar_mutex);
+ return result;
+
+}
+EXPORT_SYMBOL(register_rar);
+
+/* Suspend - returns -ENOSYS */
+static int rar_suspend(struct pci_dev *dev, pm_message_t state)
+{
+ return -ENOSYS;
+}
+
+static int rar_resume(struct pci_dev *dev)
+{
+ return -ENOSYS;
+}
+
+/*
+ * This function registers the driver with the device subsystem (
+ * either PCI, USB, etc).
+ * Function that is activaed on the succesful probe of the RAR device
+ * (Moorestown host controller).
+ */
+static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ int error;
+ int counter;
+
+ dev_dbg(&dev->dev, "PCI probe starting\n");
+
+ /* enable the device */
+ error = pci_enable_device(dev);
+ if (error) {
+ dev_err(&dev->dev,
+ "Error enabling RAR register PCI device\n");
+ goto end_function;
+ }
+
+ /* we have only one device; fill in the rar_device structure */
+ my_rar_device.rar_dev = dev;
+
+ /*
+ * Initialize the RAR parameters, which have to be retrieved
+ * via the message bus interface.
+ */
+ error = init_rar_params(dev);
+ if (error) {
+ pci_disable_device(dev);
+
+ dev_err(&dev->dev,
+ "Error retrieving RAR addresses\n");
+
+ goto end_function;
+ }
+
+ dev_dbg(&dev->dev, "PCI probe locking\n");
+ mutex_lock(&rar_mutex);
+ my_rar_device.registered = 1;
+
+ /* now call anyone who has registered (using callbacks) */
+ for (counter = 0; counter < num_clients; counter += 1) {
+ if (clients[counter].client_callback) {
+ error = (*clients[counter].client_callback)(
+ clients[counter].customer_data);
+ /* set callback to NULL to indicate it has been done */
+ clients[counter].client_callback = NULL;
+ dev_dbg(&my_rar_device.rar_dev->dev,
+ "Callback called for %d\n",
+ counter);
+ }
+ }
+
+ dev_dbg(&dev->dev, "PCI probe unlocking\n");
+ mutex_unlock(&rar_mutex);
+
+end_function:
+
+ return error;
+}
+
+const struct pci_device_id rar_pci_id_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_RAR_DEVICE_ID) },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
+
+const struct pci_device_id *my_id_table = rar_pci_id_tbl;
+
+/* field for registering driver to PCI device */
+static struct pci_driver rar_pci_driver = {
+ .name = "rar_register_driver",
+ .id_table = rar_pci_id_tbl,
+ .probe = rar_probe,
+ .suspend = rar_suspend,
+ .resume = rar_resume
+};
+
+static int __init rar_init_handler(void)
+{
+ return pci_register_driver(&rar_pci_driver);
+}
+
+static void __exit rar_exit_handler(void)
+{
+ pci_unregister_driver(&rar_pci_driver);
+}
+
+module_init(rar_init_handler);
+module_exit(rar_exit_handler);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver");
diff --git a/drivers/staging/rar_register/rar_register.h b/drivers/staging/rar_register/rar_register.h
new file mode 100644
index 00000000000..29ade0f361d
--- /dev/null
+++ b/drivers/staging/rar_register/rar_register.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
+ *
+ * This program 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.
+ *
+ * This program is distributed in 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.
+ * The full GNU General Public License is included in this
+ * distribution in the file called COPYING.
+ */
+
+
+#ifndef _RAR_REGISTER_H
+#define _RAR_REGISTER_H
+
+# include <linux/types.h>
+
+/* following are used both in drivers as well as user space apps */
+enum RAR_type {
+ RAR_TYPE_VIDEO = 0,
+ RAR_TYPE_AUDIO,
+ RAR_TYPE_IMAGE,
+ RAR_TYPE_DATA
+};
+
+#ifdef __KERNEL__
+
+/* PCI device id for controller */
+#define PCI_RAR_DEVICE_ID 0x4110
+
+/* The register_rar function is to used by other device drivers
+ * to ensure that this driver is ready. As we cannot be sure of
+ * the compile/execute order of dirvers in ther kernel, it is
+ * best to give this driver a callback function to call when
+ * it is ready to give out addresses. The callback function
+ * would have those steps that continue the initialization of
+ * a driver that do require a valid RAR address. One of those
+ * steps would be to call get_rar_address()
+ * This function return 0 on success an -1 on failure.
+ */
+int register_rar(int (*callback)(void *yourparameter), void *yourparameter);
+
+/* The get_rar_address function is used by other device drivers
+ * to obtain RAR address information on a RAR. It takes two
+ * parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar for which you wish to retrieve
+ * the address information.
+ * Values can be 0,1, or 2.
+ *
+ * struct RAR_address_struct is a pointer to a place to which the function
+ * can return the address structure for the RAR.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int rar_get_address(int rar_index,
+ dma_addr_t *start_address,
+ dma_addr_t *end_address);
+
+/* The lock_rar function is ued by other device drivers to lock an RAR.
+ * once an RAR is locked, it stays locked until the next system reboot.
+ * The function takes one parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar that you want to lock.
+ * Values can be 0,1, or 2.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int rar_lock(int rar_index);
+
+#endif /* __KERNEL__ */
+#endif /* _RAR_REGISTER_H */
diff --git a/drivers/staging/rt2860/Kconfig b/drivers/staging/rt2860/Kconfig
index f9962b69312..f3a7e47df5e 100644
--- a/drivers/staging/rt2860/Kconfig
+++ b/drivers/staging/rt2860/Kconfig
@@ -3,6 +3,8 @@ config RT2860
depends on PCI && X86 && WLAN
select WIRELESS_EXT
select WEXT_PRIV
+ select CRC_CCITT
+ select FW_LOADER
---help---
This is an experimental driver for the Ralink 2860 and 3090
wireless chips.
diff --git a/drivers/staging/rt2860/common/firmware.h b/drivers/staging/rt2860/common/firmware.h
deleted file mode 100644
index 2fecd32f760..00000000000
--- a/drivers/staging/rt2860/common/firmware.h
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- Copyright (c) 2007, Ralink Technology Corporation
- All rights reserved.
-
- Redistribution. Redistribution and use in binary form, without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions must reproduce the above copyright notice and the
- following disclaimer in the documentation and/or other materials
- provided with the distribution.
- * Neither the name of Ralink Technology Corporation nor the names of its
- suppliers may be used to endorse or promote products derived from this
- software without specific prior written permission.
- * No reverse engineering, decompilation, or disassembly of this software
- is permitted.
-
- Limited patent license. Ralink Technology Corporation grants a world-wide,
- royalty-free, non-exclusive license under patents it now or hereafter
- owns or controls to make, have made, use, import, offer to sell and
- sell ("Utilize") this software, but solely to the extent that any
- such patent is necessary to Utilize the software alone, or in
- combination with an operating system licensed under an approved Open
- Source license as listed by the Open Source Initiative at
- http://opensource.org/licenses. The patent license shall not apply to
- any other combinations which include this software. No hardware per
- se is licensed hereunder.
-
- DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- 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.
-*/
-/* AUTO GEN PLEASE DO NOT MODIFY IT */
-/* AUTO GEN PLEASE DO NOT MODIFY IT */
-
-
-u8 FirmwareImage_2860 [] = {
-0x02, 0x03, 0x5e, 0x02, 0x02, 0xb1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x82, 0xff, 0xff,
-0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x33, 0xc0, 0xe0,
-0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
-0x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14,
-0xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x2f,
-0x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14,
-0x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24,
-0x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5,
-0x50, 0x85, 0x2f, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55,
-0x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x2f, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf,
-0x2f, 0x12, 0x02, 0x8d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0,
-0xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf,
-0x2f, 0x12, 0x02, 0x8d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
-0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x53, 0xc2,
-0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d,
-0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x30, 0x90,
-0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10,
-0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a,
-0x0d, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x02, 0x2c, 0x74, 0xff, 0xf0, 0xc2, 0x05,
-0xd2, 0xaf, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0xe8, 0xc0, 0xe0,
-0xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0, 0xe0, 0xed, 0xc0, 0xe0, 0xee,
-0xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x12, 0xd2, 0xaf, 0xd0,
-0xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc, 0xd0, 0xe0, 0xfb, 0xd0, 0xe0,
-0xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0,
-0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0xc2,
-0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5, 0x54, 0x60, 0x04, 0x15, 0x54,
-0x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04, 0x15, 0x50, 0x80, 0x02, 0xc2,
-0x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04, 0x30, 0x45, 0x03, 0x12, 0x10,
-0x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32,
-0x12, 0x02, 0xd3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12,
-0x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b,
-0x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09,
-0x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12,
-0x02, 0xec, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5,
-0x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18,
-0x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x19, 0xc2, 0x18, 0xc2, 0x1a, 0x22,
-0xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16,
-0x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8,
-0xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12,
-0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83,
-0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60,
-0x1f, 0xe4, 0xfe, 0x12, 0x03, 0x6a, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x6a, 0xef, 0xf0, 0x74,
-0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3,
-0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf,
-0x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0,
-0xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x14, 0x12, 0x03, 0x1c, 0xe4, 0xf5,
-0x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x30, 0x45, 0x03, 0x12,
-0x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22,
-0xc0, 0x2a, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x2a, 0x0a, 0x22, 0xc0, 0x2a,
-0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x2a, 0x18, 0x22, 0x75, 0x89, 0x02, 0xe4,
-0xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75,
-0xa8, 0x05, 0x22, 0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x80, 0x1e, 0x80,
-0xf5, 0x22, 0xc8, 0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22,
-0xc8, 0xef, 0xc8, 0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x78, 0x7f,
-0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xd0, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4,
-0x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x7e, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a, 0x18,
-0xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x12, 0xb8, 0x02,
-0x12, 0xb9, 0x02, 0x13, 0x3e, 0x02, 0x13, 0x3f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x16, 0x56, 0x02,
-0x17, 0x6b, 0x02, 0x14, 0x2a, 0x02, 0x13, 0x40, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x00,
-0xd8, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x18, 0x5e, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0,
-0x20, 0xe7, 0x03, 0x02, 0x12, 0xb7, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0,
-0x12, 0x02, 0x67, 0x11, 0x4e, 0x30, 0x11, 0x25, 0x31, 0x10, 0x87, 0x33, 0x10, 0xaa, 0x34, 0x10,
-0xc3, 0x35, 0x11, 0x57, 0x50, 0x11, 0x7b, 0x51, 0x11, 0x84, 0x52, 0x11, 0x84, 0x53, 0x11, 0x84,
-0x54, 0x11, 0xc5, 0x55, 0x11, 0xdc, 0x70, 0x12, 0x07, 0x71, 0x12, 0x34, 0x72, 0x12, 0x5e, 0x80,
-0x12, 0x81, 0x83, 0x00, 0x00, 0x12, 0xb7, 0x75, 0x24, 0x05, 0x75, 0x25, 0xdc, 0x90, 0x70, 0x9f,
-0x74, 0x12, 0xf0, 0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x0d, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
-0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0,
-0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0xb7,
-0x02, 0x12, 0xaa, 0xe5, 0x55, 0x64, 0x02, 0x70, 0x37, 0x90, 0x70, 0x10, 0xe0, 0x60, 0x08, 0x90,
-0x01, 0x0d, 0x74, 0x09, 0xf0, 0x80, 0x25, 0xe5, 0x34, 0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14,
-0x60, 0x14, 0x24, 0x03, 0x70, 0x16, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x80, 0x0e, 0x90, 0x01,
-0x0d, 0x74, 0x0b, 0xf0, 0x80, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x1b, 0xf0, 0x7d, 0x01, 0x80, 0x02,
-0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x1b, 0x90,
-0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
-0x12, 0xb7, 0x02, 0x12, 0xaa, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, 0x56, 0x12,
-0x02, 0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4,
-0x70, 0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, 0x90, 0x70,
-0x11, 0xe0, 0x24, 0xff, 0x92, 0x1b, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60,
-0x03, 0x02, 0x12, 0xb7, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60,
-0x03, 0x02, 0x12, 0xb7, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24,
-0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70,
-0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff,
-0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
-0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
-0x12, 0xb7, 0x02, 0x12, 0xaa, 0xe5, 0x47, 0xb4, 0x07, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x07,
-0xf5, 0x26, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0xd2, 0x04, 0x22, 0x90, 0x70, 0x10, 0xe0,
-0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02,
-0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
-0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0,
-0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
-0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
-0x12, 0xb7, 0x80, 0x76, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x26, 0xff, 0xc2, 0x19, 0xc2, 0x18,
-0xc2, 0x1a, 0x75, 0x34, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x04, 0x14, 0x74,
-0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x5b, 0x80, 0x4c, 0x90, 0x70,
-0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
-0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x38, 0x80,
-0x29, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x34, 0xd3, 0x94, 0x00, 0x40, 0x07, 0x90, 0x01, 0x0d, 0xe0,
-0x54, 0xfb, 0xf0, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
-0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x0d, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01,
-0xf0, 0x90, 0x02, 0x2c, 0x74, 0xff, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x13, 0x3d,
-0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0xa2, 0x19,
-0xe4, 0x33, 0x90, 0x70, 0x90, 0xf0, 0xa2, 0x18, 0xe4, 0x33, 0xa3, 0xf0, 0x30, 0x19, 0x4d, 0x90,
-0x70, 0x98, 0x74, 0x23, 0xf0, 0xa3, 0xe5, 0x25, 0xf0, 0xe5, 0x24, 0xa3, 0xf0, 0x7f, 0x35, 0x7d,
-0x32, 0x12, 0x03, 0x42, 0x50, 0x09, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5,
-0x35, 0xd3, 0x94, 0x10, 0x40, 0x1e, 0x30, 0x1a, 0x1b, 0xc2, 0x1a, 0xa2, 0x18, 0x92, 0x19, 0x20,
-0x19, 0x12, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0,
-0xc2, 0x61, 0xd2, 0x03, 0xe5, 0x35, 0xb4, 0x0b, 0x14, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2,
-0x18, 0x92, 0x19, 0x30, 0x19, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22,
-0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x67, 0x13, 0x62, 0x00, 0x13, 0xf5, 0x04, 0x13,
-0xf1, 0x08, 0x13, 0xcc, 0x10, 0x13, 0x76, 0x20, 0x13, 0x96, 0x60, 0x13, 0xa7, 0xa0, 0x00, 0x00,
-0x13, 0xf7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60,
-0x03, 0x02, 0x13, 0xf7, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4,
-0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70,
-0x66, 0x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5,
-0x47, 0x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b,
-0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06,
-0x70, 0x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04,
-0x06, 0x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75,
-0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80,
-0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x38, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff,
-0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3,
-0xe5, 0x4a, 0xf0, 0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3,
-0xe5, 0x42, 0xf0, 0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0,
-0x70, 0x03, 0x12, 0x16, 0x36, 0x12, 0x14, 0x3f, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
-0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45,
-0x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74,
-0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x38, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5,
-0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
-0x38, 0x70, 0x05, 0x75, 0x38, 0x0c, 0x80, 0x02, 0x15, 0x38, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
-0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
-0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x38,
-0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x38, 0x70, 0x05, 0x75, 0x38, 0x07, 0x80, 0x02,
-0x15, 0x38, 0xd2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5, 0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5,
-0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a,
-0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0,
-0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x15, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2,
-0xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
-0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x15, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2,
-0xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
-0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x15, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2,
-0xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
-0x71, 0x92, 0x70, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x46, 0x90,
-0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe,
-0x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x35, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0d,
-0x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22, 0x44, 0x01, 0xf0,
-0x22, 0xe5, 0x46, 0x30, 0xe3, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02, 0x28, 0xe0,
-0x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x03, 0x02, 0x16, 0x35, 0xf5, 0x27,
-0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x26, 0x14, 0x60, 0x26, 0x14, 0x60, 0x2e, 0x14,
-0x60, 0x36, 0x24, 0x03, 0x70, 0x5f, 0xe5, 0x46, 0x13, 0x13, 0x13, 0x54, 0x1f, 0x75, 0xf0, 0x03,
-0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff,
-0x80, 0x02, 0xa2, 0x47, 0x92, 0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x3f, 0xe5, 0x46, 0x30,
-0xe3, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe3, 0x0d, 0x54, 0x70, 0xc3,
-0x94, 0x60, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47,
-0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47,
-0xb3, 0x92, 0x39, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02, 0x28, 0xe0,
-0x54, 0xfc, 0x45, 0x27, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45,
-0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59,
-0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x30, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a,
-0x14, 0x60, 0x6a, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x4c, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20,
-0x19, 0x1c, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34,
-0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20,
-0x12, 0x16, 0x4c, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x17, 0x4c,
-0xe5, 0x50, 0x70, 0x06, 0x75, 0x30, 0x03, 0x02, 0x17, 0x4c, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03,
-0x70, 0x15, 0x7f, 0x20, 0x12, 0x16, 0x4c, 0x20, 0x19, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb,
-0xf0, 0x75, 0x51, 0x02, 0x02, 0x17, 0x4c, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x7a, 0x20, 0x19, 0x0f,
-0x90, 0x02, 0x08, 0xe0, 0x20, 0xe3, 0x6c, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x64, 0x90,
-0x12, 0x04, 0x74, 0x0a, 0xf0, 0x30, 0x1b, 0x11, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3,
-0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x20, 0x19, 0x07, 0x90, 0x04, 0x01, 0xe0,
-0x44, 0x10, 0xf0, 0xe5, 0x34, 0xf4, 0x90, 0x04, 0x01, 0x60, 0x06, 0xe0, 0x54, 0xfb, 0xf0, 0x80,
-0x04, 0xe0, 0x54, 0xf9, 0xf0, 0x20, 0x19, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5,
-0x34, 0xf4, 0x60, 0x14, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x33, 0xe5, 0x34, 0xd3, 0x94, 0x02, 0x40,
-0x07, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x30, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5,
-0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x30, 0x03, 0xf5, 0x51, 0xe5, 0x30, 0x60, 0x18,
-0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x19, 0x0e, 0xad, 0x30, 0xaf, 0x40, 0x12, 0x18,
-0x2a, 0xe5, 0x30, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e,
-0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x18, 0x2a, 0xe5, 0x52,
-0x14, 0x60, 0x55, 0x14, 0x60, 0x2f, 0x24, 0x02, 0x60, 0x03, 0x02, 0x18, 0x27, 0xe5, 0x34, 0xf4,
-0x60, 0x23, 0xe5, 0x34, 0xd3, 0x94, 0x02, 0x40, 0x16, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x02, 0xf0,
-0x90, 0x01, 0x0d, 0xe0, 0x20, 0xe3, 0x03, 0x02, 0x18, 0x27, 0x7f, 0x50, 0x12, 0x16, 0x51, 0x75,
-0x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x34, 0xf4, 0x60, 0x0a, 0xe5, 0x54, 0x70, 0x69, 0x90, 0x01,
-0x0d, 0xe5, 0x33, 0xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x16, 0x51,
-0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x80, 0x4f, 0xe5, 0x54, 0x70, 0x4b, 0x90, 0x04, 0x01, 0xe0,
-0x44, 0x0e, 0xf0, 0x20, 0x19, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f,
-0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03,
-0xf0, 0x20, 0x19, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44,
-0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41,
-0x12, 0x18, 0x2a, 0x80, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe,
-0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14,
-0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4,
-0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x20, 0x19,
-0x03, 0x02, 0x19, 0x0f, 0x90, 0x70, 0x80, 0xe0, 0x04, 0xf0, 0x90, 0x04, 0x37, 0xe0, 0x30, 0xe5,
-0x03, 0x02, 0x19, 0x0b, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x31, 0xa3, 0xe0, 0xf5, 0x30, 0xf5, 0x32,
-0xe4, 0xf5, 0x37, 0x90, 0x70, 0x81, 0xe0, 0x04, 0xf0, 0x90, 0x70, 0x82, 0xe0, 0x04, 0xf0, 0xe5,
-0x32, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00, 0xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x30, 0x65,
-0x32, 0x70, 0x05, 0xfc, 0x7d, 0x18, 0x80, 0x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee,
-0x3c, 0xfe, 0x12, 0x19, 0x10, 0x50, 0x25, 0x90, 0x70, 0x83, 0xe0, 0x04, 0xf0, 0x90, 0x01, 0x14,
-0xe0, 0x44, 0x02, 0xf0, 0xe0, 0x30, 0xe1, 0x06, 0x90, 0x70, 0x92, 0x74, 0x45, 0xf0, 0x90, 0x70,
-0x93, 0xe0, 0x04, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x90, 0x70, 0x94, 0xf0, 0xe5, 0x32, 0x65, 0x31,
-0x60, 0x10, 0xe4, 0x25, 0x32, 0xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x32,
-0x80, 0x97, 0x90, 0x04, 0x10, 0x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x31, 0xf0, 0xa3, 0xe5,
-0x30, 0xf0, 0x90, 0x04, 0x11, 0x74, 0x01, 0xf0, 0x02, 0x18, 0x6a, 0xc2, 0x06, 0xd2, 0x1a, 0x22,
-0x90, 0x70, 0x84, 0xe5, 0x37, 0xf0, 0xc3, 0x94, 0x06, 0x50, 0x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0,
-0xb4, 0xff, 0x07, 0x05, 0x37, 0xe4, 0xf5, 0x36, 0x80, 0x59, 0xe4, 0xf5, 0x37, 0x8f, 0x82, 0x8e,
-0x83, 0xf0, 0x80, 0x4f, 0xe5, 0x36, 0x75, 0xf0, 0x06, 0x84, 0x74, 0x08, 0x25, 0xf0, 0xf5, 0x82,
-0xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0x6d, 0x70, 0x30,
-0x90, 0x70, 0x88, 0xe0, 0x04, 0xf0, 0xa3, 0xe0, 0xfd, 0xd3, 0x95, 0x37, 0x40, 0x02, 0x80, 0x02,
-0xad, 0x37, 0x90, 0x70, 0x89, 0xed, 0xf0, 0x05, 0x37, 0x05, 0x36, 0xe5, 0x36, 0x75, 0xf0, 0x06,
-0x84, 0x74, 0x8a, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x03,
-0xe4, 0xf5, 0x37, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x0a, 0xe5, 0x37, 0xc3,
-0x94, 0x4e, 0x50, 0x03, 0x02, 0x19, 0x10, 0xe5, 0x37, 0xb4, 0x4e, 0x03, 0xd3, 0x80, 0x01, 0xc3,
-0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x94, 0xeb, } ;
diff --git a/drivers/staging/rt2860/common/firmware_3070.h b/drivers/staging/rt2860/common/firmware_3070.h
deleted file mode 100644
index b710d40bc04..00000000000
--- a/drivers/staging/rt2860/common/firmware_3070.h
+++ /dev/null
@@ -1,517 +0,0 @@
-/* AUTO GEN PLEASE DO NOT MODIFY IT */
-/* AUTO GEN PLEASE DO NOT MODIFY IT */
-
-
-u8 FirmwareImage_3070 [] = {
-0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
-0x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
-0x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
-0x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
-0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
-0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
-0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
-0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
-0x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
-0xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
-0x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
-0x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
-0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
-0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
-0x02, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
-0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
-0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
-0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
-0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
-0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
-0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
-0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
-0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14,
-0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
-0x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
-0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
-0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
-0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
-0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2,
-0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
-0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
-0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
-0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
-0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
-0x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
-0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
-0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
-0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
-0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
-0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
-0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
-0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
-0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
-0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
-0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
-0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
-0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
-0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
-0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
-0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
-0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
-0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
-0xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
-0x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
-0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
-0x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
-0x9d, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
-0x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
-0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
-0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
-0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
-0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
-0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
-0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
-0xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
-0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
-0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
-0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
-0x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
-0x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
-0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
-0x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
-0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
-0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
-0x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
-0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
-0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
-0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
-0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
-0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
-0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
-0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
-0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
-0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
-0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
-0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
-0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
-0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
-0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
-0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
-0x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
-0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
-0x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
-0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
-0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
-0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
-0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
-0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
-0x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
-0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
-0x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
-0x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
-0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
-0x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
-0x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
-0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
-0xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
-0x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
-0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
-0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
-0xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
-0x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
-0x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
-0x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
-0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
-0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
-0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
-0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
-0x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
-0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
-0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
-0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
-0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
-0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
-0x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
-0x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
-0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
-0x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
-0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
-0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
-0xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
-0x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
-0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
-0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
-0x0d, 0x2a, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
-0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
-0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
-0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
-0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
-0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
-0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
-0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
-0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
-0x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
-0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
-0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
-0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
-0x7f, 0x01, 0x12, 0x0d, 0x2a, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
-0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
-0x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
-0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
-0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
-0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
-0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
-0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
-0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
-0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
-0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
-0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x7b, 0xc4,
-0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
-0x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
-0x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
-0x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
-0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
-0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
-0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
-0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
-0x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
-0xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
-0x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
-0x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
-0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
-0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
-0x02, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
-0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
-0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
-0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
-0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
-0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
-0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
-0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
-0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14,
-0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
-0x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
-0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
-0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
-0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
-0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2,
-0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
-0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
-0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
-0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
-0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
-0x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
-0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
-0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
-0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
-0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
-0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
-0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
-0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
-0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
-0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
-0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
-0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
-0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
-0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
-0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
-0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
-0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
-0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
-0xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
-0x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
-0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
-0x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
-0xb6, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
-0x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
-0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
-0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
-0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
-0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
-0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
-0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
-0xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
-0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
-0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
-0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
-0x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
-0x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
-0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
-0x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
-0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
-0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
-0x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
-0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
-0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
-0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
-0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
-0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
-0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
-0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
-0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
-0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
-0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
-0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
-0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
-0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
-0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
-0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
-0x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
-0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
-0x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
-0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
-0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
-0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
-0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
-0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
-0x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
-0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
-0x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
-0x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
-0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
-0x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
-0x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
-0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
-0xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
-0x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
-0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
-0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
-0xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
-0x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
-0x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
-0x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
-0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
-0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
-0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
-0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
-0x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
-0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
-0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
-0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
-0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
-0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
-0x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
-0x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
-0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
-0x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
-0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
-0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
-0xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
-0x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
-0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
-0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
-0x0d, 0x48, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
-0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
-0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
-0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
-0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
-0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
-0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
-0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
-0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
-0x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
-0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
-0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
-0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
-0x7f, 0x01, 0x12, 0x0d, 0x48, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
-0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
-0x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
-0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
-0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
-0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
-0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
-0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
-0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
-0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
-0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
-0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x65, 0xd3, } ;
diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c
index 9f03901433b..844d4b987b7 100644
--- a/drivers/staging/rt2860/common/rtmp_mcu.c
+++ b/drivers/staging/rt2860/common/rtmp_mcu.c
@@ -37,35 +37,38 @@
#include "../rt_config.h"
-#if defined(RT2860) || defined(RT3090)
-#include "firmware.h"
-#include "../../rt3090/firmware.h"
-#endif
-#ifdef RT2870
-#include "../../rt3070/firmware.h"
-#include "firmware_3070.h"
-#endif
-
-#include <linux/bitrev.h>
+#include <linux/crc-ccitt.h>
+#include <linux/firmware.h>
#ifdef RTMP_MAC_USB
-/* */
-/* RT2870 Firmware Spec only used 1 oct for version expression */
-/* */
-#define FIRMWARE_MINOR_VERSION 7
-#endif /* RTMP_MAC_USB // */
-/* New 8k byte firmware size for RT3071/RT3072 */
-#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
-#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(u8))
-#define FIRMWARE_MAJOR_VERSION 0
+#define FIRMWAREIMAGE_LENGTH 0x1000
-#define FIRMWAREIMAGEV1_LENGTH 0x1000
-#define FIRMWAREIMAGEV2_LENGTH 0x1000
+#define FIRMWARE_2870_MIN_VERSION 12
+#define FIRMWARE_2870_FILENAME "rt2870.bin"
+MODULE_FIRMWARE(FIRMWARE_2870_FILENAME);
-#ifdef RTMP_MAC_PCI
-#define FIRMWARE_MINOR_VERSION 2
-#endif /* RTMP_MAC_PCI // */
+#define FIRMWARE_3070_MIN_VERSION 17
+#define FIRMWARE_3070_FILENAME "rt3070.bin"
+MODULE_FIRMWARE(FIRMWARE_3070_FILENAME);
+
+#define FIRMWARE_3071_MIN_VERSION 17
+#define FIRMWARE_3071_FILENAME "rt3071.bin" /* for RT3071/RT3072 */
+MODULE_FIRMWARE(FIRMWARE_3071_FILENAME);
+
+#else /* RTMP_MAC_PCI */
+
+#define FIRMWAREIMAGE_LENGTH 0x2000
+
+#define FIRMWARE_2860_MIN_VERSION 11
+#define FIRMWARE_2860_FILENAME "rt2860.bin"
+MODULE_FIRMWARE(FIRMWARE_2860_FILENAME);
+
+#define FIRMWARE_3090_MIN_VERSION 19
+#define FIRMWARE_3090_FILENAME "rt3090.bin" /* for RT3090/RT3390 */
+MODULE_FIRMWARE(FIRMWARE_3090_FILENAME);
+
+#endif
/*
========================================================================
@@ -90,6 +93,78 @@ int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
return 0;
}
+static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter)
+{
+ const char *name;
+ const struct firmware *fw = NULL;
+ u8 min_version;
+ struct device *dev;
+ int err;
+
+ if (adapter->firmware)
+ return adapter->firmware;
+
+#ifdef RTMP_MAC_USB
+ if (IS_RT3071(adapter)) {
+ name = FIRMWARE_3071_FILENAME;
+ min_version = FIRMWARE_3071_MIN_VERSION;
+ } else if (IS_RT3070(adapter)) {
+ name = FIRMWARE_3070_FILENAME;
+ min_version = FIRMWARE_3070_MIN_VERSION;
+ } else {
+ name = FIRMWARE_2870_FILENAME;
+ min_version = FIRMWARE_2870_MIN_VERSION;
+ }
+ dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev;
+#else /* RTMP_MAC_PCI */
+ if (IS_RT3090(adapter) || IS_RT3390(adapter)) {
+ name = FIRMWARE_3090_FILENAME;
+ min_version = FIRMWARE_3090_MIN_VERSION;
+ } else {
+ name = FIRMWARE_2860_FILENAME;
+ min_version = FIRMWARE_2860_MIN_VERSION;
+ }
+ dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev;
+#endif
+
+ err = request_firmware(&fw, name, dev);
+ if (err) {
+ dev_err(dev, "firmware file %s request failed (%d)\n",
+ name, err);
+ return NULL;
+ }
+
+ if (fw->size < FIRMWAREIMAGE_LENGTH) {
+ dev_err(dev, "firmware file %s size is invalid\n", name);
+ goto invalid;
+ }
+
+ /* is it new enough? */
+ adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3];
+ if (adapter->FirmwareVersion < min_version) {
+ dev_err(dev,
+ "firmware file %s is too old;"
+ " driver requires v%d or later\n",
+ name, min_version);
+ goto invalid;
+ }
+
+ /* is the internal CRC correct? */
+ if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) !=
+ (fw->data[FIRMWAREIMAGE_LENGTH - 2] |
+ (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) {
+ dev_err(dev, "firmware file %s failed internal CRC\n", name);
+ goto invalid;
+ }
+
+ adapter->firmware = fw;
+ return fw;
+
+invalid:
+ release_firmware(fw);
+ return NULL;
+}
+
/*
========================================================================
@@ -109,46 +184,16 @@ int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
*/
int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
{
-
+ const struct firmware *fw;
int Status = NDIS_STATUS_SUCCESS;
- u8 *pFirmwareImage = NULL;
- unsigned long FileLength, Index;
+ unsigned long Index;
u32 MacReg = 0;
-#ifdef RTMP_MAC_USB
- u32 Version = (pAd->MACVersion >> 16);
-#endif
- /* New 8k byte firmware size for RT3071/RT3072 */
- {
-#ifdef RTMP_MAC_PCI
- if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
- pFirmwareImage = FirmwareImage_3090;
- FileLength = FIRMWAREIMAGE_MAX_LENGTH;
- } else {
- pFirmwareImage = FirmwareImage_2860;
- FileLength = FIRMWAREIMAGE_MAX_LENGTH;
- }
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
- /* the firmware image consists of two parts */
- if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) { /* use the second part */
- /*printk("KH:Use New Version,part2\n"); */
- pFirmwareImage =
- (u8 *)&
- FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH];
- FileLength = FIRMWAREIMAGEV2_LENGTH;
- } else {
- /*printk("KH:Use New Version,part1\n"); */
- if (Version == 0x3070)
- pFirmwareImage = FirmwareImage_3070;
- else
- pFirmwareImage = FirmwareImage_2870;
- FileLength = FIRMWAREIMAGEV1_LENGTH;
- }
-#endif /* RTMP_MAC_USB // */
- }
+ fw = rtmp_get_firmware(pAd);
+ if (!fw)
+ return NDIS_STATUS_FAILURE;
- RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
+ RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH);
/* check if MCU is ready */
Index = 0;
@@ -221,7 +266,7 @@ int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
("AsicSendCommanToMcu::Mail box is busy\n"));
} while (i++ < 100);
- if (i >= 100) {
+ if (i > 100) {
DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
return FALSE;
}
diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c
index 6af43041907..e665d862281 100644
--- a/drivers/staging/rt2860/pci_main_dev.c
+++ b/drivers/staging/rt2860/pci_main_dev.c
@@ -37,6 +37,7 @@
#include "rt_config.h"
#include <linux/pci.h>
+#include <linux/slab.h>
/* Following information will be show when you run 'modinfo' */
/* *** If you have a solution for the bug in current version of driver, please mail to me. */
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index 9357fb26cc2..fd9a2072139 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -25,7 +25,9 @@
*************************************************************************
*/
+#include <linux/firmware.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "rt_config.h"
unsigned long RTDebugLevel = RT_DEBUG_ERROR;
@@ -260,6 +262,8 @@ void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
NdisFreeSpinLock(&pAd->irq_lock);
+ release_firmware(pAd->firmware);
+
vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
if (os_cookie)
kfree(os_cookie);
@@ -462,9 +466,9 @@ void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
if ((skb =
__dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) {
skb_reserve(skb, 2);
- NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
+ NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
skb_put(skb, HdrLen);
- NdisMoveMemory(skb->tail, pData, DataSize);
+ NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
skb_put(skb, DataSize);
skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
pPacket = OSPKT_TO_RTPKT(skb);
@@ -515,7 +519,7 @@ void *ClonePacket(struct rt_rtmp_adapter *pAd,
pClonedPkt->dev = pRxPkt->dev;
pClonedPkt->data = pData;
pClonedPkt->len = DataSize;
- pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
+ skb_set_tail_pointer(pClonedPkt, DataSize)
ASSERT(DataSize < 1530);
}
return pClonedPkt;
@@ -535,7 +539,7 @@ void update_os_packet_info(struct rt_rtmp_adapter *pAd,
pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
pOSPkt->data = pRxBlk->pData;
pOSPkt->len = pRxBlk->DataSize;
- pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+ skb_set_tail_pointer(pOSPkt, pOSPkt->len);
}
void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
@@ -553,7 +557,7 @@ void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
pOSPkt->data = pRxBlk->pData;
pOSPkt->len = pRxBlk->DataSize;
- pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+ skb_set_tail_pointer(pOSPkt, pOSPkt->len);
/* */
/* copy 802.3 header */
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index f85508d9d5a..a7c540f8e3e 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -658,9 +658,9 @@ void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size,
(RTPKT_TO_OSPKT(_pkt)->len) = (_len)
#define GET_OS_PKT_DATATAIL(_pkt) \
- (RTPKT_TO_OSPKT(_pkt)->tail)
+ (skb_tail_pointer(RTPKT_TO_OSPKT(_pkt))
#define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \
- ((RTPKT_TO_OSPKT(_pkt))->tail) = (u8 *)((_start) + (_len))
+ (skb_set_tail_pointer(RTPKT_TO_OSPKT(_pkt), _len))
#define GET_OS_PKT_HEAD(_pkt) \
(RTPKT_TO_OSPKT(_pkt)->head)
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index c3d92802d0c..fbddb00cfed 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -216,7 +216,7 @@ int rt28xx_close(struct net_device *dev)
u32 i = 0;
#ifdef RTMP_MAC_USB
- DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
DECLARE_WAITQUEUE(wait, current);
#endif /* RTMP_MAC_USB // */
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index c50abf4b806..4401a55bda6 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -1719,6 +1719,7 @@ struct rt_rtmp_adapter {
void *OS_Cookie; /* save specific structure relative to OS */
struct net_device *net_dev;
unsigned long VirtualIfCnt;
+ const struct firmware *firmware;
struct rt_rtmp_chip_op chipOps;
u16 ThisTbttNumToNextWakeUp;
@@ -4043,10 +4044,10 @@ int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
u16 Offset, u8 *pData, u16 length);
int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
- u16 Offset, u8 *pData, u16 length);
+ u16 Offset, const u8 *pData, u16 length);
int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
- u16 Offset, u8 *pData);
+ u16 Offset, const u8 *pData);
int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd,
u8 Id, u8 *pValue);
@@ -4112,7 +4113,7 @@ int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd,
u16 Offset, u16 Value);
int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
- u8 *pFwImage, unsigned long FwLen);
+ const u8 *pFwImage, unsigned long FwLen);
int RTUSBVenderReset(struct rt_rtmp_adapter *pAd);
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
index 17e59ba3d80..55732b10062 100644
--- a/drivers/staging/rt2860/sta/connect.c
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -62,8 +62,8 @@ u8 CipherSuiteWpaNoneAes[] = {
u8 CipherSuiteWpaNoneAesLen =
(sizeof(CipherSuiteWpaNoneAes) / sizeof(u8));
-/* The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS, */
-/* or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
+/* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */
+/* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
/* All settings successfuly negotiated furing MLME state machines become final settings */
/* and are copied to pAd->StaActive */
#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index d8fbe6cc694..de4b6277bae 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -975,10 +975,7 @@ int rt_ioctl_giwscan(struct net_device *dev,
/*================================ */
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWFREQ;
- if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
- iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
- else
- iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
+ iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
iwe.u.freq.e = 0;
iwe.u.freq.i = 0;
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c
index 925a236e104..740db0c1ac0 100644
--- a/drivers/staging/rt2860/usb_main_dev.c
+++ b/drivers/staging/rt2860/usb_main_dev.c
@@ -63,6 +63,7 @@ struct usb_device_id rtusb_usb_id[] = {
{USB_DEVICE(0x07D1, 0x3C11)}, /* D-Link */
{USB_DEVICE(0x14B2, 0x3C07)}, /* AL */
{USB_DEVICE(0x050D, 0x8053)}, /* Belkin */
+ {USB_DEVICE(0x050D, 0x825B)}, /* Belkin */
{USB_DEVICE(0x14B2, 0x3C23)}, /* Airlink */
{USB_DEVICE(0x14B2, 0x3C27)}, /* Airlink */
{USB_DEVICE(0x07AA, 0x002F)}, /* Corega */
@@ -216,10 +217,6 @@ static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
static int rt2870_resume(struct usb_interface *intf);
#endif /* CONFIG_PM // */
-static int rtusb_probe(struct usb_interface *intf,
- const struct usb_device_id *id);
-static void rtusb_disconnect(struct usb_interface *intf);
-
static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
IN struct usb_interface *intf,
struct rt_rtmp_adapter *pAd)
@@ -296,7 +293,7 @@ static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
}
-static int rtusb_probe(struct usb_interface *intf,
+static int __devinit rtusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct rt_rtmp_adapter *pAd;
diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig
index fd3ba3a3b12..6ea172b433e 100644
--- a/drivers/staging/rt2870/Kconfig
+++ b/drivers/staging/rt2870/Kconfig
@@ -3,5 +3,7 @@ config RT2870
depends on USB && X86 && WLAN
select WIRELESS_EXT
select WEXT_PRIV
+ select CRC_CCITT
+ select FW_LOADER
---help---
This is an experimental driver for the Ralink xx70 wireless chips.
diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c
index 34443f2243f..cf0d2f5dbc6 100644
--- a/drivers/staging/rt2870/common/rtusb_io.c
+++ b/drivers/staging/rt2870/common/rtusb_io.c
@@ -84,7 +84,7 @@ static int RTUSBFirmwareRun(struct rt_rtmp_adapter *pAd)
========================================================================
*/
int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
- u8 *pFwImage, unsigned long FwLen)
+ const u8 *pFwImage, unsigned long FwLen)
{
u32 MacReg;
int Status;
@@ -167,7 +167,7 @@ int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
========================================================================
*/
int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
- u16 Offset, u8 *pData)
+ u16 Offset, const u8 *pData)
{
int Status;
@@ -175,18 +175,18 @@ int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
Status = RTUSB_VendorRequest(pAd,
USBD_TRANSFER_DIRECTION_OUT,
DEVICE_VENDOR_REQUEST_OUT,
- 0x6, 0, Offset, pData, 1);
+ 0x6, 0, Offset, (u8 *)pData, 1);
return Status;
}
int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
- u16 Offset, u8 *pData, u16 length)
+ u16 Offset, const u8 *pData, u16 length)
{
int Status;
u16 index = 0, Value;
- u8 *pSrc = pData;
+ const u8 *pSrc = pData;
u16 resude = 0;
resude = length % 2;
diff --git a/drivers/staging/rt3070/firmware.h b/drivers/staging/rt3070/firmware.h
deleted file mode 100644
index 5cf9cbcf4ab..00000000000
--- a/drivers/staging/rt3070/firmware.h
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- Copyright (c) 2007, Ralink Technology Corporation
- All rights reserved.
-
- Redistribution. Redistribution and use in binary form, without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions must reproduce the above copyright notice and the
- following disclaimer in the documentation and/or other materials
- provided with the distribution.
- * Neither the name of Ralink Technology Corporation nor the names of its
- suppliers may be used to endorse or promote products derived from this
- software without specific prior written permission.
- * No reverse engineering, decompilation, or disassembly of this software
- is permitted.
-
- Limited patent license. Ralink Technology Corporation grants a world-wide,
- royalty-free, non-exclusive license under patents it now or hereafter
- owns or controls to make, have made, use, import, offer to sell and
- sell ("Utilize") this software, but solely to the extent that any
- such patent is necessary to Utilize the software alone, or in
- combination with an operating system licensed under an approved Open
- Source license as listed by the Open Source Initiative at
- http://opensource.org/licenses. The patent license shall not apply to
- any other combinations which include this software. No hardware per
- se is licensed hereunder.
-
- DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- 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.
-*/
-/* AUTO GEN PLEASE DO NOT MODIFY IT */
-/* AUTO GEN PLEASE DO NOT MODIFY IT */
-
-
-u8 FirmwareImage_2870 [] = {
-0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
-0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
-0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
-0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
-0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
-0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
-0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
-0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
-0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
-0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
-0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
-0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
-0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
-0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
-0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
-0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
-0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
-0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
-0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
-0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
-0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
-0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
-0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
-0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x22, 0x90, 0x70,
-0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
-0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
-0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
-0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
-0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
-0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
-0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
-0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
-0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80,
-0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
-0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74,
-0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
-0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90,
-0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
-0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
-0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
-0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
-0x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
-0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
-0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
-0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
-0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
-0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
-0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
-0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
-0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
-0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
-0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
-0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
-0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
-0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
-0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
-0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
-0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
-0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
-0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
-0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
-0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
-0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
-0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
-0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
-0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
-0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
-0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
-0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
-0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
-0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
-0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
-0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
-0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
-0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
-0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
-0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
-0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
-0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
-0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
-0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
-0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
-0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
-0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
-0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
-0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
-0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
-0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
-0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
-0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
-0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
-0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
-0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
-0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
-0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
-0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
-0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
-0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
-0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
-0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
-0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
-0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
-0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
-0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
-0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
-0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
-0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
-0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
-0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
-0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
-0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
-0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
-0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
-0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
-0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
-0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
-0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
-0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
-0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
-0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
-0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
-0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
-0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
-0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
-0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
-0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
-0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
-0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
-0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
-0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x94, 0x3f,
-0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
-0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
-0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
-0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
-0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
-0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
-0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
-0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
-0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
-0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
-0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
-0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
-0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
-0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
-0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
-0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
-0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
-0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
-0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
-0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
-0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
-0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
-0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
-0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x22, 0x90, 0x70,
-0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
-0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
-0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
-0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
-0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
-0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
-0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
-0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
-0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80,
-0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
-0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74,
-0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
-0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90,
-0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
-0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
-0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
-0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
-0x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
-0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
-0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
-0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
-0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
-0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
-0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
-0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
-0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
-0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
-0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
-0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
-0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
-0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
-0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
-0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
-0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
-0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
-0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
-0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
-0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
-0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
-0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
-0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
-0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
-0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
-0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
-0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
-0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
-0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
-0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
-0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
-0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
-0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
-0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
-0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
-0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
-0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
-0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
-0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
-0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
-0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
-0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
-0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
-0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
-0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
-0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
-0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
-0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
-0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
-0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
-0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
-0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
-0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
-0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
-0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
-0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
-0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
-0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
-0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
-0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
-0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
-0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
-0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
-0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
-0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
-0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
-0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
-0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
-0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
-0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
-0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
-0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
-0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
-0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
-0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
-0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
-0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
-0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
-0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
-0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
-0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
-0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
-0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
-0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
-0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
-0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
-0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
-0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9b, 0xc0, } ;
diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h
index a9cc7b0f3ee..b3fb6372618 100644
--- a/drivers/staging/rt3070/md4.h
+++ b/drivers/staging/rt3070/md4.h
@@ -35,8 +35,8 @@ typedef struct _MD4_CTX_ {
u8 buffer[64]; /* input buffer */
} MD4_CTX;
-void MD4Init (MD4_CTX *);
-void MD4Update (MD4_CTX *, u8 *, UINT);
-void MD4Final (u8 [16], MD4_CTX *);
+void MD4Init(MD4_CTX *);
+void MD4Update(MD4_CTX *, u8 *, UINT);
+void MD4Final(u8 [16], MD4_CTX *);
-#endif //__MD4_H__ \ No newline at end of file
+#endif /*__MD4_H__*/
diff --git a/drivers/staging/rt3090/firmware.h b/drivers/staging/rt3090/firmware.h
deleted file mode 100644
index 17056e26795..00000000000
--- a/drivers/staging/rt3090/firmware.h
+++ /dev/null
@@ -1,517 +0,0 @@
-/* AUTO GEN PLEASE DO NOT MODIFY IT */
-/* AUTO GEN PLEASE DO NOT MODIFY IT */
-
-
-u8 FirmwareImage_3090 [] = {
-0x02, 0x02, 0xf3, 0x02, 0x02, 0xa1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x27, 0xff, 0xff,
-0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xd8, 0xc0, 0xe0,
-0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
-0x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14,
-0xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x36,
-0x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14,
-0x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24,
-0x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5,
-0x50, 0x85, 0x36, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55,
-0x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x36, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf,
-0x36, 0x12, 0x02, 0x7d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0,
-0xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf,
-0x36, 0x12, 0x02, 0x7d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
-0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82,
-0xc0, 0xd0, 0xe8, 0xc0, 0xe0, 0xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0,
-0xe0, 0xed, 0xc0, 0xe0, 0xee, 0xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12,
-0x10, 0x12, 0xd2, 0xaf, 0xd0, 0xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc,
-0xd0, 0xe0, 0xfb, 0xd0, 0xe0, 0xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82,
-0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0,
-0xd0, 0x75, 0xd0, 0x10, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5,
-0x54, 0x60, 0x04, 0x15, 0x54, 0x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04,
-0x15, 0x50, 0x80, 0x02, 0xc2, 0x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04,
-0x30, 0x45, 0x03, 0x12, 0x10, 0x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83,
-0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x43, 0xc2, 0xaf, 0x90, 0x70,
-0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
-0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x37, 0x90, 0x10, 0x1e, 0xe0,
-0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
-0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22,
-0x12, 0x02, 0xc3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12,
-0x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b,
-0x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09,
-0x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12,
-0x03, 0x1c, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5,
-0x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18,
-0x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x1a, 0xc2, 0x18, 0xc2, 0x1b, 0x22,
-0xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16,
-0x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8,
-0xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12,
-0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83,
-0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60,
-0x1f, 0xe4, 0xfe, 0x12, 0x03, 0x5b, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x5b, 0xef, 0xf0, 0x74,
-0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3,
-0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf,
-0x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0,
-0xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x04, 0x12, 0x02, 0xdc, 0xe4, 0xf5,
-0x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x75, 0x89, 0x02, 0xe4,
-0xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75,
-0xa8, 0x05, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xc0, 0xff,
-0xc0, 0x26, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x0a, 0x22, 0xc0, 0x26,
-0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x18, 0x22, 0x30, 0x45, 0x03, 0x12,
-0x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22,
-0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x71, 0x1e, 0x80, 0xf5, 0x22, 0xc8,
-0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22, 0xc8, 0xef, 0xc8,
-0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x74, 0x14, 0x2e, 0xf5, 0x82,
-0xe4, 0x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x6f, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a,
-0x18, 0xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 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,
-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, 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, 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, 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, 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, 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, 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, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x13, 0x68, 0x02,
-0x13, 0x69, 0x02, 0x14, 0x1e, 0x02, 0x14, 0x1f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x19, 0xa1, 0x02,
-0x1b, 0x31, 0x02, 0x14, 0xea, 0x02, 0x14, 0x20, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x01,
-0x75, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x1c, 0x4f, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0,
-0x20, 0xe7, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0,
-0x12, 0x02, 0x57, 0x11, 0x11, 0x30, 0x10, 0xe2, 0x31, 0x10, 0x90, 0x33, 0x10, 0xa0, 0x34, 0x10,
-0xbe, 0x35, 0x10, 0xac, 0x36, 0x11, 0x1f, 0x50, 0x11, 0x68, 0x51, 0x11, 0x71, 0x52, 0x11, 0x71,
-0x53, 0x11, 0x71, 0x54, 0x11, 0xb3, 0x55, 0x12, 0x16, 0x70, 0x12, 0x42, 0x71, 0x12, 0x71, 0x72,
-0x12, 0xda, 0x73, 0x12, 0xfe, 0x80, 0x13, 0x29, 0x83, 0x13, 0x47, 0x84, 0x00, 0x00, 0x13, 0x67,
-0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x2a, 0x75, 0x32, 0x0b, 0x75, 0x33, 0xb8, 0x02, 0x13, 0x62,
-0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0, 0x54, 0xfd, 0xf0, 0x02, 0x13, 0x62, 0x90, 0x70, 0x11, 0xe0,
-0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x22, 0xe5, 0x55,
-0xb4, 0x02, 0x0f, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x7d, 0x01,
-0x80, 0x02, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02,
-0x13, 0x62, 0x20, 0x02, 0x03, 0x30, 0x03, 0x10, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90,
-0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90,
-0x01, 0x0c, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x85, 0x56, 0x41, 0xd2, 0x02,
-0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x67, 0xe0, 0xf5, 0x30, 0x22, 0xe5,
-0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x10,
-0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, 0xb4, 0x08, 0x06, 0x75, 0x4e,
-0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x13,
-0x67, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x13,
-0x67, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47,
-0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09, 0x90,
-0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47,
-0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8,
-0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
-0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13,
-0x09, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x23, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x1d, 0xe5, 0x47, 0x64,
-0x09, 0x60, 0x17, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x0b, 0xe5,
-0x47, 0x64, 0x0d, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x0d, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f,
-0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5,
-0x47, 0xb4, 0x0a, 0x08, 0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56,
-0x12, 0x02, 0x7d, 0xd2, 0x04, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60,
-0x03, 0x02, 0x13, 0x09, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8,
-0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02,
-0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09,
-0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
-0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13,
-0x62, 0x90, 0x10, 0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5,
-0x59, 0xe5, 0x58, 0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44,
-0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe,
-0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0xc2, 0x1a, 0xc2, 0x18,
-0xc2, 0x1b, 0xf5, 0x34, 0x90, 0x05, 0xa4, 0x74, 0x11, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0xa3, 0x74,
-0x03, 0xf0, 0xe4, 0xf5, 0x30, 0xc2, 0x19, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02,
-0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40,
-0x06, 0xe5, 0x55, 0x60, 0x02, 0x80, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4,
-0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x64, 0xe5, 0x34,
-0xc3, 0x94, 0x03, 0x40, 0x0b, 0xe5, 0x55, 0x60, 0x07, 0x7d, 0x03, 0xaf, 0x56, 0x02, 0x02, 0x7d,
-0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02,
-0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x39, 0xe4, 0xf5, 0x34, 0xf5, 0x30, 0x90, 0x70,
-0x10, 0xe0, 0xf4, 0x60, 0x03, 0xe0, 0xf5, 0x34, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90,
-0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x1b, 0xd2, 0x19, 0x05, 0x2f, 0xe5, 0x2f, 0xb4, 0x1a, 0x03,
-0xe4, 0xf5, 0x2f, 0xd2, 0x04, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74,
-0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x22, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x17,
-0xe5, 0x55, 0xb4, 0x02, 0x12, 0xe5, 0x30, 0x60, 0x0e, 0x30, 0x60, 0x0b, 0x74, 0xfd, 0x25, 0x46,
-0xf5, 0x46, 0xd2, 0x04, 0xe4, 0xf5, 0x53, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x14, 0x1d, 0x30, 0x60,
-0x21, 0xb2, 0x4d, 0x30, 0x4d, 0x1c, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x11, 0xe5, 0x55, 0xb4,
-0x02, 0x0c, 0xe5, 0x30, 0x60, 0x08, 0x74, 0x03, 0x25, 0x46, 0xf5, 0x46, 0x80, 0x02, 0x05, 0x46,
-0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e,
-0x30, 0x1a, 0x49, 0x7f, 0x32, 0x7d, 0xb8, 0x7c, 0x0b, 0x12, 0x02, 0x30, 0x50, 0x06, 0x90, 0x04,
-0x10, 0x74, 0x40, 0xf0, 0x7f, 0x35, 0x7d, 0x32, 0x12, 0x03, 0x3f, 0x50, 0x09, 0x90, 0x10, 0x04,
-0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5, 0x35, 0xd3, 0x94, 0x2d, 0x40, 0x30, 0x30, 0x1b, 0x2d,
-0xc2, 0x1b, 0xa2, 0x18, 0x92, 0x1a, 0x20, 0x1a, 0x24, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0,
-0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0, 0xc2, 0x61, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2,
-0x18, 0x92, 0x1a, 0x30, 0x1a, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22,
-0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x57, 0x14, 0x42, 0x00, 0x14, 0xd5, 0x04, 0x14,
-0xd1, 0x08, 0x14, 0xac, 0x10, 0x14, 0x56, 0x20, 0x14, 0x76, 0x60, 0x14, 0x87, 0xa0, 0x00, 0x00,
-0x14, 0xd7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60,
-0x03, 0x02, 0x14, 0xd7, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4,
-0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70,
-0x66, 0x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5,
-0x47, 0x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b,
-0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06,
-0x70, 0x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04,
-0x06, 0x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75,
-0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80,
-0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x2a, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff,
-0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x1a, 0x24, 0xc0,
-0x60, 0x0a, 0x24, 0x35, 0x70, 0x09, 0x12, 0x19, 0x5f, 0x12, 0x15, 0x09, 0x12, 0x19, 0x5f, 0x12,
-0x15, 0x09, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54,
-0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2,
-0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74, 0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f,
-0xf5, 0x2d, 0xe5, 0x2a, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5, 0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d,
-0x29, 0xe5, 0x5f, 0x54, 0x30, 0x64, 0x30, 0x70, 0x21, 0xe5, 0x2a, 0x70, 0x15, 0xe5, 0x34, 0xc3,
-0x94, 0x03, 0x40, 0x09, 0xe5, 0x30, 0x60, 0x05, 0x75, 0x2a, 0x05, 0x80, 0x07, 0x75, 0x2a, 0x0c,
-0x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2,
-0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03, 0x70, 0x21, 0x30,
-0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x2a, 0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2,
-0x4c, 0xe5, 0x2a, 0x70, 0x05, 0x75, 0x2a, 0x07, 0x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d,
-0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05,
-0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a,
-0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, 0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2,
-0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e,
-0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75,
-0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x45, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
-0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00,
-0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80,
-0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0,
-0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73,
-0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x45, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
-0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00,
-0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80,
-0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0,
-0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75,
-0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x64, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x19, 0xe5,
-0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x53, 0xe5, 0x46, 0x20, 0xe4, 0x03, 0x30,
-0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x45, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80,
-0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5,
-0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80, 0x1d,
-0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe,
-0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92,
-0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30,
-0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f,
-0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06,
-0x70, 0x46, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60,
-0x14, 0x24, 0xfe, 0x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x19, 0x5e, 0x90, 0x02, 0x28, 0xe0,
-0x30, 0x47, 0x0d, 0x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22,
-0x44, 0x01, 0xf0, 0x22, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90,
-0x02, 0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47,
-0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x18, 0x27, 0xe4, 0xf5, 0x27,
-0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e, 0x14,
-0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5, 0x46,
-0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80,
-0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46, 0x30,
-0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3,
-0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47,
-0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47,
-0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39,
-0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02,
-0x28, 0xe0, 0x54, 0xfc, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64,
-0x0b, 0x60, 0x03, 0x02, 0x18, 0xc6, 0xe4, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfd, 0xf0,
-0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24,
-0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03,
-0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35,
-0xa2, 0x47, 0x92, 0x39, 0x80, 0x47, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
-0x39, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e,
-0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80, 0x02,
-0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x39, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03,
-0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x05, 0xa2, 0x47, 0xb3, 0x92, 0x39, 0x90, 0x02, 0x28,
-0xe0, 0x54, 0xfd, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0d, 0x60, 0x03, 0x02, 0x19, 0x5e, 0xf5,
-0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xef, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e,
-0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24, 0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5,
-0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
-0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35, 0xa2, 0x47, 0x92, 0x3c, 0x80, 0x47, 0xe5, 0x46,
-0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
-0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
-0x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92,
-0x3c, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x05,
-0xa2, 0x47, 0xb3, 0x92, 0x3c, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xef, 0x45, 0x27, 0xf0, 0x22, 0xe5,
-0x47, 0x64, 0x0b, 0x70, 0x1c, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, 0xf0, 0x30, 0x47, 0x04, 0xaf,
-0x45, 0x80, 0x05, 0xe5, 0x45, 0x64, 0x14, 0xff, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xeb, 0x4f, 0xf0,
-0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4,
-0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58,
-0x22, 0xe4, 0xf5, 0x37, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a, 0x14, 0x60, 0x6b, 0x24, 0x02,
-0x60, 0x03, 0x02, 0x1b, 0x12, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20, 0x1a, 0x1c, 0x90, 0x02, 0x08,
-0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3,
-0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x19, 0x97, 0x90, 0x10,
-0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x1b, 0x12, 0xe5, 0x50, 0x70, 0x06, 0x75,
-0x37, 0x03, 0x02, 0x1b, 0x12, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x15, 0x7f, 0x20, 0x12,
-0x19, 0x97, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb, 0xf0, 0x75, 0x51, 0x02, 0x02,
-0x1b, 0x12, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x1b, 0x0d, 0x20, 0x1a, 0x15, 0x90, 0x02, 0x08, 0xe0,
-0x30, 0xe3, 0x03, 0x02, 0x1b, 0x09, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x1b,
-0x09, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35,
-0x10, 0xe4, 0x90, 0x05, 0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03,
-0xf0, 0x7f, 0x01, 0x12, 0x03, 0x30, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54,
-0xf0, 0xf0, 0xe5, 0x59, 0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3,
-0x80, 0x14, 0x90, 0x13, 0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13,
-0x2a, 0x60, 0x08, 0xe0, 0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x20,
-0x1a, 0x07, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x10, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x09,
-0xe5, 0x30, 0x70, 0x05, 0x75, 0x8c, 0x40, 0x80, 0x03, 0x75, 0x8c, 0x80, 0x90, 0x04, 0x01, 0xe0,
-0x54, 0xfd, 0xf0, 0x20, 0x1a, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x59, 0xb4,
-0x28, 0x06, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x31, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x14, 0x90,
-0x01, 0x0d, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x59, 0x64, 0x35, 0x60, 0x07, 0x90, 0x12, 0x04, 0xe0,
-0x54, 0xfd, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x14, 0x20, 0x02, 0x11, 0x20, 0x03, 0x0e,
-0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x37,
-0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x37, 0x03,
-0xf5, 0x51, 0xe5, 0x37, 0x60, 0x18, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x1a, 0x0e,
-0xad, 0x37, 0xaf, 0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x37, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf,
-0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf,
-0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x52, 0x14, 0x60, 0x5c, 0x14, 0x60, 0x3a, 0x24, 0x02, 0x60, 0x03,
-0x02, 0x1c, 0x18, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x02,
-0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x13, 0x90, 0x12, 0x04,
-0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x32, 0x12, 0x03, 0x30, 0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfe, 0xf0,
-0x75, 0x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0xe5, 0x31,
-0xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x19, 0x9c, 0x75, 0x52, 0x01,
-0x75, 0x55, 0x03, 0x80, 0x73, 0xe5, 0x54, 0x70, 0x6f, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0,
-0x20, 0x1a, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0xf5, 0x8c, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f,
-0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03,
-0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90, 0x05, 0x00, 0x74, 0xe2,
-0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x03,
-0x30, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44,
-0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41,
-0x12, 0x1c, 0x1b, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4,
-0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74,
-0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82,
-0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x30,
-0x1a, 0x77, 0x90, 0x04, 0x37, 0xe0, 0x20, 0xe5, 0x6c, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x38, 0xa3,
-0xe0, 0xf5, 0x37, 0xf5, 0x39, 0xe4, 0xf5, 0x25, 0xe5, 0x39, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00,
-0xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x37, 0x65, 0x39, 0x70, 0x05, 0xfc, 0x7d, 0x28, 0x80,
-0x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee, 0x3c, 0xfe, 0x12, 0x1c, 0xca, 0x50, 0x07,
-0x90, 0x01, 0x14, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x39, 0x65, 0x38, 0x60, 0x10, 0xe4, 0x25, 0x39,
-0xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x39, 0x80, 0xbb, 0x90, 0x04, 0x10,
-0x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x38, 0xf0, 0xa3, 0xe5, 0x37, 0xf0, 0x90, 0x04, 0x11,
-0x74, 0x01, 0xf0, 0x80, 0x8d, 0xc2, 0x06, 0xd2, 0x1b, 0x22, 0xe5, 0x25, 0xc3, 0x94, 0x06, 0x50,
-0x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xb4, 0xff, 0x07, 0x05, 0x25, 0xe4, 0xf5, 0x24, 0x80, 0x2e,
-0xe4, 0xf5, 0x25, 0x8f, 0x82, 0x8e, 0x83, 0xf0, 0x80, 0x24, 0xe5, 0x24, 0x75, 0xf0, 0x06, 0x84,
-0x74, 0x08, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e,
-0x83, 0xe0, 0x6d, 0x70, 0x06, 0x05, 0x25, 0x05, 0x24, 0x80, 0x03, 0xe4, 0xf5, 0x25, 0x0f, 0xbf,
-0x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x07, 0xe5, 0x25, 0xc3, 0x94, 0x2a, 0x40, 0xab, 0xe5,
-0x25, 0xb4, 0x2a, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xe3, 0x34, } ;
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
index e24a6f7a0d8..155a78e0740 100644
--- a/drivers/staging/rtl8187se/Kconfig
+++ b/drivers/staging/rtl8187se/Kconfig
@@ -3,6 +3,7 @@ config R8187SE
depends on PCI && WLAN
select WIRELESS_EXT
select WEXT_PRIV
+ select EEPROM_93CX6
default N
---help---
If built as a module, it will be called r8187se.ko.
diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile
index b395acf5a38..e6adf91cdd2 100644
--- a/drivers/staging/rtl8187se/Makefile
+++ b/drivers/staging/rtl8187se/Makefile
@@ -18,7 +18,6 @@ EXTRA_CFLAGS += -DENABLE_LPS
r8187se-objs := \
r8180_core.o \
- r8180_93cx6.o \
r8180_wx.o \
r8180_rtl8225z2.o \
r8185b_init.o \
diff --git a/drivers/staging/rtl8187se/TODO b/drivers/staging/rtl8187se/TODO
index a762e79873e..704949a9da0 100644
--- a/drivers/staging/rtl8187se/TODO
+++ b/drivers/staging/rtl8187se/TODO
@@ -5,7 +5,6 @@ TODO:
- switch to use shared "librtl" instead of private ieee80211 stack
- switch to use LIB80211
- switch to use MAC80211
-- switch to use EEPROM_93CX6
- use kernel coding style
- checkpatch.pl fixes
- sparse fixes
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
index 9086047c32d..4cd95c3dc94 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
@@ -29,6 +29,7 @@
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/sched.h>
+#include <linux/semaphore.h>
#include <linux/wireless.h>
#include <linux/ieee80211.h>
@@ -161,10 +162,6 @@ do { if (ieee80211_debug_level & (level)) \
#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
#endif /* CONFIG_IEEE80211_DEBUG */
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \
- ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
-
/*
* To use the debug system;
*
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
index 172e8f3ae6c..40f1b99faad 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
@@ -285,7 +285,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: received packet without ExtIV"
- " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ " flag from %pM\n", hdr->addr2);
}
key->dot11RSNAStatsCCMPFormatErrors++;
return -2;
@@ -298,9 +298,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!key->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+ printk(KERN_DEBUG "CCMP: received packet from %pM"
" with keyid=%d that does not have a configured"
- " key\n", MAC_ARG(hdr->addr2), keyidx);
+ " key\n", hdr->addr2, keyidx);
}
return -3;
}
@@ -315,11 +315,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
- " previous PN %02x%02x%02x%02x%02x%02x "
- "received PN %02x%02x%02x%02x%02x%02x\n",
- MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
- MAC_ARG(pn));
+ printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
+ " previous PN %pm received PN %pm\n",
+ hdr->addr2, key->rx_pn, pn);
}
key->dot11RSNAStatsCCMPReplays++;
return -4;
@@ -347,7 +345,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: decrypt failed: STA="
- MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ "%pM\n", hdr->addr2);
}
key->dot11RSNAStatsCCMPDecryptErrors++;
return -5;
@@ -423,11 +421,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
{
struct ieee80211_ccmp_data *ccmp = priv;
p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
+ "tx_pn=%pm rx_pn=%pm "
"format_errors=%d replays=%d decrypt_errors=%d\n",
ccmp->key_idx, ccmp->key_set,
- MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+ ccmp->tx_pn, ccmp->rx_pn,
ccmp->dot11RSNAStatsCCMPFormatErrors,
ccmp->dot11RSNAStatsCCMPReplays,
ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
index e6d8385e1d8..a5254111d9a 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
@@ -385,7 +385,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ " flag from %pM\n", hdr->addr2);
}
return -2;
}
@@ -397,9 +397,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!tkey->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+ printk(KERN_DEBUG "TKIP: received packet from %pM"
" with keyid=%d that does not have a configured"
- " key\n", MAC_ARG(hdr->addr2), keyidx);
+ " key\n", hdr->addr2, keyidx);
}
return -3;
}
@@ -410,9 +410,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (iv32 < tkey->rx_iv32 ||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+ printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
" previous TSC %08x%04x received TSC "
- "%08x%04x\n", MAC_ARG(hdr->addr2),
+ "%08x%04x\n", hdr->addr2,
tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
}
tkey->dot11RSNAStatsTKIPReplays++;
@@ -431,8 +431,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
if (net_ratelimit()) {
printk(KERN_DEBUG ": TKIP: failed to decrypt "
- "received packet from " MAC_FMT "\n",
- MAC_ARG(hdr->addr2));
+ "received packet from %pM\n",
+ hdr->addr2);
}
return -7;
}
@@ -450,7 +450,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: ICV error detected: STA="
- MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ "%pM\n", hdr->addr2);
}
tkey->dot11RSNAStatsTKIPICVErrors++;
return -5;
@@ -604,8 +604,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
struct ieee80211_hdr_4addr *hdr;
hdr = (struct ieee80211_hdr_4addr *)skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- "MSDU from " MAC_FMT " keyidx=%d\n",
- skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+ "MSDU from %pM keyidx=%d\n",
+ skb->dev ? skb->dev->name : "N/A", hdr->addr2,
keyidx);
if (skb->dev)
ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
index 9128c181bc7..2b7080cc2c0 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
@@ -311,8 +311,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
strcmp(crypt->ops->name, "TKIP") == 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "received packet from " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(hdr->addr2));
+ "received packet from %pM\n",
+ ieee->dev->name, hdr->addr2);
}
return -1;
}
@@ -323,8 +323,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
atomic_dec(&crypt->refcnt);
if (res < 0) {
IEEE80211_DEBUG_DROP(
- "decryption failed (SA=" MAC_FMT
- ") res=%d\n", MAC_ARG(hdr->addr2), res);
+ "decryption failed (SA=%pM"
+ ") res=%d\n", hdr->addr2, res);
if (res == -2)
IEEE80211_DEBUG_DROP("Decryption failed ICV "
"mismatch (key %d)\n",
@@ -356,8 +356,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
atomic_dec(&crypt->refcnt);
if (res < 0) {
printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- " (SA=" MAC_FMT " keyidx=%d)\n",
- ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+ " (SA=%pM keyidx=%d)\n",
+ ieee->dev->name, hdr->addr2, keyidx);
return -1;
}
@@ -550,8 +550,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
* frames silently instead of filling system log with
* these reports. */
IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ " (SA=%pM)\n",
+ hdr->addr2);
ieee->ieee_stats.rx_discards_undecryptable++;
goto rx_dropped;
}
@@ -709,8 +709,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
} else {
IEEE80211_DEBUG_DROP(
"encryption configured, but RX "
- "frame not encrypted (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ "frame not encrypted (SA=%pM)\n",
+ hdr->addr2);
goto rx_dropped;
}
}
@@ -729,9 +729,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
!ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
IEEE80211_DEBUG_DROP(
"dropped unencrypted RX data "
- "frame from " MAC_FMT
+ "frame from %pM"
" (drop_unencrypted=1)\n",
- MAC_ARG(hdr->addr2));
+ hdr->addr2);
goto rx_dropped;
}
/*
@@ -1196,11 +1196,11 @@ inline int ieee80211_network_init(
}
if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+ IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
"network.\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid));
+ network->bssid);
return 1;
}
@@ -1341,9 +1341,9 @@ inline void ieee80211_process_probe_response(
memset(&network, 0, sizeof(struct ieee80211_network));
IEEE80211_DEBUG_SCAN(
- "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+ "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
escape_essid(info_element->data, info_element->len),
- MAC_ARG(beacon->header.addr3),
+ beacon->header.addr3,
(beacon->capability & (1<<0xf)) ? '1' : '0',
(beacon->capability & (1<<0xe)) ? '1' : '0',
(beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -1362,10 +1362,10 @@ inline void ieee80211_process_probe_response(
(beacon->capability & (1<<0x0)) ? '1' : '0');
if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
escape_essid(info_element->data,
info_element->len),
- MAC_ARG(beacon->header.addr3),
+ beacon->header.addr3,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -1464,11 +1464,11 @@ inline void ieee80211_process_probe_response(
/* If there are no more slots, expire the oldest */
list_del(&oldest->list);
target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+ IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
"network list.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid));
+ target->bssid);
} else {
/* Otherwise just pull from the free list */
target = list_entry(ieee->network_free_list.next,
@@ -1478,10 +1478,10 @@ inline void ieee80211_process_probe_response(
#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
escape_essid(network.ssid,
network.ssid_len),
- MAC_ARG(network.bssid),
+ network.bssid,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -1492,10 +1492,10 @@ inline void ieee80211_process_probe_response(
if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
ieee80211_softmac_new_net(ieee,&network);
} else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid),
+ target->bssid,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index a2150670ef5..be2d17f60c3 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -18,6 +18,7 @@
#include <linux/random.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include <asm/uaccess.h>
@@ -1573,7 +1574,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
ieee80211_resp_to_assoc_rq(ieee, dest);
}
- printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+ printk(KERN_INFO"New client associated: %pM\n", dest);
}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
index f1d6cb45256..ad42bcdc937 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
@@ -482,8 +482,7 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee,
(!ieee->enter_sleep_state) ||
(!ieee->ps_is_queue_empty)){
- printk("ERROR. PS mode is tryied to be use but\
-driver missed a callback\n\n");
+ printk("ERROR. PS mode tried to be use but driver missed a callback\n\n");
return -1;
}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
index 69bd02164b0..6cb31e1760a 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
@@ -198,8 +198,8 @@ int ieee80211_encrypt_fragment(
header = (struct ieee80211_hdr_4addr *)frag->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "TX packet to " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(header->addr1));
+ "TX packet to %pM\n",
+ ieee->dev->name, header->addr1);
}
return -1;
}
@@ -407,7 +407,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
memcpy(&header.addr2, src, ETH_ALEN);
memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
}
- // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
+ // printk(KERN_WARNING "essid MAC address is %pM", &header.addr1);
header.frame_ctl = cpu_to_le16(fc);
//hdr_len = IEEE80211_3ADDR_LEN;
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
index 6aad48fe2e1..c5b80f9c32c 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -31,6 +31,7 @@
******************************************************************************/
#include <linux/wireless.h>
#include <linux/kmod.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include "ieee80211.h"
@@ -234,10 +235,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
else
IEEE80211_DEBUG_SCAN(
"Not showing network '%s ("
- MAC_FMT ")' due to age (%lums).\n",
+ "%pM)' due to age (%lums).\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid),
+ network->bssid,
(jiffies - network->last_scanned) / (HZ / 100));
}
}
@@ -694,7 +695,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
#if 1
case IW_AUTH_WPA_ENABLED:
ieee->wpa_enabled = (data->value)?1:0;
- //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
+ //printk("enable wpa:%d\n", ieee->wpa_enabled);
break;
#endif
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
index ce828885b64..d15bdf64efd 100644
--- a/drivers/staging/rtl8187se/r8180.h
+++ b/drivers/staging/rtl8187se/r8180.h
@@ -366,7 +366,6 @@ typedef struct r8180_priv
short diversity;
u8 cs_treshold;
short rcr_csense;
- short rf_chip;
u32 key0[4];
short (*rf_set_sens)(struct net_device *dev,short sens);
void (*rf_set_chan)(struct net_device *dev,short ch);
@@ -479,9 +478,6 @@ typedef struct r8180_priv
u8 retry_rts;
u16 rts;
-//add for RF power on power off by lizhaoming 080512
- u8 RegThreeWireMode; // See "Three wire mode" defined above, 2006.05.31, by rcnjko.
-
//by amy for led
LED_STRATEGY_8185 LedStrategy;
//by amy for led
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.c b/drivers/staging/rtl8187se/r8180_93cx6.c
deleted file mode 100644
index 7e4711fb930..00000000000
--- a/drivers/staging/rtl8187se/r8180_93cx6.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- This files contains card eeprom (93c46 or 93c56) programming routines,
- memory is addressed by 16 bits words.
-
- This is part of rtl8180 OpenSource driver.
- Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
- Released under the terms of GPL (General Public Licence)
-
- Parts of this driver are based on the GPL part of the
- official realtek driver.
-
- Parts of this driver are based on the rtl8180 driver skeleton
- from Patric Schenke & Andres Salomon.
-
- Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
-
- We want to tanks the Authors of those projects and the Ndiswrapper
- project Authors.
-*/
-
-#include "r8180_93cx6.h"
-
-void eprom_cs(struct net_device *dev, short bit)
-{
- if(bit)
- write_nic_byte(dev, EPROM_CMD,
- (1<<EPROM_CS_SHIFT) | \
- read_nic_byte(dev, EPROM_CMD)); //enable EPROM
- else
- write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
- &~(1<<EPROM_CS_SHIFT)); //disable EPROM
-
- force_pci_posting(dev);
- udelay(EPROM_DELAY);
-}
-
-
-void eprom_ck_cycle(struct net_device *dev)
-{
- write_nic_byte(dev, EPROM_CMD,
- (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
- force_pci_posting(dev);
- udelay(EPROM_DELAY);
- write_nic_byte(dev, EPROM_CMD,
- read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
- force_pci_posting(dev);
- udelay(EPROM_DELAY);
-}
-
-
-void eprom_w(struct net_device *dev,short bit)
-{
- if(bit)
- write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
- read_nic_byte(dev,EPROM_CMD));
- else
- write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
- &~(1<<EPROM_W_SHIFT));
-
- force_pci_posting(dev);
- udelay(EPROM_DELAY);
-}
-
-
-short eprom_r(struct net_device *dev)
-{
- short bit;
-
- bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
- udelay(EPROM_DELAY);
-
- if(bit) return 1;
- return 0;
-}
-
-
-void eprom_send_bits_string(struct net_device *dev, short b[], int len)
-{
- int i;
-
- for(i=0; i<len; i++){
- eprom_w(dev, b[i]);
- eprom_ck_cycle(dev);
- }
-}
-
-
-u32 eprom_read(struct net_device *dev, u32 addr)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- short read_cmd[]={1,1,0};
- short addr_str[8];
- int i;
- int addr_len;
- u32 ret;
-
- ret=0;
- //enable EPROM programming
- write_nic_byte(dev, EPROM_CMD,
- (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
- force_pci_posting(dev);
- udelay(EPROM_DELAY);
-
- if (priv->epromtype==EPROM_93c56){
- addr_str[7]=addr & 1;
- addr_str[6]=addr & (1<<1);
- addr_str[5]=addr & (1<<2);
- addr_str[4]=addr & (1<<3);
- addr_str[3]=addr & (1<<4);
- addr_str[2]=addr & (1<<5);
- addr_str[1]=addr & (1<<6);
- addr_str[0]=addr & (1<<7);
- addr_len=8;
- }else{
- addr_str[5]=addr & 1;
- addr_str[4]=addr & (1<<1);
- addr_str[3]=addr & (1<<2);
- addr_str[2]=addr & (1<<3);
- addr_str[1]=addr & (1<<4);
- addr_str[0]=addr & (1<<5);
- addr_len=6;
- }
- eprom_cs(dev, 1);
- eprom_ck_cycle(dev);
- eprom_send_bits_string(dev, read_cmd, 3);
- eprom_send_bits_string(dev, addr_str, addr_len);
-
- //keep chip pin D to low state while reading.
- //I'm unsure if it is necessary, but anyway shouldn't hurt
- eprom_w(dev, 0);
-
- for(i=0;i<16;i++){
- //eeprom needs a clk cycle between writing opcode&adr
- //and reading data. (eeprom outs a dummy 0)
- eprom_ck_cycle(dev);
- ret |= (eprom_r(dev)<<(15-i));
- }
-
- eprom_cs(dev, 0);
- eprom_ck_cycle(dev);
-
- //disable EPROM programming
- write_nic_byte(dev, EPROM_CMD,
- (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
- return ret;
-}
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.h b/drivers/staging/rtl8187se/r8180_93cx6.h
index 36ae100f3f1..79e7391ac88 100644
--- a/drivers/staging/rtl8187se/r8180_93cx6.h
+++ b/drivers/staging/rtl8187se/r8180_93cx6.h
@@ -45,13 +45,10 @@
#define EPROM_TXPW_OFDM_CH1_2 0x20
-//#define EPROM_TXPW_CH1_2 0x10
-#define EPROM_TXPW_CH1_2 0x30
-#define EPROM_TXPW_CH3_4 0x11
-#define EPROM_TXPW_CH5_6 0x12
-#define EPROM_TXPW_CH7_8 0x13
-#define EPROM_TXPW_CH9_10 0x14
-#define EPROM_TXPW_CH11_12 0x15
-#define EPROM_TXPW_CH13_14 0x16
-
-u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
+#define EPROM_TXPW_CH1_2 0x30
+
+#define RTL818X_EEPROM_CMD_READ (1 << 0)
+#define RTL818X_EEPROM_CMD_WRITE (1 << 1)
+#define RTL818X_EEPROM_CMD_CK (1 << 2)
+#define RTL818X_EEPROM_CMD_CS (1 << 3)
+
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 1847f38b9f2..55d12e3271d 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -30,7 +30,9 @@
#undef RX_DONT_PASS_UL
#undef DUMMY_RX
+#include <linux/slab.h>
#include <linux/syscalls.h>
+#include <linux/eeprom_93cx6.h>
#include "r8180_hw.h"
#include "r8180.h"
@@ -41,13 +43,6 @@
#include "ieee80211/dot11d.h"
-#ifndef PCI_VENDOR_ID_BELKIN
- #define PCI_VENDOR_ID_BELKIN 0x1799
-#endif
-#ifndef PCI_VENDOR_ID_DLINK
- #define PCI_VENDOR_ID_DLINK 0x1186
-#endif
-
static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
{
.vendor = PCI_VENDOR_ID_REALTEK,
@@ -669,11 +664,8 @@ unsigned char STRENGTH_MAP[] = {
void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual)
{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
u32 temp;
u32 temp2;
- u32 temp3;
- u32 lsb;
u32 q;
u32 orig_qual;
u8 _rssi;
@@ -695,88 +687,6 @@ void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual)
*qual = temp;
temp2 = *rssi;
- switch(priv->rf_chip){
- case RFCHIPID_RFMD:
- lsb = temp2 & 1;
- temp2 &= 0x7e;
- if ( !lsb || !(temp2 <= 0x3c) ) {
- temp2 = 0x64;
- } else {
- temp2 = 100 * temp2 / 0x3c;
- }
- *rssi = temp2 & 0xff;
- _rssi = temp2 & 0xff;
- break;
- case RFCHIPID_INTERSIL:
- lsb = temp2;
- temp2 &= 0xfffffffe;
- temp2 *= 251;
- temp3 = temp2;
- temp2 <<= 6;
- temp3 += temp2;
- temp3 <<= 1;
- temp2 = 0x4950df;
- temp2 -= temp3;
- lsb &= 1;
- if ( temp2 <= 0x3e0000 ) {
- if ( temp2 < 0xffef0000 )
- temp2 = 0xffef0000;
- } else {
- temp2 = 0x3e0000;
- }
- if ( !lsb ) {
- temp2 -= 0xf0000;
- } else {
- temp2 += 0xf0000;
- }
-
- temp3 = 0x4d0000;
- temp3 -= temp2;
- temp3 *= 100;
- temp3 = temp3 / 0x6d;
- temp3 >>= 0x10;
- _rssi = temp3 & 0xff;
- *rssi = temp3 & 0xff;
- break;
- case RFCHIPID_GCT:
- lsb = temp2 & 1;
- temp2 &= 0x7e;
- if ( ! lsb || !(temp2 <= 0x3c) ){
- temp2 = 0x64;
- } else {
- temp2 = (100 * temp2) / 0x3c;
- }
- *rssi = temp2 & 0xff;
- _rssi = temp2 & 0xff;
- break;
- case RFCHIPID_PHILIPS:
- if( orig_qual <= 0x4e ){
- _rssi = STRENGTH_MAP[orig_qual];
- *rssi = _rssi;
- } else {
- orig_qual -= 0x80;
- if ( !orig_qual ){
- _rssi = 1;
- *rssi = 1;
- } else {
- _rssi = 0x32;
- *rssi = 0x32;
- }
- }
- break;
- case RFCHIPID_MAXIM:
- lsb = temp2 & 1;
- temp2 &= 0x7e;
- temp2 >>= 1;
- temp2 += 0x42;
- if( lsb != 0 ){
- temp2 += 0xa;
- }
- *rssi = temp2 & 0xff;
- _rssi = temp2 & 0xff;
- break;
- }
-
if ( _rssi < 0x64 ){
if ( _rssi == 0 ) {
*rssi = 1;
@@ -1421,11 +1331,9 @@ u16 N_DBPSOfRate(u16 DataRate)
return N_DBPS;
}
-//{by amy 080312
//
// Description:
// For Netgear case, they want good-looking singal strength.
-// 2004.12.05, by rcnjko.
//
long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
{
@@ -1481,7 +1389,6 @@ long TranslateToDbm8185(u8 SignalStrengthIndex)
// This is different with PerformSignalSmoothing8185 in smoothing fomula.
// No dramatic adjustion is apply because dynamic mechanism need some degree
// of correctness. Ported from 8187B.
-// 2007-02-26, by Bruce.
//
void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
bool bCckRate)
@@ -1502,7 +1409,6 @@ void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
priv->CurCCKRSSI = 0;
}
-//by amy 080312}
/* This is rough RX isr handling routine*/
void rtl8180_rx(struct net_device *dev)
@@ -1638,7 +1544,7 @@ void rtl8180_rx(struct net_device *dev)
}
signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16);
- signal=(signal&0xfe)>>1; // Modify by hikaru 6.6
+ signal = (signal & 0xfe) >> 1;
quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff));
@@ -1652,7 +1558,6 @@ void rtl8180_rx(struct net_device *dev)
stats.rate = rtl8180_rate2rate(rate);
Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ;
-//by amy for antenna
if(!rtl8180_IsWirelessBMode(stats.rate))
{ // OFDM rate.
@@ -1691,11 +1596,10 @@ void rtl8180_rx(struct net_device *dev)
RXAGC=(95-RXAGC)*100/65;
}
priv->SignalStrength = (u8)RXAGC;
- priv->RecvSignalPower = RxAGC_dBm ; // It can use directly by SD3 CMLin
+ priv->RecvSignalPower = RxAGC_dBm;
priv->RxPower = rxpower;
priv->RSSI = RSSI;
-//{by amy 080312
- // SQ translation formular is provided by SD3 DZ. 2006.06.27, by rcnjko.
+ /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */
if(quality >= 127)
quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now;
else if(quality < 27)
@@ -1712,7 +1616,6 @@ void rtl8180_rx(struct net_device *dev)
// printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength);
stats.rssi = priv->wstats.qual.qual = priv->SignalQuality;
stats.noise = priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
-//by amy 080312}
bHwError = (((*(priv->rxringtail))& (0x00000fff)) == 4080)| (((*(priv->rxringtail))& (0x04000000)) != 0 )
| (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 );
bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
@@ -1725,11 +1628,12 @@ void rtl8180_rx(struct net_device *dev)
(eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
&& (!bHwError) && (!bCRC)&& (!bICV))
{
-//by amy 080312
- // Perform signal smoothing for dynamic mechanism on demand.
- // This is different with PerformSignalSmoothing8185 in smoothing fomula.
- // No dramatic adjustion is apply because dynamic mechanism need some degree
- // of correctness. 2007.01.23, by shien chang.
+ /* Perform signal smoothing for dynamic
+ * mechanism on demand. This is different
+ * with PerformSignalSmoothing8185 in smoothing
+ * fomula. No dramatic adjustion is apply
+ * because dynamic mechanism need some degree
+ * of correctness. */
PerformUndecoratedSignalSmoothing8185(priv,bCckRate);
//
// For good-looking singal strength.
@@ -1749,12 +1653,9 @@ void rtl8180_rx(struct net_device *dev)
// Figure out which antenna that received the lasted packet.
priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main.
-//by amy 080312
SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
}
-//by amy for antenna
-#ifndef DUMMY_RX
if(first){
if(!priv->rx_skb_complete){
/* seems that HW sometimes fails to reiceve and
@@ -1810,19 +1711,12 @@ void rtl8180_rx(struct net_device *dev)
if(last && !priv->rx_skb_complete){
if(priv->rx_skb->len > 4)
skb_trim(priv->rx_skb,priv->rx_skb->len-4);
-#ifndef RX_DONT_PASS_UL
if(!ieee80211_rtl_rx(priv->ieee80211,
- priv->rx_skb, &stats)){
-#endif // RX_DONT_PASS_UL
-
+ priv->rx_skb, &stats))
dev_kfree_skb_any(priv->rx_skb);
-#ifndef RX_DONT_PASS_UL
- }
-#endif
priv->rx_skb_complete=1;
}
-#endif //DUMMY_RX
pci_dma_sync_single_for_device(priv->pdev,
priv->rxbuffer->dma,
priv->rxbuffersize * \
@@ -2056,7 +1950,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
u16 RtsDur = 0;
u16 ThisFrameTime = 0;
u16 TxDescDuration = 0;
- u8 ownbit_flag = false; //added by david woo for sync Tx, 2007.12.14
+ u8 ownbit_flag = false;
switch(priority) {
case MANAGE_PRIORITY:
@@ -2123,7 +2017,8 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
//YJ,add,080828,for Keep alive
priv->NumTxUnicast++;
- // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
+ /* Figure out ACK rate according to BSS basic rate
+ * and Tx rate. */
AckTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send
if ( ((len + sCrcLng) > priv->rts) && priv->rts )
@@ -2206,7 +2101,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
*tail |= (1<<15); /* no encrypt */
if(remain==len && !descfrag) {
- ownbit_flag = false; //added by david woo,2007.12.14
+ ownbit_flag = false;
*tail = *tail| (1<<29) ; //fist segment of the packet
*tail = *tail |(len);
} else {
@@ -2556,27 +2451,16 @@ void watch_dog_adaptive(unsigned long data)
}
// Tx High Power Mechanism.
-#ifdef HIGH_POWER
if(CheckHighPower((struct net_device *)data))
- {
queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq);
- }
-#endif
// Tx Power Tracking on 87SE.
-#ifdef TX_TRACK
- //if( priv->bTxPowerTrack ) //lzm mod 080826
- if( CheckTxPwrTracking((struct net_device *)data));
+ if (CheckTxPwrTracking((struct net_device *)data))
TxPwrTracking87SE((struct net_device *)data);
-#endif
// Perform DIG immediately.
-#ifdef SW_DIG
if(CheckDig((struct net_device *)data) == true)
- {
queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq);
- }
-#endif
rtl8180_watch_dog((struct net_device *)data);
queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
@@ -2675,6 +2559,36 @@ static void rtl8180_link_detect_init(plink_detect_t plink_detect)
}
//YJ,add,080828,end
+static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom)
+{
+ struct net_device *dev = eeprom->data;
+ u8 reg = read_nic_byte(dev, EPROM_CMD);
+
+ eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
+ eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
+ eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
+ eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
+}
+
+static void rtl8187se_eeprom_register_write(struct eeprom_93cx6 *eeprom)
+{
+ struct net_device *dev = eeprom->data;
+ u8 reg = 2 << 6;
+
+ if (eeprom->reg_data_in)
+ reg |= RTL818X_EEPROM_CMD_WRITE;
+ if (eeprom->reg_data_out)
+ reg |= RTL818X_EEPROM_CMD_READ;
+ if (eeprom->reg_data_clock)
+ reg |= RTL818X_EEPROM_CMD_CK;
+ if (eeprom->reg_chip_select)
+ reg |= RTL818X_EEPROM_CMD_CS;
+
+ write_nic_byte(dev, EPROM_CMD, reg);
+ read_nic_byte(dev, EPROM_CMD);
+ udelay(10);
+}
+
short rtl8180_init(struct net_device *dev)
{
struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2683,8 +2597,16 @@ short rtl8180_init(struct net_device *dev)
u32 usValue;
u16 tmpu16;
int i, j;
+ struct eeprom_93cx6 eeprom;
+ u16 eeprom_val;
+
+ eeprom.data = dev;
+ eeprom.register_read = rtl8187se_eeprom_register_read;
+ eeprom.register_write = rtl8187se_eeprom_register_write;
+ eeprom.width = PCI_EEPROM_WIDTH_93C46;
- priv->channel_plan = eprom_read(dev, EEPROM_COUNTRY_CODE>>1) & 0xFF;
+ eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val);
+ priv->channel_plan = eeprom_val & 0xFF;
if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
printk("rtl8180_init:Error channel plan! Set to default.\n");
priv->channel_plan = 0;
@@ -2701,8 +2623,6 @@ short rtl8180_init(struct net_device *dev)
priv->txbeaconcount = 2;
priv->rx_skb_complete = 1;
- priv->RegThreeWireMode = HW_THREE_WIRE_SI;
-
priv->RFChangeInProgress = false;
priv->SetRFPowerStateInProgress = false;
priv->RFProgType = 0;
@@ -2747,10 +2667,8 @@ short rtl8180_init(struct net_device *dev)
priv->TxPollingTimes = 0;//lzm add 080826
priv->bLeisurePs = true;
priv->dot11PowerSaveMode = eActive;
-//by amy for antenna
priv->AdMinCheckPeriod = 5;
priv->AdMaxCheckPeriod = 10;
-// Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
priv->AdMaxRxSsThreshold = 30;//60->30
priv->AdRxSsThreshold = 20;//50->20
priv->AdCheckPeriod = priv->AdMinCheckPeriod;
@@ -2765,8 +2683,6 @@ short rtl8180_init(struct net_device *dev)
init_timer(&priv->SwAntennaDiversityTimer);
priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
-//by amy for antenna
-//{by amy 080312
priv->bDigMechanism = 1;
priv->InitialGain = 6;
priv->bXtalCalibration = false;
@@ -2803,58 +2719,63 @@ short rtl8180_init(struct net_device *dev)
priv->NumTxUnicast = 0;
priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
priv->PowerProfile = POWER_PROFILE_AC;
- priv->CurrRetryCnt=0;
- priv->LastRetryCnt=0;
- priv->LastTxokCnt=0;
- priv->LastRxokCnt=0;
- priv->LastRetryRate=0;
- priv->bTryuping=0;
- priv->CurrTxRate=0;
- priv->CurrRetryRate=0;
- priv->TryupingCount=0;
- priv->TryupingCountNoData=0;
- priv->TryDownCountLowData=0;
- priv->LastTxOKBytes=0;
- priv->LastFailTxRate=0;
- priv->LastFailTxRateSS=0;
- priv->FailTxRateCount=0;
- priv->LastTxThroughput=0;
- priv->NumTxOkBytesTotal=0;
+ priv->CurrRetryCnt = 0;
+ priv->LastRetryCnt = 0;
+ priv->LastTxokCnt = 0;
+ priv->LastRxokCnt = 0;
+ priv->LastRetryRate = 0;
+ priv->bTryuping = 0;
+ priv->CurrTxRate = 0;
+ priv->CurrRetryRate = 0;
+ priv->TryupingCount = 0;
+ priv->TryupingCountNoData = 0;
+ priv->TryDownCountLowData = 0;
+ priv->LastTxOKBytes = 0;
+ priv->LastFailTxRate = 0;
+ priv->LastFailTxRateSS = 0;
+ priv->FailTxRateCount = 0;
+ priv->LastTxThroughput = 0;
+ priv->NumTxOkBytesTotal = 0;
priv->ForcedDataRate = 0;
priv->RegBModeGainStage = 1;
- priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
+ priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
spin_lock_init(&priv->irq_lock);
spin_lock_init(&priv->irq_th_lock);
spin_lock_init(&priv->tx_lock);
spin_lock_init(&priv->ps_lock);
spin_lock_init(&priv->rf_ps_lock);
- sema_init(&priv->wx_sem,1);
- sema_init(&priv->rf_state,1);
- INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq);
- INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq);
- INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update);
- INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);//+by amy 080312
- INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);//+by amy 080312
- INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);//+by amy 080312
-
- INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack);
-
+ sema_init(&priv->wx_sem, 1);
+ sema_init(&priv->rf_state, 1);
+ INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq);
+ INIT_WORK(&priv->tx_irq_wq, (void *)rtl8180_tx_irq_wq);
+ INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,
+ (void *)rtl8180_hw_wakeup_wq);
+ INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,
+ (void *)rtl8180_hw_sleep_wq);
+ INIT_WORK(&priv->ieee80211->wmm_param_update_wq,
+ (void *)rtl8180_wmm_param_update);
+ INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,
+ (void *)rtl8180_rate_adapter);
+ INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,
+ (void *)rtl8180_hw_dig_wq);
+ INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,
+ (void *)rtl8180_tx_pw_wq);
+ INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,
+ (void *) GPIOChangeRFWorkItemCallBack);
tasklet_init(&priv->irq_rx_tasklet,
(void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
(unsigned long)priv);
- init_timer(&priv->watch_dog_timer);
+ init_timer(&priv->watch_dog_timer);
priv->watch_dog_timer.data = (unsigned long)dev;
priv->watch_dog_timer.function = watch_dog_adaptive;
- init_timer(&priv->rateadapter_timer);
- priv->rateadapter_timer.data = (unsigned long)dev;
- priv->rateadapter_timer.function = timer_rate_adaptive;
- priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
- priv->bEnhanceTxPwr=false;
+ init_timer(&priv->rateadapter_timer);
+ priv->rateadapter_timer.data = (unsigned long)dev;
+ priv->rateadapter_timer.function = timer_rate_adaptive;
+ priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
+ priv->bEnhanceTxPwr = false;
priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
priv->ieee80211->set_chan = rtl8180_set_chan;
@@ -2877,30 +2798,28 @@ short rtl8180_init(struct net_device *dev)
priv->CSMethod = (0x01 << 29);
- priv->TransmitConfig =
- 1<<TCR_DurProcMode_OFFSET | //for RTL8185B, duration setting by HW
- (7<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
- (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
- (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
- (0 ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
-
- priv->ReceiveConfig =
- RCR_AMF | RCR_ADF | //accept management/data
- RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
- RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
- (7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
- (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
- (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
+ priv->TransmitConfig = TCR_DurProcMode_OFFSET |
+ (7<<TCR_MXDMA_OFFSET) |
+ (priv->ShortRetryLimit<<TCR_SRL_OFFSET) |
+ (priv->LongRetryLimit<<TCR_LRL_OFFSET) |
+ (0 ? TCR_SAT : 0);
+
+ priv->ReceiveConfig = RCR_AMF | RCR_ADF | RCR_ACF |
+ RCR_AB | RCR_AM | RCR_APM |
+ (7<<RCR_MXDMA_OFFSET) |
+ (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) |
+ (priv->EarlyRxThreshold == 7 ?
+ RCR_ONLYERLPKT : 0);
priv->IntrMask = IMR_TMGDOK | IMR_TBDER | IMR_THPDER |
- IMR_THPDER | IMR_THPDOK |
- IMR_TVODER | IMR_TVODOK |
- IMR_TVIDER | IMR_TVIDOK |
- IMR_TBEDER | IMR_TBEDOK |
- IMR_TBKDER | IMR_TBKDOK |
- IMR_RDU | // To handle the defragmentation not enough Rx descriptors case. Annie, 2006-03-27.
- IMR_RER | IMR_ROK |
- IMR_RQoSOK; // <NOTE> ROK and RQoSOK are mutually exclusive, so, we must handle RQoSOK interrupt to receive QoS frames, 2005.12.09, by rcnjko.
+ IMR_THPDER | IMR_THPDOK |
+ IMR_TVODER | IMR_TVODOK |
+ IMR_TVIDER | IMR_TVIDOK |
+ IMR_TBEDER | IMR_TBEDOK |
+ IMR_TBKDER | IMR_TBKDOK |
+ IMR_RDU |
+ IMR_RER | IMR_ROK |
+ IMR_RQoSOK;
priv->InitialGain = 6;
@@ -2913,7 +2832,8 @@ short rtl8180_init(struct net_device *dev)
// just for sync 85
priv->enable_gpio0 = 0;
- usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET);
+ eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &eeprom_val);
+ usValue = eeprom_val;
DMESG("usValue is 0x%x\n",usValue);
//3Read AntennaDiversity
@@ -2953,54 +2873,46 @@ short rtl8180_init(struct net_device *dev)
else
priv->epromtype=EPROM_93c46;
- dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
- dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
- dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
- dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
- dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
- dev->dev_addr[5]=(eprom_read(dev,MAC_ADR+2) & 0xff00)>>8;
+ eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)
+ dev->dev_addr, 3);
for(i=1,j=0; i<14; i+=2,j++){
- word = eprom_read(dev,EPROM_TXPW_CH1_2 + j);
+ eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word);
priv->chtxpwr[i]=word & 0xff;
priv->chtxpwr[i+1]=(word & 0xff00)>>8;
}
for (i = 1, j = 0; i < 14; i += 2, j++) {
- word = eprom_read(dev, EPROM_TXPW_OFDM_CH1_2 + j);
+ eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word);
priv->chtxpwr_ofdm[i] = word & 0xff;
- priv->chtxpwr_ofdm[i+1] = (word & 0xff00)>>8;
+ priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8;
}
- //3Read crystal calibtration and thermal meter indication on 87SE.
-
- // By SD3 SY's request. Added by Roger, 2007.12.11.
+ /* 3Read crystal calibtration and thermal meter indication on 87SE. */
+ eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16);
- tmpu16 = eprom_read(dev, EEPROM_RSV>>1);
+ /* Crystal calibration for Xin and Xout resp. */
+ priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK;
+ priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK) >> 4;
+ if ((tmpu16 & EEPROM_XTAL_CAL_ENABLE) >> 12)
+ priv->bXtalCalibration = true;
- // Crystal calibration for Xin and Xout resp.
- priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; // 0~7.5pF
- priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK)>>4; // 0~7.5pF
- if((tmpu16 & EEPROM_XTAL_CAL_ENABLE)>>12)
- priv->bXtalCalibration = true;
+ /* Thermal meter reference indication. */
+ priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK) >> 8);
+ if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13)
+ priv->bTxPowerTrack = true;
- // Thermal meter reference indication.
- priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK)>>8);
- if((tmpu16 & EEPROM_THERMAL_METER_ENABLE)>>13)
- priv->bTxPowerTrack = true;
-
- word = eprom_read(dev,EPROM_TXPW_BASE);
+ eeprom_93cx6_read(&eeprom, EPROM_TXPW_BASE, &word);
priv->cck_txpwr_base = word & 0xf;
priv->ofdm_txpwr_base = (word>>4) & 0xf;
- version = eprom_read(dev,EPROM_VERSION);
+ eeprom_93cx6_read(&eeprom, EPROM_VERSION, &version);
DMESG("EEPROM version %x",version);
priv->rcr_csense = 3;
- priv->cs_treshold = (eprom_read(dev, ENERGY_TRESHOLD) & 0xff00) >> 8;
-
- priv->rf_chip = 0xff & eprom_read(dev, RFCHIPID);
+ eeprom_93cx6_read(&eeprom, ENERGY_TRESHOLD, &eeprom_val);
+ priv->cs_treshold = (eeprom_val & 0xff00) >> 8;
- priv->rf_chip = RF_ZEBRA4;
+ eeprom_93cx6_read(&eeprom, RFCHIPID, &eeprom_val);
priv->rf_sleep = rtl8225z4_rf_sleep;
priv->rf_wakeup = rtl8225z4_rf_wakeup;
DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
@@ -3010,7 +2922,6 @@ short rtl8180_init(struct net_device *dev)
priv->rf_set_chan = rtl8225z2_rf_set_chan;
priv->rf_set_sens = NULL;
-
if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
return -ENOMEM;
@@ -3042,11 +2953,7 @@ short rtl8180_init(struct net_device *dev)
TX_BEACON_RING_ADDR))
return -ENOMEM;
-#if !defined(SA_SHIRQ)
if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){
-#else
- if(request_irq(dev->irq, (void *)rtl8180_interrupt, SA_SHIRQ, dev->name, dev)){
-#endif
DMESGE("Error allocating IRQ %d",dev->irq);
return -1;
}else{
@@ -3169,43 +3076,6 @@ void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
rtl8185_write_phy(dev, adr, data | 0x10000);
}
-/* 70*3 = 210 ms
- * I hope this is enougth
- */
-#define MAX_PHY 70
-void write_phy(struct net_device *dev, u8 adr, u8 data)
-{
- u32 phy;
- int i;
-
- phy = 0xff0000;
- phy |= adr;
- phy |= 0x80; /* this should enable writing */
- phy |= (data<<8);
-
- //PHY_ADR, PHY_R and PHY_W are contig and treated as one dword
- write_nic_dword(dev,PHY_ADR, phy);
-
- phy= 0xffff00;
- phy |= adr;
-
- write_nic_dword(dev,PHY_ADR, phy);
- for(i=0;i<MAX_PHY;i++){
- phy=read_nic_dword(dev,PHY_ADR);
- phy= phy & 0xff0000;
- phy= phy >> 16;
- if(phy == data){ //SUCCESS!
- force_pci_posting(dev);
- mdelay(3); //random value
- return;
- }else{
- force_pci_posting(dev);
- mdelay(3); //random value
- }
- }
- DMESGW ("Phy writing %x %x failed!", adr,data);
-}
-
void rtl8185_set_rate(struct net_device *dev)
{
int i;
@@ -3335,7 +3205,6 @@ static struct net_device_stats *rtl8180_stats(struct net_device *dev)
}
//
// Change current and default preamble mode.
-// 2005.01.06, by rcnjko.
//
bool
MgntActSet_802_11_PowerSaveMode(
@@ -3454,7 +3323,6 @@ void rtl8180_watch_dog(struct net_device *dev)
MgntLinkKeepAlive(priv);
//YJ,add,080828,for LPS
-#ifdef ENABLE_LPS
if (priv->PowerProfile == POWER_PROFILE_BATTERY)
priv->bLeisurePs = true;
else if (priv->PowerProfile == POWER_PROFILE_AC) {
@@ -3464,7 +3332,6 @@ void rtl8180_watch_dog(struct net_device *dev)
if(priv->ieee80211->state == IEEE80211_LINKED){
priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod;
- //printk("TxOk=%d RxOk=%d\n", priv->link_detect.NumTxOkInPeriod, priv->link_detect.NumRxOkInPeriod);
if( priv->link_detect.NumRxOkInPeriod> 666 ||
priv->link_detect.NumTxOkInPeriod> 666 ) {
bBusyTraffic = true;
@@ -3481,7 +3348,6 @@ void rtl8180_watch_dog(struct net_device *dev)
LeisurePSLeave(priv);
} else
LeisurePSLeave(priv);
-#endif
priv->link_detect.bBusyTraffic = bBusyTraffic;
priv->link_detect.NumRxOkInPeriod = 0;
priv->link_detect.NumTxOkInPeriod = 0;
@@ -3503,16 +3369,11 @@ int _rtl8180_up(struct net_device *dev)
if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
IPSLeave(dev);
}
-#ifdef RATE_ADAPT
timer_rate_adaptive((unsigned long)dev);
-#endif
watch_dog_adaptive((unsigned long)dev);
-#ifdef SW_ANTE
if(priv->bSwAntennaDiverity)
SwAntennaDiversityTimerCallback(dev);
-#endif
ieee80211_softmac_start_protocol(priv->ieee80211);
-
return 0;
}
@@ -3748,7 +3609,7 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
dev->wireless_handlers = &r8180_wx_handlers_def;
dev->type=ARPHRD_ETHER;
- dev->watchdog_timeo = HZ*3; //added by david woo, 2007.12.13
+ dev->watchdog_timeo = HZ*3;
if (dev_alloc_name(dev, ifname) < 0){
DMESG("Oops: devname already taken! Trying wlan%%d...\n");
@@ -3864,8 +3725,7 @@ static int __init rtl8180_pci_module_init(void)
return ret;
}
- printk(KERN_INFO "\nLinux kernel driver for RTL8180 \
-/ RTL8185 based WLAN cards\n");
+ printk(KERN_INFO "\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n");
printk(KERN_INFO "Copyright (c) 2004-2005, Andrea Merello\n");
DMESG("Initializing module");
DMESG("Wireless extensions version %d", WIRELESS_EXT);
@@ -4236,60 +4096,51 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
static int readf_count = 0;
-#ifdef ENABLE_LPS
if(readf_count % 10 == 0)
priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state");
readf_count = (readf_count+1)%0xffff;
-#endif
- {
- // We should turn off LED before polling FF51[4].
+ /* We should turn off LED before polling FF51[4]. */
- //Turn off LED.
- btPSR = read_nic_byte(dev, PSR);
- write_nic_byte(dev, PSR, (btPSR & ~BIT3));
+ /* Turn off LED. */
+ btPSR = read_nic_byte(dev, PSR);
+ write_nic_byte(dev, PSR, (btPSR & ~BIT3));
- //It need to delay 4us suggested by Jong, 2008-01-16
- udelay(4);
+ /* It need to delay 4us suggested by Jong, 2008-01-16 */
+ udelay(4);
- //HW radio On/Off according to the value of FF51[4](config0)
- btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
+ /* HW radio On/Off according to the value of FF51[4](config0) */
+ btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
- //Turn on LED.
- write_nic_byte(dev, PSR, btPSR| BIT3);
+ eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff;
- eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff;
+ /* Turn LED back on when radio enabled */
+ if (eRfPowerStateToSet == eRfOn)
+ write_nic_byte(dev, PSR, btPSR | BIT3);
- if((priv->ieee80211->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
- {
- priv->ieee80211->bHwRadioOff = false;
- bActuallySet = true;
- }
- else if((priv->ieee80211->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
- {
- priv->ieee80211->bHwRadioOff = true;
- bActuallySet = true;
- }
+ if ((priv->ieee80211->bHwRadioOff == true) &&
+ (eRfPowerStateToSet == eRfOn)) {
+ priv->ieee80211->bHwRadioOff = false;
+ bActuallySet = true;
+ } else if ((priv->ieee80211->bHwRadioOff == false) &&
+ (eRfPowerStateToSet == eRfOff)) {
+ priv->ieee80211->bHwRadioOff = true;
+ bActuallySet = true;
+ }
- if(bActuallySet)
- {
- MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
-
- /* To update the UI status for Power status changed */
- if(priv->ieee80211->bHwRadioOff == true)
- argv[1] = "RFOFF";
- else{
- //if(!priv->RfOffReason)
- argv[1] = "RFON";
- //else
- // argv[1] = "RFOFF";
- }
- argv[0] = RadioPowerPath;
- argv[2] = NULL;
-
- call_usermodehelper(RadioPowerPath,argv,envp,1);
- }
- }
+ if (bActuallySet) {
+ MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
+
+ /* To update the UI status for Power status changed */
+ if (priv->ieee80211->bHwRadioOff == true)
+ argv[1] = "RFOFF";
+ else
+ argv[1] = "RFON";
+ argv[0] = RadioPowerPath;
+ argv[2] = NULL;
+
+ call_usermodehelper(RadioPowerPath, argv, envp, 1);
+ }
}
static u8 read_acadapter_file(char *filename)
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
index cbca58db85e..fc4907839c5 100644
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ b/drivers/staging/rtl8187se/r8180_dm.c
@@ -282,30 +282,13 @@ DIG_Zebra(
// Dispatch DIG implementation according to RF.
//
void
-DynamicInitGain(
- struct net_device *dev
- )
+DynamicInitGain(struct net_device *dev)
{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
- case RF_ZEBRA4:
- DIG_Zebra( dev );
- break;
-
- default:
- printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
- break;
- }
+ DIG_Zebra(dev);
}
void rtl8180_hw_dig_wq (struct work_struct *work)
{
-// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
-// struct ieee80211_device * ieee = (struct ieee80211_device*)
-// container_of(work, struct ieee80211_device, watch_dog_wq);
struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
struct net_device *dev = ieee->dev;
@@ -1310,44 +1293,24 @@ SetAntenna8185(
switch(u1bAntennaIndex)
{
case 0:
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
- // Mac register, main antenna
- write_nic_byte(dev, ANTSEL, 0x03);
- //base band
- write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
-
-
- bAntennaSwitched = true;
- break;
+ /* Mac register, main antenna */
+ write_nic_byte(dev, ANTSEL, 0x03);
+ /* base band */
+ write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */
+ write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */
- default:
- printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip);
- break;
- }
+ bAntennaSwitched = true;
break;
case 1:
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
- // Mac register, aux antenna
- write_nic_byte(dev, ANTSEL, 0x00);
- //base band
- write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
-
- bAntennaSwitched = true;
- break;
+ /* Mac register, aux antenna */
+ write_nic_byte(dev, ANTSEL, 0x00);
+ /* base band */
+ write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */
+ write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */
+
+ bAntennaSwitched = true;
- default:
- printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip);
- break;
- }
break;
default:
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
index afe10f0b75a..6edf5a46fa4 100644
--- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c
+++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
@@ -854,134 +854,48 @@ bool SetZebraRFPowerState8185(struct net_device *dev,
btConfig3 = read_nic_byte(dev, CONFIG3);
write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En));
- switch (priv->rf_chip) {
- case RF_ZEBRA2:
- switch (eRFPowerState) {
- case eRfOn:
- RF_WriteReg(dev,0x4,0x9FF);
+ switch (eRFPowerState) {
+ case eRfOn:
+ write_nic_word(dev, 0x37C, 0x00EC);
- write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
- write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
+ /* turn on AFE */
+ write_nic_byte(dev, 0x54, 0x00);
+ write_nic_byte(dev, 0x62, 0x00);
- write_nic_byte(dev, CONFIG4, priv->RFProgType);
+ /* turn on RF */
+ RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
+ RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
- /* turn on CCK and OFDM */
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
- break;
- case eRfSleep:
- break;
- case eRfOff:
- break;
- default:
- bResult = false;
- break;
- }
- break;
- case RF_ZEBRA4:
- switch (eRFPowerState) {
- case eRfOn:
- write_nic_word(dev, 0x37C, 0x00EC);
-
- /* turn on AFE */
- write_nic_byte(dev, 0x54, 0x00);
- write_nic_byte(dev, 0x62, 0x00);
-
- /* turn on RF */
- RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
- RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
- /* turn on RF again */
- RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
- RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
+ /* turn on RF again */
+ RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
+ RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
- /* turn on BB */
- write_phy_ofdm(dev,0x10,0x40);
- write_phy_ofdm(dev,0x12,0x40);
-
- /* Avoid power down at init time. */
- write_nic_byte(dev, CONFIG4, priv->RFProgType);
-
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
- break;
- case eRfSleep:
- for (QueueID = 0, i = 0; QueueID < 6;) {
- if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
- QueueID++;
- continue;
- } else {
- priv->TxPollingTimes ++;
- if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
- bActionAllowed = false;
- break;
- } else
- udelay(10);
- }
- }
+ /* turn on BB */
+ write_phy_ofdm(dev, 0x10, 0x40);
+ write_phy_ofdm(dev, 0x12, 0x40);
- if (bActionAllowed) {
- /* turn off BB RXIQ matrix to cut off rx signal */
- write_phy_ofdm(dev, 0x10, 0x00);
- write_phy_ofdm(dev, 0x12, 0x00);
-
- /* turn off RF */
- RF_WriteReg(dev, 0x4, 0x0000);
- RF_WriteReg(dev, 0x0, 0x0000);
-
- /* turn off AFE except PLL */
- write_nic_byte(dev, 0x62, 0xff);
- write_nic_byte(dev, 0x54, 0xec);
-
- mdelay(1);
-
- {
- int i = 0;
- while (true) {
- u8 tmp24F = read_nic_byte(dev, 0x24f);
-
- if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
- bTurnOffBB = true;
- break;
- } else {
- udelay(10);
- i++;
- priv->TxPollingTimes++;
-
- if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
- bTurnOffBB = false;
- break;
- } else
- udelay(10);
- }
- }
- }
-
- if (bTurnOffBB) {
- /* turn off BB */
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
-
- /* turn off AFE PLL */
- write_nic_byte(dev, 0x54, 0xFC);
- write_nic_word(dev, 0x37C, 0x00FC);
- }
- }
- break;
- case eRfOff:
- for (QueueID = 0, i = 0; QueueID < 6;) {
- if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
- QueueID++;
- continue;
- } else {
- udelay(10);
- i++;
- }
+ /* Avoid power down at init time. */
+ write_nic_byte(dev, CONFIG4, priv->RFProgType);
- if (i >= MAX_DOZE_WAITING_TIMES_85B)
+ u1bTmp = read_nic_byte(dev, 0x24E);
+ write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
+ break;
+ case eRfSleep:
+ for (QueueID = 0, i = 0; QueueID < 6;) {
+ if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
+ QueueID++;
+ continue;
+ } else {
+ priv->TxPollingTimes++;
+ if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
+ bActionAllowed = false;
break;
+ } else
+ udelay(10);
}
+ }
+ if (bActionAllowed) {
/* turn off BB RXIQ matrix to cut off rx signal */
write_phy_ofdm(dev, 0x10, 0x00);
write_phy_ofdm(dev, 0x12, 0x00);
@@ -998,22 +912,23 @@ bool SetZebraRFPowerState8185(struct net_device *dev,
{
int i = 0;
-
- while (true)
- {
+ while (true) {
u8 tmp24F = read_nic_byte(dev, 0x24f);
if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
bTurnOffBB = true;
break;
} else {
- bTurnOffBB = false;
udelay(10);
i++;
- }
+ priv->TxPollingTimes++;
- if (i > MAX_POLLING_24F_TIMES_87SE)
- break;
+ if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
+ bTurnOffBB = false;
+ break;
+ } else
+ udelay(10);
+ }
}
}
@@ -1022,15 +937,68 @@ bool SetZebraRFPowerState8185(struct net_device *dev,
u1bTmp = read_nic_byte(dev, 0x24E);
write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
- /* turn off AFE PLL (80M) */
+ /* turn off AFE PLL */
write_nic_byte(dev, 0x54, 0xFC);
write_nic_word(dev, 0x37C, 0x00FC);
}
- break;
- default:
- bResult = false;
- printk("SetZebraRFPowerState8185(): unknown state to set: 0x%X!!!\n", eRFPowerState);
- break;
+ }
+ break;
+ case eRfOff:
+ for (QueueID = 0, i = 0; QueueID < 6;) {
+ if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
+ QueueID++;
+ continue;
+ } else {
+ udelay(10);
+ i++;
+ }
+
+ if (i >= MAX_DOZE_WAITING_TIMES_85B)
+ break;
+ }
+
+ /* turn off BB RXIQ matrix to cut off rx signal */
+ write_phy_ofdm(dev, 0x10, 0x00);
+ write_phy_ofdm(dev, 0x12, 0x00);
+
+ /* turn off RF */
+ RF_WriteReg(dev, 0x4, 0x0000);
+ RF_WriteReg(dev, 0x0, 0x0000);
+
+ /* turn off AFE except PLL */
+ write_nic_byte(dev, 0x62, 0xff);
+ write_nic_byte(dev, 0x54, 0xec);
+
+ mdelay(1);
+
+ {
+ int i = 0;
+
+ while (true) {
+ u8 tmp24F = read_nic_byte(dev, 0x24f);
+
+ if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
+ bTurnOffBB = true;
+ break;
+ } else {
+ bTurnOffBB = false;
+ udelay(10);
+ i++;
+ }
+
+ if (i > MAX_POLLING_24F_TIMES_87SE)
+ break;
+ }
+ }
+
+ if (bTurnOffBB) {
+ /* turn off BB */
+ u1bTmp = read_nic_byte(dev, 0x24E);
+ write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
+
+ /* turn off AFE PLL (80M) */
+ write_nic_byte(dev, 0x54, 0xFC);
+ write_nic_word(dev, 0x37C, 0x00FC);
}
break;
}
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
index 50309f2da9c..a0ece1fd64a 100644
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ b/drivers/staging/rtl8187se/r8185b_init.c
@@ -238,100 +238,12 @@ PlatformIORead4Byte(
return data;
}
-void
-SetOutputEnableOfRfPins(
- struct net_device *dev
- )
+void SetOutputEnableOfRfPins(struct net_device *dev)
{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- switch(priv->rf_chip)
- {
- case RFCHIPID_RTL8225:
- case RF_ZEBRA2:
- case RF_ZEBRA4:
- write_nic_word(dev, RFPinsEnable, 0x1bff);
- //write_nic_word(dev, RFPinsEnable, 0x1fff);
- break;
- }
+ write_nic_word(dev, RFPinsEnable, 0x1bff);
}
-void
-ZEBRA_RFSerialWrite(
- struct net_device *dev,
- u32 data2Write,
- u8 totalLength,
- u8 low2high
- )
-{
- ThreeWireReg twreg;
- int i;
- u16 oval,oval2,oval3;
- u32 mask;
- u16 UshortBuffer;
-
- u8 u1bTmp;
- // RTL8187S HSSI Read/Write Function
- u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
- u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
- write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
- UshortBuffer = read_nic_word(dev, RFPinsOutput);
- oval = UshortBuffer & 0xfff8; // We shall clear bit0, 1, 2 first, 2005.10.28, by rcnjko.
-
- oval2 = read_nic_word(dev, RFPinsEnable);
- oval3 = read_nic_word(dev, RFPinsSelect);
-
- // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
- oval3 &= 0xfff8;
-
- write_nic_word(dev, RFPinsEnable, (oval2|0x0007)); // Set To Output Enable
- write_nic_word(dev, RFPinsSelect, (oval3|0x0007)); // Set To SW Switch
- udelay(10);
-
- // Add this to avoid hardware and software 3-wire conflict.
- // 2005.03.01, by rcnjko.
- twreg.longData = 0;
- twreg.struc.enableB = 1;
- write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Set SI_EN (RFLE)
- udelay(2);
- twreg.struc.enableB = 0;
- write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Clear SI_EN (RFLE)
- udelay(10);
-
- mask = (low2high)?0x01:((u32)0x01<<(totalLength-1));
-
- for(i=0; i<totalLength/2; i++)
- {
- twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
- write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
- twreg.struc.clk = 1;
- write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
- write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
-
- mask = (low2high)?(mask<<1):(mask>>1);
- twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
- write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
- write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
- twreg.struc.clk = 0;
- write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
- mask = (low2high)?(mask<<1):(mask>>1);
- }
-
- twreg.struc.enableB = 1;
- twreg.struc.clk = 0;
- twreg.struc.data = 0;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval);
- udelay(10);
-
- write_nic_word(dev, RFPinsOutput, oval|0x0004);
- write_nic_word(dev, RFPinsSelect, oval3|0x0000);
-
- SetOutputEnableOfRfPins(dev);
-}
-//by amy
-
-
-int
+static int
HwHSSIThreeWire(
struct net_device *dev,
u8 *pDataBuf,
@@ -469,420 +381,30 @@ HwHSSIThreeWire(
return bResult;
}
-//by amy
-
-int
-HwThreeWire(
- struct net_device *dev,
- u8 *pDataBuf,
- u8 nDataBufBitCnt,
- int bHold,
- int bWrite
- )
-{
- int bResult = 1;
- u8 TryCnt;
- u8 u1bTmp;
-
- do
- {
- // Check if WE and RE are cleared.
- for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
- {
- u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
- if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
- {
- break;
- }
- udelay(10);
- }
- if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
- panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
-
- // Fill up data buffer for write operation.
- if(nDataBufBitCnt == 16)
- {
- write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
- }
- else if(nDataBufBitCnt == 64)
- {
- write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
- write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
- }
- else
- {
- int idx;
- int ByteCnt = nDataBufBitCnt / 8;
-
- if ((nDataBufBitCnt % 8) != 0)
- panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
- nDataBufBitCnt);
-
- if (nDataBufBitCnt > 64)
- panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
- nDataBufBitCnt);
-
- for(idx = 0; idx < ByteCnt; idx++)
- {
- write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
- }
- }
-
- // Fill up length field.
- u1bTmp = (u8)(nDataBufBitCnt - 1); // Number of bits - 1.
- if(bHold)
- u1bTmp |= SW_3W_CMD0_HOLD;
- write_nic_byte(dev, SW_3W_CMD0, u1bTmp);
-
- // Set up command: WE or RE.
- if(bWrite)
- {
- write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
- }
- else
- {
- write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
- }
-
- // Check if WE and RE are cleared and DONE is set.
- for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
- {
- u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
- if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 &&
- (u1bTmp & SW_3W_CMD1_DONE) != 0 )
- {
- break;
- }
- udelay(10);
- }
- if(TryCnt == TC_3W_POLL_MAX_TRY_CNT)
- {
- //RT_ASSERT(TryCnt != TC_3W_POLL_MAX_TRY_CNT,
- // ("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear or DONE is not set!!\n", u1bTmp));
- // Workaround suggested by wcchu: clear WE here. 2006.07.07, by rcnjko.
- write_nic_byte(dev, SW_3W_CMD1, 0);
- }
-
- // Read back data for read operation.
- // <RJ_TODO> I am not sure if this is correct output format of a read operation.
- if(bWrite == 0)
- {
- if(nDataBufBitCnt == 16)
- {
- *((u16 *)pDataBuf) = read_nic_word(dev, SW_3W_DB0);
- }
- else if(nDataBufBitCnt == 64)
- {
- *((u32 *)pDataBuf) = read_nic_dword(dev, SW_3W_DB0);
- *((u32 *)(pDataBuf + 4)) = read_nic_dword(dev, SW_3W_DB1);
- }
- else
- {
- int idx;
- int ByteCnt = nDataBufBitCnt / 8;
-
- if ((nDataBufBitCnt % 8) != 0)
- panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
- nDataBufBitCnt);
-
- if (nDataBufBitCnt > 64)
- panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
- nDataBufBitCnt);
-
- for(idx = 0; idx < ByteCnt; idx++)
- {
- *(pDataBuf+idx) = read_nic_byte(dev, (SW_3W_DB0+idx));
- }
- }
- }
-
- }while(0);
-
- return bResult;
-}
-
void
-RF_WriteReg(
- struct net_device *dev,
- u8 offset,
- u32 data
- )
+RF_WriteReg(struct net_device *dev, u8 offset, u32 data)
{
- //RFReg reg;
- u32 data2Write;
- u8 len;
- u8 low2high;
- //u32 RF_Read = 0;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-
- switch(priv->rf_chip)
- {
- case RFCHIPID_RTL8225:
- case RF_ZEBRA2: // Annie 2006-05-12.
- case RF_ZEBRA4: //by amy
- switch(priv->RegThreeWireMode)
- {
- case SW_THREE_WIRE:
- { // Perform SW 3-wire programming by driver.
- data2Write = (data << 4) | (u32)(offset & 0x0f);
- len = 16;
- low2high = 0;
- ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
- }
- break;
+ u32 data2Write;
+ u8 len;
- case HW_THREE_WIRE:
- { // Pure HW 3-wire.
- data2Write = (data << 4) | (u32)(offset & 0x0f);
- len = 16;
- HwThreeWire(
- dev,
- (u8 *)(&data2Write), // pDataBuf,
- len, // nDataBufBitCnt,
- 0, // bHold,
- 1); // bWrite
- }
- break;
- case HW_THREE_WIRE_PI: //Parallel Interface
- { // Pure HW 3-wire.
- data2Write = (data << 4) | (u32)(offset & 0x0f);
- len = 16;
- HwHSSIThreeWire(
- dev,
- (u8*)(&data2Write), // pDataBuf,
- len, // nDataBufBitCnt,
- 0, // bSI
- 1); // bWrite
-
- //printk("33333\n");
- }
- break;
-
- case HW_THREE_WIRE_SI: //Serial Interface
- { // Pure HW 3-wire.
- data2Write = (data << 4) | (u32)(offset & 0x0f);
- len = 16;
-// printk(" enter ZEBRA_RFSerialWrite\n ");
-// low2high = 0;
-// ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
-
- HwHSSIThreeWire(
- dev,
- (u8*)(&data2Write), // pDataBuf,
- len, // nDataBufBitCnt,
- 1, // bSI
- 1); // bWrite
-
-// printk(" exit ZEBRA_RFSerialWrite\n ");
- }
- break;
-
-
- default:
- DMESGE("RF_WriteReg(): invalid RegThreeWireMode(%d) !!!", priv->RegThreeWireMode);
- break;
- }
- break;
-
- default:
- DMESGE("RF_WriteReg(): unknown RFChipID: %#X", priv->rf_chip);
- break;
- }
-}
-
-
-void
-ZEBRA_RFSerialRead(
- struct net_device *dev,
- u32 data2Write,
- u8 wLength,
- u32 *data2Read,
- u8 rLength,
- u8 low2high
- )
-{
- ThreeWireReg twreg;
- int i;
- u16 oval,oval2,oval3,tmp, wReg80;
- u32 mask;
- u8 u1bTmp;
- ThreeWireReg tdata;
- //PHAL_DATA_8187 pHalData = GetHalData8187(pAdapter);
- { // RTL8187S HSSI Read/Write Function
- u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
- u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
- write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
- }
-
- wReg80 = oval = read_nic_word(dev, RFPinsOutput);
- oval2 = read_nic_word(dev, RFPinsEnable);
- oval3 = read_nic_word(dev, RFPinsSelect);
-
- write_nic_word(dev, RFPinsEnable, oval2|0xf);
- write_nic_word(dev, RFPinsSelect, oval3|0xf);
-
- *data2Read = 0;
-
- // We must clear BIT0-3 here, otherwise,
- // SW_Enalbe will be true when we first call ZEBRA_RFSerialRead() after 8187MPVC open,
- // which will cause the value read become 0. 2005.04.11, by rcnjko.
- oval &= ~0xf;
-
- // Avoid collision with hardware three-wire.
- twreg.longData = 0;
- twreg.struc.enableB = 1;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(4);
-
- twreg.longData = 0;
- twreg.struc.enableB = 0;
- twreg.struc.clk = 0;
- twreg.struc.read_write = 0;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(5);
-
- mask = (low2high) ? 0x01 : ((u32)0x01<<(32-1));
- for(i = 0; i < wLength/2; i++)
- {
- twreg.struc.data = ((data2Write&mask) != 0) ? 1 : 0;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
- twreg.struc.clk = 1;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-
- mask = (low2high) ? (mask<<1): (mask>>1);
-
- if(i == 2)
- {
- // Commented out by Jackie, 2004.08.26. <RJ_NOTE> We must comment out the following two lines for we cannot pull down VCOPDN during RF Serail Read.
- //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0xe); // turn off data enable
- //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0xe);
-
- twreg.struc.read_write=1;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
- twreg.struc.clk = 0;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
- break;
- }
- twreg.struc.data = ((data2Write&mask) != 0) ? 1: 0;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-
- twreg.struc.clk = 0;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
-
- mask = (low2high) ? (mask<<1) : (mask>>1);
- }
-
- twreg.struc.clk = 0;
- twreg.struc.data = 0;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
- mask = (low2high) ? 0x01 : ((u32)0x01 << (12-1));
-
- //
- // 061016, by rcnjko:
- // We must set data pin to HW controled, otherwise RF can't driver it and
- // value RF register won't be able to read back properly.
- //
- write_nic_word(dev, RFPinsEnable, ( ((oval2|0x0E) & (~0x01))) );
+ /* Pure HW 3-wire. */
+ data2Write = (data << 4) | (u32)(offset & 0x0f);
+ len = 16;
- for(i = 0; i < rLength; i++)
- {
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
- twreg.struc.clk = 1;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
- tmp = read_nic_word(dev, RFPinsInput);
- tdata.longData = tmp;
- *data2Read |= tdata.struc.clk ? mask : 0;
-
- twreg.struc.clk = 0;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-
- mask = (low2high) ? (mask<<1) : (mask>>1);
- }
- twreg.struc.enableB = 1;
- twreg.struc.clk = 0;
- twreg.struc.data = 0;
- twreg.struc.read_write = 1;
- write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
-
- //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, oval2|0x8); // Set To Output Enable
- write_nic_word(dev, RFPinsEnable, oval2); // Set To Output Enable, <RJ_NOTE> We cannot enable BIT3 here, otherwise, we will failed to switch channel. 2005.04.12.
- //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0x1bff);
- write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
- //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0x0488);
- write_nic_word(dev, RFPinsOutput, 0x3a0);
- //PlatformEFIOWrite2Byte(pAdapter, RFPinsOutput, 0x0480);
+ HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1);
}
-
-u32
-RF_ReadReg(
- struct net_device *dev,
- u8 offset
- )
+u32 RF_ReadReg(struct net_device *dev, u8 offset)
{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 data2Write;
- u8 wlen;
- u8 rlen;
- u8 low2high;
- u32 dataRead;
+ u32 data2Write;
+ u8 wlen;
+ u32 dataRead;
- switch(priv->rf_chip)
- {
- case RFCHIPID_RTL8225:
- case RF_ZEBRA2:
- case RF_ZEBRA4:
- switch(priv->RegThreeWireMode)
- {
- case HW_THREE_WIRE_PI: // For 87S Parallel Interface.
- {
- data2Write = ((u32)(offset&0x0f));
- wlen=16;
- HwHSSIThreeWire(
- dev,
- (u8*)(&data2Write), // pDataBuf,
- wlen, // nDataBufBitCnt,
- 0, // bSI
- 0); // bWrite
- dataRead= data2Write;
- }
- break;
-
- case HW_THREE_WIRE_SI: // For 87S Serial Interface.
- {
- data2Write = ((u32)(offset&0x0f)) ;
- wlen=16;
- HwHSSIThreeWire(
- dev,
- (u8*)(&data2Write), // pDataBuf,
- wlen, // nDataBufBitCnt,
- 1, // bSI
- 0 // bWrite
- );
- dataRead= data2Write;
- }
- break;
-
- // Perform SW 3-wire programming by driver.
- default:
- {
- data2Write = ((u32)(offset&0x1f)) << 27; // For Zebra E-cut. 2005.04.11, by rcnjko.
- wlen = 6;
- rlen = 12;
- low2high = 0;
- ZEBRA_RFSerialRead(dev, data2Write, wlen,&dataRead,rlen, low2high);
- }
- break;
- }
- break;
- default:
- dataRead = 0;
- break;
- }
+ data2Write = ((u32)(offset & 0x0f));
+ wlen = 16;
+ HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0);
+ dataRead = data2Write;
return dataRead;
}
@@ -1043,15 +565,12 @@ ZEBRA_Config_85BASIC_HardCode(
// Page0 : reg0-reg15
-// RF_WriteReg(dev, 0x00, 0x003f); mdelay(1);//1
RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);// 1
RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
-// RF_WriteReg(dev, 0x02, 0x004c); mdelay(1);//2
RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);// 2
-// RF_WriteReg(dev, 0x03, 0x0000); mdelay(1);//3
RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);// 3
RF_WriteReg(dev, 0x04, 0x0975); mdelay(1);
@@ -1080,8 +599,6 @@ ZEBRA_Config_85BASIC_HardCode(
RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
// Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl.
-// RF_WriteReg(dev, 0x08, 0x0597); mdelay(1);
-// RF_WriteReg(dev, 0x09, 0x050a); mdelay(1);
RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
@@ -1097,7 +614,6 @@ ZEBRA_Config_85BASIC_HardCode(
RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
-// RF_WriteReg(dev, 0x00, 0x017f); mdelay(1);//6
RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1);// 6
RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
@@ -1106,20 +622,14 @@ ZEBRA_Config_85BASIC_HardCode(
{
RF_WriteReg(dev, 0x01, i); mdelay(1);
RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
- //DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
}
RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /// 203, 343
- //RF_WriteReg(dev, 0x06, 0x0300); mdelay(1); // 400
RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); // 400
RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30, and HSSI disable 137
mdelay(10); // Deay 10 ms. //0xfd
-// RF_WriteReg(dev, 0x0c, 0x09be); mdelay(1); // 7
- //RF_WriteReg(dev, 0x0c, 0x07be); mdelay(1);
- //mdelay(10); // Deay 10 ms. //0xfd
-
RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); // Z4 synthesizer loop filter setting, 392
mdelay(10); // Deay 10 ms. //0xfd
@@ -1165,10 +675,8 @@ ZEBRA_Config_85BASIC_HardCode(
RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
}
//by amy 080312
-// RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); //-by amy 080312
RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); // switch to reg0-reg15, and HSSI enable
-// RF_WriteReg(dev, 0x0d, 0x009f); mdelay(1); // Rx BB start calibration, 00c//-edward
RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); // Rx BB start calibration, 00c//+edward
RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); // temperature meter off
RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); // Rx mode
@@ -1217,13 +725,10 @@ ZEBRA_Config_85BASIC_HardCode(
// AGC.txt
//=============================================================================
-// PlatformIOWrite4Byte( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
write_phy_ofdm(dev, 0x00, 0x12);
- //WriteBBPortUchar(dev, 0x00001280);
for (i=0; i<128; i++)
{
- //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
data = ZEBRA_AGC[i+1];
data = data << 8;
@@ -1239,7 +744,6 @@ ZEBRA_Config_85BASIC_HardCode(
}
PlatformIOWrite4Byte( dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
- //WriteBBPortUchar(dev, 0x00001080);
//=============================================================================
@@ -1252,8 +756,6 @@ ZEBRA_Config_85BASIC_HardCode(
u4bRegOffset=i;
u4bRegValue=OFDM_CONFIG[i];
- //DbgPrint("OFDM - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
-
WriteBBPortUchar(dev,
(0x00000080 |
(u4bRegOffset & 0x7f) |
@@ -1277,9 +779,6 @@ UpdateInitialGain(
)
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- //unsigned char* IGTable;
- //u8 DIG_CurrentInitialGain = 4;
- //unsigned char u1Tmp;
//lzm add 080826
if(priv->eRFPowerState != eRfOn)
@@ -1291,81 +790,59 @@ UpdateInitialGain(
return;
}
- switch(priv->rf_chip)
- {
- case RF_ZEBRA4:
- // Dynamic set initial gain, follow 87B
- switch(priv->InitialGain)
- {
- case 1: //m861dBm
- //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm \n");
- write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
-
- case 2: //m862dBm
- //DMESG("RTL8187 + 8225 Initial Gain State 2: -82 dBm \n");
- write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
-
- case 3: //m863dBm
- //DMESG("RTL8187 + 8225 Initial Gain State 3: -82 dBm \n");
- write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
-
- case 4: //m864dBm
- //DMESG("RTL8187 + 8225 Initial Gain State 4: -78 dBm \n");
- write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
+ switch (priv->InitialGain) {
+ case 1: /* m861dBm */
+ write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
+ break;
- case 5: //m82dBm
- //DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm \n");
- write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
+ case 2: /* m862dBm */
+ write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
+ break;
- case 6: //m78dBm
- //DMESG ("RTL8187 + 8225 Initial Gain State 6: -70 dBm \n");
- write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
+ case 3: /* m863dBm */
+ write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
+ break;
- case 7: //m74dBm
- //DMESG("RTL8187 + 8225 Initial Gain State 7: -66 dBm \n");
- write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
+ case 4: /* m864dBm */
+ write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
+ break;
- case 8:
- //DMESG("RTL8187 + 8225 Initial Gain State 8:\n");
- write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
+ case 5: /* m82dBm */
+ write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
+ break;
+ case 6: /* m78dBm */
+ write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
+ break;
- default: //MP
- //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm (default)\n");
- write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
- }
+ case 7: /* m74dBm */
+ write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
break;
+ case 8:
+ write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
+ break;
- default:
- DMESG("UpdateInitialGain(): unknown RFChipID: %#X\n", priv->rf_chip);
+ default: /* MP */
+ write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
+ write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
+ write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
break;
}
}
@@ -1379,13 +856,11 @@ InitTxPwrTracking87SE(
struct net_device *dev
)
{
- //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
u32 u4bRfReg;
u4bRfReg = RF_ReadReg(dev, 0x02);
// Enable Thermal meter indication.
- //printk("InitTxPwrTracking87SE(): Enable thermal meter indication, Write RF[0x02] = %#x", u4bRfReg|PWR_METER_EN);
RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
}
@@ -1397,21 +872,14 @@ PhyConfig8185(
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
write_nic_dword(dev, RCR, priv->ReceiveConfig);
priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
- // RF config
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
- ZEBRA_Config_85BASIC_HardCode( dev);
- break;
- }
+ /* RF config */
+ ZEBRA_Config_85BASIC_HardCode(dev);
//{by amy 080312
// Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06.
if(priv->bDigMechanism)
{
if(priv->InitialGain == 0)
priv->InitialGain = 4;
- //printk("PhyConfig8185(): DIG is enabled, set default initial gain index to %d\n", priv->InitialGain);
}
//
@@ -1429,34 +897,17 @@ PhyConfig8185(
return;
}
-
-
-
void
HwConfigureRTL8185(
struct net_device *dev
)
{
//RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
-// u8 bUNIVERSAL_CONTROL_RL = 1;
u8 bUNIVERSAL_CONTROL_RL = 0;
-
u8 bUNIVERSAL_CONTROL_AGC = 1;
u8 bUNIVERSAL_CONTROL_ANT = 1;
u8 bAUTO_RATE_FALLBACK_CTL = 1;
u8 val8;
- //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- //struct ieee80211_device *ieee = priv->ieee80211;
- //if(IS_WIRELESS_MODE_A(dev) || IS_WIRELESS_MODE_G(dev))
-//{by amy 080312 if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
-// {
-// write_nic_word(dev, BRSR, 0xffff);
-// }
-// else
-// {
-// write_nic_word(dev, BRSR, 0x000f);
-// }
-//by amy 080312}
write_nic_word(dev, BRSR, 0x0fff);
// Retry limit
val8 = read_nic_byte(dev, CW_CONF);
@@ -1507,20 +958,11 @@ HwConfigureRTL8185(
val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
// <RJ_TODO_8185B> We shall set up the ARFR according to user's setting.
- //write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
-//by amy
- // Aadded by Roger, 2007.11.15.
PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps.
-//by amy
- }
- else
- {
}
write_nic_byte(dev, RATE_FALLBACK, val8);
}
-
-
static void
MacConfig_85BASIC_HardCode(
struct net_device *dev)
@@ -1548,14 +990,11 @@ MacConfig_85BASIC_HardCode(
{
u4bRegOffset |= (u4bPageIndex << 8);
}
- //DbgPrint("MAC - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
}
//============================================================================
}
-
-
static void
MacConfig_85BASIC(
struct net_device *dev)
@@ -1578,8 +1017,6 @@ MacConfig_85BASIC(
PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
// Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
- //PlatformIOWrite4Byte(dev, RFTiming, 0x00004001);
-//by amy
// power save parameter based on "87SE power save parameters 20071127.doc", as follow.
//Enable DA10 TX power saving
@@ -1598,35 +1035,18 @@ MacConfig_85BASIC(
write_nic_word(dev, 0x378, 0x0560);
write_nic_word(dev, 0x37A, 0x0560);
write_nic_word(dev, 0x37C, 0x00EC);
-// write_nic_word(dev, 0x37E, 0x00FE);//-edward
write_nic_word(dev, 0x37E, 0x00EC);//+edward
write_nic_byte(dev, 0x24E,0x01);
-//by amy
-
}
-
-
-
u8
GetSupportedWirelessMode8185(
struct net_device *dev
)
{
u8 btSupportedWirelessMode = 0;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
- btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
- break;
- default:
- btSupportedWirelessMode = WIRELESS_MODE_B;
- break;
- }
+ btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
return btSupportedWirelessMode;
}
@@ -1641,7 +1061,6 @@ ActUpdateChannelAccessSetting(
struct ieee80211_device *ieee = priv->ieee80211;
AC_CODING eACI;
AC_PARAM AcParam;
- //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
u8 bFollowLegacySetting = 0;
u8 u1bAIFS;
@@ -1663,40 +1082,14 @@ ActUpdateChannelAccessSetting(
ChnlAccessSetting->CWmaxIndex = 7; // 2006.06.02, by rcnjko.
write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
- //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SLOT_TIME, &ChnlAccessSetting->SlotTimeTimer ); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
- //write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
- //write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
- //write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
- //write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
-
write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
-#ifdef TODO
- // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
- if( pStaQos->CurrentQosMode > QOS_DISABLE )
- { // QoS mode.
- if(pStaQos->QBssWirelessMode == WirelessMode)
- {
- // Follow AC Parameters of the QBSS.
- for(eACI = 0; eACI < AC_MAX; eACI++)
- {
- Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
- }
- }
- else
- {
- // Follow Default WMM AC Parameters.
- bFollowLegacySetting = 1;
- }
- }
- else
-#endif
{ // Legacy 802.11.
bFollowLegacySetting = 1;
@@ -1719,14 +1112,12 @@ ActUpdateChannelAccessSetting(
AcParam.f.TXOPLimit = 0;
//lzm reserved 080826
-#if 1
// For turbo mode setting. port from 87B by Isaiah 2008-08-01
if( ieee->current_network.Turbo_Enable == 1 )
AcParam.f.TXOPLimit = 0x01FF;
// For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB)
if (ieee->iw_mode == IW_MODE_ADHOC)
AcParam.f.TXOPLimit = 0x0020;
-#endif
for(eACI = 0; eACI < AC_MAX; eACI++)
{
@@ -1770,18 +1161,13 @@ ActUpdateChannelAccessSetting(
// Cehck ACM bit.
// If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
- //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
{
PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
AC_CODING eACI = pAciAifsn->f.ACI;
//modified Joseph
//for 8187B AsynIORead issue
-#ifdef TODO
- u8 AcmCtrl = pHalData->AcmControl;
-#else
u8 AcmCtrl = 0;
-#endif
if( pAciAifsn->f.ACM )
{ // ACM bit is 1.
switch(eACI)
@@ -1823,19 +1209,10 @@ ActUpdateChannelAccessSetting(
break;
}
}
-
- //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
-
-#ifdef TO_DO
- pHalData->AcmControl = AcmCtrl;
-#endif
- //write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
write_nic_byte(dev, ACM_CONTROL, 0);
}
}
}
-
-
}
}
@@ -1847,7 +1224,6 @@ ActSetWirelessMode8185(
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
struct ieee80211_device *ieee = priv->ieee80211;
- //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
if( (btWirelessMode & btSupportedWirelessMode) == 0 )
@@ -1880,24 +1256,11 @@ ActSetWirelessMode8185(
}
}
-
- // 2. Swtich band: RF or BB specific actions,
- // for example, refresh tables in omc8255, or change initial gain if necessary.
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
- {
- // Nothing to do for Zebra to switch band.
- // Update current wireless mode if we swtich to specified band successfully.
- ieee->mode = (WIRELESS_MODE)btWirelessMode;
- }
- break;
-
- default:
- DMESGW("ActSetWirelessMode8185(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
- break;
- }
+ /* 2. Swtich band: RF or BB specific actions,
+ * for example, refresh tables in omc8255, or change initial gain if necessary.
+ * Nothing to do for Zebra to switch band.
+ * Update current wireless mode if we swtich to specified band successfully. */
+ ieee->mode = (WIRELESS_MODE)btWirelessMode;
// 3. Change related setting.
if( ieee->mode == WIRELESS_MODE_A ){
@@ -1909,7 +1272,6 @@ ActSetWirelessMode8185(
else if( ieee->mode == WIRELESS_MODE_G ){
DMESG("WIRELESS_MODE_G\n");
}
-
ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
}
@@ -1927,11 +1289,7 @@ DrvIFIndicateDisassociation(
u16 reason
)
{
- //printk("==> DrvIFIndicateDisassociation()\n");
-
// nothing is needed after disassociation request.
-
- //printk("<== DrvIFIndicateDisassociation()\n");
}
void
MgntDisconnectIBSS(
@@ -1941,11 +1299,7 @@ MgntDisconnectIBSS(
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
u8 i;
- //printk("XXXXXXXXXX MgntDisconnect IBSS\n");
-
DrvIFIndicateDisassociation(dev, unspec_reason);
-
-// PlatformZeroMemory( pMgntInfo->Bssid, 6 );
for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x55;
priv->ieee80211->state = IEEE80211_NOLINK;
@@ -1957,16 +1311,10 @@ MgntDisconnectIBSS(
// Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send.
// Disable Beacon Queue Own bit, suggested by jong
-// Adapter->HalFunc.SetTxDescOWNHandler(Adapter, BEACON_QUEUE, 0, 0);
ieee80211_stop_send_beacons(priv->ieee80211);
priv->ieee80211->link_change(dev);
notify_wx_assoc_event(priv->ieee80211);
-
- // Stop SW Beacon.Use hw beacon so do not need to do so.by amy
-
-// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
-
}
void
MlmeDisassociateRequest(
@@ -1986,14 +1334,8 @@ MlmeDisassociateRequest(
DrvIFIndicateDisassociation(dev, unspec_reason);
- // pMgntInfo->AsocTimestamp = 0;
for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22;
-// pMgntInfo->mBrates.Length = 0;
-// Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
-
ieee80211_disassociate(priv->ieee80211);
-
-
}
}
@@ -2011,23 +1353,12 @@ MgntDisconnectAP(
// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
//
// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
-// SecClearAllKeys(Adapter);
// In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
-#ifdef TODO
- if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
- (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key
- {
- SecClearAllKeys(Adapter);
- RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
- }
-#endif
// 2004.10.11, by rcnjko.
- //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
priv->ieee80211->state = IEEE80211_NOLINK;
-// pMgntInfo->AsocTimestamp = 0;
}
bool
MgntDisconnect(
@@ -2039,20 +1370,7 @@ MgntDisconnect(
//
// Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
//
-#ifdef TODO
- if(pMgntInfo->mPss != eAwake)
- {
- //
- // Using AwkaeTimer to prevent mismatch ps state.
- // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31.
- //
- // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
- PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
- }
-#endif
- // Indication of disassociation event.
- //DrvIFIndicateDisassociation(Adapter, asRsn);
if(IS_DOT11D_ENABLE(priv->ieee80211))
Dot11d_Reset(priv->ieee80211);
// In adhoc mode, update beacon frame.
@@ -2060,8 +1378,6 @@ MgntDisconnect(
{
if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
{
-// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectIBSS\n"));
- //printk("MgntDisconnect() ===> MgntDisconnectIBSS\n");
MgntDisconnectIBSS(dev);
}
if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
@@ -2071,17 +1387,10 @@ MgntDisconnect(
// e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
// used to handle disassociation related things to AP, e.g. send Disassoc
// frame to AP. 2005.01.27, by rcnjko.
-// SecClearAllKeys(Adapter);
-
-// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectAP\n"));
- //printk("MgntDisconnect() ===> MgntDisconnectAP\n");
MgntDisconnectAP(dev, asRsn);
}
-
// Inidicate Disconnect, 2005.02.23, by rcnjko.
-// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
}
-
return true;
}
//
@@ -2101,25 +1410,12 @@ SetRFPowerState(
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
bool bResult = false;
-// printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
if(eRFPowerState == priv->eRFPowerState)
{
-// printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
return bResult;
}
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
- bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
- break;
-
- default:
- printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
- break;;
-}
-// printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
+ bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
return bResult;
}
@@ -2149,33 +1445,25 @@ MgntActSet_RF_State(
RT_RF_POWER_STATE rtState;
u16 RFWaitCounter = 0;
unsigned long flag;
-// printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
//
// Prevent the race condition of RF state change. By Bruce, 2007-11-28.
// Only one thread can change the RF state at one time, and others should wait to be executed.
//
-#if 1
while(true)
{
-// down(&priv->rf_state);
spin_lock_irqsave(&priv->rf_ps_lock,flag);
if(priv->RFChangeInProgress)
{
-// printk("====================>haha111111111\n");
-// up(&priv->rf_state);
-// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
// Set RF after the previous action is done.
while(priv->RFChangeInProgress)
{
RFWaitCounter ++;
-// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
udelay(1000); // 1 ms
// Wait too long, return FALSE to avoid to be stuck here.
if(RFWaitCounter > 1000) // 1sec
{
-// RT_ASSERT(FALSE, ("MgntActSet_RF_State(): Wait too logn to set RF\n"));
printk("MgntActSet_RF_State(): Wait too long to set RF\n");
// TODO: Reset RF state?
return false;
@@ -2184,17 +1472,13 @@ MgntActSet_RF_State(
}
else
{
-// printk("========================>haha2\n");
priv->RFChangeInProgress = true;
-// up(&priv->rf_state);
spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
break;
}
}
-#endif
rtState = priv->eRFPowerState;
-
switch(StateToSet)
{
case eRfOn:
@@ -2215,7 +1499,6 @@ MgntActSet_RF_State(
}
}
else
-// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", pMgntInfo->RfOffReason, ChangeSource));
;
break;
@@ -2232,38 +1515,26 @@ MgntActSet_RF_State(
//
// Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
// because we do NOT need to set ssid to dummy ones.
- // Revised by Roger, 2007.12.04.
//
MgntDisconnect( dev, disas_lv_ss );
// Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
- // 2007.05.28, by shien chang.
-// PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
-// pMgntInfo->NumBssDesc = 0;
-// PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
-// pMgntInfo->NumBssDesc4Query = 0;
}
-
-
priv->RfOffReason |= ChangeSource;
bActionAllowed = true;
break;
-
case eRfSleep:
priv->RfOffReason |= ChangeSource;
bActionAllowed = true;
break;
-
default:
break;
}
if(bActionAllowed)
{
-// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, pMgntInfo->RfOffReason));
// Config HW to the specified mode.
-// printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
SetRFPowerState(dev, StateToSet);
// Turn on RF.
@@ -2273,7 +1544,6 @@ MgntActSet_RF_State(
if(bConnectBySSID)
{
// by amy not supported
-// MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
}
}
// Turn off RF.
@@ -2282,18 +1552,11 @@ MgntActSet_RF_State(
HalDisableRx8185Dummy(dev);
}
}
- else
- {
- // printk("MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason);
- }
// Release RF spinlock
-// down(&priv->rf_state);
spin_lock_irqsave(&priv->rf_ps_lock,flag);
priv->RFChangeInProgress = false;
-// up(&priv->rf_state);
spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
-// printk("<===MgntActSet_RF_State()\n");
return bActionAllowed;
}
void
@@ -2302,15 +1565,12 @@ InactivePowerSave(
)
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- //u8 index = 0;
-
//
// This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
// is really scheduled.
// The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
// previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
// blocks the IPS procedure of switching RF.
- // By Bruce, 2007-12-25.
//
priv->bSwRfProcessing = true;
@@ -2326,7 +1586,6 @@ InactivePowerSave(
//
// Description:
// Enter the inactive power save mode. RF will be off
-// 2007.08.17, by shien chang.
//
void
IPSEnter(
@@ -2335,13 +1594,11 @@ IPSEnter(
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
RT_RF_POWER_STATE rtState;
- //printk("==============================>enter IPS\n");
if (priv->bInactivePs)
{
rtState = priv->eRFPowerState;
//
- // Added by Bruce, 2007-12-25.
// Do not enter IPS in the following conditions:
// (1) RF is already OFF or Sleep
// (2) bSwRfProcessing (indicates the IPS is still under going)
@@ -2352,12 +1609,10 @@ IPSEnter(
if (rtState == eRfOn && !priv->bSwRfProcessing
&& (priv->ieee80211->state != IEEE80211_LINKED ))
{
- // printk("IPSEnter(): Turn off RF.\n");
priv->eInactivePowerState = eRfOff;
InactivePowerSave(dev);
}
}
-// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
}
void
IPSLeave(
@@ -2366,20 +1621,17 @@ IPSLeave(
{
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
RT_RF_POWER_STATE rtState;
- //printk("===================================>leave IPS\n");
if (priv->bInactivePs)
{
rtState = priv->eRFPowerState;
if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
{
-// printk("IPSLeave(): Turn on RF.\n");
priv->eInactivePowerState = eRfOn;
InactivePowerSave(dev);
}
}
-// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
}
-//by amy for power save
+
void rtl8185b_adapter_start(struct net_device *dev)
{
struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2388,75 +1640,45 @@ void rtl8185b_adapter_start(struct net_device *dev)
u8 SupportedWirelessMode;
u8 InitWirelessMode;
u8 bInvalidWirelessMode = 0;
- //int i;
u8 tmpu8;
- //u8 u1tmp,u2tmp;
u8 btCR9346;
u8 TmpU1b;
u8 btPSR;
- //rtl8180_rtx_disable(dev);
-//{by amy 080312
write_nic_byte(dev,0x24e, (BIT5|BIT6|BIT0));
-//by amy 080312}
rtl8180_reset(dev);
priv->dma_poll_mask = 0;
priv->dma_poll_stop_mask = 0;
- //rtl8180_beacon_tx_disable(dev);
-
HwConfigureRTL8185(dev);
-
write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
-
write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); // default network type to 'No Link'
-
- //write_nic_byte(dev, BRSR, 0x0); // Set BRSR= 1M
-
write_nic_word(dev, BcnItv, 100);
write_nic_word(dev, AtimWnd, 2);
-
- //PlatformEFIOWrite2Byte(dev, FEMR, 0xFFFF);
PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
-
write_nic_byte(dev, WPA_CONFIG, 0);
-
MacConfig_85BASIC(dev);
-
// Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
// BT_DEMO_BOARD type
PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
-//by amy
-//#ifdef CONFIG_RTL818X_S
- // for jong required
-// PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
-//#endif
-//by amy
- //BT_QA_BOARD
- //PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
//-----------------------------------------------------------------------------
// Set up PHY related.
//-----------------------------------------------------------------------------
// Enable Config3.PARAM_En to revise AnaaParm.
write_nic_byte(dev, CR9346, 0xc0); // enable config register write
-//by amy
tmpu8 = read_nic_byte(dev, CONFIG3);
write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) );
-//by amy
// Turn on Analog power.
// Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
-//by amy
write_nic_word(dev, ANAPARAM3, 0x0010);
-//by amy
write_nic_byte(dev, CONFIG3, tmpu8);
write_nic_byte(dev, CR9346, 0x00);
-//{by amy 080312 for led
// enable EEM0 and EEM1 in 9346CR
btCR9346 = read_nic_byte(dev, CR9346);
write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
@@ -2474,7 +1696,6 @@ void rtl8185b_adapter_start(struct net_device *dev)
// B-cut RF Radio on/off 5e[3]=0
btPSR = read_nic_byte(dev, PSR);
write_nic_byte(dev, PSR, (btPSR | BIT3));
-//by amy 080312 for led}
// setup initial timing for RFE.
write_nic_word(dev, RFPinsOutput, 0x0480);
SetOutputEnableOfRfPins(dev);
@@ -2537,55 +1758,19 @@ void rtl8185b_adapter_start(struct net_device *dev)
InitWirelessMode = ieee->mode;
}
//by amy for power save
-// printk("initialize ENABLE_IPS\n");
priv->eRFPowerState = eRfOff;
priv->RfOffReason = 0;
{
- // u32 tmp2;
- // u32 tmp = jiffies;
MgntActSet_RF_State(dev, eRfOn, 0);
- // tmp2 = jiffies;
- // printk("rf on cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
}
-// DrvIFIndicateCurrentPhyStatus(priv);
//
// If inactive power mode is enabled, disable rf while in disconnected state.
- // 2007.07.16, by shien chang.
//
if (priv->bInactivePs)
{
- // u32 tmp2;
- // u32 tmp = jiffies;
MgntActSet_RF_State(dev,eRfOff, RF_CHANGE_BY_IPS);
- // tmp2 = jiffies;
- // printk("rf off cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
-
}
-// IPSEnter(dev);
//by amy for power save
-#ifdef TODO
- // Turn off RF if necessary. 2005.08.23, by rcnjko.
- // We shall turn off RF after setting CMDR, otherwise,
- // RF will be turnned on after we enable MAC Tx/Rx.
- if(Adapter->MgntInfo.RegRfOff == TRUE)
- {
- SetRFPowerState8185(Adapter, RF_OFF);
- }
- else
- {
- SetRFPowerState8185(Adapter, RF_ON);
- }
-#endif
-
-/* //these is equal with above TODO.
- write_nic_byte(dev, CR9346, 0xc0); // enable config register write
- write_nic_byte(dev, CONFIG3, read_nic_byte(dev, CONFIG3) | CONFIG3_PARM_En);
- RF_WriteReg(dev, 0x4, 0x9FF);
- write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
- write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
- write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
- write_nic_byte(dev, CR9346, 0x00);
-*/
ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
@@ -2594,14 +1779,11 @@ void rtl8185b_adapter_start(struct net_device *dev)
rtl8185b_irq_enable(dev);
netif_start_queue(dev);
-
}
-
void rtl8185b_rx_enable(struct net_device *dev)
{
u8 cmd;
- //u32 rxconf;
/* for now we accept data, management & ctl frame*/
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
@@ -2613,11 +1795,6 @@ void rtl8185b_rx_enable(struct net_device *dev)
priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
}
- /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
- rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
- rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
- }*/
-
if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
}
@@ -2629,9 +1806,6 @@ void rtl8185b_rx_enable(struct net_device *dev)
fix_rx_fifo(dev);
-#ifdef DEBUG_RX
- DMESG("rxconf: %x %x",priv->ReceiveConfig ,read_nic_dword(dev,RCR));
-#endif
cmd=read_nic_byte(dev,CMD);
write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
@@ -2640,9 +1814,7 @@ void rtl8185b_rx_enable(struct net_device *dev)
void rtl8185b_tx_enable(struct net_device *dev)
{
u8 cmd;
- //u8 tx_agc_ctl;
u8 byte;
- //u32 txconf;
struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
write_nic_dword(dev, TCR, priv->TransmitConfig);
@@ -2652,21 +1824,7 @@ void rtl8185b_tx_enable(struct net_device *dev)
fix_tx_fifo(dev);
-#ifdef DEBUG_TX
- DMESG("txconf: %x %x",priv->TransmitConfig,read_nic_dword(dev,TCR));
-#endif
-
cmd=read_nic_byte(dev,CMD);
write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
-
- //write_nic_dword(dev,TX_CONF,txconf);
-
-
-/*
- rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask);
- rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
- */
}
-
diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile
index 5e4aa9546b5..e032c3e1e86 100644
--- a/drivers/staging/rtl8192e/Makefile
+++ b/drivers/staging/rtl8192e/Makefile
@@ -1,13 +1,15 @@
NIC_SELECT = RTL8192E
-
EXTRA_CFLAGS += -DRTL8192E
EXTRA_CFLAGS += -std=gnu89
EXTRA_CFLAGS += -O2
EXTRA_CFLAGS += -DTHOMAS_TURBO
EXTRA_CFLAGS += -DENABLE_DOT11D
-r8192_pci-objs := \
+EXTRA_CFLAGS += -DENABLE_IPS
+EXTRA_CFLAGS += -DENABLE_LPS
+
+r8192e_pci-objs := \
r8192E_core.o \
r8180_93cx6.o \
r8192E_wx.o \
@@ -31,4 +33,5 @@ r8192_pci-objs := \
ieee80211/ieee80211_crypt_ccmp.o \
ieee80211/ieee80211_crypt_wep.o
-obj-$(CONFIG_RTL8192E) += r8192_pci.o
+obj-$(CONFIG_RTL8192E) += r8192e_pci.o
+
diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h
index 15b7a4ba37b..5b0e2dbc2bb 100644
--- a/drivers/staging/rtl8192e/dot11d.h
+++ b/drivers/staging/rtl8192e/dot11d.h
@@ -1,102 +1,96 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
+#ifndef INC_DOT11D_H
+#define INC_DOT11D_H
#ifdef ENABLE_DOT11D
#include "ieee80211.h"
-//#define ENABLE_DOT11D
-
-//#define DOT11D_MAX_CHNL_NUM 83
-
typedef struct _CHNL_TXPOWER_TRIPLE {
u8 FirstChnl;
u8 NumChnls;
u8 MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
typedef enum _DOT11D_STATE {
DOT11D_STATE_NONE = 0,
DOT11D_STATE_LEARNED,
DOT11D_STATE_DONE,
-}DOT11D_STATE;
+} DOT11D_STATE;
+
+/**
+ * struct _RT_DOT11D_INFO
+ * @CountryIeLen: value greater than 0 if @CountryIeBuf contains
+ * valid country information element.
+ * @chanell_map: holds channel values
+ * 0 - invalid,
+ * 1 - valid (active scan),
+ * 2 - valid (passive scan)
+ * @CountryIeSrcAddr - Source AP of the country IE
+ */
typedef struct _RT_DOT11D_INFO {
- //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+ bool bEnabled;
- bool bEnabled; // dot11MultiDomainCapabilityEnabled
+ u16 CountryIeLen;
+ u8 CountryIeBuf[MAX_IE_LEN];
+ u8 CountryIeSrcAddr[6];
+ u8 CountryIeWatchdog;
- u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
- u8 CountryIeBuf[MAX_IE_LEN];
- u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
- u8 CountryIeWatchdog;
-
- u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
- //u8 ChnlListLen; // #Bytes valid in ChnlList[].
- //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+ u8 channel_map[MAX_CHANNEL_NUMBER+1];
+ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
+} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+
+#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == \
+ (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && \
+ (a)[5] == (b)[5]) ? 1 : 0)
+
+#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], \
+ (des)[2] = (src)[2], (des)[3] = (src)[3], \
+ (des)[4] = (src)[4], (des)[5] = (src)[5])
+
+#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO) \
+ ((__pIeeeDev)->pDot11dInfo))
#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
+#define IS_COUNTRY_IE_VALID(__pIeeeDev) \
+ (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \
+ eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+
+#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \
+ cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- FALSE : \
- (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
+ (((__Ie).Length == 0 || (__Ie).Length != \
+ GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? FALSE : \
+ (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, \
+ (__Ie).Octet, (__Ie).Length)))
#define CIE_WATCHDOG_TH 1
#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-
-void
-Dot11d_Init(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_Reset(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- );
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- );
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- );
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-#endif //ENABLE_DOT11D
-#endif // #ifndef __INC_DOT11D_H
+#define IS_DOT11D_STATE_DONE(__pIeeeDev) \
+ (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
+
+
+void Dot11d_Init(struct ieee80211_device *dev);
+
+void Dot11d_Reset(struct ieee80211_device *dev);
+
+void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
+ u16 CoutryIeLen, u8 *pCoutryIe);
+
+u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 channel);
+
+void DOT11D_ScanComplete(struct ieee80211_device *dev);
+
+int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
+
+int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
+
+#endif /* ENABLE_DOT11D */
+#endif /* INC_DOT11D_H */
diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h
index 3ba9e9e90bd..c39249eb54b 100644
--- a/drivers/staging/rtl8192e/ieee80211.h
+++ b/drivers/staging/rtl8192e/ieee80211.h
@@ -547,9 +547,6 @@ do { if (ieee80211_debug_level & (level)) \
/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
/*
* To use the debug system;
*
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h
index aa76390487b..1f613a28152 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h
@@ -35,6 +35,7 @@
#endif
#include <linux/timer.h>
#include <linux/sched.h>
+#include <linux/semaphore.h>
#include <linux/delay.h>
#include <linux/wireless.h>
@@ -180,6 +181,8 @@ typedef struct cb_desc {
u8 DrvAggrNum;
u16 pkt_size;
u8 reserved12;
+
+ u8 bdhcp;
}cb_desc, *pcb_desc;
/*--------------------------Define -------------------------------------------*/
@@ -615,9 +618,6 @@ do { if (ieee80211_debug_level & (level)) \
/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
/*
* To use the debug system;
*
@@ -743,6 +743,8 @@ struct ieee80211_snap_hdr {
#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA)
+
#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
@@ -1055,7 +1057,7 @@ struct ieee80211_device;
#define SEC_ALG_NONE 0
#define SEC_ALG_WEP 1
#define SEC_ALG_TKIP 2
-#define SEC_ALG_CCMP 3
+#define SEC_ALG_CCMP 4
#define WEP_KEYS 4
#define WEP_KEY_LEN 13
@@ -1124,6 +1126,14 @@ enum ieee80211_mfie {
/* Minimal header; can be used for passing 802.11 frames with sufficient
* information to determine what type of underlying data type is actually
* stored in the data. */
+ struct ieee80211_pspoll_hdr {
+ __le16 frame_ctl;
+ __le16 aid;
+ u8 bssid[ETH_ALEN];
+ u8 ta[ETH_ALEN];
+ //u8 payload[0];
+} __attribute__ ((packed));
+
struct ieee80211_hdr {
__le16 frame_ctl;
__le16 duration_id;
@@ -1660,6 +1670,7 @@ struct ieee80211_network {
bool ralink_cap_exist;
bool atheros_cap_exist;
bool cisco_cap_exist;
+ bool marvell_cap_exist;
bool unknown_cap_exist;
// u8 berp_info;
bool berp_info_valid;
@@ -1865,6 +1876,19 @@ typedef struct _RT_POWER_SAVE_CONTROL
// Leisre Poswer Save : Disable RF if connected but traffic is not busy
//
bool bLeisurePs;
+ u32 PowerProfile;
+ u8 LpsIdleCount;
+ u8 RegMaxLPSAwakeIntvl;
+ u8 LPSAwakeIntvl;
+
+ u32 CurPsLevel;
+ u32 RegRfPsLevel;
+
+ bool bFwCtrlLPS;
+ u8 FWCtrlPSMode;
+
+ bool LinkReqInIPSRFOffPgs;
+ bool BufConnectinfoBefore;
}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
@@ -1905,14 +1929,121 @@ typedef struct _RT_LINK_DETECT_T{
u32 NumTxOkInPeriod;
u32 NumRxOkInPeriod;
+ u32 NumRxUnicastOkInPeriod;
bool bBusyTraffic;
}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
+//added by amy 090330
+typedef enum _HW_VARIABLES{
+ HW_VAR_ETHER_ADDR,
+ HW_VAR_MULTICAST_REG,
+ HW_VAR_BASIC_RATE,
+ HW_VAR_BSSID,
+ HW_VAR_MEDIA_STATUS,
+ HW_VAR_SECURITY_CONF,
+ HW_VAR_BEACON_INTERVAL,
+ HW_VAR_ATIM_WINDOW,
+ HW_VAR_LISTEN_INTERVAL,
+ HW_VAR_CS_COUNTER,
+ HW_VAR_DEFAULTKEY0,
+ HW_VAR_DEFAULTKEY1,
+ HW_VAR_DEFAULTKEY2,
+ HW_VAR_DEFAULTKEY3,
+ HW_VAR_SIFS,
+ HW_VAR_DIFS,
+ HW_VAR_EIFS,
+ HW_VAR_SLOT_TIME,
+ HW_VAR_ACK_PREAMBLE,
+ HW_VAR_CW_CONFIG,
+ HW_VAR_CW_VALUES,
+ HW_VAR_RATE_FALLBACK_CONTROL,
+ HW_VAR_CONTENTION_WINDOW,
+ HW_VAR_RETRY_COUNT,
+ HW_VAR_TR_SWITCH,
+ HW_VAR_COMMAND, // For Command Register, Annie, 2006-04-07.
+ HW_VAR_WPA_CONFIG, //2004/08/23, kcwu, for 8187 Security config
+ HW_VAR_AMPDU_MIN_SPACE, // The spacing between sub-frame. Roger, 2008.07.04.
+ HW_VAR_SHORTGI_DENSITY, // The density for shortGI. Roger, 2008.07.04.
+ HW_VAR_AMPDU_FACTOR,
+ HW_VAR_MCS_RATE_AVAILABLE,
+ HW_VAR_AC_PARAM, // For AC Parameters, 2005.12.01, by rcnjko.
+ HW_VAR_ACM_CTRL, // For ACM Control, Annie, 2005-12-13.
+ HW_VAR_DIS_Req_Qsize, // For DIS_Reg_Qsize, Joseph
+ HW_VAR_CCX_CHNL_LOAD, // For CCX 2 channel load request, 2006.05.04.
+ HW_VAR_CCX_NOISE_HISTOGRAM, // For CCX 2 noise histogram request, 2006.05.04.
+ HW_VAR_CCX_CLM_NHM, // For CCX 2 parallel channel load request and noise histogram request, 2006.05.12.
+ HW_VAR_TxOPLimit, // For turbo mode related settings, added by Roger, 2006.12.07
+ HW_VAR_TURBO_MODE, // For turbo mode related settings, added by Roger, 2006.12.15.
+ HW_VAR_RF_STATE, // For change or query RF power state, 061214, rcnjko.
+ HW_VAR_RF_OFF_BY_HW, // For UI to query if external HW signal disable RF, 061229, rcnjko.
+ HW_VAR_BUS_SPEED, // In unit of bps. 2006.07.03, by rcnjko.
+ HW_VAR_SET_DEV_POWER, // Set to low power, added by LanHsin, 2007.
+
+ //1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ //1Attention Please!!!<11n or 8190 specific code should be put below this line>
+ //1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ HW_VAR_RCR, //for RCR, David 2006,05,11
+ HW_VAR_RATR_0,
+ HW_VAR_RRSR,
+ HW_VAR_CPU_RST,
+ HW_VAR_CECHK_BSSID,
+ HW_VAR_LBK_MODE, // Set lookback mode, 2008.06.11. added by Roger.
+ // Set HW related setting for 11N AES bug.
+ HW_VAR_AES_11N_FIX,
+ // Set Usb Rx Aggregation
+ HW_VAR_USB_RX_AGGR,
+ HW_VAR_USER_CONTROL_TURBO_MODE,
+ HW_VAR_RETRY_LIMIT,
+#ifndef _RTL8192_EXT_PATCH_
+ HW_VAR_INIT_TX_RATE, //Get Current Tx rate register. 2008.12.10. Added by tynli
+#endif
+ HW_VAR_TX_RATE_REG, //Get Current Tx rate register. 2008.12.10. Added by tynli
+ HW_VAR_EFUSE_USAGE, //Get current EFUSE utilization. 2008.12.19. Added by Roger.
+ HW_VAR_EFUSE_BYTES,
+ HW_VAR_AUTOLOAD_STATUS, //Get current autoload status, 0: autoload success, 1: autoload fail. 2008.12.19. Added by Roger.
+ HW_VAR_RF_2R_DISABLE, // 2R disable
+ HW_VAR_SET_RPWM,
+ HW_VAR_H2C_FW_PWRMODE, // For setting FW related H2C cmd structure. by tynli. 2009.2.18
+ HW_VAR_H2C_FW_JOINBSSRPT, // For setting FW related H2C cmd structure. by tynli. 2009.2.18
+ HW_VAR_1X1_RECV_COMBINE, // For 1T2R but only 1SS, Add by hpfan 2009.04.16 hpfan
+ HW_VAR_STOP_SEND_BEACON,
+ HW_VAR_TSF_TIMER, // Read from TSF register to get the current TSF timer, by Bruce, 2009-07-22.
+ HW_VAR_IO_CMD,
+ HW_VAR_HANDLE_FW_C2H, //Added by tynli. For handling FW C2H command. 2009.10.07.
+ HW_VAR_DL_FW_RSVD_PAGE, //Added by tynli. Download the packets that FW will use to RSVD page. 2009.10.14.
+ HW_VAR_AID, //Added by tynli.
+ HW_VAR_HW_SEQ_ENABLE, //Added by tynli. 2009.10.20.
+ HW_VAR_UPDATE_TSF, //Added by tynli. 2009.10.22. For Hw count TBTT time.
+ HW_VAR_BCN_VALID, //Added by tynli.
+ HW_VAR_FWLPS_RF_ON //Added by tynli. 2009.11.09. For checking if Fw finishs RF on sequence.
+}HW_VARIABLES;
+
+#define RT_CHECK_FOR_HANG_PERIOD 2
struct ieee80211_device {
struct net_device *dev;
struct ieee80211_security sec;
+ bool need_sw_enc;
+#ifdef ENABLE_LPS
+ bool bAwakePktSent;
+ u8 LPSDelayCnt;
+ bool bIsAggregateFrame;
+ bool polling;
+ void (*LeisurePSLeave)(struct net_device *dev);
+#endif
+
+#ifdef ENABLE_IPS
+ bool proto_stoppping;
+ bool wx_set_enc;
+ struct semaphore ips_sem;
+ struct work_struct ips_leave_wq;
+ void (*ieee80211_ips_leave_wq) (struct net_device *dev);
+ void (*ieee80211_ips_leave)(struct net_device *dev);
+#endif
+ void (*SetHwRegHandler)(struct net_device *dev,u8 variable,u8* val);
+ u8 (*rtllib_ap_sec_type)(struct ieee80211_device *ieee);
+
//hw security related
// u8 hwsec_support; //support?
u8 hwsec_active; //hw security active.
@@ -2319,7 +2450,7 @@ struct ieee80211_device {
* stop_send_bacons is NOT guaranteed to be called only
* after start_send_beacons.
*/
- void (*start_send_beacons) (struct net_device *dev,u16 tx_rate);
+ void (*start_send_beacons) (struct net_device *dev);
void (*stop_send_beacons) (struct net_device *dev);
/* power save mode related */
@@ -2373,6 +2504,19 @@ struct ieee80211_device {
u8 priv[0];
};
+#define RT_RF_OFF_LEVL_ASPM BIT0 // PCI ASPM
+#define RT_RF_OFF_LEVL_CLK_REQ BIT1 // PCI clock request
+#define RT_RF_OFF_LEVL_PCI_D3 BIT2 // PCI D3 mode
+#define RT_RF_OFF_LEVL_HALT_NIC BIT3 // NIC halt, re-initialize hw parameters
+#define RT_RF_OFF_LEVL_FREE_FW BIT4 // FW free, re-download the FW
+#define RT_RF_OFF_LEVL_FW_32K BIT5 // FW in 32k
+#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT6 // Always enable ASPM and Clock Req in initialization.
+#define RT_RF_LPS_DISALBE_2R BIT30 // When LPS is on, disable 2R if no packet is received or transmittd.
+#define RT_RF_LPS_LEVEL_ASPM BIT31 // LPS with ASPM
+#define RT_IN_PS_LEVEL(pPSC, _PS_FLAG) ((pPSC->CurPsLevel & _PS_FLAG) ? true : false)
+#define RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel &= (~(_PS_FLAG)))
+#define RT_SET_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel |= _PS_FLAG)
+
#define IEEE_A (1<<0)
#define IEEE_B (1<<1)
#define IEEE_G (1<<2)
@@ -2609,9 +2753,9 @@ extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_stop_protocol(struct ieee80211_device *ieee,u8 shutdown);
extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee,u8 shutdown);
extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
@@ -2798,5 +2942,7 @@ extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
struct ieee80211_rx_stats *stats);
void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index);
+void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
+void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee);
#define RT_ASOC_RETRY_LIMIT 5
#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
index b1c54932da3..b3c9bf4b4ea 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
@@ -225,7 +225,7 @@ out:
}
-void __exit ieee80211_crypto_deinit(void)
+void ieee80211_crypto_deinit(void)
{
struct list_head *ptr, *n;
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
index ab871b360b5..1776f7e69bf 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
@@ -331,7 +331,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: received packet without ExtIV"
- " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ " flag from %pM\n", hdr->addr2);
}
key->dot11RSNAStatsCCMPFormatErrors++;
return -2;
@@ -344,9 +344,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!key->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+ printk(KERN_DEBUG "CCMP: received packet from %pM"
" with keyid=%d that does not have a configured"
- " key\n", MAC_ARG(hdr->addr2), keyidx);
+ " key\n", hdr->addr2, keyidx);
}
return -3;
}
@@ -361,11 +361,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
- " previous PN %02x%02x%02x%02x%02x%02x "
- "received PN %02x%02x%02x%02x%02x%02x\n",
- MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
- MAC_ARG(pn));
+ //printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
+ // " previous PN %pm received PN %pm\n",
+ // hdr->addr2, key->rx_pn, pn);
}
key->dot11RSNAStatsCCMPReplays++;
return -4;
@@ -402,7 +400,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: decrypt failed: STA="
- MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ "%pM\n", hdr->addr2);
}
key->dot11RSNAStatsCCMPDecryptErrors++;
return -5;
@@ -477,12 +475,19 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
static char * ieee80211_ccmp_print_stats(char *p, void *priv)
{
struct ieee80211_ccmp_data *ccmp = priv;
- p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
- "format_errors=%d replays=%d decrypt_errors=%d\n",
- ccmp->key_idx, ccmp->key_set,
- MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+ int i;
+
+ p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=",
+ ccmp->key_idx, ccmp->key_set);
+
+ for (i = 0; i < ARRAY_SIZE(ccmp->tx_pn); i++)
+ p += sprintf(p, "%02x", ccmp->tx_pn[i]);
+
+ sprintf(p, " rx_pn=");
+ for (i = 0; i < ARRAY_SIZE(ccmp->rx_pn); i++)
+ p += sprintf(p, "%02x", ccmp->tx_pn[i]);
+
+ p += sprintf(p, " format_errors=%d replays=%d decrypt_errors=%d\n",
ccmp->dot11RSNAStatsCCMPFormatErrors,
ccmp->dot11RSNAStatsCCMPReplays,
ccmp->dot11RSNAStatsCCMPDecryptErrors);
@@ -519,7 +524,7 @@ int __init ieee80211_crypto_ccmp_init(void)
}
-void __exit ieee80211_crypto_ccmp_exit(void)
+void ieee80211_crypto_ccmp_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
}
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
index 7a1797e6cbe..03cb21eb065 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
@@ -520,7 +520,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ " flag from %pM\n", hdr->addr2);
}
return -2;
}
@@ -532,9 +532,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!tkey->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+ printk(KERN_DEBUG "TKIP: received packet from %pM"
" with keyid=%d that does not have a configured"
- " key\n", MAC_ARG(hdr->addr2), keyidx);
+ " key\n", hdr->addr2, keyidx);
}
return -3;
}
@@ -547,9 +547,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (iv32 < tkey->rx_iv32 ||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+ printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
" previous TSC %08x%04x received TSC "
- "%08x%04x\n", MAC_ARG(hdr->addr2),
+ "%08x%04x\n", hdr->addr2,
tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
}
tkey->dot11RSNAStatsTKIPReplays++;
@@ -582,8 +582,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
if (net_ratelimit()) {
printk(KERN_DEBUG ": TKIP: failed to decrypt "
- "received packet from " MAC_FMT "\n",
- MAC_ARG(hdr->addr2));
+ "received packet from %pM\n",
+ hdr->addr2);
}
return -7;
}
@@ -606,8 +606,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
tkey->rx_phase1_done = 0;
}
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: ICV error detected: STA="
- MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ printk(KERN_DEBUG
+ "TKIP: ICV error detected: STA=%pM\n",
+ hdr->addr2);
}
tkey->dot11RSNAStatsTKIPICVErrors++;
return -5;
@@ -816,8 +817,8 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
/* TODO: needed parameters: count, keyid, key type, TSC */
sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
- MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
- MAC_ARG(hdr->addr2));
+ "%pM)", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
+ hdr->addr2);
memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.length = strlen(buf);
wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
@@ -862,8 +863,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
struct ieee80211_hdr_4addr *hdr;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- "MSDU from " MAC_FMT " keyidx=%d\n",
- skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+ "MSDU from %pM keyidx=%d\n",
+ skb->dev ? skb->dev->name : "N/A", hdr->addr2,
keyidx);
if (skb->dev)
ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
@@ -1011,7 +1012,7 @@ int __init ieee80211_crypto_tkip_init(void)
}
-void __exit ieee80211_crypto_tkip_exit(void)
+void ieee80211_crypto_tkip_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
}
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
index 06d91715143..ce265ae5fe1 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
@@ -312,6 +312,17 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
if (skb->len < 24)
return 0;
+#if 1
+ if (ieee->hwsec_active)
+ {
+ cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
+ tcb_desc->bHwSec = 1;
+
+ if(ieee->need_sw_enc)
+ tcb_desc->bHwSec = 0;
+ }
+#endif
+
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
@@ -366,8 +377,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
strcmp(crypt->ops->name, "TKIP") == 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "received packet from " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(hdr->addr2));
+ "received packet from %pM\n",
+ ieee->dev->name, hdr->addr2);
}
return -1;
}
@@ -378,8 +389,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
atomic_dec(&crypt->refcnt);
if (res < 0) {
IEEE80211_DEBUG_DROP(
- "decryption failed (SA=" MAC_FMT
- ") res=%d\n", MAC_ARG(hdr->addr2), res);
+ "decryption failed (SA=%pM"
+ ") res=%d\n", hdr->addr2, res);
if (res == -2)
IEEE80211_DEBUG_DROP("Decryption failed ICV "
"mismatch (key %d)\n",
@@ -406,6 +417,10 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
{
cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
tcb_desc->bHwSec = 1;
+
+ if(ieee->need_sw_enc)
+ tcb_desc->bHwSec = 0;
+
}
hdr = (struct ieee80211_hdr_4addr *) skb->data;
@@ -416,8 +431,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
atomic_dec(&crypt->refcnt);
if (res < 0) {
printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- " (SA=" MAC_FMT " keyidx=%d)\n",
- ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+ " (SA=%pM keyidx=%d)\n",
+ ieee->dev->name, hdr->addr2, keyidx);
return -1;
}
@@ -799,7 +814,7 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee,
#endif
}
-u8 parse_subframe(struct sk_buff *skb,
+u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats,
struct ieee80211_rxb *rxb,u8* src,u8* dst)
{
@@ -839,6 +854,7 @@ u8 parse_subframe(struct sk_buff *skb,
}
skb_pull(skb, LLCOffset);
+ ieee->bIsAggregateFrame = bIsAggregateFrame;//added by amy for Leisure PS
if(!bIsAggregateFrame) {
rxb->nr_subframes = 1;
@@ -940,6 +956,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
u8 TID = 0;
u16 SeqNum = 0;
PRX_TS_RECORD pTS = NULL;
+ bool unicast_packet = false;
//bool bIsAggregateFrame = false;
//added by amy for reorder
#ifdef NOT_YET
@@ -1045,8 +1062,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
* frames silently instead of filling system log with
* these reports. */
IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ " (SA=%pM)\n",
+ hdr->addr2);
ieee->ieee_stats.rx_discards_undecryptable++;
goto rx_dropped;
}
@@ -1114,8 +1131,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
(keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
{
printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
- "from " MAC_FMT "\n", dev->name,
- MAC_ARG(hdr->addr2));
+ "from %pM\n", dev->name,
+ hdr->addr2);
/* TODO: could inform hostapd about this so that it
* could send auth failure report */
goto rx_dropped;
@@ -1215,6 +1232,24 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
goto rx_dropped;
+#ifdef ENABLE_LPS
+ if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == 1)
+ && (ieee->polling)) {
+ if (WLAN_FC_MORE_DATA(fc)) {
+ /* more data bit is set, let's request a new frame from the AP */
+ ieee80211_sta_ps_send_pspoll_frame(ieee);
+ } else {
+ ieee->polling = false;
+ }
+ }
+#endif
+
+ ieee->need_sw_enc = 0;
+
+ if((!rx_stats->Decrypted)){
+ ieee->need_sw_enc = 1;
+ }
+
/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
@@ -1296,6 +1331,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee->LinkDetectInfo.NumRxOkInPeriod++;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ if((!is_multicast_ether_addr(hdr->addr1)) && (!is_broadcast_ether_addr(hdr->addr1)))
+ unicast_packet = true;
+
if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
if (/*ieee->ieee802_1x &&*/
ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
@@ -1311,8 +1349,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
} else {
IEEE80211_DEBUG_DROP(
"encryption configured, but RX "
- "frame not encrypted (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ "frame not encrypted (SA=%pM)\n",
+ hdr->addr2);
goto rx_dropped;
}
}
@@ -1331,9 +1369,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
!ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
IEEE80211_DEBUG_DROP(
"dropped unencrypted RX data "
- "frame from " MAC_FMT
+ "frame from %pM"
" (drop_unencrypted=1)\n",
- MAC_ARG(hdr->addr2));
+ hdr->addr2);
goto rx_dropped;
}
/*
@@ -1367,7 +1405,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
}
/* to parse amsdu packets */
/* qos data packets & reserved bit is 1 */
- if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) {
+ if(parse_subframe(ieee, skb,rx_stats,rxb,src,dst) == 0) {
/* only to free rxb, and not submit the packets to upper layer */
for(i =0; i < rxb->nr_subframes; i++) {
dev_kfree_skb(rxb->subframes[i]);
@@ -1377,6 +1415,32 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
goto rx_dropped;
}
+#ifdef ENABLE_LPS
+ if(unicast_packet)
+ {
+ if (type == IEEE80211_FTYPE_DATA)
+ {
+
+ if(ieee->bIsAggregateFrame)
+ ieee->LinkDetectInfo.NumRxUnicastOkInPeriod+=rxb->nr_subframes;
+ else
+ ieee->LinkDetectInfo.NumRxUnicastOkInPeriod++;
+
+ // 2009.03.03 Leave DC mode immediately when detect high traffic
+ // DbgPrint("ending Seq %d\n", Frame_SeqNum(pduOS));
+ if((ieee->state == IEEE80211_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
+ {
+ if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
+ (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
+ {
+ if(ieee->LeisurePSLeave)
+ ieee->LeisurePSLeave(dev);
+ }
+ }
+ }
+ }
+#endif
+
ieee->last_rx_ps_time = jiffies;
//added by amy for reorder
if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){
@@ -2013,12 +2077,22 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
info_element->data[1] == 0x13 &&
info_element->data[2] == 0x74))
{
- printk("========>%s(): athros AP is exist\n",__FUNCTION__);
+ //printk("========>%s(): athros AP is exist\n",__FUNCTION__);
network->atheros_cap_exist = true;
}
else
network->atheros_cap_exist = false;
+ if ((info_element->len >= 3 &&
+ info_element->data[0] == 0x00 &&
+ info_element->data[1] == 0x50 &&
+ info_element->data[2] == 0x43) )
+ {
+ network->marvell_cap_exist = true;
+ //printk("========>%s(): marvel AP is exist\n",__FUNCTION__);
+ }
+
+
if(info_element->len >= 3 &&
info_element->data[0] == 0x00 &&
info_element->data[1] == 0x40 &&
@@ -2219,7 +2293,8 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
}
if(!network->atheros_cap_exist && !network->broadcom_cap_exist &&
- !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation)
+ !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation &&
+ !network->marvell_cap_exist)
{
network->unknown_cap_exist = true;
}
@@ -2333,6 +2408,7 @@ static inline int ieee80211_network_init(
network->broadcom_cap_exist = false;
network->ralink_cap_exist = false;
network->atheros_cap_exist = false;
+ network->marvell_cap_exist = false;
network->cisco_cap_exist = false;
network->unknown_cap_exist = false;
#ifdef THOMAS_TURBO
@@ -2369,11 +2445,11 @@ static inline int ieee80211_network_init(
}
if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+ IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
"network.\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid));
+ network->bssid);
return 1;
}
@@ -2463,6 +2539,7 @@ static inline void update_network(struct ieee80211_network *dst,
dst->broadcom_cap_exist = src->broadcom_cap_exist;
dst->ralink_cap_exist = src->ralink_cap_exist;
dst->atheros_cap_exist = src->atheros_cap_exist;
+ dst->marvell_cap_exist = src->marvell_cap_exist;
dst->cisco_cap_exist = src->cisco_cap_exist;
dst->unknown_cap_exist = src->unknown_cap_exist;
memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
@@ -2557,9 +2634,9 @@ static inline void ieee80211_process_probe_response(
memset(&network, 0, sizeof(struct ieee80211_network));
IEEE80211_DEBUG_SCAN(
- "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+ "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
escape_essid(info_element->data, info_element->len),
- MAC_ARG(beacon->header.addr3),
+ beacon->header.addr3,
(beacon->capability & (1<<0xf)) ? '1' : '0',
(beacon->capability & (1<<0xe)) ? '1' : '0',
(beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2578,10 +2655,10 @@ static inline void ieee80211_process_probe_response(
(beacon->capability & (1<<0x0)) ? '1' : '0');
if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
escape_essid(info_element->data,
info_element->len),
- MAC_ARG(beacon->header.addr3),
+ beacon->header.addr3,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -2692,11 +2769,11 @@ static inline void ieee80211_process_probe_response(
/* If there are no more slots, expire the oldest */
list_del(&oldest->list);
target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+ IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
"network list.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid));
+ target->bssid);
} else {
/* Otherwise just pull from the free list */
target = list_entry(ieee->network_free_list.next,
@@ -2706,10 +2783,10 @@ static inline void ieee80211_process_probe_response(
#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
escape_essid(network.ssid,
network.ssid_len),
- MAC_ARG(network.bssid),
+ network.bssid,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -2719,10 +2796,10 @@ static inline void ieee80211_process_probe_response(
if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
ieee80211_softmac_new_net(ieee,&network);
} else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid),
+ target->bssid,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -2761,12 +2838,14 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
struct ieee80211_hdr_4addr *header,
struct ieee80211_rx_stats *stats)
{
+#if 0
if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
ieee->iw_mode == IW_MODE_INFRA &&
ieee->state == IEEE80211_LINKED))
{
tasklet_schedule(&ieee->ps_task);
}
+#endif
if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
@@ -2780,6 +2859,15 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
IEEE80211_DEBUG_SCAN("Beacon\n");
ieee80211_process_probe_response(
ieee, (struct ieee80211_probe_response *)header, stats);
+
+ //printk("----------->%s()\n", __func__);
+ if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
+ ieee->iw_mode == IW_MODE_INFRA &&
+ ieee->state == IEEE80211_LINKED))
+ {
+ tasklet_schedule(&ieee->ps_task);
+ }
+
break;
case IEEE80211_STYPE_PROBE_RESP:
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
index 6d1ddec39f0..d1d7b086675 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
@@ -18,6 +18,7 @@
#include <linux/random.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#ifdef ENABLE_DOT11D
@@ -646,7 +647,7 @@ void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
{
if(ieee->start_send_beacons)
- ieee->start_send_beacons(ieee->dev,ieee->basic_rate);
+ ieee->start_send_beacons(ieee->dev);
if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
ieee80211_beacons_start(ieee);
}
@@ -686,6 +687,11 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee)
/* called with ieee->lock held */
void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
{
+#ifdef ENABLE_IPS
+ if(ieee->ieee80211_ips_leave_wq != NULL)
+ ieee->ieee80211_ips_leave_wq(ieee->dev);
+#endif
+
#ifdef ENABLE_DOT11D
if(IS_DOT11D_ENABLE(ieee) )
{
@@ -1093,6 +1099,40 @@ struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
}
+struct sk_buff* ieee80211_pspoll_func(struct ieee80211_device *ieee)
+{
+ struct sk_buff *skb;
+ struct ieee80211_pspoll_hdr* hdr;
+
+#ifdef USB_USE_ALIGNMENT
+ u32 Tmpaddr=0;
+ int alignment=0;
+ skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE);
+#else
+ skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr)+ieee->tx_headroom);
+#endif
+ if (!skb)
+ return NULL;
+
+#ifdef USB_USE_ALIGNMENT
+ Tmpaddr = (u32)skb->data;
+ alignment = Tmpaddr & 0x1ff;
+ skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
+#endif
+ skb_reserve(skb, ieee->tx_headroom);
+
+ hdr = (struct ieee80211_pspoll_hdr*)skb_put(skb,sizeof(struct ieee80211_pspoll_hdr));
+
+ memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN);
+ memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN);
+
+ hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
+ hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_CTL |IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM);
+
+ return skb;
+
+}
+
void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
{
@@ -1582,6 +1622,11 @@ void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
{
#endif
ieee->sync_scan_hurryup = 1;
+#ifdef ENABLE_IPS
+ if(ieee->ieee80211_ips_leave != NULL)
+ ieee->ieee80211_ips_leave(ieee->dev);
+#endif
+
down(&ieee->wx_sem);
if (ieee->data_hard_stop)
@@ -1592,6 +1637,17 @@ void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
//ieee->set_chan(ieee->dev, ieee->current_network.channel);
HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+#ifdef ENABLE_IPS
+ if(ieee->eRFPowerState == eRfOff)
+ {
+ if(ieee->ieee80211_ips_leave_wq != NULL)
+ ieee->ieee80211_ips_leave_wq(ieee->dev);
+
+ up(&ieee->wx_sem);
+ return;
+ }
+#endif
+
ieee->associate_seq = 1;
ieee80211_associate_step1(ieee);
@@ -1897,7 +1953,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
ieee80211_resp_to_assoc_rq(ieee, dest);
}
- printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+ printk(KERN_INFO"New client associated: %pM\n", dest);
//FIXME
#if 0
spin_lock_irqsave(&ieee->lock,flags);
@@ -1918,43 +1974,92 @@ void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
}
+void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee)
+{
+
+ struct sk_buff *buf = ieee80211_pspoll_func(ieee);
+
+ if (buf)
+ softmac_ps_mgmt_xmit(buf, ieee);
+
+}
short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
{
int timeout = ieee->ps_timeout;
u8 dtim;
- /*if(ieee->ps == IEEE80211_PS_DISABLED ||
- ieee->iw_mode != IW_MODE_INFRA ||
- ieee->state != IEEE80211_LINKED)
+ PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(ieee->PowerSaveControl));
+ if(ieee->LPSDelayCnt)
+ {
+ //printk("===============>Delay enter LPS for DHCP and ARP packets...\n");
+ ieee->LPSDelayCnt --;
return 0;
- */
+ }
+
dtim = ieee->current_network.dtim_data;
- //printk("DTIM\n");
+// printk("%s():DTIM:%d\n",__FUNCTION__,dtim);
if(!(dtim & IEEE80211_DTIM_VALID))
return 0;
timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
//printk("VALID\n");
ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
-
- if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
+ /* there's no need to nofity AP that I find you buffered with broadcast packet */
+ if(dtim & (IEEE80211_DTIM_UCAST & ieee->ps))
return 2;
- if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
+ if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))){
+// printk("%s():111Oh Oh ,it is not time out return 0\n",__FUNCTION__);
return 0;
-
- if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
+ }
+ if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))){
+// printk("%s():222Oh Oh ,it is not time out return 0\n",__FUNCTION__);
return 0;
-
+ }
if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
(ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
return 0;
if(time_l){
+ if(ieee->bAwakePktSent == true) {
+ pPSC->LPSAwakeIntvl = 1;//tx wake one beacon
+ } else {
+ u8 MaxPeriod = 1;
+
+ if(pPSC->LPSAwakeIntvl == 0)
+ pPSC->LPSAwakeIntvl = 1;
+ //pNdisCommon->RegLPSMaxIntvl /// 0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl
+ if(pPSC->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl)
+ MaxPeriod = 1; // 1 Beacon interval
+ else if(pPSC->RegMaxLPSAwakeIntvl == 0xFF) // DTIM
+ MaxPeriod = ieee->current_network.dtim_period;
+ else
+ MaxPeriod = pPSC->RegMaxLPSAwakeIntvl;
+ pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (pPSC->LPSAwakeIntvl + 1);
+ }
+ {
+ u8 LPSAwakeIntvl_tmp = 0;
+ u8 period = ieee->current_network.dtim_period;
+ u8 count = ieee->current_network.tim.tim_count;
+ if(count == 0 ) {
+ if(pPSC->LPSAwakeIntvl > period)
+ LPSAwakeIntvl_tmp = period + (pPSC->LPSAwakeIntvl - period) -((pPSC->LPSAwakeIntvl-period)%period);
+ else
+ LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;
+
+ } else {
+ if(pPSC->LPSAwakeIntvl > ieee->current_network.tim.tim_count)
+ LPSAwakeIntvl_tmp = count + (pPSC->LPSAwakeIntvl - count) -((pPSC->LPSAwakeIntvl-count)%period);
+ else
+ LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;//ieee->current_network.tim.tim_count;//pPSC->LPSAwakeIntvl;
+ }
+ //printk("=========>%s()assoc_id:%d(%#x),bAwakePktSent:%d,DTIM:%d, sleep interval:%d, LPSAwakeIntvl_tmp:%d, count:%d\n",__func__,ieee->assoc_id,cpu_to_le16(ieee->assoc_id),ieee->bAwakePktSent,ieee->current_network.dtim_period,pPSC->LPSAwakeIntvl,LPSAwakeIntvl_tmp,count);
+
*time_l = ieee->current_network.last_dtim_sta_time[0]
- + (ieee->current_network.beacon_interval);
+ + MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp);
// * ieee->current_network.dtim_period) * 1000;
}
+ }
if(time_h){
*time_h = ieee->current_network.last_dtim_sta_time[1];
@@ -1982,6 +2087,8 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
ieee->state != IEEE80211_LINKED)){
// #warning CHECK_LOCK_HERE
+ printk("=====>%s(): no need to ps,wake up!! ieee->ps is %d,ieee->iw_mode is %d,ieee->state is %d\n",
+ __FUNCTION__,ieee->ps,ieee->iw_mode,ieee->state);
spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
ieee80211_sta_wakeup(ieee, 1);
@@ -1991,27 +2098,27 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
/* 2 wake, 1 sleep, 0 do nothing */
- if(sleep == 0)
+ if(sleep == 0)//it is not time out or dtim is not valid
+ {
+ //printk("===========>sleep is 0,do nothing\n");
goto out;
-
+ }
if(sleep == 1){
-
- if(ieee->sta_sleep == 1)
+ //printk("===========>sleep is 1,to sleep\n");
+ if(ieee->sta_sleep == 1){
+ //printk("%s(1): sta_sleep = 1, sleep again ++++++++++ \n", __func__);
ieee->enter_sleep_state(ieee->dev,th,tl);
+ }
else if(ieee->sta_sleep == 0){
// printk("send null 1\n");
spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
if(ieee->ps_is_queue_empty(ieee->dev)){
-
-
ieee->sta_sleep = 2;
-
ieee->ack_tx_to_ieee = 1;
-
+ //printk("%s(2): sta_sleep = 0, notify AP we will sleeped ++++++++++ SendNullFunctionData\n", __func__);
ieee80211_sta_ps_send_null_frame(ieee,1);
-
ieee->ps_th = th;
ieee->ps_tl = tl;
}
@@ -2019,11 +2126,13 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
}
+ ieee->bAwakePktSent = false;//after null to power save we set it to false. not listen every beacon.
}else if(sleep == 2){
-//#warning CHECK_LOCK_HERE
+ //printk("==========>sleep is 2,to wakeup\n");
spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
+ //printk("%s(3): pkt buffered in ap will awake ++++++++++ ieee80211_sta_wakeup\n", __func__);
ieee80211_sta_wakeup(ieee,1);
spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
@@ -2038,9 +2147,19 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
{
if(ieee->sta_sleep == 0){
if(nl){
- printk("Warning: driver is probably failing to report TX ps error\n");
- ieee->ack_tx_to_ieee = 1;
- ieee80211_sta_ps_send_null_frame(ieee, 0);
+ if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
+ {
+ //printk("%s(1): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__);
+ //printk("Warning: driver is probably failing to report TX ps error\n");
+ ieee->ack_tx_to_ieee = 1;
+ ieee80211_sta_ps_send_null_frame(ieee, 0);
+ }
+ else
+ {
+ ieee->ack_tx_to_ieee = 1;
+ //printk("%s(2): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__);
+ ieee80211_sta_ps_send_pspoll_frame(ieee);
+ }
}
return;
@@ -2048,12 +2167,27 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
if(ieee->sta_sleep == 1)
ieee->sta_wake_up(ieee->dev);
+ if(nl){
- ieee->sta_sleep = 0;
+ if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
+ {
+ //printk("%s(3): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__);
+ //printk("Warning: driver is probably failing to report TX ps error\n");
+ ieee->ack_tx_to_ieee = 1;
+ ieee80211_sta_ps_send_null_frame(ieee, 0);
+ }
+ else
+ {
+ ieee->ack_tx_to_ieee = 1;
+ ieee->polling = true;
+ //printk("%s(4): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__);
+ //ieee80211_sta_ps_send_null_frame(ieee, 0);
+ ieee80211_sta_ps_send_pspoll_frame(ieee);
+ }
- if(nl){
- ieee->ack_tx_to_ieee = 1;
- ieee80211_sta_ps_send_null_frame(ieee, 0);
+ } else {
+ ieee->sta_sleep = 0;
+ ieee->polling = false;
}
}
@@ -2067,23 +2201,30 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
/* Null frame with PS bit set */
if(success){
ieee->sta_sleep = 1;
+ //printk("notify AP we will sleep and send null ok, so sleep now++++++++++ enter_sleep_state\n");
ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
}
- /* if the card report not success we can't be sure the AP
- * has not RXed so we can't assume the AP believe us awake
- */
- }
- /* 21112005 - tx again null without PS bit if lost */
- else {
+ } else {/* 21112005 - tx again null without PS bit if lost */
if((ieee->sta_sleep == 0) && !success){
spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- ieee80211_sta_ps_send_null_frame(ieee, 0);
+ //ieee80211_sta_ps_send_null_frame(ieee, 0);
+ if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
+ {
+ //printk("notify AP we will sleep but send bull failed, so resend++++++++++ SendNullFunctionData\n");
+ ieee80211_sta_ps_send_null_frame(ieee, 0);
+ }
+ else
+ {
+ //printk("notify AP we are awaked but send pspoll failed, so resend++++++++++ Send PS-Poll\n");
+ ieee80211_sta_ps_send_pspoll_frame(ieee);
+ }
spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
}
}
spin_unlock_irqrestore(&ieee->lock, flags);
}
+
void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
{
struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
@@ -2227,7 +2368,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
{
if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
{
- // WEP or TKIP encryption
+ // WEP or TKIP encryption
if(IsHTHalfNmodeAPs(ieee))
{
bSupportNmode = true;
@@ -2238,7 +2379,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
bSupportNmode = false;
bHalfSupportNmode = false;
}
- printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
+ printk("==========>to link with AP using SEC(%d, %d)\n", bSupportNmode, bHalfSupportNmode);
}
}
/* Dummy wirless mode setting to avoid encryption issue */
@@ -2574,6 +2715,7 @@ void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
ieee->ssid_set = 1;
}
+ ieee->state = IEEE80211_NOLINK;
/* check if we have this cell in our network list */
ieee80211_softmac_check_all_nets(ieee);
@@ -2705,6 +2847,10 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
spin_lock_irqsave(&ieee->lock, flags);
if (ieee->state == IEEE80211_NOLINK){
+#ifdef ENABLE_IPS
+ if(ieee->ieee80211_ips_leave_wq != NULL)
+ ieee->ieee80211_ips_leave_wq(ieee->dev);
+#endif
ieee->actscanning = true;
ieee80211_rtl_start_scan(ieee);
}
@@ -2823,21 +2969,23 @@ struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
return skb;
}
-void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
+void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
{
ieee->sync_scan_hurryup = 1;
down(&ieee->wx_sem);
- ieee80211_stop_protocol(ieee);
+ ieee80211_stop_protocol(ieee, shutdown);
up(&ieee->wx_sem);
}
-void ieee80211_stop_protocol(struct ieee80211_device *ieee)
+void ieee80211_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
{
if (!ieee->proto_started)
return;
- ieee->proto_started = 0;
+ if(shutdown)
+ ieee->proto_started = 0;
+ ieee->proto_stoppping = 1;
ieee80211_stop_send_beacons(ieee);
del_timer_sync(&ieee->associate_timer);
@@ -2849,6 +2997,8 @@ void ieee80211_stop_protocol(struct ieee80211_device *ieee)
ieee80211_disassociate(ieee);
RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
+
+ ieee->proto_stoppping = 0;
}
void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
@@ -2894,6 +3044,8 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee)
ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
+ ieee->state = IEEE80211_NOLINK;
+
/* if the user set the MAC of the ad-hoc cell and then
* switch to managed mode, shall we make sure that association
@@ -3013,7 +3165,9 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
#endif
sema_init(&ieee->wx_sem, 1);
sema_init(&ieee->scan_sem, 1);
-
+#ifdef ENABLE_IPS
+ sema_init(&ieee->ips_sem,1);
+#endif
spin_lock_init(&ieee->mgmt_tx_lock);
spin_lock_init(&ieee->beacon_lock);
@@ -3537,5 +3691,6 @@ EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests);
EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro);
EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro);
+EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_null_frame);
+EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_pspoll_frame);
#endif
-//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
index 7c21aaab906..1bbd49f1d6f 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
@@ -160,7 +160,7 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
}
if (ifup)
- ieee80211_stop_protocol(ieee);
+ ieee80211_stop_protocol(ieee,true);
/* just to avoid to give inconsistent infos in the
* get wx method. not really needed otherwise
@@ -302,7 +302,7 @@ int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info
if (!ieee->proto_started){
ieee->iw_mode = wrqu->mode;
}else{
- ieee80211_stop_protocol(ieee);
+ ieee80211_stop_protocol(ieee,true);
ieee->iw_mode = wrqu->mode;
ieee80211_start_protocol(ieee);
}
@@ -326,6 +326,17 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
int b40M = 0;
static int count = 0;
chan = ieee->current_network.channel;
+
+#ifdef ENABLE_LPS
+ if (ieee->LeisurePSLeave) {
+ ieee->LeisurePSLeave(ieee->dev);
+ }
+
+ /* notify AP to be in PS mode */
+ ieee80211_sta_ps_send_null_frame(ieee, 1);
+ ieee80211_sta_ps_send_null_frame(ieee, 1);
+#endif
+
netif_carrier_off(ieee->dev);
if (ieee->data_hard_stop)
@@ -360,6 +371,12 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
ieee->InitialGainHandler(ieee->dev,IG_Restore);
ieee->state = IEEE80211_LINKED;
ieee->link_change(ieee->dev);
+
+#ifdef ENABLE_LPS
+ /* Notify AP that I wake up again */
+ ieee80211_sta_ps_send_null_frame(ieee, 0);
+#endif
+
// To prevent the immediately calling watch_dog after scan.
if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
{
@@ -429,8 +446,9 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
goto out;
}
- if(proto_started)
- ieee80211_stop_protocol(ieee);
+ if(proto_started){
+ ieee80211_stop_protocol(ieee,true);
+ }
/* this is just to be sure that the GET wx callback
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
index 798fb4154c2..a75f3668a40 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
@@ -200,8 +200,8 @@ int ieee80211_encrypt_fragment(
header = (struct ieee80211_hdr *) frag->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "TX packet to " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(header->addr1));
+ "TX packet to %pM\n",
+ ieee->dev->name, header->addr1);
}
return -1;
}
@@ -334,6 +334,13 @@ void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* s
if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
return;
#endif
+
+ if(tcb_desc->bdhcp)// || ieee->CntAfterLink<2)
+ {
+ return;
+ }
+
+
#if 1
if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
{
@@ -628,6 +635,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
int qos_actived = ieee->current_network.qos_data.active;
struct ieee80211_crypt_data* crypt;
+ bool bdhcp =false;
cb_desc *tcb_desc;
@@ -672,6 +680,55 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
}
#endif
+ // The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time
+ // to prevent DHCP protocol fail
+ if (skb->len > 282){//MINIMUM_DHCP_PACKET_SIZE) {
+ if (ETH_P_IP == ether_type) {// IP header
+ const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
+ if (IPPROTO_UDP == ip->protocol) {//FIXME windows is 11 but here UDP in linux kernel is 17.
+ struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
+ //if(((ntohs(udp->source) == 68) && (ntohs(udp->dest) == 67)) ||
+ /// ((ntohs(udp->source) == 67) && (ntohs(udp->dest) == 68))) {
+ if(((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) ||
+ ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) {
+ // 68 : UDP BOOTP client
+ // 67 : UDP BOOTP server
+ printk("DHCP pkt src port:%d, dest port:%d!!\n", ((u8 *)udp)[1],((u8 *)udp)[3]);
+ // Use low rate to send DHCP packet.
+ //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
+ //{
+ // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
+ // tcb_desc->bTxDisableRateFallBack = false;
+ //}
+ //else
+ //pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate;
+ //RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
+
+ bdhcp = true;
+#ifdef _RTL8192_EXT_PATCH_
+ ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; //AMY,090701
+#else
+ ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2;
+#endif
+ }
+ }
+ }else if(ETH_P_ARP == ether_type){// IP ARP packet
+ printk("=================>DHCP Protocol start tx ARP pkt!!\n");
+ bdhcp = true;
+ ieee->LPSDelayCnt = ieee->current_network.tim.tim_count;
+
+ //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
+ //{
+ // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(Adapter->MgntInfo.mBrates);//0xc;//ofdm 6m
+ // tcb_desc->bTxDisableRateFallBack = FALSE;
+ //}
+ //else
+ // tcb_desc->DataRate = Adapter->MgntInfo.LowestBasicRate;
+ //RTPRINT(FDM, WA_IOT, ("ARP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
+
+ }
+ }
+
/* Save source and destination addresses */
memcpy(&dest, skb->data, ETH_ALEN);
memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
@@ -895,6 +952,25 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
else
//tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
+
+ if(bdhcp == true){
+ // Use low rate to send DHCP packet.
+ //if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) {
+ // tcb_desc->data_rate = MGN_1M;//MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
+ // tcb_desc->bTxDisableRateFallBack = false;
+ //}
+ //else
+ {
+ tcb_desc->data_rate = MGN_1M;
+ tcb_desc->bTxDisableRateFallBack = 1;
+ }
+
+ tcb_desc->RATRIndex = 7;
+ tcb_desc->bTxUseDriverAssingedRate = 1;
+ tcb_desc->bdhcp = 1;
+ }
+
+
ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
ieee80211_query_HTCapShortGI(ieee, tcb_desc);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
index 3441b72dd8f..de57967b968 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
@@ -32,6 +32,7 @@
#include <linux/wireless.h>
#include <linux/version.h>
#include <linux/kmod.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include "ieee80211.h"
@@ -386,10 +387,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
else
IEEE80211_DEBUG_SCAN(
"Not showing network '%s ("
- MAC_FMT ")' due to age (%lums).\n",
+ "%pM)' due to age (%lums).\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid),
+ network->bssid,
(jiffies - network->last_scanned) / (HZ / 100));
}
@@ -933,7 +934,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
#if 1
case IW_AUTH_WPA_ENABLED:
ieee->wpa_enabled = (data->value)?1:0;
- //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
+ //printk("enable wpa:%d\n", ieee->wpa_enabled);
break;
#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
index e41e8a0c739..ae0e5b9e218 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
u16 tmp = 0;
u16 len = ieee->tx_headroom + 9;
//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+ IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
if (pBA == NULL||ieee == NULL)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -243,7 +243,7 @@ static struct sk_buff* ieee80211_DELBA(
u16 len = 6 + ieee->tx_headroom;
if (net_ratelimit())
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+ IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
memset(&DelbaParamSet, 0, 2);
@@ -397,7 +397,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
pBaTimeoutVal = (u16*)(tag + 5);
pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
- printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
+ printk("====================>rx ADDBAREQ from :%pM\n", dst);
//some other capability is not ready now.
if( (ieee->current_network.qos_data.active == 0) ||
(ieee->pHTInfo->bCurrentHTSupport == false)) //||
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
index 992b71825a8..f968817d073 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
@@ -458,7 +458,8 @@ typedef enum _HT_IOT_PEER
HT_IOT_PEER_RALINK = 3,
HT_IOT_PEER_ATHEROS = 4,
HT_IOT_PEER_CISCO= 5,
- HT_IOT_PEER_MAX = 6
+ HT_IOT_PEER_MARVELL=6,
+ HT_IOT_PEER_MAX = 7
}HT_IOT_PEER_E, *PHTIOT_PEER_E;
//
@@ -475,6 +476,7 @@ typedef enum _HT_IOT_ACTION{
HT_IOT_ACT_CDD_FSYNC = 0x00000080,
HT_IOT_ACT_PURE_N_MODE = 0x00000100,
HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
+ HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000,
}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
#endif //_RTL819XU_HTTYPE_H_
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
index 1e392141779..4c4b1df350a 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
@@ -32,7 +32,7 @@ u16 MCS_DATA_RATE[2][2][77] =
static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
-static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
+//static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008
static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
@@ -40,8 +40,9 @@ static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
+static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
-// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
// code in other place??
//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
/********************************************************************************************************************
@@ -349,12 +350,12 @@ bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
bool retValue = false;
struct ieee80211_network* net = &ieee->current_network;
#if 0
- if(pMgntInfo->bHalfNMode == false)
+ if(ieee->bHalfNMode == false)
retValue = false;
else
#endif
if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
- (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
+ (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
(memcmp(net->bssid, PCI_RALINK, 3)==0) ||
(memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
(memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
@@ -363,7 +364,7 @@ bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
(memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
(memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
- (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
+ //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
(net->broadcom_cap_exist))
retValue = true;
else if(net->bssht.bdRT2RTAggregation)
@@ -387,13 +388,15 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee)
struct ieee80211_network* net = &ieee->current_network;
if(net->bssht.bdRT2RTAggregation)
pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
- else if(net->broadcom_cap_exist)
+ else if(net->broadcom_cap_exist){
pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+ }
else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
(memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
- (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
- (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) )
+ (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)){//||
+ //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ){
pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+ }
else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
(memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
(memcmp(net->bssid, PCI_RALINK, 3)==0) ||
@@ -405,6 +408,10 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee)
pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0)
pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
+ else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
+ net->marvell_cap_exist){
+ pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL;
+ }
else
pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
@@ -442,6 +449,18 @@ u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
return ret;
}
+u8 HTIOTActIsForcedCTS2Self(struct ieee80211_device *ieee, struct ieee80211_network *network)
+{
+ u8 retValue = 0;
+ //if(network->marvell_cap_exist)
+ if(ieee->pHTInfo->IOTPeer == HT_IOT_PEER_MARVELL)
+ {
+ retValue = 1;
+ }
+
+ return retValue;
+}
+
/**
* Function: HTIOTActIsDisableMCS15
@@ -578,6 +597,23 @@ u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
return retValue;
}
+//
+// Send null data for to tell AP that we are awake.
+//
+bool
+HTIOTActIsNullDataPowerSaving(struct ieee80211_device* ieee,struct ieee80211_network *network)
+{
+ bool retValue = false;
+
+ PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+ {
+ if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) // ||(pBssDesc->Vender == HT_IOT_PEER_ATHEROS && pBssDesc->SubTypeOfVender == HT_IOT_PEER_ATHEROS_DIR635))
+ return true;
+
+ }
+ return retValue;
+}
+
void HTResetIOTSetting(
PRT_HIGH_THROUGHPUT pHTInfo
)
@@ -1071,6 +1107,13 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
// Config and configure A-MSDU setting
//
pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
+ if (ieee->rtllib_ap_sec_type &&
+ (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))){
+ if( (pHTInfo->IOTPeer== HT_IOT_PEER_ATHEROS) ||
+ (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN) )
+ pHTInfo->bCurrentAMPDUEnable = false;
+ }
+
nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
@@ -1515,6 +1558,9 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80
bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
if(bIOTAction)
pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
+ bIOTAction = HTIOTActIsForcedCTS2Self(ieee, pNetwork);
+ if(bIOTAction)
+ pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
bIOTAction = HTIOTActIsDisableMCS15(ieee);
if(bIOTAction)
@@ -1537,6 +1583,9 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80
if(bIOTAction)
pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
+ bIOTAction = HTIOTActIsNullDataPowerSaving(ieee, pNetwork);
+ if(bIOTAction)
+ pHTInfo->IOTAction |= HT_IOT_ACT_NULL_DATA_POWER_SAVING;
}
else
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
index 2816b60a08a..e8699616fad 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
@@ -1,5 +1,6 @@
#include "ieee80211.h"
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include "rtl819x_TS.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
@@ -304,7 +305,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8
if(search_dir[dir] ==false )
continue;
list_for_each_entry(pRet, psearch_list, List){
- // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+ // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
if (memcmp(pRet->Addr, Addr, 6) == 0)
if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -466,7 +467,7 @@ bool GetTs(
ResetRxTsEntry(tmp);
}
- IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+ IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
// Prepare TS Info releated field
pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field
pTSInfo->field.ucTSID = UP; // TSID
@@ -552,7 +553,7 @@ void RemoveTsEntry(
void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
{
PTS_COMMON_INFO pTS, pTmpTS;
- printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+ printk("===========>RemovePeerTS,%pM\n", Addr);
#if 1
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
{
diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c
index 79f7a0f3962..262ed5fd086 100644
--- a/drivers/staging/rtl8192e/r8180_93cx6.c
+++ b/drivers/staging/rtl8192e/r8180_93cx6.c
@@ -22,7 +22,7 @@
static void eprom_cs(struct net_device *dev, short bit)
{
- if(bit)
+ if (bit)
write_nic_byte(dev, EPROM_CMD,
(1<<EPROM_CS_SHIFT) | \
read_nic_byte(dev, EPROM_CMD)); //enable EPROM
@@ -38,23 +38,23 @@ static void eprom_cs(struct net_device *dev, short bit)
static void eprom_ck_cycle(struct net_device *dev)
{
write_nic_byte(dev, EPROM_CMD,
- (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
+ (1<<EPROM_CK_SHIFT) | read_nic_byte(dev, EPROM_CMD));
force_pci_posting(dev);
udelay(EPROM_DELAY);
write_nic_byte(dev, EPROM_CMD,
- read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
+ read_nic_byte(dev, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT));
force_pci_posting(dev);
udelay(EPROM_DELAY);
}
-static void eprom_w(struct net_device *dev,short bit)
+static void eprom_w(struct net_device *dev, short bit)
{
- if(bit)
+ if (bit)
write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
- read_nic_byte(dev,EPROM_CMD));
+ read_nic_byte(dev, EPROM_CMD));
else
- write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
+ write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
&~(1<<EPROM_W_SHIFT));
force_pci_posting(dev);
@@ -66,10 +66,11 @@ static short eprom_r(struct net_device *dev)
{
short bit;
- bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
+ bit = (read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT));
udelay(EPROM_DELAY);
- if(bit) return 1;
+ if (bit)
+ return 1;
return 0;
}
@@ -78,7 +79,7 @@ static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
{
int i;
- for(i=0; i<len; i++){
+ for (i = 0; i < len; i++) {
eprom_w(dev, b[i]);
eprom_ck_cycle(dev);
}
@@ -88,37 +89,37 @@ static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
u32 eprom_read(struct net_device *dev, u32 addr)
{
struct r8192_priv *priv = ieee80211_priv(dev);
- short read_cmd[]={1,1,0};
+ short read_cmd[] = {1, 1, 0};
short addr_str[8];
int i;
int addr_len;
u32 ret;
- ret=0;
+ ret = 0;
//enable EPROM programming
write_nic_byte(dev, EPROM_CMD,
(EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
force_pci_posting(dev);
udelay(EPROM_DELAY);
- if (priv->epromtype==EPROM_93c56){
- addr_str[7]=addr & 1;
- addr_str[6]=addr & (1<<1);
- addr_str[5]=addr & (1<<2);
- addr_str[4]=addr & (1<<3);
- addr_str[3]=addr & (1<<4);
- addr_str[2]=addr & (1<<5);
- addr_str[1]=addr & (1<<6);
- addr_str[0]=addr & (1<<7);
- addr_len=8;
- }else{
- addr_str[5]=addr & 1;
- addr_str[4]=addr & (1<<1);
- addr_str[3]=addr & (1<<2);
- addr_str[2]=addr & (1<<3);
- addr_str[1]=addr & (1<<4);
- addr_str[0]=addr & (1<<5);
- addr_len=6;
+ if (priv->epromtype == EPROM_93c56) {
+ addr_str[7] = addr & 1;
+ addr_str[6] = addr & (1<<1);
+ addr_str[5] = addr & (1<<2);
+ addr_str[4] = addr & (1<<3);
+ addr_str[3] = addr & (1<<4);
+ addr_str[2] = addr & (1<<5);
+ addr_str[1] = addr & (1<<6);
+ addr_str[0] = addr & (1<<7);
+ addr_len = 8;
+ } else {
+ addr_str[5] = addr & 1;
+ addr_str[4] = addr & (1<<1);
+ addr_str[3] = addr & (1<<2);
+ addr_str[2] = addr & (1<<3);
+ addr_str[1] = addr & (1<<4);
+ addr_str[0] = addr & (1<<5);
+ addr_len = 6;
}
eprom_cs(dev, 1);
eprom_ck_cycle(dev);
@@ -129,7 +130,7 @@ u32 eprom_read(struct net_device *dev, u32 addr)
//I'm unsure if it is necessary, but anyway shouldn't hurt
eprom_w(dev, 0);
- for(i=0;i<16;i++){
+ for (i = 0; i < 16; i++) {
//eeprom needs a clk cycle between writing opcode&adr
//and reading data. (eeprom outs a dummy 0)
eprom_ck_cycle(dev);
diff --git a/drivers/staging/rtl8192e/r8180_93cx6.h b/drivers/staging/rtl8192e/r8180_93cx6.h
index 62e14c78e96..4c3f675c6a6 100644
--- a/drivers/staging/rtl8192e/r8180_93cx6.h
+++ b/drivers/staging/rtl8192e/r8180_93cx6.h
@@ -1,17 +1,18 @@
-/*
- This is part of rtl8187 OpenSource driver
- Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
- Released under the terms of GPL (General Public Licence)
-
- Parts of this driver are based on the GPL part of the official realtek driver
- Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
- Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
- We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/*This files contains card eeprom (93c46 or 93c56) programming routines*/
-/*memory is addressed by WORDS*/
+/* r8180_93cx6.h - 93c46 or 93c56 eeprom card programming routines
+ *
+ * This is part of rtl8187 OpenSource driver
+ * Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
+ * Released under the terms of GPL (General Public Licence)
+ * Parts of this driver are based on the GPL part of the official realtek driver
+ *
+ * Parts of this driver are based on the rtl8180 driver skeleton from
+ * Patric Schenke & Andres Salomon.
+ *
+ * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
+ *
+ * We want to thank the authors of the above mentioned projects and to
+ * the authors of the Ndiswrapper project.
+ */
#include "r8192E.h"
#include "r8192E_hw.h"
@@ -36,5 +37,5 @@
#define EPROM_TXPW2 0x1b
#define EPROM_TXPW1 0x3d
-
-u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
+/* Reads a 16 bits word. */
+u32 eprom_read(struct net_device *dev, u32 addr);
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c
index 3d67fbb65b9..1bd054d42f2 100644
--- a/drivers/staging/rtl8192e/r8190_rtl8256.c
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.c
@@ -429,11 +429,12 @@ SetRFPowerState8190(
bool bResult = true;
//u8 eRFPath;
u8 i = 0, QueueID = 0;
- ptx_ring head=NULL,tail=NULL;
+ //ptx_ring head=NULL,tail=NULL;
+ struct rtl8192_tx_ring *ring = NULL;
if(priv->SetRFPowerStateInProgress == true)
return false;
- RT_TRACE(COMP_POWER, "===========> SetRFPowerState8190()!\n");
+ //RT_TRACE(COMP_PS, "===========> SetRFPowerState8190()!\n");
priv->SetRFPowerStateInProgress = true;
switch(priv->rf_chip)
@@ -442,11 +443,11 @@ SetRFPowerState8190(
switch( eRFPowerState )
{
case eRfOn:
- RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOn !\n");
+ //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOn !\n");
//RXTX enable control: On
//for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
- // PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2);
- #ifdef RTL8190P
+ // PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2);
+#ifdef RTL8190P
if(priv->rf_type == RF_2T4R)
{
//enable RF-Chip A/B
@@ -479,36 +480,92 @@ SetRFPowerState8190(
//analog to digital part2 on
rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11]
}
- #else
- write_nic_byte(dev, ANAPAR, 0x37);//160MHz
- write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403
- mdelay(1);
- //enable clock 80/88 MHz
-
- priv->bHwRfOffAction = 0;
- //}
-
- // Baseband reset 2008.09.30 add
- write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0));
-
- //2 AFE
- // 2008.09.30 add
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884
- //analog to digital part2 on
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
- //digital to analog on
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3]
- //analog to digital on
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8]
- //rx antenna on
- //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
- //rx antenna on 2008.09.30 mark
- //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
-
- //2 RF
- //enable RF-Chip A/B
+ else if(priv->rf_type == RF_1T1R) //RF-C
+ {
+ //enable RF-Chip C/D
+ rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4]
+ //analog to digital on
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x400, 0x1);// 0x88c[10]
+ //digital to analog on
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x80, 0x1); // 0x880[7]
+ //rx antenna on
+ rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x4, 0x1);// 0xc04[2]
+ //rx antenna on
+ rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x4, 0x1);// 0xd04[2]
+ //analog to digital part2 on
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x800, 0x1); // 0x880[11]
+ }
+
+#elif defined RTL8192E
+ // turn on RF
+ if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
+ { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC.
+ bool rtstatus = true;
+ u32 InitilizeCount = 3;
+ do
+ {
+ InitilizeCount--;
+ priv->RegRfOff = false;
+ rtstatus = NicIFEnableNIC(dev);
+ }while( (rtstatus != true) &&(InitilizeCount >0) );
+
+ if(rtstatus != true)
+ {
+ RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__);
+ priv->SetRFPowerStateInProgress = false;
+ return false;
+ }
+
+ RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
+ } else {
+ write_nic_byte(dev, ANAPAR, 0x37);//160MHz
+ //write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403
+ mdelay(1);
+ //enable clock 80/88 MHz
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2]
+ priv->bHwRfOffAction = 0;
+ //}
+
+ //RF-A, RF-B
+ //enable RF-Chip A/B
rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
- rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4]
+ //analog to digital on
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
+ //digital to analog on
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
+ //rx antenna on
+ rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
+ //rx antenna on
+ rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
+ //analog to digital part2 on
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
+
+ // Baseband reset 2008.09.30 add
+ //write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0));
+
+ //2 AFE
+ // 2008.09.30 add
+ //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884
+ //analog to digital part2 on
+ //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
+
+
+ //digital to analog on
+ //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3]
+ //analog to digital on
+ //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8]
+ //rx antenna on
+ //PHY_SetBBReg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
+ //rx antenna on 2008.09.30 mark
+ //PHY_SetBBReg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
+
+ //2 RF
+ //enable RF-Chip A/B
+ //rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
+ //rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4]
+
+ }
+
#endif
break;
@@ -517,119 +574,137 @@ SetRFPowerState8190(
// By Bruce, 2008-01-16.
//
case eRfSleep:
- case eRfOff:
- RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOff/Sleep !\n");
- if (pPSC->bLeisurePs)
+ {
+ // HW setting had been configured with deeper mode.
+ if(priv->ieee80211->eRFPowerState == eRfOff)
+ break;
+
+ // Update current RF state variable.
+ //priv->ieee80211->eRFPowerState = eRFPowerState;
+
+ //if (pPSC->bLeisurePs)
{
for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
{
- switch(QueueID) {
- case MGNT_QUEUE:
- tail=priv->txmapringtail;
- head=priv->txmapringhead;
+ ring = &priv->tx_ring[QueueID];
+
+ if(skb_queue_len(&ring->queue) == 0)
+ {
+ QueueID++;
+ continue;
+ }
+ else
+ {
+ RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
+ udelay(10);
+ i++;
+ }
+
+ if(i >= MAX_DOZE_WAITING_TIMES_9x)
+ {
+ RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
break;
+ }
+ }
+ }
- case BK_QUEUE:
- tail=priv->txbkpringtail;
- head=priv->txbkpringhead;
+ //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
+#ifdef RTL8190P
+ {
+ PHY_SetRtl8190pRfOff(dev);
+ }
+ //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+#elif defined RTL8192E
+ {
+ PHY_SetRtl8192eRfOff(dev);
+ }
+#endif
+ }
break;
- case BE_QUEUE:
- tail=priv->txbepringtail;
- head=priv->txbepringhead;
- break;
+ case eRfOff:
+ //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOff/Sleep !\n");
- case VI_QUEUE:
- tail=priv->txvipringtail;
- head=priv->txvipringhead;
- break;
+ // Update current RF state variable.
+ //priv->ieee80211->eRFPowerState = eRFPowerState;
- case VO_QUEUE:
- tail=priv->txvopringtail;
- head=priv->txvopringhead;
- break;
+ //
+ // Disconnect with Any AP or STA.
+ //
+ for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
+ {
+ ring = &priv->tx_ring[QueueID];
- default:
- tail=head=NULL;
- break;
- }
- if(tail == head)
+ if(skb_queue_len(&ring->queue) == 0)
{
- //DbgPrint("QueueID = %d", QueueID);
QueueID++;
continue;
}
else
{
- RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d times BusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
+ RT_TRACE(COMP_POWER,
+ "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
udelay(10);
i++;
}
if(i >= MAX_DOZE_WAITING_TIMES_9x)
{
- RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
+ RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
break;
}
}
+
+ //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
+#if defined RTL8190P
+ {
+ PHY_SetRtl8190pRfOff(dev);
}
- #ifdef RTL8190P
- if(priv->rf_type == RF_2T4R)
+ //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+#elif defined RTL8192E
{
- //disable RF-Chip A/B
- rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4]
+ //if(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC) && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
+ if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
+ { // Disable all components.
+ //
+ // Note:
+ // NicIFSetLinkStatus is a big problem when we indicate the status to OS,
+ // the OS(XP) will reset. But now, we cnnot find why the NIC is hard to receive
+ // packets after RF ON. Just keep this function here and still work to find out the root couse.
+ // By Bruce, 2009-05-01.
+ //
+ //NicIFSetLinkStatus( Adapter, RT_MEDIA_DISCONNECT );
+ //if HW radio of , need to indicate scan complete first for not be reset.
+ //if(MgntScanInProgress(pMgntInfo))
+ // MgntResetScanProcess( Adapter );
+
+ // <1> Disable Interrupt
+ //rtl8192_irq_disable(dev);
+ // <2> Stop all timer
+ //MgntCancelAllTimer(Adapter);
+ // <3> Disable Adapter
+ //NicIFHaltAdapter(Adapter, false);
+ NicIFDisableNIC(dev);
+ RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
+ }
+ else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC))
+ { // Normal case.
+ // IPS should go to this.
+ PHY_SetRtl8192eRfOff(dev);
+ }
+ }
+#else
+ else
+ {
+ RT_TRACE(COMP_DBG,DBG_TRACE,("It is not 8190Pci and 8192PciE \n"));
}
- //disable RF-Chip C/D
- rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x0); // 0x868[4]
- //analog to digital off, for power save
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
- //digital to analog off, for power save
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0x0); // 0x880[8:5]
- //rx antenna off
- rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
- //rx antenna off
- rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
- //analog to digital part2 off, for power save
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0x0); // 0x880[12:9]
-#else //8192E
- //2 RF
- //disable RF-Chip A/B
- rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4]
- rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x0); // 0x864[4]
- //2 AFE
- //analog to digital off, for power save
- //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0x0); // 2008.09.30 Modify
- //digital to analog off, for power save
- //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x0); // 0x880 2008.09.30 Modify
- //rx antenna off 2008.09.30 mark
- //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
- //rx antenna off 2008.09.30 mark
- //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
- //analog to digital part2 off, for power save
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); // 0x880[6:5]
- // 2008.09.30 add
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x0); // 0x884
-
-
- //disable clock 80/88 MHz 2008.09.30 mark
- //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x4, 0x0); // 0x880[2]
- //2 BB
- // Baseband reset 2008.09.30 add
- write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); // 0x101
- //MAC: off
- write_nic_byte(dev, MacBlkCtrl, 0x0); // 0x403
- //slow down cpu/lbus clock from 160MHz to Lower
- write_nic_byte(dev, ANAPAR, 0x07); // 0x 17 40MHz
- priv->bHwRfOffAction = 0;
- //}
#endif
+
break;
default:
bResult = false;
- RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknown state to set: 0x%X!!!\n", eRFPowerState);
+ RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState);
break;
}
@@ -644,64 +719,11 @@ SetRFPowerState8190(
{
// Update current RF state variable.
priv->ieee80211->eRFPowerState = eRFPowerState;
-
- switch(priv->rf_chip )
- {
- case RF_8256:
- switch(priv->ieee80211->eRFPowerState)
- {
- case eRfOff:
- //
- //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
- //
- if(priv->ieee80211->RfOffReason==RF_CHANGE_BY_IPS )
- {
- #ifdef TO_DO
- Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
- #endif
- }
- else
- {
- // Turn off LED if RF is not ON.
- #ifdef TO_DO
- Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
- #endif
- }
- break;
-
- case eRfOn:
- // Turn on RF we are still linked, which might happen when
- // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
- if( priv->ieee80211->state == IEEE80211_LINKED)
- {
- #ifdef TO_DO
- Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
- #endif
- }
- else
- {
- // Turn off LED if RF is not ON.
- #ifdef TO_DO
- Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
- #endif
- }
- break;
-
- default:
- // do nothing.
- break;
- }// Switch RF state
-
- break;
-
- default:
- RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n");
- break;
- }// Switch RFChipID
}
+ //printk("%s()priv->ieee80211->eRFPowerState:%s\n" ,__func__,priv->ieee80211->eRFPowerState == eRfOn ? "On" : "Off");
priv->SetRFPowerStateInProgress = false;
- RT_TRACE(COMP_POWER, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult);
+ //RT_TRACE(COMP_PS, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult);
return bResult;
}
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h
index 7d9095a70ae..ce49c606521 100644
--- a/drivers/staging/rtl8192e/r8190_rtl8256.h
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.h
@@ -1,28 +1,33 @@
-/*
- This is part of the rtl8180-sa2400 driver
- released under the GPL (See file COPYING for details).
- Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+/* r8190_rtl8256.h - rtl8256 radio frontend
+ *
+ * This is part of the rtl8180-sa2400 driver
+ * released under the GPL (See file COPYING for details).
+ * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Many thanks to Realtek Corp. for their great support!
+ */
- This files contains programming code for the rtl8256
- radio frontend.
-
- *Many* thanks to Realtek Corp. for their great support!
-
-*/
-
-#ifndef RTL8225H
-#define RTL8225H
+#ifndef RTL8225_H
+#define RTL8225_H
#ifdef RTL8190P
-#define RTL819X_TOTAL_RF_PATH 4
+#define RTL819X_TOTAL_RF_PATH 4
#else
-#define RTL819X_TOTAL_RF_PATH 2 //for 8192E
+#define RTL819X_TOTAL_RF_PATH 2 /* for 8192E */
#endif
-extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
-extern RT_STATUS PHY_RF8256_Config(struct net_device* dev);
-extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev);
-extern void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel);
-extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
-extern bool MgntActSet_RF_State(struct net_device* dev, RT_RF_POWER_STATE StateToSet, RT_RF_CHANGE_SOURCE ChangeSource);
-#endif
+extern void PHY_SetRF8256Bandwidth(struct net_device *dev,
+ HT_CHANNEL_WIDTH Bandwidth);
+
+extern RT_STATUS PHY_RF8256_Config(struct net_device *dev);
+
+extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device *dev);
+
+extern void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel);
+extern void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel);
+
+extern bool MgntActSet_RF_State(struct net_device *dev,
+ RT_RF_POWER_STATE StateToSet,
+ RT_RF_CHANGE_SOURCE ChangeSource);
+
+#endif /* RTL8225_H */
diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h
index 61b6f250b91..f4be9cc1100 100644
--- a/drivers/staging/rtl8192e/r8192E.h
+++ b/drivers/staging/rtl8192e/r8192E.h
@@ -39,7 +39,7 @@
#include <linux/random.h>
#include <linux/version.h>
#include <asm/io.h>
-#include "ieee80211.h"
+#include "ieee80211/ieee80211.h"
@@ -1003,6 +1003,11 @@ typedef struct r8192_priv
int irq;
short irq_enabled;
struct ieee80211_device *ieee80211;
+#ifdef ENABLE_LPS
+ bool ps_force;
+ bool force_lps;
+ bool bdisable_nic;
+#endif
bool being_init_adapter;
u8 Rf_Mode;
short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */
@@ -1477,7 +1482,7 @@ void write_nic_word(struct net_device *dev, int x,u16 y);
void write_nic_dword(struct net_device *dev, int x,u32 y);
void force_pci_posting(struct net_device *dev);
-void rtl8192_rtx_disable(struct net_device *);
+void rtl8192_halt_adapter(struct net_device *dev, bool reset);
void rtl8192_rx_enable(struct net_device *);
void rtl8192_tx_enable(struct net_device *);
@@ -1512,5 +1517,19 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev);
#ifdef ENABLE_IPS
void IPSEnter(struct net_device *dev);
void IPSLeave(struct net_device *dev);
+void InactivePsWorkItemCallback(struct net_device *dev);
+void IPSLeave_wq(void *data);
+void ieee80211_ips_leave_wq(struct net_device *dev);
+void ieee80211_ips_leave(struct net_device *dev);
+#endif
+#ifdef ENABLE_LPS
+void LeisurePSEnter(struct net_device *dev);
+void LeisurePSLeave(struct net_device *dev);
#endif
+
+bool NicIFEnableNIC(struct net_device* dev);
+bool NicIFDisableNIC(struct net_device* dev);
+
+void rtl8192_irq_disable(struct net_device *dev);
+void PHY_SetRtl8192eRfOff(struct net_device* dev);
#endif
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c
index 0ca5d8b4f74..bb7e1ef28d3 100644
--- a/drivers/staging/rtl8192e/r8192E_core.c
+++ b/drivers/staging/rtl8192e/r8192E_core.c
@@ -47,6 +47,7 @@
//#define CONFIG_RTL8192_IO_MAP
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include "r8192E_hw.h"
#include "r8192E.h"
@@ -66,7 +67,7 @@
#endif
#ifdef ENABLE_DOT11D
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
#endif
//set here to open your trace code. //WB
@@ -75,7 +76,7 @@ u32 rt_global_debug_component = \
// COMP_EPROM |
// COMP_PHY |
// COMP_RF |
- COMP_FIRMWARE |
+// COMP_FIRMWARE |
// COMP_TRACE |
// COMP_DOWN |
// COMP_SWBW |
@@ -343,6 +344,141 @@ void write_nic_word(struct net_device *dev, int x,u16 y)
#endif /* RTL_IO_MAP */
+u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
+{
+ //struct r8192_priv* priv = ieee80211_priv(dev);
+ //struct ieee80211_device *ieee = priv->ieee80211;
+
+ static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
+ static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
+ int wpa_ie_len= ieee->wpa_ie_len;
+ struct ieee80211_crypt_data* crypt;
+ int encrypt;
+
+ crypt = ieee->crypt[ieee->tx_keyidx];
+
+ encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||\
+ (ieee->host_encrypt && crypt && crypt->ops && \
+ (0 == strcmp(crypt->ops->name,"WEP")));
+
+ /* simply judge */
+ if(encrypt && (wpa_ie_len == 0)) {
+ // wep encryption, no N mode setting */
+ return SEC_ALG_WEP;
+ } else if((wpa_ie_len != 0)) {
+ // parse pairwise key type */
+ if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) ||
+ ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
+ return SEC_ALG_CCMP;
+ else
+ return SEC_ALG_TKIP;
+ } else {
+ return SEC_ALG_NONE;
+ }
+}
+
+void
+rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val)
+{
+ struct r8192_priv* priv = ieee80211_priv(dev);
+
+ switch(variable)
+ {
+
+ case HW_VAR_BSSID:
+ write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]);
+ write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]);
+ break;
+
+ case HW_VAR_MEDIA_STATUS:
+ {
+ RT_OP_MODE OpMode = *((RT_OP_MODE *)(val));
+ //LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
+ u8 btMsr = read_nic_byte(dev, MSR);
+
+ btMsr &= 0xfc;
+
+ switch(OpMode)
+ {
+ case RT_OP_MODE_INFRASTRUCTURE:
+ btMsr |= MSR_INFRA;
+ //LedAction = LED_CTL_LINK;
+ break;
+
+ case RT_OP_MODE_IBSS:
+ btMsr |= MSR_ADHOC;
+ // led link set seperate
+ break;
+
+ case RT_OP_MODE_AP:
+ btMsr |= MSR_AP;
+ //LedAction = LED_CTL_LINK;
+ break;
+
+ default:
+ btMsr |= MSR_NOLINK;
+ break;
+ }
+
+ write_nic_byte(dev, MSR, btMsr);
+
+ //priv->ieee80211->LedControlHandler(dev, LedAction);
+ }
+ break;
+
+ case HW_VAR_CECHK_BSSID:
+ {
+ u32 RegRCR, Type;
+
+ Type = ((u8*)(val))[0];
+ //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_RCR, (u8*)(&RegRCR));
+ RegRCR = read_nic_dword(dev,RCR);
+ priv->ReceiveConfig = RegRCR;
+
+ if (Type == true)
+ RegRCR |= (RCR_CBSSID);
+ else if (Type == false)
+ RegRCR &= (~RCR_CBSSID);
+
+ //priv->ieee80211->SetHwRegHandler( dev, HW_VAR_RCR, (u8*)(&RegRCR) );
+ write_nic_dword(dev, RCR,RegRCR);
+ priv->ReceiveConfig = RegRCR;
+
+ }
+ break;
+
+ case HW_VAR_SLOT_TIME:
+ {
+ //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
+ //AC_CODING eACI;
+
+ priv->slot_time = val[0];
+ write_nic_byte(dev, SLOT_TIME, val[0]);
+
+ }
+ break;
+
+ case HW_VAR_ACK_PREAMBLE:
+ {
+ u32 regTmp = 0;
+ priv->short_preamble = (bool)(*(u8*)val );
+ regTmp = priv->basic_rate;
+ if (priv->short_preamble)
+ regTmp |= BRSR_AckShortPmb;
+ write_nic_dword(dev, RRSR, regTmp);
+ }
+ break;
+
+ case HW_VAR_CPU_RST:
+ write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]);
+ break;
+
+ default:
+ break;
+ }
+
+}
+
///////////////////////////////////////////////////////////
@@ -365,11 +501,6 @@ void rtl8192_restart(struct work_struct *work);
//void rtl8192_rq_tx_ack(struct work_struct *work);
void watch_dog_timer_callback(unsigned long data);
-#ifdef ENABLE_IPS
-void IPSEnter(struct net_device *dev);
-void IPSLeave(struct net_device *dev);
-void InactivePsWorkItemCallback(struct net_device *dev);
-#endif
/****************************************************************************
-----------------------------PROCFS STUFF-------------------------
*****************************************************************************/
@@ -707,7 +838,7 @@ static void rtl8192_irq_enable(struct net_device *dev)
}
-static void rtl8192_irq_disable(struct net_device *dev)
+void rtl8192_irq_disable(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -717,6 +848,7 @@ static void rtl8192_irq_disable(struct net_device *dev)
}
+#if 0
static void rtl8192_set_mode(struct net_device *dev,int mode)
{
u8 ecmd;
@@ -727,7 +859,7 @@ static void rtl8192_set_mode(struct net_device *dev,int mode)
ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
write_nic_byte(dev, EPROM_CMD, ecmd);
}
-
+#endif
void rtl8192_update_msr(struct net_device *dev)
{
@@ -861,7 +993,7 @@ static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
ring->desc = NULL;
}
-
+#if 0
static void rtl8192_beacon_disable(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -873,38 +1005,116 @@ static void rtl8192_beacon_disable(struct net_device *dev)
reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
}
+#endif
+
+void PHY_SetRtl8192eRfOff(struct net_device* dev )
+{
+ //struct r8192_priv *priv = ieee80211_priv(dev);
+
+ //disable RF-Chip A/B
+ rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);
+ //analog to digital off, for power save
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
+ //digital to analog off, for power save
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
+ //rx antenna off
+ rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
+ //rx antenna off
+ rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
+ //analog to digital part2 off, for power save
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);
+ rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0);
+ // Analog parameter!!Change bias and Lbus control.
+ write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07);
+
+}
-void rtl8192_rtx_disable(struct net_device *dev)
+void rtl8192_halt_adapter(struct net_device *dev, bool reset)
{
- u8 cmd;
+ //u8 cmd;
struct r8192_priv *priv = ieee80211_priv(dev);
- int i;
+ int i;
+ u8 OpMode;
+ u8 u1bTmp;
+ u32 ulRegRead;
+
+ OpMode = RT_OP_MODE_NO_LINK;
+ priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode);
+#if 1
+ if(!priv->ieee80211->bSupportRemoteWakeUp)
+ {
+ u1bTmp = 0x0; // disable tx/rx. In 8185 we write 0x10 (Reset bit), but here we make reference to WMAC and wirte 0x0. 2006.11.21 Emily
+ //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp ); // Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
+ write_nic_byte(dev, CMDR, u1bTmp);
+ }
+#else
cmd=read_nic_byte(dev,CMDR);
-// if(!priv->ieee80211->bSupportRemoteWakeUp) {
- write_nic_byte(dev, CMDR, cmd &~ \
- (CR_TE|CR_RE));
-// }
- force_pci_posting(dev);
- mdelay(30);
+ write_nic_byte(dev, CMDR, cmd &~ (CR_TE|CR_RE));
+#endif
- for(i = 0; i < MAX_QUEUE_SIZE; i++) {
- skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
- }
- for(i = 0; i < MAX_QUEUE_SIZE; i++) {
- skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
- }
+ mdelay(20);
+ if(!reset)
+ {
+ //PlatformStallExecution(150000);
+ mdelay(150);
+
+#ifdef RTL8192E
+ priv->bHwRfOffAction = 2;
+#endif
+
+ //
+ // Call MgntActSet_RF_State instead to prevent RF config race condition.
+ // By Bruce, 2008-01-17.
+ //
+ if(!priv->ieee80211->bSupportRemoteWakeUp)
+ {
+ //MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT);
+ //MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason);
+ //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
+
+ PHY_SetRtl8192eRfOff(dev);
+
+ // 2006.11.30. System reset bit
+ //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) );
+ ulRegRead = read_nic_dword(dev,CPU_GEN);
+ ulRegRead|=CPU_GEN_SYSTEM_RESET;
+ //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead);
+ write_nic_dword(dev,CPU_GEN, ulRegRead);
+ }
+ else
+ {
+ //2008.06.03 for WOL
+ write_nic_dword(dev, WFCRC0, 0xffffffff);
+ write_nic_dword(dev, WFCRC1, 0xffffffff);
+ write_nic_dword(dev, WFCRC2, 0xffffffff);
+
+ //Write PMR register
+ write_nic_byte(dev, PMR, 0x5);
+ //Disable tx, enanble rx
+ write_nic_byte(dev, MacBlkCtrl, 0xa);
+ }
+ }
+
+ for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+ skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
+ }
+ for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+ skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
+ }
skb_queue_purge(&priv->skb_queue);
return;
}
+#if 0
static void rtl8192_reset(struct net_device *dev)
{
rtl8192_irq_disable(dev);
printk("This is RTL819xP Reset procedure\n");
}
+#endif
static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
inline u16 rtl8192_rate2rate(short rate)
@@ -954,6 +1164,12 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
/* shall not be referred by command packet */
assert(queue_index != TXCMD_QUEUE);
+ if((priv->bHwRadioOff == true)||(!priv->up))
+ {
+ kfree_skb(skb);
+ return;
+ }
+
//spin_lock_irqsave(&priv->tx_lock,flags);
memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
@@ -996,6 +1212,13 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
u8 queue_index = tcb_desc->queue_index;
+ if(queue_index != TXCMD_QUEUE){
+ if((priv->bHwRadioOff == true)||(!priv->up))
+ {
+ kfree_skb(skb);
+ return 0;
+ }
+ }
//spin_lock_irqsave(&priv->tx_lock,flags);
@@ -1379,6 +1602,15 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
u8* pda_addr = NULL;
int idx;
+ if(priv->bdisable_nic){
+ RT_TRACE(COMP_ERR,"%s: ERR!! Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", __FUNCTION__, skb->len, tcb_desc->queue_index);
+ return skb->len;
+ }
+
+#ifdef ENABLE_LPS
+ priv->ieee80211->bAwakePktSent = true;
+#endif
+
mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
/* collect the tx packets statitcs */
pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
@@ -1481,6 +1713,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
tcb_desc->queue_index,ring->idx, idx,skb->len);
+ spin_unlock_irqrestore(&priv->irq_th_lock,flags);
return skb->len;
}
@@ -1575,7 +1808,7 @@ static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
return 0;
priv->rx_buf[i] = skb;
mapping = (dma_addr_t *)skb->cb;
- *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
+ *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
priv->rxbuffersize, PCI_DMA_FROMDEVICE);
entry->BufferAddress = cpu_to_le32(*mapping);
@@ -1779,7 +2012,7 @@ static void rtl8192_qos_activate(struct work_struct * work)
(((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
(((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
- printk("===>u4bAcParam:%x, ", u4bAcParam);
+ //printk("===>u4bAcParam:%x, ", u4bAcParam);
write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
//write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
}
@@ -1964,11 +2197,24 @@ void rtl8192_update_ratr_table(struct net_device* dev)
write_nic_byte(dev, UFWP, 1);
}
+#if 0
static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
+#endif
+
static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
{
#if 1
+
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee80211;
+ if (ieee->rtllib_ap_sec_type &&
+ (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) {
+ return false;
+ } else {
+ return true;
+ }
+#else
struct r8192_priv* priv = ieee80211_priv(dev);
struct ieee80211_device* ieee = priv->ieee80211;
int wpa_ie_len= ieee->wpa_ie_len;
@@ -1995,18 +2241,6 @@ static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
return true;
}
-#if 0
- //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
- //We can't force in G mode if Pairwie key is AES and group key is TKIP
- if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
- (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
- (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
- {
- return false;
- }
- else
- return true;
-#endif
return true;
#endif
}
@@ -2080,7 +2314,7 @@ static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
wireless_mode = WIRELESS_MODE_B;
}
}
-#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
#endif
priv->ieee80211->mode = wireless_mode;
@@ -2127,7 +2361,19 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev)
}
static void rtl8192_hw_sleep_down(struct net_device *dev)
{
- RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&priv->rf_ps_lock,flags);
+ if (priv->RFChangeInProgress) {
+ spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
+ RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
+ printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
+ return;
+ }
+ spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
+ //RT_TRACE(COMP_PS, "%s()============>come to sleep down\n", __FUNCTION__);
+
MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
}
static void rtl8192_hw_sleep_wq (struct work_struct *work)
@@ -2138,21 +2384,29 @@ static void rtl8192_hw_sleep_wq (struct work_struct *work)
struct delayed_work *dwork = container_of(work,struct delayed_work,work);
struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
struct net_device *dev = ieee->dev;
- //printk("=========>%s()\n", __FUNCTION__);
+
rtl8192_hw_sleep_down(dev);
}
-// printk("dev is %d\n",dev);
-// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
+
static void rtl8192_hw_wakeup(struct net_device* dev)
{
-// u32 flags = 0;
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&priv->rf_ps_lock,flags);
+ if (priv->RFChangeInProgress) {
+ spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
+ RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n");
+ printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
+ queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20
+ return;
+ }
+ spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
-// spin_lock_irqsave(&priv->ps_lock,flags);
- RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
+ //RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __FUNCTION__);
MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
- //FIXME: will we send package stored while nic is sleep?
-// spin_unlock_irqrestore(&priv->ps_lock,flags);
}
+
void rtl8192_hw_wakeup_wq (struct work_struct *work)
{
// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
@@ -2169,7 +2423,6 @@ void rtl8192_hw_wakeup_wq (struct work_struct *work)
#define MAX_SLEEP_TIME 10000
static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
{
-
struct r8192_priv *priv = ieee80211_priv(dev);
u32 rb = jiffies;
@@ -2177,58 +2430,55 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
spin_lock_irqsave(&priv->ps_lock,flags);
- /* Writing HW register with 0 equals to disable
- * the timer, that is not really what we want
- */
- tl -= MSECS(4+16+7);
-
- //if(tl == 0) tl = 1;
-
- /* FIXME HACK FIXME HACK */
-// force_pci_posting(dev);
- //mdelay(1);
-
-// rb = read_nic_dword(dev, TSFTR);
+ // Writing HW register with 0 equals to disable
+ // the timer, that is not really what we want
+ //
+ tl -= MSECS(8+16+7);
- /* If the interval in witch we are requested to sleep is too
- * short then give up and remain awake
- */
+ // If the interval in witch we are requested to sleep is too
+ // short then give up and remain awake
+ // when we sleep after send null frame, the timer will be too short to sleep.
+ //
if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
- ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
+ ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
spin_unlock_irqrestore(&priv->ps_lock,flags);
- printk("too short to sleep\n");
+ printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME));
return;
}
-// write_nic_dword(dev, TimerInt, tl);
-// rb = read_nic_dword(dev, TSFTR);
- {
- u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
- // if (tl<rb)
- queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
- }
- /* if we suspect the TimerInt is gone beyond tl
- * while setting it, then give up
- */
-#if 1
if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
- ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
+ ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
+ ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
spin_unlock_irqrestore(&priv->ps_lock,flags);
return;
}
-#endif
-// if(priv->rf_sleep)
-// priv->rf_sleep(dev);
-
- //printk("<=========%s()\n", __FUNCTION__);
- queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
+ {
+ u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
+ queue_delayed_work(priv->ieee80211->wq,
+ &priv->ieee80211->hw_wakeup_wq,tmp);
+ //PowerSave not supported when kernel version less 2.6.20
+ }
+ queue_delayed_work(priv->ieee80211->wq,
+ (void *)&priv->ieee80211->hw_sleep_wq,0);
spin_unlock_irqrestore(&priv->ps_lock,flags);
+
}
static void rtl8192_init_priv_variable(struct net_device* dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
u8 i;
+ PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+
+ // Default Halt the NIC if RF is OFF.
+ pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC;
+ pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ;
+ pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM;
+ pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM;
+ pPSC->bLeisurePs = true;
+ pPSC->RegMaxLPSAwakeIntvl = 5;
+ priv->bHwRadioOff = false;
+
priv->being_init_adapter = false;
priv->txbuffsize = 1600;//1024;
priv->txfwbuffersize = 4096;
@@ -2328,6 +2578,17 @@ static void rtl8192_init_priv_variable(struct net_device* dev)
//added by amy
priv->ieee80211->InitialGainHandler = InitialGain819xPci;
+#ifdef ENABLE_IPS
+ priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq;
+ priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;
+#endif
+#ifdef ENABLE_LPS
+ priv->ieee80211->LeisurePSLeave = LeisurePSLeave;
+#endif//ENABL
+
+ priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg;
+ priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type;
+
priv->card_type = USB;
{
priv->ShortRetryLimit = 0x30;
@@ -2400,6 +2661,10 @@ static void rtl8192_init_priv_task(struct net_device* dev)
priv->priv_wq = create_workqueue(DRV_NAME);
#endif
+#ifdef ENABLE_IPS
+ INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq);
+#endif
+
// INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
INIT_WORK(&priv->reset_wq, rtl8192_restart);
// INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
@@ -2550,10 +2815,7 @@ static void rtl8192_read_eeprom_info(struct net_device* dev)
memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
}
- RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
- dev->dev_addr[0], dev->dev_addr[1],
- dev->dev_addr[2], dev->dev_addr[3],
- dev->dev_addr[4], dev->dev_addr[5]);
+ RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr);
//2 TX Power Check EEPROM Fail or not
if(priv->card_8192_version > VERSION_8190_BD) {
@@ -2926,13 +3188,14 @@ static void rtl8192_read_eeprom_info(struct net_device* dev)
#endif
break;
}
-/*
- //2008.06.03, for WOL
+
+
if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
- priv->ieee80211->bSupportRemoteWakeUp = TRUE;
+ priv->ieee80211->bSupportRemoteWakeUp = true;
else
- priv->ieee80211->bSupportRemoteWakeUp = FALSE;
-*/
+ priv->ieee80211->bSupportRemoteWakeUp = false;
+
+
RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
@@ -4006,12 +4269,19 @@ static void rtl819x_ifsilentreset(struct net_device *dev)
struct ieee80211_device *ieee = priv->ieee80211;
+ return;
+
// 2007.07.20. If we need to check CCK stop, please uncomment this line.
//bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
if(priv->ResetProgress==RESET_TYPE_NORESET)
{
RESET_START:
+#ifdef ENABLE_LPS
+ //LZM for PS-Poll AID issue. 090429
+ if(priv->ieee80211->state == IEEE80211_LINKED)
+ LeisurePSLeave(dev);
+#endif
RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
@@ -4051,9 +4321,9 @@ RESET_START:
}
else{
printk("ieee->state is NOT LINKED\n");
- ieee80211_softmac_stop_protocol(priv->ieee80211);
+ ieee80211_softmac_stop_protocol(priv->ieee80211,true);
}
- rtl8192_rtx_disable(dev);
+ rtl8192_halt_adapter(dev, true);
up(&priv->wx_sem);
RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
@@ -4150,6 +4420,128 @@ void InactivePsWorkItemCallback(struct net_device *dev)
RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
}
+#ifdef ENABLE_LPS
+//
+// Change current and default preamble mode.
+// 2005.01.06, by rcnjko.
+//
+bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode)
+{
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ //PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+ //u8 RpwmVal, FwPwrMode;
+
+ // Currently, we do not change power save mode on IBSS mode.
+ if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+ {
+ return false;
+ }
+
+ //
+ // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
+ // some AP will not response to our mgnt frames with PwrMgt bit set,
+ // e.g. cannot associate the AP.
+ // So I commented out it. 2005.02.16, by rcnjko.
+ //
+// // Change device's power save mode.
+// Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
+
+ // Update power save mode configured.
+ //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
+ if(!priv->ps_force) {
+ priv->ieee80211->ps = rtPsMode;
+ }
+
+ // Awake immediately
+ if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED)
+ {
+ unsigned long flags;
+
+ //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
+ // Notify the AP we awke.
+ rtl8192_hw_wakeup(dev);
+ priv->ieee80211->sta_sleep = 0;
+
+ spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags);
+ printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
+ ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0);
+ spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags);
+ }
+
+ return true;
+}
+
+//================================================================================
+// Leisure Power Save in linked state.
+//================================================================================
+
+//
+// Description:
+// Enter the leisure power save mode.
+//
+void LeisurePSEnter(struct net_device *dev)
+{
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+
+ //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
+ //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
+ // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
+
+ if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
+ (priv->ieee80211->state == IEEE80211_LINKED)) ||
+ (priv->ieee80211->iw_mode == IW_MODE_ADHOC) ||
+ (priv->ieee80211->iw_mode == IW_MODE_MASTER))
+ return;
+
+ if (pPSC->bLeisurePs)
+ {
+ // Idle for a while if we connect to AP a while ago.
+ if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) // 4 Sec
+ {
+
+ if(priv->ieee80211->ps == IEEE80211_PS_DISABLED)
+ {
+
+ //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
+ MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);
+
+ }
+ }
+ else
+ pPSC->LpsIdleCount++;
+ }
+}
+
+
+//
+// Description:
+// Leave the leisure power save mode.
+//
+void LeisurePSLeave(struct net_device *dev)
+{
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+
+
+ //RT_TRACE(COMP_PS, "LeisurePSLeave()...\n");
+ //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n",
+ // pPSC->bLeisurePs, priv->ieee80211->ps);
+
+ if (pPSC->bLeisurePs)
+ {
+ if(priv->ieee80211->ps != IEEE80211_PS_DISABLED)
+ {
+ // move to lps_wakecomplete()
+ //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
+ MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED);
+
+ }
+ }
+}
+#endif
+
+
//
// Description:
// Enter the inactive power save mode. RF will be off
@@ -4178,6 +4570,7 @@ IPSEnter(struct net_device *dev)
&& (priv->ieee80211->state != IEEE80211_LINKED) )
{
RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
+ //printk("IPSEnter(): Turn off RF.\n");
pPSC->eInactivePowerState = eRfOff;
// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
InactivePsWorkItemCallback(dev);
@@ -4203,12 +4596,53 @@ IPSLeave(struct net_device *dev)
if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
{
RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
+ //printk("IPSLeave(): Turn on RF.\n");
pPSC->eInactivePowerState = eRfOn;
// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
InactivePsWorkItemCallback(dev);
}
}
}
+
+void IPSLeave_wq(void *data)
+{
+ struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq);
+ struct net_device *dev = ieee->dev;
+
+ struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+ down(&priv->ieee80211->ips_sem);
+ IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
+}
+
+void ieee80211_ips_leave_wq(struct net_device *dev)
+{
+ struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+ RT_RF_POWER_STATE rtState;
+ rtState = priv->ieee80211->eRFPowerState;
+
+ if(priv->ieee80211->PowerSaveControl.bInactivePs){
+ if(rtState == eRfOff){
+ if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
+ {
+ RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
+ return;
+ }
+ else{
+ printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+ queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
+ }
+ }
+ }
+}
+//added by amy 090331 end
+void ieee80211_ips_leave(struct net_device *dev)
+{
+ struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+ down(&priv->ieee80211->ips_sem);
+ IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
+}
#endif
static void rtl819x_update_rxcounts(
@@ -4244,15 +4678,23 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work)
unsigned long flags;
bool bBusyTraffic = false;
static u8 last_time = 0;
+ bool bEnterPS = false;
+
+ if((!priv->up) || (priv->bHwRadioOff == true))
+ return;
+
if(!priv->up)
return;
hal_dm_watchdog(dev);
#ifdef ENABLE_IPS
// printk("watch_dog ENABLE_IPS\n");
if(ieee->actscanning == false){
- if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
+ //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
+ if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&\
+ (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&\
+ (!ieee->proto_stoppping) && !ieee->wx_set_enc){
if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
- printk("====================>haha:IPSEnter()\n");
+ //printk("====================>haha:IPSEnter()\n");
IPSEnter(dev);
//ieee80211_stop_scan(priv->ieee80211);
}
@@ -4262,14 +4704,49 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work)
{//to get busy traffic condition
if(ieee->state == IEEE80211_LINKED)
{
- if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
- ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
+ if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
+ ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
bBusyTraffic = true;
}
+#ifdef ENABLE_LPS
+ //added by amy for Leisure PS
+ if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
+ (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
+ {
+ //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
+ // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
+ bEnterPS= false;
+ }
+ else
+ {
+ bEnterPS= true;
+ }
+
+ //printk("***bEnterPS = %d\n", bEnterPS);
+ // LeisurePS only work in infra mode.
+ if(bEnterPS)
+ {
+ LeisurePSEnter(dev);
+ }
+ else
+ {
+ LeisurePSLeave(dev);
+ }
+#endif
+
+ }
+ else
+ {
+#ifdef ENABLE_LPS
+ //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
+ LeisurePSLeave(dev);
+#endif
}
+
ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
+ ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
}
@@ -4288,14 +4765,14 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work)
if( ieee->eRFPowerState == eRfOff)
RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
- // Dot11d_Reset(dev);
+ // Dot11d_Reset(dev);
ieee->state = IEEE80211_ASSOCIATING;
notify_wx_assoc_event(priv->ieee80211);
- RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
+ RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
ieee->is_roaming = true;
ieee->is_set_key = false;
- ieee->link_change(dev);
- queue_work(ieee->wq, &ieee->associate_procedure_wq);
+ ieee->link_change(dev);
+ queue_work(ieee->wq, &ieee->associate_procedure_wq);
}
}
ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
@@ -4348,6 +4825,7 @@ int _rtl8192_up(struct net_device *dev)
RT_STATUS init_status = RT_STATUS_SUCCESS;
priv->up=1;
priv->ieee80211->ieee_up=1;
+ priv->bdisable_nic = false; //YJ,add,091111
RT_TRACE(COMP_INIT, "Bringing up iface");
init_status = rtl8192_adapter_start(dev);
@@ -4422,6 +4900,12 @@ int rtl8192_down(struct net_device *dev)
#endif
if (priv->up == 0) return -1;
+#ifdef ENABLE_LPS
+ //LZM for PS-Poll AID issue. 090429
+ if(priv->ieee80211->state == IEEE80211_LINKED)
+ LeisurePSLeave(dev);
+#endif
+
priv->up=0;
priv->ieee80211->ieee_up = 0;
RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
@@ -4459,11 +4943,9 @@ int rtl8192_down(struct net_device *dev)
deinit_hal_dm(dev);
del_timer_sync(&priv->watch_dog_timer);
- ieee80211_softmac_stop_protocol(priv->ieee80211);
-#ifdef ENABLE_IPS
- MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
-#endif
- rtl8192_rtx_disable(dev);
+ ieee80211_softmac_stop_protocol(priv->ieee80211,true);
+
+ rtl8192_halt_adapter(dev,false);
memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
@@ -4479,10 +4961,10 @@ void rtl8192_commit(struct net_device *dev)
if (priv->up == 0) return ;
- ieee80211_softmac_stop_protocol(priv->ieee80211);
+ ieee80211_softmac_stop_protocol(priv->ieee80211,true);
rtl8192_irq_disable(dev);
- rtl8192_rtx_disable(dev);
+ rtl8192_halt_adapter(dev,true);
_rtl8192_up(dev);
}
@@ -5806,8 +6288,7 @@ static void rtl8192_rx(struct net_device *dev)
skb = new_skb;
priv->rx_buf[priv->rx_idx] = skb;
- *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
-// *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
+ *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
}
}
@@ -6036,7 +6517,7 @@ void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
/* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
* is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
* Otherwise call cancel_delayed_work is enough.
- * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
+ * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
* */
cancel_delayed_work(&priv->watch_dog_wq);
cancel_delayed_work(&priv->update_beacon_wq);
@@ -6381,11 +6862,13 @@ void setKey( struct net_device *dev,
if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
{
RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
- up(&priv->wx_sem);
+ //up(&priv->wx_sem);
return ;
}
else{
+ down(&priv->ieee80211->ips_sem);
IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
}
}
}
@@ -6394,7 +6877,7 @@ void setKey( struct net_device *dev,
if (EntryNo >= TOTAL_CAM_ENTRY)
RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
- RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
+ RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
if (DefaultKey)
usConfig |= BIT15 | (KeyType<<2);
@@ -6455,6 +6938,65 @@ void CamPrintDbgReg(struct net_device* dev)
RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
}
+bool NicIFEnableNIC(struct net_device* dev)
+{
+ RT_STATUS init_status = RT_STATUS_SUCCESS;
+ struct r8192_priv* priv = ieee80211_priv(dev);
+ PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+
+ //YJ,add,091109
+ if (priv->up == 0){
+ RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__);
+ priv->bdisable_nic = false; //YJ,add,091111
+ return false;
+ }
+ // <1> Reset memory: descriptor, buffer,..
+ //NicIFResetMemory(Adapter);
+
+ // <2> Enable Adapter
+ //printk("===========>%s()\n",__FUNCTION__);
+ //priv->bfirst_init = true;
+ init_status = rtl8192_adapter_start(dev);
+ if (init_status != RT_STATUS_SUCCESS) {
+ RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
+ priv->bdisable_nic = false; //YJ,add,091111
+ return -1;
+ }
+ //printk("start adapter finished\n");
+ RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
+ //priv->bfirst_init = false;
+
+ // <3> Enable Interrupt
+ rtl8192_irq_enable(dev);
+ priv->bdisable_nic = false;
+ //RT_TRACE(COMP_PS,"<===========%s()\n",__FUNCTION__);
+ return (init_status == RT_STATUS_SUCCESS) ? true:false;
+}
+bool NicIFDisableNIC(struct net_device* dev)
+{
+ bool status = true;
+ struct r8192_priv* priv = ieee80211_priv(dev);
+ u8 tmp_state = 0;
+ // <1> Disable Interrupt
+ //RT_TRACE(COMP_PS, "=========>%s()\n",__FUNCTION__);
+ priv->bdisable_nic = true; //YJ,move,091109
+ tmp_state = priv->ieee80211->state;
+
+ ieee80211_softmac_stop_protocol(priv->ieee80211, false);
+
+ priv->ieee80211->state = tmp_state;
+ rtl8192_cancel_deferred_work(priv);
+ rtl8192_irq_disable(dev);
+ // <2> Stop all timer
+
+ // <3> Disable Adapter
+ rtl8192_halt_adapter(dev, false);
+// priv->bdisable_nic = true;
+ //RT_TRACE(COMP_PS, "<=========%s()\n",__FUNCTION__);
+
+ return status;
+}
+
/***************************************************************************
------------------- module init / exit stubs ----------------
diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c
index 5ffb4f74055..a249f00da60 100644
--- a/drivers/staging/rtl8192e/r8192E_dm.c
+++ b/drivers/staging/rtl8192e/r8192E_dm.c
@@ -19,26 +19,28 @@ Major Change History:
#include "r819xE_phy.h"
#include "r819xE_phyreg.h"
#include "r8190_rtl8256.h"
+
+#define DRV_NAME "rtl819xE"
/*---------------------------Define Local Constant---------------------------*/
//
// Indicate different AP vendor for IOT issue.
//
#ifdef RTL8190P
static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322};
+{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322};
static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322};
+{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322};
#else
#ifdef RTL8192E
static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322};
+{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322};
static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322};
+{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322};
#else
static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f};
+{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f, 0x5e4322};
static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
-{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f};
+{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f, 0x5e4322};
#endif
#endif
@@ -275,6 +277,30 @@ void dm_CheckRxAggregation(struct net_device *dev) {
#endif
+// call the script file to enable
+void dm_check_ac_dc_power(struct net_device *dev)
+{
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
+ char *argv[] = {ac_dc_check_script_path,DRV_NAME,NULL};
+ static char *envp[] = {"HOME=/",
+ "TERM=linux",
+ "PATH=/usr/bin:/bin",
+ NULL};
+
+ if(priv->ResetProgress == RESET_TYPE_SILENT)
+ {
+ RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n");
+ return;
+ }
+
+ if(priv->ieee80211->state != IEEE80211_LINKED) {
+ return;
+ }
+ call_usermodehelper(ac_dc_check_script_path,argv,envp,1);
+
+ return;
+};
void hal_dm_watchdog(struct net_device *dev)
{
@@ -282,6 +308,8 @@ void hal_dm_watchdog(struct net_device *dev)
//static u8 previous_bssid[6] ={0};
+ dm_check_ac_dc_power(dev);
+
/*Add by amy 2008/05/15 ,porting from windows code.*/
dm_check_rate_adaptive(dev);
dm_dynamic_txpower(dev);
diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/r8192E_hw.h
index 388908fc8d2..346bfb18e2b 100644
--- a/drivers/staging/rtl8192e/r8192E_hw.h
+++ b/drivers/staging/rtl8192e/r8192E_hw.h
@@ -808,4 +808,12 @@ enum _RTL8192Pci_HW {
#define GPI 0x108
#define GPO 0x109
#define GPE 0x10a
+
+#define ANAPAR_FOR_8192PciE 0x17 // Analog parameter register
+
+#define MSR_NOLINK 0x00
+#define MSR_ADHOC 0x01
+#define MSR_INFRA 0x02
+#define MSR_AP 0x03
+
#endif
diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c
index d1eb89229cd..0b0f39ce3ce 100644
--- a/drivers/staging/rtl8192e/r8192E_wx.c
+++ b/drivers/staging/rtl8192e/r8192E_wx.c
@@ -22,7 +22,7 @@
#include "r8192E_hw.h"
#include "r8192E_wx.h"
#ifdef ENABLE_DOT11D
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
#endif
#define RATE_COUNT 12
@@ -70,6 +70,9 @@ static int r8192_wx_set_rate(struct net_device *dev,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
@@ -87,6 +90,9 @@ static int r8192_wx_set_rts(struct net_device *dev,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
@@ -111,6 +117,9 @@ static int r8192_wx_set_power(struct net_device *dev,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
@@ -290,6 +299,9 @@ static int r8192_wx_set_rawtx(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
int ret;
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
@@ -325,6 +337,9 @@ static int r8192_wx_set_crcmon(struct net_device *dev,
int enable = (parms[0] > 0);
short prev = priv->crcmon;
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
if(enable)
@@ -352,6 +367,9 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
RT_RF_POWER_STATE rtState;
int ret;
+ if(priv->bHwRadioOff == true)
+ return 0;
+
rtState = priv->ieee80211->eRFPowerState;
down(&priv->wx_sem);
#ifdef ENABLE_IPS
@@ -366,8 +384,10 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
return -1;
}
else{
- printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+ RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__);
+ down(&priv->ieee80211->ips_sem);
IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
}
}
}
@@ -425,7 +445,7 @@ static int rtl8180_wx_get_range(struct net_device *dev,
*/
/* ~5 Mb/s real (802.11b) */
- range->throughput = 5 * 1000 * 1000;
+ range->throughput = 130 * 1000 * 1000;
// TODO: Not used in 802.11b?
// range->min_nwid; /* Minimal NWID we are able to set */
@@ -468,7 +488,7 @@ static int rtl8180_wx_get_range(struct net_device *dev,
range->pmt_flags = IW_POWER_TIMEOUT;
range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 16;
+ range->we_version_source = 18;
// range->retry_capa; /* What retry options are supported */
// range->retry_flags; /* How to decode max/min retry limit */
@@ -517,7 +537,12 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
struct ieee80211_device* ieee = priv->ieee80211;
RT_RF_POWER_STATE rtState;
int ret;
+
+ if(priv->bHwRadioOff == true)
+ return 0;
+
rtState = priv->ieee80211->eRFPowerState;
+
if(!priv->up) return -ENETDOWN;
if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
return -EAGAIN;
@@ -547,8 +572,10 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
return -1;
}
else{
- printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+ //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
+ down(&priv->ieee80211->ips_sem);
IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
}
}
}
@@ -580,6 +607,9 @@ static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
+ if(priv->bHwRadioOff == true)
+ return 0;
+
if(!priv->up) return -ENETDOWN;
down(&priv->wx_sem);
@@ -599,23 +629,16 @@ static int r8192_wx_set_essid(struct net_device *dev,
RT_RF_POWER_STATE rtState;
int ret;
+ if(priv->bHwRadioOff == true)
+ return 0;
+
rtState = priv->ieee80211->eRFPowerState;
down(&priv->wx_sem);
+
#ifdef ENABLE_IPS
- if(priv->ieee80211->PowerSaveControl.bInactivePs){
- if(rtState == eRfOff){
- if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
- {
- RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
- up(&priv->wx_sem);
- return -1;
- }
- else{
- printk("=========>%s(): IPSLeave\n",__FUNCTION__);
- IPSLeave(dev);
- }
- }
- }
+ down(&priv->ieee80211->ips_sem);
+ IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
#endif
ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
@@ -650,6 +673,9 @@ static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
@@ -673,6 +699,9 @@ static int r8192_wx_set_frag(struct net_device *dev,
{
struct r8192_priv *priv = ieee80211_priv(dev);
+ if(priv->bHwRadioOff == true)
+ return 0;
+
if (wrqu->frag.disabled)
priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
else {
@@ -711,8 +740,16 @@ static int r8192_wx_set_wap(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
// struct sockaddr *temp = (struct sockaddr *)awrq;
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
+#ifdef ENABLE_IPS
+ down(&priv->ieee80211->ips_sem);
+ IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
+#endif
ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
up(&priv->wx_sem);
@@ -753,14 +790,24 @@ static int r8192_wx_set_enc(struct net_device *dev,
u32 hwkey[4]={0,0,0,0};
u8 mask=0xff;
u32 key_idx=0;
- u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
+ u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x01},
{0x00,0x00,0x00,0x00,0x00,0x02},
{0x00,0x00,0x00,0x00,0x00,0x03} };
int i;
+ if(priv->bHwRadioOff == true)
+ return 0;
+
if(!priv->up) return -ENETDOWN;
+ priv->ieee80211->wx_set_enc = 1;
+#ifdef ENABLE_IPS
+ down(&priv->ieee80211->ips_sem);
+ IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
+#endif
+
down(&priv->wx_sem);
RT_TRACE(COMP_SEC, "Setting SW wep key");
@@ -768,7 +815,6 @@ static int r8192_wx_set_enc(struct net_device *dev,
up(&priv->wx_sem);
-
//sometimes, the length is zero while we do not type key value
if(wrqu->encoding.length!=0){
@@ -868,6 +914,8 @@ static int r8192_wx_set_enc(struct net_device *dev,
}
#endif
+ priv->ieee80211->wx_set_enc = 0;
+
return ret;
}
@@ -893,6 +941,9 @@ static int r8192_wx_set_retry(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
int err = 0;
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
@@ -985,6 +1036,10 @@ static int r8192_wx_set_sens(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
short err = 0;
+
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
//DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
if(priv->rf_set_sens == NULL) {
@@ -1011,7 +1066,19 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
struct ieee80211_device* ieee = priv->ieee80211;
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
+
+ priv->ieee80211->wx_set_enc = 1;
+
+#ifdef ENABLE_IPS
+ down(&priv->ieee80211->ips_sem);
+ IPSLeave(dev);
+ up(&priv->ieee80211->ips_sem);
+#endif
+
ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
{
@@ -1091,6 +1158,7 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
}
end_hw_sec:
+ priv->ieee80211->wx_set_enc = 0;
up(&priv->wx_sem);
return ret;
@@ -1102,6 +1170,10 @@ static int r8192_wx_set_auth(struct net_device *dev,
int ret=0;
//printk("====>%s()\n", __FUNCTION__);
struct r8192_priv *priv = ieee80211_priv(dev);
+
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
up(&priv->wx_sem);
@@ -1116,6 +1188,10 @@ static int r8192_wx_set_mlme(struct net_device *dev,
int ret=0;
struct r8192_priv *priv = ieee80211_priv(dev);
+
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
up(&priv->wx_sem);
@@ -1129,6 +1205,10 @@ static int r8192_wx_set_gen_ie(struct net_device *dev,
//printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
int ret=0;
struct r8192_priv *priv = ieee80211_priv(dev);
+
+ if(priv->bHwRadioOff == true)
+ return 0;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
up(&priv->wx_sem);
@@ -1142,6 +1222,42 @@ static int dummy(struct net_device *dev, struct iw_request_info *a,
return -1;
}
+// check ac/dc status with the help of user space application */
+static int r8192_wx_adapter_power_status(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef ENABLE_LPS
+ PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+ struct ieee80211_device* ieee = priv->ieee80211;
+#endif
+ down(&priv->wx_sem);
+
+#ifdef ENABLE_LPS
+ RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power");
+ // ieee->ps shall not be set under DC mode, otherwise it conflict
+ // with Leisure power save mode setting.
+ //
+ if(*extra || priv->force_lps) {
+ priv->ps_force = false;
+ pPSC->bLeisurePs = true;
+ } else {
+ //LZM for PS-Poll AID issue. 090429
+ if(priv->ieee80211->state == IEEE80211_LINKED)
+ LeisurePSLeave(dev);
+
+ priv->ps_force = true;
+ pPSC->bLeisurePs = false;
+ ieee->ps = *extra;
+ }
+
+#endif
+ up(&priv->wx_sem);
+ return 0;
+
+}
+
static iw_handler r8192_wx_handlers[] =
{
@@ -1231,72 +1347,28 @@ static const struct iw_priv_args r8192_private_args[] = {
SIOCIWFIRSTPRIV + 0x2,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
}
-#ifdef JOHN_IOCTL
,
{
SIOCIWFIRSTPRIV + 0x3,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
+
}
,
{
SIOCIWFIRSTPRIV + 0x4,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x5,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x6,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x7,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x8,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x9,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
- }
-
-#endif
- ,
- {
- SIOCIWFIRSTPRIV + 0x3,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
-
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
+ "set_power"
}
};
static iw_handler r8192_private_handler[] = {
-// r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
-// r8192_wx_set_forceassociate,
-// r8192_wx_set_beaconinterval,
-// r8192_wx_set_monitor_type,
r8192_wx_set_scan_type,
r8192_wx_set_rawtx,
-#ifdef JOHN_IOCTL
- r8192_wx_read_regs,
- r8192_wx_write_regs,
- r8192_wx_read_bb,
- r8192_wx_write_bb,
- r8192_wx_read_nicb,
- r8192_wx_write_nicb,
- r8192_wx_get_ap_status
-#endif
r8192_wx_force_reset,
+ r8192_wx_adapter_power_status,
};
//#if WIRELESS_EXT >= 17
diff --git a/drivers/staging/rtl8192e/r8192E_wx.h b/drivers/staging/rtl8192e/r8192E_wx.h
index 79ebdb698a4..047030bc051 100644
--- a/drivers/staging/rtl8192e/r8192E_wx.h
+++ b/drivers/staging/rtl8192e/r8192E_wx.h
@@ -15,7 +15,6 @@
#ifndef R8180_WX_H
#define R8180_WX_H
//#include <linux/wireless.h>
-//#include "ieee80211.h"
extern struct iw_handler_def r8192_wx_handlers_def;
/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */
extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
index 2aaa4e1bb37..87c334fb733 100644
--- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c
+++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
@@ -135,7 +135,7 @@ RT_STATUS cmpk_message_handle_tx(
* Transform from little endian to big endian
* and pending zero
*/
- seg_ptr = skb->tail;
+ seg_ptr = skb_tail_pointer(skb);
for(i=0 ; i < frag_length; i+=4) {
*seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
*seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c
index 1f9e413bcd4..793a1754555 100644
--- a/drivers/staging/rtl8192e/r819xE_firmware.c
+++ b/drivers/staging/rtl8192e/r819xE_firmware.c
@@ -1,5 +1,5 @@
/*
- * Procedure: Init boot code/firmware code/data session
+ * Procedure: Init boot code/firmware code/data session
*
* Description: This routine will intialize firmware. If any error occurs
* during the initialization process, the routine shall terminate
@@ -7,19 +7,21 @@
* NdisOpenFile only from MiniportInitialize.
*
* Arguments: The pointer of the adapter
-
+ *
* Returns:
* NDIS_STATUS_FAILURE - the following initialization process
* should be terminated
* NDIS_STATUS_SUCCESS - if firmware initialization process
* success
*/
+
#include "r8192E.h"
#include "r8192E_hw.h"
+
#include <linux/firmware.h>
/* It should be double word alignment */
-#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4 * (v / 4) - 8)
+#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4 * (v / 4) - 8)
enum firmware_init_step {
FW_INIT_STEP0_BOOT = 0,
@@ -47,17 +49,17 @@ void firmware_init_param(struct net_device *dev)
static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
u32 buffer_len)
{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool rt_status = true;
- u16 frag_threshold;
- u16 frag_length, frag_offset = 0;
- int i;
-
- rt_firmware *pfirmware = priv->pFirmware;
- struct sk_buff *skb;
- unsigned char *seg_ptr;
- cb_desc *tcb_desc;
- u8 bLastIniPkt;
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ bool rt_status = true;
+ u16 frag_threshold;
+ u16 frag_length, frag_offset = 0;
+ int i;
+
+ rt_firmware *pfirmware = priv->pFirmware;
+ struct sk_buff *skb;
+ unsigned char *seg_ptr;
+ cb_desc *tcb_desc;
+ u8 bLastIniPkt;
firmware_init_param(dev);
@@ -89,10 +91,17 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
* Transform from little endian to big endian and pending zero
*/
for (i = 0; i < frag_length; i += 4) {
- *seg_ptr++ = ((i+0) < frag_length) ? code_virtual_address[i+3] : 0;
- *seg_ptr++ = ((i+1) < frag_length) ? code_virtual_address[i+2] : 0;
- *seg_ptr++ = ((i+2) < frag_length) ? code_virtual_address[i+1] : 0;
- *seg_ptr++ = ((i+3) < frag_length) ? code_virtual_address[i+0] : 0;
+ *seg_ptr++ = ((i+0) < frag_length) ? \
+ code_virtual_address[i+3] : 0;
+
+ *seg_ptr++ = ((i+1) < frag_length) ? \
+ code_virtual_address[i+2] : 0;
+
+ *seg_ptr++ = ((i+2) < frag_length) ? \
+ code_virtual_address[i+1] : 0;
+
+ *seg_ptr++ = ((i+3) < frag_length) ? \
+ code_virtual_address[i+0] : 0;
}
tcb_desc->txbuf_size = (u16)i;
skb_put(skb, i);
@@ -204,16 +213,16 @@ CPUCheckFirmwareReady_Fail:
bool init_firmware(struct net_device *dev)
{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool rt_status = TRUE;
- u32 file_length = 0;
- u8 *mapped_file = NULL;
- u32 init_step = 0;
- enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ bool rt_status = true;
+ u32 file_length = 0;
+ u8 *mapped_file = NULL;
+ u32 init_step = 0;
+ enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT;
- rt_firmware *pfirmware = priv->pFirmware;
- const struct firmware *fw_entry;
+ rt_firmware *pfirmware = priv->pFirmware;
+ const struct firmware *fw_entry;
const char *fw_name[3] = { "RTL8192E/boot.img",
"RTL8192E/main.img",
"RTL8192E/data.img"};
@@ -240,31 +249,37 @@ bool init_firmware(struct net_device *dev)
* Download boot, main, and data image for System reset.
* Download data image for firmware reseta
*/
- for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) {
+ for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; \
+ init_step++) {
/*
* Open Image file, and map file to contineous memory if open file success.
* or read image file from array. Default load from IMG file
*/
if (rst_opt == OPT_SYSTEM_RESET) {
if (pfirmware->firmware_buf_size[init_step] == 0) {
- rc = request_firmware(&fw_entry, fw_name[init_step], &priv->pdev->dev);
+ rc = request_firmware(&fw_entry,
+ fw_name[init_step], &priv->pdev->dev);
+
if (rc < 0) {
RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n");
goto download_firmware_fail;
}
if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) {
- RT_TRACE(COMP_FIRMWARE, "img file size exceed the container buffer fail!\n");
+ RT_TRACE(COMP_FIRMWARE, \
+ "img file size exceed the container buffer fail!\n");
goto download_firmware_fail;
}
if (init_step != FW_INIT_STEP1_MAIN) {
- memcpy(pfirmware->firmware_buf[init_step], fw_entry->data, fw_entry->size);
+ memcpy(pfirmware->firmware_buf[init_step],
+ fw_entry->data, fw_entry->size);
pfirmware->firmware_buf_size[init_step] = fw_entry->size;
} else {
memset(pfirmware->firmware_buf[init_step], 0, 128);
- memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data, fw_entry->size);
+ memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data,
+ fw_entry->size);
pfirmware->firmware_buf_size[init_step] = fw_entry->size+128;
}
@@ -273,6 +288,7 @@ bool init_firmware(struct net_device *dev)
}
mapped_file = pfirmware->firmware_buf[init_step];
file_length = pfirmware->firmware_buf_size[init_step];
+
} else if (rst_opt == OPT_FIRMWARE_RESET) {
/* we only need to download data.img here */
mapped_file = pfirmware->firmware_buf[init_step];
@@ -346,7 +362,10 @@ bool init_firmware(struct net_device *dev)
download_firmware_fail:
RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
- rt_status = FALSE;
+ rt_status = false;
return rt_status;
-
}
+
+MODULE_FIRMWARE("RTL8192E/boot.img");
+MODULE_FIRMWARE("RTL8192E/main.img");
+MODULE_FIRMWARE("RTL8192E/data.img");
diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c
index c44059aeacb..7bd4fae0667 100644
--- a/drivers/staging/rtl8192e/r819xE_phy.c
+++ b/drivers/staging/rtl8192e/r819xE_phy.c
@@ -5,7 +5,7 @@
#include "r819xE_phy.h"
#include "r8192E_dm.h"
#ifdef ENABLE_DOT11D
-#include "dot11d.h"
+#include "ieee80211/dot11d.h"
#endif
static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
0,
diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h
index fa77abe8882..41e0d777eab 100644
--- a/drivers/staging/rtl8192e/r819xE_phy.h
+++ b/drivers/staging/rtl8192e/r819xE_phy.h
@@ -1,43 +1,46 @@
#ifndef _R819XU_PHY_H
#define _R819XU_PHY_H
-/* Channel switch:The size of command tables for switch channel*/
+
+/* Channel switch: the size of command tables for switch channel */
#define MAX_PRECMD_CNT 16
#define MAX_RFDEPENDCMD_CNT 16
#define MAX_POSTCMD_CNT 16
#ifdef RTL8190P
#define MACPHY_Array_PGLength 21
-#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG
-#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array
+#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG
+#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array
#define RadioC_ArrayLength 246
#define RadioD_ArrayLength 78
-#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array
-#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array
-#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array
-#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array
-#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array
-#define PHY_REGArrayLength 280
-#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray
-#define PHY_REG_1T2RArrayLength 280
-#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray
+#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array
+#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array
+#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array
+#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array
+#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array
+#define PHY_REGArrayLength 280
+#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray
+#define PHY_REG_1T2RArrayLength 280
+#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray
+#endif
+
+
+#ifdef RTL8192E
+#define MACPHY_Array_PGLength 30
+#define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG
+#define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array
+#define RadioC_ArrayLength 1
+#define RadioD_ArrayLength 1
+#define Rtl819XRadioA_Array Rtl8192PciERadioA_Array
+#define Rtl819XRadioB_Array Rtl8192PciERadioB_Array
+#define Rtl819XRadioC_Array Rtl8192PciERadioC_Array
+#define Rtl819XRadioD_Array Rtl8192PciERadioD_Array
+#define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array
+#define PHY_REGArrayLength 1
+#define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray
+#define PHY_REG_1T2RArrayLength 296
+#define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray
#endif
- #ifdef RTL8192E
- #define MACPHY_Array_PGLength 30
- #define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG
- #define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array
- #define RadioC_ArrayLength 1
- #define RadioD_ArrayLength 1
- #define Rtl819XRadioA_Array Rtl8192PciERadioA_Array
- #define Rtl819XRadioB_Array Rtl8192PciERadioB_Array
- #define Rtl819XRadioC_Array Rtl8192PciERadioC_Array
- #define Rtl819XRadioD_Array Rtl8192PciERadioD_Array
- #define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array
- #define PHY_REGArrayLength 1
- #define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray
- #define PHY_REG_1T2RArrayLength 296
- #define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray
- #endif
#define AGCTAB_ArrayLength 384
#define MACPHY_ArrayLength 18
@@ -45,7 +48,7 @@
#define RadioB_ArrayLength 78
-typedef enum _SwChnlCmdID{
+typedef enum _SwChnlCmdID {
CmdID_End,
CmdID_SetTxPowerLevel,
CmdID_BBRegWrite10,
@@ -53,16 +56,15 @@ typedef enum _SwChnlCmdID{
CmdID_WritePortUshort,
CmdID_WritePortUchar,
CmdID_RF_WriteReg,
-}SwChnlCmdID;
+} SwChnlCmdID;
-/*--------------------------------Define structure--------------------------------*/
-/* 1. Switch channel related */
-typedef struct _SwChnlCmd{
- SwChnlCmdID CmdID;
- u32 Para1;
- u32 Para2;
- u32 msDelay;
-}__attribute__ ((packed)) SwChnlCmd;
+/* switch channel data structure */
+typedef struct _SwChnlCmd {
+ SwChnlCmdID CmdID;
+ u32 Para1;
+ u32 Para2;
+ u32 msDelay;
+} __attribute__ ((packed)) SwChnlCmd;
extern u32 rtl819XMACPHY_Array_PG[];
extern u32 rtl819XPHY_REG_1T2RArray[];
@@ -72,54 +74,90 @@ extern u32 rtl819XRadioB_Array[];
extern u32 rtl819XRadioC_Array[];
extern u32 rtl819XRadioD_Array[];
-typedef enum _HW90_BLOCK{
+typedef enum _HW90_BLOCK {
HW90_BLOCK_MAC = 0,
HW90_BLOCK_PHY0 = 1,
HW90_BLOCK_PHY1 = 2,
HW90_BLOCK_RF = 3,
- HW90_BLOCK_MAXIMUM = 4, // Never use this
-}HW90_BLOCK_E, *PHW90_BLOCK_E;
-
-typedef enum _RF90_RADIO_PATH{
- RF90_PATH_A = 0, //Radio Path A
- RF90_PATH_B = 1, //Radio Path B
- RF90_PATH_C = 2, //Radio Path C
- RF90_PATH_D = 3, //Radio Path D
- RF90_PATH_MAX //Max RF number 92 support
-}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
-
-#define bMaskByte0 0xff
-#define bMaskByte1 0xff00
-#define bMaskByte2 0xff0000
-#define bMaskByte3 0xff000000
-#define bMaskHWord 0xffff0000
-#define bMaskLWord 0x0000ffff
-#define bMaskDWord 0xffffffff
-
-//extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
-extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath);
-extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData);
-extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask);
-//extern u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset);
-//extern void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
-extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data);
-extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
-extern void rtl8192_phy_configmac(struct net_device* dev);
-extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType);
-//extern void rtl8192_InitBBRFRegDef(struct net_device* dev);
-extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
-//extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev);
-extern RT_STATUS rtl8192_BBConfig(struct net_device* dev);
-extern void rtl8192_phy_getTxPower(struct net_device* dev);
-extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel);
+ /* Don't ever use this. */
+ HW90_BLOCK_MAXIMUM = 4,
+} HW90_BLOCK_E, *PHW90_BLOCK_E;
+
+typedef enum _RF90_RADIO_PATH {
+ /* Radio paths */
+ RF90_PATH_A = 0,
+ RF90_PATH_B = 1,
+ RF90_PATH_C = 2,
+ RF90_PATH_D = 3,
+
+ /* Max RF number 92 support */
+ RF90_PATH_MAX
+} RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
+
+#define bMaskByte0 0xff
+#define bMaskByte1 0xff00
+#define bMaskByte2 0xff0000
+#define bMaskByte3 0xff000000
+#define bMaskHWord 0xffff0000
+#define bMaskLWord 0x0000ffff
+#define bMaskDWord 0xffffffff
+
+/*extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
+
+extern u32 rtl8192_phy_RFSerialRead(struct net_device *dev,
+ RF90_RADIO_PATH_E eRFPath, u32 Offset);
+
+extern void rtl8192_phy_RFSerialWrite(struct net_device *dev,
+ RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
+
+extern void rtl8192_InitBBRFRegDef(struct net_device *dev);
+
+extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device *dev); */
+
+extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath);
+
+extern void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr,
+ u32 dwBitMask, u32 dwData);
+
+extern u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr,
+ u32 dwBitMask);
+
+extern void rtl8192_phy_SetRFReg(struct net_device *dev,
+ RF90_RADIO_PATH_E eRFPath, u32 RegAddr,
+ u32 BitMask, u32 Data);
+
+extern u32 rtl8192_phy_QueryRFReg(struct net_device *dev,
+ RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
+
+extern void rtl8192_phy_configmac(struct net_device *dev);
+
+extern void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType);
+
+extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device *dev,
+ HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
+
+extern RT_STATUS rtl8192_BBConfig(struct net_device *dev);
+
+extern void rtl8192_phy_getTxPower(struct net_device *dev);
+
+extern void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel);
+
extern RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev);
+
extern void rtl8192_phy_updateInitGain(struct net_device* dev);
-extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath);
-extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel);
-extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
+ RF90_RADIO_PATH_E eRFPath);
+
+extern u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel);
+
+extern void rtl8192_SetBWMode(struct net_device *dev,
+ HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+
extern void rtl8192_SwChnl_WorkItem(struct net_device *dev);
+
extern void rtl8192_SetBWModeWorkItem(struct net_device *dev);
+
extern void InitialGain819xPci(struct net_device *dev, u8 Operation);
-#endif
+#endif /* _R819XU_PHY_H */
diff --git a/drivers/staging/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/r819xE_phyreg.h
index 37f0feefaf2..d5de279f664 100644
--- a/drivers/staging/rtl8192e/r819xE_phyreg.h
+++ b/drivers/staging/rtl8192e/r819xE_phyreg.h
@@ -38,6 +38,8 @@
#define MCS_TXAGC 0x340 // MCS AGC
#define CCK_TXAGC 0x348 // CCK AGC
+#define MacBlkCtrl 0x403 // Mac block on/off control register
+
//page8
#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC
#define rFPGA0_TxInfo 0x804
@@ -79,55 +81,70 @@
#define rFPGA0_XB_LSSIReadBack 0x8a4
#define rFPGA0_XC_LSSIReadBack 0x8a8
#define rFPGA0_XD_LSSIReadBack 0x8ac
-#define rFPGA0_PSDReport 0x8b4
+#define rFPGA0_PSDReport 0x8b4
#define rFPGA0_XAB_RFInterfaceRB 0x8e0
#define rFPGA0_XCD_RFInterfaceRB 0x8e4
-//page 9
-#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC
-#define rFPGA1_TxBlock 0x904
-#define rFPGA1_DebugSelect 0x908
-#define rFPGA1_TxInfo 0x90c
-
-//page a
-#define rCCK0_System 0xa00
-#define rCCK0_AFESetting 0xa04
-#define rCCK0_CCA 0xa08
-#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level
-#define rCCK0_RxAGC2 0xa10 //AGC & DAGC
-#define rCCK0_RxHP 0xa14
-#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold
-#define rCCK0_DSPParameter2 0xa1c //SQ threshold
-#define rCCK0_TxFilter1 0xa20
-#define rCCK0_TxFilter2 0xa24
-#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3
-#define rCCK0_FalseAlarmReport 0xa2c //0xa2d
-#define rCCK0_TRSSIReport 0xa50
-#define rCCK0_RxReport 0xa54 //0xa57
-#define rCCK0_FACounterLower 0xa5c //0xa5b
-#define rCCK0_FACounterUpper 0xa58 //0xa5c
-
-//page c
-#define rOFDM0_LSTF 0xc00
+/* Page 9 - RF mode & OFDM TxSC */
+#define rFPGA1_RFMOD 0x900
+#define rFPGA1_TxBlock 0x904
+#define rFPGA1_DebugSelect 0x908
+#define rFPGA1_TxInfo 0x90c
+
+/* Page a */
+#define rCCK0_System 0xa00
+#define rCCK0_AFESetting 0xa04
+#define rCCK0_CCA 0xa08
+/* AGC default value, saturation level */
+#define rCCK0_RxAGC1 0xa0c
+/* AGC & DAGC */
+#define rCCK0_RxAGC2 0xa10
+#define rCCK0_RxHP 0xa14
+/* Timing recovery & channel estimation threshold */
+#define rCCK0_DSPParameter1 0xa18
+/* SQ threshold */
+#define rCCK0_DSPParameter2 0xa1c
+#define rCCK0_TxFilter1 0xa20
+#define rCCK0_TxFilter2 0xa24
+/* Debug port and TX filter 3 */
+#define rCCK0_DebugPort 0xa28
+#define rCCK0_FalseAlarmReport 0xa2c
+#define rCCK0_TRSSIReport 0xa50
+#define rCCK0_RxReport 0xa54
+#define rCCK0_FACounterLower 0xa5c
+#define rCCK0_FACounterUpper 0xa58
+
+/* Page c */
+#define rOFDM0_LSTF 0xc00
#define rOFDM0_TRxPathEnable 0xc04
-#define rOFDM0_TRMuxPar 0xc08
-#define rOFDM0_TRSWIsolation 0xc0c
-#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter
-#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix
-#define rOFDM0_XBRxAFE 0xc18
+#define rOFDM0_TRMuxPar 0xc08
+#define rOFDM0_TRSWIsolation 0xc0c
+/* RxIQ DC offset, Rx digital filter, DC notch filter */
+#define rOFDM0_XARxAFE 0xc10
+/* RxIQ imblance matrix */
+#define rOFDM0_XARxIQImbalance 0xc14
+#define rOFDM0_XBRxAFE 0xc18
#define rOFDM0_XBRxIQImbalance 0xc1c
-#define rOFDM0_XCRxAFE 0xc20
+#define rOFDM0_XCRxAFE 0xc20
#define rOFDM0_XCRxIQImbalance 0xc24
-#define rOFDM0_XDRxAFE 0xc28
+#define rOFDM0_XDRxAFE 0xc28
#define rOFDM0_XDRxIQImbalance 0xc2c
-#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD
-#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync.
-#define rOFDM0_RxDetector3 0xc38 //Frame Sync.
-#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI
-#define rOFDM0_RxDSP 0xc40 //Rx Sync Path
-#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC
-#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold
-#define rOFDM0_ECCAThreshold 0xc4c // energy CCA
+/* PD, BW & SBD */
+#define rOFDM0_RxDetector1 0xc30
+/* SBD */
+#define rOFDM0_RxDetector2 0xc34
+/* Frame Sync */
+#define rOFDM0_RxDetector3 0xc38
+/* PD, SBD, Frame Sync & Short-GI */
+#define rOFDM0_RxDetector4 0xc3c
+/* Rx Sync Path */
+#define rOFDM0_RxDSP 0xc40
+/* CFO & DAGC */
+#define rOFDM0_CFOandDAGC 0xc44
+/* CCA Drop threshold */
+#define rOFDM0_CCADropThreshold 0xc48
+/* Energy CCA */
+#define rOFDM0_ECCAThreshold 0xc4c
#define rOFDM0_XAAGCCore1 0xc50
#define rOFDM0_XAAGCCore2 0xc54
#define rOFDM0_XBAGCCore1 0xc58
@@ -139,501 +156,517 @@
#define rOFDM0_AGCParameter1 0xc70
#define rOFDM0_AGCParameter2 0xc74
#define rOFDM0_AGCRSSITable 0xc78
-#define rOFDM0_HTSTFAGC 0xc7c
+#define rOFDM0_HTSTFAGC 0xc7c
#define rOFDM0_XATxIQImbalance 0xc80
-#define rOFDM0_XATxAFE 0xc84
+#define rOFDM0_XATxAFE 0xc84
#define rOFDM0_XBTxIQImbalance 0xc88
-#define rOFDM0_XBTxAFE 0xc8c
+#define rOFDM0_XBTxAFE 0xc8c
#define rOFDM0_XCTxIQImbalance 0xc90
-#define rOFDM0_XCTxAFE 0xc94
+#define rOFDM0_XCTxAFE 0xc94
#define rOFDM0_XDTxIQImbalance 0xc98
-#define rOFDM0_XDTxAFE 0xc9c
+#define rOFDM0_XDTxAFE 0xc9c
#define rOFDM0_RxHPParameter 0xce0
#define rOFDM0_TxPseudoNoiseWgt 0xce4
-#define rOFDM0_FrameSync 0xcf0
-#define rOFDM0_DFSReport 0xcf4
-#define rOFDM0_TxCoeff1 0xca4
-#define rOFDM0_TxCoeff2 0xca8
-#define rOFDM0_TxCoeff3 0xcac
-#define rOFDM0_TxCoeff4 0xcb0
-#define rOFDM0_TxCoeff5 0xcb4
-#define rOFDM0_TxCoeff6 0xcb8
-
-
-//page d
-#define rOFDM1_LSTF 0xd00
+#define rOFDM0_FrameSync 0xcf0
+#define rOFDM0_DFSReport 0xcf4
+#define rOFDM0_TxCoeff1 0xca4
+#define rOFDM0_TxCoeff2 0xca8
+#define rOFDM0_TxCoeff3 0xcac
+#define rOFDM0_TxCoeff4 0xcb0
+#define rOFDM0_TxCoeff5 0xcb4
+#define rOFDM0_TxCoeff6 0xcb8
+
+
+/* Page d */
+#define rOFDM1_LSTF 0xd00
#define rOFDM1_TRxPathEnable 0xd04
-#define rOFDM1_CFO 0xd08
-#define rOFDM1_CSI1 0xd10
-#define rOFDM1_SBD 0xd14
-#define rOFDM1_CSI2 0xd18
-#define rOFDM1_CFOTracking 0xd2c
+#define rOFDM1_CFO 0xd08
+#define rOFDM1_CSI1 0xd10
+#define rOFDM1_SBD 0xd14
+#define rOFDM1_CSI2 0xd18
+#define rOFDM1_CFOTracking 0xd2c
#define rOFDM1_TRxMesaure1 0xd34
-#define rOFDM1_IntfDet 0xd3c
-#define rOFDM1_PseudoNoiseStateAB 0xd50
-#define rOFDM1_PseudoNoiseStateCD 0xd54
-#define rOFDM1_RxPseudoNoiseWgt 0xd58
-#define rOFDM_PHYCounter1 0xda0 //cca, parity fail
-#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail
-#define rOFDM_PHYCounter3 0xda8 //MCS not support
-#define rOFDM_ShortCFOAB 0xdac
-#define rOFDM_ShortCFOCD 0xdb0
-#define rOFDM_LongCFOAB 0xdb4
-#define rOFDM_LongCFOCD 0xdb8
-#define rOFDM_TailCFOAB 0xdbc
-#define rOFDM_TailCFOCD 0xdc0
+#define rOFDM1_IntfDet 0xd3c
+#define rOFDM1_PseudoNoiseStateAB 0xd50
+#define rOFDM1_PseudoNoiseStateCD 0xd54
+#define rOFDM1_RxPseudoNoiseWgt 0xd58
+/* cca, parity fail */
+#define rOFDM_PHYCounter1 0xda0
+/* rate illegal, crc8 fail */
+#define rOFDM_PHYCounter2 0xda4
+/* MCS not supported */
+#define rOFDM_PHYCounter3 0xda8
+#define rOFDM_ShortCFOAB 0xdac
+#define rOFDM_ShortCFOCD 0xdb0
+#define rOFDM_LongCFOAB 0xdb4
+#define rOFDM_LongCFOCD 0xdb8
+#define rOFDM_TailCFOAB 0xdbc
+#define rOFDM_TailCFOCD 0xdc0
#define rOFDM_PWMeasure1 0xdc4
#define rOFDM_PWMeasure2 0xdc8
-#define rOFDM_BWReport 0xdcc
-#define rOFDM_AGCReport 0xdd0
-#define rOFDM_RxSNR 0xdd4
-#define rOFDM_RxEVMCSI 0xdd8
-#define rOFDM_SIGReport 0xddc
-
-//page e
-#define rTxAGC_Rate18_06 0xe00
-#define rTxAGC_Rate54_24 0xe04
-#define rTxAGC_CCK_Mcs32 0xe08
-#define rTxAGC_Mcs03_Mcs00 0xe10
-#define rTxAGC_Mcs07_Mcs04 0xe14
-#define rTxAGC_Mcs11_Mcs08 0xe18
-#define rTxAGC_Mcs15_Mcs12 0xe1c
-
-
-//RF
-//Zebra1
+#define rOFDM_BWReport 0xdcc
+#define rOFDM_AGCReport 0xdd0
+#define rOFDM_RxSNR 0xdd4
+#define rOFDM_RxEVMCSI 0xdd8
+#define rOFDM_SIGReport 0xddc
+
+/* Page e */
+#define rTxAGC_Rate18_06 0xe00
+#define rTxAGC_Rate54_24 0xe04
+#define rTxAGC_CCK_Mcs32 0xe08
+#define rTxAGC_Mcs03_Mcs00 0xe10
+#define rTxAGC_Mcs07_Mcs04 0xe14
+#define rTxAGC_Mcs11_Mcs08 0xe18
+#define rTxAGC_Mcs15_Mcs12 0xe1c
+
+
+/* RF Zebra 1 */
#define rZebra1_HSSIEnable 0x0
#define rZebra1_TRxEnable1 0x1
#define rZebra1_TRxEnable2 0x2
-#define rZebra1_AGC 0x4
+#define rZebra1_AGC 0x4
#define rZebra1_ChargePump 0x5
-#define rZebra1_Channel 0x7
-#define rZebra1_TxGain 0x8
-#define rZebra1_TxLPF 0x9
-#define rZebra1_RxLPF 0xb
+#define rZebra1_Channel 0x7
+#define rZebra1_TxGain 0x8
+#define rZebra1_TxLPF 0x9
+#define rZebra1_RxLPF 0xb
#define rZebra1_RxHPFCorner 0xc
-//Zebra4
-#define rGlobalCtrl 0
-#define rRTL8256_TxLPF 19
-#define rRTL8256_RxLPF 11
+/* Zebra 4 */
+#define rGlobalCtrl 0
+#define rRTL8256_TxLPF 19
+#define rRTL8256_RxLPF 11
-//RTL8258
-#define rRTL8258_TxLPF 0x11
-#define rRTL8258_RxLPF 0x13
+/* RTL8258 */
+#define rRTL8258_TxLPF 0x11
+#define rRTL8258_RxLPF 0x13
#define rRTL8258_RSSILPF 0xa
-//Bit Mask
-//page-1
-#define bBBResetB 0x100
-#define bGlobalResetB 0x200
-#define bOFDMTxStart 0x4
-#define bCCKTxStart 0x8
-#define bCRC32Debug 0x100
-#define bPMACLoopback 0x10
-#define bTxLSIG 0xffffff
-#define bOFDMTxRate 0xf
-#define bOFDMTxReserved 0x10
-#define bOFDMTxLength 0x1ffe0
-#define bOFDMTxParity 0x20000
-#define bTxHTSIG1 0xffffff
-#define bTxHTMCSRate 0x7f
-#define bTxHTBW 0x80
-#define bTxHTLength 0xffff00
-#define bTxHTSIG2 0xffffff
-#define bTxHTSmoothing 0x1
-#define bTxHTSounding 0x2
-#define bTxHTReserved 0x4
-#define bTxHTAggreation 0x8
-#define bTxHTSTBC 0x30
-#define bTxHTAdvanceCoding 0x40
-#define bTxHTShortGI 0x80
-#define bTxHTNumberHT_LTF 0x300
-#define bTxHTCRC8 0x3fc00
-#define bCounterReset 0x10000
-#define bNumOfOFDMTx 0xffff
-#define bNumOfCCKTx 0xffff0000
-#define bTxIdleInterval 0xffff
-#define bOFDMService 0xffff0000
-#define bTxMACHeader 0xffffffff
-#define bTxDataInit 0xff
-#define bTxHTMode 0x100
-#define bTxDataType 0x30000
-#define bTxRandomSeed 0xffffffff
-#define bCCKTxPreamble 0x1
-#define bCCKTxSFD 0xffff0000
-#define bCCKTxSIG 0xff
-#define bCCKTxService 0xff00
-#define bCCKLengthExt 0x8000
-#define bCCKTxLength 0xffff0000
-#define bCCKTxCRC16 0xffff
-#define bCCKTxStatus 0x1
-#define bOFDMTxStatus 0x2
-
-//page-8
-#define bRFMOD 0x1
-#define bJapanMode 0x2
-#define bCCKTxSC 0x30
-#define bCCKEn 0x1000000
-#define bOFDMEn 0x2000000
-#define bOFDMRxADCPhase 0x10000
-#define bOFDMTxDACPhase 0x40000
-#define bXATxAGC 0x3f
-#define bXBTxAGC 0xf00
-#define bXCTxAGC 0xf000
-#define bXDTxAGC 0xf0000
-#define bPAStart 0xf0000000
-#define bTRStart 0x00f00000
-#define bRFStart 0x0000f000
-#define bBBStart 0x000000f0
-#define bBBCCKStart 0x0000000f
-#define bPAEnd 0xf //Reg0x814
-#define bTREnd 0x0f000000
-#define bRFEnd 0x000f0000
-#define bCCAMask 0x000000f0 //T2R
-#define bR2RCCAMask 0x00000f00
-#define bHSSI_R2TDelay 0xf8000000
-#define bHSSI_T2RDelay 0xf80000
-#define bContTxHSSI 0x400 //channel gain at continue Tx
-#define bIGFromCCK 0x200
-#define bAGCAddress 0x3f
-#define bRxHPTx 0x7000
-#define bRxHPT2R 0x38000
-#define bRxHPCCKIni 0xc0000
-#define bAGCTxCode 0xc00000
-#define bAGCRxCode 0x300000
-#define b3WireDataLength 0x800
-#define b3WireAddressLength 0x400
-#define b3WireRFPowerDown 0x1
-//#define bHWSISelect 0x8
-#define b5GPAPEPolarity 0x40000000
-#define b2GPAPEPolarity 0x80000000
-#define bRFSW_TxDefaultAnt 0x3
-#define bRFSW_TxOptionAnt 0x30
-#define bRFSW_RxDefaultAnt 0x300
-#define bRFSW_RxOptionAnt 0x3000
-#define bRFSI_3WireData 0x1
-#define bRFSI_3WireClock 0x2
-#define bRFSI_3WireLoad 0x4
-#define bRFSI_3WireRW 0x8
-#define bRFSI_3Wire 0xf //3-wire total control
-#define bRFSI_RFENV 0x10
-#define bRFSI_TRSW 0x20
-#define bRFSI_TRSWB 0x40
-#define bRFSI_ANTSW 0x100
-#define bRFSI_ANTSWB 0x200
-#define bRFSI_PAPE 0x400
-#define bRFSI_PAPE5G 0x800
-#define bBandSelect 0x1
-#define bHTSIG2_GI 0x80
-#define bHTSIG2_Smoothing 0x01
-#define bHTSIG2_Sounding 0x02
-#define bHTSIG2_Aggreaton 0x08
-#define bHTSIG2_STBC 0x30
-#define bHTSIG2_AdvCoding 0x40
+/* Bit Mask */
+/* Page 1 */
+#define bBBResetB 0x100
+#define bGlobalResetB 0x200
+#define bOFDMTxStart 0x4
+#define bCCKTxStart 0x8
+#define bCRC32Debug 0x100
+#define bPMACLoopback 0x10
+#define bTxLSIG 0xffffff
+#define bOFDMTxRate 0xf
+#define bOFDMTxReserved 0x10
+#define bOFDMTxLength 0x1ffe0
+#define bOFDMTxParity 0x20000
+#define bTxHTSIG1 0xffffff
+#define bTxHTMCSRate 0x7f
+#define bTxHTBW 0x80
+#define bTxHTLength 0xffff00
+#define bTxHTSIG2 0xffffff
+#define bTxHTSmoothing 0x1
+#define bTxHTSounding 0x2
+#define bTxHTReserved 0x4
+#define bTxHTAggreation 0x8
+#define bTxHTSTBC 0x30
+#define bTxHTAdvanceCoding 0x40
+#define bTxHTShortGI 0x80
+#define bTxHTNumberHT_LTF 0x300
+#define bTxHTCRC8 0x3fc00
+#define bCounterReset 0x10000
+#define bNumOfOFDMTx 0xffff
+#define bNumOfCCKTx 0xffff0000
+#define bTxIdleInterval 0xffff
+#define bOFDMService 0xffff0000
+#define bTxMACHeader 0xffffffff
+#define bTxDataInit 0xff
+#define bTxHTMode 0x100
+#define bTxDataType 0x30000
+#define bTxRandomSeed 0xffffffff
+#define bCCKTxPreamble 0x1
+#define bCCKTxSFD 0xffff0000
+#define bCCKTxSIG 0xff
+#define bCCKTxService 0xff00
+#define bCCKLengthExt 0x8000
+#define bCCKTxLength 0xffff0000
+#define bCCKTxCRC16 0xffff
+#define bCCKTxStatus 0x1
+#define bOFDMTxStatus 0x2
+
+/* Page 8 */
+#define bRFMOD 0x1
+#define bJapanMode 0x2
+#define bCCKTxSC 0x30
+#define bCCKEn 0x1000000
+#define bOFDMEn 0x2000000
+#define bOFDMRxADCPhase 0x10000
+#define bOFDMTxDACPhase 0x40000
+#define bXATxAGC 0x3f
+#define bXBTxAGC 0xf00
+#define bXCTxAGC 0xf000
+#define bXDTxAGC 0xf0000
+#define bPAStart 0xf0000000
+#define bTRStart 0x00f00000
+#define bRFStart 0x0000f000
+#define bBBStart 0x000000f0
+#define bBBCCKStart 0x0000000f
+/* Reg)x814 */
+#define bPAEnd 0xf
+#define bTREnd 0x0f000000
+#define bRFEnd 0x000f0000
+/* T2R */
+#define bCCAMask 0x000000f0
+#define bR2RCCAMask 0x00000f00
+#define bHSSI_R2TDelay 0xf8000000
+#define bHSSI_T2RDelay 0xf80000
+/* Channel gain at continue TX. */
+#define bContTxHSSI 0x400
+#define bIGFromCCK 0x200
+#define bAGCAddress 0x3f
+#define bRxHPTx 0x7000
+#define bRxHPT2R 0x38000
+#define bRxHPCCKIni 0xc0000
+#define bAGCTxCode 0xc00000
+#define bAGCRxCode 0x300000
+#define b3WireDataLength 0x800
+#define b3WireAddressLength 0x400
+#define b3WireRFPowerDown 0x1
+/*#define bHWSISelect 0x8 */
+#define b5GPAPEPolarity 0x40000000
+#define b2GPAPEPolarity 0x80000000
+#define bRFSW_TxDefaultAnt 0x3
+#define bRFSW_TxOptionAnt 0x30
+#define bRFSW_RxDefaultAnt 0x300
+#define bRFSW_RxOptionAnt 0x3000
+#define bRFSI_3WireData 0x1
+#define bRFSI_3WireClock 0x2
+#define bRFSI_3WireLoad 0x4
+#define bRFSI_3WireRW 0x8
+/* 3-wire total control */
+#define bRFSI_3Wire 0xf
+#define bRFSI_RFENV 0x10
+#define bRFSI_TRSW 0x20
+#define bRFSI_TRSWB 0x40
+#define bRFSI_ANTSW 0x100
+#define bRFSI_ANTSWB 0x200
+#define bRFSI_PAPE 0x400
+#define bRFSI_PAPE5G 0x800
+#define bBandSelect 0x1
+#define bHTSIG2_GI 0x80
+#define bHTSIG2_Smoothing 0x01
+#define bHTSIG2_Sounding 0x02
+#define bHTSIG2_Aggreaton 0x08
+#define bHTSIG2_STBC 0x30
+#define bHTSIG2_AdvCoding 0x40
#define bHTSIG2_NumOfHTLTF 0x300
-#define bHTSIG2_CRC8 0x3fc
-#define bHTSIG1_MCS 0x7f
-#define bHTSIG1_BandWidth 0x80
-#define bHTSIG1_HTLength 0xffff
-#define bLSIG_Rate 0xf
-#define bLSIG_Reserved 0x10
-#define bLSIG_Length 0x1fffe
-#define bLSIG_Parity 0x20
-#define bCCKRxPhase 0x4
-#define bLSSIReadAddress 0x3f000000 //LSSI "Read" Address
-#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal
-#define bLSSIReadBackData 0xfff
-#define bLSSIReadOKFlag 0x1000
-#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz
-
-#define bRegulator0Standby 0x1
-#define bRegulatorPLLStandby 0x2
-#define bRegulator1Standby 0x4
-#define bPLLPowerUp 0x8
-#define bDPLLPowerUp 0x10
-#define bDA10PowerUp 0x20
-#define bAD7PowerUp 0x200
-#define bDA6PowerUp 0x2000
-#define bXtalPowerUp 0x4000
-#define b40MDClkPowerUP 0x8000
-#define bDA6DebugMode 0x20000
-#define bDA6Swing 0x380000
-#define bADClkPhase 0x4000000
-#define b80MClkDelay 0x18000000
-#define bAFEWatchDogEnable 0x20000000
-#define bXtalCap 0x0f000000
-#define bXtalCap01 0xc0000000
-#define bXtalCap23 0x3
-#define bXtalCap92x 0x0f000000
-#define bIntDifClkEnable 0x400
-#define bExtSigClkEnable 0x800
+#define bHTSIG2_CRC8 0x3fc
+#define bHTSIG1_MCS 0x7f
+#define bHTSIG1_BandWidth 0x80
+#define bHTSIG1_HTLength 0xffff
+#define bLSIG_Rate 0xf
+#define bLSIG_Reserved 0x10
+#define bLSIG_Length 0x1fffe
+#define bLSIG_Parity 0x20
+#define bCCKRxPhase 0x4
+/* LSSI "read" address */
+#define bLSSIReadAddress 0x3f000000
+/* LSSI "read" edge signal */
+#define bLSSIReadEdge 0x80000000
+#define bLSSIReadBackData 0xfff
+#define bLSSIReadOKFlag 0x1000
+/* 0: 44 MHz, 1: 88MHz */
+#define bCCKSampleRate 0x8
+
+#define bRegulator0Standby 0x1
+#define bRegulatorPLLStandby 0x2
+#define bRegulator1Standby 0x4
+#define bPLLPowerUp 0x8
+#define bDPLLPowerUp 0x10
+#define bDA10PowerUp 0x20
+#define bAD7PowerUp 0x200
+#define bDA6PowerUp 0x2000
+#define bXtalPowerUp 0x4000
+#define b40MDClkPowerUP 0x8000
+#define bDA6DebugMode 0x20000
+#define bDA6Swing 0x380000
+#define bADClkPhase 0x4000000
+#define b80MClkDelay 0x18000000
+#define bAFEWatchDogEnable 0x20000000
+#define bXtalCap 0x0f000000
+#define bXtalCap01 0xc0000000
+#define bXtalCap23 0x3
+#define bXtalCap92x 0x0f000000
+#define bIntDifClkEnable 0x400
+#define bExtSigClkEnable 0x800
#define bBandgapMbiasPowerUp 0x10000
-#define bAD11SHGain 0xc0000
-#define bAD11InputRange 0x700000
-#define bAD11OPCurrent 0x3800000
-#define bIPathLoopback 0x4000000
-#define bQPathLoopback 0x8000000
-#define bAFELoopback 0x10000000
-#define bDA10Swing 0x7e0
-#define bDA10Reverse 0x800
-#define bDAClkSource 0x1000
-#define bAD7InputRange 0x6000
-#define bAD7Gain 0x38000
-#define bAD7OutputCMMode 0x40000
-#define bAD7InputCMMode 0x380000
-#define bAD7Current 0xc00000
-#define bRegulatorAdjust 0x7000000
-#define bAD11PowerUpAtTx 0x1
-#define bDA10PSAtTx 0x10
-#define bAD11PowerUpAtRx 0x100
-#define bDA10PSAtRx 0x1000
-
-#define bCCKRxAGCFormat 0x200
-
-#define bPSDFFTSamplepPoint 0xc000
-#define bPSDAverageNum 0x3000
-#define bIQPathControl 0xc00
-#define bPSDFreq 0x3ff
-#define bPSDAntennaPath 0x30
-#define bPSDIQSwitch 0x40
-#define bPSDRxTrigger 0x400000
-#define bPSDTxTrigger 0x80000000
-#define bPSDSineToneScale 0x7f000000
-#define bPSDReport 0xffff
-
-//page-9
-#define bOFDMTxSC 0x30000000
-#define bCCKTxOn 0x1
-#define bOFDMTxOn 0x2
-#define bDebugPage 0xfff //reset debug page and also HWord, LWord
-#define bDebugItem 0xff //reset debug page and LWord
-#define bAntL 0x10
-#define bAntNonHT 0x100
-#define bAntHT1 0x1000
-#define bAntHT2 0x10000
-#define bAntHT1S1 0x100000
-#define bAntNonHTS1 0x1000000
-
-//page-a
-#define bCCKBBMode 0x3
-#define bCCKTxPowerSaving 0x80
-#define bCCKRxPowerSaving 0x40
-#define bCCKSideBand 0x10
-#define bCCKScramble 0x8
-#define bCCKAntDiversity 0x8000
+#define bAD11SHGain 0xc0000
+#define bAD11InputRange 0x700000
+#define bAD11OPCurrent 0x3800000
+#define bIPathLoopback 0x4000000
+#define bQPathLoopback 0x8000000
+#define bAFELoopback 0x10000000
+#define bDA10Swing 0x7e0
+#define bDA10Reverse 0x800
+#define bDAClkSource 0x1000
+#define bAD7InputRange 0x6000
+#define bAD7Gain 0x38000
+#define bAD7OutputCMMode 0x40000
+#define bAD7InputCMMode 0x380000
+#define bAD7Current 0xc00000
+#define bRegulatorAdjust 0x7000000
+#define bAD11PowerUpAtTx 0x1
+#define bDA10PSAtTx 0x10
+#define bAD11PowerUpAtRx 0x100
+#define bDA10PSAtRx 0x1000
+
+#define bCCKRxAGCFormat 0x200
+
+#define bPSDFFTSamplepPoint 0xc000
+#define bPSDAverageNum 0x3000
+#define bIQPathControl 0xc00
+#define bPSDFreq 0x3ff
+#define bPSDAntennaPath 0x30
+#define bPSDIQSwitch 0x40
+#define bPSDRxTrigger 0x400000
+#define bPSDTxTrigger 0x80000000
+#define bPSDSineToneScale 0x7f000000
+#define bPSDReport 0xffff
+
+/* Page 8 */
+#define bOFDMTxSC 0x30000000
+#define bCCKTxOn 0x1
+#define bOFDMTxOn 0x2
+/* Reset debug page and also HWord, LWord */
+#define bDebugPage 0xfff
+/* Reset debug page and LWord */
+#define bDebugItem 0xff
+#define bAntL 0x10
+#define bAntNonHT 0x100
+#define bAntHT1 0x1000
+#define bAntHT2 0x10000
+#define bAntHT1S1 0x100000
+#define bAntNonHTS1 0x1000000
+
+/* Page a */
+#define bCCKBBMode 0x3
+#define bCCKTxPowerSaving 0x80
+#define bCCKRxPowerSaving 0x40
+#define bCCKSideBand 0x10
+#define bCCKScramble 0x8
+#define bCCKAntDiversity 0x8000
#define bCCKCarrierRecovery 0x4000
-#define bCCKTxRate 0x3000
-#define bCCKDCCancel 0x0800
-#define bCCKISICancel 0x0400
-#define bCCKMatchFilter 0x0200
-#define bCCKEqualizer 0x0100
-#define bCCKPreambleDetect 0x800000
-#define bCCKFastFalseCCA 0x400000
-#define bCCKChEstStart 0x300000
-#define bCCKCCACount 0x080000
-#define bCCKcs_lim 0x070000
-#define bCCKBistMode 0x80000000
-#define bCCKCCAMask 0x40000000
+#define bCCKTxRate 0x3000
+#define bCCKDCCancel 0x0800
+#define bCCKISICancel 0x0400
+#define bCCKMatchFilter 0x0200
+#define bCCKEqualizer 0x0100
+#define bCCKPreambleDetect 0x800000
+#define bCCKFastFalseCCA 0x400000
+#define bCCKChEstStart 0x300000
+#define bCCKCCACount 0x080000
+#define bCCKcs_lim 0x070000
+#define bCCKBistMode 0x80000000
+#define bCCKCCAMask 0x40000000
#define bCCKTxDACPhase 0x4
-#define bCCKRxADCPhase 0x20000000 //r_rx_clk
+/* r_rx_clk */
+#define bCCKRxADCPhase 0x20000000
#define bCCKr_cp_mode0 0x0100
-#define bCCKTxDCOffset 0xf0
-#define bCCKRxDCOffset 0xf
-#define bCCKCCAMode 0xc000
-#define bCCKFalseCS_lim 0x3f00
-#define bCCKCS_ratio 0xc00000
-#define bCCKCorgBit_sel 0x300000
-#define bCCKPD_lim 0x0f0000
-#define bCCKNewCCA 0x80000000
-#define bCCKRxHPofIG 0x8000
-#define bCCKRxIG 0x7f00
-#define bCCKLNAPolarity 0x800000
-#define bCCKRx1stGain 0x7f0000
-#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity
-#define bCCKRxAGCSatLevel 0x1f000000
-#define bCCKRxAGCSatCount 0xe0
-#define bCCKRxRFSettle 0x1f //AGCsamp_dly
-#define bCCKFixedRxAGC 0x8000
-//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824
-#define bCCKAntennaPolarity 0x2000
-#define bCCKTxFilterType 0x0c00
+#define bCCKTxDCOffset 0xf0
+#define bCCKRxDCOffset 0xf
+#define bCCKCCAMode 0xc000
+#define bCCKFalseCS_lim 0x3f00
+#define bCCKCS_ratio 0xc00000
+#define bCCKCorgBit_sel 0x300000
+#define bCCKPD_lim 0x0f0000
+#define bCCKNewCCA 0x80000000
+#define bCCKRxHPofIG 0x8000
+#define bCCKRxIG 0x7f00
+#define bCCKLNAPolarity 0x800000
+#define bCCKRx1stGain 0x7f0000
+/* CCK Rx Initial gain polarity */
+#define bCCKRFExtend 0x20000000
+#define bCCKRxAGCSatLevel 0x1f000000
+#define bCCKRxAGCSatCount 0xe0
+/* AGCSAmp_dly */
+#define bCCKRxRFSettle 0x1f
+#define bCCKFixedRxAGC 0x8000
+/*#define bCCKRxAGCFormat 0x4000 remove to HSSI register 0x824 */
+#define bCCKAntennaPolarity 0x2000
+#define bCCKTxFilterType 0x0c00
#define bCCKRxAGCReportType 0x0300
-#define bCCKRxDAGCEn 0x80000000
-#define bCCKRxDAGCPeriod 0x20000000
+#define bCCKRxDAGCEn 0x80000000
+#define bCCKRxDAGCPeriod 0x20000000
#define bCCKRxDAGCSatLevel 0x1f000000
-#define bCCKTimingRecovery 0x800000
-#define bCCKTxC0 0x3f0000
-#define bCCKTxC1 0x3f000000
-#define bCCKTxC2 0x3f
-#define bCCKTxC3 0x3f00
-#define bCCKTxC4 0x3f0000
-#define bCCKTxC5 0x3f000000
-#define bCCKTxC6 0x3f
-#define bCCKTxC7 0x3f00
-#define bCCKDebugPort 0xff0000
-#define bCCKDACDebug 0x0f000000
-#define bCCKFalseAlarmEnable 0x8000
-#define bCCKFalseAlarmRead 0x4000
-#define bCCKTRSSI 0x7f
-#define bCCKRxAGCReport 0xfe
-#define bCCKRxReport_AntSel 0x80000000
-#define bCCKRxReport_MFOff 0x40000000
+#define bCCKTimingRecovery 0x800000
+#define bCCKTxC0 0x3f0000
+#define bCCKTxC1 0x3f000000
+#define bCCKTxC2 0x3f
+#define bCCKTxC3 0x3f00
+#define bCCKTxC4 0x3f0000
+#define bCCKTxC5 0x3f000000
+#define bCCKTxC6 0x3f
+#define bCCKTxC7 0x3f00
+#define bCCKDebugPort 0xff0000
+#define bCCKDACDebug 0x0f000000
+#define bCCKFalseAlarmEnable 0x8000
+#define bCCKFalseAlarmRead 0x4000
+#define bCCKTRSSI 0x7f
+#define bCCKRxAGCReport 0xfe
+#define bCCKRxReport_AntSel 0x80000000
+#define bCCKRxReport_MFOff 0x40000000
#define bCCKRxRxReport_SQLoss 0x20000000
-#define bCCKRxReport_Pktloss 0x10000000
+#define bCCKRxReport_Pktloss 0x10000000
#define bCCKRxReport_Lockedbit 0x08000000
#define bCCKRxReport_RateError 0x04000000
-#define bCCKRxReport_RxRate 0x03000000
+#define bCCKRxReport_RxRate 0x03000000
#define bCCKRxFACounterLower 0xff
#define bCCKRxFACounterUpper 0xff000000
-#define bCCKRxHPAGCStart 0xe000
-#define bCCKRxHPAGCFinal 0x1c00
+#define bCCKRxHPAGCStart 0xe000
+#define bCCKRxHPAGCFinal 0x1c00
#define bCCKRxFalseAlarmEnable 0x8000
-#define bCCKFACounterFreeze 0x4000
-
-#define bCCKTxPathSel 0x10000000
-#define bCCKDefaultRxPath 0xc000000
-#define bCCKOptionRxPath 0x3000000
-
-//page c
-#define bNumOfSTF 0x3
-#define bShift_L 0xc0
-#define bGI_TH 0xc
-#define bRxPathA 0x1
-#define bRxPathB 0x2
-#define bRxPathC 0x4
-#define bRxPathD 0x8
-#define bTxPathA 0x1
-#define bTxPathB 0x2
-#define bTxPathC 0x4
-#define bTxPathD 0x8
-#define bTRSSIFreq 0x200
-#define bADCBackoff 0x3000
-#define bDFIRBackoff 0xc000
-#define bTRSSILatchPhase 0x10000
-#define bRxIDCOffset 0xff
-#define bRxQDCOffset 0xff00
-#define bRxDFIRMode 0x1800000
-#define bRxDCNFType 0xe000000
-#define bRXIQImb_A 0x3ff
-#define bRXIQImb_B 0xfc00
-#define bRXIQImb_C 0x3f0000
-#define bRXIQImb_D 0xffc00000
-#define bDC_dc_Notch 0x60000
-#define bRxNBINotch 0x1f000000
-#define bPD_TH 0xf
-#define bPD_TH_Opt2 0xc000
-#define bPWED_TH 0x700
-#define bIfMF_Win_L 0x800
-#define bPD_Option 0x1000
-#define bMF_Win_L 0xe000
-#define bBW_Search_L 0x30000
-#define bwin_enh_L 0xc0000
-#define bBW_TH 0x700000
-#define bED_TH2 0x3800000
-#define bBW_option 0x4000000
-#define bRatio_TH 0x18000000
-#define bWindow_L 0xe0000000
-#define bSBD_Option 0x1
-#define bFrame_TH 0x1c
-#define bFS_Option 0x60
-#define bDC_Slope_check 0x80
-#define bFGuard_Counter_DC_L 0xe00
-#define bFrame_Weight_Short 0x7000
-#define bSub_Tune 0xe00000
-#define bFrame_DC_Length 0xe000000
-#define bSBD_start_offset 0x30000000
-#define bFrame_TH_2 0x7
-#define bFrame_GI2_TH 0x38
-#define bGI2_Sync_en 0x40
-#define bSarch_Short_Early 0x300
-#define bSarch_Short_Late 0xc00
-#define bSarch_GI2_Late 0x70000
-#define bCFOAntSum 0x1
-#define bCFOAcc 0x2
-#define bCFOStartOffset 0xc
-#define bCFOLookBack 0x70
-#define bCFOSumWeight 0x80
-#define bDAGCEnable 0x10000
-#define bTXIQImb_A 0x3ff
-#define bTXIQImb_B 0xfc00
-#define bTXIQImb_C 0x3f0000
-#define bTXIQImb_D 0xffc00000
-#define bTxIDCOffset 0xff
-#define bTxQDCOffset 0xff00
-#define bTxDFIRMode 0x10000
-#define bTxPesudoNoiseOn 0x4000000
-#define bTxPesudoNoise_A 0xff
-#define bTxPesudoNoise_B 0xff00
-#define bTxPesudoNoise_C 0xff0000
-#define bTxPesudoNoise_D 0xff000000
-#define bCCADropOption 0x20000
-#define bCCADropThres 0xfff00000
-#define bEDCCA_H 0xf
-#define bEDCCA_L 0xf0
-#define bLambda_ED 0x300
-#define bRxInitialGain 0x7f
-#define bRxAntDivEn 0x80
-#define bRxAGCAddressForLNA 0x7f00
-#define bRxHighPowerFlow 0x8000
-#define bRxAGCFreezeThres 0xc0000
-#define bRxFreezeStep_AGC1 0x300000
-#define bRxFreezeStep_AGC2 0xc00000
-#define bRxFreezeStep_AGC3 0x3000000
-#define bRxFreezeStep_AGC0 0xc000000
-#define bRxRssi_Cmp_En 0x10000000
-#define bRxQuickAGCEn 0x20000000
-#define bRxAGCFreezeThresMode 0x40000000
-#define bRxOverFlowCheckType 0x80000000
-#define bRxAGCShift 0x7f
-#define bTRSW_Tri_Only 0x80
-#define bPowerThres 0x300
-#define bRxAGCEn 0x1
-#define bRxAGCTogetherEn 0x2
-#define bRxAGCMin 0x4
-#define bRxHP_Ini 0x7
-#define bRxHP_TRLNA 0x70
-#define bRxHP_RSSI 0x700
-#define bRxHP_BBP1 0x7000
-#define bRxHP_BBP2 0x70000
-#define bRxHP_BBP3 0x700000
-#define bRSSI_H 0x7f0000 //the threshold for high power
-#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity
-#define bRxSettle_TRSW 0x7
-#define bRxSettle_LNA 0x38
-#define bRxSettle_RSSI 0x1c0
-#define bRxSettle_BBP 0xe00
-#define bRxSettle_RxHP 0x7000
-#define bRxSettle_AntSW_RSSI 0x38000
-#define bRxSettle_AntSW 0xc0000
-#define bRxProcessTime_DAGC 0x300000
-#define bRxSettle_HSSI 0x400000
-#define bRxProcessTime_BBPPW 0x800000
-#define bRxAntennaPowerShift 0x3000000
-#define bRSSITableSelect 0xc000000
-#define bRxHP_Final 0x7000000
-#define bRxHTSettle_BBP 0x7
-#define bRxHTSettle_HSSI 0x8
-#define bRxHTSettle_RxHP 0x70
-#define bRxHTSettle_BBPPW 0x80
-#define bRxHTSettle_Idle 0x300
-#define bRxHTSettle_Reserved 0x1c00
-#define bRxHTRxHPEn 0x8000
-#define bRxHTAGCFreezeThres 0x30000
-#define bRxHTAGCTogetherEn 0x40000
-#define bRxHTAGCMin 0x80000
-#define bRxHTAGCEn 0x100000
-#define bRxHTDAGCEn 0x200000
-#define bRxHTRxHP_BBP 0x1c00000
-#define bRxHTRxHP_Final 0xe0000000
-#define bRxPWRatioTH 0x3
-#define bRxPWRatioEn 0x4
-#define bRxMFHold 0x3800
-#define bRxPD_Delay_TH1 0x38
-#define bRxPD_Delay_TH2 0x1c0
-#define bRxPD_DC_COUNT_MAX 0x600
-//#define bRxMF_Hold 0x3800
+#define bCCKFACounterFreeze 0x4000
+
+#define bCCKTxPathSel 0x10000000
+#define bCCKDefaultRxPath 0xc000000
+#define bCCKOptionRxPath 0x3000000
+
+/* Page c */
+#define bNumOfSTF 0x3
+#define bShift_L 0xc0
+#define bGI_TH 0xc
+#define bRxPathA 0x1
+#define bRxPathB 0x2
+#define bRxPathC 0x4
+#define bRxPathD 0x8
+#define bTxPathA 0x1
+#define bTxPathB 0x2
+#define bTxPathC 0x4
+#define bTxPathD 0x8
+#define bTRSSIFreq 0x200
+#define bADCBackoff 0x3000
+#define bDFIRBackoff 0xc000
+#define bTRSSILatchPhase 0x10000
+#define bRxIDCOffset 0xff
+#define bRxQDCOffset 0xff00
+#define bRxDFIRMode 0x1800000
+#define bRxDCNFType 0xe000000
+#define bRXIQImb_A 0x3ff
+#define bRXIQImb_B 0xfc00
+#define bRXIQImb_C 0x3f0000
+#define bRXIQImb_D 0xffc00000
+#define bDC_dc_Notch 0x60000
+#define bRxNBINotch 0x1f000000
+#define bPD_TH 0xf
+#define bPD_TH_Opt2 0xc000
+#define bPWED_TH 0x700
+#define bIfMF_Win_L 0x800
+#define bPD_Option 0x1000
+#define bMF_Win_L 0xe000
+#define bBW_Search_L 0x30000
+#define bwin_enh_L 0xc0000
+#define bBW_TH 0x700000
+#define bED_TH2 0x3800000
+#define bBW_option 0x4000000
+#define bRatio_TH 0x18000000
+#define bWindow_L 0xe0000000
+#define bSBD_Option 0x1
+#define bFrame_TH 0x1c
+#define bFS_Option 0x60
+#define bDC_Slope_check 0x80
+#define bFGuard_Counter_DC_L 0xe00
+#define bFrame_Weight_Short 0x7000
+#define bSub_Tune 0xe00000
+#define bFrame_DC_Length 0xe000000
+#define bSBD_start_offset 0x30000000
+#define bFrame_TH_2 0x7
+#define bFrame_GI2_TH 0x38
+#define bGI2_Sync_en 0x40
+#define bSarch_Short_Early 0x300
+#define bSarch_Short_Late 0xc00
+#define bSarch_GI2_Late 0x70000
+#define bCFOAntSum 0x1
+#define bCFOAcc 0x2
+#define bCFOStartOffset 0xc
+#define bCFOLookBack 0x70
+#define bCFOSumWeight 0x80
+#define bDAGCEnable 0x10000
+#define bTXIQImb_A 0x3ff
+#define bTXIQImb_B 0xfc00
+#define bTXIQImb_C 0x3f0000
+#define bTXIQImb_D 0xffc00000
+#define bTxIDCOffset 0xff
+#define bTxQDCOffset 0xff00
+#define bTxDFIRMode 0x10000
+#define bTxPesudoNoiseOn 0x4000000
+#define bTxPesudoNoise_A 0xff
+#define bTxPesudoNoise_B 0xff00
+#define bTxPesudoNoise_C 0xff0000
+#define bTxPesudoNoise_D 0xff000000
+#define bCCADropOption 0x20000
+#define bCCADropThres 0xfff00000
+#define bEDCCA_H 0xf
+#define bEDCCA_L 0xf0
+#define bLambda_ED 0x300
+#define bRxInitialGain 0x7f
+#define bRxAntDivEn 0x80
+#define bRxAGCAddressForLNA 0x7f00
+#define bRxHighPowerFlow 0x8000
+#define bRxAGCFreezeThres 0xc0000
+#define bRxFreezeStep_AGC1 0x300000
+#define bRxFreezeStep_AGC2 0xc00000
+#define bRxFreezeStep_AGC3 0x3000000
+#define bRxFreezeStep_AGC0 0xc000000
+#define bRxRssi_Cmp_En 0x10000000
+#define bRxQuickAGCEn 0x20000000
+#define bRxAGCFreezeThresMode 0x40000000
+#define bRxOverFlowCheckType 0x80000000
+#define bRxAGCShift 0x7f
+#define bTRSW_Tri_Only 0x80
+#define bPowerThres 0x300
+#define bRxAGCEn 0x1
+#define bRxAGCTogetherEn 0x2
+#define bRxAGCMin 0x4
+#define bRxHP_Ini 0x7
+#define bRxHP_TRLNA 0x70
+#define bRxHP_RSSI 0x700
+#define bRxHP_BBP1 0x7000
+#define bRxHP_BBP2 0x70000
+#define bRxHP_BBP3 0x700000
+/* The threshold for high power */
+#define bRSSI_H 0x7f0000
+/* The threshold for ant diversity */
+#define bRSSI_Gen 0x7f000000
+#define bRxSettle_TRSW 0x7
+#define bRxSettle_LNA 0x38
+#define bRxSettle_RSSI 0x1c0
+#define bRxSettle_BBP 0xe00
+#define bRxSettle_RxHP 0x7000
+#define bRxSettle_AntSW_RSSI 0x38000
+#define bRxSettle_AntSW 0xc0000
+#define bRxProcessTime_DAGC 0x300000
+#define bRxSettle_HSSI 0x400000
+#define bRxProcessTime_BBPPW 0x800000
+#define bRxAntennaPowerShift 0x3000000
+#define bRSSITableSelect 0xc000000
+#define bRxHP_Final 0x7000000
+#define bRxHTSettle_BBP 0x7
+#define bRxHTSettle_HSSI 0x8
+#define bRxHTSettle_RxHP 0x70
+#define bRxHTSettle_BBPPW 0x80
+#define bRxHTSettle_Idle 0x300
+#define bRxHTSettle_Reserved 0x1c00
+#define bRxHTRxHPEn 0x8000
+#define bRxHTAGCFreezeThres 0x30000
+#define bRxHTAGCTogetherEn 0x40000
+#define bRxHTAGCMin 0x80000
+#define bRxHTAGCEn 0x100000
+#define bRxHTDAGCEn 0x200000
+#define bRxHTRxHP_BBP 0x1c00000
+#define bRxHTRxHP_Final 0xe0000000
+#define bRxPWRatioTH 0x3
+#define bRxPWRatioEn 0x4
+#define bRxMFHold 0x3800
+#define bRxPD_Delay_TH1 0x38
+#define bRxPD_Delay_TH2 0x1c0
+#define bRxPD_DC_COUNT_MAX 0x600
+/*#define bRxMF_Hold 0x3800*/
#define bRxPD_Delay_TH 0x8000
#define bRxProcess_Delay 0xf0000
#define bRxSearchrange_GI2_Early 0x700000
@@ -659,7 +692,7 @@
#define bExtLNAGain 0x7c00
-//page d
+/* Page d */
#define bSTBCEn 0x4
#define bAntennaMapping 0x10
#define bNss 0x20
@@ -669,12 +702,12 @@
#define bOFDMContinueTx 0x10000000
#define bOFDMSingleCarrier 0x20000000
#define bOFDMSingleTone 0x40000000
-//#define bRxPath1 0x01
-//#define bRxPath2 0x02
-//#define bRxPath3 0x04
-//#define bRxPath4 0x08
-//#define bTxPath1 0x10
-//#define bTxPath2 0x20
+/*#define bRxPath1 0x01
+#define bRxPath2 0x02
+#define bRxPath3 0x04
+#define bRxPath4 0x08
+#define bTxPath1 0x10
+#define bTxPath2 0x20*/
#define bHTDetect 0x100
#define bCFOEn 0x10000
#define bCFOValue 0xfff00000
@@ -687,8 +720,10 @@
#define bCounter_MCSNoSupport 0xffff
#define bCounter_FastSync 0xffff
#define bShortCFO 0xfff
-#define bShortCFOTLength 12 //total
-#define bShortCFOFLength 11 //fraction
+/* total */
+#define bShortCFOTLength 12
+/* fraction */
+#define bShortCFOFLength 11
#define bLongCFO 0x7ff
#define bLongCFOTLength 11
#define bLongCFOFLength 11
@@ -765,18 +800,18 @@
#define bUChCfg 0x7000000
#define bUpdEqz 0x8000000
-//page e
-#define bTxAGCRate18_06 0x7f7f7f7f
-#define bTxAGCRate54_24 0x7f7f7f7f
+/* Page e */
+#define bTxAGCRate18_06 0x7f7f7f7f
+#define bTxAGCRate54_24 0x7f7f7f7f
#define bTxAGCRateMCS32 0x7f
-#define bTxAGCRateCCK 0x7f00
+#define bTxAGCRateCCK 0x7f00
#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f
#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f
#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f
#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f
-//Rx Pseduo noise
+/* Rx Pseduo noise */
#define bRxPesudoNoiseOn 0x20000000
#define bRxPesudoNoise_A 0xff
#define bRxPesudoNoise_B 0xff00
@@ -787,8 +822,7 @@
#define bPesudoNoiseState_C 0xffff
#define bPesudoNoiseState_D 0xffff0000
-//RF
-//Zebra1
+/* RF Zebra 1 */
#define bZebra1_HSSIEnable 0x8
#define bZebra1_TRxControl 0xc00
#define bZebra1_TRxGainSetting 0x07f
@@ -799,7 +833,7 @@
#define bZebra1_TxLPFBW 0x400
#define bZebra1_RxLPFBW 0x600
-//Zebra4
+/* Zebra4 */
#define bRTL8256RegModeCtrl1 0x100
#define bRTL8256RegModeCtrl0 0x40
#define bRTL8256_TxLPFBW 0x18
@@ -810,7 +844,7 @@
#define bRTL8258_RxLPFBW 0xc00
#define bRTL8258_RSSILPFBW 0xc0
-//byte endable for sb_write
+/* byte endable for sb_write */
#define bByte0 0x1
#define bByte1 0x2
#define bByte2 0x4
@@ -819,7 +853,7 @@
#define bWord1 0xc
#define bDWord 0xf
-//for PutRegsetting & GetRegSetting BitMask
+/* for PutRegsetting & GetRegSetting BitMask */
#define bMaskByte0 0xff
#define bMaskByte1 0xff00
#define bMaskByte2 0xff0000
@@ -828,7 +862,7 @@
#define bMaskLWord 0x0000ffff
#define bMaskDWord 0xffffffff
-//for PutRFRegsetting & GetRFRegSetting BitMask
+/* for PutRFRegsetting & GetRFRegSetting BitMask */
#define bMask12Bits 0xfff
#define bEnable 0x1
@@ -837,14 +871,16 @@
#define LeftAntenna 0x0
#define RightAntenna 0x1
-#define tCheckTxStatus 500 //500ms
-#define tUpdateRxCounter 100 //100ms
+/* 500 ms */
+#define tCheckTxStatus 500
+/* 100 ms */
+#define tUpdateRxCounter 100
#define rateCCK 0
#define rateOFDM 1
#define rateHT 2
-//define Register-End
+/* define Register-End */
#define bPMAC_End 0x1ff
#define bFPGAPHY0_End 0x8ff
#define bFPGAPHY1_End 0x9ff
@@ -852,12 +888,12 @@
#define bOFDMPHY0_End 0xcff
#define bOFDMPHY1_End 0xdff
-//define max debug item in each debug page
-//#define bMaxItem_FPGA_PHY0 0x9
-//#define bMaxItem_FPGA_PHY1 0x3
-//#define bMaxItem_PHY_11B 0x16
-//#define bMaxItem_OFDM_PHY0 0x29
-//#define bMaxItem_OFDM_PHY1 0x0
+/*#define max debug item in each debug page
+#define bMaxItem_FPGA_PHY0 0x9
+#define bMaxItem_FPGA_PHY1 0x3
+#define bMaxItem_PHY_11B 0x16
+#define bMaxItem_OFDM_PHY0 0x29
+#define bMaxItem_OFDM_PHY1 0x0 */
#define bPMACControl 0x0
#define bWMACControl 0x1
@@ -868,11 +904,12 @@
#define PathC 0x2
#define PathD 0x3
-#define rRTL8256RxMixerPole 0xb
-#define bZebraRxMixerPole 0x6
-#define rRTL8256TxBBOPBias 0x9
-#define bRTL8256TxBBOPBias 0x400
-#define rRTL8256TxBBBW 19
-#define bRTL8256TxBBBW 0x18
+#define rRTL8256RxMixerPole 0xb
+#define bZebraRxMixerPole 0x6
+#define rRTL8256TxBBOPBias 0x9
+#define bRTL8256TxBBOPBias 0x400
+#define rRTL8256TxBBBW 19
+#define bRTL8256TxBBBW 0x18
+
-#endif //__INC_HAL8190PCIPHYREG_H
+#endif /* __INC_HAL8190PCIPHYREG_H */
diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig
index 123fa6d6a93..b72a96206f5 100644
--- a/drivers/staging/rtl8192su/Kconfig
+++ b/drivers/staging/rtl8192su/Kconfig
@@ -1,6 +1,7 @@
config RTL8192SU
tristate "RealTek RTL8192SU Wireless LAN NIC driver"
depends on PCI && WLAN && USB
- depends on WIRELESS_EXT
+ select WIRELESS_EXT
+ select WEXT_PRIV
default N
---help---
diff --git a/drivers/staging/rtl8192su/TODO b/drivers/staging/rtl8192su/TODO
index f11eec70003..3c8da157a93 100644
--- a/drivers/staging/rtl8192su/TODO
+++ b/drivers/staging/rtl8192su/TODO
@@ -4,7 +4,6 @@ TODO:
- cleanup ieee80211.h
- move rtl8192su's specific code out from ieee80211.h
- abstract rtl819su's specific code
- - use list_for_each_safe() in ieee80211_crypto_deinit
- switch to use shared "librtl" instead of private ieee80211 stack
- switch to use LIB80211
- switch to use MAC80211
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
index 2b8c85556dc..32b261d1559 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
@@ -30,6 +30,7 @@
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/sched.h>
+#include <linux/semaphore.h>
#include <linux/delay.h>
#include <linux/wireless.h>
@@ -195,10 +196,6 @@ extern u32 ieee80211_debug_level;
#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
#endif /* CONFIG_IEEE80211_DEBUG */
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \
- ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
-
/*
* To use the debug system;
*
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
index 521e7b98993..c4640e63196 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
@@ -226,19 +226,20 @@ out:
void __exit ieee80211_crypto_deinit(void)
{
struct list_head *ptr, *n;
+ struct ieee80211_crypto_alg *alg = NULL;
if (hcrypt == NULL)
return;
- for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
- ptr = n, n = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- list_del(ptr);
- printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- "'%s' (deinit)\n", alg->ops->name);
- kfree(alg);
+ list_for_each_safe(ptr, n, &hcrypt->algs) {
+ alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
+ if (alg) {
+ list_del(ptr);
+ printk(KERN_DEBUG
+ "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
+ alg->ops->name);
+ kfree(alg);
+ }
}
-
kfree(hcrypt);
}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
index 7bc956e1f45..8a93f7d3eb3 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
@@ -288,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: received packet without ExtIV"
- " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ " flag from %pM\n", hdr->addr2);
}
key->dot11RSNAStatsCCMPFormatErrors++;
return -2;
@@ -301,9 +301,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!key->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+ printk(KERN_DEBUG "CCMP: received packet from %pM"
" with keyid=%d that does not have a configured"
- " key\n", MAC_ARG(hdr->addr2), keyidx);
+ " key\n", hdr->addr2, keyidx);
}
return -3;
}
@@ -318,11 +318,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
- " previous PN %02x%02x%02x%02x%02x%02x "
- "received PN %02x%02x%02x%02x%02x%02x\n",
- MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
- MAC_ARG(pn));
+ printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
+ " previous PN %pm received PN %pm\n",
+ hdr->addr2, key->rx_pn, pn);
}
key->dot11RSNAStatsCCMPReplays++;
return -4;
@@ -359,7 +357,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: decrypt failed: STA="
- MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ "%pM\n", hdr->addr2);
}
key->dot11RSNAStatsCCMPDecryptErrors++;
return -5;
@@ -435,11 +433,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
{
struct ieee80211_ccmp_data *ccmp = priv;
p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
+ "tx_pn=%pm rx_pn=%pm "
"format_errors=%d replays=%d decrypt_errors=%d\n",
ccmp->key_idx, ccmp->key_set,
- MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+ ccmp->tx_pn, ccmp->rx_pn,
ccmp->dot11RSNAStatsCCMPFormatErrors,
ccmp->dot11RSNAStatsCCMPReplays,
ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
index 9b9438fb5f6..7e48748da10 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
@@ -410,7 +410,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ " flag from %pM\n", hdr->addr2);
}
return -2;
}
@@ -422,9 +422,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!tkey->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+ printk(KERN_DEBUG "TKIP: received packet from %pM"
" with keyid=%d that does not have a configured"
- " key\n", MAC_ARG(hdr->addr2), keyidx);
+ " key\n", hdr->addr2, keyidx);
}
return -3;
}
@@ -437,9 +437,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (iv32 < tkey->rx_iv32 ||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+ printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
" previous TSC %08x%04x received TSC "
- "%08x%04x\n", MAC_ARG(hdr->addr2),
+ "%08x%04x\n", hdr->addr2,
tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
}
tkey->dot11RSNAStatsTKIPReplays++;
@@ -460,8 +460,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
if (net_ratelimit()) {
printk(KERN_DEBUG ": TKIP: failed to decrypt "
- "received packet from " MAC_FMT "\n",
- MAC_ARG(hdr->addr2));
+ "received packet from %pM\n",
+ hdr->addr2);
}
return -7;
}
@@ -480,7 +480,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: ICV error detected: STA="
- MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ "%pM\n", hdr->addr2);
}
tkey->dot11RSNAStatsTKIPICVErrors++;
return -5;
@@ -635,8 +635,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
struct ieee80211_hdr_4addr *hdr;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- "MSDU from " MAC_FMT " keyidx=%d\n",
- skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+ "MSDU from %pM keyidx=%d\n",
+ skb->dev ? skb->dev->name : "N/A", hdr->addr2,
keyidx);
if (skb->dev)
ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
index e8c67d5dfb7..c024fa60072 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
@@ -262,7 +262,7 @@ static int store_debug_level(struct file *file, const char *buffer,
unsigned long count, void *data)
{
char buf[] = "0x00000000";
- unsigned long len = min(sizeof(buf) - 1, count);
+ unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
char *p = (char *)buf;
unsigned long val;
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
index 095b8c64314..cc80faf6598 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
@@ -314,8 +314,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
strcmp(crypt->ops->name, "TKIP") == 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "received packet from " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(hdr->addr2));
+ "received packet from %pM\n",
+ ieee->dev->name, hdr->addr2);
}
return -1;
}
@@ -326,8 +326,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
atomic_dec(&crypt->refcnt);
if (res < 0) {
IEEE80211_DEBUG_DROP(
- "decryption failed (SA=" MAC_FMT
- ") res=%d\n", MAC_ARG(hdr->addr2), res);
+ "decryption failed (SA=%pM"
+ ") res=%d\n", hdr->addr2, res);
if (res == -2)
IEEE80211_DEBUG_DROP("Decryption failed ICV "
"mismatch (key %d)\n",
@@ -364,8 +364,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
atomic_dec(&crypt->refcnt);
if (res < 0) {
printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- " (SA=" MAC_FMT " keyidx=%d)\n",
- ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+ " (SA=%pM keyidx=%d)\n",
+ ieee->dev->name, hdr->addr2, keyidx);
return -1;
}
@@ -939,8 +939,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
* frames silently instead of filling system log with
* these reports. */
IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ " (SA=%pM)\n",
+ hdr->addr2);
ieee->ieee_stats.rx_discards_undecryptable++;
goto rx_dropped;
}
@@ -1143,8 +1143,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
} else {
IEEE80211_DEBUG_DROP(
"encryption configured, but RX "
- "frame not encrypted (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ "frame not encrypted (SA=%pM)\n",
+ hdr->addr2);
goto rx_dropped;
}
}
@@ -1163,9 +1163,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
!ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
IEEE80211_DEBUG_DROP(
"dropped unencrypted RX data "
- "frame from " MAC_FMT
+ "frame from %pM"
" (drop_unencrypted=1)\n",
- MAC_ARG(hdr->addr2));
+ hdr->addr2);
goto rx_dropped;
}
/*
@@ -2159,11 +2159,11 @@ static inline int ieee80211_network_init(
}
if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+ IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
"network.\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid));
+ network->bssid);
return 1;
}
@@ -2345,9 +2345,9 @@ static inline void ieee80211_process_probe_response(
memset(&network, 0, sizeof(struct ieee80211_network));
IEEE80211_DEBUG_SCAN(
- "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+ "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
escape_essid(info_element->data, info_element->len),
- MAC_ARG(beacon->header.addr3),
+ beacon->header.addr3,
(beacon->capability & (1<<0xf)) ? '1' : '0',
(beacon->capability & (1<<0xe)) ? '1' : '0',
(beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2366,10 +2366,10 @@ static inline void ieee80211_process_probe_response(
(beacon->capability & (1<<0x0)) ? '1' : '0');
if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
escape_essid(info_element->data,
info_element->len),
- MAC_ARG(beacon->header.addr3),
+ beacon->header.addr3,
WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -2478,11 +2478,11 @@ static inline void ieee80211_process_probe_response(
/* If there are no more slots, expire the oldest */
list_del(&oldest->list);
target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+ IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
"network list.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid));
+ target->bssid);
} else {
/* Otherwise just pull from the free list */
target = list_entry(ieee->network_free_list.next,
@@ -2492,10 +2492,10 @@ static inline void ieee80211_process_probe_response(
#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
escape_essid(network.ssid,
network.ssid_len),
- MAC_ARG(network.bssid),
+ network.bssid,
WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -2505,10 +2505,10 @@ static inline void ieee80211_process_probe_response(
if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
ieee80211_softmac_new_net(ieee,&network);
} else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid),
+ target->bssid,
WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
index 0ba2a01a06a..84a4e23b60b 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
@@ -18,6 +18,7 @@
#include <linux/random.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#include "dot11d.h"
@@ -1709,7 +1710,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
ieee80211_resp_to_assoc_rq(ieee, dest);
}
- printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+ printk(KERN_INFO"New client associated: %pM\n", dest);
//FIXME
}
@@ -2145,8 +2146,8 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
ieee80211_sta_wakeup(ieee,0);
/* update the tx status */
-// ieee->stats.tx_bytes += txb->payload_size;
-// ieee->stats.tx_packets++;
+ ieee->stats.tx_bytes += txb->payload_size;
+ ieee->stats.tx_packets++;
tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
if(tcb_desc->bMulticast) {
ieee->stats.multicast++;
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
index 4d54e1e62d2..484c3aba5cb 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
@@ -199,8 +199,8 @@ int ieee80211_encrypt_fragment(
header = (struct rtl_ieee80211_hdr *)frag->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "TX packet to " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(header->addr1));
+ "TX packet to %pM\n",
+ ieee->dev->name, header->addr1);
}
return -1;
}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
index 85c7e96b622..727cc552c5e 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
@@ -31,6 +31,7 @@
******************************************************************************/
#include <linux/wireless.h>
#include <linux/kmod.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include "ieee80211.h"
@@ -261,10 +262,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
else
IEEE80211_DEBUG_SCAN(
"Not showing network '%s ("
- MAC_FMT ")' due to age (%lums).\n",
+ "%pM)' due to age (%lums).\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid),
+ network->bssid,
(jiffies - network->last_scanned) / (HZ / 100));
}
@@ -731,7 +732,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
#if 1
case IW_AUTH_WPA_ENABLED:
ieee->wpa_enabled = (data->value)?1:0;
- //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
+ //printk("enable wpa:%d\n", ieee->wpa_enabled);
break;
#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
index c6962450e06..8c37dd124fc 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
u16 tmp = 0;
u16 len = ieee->tx_headroom + 9;
//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+ IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
if (pBA == NULL||ieee == NULL)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -200,7 +200,7 @@ static struct sk_buff* ieee80211_DELBA(
u16 len = 6 + ieee->tx_headroom;
if (net_ratelimit())
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+ IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
memset(&DelbaParamSet, 0, 2);
@@ -339,7 +339,10 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
{
- IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
+ IEEE80211_DEBUG(IEEE80211_DL_ERR,
+ " Invalid skb len in BAREQ(%d / %zd)\n",
+ skb->len,
+ sizeof(struct ieee80211_hdr_3addr) + 9);
return -1;
}
@@ -354,7 +357,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
pBaTimeoutVal = (u16*)(tag + 5);
pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
- printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
+ printk("====================>rx ADDBAREQ from :%pM\n", dst);
//some other capability is not ready now.
if( (ieee->current_network.qos_data.active == 0) ||
(ieee->pHTInfo->bCurrentHTSupport == false) ||
@@ -440,7 +443,10 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
{
- IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
+ IEEE80211_DEBUG(IEEE80211_DL_ERR,
+ " Invalid skb len in BARSP(%d / %zd)\n",
+ skb->len,
+ sizeof(struct ieee80211_hdr_3addr) + 9);
return -1;
}
rsp = ( struct ieee80211_hdr_3addr*)skb->data;
@@ -570,7 +576,10 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
{
- IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6));
+ IEEE80211_DEBUG(IEEE80211_DL_ERR,
+ " Invalid skb len in DELBA(%d / %zd)\n",
+ skb->len,
+ sizeof(struct ieee80211_hdr_3addr) + 6);
return -1;
}
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
index 33c7fa7edc8..01114c5181b 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
@@ -42,7 +42,7 @@ static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
-// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
// code in other place??
//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
/********************************************************************************************************************
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
index ad3bf35d80e..38468c53967 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
@@ -1,5 +1,6 @@
#include "ieee80211.h"
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include "rtl819x_TS.h"
void TsSetupTimeOut(unsigned long data)
@@ -291,7 +292,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8
if(search_dir[dir] ==false )
continue;
list_for_each_entry(pRet, psearch_list, List){
- // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+ // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
if (memcmp(pRet->Addr, Addr, 6) == 0)
if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -447,7 +448,7 @@ bool GetTs(
ResetRxTsEntry(tmp);
}
- IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+ IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
// Prepare TS Info releated field
pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field
pTSInfo->field.ucTSID = UP; // TSID
@@ -533,7 +534,7 @@ void RemoveTsEntry(
void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
{
PTS_COMMON_INFO pTS, pTmpTS;
- printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+ printk("===========>RemovePeerTS,%pM\n", Addr);
#if 1
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
{
diff --git a/drivers/staging/rtl8192su/r8192SU_HWImg.c b/drivers/staging/rtl8192su/r8192SU_HWImg.c
index cbb65795a30..ba8e12c209c 100644
--- a/drivers/staging/rtl8192su/r8192SU_HWImg.c
+++ b/drivers/staging/rtl8192su/r8192SU_HWImg.c
@@ -2,4282 +2,6 @@
#include "r8192SU_HWImg.h"
-u8 Rtl8192SUFwImgArray[ImgArrayLength] = {
-0x92,0x81,0x2b,0x90,0x30,0x00,0x00,0x00,0x08,0x74,0x00,0x00,0x88,0x96,0x00,0x00,
-0x30,0x00,0x00,0x00,0x00,0x95,0x00,0x00,0x00,0x00,0x2b,0x00,0x03,0x03,0x23,0x00,
-0x92,0x81,0x02,0x01,0x00,0x00,0x12,0x04,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x00,
-0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x7f,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x1f,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x25,0xb0,0x1a,0x3c,0x80,0x03,0x5a,0x37,0x00,0x80,0x1b,0x3c,0x80,0x00,0x7b,0x37,
-0x00,0x00,0x5b,0xaf,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x37,0x00,0x80,0x1b,0x3c,
-0x80,0x00,0x7b,0x37,0x00,0x00,0x5b,0xaf,0x00,0x80,0x1a,0x3c,0x10,0x6d,0x5a,0x27,
-0x08,0x00,0x40,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x04,0x00,0xa1,0xaf,0x08,0x00,0xa2,0xaf,0x0c,0x00,0xa3,0xaf,0x10,0x00,0xa4,0xaf,
-0x14,0x00,0xa5,0xaf,0x18,0x00,0xa6,0xaf,0x1c,0x00,0xa7,0xaf,0x20,0x00,0xa8,0xaf,
-0x24,0x00,0xa9,0xaf,0x28,0x00,0xaa,0xaf,0x2c,0x00,0xab,0xaf,0x30,0x00,0xac,0xaf,
-0x34,0x00,0xad,0xaf,0x38,0x00,0xae,0xaf,0x3c,0x00,0xaf,0xaf,0x12,0x40,0x00,0x00,
-0x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0xb0,0xaf,0x44,0x00,0xb1,0xaf,
-0x48,0x00,0xb2,0xaf,0x4c,0x00,0xb3,0xaf,0x50,0x00,0xb4,0xaf,0x54,0x00,0xb5,0xaf,
-0x58,0x00,0xb6,0xaf,0x5c,0x00,0xb7,0xaf,0x60,0x00,0xb8,0xaf,0x64,0x00,0xb9,0xaf,
-0x68,0x00,0xbc,0xaf,0x6c,0x00,0xbd,0xaf,0x70,0x00,0xbe,0xaf,0x74,0x00,0xbf,0xaf,
-0x78,0x00,0xa8,0xaf,0x7c,0x00,0xa9,0xaf,0x80,0x00,0xaa,0xaf,0xdf,0x1a,0x00,0x08,
-0x21,0x20,0xa0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x25,0xb0,0x06,0x3c,0x00,0x80,0x02,0x3c,0xe8,0xff,0xbd,0x27,0x18,0x03,0xc3,0x34,
-0x00,0x03,0x42,0x24,0x14,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x62,0xac,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x42,0xb0,0x03,0x3c,
-0x03,0x00,0x63,0x34,0x00,0x00,0x62,0x90,0x02,0x80,0x0a,0x3c,0x02,0x80,0x10,0x3c,
-0xff,0x00,0x42,0x30,0x00,0x46,0x02,0x00,0x10,0x00,0x42,0x30,0x13,0x00,0x40,0x10,
-0x03,0x46,0x08,0x00,0xc4,0x7d,0x42,0x8d,0x68,0x15,0x05,0x26,0xd4,0x63,0xa4,0x94,
-0x01,0x00,0x47,0x24,0x10,0x00,0x02,0x24,0xb0,0x03,0xc9,0x34,0x00,0x00,0x62,0xa0,
-0x07,0x00,0x80,0x10,0x1c,0x03,0xc6,0x34,0xd8,0x63,0xa2,0x8c,0xd4,0x63,0xa0,0xa4,
-0xd8,0x63,0xa0,0xac,0x00,0x00,0x04,0x24,0x00,0x00,0xc2,0xac,0x00,0x00,0x20,0xad,
-0x01,0x00,0x82,0x24,0xc4,0x7d,0x47,0xad,0xd4,0x63,0xa2,0xa4,0x12,0x00,0x00,0x05,
-0x42,0xb0,0x02,0x3c,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0x68,0x15,0x04,0x26,0x0c,0x4b,0x83,0x94,0x08,0x4b,0x85,0x94,
-0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x80,0x00,0x63,0x30,0x41,0xb0,0x02,0x3c,
-0x25,0x18,0x65,0x00,0x08,0x00,0x42,0x34,0x18,0x00,0xbd,0x27,0x00,0x00,0x43,0xa4,
-0x08,0x00,0xe0,0x03,0x08,0x4b,0x83,0xa4,0x80,0xff,0x03,0x24,0x03,0x00,0x42,0x34,
-0x00,0x00,0x43,0xa0,0xc8,0x0e,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0x04,0x26,
-0x0c,0x4b,0x83,0x94,0x08,0x4b,0x85,0x94,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,
-0x80,0x00,0x63,0x30,0x41,0xb0,0x02,0x3c,0x25,0x18,0x65,0x00,0x08,0x00,0x42,0x34,
-0x18,0x00,0xbd,0x27,0x00,0x00,0x43,0xa4,0x08,0x00,0xe0,0x03,0x08,0x4b,0x83,0xa4,
-0xff,0x00,0x84,0x30,0x0b,0x00,0x82,0x2c,0xff,0xff,0xe7,0x30,0x10,0x00,0xa8,0x93,
-0x19,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0x02,0x80,0x03,0x3c,0x80,0x10,0x04,0x00,
-0xc0,0x91,0x63,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0x00,0x00,0x00,0x00,
-0x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x43,0xb0,0x02,0x3c,0x78,0x00,0x44,0x34,
-0x07,0x00,0xe2,0x30,0x00,0x00,0x85,0xac,0x04,0x00,0x86,0xac,0x04,0x00,0x40,0x18,
-0x00,0x00,0x00,0x00,0xf8,0xff,0xe2,0x30,0x08,0x00,0x42,0x24,0xff,0xff,0x47,0x30,
-0x21,0x10,0xe8,0x00,0x00,0x80,0x03,0x3c,0x08,0x00,0x82,0xac,0x25,0x10,0x43,0x00,
-0x08,0x00,0x82,0xac,0x01,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
-0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x6c,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,
-0x20,0x01,0x00,0x08,0x60,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,
-0x54,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x48,0x00,0x44,0x34,
-0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x3c,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,
-0x20,0x01,0x00,0x08,0x30,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,
-0x24,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x18,0x00,0x44,0x34,
-0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x0c,0x00,0x44,0x34,0x20,0x01,0x00,0x08,
-0x43,0xb0,0x04,0x3c,0x01,0x00,0x02,0x24,0x25,0xb0,0x03,0x3c,0x04,0x20,0x82,0x00,
-0x18,0x03,0x67,0x34,0x00,0x80,0x02,0x3c,0x43,0xb0,0x03,0x3c,0x34,0x05,0x46,0x24,
-0x88,0x00,0x65,0x34,0x21,0x10,0x00,0x00,0x01,0x00,0x42,0x24,0xff,0xff,0x42,0x30,
-0x05,0x00,0x43,0x2c,0xfd,0xff,0x60,0x14,0x01,0x00,0x42,0x24,0x00,0x00,0xe6,0xac,
-0x00,0x00,0xa2,0x94,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x30,0x24,0x10,0x44,0x00,
-0xf4,0xff,0x40,0x1c,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x25,0xb0,0x08,0x3c,0x00,0x80,0x02,0x3c,0xc8,0xff,0xbd,0x27,0x18,0x03,0x03,0x35,
-0x90,0x05,0x42,0x24,0x00,0x00,0x62,0xac,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,
-0x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf,
-0x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf,0x0c,0x00,0xf2,0x84,0x08,0x00,0xf5,0x8c,
-0xff,0x00,0xc6,0x30,0x00,0x01,0x02,0x24,0x23,0x10,0x46,0x00,0xff,0xff,0x51,0x30,
-0xd0,0x03,0x08,0x35,0xff,0x00,0x96,0x30,0x00,0x00,0x12,0xad,0x21,0xa0,0xa0,0x00,
-0x21,0x30,0xc5,0x00,0x00,0x00,0x15,0xad,0x21,0x20,0xc0,0x02,0x21,0x28,0xa0,0x02,
-0x21,0x38,0x20,0x02,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x23,0x18,0x51,0x02,
-0xff,0xff,0x82,0x32,0x00,0x94,0x03,0x00,0x03,0x94,0x12,0x00,0xa6,0x01,0x00,0x08,
-0x02,0x9a,0x02,0x00,0x28,0xb0,0x03,0x3c,0xc0,0x10,0x13,0x00,0x21,0x10,0x43,0x00,
-0x00,0x00,0x44,0x90,0x25,0xb0,0x10,0x3c,0x20,0x10,0x02,0x3c,0xff,0x00,0x93,0x30,
-0x00,0x22,0x13,0x00,0xff,0xff,0x43,0x32,0x01,0x01,0x45,0x2a,0x21,0xa0,0x82,0x00,
-0x21,0xa8,0xb1,0x02,0xd0,0x03,0x02,0x36,0x00,0x01,0x11,0x24,0x0b,0x88,0x65,0x00,
-0x21,0x20,0xc0,0x02,0x00,0x00,0x53,0xac,0x4d,0x01,0x00,0x0c,0xb0,0x03,0x10,0x36,
-0x21,0x30,0x80,0x02,0x21,0x20,0xc0,0x02,0x21,0x28,0xa0,0x02,0x21,0x38,0x20,0x02,
-0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x23,0x18,0x51,0x02,0x00,0x94,0x03,0x00,
-0x03,0x94,0x12,0x00,0x00,0x00,0x12,0xae,0xe2,0xff,0x40,0x1e,0x00,0x00,0x00,0x00,
-0x34,0x00,0xbf,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,
-0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
-0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0xc8,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,
-0x25,0xb0,0x04,0x3c,0x20,0x00,0xb2,0xaf,0x68,0x15,0x52,0x24,0x00,0x80,0x02,0x3c,
-0x18,0x03,0x83,0x34,0xc8,0x06,0x42,0x24,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,
-0x30,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
-0x00,0x00,0x62,0xac,0xb0,0x03,0x93,0x34,0x21,0xa0,0x40,0x02,0x54,0x64,0x42,0x8e,
-0xc0,0x64,0x50,0x8e,0x21,0x20,0x00,0x00,0x00,0x00,0x62,0xae,0x58,0x64,0x42,0xae,
-0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x64,0x44,0x8e,
-0xc4,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,
-0x0a,0x18,0x82,0x00,0xc0,0x64,0x43,0xae,0xc0,0x64,0x85,0x8e,0x00,0x00,0x00,0x00,
-0x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,
-0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0xff,0x00,0x15,0x24,0x21,0x20,0x00,0x00,
-0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24,
-0x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00,0x05,0x00,0x35,0x12,0x21,0x30,0x60,0x00,
-0x08,0x64,0x91,0xa2,0x54,0x64,0x83,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
-0x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e,0xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34,
-0x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00,0x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c,
-0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c,
-0x25,0x18,0x64,0x00,0xc0,0xff,0x02,0x24,0x24,0x18,0x62,0x00,0x08,0x00,0x03,0xae,
-0xc9,0x64,0x84,0x92,0x2a,0xb0,0x02,0x3c,0x01,0x00,0x03,0x24,0x01,0x00,0x84,0x24,
-0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc4,0xff,0x35,0x16,0xc9,0x64,0x84,0xa2,
-0xfc,0x4a,0x82,0x8e,0x41,0xb0,0x03,0x3c,0x30,0x00,0xbf,0x8f,0x00,0x38,0x42,0x34,
-0x00,0x00,0x62,0xac,0x2c,0x00,0xb5,0x8f,0xfc,0x4a,0x82,0xae,0x24,0x00,0xb3,0x8f,
-0x28,0x00,0xb4,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
-0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c,
-0xc8,0xff,0xbd,0x27,0x18,0x03,0x83,0x34,0x38,0x08,0x42,0x24,0x34,0x00,0xbf,0xaf,
-0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,
-0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x00,0x00,0x62,0xac,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,
-0x68,0x15,0xd2,0x26,0xb0,0x03,0x93,0x34,0x2d,0x02,0x00,0x08,0x21,0xa8,0x40,0x02,
-0x2a,0xb0,0x02,0x3c,0x08,0x00,0x04,0xae,0x09,0x00,0x42,0x34,0x01,0x00,0x03,0x24,
-0x02,0x00,0x04,0x24,0x00,0x00,0x43,0xa0,0x00,0x00,0x44,0xa0,0x42,0x00,0x34,0x12,
-0x00,0x00,0x00,0x00,0x6c,0x64,0x42,0x8e,0xd8,0x64,0x50,0x8e,0x01,0x00,0x04,0x24,
-0x00,0x00,0x62,0xae,0x70,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,
-0x00,0x00,0x00,0x00,0xd8,0x64,0x44,0x8e,0xdc,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,
-0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xd8,0x64,0x43,0xae,
-0xd8,0x64,0xa5,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c,
-0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,
-0xff,0x00,0x14,0x24,0x01,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,
-0x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24,0x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00,
-0x05,0x00,0x34,0x12,0x21,0x30,0x60,0x00,0x6c,0x64,0xa3,0xae,0x10,0x64,0xb1,0xa2,
-0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e,
-0xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34,0x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00,
-0x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c,0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,
-0x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c,0x25,0x18,0x64,0x00,0xc0,0xff,0x05,0x24,
-0x82,0x11,0x03,0x00,0x24,0x20,0x65,0x00,0x01,0x00,0x42,0x30,0xc0,0xff,0x40,0x10,
-0x04,0x00,0x84,0x34,0x2a,0xb0,0x02,0x3c,0x08,0x00,0x03,0xae,0x09,0x00,0x42,0x34,
-0x01,0x00,0x03,0x24,0x02,0x00,0x04,0x24,0x00,0x00,0x43,0xa0,0x00,0x00,0x44,0xa0,
-0xc0,0xff,0x34,0x16,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc2,0x26,0xfc,0x4a,0x43,0x8c,
-0x34,0x00,0xbf,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,
-0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
-0x00,0x38,0x63,0x34,0x41,0xb0,0x04,0x3c,0x38,0x00,0xbd,0x27,0x00,0x00,0x83,0xac,
-0x08,0x00,0xe0,0x03,0xfc,0x4a,0x43,0xac,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c,
-0xc0,0xff,0xbd,0x27,0x18,0x03,0x83,0x34,0x08,0x0a,0x42,0x24,0x38,0x00,0xbf,0xaf,
-0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf,
-0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
-0x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x02,0x80,0x17,0x3c,0x68,0x15,0xf2,0x26,0xb0,0x03,0x93,0x34,0x02,0x80,0x14,0x3c,
-0xab,0x02,0x00,0x08,0x21,0xb0,0x40,0x02,0x2a,0xb0,0x03,0x3c,0x08,0x00,0x04,0xae,
-0x05,0x00,0x63,0x34,0x01,0x00,0x02,0x24,0x02,0x00,0x04,0x24,0x00,0x00,0x62,0xa0,
-0x00,0x00,0x64,0xa0,0xca,0x7d,0x82,0x96,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,
-0xca,0x7d,0x82,0xa6,0xca,0x7d,0x83,0x96,0x25,0xb0,0x02,0x3c,0x66,0x03,0x42,0x34,
-0x00,0x00,0x43,0xa4,0x4a,0x00,0x35,0x12,0x00,0x00,0x00,0x00,0x60,0x64,0x42,0x8e,
-0xcc,0x64,0x50,0x8e,0x01,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x64,0x64,0x42,0xae,
-0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0xcc,0x64,0x44,0x8e,
-0xd0,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,
-0x0a,0x18,0x82,0x00,0xcc,0x64,0x43,0xae,0xcc,0x64,0xc5,0x8e,0x00,0x00,0x00,0x00,
-0x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,
-0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0xff,0x00,0x15,0x24,0x01,0x00,0x04,0x24,
-0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24,
-0x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00,0x05,0x00,0x35,0x12,0x21,0x30,0x60,0x00,
-0x60,0x64,0xc3,0xae,0x0c,0x64,0xd1,0xa2,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
-0x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e,0xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34,
-0x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00,0x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c,
-0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c,
-0x25,0x18,0x64,0x00,0xc0,0xff,0x05,0x24,0x82,0x11,0x03,0x00,0x24,0x20,0x65,0x00,
-0x01,0x00,0x42,0x30,0xb8,0xff,0x40,0x10,0x04,0x00,0x84,0x34,0x08,0x00,0x03,0xae,
-0x2a,0xb0,0x03,0x3c,0x05,0x00,0x63,0x34,0x01,0x00,0x02,0x24,0x02,0x00,0x04,0x24,
-0x00,0x00,0x62,0xa0,0x00,0x00,0x64,0xa0,0xca,0x7d,0x82,0x96,0x00,0x00,0x00,0x00,
-0x01,0x00,0x42,0x24,0xca,0x7d,0x82,0xa6,0xca,0x7d,0x83,0x96,0x25,0xb0,0x02,0x3c,
-0x66,0x03,0x42,0x34,0x00,0x00,0x43,0xa4,0xb8,0xff,0x35,0x16,0x00,0x00,0x00,0x00,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x68,0x15,0xe2,0x26,0xfc,0x4a,0x43,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
-0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x38,0x63,0x34,
-0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x83,0xac,0x08,0x00,0xe0,0x03,
-0xfc,0x4a,0x43,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,0x38,0x00,0xbf,0xaf,
-0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,
-0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x02,0x80,0x06,0x3c,
-0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x18,0x03,0x42,0x34,
-0x24,0x0c,0x63,0x24,0x40,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,0x21,0xa8,0x00,0x00,
-0x03,0x00,0x80,0x10,0x7f,0x00,0xa2,0x30,0xbf,0x00,0xa2,0x30,0x01,0x00,0x15,0x24,
-0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc2,0x90,0x25,0xb0,0x04,0x3c,0x88,0x02,0x83,0x34,
-0x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0xb0,0x03,0x93,0x34,0x02,0x80,0x14,0x3c,
-0x43,0x03,0x00,0x08,0x21,0xb8,0x40,0x02,0x24,0x10,0xa2,0x00,0x04,0x00,0x42,0x34,
-0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x0d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,
-0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0,
-0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,
-0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,
-0x00,0x00,0xa2,0xa4,0x5a,0x00,0x23,0x12,0x00,0x00,0x00,0x00,0x24,0x64,0x42,0x8e,
-0x90,0x64,0x50,0x8e,0x03,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x28,0x64,0x42,0xae,
-0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x90,0x64,0x44,0x8e,
-0x94,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,
-0x0a,0x18,0x82,0x00,0x90,0x64,0x43,0xae,0x90,0x64,0xe2,0x8e,0x00,0x00,0x00,0x00,
-0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,
-0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,
-0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12,0x00,0x12,0x11,0x00,
-0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x5a,0x00,0xa0,0x12,0x24,0x64,0xe2,0xae,
-0xec,0x63,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x24,0x64,0x46,0x8c,0x90,0x64,0x45,0x8c,
-0x03,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
-0x04,0x00,0x04,0x8e,0x14,0x00,0x03,0x8e,0x08,0x00,0x05,0x8e,0xff,0xe0,0x02,0x3c,
-0x1f,0x00,0x84,0x30,0x42,0x1a,0x03,0x00,0xff,0xff,0x42,0x34,0x00,0x26,0x04,0x00,
-0x24,0x28,0xa2,0x00,0x3f,0x00,0x63,0x30,0x25,0x28,0xa4,0x00,0x0c,0x00,0x63,0x28,
-0x06,0x00,0x60,0x14,0x21,0x20,0xa0,0x00,0x00,0x00,0x02,0x96,0x00,0x00,0x00,0x00,
-0xfd,0x0f,0x42,0x28,0x08,0x00,0x40,0x14,0x82,0x11,0x05,0x00,0xff,0xdf,0x02,0x3c,
-0xff,0xff,0x42,0x34,0x24,0x28,0x82,0x00,0x00,0x40,0x03,0x3c,0x25,0x20,0xa3,0x00,
-0x21,0x28,0x80,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30,0xa6,0xff,0x40,0x10,
-0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,0x0d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,
-0x08,0x00,0x04,0xae,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,
-0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,
-0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,
-0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0xa8,0xff,0x23,0x16,0x00,0x00,0x00,0x00,
-0x22,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,0xec,0x63,0x43,0x90,0x41,0x00,0xe4,0x34,
-0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa4,0x8c,
-0x01,0x00,0x02,0x3c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f,
-0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,
-0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x80,0x42,0x34,0x25,0x20,0x82,0x00,
-0x41,0xb0,0x03,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x64,0xac,0x08,0x00,0xe0,0x03,
-0xfc,0x4a,0xa4,0xac,0x65,0x03,0x00,0x08,0xe8,0x63,0xf1,0xa2,0xe8,0x63,0x43,0x90,
-0x40,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0xa3,0xac,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc5,0x26,
-0xfc,0x4a,0xa4,0x8c,0x01,0x00,0x02,0x3c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
-0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x80,0x42,0x34,
-0x25,0x20,0x82,0x00,0x41,0xb0,0x03,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x64,0xac,
-0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa4,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,
-0x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,
-0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
-0x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
-0x18,0x03,0x42,0x34,0x78,0x0f,0x63,0x24,0x10,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,
-0x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xdf,0x00,0xa2,0x30,0xef,0x00,0xa2,0x30,
-0x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c,
-0xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,
-0x21,0x98,0x40,0x00,0x02,0x80,0x14,0x3c,0x19,0x04,0x00,0x08,0x21,0xb8,0x40,0x02,
-0x24,0x10,0xa2,0x00,0x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,
-0x15,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,
-0x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,
-0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,
-0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x5a,0x00,0x23,0x12,
-0x00,0x00,0x00,0x00,0x30,0x64,0x42,0x8e,0x9c,0x64,0x50,0x8e,0x04,0x00,0x04,0x24,
-0x00,0x00,0x62,0xae,0x34,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x9c,0x64,0x44,0x8e,0xa0,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,
-0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0x9c,0x64,0x43,0xae,
-0x9c,0x64,0xe2,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,
-0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,
-0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,
-0x0d,0x00,0x22,0x12,0x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,
-0x59,0x00,0xa0,0x12,0x30,0x64,0xe2,0xae,0xf4,0x63,0xf1,0xa2,0x68,0x15,0xc2,0x26,
-0x30,0x64,0x46,0x8c,0x9c,0x64,0x45,0x8c,0x04,0x00,0x04,0x24,0x20,0x00,0x07,0x24,
-0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x04,0x00,0x04,0x8e,0x14,0x00,0x03,0x8e,
-0x08,0x00,0x05,0x8e,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x42,0x1a,0x03,0x00,
-0xff,0xff,0x42,0x34,0x00,0x26,0x04,0x00,0x24,0x28,0xa2,0x00,0x3f,0x00,0x63,0x30,
-0x25,0x28,0xa4,0x00,0x0c,0x00,0x63,0x28,0x06,0x00,0x60,0x14,0x21,0x20,0xa0,0x00,
-0x00,0x00,0x02,0x96,0x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x08,0x00,0x40,0x14,
-0x82,0x11,0x05,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34,0x24,0x28,0x82,0x00,
-0x00,0x40,0x03,0x3c,0x25,0x20,0xa3,0x00,0x21,0x28,0x80,0x00,0x82,0x11,0x05,0x00,
-0x01,0x00,0x42,0x30,0xa6,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,
-0x15,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x08,0x00,0x04,0xae,0x0b,0x10,0x75,0x00,
-0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,
-0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,
-0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,
-0xa8,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,
-0xf4,0x63,0x43,0x90,0x43,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
-0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
-0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x06,0x00,0x03,0x3c,
-0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
-0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x3b,0x04,0x00,0x08,0xf0,0x63,0xf1,0xa2,
-0xf0,0x63,0x43,0x90,0x42,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
-0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
-0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x06,0x00,0x03,0x3c,
-0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
-0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,
-0x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,
-0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
-0x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
-0x18,0x03,0x42,0x34,0xc8,0x12,0x63,0x24,0x01,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,
-0x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xf7,0x00,0xa2,0x30,0xfe,0x00,0xa2,0x30,
-0x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c,
-0xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0x21,0x98,0x40,0x00,
-0x02,0x80,0x14,0x3c,0xf8,0x04,0x00,0x08,0x21,0xb8,0x40,0x02,0x00,0x00,0x02,0x96,
-0x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x54,0x00,0x40,0x10,0xff,0xdf,0x02,0x3c,
-0x00,0x20,0x02,0x3c,0x25,0x28,0xa2,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30,
-0x57,0x00,0x40,0x14,0x2a,0xb0,0x07,0x3c,0xc0,0xff,0x02,0x24,0x24,0x10,0xa2,0x00,
-0x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x1d,0x00,0xe2,0x34,
-0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,
-0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,
-0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,
-0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x53,0x00,0x23,0x12,0x00,0x00,0x00,0x00,
-0x3c,0x64,0x42,0x8e,0xa8,0x64,0x50,0x8e,0x05,0x00,0x04,0x24,0x00,0x00,0x62,0xae,
-0x40,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,
-0xa8,0x64,0x44,0x8e,0xac,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,
-0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xa8,0x64,0x43,0xae,0xa8,0x64,0xe2,0x8e,
-0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,
-0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00,
-0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12,
-0x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x52,0x00,0xa0,0x12,
-0x3c,0x64,0xe2,0xae,0x04,0x64,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x3c,0x64,0x46,0x8c,
-0xa8,0x64,0x45,0x8c,0x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,
-0x10,0x00,0xa0,0xaf,0x14,0x00,0x03,0x8e,0x04,0x00,0x04,0x8e,0x08,0x00,0x05,0x8e,
-0x42,0x1a,0x03,0x00,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x3f,0x00,0x63,0x30,
-0xff,0xff,0x42,0x34,0x24,0x28,0xa2,0x00,0x00,0x26,0x04,0x00,0x0c,0x00,0x63,0x28,
-0xaa,0xff,0x60,0x10,0x25,0x28,0xa4,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34,
-0x24,0x10,0xa2,0x00,0x00,0x40,0x03,0x3c,0x25,0x28,0x43,0x00,0x82,0x11,0x05,0x00,
-0x01,0x00,0x42,0x30,0xad,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,
-0x1d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,
-0x02,0x00,0x03,0x24,0x08,0x00,0x05,0xae,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,
-0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,
-0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,
-0xaf,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,
-0x04,0x64,0x43,0x90,0x45,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
-0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
-0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x18,0x00,0x03,0x3c,
-0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
-0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x1a,0x05,0x00,0x08,0xf8,0x63,0xf1,0xa2,
-0xf8,0x63,0x43,0x90,0x44,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
-0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
-0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x18,0x00,0x03,0x3c,
-0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
-0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,
-0x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,
-0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
-0x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
-0x18,0x03,0x42,0x34,0x28,0x16,0x63,0x24,0x02,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,
-0x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xfb,0x00,0xa2,0x30,0xfd,0x00,0xa2,0x30,
-0x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c,
-0xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0x21,0x98,0x40,0x00,
-0x02,0x80,0x14,0x3c,0xd0,0x05,0x00,0x08,0x21,0xb8,0x40,0x02,0x00,0x00,0x02,0x96,
-0x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x54,0x00,0x40,0x10,0xff,0xdf,0x02,0x3c,
-0x00,0x20,0x02,0x3c,0x25,0x28,0xa2,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30,
-0x57,0x00,0x40,0x14,0x2a,0xb0,0x07,0x3c,0xc0,0xff,0x02,0x24,0x24,0x10,0xa2,0x00,
-0x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x25,0x00,0xe2,0x34,
-0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,
-0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,
-0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,
-0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x53,0x00,0x23,0x12,0x00,0x00,0x00,0x00,
-0x48,0x64,0x42,0x8e,0xb4,0x64,0x50,0x8e,0x06,0x00,0x04,0x24,0x00,0x00,0x62,0xae,
-0x4c,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,
-0xb4,0x64,0x44,0x8e,0xb8,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,
-0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xb4,0x64,0x43,0xae,0xb4,0x64,0xe2,0x8e,
-0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,
-0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00,
-0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12,
-0x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x52,0x00,0xa0,0x12,
-0x48,0x64,0xe2,0xae,0x00,0x64,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x48,0x64,0x46,0x8c,
-0xb4,0x64,0x45,0x8c,0x06,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,
-0x10,0x00,0xa0,0xaf,0x14,0x00,0x03,0x8e,0x04,0x00,0x04,0x8e,0x08,0x00,0x05,0x8e,
-0x42,0x1a,0x03,0x00,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x3f,0x00,0x63,0x30,
-0xff,0xff,0x42,0x34,0x24,0x28,0xa2,0x00,0x00,0x26,0x04,0x00,0x0c,0x00,0x63,0x28,
-0xaa,0xff,0x60,0x10,0x25,0x28,0xa4,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34,
-0x24,0x10,0xa2,0x00,0x00,0x40,0x03,0x3c,0x25,0x28,0x43,0x00,0x82,0x11,0x05,0x00,
-0x01,0x00,0x42,0x30,0xad,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,
-0x25,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,
-0x02,0x00,0x03,0x24,0x08,0x00,0x05,0xae,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,
-0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,
-0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,
-0xaf,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,
-0x00,0x64,0x43,0x90,0x47,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
-0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
-0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x60,0x00,0x03,0x3c,
-0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
-0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xf2,0x05,0x00,0x08,0xfc,0x63,0xf1,0xa2,
-0xfc,0x63,0x43,0x90,0x46,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
-0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
-0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x60,0x00,0x03,0x3c,
-0x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
-0x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
-0x88,0x19,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x05,0x3c,0x68,0x15,0xa5,0x24,
-0x04,0x4b,0xa2,0x8c,0xfc,0x4a,0xa4,0x8c,0x00,0x08,0x03,0x3c,0x24,0x10,0x43,0x00,
-0x25,0x20,0x82,0x00,0x41,0xb0,0x03,0x3c,0x00,0x00,0x64,0xac,0x08,0x00,0xe0,0x03,
-0xfc,0x4a,0xa4,0xac,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c,0xc0,0xff,0xbd,0x27,
-0x18,0x03,0x83,0x34,0xe4,0x19,0x42,0x24,0x3c,0x00,0xbf,0xaf,0x38,0x00,0xbe,0xaf,
-0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf,
-0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
-0x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x02,0x80,0x02,0x3c,0x2a,0xb0,0x03,0x3c,0x68,0x15,0x51,0x24,0xb0,0x03,0x93,0x34,
-0x2c,0x00,0x77,0x34,0x02,0x80,0x15,0x3c,0x02,0x80,0x16,0x3c,0x9c,0x06,0x00,0x08,
-0x02,0x80,0x1e,0x3c,0x14,0x64,0x26,0x92,0xe4,0x64,0x25,0x8e,0x00,0x32,0x06,0x00,
-0x21,0x30,0xc2,0x00,0x78,0x64,0x26,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
-0xe4,0x64,0x30,0x8e,0x0a,0x00,0x04,0x24,0x21,0x90,0x00,0x00,0x00,0x00,0x70,0xae,
-0x4d,0x01,0x00,0x0c,0xff,0xff,0x10,0x32,0x02,0x80,0x02,0x3c,0x25,0x80,0x02,0x02,
-0x0c,0x00,0x05,0x92,0x02,0x00,0x04,0x92,0xff,0x00,0x02,0x24,0xff,0x00,0xa3,0x30,
-0x04,0x00,0x62,0x10,0x21,0x80,0x04,0x02,0x00,0x00,0x63,0xae,0x01,0x00,0x12,0x24,
-0x14,0x64,0x25,0xa2,0x88,0x96,0xb0,0xae,0x21,0x28,0x00,0x02,0x02,0x00,0xa2,0x90,
-0x08,0x00,0x10,0x26,0x21,0x20,0x00,0x02,0xff,0x00,0x42,0x30,0x00,0x00,0x62,0xae,
-0x03,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x63,0xae,
-0x00,0x00,0x72,0xae,0x03,0x00,0xa2,0x90,0x84,0x96,0xc3,0x92,0x02,0x00,0xa2,0x90,
-0x00,0x00,0x00,0x00,0xff,0x00,0x42,0x30,0x2c,0x00,0x42,0x28,0x11,0x00,0x40,0x10,
-0x08,0x00,0x02,0x24,0x03,0x00,0xa2,0x90,0x00,0x00,0x00,0x00,0x7f,0x00,0x42,0x30,
-0x84,0x96,0xc2,0xa2,0x02,0x00,0xa3,0x90,0x02,0x80,0x02,0x3c,0x74,0x84,0x42,0x24,
-0xff,0x00,0x63,0x30,0xc0,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x04,0x00,0x62,0x8c,
-0x00,0x00,0x00,0x00,0x09,0xf8,0x40,0x00,0x80,0x96,0xc2,0xaf,0x21,0xa0,0x40,0x00,
-0x08,0x00,0x02,0x24,0x0a,0x00,0x04,0x24,0x05,0x00,0x82,0x12,0x00,0x01,0x07,0x24,
-0x01,0x00,0x02,0x24,0x02,0x00,0x03,0x24,0x01,0x00,0xe2,0xa2,0x01,0x00,0xe3,0xa2,
-0xbc,0xff,0x40,0x16,0x20,0x10,0x02,0x3c,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0xfc,0x4a,0x22,0x8e,0x00,0x04,0x03,0x3c,
-0x41,0xb0,0x04,0x3c,0x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x3c,0x00,0xbf,0x8f,
-0xfc,0x4a,0x22,0xae,0x38,0x00,0xbe,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f,
-0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,
-0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x40,0x00,0xbd,0x27,
-0xc8,0xff,0xbd,0x27,0xff,0xff,0xa8,0x30,0x02,0x80,0x02,0x3c,0x25,0x40,0x02,0x01,
-0x30,0x00,0xb6,0xaf,0x20,0x00,0xb2,0xaf,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf,
-0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
-0x00,0x00,0x03,0x8d,0xff,0xff,0xd2,0x30,0x21,0xb0,0xa0,0x00,0x00,0xc0,0x02,0x24,
-0x08,0x00,0x45,0x26,0x04,0x00,0x06,0x8d,0x24,0x18,0x62,0x00,0xff,0x3f,0xa5,0x30,
-0xf0,0xff,0x02,0x3c,0x25,0x18,0x65,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,
-0x00,0x80,0x05,0x3c,0x25,0x18,0x65,0x00,0xff,0x01,0xc6,0x34,0x00,0x00,0x03,0xad,
-0x04,0x00,0x06,0xad,0x21,0x48,0x80,0x00,0xff,0xff,0xe7,0x30,0x18,0x00,0x12,0xa5,
-0x1a,0x00,0x07,0xa1,0x18,0x00,0x03,0x8d,0xff,0x7f,0x02,0x3c,0xff,0xff,0x42,0x34,
-0x24,0x18,0x62,0x00,0x02,0x80,0x15,0x3c,0x18,0x00,0x03,0xad,0x68,0x15,0xa5,0x26,
-0xd6,0x63,0xa3,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x62,0x24,0xd6,0x63,0xa2,0xa0,
-0x18,0x00,0x04,0x8d,0xff,0x80,0x02,0x3c,0x20,0x00,0x45,0x26,0xff,0xff,0x42,0x34,
-0x7f,0x00,0x63,0x30,0xff,0xff,0xb2,0x30,0x24,0x20,0x82,0x00,0x00,0x1e,0x03,0x00,
-0x25,0xb0,0x02,0x3c,0xc0,0x00,0x42,0x34,0x25,0x20,0x83,0x00,0x07,0x00,0x45,0x32,
-0x18,0x00,0x04,0xad,0x00,0x00,0x52,0xa4,0x03,0x00,0xa0,0x10,0xff,0xff,0x42,0x32,
-0x08,0x00,0x42,0x26,0xff,0xff,0x42,0x30,0x68,0x15,0xb4,0x26,0x54,0x65,0x86,0x8e,
-0x58,0x65,0x90,0x8e,0xf8,0xff,0x52,0x30,0x21,0x10,0xd2,0x00,0x2b,0x10,0x02,0x02,
-0x31,0x00,0x40,0x10,0xff,0x00,0x33,0x31,0x23,0x80,0x06,0x02,0x21,0x28,0xc0,0x02,
-0xff,0xff,0x07,0x32,0x01,0x00,0x11,0x24,0x21,0x20,0x60,0x02,0x10,0x01,0x00,0x0c,
-0x10,0x00,0xb1,0xaf,0x23,0x18,0x50,0x02,0xff,0xff,0x72,0x30,0x22,0x10,0x02,0x3c,
-0x21,0x10,0x42,0x02,0x21,0x20,0x60,0x02,0x4d,0x01,0x00,0x0c,0x54,0x65,0x82,0xae,
-0x21,0x28,0xd0,0x02,0x21,0x38,0x40,0x02,0x21,0x20,0x60,0x02,0x10,0x00,0xb1,0xaf,
-0x22,0x10,0x06,0x3c,0x10,0x01,0x00,0x0c,0x68,0x15,0xb1,0x26,0x54,0x65,0x23,0x8e,
-0x25,0xb0,0x10,0x3c,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02,0x00,0x00,0x43,0xac,
-0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x54,0x65,0x25,0x8e,0xec,0x00,0x02,0x36,
-0xbd,0x00,0x04,0x36,0x00,0x00,0x45,0xac,0x00,0x00,0x83,0x90,0xc2,0x00,0x10,0x36,
-0x34,0x00,0xbf,0x8f,0x10,0x00,0x63,0x34,0x00,0x00,0x83,0xa0,0x30,0x00,0xb6,0x8f,
-0x00,0x00,0x05,0xa6,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
-0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,
-0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x21,0x28,0xc0,0x02,0x21,0x20,0x60,0x02,
-0x21,0x38,0x40,0x02,0x01,0x00,0x02,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa2,0xaf,
-0x54,0x65,0x83,0x8e,0x68,0x15,0xb1,0x26,0x25,0xb0,0x10,0x3c,0x21,0x18,0x72,0x00,
-0x54,0x65,0x83,0xae,0x54,0x65,0x23,0x8e,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02,
-0x00,0x00,0x43,0xac,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x54,0x65,0x25,0x8e,
-0xec,0x00,0x02,0x36,0xbd,0x00,0x04,0x36,0x00,0x00,0x45,0xac,0x00,0x00,0x83,0x90,
-0xc2,0x00,0x10,0x36,0x34,0x00,0xbf,0x8f,0x10,0x00,0x63,0x34,0x00,0x00,0x83,0xa0,
-0x30,0x00,0xb6,0x8f,0x00,0x00,0x05,0xa6,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,
-0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
-0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,
-0x25,0xb0,0x02,0x3c,0x14,0x00,0xb1,0xaf,0x18,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,
-0xbf,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0x21,0x28,0x00,0x00,0x08,0x00,0x06,0x24,
-0x04,0x00,0x63,0x2c,0x12,0x00,0x60,0x14,0x21,0x88,0x80,0x00,0x00,0x60,0x02,0x40,
-0x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x03,0x3c,
-0x00,0x7b,0x63,0x24,0x04,0x00,0x64,0x8c,0x00,0x00,0x23,0xae,0x04,0x00,0x71,0xac,
-0x00,0x00,0x91,0xac,0x04,0x00,0x24,0xae,0x00,0x60,0x82,0x40,0x18,0x00,0xbf,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
-0x08,0x00,0x82,0x94,0x02,0x80,0x04,0x3c,0x97,0x45,0x00,0x0c,0x25,0x20,0x44,0x00,
-0x00,0x60,0x10,0x40,0x01,0x00,0x01,0x36,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x08,0x00,0x25,0x8e,0x0c,0x00,0x26,0x96,0x14,0x00,0x27,0x96,0xf0,0x06,0x00,0x0c,
-0x09,0x00,0x04,0x24,0x04,0x00,0x23,0x8e,0x00,0x00,0x22,0x8e,0x21,0x20,0x20,0x02,
-0x00,0x00,0x62,0xac,0x04,0x00,0x43,0xac,0x00,0x00,0x31,0xae,0xbd,0x4e,0x00,0x0c,
-0x04,0x00,0x31,0xae,0x00,0x60,0x90,0x40,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x02,0x80,0x02,0x3c,
-0x68,0x15,0x47,0x24,0x8c,0x64,0xe3,0x90,0xff,0xff,0xa5,0x30,0x09,0x00,0xa3,0x10,
-0x21,0x20,0xc0,0x00,0xfc,0x64,0xe2,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0xc2,0xac,
-0x06,0x65,0xe3,0x94,0x0e,0x00,0x02,0x24,0x14,0x00,0xc2,0xac,0x8b,0x07,0x00,0x08,
-0x0c,0x00,0xc3,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x3c,
-0x25,0xb0,0x02,0x3c,0xd0,0xff,0xbd,0x27,0x4c,0x1f,0x63,0x24,0x18,0x03,0x42,0x34,
-0x28,0x00,0xbf,0xaf,0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,
-0x18,0x00,0xb0,0xaf,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x00,0x60,0x81,0x40,0x2a,0xb0,0x02,0x3c,0x36,0x00,0x42,0x34,0x00,0x00,0x43,0x90,
-0x02,0x80,0x13,0x3c,0x68,0x15,0x66,0x26,0xc0,0x18,0x03,0x00,0x5c,0x65,0xc5,0x8c,
-0x23,0xb0,0x04,0x3c,0xf0,0x07,0x63,0x30,0xff,0x1f,0x02,0x3c,0x21,0x18,0x64,0x00,
-0xff,0xff,0x42,0x34,0x24,0x20,0x62,0x00,0x23,0x88,0x85,0x00,0x2b,0x38,0x85,0x00,
-0x00,0x04,0x22,0x26,0x00,0x65,0xc3,0x8c,0x0b,0x88,0x47,0x00,0x01,0x04,0x25,0x2e,
-0xfc,0x64,0xc3,0xac,0x60,0x65,0xc4,0xac,0x06,0x65,0xc0,0xa4,0x11,0x00,0xa0,0x14,
-0x05,0x65,0xc0,0xa0,0x00,0xfc,0x83,0x24,0x23,0x10,0x02,0x3c,0x0b,0x18,0x87,0x00,
-0xff,0x03,0x42,0x34,0x2b,0x10,0x43,0x00,0x33,0x00,0x40,0x14,0x00,0x00,0x00,0x00,
-0x23,0x88,0x83,0x00,0x2b,0x10,0x83,0x00,0x5c,0x65,0xc3,0xac,0x03,0x00,0x40,0x10,
-0x01,0x04,0x25,0x2e,0x00,0x04,0x31,0x26,0x01,0x04,0x25,0x2e,0x0e,0x00,0xa0,0x10,
-0x68,0x15,0x70,0x26,0x68,0x15,0x70,0x26,0x60,0x65,0x03,0x8e,0x5c,0x65,0x04,0x8e,
-0x00,0x00,0x00,0x00,0x2b,0x10,0x83,0x00,0x25,0x00,0x40,0x14,0x2b,0x10,0x64,0x00,
-0x51,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0x80,0x00,0x03,0x24,0xd0,0x03,0x42,0x34,
-0x00,0x00,0x43,0xac,0x68,0x15,0x70,0x26,0x5c,0x65,0x03,0x96,0x2a,0xb0,0x02,0x3c,
-0x35,0x00,0x42,0x34,0xc2,0x88,0x03,0x00,0x00,0x00,0x51,0xa0,0x8f,0x10,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x06,0x65,0x03,0x96,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,
-0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0xfc,0x4a,0x02,0x8e,0x80,0x00,0x03,0x3c,0x41,0xb0,0x04,0x3c,
-0x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x28,0x00,0xbf,0x8f,0xfc,0x4a,0x02,0xae,
-0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
-0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x00,0x08,0x00,0x08,0x00,0xfc,0x63,0x24,
-0xfc,0x64,0x05,0x8e,0x21,0x30,0x80,0x00,0xff,0xff,0x27,0x32,0x09,0x00,0x04,0x24,
-0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x05,0x96,
-0x5c,0x65,0x02,0x8e,0x21,0x18,0x71,0x00,0x21,0x28,0x25,0x02,0x21,0x10,0x51,0x00,
-0x09,0x00,0x04,0x24,0x5c,0x65,0x02,0xae,0xfc,0x64,0x03,0xae,0x4d,0x01,0x00,0x0c,
-0x06,0x65,0x05,0xa6,0x68,0x15,0x70,0x26,0x5c,0x65,0x03,0x96,0x2a,0xb0,0x02,0x3c,
-0x35,0x00,0x42,0x34,0xc2,0x88,0x03,0x00,0x00,0x00,0x51,0xa0,0x8f,0x10,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x06,0x65,0x03,0x96,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,
-0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0xfc,0x4a,0x02,0x8e,0x80,0x00,0x03,0x3c,0x41,0xb0,0x04,0x3c,
-0x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x28,0x00,0xbf,0x8f,0xfc,0x4a,0x02,0xae,
-0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
-0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x64,0x65,0x02,0x8e,0xfc,0x64,0x05,0x8e,
-0x21,0x30,0x80,0x00,0x23,0x88,0x44,0x00,0xff,0xff,0x27,0x32,0x09,0x00,0x04,0x24,
-0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x02,0x96,
-0x60,0x65,0x12,0x96,0x21,0x18,0x71,0x00,0x21,0x10,0x22,0x02,0x23,0x10,0x11,0x3c,
-0xfc,0x64,0x03,0xae,0x06,0x65,0x02,0xa6,0x06,0x00,0x40,0x16,0x5c,0x65,0x11,0xae,
-0x09,0x00,0x04,0x24,0x4d,0x01,0x00,0x0c,0x68,0x15,0x70,0x26,0x46,0x08,0x00,0x08,
-0x00,0x00,0x00,0x00,0x4d,0x01,0x00,0x0c,0x09,0x00,0x04,0x24,0xfc,0x64,0x05,0x8e,
-0x09,0x00,0x04,0x24,0x23,0x10,0x06,0x3c,0x21,0x38,0x40,0x02,0x10,0x01,0x00,0x0c,
-0x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x02,0x96,0x21,0x20,0x51,0x02,
-0x21,0x18,0x72,0x00,0x21,0x10,0x42,0x02,0x5c,0x65,0x04,0xae,0x09,0x00,0x04,0x24,
-0xfc,0x64,0x03,0xae,0x75,0x08,0x00,0x08,0x06,0x65,0x02,0xa6,0x02,0x80,0x09,0x3c,
-0x68,0x15,0x28,0x25,0xdc,0x63,0x06,0x8d,0xff,0xff,0x02,0x34,0x3f,0x00,0xc2,0x10,
-0x21,0x38,0x80,0x00,0x2b,0x10,0xc7,0x00,0x30,0x00,0x40,0x10,0x02,0x19,0x06,0x00,
-0x21,0x10,0xc7,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x46,0x24,0xdc,0x63,0x06,0xad,
-0x68,0x15,0x26,0x25,0x04,0x40,0xc4,0x8c,0xe0,0x63,0x02,0xad,0xff,0xff,0x02,0x34,
-0x2f,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0x2b,0x10,0x87,0x00,0x1f,0x00,0x40,0x10,
-0x02,0x19,0x04,0x00,0x21,0x10,0x87,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x44,0x24,
-0x04,0x40,0xc4,0xac,0xe0,0x63,0xc2,0xac,0xc0,0x10,0x05,0x00,0x21,0x10,0x45,0x00,
-0x80,0x10,0x02,0x00,0x21,0x10,0x45,0x00,0x68,0x15,0x23,0x25,0x80,0x10,0x02,0x00,
-0x21,0x28,0x43,0x00,0x68,0x51,0xa6,0x8c,0x00,0x21,0x07,0x00,0xff,0xff,0xc2,0x38,
-0x0a,0x30,0x82,0x00,0x2b,0x18,0xc7,0x00,0x07,0x00,0x60,0x10,0x21,0x10,0xc7,0x00,
-0x02,0x19,0x06,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x46,0x24,0x68,0x51,0xa6,0xac,
-0x08,0x00,0xe0,0x03,0x6c,0x51,0xa2,0xac,0x02,0x19,0x06,0x00,0x23,0x10,0x43,0x00,
-0x68,0x51,0xa2,0xac,0x08,0x00,0xe0,0x03,0x6c,0x51,0xa2,0xac,0x21,0x10,0x87,0x00,
-0x23,0x10,0x43,0x00,0xa5,0x08,0x00,0x08,0x04,0x40,0xc2,0xac,0x21,0x10,0xc7,0x00,
-0x68,0x15,0x26,0x25,0x04,0x40,0xc4,0x8c,0x23,0x10,0x43,0x00,0xdc,0x63,0x02,0xad,
-0xe0,0x63,0x02,0xad,0xff,0xff,0x02,0x34,0xd4,0xff,0x82,0x14,0x2b,0x10,0x87,0x00,
-0x00,0x21,0x07,0x00,0x9e,0x08,0x00,0x08,0x04,0x40,0xc4,0xac,0x00,0x31,0x04,0x00,
-0x91,0x08,0x00,0x08,0xdc,0x63,0x06,0xad,0x63,0x00,0x82,0x24,0x77,0x00,0x42,0x2c,
-0x00,0x00,0x85,0x28,0x04,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0x64,0x00,0x82,0x24,
-0x64,0x00,0x03,0x24,0x0b,0x18,0x45,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
-0x0c,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x3f,0x00,0x42,0x30,0x04,0x00,0x42,0x28,
-0x17,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x24,0x08,0x42,0x34,0x00,0x00,0x43,0x8c,
-0x00,0x00,0x00,0x00,0x00,0x02,0x63,0x30,0x16,0x00,0x60,0x14,0x01,0x00,0x02,0x24,
-0x05,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x82,0x21,0x03,0x00,0x28,0x00,0x82,0x10,
-0xf5,0xff,0x02,0x24,0x02,0x00,0x82,0x28,0x39,0x00,0x40,0x14,0x02,0x00,0x02,0x24,
-0x2e,0x00,0x82,0x10,0xe9,0xff,0x02,0x24,0x03,0x00,0x02,0x24,0x24,0x00,0x82,0x10,
-0x3e,0x00,0x63,0x30,0x05,0x00,0xc4,0x24,0xd2,0x08,0x00,0x08,0x00,0x00,0x00,0x00,
-0x04,0x00,0xa4,0x90,0x00,0x00,0x00,0x00,0x42,0x20,0x04,0x00,0xd2,0x08,0x00,0x08,
-0x96,0xff,0x84,0x24,0x05,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x60,0x00,0x64,0x30,
-0x42,0x21,0x04,0x00,0x0e,0x00,0x82,0x10,0x1f,0x00,0x62,0x30,0x02,0x00,0x82,0x28,
-0x1d,0x00,0x40,0x14,0x02,0x00,0x02,0x24,0x14,0x00,0x82,0x10,0x1f,0x00,0x62,0x30,
-0x03,0x00,0x02,0x24,0xeb,0xff,0x82,0x14,0x1f,0x00,0x62,0x30,0x40,0x10,0x02,0x00,
-0xdd,0xff,0x03,0x24,0x23,0x30,0x62,0x00,0xf6,0x08,0x00,0x08,0x05,0x00,0xc4,0x24,
-0x40,0x10,0x02,0x00,0xf5,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00,
-0x3e,0x00,0x63,0x30,0x23,0x30,0x43,0x00,0xf6,0x08,0x00,0x08,0x05,0x00,0xc4,0x24,
-0xdd,0xff,0x02,0x24,0x16,0x09,0x00,0x08,0x23,0x30,0x43,0x00,0x40,0x10,0x02,0x00,
-0xe9,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00,0x3e,0x00,0x63,0x30,
-0x16,0x09,0x00,0x08,0x23,0x30,0x43,0x00,0xd2,0xff,0x80,0x14,0x1f,0x00,0x62,0x30,
-0x40,0x10,0x02,0x00,0xf8,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00,
-0xcc,0xff,0x80,0x14,0x3e,0x00,0x63,0x30,0xf8,0xff,0x02,0x24,0x16,0x09,0x00,0x08,
-0x23,0x30,0x43,0x00,0xa0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x4c,0x00,0xb5,0xaf,
-0x5c,0x00,0xbf,0xaf,0x58,0x00,0xbe,0xaf,0x54,0x00,0xb7,0xaf,0x50,0x00,0xb6,0xaf,
-0x48,0x00,0xb4,0xaf,0x44,0x00,0xb3,0xaf,0x40,0x00,0xb2,0xaf,0x3c,0x00,0xb1,0xaf,
-0x38,0x00,0xb0,0xaf,0x68,0x15,0x55,0x24,0x25,0xb0,0x03,0x3c,0x04,0x01,0x62,0x34,
-0x00,0x00,0x43,0x8c,0x44,0x65,0xa7,0x8e,0x00,0x00,0x00,0x00,0x33,0x00,0xe3,0x10,
-0x48,0x65,0xa3,0xae,0x2b,0x10,0x67,0x00,0xa8,0x00,0x40,0x14,0x2b,0x10,0xe3,0x00,
-0xd1,0x00,0x40,0x14,0x02,0x80,0x02,0x3c,0x68,0x15,0x44,0x24,0x18,0x65,0x83,0x94,
-0x02,0x80,0x02,0x3c,0x21,0x88,0x00,0x00,0x19,0x00,0x40,0x1a,0x25,0x98,0x62,0x00,
-0x21,0xb8,0x80,0x00,0x21,0xb0,0x80,0x00,0x01,0x00,0x14,0x24,0x21,0x20,0x00,0x00,
-0x21,0x80,0x93,0x00,0x00,0x00,0x05,0x8e,0x00,0x00,0x00,0x00,0x07,0x00,0xa0,0x10,
-0x01,0x00,0x22,0x26,0x04,0x00,0x02,0x8e,0x00,0xf0,0x03,0x3c,0x00,0x20,0x04,0x3c,
-0x24,0x10,0x43,0x00,0x1e,0x00,0x44,0x10,0x06,0x00,0x22,0x26,0xff,0xff,0x51,0x30,
-0x82,0x16,0x05,0x00,0x01,0x00,0x42,0x30,0x34,0x00,0x54,0x10,0x00,0x00,0x00,0x00,
-0x80,0x20,0x11,0x00,0x2a,0x10,0x92,0x00,0xed,0xff,0x40,0x14,0x00,0x00,0x00,0x00,
-0xbd,0x4e,0x00,0x0c,0x21,0x20,0xc0,0x03,0x02,0x80,0x02,0x3c,0x08,0x04,0x44,0x24,
-0x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,
-0x25,0xb0,0x03,0x3c,0x04,0x01,0x62,0x34,0x00,0x00,0x43,0x8c,0x44,0x65,0xa7,0x8e,
-0x00,0x00,0x00,0x00,0xcf,0xff,0xe3,0x14,0x48,0x65,0xa3,0xae,0x25,0xb0,0x03,0x3c,
-0x00,0x01,0x62,0x34,0x00,0x00,0x47,0xac,0x66,0x09,0x00,0x08,0x44,0x65,0xa7,0xae,
-0xb0,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xb0,0x4c,0xe2,0xae,
-0x0c,0x00,0x04,0x8e,0x0c,0x00,0x02,0x24,0x3f,0x00,0x83,0x30,0x64,0x00,0x62,0x10,
-0x21,0x28,0xe0,0x02,0x3f,0x00,0x83,0x30,0x0d,0x00,0x02,0x24,0x59,0x00,0x62,0x10,
-0x00,0x00,0x00,0x00,0x3f,0x00,0x83,0x30,0x0e,0x00,0x02,0x24,0x04,0x00,0x62,0x10,
-0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x8e,0x5b,0x09,0x00,0x08,0x06,0x00,0x22,0x26,
-0xbc,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xbc,0x4c,0xe2,0xae,
-0x00,0x00,0x05,0x8e,0x5b,0x09,0x00,0x08,0x06,0x00,0x22,0x26,0x00,0x40,0xc2,0x8e,
-0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x0f,0x00,0x42,0x30,0x05,0x00,0x54,0x10,
-0xc2,0x13,0x05,0x00,0x1e,0x00,0x42,0x30,0x21,0x10,0x51,0x00,0x60,0x09,0x00,0x08,
-0xff,0xff,0x51,0x30,0x02,0x40,0xc2,0x92,0x00,0x00,0x00,0x00,0x1e,0x00,0x40,0x14,
-0x02,0x80,0x03,0x3c,0x04,0x00,0x03,0x8e,0x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00,
-0x0f,0x00,0x42,0x30,0x17,0x00,0x40,0x14,0x02,0x17,0x03,0x00,0x03,0x00,0x44,0x30,
-0x08,0x00,0x80,0x10,0x00,0xc0,0x02,0x3c,0x24,0x10,0x62,0x00,0x11,0x00,0x40,0x14,
-0x03,0x00,0x02,0x24,0x10,0x00,0x82,0x10,0x02,0x80,0x03,0x3c,0x0f,0x00,0x80,0x10,
-0x68,0x15,0x63,0x24,0x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c,
-0x25,0xb0,0x02,0x3c,0xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac,
-0xdc,0x08,0x00,0x0c,0x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c,
-0x21,0x28,0x00,0x00,0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x02,0x40,0x62,0x90,
-0x00,0x00,0x00,0x00,0x85,0x00,0x54,0x10,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,
-0x68,0x15,0x84,0x24,0x02,0x40,0x83,0x90,0x02,0x00,0x02,0x24,0x68,0x00,0x62,0x10,
-0x00,0x00,0x00,0x00,0x25,0xb0,0x03,0x3c,0x4c,0x00,0x63,0x34,0x00,0x00,0x62,0x90,
-0x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30,0x08,0x00,0x54,0x10,0x02,0x80,0x04,0x3c,
-0x00,0x00,0x05,0x8e,0x00,0x00,0x00,0x00,0xc2,0x13,0x05,0x00,0x1e,0x00,0x42,0x30,
-0x21,0x10,0x51,0x00,0x60,0x09,0x00,0x08,0xff,0xff,0x51,0x30,0xd0,0x02,0x02,0x24,
-0x68,0x15,0x84,0x24,0xdc,0x63,0x82,0xac,0x00,0x00,0x05,0x8e,0xd3,0x09,0x00,0x08,
-0xc2,0x13,0x05,0x00,0xb8,0x4c,0xa2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,
-0xb8,0x4c,0xa2,0xac,0x0c,0x00,0x04,0x8e,0x86,0x09,0x00,0x08,0x3f,0x00,0x83,0x30,
-0xb4,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xb4,0x4c,0xe2,0xae,
-0x0c,0x00,0x04,0x8e,0x82,0x09,0x00,0x08,0x3f,0x00,0x83,0x30,0x4c,0x65,0xa2,0x8e,
-0xff,0xff,0x71,0x30,0x23,0x10,0x47,0x00,0xff,0xff,0x50,0x30,0x21,0x18,0x11,0x02,
-0xff,0xff,0x72,0x30,0xa1,0x4e,0x00,0x0c,0x21,0x20,0x40,0x02,0x76,0x00,0x40,0x10,
-0x21,0xf0,0x40,0x00,0x08,0x00,0x42,0x8c,0x44,0x65,0xa6,0x8e,0x21,0x38,0x00,0x02,
-0x21,0x18,0x52,0x00,0x21,0x28,0x40,0x00,0x08,0x00,0x04,0x24,0x14,0x65,0xa3,0xae,
-0x18,0x65,0xa2,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x4d,0x01,0x00,0x0c,
-0x08,0x00,0x04,0x24,0x18,0x65,0xa5,0x8e,0x25,0xb0,0x03,0x3c,0x24,0x10,0x02,0x3c,
-0x21,0x28,0xb0,0x00,0x00,0x01,0x70,0x34,0x00,0x00,0x02,0xae,0x21,0x38,0x20,0x02,
-0x08,0x00,0x04,0x24,0x24,0x10,0x06,0x3c,0x44,0x65,0xa2,0xae,0x10,0x01,0x00,0x0c,
-0x10,0x00,0xa0,0xaf,0x48,0x65,0xa3,0x8e,0x08,0x00,0x04,0x24,0x4d,0x01,0x00,0x0c,
-0x44,0x65,0xa3,0xae,0x44,0x65,0xa2,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xae,
-0x46,0x09,0x00,0x08,0x02,0x80,0x02,0x3c,0x23,0x10,0x67,0x00,0xff,0xff,0x52,0x30,
-0xa1,0x4e,0x00,0x0c,0x21,0x20,0x40,0x02,0x56,0x00,0x40,0x10,0x21,0xf0,0x40,0x00,
-0x08,0x00,0x42,0x8c,0x44,0x65,0xa6,0x8e,0x08,0x00,0x04,0x24,0x21,0x18,0x52,0x00,
-0x21,0x28,0x40,0x00,0x21,0x38,0x40,0x02,0x14,0x65,0xa3,0xae,0x18,0x65,0xa2,0xae,
-0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x48,0x65,0xa3,0x8e,0x08,0x00,0x04,0x24,
-0x4d,0x01,0x00,0x0c,0x44,0x65,0xa3,0xae,0x44,0x65,0xa3,0x8e,0x25,0xb0,0x04,0x3c,
-0x00,0x01,0x82,0x34,0x00,0x00,0x43,0xac,0x46,0x09,0x00,0x08,0x02,0x80,0x02,0x3c,
-0x04,0x00,0x03,0x8e,0x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00,0x0f,0x00,0x42,0x30,
-0x08,0x00,0x42,0x28,0x93,0xff,0x40,0x10,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30,
-0x90,0xff,0x40,0x14,0x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c,
-0x25,0xb0,0x02,0x3c,0xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac,
-0xdc,0x08,0x00,0x0c,0x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c,
-0x21,0x28,0x00,0x00,0xca,0x09,0x00,0x08,0x25,0xb0,0x03,0x3c,0x04,0x00,0x03,0x8e,
-0x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00,0x0f,0x00,0x42,0x30,0x08,0x00,0x42,0x28,
-0x06,0x00,0x40,0x10,0x00,0xc0,0x02,0x3c,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30,
-0x0c,0x00,0x40,0x10,0x80,0x10,0x11,0x00,0x00,0xc0,0x02,0x3c,0x24,0x10,0x62,0x00,
-0x6f,0xff,0x40,0x14,0x02,0x80,0x04,0x3c,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30,
-0x03,0x00,0x03,0x24,0x6b,0xff,0x43,0x10,0x68,0x15,0x84,0x24,0x67,0xff,0x40,0x10,
-0x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c,0x25,0xb0,0x02,0x3c,
-0xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac,0xdc,0x08,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c,0x21,0x28,0x00,0x00,
-0xc4,0x09,0x00,0x08,0x02,0x80,0x04,0x3c,0x25,0xb0,0x04,0x3c,0x44,0x44,0x02,0x3c,
-0xbc,0x02,0x83,0x34,0x44,0x44,0x42,0x34,0x00,0x00,0x62,0xac,0x67,0x09,0x00,0x08,
-0x02,0x80,0x02,0x3c,0x48,0x65,0xa5,0x8e,0x25,0xb0,0x04,0x3c,0x66,0x66,0x02,0x3c,
-0x00,0x01,0x83,0x34,0x66,0x66,0x42,0x34,0xbc,0x02,0x84,0x34,0x00,0x00,0x65,0xac,
-0x00,0x00,0x82,0xac,0x66,0x09,0x00,0x08,0x44,0x65,0xa5,0xae,0x00,0x60,0x02,0x40,
-0x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x03,0x3c,
-0xd8,0x8c,0x64,0xac,0x00,0x60,0x82,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x02,0x80,0x02,0x3c,0xd8,0x8c,0x45,0x8c,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
-0x18,0x03,0x42,0x34,0x10,0x2a,0x63,0x24,0x00,0x00,0x43,0xac,0x04,0x00,0x02,0x24,
-0x1e,0x00,0xa2,0x10,0x05,0x00,0xa2,0x2c,0x10,0x00,0x40,0x10,0x05,0x00,0x02,0x24,
-0x03,0x00,0x02,0x24,0x08,0x00,0xa2,0x10,0x00,0x19,0x04,0x00,0x80,0x10,0x04,0x00,
-0x21,0x10,0x44,0x00,0xc0,0x10,0x02,0x00,0x23,0x10,0x44,0x00,0x00,0x11,0x02,0x00,
-0x21,0x10,0x44,0x00,0x40,0x19,0x02,0x00,0xff,0xff,0x63,0x24,0xfe,0xff,0x60,0x14,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xf3,0xff,0xa2,0x10,
-0x06,0x00,0x02,0x24,0xf2,0xff,0xa2,0x14,0x80,0x10,0x04,0x00,0x40,0x11,0x04,0x00,
-0x23,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,0x00,0x19,0x02,0x00,
-0x23,0x18,0x62,0x00,0x9a,0x0a,0x00,0x08,0x00,0x19,0x03,0x00,0x80,0x10,0x04,0x00,
-0x21,0x10,0x44,0x00,0xc0,0x10,0x02,0x00,0x23,0x10,0x44,0x00,0x00,0x11,0x02,0x00,
-0x21,0x10,0x44,0x00,0x9a,0x0a,0x00,0x08,0x00,0x19,0x02,0x00,0x02,0x80,0x02,0x3c,
-0xd8,0x8c,0x45,0x8c,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x18,0x03,0x42,0x34,
-0xcc,0x2a,0x63,0x24,0x00,0x00,0x43,0xac,0x05,0x00,0x02,0x24,0x10,0x00,0xa2,0x10,
-0x06,0x00,0xa2,0x2c,0x09,0x00,0x40,0x14,0x04,0x00,0x02,0x24,0x06,0x00,0x02,0x24,
-0x0f,0x00,0xa2,0x10,0x00,0x11,0x04,0x00,0xff,0xff,0x84,0x24,0xfe,0xff,0x80,0x14,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xfa,0xff,0xa2,0x14,
-0x80,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x40,0x20,0x02,0x00,
-0x80,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x80,0x20,0x02,0x00,
-0x23,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x40,0x20,0x02,0x00,0xff,0xff,0x85,0x30,
-0x21,0x30,0x00,0x00,0x25,0xb0,0x03,0x3c,0x2a,0xb0,0x04,0x3c,0xb4,0x00,0x63,0x34,
-0x01,0x00,0xa2,0x24,0x31,0x00,0x84,0x34,0x00,0x00,0x65,0xa0,0x00,0x00,0x85,0xa0,
-0xff,0xff,0x45,0x30,0x12,0x00,0xa0,0x10,0x01,0x00,0x03,0x24,0x28,0xb0,0x07,0x3c,
-0xe8,0x0a,0x00,0x08,0xff,0xff,0x08,0x24,0x00,0x00,0x83,0xa0,0x01,0x00,0x63,0x24,
-0xff,0xff,0x63,0x30,0x2b,0x10,0xa3,0x00,0x09,0x00,0x40,0x14,0x08,0x00,0xc6,0x24,
-0xf9,0xff,0x65,0x14,0x21,0x20,0xc7,0x00,0x01,0x00,0x63,0x24,0xff,0xff,0x63,0x30,
-0x2b,0x10,0xa3,0x00,0x00,0x00,0x88,0xa0,0xf9,0xff,0x40,0x10,0x08,0x00,0xc6,0x24,
-0x00,0x01,0xa2,0x2c,0x13,0x00,0x40,0x10,0x21,0x18,0xa0,0x00,0xff,0x00,0x08,0x24,
-0x28,0xb0,0x07,0x3c,0xfc,0x0a,0x00,0x08,0xff,0xff,0x09,0x24,0xff,0xff,0x43,0x30,
-0x00,0x00,0xa2,0xa0,0x00,0x01,0x62,0x2c,0x0a,0x00,0x40,0x10,0x08,0x00,0xc6,0x24,
-0x01,0x00,0x62,0x24,0xf9,0xff,0x68,0x14,0x21,0x28,0xc7,0x00,0x00,0x01,0x02,0x24,
-0xff,0xff,0x43,0x30,0x00,0x01,0x62,0x2c,0x00,0x00,0xa9,0xa0,0xf8,0xff,0x40,0x14,
-0x08,0x00,0xc6,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xd8,0xff,0xbd,0x27,
-0x24,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,
-0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x42,0x00,0x14,0x36,
-0xff,0xff,0x02,0x24,0x00,0x00,0x82,0xa2,0xd8,0x00,0x05,0x36,0x40,0x00,0x11,0x36,
-0xa8,0x00,0x13,0x36,0xa0,0x00,0x12,0x36,0x00,0x10,0x03,0x24,0xa4,0x00,0x10,0x36,
-0x00,0x80,0x02,0x3c,0x00,0x00,0x23,0xa6,0x00,0x00,0xa0,0xa0,0x00,0x00,0x40,0xae,
-0x00,0x00,0x00,0xae,0x00,0x00,0x62,0xae,0x00,0x00,0xa3,0x90,0x80,0xff,0x02,0x24,
-0xfd,0x00,0x04,0x24,0x25,0x18,0x62,0x00,0xfc,0x17,0x02,0x24,0x00,0x00,0xa3,0xa0,
-0x00,0x00,0x22,0xa6,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,
-0x68,0x15,0x42,0x24,0x68,0x4b,0x45,0x8c,0x60,0x4b,0x43,0x8c,0x64,0x4b,0x44,0x8c,
-0xfc,0x37,0x02,0x24,0x00,0x00,0x43,0xae,0x00,0x00,0x04,0xae,0x00,0x00,0x65,0xae,
-0x00,0x00,0x22,0xa6,0x00,0x00,0x80,0xa2,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x00,0x60,0x81,0x40,0x24,0x00,0xbf,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,
-0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
-0x28,0x00,0xbd,0x27,0xd0,0xff,0xbd,0x27,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf,
-0x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,
-0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x40,0x00,0x05,0x36,
-0x00,0x00,0xa2,0x94,0x24,0xfa,0x03,0x24,0xa8,0x00,0x13,0x36,0x24,0x10,0x43,0x00,
-0x00,0x00,0xa2,0xa4,0xa0,0x00,0x12,0x36,0xa4,0x00,0x10,0x36,0x00,0x00,0x55,0x8e,
-0x00,0x00,0x16,0x8e,0x00,0x00,0x71,0x8e,0x00,0x80,0x14,0x3c,0xfc,0x37,0x02,0x24,
-0x00,0x00,0x40,0xae,0xfd,0x00,0x04,0x24,0x00,0x00,0x00,0xae,0x21,0x88,0x34,0x02,
-0x00,0x00,0x74,0xae,0x00,0x00,0xa2,0xa4,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x00,0x55,0xae,0x00,0x00,0x16,0xae,0x00,0x00,0x71,0xae,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f,
-0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,
-0xd0,0xff,0xbd,0x27,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf,
-0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,
-0x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x40,0x00,0x05,0x36,0x00,0x00,0xa2,0x94,
-0xaf,0xff,0x03,0x24,0xa8,0x00,0x13,0x36,0x24,0x10,0x43,0x00,0x00,0x00,0xa2,0xa4,
-0xa0,0x00,0x12,0x36,0xa4,0x00,0x10,0x36,0x00,0x00,0x55,0x8e,0x00,0x00,0x16,0x8e,
-0x00,0x00,0x71,0x8e,0x00,0x80,0x14,0x3c,0xfc,0x37,0x02,0x24,0x00,0x00,0x40,0xae,
-0xfd,0x00,0x04,0x24,0x00,0x00,0x00,0xae,0x21,0x88,0x34,0x02,0x00,0x00,0x74,0xae,
-0x00,0x00,0xa2,0xa4,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xae,
-0x00,0x00,0x16,0xae,0x00,0x00,0x71,0xae,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x00,0x60,0x81,0x40,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,
-0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x04,0x3c,
-0x40,0x00,0x84,0x34,0x00,0x00,0x82,0x94,0xd8,0xfd,0x03,0x24,0x24,0x10,0x43,0x00,
-0xfc,0x37,0x03,0x24,0x00,0x00,0x82,0xa4,0x00,0x00,0x83,0xa4,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x00,0x00,0x82,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x30,
-0x10,0x00,0x02,0x24,0x0c,0x00,0xc2,0x10,0x11,0x00,0xc3,0x28,0x06,0x00,0x60,0x10,
-0x20,0x00,0x02,0x24,0x08,0x00,0x02,0x24,0x0d,0x00,0xc2,0x10,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0xc2,0x10,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xa4,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x00,0x00,0x85,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x25,0xb0,0x02,0x3c,
-0x0a,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0xff,0xff,0xa5,0x24,0x00,0x2c,0x05,0x00,
-0xfd,0x00,0x63,0x30,0x03,0x2c,0x05,0x00,0xff,0xff,0x87,0x30,0x00,0x00,0x43,0xa0,
-0x1a,0x00,0xa0,0x04,0x00,0x00,0x00,0x00,0x21,0x30,0x40,0x00,0x07,0x10,0xa7,0x00,
-0x01,0x00,0x42,0x30,0xfd,0x00,0x64,0x30,0x00,0x00,0x42,0x38,0x02,0x00,0x63,0x34,
-0x0a,0x18,0x82,0x00,0x00,0x00,0xc3,0xa0,0x04,0x00,0x63,0x34,0x00,0x00,0xc3,0xa0,
-0x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,
-0xfb,0x00,0x63,0x30,0x00,0x00,0xc3,0xa0,0x04,0x00,0x02,0x24,0xff,0xff,0x42,0x24,
-0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0xff,0xff,0xa2,0x24,0x00,0x2c,0x02,0x00,
-0x03,0x2c,0x05,0x00,0xea,0xff,0xa1,0x04,0x07,0x10,0xa7,0x00,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,0x0a,0x00,0x42,0x34,0x00,0x00,0x43,0x90,
-0xff,0xff,0x84,0x24,0x00,0x24,0x04,0x00,0x03,0x24,0x04,0x00,0xff,0x00,0x65,0x30,
-0x1d,0x00,0x80,0x04,0x21,0x38,0x00,0x00,0x21,0x30,0x40,0x00,0x01,0x00,0x08,0x24,
-0x04,0x00,0xa5,0x34,0x00,0x00,0xc5,0xa0,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
-0xff,0x00,0x45,0x30,0x01,0x00,0xa3,0x30,0x05,0x00,0x60,0x10,0x04,0x00,0x02,0x24,
-0x04,0x10,0x88,0x00,0x25,0x10,0x47,0x00,0xff,0xff,0x47,0x30,0x04,0x00,0x02,0x24,
-0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0xfb,0x00,0xa5,0x30,
-0x00,0x00,0xc5,0xa0,0x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,
-0xff,0xff,0x42,0x24,0xff,0xff,0x82,0x24,0x00,0x24,0x02,0x00,0x03,0x24,0x04,0x00,
-0xe7,0xff,0x81,0x04,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0xe0,0x00,
-0xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x0a,0x00,0x10,0x36,
-0x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x00,0x00,0x02,0x92,0xff,0xff,0x91,0x30,
-0x03,0x00,0x05,0x24,0xc0,0x00,0x42,0x30,0x80,0x00,0x43,0x34,0x00,0x00,0x03,0xa2,
-0x04,0x00,0x63,0x34,0x00,0x00,0x03,0xa2,0xfb,0x00,0x63,0x30,0x00,0x00,0x03,0xa2,
-0x08,0x00,0x63,0x34,0x00,0x00,0x03,0xa2,0x04,0x00,0x63,0x34,0x00,0x00,0x03,0xa2,
-0xfb,0x00,0x63,0x30,0x00,0x00,0x03,0xa2,0xd7,0x0b,0x00,0x0c,0x06,0x00,0x04,0x24,
-0x42,0x20,0x11,0x00,0xd7,0x0b,0x00,0x0c,0x06,0x00,0x05,0x24,0xfd,0x0b,0x00,0x0c,
-0x10,0x00,0x04,0x24,0x00,0x00,0x03,0x92,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,
-0xc0,0x00,0x63,0x30,0x00,0x00,0x03,0xa2,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0xff,0xff,0xb1,0x30,
-0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x1c,0x00,0xbf,0xaf,0x21,0x90,0xc0,0x00,
-0x0a,0x00,0x20,0x12,0xff,0xff,0x90,0x30,0x24,0x0c,0x00,0x0c,0x21,0x20,0x00,0x02,
-0xfe,0xff,0x23,0x26,0x02,0x00,0x04,0x26,0x00,0x00,0x42,0xa6,0xff,0xff,0x71,0x30,
-0xff,0xff,0x90,0x30,0xf8,0xff,0x20,0x16,0x02,0x00,0x52,0x26,0x1c,0x00,0xbf,0x8f,
-0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0x25,0xb0,0x03,0x3c,0x0a,0x00,0x68,0x34,0x00,0x00,0x02,0x91,
-0xff,0xff,0xa5,0x30,0xff,0x00,0x84,0x30,0x1f,0x00,0xa0,0x10,0xff,0x00,0x47,0x30,
-0x21,0x48,0x00,0x01,0x0c,0x00,0x6c,0x34,0x0b,0x00,0x6b,0x34,0xc0,0xff,0x0a,0x24,
-0x21,0x68,0x00,0x01,0x25,0x10,0xea,0x00,0xff,0x00,0x47,0x30,0x00,0x00,0x64,0xa1,
-0x00,0x00,0x27,0xa1,0x00,0x00,0x22,0x91,0x00,0x00,0x00,0x00,0xff,0x00,0x47,0x30,
-0xc0,0x00,0xe3,0x30,0x08,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x21,0x40,0xa0,0x01,
-0x00,0x00,0x02,0x91,0x00,0x00,0x00,0x00,0xff,0x00,0x47,0x30,0xc0,0x00,0xe3,0x30,
-0xfb,0xff,0x60,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x8d,0xfc,0xff,0xa3,0x24,
-0x04,0x00,0x84,0x24,0xff,0xff,0x65,0x30,0x00,0x00,0xc2,0xac,0xff,0x00,0x84,0x30,
-0xe8,0xff,0xa0,0x14,0x04,0x00,0xc6,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0xff,0x00,0x84,0x30,0x21,0x68,0xe0,0x00,0xff,0xff,0xa5,0x30,0xc0,0x50,0x04,0x00,
-0x00,0x60,0x0c,0x40,0x01,0x00,0x81,0x35,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x00,0x00,0xc2,0x90,0x01,0x00,0xc3,0x90,0x25,0xb0,0x07,0x3c,0x00,0x14,0x02,0x00,
-0x25,0x28,0xa2,0x00,0x00,0x1e,0x03,0x00,0x01,0x80,0x08,0x3c,0x25,0x20,0xa3,0x00,
-0x40,0x02,0xe9,0x34,0x25,0x18,0x48,0x01,0x44,0x02,0xe7,0x34,0x00,0x00,0xe4,0xac,
-0x00,0x00,0x23,0xad,0x03,0x00,0xc2,0x90,0x02,0x00,0xc4,0x90,0x04,0x00,0xc3,0x90,
-0x05,0x00,0xc5,0x90,0x00,0x12,0x02,0x00,0x25,0x20,0x82,0x00,0x00,0x1c,0x03,0x00,
-0x01,0x00,0x4a,0x25,0x25,0x20,0x83,0x00,0x00,0x2e,0x05,0x00,0x25,0x40,0x48,0x01,
-0x25,0x20,0x85,0x00,0x00,0x00,0xe4,0xac,0x01,0x00,0x4a,0x25,0x00,0x00,0x28,0xad,
-0x01,0x80,0x0b,0x3c,0x21,0x40,0x00,0x00,0x21,0x10,0xa8,0x01,0x01,0x00,0x43,0x90,
-0x00,0x00,0x45,0x90,0x02,0x00,0x44,0x90,0x03,0x00,0x46,0x90,0x00,0x1a,0x03,0x00,
-0x25,0x28,0xa3,0x00,0x00,0x24,0x04,0x00,0x25,0x28,0xa4,0x00,0x00,0x36,0x06,0x00,
-0x04,0x00,0x08,0x25,0x25,0x10,0x4b,0x01,0x25,0x20,0xa6,0x00,0x10,0x00,0x03,0x2d,
-0x00,0x00,0xe4,0xac,0x01,0x00,0x4a,0x25,0x00,0x00,0x22,0xad,0xee,0xff,0x60,0x14,
-0x00,0x00,0x00,0x00,0x00,0x60,0x8c,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0xff,0xff,0x84,0x30,0x42,0xb0,0x08,0x3c,0x80,0x10,0x04,0x00,0x21,0x10,0x48,0x00,
-0x04,0x00,0x46,0xac,0x00,0x00,0x07,0x91,0x40,0x18,0x04,0x00,0x03,0x00,0x06,0x24,
-0xff,0x00,0xe7,0x30,0x04,0x30,0x66,0x00,0x01,0x00,0x02,0x24,0x04,0x10,0x62,0x00,
-0x25,0x30,0xc7,0x00,0xff,0xff,0xa5,0x30,0x25,0x10,0x47,0x00,0x02,0x00,0xa0,0x14,
-0xff,0x00,0xc7,0x30,0xff,0x00,0x47,0x30,0x42,0xb0,0x02,0x3c,0x00,0x00,0x47,0xa0,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x42,0xb0,0x02,0x3c,0x03,0x00,0x47,0x34,
-0x00,0x00,0xe3,0x90,0xff,0x00,0x84,0x30,0x04,0x00,0x84,0x24,0xff,0x00,0x65,0x30,
-0x01,0x00,0x02,0x24,0x04,0x30,0x82,0x00,0x07,0x18,0x85,0x00,0x25,0xb0,0x02,0x3c,
-0xe8,0x03,0x42,0x34,0x01,0x00,0x63,0x30,0x21,0x20,0xc0,0x00,0x00,0x00,0x45,0xa0,
-0x02,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe6,0xa0,0x08,0x00,0xe0,0x03,
-0x24,0x10,0x85,0x00,0x00,0x60,0x03,0x40,0x01,0x00,0x61,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0x02,0x80,0x02,0x3c,0xdc,0x8c,0x42,0x24,0x04,0x00,0x45,0x8c,
-0x00,0x00,0x82,0xac,0x04,0x00,0x44,0xac,0x00,0x00,0xa4,0xac,0x04,0x00,0x85,0xac,
-0x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x14,0x00,0x83,0x90,
-0x01,0x00,0x02,0x24,0x08,0x00,0x86,0xac,0x18,0x00,0x85,0xac,0x00,0x00,0x84,0xac,
-0x03,0x00,0x62,0x10,0x04,0x00,0x84,0xac,0xed,0x0c,0x00,0x08,0x0c,0x00,0x80,0xac,
-0x0c,0x00,0x82,0x8c,0xed,0x0c,0x00,0x08,0x10,0x00,0x82,0xac,0x00,0x60,0x03,0x40,
-0x01,0x00,0x61,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x04,0x00,0x85,0x8c,
-0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xac,0x04,0x00,0x45,0xac,
-0x00,0x00,0x84,0xac,0x04,0x00,0x84,0xac,0x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0xd0,0xff,0xbd,0x27,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf,
-0x20,0x00,0xb4,0xaf,0x14,0x00,0xb1,0xaf,0x2c,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,
-0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x80,0x16,0x3c,0x02,0x80,0x14,0x3c,
-0x02,0x80,0x11,0x3c,0x02,0x80,0x15,0x3c,0xc4,0x7d,0x24,0x8e,0x25,0xb0,0x02,0x3c,
-0x54,0x34,0xc3,0x26,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0xdc,0x8c,0x90,0x8e,
-0x18,0x00,0x80,0x10,0xdc,0x8c,0x82,0x26,0x15,0x00,0x02,0x12,0x00,0x00,0x00,0x00,
-0x21,0x98,0x40,0x00,0x01,0x00,0x12,0x24,0x14,0x00,0x02,0x92,0x00,0x00,0x00,0x00,
-0x1d,0x00,0x52,0x10,0x00,0x00,0x00,0x00,0x09,0x00,0x40,0x14,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x03,0x8e,0xc4,0x7d,0x22,0x8e,0x00,0x00,0x00,0x00,0x23,0x20,0x62,0x00,
-0x2b,0x10,0x43,0x00,0x0e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0xae,
-0x00,0x00,0x10,0x8e,0x00,0x00,0x00,0x00,0xef,0xff,0x13,0x16,0x00,0x00,0x00,0x00,
-0xc4,0x7d,0x20,0xae,0x08,0x0c,0xa4,0x26,0x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00,
-0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0x22,0x0d,0x00,0x08,0x00,0x00,0x00,0x00,
-0x08,0x00,0x02,0x8e,0x18,0x00,0x04,0x8e,0x09,0xf8,0x40,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x0d,0x00,0x08,0x0c,0x00,0x02,0xae,0x0c,0x00,0x03,0x8e,0xc4,0x7d,0x22,0x8e,
-0x00,0x00,0x00,0x00,0x23,0x20,0x62,0x00,0x2b,0x10,0x43,0x00,0xe7,0xff,0x40,0x14,
-0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x8e,0x18,0x00,0x04,0x8e,0x09,0xf8,0x40,0x00,
-0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x8e,0x3c,0x0d,0x00,0x08,0x0c,0x00,0x03,0xae,
-0xff,0x00,0xa5,0x30,0x25,0xb0,0x02,0x3c,0x21,0x28,0xa2,0x00,0xff,0x00,0x84,0x30,
-0x60,0x01,0xa4,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0x84,0x30,
-0x01,0x00,0x03,0x24,0x10,0x00,0x02,0x3c,0x04,0x18,0x83,0x00,0xf0,0x70,0x42,0x34,
-0x15,0x00,0x84,0x2c,0x06,0x00,0x80,0x10,0x24,0x28,0x62,0x00,0x0f,0x00,0x63,0x30,
-0x04,0x00,0xa0,0x14,0x01,0x00,0x02,0x24,0x02,0x00,0x60,0x14,0x02,0x00,0x02,0x24,
-0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0xa5,0x30,
-0x04,0x00,0xa2,0x2c,0x14,0x00,0x40,0x10,0xff,0x00,0x84,0x30,0x02,0x80,0x03,0x3c,
-0x8e,0x7d,0x62,0x90,0x00,0x00,0x00,0x00,0xef,0xff,0x42,0x24,0xff,0x00,0x42,0x30,
-0x02,0x00,0x42,0x2c,0x0e,0x00,0x40,0x10,0x02,0x00,0x03,0x24,0x24,0x00,0x83,0x10,
-0x0f,0x10,0x02,0x3c,0x03,0x00,0x82,0x28,0x14,0x00,0x40,0x10,0x03,0x00,0x02,0x24,
-0x01,0x00,0x02,0x24,0x2f,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0xff,0x1f,0x02,0x3c,
-0x08,0x00,0xe0,0x03,0xff,0xff,0x42,0x34,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x35,0x00,0x83,0x10,0x0f,0x1f,0x02,0x3c,0x03,0x00,0x82,0x28,0x16,0x00,0x40,0x10,
-0x03,0x00,0x02,0x24,0x01,0x00,0x02,0x24,0xf4,0xff,0x82,0x14,0x00,0x00,0x00,0x00,
-0x0f,0x1f,0x02,0x3c,0x08,0x00,0xe0,0x03,0x00,0x80,0x42,0x34,0xf0,0xff,0x82,0x14,
-0xff,0x1f,0x02,0x3c,0x01,0x00,0x02,0x24,0x29,0x00,0xa2,0x10,0x0f,0x10,0x02,0x3c,
-0x02,0x00,0xa2,0x28,0x1f,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x28,0x00,0xa3,0x10,
-0x00,0x00,0x00,0x00,0xe5,0xff,0xa4,0x14,0x00,0x00,0x00,0x00,0x0f,0x10,0x02,0x3c,
-0x08,0x00,0xe0,0x03,0x00,0xf0,0x42,0x34,0xe1,0xff,0x82,0x14,0xff,0x1f,0x02,0x3c,
-0x01,0x00,0x02,0x24,0x1c,0x00,0xa2,0x10,0x0f,0x00,0x02,0x3c,0x02,0x00,0xa2,0x28,
-0x0b,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x1c,0x00,0xa3,0x10,0x00,0x00,0x00,0x00,
-0xd6,0xff,0xa4,0x14,0x00,0x00,0x00,0x00,0x0f,0x00,0x02,0x3c,0x08,0x00,0xe0,0x03,
-0x00,0xf0,0x42,0x34,0x0f,0x10,0x02,0x3c,0x08,0x00,0xe0,0x03,0x00,0x80,0x42,0x34,
-0xce,0xff,0xa0,0x14,0x00,0x00,0x00,0x00,0x0f,0x00,0x02,0x3c,0x08,0x00,0xe0,0x03,
-0x15,0xf0,0x42,0x34,0xc9,0xff,0xa0,0x14,0x00,0x00,0x00,0x00,0x0f,0x10,0x02,0x3c,
-0x08,0x00,0xe0,0x03,0x15,0xf0,0x42,0x34,0x08,0x00,0xe0,0x03,0x00,0xf0,0x42,0x34,
-0x08,0x00,0xe0,0x03,0x10,0xf0,0x42,0x34,0x08,0x00,0xe0,0x03,0x10,0xf0,0x42,0x34,
-0x0f,0x10,0x02,0x3c,0x08,0x00,0xe0,0x03,0x05,0xf0,0x42,0x34,0x0f,0x00,0x02,0x3c,
-0x08,0x00,0xe0,0x03,0x05,0xf0,0x42,0x34,0xc0,0x40,0x04,0x00,0x21,0x18,0x04,0x01,
-0x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c,0x80,0x18,0x03,0x00,
-0x68,0x15,0x42,0x24,0x21,0x18,0x62,0x00,0x74,0x51,0x66,0x8c,0x21,0x38,0x60,0x00,
-0x7a,0x51,0x60,0xa0,0x7b,0x51,0x60,0xa0,0x1c,0x00,0x05,0x24,0xdf,0x0d,0x00,0x08,
-0x01,0x00,0x03,0x24,0x08,0x00,0xa0,0x04,0x21,0x10,0x04,0x01,0x04,0x10,0xa3,0x00,
-0x24,0x10,0xc2,0x00,0xfb,0xff,0x40,0x10,0xff,0xff,0xa5,0x24,0x01,0x00,0xa5,0x24,
-0x7a,0x51,0xe5,0xa0,0x21,0x10,0x04,0x01,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,
-0x02,0x80,0x03,0x3c,0x80,0x10,0x02,0x00,0x68,0x15,0x63,0x24,0x21,0x18,0x43,0x00,
-0x74,0x51,0x66,0x8c,0x21,0x28,0x00,0x00,0xf3,0x0d,0x00,0x08,0x01,0x00,0x07,0x24,
-0x1d,0x00,0xa2,0x28,0x08,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x04,0x10,0xa7,0x00,
-0x24,0x10,0xc2,0x00,0xfa,0xff,0x40,0x10,0x01,0x00,0xa5,0x24,0xff,0xff,0xa5,0x24,
-0x08,0x00,0xe0,0x03,0x7b,0x51,0x65,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0xc8,0xff,0xbd,0x27,0x28,0x00,0xb6,0xaf,0x02,0x80,0x16,0x3c,0x30,0x00,0xbe,0xaf,
-0x2c,0x00,0xb7,0xaf,0x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x18,0x00,0xb2,0xaf,
-0x14,0x00,0xb1,0xaf,0x01,0x00,0x15,0x24,0x21,0x88,0x00,0x00,0x68,0x15,0xde,0x26,
-0x21,0xa0,0x00,0x00,0x21,0x90,0x00,0x00,0x25,0xb0,0x17,0x3c,0x34,0x00,0xbf,0xaf,
-0x1c,0x00,0xb3,0xaf,0x14,0x0e,0x00,0x08,0x10,0x00,0xb0,0xaf,0x01,0x00,0x31,0x26,
-0x20,0x00,0x22,0x2e,0x94,0x00,0x52,0x26,0x2e,0x00,0x40,0x10,0x94,0x00,0x94,0x26,
-0x68,0x15,0xc2,0x26,0x21,0x30,0x42,0x02,0x78,0x51,0xc5,0x8c,0x00,0x00,0x00,0x00,
-0x02,0x13,0x05,0x00,0x01,0x00,0x42,0x30,0xf4,0xff,0x55,0x14,0x42,0x1a,0x05,0x00,
-0x68,0x51,0xc2,0x8c,0x07,0x00,0x64,0x30,0x02,0x11,0x02,0x00,0x7f,0x00,0x43,0x30,
-0x2d,0x00,0x95,0x10,0x07,0x00,0xb3,0x30,0x02,0x00,0x82,0x28,0x3a,0x00,0x40,0x14,
-0x02,0x00,0x02,0x24,0x30,0x00,0x82,0x10,0x03,0x00,0x02,0x24,0x3c,0x00,0x82,0x10,
-0x1a,0x00,0x62,0x2c,0x21,0x80,0x9e,0x02,0x78,0x51,0x02,0x8e,0x04,0x00,0x63,0x2e,
-0x42,0x12,0x02,0x00,0x0a,0x00,0x60,0x10,0x07,0x00,0x44,0x30,0x73,0x0d,0x00,0x0c,
-0x21,0x28,0x60,0x02,0x80,0x20,0x13,0x00,0x70,0x51,0x02,0xae,0x21,0x20,0x97,0x00,
-0x84,0x01,0x83,0x8c,0x00,0x00,0x00,0x00,0x24,0x18,0x62,0x00,0x74,0x51,0x03,0xae,
-0xce,0x0d,0x00,0x0c,0x21,0x20,0x20,0x02,0x21,0x10,0x37,0x02,0x01,0x00,0x31,0x26,
-0x60,0x01,0x43,0x90,0x20,0x00,0x22,0x2e,0x94,0x00,0x52,0x26,0xd4,0xff,0x40,0x14,
-0x94,0x00,0x94,0x26,0x34,0x00,0xbf,0x8f,0x30,0x00,0xbe,0x8f,0x2c,0x00,0xb7,0x8f,
-0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,
-0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x32,0x00,0x62,0x2c,0xda,0xff,0x40,0x10,
-0x21,0x80,0x9e,0x02,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x04,0x42,0x34,
-0x29,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac,0x38,0x00,0x62,0x2c,0x12,0x00,0x40,0x14,
-0x14,0x00,0x62,0x2c,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x02,0x42,0x34,
-0x29,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac,0xcb,0xff,0x80,0x14,0x21,0x80,0x9e,0x02,
-0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x2a,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac,
-0xc5,0xff,0x40,0x14,0x21,0x80,0x9e,0x02,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,
-0x54,0x0e,0x00,0x08,0x00,0x04,0x42,0x34,0xbf,0xff,0x40,0x10,0x21,0x80,0x9e,0x02,
-0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x06,0x42,0x34,0x2a,0x0e,0x00,0x08,
-0x78,0x51,0xc2,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xd8,0xff,0xbd,0x27,
-0x10,0x00,0xb0,0xaf,0xc0,0x80,0x04,0x00,0x21,0x80,0x04,0x02,0x80,0x80,0x10,0x00,
-0x21,0x80,0x04,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x80,0x10,0x00,
-0x20,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x21,0x80,0x02,0x02,
-0x14,0x00,0xb1,0xaf,0x78,0x51,0x03,0x8e,0x25,0xb0,0x02,0x3c,0x80,0x01,0x53,0x34,
-0x07,0x00,0x63,0x30,0x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x00,0x00,0x71,0x92,
-0x70,0x51,0x05,0x8e,0x84,0x01,0x62,0x8c,0x21,0x90,0x80,0x00,0xff,0x00,0x31,0x32,
-0x24,0x10,0x45,0x00,0xce,0x0d,0x00,0x0c,0x74,0x51,0x02,0xae,0x7a,0x51,0x04,0x92,
-0x5c,0x0d,0x00,0x0c,0xff,0x00,0x45,0x32,0x7a,0x51,0x04,0x92,0x63,0x0d,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x38,0x04,0x00,0x03,0x24,0x0a,0x88,0x62,0x00,
-0x00,0x00,0x71,0xa2,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,
-0xff,0xff,0x84,0x30,0x00,0x02,0x82,0x30,0x07,0x00,0x03,0x24,0x0d,0x00,0x40,0x14,
-0x0b,0x00,0x84,0x30,0x0c,0x00,0x82,0x2c,0x0a,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
-0x02,0x80,0x03,0x3c,0x80,0x10,0x04,0x00,0xf0,0x91,0x63,0x24,0x21,0x10,0x43,0x00,
-0x00,0x00,0x44,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
-0x07,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x06,0x00,0x03,0x24,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x05,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x60,0x00,0x04,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
-0x03,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x02,0x00,0x03,0x24,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x01,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x60,0x00,0x21,0x18,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
-0xa0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x58,0x00,0xbe,0xaf,0x54,0x00,0xb7,0xaf,
-0x50,0x00,0xb6,0xaf,0x4c,0x00,0xb5,0xaf,0x48,0x00,0xb4,0xaf,0x40,0x00,0xb2,0xaf,
-0x3c,0x00,0xb1,0xaf,0x5c,0x00,0xbf,0xaf,0x44,0x00,0xb3,0xaf,0x38,0x00,0xb0,0xaf,
-0x20,0x92,0x42,0x24,0x00,0x00,0x53,0x8c,0x08,0x00,0x03,0x24,0x02,0x80,0x0b,0x3c,
-0x21,0x90,0x00,0x00,0x21,0xa0,0x00,0x00,0x21,0xb8,0x00,0x00,0x21,0xf0,0x00,0x00,
-0x21,0xa8,0x00,0x00,0x21,0xb0,0x00,0x00,0x21,0x88,0x60,0x02,0x10,0x00,0xa3,0xaf,
-0x14,0x00,0xa0,0xaf,0x18,0x00,0xa0,0xaf,0x1c,0x00,0xa0,0xaf,0x20,0x00,0xa0,0xaf,
-0x24,0x00,0xa0,0xaf,0x28,0x00,0xa0,0xaf,0x7a,0x0f,0x00,0x08,0x2c,0x00,0xa0,0xaf,
-0x44,0x51,0x22,0xae,0x60,0x51,0x24,0x8e,0x5c,0x51,0x27,0x8e,0x48,0x51,0x28,0x8e,
-0x4c,0x51,0x25,0x8e,0x54,0x51,0x26,0x8e,0x58,0x51,0x23,0x8e,0x21,0x38,0xe4,0x00,
-0x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24,0x21,0x10,0x04,0x02,0x21,0x40,0x05,0x01,
-0x21,0x30,0xc3,0x00,0xca,0x44,0x42,0x90,0x44,0x51,0x2a,0x8e,0x0c,0x00,0xe0,0x10,
-0x21,0x48,0x00,0x00,0x2b,0x48,0x47,0x00,0x0b,0x00,0x20,0x15,0x02,0x80,0x02,0x3c,
-0x07,0x00,0x02,0x2e,0x59,0x01,0x40,0x14,0xc0,0x10,0x07,0x00,0x0c,0x00,0x02,0x24,
-0x55,0x01,0x02,0x12,0x0d,0x00,0x02,0x24,0x54,0x01,0x02,0x12,0xc0,0x10,0x07,0x00,
-0x92,0x00,0x20,0x11,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x18,0x10,0x00,
-0x21,0x18,0x62,0x00,0x21,0x20,0x30,0x02,0xb6,0x51,0x85,0x90,0xec,0x44,0x62,0x8c,
-0x00,0x00,0x00,0x00,0x04,0x10,0xa2,0x00,0x2b,0x10,0x4a,0x00,0x87,0x00,0x40,0x10,
-0x00,0x00,0x00,0x00,0xd4,0x51,0x22,0x8e,0x01,0x00,0x07,0x24,0x04,0x18,0x07,0x02,
-0x24,0x10,0x43,0x00,0xf0,0x00,0x40,0x10,0x1c,0x00,0x02,0x2e,0x21,0x28,0x30,0x02,
-0x7c,0x51,0xa6,0x90,0xb6,0x51,0xa2,0x90,0x0a,0x00,0x04,0x24,0xff,0x00,0xc3,0x30,
-0x04,0x20,0x44,0x00,0x2a,0x18,0x64,0x00,0xe7,0x00,0x60,0x10,0x1c,0x00,0x02,0x2e,
-0x01,0x00,0xc2,0x24,0xff,0x00,0x43,0x30,0x56,0x01,0x64,0x10,0x7c,0x51,0xa2,0xa0,
-0x68,0x15,0x65,0x25,0x80,0x10,0x10,0x00,0x21,0x10,0x45,0x00,0x60,0x45,0x44,0x8c,
-0xec,0x44,0x43,0x8c,0x21,0x30,0xc5,0x02,0x40,0x10,0x04,0x00,0x21,0x10,0x44,0x00,
-0x21,0x18,0x62,0x00,0x82,0x50,0x03,0x00,0x44,0x51,0xca,0xac,0x8c,0x65,0xa3,0x8c,
-0xff,0xff,0x02,0x34,0x07,0x00,0x62,0x10,0x21,0x20,0x00,0x02,0x21,0x20,0x00,0x02,
-0xff,0x00,0x45,0x32,0x5c,0x0d,0x00,0x0c,0x30,0x00,0xab,0xaf,0x30,0x00,0xab,0x8f,
-0x21,0x20,0x00,0x02,0x63,0x0d,0x00,0x0c,0x30,0x00,0xab,0xaf,0x10,0x00,0xa4,0x8f,
-0x01,0x00,0x42,0x38,0x04,0x00,0x03,0x24,0x0a,0x20,0x62,0x00,0x10,0x00,0xa4,0xaf,
-0x30,0x00,0xab,0x8f,0x11,0x00,0x40,0x16,0x68,0x15,0x62,0x25,0x58,0x51,0x47,0x8c,
-0x54,0x51,0x43,0x8c,0x4c,0x51,0x44,0x94,0x48,0x51,0x45,0x94,0x50,0x51,0x46,0x94,
-0x21,0x18,0x67,0x00,0x00,0x24,0x04,0x00,0x25,0xb0,0x02,0x3c,0x00,0x1c,0x03,0x00,
-0x21,0x28,0xa4,0x00,0x21,0x30,0xc3,0x00,0x6c,0x0c,0x44,0x34,0x68,0x0c,0x42,0x34,
-0x00,0x00,0x45,0xac,0x00,0x00,0x86,0xac,0x68,0x15,0x62,0x25,0x21,0x10,0x82,0x02,
-0x58,0x51,0x40,0xac,0x5c,0x51,0x40,0xac,0x60,0x51,0x40,0xac,0x48,0x51,0x40,0xac,
-0x4c,0x51,0x40,0xac,0x50,0x51,0x40,0xac,0x54,0x51,0x40,0xac,0x2c,0x00,0xa2,0x8f,
-0x28,0x00,0xa4,0x8f,0x01,0x00,0x52,0x26,0x94,0x00,0x42,0x24,0x2c,0x00,0xa2,0xaf,
-0x24,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24,0x28,0x00,0xa4,0xaf,0x94,0x00,0x42,0x24,
-0x20,0x00,0xa4,0x8f,0x24,0x00,0xa2,0xaf,0x1c,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24,
-0x20,0x00,0xa4,0xaf,0x94,0x00,0x42,0x24,0x18,0x00,0xa4,0x8f,0x1c,0x00,0xa2,0xaf,
-0x14,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24,0x20,0x00,0x43,0x2a,0x94,0x00,0x42,0x24,
-0x94,0x00,0x31,0x26,0x94,0x00,0xd6,0x26,0x94,0x00,0xb5,0x26,0x18,0x00,0xa4,0xaf,
-0x14,0x00,0xa2,0xaf,0x94,0x00,0xde,0x27,0x94,0x00,0x73,0x26,0x94,0x00,0xf7,0x26,
-0xe5,0x00,0x60,0x10,0x94,0x00,0x94,0x26,0x78,0x51,0x22,0x8e,0x00,0x00,0x00,0x00,
-0x02,0x13,0x02,0x00,0x01,0x00,0x42,0x30,0xd3,0xff,0x40,0x10,0x25,0xb0,0x02,0x3c,
-0x21,0x10,0x42,0x02,0x60,0x01,0x44,0x90,0x60,0x51,0x23,0x8e,0x5c,0x51,0x26,0x8e,
-0xff,0x00,0x90,0x30,0x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24,0x21,0x10,0x04,0x02,
-0x73,0x44,0x44,0x90,0x56,0x44,0x45,0x90,0x44,0x51,0x27,0x8e,0x18,0x00,0x64,0x00,
-0x12,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xc5,0x00,
-0x12,0x30,0x00,0x00,0x21,0x30,0xc3,0x00,0x2b,0x10,0xe6,0x00,0x54,0xff,0x40,0x10,
-0x23,0x10,0xe6,0x00,0xe9,0x0e,0x00,0x08,0x44,0x51,0x20,0xae,0x62,0x00,0xe0,0x10,
-0x00,0x00,0x00,0x00,0x63,0x00,0x20,0x15,0x68,0x15,0x62,0x25,0x40,0x10,0x07,0x00,
-0x21,0x10,0x47,0x00,0x82,0x10,0x02,0x00,0x2b,0x10,0x46,0x00,0x99,0xff,0x40,0x10,
-0x21,0x20,0x00,0x02,0x68,0x15,0x68,0x25,0x21,0x20,0xa8,0x02,0x21,0x30,0x90,0x00,
-0xd4,0x51,0x83,0x8c,0x01,0x00,0x05,0x24,0x04,0x10,0x05,0x02,0x99,0x51,0xc7,0x90,
-0x27,0x10,0x02,0x00,0x24,0x18,0x62,0x00,0xd4,0x51,0x83,0xac,0x09,0x00,0xe5,0x10,
-0x7c,0x51,0xc0,0xa0,0x18,0x00,0xa2,0x8f,0x21,0x38,0x00,0x00,0x21,0x20,0x48,0x00,
-0x21,0x18,0x87,0x00,0x01,0x00,0xe7,0x24,0x1d,0x00,0xe2,0x28,0xfc,0xff,0x40,0x14,
-0xb6,0x51,0x60,0xa0,0x14,0x00,0xa4,0x8f,0x68,0x15,0x63,0x25,0x21,0x50,0x60,0x00,
-0x21,0x10,0x83,0x00,0x21,0x10,0x50,0x00,0x99,0x51,0x40,0xa0,0x02,0x80,0x03,0x3c,
-0x02,0x80,0x02,0x3c,0x4c,0x91,0x49,0x24,0xd8,0x90,0x68,0x24,0x21,0x38,0x00,0x00,
-0x80,0x18,0x07,0x00,0x21,0x10,0x69,0x00,0x21,0x20,0x68,0x00,0x00,0x00,0x46,0x8c,
-0x00,0x00,0x85,0x8c,0x01,0x00,0xe7,0x24,0x21,0x18,0x6a,0x00,0x1d,0x00,0xe2,0x28,
-0xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14,0x60,0x45,0x66,0xac,0x14,0x00,0x00,0x12,
-0x68,0x15,0x63,0x25,0x7b,0x51,0x62,0x92,0xff,0xff,0x07,0x26,0x2a,0x10,0xe2,0x00,
-0x0e,0x00,0x40,0x14,0x02,0x80,0x0b,0x3c,0x68,0x15,0x62,0x25,0x21,0x10,0xc2,0x03,
-0x7b,0x51,0x45,0x90,0x74,0x51,0x44,0x8c,0x01,0x00,0x06,0x24,0x04,0x18,0xe6,0x00,
-0x24,0x10,0x83,0x00,0xb3,0x00,0x43,0x10,0x00,0x00,0x00,0x00,0xff,0xff,0xe7,0x24,
-0x2a,0x10,0xe5,0x00,0xfa,0xff,0x40,0x10,0x04,0x18,0xe6,0x00,0x68,0x15,0x63,0x25,
-0x80,0x10,0x10,0x00,0x21,0x10,0x43,0x00,0x60,0x45,0x45,0x8c,0xec,0x44,0x44,0x8c,
-0x02,0x80,0x03,0x3c,0x40,0x10,0x05,0x00,0x8e,0x7d,0x66,0x90,0x21,0x10,0x45,0x00,
-0x21,0x20,0x82,0x00,0x22,0x00,0x02,0x24,0x98,0x00,0xc2,0x10,0x82,0x50,0x04,0x00,
-0xd4,0x51,0x63,0x8e,0x01,0x00,0x02,0x24,0x04,0x10,0x02,0x02,0x25,0x18,0x62,0x00,
-0xd4,0x51,0x63,0xae,0x68,0x15,0x63,0x25,0x21,0x10,0xe3,0x02,0x44,0x51,0x4a,0xac,
-0x8c,0x65,0x64,0x8c,0xff,0xff,0x02,0x34,0x3c,0xff,0x82,0x14,0x21,0x20,0x00,0x02,
-0x39,0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x3e,0xff,0x20,0x11,0x21,0x20,0x00,0x02,
-0x68,0x15,0x62,0x25,0x80,0x18,0x10,0x00,0x21,0x18,0x62,0x00,0x60,0x45,0x64,0x8c,
-0x00,0x00,0x00,0x00,0x2b,0x20,0x44,0x01,0x36,0xff,0x80,0x10,0x21,0x20,0x00,0x02,
-0xa2,0x0f,0x00,0x08,0x68,0x15,0x68,0x25,0x1e,0xff,0x40,0x10,0x68,0x15,0x65,0x25,
-0x21,0x20,0x30,0x02,0x99,0x51,0x83,0x90,0x01,0x00,0x02,0x24,0x63,0x00,0x62,0x10,
-0x02,0x80,0x02,0x3c,0x2c,0x00,0xa3,0x8f,0x68,0x15,0x42,0x24,0x21,0x38,0x00,0x00,
-0x21,0x20,0x62,0x00,0x21,0x18,0x87,0x00,0x01,0x00,0xe7,0x24,0x1d,0x00,0xe2,0x28,
-0xfc,0xff,0x40,0x14,0xb6,0x51,0x60,0xa0,0x28,0x00,0xa3,0x8f,0x02,0x80,0x0b,0x3c,
-0x68,0x15,0x65,0x25,0x21,0x30,0x65,0x00,0xd4,0x51,0xc2,0x8c,0x01,0x00,0x03,0x24,
-0x04,0x18,0x03,0x02,0x27,0x18,0x03,0x00,0x21,0x20,0xd0,0x00,0x24,0x10,0x43,0x00,
-0x99,0x51,0x80,0xa0,0xd4,0x51,0xc2,0xac,0x12,0x00,0x00,0x16,0x7c,0x51,0x80,0xa0,
-0x7a,0x51,0xc2,0x90,0x00,0x00,0x00,0x00,0x0e,0x00,0x40,0x10,0x01,0x00,0x07,0x24,
-0x24,0x00,0xa4,0x8f,0x01,0x00,0x06,0x24,0x21,0x10,0x85,0x00,0x7a,0x51,0x44,0x90,
-0x74,0x51,0x45,0x8c,0x04,0x18,0xe6,0x00,0x24,0x10,0xa3,0x00,0x5b,0x00,0x43,0x10,
-0x00,0x00,0x00,0x00,0x01,0x00,0xe7,0x24,0x2a,0x10,0x87,0x00,0xfa,0xff,0x40,0x10,
-0x04,0x18,0xe6,0x00,0x20,0x00,0xa2,0x8f,0x02,0x80,0x0b,0x3c,0x68,0x15,0x64,0x25,
-0x21,0x18,0x44,0x00,0x7a,0x51,0x62,0x90,0x01,0x00,0x07,0x26,0x2a,0x10,0x47,0x00,
-0x0e,0x00,0x40,0x14,0x01,0x00,0x06,0x24,0x1c,0x00,0xa3,0x8f,0x00,0x00,0x00,0x00,
-0x21,0x10,0x64,0x00,0x7a,0x51,0x45,0x90,0x74,0x51,0x44,0x8c,0x04,0x18,0xe6,0x00,
-0x24,0x10,0x83,0x00,0x42,0x00,0x43,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0xe7,0x24,
-0x2a,0x10,0xa7,0x00,0xfa,0xff,0x40,0x10,0x04,0x18,0xe6,0x00,0x02,0x80,0x02,0x3c,
-0x8e,0x7d,0x44,0x90,0x22,0x00,0x03,0x24,0xd6,0xfe,0x83,0x14,0x68,0x15,0x65,0x25,
-0xee,0xff,0x02,0x26,0xff,0x00,0x42,0x30,0x02,0x00,0x42,0x2c,0x18,0x00,0x03,0x24,
-0x25,0x0f,0x00,0x08,0x0b,0x80,0x62,0x00,0xc0,0x10,0x07,0x00,0x23,0x10,0x47,0x00,
-0xc2,0x10,0x02,0x00,0x2b,0x10,0x48,0x00,0xb6,0xfe,0x40,0x14,0x00,0x00,0x00,0x00,
-0x04,0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x00,0xa3,0x8f,0x5c,0x00,0xbf,0x8f,
-0x58,0x00,0xbe,0x8f,0x54,0x00,0xb7,0x8f,0x50,0x00,0xb6,0x8f,0x4c,0x00,0xb5,0x8f,
-0x48,0x00,0xb4,0x8f,0x44,0x00,0xb3,0x8f,0x40,0x00,0xb2,0x8f,0x3c,0x00,0xb1,0x8f,
-0x38,0x00,0xb0,0x8f,0x25,0xb0,0x02,0x3c,0x80,0x01,0x42,0x34,0x60,0x00,0xbd,0x27,
-0x00,0x00,0x43,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x18,0x00,0x02,0x2e,
-0x0a,0x00,0x40,0x14,0x05,0x00,0x02,0x2e,0xb6,0x51,0x83,0x90,0x00,0x00,0x00,0x00,
-0x05,0x00,0x62,0x2c,0xa0,0xff,0x40,0x10,0x01,0x00,0x62,0x24,0x16,0x10,0x00,0x08,
-0xb6,0x51,0x82,0xa0,0x24,0x0f,0x00,0x08,0x99,0x51,0xa7,0xa0,0x04,0x00,0x40,0x10,
-0x00,0x00,0x00,0x00,0xb6,0x51,0x83,0x90,0x75,0x10,0x00,0x08,0x03,0x00,0x62,0x2c,
-0xb6,0x51,0x83,0x90,0x75,0x10,0x00,0x08,0x04,0x00,0x62,0x2c,0x13,0x00,0x02,0x24,
-0x67,0xff,0x02,0x16,0x68,0x15,0x63,0x25,0xf3,0x0f,0x00,0x08,0x21,0x10,0xe3,0x02,
-0xff,0x00,0xf0,0x30,0x4c,0x10,0x00,0x08,0x02,0x80,0x02,0x3c,0x35,0x10,0x00,0x08,
-0xff,0x00,0xf0,0x30,0xdf,0x0f,0x00,0x08,0xff,0x00,0xf0,0x30,0xd8,0xff,0xbd,0x27,
-0x02,0x80,0x02,0x3c,0x14,0x00,0xb1,0xaf,0x24,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf,
-0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x45,0x24,
-0x05,0x65,0xa4,0x90,0x00,0x65,0xa3,0x8c,0xfc,0x64,0xa2,0x8c,0x21,0x88,0x64,0x00,
-0x2b,0x10,0x22,0x02,0x60,0x00,0x40,0x10,0x21,0x80,0xa0,0x00,0x02,0x80,0x14,0x3c,
-0x21,0x98,0xa0,0x00,0xa8,0x10,0x00,0x08,0x21,0x90,0xa0,0x00,0xfc,0x64,0x42,0x8e,
-0x10,0x00,0x31,0x26,0x2b,0x10,0x22,0x02,0x57,0x00,0x40,0x10,0x21,0x80,0x40,0x02,
-0x05,0x65,0x02,0x92,0xff,0xff,0x23,0x32,0x02,0x80,0x05,0x3c,0x10,0x00,0x42,0x24,
-0x25,0x28,0x65,0x00,0x2c,0x79,0x84,0x26,0x10,0x00,0x06,0x24,0x9f,0x45,0x00,0x0c,
-0x05,0x65,0x02,0xa2,0xc8,0x63,0x06,0x8e,0x00,0x00,0x00,0x00,0x42,0x24,0x06,0x00,
-0x1f,0x00,0x84,0x30,0xc0,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,
-0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x38,0x50,0x00,0x78,0x51,0xe3,0x8c,
-0x00,0x00,0x00,0x00,0x02,0x1b,0x03,0x00,0x01,0x00,0x63,0x30,0xe3,0xff,0x60,0x10,
-0x25,0xb0,0x02,0x3c,0xc4,0x63,0x05,0x8e,0x21,0x10,0x82,0x00,0x60,0x01,0x44,0x90,
-0x82,0x1d,0x05,0x00,0x3f,0x00,0x63,0x30,0x04,0x00,0x0a,0x24,0x05,0x00,0x62,0x28,
-0x21,0x40,0x40,0x01,0x0b,0x40,0x62,0x00,0x07,0x00,0xa0,0x04,0xff,0x00,0x89,0x30,
-0x64,0x51,0xe2,0x8c,0x04,0x00,0x08,0x24,0x01,0x00,0x42,0x24,0x64,0x51,0xe2,0xac,
-0xc8,0x63,0x66,0x8e,0x00,0x00,0x00,0x00,0x02,0x13,0x06,0x00,0x1f,0x00,0x42,0x30,
-0x08,0x00,0x42,0x28,0xcd,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xc4,0x63,0x62,0x8e,
-0x00,0x00,0x00,0x00,0x3f,0x00,0x42,0x30,0xc8,0xff,0x49,0x14,0x00,0x00,0x00,0x00,
-0x29,0x00,0x00,0x11,0x01,0x00,0x02,0x24,0x2e,0x00,0x02,0x11,0x02,0x00,0x02,0x24,
-0x33,0x00,0x02,0x11,0x03,0x00,0x02,0x24,0x38,0x00,0x02,0x11,0x00,0x00,0x00,0x00,
-0x3b,0x00,0x0a,0x11,0x00,0x00,0x00,0x00,0x68,0x51,0xe2,0x8c,0x21,0x18,0x33,0x01,
-0x90,0x44,0x64,0x90,0x02,0x11,0x02,0x00,0x2b,0x10,0x44,0x00,0x3e,0x00,0x40,0x14,
-0x00,0x00,0x00,0x00,0x5c,0x51,0xe3,0x8c,0x80,0x10,0x09,0x00,0x21,0x10,0x49,0x00,
-0x01,0x00,0x63,0x24,0x21,0x10,0x53,0x00,0x5c,0x51,0xe3,0xac,0x21,0x10,0x48,0x00,
-0x34,0x43,0x44,0x90,0x44,0x51,0xe3,0x8c,0x00,0x00,0x00,0x00,0x21,0x18,0x64,0x00,
-0x44,0x51,0xe3,0xac,0xfc,0x64,0x42,0x8e,0x10,0x00,0x31,0x26,0x2b,0x10,0x22,0x02,
-0xab,0xff,0x40,0x14,0x21,0x80,0x40,0x02,0x24,0x00,0xbf,0x8f,0x20,0x00,0xb4,0x8f,
-0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
-0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x48,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00,
-0x01,0x00,0x42,0x24,0x48,0x51,0xe2,0xac,0x01,0x00,0x02,0x24,0xd4,0xff,0x02,0x15,
-0x02,0x00,0x02,0x24,0x4c,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,
-0x4c,0x51,0xe2,0xac,0x02,0x00,0x02,0x24,0xcf,0xff,0x02,0x15,0x03,0x00,0x02,0x24,
-0x50,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0x50,0x51,0xe2,0xac,
-0x03,0x00,0x02,0x24,0xca,0xff,0x02,0x15,0x00,0x00,0x00,0x00,0x54,0x51,0xe2,0x8c,
-0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xc7,0xff,0x0a,0x15,0x54,0x51,0xe2,0xac,
-0x58,0x51,0xe2,0x8c,0x21,0x18,0x33,0x01,0x01,0x00,0x42,0x24,0x58,0x51,0xe2,0xac,
-0x68,0x51,0xe2,0x8c,0x90,0x44,0x64,0x90,0x02,0x11,0x02,0x00,0x2b,0x10,0x44,0x00,
-0xc4,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x60,0x51,0xe3,0x8c,0x80,0x10,0x09,0x00,
-0x21,0x10,0x49,0x00,0x01,0x00,0x63,0x24,0x21,0x10,0x53,0x00,0x60,0x51,0xe3,0xac,
-0x21,0x10,0x48,0x00,0xc5,0x43,0x44,0x90,0x44,0x51,0xe3,0x8c,0x00,0x00,0x00,0x00,
-0x21,0x18,0x64,0x00,0xf9,0x10,0x00,0x08,0x44,0x51,0xe3,0xac,0x25,0xb0,0x02,0x3c,
-0x25,0xb0,0x05,0x3c,0x02,0x80,0x03,0x3c,0x58,0x00,0x4a,0x34,0x5c,0x00,0x4b,0x34,
-0x4c,0x00,0xa2,0x34,0x00,0x00,0x44,0x90,0x68,0x15,0x66,0x24,0xed,0x4a,0xc2,0x90,
-0x29,0xb0,0x07,0x3c,0x03,0x00,0x84,0x30,0x21,0x18,0xc0,0x00,0x0f,0x00,0x44,0x10,
-0x04,0x00,0xe8,0x34,0x07,0x00,0x80,0x14,0x58,0x0c,0xa9,0x34,0xe6,0x42,0xc2,0x90,
-0x1c,0x00,0x06,0x24,0x03,0x00,0x40,0x14,0x50,0x0c,0xa5,0x34,0x00,0x00,0xa6,0xa0,
-0x00,0x00,0x26,0xa1,0x00,0x00,0x42,0x8d,0xed,0x4a,0x64,0xa0,0x00,0x00,0xe2,0xac,
-0x00,0x00,0x62,0x8d,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xad,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x00,0x00,0x25,0xb0,0x0d,0x3c,0xe8,0xff,0xbd,0x27,0x10,0x00,0xbf,0xaf,
-0x2d,0x0a,0xa7,0x35,0xa2,0x0d,0xa2,0x35,0xa4,0x0d,0xa3,0x35,0xa6,0x0d,0xa4,0x35,
-0xa8,0x0d,0xa5,0x35,0x00,0x00,0x48,0x94,0x00,0x00,0x69,0x94,0x00,0x00,0x8a,0x94,
-0x00,0x00,0xab,0x94,0x00,0x00,0xe3,0x90,0x5b,0x0a,0xa4,0x35,0x5c,0x0a,0xa6,0x35,
-0x00,0x2e,0x03,0x00,0x03,0x2e,0x05,0x00,0x40,0x00,0xa2,0x34,0x00,0x00,0xe2,0xa0,
-0x00,0x00,0x85,0x90,0x00,0x00,0xc3,0x90,0x02,0x80,0x0e,0x3c,0x68,0x15,0xcc,0x25,
-0xff,0xff,0x22,0x31,0xff,0x00,0xa5,0x30,0xff,0xff,0x04,0x31,0x21,0x20,0x82,0x00,
-0xff,0x00,0x63,0x30,0x00,0x40,0x87,0x8d,0x00,0x2a,0x05,0x00,0xff,0xff,0x46,0x31,
-0x21,0x28,0xa3,0x00,0xff,0xff,0x62,0x31,0x21,0x20,0x86,0x00,0x21,0x20,0x82,0x00,
-0xff,0xff,0xa3,0x30,0x64,0x0c,0xa2,0x35,0x00,0x00,0x45,0xa4,0x21,0x20,0x83,0x00,
-0x0f,0x00,0xe7,0x30,0x01,0x00,0x02,0x24,0xe0,0x42,0x84,0xad,0xd8,0x42,0x88,0xa5,
-0xda,0x42,0x89,0xa5,0xdc,0x42,0x8a,0xa5,0xde,0x42,0x8b,0xa5,0x07,0x00,0xe2,0x10,
-0xe4,0x42,0x85,0xa5,0xa8,0x56,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f,
-0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x4c,0x00,0xa3,0x35,
-0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30,0x67,0x00,0x47,0x10,
-0x68,0x15,0xc4,0x25,0xe6,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x2d,0x00,0x40,0x10,
-0x01,0x00,0x03,0x24,0x68,0x15,0xc5,0x25,0xe6,0x42,0xa3,0x90,0xff,0x00,0x02,0x24,
-0xec,0xff,0x62,0x14,0x25,0xb0,0x03,0x3c,0xc8,0x42,0xa2,0x94,0xe0,0x42,0xa6,0x8c,
-0x50,0x0c,0x63,0x34,0x00,0x00,0x64,0x90,0x2b,0x10,0xc2,0x00,0x5e,0x00,0x40,0x14,
-0x7f,0x00,0x84,0x30,0xca,0x42,0xa2,0x94,0x00,0x00,0x00,0x00,0x2b,0x10,0xc2,0x00,
-0x09,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xcc,0x42,0xa2,0x94,0x00,0x00,0x00,0x00,
-0x2b,0x10,0xc2,0x00,0x02,0x00,0x40,0x10,0x02,0x00,0x82,0x24,0x01,0x00,0x82,0x24,
-0xff,0x00,0x44,0x30,0x68,0x15,0xc5,0x25,0xd0,0x42,0xa3,0x90,0x00,0x00,0x00,0x00,
-0x2b,0x10,0x64,0x00,0x4e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x21,0x20,0x60,0x00,
-0x68,0x15,0xc3,0x25,0xe0,0x42,0x62,0x8c,0x00,0x00,0x00,0x00,0xe9,0x03,0x42,0x2c,
-0x02,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0xd0,0x42,0x64,0x90,0x58,0x0c,0x43,0x34,
-0x50,0x0c,0x42,0x34,0x00,0x00,0x44,0xa0,0x00,0x00,0x64,0xa0,0x85,0x11,0x00,0x08,
-0x00,0x00,0x00,0x00,0x00,0x40,0x82,0x8c,0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,
-0x0f,0x00,0x42,0x30,0xd0,0xff,0x43,0x14,0x68,0x15,0xc5,0x25,0x25,0xb0,0x02,0x3c,
-0x4c,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x63,0x30,
-0xb8,0xff,0x60,0x10,0xff,0xff,0x02,0x34,0xdc,0x63,0x83,0x8c,0x00,0x00,0x00,0x00,
-0xb4,0xff,0x62,0x10,0x00,0x00,0x00,0x00,0xe0,0x42,0x83,0x8c,0x00,0x00,0x00,0x00,
-0x65,0x00,0x62,0x2c,0x3b,0x00,0x40,0x14,0x28,0x00,0x62,0x2c,0xd2,0x42,0x83,0x90,
-0x00,0x00,0x00,0x00,0x00,0x16,0x03,0x00,0x03,0x16,0x02,0x00,0xfe,0xff,0x42,0x24,
-0xfc,0xff,0x42,0x28,0x02,0x00,0x40,0x10,0xfe,0xff,0x62,0x24,0xfc,0xff,0x02,0x24,
-0xd2,0x42,0x82,0xa0,0x68,0x15,0xc4,0x25,0xdc,0x63,0x82,0x8c,0xd2,0x42,0x83,0x90,
-0xce,0x42,0x86,0x90,0x02,0x11,0x02,0x00,0x7f,0x00,0x42,0x30,0x0a,0x00,0x45,0x24,
-0x23,0x18,0xa3,0x00,0x00,0x2e,0x03,0x00,0x03,0x2e,0x05,0x00,0xff,0x00,0xc2,0x30,
-0x2a,0x10,0x45,0x00,0x17,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x00,0x2e,0x06,0x00,
-0x03,0x2e,0x05,0x00,0x58,0x0c,0x43,0x34,0x50,0x0c,0x42,0x34,0x00,0x00,0x45,0xa0,
-0x00,0x00,0x65,0xa0,0x85,0x11,0x00,0x08,0x00,0x00,0x00,0x00,0xe6,0x42,0x82,0x91,
-0x00,0x00,0x00,0x00,0x97,0xff,0x40,0x14,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x24,
-0x91,0x11,0x00,0x08,0xe6,0x42,0x82,0xa1,0xac,0x11,0x00,0x08,0xff,0xff,0x82,0x24,
-0xd1,0x42,0xa3,0x90,0x00,0x00,0x00,0x00,0x2b,0x10,0x83,0x00,0xb4,0x11,0x00,0x08,
-0x0b,0x20,0x62,0x00,0xcf,0x42,0x83,0x80,0x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30,
-0x2a,0x10,0xa2,0x00,0x0b,0x28,0x62,0x00,0x25,0xb0,0x02,0x3c,0x58,0x0c,0x43,0x34,
-0x50,0x0c,0x42,0x34,0x00,0x00,0x45,0xa0,0x00,0x00,0x65,0xa0,0x85,0x11,0x00,0x08,
-0x00,0x00,0x00,0x00,0xcf,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xd2,0x42,0x83,0x90,
-0x00,0x00,0x00,0x00,0x00,0x16,0x03,0x00,0x03,0x16,0x02,0x00,0x02,0x00,0x42,0x24,
-0x0d,0x00,0x42,0x28,0x03,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xe0,0x11,0x00,0x08,
-0x0c,0x00,0x02,0x24,0xe0,0x11,0x00,0x08,0x02,0x00,0x62,0x24,0xc0,0xff,0xbd,0x27,
-0x18,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,
-0x1c,0x00,0xb1,0xaf,0x3c,0x00,0xbf,0xaf,0x38,0x00,0xbe,0xaf,0x34,0x00,0xb7,0xaf,
-0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x20,0x00,0xb2,0xaf,0xd8,0x00,0x06,0x36,
-0x00,0x00,0xc3,0x90,0x02,0x80,0x02,0x3c,0x68,0x15,0x54,0x24,0x2a,0xb0,0x11,0x3c,
-0xa0,0xff,0x02,0x24,0x25,0x18,0x62,0x00,0x34,0x00,0x25,0x36,0xfe,0xff,0x02,0x24,
-0xbc,0x42,0x92,0x92,0x40,0x00,0x04,0x24,0x00,0x00,0xc3,0xa0,0x00,0x00,0xa2,0xa0,
-0xa1,0x4e,0x00,0x0c,0x00,0x96,0x12,0x00,0x21,0x98,0x40,0x00,0x6b,0x00,0x60,0x12,
-0x00,0x40,0x02,0x3c,0x08,0x00,0x63,0x8e,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02,
-0x00,0x00,0x43,0xac,0x3a,0x45,0x00,0x0c,0x21,0xb8,0x80,0x02,0x01,0x00,0x1e,0x24,
-0x42,0x00,0x16,0x36,0x03,0x0c,0x11,0x36,0x17,0x0e,0x15,0x36,0x04,0x00,0x14,0x24,
-0x2a,0xb0,0x03,0x3c,0x06,0x00,0x63,0x34,0x00,0x00,0x62,0x94,0x00,0x00,0x00,0x00,
-0x00,0xff,0x42,0x30,0x0a,0x00,0x40,0x18,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,
-0xc8,0x94,0x84,0x24,0x00,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x94,
-0x00,0x00,0x00,0x00,0x00,0xff,0x42,0x30,0xfc,0xff,0x40,0x1c,0x00,0x00,0x00,0x00,
-0x08,0x00,0x65,0x8e,0x20,0x10,0x06,0x3c,0x00,0xfe,0xc6,0x34,0x40,0x00,0x07,0x24,
-0x01,0x00,0x04,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xbe,0xaf,0x4d,0x01,0x00,0x0c,
-0x01,0x00,0x04,0x24,0x2a,0xb0,0x02,0x3c,0x05,0x00,0x42,0x34,0xff,0xff,0x03,0x24,
-0x00,0x00,0x5e,0xa0,0x00,0x00,0xc3,0xa2,0x00,0x00,0x22,0x92,0xc1,0x42,0xe5,0x92,
-0x2a,0xb0,0x04,0x3c,0x02,0x00,0x03,0x24,0x40,0x00,0x42,0x34,0x05,0x00,0x84,0x34,
-0x00,0x00,0x22,0xa2,0x00,0x00,0x83,0xa0,0xef,0xff,0x02,0x24,0x00,0x00,0xb0,0x92,
-0x64,0x00,0x04,0x24,0x00,0x00,0xa5,0xa2,0x00,0x00,0xc2,0xa2,0xb3,0x0a,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x92,0xbf,0xff,0x03,0x24,0x84,0x03,0x04,0x24,
-0x24,0x10,0x43,0x00,0x00,0x00,0x22,0xa2,0xb3,0x0a,0x00,0x0c,0xff,0x00,0x10,0x32,
-0x25,0xb0,0x02,0x3c,0xf4,0x08,0x42,0x34,0x00,0x00,0x44,0x8c,0x00,0x00,0xb0,0xa2,
-0x00,0x00,0xc0,0xa2,0x00,0x00,0x22,0x92,0xbe,0x42,0xe3,0x92,0x1f,0x00,0x85,0x30,
-0x40,0x00,0x42,0x34,0x00,0x00,0x22,0xa2,0x00,0x80,0x02,0x3c,0xdf,0x07,0x42,0x34,
-0x2b,0x18,0xa3,0x00,0x09,0x00,0x60,0x10,0x24,0x20,0x82,0x00,0xbf,0x42,0xe2,0x92,
-0x00,0x00,0x00,0x00,0x2b,0x10,0x45,0x00,0x05,0x00,0x40,0x10,0x02,0x80,0x02,0x3c,
-0x01,0x00,0x02,0x3c,0x25,0x10,0xa2,0x00,0x21,0x90,0x42,0x02,0x02,0x80,0x02,0x3c,
-0x8e,0x7d,0x43,0x90,0x22,0x00,0x02,0x24,0x1c,0x00,0x62,0x10,0x92,0x00,0x02,0x24,
-0x1b,0x00,0x62,0x10,0x02,0x80,0x03,0x3c,0xff,0xff,0x94,0x26,0xb3,0x0a,0x00,0x0c,
-0xf4,0x01,0x04,0x24,0xab,0xff,0x81,0x06,0x2a,0xb0,0x03,0x3c,0x04,0x00,0x60,0x12,
-0x25,0xb0,0x02,0x3c,0xbd,0x4e,0x00,0x0c,0x21,0x20,0x60,0x02,0x25,0xb0,0x02,0x3c,
-0xd8,0x02,0x42,0x34,0x00,0x00,0x52,0xac,0x21,0x10,0x40,0x02,0x3c,0x00,0xbf,0x8f,
-0x38,0x00,0xbe,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,
-0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,
-0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x40,0x00,0xbd,0x27,0x02,0x80,0x03,0x3c,
-0x68,0x15,0x63,0x24,0xbe,0x42,0x62,0x90,0xc0,0x07,0x83,0x30,0x82,0x19,0x03,0x00,
-0x2b,0x10,0x62,0x00,0xe0,0xff,0x40,0x10,0x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24,
-0xbf,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x2b,0x10,0x43,0x00,0xda,0xff,0x40,0x10,
-0x00,0x12,0x03,0x00,0x10,0x00,0x03,0x3c,0x25,0x10,0x43,0x00,0x9a,0x12,0x00,0x08,
-0x21,0x90,0x42,0x02,0xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x0f,0x00,0x10,0x3c,
-0xff,0xff,0x05,0x36,0xf0,0xf8,0x06,0x34,0x14,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c,
-0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,
-0x56,0x30,0x06,0x24,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,
-0x64,0x00,0x04,0x24,0x02,0x80,0x0b,0x3c,0x68,0x15,0x64,0x25,0x04,0x43,0x83,0x90,
-0x04,0x00,0x02,0x24,0x19,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c,0x14,0x43,0x8a,0x8c,
-0x18,0x43,0x88,0x8c,0x25,0xb0,0x02,0x3c,0x1c,0x0e,0x49,0x34,0x00,0x0e,0x43,0x34,
-0x04,0x0e,0x44,0x34,0x08,0x0e,0x45,0x34,0x10,0x0e,0x46,0x34,0x14,0x0e,0x47,0x34,
-0x18,0x0e,0x42,0x34,0x00,0x00,0x6a,0xac,0x00,0x00,0x8a,0xac,0x00,0x00,0xa8,0xac,
-0x00,0x00,0xca,0xac,0x00,0x00,0xea,0xac,0x00,0x00,0x4a,0xac,0x00,0x00,0x2a,0xad,
-0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x68,0x15,0x63,0x25,0x04,0x00,0x02,0x24,
-0x18,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x62,0xa0,0x00,0x0e,0x42,0x34,
-0x00,0x00,0x43,0x8c,0x14,0x43,0x8a,0x8c,0x00,0x00,0x00,0x00,0xe4,0xff,0x6a,0x14,
-0x00,0x00,0x00,0x00,0xec,0x12,0x00,0x08,0x00,0x00,0x00,0x00,0xe8,0xff,0xbd,0x27,
-0x10,0x00,0xb0,0xaf,0x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0xf0,0xf8,0x06,0x34,
-0x14,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c,0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,
-0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,0x56,0x30,0x06,0x24,0xba,0x44,0x00,0x0c,
-0x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x02,0x80,0x04,0x3c,
-0x68,0x15,0x83,0x24,0x04,0x43,0x65,0x90,0x21,0x70,0x60,0x00,0x10,0x10,0x03,0x3c,
-0x25,0xb0,0x02,0x3c,0x10,0x10,0x66,0x34,0x01,0x00,0x03,0x24,0x1c,0x0e,0x4d,0x34,
-0x00,0x0e,0x4a,0x34,0x04,0x0e,0x4b,0x34,0x08,0x0e,0x4c,0x34,0x10,0x0e,0x47,0x34,
-0x14,0x0e,0x48,0x34,0x0f,0x00,0xa3,0x10,0x18,0x0e,0x49,0x34,0x10,0x10,0x02,0x24,
-0x00,0x00,0x46,0xad,0x00,0x00,0x66,0xad,0x00,0x00,0x82,0xad,0x00,0x00,0xe6,0xac,
-0x00,0x00,0x06,0xad,0x00,0x00,0x26,0xad,0x00,0x00,0xa6,0xad,0x14,0x00,0xbf,0x8f,
-0x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,0x18,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,
-0x04,0x43,0xc2,0xa1,0x00,0x00,0x44,0x8d,0x00,0x00,0x00,0x00,0xf0,0xff,0x86,0x14,
-0x10,0x10,0x02,0x24,0x23,0x13,0x00,0x08,0x00,0x00,0x00,0x00,0xe0,0xff,0xbd,0x27,
-0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x01,0x00,0x11,0x3c,0x0f,0x00,0x10,0x3c,
-0xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0x18,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c,
-0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,
-0x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0x02,0x80,0x10,0x3c,
-0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x68,0x15,0x04,0x26,0x04,0x43,0x82,0x90,
-0x00,0x00,0x00,0x00,0x0d,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0x00,0x0e,0x42,0x34,
-0x00,0x00,0x43,0x8c,0xec,0x42,0x8f,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x6f,0x14,
-0x68,0x15,0x02,0x26,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
-0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x40,0xa0,0xec,0x42,0x8f,0x8c,
-0xe8,0x42,0x88,0x8c,0xf0,0x42,0x8a,0x8c,0xf4,0x42,0x8b,0x8c,0xf8,0x42,0x8c,0x8c,
-0xfc,0x42,0x8d,0x8c,0x25,0xb0,0x02,0x3c,0x00,0x43,0x8e,0x8c,0x1c,0x0e,0x49,0x34,
-0x08,0x0e,0x43,0x34,0x00,0x0e,0x44,0x34,0x04,0x0e,0x45,0x34,0x10,0x0e,0x46,0x34,
-0x14,0x0e,0x47,0x34,0x18,0x0e,0x42,0x34,0x00,0x00,0x68,0xac,0x18,0x00,0xbf,0x8f,
-0x00,0x00,0x8f,0xac,0x14,0x00,0xb1,0x8f,0x00,0x00,0xaa,0xac,0x00,0x00,0xcb,0xac,
-0x00,0x00,0xec,0xac,0x00,0x00,0x4d,0xac,0x68,0x15,0x02,0x26,0x10,0x00,0xb0,0x8f,
-0x20,0x00,0xbd,0x27,0x00,0x00,0x2e,0xad,0x08,0x00,0xe0,0x03,0x04,0x43,0x40,0xa0,
-0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x01,0x00,0x11,0x3c,
-0x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0x18,0x00,0xbf,0xaf,
-0xba,0x44,0x00,0x0c,0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,
-0xff,0xff,0x05,0x36,0x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,
-0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x02,0x80,0x18,0x3c,0x68,0x15,0x05,0x27,
-0x04,0x43,0xa3,0x90,0x03,0x00,0x02,0x24,0x2a,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c,
-0xec,0x42,0xaf,0x8c,0x08,0x43,0xa3,0x8c,0xe8,0x42,0xa2,0x8c,0xf0,0x42,0xac,0x8c,
-0xf4,0x42,0xad,0x8c,0xf8,0x42,0xa9,0x8c,0xfc,0x42,0xaa,0x8c,0x00,0x43,0xab,0x8c,
-0x21,0x70,0x43,0x00,0xff,0xff,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xff,0x00,0x42,0x34,
-0x00,0xff,0xc4,0x31,0x04,0x0e,0x65,0x34,0x10,0x0e,0x66,0x34,0x14,0x0e,0x67,0x34,
-0x18,0x0e,0x68,0x34,0x24,0x80,0xc2,0x01,0x08,0x0e,0x71,0x34,0x00,0x0e,0x62,0x34,
-0x01,0x3f,0x84,0x2c,0x1c,0x0e,0x63,0x34,0x00,0x00,0x4f,0xac,0x00,0x00,0xac,0xac,
-0x00,0x00,0xcd,0xac,0x00,0x00,0xe9,0xac,0x00,0x00,0x0a,0xad,0x00,0x00,0x6b,0xac,
-0x0a,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0xae,0x18,0x00,0xbf,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x68,0x15,0x03,0x27,0x03,0x00,0x02,0x24,
-0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x62,0xa0,0xa6,0x13,0x00,0x08,
-0x00,0x3f,0x0e,0x36,0x00,0x0e,0x42,0x34,0x00,0x00,0x43,0x8c,0xec,0x42,0xaf,0x8c,
-0x00,0x00,0x00,0x00,0xd3,0xff,0x6f,0x14,0x00,0x00,0x00,0x00,0xa7,0x13,0x00,0x08,
-0x00,0x00,0x00,0x00,0xd0,0xff,0xbd,0x27,0x18,0x00,0xb2,0xaf,0x02,0x80,0x12,0x3c,
-0x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x28,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,
-0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x44,0x26,0x02,0x80,0x14,0x3c,
-0x00,0x40,0x85,0x8c,0xdc,0x63,0x83,0x8c,0x8e,0x7d,0x86,0x92,0x25,0xb0,0x02,0x3c,
-0x0f,0x0c,0x42,0x34,0x00,0x00,0x46,0xa0,0x02,0x19,0x03,0x00,0xf0,0xf0,0xa5,0x30,
-0x00,0x10,0x02,0x24,0x04,0x43,0x93,0x90,0x71,0x00,0xa2,0x10,0x7f,0x00,0x75,0x30,
-0x25,0xb0,0x09,0x3c,0x4c,0x00,0x23,0x35,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,
-0x03,0x00,0x42,0x30,0x09,0x00,0x40,0x10,0x68,0x15,0x45,0x26,0x68,0x15,0x4a,0x26,
-0x00,0x40,0x42,0x8d,0x00,0x00,0x00,0x00,0x02,0x13,0x02,0x00,0x0f,0x00,0x42,0x30,
-0x33,0x00,0x40,0x10,0x00,0x0e,0x25,0x35,0x68,0x15,0x45,0x26,0x04,0x43,0xa2,0x8c,
-0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x0f,0x00,0x40,0x14,0x68,0x15,0x4a,0x26,
-0x25,0xb0,0x02,0x3c,0x84,0x01,0x42,0x34,0x00,0x00,0x44,0x8c,0x0d,0x00,0x03,0x24,
-0x7e,0x00,0x83,0x10,0x3e,0x00,0x02,0x24,0x4a,0x00,0x03,0x24,0x1f,0x43,0xa2,0xa0,
-0x1c,0x43,0xa3,0xa0,0x45,0x00,0x02,0x24,0x43,0x00,0x03,0x24,0x1d,0x43,0xa2,0xa0,
-0x1e,0x43,0xa3,0xa0,0x68,0x15,0x4a,0x26,0xdc,0x63,0x4c,0x8d,0x04,0x40,0x42,0x8d,
-0x00,0x40,0x4b,0x8d,0x1e,0x43,0x4d,0x91,0x1c,0x43,0x4e,0x91,0x25,0xb0,0x09,0x3c,
-0x02,0x11,0x02,0x00,0x60,0x0c,0x27,0x35,0x02,0x19,0x0c,0x00,0x98,0x0c,0x24,0x35,
-0x00,0x00,0xe3,0xa0,0x66,0x0c,0x25,0x35,0x00,0x00,0x82,0xa0,0x67,0x0c,0x26,0x35,
-0xf0,0xf0,0x68,0x31,0x10,0x10,0x02,0x24,0x00,0x00,0xad,0xa0,0x00,0x00,0xce,0xa0,
-0x43,0x00,0x02,0x11,0xff,0xff,0x02,0x34,0x28,0x00,0xbf,0x8f,0x24,0x00,0xb5,0x8f,
-0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,
-0x00,0x00,0xa2,0x8c,0x00,0x00,0x00,0x00,0x5d,0x00,0x40,0x10,0x10,0x0e,0x28,0x35,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x08,0x0e,0x22,0x35,0x04,0x0e,0x24,0x35,0x00,0x00,0x43,0x8c,0x00,0x00,0xa5,0x8c,
-0x00,0x00,0x82,0x8c,0xe8,0x42,0x43,0xad,0xec,0x42,0x45,0xad,0xf0,0x42,0x42,0xad,
-0x14,0x0e,0x24,0x35,0x18,0x0e,0x22,0x35,0x1c,0x0e,0x25,0x35,0x00,0x00,0x08,0x8d,
-0x8e,0x7d,0x8b,0x92,0x00,0x00,0x86,0x8c,0x00,0xff,0x63,0x30,0x00,0x00,0x47,0x8c,
-0x00,0x00,0xa4,0x8c,0x9a,0x0c,0x22,0x35,0x02,0x1a,0x03,0x00,0x00,0x00,0x43,0xa0,
-0x22,0x00,0x02,0x24,0xf4,0x42,0x48,0xad,0xf8,0x42,0x46,0xad,0xfc,0x42,0x47,0xad,
-0x58,0x00,0x62,0x11,0x00,0x43,0x44,0xad,0x92,0x00,0x02,0x24,0x56,0x00,0x62,0x11,
-0x0d,0x08,0x22,0x35,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x68,0x15,0x44,0x26,0x00,0x40,0x83,0x8c,0xff,0xff,0x02,0x3c,0xff,0x0f,0x42,0x34,
-0x24,0x18,0x62,0x00,0x00,0x10,0x63,0x34,0xde,0x13,0x00,0x08,0x00,0x40,0x83,0xac,
-0x01,0x00,0x02,0x24,0x35,0x00,0x62,0x12,0x04,0x00,0x02,0x24,0x33,0x00,0x62,0x12,
-0x68,0x15,0x43,0x26,0xff,0xff,0x02,0x24,0xd0,0x13,0x00,0x08,0x04,0x43,0x62,0xa0,
-0xbd,0xff,0x82,0x11,0x02,0x12,0x0b,0x00,0x0f,0x00,0x48,0x30,0x01,0x00,0x03,0x24,
-0xb9,0xff,0x03,0x15,0x4c,0x00,0x23,0x35,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,
-0x03,0x00,0x42,0x30,0xb4,0xff,0x40,0x10,0x03,0x00,0x02,0x24,0x5f,0x00,0x62,0x12,
-0x04,0x00,0x62,0x2a,0x45,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x64,0x00,0x60,0x12,
-0xff,0x00,0xa2,0x31,0xac,0xff,0x68,0x16,0xff,0x00,0xc2,0x31,0x2b,0x10,0xa2,0x02,
-0x52,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x1f,0x43,0x42,0x91,0x00,0x00,0x00,0x00,
-0x2b,0x10,0x55,0x00,0x44,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x2f,0x13,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x3b,0x00,0x02,0x24,
-0x46,0x00,0x03,0x24,0x1f,0x43,0xa2,0xa0,0x1c,0x43,0xa3,0xa0,0x41,0x00,0x02,0x24,
-0x40,0x00,0x03,0x24,0x1d,0x43,0xa2,0xa0,0xf1,0x13,0x00,0x08,0x1e,0x43,0xa3,0xa0,
-0x00,0x00,0x03,0x8d,0x3f,0x3f,0x02,0x3c,0x3f,0x3f,0x42,0x34,0xa0,0xff,0x62,0x14,
-0x00,0x00,0x00,0x00,0xdf,0x13,0x00,0x08,0x68,0x15,0x45,0x26,0x0f,0x00,0x10,0x3c,
-0x01,0x00,0x11,0x3c,0xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0xba,0x44,0x00,0x0c,
-0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,
-0x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,
-0x64,0x00,0x04,0x24,0x68,0x15,0x43,0x26,0xff,0xff,0x02,0x24,0xd0,0x13,0x00,0x08,
-0x04,0x43,0x62,0xa0,0x0d,0x08,0x22,0x35,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,
-0x0f,0x00,0x63,0x30,0x08,0x00,0x62,0x2c,0x0f,0x00,0x63,0x38,0xa5,0xff,0x40,0x14,
-0x01,0x00,0x65,0x24,0x00,0x16,0x05,0x00,0x00,0x24,0x05,0x00,0x00,0x1a,0x05,0x00,
-0x25,0x10,0x44,0x00,0x25,0x10,0x43,0x00,0x25,0x10,0x45,0x00,0x25,0x18,0x65,0x00,
-0x18,0x43,0x43,0xad,0x35,0x14,0x00,0x08,0x14,0x43,0x42,0xad,0x04,0x00,0x02,0x24,
-0x0d,0x00,0x62,0x12,0xff,0x00,0x02,0x24,0x67,0xff,0x62,0x16,0xff,0x00,0xa2,0x31,
-0x2b,0x10,0xa2,0x02,0x1d,0x00,0x40,0x14,0xff,0x00,0xc2,0x31,0x2b,0x10,0xa2,0x02,
-0x0a,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xfb,0x12,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x1d,0x43,0x42,0x91,0x00,0x00,0x00,0x00,
-0x2b,0x10,0x55,0x00,0xf8,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xc5,0x12,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x20,0x43,0x42,0x91,
-0x00,0x00,0x00,0x00,0x2b,0x10,0xa2,0x02,0xac,0xff,0x40,0x10,0x00,0x00,0x00,0x00,
-0x70,0x13,0x00,0x0c,0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,
-0x2b,0x10,0xa2,0x02,0xe8,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x21,0x43,0x42,0x91,
-0x00,0x00,0x00,0x00,0x2b,0x10,0x55,0x00,0xa0,0xff,0x40,0x14,0x00,0x00,0x00,0x00,
-0x70,0x13,0x00,0x0c,0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,
-0x02,0x80,0x08,0x3c,0x68,0x15,0x05,0x25,0xdc,0x63,0xa4,0x8c,0xe6,0x42,0xa3,0x90,
-0x02,0x11,0x04,0x00,0x1f,0x00,0x60,0x14,0x7f,0x00,0x46,0x30,0x25,0xb0,0x07,0x3c,
-0x4c,0x00,0xe2,0x34,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x19,0x00,0x60,0x10,
-0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x34,0x16,0x00,0x82,0x10,0x00,0x00,0x00,0x00,
-0x00,0x08,0xe3,0x34,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30,
-0x12,0x00,0x40,0x10,0x4b,0x00,0xc2,0x2c,0x29,0x00,0x40,0x10,0x01,0x00,0x04,0x24,
-0xd8,0xff,0xc2,0x24,0x1e,0x00,0x42,0x2c,0x2f,0x00,0x40,0x10,0x23,0x00,0xc2,0x2c,
-0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x29,0x00,0x40,0x10,
-0x25,0xb0,0x02,0x3c,0x20,0x00,0x03,0x24,0x87,0x0c,0x42,0x34,0x00,0x00,0x43,0xa0,
-0xd3,0x42,0x80,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x0f,0x00,0x40,0x10,
-0x01,0x00,0x04,0x24,0xd8,0xff,0xc2,0x24,0x1e,0x00,0x42,0x2c,0x2c,0x00,0x40,0x10,
-0x23,0x00,0xc2,0x2c,0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x00,0x00,0x00,0x00,
-0x26,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x44,0x00,0x03,0x24,0x30,0x0c,0x42,0x34,
-0x00,0x00,0x43,0xa0,0xed,0x14,0x00,0x08,0xd3,0x42,0x80,0xa0,0xd3,0x42,0xa2,0x90,
-0x00,0x00,0x00,0x00,0xef,0xff,0x44,0x10,0x30,0x0c,0xe3,0x34,0x43,0x00,0x02,0x24,
-0xd3,0x42,0xa4,0xa0,0x00,0x00,0x62,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0xd3,0x42,0xa2,0x90,0x00,0x00,0x00,0x00,0xd5,0xff,0x44,0x10,0x87,0x0c,0xe3,0x34,
-0x10,0x00,0x02,0x24,0xd3,0x42,0xa4,0xa0,0x00,0x00,0x62,0xa0,0x06,0x15,0x00,0x08,
-0x00,0x00,0x00,0x00,0x23,0x00,0xc2,0x2c,0xda,0xff,0x40,0x10,0x00,0x00,0x00,0x00,
-0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x02,0x00,0x03,0x24,0xd5,0xff,0x43,0x10,
-0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,0x87,0x0c,0x42,0x34,0xd3,0x42,0x83,0xa0,
-0x00,0x00,0x40,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x23,0x00,0xc2,0x2c,
-0xcc,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,
-0x02,0x00,0x03,0x24,0xc7,0xff,0x43,0x10,0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,
-0xd3,0x42,0x83,0xa0,0x30,0x0c,0x42,0x34,0x42,0x00,0x03,0x24,0x00,0x00,0x43,0xa0,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x45,0x24,
-0xd5,0x42,0xa3,0x90,0x02,0x00,0x02,0x24,0x03,0x00,0x62,0x10,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0xdc,0x63,0xa2,0x8c,0x25,0xb0,0x03,0x3c,
-0x0a,0x0a,0x68,0x34,0x02,0x11,0x02,0x00,0x7f,0x00,0x42,0x30,0x1a,0x00,0x44,0x2c,
-0x14,0x00,0x42,0x2c,0x01,0x0a,0x66,0x34,0x0b,0x00,0x40,0x14,0x2e,0x0a,0x67,0x34,
-0xf3,0xff,0x80,0x14,0x00,0x00,0x00,0x00,0xd4,0x42,0xa4,0x90,0x01,0x00,0x02,0x24,
-0x01,0x0a,0x67,0x34,0x0f,0x00,0x82,0x10,0x2e,0x0a,0x66,0x34,0xd4,0x42,0xa0,0xa0,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x40,0x00,0x02,0x24,0x00,0x00,0xc2,0xa0,
-0x01,0x00,0x03,0x24,0xdf,0xff,0x02,0x24,0xd4,0x42,0xa3,0xa0,0x00,0x00,0xe2,0xa0,
-0x03,0x00,0x03,0x24,0x21,0x10,0x00,0x00,0x00,0x00,0x03,0xa1,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x47,0x00,0x02,0x24,0x00,0x00,0xe2,0xa0,0xd3,0xff,0x03,0x24,
-0x83,0xff,0x02,0x24,0x00,0x00,0xc3,0xa0,0x00,0x00,0x02,0xa1,0x48,0x15,0x00,0x08,
-0xd4,0x42,0xa0,0xa0,0xd0,0xff,0xbd,0x27,0x1c,0x00,0xb1,0xaf,0x28,0x00,0xbf,0xaf,
-0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf,0xff,0xff,0x11,0x24,
-0x02,0x80,0x13,0x3c,0x41,0xb0,0x02,0x3c,0x68,0x15,0x66,0x26,0x04,0x00,0x42,0x34,
-0x00,0x00,0x47,0x8c,0x00,0x4b,0xc5,0x8c,0x02,0x80,0x03,0x3c,0x96,0x7d,0x64,0x90,
-0xfc,0x4a,0xc8,0x8c,0x02,0x80,0x02,0x3c,0xb8,0x7d,0x49,0x90,0x25,0xb0,0x0a,0x3c,
-0x25,0x90,0xa7,0x00,0xb0,0x03,0x42,0x35,0x00,0x00,0x52,0xac,0x00,0x24,0x04,0x00,
-0x00,0x00,0x48,0xac,0x84,0x02,0x43,0x35,0x8c,0x02,0x45,0x35,0x01,0x00,0x02,0x24,
-0x00,0x00,0x72,0xac,0x00,0x00,0xa4,0xac,0xb9,0x04,0x22,0x11,0x00,0x4b,0xd2,0xac,
-0x68,0x15,0x66,0x26,0xfc,0x4a,0xc2,0x8c,0x00,0x00,0x00,0x00,0x24,0x28,0x52,0x00,
-0x01,0x00,0xa3,0x30,0x09,0x00,0x60,0x10,0x04,0x00,0xa2,0x30,0x00,0x4b,0xc2,0x8c,
-0x25,0xb0,0x03,0x3c,0x01,0x00,0x04,0x24,0x01,0x00,0x42,0x38,0xb0,0x03,0x63,0x34,
-0x00,0x00,0x64,0xac,0x00,0x4b,0xc2,0xac,0x04,0x00,0xa2,0x30,0x09,0x00,0x40,0x10,
-0x08,0x00,0xa2,0x30,0x00,0x4b,0xc2,0x8c,0x25,0xb0,0x03,0x3c,0x04,0x00,0x04,0x24,
-0x04,0x00,0x42,0x38,0xb0,0x03,0x63,0x34,0x00,0x00,0x64,0xac,0x00,0x4b,0xc2,0xac,
-0x08,0x00,0xa2,0x30,0x0e,0x00,0x40,0x10,0x68,0x15,0x64,0x26,0xc9,0x64,0xc2,0x90,
-0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,
-0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0xc0,0xa0,0x00,0x4b,0xc2,0x8c,
-0x00,0x00,0x00,0x00,0x08,0x00,0x42,0x38,0x00,0x4b,0xc2,0xac,0x68,0x15,0x64,0x26,
-0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x10,0x00,0x42,0x30,
-0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,
-0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,
-0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,
-0x10,0x00,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,
-0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x20,0x00,0x42,0x30,0x0e,0x00,0x40,0x10,
-0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,
-0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,
-0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x20,0x00,0x42,0x38,
-0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,
-0x24,0x10,0x52,0x00,0x40,0x00,0x42,0x30,0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
-0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,
-0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,
-0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x40,0x00,0x42,0x38,0x00,0x4b,0x82,0xac,
-0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,
-0x80,0x00,0x42,0x30,0x0e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,
-0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,
-0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,
-0x00,0x00,0x00,0x00,0x80,0x00,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,
-0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x01,0x42,0x30,
-0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,
-0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,
-0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,
-0x00,0x01,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,
-0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x02,0x42,0x30,0x0e,0x00,0x40,0x10,
-0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,
-0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,
-0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x38,
-0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,
-0x24,0x10,0x52,0x00,0x00,0x04,0x42,0x30,0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
-0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,
-0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,
-0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x04,0x42,0x38,0x00,0x4b,0x82,0xac,
-0x68,0x15,0x63,0x26,0xfc,0x4a,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,
-0x00,0x08,0x42,0x30,0x3a,0x00,0x40,0x10,0x2a,0xb0,0x05,0x3c,0x00,0x00,0xa8,0x8c,
-0xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31,0x31,0x00,0x82,0x10,0x00,0x80,0x02,0x31,
-0x08,0x04,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,
-0x05,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xc9,0x64,0x62,0x90,0x00,0x00,0x00,0x00,
-0x0b,0x00,0x40,0x18,0xff,0x00,0x02,0x24,0x08,0x64,0x62,0x90,0x20,0xb0,0x03,0x3c,
-0x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00,0x0c,0x00,0x48,0x8c,0x25,0xb0,0x03,0x3c,
-0xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac,0xff,0x00,0x04,0x31,0xff,0x00,0x02,0x24,
-0x1a,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0xc0,0x64,0x05,0x8e,
-0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,
-0x54,0x64,0x03,0xae,0x21,0x20,0x00,0x00,0x08,0x64,0x08,0xa2,0x20,0x00,0x07,0x24,
-0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x4a,0x05,0x8e,0x02,0x80,0x06,0x3c,
-0x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24,0x24,0x28,0xa2,0x00,0x25,0xb0,0x02,0x3c,
-0x04,0x00,0x84,0x34,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,
-0x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac,0xfc,0x4a,0x05,0xae,0x68,0x15,0x63,0x26,
-0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x08,0x42,0x38,0x00,0x4b,0x62,0xac,
-0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,
-0x00,0x10,0x42,0x30,0x38,0x00,0x40,0x10,0x2a,0xb0,0x02,0x3c,0x08,0x00,0x43,0x34,
-0x00,0x00,0x68,0x8c,0xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31,0x2c,0x00,0x82,0x10,
-0x00,0x80,0x02,0x31,0xca,0x03,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,
-0x24,0x10,0x02,0x01,0x0b,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x10,0x64,0xa2,0x90,
-0x20,0xb0,0x03,0x3c,0x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00,0x0c,0x00,0x48,0x8c,
-0x25,0xb0,0x03,0x3c,0xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac,0xff,0x00,0x04,0x31,
-0xff,0x00,0x02,0x24,0x1a,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
-0xd8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x21,0x30,0x60,0x00,0x6c,0x64,0x03,0xae,0x01,0x00,0x04,0x24,0x10,0x64,0x08,0xa2,
-0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x4a,0x05,0x8e,
-0x02,0x80,0x06,0x3c,0x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24,0x24,0x28,0xa2,0x00,
-0x25,0xb0,0x02,0x3c,0x10,0x00,0x84,0x34,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,
-0x00,0x00,0x44,0xac,0x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac,0xfc,0x4a,0x05,0xae,
-0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x10,0x42,0x38,
-0x00,0x4b,0x62,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x00,0x00,0x00,0x00,
-0x24,0x10,0x52,0x00,0x00,0x20,0x42,0x30,0x37,0x00,0x40,0x10,0x2a,0xb0,0x02,0x3c,
-0x04,0x00,0x43,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31,
-0xab,0x03,0x82,0x10,0x00,0x80,0x02,0x31,0x90,0x03,0x40,0x14,0x00,0x80,0x02,0x3c,
-0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x0b,0x00,0x40,0x10,0xff,0x00,0x02,0x24,
-0x0c,0x64,0xa2,0x90,0x20,0xb0,0x03,0x3c,0x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00,
-0x0c,0x00,0x48,0x8c,0x25,0xb0,0x03,0x3c,0xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac,
-0xff,0x00,0x04,0x31,0xff,0x00,0x02,0x24,0x1a,0x00,0x82,0x10,0xff,0x00,0x03,0x31,
-0x68,0x15,0x70,0x26,0xcc,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,
-0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0x60,0x64,0x03,0xae,0x01,0x00,0x04,0x24,
-0x0c,0x64,0x08,0xa2,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
-0xfc,0x4a,0x05,0x8e,0x02,0x80,0x06,0x3c,0x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24,
-0x24,0x28,0xa2,0x00,0x25,0xb0,0x02,0x3c,0x20,0x00,0x84,0x34,0x80,0x03,0x42,0x34,
-0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac,
-0xfc,0x4a,0x05,0xae,0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,
-0x00,0x20,0x42,0x38,0x00,0x4b,0x62,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,
-0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x80,0x42,0x30,0x59,0x00,0x40,0x10,
-0x2a,0xb0,0x06,0x3c,0x0c,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,
-0xff,0x00,0x04,0x31,0x78,0x03,0x87,0x10,0x00,0x80,0x02,0x31,0x24,0x00,0x40,0x14,
-0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x22,0x00,0x40,0x10,
-0xff,0x00,0x02,0x24,0x40,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
-0xff,0x00,0x44,0x30,0x0f,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xe8,0x63,0xa4,0xa0,
-0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x09,0x00,0x83,0x10,
-0x68,0x15,0x62,0x26,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,
-0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xe8,0x63,0xe3,0xa0,
-0x68,0x15,0x62,0x26,0xe8,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,
-0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,
-0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0x16,0x17,0x00,0x08,0xff,0x00,0x02,0x24,
-0x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x24,0x00,0x82,0x10,0x68,0x15,0x70,0x26,
-0xff,0x00,0x03,0x31,0x90,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,
-0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0xe8,0x63,0x08,0xa2,0x24,0x64,0x03,0xae,
-0x03,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
-0x02,0x80,0x0a,0x3c,0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d,
-0xfc,0x4a,0x06,0x8e,0x01,0x00,0x08,0x3c,0x80,0xff,0x02,0x24,0x25,0x38,0xe2,0x00,
-0x00,0x80,0x03,0x35,0x80,0x00,0xa5,0x34,0x27,0x18,0x03,0x00,0x00,0x26,0x07,0x00,
-0x25,0xb0,0x02,0x3c,0x24,0x30,0xc3,0x00,0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,
-0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x27,0x88,0x08,0x00,0x00,0x00,0x66,0xac,
-0x6c,0x7e,0x25,0xad,0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x63,0x26,
-0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x80,0x42,0x38,0x00,0x4b,0x62,0xac,
-0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x01,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,
-0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x56,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,
-0x10,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,
-0x23,0x03,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,
-0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,
-0xff,0x00,0x02,0x24,0x41,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
-0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xec,0x63,0xa4,0xa0,
-0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,
-0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,
-0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xec,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,
-0xec,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,
-0x00,0x00,0x48,0xac,0x75,0x17,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
-0xff,0x00,0x02,0x24,0x22,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
-0x90,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x21,0x30,0x60,0x00,0xec,0x63,0x08,0xa2,0x24,0x64,0x03,0xae,0x03,0x00,0x04,0x24,
-0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c,
-0x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e,
-0x01,0x00,0x02,0x3c,0x00,0x80,0x42,0x34,0x40,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,
-0x24,0x30,0xc2,0x00,0x80,0x00,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,
-0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,
-0x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,
-0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x01,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,
-0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x02,0x00,0x03,0x3c,
-0x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,
-0x14,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,
-0xcc,0x02,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,
-0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,
-0xff,0x00,0x02,0x24,0x42,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
-0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xf0,0x63,0xa4,0xa0,
-0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,
-0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,
-0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xf0,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,
-0xf0,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,
-0x00,0x00,0x48,0xac,0xd1,0x17,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
-0xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
-0x9c,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x21,0x30,0x60,0x00,0xf0,0x63,0x08,0xa2,0x30,0x64,0x03,0xae,0x04,0x00,0x04,0x24,
-0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c,
-0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e,
-0x06,0x00,0x02,0x3c,0x20,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,
-0x00,0x01,0xa5,0x34,0x25,0xb0,0x03,0x3c,0x04,0x00,0x02,0x3c,0x00,0x26,0x07,0x00,
-0x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34,0x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34,
-0x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac,0x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad,
-0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26,
-0x00,0x4b,0x43,0x8c,0x02,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,
-0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x04,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,
-0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x58,0x00,0x40,0x10,0x25,0xb0,0x03,0x3c,
-0xb0,0x03,0x62,0x34,0x2a,0xb0,0x09,0x3c,0x00,0x00,0x51,0xac,0x18,0x00,0x26,0x35,
-0x00,0x00,0xc8,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,0x3a,0x02,0x87,0x10,
-0x04,0x00,0x02,0x24,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c,
-0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24,
-0x43,0x00,0x26,0x35,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30,
-0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xf4,0x63,0xa4,0xa0,0x00,0x00,0xc2,0x90,
-0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00,
-0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,
-0xff,0x00,0x44,0x30,0xf4,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,0xf4,0x63,0x43,0x90,
-0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,
-0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,
-0x34,0x18,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0xc2,0xac,0xff,0x00,0x02,0x24,
-0x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0x9c,0x64,0x05,0x8e,
-0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,
-0xf4,0x63,0x08,0xa2,0x30,0x64,0x03,0xae,0x04,0x00,0x04,0x24,0x20,0x00,0x07,0x24,
-0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c,0x7c,0x7e,0x27,0x91,
-0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e,0x06,0x00,0x02,0x3c,
-0x10,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,0x00,0x01,0xa5,0x34,
-0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,
-0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad,
-0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,
-0x04,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,
-0xfc,0x4a,0xa2,0x8c,0x08,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00,
-0x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,0x1c,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,
-0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,0x13,0x02,0x87,0x10,0x25,0xb0,0x02,0x3c,
-0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,
-0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x44,0x00,0xc6,0x34,
-0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,
-0x68,0x15,0x62,0x26,0xf8,0x63,0xa4,0xa0,0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,
-0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,
-0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,
-0xf8,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,0xf8,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,
-0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,
-0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0x8f,0x18,0x00,0x08,
-0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10,
-0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0xa8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,
-0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0xf8,0x63,0x08,0xa2,
-0x3c,0x64,0x03,0xae,0x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,
-0x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c,0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,
-0x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e,0x18,0x00,0x02,0x3c,0x08,0x00,0xe7,0x34,
-0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,0x00,0x02,0xa5,0x34,0x25,0xb0,0x03,0x3c,
-0x10,0x00,0x02,0x3c,0x00,0x26,0x07,0x00,0x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34,
-0x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34,0x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac,
-0x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad,0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,
-0x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x08,0x00,0x04,0x3c,
-0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,
-0x10,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,
-0x58,0x00,0x40,0x10,0x25,0xb0,0x06,0x3c,0xb0,0x03,0xc2,0x34,0x2a,0xb0,0x09,0x3c,
-0x00,0x00,0x51,0xac,0x20,0x00,0x23,0x35,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,
-0xff,0x00,0x04,0x31,0x80,0x01,0x87,0x10,0x90,0x03,0xc2,0x34,0x00,0x80,0x02,0x31,
-0x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,
-0x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x45,0x00,0x26,0x35,0x00,0x00,0xc2,0x90,
-0x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,
-0x04,0x64,0xa4,0xa0,0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,
-0x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,
-0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0x04,0x64,0xe3,0xa0,
-0x68,0x15,0x62,0x26,0x04,0x64,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,
-0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,
-0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0xf2,0x18,0x00,0x08,0xff,0x00,0x02,0x24,
-0x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26,
-0xff,0x00,0x03,0x31,0xa8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,
-0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0x04,0x64,0x08,0xa2,0x3c,0x64,0x03,0xae,
-0x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
-0x02,0x80,0x09,0x3c,0x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,
-0xfc,0x4a,0x06,0x8e,0x18,0x00,0x02,0x3c,0x01,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,
-0x24,0x30,0xc2,0x00,0x00,0x02,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,
-0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,
-0x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,
-0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x10,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,
-0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x20,0x00,0x03,0x3c,
-0x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,
-0x24,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,
-0x28,0x01,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,
-0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,
-0xff,0x00,0x02,0x24,0x46,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
-0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xfc,0x63,0xa4,0xa0,
-0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,
-0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,
-0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xfc,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,
-0xfc,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,
-0x00,0x00,0x48,0xac,0x4d,0x19,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
-0xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
-0xb4,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x21,0x30,0x60,0x00,0xfc,0x63,0x08,0xa2,0x48,0x64,0x03,0xae,0x06,0x00,0x04,0x24,
-0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c,
-0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e,
-0x60,0x00,0x02,0x3c,0x04,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,
-0x00,0x04,0xa5,0x34,0x25,0xb0,0x03,0x3c,0x40,0x00,0x02,0x3c,0x00,0x26,0x07,0x00,
-0x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34,0x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34,
-0x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac,0x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad,
-0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26,
-0x00,0x4b,0x43,0x8c,0x20,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,
-0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x40,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,
-0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x68,0x15,0x70,0x26,
-0x25,0xb0,0x02,0x3c,0x2a,0xb0,0x07,0x3c,0xb0,0x03,0x42,0x34,0x00,0x00,0x51,0xac,
-0x28,0x00,0xe3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x06,0x24,0xff,0x00,0x04,0x31,
-0xc9,0x00,0x86,0x10,0x25,0xbd,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,
-0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,
-0xff,0x00,0x02,0x24,0x47,0x00,0xe7,0x34,0x00,0x00,0xe2,0x90,0x00,0x00,0x00,0x00,
-0xff,0x00,0x44,0x30,0x0e,0x00,0x86,0x10,0x68,0x15,0x62,0x26,0x00,0x64,0xa4,0xa0,
-0x00,0x00,0xe2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,
-0x21,0x30,0xa0,0x00,0x21,0x28,0xe0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,
-0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0x00,0x64,0xc3,0xa0,0x68,0x15,0x62,0x26,
-0x00,0x64,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,
-0x00,0x00,0x48,0xac,0xb1,0x19,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
-0xff,0x00,0x02,0x24,0x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
-0xb4,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
-0x21,0x30,0x60,0x00,0x00,0x64,0x08,0xa2,0x48,0x64,0x03,0xae,0x06,0x00,0x04,0x24,
-0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c,
-0x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e,
-0x60,0x00,0x02,0x3c,0x02,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,
-0x00,0x04,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,0x25,0x20,0x85,0x00,
-0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x66,0xac,
-0x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x62,0x26,
-0x00,0x4b,0x43,0x8c,0x40,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,
-0x68,0x15,0x70,0x26,0xfc,0x4a,0x06,0x8e,0x00,0x04,0x11,0x3c,0x24,0x10,0xd2,0x00,
-0x24,0x10,0x51,0x00,0x4c,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x24,0x28,0xd2,0x00,
-0x00,0x08,0x04,0x3c,0x24,0x10,0xa4,0x00,0x08,0x00,0x40,0x10,0x80,0x00,0x07,0x3c,
-0x00,0x4b,0x03,0x8e,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0x26,0x18,0x64,0x00,
-0x00,0x00,0x44,0xac,0x00,0x4b,0x03,0xae,0x80,0x00,0x07,0x3c,0x24,0x10,0xa7,0x00,
-0x21,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x4b,0x03,0x8e,0x25,0xb0,0x08,0x3c,
-0xb0,0x03,0x09,0x35,0x2a,0xb0,0x02,0x3c,0x00,0x00,0x23,0xad,0x36,0x00,0x42,0x34,
-0x00,0x00,0x43,0x90,0x23,0xb0,0x04,0x3c,0xff,0x1f,0x02,0x3c,0xc0,0x18,0x03,0x00,
-0xf0,0x07,0x63,0x30,0x5c,0x65,0x05,0x8e,0x21,0x18,0x64,0x00,0xff,0xff,0x42,0x34,
-0x24,0x18,0x62,0x00,0x59,0x00,0x65,0x10,0x60,0x65,0x03,0xae,0x02,0x80,0x05,0x3c,
-0x6c,0x7e,0xa3,0x8c,0x27,0x20,0x07,0x00,0x24,0x20,0xc4,0x00,0x00,0x08,0x63,0x34,
-0x41,0xb0,0x02,0x3c,0x00,0x00,0x23,0xad,0x00,0x00,0x44,0xac,0x6c,0x7e,0xa3,0xac,
-0xfc,0x4a,0x04,0xae,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x80,0x00,0x04,0x3c,
-0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x66,0x26,0xfc,0x4a,0xc3,0x8c,
-0x00,0x01,0x04,0x3c,0x24,0x28,0x72,0x00,0x24,0x10,0xa4,0x00,0x06,0x00,0x40,0x10,
-0x25,0xb0,0x02,0x3c,0x00,0x4b,0xc3,0x8c,0xb0,0x03,0x42,0x34,0x26,0x18,0x64,0x00,
-0x00,0x00,0x44,0xac,0x00,0x4b,0xc3,0xac,0x00,0x02,0x04,0x3c,0x24,0x10,0xa4,0x00,
-0x06,0x00,0x40,0x10,0x25,0xb0,0x03,0x3c,0x00,0x4b,0xc2,0x8c,0xb0,0x03,0x63,0x34,
-0x26,0x10,0x44,0x00,0x00,0x4b,0xc2,0xac,0x00,0x00,0x64,0xac,0x28,0x00,0xbf,0x8f,
-0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
-0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x5b,0x4e,0x00,0x0c,0x07,0x00,0x04,0x24,
-0x00,0x4b,0x03,0x8e,0xfc,0x4a,0x06,0x8e,0x25,0xb0,0x02,0x3c,0x26,0x18,0x71,0x00,
-0xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0xdf,0x19,0x00,0x08,0x00,0x4b,0x03,0xae,
-0x56,0x01,0x42,0x35,0x00,0x00,0x43,0x94,0x00,0x00,0x00,0x00,0x44,0xfb,0x60,0x10,
-0x00,0x00,0x00,0x00,0x5b,0x4e,0x00,0x0c,0x07,0x00,0x04,0x24,0x7d,0x15,0x00,0x08,
-0x68,0x15,0x66,0x26,0x00,0x00,0xa2,0xac,0x48,0x16,0x00,0x08,0xff,0x00,0x02,0x24,
-0x00,0x00,0x62,0xac,0x85,0x16,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
-0xc2,0x16,0x00,0x08,0xff,0x00,0x02,0x24,0x90,0x03,0x63,0x34,0x00,0x00,0x62,0xac,
-0x57,0x18,0x00,0x08,0x68,0x15,0x62,0x26,0x00,0x00,0x40,0xac,0x15,0x19,0x00,0x08,
-0x68,0x15,0x62,0x26,0x02,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
-0x74,0x19,0x00,0x08,0x68,0x15,0x62,0x26,0x01,0x00,0x03,0x24,0x90,0x03,0x42,0x34,
-0x00,0x00,0x43,0xac,0xd4,0x19,0x00,0x08,0x68,0x15,0x62,0x26,0xd0,0x03,0x03,0x35,
-0x80,0x00,0x02,0x24,0x00,0x00,0x62,0xac,0x0a,0x1a,0x00,0x08,0x68,0x15,0x62,0x26,
-0x25,0xb0,0x02,0x3c,0x07,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
-0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x20,0x42,0x38,
-0xe2,0x16,0x00,0x08,0x00,0x4b,0x62,0xac,0x25,0xb0,0x02,0x3c,0x07,0x00,0x03,0x24,
-0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,
-0x00,0x00,0x00,0x00,0x00,0x80,0x42,0x38,0x40,0x17,0x00,0x08,0x00,0x4b,0x62,0xac,
-0x06,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x99,0x17,0x00,0x08,
-0x68,0x15,0x62,0x26,0x05,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
-0xf8,0x17,0x00,0x08,0x68,0x15,0x62,0x26,0x03,0x00,0x03,0x24,0x90,0x03,0x42,0x34,
-0x00,0x00,0x43,0xac,0xb6,0x18,0x00,0x08,0x68,0x15,0x62,0x26,0x25,0xb0,0x0d,0x3c,
-0x00,0x80,0x02,0x3c,0x18,0x03,0xa4,0x35,0xfc,0x69,0x42,0x24,0x02,0x80,0x03,0x3c,
-0x41,0xb0,0x08,0x3c,0x00,0x00,0x82,0xac,0x68,0x15,0x6a,0x24,0x0a,0x00,0x02,0x35,
-0x00,0x00,0x44,0x94,0x0a,0x4b,0x43,0x95,0x08,0x4b,0x4b,0x95,0x25,0x18,0x64,0x00,
-0xff,0xff,0x6c,0x30,0x24,0x10,0x8b,0x01,0x02,0x00,0x42,0x30,0x4d,0x00,0x40,0x10,
-0x02,0x00,0x64,0x38,0x02,0x00,0x02,0x24,0xc0,0x03,0xa3,0x35,0x00,0x00,0x62,0xac,
-0x0a,0x4b,0x44,0xa5,0x24,0x38,0x8b,0x01,0x04,0x00,0xe2,0x30,0x0a,0x00,0x40,0x10,
-0x08,0x00,0xe2,0x30,0x0a,0x4b,0x43,0x95,0x0c,0x00,0x04,0x35,0xc0,0x03,0xa5,0x35,
-0x04,0x00,0x63,0x38,0x04,0x00,0x02,0x24,0x00,0x00,0x86,0x8c,0x00,0x00,0xa2,0xac,
-0x0a,0x4b,0x43,0xa5,0x08,0x00,0xe2,0x30,0x08,0x00,0x40,0x10,0x10,0x00,0xe2,0x30,
-0x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35,0x08,0x00,0x03,0x24,0x08,0x00,0x42,0x38,
-0x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5,0x10,0x00,0xe2,0x30,0x08,0x00,0x40,0x10,
-0x20,0x00,0xe2,0x30,0x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35,0x10,0x00,0x03,0x24,
-0x10,0x00,0x42,0x38,0x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5,0x20,0x00,0xe2,0x30,
-0x08,0x00,0x40,0x10,0x80,0x00,0xe2,0x30,0x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35,
-0x20,0x00,0x03,0x24,0x20,0x00,0x42,0x38,0x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5,
-0x80,0x00,0xe2,0x30,0x15,0x00,0x40,0x10,0x24,0x10,0x8b,0x01,0x02,0x80,0x09,0x3c,
-0x0a,0x4b,0x46,0x95,0x6c,0x7e,0x25,0x8d,0x08,0x00,0x02,0x3c,0x7f,0xff,0x04,0x24,
-0x24,0x20,0x64,0x01,0x25,0x28,0xa2,0x00,0x80,0x00,0xc6,0x38,0xb0,0x03,0xa7,0x35,
-0x08,0x00,0x08,0x35,0xc0,0x03,0xa3,0x35,0x80,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
-0x21,0x58,0x80,0x00,0x00,0x00,0xe5,0xac,0x0a,0x4b,0x46,0xa5,0x6c,0x7e,0x25,0xad,
-0x00,0x00,0x04,0xa5,0x08,0x4b,0x44,0xa5,0x24,0x10,0x8b,0x01,0x00,0x30,0x42,0x30,
-0x06,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x0a,0x4b,0x42,0x95,0x00,0x00,0x00,0x00,
-0x00,0x10,0x42,0x38,0x00,0x20,0x42,0x34,0x0a,0x4b,0x42,0xa5,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x95,0x1a,0x00,0x08,0x0a,0x4b,0x43,0xa5,0xf8,0xff,0xbd,0x27,
-0x04,0x00,0xb1,0xaf,0x00,0x00,0xb0,0xaf,0x00,0x40,0x02,0x40,0x00,0x68,0x08,0x40,
-0x00,0x70,0x02,0x40,0x00,0x60,0x09,0x40,0x25,0xb0,0x05,0x3c,0x00,0x80,0x02,0x3c,
-0x18,0x03,0xa3,0x34,0x7c,0x6b,0x42,0x24,0x00,0x00,0x62,0xac,0x80,0x00,0x87,0x8c,
-0x7c,0x02,0xa2,0x34,0x84,0x02,0xa3,0x34,0x88,0x02,0xa6,0x34,0x00,0x00,0x47,0xac,
-0x00,0x00,0x68,0xac,0x00,0x00,0xc9,0xac,0x74,0x00,0x83,0x8c,0x8c,0x02,0xa2,0x34,
-0x90,0x02,0xa7,0x34,0x00,0x00,0x43,0xac,0x08,0x00,0x86,0x8c,0x94,0x02,0xa8,0x34,
-0x98,0x02,0xa9,0x34,0x00,0x00,0xe6,0xac,0x0c,0x00,0x82,0x8c,0x9c,0x02,0xa6,0x34,
-0xa0,0x02,0xa7,0x34,0x00,0x00,0x02,0xad,0x10,0x00,0x83,0x8c,0xa4,0x02,0xa8,0x34,
-0xa8,0x02,0xaa,0x34,0x00,0x00,0x23,0xad,0x14,0x00,0x82,0x8c,0xac,0x02,0xa9,0x34,
-0xb0,0x02,0xab,0x34,0x00,0x00,0xc2,0xac,0x18,0x00,0x83,0x8c,0xb4,0x02,0xa6,0x34,
-0xb8,0x02,0xac,0x34,0x00,0x00,0xe3,0xac,0x1c,0x00,0x82,0x8c,0xbc,0x02,0xa7,0x34,
-0xc0,0x02,0xad,0x34,0x00,0x00,0x02,0xad,0x20,0x00,0x83,0x8c,0xc4,0x02,0xa8,0x34,
-0xc8,0x02,0xae,0x34,0x00,0x00,0x43,0xad,0x24,0x00,0x82,0x8c,0xcc,0x02,0xaa,0x34,
-0xd0,0x02,0xaf,0x34,0x00,0x00,0x22,0xad,0x28,0x00,0x83,0x8c,0xd4,0x02,0xa9,0x34,
-0xd8,0x02,0xb0,0x34,0x00,0x00,0x63,0xad,0x2c,0x00,0x82,0x8c,0x70,0x02,0xab,0x34,
-0x74,0x02,0xb1,0x34,0x00,0x00,0xc2,0xac,0x30,0x00,0x83,0x8c,0x78,0x02,0xa5,0x34,
-0x00,0x00,0x83,0xad,0x34,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0xac,
-0x38,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xad,0x3c,0x00,0x82,0x8c,
-0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xad,0x40,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,
-0x00,0x00,0xc3,0xad,0x44,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xad,
-0x48,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xe3,0xad,0x4c,0x00,0x82,0x8c,
-0x00,0x00,0x00,0x00,0x00,0x00,0x22,0xad,0x50,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,
-0x00,0x00,0x03,0xae,0x54,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xad,
-0x58,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0xae,0x5c,0x00,0x82,0x8c,
-0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xac,0x42,0x1b,0x00,0x08,0x00,0x00,0x00,0x00,
-0x00,0x80,0x1b,0x3c,0x10,0x6d,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,
-0x00,0x00,0x5b,0xaf,0x21,0xd8,0xa0,0x03,0x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00,
-0x08,0x00,0x7b,0x27,0x04,0x00,0x61,0xaf,0x08,0x00,0x62,0xaf,0x0c,0x00,0x63,0xaf,
-0x10,0x00,0x64,0xaf,0x14,0x00,0x65,0xaf,0x18,0x00,0x66,0xaf,0x1c,0x00,0x67,0xaf,
-0x20,0x00,0x68,0xaf,0x24,0x00,0x69,0xaf,0x28,0x00,0x6a,0xaf,0x2c,0x00,0x6b,0xaf,
-0x30,0x00,0x6c,0xaf,0x34,0x00,0x6d,0xaf,0x38,0x00,0x6e,0xaf,0x3c,0x00,0x6f,0xaf,
-0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0x70,0xaf,
-0x44,0x00,0x71,0xaf,0x48,0x00,0x72,0xaf,0x4c,0x00,0x73,0xaf,0x50,0x00,0x74,0xaf,
-0x54,0x00,0x75,0xaf,0x58,0x00,0x76,0xaf,0x5c,0x00,0x77,0xaf,0x60,0x00,0x78,0xaf,
-0x64,0x00,0x79,0xaf,0x68,0x00,0x7c,0xaf,0x6c,0x00,0x7d,0xaf,0x70,0x00,0x7e,0xaf,
-0x74,0x00,0x7f,0xaf,0x78,0x00,0x68,0xaf,0x7c,0x00,0x69,0xaf,0x80,0x00,0x6a,0xaf,
-0x00,0x68,0x1a,0x40,0x25,0xb0,0x1b,0x3c,0x1c,0x03,0x7b,0x37,0x00,0x00,0x00,0x00,
-0x00,0x00,0x7a,0xaf,0x7f,0x00,0x5b,0x33,0x30,0x00,0x60,0x13,0x00,0x00,0x00,0x00,
-0x25,0xb0,0x1b,0x3c,0x30,0x03,0x7b,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x7a,0xaf,
-0x00,0x00,0x00,0x00,0x21,0xd8,0xa0,0x03,0x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00,
-0x08,0x00,0x7b,0x27,0x04,0x00,0x61,0xaf,0x08,0x00,0x62,0xaf,0x0c,0x00,0x63,0xaf,
-0x10,0x00,0x64,0xaf,0x14,0x00,0x65,0xaf,0x18,0x00,0x66,0xaf,0x1c,0x00,0x67,0xaf,
-0x20,0x00,0x68,0xaf,0x24,0x00,0x69,0xaf,0x28,0x00,0x6a,0xaf,0x2c,0x00,0x6b,0xaf,
-0x30,0x00,0x6c,0xaf,0x34,0x00,0x6d,0xaf,0x38,0x00,0x6e,0xaf,0x3c,0x00,0x6f,0xaf,
-0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0x70,0xaf,
-0x44,0x00,0x71,0xaf,0x48,0x00,0x72,0xaf,0x4c,0x00,0x73,0xaf,0x50,0x00,0x74,0xaf,
-0x54,0x00,0x75,0xaf,0x58,0x00,0x76,0xaf,0x5c,0x00,0x77,0xaf,0x60,0x00,0x78,0xaf,
-0x64,0x00,0x79,0xaf,0x68,0x00,0x7c,0xaf,0x6c,0x00,0x7d,0xaf,0x70,0x00,0x7e,0xaf,
-0x74,0x00,0x7f,0xaf,0x78,0x00,0x68,0xaf,0x7c,0x00,0x69,0xaf,0x80,0x00,0x6a,0xaf,
-0xdf,0x1a,0x00,0x08,0x21,0x20,0x60,0x03,0x00,0x00,0x00,0x00,0x25,0xb0,0x08,0x3c,
-0x20,0x03,0x08,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0xad,0x00,0x04,0x5b,0x33,
-0x0a,0x00,0x60,0x13,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0x3c,0x74,0x55,0x08,0x25,
-0x00,0x00,0x00,0x00,0x25,0xb0,0x1b,0x3c,0x24,0x03,0x7b,0x37,0x00,0x00,0x00,0x00,
-0x00,0x00,0x68,0xaf,0x09,0xf8,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x5b,0x33,
-0x25,0xb0,0x08,0x3c,0x28,0x03,0x08,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0xad,
-0x06,0x00,0x60,0x13,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0x3c,0xfc,0x69,0x08,0x25,
-0x00,0x00,0x00,0x00,0x09,0xf8,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x80,0x1a,0x3c,
-0x6c,0x7e,0x5a,0x27,0x04,0x00,0x5b,0x97,0x25,0xb0,0x08,0x3c,0x30,0x03,0x08,0x35,
-0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0xad,0x18,0x00,0x60,0x13,0x00,0x00,0x00,0x00,
-0x08,0xec,0x9b,0x27,0x00,0x00,0x00,0x00,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b,
-0x7c,0x00,0x62,0x7b,0xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b,
-0x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b,
-0xfc,0x01,0x6e,0x7b,0x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b,
-0xfc,0x02,0x76,0x7b,0x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b,
-0x80,0x00,0x7b,0x8f,0x2f,0x1c,0x00,0x08,0x00,0x00,0x00,0x00,0x21,0xd8,0xa0,0x03,
-0x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00,0x08,0x00,0x7b,0x27,0x08,0x00,0x5b,0xaf,
-0xfc,0xef,0x9d,0x27,0x00,0x00,0x4a,0x8f,0x00,0x00,0x00,0x00,0x21,0x00,0x40,0x11,
-0x00,0x00,0x00,0x00,0x02,0x80,0x08,0x3c,0xcc,0x7d,0x08,0x25,0x21,0x48,0x00,0x00,
-0x21,0x58,0x00,0x00,0x01,0x00,0x6b,0x25,0x1a,0x00,0x40,0x11,0x24,0x70,0x4b,0x01,
-0x14,0x00,0xc0,0x11,0x01,0x00,0x04,0x24,0x00,0x00,0x00,0x00,0x04,0x00,0x44,0xa3,
-0x26,0x50,0x4b,0x01,0x00,0x00,0x4a,0xaf,0x80,0x80,0x09,0x00,0x21,0x80,0x08,0x02,
-0x00,0x00,0x10,0x8e,0x00,0x00,0x00,0x00,0x09,0xf8,0x00,0x02,0x00,0x00,0x00,0x00,
-0x00,0x80,0x1b,0x3c,0xe8,0x6f,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,
-0x00,0x00,0x5b,0xaf,0x02,0x80,0x1a,0x3c,0x6c,0x7e,0x5a,0x27,0xe1,0xff,0x00,0x10,
-0x00,0x00,0x00,0x00,0x01,0x00,0x29,0x25,0x40,0x58,0x0b,0x00,0xf2,0x1b,0x00,0x08,
-0x00,0x00,0x00,0x00,0x02,0x80,0x1b,0x3c,0x6c,0x7e,0x7b,0x27,0x21,0x60,0x00,0x00,
-0x04,0x00,0x6c,0xa7,0x08,0x00,0x7a,0x8f,0x00,0x00,0x00,0x00,0xf8,0xff,0x5a,0x27,
-0x00,0x00,0x5a,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0x5a,0x27,0x84,0x00,0x44,0x8f,
-0x00,0x00,0x00,0x00,0xf9,0xff,0x80,0x10,0x00,0x00,0x00,0x00,0x04,0x00,0x41,0x8f,
-0xfc,0x03,0x50,0x7b,0x7c,0x00,0x42,0x7b,0xbc,0x00,0x44,0x7b,0xfc,0x00,0x46,0x7b,
-0x3c,0x01,0x48,0x7b,0x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x4a,0x7b,
-0xbc,0x01,0x4c,0x7b,0xfc,0x01,0x4e,0x7b,0x3c,0x02,0x50,0x7b,0x7c,0x02,0x52,0x7b,
-0xbc,0x02,0x54,0x7b,0xfc,0x02,0x56,0x7b,0x3c,0x03,0x58,0x7b,0x7c,0x03,0x5c,0x7b,
-0xbc,0x03,0x5e,0x7b,0x80,0x00,0x5b,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0x60,0x03,
-0x10,0x00,0x00,0x42,0x00,0x60,0x05,0x40,0x42,0x28,0x05,0x00,0x40,0x28,0x05,0x00,
-0x00,0x60,0x85,0x40,0x04,0x00,0x81,0xac,0x08,0x00,0x82,0xac,0x0c,0x00,0x83,0xac,
-0x20,0x00,0x88,0xac,0x24,0x00,0x89,0xac,0x28,0x00,0x8a,0xac,0x2c,0x00,0x8b,0xac,
-0x30,0x00,0x8c,0xac,0x34,0x00,0x8d,0xac,0x38,0x00,0x8e,0xac,0x3c,0x00,0x8f,0xac,
-0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x40,0x00,0x90,0xac,0x44,0x00,0x91,0xac,
-0x48,0x00,0x92,0xac,0x4c,0x00,0x93,0xac,0x50,0x00,0x94,0xac,0x54,0x00,0x95,0xac,
-0x58,0x00,0x96,0xac,0x5c,0x00,0x97,0xac,0x60,0x00,0x98,0xac,0x64,0x00,0x99,0xac,
-0x68,0x00,0x9c,0xac,0x6c,0x00,0x9d,0xac,0x70,0x00,0x9e,0xac,0x74,0x00,0x9f,0xac,
-0x78,0x00,0x88,0xac,0x7c,0x00,0x89,0xac,0x80,0x00,0x9f,0xac,0xf8,0xff,0x84,0x24,
-0x00,0x00,0x84,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x84,0x24,0x84,0x00,0x86,0x8c,
-0x00,0x00,0x00,0x00,0xf9,0xff,0xc0,0x10,0x00,0x00,0x00,0x00,0x21,0xd8,0x80,0x00,
-0x01,0x00,0xba,0x24,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b,0x7c,0x00,0x62,0x7b,
-0xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b,0x13,0x00,0x00,0x02,
-0x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b,0xfc,0x01,0x6e,0x7b,
-0x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b,0xfc,0x02,0x76,0x7b,
-0x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b,0x80,0x00,0x7b,0x8f,
-0x00,0x00,0x00,0x00,0x08,0x00,0x60,0x03,0x00,0x60,0x9a,0x40,0x00,0x60,0x05,0x40,
-0x42,0x28,0x05,0x00,0x40,0x28,0x05,0x00,0x00,0x60,0x85,0x40,0x04,0x00,0x81,0xac,
-0x08,0x00,0x82,0xac,0x0c,0x00,0x83,0xac,0x20,0x00,0x88,0xac,0x24,0x00,0x89,0xac,
-0x28,0x00,0x8a,0xac,0x2c,0x00,0x8b,0xac,0x30,0x00,0x8c,0xac,0x34,0x00,0x8d,0xac,
-0x38,0x00,0x8e,0xac,0x3c,0x00,0x8f,0xac,0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,
-0x40,0x00,0x90,0xac,0x44,0x00,0x91,0xac,0x48,0x00,0x92,0xac,0x4c,0x00,0x93,0xac,
-0x50,0x00,0x94,0xac,0x54,0x00,0x94,0xac,0x58,0x00,0x96,0xac,0x5c,0x00,0x96,0xac,
-0x60,0x00,0x98,0xac,0x64,0x00,0x99,0xac,0x68,0x00,0x9c,0xac,0x6c,0x00,0x9d,0xac,
-0x70,0x00,0x9e,0xac,0x78,0x00,0x88,0xac,0x7c,0x00,0x89,0xac,0x80,0x00,0x9f,0xac,
-0x84,0x00,0x80,0xac,0xf8,0xff,0x84,0x24,0x00,0x00,0x84,0x8c,0x00,0x00,0x00,0x00,
-0x08,0x00,0x84,0x24,0x84,0x00,0x86,0x8c,0xfa,0xff,0xc0,0x10,0x00,0x00,0x00,0x00,
-0x21,0xd8,0x80,0x00,0x01,0x00,0xba,0x24,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b,
-0x7c,0x00,0x62,0x7b,0xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b,
-0x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b,
-0xfc,0x01,0x6e,0x7b,0x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b,
-0xfc,0x02,0x76,0x7b,0x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b,
-0x80,0x00,0x7b,0x8f,0x08,0x00,0x60,0x03,0x00,0x60,0x9a,0x40,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0xc6,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x1b,0x3c,0x00,0x00,0x7b,0x27,
-0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf,0x00,0x00,0x05,0x24,
-0x03,0x00,0xa4,0x24,0x00,0xa0,0x80,0x40,0x00,0xa0,0x84,0x40,0x01,0x80,0x04,0x3c,
-0x98,0x03,0x84,0x24,0x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x01,0x80,0x1b,0x3c,0x98,0x03,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,
-0x00,0x00,0x5b,0xaf,0x02,0x80,0x1a,0x3c,0x00,0x00,0x5a,0x27,0xfc,0x03,0x5d,0x27,
-0x02,0x80,0x1c,0x3c,0x00,0x14,0x9c,0x27,0x00,0xf0,0x08,0x3c,0x00,0x0c,0x08,0x35,
-0x00,0x60,0x88,0x40,0x02,0x80,0x04,0x3c,0x00,0x00,0x84,0x24,0xff,0x7f,0x05,0x3c,
-0xff,0xff,0xa5,0x34,0x24,0x20,0x85,0x00,0x00,0x20,0x84,0x4c,0xff,0xff,0x05,0x34,
-0x21,0x28,0xa4,0x00,0x00,0x28,0x85,0x4c,0x00,0x80,0x04,0x3c,0x00,0x00,0x84,0x24,
-0xff,0x7f,0x05,0x3c,0xff,0xff,0xa5,0x34,0x24,0x20,0x85,0x00,0x00,0x00,0x84,0x4c,
-0xff,0x7f,0x06,0x24,0x21,0x30,0xc4,0x00,0x24,0x30,0xc5,0x00,0x00,0x08,0x86,0x4c,
-0x00,0xa0,0x04,0x40,0x10,0x00,0x84,0x34,0x00,0xa0,0x84,0x40,0x01,0x80,0x1b,0x3c,
-0x24,0x04,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf,
-0x00,0x00,0x00,0x00,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x85,0x84,
-0x20,0x00,0x06,0x24,0x25,0x28,0xa6,0x00,0x00,0x00,0x85,0xa4,0x01,0x80,0x1b,0x3c,
-0x54,0x04,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf,
-0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x85,0x8c,0x00,0x00,0x00,0x00,
-0x10,0x00,0xa5,0x30,0xfc,0xff,0xa0,0x10,0x00,0x00,0x00,0x00,0xff,0x1f,0x07,0x3c,
-0xff,0xff,0xe7,0x34,0x02,0x80,0x05,0x3c,0x88,0x7d,0xa5,0x24,0xff,0xff,0xa5,0x30,
-0x40,0xb0,0x04,0x3c,0x25,0x28,0xa4,0x00,0x24,0x28,0xa7,0x00,0x21,0x30,0x00,0x00,
-0x43,0xb0,0x02,0x3c,0x00,0x80,0x04,0x3c,0x40,0x00,0x84,0x34,0x00,0x00,0x45,0xac,
-0x04,0x00,0x46,0xac,0x08,0x00,0x44,0xac,0x4e,0x58,0x00,0x08,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24,
-0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0x08,0x00,0xe0,0x03,0x01,0x00,0x42,0x24,
-0x00,0x60,0x02,0x40,0x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x82,0xac,0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,
-0x21,0x18,0x40,0x00,0x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x82,0xac,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,
-0x25,0xb0,0x02,0x3c,0x44,0x05,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
-0x04,0x00,0x85,0x8c,0x00,0x80,0x03,0x3c,0x01,0x00,0x02,0x24,0x25,0x28,0xa3,0x00,
-0x00,0x00,0xa4,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,
-0x25,0xb0,0x02,0x3c,0x74,0x05,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
-0x04,0x00,0x82,0x8c,0x02,0x00,0x83,0x94,0x00,0x80,0x07,0x3c,0x25,0x28,0x47,0x00,
-0x00,0x00,0xa2,0x8c,0x10,0x00,0x02,0x24,0x13,0x00,0x62,0x10,0x11,0x00,0x66,0x28,
-0x06,0x00,0xc0,0x10,0x20,0x00,0x02,0x24,0x08,0x00,0x02,0x24,0x17,0x00,0x62,0x10,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0xfd,0xff,0x62,0x14,
-0x00,0x00,0x00,0x00,0x08,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xac,
-0x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x25,0x10,0x47,0x00,0x00,0x00,0x42,0x8c,
-0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,
-0x00,0x00,0xa2,0xa4,0x04,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x25,0x18,0x67,0x00,
-0x00,0x00,0x62,0x94,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0x82,0x8c,
-0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xa0,0x04,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,
-0x25,0x18,0x67,0x00,0x00,0x00,0x62,0x90,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
-0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c,0x1c,0x00,0xbf,0xaf,
-0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x31,0x26,0xe4,0x64,0x30,0x96,
-0x02,0x80,0x02,0x3c,0x01,0x80,0x03,0x3c,0x25,0x80,0x02,0x02,0x25,0xb0,0x02,0x3c,
-0x38,0x06,0x63,0x24,0x18,0x03,0x42,0x34,0x60,0x00,0x04,0x26,0x80,0x00,0x05,0x26,
-0x00,0x00,0x43,0xac,0xab,0x45,0x00,0x0c,0x03,0x00,0x06,0x24,0x21,0x20,0x00,0x02,
-0x21,0x28,0x00,0x00,0x97,0x45,0x00,0x0c,0x08,0x00,0x06,0x24,0xe4,0x64,0x22,0x8e,
-0x0c,0x00,0x03,0x24,0x0c,0x00,0x43,0xae,0x08,0x00,0x42,0xae,0x12,0x00,0x02,0x24,
-0x14,0x00,0x42,0xae,0x21,0x20,0x40,0x02,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x8b,0x07,0x00,0x08,0x20,0x00,0xbd,0x27,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
-0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x02,0x80,0x02,0x3c,0x21,0x48,0x80,0x00,
-0x68,0x15,0x48,0x24,0x21,0x38,0x00,0x00,0x21,0x28,0x27,0x01,0x00,0x00,0xa2,0x90,
-0x21,0x20,0xe8,0x00,0x01,0x00,0xe7,0x24,0x38,0x4c,0x82,0xa0,0x1e,0x00,0xa3,0x90,
-0x1e,0x00,0xe6,0x28,0x56,0x4c,0x83,0xa0,0x3c,0x00,0xa2,0x90,0x00,0x00,0x00,0x00,
-0x74,0x4c,0x82,0xa0,0x5a,0x00,0xa3,0x90,0xf3,0xff,0xc0,0x14,0x92,0x4c,0x83,0xa0,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
-0x20,0xbd,0x03,0x3c,0x58,0x00,0x63,0x34,0x00,0x00,0x62,0x90,0x0f,0x27,0x07,0x24,
-0x20,0x00,0x42,0x34,0x00,0x00,0x62,0xa0,0xff,0xff,0xe7,0x24,0xff,0xff,0xe1,0x04,
-0xff,0xff,0xe7,0x24,0x62,0xbd,0x04,0x3c,0x24,0x10,0x82,0x34,0x00,0x00,0x40,0xa0,
-0x28,0x10,0x83,0x34,0x0c,0x11,0x86,0x34,0x0e,0x00,0x02,0x24,0x00,0x00,0x60,0xa0,
-0x00,0x11,0x85,0x34,0x00,0x00,0xc2,0xa0,0x00,0x00,0xa7,0x8c,0xdf,0xff,0x02,0x24,
-0x10,0x00,0x86,0x34,0x24,0x38,0xe2,0x00,0x49,0x0c,0x03,0x24,0xcf,0xff,0x02,0x24,
-0x00,0x00,0xc3,0xac,0x04,0x00,0x84,0x34,0x00,0x00,0xa7,0xac,0x24,0x38,0xe2,0x00,
-0x41,0x0c,0x02,0x24,0x00,0x00,0xa7,0xac,0x00,0x00,0x80,0xac,0x00,0x00,0xc2,0xac,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0xd0,0xff,0xbd,0x27,0x25,0xb0,0x03,0x3c,
-0x01,0x80,0x02,0x3c,0xb0,0x03,0x68,0x34,0x1c,0x00,0xb1,0xaf,0x18,0x03,0x63,0x34,
-0xd8,0xff,0x91,0x24,0xa0,0x08,0x42,0x24,0x00,0x00,0x62,0xac,0x28,0x00,0xbf,0xaf,
-0x00,0x00,0x11,0xad,0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf,
-0x02,0x80,0x13,0x3c,0x00,0x00,0x23,0x96,0x68,0x15,0x73,0x26,0xff,0xff,0x32,0x32,
-0x40,0x10,0x02,0x3c,0x78,0x64,0x65,0x8e,0x25,0x90,0x42,0x02,0x02,0x80,0x10,0x3c,
-0x8c,0x96,0x10,0x26,0x20,0x00,0x42,0x26,0x00,0x00,0x03,0xad,0x20,0x00,0x06,0x24,
-0x00,0x00,0x02,0xad,0x21,0x38,0x00,0x02,0x0c,0x00,0x03,0xae,0x0a,0x00,0x04,0x24,
-0x64,0x01,0x00,0x0c,0x08,0x00,0x02,0xae,0x04,0x00,0x23,0x8e,0xff,0xe0,0x02,0x24,
-0x28,0x00,0x04,0x24,0x24,0x18,0x62,0x00,0x00,0x10,0x63,0x34,0x02,0x00,0x24,0xa2,
-0x04,0x00,0x23,0xae,0x0c,0x00,0x02,0x8e,0x0a,0x00,0x04,0x24,0xf8,0xff,0x42,0x24,
-0x4d,0x01,0x00,0x0c,0x00,0x00,0x22,0xa6,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0c,0x00,0x07,0x8e,0x20,0x10,0x06,0x3c,
-0x21,0x28,0x40,0x02,0x20,0x00,0xe7,0x24,0x00,0xfe,0xc6,0x34,0xff,0xff,0xe7,0x30,
-0x01,0x00,0x11,0x24,0x0a,0x00,0x04,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xb1,0xaf,
-0xd5,0x4a,0x63,0x92,0x2a,0xb0,0x10,0x3c,0x32,0x00,0x02,0x36,0x01,0x00,0x63,0x24,
-0x00,0x00,0x43,0xa0,0x4d,0x01,0x00,0x0c,0x0a,0x00,0x04,0x24,0xc9,0x64,0x62,0x92,
-0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xc9,0x64,0x62,0xa2,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x01,0x00,0x10,0x36,0x00,0x00,0x11,0xa2,
-0x28,0x00,0xbf,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,
-0x18,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,
-0x25,0xb0,0x05,0x3c,0x01,0x80,0x03,0x3c,0x21,0x38,0x80,0x00,0x18,0x03,0xa2,0x34,
-0xe8,0x09,0x63,0x24,0x01,0x00,0x04,0x24,0x00,0x00,0x43,0xac,0x35,0x00,0xe4,0x10,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x10,0x20,0x08,0xa2,0x34,0x02,0x00,0x02,0x24,
-0x83,0x00,0xe2,0x10,0x03,0x00,0x02,0x24,0x5a,0x00,0xe2,0x10,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x03,0x3c,0x00,0x00,0x44,0x8c,
-0x68,0x15,0x66,0x24,0x70,0x08,0x02,0x24,0xe0,0x08,0x03,0x24,0x74,0x4b,0xc2,0xac,
-0x40,0x08,0x02,0x24,0x78,0x4b,0xc3,0xac,0x84,0x4b,0xc2,0xac,0x78,0x08,0x03,0x24,
-0x0c,0x08,0x02,0x24,0x88,0x4b,0xc3,0xac,0x8c,0x4b,0xc2,0xac,0x10,0x08,0x03,0x24,
-0x20,0x08,0x02,0x24,0x90,0x4b,0xc3,0xac,0x94,0x4b,0xc2,0xac,0x24,0x08,0x03,0x24,
-0x58,0x08,0x02,0x24,0x98,0x4b,0xc3,0xac,0x9c,0x4b,0xc2,0xac,0x50,0x0c,0x03,0x24,
-0x54,0x0c,0x02,0x24,0xa0,0x4b,0xc3,0xac,0xa4,0x4b,0xc2,0xac,0x14,0x0c,0x03,0x24,
-0x10,0x0c,0x02,0x24,0x60,0x08,0x05,0x24,0xa8,0x4b,0xc3,0xac,0xac,0x4b,0xc2,0xac,
-0x80,0x0c,0x03,0x24,0x84,0x0c,0x02,0x24,0x00,0x01,0x84,0x30,0xb4,0x4b,0xc2,0xac,
-0x80,0x4b,0xc5,0xac,0xb0,0x4b,0xc3,0xac,0x71,0x4b,0xc0,0xa0,0x7c,0x4b,0xc5,0xac,
-0x02,0x00,0x80,0x10,0xa0,0x08,0x02,0x24,0xb8,0x08,0x02,0x24,0x08,0x00,0xe0,0x03,
-0xb8,0x4b,0xc2,0xac,0x28,0x08,0xa2,0x34,0x02,0x80,0x03,0x3c,0x00,0x00,0x44,0x8c,
-0x68,0x15,0x66,0x24,0x70,0x08,0x02,0x24,0xe0,0x08,0x03,0x24,0x74,0x4b,0xc2,0xac,
-0x44,0x08,0x02,0x24,0x78,0x4b,0xc3,0xac,0x84,0x4b,0xc2,0xac,0x78,0x08,0x03,0x24,
-0x0c,0x08,0x02,0x24,0x88,0x4b,0xc3,0xac,0x8c,0x4b,0xc2,0xac,0x14,0x08,0x03,0x24,
-0x28,0x08,0x02,0x24,0x90,0x4b,0xc3,0xac,0x94,0x4b,0xc2,0xac,0x2c,0x08,0x03,0x24,
-0x58,0x08,0x02,0x24,0x98,0x4b,0xc3,0xac,0x9c,0x4b,0xc2,0xac,0x58,0x0c,0x03,0x24,
-0x5c,0x0c,0x02,0x24,0xa0,0x4b,0xc3,0xac,0xa4,0x4b,0xc2,0xac,0x1c,0x0c,0x03,0x24,
-0x18,0x0c,0x02,0x24,0x64,0x08,0x05,0x24,0xa8,0x4b,0xc3,0xac,0xac,0x4b,0xc2,0xac,
-0x88,0x0c,0x03,0x24,0x8c,0x0c,0x02,0x24,0x00,0x01,0x84,0x30,0xb4,0x4b,0xc2,0xac,
-0x71,0x4b,0xc7,0xa0,0x80,0x4b,0xc5,0xac,0xb0,0x4b,0xc3,0xac,0x7c,0x4b,0xc5,0xac,
-0xd6,0xff,0x80,0x10,0xa4,0x08,0x02,0x24,0xbc,0x08,0x02,0x24,0x08,0x00,0xe0,0x03,
-0xb8,0x4b,0xc2,0xac,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0xac,0x08,0x03,0x24,
-0xb8,0x4b,0x43,0xac,0x74,0x08,0x03,0x24,0xe4,0x08,0x04,0x24,0x74,0x4b,0x43,0xac,
-0x4c,0x08,0x03,0x24,0x78,0x4b,0x44,0xac,0x84,0x4b,0x43,0xac,0x7c,0x08,0x04,0x24,
-0x0c,0x08,0x03,0x24,0x88,0x4b,0x44,0xac,0x8c,0x4b,0x43,0xac,0x1c,0x08,0x04,0x24,
-0x38,0x08,0x03,0x24,0x90,0x4b,0x44,0xac,0x94,0x4b,0x43,0xac,0x3c,0x08,0x04,0x24,
-0x5c,0x08,0x03,0x24,0x98,0x4b,0x44,0xac,0x9c,0x4b,0x43,0xac,0x68,0x0c,0x04,0x24,
-0x6c,0x0c,0x03,0x24,0xa0,0x4b,0x44,0xac,0xa4,0x4b,0x43,0xac,0x2c,0x0c,0x04,0x24,
-0x28,0x0c,0x03,0x24,0x6c,0x08,0x05,0x24,0xa8,0x4b,0x44,0xac,0xac,0x4b,0x43,0xac,
-0x98,0x0c,0x04,0x24,0x9c,0x0c,0x03,0x24,0x71,0x4b,0x47,0xa0,0x80,0x4b,0x45,0xac,
-0xb0,0x4b,0x44,0xac,0xb4,0x4b,0x43,0xac,0x08,0x00,0xe0,0x03,0x7c,0x4b,0x45,0xac,
-0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0xa8,0x08,0x03,0x24,0xb8,0x4b,0x43,0xac,
-0x74,0x08,0x03,0x24,0xe4,0x08,0x04,0x24,0x74,0x4b,0x43,0xac,0x48,0x08,0x03,0x24,
-0x78,0x4b,0x44,0xac,0x84,0x4b,0x43,0xac,0x7c,0x08,0x04,0x24,0x0c,0x08,0x03,0x24,
-0x88,0x4b,0x44,0xac,0x8c,0x4b,0x43,0xac,0x18,0x08,0x04,0x24,0x30,0x08,0x03,0x24,
-0x90,0x4b,0x44,0xac,0x94,0x4b,0x43,0xac,0x34,0x08,0x04,0x24,0x5c,0x08,0x03,0x24,
-0x98,0x4b,0x44,0xac,0x9c,0x4b,0x43,0xac,0x60,0x0c,0x04,0x24,0x64,0x0c,0x03,0x24,
-0xa0,0x4b,0x44,0xac,0xa4,0x4b,0x43,0xac,0x24,0x0c,0x04,0x24,0x20,0x0c,0x03,0x24,
-0x68,0x08,0x05,0x24,0xa8,0x4b,0x44,0xac,0xac,0x4b,0x43,0xac,0x90,0x0c,0x04,0x24,
-0x94,0x0c,0x03,0x24,0x71,0x4b,0x47,0xa0,0x80,0x4b,0x45,0xac,0xb0,0x4b,0x44,0xac,
-0xb4,0x4b,0x43,0xac,0x08,0x00,0xe0,0x03,0x7c,0x4b,0x45,0xac,0x36,0x43,0x00,0x08,
-0x21,0x18,0x00,0x00,0x20,0x00,0x62,0x2c,0x06,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
-0x06,0x10,0x64,0x00,0x01,0x00,0x42,0x30,0xfa,0xff,0x40,0x10,0x01,0x00,0x63,0x24,
-0xff,0xff,0x63,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0xd8,0xff,0xbd,0x27,
-0x25,0xb0,0x02,0x3c,0x18,0x00,0xb2,0xaf,0x21,0x90,0x82,0x00,0xff,0xff,0x02,0x24,
-0x1c,0x00,0xb3,0xaf,0x14,0x00,0xb1,0xaf,0x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,
-0x21,0x88,0xa0,0x00,0x21,0x20,0xa0,0x00,0x21,0x18,0x40,0x02,0x10,0x00,0xa2,0x10,
-0x21,0x98,0xc0,0x00,0x00,0x00,0x50,0x8e,0x31,0x43,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x04,0x10,0x53,0x00,0x27,0x18,0x11,0x00,0x25,0x18,0x62,0x00,0x24,0x18,0x70,0x00,
-0x00,0x00,0x43,0xae,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,
-0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x28,0x00,0xbd,0x27,0x00,0x00,0x66,0xac,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x21,0x30,0x80,0x00,0xec,0x60,0x44,0x8c,
-0x3d,0x43,0x00,0x08,0xff,0xff,0x05,0x24,0xe0,0xff,0xbd,0x27,0x25,0xb0,0x02,0x3c,
-0x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x21,0x20,0x82,0x00,
-0x00,0x00,0x90,0x8c,0x21,0x88,0xa0,0x00,0x31,0x43,0x00,0x0c,0x21,0x20,0xa0,0x00,
-0x24,0x80,0x11,0x02,0x06,0x10,0x50,0x00,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xd0,0xff,0xbd,0x27,
-0x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c,0x28,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf,
-0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x24,0x00,0xb5,0xaf,0x10,0x00,0xb0,0xaf,
-0x68,0x15,0x31,0x26,0x98,0x4b,0x22,0x8e,0x25,0xb0,0x12,0x3c,0x24,0x08,0x53,0x36,
-0x21,0x10,0x52,0x00,0x00,0x00,0x70,0x8e,0x00,0x00,0x55,0x8c,0x7f,0x80,0x03,0x3c,
-0xff,0x7f,0x02,0x3c,0xff,0xff,0x63,0x34,0xff,0xff,0x42,0x34,0x24,0x10,0x02,0x02,
-0x24,0x18,0xa3,0x02,0xc0,0x25,0x04,0x00,0x25,0x18,0x64,0x00,0x00,0x80,0x14,0x3c,
-0x00,0x00,0x62,0xae,0x01,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0x25,0xa8,0x74,0x00,
-0x98,0x4b,0x22,0x8e,0x25,0x80,0x14,0x02,0x01,0x00,0x04,0x24,0x21,0x10,0x52,0x00,
-0x00,0x00,0x55,0xac,0x84,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xae,
-0x84,0x0a,0x00,0x0c,0x01,0x00,0x04,0x24,0xb8,0x4b,0x24,0x8e,0x0f,0x00,0x05,0x3c,
-0x28,0x00,0xbf,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,
-0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0xff,0xff,0xa5,0x34,
-0x68,0x43,0x00,0x08,0x30,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,
-0x02,0x80,0x11,0x3c,0x10,0x00,0xb0,0xaf,0x18,0x00,0xbf,0xaf,0x68,0x15,0x27,0x26,
-0x73,0x4b,0xe5,0x90,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0xb0,0x0e,0x63,0x24,
-0x18,0x03,0x42,0x34,0x02,0x00,0x06,0x24,0x00,0x00,0x43,0xac,0x34,0x00,0xa6,0x10,
-0x21,0x80,0x80,0x00,0x03,0x00,0x03,0x24,0x3a,0x00,0xa3,0x10,0x2e,0x00,0x02,0x2e,
-0x10,0x00,0x02,0x2e,0x07,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xff,0x00,0x04,0x32,
-0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x79,0x43,0x00,0x08,
-0x20,0x00,0xbd,0x27,0xfa,0xff,0xa6,0x14,0xff,0x00,0x04,0x32,0x71,0x4b,0xe4,0x90,
-0x01,0x00,0x02,0x24,0x33,0x00,0x82,0x10,0x02,0x00,0x82,0x28,0x38,0x00,0x40,0x14,
-0x00,0x00,0x00,0x00,0x38,0x00,0x85,0x10,0x68,0x15,0x22,0x26,0x2e,0x00,0x83,0x10,
-0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x24,0x68,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,
-0xff,0xfc,0x06,0x3c,0xff,0xff,0xc6,0x34,0x24,0x30,0x46,0x00,0x00,0x08,0x04,0x24,
-0x3d,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,0x68,0x15,0x22,0x26,0x71,0x4b,0x44,0x90,
-0x01,0x00,0x03,0x24,0x07,0x00,0x83,0x10,0x02,0x00,0x82,0x28,0x2c,0x00,0x40,0x14,
-0x02,0x00,0x02,0x24,0x2c,0x00,0x82,0x10,0x03,0x00,0x02,0x24,0xdb,0xff,0x82,0x14,
-0x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,
-0x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00,0xc2,0x43,0x00,0x08,0xff,0x00,0x04,0x32,
-0x25,0x00,0x82,0x2c,0xcc,0xff,0x40,0x14,0x03,0x00,0x03,0x24,0x18,0x00,0xbf,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0xc7,0xff,0x40,0x14,0x10,0x00,0x02,0x2e,0x18,0x00,0xbf,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,
-0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,0xd4,0x43,0x00,0x08,0x00,0x08,0x04,0x24,
-0xcc,0xff,0x80,0x14,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24,
-0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,0xd4,0x43,0x00,0x08,0x00,0x08,0x04,0x24,
-0xb2,0xff,0x80,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,
-0x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00,0xc2,0x43,0x00,0x08,
-0xff,0x00,0x04,0x32,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c,
-0x68,0x15,0x28,0x26,0x73,0x4b,0x06,0x91,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
-0x5c,0x10,0x63,0x24,0x18,0x03,0x42,0x34,0x02,0x00,0x07,0x24,0x18,0x00,0xb2,0xaf,
-0x10,0x00,0xb0,0xaf,0x1c,0x00,0xbf,0xaf,0x00,0x00,0x43,0xac,0x21,0x90,0xa0,0x00,
-0x39,0x00,0xc7,0x10,0xff,0x00,0x90,0x30,0x03,0x00,0x03,0x24,0x3f,0x00,0xc3,0x10,
-0x2e,0x00,0x02,0x2e,0x10,0x00,0x02,0x2e,0x0c,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
-0x0f,0x00,0x04,0x3c,0xff,0xff,0x84,0x34,0x24,0x20,0x44,0x02,0x00,0x15,0x10,0x00,
-0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
-0x25,0x20,0x44,0x00,0x63,0x43,0x00,0x08,0x20,0x00,0xbd,0x27,0xf5,0xff,0xc7,0x14,
-0x0f,0x00,0x04,0x3c,0x71,0x4b,0x04,0x91,0x01,0x00,0x02,0x24,0x33,0x00,0x82,0x10,
-0x02,0x00,0x82,0x28,0x38,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x38,0x00,0x86,0x10,
-0x68,0x15,0x22,0x26,0x2e,0x00,0x83,0x10,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x24,
-0x68,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,0xff,0xfc,0x06,0x3c,0xff,0xff,0xc6,0x34,
-0x24,0x30,0x46,0x00,0x00,0x08,0x04,0x24,0x3d,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,
-0x68,0x15,0x22,0x26,0x71,0x4b,0x44,0x90,0x01,0x00,0x03,0x24,0x07,0x00,0x83,0x10,
-0x02,0x00,0x82,0x28,0x2c,0x00,0x40,0x14,0x02,0x00,0x02,0x24,0x2c,0x00,0x82,0x10,
-0x03,0x00,0x02,0x24,0xd6,0xff,0x82,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26,
-0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,0x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00,
-0x2f,0x44,0x00,0x08,0x0f,0x00,0x04,0x3c,0x25,0x00,0x02,0x2e,0xc7,0xff,0x40,0x14,
-0x03,0x00,0x03,0x24,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xc1,0xff,0x40,0x14,
-0x00,0x00,0x00,0x00,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x68,0x15,0x22,0x26,
-0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,
-0x46,0x44,0x00,0x08,0x00,0x08,0x04,0x24,0xcc,0xff,0x80,0x14,0x68,0x15,0x22,0x26,
-0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,
-0x46,0x44,0x00,0x08,0x00,0x08,0x04,0x24,0xad,0xff,0x80,0x14,0x00,0x00,0x00,0x00,
-0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c,
-0x21,0x30,0x00,0x00,0x2f,0x44,0x00,0x08,0x0f,0x00,0x04,0x3c,0xe8,0xff,0xbd,0x27,
-0x10,0x00,0xb0,0xaf,0x21,0x80,0x80,0x00,0x14,0x00,0xbf,0xaf,0x79,0x43,0x00,0x0c,
-0x21,0x20,0x00,0x00,0x40,0x01,0x44,0x34,0x21,0x18,0x40,0x00,0x1f,0x00,0x02,0x2e,
-0x00,0x23,0x04,0x00,0x10,0x00,0x40,0x10,0x10,0x00,0x05,0x2e,0x00,0x01,0x64,0x34,
-0x06,0x00,0xa0,0x10,0x00,0x23,0x04,0x00,0x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x63,0x43,0x00,0x0c,
-0xf1,0xff,0x10,0x26,0x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,
-0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x63,0x43,0x00,0x0c,0xe2,0xff,0x10,0x26,
-0x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
-0x18,0x00,0xbd,0x27,0x25,0xb0,0x02,0x3c,0x27,0x38,0x05,0x00,0x21,0x40,0x82,0x00,
-0xff,0xff,0x02,0x24,0x07,0x00,0xa2,0x10,0x25,0x38,0xe6,0x00,0x00,0x00,0x02,0x8d,
-0x00,0x00,0x00,0x00,0x24,0x10,0xe2,0x00,0x00,0x00,0x02,0xad,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xad,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x01,0x80,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xe8,0x12,0x42,0x24,0x18,0x03,0x63,0x34,
-0xd8,0xff,0xbd,0x27,0x00,0x00,0x62,0xac,0x0f,0x00,0x02,0x3c,0x14,0x00,0xb1,0xaf,
-0xff,0xff,0x42,0x34,0x21,0x88,0xa0,0x00,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,
-0x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x21,0x90,0xc0,0x00,0x21,0x28,0xc0,0x00,
-0x0a,0x00,0x22,0x12,0x21,0x98,0x80,0x00,0xac,0x43,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x21,0x20,0x20,0x02,0x31,0x43,0x00,0x0c,0x21,0x80,0x40,0x00,0x04,0x10,0x52,0x00,
-0x27,0x28,0x11,0x00,0x25,0x28,0xa2,0x00,0x24,0x28,0xb0,0x00,0xff,0x00,0x64,0x32,
-0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x17,0x44,0x00,0x08,0x28,0x00,0xbd,0x27,0x01,0x80,0x03,0x3c,
-0x25,0xb0,0x02,0x3c,0x74,0x13,0x63,0x24,0x18,0x03,0x42,0x34,0xe0,0xff,0xbd,0x27,
-0x00,0x00,0x43,0xac,0x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,
-0xac,0x43,0x00,0x0c,0x21,0x88,0xa0,0x00,0x21,0x80,0x40,0x00,0x31,0x43,0x00,0x0c,
-0x21,0x20,0x20,0x02,0x24,0x80,0x11,0x02,0x06,0x10,0x50,0x00,0x18,0x00,0xbf,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0xc8,0xff,0xbd,0x27,0x2c,0x00,0xb1,0xaf,0xff,0xff,0x05,0x24,0x21,0x88,0x80,0x00,
-0x02,0x00,0x06,0x24,0x10,0x00,0xa4,0x27,0x34,0x00,0xbf,0xaf,0x30,0x00,0xb2,0xaf,
-0x97,0x45,0x00,0x0c,0x28,0x00,0xb0,0xaf,0x08,0x00,0x30,0x96,0x02,0x80,0x02,0x3c,
-0x21,0x28,0x00,0x00,0x25,0x80,0x02,0x02,0x21,0x20,0x00,0x02,0x97,0x45,0x00,0x0c,
-0x10,0x00,0x06,0x24,0x20,0x00,0x02,0x96,0x24,0x00,0x04,0x26,0x10,0x00,0xa5,0x27,
-0x03,0xff,0x42,0x30,0xc8,0x00,0x42,0x34,0x20,0x00,0x02,0xa6,0x9f,0x45,0x00,0x0c,
-0x06,0x00,0x06,0x24,0x25,0xb0,0x03,0x3c,0x50,0x00,0x62,0x34,0x00,0x00,0x44,0x8c,
-0x54,0x00,0x65,0x34,0x58,0x00,0x66,0x34,0x18,0x00,0xa4,0xaf,0x00,0x00,0xa2,0x8c,
-0x5c,0x00,0x63,0x34,0x2a,0x00,0x04,0x26,0x1c,0x00,0xa2,0xaf,0x00,0x00,0xc7,0x8c,
-0x18,0x00,0xa5,0x27,0x06,0x00,0x06,0x24,0x20,0x00,0xa7,0xaf,0x00,0x00,0x62,0x8c,
-0x1a,0x00,0x12,0x24,0x9f,0x45,0x00,0x0c,0x24,0x00,0xa2,0xaf,0x30,0x00,0x04,0x26,
-0x20,0x00,0xa5,0x27,0x9f,0x45,0x00,0x0c,0x06,0x00,0x06,0x24,0x13,0x00,0x03,0x24,
-0x14,0x00,0x23,0xae,0x0c,0x00,0x32,0xae,0x08,0x00,0x05,0x8e,0x04,0x00,0x04,0x8e,
-0xff,0xdf,0x02,0x3c,0x14,0x00,0x06,0x8e,0xff,0xff,0x42,0x34,0x10,0x00,0x07,0x8e,
-0xff,0xe0,0x03,0x24,0x24,0x28,0xa2,0x00,0x00,0x40,0x02,0x3c,0x24,0x20,0x83,0x00,
-0x25,0x28,0xa2,0x00,0xff,0x81,0x03,0x24,0xfe,0xff,0x02,0x3c,0x24,0x30,0xc3,0x00,
-0xff,0xff,0x42,0x34,0x00,0x12,0x84,0x34,0x00,0x80,0x03,0x3c,0x24,0x20,0x82,0x00,
-0x25,0x38,0xe3,0x00,0x00,0x26,0xc6,0x34,0x80,0x00,0xa5,0x34,0x20,0x00,0x02,0x24,
-0x00,0x00,0x12,0xa6,0x10,0x00,0x07,0xae,0x02,0x00,0x02,0xa2,0x14,0x00,0x06,0xae,
-0x04,0x00,0x04,0xae,0x08,0x00,0x05,0xae,0x34,0x00,0xbf,0x8f,0x30,0x00,0xb2,0x8f,
-0x2c,0x00,0xb1,0x8f,0x28,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,
-0x93,0x45,0x00,0x08,0xff,0x00,0xa5,0x30,0x00,0x00,0x85,0xa0,0xff,0xff,0xc6,0x24,
-0x01,0x00,0x84,0x24,0xfc,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x05,0x00,0xc0,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac,
-0xff,0xff,0xc6,0x24,0xfd,0xff,0xc0,0x14,0x04,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x21,0x38,0x80,0x00,0x08,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24,
-0xff,0xff,0x06,0x24,0x00,0x00,0xa2,0x90,0xff,0xff,0x63,0x24,0x01,0x00,0xa5,0x24,
-0x00,0x00,0xe2,0xa0,0xfb,0xff,0x66,0x14,0x01,0x00,0xe7,0x24,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x80,0x00,0x21,0x38,0x80,0x00,0x08,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24,
-0xff,0xff,0x06,0x24,0x00,0x00,0xa2,0x8c,0xff,0xff,0x63,0x24,0x04,0x00,0xa5,0x24,
-0x00,0x00,0xe2,0xac,0xfb,0xff,0x66,0x14,0x04,0x00,0xe7,0x24,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x80,0x00,0x2b,0x10,0xa4,0x00,0x0d,0x00,0x40,0x14,0xff,0xff,0x02,0x24,
-0xff,0xff,0xc6,0x24,0x08,0x00,0xc2,0x10,0x21,0x18,0x80,0x00,0xff,0xff,0x07,0x24,
-0x00,0x00,0xa2,0x90,0xff,0xff,0xc6,0x24,0x01,0x00,0xa5,0x24,0x00,0x00,0x62,0xa0,
-0xfb,0xff,0xc7,0x14,0x01,0x00,0x63,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,
-0x21,0x28,0xa6,0x00,0x21,0x18,0x86,0x00,0xff,0xff,0xc6,0x24,0xfa,0xff,0xc2,0x10,
-0x00,0x00,0x00,0x00,0xff,0xff,0x07,0x24,0xff,0xff,0xa5,0x24,0x00,0x00,0xa2,0x90,
-0xff,0xff,0x63,0x24,0xff,0xff,0xc6,0x24,0xfb,0xff,0xc7,0x14,0x00,0x00,0x62,0xa0,
-0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0x0c,0x00,0xc0,0x10,0x00,0x00,0x00,0x00,
-0x00,0x00,0x82,0x90,0x00,0x00,0xa3,0x90,0x01,0x00,0x84,0x24,0x23,0x10,0x43,0x00,
-0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x04,0x00,0x40,0x14,0x01,0x00,0xa5,0x24,
-0xff,0xff,0xc6,0x24,0xf6,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x21,0x10,0xc0,0x00,0xea,0x45,0x00,0x08,0x21,0x18,0x86,0x00,0x00,0x00,0x82,0x90,
-0x00,0x00,0x00,0x00,0x04,0x00,0x45,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24,
-0xfa,0xff,0x83,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,
-0x09,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24,0xff,0x00,0xa5,0x30,0xff,0xff,0x06,0x24,
-0x00,0x00,0x82,0x90,0xff,0xff,0x63,0x24,0x05,0x00,0x45,0x10,0x01,0x00,0x84,0x24,
-0xfb,0xff,0x66,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0xff,0xff,0x82,0x24,0x21,0x38,0x00,0x00,0x1f,0x00,0xc0,0x10,
-0x21,0x18,0x00,0x00,0x02,0x80,0x02,0x3c,0x80,0x95,0x4b,0x24,0x00,0x00,0x87,0x90,
-0x00,0x00,0xa3,0x90,0xff,0xff,0xc6,0x24,0x01,0x00,0x84,0x24,0x21,0x10,0xeb,0x00,
-0x16,0x00,0xe0,0x10,0x01,0x00,0xa5,0x24,0x14,0x00,0x60,0x10,0x21,0x48,0x6b,0x00,
-0x10,0x00,0xe3,0x10,0x20,0x00,0xe8,0x24,0x00,0x00,0x42,0x90,0x00,0x00,0x00,0x00,
-0x01,0x00,0x42,0x30,0x02,0x00,0x40,0x10,0x20,0x00,0x6a,0x24,0xff,0x00,0x07,0x31,
-0x00,0x00,0x22,0x91,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30,0x02,0x00,0x40,0x10,
-0xff,0x00,0xe7,0x30,0xff,0x00,0x43,0x31,0xff,0x00,0x63,0x30,0x03,0x00,0xe3,0x14,
-0x00,0x00,0x00,0x00,0xe5,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x23,0x10,0xe3,0x00,0x21,0x18,0x80,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,
-0x00,0x00,0x82,0xa0,0xfc,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x60,0x00,0x21,0x38,0x80,0x00,0xff,0xff,0x03,0x24,0xff,0xff,0xc6,0x24,
-0x06,0x00,0xc3,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,
-0x00,0x00,0x82,0xa0,0xf9,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,
-0x21,0x10,0xe0,0x00,0x00,0x00,0x82,0x80,0x39,0x46,0x00,0x08,0x21,0x18,0x80,0x00,
-0x01,0x00,0x84,0x24,0x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00,0xfc,0xff,0x40,0x14,
-0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,0x00,0x00,0x82,0xa0,
-0xfc,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
-0x12,0x00,0xc0,0x10,0x21,0x18,0x80,0x00,0x00,0x00,0x82,0x80,0x4a,0x46,0x00,0x08,
-0x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24,0x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00,
-0xfc,0xff,0x40,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,
-0x00,0x00,0x82,0xa0,0x05,0x00,0x40,0x10,0x01,0x00,0x84,0x24,0xff,0xff,0xc6,0x24,
-0xf9,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa0,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x60,0x00,0x00,0x00,0x83,0x90,0x00,0x00,0xa2,0x90,0x01,0x00,0x84,0x24,
-0x23,0x10,0x62,0x00,0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x03,0x00,0x40,0x14,
-0x01,0x00,0xa5,0x24,0xf7,0xff,0x60,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x21,0x10,0x00,0x00,0x0b,0x00,0xc0,0x10,0x00,0x00,0x00,0x00,
-0x00,0x00,0xa2,0x90,0x00,0x00,0x83,0x90,0xff,0xff,0xc6,0x24,0x23,0x10,0x62,0x00,
-0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x03,0x00,0x40,0x14,0x01,0x00,0xa5,0x24,
-0xf5,0xff,0x60,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x00,0x00,0x83,0x80,0x00,0x2e,0x05,0x00,0x21,0x10,0x80,0x00,0x7b,0x46,0x00,0x08,
-0x03,0x2e,0x05,0x00,0x07,0x00,0x60,0x10,0x01,0x00,0x42,0x24,0x00,0x00,0x43,0x80,
-0x00,0x00,0x00,0x00,0xfb,0xff,0x65,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x00,0x00,0x82,0x80,
-0x87,0x46,0x00,0x08,0x21,0x18,0x80,0x00,0x01,0x00,0x63,0x24,0x00,0x00,0x62,0x80,
-0x00,0x00,0x00,0x00,0xfc,0xff,0x40,0x14,0x23,0x10,0x64,0x00,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x21,0x80,0xa0,0x00,
-0x14,0x00,0xb1,0xaf,0x18,0x00,0xbf,0xaf,0x21,0x88,0x80,0x00,0x81,0x46,0x00,0x0c,
-0x00,0x86,0x10,0x00,0x21,0x18,0x51,0x00,0x03,0x86,0x10,0x00,0x00,0x00,0x62,0x80,
-0x00,0x00,0x00,0x00,0x0a,0x00,0x50,0x10,0x21,0x10,0x60,0x00,0xff,0xff,0x63,0x24,
-0x2b,0x10,0x71,0x00,0xf9,0xff,0x40,0x10,0x21,0x10,0x00,0x00,0x18,0x00,0xbf,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
-0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0x21,0x30,0x80,0x00,0x0d,0x00,0xa0,0x10,0xff,0xff,0xa3,0x24,
-0x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00,0x09,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
-0xff,0xff,0x05,0x24,0xff,0xff,0x63,0x24,0x05,0x00,0x65,0x10,0x01,0x00,0xc6,0x24,
-0x00,0x00,0xc2,0x80,0x00,0x00,0x00,0x00,0xfa,0xff,0x40,0x14,0x00,0x00,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x23,0x10,0xc4,0x00,0x00,0x00,0x82,0x90,0x00,0x00,0x00,0x00,
-0x19,0x00,0x40,0x10,0x21,0x40,0x00,0x00,0x00,0x00,0xa9,0x80,0x00,0x00,0x00,0x00,
-0x17,0x00,0x20,0x11,0x21,0x30,0xa0,0x00,0x00,0x3e,0x02,0x00,0x03,0x3e,0x07,0x00,
-0x21,0x18,0x20,0x01,0x15,0x00,0xe3,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0xc6,0x24,
-0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0x00,0x1e,0x02,0x00,0x03,0x1e,0x03,0x00,
-0xf8,0xff,0x60,0x14,0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x06,0x00,0x40,0x10,
-0x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24,0x00,0x00,0x82,0x90,0x00,0x00,0x00,0x00,
-0xeb,0xff,0x40,0x14,0x01,0x00,0x08,0x25,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x01,
-0x00,0x00,0xa2,0x90,0xcc,0x46,0x00,0x08,0x00,0x16,0x02,0x00,0x00,0x00,0xc2,0x90,
-0xcc,0x46,0x00,0x08,0x00,0x16,0x02,0x00,0x00,0x00,0x87,0x90,0x00,0x00,0x00,0x00,
-0x14,0x00,0xe0,0x10,0x21,0x10,0x80,0x00,0x00,0x00,0xa4,0x90,0x00,0x00,0x00,0x00,
-0x00,0x1e,0x04,0x00,0x03,0x1e,0x03,0x00,0x09,0x00,0x60,0x10,0x21,0x30,0xa0,0x00,
-0x00,0x3e,0x07,0x00,0x03,0x3e,0x07,0x00,0x0b,0x00,0xe3,0x10,0x01,0x00,0xc6,0x24,
-0x00,0x00,0xc3,0x80,0x00,0x00,0x00,0x00,0xfb,0xff,0x60,0x14,0x00,0x00,0x00,0x00,
-0x01,0x00,0x42,0x24,0x00,0x00,0x47,0x90,0x00,0x00,0x00,0x00,0xf0,0xff,0xe0,0x14,
-0x00,0x00,0x00,0x00,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x18,0x00,0xbf,0xaf,
-0x21,0x80,0x80,0x00,0x1d,0x00,0x80,0x10,0x21,0x88,0xa0,0x00,0xb8,0x46,0x00,0x0c,
-0x21,0x20,0x00,0x02,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82,0x21,0x28,0x20,0x02,
-0x21,0x20,0x00,0x02,0x22,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xdc,0x46,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x10,0x21,0x18,0x40,0x00,0x00,0x00,0x42,0x80,
-0x00,0x00,0x00,0x00,0x0a,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,
-0xa8,0x96,0x43,0xac,0x21,0x18,0x00,0x02,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x21,0x10,0x60,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
-0x00,0x00,0x60,0xa0,0x0d,0x47,0x00,0x08,0x01,0x00,0x63,0x24,0x02,0x80,0x02,0x3c,
-0xa8,0x96,0x50,0x8c,0x00,0x00,0x00,0x00,0xf3,0xff,0x00,0x12,0x21,0x18,0x00,0x00,
-0xb8,0x46,0x00,0x0c,0x21,0x20,0x00,0x02,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82,
-0x21,0x28,0x20,0x02,0x21,0x20,0x00,0x02,0xe0,0xff,0x40,0x14,0x21,0x18,0x00,0x00,
-0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x02,0x80,0x02,0x3c,
-0xa8,0x96,0x40,0xac,0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
-0xe0,0xff,0xbd,0x27,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x1c,0x00,0xbf,0xaf,
-0x10,0x00,0xb0,0xaf,0x00,0x00,0x90,0x8c,0x21,0x90,0x80,0x00,0x21,0x88,0xa0,0x00,
-0x21,0x18,0x00,0x00,0x0f,0x00,0x00,0x12,0x21,0x20,0x00,0x02,0xb8,0x46,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82,0x21,0x28,0x20,0x02,
-0x21,0x20,0x00,0x02,0x07,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xdc,0x46,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x21,0x18,0x40,0x00,0x09,0x00,0x40,0x14,0x00,0x00,0x42,0xae,
-0x21,0x18,0x00,0x02,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x21,0x10,0x60,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
-0x00,0x00,0x42,0x80,0x00,0x00,0x00,0x00,0xf5,0xff,0x40,0x10,0x01,0x00,0x64,0x24,
-0x00,0x00,0x60,0xa0,0x46,0x47,0x00,0x08,0x00,0x00,0x44,0xae,0xd8,0xff,0xbd,0x27,
-0x14,0x00,0xb1,0xaf,0x21,0x88,0x80,0x00,0x21,0x20,0xa0,0x00,0x1c,0x00,0xb3,0xaf,
-0x18,0x00,0xb2,0xaf,0x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x81,0x46,0x00,0x0c,
-0x21,0x98,0xa0,0x00,0x21,0x90,0x40,0x00,0x08,0x00,0x40,0x16,0x21,0x10,0x20,0x02,
-0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x81,0x46,0x00,0x0c,
-0x21,0x20,0x20,0x02,0x21,0x80,0x40,0x00,0x2a,0x10,0x52,0x00,0x0a,0x00,0x40,0x14,
-0x00,0x00,0x00,0x00,0x21,0x20,0x20,0x02,0x21,0x28,0x60,0x02,0x21,0x30,0x40,0x02,
-0xd4,0x45,0x00,0x0c,0xff,0xff,0x10,0x26,0x0b,0x00,0x40,0x10,0x2a,0x18,0x12,0x02,
-0xf8,0xff,0x60,0x10,0x01,0x00,0x31,0x26,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,
-0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,
-0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x62,0x47,0x00,0x08,0x21,0x10,0x20,0x02,
-0x01,0x80,0x02,0x3c,0xc0,0xff,0xbd,0x27,0x08,0x1e,0x44,0x24,0x25,0xb0,0x02,0x3c,
-0x28,0x00,0xb4,0xaf,0x02,0x80,0x03,0x3c,0x25,0xb0,0x14,0x3c,0x18,0x03,0x42,0x34,
-0x38,0x00,0xbe,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,
-0x24,0x00,0xb3,0xaf,0x3c,0x00,0xbf,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,
-0x18,0x00,0xb0,0xaf,0x68,0x15,0x73,0x24,0x00,0x00,0x44,0xac,0x02,0x80,0x16,0x3c,
-0x02,0x80,0x15,0x3c,0xc4,0x02,0x9e,0x36,0x64,0x03,0x97,0x36,0x01,0x80,0x04,0x3c,
-0x08,0x1e,0x82,0x24,0x18,0x03,0x83,0x36,0x00,0x00,0x62,0xac,0xa0,0x02,0x87,0x36,
-0x00,0x00,0xe4,0x8c,0xd8,0x63,0x63,0x8e,0xff,0x0f,0x02,0x3c,0xff,0xff,0x46,0x34,
-0x24,0x80,0x86,0x00,0x01,0x00,0x05,0x3c,0x01,0x00,0x63,0x24,0x2b,0x10,0xb0,0x00,
-0x07,0x00,0x40,0x10,0xd8,0x63,0x63,0xae,0xa4,0x02,0x82,0x36,0x00,0x00,0x51,0x8c,
-0x00,0xb0,0x03,0x3c,0x25,0x80,0x03,0x02,0x00,0x00,0x11,0xae,0x00,0x00,0xe0,0xac,
-0xb0,0x02,0x84,0x36,0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x80,0x46,0x00,
-0x2b,0x18,0xb0,0x00,0x08,0x00,0x60,0x10,0xc0,0x02,0x82,0x36,0x00,0xb0,0x02,0x3c,
-0x25,0x80,0x02,0x02,0x00,0x00,0x11,0x8e,0xb4,0x02,0x82,0x36,0x00,0x00,0x51,0xac,
-0x00,0x00,0x80,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x50,0x8c,0xff,0x00,0x08,0x3c,
-0xff,0xff,0x02,0x35,0x2b,0x10,0x50,0x00,0x47,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
-0x00,0x00,0x82,0x8e,0x00,0xff,0x06,0x3c,0xac,0x02,0x84,0x36,0x01,0x00,0x45,0x24,
-0xbc,0x02,0x83,0x36,0xff,0x00,0xc2,0x34,0x00,0xfd,0x07,0x3c,0x00,0x00,0x85,0xac,
-0x00,0x00,0x70,0xac,0x24,0x18,0x02,0x02,0x07,0x00,0xe2,0x34,0x00,0x00,0x85,0x8c,
-0x52,0x03,0x62,0x10,0x25,0xb0,0x12,0x3c,0x2b,0x10,0x43,0x00,0xa2,0x00,0x40,0x14,
-0xa4,0x00,0xe2,0x34,0x00,0xf8,0x04,0x3c,0x15,0x00,0x82,0x34,0x57,0x03,0x62,0x10,
-0x2b,0x10,0x43,0x00,0xc8,0x00,0x40,0x14,0x00,0xf9,0x05,0x3c,0x00,0xf0,0x05,0x3c,
-0x20,0x00,0xa2,0x34,0x67,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x20,0x01,0x40,0x14,
-0x10,0x00,0x82,0x34,0x70,0x03,0x65,0x10,0x2b,0x10,0xa3,0x00,0xc8,0x01,0x40,0x14,
-0x02,0x00,0xa2,0x34,0x00,0xd0,0x02,0x3c,0x2a,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,
-0xaf,0x02,0x40,0x14,0x00,0xe0,0x02,0x3c,0x00,0xc0,0x02,0x3c,0xbb,0x03,0x62,0x10,
-0xff,0x00,0x03,0x3c,0x00,0xf0,0x02,0x3c,0x24,0x30,0x02,0x02,0x18,0x00,0xc2,0x10,
-0x02,0x1d,0x10,0x00,0x00,0x70,0x05,0x3c,0x24,0x10,0x05,0x02,0x02,0x4f,0x02,0x00,
-0x0f,0x00,0x02,0x3c,0xff,0xff,0x42,0x34,0x00,0x50,0x07,0x3c,0xff,0x00,0x68,0x30,
-0xff,0x00,0x04,0x32,0x96,0x01,0xc7,0x10,0x24,0x18,0x02,0x02,0x2b,0x10,0xe6,0x00,
-0x8a,0x01,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0x20,0x02,0x3c,0x1a,0x03,0xc2,0x10,
-0x2b,0x10,0x46,0x00,0x82,0x02,0x40,0x14,0x00,0x30,0x02,0x3c,0x17,0x03,0xc0,0x10,
-0x80,0x10,0x08,0x00,0x00,0x10,0x02,0x3c,0x14,0x03,0xc2,0x10,0x80,0x10,0x08,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x00,0x00,0xe2,0x92,0x25,0xb0,0x07,0x3c,
-0xc8,0x7d,0xc2,0xa2,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0xc8,0x7d,0xc2,0x92,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30,0x4e,0x00,0x40,0x10,
-0x02,0x80,0x03,0x3c,0x00,0x40,0x62,0x8e,0xf0,0xff,0x03,0x24,0xd7,0x42,0x60,0xa2,
-0x24,0x10,0x43,0x00,0x01,0x00,0x42,0x34,0x00,0x40,0x62,0xae,0xc8,0x7d,0xc2,0x92,
-0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x30,0x3d,0x00,0x40,0x10,0x0f,0xff,0x03,0x24,
-0x00,0x40,0x62,0x8e,0x00,0x00,0x00,0x00,0x24,0x10,0x43,0x00,0x10,0x00,0x42,0x34,
-0x00,0x40,0x62,0xae,0xc8,0x7d,0xc2,0x92,0x00,0x00,0x00,0x00,0x04,0x00,0x42,0x30,
-0x30,0x00,0x40,0x10,0xff,0xf0,0x03,0x24,0x00,0x40,0x62,0x8e,0x00,0x00,0x00,0x00,
-0x24,0x10,0x43,0x00,0x00,0x01,0x42,0x34,0x25,0xb0,0x05,0x3c,0x00,0x40,0x62,0xae,
-0x4c,0x00,0xa3,0x34,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30,
-0x05,0x00,0x40,0x14,0xff,0xff,0x02,0x3c,0x00,0x40,0x63,0x8e,0xff,0x0f,0x42,0x34,
-0x24,0x18,0x62,0x00,0x00,0x40,0x63,0xae,0x00,0x7b,0xa4,0x8e,0x01,0x80,0x06,0x3c,
-0x08,0x1f,0xc2,0x24,0x18,0x03,0xa3,0x34,0x00,0x7b,0xa6,0x26,0x00,0x00,0x62,0xac,
-0x10,0x00,0x86,0x10,0x02,0x80,0x02,0x3c,0xbf,0x00,0xb2,0x34,0x68,0x15,0x51,0x24,
-0x21,0x80,0xc0,0x00,0x00,0x00,0x42,0x92,0x00,0x00,0x00,0x00,0x04,0x00,0x42,0x2c,
-0x09,0x00,0x40,0x10,0x02,0x80,0x07,0x3c,0x98,0x65,0x24,0x8e,0x8b,0x07,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0x7b,0xa2,0x8e,0x00,0x00,0x00,0x00,0xf5,0xff,0x50,0x14,
-0x00,0x00,0x00,0x00,0x02,0x80,0x07,0x3c,0x08,0x08,0xe4,0x24,0x21,0x28,0x00,0x00,
-0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0x9a,0x47,0x00,0x08,
-0x01,0x80,0x04,0x3c,0x00,0x40,0x62,0x8e,0x30,0x48,0x00,0x08,0x24,0x10,0x43,0x00,
-0x00,0x40,0x62,0x8e,0x04,0x43,0x64,0x92,0x24,0x10,0x43,0x00,0x00,0x40,0x62,0xae,
-0x27,0x48,0x00,0x08,0x04,0x43,0x64,0xae,0x68,0x15,0x66,0x24,0x00,0x40,0xc2,0x8c,
-0xd7,0x42,0xc4,0x90,0xf0,0xff,0x03,0x24,0x24,0x10,0x43,0x00,0xb3,0xff,0x80,0x14,
-0x00,0x40,0xc2,0xac,0x1c,0x00,0x04,0x24,0x58,0x0c,0xe5,0x34,0x50,0x0c,0xe3,0x34,
-0x01,0x00,0x02,0x24,0xd7,0x42,0xc2,0xa0,0x00,0x00,0x64,0xa0,0x00,0x00,0xa4,0xa0,
-0x1d,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xb2,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,
-0x3f,0x00,0x40,0x14,0xaf,0x00,0xe2,0x34,0x20,0x00,0xe2,0x34,0xc0,0x02,0x62,0x10,
-0x2b,0x10,0x43,0x00,0xe3,0x00,0x40,0x14,0x29,0x00,0xe2,0x34,0x15,0x00,0xe2,0x34,
-0x0c,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x9d,0x01,0x40,0x14,0x17,0x00,0xe2,0x34,
-0x09,0x00,0xe2,0x34,0xd8,0x03,0x62,0x10,0x2b,0x10,0x62,0x00,0x81,0x02,0x40,0x14,
-0x14,0x00,0xe2,0x34,0x64,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c,0xff,0x00,0x07,0x3c,
-0x00,0xff,0xe7,0x34,0x24,0x10,0x07,0x02,0x7a,0xff,0x40,0x10,0xc0,0x02,0x82,0x36,
-0x04,0x43,0x64,0x92,0xff,0x00,0x02,0x3c,0x24,0x10,0x02,0x02,0x00,0xff,0x03,0x32,
-0x02,0x14,0x02,0x00,0x02,0x1a,0x03,0x00,0xfb,0xff,0x45,0x24,0x1c,0x43,0x62,0xa2,
-0x00,0x01,0x84,0x34,0xfb,0xff,0x66,0x24,0xc0,0x02,0x82,0x36,0x04,0x43,0x64,0xae,
-0x1d,0x43,0x65,0xa2,0x1f,0x43,0x66,0xa2,0x1e,0x43,0x63,0xa2,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x05,0x00,0xa2,0x34,0x91,0x02,0x62,0x10,
-0x2b,0x10,0x43,0x00,0x8e,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xde,0x02,0x65,0x10,
-0x2b,0x10,0xa3,0x00,0x32,0x01,0x40,0x14,0x02,0x00,0xa2,0x34,0x17,0x00,0x82,0x34,
-0x61,0x04,0x62,0x10,0x2b,0x10,0x62,0x00,0xa9,0x03,0x40,0x14,0x18,0x00,0x82,0x34,
-0x3d,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c,0x74,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0xa8,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0x95,0x00,0x40,0x14,0x0c,0x00,0xc2,0x34,
-0xaa,0x00,0xe2,0x34,0xdc,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xd9,0x00,0x40,0x14,
-0xac,0x00,0xe2,0x34,0xa6,0x00,0xe2,0x34,0x1c,0x04,0x62,0x10,0x2b,0x10,0x62,0x00,
-0x69,0x03,0x40,0x14,0xa7,0x00,0xe2,0x34,0x27,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c,
-0x00,0xff,0x02,0x32,0xff,0x00,0x04,0x3c,0x02,0x8a,0x02,0x00,0x24,0x18,0x04,0x02,
-0x01,0x00,0x02,0x24,0xa6,0x04,0x22,0x12,0x02,0x1c,0x03,0x00,0x02,0x00,0x02,0x24,
-0xc9,0x04,0x22,0x12,0x03,0x00,0x02,0x24,0xdf,0x04,0x22,0x12,0x04,0x00,0x02,0x24,
-0xd1,0x04,0x22,0x12,0x08,0x00,0x02,0x24,0x2e,0x05,0x22,0x12,0x09,0x00,0x02,0x24,
-0x1e,0x05,0x22,0x12,0x0a,0x00,0x02,0x24,0x0e,0x05,0x22,0x12,0x0b,0x00,0x02,0x24,
-0xfe,0x04,0x22,0x12,0x0c,0x00,0x02,0x24,0x5e,0x05,0x22,0x12,0x0d,0x00,0x02,0x24,
-0x4e,0x05,0x22,0x12,0x0e,0x00,0x02,0x24,0x3e,0x05,0x22,0x12,0x0f,0x00,0x02,0x24,
-0x2e,0x05,0x22,0x12,0x10,0x00,0x02,0x24,0x22,0xff,0x22,0x16,0xc0,0x02,0x82,0x36,
-0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,
-0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,0x4c,0x51,0x43,0x94,0x48,0x51,0x44,0x94,
-0x25,0xb0,0x06,0x3c,0x00,0x1c,0x03,0x00,0x21,0x20,0x83,0x00,0x00,0x00,0xc4,0xaf,
-0x58,0x51,0x45,0x8c,0x54,0x51,0x43,0x8c,0x50,0x51,0x44,0x94,0xc8,0x02,0xc6,0x34,
-0x21,0x18,0x65,0x00,0x00,0x1c,0x03,0x00,0x21,0x20,0x83,0x00,0xc0,0x02,0x82,0x36,
-0x00,0x00,0xc4,0xac,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x66,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xbf,0x00,0x40,0x14,0x12,0x00,0x82,0x34,
-0x00,0xf1,0x04,0x3c,0x01,0x00,0x82,0x34,0xc1,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,
-0xb7,0x01,0x40,0x14,0x02,0x00,0x82,0x34,0xe3,0xfe,0x64,0x14,0x00,0xf0,0x02,0x3c,
-0xff,0x00,0x04,0x3c,0x00,0xff,0x84,0x34,0x24,0x10,0x04,0x02,0x02,0x8a,0x02,0x00,
-0x80,0x1a,0x11,0x00,0x00,0xf4,0x63,0x24,0x94,0x00,0x82,0x36,0x00,0x00,0x51,0xa4,
-0x26,0xb0,0x04,0x3c,0x42,0x89,0x03,0x00,0x98,0x00,0x86,0x36,0xff,0x01,0x02,0x24,
-0x10,0x00,0x03,0x24,0x9a,0x00,0x85,0x36,0x00,0x00,0xa2,0xa4,0x7c,0x00,0x89,0x34,
-0x00,0x00,0xc3,0xa4,0x01,0x00,0x02,0x24,0x04,0x00,0x03,0x24,0x96,0x00,0x87,0x36,
-0x7a,0x00,0x84,0x34,0xb0,0x03,0x88,0x36,0x25,0xb0,0x06,0x3c,0x00,0x00,0xe2,0xa4,
-0x44,0x00,0xc6,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0x11,0xad,0x00,0x00,0x31,0xa5,
-0x00,0x00,0xc3,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x00,0xc3,0xa4,
-0x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34,0x00,0x00,0xc2,0xa4,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x65,0x01,0x67,0x10,0x2b,0x10,0xe3,0x00,0xc5,0x00,0x40,0x14,0x02,0x00,0xe2,0x34,
-0x07,0x00,0xa2,0x34,0xfc,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xa9,0x01,0x40,0x14,
-0x20,0x00,0xa2,0x34,0xb0,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,0xff,0x00,0x03,0x3c,
-0x00,0xff,0x63,0x34,0x24,0x10,0x03,0x02,0x02,0x3a,0x02,0x00,0x80,0x04,0xe0,0x10,
-0x02,0x80,0x04,0x3c,0x05,0x00,0x02,0x24,0xc2,0xfe,0xe2,0x14,0xc0,0x02,0x82,0x36,
-0x02,0x80,0x06,0x3c,0x8f,0x7d,0xc2,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x2e,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0x98,0x00,0x40,0x14,0x0e,0x00,0xc2,0x34,
-0x01,0x00,0xc2,0x34,0xab,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x48,0x01,0x40,0x14,
-0x00,0xff,0x02,0x3c,0x94,0xfe,0x66,0x14,0x00,0xf0,0x02,0x3c,0x5b,0x4e,0x00,0x0c,
-0x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x4c,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xa6,0x00,0x40,0x14,
-0xa1,0x00,0xe2,0x34,0x22,0x00,0xe2,0x34,0xbd,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,
-0x88,0x01,0x40,0x14,0x00,0x20,0x02,0x3c,0x28,0x00,0xe2,0x34,0x82,0xfe,0x62,0x14,
-0x00,0xf0,0x02,0x3c,0x0f,0x00,0x04,0x3c,0xff,0xff,0x85,0x34,0x60,0x00,0x06,0x24,
-0xba,0x44,0x00,0x0c,0x24,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0xe8,0x03,0x04,0x24,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x0f,0x00,0x06,0x3c,0x24,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0xc5,0x34,
-0x1f,0x00,0x51,0x30,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xa3,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x18,0x02,0xc2,0x10,
-0x2b,0x10,0x46,0x00,0x01,0x01,0x40,0x14,0x00,0xa0,0x02,0x3c,0x00,0x60,0x02,0x3c,
-0x04,0x00,0xc2,0x10,0x80,0x10,0x08,0x00,0x7a,0xfe,0xc5,0x14,0xc0,0x02,0x82,0x36,
-0x80,0x10,0x08,0x00,0x21,0x10,0x48,0x00,0x21,0x10,0x53,0x00,0x21,0x10,0x49,0x00,
-0xc1,0x43,0x44,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3f,0x03,0x62,0x10,0x2b,0x10,0x62,0x00,0xb6,0x02,0x40,0x14,
-0xad,0x00,0xe2,0x34,0xc7,0x03,0x62,0x10,0xae,0x00,0xe2,0x34,0x4e,0xfe,0x62,0x14,
-0x00,0xf0,0x02,0x3c,0xff,0x00,0x02,0x3c,0x24,0x20,0x02,0x02,0x00,0xff,0x05,0x32,
-0x02,0x24,0x04,0x00,0x69,0x4f,0x00,0x0c,0x02,0x2a,0x05,0x00,0x00,0x00,0xc2,0xa3,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x4b,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0x17,0x01,0x40,0x14,0x03,0x00,0xa2,0x34,
-0x82,0x03,0x62,0x10,0x08,0x00,0xa2,0x34,0x3b,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,
-0x00,0xff,0x02,0x32,0x02,0x82,0x02,0x00,0xcc,0x02,0x83,0x36,0x00,0x00,0x70,0xac,
-0x12,0x04,0x00,0x12,0x01,0x00,0x02,0x24,0x9c,0x04,0x02,0x12,0x00,0x00,0x00,0x00,
-0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x4e,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,
-0xe4,0x00,0x40,0x14,0x00,0xff,0x02,0x32,0x13,0x00,0x82,0x34,0x4c,0x03,0x62,0x10,
-0x14,0x00,0x82,0x34,0x24,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,0xd3,0x0a,0x00,0x0c,
-0xfd,0x00,0x04,0x24,0x10,0x10,0x03,0x3c,0xa0,0x00,0x82,0x36,0x10,0x10,0x63,0x34,
-0x00,0xc0,0x07,0x3c,0x25,0xb0,0x06,0x3c,0x00,0x00,0x43,0xac,0xa4,0x00,0x84,0x36,
-0x00,0xa1,0xe7,0x34,0xa8,0x00,0xc6,0x34,0xc0,0x02,0x82,0x36,0x00,0x00,0x80,0xac,
-0x00,0x00,0xc7,0xac,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x60,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xf6,0x00,0x40,0x14,0x03,0x00,0xa2,0x34,
-0x4b,0x03,0x62,0x10,0x04,0x00,0xa2,0x34,0x0b,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,
-0xf4,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x61,0x02,0x62,0x10,
-0x2b,0x10,0x62,0x00,0xfe,0x00,0x40,0x14,0x01,0x00,0x02,0x24,0x0f,0x00,0xc2,0x34,
-0x63,0x03,0x62,0x10,0x10,0x00,0xc2,0x34,0xfb,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,
-0x00,0xff,0x03,0x32,0x00,0xff,0x02,0x34,0x9d,0x03,0x62,0x10,0xc0,0x02,0x82,0x36,
-0x8c,0x65,0x60,0xae,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x47,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0x02,0x01,0x40,0x14,0x03,0x00,0xe2,0x34,
-0x8d,0x03,0x62,0x10,0x04,0x00,0xe2,0x34,0xeb,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,
-0x1e,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x9b,0x01,0x62,0x10,0x2b,0x10,0x43,0x00,
-0xcf,0x00,0x40,0x14,0xa2,0x00,0xe2,0x34,0xa0,0x00,0xe2,0x34,0xde,0xfd,0x62,0x14,
-0x00,0xf0,0x02,0x3c,0x00,0x0f,0x02,0x32,0x02,0x22,0x02,0x00,0x01,0x00,0x03,0x24,
-0x3c,0x04,0x83,0x10,0x02,0x00,0x02,0x24,0x34,0x04,0x82,0x10,0x03,0x00,0x02,0x24,
-0x46,0x03,0x82,0x10,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,0x21,0x20,0x00,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x46,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xe6,0xfd,0x40,0x14,0xc0,0x02,0x82,0x36,
-0x18,0x00,0xe2,0x34,0x45,0x03,0x62,0x10,0x19,0x00,0xe2,0x34,0xc6,0xfd,0x62,0x14,
-0x00,0xf0,0x02,0x3c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x94,0x0e,0x83,0x36,
-0x9c,0x0e,0x82,0x36,0xa4,0x0e,0x84,0x36,0xac,0x0e,0x87,0x36,0x00,0x00,0x65,0x8c,
-0x00,0x00,0x48,0x8c,0x00,0x00,0x8a,0x8c,0x00,0x00,0xe6,0x8c,0x02,0x80,0x07,0x3c,
-0x68,0x15,0xed,0x24,0xb4,0x0e,0x82,0x36,0x00,0x00,0x47,0x8c,0x0c,0x40,0xa3,0x8d,
-0xff,0x03,0x02,0x3c,0x10,0x40,0xa4,0x8d,0x24,0x28,0xa2,0x00,0x24,0x30,0xc2,0x00,
-0xbc,0x0e,0x82,0x36,0x00,0x00,0x4b,0x8c,0x00,0xfc,0x02,0x24,0x02,0x2c,0x05,0x00,
-0x24,0x18,0x62,0x00,0x02,0x34,0x06,0x00,0x24,0x20,0x82,0x00,0xc4,0x0e,0x82,0x36,
-0x25,0x18,0x65,0x00,0x25,0x20,0x86,0x00,0x00,0x00,0x45,0x8c,0xff,0x03,0x06,0x3c,
-0xf0,0xff,0x02,0x3c,0xff,0x03,0x42,0x34,0x24,0x38,0xe6,0x00,0x82,0x39,0x07,0x00,
-0x24,0x20,0x82,0x00,0x24,0x40,0x06,0x01,0x08,0x40,0xa9,0x8d,0x25,0x20,0x87,0x00,
-0xcc,0x0e,0x8c,0x36,0xff,0x03,0x07,0x3c,0x00,0x00,0x86,0x8d,0x24,0x18,0x62,0x00,
-0x24,0x50,0x47,0x01,0x24,0x58,0x67,0x01,0x82,0x41,0x08,0x00,0xff,0x9f,0x02,0x3c,
-0x0f,0xc0,0x07,0x3c,0xff,0xff,0xe7,0x34,0xff,0xff,0x42,0x34,0x25,0x18,0x68,0x00,
-0x24,0x48,0x22,0x01,0x24,0x18,0x67,0x00,0xff,0x03,0x02,0x3c,0x24,0x20,0x87,0x00,
-0xff,0x00,0x07,0x3c,0x24,0x28,0xa2,0x00,0x24,0x30,0xc2,0x00,0x00,0x51,0x0a,0x00,
-0x00,0x20,0x02,0x3c,0x00,0x59,0x0b,0x00,0x00,0xff,0xe7,0x34,0x25,0x48,0x22,0x01,
-0x25,0x18,0x6a,0x00,0x25,0x20,0x8b,0x00,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00,
-0x24,0x10,0x07,0x02,0x08,0x40,0xa9,0xad,0x0c,0x40,0xa3,0xad,0x10,0x40,0xa4,0xad,
-0x14,0x40,0xa5,0xa5,0x4e,0x03,0x40,0x10,0x16,0x40,0xa6,0xa5,0xff,0x00,0x02,0x3c,
-0x24,0x10,0x02,0x02,0x02,0x14,0x02,0x00,0x02,0x1a,0x10,0x00,0xc7,0x42,0xa2,0xa1,
-0xc3,0x42,0xa3,0xa1,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c,0x61,0x0c,0x63,0x34,
-0x10,0x00,0xa4,0x27,0x00,0x00,0x62,0xa0,0x7a,0x54,0x00,0x0c,0x00,0x00,0x00,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x95,0x00,0xc2,0x10,0x00,0x40,0x02,0x3c,0x09,0xff,0xc2,0x10,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7b,0x02,0xc2,0x10,
-0x2b,0x10,0x46,0x00,0x83,0x00,0x40,0x14,0x00,0xb0,0x02,0x3c,0x00,0x90,0x02,0x3c,
-0x78,0xfd,0xc2,0x14,0xc0,0x02,0x82,0x36,0x21,0x10,0x13,0x01,0x73,0x44,0x44,0xa0,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x55,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0x6a,0x56,0x00,0x0c,0x21,0x20,0x00,0x02,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x07,0x00,0x42,0x34,0x4c,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0x5b,0x4e,0x00,0x0c,
-0x07,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x02,0x1a,0x02,0x00,0x21,0x88,0x00,0x00,0xaf,0x4a,0x00,0x08,
-0x27,0xb0,0x06,0x3c,0x01,0x00,0x31,0x26,0x00,0x01,0x22,0x2e,0x08,0x00,0x40,0x10,
-0xff,0x00,0x22,0x2e,0x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0xff,0x00,0x42,0x30,
-0xf8,0xff,0x43,0x14,0x08,0x00,0xc6,0x24,0x00,0x00,0xd1,0xa7,0xff,0x00,0x22,0x2e,
-0x50,0xfd,0x40,0x14,0xc0,0x02,0x82,0x36,0x12,0x87,0x02,0x3c,0x00,0x00,0xc2,0xaf,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x2d,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c,0x00,0xff,0x63,0x34,
-0x24,0x10,0x03,0x02,0x02,0x82,0x02,0x00,0xcc,0x02,0x83,0x36,0x00,0x00,0x70,0xac,
-0x00,0x00,0xd1,0x8f,0x21,0x10,0x14,0x02,0x00,0x00,0x51,0xac,0x00,0x00,0x51,0x8c,
-0xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x00,0x64,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0xf4,0x02,0x62,0x10,0xa3,0x00,0xe2,0x34,0x0f,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,
-0xc0,0x02,0x82,0x36,0x8c,0x65,0x60,0xae,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xec,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0xe6,0x63,0x62,0xa6,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x08,0x40,0x63,0x8e,0xff,0x9f,0x07,0x3c,0xff,0xff,0xe7,0x34,
-0x02,0x2c,0x10,0x00,0x00,0x1f,0x04,0x32,0x24,0x18,0x67,0x00,0x25,0x18,0x62,0x00,
-0x02,0x8a,0x04,0x00,0x3f,0x00,0xa5,0x30,0xc0,0x02,0x82,0x36,0x08,0x40,0x63,0xae,
-0xbc,0x42,0x71,0xa2,0xc1,0x42,0x65,0xa2,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xfa,0x00,0x42,0x30,
-0x00,0x00,0xe2,0xa2,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xfd,0x00,0x42,0x30,
-0x00,0x00,0xe2,0xa2,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xf7,0xfc,0xc2,0x14,0xc0,0x02,0x82,0x36,0x80,0x10,0x08,0x00,
-0x21,0x10,0x53,0x00,0x60,0x45,0x43,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x80,0x10,0x08,0x00,0x21,0x10,0x48,0x00,
-0x21,0x10,0x53,0x00,0x21,0x10,0x49,0x00,0x34,0x43,0x44,0xa0,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x77,0x56,0x00,0x0c,
-0x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x34,0x8c,0x65,0x62,0xae,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x07,0x0b,0x00,0x0c,
-0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xf0,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x08,0x40,0x62,0x8e,0xff,0x9f,0x03,0x3c,0xff,0xff,0x63,0x34,0x24,0x10,0x43,0x00,
-0x08,0x40,0x62,0xae,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0x22,0x51,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x07,0x3c,0x00,0xff,0xe7,0x34,
-0x24,0x10,0x07,0x02,0x02,0x82,0x02,0x00,0xcc,0x02,0x43,0x36,0x00,0x00,0x70,0xac,
-0x21,0x10,0x12,0x02,0x00,0x00,0x51,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0xaf,
-0x00,0x00,0x51,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xb7,0x4f,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x21,0x88,0x00,0x00,
-0x6c,0x4b,0x00,0x08,0x27,0xb0,0x04,0x3c,0x01,0x00,0x31,0x26,0x00,0x01,0x22,0x2e,
-0x0a,0x00,0x40,0x10,0xff,0x00,0x22,0x2e,0x00,0x00,0x83,0x94,0x00,0x00,0x00,0x00,
-0xff,0xff,0x67,0x30,0xff,0x00,0xe2,0x30,0xf0,0x00,0x42,0x28,0xf6,0xff,0x40,0x14,
-0x08,0x00,0x84,0x24,0x00,0x00,0xc7,0xa7,0xff,0x00,0x22,0x2e,0x91,0xfc,0x40,0x14,
-0xc0,0x02,0x82,0x36,0x12,0x87,0x02,0x3c,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xe4,0x63,0x62,0x96,
-0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xa7,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x04,0x64,0x62,0x92,0x00,0x00,0x00,0x00,
-0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x00,0xff,0x02,0x32,0x02,0x12,0x02,0x00,0x03,0x00,0x43,0x2c,
-0x02,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x02,0x40,0x62,0xa2,0x02,0x40,0x63,0x92,
-0x90,0x0c,0x42,0x36,0x00,0x00,0x43,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xd7,0x56,0x00,0x0c,0x00,0x00,0x00,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x21,0x10,0x13,0x01,0x56,0x44,0x44,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c,0x24,0x20,0x03,0x02,
-0x73,0x0e,0x00,0x0c,0x02,0x24,0x04,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x1c,0x10,0x00,0x00,0x1f,0x02,0x32,
-0x02,0x8a,0x02,0x00,0x3f,0x00,0x65,0x30,0xc1,0x42,0x65,0xa2,0xbc,0x42,0x71,0xa2,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x1f,0x12,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x03,0x40,0x62,0x92,0x0e,0x0c,0x44,0x36,
-0x01,0x00,0x42,0x24,0xff,0x00,0x43,0x30,0x00,0x00,0x83,0xa0,0x03,0x40,0x62,0xa2,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x00,0xff,0x02,0x32,0x02,0x3a,0x02,0x00,0x1a,0x01,0xe0,0x10,0x4f,0x00,0x82,0x36,
-0x94,0x00,0x42,0x36,0x00,0x00,0x43,0x94,0xff,0xff,0xe2,0x24,0xb0,0x03,0x45,0x36,
-0xff,0xff,0x71,0x30,0x1b,0x00,0x27,0x02,0x02,0x00,0xe0,0x14,0x00,0x00,0x00,0x00,
-0x0d,0x00,0x07,0x00,0xff,0xff,0x47,0x30,0x00,0x00,0xb1,0xac,0x80,0xff,0x02,0x24,
-0x00,0x19,0x07,0x00,0x25,0x18,0x62,0x00,0x4f,0x00,0x44,0x36,0x9e,0x00,0x46,0x36,
-0x00,0x00,0xa7,0xac,0x00,0x00,0x83,0xa0,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,
-0x12,0x88,0x00,0x00,0x80,0x12,0x11,0x00,0x00,0xfc,0x42,0x24,0x00,0x00,0xb1,0xac,
-0x00,0x00,0xd1,0xa4,0x42,0x89,0x02,0x00,0x26,0xb0,0x02,0x3c,0x7c,0x00,0x42,0x34,
-0x00,0x00,0xb1,0xac,0x00,0x00,0x51,0xa4,0x25,0xb0,0x02,0x3c,0x44,0x00,0x42,0x34,
-0x00,0x00,0x43,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x00,0x83,0xa4,
-0x00,0x00,0x82,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34,0x00,0x00,0x82,0xa4,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x24,0x10,0x08,0x02,0xcc,0x02,0x43,0x36,0x00,0xff,0x04,0x32,0x02,0x3c,0x02,0x00,
-0x00,0x00,0x70,0xac,0x04,0x00,0xe0,0x10,0x02,0x82,0x04,0x00,0x01,0x00,0x02,0x24,
-0x02,0x00,0xe2,0x10,0x01,0x00,0x04,0x24,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x0f,0x00,0x06,0x3c,0x21,0x20,0x00,0x02,0xdd,0x44,0x00,0x0c,
-0xff,0xff,0xc5,0x34,0x0f,0x00,0x07,0x3c,0xff,0xff,0xe7,0x34,0x24,0x88,0x47,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x28,0xb0,0x02,0x3c,0x00,0x00,0x43,0x90,0xff,0x00,0x02,0x24,
-0xff,0x00,0x70,0x30,0xf3,0xfb,0x02,0x12,0xc0,0x02,0x82,0x36,0x28,0xb0,0x05,0x3c,
-0xff,0x00,0x04,0x24,0xc0,0x10,0x10,0x00,0x21,0x10,0x45,0x00,0x00,0x00,0x43,0x90,
-0x00,0x00,0x00,0x00,0xff,0x00,0x70,0x30,0xfb,0xff,0x04,0x16,0xc0,0x10,0x10,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x00,0x1f,0x02,0x32,0x02,0x1c,0x10,0x00,0x02,0x8a,0x02,0x00,0x3f,0x00,0x65,0x30,
-0xc0,0x02,0x82,0x36,0xbc,0x42,0x71,0xa2,0xc1,0x42,0x65,0xa2,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x07,0x3c,0x24,0x20,0x07,0x02,
-0x15,0x51,0x00,0x0c,0x02,0x24,0x04,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xe8,0x63,0x62,0x92,0x00,0x00,0x00,0x00,
-0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xfc,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xff,0x00,0x51,0x30,0x05,0x00,0x23,0x36,
-0xc0,0x02,0x82,0x36,0x00,0x00,0xe3,0xa2,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0xe6,0x63,0x60,0xa6,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xbd,0x56,0x00,0x0c,0x21,0x20,0x00,0x02,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x41,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,
-0xff,0x00,0x51,0x30,0x02,0x00,0x23,0x36,0xc0,0x02,0x82,0x36,0x00,0x00,0xe3,0xa2,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,
-0xec,0x91,0x42,0x24,0x00,0x00,0x47,0x8c,0xc0,0x02,0x43,0x36,0x25,0xb0,0x0c,0x3c,
-0x08,0x40,0xe4,0x8c,0x00,0x00,0x60,0xac,0x42,0x17,0x04,0x00,0x03,0x00,0x42,0x30,
-0x60,0x00,0x40,0x14,0x03,0x0d,0x42,0x36,0x00,0x00,0x45,0x90,0x10,0x40,0xe6,0x8c,
-0xff,0x9f,0x03,0x3c,0xff,0xff,0x63,0x34,0xff,0x3f,0x02,0x3c,0x24,0x20,0x83,0x00,
-0xff,0xff,0x42,0x34,0x00,0x20,0x03,0x3c,0x24,0x58,0xc2,0x00,0x25,0x20,0x83,0x00,
-0x00,0x40,0x02,0x3c,0x70,0x00,0xa5,0x30,0x25,0x58,0x62,0x01,0x08,0x01,0xa0,0x10,
-0x08,0x40,0xe4,0xac,0x94,0x0e,0x82,0x35,0x9c,0x0e,0x83,0x35,0xa4,0x0e,0x86,0x35,
-0x00,0x00,0x45,0x8c,0xac,0x0e,0x87,0x35,0x00,0x00,0x68,0x8c,0x00,0x00,0xca,0x8c,
-0x02,0x80,0x06,0x3c,0x00,0x00,0xe4,0x8c,0x68,0x15,0xc6,0x24,0x0c,0x40,0xc3,0x8c,
-0xb4,0x0e,0x82,0x35,0x00,0x00,0x47,0x8c,0xff,0x03,0x02,0x3c,0x00,0xfc,0x06,0x24,
-0x24,0x28,0xa2,0x00,0x24,0x20,0x82,0x00,0xbc,0x0e,0x82,0x35,0x00,0x00,0x49,0x8c,
-0x02,0x2c,0x05,0x00,0x24,0x10,0x66,0x01,0x24,0x18,0x66,0x00,0x02,0x24,0x04,0x00,
-0xc4,0x0e,0x86,0x35,0x25,0x18,0x65,0x00,0x25,0x10,0x44,0x00,0x00,0x00,0xc5,0x8c,
-0xff,0x03,0x04,0x3c,0xf0,0xff,0x06,0x3c,0xff,0x03,0xc6,0x34,0x24,0x38,0xe4,0x00,
-0xcc,0x0e,0x8b,0x35,0x24,0x40,0x04,0x01,0x82,0x39,0x07,0x00,0x00,0x00,0x64,0x8d,
-0x24,0x10,0x46,0x00,0x24,0x18,0x66,0x00,0x25,0x10,0x47,0x00,0x82,0x41,0x08,0x00,
-0xff,0x03,0x07,0x3c,0x0f,0xc0,0x06,0x3c,0x24,0x50,0x47,0x01,0x24,0x48,0x27,0x01,
-0xff,0xff,0xc6,0x34,0x25,0x18,0x68,0x00,0x24,0x28,0xa7,0x00,0x24,0x20,0x87,0x00,
-0x00,0x51,0x0a,0x00,0x24,0x18,0x66,0x00,0x00,0x49,0x09,0x00,0x24,0x10,0x46,0x00,
-0x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24,0x25,0x18,0x6a,0x00,0x25,0x10,0x49,0x00,
-0x02,0x2c,0x05,0x00,0x02,0x24,0x04,0x00,0x0c,0x40,0xe3,0xac,0x10,0x40,0xe2,0xac,
-0x14,0x40,0xe5,0xa4,0x16,0x40,0xe4,0xa4,0x02,0x80,0x02,0x3c,0x68,0x15,0x43,0x24,
-0x0c,0x40,0x62,0x8c,0x00,0x00,0x00,0x00,0xbd,0x00,0x40,0x04,0x00,0x00,0x00,0x00,
-0x00,0xff,0x02,0x32,0xc6,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,
-0xc3,0x42,0x62,0xa0,0x7a,0x54,0x00,0x0c,0x10,0x00,0xa4,0x27,0xc2,0x53,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x0c,0x40,0x62,0x8e,0x00,0x80,0x03,0x3c,0x25,0x10,0x43,0x00,
-0x0c,0x40,0x62,0xae,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c,0x61,0x0c,0x63,0x34,
-0x00,0x00,0x62,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xcf,0x4e,0x00,0x0c,0x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x17,0x51,0x00,0x0c,
-0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x9e,0x00,0x83,0x36,0x00,0x00,0x40,0xa0,0x00,0x00,0x60,0xa4,
-0x94,0x00,0x82,0x36,0x00,0x00,0x43,0x94,0x25,0xb0,0x06,0x3c,0x44,0x00,0xc6,0x34,
-0xff,0xff,0x71,0x30,0x80,0x12,0x11,0x00,0x00,0xf8,0x42,0x24,0x42,0x89,0x02,0x00,
-0x26,0xb0,0x02,0x3c,0xb0,0x03,0x83,0x36,0x7c,0x00,0x42,0x34,0x00,0x00,0x71,0xac,
-0x00,0x00,0x51,0xa4,0x00,0x00,0xc3,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00,
-0x00,0x00,0xc3,0xa4,0x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34,
-0x00,0x00,0xc2,0xa4,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x5b,0x4e,0x00,0x0c,0x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x80,0x10,0x08,0x00,
-0x21,0x10,0x53,0x00,0xec,0x44,0x43,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xa7,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x28,0xb0,0x11,0x3c,0x00,0x00,0x22,0x96,0xff,0x00,0x04,0x3c,0x24,0x18,0x04,0x02,
-0x02,0x24,0x03,0x00,0xff,0x00,0x42,0x30,0x0a,0x00,0x82,0x10,0xff,0x7f,0x02,0x3c,
-0x08,0x00,0x31,0x26,0x00,0x00,0x22,0x96,0xff,0xff,0x23,0x32,0xff,0x00,0x42,0x30,
-0x03,0x00,0x82,0x10,0x00,0x08,0x63,0x2c,0xf9,0xff,0x60,0x14,0x00,0x00,0x00,0x00,
-0xff,0x7f,0x02,0x3c,0xff,0xff,0x42,0x34,0x24,0x10,0x22,0x02,0x00,0x00,0xc2,0xaf,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0xf8,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c,
-0x24,0x10,0x03,0x02,0x00,0xff,0x04,0x32,0xcc,0x02,0x83,0x36,0x02,0x3c,0x02,0x00,
-0x00,0x00,0x70,0xac,0x04,0x00,0xe0,0x10,0x02,0x82,0x04,0x00,0x01,0x00,0x02,0x24,
-0x02,0x00,0xe2,0x10,0x01,0x00,0x04,0x24,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x8f,0x0f,0x00,0x06,0x3c,0xff,0xff,0xc5,0x34,
-0x21,0x20,0x00,0x02,0xba,0x44,0x00,0x0c,0x21,0x30,0x20,0x02,0x0f,0x00,0x07,0x3c,
-0x21,0x20,0x00,0x02,0xdd,0x44,0x00,0x0c,0xff,0xff,0xe5,0x34,0x00,0x00,0xc2,0xaf,
-0x21,0x88,0x40,0x00,0x25,0xb0,0x02,0x3c,0xc8,0x02,0x42,0x34,0x00,0x00,0x51,0xac,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x25,0xb0,0x06,0x3c,0xff,0x00,0x02,0x24,0x56,0x01,0xc6,0x34,0x00,0x00,0xc2,0xa4,
-0x01,0x00,0x03,0x24,0x02,0x80,0x07,0x3c,0xc0,0x02,0x82,0x36,0xb8,0x7d,0xe3,0xa0,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,
-0x03,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xde,0x4e,0x00,0x0c,0x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x40,0x62,0x8e,
-0xff,0x9f,0x04,0x3c,0xff,0xff,0x84,0x34,0x24,0x10,0x44,0x00,0x08,0x40,0x62,0xae,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,
-0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,0x70,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36,
-0x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x7a,0x54,0x00,0x0c,0x10,0x00,0xa4,0x27,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c,
-0x61,0x0c,0x63,0x34,0x00,0x00,0x62,0xa0,0xd4,0x4c,0x00,0x08,0xc0,0x02,0x82,0x36,
-0x22,0x51,0x00,0x0c,0x10,0x40,0xeb,0xac,0xbd,0x4c,0x00,0x08,0x02,0x80,0x02,0x3c,
-0xc6,0x4c,0x00,0x08,0x12,0x00,0x02,0x24,0x1a,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,
-0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0xff,0xff,0x02,0x34,0x8c,0x65,0x62,0xae,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,
-0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,
-0x74,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,
-0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,
-0xd4,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac,
-0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,
-0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c,0x80,0x10,0x02,0x00,
-0xe0,0x66,0xc3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,
-0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
-0x12,0x00,0x02,0x24,0xc7,0x42,0xa2,0xa1,0x77,0x4a,0x00,0x08,0xc3,0x42,0xa2,0xa1,
-0x88,0x7d,0x82,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c,
-0x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xff,0x00,0x06,0x3c,0x00,0xff,0xc6,0x34,0x00,0x00,0xc5,0x8f,
-0x24,0x20,0x06,0x02,0xe1,0x50,0x00,0x0c,0x02,0x22,0x04,0x00,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,
-0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c,
-0x80,0x10,0x02,0x00,0xf0,0x66,0xe3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,
-0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,
-0x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c,0x80,0x10,0x02,0x00,0xec,0x66,0xc3,0x24,
-0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,
-0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c,
-0xe8,0x66,0x83,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,
-0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,
-0x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c,0x80,0x10,0x02,0x00,0xe4,0x66,0xe3,0x24,
-0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,
-0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c,
-0x00,0x67,0x83,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,
-0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,
-0x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c,0x80,0x10,0x02,0x00,0xfc,0x66,0xe3,0x24,
-0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,
-0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c,
-0x80,0x10,0x02,0x00,0xf8,0x66,0xc3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,
-0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,
-0x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c,0xf4,0x66,0x83,0x24,0x80,0x10,0x02,0x00,
-0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,
-0x02,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,0x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,
-0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c,
-0x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
-0x00,0x00,0x00,0x00,0x25,0xb0,0x05,0x3c,0x01,0x00,0x06,0x24,0x01,0x80,0x02,0x3c,
-0x04,0x30,0x86,0x00,0xf1,0x02,0xa7,0x34,0xed,0x02,0xa4,0x34,0x6c,0x39,0x42,0x24,
-0x18,0x03,0xa5,0x34,0x08,0x00,0x03,0x24,0x00,0x00,0xa2,0xac,0x00,0x00,0xe3,0xa0,
-0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,
-0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,
-0x00,0x00,0x80,0xa0,0x00,0x00,0xe0,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x01,0x80,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xc8,0x39,0x42,0x24,0x18,0x03,0x63,0x34,
-0x00,0x00,0x62,0xac,0x00,0x00,0x83,0x90,0x30,0x00,0x02,0x24,0x05,0x00,0x62,0x10,
-0x21,0x20,0x00,0x00,0x31,0x00,0x02,0x24,0x02,0x00,0x62,0x10,0x01,0x00,0x04,0x24,
-0x07,0x00,0x04,0x24,0x5b,0x4e,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0x80,0x02,0x3c,
-0x25,0xb0,0x03,0x3c,0x04,0x3a,0x42,0x24,0x18,0x03,0x63,0x34,0x02,0x80,0x04,0x3c,
-0x00,0x00,0x62,0xac,0x08,0x00,0xe0,0x03,0xc4,0x7d,0x80,0xac,0x02,0x80,0x02,0x3c,
-0x08,0x7b,0x42,0x24,0xc0,0x20,0x04,0x00,0x21,0x20,0x82,0x00,0x21,0x28,0x00,0x00,
-0x00,0x60,0x06,0x40,0x01,0x00,0xc1,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
-0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x09,0x00,0x44,0x10,0x00,0x00,0x00,0x00,
-0x04,0x00,0x43,0x8c,0x21,0x28,0x40,0x00,0x00,0x00,0x42,0x8c,0x00,0x00,0x00,0x00,
-0x00,0x00,0x62,0xac,0x04,0x00,0x43,0xac,0x00,0x00,0xa5,0xac,0x04,0x00,0xa5,0xac,
-0x00,0x60,0x86,0x40,0x08,0x00,0xe0,0x03,0x21,0x10,0xa0,0x00,0x21,0x18,0x80,0x00,
-0xe8,0xff,0xbd,0x27,0x01,0x01,0x62,0x2c,0x10,0x00,0xbf,0xaf,0x01,0x00,0x04,0x24,
-0x01,0x02,0x65,0x2c,0x0a,0x00,0x40,0x14,0x21,0x30,0x00,0x00,0x02,0x00,0x04,0x24,
-0x07,0x00,0xa0,0x14,0x01,0x08,0x62,0x2c,0x05,0x00,0x40,0x14,0x03,0x00,0x04,0x24,
-0x10,0x00,0xbf,0x8f,0x21,0x10,0xc0,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,
-0x89,0x4e,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f,0x21,0x30,0x40,0x00,
-0x21,0x10,0xc0,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x02,0x80,0x03,0x3c,
-0x20,0x7b,0x62,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x60,0x06,0x40,
-0x01,0x00,0xc1,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x10,0x00,0x83,0x8c,
-0x02,0x80,0x02,0x3c,0x08,0x7b,0x42,0x24,0xc0,0x18,0x03,0x00,0x21,0x18,0x62,0x00,
-0x00,0x00,0x65,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac,0x04,0x00,0xa4,0xac,
-0x00,0x00,0x64,0xac,0x04,0x00,0x83,0xac,0x00,0x60,0x86,0x40,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x18,0x04,0x00,
-0x21,0x18,0x64,0x00,0x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c,
-0x68,0x15,0x42,0x24,0x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x78,0x51,0x64,0x8c,
-0xff,0xf1,0x02,0x24,0x24,0x20,0x82,0x00,0x08,0x00,0xe0,0x03,0x78,0x51,0x64,0xac,
-0x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x18,0x04,0x00,0x21,0x18,0x64,0x00,
-0x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,
-0x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x78,0x51,0x64,0x8c,0xff,0xf1,0x02,0x24,
-0x24,0x20,0x82,0x00,0x00,0x02,0x84,0x34,0x08,0x00,0xe0,0x03,0x78,0x51,0x64,0xac,
-0xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0xc0,0x80,0x04,0x00,0x21,0x80,0x04,0x02,
-0x80,0x80,0x10,0x00,0x21,0x80,0x04,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,
-0x80,0x80,0x10,0x00,0x21,0x80,0x02,0x02,0x1c,0x00,0xbf,0xaf,0x18,0x00,0xb2,0xaf,
-0x14,0x00,0xb1,0xaf,0x78,0x51,0x05,0x8e,0xff,0x1f,0x02,0x3c,0x25,0xb0,0x12,0x3c,
-0xff,0xff,0x42,0x34,0x70,0x51,0x02,0xae,0x84,0x01,0x43,0x36,0xf8,0xff,0x02,0x24,
-0x00,0x00,0x66,0x8c,0x24,0x28,0xa2,0x00,0xff,0xfe,0x02,0x24,0x24,0x28,0xa2,0x00,
-0xff,0xef,0x03,0x24,0x24,0x28,0xa3,0x00,0x74,0x51,0x06,0xae,0x78,0x51,0x05,0xae,
-0xce,0x0d,0x00,0x0c,0x21,0x88,0x80,0x00,0x7a,0x51,0x02,0x92,0x21,0x88,0x32,0x02,
-0x1c,0x00,0xbf,0x8f,0x60,0x01,0x22,0xa2,0x18,0x00,0xb2,0x8f,0x64,0x51,0x00,0xae,
-0x48,0x51,0x00,0xae,0x4c,0x51,0x00,0xae,0x50,0x51,0x00,0xae,0x54,0x51,0x00,0xae,
-0x58,0x51,0x00,0xae,0x5c,0x51,0x00,0xae,0x60,0x51,0x00,0xae,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xff,0x00,0xa5,0x30,
-0xc0,0x10,0x05,0x00,0x21,0x10,0x45,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x45,0x00,
-0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,
-0x78,0x51,0x43,0x8c,0x25,0xb0,0x05,0x3c,0xff,0x00,0xc6,0x30,0x21,0x30,0xc5,0x00,
-0xaf,0x01,0xc2,0x90,0x07,0x00,0x63,0x30,0x80,0x18,0x03,0x00,0x21,0x18,0x65,0x00,
-0xff,0x00,0x88,0x30,0xff,0x00,0x49,0x30,0x84,0x01,0x66,0x8c,0x21,0x50,0x00,0x00,
-0x21,0x58,0x00,0x00,0x2b,0x00,0x20,0x11,0x21,0x20,0x00,0x01,0x2b,0x00,0xc0,0x10,
-0x2b,0x10,0x09,0x01,0x21,0x28,0x00,0x00,0x3e,0x4f,0x00,0x08,0x01,0x00,0x07,0x24,
-0xff,0x00,0x65,0x30,0x1d,0x00,0xa2,0x2c,0x07,0x00,0x40,0x10,0xff,0xff,0x02,0x25,
-0x04,0x10,0xa7,0x00,0x24,0x10,0x46,0x00,0xf9,0xff,0x40,0x10,0x01,0x00,0xa3,0x24,
-0x21,0x58,0xa0,0x00,0xff,0xff,0x02,0x25,0xff,0x00,0x45,0x30,0x2b,0x18,0xab,0x00,
-0x0f,0x00,0x60,0x14,0x2b,0x10,0x49,0x01,0x01,0x00,0x04,0x24,0x04,0x10,0xa4,0x00,
-0x24,0x10,0x46,0x00,0xff,0xff,0xa7,0x24,0x04,0x00,0x40,0x10,0x01,0x00,0x43,0x25,
-0x17,0x00,0x49,0x11,0xff,0x00,0x6a,0x30,0x21,0x40,0xa0,0x00,0xff,0x00,0xe5,0x30,
-0x2b,0x10,0xab,0x00,0xf6,0xff,0x40,0x10,0x04,0x10,0xa4,0x00,0x2b,0x10,0x49,0x01,
-0x08,0x00,0x40,0x10,0x21,0x20,0x00,0x01,0x23,0x10,0x2a,0x01,0x2a,0x10,0x62,0x01,
-0x04,0x00,0x40,0x14,0x21,0x20,0x00,0x00,0x23,0x10,0x69,0x01,0x21,0x10,0x4a,0x00,
-0xff,0x00,0x44,0x30,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0xfd,0xff,0x40,0x14,
-0x21,0x20,0x00,0x00,0x23,0x10,0x09,0x01,0x5f,0x4f,0x00,0x08,0xff,0x00,0x44,0x30,
-0x21,0x20,0x00,0x01,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0xff,0x00,0x84,0x30,
-0xc0,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,
-0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,
-0x25,0xb0,0x06,0x3c,0x78,0x51,0x43,0x8c,0xff,0x00,0xa5,0x30,0x21,0x20,0x86,0x00,
-0x21,0x28,0xa6,0x00,0x60,0x01,0x82,0x90,0xaf,0x01,0xa4,0x90,0x07,0x00,0x63,0x30,
-0x80,0x18,0x03,0x00,0x21,0x18,0x66,0x00,0xff,0x00,0x48,0x30,0xff,0x00,0x89,0x30,
-0x84,0x01,0x66,0x8c,0x21,0x50,0x00,0x00,0x21,0x58,0x00,0x00,0x2b,0x00,0x20,0x11,
-0x21,0x20,0x00,0x01,0x2b,0x00,0xc0,0x10,0x2b,0x10,0x09,0x01,0x21,0x28,0x00,0x00,
-0x8c,0x4f,0x00,0x08,0x01,0x00,0x07,0x24,0xff,0x00,0x65,0x30,0x1d,0x00,0xa2,0x2c,
-0x07,0x00,0x40,0x10,0xff,0xff,0x02,0x25,0x04,0x10,0xa7,0x00,0x24,0x10,0x46,0x00,
-0xf9,0xff,0x40,0x10,0x01,0x00,0xa3,0x24,0x21,0x58,0xa0,0x00,0xff,0xff,0x02,0x25,
-0xff,0x00,0x45,0x30,0x2b,0x18,0xab,0x00,0x0f,0x00,0x60,0x14,0x2b,0x10,0x49,0x01,
-0x01,0x00,0x04,0x24,0x04,0x10,0xa4,0x00,0x24,0x10,0x46,0x00,0xff,0xff,0xa7,0x24,
-0x04,0x00,0x40,0x10,0x01,0x00,0x43,0x25,0x17,0x00,0x49,0x11,0xff,0x00,0x6a,0x30,
-0x21,0x40,0xa0,0x00,0xff,0x00,0xe5,0x30,0x2b,0x10,0xab,0x00,0xf6,0xff,0x40,0x10,
-0x04,0x10,0xa4,0x00,0x2b,0x10,0x49,0x01,0x08,0x00,0x40,0x10,0x21,0x20,0x00,0x01,
-0x23,0x10,0x2a,0x01,0x2a,0x10,0x62,0x01,0x04,0x00,0x40,0x14,0x21,0x20,0x00,0x00,
-0x23,0x10,0x69,0x01,0x21,0x10,0x4a,0x00,0xff,0x00,0x44,0x30,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x80,0x00,0xfd,0xff,0x40,0x14,0x21,0x20,0x00,0x00,0x23,0x10,0x09,0x01,
-0xad,0x4f,0x00,0x08,0xff,0x00,0x44,0x30,0x21,0x20,0x00,0x01,0x08,0x00,0xe0,0x03,
-0x21,0x10,0x80,0x00,0xe0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x10,0x00,0xb0,0xaf,
-0x68,0x15,0x50,0x24,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x1c,0x00,0xbf,0xaf,
-0x21,0x88,0x00,0x00,0x21,0x90,0x00,0x02,0xee,0x4e,0x00,0x0c,0x21,0x20,0x20,0x02,
-0x7a,0x51,0x02,0x92,0x21,0x28,0x00,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x52,0x00,
-0xec,0x44,0x44,0x8c,0x60,0x45,0x43,0x8c,0x00,0x00,0x00,0x00,0x21,0x18,0x64,0x00,
-0x42,0x18,0x03,0x00,0x44,0x51,0x03,0xae,0x21,0x10,0x05,0x02,0x01,0x00,0xa5,0x24,
-0x1d,0x00,0xa3,0x28,0xb6,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14,
-0x99,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x00,0xae,
-0xe9,0xff,0x40,0x14,0x94,0x00,0x10,0x26,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,
-0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
-0xc8,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x30,0x00,0xbe,0xaf,0x28,0x00,0xb6,0xaf,
-0x68,0x15,0x46,0x24,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb7,0xaf,0x24,0x00,0xb5,0xaf,
-0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,
-0x10,0x00,0xb0,0xaf,0x8c,0x65,0xc2,0x8c,0xff,0x00,0x8d,0x30,0xff,0x00,0x03,0x24,
-0xff,0xff,0x42,0x38,0x21,0xf0,0x00,0x00,0xff,0xff,0x04,0x34,0x0a,0xf0,0x62,0x00,
-0x8c,0x65,0xc4,0xac,0xb0,0x00,0xa0,0x11,0x08,0x00,0x16,0x24,0x02,0x80,0x02,0x3c,
-0xb8,0x90,0x45,0x24,0x90,0x44,0xc4,0x24,0xff,0x4f,0x00,0x08,0x21,0x88,0x00,0x00,
-0x01,0x00,0x31,0x26,0x00,0x00,0x82,0xa0,0x1d,0x00,0x22,0x2a,0x0b,0x00,0x40,0x10,
-0x01,0x00,0x84,0x24,0x21,0x10,0x25,0x02,0x00,0x00,0x42,0x90,0x00,0x00,0x00,0x00,
-0xf7,0xff,0x40,0x10,0xfd,0xff,0x43,0x24,0x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a,
-0x00,0x00,0x83,0xa0,0xf7,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x02,0x80,0x02,0x3c,
-0x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x50,0x8e,0x6c,0x24,
-0xd8,0x8d,0x4b,0x24,0x21,0x88,0x00,0x00,0x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00,
-0x21,0x40,0x2a,0x01,0x21,0x38,0x2c,0x01,0x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90,
-0x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01,0x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28,
-0xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14,0x34,0x43,0x65,0xa0,0x21,0x10,0x2b,0x02,
-0x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26,
-0x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0,0x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14,
-0x05,0x00,0x29,0x25,0xa6,0x00,0xa0,0x11,0x02,0x80,0x02,0x3c,0x68,0x15,0x48,0x24,
-0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x4c,0x91,0x69,0x24,0xd8,0x90,0x47,0x24,
-0x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x10,0x69,0x00,0x21,0x20,0x67,0x00,
-0x00,0x00,0x46,0x8c,0x00,0x00,0x85,0x8c,0x01,0x00,0x31,0x26,0x21,0x18,0x68,0x00,
-0x04,0x00,0x22,0x2a,0xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14,0x60,0x45,0x66,0xac,
-0x02,0x80,0x02,0x3c,0x68,0x15,0x49,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,
-0x4c,0x91,0x68,0x24,0xd8,0x90,0x47,0x24,0x04,0x00,0x11,0x24,0x80,0x20,0x11,0x00,
-0x21,0x10,0x88,0x00,0x21,0x30,0x87,0x00,0x00,0x00,0x45,0x8c,0x00,0x00,0xc3,0x8c,
-0x01,0x00,0x31,0x26,0x21,0x20,0x89,0x00,0x82,0x28,0x05,0x00,0x82,0x18,0x03,0x00,
-0x1d,0x00,0x22,0x2a,0xec,0x44,0x83,0xac,0xf4,0xff,0x40,0x14,0x60,0x45,0x85,0xac,
-0x02,0x80,0x02,0x3c,0x68,0x15,0x55,0x24,0x21,0x88,0x00,0x00,0x21,0xb8,0xa0,0x02,
-0x21,0xa0,0x00,0x00,0x5a,0x50,0x00,0x08,0x21,0x90,0xa0,0x02,0x01,0x00,0x31,0x26,
-0x20,0x00,0x22,0x2a,0x94,0x00,0x52,0x26,0x38,0x00,0x40,0x10,0x94,0x00,0x94,0x26,
-0x78,0x51,0x44,0x8e,0x01,0x00,0x03,0x24,0x02,0x13,0x04,0x00,0x01,0x00,0x53,0x30,
-0xf6,0xff,0x63,0x16,0x07,0x00,0x82,0x30,0x25,0xb0,0x03,0x3c,0x80,0x10,0x02,0x00,
-0x21,0x10,0x43,0x00,0x84,0x01,0x45,0x8c,0x70,0x51,0x43,0x8e,0x21,0x20,0x20,0x02,
-0x24,0x28,0xa3,0x00,0xce,0x0d,0x00,0x0c,0x74,0x51,0x45,0xae,0x7a,0x51,0x44,0x92,
-0x5c,0x0d,0x00,0x0c,0xff,0x00,0x25,0x32,0x7a,0x51,0x50,0x92,0x00,0x00,0x00,0x00,
-0x21,0x20,0x00,0x02,0x63,0x0d,0x00,0x0c,0x80,0x80,0x10,0x00,0x21,0x80,0x17,0x02,
-0x48,0x51,0x40,0xae,0x4c,0x51,0x40,0xae,0x50,0x51,0x40,0xae,0x54,0x51,0x40,0xae,
-0x58,0x51,0x40,0xae,0x5c,0x51,0x40,0xae,0x60,0x51,0x40,0xae,0x64,0x51,0x40,0xae,
-0xec,0x44,0x04,0x8e,0x60,0x45,0x03,0x8e,0x26,0x10,0x53,0x00,0x21,0x30,0x00,0x00,
-0x21,0x18,0x64,0x00,0x42,0x18,0x03,0x00,0x04,0x00,0x04,0x24,0x0a,0xb0,0x82,0x00,
-0x44,0x51,0x43,0xae,0x21,0x20,0x95,0x02,0x21,0x10,0x86,0x00,0x01,0x00,0xc6,0x24,
-0x1d,0x00,0xc3,0x28,0xb6,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14,
-0x99,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x80,0xac,
-0x94,0x00,0x52,0x26,0xca,0xff,0x40,0x14,0x94,0x00,0x94,0x26,0x25,0xb0,0x02,0x3c,
-0x80,0x01,0x42,0x34,0x00,0x00,0x56,0xa0,0x03,0x00,0xc0,0x17,0x02,0x80,0x03,0x3c,
-0x68,0x15,0x62,0x24,0x8c,0x65,0x40,0xac,0x34,0x00,0xbf,0x8f,0x30,0x00,0xbe,0x8f,
-0x2c,0x00,0xb7,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,
-0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
-0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x02,0x80,0x02,0x3c,0xb8,0x90,0x45,0x24,
-0x90,0x44,0xc4,0x24,0x21,0x88,0x00,0x00,0x21,0x10,0x25,0x02,0x00,0x00,0x43,0x90,
-0x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a,0x00,0x00,0x83,0xa0,0xfa,0xff,0x40,0x14,
-0x01,0x00,0x84,0x24,0x02,0x80,0x02,0x3c,0x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c,
-0x02,0x80,0x02,0x3c,0x74,0x8f,0x6c,0x24,0x14,0x8e,0x4b,0x24,0x21,0x88,0x00,0x00,
-0x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00,0x21,0x40,0x2a,0x01,0x21,0x38,0x2c,0x01,
-0x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01,
-0x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28,0xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14,
-0x34,0x43,0x65,0xa0,0x21,0x10,0x2b,0x02,0x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90,
-0x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0,
-0x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14,0x05,0x00,0x29,0x25,0x02,0x80,0x02,0x3c,
-0x68,0x15,0x49,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x4c,0x91,0x68,0x24,
-0xd8,0x90,0x47,0x24,0x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x10,0x68,0x00,
-0x21,0x20,0x67,0x00,0x00,0x00,0x46,0x8c,0x00,0x00,0x85,0x8c,0x01,0x00,0x31,0x26,
-0x21,0x18,0x69,0x00,0x1d,0x00,0x22,0x2a,0xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14,
-0x60,0x45,0x66,0xac,0x4f,0x50,0x00,0x08,0x02,0x80,0x02,0x3c,0xd8,0xff,0xbd,0x27,
-0xff,0xff,0x84,0x30,0x18,0x00,0xb2,0xaf,0xf0,0x01,0x92,0x30,0x02,0x91,0x12,0x00,
-0x14,0x00,0xb1,0xaf,0xc0,0x88,0x12,0x00,0x21,0x88,0x32,0x02,0x80,0x88,0x11,0x00,
-0x21,0x88,0x32,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x88,0x11,0x00,
-0x21,0x88,0x22,0x02,0x20,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,0x10,0x00,0xb0,0xaf,
-0x78,0x51,0x30,0x8e,0x00,0x02,0x82,0x30,0xff,0xfe,0x03,0x24,0x2b,0x10,0x02,0x00,
-0x00,0x10,0x10,0x36,0x24,0x80,0x03,0x02,0x00,0x12,0x02,0x00,0x25,0x80,0x02,0x02,
-0x70,0x51,0x25,0xae,0x78,0x51,0x30,0xae,0xa0,0x0e,0x00,0x0c,0x21,0x98,0xa0,0x00,
-0xf8,0xff,0x03,0x24,0x24,0x80,0x03,0x02,0x07,0x00,0x42,0x30,0x25,0x80,0x02,0x02,
-0x07,0x00,0x03,0x32,0x25,0xb0,0x02,0x3c,0x80,0x18,0x03,0x00,0x78,0x51,0x30,0xae,
-0x21,0x18,0x62,0x00,0x84,0x01,0x62,0x8c,0x21,0x20,0x40,0x02,0x24,0x10,0x53,0x00,
-0xce,0x0d,0x00,0x0c,0x74,0x51,0x22,0xae,0x7a,0x51,0x24,0x92,0x21,0x28,0x40,0x02,
-0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x5c,0x0d,0x00,0x08,0x28,0x00,0xbd,0x27,0xee,0x4e,0x00,0x08,
-0xff,0x00,0x84,0x30,0x02,0x80,0x02,0x3c,0x68,0x15,0x43,0x24,0x1f,0x00,0x04,0x24,
-0x78,0x51,0x62,0x8c,0xff,0xff,0x84,0x24,0x00,0x10,0x42,0x34,0x78,0x51,0x62,0xac,
-0xfb,0xff,0x81,0x04,0x94,0x00,0x63,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x78,0xff,0xbd,0x27,0x60,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x70,0x00,0xb4,0xaf,
-0xc4,0x02,0x14,0x36,0x00,0x00,0x80,0xae,0x74,0x00,0xb5,0xaf,0x6c,0x00,0xb3,0xaf,
-0x68,0x00,0xb2,0xaf,0x64,0x00,0xb1,0xaf,0x84,0x00,0xbf,0xaf,0x80,0x00,0xbe,0xaf,
-0x7c,0x00,0xb7,0xaf,0x78,0x00,0xb6,0xaf,0x04,0x00,0x02,0x36,0x04,0x0c,0x13,0x36,
-0x00,0x00,0x43,0x8c,0x00,0x00,0x62,0x8e,0x0f,0x00,0x11,0x3c,0x24,0x18,0x71,0x00,
-0x08,0x0c,0x12,0x36,0x4c,0x00,0xa2,0xaf,0x02,0xac,0x03,0x00,0x00,0x00,0x43,0x8e,
-0x00,0x00,0x00,0x00,0x50,0x00,0xa3,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c,
-0xff,0xff,0x25,0x36,0x10,0x00,0xa2,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,
-0x01,0x00,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,
-0x14,0x00,0xa2,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,
-0xe0,0x0e,0x05,0x36,0x00,0x00,0xad,0x8c,0xdc,0x0e,0x06,0x36,0x70,0x0e,0x07,0x36,
-0x18,0x00,0xad,0xaf,0x00,0x00,0xc2,0x8c,0x74,0x0e,0x08,0x36,0x78,0x0e,0x09,0x36,
-0x1c,0x00,0xa2,0xaf,0x00,0x00,0xe3,0x8c,0x7c,0x0e,0x0a,0x36,0x80,0x0e,0x0b,0x36,
-0x20,0x00,0xa3,0xaf,0x00,0x00,0x0d,0x8d,0x84,0x0e,0x0c,0x36,0x88,0x0e,0x17,0x36,
-0x24,0x00,0xad,0xaf,0x00,0x00,0x22,0x8d,0x8c,0x0e,0x0e,0x36,0xd0,0x0e,0x18,0x36,
-0x28,0x00,0xa2,0xaf,0x00,0x00,0x43,0x8d,0xd8,0x0e,0x11,0x36,0xd4,0x0e,0x10,0x36,
-0x2c,0x00,0xa3,0xaf,0x00,0x00,0x6d,0x8d,0xed,0x3f,0x04,0x3c,0xfb,0x92,0x84,0x34,
-0x30,0x00,0xad,0xaf,0x00,0x00,0x82,0x8d,0x25,0xb0,0x1e,0x3c,0x21,0xb0,0x00,0x00,
-0x34,0x00,0xa2,0xaf,0x00,0x00,0xe3,0x8e,0xff,0x03,0x0f,0x3c,0x38,0x00,0xa3,0xaf,
-0x00,0x00,0xcd,0x8d,0x00,0x00,0x00,0x00,0x3c,0x00,0xad,0xaf,0x00,0x00,0x02,0x8f,
-0x00,0x00,0x00,0x00,0x40,0x00,0xa2,0xaf,0x00,0x00,0x03,0x8e,0x00,0x00,0x00,0x00,
-0x44,0x00,0xa3,0xaf,0x00,0x00,0x2d,0x8e,0x00,0x00,0x00,0x00,0x48,0x00,0xad,0xaf,
-0x00,0x00,0xa4,0xac,0x00,0x00,0xc4,0xac,0x00,0x00,0xe4,0xac,0x00,0x00,0x04,0xad,
-0x00,0x00,0x24,0xad,0x00,0x00,0x44,0xad,0x00,0x00,0x64,0xad,0x00,0x00,0x84,0xad,
-0x00,0x00,0xe4,0xae,0x00,0x00,0xc4,0xad,0x00,0x00,0x04,0xaf,0x00,0x00,0x04,0xae,
-0x00,0x00,0x24,0xae,0xd0,0x51,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x00,0xa2,0x12,
-0x00,0x10,0x03,0x3c,0xac,0x0e,0xc2,0x37,0x94,0x0e,0xc3,0x37,0x25,0xb0,0x09,0x3c,
-0x00,0x00,0x4a,0x8c,0xbc,0x0e,0x29,0x35,0x00,0x00,0x64,0x8c,0xb4,0x0e,0xc2,0x37,
-0x9c,0x0e,0xc3,0x37,0x00,0x00,0x45,0x8c,0x00,0x00,0x66,0x8c,0x00,0x00,0x27,0x8d,
-0x24,0x20,0x8f,0x00,0x00,0xd8,0x02,0x3c,0x24,0x10,0x42,0x01,0x24,0x28,0xaf,0x00,
-0x24,0x30,0xcf,0x00,0x24,0x38,0xef,0x00,0x02,0x24,0x04,0x00,0x20,0x01,0x03,0x24,
-0x01,0x00,0x42,0x2c,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00,0xf2,0x00,0x83,0x10,
-0x02,0x3c,0x07,0x00,0xf0,0x00,0xa3,0x10,0x20,0x00,0x03,0x24,0xee,0x00,0xc3,0x10,
-0x00,0x00,0x00,0x00,0xec,0x00,0xe3,0x10,0x01,0x00,0x08,0x24,0x80,0x00,0x03,0x24,
-0x08,0x00,0x83,0x10,0x21,0x20,0x00,0x00,0x06,0x00,0xa3,0x10,0x21,0x20,0x00,0x00,
-0xe0,0x03,0x03,0x24,0x03,0x00,0xc3,0x10,0x00,0x00,0x00,0x00,0xe5,0x00,0xe3,0x10,
-0x01,0x00,0x04,0x24,0x06,0x00,0x40,0x10,0x09,0x00,0x02,0x24,0x04,0x00,0x00,0x11,
-0x00,0x00,0x00,0x00,0x6d,0x01,0x80,0x14,0x25,0xb0,0x12,0x3c,0x09,0x00,0x02,0x24,
-0xde,0x00,0xc2,0x12,0x25,0xb0,0x04,0x3c,0x01,0x00,0xd6,0x26,0x0a,0x00,0xc2,0x2e,
-0x1d,0x01,0x40,0x10,0x00,0x00,0x00,0x00,0xc8,0xff,0xa0,0x16,0x01,0x00,0x02,0x24,
-0xa0,0x00,0x03,0x3c,0x25,0xb0,0x09,0x3c,0x30,0x54,0x62,0x34,0x04,0x0c,0x29,0x35,
-0x00,0x00,0x22,0xad,0x25,0xb0,0x0d,0x3c,0x08,0x00,0x02,0x3c,0xe4,0x00,0x42,0x34,
-0x08,0x0c,0xad,0x35,0x25,0xb0,0x09,0x3c,0x00,0x00,0xa2,0xad,0x28,0x0e,0x29,0x35,
-0x80,0x80,0x02,0x3c,0x00,0x00,0x22,0xad,0x14,0x02,0x04,0x3c,0x16,0x68,0x02,0x3c,
-0x48,0x01,0x83,0x34,0x40,0x0e,0xc5,0x37,0x44,0x0e,0xc6,0x37,0xa2,0x04,0x42,0x34,
-0x25,0xb0,0x0d,0x3c,0x00,0x00,0xa3,0xac,0x4c,0x0e,0xad,0x35,0x00,0x00,0xc2,0xac,
-0xd1,0x28,0x02,0x24,0x00,0x00,0xa2,0xad,0x14,0x02,0x03,0x3c,0x16,0x28,0x02,0x3c,
-0x4d,0x01,0x63,0x34,0x60,0x0e,0xc7,0x37,0x64,0x0e,0xc8,0x37,0xba,0x08,0x42,0x34,
-0x00,0x00,0xe3,0xac,0x25,0xb0,0x06,0x3c,0x00,0x00,0x02,0xad,0x00,0xfb,0x0d,0x3c,
-0x25,0xb0,0x09,0x3c,0x00,0xf8,0x02,0x3c,0xd1,0x28,0x07,0x24,0x6c,0x0e,0xc6,0x34,
-0x48,0x0e,0x29,0x35,0x01,0x00,0x42,0x34,0x01,0x00,0xad,0x35,0x00,0x00,0xc7,0xac,
-0x03,0x00,0x04,0x24,0x00,0x00,0x2d,0xad,0x00,0x00,0x22,0xad,0x84,0x0a,0x00,0x0c,
-0x58,0x00,0xaf,0xaf,0xa0,0x00,0x04,0x3c,0x25,0xb0,0x03,0x3c,0x25,0xb0,0x06,0x3c,
-0x25,0xb0,0x07,0x3c,0xe4,0x00,0x02,0x24,0x33,0x54,0x84,0x34,0x04,0x0c,0x63,0x34,
-0x08,0x0c,0xc6,0x34,0x28,0x0e,0xe7,0x34,0x00,0x00,0x64,0xac,0x00,0x00,0xc2,0xac,
-0x00,0x00,0xe0,0xac,0x01,0x00,0x02,0x24,0x58,0x00,0xaf,0x8f,0x8a,0xff,0xa2,0x16,
-0xac,0x0e,0xc2,0x37,0x00,0x10,0x03,0x3c,0x1f,0xdc,0x79,0x34,0x1f,0x8c,0x7f,0x34,
-0x23,0x8c,0x6d,0x34,0xa0,0x00,0x03,0x3c,0x30,0x54,0x65,0x34,0x00,0x01,0x17,0x3c,
-0x25,0xb0,0x09,0x3c,0x25,0xb0,0x03,0x3c,0x00,0x01,0xe2,0x36,0x20,0x08,0x29,0x35,
-0x20,0x08,0x63,0x34,0x00,0x00,0x30,0x8d,0x00,0x00,0x62,0xac,0x25,0xb0,0x03,0x3c,
-0x28,0x08,0x63,0x34,0x00,0x00,0x62,0xac,0x25,0xb0,0x02,0x3c,0x04,0x0c,0x42,0x34,
-0x00,0x00,0x45,0xac,0x25,0xb0,0x03,0x3c,0x08,0x00,0x02,0x3c,0xe4,0x00,0x42,0x34,
-0x08,0x0c,0x63,0x34,0x00,0x00,0x62,0xac,0x25,0xb0,0x03,0x3c,0x00,0x7c,0xf3,0x36,
-0x00,0x48,0xf4,0x36,0x30,0x0e,0xc6,0x37,0x34,0x0e,0xc7,0x37,0x80,0x80,0x02,0x3c,
-0x28,0x0e,0x63,0x34,0x00,0x00,0x62,0xac,0x00,0x00,0xd3,0xac,0x00,0x00,0xf4,0xac,
-0x14,0x02,0x06,0x3c,0x16,0x68,0x07,0x3c,0x38,0x0e,0xc8,0x37,0x40,0x0e,0xca,0x37,
-0x44,0x0e,0xcb,0x37,0x3c,0x0e,0xc9,0x37,0x02,0x01,0xc6,0x34,0xc7,0x04,0xe7,0x34,
-0x00,0x00,0x19,0xad,0x25,0xb0,0x03,0x3c,0x00,0x00,0x3f,0xad,0x00,0x00,0x46,0xad,
-0x25,0xb0,0x09,0x3c,0x00,0x00,0x67,0xad,0x25,0xb0,0x06,0x3c,0x00,0x10,0x07,0x3c,
-0x50,0x0e,0xcc,0x37,0x58,0x0e,0xce,0x37,0x5c,0x0e,0xd8,0x37,0xd1,0x28,0x02,0x24,
-0x23,0xdc,0xe7,0x34,0x4c,0x0e,0x29,0x35,0x6c,0x0e,0x63,0x34,0x54,0x0e,0xc6,0x34,
-0x00,0x00,0x22,0xad,0x00,0x00,0x62,0xac,0x14,0x02,0x09,0x3c,0x00,0x00,0x93,0xad,
-0x25,0xb0,0x02,0x3c,0x00,0x00,0xd4,0xac,0x00,0x00,0xc7,0xad,0x00,0x00,0x0d,0xaf,
-0x16,0x28,0x0d,0x3c,0x48,0x0e,0x42,0x34,0x00,0xf8,0x06,0x3c,0x02,0x01,0x29,0x35,
-0x07,0x0d,0xad,0x35,0x00,0xfb,0x03,0x3c,0x60,0x0e,0xd1,0x37,0x64,0x0e,0xd2,0x37,
-0x00,0x00,0x29,0xae,0x03,0x00,0x04,0x24,0x00,0x00,0x4d,0xae,0x00,0x00,0x43,0xac,
-0x00,0x00,0x46,0xac,0x84,0x0a,0x00,0x0c,0x58,0x00,0xaf,0xaf,0x00,0x02,0x02,0x3c,
-0x25,0xb0,0x07,0x3c,0x25,0xb0,0x09,0x3c,0xd1,0x28,0x42,0x34,0x4c,0x0e,0xe7,0x34,
-0x6c,0x0e,0x29,0x35,0x25,0xb0,0x0d,0x3c,0x00,0x00,0xe2,0xac,0x48,0x0e,0xad,0x35,
-0x00,0x00,0x22,0xad,0x00,0xf8,0x03,0x3c,0x00,0xfb,0x02,0x3c,0x00,0x00,0xa2,0xad,
-0x03,0x00,0x04,0x24,0x00,0x00,0xa3,0xad,0x84,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x4c,0x00,0xa6,0x8f,0x25,0xb0,0x04,0x3c,0x04,0x0c,0x84,0x34,0x00,0x00,0x86,0xac,
-0x50,0x00,0xa9,0x8f,0x25,0xb0,0x07,0x3c,0x25,0xb0,0x0d,0x3c,0x00,0x01,0x10,0x32,
-0x08,0x0c,0xe7,0x34,0x28,0x0e,0xad,0x35,0x00,0x00,0xe9,0xac,0x2b,0x80,0x10,0x00,
-0x00,0x00,0xa0,0xad,0x58,0x00,0xaf,0x8f,0x17,0xff,0x00,0x16,0xac,0x0e,0xc2,0x37,
-0x25,0xb0,0x02,0x3c,0x25,0xb0,0x03,0x3c,0x20,0x08,0x42,0x34,0x28,0x08,0x63,0x34,
-0x00,0x00,0x57,0xac,0x25,0xb0,0x09,0x3c,0x00,0x00,0x77,0xac,0xac,0x0e,0xc2,0x37,
-0x94,0x0e,0xc3,0x37,0x00,0x00,0x4a,0x8c,0xbc,0x0e,0x29,0x35,0x00,0x00,0x64,0x8c,
-0xb4,0x0e,0xc2,0x37,0x9c,0x0e,0xc3,0x37,0x00,0x00,0x45,0x8c,0x00,0x00,0x66,0x8c,
-0x00,0x00,0x27,0x8d,0x24,0x20,0x8f,0x00,0x00,0xd8,0x02,0x3c,0x24,0x10,0x42,0x01,
-0x24,0x28,0xaf,0x00,0x24,0x30,0xcf,0x00,0x24,0x38,0xef,0x00,0x02,0x24,0x04,0x00,
-0x20,0x01,0x03,0x24,0x01,0x00,0x42,0x2c,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00,
-0x10,0xff,0x83,0x14,0x02,0x3c,0x07,0x00,0x80,0x00,0x03,0x24,0x16,0xff,0x83,0x14,
-0x21,0x40,0x00,0x00,0xc3,0x51,0x00,0x08,0x21,0x20,0x00,0x00,0xff,0xff,0x02,0x34,
-0xc4,0x02,0x84,0x34,0x00,0x00,0x82,0xac,0x94,0x0e,0xc3,0x37,0x9c,0x0e,0xc2,0x37,
-0xa4,0x0e,0xc4,0x37,0xac,0x0e,0xc7,0x37,0x00,0x00,0x66,0x8c,0x00,0x00,0x49,0x8c,
-0x00,0x00,0x8b,0x8c,0x00,0x00,0xe5,0x8c,0x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24,
-0x0c,0x40,0xe3,0x8c,0x10,0x40,0xe4,0x8c,0xb4,0x0e,0xc2,0x37,0x00,0x00,0x47,0x8c,
-0x25,0xb0,0x0d,0x3c,0x00,0xfc,0x02,0x24,0x24,0x30,0xcf,0x00,0x24,0x28,0xaf,0x00,
-0xbc,0x0e,0xad,0x35,0x00,0x00,0xa8,0x8d,0x24,0x20,0x82,0x00,0x02,0x34,0x06,0x00,
-0x24,0x18,0x62,0x00,0x02,0x2c,0x05,0x00,0xc4,0x0e,0xca,0x37,0xcc,0x0e,0xcc,0x37,
-0xf0,0xff,0x02,0x3c,0xff,0x03,0x42,0x34,0x25,0x18,0x66,0x00,0x25,0x20,0x85,0x00,
-0x00,0x00,0x46,0x8d,0x24,0x48,0x2f,0x01,0x00,0x00,0x85,0x8d,0x24,0x38,0xef,0x00,
-0x24,0x20,0x82,0x00,0x24,0x18,0x62,0x00,0x82,0x49,0x09,0x00,0x82,0x39,0x07,0x00,
-0x0f,0xc0,0x02,0x3c,0xff,0xff,0x42,0x34,0x25,0x18,0x69,0x00,0x25,0x20,0x87,0x00,
-0x24,0x58,0x6f,0x01,0x24,0x40,0x0f,0x01,0x24,0x20,0x82,0x00,0x24,0x18,0x62,0x00,
-0x00,0x59,0x0b,0x00,0x00,0x41,0x08,0x00,0x24,0x30,0xcf,0x00,0x24,0x28,0xaf,0x00,
-0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x25,0x18,0x6b,0x00,0x25,0x20,0x88,0x00,
-0x02,0x34,0x06,0x00,0x02,0x2c,0x05,0x00,0x01,0x00,0xd6,0x26,0x0c,0x40,0x43,0xac,
-0x10,0x40,0x44,0xac,0x14,0x40,0x46,0xa4,0x16,0x40,0x45,0xa4,0x0a,0x00,0xc2,0x2e,
-0xe5,0xfe,0x40,0x14,0x00,0x00,0x00,0x00,0x18,0x00,0xad,0x8f,0x25,0xb0,0x02,0x3c,
-0xe0,0x0e,0x43,0x34,0x10,0x00,0xa6,0x8f,0x00,0x00,0x6d,0xac,0x1c,0x00,0xa3,0x8f,
-0xdc,0x0e,0x47,0x34,0x70,0x0e,0x48,0x34,0x00,0x00,0xe3,0xac,0x20,0x00,0xa7,0x8f,
-0x74,0x0e,0x49,0x34,0x78,0x0e,0x4a,0x34,0x00,0x00,0x07,0xad,0x24,0x00,0xad,0x8f,
-0x7c,0x0e,0x4b,0x34,0x80,0x0e,0x4c,0x34,0x00,0x00,0x2d,0xad,0x28,0x00,0xa3,0x8f,
-0x25,0xb0,0x0d,0x3c,0x84,0x0e,0xad,0x35,0x00,0x00,0x43,0xad,0x2c,0x00,0xa7,0x8f,
-0x88,0x0e,0x52,0x34,0x8c,0x0e,0x4e,0x34,0x00,0x00,0x67,0xad,0x30,0x00,0xa9,0x8f,
-0xd4,0x0e,0x51,0x34,0xd0,0x0e,0x42,0x34,0x00,0x00,0x89,0xad,0x34,0x00,0xa3,0x8f,
-0x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0x00,0x00,0xa3,0xad,0x38,0x00,0xa7,0x8f,
-0x21,0x20,0x00,0x00,0x00,0x00,0x47,0xae,0x3c,0x00,0xa9,0x8f,0x00,0x00,0x00,0x00,
-0x00,0x00,0xc9,0xad,0x40,0x00,0xad,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0xac,
-0x44,0x00,0xa2,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0xae,0x48,0x00,0xa3,0x8f,
-0x00,0x00,0x00,0x00,0x00,0x00,0x43,0xae,0xba,0x44,0x00,0x0c,0x00,0x00,0x00,0x00,
-0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,
-0x14,0x00,0xa6,0x8f,0xff,0xff,0x05,0x36,0xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00,
-0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x84,0x00,0xbf,0x8f,0x80,0x00,0xbe,0x8f,
-0x7c,0x00,0xb7,0x8f,0x78,0x00,0xb6,0x8f,0x74,0x00,0xb5,0x8f,0x70,0x00,0xb4,0x8f,
-0x6c,0x00,0xb3,0x8f,0x68,0x00,0xb2,0x8f,0x64,0x00,0xb1,0x8f,0x60,0x00,0xb0,0x8f,
-0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x08,0x88,0x00,0xbd,0x27,0x94,0x0e,0x42,0x36,
-0x9c,0x0e,0x43,0x36,0xa4,0x0e,0x44,0x36,0xac,0x0e,0x45,0x36,0x02,0x80,0x0d,0x3c,
-0x00,0x00,0x47,0x8c,0x68,0x15,0xad,0x25,0x00,0x00,0x6a,0x8c,0x00,0x00,0x8c,0x8c,
-0x00,0x00,0xa3,0x8c,0x10,0x40,0xa4,0x8d,0xb4,0x0e,0x42,0x36,0x00,0x00,0x48,0x8c,
-0x0c,0x40,0xa5,0x8d,0x25,0xb0,0x02,0x3c,0x00,0xfc,0x13,0x24,0xbc,0x0e,0x42,0x34,
-0x24,0x18,0x6f,0x00,0x00,0x00,0x49,0x8c,0x02,0x1c,0x03,0x00,0x24,0x38,0xef,0x00,
-0x24,0x20,0x93,0x00,0xf0,0xff,0x06,0x3c,0x25,0x20,0x83,0x00,0xff,0x03,0xc6,0x34,
-0x02,0x3c,0x07,0x00,0xc4,0x0e,0x42,0x36,0x24,0x28,0xb3,0x00,0x24,0x40,0x0f,0x01,
-0xcc,0x0e,0x4b,0x36,0x25,0x28,0xa7,0x00,0x24,0x20,0x86,0x00,0x00,0x00,0x47,0x8c,
-0x24,0x50,0x4f,0x01,0x00,0x00,0x63,0x8d,0x82,0x41,0x08,0x00,0x0f,0xc0,0x02,0x3c,
-0xff,0xff,0x42,0x34,0x25,0x20,0x88,0x00,0x82,0x51,0x0a,0x00,0x24,0x28,0xa6,0x00,
-0x24,0x48,0x2f,0x01,0x24,0x88,0x82,0x00,0x25,0x28,0xaa,0x00,0x24,0x60,0x8f,0x01,
-0x00,0x49,0x09,0x00,0x25,0x88,0x29,0x02,0x24,0x28,0xa2,0x00,0x24,0x18,0x6f,0x00,
-0x00,0x61,0x0c,0x00,0x24,0x38,0xef,0x00,0x25,0x28,0xac,0x00,0x02,0x3c,0x07,0x00,
-0x02,0x1c,0x03,0x00,0x82,0x27,0x11,0x00,0x01,0x00,0x02,0x24,0x16,0x40,0xa3,0xa5,
-0x14,0x40,0xa7,0xa5,0x0c,0x40,0xa5,0xad,0x4a,0x00,0x82,0x10,0x10,0x40,0xb1,0xad,
-0x80,0x0c,0x4c,0x36,0x00,0x00,0x8a,0x8d,0x82,0x72,0x05,0x00,0xff,0x03,0xce,0x31,
-0x00,0x02,0xc3,0x31,0x25,0x10,0xd3,0x01,0x0b,0x70,0x43,0x00,0x82,0x85,0x0a,0x00,
-0x18,0x00,0xd0,0x01,0xff,0x03,0xaf,0x30,0x00,0x02,0xa3,0x30,0x25,0x10,0xf3,0x01,
-0x0b,0x78,0x43,0x00,0x02,0x75,0x11,0x00,0xff,0x03,0xce,0x31,0xc0,0xff,0x08,0x3c,
-0x25,0x18,0xd3,0x01,0x00,0x02,0xc2,0x31,0x00,0xfc,0x06,0x35,0x0b,0x70,0x62,0x00,
-0x24,0x38,0x46,0x01,0x94,0x0c,0x4a,0x36,0xff,0x0f,0x09,0x3c,0xff,0xff,0x29,0x35,
-0x88,0x0c,0x54,0x36,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30,
-0x18,0x00,0xf0,0x01,0x82,0x7a,0x11,0x00,0xff,0x03,0xef,0x31,0x00,0x14,0x02,0x00,
-0x25,0x38,0xe2,0x00,0x00,0x02,0xe3,0x31,0x25,0x10,0xf3,0x01,0x0b,0x78,0x43,0x00,
-0xc0,0x03,0x84,0x30,0x80,0x25,0x04,0x00,0x9c,0x0c,0x4b,0x36,0x12,0x28,0x00,0x00,
-0x02,0x2a,0x05,0x00,0xff,0x03,0xa2,0x30,0x25,0x10,0xe2,0x00,0x00,0x00,0x82,0xad,
-0x00,0x00,0x42,0x8d,0x00,0x00,0x00,0x00,0x24,0x10,0x49,0x00,0x25,0x10,0x44,0x00,
-0x00,0x00,0x42,0xad,0x00,0x00,0x8a,0x8e,0x00,0x00,0x00,0x00,0x24,0x40,0x48,0x01,
-0x82,0x85,0x08,0x00,0x18,0x00,0xd0,0x01,0x24,0x30,0x46,0x01,0x12,0x18,0x00,0x00,
-0x02,0x1a,0x03,0x00,0x3f,0x00,0x62,0x30,0x18,0x00,0xf0,0x01,0x00,0x14,0x02,0x00,
-0x25,0x30,0xc2,0x00,0xc0,0x03,0x63,0x30,0x80,0x1d,0x03,0x00,0x12,0x20,0x00,0x00,
-0x02,0x22,0x04,0x00,0xff,0x03,0x82,0x30,0x25,0x10,0xc2,0x00,0x00,0x00,0x82,0xae,
-0x00,0x00,0x62,0x8d,0x00,0x00,0x00,0x00,0x24,0x10,0x49,0x00,0x25,0x10,0x43,0x00,
-0x00,0x00,0x62,0xad,0x00,0x17,0x16,0x00,0x25,0xb0,0x03,0x3c,0xdd,0xdd,0x42,0x34,
-0xc4,0x02,0x63,0x34,0x00,0x00,0x62,0xac,0xec,0x52,0x00,0x08,0x00,0x00,0x00,0x00,
-0xe0,0xff,0xbd,0x27,0x44,0x00,0x02,0x24,0x10,0x00,0xa2,0xa3,0x49,0x00,0x03,0x24,
-0x47,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x8c,0x97,0xe7,0x24,0x11,0x00,0xa3,0xa3,
-0x12,0x00,0xa2,0xa3,0x10,0x27,0x03,0x24,0x01,0x00,0x02,0x24,0x01,0x80,0x06,0x3c,
-0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xe8,0x51,0xc6,0x24,0x0c,0x00,0xe3,0xac,
-0x14,0x00,0xe2,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,
-0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
-0xd0,0xff,0xbd,0x27,0x25,0xb0,0x02,0x3c,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,
-0x03,0x0d,0x44,0x34,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf,
-0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x83,0x90,
-0x42,0x00,0x45,0x34,0xff,0x00,0x73,0x30,0x70,0x00,0x74,0x32,0x29,0x00,0x80,0x16,
-0x8f,0x00,0x62,0x32,0xff,0xff,0x02,0x24,0x00,0x00,0xa2,0xa0,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c,
-0x18,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0x80,0x40,0x00,
-0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,
-0x64,0x00,0x04,0x24,0x00,0x80,0x06,0x36,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c,
-0x18,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0x03,0x00,0x04,0x24,0x21,0x30,0xa0,0x02,
-0xff,0xff,0x25,0x36,0x5c,0x00,0x80,0x16,0x21,0x20,0x00,0x00,0x2c,0x00,0xbf,0x8f,
-0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,
-0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x25,0xb0,0x02,0x3c,
-0x42,0x00,0x42,0x34,0x30,0x00,0xbd,0x27,0x00,0x00,0x40,0xa0,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xa0,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c,0x21,0x20,0x00,0x00,
-0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0xa8,0x40,0x00,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,
-0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c,
-0xff,0xff,0x25,0x36,0x21,0xb0,0x40,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x00,0x60,0x81,0x40,0x64,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x08,0x00,0x10,0x3c,
-0xff,0xff,0x10,0x36,0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0x01,0x00,0x12,0x3c,
-0x24,0x30,0xb0,0x02,0x25,0x30,0xd2,0x00,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c,
-0x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x24,0x80,0xd0,0x02,
-0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0x25,0x30,0x12,0x02,0xff,0xff,0x25,0x36,
-0xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,
-0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
-0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c,0x18,0x00,0x04,0x24,
-0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0x80,0x40,0x00,0x00,0x60,0x01,0x40,
-0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,
-0x00,0x80,0x06,0x36,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c,0x18,0x00,0x04,0x24,
-0x84,0x0a,0x00,0x0c,0x03,0x00,0x04,0x24,0x21,0x30,0xa0,0x02,0xff,0xff,0x25,0x36,
-0xa6,0xff,0x80,0x12,0x21,0x20,0x00,0x00,0x25,0xb0,0x02,0x3c,0x03,0x0d,0x42,0x34,
-0x00,0x00,0x53,0xa0,0xba,0x44,0x00,0x0c,0x00,0x00,0x00,0x00,0xb3,0x0a,0x00,0x0c,
-0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0xff,0xff,0x25,0x36,
-0x21,0x30,0xc0,0x02,0xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c,
-0x64,0x00,0x04,0x24,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,
-0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x08,0x30,0x00,0xbd,0x27,
-0xd0,0xff,0xbd,0x27,0x28,0x00,0xb4,0xaf,0x02,0x80,0x14,0x3c,0x2c,0x00,0xbf,0xaf,
-0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
-0x68,0x15,0x86,0x26,0x0c,0x40,0xc2,0x8c,0x00,0x00,0x00,0x00,0x82,0x17,0x02,0x00,
-0x01,0x00,0x42,0x30,0x07,0x00,0x40,0x14,0x68,0x15,0x85,0x26,0x08,0x40,0xc2,0x8c,
-0x01,0x00,0x03,0x24,0x42,0x17,0x02,0x00,0x03,0x00,0x42,0x30,0xf0,0x00,0x43,0x10,
-0x25,0xb0,0x02,0x3c,0x0c,0x40,0xa2,0x8c,0x01,0x00,0x03,0x24,0x82,0x17,0x02,0x00,
-0x01,0x00,0x44,0x30,0x0a,0x00,0x83,0x10,0x00,0x00,0x00,0x00,0x2c,0x00,0xbf,0x8f,
-0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,
-0x18,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,
-0x08,0x40,0xa2,0x8c,0x00,0x00,0x00,0x00,0x42,0x17,0x02,0x00,0x03,0x00,0x42,0x30,
-0xf2,0xff,0x44,0x14,0x25,0xb0,0x02,0x3c,0x0e,0x0c,0x44,0x34,0x00,0x00,0x83,0x90,
-0x00,0x01,0x02,0x24,0xff,0x00,0x63,0x30,0x01,0x00,0x63,0x24,0x8b,0x01,0x62,0x10,
-0x00,0x00,0x00,0x00,0x00,0x00,0x83,0xa0,0x68,0x15,0x84,0x26,0x10,0x40,0x82,0x8c,
-0x01,0x00,0x03,0x24,0x82,0x17,0x02,0x00,0xa4,0x01,0x43,0x10,0x0f,0x00,0x10,0x3c,
-0xc7,0x42,0x92,0x90,0x68,0x15,0x90,0x26,0xc6,0x42,0x03,0x92,0x25,0xb0,0x11,0x3c,
-0x62,0x0c,0x22,0x36,0x00,0x00,0x52,0xa0,0x17,0x01,0x60,0x10,0x01,0x00,0x02,0x24,
-0x03,0x0d,0x23,0x36,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x70,0x00,0x42,0x30,
-0x3e,0x01,0x40,0x14,0x63,0x0c,0x23,0x36,0xc4,0x42,0x02,0x96,0x00,0x00,0x00,0x00,
-0x23,0x20,0x52,0x00,0x2b,0x18,0x52,0x00,0x23,0x10,0x42,0x02,0x0a,0x10,0x83,0x00,
-0x03,0x00,0x42,0x2c,0x0b,0x01,0x40,0x10,0x00,0x00,0x00,0x00,0xc4,0x42,0x03,0x96,
-0x63,0x0c,0x22,0x36,0x00,0x00,0x43,0xa0,0x68,0x15,0x83,0x26,0xc3,0x42,0x62,0x90,
-0x08,0x40,0x66,0x8c,0xc2,0x42,0x72,0xa0,0x23,0x20,0x52,0x00,0x2b,0x38,0x42,0x02,
-0x23,0x50,0x42,0x02,0x02,0x2c,0x06,0x00,0x0b,0x50,0x87,0x00,0x3f,0x00,0xa5,0x30,
-0x3f,0x00,0xc4,0x30,0x24,0x00,0x02,0x24,0x20,0x00,0x03,0x24,0x23,0x10,0x44,0x00,
-0x2d,0x01,0x40,0x15,0x23,0x18,0x65,0x00,0x21,0x30,0x80,0x00,0x21,0x48,0xa0,0x00,
-0x02,0x80,0x0b,0x3c,0x68,0x15,0x83,0x26,0x80,0x10,0x06,0x00,0x21,0x10,0x43,0x00,
-0x0c,0x40,0x63,0x8c,0x18,0x40,0x44,0x8c,0xff,0x03,0x67,0x30,0x1b,0x01,0xe0,0x10,
-0x82,0x2d,0x04,0x00,0x00,0x02,0x62,0x30,0x04,0x00,0x40,0x10,0x18,0x00,0xe5,0x00,
-0x00,0xfc,0x02,0x24,0x25,0x38,0xe2,0x00,0x18,0x00,0xe5,0x00,0x82,0x22,0x03,0x00,
-0xff,0x03,0x84,0x30,0x00,0x02,0x83,0x30,0x12,0x10,0x00,0x00,0x02,0x12,0x02,0x00,
-0x03,0x00,0x60,0x10,0xff,0x03,0x48,0x30,0x00,0xfc,0x02,0x24,0x25,0x20,0x82,0x00,
-0x18,0x00,0x85,0x00,0x80,0x2d,0x05,0x00,0x25,0xb0,0x06,0x3c,0x80,0x0c,0xc7,0x34,
-0x94,0x0c,0xc6,0x34,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30,
-0x00,0x14,0x02,0x00,0x25,0x28,0xa2,0x00,0x25,0x28,0xa8,0x00,0x10,0x00,0xa5,0xaf,
-0x00,0x00,0xe5,0xac,0x00,0x00,0xc3,0x8c,0xff,0x0f,0x02,0x3c,0xc0,0x03,0x84,0x30,
-0xff,0xff,0x42,0x34,0x80,0x25,0x04,0x00,0x24,0x18,0x62,0x00,0x25,0x18,0x64,0x00,
-0x10,0x00,0xa3,0xaf,0x00,0x00,0xc3,0xac,0x68,0x15,0x83,0x26,0x08,0x40,0x62,0x8c,
-0x00,0x00,0x00,0x00,0x08,0x01,0x40,0x04,0xc0,0x28,0x09,0x00,0x21,0x28,0xa3,0x00,
-0xac,0x40,0xa3,0x90,0x25,0xb0,0x04,0x3c,0x22,0x0a,0x82,0x34,0x00,0x00,0x43,0xa0,
-0xad,0x40,0xa6,0x90,0x23,0x0a,0x82,0x34,0x24,0x0a,0x87,0x34,0x00,0x00,0x46,0xa0,
-0xae,0x40,0xa3,0x90,0x25,0x0a,0x86,0x34,0x26,0x0a,0x88,0x34,0x00,0x00,0xe3,0xa0,
-0xaf,0x40,0xa2,0x90,0x27,0x0a,0x87,0x34,0x28,0x0a,0x89,0x34,0x00,0x00,0xc2,0xa0,
-0xb0,0x40,0xa3,0x90,0x29,0x0a,0x84,0x34,0x00,0x00,0x03,0xa1,0xb1,0x40,0xa2,0x90,
-0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0xa0,0xb2,0x40,0xa3,0x90,0x00,0x00,0x00,0x00,
-0x00,0x00,0x23,0xa1,0xb3,0x40,0xa2,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xa0,
-0x8e,0x7d,0x63,0x91,0x22,0x00,0x02,0x24,0x03,0x00,0x62,0x10,0x92,0x00,0x02,0x24,
-0x62,0xff,0x62,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x82,0x26,0x08,0x40,0x43,0x8c,
-0x01,0x00,0x44,0x39,0x24,0x00,0x02,0x24,0x02,0x1a,0x03,0x00,0x3f,0x00,0x63,0x30,
-0x01,0x00,0x84,0x30,0x04,0x01,0x80,0x10,0x23,0x28,0x43,0x00,0x42,0x18,0x0a,0x00,
-0x40,0x10,0x03,0x00,0x21,0x50,0x43,0x00,0x68,0x15,0x83,0x26,0xc3,0x42,0x62,0x90,
-0x00,0x00,0x00,0x00,0x2b,0x10,0x42,0x02,0x08,0x01,0x40,0x10,0x21,0x20,0x00,0x00,
-0x2b,0x10,0x45,0x01,0x07,0x00,0x40,0x10,0x24,0x00,0x04,0x24,0x08,0x40,0x62,0x8c,
-0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x3f,0x00,0x42,0x30,0x21,0x20,0x4a,0x00,
-0x68,0x15,0x83,0x26,0x80,0x10,0x04,0x00,0x10,0x40,0x66,0x8c,0x21,0x10,0x43,0x00,
-0x18,0x40,0x44,0x8c,0x82,0x3a,0x06,0x00,0xff,0x03,0xe7,0x30,0xf0,0x00,0xe0,0x10,
-0x82,0x2d,0x04,0x00,0x00,0x02,0xe2,0x30,0x04,0x00,0x40,0x10,0x18,0x00,0xe5,0x00,
-0x00,0xfc,0x02,0x24,0x25,0x38,0xe2,0x00,0x18,0x00,0xe5,0x00,0x02,0x25,0x06,0x00,
-0xff,0x03,0x84,0x30,0x00,0x02,0x83,0x30,0x12,0x10,0x00,0x00,0x02,0x12,0x02,0x00,
-0x03,0x00,0x60,0x10,0xff,0x03,0x48,0x30,0x00,0xfc,0x02,0x24,0x25,0x20,0x82,0x00,
-0x18,0x00,0x85,0x00,0x80,0x2d,0x05,0x00,0x25,0xb0,0x06,0x3c,0x88,0x0c,0xc7,0x34,
-0x9c,0x0c,0xc6,0x34,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30,
-0x00,0x14,0x02,0x00,0x25,0x28,0xa2,0x00,0x25,0x28,0xa8,0x00,0x10,0x00,0xa5,0xaf,
-0x00,0x00,0xe5,0xac,0x00,0x00,0xc3,0x8c,0xff,0x0f,0x02,0x3c,0xc0,0x03,0x84,0x30,
-0xff,0xff,0x42,0x34,0x80,0x25,0x04,0x00,0x24,0x18,0x62,0x00,0x25,0x18,0x64,0x00,
-0x10,0x00,0xa3,0xaf,0x00,0x00,0xc3,0xac,0x95,0x54,0x00,0x08,0x00,0x00,0x00,0x00,
-0x80,0x0c,0x42,0x34,0x00,0x00,0x43,0x8c,0xc0,0xff,0x02,0x3c,0x21,0x88,0x00,0x00,
-0x24,0x28,0x62,0x00,0xc0,0xff,0x04,0x3c,0x8a,0x55,0x00,0x08,0x18,0x40,0xc3,0x24,
-0x01,0x00,0x31,0x26,0x25,0x00,0x22,0x2e,0x0d,0x00,0x40,0x10,0x02,0x80,0x0b,0x3c,
-0x00,0x00,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x44,0x00,0xf8,0xff,0x45,0x14,
-0x04,0x00,0x63,0x24,0x08,0x40,0xc2,0x8c,0xc0,0xff,0x03,0x24,0x3f,0x00,0x24,0x32,
-0x24,0x10,0x43,0x00,0x25,0x10,0x44,0x00,0x08,0x40,0xc2,0xac,0x02,0x80,0x0b,0x3c,
-0x8e,0x7d,0x63,0x91,0x22,0x00,0x02,0x24,0x3e,0x00,0x62,0x10,0x92,0x00,0x02,0x24,
-0x3d,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c,0x25,0xb0,0x02,0x3c,0x24,0x0a,0x42,0x34,
-0x00,0x00,0x44,0x8c,0x3f,0x3f,0x03,0x3c,0x3f,0x3f,0x63,0x34,0x24,0x20,0x83,0x00,
-0x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c,0x16,0x56,0x53,0x24,0x1e,0x57,0x72,0x24,
-0x21,0x88,0x00,0x00,0xb1,0x55,0x00,0x08,0x10,0x00,0xa4,0xaf,0xd4,0x45,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x47,0x00,0x40,0x10,0x68,0x15,0x85,0x26,0x01,0x00,0x31,0x26,
-0x21,0x00,0x22,0x2e,0x17,0x00,0x40,0x10,0x68,0x15,0x84,0x26,0xc0,0x80,0x11,0x00,
-0x10,0x00,0xa4,0x27,0x21,0x28,0x13,0x02,0xd4,0x45,0x00,0x0c,0x04,0x00,0x06,0x24,
-0x21,0x28,0x12,0x02,0x10,0x00,0xa4,0x27,0xf0,0xff,0x40,0x14,0x04,0x00,0x06,0x24,
-0x68,0x15,0x85,0x26,0x08,0x40,0xa3,0x8c,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34,
-0x3f,0x00,0x24,0x32,0x24,0x18,0x62,0x00,0x00,0x24,0x04,0x00,0xff,0x7f,0x02,0x3c,
-0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x08,0x40,0xa3,0xac,
-0x68,0x15,0x84,0x26,0x0c,0x40,0x83,0x8c,0x00,0x40,0x02,0x3c,0x25,0x18,0x62,0x00,
-0x25,0xb0,0x02,0x3c,0x0e,0x0c,0x42,0x34,0x0c,0x40,0x83,0xac,0x00,0x00,0x40,0xa0,
-0x8f,0x54,0x00,0x08,0x68,0x15,0x85,0x26,0xc6,0x42,0x02,0xa2,0xba,0x54,0x00,0x08,
-0xc4,0x42,0x12,0xa6,0xda,0x53,0x00,0x0c,0x00,0x00,0x00,0x00,0xc9,0x54,0x00,0x08,
-0xc4,0x42,0x12,0xa6,0x25,0xb0,0x02,0x3c,0x88,0x0c,0x42,0x34,0x00,0x00,0x44,0x8c,
-0x02,0x80,0x03,0x3c,0x68,0x15,0x66,0x24,0xc0,0xff,0x02,0x3c,0x24,0x28,0x82,0x00,
-0x21,0x88,0x00,0x00,0xc0,0xff,0x04,0x3c,0xe6,0x55,0x00,0x08,0x18,0x40,0xc3,0x24,
-0x01,0x00,0x31,0x26,0x25,0x00,0x22,0x2e,0xb8,0xff,0x40,0x10,0x25,0xb0,0x02,0x3c,
-0x00,0x00,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x44,0x00,0xf8,0xff,0x45,0x14,
-0x04,0x00,0x63,0x24,0x08,0x40,0xc2,0x8c,0x3f,0x00,0x23,0x32,0xff,0xc0,0x04,0x24,
-0x24,0x10,0x44,0x00,0x00,0x1a,0x03,0x00,0x25,0x10,0x43,0x00,0x9c,0x55,0x00,0x08,
-0x08,0x40,0xc2,0xac,0x08,0x40,0xa3,0x8c,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34,
-0x3f,0x00,0x24,0x32,0x24,0x18,0x62,0x00,0x00,0x24,0x04,0x00,0x25,0x18,0x64,0x00,
-0x00,0x80,0x02,0x3c,0xc5,0x55,0x00,0x08,0x25,0x18,0x62,0x00,0xcc,0xff,0x02,0x24,
-0x00,0x00,0x62,0xa0,0xcd,0x54,0x00,0x08,0x68,0x15,0x83,0x26,0x25,0xb0,0x02,0x3c,
-0x94,0x0c,0x43,0x34,0x80,0x0c,0x42,0x34,0x00,0x00,0x44,0xac,0x00,0x00,0x60,0xac,
-0x0d,0x55,0x00,0x08,0x68,0x15,0x83,0x26,0x2f,0x00,0xe0,0x10,0x21,0x30,0x00,0x00,
-0x2b,0x10,0x42,0x01,0x21,0x20,0x8a,0x00,0x00,0x00,0x42,0x38,0x24,0x00,0x06,0x24,
-0x2b,0x18,0x43,0x01,0x0b,0x30,0x82,0x00,0xcd,0xfe,0x60,0x10,0x20,0x00,0x09,0x24,
-0x68,0x15,0x83,0x26,0x0a,0x40,0x62,0x94,0x02,0x80,0x0b,0x3c,0x3f,0x00,0x42,0x30,
-0xe0,0x54,0x00,0x08,0x21,0x48,0x4a,0x00,0x21,0x28,0xa3,0x00,0xb4,0x41,0xa3,0x90,
-0x25,0xb0,0x04,0x3c,0x22,0x0a,0x82,0x34,0x00,0x00,0x43,0xa0,0xb5,0x41,0xa6,0x90,
-0x23,0x0a,0x82,0x34,0x24,0x0a,0x87,0x34,0x00,0x00,0x46,0xa0,0xb6,0x41,0xa3,0x90,
-0x25,0x0a,0x86,0x34,0x26,0x0a,0x88,0x34,0x00,0x00,0xe3,0xa0,0xb7,0x41,0xa2,0x90,
-0x27,0x0a,0x87,0x34,0x28,0x0a,0x89,0x34,0x00,0x00,0xc2,0xa0,0xb8,0x41,0xa3,0x90,
-0x29,0x0a,0x84,0x34,0x00,0x00,0x03,0xa1,0xb9,0x41,0xa2,0x90,0x00,0x00,0x00,0x00,
-0x00,0x00,0xe2,0xa0,0xba,0x41,0xa3,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0xa1,
-0xbb,0x41,0xa2,0x90,0x2d,0x55,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa0,
-0xad,0x54,0x00,0x08,0x68,0x15,0x84,0x26,0x23,0x10,0x8a,0x00,0x2b,0x18,0x44,0x01,
-0x2b,0x20,0x45,0x01,0x0b,0x30,0x43,0x00,0xa1,0xfe,0x80,0x14,0x23,0x48,0xaa,0x00,
-0xde,0x54,0x00,0x08,0x21,0x48,0x00,0x00,0xff,0xff,0x43,0x25,0x42,0x18,0x03,0x00,
-0x40,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x40,0x55,0x00,0x08,0x01,0x00,0x4a,0x24,
-0x25,0xb0,0x02,0x3c,0x9c,0x0c,0x43,0x34,0x88,0x0c,0x42,0x34,0x00,0x00,0x44,0xac,
-0x00,0x00,0x60,0xac,0x95,0x54,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x40,0x62,0x8c,
-0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x3f,0x00,0x42,0x30,0x23,0x18,0x4a,0x00,
-0x2b,0x10,0x42,0x01,0x4e,0x55,0x00,0x08,0x0b,0x20,0x62,0x00,0xff,0xff,0x05,0x36,
-0x60,0x00,0x06,0x24,0xba,0x44,0x00,0x0c,0x24,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,
-0xe8,0x03,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
-0x00,0x60,0x81,0x40,0x24,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0x05,0x36,
-0x1f,0x00,0x52,0x30,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xb4,0x54,0x00,0x08,0x68,0x15,0x90,0x26,
-0x00,0xff,0x84,0x30,0x02,0x22,0x04,0x00,0x08,0x00,0x80,0x10,0x02,0x80,0x02,0x3c,
-0xff,0x00,0x02,0x24,0x04,0x00,0x82,0x10,0xcc,0xff,0x03,0x24,0x02,0x80,0x02,0x3c,
-0x08,0x00,0xe0,0x03,0x4e,0x58,0x43,0xa0,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03,
-0x4e,0x58,0x44,0xa0,0x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x10,0x04,0x00,
-0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,0x02,0x80,0x03,0x3c,
-0x80,0x10,0x02,0x00,0x68,0x15,0x63,0x24,0x20,0x00,0x84,0x2c,0x09,0x00,0x80,0x10,
-0x21,0x10,0x43,0x00,0x68,0x51,0x43,0x8c,0x25,0xb0,0x02,0x3c,0xc4,0x02,0x42,0x34,
-0x02,0x19,0x03,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x43,0xac,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x44,0x79,0x43,0x8c,0x25,0xb0,0x02,0x3c,
-0xc4,0x02,0x42,0x34,0x02,0x19,0x03,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x43,0xac,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0x85,0x30,0xd2,0xff,0xa3,0x24,
-0xfe,0xff,0xa2,0x24,0xda,0xff,0xa4,0x24,0x04,0x00,0x63,0x2c,0x08,0x00,0x84,0x2c,
-0x06,0x00,0x60,0x14,0xff,0x00,0x42,0x30,0xf0,0xff,0xa2,0x24,0xfc,0xff,0xa3,0x24,
-0x16,0x00,0x46,0x2c,0x03,0x00,0x80,0x10,0xff,0x00,0x62,0x30,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0xfa,0xff,0xa3,0x24,0xfc,0xff,0xc0,0x10,0x21,0x10,0xa0,0x00,
-0x08,0x00,0xe0,0x03,0xff,0x00,0x62,0x30,0x25,0xb0,0x04,0x3c,0x03,0x0d,0x85,0x34,
-0x00,0x00,0xa3,0x90,0x2d,0x0a,0x84,0x34,0xff,0x00,0x63,0x30,0x08,0x00,0x63,0x34,
-0x00,0x00,0xa3,0xa0,0x00,0x00,0xa2,0x90,0x00,0x00,0x00,0x00,0xf7,0x00,0x42,0x30,
-0x00,0x00,0xa2,0xa0,0x00,0x00,0x83,0x90,0x00,0x00,0x00,0x00,0x3f,0x00,0x63,0x30,
-0x00,0x00,0x83,0xa0,0x00,0x00,0x82,0x90,0x80,0xff,0x03,0x24,0x25,0x10,0x43,0x00,
-0x00,0x00,0x82,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,
-0xff,0x00,0x03,0x3c,0x82,0x01,0x49,0x34,0x81,0x01,0x48,0x34,0x24,0x10,0x83,0x00,
-0x02,0x3c,0x02,0x00,0x00,0xff,0x63,0x34,0x02,0x80,0x02,0x3c,0x68,0x15,0x45,0x24,
-0x02,0x32,0x04,0x00,0x01,0x00,0x02,0x24,0x24,0x20,0x83,0x00,0xc2,0x4c,0xa2,0xa0,
-0xb0,0x4c,0xa0,0xac,0xb4,0x4c,0xa0,0xac,0xb8,0x4c,0xa0,0xac,0x06,0x00,0x80,0x14,
-0xbc,0x4c,0xa0,0xac,0x00,0x00,0x02,0x91,0x00,0x00,0x23,0x91,0xc0,0x4c,0xa2,0xa0,
-0x08,0x00,0xe0,0x03,0xc1,0x4c,0xa3,0xa0,0xc1,0x4c,0xa7,0xa0,0x08,0x00,0xe0,0x03,
-0xc0,0x4c,0xa6,0xa0,0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0xc1,0x4c,0x66,0x90,
-0xc0,0x4c,0x65,0x90,0x25,0xb0,0x02,0x3c,0x82,0x01,0x44,0x34,0x81,0x01,0x42,0x34,
-0x00,0x00,0x45,0xa0,0x00,0x00,0x86,0xa0,0x08,0x00,0xe0,0x03,0xc2,0x4c,0x60,0xa0,
-0x02,0x80,0x08,0x3c,0x68,0x15,0x04,0x25,0xc2,0x4c,0x82,0x90,0x00,0x00,0x00,0x00,
-0x15,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xb4,0x4c,0x82,0x8c,0xb0,0x4c,0x85,0x8c,
-0x25,0xb0,0x03,0x3c,0x40,0x11,0x02,0x00,0x2b,0x10,0xa2,0x00,0x82,0x01,0x67,0x34,
-0x0f,0x00,0x40,0x10,0x81,0x01,0x66,0x34,0xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90,
-0xf0,0x00,0x63,0x30,0x1f,0x00,0x42,0x30,0x00,0x00,0xc2,0xa0,0x00,0x00,0xe3,0xa0,
-0x68,0x15,0x02,0x25,0x01,0x00,0x03,0x24,0xbc,0x4c,0x40,0xac,0xb0,0x4c,0x40,0xac,
-0xb4,0x4c,0x40,0xac,0xb8,0x4c,0x40,0xac,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
-0xb8,0x4c,0x82,0x8c,0x25,0xb0,0x03,0x3c,0x82,0x01,0x69,0x34,0x40,0x11,0x02,0x00,
-0x2b,0x10,0xa2,0x00,0x0e,0x00,0x40,0x14,0x81,0x01,0x66,0x34,0xbc,0x4c,0x82,0x8c,
-0x00,0x00,0x00,0x00,0x40,0x11,0x02,0x00,0x2b,0x10,0xa2,0x00,0x08,0x00,0x40,0x14,
-0x00,0x00,0x00,0x00,0xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90,0x00,0x00,0x00,0x00,
-0x00,0x00,0xc2,0xa0,0x00,0x00,0x23,0xa1,0xf7,0x56,0x00,0x08,0x68,0x15,0x02,0x25,
-0xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90,0xf0,0x00,0x63,0x30,0x7f,0x00,0x42,0x30,
-0x00,0x00,0xc2,0xa0,0x00,0x00,0x23,0xa1,0xf7,0x56,0x00,0x08,0x68,0x15,0x02,0x25,
-0x02,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03,0x3d,0x58,0x43,0xa0,
-0xcc,0xff,0x03,0x24,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03,0x3d,0x58,0x43,0xa0,
-0x25,0xb0,0x03,0x3c,0x33,0x02,0x65,0x34,0x00,0x11,0x04,0x00,0x00,0x00,0xa2,0xa0,
-0x30,0x02,0x63,0x34,0x00,0x00,0x65,0x8c,0x0f,0x00,0x02,0x3c,0xff,0xff,0x42,0x34,
-0x24,0x28,0xa2,0x00,0x01,0x00,0x03,0x24,0x04,0x18,0x83,0x00,0x02,0x00,0xa0,0x10,
-0x21,0x10,0x00,0x00,0xff,0xff,0x62,0x30,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x25,0xb0,0x11,0x3c,0x18,0x00,0xb2,0xaf,
-0x4c,0x00,0x22,0x36,0x1c,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x44,0x90,
-0x02,0x80,0x03,0x3c,0x02,0x00,0x02,0x24,0xff,0x00,0x84,0x30,0x07,0x00,0x82,0x10,
-0x68,0x15,0x72,0x24,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
-0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xe6,0x63,0x43,0x96,
-0x01,0x00,0x02,0x24,0xf7,0xff,0x62,0x14,0x21,0x20,0x00,0x00,0x22,0x57,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x24,0x22,0x57,0x00,0x0c,0x21,0x80,0x40,0x00,
-0x25,0x80,0x02,0x02,0x33,0x02,0x23,0x36,0x08,0x00,0x02,0x24,0xff,0xff,0x10,0x32,
-0x40,0x00,0x25,0x36,0x00,0x00,0x62,0xa0,0xea,0xff,0x00,0x16,0x00,0x00,0x00,0x00,
-0x00,0x00,0xa2,0x94,0xe4,0x63,0x43,0x96,0xff,0xdf,0x42,0x30,0x00,0x20,0x44,0x34,
-0x01,0x00,0x63,0x24,0xe4,0x63,0x43,0xa6,0x00,0x00,0xa2,0xa4,0x00,0x00,0xa4,0xa4,
-0x3f,0x57,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
-0x18,0x03,0x42,0x34,0x80,0x5d,0x63,0x24,0x00,0x00,0x43,0xac,0x63,0x00,0x02,0x24,
-0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0x02,0x80,0x02,0x3c,
-0x88,0x7d,0x45,0x94,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x8b,0x7d,0x66,0x90,
-0x98,0x7d,0x47,0x90,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xa3,0x7d,0x69,0x90,
-0xa5,0x7d,0x4a,0x90,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xa8,0x7d,0x6b,0x90,
-0xaa,0x7d,0x4c,0x90,0x07,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0x25,0xb0,0x04,0x3c,
-0x95,0x7d,0x43,0xa0,0xb0,0x03,0x84,0x34,0x02,0x80,0x02,0x3c,0x02,0x80,0x18,0x3c,
-0x8a,0x7d,0x08,0x93,0x00,0x00,0x85,0xac,0x96,0x7d,0x40,0xa0,0x02,0x80,0x02,0x3c,
-0x00,0x00,0x86,0xac,0x02,0x80,0x0f,0x3c,0x97,0x7d,0x40,0xa0,0x02,0x80,0x02,0x3c,
-0x00,0x00,0x87,0xac,0x68,0x15,0xee,0x25,0xb8,0x7d,0x40,0xa0,0xfd,0xff,0x02,0x24,
-0xd5,0x4a,0xc2,0xa1,0x01,0x00,0x03,0x24,0x00,0x78,0x02,0x24,0xd4,0x4a,0xc3,0xa1,
-0xd8,0x4a,0xc2,0xa5,0xff,0x07,0x03,0x24,0x0f,0x00,0x0d,0x31,0x02,0x00,0x02,0x24,
-0xda,0x4a,0xc3,0xa5,0x00,0x00,0x88,0xac,0x00,0x00,0x89,0xac,0x00,0x00,0x8a,0xac,
-0x00,0x00,0x8b,0xac,0x00,0x00,0x8c,0xac,0x17,0x00,0xa2,0x11,0x02,0x80,0x02,0x3c,
-0x8a,0x7d,0x02,0x93,0x01,0x00,0x03,0x24,0x0f,0x00,0x42,0x30,0x05,0x00,0x43,0x10,
-0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0xca,0x7d,0x40,0xa4,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x3c,0x68,0x15,0xe4,0x25,0x02,0xbc,0x42,0x34,
-0x68,0x4b,0x82,0xac,0x15,0x15,0x03,0x3c,0x02,0x02,0x02,0x3c,0x07,0x07,0x63,0x34,
-0x64,0x4b,0x82,0xac,0x02,0x80,0x02,0x3c,0x60,0x4b,0x83,0xac,0xca,0x7d,0x40,0xa4,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x8f,0x7d,0x44,0x90,0x06,0x00,0x03,0x24,
-0x15,0x00,0x83,0x10,0x0b,0x00,0x02,0x24,0x0a,0x00,0x82,0x10,0x00,0xe0,0x02,0x3c,
-0x68,0x15,0xe4,0x25,0x00,0xb2,0x42,0x34,0x00,0x1c,0x03,0x3c,0x68,0x4b,0x82,0xac,
-0x00,0x1c,0x63,0x34,0x00,0x04,0x02,0x24,0x60,0x4b,0x83,0xac,0x9a,0x57,0x00,0x08,
-0x64,0x4b,0x82,0xac,0x00,0x80,0x02,0x3c,0x00,0xbc,0x42,0x34,0x15,0x15,0x03,0x3c,
-0x68,0x4b,0xc2,0xad,0x07,0x07,0x63,0x34,0x03,0x03,0x02,0x3c,0x60,0x4b,0xc3,0xad,
-0x9a,0x57,0x00,0x08,0x64,0x4b,0xc2,0xad,0x00,0xc0,0x02,0x3c,0x00,0xb2,0x42,0x34,
-0x1c,0x1c,0x03,0x3c,0x68,0x4b,0xc2,0xad,0x07,0x07,0x63,0x34,0x00,0x04,0x02,0x24,
-0x60,0x4b,0xc3,0xad,0x9a,0x57,0x00,0x08,0x64,0x4b,0xc2,0xad,0x25,0xb0,0x02,0x3c,
-0x4d,0x00,0x44,0x34,0xff,0x00,0x03,0x3c,0xec,0x02,0x42,0x34,0x00,0x00,0x43,0xac,
-0x00,0x00,0x80,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,
-0x25,0xb0,0x02,0x3c,0x64,0x5f,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x7f,0x00,0x02,0x3c,0xfd,0xbf,0x45,0x34,
-0x80,0x04,0x03,0x3c,0x25,0x28,0xa3,0x00,0x00,0x08,0x04,0x3c,0x02,0x80,0x02,0x3c,
-0x68,0x15,0x42,0x24,0x25,0x28,0xa4,0x00,0x41,0xb0,0x03,0x3c,0x00,0x00,0x65,0xac,
-0x04,0x4b,0x45,0xac,0xfc,0x4a,0x45,0xac,0x08,0x00,0x63,0x34,0x86,0x00,0x05,0x24,
-0x00,0x00,0x65,0xa4,0x08,0x4b,0x45,0xa4,0x00,0x4b,0x40,0xac,0x0a,0x4b,0x40,0xa4,
-0x0c,0x4b,0x45,0xa4,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
-0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xf8,0x57,0x00,0x08,0x00,0x00,0x00,0x00,
-0x42,0xb0,0x02,0x3c,0xa0,0xff,0x03,0x24,0x01,0x00,0x42,0x34,0xe8,0xff,0xbd,0x27,
-0x21,0x20,0x00,0x00,0x01,0x00,0x05,0x24,0x00,0x01,0x06,0x24,0x00,0x00,0x43,0xa0,
-0x10,0x00,0xbf,0xaf,0xc4,0x0c,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f,
-0x03,0x00,0x04,0x24,0x01,0x00,0x05,0x24,0x40,0x1f,0x06,0x24,0xc4,0x0c,0x00,0x08,
-0x18,0x00,0xbd,0x27,0xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x14,0x00,0xbf,0xaf,
-0x21,0x5b,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,
-0x48,0x01,0x03,0x24,0xe0,0x63,0x43,0xac,0xdc,0x63,0x43,0xac,0x21,0x80,0x40,0x00,
-0x1f,0x00,0x03,0x24,0xff,0xff,0x63,0x24,0xc4,0x4c,0x40,0xa4,0xc6,0x4c,0x40,0xa4,
-0xc8,0x4c,0x40,0xa4,0xca,0x4c,0x40,0xa4,0xcc,0x4c,0x40,0xa4,0xce,0x4c,0x40,0xa4,
-0xd0,0x4c,0x40,0xa4,0xd2,0x4c,0x40,0xa4,0xd4,0x4c,0x40,0xa4,0xf5,0xff,0x61,0x04,
-0x24,0x00,0x42,0x24,0x25,0xb0,0x02,0x3c,0x10,0x00,0x03,0x24,0xb0,0x03,0x42,0x34,
-0x02,0x80,0x04,0x3c,0x8c,0x58,0x84,0x24,0x00,0x00,0x43,0xac,0x21,0x28,0x00,0x00,
-0x97,0x45,0x00,0x0c,0x04,0x00,0x06,0x24,0xef,0x5b,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x71,0x5c,0x00,0x0c,0x8c,0x65,0x00,0xae,0xa7,0x5d,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x4b,0x5e,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x03,0x3c,0x8e,0x7d,0x64,0x90,
-0x92,0x00,0x02,0x24,0x03,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0xf7,0x5d,0x00,0x0c,
-0x00,0x00,0x00,0x00,0xdd,0x5d,0x00,0x0c,0x00,0x00,0x00,0x00,0x8b,0x5c,0x00,0x0c,
-0x00,0x00,0x00,0x00,0xe4,0x63,0x00,0xa6,0x67,0x5e,0x00,0x0c,0xe6,0x63,0x00,0xa6,
-0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x02,0x80,0x04,0x3c,0x02,0x80,0x05,0x3c,
-0xf8,0x7a,0x82,0x24,0x00,0x7b,0xa3,0x24,0x18,0x00,0xbd,0x27,0x04,0x00,0x42,0xac,
-0xf8,0x7a,0x82,0xac,0x00,0x7b,0xa3,0xac,0x08,0x00,0xe0,0x03,0x04,0x00,0x63,0xac,
-0xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x01,0x80,0x02,0x3c,0x25,0xb0,0x10,0x3c,
-0x18,0x03,0x03,0x36,0x38,0x61,0x42,0x24,0x00,0x00,0x62,0xac,0x14,0x00,0xbf,0xaf,
-0x60,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xd5,0x58,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x01,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0xfd,0x5a,0x00,0x0c,0xdb,0x60,0x43,0xa0,
-0xd1,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x32,0x41,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x0b,0x58,0x00,0x0c,0x00,0x00,0x00,0x00,0x44,0x00,0x03,0x36,0x00,0x00,0x62,0x94,
-0x00,0x00,0x00,0x00,0x40,0x00,0x42,0x34,0x00,0x00,0x62,0xa4,0xd9,0x57,0x00,0x0c,
-0x00,0x00,0x00,0x00,0xfa,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xc9,0x5a,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x8e,0x5a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x3c,
-0xb4,0x24,0x84,0x24,0xe6,0x5a,0x00,0x0c,0x01,0x00,0x05,0x24,0x01,0x80,0x04,0x3c,
-0x08,0x1e,0x84,0x24,0xe6,0x5a,0x00,0x0c,0x02,0x00,0x05,0x24,0x81,0x4e,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x3c,0x54,0x34,0x84,0x24,0xe6,0x5a,0x00,0x0c,
-0x03,0x00,0x05,0x24,0x02,0x80,0x02,0x3c,0x98,0x7d,0x43,0x90,0x43,0x00,0x04,0x36,
-0x29,0x00,0x60,0x10,0xd8,0x00,0x10,0x36,0x07,0x00,0x02,0x24,0x2b,0x00,0x62,0x10,
-0x25,0xb0,0x04,0x3c,0x10,0x02,0x86,0x34,0x43,0x00,0x85,0x34,0x03,0x00,0x02,0x24,
-0x10,0x00,0x03,0x24,0x00,0x00,0xa2,0xa0,0xd8,0x00,0x84,0x34,0x00,0x00,0xc3,0xa0,
-0x00,0x00,0x82,0x90,0x80,0xff,0x03,0x24,0x42,0xb0,0x05,0x3c,0x25,0x10,0x43,0x00,
-0x00,0x00,0x82,0xa0,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x82,0x94,
-0x00,0x00,0x00,0x00,0xc0,0x00,0x42,0x34,0x00,0x00,0x82,0xa4,0x00,0x00,0xa3,0x90,
-0x00,0x00,0x00,0x00,0x01,0x00,0x63,0x34,0x00,0x00,0xa3,0xa0,0xe0,0x57,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,0x08,0x00,0x84,0x24,0x21,0x28,0x00,0x00,
-0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0xf8,0x57,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,
-0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x00,0x00,0x80,0xa0,0x00,0x00,0x03,0x92,
-0x80,0xff,0x02,0x24,0x25,0x18,0x62,0x00,0x00,0x00,0x03,0xa2,0x25,0xb0,0x04,0x3c,
-0x44,0x00,0x84,0x34,0x00,0x00,0x82,0x94,0x42,0xb0,0x05,0x3c,0xc0,0x00,0x42,0x34,
-0x00,0x00,0x82,0xa4,0x00,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x63,0x34,
-0x00,0x00,0xa3,0xa0,0xe0,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,
-0x08,0x00,0x84,0x24,0x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,
-0x21,0x38,0x00,0x00,0xf8,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x14,0x00,0xbf,0x8f,
-0x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,
-0x21,0x20,0x00,0x00,0x20,0xb0,0x06,0x3c,0xff,0xff,0x05,0x34,0x21,0x18,0x86,0x00,
-0x04,0x00,0x84,0x24,0x2a,0x10,0xa4,0x00,0x00,0x00,0x60,0xac,0xfb,0xff,0x40,0x10,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xb8,0xff,0xbd,0x27,
-0x25,0xb0,0x04,0x3c,0x44,0x00,0xbf,0xaf,0x40,0x00,0xbe,0xaf,0x3c,0x00,0xb7,0xaf,
-0x38,0x00,0xb6,0xaf,0x34,0x00,0xb5,0xaf,0x30,0x00,0xb4,0xaf,0x2c,0x00,0xb3,0xaf,
-0x28,0x00,0xb2,0xaf,0x24,0x00,0xb1,0xaf,0x20,0x00,0xb0,0xaf,0x0a,0x00,0x83,0x34,
-0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x20,0x00,0x42,0x30,0x0c,0x00,0x40,0x10,
-0x4c,0x87,0x02,0x3c,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x10,0x00,0x42,0x30,
-0x66,0x01,0x40,0x10,0x4c,0x87,0x02,0x3c,0x54,0x00,0x83,0x34,0x50,0x00,0x82,0x34,
-0x00,0x00,0x45,0xac,0x00,0x00,0x65,0xa4,0xf9,0x58,0x00,0x08,0x02,0x80,0x03,0x3c,
-0x54,0x00,0x85,0x34,0x00,0xe0,0x42,0x34,0x50,0x00,0x84,0x34,0x12,0x01,0x03,0x24,
-0x00,0x00,0x82,0xac,0x00,0x00,0xa3,0xac,0x02,0x80,0x03,0x3c,0x68,0x15,0x62,0x24,
-0xd5,0x4a,0x43,0x90,0xda,0x4a,0x45,0x94,0x25,0xb0,0x1e,0x3c,0x1c,0x00,0xa3,0xa3,
-0x60,0x4b,0x43,0x8c,0x58,0x00,0xc6,0x37,0xff,0xff,0x04,0x24,0x10,0x00,0xa3,0xaf,
-0x64,0x4b,0x43,0x8c,0x5c,0x00,0xc7,0x37,0x60,0x00,0xc8,0x37,0x14,0x00,0xa3,0xaf,
-0x68,0x4b,0x42,0x8c,0x64,0x00,0xc9,0x37,0x8a,0x00,0xca,0x37,0x18,0x00,0xa2,0xaf,
-0x24,0x10,0x02,0x3c,0x21,0x28,0xa2,0x00,0x4c,0x81,0x02,0x3c,0x00,0xe0,0x42,0x34,
-0x00,0x00,0xc2,0xac,0x96,0x01,0x03,0x24,0x28,0x28,0x02,0x24,0x00,0x00,0xe3,0xac,
-0x89,0x00,0xcb,0x37,0x00,0x00,0x04,0xad,0x8c,0x00,0xcc,0x37,0x00,0x00,0x24,0xad,
-0x09,0x00,0x03,0x24,0x00,0x00,0x42,0xa5,0x10,0x10,0x02,0x24,0x00,0x00,0x63,0xa1,
-0x8e,0x00,0xcd,0x37,0x00,0x00,0x82,0xa5,0x0a,0x0a,0x03,0x24,0x13,0x00,0x02,0x24,
-0x90,0x00,0xce,0x37,0x00,0x00,0xa3,0xa5,0x00,0x00,0xc2,0xa1,0x25,0xb0,0x02,0x3c,
-0x40,0x00,0x03,0x24,0x91,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0x25,0xb0,0x03,0x3c,
-0x3a,0x01,0x02,0x24,0x92,0x00,0x63,0x34,0x00,0x00,0x62,0xa4,0xb5,0x00,0xd1,0x37,
-0x21,0x00,0x03,0x24,0x00,0x00,0x23,0xa2,0x10,0x00,0xa2,0x8f,0xa0,0x00,0xd2,0x37,
-0xa4,0x00,0xd3,0x37,0x00,0x00,0x42,0xae,0x14,0x00,0xa3,0x8f,0xa8,0x00,0xd4,0x37,
-0xac,0x00,0xd5,0x37,0x00,0x00,0x63,0xae,0x18,0x00,0xa2,0x8f,0x25,0xb0,0x03,0x3c,
-0xb0,0x00,0x63,0x34,0x00,0x00,0x82,0xae,0x21,0x10,0x02,0x3c,0xff,0x77,0x42,0x34,
-0x00,0x00,0xa2,0xae,0x25,0xb0,0x02,0x3c,0xd8,0x00,0x42,0x34,0x00,0x00,0x65,0xac,
-0x00,0x00,0x40,0xa0,0x1c,0x00,0xa2,0x93,0x25,0xb0,0x03,0x3c,0xb4,0x00,0x63,0x34,
-0x00,0x00,0x62,0xa0,0x25,0xb0,0x03,0x3c,0x04,0x00,0x02,0x24,0xb6,0x00,0x63,0x34,
-0x00,0x00,0x62,0xa0,0x25,0xb0,0x03,0x3c,0x0f,0x00,0x02,0x24,0xba,0x00,0x63,0x34,
-0xb9,0x00,0xdf,0x37,0x00,0x00,0xe4,0xa3,0x00,0x00,0x62,0xa4,0x25,0xb0,0x02,0x3c,
-0x1a,0x01,0x42,0x34,0x16,0x01,0xd0,0x37,0x18,0x01,0xcf,0x37,0x00,0x00,0x00,0xa6,
-0x25,0xb0,0x03,0x3c,0x00,0x00,0xe0,0xa5,0x00,0x00,0x40,0xa4,0xff,0xff,0x02,0x3c,
-0xff,0x0f,0x42,0x34,0xdc,0x00,0x63,0x34,0x00,0x00,0x62,0xac,0x2f,0x00,0x03,0x3c,
-0x25,0xb0,0x02,0x3c,0x32,0x32,0x63,0x34,0xd0,0x01,0x42,0x34,0x00,0x00,0x43,0xac,
-0x5e,0x00,0x02,0x3c,0x25,0xb0,0x03,0x3c,0x32,0x43,0x42,0x34,0xd4,0x01,0x63,0x34,
-0x00,0x00,0x62,0xac,0x08,0x00,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x30,0xa5,0x63,0x34,
-0xd8,0x01,0x42,0x34,0x00,0x00,0x43,0xac,0xdc,0x01,0xc4,0x37,0x02,0x80,0x03,0x3c,
-0x49,0xa5,0x02,0x34,0x8e,0x7d,0x6d,0x90,0x00,0x00,0x82,0xac,0xc2,0x00,0x02,0x3c,
-0x1a,0x06,0x03,0x24,0x51,0x10,0x42,0x34,0xe0,0x01,0xc5,0x37,0xf4,0x01,0xc6,0x37,
-0xf8,0x01,0xc7,0x37,0x07,0x07,0x04,0x24,0x00,0x00,0xa3,0xa4,0x00,0x02,0xc8,0x37,
-0x00,0x00,0xc4,0xa4,0x26,0x00,0x03,0x24,0x00,0x00,0xe2,0xac,0x03,0x02,0xc9,0x37,
-0x04,0x00,0x02,0x24,0x00,0x00,0x03,0xa5,0x36,0x02,0xca,0x37,0x00,0x00,0x22,0xa1,
-0xc0,0x01,0x03,0x24,0x0c,0x00,0x02,0x24,0x34,0x02,0xcb,0x37,0x00,0x00,0x42,0xa1,
-0x37,0x02,0xcc,0x37,0x00,0x00,0x63,0xa5,0x03,0x00,0x02,0x24,0x22,0x00,0x03,0x24,
-0x00,0x00,0x82,0xa1,0xd6,0x00,0xa3,0x11,0x1b,0x1b,0x02,0x3c,0x13,0x13,0x02,0x3c,
-0x13,0x13,0x42,0x34,0x60,0x01,0xc3,0x37,0x64,0x01,0xc4,0x37,0x68,0x01,0xc5,0x37,
-0x7c,0x01,0xca,0x37,0x6c,0x01,0xc6,0x37,0x70,0x01,0xc7,0x37,0x74,0x01,0xc8,0x37,
-0x78,0x01,0xc9,0x37,0x00,0x00,0x62,0xac,0x00,0x00,0x82,0xac,0x02,0x80,0x03,0x3c,
-0x00,0x00,0xa2,0xac,0x00,0x00,0xc2,0xac,0x00,0x00,0xe2,0xac,0x00,0x00,0x02,0xad,
-0x00,0x00,0x22,0xad,0x00,0x00,0x42,0xad,0x8e,0x7d,0x65,0x90,0x25,0xb0,0x0c,0x3c,
-0x01,0x70,0x03,0x3c,0x80,0x01,0x82,0x35,0x08,0x5f,0x63,0x34,0x22,0x00,0x04,0x24,
-0x00,0x00,0x43,0xac,0xb5,0x00,0xa4,0x10,0x0f,0x1f,0x02,0x3c,0x92,0x00,0x02,0x24,
-0xb2,0x00,0xa2,0x10,0x0f,0x1f,0x02,0x3c,0x0f,0x10,0x02,0x3c,0x00,0xf0,0x51,0x34,
-0xf7,0x01,0x92,0x35,0x15,0xf0,0x4d,0x34,0x77,0x00,0x0e,0x24,0x84,0x01,0x87,0x35,
-0x88,0x01,0x88,0x35,0x10,0xf0,0x44,0x34,0x8c,0x01,0x85,0x35,0x05,0xf0,0x42,0x34,
-0x00,0x00,0xed,0xac,0x90,0x01,0x83,0x35,0x00,0x00,0x04,0xad,0x94,0x01,0x86,0x35,
-0x00,0x00,0xa2,0xac,0xf5,0x0f,0x02,0x24,0x00,0x00,0x71,0xac,0x25,0xb0,0x05,0x3c,
-0x00,0x00,0xc2,0xac,0x98,0x01,0x89,0x35,0x9c,0x01,0x8a,0x35,0xf0,0x0f,0x03,0x24,
-0x0d,0x00,0x02,0x24,0x00,0x00,0x23,0xad,0xa0,0x01,0x8b,0x35,0x00,0x00,0x42,0xad,
-0xa7,0x01,0xb7,0x34,0xf6,0x01,0x8c,0x35,0xff,0xff,0x02,0x24,0x00,0x00,0x6d,0xad,
-0x00,0x00,0x8e,0xa1,0x00,0x00,0x4e,0xa2,0x00,0x00,0xe2,0xa2,0x25,0xb0,0x02,0x3c,
-0xa8,0x01,0xb6,0x34,0xff,0xff,0x09,0x24,0xac,0x01,0x42,0x34,0x00,0x00,0xc9,0xae,
-0x03,0x04,0x04,0x3c,0x00,0x00,0x49,0xac,0x07,0x08,0x03,0x3c,0x25,0xb0,0x02,0x3c,
-0x01,0x02,0x84,0x34,0x05,0x06,0x63,0x34,0xb4,0x01,0xb1,0x34,0xb8,0x01,0xb2,0x34,
-0xbc,0x01,0xb3,0x34,0xb0,0x01,0x42,0x34,0x00,0x00,0x44,0xac,0x00,0x00,0x23,0xae,
-0x25,0xb0,0x02,0x3c,0x00,0x00,0x44,0xae,0x00,0x00,0x63,0xae,0x25,0xb0,0x03,0x3c,
-0x0c,0x00,0x06,0x24,0xc0,0x01,0xb4,0x34,0xc1,0x01,0xb5,0x34,0x0d,0x00,0x08,0x24,
-0xc2,0x01,0x63,0x34,0xc3,0x01,0x42,0x34,0x00,0x00,0x86,0xa2,0xc4,0x01,0xab,0x34,
-0x00,0x00,0xa6,0xa2,0xc5,0x01,0xac,0x34,0x00,0x00,0x66,0xa0,0x0e,0x00,0x07,0x24,
-0x00,0x00,0x48,0xa0,0xc6,0x01,0xaa,0x34,0xc7,0x01,0xad,0x34,0x0f,0x00,0x02,0x24,
-0x00,0x00,0x68,0xa1,0x00,0x00,0x87,0xa1,0x00,0x00,0x47,0xa1,0x00,0x00,0xa2,0xa1,
-0x57,0x01,0x02,0x3c,0x48,0x00,0xbf,0x34,0x46,0x00,0xae,0x34,0x0e,0xe2,0x42,0x34,
-0x00,0x00,0xc0,0xa5,0x4c,0x00,0xbe,0x34,0x00,0x00,0xe2,0xaf,0x4d,0x00,0xb9,0x34,
-0x80,0xff,0x02,0x24,0x00,0x00,0xc0,0xa3,0x00,0x00,0x22,0xa3,0x25,0xb0,0x02,0x3c,
-0xbc,0x00,0x03,0x24,0x40,0x00,0x42,0x34,0x00,0x00,0x43,0xa4,0x25,0xb0,0x03,0x3c,
-0x64,0x03,0xb8,0x34,0xfc,0x37,0x02,0x24,0x40,0x00,0x63,0x34,0x00,0x00,0x00,0xa3,
-0xd8,0x00,0xa7,0x34,0x00,0x00,0x62,0xa4,0x00,0x00,0xe3,0x90,0x2a,0xb0,0x04,0x3c,
-0x80,0xff,0x02,0x24,0x26,0xb0,0x06,0x3c,0x25,0x18,0x62,0x00,0x30,0x00,0x89,0x34,
-0x20,0x20,0x02,0x24,0x38,0x00,0x84,0x34,0x00,0x00,0xe3,0xa0,0x79,0x00,0xc8,0x34,
-0x00,0x00,0x82,0xa4,0x40,0x00,0x03,0x24,0x16,0x00,0x02,0x24,0x00,0x00,0x23,0xa1,
-0x94,0x00,0xaa,0x34,0x00,0x00,0x02,0xa1,0x98,0x00,0xab,0x34,0x64,0x00,0x03,0x24,
-0x22,0x00,0x02,0x24,0x00,0x00,0x43,0xa5,0x7c,0x00,0xd1,0x34,0x00,0x00,0x62,0xa5,
-0x04,0x00,0x12,0x24,0x9c,0x00,0xac,0x34,0x7a,0x00,0xc6,0x34,0x20,0x0c,0x02,0x24,
-0x0a,0x00,0x03,0x24,0x00,0x00,0xd2,0xa0,0x9a,0x00,0xad,0x34,0x00,0x00,0x22,0xa6,
-0x96,0x00,0xae,0x34,0x00,0x00,0x83,0xa1,0xff,0x03,0x02,0x24,0x02,0x00,0x03,0x24,
-0x00,0x00,0xa2,0xa5,0x00,0x00,0xc3,0xa5,0x25,0xb0,0x03,0x3c,0x20,0x00,0x02,0x24,
-0xb7,0x00,0x63,0x34,0x00,0x00,0x62,0xa0,0x25,0xb0,0x02,0x3c,0x09,0x00,0x03,0x24,
-0x89,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0x44,0x00,0xa5,0x34,0x00,0x00,0xa2,0x94,
-0x02,0x80,0x03,0x3c,0x68,0x15,0x66,0x24,0xff,0xfd,0x03,0x24,0x24,0x10,0x43,0x00,
-0x00,0x00,0xa2,0xa4,0x00,0x00,0xa3,0x94,0xd5,0x4a,0xc4,0x90,0x29,0xb0,0x02,0x3c,
-0x40,0x00,0x42,0x34,0x00,0x02,0x63,0x34,0x00,0x00,0xa3,0xa4,0x00,0x00,0x52,0xa0,
-0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x44,0x00,0xbf,0x8f,0x40,0x00,0xbe,0x8f,
-0x3c,0x00,0xb7,0x8f,0x38,0x00,0xb6,0x8f,0x34,0x00,0xb5,0x8f,0x30,0x00,0xb4,0x8f,
-0x2c,0x00,0xb3,0x8f,0x28,0x00,0xb2,0x8f,0x24,0x00,0xb1,0x8f,0x20,0x00,0xb0,0x8f,
-0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x48,0x00,0xbd,0x27,0x54,0x00,0x85,0x34,
-0x00,0xe0,0x42,0x34,0x50,0x00,0x84,0x34,0x12,0x01,0x03,0x24,0x00,0x00,0x82,0xac,
-0x00,0x00,0xa3,0xa4,0xf9,0x58,0x00,0x08,0x02,0x80,0x03,0x3c,0x00,0xf0,0x51,0x34,
-0xf7,0x01,0x92,0x35,0x15,0xf0,0x4d,0x34,0xad,0x59,0x00,0x08,0xff,0xff,0x0e,0x24,
-0x8b,0x59,0x00,0x08,0x1b,0x1b,0x42,0x34,0x25,0xb0,0x03,0x3c,0x25,0xb0,0x08,0x3c,
-0xfc,0x37,0x02,0x24,0x40,0x00,0x63,0x34,0x02,0x80,0x04,0x3c,0x00,0x00,0x62,0xa4,
-0x14,0x80,0x84,0x24,0xff,0x00,0x07,0x24,0xb0,0x03,0x06,0x35,0x00,0x00,0x83,0x94,
-0x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30,0x21,0x18,0x68,0x00,0x0a,0x00,0x47,0x10,
-0xff,0x00,0x65,0x30,0x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xac,
-0x00,0x00,0xc3,0xac,0x04,0x00,0x82,0x8c,0x08,0x00,0x84,0x24,0x00,0x00,0xc2,0xac,
-0xf2,0xff,0xa7,0x14,0x00,0x00,0x00,0x00,0x25,0xb0,0x08,0x3c,0x01,0x80,0x02,0x3c,
-0x0c,0x7a,0x44,0x24,0xff,0x00,0x07,0x24,0xb0,0x03,0x06,0x35,0x00,0x00,0x83,0x94,
-0x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30,0x21,0x18,0x68,0x00,0x0a,0x00,0x47,0x10,
-0xff,0x00,0x65,0x30,0x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xac,
-0x00,0x00,0xc3,0xac,0x04,0x00,0x82,0x8c,0x08,0x00,0x84,0x24,0x00,0x00,0xc2,0xac,
-0xf2,0xff,0xa7,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
-0x01,0x80,0x02,0x3c,0x02,0x80,0x05,0x3c,0x10,0x6b,0x42,0x24,0x02,0x80,0x03,0x3c,
-0xcc,0x7d,0xa2,0xac,0x00,0x80,0x02,0x3c,0x6c,0x7e,0x60,0xac,0xcc,0x7d,0xa4,0x24,
-0x02,0x80,0x03,0x3c,0xc8,0x06,0x42,0x24,0x70,0x7e,0x60,0xa4,0x08,0x00,0x82,0xac,
-0x02,0x80,0x03,0x3c,0x00,0x80,0x02,0x3c,0x72,0x7e,0x60,0xa4,0x02,0x80,0x06,0x3c,
-0x08,0x0a,0x42,0x24,0x00,0x80,0x03,0x3c,0x74,0x7e,0xc7,0x24,0x14,0x00,0x82,0xac,
-0x38,0x08,0x63,0x24,0x02,0x80,0x02,0x3c,0x74,0x7e,0xc0,0xac,0x10,0x00,0x83,0xac,
-0x04,0x00,0xe0,0xac,0x7c,0x7e,0x40,0xa0,0x00,0x80,0x02,0x3c,0x88,0x19,0x42,0x24,
-0x3c,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,0x00,0x80,0x02,0x3c,0x24,0x0c,0x63,0x24,
-0x78,0x0f,0x42,0x24,0x1c,0x00,0x83,0xac,0x20,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,
-0x00,0x80,0x02,0x3c,0xc8,0x12,0x63,0x24,0x28,0x16,0x42,0x24,0x24,0x00,0x83,0xac,
-0x28,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,0x01,0x80,0x02,0x3c,0x4c,0x1f,0x63,0x24,
-0xd0,0x04,0x42,0x24,0x2c,0x00,0x83,0xac,0x30,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,
-0x00,0x80,0x02,0x3c,0xe4,0x19,0x63,0x24,0x00,0x03,0x42,0x24,0x38,0x00,0x83,0xac,
-0x08,0x00,0xe0,0x03,0x4c,0x00,0x82,0xac,0x25,0xb0,0x02,0x3c,0x08,0x00,0x42,0x34,
-0x00,0x00,0x43,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x0e,0x3c,
-0x02,0x80,0x08,0x3c,0x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c,0xf8,0x03,0x4d,0x24,
-0x00,0x14,0x6c,0x24,0x01,0x00,0x07,0x24,0x00,0x00,0xcb,0x25,0xff,0xff,0x0a,0x24,
-0x00,0x04,0x09,0x25,0x80,0x1a,0x07,0x00,0x21,0x10,0x6b,0x00,0x00,0x00,0x42,0xac,
-0x90,0x00,0x4a,0xac,0x00,0x04,0x04,0x8d,0x01,0x00,0xe7,0x24,0x08,0x00,0x45,0x24,
-0x21,0x18,0x6d,0x00,0x05,0x00,0xe6,0x28,0x04,0x00,0x82,0xac,0x00,0x00,0x44,0xac,
-0x04,0x00,0x49,0xac,0x00,0x04,0x02,0xad,0x8c,0x00,0x40,0xac,0x6c,0x00,0xa3,0xac,
-0xf0,0xff,0xc0,0x14,0x68,0x00,0xac,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0xc9,0xad,
-0x05,0x00,0xa2,0x2c,0x13,0x00,0x40,0x10,0xff,0xff,0x07,0x24,0x02,0x80,0x02,0x3c,
-0x80,0x1a,0x05,0x00,0x00,0x00,0x42,0x24,0x0e,0x00,0xa0,0x10,0x21,0x30,0x62,0x00,
-0x90,0x00,0xc3,0x8c,0xff,0xff,0x02,0x24,0x0a,0x00,0x62,0x14,0x00,0x00,0x00,0x00,
-0x8c,0x00,0xc2,0x8c,0x00,0x00,0x00,0x00,0x06,0x00,0x40,0x14,0x00,0x00,0x00,0x00,
-0x01,0x00,0x02,0x24,0x88,0x00,0xc4,0xac,0x8c,0x00,0xc2,0xac,0x90,0x00,0xc5,0xac,
-0x21,0x38,0xa0,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0xe0,0x00,0x25,0xb0,0x04,0x3c,
-0x01,0x80,0x02,0x3c,0x18,0x03,0x85,0x34,0xf4,0x6b,0x42,0x24,0xe0,0xff,0xbd,0x27,
-0x00,0x00,0xa2,0xac,0x1b,0x00,0x86,0x34,0xdb,0xff,0x03,0x24,0x27,0x00,0x84,0x34,
-0x07,0x00,0x02,0x24,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x83,0xa0,
-0x18,0x00,0xbf,0xaf,0x00,0x00,0xc2,0xa0,0x01,0x00,0x11,0x24,0x21,0x80,0x00,0x00,
-0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x02,0x01,0x00,0x02,0x26,0xff,0x00,0x50,0x30,
-0x2b,0x18,0x30,0x02,0xfa,0xff,0x60,0x10,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c,
-0x21,0x20,0x00,0x00,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
-0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,
-0x68,0x15,0x42,0x24,0x40,0x10,0x03,0x3c,0xff,0xff,0x44,0x30,0x25,0xc0,0x83,0x00,
-0x94,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0xa0,0x64,0x58,0xac,0x40,0x00,0x18,0x27,
-0xac,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0xb8,0x64,0x58,0xac,0x40,0x00,0x18,0x27,
-0xe0,0xff,0xbd,0x27,0xc4,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0x1c,0x00,0xb7,0xaf,
-0x18,0x00,0xb6,0xaf,0x14,0x00,0xb5,0xaf,0x10,0x00,0xb4,0xaf,0x0c,0x00,0xb3,0xaf,
-0x08,0x00,0xb2,0xaf,0x04,0x00,0xb1,0xaf,0x00,0x00,0xb0,0xaf,0xd0,0x64,0x58,0xac,
-0xa0,0x64,0x45,0x8c,0xac,0x64,0x46,0x8c,0xb8,0x64,0x47,0x8c,0xc4,0x64,0x48,0x8c,
-0xd0,0x64,0x49,0x8c,0x40,0x00,0x18,0x27,0xdc,0x64,0x58,0xac,0x21,0x50,0x00,0x03,
-0x25,0x20,0x83,0x00,0x40,0x00,0x18,0x27,0x20,0x10,0x03,0x3c,0x90,0x64,0x44,0xac,
-0x9c,0x64,0x45,0xac,0xa8,0x64,0x46,0xac,0xb4,0x64,0x47,0xac,0xc0,0x64,0x48,0xac,
-0xcc,0x64,0x49,0xac,0x25,0xb0,0x06,0x3c,0x28,0x64,0x43,0xac,0x24,0x64,0x43,0xac,
-0x34,0x64,0x43,0xac,0x30,0x64,0x43,0xac,0x40,0x64,0x43,0xac,0x3c,0x64,0x43,0xac,
-0x4c,0x64,0x43,0xac,0x48,0x64,0x43,0xac,0xe8,0x64,0x58,0xac,0x00,0x02,0x18,0x27,
-0xd8,0x64,0x4a,0xac,0x00,0x65,0x58,0xac,0x58,0x64,0x43,0xac,0x54,0x64,0x43,0xac,
-0x64,0x64,0x43,0xac,0x60,0x64,0x43,0xac,0x70,0x64,0x43,0xac,0x6c,0x64,0x43,0xac,
-0xac,0x00,0xc4,0x34,0xb0,0x00,0xc5,0x34,0x00,0x00,0x92,0x8c,0xe8,0x64,0x50,0x8c,
-0x00,0x00,0xb3,0x8c,0x21,0x10,0x04,0x3c,0x23,0x10,0x09,0x3c,0x22,0x10,0x0c,0x3c,
-0x02,0x80,0x14,0x3c,0x02,0x80,0x15,0x3c,0x02,0x80,0x16,0x3c,0x02,0x80,0x17,0x3c,
-0x24,0x10,0x05,0x3c,0x21,0x88,0x00,0x03,0x08,0x7b,0x87,0x26,0x00,0x04,0x18,0x27,
-0x10,0x7b,0xa8,0x26,0x18,0x7b,0xca,0x26,0x20,0x7b,0xeb,0x26,0x00,0x04,0x2d,0x35,
-0x00,0x40,0x8e,0x34,0x00,0x80,0x8f,0x35,0x00,0x01,0xc6,0x34,0xe4,0x64,0x50,0xac,
-0xfc,0x64,0x51,0xac,0x64,0x65,0x4d,0xac,0x28,0x65,0x52,0xac,0x34,0x65,0x4e,0xac,
-0x58,0x65,0x4f,0xac,0x4c,0x65,0x53,0xac,0x00,0x00,0xc5,0xac,0x48,0x65,0x45,0xac,
-0x68,0x65,0x43,0xac,0x74,0x65,0x58,0xac,0x7c,0x64,0x43,0xac,0x78,0x64,0x43,0xac,
-0x06,0x65,0x40,0xa4,0x05,0x65,0x40,0xa0,0x04,0x65,0x40,0xa0,0x5c,0x65,0x49,0xac,
-0x60,0x65,0x49,0xac,0x20,0x65,0x44,0xac,0x24,0x65,0x44,0xac,0x2c,0x65,0x44,0xac,
-0x30,0x65,0x44,0xac,0x50,0x65,0x4c,0xac,0x54,0x65,0x4c,0xac,0x44,0x65,0x45,0xac,
-0x6c,0x65,0x43,0xac,0x78,0x65,0x58,0xac,0x04,0x00,0x08,0xad,0x08,0x7b,0x87,0xae,
-0x04,0x00,0x4a,0xad,0x10,0x7b,0xa8,0xae,0x04,0x00,0x6b,0xad,0x18,0x7b,0xca,0xae,
-0x20,0x7b,0xeb,0xae,0x04,0x00,0xe7,0xac,0x02,0x80,0x02,0x3c,0x00,0x14,0x43,0x24,
-0x21,0x20,0xe0,0x00,0x03,0x00,0x06,0x24,0x21,0x10,0x80,0x00,0xff,0xff,0xc6,0x24,
-0x08,0x00,0x78,0xac,0x00,0x00,0x63,0xac,0x10,0x00,0x60,0xac,0x00,0x00,0x67,0xac,
-0x21,0x20,0x60,0x00,0x04,0x00,0x62,0xac,0x00,0x00,0x43,0xac,0x00,0x01,0x18,0x27,
-0xf5,0xff,0xc1,0x04,0x18,0x00,0x63,0x24,0x02,0x80,0x02,0x3c,0x10,0x7b,0x49,0x24,
-0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x04,0x00,0x28,0x8d,0x60,0x14,0x4b,0x24,
-0x04,0x00,0xe4,0xac,0x00,0x14,0x6a,0x24,0x01,0x00,0x07,0x24,0x21,0x28,0x00,0x00,
-0x07,0x00,0x06,0x24,0x21,0x20,0xab,0x00,0x21,0x10,0xaa,0x00,0xff,0xff,0xc6,0x24,
-0x68,0x00,0x58,0xac,0x70,0x00,0x47,0xac,0x18,0x00,0xa5,0x24,0x00,0x00,0x89,0xac,
-0x04,0x00,0x88,0xac,0x00,0x00,0x04,0xad,0x00,0x01,0x18,0x27,0xf5,0xff,0xc1,0x04,
-0x21,0x40,0x80,0x00,0x02,0x80,0x02,0x3c,0x18,0x7b,0x4a,0x24,0x02,0x80,0x03,0x3c,
-0x02,0x80,0x02,0x3c,0x04,0x00,0x45,0x8d,0x20,0x15,0x4b,0x24,0x04,0x00,0x24,0xad,
-0x02,0x00,0x07,0x24,0x00,0x14,0x69,0x24,0x21,0x20,0x00,0x00,0x01,0x00,0x06,0x24,
-0x21,0x40,0x8b,0x00,0x21,0x10,0x89,0x00,0xff,0xff,0xc6,0x24,0x28,0x01,0x58,0xac,
-0x30,0x01,0x47,0xac,0x18,0x00,0x84,0x24,0x00,0x00,0x0a,0xad,0x04,0x00,0x05,0xad,
-0x00,0x00,0xa8,0xac,0x00,0x02,0x18,0x27,0xf5,0xff,0xc1,0x04,0x21,0x28,0x00,0x01,
-0x02,0x80,0x05,0x3c,0x20,0x7b,0xa5,0x24,0x04,0x00,0xa6,0x8c,0x1c,0x00,0xb7,0x8f,
-0x18,0x00,0xb6,0x8f,0x14,0x00,0xb5,0x8f,0x10,0x00,0xb4,0x8f,0x0c,0x00,0xb3,0x8f,
-0x08,0x00,0xb2,0x8f,0x04,0x00,0xb1,0x8f,0x00,0x00,0xb0,0x8f,0x02,0x80,0x07,0x3c,
-0x02,0x80,0x03,0x3c,0x50,0x15,0xe4,0x24,0x00,0x14,0x63,0x24,0x03,0x00,0x02,0x24,
-0x20,0x00,0xbd,0x27,0x58,0x01,0x78,0xac,0x04,0x00,0x48,0xad,0x04,0x00,0xa4,0xac,
-0x60,0x01,0x62,0xac,0x50,0x15,0xe5,0xac,0x04,0x00,0x86,0xac,0x08,0x00,0xe0,0x03,
-0x00,0x00,0xc4,0xac,0xd0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x20,0x00,0xb2,0xaf,
-0x02,0x80,0x03,0x3c,0x4c,0x91,0x52,0x24,0x02,0x80,0x02,0x3c,0x28,0x00,0xb4,0xaf,
-0x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x2c,0x00,0xbf,0xaf,
-0xd8,0x90,0x73,0x24,0x68,0x15,0x50,0x24,0x21,0x88,0x00,0x00,0x02,0x80,0x14,0x3c,
-0xee,0x4e,0x00,0x0c,0x21,0x20,0x20,0x02,0x78,0x51,0x05,0x8e,0x6c,0x00,0x66,0x8e,
-0xb8,0x90,0x82,0x26,0x6c,0x00,0x43,0x8e,0x1b,0x00,0x44,0x90,0xff,0xf1,0x02,0x24,
-0x21,0x18,0x66,0x00,0x24,0x28,0xa2,0x00,0x00,0x21,0x04,0x00,0x42,0x18,0x03,0x00,
-0x00,0x02,0xa5,0x34,0x44,0x51,0x03,0xae,0x68,0x51,0x04,0xae,0x78,0x51,0x05,0xae,
-0x6c,0x51,0x04,0xae,0x21,0x30,0x00,0x00,0x21,0x10,0x06,0x02,0x01,0x00,0xc6,0x24,
-0x1d,0x00,0xc3,0x28,0x99,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14,
-0xb6,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x00,0xae,
-0xe3,0xff,0x40,0x14,0x94,0x00,0x10,0x26,0x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c,
-0x68,0x15,0x4b,0x24,0x02,0x80,0x02,0x3c,0x4c,0x91,0x6f,0x24,0xd8,0x90,0x4d,0x24,
-0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xb8,0x90,0x6e,0x24,0x98,0x90,0x4c,0x24,
-0x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x20,0x6d,0x00,0x21,0x10,0x6f,0x00,
-0x21,0x28,0x2e,0x02,0x21,0x30,0x2c,0x02,0x00,0x00,0x88,0x8c,0x00,0x00,0xa9,0x90,
-0x00,0x00,0xc7,0x90,0x00,0x00,0x4a,0x8c,0x21,0x10,0x2b,0x02,0x01,0x00,0x31,0x26,
-0x21,0x18,0x6b,0x00,0x1d,0x00,0x24,0x2a,0xec,0x44,0x68,0xac,0xca,0x44,0x47,0xa0,
-0x60,0x45,0x6a,0xac,0xef,0xff,0x80,0x14,0x90,0x44,0x49,0xa0,0x02,0x80,0x02,0x3c,
-0x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x74,0x8f,0x6b,0x24,
-0x14,0x8e,0x4c,0x24,0x21,0x88,0x00,0x00,0x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00,
-0x21,0x40,0x2a,0x01,0x21,0x38,0x2b,0x01,0x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90,
-0x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01,0x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28,
-0xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14,0x34,0x43,0x65,0xa0,0x21,0x10,0x2c,0x02,
-0x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26,
-0x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0,0x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14,
-0x05,0x00,0x29,0x25,0x52,0x00,0x02,0x24,0x10,0x00,0xa2,0xa3,0x41,0x00,0x03,0x24,
-0x4d,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x1c,0x97,0xe7,0x24,0x11,0x00,0xa3,0xa3,
-0x12,0x00,0xa2,0xa3,0xe8,0x03,0x03,0x24,0x01,0x00,0x02,0x24,0x00,0x80,0x06,0x3c,
-0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xf0,0x37,0xc6,0x24,0x0c,0x00,0xe3,0xac,
-0x14,0x00,0xe2,0xa0,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x2c,0x00,0xbf,0x8f,
-0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,
-0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,
-0x02,0x80,0x02,0x3c,0x42,0x00,0x03,0x24,0x10,0x00,0xa3,0xa3,0x55,0x60,0x40,0xa0,
-0x4e,0x00,0x03,0x24,0x43,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x54,0x97,0xe7,0x24,
-0x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24,
-0x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xdc,0x44,0xc6,0x24,
-0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,
-0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0x48,0xfd,0xbd,0x27,0xb4,0x02,0xb3,0xaf,0x02,0x80,0x02,0x3c,
-0x02,0x80,0x13,0x3c,0x24,0x92,0x46,0x24,0x68,0x15,0x63,0x26,0xb0,0x02,0xb2,0xaf,
-0xac,0x02,0xb1,0xaf,0xa8,0x02,0xb0,0xaf,0x03,0x40,0x60,0xa0,0x21,0x38,0xa0,0x03,
-0x90,0x00,0xc8,0x24,0x00,0x00,0xc2,0x8c,0x04,0x00,0xc3,0x8c,0x08,0x00,0xc4,0x8c,
-0x0c,0x00,0xc5,0x8c,0x10,0x00,0xc6,0x24,0x00,0x00,0xe2,0xac,0x04,0x00,0xe3,0xac,
-0x08,0x00,0xe4,0xac,0x0c,0x00,0xe5,0xac,0xf6,0xff,0xc8,0x14,0x10,0x00,0xe7,0x24,
-0x00,0x00,0xc3,0x8c,0x02,0x80,0x02,0x3c,0xb8,0x92,0x58,0x24,0x00,0x00,0xe3,0xac,
-0x98,0x00,0xb9,0x27,0x00,0x01,0x12,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93,
-0x09,0x00,0x04,0x93,0x0d,0x00,0x05,0x93,0x00,0x00,0x11,0x93,0x02,0x00,0x0d,0x93,
-0x04,0x00,0x10,0x93,0x06,0x00,0x0c,0x93,0x08,0x00,0x0f,0x93,0x0a,0x00,0x07,0x93,
-0x0c,0x00,0x0e,0x93,0x0e,0x00,0x06,0x93,0x03,0x00,0x08,0x93,0x07,0x00,0x09,0x93,
-0x0b,0x00,0x0a,0x93,0x0f,0x00,0x0b,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00,
-0x00,0x22,0x04,0x00,0x00,0x2a,0x05,0x00,0x25,0x10,0x51,0x00,0x25,0x18,0x70,0x00,
-0x25,0x20,0x8f,0x00,0x25,0x28,0xae,0x00,0x00,0x6c,0x0d,0x00,0x00,0x64,0x0c,0x00,
-0x00,0x3c,0x07,0x00,0x00,0x34,0x06,0x00,0x25,0x68,0xa2,0x01,0x25,0x60,0x83,0x01,
-0x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0x00,0x46,0x08,0x00,0x00,0x4e,0x09,0x00,
-0x00,0x56,0x0a,0x00,0x00,0x5e,0x0b,0x00,0x25,0x40,0x0d,0x01,0x25,0x48,0x2c,0x01,
-0x25,0x50,0x47,0x01,0x25,0x58,0x66,0x01,0x10,0x00,0x18,0x27,0x00,0x00,0x28,0xaf,
-0x04,0x00,0x29,0xaf,0x08,0x00,0x2a,0xaf,0x0c,0x00,0x2b,0xaf,0xd2,0xff,0x12,0x17,
-0x10,0x00,0x39,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93,0x00,0x00,0x09,0x93,
-0x02,0x00,0x04,0x93,0x04,0x00,0x08,0x93,0x06,0x00,0x05,0x93,0x07,0x00,0x06,0x93,
-0x03,0x00,0x07,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00,0x25,0x10,0x49,0x00,
-0x25,0x18,0x68,0x00,0x00,0x24,0x04,0x00,0x00,0x2c,0x05,0x00,0x25,0x20,0x82,0x00,
-0x25,0x28,0xa3,0x00,0x00,0x3e,0x07,0x00,0x00,0x36,0x06,0x00,0x02,0x80,0x02,0x3c,
-0x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0xc0,0x93,0x58,0x24,0x04,0x00,0x26,0xaf,
-0x00,0x00,0x27,0xaf,0x00,0x01,0x12,0x27,0xa0,0x01,0xb9,0x27,0x01,0x00,0x02,0x93,
-0x05,0x00,0x03,0x93,0x09,0x00,0x04,0x93,0x0d,0x00,0x05,0x93,0x00,0x00,0x11,0x93,
-0x02,0x00,0x0d,0x93,0x04,0x00,0x10,0x93,0x06,0x00,0x0c,0x93,0x08,0x00,0x0f,0x93,
-0x0a,0x00,0x07,0x93,0x0c,0x00,0x0e,0x93,0x0e,0x00,0x06,0x93,0x03,0x00,0x08,0x93,
-0x07,0x00,0x09,0x93,0x0b,0x00,0x0a,0x93,0x0f,0x00,0x0b,0x93,0x00,0x12,0x02,0x00,
-0x00,0x1a,0x03,0x00,0x00,0x22,0x04,0x00,0x00,0x2a,0x05,0x00,0x25,0x10,0x51,0x00,
-0x25,0x18,0x70,0x00,0x25,0x20,0x8f,0x00,0x25,0x28,0xae,0x00,0x00,0x6c,0x0d,0x00,
-0x00,0x64,0x0c,0x00,0x00,0x3c,0x07,0x00,0x00,0x34,0x06,0x00,0x25,0x68,0xa2,0x01,
-0x25,0x60,0x83,0x01,0x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0x00,0x46,0x08,0x00,
-0x00,0x4e,0x09,0x00,0x00,0x56,0x0a,0x00,0x00,0x5e,0x0b,0x00,0x25,0x40,0x0d,0x01,
-0x25,0x48,0x2c,0x01,0x25,0x50,0x47,0x01,0x25,0x58,0x66,0x01,0x10,0x00,0x18,0x27,
-0x00,0x00,0x28,0xaf,0x04,0x00,0x29,0xaf,0x08,0x00,0x2a,0xaf,0x0c,0x00,0x2b,0xaf,
-0xd2,0xff,0x12,0x17,0x10,0x00,0x39,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93,
-0x00,0x00,0x09,0x93,0x02,0x00,0x04,0x93,0x04,0x00,0x08,0x93,0x06,0x00,0x05,0x93,
-0x07,0x00,0x06,0x93,0x03,0x00,0x07,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00,
-0x25,0x10,0x49,0x00,0x25,0x18,0x68,0x00,0x00,0x24,0x04,0x00,0x00,0x2c,0x05,0x00,
-0x25,0x20,0x82,0x00,0x25,0x28,0xa3,0x00,0x00,0x3e,0x07,0x00,0x00,0x36,0x06,0x00,
-0x25,0x30,0xc5,0x00,0x25,0x38,0xe4,0x00,0x02,0x80,0x02,0x3c,0x04,0x00,0x26,0xaf,
-0x00,0x00,0x27,0xaf,0x68,0x15,0x46,0x24,0x21,0x50,0x00,0x00,0x80,0x20,0x0a,0x00,
-0x21,0x10,0x9d,0x00,0x00,0x00,0x45,0x8c,0x01,0x00,0x43,0x25,0xff,0x00,0x6a,0x30,
-0x21,0x20,0x86,0x00,0x25,0x00,0x42,0x2d,0xf8,0xff,0x40,0x14,0x18,0x40,0x85,0xac,
-0x02,0x80,0x02,0x3c,0x68,0x15,0x4b,0x24,0x21,0x50,0x00,0x00,0xc0,0x10,0x0a,0x00,
-0x21,0x48,0x5d,0x00,0x21,0x38,0x00,0x00,0x21,0x40,0x4b,0x00,0x21,0x10,0x27,0x01,
-0xa0,0x01,0x46,0x90,0x98,0x00,0x45,0x90,0x01,0x00,0xe4,0x24,0x21,0x18,0x07,0x01,
-0xff,0x00,0x87,0x30,0x08,0x00,0xe2,0x2c,0xb4,0x41,0x66,0xa0,0xf7,0xff,0x40,0x14,
-0xac,0x40,0x65,0xa0,0x01,0x00,0x42,0x25,0xff,0x00,0x4a,0x30,0x21,0x00,0x43,0x2d,
-0xef,0xff,0x60,0x14,0xc0,0x10,0x0a,0x00,0x25,0xb0,0x02,0x3c,0x0a,0x00,0x42,0x34,
-0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x20,0x00,0x63,0x30,0x42,0x00,0x60,0x10,
-0x68,0x15,0x64,0x26,0x33,0x00,0x02,0x24,0xc1,0x42,0x62,0xa1,0x1c,0x00,0x03,0x24,
-0x0f,0x00,0x02,0x24,0xbc,0x42,0x63,0xa1,0xbd,0x42,0x62,0xa1,0x68,0x15,0x65,0x26,
-0x08,0x40,0xa4,0x8c,0xff,0x7f,0x08,0x3c,0xff,0xff,0x08,0x35,0xc0,0xff,0x02,0x24,
-0x24,0x20,0x88,0x00,0x24,0x20,0x82,0x00,0x0c,0x00,0x84,0x34,0xff,0xc0,0x02,0x24,
-0x24,0x20,0x82,0x00,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34,0x00,0x18,0x84,0x34,
-0xbf,0xff,0x03,0x3c,0x24,0x20,0x82,0x00,0xff,0xff,0x63,0x34,0x7f,0xff,0x02,0x3c,
-0x24,0x20,0x83,0x00,0xff,0xff,0x42,0x34,0x24,0x20,0x82,0x00,0x0c,0x40,0xa6,0x8c,
-0x7f,0xff,0x03,0x24,0x40,0x40,0x84,0x34,0xff,0xff,0x02,0x3c,0x24,0x20,0x83,0x00,
-0xff,0x7f,0x42,0x34,0xff,0xbf,0x03,0x3c,0x10,0x40,0xa7,0x8c,0x24,0x20,0x82,0x00,
-0xff,0xff,0x63,0x34,0xff,0x9f,0x02,0x3c,0x24,0x30,0xc3,0x00,0xff,0xff,0x42,0x34,
-0xff,0x3f,0x03,0x3c,0x24,0x20,0x82,0x00,0xff,0xff,0x63,0x34,0x12,0x00,0x02,0x24,
-0xb4,0x02,0xb3,0x8f,0xb0,0x02,0xb2,0x8f,0xac,0x02,0xb1,0x8f,0xa8,0x02,0xb0,0x8f,
-0x24,0x38,0xe3,0x00,0xc7,0x42,0xa2,0xa0,0x1f,0x00,0x03,0x24,0x01,0x00,0x02,0x24,
-0x24,0x30,0xc8,0x00,0xbe,0x42,0xa3,0xa0,0xc0,0x42,0xa2,0xa0,0xff,0x00,0x03,0x24,
-0xff,0xff,0x02,0x24,0xb8,0x02,0xbd,0x27,0x08,0x40,0xa4,0xac,0x10,0x40,0xa7,0xac,
-0x0c,0x40,0xa6,0xac,0xc2,0x42,0xa2,0xa0,0xc4,0x42,0xa3,0xa4,0xbf,0x42,0xa0,0xa0,
-0x08,0x00,0xe0,0x03,0xc6,0x42,0xa0,0xa0,0x33,0x00,0x02,0x24,0xc1,0x42,0x82,0xa0,
-0x0d,0x00,0x03,0x24,0x03,0x00,0x02,0x24,0xbc,0x42,0x83,0xa0,0x65,0x5d,0x00,0x08,
-0xbd,0x42,0x82,0xa0,0xe0,0xff,0xbd,0x27,0x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24,
-0x18,0x00,0xbf,0xaf,0x00,0x40,0xe3,0x8c,0xf0,0xff,0x02,0x24,0x02,0x80,0x08,0x3c,
-0x24,0x18,0x62,0x00,0xff,0xf0,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x40,0xe3,0xac,
-0x1c,0x00,0x03,0x24,0x36,0x00,0x02,0x24,0xcf,0x42,0xe3,0xa0,0x20,0x00,0x03,0x24,
-0xce,0x42,0xe2,0xa0,0xd1,0x42,0xe3,0xa0,0x32,0x00,0x02,0x24,0x20,0x00,0x03,0x24,
-0xd0,0x42,0xe2,0xa0,0xc8,0x42,0xe3,0xa4,0x0a,0x00,0x02,0x24,0x00,0x02,0x03,0x24,
-0xd2,0x42,0xe2,0xa0,0xcc,0x42,0xe3,0xa4,0x00,0x01,0x02,0x24,0x49,0x00,0x03,0x24,
-0x38,0x97,0x08,0x25,0xff,0xff,0x0a,0x34,0x01,0x00,0x09,0x24,0x11,0x00,0xa3,0xa3,
-0xca,0x42,0xe2,0xa4,0xd0,0x07,0x03,0x24,0x44,0x00,0x02,0x24,0x00,0x80,0x06,0x3c,
-0x10,0x00,0xa2,0xa3,0x10,0x00,0xa5,0x27,0x47,0x00,0x02,0x24,0x21,0x20,0x00,0x01,
-0x54,0x45,0xc6,0x24,0x04,0x40,0xea,0xac,0x02,0x40,0xe9,0xa0,0x0c,0x00,0x03,0xad,
-0x14,0x00,0x09,0xa1,0xe6,0x42,0xe0,0xa0,0xdc,0x63,0xea,0xac,0xd7,0x42,0xe0,0xa0,
-0x12,0x00,0xa2,0xa3,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,
-0x02,0x80,0x02,0x3c,0x50,0x00,0x03,0x24,0x10,0x00,0xa3,0xa3,0x2a,0x62,0x40,0xa0,
-0x41,0x00,0x03,0x24,0x52,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0xc4,0x97,0xe7,0x24,
-0x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24,
-0x01,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0x88,0x5b,0xc6,0x24,
-0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,
-0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0xd8,0xff,0xbd,0x27,0x18,0x00,0xb0,0xaf,0x02,0x80,0x10,0x3c,
-0x68,0x15,0x10,0x26,0x20,0x00,0xbf,0xaf,0x1c,0x00,0xb1,0xaf,0x00,0x40,0x09,0x8e,
-0xff,0xff,0x02,0x24,0xff,0x00,0x4b,0x30,0x0f,0xff,0x02,0x24,0x24,0x48,0x22,0x01,
-0xff,0xff,0x02,0x3c,0xff,0x0f,0x42,0x34,0x24,0x48,0x22,0x01,0x01,0x00,0x07,0x3c,
-0x47,0x00,0x02,0x24,0x3b,0x00,0x03,0x24,0x02,0x80,0x08,0x3c,0x10,0x00,0xa2,0xa3,
-0x11,0x00,0xa3,0xa3,0xe0,0x97,0x08,0x25,0x56,0x30,0xea,0x34,0xd0,0x07,0x02,0x24,
-0x01,0x00,0x03,0x24,0xf4,0x98,0xe7,0x34,0x00,0x80,0x06,0x3c,0x04,0x43,0x0b,0xae,
-0x00,0x40,0x09,0xae,0x43,0x00,0x11,0x24,0x10,0x00,0xa5,0x27,0x0c,0x43,0x07,0xae,
-0x10,0x43,0x0a,0xae,0x0c,0x00,0x02,0xad,0x14,0x00,0x03,0xa1,0x08,0x43,0x00,0xae,
-0x14,0x43,0x00,0xae,0x18,0x43,0x00,0xae,0x21,0x20,0x00,0x01,0xe4,0x4e,0xc6,0x24,
-0x12,0x00,0xb1,0xa3,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x1e,0x00,0x02,0x24,
-0x21,0x43,0x02,0xa2,0x4a,0x00,0x03,0x24,0x45,0x00,0x02,0x24,0x1c,0x43,0x03,0xa2,
-0x1d,0x43,0x02,0xa2,0x23,0x00,0x03,0x24,0x3e,0x00,0x02,0x24,0x1e,0x43,0x11,0xa2,
-0x1f,0x43,0x02,0xa2,0x20,0x43,0x03,0xa2,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb1,0x8f,
-0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,
-0x3b,0x00,0x02,0x24,0x43,0x00,0x03,0x24,0x10,0x00,0xa2,0xa3,0x11,0x00,0xa3,0xa3,
-0x36,0x00,0x02,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x07,0x3c,0xfc,0x97,0xe7,0x24,
-0x12,0x00,0xa2,0xa3,0x3b,0x58,0x60,0xa0,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24,
-0x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0x20,0x53,0xc6,0x24,
-0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,
-0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0xff,0xff,0x07,0x24,0x02,0x80,0x02,0x3c,0xe0,0xff,0xbd,0x27,
-0x3d,0x58,0x47,0xa0,0x3b,0x00,0x03,0x24,0x43,0x00,0x02,0x24,0x10,0x00,0xa3,0xa3,
-0x11,0x00,0xa2,0xa3,0x36,0x00,0x03,0x24,0x16,0x00,0x02,0x24,0x02,0x80,0x08,0x3c,
-0x18,0x98,0x08,0x25,0x12,0x00,0xa3,0xa3,0x13,0x00,0xa2,0xa3,0xd0,0x07,0x03,0x24,
-0x01,0x00,0x02,0x24,0x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0x00,0x01,
-0x0c,0x00,0x03,0xad,0x14,0x00,0x02,0xa1,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,
-0xb8,0x54,0xc6,0x24,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
-0x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x52,0x00,0x03,0x24,
-0x10,0x00,0xa3,0xa3,0x4c,0x79,0x40,0xa4,0x54,0x00,0x03,0x24,0x53,0x00,0x02,0x24,
-0x02,0x80,0x07,0x3c,0x34,0x98,0xe7,0x24,0x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3,
-0xf4,0x01,0x02,0x24,0x01,0x00,0x03,0x24,0x01,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,
-0x21,0x20,0xe0,0x00,0xc8,0x5c,0xc6,0x24,0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,
-0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,
-0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x78,0x0c,0x00,0x00,0x01,0x00,0x00,0x5e,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x01,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x02,0x5e,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x03,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x04,0x5d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x05,0x5b,0x78,0x0c,0x00,0x00,0x01,0x00,0x06,0x59,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x07,0x57,0x78,0x0c,0x00,0x00,0x01,0x00,0x08,0x55,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x09,0x53,0x78,0x0c,0x00,0x00,0x01,0x00,0x0a,0x51,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x0b,0x4f,0x78,0x0c,0x00,0x00,0x01,0x00,0x0c,0x4d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x0d,0x4b,0x78,0x0c,0x00,0x00,0x01,0x00,0x0e,0x49,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x0f,0x47,0x78,0x0c,0x00,0x00,0x01,0x00,0x10,0x45,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x11,0x43,0x78,0x0c,0x00,0x00,0x01,0x00,0x12,0x41,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x13,0x3f,0x78,0x0c,0x00,0x00,0x01,0x00,0x14,0x3d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x15,0x3b,0x78,0x0c,0x00,0x00,0x01,0x00,0x16,0x39,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x17,0x37,0x78,0x0c,0x00,0x00,0x01,0x00,0x18,0x35,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x19,0x33,0x78,0x0c,0x00,0x00,0x01,0x00,0x1a,0x31,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x1b,0x2f,0x78,0x0c,0x00,0x00,0x01,0x00,0x1c,0x2d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x1d,0x2b,0x78,0x0c,0x00,0x00,0x01,0x00,0x1e,0x29,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x1f,0x27,0x78,0x0c,0x00,0x00,0x01,0x00,0x20,0x25,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x21,0x23,0x78,0x0c,0x00,0x00,0x01,0x00,0x22,0x21,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x23,0x1f,0x78,0x0c,0x00,0x00,0x01,0x00,0x24,0x1d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x25,0x1b,0x78,0x0c,0x00,0x00,0x01,0x00,0x26,0x19,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x27,0x17,0x78,0x0c,0x00,0x00,0x01,0x00,0x28,0x15,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x29,0x13,0x78,0x0c,0x00,0x00,0x01,0x00,0x2a,0x11,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x2b,0x0f,0x78,0x0c,0x00,0x00,0x01,0x00,0x2c,0x0d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x2d,0x0b,0x78,0x0c,0x00,0x00,0x01,0x00,0x2e,0x09,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x2f,0x07,0x78,0x0c,0x00,0x00,0x01,0x00,0x30,0x05,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x31,0x03,0x78,0x0c,0x00,0x00,0x01,0x00,0x32,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x33,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x34,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x35,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x36,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x37,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x38,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x39,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3a,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x3b,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3c,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x3d,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3e,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x3f,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x40,0x5e,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x41,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x42,0x5e,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x43,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x44,0x5d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x45,0x5b,0x78,0x0c,0x00,0x00,0x01,0x00,0x46,0x59,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x47,0x57,0x78,0x0c,0x00,0x00,0x01,0x00,0x48,0x55,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x49,0x53,0x78,0x0c,0x00,0x00,0x01,0x00,0x4a,0x51,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x4b,0x4f,0x78,0x0c,0x00,0x00,0x01,0x00,0x4c,0x4d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x4d,0x4b,0x78,0x0c,0x00,0x00,0x01,0x00,0x4e,0x49,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x4f,0x47,0x78,0x0c,0x00,0x00,0x01,0x00,0x50,0x45,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x51,0x43,0x78,0x0c,0x00,0x00,0x01,0x00,0x52,0x41,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x53,0x3f,0x78,0x0c,0x00,0x00,0x01,0x00,0x54,0x3d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x55,0x3b,0x78,0x0c,0x00,0x00,0x01,0x00,0x56,0x39,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x57,0x37,0x78,0x0c,0x00,0x00,0x01,0x00,0x58,0x35,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x59,0x33,0x78,0x0c,0x00,0x00,0x01,0x00,0x5a,0x31,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x5b,0x2f,0x78,0x0c,0x00,0x00,0x01,0x00,0x5c,0x2d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x5d,0x2b,0x78,0x0c,0x00,0x00,0x01,0x00,0x5e,0x29,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x5f,0x27,0x78,0x0c,0x00,0x00,0x01,0x00,0x60,0x25,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x61,0x23,0x78,0x0c,0x00,0x00,0x01,0x00,0x62,0x21,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x63,0x1f,0x78,0x0c,0x00,0x00,0x01,0x00,0x64,0x1d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x65,0x1b,0x78,0x0c,0x00,0x00,0x01,0x00,0x66,0x19,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x67,0x17,0x78,0x0c,0x00,0x00,0x01,0x00,0x68,0x15,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x69,0x13,0x78,0x0c,0x00,0x00,0x01,0x00,0x6a,0x11,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x6b,0x0f,0x78,0x0c,0x00,0x00,0x01,0x00,0x6c,0x0d,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x6d,0x0b,0x78,0x0c,0x00,0x00,0x01,0x00,0x6e,0x09,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x6f,0x07,0x78,0x0c,0x00,0x00,0x01,0x00,0x70,0x05,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x71,0x03,0x78,0x0c,0x00,0x00,0x01,0x00,0x72,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x73,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x74,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x75,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x76,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x77,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x78,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x79,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7a,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x7b,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7c,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x7d,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7e,0x01,0x78,0x0c,0x00,0x00,
-0x01,0x00,0x7f,0x01,0x78,0x0c,0x00,0x00,0x1e,0x00,0x00,0x30,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x01,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x02,0x30,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x03,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x04,0x30,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x05,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x06,0x30,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x07,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x08,0x3e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x09,0x40,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0a,0x42,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x0b,0x44,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0c,0x46,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x0d,0x48,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0e,0x48,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x0f,0x4a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x10,0x4a,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x11,0x4c,0x78,0x0c,0x00,0x00,0x1e,0x00,0x12,0x4c,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x13,0x4e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x14,0x50,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x15,0x50,0x78,0x0c,0x00,0x00,0x1e,0x00,0x16,0x50,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x17,0x52,0x78,0x0c,0x00,0x00,0x1e,0x00,0x18,0x52,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x19,0x52,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1a,0x54,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x1b,0x54,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1c,0x54,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x1d,0x56,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1e,0x56,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x1f,0x56,0x78,0x0c,0x00,0x00,0x1e,0x00,0x20,0x56,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x21,0x58,0x78,0x0c,0x00,0x00,0x1e,0x00,0x22,0x58,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x23,0x58,0x78,0x0c,0x00,0x00,0x1e,0x00,0x24,0x58,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x25,0x5a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x26,0x5a,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x27,0x5a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x28,0x5c,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x29,0x5c,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2a,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x2b,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2c,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x2d,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2e,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x2f,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x30,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x31,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x32,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x33,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x34,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x35,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x36,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x37,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x38,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x39,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3a,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x3b,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3c,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x3d,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3e,0x5e,0x78,0x0c,0x00,0x00,
-0x1e,0x00,0x3f,0x5e,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x08,0x00,0x00,
-0x00,0x00,0x04,0x03,0x04,0x08,0x00,0x00,0x03,0x00,0x00,0x00,0x08,0x08,0x00,0x00,
-0x00,0xfc,0x00,0x00,0x0c,0x08,0x00,0x00,0x0a,0x00,0x00,0x04,0x10,0x08,0x00,0x00,
-0xff,0x10,0x10,0x80,0x14,0x08,0x00,0x00,0x10,0x3d,0x0c,0x02,0x18,0x08,0x00,0x00,
-0xc5,0x03,0x00,0x00,0x1c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x00,
-0x04,0x00,0x00,0x00,0x24,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x28,0x08,0x00,0x00,
-0x04,0x00,0x00,0x00,0x2c,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x30,0x08,0x00,0x00,
-0x04,0x00,0x00,0x00,0x34,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x38,0x08,0x00,0x00,
-0x04,0x00,0x00,0x00,0x3c,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x40,0x08,0x00,0x00,
-0x00,0x00,0x00,0x00,0x44,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x00,0x00,
-0x00,0x00,0x00,0x00,0x4c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x08,0x00,0x00,
-0x00,0x00,0x00,0x00,0x54,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x08,0x00,0x00,
-0x65,0xa9,0x65,0xa9,0x5c,0x08,0x00,0x00,0x65,0xa9,0x65,0xa9,0x60,0x08,0x00,0x00,
-0x30,0x01,0x7f,0x0f,0x64,0x08,0x00,0x00,0x30,0x01,0x7f,0x0f,0x68,0x08,0x00,0x00,
-0x30,0x01,0x7f,0x0f,0x6c,0x08,0x00,0x00,0x30,0x01,0x7f,0x0f,0x70,0x08,0x00,0x00,
-0x00,0x03,0x00,0x03,0x74,0x08,0x00,0x00,0x00,0x03,0x00,0x03,0x78,0x08,0x00,0x00,
-0x00,0x00,0x00,0x00,0x7c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x08,0x00,0x00,
-0x00,0x00,0x00,0x00,0x94,0x08,0x00,0x00,0xfe,0xff,0xff,0xff,0x98,0x08,0x00,0x00,
-0x10,0x20,0x30,0x40,0x9c,0x08,0x00,0x00,0x50,0x60,0x70,0x00,0xb0,0x08,0x00,0x00,
-0x00,0x00,0x00,0x00,0xe0,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x08,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x04,0x0e,0x00,0x00,
-0x03,0x03,0x03,0x03,0x08,0x0e,0x00,0x00,0x03,0x03,0x00,0x00,0x0c,0x0e,0x00,0x00,
-0x00,0x00,0x00,0x00,0x10,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x14,0x0e,0x00,0x00,
-0x03,0x03,0x03,0x03,0x18,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x1c,0x0e,0x00,0x00,
-0x03,0x03,0x03,0x03,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x00,0x00,
-0x23,0x00,0x00,0x00,0x08,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x09,0x00,0x00,
-0x33,0x13,0x32,0x03,0x08,0x0a,0x00,0x00,0x00,0x86,0x88,0x8f,0x2c,0x0a,0x00,0x00,
-0x00,0x00,0x92,0x00,0x00,0x0c,0x00,0x00,0x80,0x00,0x00,0x00,0x04,0x0c,0x00,0x00,
-0x33,0x54,0x00,0x00,0x08,0x0c,0x00,0x00,0xe4,0x00,0x00,0x00,0x0c,0x0c,0x00,0x00,
-0x6c,0x6c,0x6c,0x6c,0x10,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x0c,0x00,0x00,
-0x00,0x01,0x00,0x40,0x18,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x0c,0x00,0x00,
-0x00,0x01,0x00,0x40,0x20,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x24,0x0c,0x00,0x00,
-0x00,0x01,0x00,0x40,0x28,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x2c,0x0c,0x00,0x00,
-0x00,0x01,0x00,0x40,0x30,0x0c,0x00,0x00,0x44,0x6a,0xe9,0x8d,0x34,0x0c,0x00,0x00,
-0xcd,0x52,0x96,0x46,0x38,0x0c,0x00,0x00,0x90,0x5a,0x01,0x48,0x3c,0x0c,0x00,0x00,
-0x64,0x97,0x97,0x1a,0x40,0x0c,0x00,0x00,0x3f,0x42,0x7c,0x1f,0x44,0x0c,0x00,0x00,
-0xb7,0x00,0x01,0x00,0x48,0x0c,0x00,0x00,0x00,0x00,0x02,0xec,0x4c,0x0c,0x00,0x00,
-0x03,0x03,0xfc,0x00,0x50,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x54,0x0c,0x00,0x00,
-0x94,0x00,0x3c,0x43,0x58,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x5c,0x0c,0x00,0x00,
-0x94,0x00,0x3c,0x43,0x60,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x64,0x0c,0x00,0x00,
-0x94,0x00,0x3c,0x43,0x68,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x6c,0x0c,0x00,0x00,
-0x94,0x00,0x3c,0x43,0x70,0x0c,0x00,0x00,0x0d,0x00,0x5a,0x2c,0x74,0x0c,0x00,0x00,
-0x1b,0x15,0x86,0x01,0x78,0x0c,0x00,0x00,0x1f,0x00,0x00,0x00,0x7c,0x0c,0x00,0x00,
-0x12,0x16,0xb9,0x00,0x80,0x0c,0x00,0x00,0x80,0x00,0x00,0x20,0x84,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0x88,0x0c,0x00,0x00,0x80,0x00,0x00,0x20,0x8c,0x0c,0x00,0x00,
-0x00,0x00,0x20,0x08,0x90,0x0c,0x00,0x00,0x00,0x01,0x00,0x40,0x94,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0x98,0x0c,0x00,0x00,0x00,0x01,0x00,0x40,0x9c,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0xa0,0x0c,0x00,0x00,0x92,0x24,0x49,0x00,0xa4,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0xa8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0xb0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xb4,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0xb8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0x0c,0x00,0x00,
-0x92,0x24,0x49,0x00,0xc0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0xc8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xcc,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0xd0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0xd8,0x0c,0x00,0x00,0x27,0x24,0xb2,0x64,0xdc,0x0c,0x00,0x00,
-0x32,0x69,0x76,0x00,0xe0,0x0c,0x00,0x00,0x22,0x22,0x22,0x00,0xe4,0x0c,0x00,0x00,
-0x00,0x00,0x00,0x00,0xe8,0x0c,0x00,0x00,0x02,0x43,0x64,0x07,0x00,0x0d,0x00,0x00,
-0x80,0x07,0x00,0x00,0x04,0x0d,0x00,0x00,0x03,0x04,0x00,0x00,0x08,0x0d,0x00,0x00,
-0x7f,0x90,0x00,0x00,0x0c,0x0d,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x0d,0x00,0x00,
-0x99,0x99,0x69,0xa0,0x14,0x0d,0x00,0x00,0x67,0x3c,0x99,0x99,0x18,0x0d,0x00,0x00,
-0x6b,0x5b,0x8f,0x6a,0x1c,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x0d,0x00,0x00,
-0x00,0x00,0x00,0x00,0x24,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x0d,0x00,0x00,
-0x00,0x00,0x00,0x00,0x2c,0x0d,0x00,0x00,0x75,0x19,0x97,0xcc,0x30,0x0d,0x00,0x00,
-0x00,0x00,0x00,0x00,0x34,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x0d,0x00,0x00,
-0x00,0x00,0x00,0x00,0x3c,0x0d,0x00,0x00,0x93,0x72,0x02,0x00,0x40,0x0d,0x00,0x00,
-0x00,0x00,0x00,0x00,0x44,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x0d,0x00,0x00,
-0x00,0x00,0x00,0x00,0x50,0x0d,0x00,0x00,0x0a,0x14,0x37,0x64,0x54,0x0d,0x00,0x00,
-0x02,0xbd,0x4d,0x02,0x58,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0x0d,0x00,0x00,
-0x64,0x20,0x03,0x30,0x60,0x0d,0x00,0x00,0x68,0xde,0x53,0x46,0x64,0x0d,0x00,0x00,
-0x3c,0x8a,0x51,0x00,0x68,0x0d,0x00,0x00,0x06,0x01,0x00,0x00,0xff,0x00,0x00,0x00,
-0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
-0x44,0x05,0x01,0x80,0x10,0x00,0x00,0x00,0x74,0x05,0x01,0x80,0x10,0x00,0x00,0x00,
-0xe0,0x2e,0x00,0x80,0x10,0x00,0x00,0x00,0xec,0x2e,0x00,0x80,0x10,0x00,0x00,0x00,
-0xa0,0x08,0x01,0x80,0x08,0x00,0x00,0x00,0x38,0x06,0x01,0x80,0x00,0xb7,0x00,0x00,
-0x01,0xe0,0x0e,0x00,0x02,0x4d,0x04,0x00,0x03,0x41,0x04,0x00,0x04,0xc3,0x08,0x00,
-0x05,0x72,0x0c,0x00,0x06,0xe6,0x00,0x00,0x07,0x2a,0x08,0x00,0x08,0x3f,0x00,0x00,
-0x09,0x35,0x03,0x00,0x0a,0xd4,0x09,0x00,0x0b,0xbb,0x07,0x00,0x0c,0x50,0x08,0x00,
-0x0d,0xdf,0x0c,0x00,0x0e,0x2b,0x00,0x00,0x0f,0x14,0x01,0x00,0x00,0xb7,0x01,0x00,
-0x01,0x01,0x00,0x00,0x02,0x00,0x04,0x00,0x01,0x02,0x00,0x00,0x02,0x01,0x04,0x00,
-0x01,0x03,0x00,0x00,0x02,0x02,0x04,0x00,0x01,0x04,0x00,0x00,0x02,0x03,0x04,0x00,
-0x01,0x05,0x00,0x00,0x02,0x04,0x04,0x00,0x01,0x06,0x00,0x00,0x02,0x05,0x04,0x00,
-0x01,0x07,0x00,0x00,0x02,0x08,0x04,0x00,0x01,0x08,0x00,0x00,0x02,0x09,0x04,0x00,
-0x01,0x09,0x00,0x00,0x02,0x0a,0x04,0x00,0x01,0x0a,0x00,0x00,0x02,0x0b,0x04,0x00,
-0x01,0x0b,0x00,0x00,0x02,0x02,0x05,0x00,0x01,0x0c,0x00,0x00,0x02,0x03,0x05,0x00,
-0x01,0x0d,0x00,0x00,0x02,0x04,0x05,0x00,0x01,0x0e,0x00,0x00,0x02,0x05,0x05,0x00,
-0x01,0x0f,0x00,0x00,0x02,0x40,0x05,0x00,0x01,0x10,0x00,0x00,0x02,0x41,0x05,0x00,
-0x01,0x11,0x00,0x00,0x02,0x42,0x05,0x00,0x01,0x12,0x00,0x00,0x02,0x43,0x05,0x00,
-0x01,0x13,0x00,0x00,0x02,0x44,0x05,0x00,0x01,0x14,0x00,0x00,0x02,0x45,0x05,0x00,
-0x01,0x15,0x00,0x00,0x02,0x80,0x05,0x00,0x01,0x16,0x00,0x00,0x02,0x81,0x05,0x00,
-0x01,0x17,0x00,0x00,0x02,0x82,0x05,0x00,0x01,0x18,0x00,0x00,0x02,0x83,0x05,0x00,
-0x01,0x19,0x00,0x00,0x02,0x84,0x05,0x00,0x01,0x1a,0x00,0x00,0x02,0x85,0x05,0x00,
-0x01,0x1b,0x00,0x00,0x02,0x88,0x05,0x00,0x01,0x1c,0x00,0x00,0x02,0x89,0x05,0x00,
-0x01,0x1d,0x00,0x00,0x02,0x8a,0x05,0x00,0x01,0x1e,0x00,0x00,0x02,0x8b,0x05,0x00,
-0x01,0x1f,0x00,0x00,0x02,0x43,0x06,0x00,0x01,0x20,0x00,0x00,0x02,0x44,0x06,0x00,
-0x01,0x21,0x00,0x00,0x02,0x45,0x06,0x00,0x01,0x22,0x00,0x00,0x02,0x80,0x06,0x00,
-0x01,0x23,0x00,0x00,0x02,0x81,0x06,0x00,0x01,0x24,0x00,0x00,0x02,0x82,0x06,0x00,
-0x01,0x25,0x00,0x00,0x02,0x83,0x06,0x00,0x01,0x26,0x00,0x00,0x02,0x84,0x06,0x00,
-0x01,0x27,0x00,0x00,0x02,0x85,0x06,0x00,0x01,0x28,0x00,0x00,0x02,0x88,0x06,0x00,
-0x01,0x29,0x00,0x00,0x02,0x89,0x06,0x00,0x01,0x2a,0x00,0x00,0x02,0x8a,0x06,0x00,
-0x01,0x2b,0x00,0x00,0x02,0x8b,0x06,0x00,0x01,0x2c,0x00,0x00,0x02,0x8c,0x06,0x00,
-0x01,0x2d,0x00,0x00,0x02,0x42,0x07,0x00,0x01,0x2e,0x00,0x00,0x02,0x43,0x07,0x00,
-0x01,0x2f,0x00,0x00,0x02,0x44,0x07,0x00,0x01,0x30,0x00,0x00,0x02,0x45,0x07,0x00,
-0x01,0x31,0x00,0x00,0x02,0x80,0x07,0x00,0x01,0x32,0x00,0x00,0x02,0x81,0x07,0x00,
-0x01,0x33,0x00,0x00,0x02,0x82,0x07,0x00,0x01,0x34,0x00,0x00,0x02,0x83,0x07,0x00,
-0x01,0x35,0x00,0x00,0x02,0x84,0x07,0x00,0x01,0x36,0x00,0x00,0x02,0x85,0x07,0x00,
-0x01,0x37,0x00,0x00,0x02,0x88,0x07,0x00,0x01,0x38,0x00,0x00,0x02,0x89,0x07,0x00,
-0x01,0x39,0x00,0x00,0x02,0x8a,0x07,0x00,0x01,0x3a,0x00,0x00,0x02,0x8b,0x07,0x00,
-0x01,0x3b,0x00,0x00,0x02,0x8c,0x07,0x00,0x01,0x3c,0x00,0x00,0x02,0x8d,0x07,0x00,
-0x01,0x3d,0x00,0x00,0x02,0x90,0x07,0x00,0x01,0x3e,0x00,0x00,0x02,0x91,0x07,0x00,
-0x01,0x3f,0x00,0x00,0x02,0x92,0x07,0x00,0x01,0x40,0x00,0x00,0x02,0x93,0x07,0x00,
-0x01,0x41,0x00,0x00,0x02,0x94,0x07,0x00,0x01,0x42,0x00,0x00,0x02,0x95,0x07,0x00,
-0x01,0x43,0x00,0x00,0x02,0x98,0x07,0x00,0x01,0x44,0x00,0x00,0x02,0x99,0x07,0x00,
-0x01,0x45,0x00,0x00,0x02,0x9a,0x07,0x00,0x01,0x46,0x00,0x00,0x02,0x9b,0x07,0x00,
-0x01,0x47,0x00,0x00,0x02,0x9c,0x07,0x00,0x01,0x48,0x00,0x00,0x02,0x9d,0x07,0x00,
-0x01,0x49,0x00,0x00,0x02,0xa0,0x07,0x00,0x01,0x4a,0x00,0x00,0x02,0xa1,0x07,0x00,
-0x01,0x4b,0x00,0x00,0x02,0xa2,0x07,0x00,0x01,0x4c,0x00,0x00,0x02,0xa3,0x07,0x00,
-0x01,0x4d,0x00,0x00,0x02,0xa4,0x07,0x00,0x01,0x4e,0x00,0x00,0x02,0xa5,0x07,0x00,
-0x01,0x4f,0x00,0x00,0x02,0xa8,0x07,0x00,0x01,0x50,0x00,0x00,0x02,0xa9,0x07,0x00,
-0x01,0x51,0x00,0x00,0x02,0xaa,0x03,0x00,0x01,0x52,0x00,0x00,0x02,0xab,0x03,0x00,
-0x01,0x53,0x00,0x00,0x02,0xac,0x03,0x00,0x01,0x54,0x00,0x00,0x02,0xad,0x03,0x00,
-0x01,0x55,0x00,0x00,0x02,0xb0,0x03,0x00,0x01,0x56,0x00,0x00,0x02,0xb1,0x03,0x00,
-0x01,0x57,0x00,0x00,0x02,0xb2,0x03,0x00,0x01,0x58,0x00,0x00,0x02,0xb3,0x03,0x00,
-0x01,0x59,0x00,0x00,0x02,0xb4,0x03,0x00,0x01,0x5a,0x00,0x00,0x02,0xb5,0x03,0x00,
-0x01,0x5b,0x00,0x00,0x02,0xb8,0x03,0x00,0x01,0x5c,0x00,0x00,0x02,0xb9,0x03,0x00,
-0x01,0x5d,0x00,0x00,0x02,0xba,0x03,0x00,0x01,0x5e,0x00,0x00,0x02,0xbb,0x03,0x00,
-0x01,0x5f,0x00,0x00,0x02,0xbb,0x03,0x00,0x03,0x80,0x00,0x00,0x05,0x04,0x00,0x00,
-0x00,0xb7,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,
-0x02,0x4d,0x0c,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x02,0x4d,0x04,0x00,
-0x00,0xbf,0x02,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0xb7,0x00,0x00,
-0x01,0xe0,0x0e,0x00,0x02,0x4d,0x04,0x00,0x03,0x41,0x04,0x00,0x04,0xc3,0x08,0x00,
-0x05,0x72,0x0c,0x00,0x06,0xe6,0x00,0x00,0x07,0x2a,0x08,0x00,0x08,0x3f,0x00,0x00,
-0x09,0x35,0x03,0x00,0x0a,0xd4,0x09,0x00,0x0b,0xbb,0x07,0x00,0x0c,0x50,0x08,0x00,
-0x0d,0xdf,0x0c,0x00,0x0e,0x2b,0x00,0x00,0x0f,0x14,0x01,0x00,0x00,0xb7,0x01,0x00,
-0x01,0x01,0x00,0x00,0x02,0x00,0x04,0x00,0x01,0x02,0x00,0x00,0x02,0x01,0x04,0x00,
-0x01,0x03,0x00,0x00,0x02,0x02,0x04,0x00,0x01,0x04,0x00,0x00,0x02,0x03,0x04,0x00,
-0x01,0x05,0x00,0x00,0x02,0x04,0x04,0x00,0x01,0x06,0x00,0x00,0x02,0x05,0x04,0x00,
-0x01,0x07,0x00,0x00,0x02,0x08,0x04,0x00,0x01,0x08,0x00,0x00,0x02,0x09,0x04,0x00,
-0x01,0x09,0x00,0x00,0x02,0x0a,0x04,0x00,0x01,0x0a,0x00,0x00,0x02,0x0b,0x04,0x00,
-0x01,0x0b,0x00,0x00,0x02,0x02,0x05,0x00,0x01,0x0c,0x00,0x00,0x02,0x03,0x05,0x00,
-0x01,0x0d,0x00,0x00,0x02,0x04,0x05,0x00,0x01,0x0e,0x00,0x00,0x02,0x05,0x05,0x00,
-0x01,0x0f,0x00,0x00,0x02,0x40,0x05,0x00,0x01,0x10,0x00,0x00,0x02,0x41,0x05,0x00,
-0x01,0x11,0x00,0x00,0x02,0x42,0x05,0x00,0x01,0x12,0x00,0x00,0x02,0x43,0x05,0x00,
-0x01,0x13,0x00,0x00,0x02,0x44,0x05,0x00,0x01,0x14,0x00,0x00,0x02,0x45,0x05,0x00,
-0x01,0x15,0x00,0x00,0x02,0x80,0x05,0x00,0x01,0x16,0x00,0x00,0x02,0x81,0x05,0x00,
-0x01,0x17,0x00,0x00,0x02,0x82,0x05,0x00,0x01,0x18,0x00,0x00,0x02,0x83,0x05,0x00,
-0x01,0x19,0x00,0x00,0x02,0x84,0x05,0x00,0x01,0x1a,0x00,0x00,0x02,0x85,0x05,0x00,
-0x01,0x1b,0x00,0x00,0x02,0x88,0x05,0x00,0x01,0x1c,0x00,0x00,0x02,0x89,0x05,0x00,
-0x01,0x1d,0x00,0x00,0x02,0x8a,0x05,0x00,0x01,0x1e,0x00,0x00,0x02,0x8b,0x05,0x00,
-0x01,0x1f,0x00,0x00,0x02,0x43,0x06,0x00,0x01,0x20,0x00,0x00,0x02,0x44,0x06,0x00,
-0x01,0x21,0x00,0x00,0x02,0x45,0x06,0x00,0x01,0x22,0x00,0x00,0x02,0x80,0x06,0x00,
-0x01,0x23,0x00,0x00,0x02,0x81,0x06,0x00,0x01,0x24,0x00,0x00,0x02,0x82,0x06,0x00,
-0x01,0x25,0x00,0x00,0x02,0x83,0x06,0x00,0x01,0x26,0x00,0x00,0x02,0x84,0x06,0x00,
-0x01,0x27,0x00,0x00,0x02,0x85,0x06,0x00,0x01,0x28,0x00,0x00,0x02,0x88,0x06,0x00,
-0x01,0x29,0x00,0x00,0x02,0x89,0x06,0x00,0x01,0x2a,0x00,0x00,0x02,0x8a,0x06,0x00,
-0x01,0x2b,0x00,0x00,0x02,0x8b,0x06,0x00,0x01,0x2c,0x00,0x00,0x02,0x8c,0x06,0x00,
-0x01,0x2d,0x00,0x00,0x02,0x42,0x07,0x00,0x01,0x2e,0x00,0x00,0x02,0x43,0x07,0x00,
-0x01,0x2f,0x00,0x00,0x02,0x44,0x07,0x00,0x01,0x30,0x00,0x00,0x02,0x45,0x07,0x00,
-0x01,0x31,0x00,0x00,0x02,0x80,0x07,0x00,0x01,0x32,0x00,0x00,0x02,0x81,0x07,0x00,
-0x01,0x33,0x00,0x00,0x02,0x82,0x07,0x00,0x01,0x34,0x00,0x00,0x02,0x83,0x07,0x00,
-0x01,0x35,0x00,0x00,0x02,0x84,0x07,0x00,0x01,0x36,0x00,0x00,0x02,0x85,0x07,0x00,
-0x01,0x37,0x00,0x00,0x02,0x88,0x07,0x00,0x01,0x38,0x00,0x00,0x02,0x89,0x07,0x00,
-0x01,0x39,0x00,0x00,0x02,0x8a,0x07,0x00,0x01,0x3a,0x00,0x00,0x02,0x8b,0x07,0x00,
-0x01,0x3b,0x00,0x00,0x02,0x8c,0x07,0x00,0x01,0x3c,0x00,0x00,0x02,0x8d,0x07,0x00,
-0x01,0x3d,0x00,0x00,0x02,0x90,0x07,0x00,0x01,0x3e,0x00,0x00,0x02,0x91,0x07,0x00,
-0x01,0x3f,0x00,0x00,0x02,0x92,0x07,0x00,0x01,0x40,0x00,0x00,0x02,0x93,0x07,0x00,
-0x01,0x41,0x00,0x00,0x02,0x94,0x07,0x00,0x01,0x42,0x00,0x00,0x02,0x95,0x07,0x00,
-0x01,0x43,0x00,0x00,0x02,0x98,0x07,0x00,0x01,0x44,0x00,0x00,0x02,0x99,0x07,0x00,
-0x01,0x45,0x00,0x00,0x02,0x9a,0x07,0x00,0x01,0x46,0x00,0x00,0x02,0x9b,0x07,0x00,
-0x01,0x47,0x00,0x00,0x02,0x9c,0x07,0x00,0x01,0x48,0x00,0x00,0x02,0x9d,0x07,0x00,
-0x01,0x49,0x00,0x00,0x02,0xa0,0x07,0x00,0x01,0x4a,0x00,0x00,0x02,0xa1,0x07,0x00,
-0x01,0x4b,0x00,0x00,0x02,0xa2,0x07,0x00,0x01,0x4c,0x00,0x00,0x02,0xa3,0x07,0x00,
-0x01,0x4d,0x00,0x00,0x02,0xa4,0x07,0x00,0x01,0x4e,0x00,0x00,0x02,0xa5,0x07,0x00,
-0x01,0x4f,0x00,0x00,0x02,0xa8,0x07,0x00,0x01,0x50,0x00,0x00,0x02,0xa9,0x07,0x00,
-0x01,0x51,0x00,0x00,0x02,0xaa,0x03,0x00,0x01,0x52,0x00,0x00,0x02,0xab,0x03,0x00,
-0x01,0x53,0x00,0x00,0x02,0xac,0x03,0x00,0x01,0x54,0x00,0x00,0x02,0xad,0x03,0x00,
-0x01,0x55,0x00,0x00,0x02,0xb0,0x03,0x00,0x01,0x56,0x00,0x00,0x02,0xb1,0x03,0x00,
-0x01,0x57,0x00,0x00,0x02,0xb2,0x03,0x00,0x01,0x58,0x00,0x00,0x02,0xb3,0x03,0x00,
-0x01,0x59,0x00,0x00,0x02,0xb4,0x03,0x00,0x01,0x5a,0x00,0x00,0x02,0xb5,0x03,0x00,
-0x01,0x5b,0x00,0x00,0x02,0xb8,0x03,0x00,0x01,0x5c,0x00,0x00,0x02,0xb9,0x03,0x00,
-0x01,0x5d,0x00,0x00,0x02,0xba,0x03,0x00,0x01,0x5e,0x00,0x00,0x02,0xbb,0x03,0x00,
-0x01,0x5f,0x00,0x00,0x02,0xbb,0x03,0x00,0x03,0x80,0x00,0x00,0x05,0x04,0x00,0x00,
-0x00,0xb7,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,
-0x02,0x4d,0x0c,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x02,0x4d,0x04,0x00,
-0x00,0xbf,0x02,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x0a,0x00,0x00,0x00,
-0x4f,0x6e,0x41,0x73,0x73,0x6f,0x63,0x52,0x65,0x71,0x00,0x00,0x4f,0x6e,0x41,0x73,
-0x73,0x6f,0x63,0x52,0x73,0x70,0x00,0x00,0x4f,0x6e,0x52,0x65,0x41,0x73,0x73,0x6f,
-0x63,0x52,0x65,0x71,0x00,0x00,0x00,0x00,0x4f,0x6e,0x52,0x65,0x41,0x73,0x73,0x6f,
-0x63,0x52,0x73,0x70,0x00,0x00,0x00,0x00,0x4f,0x6e,0x50,0x72,0x6f,0x62,0x65,0x52,
-0x65,0x71,0x00,0x00,0x4f,0x6e,0x50,0x72,0x6f,0x62,0x65,0x52,0x73,0x70,0x00,0x00,
-0x44,0x6f,0x52,0x65,0x73,0x65,0x72,0x76,0x65,0x64,0x00,0x00,0x44,0x6f,0x52,0x65,
-0x73,0x65,0x72,0x76,0x65,0x64,0x00,0x00,0x4f,0x6e,0x42,0x65,0x61,0x63,0x6f,0x6e,
-0x00,0x00,0x00,0x00,0x4f,0x6e,0x41,0x54,0x49,0x4d,0x00,0x00,0x4f,0x6e,0x44,0x69,
-0x73,0x61,0x73,0x73,0x6f,0x63,0x00,0x00,0x4f,0x6e,0x41,0x75,0x74,0x68,0x00,0x00,
-0x4f,0x6e,0x44,0x65,0x41,0x75,0x74,0x68,0x00,0x00,0x00,0x00,0x4f,0x6e,0x41,0x63,
-0x74,0x69,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x8b,0x01,0x80,
-0x28,0x14,0x01,0x80,0x10,0x00,0x00,0x00,0x94,0x8b,0x01,0x80,0x30,0x14,0x01,0x80,
-0x20,0x00,0x00,0x00,0xa0,0x8b,0x01,0x80,0x28,0x14,0x01,0x80,0x30,0x00,0x00,0x00,
-0xb0,0x8b,0x01,0x80,0x30,0x14,0x01,0x80,0x40,0x00,0x00,0x00,0xc0,0x8b,0x01,0x80,
-0x38,0x14,0x01,0x80,0x50,0x00,0x00,0x00,0xcc,0x8b,0x01,0x80,0x40,0x14,0x01,0x80,
-0x00,0x00,0x00,0x00,0xd8,0x8b,0x01,0x80,0xa8,0x14,0x01,0x80,0x00,0x00,0x00,0x00,
-0xe4,0x8b,0x01,0x80,0xa8,0x14,0x01,0x80,0x80,0x00,0x00,0x00,0xf0,0x8b,0x01,0x80,
-0x48,0x14,0x01,0x80,0x90,0x00,0x00,0x00,0xfc,0x8b,0x01,0x80,0x50,0x14,0x01,0x80,
-0xa0,0x00,0x00,0x00,0x04,0x8c,0x01,0x80,0x58,0x14,0x01,0x80,0xb0,0x00,0x00,0x00,
-0x10,0x8c,0x01,0x80,0x90,0x14,0x01,0x80,0xc0,0x00,0x00,0x00,0x18,0x8c,0x01,0x80,
-0x98,0x14,0x01,0x80,0xd0,0x00,0x00,0x00,0x24,0x8c,0x01,0x80,0xa0,0x14,0x01,0x80,
-0x00,0x00,0x00,0x00,0xdc,0x8c,0x01,0x80,0xdc,0x8c,0x01,0x80,0x31,0x10,0x10,0x00,
-0x00,0x30,0x00,0x00,0x31,0x20,0x10,0x00,0x00,0x30,0x00,0x00,0x31,0x28,0x10,0x00,
-0x00,0x30,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x30,0x00,0x00,0x31,0x2f,0x10,0x10,
-0x00,0x30,0x00,0x00,0x31,0x30,0x18,0x00,0x00,0x30,0x00,0x00,0x31,0x30,0x20,0x10,
-0x00,0x30,0x00,0x00,0x22,0x20,0x18,0x08,0x00,0x20,0x00,0x00,0x22,0x21,0x14,0x08,
-0x00,0x20,0x00,0x00,0x22,0x21,0x1c,0x08,0x00,0x20,0x00,0x00,0x22,0x21,0x20,0x08,
-0x00,0x20,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x20,0x00,0x00,0x22,0x21,0x20,0x18,
-0x00,0x20,0x00,0x00,0x1a,0x19,0x18,0x10,0x00,0x18,0x00,0x00,0x12,0x11,0x10,0x08,
-0x00,0x10,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x02,
-0x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x06,
-0x00,0x08,0x00,0x00,0x08,0x07,0x06,0x04,0x00,0x06,0x00,0x00,0x06,0x05,0x04,0x02,
-0x00,0x04,0x00,0x00,0x06,0x05,0x04,0x03,0x00,0x04,0x00,0x00,0x05,0x04,0x03,0x02,
-0x00,0x03,0x00,0x00,0x09,0x08,0x07,0x06,0x07,0x06,0x06,0x05,0x05,0x04,0x04,0x03,
-0x06,0x05,0x05,0x04,0x04,0x03,0x03,0x03,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x02,
-0x00,0x09,0x08,0x07,0x06,0x07,0x06,0x06,0x05,0x05,0x04,0x04,0x03,0x05,0x04,0x04,
-0x03,0x03,0x02,0x02,0x02,0x04,0x03,0x03,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,
-0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x08,0x08,0x08,0x08,
-0x20,0x20,0x20,0x20,0x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20,0x30,0x08,0x08,0x08,
-0x08,0x18,0x18,0x18,0x18,0x18,0x20,0x30,0x30,0x10,0x20,0x20,0x20,0x20,0x20,0x30,
-0x30,0x08,0x10,0x20,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x08,0x08,0x08,0x08,
-0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20,
-0x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20,0x20,0x08,0x08,0x08,0x08,0x18,0x18,0x18,
-0x18,0x18,0x20,0x30,0x30,0x10,0x20,0x20,0x20,0x20,0x20,0x30,0x30,0x08,0x10,0x20,
-0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,
-0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x00,
-0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,
-0x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x12,0x11,0x10,0x08,0x00,0x22,
-0x21,0x20,0x18,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,
-0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20,
-0x18,0x00,0x22,0x21,0x1c,0x08,0x00,0x22,0x20,0x18,0x08,0x00,0x0a,0x09,0x08,0x02,
-0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,
-0x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x22,
-0x21,0x1c,0x08,0x00,0x31,0x30,0x18,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,
-0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x1a,0x19,0x18,
-0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,
-0x00,0x1a,0x19,0x18,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x31,0x2c,0x10,0x10,0x00,
-0x31,0x28,0x10,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x22,
-0x21,0x20,0x18,0x00,0x22,0x21,0x20,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x22,0x20,
-0x18,0x08,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2c,0x10,0x10,0x00,0x0a,0x09,0x08,
-0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20,0x18,
-0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2f,0x10,0x10,0x00,0x31,0x2f,0x10,0x10,0x00,
-0x31,0x10,0x10,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x00,0x00,0x0a,0x09,0x08,0x04,
-0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,
-0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,
-0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x12,0x11,
-0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,
-0x04,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,
-0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x1c,0x08,0x00,0x22,0x21,0x14,0x08,0x00,
-0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,
-0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x22,0x21,
-0x20,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x0a,0x09,0x08,
-0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,
-0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,
-0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x31,
-0x2c,0x10,0x10,0x00,0x31,0x28,0x10,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,
-0x20,0x18,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20,0x08,0x00,0x22,0x21,0x14,
-0x08,0x00,0x22,0x20,0x18,0x08,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2c,0x10,0x10,
-0x00,0x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,
-0x22,0x21,0x20,0x18,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2f,0x10,0x10,0x00,0x31,
-0x2f,0x10,0x10,0x00,0x31,0x10,0x10,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x00,0x00,
-0x01,0x02,0x04,0x08,0x02,0x04,0x08,0x0c,0x10,0x18,0x20,0x30,0x02,0x04,0x08,0x0c,
-0x10,0x18,0x20,0x30,0x06,0x0c,0x10,0x18,0x24,0x30,0x3c,0x48,0x48,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x27,0x2c,0x19,0x1b,0x1e,0x20,
-0x23,0x29,0x2a,0x2b,0x00,0x00,0x00,0x00,0x25,0x29,0x2b,0x2e,0x2e,0x00,0x00,0x00,
-0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
-0x18,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,
-0x60,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xd8,0x00,0x00,0x00,
-0x50,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,
-0x40,0x01,0x00,0x00,0x90,0x01,0x00,0x00,0xe0,0x01,0x00,0x00,0x30,0x02,0x00,0x00,
-0x2c,0x01,0x00,0x00,0x40,0x01,0x00,0x00,0xe0,0x01,0x00,0x00,0xd0,0x02,0x00,0x00,
-0x80,0x0c,0x00,0x00,0x80,0x0c,0x00,0x00,0x80,0x0c,0x00,0x00,0xa0,0x0f,0x00,0x00,
-0xa0,0x0f,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
-0x08,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
-0x24,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60,0x00,0x00,0x00,
-0x6c,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x50,0x00,0x00,0x00,
-0x64,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,
-0x18,0x01,0x00,0x00,0x64,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,
-0x68,0x01,0x00,0x00,0x40,0x06,0x00,0x00,0x40,0x06,0x00,0x00,0x40,0x06,0x00,0x00,
-0xd0,0x07,0x00,0x00,0xd0,0x07,0x00,0x00,0x2c,0x05,0x00,0x80,0x20,0x05,0x00,0x80,
-0x14,0x05,0x00,0x80,0x08,0x05,0x00,0x80,0xfc,0x04,0x00,0x80,0xf0,0x04,0x00,0x80,
-0xe4,0x04,0x00,0x80,0xd8,0x04,0x00,0x80,0xcc,0x04,0x00,0x80,0xc0,0x04,0x00,0x80,
-0x78,0x04,0x00,0x80,0x68,0x15,0x02,0x80,0xc0,0x3a,0x00,0x80,0xcc,0x3a,0x00,0x80,
-0xd8,0x3a,0x00,0x80,0xe4,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80,
-0xc0,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80,0xf0,0x3a,0x00,0x80,0xfc,0x3a,0x00,0x80,
-0x08,0x3b,0x00,0x80,0x14,0x3b,0x00,0x80,0x68,0x15,0x02,0x80,0xfe,0x01,0x80,0x7f,
-0xe2,0x01,0x80,0x78,0xc7,0x01,0xc0,0x71,0xae,0x01,0x80,0x6b,0x95,0x01,0x40,0x65,
-0x7f,0x01,0xc0,0x5f,0x69,0x01,0x40,0x5a,0x55,0x01,0x40,0x55,0x42,0x01,0x80,0x50,
-0x30,0x01,0x00,0x4c,0x1f,0x01,0xc0,0x47,0x0f,0x01,0xc0,0x43,0x00,0x01,0x00,0x40,
-0xf2,0x00,0x80,0x3c,0xe4,0x00,0x00,0x39,0xd7,0x00,0xc0,0x35,0xcb,0x00,0xc0,0x32,
-0xc0,0x00,0x00,0x30,0xb5,0x00,0x40,0x2d,0xab,0x00,0xc0,0x2a,0xa2,0x00,0x80,0x28,
-0x98,0x00,0x00,0x26,0x90,0x00,0x00,0x24,0x88,0x00,0x00,0x22,0x80,0x00,0x00,0x20,
-0x79,0x00,0x40,0x1e,0x72,0x00,0x80,0x1c,0x6c,0x00,0x00,0x1b,0x66,0x00,0x80,0x19,
-0x60,0x00,0x00,0x18,0x5b,0x00,0xc0,0x16,0x56,0x00,0x80,0x15,0x51,0x00,0x40,0x14,
-0x4c,0x00,0x00,0x13,0x48,0x00,0x00,0x12,0x44,0x00,0x00,0x11,0x40,0x00,0x00,0x10,
-0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04,0x33,0x32,0x2b,0x23,0x1a,0x11,0x08,0x04,
-0x30,0x2f,0x29,0x21,0x19,0x10,0x08,0x03,0x2d,0x2d,0x27,0x1f,0x18,0x0f,0x08,0x03,
-0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03,0x28,0x28,0x22,0x1c,0x15,0x0d,0x07,0x03,
-0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,0x24,0x23,0x1f,0x19,0x13,0x0c,0x06,0x03,
-0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,0x20,0x20,0x1b,0x16,0x11,0x08,0x05,0x02,
-0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,0x1d,0x1c,0x18,0x14,0x0f,0x0a,0x05,0x02,
-0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,0x1a,0x19,0x16,0x12,0x0d,0x09,0x04,0x02,
-0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,0x17,0x16,0x13,0x10,0x0c,0x08,0x04,0x02,
-0x16,0x15,0x12,0x0f,0x0b,0x07,0x04,0x01,0x14,0x14,0x11,0x0e,0x0b,0x07,0x03,0x02,
-0x13,0x13,0x10,0x0d,0x0a,0x06,0x03,0x01,0x12,0x12,0x0f,0x0c,0x09,0x06,0x03,0x01,
-0x11,0x11,0x0f,0x0c,0x09,0x06,0x03,0x01,0x10,0x10,0x0e,0x0b,0x08,0x05,0x03,0x01,
-0x0f,0x0f,0x0d,0x0b,0x08,0x05,0x03,0x01,0x0e,0x0e,0x0c,0x0a,0x08,0x05,0x02,0x01,
-0x0d,0x0d,0x0c,0x0a,0x07,0x05,0x02,0x01,0x0d,0x0c,0x0b,0x09,0x07,0x04,0x02,0x01,
-0x0c,0x0c,0x0a,0x09,0x06,0x04,0x02,0x01,0x0b,0x0b,0x0a,0x08,0x06,0x04,0x02,0x01,
-0x0b,0x0a,0x09,0x08,0x06,0x04,0x02,0x01,0x0a,0x0a,0x09,0x07,0x05,0x03,0x02,0x01,
-0x0a,0x09,0x08,0x07,0x05,0x03,0x02,0x01,0x09,0x09,0x08,0x06,0x05,0x03,0x01,0x01,
-0x09,0x08,0x07,0x06,0x04,0x03,0x01,0x01,0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00,
-0x33,0x32,0x2b,0x19,0x00,0x00,0x00,0x00,0x30,0x2f,0x29,0x18,0x00,0x00,0x00,0x00,
-0x2d,0x2d,0x17,0x17,0x00,0x00,0x00,0x00,0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00,
-0x28,0x28,0x24,0x14,0x00,0x00,0x00,0x00,0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
-0x24,0x23,0x1f,0x12,0x00,0x00,0x00,0x00,0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
-0x20,0x20,0x1b,0x10,0x00,0x00,0x00,0x00,0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
-0x1d,0x1c,0x18,0x0e,0x00,0x00,0x00,0x00,0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
-0x1a,0x19,0x16,0x0d,0x00,0x00,0x00,0x00,0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
-0x17,0x16,0x13,0x0b,0x00,0x00,0x00,0x00,0x16,0x15,0x12,0x0b,0x00,0x00,0x00,0x00,
-0x14,0x14,0x11,0x0a,0x00,0x00,0x00,0x00,0x13,0x13,0x10,0x0a,0x00,0x00,0x00,0x00,
-0x12,0x12,0x0f,0x09,0x00,0x00,0x00,0x00,0x11,0x11,0x0f,0x09,0x00,0x00,0x00,0x00,
-0x10,0x10,0x0e,0x08,0x00,0x00,0x00,0x00,0x0f,0x0f,0x0d,0x08,0x00,0x00,0x00,0x00,
-0x0e,0x0e,0x0c,0x07,0x00,0x00,0x00,0x00,0x0d,0x0d,0x0c,0x07,0x00,0x00,0x00,0x00,
-0x0d,0x0c,0x0b,0x06,0x00,0x00,0x00,0x00,0x0c,0x0c,0x0a,0x06,0x00,0x00,0x00,0x00,
-0x0b,0x0b,0x0a,0x06,0x00,0x00,0x00,0x00,0x0b,0x0a,0x09,0x05,0x00,0x00,0x00,0x00,
-0x0a,0x0a,0x09,0x05,0x00,0x00,0x00,0x00,0x0a,0x09,0x08,0x05,0x00,0x00,0x00,0x00,
-0x09,0x09,0x08,0x05,0x00,0x00,0x00,0x00,0x09,0x08,0x07,0x04,0x00,0x00,0x00,0x00,
-0x06,0x00,0x2a,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-0x08,0x28,0x28,0x28,0x28,0x28,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xa0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
-0x04,0x04,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x41,0x41,0x41,0x41,0x41,0x41,0x01,
-0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-0x01,0x01,0x01,0x10,0x10,0x10,0x10,0x10,0x10,0x42,0x42,0x42,0x42,0x42,0x42,0x02,
-0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
-0x02,0x02,0x02,0x10,0x10,0x10,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,
-0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
-0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,
-0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x19,0x77,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x26,0x72,0xb0,0x00,0x26,0x72,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x26,0x65,0x60,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x02,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xf2,0x30,0xb8,0xff,0xff,0xff,0xff,
-};
-
u8 Rtl8192SUFwMainArray[MainArrayLength] = {
0x0, };
diff --git a/drivers/staging/rtl8192su/r8192SU_HWImg.h b/drivers/staging/rtl8192su/r8192SU_HWImg.h
index 96b15252ea8..36e84aff6ed 100644
--- a/drivers/staging/rtl8192su/r8192SU_HWImg.h
+++ b/drivers/staging/rtl8192su/r8192SU_HWImg.h
@@ -5,8 +5,6 @@
/*Created on 2009/ 3/ 6, 5:29*/
-#define ImgArrayLength 68368
-extern u8 Rtl8192SUFwImgArray[ImgArrayLength];
#define MainArrayLength 1
extern u8 Rtl8192SUFwMainArray[MainArrayLength];
#define DataArrayLength 1
diff --git a/drivers/staging/rtl8192su/r8192S_firmware.c b/drivers/staging/rtl8192su/r8192S_firmware.c
index 3561adf0468..752a3f1fb3f 100644
--- a/drivers/staging/rtl8192su/r8192S_firmware.c
+++ b/drivers/staging/rtl8192su/r8192S_firmware.c
@@ -360,117 +360,58 @@ bool FirmwareDownload92S(struct net_device *dev)
RT_TRACE(COMP_FIRMWARE, " --->FirmwareDownload92S()\n");
- //3//
- //3 //<1> Open Image file, and map file to contineous memory if open file success.
- //3 // or read image file from array. Default load from BIN file
- //3//
- priv->firmware_source = FW_SOURCE_IMG_FILE;// We should decided by Reg.
-
- switch( priv->firmware_source )
+/*
+* Load the firmware from RTL8192SU/rtl8192sfw.bin
+*/
+ if(pFirmware->szFwTmpBufferLen == 0)
{
- case FW_SOURCE_IMG_FILE:
- if(pFirmware->szFwTmpBufferLen == 0)
- {
-
- rc = request_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev);//===>1
- if(rc < 0 ) {
- RT_TRACE(COMP_ERR, "request firmware fail!\n");
- goto DownloadFirmware_Fail;
- }
-
- if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer))
- {
- RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
- release_firmware(fw_entry);
- goto DownloadFirmware_Fail;
- }
+ rc = request_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev);
+ if(rc < 0 ) {
+ RT_TRACE(COMP_ERR, "request firmware fail!\n");
+ goto DownloadFirmware_Fail;
+ }
- memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size);
- pFirmware->szFwTmpBufferLen = fw_entry->size;
+ if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) {
+ RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
release_firmware(fw_entry);
-
- pucMappedFile = pFirmware->szFwTmpBuffer;
- file_length = pFirmware->szFwTmpBufferLen;
-
- //Retrieve FW header.
- pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;
- pFwHdr = pFirmware->pFwHeader;
- RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \
- pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \
- pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE);
- pFirmware->FirmwareVersion = byte(pFwHdr->Version ,0);
- if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM)))
- {
- RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\
- __FUNCTION__);
- goto DownloadFirmware_Fail;
- } else {
- pucMappedFile+=FwHdrSize;
-
- //Retrieve IMEM image.
- memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
- pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;
- }
-
- if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM))
- {
- RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\
- __FUNCTION__);
- goto DownloadFirmware_Fail;
- } else {
- pucMappedFile += pFirmware->FwIMEMLen;
-
- /* Retriecve EMEM image */
- memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);//===>6
- pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;
- }
-
-
+ goto DownloadFirmware_Fail;
}
- break;
- case FW_SOURCE_HEADER_FILE:
-#if 1
-#define Rtl819XFwImageArray Rtl8192SUFwImgArray
- //2008.11.10 Add by tynli.
- pucMappedFile = Rtl819XFwImageArray;
- ulFileLength = ImgArrayLength;
+ memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size);
+ pFirmware->szFwTmpBufferLen = fw_entry->size;
+ release_firmware(fw_entry);
+
+ pucMappedFile = pFirmware->szFwTmpBuffer;
+ file_length = pFirmware->szFwTmpBufferLen;
- RT_TRACE(COMP_INIT,"Fw download from header.\n");
- /* Retrieve FW header*/
+ /* Retrieve FW header. */
pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;
pFwHdr = pFirmware->pFwHeader;
RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \
pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \
pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE);
pFirmware->FirmwareVersion = byte(pFwHdr->Version ,0);
-
- if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM)))
- {
- printk("FirmwareDownload92S(): memory for data image is less than IMEM required\n");
+ if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) {
+ RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\
+ __FUNCTION__);
goto DownloadFirmware_Fail;
} else {
pucMappedFile+=FwHdrSize;
- //Retrieve IMEM image.
+ /* Retrieve IMEM image. */
memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;
}
- if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM))
- {
- printk(" FirmwareDownload92S(): memory for data image is less than EMEM required\n");
- goto DownloadFirmware_Fail;
- } else {
- pucMappedFile+= pFirmware->FwIMEMLen;
-
- //Retriecve EMEM image.
- memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);
- pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;
- }
-#endif
- break;
- default:
- break;
+ if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) {
+ RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\
+ __FUNCTION__);
+ goto DownloadFirmware_Fail;
+ } else {
+ pucMappedFile += pFirmware->FwIMEMLen;
+ /* Retriecve EMEM image */
+ memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);//===>6
+ pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;
+ }
}
FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
@@ -538,3 +479,4 @@ bool FirmwareDownload92S(struct net_device *dev)
return rtStatus;
}
+MODULE_FIRMWARE("RTL8192SU/rtl8192sfw.bin");
diff --git a/drivers/staging/rtl8192su/r8192S_firmware.h b/drivers/staging/rtl8192su/r8192S_firmware.h
index c525380e647..2c2cf8032de 100644
--- a/drivers/staging/rtl8192su/r8192S_firmware.h
+++ b/drivers/staging/rtl8192su/r8192S_firmware.h
@@ -59,12 +59,6 @@ typedef enum _desc_packet_type_e{
DESC_PACKET_TYPE_NORMAL = 1,
}desc_packet_type_e;
-typedef enum _firmware_source{
- FW_SOURCE_IMG_FILE = 0,
- FW_SOURCE_HEADER_FILE = 1,
-}firmware_source_e, *pfirmware_source_e;
-
-
typedef enum _opt_rst_type{
OPT_SYSTEM_RESET = 0,
OPT_FIRMWARE_RESET = 1,
@@ -185,7 +179,6 @@ typedef enum _FIRMWARE_8192S_STATUS{
#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k
typedef struct _rt_firmware{
- firmware_source_e eFWSource;
PRT_8192S_FIRMWARE_HDR pFwHeader;
FIRMWARE_8192S_STATUS FWStatus;
u16 FirmwareVersion;
diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c
index 77ab026288d..63d4e5fd7b1 100644
--- a/drivers/staging/rtl8192su/r8192S_phy.c
+++ b/drivers/staging/rtl8192su/r8192S_phy.c
@@ -2407,8 +2407,8 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
break;
default:
- RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci():\
- unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
+ RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n",
+ priv->CurrentChannelBW);
break;
}
@@ -3398,8 +3398,8 @@ void SwChnlCallback8192SUsb(struct net_device *dev)
u32 delay;
// bool ret;
- RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel\
- %d\n", priv->chan);
+ RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel %d\n",
+ priv->chan);
if(!priv->up)
@@ -3525,8 +3525,8 @@ void SetBWModeCallback8192SUsb(struct net_device *dev)
break;
default:
- RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci():\
- unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
+ RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n",
+ priv->CurrentChannelBW);
break;
}
@@ -3660,8 +3660,8 @@ void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev)
break;
default:
- RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem():\
- unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
+ RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem(): unknown Bandwidth: %#X\n",
+ priv->CurrentChannelBW);
break;
}
diff --git a/drivers/staging/rtl8192su/r8192U.h b/drivers/staging/rtl8192su/r8192U.h
index 2a11e0113d3..ba87623f32e 100644
--- a/drivers/staging/rtl8192su/r8192U.h
+++ b/drivers/staging/rtl8192su/r8192U.h
@@ -1258,7 +1258,6 @@ typedef struct r8192_priv
u8 Rf_Mode; //add for Firmware RF -R/W switch
prt_firmware pFirmware;
rtl819xUsb_loopback_e LoopbackMode;
- firmware_source_e firmware_source;
bool usb_error;
u16 EEPROMTxPowerDiff;
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c
index 6f424fe8a23..04d9b85f3d4 100644
--- a/drivers/staging/rtl8192su/r8192U_core.c
+++ b/drivers/staging/rtl8192su/r8192U_core.c
@@ -25,6 +25,7 @@
*/
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#undef LOOP_TEST
#undef DUMP_RX
@@ -110,16 +111,19 @@ u32 rt_global_debug_component = \
#define TOTAL_CAM_ENTRY 32
#define CAM_CONTENT_COUNT 8
-static struct usb_device_id rtl8192_usb_id_tbl[] = {
+static const struct usb_device_id rtl8192_usb_id_tbl[] = {
/* Realtek */
+ {USB_DEVICE(0x0bda, 0x8171)},
{USB_DEVICE(0x0bda, 0x8192)},
{USB_DEVICE(0x0bda, 0x8709)},
/* Corega */
{USB_DEVICE(0x07aa, 0x0043)},
/* Belkin */
{USB_DEVICE(0x050d, 0x805E)},
+ {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */
/* Sitecom */
{USB_DEVICE(0x0df6, 0x0031)},
+ {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
/* EnGenius */
{USB_DEVICE(0x1740, 0x9201)},
/* Dlink */
@@ -2340,25 +2344,24 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
skb->len, rtl8192_tx_isr, skb);
status = usb_submit_urb(tx_urb, GFP_ATOMIC);
- if (!status){
-//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
+ if (!status) {
+ /*
+ * we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted.
+ * Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
+ */
bool bSend0Byte = false;
u8 zero = 0;
- if(udev->speed == USB_SPEED_HIGH)
- {
+ if(udev->speed == USB_SPEED_HIGH) {
if (skb->len > 0 && skb->len % 512 == 0)
bSend0Byte = true;
}
- else
- {
+ else {
if (skb->len > 0 && skb->len % 64 == 0)
bSend0Byte = true;
}
- if (bSend0Byte)
- {
-#if 1
+ if (bSend0Byte) {
tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
- if(!tx_urb_zero){
+ if(!tx_urb_zero) {
RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
return -ENOMEM;
}
@@ -2366,16 +2369,23 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
usb_sndbulkpipe(udev,idx_pipe), &zero,
0, tx_zero_isr, dev);
status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
- if (status){
- RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
- return -1;
+ switch (status) {
+ case 0:
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ break;
+ default:
+ RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d",
+ atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
+ return -1;
}
-#endif
}
dev->trans_start = jiffies;
atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
return 0;
- }else{
+ } else {
RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
status);
return -1;
@@ -2952,7 +2962,7 @@ void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
wireless_mode = WIRELESS_MODE_B;
}
}
-#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
#endif
//LZM 090306 usb crash here, mark it temp
@@ -3359,6 +3369,46 @@ u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype)
return RFtype;
}
+void update_hal_variables(struct r8192_priv *priv)
+{
+ int rf_path;
+ int i;
+ u8 index;
+
+ for (rf_path = 0; rf_path < 2; rf_path++) {
+ for (i = 0; i < 3; i++) {
+ RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfCckChnlAreaTxPwr[rf_path][i]);
+ RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
+ RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
+ }
+ /* Assign dedicated channel tx power */
+ for(i = 0; i < 14; i++) {
+ /* channel 1-3 use the same Tx Power Level. */
+ if (i < 3) /* Channel 1-3 */
+ index = 0;
+ else if (i < 9) /* Channel 4-9 */
+ index = 1;
+ else /* Channel 10-14 */
+ index = 2;
+ /* Record A & B CCK /OFDM - 1T/2T Channel area tx power */
+ priv->RfTxPwrLevelCck[rf_path][i] = priv->RfCckChnlAreaTxPwr[rf_path][index];
+ priv->RfTxPwrLevelOfdm1T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
+ priv->RfTxPwrLevelOfdm2T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
+ if (rf_path == 0) {
+ priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
+ priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
+ }
+ }
+ for(i = 0; i < 14; i++) {
+ RT_TRACE((COMP_INIT),
+ "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
+ rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
+ priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
+ priv->RfTxPwrLevelOfdm2T[rf_path][i] );
+ }
+ }
+}
+
//
// Description:
// Config HW adapter information into initial value.
@@ -3374,7 +3424,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
struct r8192_priv *priv = ieee80211_priv(dev);
//u16 i,usValue;
//u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
- u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117
+ u8 rf_path; // For EEPROM/EFUSE After V0.6_1117
int i;
RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
@@ -3426,10 +3476,9 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
- RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
- dev->dev_addr[0], dev->dev_addr[1],
- dev->dev_addr[2], dev->dev_addr[3],
- dev->dev_addr[4], dev->dev_addr[5]);
+ RT_TRACE(COMP_INIT,
+ "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
+ dev->dev_addr);
priv->EEPROMBoardType = EEPROM_Default_BoardType;
priv->rf_type = RF_1T2R; //RF_2T2R
@@ -3455,42 +3504,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
}
}
- for (i = 0; i < 3; i++)
- {
- //RT_TRACE((COMP_EFUSE), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
- //priv->RfCckChnlAreaTxPwr[rf_path][i]);
- //RT_TRACE((COMP_EFUSE), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
- //priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
- //RT_TRACE((COMP_EFUSE), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
- //priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
- }
-
- // Assign dedicated channel tx power
- for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
- {
- if (i < 3) // Cjanel 1-3
- index = 0;
- else if (i < 9) // Channel 4-9
- index = 1;
- else // Channel 10-14
- index = 2;
-
- // Record A & B CCK /OFDM - 1T/2T Channel area tx power
- priv->RfTxPwrLevelCck[rf_path][i] =
- priv->RfCckChnlAreaTxPwr[rf_path][index];
- priv->RfTxPwrLevelOfdm1T[rf_path][i] =
- priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
- priv->RfTxPwrLevelOfdm2T[rf_path][i] =
- priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
- }
-
- for(i=0; i<14; i++)
- {
- //RT_TRACE((COMP_EFUSE), "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
- //rf_path, i, priv->RfTxPwrLevelCck[0][i],
- //priv->RfTxPwrLevelOfdm1T[0][i] ,
- //priv->RfTxPwrLevelOfdm2T[0][i] );
- }
+ update_hal_variables(priv);
//
// Update remained HAL variables.
@@ -3767,10 +3781,9 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
- RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
- dev->dev_addr[0], dev->dev_addr[1],
- dev->dev_addr[2], dev->dev_addr[3],
- dev->dev_addr[4], dev->dev_addr[5]);
+ RT_TRACE(COMP_INIT,
+ "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
+ dev->dev_addr);
//
// Get CustomerID(Boad Type)
@@ -3901,53 +3914,7 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
}
}
-//
- // Update Tx Power HAL variables.
-//
- for (rf_path = 0; rf_path < 2; rf_path++)
- {
- for (i = 0; i < 3; i++)
- {
- RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
- priv->RfCckChnlAreaTxPwr[rf_path][i]);
- RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
- priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
- RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
- }
-
- // Assign dedicated channel tx power
- for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
- {
- if (i < 3) // Cjanel 1-3
- index = 0;
- else if (i < 9) // Channel 4-9
- index = 1;
- else // Channel 10-14
- index = 2;
-
- // Record A & B CCK /OFDM - 1T/2T Channel area tx power
- priv->RfTxPwrLevelCck[rf_path][i] =
- priv->RfCckChnlAreaTxPwr[rf_path][index];
- priv->RfTxPwrLevelOfdm1T[rf_path][i] =
- priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
- priv->RfTxPwrLevelOfdm2T[rf_path][i] =
- priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
- if (rf_path == 0)
- {
- priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
- priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
- }
- }
-
- for(i=0; i<14; i++)
- {
- RT_TRACE((COMP_INIT),
- "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
- rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
- priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
- priv->RfTxPwrLevelOfdm2T[rf_path][i] );
- }
- }
+ update_hal_variables(priv);
}
//
@@ -7677,7 +7644,7 @@ void setKey( struct net_device *dev,
if (EntryNo >= TOTAL_CAM_ENTRY)
RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
- RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
+ RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
if (DefaultKey)
usConfig |= BIT15 | (KeyType<<2);
diff --git a/drivers/staging/rtl8192su/r8192U_dm.c b/drivers/staging/rtl8192su/r8192U_dm.c
index 7891e964027..fa5e24416dd 100644
--- a/drivers/staging/rtl8192su/r8192U_dm.c
+++ b/drivers/staging/rtl8192su/r8192U_dm.c
@@ -2697,7 +2697,7 @@ static void dm_check_edca_turbo(
u8* peername[11] = {"unknown", "realtek", "realtek_92se", "broadcom", "ralink", "atheros", "cisco", "marvell", "92u_softap", "self_softap"};
static int wb_tmp = 0;
if (wb_tmp == 0){
- printk("%s():iot peer is %#x:%s, bssid:"MAC_FMT"\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], MAC_ARG(priv->ieee80211->current_network.bssid));
+ printk("%s():iot peer is %#x:%s, bssid:%pM\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], priv->ieee80211->current_network.bssid);
wb_tmp = 1;
}
}
diff --git a/drivers/staging/rtl8192u/Kconfig b/drivers/staging/rtl8192u/Kconfig
index 9913ab8fb35..0439c90b416 100644
--- a/drivers/staging/rtl8192u/Kconfig
+++ b/drivers/staging/rtl8192u/Kconfig
@@ -1,6 +1,7 @@
config RTL8192U
tristate "RealTek RTL8192U Wireless LAN NIC driver"
depends on PCI && WLAN && USB
- depends on WIRELESS_EXT
+ select WIRELESS_EXT
+ select WEXT_PRIV
default N
---help---
diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile
index 2d59c4ef6c5..738f4a80ec6 100644
--- a/drivers/staging/rtl8192u/Makefile
+++ b/drivers/staging/rtl8192u/Makefile
@@ -3,7 +3,7 @@ NIC_SELECT = RTL8192U
EXTRA_CFLAGS += -std=gnu89
EXTRA_CFLAGS += -O2
-EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
+EXTRA_CFLAGS += -DCONFIG_FORCE_HARD_FLOAT=y
EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
#EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE
diff --git a/drivers/staging/rtl8192u/ieee80211.h b/drivers/staging/rtl8192u/ieee80211.h
index 3a47f1213e8..9d05ed6791e 100644
--- a/drivers/staging/rtl8192u/ieee80211.h
+++ b/drivers/staging/rtl8192u/ieee80211.h
@@ -551,9 +551,6 @@ do { if (ieee80211_debug_level & (level)) \
/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
/*
* To use the debug system;
*
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
index 10908e123b8..39847c81e29 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
@@ -30,6 +30,7 @@
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/sched.h>
+#include <linux/semaphore.h>
#include <linux/delay.h>
#include <linux/wireless.h>
@@ -551,9 +552,6 @@ do { if (ieee80211_debug_level & (level)) \
/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
/*
* To use the debug system;
*
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
index 0b33bf46332..0b57632bcff 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
@@ -288,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: received packet without ExtIV"
- " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ " flag from %pM\n", hdr->addr2);
}
key->dot11RSNAStatsCCMPFormatErrors++;
return -2;
@@ -301,9 +301,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!key->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+ printk(KERN_DEBUG "CCMP: received packet from %pM"
" with keyid=%d that does not have a configured"
- " key\n", MAC_ARG(hdr->addr2), keyidx);
+ " key\n", hdr->addr2, keyidx);
}
return -3;
}
@@ -318,11 +318,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
- " previous PN %02x%02x%02x%02x%02x%02x "
- "received PN %02x%02x%02x%02x%02x%02x\n",
- MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
- MAC_ARG(pn));
+ printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
+ " previous PN %pm received PN %pm\n",
+ hdr->addr2, key->rx_pn, pn);
}
key->dot11RSNAStatsCCMPReplays++;
return -4;
@@ -359,7 +357,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: decrypt failed: STA="
- MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ "%pM\n", hdr->addr2);
}
key->dot11RSNAStatsCCMPDecryptErrors++;
return -5;
@@ -435,11 +433,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
{
struct ieee80211_ccmp_data *ccmp = priv;
p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
+ "tx_pn=%pm rx_pn=%pm "
"format_errors=%d replays=%d decrypt_errors=%d\n",
ccmp->key_idx, ccmp->key_set,
- MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+ ccmp->tx_pn, ccmp->rx_pn,
ccmp->dot11RSNAStatsCCMPFormatErrors,
ccmp->dot11RSNAStatsCCMPReplays,
ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
index 841b99955b7..9510507d8d0 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
@@ -410,7 +410,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (!(keyidx & (1 << 5))) {
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ " flag from %pM\n", hdr->addr2);
}
return -2;
}
@@ -422,9 +422,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (!tkey->key_set) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+ printk(KERN_DEBUG "TKIP: received packet from %pM"
" with keyid=%d that does not have a configured"
- " key\n", MAC_ARG(hdr->addr2), keyidx);
+ " key\n", hdr->addr2, keyidx);
}
return -3;
}
@@ -437,9 +437,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (iv32 < tkey->rx_iv32 ||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+ printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
" previous TSC %08x%04x received TSC "
- "%08x%04x\n", MAC_ARG(hdr->addr2),
+ "%08x%04x\n", hdr->addr2,
tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
}
tkey->dot11RSNAStatsTKIPReplays++;
@@ -460,8 +460,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
if (net_ratelimit()) {
printk(KERN_DEBUG ": TKIP: failed to decrypt "
- "received packet from " MAC_FMT "\n",
- MAC_ARG(hdr->addr2));
+ "received packet from %pM\n",
+ hdr->addr2);
}
return -7;
}
@@ -480,7 +480,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
}
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: ICV error detected: STA="
- MAC_FMT "\n", MAC_ARG(hdr->addr2));
+ "%pM\n", hdr->addr2);
}
tkey->dot11RSNAStatsTKIPICVErrors++;
return -5;
@@ -635,8 +635,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
struct ieee80211_hdr_4addr *hdr;
hdr = (struct ieee80211_hdr_4addr *) skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- "MSDU from " MAC_FMT " keyidx=%d\n",
- skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+ "MSDU from %pM keyidx=%d\n",
+ skb->dev ? skb->dev->name : "N/A", hdr->addr2,
keyidx);
if (skb->dev)
ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
index 7a8690f449b..b752017a4d1 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
@@ -260,7 +260,7 @@ static int store_debug_level(struct file *file, const char *buffer,
unsigned long count, void *data)
{
char buf[] = "0x00000000";
- unsigned long len = min(sizeof(buf) - 1, count);
+ unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
char *p = (char *)buf;
unsigned long val;
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
index 0e003c5bb00..7e9b367594a 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -360,8 +360,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
strcmp(crypt->ops->name, "TKIP") == 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "received packet from " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(hdr->addr2));
+ "received packet from %pM\n",
+ ieee->dev->name, hdr->addr2);
}
return -1;
}
@@ -372,8 +372,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
atomic_dec(&crypt->refcnt);
if (res < 0) {
IEEE80211_DEBUG_DROP(
- "decryption failed (SA=" MAC_FMT
- ") res=%d\n", MAC_ARG(hdr->addr2), res);
+ "decryption failed (SA=%pM"
+ ") res=%d\n", hdr->addr2, res);
if (res == -2)
IEEE80211_DEBUG_DROP("Decryption failed ICV "
"mismatch (key %d)\n",
@@ -410,8 +410,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
atomic_dec(&crypt->refcnt);
if (res < 0) {
printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- " (SA=" MAC_FMT " keyidx=%d)\n",
- ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+ " (SA=%pM keyidx=%d)\n",
+ ieee->dev->name, hdr->addr2, keyidx);
return -1;
}
@@ -1016,8 +1016,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
* frames silently instead of filling system log with
* these reports. */
IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ " (SA=%pM)\n",
+ hdr->addr2);
ieee->ieee_stats.rx_discards_undecryptable++;
goto rx_dropped;
}
@@ -1256,8 +1256,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
} else {
IEEE80211_DEBUG_DROP(
"encryption configured, but RX "
- "frame not encrypted (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ "frame not encrypted (SA=%pM)\n",
+ hdr->addr2);
goto rx_dropped;
}
}
@@ -1276,9 +1276,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
!ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
IEEE80211_DEBUG_DROP(
"dropped unencrypted RX data "
- "frame from " MAC_FMT
+ "frame from %pM"
" (drop_unencrypted=1)\n",
- MAC_ARG(hdr->addr2));
+ hdr->addr2);
goto rx_dropped;
}
/*
@@ -2260,11 +2260,11 @@ static inline int ieee80211_network_init(
}
if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+ IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
"network.\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid));
+ network->bssid);
return 1;
}
@@ -2439,9 +2439,9 @@ static inline void ieee80211_process_probe_response(
memset(&network, 0, sizeof(struct ieee80211_network));
IEEE80211_DEBUG_SCAN(
- "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+ "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
escape_essid(info_element->data, info_element->len),
- MAC_ARG(beacon->header.addr3),
+ beacon->header.addr3,
(beacon->capability & (1<<0xf)) ? '1' : '0',
(beacon->capability & (1<<0xe)) ? '1' : '0',
(beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2460,10 +2460,10 @@ static inline void ieee80211_process_probe_response(
(beacon->capability & (1<<0x0)) ? '1' : '0');
if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
escape_essid(info_element->data,
info_element->len),
- MAC_ARG(beacon->header.addr3),
+ beacon->header.addr3,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -2574,11 +2574,11 @@ static inline void ieee80211_process_probe_response(
/* If there are no more slots, expire the oldest */
list_del(&oldest->list);
target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+ IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
"network list.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid));
+ target->bssid);
} else {
/* Otherwise just pull from the free list */
target = list_entry(ieee->network_free_list.next,
@@ -2588,10 +2588,10 @@ static inline void ieee80211_process_probe_response(
#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
escape_essid(network.ssid,
network.ssid_len),
- MAC_ARG(network.bssid),
+ network.bssid,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
@@ -2601,10 +2601,10 @@ static inline void ieee80211_process_probe_response(
if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
ieee80211_softmac_new_net(ieee,&network);
} else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid),
+ target->bssid,
WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
index 8a86e93465c..d54e3a77423 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
@@ -18,6 +18,7 @@
#include <linux/random.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#ifdef ENABLE_DOT11D
@@ -1731,7 +1732,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
ieee80211_resp_to_assoc_rq(ieee, dest);
}
- printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+ printk(KERN_INFO"New client associated: %pM\n", dest);
//FIXME
}
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
index b29c36bac37..48537d94894 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
@@ -200,8 +200,8 @@ int ieee80211_encrypt_fragment(
header = (struct ieee80211_hdr *) frag->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "TX packet to " MAC_FMT "\n",
- ieee->dev->name, MAC_ARG(header->addr1));
+ "TX packet to %pM\n",
+ ieee->dev->name, header->addr1);
}
return -1;
}
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
index 5f12d62658c..750e94e1711 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
@@ -32,6 +32,7 @@
#include <linux/wireless.h>
#include <linux/version.h>
#include <linux/kmod.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include "ieee80211.h"
@@ -289,10 +290,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
else
IEEE80211_DEBUG_SCAN(
"Not showing network '%s ("
- MAC_FMT ")' due to age (%lums).\n",
+ "%pM)' due to age (%lums).\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid),
+ network->bssid,
(jiffies - network->last_scanned) / (HZ / 100));
}
@@ -718,7 +719,7 @@ int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
} else
idx = ieee->tx_keyidx;
- if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
+ if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
ext->alg != IW_ENCODE_ALG_WEP)
if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
return -EINVAL;
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
index 512a57aebde..27d083a70eb 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
u16 tmp = 0;
u16 len = ieee->tx_headroom + 9;
//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+ IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
if (pBA == NULL||ieee == NULL)
{
IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -201,7 +201,7 @@ static struct sk_buff* ieee80211_DELBA(
u16 len = 6 + ieee->tx_headroom;
if (net_ratelimit())
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+ IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
memset(&DelbaParamSet, 0, 2);
@@ -355,7 +355,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
pBaTimeoutVal = (u16*)(tag + 5);
pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
- printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
+ printk("====================>rx ADDBAREQ from :%pM\n", dst);
//some other capability is not ready now.
if( (ieee->current_network.qos_data.active == 0) ||
(ieee->pHTInfo->bCurrentHTSupport == false)) //||
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
index 2c4eb38c89a..50f4f5943e7 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
@@ -41,7 +41,7 @@ static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
//static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
-// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
// code in other place??
//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
/********************************************************************************************************************
@@ -1342,7 +1342,7 @@ void HTUseDefaultSetting(struct ieee80211_device* ieee)
pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
- pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
+ pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
// Set BWOpMode register
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
index 5373d565af2..451120ff213 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
@@ -1,5 +1,6 @@
#include "ieee80211.h"
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include "rtl819x_TS.h"
void TsSetupTimeOut(unsigned long data)
@@ -290,7 +291,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8
if(search_dir[dir] ==false )
continue;
list_for_each_entry(pRet, psearch_list, List){
- // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+ // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
if (memcmp(pRet->Addr, Addr, 6) == 0)
if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -445,7 +446,7 @@ bool GetTs(
ResetRxTsEntry(tmp);
}
- IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+ IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
// Prepare TS Info releated field
pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field
pTSInfo->field.ucTSID = UP; // TSID
@@ -531,7 +532,7 @@ void RemoveTsEntry(
void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
{
PTS_COMMON_INFO pTS, pTmpTS;
- printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+ printk("===========>RemovePeerTS,%pM\n", Addr);
list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
{
if (memcmp(pTS->Addr, Addr, 6) == 0)
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index adade13e1e1..68ebb025677 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -70,6 +70,7 @@ double __extendsfdf2(float a) {return a;}
#include "r8192U_dm.h"
//#include "r8192xU_phyreg.h"
#include <linux/usb.h>
+#include <linux/slab.h>
// FIXME: check if 2.6.7 is ok
#ifdef CONFIG_RTL8192_PM
@@ -104,7 +105,7 @@ u32 rt_global_debug_component = \
#define TOTAL_CAM_ENTRY 32
#define CAM_CONTENT_COUNT 8
-static struct usb_device_id rtl8192_usb_id_tbl[] = {
+static const struct usb_device_id rtl8192_usb_id_tbl[] = {
/* Realtek */
{USB_DEVICE(0x0bda, 0x8192)},
{USB_DEVICE(0x0bda, 0x8709)},
@@ -2719,7 +2720,7 @@ void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
wireless_mode = WIRELESS_MODE_B;
}
}
-#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
#endif
priv->ieee80211->mode = wireless_mode;
@@ -2976,7 +2977,7 @@ static void rtl8192_read_eeprom_info(struct net_device* dev)
memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
//should I set IDR0 here?
}
- RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
+ RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
priv->rf_chip = RF_8256;
@@ -6037,7 +6038,7 @@ void setKey( struct net_device *dev,
if (EntryNo >= TOTAL_CAM_ENTRY)
RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
- RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
+ RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
if (DefaultKey)
usConfig |= BIT15 | (KeyType<<2);
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c
index 4877138a9f9..eb44b60e1eb 100644
--- a/drivers/staging/samsung-laptop/samsung-laptop.c
+++ b/drivers/staging/samsung-laptop/samsung-laptop.c
@@ -99,7 +99,8 @@ static struct rfkill *rfk;
static int force;
module_param(force, bool, 0);
-MODULE_PARM_DESC(force, "Disable the DMI check and forces the driver to be loaded");
+MODULE_PARM_DESC(force,
+ "Disable the DMI check and forces the driver to be loaded");
static int debug;
module_param(debug, bool, S_IRUGO | S_IWUSR);
@@ -370,7 +371,8 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
{
.ident = "N128",
.matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
DMI_MATCH(DMI_PRODUCT_NAME, "N128"),
DMI_MATCH(DMI_BOARD_NAME, "N128"),
},
@@ -379,7 +381,8 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
{
.ident = "N130",
.matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
DMI_MATCH(DMI_PRODUCT_NAME, "N130"),
DMI_MATCH(DMI_BOARD_NAME, "N130"),
},
@@ -391,6 +394,7 @@ MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
static int __init samsung_init(void)
{
+ struct backlight_properties props;
struct sabi_retval sretval;
const char *testStr = "SECLINUX";
void __iomem *memcheck;
@@ -483,12 +487,14 @@ static int __init samsung_init(void)
goto error_no_platform;
/* create a backlight device to talk to this one */
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = MAX_BRIGHT;
backlight_device = backlight_device_register("samsung", &sdev->dev,
- NULL, &backlight_ops);
+ NULL, &backlight_ops,
+ &props);
if (IS_ERR(backlight_device))
goto error_no_backlight;
- backlight_device->props.max_brightness = MAX_BRIGHT;
backlight_device->props.brightness = read_brightness();
backlight_device->props.power = FB_BLANK_UNBLANK;
backlight_update_status(backlight_device);
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
index e7bc9ec63a8..88880734921 100644
--- a/drivers/staging/sep/sep_driver.c
+++ b/drivers/staging/sep/sep_driver.c
@@ -35,12 +35,14 @@
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <asm/ioctl.h>
#include <linux/ioport.h>
#include <asm/io.h>
@@ -182,8 +184,8 @@ static DECLARE_WAIT_QUEUE_HEAD(sep_event);
static int sep_load_firmware(struct sep_device *sep)
{
const struct firmware *fw;
- char *cache_name = "cache.image.bin";
- char *res_name = "resident.image.bin";
+ char *cache_name = "sep/cache.image.bin";
+ char *res_name = "sep/resident.image.bin";
int error;
edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
@@ -222,6 +224,9 @@ static int sep_load_firmware(struct sep_device *sep)
return 0;
}
+MODULE_FIRMWARE("sep/cache.image.bin");
+MODULE_FIRMWARE("sep/resident.image.bin");
+
/**
* sep_map_and_alloc_shared_area - allocate shared block
* @sep: security processor
@@ -273,8 +278,8 @@ static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep,
void *virt_address)
{
dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
- edbg("sep: virt to bus b %08llx v %p\n",
- (unsigned long long)pa, virt_address);
+ edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa,
+ virt_address);
return pa;
}
@@ -380,8 +385,7 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
shared area */
if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
edbg("SEP Driver mmap requested size is more than allowed\n");
- printk(KERN_WARNING "SEP Driver mmap requested size is more \
- than allowed\n");
+ printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n");
printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
return -EAGAIN;
@@ -941,8 +945,9 @@ static int sep_lock_user_pages(struct sep_device *sep,
dbg("data_size is %lu\n", data_size);
while (1);
}
- edbg("lli_array[%lu].physical_address is %08lx, \
- lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+ edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n",
+ count, lli_array[count].physical_address,
+ count, lli_array[count].block_size);
}
/* set output params */
@@ -1771,7 +1776,7 @@ static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep,
static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
unsigned long arg)
{
- int error;
+ int error = -ENOENT;
struct sep_driver_build_flow_table_t command_args;
/* first table - output */
struct sep_lli_entry_t first_table_data;
@@ -2232,7 +2237,7 @@ static int sep_set_flow_id_handler(struct sep_device *sep,
return error;
}
-static int sep_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int error = 0;
struct sep_device *sep = filp->private_data;
@@ -2586,7 +2591,7 @@ end_function:
return error;
}
-static struct pci_device_id sep_pci_id_tbl[] = {
+static const struct pci_device_id sep_pci_id_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
{0}
};
@@ -2607,7 +2612,7 @@ static dev_t sep_devno;
/* the files operations structure of the driver */
static struct file_operations sep_file_operations = {
.owner = THIS_MODULE,
- .ioctl = sep_ioctl,
+ .unlocked_ioctl = sep_ioctl,
.poll = sep_poll,
.open = sep_open,
.release = sep_release,
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c
index 060e9de3b06..44f2d4eaf84 100644
--- a/drivers/staging/serqt_usb2/serqt_usb2.c
+++ b/drivers/staging/serqt_usb2/serqt_usb2.c
@@ -126,7 +126,7 @@ static int debug;
#define MODEM_CTRL 0x40
#define RS232_MODE 0x00
-static struct usb_device_id serqt_id_table[] = {
+static const struct usb_device_id serqt_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)},
@@ -1277,7 +1277,7 @@ static void qt_set_termios(struct tty_struct *tty,
if (cflag & CSTOPB)
new_LCR |= SERIAL_TWO_STOPB;
else
- new_LCR |= SERIAL_TWO_STOPB;
+ new_LCR |= SERIAL_ONE_STOPB;
dbg("%s - 4\n", __func__);
diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h
index ccf7625b8bb..eb3a619c6a9 100644
--- a/drivers/staging/slicoss/slic.h
+++ b/drivers/staging/slicoss/slic.h
@@ -527,15 +527,6 @@ struct adapter {
(largestat) += ((newstat) - (oldstat)); \
}
-#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \
-{ \
- _Result = true; \
- if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \
- _Result = false; \
- if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \
- _Result = false; \
-}
-
#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
#define SLIC_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & \
0x00000000FFFFFFFF)
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index f5cc01ba414..7daeced317c 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -101,7 +101,7 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev);
static int slic_entry_open(struct net_device *dev);
static int slic_entry_halt(struct net_device *dev);
static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
static void slic_xmit_fail(struct adapter *adapter, struct sk_buff *skb,
void *cmd, u32 skbtype, u32 status);
static void slic_config_pci(struct pci_dev *pcidev);
@@ -194,14 +194,10 @@ MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting");
module_param(intagg_delay, int, 0);
MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay");
-static struct pci_device_id slic_pci_tbl[] __devinitdata = {
- {PCI_VENDOR_ID_ALACRITECH,
- SLIC_1GB_DEVICE_ID,
- PCI_ANY_ID, PCI_ANY_ID,},
- {PCI_VENDOR_ID_ALACRITECH,
- SLIC_2GB_DEVICE_ID,
- PCI_ANY_ID, PCI_ANY_ID,},
- {0,}
+static DEFINE_PCI_DEVICE_TABLE(slic_pci_tbl) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_1GB_DEVICE_ID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_2GB_DEVICE_ID) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
@@ -292,7 +288,7 @@ static void slic_init_adapter(struct net_device *netdev,
{
ushort index;
struct slic_handle *pslic_handle;
- struct adapter *adapter = (struct adapter *)netdev_priv(netdev);
+ struct adapter *adapter = netdev_priv(netdev);
/* adapter->pcidev = pcidev;*/
adapter->vendid = pci_tbl_entry->vendor;
@@ -370,6 +366,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
ulong mmio_start = 0;
ulong mmio_len = 0;
struct sliccard *card = NULL;
+ int pci_using_dac = 0;
slic_global.dynamic_intagg = dynamic_intagg;
@@ -383,16 +380,26 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
printk(KERN_DEBUG "%s\n", slic_proc_version);
}
- err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
- if (err) {
- err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
- if (err)
+ if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
+ pci_using_dac = 1;
+ if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
+ dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for "
+ "consistent allocations\n");
goto err_out_disable_pci;
+ }
+ } else if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) {
+ pci_using_dac = 0;
+ pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
+ } else {
+ dev_err(&pcidev->dev, "no usable DMA configuration\n");
+ goto err_out_disable_pci;
}
err = pci_request_regions(pcidev, DRV_NAME);
- if (err)
+ if (err) {
+ dev_err(&pcidev->dev, "can't obtain PCI resources\n");
goto err_out_disable_pci;
+ }
pci_set_master(pcidev);
@@ -408,6 +415,8 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
adapter = netdev_priv(netdev);
adapter->netdev = netdev;
adapter->pcidev = pcidev;
+ if (pci_using_dac)
+ netdev->features |= NETIF_F_HIGHDMA;
mmio_start = pci_resource_start(pcidev, 0);
mmio_len = pci_resource_len(pcidev, 0);
@@ -484,7 +493,7 @@ err_out_disable_pci:
static int slic_entry_open(struct net_device *dev)
{
- struct adapter *adapter = (struct adapter *) netdev_priv(dev);
+ struct adapter *adapter = netdev_priv(dev);
struct sliccard *card = adapter->card;
u32 locked = 0;
int status;
@@ -534,7 +543,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
struct net_device *dev = pci_get_drvdata(pcidev);
u32 mmio_start = 0;
uint mmio_len = 0;
- struct adapter *adapter = (struct adapter *) netdev_priv(dev);
+ struct adapter *adapter = netdev_priv(dev);
struct sliccard *card;
struct mcast_address *mcaddr, *mlist;
@@ -581,7 +590,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
static int slic_entry_halt(struct net_device *dev)
{
- struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct adapter *adapter = netdev_priv(dev);
struct sliccard *card = adapter->card;
__iomem struct slic_regs *slic_regs = adapter->slic_regs;
@@ -624,7 +633,7 @@ static int slic_entry_halt(struct net_device *dev)
static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct adapter *adapter = netdev_priv(dev);
struct ethtool_cmd edata;
struct ethtool_cmd ecmd;
u32 data[7];
@@ -649,8 +658,7 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (copy_from_user(data, rq->ifr_data, 28)) {
PRINT_ERROR
- ("slic: copy_from_user FAILED getting \
- initial simba param\n");
+ ("slic: copy_from_user FAILED getting initial simba param\n");
return -EFAULT;
}
@@ -665,8 +673,7 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
(tracemon_request ==
SLIC_DUMP_IN_PROGRESS)) {
PRINT_ERROR
- ("ATK Diagnostic Trace Dump Requested but \
- already in progress... ignore\n");
+ ("ATK Diagnostic Trace Dump Requested but already in progress... ignore\n");
} else {
PRINT_ERROR
("ATK Diagnostic Trace Dump Requested\n");
@@ -784,10 +791,10 @@ static void slic_xmit_build_request(struct adapter *adapter,
#define NORMAL_ETHFRAME 0
-static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
{
struct sliccard *card;
- struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct adapter *adapter = netdev_priv(dev);
struct slic_hostcmd *hcmd = NULL;
u32 status = 0;
u32 skbtype = NORMAL_ETHFRAME;
@@ -1071,7 +1078,7 @@ static void slic_xmit_complete(struct adapter *adapter)
static irqreturn_t slic_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *)dev_id;
- struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct adapter *adapter = netdev_priv(dev);
u32 isr;
if ((adapter->pshmem) && (adapter->pshmem->isr)) {
@@ -1229,22 +1236,21 @@ static void slic_init_cleanup(struct adapter *adapter)
static struct net_device_stats *slic_get_stats(struct net_device *dev)
{
- struct adapter *adapter = (struct adapter *)netdev_priv(dev);
- struct net_device_stats *stats;
+ struct adapter *adapter = netdev_priv(dev);
ASSERT(adapter);
- stats = &adapter->stats;
- stats->collisions = adapter->slic_stats.iface.xmit_collisions;
- stats->rx_errors = adapter->slic_stats.iface.rcv_errors;
- stats->tx_errors = adapter->slic_stats.iface.xmt_errors;
- stats->rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
- stats->tx_heartbeat_errors = 0;
- stats->tx_aborted_errors = 0;
- stats->tx_window_errors = 0;
- stats->tx_fifo_errors = 0;
- stats->rx_frame_errors = 0;
- stats->rx_length_errors = 0;
- return &adapter->stats;
+ dev->stats.collisions = adapter->slic_stats.iface.xmit_collisions;
+ dev->stats.rx_errors = adapter->slic_stats.iface.rcv_errors;
+ dev->stats.tx_errors = adapter->slic_stats.iface.xmt_errors;
+ dev->stats.rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
+ dev->stats.tx_heartbeat_errors = 0;
+ dev->stats.tx_aborted_errors = 0;
+ dev->stats.tx_window_errors = 0;
+ dev->stats.tx_fifo_errors = 0;
+ dev->stats.rx_frame_errors = 0;
+ dev->stats.rx_length_errors = 0;
+
+ return &dev->stats;
}
/*
@@ -1254,13 +1260,11 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev)
static int slic_mcast_add_list(struct adapter *adapter, char *address)
{
struct mcast_address *mcaddr, *mlist;
- bool equaladdr;
/* Check to see if it already exists */
mlist = adapter->mcastaddrs;
while (mlist) {
- ETHER_EQ_ADDR(mlist->address, address, equaladdr);
- if (equaladdr)
+ if (!compare_ether_addr(mlist->address, address))
return STATUS_SUCCESS;
mlist = mlist->next;
}
@@ -1360,7 +1364,7 @@ static void slic_mcast_set_bit(struct adapter *adapter, char *address)
static void slic_mcast_set_list(struct net_device *dev)
{
- struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct adapter *adapter = netdev_priv(dev);
int status = STATUS_SUCCESS;
char *addresses;
struct dev_mc_list *mc_list;
@@ -1852,6 +1856,9 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
return 0;
}
+MODULE_FIRMWARE("slicoss/oasisrcvucode.sys");
+MODULE_FIRMWARE("slicoss/gbrcvucode.sys");
+
static int slic_card_download(struct adapter *adapter)
{
const struct firmware *fw;
@@ -1963,6 +1970,9 @@ static int slic_card_download(struct adapter *adapter)
return STATUS_SUCCESS;
}
+MODULE_FIRMWARE("slicoss/oasisdownload.sys");
+MODULE_FIRMWARE("slicoss/gbdownload.sys");
+
static void slic_adapter_set_hwaddr(struct adapter *adapter)
{
struct sliccard *card = adapter->card;
@@ -2466,7 +2476,6 @@ static bool slic_mac_filter(struct adapter *adapter,
u32 opts = adapter->macopts;
u32 *dhost4 = (u32 *)&ether_frame->ether_dhost[0];
u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4];
- bool equaladdr;
if (opts & MAC_PROMISC)
return true;
@@ -2490,10 +2499,8 @@ static bool slic_mac_filter(struct adapter *adapter,
struct mcast_address *mcaddr = adapter->mcastaddrs;
while (mcaddr) {
- ETHER_EQ_ADDR(mcaddr->address,
- ether_frame->ether_dhost,
- equaladdr);
- if (equaladdr) {
+ if (!compare_ether_addr(mcaddr->address,
+ ether_frame->ether_dhost)) {
adapter->rcv_multicasts++;
adapter->stats.multicast++;
return true;
@@ -2515,7 +2522,7 @@ static bool slic_mac_filter(struct adapter *adapter,
static int slic_mac_set_address(struct net_device *dev, void *ptr)
{
- struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct adapter *adapter = netdev_priv(dev);
struct sockaddr *addr = ptr;
if (netif_running(dev))
@@ -2523,6 +2530,9 @@ static int slic_mac_set_address(struct net_device *dev, void *ptr)
if (!adapter)
return -EBUSY;
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
@@ -3960,10 +3970,8 @@ static void slic_debug_adapter_create(struct adapter *adapter)
static void slic_debug_adapter_destroy(struct adapter *adapter)
{
- if (adapter->debugfs_entry) {
- debugfs_remove(adapter->debugfs_entry);
- adapter->debugfs_entry = NULL;
- }
+ debugfs_remove(adapter->debugfs_entry);
+ adapter->debugfs_entry = NULL;
}
static void slic_debug_card_create(struct sliccard *card)
diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig
index 204dbfc3c38..315102c7fed 100644
--- a/drivers/staging/sm7xx/Kconfig
+++ b/drivers/staging/sm7xx/Kconfig
@@ -6,10 +6,3 @@ config FB_SM7XX
select FB_CFB_IMAGEBLIT
help
Frame Buffer driver for the Silicon Motion SM7XX serial graphic card.
-
-config FB_SM7XX_ACCEL
- bool "Siliconmotion Acceleration functions (EXPERIMENTAL)"
- depends on FB_SM7XX && EXPERIMENTAL
- help
- This will compile the Trident frame buffer device with
- acceleration functions.
diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO
index 1f61f5e11cf..a66d9e40649 100644
--- a/drivers/staging/sm7xx/TODO
+++ b/drivers/staging/sm7xx/TODO
@@ -1,5 +1,6 @@
TODO:
- Dual head support
+- 2D acceleration support
- use kernel coding style
- checkpatch.pl clean
- refine the code and remove unused code
diff --git a/drivers/staging/sm7xx/smtc2d.c b/drivers/staging/sm7xx/smtc2d.c
deleted file mode 100644
index 2fff0a0052d..00000000000
--- a/drivers/staging/sm7xx/smtc2d.c
+++ /dev/null
@@ -1,979 +0,0 @@
-/*
- * Silicon Motion SM7XX 2D drawing engine functions.
- *
- * Copyright (C) 2006 Silicon Motion Technology Corp.
- * Author: Boyod boyod.yang@siliconmotion.com.cn
- *
- * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzhangjin@gmail.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.
- *
- * Version 0.10.26192.21.01
- * - Add PowerPC support
- * - Add 2D support for Lynx -
- * Verified on 2.6.19.2
- * Boyod.yang <boyod.yang@siliconmotion.com.cn>
- */
-
-unsigned char smtc_de_busy;
-
-void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData)
-{
- writel(nData, smtc_2DBaseAddress + nOffset);
-}
-
-unsigned long SMTC_read2Dreg(unsigned long nOffset)
-{
- return readl(smtc_2DBaseAddress + nOffset);
-}
-
-void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData)
-{
- writel(nData, smtc_2Ddataport + nOffset);
-}
-
-/**********************************************************************
- *
- * deInit
- *
- * Purpose
- * Drawing engine initialization.
- *
- **********************************************************************/
-
-void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
- unsigned int bpp)
-{
- /* Get current power configuration. */
- unsigned char clock;
- clock = smtc_seqr(0x21);
-
- /* initialize global 'mutex lock' variable */
- smtc_de_busy = 0;
-
- /* Enable 2D Drawing Engine */
- smtc_seqw(0x21, clock & 0xF8);
-
- SMTC_write2Dreg(DE_CLIP_TL,
- FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) |
- FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) |
- FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) |
- FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0));
-
- if (bpp >= 24) {
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION,
- nModeWidth * 3) | FIELD_VALUE(0,
- DE_PITCH,
- SOURCE,
- nModeWidth
- * 3));
- } else {
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION,
- nModeWidth) | FIELD_VALUE(0,
- DE_PITCH,
- SOURCE,
- nModeWidth));
- }
-
- SMTC_write2Dreg(DE_WINDOW_WIDTH,
- FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- nModeWidth) | FIELD_VALUE(0,
- DE_WINDOW_WIDTH,
- SOURCE,
- nModeWidth));
-
- switch (bpp) {
- case 8:
- SMTC_write2Dreg(DE_STRETCH_FORMAT,
- FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
- NORMAL) | FIELD_VALUE(0,
- DE_STRETCH_FORMAT,
- PATTERN_Y,
- 0) |
- FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
- 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
- PIXEL_FORMAT,
- 8) | FIELD_SET(0,
- DE_STRETCH_FORMAT,
- ADDRESSING,
- XY) |
- FIELD_VALUE(0, DE_STRETCH_FORMAT,
- SOURCE_HEIGHT, 3));
- break;
- case 24:
- SMTC_write2Dreg(DE_STRETCH_FORMAT,
- FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
- NORMAL) | FIELD_VALUE(0,
- DE_STRETCH_FORMAT,
- PATTERN_Y,
- 0) |
- FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
- 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
- PIXEL_FORMAT,
- 24) | FIELD_SET(0,
- DE_STRETCH_FORMAT,
- ADDRESSING,
- XY) |
- FIELD_VALUE(0, DE_STRETCH_FORMAT,
- SOURCE_HEIGHT, 3));
- break;
- case 16:
- default:
- SMTC_write2Dreg(DE_STRETCH_FORMAT,
- FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
- NORMAL) | FIELD_VALUE(0,
- DE_STRETCH_FORMAT,
- PATTERN_Y,
- 0) |
- FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
- 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
- PIXEL_FORMAT,
- 16) | FIELD_SET(0,
- DE_STRETCH_FORMAT,
- ADDRESSING,
- XY) |
- FIELD_VALUE(0, DE_STRETCH_FORMAT,
- SOURCE_HEIGHT, 3));
- break;
- }
-
- SMTC_write2Dreg(DE_MASKS,
- FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) |
- FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF));
- SMTC_write2Dreg(DE_COLOR_COMPARE_MASK,
- FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \
- 0xFFFFFF));
- SMTC_write2Dreg(DE_COLOR_COMPARE,
- FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF));
-}
-
-void deVerticalLine(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long nX,
- unsigned long nY,
- unsigned long dst_height, unsigned long nColor)
-{
- deWaitForNotBusy();
-
- SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
- dst_base));
-
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
- FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
-
- SMTC_write2Dreg(DE_WINDOW_WIDTH,
- FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
- SOURCE,
- dst_pitch));
-
- SMTC_write2Dreg(DE_FOREGROUND,
- FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-
- SMTC_write2Dreg(DE_DESTINATION,
- FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_DESTINATION, X, nX) |
- FIELD_VALUE(0, DE_DESTINATION, Y, nY));
-
- SMTC_write2Dreg(DE_DIMENSION,
- FIELD_VALUE(0, DE_DIMENSION, X, 1) |
- FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
-
- SMTC_write2Dreg(DE_CONTROL,
- FIELD_SET(0, DE_CONTROL, STATUS, START) |
- FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
- FIELD_SET(0, DE_CONTROL, MAJOR, Y) |
- FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) |
- FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
- FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
- FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) |
- FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
-
- smtc_de_busy = 1;
-}
-
-void deHorizontalLine(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long nX,
- unsigned long nY,
- unsigned long dst_width, unsigned long nColor)
-{
- deWaitForNotBusy();
-
- SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
- dst_base));
-
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
- FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
-
- SMTC_write2Dreg(DE_WINDOW_WIDTH,
- FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
- SOURCE,
- dst_pitch));
- SMTC_write2Dreg(DE_FOREGROUND,
- FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
- SMTC_write2Dreg(DE_DESTINATION,
- FIELD_SET(0, DE_DESTINATION, WRAP,
- DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X,
- nX) | FIELD_VALUE(0,
- DE_DESTINATION,
- Y,
- nY));
- SMTC_write2Dreg(DE_DIMENSION,
- FIELD_VALUE(0, DE_DIMENSION, X,
- dst_width) | FIELD_VALUE(0, DE_DIMENSION,
- Y_ET, 1));
- SMTC_write2Dreg(DE_CONTROL,
- FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0,
- DE_CONTROL,
- DIRECTION,
- RIGHT_TO_LEFT)
- | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0,
- DE_CONTROL,
- STEP_X,
- POSITIVE)
- | FIELD_SET(0, DE_CONTROL, STEP_Y,
- NEGATIVE) | FIELD_SET(0, DE_CONTROL,
- LAST_PIXEL,
- OFF) | FIELD_SET(0,
- DE_CONTROL,
- COMMAND,
- SHORT_STROKE)
- | FIELD_SET(0, DE_CONTROL, ROP_SELECT,
- ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP,
- 0x0C));
-
- smtc_de_busy = 1;
-}
-
-void deLine(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long nX1,
- unsigned long nY1,
- unsigned long nX2, unsigned long nY2, unsigned long nColor)
-{
- unsigned long nCommand =
- FIELD_SET(0, DE_CONTROL, STATUS, START) |
- FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
- FIELD_SET(0, DE_CONTROL, MAJOR, X) |
- FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) |
- FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
- FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
- FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C);
- unsigned long DeltaX;
- unsigned long DeltaY;
-
- /* Calculate delta X */
- if (nX1 <= nX2)
- DeltaX = nX2 - nX1;
- else {
- DeltaX = nX1 - nX2;
- nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE);
- }
-
- /* Calculate delta Y */
- if (nY1 <= nY2)
- DeltaY = nY2 - nY1;
- else {
- DeltaY = nY1 - nY2;
- nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE);
- }
-
- /* Determine the major axis */
- if (DeltaX < DeltaY)
- nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y);
-
- /* Vertical line? */
- if (nX1 == nX2)
- deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor);
-
- /* Horizontal line? */
- else if (nY1 == nY2)
- deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \
- DeltaX, nColor);
-
- /* Diagonal line? */
- else if (DeltaX == DeltaY) {
- deWaitForNotBusy();
-
- SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
- ADDRESS, dst_base));
-
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0,
- DE_PITCH,
- SOURCE,
- dst_pitch));
-
- SMTC_write2Dreg(DE_WINDOW_WIDTH,
- FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0,
- DE_WINDOW_WIDTH,
- SOURCE,
- dst_pitch));
-
- SMTC_write2Dreg(DE_FOREGROUND,
- FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-
- SMTC_write2Dreg(DE_DESTINATION,
- FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_DESTINATION, X, 1) |
- FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
-
- SMTC_write2Dreg(DE_DIMENSION,
- FIELD_VALUE(0, DE_DIMENSION, X, 1) |
- FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX));
-
- SMTC_write2Dreg(DE_CONTROL,
- FIELD_SET(nCommand, DE_CONTROL, COMMAND,
- SHORT_STROKE));
- }
-
- /* Generic line */
- else {
- unsigned int k1, k2, et, w;
- if (DeltaX < DeltaY) {
- k1 = 2 * DeltaX;
- et = k1 - DeltaY;
- k2 = et - DeltaY;
- w = DeltaY + 1;
- } else {
- k1 = 2 * DeltaY;
- et = k1 - DeltaX;
- k2 = et - DeltaX;
- w = DeltaX + 1;
- }
-
- deWaitForNotBusy();
-
- SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
- ADDRESS, dst_base));
-
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0,
- DE_PITCH,
- SOURCE,
- dst_pitch));
-
- SMTC_write2Dreg(DE_WINDOW_WIDTH,
- FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0,
- DE_WINDOW_WIDTH,
- SOURCE,
- dst_pitch));
-
- SMTC_write2Dreg(DE_FOREGROUND,
- FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-
- SMTC_write2Dreg(DE_SOURCE,
- FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_SOURCE, X_K1, k1) |
- FIELD_VALUE(0, DE_SOURCE, Y_K2, k2));
-
- SMTC_write2Dreg(DE_DESTINATION,
- FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_DESTINATION, X, nX1) |
- FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
-
- SMTC_write2Dreg(DE_DIMENSION,
- FIELD_VALUE(0, DE_DIMENSION, X, w) |
- FIELD_VALUE(0, DE_DIMENSION, Y_ET, et));
-
- SMTC_write2Dreg(DE_CONTROL,
- FIELD_SET(nCommand, DE_CONTROL, COMMAND,
- LINE_DRAW));
- }
-
- smtc_de_busy = 1;
-}
-
-void deFillRect(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long dst_X,
- unsigned long dst_Y,
- unsigned long dst_width,
- unsigned long dst_height, unsigned long nColor)
-{
- deWaitForNotBusy();
-
- SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
- dst_base));
-
- if (dst_pitch) {
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0,
- DE_PITCH,
- SOURCE,
- dst_pitch));
-
- SMTC_write2Dreg(DE_WINDOW_WIDTH,
- FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0,
- DE_WINDOW_WIDTH,
- SOURCE,
- dst_pitch));
- }
-
- SMTC_write2Dreg(DE_FOREGROUND,
- FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
-
- SMTC_write2Dreg(DE_DESTINATION,
- FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
- FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
-
- SMTC_write2Dreg(DE_DIMENSION,
- FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
- FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
-
- SMTC_write2Dreg(DE_CONTROL,
- FIELD_SET(0, DE_CONTROL, STATUS, START) |
- FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
- FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
- FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) |
- FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
-
- smtc_de_busy = 1;
-}
-
-/**********************************************************************
- *
- * deRotatePattern
- *
- * Purpose
- * Rotate the given pattern if necessary
- *
- * Parameters
- * [in]
- * pPattern - Pointer to DE_SURFACE structure containing
- * pattern attributes
- * patternX - X position (0-7) of pattern origin
- * patternY - Y position (0-7) of pattern origin
- *
- * [out]
- * pattern_dstaddr - Pointer to pre-allocated buffer containing
- * rotated pattern
- *
- **********************************************************************/
-void deRotatePattern(unsigned char *pattern_dstaddr,
- unsigned long pattern_src_addr,
- unsigned long pattern_BPP,
- unsigned long pattern_stride, int patternX, int patternY)
-{
- unsigned int i;
- unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT];
- unsigned int x, y;
- unsigned char *pjPatByte;
-
- if (pattern_dstaddr != NULL) {
- deWaitForNotBusy();
-
- if (patternX || patternY) {
- /* Rotate pattern */
- pjPatByte = (unsigned char *)pattern;
-
- switch (pattern_BPP) {
- case 8:
- {
- for (y = 0; y < 8; y++) {
- unsigned char *pjBuffer =
- pattern_dstaddr +
- ((patternY + y) & 7) * 8;
- for (x = 0; x < 8; x++) {
- pjBuffer[(patternX +
- x) & 7] =
- pjPatByte[x];
- }
- pjPatByte += pattern_stride;
- }
- break;
- }
-
- case 16:
- {
- for (y = 0; y < 8; y++) {
- unsigned short *pjBuffer =
- (unsigned short *)
- pattern_dstaddr +
- ((patternY + y) & 7) * 8;
- for (x = 0; x < 8; x++) {
- pjBuffer[(patternX +
- x) & 7] =
- ((unsigned short *)
- pjPatByte)[x];
- }
- pjPatByte += pattern_stride;
- }
- break;
- }
-
- case 32:
- {
- for (y = 0; y < 8; y++) {
- unsigned long *pjBuffer =
- (unsigned long *)
- pattern_dstaddr +
- ((patternY + y) & 7) * 8;
- for (x = 0; x < 8; x++) {
- pjBuffer[(patternX +
- x) & 7] =
- ((unsigned long *)
- pjPatByte)[x];
- }
- pjPatByte += pattern_stride;
- }
- break;
- }
- }
- } else {
- /*Don't rotate,just copy pattern into pattern_dstaddr*/
- for (i = 0; i < (pattern_BPP * 2); i++) {
- ((unsigned long *)pattern_dstaddr)[i] =
- pattern[i];
- }
- }
-
- }
-}
-
-/**********************************************************************
- *
- * deCopy
- *
- * Purpose
- * Copy a rectangular area of the source surface to a destination surface
- *
- * Remarks
- * Source bitmap must have the same color depth (BPP) as the destination
- * bitmap.
- *
-**********************************************************************/
-void deCopy(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long dst_BPP,
- unsigned long dst_X,
- unsigned long dst_Y,
- unsigned long dst_width,
- unsigned long dst_height,
- unsigned long src_base,
- unsigned long src_pitch,
- unsigned long src_X,
- unsigned long src_Y, pTransparent pTransp, unsigned char nROP2)
-{
- unsigned long nDirection = 0;
- unsigned long nTransparent = 0;
- /* Direction of ROP2 operation:
- * 1 = Left to Right,
- * (-1) = Right to Left
- */
- unsigned long opSign = 1;
- /* xWidth is in pixels */
- unsigned long xWidth = 192 / (dst_BPP / 8);
- unsigned long de_ctrl = 0;
-
- deWaitForNotBusy();
-
- SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
- dst_base));
-
- SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE,
- FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS,
- src_base));
-
- if (dst_pitch && src_pitch) {
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0,
- DE_PITCH,
- SOURCE,
- src_pitch));
-
- SMTC_write2Dreg(DE_WINDOW_WIDTH,
- FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- dst_pitch) | FIELD_VALUE(0,
- DE_WINDOW_WIDTH,
- SOURCE,
- src_pitch));
- }
-
- /* Set transparent bits if necessary */
- if (pTransp != NULL) {
- nTransparent =
- pTransp->match | pTransp->select | pTransp->control;
-
- /* Set color compare register */
- SMTC_write2Dreg(DE_COLOR_COMPARE,
- FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR,
- pTransp->color));
- }
-
- /* Determine direction of operation */
- if (src_Y < dst_Y) {
- /* +----------+
- |S |
- | +----------+
- | | | |
- | | | |
- +---|------+ |
- | D |
- +----------+ */
-
- nDirection = BOTTOM_TO_TOP;
- } else if (src_Y > dst_Y) {
- /* +----------+
- |D |
- | +----------+
- | | | |
- | | | |
- +---|------+ |
- | S |
- +----------+ */
-
- nDirection = TOP_TO_BOTTOM;
- } else {
- /* src_Y == dst_Y */
-
- if (src_X <= dst_X) {
- /* +------+---+------+
- |S | | D|
- | | | |
- | | | |
- | | | |
- +------+---+------+ */
-
- nDirection = RIGHT_TO_LEFT;
- } else {
- /* src_X > dst_X */
-
- /* +------+---+------+
- |D | | S|
- | | | |
- | | | |
- | | | |
- +------+---+------+ */
-
- nDirection = LEFT_TO_RIGHT;
- }
- }
-
- if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
- src_X += dst_width - 1;
- src_Y += dst_height - 1;
- dst_X += dst_width - 1;
- dst_Y += dst_height - 1;
- opSign = (-1);
- }
-
- if (dst_BPP >= 24) {
- src_X *= 3;
- src_Y *= 3;
- dst_X *= 3;
- dst_Y *= 3;
- dst_width *= 3;
- if ((nDirection == BOTTOM_TO_TOP)
- || (nDirection == RIGHT_TO_LEFT)) {
- src_X += 2;
- dst_X += 2;
- }
- }
-
- /* Workaround for 192 byte hw bug */
- if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) {
- /*
- * Perform the ROP2 operation in chunks of (xWidth *
- * dst_height)
- */
- while (1) {
- deWaitForNotBusy();
-
- SMTC_write2Dreg(DE_SOURCE,
- FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
- FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
-
- SMTC_write2Dreg(DE_DESTINATION,
- FIELD_SET(0, DE_DESTINATION, WRAP,
- DISABLE) | FIELD_VALUE(0,
- DE_DESTINATION,
- X,
- dst_X)
- | FIELD_VALUE(0, DE_DESTINATION, Y,
- dst_Y));
-
- SMTC_write2Dreg(DE_DIMENSION,
- FIELD_VALUE(0, DE_DIMENSION, X,
- xWidth) | FIELD_VALUE(0,
- DE_DIMENSION,
- Y_ET,
- dst_height));
-
- de_ctrl =
- FIELD_VALUE(0, DE_CONTROL, ROP,
- nROP2) | nTransparent | FIELD_SET(0,
- DE_CONTROL,
- ROP_SELECT,
- ROP2)
- | FIELD_SET(0, DE_CONTROL, COMMAND,
- BITBLT) | ((nDirection ==
- 1) ? FIELD_SET(0,
- DE_CONTROL,
- DIRECTION,
- RIGHT_TO_LEFT)
- : FIELD_SET(0, DE_CONTROL,
- DIRECTION,
- LEFT_TO_RIGHT)) |
- FIELD_SET(0, DE_CONTROL, STATUS, START);
-
- SMTC_write2Dreg(DE_CONTROL, de_ctrl);
-
- src_X += (opSign * xWidth);
- dst_X += (opSign * xWidth);
- dst_width -= xWidth;
-
- if (dst_width <= 0) {
- /* ROP2 operation is complete */
- break;
- }
-
- if (xWidth > dst_width)
- xWidth = dst_width;
- }
- } else {
- deWaitForNotBusy();
- SMTC_write2Dreg(DE_SOURCE,
- FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
- FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
-
- SMTC_write2Dreg(DE_DESTINATION,
- FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
- FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
-
- SMTC_write2Dreg(DE_DIMENSION,
- FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
- FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
-
- de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) |
- nTransparent |
- FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) |
- ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION,
- RIGHT_TO_LEFT)
- : FIELD_SET(0, DE_CONTROL, DIRECTION,
- LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL,
- STATUS, START);
- SMTC_write2Dreg(DE_CONTROL, de_ctrl);
- }
-
- smtc_de_busy = 1;
-}
-
-/*
- * This function sets the pixel format that will apply to the 2D Engine.
- */
-void deSetPixelFormat(unsigned long bpp)
-{
- unsigned long de_format;
-
- de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT);
-
- switch (bpp) {
- case 8:
- de_format =
- FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8);
- break;
- default:
- case 16:
- de_format =
- FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16);
- break;
- case 32:
- de_format =
- FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32);
- break;
- }
-
- SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format);
-}
-
-/*
- * System memory to Video memory monochrome expansion.
- *
- * Source is monochrome image in system memory. This function expands the
- * monochrome data to color image in video memory.
- */
-
-long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf,
- long srcDelta,
- unsigned long startBit,
- unsigned long dBase,
- unsigned long dPitch,
- unsigned long bpp,
- unsigned long dx, unsigned long dy,
- unsigned long width, unsigned long height,
- unsigned long fColor,
- unsigned long bColor,
- unsigned long rop2) {
- unsigned long bytePerPixel;
- unsigned long ulBytesPerScan;
- unsigned long ul4BytesPerScan;
- unsigned long ulBytesRemain;
- unsigned long de_ctrl = 0;
- unsigned char ajRemain[4];
- long i, j;
-
- bytePerPixel = bpp / 8;
-
- /* Just make sure the start bit is within legal range */
- startBit &= 7;
-
- ulBytesPerScan = (width + startBit + 7) / 8;
- ul4BytesPerScan = ulBytesPerScan & ~3;
- ulBytesRemain = ulBytesPerScan & 3;
-
- if (smtc_de_busy)
- deWaitForNotBusy();
-
- /*
- * 2D Source Base. Use 0 for HOST Blt.
- */
-
- SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0);
-
- /*
- * 2D Destination Base.
- *
- * It is an address offset (128 bit aligned) from the beginning of
- * frame buffer.
- */
-
- SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase);
-
- if (dPitch) {
-
- /*
- * Program pitch (distance between the 1st points of two
- * adjacent lines).
- *
- * Note that input pitch is BYTE value, but the 2D Pitch
- * register uses pixel values. Need Byte to pixel convertion.
- */
-
- SMTC_write2Dreg(DE_PITCH,
- FIELD_VALUE(0, DE_PITCH, DESTINATION,
- dPitch /
- bytePerPixel) | FIELD_VALUE(0,
- DE_PITCH,
- SOURCE,
- dPitch /
- bytePerPixel));
-
- /* Screen Window width in Pixels.
- *
- * 2D engine uses this value to calculate the linear address in
- * frame buffer for a given point.
- */
-
- SMTC_write2Dreg(DE_WINDOW_WIDTH,
- FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- (dPitch /
- bytePerPixel)) | FIELD_VALUE(0,
- DE_WINDOW_WIDTH,
- SOURCE,
- (dPitch
- /
- bytePerPixel)));
- }
- /* Note: For 2D Source in Host Write, only X_K1 field is needed, and
- * Y_K2 field is not used. For mono bitmap, use startBit for X_K1.
- */
-
- SMTC_write2Dreg(DE_SOURCE,
- FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) |
- FIELD_VALUE(0, DE_SOURCE, Y_K2, 0));
-
- SMTC_write2Dreg(DE_DESTINATION,
- FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- FIELD_VALUE(0, DE_DESTINATION, X, dx) |
- FIELD_VALUE(0, DE_DESTINATION, Y, dy));
-
- SMTC_write2Dreg(DE_DIMENSION,
- FIELD_VALUE(0, DE_DIMENSION, X, width) |
- FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));
-
- SMTC_write2Dreg(DE_FOREGROUND, fColor);
- SMTC_write2Dreg(DE_BACKGROUND, bColor);
-
- if (bpp)
- deSetPixelFormat(bpp);
- /* Set the pixel format of the destination */
-
- de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) |
- FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) |
- FIELD_SET(0, DE_CONTROL, HOST, MONO) |
- FIELD_SET(0, DE_CONTROL, STATUS, START);
-
- SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency());
-
- /* Write MONO data (line by line) to 2D Engine data port */
- for (i = 0; i < height; i++) {
- /* For each line, send the data in chunks of 4 bytes */
- for (j = 0; j < (ul4BytesPerScan / 4); j++)
- SMTC_write2Ddataport(0,
- *(unsigned long *)(pSrcbuf +
- (j * 4)));
-
- if (ulBytesRemain) {
- memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
- ulBytesRemain);
- SMTC_write2Ddataport(0, *(unsigned long *)ajRemain);
- }
-
- pSrcbuf += srcDelta;
- }
- smtc_de_busy = 1;
-
- return 0;
-}
-
-/*
- * This function gets the transparency status from DE_CONTROL register.
- * It returns a double word with the transparent fields properly set,
- * while other fields are 0.
- */
-unsigned long deGetTransparency(void)
-{
- unsigned long de_ctrl;
-
- de_ctrl = SMTC_read2Dreg(DE_CONTROL);
-
- de_ctrl &=
- FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) |
- FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) |
- FIELD_MASK(DE_CONTROL_TRANSPARENCY);
-
- return de_ctrl;
-}
diff --git a/drivers/staging/sm7xx/smtc2d.h b/drivers/staging/sm7xx/smtc2d.h
deleted file mode 100644
index 02b4fa29136..00000000000
--- a/drivers/staging/sm7xx/smtc2d.h
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Silicon Motion SM712 2D drawing engine functions.
- *
- * Copyright (C) 2006 Silicon Motion Technology Corp.
- * Author: Ge Wang, gewang@siliconmotion.com
- *
- * Copyright (C) 2009 Lemote, Inc.
- * Author: Wu Zhangjin, wuzhangjin@gmail.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.
- */
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* Internal macros */
-
-#define _F_START(f) (0 ? f)
-#define _F_END(f) (1 ? f)
-#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f))
-#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f))
-#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f))
-#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f))
-
-/* Global macros */
-
-#define FIELD_GET(x, reg, field) \
-( \
- _F_NORMALIZE((x), reg ## _ ## field) \
-)
-
-#define FIELD_SET(x, reg, field, value) \
-( \
- (x & ~_F_MASK(reg ## _ ## field)) \
- | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
-)
-
-#define FIELD_VALUE(x, reg, field, value) \
-( \
- (x & ~_F_MASK(reg ## _ ## field)) \
- | _F_DENORMALIZE(value, reg ## _ ## field) \
-)
-
-#define FIELD_CLEAR(reg, field) \
-( \
- ~_F_MASK(reg ## _ ## field) \
-)
-
-/* Field Macros */
-
-#define FIELD_START(field) (0 ? field)
-#define FIELD_END(field) (1 ? field)
-#define FIELD_SIZE(field) \
- (1 + FIELD_END(field) - FIELD_START(field))
-
-#define FIELD_MASK(field) \
- (((1 << (FIELD_SIZE(field)-1)) \
- | ((1 << (FIELD_SIZE(field)-1)) - 1)) \
- << FIELD_START(field))
-
-#define FIELD_NORMALIZE(reg, field) \
- (((reg) & FIELD_MASK(field)) >> FIELD_START(field))
-
-#define FIELD_DENORMALIZE(field, value) \
- (((value) << FIELD_START(field)) & FIELD_MASK(field))
-
-#define FIELD_INIT(reg, field, value) \
- FIELD_DENORMALIZE(reg ## _ ## field, \
- reg ## _ ## field ## _ ## value)
-
-#define FIELD_INIT_VAL(reg, field, value) \
- (FIELD_DENORMALIZE(reg ## _ ## field, value))
-
-#define FIELD_VAL_SET(x, r, f, v) ({ \
- x = (x & ~FIELD_MASK(r ## _ ## f)) \
- | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \
-})
-
-#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b)))
-
-/* Transparent info definition */
-typedef struct {
- unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */
- unsigned long select; /* Transparency controlled by SRC/DST */
- unsigned long control; /* ENABLE/DISABLE transparency */
- unsigned long color; /* Transparent color */
-} Transparent, *pTransparent;
-
-#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */
-#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */
-#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */
-#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */
-#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */
-#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */
-
-#define PATTERN_WIDTH 8
-#define PATTERN_HEIGHT 8
-
-#define TOP_TO_BOTTOM 0
-#define BOTTOM_TO_TOP 1
-#define RIGHT_TO_LEFT BOTTOM_TO_TOP
-#define LEFT_TO_RIGHT TOP_TO_BOTTOM
-
-/* Constants used in Transparent structure */
-#define MATCH_OPAQUE 0x00000000
-#define MATCH_TRANSPARENT 0x00000400
-#define SOURCE 0x00000000
-#define DESTINATION 0x00000200
-
-/* 2D registers. */
-
-#define DE_SOURCE 0x000000
-#define DE_SOURCE_WRAP 31 : 31
-#define DE_SOURCE_WRAP_DISABLE 0
-#define DE_SOURCE_WRAP_ENABLE 1
-#define DE_SOURCE_X_K1 29 : 16
-#define DE_SOURCE_Y_K2 15 : 0
-
-#define DE_DESTINATION 0x000004
-#define DE_DESTINATION_WRAP 31 : 31
-#define DE_DESTINATION_WRAP_DISABLE 0
-#define DE_DESTINATION_WRAP_ENABLE 1
-#define DE_DESTINATION_X 28 : 16
-#define DE_DESTINATION_Y 15 : 0
-
-#define DE_DIMENSION 0x000008
-#define DE_DIMENSION_X 28 : 16
-#define DE_DIMENSION_Y_ET 15 : 0
-
-#define DE_CONTROL 0x00000C
-#define DE_CONTROL_STATUS 31 : 31
-#define DE_CONTROL_STATUS_STOP 0
-#define DE_CONTROL_STATUS_START 1
-#define DE_CONTROL_PATTERN 30 : 30
-#define DE_CONTROL_PATTERN_MONO 0
-#define DE_CONTROL_PATTERN_COLOR 1
-#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29
-#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0
-#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1
-#define DE_CONTROL_QUICK_START 28 : 28
-#define DE_CONTROL_QUICK_START_DISABLE 0
-#define DE_CONTROL_QUICK_START_ENABLE 1
-#define DE_CONTROL_DIRECTION 27 : 27
-#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0
-#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1
-#define DE_CONTROL_MAJOR 26 : 26
-#define DE_CONTROL_MAJOR_X 0
-#define DE_CONTROL_MAJOR_Y 1
-#define DE_CONTROL_STEP_X 25 : 25
-#define DE_CONTROL_STEP_X_POSITIVE 1
-#define DE_CONTROL_STEP_X_NEGATIVE 0
-#define DE_CONTROL_STEP_Y 24 : 24
-#define DE_CONTROL_STEP_Y_POSITIVE 1
-#define DE_CONTROL_STEP_Y_NEGATIVE 0
-#define DE_CONTROL_STRETCH 23 : 23
-#define DE_CONTROL_STRETCH_DISABLE 0
-#define DE_CONTROL_STRETCH_ENABLE 1
-#define DE_CONTROL_HOST 22 : 22
-#define DE_CONTROL_HOST_COLOR 0
-#define DE_CONTROL_HOST_MONO 1
-#define DE_CONTROL_LAST_PIXEL 21 : 21
-#define DE_CONTROL_LAST_PIXEL_OFF 0
-#define DE_CONTROL_LAST_PIXEL_ON 1
-#define DE_CONTROL_COMMAND 20 : 16
-#define DE_CONTROL_COMMAND_BITBLT 0
-#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1
-#define DE_CONTROL_COMMAND_DE_TILE 2
-#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3
-#define DE_CONTROL_COMMAND_ALPHA_BLEND 4
-#define DE_CONTROL_COMMAND_RLE_STRIP 5
-#define DE_CONTROL_COMMAND_SHORT_STROKE 6
-#define DE_CONTROL_COMMAND_LINE_DRAW 7
-#define DE_CONTROL_COMMAND_HOST_WRITE 8
-#define DE_CONTROL_COMMAND_HOST_READ 9
-#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10
-#define DE_CONTROL_COMMAND_ROTATE 11
-#define DE_CONTROL_COMMAND_FONT 12
-#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15
-#define DE_CONTROL_ROP_SELECT 15 : 15
-#define DE_CONTROL_ROP_SELECT_ROP3 0
-#define DE_CONTROL_ROP_SELECT_ROP2 1
-#define DE_CONTROL_ROP2_SOURCE 14 : 14
-#define DE_CONTROL_ROP2_SOURCE_BITMAP 0
-#define DE_CONTROL_ROP2_SOURCE_PATTERN 1
-#define DE_CONTROL_MONO_DATA 13 : 12
-#define DE_CONTROL_MONO_DATA_NOT_PACKED 0
-#define DE_CONTROL_MONO_DATA_8_PACKED 1
-#define DE_CONTROL_MONO_DATA_16_PACKED 2
-#define DE_CONTROL_MONO_DATA_32_PACKED 3
-#define DE_CONTROL_REPEAT_ROTATE 11 : 11
-#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0
-#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1
-#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10
-#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0
-#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1
-#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9
-#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0
-#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1
-#define DE_CONTROL_TRANSPARENCY 8 : 8
-#define DE_CONTROL_TRANSPARENCY_DISABLE 0
-#define DE_CONTROL_TRANSPARENCY_ENABLE 1
-#define DE_CONTROL_ROP 7 : 0
-
-/* Pseudo fields. */
-
-#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24
-#define DE_CONTROL_SHORT_STROKE_DIR_225 0
-#define DE_CONTROL_SHORT_STROKE_DIR_135 1
-#define DE_CONTROL_SHORT_STROKE_DIR_315 2
-#define DE_CONTROL_SHORT_STROKE_DIR_45 3
-#define DE_CONTROL_SHORT_STROKE_DIR_270 4
-#define DE_CONTROL_SHORT_STROKE_DIR_90 5
-#define DE_CONTROL_SHORT_STROKE_DIR_180 8
-#define DE_CONTROL_SHORT_STROKE_DIR_0 10
-#define DE_CONTROL_ROTATION 25 : 24
-#define DE_CONTROL_ROTATION_0 0
-#define DE_CONTROL_ROTATION_270 1
-#define DE_CONTROL_ROTATION_90 2
-#define DE_CONTROL_ROTATION_180 3
-
-#define DE_PITCH 0x000010
-#define DE_PITCH_DESTINATION 28 : 16
-#define DE_PITCH_SOURCE 12 : 0
-
-#define DE_FOREGROUND 0x000014
-#define DE_FOREGROUND_COLOR 31 : 0
-
-#define DE_BACKGROUND 0x000018
-#define DE_BACKGROUND_COLOR 31 : 0
-
-#define DE_STRETCH_FORMAT 0x00001C
-#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30
-#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0
-#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1
-#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27
-#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23
-#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20
-#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0
-#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1
-#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3
-#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2
-#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16
-#define DE_STRETCH_FORMAT_ADDRESSING_XY 0
-#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15
-#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0
-
-#define DE_COLOR_COMPARE 0x000020
-#define DE_COLOR_COMPARE_COLOR 23 : 0
-
-#define DE_COLOR_COMPARE_MASK 0x000024
-#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0
-
-#define DE_MASKS 0x000028
-#define DE_MASKS_BYTE_MASK 31 : 16
-#define DE_MASKS_BIT_MASK 15 : 0
-
-#define DE_CLIP_TL 0x00002C
-#define DE_CLIP_TL_TOP 31 : 16
-#define DE_CLIP_TL_STATUS 13 : 13
-#define DE_CLIP_TL_STATUS_DISABLE 0
-#define DE_CLIP_TL_STATUS_ENABLE 1
-#define DE_CLIP_TL_INHIBIT 12 : 12
-#define DE_CLIP_TL_INHIBIT_OUTSIDE 0
-#define DE_CLIP_TL_INHIBIT_INSIDE 1
-#define DE_CLIP_TL_LEFT 11 : 0
-
-#define DE_CLIP_BR 0x000030
-#define DE_CLIP_BR_BOTTOM 31 : 16
-#define DE_CLIP_BR_RIGHT 12 : 0
-
-#define DE_MONO_PATTERN_LOW 0x000034
-#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0
-
-#define DE_MONO_PATTERN_HIGH 0x000038
-#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0
-
-#define DE_WINDOW_WIDTH 0x00003C
-#define DE_WINDOW_WIDTH_DESTINATION 28 : 16
-#define DE_WINDOW_WIDTH_SOURCE 12 : 0
-
-#define DE_WINDOW_SOURCE_BASE 0x000040
-#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27
-#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0
-#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1
-#define DE_WINDOW_SOURCE_BASE_CS 26 : 26
-#define DE_WINDOW_SOURCE_BASE_CS_0 0
-#define DE_WINDOW_SOURCE_BASE_CS_1 1
-#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0
-
-#define DE_WINDOW_DESTINATION_BASE 0x000044
-#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27
-#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0
-#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1
-#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26
-#define DE_WINDOW_DESTINATION_BASE_CS_0 0
-#define DE_WINDOW_DESTINATION_BASE_CS_1 1
-#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0
-
-#define DE_ALPHA 0x000048
-#define DE_ALPHA_VALUE 7 : 0
-
-#define DE_WRAP 0x00004C
-#define DE_WRAP_X 31 : 16
-#define DE_WRAP_Y 15 : 0
-
-#define DE_STATUS 0x000050
-#define DE_STATUS_CSC 1 : 1
-#define DE_STATUS_CSC_CLEAR 0
-#define DE_STATUS_CSC_NOT_ACTIVE 0
-#define DE_STATUS_CSC_ACTIVE 1
-#define DE_STATUS_2D 0 : 0
-#define DE_STATUS_2D_CLEAR 0
-#define DE_STATUS_2D_NOT_ACTIVE 0
-#define DE_STATUS_2D_ACTIVE 1
-
-/* Color Space Conversion registers. */
-
-#define CSC_Y_SOURCE_BASE 0x0000C8
-#define CSC_Y_SOURCE_BASE_EXT 27 : 27
-#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0
-#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1
-#define CSC_Y_SOURCE_BASE_CS 26 : 26
-#define CSC_Y_SOURCE_BASE_CS_0 0
-#define CSC_Y_SOURCE_BASE_CS_1 1
-#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0
-
-#define CSC_CONSTANTS 0x0000CC
-#define CSC_CONSTANTS_Y 31 : 24
-#define CSC_CONSTANTS_R 23 : 16
-#define CSC_CONSTANTS_G 15 : 8
-#define CSC_CONSTANTS_B 7 : 0
-
-#define CSC_Y_SOURCE_X 0x0000D0
-#define CSC_Y_SOURCE_X_INTEGER 26 : 16
-#define CSC_Y_SOURCE_X_FRACTION 15 : 3
-
-#define CSC_Y_SOURCE_Y 0x0000D4
-#define CSC_Y_SOURCE_Y_INTEGER 27 : 16
-#define CSC_Y_SOURCE_Y_FRACTION 15 : 3
-
-#define CSC_U_SOURCE_BASE 0x0000D8
-#define CSC_U_SOURCE_BASE_EXT 27 : 27
-#define CSC_U_SOURCE_BASE_EXT_LOCAL 0
-#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1
-#define CSC_U_SOURCE_BASE_CS 26 : 26
-#define CSC_U_SOURCE_BASE_CS_0 0
-#define CSC_U_SOURCE_BASE_CS_1 1
-#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0
-
-#define CSC_V_SOURCE_BASE 0x0000DC
-#define CSC_V_SOURCE_BASE_EXT 27 : 27
-#define CSC_V_SOURCE_BASE_EXT_LOCAL 0
-#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1
-#define CSC_V_SOURCE_BASE_CS 26 : 26
-#define CSC_V_SOURCE_BASE_CS_0 0
-#define CSC_V_SOURCE_BASE_CS_1 1
-#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0
-
-#define CSC_SOURCE_DIMENSION 0x0000E0
-#define CSC_SOURCE_DIMENSION_X 31 : 16
-#define CSC_SOURCE_DIMENSION_Y 15 : 0
-
-#define CSC_SOURCE_PITCH 0x0000E4
-#define CSC_SOURCE_PITCH_Y 31 : 16
-#define CSC_SOURCE_PITCH_UV 15 : 0
-
-#define CSC_DESTINATION 0x0000E8
-#define CSC_DESTINATION_WRAP 31 : 31
-#define CSC_DESTINATION_WRAP_DISABLE 0
-#define CSC_DESTINATION_WRAP_ENABLE 1
-#define CSC_DESTINATION_X 27 : 16
-#define CSC_DESTINATION_Y 11 : 0
-
-#define CSC_DESTINATION_DIMENSION 0x0000EC
-#define CSC_DESTINATION_DIMENSION_X 31 : 16
-#define CSC_DESTINATION_DIMENSION_Y 15 : 0
-
-#define CSC_DESTINATION_PITCH 0x0000F0
-#define CSC_DESTINATION_PITCH_X 31 : 16
-#define CSC_DESTINATION_PITCH_Y 15 : 0
-
-#define CSC_SCALE_FACTOR 0x0000F4
-#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16
-#define CSC_SCALE_FACTOR_VERTICAL 15 : 0
-
-#define CSC_DESTINATION_BASE 0x0000F8
-#define CSC_DESTINATION_BASE_EXT 27 : 27
-#define CSC_DESTINATION_BASE_EXT_LOCAL 0
-#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1
-#define CSC_DESTINATION_BASE_CS 26 : 26
-#define CSC_DESTINATION_BASE_CS_0 0
-#define CSC_DESTINATION_BASE_CS_1 1
-#define CSC_DESTINATION_BASE_ADDRESS 25 : 0
-
-#define CSC_CONTROL 0x0000FC
-#define CSC_CONTROL_STATUS 31 : 31
-#define CSC_CONTROL_STATUS_STOP 0
-#define CSC_CONTROL_STATUS_START 1
-#define CSC_CONTROL_SOURCE_FORMAT 30 : 28
-#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0
-#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1
-#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2
-#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3
-#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4
-#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5
-#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6
-#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7
-#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26
-#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0
-#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1
-#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25
-#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0
-#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1
-#define CSC_CONTROL_VERTICAL_FILTER 24 : 24
-#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0
-#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1
-#define CSC_CONTROL_BYTE_ORDER 23 : 23
-#define CSC_CONTROL_BYTE_ORDER_YUYV 0
-#define CSC_CONTROL_BYTE_ORDER_UYVY 1
-
-#define DE_DATA_PORT_501 0x110000
-#define DE_DATA_PORT_712 0x400000
-#define DE_DATA_PORT_722 0x6000
-
-/* point to virtual Memory Map IO starting address */
-extern char *smtc_RegBaseAddress;
-/* point to virtual video memory starting address */
-extern char *smtc_VRAMBaseAddress;
-extern unsigned char smtc_de_busy;
-
-extern unsigned long memRead32(unsigned long nOffset);
-extern void memWrite32(unsigned long nOffset, unsigned long nData);
-extern unsigned long SMTC_read2Dreg(unsigned long nOffset);
-
-/* 2D functions */
-extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
- unsigned int bpp);
-
-extern void deWaitForNotBusy(void);
-
-extern void deVerticalLine(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long nX,
- unsigned long nY,
- unsigned long dst_height,
- unsigned long nColor);
-
-extern void deHorizontalLine(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long nX,
- unsigned long nY,
- unsigned long dst_width,
- unsigned long nColor);
-
-extern void deLine(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long nX1,
- unsigned long nY1,
- unsigned long nX2,
- unsigned long nY2,
- unsigned long nColor);
-
-extern void deFillRect(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long dst_X,
- unsigned long dst_Y,
- unsigned long dst_width,
- unsigned long dst_height,
- unsigned long nColor);
-
-extern void deRotatePattern(unsigned char *pattern_dstaddr,
- unsigned long pattern_src_addr,
- unsigned long pattern_BPP,
- unsigned long pattern_stride,
- int patternX,
- int patternY);
-
-extern void deCopy(unsigned long dst_base,
- unsigned long dst_pitch,
- unsigned long dst_BPP,
- unsigned long dst_X,
- unsigned long dst_Y,
- unsigned long dst_width,
- unsigned long dst_height,
- unsigned long src_base,
- unsigned long src_pitch,
- unsigned long src_X,
- unsigned long src_Y,
- pTransparent pTransp,
- unsigned char nROP2);
-
-/*
- * System memory to Video memory monochrome expansion.
- *
- * Source is monochrome image in system memory. This function expands the
- * monochrome data to color image in video memory.
- *
- * @pSrcbuf: pointer to start of source buffer in system memory
- * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top
- * down and -ive mean button up
- * @startBit: Mono data can start at any bit in a byte, this value should
- * be 0 to 7
- * @dBase: Address of destination : offset in frame buffer
- * @dPitch: Pitch value of destination surface in BYTE
- * @bpp: Color depth of destination surface
- * @dx, dy: Starting coordinate of destination surface
- * @width, height: width and height of rectange in pixel value
- * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in
- * the monochrome data)
- * @rop2: ROP value
- */
-
-extern long deSystemMem2VideoMemMonoBlt(
- const char *pSrcbuf,
- long srcDelta,
- unsigned long startBit,
- unsigned long dBase,
- unsigned long dPitch,
- unsigned long bpp,
- unsigned long dx, unsigned long dy,
- unsigned long width, unsigned long height,
- unsigned long fColor,
- unsigned long bColor,
- unsigned long rop2);
-
-extern unsigned long deGetTransparency(void);
-extern void deSetPixelFormat(unsigned long bpp);
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
index a4f6f49aef4..8d7261c052e 100644
--- a/drivers/staging/sm7xx/smtcfb.c
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -34,6 +34,7 @@
#include <linux/fb.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/console.h>
#include <linux/screen_info.h>
@@ -45,7 +46,6 @@
struct screen_info smtc_screen_info;
#include "smtcfb.h"
-#include "smtc2d.h"
#ifdef DEBUG
#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg)
@@ -120,10 +120,6 @@ static struct vesa_mode_table vesa_mode[] = {
char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */
-char *smtc_2DBaseAddress; /* 2D engine starting address */
-char *smtc_2Ddataport; /* 2D data port offset */
-short smtc_2Dacceleration;
-
static u32 colreg[17];
static struct par_info hw; /* hardware information */
@@ -135,16 +131,6 @@ u16 smtc_ChipIDs[] = {
#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
-void deWaitForNotBusy(void)
-{
- unsigned long i = 0x1000000;
- while (i--) {
- if ((smtc_seqr(0x16) & 0x18) == 0x10)
- break;
- }
- smtc_de_busy = 0;
-}
-
static void sm712_set_timing(struct smtcfb_info *sfb,
struct par_info *ppar_info)
{
@@ -324,7 +310,7 @@ static inline unsigned int chan_to_field(unsigned int chan,
return chan << bf->offset;
}
-static int smtcfb_blank(int blank_mode, struct fb_info *info)
+static int cfb_blank(int blank_mode, struct fb_info *info)
{
/* clear DPMS setting */
switch (blank_mode) {
@@ -622,93 +608,13 @@ smtcfb_write(struct fb_info *info, const char __user *buf, size_t count,
}
#endif /* ! __BIG_ENDIAN */
-#include "smtc2d.c"
-
-void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
-{
- struct par_info *p = (struct par_info *)info->par;
-
- if (smtc_2Dacceleration) {
- if (!area->width || !area->height)
- return;
-
- deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel,
- area->dx, area->dy, area->width, area->height,
- p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC);
-
- } else
- cfb_copyarea(info, area);
-}
-
-void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
-{
- struct par_info *p = (struct par_info *)info->par;
-
- if (smtc_2Dacceleration) {
- if (!rect->width || !rect->height)
- return;
- if (info->var.bits_per_pixel >= 24)
- deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3,
- rect->dy * 3, rect->width * 3, rect->height,
- rect->color);
- else
- deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy,
- rect->width, rect->height, rect->color);
- } else
- cfb_fillrect(info, rect);
-}
-
-void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image)
-{
- struct par_info *p = (struct par_info *)info->par;
- u32 bg_col = 0, fg_col = 0;
-
- if ((smtc_2Dacceleration) && (image->depth == 1)) {
- if (smtc_de_busy)
- deWaitForNotBusy();
-
- switch (info->var.bits_per_pixel) {
- case 8:
- bg_col = image->bg_color;
- fg_col = image->fg_color;
- break;
- case 16:
- bg_col =
- ((u32 *) (info->pseudo_palette))[image->bg_color];
- fg_col =
- ((u32 *) (info->pseudo_palette))[image->fg_color];
- break;
- case 32:
- bg_col =
- ((u32 *) (info->pseudo_palette))[image->bg_color];
- fg_col =
- ((u32 *) (info->pseudo_palette))[image->fg_color];
- break;
- }
-
- deSystemMem2VideoMemMonoBlt(
- image->data,
- image->width / 8,
- 0,
- p->BaseAddressInVRAM,
- 0,
- 0,
- image->dx, image->dy,
- image->width, image->height,
- fg_col, bg_col,
- 0x0C);
-
- } else
- cfb_imageblit(info, image);
-}
-
static struct fb_ops smtcfb_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = smtc_setcolreg,
- .fb_blank = smtcfb_blank,
- .fb_fillrect = smtcfb_fillrect,
- .fb_imageblit = smtcfb_imageblit,
- .fb_copyarea = smtcfb_copyarea,
+ .fb_blank = cfb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_imageblit = cfb_imageblit,
+ .fb_copyarea = cfb_copyarea,
#ifdef __BIG_ENDIAN
.fb_read = smtcfb_read,
.fb_write = smtcfb_write,
@@ -772,12 +678,6 @@ void smtcfb_setmode(struct smtcfb_info *sfb)
hw.height = sfb->fb.var.yres;
hw.hz = 60;
smtc_set_timing(sfb, &hw);
- if (smtc_2Dacceleration) {
- printk("2D acceleration enabled!\n");
- /* Init smtc drawing engine */
- deInit(sfb->fb.var.xres, sfb->fb.var.yres,
- sfb->fb.var.bits_per_pixel);
- }
}
/*
@@ -1004,9 +904,7 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev,
#endif
hw.m_pMMIO = (smtc_RegBaseAddress =
smtc_VRAMBaseAddress + 0x00700000);
- smtc_2DBaseAddress = (hw.m_pDPR =
- smtc_VRAMBaseAddress + 0x00408000);
- smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712;
+ hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000;
hw.m_pVPR = hw.m_pLFB + 0x0040c000;
#ifdef __BIG_ENDIAN
if (sfb->fb.var.bits_per_pixel == 32) {
@@ -1035,27 +933,21 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev,
if (sfb->fb.var.bits_per_pixel == 32)
smtc_seqw(0x17, 0x30);
#endif
-#ifdef CONFIG_FB_SM7XX_ACCEL
- smtc_2Dacceleration = 1;
-#endif
break;
case 0x720:
sfb->fb.fix.mmio_start = pFramebufferPhysical;
sfb->fb.fix.mmio_len = 0x00200000;
smem_size = SM722_VIDEOMEMORYSIZE;
- smtc_2DBaseAddress = (hw.m_pDPR =
- ioremap(pFramebufferPhysical, 0x00a00000));
+ hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000);
hw.m_pLFB = (smtc_VRAMBaseAddress =
- smtc_2DBaseAddress + 0x00200000);
+ hw.m_pDPR + 0x00200000);
hw.m_pMMIO = (smtc_RegBaseAddress =
- smtc_2DBaseAddress + 0x000c0000);
- smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722;
- hw.m_pVPR = smtc_2DBaseAddress + 0x800;
+ hw.m_pDPR + 0x000c0000);
+ hw.m_pVPR = hw.m_pDPR + 0x800;
smtc_seqw(0x62, 0xff);
smtc_seqw(0x6a, 0x0d);
smtc_seqw(0x6b, 0x02);
- smtc_2Dacceleration = 0;
break;
default:
printk(KERN_INFO
@@ -1103,7 +995,7 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev,
/* Jason (08/11/2009) PCI_DRV wrapper essential structs */
-static struct pci_device_id smtcfb_pci_table[] = {
+static const struct pci_device_id smtcfb_pci_table[] = {
{0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
diff --git a/drivers/staging/strip/strip.c b/drivers/staging/strip/strip.c
index 698aade79d4..c976c6b4d28 100644
--- a/drivers/staging/strip/strip.c
+++ b/drivers/staging/strip/strip.c
@@ -107,6 +107,7 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
#include <linux/serialP.h>
#include <linux/rcupdate.h>
#include <linux/compat.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <net/net_namespace.h>
diff --git a/drivers/staging/udlfb/Kconfig b/drivers/staging/udlfb/Kconfig
index 641692da0e4..65bd5db4ca5 100644
--- a/drivers/staging/udlfb/Kconfig
+++ b/drivers/staging/udlfb/Kconfig
@@ -1,8 +1,14 @@
config FB_UDL
tristate "Displaylink USB Framebuffer support"
depends on FB && USB
+ select FB_MODE_HELPERS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
---help---
- This is an experimental driver for DisplayLink USB devices
- that provides a framebuffer device. A normal framebuffer can
- be used with this driver, or xorg can be run on the device
- using it.
+ This is a kernel framebuffer driver for DisplayLink USB devices.
+ Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
+ mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
+ To compile as a module, choose M here: the module name is udlfb.
diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c
index f5416af1e90..a78ade0dc68 100644
--- a/drivers/staging/udlfb/udlfb.c
+++ b/drivers/staging/udlfb/udlfb.c
@@ -1,17 +1,20 @@
-/*****************************************************************************
- * DLFB Kernel Driver *
- * Version 0.2 (udlfb) *
- * (C) 2009 Roberto De Ioris <roberto@unbit.it> *
- * *
- * This file is licensed under the GPLv2. See COPYING in the package. *
- * Based on the amazing work of Florian Echtler and libdlo 0.1 *
- * *
- * *
- * 10.06.09 release 0.2.3 (edid ioctl, fallback for unsupported modes) *
- * 05.06.09 release 0.2.2 (real screen blanking, rle compression, double buffer) *
- * 31.05.09 release 0.2 *
- * 22.05.09 First public (ugly) release *
- *****************************************************************************/
+/*
+ * udlfb.c -- Framebuffer driver for DisplayLink USB controller
+ *
+ * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it>
+ * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com>
+ * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License v2. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Layout is based on skeletonfb by James Simmons and Geert Uytterhoeven,
+ * usb-skeleton by GregKH.
+ *
+ * Device-specific portions based on information from Displaylink, with work
+ * from Florian Echtler, Henrik Bjerregaard Pedersen, and others.
+ */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -20,606 +23,673 @@
#include <linux/uaccess.h>
#include <linux/mm.h>
#include <linux/fb.h>
-#include <linux/mutex.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include "udlfb.h"
-#define DRIVER_VERSION "DLFB 0.2"
+static struct fb_fix_screeninfo dlfb_fix = {
+ .id = "udlfb",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .accel = FB_ACCEL_NONE,
+};
-/* memory functions taken from vfb */
+static const u32 udlfb_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
+#ifdef FBINFO_VIRTFB
+ FBINFO_VIRTFB |
+#endif
+ FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT |
+ FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR;
-static void *rvmalloc(unsigned long size)
-{
- void *mem;
- unsigned long adr;
+/*
+ * There are many DisplayLink-based products, all with unique PIDs. We are able
+ * to support all volume ones (circa 2009) with a single driver, so we match
+ * globally on VID. TODO: Probe() needs to detect when we might be running
+ * "future" chips, and bail on those, so a compatible driver can match.
+ */
+static struct usb_device_id id_table[] = {
+ {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,},
+ {},
+};
+MODULE_DEVICE_TABLE(usb, id_table);
- size = PAGE_ALIGN(size);
- mem = vmalloc_32(size);
- if (!mem)
- return NULL;
+#ifndef CONFIG_FB_DEFERRED_IO
+#warning message "kernel FB_DEFFERRED_IO option to support generic fbdev apps"
+#endif
- 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;
- }
+#ifndef CONFIG_FB_SYS_IMAGEBLIT
+#ifndef CONFIG_FB_SYS_IMAGEBLIT_MODULE
+#warning message "FB_SYS_* in kernel or module option to support fb console"
+#endif
+#endif
- return mem;
-}
+#ifndef CONFIG_FB_MODE_HELPERS
+#warning message "kernel FB_MODE_HELPERS required. Expect build break"
+#endif
-static void rvfree(void *mem, unsigned long size)
-{
- unsigned long adr;
+/* dlfb keeps a list of urbs for efficient bulk transfers */
+static void dlfb_urb_completion(struct urb *urb);
+static struct urb *dlfb_get_urb(struct dlfb_data *dev);
+static int dlfb_submit_urb(struct dlfb_data *dev, struct urb * urb, size_t len);
+static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size);
+static void dlfb_free_urb_list(struct dlfb_data *dev);
- if (!mem)
- return;
+/* other symbols with dependents */
+#ifdef CONFIG_FB_DEFERRED_IO
+static struct fb_deferred_io dlfb_defio;
+#endif
- adr = (unsigned long)mem;
- while ((long)size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree(mem);
+/*
+ * All DisplayLink bulk operations start with 0xAF, followed by specific code
+ * All operations are written to buffers which then later get sent to device
+ */
+static char *dlfb_set_register(char *buf, u8 reg, u8 val)
+{
+ *buf++ = 0xAF;
+ *buf++ = 0x20;
+ *buf++ = reg;
+ *buf++ = val;
+ return buf;
}
-static int dlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+static char *dlfb_vidreg_lock(char *buf)
{
- unsigned long start = vma->vm_start;
- unsigned long size = vma->vm_end - vma->vm_start;
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long page, pos;
-
- printk("MMAP: %lu %u\n", offset + size, info->fix.smem_len);
-
- if (offset + size > info->fix.smem_len)
- return -EINVAL;
-
- pos = (unsigned long)info->fix.smem_start + offset;
-
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
- return -EAGAIN;
-
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
-
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
- return 0;
-
+ return dlfb_set_register(buf, 0xFF, 0x00);
}
-/* ioctl structure */
-struct dloarea {
- int x, y;
- int w, h;
- int x2, y2;
-};
+static char *dlfb_vidreg_unlock(char *buf)
+{
+ return dlfb_set_register(buf, 0xFF, 0xFF);
+}
/*
-static struct usb_device_id id_table [] = {
- { USB_DEVICE(0x17e9, 0x023d) },
- { }
-};
-*/
+ * On/Off for driving the DisplayLink framebuffer to the display
+ */
+static char *dlfb_enable_hvsync(char *buf, bool enable)
+{
+ if (enable)
+ return dlfb_set_register(buf, 0x1F, 0x00);
+ else
+ return dlfb_set_register(buf, 0x1F, 0x01);
+}
-static struct usb_device_id id_table[] = {
- {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,},
- {},
-};
-MODULE_DEVICE_TABLE(usb, id_table);
+static char *dlfb_set_color_depth(char *buf, u8 selection)
+{
+ return dlfb_set_register(buf, 0x00, selection);
+}
-static struct usb_driver dlfb_driver;
+static char *dlfb_set_base16bpp(char *wrptr, u32 base)
+{
+ /* the base pointer is 16 bits wide, 0x20 is hi byte. */
+ wrptr = dlfb_set_register(wrptr, 0x20, base >> 16);
+ wrptr = dlfb_set_register(wrptr, 0x21, base >> 8);
+ return dlfb_set_register(wrptr, 0x22, base);
+}
-// thanks to Henrik Bjerregaard Pedersen for this function
-static char *rle_compress16(uint16_t * src, char *dst, int rem)
+/*
+ * DisplayLink HW has separate 16bpp and 8bpp framebuffers.
+ * In 24bpp modes, the low 323 RGB bits go in the 8bpp framebuffer
+ */
+static char *dlfb_set_base8bpp(char *wrptr, u32 base)
{
+ wrptr = dlfb_set_register(wrptr, 0x26, base >> 16);
+ wrptr = dlfb_set_register(wrptr, 0x27, base >> 8);
+ return dlfb_set_register(wrptr, 0x28, base);
+}
- int rl;
- uint16_t pix0;
- char *end_if_raw = dst + 6 + 2 * rem;
+static char *dlfb_set_register_16(char *wrptr, u8 reg, u16 value)
+{
+ wrptr = dlfb_set_register(wrptr, reg, value >> 8);
+ return dlfb_set_register(wrptr, reg+1, value);
+}
- dst += 6; // header will be filled in if RLE is worth it
+/*
+ * This is kind of weird because the controller takes some
+ * register values in a different byte order than other registers.
+ */
+static char *dlfb_set_register_16be(char *wrptr, u8 reg, u16 value)
+{
+ wrptr = dlfb_set_register(wrptr, reg, value);
+ return dlfb_set_register(wrptr, reg+1, value >> 8);
+}
- while (rem && dst < end_if_raw) {
- char *start = (char *)src;
+/*
+ * LFSR is linear feedback shift register. The reason we have this is
+ * because the display controller needs to minimize the clock depth of
+ * various counters used in the display path. So this code reverses the
+ * provided value into the lfsr16 value by counting backwards to get
+ * the value that needs to be set in the hardware comparator to get the
+ * same actual count. This makes sense once you read above a couple of
+ * times and think about it from a hardware perspective.
+ */
+static u16 dlfb_lfsr16(u16 actual_count)
+{
+ u32 lv = 0xFFFF; /* This is the lfsr value that the hw starts with */
- pix0 = *src++;
- rl = 1;
- rem--;
- while (rem && *src == pix0)
- rem--, rl++, src++;
- *dst++ = rl;
- *dst++ = start[1];
- *dst++ = start[0];
+ while (actual_count--) {
+ lv = ((lv << 1) |
+ (((lv >> 15) ^ (lv >> 4) ^ (lv >> 2) ^ (lv >> 1)) & 1))
+ & 0xFFFF;
}
- return dst;
+ return (u16) lv;
}
/*
-Thanks to Henrik Bjerregaard Pedersen for rle implementation and code refactoring.
-Next step is huffman compression.
-*/
-
-static int
-image_blit(struct dlfb_data *dev_info, int x, int y, int width, int height,
- char *data)
+ * This does LFSR conversion on the value that is to be written.
+ * See LFSR explanation above for more detail.
+ */
+static char *dlfb_set_register_lfsr16(char *wrptr, u8 reg, u16 value)
{
+ return dlfb_set_register_16(wrptr, reg, dlfb_lfsr16(value));
+}
- int i, j, base;
- int rem = width;
- int ret;
-
- int firstdiff, thistime;
-
- char *bufptr;
-
- if (x + width > dev_info->info->var.xres)
- return -EINVAL;
-
- if (y + height > dev_info->info->var.yres)
- return -EINVAL;
+/*
+ * This takes a standard fbdev screeninfo struct and all of its monitor mode
+ * details and converts them into the DisplayLink equivalent register commands.
+ */
+static char *dlfb_set_vid_cmds(char *wrptr, struct fb_var_screeninfo *var)
+{
+ u16 xds, yds;
+ u16 xde, yde;
+ u16 yec;
- mutex_lock(&dev_info->bulk_mutex);
+ /* x display start */
+ xds = var->left_margin + var->hsync_len;
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x01, xds);
+ /* x display end */
+ xde = xds + var->xres;
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x03, xde);
- base =
- dev_info->base16 + ((dev_info->info->var.xres * 2 * y) + (x * 2));
+ /* y display start */
+ yds = var->upper_margin + var->vsync_len;
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x05, yds);
+ /* y display end */
+ yde = yds + var->yres;
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x07, yde);
- data += (dev_info->info->var.xres * 2 * y) + (x * 2);
+ /* x end count is active + blanking - 1 */
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x09,
+ xde + var->right_margin - 1);
- /* printk("IMAGE_BLIT\n"); */
+ /* libdlo hardcodes hsync start to 1 */
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x0B, 1);
- bufptr = dev_info->buf;
+ /* hsync end is width of sync pulse + 1 */
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x0D, var->hsync_len + 1);
- for (i = y; i < y + height; i++) {
+ /* hpixels is active pixels */
+ wrptr = dlfb_set_register_16(wrptr, 0x0F, var->xres);
- if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
- bufptr = dev_info->buf;
- }
+ /* yendcount is vertical active + vertical blanking */
+ yec = var->yres + var->upper_margin + var->lower_margin +
+ var->vsync_len;
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x11, yec);
- rem = width;
+ /* libdlo hardcodes vsync start to 0 */
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x13, 0);
- /* printk("WRITING LINE %d\n", i); */
+ /* vsync end is width of vsync pulse */
+ wrptr = dlfb_set_register_lfsr16(wrptr, 0x15, var->vsync_len);
- while (rem) {
+ /* vpixels is active pixels */
+ wrptr = dlfb_set_register_16(wrptr, 0x17, var->yres);
- if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
- ret =
- dlfb_bulk_msg(dev_info,
- bufptr - dev_info->buf);
- bufptr = dev_info->buf;
- }
- // number of pixels to consider this time
- thistime = rem;
- if (thistime > 255)
- thistime = 255;
-
- // find position of first pixel that has changed
- firstdiff = -1;
- for (j = 0; j < thistime * 2; j++) {
- if (dev_info->backing_buffer
- [base - dev_info->base16 + j] != data[j]) {
- firstdiff = j / 2;
- break;
- }
- }
+ /* convert picoseconds to 5kHz multiple for pclk5k = x * 1E12/5k */
+ wrptr = dlfb_set_register_16be(wrptr, 0x1B,
+ 200*1000*1000/var->pixclock);
- if (firstdiff >= 0) {
- char *end_of_rle;
-
- end_of_rle =
- rle_compress16((uint16_t *) (data +
- firstdiff * 2),
- bufptr,
- thistime - firstdiff);
-
- if (end_of_rle <
- bufptr + 6 + 2 * (thistime - firstdiff)) {
- bufptr[0] = 0xAF;
- bufptr[1] = 0x69;
-
- bufptr[2] =
- (char)((base +
- firstdiff * 2) >> 16);
- bufptr[3] =
- (char)((base + firstdiff * 2) >> 8);
- bufptr[4] =
- (char)(base + firstdiff * 2);
- bufptr[5] = thistime - firstdiff;
-
- bufptr = end_of_rle;
-
- } else {
- // fallback to raw (or some other encoding?)
- *bufptr++ = 0xAF;
- *bufptr++ = 0x68;
-
- *bufptr++ =
- (char)((base +
- firstdiff * 2) >> 16);
- *bufptr++ =
- (char)((base + firstdiff * 2) >> 8);
- *bufptr++ =
- (char)(base + firstdiff * 2);
- *bufptr++ = thistime - firstdiff;
- // PUT COMPRESSION HERE
- for (j = firstdiff * 2;
- j < thistime * 2; j += 2) {
- *bufptr++ = data[j + 1];
- *bufptr++ = data[j];
- }
- }
- }
+ return wrptr;
+}
- base += thistime * 2;
- data += thistime * 2;
- rem -= thistime;
- }
+/*
+ * This takes a standard fbdev screeninfo struct that was fetched or prepared
+ * and then generates the appropriate command sequence that then drives the
+ * display controller.
+ */
+static int dlfb_set_video_mode(struct dlfb_data *dev,
+ struct fb_var_screeninfo *var)
+{
+ char *buf;
+ char *wrptr;
+ int retval = 0;
+ int writesize;
+ struct urb *urb;
- memcpy(dev_info->backing_buffer + (base - dev_info->base16) -
- (width * 2), data - (width * 2), width * 2);
+ if (!atomic_read(&dev->usb_active))
+ return -EPERM;
- base += (dev_info->info->var.xres * 2) - (width * 2);
- data += (dev_info->info->var.xres * 2) - (width * 2);
+ urb = dlfb_get_urb(dev);
+ if (!urb)
+ return -ENOMEM;
+ buf = (char *) urb->transfer_buffer;
- }
+ /*
+ * This first section has to do with setting the base address on the
+ * controller * associated with the display. There are 2 base
+ * pointers, currently, we only * use the 16 bpp segment.
+ */
+ wrptr = dlfb_vidreg_lock(buf);
+ wrptr = dlfb_set_color_depth(wrptr, 0x00);
+ /* set base for 16bpp segment to 0 */
+ wrptr = dlfb_set_base16bpp(wrptr, 0);
+ /* set base for 8bpp segment to end of fb */
+ wrptr = dlfb_set_base8bpp(wrptr, dev->info->fix.smem_len);
- if (bufptr > dev_info->buf) {
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
- }
+ wrptr = dlfb_set_vid_cmds(wrptr, var);
+ wrptr = dlfb_enable_hvsync(wrptr, true);
+ wrptr = dlfb_vidreg_unlock(wrptr);
- mutex_unlock(&dev_info->bulk_mutex);
+ writesize = wrptr - buf;
- return base;
+ retval = dlfb_submit_urb(dev, urb, writesize);
+ return retval;
}
-static int
-draw_rect(struct dlfb_data *dev_info, int x, int y, int width, int height,
- unsigned char red, unsigned char green, unsigned char blue)
+static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
+ unsigned long start = vma->vm_start;
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ unsigned long page, pos;
+ struct dlfb_data *dev = info->par;
- int i, j, base;
- int ret;
- unsigned short col =
- (((((red) & 0xF8) | ((green) >> 5)) & 0xFF) << 8) +
- (((((green) & 0x1C) << 3) | ((blue) >> 3)) & 0xFF);
- int rem = width;
-
- char *bufptr;
+ dl_notice("MMAP: %lu %u\n", offset + size, info->fix.smem_len);
- if (x + width > dev_info->info->var.xres)
+ if (offset + size > info->fix.smem_len)
return -EINVAL;
- if (y + height > dev_info->info->var.yres)
- return -EINVAL;
+ pos = (unsigned long)info->fix.smem_start + offset;
- mutex_lock(&dev_info->bulk_mutex);
+ while (size > 0) {
+ page = vmalloc_to_pfn((void *)pos);
+ if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
+ return -EAGAIN;
- base = dev_info->base16 + (dev_info->info->var.xres * 2 * y) + (x * 2);
+ start += PAGE_SIZE;
+ pos += PAGE_SIZE;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
- bufptr = dev_info->buf;
+ vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+ return 0;
- for (i = y; i < y + height; i++) {
+}
- for (j = 0; j < width * 2; j += 2) {
- dev_info->backing_buffer[base - dev_info->base16 + j] =
- (char)(col >> 8);
- dev_info->backing_buffer[base - dev_info->base16 + j +
- 1] = (char)(col);
- }
- if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
- bufptr = dev_info->buf;
+/*
+ * Trims identical data from front and back of line
+ * Sets new front buffer address and width
+ * And returns byte count of identical pixels
+ * Assumes CPU natural alignment (unsigned long)
+ * for back and front buffer ptrs and width
+ */
+static int dlfb_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes)
+{
+ int j, k;
+ const unsigned long *back = (const unsigned long *) bback;
+ const unsigned long *front = (const unsigned long *) *bfront;
+ const int width = *width_bytes / sizeof(unsigned long);
+ int identical = width;
+ int start = width;
+ int end = width;
+
+ prefetch((void *) front);
+ prefetch((void *) back);
+
+ for (j = 0; j < width; j++) {
+ if (back[j] != front[j]) {
+ start = j;
+ break;
}
+ }
- rem = width;
-
- while (rem) {
-
- if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
- ret =
- dlfb_bulk_msg(dev_info,
- bufptr - dev_info->buf);
- bufptr = dev_info->buf;
- }
-
- *bufptr++ = 0xAF;
- *bufptr++ = 0x69;
-
- *bufptr++ = (char)(base >> 16);
- *bufptr++ = (char)(base >> 8);
- *bufptr++ = (char)(base);
-
- if (rem > 255) {
- *bufptr++ = 255;
- *bufptr++ = 255;
- rem -= 255;
- base += 255 * 2;
- } else {
- *bufptr++ = rem;
- *bufptr++ = rem;
- base += rem * 2;
- rem = 0;
- }
-
- *bufptr++ = (char)(col >> 8);
- *bufptr++ = (char)(col);
-
+ for (k = width - 1; k > j; k--) {
+ if (back[k] != front[k]) {
+ end = k+1;
+ break;
}
-
- base += (dev_info->info->var.xres * 2) - (width * 2);
-
}
- if (bufptr > dev_info->buf)
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+ identical = start + (width - end);
+ *bfront = (u8 *) &front[start];
+ *width_bytes = (end - start) * sizeof(unsigned long);
- mutex_unlock(&dev_info->bulk_mutex);
-
- return 1;
+ return identical * sizeof(unsigned long);
}
-static void swapfb(struct dlfb_data *dev_info)
+/*
+Render a command stream for an encoded horizontal line segment of pixels.
+
+A command buffer holds several commands.
+It always begins with a fresh command header
+(the protocol doesn't require this, but we enforce it to allow
+multiple buffers to be potentially encoded and sent in parallel).
+A single command encodes one contiguous horizontal line of pixels
+
+The function relies on the client to do all allocation, so that
+rendering can be done directly to output buffers (e.g. USB URBs).
+The function fills the supplied command buffer, providing information
+on where it left off, so the client may call in again with additional
+buffers if the line will take several buffers to complete.
+
+A single command can transmit a maximum of 256 pixels,
+regardless of the compression ratio (protocol design limit).
+To the hardware, 0 for a size byte means 256
+
+Rather than 256 pixel commands which are either rl or raw encoded,
+the rlx command simply assumes alternating raw and rl spans within one cmd.
+This has a slightly larger header overhead, but produces more even results.
+It also processes all data (read and write) in a single pass.
+Performance benchmarks of common cases show it having just slightly better
+compression than 256 pixel raw -or- rle commands, with similar CPU consumpion.
+But for very rl friendly data, will compress not quite as well.
+*/
+static void dlfb_compress_hline(
+ const uint16_t **pixel_start_ptr,
+ const uint16_t *const pixel_end,
+ uint32_t *device_address_ptr,
+ uint8_t **command_buffer_ptr,
+ const uint8_t *const cmd_buffer_end)
{
+ const uint16_t *pixel = *pixel_start_ptr;
+ uint32_t dev_addr = *device_address_ptr;
+ uint8_t *cmd = *command_buffer_ptr;
+ const int bpp = 2;
+
+ while ((pixel_end > pixel) &&
+ (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) {
+ uint8_t *raw_pixels_count_byte = 0;
+ uint8_t *cmd_pixels_count_byte = 0;
+ const uint16_t *raw_pixel_start = 0;
+ const uint16_t *cmd_pixel_start, *cmd_pixel_end = 0;
+ const uint32_t be_dev_addr = cpu_to_be32(dev_addr);
+
+ prefetchw((void *) cmd); /* pull in one cache line at least */
+
+ *cmd++ = 0xAF;
+ *cmd++ = 0x6B;
+ *cmd++ = (uint8_t) ((be_dev_addr >> 8) & 0xFF);
+ *cmd++ = (uint8_t) ((be_dev_addr >> 16) & 0xFF);
+ *cmd++ = (uint8_t) ((be_dev_addr >> 24) & 0xFF);
+
+ cmd_pixels_count_byte = cmd++; /* we'll know this later */
+ cmd_pixel_start = pixel;
+
+ raw_pixels_count_byte = cmd++; /* we'll know this later */
+ raw_pixel_start = pixel;
+
+ cmd_pixel_end = pixel + min(MAX_CMD_PIXELS + 1,
+ min((int)(pixel_end - pixel),
+ (int)(cmd_buffer_end - cmd) / bpp));
+
+ prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
+
+ while (pixel < cmd_pixel_end) {
+ const uint16_t * const repeating_pixel = pixel;
+
+ *(uint16_t *)cmd = cpu_to_be16p(pixel);
+ cmd += 2;
+ pixel++;
+
+ if (unlikely((pixel < cmd_pixel_end) &&
+ (*pixel == *repeating_pixel))) {
+ /* go back and fill in raw pixel count */
+ *raw_pixels_count_byte = ((repeating_pixel -
+ raw_pixel_start) + 1) & 0xFF;
+
+ while ((pixel < cmd_pixel_end)
+ && (*pixel == *repeating_pixel)) {
+ pixel++;
+ }
- int tmpbase;
- char *bufptr;
-
- mutex_lock(&dev_info->bulk_mutex);
-
- tmpbase = dev_info->base16;
-
- dev_info->base16 = dev_info->base16d;
- dev_info->base16d = tmpbase;
+ /* immediately after raw data is repeat byte */
+ *cmd++ = ((pixel - repeating_pixel) - 1) & 0xFF;
- bufptr = dev_info->buf;
+ /* Then start another raw pixel span */
+ raw_pixel_start = pixel;
+ raw_pixels_count_byte = cmd++;
+ }
+ }
- bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
+ if (pixel > raw_pixel_start) {
+ /* finalize last RAW span */
+ *raw_pixels_count_byte = (pixel-raw_pixel_start) & 0xFF;
+ }
- // set addresses
- bufptr =
- dlfb_set_register(bufptr, 0x20, (char)(dev_info->base16 >> 16));
- bufptr = dlfb_set_register(bufptr, 0x21, (char)(dev_info->base16 >> 8));
- bufptr = dlfb_set_register(bufptr, 0x22, (char)(dev_info->base16));
+ *cmd_pixels_count_byte = (pixel - cmd_pixel_start) & 0xFF;
+ dev_addr += (pixel - cmd_pixel_start) * bpp;
+ }
- bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
+ if (cmd_buffer_end <= MIN_RLX_CMD_BYTES + cmd) {
+ /* Fill leftover bytes with no-ops */
+ if (cmd_buffer_end > cmd)
+ memset(cmd, 0xAF, cmd_buffer_end - cmd);
+ cmd = (uint8_t *) cmd_buffer_end;
+ }
- dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+ *command_buffer_ptr = cmd;
+ *pixel_start_ptr = pixel;
+ *device_address_ptr = dev_addr;
- mutex_unlock(&dev_info->bulk_mutex);
+ return;
}
-static int copyfb(struct dlfb_data *dev_info)
+/*
+ * There are 3 copies of every pixel: The front buffer that the fbdev
+ * client renders to, the actual framebuffer across the USB bus in hardware
+ * (that we can only write to, slowly, and can never read), and (optionally)
+ * our shadow copy that tracks what's been sent to that hardware buffer.
+ */
+static void dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
+ const char *front, char **urb_buf_ptr,
+ u32 byte_offset, u32 byte_width,
+ int *ident_ptr, int *sent_ptr)
{
- int base;
- int source;
- int rem;
- int i, ret;
-
- char *bufptr;
-
- base = dev_info->base16d;
-
- mutex_lock(&dev_info->bulk_mutex);
-
- source = dev_info->base16;
-
- bufptr = dev_info->buf;
-
- for (i = 0; i < dev_info->info->var.yres; i++) {
-
- if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
- bufptr = dev_info->buf;
- }
-
- rem = dev_info->info->var.xres;
-
- while (rem) {
-
- if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
- ret =
- dlfb_bulk_msg(dev_info,
- bufptr - dev_info->buf);
- bufptr = dev_info->buf;
-
- }
-
- *bufptr++ = 0xAF;
- *bufptr++ = 0x6A;
-
- *bufptr++ = (char)(base >> 16);
- *bufptr++ = (char)(base >> 8);
- *bufptr++ = (char)(base);
-
- if (rem > 255) {
- *bufptr++ = 255;
- *bufptr++ = (char)(source >> 16);
- *bufptr++ = (char)(source >> 8);
- *bufptr++ = (char)(source);
-
- rem -= 255;
- base += 255 * 2;
- source += 255 * 2;
-
- } else {
- *bufptr++ = rem;
- *bufptr++ = (char)(source >> 16);
- *bufptr++ = (char)(source >> 8);
- *bufptr++ = (char)(source);
+ const u8 *line_start, *line_end, *next_pixel;
+ u32 dev_addr = dev->base16 + byte_offset;
+ struct urb *urb = *urb_ptr;
+ u8 *cmd = *urb_buf_ptr;
+ u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
+
+ line_start = (u8 *) (front + byte_offset);
+ next_pixel = line_start;
+ line_end = next_pixel + byte_width;
+
+ if (dev->backing_buffer) {
+ int offset;
+ const u8 *back_start = (u8 *) (dev->backing_buffer
+ + byte_offset);
+
+ *ident_ptr += dlfb_trim_hline(back_start, &next_pixel,
+ &byte_width);
+
+ offset = next_pixel - line_start;
+ line_end = next_pixel + byte_width;
+ dev_addr += offset;
+ back_start += offset;
+ line_start += offset;
+
+ memcpy((char *)back_start, (char *) line_start,
+ byte_width);
+ }
- base += rem * 2;
- source += rem * 2;
- rem = 0;
- }
+ while (next_pixel < line_end) {
+
+ dlfb_compress_hline((const uint16_t **) &next_pixel,
+ (const uint16_t *) line_end, &dev_addr,
+ (u8 **) &cmd, (u8 *) cmd_end);
+
+ if (cmd >= cmd_end) {
+ int len = cmd - (u8 *) urb->transfer_buffer;
+ if (dlfb_submit_urb(dev, urb, len))
+ return; /* lost pixels is set */
+ *sent_ptr += len;
+ urb = dlfb_get_urb(dev);
+ if (!urb)
+ return; /* lost_pixels is set */
+ *urb_ptr = urb;
+ cmd = urb->transfer_buffer;
+ cmd_end = &cmd[urb->transfer_buffer_length];
}
}
- if (bufptr > dev_info->buf)
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
-
- mutex_unlock(&dev_info->bulk_mutex);
-
- return 1;
-
+ *urb_buf_ptr = cmd;
}
-static int
-copyarea(struct dlfb_data *dev_info, int dx, int dy, int sx, int sy,
- int width, int height)
+int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
+ int width, int height, char *data)
{
- int base;
- int source;
- int rem;
int i, ret;
-
- char *bufptr;
-
- if (dx + width > dev_info->info->var.xres)
+ char *cmd;
+ cycles_t start_cycles, end_cycles;
+ int bytes_sent = 0;
+ int bytes_identical = 0;
+ struct urb *urb;
+ int aligned_x;
+
+ start_cycles = get_cycles();
+
+ aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
+ width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
+ x = aligned_x;
+
+ if ((width <= 0) ||
+ (x + width > dev->info->var.xres) ||
+ (y + height > dev->info->var.yres))
return -EINVAL;
- if (dy + height > dev_info->info->var.yres)
- return -EINVAL;
-
- mutex_lock(&dev_info->bulk_mutex);
+ if (!atomic_read(&dev->usb_active))
+ return 0;
- base =
- dev_info->base16 + (dev_info->info->var.xres * 2 * dy) + (dx * 2);
- source = (dev_info->info->var.xres * 2 * sy) + (sx * 2);
+ urb = dlfb_get_urb(dev);
+ if (!urb)
+ return 0;
+ cmd = urb->transfer_buffer;
- bufptr = dev_info->buf;
+ for (i = y; i < y + height ; i++) {
+ const int line_offset = dev->info->fix.line_length * i;
+ const int byte_offset = line_offset + (x * BPP);
- for (i = sy; i < sy + height; i++) {
+ dlfb_render_hline(dev, &urb, (char *) dev->info->fix.smem_start,
+ &cmd, byte_offset, width * BPP,
+ &bytes_identical, &bytes_sent);
+ }
- memcpy(dev_info->backing_buffer + base - dev_info->base16,
- dev_info->backing_buffer + source, width * 2);
+ if (cmd > (char *) urb->transfer_buffer) {
+ /* Send partial buffer remaining before exiting */
+ int len = cmd - (char *) urb->transfer_buffer;
+ ret = dlfb_submit_urb(dev, urb, len);
+ bytes_sent += len;
+ } else
+ dlfb_urb_completion(urb);
+
+ atomic_add(bytes_sent, &dev->bytes_sent);
+ atomic_add(bytes_identical, &dev->bytes_identical);
+ atomic_add(width*height*2, &dev->bytes_rendered);
+ end_cycles = get_cycles();
+ atomic_add(((unsigned int) ((end_cycles - start_cycles)
+ >> 10)), /* Kcycles */
+ &dev->cpu_kcycles_used);
- if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
- bufptr = dev_info->buf;
- }
-
- rem = width;
+ return 0;
+}
- while (rem) {
+/* hardware has native COPY command (see libdlo), but not worth it for fbcon */
+static void dlfb_ops_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
- if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
- ret =
- dlfb_bulk_msg(dev_info,
- bufptr - dev_info->buf);
- bufptr = dev_info->buf;
- }
+ struct dlfb_data *dev = info->par;
- *bufptr++ = 0xAF;
- *bufptr++ = 0x6A;
+#if defined CONFIG_FB_SYS_COPYAREA || defined CONFIG_FB_SYS_COPYAREA_MODULE
- *bufptr++ = (char)(base >> 16);
- *bufptr++ = (char)(base >> 8);
- *bufptr++ = (char)(base);
+ sys_copyarea(info, area);
- if (rem > 255) {
- *bufptr++ = 255;
- *bufptr++ = (char)(source >> 16);
- *bufptr++ = (char)(source >> 8);
- *bufptr++ = (char)(source);
+ dlfb_handle_damage(dev, area->dx, area->dy,
+ area->width, area->height, info->screen_base);
+#endif
+ atomic_inc(&dev->copy_count);
- rem -= 255;
- base += 255 * 2;
- source += 255 * 2;
+}
- } else {
- *bufptr++ = rem;
- *bufptr++ = (char)(source >> 16);
- *bufptr++ = (char)(source >> 8);
- *bufptr++ = (char)(source);
+static void dlfb_ops_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+{
+ struct dlfb_data *dev = info->par;
- base += rem * 2;
- source += rem * 2;
- rem = 0;
- }
- }
+#if defined CONFIG_FB_SYS_IMAGEBLIT || defined CONFIG_FB_SYS_IMAGEBLIT_MODULE
- base += (dev_info->info->var.xres * 2) - (width * 2);
- source += (dev_info->info->var.xres * 2) - (width * 2);
- }
+ sys_imageblit(info, image);
- if (bufptr > dev_info->buf)
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+ dlfb_handle_damage(dev, image->dx, image->dy,
+ image->width, image->height, info->screen_base);
- mutex_unlock(&dev_info->bulk_mutex);
+#endif
- return 1;
+ atomic_inc(&dev->blit_count);
}
-static void dlfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void dlfb_ops_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
{
-
struct dlfb_data *dev = info->par;
- copyarea(dev, area->dx, area->dy, area->sx, area->sy, area->width,
- area->height);
+#if defined CONFIG_FB_SYS_FILLRECT || defined CONFIG_FB_SYS_FILLRECT_MODULE
- /* printk("COPY AREA %d %d %d %d %d %d !!!\n", area->dx, area->dy, area->sx, area->sy, area->width, area->height); */
+ sys_fillrect(info, rect);
-}
+ dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width,
+ rect->height, info->screen_base);
+#endif
-static void dlfb_imageblit(struct fb_info *info, const struct fb_image *image)
-{
+ atomic_inc(&dev->fill_count);
- int ret;
- struct dlfb_data *dev = info->par;
- /* printk("IMAGE BLIT (1) %d %d %d %d DEPTH %d {%p}!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev); */
- cfb_imageblit(info, image);
- ret =
- image_blit(dev, image->dx, image->dy, image->width, image->height,
- info->screen_base);
- /* printk("IMAGE BLIT (2) %d %d %d %d DEPTH %d {%p} %d!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev, ret); */
}
-static void dlfb_fillrect(struct fb_info *info,
- const struct fb_fillrect *region)
+static void dlfb_get_edid(struct dlfb_data *dev)
{
-
- unsigned char red, green, blue;
- struct dlfb_data *dev = info->par;
-
- memcpy(&red, &region->color, 1);
- memcpy(&green, &region->color + 1, 1);
- memcpy(&blue, &region->color + 2, 1);
- draw_rect(dev, region->dx, region->dy, region->width, region->height,
- red, green, blue);
- /* printk("FILL RECT %d %d !!!\n", region->dx, region->dy); */
-
+ int i;
+ int ret;
+ char rbuf[2];
+
+ for (i = 0; i < sizeof(dev->edid); i++) {
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0), (0x02),
+ (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
+ 0);
+ dev->edid[i] = rbuf[1];
+ }
}
-static int dlfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
{
- struct dlfb_data *dev_info = info->par;
+ struct dlfb_data *dev = info->par;
struct dloarea *area = NULL;
- if (cmd == 0xAD) {
+ if (!atomic_read(&dev->usb_active))
+ return 0;
+
+ /* TODO: Update X server to get this from sysfs instead */
+ if (cmd == DLFB_IOCTL_RETURN_EDID) {
char *edid = (char *)arg;
- dlfb_edid(dev_info);
- if (copy_to_user(edid, dev_info->edid, 128)) {
+ dlfb_get_edid(dev);
+ if (copy_to_user(edid, dev->edid, sizeof(dev->edid)))
return -EFAULT;
- }
return 0;
}
- if (cmd == 0xAA || cmd == 0xAB || cmd == 0xAC) {
+ /* TODO: Help propose a standard fb.h ioctl to report mmap damage */
+ if (cmd == DLFB_IOCTL_REPORT_DAMAGE) {
area = (struct dloarea *)arg;
@@ -634,36 +704,20 @@ static int dlfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
if (area->y > info->var.yres)
area->y = info->var.yres;
- }
- if (cmd == 0xAA) {
- image_blit(dev_info, area->x, area->y, area->w, area->h,
+ atomic_set(&dev->use_defio, 0);
+
+ dlfb_handle_damage(dev, area->x, area->y, area->w, area->h,
info->screen_base);
+ atomic_inc(&dev->damage_count);
}
- if (cmd == 0xAC) {
- copyfb(dev_info);
- image_blit(dev_info, area->x, area->y, area->w, area->h,
- info->screen_base);
- swapfb(dev_info);
- } else if (cmd == 0xAB) {
-
- if (area->x2 < 0)
- area->x2 = 0;
-
- if (area->y2 < 0)
- area->y2 = 0;
- copyarea(dev_info,
- area->x2, area->y2, area->x, area->y, area->w,
- area->h);
- }
return 0;
}
/* taken from vesafb */
-
static int
-dlfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+dlfb_ops_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp, struct fb_info *info)
{
int err = 0;
@@ -688,234 +742,698 @@ dlfb_setcolreg(unsigned regno, unsigned red, unsigned green,
return err;
}
-static int dlfb_release(struct fb_info *info, int user)
+/*
+ * It's common for several clients to have framebuffer open simultaneously.
+ * e.g. both fbcon and X. Makes things interesting.
+ */
+static int dlfb_ops_open(struct fb_info *info, int user)
+{
+ struct dlfb_data *dev = info->par;
+
+/* if (user == 0)
+ * We could special case kernel mode clients (fbcon) here
+ */
+
+ mutex_lock(&dev->fb_open_lock);
+
+ dev->fb_count++;
+
+#ifdef CONFIG_FB_DEFERRED_IO
+ if ((atomic_read(&dev->use_defio)) && (info->fbdefio == NULL)) {
+ /* enable defio */
+ info->fbdefio = &dlfb_defio;
+ fb_deferred_io_init(info);
+ }
+#endif
+
+ dl_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
+ info->node, user, info, dev->fb_count);
+
+ mutex_unlock(&dev->fb_open_lock);
+
+ return 0;
+}
+
+static int dlfb_ops_release(struct fb_info *info, int user)
+{
+ struct dlfb_data *dev = info->par;
+
+ mutex_lock(&dev->fb_open_lock);
+
+ dev->fb_count--;
+
+#ifdef CONFIG_FB_DEFERRED_IO
+ if ((dev->fb_count == 0) && (info->fbdefio)) {
+ fb_deferred_io_cleanup(info);
+ info->fbdefio = NULL;
+ info->fbops->fb_mmap = dlfb_ops_mmap;
+ }
+#endif
+
+ dl_notice("release /dev/fb%d user=%d count=%d\n",
+ info->node, user, dev->fb_count);
+
+ mutex_unlock(&dev->fb_open_lock);
+
+ return 0;
+}
+
+/*
+ * Called when all client interfaces to start transactions have been disabled,
+ * and all references to our device instance (dlfb_data) are released.
+ * Every transaction must have a reference, so we know are fully spun down
+ */
+static void dlfb_delete(struct kref *kref)
+{
+ struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
+
+ if (dev->backing_buffer)
+ vfree(dev->backing_buffer);
+
+ mutex_destroy(&dev->fb_open_lock);
+
+ kfree(dev);
+}
+
+/*
+ * Called by fbdev as last part of unregister_framebuffer() process
+ * No new clients can open connections. Deallocate everything fb_info.
+ */
+static void dlfb_ops_destroy(struct fb_info *info)
+{
+ struct dlfb_data *dev = info->par;
+
+ if (info->cmap.len != 0)
+ fb_dealloc_cmap(&info->cmap);
+ if (info->monspecs.modedb)
+ fb_destroy_modedb(info->monspecs.modedb);
+ if (info->screen_base)
+ vfree(info->screen_base);
+
+ fb_destroy_modelist(&info->modelist);
+
+ framebuffer_release(info);
+
+ /* ref taken before register_framebuffer() for dlfb_data clients */
+ kref_put(&dev->kref, dlfb_delete);
+}
+
+/*
+ * Check whether a video mode is supported by the DisplayLink chip
+ * We start from monitor's modes, so don't need to filter that here
+ */
+static int dlfb_is_valid_mode(struct fb_videomode *mode,
+ struct fb_info *info)
+{
+ struct dlfb_data *dev = info->par;
+
+ if (mode->xres * mode->yres > dev->sku_pixel_limit)
+ return 0;
+
+ return 1;
+}
+
+static void dlfb_var_color_format(struct fb_var_screeninfo *var)
+{
+ const struct fb_bitfield red = { 11, 5, 0 };
+ const struct fb_bitfield green = { 5, 6, 0 };
+ const struct fb_bitfield blue = { 0, 5, 0 };
+
+ var->bits_per_pixel = 16;
+ var->red = red;
+ var->green = green;
+ var->blue = blue;
+}
+
+static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
- struct dlfb_data *dev_info = info->par;
- image_blit(dev_info, 0, 0, info->var.xres, info->var.yres,
- info->screen_base);
+ struct fb_videomode mode;
+
+ /* TODO: support dynamically changing framebuffer size */
+ if ((var->xres * var->yres * 2) > info->fix.smem_len)
+ return -EINVAL;
+
+ /* set device-specific elements of var unrelated to mode */
+ dlfb_var_color_format(var);
+
+ fb_var_to_videomode(&mode, var);
+
+ if (!dlfb_is_valid_mode(&mode, info))
+ return -EINVAL;
+
return 0;
}
-static int dlfb_blank(int blank_mode, struct fb_info *info)
+static int dlfb_ops_set_par(struct fb_info *info)
{
- struct dlfb_data *dev_info = info->par;
- char *bufptr = dev_info->buf;
+ struct dlfb_data *dev = info->par;
+
+ dl_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres);
- bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
+ return dlfb_set_video_mode(dev, &info->var);
+}
+
+static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
+{
+ struct dlfb_data *dev = info->par;
+ char *bufptr;
+ struct urb *urb;
+
+ urb = dlfb_get_urb(dev);
+ if (!urb)
+ return 0;
+ bufptr = (char *) urb->transfer_buffer;
+
+ /* overloading usb_active. UNBLANK can conflict with teardown */
+
+ bufptr = dlfb_vidreg_lock(bufptr);
if (blank_mode != FB_BLANK_UNBLANK) {
- bufptr = dlfb_set_register(bufptr, 0x1F, 0x01);
+ atomic_set(&dev->usb_active, 0);
+ bufptr = dlfb_enable_hvsync(bufptr, false);
} else {
- bufptr = dlfb_set_register(bufptr, 0x1F, 0x00);
+ atomic_set(&dev->usb_active, 1);
+ bufptr = dlfb_enable_hvsync(bufptr, true);
}
- bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF);
+ bufptr = dlfb_vidreg_unlock(bufptr);
- dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
+ dlfb_submit_urb(dev, urb, bufptr - (char *) urb->transfer_buffer);
return 0;
}
static struct fb_ops dlfb_ops = {
- .fb_setcolreg = dlfb_setcolreg,
- .fb_fillrect = dlfb_fillrect,
- .fb_copyarea = dlfb_copyarea,
- .fb_imageblit = dlfb_imageblit,
- .fb_mmap = dlfb_mmap,
- .fb_ioctl = dlfb_ioctl,
- .fb_release = dlfb_release,
- .fb_blank = dlfb_blank,
+ .owner = THIS_MODULE,
+ .fb_setcolreg = dlfb_ops_setcolreg,
+ .fb_fillrect = dlfb_ops_fillrect,
+ .fb_copyarea = dlfb_ops_copyarea,
+ .fb_imageblit = dlfb_ops_imageblit,
+ .fb_mmap = dlfb_ops_mmap,
+ .fb_ioctl = dlfb_ops_ioctl,
+ .fb_open = dlfb_ops_open,
+ .fb_release = dlfb_ops_release,
+ .fb_blank = dlfb_ops_blank,
+ .fb_check_var = dlfb_ops_check_var,
+ .fb_set_par = dlfb_ops_set_par,
};
-static int
-dlfb_probe(struct usb_interface *interface, const struct usb_device_id *id)
+/*
+ * Calls dlfb_get_edid() to query the EDID of attached monitor via usb cmds
+ * Then parses EDID into three places used by various parts of fbdev:
+ * fb_var_screeninfo contains the timing of the monitor's preferred mode
+ * fb_info.monspecs is full parsed EDID info, including monspecs.modedb
+ * fb_info.modelist is a linked list of all monitor & VESA modes which work
+ *
+ * If EDID is not readable/valid, then modelist is all VESA modes,
+ * monspecs is NULL, and fb_var_screeninfo is set to safe VESA mode
+ * Returns 0 if EDID parses successfully
+ */
+static int dlfb_parse_edid(struct dlfb_data *dev,
+ struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
- struct dlfb_data *dev_info;
- struct fb_info *info;
+ int i;
+ const struct fb_videomode *default_vmode = NULL;
+ int result = 0;
- int ret;
- char rbuf[4];
+ fb_destroy_modelist(&info->modelist);
+ memset(&info->monspecs, 0, sizeof(info->monspecs));
- dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
- if (dev_info == NULL) {
- printk("cannot allocate dev_info structure.\n");
- return -ENOMEM;
+ dlfb_get_edid(dev);
+ fb_edid_to_monspecs(dev->edid, &info->monspecs);
+
+ if (info->monspecs.modedb_len > 0) {
+
+ for (i = 0; i < info->monspecs.modedb_len; i++) {
+ if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
+ fb_add_videomode(&info->monspecs.modedb[i],
+ &info->modelist);
+ }
+
+ default_vmode = fb_find_best_display(&info->monspecs,
+ &info->modelist);
+ } else {
+ struct fb_videomode fb_vmode = {0};
+
+ dl_err("Unable to get valid EDID from device/display\n");
+ result = 1;
+
+ /*
+ * Add the standard VESA modes to our modelist
+ * Since we don't have EDID, there may be modes that
+ * overspec monitor and/or are incorrect aspect ratio, etc.
+ * But at least the user has a chance to choose
+ */
+ for (i = 0; i < VESA_MODEDB_SIZE; i++) {
+ if (dlfb_is_valid_mode((struct fb_videomode *)
+ &vesa_modes[i], info))
+ fb_add_videomode(&vesa_modes[i],
+ &info->modelist);
+ }
+
+ /*
+ * default to resolution safe for projectors
+ * (since they are most common case without EDID)
+ */
+ fb_vmode.xres = 800;
+ fb_vmode.yres = 600;
+ fb_vmode.refresh = 60;
+ default_vmode = fb_find_nearest_mode(&fb_vmode,
+ &info->modelist);
}
- mutex_init(&dev_info->bulk_mutex);
+ fb_videomode_to_var(var, default_vmode);
+ dlfb_var_color_format(var);
- dev_info->udev = usb_get_dev(interface_to_usbdev(interface));
- dev_info->interface = interface;
+ return result;
+}
- printk("DisplayLink device attached\n");
+static ssize_t metrics_bytes_rendered_show(struct device *fbdev,
+ struct device_attribute *a, char *buf) {
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ atomic_read(&dev->bytes_rendered));
+}
- /* add framebuffer info to usb interface */
- usb_set_intfdata(interface, dev_info);
+static ssize_t metrics_bytes_identical_show(struct device *fbdev,
+ struct device_attribute *a, char *buf) {
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ atomic_read(&dev->bytes_identical));
+}
- dev_info->buf = kmalloc(BUF_SIZE, GFP_KERNEL);
- /* usb_buffer_alloc(dev_info->udev, BUF_SIZE , GFP_KERNEL, &dev_info->tx_urb->transfer_dma); */
+static ssize_t metrics_bytes_sent_show(struct device *fbdev,
+ struct device_attribute *a, char *buf) {
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ atomic_read(&dev->bytes_sent));
+}
- if (dev_info->buf == NULL) {
- printk("unable to allocate memory for dlfb commands\n");
- goto out;
- }
- dev_info->bufend = dev_info->buf + BUF_SIZE;
+static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev,
+ struct device_attribute *a, char *buf) {
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ atomic_read(&dev->cpu_kcycles_used));
+}
- dev_info->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- usb_fill_bulk_urb(dev_info->tx_urb, dev_info->udev,
- usb_sndbulkpipe(dev_info->udev, 1), dev_info->buf, 0,
- dlfb_bulk_callback, dev_info);
+static ssize_t metrics_misc_show(struct device *fbdev,
+ struct device_attribute *a, char *buf) {
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+ return snprintf(buf, PAGE_SIZE,
+ "Calls to\ndamage: %u\nblit: %u\n"
+ "defio faults: %u\ncopy: %u\n"
+ "fill: %u\n\n"
+ "active framebuffer clients: %d\n"
+ "urbs available %d(%d)\n"
+ "Shadow framebuffer in use? %s\n"
+ "Any lost pixels? %s\n",
+ atomic_read(&dev->damage_count),
+ atomic_read(&dev->blit_count),
+ atomic_read(&dev->defio_fault_count),
+ atomic_read(&dev->copy_count),
+ atomic_read(&dev->fill_count),
+ dev->fb_count,
+ dev->urbs.available, dev->urbs.limit_sem.count,
+ (dev->backing_buffer) ? "yes" : "no",
+ atomic_read(&dev->lost_pixels) ? "yes" : "no");
+}
- ret =
- usb_control_msg(dev_info->udev, usb_rcvctrlpipe(dev_info->udev, 0),
- (0x06), (0x80 | (0x02 << 5)), 0, 0, rbuf, 4, 0);
- printk("ret control msg 0: %d %x%x%x%x\n", ret, rbuf[0], rbuf[1],
- rbuf[2], rbuf[3]);
+static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *a,
+ char *buf, loff_t off, size_t count) {
+ struct device *fbdev = container_of(kobj, struct device, kobj);
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+ char *edid = &dev->edid[0];
+ const size_t size = sizeof(dev->edid);
- dlfb_edid(dev_info);
+ if (dlfb_parse_edid(dev, &fb_info->var, fb_info))
+ return 0;
- info = framebuffer_alloc(sizeof(u32) * 256, &dev_info->udev->dev);
+ if (off >= size)
+ return 0;
- if (!info) {
- printk("non posso allocare il framebuffer displaylink");
- goto out;
- }
+ if (off + count > size)
+ count = size - off;
+ memcpy(buf, edid + off, count);
- fb_parse_edid(dev_info->edid, &info->var);
+ return count;
+}
- printk("EDID XRES %d YRES %d\n", info->var.xres, info->var.yres);
- if (dlfb_set_video_mode(dev_info, info->var.xres, info->var.yres) != 0) {
- info->var.xres = 1280;
- info->var.yres = 1024;
- if (dlfb_set_video_mode
- (dev_info, info->var.xres, info->var.yres) != 0) {
- goto out;
- }
+static ssize_t metrics_reset_store(struct device *fbdev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+
+ atomic_set(&dev->bytes_rendered, 0);
+ atomic_set(&dev->bytes_identical, 0);
+ atomic_set(&dev->bytes_sent, 0);
+ atomic_set(&dev->cpu_kcycles_used, 0);
+ atomic_set(&dev->blit_count, 0);
+ atomic_set(&dev->copy_count, 0);
+ atomic_set(&dev->fill_count, 0);
+ atomic_set(&dev->defio_fault_count, 0);
+ atomic_set(&dev->damage_count, 0);
+
+ return count;
+}
+
+static ssize_t use_defio_show(struct device *fbdev,
+ struct device_attribute *a, char *buf) {
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ atomic_read(&dev->use_defio));
+}
+
+static ssize_t use_defio_store(struct device *fbdev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fb_info *fb_info = dev_get_drvdata(fbdev);
+ struct dlfb_data *dev = fb_info->par;
+
+ if (count > 0) {
+ if (buf[0] == '0')
+ atomic_set(&dev->use_defio, 0);
+ if (buf[0] == '1')
+ atomic_set(&dev->use_defio, 1);
}
+ return count;
+}
- printk("found valid mode...%d\n", info->var.pixclock);
+static struct bin_attribute edid_attr = {
+ .attr.name = "edid",
+ .attr.mode = 0444,
+ .size = 128,
+ .read = edid_show,
+};
- info->pseudo_palette = info->par;
- info->par = dev_info;
+static struct device_attribute fb_device_attrs[] = {
+ __ATTR_RO(metrics_bytes_rendered),
+ __ATTR_RO(metrics_bytes_identical),
+ __ATTR_RO(metrics_bytes_sent),
+ __ATTR_RO(metrics_cpu_kcycles_used),
+ __ATTR_RO(metrics_misc),
+ __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
+ __ATTR_RW(use_defio),
+};
- dev_info->info = info;
+#ifdef CONFIG_FB_DEFERRED_IO
+static void dlfb_dpy_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ struct page *cur;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+ struct dlfb_data *dev = info->par;
+ struct urb *urb;
+ char *cmd;
+ cycles_t start_cycles, end_cycles;
+ int bytes_sent = 0;
+ int bytes_identical = 0;
+ int bytes_rendered = 0;
+ int fault_count = 0;
+
+ if (!atomic_read(&dev->use_defio))
+ return;
- info->flags =
- FBINFO_DEFAULT | FBINFO_READS_FAST | FBINFO_HWACCEL_IMAGEBLIT |
- FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
- info->fbops = &dlfb_ops;
- info->screen_base = rvmalloc(dev_info->screen_size);
+ if (!atomic_read(&dev->usb_active))
+ return;
+
+ start_cycles = get_cycles();
- if (info->screen_base == NULL) {
- printk
- ("cannot allocate framebuffer virtual memory of %d bytes\n",
- dev_info->screen_size);
- goto out0;
+ urb = dlfb_get_urb(dev);
+ if (!urb)
+ return;
+ cmd = urb->transfer_buffer;
+
+ /* walk the written page list and render each to device */
+ list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+ dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
+ &cmd, cur->index << PAGE_SHIFT,
+ PAGE_SIZE, &bytes_identical, &bytes_sent);
+ bytes_rendered += PAGE_SIZE;
+ fault_count++;
}
- printk("screen base allocated !!!\n");
+ if (cmd > (char *) urb->transfer_buffer) {
+ /* Send partial buffer remaining before exiting */
+ int len = cmd - (char *) urb->transfer_buffer;
+ dlfb_submit_urb(dev, urb, len);
+ bytes_sent += len;
+ } else
+ dlfb_urb_completion(urb);
+
+ atomic_add(fault_count, &dev->defio_fault_count);
+ atomic_add(bytes_sent, &dev->bytes_sent);
+ atomic_add(bytes_identical, &dev->bytes_identical);
+ atomic_add(bytes_rendered, &dev->bytes_rendered);
+ end_cycles = get_cycles();
+ atomic_add(((unsigned int) ((end_cycles - start_cycles)
+ >> 10)), /* Kcycles */
+ &dev->cpu_kcycles_used);
+}
- dev_info->backing_buffer = kzalloc(dev_info->screen_size, GFP_KERNEL);
+static struct fb_deferred_io dlfb_defio = {
+ .delay = 5,
+ .deferred_io = dlfb_dpy_deferred_io,
+};
- if (!dev_info->backing_buffer)
- printk("non posso allocare il backing buffer\n");
+#endif
- /* info->var = dev_info->si; */
+/*
+ * This is necessary before we can communicate with the display controller.
+ */
+static int dlfb_select_std_channel(struct dlfb_data *dev)
+{
+ int ret;
+ u8 set_def_chn[] = { 0x57, 0xCD, 0xDC, 0xA7,
+ 0x1C, 0x88, 0x5E, 0x15,
+ 0x60, 0xFE, 0xC6, 0x97,
+ 0x16, 0x3D, 0x47, 0xF2 };
+
+ ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ NR_USB_REQUEST_CHANNEL,
+ (USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
+ set_def_chn, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
+ return ret;
+}
- info->var.bits_per_pixel = 16;
- info->var.activate = FB_ACTIVATE_TEST;
- info->var.vmode = FB_VMODE_NONINTERLACED;
- info->var.red.offset = 11;
- info->var.red.length = 5;
- info->var.red.msb_right = 0;
+static int dlfb_usb_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_device *usbdev;
+ struct dlfb_data *dev;
+ struct fb_info *info;
+ int videomemorysize;
+ int i;
+ unsigned char *videomemory;
+ int retval = -ENOMEM;
+ struct fb_var_screeninfo *var;
+ int registered = 0;
+ u16 *pix_framebuffer;
+
+ /* usb initialization */
+
+ usbdev = interface_to_usbdev(interface);
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
+ err("dlfb_usb_probe: failed alloc of dev struct\n");
+ goto error;
+ }
- info->var.green.offset = 5;
- info->var.green.length = 6;
- info->var.green.msb_right = 0;
+ /* we need to wait for both usb and fbdev to spin down on disconnect */
+ kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
+ kref_get(&dev->kref); /* matching kref_put in .fb_destroy function*/
- info->var.blue.offset = 0;
- info->var.blue.length = 5;
- info->var.blue.msb_right = 0;
+ dev->udev = usbdev;
+ dev->gdev = &usbdev->dev; /* our generic struct device * */
+ usb_set_intfdata(interface, dev);
- /* info->var.pixclock = (10000000 / FB_W * 1000 / FB_H)/2 ; */
+ if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
+ retval = -ENOMEM;
+ dl_err("dlfb_alloc_urb_list failed\n");
+ goto error;
+ }
- info->fix.smem_start = (unsigned long)info->screen_base;
- info->fix.smem_len = PAGE_ALIGN(dev_info->screen_size);
- if (strlen(dev_info->udev->product) > 15) {
- memcpy(info->fix.id, dev_info->udev->product, 15);
- } else {
- memcpy(info->fix.id, dev_info->udev->product,
- strlen(dev_info->udev->product));
+ mutex_init(&dev->fb_open_lock);
+
+ /* We don't register a new USB class. Our client interface is fbdev */
+
+ /* allocates framebuffer driver structure, not framebuffer memory */
+ info = framebuffer_alloc(0, &usbdev->dev);
+ if (!info) {
+ retval = -ENOMEM;
+ dl_err("framebuffer_alloc failed\n");
+ goto error;
+ }
+ dev->info = info;
+ info->par = dev;
+ info->pseudo_palette = dev->pseudo_palette;
+ info->fbops = &dlfb_ops;
+
+ var = &info->var;
+
+ /* TODO set limit based on actual SKU detection */
+ dev->sku_pixel_limit = 2048 * 1152;
+
+ INIT_LIST_HEAD(&info->modelist);
+ dlfb_parse_edid(dev, var, info);
+
+ /*
+ * ok, now that we've got the size info, we can alloc our framebuffer.
+ */
+ info->fix = dlfb_fix;
+ info->fix.line_length = var->xres * (var->bits_per_pixel / 8);
+ videomemorysize = info->fix.line_length * var->yres;
+
+ /*
+ * The big chunk of system memory we use as a virtual framebuffer.
+ * TODO: Handle fbcon cursor code calling blit in interrupt context
+ */
+ videomemory = vmalloc(videomemorysize);
+ if (!videomemory) {
+ retval = -ENOMEM;
+ dl_err("Virtual framebuffer alloc failed\n");
+ goto error;
}
- info->fix.type = FB_TYPE_PACKED_PIXELS;
- info->fix.visual = FB_VISUAL_TRUECOLOR;
- info->fix.accel = info->flags;
- info->fix.line_length = dev_info->line_length;
- if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
- goto out1;
+ info->screen_base = videomemory;
+ info->fix.smem_len = PAGE_ALIGN(videomemorysize);
+ info->fix.smem_start = (unsigned long) videomemory;
+ info->flags = udlfb_info_flags;
+
+
+ /*
+ * Second framebuffer copy, mirroring the state of the framebuffer
+ * on the physical USB device. We can function without this.
+ * But with imperfect damage info we may end up sending pixels over USB
+ * that were, in fact, unchanged -- wasting limited USB bandwidth
+ */
+ dev->backing_buffer = vmalloc(videomemorysize);
+ if (!dev->backing_buffer)
+ dl_warn("No shadow/backing buffer allcoated\n");
+ else
+ memset(dev->backing_buffer, 0, videomemorysize);
+
+ retval = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (retval < 0) {
+ dl_err("fb_alloc_cmap failed %x\n", retval);
+ goto error;
+ }
+
+ /* ready to begin using device */
+
+#ifdef CONFIG_FB_DEFERRED_IO
+ atomic_set(&dev->use_defio, 1);
+#endif
+ atomic_set(&dev->usb_active, 1);
+ dlfb_select_std_channel(dev);
+
+ dlfb_ops_check_var(var, info);
+ dlfb_ops_set_par(info);
+
+ /* paint greenscreen */
+ pix_framebuffer = (u16 *) videomemory;
+ for (i = 0; i < videomemorysize / 2; i++)
+ pix_framebuffer[i] = 0x37e6;
+
+ dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres,
+ videomemory);
- printk("colormap allocated\n");
- if (register_framebuffer(info) < 0)
- goto out2;
+ retval = register_framebuffer(info);
+ if (retval < 0) {
+ dl_err("register_framebuffer failed %d\n", retval);
+ goto error;
+ }
+ registered = 1;
+
+ for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
+ device_create_file(info->dev, &fb_device_attrs[i]);
- draw_rect(dev_info, 0, 0, dev_info->info->var.xres,
- dev_info->info->var.yres, 0x30, 0xff, 0x30);
+ device_create_bin_file(info->dev, &edid_attr);
+ dl_err("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
+ " Using %dK framebuffer memory\n", info->node,
+ var->xres, var->yres,
+ ((dev->backing_buffer) ?
+ videomemorysize * 2 : videomemorysize) >> 10);
return 0;
-out2:
- fb_dealloc_cmap(&info->cmap);
-out1:
- rvfree(info->screen_base, dev_info->screen_size);
-out0:
- framebuffer_release(info);
-out:
- usb_set_intfdata(interface, NULL);
- usb_put_dev(dev_info->udev);
- kfree(dev_info);
- return -ENOMEM;
+error:
+ if (dev) {
+ if (registered) {
+ unregister_framebuffer(info);
+ dlfb_ops_destroy(info);
+ } else
+ kref_put(&dev->kref, dlfb_delete);
+
+ if (dev->urbs.count > 0)
+ dlfb_free_urb_list(dev);
+ kref_put(&dev->kref, dlfb_delete); /* last ref from kref_init */
+
+ /* dev has been deallocated. Do not dereference */
+ }
+ return retval;
}
-static void dlfb_disconnect(struct usb_interface *interface)
+static void dlfb_usb_disconnect(struct usb_interface *interface)
{
- struct dlfb_data *dev_info = usb_get_intfdata(interface);
+ struct dlfb_data *dev;
+ struct fb_info *info;
+ int i;
+
+ dev = usb_get_intfdata(interface);
+ info = dev->info;
- mutex_unlock(&dev_info->bulk_mutex);
+ /* when non-active we'll update virtual framebuffer, but no new urbs */
+ atomic_set(&dev->usb_active, 0);
- usb_kill_urb(dev_info->tx_urb);
- usb_free_urb(dev_info->tx_urb);
usb_set_intfdata(interface, NULL);
- usb_put_dev(dev_info->udev);
- if (dev_info->info) {
- unregister_framebuffer(dev_info->info);
- fb_dealloc_cmap(&dev_info->info->cmap);
- rvfree(dev_info->info->screen_base, dev_info->screen_size);
- kfree(dev_info->backing_buffer);
- framebuffer_release(dev_info->info);
+ for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
+ device_remove_file(info->dev, &fb_device_attrs[i]);
+
+ device_remove_bin_file(info->dev, &edid_attr);
+ /* this function will wait for all in-flight urbs to complete */
+ dlfb_free_urb_list(dev);
+
+ if (info) {
+ dl_notice("Detaching /dev/fb%d\n", info->node);
+ unregister_framebuffer(info);
+ dlfb_ops_destroy(info);
}
- kfree(dev_info);
+ /* release reference taken by kref_init in probe() */
+ kref_put(&dev->kref, dlfb_delete);
+
+ /* consider dlfb_data freed */
- printk("DisplayLink device disconnected\n");
+ return;
}
static struct usb_driver dlfb_driver = {
.name = "udlfb",
- .probe = dlfb_probe,
- .disconnect = dlfb_disconnect,
+ .probe = dlfb_usb_probe,
+ .disconnect = dlfb_usb_disconnect,
.id_table = id_table,
};
-static int __init dlfb_init(void)
+static int __init dlfb_module_init(void)
{
int res;
- dlfb_init_modes();
-
res = usb_register(&dlfb_driver);
if (res)
err("usb_register failed. Error number %d", res);
@@ -925,14 +1443,186 @@ static int __init dlfb_init(void)
return res;
}
-static void __exit dlfb_exit(void)
+static void __exit dlfb_module_exit(void)
{
usb_deregister(&dlfb_driver);
}
-module_init(dlfb_init);
-module_exit(dlfb_exit);
+module_init(dlfb_module_init);
+module_exit(dlfb_module_exit);
-MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>");
-MODULE_DESCRIPTION(DRIVER_VERSION);
+static void dlfb_urb_completion(struct urb *urb)
+{
+ struct urb_node *unode = urb->context;
+ struct dlfb_data *dev = unode->dev;
+ unsigned long flags;
+
+ /* sync/async unlink faults aren't errors */
+ if (urb->status) {
+ if (!(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN)) {
+ dl_err("%s - nonzero write bulk status received: %d\n",
+ __func__, urb->status);
+ atomic_set(&dev->lost_pixels, 1);
+ }
+ }
+
+ urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */
+
+ spin_lock_irqsave(&dev->urbs.lock, flags);
+ list_add_tail(&unode->entry, &dev->urbs.list);
+ dev->urbs.available++;
+ spin_unlock_irqrestore(&dev->urbs.lock, flags);
+
+ up(&dev->urbs.limit_sem);
+}
+
+static void dlfb_free_urb_list(struct dlfb_data *dev)
+{
+ int count = dev->urbs.count;
+ struct list_head *node;
+ struct urb_node *unode;
+ struct urb *urb;
+ int ret;
+ unsigned long flags;
+
+ dl_notice("Waiting for completes and freeing all render urbs\n");
+
+ /* keep waiting and freeing, until we've got 'em all */
+ while (count--) {
+ /* Timeout means a memory leak and/or fault */
+ ret = down_timeout(&dev->urbs.limit_sem, FREE_URB_TIMEOUT);
+ if (ret) {
+ BUG_ON(ret);
+ break;
+ }
+ spin_lock_irqsave(&dev->urbs.lock, flags);
+
+ node = dev->urbs.list.next; /* have reserved one with sem */
+ list_del_init(node);
+
+ spin_unlock_irqrestore(&dev->urbs.lock, flags);
+
+ unode = list_entry(node, struct urb_node, entry);
+ urb = unode->urb;
+
+ /* Free each separately allocated piece */
+ usb_buffer_free(urb->dev, dev->urbs.size,
+ urb->transfer_buffer, urb->transfer_dma);
+ usb_free_urb(urb);
+ kfree(node);
+ }
+
+ kref_put(&dev->kref, dlfb_delete);
+
+}
+
+static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
+{
+ int i = 0;
+ struct urb *urb;
+ struct urb_node *unode;
+ char *buf;
+
+ spin_lock_init(&dev->urbs.lock);
+
+ dev->urbs.size = size;
+ INIT_LIST_HEAD(&dev->urbs.list);
+
+ while (i < count) {
+ unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
+ if (!unode)
+ break;
+ unode->dev = dev;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ kfree(unode);
+ break;
+ }
+ unode->urb = urb;
+
+ buf = usb_buffer_alloc(dev->udev, MAX_TRANSFER, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!buf) {
+ kfree(unode);
+ usb_free_urb(urb);
+ break;
+ }
+
+ /* urb->transfer_buffer_length set to actual before submit */
+ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1),
+ buf, size, dlfb_urb_completion, unode);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ list_add_tail(&unode->entry, &dev->urbs.list);
+
+ i++;
+ }
+
+ sema_init(&dev->urbs.limit_sem, i);
+ dev->urbs.count = i;
+ dev->urbs.available = i;
+
+ kref_get(&dev->kref); /* released in free_render_urbs() */
+
+ dl_notice("allocated %d %d byte urbs \n", i, (int) size);
+
+ return i;
+}
+
+static struct urb *dlfb_get_urb(struct dlfb_data *dev)
+{
+ int ret = 0;
+ struct list_head *entry;
+ struct urb_node *unode;
+ struct urb *urb = NULL;
+ unsigned long flags;
+
+ /* Wait for an in-flight buffer to complete and get re-queued */
+ ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT);
+ if (ret) {
+ atomic_set(&dev->lost_pixels, 1);
+ dl_err("wait for urb interrupted: %x\n", ret);
+ goto error;
+ }
+
+ spin_lock_irqsave(&dev->urbs.lock, flags);
+
+ BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */
+ entry = dev->urbs.list.next;
+ list_del_init(entry);
+ dev->urbs.available--;
+
+ spin_unlock_irqrestore(&dev->urbs.lock, flags);
+
+ unode = list_entry(entry, struct urb_node, entry);
+ urb = unode->urb;
+
+error:
+ return urb;
+}
+
+static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len)
+{
+ int ret;
+
+ BUG_ON(len > dev->urbs.size);
+
+ urb->transfer_buffer_length = len; /* set to actual payload len */
+ ret = usb_submit_urb(urb, GFP_KERNEL);
+ if (ret) {
+ dlfb_urb_completion(urb); /* because no one else will */
+ atomic_set(&dev->lost_pixels, 1);
+ dl_err("usb_submit_urb error %x\n", ret);
+ }
+ return ret;
+}
+
+MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, "
+ "Jaya Kumar <jayakumar.lkml@gmail.com>, "
+ "Bernie Thompson <bernie@plugable.com>");
+MODULE_DESCRIPTION("DisplayLink kernel framebuffer driver");
MODULE_LICENSE("GPL");
+
diff --git a/drivers/staging/udlfb/udlfb.h b/drivers/staging/udlfb/udlfb.h
index 40ad85ea8e6..b07a69371f1 100644
--- a/drivers/staging/udlfb/udlfb.h
+++ b/drivers/staging/udlfb/udlfb.h
@@ -1,225 +1,106 @@
#ifndef UDLFB_H
#define UDLFB_H
-#define MAX_VMODES 4
-#define FB_BPP 16
+/*
+ * TODO: Propose standard fb.h ioctl for reporting damage,
+ * using _IOWR() and one of the existing area structs from fb.h
+ * Consider these ioctls deprecated, but they're still used by the
+ * DisplayLink X server as yet - need both to be modified in tandem
+ * when new ioctl(s) are ready.
+ */
+#define DLFB_IOCTL_RETURN_EDID 0xAD
+#define DLFB_IOCTL_REPORT_DAMAGE 0xAA
+struct dloarea {
+ int x, y;
+ int w, h;
+ int x2, y2;
+};
-#define STD_CHANNEL "\x57\xCD\xDC\xA7\x1C\x88\x5E\x15" \
- "\x60\xFE\xC6\x97\x16\x3D\x47\xF2"
+struct urb_node {
+ struct list_head entry;
+ struct dlfb_data *dev;
+ struct urb *urb;
+};
-/* as libdlo */
-#define BUF_HIGH_WATER_MARK 1024
-#define BUF_SIZE (64*1024)
+struct urb_list {
+ struct list_head list;
+ spinlock_t lock;
+ struct semaphore limit_sem;
+ int available;
+ int count;
+ size_t size;
+};
struct dlfb_data {
struct usb_device *udev;
- struct usb_interface *interface;
- struct urb *tx_urb, *ctrl_urb;
- struct usb_ctrlrequest dr;
+ struct device *gdev; /* &udev->dev */
struct fb_info *info;
- char *buf;
- char *bufend;
+ struct urb_list urbs;
+ struct kref kref;
char *backing_buffer;
- struct mutex bulk_mutex;
+ struct delayed_work deferred_work;
+ struct mutex fb_open_lock;
+ int fb_count;
+ atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
+ atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
+ atomic_t use_defio; /* 0 = rely on ioctls and blit/copy/fill rects */
char edid[128];
- int screen_size;
- int line_length;
- struct completion done;
+ int sku_pixel_limit;
int base16;
- int base16d;
int base8;
- int base8d;
+ u32 pseudo_palette[256];
+ /* blit-only rendering path metrics, exposed through sysfs */
+ atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */
+ atomic_t bytes_identical; /* saved effort with backbuffer comparison */
+ atomic_t bytes_sent; /* to usb, after compression including overhead */
+ atomic_t cpu_kcycles_used; /* transpired during pixel processing */
+ /* interface usage metrics. Clients can call driver via several */
+ atomic_t blit_count;
+ atomic_t copy_count;
+ atomic_t fill_count;
+ atomic_t damage_count;
+ atomic_t defio_fault_count;
};
-struct dlfb_video_mode {
- uint8_t col;
- uint32_t hclock;
- uint32_t vclock;
- uint8_t unknown1[6];
- uint16_t xres;
- uint8_t unknown2[6];
- uint16_t yres;
- uint8_t unknown3[4];
-} __attribute__ ((__packed__));
-
-static struct dlfb_video_mode dlfb_video_modes[MAX_VMODES];
-
-static void dlfb_bulk_callback(struct urb *urb)
-{
- struct dlfb_data *dev_info = urb->context;
- complete(&dev_info->done);
-}
-
-static void dlfb_edid(struct dlfb_data *dev_info)
-{
- int i;
- int ret;
- char rbuf[2];
-
- for (i = 0; i < 128; i++) {
- ret =
- usb_control_msg(dev_info->udev,
- usb_rcvctrlpipe(dev_info->udev, 0), (0x02),
- (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
- 0);
- /*printk("ret control msg edid %d: %d [%d]\n",i, ret, rbuf[1]); */
- dev_info->edid[i] = rbuf[1];
- }
-
-}
-
-static int dlfb_bulk_msg(struct dlfb_data *dev_info, int len)
-{
- int ret;
-
- init_completion(&dev_info->done);
-
- dev_info->tx_urb->actual_length = 0;
- dev_info->tx_urb->transfer_buffer_length = len;
-
- ret = usb_submit_urb(dev_info->tx_urb, GFP_KERNEL);
- if (!wait_for_completion_timeout(&dev_info->done, 1000)) {
- usb_kill_urb(dev_info->tx_urb);
- printk("usb timeout !!!\n");
- }
-
- return dev_info->tx_urb->actual_length;
-}
-
-static void dlfb_init_modes(void)
-{
- dlfb_video_modes[0].col = 0;
- memcpy(&dlfb_video_modes[0].hclock, "\x20\x3C\x7A\xC9", 4);
- memcpy(&dlfb_video_modes[0].vclock, "\xF2\x6C\x48\xF9", 4);
- memcpy(&dlfb_video_modes[0].unknown1, "\x70\x53\xFF\xFF\x21\x27", 6);
- dlfb_video_modes[0].xres = 800;
- memcpy(&dlfb_video_modes[0].unknown2, "\x91\xF3\xFF\xFF\xFF\xF9", 6);
- dlfb_video_modes[0].yres = 480;
- memcpy(&dlfb_video_modes[0].unknown3, "\x01\x02\xC8\x19", 4);
-
- dlfb_video_modes[1].col = 0;
- memcpy(&dlfb_video_modes[1].hclock, "\x36\x18\xD5\x10", 4);
- memcpy(&dlfb_video_modes[1].vclock, "\x60\xA9\x7B\x33", 4);
- memcpy(&dlfb_video_modes[1].unknown1, "\xA1\x2B\x27\x32\xFF\xFF", 6);
- dlfb_video_modes[1].xres = 1024;
- memcpy(&dlfb_video_modes[1].unknown2, "\xD9\x9A\xFF\xCA\xFF\xFF", 6);
- dlfb_video_modes[1].yres = 768;
- memcpy(&dlfb_video_modes[1].unknown3, "\x04\x03\xC8\x32", 4);
-
- dlfb_video_modes[2].col = 0;
- memcpy(&dlfb_video_modes[2].hclock, "\x98\xF8\x0D\x57", 4);
- memcpy(&dlfb_video_modes[2].vclock, "\x2A\x55\x4D\x54", 4);
- memcpy(&dlfb_video_modes[2].unknown1, "\xCA\x0D\xFF\xFF\x94\x43", 6);
- dlfb_video_modes[2].xres = 1280;
- memcpy(&dlfb_video_modes[2].unknown2, "\x9A\xA8\xFF\xFF\xFF\xF9", 6);
- dlfb_video_modes[2].yres = 1024;
- memcpy(&dlfb_video_modes[2].unknown3, "\x04\x02\x60\x54", 4);
-
- dlfb_video_modes[3].col = 0;
- memcpy(&dlfb_video_modes[3].hclock, "\x42\x24\x38\x36", 4);
- memcpy(&dlfb_video_modes[3].vclock, "\xC1\x52\xD9\x29", 4);
- memcpy(&dlfb_video_modes[3].unknown1, "\xEA\xB8\x32\x60\xFF\xFF", 6);
- dlfb_video_modes[3].xres = 1400;
- memcpy(&dlfb_video_modes[3].unknown2, "\xC9\x4E\xFF\xFF\xFF\xF2", 6);
- dlfb_video_modes[3].yres = 1050;
- memcpy(&dlfb_video_modes[3].unknown3, "\x04\x02\x1E\x5F", 4);
-}
-
-static char *dlfb_set_register(char *bufptr, uint8_t reg, uint8_t val)
-{
- *bufptr++ = 0xAF;
- *bufptr++ = 0x20;
- *bufptr++ = reg;
- *bufptr++ = val;
-
- return bufptr;
-}
-
-static int dlfb_set_video_mode(struct dlfb_data *dev_info, int width, int height)
-{
- int i, ret;
- unsigned char j;
- char *bufptr = dev_info->buf;
- uint8_t *vdata;
-
- for (i = 0; i < MAX_VMODES; i++) {
- printk("INIT VIDEO %d %d %d\n", i, dlfb_video_modes[i].xres,
- dlfb_video_modes[i].yres);
- if (dlfb_video_modes[i].xres == width
- && dlfb_video_modes[i].yres == height) {
-
- dev_info->base16 = 0;
- dev_info->base16d = width * height * (FB_BPP / 8);
-
- //dev_info->base8 = width * height * (FB_BPP / 8);
-
- dev_info->base8 = dev_info->base16;
- dev_info->base8d = dev_info->base16d;
-
- /* set encryption key (null) */
- memcpy(dev_info->buf, STD_CHANNEL, 16);
- ret =
- usb_control_msg(dev_info->udev,
- usb_sndctrlpipe(dev_info->udev, 0),
- 0x12, (0x02 << 5), 0, 0,
- dev_info->buf, 16, 0);
- printk("ret control msg 1 (STD_CHANNEL): %d\n", ret);
-
- /* set registers */
- bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
-
- /* set color depth */
- bufptr = dlfb_set_register(bufptr, 0x00, 0x00);
-
- /* set addresses */
- bufptr =
- dlfb_set_register(bufptr, 0x20,
- (char)(dev_info->base16 >> 16));
- bufptr =
- dlfb_set_register(bufptr, 0x21,
- (char)(dev_info->base16 >> 8));
- bufptr =
- dlfb_set_register(bufptr, 0x22,
- (char)(dev_info->base16));
-
- bufptr =
- dlfb_set_register(bufptr, 0x26,
- (char)(dev_info->base8 >> 16));
- bufptr =
- dlfb_set_register(bufptr, 0x27,
- (char)(dev_info->base8 >> 8));
- bufptr =
- dlfb_set_register(bufptr, 0x28,
- (char)(dev_info->base8));
+#define NR_USB_REQUEST_I2C_SUB_IO 0x02
+#define NR_USB_REQUEST_CHANNEL 0x12
- /* set video mode */
- vdata = (uint8_t *)&dlfb_video_modes[i];
- for (j = 0; j < 29; j++)
- bufptr = dlfb_set_register(bufptr, j, vdata[j]);
+/* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */
+#define BULK_SIZE 512
+#define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE)
+#define WRITES_IN_FLIGHT (4)
- /* blank */
- bufptr = dlfb_set_register(bufptr, 0x1F, 0x00);
+#define GET_URB_TIMEOUT HZ
+#define FREE_URB_TIMEOUT (HZ*2)
- /* end registers */
- bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF);
+#define BPP 2
+#define MAX_CMD_PIXELS 255
- /* send */
- ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
- printk("ret bulk 2: %d %td\n", ret,
- bufptr - dev_info->buf);
+#define RLX_HEADER_BYTES 7
+#define MIN_RLX_PIX_BYTES 4
+#define MIN_RLX_CMD_BYTES (RLX_HEADER_BYTES + MIN_RLX_PIX_BYTES)
- /* flush */
- ret = dlfb_bulk_msg(dev_info, 0);
- printk("ret bulk 3: %d\n", ret);
+#define RLE_HEADER_BYTES 6
+#define MIN_RLE_PIX_BYTES 3
+#define MIN_RLE_CMD_BYTES (RLE_HEADER_BYTES + MIN_RLE_PIX_BYTES)
- dev_info->screen_size = width * height * (FB_BPP / 8);
- dev_info->line_length = width * (FB_BPP / 8);
+#define RAW_HEADER_BYTES 6
+#define MIN_RAW_PIX_BYTES 2
+#define MIN_RAW_CMD_BYTES (RAW_HEADER_BYTES + MIN_RAW_PIX_BYTES)
- return 0;
- }
- }
+/* remove these once align.h patch is taken into kernel */
+#define DL_ALIGN_UP(x, a) ALIGN(x, a)
+#define DL_ALIGN_DOWN(x, a) ALIGN(x-(a-1), a)
- return -1;
-}
+/* remove once this gets added to sysfs.h */
+#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store)
+#define dl_err(format, arg...) \
+ dev_err(dev->gdev, "dlfb: " format, ## arg)
+#define dl_warn(format, arg...) \
+ dev_warn(dev->gdev, "dlfb: " format, ## arg)
+#define dl_notice(format, arg...) \
+ dev_notice(dev->gdev, "dlfb: " format, ## arg)
+#define dl_info(format, arg...) \
+ dev_info(dev->gdev, "dlfb: " format, ## arg)
#endif
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig
index 350d5d65ccf..2c1d10acb8b 100644
--- a/drivers/staging/usbip/Kconfig
+++ b/drivers/staging/usbip/Kconfig
@@ -34,3 +34,10 @@ config USB_IP_HOST
To compile this driver as a module, choose M here: the
module will be called usbip.
+
+config USB_IP_DEBUG_ENABLE
+ bool "USB-IP Debug Enable"
+ depends on USB_IP_COMMON
+ default N
+ ---help---
+ This enables the debug messages from the USB-IP drivers.
diff --git a/drivers/staging/usbip/Makefile b/drivers/staging/usbip/Makefile
index 179f4211f96..6f2916b1807 100644
--- a/drivers/staging/usbip/Makefile
+++ b/drivers/staging/usbip/Makefile
@@ -7,6 +7,6 @@ vhci-hcd-objs := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
obj-$(CONFIG_USB_IP_HOST) += usbip.o
usbip-objs := stub_dev.o stub_main.o stub_rx.o stub_tx.o
-ifeq ($(CONFIG_USB_DEBUG),y)
+ifeq ($(CONFIG_USB_IP_DEBUG_ENABLE),y)
EXTRA_CFLAGS += -DDEBUG
endif
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
index 173b018c56d..3f95605427a 100644
--- a/drivers/staging/usbip/stub_dev.c
+++ b/drivers/staging/usbip/stub_dev.c
@@ -17,6 +17,8 @@
* USA.
*/
+#include <linux/slab.h>
+
#include "usbip_common.h"
#include "stub.h"
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c
index ba1678fa631..6665cefe573 100644
--- a/drivers/staging/usbip/stub_main.c
+++ b/drivers/staging/usbip/stub_main.c
@@ -17,6 +17,7 @@
* USA.
*/
+#include <linux/slab.h>
#include "usbip_common.h"
#include "stub.h"
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 815fb7cc3b2..bc267408667 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -17,6 +17,8 @@
* USA.
*/
+#include <linux/slab.h>
+
#include "usbip_common.h"
#include "stub.h"
#include "../../usb/core/hcd.h"
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c
index e2ab4f3fdac..d7136e2c86f 100644
--- a/drivers/staging/usbip/stub_tx.c
+++ b/drivers/staging/usbip/stub_tx.c
@@ -17,6 +17,8 @@
* USA.
*/
+#include <linux/slab.h>
+
#include "usbip_common.h"
#include "stub.h"
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index ddb6f5fd04d..e3fa4216c1c 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -23,6 +23,7 @@
#include <linux/tcp.h>
#include <linux/in.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include "usbip_common.h"
/* version information */
@@ -33,7 +34,7 @@
/*-------------------------------------------------------------------------*/
/* debug routines */
-#ifdef CONFIG_USB_DEBUG
+#ifdef CONFIG_USB_IP_DEBUG_ENABLE
unsigned long usbip_debug_flag = 0xffffffff;
#else
unsigned long usbip_debug_flag;
@@ -55,10 +56,7 @@ static ssize_t show_flag(struct device *dev, struct device_attribute *attr,
static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- unsigned long flag;
-
- sscanf(buf, "%lx", &flag);
- usbip_debug_flag = flag;
+ sscanf(buf, "%lx", &usbip_debug_flag);
return count;
}
@@ -66,33 +64,8 @@ DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag);
static void usbip_dump_buffer(char *buff, int bufflen)
{
- int i;
-
- if (bufflen > 128) {
- for (i = 0; i < 128; i++) {
- if (i%24 == 0)
- printk(KERN_DEBUG " ");
- printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]);
- if (i%4 == 3)
- printk(KERN_DEBUG "| ");
- if (i%24 == 23)
- printk(KERN_DEBUG "\n");
- }
- printk(KERN_DEBUG "... (%d byte)\n", bufflen);
- return;
- }
-
- for (i = 0; i < bufflen; i++) {
- if (i%24 == 0)
- printk(KERN_DEBUG " ");
- printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]);
- if (i%4 == 3)
- printk(KERN_DEBUG "| ");
- if (i%24 == 23)
- printk(KERN_DEBUG "\n");
- }
- printk(KERN_DEBUG "\n");
-
+ print_hex_dump(KERN_DEBUG, "usb-ip", DUMP_PREFIX_OFFSET, 16, 4,
+ buff, bufflen, false);
}
static void usbip_dump_pipe(unsigned int p)
@@ -558,60 +531,6 @@ err:
}
EXPORT_SYMBOL_GPL(usbip_xmit);
-
-/* now a usrland utility should set options. */
-#if 0
-int setquickack(struct socket *socket)
-{
- mm_segment_t oldfs;
- int val = 1;
- int ret;
-
- oldfs = get_fs();
- set_fs(get_ds());
- ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK,
- (char __user *) &val, sizeof(ret));
- set_fs(oldfs);
-
- return ret;
-}
-
-int setnodelay(struct socket *socket)
-{
- mm_segment_t oldfs;
- int val = 1;
- int ret;
-
- oldfs = get_fs();
- set_fs(get_ds());
- ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY,
- (char __user *) &val, sizeof(ret));
- set_fs(oldfs);
-
- return ret;
-}
-
-int setkeepalive(struct socket *socket)
-{
- mm_segment_t oldfs;
- int val = 1;
- int ret;
-
- oldfs = get_fs();
- set_fs(get_ds());
- ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE,
- (char __user *) &val, sizeof(ret));
- set_fs(oldfs);
-
- return ret;
-}
-
-void setreuse(struct socket *socket)
-{
- socket->sk->sk_reuse = 1;
-}
-#endif
-
struct socket *sockfd_to_socket(unsigned int sockfd)
{
struct socket *socket;
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index 1ca3eab8af1..6f1dcb197d1 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -33,12 +33,12 @@
*/
/**
- * usbip_udbg - print debug messages if CONFIG_USB_DEBUG is defined
+ * usbip_udbg - print debug messages if CONFIG_USB_IP_DEBUG_ENABLE is defined
* @fmt:
* @args:
*/
-#ifdef CONFIG_USB_DEBUG
+#ifdef CONFIG_USB_IP_DEBUG_ENABLE
#define usbip_udbg(fmt, args...) \
do { \
@@ -47,11 +47,11 @@
__FILE__, __LINE__, __func__, ##args); \
} while (0)
-#else /* CONFIG_USB_DEBUG */
+#else /* CONFIG_USB_IP_DEBUG_ENABLE */
#define usbip_udbg(fmt, args...) do { } while (0)
-#endif /* CONFIG_USB_DEBUG */
+#endif /* CONFIG_USB_IP_DEBUG_ENABLE */
enum {
diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/staging/usbip/usbip_event.c
index 6da1021e8a6..a2566f1075d 100644
--- a/drivers/staging/usbip/usbip_event.c
+++ b/drivers/staging/usbip/usbip_event.c
@@ -117,6 +117,9 @@ void usbip_stop_eh(struct usbip_device *ud)
{
struct usbip_task *eh = &ud->eh;
+ if (eh->thread == current)
+ return; /* do not wait for myself */
+
wait_for_completion(&eh->thread_done);
usbip_dbg_eh("usbip_eh has finished\n");
}
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index ef4371358db..0b1766122d3 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -17,6 +17,7 @@
* USA.
*/
+#include <linux/slab.h>
#include "usbip_common.h"
#include "vhci.h"
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index 7636d86c238..8147d7202b2 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -17,6 +17,8 @@
* USA.
*/
+#include <linux/slab.h>
+
#include "usbip_common.h"
#include "vhci.h"
diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c
index 7a00eb44b79..b71b4c2fbd8 100644
--- a/drivers/staging/usbip/vhci_tx.c
+++ b/drivers/staging/usbip/vhci_tx.c
@@ -17,6 +17,8 @@
* USA.
*/
+#include <linux/slab.h>
+
#include "usbip_common.h"
#include "vhci.h"
diff --git a/drivers/staging/vme/Kconfig b/drivers/staging/vme/Kconfig
index ae628a58b0c..6411ae51ed3 100644
--- a/drivers/staging/vme/Kconfig
+++ b/drivers/staging/vme/Kconfig
@@ -14,4 +14,6 @@ source "drivers/staging/vme/bridges/Kconfig"
source "drivers/staging/vme/devices/Kconfig"
+source "drivers/staging/vme/boards/Kconfig"
+
endif # VME
diff --git a/drivers/staging/vme/Makefile b/drivers/staging/vme/Makefile
index 8c3b90ee585..b4ea3f8d0a5 100644
--- a/drivers/staging/vme/Makefile
+++ b/drivers/staging/vme/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_VME_BUS) += vme.o
obj-y += bridges/
obj-y += devices/
+obj-y += boards/
diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO
index 2201ff6f74d..82c222b4a14 100644
--- a/drivers/staging/vme/TODO
+++ b/drivers/staging/vme/TODO
@@ -4,28 +4,6 @@
API
===
-DMA Resource Allocation incomplete
-----------------------------------
-
-The current DMA resource Allocation provides no means of selecting the
-suitability of a DMA controller based on it's supported modes of operation, as
-opposed to the resource allocation mechanisms for master and slave windows:
-
- struct vme_resource *vme_dma_request(struct device *dev);
-
-As opposed to:
-
- struct vme_resource * vme_master_request(struct device *dev,
- vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
-
-The TSI148 can perform, VME-to-PCI, PCI-to-VME, PATTERN-to-VME, PATTERN-to-PCI,
-VME-to-VME and PCI-to-PCI transfers. The CA91C142 can only provide VME-to-PCI
-and PCI-to-VME.
-
-Add a mechanism to select a VME controller based on source/target type,
-required aspace, cycle and width requirements.
-
-
Master window broadcast select mask
-----------------------------------
@@ -59,7 +37,6 @@ chips. They are currently not supported at all by the API.
Core
====
-- Rename vme_master_resource's "pci_resource" to be bus agnostic.
- Improve generic sanity checks (Such as does an offset and size fit within a
window and parameter checking).
@@ -69,7 +46,6 @@ Bridge Support
Tempe (tsi148)
--------------
-- Driver can currently only support a single bridge.
- 2eSST Broadcast mode.
- Mailboxes unsupported.
- Improve error detection.
@@ -80,10 +56,6 @@ Tempe (tsi148)
Universe II (ca91c142)
----------------------
-- Driver can currently only support a single bridge.
-- DMA unsupported.
-- RMW transactions unsupported.
-- Location Monitors unsupported.
- Mailboxes unsupported.
- Error Detection.
- Control of prefetch size, threshold.
diff --git a/drivers/staging/vme/boards/Kconfig b/drivers/staging/vme/boards/Kconfig
new file mode 100644
index 00000000000..76163135352
--- /dev/null
+++ b/drivers/staging/vme/boards/Kconfig
@@ -0,0 +1,9 @@
+comment "VME Board Drivers"
+
+config VMIVME_7805
+ tristate "VMIVME-7805"
+ help
+ If you say Y here you get support for the VMIVME-7805 board.
+ This board has an additional control interface to the Universe II
+ chip. This driver has to be included if you want to access VME bus
+ with VMIVME-7805 board.
diff --git a/drivers/staging/vme/boards/Makefile b/drivers/staging/vme/boards/Makefile
new file mode 100644
index 00000000000..43658340885
--- /dev/null
+++ b/drivers/staging/vme/boards/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the VME board drivers.
+#
+
+obj-$(CONFIG_VMIVME_7805) += vme_vmivme7805.o
diff --git a/drivers/staging/vme/boards/vme_vmivme7805.c b/drivers/staging/vme/boards/vme_vmivme7805.c
new file mode 100644
index 00000000000..843c9edde55
--- /dev/null
+++ b/drivers/staging/vme/boards/vme_vmivme7805.c
@@ -0,0 +1,124 @@
+/*
+ * Support for the VMIVME-7805 board access to the Universe II bridge.
+ *
+ * Author: Arthur Benilov <arthur.benilov@iba-group.com>
+ * Copyright 2010 Ion Beam Application, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/io.h>
+
+#include "vme_vmivme7805.h"
+
+static int __init vmic_init(void);
+static int vmic_probe(struct pci_dev *, const struct pci_device_id *);
+static void vmic_remove(struct pci_dev *);
+static void __exit vmic_exit(void);
+
+/** Base address to access FPGA register */
+static void *vmic_base;
+
+static char driver_name[] = "vmivme_7805";
+
+static struct pci_device_id vmic_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) },
+ { },
+};
+
+static struct pci_driver vmic_driver = {
+ .name = driver_name,
+ .id_table = vmic_ids,
+ .probe = vmic_probe,
+ .remove = vmic_remove,
+};
+
+static int __init vmic_init(void)
+{
+ return pci_register_driver(&vmic_driver);
+}
+
+static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int retval;
+ u32 data;
+
+ /* Enable the device */
+ retval = pci_enable_device(pdev);
+ if (retval) {
+ dev_err(&pdev->dev, "Unable to enable device\n");
+ goto err;
+ }
+
+ /* Map Registers */
+ retval = pci_request_regions(pdev, driver_name);
+ if (retval) {
+ dev_err(&pdev->dev, "Unable to reserve resources\n");
+ goto err_resource;
+ }
+
+ /* Map registers in BAR 0 */
+ vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16);
+ if (!vmic_base) {
+ dev_err(&pdev->dev, "Unable to remap CRG region\n");
+ retval = -EIO;
+ goto err_remap;
+ }
+
+ /* Clear the FPGA VME IF contents */
+ iowrite32(0, vmic_base + VME_CONTROL);
+
+ /* Clear any initial BERR */
+ data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
+ data |= BM_VME_CONTROL_BERRST;
+ iowrite32(data, vmic_base + VME_CONTROL);
+
+ /* Enable the vme interface and byte swapping */
+ data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
+ data = data | BM_VME_CONTROL_MASTER_ENDIAN |
+ BM_VME_CONTROL_SLAVE_ENDIAN |
+ BM_VME_CONTROL_ABLE |
+ BM_VME_CONTROL_BERRI |
+ BM_VME_CONTROL_BPENA |
+ BM_VME_CONTROL_VBENA;
+ iowrite32(data, vmic_base + VME_CONTROL);
+
+ return 0;
+
+err_remap:
+ pci_release_regions(pdev);
+err_resource:
+ pci_disable_device(pdev);
+err:
+ return retval;
+}
+
+static void vmic_remove(struct pci_dev *pdev)
+{
+ iounmap(vmic_base);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+
+}
+
+static void __exit vmic_exit(void)
+{
+ pci_unregister_driver(&vmic_driver);
+}
+
+MODULE_DESCRIPTION("VMIVME-7805 board support driver");
+MODULE_AUTHOR("Arthur Benilov <arthur.benilov@iba-group.com>");
+MODULE_LICENSE("GPL");
+
+module_init(vmic_init);
+module_exit(vmic_exit);
+
diff --git a/drivers/staging/vme/boards/vme_vmivme7805.h b/drivers/staging/vme/boards/vme_vmivme7805.h
new file mode 100644
index 00000000000..44c2c449808
--- /dev/null
+++ b/drivers/staging/vme/boards/vme_vmivme7805.h
@@ -0,0 +1,37 @@
+/*
+ * vmivme_7805.h
+ *
+ * Support for the VMIVME-7805 board access to the Universe II bridge.
+ *
+ * Author: Arthur Benilov <arthur.benilov@iba-group.com>
+ * Copyright 2010 Ion Beam Application, 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.
+ */
+
+
+#ifndef _VMIVME_7805_H
+#define _VMIVME_7805_H
+
+#ifndef PCI_VENDOR_ID_VMIC
+#define PCI_VENDOR_ID_VMIC 0x114A
+#endif
+
+#ifndef PCI_DEVICE_ID_VTIMR
+#define PCI_DEVICE_ID_VTIMR 0x0004
+#endif
+
+#define VME_CONTROL 0x0000
+#define BM_VME_CONTROL_MASTER_ENDIAN 0x0001
+#define BM_VME_CONTROL_SLAVE_ENDIAN 0x0002
+#define BM_VME_CONTROL_ABLE 0x0004
+#define BM_VME_CONTROL_BERRI 0x0040
+#define BM_VME_CONTROL_BERRST 0x0080
+#define BM_VME_CONTROL_BPENA 0x0400
+#define BM_VME_CONTROL_VBENA 0x0800
+
+#endif /* _VMIVME_7805_H */
+
diff --git a/drivers/staging/vme/bridges/Kconfig b/drivers/staging/vme/bridges/Kconfig
index 023cceba0c5..9331064e047 100644
--- a/drivers/staging/vme/bridges/Kconfig
+++ b/drivers/staging/vme/bridges/Kconfig
@@ -2,12 +2,14 @@ comment "VME Bridge Drivers"
config VME_CA91CX42
tristate "Universe II"
+ depends on VIRT_TO_BUS
help
If you say Y here you get support for the Tundra CA91C142
(Universe II) VME bridge chip.
config VME_TSI148
tristate "Tempe"
+ depends on VIRT_TO_BUS
help
If you say Y here you get support for the Tundra TSI148 VME bridge
chip.
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c
index 1cf3e91db59..b159ea58adf 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.c
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -1,8 +1,8 @@
/*
* Support for the Tundra Universe I/II VME-PCI Bridge Chips
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
*
* Based on work by Tom Armistead and Ajit Prem
* Copyright 2004 Motorola Inc.
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -38,25 +39,12 @@ static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *);
static void ca91cx42_remove(struct pci_dev *);
static void __exit ca91cx42_exit(void);
-struct vme_bridge *ca91cx42_bridge;
-wait_queue_head_t dma_queue;
-wait_queue_head_t iack_queue;
-wait_queue_head_t lm_queue;
-wait_queue_head_t mbox_queue;
-
-void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */
-void *crcsr_kernel;
-dma_addr_t crcsr_bus;
-
-struct mutex vme_rmw; /* Only one RMW cycle at a time */
-struct mutex vme_int; /*
- * Only one VME interrupt can be
- * generated at a time, provide locking
- */
+/* Module parameters */
+static int geoid;
static char driver_name[] = "vme_ca91cx42";
-static struct pci_device_id ca91cx42_ids[] = {
+static const struct pci_device_id ca91cx42_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) },
{ },
};
@@ -68,14 +56,14 @@ static struct pci_driver ca91cx42_driver = {
.remove = ca91cx42_remove,
};
-static u32 ca91cx42_DMA_irqhandler(void)
+static u32 ca91cx42_DMA_irqhandler(struct ca91cx42_driver *bridge)
{
- wake_up(&dma_queue);
+ wake_up(&(bridge->dma_queue));
return CA91CX42_LINT_DMA;
}
-static u32 ca91cx42_LM_irqhandler(u32 stat)
+static u32 ca91cx42_LM_irqhandler(struct ca91cx42_driver *bridge, u32 stat)
{
int i;
u32 serviced = 0;
@@ -83,7 +71,7 @@ static u32 ca91cx42_LM_irqhandler(u32 stat)
for (i = 0; i < 4; i++) {
if (stat & CA91CX42_LINT_LM[i]) {
/* We only enable interrupts if the callback is set */
- lm_callback[i](i);
+ bridge->lm_callback[i](i);
serviced |= CA91CX42_LINT_LM[i];
}
}
@@ -92,40 +80,25 @@ static u32 ca91cx42_LM_irqhandler(u32 stat)
}
/* XXX This needs to be split into 4 queues */
-static u32 ca91cx42_MB_irqhandler(int mbox_mask)
+static u32 ca91cx42_MB_irqhandler(struct ca91cx42_driver *bridge, int mbox_mask)
{
- wake_up(&mbox_queue);
+ wake_up(&(bridge->mbox_queue));
return CA91CX42_LINT_MBOX;
}
-static u32 ca91cx42_IACK_irqhandler(void)
+static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge)
{
- wake_up(&iack_queue);
+ wake_up(&(bridge->iack_queue));
return CA91CX42_LINT_SW_IACK;
}
-#if 0
-int ca91cx42_bus_error_chk(int clrflag)
-{
- int tmp;
- tmp = ioread32(ca91cx42_bridge->base + PCI_COMMAND);
- if (tmp & 0x08000000) { /* S_TA is Set */
- if (clrflag)
- iowrite32(tmp | 0x08000000,
- ca91cx42_bridge->base + PCI_COMMAND);
- return 1;
- }
- return 0;
-}
-#endif
-
-static u32 ca91cx42_VERR_irqhandler(void)
+static u32 ca91cx42_VERR_irqhandler(struct ca91cx42_driver *bridge)
{
int val;
- val = ioread32(ca91cx42_bridge->base + DGCS);
+ val = ioread32(bridge->base + DGCS);
if (!(val & 0x00000800)) {
printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read "
@@ -135,11 +108,11 @@ static u32 ca91cx42_VERR_irqhandler(void)
return CA91CX42_LINT_VERR;
}
-static u32 ca91cx42_LERR_irqhandler(void)
+static u32 ca91cx42_LERR_irqhandler(struct ca91cx42_driver *bridge)
{
int val;
- val = ioread32(ca91cx42_bridge->base + DGCS);
+ val = ioread32(bridge->base + DGCS);
if (!(val & 0x00000800)) {
printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read "
@@ -151,13 +124,18 @@ static u32 ca91cx42_LERR_irqhandler(void)
}
-static u32 ca91cx42_VIRQ_irqhandler(int stat)
+static u32 ca91cx42_VIRQ_irqhandler(struct vme_bridge *ca91cx42_bridge,
+ int stat)
{
int vec, i, serviced = 0;
+ struct ca91cx42_driver *bridge;
+
+ bridge = ca91cx42_bridge->driver_priv;
+
for (i = 7; i > 0; i--) {
if (stat & (1 << i)) {
- vec = ioread32(ca91cx42_bridge->base +
+ vec = ioread32(bridge->base +
CA91CX42_V_STATID[i]) & 0xff;
vme_irq_handler(ca91cx42_bridge, i, vec);
@@ -169,15 +147,18 @@ static u32 ca91cx42_VIRQ_irqhandler(int stat)
return serviced;
}
-static irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id)
+static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr)
{
u32 stat, enable, serviced = 0;
+ struct vme_bridge *ca91cx42_bridge;
+ struct ca91cx42_driver *bridge;
- if (dev_id != ca91cx42_bridge->base)
- return IRQ_NONE;
+ ca91cx42_bridge = ptr;
- enable = ioread32(ca91cx42_bridge->base + LINT_EN);
- stat = ioread32(ca91cx42_bridge->base + LINT_STAT);
+ bridge = ca91cx42_bridge->driver_priv;
+
+ enable = ioread32(bridge->base + LINT_EN);
+ stat = ioread32(bridge->base + LINT_STAT);
/* Only look at unmasked interrupts */
stat &= enable;
@@ -186,42 +167,45 @@ static irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id)
return IRQ_NONE;
if (stat & CA91CX42_LINT_DMA)
- serviced |= ca91cx42_DMA_irqhandler();
+ serviced |= ca91cx42_DMA_irqhandler(bridge);
if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 |
CA91CX42_LINT_LM3))
- serviced |= ca91cx42_LM_irqhandler(stat);
+ serviced |= ca91cx42_LM_irqhandler(bridge, stat);
if (stat & CA91CX42_LINT_MBOX)
- serviced |= ca91cx42_MB_irqhandler(stat);
+ serviced |= ca91cx42_MB_irqhandler(bridge, stat);
if (stat & CA91CX42_LINT_SW_IACK)
- serviced |= ca91cx42_IACK_irqhandler();
+ serviced |= ca91cx42_IACK_irqhandler(bridge);
if (stat & CA91CX42_LINT_VERR)
- serviced |= ca91cx42_VERR_irqhandler();
+ serviced |= ca91cx42_VERR_irqhandler(bridge);
if (stat & CA91CX42_LINT_LERR)
- serviced |= ca91cx42_LERR_irqhandler();
+ serviced |= ca91cx42_LERR_irqhandler(bridge);
if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 |
CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 |
CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 |
CA91CX42_LINT_VIRQ7))
- serviced |= ca91cx42_VIRQ_irqhandler(stat);
+ serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat);
/* Clear serviced interrupts */
- iowrite32(stat, ca91cx42_bridge->base + LINT_STAT);
+ iowrite32(stat, bridge->base + LINT_STAT);
return IRQ_HANDLED;
}
-static int ca91cx42_irq_init(struct vme_bridge *bridge)
+static int ca91cx42_irq_init(struct vme_bridge *ca91cx42_bridge)
{
int result, tmp;
struct pci_dev *pdev;
+ struct ca91cx42_driver *bridge;
+
+ bridge = ca91cx42_bridge->driver_priv;
/* Need pdev */
- pdev = container_of(bridge->parent, struct pci_dev, dev);
+ pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev);
/* Initialise list for VME bus errors */
- INIT_LIST_HEAD(&(bridge->vme_errors));
+ INIT_LIST_HEAD(&(ca91cx42_bridge->vme_errors));
- mutex_init(&(bridge->irq_mtx));
+ mutex_init(&(ca91cx42_bridge->irq_mtx));
/* Disable interrupts from PCI to VME */
iowrite32(0, bridge->base + VINT_EN);
@@ -232,7 +216,7 @@ static int ca91cx42_irq_init(struct vme_bridge *bridge)
iowrite32(0x00FFFFFF, bridge->base + LINT_STAT);
result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED,
- driver_name, pdev);
+ driver_name, ca91cx42_bridge);
if (result) {
dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n",
pdev->irq);
@@ -254,15 +238,16 @@ static int ca91cx42_irq_init(struct vme_bridge *bridge)
return 0;
}
-static void ca91cx42_irq_exit(struct pci_dev *pdev)
+static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge,
+ struct pci_dev *pdev)
{
/* Disable interrupts from PCI to VME */
- iowrite32(0, ca91cx42_bridge->base + VINT_EN);
+ iowrite32(0, bridge->base + VINT_EN);
/* Disable PCI interrupts */
- iowrite32(0, ca91cx42_bridge->base + LINT_EN);
+ iowrite32(0, bridge->base + LINT_EN);
/* Clear Any Pending PCI Interrupts */
- iowrite32(0x00FFFFFF, ca91cx42_bridge->base + LINT_STAT);
+ iowrite32(0x00FFFFFF, bridge->base + LINT_STAT);
free_irq(pdev->irq, pdev);
}
@@ -270,21 +255,25 @@ static void ca91cx42_irq_exit(struct pci_dev *pdev)
/*
* Set up an VME interrupt
*/
-void ca91cx42_irq_set(int level, int state, int sync)
+void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, int state,
+ int sync)
{
struct pci_dev *pdev;
u32 tmp;
+ struct ca91cx42_driver *bridge;
+
+ bridge = ca91cx42_bridge->driver_priv;
/* Enable IRQ level */
- tmp = ioread32(ca91cx42_bridge->base + LINT_EN);
+ tmp = ioread32(bridge->base + LINT_EN);
if (state == 0)
tmp &= ~CA91CX42_LINT_VIRQ[level];
else
tmp |= CA91CX42_LINT_VIRQ[level];
- iowrite32(tmp, ca91cx42_bridge->base + LINT_EN);
+ iowrite32(tmp, bridge->base + LINT_EN);
if ((state == 0) && (sync != 0)) {
pdev = container_of(ca91cx42_bridge->parent, struct pci_dev,
@@ -294,34 +283,38 @@ void ca91cx42_irq_set(int level, int state, int sync)
}
}
-int ca91cx42_irq_generate(int level, int statid)
+int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level,
+ int statid)
{
u32 tmp;
+ struct ca91cx42_driver *bridge;
+
+ bridge = ca91cx42_bridge->driver_priv;
/* Universe can only generate even vectors */
if (statid & 1)
return -EINVAL;
- mutex_lock(&(vme_int));
+ mutex_lock(&(bridge->vme_int));
- tmp = ioread32(ca91cx42_bridge->base + VINT_EN);
+ tmp = ioread32(bridge->base + VINT_EN);
/* Set Status/ID */
- iowrite32(statid << 24, ca91cx42_bridge->base + STATID);
+ iowrite32(statid << 24, bridge->base + STATID);
/* Assert VMEbus IRQ */
tmp = tmp | (1 << (level + 24));
- iowrite32(tmp, ca91cx42_bridge->base + VINT_EN);
+ iowrite32(tmp, bridge->base + VINT_EN);
/* Wait for IACK */
- wait_event_interruptible(iack_queue, 0);
+ wait_event_interruptible(bridge->iack_queue, 0);
/* Return interrupt to low state */
- tmp = ioread32(ca91cx42_bridge->base + VINT_EN);
+ tmp = ioread32(bridge->base + VINT_EN);
tmp = tmp & ~(1 << (level + 24));
- iowrite32(tmp, ca91cx42_bridge->base + VINT_EN);
+ iowrite32(tmp, bridge->base + VINT_EN);
- mutex_unlock(&(vme_int));
+ mutex_unlock(&(bridge->vme_int));
return 0;
}
@@ -330,9 +323,12 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
unsigned long long vme_base, unsigned long long size,
dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle)
{
- unsigned int i, addr = 0, granularity = 0;
+ unsigned int i, addr = 0, granularity;
unsigned int temp_ctl = 0;
unsigned int vme_bound, pci_offset;
+ struct ca91cx42_driver *bridge;
+
+ bridge = image->parent->driver_priv;
i = image->number;
@@ -366,13 +362,9 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
* Bound address is a valid address for the window, adjust
* accordingly
*/
- vme_bound = vme_base + size - granularity;
+ vme_bound = vme_base + size;
pci_offset = pci_base - vme_base;
- /* XXX Need to check that vme_base, vme_bound and pci_offset aren't
- * too big for registers
- */
-
if ((i == 0) || (i == 4))
granularity = 0x1000;
else
@@ -392,26 +384,14 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
}
/* Disable while we are mucking around */
- temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+ temp_ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]);
temp_ctl &= ~CA91CX42_VSI_CTL_EN;
- iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+ iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
/* Setup mapping */
- iowrite32(vme_base, ca91cx42_bridge->base + CA91CX42_VSI_BS[i]);
- iowrite32(vme_bound, ca91cx42_bridge->base + CA91CX42_VSI_BD[i]);
- iowrite32(pci_offset, ca91cx42_bridge->base + CA91CX42_VSI_TO[i]);
-
-/* XXX Prefetch stuff currently unsupported */
-#if 0
- if (vmeIn->wrPostEnable)
- temp_ctl |= CA91CX42_VSI_CTL_PWEN;
- if (vmeIn->prefetchEnable)
- temp_ctl |= CA91CX42_VSI_CTL_PREN;
- if (vmeIn->rmwLock)
- temp_ctl |= CA91CX42_VSI_CTL_LLRMW;
- if (vmeIn->data64BitCapable)
- temp_ctl |= CA91CX42_VSI_CTL_LD64EN;
-#endif
+ iowrite32(vme_base, bridge->base + CA91CX42_VSI_BS[i]);
+ iowrite32(vme_bound, bridge->base + CA91CX42_VSI_BD[i]);
+ iowrite32(pci_offset, bridge->base + CA91CX42_VSI_TO[i]);
/* Setup address space */
temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M;
@@ -429,12 +409,12 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA;
/* Write ctl reg without enable */
- iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+ iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
if (enabled)
temp_ctl |= CA91CX42_VSI_CTL_EN;
- iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+ iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
return 0;
}
@@ -445,6 +425,9 @@ int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled,
{
unsigned int i, granularity = 0, ctl = 0;
unsigned long long vme_bound, pci_offset;
+ struct ca91cx42_driver *bridge;
+
+ bridge = image->parent->driver_priv;
i = image->number;
@@ -454,11 +437,11 @@ int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled,
granularity = 0x10000;
/* Read Registers */
- ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+ ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]);
- *vme_base = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BS[i]);
- vme_bound = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BD[i]);
- pci_offset = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_TO[i]);
+ *vme_base = ioread32(bridge->base + CA91CX42_VSI_BS[i]);
+ vme_bound = ioread32(bridge->base + CA91CX42_VSI_BD[i]);
+ pci_offset = ioread32(bridge->base + CA91CX42_VSI_TO[i]);
*pci_base = (dma_addr_t)vme_base + pci_offset;
*size = (unsigned long long)((vme_bound - *vme_base) + granularity);
@@ -502,6 +485,9 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
unsigned long long existing_size;
int retval = 0;
struct pci_dev *pdev;
+ struct vme_bridge *ca91cx42_bridge;
+
+ ca91cx42_bridge = image->parent;
/* Find pci_dev container of dev */
if (ca91cx42_bridge->parent == NULL) {
@@ -510,8 +496,8 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
}
pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev);
- existing_size = (unsigned long long)(image->pci_resource.end -
- image->pci_resource.start);
+ existing_size = (unsigned long long)(image->bus_resource.end -
+ image->bus_resource.start);
/* If the existing size is OK, return */
if (existing_size == (size - 1))
@@ -520,15 +506,15 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
if (existing_size != 0) {
iounmap(image->kern_base);
image->kern_base = NULL;
- if (image->pci_resource.name != NULL)
- kfree(image->pci_resource.name);
- release_resource(&(image->pci_resource));
- memset(&(image->pci_resource), 0, sizeof(struct resource));
+ if (image->bus_resource.name != NULL)
+ kfree(image->bus_resource.name);
+ release_resource(&(image->bus_resource));
+ memset(&(image->bus_resource), 0, sizeof(struct resource));
}
- if (image->pci_resource.name == NULL) {
- image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
- if (image->pci_resource.name == NULL) {
+ if (image->bus_resource.name == NULL) {
+ image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
+ if (image->bus_resource.name == NULL) {
printk(KERN_ERR "Unable to allocate memory for resource"
" name\n");
retval = -ENOMEM;
@@ -536,26 +522,26 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
}
}
- sprintf((char *)image->pci_resource.name, "%s.%d",
+ sprintf((char *)image->bus_resource.name, "%s.%d",
ca91cx42_bridge->name, image->number);
- image->pci_resource.start = 0;
- image->pci_resource.end = (unsigned long)size;
- image->pci_resource.flags = IORESOURCE_MEM;
+ image->bus_resource.start = 0;
+ image->bus_resource.end = (unsigned long)size;
+ image->bus_resource.flags = IORESOURCE_MEM;
retval = pci_bus_alloc_resource(pdev->bus,
- &(image->pci_resource), size, size, PCIBIOS_MIN_MEM,
+ &(image->bus_resource), size, size, PCIBIOS_MIN_MEM,
0, NULL, NULL);
if (retval) {
printk(KERN_ERR "Failed to allocate mem resource for "
"window %d size 0x%lx start 0x%lx\n",
image->number, (unsigned long)size,
- (unsigned long)image->pci_resource.start);
+ (unsigned long)image->bus_resource.start);
goto err_resource;
}
image->kern_base = ioremap_nocache(
- image->pci_resource.start, size);
+ image->bus_resource.start, size);
if (image->kern_base == NULL) {
printk(KERN_ERR "Failed to remap resource\n");
retval = -ENOMEM;
@@ -567,24 +553,24 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
iounmap(image->kern_base);
image->kern_base = NULL;
err_remap:
- release_resource(&(image->pci_resource));
+ release_resource(&(image->bus_resource));
err_resource:
- kfree(image->pci_resource.name);
- memset(&(image->pci_resource), 0, sizeof(struct resource));
+ kfree(image->bus_resource.name);
+ memset(&(image->bus_resource), 0, sizeof(struct resource));
err_name:
return retval;
}
/*
- * * Free and unmap PCI Resource
- * */
+ * Free and unmap PCI Resource
+ */
static void ca91cx42_free_resource(struct vme_master_resource *image)
{
iounmap(image->kern_base);
image->kern_base = NULL;
- release_resource(&(image->pci_resource));
- kfree(image->pci_resource.name);
- memset(&(image->pci_resource), 0, sizeof(struct resource));
+ release_resource(&(image->bus_resource));
+ kfree(image->bus_resource.name);
+ memset(&(image->bus_resource), 0, sizeof(struct resource));
}
@@ -593,17 +579,27 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
{
int retval = 0;
- unsigned int i;
+ unsigned int i, granularity = 0;
unsigned int temp_ctl = 0;
unsigned long long pci_bound, vme_offset, pci_base;
+ struct ca91cx42_driver *bridge;
+
+ bridge = image->parent->driver_priv;
+
+ i = image->number;
+
+ if ((i == 0) || (i == 4))
+ granularity = 0x1000;
+ else
+ granularity = 0x10000;
/* Verify input data */
- if (vme_base & 0xFFF) {
+ if (vme_base & (granularity - 1)) {
printk(KERN_ERR "Invalid VME Window alignment\n");
retval = -EINVAL;
goto err_window;
}
- if (size & 0xFFF) {
+ if (size & (granularity - 1)) {
printk(KERN_ERR "Invalid VME Window alignment\n");
retval = -EINVAL;
goto err_window;
@@ -611,9 +607,6 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
spin_lock(&(image->lock));
- /* XXX We should do this much later, so that we can exit without
- * needing to redo the mapping...
- */
/*
* Let's allocate the resource here rather than further up the stack as
* it avoids pushing loads of bus dependant stuff up the stack
@@ -627,27 +620,19 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
goto err_res;
}
- pci_base = (unsigned long long)image->pci_resource.start;
+ pci_base = (unsigned long long)image->bus_resource.start;
/*
* Bound address is a valid address for the window, adjust
* according to window granularity.
*/
- pci_bound = pci_base + (size - 0x1000);
+ pci_bound = pci_base + size;
vme_offset = vme_base - pci_base;
- i = image->number;
-
/* Disable while we are mucking around */
- temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+ temp_ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]);
temp_ctl &= ~CA91CX42_LSI_CTL_EN;
- iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
-
-/* XXX Prefetch stuff currently unsupported */
-#if 0
- if (vmeOut->wrPostEnable)
- temp_ctl |= 0x40000000;
-#endif
+ iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
/* Setup cycle types */
temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M;
@@ -718,17 +703,17 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM;
/* Setup mapping */
- iowrite32(pci_base, ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
- iowrite32(pci_bound, ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
- iowrite32(vme_offset, ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
+ iowrite32(pci_base, bridge->base + CA91CX42_LSI_BS[i]);
+ iowrite32(pci_bound, bridge->base + CA91CX42_LSI_BD[i]);
+ iowrite32(vme_offset, bridge->base + CA91CX42_LSI_TO[i]);
/* Write ctl reg without enable */
- iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+ iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
if (enabled)
temp_ctl |= CA91CX42_LSI_CTL_EN;
- iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+ iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
spin_unlock(&(image->lock));
return 0;
@@ -747,17 +732,20 @@ int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
{
unsigned int i, ctl;
unsigned long long pci_base, pci_bound, vme_offset;
+ struct ca91cx42_driver *bridge;
+
+ bridge = image->parent->driver_priv;
i = image->number;
- ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+ ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]);
- pci_base = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
- vme_offset = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
- pci_bound = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
+ pci_base = ioread32(bridge->base + CA91CX42_LSI_BS[i]);
+ vme_offset = ioread32(bridge->base + CA91CX42_LSI_TO[i]);
+ pci_bound = ioread32(bridge->base + CA91CX42_LSI_BD[i]);
*vme_base = pci_base + vme_offset;
- *size = (pci_bound - pci_base) + 0x1000;
+ *size = (unsigned long long)(pci_bound - pci_base);
*enabled = 0;
*aspace = 0;
@@ -822,12 +810,6 @@ int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
break;
}
-/* XXX Prefetch stuff currently unsupported */
-#if 0
- if (ctl & 0x40000000)
- vmeOut->wrPostEnable = 1;
-#endif
-
return 0;
}
@@ -850,7 +832,7 @@ int ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf,
size_t count, loff_t offset)
{
- int retval;
+ ssize_t retval;
spin_lock(&(image->lock));
@@ -877,12 +859,528 @@ ssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf,
return retval;
}
-int ca91cx42_slot_get(void)
+unsigned int ca91cx42_master_rmw(struct vme_master_resource *image,
+ unsigned int mask, unsigned int compare, unsigned int swap,
+ loff_t offset)
+{
+ u32 pci_addr, result;
+ int i;
+ struct ca91cx42_driver *bridge;
+ struct device *dev;
+
+ bridge = image->parent->driver_priv;
+ dev = image->parent->parent;
+
+ /* Find the PCI address that maps to the desired VME address */
+ i = image->number;
+
+ /* Locking as we can only do one of these at a time */
+ mutex_lock(&(bridge->vme_rmw));
+
+ /* Lock image */
+ spin_lock(&(image->lock));
+
+ pci_addr = (u32)image->kern_base + offset;
+
+ /* Address must be 4-byte aligned */
+ if (pci_addr & 0x3) {
+ dev_err(dev, "RMW Address not 4-byte aligned\n");
+ return -EINVAL;
+ }
+
+ /* Ensure RMW Disabled whilst configuring */
+ iowrite32(0, bridge->base + SCYC_CTL);
+
+ /* Configure registers */
+ iowrite32(mask, bridge->base + SCYC_EN);
+ iowrite32(compare, bridge->base + SCYC_CMP);
+ iowrite32(swap, bridge->base + SCYC_SWP);
+ iowrite32(pci_addr, bridge->base + SCYC_ADDR);
+
+ /* Enable RMW */
+ iowrite32(CA91CX42_SCYC_CTL_CYC_RMW, bridge->base + SCYC_CTL);
+
+ /* Kick process off with a read to the required address. */
+ result = ioread32(image->kern_base + offset);
+
+ /* Disable RMW */
+ iowrite32(0, bridge->base + SCYC_CTL);
+
+ spin_unlock(&(image->lock));
+
+ mutex_unlock(&(bridge->vme_rmw));
+
+ return result;
+}
+
+int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
+ struct vme_dma_attr *dest, size_t count)
+{
+ struct ca91cx42_dma_entry *entry, *prev;
+ struct vme_dma_pci *pci_attr;
+ struct vme_dma_vme *vme_attr;
+ dma_addr_t desc_ptr;
+ int retval = 0;
+
+ /* XXX descriptor must be aligned on 64-bit boundaries */
+ entry = (struct ca91cx42_dma_entry *)
+ kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL);
+ if (entry == NULL) {
+ printk(KERN_ERR "Failed to allocate memory for dma resource "
+ "structure\n");
+ retval = -ENOMEM;
+ goto err_mem;
+ }
+
+ /* Test descriptor alignment */
+ if ((unsigned long)&(entry->descriptor) & CA91CX42_DCPP_M) {
+ printk("Descriptor not aligned to 16 byte boundary as "
+ "required: %p\n", &(entry->descriptor));
+ retval = -EINVAL;
+ goto err_align;
+ }
+
+ memset(&(entry->descriptor), 0, sizeof(struct ca91cx42_dma_descriptor));
+
+ if (dest->type == VME_DMA_VME) {
+ entry->descriptor.dctl |= CA91CX42_DCTL_L2V;
+ vme_attr = (struct vme_dma_vme *)dest->private;
+ pci_attr = (struct vme_dma_pci *)src->private;
+ } else {
+ vme_attr = (struct vme_dma_vme *)src->private;
+ pci_attr = (struct vme_dma_pci *)dest->private;
+ }
+
+ /* Check we can do fullfill required attributes */
+ if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 |
+ VME_USER2)) != 0) {
+
+ printk(KERN_ERR "Unsupported cycle type\n");
+ retval = -EINVAL;
+ goto err_aspace;
+ }
+
+ if ((vme_attr->cycle & ~(VME_SCT | VME_BLT | VME_SUPER | VME_USER |
+ VME_PROG | VME_DATA)) != 0) {
+
+ printk(KERN_ERR "Unsupported cycle type\n");
+ retval = -EINVAL;
+ goto err_cycle;
+ }
+
+ /* Check to see if we can fullfill source and destination */
+ if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) ||
+ ((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) {
+
+ printk(KERN_ERR "Cannot perform transfer with this "
+ "source-destination combination\n");
+ retval = -EINVAL;
+ goto err_direct;
+ }
+
+ /* Setup cycle types */
+ if (vme_attr->cycle & VME_BLT)
+ entry->descriptor.dctl |= CA91CX42_DCTL_VCT_BLT;
+
+ /* Setup data width */
+ switch (vme_attr->dwidth) {
+ case VME_D8:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D8;
+ break;
+ case VME_D16:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D16;
+ break;
+ case VME_D32:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D32;
+ break;
+ case VME_D64:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D64;
+ break;
+ default:
+ printk(KERN_ERR "Invalid data width\n");
+ return -EINVAL;
+ }
+
+ /* Setup address space */
+ switch (vme_attr->aspace) {
+ case VME_A16:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A16;
+ break;
+ case VME_A24:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A24;
+ break;
+ case VME_A32:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A32;
+ break;
+ case VME_USER1:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER1;
+ break;
+ case VME_USER2:
+ entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER2;
+ break;
+ default:
+ printk(KERN_ERR "Invalid address space\n");
+ return -EINVAL;
+ break;
+ }
+
+ if (vme_attr->cycle & VME_SUPER)
+ entry->descriptor.dctl |= CA91CX42_DCTL_SUPER_SUPR;
+ if (vme_attr->cycle & VME_PROG)
+ entry->descriptor.dctl |= CA91CX42_DCTL_PGM_PGM;
+
+ entry->descriptor.dtbc = count;
+ entry->descriptor.dla = pci_attr->address;
+ entry->descriptor.dva = vme_attr->address;
+ entry->descriptor.dcpp = CA91CX42_DCPP_NULL;
+
+ /* Add to list */
+ list_add_tail(&(entry->list), &(list->entries));
+
+ /* Fill out previous descriptors "Next Address" */
+ if (entry->list.prev != &(list->entries)) {
+ prev = list_entry(entry->list.prev, struct ca91cx42_dma_entry,
+ list);
+ /* We need the bus address for the pointer */
+ desc_ptr = virt_to_bus(&(entry->descriptor));
+ prev->descriptor.dcpp = desc_ptr & ~CA91CX42_DCPP_M;
+ }
+
+ return 0;
+
+err_cycle:
+err_aspace:
+err_direct:
+err_align:
+ kfree(entry);
+err_mem:
+ return retval;
+}
+
+static int ca91cx42_dma_busy(struct vme_bridge *ca91cx42_bridge)
+{
+ u32 tmp;
+ struct ca91cx42_driver *bridge;
+
+ bridge = ca91cx42_bridge->driver_priv;
+
+ tmp = ioread32(bridge->base + DGCS);
+
+ if (tmp & CA91CX42_DGCS_ACT)
+ return 0;
+ else
+ return 1;
+}
+
+int ca91cx42_dma_list_exec(struct vme_dma_list *list)
+{
+ struct vme_dma_resource *ctrlr;
+ struct ca91cx42_dma_entry *entry;
+ int retval = 0;
+ dma_addr_t bus_addr;
+ u32 val;
+
+ struct ca91cx42_driver *bridge;
+
+ ctrlr = list->parent;
+
+ bridge = ctrlr->parent->driver_priv;
+
+ mutex_lock(&(ctrlr->mtx));
+
+ if (!(list_empty(&(ctrlr->running)))) {
+ /*
+ * XXX We have an active DMA transfer and currently haven't
+ * sorted out the mechanism for "pending" DMA transfers.
+ * Return busy.
+ */
+ /* Need to add to pending here */
+ mutex_unlock(&(ctrlr->mtx));
+ return -EBUSY;
+ } else {
+ list_add(&(list->list), &(ctrlr->running));
+ }
+
+ /* Get first bus address and write into registers */
+ entry = list_first_entry(&(list->entries), struct ca91cx42_dma_entry,
+ list);
+
+ bus_addr = virt_to_bus(&(entry->descriptor));
+
+ mutex_unlock(&(ctrlr->mtx));
+
+ iowrite32(0, bridge->base + DTBC);
+ iowrite32(bus_addr & ~CA91CX42_DCPP_M, bridge->base + DCPP);
+
+ /* Start the operation */
+ val = ioread32(bridge->base + DGCS);
+
+ /* XXX Could set VMEbus On and Off Counters here */
+ val &= (CA91CX42_DGCS_VON_M | CA91CX42_DGCS_VOFF_M);
+
+ val |= (CA91CX42_DGCS_CHAIN | CA91CX42_DGCS_STOP | CA91CX42_DGCS_HALT |
+ CA91CX42_DGCS_DONE | CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR |
+ CA91CX42_DGCS_PERR);
+
+ iowrite32(val, bridge->base + DGCS);
+
+ val |= CA91CX42_DGCS_GO;
+
+ iowrite32(val, bridge->base + DGCS);
+
+ wait_event_interruptible(bridge->dma_queue,
+ ca91cx42_dma_busy(ctrlr->parent));
+
+ /*
+ * Read status register, this register is valid until we kick off a
+ * new transfer.
+ */
+ val = ioread32(bridge->base + DGCS);
+
+ if (val & (CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR |
+ CA91CX42_DGCS_PERR)) {
+
+ printk(KERN_ERR "ca91c042: DMA Error. DGCS=%08X\n", val);
+ val = ioread32(bridge->base + DCTL);
+ }
+
+ /* Remove list from running list */
+ mutex_lock(&(ctrlr->mtx));
+ list_del(&(list->list));
+ mutex_unlock(&(ctrlr->mtx));
+
+ return retval;
+
+}
+
+int ca91cx42_dma_list_empty(struct vme_dma_list *list)
+{
+ struct list_head *pos, *temp;
+ struct ca91cx42_dma_entry *entry;
+
+ /* detach and free each entry */
+ list_for_each_safe(pos, temp, &(list->entries)) {
+ list_del(pos);
+ entry = list_entry(pos, struct ca91cx42_dma_entry, list);
+ kfree(entry);
+ }
+
+ return 0;
+}
+
+/*
+ * All 4 location monitors reside at the same base - this is therefore a
+ * system wide configuration.
+ *
+ * This does not enable the LM monitor - that should be done when the first
+ * callback is attached and disabled when the last callback is removed.
+ */
+int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
+ vme_address_t aspace, vme_cycle_t cycle)
+{
+ u32 temp_base, lm_ctl = 0;
+ int i;
+ struct ca91cx42_driver *bridge;
+ struct device *dev;
+
+ bridge = lm->parent->driver_priv;
+ dev = lm->parent->parent;
+
+ /* Check the alignment of the location monitor */
+ temp_base = (u32)lm_base;
+ if (temp_base & 0xffff) {
+ dev_err(dev, "Location monitor must be aligned to 64KB "
+ "boundary");
+ return -EINVAL;
+ }
+
+ mutex_lock(&(lm->mtx));
+
+ /* If we already have a callback attached, we can't move it! */
+ for (i = 0; i < lm->monitors; i++) {
+ if (bridge->lm_callback[i] != NULL) {
+ mutex_unlock(&(lm->mtx));
+ dev_err(dev, "Location monitor callback attached, "
+ "can't reset\n");
+ return -EBUSY;
+ }
+ }
+
+ switch (aspace) {
+ case VME_A16:
+ lm_ctl |= CA91CX42_LM_CTL_AS_A16;
+ break;
+ case VME_A24:
+ lm_ctl |= CA91CX42_LM_CTL_AS_A24;
+ break;
+ case VME_A32:
+ lm_ctl |= CA91CX42_LM_CTL_AS_A32;
+ break;
+ default:
+ mutex_unlock(&(lm->mtx));
+ dev_err(dev, "Invalid address space\n");
+ return -EINVAL;
+ break;
+ }
+
+ if (cycle & VME_SUPER)
+ lm_ctl |= CA91CX42_LM_CTL_SUPR;
+ if (cycle & VME_USER)
+ lm_ctl |= CA91CX42_LM_CTL_NPRIV;
+ if (cycle & VME_PROG)
+ lm_ctl |= CA91CX42_LM_CTL_PGM;
+ if (cycle & VME_DATA)
+ lm_ctl |= CA91CX42_LM_CTL_DATA;
+
+ iowrite32(lm_base, bridge->base + LM_BS);
+ iowrite32(lm_ctl, bridge->base + LM_CTL);
+
+ mutex_unlock(&(lm->mtx));
+
+ return 0;
+}
+
+/* Get configuration of the callback monitor and return whether it is enabled
+ * or disabled.
+ */
+int ca91cx42_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base,
+ vme_address_t *aspace, vme_cycle_t *cycle)
+{
+ u32 lm_ctl, enabled = 0;
+ struct ca91cx42_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
+
+ mutex_lock(&(lm->mtx));
+
+ *lm_base = (unsigned long long)ioread32(bridge->base + LM_BS);
+ lm_ctl = ioread32(bridge->base + LM_CTL);
+
+ if (lm_ctl & CA91CX42_LM_CTL_EN)
+ enabled = 1;
+
+ if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A16)
+ *aspace = VME_A16;
+ if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A24)
+ *aspace = VME_A24;
+ if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A32)
+ *aspace = VME_A32;
+
+ *cycle = 0;
+ if (lm_ctl & CA91CX42_LM_CTL_SUPR)
+ *cycle |= VME_SUPER;
+ if (lm_ctl & CA91CX42_LM_CTL_NPRIV)
+ *cycle |= VME_USER;
+ if (lm_ctl & CA91CX42_LM_CTL_PGM)
+ *cycle |= VME_PROG;
+ if (lm_ctl & CA91CX42_LM_CTL_DATA)
+ *cycle |= VME_DATA;
+
+ mutex_unlock(&(lm->mtx));
+
+ return enabled;
+}
+
+/*
+ * Attach a callback to a specific location monitor.
+ *
+ * Callback will be passed the monitor triggered.
+ */
+int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor,
+ void (*callback)(int))
+{
+ u32 lm_ctl, tmp;
+ struct ca91cx42_driver *bridge;
+ struct device *dev;
+
+ bridge = lm->parent->driver_priv;
+ dev = lm->parent->parent;
+
+ mutex_lock(&(lm->mtx));
+
+ /* Ensure that the location monitor is configured - need PGM or DATA */
+ lm_ctl = ioread32(bridge->base + LM_CTL);
+ if ((lm_ctl & (CA91CX42_LM_CTL_PGM | CA91CX42_LM_CTL_DATA)) == 0) {
+ mutex_unlock(&(lm->mtx));
+ dev_err(dev, "Location monitor not properly configured\n");
+ return -EINVAL;
+ }
+
+ /* Check that a callback isn't already attached */
+ if (bridge->lm_callback[monitor] != NULL) {
+ mutex_unlock(&(lm->mtx));
+ dev_err(dev, "Existing callback attached\n");
+ return -EBUSY;
+ }
+
+ /* Attach callback */
+ bridge->lm_callback[monitor] = callback;
+
+ /* Enable Location Monitor interrupt */
+ tmp = ioread32(bridge->base + LINT_EN);
+ tmp |= CA91CX42_LINT_LM[monitor];
+ iowrite32(tmp, bridge->base + LINT_EN);
+
+ /* Ensure that global Location Monitor Enable set */
+ if ((lm_ctl & CA91CX42_LM_CTL_EN) == 0) {
+ lm_ctl |= CA91CX42_LM_CTL_EN;
+ iowrite32(lm_ctl, bridge->base + LM_CTL);
+ }
+
+ mutex_unlock(&(lm->mtx));
+
+ return 0;
+}
+
+/*
+ * Detach a callback function forn a specific location monitor.
+ */
+int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor)
+{
+ u32 tmp;
+ struct ca91cx42_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
+
+ mutex_lock(&(lm->mtx));
+
+ /* Disable Location Monitor and ensure previous interrupts are clear */
+ tmp = ioread32(bridge->base + LINT_EN);
+ tmp &= ~CA91CX42_LINT_LM[monitor];
+ iowrite32(tmp, bridge->base + LINT_EN);
+
+ iowrite32(CA91CX42_LINT_LM[monitor],
+ bridge->base + LINT_STAT);
+
+ /* Detach callback */
+ bridge->lm_callback[monitor] = NULL;
+
+ /* If all location monitors disabled, disable global Location Monitor */
+ if ((tmp & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 |
+ CA91CX42_LINT_LM3)) == 0) {
+ tmp = ioread32(bridge->base + LM_CTL);
+ tmp &= ~CA91CX42_LM_CTL_EN;
+ iowrite32(tmp, bridge->base + LM_CTL);
+ }
+
+ mutex_unlock(&(lm->mtx));
+
+ return 0;
+}
+
+int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge)
{
u32 slot = 0;
+ struct ca91cx42_driver *bridge;
+
+ bridge = ca91cx42_bridge->driver_priv;
+
+ if (!geoid) {
+ slot = ioread32(bridge->base + VCSR_BS);
+ slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27);
+ } else
+ slot = geoid;
- slot = ioread32(ca91cx42_bridge->base + VCSR_BS);
- slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27);
return (int)slot;
}
@@ -900,19 +1398,21 @@ static int __init ca91cx42_init(void)
* Auto-ID or Geographic address. This function ensures that the window is
* enabled at an offset consistent with the boards geopgraphic address.
*/
-static int ca91cx42_crcsr_init(struct pci_dev *pdev)
+static int ca91cx42_crcsr_init(struct vme_bridge *ca91cx42_bridge,
+ struct pci_dev *pdev)
{
unsigned int crcsr_addr;
int tmp, slot;
+ struct ca91cx42_driver *bridge;
+
+ bridge = ca91cx42_bridge->driver_priv;
+
+ slot = ca91cx42_slot_get(ca91cx42_bridge);
+
+ /* Write CSR Base Address if slot ID is supplied as a module param */
+ if (geoid)
+ iowrite32(geoid << 27, bridge->base + VCSR_BS);
-/* XXX We may need to set this somehow as the Universe II does not support
- * geographical addressing.
- */
-#if 0
- if (vme_slotnum != -1)
- iowrite32(vme_slotnum << 27, ca91cx42_bridge->base + VCSR_BS);
-#endif
- slot = ca91cx42_slot_get();
dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot);
if (slot == 0) {
dev_err(&pdev->dev, "Slot number is unset, not configuring "
@@ -921,39 +1421,44 @@ static int ca91cx42_crcsr_init(struct pci_dev *pdev)
}
/* Allocate mem for CR/CSR image */
- crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
- &crcsr_bus);
- if (crcsr_kernel == NULL) {
+ bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
+ &(bridge->crcsr_bus));
+ if (bridge->crcsr_kernel == NULL) {
dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR "
"image\n");
return -ENOMEM;
}
- memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
+ memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
crcsr_addr = slot * (512 * 1024);
- iowrite32(crcsr_bus - crcsr_addr, ca91cx42_bridge->base + VCSR_TO);
+ iowrite32(bridge->crcsr_bus - crcsr_addr, bridge->base + VCSR_TO);
- tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL);
+ tmp = ioread32(bridge->base + VCSR_CTL);
tmp |= CA91CX42_VCSR_CTL_EN;
- iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL);
+ iowrite32(tmp, bridge->base + VCSR_CTL);
return 0;
}
-static void ca91cx42_crcsr_exit(struct pci_dev *pdev)
+static void ca91cx42_crcsr_exit(struct vme_bridge *ca91cx42_bridge,
+ struct pci_dev *pdev)
{
u32 tmp;
+ struct ca91cx42_driver *bridge;
+
+ bridge = ca91cx42_bridge->driver_priv;
/* Turn off CR/CSR space */
- tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL);
+ tmp = ioread32(bridge->base + VCSR_CTL);
tmp &= ~CA91CX42_VCSR_CTL_EN;
- iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL);
+ iowrite32(tmp, bridge->base + VCSR_CTL);
/* Free image */
- iowrite32(0, ca91cx42_bridge->base + VCSR_TO);
+ iowrite32(0, bridge->base + VCSR_TO);
- pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus);
+ pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel,
+ bridge->crcsr_bus);
}
static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -961,11 +1466,11 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
int retval, i;
u32 data;
struct list_head *pos = NULL;
+ struct vme_bridge *ca91cx42_bridge;
+ struct ca91cx42_driver *ca91cx42_device;
struct vme_master_resource *master_image;
struct vme_slave_resource *slave_image;
-#if 0
struct vme_dma_resource *dma_ctrlr;
-#endif
struct vme_lm_resource *lm;
/* We want to support more than one of each bridge so we need to
@@ -982,6 +1487,19 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge));
+ ca91cx42_device = kmalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL);
+
+ if (ca91cx42_device == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate memory for device "
+ "structure\n");
+ retval = -ENOMEM;
+ goto err_driver;
+ }
+
+ memset(ca91cx42_device, 0, sizeof(struct ca91cx42_driver));
+
+ ca91cx42_bridge->driver_priv = ca91cx42_device;
+
/* Enable the device */
retval = pci_enable_device(pdev);
if (retval) {
@@ -997,16 +1515,16 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* map registers in BAR 0 */
- ca91cx42_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0),
+ ca91cx42_device->base = ioremap_nocache(pci_resource_start(pdev, 0),
4096);
- if (!ca91cx42_bridge->base) {
+ if (!ca91cx42_device->base) {
dev_err(&pdev->dev, "Unable to remap CRG region\n");
retval = -EIO;
goto err_remap;
}
/* Check to see if the mapping worked out */
- data = ioread32(ca91cx42_bridge->base + CA91CX42_PCI_ID) & 0x0000FFFF;
+ data = ioread32(ca91cx42_device->base + CA91CX42_PCI_ID) & 0x0000FFFF;
if (data != PCI_VENDOR_ID_TUNDRA) {
dev_err(&pdev->dev, "PCI_ID check failed\n");
retval = -EIO;
@@ -1014,11 +1532,10 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* Initialize wait queues & mutual exclusion flags */
- /* XXX These need to be moved to the vme_bridge structure */
- init_waitqueue_head(&dma_queue);
- init_waitqueue_head(&iack_queue);
- mutex_init(&(vme_int));
- mutex_init(&(vme_rmw));
+ init_waitqueue_head(&(ca91cx42_device->dma_queue));
+ init_waitqueue_head(&(ca91cx42_device->iack_queue));
+ mutex_init(&(ca91cx42_device->vme_int));
+ mutex_init(&(ca91cx42_device->vme_rmw));
ca91cx42_bridge->parent = &(pdev->dev);
strcpy(ca91cx42_bridge->name, driver_name);
@@ -1050,7 +1567,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
VME_SUPER | VME_USER | VME_PROG | VME_DATA;
master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64;
- memset(&(master_image->pci_resource), 0,
+ memset(&(master_image->bus_resource), 0,
sizeof(struct resource));
master_image->kern_base = NULL;
list_add_tail(&(master_image->list),
@@ -1084,7 +1601,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
list_add_tail(&(slave_image->list),
&(ca91cx42_bridge->slave_resources));
}
-#if 0
+
/* Add dma engines to list */
INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources));
for (i = 0; i < CA91C142_MAX_DMA; i++) {
@@ -1100,12 +1617,14 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mutex_init(&(dma_ctrlr->mtx));
dma_ctrlr->locked = 0;
dma_ctrlr->number = i;
+ dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
+ VME_DMA_MEM_TO_VME;
INIT_LIST_HEAD(&(dma_ctrlr->pending));
INIT_LIST_HEAD(&(dma_ctrlr->running));
list_add_tail(&(dma_ctrlr->list),
&(ca91cx42_bridge->dma_resources));
}
-#endif
+
/* Add location monitor to list */
INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources));
lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL);
@@ -1128,33 +1647,26 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ca91cx42_bridge->master_set = ca91cx42_master_set;
ca91cx42_bridge->master_read = ca91cx42_master_read;
ca91cx42_bridge->master_write = ca91cx42_master_write;
-#if 0
ca91cx42_bridge->master_rmw = ca91cx42_master_rmw;
ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add;
ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec;
ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty;
-#endif
ca91cx42_bridge->irq_set = ca91cx42_irq_set;
ca91cx42_bridge->irq_generate = ca91cx42_irq_generate;
-#if 0
ca91cx42_bridge->lm_set = ca91cx42_lm_set;
ca91cx42_bridge->lm_get = ca91cx42_lm_get;
ca91cx42_bridge->lm_attach = ca91cx42_lm_attach;
ca91cx42_bridge->lm_detach = ca91cx42_lm_detach;
-#endif
ca91cx42_bridge->slot_get = ca91cx42_slot_get;
- data = ioread32(ca91cx42_bridge->base + MISC_CTL);
+ data = ioread32(ca91cx42_device->base + MISC_CTL);
dev_info(&pdev->dev, "Board is%s the VME system controller\n",
(data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not");
- dev_info(&pdev->dev, "Slot ID is %d\n", ca91cx42_slot_get());
+ dev_info(&pdev->dev, "Slot ID is %d\n",
+ ca91cx42_slot_get(ca91cx42_bridge));
- if (ca91cx42_crcsr_init(pdev)) {
+ if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) {
dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
- retval = -EINVAL;
-#if 0
- goto err_crcsr;
-#endif
}
/* Need to save ca91cx42_bridge pointer locally in link list for use in
@@ -1166,14 +1678,13 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_reg;
}
+ pci_set_drvdata(pdev, ca91cx42_bridge);
+
return 0;
vme_unregister_bridge(ca91cx42_bridge);
err_reg:
- ca91cx42_crcsr_exit(pdev);
-#if 0
-err_crcsr:
-#endif
+ ca91cx42_crcsr_exit(ca91cx42_bridge, pdev);
err_lm:
/* resources are stored in link list */
list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
@@ -1181,7 +1692,6 @@ err_lm:
list_del(pos);
kfree(lm);
}
-#if 0
err_dma:
/* resources are stored in link list */
list_for_each(pos, &(ca91cx42_bridge->dma_resources)) {
@@ -1189,7 +1699,6 @@ err_dma:
list_del(pos);
kfree(dma_ctrlr);
}
-#endif
err_slave:
/* resources are stored in link list */
list_for_each(pos, &(ca91cx42_bridge->slave_resources)) {
@@ -1206,15 +1715,17 @@ err_master:
kfree(master_image);
}
- ca91cx42_irq_exit(pdev);
+ ca91cx42_irq_exit(ca91cx42_device, pdev);
err_irq:
err_test:
- iounmap(ca91cx42_bridge->base);
+ iounmap(ca91cx42_device->base);
err_remap:
pci_release_regions(pdev);
err_resource:
pci_disable_device(pdev);
err_enable:
+ kfree(ca91cx42_device);
+err_driver:
kfree(ca91cx42_bridge);
err_struct:
return retval;
@@ -1228,32 +1739,37 @@ void ca91cx42_remove(struct pci_dev *pdev)
struct vme_slave_resource *slave_image;
struct vme_dma_resource *dma_ctrlr;
struct vme_lm_resource *lm;
+ struct ca91cx42_driver *bridge;
+ struct vme_bridge *ca91cx42_bridge = pci_get_drvdata(pdev);
+
+ bridge = ca91cx42_bridge->driver_priv;
+
/* Turn off Ints */
- iowrite32(0, ca91cx42_bridge->base + LINT_EN);
+ iowrite32(0, bridge->base + LINT_EN);
/* Turn off the windows */
- iowrite32(0x00800000, ca91cx42_bridge->base + LSI0_CTL);
- iowrite32(0x00800000, ca91cx42_bridge->base + LSI1_CTL);
- iowrite32(0x00800000, ca91cx42_bridge->base + LSI2_CTL);
- iowrite32(0x00800000, ca91cx42_bridge->base + LSI3_CTL);
- iowrite32(0x00800000, ca91cx42_bridge->base + LSI4_CTL);
- iowrite32(0x00800000, ca91cx42_bridge->base + LSI5_CTL);
- iowrite32(0x00800000, ca91cx42_bridge->base + LSI6_CTL);
- iowrite32(0x00800000, ca91cx42_bridge->base + LSI7_CTL);
- iowrite32(0x00F00000, ca91cx42_bridge->base + VSI0_CTL);
- iowrite32(0x00F00000, ca91cx42_bridge->base + VSI1_CTL);
- iowrite32(0x00F00000, ca91cx42_bridge->base + VSI2_CTL);
- iowrite32(0x00F00000, ca91cx42_bridge->base + VSI3_CTL);
- iowrite32(0x00F00000, ca91cx42_bridge->base + VSI4_CTL);
- iowrite32(0x00F00000, ca91cx42_bridge->base + VSI5_CTL);
- iowrite32(0x00F00000, ca91cx42_bridge->base + VSI6_CTL);
- iowrite32(0x00F00000, ca91cx42_bridge->base + VSI7_CTL);
+ iowrite32(0x00800000, bridge->base + LSI0_CTL);
+ iowrite32(0x00800000, bridge->base + LSI1_CTL);
+ iowrite32(0x00800000, bridge->base + LSI2_CTL);
+ iowrite32(0x00800000, bridge->base + LSI3_CTL);
+ iowrite32(0x00800000, bridge->base + LSI4_CTL);
+ iowrite32(0x00800000, bridge->base + LSI5_CTL);
+ iowrite32(0x00800000, bridge->base + LSI6_CTL);
+ iowrite32(0x00800000, bridge->base + LSI7_CTL);
+ iowrite32(0x00F00000, bridge->base + VSI0_CTL);
+ iowrite32(0x00F00000, bridge->base + VSI1_CTL);
+ iowrite32(0x00F00000, bridge->base + VSI2_CTL);
+ iowrite32(0x00F00000, bridge->base + VSI3_CTL);
+ iowrite32(0x00F00000, bridge->base + VSI4_CTL);
+ iowrite32(0x00F00000, bridge->base + VSI5_CTL);
+ iowrite32(0x00F00000, bridge->base + VSI6_CTL);
+ iowrite32(0x00F00000, bridge->base + VSI7_CTL);
vme_unregister_bridge(ca91cx42_bridge);
-#if 0
- ca91cx42_crcsr_exit(pdev);
-#endif
+
+ ca91cx42_crcsr_exit(ca91cx42_bridge, pdev);
+
/* resources are stored in link list */
list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
lm = list_entry(pos, struct vme_lm_resource, list);
@@ -1283,9 +1799,9 @@ void ca91cx42_remove(struct pci_dev *pdev)
kfree(master_image);
}
- ca91cx42_irq_exit(pdev);
+ ca91cx42_irq_exit(bridge, pdev);
- iounmap(ca91cx42_bridge->base);
+ iounmap(bridge->base);
pci_release_regions(pdev);
@@ -1299,588 +1815,11 @@ static void __exit ca91cx42_exit(void)
pci_unregister_driver(&ca91cx42_driver);
}
+MODULE_PARM_DESC(geoid, "Override geographical addressing");
+module_param(geoid, int, 0);
+
MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge");
MODULE_LICENSE("GPL");
module_init(ca91cx42_init);
module_exit(ca91cx42_exit);
-
-/*----------------------------------------------------------------------------
- * STAGING
- *--------------------------------------------------------------------------*/
-
-#if 0
-#define SWIZZLE(X) ( ((X & 0xFF000000) >> 24) | ((X & 0x00FF0000) >> 8) | ((X & 0x0000FF00) << 8) | ((X & 0x000000FF) << 24))
-
-int ca91cx42_master_rmw(vmeRmwCfg_t *vmeRmw)
-{
- int temp_ctl = 0;
- int tempBS = 0;
- int tempBD = 0;
- int tempTO = 0;
- int vmeBS = 0;
- int vmeBD = 0;
- int *rmw_pci_data_ptr = NULL;
- int *vaDataPtr = NULL;
- int i;
- vmeOutWindowCfg_t vmeOut;
- if (vmeRmw->maxAttempts < 1) {
- return -EINVAL;
- }
- if (vmeRmw->targetAddrU) {
- return -EINVAL;
- }
- /* Find the PCI address that maps to the desired VME address */
- for (i = 0; i < 8; i++) {
- temp_ctl = ioread32(ca91cx42_bridge->base +
- CA91CX42_LSI_CTL[i]);
- if ((temp_ctl & 0x80000000) == 0) {
- continue;
- }
- memset(&vmeOut, 0, sizeof(vmeOut));
- vmeOut.windowNbr = i;
- ca91cx42_get_out_bound(&vmeOut);
- if (vmeOut.addrSpace != vmeRmw->addrSpace) {
- continue;
- }
- tempBS = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
- tempBD = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
- tempTO = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
- vmeBS = tempBS + tempTO;
- vmeBD = tempBD + tempTO;
- if ((vmeRmw->targetAddr >= vmeBS) &&
- (vmeRmw->targetAddr < vmeBD)) {
- rmw_pci_data_ptr =
- (int *)(tempBS + (vmeRmw->targetAddr - vmeBS));
- vaDataPtr =
- (int *)(out_image_va[i] +
- (vmeRmw->targetAddr - vmeBS));
- break;
- }
- }
-
- /* If no window - fail. */
- if (rmw_pci_data_ptr == NULL) {
- return -EINVAL;
- }
- /* Setup the RMW registers. */
- iowrite32(0, ca91cx42_bridge->base + SCYC_CTL);
- iowrite32(SWIZZLE(vmeRmw->enableMask), ca91cx42_bridge->base + SCYC_EN);
- iowrite32(SWIZZLE(vmeRmw->compareData), ca91cx42_bridge->base +
- SCYC_CMP);
- iowrite32(SWIZZLE(vmeRmw->swapData), ca91cx42_bridge->base + SCYC_SWP);
- iowrite32((int)rmw_pci_data_ptr, ca91cx42_bridge->base + SCYC_ADDR);
- iowrite32(1, ca91cx42_bridge->base + SCYC_CTL);
-
- /* Run the RMW cycle until either success or max attempts. */
- vmeRmw->numAttempts = 1;
- while (vmeRmw->numAttempts <= vmeRmw->maxAttempts) {
-
- if ((ioread32(vaDataPtr) & vmeRmw->enableMask) ==
- (vmeRmw->swapData & vmeRmw->enableMask)) {
-
- iowrite32(0, ca91cx42_bridge->base + SCYC_CTL);
- break;
-
- }
- vmeRmw->numAttempts++;
- }
-
- /* If no success, set num Attempts to be greater than max attempts */
- if (vmeRmw->numAttempts > vmeRmw->maxAttempts) {
- vmeRmw->numAttempts = vmeRmw->maxAttempts + 1;
- }
-
- return 0;
-}
-
-int uniSetupDctlReg(vmeDmaPacket_t * vmeDma, int *dctlregreturn)
-{
- unsigned int dctlreg = 0x80;
- struct vmeAttr *vmeAttr;
-
- if (vmeDma->srcBus == VME_DMA_VME) {
- dctlreg = 0;
- vmeAttr = &vmeDma->srcVmeAttr;
- } else {
- dctlreg = 0x80000000;
- vmeAttr = &vmeDma->dstVmeAttr;
- }
-
- switch (vmeAttr->maxDataWidth) {
- case VME_D8:
- break;
- case VME_D16:
- dctlreg |= 0x00400000;
- break;
- case VME_D32:
- dctlreg |= 0x00800000;
- break;
- case VME_D64:
- dctlreg |= 0x00C00000;
- break;
- }
-
- switch (vmeAttr->addrSpace) {
- case VME_A16:
- break;
- case VME_A24:
- dctlreg |= 0x00010000;
- break;
- case VME_A32:
- dctlreg |= 0x00020000;
- break;
- case VME_USER1:
- dctlreg |= 0x00060000;
- break;
- case VME_USER2:
- dctlreg |= 0x00070000;
- break;
-
- case VME_A64: /* not supported in Universe DMA */
- case VME_CRCSR:
- case VME_USER3:
- case VME_USER4:
- return -EINVAL;
- break;
- }
- if (vmeAttr->userAccessType == VME_PROG) {
- dctlreg |= 0x00004000;
- }
- if (vmeAttr->dataAccessType == VME_SUPER) {
- dctlreg |= 0x00001000;
- }
- if (vmeAttr->xferProtocol != VME_SCT) {
- dctlreg |= 0x00000100;
- }
- *dctlregreturn = dctlreg;
- return 0;
-}
-
-unsigned int
-ca91cx42_start_dma(int channel, unsigned int dgcsreg, TDMA_Cmd_Packet *vmeLL)
-{
- unsigned int val;
-
- /* Setup registers as needed for direct or chained. */
- if (dgcsreg & 0x8000000) {
- iowrite32(0, ca91cx42_bridge->base + DTBC);
- iowrite32((unsigned int)vmeLL, ca91cx42_bridge->base + DCPP);
- } else {
-#if 0
- printk(KERN_ERR "Starting: DGCS = %08x\n", dgcsreg);
- printk(KERN_ERR "Starting: DVA = %08x\n",
- ioread32(&vmeLL->dva));
- printk(KERN_ERR "Starting: DLV = %08x\n",
- ioread32(&vmeLL->dlv));
- printk(KERN_ERR "Starting: DTBC = %08x\n",
- ioread32(&vmeLL->dtbc));
- printk(KERN_ERR "Starting: DCTL = %08x\n",
- ioread32(&vmeLL->dctl));
-#endif
- /* Write registers */
- iowrite32(ioread32(&vmeLL->dva), ca91cx42_bridge->base + DVA);
- iowrite32(ioread32(&vmeLL->dlv), ca91cx42_bridge->base + DLA);
- iowrite32(ioread32(&vmeLL->dtbc), ca91cx42_bridge->base + DTBC);
- iowrite32(ioread32(&vmeLL->dctl), ca91cx42_bridge->base + DCTL);
- iowrite32(0, ca91cx42_bridge->base + DCPP);
- }
-
- /* Start the operation */
- iowrite32(dgcsreg, ca91cx42_bridge->base + DGCS);
- val = get_tbl();
- iowrite32(dgcsreg | 0x8000000F, ca91cx42_bridge->base + DGCS);
- return val;
-}
-
-TDMA_Cmd_Packet *ca91cx42_setup_dma(vmeDmaPacket_t * vmeDma)
-{
- vmeDmaPacket_t *vmeCur;
- int maxPerPage;
- int currentLLcount;
- TDMA_Cmd_Packet *startLL;
- TDMA_Cmd_Packet *currentLL;
- TDMA_Cmd_Packet *nextLL;
- unsigned int dctlreg = 0;
-
- maxPerPage = PAGESIZE / sizeof(TDMA_Cmd_Packet) - 1;
- startLL = (TDMA_Cmd_Packet *) __get_free_pages(GFP_KERNEL, 0);
- if (startLL == 0) {
- return startLL;
- }
- /* First allocate pages for descriptors and create linked list */
- vmeCur = vmeDma;
- currentLL = startLL;
- currentLLcount = 0;
- while (vmeCur != 0) {
- if (vmeCur->pNextPacket != 0) {
- currentLL->dcpp = (unsigned int)(currentLL + 1);
- currentLLcount++;
- if (currentLLcount >= maxPerPage) {
- currentLL->dcpp =
- __get_free_pages(GFP_KERNEL, 0);
- currentLLcount = 0;
- }
- currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
- } else {
- currentLL->dcpp = (unsigned int)0;
- }
- vmeCur = vmeCur->pNextPacket;
- }
-
- /* Next fill in information for each descriptor */
- vmeCur = vmeDma;
- currentLL = startLL;
- while (vmeCur != 0) {
- if (vmeCur->srcBus == VME_DMA_VME) {
- iowrite32(vmeCur->srcAddr, &currentLL->dva);
- iowrite32(vmeCur->dstAddr, &currentLL->dlv);
- } else {
- iowrite32(vmeCur->srcAddr, &currentLL->dlv);
- iowrite32(vmeCur->dstAddr, &currentLL->dva);
- }
- uniSetupDctlReg(vmeCur, &dctlreg);
- iowrite32(dctlreg, &currentLL->dctl);
- iowrite32(vmeCur->byteCount, &currentLL->dtbc);
-
- currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
- vmeCur = vmeCur->pNextPacket;
- }
-
- /* Convert Links to PCI addresses. */
- currentLL = startLL;
- while (currentLL != 0) {
- nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
- if (nextLL == 0) {
- iowrite32(1, &currentLL->dcpp);
- } else {
- iowrite32((unsigned int)virt_to_bus(nextLL),
- &currentLL->dcpp);
- }
- currentLL = nextLL;
- }
-
- /* Return pointer to descriptors list */
- return startLL;
-}
-
-int ca91cx42_free_dma(TDMA_Cmd_Packet *startLL)
-{
- TDMA_Cmd_Packet *currentLL;
- TDMA_Cmd_Packet *prevLL;
- TDMA_Cmd_Packet *nextLL;
- unsigned int dcppreg;
-
- /* Convert Links to virtual addresses. */
- currentLL = startLL;
- while (currentLL != 0) {
- dcppreg = ioread32(&currentLL->dcpp);
- dcppreg &= ~6;
- if (dcppreg & 1) {
- currentLL->dcpp = 0;
- } else {
- currentLL->dcpp = (unsigned int)bus_to_virt(dcppreg);
- }
- currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
- }
-
- /* Free all pages associated with the descriptors. */
- currentLL = startLL;
- prevLL = currentLL;
- while (currentLL != 0) {
- nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
- if (currentLL + 1 != nextLL) {
- free_pages((int)prevLL, 0);
- prevLL = nextLL;
- }
- currentLL = nextLL;
- }
-
- /* Return pointer to descriptors list */
- return 0;
-}
-
-int ca91cx42_do_dma(vmeDmaPacket_t *vmeDma)
-{
- unsigned int dgcsreg = 0;
- unsigned int dctlreg = 0;
- int val;
- int channel, x;
- vmeDmaPacket_t *curDma;
- TDMA_Cmd_Packet *dmaLL;
-
- /* Sanity check the VME chain. */
- channel = vmeDma->channel_number;
- if (channel > 0) {
- return -EINVAL;
- }
- curDma = vmeDma;
- while (curDma != 0) {
- if (curDma->byteCount == 0) {
- return -EINVAL;
- }
- if (curDma->byteCount >= 0x1000000) {
- return -EINVAL;
- }
- if ((curDma->srcAddr & 7) != (curDma->dstAddr & 7)) {
- return -EINVAL;
- }
- switch (curDma->srcBus) {
- case VME_DMA_PCI:
- if (curDma->dstBus != VME_DMA_VME) {
- return -EINVAL;
- }
- break;
- case VME_DMA_VME:
- if (curDma->dstBus != VME_DMA_PCI) {
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- break;
- }
- if (uniSetupDctlReg(curDma, &dctlreg) < 0) {
- return -EINVAL;
- }
-
- curDma = curDma->pNextPacket;
- if (curDma == vmeDma) { /* Endless Loop! */
- return -EINVAL;
- }
- }
-
- /* calculate control register */
- if (vmeDma->pNextPacket != 0) {
- dgcsreg = 0x8000000;
- } else {
- dgcsreg = 0;
- }
-
- for (x = 0; x < 8; x++) { /* vme block size */
- if ((256 << x) >= vmeDma->maxVmeBlockSize) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dgcsreg |= (x << 20);
-
- if (vmeDma->vmeBackOffTimer) {
- for (x = 1; x < 8; x++) { /* vme timer */
- if ((16 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dgcsreg |= (x << 16);
- }
- /*` Setup the dma chain */
- dmaLL = ca91cx42_setup_dma(vmeDma);
-
- /* Start the DMA */
- if (dgcsreg & 0x8000000) {
- vmeDma->vmeDmaStartTick =
- ca91cx42_start_dma(channel, dgcsreg,
- (TDMA_Cmd_Packet *) virt_to_phys(dmaLL));
- } else {
- vmeDma->vmeDmaStartTick =
- ca91cx42_start_dma(channel, dgcsreg, dmaLL);
- }
-
- wait_event_interruptible(dma_queue,
- ioread32(ca91cx42_bridge->base + DGCS) & 0x800);
-
- val = ioread32(ca91cx42_bridge->base + DGCS);
- iowrite32(val | 0xF00, ca91cx42_bridge->base + DGCS);
-
- vmeDma->vmeDmaStatus = 0;
-
- if (!(val & 0x00000800)) {
- vmeDma->vmeDmaStatus = val & 0x700;
- printk(KERN_ERR "ca91c042: DMA Error in ca91cx42_DMA_irqhandler"
- " DGCS=%08X\n", val);
- val = ioread32(ca91cx42_bridge->base + DCPP);
- printk(KERN_ERR "ca91c042: DCPP=%08X\n", val);
- val = ioread32(ca91cx42_bridge->base + DCTL);
- printk(KERN_ERR "ca91c042: DCTL=%08X\n", val);
- val = ioread32(ca91cx42_bridge->base + DTBC);
- printk(KERN_ERR "ca91c042: DTBC=%08X\n", val);
- val = ioread32(ca91cx42_bridge->base + DLA);
- printk(KERN_ERR "ca91c042: DLA=%08X\n", val);
- val = ioread32(ca91cx42_bridge->base + DVA);
- printk(KERN_ERR "ca91c042: DVA=%08X\n", val);
-
- }
- /* Free the dma chain */
- ca91cx42_free_dma(dmaLL);
-
- return 0;
-}
-
-int ca91cx42_lm_set(vmeLmCfg_t *vmeLm)
-{
- int temp_ctl = 0;
-
- if (vmeLm->addrU)
- return -EINVAL;
-
- switch (vmeLm->addrSpace) {
- case VME_A64:
- case VME_USER3:
- case VME_USER4:
- return -EINVAL;
- case VME_A16:
- temp_ctl |= 0x00000;
- break;
- case VME_A24:
- temp_ctl |= 0x10000;
- break;
- case VME_A32:
- temp_ctl |= 0x20000;
- break;
- case VME_CRCSR:
- temp_ctl |= 0x50000;
- break;
- case VME_USER1:
- temp_ctl |= 0x60000;
- break;
- case VME_USER2:
- temp_ctl |= 0x70000;
- break;
- }
-
- /* Disable while we are mucking around */
- iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL);
-
- iowrite32(vmeLm->addr, ca91cx42_bridge->base + LM_BS);
-
- /* Setup CTL register. */
- if (vmeLm->userAccessType & VME_SUPER)
- temp_ctl |= 0x00200000;
- if (vmeLm->userAccessType & VME_USER)
- temp_ctl |= 0x00100000;
- if (vmeLm->dataAccessType & VME_PROG)
- temp_ctl |= 0x00800000;
- if (vmeLm->dataAccessType & VME_DATA)
- temp_ctl |= 0x00400000;
-
-
- /* Write ctl reg and enable */
- iowrite32(0x80000000 | temp_ctl, ca91cx42_bridge->base + LM_CTL);
- temp_ctl = ioread32(ca91cx42_bridge->base + LM_CTL);
-
- return 0;
-}
-
-int ca91cx42_wait_lm(vmeLmCfg_t *vmeLm)
-{
- unsigned long flags;
- unsigned int tmp;
-
- spin_lock_irqsave(&lm_lock, flags);
- spin_unlock_irqrestore(&lm_lock, flags);
- if (tmp == 0) {
- if (vmeLm->lmWait < 10)
- vmeLm->lmWait = 10;
- interruptible_sleep_on_timeout(&lm_queue, vmeLm->lmWait);
- }
- iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL);
-
- return 0;
-}
-
-
-
-int ca91cx42_set_arbiter(vmeArbiterCfg_t *vmeArb)
-{
- int temp_ctl = 0;
- int vbto = 0;
-
- temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL);
- temp_ctl &= 0x00FFFFFF;
-
- if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
- vbto = 7;
- } else if (vmeArb->globalTimeoutTimer > 1024) {
- return -EINVAL;
- } else if (vmeArb->globalTimeoutTimer == 0) {
- vbto = 0;
- } else {
- vbto = 1;
- while ((16 * (1 << (vbto - 1))) < vmeArb->globalTimeoutTimer)
- vbto += 1;
- }
- temp_ctl |= (vbto << 28);
-
- if (vmeArb->arbiterMode == VME_PRIORITY_MODE)
- temp_ctl |= 1 << 26;
-
- if (vmeArb->arbiterTimeoutFlag)
- temp_ctl |= 2 << 24;
-
- iowrite32(temp_ctl, ca91cx42_bridge->base + MISC_CTL);
- return 0;
-}
-
-int ca91cx42_get_arbiter(vmeArbiterCfg_t *vmeArb)
-{
- int temp_ctl = 0;
- int vbto = 0;
-
- temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL);
-
- vbto = (temp_ctl >> 28) & 0xF;
- if (vbto != 0)
- vmeArb->globalTimeoutTimer = (16 * (1 << (vbto - 1)));
-
- if (temp_ctl & (1 << 26))
- vmeArb->arbiterMode = VME_PRIORITY_MODE;
- else
- vmeArb->arbiterMode = VME_R_ROBIN_MODE;
-
- if (temp_ctl & (3 << 24))
- vmeArb->arbiterTimeoutFlag = 1;
-
- return 0;
-}
-
-int ca91cx42_set_requestor(vmeRequesterCfg_t *vmeReq)
-{
- int temp_ctl = 0;
-
- temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL);
- temp_ctl &= 0xFF0FFFFF;
-
- if (vmeReq->releaseMode == 1)
- temp_ctl |= (1 << 20);
-
- if (vmeReq->fairMode == 1)
- temp_ctl |= (1 << 21);
-
- temp_ctl |= (vmeReq->requestLevel << 22);
-
- iowrite32(temp_ctl, ca91cx42_bridge->base + MAST_CTL);
- return 0;
-}
-
-int ca91cx42_get_requestor(vmeRequesterCfg_t *vmeReq)
-{
- int temp_ctl = 0;
-
- temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL);
-
- if (temp_ctl & (1 << 20))
- vmeReq->releaseMode = 1;
-
- if (temp_ctl & (1 << 21))
- vmeReq->fairMode = 1;
-
- vmeReq->requestLevel = (temp_ctl & 0xC00000) >> 22;
-
- return 0;
-}
-
-
-#endif
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.h b/drivers/staging/vme/bridges/vme_ca91cx42.h
index 95a42c240a2..e72c65b193e 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.h
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.h
@@ -7,8 +7,8 @@
* Updated by Ajit Prem
* Copyright 2004 Motorola Inc.
*
- * Further updated by Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2009 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Further updated by Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
*
* Derived from ca91c042.h by Michael Wyrick
*
@@ -37,11 +37,27 @@
#define CA91C142_MAX_DMA 1 /* Max DMA Controllers */
#define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */
+/* Structure used to hold driver specific information */
+struct ca91cx42_driver {
+ void *base; /* Base Address of device registers */
+ wait_queue_head_t dma_queue;
+ wait_queue_head_t iack_queue;
+ wait_queue_head_t mbox_queue;
+ void (*lm_callback[4])(int); /* Called in interrupt handler */
+ void *crcsr_kernel;
+ dma_addr_t crcsr_bus;
+ struct mutex vme_rmw; /* Only one RMW cycle at a time */
+ struct mutex vme_int; /*
+ * Only one VME interrupt can be
+ * generated at a time, provide locking
+ */
+};
+
/* See Page 2-77 in the Universe User Manual */
struct ca91cx42_dma_descriptor {
unsigned int dctl; /* DMA Control */
unsigned int dtbc; /* Transfer Byte Count */
- unsigned int dlv; /* PCI Address */
+ unsigned int dla; /* PCI Address */
unsigned int res1; /* Reserved */
unsigned int dva; /* Vme Address */
unsigned int res2; /* Reserved */
@@ -237,32 +253,6 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
#define VCSR_SET 0x0FF8
#define VCSR_BS 0x0FFC
-// DMA General Control/Status Register DGCS (0x220)
-// 32-24 || GO | STOPR | HALTR | 0 || CHAIN | 0 | 0 | 0 ||
-// 23-16 || VON || VOFF ||
-// 15-08 || ACT | STOP | HALT | 0 || DONE | LERR | VERR | P_ERR ||
-// 07-00 || 0 | INT_S | INT_H | 0 || I_DNE | I_LER | I_VER | I_PER ||
-
-// VON - Length Per DMA VMEBus Transfer
-// 0000 = None
-// 0001 = 256 Bytes
-// 0010 = 512
-// 0011 = 1024
-// 0100 = 2048
-// 0101 = 4096
-// 0110 = 8192
-// 0111 = 16384
-
-// VOFF - wait between DMA tenures
-// 0000 = 0 us
-// 0001 = 16
-// 0010 = 32
-// 0011 = 64
-// 0100 = 128
-// 0101 = 256
-// 0110 = 512
-// 0111 = 1024
-
/*
* PCI Class Register
* offset 008
@@ -326,6 +316,16 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
#define CA91CX42_LSI_CTL_VCT_MBLT (1<<8)
#define CA91CX42_LSI_CTL_LAS (1<<0)
+/*
+ * SCYC_CTL Register
+ * offset 178
+ */
+#define CA91CX42_SCYC_CTL_LAS_PCIMEM 0
+#define CA91CX42_SCYC_CTL_LAS_PCIIO (1<<2)
+
+#define CA91CX42_SCYC_CTL_CYC_M (3<<0)
+#define CA91CX42_SCYC_CTL_CYC_RMW (1<<0)
+#define CA91CX42_SCYC_CTL_CYC_ADOH (1<<1)
/*
* LMISC Register
@@ -355,6 +355,71 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
#define CA91CX42_BM_SLSI_RESERVED 0x3F0F0000
/*
+ * DCTL Register
+ * offset 200
+ */
+#define CA91CX42_DCTL_L2V (1<<31)
+#define CA91CX42_DCTL_VDW_M (3<<22)
+#define CA91CX42_DCTL_VDW_M (3<<22)
+#define CA91CX42_DCTL_VDW_D8 0
+#define CA91CX42_DCTL_VDW_D16 (1<<22)
+#define CA91CX42_DCTL_VDW_D32 (1<<23)
+#define CA91CX42_DCTL_VDW_D64 (3<<22)
+
+#define CA91CX42_DCTL_VAS_M (7<<16)
+#define CA91CX42_DCTL_VAS_A16 0
+#define CA91CX42_DCTL_VAS_A24 (1<<16)
+#define CA91CX42_DCTL_VAS_A32 (1<<17)
+#define CA91CX42_DCTL_VAS_USER1 (3<<17)
+#define CA91CX42_DCTL_VAS_USER2 (7<<16)
+
+#define CA91CX42_DCTL_PGM_M (1<<14)
+#define CA91CX42_DCTL_PGM_DATA 0
+#define CA91CX42_DCTL_PGM_PGM (1<<14)
+
+#define CA91CX42_DCTL_SUPER_M (1<<12)
+#define CA91CX42_DCTL_SUPER_NPRIV 0
+#define CA91CX42_DCTL_SUPER_SUPR (1<<12)
+
+#define CA91CX42_DCTL_VCT_M (1<<8)
+#define CA91CX42_DCTL_VCT_BLT (1<<8)
+#define CA91CX42_DCTL_LD64EN (1<<7)
+
+/*
+ * DCPP Register
+ * offset 218
+ */
+#define CA91CX42_DCPP_M 0xf
+#define CA91CX42_DCPP_NULL (1<<0)
+
+/*
+ * DMA General Control/Status Register (DGCS)
+ * offset 220
+ */
+#define CA91CX42_DGCS_GO (1<<31)
+#define CA91CX42_DGCS_STOP_REQ (1<<30)
+#define CA91CX42_DGCS_HALT_REQ (1<<29)
+#define CA91CX42_DGCS_CHAIN (1<<27)
+
+#define CA91CX42_DGCS_VON_M (7<<20)
+
+#define CA91CX42_DGCS_VOFF_M (0xf<<16)
+
+#define CA91CX42_DGCS_ACT (1<<15)
+#define CA91CX42_DGCS_STOP (1<<14)
+#define CA91CX42_DGCS_HALT (1<<13)
+#define CA91CX42_DGCS_DONE (1<<11)
+#define CA91CX42_DGCS_LERR (1<<10)
+#define CA91CX42_DGCS_VERR (1<<9)
+#define CA91CX42_DGCS_PERR (1<<8)
+#define CA91CX42_DGCS_INT_STOP (1<<6)
+#define CA91CX42_DGCS_INT_HALT (1<<5)
+#define CA91CX42_DGCS_INT_DONE (1<<3)
+#define CA91CX42_DGCS_INT_LERR (1<<2)
+#define CA91CX42_DGCS_INT_VERR (1<<1)
+#define CA91CX42_DGCS_INT_PERR (1<<0)
+
+/*
* PCI Interrupt Enable Register
* offset 300
*/
@@ -475,6 +540,19 @@ static const int CA91CX42_LINT_LM[] = { CA91CX42_LINT_LM0, CA91CX42_LINT_LM1,
#define CA91CX42_VSI_CTL_LAS_PCI_IO (1<<0)
#define CA91CX42_VSI_CTL_LAS_PCI_CONF (1<<1)
+/* LM_CTL Register
+ * offset F64
+ */
+#define CA91CX42_LM_CTL_EN (1<<31)
+#define CA91CX42_LM_CTL_PGM (1<<23)
+#define CA91CX42_LM_CTL_DATA (1<<22)
+#define CA91CX42_LM_CTL_SUPR (1<<21)
+#define CA91CX42_LM_CTL_NPRIV (1<<20)
+#define CA91CX42_LM_CTL_AS_M (5<<16)
+#define CA91CX42_LM_CTL_AS_A16 0
+#define CA91CX42_LM_CTL_AS_A24 (1<<16)
+#define CA91CX42_LM_CTL_AS_A32 (1<<17)
+
/*
* VRAI_CTL Register
* offset F70
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index 89a7dccb934..783051f59f1 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -1,8 +1,8 @@
/*
* Support for the Tundra TSI148 VME-PCI Bridge Chip
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
*
* Based on work by Tom Armistead and Ajit Prem
* Copyright 2004 Motorola Inc.
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -59,28 +60,14 @@ int tsi148_dma_list_add (struct vme_dma_list *, struct vme_dma_attr *,
int tsi148_dma_list_exec(struct vme_dma_list *);
int tsi148_dma_list_empty(struct vme_dma_list *);
int tsi148_generate_irq(int, int);
-int tsi148_slot_get(void);
-
-/* Modue parameter */
-int err_chk = 0;
-
-/* XXX These should all be in a per device structure */
-struct vme_bridge *tsi148_bridge;
-wait_queue_head_t dma_queue[2];
-wait_queue_head_t iack_queue;
-void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */
-void *crcsr_kernel;
-dma_addr_t crcsr_bus;
-struct vme_master_resource *flush_image;
-struct mutex vme_rmw; /* Only one RMW cycle at a time */
-struct mutex vme_int; /*
- * Only one VME interrupt can be
- * generated at a time, provide locking
- */
+
+/* Module parameter */
+static int err_chk;
+static int geoid;
static char driver_name[] = "vme_tsi148";
-static struct pci_device_id tsi148_ids[] = {
+static const struct pci_device_id tsi148_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) },
{ },
};
@@ -109,16 +96,17 @@ static void reg_split(unsigned long long variable, unsigned int *high,
/*
* Wakes up DMA queue.
*/
-static u32 tsi148_DMA_irqhandler(int channel_mask)
+static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge,
+ int channel_mask)
{
u32 serviced = 0;
if (channel_mask & TSI148_LCSR_INTS_DMA0S) {
- wake_up(&dma_queue[0]);
+ wake_up(&(bridge->dma_queue[0]));
serviced |= TSI148_LCSR_INTC_DMA0C;
}
if (channel_mask & TSI148_LCSR_INTS_DMA1S) {
- wake_up(&dma_queue[1]);
+ wake_up(&(bridge->dma_queue[1]));
serviced |= TSI148_LCSR_INTC_DMA1C;
}
@@ -128,7 +116,7 @@ static u32 tsi148_DMA_irqhandler(int channel_mask)
/*
* Wake up location monitor queue
*/
-static u32 tsi148_LM_irqhandler(u32 stat)
+static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat)
{
int i;
u32 serviced = 0;
@@ -136,7 +124,7 @@ static u32 tsi148_LM_irqhandler(u32 stat)
for (i = 0; i < 4; i++) {
if(stat & TSI148_LCSR_INTS_LMS[i]) {
/* We only enable interrupts if the callback is set */
- lm_callback[i](i);
+ bridge->lm_callback[i](i);
serviced |= TSI148_LCSR_INTC_LMC[i];
}
}
@@ -149,7 +137,7 @@ static u32 tsi148_LM_irqhandler(u32 stat)
*
* XXX This functionality is not exposed up though API.
*/
-static u32 tsi148_MB_irqhandler(u32 stat)
+static u32 tsi148_MB_irqhandler(struct tsi148_driver *bridge, u32 stat)
{
int i;
u32 val;
@@ -157,8 +145,7 @@ static u32 tsi148_MB_irqhandler(u32 stat)
for (i = 0; i < 4; i++) {
if(stat & TSI148_LCSR_INTS_MBS[i]) {
- val = ioread32be(tsi148_bridge->base +
- TSI148_GCSR_MBOX[i]);
+ val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]);
printk("VME Mailbox %d received: 0x%x\n", i, val);
serviced |= TSI148_LCSR_INTC_MBC[i];
}
@@ -170,22 +157,21 @@ static u32 tsi148_MB_irqhandler(u32 stat)
/*
* Display error & status message when PERR (PCI) exception interrupt occurs.
*/
-static u32 tsi148_PERR_irqhandler(void)
+static u32 tsi148_PERR_irqhandler(struct tsi148_driver *bridge)
{
printk(KERN_ERR
"PCI Exception at address: 0x%08x:%08x, attributes: %08x\n",
- ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAU),
- ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAL),
- ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAT)
+ ioread32be(bridge->base + TSI148_LCSR_EDPAU),
+ ioread32be(bridge->base + TSI148_LCSR_EDPAL),
+ ioread32be(bridge->base + TSI148_LCSR_EDPAT)
);
printk(KERN_ERR
"PCI-X attribute reg: %08x, PCI-X split completion reg: %08x\n",
- ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXA),
- ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXS)
+ ioread32be(bridge->base + TSI148_LCSR_EDPXA),
+ ioread32be(bridge->base + TSI148_LCSR_EDPXS)
);
- iowrite32be(TSI148_LCSR_EDPAT_EDPCL,
- tsi148_bridge->base + TSI148_LCSR_EDPAT);
+ iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT);
return TSI148_LCSR_INTC_PERRC;
}
@@ -193,16 +179,19 @@ static u32 tsi148_PERR_irqhandler(void)
/*
* Save address and status when VME error interrupt occurs.
*/
-static u32 tsi148_VERR_irqhandler(void)
+static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge)
{
unsigned int error_addr_high, error_addr_low;
unsigned long long error_addr;
u32 error_attrib;
struct vme_bus_error *error;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
- error_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAU);
- error_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAL);
- error_attrib = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAT);
+ error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU);
+ error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL);
+ error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT);
reg_join(error_addr_high, error_addr_low, &error_addr);
@@ -226,8 +215,7 @@ static u32 tsi148_VERR_irqhandler(void)
}
/* Clear Status */
- iowrite32be(TSI148_LCSR_VEAT_VESCL,
- tsi148_bridge->base + TSI148_LCSR_VEAT);
+ iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT);
return TSI148_LCSR_INTC_VERRC;
}
@@ -235,9 +223,9 @@ static u32 tsi148_VERR_irqhandler(void)
/*
* Wake up IACK queue.
*/
-static u32 tsi148_IACK_irqhandler(void)
+static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge)
{
- wake_up(&iack_queue);
+ wake_up(&(bridge->iack_queue));
return TSI148_LCSR_INTC_IACKC;
}
@@ -245,9 +233,13 @@ static u32 tsi148_IACK_irqhandler(void)
/*
* Calling VME bus interrupt callback if provided.
*/
-static u32 tsi148_VIRQ_irqhandler(u32 stat)
+static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge,
+ u32 stat)
{
int vec, i, serviced = 0;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
for (i = 7; i > 0; i--) {
if (stat & (1 << i)) {
@@ -257,8 +249,7 @@ static u32 tsi148_VIRQ_irqhandler(u32 stat)
* 8-bit IACK cycles on the bus, read from offset
* 3.
*/
- vec = ioread8(tsi148_bridge->base +
- TSI148_LCSR_VIACK[i] + 3);
+ vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3);
vme_irq_handler(tsi148_bridge, i, vec);
@@ -273,13 +264,19 @@ static u32 tsi148_VIRQ_irqhandler(u32 stat)
* Top level interrupt handler. Clears appropriate interrupt status bits and
* then calls appropriate sub handler(s).
*/
-static irqreturn_t tsi148_irqhandler(int irq, void *dev_id)
+static irqreturn_t tsi148_irqhandler(int irq, void *ptr)
{
u32 stat, enable, serviced = 0;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+
+ tsi148_bridge = ptr;
+
+ bridge = tsi148_bridge->driver_priv;
/* Determine which interrupts are unmasked and set */
- enable = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
- stat = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTS);
+ enable = ioread32be(bridge->base + TSI148_LCSR_INTEO);
+ stat = ioread32be(bridge->base + TSI148_LCSR_INTS);
/* Only look at unmasked interrupts */
stat &= enable;
@@ -291,61 +288,63 @@ static irqreturn_t tsi148_irqhandler(int irq, void *dev_id)
/* Call subhandlers as appropriate */
/* DMA irqs */
if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S))
- serviced |= tsi148_DMA_irqhandler(stat);
+ serviced |= tsi148_DMA_irqhandler(bridge, stat);
/* Location monitor irqs */
if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S |
TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S))
- serviced |= tsi148_LM_irqhandler(stat);
+ serviced |= tsi148_LM_irqhandler(bridge, stat);
/* Mail box irqs */
if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S |
TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S))
- serviced |= tsi148_MB_irqhandler(stat);
+ serviced |= tsi148_MB_irqhandler(bridge, stat);
/* PCI bus error */
if (stat & TSI148_LCSR_INTS_PERRS)
- serviced |= tsi148_PERR_irqhandler();
+ serviced |= tsi148_PERR_irqhandler(bridge);
/* VME bus error */
if (stat & TSI148_LCSR_INTS_VERRS)
- serviced |= tsi148_VERR_irqhandler();
+ serviced |= tsi148_VERR_irqhandler(tsi148_bridge);
/* IACK irq */
if (stat & TSI148_LCSR_INTS_IACKS)
- serviced |= tsi148_IACK_irqhandler();
+ serviced |= tsi148_IACK_irqhandler(bridge);
/* VME bus irqs */
if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S |
TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S |
TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S |
TSI148_LCSR_INTS_IRQ1S))
- serviced |= tsi148_VIRQ_irqhandler(stat);
+ serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat);
/* Clear serviced interrupts */
- iowrite32be(serviced, tsi148_bridge->base + TSI148_LCSR_INTC);
+ iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC);
return IRQ_HANDLED;
}
-static int tsi148_irq_init(struct vme_bridge *bridge)
+static int tsi148_irq_init(struct vme_bridge *tsi148_bridge)
{
int result;
unsigned int tmp;
struct pci_dev *pdev;
+ struct tsi148_driver *bridge;
+
+ pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
- /* Need pdev */
- pdev = container_of(bridge->parent, struct pci_dev, dev);
+ bridge = tsi148_bridge->driver_priv;
/* Initialise list for VME bus errors */
- INIT_LIST_HEAD(&(bridge->vme_errors));
+ INIT_LIST_HEAD(&(tsi148_bridge->vme_errors));
- mutex_init(&(bridge->irq_mtx));
+ mutex_init(&(tsi148_bridge->irq_mtx));
result = request_irq(pdev->irq,
tsi148_irqhandler,
IRQF_SHARED,
- driver_name, pdev);
+ driver_name, tsi148_bridge);
if (result) {
dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n",
pdev->irq);
@@ -359,7 +358,7 @@ static int tsi148_irq_init(struct vme_bridge *bridge)
TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO |
TSI148_LCSR_INTEO_IACKEO;
- /* XXX This leaves the following interrupts masked.
+ /* This leaves the following interrupts masked.
* TSI148_LCSR_INTEO_VIEEO
* TSI148_LCSR_INTEO_SYSFLEO
* TSI148_LCSR_INTEO_ACFLEO
@@ -392,14 +391,14 @@ static int tsi148_irq_init(struct vme_bridge *bridge)
return 0;
}
-static void tsi148_irq_exit(struct pci_dev *pdev)
+static void tsi148_irq_exit(struct tsi148_driver *bridge, struct pci_dev *pdev)
{
/* Turn off interrupts */
- iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEO);
- iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEN);
+ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO);
+ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN);
/* Clear all interrupts */
- iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTC);
+ iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC);
/* Detach interrupt handler */
free_irq(pdev->irq, pdev);
@@ -408,11 +407,11 @@ static void tsi148_irq_exit(struct pci_dev *pdev)
/*
* Check to see if an IACk has been received, return true (1) or false (0).
*/
-int tsi148_iack_received(void)
+int tsi148_iack_received(struct tsi148_driver *bridge)
{
u32 tmp;
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
if (tmp & TSI148_LCSR_VICR_IRQS)
return 0;
@@ -423,20 +422,24 @@ int tsi148_iack_received(void)
/*
* Configure VME interrupt
*/
-void tsi148_irq_set(int level, int state, int sync)
+void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level,
+ int state, int sync)
{
struct pci_dev *pdev;
u32 tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
/* We need to do the ordering differently for enabling and disabling */
if (state == 0) {
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1];
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1];
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
if (sync != 0) {
pdev = container_of(tsi148_bridge->parent,
@@ -445,13 +448,13 @@ void tsi148_irq_set(int level, int state, int sync)
synchronize_irq(pdev->irq);
}
} else {
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
}
}
@@ -459,28 +462,32 @@ void tsi148_irq_set(int level, int state, int sync)
* Generate a VME bus interrupt at the requested level & vector. Wait for
* interrupt to be acked.
*/
-int tsi148_irq_generate(int level, int statid)
+int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, int statid)
{
u32 tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
- mutex_lock(&(vme_int));
+ mutex_lock(&(bridge->vme_int));
/* Read VICR register */
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
/* Set Status/ID */
tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) |
(statid & TSI148_LCSR_VICR_STID_M);
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
/* Assert VMEbus IRQ */
tmp = tmp | TSI148_LCSR_VICR_IRQL[level];
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
/* XXX Consider implementing a timeout? */
- wait_event_interruptible(iack_queue, tsi148_iack_received());
+ wait_event_interruptible(bridge->iack_queue,
+ tsi148_iack_received(bridge));
- mutex_unlock(&(vme_int));
+ mutex_unlock(&(bridge->vme_int));
return 0;
}
@@ -488,8 +495,8 @@ int tsi148_irq_generate(int level, int statid)
/*
* Find the first error in this address range
*/
-static struct vme_bus_error *tsi148_find_error(vme_address_t aspace,
- unsigned long long address, size_t count)
+static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge,
+ vme_address_t aspace, unsigned long long address, size_t count)
{
struct list_head *err_pos;
struct vme_bus_error *vme_err, *valid = NULL;
@@ -520,8 +527,8 @@ static struct vme_bus_error *tsi148_find_error(vme_address_t aspace,
/*
* Clear errors in the provided address range.
*/
-static void tsi148_clear_errors(vme_address_t aspace,
- unsigned long long address, size_t count)
+static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge,
+ vme_address_t aspace, unsigned long long address, size_t count)
{
struct list_head *err_pos, *temp;
struct vme_bus_error *vme_err;
@@ -561,16 +568,9 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
unsigned int vme_bound_low, vme_bound_high;
unsigned int pci_offset_low, pci_offset_high;
unsigned long long vme_bound, pci_offset;
+ struct tsi148_driver *bridge;
-#if 0
- printk("Set slave image %d to:\n", image->number);
- printk("\tEnabled: %s\n", (enabled == 1)? "yes" : "no");
- printk("\tVME Base:0x%llx\n", vme_base);
- printk("\tWindow Size:0x%llx\n", size);
- printk("\tPCI Base:0x%lx\n", (unsigned long)pci_base);
- printk("\tAddress Space:0x%x\n", aspace);
- printk("\tTransfer Cycle Properties:0x%x\n", cycle);
-#endif
+ bridge = image->parent->driver_priv;
i = image->number;
@@ -627,49 +627,27 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
return -EINVAL;
}
-#if 0
- printk("\tVME Bound:0x%llx\n", vme_bound);
- printk("\tPCI Offset:0x%llx\n", pci_offset);
-#endif
-
/* Disable while we are mucking around */
- temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITAT);
temp_ctl &= ~TSI148_LCSR_ITAT_EN;
- iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITAT);
/* Setup mapping */
- iowrite32be(vme_base_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITSAU);
- iowrite32be(vme_base_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITSAL);
- iowrite32be(vme_bound_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITEAU);
- iowrite32be(vme_bound_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITEAL);
- iowrite32be(pci_offset_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITOFU);
- iowrite32be(pci_offset_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITOFL);
-/* XXX Prefetch stuff currently unsupported */
-#if 0
-
- for (x = 0; x < 4; x++) {
- if ((64 << x) >= vmeIn->prefetchSize) {
- break;
- }
- }
- if (x == 4)
- x--;
- temp_ctl |= (x << 16);
-
- if (vmeIn->prefetchThreshold)
- if (vmeIn->prefetchThreshold)
- temp_ctl |= 0x40000;
-#endif
-
/* Setup 2eSST speeds */
temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M;
switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
@@ -712,13 +690,13 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
temp_ctl |= TSI148_LCSR_ITAT_DATA;
/* Write ctl reg without enable */
- iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITAT);
if (enabled)
temp_ctl |= TSI148_LCSR_ITAT_EN;
- iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITAT);
return 0;
@@ -726,8 +704,6 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
/*
* Get slave window configuration.
- *
- * XXX Prefetch currently unsupported.
*/
int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
unsigned long long *vme_base, unsigned long long *size,
@@ -738,25 +714,27 @@ int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
unsigned int vme_bound_low, vme_bound_high;
unsigned int pci_offset_low, pci_offset_high;
unsigned long long vme_bound, pci_offset;
+ struct tsi148_driver *bridge;
+ bridge = image->parent->driver_priv;
i = image->number;
/* Read registers */
- ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITAT);
- vme_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITSAU);
- vme_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITSAL);
- vme_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITEAU);
- vme_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITEAL);
- pci_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITOFU);
- pci_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITOFL);
/* Convert 64-bit variables to 2x 32-bit variables */
@@ -833,6 +811,9 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
unsigned long long existing_size;
int retval = 0;
struct pci_dev *pdev;
+ struct vme_bridge *tsi148_bridge;
+
+ tsi148_bridge = image->parent;
/* Find pci_dev container of dev */
if (tsi148_bridge->parent == NULL) {
@@ -841,8 +822,8 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
}
pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
- existing_size = (unsigned long long)(image->pci_resource.end -
- image->pci_resource.start);
+ existing_size = (unsigned long long)(image->bus_resource.end -
+ image->bus_resource.start);
/* If the existing size is OK, return */
if ((size != 0) && (existing_size == (size - 1)))
@@ -851,10 +832,10 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
if (existing_size != 0) {
iounmap(image->kern_base);
image->kern_base = NULL;
- if (image->pci_resource.name != NULL)
- kfree(image->pci_resource.name);
- release_resource(&(image->pci_resource));
- memset(&(image->pci_resource), 0, sizeof(struct resource));
+ if (image->bus_resource.name != NULL)
+ kfree(image->bus_resource.name);
+ release_resource(&(image->bus_resource));
+ memset(&(image->bus_resource), 0, sizeof(struct resource));
}
/* Exit here if size is zero */
@@ -862,9 +843,9 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
return 0;
}
- if (image->pci_resource.name == NULL) {
- image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
- if (image->pci_resource.name == NULL) {
+ if (image->bus_resource.name == NULL) {
+ image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
+ if (image->bus_resource.name == NULL) {
printk(KERN_ERR "Unable to allocate memory for resource"
" name\n");
retval = -ENOMEM;
@@ -872,26 +853,26 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
}
}
- sprintf((char *)image->pci_resource.name, "%s.%d", tsi148_bridge->name,
+ sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name,
image->number);
- image->pci_resource.start = 0;
- image->pci_resource.end = (unsigned long)size;
- image->pci_resource.flags = IORESOURCE_MEM;
+ image->bus_resource.start = 0;
+ image->bus_resource.end = (unsigned long)size;
+ image->bus_resource.flags = IORESOURCE_MEM;
retval = pci_bus_alloc_resource(pdev->bus,
- &(image->pci_resource), size, size, PCIBIOS_MIN_MEM,
+ &(image->bus_resource), size, size, PCIBIOS_MIN_MEM,
0, NULL, NULL);
if (retval) {
printk(KERN_ERR "Failed to allocate mem resource for "
"window %d size 0x%lx start 0x%lx\n",
image->number, (unsigned long)size,
- (unsigned long)image->pci_resource.start);
+ (unsigned long)image->bus_resource.start);
goto err_resource;
}
image->kern_base = ioremap_nocache(
- image->pci_resource.start, size);
+ image->bus_resource.start, size);
if (image->kern_base == NULL) {
printk(KERN_ERR "Failed to remap resource\n");
retval = -ENOMEM;
@@ -903,10 +884,10 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
iounmap(image->kern_base);
image->kern_base = NULL;
err_remap:
- release_resource(&(image->pci_resource));
+ release_resource(&(image->bus_resource));
err_resource:
- kfree(image->pci_resource.name);
- memset(&(image->pci_resource), 0, sizeof(struct resource));
+ kfree(image->bus_resource.name);
+ memset(&(image->bus_resource), 0, sizeof(struct resource));
err_name:
return retval;
}
@@ -918,9 +899,9 @@ static void tsi148_free_resource(struct vme_master_resource *image)
{
iounmap(image->kern_base);
image->kern_base = NULL;
- release_resource(&(image->pci_resource));
- kfree(image->pci_resource.name);
- memset(&(image->pci_resource), 0, sizeof(struct resource));
+ release_resource(&(image->bus_resource));
+ kfree(image->bus_resource.name);
+ memset(&(image->bus_resource), 0, sizeof(struct resource));
}
/*
@@ -937,6 +918,9 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
unsigned int pci_bound_low, pci_bound_high;
unsigned int vme_offset_low, vme_offset_high;
unsigned long long pci_bound, vme_offset, pci_base;
+ struct tsi148_driver *bridge;
+
+ bridge = image->parent->driver_priv;
/* Verify input data */
if (vme_base & 0xFFFF) {
@@ -970,7 +954,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
pci_bound = 0;
vme_offset = 0;
} else {
- pci_base = (unsigned long long)image->pci_resource.start;
+ pci_base = (unsigned long long)image->bus_resource.start;
/*
* Bound address is a valid address for the window, adjust
@@ -1007,26 +991,12 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
i = image->number;
/* Disable while we are mucking around */
- temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTAT);
temp_ctl &= ~TSI148_LCSR_OTAT_EN;
- iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTAT);
-/* XXX Prefetch stuff currently unsupported */
-#if 0
- if (vmeOut->prefetchEnable) {
- temp_ctl |= 0x40000;
- for (x = 0; x < 4; x++) {
- if ((2 << x) >= vmeOut->prefetchSize)
- break;
- }
- if (x == 4)
- x = 3;
- temp_ctl |= (x << 16);
- }
-#endif
-
/* Setup 2eSST speeds */
temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M;
switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
@@ -1126,33 +1096,27 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
temp_ctl |= TSI148_LCSR_OTAT_PGM;
/* Setup mapping */
- iowrite32be(pci_base_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTSAU);
- iowrite32be(pci_base_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTSAL);
- iowrite32be(pci_bound_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTEAU);
- iowrite32be(pci_bound_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTEAL);
- iowrite32be(vme_offset_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTOFU);
- iowrite32be(vme_offset_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTOFL);
-/* XXX We need to deal with OTBS */
-#if 0
- iowrite32be(vmeOut->bcastSelect2esst, tsi148_bridge->base +
- TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTBS);
-#endif
-
/* Write ctl reg without enable */
- iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTAT);
if (enabled)
temp_ctl |= TSI148_LCSR_OTAT_EN;
- iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTAT);
spin_unlock(&(image->lock));
@@ -1183,23 +1147,26 @@ int __tsi148_master_get( struct vme_master_resource *image, int *enabled,
unsigned int vme_offset_low, vme_offset_high;
unsigned long long pci_base, pci_bound, vme_offset;
+ struct tsi148_driver *bridge;
+
+ bridge = image->parent->driver_priv;
i = image->number;
- ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTAT);
- pci_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTSAU);
- pci_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTSAL);
- pci_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTEAU);
- pci_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTEAL);
- vme_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTOFU);
- vme_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTOFL);
/* Convert 64-bit variables to 2x 32-bit variables */
@@ -1305,6 +1272,9 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
vme_cycle_t cycle;
vme_width_t dwidth;
struct vme_bus_error *vme_err = NULL;
+ struct vme_bridge *tsi148_bridge;
+
+ tsi148_bridge = image->parent;
spin_lock(&(image->lock));
@@ -1317,13 +1287,15 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
__tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
&dwidth);
- vme_err = tsi148_find_error(aspace, vme_base + offset, count);
+ vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
+ count);
if(vme_err != NULL) {
dev_err(image->parent->parent, "First VME read error detected "
"an at address 0x%llx\n", vme_err->address);
retval = vme_err->address - (vme_base + offset);
/* Clear down save errors in this address range */
- tsi148_clear_errors(aspace, vme_base + offset, count);
+ tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
+ count);
}
skip_chk:
@@ -1333,9 +1305,6 @@ skip_chk:
}
-/* XXX We need to change vme_master_resource->mtx to a spinlock so that read
- * and write functions can be used in an interrupt context
- */
ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
size_t count, loff_t offset)
{
@@ -1346,6 +1315,12 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
vme_width_t dwidth;
struct vme_bus_error *vme_err = NULL;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+
+ tsi148_bridge = image->parent;
+
+ bridge = tsi148_bridge->driver_priv;
spin_lock(&(image->lock));
@@ -1373,15 +1348,17 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
__tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
&dwidth);
- ioread16(flush_image->kern_base + 0x7F000);
+ ioread16(bridge->flush_image->kern_base + 0x7F000);
- vme_err = tsi148_find_error(aspace, vme_base + offset, count);
+ vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
+ count);
if(vme_err != NULL) {
printk("First VME write error detected an at address 0x%llx\n",
vme_err->address);
retval = vme_err->address - (vme_base + offset);
/* Clear down save errors in this address range */
- tsi148_clear_errors(aspace, vme_base + offset, count);
+ tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
+ count);
}
skip_chk:
@@ -1403,48 +1380,50 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image,
unsigned int pci_addr_high, pci_addr_low;
u32 tmp, result;
int i;
+ struct tsi148_driver *bridge;
+ bridge = image->parent->driver_priv;
/* Find the PCI address that maps to the desired VME address */
i = image->number;
/* Locking as we can only do one of these at a time */
- mutex_lock(&(vme_rmw));
+ mutex_lock(&(bridge->vme_rmw));
/* Lock image */
spin_lock(&(image->lock));
- pci_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTSAU);
- pci_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTSAL);
reg_join(pci_addr_high, pci_addr_low, &pci_addr);
reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low);
/* Configure registers */
- iowrite32be(mask, tsi148_bridge->base + TSI148_LCSR_RMWEN);
- iowrite32be(compare, tsi148_bridge->base + TSI148_LCSR_RMWC);
- iowrite32be(swap, tsi148_bridge->base + TSI148_LCSR_RMWS);
- iowrite32be(pci_addr_high, tsi148_bridge->base + TSI148_LCSR_RMWAU);
- iowrite32be(pci_addr_low, tsi148_bridge->base + TSI148_LCSR_RMWAL);
+ iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN);
+ iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC);
+ iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS);
+ iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU);
+ iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL);
/* Enable RMW */
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
tmp |= TSI148_LCSR_VMCTRL_RMWEN;
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
/* Kick process off with a read to the required address. */
result = ioread32be(image->kern_base + offset);
/* Disable RMW */
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
tmp &= ~TSI148_LCSR_VMCTRL_RMWEN;
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
spin_unlock(&(image->lock));
- mutex_unlock(&(vme_rmw));
+ mutex_unlock(&(bridge->vme_rmw));
return result;
}
@@ -1637,8 +1616,6 @@ static int tsi148_dma_set_vme_dest_attributes(u32 *attr, vme_address_t aspace,
/*
* Add a link list descriptor to the list
- *
- * XXX Need to handle 2eSST Broadcast select bits
*/
int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src,
struct vme_dma_attr *dest, size_t count)
@@ -1651,7 +1628,7 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src,
dma_addr_t desc_ptr;
int retval = 0;
- /* XXX descriptor must be aligned on 64-bit boundaries */
+ /* Descriptor must be aligned on 64-bit boundaries */
entry = (struct tsi148_dma_entry *)kmalloc(
sizeof(struct tsi148_dma_entry), GFP_KERNEL);
if (entry == NULL) {
@@ -1788,11 +1765,14 @@ err_mem:
/*
* Check to see if the provided DMA channel is busy.
*/
-static int tsi148_dma_busy(int channel)
+static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel)
{
u32 tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
+ tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
TSI148_LCSR_OFFSET_DSTA);
if (tmp & TSI148_LCSR_DSTA_BSY)
@@ -1815,12 +1795,12 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
dma_addr_t bus_addr;
u32 bus_addr_high, bus_addr_low;
u32 val, dctlreg = 0;
-#if 0
- int x;
-#endif
+ struct tsi148_driver *bridge;
ctrlr = list->parent;
+ bridge = ctrlr->parent->driver_priv;
+
mutex_lock(&(ctrlr->mtx));
channel = ctrlr->number;
@@ -1837,48 +1817,6 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
} else {
list_add(&(list->list), &(ctrlr->running));
}
-#if 0
- /* XXX Still todo */
- for (x = 0; x < 8; x++) { /* vme block size */
- if ((32 << x) >= vmeDma->maxVmeBlockSize) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dctlreg |= (x << 12);
-
- for (x = 0; x < 8; x++) { /* pci block size */
- if ((32 << x) >= vmeDma->maxPciBlockSize) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dctlreg |= (x << 4);
-
- if (vmeDma->vmeBackOffTimer) {
- for (x = 1; x < 8; x++) { /* vme timer */
- if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dctlreg |= (x << 8);
- }
-
- if (vmeDma->pciBackOffTimer) {
- for (x = 1; x < 8; x++) { /* pci timer */
- if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dctlreg |= (x << 0);
- }
-#endif
/* Get first bus address and write into registers */
entry = list_first_entry(&(list->entries), struct tsi148_dma_entry,
@@ -1890,21 +1828,22 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
reg_split(bus_addr, &bus_addr_high, &bus_addr_low);
- iowrite32be(bus_addr_high, tsi148_bridge->base +
+ iowrite32be(bus_addr_high, bridge->base +
TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU);
- iowrite32be(bus_addr_low, tsi148_bridge->base +
+ iowrite32be(bus_addr_low, bridge->base +
TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL);
/* Start the operation */
- iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, tsi148_bridge->base +
+ iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
- wait_event_interruptible(dma_queue[channel], tsi148_dma_busy(channel));
+ wait_event_interruptible(bridge->dma_queue[channel],
+ tsi148_dma_busy(ctrlr->parent, channel));
/*
* Read status register, this register is valid until we kick off a
* new transfer.
*/
- val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
+ val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
TSI148_LCSR_OFFSET_DSTA);
if (val & TSI148_LCSR_DSTA_VBE) {
@@ -1952,12 +1891,15 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
{
u32 lm_base_high, lm_base_low, lm_ctl = 0;
int i;
+ struct tsi148_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
mutex_lock(&(lm->mtx));
/* If we already have a callback attached, we can't move it! */
for (i = 0; i < lm->monitors; i++) {
- if(lm_callback[i] != NULL) {
+ if (bridge->lm_callback[i] != NULL) {
mutex_unlock(&(lm->mtx));
printk("Location monitor callback attached, can't "
"reset\n");
@@ -1996,9 +1938,9 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
reg_split(lm_base, &lm_base_high, &lm_base_low);
- iowrite32be(lm_base_high, tsi148_bridge->base + TSI148_LCSR_LMBAU);
- iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL);
- iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT);
+ iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU);
+ iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL);
+ iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
mutex_unlock(&(lm->mtx));
@@ -2012,12 +1954,15 @@ int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base,
vme_address_t *aspace, vme_cycle_t *cycle)
{
u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
+ struct tsi148_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
mutex_lock(&(lm->mtx));
- lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU);
- lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL);
- lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+ lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU);
+ lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL);
+ lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
reg_join(lm_base_high, lm_base_low, lm_base);
@@ -2060,11 +2005,14 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
void (*callback)(int))
{
u32 lm_ctl, tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
mutex_lock(&(lm->mtx));
/* Ensure that the location monitor is configured - need PGM or DATA */
- lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+ lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) {
mutex_unlock(&(lm->mtx));
printk("Location monitor not properly configured\n");
@@ -2072,28 +2020,28 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
}
/* Check that a callback isn't already attached */
- if (lm_callback[monitor] != NULL) {
+ if (bridge->lm_callback[monitor] != NULL) {
mutex_unlock(&(lm->mtx));
printk("Existing callback attached\n");
return -EBUSY;
}
/* Attach callback */
- lm_callback[monitor] = callback;
+ bridge->lm_callback[monitor] = callback;
/* Enable Location Monitor interrupt */
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
tmp |= TSI148_LCSR_INTEN_LMEN[monitor];
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
tmp |= TSI148_LCSR_INTEO_LMEO[monitor];
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
/* Ensure that global Location Monitor Enable set */
if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) {
lm_ctl |= TSI148_LCSR_LMAT_EN;
- iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT);
+ iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
}
mutex_unlock(&(lm->mtx));
@@ -2107,30 +2055,33 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
{
u32 lm_en, tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
mutex_lock(&(lm->mtx));
/* Disable Location Monitor and ensure previous interrupts are clear */
- lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+ lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN);
lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor];
- iowrite32be(lm_en, tsi148_bridge->base + TSI148_LCSR_INTEN);
+ iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN);
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor];
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
iowrite32be(TSI148_LCSR_INTC_LMC[monitor],
- tsi148_bridge->base + TSI148_LCSR_INTC);
+ bridge->base + TSI148_LCSR_INTC);
/* Detach callback */
- lm_callback[monitor] = NULL;
+ bridge->lm_callback[monitor] = NULL;
/* If all location monitors disabled, disable global Location Monitor */
if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S |
TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) {
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+ tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT);
tmp &= ~TSI148_LCSR_LMAT_EN;
- iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT);
}
mutex_unlock(&(lm->mtx));
@@ -2141,12 +2092,19 @@ int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
/*
* Determine Geographical Addressing
*/
-int tsi148_slot_get(void)
+int tsi148_slot_get(struct vme_bridge *tsi148_bridge)
{
u32 slot = 0;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ if (!geoid) {
+ slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT);
+ slot = slot & TSI148_LCSR_VSTAT_GA_M;
+ } else
+ slot = geoid;
- slot = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
- slot = slot & TSI148_LCSR_VSTAT_GA_M;
return (int)slot;
}
@@ -2167,45 +2125,50 @@ static int __init tsi148_init(void)
* boards registers, this means there is a fix length 508kB window which must
* be mapped onto PCI memory.
*/
-static int tsi148_crcsr_init(struct pci_dev *pdev)
+static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge,
+ struct pci_dev *pdev)
{
u32 cbar, crat, vstat;
u32 crcsr_bus_high, crcsr_bus_low;
int retval;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
/* Allocate mem for CR/CSR image */
- crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
- &crcsr_bus);
- if (crcsr_kernel == NULL) {
+ bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
+ &(bridge->crcsr_bus));
+ if (bridge->crcsr_kernel == NULL) {
dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR "
"image\n");
return -ENOMEM;
}
- memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
+ memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
- reg_split(crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
+ reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
- iowrite32be(crcsr_bus_high, tsi148_bridge->base + TSI148_LCSR_CROU);
- iowrite32be(crcsr_bus_low, tsi148_bridge->base + TSI148_LCSR_CROL);
+ iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU);
+ iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL);
/* Ensure that the CR/CSR is configured at the correct offset */
- cbar = ioread32be(tsi148_bridge->base + TSI148_CBAR);
+ cbar = ioread32be(bridge->base + TSI148_CBAR);
cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3;
- vstat = tsi148_slot_get();
+ vstat = tsi148_slot_get(tsi148_bridge);
if (cbar != vstat) {
+ cbar = vstat;
dev_info(&pdev->dev, "Setting CR/CSR offset\n");
- iowrite32be(cbar<<3, tsi148_bridge->base + TSI148_CBAR);
+ iowrite32be(cbar<<3, bridge->base + TSI148_CBAR);
}
dev_info(&pdev->dev, "CR/CSR Offset: %d\n", cbar);
- crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT);
+ crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
if (crat & TSI148_LCSR_CRAT_EN) {
dev_info(&pdev->dev, "Enabling CR/CSR space\n");
iowrite32be(crat | TSI148_LCSR_CRAT_EN,
- tsi148_bridge->base + TSI148_LCSR_CRAT);
+ bridge->base + TSI148_LCSR_CRAT);
} else
dev_info(&pdev->dev, "CR/CSR already enabled\n");
@@ -2214,8 +2177,9 @@ static int tsi148_crcsr_init(struct pci_dev *pdev)
* through VME writes.
*/
if(err_chk) {
- retval = tsi148_master_set(flush_image, 1, (vstat * 0x80000),
- 0x80000, VME_CRCSR, VME_SCT, VME_D16);
+ retval = tsi148_master_set(bridge->flush_image, 1,
+ (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT,
+ VME_D16);
if (retval)
dev_err(&pdev->dev, "Configuring flush image failed\n");
}
@@ -2224,20 +2188,25 @@ static int tsi148_crcsr_init(struct pci_dev *pdev)
}
-static void tsi148_crcsr_exit(struct pci_dev *pdev)
+static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge,
+ struct pci_dev *pdev)
{
u32 crat;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
/* Turn off CR/CSR space */
- crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT);
+ crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
iowrite32be(crat & ~TSI148_LCSR_CRAT_EN,
- tsi148_bridge->base + TSI148_LCSR_CRAT);
+ bridge->base + TSI148_LCSR_CRAT);
/* Free image */
- iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROU);
- iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROL);
+ iowrite32be(0, bridge->base + TSI148_LCSR_CROU);
+ iowrite32be(0, bridge->base + TSI148_LCSR_CROL);
- pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus);
+ pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel,
+ bridge->crcsr_bus);
}
static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -2245,6 +2214,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
int retval, i, master_num;
u32 data;
struct list_head *pos = NULL;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *tsi148_device;
struct vme_master_resource *master_image;
struct vme_slave_resource *slave_image;
struct vme_dma_resource *dma_ctrlr;
@@ -2264,6 +2235,18 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
memset(tsi148_bridge, 0, sizeof(struct vme_bridge));
+ tsi148_device = kmalloc(sizeof(struct tsi148_driver), GFP_KERNEL);
+ if (tsi148_device == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate memory for device "
+ "structure\n");
+ retval = -ENOMEM;
+ goto err_driver;
+ }
+
+ memset(tsi148_device, 0, sizeof(struct tsi148_driver));
+
+ tsi148_bridge->driver_priv = tsi148_device;
+
/* Enable the device */
retval = pci_enable_device(pdev);
if (retval) {
@@ -2279,15 +2262,16 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* map registers in BAR 0 */
- tsi148_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), 4096);
- if (!tsi148_bridge->base) {
+ tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0),
+ 4096);
+ if (!tsi148_device->base) {
dev_err(&pdev->dev, "Unable to remap CRG region\n");
retval = -EIO;
goto err_remap;
}
/* Check to see if the mapping worked out */
- data = ioread32(tsi148_bridge->base + TSI148_PCFS_ID) & 0x0000FFFF;
+ data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF;
if (data != PCI_VENDOR_ID_TUNDRA) {
dev_err(&pdev->dev, "CRG region check failed\n");
retval = -EIO;
@@ -2295,12 +2279,11 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* Initialize wait queues & mutual exclusion flags */
- /* XXX These need to be moved to the vme_bridge structure */
- init_waitqueue_head(&dma_queue[0]);
- init_waitqueue_head(&dma_queue[1]);
- init_waitqueue_head(&iack_queue);
- mutex_init(&(vme_int));
- mutex_init(&(vme_rmw));
+ init_waitqueue_head(&(tsi148_device->dma_queue[0]));
+ init_waitqueue_head(&(tsi148_device->dma_queue[1]));
+ init_waitqueue_head(&(tsi148_device->iack_queue));
+ mutex_init(&(tsi148_device->vme_int));
+ mutex_init(&(tsi148_device->vme_rmw));
tsi148_bridge->parent = &(pdev->dev);
strcpy(tsi148_bridge->name, driver_name);
@@ -2320,29 +2303,29 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
master_num = TSI148_MAX_MASTER;
if(err_chk){
master_num--;
- /* XXX */
- flush_image = (struct vme_master_resource *)kmalloc(
- sizeof(struct vme_master_resource), GFP_KERNEL);
- if (flush_image == NULL) {
+
+ tsi148_device->flush_image = (struct vme_master_resource *)
+ kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL);
+ if (tsi148_device->flush_image == NULL) {
dev_err(&pdev->dev, "Failed to allocate memory for "
"flush resource structure\n");
retval = -ENOMEM;
goto err_master;
}
- flush_image->parent = tsi148_bridge;
- spin_lock_init(&(flush_image->lock));
- flush_image->locked = 1;
- flush_image->number = master_num;
- flush_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
- VME_A64;
- flush_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
- VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
- VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
- VME_PROG | VME_DATA;
- flush_image->width_attr = VME_D16 | VME_D32;
- memset(&(flush_image->pci_resource), 0,
+ tsi148_device->flush_image->parent = tsi148_bridge;
+ spin_lock_init(&(tsi148_device->flush_image->lock));
+ tsi148_device->flush_image->locked = 1;
+ tsi148_device->flush_image->number = master_num;
+ tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 |
+ VME_A32 | VME_A64;
+ tsi148_device->flush_image->cycle_attr = VME_SCT | VME_BLT |
+ VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB |
+ VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER |
+ VME_USER | VME_PROG | VME_DATA;
+ tsi148_device->flush_image->width_attr = VME_D16 | VME_D32;
+ memset(&(tsi148_device->flush_image->bus_resource), 0,
sizeof(struct resource));
- flush_image->kern_base = NULL;
+ tsi148_device->flush_image->kern_base = NULL;
}
/* Add master windows to list */
@@ -2367,7 +2350,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
VME_PROG | VME_DATA;
master_image->width_attr = VME_D16 | VME_D32;
- memset(&(master_image->pci_resource), 0,
+ memset(&(master_image->bus_resource), 0,
sizeof(struct resource));
master_image->kern_base = NULL;
list_add_tail(&(master_image->list),
@@ -2415,6 +2398,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mutex_init(&(dma_ctrlr->mtx));
dma_ctrlr->locked = 0;
dma_ctrlr->number = i;
+ dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
+ VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME |
+ VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME |
+ VME_DMA_PATTERN_TO_MEM;
INIT_LIST_HEAD(&(dma_ctrlr->pending));
INIT_LIST_HEAD(&(dma_ctrlr->running));
list_add_tail(&(dma_ctrlr->list),
@@ -2455,40 +2442,43 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
tsi148_bridge->lm_detach = tsi148_lm_detach;
tsi148_bridge->slot_get = tsi148_slot_get;
- data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
+ data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
dev_info(&pdev->dev, "Board is%s the VME system controller\n",
(data & TSI148_LCSR_VSTAT_SCONS)? "" : " not");
- dev_info(&pdev->dev, "VME geographical address is %d\n",
- data & TSI148_LCSR_VSTAT_GA_M);
+ if (!geoid)
+ dev_info(&pdev->dev, "VME geographical address is %d\n",
+ data & TSI148_LCSR_VSTAT_GA_M);
+ else
+ dev_info(&pdev->dev, "VME geographical address is set to %d\n",
+ geoid);
+
dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
err_chk ? "enabled" : "disabled");
- if(tsi148_crcsr_init(pdev)) {
+ if (tsi148_crcsr_init(tsi148_bridge, pdev)) {
dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
goto err_crcsr;
-
}
- /* Need to save tsi148_bridge pointer locally in link list for use in
- * tsi148_remove()
- */
retval = vme_register_bridge(tsi148_bridge);
if (retval != 0) {
dev_err(&pdev->dev, "Chip Registration failed.\n");
goto err_reg;
}
+ pci_set_drvdata(pdev, tsi148_bridge);
+
/* Clear VME bus "board fail", and "power-up reset" lines */
- data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
+ data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
data &= ~TSI148_LCSR_VSTAT_BRDFL;
data |= TSI148_LCSR_VSTAT_CPURST;
- iowrite32be(data, tsi148_bridge->base + TSI148_LCSR_VSTAT);
+ iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT);
return 0;
vme_unregister_bridge(tsi148_bridge);
err_reg:
- tsi148_crcsr_exit(pdev);
+ tsi148_crcsr_exit(tsi148_bridge, pdev);
err_crcsr:
err_lm:
/* resources are stored in link list */
@@ -2519,15 +2509,17 @@ err_master:
kfree(master_image);
}
- tsi148_irq_exit(pdev);
+ tsi148_irq_exit(tsi148_device, pdev);
err_irq:
err_test:
- iounmap(tsi148_bridge->base);
+ iounmap(tsi148_device->base);
err_remap:
pci_release_regions(pdev);
err_resource:
pci_disable_device(pdev);
err_enable:
+ kfree(tsi148_device);
+err_driver:
kfree(tsi148_bridge);
err_struct:
return retval;
@@ -2541,56 +2533,58 @@ static void tsi148_remove(struct pci_dev *pdev)
struct vme_slave_resource *slave_image;
struct vme_dma_resource *dma_ctrlr;
int i;
+ struct tsi148_driver *bridge;
+ struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev);
- dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
+ bridge = tsi148_bridge->driver_priv;
- /* XXX We need to find the pdev->dev in the list of vme_bridge->dev's */
+
+ dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
/*
* Shutdown all inbound and outbound windows.
*/
for (i = 0; i < 8; i++) {
- iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+ iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] +
TSI148_LCSR_OFFSET_ITAT);
- iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+ iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] +
TSI148_LCSR_OFFSET_OTAT);
}
/*
* Shutdown Location monitor.
*/
- iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_LMAT);
+ iowrite32be(0, bridge->base + TSI148_LCSR_LMAT);
/*
* Shutdown CRG map.
*/
- iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CSRAT);
+ iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT);
/*
* Clear error status.
*/
- iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_EDPAT);
- iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_VEAT);
- iowrite32be(0x07000700, tsi148_bridge->base + TSI148_LCSR_PSTAT);
+ iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT);
+ iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT);
+ iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT);
/*
* Remove VIRQ interrupt (if any)
*/
- if (ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR) & 0x800) {
- iowrite32be(0x8000, tsi148_bridge->base + TSI148_LCSR_VICR);
- }
+ if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800)
+ iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR);
/*
* Map all Interrupts to PCI INTA
*/
- iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM1);
- iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM2);
+ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1);
+ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2);
- tsi148_irq_exit(pdev);
+ tsi148_irq_exit(bridge, pdev);
vme_unregister_bridge(tsi148_bridge);
- tsi148_crcsr_exit(pdev);
+ tsi148_crcsr_exit(tsi148_bridge, pdev);
/* resources are stored in link list */
list_for_each(pos, &(tsi148_bridge->dma_resources)) {
@@ -2608,19 +2602,22 @@ static void tsi148_remove(struct pci_dev *pdev)
/* resources are stored in link list */
list_for_each(pos, &(tsi148_bridge->master_resources)) {
- master_image = list_entry(pos, struct vme_master_resource, list);
+ master_image = list_entry(pos, struct vme_master_resource,
+ list);
list_del(pos);
kfree(master_image);
}
- tsi148_irq_exit(pdev);
+ tsi148_irq_exit(bridge, pdev);
- iounmap(tsi148_bridge->base);
+ iounmap(bridge->base);
pci_release_regions(pdev);
pci_disable_device(pdev);
+ kfree(tsi148_bridge->driver_priv);
+
kfree(tsi148_bridge);
}
@@ -2634,250 +2631,11 @@ static void __exit tsi148_exit(void)
MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes");
module_param(err_chk, bool, 0);
+MODULE_PARM_DESC(geoid, "Override geographical addressing");
+module_param(geoid, int, 0);
+
MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge");
MODULE_LICENSE("GPL");
module_init(tsi148_init);
module_exit(tsi148_exit);
-
-/*----------------------------------------------------------------------------
- * STAGING
- *--------------------------------------------------------------------------*/
-
-#if 0
-/*
- * Direct Mode DMA transfer
- *
- * XXX Not looking at direct mode for now, we can always use link list mode
- * with a single entry.
- */
-int tsi148_dma_run(struct vme_dma_resource *resource, struct vme_dma_attr src,
- struct vme_dma_attr dest, size_t count)
-{
- u32 dctlreg = 0;
- unsigned int tmp;
- int val;
- int channel, x;
- struct vmeDmaPacket *cur_dma;
- struct tsi148_dma_descriptor *dmaLL;
-
- /* direct mode */
- dctlreg = 0x800000;
-
- for (x = 0; x < 8; x++) { /* vme block size */
- if ((32 << x) >= vmeDma->maxVmeBlockSize) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dctlreg |= (x << 12);
-
- for (x = 0; x < 8; x++) { /* pci block size */
- if ((32 << x) >= vmeDma->maxPciBlockSize) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dctlreg |= (x << 4);
-
- if (vmeDma->vmeBackOffTimer) {
- for (x = 1; x < 8; x++) { /* vme timer */
- if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dctlreg |= (x << 8);
- }
-
- if (vmeDma->pciBackOffTimer) {
- for (x = 1; x < 8; x++) { /* pci timer */
- if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) {
- break;
- }
- }
- if (x == 8)
- x = 7;
- dctlreg |= (x << 0);
- }
-
- /* Program registers for DMA transfer */
- iowrite32be(dmaLL->dsau, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAU);
- iowrite32be(dmaLL->dsal, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAL);
- iowrite32be(dmaLL->ddau, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAU);
- iowrite32be(dmaLL->ddal, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAL);
- iowrite32be(dmaLL->dsat, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAT);
- iowrite32be(dmaLL->ddat, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAT);
- iowrite32be(dmaLL->dcnt, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCNT);
- iowrite32be(dmaLL->ddbs, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDBS);
-
- /* Start the operation */
- iowrite32be(dctlreg | 0x2000000, tsi148_bridge->base +
- TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
-
- tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
- TSI148_LCSR_OFFSET_DSTA);
- wait_event_interruptible(dma_queue[channel], (tmp & 0x1000000) == 0);
-
- /*
- * Read status register, we should probably do this in some error
- * handler rather than here so that we can be sure we haven't kicked off
- * another DMA transfer.
- */
- val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
- TSI148_LCSR_OFFSET_DSTA);
-
- vmeDma->vmeDmaStatus = 0;
- if (val & 0x10000000) {
- printk(KERN_ERR
- "DMA Error in DMA_tempe_irqhandler DSTA=%08X\n",
- val);
- vmeDma->vmeDmaStatus = val;
-
- }
- return (0);
-}
-#endif
-
-#if 0
-
-/* Global VME controller information */
-struct pci_dev *vme_pci_dev;
-
-/*
- * Set the VME bus arbiter with the requested attributes
- */
-int tempe_set_arbiter(vmeArbiterCfg_t * vmeArb)
-{
- int temp_ctl = 0;
- int gto = 0;
-
- temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL);
- temp_ctl &= 0xFFEFFF00;
-
- if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
- gto = 8;
- } else if (vmeArb->globalTimeoutTimer > 2048) {
- return (-EINVAL);
- } else if (vmeArb->globalTimeoutTimer == 0) {
- gto = 0;
- } else {
- gto = 1;
- while ((16 * (1 << (gto - 1))) < vmeArb->globalTimeoutTimer) {
- gto += 1;
- }
- }
- temp_ctl |= gto;
-
- if (vmeArb->arbiterMode != VME_PRIORITY_MODE) {
- temp_ctl |= 1 << 6;
- }
-
- if (vmeArb->arbiterTimeoutFlag) {
- temp_ctl |= 1 << 7;
- }
-
- if (vmeArb->noEarlyReleaseFlag) {
- temp_ctl |= 1 << 20;
- }
- iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VCTRL);
-
- return (0);
-}
-
-/*
- * Return the attributes of the VME bus arbiter.
- */
-int tempe_get_arbiter(vmeArbiterCfg_t * vmeArb)
-{
- int temp_ctl = 0;
- int gto = 0;
-
-
- temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL);
-
- gto = temp_ctl & 0xF;
- if (gto != 0) {
- vmeArb->globalTimeoutTimer = (16 * (1 << (gto - 1)));
- }
-
- if (temp_ctl & (1 << 6)) {
- vmeArb->arbiterMode = VME_R_ROBIN_MODE;
- } else {
- vmeArb->arbiterMode = VME_PRIORITY_MODE;
- }
-
- if (temp_ctl & (1 << 7)) {
- vmeArb->arbiterTimeoutFlag = 1;
- }
-
- if (temp_ctl & (1 << 20)) {
- vmeArb->noEarlyReleaseFlag = 1;
- }
-
- return (0);
-}
-
-/*
- * Set the VME bus requestor with the requested attributes
- */
-int tempe_set_requestor(vmeRequesterCfg_t * vmeReq)
-{
- int temp_ctl = 0;
-
- temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
- temp_ctl &= 0xFFFF0000;
-
- if (vmeReq->releaseMode == 1) {
- temp_ctl |= (1 << 3);
- }
-
- if (vmeReq->fairMode == 1) {
- temp_ctl |= (1 << 2);
- }
-
- temp_ctl |= (vmeReq->timeonTimeoutTimer & 7) << 8;
- temp_ctl |= (vmeReq->timeoffTimeoutTimer & 7) << 12;
- temp_ctl |= vmeReq->requestLevel;
-
- iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
- return (0);
-}
-
-/*
- * Return the attributes of the VME bus requestor
- */
-int tempe_get_requestor(vmeRequesterCfg_t * vmeReq)
-{
- int temp_ctl = 0;
-
- temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
-
- if (temp_ctl & 0x18) {
- vmeReq->releaseMode = 1;
- }
-
- if (temp_ctl & (1 << 2)) {
- vmeReq->fairMode = 1;
- }
-
- vmeReq->requestLevel = temp_ctl & 3;
- vmeReq->timeonTimeoutTimer = (temp_ctl >> 8) & 7;
- vmeReq->timeoffTimeoutTimer = (temp_ctl >> 12) & 7;
-
- return (0);
-}
-
-
-#endif
diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h
index 6f0f705ce6b..9e5f7fa1d74 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.h
+++ b/drivers/staging/vme/bridges/vme_tsi148.h
@@ -33,6 +33,22 @@
#define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */
#define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */
+/* Structure used to hold driver specific information */
+struct tsi148_driver {
+ void *base; /* Base Address of device registers */
+ wait_queue_head_t dma_queue[2];
+ wait_queue_head_t iack_queue;
+ void (*lm_callback[4])(int); /* Called in interrupt handler */
+ void *crcsr_kernel;
+ dma_addr_t crcsr_bus;
+ struct vme_master_resource *flush_image;
+ struct mutex vme_rmw; /* Only one RMW cycle at a time */
+ struct mutex vme_int; /*
+ * Only one VME interrupt can be
+ * generated at a time, provide locking
+ */
+};
+
/*
* Layout of a DMAC Linked-List Descriptor
*
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index e228942ee08..1ab9a985dfb 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -1,8 +1,8 @@
/*
* VMEbus User access driver
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
*
* Based on work by:
* Tom Armistead and Ajit Prem
@@ -28,6 +28,7 @@
#include <linux/pagemap.h>
#include <linux/pci.h>
#include <linux/semaphore.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/types.h>
@@ -400,8 +401,39 @@ static ssize_t vme_user_write(struct file *file, const char *buf, size_t count,
static loff_t vme_user_llseek(struct file *file, loff_t off, int whence)
{
- printk(KERN_ERR "Llseek currently incomplete\n");
- return -EINVAL;
+ loff_t absolute = -1;
+ unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ size_t image_size;
+
+ down(&image[minor].sem);
+ image_size = vme_get_size(image[minor].resource);
+
+ switch (whence) {
+ case SEEK_SET:
+ absolute = off;
+ break;
+ case SEEK_CUR:
+ absolute = file->f_pos + off;
+ break;
+ case SEEK_END:
+ absolute = image_size + off;
+ break;
+ default:
+ up(&image[minor].sem);
+ return -EINVAL;
+ break;
+ }
+
+ if ((absolute < 0) || (absolute >= image_size)) {
+ up(&image[minor].sem);
+ return -EINVAL;
+ }
+
+ file->f_pos = absolute;
+
+ up(&image[minor].sem);
+
+ return absolute;
}
/*
@@ -574,8 +606,8 @@ static int __init vme_user_init(void)
* in future revisions if that ever becomes necessary.
*/
if (bus_num > USER_BUS_MAX) {
- printk(KERN_ERR "%s: Driver only able to handle %d PIO2 "
- "Cards\n", driver_name, USER_BUS_MAX);
+ printk(KERN_ERR "%s: Driver only able to handle %d buses\n",
+ driver_name, USER_BUS_MAX);
bus_num = USER_BUS_MAX;
}
@@ -670,8 +702,12 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
/* Request slave resources and allocate buffers (128kB wide) */
for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
/* XXX Need to properly request attributes */
+ /* For ca91cx42 bridge there are only two slave windows
+ * supporting A16 addressing, so we request A24 supported
+ * by all windows.
+ */
image[i].resource = vme_slave_request(vme_user_bridge,
- VME_A16, VME_SCT);
+ VME_A24, VME_SCT);
if (image[i].resource == NULL) {
printk(KERN_WARNING "Unable to allocate slave "
"resource\n");
@@ -703,6 +739,14 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
"resource\n");
goto err_master;
}
+ image[i].size_buf = PCI_BUF_SIZE;
+ image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL);
+ if (image[i].kern_buf == NULL) {
+ printk(KERN_WARNING "Unable to allocate memory for "
+ "master window buffers\n");
+ err = -ENOMEM;
+ goto err_master_buf;
+ }
}
/* Create sysfs entries - on udev systems this creates the dev files */
@@ -756,6 +800,9 @@ err_sysfs:
/* Ensure counter set correcty to unalloc all master windows */
i = MASTER_MAX + 1;
+err_master_buf:
+ for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
+ kfree(image[i].kern_buf);
err_master:
while (i > MASTER_MINOR) {
i--;
@@ -791,6 +838,9 @@ static int __exit vme_user_remove(struct device *dev, int cur_bus, int cur_slot)
}
class_destroy(vme_user_sysfs_class);
+ for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
+ kfree(image[i].kern_buf);
+
for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
vme_slave_set(image[i].resource, 0, 0, 0, 0, VME_A32, 0);
vme_slave_free(image[i].resource);
@@ -818,7 +868,7 @@ MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the driver is connected");
module_param_array(bus, int, &bus_num, 0);
MODULE_DESCRIPTION("VME User Space Access Driver");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
MODULE_LICENSE("GPL");
module_init(vme_user_init);
diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c
index 994fdb9b212..934283a19ca 100644
--- a/drivers/staging/vme/vme.c
+++ b/drivers/staging/vme/vme.c
@@ -1,8 +1,8 @@
/*
* VME Bridge Framework
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
*
* Based on work by Tom Armistead and Ajit Prem
* Copyright 2004 Motorola Inc.
@@ -29,6 +29,7 @@
#include <linux/syscalls.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include "vme.h"
#include "vme_bridge.h"
@@ -37,8 +38,8 @@
static unsigned int vme_bus_numbers;
DEFINE_MUTEX(vme_bus_num_mtx);
-static void __exit vme_exit (void);
-static int __init vme_init (void);
+static void __exit vme_exit(void);
+static int __init vme_init(void);
/*
@@ -86,26 +87,26 @@ static struct vme_bridge *find_bridge(struct vme_resource *resource)
* XXX VME bridges could be available on buses other than PCI. At the momment
* this framework only supports PCI devices.
*/
-void * vme_alloc_consistent(struct vme_resource *resource, size_t size,
+void *vme_alloc_consistent(struct vme_resource *resource, size_t size,
dma_addr_t *dma)
{
struct vme_bridge *bridge;
struct pci_dev *pdev;
- if(resource == NULL) {
- printk("No resource\n");
+ if (resource == NULL) {
+ printk(KERN_ERR "No resource\n");
return NULL;
}
bridge = find_bridge(resource);
- if(bridge == NULL) {
- printk("Can't find bridge\n");
+ if (bridge == NULL) {
+ printk(KERN_ERR "Can't find bridge\n");
return NULL;
}
/* Find pci_dev container of dev */
if (bridge->parent == NULL) {
- printk("Dev entry NULL\n");
+ printk(KERN_ERR "Dev entry NULL\n");
return NULL;
}
pdev = container_of(bridge->parent, struct pci_dev, dev);
@@ -126,14 +127,14 @@ void vme_free_consistent(struct vme_resource *resource, size_t size,
struct vme_bridge *bridge;
struct pci_dev *pdev;
- if(resource == NULL) {
- printk("No resource\n");
+ if (resource == NULL) {
+ printk(KERN_ERR "No resource\n");
return;
}
bridge = find_bridge(resource);
- if(bridge == NULL) {
- printk("Can't find bridge\n");
+ if (bridge == NULL) {
+ printk(KERN_ERR "Can't find bridge\n");
return;
}
@@ -216,7 +217,7 @@ static int vme_check_window(vme_address_t aspace, unsigned long long vme_base,
/* User Defined */
break;
default:
- printk("Invalid address space\n");
+ printk(KERN_ERR "Invalid address space\n");
retval = -EINVAL;
break;
}
@@ -228,7 +229,7 @@ static int vme_check_window(vme_address_t aspace, unsigned long long vme_base,
* Request a slave image with specific attributes, return some unique
* identifier.
*/
-struct vme_resource * vme_slave_request(struct device *dev,
+struct vme_resource *vme_slave_request(struct device *dev,
vme_address_t address, vme_cycle_t cycle)
{
struct vme_bridge *bridge;
@@ -249,13 +250,13 @@ struct vme_resource * vme_slave_request(struct device *dev,
struct vme_slave_resource, list);
if (slave_image == NULL) {
- printk("Registered NULL Slave resource\n");
+ printk(KERN_ERR "Registered NULL Slave resource\n");
continue;
}
/* Find an unlocked and compatible image */
mutex_lock(&(slave_image->mtx));
- if(((slave_image->address_attr & address) == address) &&
+ if (((slave_image->address_attr & address) == address) &&
((slave_image->cycle_attr & cycle) == cycle) &&
(slave_image->locked == 0)) {
@@ -292,7 +293,7 @@ err_bus:
}
EXPORT_SYMBOL(vme_slave_request);
-int vme_slave_set (struct vme_resource *resource, int enabled,
+int vme_slave_set(struct vme_resource *resource, int enabled,
unsigned long long vme_base, unsigned long long size,
dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle)
{
@@ -301,25 +302,25 @@ int vme_slave_set (struct vme_resource *resource, int enabled,
int retval;
if (resource->type != VME_SLAVE) {
- printk("Not a slave resource\n");
+ printk(KERN_ERR "Not a slave resource\n");
return -EINVAL;
}
image = list_entry(resource->entry, struct vme_slave_resource, list);
if (bridge->slave_set == NULL) {
- printk("Function not supported\n");
+ printk(KERN_ERR "Function not supported\n");
return -ENOSYS;
}
- if(!(((image->address_attr & aspace) == aspace) &&
+ if (!(((image->address_attr & aspace) == aspace) &&
((image->cycle_attr & cycle) == cycle))) {
- printk("Invalid attributes\n");
+ printk(KERN_ERR "Invalid attributes\n");
return -EINVAL;
}
retval = vme_check_window(aspace, vme_base, size);
- if(retval)
+ if (retval)
return retval;
return bridge->slave_set(image, enabled, vme_base, size, buf_base,
@@ -327,7 +328,7 @@ int vme_slave_set (struct vme_resource *resource, int enabled,
}
EXPORT_SYMBOL(vme_slave_set);
-int vme_slave_get (struct vme_resource *resource, int *enabled,
+int vme_slave_get(struct vme_resource *resource, int *enabled,
unsigned long long *vme_base, unsigned long long *size,
dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle)
{
@@ -335,14 +336,14 @@ int vme_slave_get (struct vme_resource *resource, int *enabled,
struct vme_slave_resource *image;
if (resource->type != VME_SLAVE) {
- printk("Not a slave resource\n");
+ printk(KERN_ERR "Not a slave resource\n");
return -EINVAL;
}
image = list_entry(resource->entry, struct vme_slave_resource, list);
if (bridge->slave_get == NULL) {
- printk("vme_slave_get not supported\n");
+ printk(KERN_ERR "vme_slave_get not supported\n");
return -EINVAL;
}
@@ -356,14 +357,14 @@ void vme_slave_free(struct vme_resource *resource)
struct vme_slave_resource *slave_image;
if (resource->type != VME_SLAVE) {
- printk("Not a slave resource\n");
+ printk(KERN_ERR "Not a slave resource\n");
return;
}
slave_image = list_entry(resource->entry, struct vme_slave_resource,
list);
if (slave_image == NULL) {
- printk("Can't find slave resource\n");
+ printk(KERN_ERR "Can't find slave resource\n");
return;
}
@@ -384,7 +385,7 @@ EXPORT_SYMBOL(vme_slave_free);
* Request a master image with specific attributes, return some unique
* identifier.
*/
-struct vme_resource * vme_master_request(struct device *dev,
+struct vme_resource *vme_master_request(struct device *dev,
vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth)
{
struct vme_bridge *bridge;
@@ -411,7 +412,7 @@ struct vme_resource * vme_master_request(struct device *dev,
/* Find an unlocked and compatible image */
spin_lock(&(master_image->lock));
- if(((master_image->address_attr & address) == address) &&
+ if (((master_image->address_attr & address) == address) &&
((master_image->cycle_attr & cycle) == cycle) &&
((master_image->width_attr & dwidth) == dwidth) &&
(master_image->locked == 0)) {
@@ -452,7 +453,7 @@ err_bus:
}
EXPORT_SYMBOL(vme_master_request);
-int vme_master_set (struct vme_resource *resource, int enabled,
+int vme_master_set(struct vme_resource *resource, int enabled,
unsigned long long vme_base, unsigned long long size,
vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
{
@@ -461,26 +462,26 @@ int vme_master_set (struct vme_resource *resource, int enabled,
int retval;
if (resource->type != VME_MASTER) {
- printk("Not a master resource\n");
+ printk(KERN_ERR "Not a master resource\n");
return -EINVAL;
}
image = list_entry(resource->entry, struct vme_master_resource, list);
if (bridge->master_set == NULL) {
- printk("vme_master_set not supported\n");
+ printk(KERN_WARNING "vme_master_set not supported\n");
return -EINVAL;
}
- if(!(((image->address_attr & aspace) == aspace) &&
+ if (!(((image->address_attr & aspace) == aspace) &&
((image->cycle_attr & cycle) == cycle) &&
((image->width_attr & dwidth) == dwidth))) {
- printk("Invalid attributes\n");
+ printk(KERN_WARNING "Invalid attributes\n");
return -EINVAL;
}
retval = vme_check_window(aspace, vme_base, size);
- if(retval)
+ if (retval)
return retval;
return bridge->master_set(image, enabled, vme_base, size, aspace,
@@ -488,7 +489,7 @@ int vme_master_set (struct vme_resource *resource, int enabled,
}
EXPORT_SYMBOL(vme_master_set);
-int vme_master_get (struct vme_resource *resource, int *enabled,
+int vme_master_get(struct vme_resource *resource, int *enabled,
unsigned long long *vme_base, unsigned long long *size,
vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
{
@@ -496,14 +497,14 @@ int vme_master_get (struct vme_resource *resource, int *enabled,
struct vme_master_resource *image;
if (resource->type != VME_MASTER) {
- printk("Not a master resource\n");
+ printk(KERN_ERR "Not a master resource\n");
return -EINVAL;
}
image = list_entry(resource->entry, struct vme_master_resource, list);
if (bridge->master_get == NULL) {
- printk("vme_master_set not supported\n");
+ printk(KERN_WARNING "vme_master_set not supported\n");
return -EINVAL;
}
@@ -515,7 +516,7 @@ EXPORT_SYMBOL(vme_master_get);
/*
* Read data out of VME space into a buffer.
*/
-ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
+ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count,
loff_t offset)
{
struct vme_bridge *bridge = find_bridge(resource);
@@ -523,12 +524,12 @@ ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
size_t length;
if (bridge->master_read == NULL) {
- printk("Reading from resource not supported\n");
+ printk(KERN_WARNING "Reading from resource not supported\n");
return -EINVAL;
}
if (resource->type != VME_MASTER) {
- printk("Not a master resource\n");
+ printk(KERN_ERR "Not a master resource\n");
return -EINVAL;
}
@@ -537,7 +538,7 @@ ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
length = vme_get_size(resource);
if (offset > length) {
- printk("Invalid Offset\n");
+ printk(KERN_WARNING "Invalid Offset\n");
return -EFAULT;
}
@@ -552,7 +553,7 @@ EXPORT_SYMBOL(vme_master_read);
/*
* Write data out to VME space from a buffer.
*/
-ssize_t vme_master_write (struct vme_resource *resource, void *buf,
+ssize_t vme_master_write(struct vme_resource *resource, void *buf,
size_t count, loff_t offset)
{
struct vme_bridge *bridge = find_bridge(resource);
@@ -560,12 +561,12 @@ ssize_t vme_master_write (struct vme_resource *resource, void *buf,
size_t length;
if (bridge->master_write == NULL) {
- printk("Writing to resource not supported\n");
+ printk(KERN_WARNING "Writing to resource not supported\n");
return -EINVAL;
}
if (resource->type != VME_MASTER) {
- printk("Not a master resource\n");
+ printk(KERN_ERR "Not a master resource\n");
return -EINVAL;
}
@@ -574,7 +575,7 @@ ssize_t vme_master_write (struct vme_resource *resource, void *buf,
length = vme_get_size(resource);
if (offset > length) {
- printk("Invalid Offset\n");
+ printk(KERN_WARNING "Invalid Offset\n");
return -EFAULT;
}
@@ -588,19 +589,19 @@ EXPORT_SYMBOL(vme_master_write);
/*
* Perform RMW cycle to provided location.
*/
-unsigned int vme_master_rmw (struct vme_resource *resource, unsigned int mask,
+unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
unsigned int compare, unsigned int swap, loff_t offset)
{
struct vme_bridge *bridge = find_bridge(resource);
struct vme_master_resource *image;
if (bridge->master_rmw == NULL) {
- printk("Writing to resource not supported\n");
+ printk(KERN_WARNING "Writing to resource not supported\n");
return -EINVAL;
}
if (resource->type != VME_MASTER) {
- printk("Not a master resource\n");
+ printk(KERN_ERR "Not a master resource\n");
return -EINVAL;
}
@@ -615,14 +616,14 @@ void vme_master_free(struct vme_resource *resource)
struct vme_master_resource *master_image;
if (resource->type != VME_MASTER) {
- printk("Not a master resource\n");
+ printk(KERN_ERR "Not a master resource\n");
return;
}
master_image = list_entry(resource->entry, struct vme_master_resource,
list);
if (master_image == NULL) {
- printk("Can't find master resource\n");
+ printk(KERN_ERR "Can't find master resource\n");
return;
}
@@ -643,7 +644,7 @@ EXPORT_SYMBOL(vme_master_free);
* Request a DMA controller with specific attributes, return some unique
* identifier.
*/
-struct vme_resource *vme_dma_request(struct device *dev)
+struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route)
{
struct vme_bridge *bridge;
struct list_head *dma_pos = NULL;
@@ -666,13 +667,15 @@ struct vme_resource *vme_dma_request(struct device *dev)
struct vme_dma_resource, list);
if (dma_ctrlr == NULL) {
- printk("Registered NULL DMA resource\n");
+ printk(KERN_ERR "Registered NULL DMA resource\n");
continue;
}
- /* Find an unlocked controller */
+ /* Find an unlocked and compatible controller */
mutex_lock(&(dma_ctrlr->mtx));
- if(dma_ctrlr->locked == 0) {
+ if (((dma_ctrlr->route_attr & route) == route) &&
+ (dma_ctrlr->locked == 0)) {
+
dma_ctrlr->locked = 1;
mutex_unlock(&(dma_ctrlr->mtx));
allocated_ctrlr = dma_ctrlr;
@@ -715,16 +718,15 @@ struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
struct vme_dma_list *dma_list;
if (resource->type != VME_DMA) {
- printk("Not a DMA resource\n");
+ printk(KERN_ERR "Not a DMA resource\n");
return NULL;
}
ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
- dma_list = (struct vme_dma_list *)kmalloc(
- sizeof(struct vme_dma_list), GFP_KERNEL);
- if(dma_list == NULL) {
- printk("Unable to allocate memory for new dma list\n");
+ dma_list = kmalloc(sizeof(struct vme_dma_list), GFP_KERNEL);
+ if (dma_list == NULL) {
+ printk(KERN_ERR "Unable to allocate memory for new dma list\n");
return NULL;
}
INIT_LIST_HEAD(&(dma_list->entries));
@@ -744,17 +746,17 @@ struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern,
struct vme_dma_attr *attributes;
struct vme_dma_pattern *pattern_attr;
- attributes = (struct vme_dma_attr *)kmalloc(
- sizeof(struct vme_dma_attr), GFP_KERNEL);
- if(attributes == NULL) {
- printk("Unable to allocate memory for attributes structure\n");
+ attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL);
+ if (attributes == NULL) {
+ printk(KERN_ERR "Unable to allocate memory for attributes "
+ "structure\n");
goto err_attr;
}
- pattern_attr = (struct vme_dma_pattern *)kmalloc(
- sizeof(struct vme_dma_pattern), GFP_KERNEL);
- if(pattern_attr == NULL) {
- printk("Unable to allocate memory for pattern attributes\n");
+ pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL);
+ if (pattern_attr == NULL) {
+ printk(KERN_ERR "Unable to allocate memory for pattern "
+ "attributes\n");
goto err_pat;
}
@@ -784,17 +786,17 @@ struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
/* XXX Run some sanity checks here */
- attributes = (struct vme_dma_attr *)kmalloc(
- sizeof(struct vme_dma_attr), GFP_KERNEL);
- if(attributes == NULL) {
- printk("Unable to allocate memory for attributes structure\n");
+ attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL);
+ if (attributes == NULL) {
+ printk(KERN_ERR "Unable to allocate memory for attributes "
+ "structure\n");
goto err_attr;
}
- pci_attr = (struct vme_dma_pci *)kmalloc(sizeof(struct vme_dma_pci),
- GFP_KERNEL);
- if(pci_attr == NULL) {
- printk("Unable to allocate memory for pci attributes\n");
+ pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL);
+ if (pci_attr == NULL) {
+ printk(KERN_ERR "Unable to allocate memory for pci "
+ "attributes\n");
goto err_pci;
}
@@ -824,19 +826,18 @@ struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
struct vme_dma_attr *attributes;
struct vme_dma_vme *vme_attr;
- /* XXX Run some sanity checks here */
-
- attributes = (struct vme_dma_attr *)kmalloc(
+ attributes = kmalloc(
sizeof(struct vme_dma_attr), GFP_KERNEL);
- if(attributes == NULL) {
- printk("Unable to allocate memory for attributes structure\n");
+ if (attributes == NULL) {
+ printk(KERN_ERR "Unable to allocate memory for attributes "
+ "structure\n");
goto err_attr;
}
- vme_attr = (struct vme_dma_vme *)kmalloc(sizeof(struct vme_dma_vme),
- GFP_KERNEL);
- if(vme_attr == NULL) {
- printk("Unable to allocate memory for vme attributes\n");
+ vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL);
+ if (vme_attr == NULL) {
+ printk(KERN_ERR "Unable to allocate memory for vme "
+ "attributes\n");
goto err_vme;
}
@@ -875,12 +876,12 @@ int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
int retval;
if (bridge->dma_list_add == NULL) {
- printk("Link List DMA generation not supported\n");
+ printk(KERN_WARNING "Link List DMA generation not supported\n");
return -EINVAL;
}
if (!mutex_trylock(&(list->mtx))) {
- printk("Link List already submitted\n");
+ printk(KERN_ERR "Link List already submitted\n");
return -EINVAL;
}
@@ -898,7 +899,7 @@ int vme_dma_list_exec(struct vme_dma_list *list)
int retval;
if (bridge->dma_list_exec == NULL) {
- printk("Link List DMA execution not supported\n");
+ printk(KERN_ERR "Link List DMA execution not supported\n");
return -EINVAL;
}
@@ -918,12 +919,12 @@ int vme_dma_list_free(struct vme_dma_list *list)
int retval;
if (bridge->dma_list_empty == NULL) {
- printk("Emptying of Link Lists not supported\n");
+ printk(KERN_WARNING "Emptying of Link Lists not supported\n");
return -EINVAL;
}
if (!mutex_trylock(&(list->mtx))) {
- printk("Link List in use\n");
+ printk(KERN_ERR "Link List in use\n");
return -EINVAL;
}
@@ -933,7 +934,7 @@ int vme_dma_list_free(struct vme_dma_list *list)
*/
retval = bridge->dma_list_empty(list);
if (retval) {
- printk("Unable to empty link-list entries\n");
+ printk(KERN_ERR "Unable to empty link-list entries\n");
mutex_unlock(&(list->mtx));
return retval;
}
@@ -949,19 +950,19 @@ int vme_dma_free(struct vme_resource *resource)
struct vme_dma_resource *ctrlr;
if (resource->type != VME_DMA) {
- printk("Not a DMA resource\n");
+ printk(KERN_ERR "Not a DMA resource\n");
return -EINVAL;
}
ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
if (!mutex_trylock(&(ctrlr->mtx))) {
- printk("Resource busy, can't free\n");
+ printk(KERN_ERR "Resource busy, can't free\n");
return -EBUSY;
}
if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) {
- printk("Resource still processing transfers\n");
+ printk(KERN_WARNING "Resource still processing transfers\n");
mutex_unlock(&(ctrlr->mtx));
return -EBUSY;
}
@@ -991,7 +992,7 @@ void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
EXPORT_SYMBOL(vme_irq_handler);
int vme_irq_request(struct device *dev, int level, int statid,
- void (*callback)(int level, int vector, void *priv_data),
+ void (*callback)(int, int, void *),
void *priv_data)
{
struct vme_bridge *bridge;
@@ -1002,7 +1003,7 @@ int vme_irq_request(struct device *dev, int level, int statid,
return -EINVAL;
}
- if((level < 1) || (level > 7)) {
+ if ((level < 1) || (level > 7)) {
printk(KERN_ERR "Invalid interrupt level\n");
return -EINVAL;
}
@@ -1025,7 +1026,7 @@ int vme_irq_request(struct device *dev, int level, int statid,
bridge->irq[level - 1].callback[statid].func = callback;
/* Enable IRQ level */
- bridge->irq_set(level, 1, 1);
+ bridge->irq_set(bridge, level, 1, 1);
mutex_unlock(&(bridge->irq_mtx));
@@ -1043,7 +1044,7 @@ void vme_irq_free(struct device *dev, int level, int statid)
return;
}
- if((level < 1) || (level > 7)) {
+ if ((level < 1) || (level > 7)) {
printk(KERN_ERR "Invalid interrupt level\n");
return;
}
@@ -1059,7 +1060,7 @@ void vme_irq_free(struct device *dev, int level, int statid)
/* Disable IRQ level if no more interrupts attached at this level*/
if (bridge->irq[level - 1].count == 0)
- bridge->irq_set(level, 0, 1);
+ bridge->irq_set(bridge, level, 0, 1);
bridge->irq[level - 1].callback[statid].func = NULL;
bridge->irq[level - 1].callback[statid].priv_data = NULL;
@@ -1078,17 +1079,17 @@ int vme_irq_generate(struct device *dev, int level, int statid)
return -EINVAL;
}
- if((level < 1) || (level > 7)) {
+ if ((level < 1) || (level > 7)) {
printk(KERN_WARNING "Invalid interrupt level\n");
return -EINVAL;
}
if (bridge->irq_generate == NULL) {
- printk("Interrupt generation not supported\n");
+ printk(KERN_WARNING "Interrupt generation not supported\n");
return -EINVAL;
}
- return bridge->irq_generate(level, statid);
+ return bridge->irq_generate(bridge, level, statid);
}
EXPORT_SYMBOL(vme_irq_generate);
@@ -1189,8 +1190,6 @@ int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
return -EINVAL;
}
- /* XXX Check parameters */
-
return bridge->lm_set(lm, lm_base, aspace, cycle);
}
EXPORT_SYMBOL(vme_lm_set);
@@ -1297,11 +1296,11 @@ int vme_slot_get(struct device *bus)
}
if (bridge->slot_get == NULL) {
- printk("vme_slot_get not supported\n");
+ printk(KERN_WARNING "vme_slot_get not supported\n");
return -EINVAL;
}
- return bridge->slot_get();
+ return bridge->slot_get(bridge);
}
EXPORT_SYMBOL(vme_slot_get);
@@ -1331,7 +1330,7 @@ static void vme_free_bus_num(int bus)
mutex_unlock(&vme_bus_num_mtx);
}
-int vme_register_bridge (struct vme_bridge *bridge)
+int vme_register_bridge(struct vme_bridge *bridge)
{
struct device *dev;
int retval;
@@ -1358,7 +1357,7 @@ int vme_register_bridge (struct vme_bridge *bridge)
dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1);
retval = device_register(dev);
- if(retval)
+ if (retval)
goto err_reg;
}
@@ -1375,7 +1374,7 @@ err_reg:
}
EXPORT_SYMBOL(vme_register_bridge);
-void vme_unregister_bridge (struct vme_bridge *bridge)
+void vme_unregister_bridge(struct vme_bridge *bridge)
{
int i;
struct device *dev;
@@ -1392,7 +1391,7 @@ EXPORT_SYMBOL(vme_unregister_bridge);
/* - Driver Registration --------------------------------------------------- */
-int vme_register_driver (struct vme_driver *drv)
+int vme_register_driver(struct vme_driver *drv)
{
drv->driver.name = drv->name;
drv->driver.bus = &vme_bus_type;
@@ -1401,7 +1400,7 @@ int vme_register_driver (struct vme_driver *drv)
}
EXPORT_SYMBOL(vme_register_driver);
-void vme_unregister_driver (struct vme_driver *drv)
+void vme_unregister_driver(struct vme_driver *drv)
{
driver_unregister(&drv->driver);
}
@@ -1418,10 +1417,10 @@ int vme_calc_slot(struct device *dev)
/* Determine slot number */
num = 0;
- while(num < VME_SLOTS_MAX) {
- if(&(bridge->dev[num]) == dev) {
+ while (num < VME_SLOTS_MAX) {
+ if (&(bridge->dev[num]) == dev)
break;
- }
+
num++;
}
if (num == VME_SLOTS_MAX) {
@@ -1437,8 +1436,8 @@ err_dev:
static struct vme_driver *dev_to_vme_driver(struct device *dev)
{
- if(dev->driver == NULL)
- printk("Bugger dev->driver is NULL\n");
+ if (dev->driver == NULL)
+ printk(KERN_ERR "Bugger dev->driver is NULL\n");
return container_of(dev->driver, struct vme_driver, driver);
}
@@ -1462,7 +1461,7 @@ static int vme_bus_match(struct device *dev, struct device_driver *drv)
}
i = 0;
- while((driver->bind_table[i].bus != 0) ||
+ while ((driver->bind_table[i].bus != 0) ||
(driver->bind_table[i].slot != 0)) {
if (bridge->num == driver->bind_table[i].bus) {
@@ -1493,9 +1492,8 @@ static int vme_bus_probe(struct device *dev)
driver = dev_to_vme_driver(dev);
bridge = dev_to_bridge(dev);
- if(driver->probe != NULL) {
+ if (driver->probe != NULL)
retval = driver->probe(dev, bridge->num, vme_calc_slot(dev));
- }
return retval;
}
@@ -1509,9 +1507,8 @@ static int vme_bus_remove(struct device *dev)
driver = dev_to_vme_driver(dev);
bridge = dev_to_bridge(dev);
- if(driver->remove != NULL) {
+ if (driver->remove != NULL)
retval = driver->remove(dev, bridge->num, vme_calc_slot(dev));
- }
return retval;
}
@@ -1524,18 +1521,18 @@ struct bus_type vme_bus_type = {
};
EXPORT_SYMBOL(vme_bus_type);
-static int __init vme_init (void)
+static int __init vme_init(void)
{
return bus_register(&vme_bus_type);
}
-static void __exit vme_exit (void)
+static void __exit vme_exit(void)
{
bus_unregister(&vme_bus_type);
}
MODULE_DESCRIPTION("VME bridge driver framework");
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
MODULE_LICENSE("GPL");
module_init(vme_init);
diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h
index 97dc22e34ca..48768ca97e1 100644
--- a/drivers/staging/vme/vme.h
+++ b/drivers/staging/vme/vme.h
@@ -68,6 +68,14 @@ typedef u32 vme_pattern_t;
#define VME_DMA_PATTERN_WORD (1<<1)
#define VME_DMA_PATTERN_INCREMENT (1<<2)
+typedef u32 vme_dma_route_t;
+#define VME_DMA_VME_TO_MEM (1<<0)
+#define VME_DMA_MEM_TO_VME (1<<1)
+#define VME_DMA_VME_TO_VME (1<<2)
+#define VME_DMA_MEM_TO_MEM (1<<3)
+#define VME_DMA_PATTERN_TO_VME (1<<4)
+#define VME_DMA_PATTERN_TO_MEM (1<<5)
+
struct vme_dma_attr {
vme_dma_t type;
void *private;
@@ -98,32 +106,33 @@ struct vme_driver {
struct device_driver driver;
};
-void * vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *);
+void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *);
void vme_free_consistent(struct vme_resource *, size_t, void *,
dma_addr_t);
size_t vme_get_size(struct vme_resource *);
-struct vme_resource * vme_slave_request(struct device *, vme_address_t, vme_cycle_t);
-int vme_slave_set (struct vme_resource *, int, unsigned long long,
+struct vme_resource *vme_slave_request(struct device *, vme_address_t,
+ vme_cycle_t);
+int vme_slave_set(struct vme_resource *, int, unsigned long long,
unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
-int vme_slave_get (struct vme_resource *, int *, unsigned long long *,
+int vme_slave_get(struct vme_resource *, int *, unsigned long long *,
unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *);
void vme_slave_free(struct vme_resource *);
-struct vme_resource * vme_master_request(struct device *, vme_address_t, vme_cycle_t,
- vme_width_t);
-int vme_master_set (struct vme_resource *, int, unsigned long long,
+struct vme_resource *vme_master_request(struct device *, vme_address_t,
+ vme_cycle_t, vme_width_t);
+int vme_master_set(struct vme_resource *, int, unsigned long long,
unsigned long long, vme_address_t, vme_cycle_t, vme_width_t);
-int vme_master_get (struct vme_resource *, int *, unsigned long long *,
+int vme_master_get(struct vme_resource *, int *, unsigned long long *,
unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *);
ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t);
ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t);
-unsigned int vme_master_rmw (struct vme_resource *, unsigned int, unsigned int,
+unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int,
unsigned int, loff_t);
void vme_master_free(struct vme_resource *);
-struct vme_resource *vme_dma_request(struct device *);
+struct vme_resource *vme_dma_request(struct device *, vme_dma_route_t);
struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t);
struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
@@ -153,8 +162,8 @@ void vme_lm_free(struct vme_resource *);
int vme_slot_get(struct device *);
-int vme_register_driver (struct vme_driver *);
-void vme_unregister_driver (struct vme_driver *);
+int vme_register_driver(struct vme_driver *);
+void vme_unregister_driver(struct vme_driver *);
#endif /* _VME_H_ */
diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt
index a5c1b1cd5fc..a910a0c4388 100644
--- a/drivers/staging/vme/vme_api.txt
+++ b/drivers/staging/vme/vme_api.txt
@@ -77,16 +77,21 @@ driver in question:
struct vme_resource * vme_slave_request(struct device *dev,
vme_address_t aspace, vme_cycle_t cycle);
- struct vme_resource *vme_dma_request(struct device *dev);
+ struct vme_resource *vme_dma_request(struct device *dev,
+ vme_dma_route_t route);
For slave windows these attributes are split into those of type 'vme_address_t'
-and 'vme_cycle_t'. Master windows add a further set of attributes 'vme_cycle_t'.
-These attributes are defined as bitmasks and as such any combination of the
-attributes can be requested for a single window, the core will assign a window
-that meets the requirements, returning a pointer of type vme_resource that
-should be used to identify the allocated resource when it is used. If an
-unallocated window fitting the requirements can not be found a NULL pointer will
-be returned.
+and 'vme_cycle_t'. Master windows add a further set of attributes
+'vme_cycle_t'. These attributes are defined as bitmasks and as such any
+combination of the attributes can be requested for a single window, the core
+will assign a window that meets the requirements, returning a pointer of type
+vme_resource that should be used to identify the allocated resource when it is
+used. For DMA controllers, the request function requires the potential
+direction of any transfers to be provided in the route attributes. This is
+typically VME-to-MEM and/or MEM-to-VME, though some hardware can support
+VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. If an
+unallocated window fitting the requirements can not be found a NULL pointer
+will be returned.
Functions are also provided to free window allocations once they are no longer
required. These functions should be passed the pointer to the resource provided
@@ -237,6 +242,12 @@ covered under "Transfer Attributes"):
struct vme_dma_attr *src, struct vme_dma_attr *dest,
size_t count);
+NOTE: The detailed attributes of the transfers source and destination
+ are not checked until an entry is added to a DMA list, the request
+ for a DMA channel purely checks the directions in which the
+ controller is expected to transfer data. As a result it is
+ possible for this call to return an error, for example if the
+ source or destination is in an unsupported VME address space.
Transfer Attributes
-------------------
diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h
index 851fa92559f..b653ec02e1f 100644
--- a/drivers/staging/vme/vme_bridge.h
+++ b/drivers/staging/vme/vme_bridge.h
@@ -19,7 +19,7 @@ struct vme_master_resource {
vme_address_t address_attr;
vme_cycle_t cycle_attr;
vme_width_t width_attr;
- struct resource pci_resource; /* XXX Rename to be bus agnostic */
+ struct resource bus_resource;
void *kern_base;
};
@@ -64,6 +64,7 @@ struct vme_dma_resource {
int number;
struct list_head pending;
struct list_head running;
+ vme_dma_route_t route_attr;
};
struct vme_lm_resource {
@@ -101,7 +102,7 @@ struct vme_irq {
* Currently we assume that all chips are PCI-based
*/
struct vme_bridge {
- char name[VMENAMSIZ];
+ char name[VMENAMSIZ];
int num;
struct list_head master_resources;
struct list_head slave_resources;
@@ -112,7 +113,7 @@ struct vme_bridge {
/* Bridge Info - XXX Move to private structure? */
struct device *parent; /* Generic device struct (pdev->dev for PCI) */
- void * base; /* Base Address of device registers */
+ void *driver_priv; /* Private pointer for the bridge driver */
struct device dev[VME_SLOTS_MAX]; /* Device registered with
* device model on VME bus
@@ -151,8 +152,8 @@ struct vme_bridge {
int (*dma_list_empty) (struct vme_dma_list *);
/* Interrupt Functions */
- void (*irq_set) (int, int, int);
- int (*irq_generate) (int, int);
+ void (*irq_set) (struct vme_bridge *, int, int, int);
+ int (*irq_generate) (struct vme_bridge *, int, int);
/* Location monitor functions */
int (*lm_set) (struct vme_lm_resource *, unsigned long long,
@@ -163,102 +164,12 @@ struct vme_bridge {
int (*lm_detach) (struct vme_lm_resource *, int);
/* CR/CSR space functions */
- int (*slot_get) (void);
- /* Use standard master read and write functions to access CR/CSR */
-
-#if 0
- int (*set_prefetch) (void);
- int (*get_prefetch) (void);
- int (*set_arbiter) (void);
- int (*get_arbiter) (void);
- int (*set_requestor) (void);
- int (*get_requestor) (void);
-#endif
+ int (*slot_get) (struct vme_bridge *);
};
void vme_irq_handler(struct vme_bridge *, int, int);
-int vme_register_bridge (struct vme_bridge *);
-void vme_unregister_bridge (struct vme_bridge *);
+int vme_register_bridge(struct vme_bridge *);
+void vme_unregister_bridge(struct vme_bridge *);
#endif /* _VME_BRIDGE_H_ */
-
-#if 0
-/*
- * VMEbus GET INFO Arg Structure
- */
-struct vmeInfoCfg {
- int vmeSlotNum; /* VME slot number of interest */
- int boardResponded; /* Board responded */
- char sysConFlag; /* System controller flag */
- int vmeControllerID; /* Vendor/device ID of VME bridge */
- int vmeControllerRev; /* Revision of VME bridge */
- char osName[8]; /* Name of OS e.g. "Linux" */
- int vmeSharedDataValid; /* Validity of data struct */
- int vmeDriverRev; /* Revision of VME driver */
- unsigned int vmeAddrHi[8]; /* Address on VME bus */
- unsigned int vmeAddrLo[8]; /* Address on VME bus */
- unsigned int vmeSize[8]; /* Size on VME bus */
- unsigned int vmeAm[8]; /* Address modifier on VME bus */
- int reserved; /* For future use */
-};
-typedef struct vmeInfoCfg vmeInfoCfg_t;
-
-/*
- * VMEbus Requester Arg Structure
- */
-struct vmeRequesterCfg {
- int requestLevel; /* Requester Bus Request Level */
- char fairMode; /* Requester Fairness Mode Indicator */
- int releaseMode; /* Requester Bus Release Mode */
- int timeonTimeoutTimer; /* Master Time-on Time-out Timer */
- int timeoffTimeoutTimer; /* Master Time-off Time-out Timer */
- int reserved; /* For future use */
-};
-typedef struct vmeRequesterCfg vmeRequesterCfg_t;
-
-/*
- * VMEbus Arbiter Arg Structure
- */
-struct vmeArbiterCfg {
- vme_arbitration_t arbiterMode; /* Arbitration Scheduling Algorithm */
- char arbiterTimeoutFlag; /* Arbiter Time-out Timer Indicator */
- int globalTimeoutTimer; /* VMEbus Global Time-out Timer */
- char noEarlyReleaseFlag; /* No Early Release on BBUSY */
- int reserved; /* For future use */
-};
-typedef struct vmeArbiterCfg vmeArbiterCfg_t;
-
-
-/*
- * VMEbus RMW Configuration Data
- */
-struct vmeRmwCfg {
- unsigned int targetAddrU; /* VME Address (Upper) to trigger RMW cycle */
- unsigned int targetAddr; /* VME Address (Lower) to trigger RMW cycle */
- vme_address_t addrSpace; /* VME Address Space */
- int enableMask; /* Bit mask defining the bits of interest */
- int compareData; /* Data to be compared with the data read */
- int swapData; /* Data written to the VMEbus on success */
- int maxAttempts; /* Maximum times to try */
- int numAttempts; /* Number of attempts before success */
- int reserved; /* For future use */
-
-};
-typedef struct vmeRmwCfg vmeRmwCfg_t;
-
-/*
- * VMEbus Location Monitor Arg Structure
- */
-struct vmeLmCfg {
- unsigned int addrU; /* Location Monitor Address upper */
- unsigned int addr; /* Location Monitor Address lower */
- vme_address_t addrSpace; /* Address Space */
- int userAccessType; /* User/Supervisor Access Type */
- int dataAccessType; /* Data/Program Access Type */
- int lmWait; /* Time to wait for access */
- int lmEvents; /* Lm event mask */
- int reserved; /* For future use */
-};
-typedef struct vmeLmCfg vmeLmCfg_t;
-#endif
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index db786142717..bf4fd49709d 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -2788,16 +2788,18 @@ void CARDvUpdateBasicTopRate (PVOID pDeviceHandler)
//Determines the highest basic rate.
for (ii = RATE_54M; ii >= RATE_6M; ii --) {
- if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) )
+ if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
byTopOFDM = ii;
break;
+ }
}
pDevice->byTopOFDMBasicRate = byTopOFDM;
for (ii = RATE_11M;; ii --) {
- if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) )
+ if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
byTopCCK = ii;
break;
+ }
if (ii == RATE_1M)
break;
}
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 0dadb765fec..e40a2e990f4 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -84,6 +84,7 @@
#include "iowpa.h"
#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
//#define DEBUG
/*--------------------- Static Definitions -------------------------*/
@@ -1105,10 +1106,7 @@ static void device_print_info(PSDevice pDevice)
struct net_device* dev=pDevice->dev;
DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id));
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- dev->name,
- dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2],
- dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]);
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr);
#ifdef IO_MAP
DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx ",(ULONG) pDevice->ioaddr);
DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c
index 108830ff3b3..78b49830a25 100644
--- a/drivers/staging/vt6655/iwctl.c
+++ b/drivers/staging/vt6655/iwctl.c
@@ -1472,7 +1472,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
if ( index < 4 ) {
pDevice->byKeyIndex = index;
}
- else if(!wrq->flags & IW_ENCODE_MODE) {
+ else if(!(wrq->flags & IW_ENCODE_MODE)) {
rc = -EINVAL;
return rc;
}
diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h
index 7d4bd5e8f69..0a2060bf4f9 100644
--- a/drivers/staging/winbond/core.h
+++ b/drivers/staging/winbond/core.h
@@ -14,7 +14,7 @@
struct wbsoft_priv {
u32 adapterIndex; // 20060703.4 Add for using padapterContext global adapter point
- WB_LOCALDESCRIPT sLocalPara; // Myself connected parameters
+ struct wb_local_para sLocalPara; // Myself connected parameters
MLME_FRAME sMlmeFrame; // connect to peerSTA parameters
diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h
index 5626a76d69a..fcf6a0442dc 100644
--- a/drivers/staging/winbond/localpara.h
+++ b/drivers/staging/winbond/localpara.h
@@ -110,33 +110,20 @@
// 20061108 WPS IE buffer
#define MAX_IE_APPEND_SIZE 256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes
-typedef struct _EVENTLOG
-{
- u16 Count; //Total count from start
- u16 index; //Buffer index, 0 ~ 63
- u32 EventValue[64]; //BYTE 3~2 : count, BYTE 1 : Event, BYTE 0 : reason
-} Event_Log, *pEvent_Log;
-
-typedef struct _ChanInfo
+struct chan_info
{
u8 band;
u8 ChanNo;
-} ChanInfo, *pChanInfo;
+};
-typedef struct _CHAN_LIST
-{
- u16 Count;
- ChanInfo Channel[50]; // 100B
-} CHAN_LIST, *psCHAN_LIST;
-
-typedef struct _RadioOff
+struct radio_off
{
u8 boHwRadioOff;
u8 boSwRadioOff;
-} RadioOff, *psRadioOff;
+};
//===========================================================================
-typedef struct LOCAL_PARA
+struct wb_local_para
{
u8 PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; // read from EPROM, manufacture set for each NetCard
u8 ThisMacAddress[ MAC_ADDR_LENGTH + 2 ]; // the driver will use actually.
@@ -186,7 +173,7 @@ typedef struct LOCAL_PARA
u16 ListenInterval; // The listen interval when SME invoking MLME_
// (Re)Associate_Request().
- RadioOff RadioOffStatus;
+ struct radio_off RadioOffStatus;
u8 Reserved0[2];
u8 boMsRadioOff; // Ndis demands to be true when set Disassoc. OID and be false when set SSID OID.
@@ -196,7 +183,7 @@ typedef struct LOCAL_PARA
u8 RoamStatus;
u8 reserved7[3];
- ChanInfo CurrentChan; //Current channel no. and channel band. It may be changed by scanning.
+ struct chan_info CurrentChan; //Current channel no. and channel band. It may be changed by scanning.
u8 boHandover; // Roaming, Hnadover to other AP.
u8 boCCAbusy;
@@ -253,19 +240,16 @@ typedef struct LOCAL_PARA
u32 _dot11WEPUndecryptableCount;
u32 _dot11FrameDuplicateCount;
- ChanInfo IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU.
+ struct chan_info IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU.
u8 reserved_5[2]; //It may not be used after considering RF type,
//region and modulation type.
- CHAN_LIST sSupportChanList; // 86B. It will be obtained according to RF type and region
u8 reserved_6[2]; //two variables are for wep key error detection added by ws 02/02/04
u32 bWepKeyError;
u32 bToSelfPacketReceived;
u32 WepKeyDetectTimerCount;
- Event_Log EventLog;
-
u16 SignalLostTh;
u16 SignalRoamTh;
@@ -274,6 +258,6 @@ typedef struct LOCAL_PARA
u16 IE_Append_size;
u16 reserved_7;
-} WB_LOCALDESCRIPT, *PWB_LOCALDESCRIPT;
+};
#endif
diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h
index ab1ea535f7d..e09dd4b879d 100644
--- a/drivers/staging/winbond/mds_f.h
+++ b/drivers/staging/winbond/mds_f.h
@@ -11,9 +11,6 @@ void Mds_SendComplete( struct wbsoft_priv *adapter, PT02_DESCRIPTOR pT02 );
void Mds_MpduProcess( struct wbsoft_priv *adapter, struct wb35_descriptor *pRxDes );
extern void DataDmp(u8 *pdata, u32 len, u32 offset);
-// For Asynchronous indicating. The routine collocates with USB.
-void Mds_MsduProcess( struct wbsoft_priv *adapter, PRXLAYER1 pRxLayer1, u8 SlotIndex);
-
// For data frame sending 20060802
u16 MDS_GetPacketSize( struct wbsoft_priv *adapter );
void MDS_GetNextPacket( struct wbsoft_priv *adapter, struct wb35_descriptor *pDes );
diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
index e8e13bde474..217ff0819a9 100644
--- a/drivers/staging/winbond/mds_s.h
+++ b/drivers/staging/winbond/mds_s.h
@@ -133,32 +133,4 @@ struct wb35_mds {
};
-//
-// Reveive Layer 1 Format.
-//----------------------------
-typedef struct _RXLAYER1
-{
- u16 SequenceNumber; // The sequence number of the last received packet.
- u16 BufferTotalSize;
-
- u32 InUsed;
- u32 DecryptionMethod; // The desired defragment number of the next incoming packet.
-
- u8 DeFragmentNumber;
- u8 FrameType;
- u8 TypeEncapsulated;
- u8 BufferNumber;
-
- u32 FirstFrameArrivedTime;
-
- u8 LastFrameType; // 20061004 for fix intel 3945 's bug
- u8 RESERVED[3]; //@@ anson
-
- /////////////////////////////////////////////////////////////////////////////////////////////
- // For brand-new Rx system
- u8 ReservedBuffer[ 2400 ];//If Buffer ID is reserved one, it must copy the data into this area
- u8 *ReservedBufferPoint;// Point to the next availabe address of reserved buffer
-
-}RXLAYER1, * PRXLAYER1;
-
#endif
diff --git a/drivers/staging/winbond/mlme_s.h b/drivers/staging/winbond/mlme_s.h
index ea12684a2b1..1217a1c025e 100644
--- a/drivers/staging/winbond/mlme_s.h
+++ b/drivers/staging/winbond/mlme_s.h
@@ -165,14 +165,6 @@ typedef struct _AUTHREQ {
} MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA;
-struct _Reason_Code {
-
- u8 peerMACaddr[MAC_ADDR_LENGTH];
- u16 wReasonCode;
-};
-typedef struct _Reason_Code MLME_DEAUTHREQ_PARA, *psMLME_DEAUTHREQ_PARA;
-typedef struct _Reason_Code MLME_DISASSOCREQ_PARA, *psMLME_DISASSOCREQ_PARA;
-
typedef struct _ASSOCREQ {
u8 PeerSTAAddr[MAC_ADDR_LENGTH];
u16 CapabilityInfo;
diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
index 4fe24b0f279..fb4781d5781 100644
--- a/drivers/staging/winbond/mto.h
+++ b/drivers/staging/winbond/mto.h
@@ -141,11 +141,6 @@ extern u16 MTO_Frag_Th_Tbl[];
#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()]
#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()]
-typedef struct {
- u8 tx_rate;
- u8 tx_retry_rate;
-} TXRETRY_REC;
-
extern void MTO_Init(struct wbsoft_priv *);
extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c
index d915cbdd38e..5f5048af26a 100644
--- a/drivers/staging/winbond/reg.c
+++ b/drivers/staging/winbond/reg.c
@@ -1823,12 +1823,12 @@ BBProcessor_initial( struct hw_data * pHwData )
reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6
}
-void set_tx_power_per_channel_max2829( struct hw_data * pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_max2829( struct hw_data * pHwData, struct chan_info Channel)
{
RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify
}
-void set_tx_power_per_channel_al2230( struct hw_data * pHwData, ChanInfo Channel )
+void set_tx_power_per_channel_al2230( struct hw_data * pHwData, struct chan_info Channel )
{
u8 index = 100;
@@ -1838,7 +1838,7 @@ void set_tx_power_per_channel_al2230( struct hw_data * pHwData, ChanInfo Chann
RFSynthesizer_SetPowerIndex( pHwData, index );
}
-void set_tx_power_per_channel_al7230( struct hw_data * pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_al7230( struct hw_data * pHwData, struct chan_info Channel)
{
u8 i, index = 100;
@@ -1868,7 +1868,7 @@ void set_tx_power_per_channel_al7230( struct hw_data * pHwData, ChanInfo Chann
RFSynthesizer_SetPowerIndex( pHwData, index );
}
-void set_tx_power_per_channel_wb242( struct hw_data * pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_wb242( struct hw_data * pHwData, struct chan_info Channel)
{
u8 index = 100;
@@ -1901,7 +1901,7 @@ void set_tx_power_per_channel_wb242( struct hw_data * pHwData, ChanInfo Channe
// None.
//=============================================================================================================
void
-RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel )
+RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, struct chan_info Channel )
{
struct wb35_reg *reg = &pHwData->reg;
u32 pltmp[16]; // The 16 is the maximum capability of hardware
diff --git a/drivers/staging/winbond/scan_s.h b/drivers/staging/winbond/scan_s.h
index 775bb81f23c..209717f5d47 100644
--- a/drivers/staging/winbond/scan_s.h
+++ b/drivers/staging/winbond/scan_s.h
@@ -35,7 +35,6 @@ typedef struct _SCAN_REQ_PARA //mandatory parameters for SCAN request
{
u32 ScanType; //passive/active scan
- CHAN_LIST sChannelList; // 86B
u8 reserved_1[2];
struct SSID_Element sSSID; // 34B. scan only for this SSID
diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h
index 54987830228..b5898294eb8 100644
--- a/drivers/staging/winbond/sme_api.h
+++ b/drivers/staging/winbond/sme_api.h
@@ -193,8 +193,6 @@ s8 sme_get_cwmin_value(void *pcore_data, u8 *cwmin);
s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax);
s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff);
s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff);
-s8 sme_get_radio_mode(void *pcore_data, psRadioOff pRadioOffData);
-s8 sme_set_radio_mode(void *pcore_data, RadioOff RadioOffData);
void sme_get_tx_power_level(void *pcore_data, u32 *TxPower);
u8 sme_set_tx_power_level(void *pcore_data, u32 TxPower);
@@ -203,7 +201,7 @@ void sme_get_rx_antenna(void *pcore_data, u32 *RxAntenna);
u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna);
void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna);
s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna);
-s8 sme_set_IBSS_chan(void *pcore_data, ChanInfo chan);
+s8 sme_set_IBSS_chan(void *pcore_data, struct chan_info chan);
//20061108 WPS
s8 sme_set_IE_append(void *pcore_data, u8 *buffer, u16 buf_len);
diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c
index f5608ad9ed0..1b93547ff5b 100644
--- a/drivers/staging/winbond/wb35reg.c
+++ b/drivers/staging/winbond/wb35reg.c
@@ -2,6 +2,7 @@
#include "wb35reg_f.h"
#include <linux/usb.h>
+#include <linux/slab.h>
extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency);
diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h
index 30f5b5ad63a..d352bce5c17 100644
--- a/drivers/staging/winbond/wb35reg_f.h
+++ b/drivers/staging/winbond/wb35reg_f.h
@@ -14,7 +14,7 @@ void Dxx_initial( struct hw_data * pHwData );
void Mxx_initial( struct hw_data * pHwData );
void RFSynthesizer_initial( struct hw_data * pHwData );
//void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, s8 Channel );
-void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel );
+void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, struct chan_info Channel );
void BBProcessor_initial( struct hw_data * pHwData );
void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060613.1
//void RF_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060626.5.c Add
diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c
index 4d41f6c3563..d7b57e62db0 100644
--- a/drivers/staging/winbond/wb35rx.c
+++ b/drivers/staging/winbond/wb35rx.c
@@ -9,6 +9,7 @@
//
//============================================================================
#include <linux/usb.h>
+#include <linux/slab.h>
#include "core.h"
#include "sysdef.h"
diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c
index 5869ef473fc..bda7a913edf 100644
--- a/drivers/staging/winbond/wb35tx.c
+++ b/drivers/staging/winbond/wb35tx.c
@@ -9,6 +9,7 @@
//
//============================================================================
#include <linux/usb.h>
+#include <linux/gfp.h>
#include "wb35tx_f.h"
#include "mds_f.h"
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index 067082a7d75..3482eec1865 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -23,7 +23,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.1");
-static struct usb_device_id wb35_table[] __devinitdata = {
+static const struct usb_device_id wb35_table[] __devinitconst = {
{ USB_DEVICE(0x0416, 0x0035) },
{ USB_DEVICE(0x18E8, 0x6201) },
{ USB_DEVICE(0x18E8, 0x6206) },
@@ -65,17 +65,17 @@ static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
}
static int wbsoft_add_interface(struct ieee80211_hw *dev,
- struct ieee80211_if_init_conf *conf)
+ struct ieee80211_vif *vif)
{
struct wbsoft_priv *priv = dev->priv;
- hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int);
+ hal_set_beacon_period(&priv->sHwData, vif->bss_conf.beacon_int);
return 0;
}
static void wbsoft_remove_interface(struct ieee80211_hw *dev,
- struct ieee80211_if_init_conf *conf)
+ struct ieee80211_vif *vif)
{
printk("wbsoft_remove interface called\n");
}
@@ -92,13 +92,6 @@ static int wbsoft_get_stats(struct ieee80211_hw *hw,
return 0;
}
-static int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
- struct ieee80211_tx_queue_stats *stats)
-{
- printk(KERN_INFO "%s called\n", __func__);
- return 0;
-}
-
static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
struct dev_addr_list *mc_list)
{
@@ -161,7 +154,7 @@ static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
}
static void
-hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel)
+hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
{
struct wb35_reg *reg = &pHwData->reg;
@@ -180,10 +173,10 @@ hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel)
reg->M28_MacControl &= ~0xff; // Clean channel information field
reg->M28_MacControl |= channel.ChanNo;
Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
- (s8 *) & channel, sizeof(ChanInfo));
+ (s8 *) & channel, sizeof(struct chan_info));
}
-static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel)
+static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
{
hal_set_current_channel_ex(pHwData, channel);
}
@@ -253,7 +246,7 @@ static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
{
struct wbsoft_priv *priv = dev->priv;
- ChanInfo ch;
+ struct chan_info ch;
printk("wbsoft_config called\n");
@@ -287,7 +280,6 @@ static const struct ieee80211_ops wbsoft_ops = {
.prepare_multicast = wbsoft_prepare_multicast,
.configure_filter = wbsoft_configure_filter,
.get_stats = wbsoft_get_stats,
- .get_tx_stats = wbsoft_get_tx_stats,
.get_tsf = wbsoft_get_tsf,
};
diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c
index 811a8daa660..9da42e66085 100644
--- a/drivers/staging/wlags49_h2/wl_cs.c
+++ b/drivers/staging/wlags49_h2/wl_cs.c
@@ -67,7 +67,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c
index 16764a00094..cf0c38468b2 100644
--- a/drivers/staging/wlags49_h2/wl_main.c
+++ b/drivers/staging/wlags49_h2/wl_main.c
@@ -3792,7 +3792,7 @@ static int write_int(struct file *file, const char *buffer, unsigned long count,
}
if (count > 0 ) {
proc_number[count] = 0;
- nr = wl_atoi( proc_number );
+ nr = simple_strtoul(proc_number , NULL, 0);
*(unsigned int *)data = nr;
if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
#if DBG
diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c
index c33e225bc0e..1db73ebcae2 100644
--- a/drivers/staging/wlags49_h2/wl_netdev.c
+++ b/drivers/staging/wlags49_h2/wl_netdev.c
@@ -65,6 +65,7 @@
#include <wl_version.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
// #include <linux/sched.h>
@@ -360,7 +361,7 @@ int wl_open(struct net_device *dev)
wl_lock( lp, &flags );
if( status != HCF_SUCCESS ) {
- // Unsuccesfull, try reset of the card to recover
+ // Unsuccessful, try reset of the card to recover
status = wl_reset( dev );
}
diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c
index a3db111d4a9..6751b4bad2e 100644
--- a/drivers/staging/wlags49_h2/wl_pci.c
+++ b/drivers/staging/wlags49_h2/wl_pci.c
@@ -71,7 +71,6 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
//#include <linux/timer.h>
@@ -81,7 +80,6 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c
index ee610c76457..727ea8a483a 100644
--- a/drivers/staging/wlags49_h2/wl_priv.c
+++ b/drivers/staging/wlags49_h2/wl_priv.c
@@ -65,6 +65,7 @@
#include <linux/if_arp.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c
index 715f027a923..1e0c75f2855 100644
--- a/drivers/staging/wlags49_h2/wl_profile.c
+++ b/drivers/staging/wlags49_h2/wl_profile.c
@@ -383,15 +383,15 @@ void translate_option( char *buffer, struct wl_private *lp )
DbgInfo->DebugFlag |= DBG_DEFAULTS;
}
} else {
- DbgInfo->DebugFlag = wl_atoi( value ); //;?DebugFlag;
+ DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?DebugFlag;
}
- DbgInfo->DebugFlag = wl_atoi( value ); //;?Delete ASAP
+ DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?Delete ASAP
}
#endif /* DBG */
if ( strcmp( key, PARM_NAME_AUTH_KEY_MGMT_SUITE ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE ) || ( value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE )) {
lp->AuthKeyMgmtSuite = value_convert;
} else {
@@ -401,7 +401,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_BRSC_2GHZ ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) {
lp->brsc[0] = value_convert;
} else {
@@ -411,7 +411,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_BRSC_5GHZ ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) {
lp->brsc[1] = value_convert;
} else {
@@ -448,7 +448,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_ENABLE_ENCRYPTION ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_ENABLE_ENCRYPTION ) && ( value_convert <= PARM_MAX_ENABLE_ENCRYPTION )) {
lp->EnableEncryption = value_convert;
} else {
@@ -529,7 +529,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_MULTICAST_RATE ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_MULTICAST_RATE ) && ( value_convert <= PARM_MAX_MULTICAST_RATE )) {
lp->MulticastRate[0] = value_convert;
@@ -540,7 +540,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_OWN_CHANNEL ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if ( wl_is_a_valid_chan( value_convert )) {
if ( value_convert > 14 ) {
value_convert = value_convert | 0x100;
@@ -567,7 +567,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
lp->RTSThreshold = value_convert;
} else {
@@ -577,7 +577,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_SRSC_2GHZ ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) {
lp->srsc[0] = value_convert;
} else {
@@ -587,7 +587,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_SRSC_5GHZ ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) {
lp->srsc[1] = value_convert;
} else {
@@ -597,7 +597,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_SYSTEM_SCALE ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_SYSTEM_SCALE ) && ( value_convert <= PARM_MAX_SYSTEM_SCALE )) {
lp->DistanceBetweenAPs = value_convert;
} else {
@@ -607,9 +607,9 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_KEY ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_KEY ) && ( value_convert <= PARM_MAX_TX_KEY )) {
- lp->TransmitKeyID = wl_atoi( value );
+ lp->TransmitKeyID = simple_strtoul(value, NULL, 0);
} else {
DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY );
}
@@ -617,7 +617,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_RATE ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
lp->TxRateControl[0] = value_convert;
} else {
@@ -627,7 +627,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_POW_LEVEL ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_POW_LEVEL ) || ( value_convert <= PARM_MAX_TX_POW_LEVEL )) {
lp->txPowLevel = value_convert;
} else {
@@ -645,7 +645,7 @@ void translate_option( char *buffer, struct wl_private *lp )
if ( strcmp( key, PARM_NAME_PORT_TYPE ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert == PARM_MIN_PORT_TYPE ) || ( value_convert == PARM_MAX_PORT_TYPE )) {
lp->PortType = value_convert;
} else {
@@ -654,7 +654,7 @@ void translate_option( char *buffer, struct wl_private *lp )
}
else if ( strcmp( key, PARM_NAME_PM_ENABLED ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
/* ;? how about wl_main.c containing
* VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
* ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
@@ -677,7 +677,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_MAX_SLEEP ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= 0 ) && ( value_convert <= 65535 )) {
lp->MaxSleepDuration = value_convert;
} else {
@@ -696,7 +696,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_AUTHENTICATION ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_AUTHENTICATION ) && ( value_convert <= PARM_MAX_AUTHENTICATION )) {
lp->authentication = value_convert;
} else {
@@ -706,7 +706,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_OWN_ATIM_WINDOW ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_OWN_ATIM_WINDOW ) && ( value_convert <= PARM_MAX_OWN_ATIM_WINDOW )) {
lp->atimWindow = value_convert;
} else {
@@ -716,7 +716,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_PM_HOLDOVER_DURATION ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_PM_HOLDOVER_DURATION ) && ( value_convert <= PARM_MAX_PM_HOLDOVER_DURATION )) {
lp->holdoverDuration = value_convert;
} else {
@@ -730,7 +730,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_CONNECTION_CONTROL ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_CONNECTION_CONTROL ) && ( value_convert <= PARM_MAX_CONNECTION_CONTROL )) {
lp->connectionControl = value_convert;
} else {
@@ -749,7 +749,7 @@ void translate_option( char *buffer, struct wl_private *lp )
if ( strcmp( key, PARM_NAME_OWN_DTIM_PERIOD ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if ( value_convert >= PARM_MIN_OWN_DTIM_PERIOD ) {
lp->DTIMPeriod = value_convert;
} else {
@@ -775,7 +775,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_OWN_BEACON_INTERVAL ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if ( value_convert >= PARM_MIN_OWN_BEACON_INTERVAL ) {
lp->ownBeaconInterval = value_convert;
} else {
@@ -785,7 +785,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_COEXISTENCE ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if ( value_convert >= PARM_MIN_COEXISTENCE ) {
lp->coexistence = value_convert;
} else {
@@ -797,7 +797,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD1 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
lp->wds_port[0].rtsThreshold = value_convert;
} else {
@@ -807,7 +807,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD2 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
lp->wds_port[1].rtsThreshold = value_convert;
} else {
@@ -817,7 +817,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD3 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
lp->wds_port[2].rtsThreshold = value_convert;
} else {
@@ -827,7 +827,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD4 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
lp->wds_port[3].rtsThreshold = value_convert;
} else {
@@ -837,7 +837,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD5 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
lp->wds_port[4].rtsThreshold = value_convert;
} else {
@@ -847,7 +847,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD6 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
lp->wds_port[5].rtsThreshold = value_convert;
} else {
@@ -857,7 +857,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_RATE1 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
lp->wds_port[0].txRateCntl = value_convert;
} else {
@@ -867,7 +867,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_RATE2 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
lp->wds_port[1].txRateCntl = value_convert;
} else {
@@ -877,7 +877,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_RATE3 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
lp->wds_port[2].txRateCntl = value_convert;
} else {
@@ -887,7 +887,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_RATE4 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
lp->wds_port[3].txRateCntl = value_convert;
} else {
@@ -897,7 +897,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_RATE5 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
lp->wds_port[4].txRateCntl = value_convert;
} else {
@@ -907,7 +907,7 @@ void translate_option( char *buffer, struct wl_private *lp )
else if ( strcmp( key, PARM_NAME_TX_RATE6 ) == 0 ) {
DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value );
- value_convert = wl_atoi( value );
+ value_convert = simple_strtoul(value, NULL, 0);
if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
lp->wds_port[5].txRateCntl = value_convert;
} else {
diff --git a/drivers/staging/wlags49_h2/wl_util.c b/drivers/staging/wlags49_h2/wl_util.c
index ac1e7f38f98..bbdb9973d1e 100644
--- a/drivers/staging/wlags49_h2/wl_util.c
+++ b/drivers/staging/wlags49_h2/wl_util.c
@@ -1536,52 +1536,3 @@ int wl_get_tallies(struct wl_private *lp,
return ret;
}
-/*******************************************************************************
- * wl_atoi()
- *******************************************************************************
- *
- * DESCRIPTION:
- *
- * Believe it or not, we need our own implementation of atoi in the kernel.
- *
- * PARAMETERS:
- *
- * string - the ASCII string to convert to an integer
- *
- * RETURNS:
- *
- * unsigned integer
- *
- ******************************************************************************/
-unsigned int wl_atoi( char *string )
-{
-unsigned int base = 10; //default to decimal
-unsigned int value = 0;
-unsigned int c;
-int i = strlen( string );
-
- if ( i > 2 && string[0] == '0' && ( string[1] | ('X'^'x') ) == 'x' ) {
- base = 16;
- string +=2;
- }
- while ( ( c = *string++ ) != '\0' ) {
- if ( value > UINT_MAX / base ) { //test for overrun
- DBG_FUNC( "wl_atoi" ); //don't overload the log file with good messages
- DBG_ENTER( DbgInfo );
- DBG_ERROR( DbgInfo, "string \"%s\", lenght exceeds expectations\n", string );
- printk( "<1>string \"%s\", lenght exceeds expectations\n", string );
- DBG_LEAVE( DbgInfo );
- break;
- }
- c -= '0';
- if ( 0 <= c && c <= 9 ) value = base * value + c;
- else if ( base == 16 ) {
- c += '0';
- c |= 'A'^'a';
- c = c - 'a'+ 10;
- if ( 10 <= c && c <= 15 ) value = base * value + c;
- }
- }
- return value;
-} // wl_atoi
-
diff --git a/drivers/staging/wlags49_h2/wl_util.h b/drivers/staging/wlags49_h2/wl_util.h
index 16cd6c578ad..561e85b5c9b 100644
--- a/drivers/staging/wlags49_h2/wl_util.h
+++ b/drivers/staging/wlags49_h2/wl_util.h
@@ -100,6 +100,4 @@ void wl_process_updated_record( struct wl_private *lp );
void wl_process_assoc_status( struct wl_private *lp );
void wl_process_security_status( struct wl_private *lp );
-unsigned int wl_atoi( char *string );
-
#endif // __WL_UTIL_H__
diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig
index f44294b0d8d..82fcc1665e9 100644
--- a/drivers/staging/wlan-ng/Kconfig
+++ b/drivers/staging/wlan-ng/Kconfig
@@ -1,6 +1,8 @@
config PRISM2_USB
tristate "Prism2.5/3 USB driver"
- depends on WLAN && USB && WIRELESS_EXT
+ depends on WLAN && USB
+ select WIRELESS_EXT
+ select WEXT_PRIV
default n
---help---
This is the wlan-ng prism 2.5/3 USB driver for a wide range of
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 46cce8159e5..1fa42e01e8c 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -61,17 +61,17 @@
#include <linux/if_ether.h>
/*--- Mins & Maxs -----------------------------------*/
-#define HFA384x_PORTID_MAX ((u16)7)
-#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1))
-#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */
-#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */
-#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK */
-#define HFA384x_SCANRESULT_MAX ((u16)31)
-#define HFA384x_HSCANRESULT_MAX ((u16)31)
-#define HFA384x_CHINFORESULT_MAX ((u16)16)
-#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */
-#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN
-#define HFA384x_USB_RWMEM_MAXLEN 2048
+#define HFA384x_PORTID_MAX ((u16)7)
+#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1))
+#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */
+#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */
+#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK*/
+#define HFA384x_SCANRESULT_MAX ((u16)31)
+#define HFA384x_HSCANRESULT_MAX ((u16)31)
+#define HFA384x_CHINFORESULT_MAX ((u16)16)
+#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */
+#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN
+#define HFA384x_USB_RWMEM_MAXLEN 2048
/*--- Support Constants -----------------------------*/
#define HFA384x_PORTTYPE_IBSS ((u16)0)
@@ -115,8 +115,8 @@
/* Make a 32-bit flat address from AUX format 16-bit page and offset */
#define HFA384x_ADDR_AUX_MKFLAT(p, o) \
- (((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
- ((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK))
+ ((((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
+ ((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK)))
/* Make CMD format offset and page from a 32-bit flat address */
#define HFA384x_ADDR_CMD_MKPAGE(f) \
@@ -135,12 +135,21 @@
#define HFA384x_DLSTATE_FLASHENABLED 2
/*--- Register Field Masks --------------------------*/
-#define HFA384x_CMD_AINFO ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
-#define HFA384x_CMD_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_CMD_AINFO ((u16)(BIT(14) | BIT(13) \
+ | BIT(12) | BIT(11) \
+ | BIT(10) | BIT(9) \
+ | BIT(8)))
+#define HFA384x_CMD_MACPORT ((u16)(BIT(10) | BIT(9) | \
+ BIT(8)))
#define HFA384x_CMD_PROGMODE ((u16)(BIT(9) | BIT(8)))
-#define HFA384x_CMD_CMDCODE ((u16)(BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)))
+#define HFA384x_CMD_CMDCODE ((u16)(BIT(5) | BIT(4) | \
+ BIT(3) | BIT(2) | \
+ BIT(1) | BIT(0)))
-#define HFA384x_STATUS_RESULT ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_STATUS_RESULT ((u16)(BIT(14) | BIT(13) \
+ | BIT(12) | BIT(11) \
+ | BIT(10) | BIT(9) \
+ | BIT(8)))
/*--- Command Code Constants --------------------------*/
/*--- Controller Commands --------------------------*/
@@ -244,8 +253,10 @@ Information RID Lengths: MAC Information
This is the length of JUST the DATA part of the RID (does not
include the len or code fields)
--------------------------------------------------------------------*/
-#define HFA384x_RID_DBMCOMMSQUALITY_LEN ((u16)sizeof(hfa384x_dbmcommsquality_t))
-#define HFA384x_RID_JOINREQUEST_LEN ((u16)sizeof(hfa384x_JoinRequest_data_t))
+#define HFA384x_RID_DBMCOMMSQUALITY_LEN \
+ ((u16) sizeof(hfa384x_dbmcommsquality_t))
+#define HFA384x_RID_JOINREQUEST_LEN \
+ ((u16)sizeof(hfa384x_JoinRequest_data_t))
/*--------------------------------------------------------------------
Information RIDs: Modem Information
@@ -322,9 +333,11 @@ PD Record codes
/*--- Register Test/Get/Set Field macros ------------------------*/
-#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8))
-#define HFA384x_CMD_MACPORT_SET(value) ((u16)HFA384x_CMD_AINFO_SET(value))
-#define HFA384x_CMD_PROGMODE_SET(value) ((u16)HFA384x_CMD_AINFO_SET((u16)value))
+#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8))
+#define HFA384x_CMD_MACPORT_SET(value) \
+ ((u16)HFA384x_CMD_AINFO_SET(value))
+#define HFA384x_CMD_PROGMODE_SET(value) \
+ ((u16)HFA384x_CMD_AINFO_SET((u16)value))
#define HFA384x_CMD_CMDCODE_SET(value) ((u16)(value))
#define HFA384x_STATUS_RESULT_SET(value) (((u16)(value)) << 8)
@@ -402,7 +415,7 @@ typedef struct hfa384x_authenticateStation_data {
/*-- Configuration Record: WPAData (data portion only) --*/
typedef struct hfa384x_WPAData {
u16 datalen;
- u8 data[0]; // max 80
+ u8 data[0]; /* max 80 */
} __attribute__ ((packed)) hfa384x_WPAData_t;
/*--------------------------------------------------------------------
@@ -479,7 +492,8 @@ Communication Frames: Field Masks for Transmit Frames
#define HFA384x_TXSTATUS_AGEDERR ((u16)BIT(1))
#define HFA384x_TXSTATUS_RETRYERR ((u16)BIT(0))
/*-- Transmit Control Field --*/
-#define HFA384x_TX_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_TX_MACPORT ((u16)(BIT(10) | \
+ BIT(9) | BIT(8)))
#define HFA384x_TX_STRUCTYPE ((u16)(BIT(4) | BIT(3)))
#define HFA384x_TX_TXEX ((u16)BIT(2))
#define HFA384x_TX_TXOK ((u16)BIT(1))
@@ -496,7 +510,8 @@ Communication Frames: Test/Get/Set Field Values for Transmit Frames
#define HFA384x_TX_SET(v, m, s) ((((u16)(v))<<((u16)(s)))&((u16)(m)))
#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8)
-#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3)
+#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, \
+ HFA384x_TX_STRUCTYPE, 3)
#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2)
#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1)
/*--------------------------------------------------------------------
@@ -534,13 +549,17 @@ Communication Frames: Field Masks for Receive Frames
--------------------------------------------------------------------*/
/*-- Status Fields --*/
-#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | \
+ BIT(9) | \
+ BIT(8)))
#define HFA384x_RXSTATUS_FCSERR ((u16)BIT(0))
/*--------------------------------------------------------------------
Communication Frames: Test/Get/Set Field Values for Receive Frames
--------------------------------------------------------------------*/
-#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8))
-#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) & HFA384x_RXSTATUS_FCSERR))
+#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) \
+ & HFA384x_RXSTATUS_MACPORT) >> 8))
+#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) \
+ & HFA384x_RXSTATUS_FCSERR))
/*--------------------------------------------------------------------
FRAME STRUCTURES: Information Types and Information Frame Structures
----------------------------------------------------------------------
@@ -1133,7 +1152,7 @@ struct hfa384x;
typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *);
-typedef void (*ctlx_usercb_t) (struct hfa384x * hw,
+typedef void (*ctlx_usercb_t) (struct hfa384x *hw,
void *ctlxresult, void *usercb_data);
typedef struct hfa384x_usbctlx {
@@ -1174,14 +1193,14 @@ typedef struct hfa484x_metacmd {
} hfa384x_metacmd_t;
#define MAX_GRP_ADDR 32
-#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */
+#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */
-#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */
-#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */
-#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */
-#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */
-#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */
-#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */
+#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */
+#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */
+#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */
+#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */
+#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */
+#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */
/* XXX These are going away ASAP */
typedef struct prism2sta_authlist {
@@ -1294,10 +1313,23 @@ typedef struct hfa384x {
hfa384x_caplevel_t cap_sup_ap;
/* Actor compatibility ranges */
- hfa384x_caplevel_t cap_act_pri_cfi; /* pri f/w to controller interface */
- hfa384x_caplevel_t cap_act_sta_cfi; /* sta f/w to controller interface */
+ hfa384x_caplevel_t cap_act_pri_cfi; /*
+ * pri f/w to controller
+ * interface
+ */
+
+ hfa384x_caplevel_t cap_act_sta_cfi; /*
+ * sta f/w to controller
+ * interface
+ */
+
hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */
- hfa384x_caplevel_t cap_act_ap_cfi; /* ap f/w to controller interface */
+
+ hfa384x_caplevel_t cap_act_ap_cfi; /*
+ * ap f/w to controller
+ * interface
+ */
+
hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */
u32 psusercount; /* Power save user count. */
@@ -1320,25 +1352,25 @@ typedef struct hfa384x {
} hfa384x_t;
-void hfa384x_create(hfa384x_t * hw, struct usb_device *usb);
-void hfa384x_destroy(hfa384x_t * hw);
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb);
+void hfa384x_destroy(hfa384x_t *hw);
int
-hfa384x_corereset(hfa384x_t * hw, int holdtime, int settletime, int genesis);
-int hfa384x_drvr_commtallies(hfa384x_t * hw);
-int hfa384x_drvr_disable(hfa384x_t * hw, u16 macport);
-int hfa384x_drvr_enable(hfa384x_t * hw, u16 macport);
-int hfa384x_drvr_flashdl_enable(hfa384x_t * hw);
-int hfa384x_drvr_flashdl_disable(hfa384x_t * hw);
-int hfa384x_drvr_flashdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len);
-int hfa384x_drvr_getconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len);
-int hfa384x_drvr_ramdl_enable(hfa384x_t * hw, u32 exeaddr);
-int hfa384x_drvr_ramdl_disable(hfa384x_t * hw);
-int hfa384x_drvr_ramdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len);
-int hfa384x_drvr_readpda(hfa384x_t * hw, void *buf, unsigned int len);
-int hfa384x_drvr_setconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len);
-
-static inline int hfa384x_drvr_getconfig16(hfa384x_t * hw, u16 rid, void *val)
+hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis);
+int hfa384x_drvr_commtallies(hfa384x_t *hw);
+int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
+int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
+
+static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
{
int result = 0;
result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16));
@@ -1347,46 +1379,46 @@ static inline int hfa384x_drvr_getconfig16(hfa384x_t * hw, u16 rid, void *val)
return result;
}
-static inline int hfa384x_drvr_setconfig16(hfa384x_t * hw, u16 rid, u16 val)
+static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
{
u16 value = cpu_to_le16(val);
return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
}
int
-hfa384x_drvr_getconfig_async(hfa384x_t * hw,
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
u16 rid, ctlx_usercb_t usercb, void *usercb_data);
int
-hfa384x_drvr_setconfig_async(hfa384x_t * hw,
+hfa384x_drvr_setconfig_async(hfa384x_t *hw,
u16 rid,
void *buf,
u16 len, ctlx_usercb_t usercb, void *usercb_data);
static inline int
-hfa384x_drvr_setconfig16_async(hfa384x_t * hw, u16 rid, u16 val)
+hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val)
{
u16 value = cpu_to_le16(val);
return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
NULL, NULL);
}
-int hfa384x_drvr_start(hfa384x_t * hw);
-int hfa384x_drvr_stop(hfa384x_t * hw);
+int hfa384x_drvr_start(hfa384x_t *hw);
+int hfa384x_drvr_stop(hfa384x_t *hw);
int
-hfa384x_drvr_txframe(hfa384x_t * hw, struct sk_buff *skb,
- p80211_hdr_t * p80211_hdr, p80211_metawep_t * p80211_wep);
-void hfa384x_tx_timeout(wlandevice_t * wlandev);
-
-int hfa384x_cmd_initialize(hfa384x_t * hw);
-int hfa384x_cmd_enable(hfa384x_t * hw, u16 macport);
-int hfa384x_cmd_disable(hfa384x_t * hw, u16 macport);
-int hfa384x_cmd_allocate(hfa384x_t * hw, u16 len);
-int hfa384x_cmd_monitor(hfa384x_t * hw, u16 enable);
+hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
+ p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+void hfa384x_tx_timeout(wlandevice_t *wlandev);
+
+int hfa384x_cmd_initialize(hfa384x_t *hw);
+int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
+int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
int
-hfa384x_cmd_download(hfa384x_t * hw,
+hfa384x_cmd_download(hfa384x_t *hw,
u16 mode, u16 lowaddr, u16 highaddr, u16 codelen);
-#endif /* __KERNEL__ */
+#endif /*__KERNEL__ */
-#endif /* _HFA384x_H */
+#endif /*_HFA384x_H */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 925678babd9..5df56f0238d 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -52,7 +52,7 @@
* around the register accesses. The next higher level represents C-callable
* prism2 API functions that match the Intersil documentation as closely
* as is reasonable. The next higher layer implements common sequences
-* of invokations of the API layer (e.g. write to bap, followed by cmd).
+* of invocations of the API layer (e.g. write to bap, followed by cmd).
*
* Common sequences:
* hfa384x_drvr_xxx Highest level abstractions provided by the
@@ -118,15 +118,15 @@
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/timer.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <asm/byteorder.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <linux/list.h>
#include <linux/usb.h>
#include <linux/byteorder/generic.h>
-#define SUBMIT_URB(u,f) usb_submit_urb(u,f)
+#define SUBMIT_URB(u, f) usb_submit_urb(u, f)
#include "p80211types.h"
#include "p80211hdr.h"
@@ -627,7 +627,7 @@ static hfa384x_usbctlx_t *usbctlx_alloc(void)
{
hfa384x_usbctlx_t *ctlx;
- ctlx = kmalloc(sizeof(*ctlx), in_interrupt()? GFP_ATOMIC : GFP_KERNEL);
+ ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (ctlx != NULL) {
memset(ctlx, 0, sizeof(*ctlx));
init_completion(&ctlx->done);
@@ -675,7 +675,7 @@ struct usbctlx_cmd_completor {
};
typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t;
-static int usbctlx_cmd_completor_fn(usbctlx_completor_t * head)
+static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head)
{
usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t *) head;
return usbctlx_get_status(complete->cmdresp, complete->result);
@@ -1909,18 +1909,19 @@ int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
return -EINVAL;
/* Retrieve the buffer loc&size and timeout */
- if ((result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
- &(hw->bufinfo),
- sizeof(hw->bufinfo)))) {
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+ &(hw->bufinfo), sizeof(hw->bufinfo));
+ if (result)
return result;
- }
+
hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page);
hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset);
hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len);
- if ((result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
- &(hw->dltimeout)))) {
+ result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+ &(hw->dltimeout));
+ if (result)
return result;
- }
+
hw->dltimeout = le16_to_cpu(hw->dltimeout);
pr_debug("flashdl_enable\n");
@@ -3071,9 +3072,9 @@ static void hfa384x_usbctlxq_run(hfa384x_t *hw)
hfa384x_ctlxout_callback, hw);
hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
- /* Now submit the URB and update the CTLX's state
- */
- if ((result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC)) == 0) {
+ /* Now submit the URB and update the CTLX's state */
+ result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC);
+ if (result == 0) {
/* This CTLX is now running on the active queue */
head->state = CTLX_REQ_SUBMITTED;
@@ -3599,7 +3600,8 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
skblen - sizeof(p80211_caphdr_t));
}
- if ((skb = dev_alloc_skb(skblen)) == NULL) {
+ skb = dev_alloc_skb(skblen);
+ if (skb == NULL) {
printk(KERN_ERR
"alloc_skb failed trying to allocate %d bytes\n",
skblen);
@@ -3642,7 +3644,7 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
/* check for unencrypted stuff if WEP bit set. */
if (*(datap - hdrlen + 1) & 0x40) /* wep set */
if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa))
- *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
+ *(datap - hdrlen + 1) &= 0xbf; /* clear wep; it's the 802.2 header! */
}
if (hw->sniff_fcs) {
@@ -3870,9 +3872,9 @@ retry:
delresp:
if (delete_resptimer) {
- if ((timer_ok = del_timer(&hw->resptimer)) != 0) {
+ timer_ok = del_timer(&hw->resptimer);
+ if (timer_ok != 0)
hw->resp_timer_done = 1;
- }
}
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index 5952c671073..a1605fbc809 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -206,12 +206,11 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
/* XXXX need to pick keynum other than default? */
p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
-
- if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
- skb->len,
- (wlandev->hostwep &
- HOSTWEP_DEFAULTKEY_MASK),
- p80211_wep->iv, p80211_wep->icv))) {
+ foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
+ skb->len,
+ (wlandev->hostwep &HOSTWEP_DEFAULTKEY_MASK),
+ p80211_wep->iv, p80211_wep->icv);
+ if (foo) {
printk(KERN_WARNING
"Host en-WEP failed, dropping frame (%d).\n",
foo);
@@ -323,11 +322,12 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
skb->len);
return 1;
}
- if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
+ foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
payload_length - 8, -1,
skb->data + payload_offset,
skb->data + payload_offset +
- payload_length - 4))) {
+ payload_length - 4);
+ if (foo) {
/* de-wep failed, drop skb. */
pr_debug("Host de-WEP failed, dropping frame (%d).\n",
foo);
diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h
index 0c62df19fa7..6fe163be24f 100644
--- a/drivers/staging/wlan-ng/p80211conv.h
+++ b/drivers/staging/wlan-ng/p80211conv.h
@@ -153,8 +153,8 @@ struct wlandevice;
int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
struct sk_buff *skb);
int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
- struct sk_buff *skb, p80211_hdr_t * p80211_hdr,
- p80211_metawep_t * p80211_wep);
+ struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep);
int p80211_stt_findproto(u16 proto);
diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h
index da8b6f53c74..0ccfba1294d 100644
--- a/drivers/staging/wlan-ng/p80211metadef.h
+++ b/drivers/staging/wlan-ng/p80211metadef.h
@@ -190,9 +190,9 @@
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1))
#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(1) | \
- P80211DID_MKITEM(1) | 0x18000000)
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x18000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1) | \
@@ -210,18 +210,18 @@
P80211DID_MKGROUP(1) | \
P80211DID_MKITEM(5) | 0x18000000)
#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(1) | \
- P80211DID_MKITEM(6) | 0x10000000)
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(6) | 0x10000000)
#define DIDmib_cat_dot11phy \
P80211DID_MKSECTION(3)
#define DIDmib_dot11phy_dot11PhyOperationTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1))
#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(3) | \
- P80211DID_MKITEM(10) | 0x18000000)
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(10) | 0x18000000)
#define DIDmib_dot11phy_dot11PhyDSSSTable \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5))
diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h
index 14cdc86d167..deb52f5fd78 100644
--- a/drivers/staging/wlan-ng/p80211mgmt.h
+++ b/drivers/staging/wlan-ng/p80211mgmt.h
@@ -100,7 +100,7 @@
#ifndef _P80211MGMT_H
#define _P80211MGMT_H
-#ifndef _P80211HDR_H
+#ifndef _P80211HDR_H
#include "p80211hdr.h"
#endif
@@ -496,25 +496,25 @@ typedef struct wlan_fr_deauthen {
} wlan_fr_deauthen_t;
-void wlan_mgmt_encode_beacon(wlan_fr_beacon_t * f);
-void wlan_mgmt_decode_beacon(wlan_fr_beacon_t * f);
-void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t * f);
-void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t * f);
-void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t * f);
-void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t * f);
-void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t * f);
-void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t * f);
-void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t * f);
-void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f);
-void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t * f);
-void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t * f);
-void wlan_mgmt_encode_probereq(wlan_fr_probereq_t * f);
-void wlan_mgmt_decode_probereq(wlan_fr_probereq_t * f);
-void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t * f);
-void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t * f);
-void wlan_mgmt_encode_authen(wlan_fr_authen_t * f);
-void wlan_mgmt_decode_authen(wlan_fr_authen_t * f);
-void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t * f);
-void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t * f);
+void wlan_mgmt_encode_beacon(wlan_fr_beacon_t *f);
+void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f);
+void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t *f);
+void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f);
+void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t *f);
+void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f);
+void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t *f);
+void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f);
+void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t *f);
+void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f);
+void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t *f);
+void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f);
+void wlan_mgmt_encode_probereq(wlan_fr_probereq_t *f);
+void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f);
+void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t *f);
+void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f);
+void wlan_mgmt_encode_authen(wlan_fr_authen_t *f);
+void wlan_mgmt_decode_authen(wlan_fr_authen_t *f);
+void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t *f);
+void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f);
#endif /* _P80211MGMT_H */
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 22424c8903e..763ab1187a1 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -586,7 +586,8 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
}
/* Allocate a buf of size req->len */
- if ((msgbuf = kmalloc(req->len, GFP_KERNEL))) {
+ msgbuf = kmalloc(req->len, GFP_KERNEL);
+ if (msgbuf) {
if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
result = -EFAULT;
else
@@ -646,7 +647,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
/* Set up some convenience pointers. */
mibattr = &dot11req.mibattribute;
- macaddr = (p80211item_pstr6_t *) & mibattr->data;
+ macaddr = (p80211item_pstr6_t *) &mibattr->data;
resultcode = &dot11req.resultcode;
/* Set up a dot11req_mibset */
@@ -674,7 +675,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
resultcode->data = 0;
/* now fire the request */
- result = p80211req_dorequest(dev->ml_priv, (u8 *) & dot11req);
+ result = p80211req_dorequest(dev->ml_priv, (u8 *) &dot11req);
/* If the request wasn't successful, report an error and don't
* change the netdev address
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
index 8bd9dfb3b9b..3c8c6480056 100644
--- a/drivers/staging/wlan-ng/p80211netdev.h
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -179,16 +179,16 @@ typedef struct wlandevice {
unsigned int ethconv;
/* device methods (init by MSD, used by p80211 */
- int (*open) (struct wlandevice * wlandev);
- int (*close) (struct wlandevice * wlandev);
- void (*reset) (struct wlandevice * wlandev);
- int (*txframe) (struct wlandevice * wlandev, struct sk_buff * skb,
- p80211_hdr_t * p80211_hdr,
- p80211_metawep_t * p80211_wep);
- int (*mlmerequest) (struct wlandevice * wlandev, p80211msg_t * msg);
- int (*set_multicast_list) (struct wlandevice * wlandev,
- netdevice_t * dev);
- void (*tx_timeout) (struct wlandevice * wlandev);
+ int (*open) (struct wlandevice *wlandev);
+ int (*close) (struct wlandevice *wlandev);
+ void (*reset) (struct wlandevice *wlandev);
+ int (*txframe) (struct wlandevice *wlandev, struct sk_buff *skb,
+ p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep);
+ int (*mlmerequest) (struct wlandevice *wlandev, p80211msg_t *msg);
+ int (*set_multicast_list) (struct wlandevice *wlandev,
+ netdevice_t *dev);
+ void (*tx_timeout) (struct wlandevice *wlandev);
/* 802.11 State */
u8 bssid[WLAN_BSSID_LEN];
@@ -227,16 +227,16 @@ typedef struct wlandevice {
} wlandevice_t;
/* WEP stuff */
-int wep_change_key(wlandevice_t * wlandev, int keynum, u8 * key, int keylen);
-int wep_decrypt(wlandevice_t * wlandev, u8 * buf, u32 len, int key_override,
- u8 * iv, u8 * icv);
-int wep_encrypt(wlandevice_t * wlandev, u8 * buf, u8 * dst, u32 len, int keynum,
- u8 * iv, u8 * icv);
-
-int wlan_setup(wlandevice_t * wlandev);
-int wlan_unsetup(wlandevice_t * wlandev);
-int register_wlandev(wlandevice_t * wlandev);
-int unregister_wlandev(wlandevice_t * wlandev);
-void p80211netdev_rx(wlandevice_t * wlandev, struct sk_buff *skb);
-void p80211netdev_hwremoved(wlandevice_t * wlandev);
+int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen);
+int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
+ u8 *iv, u8 *icv);
+int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
+ u8 *iv, u8 *icv);
+
+int wlan_setup(wlandevice_t *wlandev);
+int wlan_unsetup(wlandevice_t *wlandev);
+int register_wlandev(wlandevice_t *wlandev);
+int unregister_wlandev(wlandevice_t *wlandev);
+void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void p80211netdev_hwremoved(wlandevice_t *wlandev);
#endif
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index c88156cdf68..e1e7bf1bf27 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -55,7 +55,6 @@
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -94,7 +93,7 @@ static int p80211req_mibset_mibget(wlandevice_t *wlandev,
* Potentially blocks the caller, so it's a good idea to
* not call this function from an interrupt context.
----------------------------------------------------------------*/
-int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf)
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
{
int result = 0;
p80211msg_t *msg = (p80211msg_t *) msgbuf;
diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h
index 5d9176762ba..a95a45a6814 100644
--- a/drivers/staging/wlan-ng/p80211req.h
+++ b/drivers/staging/wlan-ng/p80211req.h
@@ -48,6 +48,6 @@
#ifndef _LINUX_P80211REQ_H
#define _LINUX_P80211REQ_H
-int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf);
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
#endif
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
index 2b83ab0c711..41a99c59c6c 100644
--- a/drivers/staging/wlan-ng/p80211types.h
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -168,12 +168,12 @@
P80211DID_MASK_ISTABLE, \
P80211DID_LSB_ISTABLE)
-#define P80211DID_MKID(s,g,i,n,t,a) (P80211DID_MKSECTION(s) | \
- P80211DID_MKGROUP(g) | \
- P80211DID_MKITEM(i) | \
- P80211DID_MKINDEX(n) | \
- P80211DID_MKISTABLE(t) | \
- (a))
+#define P80211DID_MKID(s, g, i, n, t, a) (P80211DID_MKSECTION(s) | \
+ P80211DID_MKGROUP(g) | \
+ P80211DID_MKITEM(i) | \
+ P80211DID_MKINDEX(n) | \
+ P80211DID_MKISTABLE(t) | \
+ (a))
#define P80211DID_GET(a, m, l) ((((u32)(a)) >> (l)) & (m))
@@ -340,11 +340,11 @@ struct catlistitem;
/* metadata items. Some components may choose to use more, */
/* less or different metadata items. */
-typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 * itembuf,
+typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 *itembuf,
char *textbuf);
-typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 * itembuf,
+typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 *itembuf,
char *textbuf);
-typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 * itembuf);
+typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 *itembuf);
/*----------------------------------------------------------------*/
/* Enumeration Lists */
diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c
index ecbb15b297a..80c2d3b672b 100644
--- a/drivers/staging/wlan-ng/p80211wep.c
+++ b/drivers/staging/wlan-ng/p80211wep.c
@@ -50,7 +50,6 @@
#include <linux/netdevice.h>
#include <linux/wireless.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/kernel.h>
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
index 74d8022adb2..83f1d6cd799 100644
--- a/drivers/staging/wlan-ng/p80211wext.c
+++ b/drivers/staging/wlan-ng/p80211wext.c
@@ -40,14 +40,13 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <linux/if_arp.h>
-#include <asm/bitops.h>
-#include <asm/uaccess.h>
+#include <linux/bitops.h>
+#include <linux/uaccess.h>
#include <asm/byteorder.h>
#include <linux/if_ether.h>
#include <linux/bitops.h>
@@ -134,10 +133,11 @@ static int p80211wext_dorequest(wlandevice_t *wlandev, u32 did, u32 data)
int result;
msg.msgcode = DIDmsg_dot11req_mibset;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did = did;
mibitem.data = data;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
return result;
}
@@ -174,7 +174,7 @@ static int p80211wext_autojoin(wlandevice_t *wlandev)
memcpy(msg.ssid.data.data, ssid, data.length);
msg.ssid.data.len = data.length;
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -211,7 +211,7 @@ struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t *dev)
if (wlandev->mlmerequest == NULL)
return NULL;
- retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) & quality);
+ retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) &quality);
wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */
wstats->qual.level = quality.level.data; /* instant signal level */
@@ -269,9 +269,10 @@ static int p80211wext_giwfreq(netdevice_t *dev,
int err = 0;
msg.msgcode = DIDmsg_dot11req_mibget;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -309,6 +310,7 @@ static int p80211wext_siwfreq(netdevice_t *dev,
}
msg.msgcode = DIDmsg_dot11req_mibset;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
mibitem.status = P80211ENUM_msgitem_status_data_ok;
@@ -318,7 +320,7 @@ static int p80211wext_siwfreq(netdevice_t *dev,
mibitem.data = p80211_mhz_to_channel(freq->m);
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -396,10 +398,11 @@ static int p80211wext_siwmode(netdevice_t *dev,
/* Set Operation mode to the PORT TYPE RID */
msg.msgcode = DIDmsg_dot11req_mibset;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result)
err = -EFAULT;
@@ -549,14 +552,14 @@ static int p80211wext_siwencode(netdevice_t *dev,
}
/* Check the Key index first. */
- if ((i = (erq->flags & IW_ENCODE_INDEX))) {
-
+ i = (erq->flags & IW_ENCODE_INDEX);
+ if (i) {
if ((i < 1) || (i > NUM_WEPKEYS)) {
err = -EINVAL;
goto exit;
- } else
+ } else {
i--;
-
+ }
/* Set current key number only if no keys are given */
if (erq->flags & IW_ENCODE_NOKEY) {
result =
@@ -621,7 +624,7 @@ static int p80211wext_siwencode(netdevice_t *dev,
msg.msgcode = DIDmsg_dot11req_mibset;
memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -729,7 +732,7 @@ static int p80211wext_siwessid(netdevice_t *dev,
msg.ssid.data.len = length;
pr_debug("autojoin_ssid for %s \n", essid);
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
pr_debug("autojoin_ssid %d\n", result);
if (result) {
@@ -771,9 +774,10 @@ static int p80211wext_giwrate(netdevice_t *dev,
int err = 0;
msg.msgcode = DIDmsg_dot11req_mibget;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -822,9 +826,10 @@ static int p80211wext_giwrts(netdevice_t *dev,
int err = 0;
msg.msgcode = DIDmsg_dot11req_mibget;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -857,6 +862,7 @@ static int p80211wext_siwrts(netdevice_t *dev,
}
msg.msgcode = DIDmsg_dot11req_mibget;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
if (rts->disabled)
mibitem.data = 2347;
@@ -864,7 +870,7 @@ static int p80211wext_siwrts(netdevice_t *dev,
mibitem.data = rts->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -886,10 +892,11 @@ static int p80211wext_giwfrag(netdevice_t *dev,
int err = 0;
msg.msgcode = DIDmsg_dot11req_mibget;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did =
DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -922,6 +929,7 @@ static int p80211wext_siwfrag(netdevice_t *dev,
}
msg.msgcode = DIDmsg_dot11req_mibset;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did =
DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
@@ -931,7 +939,7 @@ static int p80211wext_siwfrag(netdevice_t *dev,
mibitem.data = frag->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -962,10 +970,11 @@ static int p80211wext_giwretry(netdevice_t *dev,
u16 shortretry, longretry, lifetime;
msg.msgcode = DIDmsg_dot11req_mibget;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -979,7 +988,7 @@ static int p80211wext_giwretry(netdevice_t *dev,
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -994,7 +1003,7 @@ static int p80211wext_giwretry(netdevice_t *dev,
DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -1037,6 +1046,8 @@ static int p80211wext_siwretry(netdevice_t *dev,
int result;
int err = 0;
+ memset(&mibitem, 0, sizeof(mibitem));
+
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -1055,7 +1066,7 @@ static int p80211wext_siwretry(netdevice_t *dev,
mibitem.data = rrq->value /= 1024;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -1069,7 +1080,7 @@ static int p80211wext_siwretry(netdevice_t *dev,
memcpy(&msg.mibattribute.data, &mibitem,
sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -1084,7 +1095,7 @@ static int p80211wext_siwretry(netdevice_t *dev,
memcpy(&msg.mibattribute.data, &mibitem,
sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -1114,6 +1125,7 @@ static int p80211wext_siwtxpow(netdevice_t *dev,
}
msg.msgcode = DIDmsg_dot11req_mibset;
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did =
DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
if (rrq->fixed == 0)
@@ -1121,7 +1133,7 @@ static int p80211wext_siwtxpow(netdevice_t *dev,
else
mibitem.data = rrq->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -1143,11 +1155,13 @@ static int p80211wext_giwtxpow(netdevice_t *dev,
int err = 0;
msg.msgcode = DIDmsg_dot11req_mibget;
+
+ memset(&mibitem, 0, sizeof(mibitem));
mibitem.did =
DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result) {
err = -EFAULT;
@@ -1295,7 +1309,7 @@ static int p80211wext_siwscan(netdevice_t *dev,
msg.maxchanneltime.data = 250;
msg.minchanneltime.data = 200;
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if (result)
err = prism2_result2err(msg.resultcode.data);
@@ -1414,7 +1428,7 @@ static int p80211wext_giwscan(netdevice_t *dev,
msg.msgcode = DIDmsg_dot11req_scan_results;
msg.bssindex.data = i;
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
if ((result != 0) ||
(msg.resultcode.data != P80211ENUM_resultcode_success)) {
break;
@@ -1489,7 +1503,7 @@ static int p80211wext_set_encodeext(struct net_device *dev,
memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
memset(&msg, 0, sizeof(msg));
- pstr = (p80211item_pstr32_t *) & msg.mibattribute.data;
+ pstr = (p80211item_pstr32_t *) &msg.mibattribute.data;
memcpy(pstr->data.data, ext->key, ext->key_len);
pstr->data.len = ext->key_len;
switch (idx) {
@@ -1513,7 +1527,7 @@ static int p80211wext_set_encodeext(struct net_device *dev,
break;
}
msg.msgcode = DIDmsg_dot11req_mibset;
- result = p80211req_dorequest(wlandev, (u8 *) & msg);
+ result = p80211req_dorequest(wlandev, (u8 *) &msg);
pr_debug("result (%d)\n", result);
}
return result;
@@ -1729,15 +1743,11 @@ static iw_handler p80211wext_handlers[] = {
struct iw_handler_def p80211wext_handler_def = {
.num_standard = ARRAY_SIZE(p80211wext_handlers),
- .num_private = 0,
- .num_private_args = 0,
.standard = p80211wext_handlers,
- .private = NULL,
- .private_args = NULL,
.get_wireless_stats = p80211wext_get_wireless_stats
};
-int p80211wext_event_associated(wlandevice_t * wlandev, int assoc)
+int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
{
union iwreq_data data;
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c
index aaa70ed5771..d383ea85c9b 100644
--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -48,11 +48,13 @@
/*================================================================*/
/* System Includes */
#include <linux/ihex.h>
+#include <linux/slab.h>
/*================================================================*/
/* Local Constants */
#define PRISM2_USB_FWFILE "prism2_ru.fw"
+MODULE_FIRMWARE(PRISM2_USB_FWFILE);
#define S3DATA_MAX 5000
#define S3PLUG_MAX 200
@@ -108,9 +110,9 @@ typedef struct pda {
} pda_t;
typedef struct imgchunk {
- u32 addr; /* start address */
- u32 len; /* in bytes */
- u16 crc; /* CRC value (if it falls at a chunk boundary) */
+ u32 addr; /* start address */
+ u32 len; /* in bytes */
+ u16 crc; /* CRC value (if it falls at a chunk boundary) */
u8 *data;
} imgchunk_t;
@@ -204,7 +206,7 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev)
return 1;
}
- printk(KERN_INFO "prism2_usb: %s will be processed, size %d\n",
+ printk(KERN_INFO "prism2_usb: %s will be processed, size %zu\n",
PRISM2_USB_FWFILE, fw_entry->size);
prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev);
@@ -264,7 +266,7 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
/* Build the PDA we're going to use. */
if (read_cardpda(&pda, wlandev)) {
printk(KERN_ERR "load_cardpda failed, exiting.\n");
- return (1);
+ return 1;
}
/* read the card's PRI-SUP */
@@ -286,9 +288,8 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
/* DIDmsg_dot11req_mibget */
prism2mgmt_mibset_mibget(wlandev, &getmsg);
- if (getmsg.resultcode.data != P80211ENUM_resultcode_success) {
+ if (getmsg.resultcode.data != P80211ENUM_resultcode_success)
printk(KERN_ERR "Couldn't fetch PRI-SUP info\n");
- }
/* Already in host order */
priid.role = *data++;
@@ -301,19 +302,19 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
result = read_fwfile(rfptr);
if (result) {
printk(KERN_ERR "Failed to read the data exiting.\n");
- return (1);
+ return 1;
}
result = validate_identity();
if (result) {
printk(KERN_ERR "Incompatible firmware image.\n");
- return (1);
+ return 1;
}
if (startaddr == 0x00000000) {
printk(KERN_ERR "Can't RAM download a Flash image!\n");
- return (1);
+ return 1;
}
/* Make the image chunks */
@@ -323,20 +324,20 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
result = plugimage(fchunk, nfchunks, s3plug, ns3plug, &pda);
if (result) {
printk(KERN_ERR "Failed to plug data.\n");
- return (1);
+ return 1;
}
/* Insert any CRCs */
if (crcimage(fchunk, nfchunks, s3crc, ns3crc)) {
printk(KERN_ERR "Failed to insert all CRCs\n");
- return (1);
+ return 1;
}
/* Write the image */
result = writeimage(wlandev, fchunk, nfchunks);
if (result) {
printk(KERN_ERR "Failed to ramwrite image data.\n");
- return (1);
+ return 1;
}
/* clear any allocated memory */
@@ -434,9 +435,8 @@ void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks)
{
int i;
for (i = 0; i < *nfchunks; i++) {
- if (fchunk[i].data != NULL) {
+ if (fchunk[i].data != NULL)
kfree(fchunk[i].data);
- }
}
*nfchunks = 0;
memset(fchunk, 0, sizeof(*fchunk));
@@ -531,7 +531,7 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt)
if (clist[i].data == NULL) {
printk(KERN_ERR
"failed to allocate image space, exitting.\n");
- return (1);
+ return 1;
}
memset(clist[i].data, 0, clist[i].len);
pr_debug("chunk[%d]: addr=0x%06x len=%d\n",
@@ -545,15 +545,14 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt)
for (j = 0; j < *ccnt; j++) {
cstart = clist[j].addr;
cend = cstart + clist[j].len - 1;
- if (s3start >= cstart && s3end <= cend) {
+ if (s3start >= cstart && s3end <= cend)
break;
- }
}
if (((unsigned int)j) >= (*ccnt)) {
printk(KERN_ERR
"s3rec(a=0x%06x,l=%d), no chunk match, exiting.\n",
s3start, s3data[i].len);
- return (1);
+ return 1;
}
coffset = s3start - cstart;
memcpy(clist[j].data + coffset, s3data[i].data, s3data[i].len);
@@ -586,7 +585,7 @@ int mkpdrlist(pda_t *pda)
curroff = 0;
while (curroff < (HFA384x_PDA_LEN_MAX / 2) &&
le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) {
- pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]);
+ pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]);
if (le16_to_cpu(pda->rec[pda->nrec]->code) == HFA384x_PDR_NICID) {
memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid,
@@ -623,10 +622,10 @@ int mkpdrlist(pda_t *pda)
printk(KERN_ERR
"no end record found or invalid lengths in "
"PDR data, exiting. %x %d\n", curroff, pda->nrec);
- return (1);
+ return 1;
}
if (le16_to_cpu(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA) {
- pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]);
+ pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]);
(pda->nrec)++;
}
return result;
@@ -869,7 +868,7 @@ int read_fwfile(const struct ihex_binrec *record)
ptr16 = (u16 *) record->data;
/* parse what was an S3 srec and put it in the right array */
- switch(addr) {
+ switch (addr) {
case S3ADDR_START:
startaddr = *ptr32;
pr_debug(" S7 start addr, record=%d "
@@ -890,7 +889,7 @@ int read_fwfile(const struct ihex_binrec *record)
s3plug[ns3plug].len);
ns3plug++;
- if ( ns3plug == S3PLUG_MAX ) {
+ if (ns3plug == S3PLUG_MAX) {
printk(KERN_ERR "S3 plugrec limit reached - aborting\n");
return 1;
}
@@ -907,7 +906,7 @@ int read_fwfile(const struct ihex_binrec *record)
s3crc[ns3crc].len,
s3crc[ns3crc].dowrite);
ns3crc++;
- if ( ns3crc == S3CRC_MAX ) {
+ if (ns3crc == S3CRC_MAX) {
printk(KERN_ERR "S3 crcrec limit reached - aborting\n");
return 1;
}
@@ -921,12 +920,12 @@ int read_fwfile(const struct ihex_binrec *record)
rcnt,
s3info[ns3info].len,
s3info[ns3info].type);
- if ( ((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info) ) {
+ if (((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info)) {
printk(KERN_ERR " S3 inforec length too long - aborting\n");
return 1;
}
- tmpinfo = (u16*)&(s3info[ns3info].info.version);
+ tmpinfo = (u16 *)&(s3info[ns3info].info.version);
pr_debug(" info=");
for (i = 0; i < s3info[ns3info].len - 1; i++) {
tmpinfo[i] = *(ptr16 + 2 + i);
@@ -935,7 +934,7 @@ int read_fwfile(const struct ihex_binrec *record)
pr_debug("\n");
ns3info++;
- if ( ns3info == S3INFO_MAX ) {
+ if (ns3info == S3INFO_MAX) {
printk(KERN_ERR "S3 inforec limit reached - aborting\n");
return 1;
}
@@ -945,7 +944,7 @@ int read_fwfile(const struct ihex_binrec *record)
s3data[ns3data].len = len;
s3data[ns3data].data = (uint8_t *) record->data;
ns3data++;
- if ( ns3data == S3DATA_MAX ) {
+ if (ns3data == S3DATA_MAX) {
printk(KERN_ERR "S3 datarec limit reached - aborting\n");
return 1;
}
@@ -1023,7 +1022,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
rstatemsg.enable.data = P80211ENUM_truth_true;
rstatemsg.exeaddr.data = startaddr;
- msgp = (p80211msg_t *) & rstatemsg;
+ msgp = (p80211msg_t *) &rstatemsg;
result = prism2mgmt_ramdl_state(wlandev, msgp);
if (result) {
printk(KERN_ERR
@@ -1063,7 +1062,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
("Sending xxxdl_write message addr=%06x len=%d.\n",
currdaddr, currlen);
- msgp = (p80211msg_t *) & rwritemsg;
+ msgp = (p80211msg_t *) &rwritemsg;
result = prism2mgmt_ramdl_write(wlandev, msgp);
/* Check the results */
@@ -1090,7 +1089,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
rstatemsg.enable.data = P80211ENUM_truth_false;
rstatemsg.exeaddr.data = 0;
- msgp = (p80211msg_t *) & rstatemsg;
+ msgp = (p80211msg_t *) &rstatemsg;
result = prism2mgmt_ramdl_state(wlandev, msgp);
if (result) {
printk(KERN_ERR
@@ -1161,7 +1160,7 @@ int validate_identity(void)
/* SEC compat range */
if ((s3info[i].info.compat.role == 1) &&
(s3info[i].info.compat.id == 4)) {
-
+ /* FIXME: isn't something missing here? */
}
break;
@@ -1196,8 +1195,9 @@ int validate_identity(void)
pr_debug("Unknown inforec type %d\n", s3info[i].type);
}
}
- // walk through
+ /* walk through */
- if (trump && (result != 2)) result = 0;
+ if (trump && (result != 2))
+ result = 0;
return result;
}
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index 9f7d96cae8e..4d1cdfc3542 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -63,11 +63,10 @@
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/byteorder.h>
#include <linux/random.h>
#include <linux/usb.h>
@@ -541,7 +540,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
/*** STATION ***/
/* Set the REQUIRED config items */
/* SSID */
- pstr = (p80211pstrd_t *) & (msg->ssid.data);
+ pstr = (p80211pstrd_t *) &(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
@@ -1034,7 +1033,7 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
/* Set the ssid */
memset(bytebuf, 0, 256);
- pstr = (p80211pstrd_t *) & (msg->ssid.data);
+ pstr = (p80211pstrd_t *) &(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
bytebuf,
@@ -1123,8 +1122,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
if (hw->presniff_port_type != 0) {
word = hw->presniff_port_type;
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFPORTTYPE,
- word);
+ HFA384x_RID_CNFPORTTYPE,
+ word);
if (result) {
pr_debug
("failed to restore porttype, result=%d\n",
@@ -1156,10 +1155,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
if (wlandev->netdev->type == ARPHRD_ETHER) {
/* Save macport 0 state */
result = hfa384x_drvr_getconfig16(hw,
- HFA384x_RID_CNFPORTTYPE,
- &
- (hw->
- presniff_port_type));
+ HFA384x_RID_CNFPORTTYPE,
+ &(hw->presniff_port_type));
if (result) {
pr_debug
("failed to read porttype, result=%d\n",
@@ -1168,10 +1165,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
}
/* Save the wepflags state */
result = hfa384x_drvr_getconfig16(hw,
- HFA384x_RID_CNFWEPFLAGS,
- &
- (hw->
- presniff_wepflags));
+ HFA384x_RID_CNFWEPFLAGS,
+ &(hw->presniff_wepflags));
if (result) {
pr_debug
("failed to read wepflags, result=%d\n",
@@ -1218,8 +1213,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* Set the port type to pIbss */
word = HFA384x_PORTTYPE_PSUEDOIBSS;
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFPORTTYPE,
- word);
+ HFA384x_RID_CNFPORTTYPE,
+ word);
if (result) {
pr_debug
("failed to set porttype %d, result=%d\n",
@@ -1235,8 +1230,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
result =
hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFWEPFLAGS,
- word);
+ HFA384x_RID_CNFWEPFLAGS,
+ word);
}
if (result) {
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
index bdf2b3e0325..07eecebeb6c 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.h
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -63,43 +63,43 @@
extern int prism2_reset_holdtime;
extern int prism2_reset_settletime;
-u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate);
+u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
-void prism2sta_ev_info(wlandevice_t * wlandev, hfa384x_InfFrame_t * inf);
-void prism2sta_ev_txexc(wlandevice_t * wlandev, u16 status);
-void prism2sta_ev_tx(wlandevice_t * wlandev, u16 status);
-void prism2sta_ev_rx(wlandevice_t * wlandev, struct sk_buff *skb);
-void prism2sta_ev_alloc(wlandevice_t * wlandev);
+void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void prism2sta_ev_alloc(wlandevice_t *wlandev);
-int prism2mgmt_mibset_mibget(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_scan(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_scan_results(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_start(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_wlansniff(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_readpda(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_ramdl_state(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_ramdl_write(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_flashdl_state(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_flashdl_write(wlandevice_t * wlandev, void *msgp);
-int prism2mgmt_autojoin(wlandevice_t * wlandev, void *msgp);
+int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_start(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp);
/*---------------------------------------------------------------
* conversion functions going between wlan message data types and
* Prism2 data types
---------------------------------------------------------------*/
/* byte area conversion functions*/
-void prism2mgmt_pstr2bytearea(u8 * bytearea, p80211pstrd_t * pstr);
-void prism2mgmt_bytearea2pstr(u8 * bytearea, p80211pstrd_t * pstr, int len);
+void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr);
+void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len);
/* byte string conversion functions*/
-void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr);
-void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr);
+void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
+void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
/* functions to convert Group Addresses */
-void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t * pstr, hfa384x_t * priv);
+void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv);
int prism2mgmt_set_grpaddr(u32 did,
- u8 * prism2buf, p80211pstrd_t * pstr,
- hfa384x_t * priv);
+ u8 *prism2buf, p80211pstrd_t *pstr,
+ hfa384x_t *priv);
int prism2mgmt_get_grpaddr_index(u32 did);
void prism2sta_processing_defer(struct work_struct *data);
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
index 2fff0a110bc..0b0ec9c59a5 100644
--- a/drivers/staging/wlan-ng/prism2mib.c
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -54,7 +54,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/io.h>
@@ -114,7 +113,7 @@ static int prism2mib_flag(mibrec_t *mib,
static int prism2mib_wepdefaultkey(mibrec_t *mib,
int isget,
- wlandevice_t * wlandev,
+ wlandevice_t *wlandev,
hfa384x_t *hw,
p80211msg_dot11req_mibset_t *msg,
void *data);
@@ -726,7 +725,7 @@ static int prism2mib_priv(mibrec_t *mib,
if (isget) {
hfa384x_drvr_getconfig(hw,
HFA384x_RID_CNFWPADATA,
- (u8 *) & wpa,
+ (u8 *) &wpa,
sizeof(wpa));
pstr->len = le16_to_cpu(wpa.datalen);
memcpy(pstr->data, wpa.data, pstr->len);
@@ -736,9 +735,9 @@ static int prism2mib_priv(mibrec_t *mib,
result =
hfa384x_drvr_setconfig(hw,
- HFA384x_RID_CNFWPADATA,
- (u8 *) & wpa,
- sizeof(wpa));
+ HFA384x_RID_CNFWPADATA,
+ (u8 *) &wpa,
+ sizeof(wpa));
}
break;
}
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index 50f301d6521..31ac8da39c8 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -64,7 +64,7 @@
#include <linux/byteorder/generic.h>
#include <linux/ctype.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <asm/byteorder.h>
#include <linux/if_arp.h>
@@ -1023,13 +1023,13 @@ static void prism2sta_inf_tallies(wlandevice_t *wlandev,
cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32);
if (inf->framelen > 22) {
- dst = (u32 *) & hw->tallies;
- src32 = (u32 *) & inf->info.commtallies32;
+ dst = (u32 *) &hw->tallies;
+ src32 = (u32 *) &inf->info.commtallies32;
for (i = 0; i < cnt; i++, dst++, src32++)
*dst += le32_to_cpu(*src32);
} else {
- dst = (u32 *) & hw->tallies;
- src16 = (u16 *) & inf->info.commtallies16;
+ dst = (u32 *) &hw->tallies;
+ src16 = (u16 *) &inf->info.commtallies16;
for (i = 0; i < cnt; i++, dst++, src16++)
*dst += le16_to_cpu(*src16);
}
@@ -1280,7 +1280,7 @@ void prism2sta_processing_defer(struct work_struct *data)
HFA384x_RID_CURRENTSSID, result);
goto failed;
}
- prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid,
+ prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
(p80211pstrd_t *) &
wlandev->ssid);
@@ -1368,8 +1368,8 @@ void prism2sta_processing_defer(struct work_struct *data)
HFA384x_RID_CURRENTSSID, result);
goto failed;
}
- prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid,
- (p80211pstrd_t *) & wlandev->ssid);
+ prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
+ (p80211pstrd_t *) &wlandev->ssid);
hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev);
@@ -2028,8 +2028,8 @@ void prism2sta_commsqual_defer(struct work_struct *data)
HFA384x_RID_CURRENTSSID, result);
goto done;
}
- prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid,
- (p80211pstrd_t *) & wlandev->ssid);
+ prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
+ (p80211pstrd_t *) &wlandev->ssid);
/* Reschedule timer */
mod_timer(&hw->commsqual_timer, jiffies + HZ);
diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c
index 9dde68be8d7..501d27f74c7 100644
--- a/drivers/staging/wlan-ng/prism2usb.c
+++ b/drivers/staging/wlan-ng/prism2usb.c
@@ -24,8 +24,9 @@ static struct usb_device_id usb_prism_tbl[] = {
(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
{PRISM_USB_DEVICE
(0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x049f, 0x0033,
- "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
+ {PRISM_USB_DEVICE
+ (0x049f, 0x0033,
+ "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
{PRISM_USB_DEVICE
(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
{PRISM_USB_DEVICE
@@ -55,7 +56,6 @@ static struct usb_device_id usb_prism_tbl[] = {
(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
{PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
{PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
-/* {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")}, */
{PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
{PRISM_USB_DEVICE
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
index e5bd4470a57..a8aaf6ac2ae 100644
--- a/drivers/tc/tc.c
+++ b/drivers/tc/tc.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/tc.h>
#include <linux/types.h>
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 5066de5cfc0..13c72c62932 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/idr.h>
#include <linux/thermal.h>
@@ -505,6 +506,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
tz->temp_input.attr.attr.name = tz->temp_input.name;
tz->temp_input.attr.attr.mode = 0444;
tz->temp_input.attr.show = temp_input_show;
+ sysfs_attr_init(&tz->temp_input.attr.attr);
result = device_create_file(hwmon->device, &tz->temp_input.attr);
if (result)
goto unregister_hwmon_device;
@@ -517,6 +519,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
tz->temp_crit.attr.attr.name = tz->temp_crit.name;
tz->temp_crit.attr.attr.mode = 0444;
tz->temp_crit.attr.show = temp_crit_show;
+ sysfs_attr_init(&tz->temp_crit.attr.attr);
result = device_create_file(hwmon->device,
&tz->temp_crit.attr);
if (result)
@@ -725,6 +728,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
goto release_idr;
sprintf(dev->attr_name, "cdev%d_trip_point", dev->id);
+ sysfs_attr_init(&dev->attr.attr);
dev->attr.attr.name = dev->attr_name;
dev->attr.attr.mode = 0444;
dev->attr.show = thermal_cooling_device_trip_point_show;
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 8aa1955f35e..1da73ecd979 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -44,17 +44,6 @@ config UIO_PDRV_GENIRQ
If you don't know what to do here, say N.
-config UIO_SMX
- tristate "SMX cryptengine UIO interface"
- help
- Userspace IO interface to the Cryptography engine found on the
- Nias Digital SMX boards. These will be available from Q4 2008
- from http://www.niasdigital.com. The userspace part of this
- driver will be released under the GPL at the same time as the
- hardware and will be able to be downloaded from the same site.
-
- If you compile this as a module, it will be called uio_smx.
-
config UIO_AEC
tristate "AEC video timestamp device"
depends on PCI
@@ -74,6 +63,7 @@ config UIO_AEC
config UIO_SERCOS3
tristate "Automata Sercos III PCI card driver"
+ depends on PCI
help
Userspace I/O interface for the Sercos III PCI card from
Automata GmbH. The userspace part of this driver will be
@@ -87,11 +77,21 @@ config UIO_SERCOS3
config UIO_PCI_GENERIC
tristate "Generic driver for PCI 2.3 and PCI Express cards"
depends on PCI
- default n
help
Generic driver that you can bind, dynamically, to any
PCI 2.3 compliant and PCI Express card. It is useful,
primarily, for virtualization scenarios.
If you compile this as a module, it will be called uio_pci_generic.
+config UIO_NETX
+ tristate "Hilscher NetX Card driver"
+ depends on PCI
+ help
+ Driver for Hilscher NetX based fieldbus cards (cifX, comX).
+ This driver requires a userspace component that comes with the card
+ or is available from Hilscher (http://www.hilscher.com).
+
+ To compile this driver as a module, choose M here; the module
+ will be called uio_netx.
+
endif
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index 73b2e751672..18fd818c5b9 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_UIO) += uio.o
obj-$(CONFIG_UIO_CIF) += uio_cif.o
obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o
-obj-$(CONFIG_UIO_SMX) += uio_smx.o
obj-$(CONFIG_UIO_AEC) += uio_aec.o
obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o
+obj-$(CONFIG_UIO_NETX) += uio_netx.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index e941367dd28..bff1afbde5a 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/idr.h>
#include <linux/sched.h>
@@ -129,7 +130,7 @@ static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr,
return entry->show(mem, buf);
}
-static struct sysfs_ops map_sysfs_ops = {
+static const struct sysfs_ops map_sysfs_ops = {
.show = map_type_show,
};
@@ -217,7 +218,7 @@ static ssize_t portio_type_show(struct kobject *kobj, struct attribute *attr,
return entry->show(port, buf);
}
-static struct sysfs_ops portio_sysfs_ops = {
+static const struct sysfs_ops portio_sysfs_ops = {
.show = portio_type_show,
};
diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c
index b7830e9a3ba..72b22d44e8b 100644
--- a/drivers/uio/uio_aec.c
+++ b/drivers/uio/uio_aec.c
@@ -27,6 +27,7 @@
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/uio_driver.h>
+#include <linux/slab.h>
#define PCI_VENDOR_ID_AEC 0xaecb
#define PCI_DEVICE_ID_AEC_VITCLTC 0x6250
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
index 28034c81291..371f87f8bc2 100644
--- a/drivers/uio/uio_cif.c
+++ b/drivers/uio/uio_cif.c
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/uio_driver.h>
#include <asm/io.h>
diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c
new file mode 100644
index 00000000000..5a18e9f7b83
--- /dev/null
+++ b/drivers/uio/uio_netx.c
@@ -0,0 +1,173 @@
+/*
+ * UIO driver for Hilscher NetX based fieldbus cards (cifX, comX).
+ * See http://www.hilscher.com for details.
+ *
+ * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2008 Manuel Traut <manut@linutronix.de>
+ *
+ * Licensed under GPL version 2 only.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/uio_driver.h>
+
+#define PCI_VENDOR_ID_HILSCHER 0x15CF
+#define PCI_DEVICE_ID_HILSCHER_NETX 0x0000
+#define PCI_SUBDEVICE_ID_NXSB_PCA 0x3235
+#define PCI_SUBDEVICE_ID_NXPCA 0x3335
+
+#define DPM_HOST_INT_EN0 0xfff0
+#define DPM_HOST_INT_STAT0 0xffe0
+
+#define DPM_HOST_INT_MASK 0xe600ffff
+#define DPM_HOST_INT_GLOBAL_EN 0x80000000
+
+static irqreturn_t netx_handler(int irq, struct uio_info *dev_info)
+{
+ void __iomem *int_enable_reg = dev_info->mem[0].internal_addr
+ + DPM_HOST_INT_EN0;
+ void __iomem *int_status_reg = dev_info->mem[0].internal_addr
+ + DPM_HOST_INT_STAT0;
+
+ /* Is one of our interrupts enabled and active ? */
+ if (!(ioread32(int_enable_reg) & ioread32(int_status_reg)
+ & DPM_HOST_INT_MASK))
+ return IRQ_NONE;
+
+ /* Disable interrupt */
+ iowrite32(ioread32(int_enable_reg) & ~DPM_HOST_INT_GLOBAL_EN,
+ int_enable_reg);
+ return IRQ_HANDLED;
+}
+
+static int __devinit netx_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct uio_info *info;
+ int bar;
+
+ info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ if (pci_enable_device(dev))
+ goto out_free;
+
+ if (pci_request_regions(dev, "netx"))
+ goto out_disable;
+
+ switch (id->device) {
+ case PCI_DEVICE_ID_HILSCHER_NETX:
+ bar = 0;
+ info->name = "netx";
+ break;
+ default:
+ bar = 2;
+ info->name = "netx_plx";
+ }
+
+ /* BAR0 or 2 points to the card's dual port memory */
+ info->mem[0].addr = pci_resource_start(dev, bar);
+ if (!info->mem[0].addr)
+ goto out_release;
+ info->mem[0].internal_addr = ioremap(pci_resource_start(dev, bar),
+ pci_resource_len(dev, bar));
+
+ if (!info->mem[0].internal_addr)
+ goto out_release;
+
+ info->mem[0].size = pci_resource_len(dev, bar);
+ info->mem[0].memtype = UIO_MEM_PHYS;
+ info->irq = dev->irq;
+ info->irq_flags = IRQF_SHARED;
+ info->handler = netx_handler;
+ info->version = "0.0.1";
+
+ /* Make sure all interrupts are disabled */
+ iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0);
+
+ if (uio_register_device(&dev->dev, info))
+ goto out_unmap;
+
+ pci_set_drvdata(dev, info);
+ dev_info(&dev->dev, "Found %s card, registered UIO device.\n",
+ info->name);
+
+ return 0;
+
+out_unmap:
+ iounmap(info->mem[0].internal_addr);
+out_release:
+ pci_release_regions(dev);
+out_disable:
+ pci_disable_device(dev);
+out_free:
+ kfree(info);
+ return -ENODEV;
+}
+
+static void netx_pci_remove(struct pci_dev *dev)
+{
+ struct uio_info *info = pci_get_drvdata(dev);
+
+ /* Disable all interrupts */
+ iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0);
+ uio_unregister_device(info);
+ pci_release_regions(dev);
+ pci_disable_device(dev);
+ pci_set_drvdata(dev, NULL);
+ iounmap(info->mem[0].internal_addr);
+
+ kfree(info);
+}
+
+static struct pci_device_id netx_pci_ids[] = {
+ {
+ .vendor = PCI_VENDOR_ID_HILSCHER,
+ .device = PCI_DEVICE_ID_HILSCHER_NETX,
+ .subvendor = 0,
+ .subdevice = 0,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = PCI_VENDOR_ID_PLX,
+ .subdevice = PCI_SUBDEVICE_ID_NXSB_PCA,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = PCI_VENDOR_ID_PLX,
+ .subdevice = PCI_SUBDEVICE_ID_NXPCA,
+ },
+ { 0, }
+};
+
+static struct pci_driver netx_pci_driver = {
+ .name = "netx",
+ .id_table = netx_pci_ids,
+ .probe = netx_pci_probe,
+ .remove = netx_pci_remove,
+};
+
+static int __init netx_init_module(void)
+{
+ return pci_register_driver(&netx_pci_driver);
+}
+
+static void __exit netx_exit_module(void)
+{
+ pci_unregister_driver(&netx_pci_driver);
+}
+
+module_init(netx_init_module);
+module_exit(netx_exit_module);
+
+MODULE_DEVICE_TABLE(pci, netx_pci_ids);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Hans J. Koch, Manuel Traut");
diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c
index 313da35984a..85c9884a67f 100644
--- a/drivers/uio/uio_pci_generic.c
+++ b/drivers/uio/uio_pci_generic.c
@@ -22,6 +22,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/uio_driver.h>
#include <linux/spinlock.h>
diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
index d494ce9288c..7d3e469b990 100644
--- a/drivers/uio/uio_pdrv.c
+++ b/drivers/uio/uio_pdrv.c
@@ -11,6 +11,7 @@
#include <linux/platform_device.h>
#include <linux/uio_driver.h>
#include <linux/stringify.h>
+#include <linux/slab.h>
#define DRIVER_NAME "uio_pdrv"
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 1ef3b8fc50b..61e569df2bb 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/stringify.h>
#include <linux/pm_runtime.h>
+#include <linux/slab.h>
#define DRIVER_NAME "uio_pdrv_genirq"
diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c
index a6d1b2bc47f..3d461cd73e6 100644
--- a/drivers/uio/uio_sercos3.c
+++ b/drivers/uio/uio_sercos3.c
@@ -28,6 +28,7 @@
#include <linux/pci.h>
#include <linux/uio_driver.h>
#include <linux/io.h>
+#include <linux/slab.h>
/* ID's for SERCOS III PCI card (PLX 9030) */
#define SERCOS_SUB_VENDOR_ID 0x1971
diff --git a/drivers/uio/uio_smx.c b/drivers/uio/uio_smx.c
deleted file mode 100644
index 44054a650a8..00000000000
--- a/drivers/uio/uio_smx.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * UIO SMX Cryptengine driver.
- *
- * (C) 2008 Nias Digital P/L <bn@niasdigital.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/device.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/uio_driver.h>
-#include <linux/io.h>
-
-#define DRV_NAME "smx-ce"
-#define DRV_VERSION "0.03"
-
-#define SMX_CSR 0x00000000
-#define SMX_EnD 0x00000001
-#define SMX_RUN 0x00000002
-#define SMX_DRDY 0x00000004
-#define SMX_ERR 0x00000008
-
-static irqreturn_t smx_handler(int irq, struct uio_info *dev_info)
-{
- void __iomem *csr = dev_info->mem[0].internal_addr + SMX_CSR;
-
- u32 status = ioread32(csr);
-
- if (!(status & SMX_DRDY))
- return IRQ_NONE;
-
- /* Disable interrupt */
- iowrite32(status & ~SMX_DRDY, csr);
- return IRQ_HANDLED;
-}
-
-static int __devinit smx_ce_probe(struct platform_device *dev)
-{
-
- int ret = -ENODEV;
- struct uio_info *info;
- struct resource *regs;
-
- info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!regs) {
- dev_err(&dev->dev, "No memory resource specified\n");
- goto out_free;
- }
-
- info->mem[0].addr = regs->start;
- if (!info->mem[0].addr) {
- dev_err(&dev->dev, "Invalid memory resource\n");
- goto out_free;
- }
-
- info->mem[0].size = regs->end - regs->start + 1;
- info->mem[0].internal_addr = ioremap(regs->start, info->mem[0].size);
-
- if (!info->mem[0].internal_addr) {
- dev_err(&dev->dev, "Can't remap memory address range\n");
- goto out_free;
- }
-
- info->mem[0].memtype = UIO_MEM_PHYS;
-
- info->name = "smx-ce";
- info->version = "0.03";
-
- info->irq = platform_get_irq(dev, 0);
- if (info->irq < 0) {
- ret = info->irq;
- dev_err(&dev->dev, "No (or invalid) IRQ resource specified\n");
- goto out_unmap;
- }
-
- info->irq_flags = IRQF_SHARED;
- info->handler = smx_handler;
-
- platform_set_drvdata(dev, info);
-
- ret = uio_register_device(&dev->dev, info);
-
- if (ret)
- goto out_unmap;
-
- return 0;
-
-out_unmap:
- iounmap(info->mem[0].internal_addr);
-out_free:
- kfree(info);
-
- return ret;
-}
-
-static int __devexit smx_ce_remove(struct platform_device *dev)
-{
- struct uio_info *info = platform_get_drvdata(dev);
-
- uio_unregister_device(info);
- platform_set_drvdata(dev, NULL);
- iounmap(info->mem[0].internal_addr);
-
- kfree(info);
-
- return 0;
-}
-
-static struct platform_driver smx_ce_driver = {
- .probe = smx_ce_probe,
- .remove = __devexit_p(smx_ce_remove),
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-static int __init smx_ce_init_module(void)
-{
- return platform_driver_register(&smx_ce_driver);
-}
-module_init(smx_ce_init_module);
-
-static void __exit smx_ce_exit_module(void)
-{
- platform_driver_unregister(&smx_ce_driver);
-}
-module_exit(smx_ce_exit_module);
-
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
-MODULE_AUTHOR("Ben Nizette <bn@niasdigital.com>");
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 3e862401a63..1e9ba4bdffe 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -27,7 +27,6 @@
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/firmware.h>
-#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index c5395246886..25f01b536f6 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -66,6 +66,7 @@
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/freezer.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c
index 029ee4a8a1f..b6d49234e52 100644
--- a/drivers/usb/c67x00/c67x00-drv.c
+++ b/drivers/usb/c67x00/c67x00-drv.c
@@ -37,6 +37,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/c67x00.h>
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index 85dfe296566..f6b3c253f3f 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -22,6 +22,7 @@
*/
#include <linux/kthread.h>
+#include <linux/slab.h>
#include "c67x00.h"
#include "c67x00-hcd.h"
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 975d556b478..5e1a253b08a 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1441,7 +1441,7 @@ static int acm_resume(struct usb_interface *intf)
wb = acm->delayed_wb;
acm->delayed_wb = NULL;
spin_unlock_irq(&acm->write_lock);
- acm_start_wb(acm, acm->delayed_wb);
+ acm_start_wb(acm, wb);
} else {
spin_unlock_irq(&acm->write_lock);
}
@@ -1542,6 +1542,9 @@ static const struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
},
+ { USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
+ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+ },
/* Nokia S60 phones expose two ACM channels. The first is
* a modem and is picked up by the standard AT-command
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 18aafcb08fc..189141ca4e0 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -52,7 +52,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
#define WDM_READ 4
#define WDM_INT_STALL 5
#define WDM_POLL_RUNNING 6
-
+#define WDM_RESPONDING 7
+#define WDM_SUSPENDING 8
#define WDM_MAX 16
@@ -87,9 +88,7 @@ struct wdm_device {
int count;
dma_addr_t shandle;
dma_addr_t ihandle;
- struct mutex wlock;
- struct mutex rlock;
- struct mutex plock;
+ struct mutex lock;
wait_queue_head_t wait;
struct work_struct rxwork;
int werr;
@@ -117,21 +116,22 @@ static void wdm_in_callback(struct urb *urb)
int status = urb->status;
spin_lock(&desc->iuspin);
+ clear_bit(WDM_RESPONDING, &desc->flags);
if (status) {
switch (status) {
case -ENOENT:
dev_dbg(&desc->intf->dev,
"nonzero urb status received: -ENOENT");
- break;
+ goto skip_error;
case -ECONNRESET:
dev_dbg(&desc->intf->dev,
"nonzero urb status received: -ECONNRESET");
- break;
+ goto skip_error;
case -ESHUTDOWN:
dev_dbg(&desc->intf->dev,
"nonzero urb status received: -ESHUTDOWN");
- break;
+ goto skip_error;
case -EPIPE:
dev_err(&desc->intf->dev,
"nonzero urb status received: -EPIPE\n");
@@ -147,6 +147,7 @@ static void wdm_in_callback(struct urb *urb)
desc->reslength = urb->actual_length;
memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
desc->length += desc->reslength;
+skip_error:
wake_up(&desc->wait);
set_bit(WDM_READ, &desc->flags);
@@ -229,13 +230,16 @@ static void wdm_int_callback(struct urb *urb)
desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
spin_lock(&desc->iuspin);
clear_bit(WDM_READ, &desc->flags);
- if (!test_bit(WDM_DISCONNECTING, &desc->flags)) {
+ set_bit(WDM_RESPONDING, &desc->flags);
+ if (!test_bit(WDM_DISCONNECTING, &desc->flags)
+ && !test_bit(WDM_SUSPENDING, &desc->flags)) {
rv = usb_submit_urb(desc->response, GFP_ATOMIC);
dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d",
__func__, rv);
}
spin_unlock(&desc->iuspin);
if (rv < 0) {
+ clear_bit(WDM_RESPONDING, &desc->flags);
if (rv == -EPERM)
return;
if (rv == -ENOMEM) {
@@ -305,14 +309,38 @@ static ssize_t wdm_write
if (we < 0)
return -EIO;
- r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */
+ desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
+ if (!buf) {
+ rv = -ENOMEM;
+ goto outnl;
+ }
+
+ r = copy_from_user(buf, buffer, count);
+ if (r > 0) {
+ kfree(buf);
+ rv = -EFAULT;
+ goto outnl;
+ }
+
+ /* concurrent writes and disconnect */
+ r = mutex_lock_interruptible(&desc->lock);
rv = -ERESTARTSYS;
- if (r)
+ if (r) {
+ kfree(buf);
goto outnl;
+ }
+
+ if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
+ kfree(buf);
+ rv = -ENODEV;
+ goto outnp;
+ }
r = usb_autopm_get_interface(desc->intf);
- if (r < 0)
+ if (r < 0) {
+ kfree(buf);
goto outnp;
+ }
if (!file->f_flags && O_NONBLOCK)
r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
@@ -320,24 +348,8 @@ static ssize_t wdm_write
else
if (test_bit(WDM_IN_USE, &desc->flags))
r = -EAGAIN;
- if (r < 0)
- goto out;
-
- if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
- rv = -ENODEV;
- goto out;
- }
-
- desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
- if (!buf) {
- rv = -ENOMEM;
- goto out;
- }
-
- r = copy_from_user(buf, buffer, count);
- if (r > 0) {
+ if (r < 0) {
kfree(buf);
- rv = -EFAULT;
goto out;
}
@@ -374,7 +386,7 @@ static ssize_t wdm_write
out:
usb_autopm_put_interface(desc->intf);
outnp:
- mutex_unlock(&desc->wlock);
+ mutex_unlock(&desc->lock);
outnl:
return rv < 0 ? rv : count;
}
@@ -387,7 +399,7 @@ static ssize_t wdm_read
struct wdm_device *desc = file->private_data;
- rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
+ rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */
if (rv < 0)
return -ERESTARTSYS;
@@ -424,11 +436,8 @@ retry:
spin_lock_irq(&desc->iuspin);
if (desc->rerr) { /* read completed, error happened */
- int t = desc->rerr;
desc->rerr = 0;
spin_unlock_irq(&desc->iuspin);
- dev_err(&desc->intf->dev,
- "reading had resulted in %d\n", t);
rv = -EIO;
goto err;
}
@@ -465,9 +474,7 @@ retry:
rv = cntr;
err:
- mutex_unlock(&desc->rlock);
- if (rv < 0 && rv != -EAGAIN)
- dev_err(&desc->intf->dev, "wdm_read: exit error\n");
+ mutex_unlock(&desc->lock);
return rv;
}
@@ -533,7 +540,7 @@ static int wdm_open(struct inode *inode, struct file *file)
}
intf->needs_remote_wakeup = 1;
- mutex_lock(&desc->plock);
+ mutex_lock(&desc->lock);
if (!desc->count++) {
rv = usb_submit_urb(desc->validity, GFP_KERNEL);
if (rv < 0) {
@@ -544,7 +551,7 @@ static int wdm_open(struct inode *inode, struct file *file)
} else {
rv = 0;
}
- mutex_unlock(&desc->plock);
+ mutex_unlock(&desc->lock);
usb_autopm_put_interface(desc->intf);
out:
mutex_unlock(&wdm_mutex);
@@ -556,9 +563,9 @@ static int wdm_release(struct inode *inode, struct file *file)
struct wdm_device *desc = file->private_data;
mutex_lock(&wdm_mutex);
- mutex_lock(&desc->plock);
+ mutex_lock(&desc->lock);
desc->count--;
- mutex_unlock(&desc->plock);
+ mutex_unlock(&desc->lock);
if (!desc->count) {
dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
@@ -655,9 +662,7 @@ next_desc:
desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
if (!desc)
goto out;
- mutex_init(&desc->wlock);
- mutex_init(&desc->rlock);
- mutex_init(&desc->plock);
+ mutex_init(&desc->lock);
spin_lock_init(&desc->iuspin);
init_waitqueue_head(&desc->wait);
desc->wMaxCommand = maxcom;
@@ -771,14 +776,17 @@ static void wdm_disconnect(struct usb_interface *intf)
/* to terminate pending flushes */
clear_bit(WDM_IN_USE, &desc->flags);
spin_unlock_irqrestore(&desc->iuspin, flags);
- cancel_work_sync(&desc->rxwork);
+ mutex_lock(&desc->lock);
kill_urbs(desc);
+ cancel_work_sync(&desc->rxwork);
+ mutex_unlock(&desc->lock);
wake_up_all(&desc->wait);
if (!desc->count)
cleanup(desc);
mutex_unlock(&wdm_mutex);
}
+#ifdef CONFIG_PM
static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
{
struct wdm_device *desc = usb_get_intfdata(intf);
@@ -786,22 +794,30 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
- mutex_lock(&desc->plock);
-#ifdef CONFIG_PM
+ /* if this is an autosuspend the caller does the locking */
+ if (!(message.event & PM_EVENT_AUTO))
+ mutex_lock(&desc->lock);
+ spin_lock_irq(&desc->iuspin);
+
if ((message.event & PM_EVENT_AUTO) &&
- test_bit(WDM_IN_USE, &desc->flags)) {
+ (test_bit(WDM_IN_USE, &desc->flags)
+ || test_bit(WDM_RESPONDING, &desc->flags))) {
+ spin_unlock_irq(&desc->iuspin);
rv = -EBUSY;
} else {
-#endif
- cancel_work_sync(&desc->rxwork);
+
+ set_bit(WDM_SUSPENDING, &desc->flags);
+ spin_unlock_irq(&desc->iuspin);
+ /* callback submits work - order is essential */
kill_urbs(desc);
-#ifdef CONFIG_PM
+ cancel_work_sync(&desc->rxwork);
}
-#endif
- mutex_unlock(&desc->plock);
+ if (!(message.event & PM_EVENT_AUTO))
+ mutex_unlock(&desc->lock);
return rv;
}
+#endif
static int recover_from_urb_loss(struct wdm_device *desc)
{
@@ -815,23 +831,27 @@ static int recover_from_urb_loss(struct wdm_device *desc)
}
return rv;
}
+
+#ifdef CONFIG_PM
static int wdm_resume(struct usb_interface *intf)
{
struct wdm_device *desc = usb_get_intfdata(intf);
int rv;
dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
- mutex_lock(&desc->plock);
+
+ clear_bit(WDM_SUSPENDING, &desc->flags);
rv = recover_from_urb_loss(desc);
- mutex_unlock(&desc->plock);
+
return rv;
}
+#endif
static int wdm_pre_reset(struct usb_interface *intf)
{
struct wdm_device *desc = usb_get_intfdata(intf);
- mutex_lock(&desc->plock);
+ mutex_lock(&desc->lock);
return 0;
}
@@ -841,7 +861,7 @@ static int wdm_post_reset(struct usb_interface *intf)
int rv;
rv = recover_from_urb_loss(desc);
- mutex_unlock(&desc->plock);
+ mutex_unlock(&desc->lock);
return 0;
}
@@ -849,9 +869,11 @@ static struct usb_driver wdm_driver = {
.name = "cdc_wdm",
.probe = wdm_probe,
.disconnect = wdm_disconnect,
+#ifdef CONFIG_PM
.suspend = wdm_suspend,
.resume = wdm_resume,
.reset_resume = wdm_resume,
+#endif
.pre_reset = wdm_pre_reset,
.post_reset = wdm_post_reset,
.id_table = wdm_ids,
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index 8588c0937a8..3e7c1b800eb 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -25,6 +25,7 @@
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/kref.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/usb.h>
#include <linux/usb/tmc.h>
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 97a819c23ef..7e594449600 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -109,7 +109,7 @@ config USB_SUSPEND
config USB_OTG
bool
depends on USB && EXPERIMENTAL
- select USB_SUSPEND
+ depends on USB_SUSPEND
default n
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index c83c975152a..19bc03a9fec 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -50,7 +50,7 @@
#include <linux/fs.h>
#include <linux/mm.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/poll.h>
#include <linux/usb.h>
#include <linux/smp_lock.h>
@@ -117,13 +117,20 @@ static const char *format_endpt =
* However, these will come from functions that return ptrs to each of them.
*/
-static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq);
-/* guarded by usbfs_mutex */
-static unsigned int conndiscevcnt;
-
-/* this struct stores the poll state for <mountpoint>/devices pollers */
-struct usb_device_status {
- unsigned int lastev;
+/*
+ * Wait for an connect/disconnect event to happen. We initialize
+ * the event counter with an odd number, and each event will increment
+ * the event counter by two, so it will always _stay_ odd. That means
+ * that it will never be zero, so "event 0" will never match a current
+ * event, and thus 'poll' will always trigger as readable for the first
+ * time it gets called.
+ */
+static struct device_connect_event {
+ atomic_t count;
+ wait_queue_head_t wait;
+} device_event = {
+ .count = ATOMIC_INIT(1),
+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER(device_event.wait)
};
struct class_info {
@@ -157,10 +164,8 @@ static const struct class_info clas_info[] =
void usbfs_conn_disc_event(void)
{
- mutex_lock(&usbfs_mutex);
- conndiscevcnt++;
- mutex_unlock(&usbfs_mutex);
- wake_up(&deviceconndiscwq);
+ atomic_add(2, &device_event.count);
+ wake_up(&device_event.wait);
}
static const char *class_decode(const int class)
@@ -632,42 +637,16 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
static unsigned int usb_device_poll(struct file *file,
struct poll_table_struct *wait)
{
- struct usb_device_status *st;
- unsigned int mask = 0;
-
- mutex_lock(&usbfs_mutex);
- st = file->private_data;
- if (!st) {
- st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
- if (!st) {
- mutex_unlock(&usbfs_mutex);
- return POLLIN;
- }
-
- st->lastev = conndiscevcnt;
- file->private_data = st;
- mask = POLLIN;
- }
+ unsigned int event_count;
- if (file->f_mode & FMODE_READ)
- poll_wait(file, &deviceconndiscwq, wait);
- if (st->lastev != conndiscevcnt)
- mask |= POLLIN;
- st->lastev = conndiscevcnt;
- mutex_unlock(&usbfs_mutex);
- return mask;
-}
+ poll_wait(file, &device_event.wait, wait);
-static int usb_device_open(struct inode *inode, struct file *file)
-{
- file->private_data = NULL;
- return 0;
-}
+ event_count = atomic_read(&device_event.count);
+ if (file->f_version != event_count) {
+ file->f_version = event_count;
+ return POLLIN | POLLRDNORM;
+ }
-static int usb_device_release(struct inode *inode, struct file *file)
-{
- kfree(file->private_data);
- file->private_data = NULL;
return 0;
}
@@ -699,6 +678,4 @@ const struct file_operations usbfs_devices_fops = {
.llseek = usb_device_lseek,
.read = usb_device_read,
.poll = usb_device_poll,
- .open = usb_device_open,
- .release = usb_device_release,
};
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index e909ff7b909..3466fdc5bb1 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1207,6 +1207,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
free_async(as);
return -ENOMEM;
}
+ /* Isochronous input data may end up being discontiguous
+ * if some of the packets are short. Clear the buffer so
+ * that the gaps don't leak kernel data to userspace.
+ */
+ if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO)
+ memset(as->urb->transfer_buffer, 0,
+ uurb->buffer_length);
}
as->urb->dev = ps->dev;
as->urb->pipe = (uurb->type << 30) |
@@ -1345,10 +1352,14 @@ static int processcompl(struct async *as, void __user * __user *arg)
void __user *addr = as->userurb;
unsigned int i;
- if (as->userbuffer && urb->actual_length)
- if (copy_to_user(as->userbuffer, urb->transfer_buffer,
- urb->actual_length))
+ if (as->userbuffer && urb->actual_length) {
+ if (urb->number_of_packets > 0) /* Isochronous */
+ i = urb->transfer_buffer_length;
+ else /* Non-Isoc */
+ i = urb->actual_length;
+ if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
goto err_out;
+ }
if (put_user(as->status, &userurb->status))
goto err_out;
if (put_user(urb->actual_length, &userurb->actual_length))
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index a7037bf8168..2f3dc4cdf79 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -23,6 +23,7 @@
*/
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/quirks.h>
#include <linux/pm_runtime.h>
@@ -300,7 +301,7 @@ static int usb_probe_interface(struct device *dev)
intf->condition = USB_INTERFACE_BINDING;
- /* Bound interfaces are initially active. They are
+ /* Probed interfaces are initially active. They are
* runtime-PM-enabled only if the driver has autosuspend support.
* They are sensitive to their children's power states.
*/
@@ -436,11 +437,11 @@ int usb_driver_claim_interface(struct usb_driver *driver,
iface->condition = USB_INTERFACE_BOUND;
- /* Bound interfaces are initially active. They are
+ /* Claimed interfaces are initially inactive (suspended). They are
* runtime-PM-enabled only if the driver has autosuspend support.
* They are sensitive to their children's power states.
*/
- pm_runtime_set_active(dev);
+ pm_runtime_set_suspended(dev);
pm_suspend_ignore_children(dev, false);
if (driver->supports_autosuspend)
pm_runtime_enable(dev);
@@ -489,10 +490,10 @@ void usb_driver_release_interface(struct usb_driver *driver,
if (device_is_registered(dev)) {
device_release_driver(dev);
} else {
- down(&dev->sem);
+ device_lock(dev);
usb_unbind_interface(dev);
dev->driver = NULL;
- up(&dev->sem);
+ device_unlock(dev);
}
}
EXPORT_SYMBOL_GPL(usb_driver_release_interface);
@@ -1169,7 +1170,7 @@ done:
static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
{
int status = 0;
- int i = 0;
+ int i = 0, n = 0;
struct usb_interface *intf;
if (udev->state == USB_STATE_NOTATTACHED ||
@@ -1178,7 +1179,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
/* Suspend all the interfaces and then udev itself */
if (udev->actconfig) {
- for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
+ n = udev->actconfig->desc.bNumInterfaces;
+ for (i = n - 1; i >= 0; --i) {
intf = udev->actconfig->interface[i];
status = usb_suspend_interface(udev, intf, msg);
if (status != 0)
@@ -1191,7 +1193,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
/* If the suspend failed, resume interfaces that did get suspended */
if (status != 0) {
msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
- while (--i >= 0) {
+ while (++i < n) {
intf = udev->actconfig->interface[i];
usb_resume_interface(udev, intf, msg, 0);
}
@@ -1262,13 +1264,47 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
return status;
}
+static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
+{
+ int w, i;
+ struct usb_interface *intf;
+
+ /* Remote wakeup is needed only when we actually go to sleep.
+ * For things like FREEZE and QUIESCE, if the device is already
+ * autosuspended then its current wakeup setting is okay.
+ */
+ if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) {
+ if (udev->state != USB_STATE_SUSPENDED)
+ udev->do_remote_wakeup = 0;
+ return;
+ }
+
+ /* If remote wakeup is permitted, see whether any interface drivers
+ * actually want it.
+ */
+ w = 0;
+ if (device_may_wakeup(&udev->dev) && udev->actconfig) {
+ for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+ intf = udev->actconfig->interface[i];
+ w |= intf->needs_remote_wakeup;
+ }
+ }
+
+ /* If the device is autosuspended with the wrong wakeup setting,
+ * autoresume now so the setting can be changed.
+ */
+ if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup)
+ pm_runtime_resume(&udev->dev);
+ udev->do_remote_wakeup = w;
+}
+
/* The device lock is held by the PM core */
int usb_suspend(struct device *dev, pm_message_t msg)
{
struct usb_device *udev = to_usb_device(dev);
do_unbind_rebind(udev, DO_UNBIND);
- udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
+ choose_wakeup(udev, msg);
return usb_suspend_both(udev, msg);
}
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index d26b9ea981f..4f84a41ee7a 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/idr.h>
#include <linux/usb.h>
#include "usb.h"
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index c3536f151f0..f06f5dbc8cd 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/rwsem.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/usb.h>
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index bdf87a8414a..2c95153c0f2 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -120,7 +120,7 @@ int usb_choose_configuration(struct usb_device *udev)
* than a vendor-specific driver. */
else if (udev->descriptor.bDeviceClass !=
USB_CLASS_VENDOR_SPEC &&
- (!desc || desc->bInterfaceClass !=
+ (desc && desc->bInterfaceClass !=
USB_CLASS_VENDOR_SPEC)) {
best = c;
break;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 97b40ce133f..4a6366a4212 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -515,13 +515,13 @@ static int fs_create_by_name (const char *name, mode_t mode,
*dentry = NULL;
mutex_lock(&parent->d_inode->i_mutex);
*dentry = lookup_one_len(name, parent, strlen(name));
- if (!IS_ERR(dentry)) {
+ if (!IS_ERR(*dentry)) {
if ((mode & S_IFMT) == S_IFDIR)
error = usbfs_mkdir (parent->d_inode, *dentry, mode);
else
error = usbfs_create (parent->d_inode, *dentry, mode);
} else
- error = PTR_ERR(dentry);
+ error = PTR_ERR(*dentry);
mutex_unlock(&parent->d_inode->i_mutex);
return error;
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 27080561a1c..45a32dadb40 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -453,6 +453,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (urb->interval > (1 << 15))
return -EINVAL;
max = 1 << 15;
+ break;
case USB_SPEED_WIRELESS:
if (urb->interval > 16)
return -EINVAL;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 1297e9b16a5..0561430f2ed 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -718,7 +718,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
/**
- * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
+ * usb_alloc_coherent - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
* @dev: device the buffer will be used with
* @size: requested buffer size
* @mem_flags: affect whether allocation may block
@@ -737,30 +737,30 @@ EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
* architectures where CPU caches are not DMA-coherent. On systems without
* bus-snooping caches, these buffers are uncached.
*
- * When the buffer is no longer used, free it with usb_buffer_free().
+ * When the buffer is no longer used, free it with usb_free_coherent().
*/
-void *usb_buffer_alloc(struct usb_device *dev, size_t size, gfp_t mem_flags,
- dma_addr_t *dma)
+void *usb_alloc_coherent(struct usb_device *dev, size_t size, gfp_t mem_flags,
+ dma_addr_t *dma)
{
if (!dev || !dev->bus)
return NULL;
return hcd_buffer_alloc(dev->bus, size, mem_flags, dma);
}
-EXPORT_SYMBOL_GPL(usb_buffer_alloc);
+EXPORT_SYMBOL_GPL(usb_alloc_coherent);
/**
- * usb_buffer_free - free memory allocated with usb_buffer_alloc()
+ * usb_free_coherent - free memory allocated with usb_alloc_coherent()
* @dev: device the buffer was used with
* @size: requested buffer size
* @addr: CPU address of buffer
* @dma: DMA address of buffer
*
* This reclaims an I/O buffer, letting it be reused. The memory must have
- * been allocated using usb_buffer_alloc(), and the parameters must match
+ * been allocated using usb_alloc_coherent(), and the parameters must match
* those provided in that allocation request.
*/
-void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
- dma_addr_t dma)
+void usb_free_coherent(struct usb_device *dev, size_t size, void *addr,
+ dma_addr_t dma)
{
if (!dev || !dev->bus)
return;
@@ -768,7 +768,7 @@ void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
return;
hcd_buffer_free(dev->bus, size, addr, dma);
}
-EXPORT_SYMBOL_GPL(usb_buffer_free);
+EXPORT_SYMBOL_GPL(usb_free_coherent);
/**
* usb_buffer_map - create DMA mapping(s) for an urb
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 7460cd797f4..11a3e0fa433 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -747,7 +747,7 @@ config USB_MASS_STORAGE
which may be used with composite framework.
Say "y" to link the driver statically, or "m" to build
- a dynamically linked module called "g_file_storage". If unsure,
+ a dynamically linked module called "g_mass_storage". If unsure,
consider File-backed Storage Gadget.
config USB_G_SERIAL
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 12ac9cd32a0..df1bae9b048 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1370,6 +1370,12 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
{
struct at91_udc *udc = _udc;
u32 rescans = 5;
+ int disable_clock = 0;
+
+ if (!udc->clocked) {
+ clk_on(udc);
+ disable_clock = 1;
+ }
while (rescans--) {
u32 status;
@@ -1458,6 +1464,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
}
}
+ if (disable_clock)
+ clk_off(udc);
+
return IRQ_HANDLED;
}
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index f79bdfe4bed..75a256f3d45 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index c7cb87a6fee..699695128e3 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -62,6 +62,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index e1191b9a316..47e8e722682 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -19,6 +19,7 @@
*/
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/string.h>
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index 65a5f94cbc0..3568de210f7 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -266,7 +266,7 @@ struct usb_ep * __init usb_ep_autoconfig (
}
#ifdef CONFIG_BLACKFIN
- } else if (gadget_is_musbhsfc(gadget) || gadget_is_musbhdrc(gadget)) {
+ } else if (gadget_is_musbhdrc(gadget)) {
if ((USB_ENDPOINT_XFER_BULK == type) ||
(USB_ENDPOINT_XFER_ISOC == type)) {
if (USB_DIR_IN & desc->bEndpointAddress)
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index e49c7325dce..400e1ebe697 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -14,6 +14,7 @@
/* #define VERBOSE_DEBUG */
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c
index f1e3aad76c3..43bf44514c4 100644
--- a/drivers/usb/gadget/f_audio.c
+++ b/drivers/usb/gadget/f_audio.c
@@ -9,6 +9,7 @@
* Licensed under the GPL-2 or later.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <asm/atomic.h>
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index 2fff530efc1..4e595324c61 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -21,6 +21,7 @@
/* #define VERBOSE_DEBUG */
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index d4f0db58a8a..38226e9a371 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -24,6 +24,7 @@
#include <linux/device.h>
#include <linux/etherdevice.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include "u_ether.h"
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 6cb29d3df57..e91d1b16d9b 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -21,6 +21,7 @@
/* #define VERBOSE_DEBUG */
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 5a3cdd08f1d..f4911c09022 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2910,7 +2910,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
}
-static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f)
{
struct fsg_dev *fsg = fsg_from_func(f);
struct usb_gadget *gadget = c->cdev->gadget;
@@ -2954,7 +2954,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
autoconf_fail:
ERROR(fsg, "unable to autoconfigure all endpoints\n");
rc = -ENOTSUPP;
- fsg_unbind(c, f);
return rc;
}
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index b4a3ba654ea..8f8c6437147 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -23,6 +23,7 @@
/* #define VERBOSE_DEBUG */
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index d2de10b9dc4..3c6e1a05874 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -20,6 +20,7 @@
* 02110-1301 USA
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index a30e60c7f12..56b022150f2 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -24,6 +24,7 @@
/* #define VERBOSE_DEBUG */
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index db0aa93606e..490b00b01a7 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -10,6 +10,7 @@
* either version 2 of that License or (at your option) any later version.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index 09cba273d2d..6d3cc443d91 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -21,6 +21,7 @@
/* #define VERBOSE_DEBUG */
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index a9c98fdb626..8675ca41532 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
diff --git a/drivers/usb/gadget/fsl_mx3_udc.c b/drivers/usb/gadget/fsl_mx3_udc.c
index 4bc2bf3d602..20a802ecaa1 100644
--- a/drivers/usb/gadget/fsl_mx3_udc.c
+++ b/drivers/usb/gadget/fsl_mx3_udc.c
@@ -17,6 +17,8 @@
#include <linux/fsl_devices.h>
#include <linux/platform_device.h>
+#include <mach/hardware.h>
+
static struct clk *mxc_ahb_clk;
static struct clk *mxc_usb_clk;
@@ -28,14 +30,16 @@ int fsl_udc_clk_init(struct platform_device *pdev)
pdata = pdev->dev.platform_data;
- mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb");
- if (IS_ERR(mxc_ahb_clk))
- return PTR_ERR(mxc_ahb_clk);
+ if (!cpu_is_mx35()) {
+ mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb");
+ if (IS_ERR(mxc_ahb_clk))
+ return PTR_ERR(mxc_ahb_clk);
- ret = clk_enable(mxc_ahb_clk);
- if (ret < 0) {
- dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n");
- goto eenahb;
+ ret = clk_enable(mxc_ahb_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n");
+ goto eenahb;
+ }
}
/* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
@@ -50,6 +54,7 @@ int fsl_udc_clk_init(struct platform_device *pdev)
if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
(freq < 59999000 || freq > 60001000)) {
dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq);
+ ret = -EINVAL;
goto eclkrate;
}
@@ -66,9 +71,11 @@ eclkrate:
clk_put(mxc_usb_clk);
mxc_usb_clk = NULL;
egusb:
- clk_disable(mxc_ahb_clk);
+ if (!cpu_is_mx35())
+ clk_disable(mxc_ahb_clk);
eenahb:
- clk_put(mxc_ahb_clk);
+ if (!cpu_is_mx35())
+ clk_put(mxc_ahb_clk);
return ret;
}
@@ -90,6 +97,8 @@ void fsl_udc_clk_release(void)
clk_disable(mxc_usb_clk);
clk_put(mxc_usb_clk);
}
- clk_disable(mxc_ahb_clk);
- clk_put(mxc_ahb_clk);
+ if (!cpu_is_mx35()) {
+ clk_disable(mxc_ahb_clk);
+ clk_put(mxc_ahb_clk);
+ }
}
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 1edbc12fff1..e511fec9f26 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -136,6 +136,12 @@
#define gadget_is_r8a66597(g) 0
#endif
+#ifdef CONFIG_USB_S3C_HSOTG
+#define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name))
+#else
+#define gadget_is_s3c_hsotg(g) 0
+#endif
+
/**
* usb_gadget_controller_number - support bcdDevice id convention
@@ -192,6 +198,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x24;
else if (gadget_is_r8a66597(gadget))
return 0x25;
+ else if (gadget_is_s3c_hsotg(gadget))
+ return 0x26;
return -ENOENT;
}
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 04f6224b7e0..2b56ce62185 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -21,6 +21,7 @@
/* #define VERBOSE_DEBUG */
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/utsname.h>
#include <linux/device.h>
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index e8edc640381..1088d08c7ed 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1768,7 +1768,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
* usb_gadget_driver_{register,unregister}() must change.
*/
if (the_controller) {
- WARNING(dev, "ignoring %s\n", pci_name(pdev));
+ pr_warning("ignoring %s\n", pci_name(pdev));
return -EBUSY;
}
if (!pdev->irq) {
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index 01ee0b9bc95..e743122fcd9 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -29,6 +29,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/timer.h>
+#include <linux/slab.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index 6cd3d54f564..fded3fca793 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -22,6 +22,7 @@
*/
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "lh7a40x_udc.h"
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index a8c8543d1b0..166bf71fd34 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 76496f5d272..a930d7fd7e7 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -211,8 +211,6 @@ static int __init cdc_do_config(struct usb_configuration *c)
ret = fsg_add(c->cdev, c, fsg_common);
if (ret < 0)
return ret;
- if (ret < 0)
- return ret;
return 0;
}
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index e6fedbd5a65..be5fb34d960 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -65,6 +65,10 @@
#include <mach/pxa25x-udc.h>
#endif
+#ifdef CONFIG_ARCH_LUBBOCK
+#include <mach/lubbock.h>
+#endif
+
#include <asm/mach/udc_pxa2xx.h>
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 05b892c3d68..85b0d8921ea 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -31,6 +31,7 @@
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <mach/hardware.h>
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 8b45145b913..888d8f166c0 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -27,6 +27,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 48267bc0b2e..5c0d06c79a8 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/netdevice.h>
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 7e5bf593d38..1f73b485732 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -22,6 +22,7 @@
#include <linux/seq_file.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -30,7 +31,7 @@
#include <plat/regs-usb-hsotg-phy.h>
#include <plat/regs-usb-hsotg.h>
-#include <plat/regs-sys.h>
+#include <mach/regs-sys.h>
#include <plat/udc-hs.h>
#define DMA_ADDR_INVALID (~((dma_addr_t)0))
@@ -2144,6 +2145,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
u32 epctrl;
u32 mps;
int dir_in;
+ int ret = 0;
dev_dbg(hsotg->dev,
"%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n",
@@ -2195,7 +2197,8 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
case USB_ENDPOINT_XFER_ISOC:
dev_err(hsotg->dev, "no current ISOC support\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
case USB_ENDPOINT_XFER_BULK:
epctrl |= S3C_DxEPCTL_EPType_Bulk;
@@ -2234,8 +2237,9 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
/* enable the endpoint interrupt */
s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
+out:
spin_unlock_irqrestore(&hs_ep->lock, flags);
- return 0;
+ return ret;
}
static int s3c_hsotg_ep_disable(struct usb_ep *ep)
diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c
index 35e0930f5bb..7a86d2c9109 100644
--- a/drivers/usb/gadget/u_audio.c
+++ b/drivers/usb/gadget/u_audio.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/ctype.h>
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 84ca195c2d1..07f4178ad17 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -23,6 +23,7 @@
/* #define VERBOSE_DEBUG */
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/device.h>
#include <linux/ctype.h>
#include <linux/etherdevice.h>
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index adf8260c3a6..16bdf77f582 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
+#include <linux/slab.h>
#include "u_serial.h"
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index fac81ee193d..807280d069f 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -50,6 +50,7 @@
/* #define VERBOSE_DEBUG */
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/utsname.h>
#include <linux/device.h>
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 4e0c67f1f51..b6315aa47f7 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -12,7 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \
ifeq ($(CONFIG_FHCI_DEBUG),y)
fhci-objs += fhci-dbg.o
endif
-xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o
+xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o
obj-$(CONFIG_USB_WHCI_HCD) += whci/
@@ -25,7 +25,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
obj-$(CONFIG_USB_FHCI_HCD) += fhci.o
-obj-$(CONFIG_USB_XHCI_HCD) += xhci.o
+obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o
obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d8d6d3461d3..13ead00aecd 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -23,7 +23,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/errno.h>
#include <linux/init.h>
@@ -35,6 +34,7 @@
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include "../core/hcd.h"
@@ -543,6 +543,7 @@ static int ehci_init(struct usb_hcd *hcd)
*/
ehci->periodic_size = DEFAULT_I_TDPS;
INIT_LIST_HEAD(&ehci->cached_itd_list);
+ INIT_LIST_HEAD(&ehci->cached_sitd_list);
if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
return retval;
@@ -995,7 +996,7 @@ rescan:
/* endpoints can be iso streams. for now, we don't
* accelerate iso completions ... so spin a while.
*/
- if (qh->hw->hw_info1 == 0) {
+ if (qh->hw == NULL) {
ehci_vdbg (ehci, "iso delay\n");
goto idle_timeout;
}
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 19372673bf0..c7178bcde67 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -801,7 +801,7 @@ static int ehci_hub_control (
* this bit; seems too long to spin routinely...
*/
retval = handshake(ehci, status_reg,
- PORT_RESET, 0, 750);
+ PORT_RESET, 0, 1000);
if (retval != 0) {
ehci_err (ehci, "port %d reset error %d\n",
wIndex + 1, retval);
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index aeda96e0af6..1f3f01eacaf 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -136,7 +136,7 @@ static inline void qh_put (struct ehci_qh *qh)
static void ehci_mem_cleanup (struct ehci_hcd *ehci)
{
- free_cached_itd_list(ehci);
+ free_cached_lists(ehci);
if (ehci->async)
qh_put (ehci->async);
ehci->async = NULL;
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 23cd917088b..ead59f42e69 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -21,6 +21,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/usb/otg.h>
+#include <linux/slab.h>
#include <mach/mxc_ehci.h>
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index f0282d6bb7a..40a85833503 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -37,6 +37,7 @@
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <plat/usb.h>
/*
@@ -628,11 +629,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
}
snprintf(supply, sizeof(supply), "hsusb%d", i);
omap->regulator[i] = regulator_get(omap->dev, supply);
- if (IS_ERR(omap->regulator[i]))
+ if (IS_ERR(omap->regulator[i])) {
+ omap->regulator[i] = NULL;
dev_dbg(&pdev->dev,
"failed to get ehci port%d regulator\n", i);
- else
+ } else {
regulator_enable(omap->regulator[i]);
+ }
}
ret = omap_start_ehc(omap, hcd);
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 39340ae00ac..805ec633a65 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -510,7 +510,7 @@ static int disable_periodic (struct ehci_hcd *ehci)
ehci_writel(ehci, cmd, &ehci->regs->command);
/* posted write ... */
- free_cached_itd_list(ehci);
+ free_cached_lists(ehci);
ehci->next_uframe = -1;
return 0;
@@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
urb->interval);
}
- /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */
- } else if (unlikely (stream->hw_info1 != 0)) {
+ /* if dev->ep [epnum] is a QH, hw is set */
+ } else if (unlikely (stream->hw != NULL)) {
ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n",
urb->dev->devpath, epnum,
usb_pipein(urb->pipe) ? "in" : "out");
@@ -1565,13 +1565,27 @@ itd_patch(
static inline void
itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
{
- /* always prepend ITD/SITD ... only QH tree is order-sensitive */
- itd->itd_next = ehci->pshadow [frame];
- itd->hw_next = ehci->periodic [frame];
- ehci->pshadow [frame].itd = itd;
+ union ehci_shadow *prev = &ehci->pshadow[frame];
+ __hc32 *hw_p = &ehci->periodic[frame];
+ union ehci_shadow here = *prev;
+ __hc32 type = 0;
+
+ /* skip any iso nodes which might belong to previous microframes */
+ while (here.ptr) {
+ type = Q_NEXT_TYPE(ehci, *hw_p);
+ if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
+ break;
+ prev = periodic_next_shadow(ehci, prev, type);
+ hw_p = shadow_next_periodic(ehci, &here, type);
+ here = *prev;
+ }
+
+ itd->itd_next = here;
+ itd->hw_next = *hw_p;
+ prev->itd = itd;
itd->frame = frame;
wmb ();
- ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
+ *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
}
/* fit urb's itds into the selected schedule slot; activate as needed */
@@ -2125,13 +2139,27 @@ sitd_complete (
(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
}
iso_stream_put (ehci, stream);
- /* OK to recycle this SITD now that its completion callback ran. */
+
done:
sitd->urb = NULL;
- sitd->stream = NULL;
- list_move(&sitd->sitd_list, &stream->free_list);
- iso_stream_put(ehci, stream);
-
+ if (ehci->clock_frame != sitd->frame) {
+ /* OK to recycle this SITD now. */
+ sitd->stream = NULL;
+ list_move(&sitd->sitd_list, &stream->free_list);
+ iso_stream_put(ehci, stream);
+ } else {
+ /* HW might remember this SITD, so we can't recycle it yet.
+ * Move it to a safe place until a new frame starts.
+ */
+ list_move(&sitd->sitd_list, &ehci->cached_sitd_list);
+ if (stream->refcount == 2) {
+ /* If iso_stream_put() were called here, stream
+ * would be freed. Instead, just prevent reuse.
+ */
+ stream->ep->hcpriv = NULL;
+ stream->ep = NULL;
+ }
+ }
return retval;
}
@@ -2197,9 +2225,10 @@ done:
/*-------------------------------------------------------------------------*/
-static void free_cached_itd_list(struct ehci_hcd *ehci)
+static void free_cached_lists(struct ehci_hcd *ehci)
{
struct ehci_itd *itd, *n;
+ struct ehci_sitd *sitd, *sn;
list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
struct ehci_iso_stream *stream = itd->stream;
@@ -2207,6 +2236,13 @@ static void free_cached_itd_list(struct ehci_hcd *ehci)
list_move(&itd->itd_list, &stream->free_list);
iso_stream_put(ehci, stream);
}
+
+ list_for_each_entry_safe(sitd, sn, &ehci->cached_sitd_list, sitd_list) {
+ struct ehci_iso_stream *stream = sitd->stream;
+ sitd->stream = NULL;
+ list_move(&sitd->sitd_list, &stream->free_list);
+ iso_stream_put(ehci, stream);
+ }
}
/*-------------------------------------------------------------------------*/
@@ -2233,7 +2269,7 @@ scan_periodic (struct ehci_hcd *ehci)
clock_frame = -1;
}
if (ehci->clock_frame != clock_frame) {
- free_cached_itd_list(ehci);
+ free_cached_lists(ehci);
ehci->clock_frame = clock_frame;
}
clock %= mod;
@@ -2400,7 +2436,7 @@ restart:
clock = now;
clock_frame = clock >> 3;
if (ehci->clock_frame != clock_frame) {
- free_cached_itd_list(ehci);
+ free_cached_lists(ehci);
ehci->clock_frame = clock_frame;
}
} else {
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 2d85e21ff28..556c0b48f3a 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -87,8 +87,9 @@ struct ehci_hcd { /* one per controller */
int next_uframe; /* scan periodic, start here */
unsigned periodic_sched; /* periodic activity count */
- /* list of itds completed while clock_frame was still active */
+ /* list of itds & sitds completed while clock_frame was still active */
struct list_head cached_itd_list;
+ struct list_head cached_sitd_list;
unsigned clock_frame;
/* per root hub port */
@@ -195,7 +196,7 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
clear_bit (action, &ehci->actions);
}
-static void free_cached_itd_list(struct ehci_hcd *ehci);
+static void free_cached_lists(struct ehci_hcd *ehci);
/*-------------------------------------------------------------------------*/
@@ -394,9 +395,8 @@ struct ehci_iso_sched {
* acts like a qh would, if EHCI had them for ISO.
*/
struct ehci_iso_stream {
- /* first two fields match QH, but info1 == 0 */
- __hc32 hw_next;
- __hc32 hw_info1;
+ /* first field matches ehci_hq, but is NULL */
+ struct ehci_qh_hw *hw;
u32 refcount;
u8 bEndpointAddress;
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
index 5dcfb3de994..15379c63614 100644
--- a/drivers/usb/host/fhci-hcd.c
+++ b/drivers/usb/host/fhci-hcd.c
@@ -27,6 +27,7 @@
#include <linux/usb.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
+#include <linux/slab.h>
#include <asm/qe.h>
#include <asm/fsl_gtm.h>
#include "../core/hcd.h"
diff --git a/drivers/usb/host/fhci-mem.c b/drivers/usb/host/fhci-mem.c
index 2c0736c9971..5591bfb499d 100644
--- a/drivers/usb/host/fhci-mem.c
+++ b/drivers/usb/host/fhci-mem.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/usb.h>
#include "../core/hcd.h"
diff --git a/drivers/usb/host/fhci-q.c b/drivers/usb/host/fhci-q.c
index b0a1446ba29..f73c92359be 100644
--- a/drivers/usb/host/fhci-q.c
+++ b/drivers/usb/host/fhci-q.c
@@ -19,6 +19,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/usb.h>
#include "../core/hcd.h"
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c
index e1232890c78..57013479d7f 100644
--- a/drivers/usb/host/fhci-tds.c
+++ b/drivers/usb/host/fhci-tds.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/io.h>
#include <linux/usb.h>
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
index 88b03214622..35742f8c7cd 100644
--- a/drivers/usb/host/hwa-hc.c
+++ b/drivers/usb/host/hwa-hc.c
@@ -55,6 +55,7 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
index 213e270e1c2..8a12f297645 100644
--- a/drivers/usb/host/imx21-hcd.c
+++ b/drivers/usb/host/imx21-hcd.c
@@ -54,6 +54,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "../core/hcd.h"
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index a2b305477af..92de71dc772 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -62,6 +62,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/isp116x.h>
#include <linux/platform_device.h>
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 68b83ab7071..944291e10f9 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -331,6 +331,8 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
*/
if (at91_suspend_entering_slow_clock()) {
ohci_usb_reset (ohci);
+ /* flush the writes */
+ (void) ohci_readl (ohci, &ohci->regs->control);
at91_stop_clock();
}
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 4aa08d36d07..d22fb4d577b 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -23,7 +23,7 @@
#error "This file is DA8xx bus glue. Define CONFIG_ARCH_DAVINCI_DA8XX."
#endif
-#define CFGCHIP2 DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG)
+#define CFGCHIP2 DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)
static struct clk *usb11_clk;
static struct clk *usb20_clk;
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 32bbce9718f..65cac8cc892 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -697,7 +697,7 @@ static int ohci_hub_control (
u16 wLength
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ports = hcd_to_bus (hcd)->root_hub->maxchild;
+ int ports = ohci->num_ports;
u32 temp;
int retval = 0;
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 35288bcae0d..83094d067e0 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -8,6 +8,7 @@
*/
#include <linux/irq.h>
+#include <linux/slab.h>
static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
{
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 50f57f46883..e62b30b3e42 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -660,13 +660,13 @@ static struct ehci_qh *oxu_qh_alloc(struct oxu_hcd *oxu)
if (qh->dummy == NULL) {
oxu_dbg(oxu, "no dummy td\n");
oxu->qh_used[i] = 0;
-
- return NULL;
+ qh = NULL;
+ goto unlock;
}
oxu->qh_used[i] = 1;
}
-
+unlock:
spin_unlock(&oxu->mem_lock);
return qh;
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index bee558aed42..d478ffad59b 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -37,6 +37,7 @@
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/irq.h>
+#include <linux/slab.h>
#include <asm/cacheflush.h>
#include "../core/hcd.h"
@@ -418,7 +419,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
/* this function must be called with interrupt disabled */
static void free_usb_address(struct r8a66597 *r8a66597,
- struct r8a66597_device *dev)
+ struct r8a66597_device *dev, int reset)
{
int port;
@@ -430,7 +431,13 @@ static void free_usb_address(struct r8a66597 *r8a66597,
dev->state = USB_STATE_DEFAULT;
r8a66597->address_map &= ~(1 << dev->address);
dev->address = 0;
- dev_set_drvdata(&dev->udev->dev, NULL);
+ /*
+ * Only when resetting USB, it is necessary to erase drvdata. When
+ * a usb device with usb hub is disconnect, "dev->udev" is already
+ * freed on usb_desconnect(). So we cannot access the data.
+ */
+ if (reset)
+ dev_set_drvdata(&dev->udev->dev, NULL);
list_del(&dev->device_list);
kfree(dev);
@@ -1069,7 +1076,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port)
struct r8a66597_device *dev = r8a66597->root_hub[port].dev;
disable_r8a66597_pipe_all(r8a66597, dev);
- free_usb_address(r8a66597, dev);
+ free_usb_address(r8a66597, dev, 0);
start_root_hub_sampling(r8a66597, port, 0);
}
@@ -2085,7 +2092,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597,
spin_lock_irqsave(&r8a66597->lock, flags);
dev = get_r8a66597_device(r8a66597, addr);
disable_r8a66597_pipe_all(r8a66597, dev);
- free_usb_address(r8a66597, dev);
+ free_usb_address(r8a66597, dev, 0);
put_child_connect_map(r8a66597, addr);
spin_unlock_irqrestore(&r8a66597->lock, flags);
}
@@ -2228,7 +2235,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
rh->port |= (1 << USB_PORT_FEAT_RESET);
disable_r8a66597_pipe_all(r8a66597, dev);
- free_usb_address(r8a66597, dev);
+ free_usb_address(r8a66597, dev, 1);
r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT,
get_dvstctr_reg(port));
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index e11cc3aa4b8..3b867a8af7b 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -720,10 +720,10 @@ retry:
/* port status seems weird until after reset, so
* force the reset and make khubd clean up later.
*/
- if (sl811->stat_insrmv & 1)
- sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
- else
+ if (irqstat & SL11H_INTMASK_RD)
sl811->port1 &= ~(1 << USB_PORT_FEAT_CONNECTION);
+ else
+ sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
sl811->port1 |= 1 << USB_PORT_FEAT_C_CONNECTION;
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index e52b954dda4..98cf0b26b96 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -9,6 +9,7 @@
* (C) Copyright 1999-2001 Johannes Erdfelt
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/smp_lock.h>
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 562eba10881..77324930603 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/dma-mapping.h>
#include <linux/uwb/umc.h>
#include <linux/usb.h>
diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c
index 8c1c610c951..c5305b599ca 100644
--- a/drivers/usb/host/whci/debug.c
+++ b/drivers/usb/host/whci/debug.c
@@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c
index 34a783cb013..f7582e8e216 100644
--- a/drivers/usb/host/whci/init.c
+++ b/drivers/usb/host/whci/init.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/dma-mapping.h>
#include <linux/uwb/umc.h>
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index 0db3fb2dc03..33c5580b4d2 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/dma-mapping.h>
#include <linux/uwb/umc.h>
#include <linux/usb.h>
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
index 7d4204db0f6..141d049beb3 100644
--- a/drivers/usb/host/whci/qset.c
+++ b/drivers/usb/host/whci/qset.c
@@ -17,6 +17,7 @@
*/
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/uwb/umc.h>
#include <linux/usb.h>
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
deleted file mode 100644
index 4cb69e0af83..00000000000
--- a/drivers/usb/host/xhci-hcd.c
+++ /dev/null
@@ -1,1916 +0,0 @@
-/*
- * xHCI host controller driver
- *
- * Copyright (C) 2008 Intel Corp.
- *
- * Author: Sarah Sharp
- * Some code borrowed from the Linux EHCI driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in 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/irq.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-
-#include "xhci.h"
-
-#define DRIVER_AUTHOR "Sarah Sharp"
-#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
-
-/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
-static int link_quirk;
-module_param(link_quirk, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
-
-/* TODO: copied from ehci-hcd.c - can this be refactored? */
-/*
- * handshake - spin reading hc until handshake completes or fails
- * @ptr: address of hc register to be read
- * @mask: bits to look at in result of read
- * @done: value of those bits when handshake succeeds
- * @usec: timeout in microseconds
- *
- * Returns negative errno, or zero on success
- *
- * Success happens when the "mask" bits have the specified value (hardware
- * handshake done). There are two failure modes: "usec" have passed (major
- * hardware flakeout), or the register reads as all-ones (hardware removed).
- */
-static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
- u32 mask, u32 done, int usec)
-{
- u32 result;
-
- do {
- result = xhci_readl(xhci, ptr);
- if (result == ~(u32)0) /* card removed */
- return -ENODEV;
- result &= mask;
- if (result == done)
- return 0;
- udelay(1);
- usec--;
- } while (usec > 0);
- return -ETIMEDOUT;
-}
-
-/*
- * Disable interrupts and begin the xHCI halting process.
- */
-void xhci_quiesce(struct xhci_hcd *xhci)
-{
- u32 halted;
- u32 cmd;
- u32 mask;
-
- mask = ~(XHCI_IRQS);
- halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
- if (!halted)
- mask &= ~CMD_RUN;
-
- cmd = xhci_readl(xhci, &xhci->op_regs->command);
- cmd &= mask;
- xhci_writel(xhci, cmd, &xhci->op_regs->command);
-}
-
-/*
- * Force HC into halt state.
- *
- * Disable any IRQs and clear the run/stop bit.
- * HC will complete any current and actively pipelined transactions, and
- * should halt within 16 microframes of the run/stop bit being cleared.
- * Read HC Halted bit in the status register to see when the HC is finished.
- * XXX: shouldn't we set HC_STATE_HALT here somewhere?
- */
-int xhci_halt(struct xhci_hcd *xhci)
-{
- xhci_dbg(xhci, "// Halt the HC\n");
- xhci_quiesce(xhci);
-
- return handshake(xhci, &xhci->op_regs->status,
- STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
-}
-
-/*
- * Reset a halted HC, and set the internal HC state to HC_STATE_HALT.
- *
- * This resets pipelines, timers, counters, state machines, etc.
- * Transactions will be terminated immediately, and operational registers
- * will be set to their defaults.
- */
-int xhci_reset(struct xhci_hcd *xhci)
-{
- u32 command;
- u32 state;
-
- state = xhci_readl(xhci, &xhci->op_regs->status);
- if ((state & STS_HALT) == 0) {
- xhci_warn(xhci, "Host controller not halted, aborting reset.\n");
- return 0;
- }
-
- xhci_dbg(xhci, "// Reset the HC\n");
- command = xhci_readl(xhci, &xhci->op_regs->command);
- command |= CMD_RESET;
- xhci_writel(xhci, command, &xhci->op_regs->command);
- /* XXX: Why does EHCI set this here? Shouldn't other code do this? */
- xhci_to_hcd(xhci)->state = HC_STATE_HALT;
-
- return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
-}
-
-
-#if 0
-/* Set up MSI-X table for entry 0 (may claim other entries later) */
-static int xhci_setup_msix(struct xhci_hcd *xhci)
-{
- int ret;
- struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
-
- xhci->msix_count = 0;
- /* XXX: did I do this right? ixgbe does kcalloc for more than one */
- xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL);
- if (!xhci->msix_entries) {
- xhci_err(xhci, "Failed to allocate MSI-X entries\n");
- return -ENOMEM;
- }
- xhci->msix_entries[0].entry = 0;
-
- ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count);
- if (ret) {
- xhci_err(xhci, "Failed to enable MSI-X\n");
- goto free_entries;
- }
-
- /*
- * Pass the xhci pointer value as the request_irq "cookie".
- * If more irqs are added, this will need to be unique for each one.
- */
- ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0,
- "xHCI", xhci_to_hcd(xhci));
- if (ret) {
- xhci_err(xhci, "Failed to allocate MSI-X interrupt\n");
- goto disable_msix;
- }
- xhci_dbg(xhci, "Finished setting up MSI-X\n");
- return 0;
-
-disable_msix:
- pci_disable_msix(pdev);
-free_entries:
- kfree(xhci->msix_entries);
- xhci->msix_entries = NULL;
- return ret;
-}
-
-/* XXX: code duplication; can xhci_setup_msix call this? */
-/* Free any IRQs and disable MSI-X */
-static void xhci_cleanup_msix(struct xhci_hcd *xhci)
-{
- struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
- if (!xhci->msix_entries)
- return;
-
- free_irq(xhci->msix_entries[0].vector, xhci);
- pci_disable_msix(pdev);
- kfree(xhci->msix_entries);
- xhci->msix_entries = NULL;
- xhci_dbg(xhci, "Finished cleaning up MSI-X\n");
-}
-#endif
-
-/*
- * Initialize memory for HCD and xHC (one-time init).
- *
- * Program the PAGESIZE register, initialize the device context array, create
- * device contexts (?), set up a command ring segment (or two?), create event
- * ring (one for now).
- */
-int xhci_init(struct usb_hcd *hcd)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- int retval = 0;
-
- xhci_dbg(xhci, "xhci_init\n");
- spin_lock_init(&xhci->lock);
- if (link_quirk) {
- xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n");
- xhci->quirks |= XHCI_LINK_TRB_QUIRK;
- } else {
- xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n");
- }
- retval = xhci_mem_init(xhci, GFP_KERNEL);
- xhci_dbg(xhci, "Finished xhci_init\n");
-
- return retval;
-}
-
-/*
- * Called in interrupt context when there might be work
- * queued on the event ring
- *
- * xhci->lock must be held by caller.
- */
-static void xhci_work(struct xhci_hcd *xhci)
-{
- u32 temp;
- u64 temp_64;
-
- /*
- * Clear the op reg interrupt status first,
- * so we can receive interrupts from other MSI-X interrupters.
- * Write 1 to clear the interrupt status.
- */
- temp = xhci_readl(xhci, &xhci->op_regs->status);
- temp |= STS_EINT;
- xhci_writel(xhci, temp, &xhci->op_regs->status);
- /* FIXME when MSI-X is supported and there are multiple vectors */
- /* Clear the MSI-X event interrupt status */
-
- /* Acknowledge the interrupt */
- temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
- temp |= 0x3;
- xhci_writel(xhci, temp, &xhci->ir_set->irq_pending);
- /* Flush posted writes */
- xhci_readl(xhci, &xhci->ir_set->irq_pending);
-
- if (xhci->xhc_state & XHCI_STATE_DYING)
- xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
- "Shouldn't IRQs be disabled?\n");
- else
- /* FIXME this should be a delayed service routine
- * that clears the EHB.
- */
- xhci_handle_event(xhci);
-
- /* Clear the event handler busy flag (RW1C); the event ring should be empty. */
- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
- xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue);
- /* Flush posted writes -- FIXME is this necessary? */
- xhci_readl(xhci, &xhci->ir_set->irq_pending);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * xHCI spec says we can get an interrupt, and if the HC has an error condition,
- * we might get bad data out of the event ring. Section 4.10.2.7 has a list of
- * indicators of an event TRB error, but we check the status *first* to be safe.
- */
-irqreturn_t xhci_irq(struct usb_hcd *hcd)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- u32 temp, temp2;
- union xhci_trb *trb;
-
- spin_lock(&xhci->lock);
- trb = xhci->event_ring->dequeue;
- /* Check if the xHC generated the interrupt, or the irq is shared */
- temp = xhci_readl(xhci, &xhci->op_regs->status);
- temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending);
- if (temp == 0xffffffff && temp2 == 0xffffffff)
- goto hw_died;
-
- if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) {
- spin_unlock(&xhci->lock);
- return IRQ_NONE;
- }
- xhci_dbg(xhci, "op reg status = %08x\n", temp);
- xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2);
- xhci_dbg(xhci, "Event ring dequeue ptr:\n");
- xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n",
- (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb),
- lower_32_bits(trb->link.segment_ptr),
- upper_32_bits(trb->link.segment_ptr),
- (unsigned int) trb->link.intr_target,
- (unsigned int) trb->link.control);
-
- if (temp & STS_FATAL) {
- xhci_warn(xhci, "WARNING: Host System Error\n");
- xhci_halt(xhci);
-hw_died:
- xhci_to_hcd(xhci)->state = HC_STATE_HALT;
- spin_unlock(&xhci->lock);
- return -ESHUTDOWN;
- }
-
- xhci_work(xhci);
- spin_unlock(&xhci->lock);
-
- return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
-void xhci_event_ring_work(unsigned long arg)
-{
- unsigned long flags;
- int temp;
- u64 temp_64;
- struct xhci_hcd *xhci = (struct xhci_hcd *) arg;
- int i, j;
-
- xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies);
-
- spin_lock_irqsave(&xhci->lock, flags);
- temp = xhci_readl(xhci, &xhci->op_regs->status);
- xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
- if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
- xhci_dbg(xhci, "HW died, polling stopped.\n");
- spin_unlock_irqrestore(&xhci->lock, flags);
- return;
- }
-
- temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
- xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp);
- xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled);
- xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask);
- xhci->error_bitmask = 0;
- xhci_dbg(xhci, "Event ring:\n");
- xhci_debug_segment(xhci, xhci->event_ring->deq_seg);
- xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
- temp_64 &= ~ERST_PTR_MASK;
- xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
- xhci_dbg(xhci, "Command ring:\n");
- xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg);
- xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
- xhci_dbg_cmd_ptrs(xhci);
- for (i = 0; i < MAX_HC_SLOTS; ++i) {
- if (!xhci->devs[i])
- continue;
- for (j = 0; j < 31; ++j) {
- struct xhci_ring *ring = xhci->devs[i]->eps[j].ring;
- if (!ring)
- continue;
- xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
- xhci_debug_segment(xhci, ring->deq_seg);
- }
- }
-
- if (xhci->noops_submitted != NUM_TEST_NOOPS)
- if (xhci_setup_one_noop(xhci))
- xhci_ring_cmd_db(xhci);
- spin_unlock_irqrestore(&xhci->lock, flags);
-
- if (!xhci->zombie)
- mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ);
- else
- xhci_dbg(xhci, "Quit polling the event ring.\n");
-}
-#endif
-
-/*
- * Start the HC after it was halted.
- *
- * This function is called by the USB core when the HC driver is added.
- * Its opposite is xhci_stop().
- *
- * xhci_init() must be called once before this function can be called.
- * Reset the HC, enable device slot contexts, program DCBAAP, and
- * set command ring pointer and event ring pointer.
- *
- * Setup MSI-X vectors and enable interrupts.
- */
-int xhci_run(struct usb_hcd *hcd)
-{
- u32 temp;
- u64 temp_64;
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- void (*doorbell)(struct xhci_hcd *) = NULL;
-
- hcd->uses_new_polling = 1;
- hcd->poll_rh = 0;
-
- xhci_dbg(xhci, "xhci_run\n");
-#if 0 /* FIXME: MSI not setup yet */
- /* Do this at the very last minute */
- ret = xhci_setup_msix(xhci);
- if (!ret)
- return ret;
-
- return -ENOSYS;
-#endif
-#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
- init_timer(&xhci->event_ring_timer);
- xhci->event_ring_timer.data = (unsigned long) xhci;
- xhci->event_ring_timer.function = xhci_event_ring_work;
- /* Poll the event ring */
- xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ;
- xhci->zombie = 0;
- xhci_dbg(xhci, "Setting event ring polling timer\n");
- add_timer(&xhci->event_ring_timer);
-#endif
-
- xhci_dbg(xhci, "Command ring memory map follows:\n");
- xhci_debug_ring(xhci, xhci->cmd_ring);
- xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
- xhci_dbg_cmd_ptrs(xhci);
-
- xhci_dbg(xhci, "ERST memory map follows:\n");
- xhci_dbg_erst(xhci, &xhci->erst);
- xhci_dbg(xhci, "Event ring:\n");
- xhci_debug_ring(xhci, xhci->event_ring);
- xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
- temp_64 &= ~ERST_PTR_MASK;
- xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
-
- xhci_dbg(xhci, "// Set the interrupt modulation register\n");
- temp = xhci_readl(xhci, &xhci->ir_set->irq_control);
- temp &= ~ER_IRQ_INTERVAL_MASK;
- temp |= (u32) 160;
- xhci_writel(xhci, temp, &xhci->ir_set->irq_control);
-
- /* Set the HCD state before we enable the irqs */
- hcd->state = HC_STATE_RUNNING;
- temp = xhci_readl(xhci, &xhci->op_regs->command);
- temp |= (CMD_EIE);
- xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n",
- temp);
- xhci_writel(xhci, temp, &xhci->op_regs->command);
-
- temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
- xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n",
- xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp));
- xhci_writel(xhci, ER_IRQ_ENABLE(temp),
- &xhci->ir_set->irq_pending);
- xhci_print_ir_set(xhci, xhci->ir_set, 0);
-
- if (NUM_TEST_NOOPS > 0)
- doorbell = xhci_setup_one_noop(xhci);
-
- temp = xhci_readl(xhci, &xhci->op_regs->command);
- temp |= (CMD_RUN);
- xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
- temp);
- xhci_writel(xhci, temp, &xhci->op_regs->command);
- /* Flush PCI posted writes */
- temp = xhci_readl(xhci, &xhci->op_regs->command);
- xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp);
- if (doorbell)
- (*doorbell)(xhci);
-
- xhci_dbg(xhci, "Finished xhci_run\n");
- return 0;
-}
-
-/*
- * Stop xHCI driver.
- *
- * This function is called by the USB core when the HC driver is removed.
- * Its opposite is xhci_run().
- *
- * Disable device contexts, disable IRQs, and quiesce the HC.
- * Reset the HC, finish any completed transactions, and cleanup memory.
- */
-void xhci_stop(struct usb_hcd *hcd)
-{
- u32 temp;
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
- spin_lock_irq(&xhci->lock);
- xhci_halt(xhci);
- xhci_reset(xhci);
- spin_unlock_irq(&xhci->lock);
-
-#if 0 /* No MSI yet */
- xhci_cleanup_msix(xhci);
-#endif
-#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
- /* Tell the event ring poll function not to reschedule */
- xhci->zombie = 1;
- del_timer_sync(&xhci->event_ring_timer);
-#endif
-
- xhci_dbg(xhci, "// Disabling event ring interrupts\n");
- temp = xhci_readl(xhci, &xhci->op_regs->status);
- xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status);
- temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
- xhci_writel(xhci, ER_IRQ_DISABLE(temp),
- &xhci->ir_set->irq_pending);
- xhci_print_ir_set(xhci, xhci->ir_set, 0);
-
- xhci_dbg(xhci, "cleaning up memory\n");
- xhci_mem_cleanup(xhci);
- xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
- xhci_readl(xhci, &xhci->op_regs->status));
-}
-
-/*
- * Shutdown HC (not bus-specific)
- *
- * This is called when the machine is rebooting or halting. We assume that the
- * machine will be powered off, and the HC's internal state will be reset.
- * Don't bother to free memory.
- */
-void xhci_shutdown(struct usb_hcd *hcd)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
- spin_lock_irq(&xhci->lock);
- xhci_halt(xhci);
- spin_unlock_irq(&xhci->lock);
-
-#if 0
- xhci_cleanup_msix(xhci);
-#endif
-
- xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
- xhci_readl(xhci, &xhci->op_regs->status));
-}
-
-/*-------------------------------------------------------------------------*/
-
-/**
- * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and
- * HCDs. Find the index for an endpoint given its descriptor. Use the return
- * value to right shift 1 for the bitmask.
- *
- * Index = (epnum * 2) + direction - 1,
- * where direction = 0 for OUT, 1 for IN.
- * For control endpoints, the IN index is used (OUT index is unused), so
- * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2)
- */
-unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc)
-{
- unsigned int index;
- if (usb_endpoint_xfer_control(desc))
- index = (unsigned int) (usb_endpoint_num(desc)*2);
- else
- index = (unsigned int) (usb_endpoint_num(desc)*2) +
- (usb_endpoint_dir_in(desc) ? 1 : 0) - 1;
- return index;
-}
-
-/* Find the flag for this endpoint (for use in the control context). Use the
- * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
- * bit 1, etc.
- */
-unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc)
-{
- return 1 << (xhci_get_endpoint_index(desc) + 1);
-}
-
-/* Find the flag for this endpoint (for use in the control context). Use the
- * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
- * bit 1, etc.
- */
-unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index)
-{
- return 1 << (ep_index + 1);
-}
-
-/* Compute the last valid endpoint context index. Basically, this is the
- * endpoint index plus one. For slot contexts with more than valid endpoint,
- * we find the most significant bit set in the added contexts flags.
- * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000
- * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one.
- */
-unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
-{
- return fls(added_ctxs) - 1;
-}
-
-/* Returns 1 if the arguments are OK;
- * returns 0 this is a root hub; returns -EINVAL for NULL pointers.
- */
-int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
- struct usb_host_endpoint *ep, int check_ep, const char *func) {
- if (!hcd || (check_ep && !ep) || !udev) {
- printk(KERN_DEBUG "xHCI %s called with invalid args\n",
- func);
- return -EINVAL;
- }
- if (!udev->parent) {
- printk(KERN_DEBUG "xHCI %s called for root hub\n",
- func);
- return 0;
- }
- if (!udev->slot_id) {
- printk(KERN_DEBUG "xHCI %s called with unaddressed device\n",
- func);
- return -EINVAL;
- }
- return 1;
-}
-
-static int xhci_configure_endpoint(struct xhci_hcd *xhci,
- struct usb_device *udev, struct xhci_command *command,
- bool ctx_change, bool must_succeed);
-
-/*
- * Full speed devices may have a max packet size greater than 8 bytes, but the
- * USB core doesn't know that until it reads the first 8 bytes of the
- * descriptor. If the usb_device's max packet size changes after that point,
- * we need to issue an evaluate context command and wait on it.
- */
-static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
- unsigned int ep_index, struct urb *urb)
-{
- struct xhci_container_ctx *in_ctx;
- struct xhci_container_ctx *out_ctx;
- struct xhci_input_control_ctx *ctrl_ctx;
- struct xhci_ep_ctx *ep_ctx;
- int max_packet_size;
- int hw_max_packet_size;
- int ret = 0;
-
- out_ctx = xhci->devs[slot_id]->out_ctx;
- ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
- hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2);
- max_packet_size = urb->dev->ep0.desc.wMaxPacketSize;
- if (hw_max_packet_size != max_packet_size) {
- xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n");
- xhci_dbg(xhci, "Max packet size in usb_device = %d\n",
- max_packet_size);
- xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n",
- hw_max_packet_size);
- xhci_dbg(xhci, "Issuing evaluate context command.\n");
-
- /* Set up the modified control endpoint 0 */
- xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
- xhci->devs[slot_id]->out_ctx, ep_index);
- in_ctx = xhci->devs[slot_id]->in_ctx;
- ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
- ep_ctx->ep_info2 &= ~MAX_PACKET_MASK;
- ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size);
-
- /* Set up the input context flags for the command */
- /* FIXME: This won't work if a non-default control endpoint
- * changes max packet sizes.
- */
- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
- ctrl_ctx->add_flags = EP0_FLAG;
- ctrl_ctx->drop_flags = 0;
-
- xhci_dbg(xhci, "Slot %d input context\n", slot_id);
- xhci_dbg_ctx(xhci, in_ctx, ep_index);
- xhci_dbg(xhci, "Slot %d output context\n", slot_id);
- xhci_dbg_ctx(xhci, out_ctx, ep_index);
-
- ret = xhci_configure_endpoint(xhci, urb->dev, NULL,
- true, false);
-
- /* Clean up the input context for later use by bandwidth
- * functions.
- */
- ctrl_ctx->add_flags = SLOT_FLAG;
- }
- return ret;
-}
-
-/*
- * non-error returns are a promise to giveback() the urb later
- * we drop ownership so next owner (or urb unlink) can get it
- */
-int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- unsigned long flags;
- int ret = 0;
- unsigned int slot_id, ep_index;
-
-
- if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
- return -EINVAL;
-
- slot_id = urb->dev->slot_id;
- ep_index = xhci_get_endpoint_index(&urb->ep->desc);
-
- if (!xhci->devs || !xhci->devs[slot_id]) {
- if (!in_interrupt())
- dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
- ret = -EINVAL;
- goto exit;
- }
- if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
- if (!in_interrupt())
- xhci_dbg(xhci, "urb submitted during PCI suspend\n");
- ret = -ESHUTDOWN;
- goto exit;
- }
- if (usb_endpoint_xfer_control(&urb->ep->desc)) {
- /* Check to see if the max packet size for the default control
- * endpoint changed during FS device enumeration
- */
- if (urb->dev->speed == USB_SPEED_FULL) {
- ret = xhci_check_maxpacket(xhci, slot_id,
- ep_index, urb);
- if (ret < 0)
- return ret;
- }
-
- /* We have a spinlock and interrupts disabled, so we must pass
- * atomic context to this function, which may allocate memory.
- */
- spin_lock_irqsave(&xhci->lock, flags);
- if (xhci->xhc_state & XHCI_STATE_DYING)
- goto dying;
- ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
- slot_id, ep_index);
- spin_unlock_irqrestore(&xhci->lock, flags);
- } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
- spin_lock_irqsave(&xhci->lock, flags);
- if (xhci->xhc_state & XHCI_STATE_DYING)
- goto dying;
- ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
- slot_id, ep_index);
- spin_unlock_irqrestore(&xhci->lock, flags);
- } else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
- spin_lock_irqsave(&xhci->lock, flags);
- if (xhci->xhc_state & XHCI_STATE_DYING)
- goto dying;
- ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
- slot_id, ep_index);
- spin_unlock_irqrestore(&xhci->lock, flags);
- } else {
- ret = -EINVAL;
- }
-exit:
- return ret;
-dying:
- xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
- "non-responsive xHCI host.\n",
- urb->ep->desc.bEndpointAddress, urb);
- spin_unlock_irqrestore(&xhci->lock, flags);
- return -ESHUTDOWN;
-}
-
-/*
- * Remove the URB's TD from the endpoint ring. This may cause the HC to stop
- * USB transfers, potentially stopping in the middle of a TRB buffer. The HC
- * should pick up where it left off in the TD, unless a Set Transfer Ring
- * Dequeue Pointer is issued.
- *
- * The TRBs that make up the buffers for the canceled URB will be "removed" from
- * the ring. Since the ring is a contiguous structure, they can't be physically
- * removed. Instead, there are two options:
- *
- * 1) If the HC is in the middle of processing the URB to be canceled, we
- * simply move the ring's dequeue pointer past those TRBs using the Set
- * Transfer Ring Dequeue Pointer command. This will be the common case,
- * when drivers timeout on the last submitted URB and attempt to cancel.
- *
- * 2) If the HC is in the middle of a different TD, we turn the TRBs into a
- * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The
- * HC will need to invalidate the any TRBs it has cached after the stop
- * endpoint command, as noted in the xHCI 0.95 errata.
- *
- * 3) The TD may have completed by the time the Stop Endpoint Command
- * completes, so software needs to handle that case too.
- *
- * This function should protect against the TD enqueueing code ringing the
- * doorbell while this code is waiting for a Stop Endpoint command to complete.
- * It also needs to account for multiple cancellations on happening at the same
- * time for the same endpoint.
- *
- * Note that this function can be called in any context, or so says
- * usb_hcd_unlink_urb()
- */
-int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
-{
- unsigned long flags;
- int ret;
- u32 temp;
- struct xhci_hcd *xhci;
- struct xhci_td *td;
- unsigned int ep_index;
- struct xhci_ring *ep_ring;
- struct xhci_virt_ep *ep;
-
- xhci = hcd_to_xhci(hcd);
- spin_lock_irqsave(&xhci->lock, flags);
- /* Make sure the URB hasn't completed or been unlinked already */
- ret = usb_hcd_check_unlink_urb(hcd, urb, status);
- if (ret || !urb->hcpriv)
- goto done;
- temp = xhci_readl(xhci, &xhci->op_regs->status);
- if (temp == 0xffffffff) {
- xhci_dbg(xhci, "HW died, freeing TD.\n");
- td = (struct xhci_td *) urb->hcpriv;
-
- usb_hcd_unlink_urb_from_ep(hcd, urb);
- spin_unlock_irqrestore(&xhci->lock, flags);
- usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
- kfree(td);
- return ret;
- }
- if (xhci->xhc_state & XHCI_STATE_DYING) {
- xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on "
- "non-responsive xHCI host.\n",
- urb->ep->desc.bEndpointAddress, urb);
- /* Let the stop endpoint command watchdog timer (which set this
- * state) finish cleaning up the endpoint TD lists. We must
- * have caught it in the middle of dropping a lock and giving
- * back an URB.
- */
- goto done;
- }
-
- xhci_dbg(xhci, "Cancel URB %p\n", urb);
- xhci_dbg(xhci, "Event ring:\n");
- xhci_debug_ring(xhci, xhci->event_ring);
- ep_index = xhci_get_endpoint_index(&urb->ep->desc);
- ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
- ep_ring = ep->ring;
- xhci_dbg(xhci, "Endpoint ring:\n");
- xhci_debug_ring(xhci, ep_ring);
- td = (struct xhci_td *) urb->hcpriv;
-
- list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
- /* Queue a stop endpoint command, but only if this is
- * the first cancellation to be handled.
- */
- if (!(ep->ep_state & EP_HALT_PENDING)) {
- ep->ep_state |= EP_HALT_PENDING;
- ep->stop_cmds_pending++;
- ep->stop_cmd_timer.expires = jiffies +
- XHCI_STOP_EP_CMD_TIMEOUT * HZ;
- add_timer(&ep->stop_cmd_timer);
- xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
- xhci_ring_cmd_db(xhci);
- }
-done:
- spin_unlock_irqrestore(&xhci->lock, flags);
- return ret;
-}
-
-/* Drop an endpoint from a new bandwidth configuration for this device.
- * Only one call to this function is allowed per endpoint before
- * check_bandwidth() or reset_bandwidth() must be called.
- * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
- * add the endpoint to the schedule with possibly new parameters denoted by a
- * different endpoint descriptor in usb_host_endpoint.
- * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
- * not allowed.
- *
- * The USB core will not allow URBs to be queued to an endpoint that is being
- * disabled, so there's no need for mutual exclusion to protect
- * the xhci->devs[slot_id] structure.
- */
-int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
- struct usb_host_endpoint *ep)
-{
- struct xhci_hcd *xhci;
- struct xhci_container_ctx *in_ctx, *out_ctx;
- struct xhci_input_control_ctx *ctrl_ctx;
- struct xhci_slot_ctx *slot_ctx;
- unsigned int last_ctx;
- unsigned int ep_index;
- struct xhci_ep_ctx *ep_ctx;
- u32 drop_flag;
- u32 new_add_flags, new_drop_flags, new_slot_info;
- int ret;
-
- ret = xhci_check_args(hcd, udev, ep, 1, __func__);
- if (ret <= 0)
- return ret;
- xhci = hcd_to_xhci(hcd);
- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
-
- drop_flag = xhci_get_endpoint_flag(&ep->desc);
- if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) {
- xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n",
- __func__, drop_flag);
- return 0;
- }
-
- if (!xhci->devs || !xhci->devs[udev->slot_id]) {
- xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
- __func__);
- return -EINVAL;
- }
-
- in_ctx = xhci->devs[udev->slot_id]->in_ctx;
- out_ctx = xhci->devs[udev->slot_id]->out_ctx;
- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
- ep_index = xhci_get_endpoint_index(&ep->desc);
- ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
- /* If the HC already knows the endpoint is disabled,
- * or the HCD has noted it is disabled, ignore this request
- */
- if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED ||
- ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) {
- xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
- __func__, ep);
- return 0;
- }
-
- ctrl_ctx->drop_flags |= drop_flag;
- new_drop_flags = ctrl_ctx->drop_flags;
-
- ctrl_ctx->add_flags &= ~drop_flag;
- new_add_flags = ctrl_ctx->add_flags;
-
- last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
- slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
- /* Update the last valid endpoint context, if we deleted the last one */
- if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) {
- slot_ctx->dev_info &= ~LAST_CTX_MASK;
- slot_ctx->dev_info |= LAST_CTX(last_ctx);
- }
- new_slot_info = slot_ctx->dev_info;
-
- xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
-
- xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
- (unsigned int) ep->desc.bEndpointAddress,
- udev->slot_id,
- (unsigned int) new_drop_flags,
- (unsigned int) new_add_flags,
- (unsigned int) new_slot_info);
- return 0;
-}
-
-/* Add an endpoint to a new possible bandwidth configuration for this device.
- * Only one call to this function is allowed per endpoint before
- * check_bandwidth() or reset_bandwidth() must be called.
- * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
- * add the endpoint to the schedule with possibly new parameters denoted by a
- * different endpoint descriptor in usb_host_endpoint.
- * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
- * not allowed.
- *
- * The USB core will not allow URBs to be queued to an endpoint until the
- * configuration or alt setting is installed in the device, so there's no need
- * for mutual exclusion to protect the xhci->devs[slot_id] structure.
- */
-int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
- struct usb_host_endpoint *ep)
-{
- struct xhci_hcd *xhci;
- struct xhci_container_ctx *in_ctx, *out_ctx;
- unsigned int ep_index;
- struct xhci_ep_ctx *ep_ctx;
- struct xhci_slot_ctx *slot_ctx;
- struct xhci_input_control_ctx *ctrl_ctx;
- u32 added_ctxs;
- unsigned int last_ctx;
- u32 new_add_flags, new_drop_flags, new_slot_info;
- int ret = 0;
-
- ret = xhci_check_args(hcd, udev, ep, 1, __func__);
- if (ret <= 0) {
- /* So we won't queue a reset ep command for a root hub */
- ep->hcpriv = NULL;
- return ret;
- }
- xhci = hcd_to_xhci(hcd);
-
- added_ctxs = xhci_get_endpoint_flag(&ep->desc);
- last_ctx = xhci_last_valid_endpoint(added_ctxs);
- if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) {
- /* FIXME when we have to issue an evaluate endpoint command to
- * deal with ep0 max packet size changing once we get the
- * descriptors
- */
- xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n",
- __func__, added_ctxs);
- return 0;
- }
-
- if (!xhci->devs || !xhci->devs[udev->slot_id]) {
- xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
- __func__);
- return -EINVAL;
- }
-
- in_ctx = xhci->devs[udev->slot_id]->in_ctx;
- out_ctx = xhci->devs[udev->slot_id]->out_ctx;
- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
- ep_index = xhci_get_endpoint_index(&ep->desc);
- ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
- /* If the HCD has already noted the endpoint is enabled,
- * ignore this request.
- */
- if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) {
- xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
- __func__, ep);
- return 0;
- }
-
- /*
- * Configuration and alternate setting changes must be done in
- * process context, not interrupt context (or so documenation
- * for usb_set_interface() and usb_set_configuration() claim).
- */
- if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id],
- udev, ep, GFP_NOIO) < 0) {
- dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
- __func__, ep->desc.bEndpointAddress);
- return -ENOMEM;
- }
-
- ctrl_ctx->add_flags |= added_ctxs;
- new_add_flags = ctrl_ctx->add_flags;
-
- /* If xhci_endpoint_disable() was called for this endpoint, but the
- * xHC hasn't been notified yet through the check_bandwidth() call,
- * this re-adds a new state for the endpoint from the new endpoint
- * descriptors. We must drop and re-add this endpoint, so we leave the
- * drop flags alone.
- */
- new_drop_flags = ctrl_ctx->drop_flags;
-
- slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
- /* Update the last valid endpoint context, if we just added one past */
- if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) {
- slot_ctx->dev_info &= ~LAST_CTX_MASK;
- slot_ctx->dev_info |= LAST_CTX(last_ctx);
- }
- new_slot_info = slot_ctx->dev_info;
-
- /* Store the usb_device pointer for later use */
- ep->hcpriv = udev;
-
- xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
- (unsigned int) ep->desc.bEndpointAddress,
- udev->slot_id,
- (unsigned int) new_drop_flags,
- (unsigned int) new_add_flags,
- (unsigned int) new_slot_info);
- return 0;
-}
-
-static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev)
-{
- struct xhci_input_control_ctx *ctrl_ctx;
- struct xhci_ep_ctx *ep_ctx;
- struct xhci_slot_ctx *slot_ctx;
- int i;
-
- /* When a device's add flag and drop flag are zero, any subsequent
- * configure endpoint command will leave that endpoint's state
- * untouched. Make sure we don't leave any old state in the input
- * endpoint contexts.
- */
- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
- ctrl_ctx->drop_flags = 0;
- ctrl_ctx->add_flags = 0;
- slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
- slot_ctx->dev_info &= ~LAST_CTX_MASK;
- /* Endpoint 0 is always valid */
- slot_ctx->dev_info |= LAST_CTX(1);
- for (i = 1; i < 31; ++i) {
- ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i);
- ep_ctx->ep_info = 0;
- ep_ctx->ep_info2 = 0;
- ep_ctx->deq = 0;
- ep_ctx->tx_info = 0;
- }
-}
-
-static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
- struct usb_device *udev, int *cmd_status)
-{
- int ret;
-
- switch (*cmd_status) {
- case COMP_ENOMEM:
- dev_warn(&udev->dev, "Not enough host controller resources "
- "for new device state.\n");
- ret = -ENOMEM;
- /* FIXME: can we allocate more resources for the HC? */
- break;
- case COMP_BW_ERR:
- dev_warn(&udev->dev, "Not enough bandwidth "
- "for new device state.\n");
- ret = -ENOSPC;
- /* FIXME: can we go back to the old state? */
- break;
- case COMP_TRB_ERR:
- /* the HCD set up something wrong */
- dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, "
- "add flag = 1, "
- "and endpoint is not disabled.\n");
- ret = -EINVAL;
- break;
- case COMP_SUCCESS:
- dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
- ret = 0;
- break;
- default:
- xhci_err(xhci, "ERROR: unexpected command completion "
- "code 0x%x.\n", *cmd_status);
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
- struct usb_device *udev, int *cmd_status)
-{
- int ret;
- struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
-
- switch (*cmd_status) {
- case COMP_EINVAL:
- dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate "
- "context command.\n");
- ret = -EINVAL;
- break;
- case COMP_EBADSLT:
- dev_warn(&udev->dev, "WARN: slot not enabled for"
- "evaluate context command.\n");
- case COMP_CTX_STATE:
- dev_warn(&udev->dev, "WARN: invalid context state for "
- "evaluate context command.\n");
- xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
- ret = -EINVAL;
- break;
- case COMP_SUCCESS:
- dev_dbg(&udev->dev, "Successful evaluate context command\n");
- ret = 0;
- break;
- default:
- xhci_err(xhci, "ERROR: unexpected command completion "
- "code 0x%x.\n", *cmd_status);
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-/* Issue a configure endpoint command or evaluate context command
- * and wait for it to finish.
- */
-static int xhci_configure_endpoint(struct xhci_hcd *xhci,
- struct usb_device *udev,
- struct xhci_command *command,
- bool ctx_change, bool must_succeed)
-{
- int ret;
- int timeleft;
- unsigned long flags;
- struct xhci_container_ctx *in_ctx;
- struct completion *cmd_completion;
- int *cmd_status;
- struct xhci_virt_device *virt_dev;
-
- spin_lock_irqsave(&xhci->lock, flags);
- virt_dev = xhci->devs[udev->slot_id];
- if (command) {
- in_ctx = command->in_ctx;
- cmd_completion = command->completion;
- cmd_status = &command->status;
- command->command_trb = xhci->cmd_ring->enqueue;
- list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
- } else {
- in_ctx = virt_dev->in_ctx;
- cmd_completion = &virt_dev->cmd_completion;
- cmd_status = &virt_dev->cmd_status;
- }
-
- if (!ctx_change)
- ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
- udev->slot_id, must_succeed);
- else
- ret = xhci_queue_evaluate_context(xhci, in_ctx->dma,
- udev->slot_id);
- if (ret < 0) {
- if (command)
- list_del(&command->cmd_list);
- spin_unlock_irqrestore(&xhci->lock, flags);
- xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
- return -ENOMEM;
- }
- xhci_ring_cmd_db(xhci);
- spin_unlock_irqrestore(&xhci->lock, flags);
-
- /* Wait for the configure endpoint command to complete */
- timeleft = wait_for_completion_interruptible_timeout(
- cmd_completion,
- USB_CTRL_SET_TIMEOUT);
- if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for %s command\n",
- timeleft == 0 ? "Timeout" : "Signal",
- ctx_change == 0 ?
- "configure endpoint" :
- "evaluate context");
- /* FIXME cancel the configure endpoint command */
- return -ETIME;
- }
-
- if (!ctx_change)
- return xhci_configure_endpoint_result(xhci, udev, cmd_status);
- return xhci_evaluate_context_result(xhci, udev, cmd_status);
-}
-
-/* Called after one or more calls to xhci_add_endpoint() or
- * xhci_drop_endpoint(). If this call fails, the USB core is expected
- * to call xhci_reset_bandwidth().
- *
- * Since we are in the middle of changing either configuration or
- * installing a new alt setting, the USB core won't allow URBs to be
- * enqueued for any endpoint on the old config or interface. Nothing
- * else should be touching the xhci->devs[slot_id] structure, so we
- * don't need to take the xhci->lock for manipulating that.
- */
-int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
-{
- int i;
- int ret = 0;
- struct xhci_hcd *xhci;
- struct xhci_virt_device *virt_dev;
- struct xhci_input_control_ctx *ctrl_ctx;
- struct xhci_slot_ctx *slot_ctx;
-
- ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
- if (ret <= 0)
- return ret;
- xhci = hcd_to_xhci(hcd);
-
- if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) {
- xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
- __func__);
- return -EINVAL;
- }
- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
- virt_dev = xhci->devs[udev->slot_id];
-
- /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */
- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
- ctrl_ctx->add_flags |= SLOT_FLAG;
- ctrl_ctx->add_flags &= ~EP0_FLAG;
- ctrl_ctx->drop_flags &= ~SLOT_FLAG;
- ctrl_ctx->drop_flags &= ~EP0_FLAG;
- xhci_dbg(xhci, "New Input Control Context:\n");
- slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
- xhci_dbg_ctx(xhci, virt_dev->in_ctx,
- LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
-
- ret = xhci_configure_endpoint(xhci, udev, NULL,
- false, false);
- if (ret) {
- /* Callee should call reset_bandwidth() */
- return ret;
- }
-
- xhci_dbg(xhci, "Output context after successful config ep cmd:\n");
- xhci_dbg_ctx(xhci, virt_dev->out_ctx,
- LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
-
- xhci_zero_in_ctx(xhci, virt_dev);
- /* Install new rings and free or cache any old rings */
- for (i = 1; i < 31; ++i) {
- if (!virt_dev->eps[i].new_ring)
- continue;
- /* Only cache or free the old ring if it exists.
- * It may not if this is the first add of an endpoint.
- */
- if (virt_dev->eps[i].ring) {
- xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
- }
- virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
- virt_dev->eps[i].new_ring = NULL;
- }
-
- return ret;
-}
-
-void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct xhci_hcd *xhci;
- struct xhci_virt_device *virt_dev;
- int i, ret;
-
- ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
- if (ret <= 0)
- return;
- xhci = hcd_to_xhci(hcd);
-
- if (!xhci->devs || !xhci->devs[udev->slot_id]) {
- xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
- __func__);
- return;
- }
- xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
- virt_dev = xhci->devs[udev->slot_id];
- /* Free any rings allocated for added endpoints */
- for (i = 0; i < 31; ++i) {
- if (virt_dev->eps[i].new_ring) {
- xhci_ring_free(xhci, virt_dev->eps[i].new_ring);
- virt_dev->eps[i].new_ring = NULL;
- }
- }
- xhci_zero_in_ctx(xhci, virt_dev);
-}
-
-static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci,
- struct xhci_container_ctx *in_ctx,
- struct xhci_container_ctx *out_ctx,
- u32 add_flags, u32 drop_flags)
-{
- struct xhci_input_control_ctx *ctrl_ctx;
- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
- ctrl_ctx->add_flags = add_flags;
- ctrl_ctx->drop_flags = drop_flags;
- xhci_slot_copy(xhci, in_ctx, out_ctx);
- ctrl_ctx->add_flags |= SLOT_FLAG;
-
- xhci_dbg(xhci, "Input Context:\n");
- xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags));
-}
-
-void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
- unsigned int slot_id, unsigned int ep_index,
- struct xhci_dequeue_state *deq_state)
-{
- struct xhci_container_ctx *in_ctx;
- struct xhci_ep_ctx *ep_ctx;
- u32 added_ctxs;
- dma_addr_t addr;
-
- xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
- xhci->devs[slot_id]->out_ctx, ep_index);
- in_ctx = xhci->devs[slot_id]->in_ctx;
- ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
- addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg,
- deq_state->new_deq_ptr);
- if (addr == 0) {
- xhci_warn(xhci, "WARN Cannot submit config ep after "
- "reset ep command\n");
- xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
- deq_state->new_deq_seg,
- deq_state->new_deq_ptr);
- return;
- }
- ep_ctx->deq = addr | deq_state->new_cycle_state;
-
- added_ctxs = xhci_get_endpoint_flag_from_index(ep_index);
- xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx,
- xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs);
-}
-
-void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
- struct usb_device *udev, unsigned int ep_index)
-{
- struct xhci_dequeue_state deq_state;
- struct xhci_virt_ep *ep;
-
- xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
- ep = &xhci->devs[udev->slot_id]->eps[ep_index];
- /* We need to move the HW's dequeue pointer past this TD,
- * or it will attempt to resend it on the next doorbell ring.
- */
- xhci_find_new_dequeue_state(xhci, udev->slot_id,
- ep_index, ep->stopped_td,
- &deq_state);
-
- /* HW with the reset endpoint quirk will use the saved dequeue state to
- * issue a configure endpoint command later.
- */
- if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
- xhci_dbg(xhci, "Queueing new dequeue state\n");
- xhci_queue_new_dequeue_state(xhci, udev->slot_id,
- ep_index, &deq_state);
- } else {
- /* Better hope no one uses the input context between now and the
- * reset endpoint completion!
- */
- xhci_dbg(xhci, "Setting up input context for "
- "configure endpoint command\n");
- xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id,
- ep_index, &deq_state);
- }
-}
-
-/* Deal with stalled endpoints. The core should have sent the control message
- * to clear the halt condition. However, we need to make the xHCI hardware
- * reset its sequence number, since a device will expect a sequence number of
- * zero after the halt condition is cleared.
- * Context: in_interrupt
- */
-void xhci_endpoint_reset(struct usb_hcd *hcd,
- struct usb_host_endpoint *ep)
-{
- struct xhci_hcd *xhci;
- struct usb_device *udev;
- unsigned int ep_index;
- unsigned long flags;
- int ret;
- struct xhci_virt_ep *virt_ep;
-
- xhci = hcd_to_xhci(hcd);
- udev = (struct usb_device *) ep->hcpriv;
- /* Called with a root hub endpoint (or an endpoint that wasn't added
- * with xhci_add_endpoint()
- */
- if (!ep->hcpriv)
- return;
- ep_index = xhci_get_endpoint_index(&ep->desc);
- virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index];
- if (!virt_ep->stopped_td) {
- xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n",
- ep->desc.bEndpointAddress);
- return;
- }
- if (usb_endpoint_xfer_control(&ep->desc)) {
- xhci_dbg(xhci, "Control endpoint stall already handled.\n");
- return;
- }
-
- xhci_dbg(xhci, "Queueing reset endpoint command\n");
- spin_lock_irqsave(&xhci->lock, flags);
- ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index);
- /*
- * Can't change the ring dequeue pointer until it's transitioned to the
- * stopped state, which is only upon a successful reset endpoint
- * command. Better hope that last command worked!
- */
- if (!ret) {
- xhci_cleanup_stalled_ring(xhci, udev, ep_index);
- kfree(virt_ep->stopped_td);
- xhci_ring_cmd_db(xhci);
- }
- spin_unlock_irqrestore(&xhci->lock, flags);
-
- if (ret)
- xhci_warn(xhci, "FIXME allocate a new ring segment\n");
-}
-
-/*
- * This submits a Reset Device Command, which will set the device state to 0,
- * set the device address to 0, and disable all the endpoints except the default
- * control endpoint. The USB core should come back and call
- * xhci_address_device(), and then re-set up the configuration. If this is
- * called because of a usb_reset_and_verify_device(), then the old alternate
- * settings will be re-installed through the normal bandwidth allocation
- * functions.
- *
- * Wait for the Reset Device command to finish. Remove all structures
- * associated with the endpoints that were disabled. Clear the input device
- * structure? Cache the rings? Reset the control endpoint 0 max packet size?
- */
-int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
- int ret, i;
- unsigned long flags;
- struct xhci_hcd *xhci;
- unsigned int slot_id;
- struct xhci_virt_device *virt_dev;
- struct xhci_command *reset_device_cmd;
- int timeleft;
- int last_freed_endpoint;
-
- ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
- if (ret <= 0)
- return ret;
- xhci = hcd_to_xhci(hcd);
- slot_id = udev->slot_id;
- virt_dev = xhci->devs[slot_id];
- if (!virt_dev) {
- xhci_dbg(xhci, "%s called with invalid slot ID %u\n",
- __func__, slot_id);
- return -EINVAL;
- }
-
- xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
- /* Allocate the command structure that holds the struct completion.
- * Assume we're in process context, since the normal device reset
- * process has to wait for the device anyway. Storage devices are
- * reset as part of error handling, so use GFP_NOIO instead of
- * GFP_KERNEL.
- */
- reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
- if (!reset_device_cmd) {
- xhci_dbg(xhci, "Couldn't allocate command structure.\n");
- return -ENOMEM;
- }
-
- /* Attempt to submit the Reset Device command to the command ring */
- spin_lock_irqsave(&xhci->lock, flags);
- reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
- list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
- ret = xhci_queue_reset_device(xhci, slot_id);
- if (ret) {
- xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
- list_del(&reset_device_cmd->cmd_list);
- spin_unlock_irqrestore(&xhci->lock, flags);
- goto command_cleanup;
- }
- xhci_ring_cmd_db(xhci);
- spin_unlock_irqrestore(&xhci->lock, flags);
-
- /* Wait for the Reset Device command to finish */
- timeleft = wait_for_completion_interruptible_timeout(
- reset_device_cmd->completion,
- USB_CTRL_SET_TIMEOUT);
- if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for reset device command\n",
- timeleft == 0 ? "Timeout" : "Signal");
- spin_lock_irqsave(&xhci->lock, flags);
- /* The timeout might have raced with the event ring handler, so
- * only delete from the list if the item isn't poisoned.
- */
- if (reset_device_cmd->cmd_list.next != LIST_POISON1)
- list_del(&reset_device_cmd->cmd_list);
- spin_unlock_irqrestore(&xhci->lock, flags);
- ret = -ETIME;
- goto command_cleanup;
- }
-
- /* The Reset Device command can't fail, according to the 0.95/0.96 spec,
- * unless we tried to reset a slot ID that wasn't enabled,
- * or the device wasn't in the addressed or configured state.
- */
- ret = reset_device_cmd->status;
- switch (ret) {
- case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */
- case COMP_CTX_STATE: /* 0.96 completion code for same thing */
- xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n",
- slot_id,
- xhci_get_slot_state(xhci, virt_dev->out_ctx));
- xhci_info(xhci, "Not freeing device rings.\n");
- /* Don't treat this as an error. May change my mind later. */
- ret = 0;
- goto command_cleanup;
- case COMP_SUCCESS:
- xhci_dbg(xhci, "Successful reset device command.\n");
- break;
- default:
- if (xhci_is_vendor_info_code(xhci, ret))
- break;
- xhci_warn(xhci, "Unknown completion code %u for "
- "reset device command.\n", ret);
- ret = -EINVAL;
- goto command_cleanup;
- }
-
- /* Everything but endpoint 0 is disabled, so free or cache the rings. */
- last_freed_endpoint = 1;
- for (i = 1; i < 31; ++i) {
- if (!virt_dev->eps[i].ring)
- continue;
- xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
- last_freed_endpoint = i;
- }
- xhci_dbg(xhci, "Output context after successful reset device cmd:\n");
- xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint);
- ret = 0;
-
-command_cleanup:
- xhci_free_command(xhci, reset_device_cmd);
- return ret;
-}
-
-/*
- * At this point, the struct usb_device is about to go away, the device has
- * disconnected, and all traffic has been stopped and the endpoints have been
- * disabled. Free any HC data structures associated with that device.
- */
-void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- struct xhci_virt_device *virt_dev;
- unsigned long flags;
- u32 state;
- int i;
-
- if (udev->slot_id == 0)
- return;
- virt_dev = xhci->devs[udev->slot_id];
- if (!virt_dev)
- return;
-
- /* Stop any wayward timer functions (which may grab the lock) */
- for (i = 0; i < 31; ++i) {
- virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING;
- del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
- }
-
- spin_lock_irqsave(&xhci->lock, flags);
- /* Don't disable the slot if the host controller is dead. */
- state = xhci_readl(xhci, &xhci->op_regs->status);
- if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
- xhci_free_virt_device(xhci, udev->slot_id);
- spin_unlock_irqrestore(&xhci->lock, flags);
- return;
- }
-
- if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) {
- spin_unlock_irqrestore(&xhci->lock, flags);
- xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
- return;
- }
- xhci_ring_cmd_db(xhci);
- spin_unlock_irqrestore(&xhci->lock, flags);
- /*
- * Event command completion handler will free any data structures
- * associated with the slot. XXX Can free sleep?
- */
-}
-
-/*
- * Returns 0 if the xHC ran out of device slots, the Enable Slot command
- * timed out, or allocating memory failed. Returns 1 on success.
- */
-int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- unsigned long flags;
- int timeleft;
- int ret;
-
- spin_lock_irqsave(&xhci->lock, flags);
- ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0);
- if (ret) {
- spin_unlock_irqrestore(&xhci->lock, flags);
- xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
- return 0;
- }
- xhci_ring_cmd_db(xhci);
- spin_unlock_irqrestore(&xhci->lock, flags);
-
- /* XXX: how much time for xHC slot assignment? */
- timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
- USB_CTRL_SET_TIMEOUT);
- if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for a slot\n",
- timeleft == 0 ? "Timeout" : "Signal");
- /* FIXME cancel the enable slot request */
- return 0;
- }
-
- if (!xhci->slot_id) {
- xhci_err(xhci, "Error while assigning device slot ID\n");
- return 0;
- }
- /* xhci_alloc_virt_device() does not touch rings; no need to lock */
- if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) {
- /* Disable slot, if we can do it without mem alloc */
- xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
- spin_lock_irqsave(&xhci->lock, flags);
- if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id))
- xhci_ring_cmd_db(xhci);
- spin_unlock_irqrestore(&xhci->lock, flags);
- return 0;
- }
- udev->slot_id = xhci->slot_id;
- /* Is this a LS or FS device under a HS hub? */
- /* Hub or peripherial? */
- return 1;
-}
-
-/*
- * Issue an Address Device command (which will issue a SetAddress request to
- * the device).
- * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so
- * we should only issue and wait on one address command at the same time.
- *
- * We add one to the device address issued by the hardware because the USB core
- * uses address 1 for the root hubs (even though they're not really devices).
- */
-int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
-{
- unsigned long flags;
- int timeleft;
- struct xhci_virt_device *virt_dev;
- int ret = 0;
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- struct xhci_slot_ctx *slot_ctx;
- struct xhci_input_control_ctx *ctrl_ctx;
- u64 temp_64;
-
- if (!udev->slot_id) {
- xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id);
- return -EINVAL;
- }
-
- virt_dev = xhci->devs[udev->slot_id];
-
- /* If this is a Set Address to an unconfigured device, setup ep 0 */
- if (!udev->config)
- xhci_setup_addressable_virt_dev(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);
-
- spin_lock_irqsave(&xhci->lock, flags);
- ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
- udev->slot_id);
- if (ret) {
- spin_unlock_irqrestore(&xhci->lock, flags);
- xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
- return ret;
- }
- xhci_ring_cmd_db(xhci);
- spin_unlock_irqrestore(&xhci->lock, flags);
-
- /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
- timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
- USB_CTRL_SET_TIMEOUT);
- /* FIXME: From section 4.3.4: "Software shall be responsible for timing
- * the SetAddress() "recovery interval" required by USB and aborting the
- * command on a timeout.
- */
- if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for a slot\n",
- timeleft == 0 ? "Timeout" : "Signal");
- /* FIXME cancel the address device command */
- return -ETIME;
- }
-
- switch (virt_dev->cmd_status) {
- case COMP_CTX_STATE:
- case COMP_EBADSLT:
- xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n",
- udev->slot_id);
- ret = -EINVAL;
- break;
- case COMP_TX_ERR:
- dev_warn(&udev->dev, "Device not responding to set address.\n");
- ret = -EPROTO;
- break;
- case COMP_SUCCESS:
- xhci_dbg(xhci, "Successful Address Device command\n");
- break;
- default:
- xhci_err(xhci, "ERROR: unexpected command completion "
- "code 0x%x.\n", virt_dev->cmd_status);
- xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
- xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
- ret = -EINVAL;
- break;
- }
- if (ret) {
- return ret;
- }
- temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
- xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64);
- xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n",
- udev->slot_id,
- &xhci->dcbaa->dev_context_ptrs[udev->slot_id],
- (unsigned long long)
- xhci->dcbaa->dev_context_ptrs[udev->slot_id]);
- xhci_dbg(xhci, "Output Context DMA address = %#08llx\n",
- (unsigned long long)virt_dev->out_ctx->dma);
- xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
- xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
- xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
- xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
- /*
- * USB core uses address 1 for the roothubs, so we add one to the
- * address given back to us by the HC.
- */
- slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
- udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1;
- /* Zero the input context control for later use */
- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
- ctrl_ctx->add_flags = 0;
- ctrl_ctx->drop_flags = 0;
-
- xhci_dbg(xhci, "Device address = %d\n", udev->devnum);
- /* XXX Meh, not sure if anyone else but choose_address uses this. */
- set_bit(udev->devnum, udev->bus->devmap.devicemap);
-
- return 0;
-}
-
-/* Once a hub descriptor is fetched for a device, we need to update the xHC's
- * internal data structures for the device.
- */
-int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
- struct usb_tt *tt, gfp_t mem_flags)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- struct xhci_virt_device *vdev;
- struct xhci_command *config_cmd;
- struct xhci_input_control_ctx *ctrl_ctx;
- struct xhci_slot_ctx *slot_ctx;
- unsigned long flags;
- unsigned think_time;
- int ret;
-
- /* Ignore root hubs */
- if (!hdev->parent)
- return 0;
-
- vdev = xhci->devs[hdev->slot_id];
- if (!vdev) {
- xhci_warn(xhci, "Cannot update hub desc for unknown device.\n");
- return -EINVAL;
- }
- config_cmd = xhci_alloc_command(xhci, true, true, mem_flags);
- if (!config_cmd) {
- xhci_dbg(xhci, "Could not allocate xHCI command structure.\n");
- return -ENOMEM;
- }
-
- spin_lock_irqsave(&xhci->lock, flags);
- xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx);
- ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx);
- ctrl_ctx->add_flags |= SLOT_FLAG;
- slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
- slot_ctx->dev_info |= DEV_HUB;
- if (tt->multi)
- slot_ctx->dev_info |= DEV_MTT;
- if (xhci->hci_version > 0x95) {
- xhci_dbg(xhci, "xHCI version %x needs hub "
- "TT think time and number of ports\n",
- (unsigned int) xhci->hci_version);
- slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild);
- /* Set TT think time - convert from ns to FS bit times.
- * 0 = 8 FS bit times, 1 = 16 FS bit times,
- * 2 = 24 FS bit times, 3 = 32 FS bit times.
- */
- think_time = tt->think_time;
- if (think_time != 0)
- think_time = (think_time / 666) - 1;
- slot_ctx->tt_info |= TT_THINK_TIME(think_time);
- } else {
- xhci_dbg(xhci, "xHCI version %x doesn't need hub "
- "TT think time or number of ports\n",
- (unsigned int) xhci->hci_version);
- }
- slot_ctx->dev_state = 0;
- spin_unlock_irqrestore(&xhci->lock, flags);
-
- xhci_dbg(xhci, "Set up %s for hub device.\n",
- (xhci->hci_version > 0x95) ?
- "configure endpoint" : "evaluate context");
- xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id);
- xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0);
-
- /* Issue and wait for the configure endpoint or
- * evaluate context command.
- */
- if (xhci->hci_version > 0x95)
- ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
- false, false);
- else
- ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
- true, false);
-
- xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id);
- xhci_dbg_ctx(xhci, vdev->out_ctx, 0);
-
- xhci_free_command(xhci, config_cmd);
- return ret;
-}
-
-int xhci_get_frame(struct usb_hcd *hcd)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- /* EHCI mods by the periodic size. Why? */
- return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3;
-}
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_LICENSE("GPL");
-
-static int __init xhci_hcd_init(void)
-{
-#ifdef CONFIG_PCI
- int retval = 0;
-
- retval = xhci_register_pci();
-
- if (retval < 0) {
- printk(KERN_DEBUG "Problem registering PCI driver.");
- return retval;
- }
-#endif
- /*
- * Check the compiler generated sizes of structures that must be laid
- * out in specific ways for hardware access.
- */
- BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
- BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8);
- BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8);
- /* xhci_device_control has eight fields, and also
- * embeds one xhci_slot_ctx and 31 xhci_ep_ctx
- */
- BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8);
- BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8);
- BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8);
- BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8);
- BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
- /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
- BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
- BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
- return 0;
-}
-module_init(xhci_hcd_init);
-
-static void __exit xhci_hcd_cleanup(void)
-{
-#ifdef CONFIG_PCI
- xhci_unregister_pci();
-#endif
-}
-module_exit(xhci_hcd_cleanup);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 49f7d72f8b1..d64f5724bfc 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -22,6 +22,7 @@
#include <linux/usb.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/dmapool.h>
#include "xhci.h"
@@ -566,8 +567,13 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
if (interval < 3)
interval = 3;
if ((1 << interval) != 8*ep->desc.bInterval)
- dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n",
- ep->desc.bEndpointAddress, 1 << interval);
+ dev_warn(&udev->dev,
+ "ep %#x - rounding interval"
+ " to %d microframes, "
+ "ep desc says %d microframes\n",
+ ep->desc.bEndpointAddress,
+ 1 << interval,
+ 8*ep->desc.bInterval);
}
break;
default:
@@ -576,6 +582,19 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
return EP_INTERVAL(interval);
}
+/* The "Mult" field in the endpoint context is only set for SuperSpeed devices.
+ * High speed endpoint descriptors can define "the number of additional
+ * transaction opportunities per microframe", but that goes in the Max Burst
+ * endpoint context field.
+ */
+static inline u32 xhci_get_endpoint_mult(struct usb_device *udev,
+ struct usb_host_endpoint *ep)
+{
+ if (udev->speed != USB_SPEED_SUPER || !ep->ss_ep_comp)
+ return 0;
+ return ep->ss_ep_comp->desc.bmAttributes;
+}
+
static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
struct usb_host_endpoint *ep)
{
@@ -606,6 +625,36 @@ static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
return type;
}
+/* Return the maximum endpoint service interval time (ESIT) payload.
+ * Basically, this is the maxpacket size, multiplied by the burst size
+ * and mult size.
+ */
+static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
+ struct usb_device *udev,
+ struct usb_host_endpoint *ep)
+{
+ int max_burst;
+ int max_packet;
+
+ /* Only applies for interrupt or isochronous endpoints */
+ if (usb_endpoint_xfer_control(&ep->desc) ||
+ usb_endpoint_xfer_bulk(&ep->desc))
+ return 0;
+
+ if (udev->speed == USB_SPEED_SUPER) {
+ if (ep->ss_ep_comp)
+ return ep->ss_ep_comp->desc.wBytesPerInterval;
+ xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n");
+ /* Assume no bursts, no multiple opportunities to send. */
+ return ep->desc.wMaxPacketSize;
+ }
+
+ max_packet = ep->desc.wMaxPacketSize & 0x3ff;
+ max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
+ /* A 0 in max burst means 1 transfer per ESIT */
+ return max_packet * (max_burst + 1);
+}
+
int xhci_endpoint_init(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
struct usb_device *udev,
@@ -617,6 +666,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
struct xhci_ring *ep_ring;
unsigned int max_packet;
unsigned int max_burst;
+ u32 max_esit_payload;
ep_index = xhci_get_endpoint_index(&ep->desc);
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
@@ -638,6 +688,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
+ ep_ctx->ep_info |= EP_MULT(xhci_get_endpoint_mult(udev, ep));
/* FIXME dig Mult and streams info out of ep companion desc */
@@ -683,6 +734,26 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
default:
BUG();
}
+ max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
+ ep_ctx->tx_info = MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload);
+
+ /*
+ * XXX no idea how to calculate the average TRB buffer length for bulk
+ * endpoints, as the driver gives us no clue how big each scatter gather
+ * list entry (or buffer) is going to be.
+ *
+ * For isochronous and interrupt endpoints, we set it to the max
+ * available, until we have new API in the USB core to allow drivers to
+ * declare how much bandwidth they actually need.
+ *
+ * Normally, it would be calculated by taking the total of the buffer
+ * lengths in the TD and then dividing by the number of TRBs in a TD,
+ * including link TRBs, No-op TRBs, and Event data TRBs. Since we don't
+ * use Event Data TRBs, and we don't chain in a link TRB on short
+ * transfers, we're basically dividing by 1.
+ */
+ ep_ctx->tx_info |= AVG_TRB_LENGTH_FOR_EP(max_esit_payload);
+
/* FIXME Debug endpoint context */
return 0;
}
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6ba841bca4a..85d7e8f2085 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -65,6 +65,7 @@
*/
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include "xhci.h"
/*
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
new file mode 100644
index 00000000000..7e427727390
--- /dev/null
+++ b/drivers/usb/host/xhci.c
@@ -0,0 +1,1918 @@
+/*
+ * xHCI host controller driver
+ *
+ * Copyright (C) 2008 Intel Corp.
+ *
+ * Author: Sarah Sharp
+ * Some code borrowed from the Linux EHCI driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in 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/irq.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+
+#include "xhci.h"
+
+#define DRIVER_AUTHOR "Sarah Sharp"
+#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
+
+/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
+static int link_quirk;
+module_param(link_quirk, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
+
+/* TODO: copied from ehci-hcd.c - can this be refactored? */
+/*
+ * handshake - spin reading hc until handshake completes or fails
+ * @ptr: address of hc register to be read
+ * @mask: bits to look at in result of read
+ * @done: value of those bits when handshake succeeds
+ * @usec: timeout in microseconds
+ *
+ * Returns negative errno, or zero on success
+ *
+ * Success happens when the "mask" bits have the specified value (hardware
+ * handshake done). There are two failure modes: "usec" have passed (major
+ * hardware flakeout), or the register reads as all-ones (hardware removed).
+ */
+static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
+ u32 mask, u32 done, int usec)
+{
+ u32 result;
+
+ do {
+ result = xhci_readl(xhci, ptr);
+ if (result == ~(u32)0) /* card removed */
+ return -ENODEV;
+ result &= mask;
+ if (result == done)
+ return 0;
+ udelay(1);
+ usec--;
+ } while (usec > 0);
+ return -ETIMEDOUT;
+}
+
+/*
+ * Disable interrupts and begin the xHCI halting process.
+ */
+void xhci_quiesce(struct xhci_hcd *xhci)
+{
+ u32 halted;
+ u32 cmd;
+ u32 mask;
+
+ mask = ~(XHCI_IRQS);
+ halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
+ if (!halted)
+ mask &= ~CMD_RUN;
+
+ cmd = xhci_readl(xhci, &xhci->op_regs->command);
+ cmd &= mask;
+ xhci_writel(xhci, cmd, &xhci->op_regs->command);
+}
+
+/*
+ * Force HC into halt state.
+ *
+ * Disable any IRQs and clear the run/stop bit.
+ * HC will complete any current and actively pipelined transactions, and
+ * should halt within 16 microframes of the run/stop bit being cleared.
+ * Read HC Halted bit in the status register to see when the HC is finished.
+ * XXX: shouldn't we set HC_STATE_HALT here somewhere?
+ */
+int xhci_halt(struct xhci_hcd *xhci)
+{
+ xhci_dbg(xhci, "// Halt the HC\n");
+ xhci_quiesce(xhci);
+
+ return handshake(xhci, &xhci->op_regs->status,
+ STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
+}
+
+/*
+ * Reset a halted HC, and set the internal HC state to HC_STATE_HALT.
+ *
+ * This resets pipelines, timers, counters, state machines, etc.
+ * Transactions will be terminated immediately, and operational registers
+ * will be set to their defaults.
+ */
+int xhci_reset(struct xhci_hcd *xhci)
+{
+ u32 command;
+ u32 state;
+
+ state = xhci_readl(xhci, &xhci->op_regs->status);
+ if ((state & STS_HALT) == 0) {
+ xhci_warn(xhci, "Host controller not halted, aborting reset.\n");
+ return 0;
+ }
+
+ xhci_dbg(xhci, "// Reset the HC\n");
+ command = xhci_readl(xhci, &xhci->op_regs->command);
+ command |= CMD_RESET;
+ xhci_writel(xhci, command, &xhci->op_regs->command);
+ /* XXX: Why does EHCI set this here? Shouldn't other code do this? */
+ xhci_to_hcd(xhci)->state = HC_STATE_HALT;
+
+ return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
+}
+
+
+#if 0
+/* Set up MSI-X table for entry 0 (may claim other entries later) */
+static int xhci_setup_msix(struct xhci_hcd *xhci)
+{
+ int ret;
+ struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+
+ xhci->msix_count = 0;
+ /* XXX: did I do this right? ixgbe does kcalloc for more than one */
+ xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL);
+ if (!xhci->msix_entries) {
+ xhci_err(xhci, "Failed to allocate MSI-X entries\n");
+ return -ENOMEM;
+ }
+ xhci->msix_entries[0].entry = 0;
+
+ ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count);
+ if (ret) {
+ xhci_err(xhci, "Failed to enable MSI-X\n");
+ goto free_entries;
+ }
+
+ /*
+ * Pass the xhci pointer value as the request_irq "cookie".
+ * If more irqs are added, this will need to be unique for each one.
+ */
+ ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0,
+ "xHCI", xhci_to_hcd(xhci));
+ if (ret) {
+ xhci_err(xhci, "Failed to allocate MSI-X interrupt\n");
+ goto disable_msix;
+ }
+ xhci_dbg(xhci, "Finished setting up MSI-X\n");
+ return 0;
+
+disable_msix:
+ pci_disable_msix(pdev);
+free_entries:
+ kfree(xhci->msix_entries);
+ xhci->msix_entries = NULL;
+ return ret;
+}
+
+/* XXX: code duplication; can xhci_setup_msix call this? */
+/* Free any IRQs and disable MSI-X */
+static void xhci_cleanup_msix(struct xhci_hcd *xhci)
+{
+ struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+ if (!xhci->msix_entries)
+ return;
+
+ free_irq(xhci->msix_entries[0].vector, xhci);
+ pci_disable_msix(pdev);
+ kfree(xhci->msix_entries);
+ xhci->msix_entries = NULL;
+ xhci_dbg(xhci, "Finished cleaning up MSI-X\n");
+}
+#endif
+
+/*
+ * Initialize memory for HCD and xHC (one-time init).
+ *
+ * Program the PAGESIZE register, initialize the device context array, create
+ * device contexts (?), set up a command ring segment (or two?), create event
+ * ring (one for now).
+ */
+int xhci_init(struct usb_hcd *hcd)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ int retval = 0;
+
+ xhci_dbg(xhci, "xhci_init\n");
+ spin_lock_init(&xhci->lock);
+ if (link_quirk) {
+ xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n");
+ xhci->quirks |= XHCI_LINK_TRB_QUIRK;
+ } else {
+ xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n");
+ }
+ retval = xhci_mem_init(xhci, GFP_KERNEL);
+ xhci_dbg(xhci, "Finished xhci_init\n");
+
+ return retval;
+}
+
+/*
+ * Called in interrupt context when there might be work
+ * queued on the event ring
+ *
+ * xhci->lock must be held by caller.
+ */
+static void xhci_work(struct xhci_hcd *xhci)
+{
+ u32 temp;
+ u64 temp_64;
+
+ /*
+ * Clear the op reg interrupt status first,
+ * so we can receive interrupts from other MSI-X interrupters.
+ * Write 1 to clear the interrupt status.
+ */
+ temp = xhci_readl(xhci, &xhci->op_regs->status);
+ temp |= STS_EINT;
+ xhci_writel(xhci, temp, &xhci->op_regs->status);
+ /* FIXME when MSI-X is supported and there are multiple vectors */
+ /* Clear the MSI-X event interrupt status */
+
+ /* Acknowledge the interrupt */
+ temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+ temp |= 0x3;
+ xhci_writel(xhci, temp, &xhci->ir_set->irq_pending);
+ /* Flush posted writes */
+ xhci_readl(xhci, &xhci->ir_set->irq_pending);
+
+ if (xhci->xhc_state & XHCI_STATE_DYING)
+ xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
+ "Shouldn't IRQs be disabled?\n");
+ else
+ /* FIXME this should be a delayed service routine
+ * that clears the EHB.
+ */
+ xhci_handle_event(xhci);
+
+ /* Clear the event handler busy flag (RW1C); the event ring should be empty. */
+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue);
+ /* Flush posted writes -- FIXME is this necessary? */
+ xhci_readl(xhci, &xhci->ir_set->irq_pending);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * xHCI spec says we can get an interrupt, and if the HC has an error condition,
+ * we might get bad data out of the event ring. Section 4.10.2.7 has a list of
+ * indicators of an event TRB error, but we check the status *first* to be safe.
+ */
+irqreturn_t xhci_irq(struct usb_hcd *hcd)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ u32 temp, temp2;
+ union xhci_trb *trb;
+
+ spin_lock(&xhci->lock);
+ trb = xhci->event_ring->dequeue;
+ /* Check if the xHC generated the interrupt, or the irq is shared */
+ temp = xhci_readl(xhci, &xhci->op_regs->status);
+ temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+ if (temp == 0xffffffff && temp2 == 0xffffffff)
+ goto hw_died;
+
+ if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) {
+ spin_unlock(&xhci->lock);
+ return IRQ_NONE;
+ }
+ xhci_dbg(xhci, "op reg status = %08x\n", temp);
+ xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2);
+ xhci_dbg(xhci, "Event ring dequeue ptr:\n");
+ xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n",
+ (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb),
+ lower_32_bits(trb->link.segment_ptr),
+ upper_32_bits(trb->link.segment_ptr),
+ (unsigned int) trb->link.intr_target,
+ (unsigned int) trb->link.control);
+
+ if (temp & STS_FATAL) {
+ xhci_warn(xhci, "WARNING: Host System Error\n");
+ xhci_halt(xhci);
+hw_died:
+ xhci_to_hcd(xhci)->state = HC_STATE_HALT;
+ spin_unlock(&xhci->lock);
+ return -ESHUTDOWN;
+ }
+
+ xhci_work(xhci);
+ spin_unlock(&xhci->lock);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
+void xhci_event_ring_work(unsigned long arg)
+{
+ unsigned long flags;
+ int temp;
+ u64 temp_64;
+ struct xhci_hcd *xhci = (struct xhci_hcd *) arg;
+ int i, j;
+
+ xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies);
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ temp = xhci_readl(xhci, &xhci->op_regs->status);
+ xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
+ if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
+ xhci_dbg(xhci, "HW died, polling stopped.\n");
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return;
+ }
+
+ temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+ xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp);
+ xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled);
+ xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask);
+ xhci->error_bitmask = 0;
+ xhci_dbg(xhci, "Event ring:\n");
+ xhci_debug_segment(xhci, xhci->event_ring->deq_seg);
+ xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ temp_64 &= ~ERST_PTR_MASK;
+ xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
+ xhci_dbg(xhci, "Command ring:\n");
+ xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg);
+ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
+ xhci_dbg_cmd_ptrs(xhci);
+ for (i = 0; i < MAX_HC_SLOTS; ++i) {
+ if (!xhci->devs[i])
+ continue;
+ for (j = 0; j < 31; ++j) {
+ struct xhci_ring *ring = xhci->devs[i]->eps[j].ring;
+ if (!ring)
+ continue;
+ xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
+ xhci_debug_segment(xhci, ring->deq_seg);
+ }
+ }
+
+ if (xhci->noops_submitted != NUM_TEST_NOOPS)
+ if (xhci_setup_one_noop(xhci))
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ if (!xhci->zombie)
+ mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ);
+ else
+ xhci_dbg(xhci, "Quit polling the event ring.\n");
+}
+#endif
+
+/*
+ * Start the HC after it was halted.
+ *
+ * This function is called by the USB core when the HC driver is added.
+ * Its opposite is xhci_stop().
+ *
+ * xhci_init() must be called once before this function can be called.
+ * Reset the HC, enable device slot contexts, program DCBAAP, and
+ * set command ring pointer and event ring pointer.
+ *
+ * Setup MSI-X vectors and enable interrupts.
+ */
+int xhci_run(struct usb_hcd *hcd)
+{
+ u32 temp;
+ u64 temp_64;
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ void (*doorbell)(struct xhci_hcd *) = NULL;
+
+ hcd->uses_new_polling = 1;
+ hcd->poll_rh = 0;
+
+ xhci_dbg(xhci, "xhci_run\n");
+#if 0 /* FIXME: MSI not setup yet */
+ /* Do this at the very last minute */
+ ret = xhci_setup_msix(xhci);
+ if (!ret)
+ return ret;
+
+ return -ENOSYS;
+#endif
+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
+ init_timer(&xhci->event_ring_timer);
+ xhci->event_ring_timer.data = (unsigned long) xhci;
+ xhci->event_ring_timer.function = xhci_event_ring_work;
+ /* Poll the event ring */
+ xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ;
+ xhci->zombie = 0;
+ xhci_dbg(xhci, "Setting event ring polling timer\n");
+ add_timer(&xhci->event_ring_timer);
+#endif
+
+ xhci_dbg(xhci, "Command ring memory map follows:\n");
+ xhci_debug_ring(xhci, xhci->cmd_ring);
+ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
+ xhci_dbg_cmd_ptrs(xhci);
+
+ xhci_dbg(xhci, "ERST memory map follows:\n");
+ xhci_dbg_erst(xhci, &xhci->erst);
+ xhci_dbg(xhci, "Event ring:\n");
+ xhci_debug_ring(xhci, xhci->event_ring);
+ xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ temp_64 &= ~ERST_PTR_MASK;
+ xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
+
+ xhci_dbg(xhci, "// Set the interrupt modulation register\n");
+ temp = xhci_readl(xhci, &xhci->ir_set->irq_control);
+ temp &= ~ER_IRQ_INTERVAL_MASK;
+ temp |= (u32) 160;
+ xhci_writel(xhci, temp, &xhci->ir_set->irq_control);
+
+ /* Set the HCD state before we enable the irqs */
+ hcd->state = HC_STATE_RUNNING;
+ temp = xhci_readl(xhci, &xhci->op_regs->command);
+ temp |= (CMD_EIE);
+ xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n",
+ temp);
+ xhci_writel(xhci, temp, &xhci->op_regs->command);
+
+ temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+ xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n",
+ xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp));
+ xhci_writel(xhci, ER_IRQ_ENABLE(temp),
+ &xhci->ir_set->irq_pending);
+ xhci_print_ir_set(xhci, xhci->ir_set, 0);
+
+ if (NUM_TEST_NOOPS > 0)
+ doorbell = xhci_setup_one_noop(xhci);
+
+ temp = xhci_readl(xhci, &xhci->op_regs->command);
+ temp |= (CMD_RUN);
+ xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
+ temp);
+ xhci_writel(xhci, temp, &xhci->op_regs->command);
+ /* Flush PCI posted writes */
+ temp = xhci_readl(xhci, &xhci->op_regs->command);
+ xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp);
+ if (doorbell)
+ (*doorbell)(xhci);
+
+ xhci_dbg(xhci, "Finished xhci_run\n");
+ return 0;
+}
+
+/*
+ * Stop xHCI driver.
+ *
+ * This function is called by the USB core when the HC driver is removed.
+ * Its opposite is xhci_run().
+ *
+ * Disable device contexts, disable IRQs, and quiesce the HC.
+ * Reset the HC, finish any completed transactions, and cleanup memory.
+ */
+void xhci_stop(struct usb_hcd *hcd)
+{
+ u32 temp;
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+ spin_lock_irq(&xhci->lock);
+ xhci_halt(xhci);
+ xhci_reset(xhci);
+ spin_unlock_irq(&xhci->lock);
+
+#if 0 /* No MSI yet */
+ xhci_cleanup_msix(xhci);
+#endif
+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
+ /* Tell the event ring poll function not to reschedule */
+ xhci->zombie = 1;
+ del_timer_sync(&xhci->event_ring_timer);
+#endif
+
+ xhci_dbg(xhci, "// Disabling event ring interrupts\n");
+ temp = xhci_readl(xhci, &xhci->op_regs->status);
+ xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status);
+ temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+ xhci_writel(xhci, ER_IRQ_DISABLE(temp),
+ &xhci->ir_set->irq_pending);
+ xhci_print_ir_set(xhci, xhci->ir_set, 0);
+
+ xhci_dbg(xhci, "cleaning up memory\n");
+ xhci_mem_cleanup(xhci);
+ xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
+ xhci_readl(xhci, &xhci->op_regs->status));
+}
+
+/*
+ * Shutdown HC (not bus-specific)
+ *
+ * This is called when the machine is rebooting or halting. We assume that the
+ * machine will be powered off, and the HC's internal state will be reset.
+ * Don't bother to free memory.
+ */
+void xhci_shutdown(struct usb_hcd *hcd)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+ spin_lock_irq(&xhci->lock);
+ xhci_halt(xhci);
+ spin_unlock_irq(&xhci->lock);
+
+#if 0
+ xhci_cleanup_msix(xhci);
+#endif
+
+ xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
+ xhci_readl(xhci, &xhci->op_regs->status));
+}
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and
+ * HCDs. Find the index for an endpoint given its descriptor. Use the return
+ * value to right shift 1 for the bitmask.
+ *
+ * Index = (epnum * 2) + direction - 1,
+ * where direction = 0 for OUT, 1 for IN.
+ * For control endpoints, the IN index is used (OUT index is unused), so
+ * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2)
+ */
+unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc)
+{
+ unsigned int index;
+ if (usb_endpoint_xfer_control(desc))
+ index = (unsigned int) (usb_endpoint_num(desc)*2);
+ else
+ index = (unsigned int) (usb_endpoint_num(desc)*2) +
+ (usb_endpoint_dir_in(desc) ? 1 : 0) - 1;
+ return index;
+}
+
+/* Find the flag for this endpoint (for use in the control context). Use the
+ * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
+ * bit 1, etc.
+ */
+unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc)
+{
+ return 1 << (xhci_get_endpoint_index(desc) + 1);
+}
+
+/* Find the flag for this endpoint (for use in the control context). Use the
+ * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
+ * bit 1, etc.
+ */
+unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index)
+{
+ return 1 << (ep_index + 1);
+}
+
+/* Compute the last valid endpoint context index. Basically, this is the
+ * endpoint index plus one. For slot contexts with more than valid endpoint,
+ * we find the most significant bit set in the added contexts flags.
+ * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000
+ * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one.
+ */
+unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
+{
+ return fls(added_ctxs) - 1;
+}
+
+/* Returns 1 if the arguments are OK;
+ * returns 0 this is a root hub; returns -EINVAL for NULL pointers.
+ */
+int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
+ struct usb_host_endpoint *ep, int check_ep, const char *func) {
+ if (!hcd || (check_ep && !ep) || !udev) {
+ printk(KERN_DEBUG "xHCI %s called with invalid args\n",
+ func);
+ return -EINVAL;
+ }
+ if (!udev->parent) {
+ printk(KERN_DEBUG "xHCI %s called for root hub\n",
+ func);
+ return 0;
+ }
+ if (!udev->slot_id) {
+ printk(KERN_DEBUG "xHCI %s called with unaddressed device\n",
+ func);
+ return -EINVAL;
+ }
+ return 1;
+}
+
+static int xhci_configure_endpoint(struct xhci_hcd *xhci,
+ struct usb_device *udev, struct xhci_command *command,
+ bool ctx_change, bool must_succeed);
+
+/*
+ * Full speed devices may have a max packet size greater than 8 bytes, but the
+ * USB core doesn't know that until it reads the first 8 bytes of the
+ * descriptor. If the usb_device's max packet size changes after that point,
+ * we need to issue an evaluate context command and wait on it.
+ */
+static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
+ unsigned int ep_index, struct urb *urb)
+{
+ struct xhci_container_ctx *in_ctx;
+ struct xhci_container_ctx *out_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_ep_ctx *ep_ctx;
+ int max_packet_size;
+ int hw_max_packet_size;
+ int ret = 0;
+
+ out_ctx = xhci->devs[slot_id]->out_ctx;
+ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+ hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2);
+ max_packet_size = urb->dev->ep0.desc.wMaxPacketSize;
+ if (hw_max_packet_size != max_packet_size) {
+ xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n");
+ xhci_dbg(xhci, "Max packet size in usb_device = %d\n",
+ max_packet_size);
+ xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n",
+ hw_max_packet_size);
+ xhci_dbg(xhci, "Issuing evaluate context command.\n");
+
+ /* Set up the modified control endpoint 0 */
+ xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
+ xhci->devs[slot_id]->out_ctx, ep_index);
+ in_ctx = xhci->devs[slot_id]->in_ctx;
+ ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
+ ep_ctx->ep_info2 &= ~MAX_PACKET_MASK;
+ ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size);
+
+ /* Set up the input context flags for the command */
+ /* FIXME: This won't work if a non-default control endpoint
+ * changes max packet sizes.
+ */
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
+ ctrl_ctx->add_flags = EP0_FLAG;
+ ctrl_ctx->drop_flags = 0;
+
+ xhci_dbg(xhci, "Slot %d input context\n", slot_id);
+ xhci_dbg_ctx(xhci, in_ctx, ep_index);
+ xhci_dbg(xhci, "Slot %d output context\n", slot_id);
+ xhci_dbg_ctx(xhci, out_ctx, ep_index);
+
+ ret = xhci_configure_endpoint(xhci, urb->dev, NULL,
+ true, false);
+
+ /* Clean up the input context for later use by bandwidth
+ * functions.
+ */
+ ctrl_ctx->add_flags = SLOT_FLAG;
+ }
+ return ret;
+}
+
+/*
+ * non-error returns are a promise to giveback() the urb later
+ * we drop ownership so next owner (or urb unlink) can get it
+ */
+int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ unsigned long flags;
+ int ret = 0;
+ unsigned int slot_id, ep_index;
+
+
+ if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
+ return -EINVAL;
+
+ slot_id = urb->dev->slot_id;
+ ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+
+ if (!xhci->devs || !xhci->devs[slot_id]) {
+ if (!in_interrupt())
+ dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+ if (!in_interrupt())
+ xhci_dbg(xhci, "urb submitted during PCI suspend\n");
+ ret = -ESHUTDOWN;
+ goto exit;
+ }
+ if (usb_endpoint_xfer_control(&urb->ep->desc)) {
+ /* Check to see if the max packet size for the default control
+ * endpoint changed during FS device enumeration
+ */
+ if (urb->dev->speed == USB_SPEED_FULL) {
+ ret = xhci_check_maxpacket(xhci, slot_id,
+ ep_index, urb);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* We have a spinlock and interrupts disabled, so we must pass
+ * atomic context to this function, which may allocate memory.
+ */
+ spin_lock_irqsave(&xhci->lock, flags);
+ if (xhci->xhc_state & XHCI_STATE_DYING)
+ goto dying;
+ ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
+ spin_lock_irqsave(&xhci->lock, flags);
+ if (xhci->xhc_state & XHCI_STATE_DYING)
+ goto dying;
+ ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ } else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
+ spin_lock_irqsave(&xhci->lock, flags);
+ if (xhci->xhc_state & XHCI_STATE_DYING)
+ goto dying;
+ ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ } else {
+ ret = -EINVAL;
+ }
+exit:
+ return ret;
+dying:
+ xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
+ "non-responsive xHCI host.\n",
+ urb->ep->desc.bEndpointAddress, urb);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return -ESHUTDOWN;
+}
+
+/*
+ * Remove the URB's TD from the endpoint ring. This may cause the HC to stop
+ * USB transfers, potentially stopping in the middle of a TRB buffer. The HC
+ * should pick up where it left off in the TD, unless a Set Transfer Ring
+ * Dequeue Pointer is issued.
+ *
+ * The TRBs that make up the buffers for the canceled URB will be "removed" from
+ * the ring. Since the ring is a contiguous structure, they can't be physically
+ * removed. Instead, there are two options:
+ *
+ * 1) If the HC is in the middle of processing the URB to be canceled, we
+ * simply move the ring's dequeue pointer past those TRBs using the Set
+ * Transfer Ring Dequeue Pointer command. This will be the common case,
+ * when drivers timeout on the last submitted URB and attempt to cancel.
+ *
+ * 2) If the HC is in the middle of a different TD, we turn the TRBs into a
+ * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The
+ * HC will need to invalidate the any TRBs it has cached after the stop
+ * endpoint command, as noted in the xHCI 0.95 errata.
+ *
+ * 3) The TD may have completed by the time the Stop Endpoint Command
+ * completes, so software needs to handle that case too.
+ *
+ * This function should protect against the TD enqueueing code ringing the
+ * doorbell while this code is waiting for a Stop Endpoint command to complete.
+ * It also needs to account for multiple cancellations on happening at the same
+ * time for the same endpoint.
+ *
+ * Note that this function can be called in any context, or so says
+ * usb_hcd_unlink_urb()
+ */
+int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+ unsigned long flags;
+ int ret;
+ u32 temp;
+ struct xhci_hcd *xhci;
+ struct xhci_td *td;
+ unsigned int ep_index;
+ struct xhci_ring *ep_ring;
+ struct xhci_virt_ep *ep;
+
+ xhci = hcd_to_xhci(hcd);
+ spin_lock_irqsave(&xhci->lock, flags);
+ /* Make sure the URB hasn't completed or been unlinked already */
+ ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (ret || !urb->hcpriv)
+ goto done;
+ temp = xhci_readl(xhci, &xhci->op_regs->status);
+ if (temp == 0xffffffff) {
+ xhci_dbg(xhci, "HW died, freeing TD.\n");
+ td = (struct xhci_td *) urb->hcpriv;
+
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
+ kfree(td);
+ return ret;
+ }
+ if (xhci->xhc_state & XHCI_STATE_DYING) {
+ xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on "
+ "non-responsive xHCI host.\n",
+ urb->ep->desc.bEndpointAddress, urb);
+ /* Let the stop endpoint command watchdog timer (which set this
+ * state) finish cleaning up the endpoint TD lists. We must
+ * have caught it in the middle of dropping a lock and giving
+ * back an URB.
+ */
+ goto done;
+ }
+
+ xhci_dbg(xhci, "Cancel URB %p\n", urb);
+ xhci_dbg(xhci, "Event ring:\n");
+ xhci_debug_ring(xhci, xhci->event_ring);
+ ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+ ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
+ ep_ring = ep->ring;
+ xhci_dbg(xhci, "Endpoint ring:\n");
+ xhci_debug_ring(xhci, ep_ring);
+ td = (struct xhci_td *) urb->hcpriv;
+
+ list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
+ /* Queue a stop endpoint command, but only if this is
+ * the first cancellation to be handled.
+ */
+ if (!(ep->ep_state & EP_HALT_PENDING)) {
+ ep->ep_state |= EP_HALT_PENDING;
+ ep->stop_cmds_pending++;
+ ep->stop_cmd_timer.expires = jiffies +
+ XHCI_STOP_EP_CMD_TIMEOUT * HZ;
+ add_timer(&ep->stop_cmd_timer);
+ xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
+ xhci_ring_cmd_db(xhci);
+ }
+done:
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return ret;
+}
+
+/* Drop an endpoint from a new bandwidth configuration for this device.
+ * Only one call to this function is allowed per endpoint before
+ * check_bandwidth() or reset_bandwidth() must be called.
+ * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
+ * add the endpoint to the schedule with possibly new parameters denoted by a
+ * different endpoint descriptor in usb_host_endpoint.
+ * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
+ * not allowed.
+ *
+ * The USB core will not allow URBs to be queued to an endpoint that is being
+ * disabled, so there's no need for mutual exclusion to protect
+ * the xhci->devs[slot_id] structure.
+ */
+int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
+ struct usb_host_endpoint *ep)
+{
+ struct xhci_hcd *xhci;
+ struct xhci_container_ctx *in_ctx, *out_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_slot_ctx *slot_ctx;
+ unsigned int last_ctx;
+ unsigned int ep_index;
+ struct xhci_ep_ctx *ep_ctx;
+ u32 drop_flag;
+ u32 new_add_flags, new_drop_flags, new_slot_info;
+ int ret;
+
+ ret = xhci_check_args(hcd, udev, ep, 1, __func__);
+ if (ret <= 0)
+ return ret;
+ xhci = hcd_to_xhci(hcd);
+ xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+
+ drop_flag = xhci_get_endpoint_flag(&ep->desc);
+ if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) {
+ xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n",
+ __func__, drop_flag);
+ return 0;
+ }
+
+ if (!xhci->devs || !xhci->devs[udev->slot_id]) {
+ xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ in_ctx = xhci->devs[udev->slot_id]->in_ctx;
+ out_ctx = xhci->devs[udev->slot_id]->out_ctx;
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
+ ep_index = xhci_get_endpoint_index(&ep->desc);
+ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+ /* If the HC already knows the endpoint is disabled,
+ * or the HCD has noted it is disabled, ignore this request
+ */
+ if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED ||
+ ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) {
+ xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
+ __func__, ep);
+ return 0;
+ }
+
+ ctrl_ctx->drop_flags |= drop_flag;
+ new_drop_flags = ctrl_ctx->drop_flags;
+
+ ctrl_ctx->add_flags &= ~drop_flag;
+ new_add_flags = ctrl_ctx->add_flags;
+
+ last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
+ slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
+ /* Update the last valid endpoint context, if we deleted the last one */
+ if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) {
+ slot_ctx->dev_info &= ~LAST_CTX_MASK;
+ slot_ctx->dev_info |= LAST_CTX(last_ctx);
+ }
+ new_slot_info = slot_ctx->dev_info;
+
+ xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
+
+ xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
+ (unsigned int) ep->desc.bEndpointAddress,
+ udev->slot_id,
+ (unsigned int) new_drop_flags,
+ (unsigned int) new_add_flags,
+ (unsigned int) new_slot_info);
+ return 0;
+}
+
+/* Add an endpoint to a new possible bandwidth configuration for this device.
+ * Only one call to this function is allowed per endpoint before
+ * check_bandwidth() or reset_bandwidth() must be called.
+ * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will
+ * add the endpoint to the schedule with possibly new parameters denoted by a
+ * different endpoint descriptor in usb_host_endpoint.
+ * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is
+ * not allowed.
+ *
+ * The USB core will not allow URBs to be queued to an endpoint until the
+ * configuration or alt setting is installed in the device, so there's no need
+ * for mutual exclusion to protect the xhci->devs[slot_id] structure.
+ */
+int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
+ struct usb_host_endpoint *ep)
+{
+ struct xhci_hcd *xhci;
+ struct xhci_container_ctx *in_ctx, *out_ctx;
+ unsigned int ep_index;
+ struct xhci_ep_ctx *ep_ctx;
+ struct xhci_slot_ctx *slot_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ u32 added_ctxs;
+ unsigned int last_ctx;
+ u32 new_add_flags, new_drop_flags, new_slot_info;
+ int ret = 0;
+
+ ret = xhci_check_args(hcd, udev, ep, 1, __func__);
+ if (ret <= 0) {
+ /* So we won't queue a reset ep command for a root hub */
+ ep->hcpriv = NULL;
+ return ret;
+ }
+ xhci = hcd_to_xhci(hcd);
+
+ added_ctxs = xhci_get_endpoint_flag(&ep->desc);
+ last_ctx = xhci_last_valid_endpoint(added_ctxs);
+ if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) {
+ /* FIXME when we have to issue an evaluate endpoint command to
+ * deal with ep0 max packet size changing once we get the
+ * descriptors
+ */
+ xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n",
+ __func__, added_ctxs);
+ return 0;
+ }
+
+ if (!xhci->devs || !xhci->devs[udev->slot_id]) {
+ xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ in_ctx = xhci->devs[udev->slot_id]->in_ctx;
+ out_ctx = xhci->devs[udev->slot_id]->out_ctx;
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
+ ep_index = xhci_get_endpoint_index(&ep->desc);
+ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+ /* If the HCD has already noted the endpoint is enabled,
+ * ignore this request.
+ */
+ if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) {
+ xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
+ __func__, ep);
+ return 0;
+ }
+
+ /*
+ * Configuration and alternate setting changes must be done in
+ * process context, not interrupt context (or so documenation
+ * for usb_set_interface() and usb_set_configuration() claim).
+ */
+ if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id],
+ udev, ep, GFP_NOIO) < 0) {
+ dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
+ __func__, ep->desc.bEndpointAddress);
+ return -ENOMEM;
+ }
+
+ ctrl_ctx->add_flags |= added_ctxs;
+ new_add_flags = ctrl_ctx->add_flags;
+
+ /* If xhci_endpoint_disable() was called for this endpoint, but the
+ * xHC hasn't been notified yet through the check_bandwidth() call,
+ * this re-adds a new state for the endpoint from the new endpoint
+ * descriptors. We must drop and re-add this endpoint, so we leave the
+ * drop flags alone.
+ */
+ new_drop_flags = ctrl_ctx->drop_flags;
+
+ slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
+ /* Update the last valid endpoint context, if we just added one past */
+ if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) {
+ slot_ctx->dev_info &= ~LAST_CTX_MASK;
+ slot_ctx->dev_info |= LAST_CTX(last_ctx);
+ }
+ new_slot_info = slot_ctx->dev_info;
+
+ /* Store the usb_device pointer for later use */
+ ep->hcpriv = udev;
+
+ xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
+ (unsigned int) ep->desc.bEndpointAddress,
+ udev->slot_id,
+ (unsigned int) new_drop_flags,
+ (unsigned int) new_add_flags,
+ (unsigned int) new_slot_info);
+ return 0;
+}
+
+static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev)
+{
+ struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_ep_ctx *ep_ctx;
+ struct xhci_slot_ctx *slot_ctx;
+ int i;
+
+ /* When a device's add flag and drop flag are zero, any subsequent
+ * configure endpoint command will leave that endpoint's state
+ * untouched. Make sure we don't leave any old state in the input
+ * endpoint contexts.
+ */
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+ ctrl_ctx->drop_flags = 0;
+ ctrl_ctx->add_flags = 0;
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+ slot_ctx->dev_info &= ~LAST_CTX_MASK;
+ /* Endpoint 0 is always valid */
+ slot_ctx->dev_info |= LAST_CTX(1);
+ for (i = 1; i < 31; ++i) {
+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i);
+ ep_ctx->ep_info = 0;
+ ep_ctx->ep_info2 = 0;
+ ep_ctx->deq = 0;
+ ep_ctx->tx_info = 0;
+ }
+}
+
+static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
+ struct usb_device *udev, int *cmd_status)
+{
+ int ret;
+
+ switch (*cmd_status) {
+ case COMP_ENOMEM:
+ dev_warn(&udev->dev, "Not enough host controller resources "
+ "for new device state.\n");
+ ret = -ENOMEM;
+ /* FIXME: can we allocate more resources for the HC? */
+ break;
+ case COMP_BW_ERR:
+ dev_warn(&udev->dev, "Not enough bandwidth "
+ "for new device state.\n");
+ ret = -ENOSPC;
+ /* FIXME: can we go back to the old state? */
+ break;
+ case COMP_TRB_ERR:
+ /* the HCD set up something wrong */
+ dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, "
+ "add flag = 1, "
+ "and endpoint is not disabled.\n");
+ ret = -EINVAL;
+ break;
+ case COMP_SUCCESS:
+ dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
+ ret = 0;
+ break;
+ default:
+ xhci_err(xhci, "ERROR: unexpected command completion "
+ "code 0x%x.\n", *cmd_status);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
+ struct usb_device *udev, int *cmd_status)
+{
+ int ret;
+ struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
+
+ switch (*cmd_status) {
+ case COMP_EINVAL:
+ dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate "
+ "context command.\n");
+ ret = -EINVAL;
+ break;
+ case COMP_EBADSLT:
+ dev_warn(&udev->dev, "WARN: slot not enabled for"
+ "evaluate context command.\n");
+ case COMP_CTX_STATE:
+ dev_warn(&udev->dev, "WARN: invalid context state for "
+ "evaluate context command.\n");
+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
+ ret = -EINVAL;
+ break;
+ case COMP_SUCCESS:
+ dev_dbg(&udev->dev, "Successful evaluate context command\n");
+ ret = 0;
+ break;
+ default:
+ xhci_err(xhci, "ERROR: unexpected command completion "
+ "code 0x%x.\n", *cmd_status);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+/* Issue a configure endpoint command or evaluate context command
+ * and wait for it to finish.
+ */
+static int xhci_configure_endpoint(struct xhci_hcd *xhci,
+ struct usb_device *udev,
+ struct xhci_command *command,
+ bool ctx_change, bool must_succeed)
+{
+ int ret;
+ int timeleft;
+ unsigned long flags;
+ struct xhci_container_ctx *in_ctx;
+ struct completion *cmd_completion;
+ int *cmd_status;
+ struct xhci_virt_device *virt_dev;
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ virt_dev = xhci->devs[udev->slot_id];
+ if (command) {
+ in_ctx = command->in_ctx;
+ cmd_completion = command->completion;
+ cmd_status = &command->status;
+ command->command_trb = xhci->cmd_ring->enqueue;
+ list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
+ } else {
+ in_ctx = virt_dev->in_ctx;
+ cmd_completion = &virt_dev->cmd_completion;
+ cmd_status = &virt_dev->cmd_status;
+ }
+ init_completion(cmd_completion);
+
+ if (!ctx_change)
+ ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
+ udev->slot_id, must_succeed);
+ else
+ ret = xhci_queue_evaluate_context(xhci, in_ctx->dma,
+ udev->slot_id);
+ if (ret < 0) {
+ if (command)
+ list_del(&command->cmd_list);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
+ return -ENOMEM;
+ }
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ /* Wait for the configure endpoint command to complete */
+ timeleft = wait_for_completion_interruptible_timeout(
+ cmd_completion,
+ USB_CTRL_SET_TIMEOUT);
+ if (timeleft <= 0) {
+ xhci_warn(xhci, "%s while waiting for %s command\n",
+ timeleft == 0 ? "Timeout" : "Signal",
+ ctx_change == 0 ?
+ "configure endpoint" :
+ "evaluate context");
+ /* FIXME cancel the configure endpoint command */
+ return -ETIME;
+ }
+
+ if (!ctx_change)
+ return xhci_configure_endpoint_result(xhci, udev, cmd_status);
+ return xhci_evaluate_context_result(xhci, udev, cmd_status);
+}
+
+/* Called after one or more calls to xhci_add_endpoint() or
+ * xhci_drop_endpoint(). If this call fails, the USB core is expected
+ * to call xhci_reset_bandwidth().
+ *
+ * Since we are in the middle of changing either configuration or
+ * installing a new alt setting, the USB core won't allow URBs to be
+ * enqueued for any endpoint on the old config or interface. Nothing
+ * else should be touching the xhci->devs[slot_id] structure, so we
+ * don't need to take the xhci->lock for manipulating that.
+ */
+int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+{
+ int i;
+ int ret = 0;
+ struct xhci_hcd *xhci;
+ struct xhci_virt_device *virt_dev;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_slot_ctx *slot_ctx;
+
+ ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+ if (ret <= 0)
+ return ret;
+ xhci = hcd_to_xhci(hcd);
+
+ if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) {
+ xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
+ __func__);
+ return -EINVAL;
+ }
+ xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+ virt_dev = xhci->devs[udev->slot_id];
+
+ /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+ ctrl_ctx->add_flags |= SLOT_FLAG;
+ ctrl_ctx->add_flags &= ~EP0_FLAG;
+ ctrl_ctx->drop_flags &= ~SLOT_FLAG;
+ ctrl_ctx->drop_flags &= ~EP0_FLAG;
+ xhci_dbg(xhci, "New Input Control Context:\n");
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+ xhci_dbg_ctx(xhci, virt_dev->in_ctx,
+ LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
+
+ ret = xhci_configure_endpoint(xhci, udev, NULL,
+ false, false);
+ if (ret) {
+ /* Callee should call reset_bandwidth() */
+ return ret;
+ }
+
+ xhci_dbg(xhci, "Output context after successful config ep cmd:\n");
+ xhci_dbg_ctx(xhci, virt_dev->out_ctx,
+ LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
+
+ xhci_zero_in_ctx(xhci, virt_dev);
+ /* Install new rings and free or cache any old rings */
+ for (i = 1; i < 31; ++i) {
+ if (!virt_dev->eps[i].new_ring)
+ continue;
+ /* Only cache or free the old ring if it exists.
+ * It may not if this is the first add of an endpoint.
+ */
+ if (virt_dev->eps[i].ring) {
+ xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
+ }
+ virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
+ virt_dev->eps[i].new_ring = NULL;
+ }
+
+ return ret;
+}
+
+void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+{
+ struct xhci_hcd *xhci;
+ struct xhci_virt_device *virt_dev;
+ int i, ret;
+
+ ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+ if (ret <= 0)
+ return;
+ xhci = hcd_to_xhci(hcd);
+
+ if (!xhci->devs || !xhci->devs[udev->slot_id]) {
+ xhci_warn(xhci, "xHCI %s called with unaddressed device\n",
+ __func__);
+ return;
+ }
+ xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+ virt_dev = xhci->devs[udev->slot_id];
+ /* Free any rings allocated for added endpoints */
+ for (i = 0; i < 31; ++i) {
+ if (virt_dev->eps[i].new_ring) {
+ xhci_ring_free(xhci, virt_dev->eps[i].new_ring);
+ virt_dev->eps[i].new_ring = NULL;
+ }
+ }
+ xhci_zero_in_ctx(xhci, virt_dev);
+}
+
+static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci,
+ struct xhci_container_ctx *in_ctx,
+ struct xhci_container_ctx *out_ctx,
+ u32 add_flags, u32 drop_flags)
+{
+ struct xhci_input_control_ctx *ctrl_ctx;
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
+ ctrl_ctx->add_flags = add_flags;
+ ctrl_ctx->drop_flags = drop_flags;
+ xhci_slot_copy(xhci, in_ctx, out_ctx);
+ ctrl_ctx->add_flags |= SLOT_FLAG;
+
+ xhci_dbg(xhci, "Input Context:\n");
+ xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags));
+}
+
+void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
+ unsigned int slot_id, unsigned int ep_index,
+ struct xhci_dequeue_state *deq_state)
+{
+ struct xhci_container_ctx *in_ctx;
+ struct xhci_ep_ctx *ep_ctx;
+ u32 added_ctxs;
+ dma_addr_t addr;
+
+ xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
+ xhci->devs[slot_id]->out_ctx, ep_index);
+ in_ctx = xhci->devs[slot_id]->in_ctx;
+ ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
+ addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg,
+ deq_state->new_deq_ptr);
+ if (addr == 0) {
+ xhci_warn(xhci, "WARN Cannot submit config ep after "
+ "reset ep command\n");
+ xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
+ deq_state->new_deq_seg,
+ deq_state->new_deq_ptr);
+ return;
+ }
+ ep_ctx->deq = addr | deq_state->new_cycle_state;
+
+ added_ctxs = xhci_get_endpoint_flag_from_index(ep_index);
+ xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx,
+ xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs);
+}
+
+void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
+ struct usb_device *udev, unsigned int ep_index)
+{
+ struct xhci_dequeue_state deq_state;
+ struct xhci_virt_ep *ep;
+
+ xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
+ ep = &xhci->devs[udev->slot_id]->eps[ep_index];
+ /* We need to move the HW's dequeue pointer past this TD,
+ * or it will attempt to resend it on the next doorbell ring.
+ */
+ xhci_find_new_dequeue_state(xhci, udev->slot_id,
+ ep_index, ep->stopped_td,
+ &deq_state);
+
+ /* HW with the reset endpoint quirk will use the saved dequeue state to
+ * issue a configure endpoint command later.
+ */
+ if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
+ xhci_dbg(xhci, "Queueing new dequeue state\n");
+ xhci_queue_new_dequeue_state(xhci, udev->slot_id,
+ ep_index, &deq_state);
+ } else {
+ /* Better hope no one uses the input context between now and the
+ * reset endpoint completion!
+ */
+ xhci_dbg(xhci, "Setting up input context for "
+ "configure endpoint command\n");
+ xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id,
+ ep_index, &deq_state);
+ }
+}
+
+/* Deal with stalled endpoints. The core should have sent the control message
+ * to clear the halt condition. However, we need to make the xHCI hardware
+ * reset its sequence number, since a device will expect a sequence number of
+ * zero after the halt condition is cleared.
+ * Context: in_interrupt
+ */
+void xhci_endpoint_reset(struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep)
+{
+ struct xhci_hcd *xhci;
+ struct usb_device *udev;
+ unsigned int ep_index;
+ unsigned long flags;
+ int ret;
+ struct xhci_virt_ep *virt_ep;
+
+ xhci = hcd_to_xhci(hcd);
+ udev = (struct usb_device *) ep->hcpriv;
+ /* Called with a root hub endpoint (or an endpoint that wasn't added
+ * with xhci_add_endpoint()
+ */
+ if (!ep->hcpriv)
+ return;
+ ep_index = xhci_get_endpoint_index(&ep->desc);
+ virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index];
+ if (!virt_ep->stopped_td) {
+ xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n",
+ ep->desc.bEndpointAddress);
+ return;
+ }
+ if (usb_endpoint_xfer_control(&ep->desc)) {
+ xhci_dbg(xhci, "Control endpoint stall already handled.\n");
+ return;
+ }
+
+ xhci_dbg(xhci, "Queueing reset endpoint command\n");
+ spin_lock_irqsave(&xhci->lock, flags);
+ ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index);
+ /*
+ * Can't change the ring dequeue pointer until it's transitioned to the
+ * stopped state, which is only upon a successful reset endpoint
+ * command. Better hope that last command worked!
+ */
+ if (!ret) {
+ xhci_cleanup_stalled_ring(xhci, udev, ep_index);
+ kfree(virt_ep->stopped_td);
+ xhci_ring_cmd_db(xhci);
+ }
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ if (ret)
+ xhci_warn(xhci, "FIXME allocate a new ring segment\n");
+}
+
+/*
+ * This submits a Reset Device Command, which will set the device state to 0,
+ * set the device address to 0, and disable all the endpoints except the default
+ * control endpoint. The USB core should come back and call
+ * xhci_address_device(), and then re-set up the configuration. If this is
+ * called because of a usb_reset_and_verify_device(), then the old alternate
+ * settings will be re-installed through the normal bandwidth allocation
+ * functions.
+ *
+ * Wait for the Reset Device command to finish. Remove all structures
+ * associated with the endpoints that were disabled. Clear the input device
+ * structure? Cache the rings? Reset the control endpoint 0 max packet size?
+ */
+int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
+{
+ int ret, i;
+ unsigned long flags;
+ struct xhci_hcd *xhci;
+ unsigned int slot_id;
+ struct xhci_virt_device *virt_dev;
+ struct xhci_command *reset_device_cmd;
+ int timeleft;
+ int last_freed_endpoint;
+
+ ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
+ if (ret <= 0)
+ return ret;
+ xhci = hcd_to_xhci(hcd);
+ slot_id = udev->slot_id;
+ virt_dev = xhci->devs[slot_id];
+ if (!virt_dev) {
+ xhci_dbg(xhci, "%s called with invalid slot ID %u\n",
+ __func__, slot_id);
+ return -EINVAL;
+ }
+
+ xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
+ /* Allocate the command structure that holds the struct completion.
+ * Assume we're in process context, since the normal device reset
+ * process has to wait for the device anyway. Storage devices are
+ * reset as part of error handling, so use GFP_NOIO instead of
+ * GFP_KERNEL.
+ */
+ reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
+ if (!reset_device_cmd) {
+ xhci_dbg(xhci, "Couldn't allocate command structure.\n");
+ return -ENOMEM;
+ }
+
+ /* Attempt to submit the Reset Device command to the command ring */
+ spin_lock_irqsave(&xhci->lock, flags);
+ reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
+ list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
+ ret = xhci_queue_reset_device(xhci, slot_id);
+ if (ret) {
+ xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
+ list_del(&reset_device_cmd->cmd_list);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ goto command_cleanup;
+ }
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ /* Wait for the Reset Device command to finish */
+ timeleft = wait_for_completion_interruptible_timeout(
+ reset_device_cmd->completion,
+ USB_CTRL_SET_TIMEOUT);
+ if (timeleft <= 0) {
+ xhci_warn(xhci, "%s while waiting for reset device command\n",
+ timeleft == 0 ? "Timeout" : "Signal");
+ spin_lock_irqsave(&xhci->lock, flags);
+ /* The timeout might have raced with the event ring handler, so
+ * only delete from the list if the item isn't poisoned.
+ */
+ if (reset_device_cmd->cmd_list.next != LIST_POISON1)
+ list_del(&reset_device_cmd->cmd_list);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ ret = -ETIME;
+ goto command_cleanup;
+ }
+
+ /* The Reset Device command can't fail, according to the 0.95/0.96 spec,
+ * unless we tried to reset a slot ID that wasn't enabled,
+ * or the device wasn't in the addressed or configured state.
+ */
+ ret = reset_device_cmd->status;
+ switch (ret) {
+ case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */
+ case COMP_CTX_STATE: /* 0.96 completion code for same thing */
+ xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n",
+ slot_id,
+ xhci_get_slot_state(xhci, virt_dev->out_ctx));
+ xhci_info(xhci, "Not freeing device rings.\n");
+ /* Don't treat this as an error. May change my mind later. */
+ ret = 0;
+ goto command_cleanup;
+ case COMP_SUCCESS:
+ xhci_dbg(xhci, "Successful reset device command.\n");
+ break;
+ default:
+ if (xhci_is_vendor_info_code(xhci, ret))
+ break;
+ xhci_warn(xhci, "Unknown completion code %u for "
+ "reset device command.\n", ret);
+ ret = -EINVAL;
+ goto command_cleanup;
+ }
+
+ /* Everything but endpoint 0 is disabled, so free or cache the rings. */
+ last_freed_endpoint = 1;
+ for (i = 1; i < 31; ++i) {
+ if (!virt_dev->eps[i].ring)
+ continue;
+ xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
+ last_freed_endpoint = i;
+ }
+ xhci_dbg(xhci, "Output context after successful reset device cmd:\n");
+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint);
+ ret = 0;
+
+command_cleanup:
+ xhci_free_command(xhci, reset_device_cmd);
+ return ret;
+}
+
+/*
+ * At this point, the struct usb_device is about to go away, the device has
+ * disconnected, and all traffic has been stopped and the endpoints have been
+ * disabled. Free any HC data structures associated with that device.
+ */
+void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct xhci_virt_device *virt_dev;
+ unsigned long flags;
+ u32 state;
+ int i;
+
+ if (udev->slot_id == 0)
+ return;
+ virt_dev = xhci->devs[udev->slot_id];
+ if (!virt_dev)
+ return;
+
+ /* Stop any wayward timer functions (which may grab the lock) */
+ for (i = 0; i < 31; ++i) {
+ virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING;
+ del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
+ }
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ /* Don't disable the slot if the host controller is dead. */
+ state = xhci_readl(xhci, &xhci->op_regs->status);
+ if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
+ xhci_free_virt_device(xhci, udev->slot_id);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return;
+ }
+
+ if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
+ return;
+ }
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ /*
+ * Event command completion handler will free any data structures
+ * associated with the slot. XXX Can free sleep?
+ */
+}
+
+/*
+ * Returns 0 if the xHC ran out of device slots, the Enable Slot command
+ * timed out, or allocating memory failed. Returns 1 on success.
+ */
+int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ unsigned long flags;
+ int timeleft;
+ int ret;
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0);
+ if (ret) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
+ return 0;
+ }
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ /* XXX: how much time for xHC slot assignment? */
+ timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
+ USB_CTRL_SET_TIMEOUT);
+ if (timeleft <= 0) {
+ xhci_warn(xhci, "%s while waiting for a slot\n",
+ timeleft == 0 ? "Timeout" : "Signal");
+ /* FIXME cancel the enable slot request */
+ return 0;
+ }
+
+ if (!xhci->slot_id) {
+ xhci_err(xhci, "Error while assigning device slot ID\n");
+ return 0;
+ }
+ /* xhci_alloc_virt_device() does not touch rings; no need to lock */
+ if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) {
+ /* Disable slot, if we can do it without mem alloc */
+ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
+ spin_lock_irqsave(&xhci->lock, flags);
+ if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id))
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return 0;
+ }
+ udev->slot_id = xhci->slot_id;
+ /* Is this a LS or FS device under a HS hub? */
+ /* Hub or peripherial? */
+ return 1;
+}
+
+/*
+ * Issue an Address Device command (which will issue a SetAddress request to
+ * the device).
+ * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so
+ * we should only issue and wait on one address command at the same time.
+ *
+ * We add one to the device address issued by the hardware because the USB core
+ * uses address 1 for the root hubs (even though they're not really devices).
+ */
+int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
+{
+ unsigned long flags;
+ int timeleft;
+ struct xhci_virt_device *virt_dev;
+ int ret = 0;
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct xhci_slot_ctx *slot_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ u64 temp_64;
+
+ if (!udev->slot_id) {
+ xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id);
+ return -EINVAL;
+ }
+
+ virt_dev = xhci->devs[udev->slot_id];
+
+ /* If this is a Set Address to an unconfigured device, setup ep 0 */
+ if (!udev->config)
+ xhci_setup_addressable_virt_dev(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);
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
+ udev->slot_id);
+ if (ret) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
+ return ret;
+ }
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
+ timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
+ USB_CTRL_SET_TIMEOUT);
+ /* FIXME: From section 4.3.4: "Software shall be responsible for timing
+ * the SetAddress() "recovery interval" required by USB and aborting the
+ * command on a timeout.
+ */
+ if (timeleft <= 0) {
+ xhci_warn(xhci, "%s while waiting for a slot\n",
+ timeleft == 0 ? "Timeout" : "Signal");
+ /* FIXME cancel the address device command */
+ return -ETIME;
+ }
+
+ switch (virt_dev->cmd_status) {
+ case COMP_CTX_STATE:
+ case COMP_EBADSLT:
+ xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n",
+ udev->slot_id);
+ ret = -EINVAL;
+ break;
+ case COMP_TX_ERR:
+ dev_warn(&udev->dev, "Device not responding to set address.\n");
+ ret = -EPROTO;
+ break;
+ case COMP_SUCCESS:
+ xhci_dbg(xhci, "Successful Address Device command\n");
+ break;
+ default:
+ xhci_err(xhci, "ERROR: unexpected command completion "
+ "code 0x%x.\n", virt_dev->cmd_status);
+ xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
+ ret = -EINVAL;
+ break;
+ }
+ if (ret) {
+ return ret;
+ }
+ temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
+ xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64);
+ xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n",
+ udev->slot_id,
+ &xhci->dcbaa->dev_context_ptrs[udev->slot_id],
+ (unsigned long long)
+ xhci->dcbaa->dev_context_ptrs[udev->slot_id]);
+ xhci_dbg(xhci, "Output Context DMA address = %#08llx\n",
+ (unsigned long long)virt_dev->out_ctx->dma);
+ xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
+ xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
+ xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
+ /*
+ * USB core uses address 1 for the roothubs, so we add one to the
+ * address given back to us by the HC.
+ */
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
+ udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1;
+ /* Zero the input context control for later use */
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+ ctrl_ctx->add_flags = 0;
+ ctrl_ctx->drop_flags = 0;
+
+ xhci_dbg(xhci, "Device address = %d\n", udev->devnum);
+ /* XXX Meh, not sure if anyone else but choose_address uses this. */
+ set_bit(udev->devnum, udev->bus->devmap.devicemap);
+
+ return 0;
+}
+
+/* Once a hub descriptor is fetched for a device, we need to update the xHC's
+ * internal data structures for the device.
+ */
+int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
+ struct usb_tt *tt, gfp_t mem_flags)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct xhci_virt_device *vdev;
+ struct xhci_command *config_cmd;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_slot_ctx *slot_ctx;
+ unsigned long flags;
+ unsigned think_time;
+ int ret;
+
+ /* Ignore root hubs */
+ if (!hdev->parent)
+ return 0;
+
+ vdev = xhci->devs[hdev->slot_id];
+ if (!vdev) {
+ xhci_warn(xhci, "Cannot update hub desc for unknown device.\n");
+ return -EINVAL;
+ }
+ config_cmd = xhci_alloc_command(xhci, true, true, mem_flags);
+ if (!config_cmd) {
+ xhci_dbg(xhci, "Could not allocate xHCI command structure.\n");
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx);
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx);
+ ctrl_ctx->add_flags |= SLOT_FLAG;
+ slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
+ slot_ctx->dev_info |= DEV_HUB;
+ if (tt->multi)
+ slot_ctx->dev_info |= DEV_MTT;
+ if (xhci->hci_version > 0x95) {
+ xhci_dbg(xhci, "xHCI version %x needs hub "
+ "TT think time and number of ports\n",
+ (unsigned int) xhci->hci_version);
+ slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild);
+ /* Set TT think time - convert from ns to FS bit times.
+ * 0 = 8 FS bit times, 1 = 16 FS bit times,
+ * 2 = 24 FS bit times, 3 = 32 FS bit times.
+ */
+ think_time = tt->think_time;
+ if (think_time != 0)
+ think_time = (think_time / 666) - 1;
+ slot_ctx->tt_info |= TT_THINK_TIME(think_time);
+ } else {
+ xhci_dbg(xhci, "xHCI version %x doesn't need hub "
+ "TT think time or number of ports\n",
+ (unsigned int) xhci->hci_version);
+ }
+ slot_ctx->dev_state = 0;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ xhci_dbg(xhci, "Set up %s for hub device.\n",
+ (xhci->hci_version > 0x95) ?
+ "configure endpoint" : "evaluate context");
+ xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id);
+ xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0);
+
+ /* Issue and wait for the configure endpoint or
+ * evaluate context command.
+ */
+ if (xhci->hci_version > 0x95)
+ ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
+ false, false);
+ else
+ ret = xhci_configure_endpoint(xhci, hdev, config_cmd,
+ true, false);
+
+ xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id);
+ xhci_dbg_ctx(xhci, vdev->out_ctx, 0);
+
+ xhci_free_command(xhci, config_cmd);
+ return ret;
+}
+
+int xhci_get_frame(struct usb_hcd *hcd)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ /* EHCI mods by the periodic size. Why? */
+ return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3;
+}
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+
+static int __init xhci_hcd_init(void)
+{
+#ifdef CONFIG_PCI
+ int retval = 0;
+
+ retval = xhci_register_pci();
+
+ if (retval < 0) {
+ printk(KERN_DEBUG "Problem registering PCI driver.");
+ return retval;
+ }
+#endif
+ /*
+ * Check the compiler generated sizes of structures that must be laid
+ * out in specific ways for hardware access.
+ */
+ BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
+ BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8);
+ BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8);
+ /* xhci_device_control has eight fields, and also
+ * embeds one xhci_slot_ctx and 31 xhci_ep_ctx
+ */
+ BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8);
+ BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8);
+ BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8);
+ BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8);
+ BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
+ /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
+ BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
+ BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
+ return 0;
+}
+module_init(xhci_hcd_init);
+
+static void __exit xhci_hcd_cleanup(void)
+{
+#ifdef CONFIG_PCI
+ xhci_unregister_pci();
+#endif
+}
+module_exit(xhci_hcd_cleanup);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index e5eb09b2f38..ea389e9a493 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -609,6 +609,10 @@ struct xhci_ep_ctx {
#define MAX_PACKET_MASK (0xffff << 16)
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
+/* tx_info bitmasks */
+#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff)
+#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16)
+
/**
* struct xhci_input_control_context
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index 4d2952f1fb1..094f91cbc57 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -24,6 +24,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/backlight.h>
#include <linux/timer.h>
@@ -202,6 +203,7 @@ static void appledisplay_work(struct work_struct *work)
static int appledisplay_probe(struct usb_interface *iface,
const struct usb_device_id *id)
{
+ struct backlight_properties props;
struct appledisplay *pdata;
struct usb_device *udev = interface_to_usbdev(iface);
struct usb_host_interface *iface_desc;
@@ -279,16 +281,16 @@ static int appledisplay_probe(struct usb_interface *iface,
/* Register backlight device */
snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
atomic_inc_return(&count_displays) - 1);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 0xff;
pdata->bd = backlight_device_register(bl_name, NULL, pdata,
- &appledisplay_bl_data);
+ &appledisplay_bl_data, &props);
if (IS_ERR(pdata->bd)) {
dev_err(&iface->dev, "Backlight registration failed\n");
retval = PTR_ERR(pdata->bd);
goto error;
}
- pdata->bd->props.max_brightness = 0xff;
-
/* Try to get brightness */
brightness = appledisplay_bl_get_brightness(pdata->bd);
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c
index 1547d8cac5f..2f43c57743c 100644
--- a/drivers/usb/misc/cypress_cy7c63.c
+++ b/drivers/usb/misc/cypress_cy7c63.c
@@ -32,6 +32,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#define DRIVER_AUTHOR "Oliver Bock (bock@tfh-berlin.de)"
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index b9cbbbda824..1d7251bc1b5 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c
index 06e990adc6c..fe1d44319d0 100644
--- a/drivers/usb/misc/isight_firmware.c
+++ b/drivers/usb/misc/isight_firmware.c
@@ -25,6 +25,7 @@
#include <linux/firmware.h>
#include <linux/errno.h>
#include <linux/module.h>
+#include <linux/slab.h>
static const struct usb_device_id id_table[] = {
{USB_DEVICE(0x05ac, 0x8300)},
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index b624320df90..b271b0557a1 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -58,7 +58,6 @@
#include <linux/string.h>
#include <linux/kd.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
#include <linux/spinlock.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c
index 0ab99074483..cb8a3d91f97 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.c
@@ -41,7 +41,6 @@
#include <linux/errno.h>
#include <linux/poll.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include "sisusb.h"
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c
index 5da28eaee31..d77aba46ae8 100644
--- a/drivers/usb/misc/trancevibrator.c
+++ b/drivers/usb/misc/trancevibrator.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c
index a9555cb901a..de8ef945b53 100644
--- a/drivers/usb/misc/usbsevseg.c
+++ b/drivers/usb/misc/usbsevseg.c
@@ -49,6 +49,7 @@ struct usb_sevsegdev {
u16 textlength;
u8 shadow_power; /* for PM */
+ u8 has_interface_pm;
};
/* sysfs_streq can't replace this completely
@@ -68,12 +69,16 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
{
int rc;
- if (!mydev->shadow_power && mydev->powered) {
+ if (mydev->powered && !mydev->has_interface_pm) {
rc = usb_autopm_get_interface(mydev->intf);
if (rc < 0)
return;
+ mydev->has_interface_pm = 1;
}
+ if (mydev->shadow_power != 1)
+ return;
+
rc = usb_control_msg(mydev->udev,
usb_sndctrlpipe(mydev->udev, 0),
0x12,
@@ -86,8 +91,10 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
if (rc < 0)
dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);
- if (mydev->shadow_power && !mydev->powered)
+ if (!mydev->powered && mydev->has_interface_pm) {
usb_autopm_put_interface(mydev->intf);
+ mydev->has_interface_pm = 0;
+ }
}
static void update_display_mode(struct usb_sevsegdev *mydev)
@@ -351,6 +358,10 @@ static int sevseg_probe(struct usb_interface *interface,
mydev->intf = interface;
usb_set_intfdata(interface, mydev);
+ /* PM */
+ mydev->shadow_power = 1; /* currently active */
+ mydev->has_interface_pm = 0; /* have not issued autopm_get */
+
/*set defaults */
mydev->textmode = 0x02; /* ascii mode */
mydev->mode_msb = 0x06; /* 6 characters */
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index f56fed53f2d..796e2f68f74 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -49,6 +49,7 @@
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/kref.h>
+#include <linux/slab.h>
/*
* Version Information
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 6dd44bc1f5f..ddf7f9a1b33 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -17,6 +17,7 @@
#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index e0c2db3b767..e4af18b93c7 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include <linux/notifier.h>
#include <linux/mutex.h>
diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c
index ac8b0d5ce7f..1becdc3837e 100644
--- a/drivers/usb/mon/mon_stat.c
+++ b/drivers/usb/mon/mon_stat.c
@@ -8,6 +8,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 31c11888ec6..4d0be130f49 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -7,6 +7,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mutex.h>
#include <linux/debugfs.h>
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index b4c783c284b..07fe490b44d 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -42,7 +42,7 @@ config USB_MUSB_SOC
default y if (BF52x && !BF522 && !BF523)
comment "DaVinci 35x and 644x USB support"
- depends on USB_MUSB_HDRC && ARCH_DAVINCI
+ depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx
comment "OMAP 243x high speed USB support"
depends on USB_MUSB_HDRC && ARCH_OMAP2430
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 85710ccc188..3a485dabebb 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -6,7 +6,7 @@ musb_hdrc-objs := musb_core.o
obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o
-ifeq ($(CONFIG_ARCH_DAVINCI),y)
+ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
musb_hdrc-objs += davinci.o
endif
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index bcee1339d4f..ec8d324237f 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/gpio.h>
@@ -173,13 +172,7 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci)
spin_unlock_irqrestore(&musb->lock, flags);
- /* REVISIT we sometimes get spurious IRQs on g_ep0
- * not clear why... fall in BF54x too.
- */
- if (retval != IRQ_HANDLED)
- DBG(5, "spurious?\n");
-
- return IRQ_HANDLED;
+ return retval;
}
static void musb_conn_timer_handler(unsigned long _musb)
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 3c69a76ec39..59dc3d351b6 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -7,6 +7,7 @@
*/
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include "musb_core.h"
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 66913811af5..ce2e16fee0d 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -24,7 +24,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/delay.h>
@@ -274,7 +273,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
/* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through
* the Mentor registers (except for setup), use the TI ones and EOI.
*
- * Docs describe irq "vector" registers asociated with the CPPI and
+ * Docs describe irq "vector" registers associated with the CPPI and
* USB EOI registers. These hold a bitmask corresponding to the
* current IRQ, not an irq handler address. Would using those bits
* resolve some of the races observed in this dispatch code??
@@ -445,6 +444,8 @@ int __init musb_platform_init(struct musb *musb)
return 0;
fail:
+ clk_disable(musb->clock);
+
usb_nop_xceiv_unregister();
return -ENODEV;
}
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index b4bbf8f2c23..705cc4ad873 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
u8 devctl, u8 power)
{
irqreturn_t handled = IRQ_NONE;
- void __iomem *mbase = musb->mregs;
DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
int_usb);
@@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
if (devctl & MUSB_DEVCTL_HM) {
#ifdef CONFIG_USB_MUSB_HDRC_HCD
+ void __iomem *mbase = musb->mregs;
+
switch (musb->xceiv->state) {
case OTG_STATE_A_SUSPEND:
/* remote wakeup? later, GetPortStatus
@@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
#ifdef CONFIG_USB_MUSB_HDRC_HCD
/* see manual for the order of the tests */
if (int_usb & MUSB_INTR_SESSREQ) {
+ void __iomem *mbase = musb->mregs;
+
DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb));
/* IRQ arrives from ID pin sense or (later, if VBUS power
@@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
case OTG_STATE_A_WAIT_BCON:
case OTG_STATE_A_WAIT_VRISE:
if (musb->vbuserr_retry) {
+ void __iomem *mbase = musb->mregs;
+
musb->vbuserr_retry--;
ignore = 1;
devctl |= MUSB_DEVCTL_SESSION;
@@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
if (int_usb & MUSB_INTR_CONNECT) {
struct usb_hcd *hcd = musb_to_hcd(musb);
+ void __iomem *mbase = musb->mregs;
handled = IRQ_HANDLED;
musb->is_active = 1;
@@ -959,10 +965,8 @@ static void musb_shutdown(struct platform_device *pdev)
spin_lock_irqsave(&musb->lock, flags);
musb_platform_disable(musb);
musb_generic_disable(musb);
- if (musb->clock) {
+ if (musb->clock)
clk_put(musb->clock);
- musb->clock = NULL;
- }
spin_unlock_irqrestore(&musb->lock, flags);
/* FIXME power down */
@@ -1847,15 +1851,6 @@ static void musb_free(struct musb *musb)
put_device(musb->xceiv->dev);
#endif
- musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
- musb_platform_exit(musb);
- musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-
- if (musb->clock) {
- clk_disable(musb->clock);
- clk_put(musb->clock);
- }
-
#ifdef CONFIG_USB_MUSB_HDRC_HCD
usb_put_hcd(musb_to_hcd(musb));
#else
@@ -1883,8 +1878,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
*/
if (!plat) {
dev_dbg(dev, "no platform_data?\n");
- return -ENODEV;
+ status = -ENODEV;
+ goto fail0;
}
+
switch (plat->mode) {
case MUSB_HOST:
#ifdef CONFIG_USB_MUSB_HDRC_HCD
@@ -1906,13 +1903,16 @@ bad_config:
#endif
default:
dev_err(dev, "incompatible Kconfig role setting\n");
- return -EINVAL;
+ status = -EINVAL;
+ goto fail0;
}
/* allocate */
musb = allocate_instance(dev, plat->config, ctrl);
- if (!musb)
- return -ENOMEM;
+ if (!musb) {
+ status = -ENOMEM;
+ goto fail0;
+ }
spin_lock_init(&musb->lock);
musb->board_mode = plat->mode;
@@ -1930,7 +1930,7 @@ bad_config:
if (IS_ERR(musb->clock)) {
status = PTR_ERR(musb->clock);
musb->clock = NULL;
- goto fail;
+ goto fail1;
}
}
@@ -1949,12 +1949,12 @@ bad_config:
*/
musb->isr = generic_interrupt;
status = musb_platform_init(musb);
-
if (status < 0)
- goto fail;
+ goto fail2;
+
if (!musb->isr) {
status = -ENODEV;
- goto fail2;
+ goto fail3;
}
#ifndef CONFIG_MUSB_PIO_ONLY
@@ -1980,7 +1980,7 @@ bad_config:
? MUSB_CONTROLLER_MHDRC
: MUSB_CONTROLLER_HDRC, musb);
if (status < 0)
- goto fail2;
+ goto fail3;
#ifdef CONFIG_USB_MUSB_OTG
setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
@@ -1993,7 +1993,7 @@ bad_config:
if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
dev_err(dev, "request_irq %d failed!\n", nIrq);
status = -ENODEV;
- goto fail2;
+ goto fail3;
}
musb->nIrq = nIrq;
/* FIXME this handles wakeup irqs wrong */
@@ -2007,7 +2007,6 @@ bad_config:
/* host side needs more setup */
if (is_host_enabled(musb)) {
struct usb_hcd *hcd = musb_to_hcd(musb);
- u8 busctl;
otg_set_host(musb->xceiv, &hcd->self);
@@ -2018,9 +2017,9 @@ bad_config:
/* program PHY to use external vBus if required */
if (plat->extvbus) {
- busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL);
+ u8 busctl = musb_read_ulpi_buscontrol(musb->mregs);
busctl |= MUSB_ULPI_USE_EXTVBUS;
- musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl);
+ musb_write_ulpi_buscontrol(musb->mregs, busctl);
}
}
@@ -2034,8 +2033,6 @@ bad_config:
musb->xceiv->state = OTG_STATE_A_IDLE;
status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
- if (status)
- goto fail;
DBG(1, "%s mode, status %d, devctl %02x %c\n",
"HOST", status,
@@ -2050,8 +2047,6 @@ bad_config:
musb->xceiv->state = OTG_STATE_B_IDLE;
status = musb_gadget_setup(musb);
- if (status)
- goto fail;
DBG(1, "%s mode, status %d, dev%02x\n",
is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
@@ -2059,12 +2054,14 @@ bad_config:
musb_readb(musb->mregs, MUSB_DEVCTL));
}
+ if (status < 0)
+ goto fail3;
#ifdef CONFIG_SYSFS
status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
-#endif
if (status)
- goto fail2;
+ goto fail4;
+#endif
dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
({char *s;
@@ -2080,17 +2077,29 @@ bad_config:
return 0;
-fail2:
+fail4:
+ if (!is_otg_enabled(musb) && is_host_enabled(musb))
+ usb_remove_hcd(musb_to_hcd(musb));
+ else
+ musb_gadget_cleanup(musb);
+
+fail3:
+ if (musb->irq_wake)
+ device_init_wakeup(dev, 0);
musb_platform_exit(musb);
-fail:
- dev_err(musb->controller,
- "musb_init_controller failed with status %d\n", status);
+fail2:
if (musb->clock)
clk_put(musb->clock);
- device_init_wakeup(dev, 0);
+
+fail1:
+ dev_err(musb->controller,
+ "musb_init_controller failed with status %d\n", status);
+
musb_free(musb);
+fail0:
+
return status;
}
@@ -2127,7 +2136,6 @@ static int __init musb_probe(struct platform_device *pdev)
/* clobbered by use_dma=n */
orig_dma_mask = dev->dma_mask;
#endif
-
status = musb_init_controller(dev, irq, base);
if (status < 0)
iounmap(base);
@@ -2150,6 +2158,10 @@ static int __exit musb_remove(struct platform_device *pdev)
if (musb->board_mode == MUSB_HOST)
usb_remove_hcd(musb_to_hcd(musb));
#endif
+ musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+ musb_platform_exit(musb);
+ musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+
musb_free(musb);
iounmap(ctrl_base);
device_init_wakeup(&pdev->dev, 0);
@@ -2171,6 +2183,7 @@ void musb_save_context(struct musb *musb)
if (is_host_enabled(musb)) {
musb_context.frame = musb_readw(musb_base, MUSB_FRAME);
musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
+ musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
}
musb_context.power = musb_readb(musb_base, MUSB_POWER);
musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
@@ -2242,6 +2255,7 @@ void musb_restore_context(struct musb *musb)
if (is_host_enabled(musb)) {
musb_writew(musb_base, MUSB_FRAME, musb_context.frame);
musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode);
+ musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl);
}
musb_writeb(musb_base, MUSB_POWER, musb_context.power);
musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index d849fb81c13..ac17b004909 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -469,7 +469,7 @@ struct musb_csr_regs {
struct musb_context_registers {
-#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430)
+#ifdef CONFIG_PM
u32 otg_sysconfig, otg_forcestandby;
#endif
u8 power;
@@ -478,12 +478,12 @@ struct musb_context_registers {
u16 frame;
u8 index, testmode;
- u8 devctl, misc;
+ u8 devctl, busctl, misc;
struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
};
-#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430)
+#ifdef CONFIG_PM
extern void musb_platform_save_context(struct musb *musb,
struct musb_context_registers *musb_context);
extern void musb_platform_restore_context(struct musb *musb,
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index a9f288cd70e..6fca870e957 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -43,6 +43,7 @@
#include <linux/moduleparam.h>
#include <linux/stat.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include "musb_core.h"
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 3421cf9858b..877d20b1dff 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1689,7 +1689,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
dma->desired_mode = 1;
if (rx_count < hw_ep->max_packet_sz_rx) {
length = rx_count;
- dma->bDesiredMode = 0;
+ dma->desired_mode = 0;
} else {
length = urb->transfer_buffer_length;
}
@@ -2042,6 +2042,7 @@ static int musb_urb_enqueue(
* odd, rare, error prone, but legal.
*/
kfree(qh);
+ qh = NULL;
ret = 0;
} else
ret = musb_schedule(musb, qh,
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index 292894a2c24..fa55aacc385 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -326,6 +326,11 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
musb_writew(mbase, MUSB_RXFIFOADD, c_off);
}
+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
+{
+ musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val);
+}
+
static inline u8 musb_read_txfifosz(void __iomem *mbase)
{
return musb_readb(mbase, MUSB_TXFIFOSZ);
@@ -346,6 +351,11 @@ static inline u16 musb_read_rxfifoadd(void __iomem *mbase)
return musb_readw(mbase, MUSB_RXFIFOADD);
}
+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
+{
+ return musb_readb(mbase, MUSB_ULPI_BUSCONTROL);
+}
+
static inline u8 musb_read_configdata(void __iomem *mbase)
{
musb_writeb(mbase, MUSB_INDEX, 0);
@@ -491,7 +501,7 @@ static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum)
#define MUSB_FLAT_OFFSET(_epnum, _offset) \
(USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset))
-/* Not implemented - HW has seperate Tx/Rx FIFO */
+/* Not implemented - HW has separate Tx/Rx FIFO */
#define MUSB_TXCSR_MODE 0x0000
static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
@@ -510,20 +520,33 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
{
}
+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
+{
+}
+
static inline u8 musb_read_txfifosz(void __iomem *mbase)
{
+ return 0;
}
static inline u16 musb_read_txfifoadd(void __iomem *mbase)
{
+ return 0;
}
static inline u8 musb_read_rxfifosz(void __iomem *mbase)
{
+ return 0;
}
static inline u16 musb_read_rxfifoadd(void __iomem *mbase)
{
+ return 0;
+}
+
+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
+{
+ return 0;
}
static inline u8 musb_read_configdata(void __iomem *mbase)
@@ -577,22 +600,27 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum,
static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum)
{
+ return 0;
}
static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum)
{
+ return 0;
}
static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum)
{
+ return 0;
}
static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum)
{
+ return 0;
}
static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
{
+ return 0;
}
static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum)
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index bfe5fe4ebfe..7775e1c0a21 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -35,7 +35,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/time.h>
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 2fa7d5c00f3..1008044a3bb 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -33,6 +33,7 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "musb_core.h"
#include "musbhsdma.h"
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 3fe16867b5a..82592633502 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -27,7 +27,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/clk.h>
@@ -332,8 +331,5 @@ int musb_platform_exit(struct musb *musb)
musb_platform_suspend(musb);
- clk_put(musb->clock);
- musb->clock = NULL;
-
return 0;
}
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index ab776a8d98c..60d3938cafc 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -29,6 +29,19 @@ static void tusb_source_power(struct musb *musb, int is_on);
#define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf)
#define TUSB_REV_MINOR(reg_val) (reg_val & 0xf)
+#ifdef CONFIG_PM
+/* REVISIT: These should be only needed if somebody implements off idle */
+void musb_platform_save_context(struct musb *musb,
+ struct musb_context_registers *musb_context)
+{
+}
+
+void musb_platform_restore_context(struct musb *musb,
+ struct musb_context_registers *musb_context)
+{
+}
+#endif
+
/*
* Checks the revision. We need to use the DMA register as 3.0 does not
* have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 1c868096bd6..c061a88f2b0 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -15,6 +15,7 @@
#include <linux/usb.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <plat/dma.h>
#include <plat/mux.h>
@@ -38,7 +39,7 @@ struct tusb_omap_dma_ch {
struct tusb_omap_dma *tusb_dma;
- void __iomem *dma_addr;
+ dma_addr_t dma_addr;
u32 len;
u16 packet_sz;
@@ -125,6 +126,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
struct tusb_omap_dma_ch *chdat = to_chdat(channel);
struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
struct musb *musb = chdat->musb;
+ struct device *dev = musb->controller;
struct musb_hw_ep *hw_ep = chdat->hw_ep;
void __iomem *ep_conf = hw_ep->conf;
void __iomem *mbase = musb->mregs;
@@ -172,13 +174,15 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
DBG(3, "Using PIO for remaining %lu bytes\n", pio);
buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
if (chdat->tx) {
- dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
- chdat->transfer_len, DMA_TO_DEVICE);
+ dma_unmap_single(dev, chdat->dma_addr,
+ chdat->transfer_len,
+ DMA_TO_DEVICE);
musb_write_fifo(hw_ep, pio, buf);
} else {
+ dma_unmap_single(dev, chdat->dma_addr,
+ chdat->transfer_len,
+ DMA_FROM_DEVICE);
musb_read_fifo(hw_ep, pio, buf);
- dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
- chdat->transfer_len, DMA_FROM_DEVICE);
}
channel->actual_len += pio;
}
@@ -223,6 +227,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
struct tusb_omap_dma_ch *chdat = to_chdat(channel);
struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
struct musb *musb = chdat->musb;
+ struct device *dev = musb->controller;
struct musb_hw_ep *hw_ep = chdat->hw_ep;
void __iomem *mbase = musb->mregs;
void __iomem *ep_conf = hw_ep->conf;
@@ -298,14 +303,16 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
chdat->packet_sz = packet_sz;
chdat->len = len;
channel->actual_len = 0;
- chdat->dma_addr = (void __iomem *)dma_addr;
+ chdat->dma_addr = dma_addr;
channel->status = MUSB_DMA_STATUS_BUSY;
/* Since we're recycling dma areas, we need to clean or invalidate */
if (chdat->tx)
- dma_cache_maint(phys_to_virt(dma_addr), len, DMA_TO_DEVICE);
+ dma_map_single(dev, phys_to_virt(dma_addr), len,
+ DMA_TO_DEVICE);
else
- dma_cache_maint(phys_to_virt(dma_addr), len, DMA_FROM_DEVICE);
+ dma_map_single(dev, phys_to_virt(dma_addr), len,
+ DMA_FROM_DEVICE);
/* Use 16-bit transfer if dma_addr is not 32-bit aligned */
if ((dma_addr & 0x3) == 0) {
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c
index 1c26c94513e..221c44444ec 100644
--- a/drivers/usb/otg/gpio_vbus.c
+++ b/drivers/usb/otg/gpio_vbus.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/workqueue.h>
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
index af456b48985..e70014ab097 100644
--- a/drivers/usb/otg/nop-usb-xceiv.c
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -30,6 +30,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/usb/otg.h>
+#include <linux/slab.h>
struct nop_usb_xceiv {
struct otg_transceiver otg;
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 3e4e9f434d7..223cdf46ccb 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -37,6 +37,7 @@
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/notifier.h>
+#include <linux/slab.h>
/* Register defines */
diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
index 896527456b7..9010225e0d0 100644
--- a/drivers/usb/otg/ulpi.c
+++ b/drivers/usb/otg/ulpi.c
@@ -24,6 +24,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index c78b255e3f8..a0ecb42cb33 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -474,14 +474,14 @@ config USB_SERIAL_OTI6858
config USB_SERIAL_QCAUX
tristate "USB Qualcomm Auxiliary Serial Port Driver"
- ---help---
+ help
Say Y here if you want to use the auxiliary serial ports provided
by many modems based on Qualcomm chipsets. These ports often use
a proprietary protocol called DM and cannot be used for AT- or
PPP-based communication.
To compile this driver as a module, choose M here: the
- module will be called moto_modem. If unsure, choose N.
+ module will be called qcaux. If unsure, choose N.
config USB_SERIAL_QUALCOMM
tristate "USB Qualcomm Serial modem"
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 365db1097bf..4fd7af98b1a 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -43,6 +43,7 @@
*/
#include <linux/tty.h>
+#include <linux/slab.h>
#include <linux/tty_flip.h>
#include <linux/circ_buf.h>
#include <linux/usb.h>
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 547c9448c28..9b66bf19f75 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/ioctl.h>
#include <linux/tty.h>
+#include <linux/slab.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index ba555c528cc..7f547dc3a59 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/tty.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 9f4fed1968b..7e8e3981841 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/serial.h>
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index b22ac325852..f347da2ef00 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -181,6 +181,7 @@ static int usb_console_setup(struct console *co, char *options)
/* The console is special in terms of closing the device so
* indicate this port is now acting as a system console. */
port->console = 1;
+ port->port.console = 1;
mutex_unlock(&serial->disc_mutex);
return retval;
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 507382b0a9e..ec9b0449ccf 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -313,11 +313,6 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
return -EPROTO;
}
- /* Single data value */
- result = usb_control_msg(serial->dev,
- usb_sndctrlpipe(serial->dev, 0),
- request, REQTYPE_HOST_TO_DEVICE, data[0],
- 0, NULL, 0, 300);
return 0;
}
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index baf74b44e6e..e23c77925e7 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -152,7 +152,7 @@ struct cypress_private {
int isthrottled; /* if throttled, discard reads */
wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
char prev_status, diff_status; /* used for TIOCMIWAIT */
- /* we pass a pointer to this as the arguement sent to
+ /* we pass a pointer to this as the argument sent to
cypress_set_termios old_termios */
struct ktermios tmp_termios; /* stores the old termios settings */
};
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 6af0dfa5f5a..1d7c4fac02e 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -91,7 +91,7 @@ struct ftdi_private {
unsigned long tx_outstanding_bytes;
unsigned long tx_outstanding_urbs;
unsigned short max_packet_size;
- struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */
+ struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */
};
/* struct ftdi_sio_quirk is used by devices requiring special attention. */
@@ -658,6 +658,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
+ { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
@@ -1272,8 +1273,8 @@ check_and_exit:
(priv->flags & ASYNC_SPD_MASK)) ||
(((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
(old_priv.custom_divisor != priv->custom_divisor))) {
- mutex_unlock(&priv->cfg_lock);
change_speed(tty, port);
+ mutex_unlock(&priv->cfg_lock);
}
else
mutex_unlock(&priv->cfg_lock);
@@ -2264,9 +2265,11 @@ static void ftdi_set_termios(struct tty_struct *tty,
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
} else {
/* set the baudrate determined before */
+ mutex_lock(&priv->cfg_lock);
if (change_speed(tty, port))
dev_err(&port->dev, "%s urb failed to set baudrate\n",
__func__);
+ mutex_unlock(&priv->cfg_lock);
/* Ensure RTS and DTR are raised when baudrate changed from 0 */
if (!old_termios || (old_termios->c_cflag & CBAUD) == B0)
set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 0727e198503..75482cbc399 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -501,6 +501,13 @@
#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */
/*
+ * Contec products (http://www.contec.com)
+ * Submitted by Daniel Sangorrin
+ */
+#define CONTEC_VID 0x06CE /* Vendor ID */
+#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */
+
+/*
* Definitions for B&B Electronics products.
*/
#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 89fac36684c..f804acb138e 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -130,7 +130,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port
spin_unlock_irqrestore(&port->lock, flags);
/* if we have a bulk endpoint, start reading from it */
- if (serial->num_bulk_in) {
+ if (port->bulk_in_size) {
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev,
@@ -159,10 +159,10 @@ static void generic_cleanup(struct usb_serial_port *port)
dbg("%s - port %d", __func__, port->number);
if (serial->dev) {
- /* shutdown any bulk reads that might be going on */
- if (serial->num_bulk_out)
+ /* shutdown any bulk transfers that might be going on */
+ if (port->bulk_out_size)
usb_kill_urb(port->write_urb);
- if (serial->num_bulk_in)
+ if (port->bulk_in_size)
usb_kill_urb(port->read_urb);
}
}
@@ -333,15 +333,15 @@ int usb_serial_generic_write(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);
+ /* only do something if we have a bulk out endpoint */
+ if (!port->bulk_out_size)
+ return -ENODEV;
+
if (count == 0) {
dbg("%s - write request of 0 bytes", __func__);
return 0;
}
- /* only do something if we have a bulk out endpoint */
- if (!serial->num_bulk_out)
- return 0;
-
if (serial->type->max_in_flight_urbs)
return usb_serial_multi_urb_write(tty, port,
buf, count);
@@ -364,14 +364,19 @@ int usb_serial_generic_write_room(struct tty_struct *tty)
int room = 0;
dbg("%s - port %d", __func__, port->number);
+
+ if (!port->bulk_out_size)
+ return 0;
+
spin_lock_irqsave(&port->lock, flags);
if (serial->type->max_in_flight_urbs) {
if (port->urbs_in_flight < serial->type->max_in_flight_urbs)
room = port->bulk_out_size *
(serial->type->max_in_flight_urbs -
port->urbs_in_flight);
- } else if (serial->num_bulk_out)
+ } else {
room = kfifo_avail(&port->write_fifo);
+ }
spin_unlock_irqrestore(&port->lock, flags);
dbg("%s - returns %d", __func__, room);
@@ -382,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
- int chars = 0;
unsigned long flags;
+ int chars;
dbg("%s - port %d", __func__, port->number);
+ if (!port->bulk_out_size)
+ return 0;
+
spin_lock_irqsave(&port->lock, flags);
if (serial->type->max_in_flight_urbs)
chars = port->tx_bytes_flight;
- else if (serial->num_bulk_out)
+ else
chars = kfifo_len(&port->write_fifo);
spin_unlock_irqrestore(&port->lock, flags);
@@ -415,11 +423,13 @@ void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port,
((serial->type->read_bulk_callback) ?
serial->type->read_bulk_callback :
usb_serial_generic_read_bulk_callback), port);
+
result = usb_submit_urb(urb, mem_flags);
- if (result)
+ if (result && result != -EPERM) {
dev_err(&port->dev,
"%s - failed resubmitting read urb, error %d\n",
__func__, result);
+ }
}
EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb);
@@ -498,23 +508,18 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
if (port->urbs_in_flight < 0)
port->urbs_in_flight = 0;
spin_unlock_irqrestore(&port->lock, flags);
-
- if (status) {
- dbg("%s - nonzero multi-urb write bulk status "
- "received: %d", __func__, status);
- return;
- }
} else {
port->write_urb_busy = 0;
- if (status) {
- dbg("%s - nonzero multi-urb write bulk status "
- "received: %d", __func__, status);
+ if (status)
kfifo_reset_out(&port->write_fifo);
- } else
+ else
usb_serial_generic_write_start(port);
}
+ if (status)
+ dbg("%s - non-zero urb status: %d", __func__, status);
+
usb_serial_port_softint(port);
}
EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index 04a6cbbed2c..a6b207c8491 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -12,6 +12,7 @@
* flags as the navman is rx only so cannot echo.
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index f37476e2268..ed01f3b2de8 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
+#include <linux/slab.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/module.h>
@@ -115,7 +116,7 @@ static void opticon_bulk_callback(struct urb *urb)
}
} else {
dev_dbg(&priv->udev->dev,
- "Improper ammount of data received from the device, "
+ "Improper amount of data received from the device, "
"%d bytes", urb->actual_length);
}
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 847b805d63a..84d0edad8e4 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -37,6 +37,7 @@
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/usb.h>
@@ -288,7 +289,9 @@ static int option_resume(struct usb_serial *serial);
#define QUALCOMM_VENDOR_ID 0x05C6
-#define MAXON_VENDOR_ID 0x16d8
+#define CMOTECH_VENDOR_ID 0x16d8
+#define CMOTECH_PRODUCT_6008 0x6008
+#define CMOTECH_PRODUCT_6280 0x6280
#define TELIT_VENDOR_ID 0x1bc7
#define TELIT_PRODUCT_UC864E 0x1003
@@ -302,6 +305,11 @@ static int option_resume(struct usb_serial *serial);
#define ZTE_PRODUCT_CDMA_TECH 0xfffe
#define ZTE_PRODUCT_AC8710 0xfff1
#define ZTE_PRODUCT_AC2726 0xfff5
+#define ZTE_PRODUCT_AC8710T 0xffff
+
+/* ZTE PRODUCTS -- alternate vendor ID */
+#define ZTE_VENDOR_ID2 0x1d6b
+#define ZTE_PRODUCT_MF_330 0x0002
#define BENQ_VENDOR_ID 0x04a5
#define BENQ_PRODUCT_H10 0x4068
@@ -309,6 +317,7 @@ static int option_resume(struct usb_serial *serial);
#define DLINK_VENDOR_ID 0x1186
#define DLINK_PRODUCT_DWM_652 0x3e04
#define DLINK_PRODUCT_DWM_652_U5 0xce16
+#define DLINK_PRODUCT_DWM_652_U5A 0xce1e
#define QISDA_VENDOR_ID 0x1da5
#define QISDA_PRODUCT_H21_4512 0x4512
@@ -332,6 +341,24 @@ static int option_resume(struct usb_serial *serial);
#define ALCATEL_VENDOR_ID 0x1bbb
#define ALCATEL_PRODUCT_X060S 0x0000
+#define PIRELLI_VENDOR_ID 0x1266
+#define PIRELLI_PRODUCT_C100_1 0x1002
+#define PIRELLI_PRODUCT_C100_2 0x1003
+#define PIRELLI_PRODUCT_1004 0x1004
+#define PIRELLI_PRODUCT_1005 0x1005
+#define PIRELLI_PRODUCT_1006 0x1006
+#define PIRELLI_PRODUCT_1007 0x1007
+#define PIRELLI_PRODUCT_1008 0x1008
+#define PIRELLI_PRODUCT_1009 0x1009
+#define PIRELLI_PRODUCT_100A 0x100a
+#define PIRELLI_PRODUCT_100B 0x100b
+#define PIRELLI_PRODUCT_100C 0x100c
+#define PIRELLI_PRODUCT_100D 0x100d
+#define PIRELLI_PRODUCT_100E 0x100e
+#define PIRELLI_PRODUCT_100F 0x100f
+#define PIRELLI_PRODUCT_1011 0x1011
+#define PIRELLI_PRODUCT_1012 0x1012
+
/* Airplus products */
#define AIRPLUS_VENDOR_ID 0x1011
#define AIRPLUS_PRODUCT_MCD650 0x3198
@@ -351,6 +378,8 @@ static int option_resume(struct usb_serial *serial);
#define HAIER_VENDOR_ID 0x201e
#define HAIER_PRODUCT_CE100 0x2009
+#define CINTERION_VENDOR_ID 0x0681
+
/* some devices interfaces need special handling due to a number of reasons */
enum option_blacklist_reason {
OPTION_BLACKLIST_NONE = 0,
@@ -547,7 +576,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
- { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
@@ -656,9 +686,12 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+ { USB_DEVICE(ZTE_VENDOR_ID2, ZTE_PRODUCT_MF_330) },
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
{ USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
+ { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) },
{ 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) },
@@ -666,7 +699,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
- { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) },
{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
@@ -675,6 +707,25 @@ static const struct usb_device_id option_ids[] = {
.driver_info = (kernel_ulong_t)&four_g_w14_blacklist
},
{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
+ /* Pirelli */
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) },
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) },
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) },
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) },
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
+
+ { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
@@ -798,12 +849,19 @@ static int option_probe(struct usb_serial *serial,
const struct usb_device_id *id)
{
struct option_intf_private *data;
+
/* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */
if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8)
return -ENODEV;
+ /* Bandrich modem and AT command interface is 0xff */
+ if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID ||
+ serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) &&
+ serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
+ return -ENODEV;
+
data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL);
if (!data)
return -ENOMEM;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 73d5f346d3e..c28b1607eac 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -59,6 +59,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
@@ -97,6 +98,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
+ { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index d640dc95156..23c09b38b9e 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -20,6 +20,7 @@
#define PL2303_PRODUCT_ID_ALDIGA 0x0611
#define PL2303_PRODUCT_ID_MMX 0x0612
#define PL2303_PRODUCT_ID_GPRS 0x0609
+#define PL2303_PRODUCT_ID_HCR331 0x331a
#define ATEN_VENDOR_ID 0x0557
#define ATEN_VENDOR_ID2 0x0547
@@ -134,3 +135,7 @@
/* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
#define SANWA_VENDOR_ID 0x11ad
#define SANWA_PRODUCT_ID 0x0001
+
+/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
+#define ADLINK_VENDOR_ID 0x0b63
+#define ADLINK_ND6530_PRODUCT_ID 0x6530
diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c
index 0b936206171..7e3bea23600 100644
--- a/drivers/usb/serial/qcaux.c
+++ b/drivers/usb/serial/qcaux.c
@@ -42,6 +42,14 @@
#define CMOTECH_PRODUCT_CDU550 0x5553
#define CMOTECH_PRODUCT_CDX650 0x6512
+/* LG devices */
+#define LG_VENDOR_ID 0x1004
+#define LG_PRODUCT_VX4400_6000 0x6000 /* VX4400/VX6000/Rumor */
+
+/* Sanyo devices */
+#define SANYO_VENDOR_ID 0x0474
+#define SANYO_PRODUCT_KATANA_LX 0x0754 /* SCP-3800 (Katana LX) */
+
static struct usb_device_id id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) },
@@ -51,6 +59,8 @@ static struct usb_device_id id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_ALLTEL, 0xff, 0x00, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU550, 0xff, 0xff, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 310ff6ec656..53a2d5a935a 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -47,6 +47,35 @@ static const struct usb_device_id id_table[] = {
{USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
{USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */
{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, 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) */
+ {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */
+ {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */
+ {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */
+ {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */
+ {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
+ {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */
+ {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */
+ {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */
+ {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */
+ {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */
+ {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */
+ {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */
+ {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+ {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */
+ {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index 4b463cd140e..43a0cadd578 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -64,8 +64,8 @@
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 34e6f894cba..ef0bdb08d78 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -26,6 +26,7 @@
#include <linux/jiffies.h>
#include <linux/errno.h>
#include <linux/tty.h>
+#include <linux/slab.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
@@ -229,6 +230,7 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = {
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
{ USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
+ { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */
{ USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
{ USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index 72398888858..d9457bd4fe1 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
+#include <linux/slab.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
@@ -94,7 +95,7 @@ static void symbol_int_callback(struct urb *urb)
}
} else {
dev_dbg(&priv->udev->dev,
- "Improper ammount of data received from the device, "
+ "Improper amount of data received from the device, "
"%d bytes", urb->actual_length);
}
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 0afe5c71c17..e1bfda33f5b 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -172,7 +172,7 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -180,6 +180,9 @@ static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
@@ -192,7 +195,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -200,6 +203,9 @@ static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1]
{ USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
@@ -287,6 +293,8 @@ MODULE_FIRMWARE("ti_5052.fw");
MODULE_FIRMWARE("mts_cdma.fw");
MODULE_FIRMWARE("mts_gsm.fw");
MODULE_FIRMWARE("mts_edge.fw");
+MODULE_FIRMWARE("mts_mt9234mu.fw");
+MODULE_FIRMWARE("mts_mt9234zba.fw");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
@@ -1687,6 +1695,7 @@ static int ti_download_firmware(struct ti_device *tdev)
const struct firmware *fw_p;
char buf[32];
+ dbg("%s\n", __func__);
/* try ID specific firmware first, then try generic firmware */
sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
dev->descriptor.idProduct);
@@ -1703,7 +1712,15 @@ static int ti_download_firmware(struct ti_device *tdev)
case MTS_EDGE_PRODUCT_ID:
strcpy(buf, "mts_edge.fw");
break;
- }
+ case MTS_MT9234MU_PRODUCT_ID:
+ strcpy(buf, "mts_mt9234mu.fw");
+ break;
+ case MTS_MT9234ZBA_PRODUCT_ID:
+ strcpy(buf, "mts_mt9234zba.fw");
+ break;
+ case MTS_MT9234ZBAOLD_PRODUCT_ID:
+ strcpy(buf, "mts_mt9234zba.fw");
+ break; }
}
if (buf[0] == '\0') {
if (tdev->td_is_3410)
@@ -1718,7 +1735,7 @@ static int ti_download_firmware(struct ti_device *tdev)
return -ENOENT;
}
if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
- dev_err(&dev->dev, "%s - firmware too large\n", __func__);
+ dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
return -ENOENT;
}
@@ -1730,6 +1747,7 @@ static int ti_download_firmware(struct ti_device *tdev)
status = ti_do_download(dev, pipe, buffer, fw_p->size);
kfree(buffer);
} else {
+ dbg("%s ENOMEM\n", __func__);
status = -ENOMEM;
}
release_firmware(fw_p);
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index f323c602585..2aac1953993 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -45,6 +45,9 @@
#define MTS_CDMA_PRODUCT_ID 0xF110
#define MTS_GSM_PRODUCT_ID 0xF111
#define MTS_EDGE_PRODUCT_ID 0xF112
+#define MTS_MT9234MU_PRODUCT_ID 0xF114
+#define MTS_MT9234ZBA_PRODUCT_ID 0xF115
+#define MTS_MT9234ZBAOLD_PRODUCT_ID 0x0319
/* Commands */
#define TI_GET_VERSION 0x01
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c
index 252cc2d993b..28026b47344 100644
--- a/drivers/usb/serial/usb_debug.c
+++ b/drivers/usb/serial/usb_debug.c
@@ -8,6 +8,7 @@
* 2 as published by the Free Software Foundation.
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 67edc65acb8..42d0eaed4a0 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -32,6 +32,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c
index 7953d93a773..ba1b7890688 100644
--- a/drivers/usb/storage/karma.c
+++ b/drivers/usb/storage/karma.c
@@ -19,6 +19,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c
index 773a5cd38c5..89460181d12 100644
--- a/drivers/usb/storage/option_ms.c
+++ b/drivers/usb/storage/option_ms.c
@@ -21,6 +21,7 @@
*/
#include <linux/usb.h>
+#include <linux/slab.h>
#include "usb.h"
#include "transport.h"
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 4cc035562cc..d8d98cfecad 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -43,7 +43,6 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mutex.h>
diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c
index 4395c4100ec..57fc2f532ca 100644
--- a/drivers/usb/storage/sierra_ms.c
+++ b/drivers/usb/storage/sierra_ms.c
@@ -3,6 +3,7 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include "usb.h"
#include "transport.h"
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 468038126e5..f253edec3bb 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -44,8 +44,8 @@
*/
#include <linux/sched.h>
+#include <linux/gfp.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/usb/quirks.h>
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 98b549b1cab..ccf1dbbb87e 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -374,6 +374,15 @@ UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY),
+/* Reported by Ondrej Zary <linux@rainbow-software.org>
+ * The device reports one sector more and breaks when that sector is accessed
+ */
+UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c,
+ "ScanLogic",
+ "SL11R-IDE",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY),
+
/* Reported by Kriston Fincher <kriston@airmail.net>
* Patch submitted by Sean Millichamp <sean@bruenor.org>
* This is to support the Panasonic PalmCam PV-SD4090
@@ -1380,20 +1389,6 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
-/* Jeremy Katz <katzj@redhat.com>:
- * The Blackberry Pearl can run in two modes; a usb-storage only mode
- * and a mode that allows access via mass storage and to its database.
- * The berry_charge module will set the device to dual mode and thus we
- * should ignore its native mode if that module is built
- */
-#ifdef CONFIG_USB_BERRY_CHARGE
-UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001,
- "RIM",
- "Blackberry Pearl",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_IGNORE_DEVICE ),
-#endif
-
/* Reported by Michael Stattmann <michael@stattmann.com> */
UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
"Sony Ericsson",
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c
index 51a8e0d5789..c0c5665e60a 100644
--- a/drivers/usb/wusbcore/cbaf.c
+++ b/drivers/usb/wusbcore/cbaf.c
@@ -92,6 +92,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/uwb.h>
#include <linux/usb/wusb.h>
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c
index 9579cf4c38b..827c87f10cc 100644
--- a/drivers/usb/wusbcore/crypto.c
+++ b/drivers/usb/wusbcore/crypto.c
@@ -49,6 +49,7 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/uwb.h>
+#include <linux/slab.h>
#include <linux/usb/wusb.h>
#include <linux/scatterlist.h>
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index 1c918286159..7ec24e46b34 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -88,6 +88,7 @@
#include <linux/jiffies.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include "wusbhc.h"
@@ -437,7 +438,7 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
keep_alives = 0;
for (cnt = 0;
- keep_alives <= WUIE_ELT_MAX && cnt < wusbhc->ports_max;
+ keep_alives < WUIE_ELT_MAX && cnt < wusbhc->ports_max;
cnt++) {
unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);
diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c
index 2d827397e30..0a57ff0a0b0 100644
--- a/drivers/usb/wusbcore/mmc.c
+++ b/drivers/usb/wusbcore/mmc.c
@@ -37,6 +37,7 @@
* - add timers that autoremove intervalled IEs?
*/
#include <linux/usb/wusb.h>
+#include <linux/slab.h>
#include "wusbhc.h"
/* Initialize the MMCIEs handling mechanism */
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
index 9fe4246cecb..a68ad7aa0b5 100644
--- a/drivers/usb/wusbcore/rh.c
+++ b/drivers/usb/wusbcore/rh.c
@@ -69,6 +69,7 @@
*
* wusbhc_rh_start_port_reset() ??? unimplemented
*/
+#include <linux/slab.h>
#include "wusbhc.h"
/*
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index edcd2d75603..b60799b811c 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -23,6 +23,7 @@
* FIXME: docs
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/usb/ch9.h>
#include <linux/random.h>
#include "wusbhc.h"
diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/usb/wusbcore/wa-hc.c
index 9d04722415b..59a748a0e5d 100644
--- a/drivers/usb/wusbcore/wa-hc.c
+++ b/drivers/usb/wusbcore/wa-hc.c
@@ -22,6 +22,7 @@
*
* FIXME: docs
*/
+#include <linux/slab.h>
#include "wusbhc.h"
#include "wa-hc.h"
diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/usb/wusbcore/wa-nep.c
index 17d2626038b..f67f7f1e6df 100644
--- a/drivers/usb/wusbcore/wa-nep.c
+++ b/drivers/usb/wusbcore/wa-nep.c
@@ -51,6 +51,7 @@
*/
#include <linux/workqueue.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include "wa-hc.h"
#include "wusbhc.h"
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c
index 7369655f69c..c7b1d8108de 100644
--- a/drivers/usb/wusbcore/wa-rpipe.c
+++ b/drivers/usb/wusbcore/wa-rpipe.c
@@ -60,6 +60,7 @@
#include <linux/init.h>
#include <asm/atomic.h>
#include <linux/bitmap.h>
+#include <linux/slab.h>
#include "wusbhc.h"
#include "wa-hc.h"
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
index 489b47833e2..112ef7e26f6 100644
--- a/drivers/usb/wusbcore/wa-xfer.c
+++ b/drivers/usb/wusbcore/wa-xfer.c
@@ -81,6 +81,7 @@
*/
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/hash.h>
#include "wa-hc.h"
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h
index fd2fd4e277e..759cda55f7c 100644
--- a/drivers/usb/wusbcore/wusbhc.h
+++ b/drivers/usb/wusbcore/wusbhc.h
@@ -198,7 +198,7 @@ struct wusb_port {
* ports) this HC will take. Read-only.
*
* @port Array of port status for each fake root port. Guaranteed to
- * always be the same lenght during device existence
+ * always be the same length during device existence
* [this allows for some unlocked but referenced reading].
*
* @mmcies_max Max number of Information Elements this HC can send
diff --git a/drivers/uwb/address.c b/drivers/uwb/address.c
index ad21b1d7218..973321327c4 100644
--- a/drivers/uwb/address.c
+++ b/drivers/uwb/address.c
@@ -23,6 +23,7 @@
* FIXME: docs
*/
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/device.h>
diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c
index c13cec7dcbc..436e4f7110c 100644
--- a/drivers/uwb/allocator.c
+++ b/drivers/uwb/allocator.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/uwb.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c
index 36bc3158006..dcdd59bfcd0 100644
--- a/drivers/uwb/beacon.c
+++ b/drivers/uwb/beacon.c
@@ -28,6 +28,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kdev_t.h>
+#include <linux/slab.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/driver.c b/drivers/uwb/driver.c
index da77e41de99..08bd6dbfd4a 100644
--- a/drivers/uwb/driver.c
+++ b/drivers/uwb/driver.c
@@ -74,13 +74,16 @@
unsigned long beacon_timeout_ms = 500;
static
-ssize_t beacon_timeout_ms_show(struct class *class, char *buf)
+ssize_t beacon_timeout_ms_show(struct class *class,
+ struct class_attribute *attr,
+ char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%lu\n", beacon_timeout_ms);
}
static
ssize_t beacon_timeout_ms_store(struct class *class,
+ struct class_attribute *attr,
const char *buf, size_t size)
{
unsigned long bt;
diff --git a/drivers/uwb/drp-ie.c b/drivers/uwb/drp-ie.c
index 2840d7bf9e6..520673109a7 100644
--- a/drivers/uwb/drp-ie.c
+++ b/drivers/uwb/drp-ie.c
@@ -18,6 +18,7 @@
*/
#include <linux/kernel.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/uwb.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index 4f5ca99a04b..a8d83e25e3b 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -20,6 +20,7 @@
*/
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/est.c b/drivers/uwb/est.c
index 328fcc2b609..a2eaa3c33b0 100644
--- a/drivers/uwb/est.c
+++ b/drivers/uwb/est.c
@@ -40,6 +40,7 @@
* uwb_est_get_size()
*/
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
index e7eeb63fab2..2babcd4fbfc 100644
--- a/drivers/uwb/hwa-rc.c
+++ b/drivers/uwb/hwa-rc.c
@@ -53,6 +53,7 @@
*/
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/wusb.h>
#include <linux/usb/wusb-wa.h>
@@ -891,7 +892,7 @@ static int hwarc_post_reset(struct usb_interface *iface)
}
/** USB device ID's that we handle */
-static struct usb_device_id hwarc_id_table[] = {
+static const struct usb_device_id hwarc_id_table[] = {
/* D-Link DUB-1210 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3d02, 0xe0, 0x01, 0x02),
.driver_info = WUSB_QUIRK_WHCI_CMD_EVT },
diff --git a/drivers/uwb/i1480/dfu/mac.c b/drivers/uwb/i1480/dfu/mac.c
index 694d0daf88a..6ec14f5fcde 100644
--- a/drivers/uwb/i1480/dfu/mac.c
+++ b/drivers/uwb/i1480/dfu/mac.c
@@ -28,6 +28,7 @@
*/
#include <linux/delay.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <linux/uwb.h>
#include "i1480-dfu.h"
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c
index 0bb665a0c02..ba8664328af 100644
--- a/drivers/uwb/i1480/dfu/usb.c
+++ b/drivers/uwb/i1480/dfu/usb.c
@@ -37,6 +37,7 @@
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/uwb.h>
#include <linux/usb/wusb.h>
@@ -120,8 +121,7 @@ int i1480_usb_write(struct i1480 *i1480, u32 memory_address,
result = usb_control_msg(
i1480_usb->usb_dev, usb_sndctrlpipe(i1480_usb->usb_dev, 0),
0xf0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- cpu_to_le16(memory_address & 0xffff),
- cpu_to_le16((memory_address >> 16) & 0xffff),
+ memory_address, (memory_address >> 16),
i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */);
if (result < 0)
break;
@@ -166,8 +166,7 @@ int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size)
result = usb_control_msg(
i1480_usb->usb_dev, usb_rcvctrlpipe(i1480_usb->usb_dev, 0),
0xf0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- cpu_to_le16(itr_addr & 0xffff),
- cpu_to_le16((itr_addr >> 16) & 0xffff),
+ itr_addr, (itr_addr >> 16),
i1480->cmd_buf + itr, itr_size,
100 /* FIXME: arbitrary */);
if (result < 0) {
@@ -413,6 +412,10 @@ error:
return result;
}
+MODULE_FIRMWARE("i1480-pre-phy-0.0.bin");
+MODULE_FIRMWARE("i1480-usb-0.0.bin");
+MODULE_FIRMWARE("i1480-phy-0.0.bin");
+
#define i1480_USB_DEV(v, p) \
{ \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE \
@@ -430,7 +433,7 @@ error:
/** USB device ID's that we handle */
-static struct usb_device_id i1480_usb_id_table[] = {
+static const struct usb_device_id i1480_usb_id_table[] = {
i1480_USB_DEV(0x8086, 0xdf3b),
i1480_USB_DEV(0x15a9, 0x0005),
i1480_USB_DEV(0x07d1, 0x3802),
diff --git a/drivers/uwb/i1480/i1480-est.c b/drivers/uwb/i1480/i1480-est.c
index 7bf8c6febae..f2eb4d8b76c 100644
--- a/drivers/uwb/i1480/i1480-est.c
+++ b/drivers/uwb/i1480/i1480-est.c
@@ -54,7 +54,7 @@ static struct uwb_est_entry i1480_est_fd01[] = {
.size = sizeof(struct i1480_rceb) + 2 },
};
-static int i1480_est_init(void)
+static int __init i1480_est_init(void)
{
int result = uwb_est_register(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b,
i1480_est_fd00,
@@ -73,7 +73,7 @@ static int i1480_est_init(void)
}
module_init(i1480_est_init);
-static void i1480_est_exit(void)
+static void __exit i1480_est_exit(void)
{
uwb_est_unregister(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b,
i1480_est_fd00, ARRAY_SIZE(i1480_est_fd00));
diff --git a/drivers/uwb/i1480/i1480u-wlp/lc.c b/drivers/uwb/i1480/i1480u-wlp/lc.c
index f272dfe54d4..def778cf221 100644
--- a/drivers/uwb/i1480/i1480u-wlp/lc.c
+++ b/drivers/uwb/i1480/i1480u-wlp/lc.c
@@ -55,6 +55,7 @@
* is being removed.
* i1480u_rm()
*/
+#include <linux/gfp.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
diff --git a/drivers/uwb/i1480/i1480u-wlp/netdev.c b/drivers/uwb/i1480/i1480u-wlp/netdev.c
index b236e696994..f98f6ce8b9e 100644
--- a/drivers/uwb/i1480/i1480u-wlp/netdev.c
+++ b/drivers/uwb/i1480/i1480u-wlp/netdev.c
@@ -39,6 +39,7 @@
* i1480u_set_config():
*/
+#include <linux/slab.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
diff --git a/drivers/uwb/i1480/i1480u-wlp/rx.c b/drivers/uwb/i1480/i1480u-wlp/rx.c
index 25a2758beb6..d4e51e108aa 100644
--- a/drivers/uwb/i1480/i1480u-wlp/rx.c
+++ b/drivers/uwb/i1480/i1480u-wlp/rx.c
@@ -64,6 +64,7 @@
*
*/
+#include <linux/gfp.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include "i1480u-wlp.h"
diff --git a/drivers/uwb/i1480/i1480u-wlp/tx.c b/drivers/uwb/i1480/i1480u-wlp/tx.c
index 3db3449dbda..3c117a36456 100644
--- a/drivers/uwb/i1480/i1480u-wlp/tx.c
+++ b/drivers/uwb/i1480/i1480u-wlp/tx.c
@@ -54,6 +54,7 @@
* the times the MTU will be smaller than one page...
*/
+#include <linux/slab.h>
#include "i1480u-wlp.h"
enum {
diff --git a/drivers/uwb/ie.c b/drivers/uwb/ie.c
index ab976686175..30acec74042 100644
--- a/drivers/uwb/ie.c
+++ b/drivers/uwb/ie.c
@@ -24,6 +24,7 @@
* FIXME: docs
*/
+#include <linux/slab.h>
#include "uwb-internal.h"
/**
diff --git a/drivers/uwb/lc-dev.c b/drivers/uwb/lc-dev.c
index 1097e81b56d..90113bafefc 100644
--- a/drivers/uwb/lc-dev.c
+++ b/drivers/uwb/lc-dev.c
@@ -23,6 +23,7 @@
* FIXME: docs
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kdev_t.h>
diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c
index 9611ef3b787..b0091c771b9 100644
--- a/drivers/uwb/lc-rc.c
+++ b/drivers/uwb/lc-rc.c
@@ -35,6 +35,7 @@
#include <linux/kdev_t.h>
#include <linux/etherdevice.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
index 78510a1f410..697e56a5bcd 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -83,6 +83,7 @@
*/
#include <linux/kernel.h>
#include <linux/timer.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c
index 7f0512e43d9..27849292b55 100644
--- a/drivers/uwb/reset.c
+++ b/drivers/uwb/reset.c
@@ -30,6 +30,7 @@
*/
#include <linux/kernel.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index 6b76f4bb4cc..78c892233cf 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -17,6 +17,7 @@
*/
#include <linux/kernel.h>
#include <linux/uwb.h>
+#include <linux/slab.h>
#include <linux/random.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/scan.c b/drivers/uwb/scan.c
index 2d270748f32..76a1a1ed7d3 100644
--- a/drivers/uwb/scan.c
+++ b/drivers/uwb/scan.c
@@ -35,6 +35,7 @@
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include "uwb-internal.h"
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c
index cdd6c8efc9f..5fad4e791b3 100644
--- a/drivers/uwb/umc-bus.c
+++ b/drivers/uwb/umc-bus.c
@@ -62,12 +62,12 @@ int umc_controller_reset(struct umc_dev *umc)
struct device *parent = umc->dev.parent;
int ret = 0;
- if(down_trylock(&parent->sem))
+ if (device_trylock(parent))
return -EAGAIN;
ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
if (ret >= 0)
ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper);
- up(&parent->sem);
+ device_unlock(parent);
return ret;
}
diff --git a/drivers/uwb/umc-dev.c b/drivers/uwb/umc-dev.c
index 1fc7d8270bb..43ea9982e68 100644
--- a/drivers/uwb/umc-dev.c
+++ b/drivers/uwb/umc-dev.c
@@ -6,6 +6,7 @@
* This file is released under the GNU GPL v2.
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/uwb/umc.h>
static void umc_device_release(struct device *dev)
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h
index d5bcfc1c227..157485c862c 100644
--- a/drivers/uwb/uwb-internal.h
+++ b/drivers/uwb/uwb-internal.h
@@ -366,12 +366,12 @@ struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal);
static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
{
- down(&uwb_dev->dev.sem);
+ device_lock(&uwb_dev->dev);
}
static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev)
{
- up(&uwb_dev->dev.sem);
+ device_unlock(&uwb_dev->dev);
}
#endif /* #ifndef __UWB_INTERNAL_H__ */
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c
index 5a777d8624d..001c8b4020a 100644
--- a/drivers/uwb/uwbd.c
+++ b/drivers/uwb/uwbd.c
@@ -43,7 +43,7 @@
*
* EVENTS
*
- * Events have a type, a subtype, a lenght, some other stuff and the
+ * Events have a type, a subtype, a length, some other stuff and the
* data blob, which depends on the event. The header is 'struct
* uwb_event'; for payloads, see 'struct uwbd_evt_*'.
*
@@ -69,6 +69,7 @@
* Handler functions are called normally uwbd_evt_handle_*().
*/
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/freezer.h>
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c
index 01950c62dc8..73495583c44 100644
--- a/drivers/uwb/whc-rc.c
+++ b/drivers/uwb/whc-rc.c
@@ -45,6 +45,7 @@
#include <linux/sched.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/uwb.h>
#include <linux/uwb/whci.h>
diff --git a/drivers/uwb/whci.c b/drivers/uwb/whci.c
index 2e2784627ad..b221142446a 100644
--- a/drivers/uwb/whci.c
+++ b/drivers/uwb/whci.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/uwb/whci.h>
#include <linux/uwb/umc.h>
diff --git a/drivers/uwb/wlp/eda.c b/drivers/uwb/wlp/eda.c
index 69e02003971..086fc0cf940 100644
--- a/drivers/uwb/wlp/eda.c
+++ b/drivers/uwb/wlp/eda.c
@@ -53,6 +53,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <linux/wlp.h>
#include "wlp-internal.h"
diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c
index aa42fcee4c4..3a8e033dce2 100644
--- a/drivers/uwb/wlp/messages.c
+++ b/drivers/uwb/wlp/messages.c
@@ -24,6 +24,7 @@
*/
#include <linux/wlp.h>
+#include <linux/slab.h>
#include "wlp-internal.h"
@@ -259,6 +260,63 @@ out:
}
+static ssize_t wlp_get_attribute(struct wlp *wlp, u16 type_code,
+ struct wlp_attr_hdr *attr_hdr, void *value, ssize_t value_len,
+ ssize_t buflen)
+{
+ struct device *dev = &wlp->rc->uwb_dev.dev;
+ ssize_t attr_len = sizeof(*attr_hdr) + value_len;
+ if (buflen < 0)
+ return -EINVAL;
+ if (buflen < attr_len) {
+ dev_err(dev, "WLP: Not enough space in buffer to parse"
+ " attribute field. Need %d, received %zu\n",
+ (int)attr_len, buflen);
+ return -EIO;
+ }
+ if (wlp_check_attr_hdr(wlp, attr_hdr, type_code, value_len) < 0) {
+ dev_err(dev, "WLP: Header verification failed. \n");
+ return -EINVAL;
+ }
+ memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), value_len);
+ return attr_len;
+}
+
+static ssize_t wlp_vget_attribute(struct wlp *wlp, u16 type_code,
+ struct wlp_attr_hdr *attr_hdr, void *value, ssize_t max_value_len,
+ ssize_t buflen)
+{
+ struct device *dev = &wlp->rc->uwb_dev.dev;
+ size_t len;
+ if (buflen < 0)
+ return -EINVAL;
+ if (buflen < sizeof(*attr_hdr)) {
+ dev_err(dev, "WLP: Not enough space in buffer to parse"
+ " header.\n");
+ return -EIO;
+ }
+ if (le16_to_cpu(attr_hdr->type) != type_code) {
+ dev_err(dev, "WLP: Unexpected attribute type. Got %u, "
+ "expected %u.\n", le16_to_cpu(attr_hdr->type),
+ type_code);
+ return -EINVAL;
+ }
+ len = le16_to_cpu(attr_hdr->length);
+ if (len > max_value_len) {
+ dev_err(dev, "WLP: Attribute larger than maximum "
+ "allowed. Received %zu, max is %d.\n", len,
+ (int)max_value_len);
+ return -EFBIG;
+ }
+ if (buflen < sizeof(*attr_hdr) + len) {
+ dev_err(dev, "WLP: Not enough space in buffer to parse "
+ "variable data.\n");
+ return -EIO;
+ }
+ memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), len);
+ return sizeof(*attr_hdr) + len;
+}
+
/**
* Get value of attribute from fixed size attribute field.
*
@@ -274,22 +332,8 @@ out:
ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr, \
type *value, ssize_t buflen) \
{ \
- struct device *dev = &wlp->rc->uwb_dev.dev; \
- if (buflen < 0) \
- return -EINVAL; \
- if (buflen < sizeof(*attr)) { \
- dev_err(dev, "WLP: Not enough space in buffer to parse" \
- " attribute field. Need %d, received %zu\n", \
- (int)sizeof(*attr), buflen); \
- return -EIO; \
- } \
- if (wlp_check_attr_hdr(wlp, &attr->hdr, type_code, \
- sizeof(attr->name)) < 0) { \
- dev_err(dev, "WLP: Header verification failed. \n"); \
- return -EINVAL; \
- } \
- *value = attr->name; \
- return sizeof(*attr); \
+ return wlp_get_attribute(wlp, (type_code), &attr->hdr, \
+ value, sizeof(*value), buflen); \
}
#define wlp_get_sparse(type, type_code, name) \
@@ -313,35 +357,8 @@ static ssize_t wlp_get_##name(struct wlp *wlp, \
struct wlp_attr_##name *attr, \
type_val *value, ssize_t buflen) \
{ \
- struct device *dev = &wlp->rc->uwb_dev.dev; \
- size_t len; \
- if (buflen < 0) \
- return -EINVAL; \
- if (buflen < sizeof(*attr)) { \
- dev_err(dev, "WLP: Not enough space in buffer to parse" \
- " header.\n"); \
- return -EIO; \
- } \
- if (le16_to_cpu(attr->hdr.type) != type_code) { \
- dev_err(dev, "WLP: Unexpected attribute type. Got %u, " \
- "expected %u.\n", le16_to_cpu(attr->hdr.type), \
- type_code); \
- return -EINVAL; \
- } \
- len = le16_to_cpu(attr->hdr.length); \
- if (len > max) { \
- dev_err(dev, "WLP: Attribute larger than maximum " \
- "allowed. Received %zu, max is %d.\n", len, \
- (int)max); \
- return -EFBIG; \
- } \
- if (buflen < sizeof(*attr) + len) { \
- dev_err(dev, "WLP: Not enough space in buffer to parse "\
- "variable data.\n"); \
- return -EIO; \
- } \
- memcpy(value, (void *) attr + sizeof(*attr), len); \
- return sizeof(*attr) + len; \
+ return wlp_vget_attribute(wlp, (type_code), &attr->hdr, \
+ value, (max), buflen); \
}
wlp_get(u8, WLP_ATTR_WLP_VER, version)
diff --git a/drivers/uwb/wlp/sysfs.c b/drivers/uwb/wlp/sysfs.c
index 0370399ff4b..6627c94cc85 100644
--- a/drivers/uwb/wlp/sysfs.c
+++ b/drivers/uwb/wlp/sysfs.c
@@ -615,8 +615,7 @@ ssize_t wlp_wss_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static
-struct sysfs_ops wss_sysfs_ops = {
+static const struct sysfs_ops wss_sysfs_ops = {
.show = wlp_wss_attr_show,
.store = wlp_wss_attr_store,
};
diff --git a/drivers/uwb/wlp/txrx.c b/drivers/uwb/wlp/txrx.c
index 7350ed6909f..05dde44b359 100644
--- a/drivers/uwb/wlp/txrx.c
+++ b/drivers/uwb/wlp/txrx.c
@@ -25,6 +25,7 @@
*/
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <linux/wlp.h>
#include "wlp-internal.h"
diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c
index 13db739c4e3..7f6a630bf26 100644
--- a/drivers/uwb/wlp/wlp-lc.c
+++ b/drivers/uwb/wlp/wlp-lc.c
@@ -22,6 +22,7 @@
* FIXME: docs
*/
#include <linux/wlp.h>
+#include <linux/slab.h>
#include "wlp-internal.h"
diff --git a/drivers/uwb/wlp/wss-lc.c b/drivers/uwb/wlp/wss-lc.c
index 5913c7a5d92..90accdd54c0 100644
--- a/drivers/uwb/wlp/wss-lc.c
+++ b/drivers/uwb/wlp/wss-lc.c
@@ -45,6 +45,7 @@
*/
#include <linux/etherdevice.h> /* for is_valid_ether_addr */
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/wlp.h>
#include "wlp-internal.h"
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index ad37da2b6cb..9777583218f 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -17,6 +17,7 @@
#include <linux/workqueue.h>
#include <linux/rcupdate.h>
#include <linux/file.h>
+#include <linux/slab.h>
#include <linux/net.h>
#include <linux/if_packet.h>
@@ -125,7 +126,7 @@ static void handle_tx(struct vhost_net *net)
mutex_lock(&vq->mutex);
vhost_disable_notify(vq);
- if (wmem < sock->sk->sk_sndbuf * 2)
+ if (wmem < sock->sk->sk_sndbuf / 2)
tx_poll_stop(net);
hdr_size = vq->hdr_size;
@@ -508,12 +509,12 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
/* Verify that ring has been setup correctly. */
if (!vhost_vq_access_ok(vq)) {
r = -EFAULT;
- goto err;
+ goto err_vq;
}
sock = get_socket(fd);
if (IS_ERR(sock)) {
r = PTR_ERR(sock);
- goto err;
+ goto err_vq;
}
/* start polling new socket */
@@ -524,12 +525,14 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
vhost_net_disable_vq(n, vq);
rcu_assign_pointer(vq->private_data, sock);
vhost_net_enable_vq(n, vq);
- mutex_unlock(&vq->mutex);
done:
if (oldsock) {
vhost_net_flush_vq(n, index);
fput(oldsock->file);
}
+
+err_vq:
+ mutex_unlock(&vq->mutex);
err:
mutex_unlock(&n->dev.mutex);
return r;
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 7cd55e07879..e69d238c5af 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -22,6 +22,7 @@
#include <linux/poll.h>
#include <linux/file.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <linux/net.h>
#include <linux/if_packet.h>
@@ -235,6 +236,10 @@ static int vq_memory_access_ok(void __user *log_base, struct vhost_memory *mem,
int log_all)
{
int i;
+
+ if (!mem)
+ return 0;
+
for (i = 0; i < mem->nregions; ++i) {
struct vhost_memory_region *m = mem->regions + i;
unsigned long a = m->userspace_addr;
@@ -476,8 +481,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
if (r < 0)
break;
eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
- if (IS_ERR(eventfp))
- return PTR_ERR(eventfp);
+ if (IS_ERR(eventfp)) {
+ r = PTR_ERR(eventfp);
+ break;
+ }
if (eventfp != vq->kick) {
pollstop = filep = vq->kick;
pollstart = vq->kick = eventfp;
@@ -489,8 +496,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
if (r < 0)
break;
eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
- if (IS_ERR(eventfp))
- return PTR_ERR(eventfp);
+ if (IS_ERR(eventfp)) {
+ r = PTR_ERR(eventfp);
+ break;
+ }
if (eventfp != vq->call) {
filep = vq->call;
ctx = vq->call_ctx;
@@ -505,8 +514,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
if (r < 0)
break;
eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
- if (IS_ERR(eventfp))
- return PTR_ERR(eventfp);
+ if (IS_ERR(eventfp)) {
+ r = PTR_ERR(eventfp);
+ break;
+ }
if (eventfp != vq->error) {
filep = vq->error;
vq->error = eventfp;
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 0b17824b0eb..75a39eab70c 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -32,7 +32,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -308,7 +307,7 @@ static int mc68x328fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* Pseudocolor:
* uses offset = 0 && length = RAMDAC register width.
* var->{color}.offset is 0
- * var->{color}.length contains widht of DAC
+ * var->{color}.length contains width of DAC
* cmap is not used
* RAMDAC[X] is programmed to (red, green, blue)
* Truecolor:
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5a5c303a637..6e16244f3ed 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -400,9 +400,12 @@ config FB_SA1100
If you plan to use the LCD display with your SA-1100 system, say
Y here.
+config HAVE_FB_IMX
+ bool
+
config FB_IMX
tristate "Motorola i.MX LCD support"
- depends on FB && (ARCH_MX1 || ARCH_MX2)
+ depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -909,6 +912,18 @@ config FB_XVR2500
mostly initialized the card already. It is treated as a
completely dumb framebuffer device.
+config FB_XVR1000
+ bool "Sun XVR-1000 support"
+ depends on (FB = y) && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-1000 and similar
+ graphics cards. The driver only works on sparc64 systems where
+ the system firmware has mostly initialized the card already. It
+ is treated as a completely dumb framebuffer device.
+
config FB_PVR2
tristate "NEC PowerVR 2 display support"
depends on FB && SH_DREAMCAST
@@ -1494,7 +1509,6 @@ config FB_VIA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
select I2C_ALGOBIT
select I2C
help
@@ -1867,7 +1881,7 @@ config FB_W100
config FB_SH_MOBILE_LCDC
tristate "SuperH Mobile LCDC framebuffer support"
- depends on FB && SUPERH && HAVE_CLK
+ depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
@@ -1945,6 +1959,27 @@ config FB_S3C2410_DEBUG
Turn on debugging messages. Note that you can set/unset at run time
through sysfs
+config FB_NUC900
+ bool "NUC900 LCD framebuffer support"
+ depends on FB && ARCH_W90X900
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Nuvoton
+ NUC900 processor
+
+config GPM1040A0_320X240
+ bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
+ depends on FB_NUC900
+
+config FB_NUC900_DEBUG
+ bool "NUC900 lcd debug messages"
+ depends on FB_NUC900
+ help
+ Turn on debugging messages. Note that you can set/unset at run time
+ through sysfs
+
config FB_SM501
tristate "Silicon Motion SM501 framebuffer support"
depends on FB && MFD_SM501
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 4ecb30c4f3f..ddc2af2ba45 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -79,6 +79,7 @@ obj-$(CONFIG_FB_N411) += n411.o
obj-$(CONFIG_FB_HGA) += hgafb.o
obj-$(CONFIG_FB_XVR500) += sunxvr500.o
obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
+obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o
obj-$(CONFIG_FB_IGA) += igafb.o
obj-$(CONFIG_FB_APOLLO) += dnfb.o
obj-$(CONFIG_FB_Q40) += q40fb.o
@@ -129,6 +130,7 @@ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
obj-$(CONFIG_FB_CARMINE) += carminefb.o
obj-$(CONFIG_FB_MB862XX) += mb862xx/
obj-$(CONFIG_FB_MSM) += msm/
+obj-$(CONFIG_FB_NUC900) += nuc900fb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_UVESA) += uvesafb.o
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 0bcc59eb37f..82acb8dc4aa 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -22,13 +22,13 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/ctype.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -1221,7 +1221,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
printk("acornfb: freed %dK memory\n", mb_freed);
}
-static int __init acornfb_probe(struct platform_device *dev)
+static int __devinit acornfb_probe(struct platform_device *dev)
{
unsigned long size;
u_int h_sync, v_sync;
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index a21efcd10b7..afe21e6eb54 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -65,16 +65,16 @@ static void clcdfb_disable(struct clcd_fb *fb)
if (fb->board->disable)
fb->board->disable(fb);
- val = readl(fb->regs + CLCD_CNTL);
+ val = readl(fb->regs + fb->off_cntl);
if (val & CNTL_LCDPWR) {
val &= ~CNTL_LCDPWR;
- writel(val, fb->regs + CLCD_CNTL);
+ writel(val, fb->regs + fb->off_cntl);
clcdfb_sleep(20);
}
if (val & CNTL_LCDEN) {
val &= ~CNTL_LCDEN;
- writel(val, fb->regs + CLCD_CNTL);
+ writel(val, fb->regs + fb->off_cntl);
}
/*
@@ -94,7 +94,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
* Bring up by first enabling..
*/
cntl |= CNTL_LCDEN;
- writel(cntl, fb->regs + CLCD_CNTL);
+ writel(cntl, fb->regs + fb->off_cntl);
clcdfb_sleep(20);
@@ -102,7 +102,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
* and now apply power.
*/
cntl |= CNTL_LCDPWR;
- writel(cntl, fb->regs + CLCD_CNTL);
+ writel(cntl, fb->regs + fb->off_cntl);
/*
* finally, enable the interface.
@@ -233,7 +233,7 @@ static int clcdfb_set_par(struct fb_info *info)
readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1),
readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3),
readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS),
- readl(fb->regs + CLCD_IENB), readl(fb->regs + CLCD_CNTL));
+ readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl));
#endif
return 0;
@@ -345,6 +345,23 @@ static int clcdfb_register(struct clcd_fb *fb)
{
int ret;
+ /*
+ * ARM PL111 always has IENB at 0x1c; it's only PL110
+ * which is reversed on some platforms.
+ */
+ if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) {
+ fb->off_ienb = CLCD_PL111_IENB;
+ fb->off_cntl = CLCD_PL111_CNTL;
+ } else {
+#ifdef CONFIG_ARCH_VERSATILE
+ fb->off_ienb = CLCD_PL111_IENB;
+ fb->off_cntl = CLCD_PL111_CNTL;
+#else
+ fb->off_ienb = CLCD_PL110_IENB;
+ fb->off_cntl = CLCD_PL110_CNTL;
+#endif
+ }
+
fb->clk = clk_get(&fb->dev->dev, NULL);
if (IS_ERR(fb->clk)) {
ret = PTR_ERR(fb->clk);
@@ -416,7 +433,7 @@ static int clcdfb_register(struct clcd_fb *fb)
/*
* Ensure interrupts are disabled.
*/
- writel(0, fb->regs + CLCD_IENB);
+ writel(0, fb->regs + fb->off_ienb);
fb_set_var(&fb->fb, &fb->fb.var);
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 82bedd7f778..dca48df9844 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -45,7 +45,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index c3431691c9f..8d406fb689c 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -39,7 +39,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -504,7 +503,7 @@ static struct fb_ops arcfb_ops = {
.fb_ioctl = arcfb_ioctl,
};
-static int __init arcfb_probe(struct platform_device *dev)
+static int __devinit arcfb_probe(struct platform_device *dev)
{
struct fb_info *info;
int retval = -ENOMEM;
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index 9fe90ce928f..8cdf88e20b4 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -34,7 +34,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -140,7 +139,7 @@ static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dc
/* 3 <= m <= 257 */
if (m >= 3 && m <= 257) {
- unsigned new_error = ((Ftarget * n) - (Fref * m)) >= 0 ?
+ unsigned new_error = Ftarget * n >= Fref * m ?
((Ftarget * n) - (Fref * m)) : ((Fref * m) - (Ftarget * n));
if (new_error < best_error) {
best_n = n;
@@ -152,7 +151,7 @@ static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dc
else if (m <= 1028) {
/* remember there are still only 8-bits of precision in m, so
* avoid over-optimistic error calculations */
- unsigned new_error = ((Ftarget * n) - (Fref * (m & ~3))) >= 0 ?
+ unsigned new_error = Ftarget * n >= Fref * (m & ~3) ?
((Ftarget * n) - (Fref * (m & ~3))) : ((Fref * (m & ~3)) - (Ftarget * n));
if (new_error < best_error) {
best_n = n;
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index b7687c55fe1..f3aada20fa0 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -52,7 +52,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 3d886c6902f..8dce2512633 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/backlight.h>
+#include <linux/gfp.h>
#include <mach/board.h>
#include <mach/cpu.h>
@@ -117,6 +118,7 @@ static struct backlight_ops atmel_lcdc_bl_ops = {
static void init_backlight(struct atmel_lcdfb_info *sinfo)
{
+ struct backlight_properties props;
struct backlight_device *bl;
sinfo->bl_power = FB_BLANK_UNBLANK;
@@ -124,8 +126,10 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
if (sinfo->backlight)
return;
- bl = backlight_device_register("backlight", &sinfo->pdev->dev,
- sinfo, &atmel_lcdc_bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 0xff;
+ bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo,
+ &atmel_lcdc_bl_ops, &props);
if (IS_ERR(bl)) {
dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n",
PTR_ERR(bl));
@@ -135,7 +139,6 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
bl->props.power = FB_BLANK_UNBLANK;
bl->props.fb_blank = FB_BLANK_UNBLANK;
- bl->props.max_brightness = 0xff;
bl->props.brightness = atmel_bl_get_brightness(bl);
}
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 9ee67d6da71..34a0851bcbf 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -52,7 +52,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -1802,6 +1801,7 @@ static void aty128_bl_set_power(struct fb_info *info, int power)
static void aty128_bl_init(struct aty128fb_par *par)
{
+ struct backlight_properties props;
struct fb_info *info = pci_get_drvdata(par->pdev);
struct backlight_device *bd;
char name[12];
@@ -1817,7 +1817,10 @@ static void aty128_bl_init(struct aty128fb_par *par)
snprintf(name, sizeof(name), "aty128bl%d", info->node);
- bd = backlight_device_register(name, info->dev, par, &aty128_bl_data);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+ bd = backlight_device_register(name, info->dev, par, &aty128_bl_data,
+ &props);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
printk(KERN_WARNING "aty128: Backlight registration failed\n");
@@ -1829,7 +1832,6 @@ static void aty128_bl_init(struct aty128fb_par *par)
63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
- bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
bd->props.brightness = bd->props.max_brightness;
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index e45ab8db2dd..29d72851f85 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2232,6 +2232,7 @@ static struct backlight_ops aty_bl_data = {
static void aty_bl_init(struct atyfb_par *par)
{
+ struct backlight_properties props;
struct fb_info *info = pci_get_drvdata(par->pdev);
struct backlight_device *bd;
char name[12];
@@ -2243,7 +2244,10 @@ static void aty_bl_init(struct atyfb_par *par)
snprintf(name, sizeof(name), "atybl%d", info->node);
- bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+ bd = backlight_device_register(name, info->dev, par, &aty_bl_data,
+ &props);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
printk(KERN_WARNING "aty: Backlight registration failed\n");
@@ -2255,7 +2259,6 @@ static void aty_bl_init(struct atyfb_par *par)
0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
- bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
bd->props.brightness = bd->props.max_brightness;
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index 04c710804bb..2ba8b3c421a 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -2,7 +2,6 @@
* ATI Mach64 CT/VT/GT/LT Cursor Support
*/
-#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/string.h>
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index fa1198c4ccc..256966e9667 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -12,6 +12,7 @@
#include "radeonfb.h"
#include <linux/backlight.h>
+#include <linux/slab.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
@@ -134,6 +135,7 @@ static struct backlight_ops radeon_bl_data = {
void radeonfb_bl_init(struct radeonfb_info *rinfo)
{
+ struct backlight_properties props;
struct backlight_device *bd;
struct radeon_bl_privdata *pdata;
char name[12];
@@ -155,7 +157,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
- bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+ bd = backlight_device_register(name, rinfo->info->dev, pdata,
+ &radeon_bl_data, &props);
if (IS_ERR(bd)) {
rinfo->info->bl_dev = NULL;
printk("radeonfb: Backlight registration failed\n");
@@ -185,7 +190,6 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
- bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
bd->props.brightness = bd->props.max_brightness;
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index b4d4b88afc0..9261c918fde 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -1,4 +1,7 @@
#include "radeonfb.h"
+
+#include <linux/slab.h>
+
#include "../edid.h"
static struct fb_var_screeninfo radeonfb_default_var = {
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index a699aab6382..40f61320ce1 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -52,6 +52,7 @@
#include <linux/ctype.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/mach-au1x00/au1000.h>
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 0d96f1d2d4c..e77e8e4280f 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -41,6 +41,7 @@
#include <linux/interrupt.h>
#include <linux/ctype.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <asm/mach-au1x00/au1000.h>
#include "au1200fb.h"
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
new file mode 100644
index 00000000000..68d2518fada
--- /dev/null
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -0,0 +1,307 @@
+/*
+ * Backlight driver for Marvell Semiconductor 88PM8606
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
+
+#define MAX_BRIGHTNESS (0xFF)
+#define MIN_BRIGHTNESS (0)
+
+#define CURRENT_MASK (0x1F << 1)
+
+struct pm860x_backlight_data {
+ struct pm860x_chip *chip;
+ struct i2c_client *i2c;
+ int current_brightness;
+ int port;
+ int pwm;
+ int iset;
+};
+
+static inline int wled_a(int port)
+{
+ int ret;
+
+ ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
+ return ret;
+}
+
+static inline int wled_b(int port)
+{
+ int ret;
+
+ ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
+ return ret;
+}
+
+/* WLED2 & WLED3 share the same IDC */
+static inline int wled_idc(int port)
+{
+ int ret;
+
+ switch (port) {
+ case PM8606_BACKLIGHT1:
+ case PM8606_BACKLIGHT2:
+ ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
+ break;
+ case PM8606_BACKLIGHT3:
+ default:
+ ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
+ break;
+ }
+ return ret;
+}
+
+static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
+{
+ struct pm860x_backlight_data *data = bl_get_data(bl);
+ struct pm860x_chip *chip = data->chip;
+ unsigned char value;
+ int ret;
+
+ if (brightness > MAX_BRIGHTNESS)
+ value = MAX_BRIGHTNESS;
+ else
+ value = brightness;
+
+ ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
+ if (ret < 0)
+ goto out;
+
+ if ((data->current_brightness == 0) && brightness) {
+ if (data->iset) {
+ ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
+ CURRENT_MASK, data->iset);
+ if (ret < 0)
+ goto out;
+ }
+ if (data->pwm) {
+ ret = pm860x_set_bits(data->i2c, PM8606_PWM,
+ PM8606_PWM_FREQ_MASK, data->pwm);
+ if (ret < 0)
+ goto out;
+ }
+ if (brightness == MAX_BRIGHTNESS) {
+ /* set WLED_ON bit as 100% */
+ ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ PM8606_WLED_ON, PM8606_WLED_ON);
+ }
+ } else {
+ if (brightness == MAX_BRIGHTNESS) {
+ /* set WLED_ON bit as 100% */
+ ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ PM8606_WLED_ON, PM8606_WLED_ON);
+ } else {
+ /* clear WLED_ON bit since it's not 100% */
+ ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ PM8606_WLED_ON, 0);
+ }
+ }
+ if (ret < 0)
+ goto out;
+
+ dev_dbg(chip->dev, "set brightness %d\n", value);
+ data->current_brightness = value;
+ return 0;
+out:
+ dev_dbg(chip->dev, "set brightness %d failure with return "
+ "value:%d\n", value, ret);
+ return ret;
+}
+
+static int pm860x_backlight_update_status(struct backlight_device *bl)
+{
+ int brightness = bl->props.brightness;
+
+ if (bl->props.power != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ return pm860x_backlight_set(bl, brightness);
+}
+
+static int pm860x_backlight_get_brightness(struct backlight_device *bl)
+{
+ struct pm860x_backlight_data *data = bl_get_data(bl);
+ struct pm860x_chip *chip = data->chip;
+ int ret;
+
+ ret = pm860x_reg_read(data->i2c, wled_a(data->port));
+ if (ret < 0)
+ goto out;
+ data->current_brightness = ret;
+ dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
+ return data->current_brightness;
+out:
+ return -EINVAL;
+}
+
+static struct backlight_ops pm860x_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = pm860x_backlight_update_status,
+ .get_brightness = pm860x_backlight_get_brightness,
+};
+
+static int __check_device(struct pm860x_backlight_pdata *pdata, char *name)
+{
+ struct pm860x_backlight_pdata *p = pdata;
+ int ret = -EINVAL;
+
+ while (p && p->id) {
+ if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0))
+ break;
+
+ if (!strncmp(name, pm860x_backlight_name[p->flags],
+ MFD_NAME_SIZE)) {
+ ret = (int)p->flags;
+ break;
+ }
+ p++;
+ }
+ return ret;
+}
+
+static int pm860x_backlight_probe(struct platform_device *pdev)
+{
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pm860x_platform_data *pm860x_pdata;
+ struct pm860x_backlight_pdata *pdata = NULL;
+ struct pm860x_backlight_data *data;
+ struct backlight_device *bl;
+ struct resource *res;
+ struct backlight_properties props;
+ unsigned char value;
+ char name[MFD_NAME_SIZE];
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "No I/O resource!\n");
+ return -EINVAL;
+ }
+
+ if (pdev->dev.parent->platform_data) {
+ pm860x_pdata = pdev->dev.parent->platform_data;
+ pdata = pm860x_pdata->backlight;
+ }
+ if (pdata == NULL) {
+ dev_err(&pdev->dev, "platform data isn't assigned to "
+ "backlight\n");
+ return -EINVAL;
+ }
+
+ data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+ strncpy(name, res->name, MFD_NAME_SIZE);
+ data->chip = chip;
+ data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
+ : chip->companion;
+ data->current_brightness = MAX_BRIGHTNESS;
+ data->pwm = pdata->pwm;
+ data->iset = pdata->iset;
+ data->port = __check_device(pdata, name);
+ if (data->port < 0) {
+ dev_err(&pdev->dev, "wrong platform data is assigned");
+ return -EINVAL;
+ }
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = MAX_BRIGHTNESS;
+ bl = backlight_device_register(name, &pdev->dev, data,
+ &pm860x_backlight_ops, &props);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "failed to register backlight\n");
+ kfree(data);
+ return PTR_ERR(bl);
+ }
+ bl->props.brightness = MAX_BRIGHTNESS;
+
+ platform_set_drvdata(pdev, bl);
+
+ /* Enable reference VSYS */
+ ret = pm860x_reg_read(data->i2c, PM8606_VSYS);
+ if (ret < 0)
+ goto out;
+ if ((ret & PM8606_VSYS_EN) == 0) {
+ value = ret | PM8606_VSYS_EN;
+ ret = pm860x_reg_write(data->i2c, PM8606_VSYS, value);
+ if (ret < 0)
+ goto out;
+ }
+ /* Enable reference OSC */
+ ret = pm860x_reg_read(data->i2c, PM8606_MISC);
+ if (ret < 0)
+ goto out;
+ if ((ret & PM8606_MISC_OSC_EN) == 0) {
+ value = ret | PM8606_MISC_OSC_EN;
+ ret = pm860x_reg_write(data->i2c, PM8606_MISC, value);
+ if (ret < 0)
+ goto out;
+ }
+ /* read current backlight */
+ ret = pm860x_backlight_get_brightness(bl);
+ if (ret < 0)
+ goto out;
+
+ backlight_update_status(bl);
+ return 0;
+out:
+ kfree(data);
+ return ret;
+}
+
+static int pm860x_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct pm860x_backlight_data *data = bl_get_data(bl);
+
+ backlight_device_unregister(bl);
+ kfree(data);
+ return 0;
+}
+
+static struct platform_driver pm860x_backlight_driver = {
+ .driver = {
+ .name = "88pm860x-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = pm860x_backlight_probe,
+ .remove = pm860x_backlight_remove,
+};
+
+static int __init pm860x_backlight_init(void)
+{
+ return platform_driver_register(&pm860x_backlight_driver);
+}
+module_init(pm860x_backlight_init);
+
+static void __exit pm860x_backlight_exit(void)
+{
+ platform_driver_unregister(&pm860x_backlight_driver);
+}
+module_exit(pm860x_backlight_exit);
+
+MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:88pm860x-backlight");
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 09bfa9662e4..c025c84601b 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -31,6 +31,13 @@ config LCD_CORGI
Say y here to support the LCD panels usually found on SHARP
corgi (C7x0) and spitz (Cxx00) models.
+config LCD_L4F00242T03
+ tristate "Epson L4F00242T03 LCD"
+ depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
+ help
+ SPI driver for Epson L4F00242T03. This provides basic support
+ for init and powering the LCD up/down through a sysfs interface.
+
config LCD_LMS283GF05
tristate "Samsung LMS283GF05 LCD"
depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
@@ -212,6 +219,13 @@ config BACKLIGHT_DA903X
If you have a LCD backlight connected to the WLED output of DA9030
or DA9034 WLED output, say Y here to enable this driver.
+config BACKLIGHT_MAX8925
+ tristate "Backlight driver for MAX8925"
+ depends on BACKLIGHT_CLASS_DEVICE && MFD_MAX8925
+ help
+ If you have a LCD backlight connected to the WLED output of MAX8925
+ WLED output, say Y here to enable this driver.
+
config BACKLIGHT_MBP_NVIDIA
tristate "MacBook Pro Nvidia Backlight Driver"
depends on BACKLIGHT_CLASS_DEVICE && X86
@@ -262,3 +276,9 @@ config BACKLIGHT_ADP5520
To compile this driver as a module, choose M here: the module will
be called adp5520_bl.
+config BACKLIGHT_88PM860X
+ tristate "Backlight Driver for 88PM8606 using WLED"
+ depends on BACKLIGHT_CLASS_DEVICE && MFD_88PM860X
+ help
+ Say Y to enable the backlight driver for Marvell 88PM8606.
+
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 9a405548874..09d1f14d625 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -3,6 +3,7 @@
obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
+obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
obj-$(CONFIG_LCD_ILI9320) += ili9320.o
@@ -22,10 +23,12 @@ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
+obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o
obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
+obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index 86d95c228ad..9f436e014f8 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -12,6 +12,7 @@
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
struct adp5520_bl {
struct device *master;
@@ -278,6 +279,7 @@ static const struct attribute_group adp5520_bl_attr_group = {
static int __devinit adp5520_bl_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct backlight_device *bl;
struct adp5520_bl *data;
int ret = 0;
@@ -300,17 +302,17 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
mutex_init(&data->lock);
- bl = backlight_device_register(pdev->name, data->master,
- data, &adp5520_bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = ADP5020_MAX_BRIGHTNESS;
+ bl = backlight_device_register(pdev->name, data->master, data,
+ &adp5520_bl_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
kfree(data);
return PTR_ERR(bl);
}
- bl->props.max_brightness =
- bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
-
+ bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
if (data->pdata->en_ambl_sens)
ret = sysfs_create_group(&bl->dev.kobj,
&adp5520_bl_attr_group);
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c
index d769b0bab21..7f4a7c30a98 100644
--- a/drivers/video/backlight/adx_bl.c
+++ b/drivers/video/backlight/adx_bl.c
@@ -12,6 +12,7 @@
#include <linux/backlight.h>
#include <linux/fb.h>
+#include <linux/gfp.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -56,7 +57,7 @@ static int adx_backlight_get_brightness(struct backlight_device *bldev)
return brightness & 0xff;
}
-static int adx_backlight_check_fb(struct fb_info *fb)
+static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb)
{
return 1;
}
@@ -70,6 +71,7 @@ static const struct backlight_ops adx_backlight_ops = {
static int __devinit adx_backlight_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct backlight_device *bldev;
struct resource *res;
struct adxbl *bl;
@@ -101,14 +103,15 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev)
goto out;
}
- bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl,
- &adx_backlight_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 0xff;
+ bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
+ bl, &adx_backlight_ops, &props);
if (!bldev) {
ret = -ENOMEM;
goto out;
}
- bldev->props.max_brightness = 0xff;
bldev->props.brightness = 0xff;
bldev->props.power = FB_BLANK_UNBLANK;
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index f625ffc69ad..e6a66dab088 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -17,6 +17,7 @@
#include <linux/backlight.h>
#include <linux/atmel_pwm.h>
#include <linux/atmel-pwm-bl.h>
+#include <linux/slab.h>
struct atmel_pwm_bl {
const struct atmel_pwm_bl_platform_data *pdata;
@@ -120,6 +121,7 @@ static const struct backlight_ops atmel_pwm_bl_ops = {
static int atmel_pwm_bl_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
const struct atmel_pwm_bl_platform_data *pdata;
struct backlight_device *bldev;
struct atmel_pwm_bl *pwmbl;
@@ -165,8 +167,10 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
goto err_free_gpio;
}
- bldev = backlight_device_register("atmel-pwm-bl",
- &pdev->dev, pwmbl, &atmel_pwm_bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
+ bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl,
+ &atmel_pwm_bl_ops, &props);
if (IS_ERR(bldev)) {
retval = PTR_ERR(bldev);
goto err_free_gpio;
@@ -178,7 +182,6 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
/* Power up the backlight by default at middle intesity. */
bldev->props.power = FB_BLANK_UNBLANK;
- bldev->props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
bldev->props.brightness = bldev->props.max_brightness / 2;
retval = atmel_pwm_bl_init_pwm(pwmbl);
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 18829cf68b1..e207810bba3 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -13,6 +13,7 @@
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/fb.h>
+#include <linux/slab.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
@@ -38,7 +39,7 @@ static int fb_notifier_callback(struct notifier_block *self,
mutex_lock(&bd->ops_lock);
if (bd->ops)
if (!bd->ops->check_fb ||
- bd->ops->check_fb(evdata->info)) {
+ bd->ops->check_fb(bd, evdata->info)) {
bd->props.fb_blank = *(int *)evdata->data;
if (bd->props.fb_blank == FB_BLANK_UNBLANK)
bd->props.state &= ~BL_CORE_FBBLANK;
@@ -269,7 +270,8 @@ EXPORT_SYMBOL(backlight_force_update);
* ERR_PTR() or a pointer to the newly allocated device.
*/
struct backlight_device *backlight_device_register(const char *name,
- struct device *parent, void *devdata, const struct backlight_ops *ops)
+ struct device *parent, void *devdata, const struct backlight_ops *ops,
+ const struct backlight_properties *props)
{
struct backlight_device *new_bd;
int rc;
@@ -289,6 +291,11 @@ struct backlight_device *backlight_device_register(const char *name,
dev_set_name(&new_bd->dev, name);
dev_set_drvdata(&new_bd->dev, devdata);
+ /* Set default properties */
+ if (props)
+ memcpy(&new_bd->props, props,
+ sizeof(struct backlight_properties));
+
rc = device_register(&new_bd->dev);
if (rc) {
kfree(new_bd);
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index b4bcf804379..1e71c35083b 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -24,6 +24,7 @@
#include <linux/lcd.h>
#include <linux/spi/spi.h>
#include <linux/spi/corgi_lcd.h>
+#include <linux/slab.h>
#include <asm/mach/sharpsl_param.h>
#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
@@ -533,6 +534,7 @@ err_free_backlight_on:
static int __devinit corgi_lcd_probe(struct spi_device *spi)
{
+ struct backlight_properties props;
struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
struct corgi_lcd *lcd;
int ret = 0;
@@ -559,13 +561,14 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi)
lcd->power = FB_BLANK_POWERDOWN;
lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
- lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev,
- lcd, &corgi_bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = pdata->max_intensity;
+ lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd,
+ &corgi_bl_ops, &props);
if (IS_ERR(lcd->bl_dev)) {
ret = PTR_ERR(lcd->bl_dev);
goto err_unregister_lcd;
}
- lcd->bl_dev->props.max_brightness = pdata->max_intensity;
lcd->bl_dev->props.brightness = pdata->default_intensity;
lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index da86db4374a..a4f4546f0be 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -36,6 +36,7 @@
#include <linux/backlight.h>
#include <linux/lcd.h>
#include <linux/pci.h>
+#include <linux/slab.h>
/* The LVDS- and panel power controls sits on the
* GPIO port of the ISA bridge.
@@ -170,6 +171,7 @@ static struct lcd_ops cr_lcd_ops = {
static int cr_backlight_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct backlight_device *bdp;
struct lcd_device *ldp;
struct cr_panel *crp;
@@ -190,8 +192,9 @@ static int cr_backlight_probe(struct platform_device *pdev)
return -ENODEV;
}
- bdp = backlight_device_register("cr-backlight",
- &pdev->dev, NULL, &cr_backlight_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL,
+ &cr_backlight_ops, &props);
if (IS_ERR(bdp)) {
pci_dev_put(lpc_dev);
return PTR_ERR(bdp);
@@ -220,9 +223,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
crp->cr_lcd_device = ldp;
crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
crp->cr_backlight_device->props.brightness = 0;
- crp->cr_backlight_device->props.max_brightness = 0;
cr_backlight_set_intensity(crp->cr_backlight_device);
-
cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
platform_set_drvdata(pdev, crp);
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index 74cdc640173..87659ed79bd 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -18,6 +18,7 @@
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/mfd/da903x.h>
+#include <linux/slab.h>
#define DA9030_WLED_CONTROL 0x25
#define DA9030_WLED_CP_EN (1 << 6)
@@ -105,6 +106,7 @@ static int da903x_backlight_probe(struct platform_device *pdev)
struct da9034_backlight_pdata *pdata = pdev->dev.platform_data;
struct da903x_backlight_data *data;
struct backlight_device *bl;
+ struct backlight_properties props;
int max_brightness;
data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -134,15 +136,15 @@ static int da903x_backlight_probe(struct platform_device *pdev)
da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
DA9034_WLED_ISET(pdata->output_current));
- bl = backlight_device_register(pdev->name, data->da903x_dev,
- data, &da903x_backlight_ops);
+ props.max_brightness = max_brightness;
+ bl = backlight_device_register(pdev->name, data->da903x_dev, data,
+ &da903x_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
kfree(data);
return PTR_ERR(bl);
}
- bl->props.max_brightness = max_brightness;
bl->props.brightness = max_brightness;
platform_set_drvdata(pdev, bl);
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c
index e6d348e6359..312ca619735 100644
--- a/drivers/video/backlight/generic_bl.c
+++ b/drivers/video/backlight/generic_bl.c
@@ -78,6 +78,7 @@ static const struct backlight_ops genericbl_ops = {
static int genericbl_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct generic_bl_info *machinfo = pdev->dev.platform_data;
const char *name = "generic-bl";
struct backlight_device *bd;
@@ -89,14 +90,15 @@ static int genericbl_probe(struct platform_device *pdev)
if (machinfo->name)
name = machinfo->name;
- bd = backlight_device_register (name,
- &pdev->dev, NULL, &genericbl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = machinfo->max_intensity;
+ bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
+ &props);
if (IS_ERR (bd))
return PTR_ERR (bd);
platform_set_drvdata(pdev, bd);
- bd->props.max_brightness = machinfo->max_intensity;
bd->props.power = FB_BLANK_UNBLANK;
bd->props.brightness = machinfo->default_intensity;
backlight_update_status(bd);
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index f7cc528d5be..267d23f8d64 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -105,16 +105,18 @@ static const struct backlight_ops hp680bl_ops = {
static int __devinit hp680bl_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct backlight_device *bd;
- bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL,
- &hp680bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = HP680_MAX_INTENSITY;
+ bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
+ &hp680bl_ops, &props);
if (IS_ERR(bd))
return PTR_ERR(bd);
platform_set_drvdata(pdev, bd);
- bd->props.max_brightness = HP680_MAX_INTENSITY;
bd->props.brightness = HP680_DEFAULT_INTENSITY;
hp680bl_send_intensity(bd);
diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c
index ba89b41b639..5118a9f029a 100644
--- a/drivers/video/backlight/ili9320.c
+++ b/drivers/video/backlight/ili9320.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/lcd.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
index db9071fc566..2f177b3a488 100644
--- a/drivers/video/backlight/jornada720_bl.c
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -101,10 +101,14 @@ static const struct backlight_ops jornada_bl_ops = {
static int jornada_bl_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
int ret;
struct backlight_device *bd;
- bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = BL_MAX_BRIGHT;
+ bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
+ &jornada_bl_ops, &props);
if (IS_ERR(bd)) {
ret = PTR_ERR(bd);
@@ -117,7 +121,6 @@ static int jornada_bl_probe(struct platform_device *pdev)
/* note. make sure max brightness is set otherwise
you will get seemingly non-related errors when
trying to change brightness */
- bd->props.max_brightness = BL_MAX_BRIGHT;
jornada_bl_update_status(bd);
platform_set_drvdata(pdev, bd);
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
index 939e7b830cf..f439a863228 100644
--- a/drivers/video/backlight/kb3886_bl.c
+++ b/drivers/video/backlight/kb3886_bl.c
@@ -141,20 +141,24 @@ static const struct backlight_ops kb3886bl_ops = {
static int kb3886bl_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data;
bl_machinfo = machinfo;
if (!machinfo->limit_mask)
machinfo->limit_mask = -1;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = machinfo->max_intensity;
kb3886_backlight_device = backlight_device_register("kb3886-bl",
- &pdev->dev, NULL, &kb3886bl_ops);
+ &pdev->dev, NULL,
+ &kb3886bl_ops,
+ &props);
if (IS_ERR(kb3886_backlight_device))
return PTR_ERR(kb3886_backlight_device);
platform_set_drvdata(pdev, kb3886_backlight_device);
- kb3886_backlight_device->props.max_brightness = machinfo->max_intensity;
kb3886_backlight_device->props.power = FB_BLANK_UNBLANK;
kb3886_backlight_device->props.brightness = machinfo->default_intensity;
backlight_update_status(kb3886_backlight_device);
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
new file mode 100644
index 00000000000..bcdb12c93ef
--- /dev/null
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -0,0 +1,258 @@
+/*
+ * l4f00242t03.c -- support for Epson L4F00242T03 LCD
+ *
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Inspired by Marek Vasut work in l4f00242t03.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/device.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/l4f00242t03.h>
+
+struct l4f00242t03_priv {
+ struct spi_device *spi;
+ struct lcd_device *ld;
+ int lcd_on:1;
+ struct regulator *io_reg;
+ struct regulator *core_reg;
+};
+
+
+static void l4f00242t03_reset(unsigned int gpio)
+{
+ pr_debug("l4f00242t03_reset.\n");
+ gpio_set_value(gpio, 1);
+ mdelay(100);
+ gpio_set_value(gpio, 0);
+ mdelay(10); /* tRES >= 100us */
+ gpio_set_value(gpio, 1);
+ mdelay(20);
+}
+
+#define param(x) ((x) | 0x100)
+
+static void l4f00242t03_lcd_init(struct spi_device *spi)
+{
+ struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+ struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+ const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
+
+ dev_dbg(&spi->dev, "initializing LCD\n");
+
+ if (priv->io_reg) {
+ regulator_set_voltage(priv->io_reg, 1800000, 1800000);
+ regulator_enable(priv->io_reg);
+ }
+
+ if (priv->core_reg) {
+ regulator_set_voltage(priv->core_reg, 2800000, 2800000);
+ regulator_enable(priv->core_reg);
+ }
+
+ gpio_set_value(pdata->data_enable_gpio, 1);
+ msleep(60);
+ spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16));
+}
+
+static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power)
+{
+ struct l4f00242t03_priv *priv = lcd_get_data(ld);
+ struct spi_device *spi = priv->spi;
+
+ const u16 slpout = 0x11;
+ const u16 dison = 0x29;
+
+ const u16 slpin = 0x10;
+ const u16 disoff = 0x28;
+
+ if (power) {
+ if (priv->lcd_on)
+ return 0;
+
+ dev_dbg(&spi->dev, "turning on LCD\n");
+
+ spi_write(spi, (const u8 *)&slpout, sizeof(u16));
+ msleep(60);
+ spi_write(spi, (const u8 *)&dison, sizeof(u16));
+
+ priv->lcd_on = 1;
+ } else {
+ if (!priv->lcd_on)
+ return 0;
+
+ dev_dbg(&spi->dev, "turning off LCD\n");
+
+ spi_write(spi, (const u8 *)&disoff, sizeof(u16));
+ msleep(60);
+ spi_write(spi, (const u8 *)&slpin, sizeof(u16));
+
+ priv->lcd_on = 0;
+ }
+
+ return 0;
+}
+
+static struct lcd_ops l4f_ops = {
+ .set_power = l4f00242t03_lcd_power_set,
+ .get_power = NULL,
+};
+
+static int __devinit l4f00242t03_probe(struct spi_device *spi)
+{
+ struct l4f00242t03_priv *priv;
+ struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+ int ret;
+
+ if (pdata == NULL) {
+ dev_err(&spi->dev, "Uninitialized platform data.\n");
+ return -EINVAL;
+ }
+
+ priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL);
+
+ if (priv == NULL) {
+ dev_err(&spi->dev, "No memory for this device.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ dev_set_drvdata(&spi->dev, priv);
+ spi->bits_per_word = 9;
+ spi_setup(spi);
+
+ priv->spi = spi;
+
+ ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset");
+ if (ret) {
+ dev_err(&spi->dev,
+ "Unable to get the lcd l4f00242t03 reset gpio.\n");
+ return ret;
+ }
+
+ ret = gpio_direction_output(pdata->reset_gpio, 1);
+ if (ret)
+ goto err2;
+
+ ret = gpio_request(pdata->data_enable_gpio,
+ "lcd l4f00242t03 data enable");
+ if (ret) {
+ dev_err(&spi->dev,
+ "Unable to get the lcd l4f00242t03 data en gpio.\n");
+ return ret;
+ }
+
+ ret = gpio_direction_output(pdata->data_enable_gpio, 0);
+ if (ret)
+ goto err3;
+
+ if (pdata->io_supply) {
+ priv->io_reg = regulator_get(NULL, pdata->io_supply);
+
+ if (IS_ERR(priv->io_reg)) {
+ pr_err("%s: Unable to get the IO regulator\n",
+ __func__);
+ goto err3;
+ }
+ }
+
+ if (pdata->core_supply) {
+ priv->core_reg = regulator_get(NULL, pdata->core_supply);
+
+ if (IS_ERR(priv->core_reg)) {
+ pr_err("%s: Unable to get the core regulator\n",
+ __func__);
+ goto err4;
+ }
+ }
+
+ priv->ld = lcd_device_register("l4f00242t03",
+ &spi->dev, priv, &l4f_ops);
+ if (IS_ERR(priv->ld)) {
+ ret = PTR_ERR(priv->ld);
+ goto err5;
+ }
+
+ /* Init the LCD */
+ l4f00242t03_reset(pdata->reset_gpio);
+ l4f00242t03_lcd_init(spi);
+ l4f00242t03_lcd_power_set(priv->ld, 1);
+
+ dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n");
+
+ return 0;
+
+err5:
+ if (priv->core_reg)
+ regulator_put(priv->core_reg);
+err4:
+ if (priv->io_reg)
+ regulator_put(priv->io_reg);
+err3:
+ gpio_free(pdata->data_enable_gpio);
+err2:
+ gpio_free(pdata->reset_gpio);
+err:
+ kfree(priv);
+
+ return ret;
+}
+
+static int __devexit l4f00242t03_remove(struct spi_device *spi)
+{
+ struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+ struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data;
+
+ l4f00242t03_lcd_power_set(priv->ld, 0);
+ lcd_device_unregister(priv->ld);
+
+ gpio_free(pdata->data_enable_gpio);
+ gpio_free(pdata->reset_gpio);
+
+ if (priv->io_reg)
+ regulator_put(priv->core_reg);
+ if (priv->core_reg)
+ regulator_put(priv->io_reg);
+
+ kfree(priv);
+
+ return 0;
+}
+
+static struct spi_driver l4f00242t03_driver = {
+ .driver = {
+ .name = "l4f00242t03",
+ .owner = THIS_MODULE,
+ },
+ .probe = l4f00242t03_probe,
+ .remove = __devexit_p(l4f00242t03_remove),
+};
+
+static __init int l4f00242t03_init(void)
+{
+ return spi_register_driver(&l4f00242t03_driver);
+}
+
+static __exit void l4f00242t03_exit(void)
+{
+ spi_unregister_driver(&l4f00242t03_driver);
+}
+
+module_init(l4f00242t03_init);
+module_exit(l4f00242t03_exit);
+
+MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
+MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 9b3be74cee5..71a11cadffc 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -13,6 +13,7 @@
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/fb.h>
+#include <linux/slab.h>
#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
defined(CONFIG_LCD_CLASS_DEVICE_MODULE))
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c
index 447b542a20c..abc43a0eb97 100644
--- a/drivers/video/backlight/lms283gf05.c
+++ b/drivers/video/backlight/lms283gf05.c
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/lcd.h>
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 00a9591b000..7571bc26071 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -167,6 +167,7 @@ static int locomolcd_resume(struct locomo_dev *dev)
static int locomolcd_probe(struct locomo_dev *ldev)
{
+ struct backlight_properties props;
unsigned long flags;
local_irq_save(flags);
@@ -182,13 +183,16 @@ static int locomolcd_probe(struct locomo_dev *ldev)
local_irq_restore(flags);
- locomolcd_bl_device = backlight_device_register("locomo-bl", &ldev->dev, NULL, &locomobl_data);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 4;
+ locomolcd_bl_device = backlight_device_register("locomo-bl",
+ &ldev->dev, NULL,
+ &locomobl_data, &props);
if (IS_ERR (locomolcd_bl_device))
return PTR_ERR (locomolcd_bl_device);
/* Set up frontlight so that screen is readable */
- locomolcd_bl_device->props.max_brightness = 4,
locomolcd_bl_device->props.brightness = 2;
locomolcd_set_intensity(locomolcd_bl_device);
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index 4631ca8fa4a..8010aaeb5ad 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/lcd.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/spi/spi.h>
#include "ltv350qv.h"
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
new file mode 100644
index 00000000000..b5accc957ad
--- /dev/null
+++ b/drivers/video/backlight/max8925_bl.c
@@ -0,0 +1,203 @@
+/*
+ * Backlight driver for Maxim MAX8925
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/mfd/max8925.h>
+#include <linux/slab.h>
+
+#define MAX_BRIGHTNESS (0xff)
+#define MIN_BRIGHTNESS (0)
+
+#define LWX_FREQ(x) (((x - 601) / 100) & 0x7)
+
+struct max8925_backlight_data {
+ struct max8925_chip *chip;
+
+ int current_brightness;
+};
+
+static int max8925_backlight_set(struct backlight_device *bl, int brightness)
+{
+ struct max8925_backlight_data *data = bl_get_data(bl);
+ struct max8925_chip *chip = data->chip;
+ unsigned char value;
+ int ret;
+
+ if (brightness > MAX_BRIGHTNESS)
+ value = MAX_BRIGHTNESS;
+ else
+ value = brightness;
+
+ ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
+ if (ret < 0)
+ goto out;
+
+ if (!data->current_brightness && brightness)
+ /* enable WLED output */
+ ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
+ else if (!brightness)
+ /* disable WLED output */
+ ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
+ if (ret < 0)
+ goto out;
+ dev_dbg(chip->dev, "set brightness %d\n", value);
+ data->current_brightness = value;
+ return 0;
+out:
+ dev_dbg(chip->dev, "set brightness %d failure with return value:%d\n",
+ value, ret);
+ return ret;
+}
+
+static int max8925_backlight_update_status(struct backlight_device *bl)
+{
+ int brightness = bl->props.brightness;
+
+ if (bl->props.power != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ if (bl->props.fb_blank != FB_BLANK_UNBLANK)
+ brightness = 0;
+
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ return max8925_backlight_set(bl, brightness);
+}
+
+static int max8925_backlight_get_brightness(struct backlight_device *bl)
+{
+ struct max8925_backlight_data *data = bl_get_data(bl);
+ struct max8925_chip *chip = data->chip;
+ int ret;
+
+ ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
+ if (ret < 0)
+ return -EINVAL;
+ data->current_brightness = ret;
+ dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
+ return ret;
+}
+
+static struct backlight_ops max8925_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = max8925_backlight_update_status,
+ .get_brightness = max8925_backlight_get_brightness,
+};
+
+static int __devinit max8925_backlight_probe(struct platform_device *pdev)
+{
+ struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct max8925_platform_data *max8925_pdata;
+ struct max8925_backlight_pdata *pdata = NULL;
+ struct max8925_backlight_data *data;
+ struct backlight_device *bl;
+ struct backlight_properties props;
+ struct resource *res;
+ char name[MAX8925_NAME_SIZE];
+ unsigned char value;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "No I/O resource!\n");
+ return -EINVAL;
+ }
+
+ if (pdev->dev.parent->platform_data) {
+ max8925_pdata = pdev->dev.parent->platform_data;
+ pdata = max8925_pdata->backlight;
+ }
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "platform data isn't assigned to "
+ "backlight\n");
+ return -EINVAL;
+ }
+
+ data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+ strncpy(name, res->name, MAX8925_NAME_SIZE);
+ data->chip = chip;
+ data->current_brightness = 0;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = MAX_BRIGHTNESS;
+ bl = backlight_device_register(name, &pdev->dev, data,
+ &max8925_backlight_ops, &props);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "failed to register backlight\n");
+ kfree(data);
+ return PTR_ERR(bl);
+ }
+ bl->props.brightness = MAX_BRIGHTNESS;
+
+ platform_set_drvdata(pdev, bl);
+
+ value = 0;
+ if (pdata->lxw_scl)
+ value |= (1 << 7);
+ if (pdata->lxw_freq)
+ value |= (LWX_FREQ(pdata->lxw_freq) << 4);
+ if (pdata->dual_string)
+ value |= (1 << 1);
+ ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
+ if (ret < 0)
+ goto out;
+
+ backlight_update_status(bl);
+ return 0;
+out:
+ kfree(data);
+ return ret;
+}
+
+static int __devexit max8925_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct max8925_backlight_data *data = bl_get_data(bl);
+
+ backlight_device_unregister(bl);
+ kfree(data);
+ return 0;
+}
+
+static struct platform_driver max8925_backlight_driver = {
+ .driver = {
+ .name = "max8925-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8925_backlight_probe,
+ .remove = __devexit_p(max8925_backlight_remove),
+};
+
+static int __init max8925_backlight_init(void)
+{
+ return platform_driver_register(&max8925_backlight_driver);
+}
+module_init(max8925_backlight_init);
+
+static void __exit max8925_backlight_exit(void)
+{
+ platform_driver_unregister(&max8925_backlight_driver);
+};
+module_exit(max8925_backlight_exit);
+
+MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:max8925-backlight");
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 2e78b0784bd..1b5d3fe6bbb 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -139,6 +139,51 @@ static int mbp_dmi_match(const struct dmi_system_id *id)
static const struct dmi_system_id __initdata mbp_device_table[] = {
{
.callback = mbp_dmi_match,
+ .ident = "MacBook 1,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
+ },
+ .driver_data = (void *)&intel_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBook 2,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
+ },
+ .driver_data = (void *)&intel_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBook 3,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"),
+ },
+ .driver_data = (void *)&intel_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBook 4,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"),
+ },
+ .driver_data = (void *)&intel_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBook 4,2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"),
+ },
+ .driver_data = (void *)&intel_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
.ident = "MacBookPro 3,1",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
@@ -250,6 +295,7 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
static int __init mbp_init(void)
{
+ struct backlight_properties props;
if (!dmi_check_system(mbp_device_table))
return -ENODEV;
@@ -257,14 +303,17 @@ static int __init mbp_init(void)
"Macbook Pro backlight"))
return -ENXIO;
- mbp_backlight_device = backlight_device_register("mbp_backlight",
- NULL, NULL, &driver_data->backlight_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 15;
+ mbp_backlight_device = backlight_device_register("mbp_backlight", NULL,
+ NULL,
+ &driver_data->backlight_ops,
+ &props);
if (IS_ERR(mbp_backlight_device)) {
release_region(driver_data->iostart, driver_data->iolen);
return PTR_ERR(mbp_backlight_device);
}
- mbp_backlight_device->props.max_brightness = 15;
mbp_backlight_device->props.brightness =
driver_data->backlight_ops.get_brightness(mbp_backlight_device);
backlight_update_status(mbp_backlight_device);
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index a3a7f893817..d3bc56296c8 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/backlight.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <plat/board.h>
@@ -132,6 +133,7 @@ static const struct backlight_ops omapbl_ops = {
static int omapbl_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct backlight_device *dev;
struct omap_backlight *bl;
struct omap_backlight_config *pdata = pdev->dev.platform_data;
@@ -143,7 +145,10 @@ static int omapbl_probe(struct platform_device *pdev)
if (unlikely(!bl))
return -ENOMEM;
- dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = OMAPBL_MAX_INTENSITY;
+ dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
+ &props);
if (IS_ERR(dev)) {
kfree(bl);
return PTR_ERR(dev);
@@ -160,7 +165,6 @@ static int omapbl_probe(struct platform_device *pdev)
omap_cfg_reg(PWL); /* Conflicts with UART3 */
dev->props.fb_blank = FB_BLANK_UNBLANK;
- dev->props.max_brightness = OMAPBL_MAX_INTENSITY;
dev->props.brightness = pdata->default_intensity;
omapbl_update_status(dev);
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index 738694d2388..302330acf62 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -16,6 +16,7 @@
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/lcd.h>
+#include <linux/slab.h>
#include <video/platform_lcd.h>
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
index 075786e0503..809278c9073 100644
--- a/drivers/video/backlight/progear_bl.c
+++ b/drivers/video/backlight/progear_bl.c
@@ -61,8 +61,10 @@ static const struct backlight_ops progearbl_ops = {
static int progearbl_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
u8 temp;
struct backlight_device *progear_backlight_device;
+ int ret;
pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
if (!pmu_dev) {
@@ -73,28 +75,37 @@ static int progearbl_probe(struct platform_device *pdev)
sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
if (!sb_dev) {
printk("ALI 1533 SB not found.\n");
- pci_dev_put(pmu_dev);
- return -ENODEV;
+ ret = -ENODEV;
+ goto put_pmu;
}
/* Set SB_MPS1 to enable brightness control. */
pci_read_config_byte(sb_dev, SB_MPS1, &temp);
pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
progear_backlight_device = backlight_device_register("progear-bl",
&pdev->dev, NULL,
- &progearbl_ops);
- if (IS_ERR(progear_backlight_device))
- return PTR_ERR(progear_backlight_device);
+ &progearbl_ops,
+ &props);
+ if (IS_ERR(progear_backlight_device)) {
+ ret = PTR_ERR(progear_backlight_device);
+ goto put_sb;
+ }
platform_set_drvdata(pdev, progear_backlight_device);
progear_backlight_device->props.power = FB_BLANK_UNBLANK;
progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
- progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
progearbl_set_intensity(progear_backlight_device);
return 0;
+put_sb:
+ pci_dev_put(sb_dev);
+put_pmu:
+ pci_dev_put(pmu_dev);
+ return ret;
}
static int progearbl_remove(struct platform_device *pdev)
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 9d2ec2a1cce..55044351889 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -19,6 +19,7 @@
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
+#include <linux/slab.h>
struct pwm_bl_data {
struct pwm_device *pwm;
@@ -65,6 +66,7 @@ static const struct backlight_ops pwm_backlight_ops = {
static int pwm_backlight_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
struct backlight_device *bl;
struct pwm_bl_data *pb;
@@ -100,15 +102,16 @@ static int pwm_backlight_probe(struct platform_device *pdev)
} else
dev_dbg(&pdev->dev, "got pwm for backlight\n");
- bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
- pb, &pwm_backlight_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = data->max_brightness;
+ bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
+ &pwm_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
ret = PTR_ERR(bl);
goto err_bl;
}
- bl->props.max_brightness = data->max_brightness;
bl->props.brightness = data->dft_brightness;
backlight_update_status(bl);
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
index 4a3d46e0801..1997e12a105 100644
--- a/drivers/video/backlight/tdo24m.c
+++ b/drivers/video/backlight/tdo24m.c
@@ -17,6 +17,7 @@
#include <linux/spi/tdo24m.h>
#include <linux/fb.h>
#include <linux/lcd.h>
+#include <linux/slab.h>
#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index e14ce4d469f..e03e60bbfd8 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -18,6 +18,7 @@
#include <linux/gpio.h>
#include <linux/fb.h>
#include <linux/backlight.h>
+#include <linux/slab.h>
#include <asm/mach/sharpsl_param.h>
@@ -80,6 +81,7 @@ static const struct backlight_ops bl_ops = {
static int __devinit tosa_bl_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct backlight_properties props;
struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL);
int ret = 0;
if (!data)
@@ -99,15 +101,16 @@ static int __devinit tosa_bl_probe(struct i2c_client *client,
i2c_set_clientdata(client, data);
data->i2c = client;
- data->bl = backlight_device_register("tosa-bl", &client->dev,
- data, &bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 512 - 1;
+ data->bl = backlight_device_register("tosa-bl", &client->dev, data,
+ &bl_ops, &props);
if (IS_ERR(data->bl)) {
ret = PTR_ERR(data->bl);
goto err_reg;
}
data->bl->props.brightness = 69;
- data->bl->props.max_brightness = 512 - 1;
data->bl->props.power = FB_BLANK_UNBLANK;
backlight_update_status(data->bl);
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
index fa32b94a454..772f6015219 100644
--- a/drivers/video/backlight/tosa_lcd.c
+++ b/drivers/video/backlight/tosa_lcd.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/lcd.h>
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
index e32add37a20..08fd87f3aec 100644
--- a/drivers/video/backlight/wm831x_bl.c
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/backlight.h>
+#include <linux/slab.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/pdata.h>
@@ -125,6 +126,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
struct wm831x_backlight_pdata *pdata;
struct wm831x_backlight_data *data;
struct backlight_device *bl;
+ struct backlight_properties props;
int ret, i, max_isel, isink_reg, dcdc_cfg;
/* We need platform data */
@@ -191,15 +193,15 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
data->current_brightness = 0;
data->isink_reg = isink_reg;
- bl = backlight_device_register("wm831x", &pdev->dev,
- data, &wm831x_backlight_ops);
+ props.max_brightness = max_isel;
+ bl = backlight_device_register("wm831x", &pdev->dev, data,
+ &wm831x_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
kfree(data);
return PTR_ERR(bl);
}
- bl->props.max_brightness = max_isel;
bl->props.brightness = max_isel;
platform_set_drvdata(pdev, bl);
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index e49ae5edcc0..23b2a8c0dbf 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -82,7 +82,6 @@ struct bfin_bf54xfb_info {
unsigned char *fb_buffer; /* RGB Buffer */
dma_addr_t dma_handle;
- int lq043_mmap;
int lq043_open_cnt;
int irq;
spinlock_t lock; /* lock */
@@ -316,7 +315,6 @@ static int bfin_bf54x_fb_release(struct fb_info *info, int user)
spin_lock(&fbi->lock);
fbi->lq043_open_cnt--;
- fbi->lq043_mmap = 0;
if (fbi->lq043_open_cnt <= 0) {
@@ -374,33 +372,6 @@ static int bfin_bf54x_fb_check_var(struct fb_var_screeninfo *var,
return 0;
}
-static int bfin_bf54x_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-
- struct bfin_bf54xfb_info *fbi = info->par;
-
- if (fbi->lq043_mmap)
- return -1;
-
- spin_lock(&fbi->lock);
- fbi->lq043_mmap = 1;
- spin_unlock(&fbi->lock);
-
- vma->vm_start = (unsigned long)(fbi->fb_buffer);
-
- vma->vm_end = vma->vm_start + info->fix.smem_len;
- /* For those who don't understand how mmap works, go read
- * Documentation/nommu-mmap.txt.
- * For those that do, you will know that the VM_MAYSHARE flag
- * must be set in the vma->vm_flags structure on noMMU
- * Other flags can be set, and are documented in
- * include/linux/mm.h
- */
- vma->vm_flags |= VM_MAYSHARE | VM_SHARED;
-
- return 0;
-}
-
int bfin_bf54x_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
if (nocursor)
@@ -452,7 +423,6 @@ static struct fb_ops bfin_bf54x_fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_mmap = bfin_bf54x_fb_mmap,
.fb_cursor = bfin_bf54x_fb_cursor,
.fb_setcolreg = bfin_bf54x_fb_setcolreg,
};
@@ -463,7 +433,7 @@ static int bl_get_brightness(struct backlight_device *bd)
return 0;
}
-static struct backlight_ops bfin_lq043fb_bl_ops = {
+static const struct backlight_ops bfin_lq043fb_bl_ops = {
.get_brightness = bl_get_brightness,
};
@@ -531,6 +501,7 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct bfin_bf54xfb_info *info;
struct fb_info *fbinfo;
int ret;
@@ -675,10 +646,16 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
goto out8;
}
#ifndef NO_BL_SUPPORT
- bl_dev =
- backlight_device_register("bf54x-bl", NULL, NULL,
- &bfin_lq043fb_bl_ops);
- bl_dev->props.max_brightness = 255;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 255;
+ bl_dev = backlight_device_register("bf54x-bl", NULL, NULL,
+ &bfin_lq043fb_bl_ops, &props);
+ if (IS_ERR(bl_dev)) {
+ printk(KERN_ERR DRIVER_NAME
+ ": unable to register backlight.\n");
+ ret = -EINVAL;
+ goto out9;
+ }
lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops);
lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
@@ -686,6 +663,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
return 0;
+out9:
+ unregister_framebuffer(fbinfo);
out8:
free_irq(info->irq, info);
out7:
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index b690c269784..2baac7cc142 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -13,6 +13,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/fb.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
@@ -22,7 +23,6 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
-#include <linux/dma-mapping.h>
#include <asm/blackfin.h>
#include <asm/irq.h>
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 2549c53b26a..44e49c28b2a 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/gfp.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -87,7 +88,6 @@ struct bfin_t350mcqbfb_info {
struct device *dev;
unsigned char *fb_buffer; /* RGB Buffer */
dma_addr_t dma_handle;
- int lq043_mmap;
int lq043_open_cnt;
int irq;
spinlock_t lock; /* lock */
@@ -235,7 +235,6 @@ static int bfin_t350mcqb_fb_release(struct fb_info *info, int user)
spin_lock(&fbi->lock);
fbi->lq043_open_cnt--;
- fbi->lq043_mmap = 0;
if (fbi->lq043_open_cnt <= 0) {
bfin_t350mcqb_disable_ppi();
@@ -293,32 +292,6 @@ static int bfin_t350mcqb_fb_check_var(struct fb_var_screeninfo *var,
return 0;
}
-static int bfin_t350mcqb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
- struct bfin_t350mcqbfb_info *fbi = info->par;
-
- if (fbi->lq043_mmap)
- return -1;
-
- spin_lock(&fbi->lock);
- fbi->lq043_mmap = 1;
- spin_unlock(&fbi->lock);
-
- vma->vm_start = (unsigned long)(fbi->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET);
-
- vma->vm_end = vma->vm_start + info->fix.smem_len;
- /* For those who don't understand how mmap works, go read
- * Documentation/nommu-mmap.txt.
- * For those that do, you will know that the VM_MAYSHARE flag
- * must be set in the vma->vm_flags structure on noMMU
- * Other flags can be set, and are documented in
- * include/linux/mm.h
- */
- vma->vm_flags |= VM_MAYSHARE | VM_SHARED;
-
- return 0;
-}
-
int bfin_t350mcqb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
if (nocursor)
@@ -370,7 +343,6 @@ static struct fb_ops bfin_t350mcqb_fb_ops = {
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_mmap = bfin_t350mcqb_fb_mmap,
.fb_cursor = bfin_t350mcqb_fb_cursor,
.fb_setcolreg = bfin_t350mcqb_fb_setcolreg,
};
@@ -381,7 +353,7 @@ static int bl_get_brightness(struct backlight_device *bd)
return 0;
}
-static struct backlight_ops bfin_lq043fb_bl_ops = {
+static const struct backlight_ops bfin_lq043fb_bl_ops = {
.get_brightness = bl_get_brightness,
};
@@ -448,6 +420,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id)
static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
{
+ struct backlight_properties props;
struct bfin_t350mcqbfb_info *info;
struct fb_info *fbinfo;
int ret;
@@ -569,10 +542,16 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
goto out8;
}
#ifndef NO_BL_SUPPORT
- bl_dev =
- backlight_device_register("bf52x-bl", NULL, NULL,
- &bfin_lq043fb_bl_ops);
- bl_dev->props.max_brightness = 255;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 255;
+ bl_dev = backlight_device_register("bf52x-bl", NULL, NULL,
+ &bfin_lq043fb_bl_ops, &props);
+ if (IS_ERR(bl_dev)) {
+ printk(KERN_ERR DRIVER_NAME
+ ": unable to register backlight.\n");
+ ret = -EINVAL;
+ goto out9;
+ }
lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops);
lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
@@ -580,6 +559,8 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
return 0;
+out9:
+ unregister_framebuffer(fbinfo);
out8:
free_irq(info->irq, info);
out7:
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c
index df9ccb901d8..ebda6876d3a 100644
--- a/drivers/video/broadsheetfb.c
+++ b/drivers/video/broadsheetfb.c
@@ -29,11 +29,65 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/list.h>
+#include <linux/firmware.h>
#include <linux/uaccess.h>
#include <video/broadsheetfb.h>
-/* Display specific information */
+/* track panel specific parameters */
+struct panel_info {
+ int w;
+ int h;
+ u16 sdcfg;
+ u16 gdcfg;
+ u16 lutfmt;
+ u16 fsynclen;
+ u16 fendfbegin;
+ u16 lsynclen;
+ u16 lendlbegin;
+ u16 pixclk;
+};
+
+/* table of panel specific parameters to be indexed into by the board drivers */
+static struct panel_info panel_table[] = {
+ { /* standard 6" on TFT backplane */
+ .w = 800,
+ .h = 600,
+ .sdcfg = (100 | (1 << 8) | (1 << 9)),
+ .gdcfg = 2,
+ .lutfmt = (4 | (1 << 7)),
+ .fsynclen = 4,
+ .fendfbegin = (10 << 8) | 4,
+ .lsynclen = 10,
+ .lendlbegin = (100 << 8) | 4,
+ .pixclk = 6,
+ },
+ { /* custom 3.7" flexible on PET or steel */
+ .w = 320,
+ .h = 240,
+ .sdcfg = (67 | (0 << 8) | (0 << 9) | (0 << 10) | (0 << 12)),
+ .gdcfg = 3,
+ .lutfmt = (4 | (1 << 7)),
+ .fsynclen = 0,
+ .fendfbegin = (80 << 8) | 4,
+ .lsynclen = 10,
+ .lendlbegin = (80 << 8) | 20,
+ .pixclk = 14,
+ },
+ { /* standard 9.7" on TFT backplane */
+ .w = 1200,
+ .h = 825,
+ .sdcfg = (100 | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 12)),
+ .gdcfg = 2,
+ .lutfmt = (4 | (1 << 7)),
+ .fsynclen = 0,
+ .fendfbegin = (4 << 8) | 4,
+ .lsynclen = 4,
+ .lendlbegin = (60 << 8) | 10,
+ .pixclk = 3,
+ },
+};
+
#define DPY_W 800
#define DPY_H 600
@@ -62,30 +116,30 @@ static struct fb_var_screeninfo broadsheetfb_var __devinitdata = {
};
/* main broadsheetfb functions */
-static void broadsheet_issue_data(struct broadsheetfb_par *par, u16 data)
+static void broadsheet_gpio_issue_data(struct broadsheetfb_par *par, u16 data)
{
par->board->set_ctl(par, BS_WR, 0);
par->board->set_hdb(par, data);
par->board->set_ctl(par, BS_WR, 1);
}
-static void broadsheet_issue_cmd(struct broadsheetfb_par *par, u16 data)
+static void broadsheet_gpio_issue_cmd(struct broadsheetfb_par *par, u16 data)
{
par->board->set_ctl(par, BS_DC, 0);
- broadsheet_issue_data(par, data);
+ broadsheet_gpio_issue_data(par, data);
}
-static void broadsheet_send_command(struct broadsheetfb_par *par, u16 data)
+static void broadsheet_gpio_send_command(struct broadsheetfb_par *par, u16 data)
{
par->board->wait_for_rdy(par);
par->board->set_ctl(par, BS_CS, 0);
- broadsheet_issue_cmd(par, data);
+ broadsheet_gpio_issue_cmd(par, data);
par->board->set_ctl(par, BS_DC, 1);
par->board->set_ctl(par, BS_CS, 1);
}
-static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
+static void broadsheet_gpio_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
int argc, u16 *argv)
{
int i;
@@ -93,15 +147,43 @@ static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
par->board->wait_for_rdy(par);
par->board->set_ctl(par, BS_CS, 0);
- broadsheet_issue_cmd(par, cmd);
+ broadsheet_gpio_issue_cmd(par, cmd);
par->board->set_ctl(par, BS_DC, 1);
for (i = 0; i < argc; i++)
- broadsheet_issue_data(par, argv[i]);
+ broadsheet_gpio_issue_data(par, argv[i]);
par->board->set_ctl(par, BS_CS, 1);
}
-static void broadsheet_burst_write(struct broadsheetfb_par *par, int size,
+static void broadsheet_mmio_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
+ int argc, u16 *argv)
+{
+ int i;
+
+ par->board->mmio_write(par, BS_MMIO_CMD, cmd);
+
+ for (i = 0; i < argc; i++)
+ par->board->mmio_write(par, BS_MMIO_DATA, argv[i]);
+}
+
+static void broadsheet_send_command(struct broadsheetfb_par *par, u16 data)
+{
+ if (par->board->mmio_write)
+ par->board->mmio_write(par, BS_MMIO_CMD, data);
+ else
+ broadsheet_gpio_send_command(par, data);
+}
+
+static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
+ int argc, u16 *argv)
+{
+ if (par->board->mmio_write)
+ broadsheet_mmio_send_cmdargs(par, cmd, argc, argv);
+ else
+ broadsheet_gpio_send_cmdargs(par, cmd, argc, argv);
+}
+
+static void broadsheet_gpio_burst_write(struct broadsheetfb_par *par, int size,
u16 *data)
{
int i;
@@ -121,7 +203,30 @@ static void broadsheet_burst_write(struct broadsheetfb_par *par, int size,
par->board->set_ctl(par, BS_CS, 1);
}
-static u16 broadsheet_get_data(struct broadsheetfb_par *par)
+static void broadsheet_mmio_burst_write(struct broadsheetfb_par *par, int size,
+ u16 *data)
+{
+ int i;
+ u16 tmp;
+
+ for (i = 0; i < size; i++) {
+ tmp = (data[i] & 0x0F) << 4;
+ tmp |= (data[i] & 0x0F00) << 4;
+ par->board->mmio_write(par, BS_MMIO_DATA, tmp);
+ }
+
+}
+
+static void broadsheet_burst_write(struct broadsheetfb_par *par, int size,
+ u16 *data)
+{
+ if (par->board->mmio_write)
+ broadsheet_mmio_burst_write(par, size, data);
+ else
+ broadsheet_gpio_burst_write(par, size, data);
+}
+
+static u16 broadsheet_gpio_get_data(struct broadsheetfb_par *par)
{
u16 res;
/* wait for ready to go hi. (lo is busy) */
@@ -141,7 +246,16 @@ static u16 broadsheet_get_data(struct broadsheetfb_par *par)
return res;
}
-static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg,
+
+static u16 broadsheet_get_data(struct broadsheetfb_par *par)
+{
+ if (par->board->mmio_read)
+ return par->board->mmio_read(par);
+ else
+ return broadsheet_gpio_get_data(par);
+}
+
+static void broadsheet_gpio_write_reg(struct broadsheetfb_par *par, u16 reg,
u16 data)
{
/* wait for ready to go hi. (lo is busy) */
@@ -150,44 +264,541 @@ static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg,
/* cs lo, dc lo for cmd, we lo for each data, db as usual */
par->board->set_ctl(par, BS_CS, 0);
- broadsheet_issue_cmd(par, BS_CMD_WR_REG);
+ broadsheet_gpio_issue_cmd(par, BS_CMD_WR_REG);
par->board->set_ctl(par, BS_DC, 1);
- broadsheet_issue_data(par, reg);
- broadsheet_issue_data(par, data);
+ broadsheet_gpio_issue_data(par, reg);
+ broadsheet_gpio_issue_data(par, data);
par->board->set_ctl(par, BS_CS, 1);
}
+static void broadsheet_mmio_write_reg(struct broadsheetfb_par *par, u16 reg,
+ u16 data)
+{
+ par->board->mmio_write(par, BS_MMIO_CMD, BS_CMD_WR_REG);
+ par->board->mmio_write(par, BS_MMIO_DATA, reg);
+ par->board->mmio_write(par, BS_MMIO_DATA, data);
+
+}
+
+static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg,
+ u16 data)
+{
+ if (par->board->mmio_write)
+ broadsheet_mmio_write_reg(par, reg, data);
+ else
+ broadsheet_gpio_write_reg(par, reg, data);
+}
+
+static void broadsheet_write_reg32(struct broadsheetfb_par *par, u16 reg,
+ u32 data)
+{
+ broadsheet_write_reg(par, reg, cpu_to_le32(data) & 0xFFFF);
+ broadsheet_write_reg(par, reg + 2, (cpu_to_le32(data) >> 16) & 0xFFFF);
+}
+
+
static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg)
{
- broadsheet_send_command(par, reg);
- msleep(100);
+ broadsheet_send_cmdargs(par, BS_CMD_RD_REG, 1, &reg);
+ par->board->wait_for_rdy(par);
return broadsheet_get_data(par);
}
+/* functions for waveform manipulation */
+static int is_broadsheet_pll_locked(struct broadsheetfb_par *par)
+{
+ return broadsheet_read_reg(par, 0x000A) & 0x0001;
+}
+
+static int broadsheet_setup_plls(struct broadsheetfb_par *par)
+{
+ int retry_count = 0;
+ u16 tmp;
+
+ /* disable arral saemipu mode */
+ broadsheet_write_reg(par, 0x0006, 0x0000);
+
+ broadsheet_write_reg(par, 0x0010, 0x0004);
+ broadsheet_write_reg(par, 0x0012, 0x5949);
+ broadsheet_write_reg(par, 0x0014, 0x0040);
+ broadsheet_write_reg(par, 0x0016, 0x0000);
+
+ do {
+ if (retry_count++ > 100)
+ return -ETIMEDOUT;
+ mdelay(1);
+ } while (!is_broadsheet_pll_locked(par));
+
+ tmp = broadsheet_read_reg(par, 0x0006);
+ tmp &= ~0x1;
+ broadsheet_write_reg(par, 0x0006, tmp);
+
+ return 0;
+}
+
+static int broadsheet_setup_spi(struct broadsheetfb_par *par)
+{
+
+ broadsheet_write_reg(par, 0x0204, ((3 << 3) | 1));
+ broadsheet_write_reg(par, 0x0208, 0x0001);
+
+ return 0;
+}
+
+static int broadsheet_setup_spiflash(struct broadsheetfb_par *par,
+ u16 *orig_sfmcd)
+{
+
+ *orig_sfmcd = broadsheet_read_reg(par, 0x0204);
+ broadsheet_write_reg(par, 0x0208, 0);
+ broadsheet_write_reg(par, 0x0204, 0);
+ broadsheet_write_reg(par, 0x0204, ((3 << 3) | 1));
+
+ return 0;
+}
+
+static int broadsheet_spiflash_wait_for_bit(struct broadsheetfb_par *par,
+ u16 reg, int bitnum, int val,
+ int timeout)
+{
+ u16 tmp;
+
+ do {
+ tmp = broadsheet_read_reg(par, reg);
+ if (((tmp >> bitnum) & 1) == val)
+ return 0;
+ mdelay(1);
+ } while (timeout--);
+
+ return -ETIMEDOUT;
+}
+
+static int broadsheet_spiflash_write_byte(struct broadsheetfb_par *par, u8 data)
+{
+ broadsheet_write_reg(par, 0x0202, (data | 0x100));
+
+ return broadsheet_spiflash_wait_for_bit(par, 0x0206, 3, 0, 100);
+}
+
+static int broadsheet_spiflash_read_byte(struct broadsheetfb_par *par, u8 *data)
+{
+ int err;
+ u16 tmp;
+
+ broadsheet_write_reg(par, 0x0202, 0);
+
+ err = broadsheet_spiflash_wait_for_bit(par, 0x0206, 3, 0, 100);
+ if (err)
+ return err;
+
+ tmp = broadsheet_read_reg(par, 0x200);
+
+ *data = tmp & 0xFF;
+
+ return 0;
+}
+
+static int broadsheet_spiflash_wait_for_status(struct broadsheetfb_par *par,
+ int timeout)
+{
+ u8 tmp;
+ int err;
+
+ do {
+ broadsheet_write_reg(par, 0x0208, 1);
+
+ err = broadsheet_spiflash_write_byte(par, 0x05);
+ if (err)
+ goto failout;
+
+ err = broadsheet_spiflash_read_byte(par, &tmp);
+ if (err)
+ goto failout;
+
+ broadsheet_write_reg(par, 0x0208, 0);
+
+ if (!(tmp & 0x1))
+ return 0;
+
+ mdelay(5);
+ } while (timeout--);
+
+ dev_err(par->info->device, "Timed out waiting for spiflash status\n");
+ return -ETIMEDOUT;
+
+failout:
+ broadsheet_write_reg(par, 0x0208, 0);
+ return err;
+}
+
+static int broadsheet_spiflash_op_on_address(struct broadsheetfb_par *par,
+ u8 op, u32 addr)
+{
+ int i;
+ u8 tmp;
+ int err;
+
+ broadsheet_write_reg(par, 0x0208, 1);
+
+ err = broadsheet_spiflash_write_byte(par, op);
+ if (err)
+ return err;
+
+ for (i = 2; i >= 0; i--) {
+ tmp = ((addr >> (i * 8)) & 0xFF);
+ err = broadsheet_spiflash_write_byte(par, tmp);
+ if (err)
+ return err;
+ }
+
+ return err;
+}
+
+static int broadsheet_verify_spiflash(struct broadsheetfb_par *par,
+ int *flash_type)
+{
+ int err = 0;
+ u8 sig;
+
+ err = broadsheet_spiflash_op_on_address(par, 0xAB, 0x00000000);
+ if (err)
+ goto failout;
+
+ err = broadsheet_spiflash_read_byte(par, &sig);
+ if (err)
+ goto failout;
+
+ if ((sig != 0x10) && (sig != 0x11)) {
+ dev_err(par->info->device, "Unexpected flash type\n");
+ err = -EINVAL;
+ goto failout;
+ }
+
+ *flash_type = sig;
+
+failout:
+ broadsheet_write_reg(par, 0x0208, 0);
+ return err;
+}
+
+static int broadsheet_setup_for_wfm_write(struct broadsheetfb_par *par,
+ u16 *initial_sfmcd, int *flash_type)
+
+{
+ int err;
+
+ err = broadsheet_setup_plls(par);
+ if (err)
+ return err;
+
+ broadsheet_write_reg(par, 0x0106, 0x0203);
+
+ err = broadsheet_setup_spi(par);
+ if (err)
+ return err;
+
+ err = broadsheet_setup_spiflash(par, initial_sfmcd);
+ if (err)
+ return err;
+
+ return broadsheet_verify_spiflash(par, flash_type);
+}
+
+static int broadsheet_spiflash_write_control(struct broadsheetfb_par *par,
+ int mode)
+{
+ int err;
+
+ broadsheet_write_reg(par, 0x0208, 1);
+ if (mode)
+ err = broadsheet_spiflash_write_byte(par, 0x06);
+ else
+ err = broadsheet_spiflash_write_byte(par, 0x04);
+
+ broadsheet_write_reg(par, 0x0208, 0);
+ return err;
+}
+
+static int broadsheet_spiflash_erase_sector(struct broadsheetfb_par *par,
+ int addr)
+{
+ int err;
+
+ broadsheet_spiflash_write_control(par, 1);
+
+ err = broadsheet_spiflash_op_on_address(par, 0xD8, addr);
+
+ broadsheet_write_reg(par, 0x0208, 0);
+
+ if (err)
+ return err;
+
+ err = broadsheet_spiflash_wait_for_status(par, 1000);
+
+ return err;
+}
+
+static int broadsheet_spiflash_read_range(struct broadsheetfb_par *par,
+ int addr, int size, char *data)
+{
+ int err;
+ int i;
+
+ err = broadsheet_spiflash_op_on_address(par, 0x03, addr);
+ if (err)
+ goto failout;
+
+ for (i = 0; i < size; i++) {
+ err = broadsheet_spiflash_read_byte(par, &data[i]);
+ if (err)
+ goto failout;
+ }
+
+failout:
+ broadsheet_write_reg(par, 0x0208, 0);
+ return err;
+}
+
+#define BS_SPIFLASH_PAGE_SIZE 256
+static int broadsheet_spiflash_write_page(struct broadsheetfb_par *par,
+ int addr, const char *data)
+{
+ int err;
+ int i;
+
+ broadsheet_spiflash_write_control(par, 1);
+
+ err = broadsheet_spiflash_op_on_address(par, 0x02, addr);
+ if (err)
+ goto failout;
+
+ for (i = 0; i < BS_SPIFLASH_PAGE_SIZE; i++) {
+ err = broadsheet_spiflash_write_byte(par, data[i]);
+ if (err)
+ goto failout;
+ }
+
+ broadsheet_write_reg(par, 0x0208, 0);
+
+ err = broadsheet_spiflash_wait_for_status(par, 100);
+
+failout:
+ return err;
+}
+
+static int broadsheet_spiflash_write_sector(struct broadsheetfb_par *par,
+ int addr, const char *data, int sector_size)
+{
+ int i;
+ int err;
+
+ for (i = 0; i < sector_size; i += BS_SPIFLASH_PAGE_SIZE) {
+ err = broadsheet_spiflash_write_page(par, addr + i, &data[i]);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+/*
+ * The caller must guarantee that the data to be rewritten is entirely
+ * contained within this sector. That is, data_start_addr + data_len
+ * must be less than sector_start_addr + sector_size.
+ */
+static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par,
+ int sector_size, int data_start_addr,
+ int data_len, const char *data)
+{
+ int err;
+ char *sector_buffer;
+ int tail_start_addr;
+ int start_sector_addr;
+
+ sector_buffer = kzalloc(sizeof(char)*sector_size, GFP_KERNEL);
+ if (!sector_buffer)
+ return -ENOMEM;
+
+ /* the start address of the sector is the 0th byte of that sector */
+ start_sector_addr = (data_start_addr / sector_size) * sector_size;
+
+ /*
+ * check if there is head data that we need to readback into our sector
+ * buffer first
+ */
+ if (data_start_addr != start_sector_addr) {
+ /*
+ * we need to read every byte up till the start address of our
+ * data and we put it into our sector buffer.
+ */
+ err = broadsheet_spiflash_read_range(par, start_sector_addr,
+ data_start_addr, sector_buffer);
+ if (err)
+ return err;
+ }
+
+ /* now we copy our data into the right place in the sector buffer */
+ memcpy(sector_buffer + data_start_addr, data, data_len);
+
+ /*
+ * now we check if there is a tail section of the sector that we need to
+ * readback.
+ */
+ tail_start_addr = (data_start_addr + data_len) % sector_size;
+
+ if (tail_start_addr) {
+ int tail_len;
+
+ tail_len = sector_size - tail_start_addr;
+
+ /* now we read this tail into our sector buffer */
+ err = broadsheet_spiflash_read_range(par, tail_start_addr,
+ tail_len, sector_buffer + tail_start_addr);
+ if (err)
+ return err;
+ }
+
+ /* if we got here we have the full sector that we want to rewrite. */
+
+ /* first erase the sector */
+ err = broadsheet_spiflash_erase_sector(par, start_sector_addr);
+ if (err)
+ return err;
+
+ /* now write it */
+ err = broadsheet_spiflash_write_sector(par, start_sector_addr,
+ sector_buffer, sector_size);
+ return err;
+}
+
+static int broadsheet_write_spiflash(struct broadsheetfb_par *par, u32 wfm_addr,
+ const u8 *wfm, int bytecount, int flash_type)
+{
+ int sector_size;
+ int err;
+ int cur_addr;
+ int writecount;
+ int maxlen;
+ int offset = 0;
+
+ switch (flash_type) {
+ case 0x10:
+ sector_size = 32*1024;
+ break;
+ case 0x11:
+ default:
+ sector_size = 64*1024;
+ break;
+ }
+
+ while (bytecount) {
+ cur_addr = wfm_addr + offset;
+ maxlen = roundup(cur_addr, sector_size) - cur_addr;
+ writecount = min(bytecount, maxlen);
+
+ err = broadsheet_spiflash_rewrite_sector(par, sector_size,
+ cur_addr, writecount, wfm + offset);
+ if (err)
+ return err;
+
+ offset += writecount;
+ bytecount -= writecount;
+ }
+
+ return 0;
+}
+
+static int broadsheet_store_waveform_to_spiflash(struct broadsheetfb_par *par,
+ const u8 *wfm, size_t wfm_size)
+{
+ int err = 0;
+ u16 initial_sfmcd = 0;
+ int flash_type = 0;
+
+ err = broadsheet_setup_for_wfm_write(par, &initial_sfmcd, &flash_type);
+ if (err)
+ goto failout;
+
+ err = broadsheet_write_spiflash(par, 0x886, wfm, wfm_size, flash_type);
+
+failout:
+ broadsheet_write_reg(par, 0x0204, initial_sfmcd);
+ return err;
+}
+
+static ssize_t broadsheet_loadstore_waveform(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ int err;
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct broadsheetfb_par *par = info->par;
+ const struct firmware *fw_entry;
+
+ if (len < 1)
+ return -EINVAL;
+
+ err = request_firmware(&fw_entry, "broadsheet.wbf", dev);
+ if (err < 0) {
+ dev_err(dev, "Failed to get broadsheet waveform\n");
+ goto err_failed;
+ }
+
+ /* try to enforce reasonable min max on waveform */
+ if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) {
+ dev_err(dev, "Invalid waveform\n");
+ err = -EINVAL;
+ goto err_failed;
+ }
+
+ mutex_lock(&(par->io_lock));
+ err = broadsheet_store_waveform_to_spiflash(par, fw_entry->data,
+ fw_entry->size);
+
+ mutex_unlock(&(par->io_lock));
+ if (err < 0) {
+ dev_err(dev, "Failed to store broadsheet waveform\n");
+ goto err_failed;
+ }
+
+ dev_info(dev, "Stored broadsheet waveform, size %zd\n", fw_entry->size);
+
+ return len;
+
+err_failed:
+ return err;
+}
+static DEVICE_ATTR(loadstore_waveform, S_IWUSR, NULL,
+ broadsheet_loadstore_waveform);
+
+/* upper level functions that manipulate the display and other stuff */
static void __devinit broadsheet_init_display(struct broadsheetfb_par *par)
{
u16 args[5];
-
- args[0] = DPY_W;
- args[1] = DPY_H;
- args[2] = (100 | (1 << 8) | (1 << 9)); /* sdcfg */
- args[3] = 2; /* gdrv cfg */
- args[4] = (4 | (1 << 7)); /* lut index format */
+ int xres = par->info->var.xres;
+ int yres = par->info->var.yres;
+
+ args[0] = panel_table[par->panel_index].w;
+ args[1] = panel_table[par->panel_index].h;
+ args[2] = panel_table[par->panel_index].sdcfg;
+ args[3] = panel_table[par->panel_index].gdcfg;
+ args[4] = panel_table[par->panel_index].lutfmt;
broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args);
/* did the controller really set it? */
broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args);
- args[0] = 4; /* fsync len */
- args[1] = (10 << 8) | 4; /* fend/fbegin len */
- args[2] = 10; /* line sync len */
- args[3] = (100 << 8) | 4; /* line end/begin len */
- args[4] = 6; /* pixel clock cfg */
+ args[0] = panel_table[par->panel_index].fsynclen;
+ args[1] = panel_table[par->panel_index].fendfbegin;
+ args[2] = panel_table[par->panel_index].lsynclen;
+ args[3] = panel_table[par->panel_index].lendlbegin;
+ args[4] = panel_table[par->panel_index].pixclk;
broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args);
+ broadsheet_write_reg32(par, 0x310, xres*yres*2);
+
/* setup waveform */
args[0] = 0x886;
args[1] = 0;
@@ -207,8 +818,9 @@ static void __devinit broadsheet_init_display(struct broadsheetfb_par *par)
args[0] = 0x154;
broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args);
- broadsheet_burst_write(par, DPY_W*DPY_H/2,
- (u16 *) par->info->screen_base);
+ broadsheet_burst_write(par, (panel_table[par->panel_index].w *
+ panel_table[par->panel_index].h)/2,
+ (u16 *) par->info->screen_base);
broadsheet_send_command(par, BS_CMD_LD_IMG_END);
@@ -222,6 +834,21 @@ static void __devinit broadsheet_init_display(struct broadsheetfb_par *par)
par->board->wait_for_rdy(par);
}
+static void __devinit broadsheet_identify(struct broadsheetfb_par *par)
+{
+ u16 rev, prc;
+ struct device *dev = par->info->device;
+
+ rev = broadsheet_read_reg(par, BS_REG_REV);
+ prc = broadsheet_read_reg(par, BS_REG_PRC);
+ dev_info(dev, "Broadsheet Rev 0x%x, Product Code 0x%x\n", rev, prc);
+
+ if (prc != 0x0047)
+ dev_warn(dev, "Unrecognized Broadsheet Product Code\n");
+ if (rev != 0x0100)
+ dev_warn(dev, "Unrecognized Broadsheet Revision\n");
+}
+
static void __devinit broadsheet_init(struct broadsheetfb_par *par)
{
broadsheet_send_command(par, BS_CMD_INIT_SYS_RUN);
@@ -236,6 +863,7 @@ static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par,
u16 args[5];
unsigned char *buf = (unsigned char *)par->info->screen_base;
+ mutex_lock(&(par->io_lock));
/* y1 must be a multiple of 4 so drop the lower bits */
y1 &= 0xFFFC;
/* y2 must be a multiple of 4 , but - 1 so up the lower bits */
@@ -265,6 +893,7 @@ static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par,
broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND);
par->board->wait_for_rdy(par);
+ mutex_unlock(&(par->io_lock));
}
@@ -272,13 +901,15 @@ static void broadsheetfb_dpy_update(struct broadsheetfb_par *par)
{
u16 args[5];
+ mutex_lock(&(par->io_lock));
args[0] = 0x3 << 4;
broadsheet_send_cmdargs(par, BS_CMD_LD_IMG, 1, args);
args[0] = 0x154;
broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args);
- broadsheet_burst_write(par, DPY_W*DPY_H/2,
- (u16 *) par->info->screen_base);
+ broadsheet_burst_write(par, (panel_table[par->panel_index].w *
+ panel_table[par->panel_index].h)/2,
+ (u16 *) par->info->screen_base);
broadsheet_send_command(par, BS_CMD_LD_IMG_END);
@@ -290,7 +921,7 @@ static void broadsheetfb_dpy_update(struct broadsheetfb_par *par)
broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND);
par->board->wait_for_rdy(par);
-
+ mutex_unlock(&(par->io_lock));
}
/* this is called back from the deferred io workqueue */
@@ -436,6 +1067,8 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev)
unsigned char *videomemory;
struct broadsheetfb_par *par;
int i;
+ int dpyw, dpyh;
+ int panel_index;
/* pick up board specific routines */
board = dev->dev.platform_data;
@@ -450,7 +1083,24 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev)
if (!info)
goto err;
- videomemorysize = (DPY_W*DPY_H);
+ switch (board->get_panel_type()) {
+ case 37:
+ panel_index = 1;
+ break;
+ case 97:
+ panel_index = 2;
+ break;
+ case 6:
+ default:
+ panel_index = 0;
+ break;
+ }
+
+ dpyw = panel_table[panel_index].w;
+ dpyh = panel_table[panel_index].h;
+
+ videomemorysize = roundup((dpyw*dpyh), PAGE_SIZE);
+
videomemory = vmalloc(videomemorysize);
if (!videomemory)
goto err_fb_rel;
@@ -460,16 +1110,25 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev)
info->screen_base = (char *)videomemory;
info->fbops = &broadsheetfb_ops;
+ broadsheetfb_var.xres = dpyw;
+ broadsheetfb_var.yres = dpyh;
+ broadsheetfb_var.xres_virtual = dpyw;
+ broadsheetfb_var.yres_virtual = dpyh;
info->var = broadsheetfb_var;
+
+ broadsheetfb_fix.line_length = dpyw;
info->fix = broadsheetfb_fix;
info->fix.smem_len = videomemorysize;
par = info->par;
+ par->panel_index = panel_index;
par->info = info;
par->board = board;
par->write_reg = broadsheet_write_reg;
par->read_reg = broadsheet_read_reg;
init_waitqueue_head(&par->waitq);
+ mutex_init(&par->io_lock);
+
info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
info->fbdefio = &broadsheetfb_defio;
@@ -496,13 +1155,20 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev)
if (retval < 0)
goto err_free_irq;
+ broadsheet_identify(par);
+
broadsheet_init(par);
retval = register_framebuffer(info);
if (retval < 0)
goto err_free_irq;
+
platform_set_drvdata(dev, info);
+ retval = device_create_file(&dev->dev, &dev_attr_loadstore_waveform);
+ if (retval < 0)
+ goto err_unreg_fb;
+
printk(KERN_INFO
"fb%d: Broadsheet frame buffer, using %dK of video memory\n",
info->node, videomemorysize >> 10);
@@ -510,6 +1176,8 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev)
return 0;
+err_unreg_fb:
+ unregister_framebuffer(info);
err_free_irq:
board->cleanup(par);
err_cmap:
@@ -530,6 +1198,8 @@ static int __devexit broadsheetfb_remove(struct platform_device *dev)
if (info) {
struct broadsheetfb_par *par = info->par;
+
+ device_remove_file(info->dev, &dev_attr_loadstore_waveform);
unregister_framebuffer(info);
fb_deferred_io_cleanup(info);
par->board->cleanup(par);
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index b0b147cb4cb..43320925c4c 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c
index 0c02f8ec4bf..d8345fcc4fe 100644
--- a/drivers/video/carminefb.c
+++ b/drivers/video/carminefb.c
@@ -11,6 +11,7 @@
#include <linux/fb.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "carminefb.h"
#include "carminefb_regs.h"
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 79e5f40e648..bb5a96b1645 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -26,7 +26,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/fb.h>
-#include <linux/slab.h>
#include <asm/types.h>
#include <asm/io.h>
#include "fb_draw.h"
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index fe45a3b8d0e..77a040af20a 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index b2319fa7286..30eedf79322 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 0d47c6030e3..6d0fcb43696 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 57b9d276497..d637e1f5317 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -19,7 +19,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 4c2bf923418..8d8dfda2f86 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -39,7 +39,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c
index 108b89e09a8..5eb61b5adfe 100644
--- a/drivers/video/cobalt_lcdfb.c
+++ b/drivers/video/cobalt_lcdfb.c
@@ -287,7 +287,7 @@ static struct fb_ops cobalt_lcd_fbops = {
.fb_cursor = cobalt_lcdfb_cursor,
};
-static int __init cobalt_lcdfb_probe(struct platform_device *dev)
+static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
{
struct fb_info *info;
struct resource *res;
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fc7d9bbb548..8e8f18d29d7 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -37,6 +37,7 @@ config VGACON_SOFT_SCROLLBACK
config VGACON_SOFT_SCROLLBACK_SIZE
int "Scrollback Buffer Size (in KB)"
depends on VGACON_SOFT_SCROLLBACK
+ range 1 1024
default "64"
help
Enter the amount of System RAM to allocate for the scrollback
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 6b7c8fbc549..af88651b073 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index bdf913ecf00..d135671d996 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -9,6 +9,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index a6819b9d177..126110f8454 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -9,6 +9,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c
index 00884e013f0..db6528f2d3f 100644
--- a/drivers/video/console/fbcon_rotate.c
+++ b/drivers/video/console/fbcon_rotate.c
@@ -9,6 +9,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index d9b5d6eb68a..93a3e7381b5 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -9,6 +9,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index dd3eaaad444..0b67866cae1 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -33,7 +33,6 @@
#include <linux/console.h>
#include <linux/string.h>
#include <linux/kd.h>
-#include <linux/slab.h>
#include <linux/vt_kern.h>
#include <linux/vt_buffer.h>
#include <linux/selection.h>
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index cc4bbbe44ac..182dd6f8aad 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -112,7 +112,7 @@ static int vga_video_font_height;
static int vga_scan_lines __read_mostly;
static unsigned int vga_rolled_over;
-int vgacon_text_mode_force = 0;
+static int vgacon_text_mode_force;
bool vgacon_text_force(void)
{
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 369a5b3ac64..8d244ba0f60 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -30,6 +30,7 @@
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/console.h>
+#include <linux/slab.h>
#include <video/da8xx-fb.h>
#define DRIVER_NAME "da8xx_lcdc"
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
index 80abbf323b9..f6a09ab0dac 100644
--- a/drivers/video/display/display-sysfs.c
+++ b/drivers/video/display/display-sysfs.c
@@ -27,6 +27,7 @@
#include <linux/idr.h>
#include <linux/err.h>
#include <linux/kdev_t.h>
+#include <linux/slab.h>
static ssize_t display_show_name(struct device *dev,
struct device_attribute *attr, char *buf)
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 606da043f4b..ec56d2544c7 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -2,7 +2,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index d25df51bb0d..ecf405562f5 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -49,6 +49,7 @@ enum {
M_MBP_2, /* MacBook Pro 2nd gen */
M_MBP_SR, /* MacBook Pro (Santa Rosa) */
M_MBP_4, /* MacBook Pro, 4th gen */
+ M_MBP_5_1, /* MacBook Pro, 5,1th gen */
M_UNKNOWN /* placeholder */
};
@@ -70,6 +71,7 @@ static struct efifb_dmi_info {
[M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
+ [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 },
[M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
};
@@ -106,6 +108,7 @@ static struct dmi_system_id __initdata dmi_system_table[] = {
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1),
{},
};
@@ -210,7 +213,7 @@ static int __init efifb_setup(char *options)
return 0;
}
-static int __init efifb_probe(struct platform_device *dev)
+static int __devinit efifb_probe(struct platform_device *dev)
{
struct fb_info *info;
int err;
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index 27aab4a0619..0c99de0562c 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/fb.h>
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 2735b79e52a..db9713b49ce 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -48,7 +48,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
@@ -602,7 +601,7 @@ static int epson1355fb_remove(struct platform_device *dev)
return 0;
}
-int __init epson1355fb_probe(struct platform_device *dev)
+int __devinit epson1355fb_probe(struct platform_device *dev)
{
struct epson1355_par *default_par;
struct fb_info *info;
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c
index 0cf96eb8a60..4a874c8d039 100644
--- a/drivers/video/fb_ddc.c
+++ b/drivers/video/fb_ddc.c
@@ -12,6 +12,7 @@
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/i2c-algo-bit.h>
+#include <linux/slab.h>
#include "edid.h"
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 44ce908a478..6113c47e095 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -13,7 +13,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c
index 0847c5e72cb..7293eaccd81 100644
--- a/drivers/video/fbcvt.c
+++ b/drivers/video/fbcvt.c
@@ -13,6 +13,7 @@
*
*/
#include <linux/fb.h>
+#include <linux/slab.h>
#define FB_CVT_CELLSIZE 8
#define FB_CVT_GTF_C 40
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 9ae9cd32bd0..563a98b88e9 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -29,6 +29,7 @@
#include <linux/fb.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <video/edid.h>
#ifdef CONFIG_PPC_OF
#include <asm/prom.h>
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index d4a2c11d980..81aa3129c17 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -16,6 +16,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/console.h>
#include <linux/module.h>
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 9dbb9646081..a42fabab69d 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 4637bcbe03a..994358a4f30 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1536,6 +1536,7 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
goto error;
}
+ sysfs_attr_init(&machine_data->dev_attr.attr);
machine_data->dev_attr.attr.name = "monitor";
machine_data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
machine_data->dev_attr.show = show_monitor;
diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c
index b7655c05da5..d662317d85e 100644
--- a/drivers/video/g364fb.c
+++ b/drivers/video/g364fb.c
@@ -20,7 +20,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 695fa013fe7..7d8c55d7fd2 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -1128,7 +1129,7 @@ static int __init gbefb_setup(char *options)
return 0;
}
-static int __init gbefb_probe(struct platform_device *p_dev)
+static int __devinit gbefb_probe(struct platform_device *p_dev)
{
int i, ret = 0;
struct fb_info *info;
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index f20eff8c4a8..c6b554f72c6 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -15,7 +15,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index b3e639d1e12..76e7dac6f25 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -25,7 +25,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/console.h>
diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h
index cc781c00f75..e4c4d89b786 100644
--- a/drivers/video/geode/lxfb.h
+++ b/drivers/video/geode/lxfb.h
@@ -365,6 +365,8 @@ enum fp_registers {
FP_CRC, /* 0x458 */
};
+#define FP_PT2_HSP (1 << 22)
+#define FP_PT2_VSP (1 << 23)
#define FP_PT2_SCRC (1 << 27) /* shfclk free */
#define FP_PM_P (1 << 24) /* panel power ctl */
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index 889cbe39e58..1a18da86d3f 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -16,7 +16,6 @@
#include <linux/string.h>
#include <linux/console.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/delay.h>
#include <linux/fb.h>
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c
index 0e5d8c7c3eb..bc35a95e59d 100644
--- a/drivers/video/geode/lxfb_ops.c
+++ b/drivers/video/geode/lxfb_ops.c
@@ -274,7 +274,15 @@ static void lx_graphics_enable(struct fb_info *info)
u32 msrlo, msrhi;
write_fp(par, FP_PT1, 0);
- write_fp(par, FP_PT2, FP_PT2_SCRC);
+ temp = FP_PT2_SCRC;
+
+ if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
+ temp |= FP_PT2_HSP;
+
+ if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
+ temp |= FP_PT2_VSP;
+
+ write_fp(par, FP_PT2, temp);
write_fp(par, FP_DFC, FP_DFC_BC);
msrlo = MSR_LX_MSR_PADSEL_TFT_SEL_LOW;
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index f9d77adf035..c77bcc6ab46 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -32,7 +32,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c
index 0129c044f6d..8bbf251f83d 100644
--- a/drivers/video/hgafb.c
+++ b/drivers/video/hgafb.c
@@ -36,7 +36,6 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
@@ -551,7 +550,7 @@ static struct fb_ops hgafb_ops = {
* Initialization
*/
-static int __init hgafb_probe(struct platform_device *pdev)
+static int __devinit hgafb_probe(struct platform_device *pdev)
{
struct fb_info *info;
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 73c83a8de2d..393f3f3d3df 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -16,7 +16,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/platform_device.h>
@@ -325,7 +324,7 @@ static struct fb_ops hitfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __init hitfb_probe(struct platform_device *dev)
+static int __devinit hitfb_probe(struct platform_device *dev)
{
unsigned short lcdclor, ldr3, ldvndr;
struct fb_info *info;
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index b8ebff1e849..c8e280f1bb0 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -10,7 +10,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 9dd55e5324a..cd2c728a809 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/fb.h>
#include "i810.h"
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 15d50b9906c..efb2c10656b 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -21,7 +21,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 81627466804..38065cf94ac 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -24,7 +24,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/ioport.h>
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index e145e2d16fe..1db55f12849 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index f3728ab262f..403b14445a7 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -13,6 +13,7 @@
#include "matroxfb_base.h"
#include "matroxfb_maven.h"
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/i2c-algo-bit.h>
/* MGA-TVO I2C for G200, G400 */
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 7064fb4427b..052dd9f0b76 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -113,6 +113,7 @@
#include "matroxfb_g450.h"
#include <linux/matroxfb.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#ifdef CONFIG_PPC_PMAC
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 78414baa5a5..d7112c39614 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -15,6 +15,7 @@
#include "matroxfb_misc.h"
#include "matroxfb_DAC1064.h"
#include <linux/matroxfb.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
/* **************************************************** */
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index 91af9159111..1e3e8f19783 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -17,6 +17,7 @@
#include "matroxfb_DAC1064.h"
#include <linux/i2c.h>
#include <linux/matroxfb.h>
+#include <linux/slab.h>
#include <asm/div64.h>
#define MGATVO_B 1
diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
index 7854c7a37dc..5cf52d3c8e7 100644
--- a/drivers/video/maxinefb.c
+++ b/drivers/video/maxinefb.c
@@ -28,7 +28,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c
index fabb0c59a21..8280a58a0e5 100644
--- a/drivers/video/mb862xx/mb862xxfb.c
+++ b/drivers/video/mb862xx/mb862xxfb.c
@@ -31,15 +31,6 @@
#define CARMINE_MEM_SIZE 0x8000000
#define DRV_NAME "mb862xxfb"
-#if defined(CONFIG_LWMON5)
-static struct mb862xx_gc_mode lwmon5_gc_mode = {
- /* Mode for Sharp LQ104V1DG61 TFT LCD Panel */
- { "640x480", 60, 640, 480, 40000, 48, 16, 32, 11, 96, 2, 0, 0, 0 },
- /* 16 bits/pixel, 32MB, 100MHz, SDRAM memory mode value */
- 16, 0x2000000, GC_CCF_COT_100, 0x414fb7f2
-};
-#endif
-
#if defined(CONFIG_SOCRATES)
static struct mb862xx_gc_mode socrates_gc_mode = {
/* Mode for Prime View PM070WL4 TFT LCD Panel */
@@ -600,10 +591,6 @@ static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev,
goto irqdisp;
}
-#if defined(CONFIG_LWMON5)
- par->gc_mode = &lwmon5_gc_mode;
-#endif
-
#if defined(CONFIG_SOCRATES)
par->gc_mode = &socrates_gc_mode;
#endif
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/mb862xx/mb862xxfb_accel.c
index 049256052b1..fe92eed6da7 100644
--- a/drivers/video/mb862xx/mb862xxfb_accel.c
+++ b/drivers/video/mb862xx/mb862xxfb_accel.c
@@ -4,7 +4,7 @@
* Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver acceleration support
*
* (C) 2007 Alexander Shishkin <virtuoso@slind.org>
- * (C) 2009 Valentin Sitdikov <valentin.sitdikov@siemens.com>
+ * (C) 2009 Valentin Sitdikov <v.sitdikov@gmail.com>
* (C) 2009 Siemens AG
*
* This program is free software; you can redistribute it and/or modify
@@ -16,7 +16,9 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#if defined(CONFIG_OF)
#include <linux/of_platform.h>
#endif
@@ -329,3 +331,5 @@ void mb862xxfb_init_accel(struct fb_info *info, int xres)
info->fix.accel = 0xff; /*FIXME: add right define */
}
EXPORT_SYMBOL(mb862xxfb_init_accel);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
index 15b8b3c4330..ecad9652457 100644
--- a/drivers/video/mbx/mbxdebugfs.c
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -1,4 +1,5 @@
#include <linux/debugfs.h>
+#include <linux/slab.h>
#define BIG_BUFFER_SIZE (1024)
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 01f77bcc68f..afea9abbd67 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -693,7 +693,7 @@ static void __devinit setup_memc(struct fb_info *fbi)
unsigned long tmp;
int i;
- /* FIXME: use platfrom specific parameters */
+ /* FIXME: use platform specific parameters */
/* setup SDRAM controller */
write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
LMCFG_LMA_TS),
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
index 661bfd20d19..9b3d6e4584c 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/metronomefb.c
@@ -23,7 +23,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 0129f1bc352..0a4dbdc1693 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -12,6 +12,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/kernel.h>
@@ -893,7 +894,7 @@ const struct fb_videomode *fb_match_mode(const struct fb_var_screeninfo *var,
}
/**
- * fb_add_videomode: adds videomode entry to modelist
+ * fb_add_videomode - adds videomode entry to modelist
* @mode: videomode to add
* @head: struct list_head of modelist
*
@@ -928,7 +929,7 @@ int fb_add_videomode(const struct fb_videomode *mode, struct list_head *head)
}
/**
- * fb_delete_videomode: removed videomode entry from modelist
+ * fb_delete_videomode - removed videomode entry from modelist
* @mode: videomode to remove
* @head: struct list_head of modelist
*
@@ -953,7 +954,7 @@ void fb_delete_videomode(const struct fb_videomode *mode,
}
/**
- * fb_destroy_modelist: destroy modelist
+ * fb_destroy_modelist - destroy modelist
* @head: struct list_head of modelist
*/
void fb_destroy_modelist(struct list_head *head)
@@ -968,7 +969,7 @@ void fb_destroy_modelist(struct list_head *head)
EXPORT_SYMBOL_GPL(fb_destroy_modelist);
/**
- * fb_videomode_to_modelist: convert mode array to mode list
+ * fb_videomode_to_modelist - convert mode array to mode list
* @modedb: array of struct fb_videomode
* @num: number of entries in array
* @head: struct list_head of modelist
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index 474421fe79a..c1ff271017a 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/io.h>
diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/msm/mddi_client_dummy.c
index ebbae87885b..d2a091cebe2 100644
--- a/drivers/video/msm/mddi_client_dummy.c
+++ b/drivers/video/msm/mddi_client_dummy.c
@@ -15,6 +15,7 @@
* GNU General Public License for more details.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index c9e9349451c..f239f4a25e0 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <mach/msm_fb.h>
static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
index 71048e78f7f..f9bc932ac46 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <mach/msm_fb.h>
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 6c519e2fa2b..19c01c6208e 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -23,6 +23,7 @@
#include <linux/clk.h>
#include <linux/file.h>
#include <linux/major.h>
+#include <linux/slab.h>
#include <mach/msm_iomap.h>
#include <mach/msm_fb.h>
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 49101dda45e..debe5933fd2 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/fb.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/freezer.h>
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
new file mode 100644
index 00000000000..6bf0d460a73
--- /dev/null
+++ b/drivers/video/nuc900fb.c
@@ -0,0 +1,779 @@
+/*
+ *
+ * Copyright (c) 2009 Nuvoton technology 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Description:
+ * Nuvoton LCD Controller Driver
+ * Author:
+ * Wang Qiang (rurality.linux@gmail.com) 2009/12/11
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/wait.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/io.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-ldm.h>
+#include <mach/fb.h>
+#include <mach/clkdev.h>
+
+#include "nuc900fb.h"
+
+
+/*
+ * Initialize the nuc900 video (dual) buffer address
+ */
+static void nuc900fb_set_lcdaddr(struct fb_info *info)
+{
+ struct nuc900fb_info *fbi = info->par;
+ void __iomem *regs = fbi->io;
+ unsigned long vbaddr1, vbaddr2;
+
+ vbaddr1 = info->fix.smem_start;
+ vbaddr2 = info->fix.smem_start;
+ vbaddr2 += info->fix.line_length * info->var.yres;
+
+ /* set frambuffer start phy addr*/
+ writel(vbaddr1, regs + REG_LCM_VA_BADDR0);
+ writel(vbaddr2, regs + REG_LCM_VA_BADDR1);
+
+ writel(fbi->regs.lcd_va_fbctrl, regs + REG_LCM_VA_FBCTRL);
+ writel(fbi->regs.lcd_va_scale, regs + REG_LCM_VA_SCALE);
+}
+
+/*
+ * calculate divider for lcd div
+ */
+static unsigned int nuc900fb_calc_pixclk(struct nuc900fb_info *fbi,
+ unsigned long pixclk)
+{
+ unsigned long clk = fbi->clk_rate;
+ unsigned long long div;
+
+ /* pixclk is in picseconds. our clock is in Hz*/
+ /* div = (clk * pixclk)/10^12 */
+ div = (unsigned long long)clk * pixclk;
+ div >>= 12;
+ do_div(div, 625 * 625UL * 625);
+
+ dev_dbg(fbi->dev, "pixclk %ld, divisor is %lld\n", pixclk, div);
+
+ return div;
+}
+
+/*
+ * Check the video params of 'var'.
+ */
+static int nuc900fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct nuc900fb_info *fbi = info->par;
+ struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data;
+ struct nuc900fb_display *display = NULL;
+ struct nuc900fb_display *default_display = mach_info->displays +
+ mach_info->default_display;
+ int i;
+
+ dev_dbg(fbi->dev, "check_var(var=%p, info=%p)\n", var, info);
+
+ /* validate x/y resolution */
+ /* choose default mode if possible */
+ if (var->xres == default_display->xres &&
+ var->yres == default_display->yres &&
+ var->bits_per_pixel == default_display->bpp)
+ display = default_display;
+ else
+ for (i = 0; i < mach_info->num_displays; i++)
+ if (var->xres == mach_info->displays[i].xres &&
+ var->yres == mach_info->displays[i].yres &&
+ var->bits_per_pixel == mach_info->displays[i].bpp) {
+ display = mach_info->displays + i;
+ break;
+ }
+
+ if (display == NULL) {
+ printk(KERN_ERR "wrong resolution or depth %dx%d at %d bit per pixel\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ /* it should be the same size as the display */
+ var->xres_virtual = display->xres;
+ var->yres_virtual = display->yres;
+ var->height = display->height;
+ var->width = display->width;
+
+ /* copy lcd settings */
+ var->pixclock = display->pixclock;
+ var->left_margin = display->left_margin;
+ var->right_margin = display->right_margin;
+ var->upper_margin = display->upper_margin;
+ var->lower_margin = display->lower_margin;
+ var->vsync_len = display->vsync_len;
+ var->hsync_len = display->hsync_len;
+
+ var->transp.offset = 0;
+ var->transp.length = 0;
+
+ fbi->regs.lcd_dccs = display->dccs;
+ fbi->regs.lcd_device_ctrl = display->devctl;
+ fbi->regs.lcd_va_fbctrl = display->fbctrl;
+ fbi->regs.lcd_va_scale = display->scale;
+
+ /* set R/G/B possions */
+ switch (var->bits_per_pixel) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ default:
+ var->red.offset = 0;
+ var->red.length = var->bits_per_pixel;
+ var->green = var->red;
+ var->blue = var->red;
+ break;
+ case 12:
+ var->red.length = 4;
+ var->green.length = 4;
+ var->blue.length = 4;
+ var->red.offset = 8;
+ var->green.offset = 4;
+ var->blue.offset = 0;
+ break;
+ case 16:
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ break;
+ case 18:
+ var->red.length = 6;
+ var->green.length = 6;
+ var->blue.length = 6;
+ var->red.offset = 12;
+ var->green.offset = 6;
+ var->blue.offset = 0;
+ break;
+ case 32:
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Calculate lcd register values from var setting & save into hw
+ */
+static void nuc900fb_calculate_lcd_regs(const struct fb_info *info,
+ struct nuc900fb_hw *regs)
+{
+ const struct fb_var_screeninfo *var = &info->var;
+ int vtt = var->height + var->upper_margin + var->lower_margin;
+ int htt = var->width + var->left_margin + var->right_margin;
+ int hsync = var->width + var->right_margin;
+ int vsync = var->height + var->lower_margin;
+
+ regs->lcd_crtc_size = LCM_CRTC_SIZE_VTTVAL(vtt) |
+ LCM_CRTC_SIZE_HTTVAL(htt);
+ regs->lcd_crtc_dend = LCM_CRTC_DEND_VDENDVAL(var->height) |
+ LCM_CRTC_DEND_HDENDVAL(var->width);
+ regs->lcd_crtc_hr = LCM_CRTC_HR_EVAL(var->width + 5) |
+ LCM_CRTC_HR_SVAL(var->width + 1);
+ regs->lcd_crtc_hsync = LCM_CRTC_HSYNC_EVAL(hsync + var->hsync_len) |
+ LCM_CRTC_HSYNC_SVAL(hsync);
+ regs->lcd_crtc_vr = LCM_CRTC_VR_EVAL(vsync + var->vsync_len) |
+ LCM_CRTC_VR_SVAL(vsync);
+
+}
+
+/*
+ * Activate (set) the controller from the given framebuffer
+ * information
+ */
+static void nuc900fb_activate_var(struct fb_info *info)
+{
+ struct nuc900fb_info *fbi = info->par;
+ void __iomem *regs = fbi->io;
+ struct fb_var_screeninfo *var = &info->var;
+ int clkdiv;
+
+ clkdiv = nuc900fb_calc_pixclk(fbi, var->pixclock) - 1;
+ if (clkdiv < 0)
+ clkdiv = 0;
+
+ nuc900fb_calculate_lcd_regs(info, &fbi->regs);
+
+ /* set the new lcd registers*/
+
+ dev_dbg(fbi->dev, "new lcd register set:\n");
+ dev_dbg(fbi->dev, "dccs = 0x%08x\n", fbi->regs.lcd_dccs);
+ dev_dbg(fbi->dev, "dev_ctl = 0x%08x\n", fbi->regs.lcd_device_ctrl);
+ dev_dbg(fbi->dev, "crtc_size = 0x%08x\n", fbi->regs.lcd_crtc_size);
+ dev_dbg(fbi->dev, "crtc_dend = 0x%08x\n", fbi->regs.lcd_crtc_dend);
+ dev_dbg(fbi->dev, "crtc_hr = 0x%08x\n", fbi->regs.lcd_crtc_hr);
+ dev_dbg(fbi->dev, "crtc_hsync = 0x%08x\n", fbi->regs.lcd_crtc_hsync);
+ dev_dbg(fbi->dev, "crtc_vr = 0x%08x\n", fbi->regs.lcd_crtc_vr);
+
+ writel(fbi->regs.lcd_device_ctrl, regs + REG_LCM_DEV_CTRL);
+ writel(fbi->regs.lcd_crtc_size, regs + REG_LCM_CRTC_SIZE);
+ writel(fbi->regs.lcd_crtc_dend, regs + REG_LCM_CRTC_DEND);
+ writel(fbi->regs.lcd_crtc_hr, regs + REG_LCM_CRTC_HR);
+ writel(fbi->regs.lcd_crtc_hsync, regs + REG_LCM_CRTC_HSYNC);
+ writel(fbi->regs.lcd_crtc_vr, regs + REG_LCM_CRTC_VR);
+
+ /* set lcd address pointers */
+ nuc900fb_set_lcdaddr(info);
+
+ writel(fbi->regs.lcd_dccs, regs + REG_LCM_DCCS);
+}
+
+/*
+ * Alters the hardware state.
+ *
+ */
+static int nuc900fb_set_par(struct fb_info *info)
+{
+ struct fb_var_screeninfo *var = &info->var;
+
+ switch (var->bits_per_pixel) {
+ case 32:
+ case 24:
+ case 18:
+ case 16:
+ case 12:
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
+ case 1:
+ info->fix.visual = FB_VISUAL_MONO01;
+ break;
+ default:
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ break;
+ }
+
+ info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
+
+ /* activate this new configuration */
+ nuc900fb_activate_var(info);
+ return 0;
+}
+
+static inline unsigned int chan_to_field(unsigned int chan,
+ struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int nuc900fb_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
+{
+ unsigned int val;
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /* true-colour, use pseuo-palette */
+ if (regno < 16) {
+ u32 *pal = info->pseudo_palette;
+
+ val = chan_to_field(red, &info->var.red);
+ val |= chan_to_field(green, &info->var.green);
+ val |= chan_to_field(blue, &info->var.blue);
+ pal[regno] = val;
+ }
+ break;
+
+ default:
+ return 1; /* unknown type */
+ }
+ return 0;
+}
+
+/**
+ * nuc900fb_blank
+ *
+ */
+static int nuc900fb_blank(int blank_mode, struct fb_info *info)
+{
+
+ return 0;
+}
+
+static struct fb_ops nuc900fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = nuc900fb_check_var,
+ .fb_set_par = nuc900fb_set_par,
+ .fb_blank = nuc900fb_blank,
+ .fb_setcolreg = nuc900fb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+
+static inline void modify_gpio(void __iomem *reg,
+ unsigned long set, unsigned long mask)
+{
+ unsigned long tmp;
+ tmp = readl(reg) & ~mask;
+ writel(tmp | set, reg);
+}
+
+/*
+ * Initialise LCD-related registers
+ */
+static int nuc900fb_init_registers(struct fb_info *info)
+{
+ struct nuc900fb_info *fbi = info->par;
+ struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data;
+ void __iomem *regs = fbi->io;
+
+ /*reset the display engine*/
+ writel(0, regs + REG_LCM_DCCS);
+ writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_ENG_RST,
+ regs + REG_LCM_DCCS);
+ ndelay(100);
+ writel(readl(regs + REG_LCM_DCCS) & (~LCM_DCCS_ENG_RST),
+ regs + REG_LCM_DCCS);
+ ndelay(100);
+
+ writel(0, regs + REG_LCM_DEV_CTRL);
+
+ /* config gpio output */
+ modify_gpio(W90X900_VA_GPIO + 0x54, mach_info->gpio_dir,
+ mach_info->gpio_dir_mask);
+ modify_gpio(W90X900_VA_GPIO + 0x58, mach_info->gpio_data,
+ mach_info->gpio_data_mask);
+
+ return 0;
+}
+
+
+/*
+ * Alloc the SDRAM region of NUC900 for the frame buffer.
+ * The buffer should be a non-cached, non-buffered, memory region
+ * to allow palette and pixel writes without flushing the cache.
+ */
+static int __init nuc900fb_map_video_memory(struct fb_info *info)
+{
+ struct nuc900fb_info *fbi = info->par;
+ dma_addr_t map_dma;
+ unsigned long map_size = PAGE_ALIGN(info->fix.smem_len);
+
+ dev_dbg(fbi->dev, "nuc900fb_map_video_memory(fbi=%p) map_size %lu\n",
+ fbi, map_size);
+
+ info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
+ &map_dma, GFP_KERNEL);
+
+ if (!info->screen_base)
+ return -ENOMEM;
+
+ memset(info->screen_base, 0x00, map_size);
+ info->fix.smem_start = map_dma;
+
+ return 0;
+}
+
+static inline void nuc900fb_unmap_video_memory(struct fb_info *info)
+{
+ struct nuc900fb_info *fbi = info->par;
+ dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
+ info->screen_base, info->fix.smem_start);
+}
+
+static irqreturn_t nuc900fb_irqhandler(int irq, void *dev_id)
+{
+ struct nuc900fb_info *fbi = dev_id;
+ void __iomem *regs = fbi->io;
+ void __iomem *irq_base = fbi->irq_base;
+ unsigned long lcdirq = readl(regs + REG_LCM_INT_CS);
+
+ if (lcdirq & LCM_INT_CS_DISP_F_STATUS) {
+ writel(readl(irq_base) | 1<<30, irq_base);
+
+ /* wait VA_EN low */
+ if ((readl(regs + REG_LCM_DCCS) &
+ LCM_DCCS_SINGLE) == LCM_DCCS_SINGLE)
+ while ((readl(regs + REG_LCM_DCCS) &
+ LCM_DCCS_VA_EN) == LCM_DCCS_VA_EN)
+ ;
+ /* display_out-enable */
+ writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_DISP_OUT_EN,
+ regs + REG_LCM_DCCS);
+ /* va-enable*/
+ writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_VA_EN,
+ regs + REG_LCM_DCCS);
+ } else if (lcdirq & LCM_INT_CS_UNDERRUN_INT) {
+ writel(readl(irq_base) | LCM_INT_CS_UNDERRUN_INT, irq_base);
+ } else if (lcdirq & LCM_INT_CS_BUS_ERROR_INT) {
+ writel(readl(irq_base) | LCM_INT_CS_BUS_ERROR_INT, irq_base);
+ }
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_CPU_FREQ
+
+static int nuc900fb_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct nuc900fb_info *info;
+ struct fb_info *fbinfo;
+ long delta_f;
+ info = container_of(nb, struct nuc900fb_info, freq_transition);
+ fbinfo = platform_get_drvdata(to_platform_device(info->dev));
+
+ delta_f = info->clk_rate - clk_get_rate(info->clk);
+
+ if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) ||
+ (val == CPUFREQ_PRECHANGE && delta_f < 0)) {
+ info->clk_rate = clk_get_rate(info->clk);
+ nuc900fb_activate_var(fbinfo);
+ }
+
+ return 0;
+}
+
+static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
+{
+ fbi->freq_transition.notifier_call = nuc900fb_cpufreq_transition;
+ return cpufreq_register_notifier(&fbi->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *fbi)
+{
+ cpufreq_unregister_notifier(&fbi->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+#else
+static inline int nuc900fb_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ return 0;
+}
+
+static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
+{
+ return 0;
+}
+
+static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *info)
+{
+}
+#endif
+
+static char driver_name[] = "nuc900fb";
+
+static int __devinit nuc900fb_probe(struct platform_device *pdev)
+{
+ struct nuc900fb_info *fbi;
+ struct nuc900fb_display *display;
+ struct fb_info *fbinfo;
+ struct nuc900fb_mach_info *mach_info;
+ struct resource *res;
+ int ret;
+ int irq;
+ int i;
+ int size;
+
+ dev_dbg(&pdev->dev, "devinit\n");
+ mach_info = pdev->dev.platform_data;
+ if (mach_info == NULL) {
+ dev_err(&pdev->dev,
+ "no platform data for lcd, cannot attach\n");
+ return -EINVAL;
+ }
+
+ if (mach_info->default_display > mach_info->num_displays) {
+ dev_err(&pdev->dev,
+ "default display No. is %d but only %d displays \n",
+ mach_info->default_display, mach_info->num_displays);
+ return -EINVAL;
+ }
+
+
+ display = mach_info->displays + mach_info->default_display;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no irq for device\n");
+ return -ENOENT;
+ }
+
+ fbinfo = framebuffer_alloc(sizeof(struct nuc900fb_info), &pdev->dev);
+ if (!fbinfo)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, fbinfo);
+
+ fbi = fbinfo->par;
+ fbi->dev = &pdev->dev;
+
+#ifdef CONFIG_CPU_NUC950
+ fbi->drv_type = LCDDRV_NUC950;
+#endif
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ size = (res->end - res->start) + 1;
+ fbi->mem = request_mem_region(res->start, size, pdev->name);
+ if (fbi->mem == NULL) {
+ dev_err(&pdev->dev, "failed to alloc memory region\n");
+ ret = -ENOENT;
+ goto free_fb;
+ }
+
+ fbi->io = ioremap(res->start, size);
+ if (fbi->io == NULL) {
+ dev_err(&pdev->dev, "ioremap() of lcd registers failed\n");
+ ret = -ENXIO;
+ goto release_mem_region;
+ }
+
+ fbi->irq_base = fbi->io + REG_LCM_INT_CS;
+
+
+ /* Stop the LCD */
+ writel(0, fbi->io + REG_LCM_DCCS);
+
+ /* fill the fbinfo*/
+ strcpy(fbinfo->fix.id, driver_name);
+ fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
+ fbinfo->fix.type_aux = 0;
+ fbinfo->fix.xpanstep = 0;
+ fbinfo->fix.ypanstep = 0;
+ fbinfo->fix.ywrapstep = 0;
+ fbinfo->fix.accel = FB_ACCEL_NONE;
+ fbinfo->var.nonstd = 0;
+ fbinfo->var.activate = FB_ACTIVATE_NOW;
+ fbinfo->var.accel_flags = 0;
+ fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
+ fbinfo->fbops = &nuc900fb_ops;
+ fbinfo->flags = FBINFO_FLAG_DEFAULT;
+ fbinfo->pseudo_palette = &fbi->pseudo_pal;
+
+ ret = request_irq(irq, nuc900fb_irqhandler, IRQF_DISABLED,
+ pdev->name, fbinfo);
+ if (ret) {
+ dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n",
+ irq, ret);
+ ret = -EBUSY;
+ goto release_regs;
+ }
+
+ nuc900_driver_clksrc_div(&pdev->dev, "ext", 0x2);
+
+ fbi->clk = clk_get(&pdev->dev, NULL);
+ if (!fbi->clk || IS_ERR(fbi->clk)) {
+ printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n");
+ ret = -ENOENT;
+ goto release_irq;
+ }
+
+ clk_enable(fbi->clk);
+ dev_dbg(&pdev->dev, "got and enabled clock\n");
+
+ fbi->clk_rate = clk_get_rate(fbi->clk);
+
+ /* calutate the video buffer size */
+ for (i = 0; i < mach_info->num_displays; i++) {
+ unsigned long smem_len = mach_info->displays[i].xres;
+ smem_len *= mach_info->displays[i].yres;
+ smem_len *= mach_info->displays[i].bpp;
+ smem_len >>= 3;
+ if (fbinfo->fix.smem_len < smem_len)
+ fbinfo->fix.smem_len = smem_len;
+ }
+
+ /* Initialize Video Memory */
+ ret = nuc900fb_map_video_memory(fbinfo);
+ if (ret) {
+ printk(KERN_ERR "Failed to allocate video RAM: %x\n", ret);
+ goto release_clock;
+ }
+
+ dev_dbg(&pdev->dev, "got video memory\n");
+
+ fbinfo->var.xres = display->xres;
+ fbinfo->var.yres = display->yres;
+ fbinfo->var.bits_per_pixel = display->bpp;
+
+ nuc900fb_init_registers(fbinfo);
+
+ nuc900fb_check_var(&fbinfo->var, fbinfo);
+
+ ret = nuc900fb_cpufreq_register(fbi);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register cpufreq\n");
+ goto free_video_memory;
+ }
+
+ ret = register_framebuffer(fbinfo);
+ if (ret) {
+ printk(KERN_ERR "failed to register framebuffer device: %d\n",
+ ret);
+ goto free_cpufreq;
+ }
+
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
+ fbinfo->node, fbinfo->fix.id);
+
+ return 0;
+
+free_cpufreq:
+ nuc900fb_cpufreq_deregister(fbi);
+free_video_memory:
+ nuc900fb_unmap_video_memory(fbinfo);
+release_clock:
+ clk_disable(fbi->clk);
+ clk_put(fbi->clk);
+release_irq:
+ free_irq(irq, fbi);
+release_regs:
+ iounmap(fbi->io);
+release_mem_region:
+ release_mem_region((unsigned long)fbi->mem, size);
+free_fb:
+ framebuffer_release(fbinfo);
+ return ret;
+}
+
+/*
+ * shutdown the lcd controller
+ */
+static void nuc900fb_stop_lcd(struct fb_info *info)
+{
+ struct nuc900fb_info *fbi = info->par;
+ void __iomem *regs = fbi->io;
+
+ writel((~LCM_DCCS_DISP_INT_EN) | (~LCM_DCCS_VA_EN) | (~LCM_DCCS_OSD_EN),
+ regs + REG_LCM_DCCS);
+}
+
+/*
+ * Cleanup
+ */
+static int nuc900fb_remove(struct platform_device *pdev)
+{
+ struct fb_info *fbinfo = platform_get_drvdata(pdev);
+ struct nuc900fb_info *fbi = fbinfo->par;
+ int irq;
+
+ nuc900fb_stop_lcd(fbinfo);
+ msleep(1);
+
+ nuc900fb_unmap_video_memory(fbinfo);
+
+ iounmap(fbi->io);
+
+ irq = platform_get_irq(pdev, 0);
+ free_irq(irq, fbi);
+
+ release_resource(fbi->mem);
+ kfree(fbi->mem);
+
+ platform_set_drvdata(pdev, NULL);
+ framebuffer_release(fbinfo);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+/*
+ * suspend and resume support for the lcd controller
+ */
+
+static int nuc900fb_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct fb_info *fbinfo = platform_get_drvdata(dev);
+ struct nuc900fb_info *info = fbinfo->par;
+
+ nuc900fb_stop_lcd();
+ msleep(1);
+ clk_disable(info->clk);
+ return 0;
+}
+
+static int nuc900fb_resume(struct platform_device *dev)
+{
+ struct fb_info *fbinfo = platform_get_drvdata(dev);
+ struct nuc900fb_info *fbi = fbinfo->par;
+
+ printk(KERN_INFO "nuc900fb resume\n");
+
+ clk_enable(fbi->clk);
+ msleep(1);
+
+ nuc900fb_init_registers(fbinfo);
+ nuc900fb_activate_var(bfinfo);
+
+ return 0;
+}
+
+#else
+#define nuc900fb_suspend NULL
+#define nuc900fb_resume NULL
+#endif
+
+static struct platform_driver nuc900fb_driver = {
+ .probe = nuc900fb_probe,
+ .remove = nuc900fb_remove,
+ .suspend = nuc900fb_suspend,
+ .resume = nuc900fb_resume,
+ .driver = {
+ .name = "nuc900-lcd",
+ .owner = THIS_MODULE,
+ },
+};
+
+int __devinit nuc900fb_init(void)
+{
+ return platform_driver_register(&nuc900fb_driver);
+}
+
+static void __exit nuc900fb_cleanup(void)
+{
+ platform_driver_unregister(&nuc900fb_driver);
+}
+
+module_init(nuc900fb_init);
+module_exit(nuc900fb_cleanup);
+
+MODULE_DESCRIPTION("Framebuffer driver for the NUC900");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/nuc900fb.h b/drivers/video/nuc900fb.h
new file mode 100644
index 00000000000..6c23aa3d3b8
--- /dev/null
+++ b/drivers/video/nuc900fb.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 2009 Nuvoton technology 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Auther:
+ * Wang Qiang(rurality.linux@gmail.com) 2009/12/16
+ */
+
+#ifndef __NUC900FB_H
+#define __NUC900FB_H
+
+#include <mach/map.h>
+#include <mach/fb.h>
+
+enum nuc900_lcddrv_type {
+ LCDDRV_NUC910,
+ LCDDRV_NUC930,
+ LCDDRV_NUC932,
+ LCDDRV_NUC950,
+ LCDDRV_NUC960,
+};
+
+
+#define PALETTE_BUFFER_SIZE 256
+#define PALETTE_BUFF_CLEAR (0x80000000) /* entry is clear/invalid */
+
+struct nuc900fb_info {
+ struct device *dev;
+ struct clk *clk;
+
+ struct resource *mem;
+ void __iomem *io;
+ void __iomem *irq_base;
+ int drv_type;
+ struct nuc900fb_hw regs;
+ unsigned long clk_rate;
+
+#ifdef CONFIG_CPU_FREQ
+ struct notifier_block freq_transition;
+#endif
+
+ /* keep these registers in case we need to re-write palette */
+ u32 palette_buffer[PALETTE_BUFFER_SIZE];
+ u32 pseudo_pal[16];
+};
+
+int nuc900fb_init(void);
+
+#endif /* __NUC900FB_H */
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index 443e3c85a9a..2fb552a6f32 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -94,6 +94,7 @@ static struct backlight_ops nvidia_bl_ops = {
void nvidia_bl_init(struct nvidia_par *par)
{
+ struct backlight_properties props;
struct fb_info *info = pci_get_drvdata(par->pci_dev);
struct backlight_device *bd;
char name[12];
@@ -109,7 +110,10 @@ void nvidia_bl_init(struct nvidia_par *par)
snprintf(name, sizeof(name), "nvidiabl%d", info->node);
- bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+ bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops,
+ &props);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
printk(KERN_WARNING "nvidia: Backlight registration failed\n");
@@ -121,7 +125,6 @@ void nvidia_bl_init(struct nvidia_par *par)
0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
- bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
bd->props.brightness = bd->props.max_brightness;
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 6aaddb4f678..d7994a17324 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/fb.h>
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 73afd7eb997..3bc13df4b12 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/fb.h>
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index eef2bb298d9..2f2e162134f 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -50,6 +50,7 @@
#include <video/vga.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "nv_type.h"
#include "nv_local.h"
#include "nv_proto.h"
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index b043ac83c41..61f8b8f919b 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index e192b058a68..529483467ab 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -25,6 +25,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <plat/sram.h>
#include <plat/board.h>
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
index abe1c76a325..64dcc7439c9 100644
--- a/drivers/video/omap/lcd_mipid.c
+++ b/drivers/video/omap/lcd_mipid.c
@@ -20,6 +20,7 @@
*/
#include <linux/device.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/spi/spi.h>
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index a33483910dc..43ab7d8b66b 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
#include <linux/clk.h>
+#include <linux/gfp.h>
#include <mach/lcdc.h>
#include <plat/dma.h>
@@ -389,7 +390,7 @@ static int omap_lcdc_enable_plane(int plane, int enable)
/*
* Configure the LCD DMA for a palette load operation and do the palette
* downloading synchronously. We don't use the frame+palette load mode of
- * the controller, since the palette can always be downloaded seperately.
+ * the controller, since the palette can always be downloaded separately.
*/
static void load_palette(void)
{
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 8ce60e1b220..e264efd0278 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -26,6 +26,7 @@
*/
#include <linux/platform_device.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include <plat/dma.h>
diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c
index c59e4baed8b..300eff5de1b 100644
--- a/drivers/video/omap2/displays/panel-generic.c
+++ b/drivers/video/omap2/displays/panel-generic.c
@@ -116,6 +116,24 @@ static int generic_panel_resume(struct omap_dss_device *dssdev)
return 0;
}
+static void generic_panel_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ dpi_set_timings(dssdev, timings);
+}
+
+static void generic_panel_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ *timings = dssdev->panel.timings;
+}
+
+static int generic_panel_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ return dpi_check_timings(dssdev, timings);
+}
+
static struct omap_dss_driver generic_driver = {
.probe = generic_panel_probe,
.remove = generic_panel_remove,
@@ -125,6 +143,10 @@ static struct omap_dss_driver generic_driver = {
.suspend = generic_panel_suspend,
.resume = generic_panel_resume,
+ .set_timings = generic_panel_set_timings,
+ .get_timings = generic_panel_get_timings,
+ .check_timings = generic_panel_check_timings,
+
.driver = {
.name = "generic_panel",
.owner = THIS_MODULE,
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index fcd6a61a91e..4f3988a4108 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -30,6 +30,7 @@
#include <linux/gpio.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include <plat/display.h>
@@ -486,6 +487,7 @@ static struct attribute_group taal_attr_group = {
static int taal_probe(struct omap_dss_device *dssdev)
{
+ struct backlight_properties props;
struct taal_data *td;
struct backlight_device *bldev;
int r;
@@ -520,11 +522,16 @@ static int taal_probe(struct omap_dss_device *dssdev)
/* if no platform set_backlight() defined, presume DSI backlight
* control */
+ memset(&props, 0, sizeof(struct backlight_properties));
if (!dssdev->set_backlight)
td->use_dsi_bl = true;
+ if (td->use_dsi_bl)
+ props.max_brightness = 255;
+ else
+ props.max_brightness = 127;
bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
- &taal_bl_ops);
+ &taal_bl_ops, &props);
if (IS_ERR(bldev)) {
r = PTR_ERR(bldev);
goto err2;
@@ -534,13 +541,10 @@ static int taal_probe(struct omap_dss_device *dssdev)
bldev->props.fb_blank = FB_BLANK_UNBLANK;
bldev->props.power = FB_BLANK_UNBLANK;
- if (td->use_dsi_bl) {
- bldev->props.max_brightness = 255;
+ if (td->use_dsi_bl)
bldev->props.brightness = 255;
- } else {
- bldev->props.max_brightness = 127;
+ else
bldev->props.brightness = 127;
- }
taal_bl_update_status(bldev);
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index d578feee355..e866e76b13d 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -15,6 +15,7 @@
#include <linux/regulator/consumer.h>
#include <linux/gpio.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <plat/display.h>
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 8254a4232a5..54344184dd7 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -590,6 +590,9 @@ int dss_init(bool skip_init)
}
}
+ dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
+ dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
+
dss_save_context();
rev = dss_read_reg(DSS_REVISION);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 913142d4cab..0820986d4a6 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -23,6 +23,7 @@
#define DSS_SUBSYS_NAME "MANAGER"
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
@@ -341,7 +342,7 @@ static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
return manager_attr->store(manager, buf, size);
}
-static struct sysfs_ops manager_sysfs_ops = {
+static const struct sysfs_ops manager_sysfs_ops = {
.show = manager_attr_show,
.store = manager_attr_store,
};
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 0c5bea263ac..82336583ade 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -29,6 +29,7 @@
#include <linux/kobject.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <plat/display.h>
#include <plat/cpu.h>
@@ -320,7 +321,7 @@ static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
return overlay_attr->store(overlay, buf, size);
}
-static struct sysfs_ops overlay_sysfs_ops = {
+static const struct sysfs_ops overlay_sysfs_ops = {
.show = overlay_attr_show,
.store = overlay_attr_store,
};
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 4a76917b7cc..4b4506da96d 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 55a4de5e5d1..3b1237ad85e 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/bootmem.h>
#include <linux/completion.h>
@@ -511,13 +512,14 @@ static u32 omap_vram_sdram_size __initdata;
static u32 omap_vram_def_sdram_size __initdata;
static u32 omap_vram_def_sdram_start __initdata;
-static void __init omap_vram_early_vram(char **p)
+static int __init omap_vram_early_vram(char *p)
{
- omap_vram_def_sdram_size = memparse(*p, p);
- if (**p == ',')
- omap_vram_def_sdram_start = simple_strtoul((*p) + 1, p, 16);
+ omap_vram_def_sdram_size = memparse(p, &p);
+ if (*p == ',')
+ omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16);
+ return 0;
}
-__early_param("vram=", omap_vram_early_vram);
+early_param("vram", omap_vram_early_vram);
/*
* Called from map_io. We need to call to this early enough so that we
diff --git a/drivers/video/output.c b/drivers/video/output.c
index 5137aa016b8..0d6f2cda936 100644
--- a/drivers/video/output.c
+++ b/drivers/video/output.c
@@ -23,6 +23,7 @@
*/
#include <linux/module.h>
#include <linux/video_output.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/ctype.h>
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 7fa4ab01b0d..81440f2b909 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 0a366d86f08..8a204e7a5b5 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -24,7 +24,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 36436ee6c1a..27f93aab6dd 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -896,7 +896,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
* Pseudocolor:
* uses offset = 0 && length = DAC register width.
* var->{color}.offset is 0
- * var->{color}.length contains widht of DAC
+ * var->{color}.length contains width of DAC
* cmap is not used
* DAC[X] is programmed to (red, green, blue)
* Truecolor:
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/pmag-aa-fb.c
index 6515ec11c16..838424817de 100644
--- a/drivers/video/pmag-aa-fb.c
+++ b/drivers/video/pmag-aa-fb.c
@@ -28,7 +28,6 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
index 4db6b48a871..b2252fea285 100644
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -18,7 +18,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
index 2aa09bce394..5ec4f2d439c 100644
--- a/drivers/video/pnx4008/sdum.c
+++ b/drivers/video/pnx4008/sdum.c
@@ -20,7 +20,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -29,6 +28,7 @@
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <mach/gpio.h>
diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c
index 75285d3f393..c91a7f70f7b 100644
--- a/drivers/video/pxa168fb.c
+++ b/drivers/video/pxa168fb.c
@@ -668,7 +668,7 @@ static int __init pxa168fb_probe(struct platform_device *pdev)
/*
* Map LCD controller registers.
*/
- fbi->reg_base = ioremap_nocache(res->start, res->end - res->start);
+ fbi->reg_base = ioremap_nocache(res->start, resource_size(res));
if (fbi->reg_base == NULL) {
ret = -ENOMEM;
goto failed;
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index 4beac1df617..fc32c323a38 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -14,7 +14,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
@@ -85,7 +84,7 @@ static struct fb_ops q40fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __init q40fb_probe(struct platform_device *dev)
+static int __devinit q40fb_probe(struct platform_device *dev)
{
struct fb_info *info;
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index d94c57ffbdb..618f36bec10 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -338,6 +338,7 @@ static struct backlight_ops riva_bl_ops = {
static void riva_bl_init(struct riva_par *par)
{
+ struct backlight_properties props;
struct fb_info *info = pci_get_drvdata(par->pdev);
struct backlight_device *bd;
char name[12];
@@ -353,7 +354,10 @@ static void riva_bl_init(struct riva_par *par)
snprintf(name, sizeof(name), "rivabl%d", info->node);
- bd = backlight_device_register(name, info->dev, par, &riva_bl_ops);
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+ bd = backlight_device_register(name, info->dev, par, &riva_bl_ops,
+ &props);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
printk(KERN_WARNING "riva: Backlight registration failed\n");
@@ -365,7 +369,6 @@ static void riva_bl_init(struct riva_par *par)
MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
FB_BACKLIGHT_MAX);
- bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
bd->props.brightness = bd->props.max_brightness;
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index 0deb0a8867b..a6247fc081a 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -31,6 +31,7 @@
#include <linux/fb.h>
#include <linux/spinlock_types.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <asm/io.h>
@@ -517,12 +518,12 @@ s1d13xxxfb_bitblt_copyarea(struct fb_info *info, const struct fb_copyarea *area)
src = (sy * stride) + (bpp * sx);
}
- /* set source adress */
+ /* set source address */
s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff));
s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff);
s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff);
- /* set destination adress */
+ /* set destination address */
s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff));
s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff);
s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff);
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 53cb722c45a..9682ecc60e1 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -16,8 +16,8 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <linux/init.h>
-#include <linux/gfp.h>
#include <linux/clk.h>
#include <linux/fb.h>
#include <linux/io.h>
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index aac661225c7..2b094dec4a5 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -1004,12 +1004,12 @@ dealloc_fb:
return ret;
}
-static int __init s3c2410fb_probe(struct platform_device *pdev)
+static int __devinit s3c2410fb_probe(struct platform_device *pdev)
{
return s3c24xxfb_probe(pdev, DRV_S3C2410);
}
-static int __init s3c2412fb_probe(struct platform_device *pdev)
+static int __devinit s3c2412fb_probe(struct platform_device *pdev)
{
return s3c24xxfb_probe(pdev, DRV_S3C2412);
}
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index c3fad34309e..d4471b4c037 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/svga.h>
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index cdaa873a605..e8b76d65a07 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1435,7 +1435,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
return fbi;
}
-static int __init sa1100fb_probe(struct platform_device *pdev)
+static int __devinit sa1100fb_probe(struct platform_device *pdev)
{
struct sa1100fb_info *fbi;
int ret, irq;
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 574b29e9f8f..ed371c868b3 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/fb.h>
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index f86012239bf..7a3a5e28eca 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -745,7 +745,7 @@ int __init sgivwfb_setup(char *options)
/*
* Initialisation
*/
-static int __init sgivwfb_probe(struct platform_device *dev)
+static int __devinit sgivwfb_probe(struct platform_device *dev)
{
struct sgivw_par *par;
struct fb_info *info;
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index 9f6d6e61f0c..bea38fce247 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <asm/sh7760fb.h>
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 8d7653e56df..e14bd074912 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/ioctl.h>
+#include <linux/slab.h>
#include <video/sh_mobile_lcdc.h>
#include <asm/atomic.h>
@@ -943,7 +944,7 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
static int sh_mobile_lcdc_remove(struct platform_device *pdev);
-static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
+static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
{
struct fb_info *info;
struct sh_mobile_lcdc_priv *priv;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 9d2b6bc4903..a531a0f7cdf 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -1891,9 +1891,6 @@ static struct fb_ops sisfb_ops = {
.fb_fillrect = fbcon_sis_fillrect,
.fb_copyarea = fbcon_sis_copyarea,
.fb_imageblit = cfb_imageblit,
-#ifdef CONFIG_FB_SOFT_CURSOR
- .fb_cursor = soft_cursor,
-#endif
.fb_sync = fbcon_sis_sync,
#ifdef SIS_NEW_CONFIG_COMPAT
.fb_compat_ioctl= sisfb_ioctl,
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 35370d0ecf0..b7dc1800efa 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -411,7 +411,7 @@ static int sm501fb_set_par_common(struct fb_info *info,
struct sm501fb_par *par = info->par;
struct sm501fb_info *fbi = par->info;
unsigned long pixclock; /* pixelclock in Hz */
- unsigned long sm501pixclock; /* pixelclock the 501 can achive in Hz */
+ unsigned long sm501pixclock; /* pixelclock the 501 can achieve in Hz */
unsigned int mem_type;
unsigned int clock_type;
unsigned int head_addr;
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 609d0a521ca..dee64c3b1e6 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -86,7 +86,6 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#include <video/sstfb.h>
@@ -1102,7 +1101,7 @@ static void sst_set_vidmod_ics(struct fb_info *info, const int bpp)
* detect dac type
* prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset,
* dram refresh disabled, FbiInit remaped.
- * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ...
+ * TODO: mmh.. maybe i should put the "prerequisite" in the func ...
*/
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c
new file mode 100644
index 00000000000..23e69e834a1
--- /dev/null
+++ b/drivers/video/sunxvr1000.c
@@ -0,0 +1,227 @@
+/* sunxvr1000.c: Sun XVR-1000 driver for sparc64 systems
+ *
+ * Copyright (C) 2010 David S. Miller (davem@davemloft.net)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/of_device.h>
+
+struct gfb_info {
+ struct fb_info *info;
+
+ char __iomem *fb_base;
+ unsigned long fb_base_phys;
+
+ struct device_node *of_node;
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int depth;
+ unsigned int fb_size;
+
+ u32 pseudo_palette[16];
+};
+
+static int __devinit gfb_get_props(struct gfb_info *gp)
+{
+ gp->width = of_getintprop_default(gp->of_node, "width", 0);
+ gp->height = of_getintprop_default(gp->of_node, "height", 0);
+ gp->depth = of_getintprop_default(gp->of_node, "depth", 32);
+
+ if (!gp->width || !gp->height) {
+ printk(KERN_ERR "gfb: Critical properties missing for %s\n",
+ gp->of_node->full_name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int gfb_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
+{
+ u32 value;
+
+ if (regno < 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ value = (blue << 16) | (green << 8) | red;
+ ((u32 *)info->pseudo_palette)[regno] = value;
+ }
+
+ return 0;
+}
+
+static struct fb_ops gfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = gfb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+static int __devinit gfb_set_fbinfo(struct gfb_info *gp)
+{
+ struct fb_info *info = gp->info;
+ struct fb_var_screeninfo *var = &info->var;
+
+ info->flags = FBINFO_DEFAULT;
+ info->fbops = &gfb_ops;
+ info->screen_base = gp->fb_base;
+ info->screen_size = gp->fb_size;
+
+ info->pseudo_palette = gp->pseudo_palette;
+
+ /* Fill fix common fields */
+ strlcpy(info->fix.id, "gfb", sizeof(info->fix.id));
+ info->fix.smem_start = gp->fb_base_phys;
+ info->fix.smem_len = gp->fb_size;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ if (gp->depth == 32 || gp->depth == 24)
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ else
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ var->xres = gp->width;
+ var->yres = gp->height;
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres;
+ var->bits_per_pixel = gp->depth;
+
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 16;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+
+ if (fb_alloc_cmap(&info->cmap, 256, 0)) {
+ printk(KERN_ERR "gfb: Cannot allocate color map.\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int __devinit gfb_probe(struct of_device *op,
+ const struct of_device_id *match)
+{
+ struct device_node *dp = op->node;
+ struct fb_info *info;
+ struct gfb_info *gp;
+ int err;
+
+ info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev);
+ if (!info) {
+ printk(KERN_ERR "gfb: Cannot allocate fb_info\n");
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ gp = info->par;
+ gp->info = info;
+ gp->of_node = dp;
+
+ gp->fb_base_phys = op->resource[6].start;
+
+ err = gfb_get_props(gp);
+ if (err)
+ goto err_release_fb;
+
+ /* Framebuffer length is the same regardless of resolution. */
+ info->fix.line_length = 16384;
+ gp->fb_size = info->fix.line_length * gp->height;
+
+ gp->fb_base = of_ioremap(&op->resource[6], 0,
+ gp->fb_size, "gfb fb");
+ if (!gp->fb_base)
+ goto err_release_fb;
+
+ err = gfb_set_fbinfo(gp);
+ if (err)
+ goto err_unmap_fb;
+
+ printk("gfb: Found device at %s\n", dp->full_name);
+
+ err = register_framebuffer(info);
+ if (err < 0) {
+ printk(KERN_ERR "gfb: Could not register framebuffer %s\n",
+ dp->full_name);
+ goto err_unmap_fb;
+ }
+
+ dev_set_drvdata(&op->dev, info);
+
+ return 0;
+
+err_unmap_fb:
+ of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size);
+
+err_release_fb:
+ framebuffer_release(info);
+
+err_out:
+ return err;
+}
+
+static int __devexit gfb_remove(struct of_device *op)
+{
+ struct fb_info *info = dev_get_drvdata(&op->dev);
+ struct gfb_info *gp = info->par;
+
+ unregister_framebuffer(info);
+
+ iounmap(gp->fb_base);
+
+ of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size);
+
+ framebuffer_release(info);
+
+ dev_set_drvdata(&op->dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id gfb_match[] = {
+ {
+ .name = "SUNW,gfb",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ffb_match);
+
+static struct of_platform_driver gfb_driver = {
+ .name = "gfb",
+ .match_table = gfb_match,
+ .probe = gfb_probe,
+ .remove = __devexit_p(gfb_remove),
+};
+
+static int __init gfb_init(void)
+{
+ if (fb_get_options("gfb", NULL))
+ return -ENODEV;
+
+ return of_register_driver(&gfb_driver, &of_bus_type);
+}
+
+static void __exit gfb_exit(void)
+{
+ of_unregister_driver(&gfb_driver);
+}
+
+module_init(gfb_init);
+module_exit(gfb_exit);
+
+MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c
index b1dde09e701..5848436c19d 100644
--- a/drivers/video/sunxvr2500.c
+++ b/drivers/video/sunxvr2500.c
@@ -5,7 +5,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/pci.h>
#include <linux/init.h>
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index 4cd50497264..b9c2b948d34 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -5,7 +5,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/pci.h>
#include <linux/init.h>
@@ -242,11 +241,27 @@ static int __devinit e3d_set_fbinfo(struct e3d_info *ep)
static int __devinit e3d_pci_register(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+ struct device_node *of_node;
+ const char *device_type;
struct fb_info *info;
struct e3d_info *ep;
unsigned int line_length;
int err;
+ of_node = pci_device_to_OF_node(pdev);
+ if (!of_node) {
+ printk(KERN_ERR "e3d: Cannot find OF node of %s\n",
+ pci_name(pdev));
+ return -ENODEV;
+ }
+
+ device_type = of_get_property(of_node, "device_type", NULL);
+ if (!device_type) {
+ printk(KERN_INFO "e3d: Ignoring secondary output device "
+ "at %s\n", pci_name(pdev));
+ return -ENODEV;
+ }
+
err = pci_enable_device(pdev);
if (err < 0) {
printk(KERN_ERR "e3d: Cannot enable PCI device %s\n",
@@ -265,13 +280,7 @@ static int __devinit e3d_pci_register(struct pci_dev *pdev,
ep->info = info;
ep->pdev = pdev;
spin_lock_init(&ep->lock);
- ep->of_node = pci_device_to_OF_node(pdev);
- if (!ep->of_node) {
- printk(KERN_ERR "e3d: Cannot find OF node of %s\n",
- pci_name(pdev));
- err = -ENODEV;
- goto err_release_fb;
- }
+ ep->of_node = of_node;
/* Read the PCI base register of the frame buffer, which we
* need in order to interpret the RAMDAC_VID_*FB* values in
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index 9c710670157..fdb45674e2f 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -15,7 +15,6 @@
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/svga.h>
-#include <linux/slab.h>
#include <asm/types.h>
#include <asm/io.h>
diff --git a/drivers/video/syscopyarea.c b/drivers/video/syscopyarea.c
index a352d5f46bb..844a32fd38e 100644
--- a/drivers/video/syscopyarea.c
+++ b/drivers/video/syscopyarea.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/fb.h>
-#include <linux/slab.h>
#include <asm/types.h>
#include <asm/io.h>
#include "fb_draw.h"
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 45b883598bf..c0c2b18fcdc 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fb.h>
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index a86046ff60a..1b3b1c718e8 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -25,7 +25,6 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/selection.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/tc.h>
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 03a9c35e9f5..c6c77562839 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -19,6 +19,7 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <video/vga.h>
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 54fbb2995a5..7b8839ebf3c 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -18,6 +18,7 @@
#include <linux/fb.h>
#include <linux/io.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <video/edid.h>
#include <video/uvesafb.h>
#ifdef CONFIG_X86
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index c18f1884b55..931a567f9af 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -33,6 +33,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/pci.h>
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index bd37ee1f6a2..0cadf7aee27 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -13,7 +13,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/ioport.h>
@@ -477,7 +476,6 @@ err:
}
static struct platform_driver vesafb_driver = {
- .probe = vesafb_probe,
.driver = {
.name = "vesafb",
},
@@ -493,20 +491,21 @@ static int __init vesafb_init(void)
/* ignore error return of fb_get_options */
fb_get_options("vesafb", &option);
vesafb_setup(option);
- ret = platform_driver_register(&vesafb_driver);
- if (!ret) {
- vesafb_device = platform_device_alloc("vesafb", 0);
+ vesafb_device = platform_device_alloc("vesafb", 0);
+ if (!vesafb_device)
+ return -ENOMEM;
- if (vesafb_device)
- ret = platform_device_add(vesafb_device);
- else
- ret = -ENOMEM;
+ ret = platform_device_add(vesafb_device);
+ if (!ret) {
+ ret = platform_driver_probe(&vesafb_driver, vesafb_probe);
+ if (ret)
+ platform_device_del(vesafb_device);
+ }
- if (ret) {
- platform_device_put(vesafb_device);
- platform_driver_unregister(&vesafb_driver);
- }
+ if (ret) {
+ platform_device_put(vesafb_device);
+ vesafb_device = NULL;
}
return ret;
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 050d432c7d9..9b5532b4de3 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -15,7 +15,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -479,7 +478,7 @@ static int __init vfb_setup(char *options)
* Initialisation
*/
-static int __init vfb_probe(struct platform_device *dev)
+static int __devinit vfb_probe(struct platform_device *dev)
{
struct fb_info *info;
int retval = -ENOMEM;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 5b2938903ac..bf638a47a5b 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -15,7 +15,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/ioport.h>
@@ -1293,7 +1292,7 @@ static int vga16fb_setup(char *options)
}
#endif
-static int __init vga16fb_probe(struct platform_device *dev)
+static int __devinit vga16fb_probe(struct platform_device *dev)
{
struct fb_info *info;
struct vga16fb_par *par;
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
index e533b4b6aba..eeed238ad6a 100644
--- a/drivers/video/via/Makefile
+++ b/drivers/video/via/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_FB_VIA) += viafb.o
-viafb-y :=viafbdev.o hw.o iface.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o
+viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index 474f428aea9..8c06bd3c0b4 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -107,7 +107,6 @@
struct tmds_chip_information {
int tmds_chip_name;
int tmds_chip_slave_addr;
- int dvi_panel_id;
int data_mode;
int output_interface;
int i2c_port;
@@ -142,14 +141,9 @@ struct tmds_setting_information {
int iga_path;
int h_active;
int v_active;
- int bpp;
- int refresh_rate;
- int get_dvi_size_method;
int max_pixel_clock;
- int dvi_panel_size;
- int dvi_panel_hres;
- int dvi_panel_vres;
- int native_size;
+ int max_hres;
+ int max_vres;
};
struct lvds_setting_information {
@@ -160,7 +154,6 @@ struct lvds_setting_information {
int refresh_rate;
int get_lcd_size_method;
int lcd_panel_id;
- int lcd_panel_size;
int lcd_panel_hres;
int lcd_panel_vres;
int display_method;
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index 67b36932212..abe59b8c7a0 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -23,11 +23,10 @@
static void tmds_register_write(int index, u8 data);
static int tmds_register_read(int index);
static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
-static int check_reduce_blanking_mode(int mode_index,
- int refresh_rate);
-static int dvi_get_panel_size_from_DDCv1(void);
-static int dvi_get_panel_size_from_DDCv2(void);
-static unsigned char dvi_get_panel_info(void);
+static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information
+ *tmds_chip, struct tmds_setting_information *tmds_setting);
+static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information
+ *tmds_chip, struct tmds_setting_information *tmds_setting);
static int viafb_dvi_query_EDID(void);
static int check_tmds_chip(int device_id_subaddr, int device_id)
@@ -38,23 +37,24 @@ static int check_tmds_chip(int device_id_subaddr, int device_id)
return FAIL;
}
-void viafb_init_dvi_size(void)
+void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
+ struct tmds_setting_information *tmds_setting)
{
DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
- DEBUG_MSG(KERN_INFO
- "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
- viaparinfo->tmds_setting_info->get_dvi_size_method);
- switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
- case GET_DVI_SIZE_BY_SYSTEM_BIOS:
+ viafb_dvi_sense();
+ switch (viafb_dvi_query_EDID()) {
+ case 1:
+ dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting);
break;
- case GET_DVI_SZIE_BY_HW_STRAPPING:
+ case 2:
+ dvi_get_panel_size_from_DDCv2(tmds_chip, tmds_setting);
break;
- case GET_DVI_SIZE_BY_VGA_BIOS:
default:
- dvi_get_panel_info();
+ printk(KERN_WARNING "viafb_init_dvi_size: DVI panel size undetected!\n");
break;
}
+
return;
}
@@ -189,42 +189,14 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
return 0;
}
-static int check_reduce_blanking_mode(int mode_index,
- int refresh_rate)
-{
- if (refresh_rate != 60)
- return false;
-
- switch (mode_index) {
- /* Following modes have reduce blanking mode. */
- case VIA_RES_1360X768:
- case VIA_RES_1400X1050:
- case VIA_RES_1440X900:
- case VIA_RES_1600X900:
- case VIA_RES_1680X1050:
- case VIA_RES_1920X1080:
- case VIA_RES_1920X1200:
- break;
-
- default:
- DEBUG_MSG(KERN_INFO
- "This dvi mode %d have no reduce blanking mode!\n",
- mode_index);
- return false;
- }
-
- return true;
-}
-
/* DVI Set Mode */
-void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
+void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
+ int set_iga)
{
- struct VideoModeTable *videoMode = NULL;
+ struct VideoModeTable *rb_mode;
struct crt_mode_table *pDviTiming;
unsigned long desirePixelClock, maxPixelClock;
- int status = 0;
- videoMode = viafb_get_modetbl_pointer(video_index);
- pDviTiming = videoMode->crtc;
+ pDviTiming = mode->crtc;
desirePixelClock = pDviTiming->clk / 1000000;
maxPixelClock = (unsigned long)viaparinfo->
tmds_setting_info->max_pixel_clock;
@@ -232,20 +204,14 @@ void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
- /*Check if reduce-blanking mode is exist */
- status =
- check_reduce_blanking_mode(video_index,
- pDviTiming->refresh_rate);
- if (status) {
- video_index += 100; /*Use reduce-blanking mode */
- videoMode = viafb_get_modetbl_pointer(video_index);
- pDviTiming = videoMode->crtc;
- DEBUG_MSG(KERN_INFO
- "DVI use reduce blanking mode %d!!\n",
- video_index);
+ rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr,
+ mode->crtc[0].crtc.ver_addr);
+ if (rb_mode) {
+ mode = rb_mode;
+ pDviTiming = rb_mode->crtc;
}
}
- viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
+ viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga);
viafb_set_output_path(DEVICE_DVI, set_iga,
viaparinfo->chip_info->tmds_chip_info.output_interface);
}
@@ -350,25 +316,18 @@ static int viafb_dvi_query_EDID(void)
return false;
}
-/*
- *
- * int dvi_get_panel_size_from_DDCv1(void)
- *
- * - Get Panel Size Using EDID1 Table
- *
- * Return Type: int
- *
- */
-static int dvi_get_panel_size_from_DDCv1(void)
+/* Get Panel Size Using EDID1 Table */
+static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information
+ *tmds_chip, struct tmds_setting_information *tmds_setting)
{
- int i, max_h = 0, max_v = 0, tmp, restore;
+ int i, max_h = 0, tmp, restore;
unsigned char rData;
unsigned char EDID_DATA[18];
DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
- restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
- viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+ restore = tmds_chip->tmds_chip_slave_addr;
+ tmds_chip->tmds_chip_slave_addr = 0xA0;
rData = tmds_register_read(0x23);
if (rData & 0x3C)
@@ -414,8 +373,8 @@ static int dvi_get_panel_size_from_DDCv1(void)
/* The first two byte must be zero. */
if (EDID_DATA[3] == 0xFD) {
/* To get max pixel clock. */
- viaparinfo->tmds_setting_info->
- max_pixel_clock = EDID_DATA[9] * 10;
+ tmds_setting->max_pixel_clock =
+ EDID_DATA[9] * 10;
}
}
break;
@@ -425,154 +384,88 @@ static int dvi_get_panel_size_from_DDCv1(void)
}
}
+ tmds_setting->max_hres = max_h;
switch (max_h) {
case 640:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_640X480;
+ tmds_setting->max_vres = 480;
break;
case 800:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_800X600;
+ tmds_setting->max_vres = 600;
break;
case 1024:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1024X768;
+ tmds_setting->max_vres = 768;
break;
case 1280:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1280X1024;
+ tmds_setting->max_vres = 1024;
break;
case 1400:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1400X1050;
+ tmds_setting->max_vres = 1050;
break;
case 1440:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1440X1050;
+ tmds_setting->max_vres = 1050;
break;
case 1600:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1600X1200;
+ tmds_setting->max_vres = 1200;
break;
case 1920:
- if (max_v == 1200) {
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1920X1200;
- } else {
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1920X1080;
- }
-
+ tmds_setting->max_vres = 1080;
break;
default:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1024X768;
- DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\
- set default panel size.\n", max_h);
+ DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d ! "
+ "set default panel size.\n", max_h);
break;
}
DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
- viaparinfo->tmds_setting_info->max_pixel_clock);
- viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
- return viaparinfo->tmds_setting_info->dvi_panel_size;
+ tmds_setting->max_pixel_clock);
+ tmds_chip->tmds_chip_slave_addr = restore;
}
-/*
- *
- * int dvi_get_panel_size_from_DDCv2(void)
- *
- * - Get Panel Size Using EDID2 Table
- *
- * Return Type: int
- *
- */
-static int dvi_get_panel_size_from_DDCv2(void)
+/* Get Panel Size Using EDID2 Table */
+static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information
+ *tmds_chip, struct tmds_setting_information *tmds_setting)
{
- int HSize = 0, restore;
+ int restore;
unsigned char R_Buffer[2];
DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
- restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
- viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
+ restore = tmds_chip->tmds_chip_slave_addr;
+ tmds_chip->tmds_chip_slave_addr = 0xA2;
/* Horizontal: 0x76, 0x77 */
tmds_register_read_bytes(0x76, R_Buffer, 2);
- HSize = R_Buffer[0];
- HSize += R_Buffer[1] << 8;
+ tmds_setting->max_hres = R_Buffer[0] + (R_Buffer[1] << 8);
- switch (HSize) {
+ switch (tmds_setting->max_hres) {
case 640:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_640X480;
+ tmds_setting->max_vres = 480;
break;
case 800:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_800X600;
+ tmds_setting->max_vres = 600;
break;
case 1024:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1024X768;
+ tmds_setting->max_vres = 768;
break;
case 1280:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1280X1024;
+ tmds_setting->max_vres = 1024;
break;
case 1400:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1400X1050;
+ tmds_setting->max_vres = 1050;
break;
case 1440:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1440X1050;
+ tmds_setting->max_vres = 1050;
break;
case 1600:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1600X1200;
- break;
- default:
- viaparinfo->tmds_setting_info->dvi_panel_size =
- VIA_RES_1024X768;
- DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\
- set default panel size.\n", HSize);
- break;
- }
-
- viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
- return viaparinfo->tmds_setting_info->dvi_panel_size;
-}
-
-/*
- *
- * unsigned char dvi_get_panel_info(void)
- *
- * - Get Panel Size
- *
- * Return Type: unsigned char
- */
-static unsigned char dvi_get_panel_info(void)
-{
- unsigned char dvipanelsize;
- DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
-
- viafb_dvi_sense();
- switch (viafb_dvi_query_EDID()) {
- case 1:
- dvi_get_panel_size_from_DDCv1();
- break;
- case 2:
- dvi_get_panel_size_from_DDCv2();
+ tmds_setting->max_vres = 1200;
break;
default:
+ DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d! "
+ "set default panel size.\n", tmds_setting->max_hres);
break;
}
- DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
- viaparinfo->tmds_setting_info->dvi_panel_size);
- dvipanelsize = (unsigned char)(viaparinfo->
- tmds_setting_info->dvi_panel_size);
- return dvipanelsize;
+ tmds_chip->tmds_chip_slave_addr = restore;
}
/* If Disable DVI, turn off pad */
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
index e1ec37fb0dc..0dffcfd395f 100644
--- a/drivers/video/via/dvi.h
+++ b/drivers/video/via/dvi.h
@@ -53,12 +53,13 @@
#define DEV_CONNECT_DVI 0x01
#define DEV_CONNECT_HDMI 0x02
-struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index);
int viafb_dvi_sense(void);
void viafb_dvi_disable(void);
void viafb_dvi_enable(void);
int viafb_tmds_trasmitter_identify(void);
-void viafb_init_dvi_size(void);
-void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga);
+void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
+ struct tmds_setting_information *tmds_setting);
+void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp,
+ int set_iga);
#endif /* __DVI_H__ */
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
index b675cdbb03a..1ee511b7330 100644
--- a/drivers/video/via/global.c
+++ b/drivers/video/via/global.c
@@ -23,15 +23,12 @@ int viafb_platform_epia_dvi = STATE_OFF;
int viafb_device_lcd_dualedge = STATE_OFF;
int viafb_bus_width = 12;
int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI;
-int viafb_memsize;
int viafb_DeviceStatus = CRT_Device;
int viafb_hotplug;
int viafb_refresh = 60;
int viafb_refresh1 = 60;
int viafb_lcd_dsp_method = LCD_EXPANDSION;
int viafb_lcd_mode = LCD_OPENLDI;
-int viafb_bpp = 32;
-int viafb_bpp1 = 32;
int viafb_CRT_ON = 1;
int viafb_DVI_ON;
int viafb_LCD_ON ;
@@ -42,8 +39,6 @@ int viafb_hotplug_Xres = 640;
int viafb_hotplug_Yres = 480;
int viafb_hotplug_bpp = 32;
int viafb_hotplug_refresh = 60;
-unsigned int viafb_second_offset;
-int viafb_second_size;
int viafb_primary_dev = None_Device;
unsigned int viafb_second_xres = 640;
unsigned int viafb_second_yres = 480;
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
index d69d0ca99c2..8d95d5fd138 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/via/global.h
@@ -35,7 +35,6 @@
#include "debug.h"
-#include "iface.h"
#include "viafbdev.h"
#include "chip.h"
#include "accel.h"
@@ -68,8 +67,6 @@ extern int viafb_refresh;
extern int viafb_refresh1;
extern int viafb_lcd_dsp_method;
extern int viafb_lcd_mode;
-extern int viafb_bpp;
-extern int viafb_bpp1;
extern int viafb_CRT_ON;
extern int viafb_hotplug_Xres;
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 3e083ff67ae..f2583b1b527 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -524,7 +524,6 @@ static void dvi_patch_skew_dvp1(void);
static void dvi_patch_skew_dvp_low(void);
static void set_dvi_output_path(int set_iga, int output_interface);
static void set_lcd_output_path(int set_iga, int output_interface);
-static int search_mode_setting(int ModeInfoIndex);
static void load_fix_bit_crtc_reg(void);
static void init_gfx_chip_info(struct pci_dev *pdev,
const struct pci_device_id *pdi);
@@ -686,6 +685,84 @@ void viafb_set_secondary_pitch(u32 pitch)
viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80);
}
+void viafb_set_primary_color_depth(u8 depth)
+{
+ u8 value;
+
+ DEBUG_MSG(KERN_DEBUG "viafb_set_primary_color_depth(%d)\n", depth);
+ switch (depth) {
+ case 8:
+ value = 0x00;
+ break;
+ case 15:
+ value = 0x04;
+ break;
+ case 16:
+ value = 0x14;
+ break;
+ case 24:
+ value = 0x0C;
+ break;
+ case 30:
+ value = 0x08;
+ break;
+ default:
+ printk(KERN_WARNING "viafb_set_primary_color_depth: "
+ "Unsupported depth: %d\n", depth);
+ return;
+ }
+
+ viafb_write_reg_mask(0x15, VIASR, value, 0x1C);
+}
+
+void viafb_set_secondary_color_depth(u8 depth)
+{
+ u8 value;
+
+ DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_color_depth(%d)\n", depth);
+ switch (depth) {
+ case 8:
+ value = 0x00;
+ break;
+ case 16:
+ value = 0x40;
+ break;
+ case 24:
+ value = 0xC0;
+ break;
+ case 30:
+ value = 0x80;
+ break;
+ default:
+ printk(KERN_WARNING "viafb_set_secondary_color_depth: "
+ "Unsupported depth: %d\n", depth);
+ return;
+ }
+
+ viafb_write_reg_mask(0x67, VIACR, value, 0xC0);
+}
+
+static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
+{
+ outb(0xFF, 0x3C6); /* bit mask of palette */
+ outb(index, 0x3C8);
+ outb(red, 0x3C9);
+ outb(green, 0x3C9);
+ outb(blue, 0x3C9);
+}
+
+void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue)
+{
+ viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01);
+ set_color_register(index, red, green, blue);
+}
+
+void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
+{
+ viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01);
+ set_color_register(index, red, green, blue);
+}
+
void viafb_set_output_path(int device, int set_iga, int output_interface)
{
switch (device) {
@@ -710,11 +787,8 @@ static void set_crt_output_path(int set_iga)
viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6);
break;
case IGA2:
- case IGA1_IGA2:
viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6);
- if (set_iga == IGA1_IGA2)
- viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
break;
}
}
@@ -904,13 +978,6 @@ static void set_lcd_output_path(int set_iga, int output_interface)
enable_second_display_channel();
break;
-
- case IGA1_IGA2:
- viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
- viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
-
- disable_second_display_channel();
- break;
}
switch (output_interface) {
@@ -987,49 +1054,6 @@ static void set_lcd_output_path(int set_iga, int output_interface)
}
}
-/* Search Mode Index */
-static int search_mode_setting(int ModeInfoIndex)
-{
- int i = 0;
-
- while ((i < NUM_TOTAL_MODETABLE) &&
- (ModeInfoIndex != CLE266Modes[i].ModeIndex))
- i++;
- if (i >= NUM_TOTAL_MODETABLE)
- i = 0;
- return i;
-
-}
-
-struct VideoModeTable *viafb_get_modetbl_pointer(int Index)
-{
- struct VideoModeTable *TmpTbl = NULL;
- TmpTbl = &CLE266Modes[search_mode_setting(Index)];
- return TmpTbl;
-}
-
-struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index)
-{
- struct VideoModeTable *TmpTbl = NULL;
- int i = 0;
- while ((i < NUM_TOTAL_CEA_MODES) &&
- (Index != CEA_HDMI_Modes[i].ModeIndex))
- i++;
- if ((i < NUM_TOTAL_CEA_MODES))
- TmpTbl = &CEA_HDMI_Modes[i];
- else {
- /*Still use general timing if don't find CEA timing */
- i = 0;
- while ((i < NUM_TOTAL_MODETABLE) &&
- (Index != CLE266Modes[i].ModeIndex))
- i++;
- if (i >= NUM_TOTAL_MODETABLE)
- i = 0;
- TmpTbl = &CLE266Modes[i];
- }
- return TmpTbl;
-}
-
static void load_fix_bit_crtc_reg(void)
{
/* always set to 1 */
@@ -1121,15 +1145,13 @@ void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
struct io_register *reg = NULL;
switch (set_iga) {
- case IGA1_IGA2:
case IGA1:
reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
viafb_load_reg_num = fetch_count_reg.
iga1_fetch_count_reg.reg_num;
reg = fetch_count_reg.iga1_fetch_count_reg.reg;
viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
- if (set_iga == IGA1)
- break;
+ break;
case IGA2:
reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
viafb_load_reg_num = fetch_count_reg.
@@ -1499,7 +1521,7 @@ void viafb_set_vclock(u32 CLK, int set_iga)
/* H.W. Reset : ON */
viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
- if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
+ if (set_iga == IGA1) {
/* Change D,N FOR VCLK */
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_CLE266:
@@ -1528,7 +1550,7 @@ void viafb_set_vclock(u32 CLK, int set_iga)
}
}
- if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
+ if (set_iga == IGA2) {
/* Change D,N FOR LCK */
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_CLE266:
@@ -1557,12 +1579,12 @@ void viafb_set_vclock(u32 CLK, int set_iga)
viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
/* Reset PLL */
- if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
+ if (set_iga == IGA1) {
viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
}
- if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
+ if (set_iga == IGA2) {
viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0);
viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0);
}
@@ -1805,47 +1827,15 @@ void viafb_load_crtc_timing(struct display_timing device_timing,
viafb_lock_crt();
}
-void viafb_set_color_depth(int bpp_byte, int set_iga)
-{
- if (set_iga == IGA1) {
- switch (bpp_byte) {
- case MODE_8BPP:
- viafb_write_reg_mask(SR15, VIASR, 0x22, 0x7E);
- break;
- case MODE_16BPP:
- viafb_write_reg_mask(SR15, VIASR, 0xB6, 0xFE);
- break;
- case MODE_32BPP:
- viafb_write_reg_mask(SR15, VIASR, 0xAE, 0xFE);
- break;
- }
- } else {
- switch (bpp_byte) {
- case MODE_8BPP:
- viafb_write_reg_mask(CR67, VIACR, 0x00, BIT6 + BIT7);
- break;
- case MODE_16BPP:
- viafb_write_reg_mask(CR67, VIACR, 0x40, BIT6 + BIT7);
- break;
- case MODE_32BPP:
- viafb_write_reg_mask(CR67, VIACR, 0xC0, BIT6 + BIT7);
- break;
- }
- }
-}
-
void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
- int mode_index, int bpp_byte, int set_iga)
+ struct VideoModeTable *video_mode, int bpp_byte, int set_iga)
{
- struct VideoModeTable *video_mode;
struct display_timing crt_reg;
int i;
int index = 0;
int h_addr, v_addr;
u32 pll_D_N;
- video_mode = &CLE266Modes[search_mode_setting(mode_index)];
-
for (i = 0; i < video_mode->mode_array; i++) {
index = i;
@@ -1858,8 +1848,10 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
/* Mode 640x480 has border, but LCD/DFP didn't have border. */
/* So we would delete border. */
- if ((viafb_LCD_ON | viafb_DVI_ON) && (mode_index == VIA_RES_640X480)
- && (viaparinfo->crt_setting_info->refresh_rate == 60)) {
+ if ((viafb_LCD_ON | viafb_DVI_ON)
+ && video_mode->crtc[0].crtc.hor_addr == 640
+ && video_mode->crtc[0].crtc.ver_addr == 480
+ && viaparinfo->crt_setting_info->refresh_rate == 60) {
/* The border is 8 pixels. */
crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
@@ -1912,9 +1904,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
&& (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
- /* load SR Register About Memory and Color part */
- viafb_set_color_depth(bpp_byte, set_iga);
-
pll_D_N = viafb_get_clk_value(crt_table[index].clk);
DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
viafb_set_vclock(pll_D_N, set_iga);
@@ -1956,9 +1945,6 @@ void viafb_update_device_setting(int hres, int vres,
viaparinfo->tmds_setting_info->h_active = hres;
viaparinfo->tmds_setting_info->v_active = vres;
- viaparinfo->tmds_setting_info->bpp = bpp;
- viaparinfo->tmds_setting_info->refresh_rate =
- vmode_refresh;
viaparinfo->lvds_setting_info->h_active = hres;
viaparinfo->lvds_setting_info->v_active = vres;
@@ -1975,9 +1961,6 @@ void viafb_update_device_setting(int hres, int vres,
if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
viaparinfo->tmds_setting_info->h_active = hres;
viaparinfo->tmds_setting_info->v_active = vres;
- viaparinfo->tmds_setting_info->bpp = bpp;
- viaparinfo->tmds_setting_info->refresh_rate =
- vmode_refresh;
}
if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
@@ -2076,9 +2059,8 @@ static void init_tmds_chip_info(void)
DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
- viaparinfo->tmds_setting_info->get_dvi_size_method =
- GET_DVI_SIZE_BY_VGA_BIOS;
- viafb_init_dvi_size();
+ viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info,
+ &viaparinfo->shared->tmds_setting_info);
}
static void init_lvds_chip_info(void)
@@ -2195,28 +2177,19 @@ static void set_display_channel(void)
}
}
-int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
- int vmode_index1, int hor_res1, int ver_res1, int video_bpp1)
+int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
+ struct VideoModeTable *vmode_tbl1, int video_bpp1)
{
int i, j;
int port;
u8 value, index, mask;
- struct VideoModeTable *vmode_tbl;
struct crt_mode_table *crt_timing;
- struct VideoModeTable *vmode_tbl1 = NULL;
struct crt_mode_table *crt_timing1 = NULL;
- DEBUG_MSG(KERN_INFO "Set Mode!!\n");
- DEBUG_MSG(KERN_INFO
- "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n",
- vmode_index, hor_res, ver_res, video_bpp);
-
device_screen_off();
- vmode_tbl = &CLE266Modes[search_mode_setting(vmode_index)];
crt_timing = vmode_tbl->crtc;
if (viafb_SAMM_ON == 1) {
- vmode_tbl1 = &CLE266Modes[search_mode_setting(vmode_index1)];
crt_timing1 = vmode_tbl1->crtc;
}
@@ -2267,12 +2240,11 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
outb(VPIT.SR[i - 1], VIASR + 1);
}
- viafb_set_primary_address(0);
- viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
+ viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
viafb_set_iga_path();
/* Write CRTC */
- viafb_fill_crtc_timing(crt_timing, vmode_index, video_bpp / 8, IGA1);
+ viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
/* Write Graphic Controller */
for (i = 0; i < StdGR; i++) {
@@ -2292,65 +2264,25 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
/* Update Patch Register */
- if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
- || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)) {
- for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
- if (res_patch_table[i].mode_index == vmode_index) {
- for (j = 0;
- j < res_patch_table[i].table_length; j++) {
- index =
- res_patch_table[i].
- io_reg_table[j].index;
- port =
- res_patch_table[i].
- io_reg_table[j].port;
- value =
- res_patch_table[i].
- io_reg_table[j].value;
- mask =
- res_patch_table[i].
- io_reg_table[j].mask;
- viafb_write_reg_mask(index, port, value,
- mask);
- }
- }
- }
- }
-
- if (viafb_SAMM_ON == 1) {
- if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
- || (viaparinfo->chip_info->gfx_chip_name ==
- UNICHROME_K400)) {
- for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
- if (res_patch_table[i].mode_index ==
- vmode_index1) {
- for (j = 0;
- j <
- res_patch_table[i].
- table_length; j++) {
- index =
- res_patch_table[i].
- io_reg_table[j].index;
- port =
- res_patch_table[i].
- io_reg_table[j].port;
- value =
- res_patch_table[i].
- io_reg_table[j].value;
- mask =
- res_patch_table[i].
- io_reg_table[j].mask;
- viafb_write_reg_mask(index,
- port, value, mask);
- }
- }
- }
+ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
+ || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
+ && vmode_tbl->crtc[0].crtc.hor_addr == 1024
+ && vmode_tbl->crtc[0].crtc.ver_addr == 768) {
+ for (j = 0; j < res_patch_table[0].table_length; j++) {
+ index = res_patch_table[0].io_reg_table[j].index;
+ port = res_patch_table[0].io_reg_table[j].port;
+ value = res_patch_table[0].io_reg_table[j].value;
+ mask = res_patch_table[0].io_reg_table[j].mask;
+ viafb_write_reg_mask(index, port, value, mask);
}
}
viafb_set_primary_pitch(viafbinfo->fix.line_length);
viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
: viafbinfo->fix.line_length);
+ viafb_set_primary_color_depth(viaparinfo->depth);
+ viafb_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
+ : viaparinfo->depth);
/* Update Refresh Rate Setting */
/* Clear On Screen */
@@ -2359,11 +2291,11 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
if (viafb_CRT_ON) {
if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path ==
IGA2)) {
- viafb_fill_crtc_timing(crt_timing1, vmode_index1,
+ viafb_fill_crtc_timing(crt_timing1, vmode_tbl1,
video_bpp1 / 8,
viaparinfo->crt_setting_info->iga_path);
} else {
- viafb_fill_crtc_timing(crt_timing, vmode_index,
+ viafb_fill_crtc_timing(crt_timing, vmode_tbl,
video_bpp / 8,
viaparinfo->crt_setting_info->iga_path);
}
@@ -2373,7 +2305,7 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
to 8 alignment (1368),there is several pixels (2 pixels)
on right side of screen. */
- if (hor_res % 8) {
+ if (vmode_tbl->crtc[0].crtc.hor_addr % 8) {
viafb_unlock_crt();
viafb_write_reg(CR02, VIACR,
viafb_read_reg(VIACR, CR02) - 1);
@@ -2384,14 +2316,14 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
if (viafb_DVI_ON) {
if (viafb_SAMM_ON &&
(viaparinfo->tmds_setting_info->iga_path == IGA2)) {
- viafb_dvi_set_mode(viafb_get_mode_index
+ viafb_dvi_set_mode(viafb_get_mode
(viaparinfo->tmds_setting_info->h_active,
viaparinfo->tmds_setting_info->
v_active),
video_bpp1, viaparinfo->
tmds_setting_info->iga_path);
} else {
- viafb_dvi_set_mode(viafb_get_mode_index
+ viafb_dvi_set_mode(viafb_get_mode
(viaparinfo->tmds_setting_info->h_active,
viaparinfo->
tmds_setting_info->v_active),
@@ -2445,8 +2377,8 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
/* If set mode normally, save resolution information for hot-plug . */
if (!viafb_hotplug) {
- viafb_hotplug_Xres = hor_res;
- viafb_hotplug_Yres = ver_res;
+ viafb_hotplug_Xres = vmode_tbl->crtc[0].crtc.hor_addr;
+ viafb_hotplug_Yres = vmode_tbl->crtc[0].crtc.ver_addr;
viafb_hotplug_bpp = video_bpp;
viafb_hotplug_refresh = viafb_refresh;
@@ -2706,13 +2638,11 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
/*According var's xres, yres fill var's other timing information*/
void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
- int mode_index)
+ struct VideoModeTable *vmode_tbl)
{
- struct VideoModeTable *vmode_tbl = NULL;
struct crt_mode_table *crt_timing = NULL;
struct display_timing crt_reg;
int i = 0, index = 0;
- vmode_tbl = &CLE266Modes[search_mode_setting(mode_index)];
crt_timing = vmode_tbl->crtc;
for (i = 0; i < vmode_tbl->mode_array; i++) {
index = i;
@@ -2721,36 +2651,6 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
}
crt_reg = crt_timing[index].crtc;
- switch (var->bits_per_pixel) {
- case 8:
- var->red.offset = 0;
- var->green.offset = 0;
- var->blue.offset = 0;
- var->red.length = 6;
- var->green.length = 6;
- var->blue.length = 6;
- break;
- case 16:
- var->red.offset = 11;
- var->green.offset = 5;
- var->blue.offset = 0;
- var->red.length = 5;
- var->green.length = 6;
- var->blue.length = 5;
- break;
- case 32:
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- break;
- default:
- /* never happed, put here to keep consistent */
- break;
- }
-
var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
var->left_margin =
crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index b874d952b44..12ef32d334c 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -22,6 +22,7 @@
#ifndef __HW_H__
#define __HW_H__
+#include "viamode.h"
#include "global.h"
/***************************************************
@@ -862,8 +863,6 @@ struct pci_device_id_info {
};
extern unsigned int viafb_second_virtual_xres;
-extern unsigned int viafb_second_offset;
-extern int viafb_second_size;
extern int viafb_SAMM_ON;
extern int viafb_dual_fb;
extern int viafb_LCD2_ON;
@@ -874,8 +873,9 @@ extern int viafb_hotplug;
void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
void viafb_set_output_path(int device, int set_iga,
int output_interface);
+
void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
- int mode_index, int bpp_byte, int set_iga);
+ struct VideoModeTable *video_mode, int bpp_byte, int set_iga);
void viafb_set_vclock(u32 CLK, int set_iga);
void viafb_load_reg(int timing_value, int viafb_load_reg_num,
@@ -891,16 +891,15 @@ void viafb_lock_crt(void);
void viafb_unlock_crt(void);
void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
-struct VideoModeTable *viafb_get_modetbl_pointer(int Index);
u32 viafb_get_clk_value(int clk);
void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
-void viafb_set_color_depth(int bpp_byte, int set_iga);
void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
*p_gfx_dpa_setting);
-int viafb_setmode(int vmode_index, int hor_res, int ver_res,
- int video_bpp, int vmode_index1, int hor_res1,
- int ver_res1, int video_bpp1);
+int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
+ struct VideoModeTable *vmode_tbl1, int video_bpp1);
+void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
+ struct VideoModeTable *vmode_tbl);
void viafb_init_chip_info(struct pci_dev *pdev,
const struct pci_device_id *pdi);
void viafb_init_dac(int set_iga);
@@ -915,6 +914,8 @@ void viafb_set_primary_address(u32 addr);
void viafb_set_secondary_address(u32 addr);
void viafb_set_primary_pitch(u32 pitch);
void viafb_set_secondary_pitch(u32 pitch);
+void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue);
+void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue);
void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len);
#endif /* __HW_H__ */
diff --git a/drivers/video/via/iface.c b/drivers/video/via/iface.c
deleted file mode 100644
index 1570636c8d5..00000000000
--- a/drivers/video/via/iface.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2008 S3 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;
- * either version 2, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
-
-/* Get frame buffer size from VGA BIOS */
-
-unsigned int viafb_get_memsize(void)
-{
- unsigned int m;
-
- /* If memory size provided by user */
- if (viafb_memsize)
- m = viafb_memsize * Mb;
- else {
- m = (unsigned int)viafb_read_reg(VIASR, SR39);
- m = m * (4 * Mb);
-
- if ((m < (16 * Mb)) || (m > (64 * Mb)))
- m = 16 * Mb;
- }
- DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m / Mb);
- return m;
-}
-
-/* Get Video Buffer Starting Physical Address(back door)*/
-
-unsigned long viafb_get_videobuf_addr(void)
-{
- struct pci_dev *pdev = NULL;
- unsigned char sys_mem;
- unsigned char video_mem;
- unsigned long sys_mem_size;
- unsigned long video_mem_size;
- /*system memory = 256 MB, video memory 64 MB */
- unsigned long vmem_starting_adr = 0x0C000000;
-
- pdev =
- (struct pci_dev *)pci_get_device(VIA_K800_BRIDGE_VID,
- VIA_K800_BRIDGE_DID, NULL);
- if (pdev != NULL) {
- pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG,
- &sys_mem);
- pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG,
- &video_mem);
- video_mem = (video_mem & 0x70) >> 4;
- sys_mem_size = ((unsigned long)sys_mem) << 24;
- if (video_mem != 0)
- video_mem_size = (1 << (video_mem)) * 1024 * 1024;
- else
- video_mem_size = 0;
-
- vmem_starting_adr = sys_mem_size - video_mem_size;
- pci_dev_put(pdev);
- }
-
- DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n",
- vmem_starting_adr);
- return vmem_starting_adr;
-}
diff --git a/drivers/video/via/iface.h b/drivers/video/via/iface.h
deleted file mode 100644
index 790ec3e3aea..00000000000
--- a/drivers/video/via/iface.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2008 S3 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;
- * either version 2, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 __IFACE_H__
-#define __IFACE_H__
-
-#define Kb (1024)
-#define Mb (Kb*Kb)
-
-#define VIA_K800_BRIDGE_VID 0x1106
-#define VIA_K800_BRIDGE_DID 0x3204
-
-#define VIA_K800_SYSTEM_MEMORY_REG 0x47
-#define VIA_K800_VIDEO_MEMORY_REG 0xA1
-
-extern int viafb_memsize;
-unsigned int viafb_get_memsize(void);
-unsigned long viafb_get_videobuf_addr(void);
-
-#endif /* __IFACE_H__ */
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 09353e2b92f..1b1ccdc2d83 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -22,25 +22,7 @@
#include "global.h"
#include "lcdtbl.h"
-static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = {
- /* IGA2 Shadow Horizontal Total */
- {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } },
- /* IGA2 Shadow Horizontal Blank End */
- {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } },
- /* IGA2 Shadow Vertical Total */
- {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } },
- /* IGA2 Shadow Vertical Addressable Video */
- {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } },
- /* IGA2 Shadow Vertical Blank Start */
- {IGA2_SHADOW_VER_BLANK_START_REG_NUM,
- {{CR72, 0, 7}, {CR74, 4, 6} } },
- /* IGA2 Shadow Vertical Blank End */
- {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } },
- /* IGA2 Shadow Vertical Sync Start */
- {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } },
- /* IGA2 Shadow Vertical Sync End */
- {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } }
-};
+#define viafb_compact_res(x, y) (((x)<<16)|(y))
static struct _lcd_scaling_factor lcd_scaling_factor = {
/* LCD Horizontal Scaling Factor Register */
@@ -59,16 +41,10 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
static int check_lvds_chip(int device_id_subaddr, int device_id);
static bool lvds_identify_integratedlvds(void);
-static int fp_id_to_vindex(int panel_id);
+static void fp_id_to_vindex(int panel_id);
static int lvds_register_read(int index);
static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
int panel_vres);
-static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
- int panel_id);
-static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
- int panel_id);
-static void load_lcd_patch_regs(int set_hres, int set_vres,
- int panel_id, int set_iga);
static void via_pitch_alignment_patch_lcd(
struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information
@@ -98,8 +74,6 @@ static void check_diport_of_integrated_lvds(
static struct display_timing lcd_centering_timging(struct display_timing
mode_crt_reg,
struct display_timing panel_crt_reg);
-static void load_crtc_shadow_timing(struct display_timing mode_timing,
- struct display_timing panel_timing);
static void viafb_load_scaling_factor_for_p4m900(int set_hres,
int set_vres, int panel_hres, int panel_vres);
@@ -125,33 +99,24 @@ void viafb_init_lcd_size(void)
break;
case GET_LCD_SIZE_BY_VGA_BIOS:
DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
- viaparinfo->lvds_setting_info->lcd_panel_size =
- fp_id_to_vindex(viafb_lcd_panel_id);
+ fp_id_to_vindex(viafb_lcd_panel_id);
DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
viaparinfo->lvds_setting_info->lcd_panel_id);
- DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
- viaparinfo->lvds_setting_info->lcd_panel_size);
break;
case GET_LCD_SIZE_BY_USER_SETTING:
DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
- viaparinfo->lvds_setting_info->lcd_panel_size =
- fp_id_to_vindex(viafb_lcd_panel_id);
+ fp_id_to_vindex(viafb_lcd_panel_id);
DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
viaparinfo->lvds_setting_info->lcd_panel_id);
- DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
- viaparinfo->lvds_setting_info->lcd_panel_size);
break;
default:
DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
viaparinfo->lvds_setting_info->lcd_panel_id =
LCD_PANEL_ID1_800X600;
- viaparinfo->lvds_setting_info->lcd_panel_size =
- fp_id_to_vindex(LCD_PANEL_ID1_800X600);
+ fp_id_to_vindex(LCD_PANEL_ID1_800X600);
}
viaparinfo->lvds_setting_info2->lcd_panel_id =
viaparinfo->lvds_setting_info->lcd_panel_id;
- viaparinfo->lvds_setting_info2->lcd_panel_size =
- viaparinfo->lvds_setting_info->lcd_panel_size;
viaparinfo->lvds_setting_info2->lcd_panel_hres =
viaparinfo->lvds_setting_info->lcd_panel_hres;
viaparinfo->lvds_setting_info2->lcd_panel_vres =
@@ -171,13 +136,13 @@ static bool lvds_identify_integratedlvds(void)
if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
INTEGRATED_LVDS;
- DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\
- (Internal LVDS + External LVDS)\n");
+ DEBUG_MSG(KERN_INFO "Support two dual channel LVDS! "
+ "(Internal LVDS + External LVDS)\n");
} else {
viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
INTEGRATED_LVDS;
- DEBUG_MSG(KERN_INFO "Not found external LVDS,\
- so can't support two dual channel LVDS!\n");
+ DEBUG_MSG(KERN_INFO "Not found external LVDS, "
+ "so can't support two dual channel LVDS!\n");
}
} else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
/* Two single channel LCD (Internal LVDS + Internal LVDS): */
@@ -185,8 +150,8 @@ static bool lvds_identify_integratedlvds(void)
INTEGRATED_LVDS;
viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
INTEGRATED_LVDS;
- DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\
- (Internal LVDS + Internal LVDS)\n");
+ DEBUG_MSG(KERN_INFO "Support two single channel LVDS! "
+ "(Internal LVDS + Internal LVDS)\n");
} else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
/* If we have found external LVDS, just use it,
otherwise, we will use internal LVDS as default. */
@@ -248,7 +213,7 @@ int viafb_lvds_trasmitter_identify(void)
return FAIL;
}
-static int fp_id_to_vindex(int panel_id)
+static void fp_id_to_vindex(int panel_id)
{
DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
@@ -264,7 +229,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID0_640X480;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_640X480;
break;
case 0x1:
viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
@@ -273,7 +237,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID1_800X600;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_800X600;
break;
case 0x2:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -282,7 +245,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID2_1024X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1024X768;
break;
case 0x3:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -291,7 +253,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID3_1280X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1280X768;
break;
case 0x4:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -300,7 +261,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID4_1280X1024;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1280X1024;
break;
case 0x5:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
@@ -309,7 +269,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID5_1400X1050;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1400X1050;
break;
case 0x6:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
@@ -318,7 +277,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID6_1600X1200;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1600X1200;
break;
case 0x8:
viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
@@ -327,7 +285,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_IDA_800X480;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_800X480;
break;
case 0x9:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -336,7 +293,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID2_1024X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1024X768;
break;
case 0xA:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -345,7 +301,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID2_1024X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1024X768;
break;
case 0xB:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -354,7 +309,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID2_1024X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1024X768;
break;
case 0xC:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -363,7 +317,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID3_1280X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1280X768;
break;
case 0xD:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -372,7 +325,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID4_1280X1024;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1280X1024;
break;
case 0xE:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
@@ -381,7 +333,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID5_1400X1050;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1400X1050;
break;
case 0xF:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
@@ -390,7 +341,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID6_1600X1200;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1600X1200;
break;
case 0x10:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
@@ -399,7 +349,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID7_1366X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1368X768;
break;
case 0x11:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
@@ -408,7 +357,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID8_1024X600;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1024X600;
break;
case 0x12:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -417,7 +365,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID3_1280X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1280X768;
break;
case 0x13:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -426,7 +373,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID9_1280X800;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_1280X800;
break;
case 0x14:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
@@ -435,7 +381,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_IDB_1360X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1360X768;
break;
case 0x15:
viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
@@ -444,7 +389,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID3_1280X768;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
viaparinfo->lvds_setting_info->LCDDithering = 0;
- return VIA_RES_1280X768;
break;
case 0x16:
viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
@@ -453,7 +397,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_IDC_480X640;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_480X640;
break;
default:
viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
@@ -462,7 +405,6 @@ static int fp_id_to_vindex(int panel_id)
LCD_PANEL_ID1_800X600;
viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
viaparinfo->lvds_setting_info->LCDDithering = 1;
- return VIA_RES_800X600;
}
}
@@ -573,284 +515,6 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
}
}
-static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
- int panel_id)
-{
- int vmode_index;
- int reg_num = 0;
- struct io_reg *lcd_patch_reg = NULL;
-
- vmode_index = viafb_get_mode_index(set_hres, set_vres);
- switch (panel_id) {
- /* LCD 800x600 */
- case LCD_PANEL_ID1_800X600:
- switch (vmode_index) {
- case VIA_RES_640X400:
- case VIA_RES_640X480:
- reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6;
- lcd_patch_reg = K400_LCD_RES_6X4_8X6;
- break;
- case VIA_RES_720X480:
- case VIA_RES_720X576:
- reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6;
- lcd_patch_reg = K400_LCD_RES_7X4_8X6;
- break;
- }
- break;
-
- /* LCD 1024x768 */
- case LCD_PANEL_ID2_1024X768:
- switch (vmode_index) {
- case VIA_RES_640X400:
- case VIA_RES_640X480:
- reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7;
- lcd_patch_reg = K400_LCD_RES_6X4_10X7;
- break;
- case VIA_RES_720X480:
- case VIA_RES_720X576:
- reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7;
- lcd_patch_reg = K400_LCD_RES_7X4_10X7;
- break;
- case VIA_RES_800X600:
- reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7;
- lcd_patch_reg = K400_LCD_RES_8X6_10X7;
- break;
- }
- break;
-
- /* LCD 1280x1024 */
- case LCD_PANEL_ID4_1280X1024:
- switch (vmode_index) {
- case VIA_RES_640X400:
- case VIA_RES_640X480:
- reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10;
- lcd_patch_reg = K400_LCD_RES_6X4_12X10;
- break;
- case VIA_RES_720X480:
- case VIA_RES_720X576:
- reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10;
- lcd_patch_reg = K400_LCD_RES_7X4_12X10;
- break;
- case VIA_RES_800X600:
- reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10;
- lcd_patch_reg = K400_LCD_RES_8X6_12X10;
- break;
- case VIA_RES_1024X768:
- reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10;
- lcd_patch_reg = K400_LCD_RES_10X7_12X10;
- break;
-
- }
- break;
-
- /* LCD 1400x1050 */
- case LCD_PANEL_ID5_1400X1050:
- switch (vmode_index) {
- case VIA_RES_640X480:
- reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10;
- lcd_patch_reg = K400_LCD_RES_6X4_14X10;
- break;
- case VIA_RES_800X600:
- reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10;
- lcd_patch_reg = K400_LCD_RES_8X6_14X10;
- break;
- case VIA_RES_1024X768:
- reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10;
- lcd_patch_reg = K400_LCD_RES_10X7_14X10;
- break;
- case VIA_RES_1280X768:
- case VIA_RES_1280X800:
- case VIA_RES_1280X960:
- case VIA_RES_1280X1024:
- reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10;
- lcd_patch_reg = K400_LCD_RES_12X10_14X10;
- break;
- }
- break;
-
- /* LCD 1600x1200 */
- case LCD_PANEL_ID6_1600X1200:
- switch (vmode_index) {
- case VIA_RES_640X400:
- case VIA_RES_640X480:
- reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12;
- lcd_patch_reg = K400_LCD_RES_6X4_16X12;
- break;
- case VIA_RES_720X480:
- case VIA_RES_720X576:
- reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12;
- lcd_patch_reg = K400_LCD_RES_7X4_16X12;
- break;
- case VIA_RES_800X600:
- reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12;
- lcd_patch_reg = K400_LCD_RES_8X6_16X12;
- break;
- case VIA_RES_1024X768:
- reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12;
- lcd_patch_reg = K400_LCD_RES_10X7_16X12;
- break;
- case VIA_RES_1280X768:
- case VIA_RES_1280X800:
- case VIA_RES_1280X960:
- case VIA_RES_1280X1024:
- reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12;
- lcd_patch_reg = K400_LCD_RES_12X10_16X12;
- break;
- }
- break;
-
- /* LCD 1366x768 */
- case LCD_PANEL_ID7_1366X768:
- switch (vmode_index) {
- case VIA_RES_640X480:
- reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7;
- lcd_patch_reg = K400_LCD_RES_6X4_1366X7;
- break;
- case VIA_RES_720X480:
- case VIA_RES_720X576:
- reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7;
- lcd_patch_reg = K400_LCD_RES_7X4_1366X7;
- break;
- case VIA_RES_800X600:
- reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7;
- lcd_patch_reg = K400_LCD_RES_8X6_1366X7;
- break;
- case VIA_RES_1024X768:
- reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7;
- lcd_patch_reg = K400_LCD_RES_10X7_1366X7;
- break;
- case VIA_RES_1280X768:
- case VIA_RES_1280X800:
- case VIA_RES_1280X960:
- case VIA_RES_1280X1024:
- reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7;
- lcd_patch_reg = K400_LCD_RES_12X10_1366X7;
- break;
- }
- break;
-
- /* LCD 1360x768 */
- case LCD_PANEL_IDB_1360X768:
- break;
- }
- if (reg_num != 0) {
- /* H.W. Reset : ON */
- viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
-
- viafb_write_regx(lcd_patch_reg, reg_num);
-
- /* H.W. Reset : OFF */
- viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
-
- /* Reset PLL */
- viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
- viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
-
- /* Fire! */
- outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
- }
-}
-
-static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
- int panel_id)
-{
- int vmode_index;
- int reg_num = 0;
- struct io_reg *lcd_patch_reg = NULL;
-
- vmode_index = viafb_get_mode_index(set_hres, set_vres);
-
- switch (panel_id) {
- case LCD_PANEL_ID5_1400X1050:
- switch (vmode_index) {
- case VIA_RES_640X480:
- reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10;
- lcd_patch_reg = P880_LCD_RES_6X4_14X10;
- break;
- case VIA_RES_800X600:
- reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10;
- lcd_patch_reg = P880_LCD_RES_8X6_14X10;
- break;
- }
- break;
- case LCD_PANEL_ID6_1600X1200:
- switch (vmode_index) {
- case VIA_RES_640X400:
- case VIA_RES_640X480:
- reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12;
- lcd_patch_reg = P880_LCD_RES_6X4_16X12;
- break;
- case VIA_RES_720X480:
- case VIA_RES_720X576:
- reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12;
- lcd_patch_reg = P880_LCD_RES_7X4_16X12;
- break;
- case VIA_RES_800X600:
- reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12;
- lcd_patch_reg = P880_LCD_RES_8X6_16X12;
- break;
- case VIA_RES_1024X768:
- reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12;
- lcd_patch_reg = P880_LCD_RES_10X7_16X12;
- break;
- case VIA_RES_1280X768:
- case VIA_RES_1280X960:
- case VIA_RES_1280X1024:
- reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12;
- lcd_patch_reg = P880_LCD_RES_12X10_16X12;
- break;
- }
- break;
-
- }
- if (reg_num != 0) {
- /* H.W. Reset : ON */
- viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
-
- viafb_write_regx(lcd_patch_reg, reg_num);
-
- /* H.W. Reset : OFF */
- viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
-
- /* Reset PLL */
- viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
- viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
-
- /* Fire! */
- outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
- }
-}
-
-static void load_lcd_patch_regs(int set_hres, int set_vres,
- int panel_id, int set_iga)
-{
- int vmode_index;
-
- vmode_index = viafb_get_mode_index(set_hres, set_vres);
-
- viafb_unlock_crt();
-
- /* Patch for simultaneous & Expansion */
- if ((set_iga == IGA1_IGA2) &&
- (viaparinfo->lvds_setting_info->display_method ==
- LCD_EXPANDSION)) {
- switch (viaparinfo->chip_info->gfx_chip_name) {
- case UNICHROME_CLE266:
- case UNICHROME_K400:
- load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id);
- break;
- case UNICHROME_K800:
- break;
- case UNICHROME_PM800:
- case UNICHROME_CN700:
- case UNICHROME_CX700:
- load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id);
- }
- }
-
- viafb_lock_crt();
-}
-
static void via_pitch_alignment_patch_lcd(
struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information
@@ -949,29 +613,25 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information *plvds_chip_info)
{
- int video_index = plvds_setting_info->lcd_panel_size;
int set_iga = plvds_setting_info->iga_path;
int mode_bpp = plvds_setting_info->bpp;
- int set_hres, set_vres;
- int panel_hres, panel_vres;
+ int set_hres = plvds_setting_info->h_active;
+ int set_vres = plvds_setting_info->v_active;
+ int panel_hres = plvds_setting_info->lcd_panel_hres;
+ int panel_vres = plvds_setting_info->lcd_panel_vres;
u32 pll_D_N;
- int offset;
struct display_timing mode_crt_reg, panel_crt_reg;
struct crt_mode_table *panel_crt_table = NULL;
- struct VideoModeTable *vmode_tbl = NULL;
+ struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres,
+ panel_vres);
DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
/* Get mode table */
mode_crt_reg = mode_crt_table->crtc;
/* Get panel table Pointer */
- vmode_tbl = viafb_get_modetbl_pointer(video_index);
panel_crt_table = vmode_tbl->crtc;
panel_crt_reg = panel_crt_table->crtc;
DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
- set_hres = plvds_setting_info->h_active;
- set_vres = plvds_setting_info->v_active;
- panel_hres = plvds_setting_info->lcd_panel_hres;
- panel_vres = plvds_setting_info->lcd_panel_vres;
if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
plvds_setting_info->vclk = panel_crt_table->clk;
@@ -1001,54 +661,12 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
}
}
- if (set_iga == IGA1_IGA2) {
- load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg);
- /* Fill shadow registers */
-
- switch (plvds_setting_info->lcd_panel_id) {
- case LCD_PANEL_ID0_640X480:
- offset = 80;
- break;
- case LCD_PANEL_ID1_800X600:
- case LCD_PANEL_IDA_800X480:
- offset = 110;
- break;
- case LCD_PANEL_ID2_1024X768:
- offset = 150;
- break;
- case LCD_PANEL_ID3_1280X768:
- case LCD_PANEL_ID4_1280X1024:
- case LCD_PANEL_ID5_1400X1050:
- case LCD_PANEL_ID9_1280X800:
- offset = 190;
- break;
- case LCD_PANEL_ID6_1600X1200:
- offset = 250;
- break;
- case LCD_PANEL_ID7_1366X768:
- case LCD_PANEL_IDB_1360X768:
- offset = 212;
- break;
- default:
- offset = 140;
- break;
- }
-
- /* Offset for simultaneous */
- viafb_set_secondary_pitch(offset << 3);
- DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n");
- viafb_load_fetch_count_reg(set_hres, 4, IGA2);
- /* Fetch count for simultaneous */
- } else { /* SAMM */
- /* Fetch count for IGA2 only */
- viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
-
- if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
- && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
- viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
+ /* Fetch count for IGA2 only */
+ viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
- viafb_set_color_depth(mode_bpp / 8, set_iga);
- }
+ if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
+ && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
+ viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
fill_lcd_format();
@@ -1065,11 +683,6 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
|| (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
- load_lcd_patch_regs(set_hres, set_vres,
- plvds_setting_info->lcd_panel_id, set_iga);
-
- DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n");
-
/* Patch for non 32bit alignment mode */
via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
}
@@ -1283,8 +896,7 @@ void viafb_lcd_enable(void)
viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
}
- if ((viaparinfo->lvds_setting_info->iga_path == IGA1)
- || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) {
+ if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
/* CRT path set to IGA2 */
viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40);
/* IGA2 path disabled */
@@ -1476,210 +1088,6 @@ static struct display_timing lcd_centering_timging(struct display_timing
return crt_reg;
}
-static void load_crtc_shadow_timing(struct display_timing mode_timing,
- struct display_timing panel_timing)
-{
- struct io_register *reg = NULL;
- int i;
- int viafb_load_reg_Num = 0;
- int reg_value = 0;
-
- if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) {
- /* Expansion */
- for (i = 12; i < 20; i++) {
- switch (i) {
- case H_TOTAL_SHADOW_INDEX:
- reg_value =
- IGA2_HOR_TOTAL_SHADOW_FORMULA
- (panel_timing.hor_total);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.hor_total_shadow.
- reg_num;
- reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
- break;
- case H_BLANK_END_SHADOW_INDEX:
- reg_value =
- IGA2_HOR_BLANK_END_SHADOW_FORMULA
- (panel_timing.hor_blank_start,
- panel_timing.hor_blank_end);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.
- hor_blank_end_shadow.reg_num;
- reg =
- iga2_shadow_crtc_reg.
- hor_blank_end_shadow.reg;
- break;
- case V_TOTAL_SHADOW_INDEX:
- reg_value =
- IGA2_VER_TOTAL_SHADOW_FORMULA
- (panel_timing.ver_total);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.ver_total_shadow.
- reg_num;
- reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
- break;
- case V_ADDR_SHADOW_INDEX:
- reg_value =
- IGA2_VER_ADDR_SHADOW_FORMULA
- (panel_timing.ver_addr);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.ver_addr_shadow.
- reg_num;
- reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
- break;
- case V_BLANK_SATRT_SHADOW_INDEX:
- reg_value =
- IGA2_VER_BLANK_START_SHADOW_FORMULA
- (panel_timing.ver_blank_start);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.
- ver_blank_start_shadow.reg_num;
- reg =
- iga2_shadow_crtc_reg.
- ver_blank_start_shadow.reg;
- break;
- case V_BLANK_END_SHADOW_INDEX:
- reg_value =
- IGA2_VER_BLANK_END_SHADOW_FORMULA
- (panel_timing.ver_blank_start,
- panel_timing.ver_blank_end);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.
- ver_blank_end_shadow.reg_num;
- reg =
- iga2_shadow_crtc_reg.
- ver_blank_end_shadow.reg;
- break;
- case V_SYNC_SATRT_SHADOW_INDEX:
- reg_value =
- IGA2_VER_SYNC_START_SHADOW_FORMULA
- (panel_timing.ver_sync_start);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.
- ver_sync_start_shadow.reg_num;
- reg =
- iga2_shadow_crtc_reg.
- ver_sync_start_shadow.reg;
- break;
- case V_SYNC_END_SHADOW_INDEX:
- reg_value =
- IGA2_VER_SYNC_END_SHADOW_FORMULA
- (panel_timing.ver_sync_start,
- panel_timing.ver_sync_end);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.
- ver_sync_end_shadow.reg_num;
- reg =
- iga2_shadow_crtc_reg.
- ver_sync_end_shadow.reg;
- break;
- }
- viafb_load_reg(reg_value,
- viafb_load_reg_Num, reg, VIACR);
- }
- } else { /* Centering */
- for (i = 12; i < 20; i++) {
- switch (i) {
- case H_TOTAL_SHADOW_INDEX:
- reg_value =
- IGA2_HOR_TOTAL_SHADOW_FORMULA
- (panel_timing.hor_total);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.hor_total_shadow.
- reg_num;
- reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
- break;
- case H_BLANK_END_SHADOW_INDEX:
- reg_value =
- IGA2_HOR_BLANK_END_SHADOW_FORMULA
- (panel_timing.hor_blank_start,
- panel_timing.hor_blank_end);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.
- hor_blank_end_shadow.reg_num;
- reg =
- iga2_shadow_crtc_reg.
- hor_blank_end_shadow.reg;
- break;
- case V_TOTAL_SHADOW_INDEX:
- reg_value =
- IGA2_VER_TOTAL_SHADOW_FORMULA
- (panel_timing.ver_total);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.ver_total_shadow.
- reg_num;
- reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
- break;
- case V_ADDR_SHADOW_INDEX:
- reg_value =
- IGA2_VER_ADDR_SHADOW_FORMULA
- (mode_timing.ver_addr);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.ver_addr_shadow.
- reg_num;
- reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
- break;
- case V_BLANK_SATRT_SHADOW_INDEX:
- reg_value =
- IGA2_VER_BLANK_START_SHADOW_FORMULA
- (mode_timing.ver_blank_start);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.
- ver_blank_start_shadow.reg_num;
- reg =
- iga2_shadow_crtc_reg.
- ver_blank_start_shadow.reg;
- break;
- case V_BLANK_END_SHADOW_INDEX:
- reg_value =
- IGA2_VER_BLANK_END_SHADOW_FORMULA
- (panel_timing.ver_blank_start,
- panel_timing.ver_blank_end);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.
- ver_blank_end_shadow.reg_num;
- reg =
- iga2_shadow_crtc_reg.
- ver_blank_end_shadow.reg;
- break;
- case V_SYNC_SATRT_SHADOW_INDEX:
- reg_value =
- IGA2_VER_SYNC_START_SHADOW_FORMULA(
- (panel_timing.ver_sync_start -
- panel_timing.ver_blank_start) +
- (panel_timing.ver_addr -
- mode_timing.ver_addr) / 2 +
- mode_timing.ver_addr);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.ver_sync_start_shadow.
- reg_num;
- reg =
- iga2_shadow_crtc_reg.ver_sync_start_shadow.
- reg;
- break;
- case V_SYNC_END_SHADOW_INDEX:
- reg_value =
- IGA2_VER_SYNC_END_SHADOW_FORMULA(
- (panel_timing.ver_sync_start -
- panel_timing.ver_blank_start) +
- (panel_timing.ver_addr -
- mode_timing.ver_addr) / 2 +
- mode_timing.ver_addr,
- panel_timing.ver_sync_end);
- viafb_load_reg_Num =
- iga2_shadow_crtc_reg.ver_sync_end_shadow.
- reg_num;
- reg =
- iga2_shadow_crtc_reg.ver_sync_end_shadow.
- reg;
- break;
- }
- viafb_load_reg(reg_value,
- viafb_load_reg_Num, reg, VIACR);
- }
- }
-}
-
bool viafb_lcd_get_mobile_state(bool *mobile)
{
unsigned char *romptr, *tableptr;
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 7cd03e2a127..d55aaa7b912 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -43,61 +43,6 @@
/* Video Memory Size */
#define VIDEO_MEMORY_SIZE_16M 0x1000000
-/* Definition Mode Index
-*/
-#define VIA_RES_640X480 0
-#define VIA_RES_800X600 1
-#define VIA_RES_1024X768 2
-#define VIA_RES_1152X864 3
-#define VIA_RES_1280X1024 4
-#define VIA_RES_1600X1200 5
-#define VIA_RES_1440X1050 6
-#define VIA_RES_1280X768 7
-#define VIA_RES_1280X960 8
-#define VIA_RES_1920X1440 9
-#define VIA_RES_848X480 10
-#define VIA_RES_1400X1050 11
-#define VIA_RES_720X480 12
-#define VIA_RES_720X576 13
-#define VIA_RES_1024X512 14
-#define VIA_RES_856X480 15
-#define VIA_RES_1024X576 16
-#define VIA_RES_640X400 17
-#define VIA_RES_1280X720 18
-#define VIA_RES_1920X1080 19
-#define VIA_RES_800X480 20
-#define VIA_RES_1368X768 21
-#define VIA_RES_1024X600 22
-#define VIA_RES_1280X800 23
-#define VIA_RES_1680X1050 24
-#define VIA_RES_960X600 25
-#define VIA_RES_1000X600 26
-#define VIA_RES_1088X612 27
-#define VIA_RES_1152X720 28
-#define VIA_RES_1200X720 29
-#define VIA_RES_1280X600 30
-#define VIA_RES_1360X768 31
-#define VIA_RES_1366X768 32
-#define VIA_RES_1440X900 33
-#define VIA_RES_1600X900 34
-#define VIA_RES_1600X1024 35
-#define VIA_RES_1792X1344 36
-#define VIA_RES_1856X1392 37
-#define VIA_RES_1920X1200 38
-#define VIA_RES_2048X1536 39
-#define VIA_RES_480X640 40
-
-/*Reduce Blanking*/
-#define VIA_RES_1360X768_RB 131
-#define VIA_RES_1440X900_RB 133
-#define VIA_RES_1400X1050_RB 111
-#define VIA_RES_1600X900_RB 134
-#define VIA_RES_1680X1050_RB 124
-#define VIA_RES_1920X1080_RB 119
-#define VIA_RES_1920X1200_RB 138
-
-#define VIA_RES_INVALID 255
-
/* standard VGA IO port
*/
#define VIARMisc 0x3CC
@@ -118,7 +63,6 @@
/* Display path */
#define IGA1 1
#define IGA2 2
-#define IGA1_IGA2 3
/* Define Color Depth */
#define MODE_8BPP 1
diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c
index d53c3d54ed8..aefdeeec89b 100644
--- a/drivers/video/via/via_utility.c
+++ b/drivers/video/via/via_utility.c
@@ -239,15 +239,3 @@ void viafb_get_gamma_support_state(int bpp, unsigned int *support_state)
else
*support_state = CRT_Device | DVI_Device | LCD_Device;
}
-
-int viafb_input_parameter_converter(int parameter_value)
-{
- int result;
-
- if (parameter_value >= 1 && parameter_value <= 9)
- result = 1 << (parameter_value - 1);
- else
- result = 1;
-
- return result;
-}
diff --git a/drivers/video/via/via_utility.h b/drivers/video/via/via_utility.h
index 2fd455202eb..1670ba82143 100644
--- a/drivers/video/via/via_utility.h
+++ b/drivers/video/via/via_utility.h
@@ -30,6 +30,5 @@ bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres);
void viafb_set_gamma_table(int bpp, unsigned int *gamma_table);
void viafb_get_gamma_table(unsigned int *gamma_table);
void viafb_get_gamma_support_state(int bpp, unsigned int *support_state);
-int viafb_input_parameter_converter(int parameter_value);
#endif /* __VIAUTILITY_H__ */
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 3028e7ddc3b..777b38a06d4 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -21,23 +21,28 @@
#include <linux/module.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/stat.h>
#define _MASTER_FILE
#include "global.h"
-static struct fb_var_screeninfo default_var;
static char *viafb_name = "Via";
static u32 pseudo_pal[17];
/* video mode */
-static char *viafb_mode = "640x480";
-static char *viafb_mode1 = "640x480";
+static char *viafb_mode;
+static char *viafb_mode1;
+static int viafb_bpp = 32;
+static int viafb_bpp1 = 32;
+
+static unsigned int viafb_second_offset;
+static int viafb_second_size;
static int viafb_accel = 1;
/* Added for specifying active devices.*/
-char *viafb_active_dev = "";
+char *viafb_active_dev;
/*Added for specify lcd output port*/
char *viafb_lcd_port = "";
@@ -50,18 +55,78 @@ static void apply_second_mode_setting(struct fb_var_screeninfo
*sec_var);
static void retrieve_device_setting(struct viafb_ioctl_setting
*setting_info);
+static int viafb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info);
static struct fb_ops viafb_ops;
+static void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth)
+{
+ var->grayscale = 0;
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ var->transp.msb_right = 0;
+ var->nonstd = 0;
+ switch (depth) {
+ case 8:
+ var->bits_per_pixel = 8;
+ var->red.offset = 0;
+ var->green.offset = 0;
+ var->blue.offset = 0;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ case 15:
+ var->bits_per_pixel = 16;
+ var->red.offset = 10;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 5;
+ var->blue.length = 5;
+ break;
+ case 16:
+ var->bits_per_pixel = 16;
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ break;
+ case 24:
+ var->bits_per_pixel = 32;
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ case 30:
+ var->bits_per_pixel = 32;
+ var->red.offset = 20;
+ var->green.offset = 10;
+ var->blue.offset = 0;
+ var->red.length = 10;
+ var->green.length = 10;
+ var->blue.length = 10;
+ break;
+ }
+}
+
static void viafb_update_fix(struct fb_info *info)
{
u32 bpp = info->var.bits_per_pixel;
info->fix.visual =
bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- info->fix.line_length =
- ((info->var.xres_virtual + 7) & ~7) * bpp / 8;
+ info->fix.line_length = (info->var.xres_virtual * bpp / 8 + 7) & ~7;
}
static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
@@ -75,6 +140,7 @@ static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
+ fix->visual = FB_VISUAL_TRUECOLOR;
fix->xpanstep = fix->ywrapstep = 0;
fix->ypanstep = 1;
@@ -97,9 +163,10 @@ static int viafb_release(struct fb_info *info, int user)
static int viafb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- int vmode_index, htotal, vtotal;
+ int htotal, vtotal, depth;
+ struct VideoModeTable *vmode_entry;
struct viafb_par *ppar = info->par;
- u32 long_refresh;
+ u32 long_refresh, line;
DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
/* Sanity check */
@@ -107,26 +174,36 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
return -EINVAL;
- vmode_index = viafb_get_mode_index(var->xres, var->yres);
- if (vmode_index == VIA_RES_INVALID) {
+ vmode_entry = viafb_get_mode(var->xres, var->yres);
+ if (!vmode_entry) {
DEBUG_MSG(KERN_INFO
"viafb: Mode %dx%dx%d not supported!!\n",
var->xres, var->yres, var->bits_per_pixel);
return -EINVAL;
}
- if (24 == var->bits_per_pixel)
- var->bits_per_pixel = 32;
+ depth = fb_get_color_depth(var, &info->fix);
+ if (!depth)
+ depth = var->bits_per_pixel;
- if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 &&
- var->bits_per_pixel != 32)
+ if (depth < 0 || depth > 32)
return -EINVAL;
+ else if (!depth)
+ depth = 24;
+ else if (depth == 15 && viafb_dual_fb && ppar->iga_path == IGA1)
+ depth = 15;
+ else if (depth == 30)
+ depth = 30;
+ else if (depth <= 8)
+ depth = 8;
+ else if (depth <= 16)
+ depth = 16;
+ else
+ depth = 24;
- if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F)
- /*32 pixel alignment */
- var->xres_virtual = (var->xres_virtual + 31) & ~31;
- if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
- ppar->memsize)
+ viafb_fill_var_color_info(var, depth);
+ line = (var->xres_virtual * var->bits_per_pixel / 8 + 7) & ~7;
+ if (line * var->yres_virtual > ppar->memsize)
return -EINVAL;
/* Based on var passed in to calculate the refresh,
@@ -142,7 +219,7 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh);
/* Adjust var according to our driver's own table */
- viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);
+ viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry);
if (info->var.accel_flags & FB_ACCELF_TEXT &&
!ppar->shared->engine_mmio)
info->var.accel_flags = 0;
@@ -153,39 +230,45 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
static int viafb_set_par(struct fb_info *info)
{
struct viafb_par *viapar = info->par;
- int vmode_index;
- int vmode_index1 = 0;
+ struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
viapar->depth = fb_get_color_depth(&info->var, &info->fix);
- viafb_update_device_setting(info->var.xres, info->var.yres,
- info->var.bits_per_pixel, viafb_refresh, 0);
+ viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
+ viafbinfo->var.bits_per_pixel, viafb_refresh, 0);
- vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres);
-
- if (viafb_SAMM_ON == 1) {
+ vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres);
+ if (viafb_dual_fb) {
+ vmode_entry1 = viafb_get_mode(viafbinfo1->var.xres,
+ viafbinfo1->var.yres);
+ viafb_update_device_setting(viafbinfo1->var.xres,
+ viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel,
+ viafb_refresh1, 1);
+ } else if (viafb_SAMM_ON == 1) {
DEBUG_MSG(KERN_INFO
"viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
viafb_second_xres, viafb_second_yres, viafb_bpp1);
- vmode_index1 = viafb_get_mode_index(viafb_second_xres,
+ vmode_entry1 = viafb_get_mode(viafb_second_xres,
viafb_second_yres);
- DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n",
- vmode_index1);
viafb_update_device_setting(viafb_second_xres,
viafb_second_yres, viafb_bpp1, viafb_refresh1, 1);
}
- if (vmode_index != VIA_RES_INVALID) {
+ if (vmode_entry) {
viafb_update_fix(info);
- viafb_bpp = info->var.bits_per_pixel;
+ if (viafb_dual_fb && viapar->iga_path == IGA2)
+ viafb_bpp1 = info->var.bits_per_pixel;
+ else
+ viafb_bpp = info->var.bits_per_pixel;
+
if (info->var.accel_flags & FB_ACCELF_TEXT)
info->flags &= ~FBINFO_HWACCEL_DISABLED;
else
info->flags |= FBINFO_HWACCEL_DISABLED;
- viafb_setmode(vmode_index, info->var.xres, info->var.yres,
- info->var.bits_per_pixel, vmode_index1,
- viafb_second_xres, viafb_second_yres, viafb_bpp1);
+ viafb_setmode(vmode_entry, info->var.bits_per_pixel,
+ vmode_entry1, viafb_bpp1);
+ viafb_pan_display(&info->var, info);
}
return 0;
@@ -195,234 +278,52 @@ static int viafb_set_par(struct fb_info *info)
static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp, struct fb_info *info)
{
- u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
- unsigned cmap_entries = (info->var.bits_per_pixel == 8) ? 256 : 16;
- DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n");
- if (regno >= cmap_entries)
- return 1;
- if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
- /*
- * Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev.
- */
- outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
- rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
- }
- switch (info->var.bits_per_pixel) {
- case 8:
- outb(0x1A, 0x3C4);
- sr1a = inb(0x3C5);
- outb(0x1B, 0x3C4);
- sr1b = inb(0x3C5);
- outb(0x67, 0x3D4);
- cr67 = inb(0x3D5);
- outb(0x6A, 0x3D4);
- cr6a = inb(0x3D5);
-
- /* Map the 3C6/7/8/9 to the IGA2 */
- outb(0x1A, 0x3C4);
- outb(sr1a | 0x01, 0x3C5);
- /* Second Display Engine colck always on */
- outb(0x1B, 0x3C4);
- outb(sr1b | 0x80, 0x3C5);
- /* Second Display Color Depth 8 */
- outb(0x67, 0x3D4);
- outb(cr67 & 0x3F, 0x3D5);
- outb(0x6A, 0x3D4);
- /* Second Display Channel Reset CR6A[6]) */
- outb(cr6a & 0xBF, 0x3D5);
- /* Second Display Channel Enable CR6A[7] */
- outb(cr6a | 0x80, 0x3D5);
- /* Second Display Channel stop reset) */
- outb(cr6a | 0x40, 0x3D5);
-
- /* Bit mask of palette */
- outb(0xFF, 0x3c6);
- /* Write one register of IGA2 */
- outb(regno, 0x3C8);
- if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
- rev >= 15) {
- shift = 8;
- viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
- viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
- } else {
- shift = 10;
- viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
- viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
- }
- outb(red >> shift, 0x3C9);
- outb(green >> shift, 0x3C9);
- outb(blue >> shift, 0x3C9);
-
- /* Map the 3C6/7/8/9 to the IGA1 */
- outb(0x1A, 0x3C4);
- outb(sr1a & 0xFE, 0x3C5);
- /* Bit mask of palette */
- outb(0xFF, 0x3c6);
- /* Write one register of IGA1 */
- outb(regno, 0x3C8);
- outb(red >> shift, 0x3C9);
- outb(green >> shift, 0x3C9);
- outb(blue >> shift, 0x3C9);
-
- outb(0x1A, 0x3C4);
- outb(sr1a, 0x3C5);
- outb(0x1B, 0x3C4);
- outb(sr1b, 0x3C5);
- outb(0x67, 0x3D4);
- outb(cr67, 0x3D5);
- outb(0x6A, 0x3D4);
- outb(cr6a, 0x3D5);
- break;
- case 16:
- ((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) |
- ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
- break;
- case 32:
- ((u32 *) info->pseudo_palette)[regno] =
- ((transp & 0xFF00) << 16) |
- ((red & 0xFF00) << 8) |
- ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
- break;
- }
-
- return 0;
+ struct viafb_par *viapar = info->par;
+ u32 r, g, b;
-}
+ if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
+ if (regno > 255)
+ return -EINVAL;
-/*CALLED BY: fb_set_cmap */
-/* fb_set_var, pass 256 colors */
-/*CALLED BY: fb_set_cmap */
-/* fbcon_set_palette, pass 16 colors */
-static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
-{
- u32 len = cmap->len;
- u32 i;
- u16 *pred = cmap->red;
- u16 *pgreen = cmap->green;
- u16 *pblue = cmap->blue;
- u16 *ptransp = cmap->transp;
- u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
- if (len > 256)
- return 1;
- if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
- /*
- * Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip
- * rev.
- */
- outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
- rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
- }
- switch (info->var.bits_per_pixel) {
- case 8:
- outb(0x1A, 0x3C4);
- sr1a = inb(0x3C5);
- outb(0x1B, 0x3C4);
- sr1b = inb(0x3C5);
- outb(0x67, 0x3D4);
- cr67 = inb(0x3D5);
- outb(0x6A, 0x3D4);
- cr6a = inb(0x3D5);
- /* Map the 3C6/7/8/9 to the IGA2 */
- outb(0x1A, 0x3C4);
- outb(sr1a | 0x01, 0x3C5);
- outb(0x1B, 0x3C4);
- /* Second Display Engine colck always on */
- outb(sr1b | 0x80, 0x3C5);
- outb(0x67, 0x3D4);
- /* Second Display Color Depth 8 */
- outb(cr67 & 0x3F, 0x3D5);
- outb(0x6A, 0x3D4);
- /* Second Display Channel Reset CR6A[6]) */
- outb(cr6a & 0xBF, 0x3D5);
- /* Second Display Channel Enable CR6A[7] */
- outb(cr6a | 0x80, 0x3D5);
- /* Second Display Channel stop reset) */
- outb(cr6a | 0xC0, 0x3D5);
-
- /* Bit mask of palette */
- outb(0xFF, 0x3c6);
- outb(0x00, 0x3C8);
- if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
- rev >= 15) {
- shift = 8;
- viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
- viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
- } else {
- shift = 10;
- viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
- viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
- }
- for (i = 0; i < len; i++) {
- outb((*(pred + i)) >> shift, 0x3C9);
- outb((*(pgreen + i)) >> shift, 0x3C9);
- outb((*(pblue + i)) >> shift, 0x3C9);
- }
+ if (!viafb_dual_fb || viapar->iga_path == IGA1)
+ viafb_set_primary_color_register(regno, red >> 8,
+ green >> 8, blue >> 8);
- outb(0x1A, 0x3C4);
- /* Map the 3C6/7/8/9 to the IGA1 */
- outb(sr1a & 0xFE, 0x3C5);
- /* Bit mask of palette */
- outb(0xFF, 0x3c6);
- outb(0x00, 0x3C8);
- for (i = 0; i < len; i++) {
- outb((*(pred + i)) >> shift, 0x3C9);
- outb((*(pgreen + i)) >> shift, 0x3C9);
- outb((*(pblue + i)) >> shift, 0x3C9);
- }
+ if (!viafb_dual_fb || viapar->iga_path == IGA2)
+ viafb_set_secondary_color_register(regno, red >> 8,
+ green >> 8, blue >> 8);
+ } else {
+ if (regno > 15)
+ return -EINVAL;
- outb(0x1A, 0x3C4);
- outb(sr1a, 0x3C5);
- outb(0x1B, 0x3C4);
- outb(sr1b, 0x3C5);
- outb(0x67, 0x3D4);
- outb(cr67, 0x3D5);
- outb(0x6A, 0x3D4);
- outb(cr6a, 0x3D5);
- break;
- case 16:
- if (len > 17)
- return 0; /* Because static u32 pseudo_pal[17]; */
- for (i = 0; i < len; i++)
- ((u32 *) info->pseudo_palette)[i] =
- (*(pred + i) & 0xF800) |
- ((*(pgreen + i) & 0xFC00) >> 5) |
- ((*(pblue + i) & 0xF800) >> 11);
- break;
- case 32:
- if (len > 17)
- return 0;
- if (ptransp) {
- for (i = 0; i < len; i++)
- ((u32 *) info->pseudo_palette)[i] =
- ((*(ptransp + i) & 0xFF00) << 16) |
- ((*(pred + i) & 0xFF00) << 8) |
- ((*(pgreen + i) & 0xFF00)) |
- ((*(pblue + i) & 0xFF00) >> 8);
- } else {
- for (i = 0; i < len; i++)
- ((u32 *) info->pseudo_palette)[i] =
- 0x00000000 |
- ((*(pred + i) & 0xFF00) << 8) |
- ((*(pgreen + i) & 0xFF00)) |
- ((*(pblue + i) & 0xFF00) >> 8);
- }
- break;
+ r = (red >> (16 - info->var.red.length))
+ << info->var.red.offset;
+ b = (blue >> (16 - info->var.blue.length))
+ << info->var.blue.offset;
+ g = (green >> (16 - info->var.green.length))
+ << info->var.green.offset;
+ ((u32 *) info->pseudo_palette)[regno] = r | g | b;
}
+
return 0;
}
static int viafb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- unsigned int offset;
-
- DEBUG_MSG(KERN_INFO "viafb_pan_display!\n");
-
- offset = (var->xoffset + (var->yoffset * var->xres_virtual)) *
- var->bits_per_pixel / 16;
+ struct viafb_par *viapar = info->par;
+ u32 vram_addr = (var->yoffset * var->xres_virtual + var->xoffset)
+ * (var->bits_per_pixel / 8) + viapar->vram_addr;
+
+ DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr);
+ if (!viafb_dual_fb) {
+ viafb_set_primary_address(vram_addr);
+ viafb_set_secondary_address(vram_addr);
+ } else if (viapar->iga_path == IGA1)
+ viafb_set_primary_address(vram_addr);
+ else
+ viafb_set_secondary_address(vram_addr);
- DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset);
- viafb_set_primary_address(offset);
return 0;
}
@@ -476,6 +377,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
u32 gpu32;
DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd);
+ printk(KERN_WARNING "viafb_ioctl: Please avoid this interface as it is unstable and might change or vanish at any time!\n");
memset(&u, 0, sizeof(u));
switch (cmd) {
@@ -1015,23 +917,6 @@ static int viafb_sync(struct fb_info *info)
return 0;
}
-int viafb_get_mode_index(int hres, int vres)
-{
- u32 i;
- DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n");
-
- for (i = 0; i < NUM_TOTAL_MODETABLE; i++)
- if (CLE266Modes[i].mode_array &&
- CLE266Modes[i].crtc[0].crtc.hor_addr == hres &&
- CLE266Modes[i].crtc[0].crtc.ver_addr == vres)
- break;
-
- if (i == NUM_TOTAL_MODETABLE)
- return VIA_RES_INVALID;
-
- return CLE266Modes[i].ModeIndex;
-}
-
static void check_available_device_to_enable(int device_id)
{
int device_num = 0;
@@ -1330,7 +1215,7 @@ static void retrieve_device_setting(struct viafb_ioctl_setting
setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode;
}
-static void parse_active_dev(void)
+static int parse_active_dev(void)
{
viafb_CRT_ON = STATE_OFF;
viafb_DVI_ON = STATE_OFF;
@@ -1341,60 +1226,63 @@ static void parse_active_dev(void)
IGA path to devices in SAMM case. */
/* Note: The previous of active_dev is primary device,
and the following is secondary device. */
- if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) {
+ if (!viafb_active_dev) {
+ viafb_CRT_ON = STATE_ON;
+ viafb_SAMM_ON = STATE_OFF;
+ } else if (!strcmp(viafb_active_dev, "CRT+DVI")) {
/* CRT+DVI */
viafb_CRT_ON = STATE_ON;
viafb_DVI_ON = STATE_ON;
viafb_primary_dev = CRT_Device;
- } else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) {
+ } else if (!strcmp(viafb_active_dev, "DVI+CRT")) {
/* DVI+CRT */
viafb_CRT_ON = STATE_ON;
viafb_DVI_ON = STATE_ON;
viafb_primary_dev = DVI_Device;
- } else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) {
+ } else if (!strcmp(viafb_active_dev, "CRT+LCD")) {
/* CRT+LCD */
viafb_CRT_ON = STATE_ON;
viafb_LCD_ON = STATE_ON;
viafb_primary_dev = CRT_Device;
- } else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) {
+ } else if (!strcmp(viafb_active_dev, "LCD+CRT")) {
/* LCD+CRT */
viafb_CRT_ON = STATE_ON;
viafb_LCD_ON = STATE_ON;
viafb_primary_dev = LCD_Device;
- } else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) {
+ } else if (!strcmp(viafb_active_dev, "DVI+LCD")) {
/* DVI+LCD */
viafb_DVI_ON = STATE_ON;
viafb_LCD_ON = STATE_ON;
viafb_primary_dev = DVI_Device;
- } else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) {
+ } else if (!strcmp(viafb_active_dev, "LCD+DVI")) {
/* LCD+DVI */
viafb_DVI_ON = STATE_ON;
viafb_LCD_ON = STATE_ON;
viafb_primary_dev = LCD_Device;
- } else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) {
+ } else if (!strcmp(viafb_active_dev, "LCD+LCD2")) {
viafb_LCD_ON = STATE_ON;
viafb_LCD2_ON = STATE_ON;
viafb_primary_dev = LCD_Device;
- } else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) {
+ } else if (!strcmp(viafb_active_dev, "LCD2+LCD")) {
viafb_LCD_ON = STATE_ON;
viafb_LCD2_ON = STATE_ON;
viafb_primary_dev = LCD2_Device;
- } else if (!strncmp(viafb_active_dev, "CRT", 3)) {
+ } else if (!strcmp(viafb_active_dev, "CRT")) {
/* CRT only */
viafb_CRT_ON = STATE_ON;
viafb_SAMM_ON = STATE_OFF;
- } else if (!strncmp(viafb_active_dev, "DVI", 3)) {
+ } else if (!strcmp(viafb_active_dev, "DVI")) {
/* DVI only */
viafb_DVI_ON = STATE_ON;
viafb_SAMM_ON = STATE_OFF;
- } else if (!strncmp(viafb_active_dev, "LCD", 3)) {
+ } else if (!strcmp(viafb_active_dev, "LCD")) {
/* LCD only */
viafb_LCD_ON = STATE_ON;
viafb_SAMM_ON = STATE_OFF;
- } else {
- viafb_CRT_ON = STATE_ON;
- viafb_SAMM_ON = STATE_OFF;
- }
+ } else
+ return -EINVAL;
+
+ return 0;
}
static int parse_port(char *opt_str, int *output_interface)
@@ -1823,35 +1711,37 @@ static void viafb_remove_proc(struct proc_dir_entry *viafb_entry)
remove_proc_entry("viafb", NULL);
}
-static void parse_mode(const char *str, u32 *xres, u32 *yres)
+static int parse_mode(const char *str, u32 *xres, u32 *yres)
{
char *ptr;
+ if (!str) {
+ *xres = 640;
+ *yres = 480;
+ return 0;
+ }
+
*xres = simple_strtoul(str, &ptr, 10);
if (ptr[0] != 'x')
- goto out_default;
+ return -EINVAL;
*yres = simple_strtoul(&ptr[1], &ptr, 10);
if (ptr[0])
- goto out_default;
-
- return;
+ return -EINVAL;
-out_default:
- printk(KERN_WARNING "viafb received invalid mode string: %s\n", str);
- *xres = 640;
- *yres = 480;
+ return 0;
}
static int __devinit via_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
u32 default_xres, default_yres;
- int vmode_index;
+ struct VideoModeTable *vmode_entry;
+ struct fb_var_screeninfo default_var;
u32 viafb_par_length;
DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
-
+ memset(&default_var, 0, sizeof(default_var));
viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8);
/* Allocate fb_info and ***_par here, also including some other needed
@@ -1877,7 +1767,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
if (viafb_dual_fb)
viafb_SAMM_ON = 1;
- parse_active_dev();
parse_lcd_port();
parse_dvi_port();
@@ -1926,9 +1815,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
}
parse_mode(viafb_mode, &default_xres, &default_yres);
- vmode_index = viafb_get_mode_index(default_xres, default_yres);
- DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
-
+ vmode_entry = viafb_get_mode(default_xres, default_yres);
if (viafb_SAMM_ON == 1) {
parse_mode(viafb_mode1, &viafb_second_xres,
&viafb_second_yres);
@@ -1947,19 +1834,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
viafb_second_virtual_yres = viafb_second_yres;
}
- switch (viafb_bpp) {
- case 0 ... 8:
- viafb_bpp = 8;
- break;
- case 9 ... 16:
- viafb_bpp = 16;
- break;
- case 17 ... 32:
- viafb_bpp = 32;
- break;
- default:
- viafb_bpp = 8;
- }
default_var.xres = default_xres;
default_var.yres = default_yres;
switch (default_xres) {
@@ -1972,8 +1846,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
}
default_var.yres_virtual = default_yres;
default_var.bits_per_pixel = viafb_bpp;
- if (default_var.bits_per_pixel == 15)
- default_var.bits_per_pixel = 16;
default_var.pixclock =
viafb_get_pixclock(default_xres, default_yres, viafb_refresh);
default_var.left_margin = (default_xres >> 3) & 0xf8;
@@ -1982,6 +1854,8 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
default_var.lower_margin = 4;
default_var.hsync_len = default_var.left_margin;
default_var.vsync_len = 4;
+ viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
+ viafbinfo->var = default_var;
if (viafb_dual_fb) {
viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev);
@@ -2016,8 +1890,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
default_var.yres = viafb_second_yres;
default_var.xres_virtual = viafb_second_virtual_xres;
default_var.yres_virtual = viafb_second_virtual_yres;
- if (viafb_bpp1 != viafb_bpp)
- viafb_bpp1 = viafb_bpp;
default_var.bits_per_pixel = viafb_bpp1;
default_var.pixclock =
viafb_get_pixclock(viafb_second_xres, viafb_second_yres,
@@ -2037,9 +1909,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
&viafbinfo1->fix);
}
- viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
- viafb_check_var(&default_var, viafbinfo);
- viafbinfo->var = default_var;
+ viafb_check_var(&viafbinfo->var, viafbinfo);
viafb_update_fix(viafbinfo);
viaparinfo->depth = fb_get_color_depth(&viafbinfo->var,
&viafbinfo->fix);
@@ -2197,12 +2067,20 @@ static struct pci_driver viafb_driver = {
static int __init viafb_init(void)
{
+ u32 dummy;
#ifndef MODULE
char *option = NULL;
if (fb_get_options("viafb", &option))
return -ENODEV;
viafb_setup(option);
#endif
+ if (parse_mode(viafb_mode, &dummy, &dummy)
+ || parse_mode(viafb_mode1, &dummy, &dummy)
+ || viafb_bpp < 0 || viafb_bpp > 32
+ || viafb_bpp1 < 0 || viafb_bpp1 > 32
+ || parse_active_dev())
+ return -EINVAL;
+
printk(KERN_INFO
"VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n",
VERSION_MAJOR, VERSION_MINOR);
@@ -2230,15 +2108,12 @@ static struct fb_ops viafb_ops = {
.fb_cursor = viafb_cursor,
.fb_ioctl = viafb_ioctl,
.fb_sync = viafb_sync,
- .fb_setcmap = viafb_setcmap,
};
module_init(viafb_init);
module_exit(viafb_exit);
#ifdef MODULE
-module_param(viafb_memsize, int, S_IRUSR);
-
module_param(viafb_mode, charp, S_IRUSR);
MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)");
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 0c94d244192..61b5953cd15 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -83,22 +83,16 @@ struct viafb_par {
extern unsigned int viafb_second_virtual_yres;
extern unsigned int viafb_second_virtual_xres;
-extern unsigned int viafb_second_offset;
-extern int viafb_second_size;
extern int viafb_SAMM_ON;
extern int viafb_dual_fb;
extern int viafb_LCD2_ON;
extern int viafb_LCD_ON;
extern int viafb_DVI_ON;
extern int viafb_hotplug;
-extern int viafb_memsize;
extern int strict_strtoul(const char *cp, unsigned int base,
unsigned long *res);
-void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
- int mode_index);
-int viafb_get_mode_index(int hres, int vres);
u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
*plvds_setting_info, struct lvds_chip_information
*plvds_chip_info, u8 index);
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
index b74f8a67923..af50e244016 100644
--- a/drivers/video/via/viamode.c
+++ b/drivers/video/via/viamode.c
@@ -412,7 +412,7 @@ struct io_reg PM1024x768[] = { {VIASR, 0x16, 0xBF, 0x0C},
};
struct patch_table res_patch_table[] = {
- {VIA_RES_1024X768, ARRAY_SIZE(PM1024x768), PM1024x768}
+ {ARRAY_SIZE(PM1024x768), PM1024x768}
};
/* struct VPITTable {
@@ -879,169 +879,151 @@ struct crt_mode_table CRTM2048x1536[] = {
{2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} }
};
-/* Video Mode Table */
-/* struct VideoModeTable {*/
-/* int ModeIndex;*/
-/* struct crt_mode_table *crtc;*/
-/* int mode_array;*/
-/* };*/
-struct VideoModeTable CLE266Modes[] = {
+struct VideoModeTable viafb_modes[] = {
/* Display : 480x640 (GTF) */
- {VIA_RES_480X640, CRTM480x640, ARRAY_SIZE(CRTM480x640)},
+ {CRTM480x640, ARRAY_SIZE(CRTM480x640)},
/* Display : 640x480 */
- {VIA_RES_640X480, CRTM640x480, ARRAY_SIZE(CRTM640x480)},
+ {CRTM640x480, ARRAY_SIZE(CRTM640x480)},
/* Display : 720x480 (GTF) */
- {VIA_RES_720X480, CRTM720x480, ARRAY_SIZE(CRTM720x480)},
+ {CRTM720x480, ARRAY_SIZE(CRTM720x480)},
/* Display : 720x576 (GTF) */
- {VIA_RES_720X576, CRTM720x576, ARRAY_SIZE(CRTM720x576)},
+ {CRTM720x576, ARRAY_SIZE(CRTM720x576)},
/* Display : 800x600 */
- {VIA_RES_800X600, CRTM800x600, ARRAY_SIZE(CRTM800x600)},
+ {CRTM800x600, ARRAY_SIZE(CRTM800x600)},
/* Display : 800x480 (CVT) */
- {VIA_RES_800X480, CRTM800x480, ARRAY_SIZE(CRTM800x480)},
+ {CRTM800x480, ARRAY_SIZE(CRTM800x480)},
/* Display : 848x480 (CVT) */
- {VIA_RES_848X480, CRTM848x480, ARRAY_SIZE(CRTM848x480)},
+ {CRTM848x480, ARRAY_SIZE(CRTM848x480)},
/* Display : 852x480 (GTF) */
- {VIA_RES_856X480, CRTM852x480, ARRAY_SIZE(CRTM852x480)},
+ {CRTM852x480, ARRAY_SIZE(CRTM852x480)},
/* Display : 1024x512 (GTF) */
- {VIA_RES_1024X512, CRTM1024x512, ARRAY_SIZE(CRTM1024x512)},
+ {CRTM1024x512, ARRAY_SIZE(CRTM1024x512)},
/* Display : 1024x600 */
- {VIA_RES_1024X600, CRTM1024x600, ARRAY_SIZE(CRTM1024x600)},
-
- /* Display : 1024x576 (GTF) */
- /*{ VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, */
+ {CRTM1024x600, ARRAY_SIZE(CRTM1024x600)},
/* Display : 1024x768 */
- {VIA_RES_1024X768, CRTM1024x768, ARRAY_SIZE(CRTM1024x768)},
+ {CRTM1024x768, ARRAY_SIZE(CRTM1024x768)},
/* Display : 1152x864 */
- {VIA_RES_1152X864, CRTM1152x864, ARRAY_SIZE(CRTM1152x864)},
+ {CRTM1152x864, ARRAY_SIZE(CRTM1152x864)},
/* Display : 1280x768 (GTF) */
- {VIA_RES_1280X768, CRTM1280x768, ARRAY_SIZE(CRTM1280x768)},
+ {CRTM1280x768, ARRAY_SIZE(CRTM1280x768)},
/* Display : 960x600 (CVT) */
- {VIA_RES_960X600, CRTM960x600, ARRAY_SIZE(CRTM960x600)},
+ {CRTM960x600, ARRAY_SIZE(CRTM960x600)},
/* Display : 1000x600 (GTF) */
- {VIA_RES_1000X600, CRTM1000x600, ARRAY_SIZE(CRTM1000x600)},
+ {CRTM1000x600, ARRAY_SIZE(CRTM1000x600)},
/* Display : 1024x576 (GTF) */
- {VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)},
+ {CRTM1024x576, ARRAY_SIZE(CRTM1024x576)},
/* Display : 1088x612 (GTF) */
- {VIA_RES_1088X612, CRTM1088x612, ARRAY_SIZE(CRTM1088x612)},
+ {CRTM1088x612, ARRAY_SIZE(CRTM1088x612)},
/* Display : 1152x720 (CVT) */
- {VIA_RES_1152X720, CRTM1152x720, ARRAY_SIZE(CRTM1152x720)},
+ {CRTM1152x720, ARRAY_SIZE(CRTM1152x720)},
/* Display : 1200x720 (GTF) */
- {VIA_RES_1200X720, CRTM1200x720, ARRAY_SIZE(CRTM1200x720)},
+ {CRTM1200x720, ARRAY_SIZE(CRTM1200x720)},
/* Display : 1280x600 (GTF) */
- {VIA_RES_1280X600, CRTM1280x600, ARRAY_SIZE(CRTM1280x600)},
+ {CRTM1280x600, ARRAY_SIZE(CRTM1280x600)},
/* Display : 1280x800 (CVT) */
- {VIA_RES_1280X800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)},
-
- /* Display : 1280x800 (GTF) */
- /*{ M1280x800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, */
+ {CRTM1280x800, ARRAY_SIZE(CRTM1280x800)},
/* Display : 1280x960 */
- {VIA_RES_1280X960, CRTM1280x960, ARRAY_SIZE(CRTM1280x960)},
+ {CRTM1280x960, ARRAY_SIZE(CRTM1280x960)},
/* Display : 1280x1024 */
- {VIA_RES_1280X1024, CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)},
+ {CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)},
/* Display : 1360x768 (CVT) */
- {VIA_RES_1360X768, CRTM1360x768, ARRAY_SIZE(CRTM1360x768)},
-
- /* Display : 1360x768 (CVT Reduce Blanking) */
- {VIA_RES_1360X768_RB, CRTM1360x768_RB,
- ARRAY_SIZE(CRTM1360x768_RB)},
+ {CRTM1360x768, ARRAY_SIZE(CRTM1360x768)},
/* Display : 1366x768 */
- {VIA_RES_1366X768, CRTM1366x768, ARRAY_SIZE(CRTM1366x768)},
+ {CRTM1366x768, ARRAY_SIZE(CRTM1366x768)},
/* Display : 1368x768 (GTF) */
- /*{ M1368x768,CRTM1368x768,ARRAY_SIZE(CRTM1368x768)}, */
- /* Display : 1368x768 (GTF) */
- {VIA_RES_1368X768, CRTM1368x768, ARRAY_SIZE(CRTM1368x768)},
+ {CRTM1368x768, ARRAY_SIZE(CRTM1368x768)},
/* Display : 1440x900 (CVT) */
- {VIA_RES_1440X900, CRTM1440x900, ARRAY_SIZE(CRTM1440x900)},
-
- /* Display : 1440x900 (CVT Reduce Blanking) */
- {VIA_RES_1440X900_RB, CRTM1440x900_RB,
- ARRAY_SIZE(CRTM1440x900_RB)},
+ {CRTM1440x900, ARRAY_SIZE(CRTM1440x900)},
/* Display : 1440x1050 (GTF) */
- {VIA_RES_1440X1050, CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)},
-
- /* Display : 1400x1050 (CVT Reduce Blanking) */
- {VIA_RES_1400X1050_RB, CRTM1400x1050_RB,
- ARRAY_SIZE(CRTM1400x1050_RB)},
+ {CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)},
/* Display : 1600x900 (CVT) */
- {VIA_RES_1600X900, CRTM1600x900, ARRAY_SIZE(CRTM1600x900)},
-
- /* Display : 1600x900 (CVT Reduce Blanking) */
- {VIA_RES_1600X900_RB, CRTM1600x900_RB,
- ARRAY_SIZE(CRTM1600x900_RB)},
+ {CRTM1600x900, ARRAY_SIZE(CRTM1600x900)},
/* Display : 1600x1024 (GTF) */
- {VIA_RES_1600X1024, CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)},
+ {CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)},
/* Display : 1600x1200 */
- {VIA_RES_1600X1200, CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)},
+ {CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)},
/* Display : 1680x1050 (CVT) */
- {VIA_RES_1680X1050, CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)},
-
- /* Display : 1680x1050 (CVT Reduce Blanking) */
- {VIA_RES_1680X1050_RB, CRTM1680x1050_RB,
- ARRAY_SIZE(CRTM1680x1050_RB)},
+ {CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)},
/* Display : 1792x1344 (DMT) */
- {VIA_RES_1792X1344, CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)},
+ {CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)},
/* Display : 1856x1392 (DMT) */
- {VIA_RES_1856X1392, CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)},
+ {CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)},
/* Display : 1920x1440 */
- {VIA_RES_1920X1440, CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)},
+ {CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)},
/* Display : 2048x1536 */
- {VIA_RES_2048X1536, CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)},
+ {CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)},
/* Display : 1280x720 */
- {VIA_RES_1280X720, CRTM1280x720, ARRAY_SIZE(CRTM1280x720)},
+ {CRTM1280x720, ARRAY_SIZE(CRTM1280x720)},
/* Display : 1920x1080 (CVT) */
- {VIA_RES_1920X1080, CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)},
-
- /* Display : 1920x1080 (CVT Reduce Blanking) */
- {VIA_RES_1920X1080_RB, CRTM1920x1080_RB,
- ARRAY_SIZE(CRTM1920x1080_RB)},
+ {CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)},
/* Display : 1920x1200 (CVT) */
- {VIA_RES_1920X1200, CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)},
-
- /* Display : 1920x1200 (CVT Reduce Blanking) */
- {VIA_RES_1920X1200_RB, CRTM1920x1200_RB,
- ARRAY_SIZE(CRTM1920x1200_RB)},
+ {CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)},
/* Display : 1400x1050 (CVT) */
- {VIA_RES_1400X1050, CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)}
+ {CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)}
};
+
+struct VideoModeTable viafb_rb_modes[] = {
+ /* Display : 1360x768 (CVT Reduce Blanking) */
+ {CRTM1360x768_RB, ARRAY_SIZE(CRTM1360x768_RB)},
+
+ /* Display : 1440x900 (CVT Reduce Blanking) */
+ {CRTM1440x900_RB, ARRAY_SIZE(CRTM1440x900_RB)},
+
+ /* Display : 1400x1050 (CVT Reduce Blanking) */
+ {CRTM1400x1050_RB, ARRAY_SIZE(CRTM1400x1050_RB)},
+
+ /* Display : 1600x900 (CVT Reduce Blanking) */
+ {CRTM1600x900_RB, ARRAY_SIZE(CRTM1600x900_RB)},
+
+ /* Display : 1680x1050 (CVT Reduce Blanking) */
+ {CRTM1680x1050_RB, ARRAY_SIZE(CRTM1680x1050_RB)},
+
+ /* Display : 1920x1080 (CVT Reduce Blanking) */
+ {CRTM1920x1080_RB, ARRAY_SIZE(CRTM1920x1080_RB)},
+
+ /* Display : 1920x1200 (CVT Reduce Blanking) */
+ {CRTM1920x1200_RB, ARRAY_SIZE(CRTM1920x1200_RB)}
+};
+
struct crt_mode_table CEAM1280x720[] = {
{REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP,
M1280X720_CEA_R60_VSP,
@@ -1056,8 +1038,8 @@ struct crt_mode_table CEAM1920x1080[] = {
};
struct VideoModeTable CEA_HDMI_Modes[] = {
/* Display : 1280x720 */
- {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
- {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
+ {CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
+ {CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
};
int NUM_TOTAL_RES_MAP_REFRESH = ARRAY_SIZE(res_map_refresh_tbl);
@@ -1069,4 +1051,28 @@ int NUM_TOTAL_CX700_ModeXregs = ARRAY_SIZE(CX700_ModeXregs);
int NUM_TOTAL_VX855_ModeXregs = ARRAY_SIZE(VX855_ModeXregs);
int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs);
int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table);
-int NUM_TOTAL_MODETABLE = ARRAY_SIZE(CLE266Modes);
+
+
+struct VideoModeTable *viafb_get_mode(int hres, int vres)
+{
+ u32 i;
+ for (i = 0; i < ARRAY_SIZE(viafb_modes); i++)
+ if (viafb_modes[i].mode_array &&
+ viafb_modes[i].crtc[0].crtc.hor_addr == hres &&
+ viafb_modes[i].crtc[0].crtc.ver_addr == vres)
+ return &viafb_modes[i];
+
+ return NULL;
+}
+
+struct VideoModeTable *viafb_get_rb_mode(int hres, int vres)
+{
+ u32 i;
+ for (i = 0; i < ARRAY_SIZE(viafb_rb_modes); i++)
+ if (viafb_rb_modes[i].mode_array &&
+ viafb_rb_modes[i].crtc[0].crtc.hor_addr == hres &&
+ viafb_rb_modes[i].crtc[0].crtc.ver_addr == vres)
+ return &viafb_rb_modes[i];
+
+ return NULL;
+}
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
index a9d6554fabd..5b1ced86514 100644
--- a/drivers/video/via/viamode.h
+++ b/drivers/video/via/viamode.h
@@ -32,13 +32,11 @@ struct VPITTable {
};
struct VideoModeTable {
- int ModeIndex;
struct crt_mode_table *crtc;
int mode_array;
};
struct patch_table {
- int mode_index;
int table_length;
struct io_reg *io_reg_table;
};
@@ -59,13 +57,11 @@ extern int NUM_TOTAL_CX700_ModeXregs;
extern int NUM_TOTAL_VX855_ModeXregs;
extern int NUM_TOTAL_CLE266_ModeXregs;
extern int NUM_TOTAL_PATCH_MODE;
-extern int NUM_TOTAL_MODETABLE;
/********************/
/* Mode Table */
/********************/
-extern struct VideoModeTable CLE266Modes[];
extern struct crt_mode_table CEAM1280x720[];
extern struct crt_mode_table CEAM1920x1080[];
extern struct VideoModeTable CEA_HDMI_Modes[];
@@ -81,4 +77,8 @@ extern struct io_reg CLE266_ModeXregs[];
extern struct io_reg PM1024x768[];
extern struct patch_table res_patch_table[];
extern struct VPITTable VPIT;
+
+struct VideoModeTable *viafb_get_mode(int hres, int vres);
+struct VideoModeTable *viafb_get_rb_mode(int hres, int vres);
+
#endif /* __VIAMODE_H__ */
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index 65ccd215d49..d31dc96f838 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -18,7 +18,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/svga.h>
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 2376f688ec8..31b0e17ed09 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
@@ -628,7 +629,7 @@ static int w100fb_resume(struct platform_device *dev)
#endif
-int __init w100fb_probe(struct platform_device *pdev)
+int __devinit w100fb_probe(struct platform_device *pdev)
{
int err = -EIO;
struct w100fb_mach_info *inf;
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 603598f4dbb..fa97d3e7c21 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -23,6 +23,7 @@
#include <linux/errno.h>
#include <linux/fb.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index ed7c8d0ddcc..3fcb83f0388 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -34,6 +34,7 @@
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/xilinxfb.h>
+#include <linux/slab.h>
#include <asm/dcr.h>
#define DRIVER_NAME "xilinxfb"
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 369f2eebbad..bfec7c29486 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -24,6 +24,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/delay.h>
+#include <linux/slab.h>
struct virtio_balloon
{
@@ -102,7 +103,8 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)
num = min(num, ARRAY_SIZE(vb->pfns));
for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
- struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY);
+ struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
+ __GFP_NOMEMALLOC | __GFP_NOWARN);
if (!page) {
if (printk_ratelimit())
dev_printk(KERN_INFO, &vb->vdev->dev,
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 1b657321699..24747aef195 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/list.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>
@@ -649,6 +650,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,
goto out_req_regions;
pci_set_drvdata(pci_dev, vp_dev);
+ pci_set_master(pci_dev);
/* we use the subsystem vendor/device id as the virtio vendor/device
* id. this allows us to use the same PCI vendor/device id for all
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 0db906b3c95..0f90634bcb8 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -20,6 +20,7 @@
#include <linux/virtio_ring.h>
#include <linux/virtio_config.h>
#include <linux/device.h>
+#include <linux/slab.h>
/* virtio guest is communicating with a virtual "device" that actually runs on
* a host processor. Memory barriers are used to control SMP effects. */
diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c
index 9554ad5f9af..f2d9e667972 100644
--- a/drivers/vlynq/vlynq.c
+++ b/drivers/vlynq/vlynq.c
@@ -30,6 +30,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/vlynq.h>
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 37f08c85060..6b85e7fefa4 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/mfd/core.h>
#include <linux/mfd/ds1wm.h>
+#include <linux/slab.h>
#include <asm/io.h>
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
index 406caa6a71c..e5f74416d4b 100644
--- a/drivers/w1/masters/ds2482.c
+++ b/drivers/w1/masters/ds2482.c
@@ -214,7 +214,7 @@ static int ds2482_wait_1wire_idle(struct ds2482_data *pdev)
(++retries < DS2482_WAIT_IDLE_TIMEOUT));
}
- if (retries > DS2482_WAIT_IDLE_TIMEOUT)
+ if (retries >= DS2482_WAIT_IDLE_TIMEOUT)
printk(KERN_ERR "%s: timeout on channel %d\n",
__func__, pdev->channel);
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
index 59ad6e95af8..02bf7bf7160 100644
--- a/drivers/w1/masters/ds2490.c
+++ b/drivers/w1/masters/ds2490.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/usb.h>
+#include <linux/slab.h>
#include "../w1_int.h"
#include "../w1.h"
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
index 65244c02551..a3b6a74c67a 100644
--- a/drivers/w1/masters/mxc_w1.c
+++ b/drivers/w1/masters/mxc_w1.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
@@ -102,7 +103,7 @@ static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)
return ((__raw_readb(ctrl_addr)) >> 3) & 0x1;
}
-static int __init mxc_w1_probe(struct platform_device *pdev)
+static int __devinit mxc_w1_probe(struct platform_device *pdev)
{
struct mxc_w1_device *mdev;
struct resource *res;
@@ -166,7 +167,7 @@ failed_clk:
/*
* disassociate the w1 device from the driver
*/
-static int mxc_w1_remove(struct platform_device *pdev)
+static int __devexit mxc_w1_remove(struct platform_device *pdev)
{
struct mxc_w1_device *mdev = platform_get_drvdata(pdev);
struct resource *res;
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
index 0d92969404c..3a7e9ff8a74 100644
--- a/drivers/w1/masters/omap_hdq.c
+++ b/drivers/w1/masters/omap_hdq.c
@@ -12,9 +12,11 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/sched.h>
#include <asm/irq.h>
#include <mach/hardware.h>
@@ -72,7 +74,7 @@ struct hdq_data {
int init_trans;
};
-static int __init omap_hdq_probe(struct platform_device *pdev);
+static int __devinit omap_hdq_probe(struct platform_device *pdev);
static int omap_hdq_remove(struct platform_device *pdev);
static struct platform_driver omap_hdq_driver = {
@@ -558,7 +560,7 @@ static void omap_w1_write_byte(void *_hdq, u8 byte)
return;
}
-static int __init omap_hdq_probe(struct platform_device *pdev)
+static int __devinit omap_hdq_probe(struct platform_device *pdev)
{
struct hdq_data *hdq_data;
struct resource *res;
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index 6f8866d6a90..fcbe742188a 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/w1-gpio.h>
#include "../w1.h"
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c
index 13944714882..d2bf32118a9 100644
--- a/drivers/w1/slaves/w1_ds2433.c
+++ b/drivers/w1/slaves/w1_ds2433.c
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/types.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#ifdef CONFIG_W1_SLAVE_DS2433_CRC
#include <linux/crc16.h>
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
index 59f708efe25..6e153343e11 100644
--- a/drivers/w1/slaves/w1_ds2760.c
+++ b/drivers/w1/slaves/w1_ds2760.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/idr.h>
+#include <linux/gfp.h>
#include "../w1.h"
#include "../w1_int.h"
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 1ed3d554e37..17726a05a0a 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -115,9 +115,8 @@ static struct w1_therm_family_converter w1_therm_families[] = {
static inline int w1_DS18B20_convert_temp(u8 rom[9])
{
- int t = ((s16)rom[1] << 8) | rom[0];
- t = t*1000/16;
- return t;
+ s16 t = le16_to_cpup((__le16 *)rom);
+ return t*1000/16;
}
static inline int w1_DS18S20_convert_temp(u8 rom[9])
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index acc7e3b7fe1..ad5897dc449 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -986,7 +986,7 @@ int w1_process(void *data)
return 0;
}
-static int w1_init(void)
+static int __init w1_init(void)
{
int retval;
@@ -1034,7 +1034,7 @@ err_out_exit_init:
return retval;
}
-static void w1_fini(void)
+static void __exit w1_fini(void)
{
struct w1_master *dev;
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 4a46ed58ece..b50be3f1073 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -23,6 +23,7 @@
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include "w1.h"
#include "w1_log.h"
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 45c126fea31..7e667bc77ef 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/connector.h>
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3da3f48720a..0bf5020d0d3 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -194,10 +194,10 @@ config EP93XX_WATCHDOG
config OMAP_WATCHDOG
tristate "OMAP Watchdog"
- depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP3
+ depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
help
- Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y'
- here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer.
+ Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y'
+ here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
config PNX4008_WATCHDOG
tristate "PNX4008 Watchdog"
@@ -289,6 +289,23 @@ config ADX_WATCHDOG
Say Y here if you want support for the watchdog timer on Avionic
Design Xanthos boards.
+config TS72XX_WATCHDOG
+ tristate "TS-72XX SBC Watchdog"
+ depends on MACH_TS72XX
+ help
+ Technologic Systems TS-7200, TS-7250 and TS-7260 boards have
+ watchdog timer implemented in a external CPLD chip. Say Y here
+ if you want to support for the watchdog timer on TS-72XX boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ts72xx_wdt.
+
+config MAX63XX_WATCHDOG
+ tristate "Max63xx watchdog"
+ depends on ARM && HAS_IOMEM
+ help
+ Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
+
# AVR32 Architecture
config AT32AP700X_WDT
@@ -845,10 +862,10 @@ config TXX9_WDT
# POWERPC Architecture
config GEF_WDT
- tristate "GE Fanuc Watchdog Timer"
+ tristate "GE Watchdog Timer"
depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
---help---
- Watchdog timer found in a number of GE Fanuc single board computers.
+ Watchdog timer found in a number of GE single board computers.
config MPC5200_WDT
bool "MPC52xx Watchdog Timer"
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 475c6110006..5e3cb95bb0e 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o
+obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
# AVR32 Architecture
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -142,4 +143,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o
# Architecture Independant
obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
+obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 4d18c874d96..2ffce4d7544 100644
--- a/drivers/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
@@ -150,7 +150,7 @@ static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int options, retval = -EINVAL;
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.firmware_version = 1,
.identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 824d076a5cd..4d40965d2c9 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -137,7 +137,7 @@ static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int new_timeout;
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c
index 9d7d155364f..af6e6b16475 100644
--- a/drivers/watchdog/adx_wdt.c
+++ b/drivers/watchdog/adx_wdt.c
@@ -7,6 +7,7 @@
*/
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/io.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
@@ -37,7 +38,7 @@ struct adx_wdt {
spinlock_t lock;
};
-static struct watchdog_info adx_wdt_info = {
+static const struct watchdog_info adx_wdt_info = {
.identity = "Avionic Design Xanthos Watchdog",
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
};
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 937a80fb61e..1e9caea8ff8 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -180,7 +180,7 @@ static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index f90afdb1b25..d8d4da9a483 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -238,7 +238,7 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
| WDIOF_MAGICCLOSE,
.firmware_version = 1,
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index 2bb95cd308c..c764c52412e 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -219,7 +219,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data,
static long ar7_wdt_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.identity = LONGNAME,
.firmware_version = 1,
.options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index 037847923dc..1cddf92cb9a 100644
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
@@ -32,6 +32,7 @@
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#define TIMEOUT_MIN 1
#define TIMEOUT_MAX 2
@@ -202,7 +203,7 @@ static int at32_wdt_get_status(void)
return status;
}
-static struct watchdog_info at32_wdt_info = {
+static const struct watchdog_info at32_wdt_info = {
.identity = "at32ap700x watchdog",
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index b185dafe149..b3046dc4b56 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -121,7 +121,7 @@ static int at91_wdt_settimeout(int new_time)
return 0;
}
-static struct watchdog_info at91_wdt_info = {
+static const struct watchdog_info at91_wdt_info = {
.identity = "at91 watchdog",
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
};
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 751c003864a..5f245522397 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -149,7 +149,7 @@ static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data,
return len;
}
-static struct watchdog_info bcm47xx_wdt_info = {
+static const struct watchdog_info bcm47xx_wdt_info = {
.identity = DRV_NAME,
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 2159e668751..9c7ccd1e908 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -19,8 +19,6 @@
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/uaccess.h>
@@ -74,7 +72,7 @@
static unsigned int timeout = WATCHDOG_TIMEOUT;
static int nowayout = WATCHDOG_NOWAYOUT;
-static struct watchdog_info bfin_wdt_info;
+static const struct watchdog_info bfin_wdt_info;
static unsigned long open_check;
static char expect_close;
static DEFINE_SPINLOCK(bfin_wdt_spinlock);
@@ -309,26 +307,6 @@ static long bfin_wdt_ioctl(struct file *file,
}
}
-/**
- * bfin_wdt_notify_sys - Notifier Handler
- * @this: notifier block
- * @code: notifier event
- * @unused: unused
- *
- * Handles specific events, such as turning off the watchdog during a
- * shutdown event.
- */
-static int bfin_wdt_notify_sys(struct notifier_block *this,
- unsigned long code, void *unused)
-{
- stampit();
-
- if (code == SYS_DOWN || code == SYS_HALT)
- bfin_wdt_stop();
-
- return NOTIFY_DONE;
-}
-
#ifdef CONFIG_PM
static int state_before_suspend;
@@ -388,40 +366,28 @@ static struct miscdevice bfin_wdt_miscdev = {
.fops = &bfin_wdt_fops,
};
-static struct watchdog_info bfin_wdt_info = {
+static const struct watchdog_info bfin_wdt_info = {
.identity = "Blackfin Watchdog",
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
};
-static struct notifier_block bfin_wdt_notifier = {
- .notifier_call = bfin_wdt_notify_sys,
-};
-
/**
* bfin_wdt_probe - Initialize module
*
- * Registers the misc device and notifier handler. Actual device
+ * Registers the misc device. Actual device
* initialization is handled by bfin_wdt_open().
*/
static int __devinit bfin_wdt_probe(struct platform_device *pdev)
{
int ret;
- ret = register_reboot_notifier(&bfin_wdt_notifier);
- if (ret) {
- pr_devinit(KERN_ERR PFX
- "cannot register reboot notifier (err=%d)\n", ret);
- return ret;
- }
-
ret = misc_register(&bfin_wdt_miscdev);
if (ret) {
pr_devinit(KERN_ERR PFX
"cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, ret);
- unregister_reboot_notifier(&bfin_wdt_notifier);
return ret;
}
@@ -434,21 +400,33 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev)
/**
* bfin_wdt_remove - Initialize module
*
- * Unregisters the misc device and notifier handler. Actual device
+ * Unregisters the misc device. Actual device
* deinitialization is handled by bfin_wdt_close().
*/
static int __devexit bfin_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&bfin_wdt_miscdev);
- unregister_reboot_notifier(&bfin_wdt_notifier);
return 0;
}
+/**
+ * bfin_wdt_shutdown - Soft Shutdown Handler
+ *
+ * Handles the soft shutdown event.
+ */
+static void bfin_wdt_shutdown(struct platform_device *pdev)
+{
+ stampit();
+
+ bfin_wdt_stop();
+}
+
static struct platform_device *bfin_wdt_device;
static struct platform_driver bfin_wdt_driver = {
.probe = bfin_wdt_probe,
.remove = __devexit_p(bfin_wdt_remove),
+ .shutdown = bfin_wdt_shutdown,
.suspend = bfin_wdt_suspend,
.resume = bfin_wdt_resume,
.driver = {
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index e8380ef65c1..801ead19149 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
#ifdef CONFIG_FSL_BOOKE
#define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15))
-#define WDTP_MASK (WDTP(0))
+#define WDTP_MASK (WDTP(0x3f))
#else
#define WDTP(x) (TCR_WP(x))
#define WDTP_MASK (TCR_WP_MASK)
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index 923cc68dba2..9291506b8b2 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -257,7 +257,7 @@ static long coh901327_ioctl(struct file *file, unsigned int cmd,
struct watchdog_info __user *ident;
int __user *i;
} uarg;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_CARDRESET |
WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index 71f6d7eec9a..edd3475f41d 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -154,7 +154,7 @@ static long cpu5wdt_ioctl(struct file *file, unsigned int cmd,
void __user *argp = (void __user *)arg;
int __user *p = argp;
unsigned int value;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_CARDRESET,
.identity = "CPU5 WDT",
};
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 081f2955419..ba2efce4b40 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -24,6 +24,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timer.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -403,7 +404,7 @@ static int cpwd_release(struct inode *inode, struct file *file)
static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- static struct watchdog_info info = {
+ static const struct watchdog_info info = {
.options = WDIOF_SETTIMEOUT,
.firmware_version = 1,
.identity = DRIVER_NAME,
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 887136de185..596ba604e78 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -26,6 +26,7 @@
#include <linux/io.h>
#include <linux/device.h>
#include <linux/clk.h>
+#include <linux/slab.h>
#define MODULE_NAME "DAVINCI-WDT: "
@@ -142,7 +143,7 @@ davinci_wdt_write(struct file *file, const char *data, size_t len,
return len;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING,
.identity = "DaVinci Watchdog",
};
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index cdd55e0d09f..88ed54e50f7 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -131,7 +131,7 @@ ep93xx_wdt_write(struct file *file, const char __user *data, size_t len,
return len;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE,
.identity = "EP93xx Watchdog",
};
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index 9add3541fb4..d1c4e55b1db 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -238,7 +238,7 @@ static long eurwdt_ioctl(struct file *file,
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
| WDIOF_MAGICCLOSE,
.firmware_version = 1,
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index 734d9806a87..abdbad034a6 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -1,9 +1,9 @@
/*
- * GE Fanuc watchdog userspace interface
+ * GE watchdog userspace interface
*
- * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Author: Martyn Welch <martyn.welch@ge.com>
*
- * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, 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
@@ -161,11 +161,11 @@ static long gef_wdt_ioctl(struct file *file, unsigned int cmd,
int timeout;
int options;
void __user *argp = (void __user *)arg;
- static struct watchdog_info info = {
+ static const struct watchdog_info info = {
.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
WDIOF_KEEPALIVEPING,
.firmware_version = 0,
- .identity = "GE Fanuc watchdog",
+ .identity = "GE watchdog",
};
switch (cmd) {
@@ -311,7 +311,7 @@ static struct of_platform_driver gef_wdt_driver = {
static int __init gef_wdt_init(void)
{
- printk(KERN_INFO "GE Fanuc watchdog driver\n");
+ printk(KERN_INFO "GE watchdog driver\n");
return of_register_platform_driver(&gef_wdt_driver);
}
@@ -323,8 +323,8 @@ static void __exit gef_wdt_exit(void)
module_init(gef_wdt_init);
module_exit(gef_wdt_exit);
-MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>");
-MODULE_DESCRIPTION("GE Fanuc watchdog driver");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
+MODULE_DESCRIPTION("GE watchdog driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
MODULE_ALIAS("platform: gef_wdt");
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c
index 38252ff828c..9b49b125ad5 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -142,7 +142,7 @@ static long geodewdt_ioctl(struct file *file, unsigned int cmd,
int __user *p = argp;
int interval;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
| WDIOF_MAGICCLOSE,
.firmware_version = 1,
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index a6c5674c78e..809e7167a62 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -39,7 +39,6 @@
#include <linux/efi.h>
#include <linux/string.h>
#include <linux/bootmem.h>
-#include <linux/slab.h>
#include <asm/desc.h>
#include <asm/cacheflush.h>
@@ -443,7 +442,7 @@ static void hpwdt_ping(void)
static int hpwdt_change_timer(int new_margin)
{
/* Arbitrary, can't find the card's limits */
- if (new_margin < 30 || new_margin > 600) {
+ if (new_margin < 5 || new_margin > 600) {
printk(KERN_WARNING
"hpwdt: New value passed in is invalid: %d seconds.\n",
new_margin);
@@ -554,7 +553,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data,
return len;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 7ba0b11ec52..bb9750a0394 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -34,7 +34,6 @@
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/ioport.h>
@@ -42,7 +41,7 @@
#include <linux/io.h>
/* Module and version information */
-#define ESB_VERSION "0.04"
+#define ESB_VERSION "0.05"
#define ESB_MODULE_NAME "i6300ESB timer"
#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
#define PFX ESB_MODULE_NAME ": "
@@ -65,7 +64,7 @@
/* Config register bits */
#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */
#define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */
-#define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */
+#define ESB_WDT_INTTYPE (0x03 << 0) /* Interrupt type on timer1 timeout */
/* Reload register bits */
#define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */
@@ -82,7 +81,9 @@ static unsigned long timer_alive;
static struct pci_dev *esb_pci;
static unsigned short triggered; /* The status of the watchdog upon boot */
static char esb_expect_close;
-static struct platform_device *esb_platform_device;
+
+/* We can only use 1 card due to the /dev/watchdog restriction */
+static int cards_found;
/* module parameters */
/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
@@ -111,8 +112,8 @@ MODULE_PARM_DESC(nowayout,
*/
static inline void esb_unlock_registers(void)
{
- writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
- writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
+ writew(ESB_UNLOCK1, ESB_RELOAD_REG);
+ writew(ESB_UNLOCK2, ESB_RELOAD_REG);
}
static int esb_timer_start(void)
@@ -256,7 +257,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int new_heartbeat;
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
@@ -332,11 +333,6 @@ static struct miscdevice esb_miscdev = {
/*
* Data for PCI driver interface
- *
- * This data only exists for exporting the supported
- * PCI ids via MODULE_DEVICE_TABLE. We do not actually
- * register a pci_driver, because someone else might one day
- * want to register another driver on the same PCI id.
*/
static struct pci_device_id esb_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
@@ -348,29 +344,19 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
* Init & exit routines
*/
-static unsigned char __devinit esb_getdevice(void)
+static unsigned char __devinit esb_getdevice(struct pci_dev *pdev)
{
- /*
- * Find the PCI device
- */
-
- esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_ESB_9, NULL);
-
- if (!esb_pci)
- return 0;
-
- if (pci_enable_device(esb_pci)) {
+ if (pci_enable_device(pdev)) {
printk(KERN_ERR PFX "failed to enable device\n");
goto err_devput;
}
- if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
+ if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) {
printk(KERN_ERR PFX "failed to request region\n");
goto err_disable;
}
- BASEADDR = pci_ioremap_bar(esb_pci, 0);
+ BASEADDR = pci_ioremap_bar(pdev, 0);
if (BASEADDR == NULL) {
/* Something's wrong here, BASEADDR has to be set */
printk(KERN_ERR PFX "failed to get BASEADDR\n");
@@ -378,14 +364,14 @@ static unsigned char __devinit esb_getdevice(void)
}
/* Done */
+ esb_pci = pdev;
return 1;
err_release:
- pci_release_region(esb_pci, 0);
+ pci_release_region(pdev, 0);
err_disable:
- pci_disable_device(esb_pci);
+ pci_disable_device(pdev);
err_devput:
- pci_dev_put(esb_pci);
return 0;
}
@@ -430,12 +416,23 @@ static void __devinit esb_initdevice(void)
esb_timer_set_heartbeat(heartbeat);
}
-static int __devinit esb_probe(struct platform_device *dev)
+static int __devinit esb_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
int ret;
+ cards_found++;
+ if (cards_found == 1)
+ printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
+ ESB_VERSION);
+
+ if (cards_found > 1) {
+ printk(KERN_ERR PFX "This driver only supports 1 device\n");
+ return -ENODEV;
+ }
+
/* Check whether or not the hardware watchdog is there */
- if (!esb_getdevice() || esb_pci == NULL)
+ if (!esb_getdevice(pdev) || esb_pci == NULL)
return -ENODEV;
/* Check that the heartbeat value is within it's range;
@@ -467,11 +464,11 @@ err_unmap:
iounmap(BASEADDR);
pci_release_region(esb_pci, 0);
pci_disable_device(esb_pci);
- pci_dev_put(esb_pci);
+ esb_pci = NULL;
return ret;
}
-static int __devexit esb_remove(struct platform_device *dev)
+static void __devexit esb_remove(struct pci_dev *pdev)
{
/* Stop the timer before we leave */
if (!nowayout)
@@ -482,54 +479,30 @@ static int __devexit esb_remove(struct platform_device *dev)
iounmap(BASEADDR);
pci_release_region(esb_pci, 0);
pci_disable_device(esb_pci);
- pci_dev_put(esb_pci);
- return 0;
+ esb_pci = NULL;
}
-static void esb_shutdown(struct platform_device *dev)
+static void esb_shutdown(struct pci_dev *pdev)
{
esb_timer_stop();
}
-static struct platform_driver esb_platform_driver = {
+static struct pci_driver esb_driver = {
+ .name = ESB_MODULE_NAME,
+ .id_table = esb_pci_tbl,
.probe = esb_probe,
.remove = __devexit_p(esb_remove),
.shutdown = esb_shutdown,
- .driver = {
- .owner = THIS_MODULE,
- .name = ESB_MODULE_NAME,
- },
};
static int __init watchdog_init(void)
{
- int err;
-
- printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
- ESB_VERSION);
-
- err = platform_driver_register(&esb_platform_driver);
- if (err)
- return err;
-
- esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME,
- -1, NULL, 0);
- if (IS_ERR(esb_platform_device)) {
- err = PTR_ERR(esb_platform_device);
- goto unreg_platform_driver;
- }
-
- return 0;
-
-unreg_platform_driver:
- platform_driver_unregister(&esb_platform_driver);
- return err;
+ return pci_register_driver(&esb_driver);
}
static void __exit watchdog_cleanup(void)
{
- platform_device_unregister(esb_platform_device);
- platform_driver_unregister(&esb_platform_driver);
+ pci_unregister_driver(&esb_driver);
printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
}
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 4bdb7f1a907..8da88603537 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -115,8 +115,37 @@ enum iTCO_chipsets {
TCO_3420, /* 3420 */
TCO_3450, /* 3450 */
TCO_EP80579, /* EP80579 */
- TCO_CPTD, /* CPT Desktop */
- TCO_CPTM, /* CPT Mobile */
+ TCO_CPT1, /* Cougar Point */
+ TCO_CPT2, /* Cougar Point Desktop */
+ TCO_CPT3, /* Cougar Point Mobile */
+ TCO_CPT4, /* Cougar Point */
+ TCO_CPT5, /* Cougar Point */
+ TCO_CPT6, /* Cougar Point */
+ TCO_CPT7, /* Cougar Point */
+ TCO_CPT8, /* Cougar Point */
+ TCO_CPT9, /* Cougar Point */
+ TCO_CPT10, /* Cougar Point */
+ TCO_CPT11, /* Cougar Point */
+ TCO_CPT12, /* Cougar Point */
+ TCO_CPT13, /* Cougar Point */
+ TCO_CPT14, /* Cougar Point */
+ TCO_CPT15, /* Cougar Point */
+ TCO_CPT16, /* Cougar Point */
+ TCO_CPT17, /* Cougar Point */
+ TCO_CPT18, /* Cougar Point */
+ TCO_CPT19, /* Cougar Point */
+ TCO_CPT20, /* Cougar Point */
+ TCO_CPT21, /* Cougar Point */
+ TCO_CPT22, /* Cougar Point */
+ TCO_CPT23, /* Cougar Point */
+ TCO_CPT24, /* Cougar Point */
+ TCO_CPT25, /* Cougar Point */
+ TCO_CPT26, /* Cougar Point */
+ TCO_CPT27, /* Cougar Point */
+ TCO_CPT28, /* Cougar Point */
+ TCO_CPT29, /* Cougar Point */
+ TCO_CPT30, /* Cougar Point */
+ TCO_CPT31, /* Cougar Point */
};
static struct {
@@ -173,8 +202,37 @@ static struct {
{"3420", 2},
{"3450", 2},
{"EP80579", 2},
- {"CPT Desktop", 2},
- {"CPT Mobile", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
+ {"Cougar Point", 2},
{NULL, 0}
};
@@ -259,8 +317,37 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
{ ITCO_PCI_DEVICE(0x3b14, TCO_3420)},
{ ITCO_PCI_DEVICE(0x3b16, TCO_3450)},
{ ITCO_PCI_DEVICE(0x5031, TCO_EP80579)},
- { ITCO_PCI_DEVICE(0x1c42, TCO_CPTD)},
- { ITCO_PCI_DEVICE(0x1c43, TCO_CPTM)},
+ { ITCO_PCI_DEVICE(0x1c41, TCO_CPT1)},
+ { ITCO_PCI_DEVICE(0x1c42, TCO_CPT2)},
+ { ITCO_PCI_DEVICE(0x1c43, TCO_CPT3)},
+ { ITCO_PCI_DEVICE(0x1c44, TCO_CPT4)},
+ { ITCO_PCI_DEVICE(0x1c45, TCO_CPT5)},
+ { ITCO_PCI_DEVICE(0x1c46, TCO_CPT6)},
+ { ITCO_PCI_DEVICE(0x1c47, TCO_CPT7)},
+ { ITCO_PCI_DEVICE(0x1c48, TCO_CPT8)},
+ { ITCO_PCI_DEVICE(0x1c49, TCO_CPT9)},
+ { ITCO_PCI_DEVICE(0x1c4a, TCO_CPT10)},
+ { ITCO_PCI_DEVICE(0x1c4b, TCO_CPT11)},
+ { ITCO_PCI_DEVICE(0x1c4c, TCO_CPT12)},
+ { ITCO_PCI_DEVICE(0x1c4d, TCO_CPT13)},
+ { ITCO_PCI_DEVICE(0x1c4e, TCO_CPT14)},
+ { ITCO_PCI_DEVICE(0x1c4f, TCO_CPT15)},
+ { ITCO_PCI_DEVICE(0x1c50, TCO_CPT16)},
+ { ITCO_PCI_DEVICE(0x1c51, TCO_CPT17)},
+ { ITCO_PCI_DEVICE(0x1c52, TCO_CPT18)},
+ { ITCO_PCI_DEVICE(0x1c53, TCO_CPT19)},
+ { ITCO_PCI_DEVICE(0x1c54, TCO_CPT20)},
+ { ITCO_PCI_DEVICE(0x1c55, TCO_CPT21)},
+ { ITCO_PCI_DEVICE(0x1c56, TCO_CPT22)},
+ { ITCO_PCI_DEVICE(0x1c57, TCO_CPT23)},
+ { ITCO_PCI_DEVICE(0x1c58, TCO_CPT24)},
+ { ITCO_PCI_DEVICE(0x1c59, TCO_CPT25)},
+ { ITCO_PCI_DEVICE(0x1c5a, TCO_CPT26)},
+ { ITCO_PCI_DEVICE(0x1c5b, TCO_CPT27)},
+ { ITCO_PCI_DEVICE(0x1c5c, TCO_CPT28)},
+ { ITCO_PCI_DEVICE(0x1c5d, TCO_CPT29)},
+ { ITCO_PCI_DEVICE(0x1c5e, TCO_CPT30)},
+ { ITCO_PCI_DEVICE(0x1c5f, TCO_CPT31)},
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
@@ -584,7 +671,7 @@ static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
int new_heartbeat;
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
@@ -698,7 +785,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
if (iTCO_wdt_private.iTCO_version == 2) {
pci_read_config_dword(pdev, 0xf0, &base_address);
if ((base_address & 1) == 0) {
- printk(KERN_ERR PFX "RCBA is disabled by harddware\n");
+ printk(KERN_ERR PFX "RCBA is disabled by hardware\n");
ret = -ENODEV;
goto out;
}
@@ -708,8 +795,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
/* Check chipset's NO_REBOOT bit */
if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
- printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, "
- "reboot disabled by hardware\n");
+ printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, "
+ "platform may have disabled it\n");
ret = -ENODEV; /* Cannot reset NO_REBOOT bit */
goto out_unmap;
}
@@ -805,6 +892,7 @@ static void __devexit iTCO_wdt_cleanup(void)
static int __devinit iTCO_wdt_probe(struct platform_device *dev)
{
+ int ret = -ENODEV;
int found = 0;
struct pci_dev *pdev = NULL;
const struct pci_device_id *ent;
@@ -814,19 +902,17 @@ static int __devinit iTCO_wdt_probe(struct platform_device *dev)
for_each_pci_dev(pdev) {
ent = pci_match_id(iTCO_wdt_pci_tbl, pdev);
if (ent) {
- if (!(iTCO_wdt_init(pdev, ent, dev))) {
- found++;
+ found++;
+ ret = iTCO_wdt_init(pdev, ent, dev);
+ if (!ret)
break;
- }
}
}
- if (!found) {
+ if (!found)
printk(KERN_INFO PFX "No card detected\n");
- return -ENODEV;
- }
- return 0;
+ return ret;
}
static int __devexit iTCO_wdt_remove(struct platform_device *dev)
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index 4bef3ddff4a..0149d8dfc81 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -174,7 +174,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
| WDIOF_MAGICCLOSE,
.firmware_version = 1,
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c
index 89fcefcc851..195e0f798e7 100644
--- a/drivers/watchdog/ibmasr.c
+++ b/drivers/watchdog/ibmasr.c
@@ -12,7 +12,6 @@
#include <linux/fs.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/timer.h>
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c
index bea8a124a55..1cc5609666d 100644
--- a/drivers/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
@@ -111,7 +111,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
int options, retval = -EINVAL;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING,
.firmware_version = 0,
.identity = "Hardware Watchdog for SGI IP22",
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index daed48ded7f..f52c162b1be 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -236,7 +236,7 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.identity = "IT8712F Watchdog",
.firmware_version = 1,
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index cc133c531d0..b709b3b2d1e 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -421,7 +421,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf,
return count;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
.firmware_version = 1,
.identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index 3c79dc58795..e86952a7168 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -100,7 +100,7 @@ static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING,
.identity = "IXP2000 Watchdog",
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index 147b4d5c63b..e02c0ecda26 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -89,7 +89,7 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
return len;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
.identity = "IXP4xx Watchdog",
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index e1c82769b08..2852bb2e3fd 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -145,7 +145,7 @@ static int ks8695_wdt_close(struct inode *inode, struct file *file)
return 0;
}
-static struct watchdog_info ks8695_wdt_info = {
+static const struct watchdog_info ks8695_wdt_info = {
.identity = "ks8695 watchdog",
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
};
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 47d719717a3..2d118cf022f 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -101,7 +101,7 @@ MODULE_PARM_DESC(nowayout,
#define PFX "machzwd"
-static struct watchdog_info zf_info = {
+static const struct watchdog_info zf_info = {
.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.firmware_version = 1,
.identity = "ZF-Logic watchdog",
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c
new file mode 100644
index 00000000000..3053ff05ca4
--- /dev/null
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -0,0 +1,403 @@
+/*
+ * drivers/char/watchdog/max63xx_wdt.c
+ *
+ * Driver for max63{69,70,71,72,73,74} watchdog timers
+ *
+ * Copyright (C) 2009 Marc Zyngier <maz@misterjones.org>
+ *
+ * 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.
+ *
+ * This driver assumes the watchdog pins are memory mapped (as it is
+ * the case for the Arcom Zeus). Should it be connected over GPIOs or
+ * another interface, some abstraction will have to be introduced.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#define DEFAULT_HEARTBEAT 60
+#define MAX_HEARTBEAT 60
+
+static int heartbeat = DEFAULT_HEARTBEAT;
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+/*
+ * Memory mapping: a single byte, 3 first lower bits to select bit 3
+ * to ping the watchdog.
+ */
+#define MAX6369_WDSET (7 << 0)
+#define MAX6369_WDI (1 << 3)
+
+static DEFINE_SPINLOCK(io_lock);
+
+static unsigned long wdt_status;
+#define WDT_IN_USE 0
+#define WDT_RUNNING 1
+#define WDT_OK_TO_CLOSE 2
+
+static int nodelay;
+static struct resource *wdt_mem;
+static void __iomem *wdt_base;
+static struct platform_device *max63xx_pdev;
+
+/*
+ * The timeout values used are actually the absolute minimum the chip
+ * offers. Typical values on my board are slightly over twice as long
+ * (10s setting ends up with a 25s timeout), and can be up to 3 times
+ * the nominal setting (according to the datasheet). So please take
+ * these values with a grain of salt. Same goes for the initial delay
+ * "feature". Only max6373/74 have a few settings without this initial
+ * delay (selected with the "nodelay" parameter).
+ *
+ * I also decided to remove from the tables any timeout smaller than a
+ * second, as it looked completly overkill...
+ */
+
+/* Timeouts in second */
+struct max63xx_timeout {
+ u8 wdset;
+ u8 tdelay;
+ u8 twd;
+};
+
+static struct max63xx_timeout max6369_table[] = {
+ { 5, 1, 1 },
+ { 6, 10, 10 },
+ { 7, 60, 60 },
+ { },
+};
+
+static struct max63xx_timeout max6371_table[] = {
+ { 6, 60, 3 },
+ { 7, 60, 60 },
+ { },
+};
+
+static struct max63xx_timeout max6373_table[] = {
+ { 2, 60, 1 },
+ { 5, 0, 1 },
+ { 1, 3, 3 },
+ { 7, 60, 10 },
+ { 6, 0, 10 },
+ { },
+};
+
+static struct max63xx_timeout *current_timeout;
+
+static struct max63xx_timeout *
+max63xx_select_timeout(struct max63xx_timeout *table, int value)
+{
+ while (table->twd) {
+ if (value <= table->twd) {
+ if (nodelay && table->tdelay == 0)
+ return table;
+
+ if (!nodelay)
+ return table;
+ }
+
+ table++;
+ }
+
+ return NULL;
+}
+
+static void max63xx_wdt_ping(void)
+{
+ u8 val;
+
+ spin_lock(&io_lock);
+
+ val = __raw_readb(wdt_base);
+
+ __raw_writeb(val | MAX6369_WDI, wdt_base);
+ __raw_writeb(val & ~MAX6369_WDI, wdt_base);
+
+ spin_unlock(&io_lock);
+}
+
+static void max63xx_wdt_enable(struct max63xx_timeout *entry)
+{
+ u8 val;
+
+ if (test_and_set_bit(WDT_RUNNING, &wdt_status))
+ return;
+
+ spin_lock(&io_lock);
+
+ val = __raw_readb(wdt_base);
+ val &= ~MAX6369_WDSET;
+ val |= entry->wdset;
+ __raw_writeb(val, wdt_base);
+
+ spin_unlock(&io_lock);
+
+ /* check for a edge triggered startup */
+ if (entry->tdelay == 0)
+ max63xx_wdt_ping();
+}
+
+static void max63xx_wdt_disable(void)
+{
+ u8 val;
+
+ spin_lock(&io_lock);
+
+ val = __raw_readb(wdt_base);
+ val &= ~MAX6369_WDSET;
+ val |= 3;
+ __raw_writeb(val, wdt_base);
+
+ spin_unlock(&io_lock);
+
+ clear_bit(WDT_RUNNING, &wdt_status);
+}
+
+static int max63xx_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+ return -EBUSY;
+
+ max63xx_wdt_enable(current_timeout);
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+ return nonseekable_open(inode, file);
+}
+
+static ssize_t max63xx_wdt_write(struct file *file, const char *data,
+ size_t len, loff_t *ppos)
+{
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+ for (i = 0; i != len; i++) {
+ char c;
+
+ if (get_user(c, data + i))
+ return -EFAULT;
+
+ if (c == 'V')
+ set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+ }
+ }
+
+ max63xx_wdt_ping();
+ }
+
+ return len;
+}
+
+static const struct watchdog_info ident = {
+ .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+ .identity = "max63xx Watchdog",
+};
+
+static long max63xx_wdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = -ENOTTY;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ ret = copy_to_user((struct watchdog_info *)arg, &ident,
+ sizeof(ident)) ? -EFAULT : 0;
+ break;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ ret = put_user(0, (int *)arg);
+ break;
+
+ case WDIOC_KEEPALIVE:
+ max63xx_wdt_ping();
+ ret = 0;
+ break;
+
+ case WDIOC_GETTIMEOUT:
+ ret = put_user(heartbeat, (int *)arg);
+ break;
+ }
+ return ret;
+}
+
+static int max63xx_wdt_release(struct inode *inode, struct file *file)
+{
+ if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
+ max63xx_wdt_disable();
+ else
+ dev_crit(&max63xx_pdev->dev,
+ "device closed unexpectedly - timer will not stop\n");
+
+ clear_bit(WDT_IN_USE, &wdt_status);
+ clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+ return 0;
+}
+
+static const struct file_operations max63xx_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = max63xx_wdt_write,
+ .unlocked_ioctl = max63xx_wdt_ioctl,
+ .open = max63xx_wdt_open,
+ .release = max63xx_wdt_release,
+};
+
+static struct miscdevice max63xx_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &max63xx_wdt_fops,
+};
+
+static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ int size;
+ struct resource *res;
+ struct device *dev = &pdev->dev;
+ struct max63xx_timeout *table;
+
+ table = (struct max63xx_timeout *)pdev->id_entry->driver_data;
+
+ if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
+ heartbeat = DEFAULT_HEARTBEAT;
+
+ dev_info(dev, "requesting %ds heartbeat\n", heartbeat);
+ current_timeout = max63xx_select_timeout(table, heartbeat);
+
+ if (!current_timeout) {
+ dev_err(dev, "unable to satisfy heartbeat request\n");
+ return -EINVAL;
+ }
+
+ dev_info(dev, "using %ds heartbeat with %ds initial delay\n",
+ current_timeout->twd, current_timeout->tdelay);
+
+ heartbeat = current_timeout->twd;
+
+ max63xx_pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(dev, "failed to get memory region resource\n");
+ return -ENOENT;
+ }
+
+ size = resource_size(res);
+ wdt_mem = request_mem_region(res->start, size, pdev->name);
+
+ if (wdt_mem == NULL) {
+ dev_err(dev, "failed to get memory region\n");
+ return -ENOENT;
+ }
+
+ wdt_base = ioremap(res->start, size);
+ if (!wdt_base) {
+ dev_err(dev, "failed to map memory region\n");
+ ret = -ENOMEM;
+ goto out_request;
+ }
+
+ ret = misc_register(&max63xx_wdt_miscdev);
+ if (ret < 0) {
+ dev_err(dev, "cannot register misc device\n");
+ goto out_unmap;
+ }
+
+ return 0;
+
+out_unmap:
+ iounmap(wdt_base);
+out_request:
+ release_resource(wdt_mem);
+ kfree(wdt_mem);
+
+ return ret;
+}
+
+static int __devexit max63xx_wdt_remove(struct platform_device *pdev)
+{
+ misc_deregister(&max63xx_wdt_miscdev);
+ if (wdt_mem) {
+ release_resource(wdt_mem);
+ kfree(wdt_mem);
+ wdt_mem = NULL;
+ }
+
+ if (wdt_base)
+ iounmap(wdt_base);
+
+ return 0;
+}
+
+static struct platform_device_id max63xx_id_table[] = {
+ { "max6369_wdt", (kernel_ulong_t)max6369_table, },
+ { "max6370_wdt", (kernel_ulong_t)max6369_table, },
+ { "max6371_wdt", (kernel_ulong_t)max6371_table, },
+ { "max6372_wdt", (kernel_ulong_t)max6371_table, },
+ { "max6373_wdt", (kernel_ulong_t)max6373_table, },
+ { "max6374_wdt", (kernel_ulong_t)max6373_table, },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, max63xx_id_table);
+
+static struct platform_driver max63xx_wdt_driver = {
+ .probe = max63xx_wdt_probe,
+ .remove = __devexit_p(max63xx_wdt_remove),
+ .id_table = max63xx_id_table,
+ .driver = {
+ .name = "max63xx_wdt",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init max63xx_wdt_init(void)
+{
+ return platform_driver_register(&max63xx_wdt_driver);
+}
+
+static void __exit max63xx_wdt_exit(void)
+{
+ platform_driver_unregister(&max63xx_wdt_driver);
+}
+
+module_init(max63xx_wdt_init);
+module_exit(max63xx_wdt_exit);
+
+MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>");
+MODULE_DESCRIPTION("max63xx Watchdog Driver");
+
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat,
+ "Watchdog heartbeat period in seconds from 1 to "
+ __MODULE_STRING(MAX_HEARTBEAT) ", default "
+ __MODULE_STRING(DEFAULT_HEARTBEAT));
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+module_param(nodelay, int, 0);
+MODULE_PARM_DESC(nodelay,
+ "Force selection of a timeout setting without initial delay "
+ "(max6373/74 only, default=0)");
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
index 407b025cb10..bc820d16699 100644
--- a/drivers/watchdog/mixcomwd.c
+++ b/drivers/watchdog/mixcomwd.c
@@ -201,7 +201,7 @@ static long mixcomwd_ioctl(struct file *file,
void __user *argp = (void __user *)arg;
int __user *p = argp;
int status;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.firmware_version = 1,
.identity = "MixCOM watchdog",
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 38c588ee694..4e3941c5e29 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -148,7 +148,7 @@ static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd,
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING,
.firmware_version = 1,
.identity = "MPC8xxx",
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index a2dc07c2ed4..016c6a791ca 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -30,6 +30,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <asm/hardware/arm_twd.h>
@@ -213,7 +214,7 @@ static ssize_t mpcore_wdt_write(struct file *file, const char *data,
return len;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index a51dbe4c43d..97f8a48d8b7 100644
--- a/drivers/watchdog/mv64x60_wdt.c
+++ b/drivers/watchdog/mv64x60_wdt.c
@@ -179,7 +179,7 @@ static long mv64x60_wdt_ioctl(struct file *file,
int timeout;
int options;
void __user *argp = (void __user *)arg;
- static struct watchdog_info info = {
+ static const struct watchdog_info info = {
.options = WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE |
WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c
index adefe3a9d51..6cee33d4b16 100644
--- a/drivers/watchdog/nuc900_wdt.c
+++ b/drivers/watchdog/nuc900_wdt.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/watchdog.h>
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index c6aaf284574..76b58abf445 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -42,6 +42,7 @@
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#include <plat/prcm.h>
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 1a2b916e3f8..d3aa2f1fe61 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -407,7 +407,7 @@ static long pc87413_ioctl(struct file *file, unsigned int cmd,
int __user *i;
} uarg;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index aa9512321f3..06f7922606c 100644
--- a/drivers/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
@@ -606,7 +606,7 @@ static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int temperature;
int new_heartbeat;
int __user *argp = (int __user *)arg;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_OVERHEAT |
WDIOF_CARDRESET |
WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index 698f51bff1b..64374d636f0 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -481,7 +481,7 @@ static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_OVERHEAT |
WDIOF_CARDRESET |
WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index 052fe451851..8e4eacc5bb5 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -404,7 +404,7 @@ static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index c7a9479934a..bf5b97c546e 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -30,6 +30,7 @@
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <mach/hardware.h>
#define MODULE_NAME "PNX4008-WDT: "
diff --git a/drivers/watchdog/pnx833x_wdt.c b/drivers/watchdog/pnx833x_wdt.c
index 538ec2c0519..09102f09e68 100644
--- a/drivers/watchdog/pnx833x_wdt.c
+++ b/drivers/watchdog/pnx833x_wdt.c
@@ -141,7 +141,7 @@ static long pnx833x_wdt_ioctl(struct file *file, unsigned int cmd,
int options, new_timeout = 0;
uint32_t timeout, timeout_left = 0;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
.firmware_version = 0,
.identity = "Hardware Watchdog for PNX833x",
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index bf12d06b587..d4c29b5311a 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -198,7 +198,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
void __user *argp = (void __user *)arg;
int new_timeout;
unsigned int value;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 4976bfd1fce..69c6adbd820 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -149,7 +149,7 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd,
{
void __user *argp = (void __user *)arg;
unsigned int value;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_CARDRESET,
.identity = "RDC321x WDT",
};
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index c14ae867690..ea7f803f624 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -15,6 +15,7 @@
#include <linux/of_device.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
/* RIO uses the NatSemi Super I/O power management logical device
@@ -85,7 +86,7 @@ static int riowd_release(struct inode *inode, struct file *filp)
static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
- static struct watchdog_info info = {
+ static const struct watchdog_info info = {
.options = WDIOF_SETTIMEOUT,
.firmware_version = 1,
.identity = DRIVER_NAME,
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 8760a26ab2a..e4cebef5517 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -37,6 +37,7 @@
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/cpufreq.h>
+#include <linux/slab.h>
#include <mach/map.h>
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index c8eadd47817..88c83aa5730 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -67,8 +67,8 @@ static DEFINE_SPINLOCK(sbwd_lock);
void sbwdog_set(char __iomem *wdog, unsigned long t)
{
spin_lock(&sbwd_lock);
- __raw_writeb(0, wdog - 0x10);
- __raw_writeq(t & 0x7fffffUL, wdog);
+ __raw_writeb(0, wdog);
+ __raw_writeq(t & 0x7fffffUL, wdog - 0x10);
spin_unlock(&sbwd_lock);
}
diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c
index e6763d2a567..c7d67e9a746 100644
--- a/drivers/watchdog/sbc_fitpc2_wdt.c
+++ b/drivers/watchdog/sbc_fitpc2_wdt.c
@@ -30,7 +30,7 @@
static int nowayout = WATCHDOG_NOWAYOUT;
static unsigned int margin = 60; /* (secs) Default is 1 minute */
static unsigned long wdt_status;
-static DEFINE_SPINLOCK(wdt_lock);
+static DEFINE_MUTEX(wdt_lock);
#define WDT_IN_USE 0
#define WDT_OK_TO_CLOSE 1
@@ -45,26 +45,26 @@ static DEFINE_SPINLOCK(wdt_lock);
static void wdt_send_data(unsigned char command, unsigned char data)
{
- outb(command, COMMAND_PORT);
- msleep(100);
outb(data, DATA_PORT);
msleep(200);
+ outb(command, COMMAND_PORT);
+ msleep(100);
}
static void wdt_enable(void)
{
- spin_lock(&wdt_lock);
+ mutex_lock(&wdt_lock);
wdt_send_data(IFACE_ON_COMMAND, 1);
wdt_send_data(REBOOT_COMMAND, margin);
- spin_unlock(&wdt_lock);
+ mutex_unlock(&wdt_lock);
}
static void wdt_disable(void)
{
- spin_lock(&wdt_lock);
+ mutex_lock(&wdt_lock);
wdt_send_data(IFACE_ON_COMMAND, 0);
wdt_send_data(REBOOT_COMMAND, 0);
- spin_unlock(&wdt_lock);
+ mutex_unlock(&wdt_lock);
}
static int fitpc2_wdt_open(struct inode *inode, struct file *file)
@@ -111,7 +111,7 @@ out:
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING,
.identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c
index 569eb295a7a..9c40f48804f 100644
--- a/drivers/watchdog/sch311x_wdt.c
+++ b/drivers/watchdog/sch311x_wdt.c
@@ -250,7 +250,7 @@ static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd,
int new_timeout;
void __user *argp = (void __user *)arg;
int __user *p = argp;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c
index 5dd952681f3..b3421fd2cda 100644
--- a/drivers/watchdog/stmp3xxx_wdt.c
+++ b/drivers/watchdog/stmp3xxx_wdt.c
@@ -94,7 +94,7 @@ static ssize_t stmp3xxx_wdt_write(struct file *file, const char __user *data,
return len;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_CARDRESET |
WDIOF_MAGICCLOSE |
WDIOF_SETTIMEOUT |
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
new file mode 100644
index 00000000000..458c499c122
--- /dev/null
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -0,0 +1,521 @@
+/*
+ * Watchdog driver for Technologic Systems TS-72xx based SBCs
+ * (TS-7200, TS-7250 and TS-7260). These boards have external
+ * glue logic CPLD chip, which includes programmable watchdog
+ * timer.
+ *
+ * Copyright (c) 2009 Mika Westerberg <mika.westerberg@iki.fi>
+ *
+ * This driver is based on ep93xx_wdt and wm831x_wdt drivers.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/watchdog.h>
+#include <linux/uaccess.h>
+
+#define TS72XX_WDT_FEED_VAL 0x05
+#define TS72XX_WDT_DEFAULT_TIMEOUT 8
+
+static int timeout = TS72XX_WDT_DEFAULT_TIMEOUT;
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. "
+ "(1 <= timeout <= 8, default="
+ __MODULE_STRING(TS72XX_WDT_DEFAULT_TIMEOUT)
+ ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+/**
+ * struct ts72xx_wdt - watchdog control structure
+ * @lock: lock that protects this structure
+ * @regval: watchdog timeout value suitable for control register
+ * @flags: flags controlling watchdog device state
+ * @control_reg: watchdog control register
+ * @feed_reg: watchdog feed register
+ * @pdev: back pointer to platform dev
+ */
+struct ts72xx_wdt {
+ struct mutex lock;
+ int regval;
+
+#define TS72XX_WDT_BUSY_FLAG 1
+#define TS72XX_WDT_EXPECT_CLOSE_FLAG 2
+ int flags;
+
+ void __iomem *control_reg;
+ void __iomem *feed_reg;
+
+ struct platform_device *pdev;
+};
+
+struct platform_device *ts72xx_wdt_pdev;
+
+/*
+ * TS-72xx Watchdog supports following timeouts (value written
+ * to control register):
+ * value description
+ * -------------------------
+ * 0x00 watchdog disabled
+ * 0x01 250ms
+ * 0x02 500ms
+ * 0x03 1s
+ * 0x04 reserved
+ * 0x05 2s
+ * 0x06 4s
+ * 0x07 8s
+ *
+ * Timeouts below 1s are not very usable so we don't
+ * allow them at all.
+ *
+ * We provide two functions that convert between these:
+ * timeout_to_regval() and regval_to_timeout().
+ */
+static const struct {
+ int timeout;
+ int regval;
+} ts72xx_wdt_map[] = {
+ { 1, 3 },
+ { 2, 5 },
+ { 4, 6 },
+ { 8, 7 },
+};
+
+/**
+ * timeout_to_regval() - converts given timeout to control register value
+ * @new_timeout: timeout in seconds to be converted
+ *
+ * Function converts given @new_timeout into valid value that can
+ * be programmed into watchdog control register. When conversion is
+ * not possible, function returns %-EINVAL.
+ */
+static int timeout_to_regval(int new_timeout)
+{
+ int i;
+
+ /* first limit it to 1 - 8 seconds */
+ new_timeout = clamp_val(new_timeout, 1, 8);
+
+ for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
+ if (ts72xx_wdt_map[i].timeout >= new_timeout)
+ return ts72xx_wdt_map[i].regval;
+ }
+
+ return -EINVAL;
+}
+
+/**
+ * regval_to_timeout() - converts control register value to timeout
+ * @regval: control register value to be converted
+ *
+ * Function converts given @regval to timeout in seconds (1, 2, 4 or 8).
+ * If @regval cannot be converted, function returns %-EINVAL.
+ */
+static int regval_to_timeout(int regval)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
+ if (ts72xx_wdt_map[i].regval == regval)
+ return ts72xx_wdt_map[i].timeout;
+ }
+
+ return -EINVAL;
+}
+
+/**
+ * ts72xx_wdt_kick() - kick the watchdog
+ * @wdt: watchdog to be kicked
+ *
+ * Called with @wdt->lock held.
+ */
+static inline void ts72xx_wdt_kick(struct ts72xx_wdt *wdt)
+{
+ __raw_writeb(TS72XX_WDT_FEED_VAL, wdt->feed_reg);
+}
+
+/**
+ * ts72xx_wdt_start() - starts the watchdog timer
+ * @wdt: watchdog to be started
+ *
+ * This function programs timeout to watchdog timer
+ * and starts it.
+ *
+ * Called with @wdt->lock held.
+ */
+static void ts72xx_wdt_start(struct ts72xx_wdt *wdt)
+{
+ /*
+ * To program the wdt, it first must be "fed" and
+ * only after that (within 30 usecs) the configuration
+ * can be changed.
+ */
+ ts72xx_wdt_kick(wdt);
+ __raw_writeb((u8)wdt->regval, wdt->control_reg);
+}
+
+/**
+ * ts72xx_wdt_stop() - stops the watchdog timer
+ * @wdt: watchdog to be stopped
+ *
+ * Called with @wdt->lock held.
+ */
+static void ts72xx_wdt_stop(struct ts72xx_wdt *wdt)
+{
+ ts72xx_wdt_kick(wdt);
+ __raw_writeb(0, wdt->control_reg);
+}
+
+static int ts72xx_wdt_open(struct inode *inode, struct file *file)
+{
+ struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev);
+ int regval;
+
+ /*
+ * Try to convert default timeout to valid register
+ * value first.
+ */
+ regval = timeout_to_regval(timeout);
+ if (regval < 0) {
+ dev_err(&wdt->pdev->dev,
+ "failed to convert timeout (%d) to register value\n",
+ timeout);
+ return -EINVAL;
+ }
+
+ if (mutex_lock_interruptible(&wdt->lock))
+ return -ERESTARTSYS;
+
+ if ((wdt->flags & TS72XX_WDT_BUSY_FLAG) != 0) {
+ mutex_unlock(&wdt->lock);
+ return -EBUSY;
+ }
+
+ wdt->flags = TS72XX_WDT_BUSY_FLAG;
+ wdt->regval = regval;
+ file->private_data = wdt;
+
+ ts72xx_wdt_start(wdt);
+
+ mutex_unlock(&wdt->lock);
+ return nonseekable_open(inode, file);
+}
+
+static int ts72xx_wdt_release(struct inode *inode, struct file *file)
+{
+ struct ts72xx_wdt *wdt = file->private_data;
+
+ if (mutex_lock_interruptible(&wdt->lock))
+ return -ERESTARTSYS;
+
+ if ((wdt->flags & TS72XX_WDT_EXPECT_CLOSE_FLAG) != 0) {
+ ts72xx_wdt_stop(wdt);
+ } else {
+ dev_warn(&wdt->pdev->dev,
+ "TS-72XX WDT device closed unexpectly. "
+ "Watchdog timer will not stop!\n");
+ /*
+ * Kick it one more time, to give userland some time
+ * to recover (for example, respawning the kicker
+ * daemon).
+ */
+ ts72xx_wdt_kick(wdt);
+ }
+
+ wdt->flags = 0;
+
+ mutex_unlock(&wdt->lock);
+ return 0;
+}
+
+static ssize_t ts72xx_wdt_write(struct file *file,
+ const char __user *data,
+ size_t len,
+ loff_t *ppos)
+{
+ struct ts72xx_wdt *wdt = file->private_data;
+
+ if (!len)
+ return 0;
+
+ if (mutex_lock_interruptible(&wdt->lock))
+ return -ERESTARTSYS;
+
+ ts72xx_wdt_kick(wdt);
+
+ /*
+ * Support for magic character closing. User process
+ * writes 'V' into the device, just before it is closed.
+ * This means that we know that the wdt timer can be
+ * stopped after user closes the device.
+ */
+ if (!nowayout) {
+ int i;
+
+ for (i = 0; i < len; i++) {
+ char c;
+
+ /* In case it was set long ago */
+ wdt->flags &= ~TS72XX_WDT_EXPECT_CLOSE_FLAG;
+
+ if (get_user(c, data + i)) {
+ mutex_unlock(&wdt->lock);
+ return -EFAULT;
+ }
+ if (c == 'V') {
+ wdt->flags |= TS72XX_WDT_EXPECT_CLOSE_FLAG;
+ break;
+ }
+ }
+ }
+
+ mutex_unlock(&wdt->lock);
+ return len;
+}
+
+static const struct watchdog_info winfo = {
+ .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
+ WDIOF_MAGICCLOSE,
+ .firmware_version = 1,
+ .identity = "TS-72XX WDT",
+};
+
+static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct ts72xx_wdt *wdt = file->private_data;
+ void __user *argp = (void __user *)arg;
+ int __user *p = (int __user *)argp;
+ int error = 0;
+
+ if (mutex_lock_interruptible(&wdt->lock))
+ return -ERESTARTSYS;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ error = copy_to_user(argp, &winfo, sizeof(winfo));
+ break;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, p);
+
+ case WDIOC_KEEPALIVE:
+ ts72xx_wdt_kick(wdt);
+ break;
+
+ case WDIOC_SETOPTIONS: {
+ int options;
+
+ if (get_user(options, p)) {
+ error = -EFAULT;
+ break;
+ }
+
+ error = -EINVAL;
+
+ if ((options & WDIOS_DISABLECARD) != 0) {
+ ts72xx_wdt_stop(wdt);
+ error = 0;
+ }
+ if ((options & WDIOS_ENABLECARD) != 0) {
+ ts72xx_wdt_start(wdt);
+ error = 0;
+ }
+
+ break;
+ }
+
+ case WDIOC_SETTIMEOUT: {
+ int new_timeout;
+
+ if (get_user(new_timeout, p)) {
+ error = -EFAULT;
+ } else {
+ int regval;
+
+ regval = timeout_to_regval(new_timeout);
+ if (regval < 0) {
+ error = -EINVAL;
+ } else {
+ ts72xx_wdt_stop(wdt);
+ wdt->regval = regval;
+ ts72xx_wdt_start(wdt);
+ }
+ }
+ if (error)
+ break;
+
+ /*FALLTHROUGH*/
+ }
+
+ case WDIOC_GETTIMEOUT:
+ if (put_user(regval_to_timeout(wdt->regval), p))
+ error = -EFAULT;
+ break;
+
+ default:
+ error = -ENOTTY;
+ break;
+ }
+
+ mutex_unlock(&wdt->lock);
+ return error;
+}
+
+static const struct file_operations ts72xx_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = ts72xx_wdt_open,
+ .release = ts72xx_wdt_release,
+ .write = ts72xx_wdt_write,
+ .unlocked_ioctl = ts72xx_wdt_ioctl,
+};
+
+static struct miscdevice ts72xx_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &ts72xx_wdt_fops,
+};
+
+static __devinit int ts72xx_wdt_probe(struct platform_device *pdev)
+{
+ struct ts72xx_wdt *wdt;
+ struct resource *r1, *r2;
+ int error = 0;
+
+ wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL);
+ if (!wdt) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r1) {
+ dev_err(&pdev->dev, "failed to get memory resource\n");
+ error = -ENODEV;
+ goto fail;
+ }
+
+ r1 = request_mem_region(r1->start, resource_size(r1), pdev->name);
+ if (!r1) {
+ dev_err(&pdev->dev, "cannot request memory region\n");
+ error = -EBUSY;
+ goto fail;
+ }
+
+ wdt->control_reg = ioremap(r1->start, resource_size(r1));
+ if (!wdt->control_reg) {
+ dev_err(&pdev->dev, "failed to map memory\n");
+ error = -ENODEV;
+ goto fail_free_control;
+ }
+
+ r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!r2) {
+ dev_err(&pdev->dev, "failed to get memory resource\n");
+ error = -ENODEV;
+ goto fail_unmap_control;
+ }
+
+ r2 = request_mem_region(r2->start, resource_size(r2), pdev->name);
+ if (!r2) {
+ dev_err(&pdev->dev, "cannot request memory region\n");
+ error = -EBUSY;
+ goto fail_unmap_control;
+ }
+
+ wdt->feed_reg = ioremap(r2->start, resource_size(r2));
+ if (!wdt->feed_reg) {
+ dev_err(&pdev->dev, "failed to map memory\n");
+ error = -ENODEV;
+ goto fail_free_feed;
+ }
+
+ platform_set_drvdata(pdev, wdt);
+ ts72xx_wdt_pdev = pdev;
+ wdt->pdev = pdev;
+ mutex_init(&wdt->lock);
+
+ error = misc_register(&ts72xx_wdt_miscdev);
+ if (error) {
+ dev_err(&pdev->dev, "failed to register miscdev\n");
+ goto fail_unmap_feed;
+ }
+
+ dev_info(&pdev->dev, "TS-72xx Watchdog driver\n");
+
+ return 0;
+
+fail_unmap_feed:
+ platform_set_drvdata(pdev, NULL);
+ iounmap(wdt->feed_reg);
+fail_free_feed:
+ release_mem_region(r2->start, resource_size(r2));
+fail_unmap_control:
+ iounmap(wdt->control_reg);
+fail_free_control:
+ release_mem_region(r1->start, resource_size(r1));
+fail:
+ kfree(wdt);
+ return error;
+}
+
+static __devexit int ts72xx_wdt_remove(struct platform_device *pdev)
+{
+ struct ts72xx_wdt *wdt = platform_get_drvdata(pdev);
+ struct resource *res;
+ int error;
+
+ error = misc_deregister(&ts72xx_wdt_miscdev);
+ platform_set_drvdata(pdev, NULL);
+
+ iounmap(wdt->feed_reg);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ release_mem_region(res->start, resource_size(res));
+
+ iounmap(wdt->control_reg);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+ kfree(wdt);
+ return error;
+}
+
+static struct platform_driver ts72xx_wdt_driver = {
+ .probe = ts72xx_wdt_probe,
+ .remove = __devexit_p(ts72xx_wdt_remove),
+ .driver = {
+ .name = "ts72xx-wdt",
+ .owner = THIS_MODULE,
+ },
+};
+
+static __init int ts72xx_wdt_init(void)
+{
+ return platform_driver_register(&ts72xx_wdt_driver);
+}
+module_init(ts72xx_wdt_init);
+
+static __exit void ts72xx_wdt_exit(void)
+{
+ platform_driver_unregister(&ts72xx_wdt_driver);
+}
+module_exit(ts72xx_wdt_exit);
+
+MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
+MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ts72xx-wdt");
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 8162a40d152..dcabe77ad14 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/watchdog.h>
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index d635566e930..9e9ed7bfabc 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -13,7 +13,6 @@
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
-#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
@@ -166,14 +165,6 @@ static long txx9wdt_ioctl(struct file *file, unsigned int cmd,
}
}
-static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code,
- void *unused)
-{
- if (code == SYS_DOWN || code == SYS_HALT)
- txx9wdt_stop();
- return NOTIFY_DONE;
-}
-
static const struct file_operations txx9wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -189,10 +180,6 @@ static struct miscdevice txx9wdt_miscdev = {
.fops = &txx9wdt_fops,
};
-static struct notifier_block txx9wdt_notifier = {
- .notifier_call = txx9wdt_notify_sys,
-};
-
static int __init txx9wdt_probe(struct platform_device *dev)
{
struct resource *res;
@@ -221,13 +208,8 @@ static int __init txx9wdt_probe(struct platform_device *dev)
if (!txx9wdt_reg)
goto exit_busy;
- ret = register_reboot_notifier(&txx9wdt_notifier);
- if (ret)
- goto exit;
-
ret = misc_register(&txx9wdt_miscdev);
if (ret) {
- unregister_reboot_notifier(&txx9wdt_notifier);
goto exit;
}
@@ -249,14 +231,19 @@ exit:
static int __exit txx9wdt_remove(struct platform_device *dev)
{
misc_deregister(&txx9wdt_miscdev);
- unregister_reboot_notifier(&txx9wdt_notifier);
clk_disable(txx9_imclk);
clk_put(txx9_imclk);
return 0;
}
+static void txx9wdt_shutdown(struct platform_device *dev)
+{
+ txx9wdt_stop();
+}
+
static struct platform_driver txx9wdt_driver = {
.remove = __exit_p(txx9wdt_remove),
+ .shutdown = txx9wdt_shutdown,
.driver = {
.name = "txx9wdt",
.owner = THIS_MODULE,
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index f201accc4e3..0f5288df009 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -201,7 +201,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
void __user *argp = (void __user *)arg;
int __user *p = argp;
int new_timeout;
- static struct watchdog_info ident = {
+ static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE,
.firmware_version = 1,
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c
index 0560182a1d0..6e6743d1066 100644
--- a/drivers/watchdog/w83977f_wdt.c
+++ b/drivers/watchdog/w83977f_wdt.c
@@ -371,7 +371,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf,
* according to their available features.
*/
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
.firmware_version = 1,
.identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 5bfb1f2c531..94ec22b9e66 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -312,7 +312,7 @@ static long wdrtas_ioctl(struct file *file, unsigned int cmd,
{
int __user *argp = (void __user *)arg;
int i;
- static struct watchdog_info wdinfo = {
+ static const struct watchdog_info wdinfo = {
.options = WDRTAS_SUPPORTED_MASK,
.firmware_version = 0,
.identity = "wdrtas",
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c
index 3bbefe9a263..bfda2e99dd8 100644
--- a/drivers/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
@@ -358,7 +358,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int new_heartbeat;
int status;
- static struct watchdog_info ident = {
+ struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT|
WDIOF_MAGICCLOSE|
WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index f368dd87083..7b22e3cdbc8 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -412,7 +412,7 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
int new_heartbeat;
int status;
- static struct watchdog_info ident = {
+ struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT|
WDIOF_MAGICCLOSE|
WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 775bcd807f3..8c4b2d5bb7d 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -213,7 +213,7 @@ static ssize_t wm831x_wdt_write(struct file *file,
return count;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.identity = "WM831x Watchdog",
};
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index a2d2e8eb228..89dd7b03529 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -177,7 +177,7 @@ static ssize_t wm8350_wdt_write(struct file *file,
return count;
}
-static struct watchdog_info ident = {
+static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.identity = "WM8350 Watchdog",
};
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index cab100acf98..fad3df2c127 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -1,6 +1,8 @@
+menu "Xen driver support"
+ depends on XEN
+
config XEN_BALLOON
bool "Xen memory balloon driver"
- depends on XEN
default y
help
The balloon driver allows the Xen domain to request more memory from
@@ -20,7 +22,6 @@ config XEN_SCRUB_PAGES
config XEN_DEV_EVTCHN
tristate "Xen /dev/xen/evtchn device"
- depends on XEN
default y
help
The evtchn driver allows a userspace process to triger event
@@ -30,7 +31,6 @@ config XEN_DEV_EVTCHN
config XENFS
tristate "Xen filesystem"
- depends on XEN
default y
help
The xen filesystem provides a way for domains to share
@@ -53,11 +53,13 @@ config XEN_COMPAT_XENFS
config XEN_SYS_HYPERVISOR
bool "Create xen entries under /sys/hypervisor"
- depends on XEN && SYSFS
+ depends on SYSFS
select SYS_HYPERVISOR
default y
help
Create entries under /sys/hypervisor describing the Xen
hypervisor environment. When running native or in another
virtual environment, /sys/hypervisor will still be present,
- but will have no xen contents. \ No newline at end of file
+ but will have no xen contents.
+
+endmenu
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index f6738d8b02b..1a0d8c2a035 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -43,6 +43,7 @@
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/sysdev.h>
+#include <linux/gfp.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 2f8413794d0..db8f506817f 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/bootmem.h>
+#include <linux/slab.h>
#include <asm/ptrace.h>
#include <asm/irq.h>
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index f70a4f4698c..66e185cfe92 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -45,7 +45,6 @@
#include <linux/poll.h>
#include <linux/irq.h>
#include <linux/init.h>
-#include <linux/gfp.h>
#include <linux/mutex.h>
#include <linux/cpu.h>
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 4c6c0bd636a..f66db3b91d6 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 5d42d55e299..2ac4440e7b0 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -3,6 +3,7 @@
*/
#include <linux/kernel.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/reboot.h>
#include <linux/sysrq.h>
#include <linux/stop_machine.h>
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c
index ae5cb05a1a1..60f1827a32c 100644
--- a/drivers/xen/sys-hypervisor.c
+++ b/drivers/xen/sys-hypervisor.c
@@ -7,6 +7,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kobject.h>
@@ -426,7 +427,7 @@ static ssize_t hyp_sysfs_store(struct kobject *kobj,
return 0;
}
-static struct sysfs_ops hyp_sysfs_ops = {
+static const struct sysfs_ops hyp_sysfs_ops = {
.show = hyp_sysfs_show,
.store = hyp_sysfs_store,
};
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 92a1ef80a28..7b3e973a1ae 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -30,6 +30,7 @@
* IN THE SOFTWARE.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <asm/xen/hypervisor.h>
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 2f7aaa99dc4..3479332113e 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -45,6 +45,7 @@
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/page.h>
#include <asm/pgtable.h>
diff --git a/drivers/xen/xencomm.c b/drivers/xen/xencomm.c
index a240b2c20b9..b91f8ff50d0 100644
--- a/drivers/xen/xencomm.c
+++ b/drivers/xen/xencomm.c
@@ -18,8 +18,8 @@
* Authors: Hollis Blanchard <hollisb@us.ibm.com>
*/
-#include <linux/gfp.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <asm/page.h>
#include <xen/xencomm.h>
#include <xen/interface/xen.h>
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c
index 6c4269b836b..f28ece39736 100644
--- a/drivers/xen/xenfs/xenbus.c
+++ b/drivers/xen/xenfs/xenbus.c
@@ -51,6 +51,7 @@
#include <linux/init.h>
#include <linux/namei.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include "xenfs.h"
#include "../xenbus/xenbus_comms.h"
diff --git a/drivers/zorro/zorro.ids b/drivers/zorro/zorro.ids
index 0c0f99e2dd6..de24e3deced 100644
--- a/drivers/zorro/zorro.ids
+++ b/drivers/zorro/zorro.ids
@@ -108,7 +108,7 @@
0c00 500XP/SupraDrive WordSync [SCSI Host Adapter]
0d00 SupraDrive WordSync II [SCSI Host Adapter]
1000 2400zi+ [Modem]
-0422 Computer Systems Assosiates
+0422 Computer Systems Associates
1100 Magnum 40 [Accelerator and SCSI Host Adapter]
1500 12 Gauge [SCSI Host Adapter]
0439 Marc Michael Groth
diff --git a/firmware/bnx2x-e1-5.2.7.0.fw.ihex b/firmware/bnx2x-e1-5.2.7.0.fw.ihex
deleted file mode 100644
index a99c41c993b..00000000000
--- a/firmware/bnx2x-e1-5.2.7.0.fw.ihex
+++ /dev/null
@@ -1,10178 +0,0 @@
-:10000000000028B0000000600000068800002918E9
-:100010000000161400002FA800000098000045C042
-:10002000000073C400004660000000CC0000BA2845
-:10003000000099A00000BAF800000094000154A04C
-:10004000000057BC00015538000000B80001ACF8B2
-:100050000000CE2C0001ADB80000000400027BE8D7
-:10006000020400480000000F020400540000004594
-:1000700002040058000000840204005C0000000636
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000060400CC0000000418
-:10010000020400DC00100000020400E012140000F1
-:10011000020400E422140000020400E8321400008B
-:10012000060400EC000000040104012400000000AB
-:1001300001040128000000000104012C000000005F
-:10014000010401300000000002040004000000FF70
-:1001500002040008000000FF0204000C000000FF81
-:1001600002040010000000FF02040014000000FF61
-:1001700002040018000000FF0204001C000000FF41
-:1001800002040020000000FF020400240000003EE2
-:1001900002040028000000000204002C0000003FC0
-:1001A000020400300000003F020400340000003F61
-:1001B00002040038000000000204003C0000003F80
-:1001C000020400400000003F020400440000003F21
-:1001D00002042008000004110204200C00000400A6
-:1001E000020420100000040402042014000004197A
-:1001F0000204201C0000FFFF020420200000FFFF7B
-:10020000020420240000FFFF020420280000FFFF5A
-:1002100006042038000000020204204000000034E0
-:100220000204204400000035060420480000007C41
-:100230000204223807FFFFFF0204223C0000003FB7
-:100240000204224007FFFFFF020422440000000FC7
-:1002500001042248000000000104224C00000000BC
-:10026000010422500000000001042254000000009C
-:1002700001042258000000000104225C000000007C
-:10028000010422600000000001042264000000005C
-:1002900001042268000000000104226C000000003C
-:1002A000010422700000000001042274000000001C
-:1002B00001042278000000000104227C00000000FC
-:1002C000020424BC000000010C042000000003E82C
-:1002D0000A042000000000010B0420000000000AB6
-:1002E0000205004400000020020500480000003222
-:1002F000020500900215002002050094021500205E
-:1003000002050098000000300205009C0810000063
-:10031000020500A000000033020500A40000003028
-:10032000020500A800000031020500AC0000000238
-:10033000020500B000000005020500B40000000640
-:10034000020500B800000002020500BC0000000227
-:10035000020500C000000000020500C40000000506
-:10036000020500C800000002020500CC00000002E7
-:10037000020500D000000002020500D400000001C8
-:1003800002050114000000010205011C000000012B
-:100390000205012000000002020502040000000125
-:1003A0000205020C0000004002050210000000409F
-:1003B0000205021C000000200205022000000013BC
-:1003C0000205022400000020060502400000000A89
-:1003D0000405028000200000020500500000000714
-:1003E0000205005400000007020500580000000844
-:1003F0000205005C00000008060500600000000423
-:10040000020500D800000006020500E00000000D13
-:10041000020500E40000002D020500E800000007CE
-:10042000020500EC00000027020500F000000007B4
-:10043000020500F400000027020500F80000000794
-:10044000020500FC00000027020500040000000176
-:1004500002050008000000010205000C0000000178
-:100460000205001000000001020500140000000158
-:1004700002050018000000010205001C0000000138
-:100480000205002000000001020500240000000118
-:1004900002050028000000010205002C00000001F8
-:1004A00002050030000000010205003400000001D8
-:1004B00002050038000000010205003C00000001B8
-:1004C00002050040000000010406100002000020A8
-:1004D000020600DC00000001010600D80000000058
-:1004E0000406020000030220020600DC00000000F7
-:1004F00002060068000000B802060078000001143F
-:10050000010600B800000000010600C8000000005D
-:100510000206006C000000B80206007C0000011416
-:10052000010600BC00000000010600CC0000000035
-:100530000718040000960000081807600014022342
-:10054000071C000034C50000071C800034DB0D329E
-:10055000071D00000A1D1A69081D14405D78022558
-:100560000118000000000000011800040000000055
-:1005700001180008000000000118000C0000000035
-:100580000118001000000000011800140000000015
-:1005900002180020000000010218002400000002E0
-:1005A00002180028000000030218002C00000000C0
-:1005B000021800300000000402180034000000019E
-:1005C00002180038000000000218003C0000000182
-:1005D000021800400000000402180044000000005F
-:1005E00002180048000000010218004C000000033F
-:1005F0000218005000000000021800540000000122
-:1006000002180058000000040218005C00000000FE
-:1006100002180060000000010218006400000003DE
-:1006200002180068000000000218006C00000001C1
-:10063000021800700000000402180074000000009E
-:1006400002180078000000040218007C000000037B
-:100650000618008000000002021800A400003FFFFE
-:10066000021800A8000003FF021802240000000086
-:1006700002180234000000000218024C00000000C2
-:10068000021802E4000000FF061810000000040039
-:10069000021B8BC000000001021B80000000003420
-:1006A000021B804000000018021B80800000000C2C
-:1006B000021B80C0000000200C1B83000007A1204B
-:1006C0000A1B8300000001380B1B83000000138805
-:1006D000021B83C0000001F4061A2000000000B2D3
-:1006E000061A23C800000181041A29CC0001022740
-:1006F000061A1020000000C8061A100000000002B0
-:10070000061A1E3800000002061A1E300000000201
-:10071000061A080000000002061A0808000000027D
-:10072000061A081000000004041A1FB00005022871
-:10073000041A4CB00008022D061A22C8000000203E
-:10074000061A400000000124021A4920000000009F
-:10075000061A14000000000A061A145000000006D1
-:10076000061A150000000002041A150800050235DB
-:10077000061A151C00000009061A15800000001456
-:10078000061A09C000000048061A0800000000020E
-:10079000061A08200000000E041A1FB00002023AD8
-:1007A000061A2C2800000002061A23480000002028
-:1007B000061A449000000124021A49240000000097
-:1007C000061A14280000000A061A14680000000621
-:1007D000061A154000000002041A15480005023CE4
-:1007E000061A155C00000009061A15D00000001456
-:1007F000061A0AE000000048061A08080000000275
-:10080000061A08580000000E041A1FB80002024120
-:10081000061A2C30000000020200A2800000000135
-:100820000200A294071D29110200A29800000000F6
-:100830000200A29C009C04240200A2A00000000070
-:100840000200A2A4000002090200A4FCFF000000B4
-:10085000020100B400000001020100B80000000124
-:10086000020100DC000000010201010000000001A3
-:1008700002010104000000010201007C00300000C0
-:1008800002010084000000280201008C000000002A
-:1008900002010130000000040201025C00000001BE
-:1008A000020103280000000002010554000000308E
-:1008B000020100C400000001020100CC00000001A0
-:1008C000020100F800000001020100F00000000138
-:1008D00002010080003000000201008800000028B2
-:1008E0000201009000000000020101340000000439
-:1008F000020102DC000000010201032C00000000E4
-:100900000201056400000030020100C8000000017F
-:10091000020100D000000001020100FC0000000103
-:10092000020100F400000001020C10000000002091
-:10093000020C200800000A11020C200C00000A0022
-:10094000020C201000000A04020C201C0000FFFF13
-:10095000020C20200000FFFF020C20240000FFFFFB
-:10096000020C20280000FFFF060C203800000002C7
-:10097000020C204000000034020C2044000000352E
-:10098000020C204800000020020C204C0000002136
-:10099000020C205000000022020C20540000002312
-:1009A000020C205800000024020C205C00000025EE
-:1009B000020C206000000026020C206400000027CA
-:1009C000020C206800000028020C206C00000029A6
-:1009D000020C20700000002A020C20740000002B82
-:1009E000060C207800000056020C21D00000000107
-:1009F000020C21D400000001020C21D800000001EB
-:100A0000020C21DC00000001020C21E000000001CA
-:100A1000020C21E400000001020C21E800000001AA
-:100A2000020C21EC00000001020C21F0000000018A
-:100A3000020C21F400000001060C21F80000001057
-:100A4000020C223807FFFFFF020C223C0000003F8F
-:100A5000020C224007FFFFFF020C22440000000F9F
-:100A6000010C224800000000010C224C0000000094
-:100A7000010C225000000000010C22540000000074
-:100A8000010C225800000000010C225C0000000054
-:100A9000010C226000000000010C22640000000034
-:100AA000010C226800000000010C226C0000000014
-:100AB000010C227000000000010C227400000000F4
-:100AC000010C227800000000010C227C00000000D4
-:100AD000020C24BC000000010C0C2000000003E804
-:100AE0000A0C2000000000010B0C20000000000A8E
-:100AF000020C400800000365020C400C0000035487
-:100B0000020C401000000358020C40140000037552
-:100B1000020C401C0000FFFF020C40200000FFFF01
-:100B2000020C40240000FFFF020C40280000FFFFE1
-:100B3000020C403800000046020C403C000000055A
-:100B4000060C40400000005E020C41B800000001AD
-:100B5000060C41BC0000001F020C423807FFFFFFDB
-:100B6000020C423C0000003F020C424007FFFFFF26
-:100B7000020C42440000000F010C4248000000003B
-:100B8000010C424C00000000010C4250000000002B
-:100B9000010C425400000000010C4258000000000B
-:100BA000010C425C00000000010C426000000000EB
-:100BB000010C426400000000010C426800000000CB
-:100BC000010C426C00000000010C427000000000AB
-:100BD000010C427400000000010C4278000000008B
-:100BE000010C427C00000000010C4280000000006B
-:100BF000020C44C0000000010C0C4000000003E89F
-:100C00000A0C4000000000010B0C40000000000A2C
-:100C1000020D004400000032020D008C021500207D
-:100C2000020D009002150020020D00940810000033
-:100C3000020D009800000033020D009C000000022D
-:100C4000020D00A000000000020D00A4000000053D
-:100C5000020D00A800000005060D00AC0000000217
-:100C6000020D00B400000002020D00B800000003F5
-:100C7000020D00BC00000002020D00C000000001D7
-:100C8000020D00C800000002020D00CC00000002AE
-:100C9000020D010800000001020D015C00000001CE
-:100CA000020D016400000001020D01680000000255
-:100CB000020D020400000001020D020C00000020E1
-:100CC000020D021000000040020D0214000000405E
-:100CD000020D022000000003020D02240000001893
-:100CE000060D028000000012040D030000240243E0
-:100CF000020D004C00000001020D00500000000237
-:100D0000020D005400000008020D00580000000809
-:100D1000060D005C00000004020D00C40000000489
-:100D2000020D011400000009020D01180000002945
-:100D3000020D011C0000000A020D01200000002A23
-:100D4000020D012400000007020D01280000002709
-:100D5000020D012C00000007020D013000000027E9
-:100D6000020D01340000000C020D01380000002CBF
-:100D7000020D013C0000000C020D01400000002C9F
-:100D8000020D01440000000C020D01480000002C7F
-:100D9000020D000400000001020D00080000000127
-:100DA000020D000C00000001020D00100000000107
-:100DB000020D001400000001020D001800000001E7
-:100DC000020D001C00000001020D002000000001C7
-:100DD000020D002400000001020D002800000001A7
-:100DE000020D002C00000001020D00300000000187
-:100DF000020D003400000001020D00380000000167
-:100E0000020D003C00000001020E004C0000003208
-:100E1000020E009402150020020E00980215002018
-:100E2000020E009C00000030020E00A0081000001E
-:100E3000020E00A400000033020E00A800000030E3
-:100E4000020E00AC00000031020E00B000000002F3
-:100E5000020E00B400000004020E00B80000000002
-:100E6000020E00BC00000002020E00C000000002E2
-:100E7000020E00C400000000020E00C800000002C4
-:100E8000020E00CC00000007020E00D0000000029D
-:100E9000020E00D400000002020E00D80000000183
-:100EA000020E00E400000001020E014400000001F7
-:100EB000020E014C00000001020E01500000000271
-:100EC000020E020400000001020E020C00000040AD
-:100ED000020E021000000040020E021C000000047E
-:100EE000020E022000000020020E02240000000E6C
-:100EF000020E02280000001B060E03000000001274
-:100F0000040E0280001B0267020E00540000000C59
-:100F1000020E005800000009020E005C0000000FE5
-:100F2000020E006000000010060E006400000004C5
-:100F3000020E00DC00000003020E01100000000F92
-:100F4000020E01140000002F020E01180000000E16
-:100F5000020E011C0000002E020E00040000000121
-:100F6000020E000800000001020E000C000000014B
-:100F7000020E001000000001020E0014000000012B
-:100F8000020E001800000001020E001C000000010B
-:100F9000020E002000000001020E002400000001EB
-:100FA000020E002800000001020E002C00000001CB
-:100FB000020E003000000001020E003400000001AB
-:100FC000020E003800000001020E003C000000018B
-:100FD000020E004000000001020E0044000000016B
-:100FE0000730040000CA00000830076800130282BE
-:100FF00007340000336100000734800037270CD924
-:10100000073500002F111AA30835708051F00284B3
-:10101000013000000000000001300004000000006A
-:1010200001300008000000000130000C000000004A
-:10103000013000100000000001300014000000002A
-:1010400002300020000000010230002400000002F5
-:1010500002300028000000030230002C00000000D5
-:1010600002300030000000040230003400000001B3
-:1010700002300038000000000230003C0000000197
-:101080000230004000000004023000440000000074
-:1010900002300048000000010230004C0000000354
-:1010A0000230005000000000023000540000000137
-:1010B00002300058000000040230005C0000000014
-:1010C00002300060000000010230006400000003F4
-:1010D00002300068000000000230006C00000001D7
-:1010E00002300070000000040230007400000000B4
-:1010F00002300078000000040230007C0000000391
-:101100000630008000000002023000A400003FFF13
-:10111000023000A8000003FF02300224000000009B
-:1011200002300234000000000230024C00000000D7
-:10113000023002E40000FFFF06302000000008003B
-:1011400002338BC000000001023380000000001A4F
-:10115000023380400000004E023380800000001007
-:10116000023380C0000000200C3383000007A12060
-:101170000A338300000001380B338300000013881A
-:10118000023383C0000001F40C3383801DCD650061
-:101190000A3383800004C4B40B338380004C4B407B
-:1011A00006321AA0000000C206321020000000C85B
-:1011B0000632100000000002063214000000004059
-:1011C00006325098000000040632508000000005EE
-:1011D00004325094000102860632500000000020C4
-:1011E00004322830000202870233080001000000A8
-:1011F00004330C00001002890233080000000000D4
-:1012000004330C400010029906321500000000B4AF
-:1012100002321DC80000000006324000000000D865
-:10122000063217D0000000B402321DCC00000000CE
-:1012300006324360000000D807200400009200003E
-:1012400008200780001002A9072400002CD100000C
-:10125000072480002AE50B350824DC6062DA02AB43
-:101260000120000000000000012000040000000038
-:1012700001200008000000000120000C0000000018
-:1012800001200010000000000120001400000000F8
-:1012900002200020000000010220002400000002C3
-:1012A00002200028000000030220002C00000000A3
-:1012B0000220003000000004022000340000000181
-:1012C00002200038000000000220003C0000000165
-:1012D0000220004000000004022000440000000042
-:1012E00002200048000000010220004C0000000322
-:1012F0000220005000000000022000540000000105
-:1013000002200058000000040220005C00000000E1
-:1013100002200060000000010220006400000003C1
-:1013200002200068000000000220006C00000001A4
-:101330000220007000000004022000740000000081
-:1013400002200078000000040220007C000000035E
-:101350000620008000000002022000A400003FFFE1
-:10136000022000A8000003FF022002240000000069
-:1013700002200234000000000220024C00000000A5
-:10138000022002E40000FFFF062020000000080009
-:1013900002238BC000000001022380000000001027
-:1013A00002238040000000120223808000000030F1
-:1013B000022380C00000000E022383C0000001F45D
-:1013C000062250000000004206221020000000C843
-:1013D000062210000000000206222000000000C0CB
-:1013E000062225C00000024004222EC8000802ADDB
-:1013F00002230800013FFFFF04230C00001002B588
-:10140000022308000000000004230C40001002C565
-:1014100006223040000000A00622354000000010E7
-:10142000062236C000000030062240000000020004
-:10143000062235C00000002006223840000000309F
-:1014400006223000000000080222511800000000AF
-:10145000062223000000000E0622241000000030A7
-:10146000062232C0000000A00622358000000010D5
-:1014700006223780000000300622480000000200EB
-:10148000062236400000002006223900000000300D
-:1014900006223020000000080222511C000000003B
-:1014A000062223380000000E062224D0000000305F
-:1014B00002161000000000280217000800000002B9
-:1014C0000217002C000000030217003C000000047B
-:1014D0000217004400000008021700480000000244
-:1014E0000217004C0000009002170050000000900E
-:1014F00002170054008000900217005808140000E2
-:10150000021700600000008A0217006400000080DB
-:1015100002170068000000810217006C00000080C4
-:10152000021700700000000602170078000007D0C4
-:101530000217007C0000076C02170038007C1004C2
-:10154000021700040000000F0616402400000002ED
-:10155000021640700000001C021642080000000144
-:101560000216421000000001021642200000000195
-:10157000021642280000000102164230000000015D
-:10158000021642380000000102164260000000010D
-:101590000C16401C0003D0900A16401C0000009C52
-:1015A0000B16401C000009C4021640300000000861
-:1015B000021640340000000C0216403800000010F3
-:1015C0000216404400000020021640000000000106
-:1015D000021640D800000001021640080000000179
-:1015E0000216400C0000000102164010000000012D
-:1015F00002164240000000000216424800000000AF
-:101600000616427000000002021642500000000060
-:101610000216425800000000061642800000000238
-:1016200002166008000006140216600C0000060096
-:1016300002166010000006040216601C0000FFFF86
-:10164000021660200000FFFF021660240000FFFF6A
-:10165000021660280000FFFF02166038000000201C
-:101660000216603C000000200216604000000034BA
-:101670000216604400000035021660480000002396
-:101680000216604C00000024021660500000002585
-:101690000216605400000026021660580000002761
-:1016A0000216605C00000029021660600000002A3B
-:1016B000021660640000002B021660680000002C17
-:1016C0000216606C0000002D0616607000000052CB
-:1016D000021661B800000001061661BC0000001F80
-:1016E0000216623807FFFFFF0216623C0000003F4F
-:1016F0000216624007FFFFFF021662440000000F5F
-:1017000001166248000000000116624C0000000053
-:101710000116625000000000011662540000000033
-:1017200001166258000000000116625C0000000013
-:1017300001166260000000000116626400000000F3
-:1017400001166268000000000116626C00000000D3
-:1017500001166270000000000116627400000000B3
-:1017600001166278000000000116627C0000000093
-:10177000021664BC000000010C166000000003E8C3
-:101780000A166000000000010B1660000000000A4D
-:10179000021680400000000602168044000000058A
-:1017A000021680480000000A0216804C0000000566
-:1017B0000216805400000002021680CC00000004D3
-:1017C000021680D000000004021680D4000000043D
-:1017D000021680D800000004021680DC000000041D
-:1017E000021680E000000004021680E400000004FD
-:1017F000021680E8000000040216880400000004BD
-:10180000021680300000007C021680340000003D8B
-:10181000021680380000003F0216803C0000009C49
-:10182000021680F000000007061680F40000000594
-:101830000216880C01010101021681080000000057
-:101840000216810C00000004021681100000000442
-:1018500002168114000000020216881008012004FC
-:1018600002168118000000050216811C0000000508
-:1018700002168120000000050216812400000005E8
-:101880000216882C2008100102168128000000088A
-:101890000216812C000000060216813000000007AD
-:1018A0000216813400000000021688300101012078
-:1018B0000616813800000004021688340101010177
-:1018C0000616814800000004021688380101010153
-:1018D00006168158000000040216883C010101012F
-:1018E00006168168000000030216817400000001E2
-:1018F00002168840010101010216817800000001F2
-:101900000216817C000000010216818000000001A7
-:1019100002168184000000010216884401010101C1
-:1019200002168188000000010216818C000000046C
-:10193000021681900000000402168194000000024B
-:10194000021688480801200402168198000000054C
-:101950000216819C00000005021681A0000000050F
-:10196000021681A400000005021688142008100148
-:10197000021681A800000008021681AC00000006D3
-:10198000021681B000000007021681B400000001B9
-:101990000216881801010120021681B8000000011A
-:1019A000021681BC00000001021681C00000000187
-:1019B000021681C4000000010216881C0101010109
-:1019C000021681C800000001021681CC000000014F
-:1019D000021681D000000001021681D4000000012F
-:1019E0000216882001010101021681D800000001C1
-:1019F000021681DC00000001021681E000000001F7
-:101A0000021681E400000001021688240101010190
-:101A1000021681E800000001021681EC00000001BE
-:101A2000021681F000000001021688280101010160
-:101A300002168240FFFF003F0616824400000002AB
-:101A40000216824CFFFF003F021682500000010088
-:101A5000021682540000010006168258000000029F
-:101A600002168260000000C002168264000000C0FE
-:101A70000216826800001E000216826C00001E0022
-:101A800002168270000040000216827400004000BE
-:101A900002168278000080000216827C000080001E
-:101AA00002168280000020000216828400002000BE
-:101AB0000616828800000007021682A400000001BA
-:101AC000061682A80000000A021681F400000C0825
-:101AD000021681F800000040021681FC000001009F
-:101AE0000216820000000020021682040000001787
-:101AF00002168208000000800216820C000002001C
-:101B0000021682100000000002168218FFFF01FF7B
-:101B100002168214FFFF01FF0216823C0000001330
-:101B2000021680900000013F021680600000014014
-:101B30000216806400000140061680680000000262
-:101B400002168070000000C00616807400000007B6
-:101B50000216809C00000048021680A00000004889
-:101B6000061680A400000002021680AC00000048A7
-:101B7000061680B0000000070216823800008000C0
-:101B800002168234000025E40216809400007FFFD4
-:101B900002168220000000070216821C00000007C7
-:101BA000021682280000000002168224FFFFFFFFB9
-:101BB00002168230000000000216822CFFFFFFFF99
-:101BC000021680EC000000FF02140000000000017B
-:101BD0000214000C0000000102140040000000018B
-:101BE0000214004400007FFF0214000C00000000FB
-:101BF00002140000000000000214006C000000004D
-:101C00000214000400000001021400300000000172
-:101C100002140004000000000214005C0000000038
-:101C2000021400080000000102140034000000014A
-:101C30000214000800000000021400600000000010
-:101C40000202005800000032020200A0031500202A
-:101C5000020200A403150020020200A801000030C7
-:101C6000020200AC08100000020200B000000033C5
-:101C7000020200B400000030020200B8000000318F
-:101C8000020200BC00000003020200C000000006C7
-:101C9000020200C400000003020200C800000003AA
-:101CA000020200CC00000002020200D0000000008E
-:101CB000020200D400000002020200DC000000006A
-:101CC000020200E000000006020200E4000000043E
-:101CD000020200E800000002020200EC0000000224
-:101CE000020200F000000001020200FC00000006F9
-:101CF0000202012000000000020201340000000284
-:101D0000020201B0000000010202020C000000010A
-:101D10000202021400000001020202180000000288
-:101D200002020404000000010202040C0000004052
-:101D300002020410000000400202041C0000000423
-:101D4000020204200000002002020424000000021D
-:101D5000020204280000001F060205000000001215
-:101D600004020480001F02D5020200600000000F80
-:101D70000202006400000007020200680000000B7D
-:101D80000202006C0000000E060200700000000459
-:101D9000020200F40000000402020004000000013E
-:101DA00002020008000000010202000C0000000115
-:101DB00002020010000000010202001400000001F5
-:101DC00002020018000000010202001C00000001D5
-:101DD00002020020000000010202002400000001B5
-:101DE00002020028000000010202002C0000000195
-:101DF0000202003000000001020200340000000175
-:101E000002020038000000010202003C0000000154
-:101E10000202004000000001020200440000000134
-:101E200002020048000000010202004C0000000114
-:101E3000020200500000000102020108000000C878
-:101E40000202011800000002020201C400000000AA
-:101E5000020201CC00000000020201D400000002D6
-:101E6000020201DC00000002020201E4000000FFA7
-:101E7000020201EC000000FF0202010C000000C899
-:101E80000202011C00000002020201C80000000062
-:101E9000020201D000000000020201D8000000028E
-:101EA000020201E000000002020201E8000000FF5F
-:101EB000020201F0000000FF0728040000B5000046
-:101EC00008280768001302F4072C000035D300002F
-:101ED000072C80003A3E0D75072D00003B541C0571
-:101EE000072D800022BC2ADB082DC770471202F69E
-:101EF000012800000000000001280004000000008C
-:101F000001280008000000000128000C000000006B
-:101F1000012800100000000001280014000000004B
-:101F20000228002000000001022800240000000216
-:101F300002280028000000030228002C00000000F6
-:101F400002280030000000040228003400000001D4
-:101F500002280038000000000228003C00000001B8
-:101F60000228004000000004022800440000000095
-:101F700002280048000000010228004C0000000375
-:101F80000228005000000000022800540000000158
-:101F900002280058000000040228005C0000000035
-:101FA0000228006000000001022800640000000315
-:101FB00002280068000000000228006C00000001F8
-:101FC00002280070000000040228007400000000D5
-:101FD00002280078000000040228007C00000003B2
-:101FE0000628008000000002022800A400003FFF35
-:101FF000022800A8000003FF0228022400000000BD
-:1020000002280234000000000228024C00000000F8
-:10201000022802E40000FFFF06282000000008005C
-:10202000022B8BC000000001022B8000000000008A
-:10203000022B804000000018022B80800000000C62
-:10204000022B80C0000000660C2B83000007A1203B
-:102050000A2B8300000001380B2B8300000013883B
-:10206000022B83C0000001F40C2B8340000001F41C
-:102070000A2B8340000000000B2B8340000000056A
-:102080000A2B83800004C4B40C2B83801DCD650013
-:102090000B2B8380004C4B40062A3C400000000480
-:1020A000042A3C50000202F8062A300000000048D2
-:1020B000062A1020000000C8062A100000000002B6
-:1020C000062A31280000008E022A33680000000032
-:1020D000042A3370000202FA042A3A70000402FC57
-:1020E000042A3D0000020300042A15000002030236
-:1020F000062A150800000100022A197000000000DD
-:10210000022A197800000000042A19600002030462
-:10211000062A4AC000000002062A4B000000000404
-:10212000042A1F4800020306022B080000000000DA
-:10213000042B0C0000100308022B08000100000013
-:10214000042B0C4000080318022B080002000000BA
-:10215000042B0C6000080320062A3A8000000014BB
-:10216000062A3B2000000024062A14000000000A72
-:10217000062A145000000006062A3378000000D812
-:10218000022A3A3800000000042A3C5800020328C2
-:10219000042A3C680010032A062A5020000000028E
-:1021A000062A503000000002062A500000000002FB
-:1021B000062A501000000002022A504000000000D1
-:1021C000062A50480000000E022A50B80000000104
-:1021D000042A4AC80002033A062A4B1000000042B3
-:1021E000062A4D2000000004062A3AD00000001400
-:1021F000062A3BB000000024062A14280000000A2A
-:10220000062A146800000006062A36D8000000D806
-:10221000022A3A3C00000000042A3C600002033C11
-:10222000042A3CA80010033E062A502800000002A1
-:10223000062A503800000002062A5008000000025A
-:10224000062A501800000002022A50440000000034
-:10225000062A50800000000E022A50BC0000000137
-:10226000042A4AD00002034E062A4C1800000042FD
-:10227000062A4D3000000004021010080000000182
-:102280000210101000000264021010000003D000C1
-:10229000021010040000003D091018000200035055
-:1022A00009101100002005500610118000000002E6
-:1022B0000910118800060570061011A00000001812
-:1022C000021010100000000006102400000000E0C2
-:1022D0000210201C0000000002102020000000015D
-:1022E000021020C0000000010210200400000001C4
-:1022F000021020080000000109103C0000050576CE
-:1023000009103C200005057B0910380000050580F8
-:1023100002104028000000100210404400003FFF5F
-:102320000210405800280000021040840084924AA5
-:1023300002104058000000000610806800000004F1
-:1023400002108000000010800610802800000002AB
-:102350000210803800000010021080400000FFFFD3
-:10236000021080440000FFFF0210805000000000B7
-:102370000210810000000000061081200000000211
-:1023800002108008000002B502108010000000005A
-:10239000061082000000004A021081080001FFFFC1
-:1023A00006108140000000020210800000001A8028
-:1023B0000610900000000024061091200000004A42
-:1023C000061093700000004A061095C00000004AF5
-:1023D000021080040000108006108030000000020F
-:1023E0000210803C00000010021080480000FFFF37
-:1023F0000210804C0000FFFF02108054000000001B
-:102400000210810400000000061081280000000274
-:102410000210800C000002B50210801400000000C1
-:10242000061084000000004A0210810C0001FFFF2A
-:1024300006108148000000020210800400001A808B
-:102440000610909000000024061092480000004AF8
-:10245000061094980000004A061096E80000004A12
-:102460000212049000E383400212051400003C10A5
-:10247000021205200000000202120494FFFFFFFF79
-:1024800002120498FFFFFFFF0212049CFFFFFFFFF0
-:10249000021204A0FFFFFFFF021204A4FFFFFFFFD0
-:1024A000021204A8FFFFFFFF021204ACFFFFFFFFB0
-:1024B000021204B0FFFFFFFF021204B8FFFFFFFF8C
-:1024C000021204BCFFFFFFFF021204C0FFFFFFFF68
-:1024D000021204C4FFFFFFFF021204C8FFFFFFFF48
-:1024E000021204CCFFFFFFFF021204D0FFFFFFFF28
-:1024F000021204DCFFFFFFFF021204E0FFFFFFFFF8
-:10250000021204E4FFFFFFFF021204E8FFFFFFFFD7
-:10251000021204ECFFFFFFFF021204F0FFFFFFFFB7
-:10252000021204F4FFFFFFFF021204F8FFFFFFFF97
-:10253000021204FCFFFFFFFF02120500FFFFFFFF76
-:1025400002120504FFFFFFFF02120508FFFFFFFF55
-:102550000212050CFFFFFFFF02120510FFFFFFFF35
-:10256000021204D4FFFF3330021204D8FFFF3340BD
-:10257000021204B4F00030000212039000000008C0
-:102580000212039C00000008061203A000000002D3
-:10259000021203BC00000004021203C40000000485
-:1025A000021203D000000000021203DC0000000051
-:1025B0000212036C00000001021203680000003FD9
-:1025C000021201BC00000040021201C00000180805
-:1025D000021201C400000803021201C8000008032F
-:1025E000021201CC00000040021201D000000003E2
-:1025F000021201D400000803021201D800000803EF
-:10260000021201DC00000803021201E000010003D5
-:10261000021201E400000803021201E800000803AE
-:10262000021201EC00000003021201F0000000039E
-:10263000021201F400000003021201F8000000037E
-:10264000021201FC0000000302120200000000035D
-:10265000021202040000000302120208000000033C
-:102660000212020C0000000302120210000000031C
-:1026700002120214000000030212021800000003FC
-:102680000212021C000000030212022000000003DC
-:102690000212022400000003021202280000240398
-:1026A0000212022C0000002F02120230000000096A
-:1026B00002120234000000190212023800000184E4
-:1026C0000212023C000001830212024000000306D5
-:1026D0000212024400000019021202480000000623
-:1026E0000212024C00000306021202500000030610
-:1026F00002120254000003060212025800000C8667
-:102700000212025C000003060212026000000306CF
-:1027100002120264000000060212026800000006B5
-:102720000212026C00000006021202700000000695
-:102730000212027400000006021202780000000675
-:102740000212027C00000006021202800000000655
-:102750000212028400000006021202880000000635
-:102760000212028C00000006021202900000000615
-:1027700002120294000000060212029800000006F5
-:102780000212029C00000006021202A000000306D2
-:10279000021202A400000013021202A800000006A8
-:1027A000021202B000001004021202B40000100471
-:1027B0000212032400106440021203280010644037
-:1027C000021201B0000000010600A0000000001687
-:1027D0000200A06CBF5C00000200A070FFF51FEFBC
-:1027E0000200A0740000FFFF0200A078500003E088
-:1027F0000200A07C000000000200A0800000A000F9
-:102800000600A084000000050200A0980FE0000070
-:102810000600A09C000000140200A0EC555400002B
-:102820000200A0F0555555550200A0F40000555582
-:102830000200A0F8000000000200A0FC55540000B7
-:102840000200A100555555550200A1040000555540
-:102850000200A108000000000200A22C00000000FD
-:102860000600A230000000030200A0600000000784
-:102870000200A10CBF5C00000200A110FFF51FEFD9
-:102880000200A1140000FFFF0200A118500003E0A5
-:102890000200A11C000000000200A1200000A00016
-:1028A0000600A124000000050200A1380FE000008E
-:1028B0000600A13C000000140200A18C5554000049
-:1028C0000200A190555555550200A19400005555A0
-:1028D0000200A198000000000200A19C55540000D5
-:1028E0000200A1A0555555550200A1A40000555560
-:1028F0000200A1A8000000000200A23C00000000AD
-:102900000600A240000000030200A06400000007CF
-:1029100000000000000000000000002E0000000089
-:1029200000000000000000000000000000000000A7
-:102930000000000000000000000000000000000097
-:102940000000000000000000000000000000000087
-:102950000000000000000000000000000000000077
-:102960000000000000000000000000000000000067
-:10297000002E0050000000000000000000000000D9
-:102980000000000000000000000000000000000047
-:102990000000000000000000000000000050008D5A
-:1029A0000000000000000000000000000000000027
-:1029B0000000000000000000000000000000000017
-:1029C0000000000000000000008D009200920096C0
-:1029D0000096009A000000000000000000000000C7
-:1029E00000000000000000000000000000000000E7
-:1029F00000000000009A00DB00DB00E900E900F7BE
-:102A000000000000000000000000000000000000C6
-:102A100000000000000000000000000000000000B6
-:102A200000000000000000000000000000000000A6
-:102A30000000000000000000000000000000000096
-:102A40000000000000000000000000000000000086
-:102A50000000000000000000000000000000000076
-:102A60000000000000000000000000000000000066
-:102A70000000000000000000000000000000000056
-:102A80000000000000000000000000000000000046
-:102A90000000000000000000000000000000000036
-:102AA0000000000000000000000000000000000026
-:102AB0000000000000000000000000000000000016
-:102AC0000000000000000000000000000000000006
-:102AD00000F700FE00000000000000000000000001
-:102AE00000000000000000000000000000000000E6
-:102AF00000000000000000000000000000000000D6
-:102B000000000000000000000000000000000000C5
-:102B100000000000000000000000000000000000B5
-:102B2000000000000000000000FE01030103010E90
-:102B3000010E01190000000000000000000000006C
-:102B40000000000000000000000000000000000085
-:102B50000000000000000000000000000000000075
-:102B60000000000000000000000000000000000065
-:102B70000000000000000000000000000000000055
-:102B80000119011A00000000000000000000000010
-:102B90000000000000000000000000000000000035
-:102BA000000000000000000000000000011A0152B7
-:102BB0000000000000000000000000000000000015
-:102BC0000000000000000000000000000000000005
-:102BD000000000000000000001520176000000002B
-:102BE00000000000000000000000000000000000E5
-:102BF00000000000000000000000000000000000D5
-:102C000000000000017601B5000000000000000097
-:102C100000000000000000000000000000000000B4
-:102C200000000000000000000000000000000000A4
-:102C300001B501F0000000000000000000000000ED
-:102C40000000000000000000000000000000000084
-:102C500000000000000000000000000001F002354C
-:102C6000023502380238023B00000000000000007C
-:102C70000000000000000000000000000000000054
-:102C80000000000000000000023B02760276028095
-:102C90000280028A00000000000000000000000026
-:102CA0000000000000000000000000000000000024
-:102CB00000000000028A028B0000000000000000FB
-:102CC0000000000000000000000000000000000004
-:102CD00000000000000000000000000000000000F4
-:102CE000028B029D000000000000000000000000B8
-:102CF00000000000000000000000000000000000D4
-:102D0000000000000000000000000000029D02B270
-:102D100002B202B502B502B80000000000000000D7
-:102D200000000000000000000000000000000000A3
-:102D3000000000000000000002B802E600000000F1
-:102D40000000000000000000000000000000000083
-:102D50000000000000000000000000000000000073
-:102D60000000000002E6036D00000000000000000B
-:102D70000000000000000000000000000000000053
-:102D80000000000000000000000000000000000043
-:102D9000036D0374037403780378037C0000000060
-:102DA0000000000000000000000000000000000023
-:102DB000000000000000000000000000037C03BBD6
-:102DC00003BB03C303C303CB0000000000000000EB
-:102DD00000000000000000000000000000000000F3
-:102DE000000000000000000003CB041F041F04319A
-:102DF0000431044300000000000000000000000057
-:102E000000000000000000000000000000000000C2
-:102E1000000000000443044D00000000000000001A
-:102E200000000000000000000000000000000000A2
-:102E30000000000000000000000000000000000092
-:102E4000044D0453000000000000000000000000DA
-:102E50000000000000000000000000000000000072
-:102E600000000000000000000000000004530456B1
-:102E70000000000000000000000000000000000052
-:102E80000000000000000000000000000000000042
-:102E900000000000000000000456045B0000000079
-:102EA0000000000000000000000000000000000022
-:102EB0000000000000000000000000000000000012
-:102EC00000000000045B045C045C046E046E04807B
-:102ED00000000000000000000000000000000000F2
-:102EE00000000000000000000000000000000000E2
-:102EF000048004ED0000000000000000000000005D
-:102F000000000000000000000000000000000000C1
-:102F100000000000000000000000000004ED04EECE
-:102F200004EE050205020516000000000000000086
-:102F30000000000000000000000000000000000091
-:102F40000000000000000000000000000000000081
-:102F50000000000000000000000000000000000071
-:102F60000000000000000000000000000000000061
-:102F70000000000000000000000000000000000051
-:102F80000000000000000000000000000000000041
-:102F90000000000000000000000000000000000031
-:102FA000000000000000000000010000000204C05A
-:102FB0000003098000040E4000051300000617C03E
-:102FC00000071C800008214000092600000A2AC0D2
-:102FD000000B2F80000C3440000D3900000E3DC066
-:102FE000000F42800010474000114C00001250C0FA
-:102FF0000013558000145A4000155F00001663C08E
-:103000000017688000186D4000197200001A76C021
-:10301000001B7B80001C8040001D8500001E89C0B5
-:10302000001F8E8000209340000020000000400020
-:1030300000006000000080000000A0000000C00050
-:103040000000E0000001000000012000000140003D
-:1030500000016000000180000001A0000001C0002C
-:103060000001E00000020000000220000002400019
-:1030700000026000000280000002A0000002C00008
-:103080000002E000000300000003200000034000F5
-:1030900000036000000380000003A0000003C000E4
-:1030A0000003E000000400000004200000044000D1
-:1030B00000046000000480000004A0000004C000C0
-:1030C0000004E000000500000005200000054000AD
-:1030D00000056000000580000005A0000005C0009C
-:1030E0000005E00000060000000620000006400089
-:1030F00000066000000680000006A0000006C00078
-:103100000006E00000070000000720000007400064
-:1031100000076000000780000007A0000007C00053
-:103120000007E00000080000000820000008400040
-:1031300000086000000880000008A0000008C0002F
-:103140000008E0000009000000092000000940001C
-:1031500000096000000980000009A0000009C0000B
-:103160000009E000000A0000000A2000000A4000F8
-:10317000000A6000000A8000000AA000000AC000E7
-:10318000000AE000000B0000000B2000000B4000D4
-:10319000000B6000000B8000000BA000000BC000C3
-:1031A000000BE000000C0000000C2000000C4000B0
-:1031B000000C6000000C8000000CA000000CC0009F
-:1031C000000CE000000D0000000D2000000D40008C
-:1031D000000D6000000D8000000DA000000DC0007B
-:1031E000000DE000000E0000000E2000000E400068
-:1031F000000E6000000E8000000EA000000EC00057
-:10320000000EE000000F0000000F2000000F400043
-:10321000000F6000000F8000000FA000000FC00032
-:10322000000FE0000010000000102000001040001F
-:1032300000106000001080000010A0000010C0000E
-:103240000010E000001100000011200000114000FB
-:1032500000116000001180000011A0000011C000EA
-:103260000011E000001200000012200000124000D7
-:1032700000126000001280000012A0000012C000C6
-:103280000012E000001300000013200000134000B3
-:1032900000136000001380000013A0000013C000A2
-:1032A0000013E0000014000000142000001440008F
-:1032B00000146000001480000014A0000014C0007E
-:1032C0000014E0000015000000152000001540006B
-:1032D00000156000001580000015A0000015C0005A
-:1032E0000015E00000160000001620000016400047
-:1032F00000166000001680000016A0000016C00036
-:103300000016E00000170000001720000017400022
-:1033100000176000001780000017A0000017C00011
-:103320000017E000001800000018200000184000FE
-:1033300000186000001880000018A0000018C000ED
-:103340000018E000001900000019200000194000DA
-:1033500000196000001980000019A0000019C000C9
-:103360000019E000001A0000001A2000001A4000B6
-:10337000001A6000001A8000001AA000001AC000A5
-:10338000001AE000001B0000001B2000001B400092
-:10339000001B6000001B8000001BA000001BC00081
-:1033A000001BE000001C0000001C2000001C40006E
-:1033B000001C6000001C8000001CA000001CC0005D
-:1033C000001CE000001D0000001D2000001D40004A
-:1033D000001D6000001D8000001DA000001DC00039
-:1033E000001DE000001E0000001E2000001E400026
-:1033F000001E6000001E8000001EA000001EC00015
-:10340000001EE000001F0000001F2000001F400001
-:10341000001F6000001F8000001FA000001FC000F0
-:10342000001FE000002000000020200000204000DD
-:1034300000206000002080000020A0000020C000CC
-:103440000020E000002100000021200000214000B9
-:1034500000216000002180000021A0000021C000A8
-:103460000021E00000220000002220000022400095
-:1034700000226000002280000022A0000022C00084
-:103480000022E00000230000002320000023400071
-:1034900000236000002380000023A0000023C00060
-:1034A0000023E0000024000000242000002440004D
-:1034B00000246000002480000024A0000024C0003C
-:1034C0000024E00000250000002520000025400029
-:1034D00000256000002580000025A0000025C00018
-:1034E0000025E00000260000002620000026400005
-:1034F00000266000002680000026A0000026C000F4
-:103500000026E000002700000027200000274000E0
-:1035100000276000002780000027A0000027C000CF
-:103520000027E000002800000028200000284000BC
-:1035300000286000002880000028A0000028C000AB
-:103540000028E00000290000002920000029400098
-:1035500000296000002980000029A0000029C00087
-:103560000029E000002A0000002A2000002A400074
-:10357000002A6000002A8000002AA000002AC00063
-:10358000002AE000002B0000002B2000002B400050
-:10359000002B6000002B8000002BA000002BC0003F
-:1035A000002BE000002C0000002C2000002C40002C
-:1035B000002C6000002C8000002CA000002CC0001B
-:1035C000002CE000002D0000002D2000002D400008
-:1035D000002D6000002D8000002DA000002DC000F7
-:1035E000002DE000002E0000002E2000002E4000E4
-:1035F000002E6000002E8000002EA000002EC000D3
-:10360000002EE000002F0000002F2000002F4000BF
-:10361000002F6000002F8000002FA000002FC000AE
-:10362000002FE0000030000000302000003040009B
-:1036300000306000003080000030A0000030C0008A
-:103640000030E00000310000003120000031400077
-:1036500000316000003180000031A0000031C00066
-:103660000031E00000320000003220000032400053
-:1036700000326000003280000032A0000032C00042
-:103680000032E0000033000000332000003340002F
-:1036900000336000003380000033A0000033C0001E
-:1036A0000033E0000034000000342000003440000B
-:1036B00000346000003480000034A0000034C000FA
-:1036C0000034E000003500000035200000354000E7
-:1036D00000356000003580000035A0000035C000D6
-:1036E0000035E000003600000036200000364000C3
-:1036F00000366000003680000036A0000036C000B2
-:103700000036E0000037000000372000003740009E
-:1037100000376000003780000037A0000037C0008D
-:103720000037E0000038000000382000003840007A
-:1037300000386000003880000038A0000038C00069
-:103740000038E00000390000003920000039400056
-:1037500000396000003980000039A0000039C00045
-:103760000039E000003A0000003A2000003A400032
-:10377000003A6000003A8000003AA000003AC00021
-:10378000003AE000003B0000003B2000003B40000E
-:10379000003B6000003B8000003BA000003BC000FD
-:1037A000003BE000003C0000003C2000003C4000EA
-:1037B000003C6000003C8000003CA000003CC000D9
-:1037C000003CE000003D0000003D2000003D4000C6
-:1037D000003D6000003D8000003DA000003DC000B5
-:1037E000003DE000003E0000003E2000003E4000A2
-:1037F000003E6000003E8000003EA000003EC00091
-:10380000003EE000003F0000003F2000003F40007D
-:10381000003F6000003F8000003FA000003FC0006C
-:10382000003FE000003FE00100000000000001FF59
-:103830000000020000007FF800007FF80000026F27
-:1038400000001500000000010000000300BEBC20C5
-:103850000000000300BEBC2000000001FFFFFFFFCE
-:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
-:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
-:1038800000000000FFFFFFFF00000000FFFFFFFF40
-:103890000000000300BEBC20FFFFFFFF000000008F
-:1038A000FFFFFFFF00000000FFFFFFFF000000031D
-:1038B00000BEBC2000002000000040C0000061806D
-:1038C000000082400000A3000000C3C00000E480AC
-:1038D0000001054000012600000146C0000167808C
-:1038E000000188400001A9000001C9C00001EA8070
-:1038F00000020B4000022C0000024CC000026D8050
-:1039000000028E400002AF000002CFC00002F08033
-:103910000003114000033200000352C00003738013
-:10392000000394400003B5000003D5C00003F680F7
-:103930000004174000043800000458C000047980D7
-:1039400000049A400000800000010380000187000D
-:1039500000020A8000028E0000031180000395001F
-:103960000004188000049C0000051F800005A300CF
-:10397000000626800006AA0000072D800007B1007F
-:10398000000834800008B80000093B800009BF002F
-:10399000000A4280000AC600000B4980000BCD00DF
-:1039A000000C5080000CD400000D5780000DDB008F
-:1039B00000007FF800007FF800000174000015008F
-:1039C0000000190000000000FFFFFFFF40000000A2
-:1039D00040000000400000004000000040000000E7
-:1039E00040000000400000004000000040000000D7
-:1039F00040000000400000004000000040000000C7
-:103A000040000000400000004000000040000000B6
-:103A100040000000400000004000000040000000A6
-:103A20004000000040000000400000004000000096
-:103A30004000000040000000400000004000000086
-:103A400040000000400000004000000000007FF83F
-:103A500000007FF80000050900003500FFFFFFFFB0
-:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
-:103A7000FFFFFFFFFFFFFFFFFFFFFFFF4000000012
-:103A80004000000040000000400000004000000036
-:103A90004000000040000000400000004000000026
-:103AA0004000000040000000400000004000000016
-:103AB0004000000040000000400000004000000006
-:103AC00040000000400000004000000040000000F6
-:103AD00040000000400000004000000040000000E6
-:103AE00040000000400000004000000040000000D6
-:103AF00040000000400000004000000000001000F6
-:103B000000002080000031000000418000005200D1
-:103B100000006280000073000000838000009400B9
-:103B20000000A4800000B5000000C5800000D600A1
-:103B30000000E6800000F700000107800001180087
-:103B400000012880000139000001498000015A006D
-:103B500000016A8000017B0000018B8000019C0055
-:103B60000001AC800001BD000001CD800001DE003D
-:103B70000001EE800001FF0000007FF800007FF8E8
-:103B8000000004480000150010000000000028ADEF
-:103B9000000000000001000100070205CCCCCCC1F0
-:103BA000FFFFFFFFFFFFFFFF7058103C0000000009
-:103BB0000000000000000001CCCC0201CCCCCCCC39
-:103BC00000000000FFFFFFFF400000004000000079
-:103BD00040000000400000004000000040000000E5
-:103BE00040000000400000004000000040000000D5
-:103BF00040000000400000004000000040000000C5
-:103C000040000000400000004000000040000000B4
-:103C100040000000400000004000000040000000A4
-:103C20004000000040000000400000004000000094
-:103C30004000000040000000400000004000000084
-:103C40004000000040000000000E01B7011600D641
-:103C50000000FFFF000000000000FFFF0000000068
-:103C60000000FFFF000000000000FFFF0000000058
-:103C70000000FFFF000000000000FFFF0000000048
-:103C80000000FFFF000000000000FFFF0000000038
-:103C90000010000000000000007201BB012300F3CF
-:103CA0000000FFFF000000000000FFFF0000000018
-:103CB0000000FFFF000000000000FFFF0000000008
-:103CC0000000FFFF000000000000FFFF00000000F8
-:103CD0000000FFFF000000000000FFFF00000000E8
-:103CE0000010000000000000FFFFFFF3318FFFFF16
-:103CF0000C30C30CC30C30C3CF3CF300F3CF3CF308
-:103D00000000CF3CCDCDCDCDFFFFFFF130EFFFFF69
-:103D10000C30C30CC30C30C3CF3CF300F3CF3CF3E7
-:103D20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD3
-:103D30000C30C30CC30C30C3CF3CF300F3CF3CF3C7
-:103D40000002CF3CCDCDCDCDFFFFF4061CBFFFFF61
-:103D50000C30C305C30C30C3CF300014F3CF3CF399
-:103D60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA4
-:103D70000C30C30CC30C30C3CF3CF300F3CF3CF387
-:103D80000008CF3CCDCDCDCDFFFFFFFA302FFFFF98
-:103D90000C30C30CC30C30C3CF3CF300F3CF3CF367
-:103DA0000010CF3CCDCDCDCDFFFFFFF731EFFFFFB2
-:103DB0000C30C30CC30C30C3CF3CF300F3CF3CF347
-:103DC0000020CF3CCDCDCDCDFFFFFFF5302FFFFF45
-:103DD0000C30C30CC30C30C3CF3CF300F3CF3CF327
-:103DE0000040CF3CCDCDCDCDFFFFFFF3318FFFFFA6
-:103DF0000C30C30CC30C30C3CF3CF300F3CF3CF307
-:103E00000000CF3CCDCDCDCDFFFFFFF1310FFFFF47
-:103E10000C30C30CC30C30C3CF3CF300F3CF3CF3E6
-:103E20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD2
-:103E30000C30C30CC30C30C3CF3CF300F3CF3CF3C6
-:103E40000002CF3CCDCDCDCDFFFFF4061CBFFFFF60
-:103E50000C30C305C30C30C3CF300014F3CF3CF398
-:103E60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA3
-:103E70000C30C30CC30C30C3CF3CF300F3CF3CF386
-:103E80000008CF3CCDCDCDCDFFFFFFFA302FFFFF97
-:103E90000C30C30CC30C30C3CF3CF300F3CF3CF366
-:103EA0000010CF3CCDCDCDCDFFFFFFF730EFFFFFB2
-:103EB0000C30C30CC30C30C3CF3CF300F3CF3CF346
-:103EC0000020CF3CCDCDCDCDFFFFFFF5304FFFFF24
-:103ED0000C30C30CC30C30C3CF3CF300F3CF3CF326
-:103EE0000040CF3CCDCDCDCDFFFFFFF331EFFFFF45
-:103EF0000C30C30CC30C30C3CF3CF300F3CF3CF306
-:103F00000000CF3CCDCDCDCDFFFFFFF1310FFFFF46
-:103F10000C30C30CC30C30C3CF3CF300F3CF3CF3E5
-:103F20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD1
-:103F30000C30C30CC30C30C3CF3CF300F3CF3CF3C5
-:103F40000002CF3CCDCDCDCDFFFFF4061CBFFFFF5F
-:103F50000C30C305C30C30C3CF300014F3CF3CF397
-:103F60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA2
-:103F70000C30C30CC30C30C3CF3CF300F3CF3CF385
-:103F80000008CF3CCDCDCDCDFFFFFFFA302FFFFF96
-:103F90000C30C30CC30C30C3CF3CF300F3CF3CF365
-:103FA0000010CF3CCDCDCDCDFFFFFF97056FFFFFBC
-:103FB0000C30C30CC30C30C3CF3CC000F3CF3CF378
-:103FC0000020CF3CCDCDCDCDFFFFFFF5310FFFFF62
-:103FD0000C30C30CC30C30C3CF3CF300F3CF3CF325
-:103FE0000040CF3CCDCDCDCDFFFFFFF3320FFFFF23
-:103FF0000C30C30CC30C30C3CF3CF300F3CF3CF305
-:104000000000CF3CCDCDCDCDFFFFFFF1310FFFFF45
-:104010000C30C30CC30C30C3CF3CF300F3CF3CF3E4
-:104020000001CF3CCDCDCDCDFFFFFFF6305FFFFFD0
-:104030000C30C30CC30C30C3CF3CF300F3CF3CF3C4
-:104040000002CF3CCDCDCDCDFFFFF4061CBFFFFF5E
-:104050000C30C305C30C30C3CF300014F3CF3CF396
-:104060000004CF3CCDCDCDCDFFFFFFF2304FFFFFA1
-:104070000C30C30CC30C30C3CF3CF300F3CF3CF384
-:104080000008CF3CCDCDCDCDFFFFFF8A042FFFFF31
-:104090000C30C30CC30C30C3CF3CC000F3CF3CF397
-:1040A0000010CF3CCDCDCDCDFFFFFF9705CFFFFF5B
-:1040B0000C30C30CC30C30C3CF3CC000F3CF3CF377
-:1040C0000020CF3CCDCDCDCDFFFFFFF5310FFFFF61
-:1040D0000C30C30CC30C30C3CF3CF300F3CF3CF324
-:1040E0000040CF3CCDCDCDCDFFFFFFF3300FFFFF24
-:1040F0000C30C30CC30C30C3CF3CF300F3CF3CF304
-:104100000000CF3CCDCDCDCDFFFFFFF1300FFFFF45
-:104110000C30C30CC30C30C3CF3CF300F3CF3CF3E3
-:104120000001CF3CCDCDCDCDFFFFFFF6305FFFFFCF
-:104130000C30C30CC30C30C3CF3CF300F3CF3CF3C3
-:104140000002CF3CCDCDCDCDFFFFF4061CBFFFFF5D
-:104150000C30C305C30C30C3CF300014F3CF3CF395
-:104160000004CF3CCDCDCDCDFFFFFFF2304FFFFFA0
-:104170000C30C30CC30C30C3CF3CF300F3CF3CF383
-:104180000008CF3CCDCDCDCDFFFFFFFA302FFFFF94
-:104190000C30C30CC30C30C3CF3CF300F3CF3CF363
-:1041A0000010CF3CCDCDCDCDFFFFFF97040FFFFF1B
-:1041B0000C30C30CC30C30C3CF3CC000F3CF3CF376
-:1041C0000020CF3CCDCDCDCDFFFFFFF5300FFFFF61
-:1041D0000C30C30CC30C30C3CF3CF300F3CF3CF323
-:1041E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF57
-:1041F0000C30C30CC30C30C3CF3CF3CCF3CF3CF337
-:104200000000CF3CCDCDCDCDFFFFFFFF30CFFFFF76
-:104210000C30C30CC30C30C3CF3CF3CCF3CF3CF316
-:104220000001CF3CCDCDCDCDFFFFFFFF30CFFFFF55
-:104230000C30C30CC30C30C3CF3CF3CCF3CF3CF3F6
-:104240000002CF3CCDCDCDCDFFFFFFFF30CFFFFF34
-:104250000C30C30CC30C30C3CF3CF3CCF3CF3CF3D6
-:104260000004CF3CCDCDCDCDFFFFFFFF30CFFFFF12
-:104270000C30C30CC30C30C3CF3CF3CCF3CF3CF3B6
-:104280000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEE
-:104290000C30C30CC30C30C3CF3CF3CCF3CF3CF396
-:1042A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC6
-:1042B0000C30C30CC30C30C3CF3CF3CCF3CF3CF376
-:1042C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF96
-:1042D0000C30C30CC30C30C3CF3CF3CCF3CF3CF356
-:1042E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF56
-:1042F0000C30C30CC30C30C3CF3CF3CCF3CF3CF336
-:104300000000CF3CCDCDCDCDFFFFFFFF30CFFFFF75
-:104310000C30C30CC30C30C3CF3CF3CCF3CF3CF315
-:104320000001CF3CCDCDCDCDFFFFFFFF30CFFFFF54
-:104330000C30C30CC30C30C3CF3CF3CCF3CF3CF3F5
-:104340000002CF3CCDCDCDCDFFFFFFFF30CFFFFF33
-:104350000C30C30CC30C30C3CF3CF3CCF3CF3CF3D5
-:104360000004CF3CCDCDCDCDFFFFFFFF30CFFFFF11
-:104370000C30C30CC30C30C3CF3CF3CCF3CF3CF3B5
-:104380000008CF3CCDCDCDCDFFFFFFFF30CFFFFFED
-:104390000C30C30CC30C30C3CF3CF3CCF3CF3CF395
-:1043A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC5
-:1043B0000C30C30CC30C30C3CF3CF3CCF3CF3CF375
-:1043C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF95
-:1043D0000C30C30CC30C30C3CF3CF3CCF3CF3CF355
-:1043E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF55
-:1043F0000C30C30CC30C30C3CF3CF3CCF3CF3CF335
-:104400000000CF3CCDCDCDCDFFFFFFFF30CFFFFF74
-:104410000C30C30CC30C30C3CF3CF3CCF3CF3CF314
-:104420000001CF3CCDCDCDCDFFFFFFFF30CFFFFF53
-:104430000C30C30CC30C30C3CF3CF3CCF3CF3CF3F4
-:104440000002CF3CCDCDCDCDFFFFFFFF30CFFFFF32
-:104450000C30C30CC30C30C3CF3CF3CCF3CF3CF3D4
-:104460000004CF3CCDCDCDCDFFFFFFFF30CFFFFF10
-:104470000C30C30CC30C30C3CF3CF3CCF3CF3CF3B4
-:104480000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEC
-:104490000C30C30CC30C30C3CF3CF3CCF3CF3CF394
-:1044A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC4
-:1044B0000C30C30CC30C30C3CF3CF3CCF3CF3CF374
-:1044C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF94
-:1044D0000C30C30CC30C30C3CF3CF3CCF3CF3CF354
-:1044E0000040CF3CCDCDCDCD000C0000000700C07A
-:1044F00000028130000B81580002021000010230DE
-:10450000000F024000010330000C0000000800C052
-:1045100000028140000B816800020220000102407D
-:1045200000070250000202C0000F0000000800F067
-:1045300000028170000B819800020250000102709D
-:10454000000B828000080338001000000008010002
-:1045500000028180000B81A80002026000018280BD
-:10456000000E82980008038000028000000B802863
-:10457000000200E0000101000000811000000118AD
-:10458000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6B
-:1045900000002000CCCCCCCCCCCCCCCCCCCCCCCC6B
-:1045A000CCCCCCCC00002000CCCCCCCCCCCCCCCC5B
-:1045B000CCCCCCCCCCCCCCCC00002000000000007B
-:1045C0001F8B080000000000000BFB51CFC0F00360
-:1045D0008A7BD81818F67020F843015F646260B8CF
-:1045E0000CC45781588099812198918121849178B8
-:1045F000FD19A208F63B210606296106860841A09E
-:1046000079C208F1D3403576220C0C8C22107E2B17
-:1046100090E612A58EFB071AEF94C214DB26816088
-:10462000EFC2228F8C77A3C98B4AA2F2F710D03F3A
-:10463000D0F895222A5F5601429741C55FA3C9CBA6
-:1046400041E56F41FDF54611BBB9B7A1F2009CB43D
-:10465000B6A260030000000000000000000000009F
-:104660001F8B080000000000000BED7D0B7854D577
-:10467000B5F03E73CE9C9949662627214F1E6112E4
-:1046800020028638BC0228F73A212140A575A055A2
-:10469000D1A21D3040C85B8A5E5ADB2F130831025D
-:1046A000DAE08F8A16EDF0AAA8A80123450B7478EA
-:1046B0008A5E6F6FB06A69B5DE888A8A3C22AD4A2D
-:1046C000EF6D7FFFB5D6DE3B73CE6402D8AFF7FE49
-:1046D000F7BFDF1F3FBFC33E7B9FBDD75EAFBDD6D9
-:1046E000DA6BEFB1DB1C4CBF96B1AFF00F9EF53625
-:1046F000C65846ECF9A89D7D2FE866AC60BD6F8575
-:104700003B1DDEEFCEDB91EC632C67CF5A650ABC14
-:10471000CFD9D0A6CC2F8C7D1F7041E57878BF7B98
-:10472000AD5202EF735E6B53E6E1D361639DD09EA1
-:1047300069BE14864F16602C93B1211399F80BB8FB
-:10474000738A191B88FF842ECE1BC98C8D632C6F36
-:10475000A52D1256E07DA87226F332B619E0CA499B
-:1047600083EFD4BFECB763DB06ED44979331A7E644
-:10477000D4BECA672C770EB331780E5EC6DFE3DF96
-:1047800057F07F5ED85A1EC24CE53C2C7BD24FC2FC
-:1047900090CCC33C5FA989E0EDD683A362F394CFAC
-:1047A0000D8DBE4CB7D6FBBD7C2EB9E363FD1EF864
-:1047B000FA716C3794B1485CFBDAB0AEB1ABE0098A
-:1047C00008682FECFDFD4C56528C74B88D4DA167D6
-:1047D000BDE6BB09F1527FD4CEC200777DC3C9725A
-:1047E0002CB3DD0A1B96D7FBFB51CC4EF428618A13
-:1047F0007612E7EB655E9C9F5AE37BB81CF0DC9079
-:104800001C28C37E1F490ED153BECF9E3F3D3B04A3
-:10481000F0942E2A0C33A0FBF9F58ADF019F7FA4C8
-:1048200044743BD0A3FA3B0D45D3A0DD9B7AE83A14
-:10483000FC6E911A6DB1C3F8B5731B0A8002AC53BC
-:10484000E7FC337877C9271AD06D3063E19434A43C
-:104850000B63274C74C0BF13C34559ED1B8F977A68
-:1048600056603F1AF612A1F9CAF779E1A34386C64A
-:104870008DC78A091E867032D6A524A2EBE0174B9D
-:104880008E6A457D8FF79F3F8F309743C01DD2B70B
-:10489000D6A34796037E4B5FB047AF057AD46E54DC
-:1048A000220E28DBF6B902489FB35BA00C74897A0C
-:1048B000746A7FC67052B9DED179FF3550EE7E4101
-:1048C000659BB0DBE1493694BB930276360ECA8015
-:1048D0008F852E5EACDDB8FF36ECAF72B783B99032
-:1048E0009E2F2EFAD635505E04FC864D6AB736E907
-:1048F000FDA1BC38A2B463F9DC1446FC114ED323ED
-:104900005B61BC73DECECC1B405E4E353A990F40E6
-:1049100059E1E9CCFC0EF051556447397E57B55D3D
-:10492000F123DA4B5FD87A2407E7F524F015F0512C
-:10493000F5B664E693F883FF4FC254AE85FA25308E
-:104940004F94FF45ACAD9CA938FE5ADDE789E1EBF9
-:1049500054A341E3F4C8D393300E7C57F7ACE2C7BD
-:1049600029D6D95808E5EAEC8BAE399BDD38BF264D
-:10497000BDC083F3BA47C7768B22F376A1CAAA8A51
-:104980006CD4CBA1BE6AC3467D6121E20DF45E21E9
-:10499000C2D5CF0AD77A3580F85D92EADCA4027ED0
-:1049A000983B903D3B01FF9C6A043556102B57A164
-:1049B0007C933E89E8B34CEDCB9554E2D7EA6D2A5F
-:1049C000F359F889D33F7C8CD33FBCD713D99A17BE
-:1049D000A3DF1283EB4949BF25A9829E5A77712232
-:1049E00078EE477A003C6D882F78AE11F07927B3C6
-:1049F000120DE8E20D30436197E6CF363B9BC7606E
-:104A0000ECD7D982803609CA3ABB83F91933B4DAB4
-:104A1000401994FFC282AFE17C18F3FB8280E71655
-:104A200085CDC1791F4660613E2D393AE1AF6D6A8F
-:104A3000F166551130A76379E1CF57E5D1F76FD013
-:104A4000F71A7C3FAAEFEF8DF28996EF8DF24AF9C3
-:104A5000FD3BD88E392FFE7D5BF9D5D6F1CBABE48B
-:104A6000F71FD0F8EE8BC36F4C9B6C1D7F5A0D7DEA
-:104A70005FEFE0F4EA4E75463641B9D9E50F684874
-:104A8000378D45F1BD9656B009DBA9921F58674096
-:104A900085EFDDDB53C7AC6266BE98F2271CCF03FF
-:104AA000D262E68B948949167E4C0DA459CAD093E4
-:104AB00071F2CA981E0A789D048FDE5F277D51D25D
-:104AC000DF49F0DEB5CF45E5BBAEE6F0DED5DF4D24
-:104AD000728630B01C28EBA1AB0CD37A04702A2C60
-:104AE0009BB1CF95904B196F7EEFB3E1FB249535C9
-:104AF000E07C921C8CF4D13D79C59BC326FCB40E9E
-:104B000002FA42395DD1391E055EEF19B4307B9E41
-:104B1000699C9641FA9C4D85FCFDED6E1C2F98A971
-:104B2000A01ED4BB0B0C77EF711CF9132DE3387367
-:104B30002B699CBCB8711CB99571E338E76C12EF16
-:104B4000C538432E36CE3DF9575BE7935B45E314FA
-:104B5000C5CF27B72A6E9C243E1F782FC6F123FEAF
-:104B6000FA9CCF90C9D6F90CAEA171AEC171C69BAB
-:104B7000E633B8266E1C378D83EF711C30A47C2C75
-:104B80000BE8EEE85E48F4FF958BEC05DD117A0248
-:104B9000FB656FBB18E9131F8C9B857A0516679020
-:104BA0005F4D49A371BE4802FABBCD74E6FA889EF8
-:104BB000A07F16081059042002FD532778B462FB29
-:104BC000ACDC267CEE2ECD9E8776C93A8F7F188886
-:104BD000CED9DDA5FAED09EC9B056DF6935D16FEC9
-:104BE000157A6F0A1BDE00E377A0B231954F82FE83
-:104BF00062A0B74E80FEC2E747C23EFD00F41BD361
-:104C0000CDF036D13C4E6A1C8F2737F075E48BB55A
-:104C1000C7EC60ECE1306F1402DC378A692C680362
-:104C2000E3CF2467F5821EDD2F3A229B881E810187
-:104C300036E073B6BE1FE04AB4033BF30FC21E85D5
-:104C4000BF0136B0656F69DD71189BBDA5CC1BB483
-:104C500004E63BA763AD7D0094CFDABB6EF3BB4D9A
-:104C6000FDCCB19FC0793BE13FECE7E690DD629F70
-:104C70007EB7D25ABE35CE5EAD51F2053DC4B8BE48
-:104C8000881DE975632687E7567C8EC16A83E875BF
-:104C90009BC1BF95F0D4DF6D67515A8FBA3258214E
-:104CA000E22383ECA2905C57E2E0BBCDEE0C0481E2
-:104CB0009EB7FD40253CC6C3DBB52F3960037BA9F9
-:104CC0006BFD1FED687F5F0AFEEF2DB3D6B3301F7B
-:104CD0004FE255F2C14D734AFA7D606A77736846B8
-:104CE000BF0F4CFCF2DDCA5996F2AD0D375BDA7F8F
-:104CF0006FD93C4BFDBCF0624BFDEDAD7758CA0B54
-:104D0000DA7E6069BF687D93A57E71E45E4B7DF5B8
-:104D1000B6B596726DFB2396F6F5BB375AEA6DFB76
-:104D2000465C8FF2B8E24D95A17DF6B9FBE4FD68D3
-:104D30005F7D6E687E6C5387BC0672F8716336F1D6
-:104D4000F7A9461F3DCFEE1EEB447BBC3E09E4199C
-:104D5000D6FA7DCA1FC2AD93518F407BD0E1079434
-:104D6000F7C361709E5E517CC4F7EA7A9D45815518
-:104D70001596D6C3D7DD6AAC5EEB82FAB17DD7ABB0
-:104D8000EBB584F55A9796B0DF734A7701DA77E18D
-:104D9000DF3918DA817DD90FF03700D78BBEEA4FA3
-:104DA000DB5865BB49EF9C546CC407372A534EA2AD
-:104DB0007EAED1B9BCD7ECCC9982FE608D1E2D6839
-:104DC000705F64BC7600260BFBC9A7792D8E0C881A
-:104DD000C92FD16F8845EE97B2D087A89F4FEF5764
-:104DE00049CFB2E8C1DC6F8FC2F10327F13DDB9DF3
-:104DF00041EBE35B8D817E1F803F77BC713A3D7F45
-:104E0000DF18ECF701E89A771AE750F9DDC6103D94
-:104E1000BB1A2BE979A2B181EA3F685C46E5938D24
-:104E2000617A7EDCD84ACF538D6D547FBA713D953F
-:104E3000CF3646E8D9E307087B94A50BFB4FD8EBA8
-:104E4000B07250F9BC98830AFFE67EAB3F1BE5FACF
-:104E5000BCFB8B02B473CF1F07C324817F289FF153
-:104E6000FCD637FD02B4DE2F8C00FDC7F6AE7725E9
-:104E700071FAB86C6C3A03FD73EF309D69307ED2E5
-:104E8000AFAE247B19DE6B8CF465C43FCB93A07F5F
-:104E90009C73D6A5E9D4C31F8FFE4731C61F6E147D
-:104EA000FA30E9A0DAC0E9B6D98F7433E18FDB6557
-:104EB0002F087D1E8747B2E5727AE3F34C86C467FC
-:104EC000672EC601D629C11136E083F31D0E9AD78D
-:104ED000F93DC91186DF627064D2C5F0C6E1A8DE73
-:104EE000E632CCFAA1B63DD5B0EA8B1CC3AC2FCECE
-:104EF0001FDDEC45B95F926D333E188BFC1110FC41
-:104F0000C1F94EF65FDB9E67B82DFD58CBE7DB9409
-:104F1000E9E80781724FF94E02FF403E9764EBC605
-:104F20000720DFA7B60D49C171C18F33709CD38DA7
-:104F300086C1C7CD36CC7C59B32C89DA4BF8FAEA56
-:104F4000F7EF0D1F5A06EF3B19A1FEAB215FDFCF34
-:104F500066DA9F289EC3F6D8BFC075C701FF7F459C
-:104F6000F1008DCAB2DFFA7635ECB80ADF6FB78C84
-:104F700007DFF9A40F8DEB55DF74D7D849535CA038
-:104F80000EC720FFC849740E418F29D0DF39CDDD0F
-:104F9000AAC038D36D3EAAAF17FC58EBECD243F051
-:104FA000EA4C07A7475FE39C6A3CEAD3407F543A48
-:104FB000C12383712ADB4794A17E3CD3B122330401
-:104FC0007C5BAD9EBF2B98E0FB569BC2E189D8BBB2
-:104FD000BB4CF3917114C6A05F670C7EE4F493A6FA
-:104FE00072BCBE96CF07B05FE08FBAEDC7CAAF0103
-:104FF000F8EB767FA6231CD36DA1076C19B1F92BB2
-:10500000387FE8A76ADB7B3ACEEF637BB8E0EE8BB4
-:10501000E8A9DE70BAB3296E27E10BB34EB463E69C
-:10502000F7C4157D37BD0DA2F9C93FDBD92A8083AE
-:10503000FD055A41BD5DD456B0A017F135BFA39A06
-:10504000E28B9FD8A4DDD4568CFC7186D9A6E3FCF4
-:10505000CEB0D7BD634DF8EBB071BB9FB5723B26A8
-:105060000CFF213C60CF5AEC9A45EBADE5856C76A0
-:1050700026EA8D85EBEC2C02285A8C7691E40F9869
-:10508000F7161BB77717B18616B4E73407F70FE6A4
-:105090001B4C1B0070D5FEE2B162B4FB7F69B311FB
-:1050A0007D649C61711A87BB2A3DA207A0FEFD8E1C
-:1050B000B1375E83DCE788B4E0BACC52987F2BEB43
-:1050C0008DCFDB5BADF05D0AFE7878195B6E8143B6
-:1050D000F62BE150B729814802BE7B45F29DD023D3
-:1050E00069AAD5CECF8A2BBF6313F14B95A948E7A8
-:1050F0003386336C4BA17A7F14E3233B1DFE1540AE
-:10510000DF3B6DC12ED4CF6017143153BB3B6D21F3
-:105110007A7F5A796D21DAA74C8B16A17F0F6B8AA3
-:1051200086FCA00B7E5093BC45188FF530583F414C
-:105130002E1D081FF4D3E2A99CC98A30FE0A720A08
-:10514000FDDDE72D3FAA40D9E5EE60D89F23DB1AAD
-:105150005F76F9ACE57AFC07D26138A3384EF2707D
-:105160006B3D2C580CF9CDE3B7BEFFF71E3C4589CB
-:105170006FBDC4D2F074BAA32A8CCF266AA7CD76AD
-:10518000739D93C34F7E39B45F2AECF93AE60B5313
-:105190009C389BF3C1D219368267A9C7E70F43BD7C
-:1051A000A20518CA1FC6AACDEB58FD0510B97EA6E8
-:1051B000B2D6AD235FD65FD05804F47D912DE45173
-:1051C000C723FE0264E73A01595F01C89A7BBAC55A
-:1051D000EE6503D3C4FA3AD030CBEB40A4F3F81811
-:1051E0009DA55EB00BBD08FA224BCD403DD85D4E6B
-:1051F0007E09EB223D21DBE9B17603118EBEDAB9DF
-:1052000062EDF212F557FB8B67768501FF55CF3DB6
-:10521000E805E2B34FB4B64C3FBCAFD9BAD28B7CF1
-:10522000FCB116F6E2BC3F89A8D313F1F38DAA2294
-:10523000FCB1805B417F58D0E9D453ABBF8578FF88
-:1052400062ABDDC026F5DB1C510710B1AE6331E760
-:10525000A76D8EF778F99ECF909EF5BBADF256F50F
-:10526000C4839918EF040C71BF9145C97EAEDBF27F
-:105270006139DA23F5AC9BF444FC7738FE85345A67
-:10528000BFE6E929BDEBE5FE4BBDE0FBFA8ED59FFD
-:10529000A95E2C5BE5BB52F823D3544F3AC5952643
-:1052A000B0094837890716E1F6F08A271F2E7A0FD2
-:1052B000E038BDE59FBD8A256EC4F5C3F9F6DB7FF6
-:1052C000F692AF6FBD7E56F8F3B1EF22F49D6F37C3
-:1052D000B7DFD91EFEACB147BDE82FD56CB4FB419A
-:1052E0003259CD339B7FFE28F2F5EF1C1467A87E60
-:1052F000E6F05B5743B97A873D7D269F865BC98C74
-:10530000D1A31EFE5F362686FFAAE70FEBBE51FC37
-:10531000FD8FD26274A8DEB15F67A37AE3ADB47D7E
-:10532000BFDEE54E408FF6F7CAD1DE5EF1E4973A74
-:10533000CAD527FB149695D7FBFBCA8D87C99E4318
-:105340003C11FD047D7AE8D58B4ED16FBD348EDAE9
-:1053500019B87EF545A791B8F665101F3FFB12C638
-:10536000EF7FEFF0E3FC2B9FFDBE17E7F191D6C076
-:10537000F9F9B195990118B7D21ECE34E8C9DF57B3
-:105380003E7E27F1D9A2637766523C8005726CB4E9
-:10539000868673707E0B36DC40F35BC842C46F9523
-:1053A0008FA9C108C6B334367D470279784DC8C38A
-:1053B000479B1CB8F6B08F50C1A27FF8BA4AFB04D5
-:1053C0008CDD41F1863BE53E045B42E5CF9D9C4E82
-:1053D0009B559B8C6F382D7CBAE59E4EA4CFA9417E
-:1053E000812C8C4F021EC2025F0AEA1DF5D8D42C14
-:1053F0004E1FE6D38AC577A0174BF13DB6EFB40731
-:105400005C4596EFC43AC6C75F2AC607B893D01E5C
-:10541000FB2813EC9B04F3FB52957A19EC0D137FD8
-:1054200099E49ACBF9967BB95C4B398FCC9A8EF57F
-:105430007F7A83CB0F7E87EB3AC015CDA2FAFDDFD2
-:1054400051480F385834913C6FB10B79B6D6CBFD2B
-:1054500049805BC3F529C627D07F1AE19FECB4854C
-:10546000EBE03B935EAEC7F1A89D1E7B6F5AD7174A
-:1054700009F97F5915FBA342FED9062EF77DDBBD46
-:1054800061EE1FD8233F7F14E515E413D7999A677F
-:10549000EC419CF7A7DB0FBE750BF0F5A7ED524E64
-:1054A000AD7A335E4E2B778E6789E4F453B79F2530
-:1054B0009453789F504EDD5DC4C7FFD97A53E2ED17
-:1054C0006C9CDE947AB02FFCC5EBC135AA2FA11ECF
-:1054D00084BF3758716FBE93FC26F9ACEAE9DAC194
-:1054E000143792FC28F9AD871F25BFC5CFD38AB7E3
-:1054F000F8FA1785BE9174B62F67610FC64BF7AAED
-:10550000E45F9F03985A80BEE7B6E74530EEBCD211
-:10551000C5E317E78C6E6F1A3C57A6F2727786DEEA
-:1055200082FA41BEEF76F1F8F6B960B737D5E457A5
-:10553000BCB747F5FAA0BE2BC2A627F23740F3123C
-:105540001C5DACAF7A1E0F9EAABA7397A1DFDEA6D0
-:10555000D27E7645D34D5EDC073EB767C84F503FDD
-:105560002D78050C4C80F71CDA812938BD808679AE
-:1055700009B70B7A7FCCC20F4D86F9DDBE87FB0BD6
-:10558000156BE2EC7BF7521DF50DD8F727AC716D6A
-:10559000CE3755A29FCA0DD6FA2AB686E85615C749
-:1055A0004721E1074ED0041F8D66A3851FC6E31770
-:1055B000425F4D550B7F8276C6B9A33CAE787E8F95
-:1055C0004AF83FBF5D8960DC87E2BB9390FEDD3A1D
-:1055D00033F9CBA791DFF4BEE5F8F40B7F28BE1BAF
-:1055E0009AD4EC7ABBE8A7F03CBDEB7705BFC4F2D8
-:1055F0002F7E9BFB36EBDDBE74DF9F69FFF8DC3E40
-:1056000007C1716EDFCBB97763F925871FE13CB71E
-:10561000DC41FB67E17D9EC830AC1F04F4C67573A6
-:10562000EF97455DB4EE34139DE66B7CBFE3FC9EC3
-:10563000FF7857C1FC833D0E1FCEA37E1FCF0BA961
-:105640007FC9457197737BBF2C0EB9FF7EF3A9D339
-:105650005988F8CFC3E6EC447E4DE5FB00F5BF9CCE
-:10566000B4B909F7C33BF6EBB8BF52FAABBF16A10A
-:105670007E39B793DB0967ED5D8FE33E68AD367425
-:10568000B91DE51E6DB6FE6077DA174C091726C204
-:105690000BC7C339C003CE0BF052897AB12F7C34CB
-:1056A0006BDCDFFCEF878FCF6EC3F16BF64C20B95C
-:1056B00089E14509F0F79E8853A1F9F3F7FBBE2C69
-:1056C00042BBE7D3F6265AC72F35EFCDFFE3E6AD51
-:1056D000442F67DE07FE9BF3FF748DAF4BF172D052
-:1056E0009BCF7F7117959FF5F809DECB94FF13FFD1
-:1056F000D3E8BE13E8EEBD34DD15FB7FD7795F8AB2
-:10570000EEAF08BA7B0CCC2B38B7F7AF142F97F35A
-:10571000BFD4BC7DFF8FCE5BDA3FAB6CFEB67C683E
-:10572000BF86453B7D00E7CAE1B3DB30CC046E4267
-:1057300030913D12B473FF4855781C860DE27121FB
-:1057400026FC094A01F3611C6521D9759ABB85ECD9
-:105750004CA6F93B03808F5523E7FB2957838D39EE
-:105760001EC2F2C0C97E8A6FC6F955CD0A0B2860E9
-:10577000EF6923BF7114ED7CFB705BD45144CFF70C
-:10578000F0798F8863D90DDDE24FB8E3FC0197CF44
-:105790005AEF10FD39D998B67CCC53706B4604C6CD
-:1057A0007797B4D17CDCC3186B33ED033A98E97B6F
-:1057B000E8AF1003B026FBF1EBE2AFA9077F633A35
-:1057C0000388BF11368A6B51521FE1C31F59457EB2
-:1057D00026F71F63F86CE9443C6A0CFC3F3E3FF23D
-:1057E0001B99F01735D18536DC167059DB09BFE8F7
-:1057F00092F4E1F4C8AD11F45962A187C47F02BAF2
-:1058000058E821F1FB75E9124F8F78BC7FC7CEE3D2
-:105810006DF174B2E47764703F240A7EC8CBDB3745
-:1058200053BCE3CC53EF7D0BDB57FF52654EE8E7EB
-:10583000EC760F8BA2FC6A111DFDA9AA0E35619CA6
-:1058400057DAE5D5CF7968BCAA9D8EC84CF8BE6AF8
-:10585000D7FB4564372DEF3E3200E3024F299C7E93
-:10586000E1AE22DCB7ABD2B87F10DFDF063B8F0B97
-:105870009C7E31790EC61F946D3C5FB1AAFD26BB9C
-:10588000C3C46FFFCBCEF35EA11DC973F84985D6A3
-:105890009BDEF071BFE0F4930A876FB73D82798F8A
-:1058A00055DB36EA21F42BB77D4671ECD2E79EF149
-:1058B0007691BFA85AFDE76D2AD1139E44BF783F69
-:1058C000B6AEA396FC84BA76E127C6F951D5CFEDE2
-:1058D000DD1506D4543FFF8417E32FA73AB77AC9E2
-:1058E0003FDDC6FD4FCDAD25F64F2FE597B6DF9BCB
-:1058F000D02F3D85FF007F62BF3DCE9FDFD6EFF208
-:10590000F62F9FF9FC718C939EDEF9E9E30877CDC1
-:10591000FFFEE3E368DFB37D2E632BCCB7FEA93730
-:1059200029DE24BF7B5BC8E9D9412C9C03EDCEFE68
-:10593000CE41F92367F77E948BFEDCD91D7FCE44E0
-:10594000BF7EE9DEA95938EFA52F9466B104F22E87
-:105950009FC89791CB8813C6D3E160C741F243CE6D
-:105960001C7790DFD7135F68AFE5F11A9F882B6C27
-:105970004F1C8795FE705DC7FBE53C3E26FCE24B65
-:10598000C511DE003A5E7519F4DA2EE24471F43A7C
-:1059900083FF00BA7C1947AFCF59E86739B80FD9F0
-:1059A000D1AFCF3842F432F024E3BB47EC019B8EF9
-:1059B00072B033B9874E33914ECF7C9E8BF1F08F0E
-:1059C000EDDD64F774EF7518E8DF57EDFD2DC9C5FF
-:1059D000D9178E51FC948938EB59D6F3C7E3628A04
-:1059E00098DF160F8F3F087C637CC2E7A5F7220E75
-:1059F000C1F955C627FA8A4B4CD045DE93883BD770
-:105A00006E795B6771711E6522D2E93D4B7C5CCE7D
-:105A10003BBE3F03F130C11C5F4B1CF7917E738C82
-:105A20004E3CAE26E36767378AB81BBC1F3806FDBD
-:105A3000411EC7A88F28BF6509E450C6D7C6E871C4
-:105A40007218B9BCB8DAA5E0FD5BF1314CE7EB8325
-:105A5000C4CBE9BF24D6C3DFD4B95C4FB78566EAAF
-:105A6000A6FDECEF897D16892F09EF69918777FAFA
-:105A70002995E2412DED07499FC6CB735D1FE720B5
-:105A80006ED379BCB56EF7FE22D43BA70FBC487C21
-:105A900057B7FD3D3D0CFD1CD9F6BCCEED49CEE718
-:105AA000A8A723263D7DFAD9FD453CEEC7F36EE35A
-:105AB000FBAF16FDD7EFB1F65FBFFD334BFFD5E16E
-:105AC00076DAFFBAD438A7B4C04D38DF539D768656
-:105AD000FAEE54BB3A3D92C80ED4ED967DD0966353
-:105AE0003AAD57E35E4FA2FCDCA5C7A6BF9D82FB83
-:105AF00074206668FF763471BEEAF8716000D2A542
-:105B0000E3D82D2AAE1BBB108F263BB8F88D8652EA
-:105B10000FC86BF13BC171C856F17A60C2719B0529
-:105B20006E18270BF57133F483F9F4983F84FBA3C7
-:105B3000AAB77C3AC2A31A36C39570FDE4FDD9DD3D
-:105B4000418676B9DDB0E62B67CF1671B4A8356F04
-:105B50003D5B67C3711F9CD992FCB81FB064446061
-:105B6000F461CCAB5F904D71E29C6FF3EFCE18EE19
-:105B7000B0EDAAD8BE6DF205E81FF3606C91B57365
-:105B8000E1BB64AD5DC17D007832A4CB9DB6D0266B
-:105B90003D03DBE9CC07AAF1715DD128FF429C7B74
-:105BA00091FDC9767DED07CB7348AA807F88D80F19
-:105BB0001EC4BA14DC0FDEE0E1E79106BBD3E9BCFA
-:105BC000D16661B7F970DF15DB3558D7ED4B9E47CD
-:105BD0006AB596D34B4BEE18EC073F58BFAB540356
-:105BE0007D907E53C98E0106EE4BAF2BC5BCFBF4F6
-:105BF000274A46E740798EA3A88CEAFFB564742E45
-:105C000094BFDF3AA98CEAAB15CA0BDCAB77978659
-:105C1000DD31F9CC00E316F32D406E0FA0DC9E09B8
-:105C20009E6EC1DADA1BBED0F9791816C4F90F9A44
-:105C3000C8E73FD0FDCE0E9CEF605B5713F2DFCF7D
-:105C4000F67E998AED7CCCA0791AACD9C07D7978A2
-:105C500035F1AB8BE4FFC4E7C1487E7F2E39F41BDE
-:105C600084E3DEF9C31F2E479D5AE3273E8ADF27D0
-:105C700066463AD1A542D005E1749AF2902BF12400
-:105C800002E99B3203C751C235EA57577E7D784EF1
-:105C90004A7E11E7C04CE7A43E41381F490ED1337C
-:105CA000FE9CD4013DF829F253CEC20BB908BF3C8B
-:105CB000FF54BAC84D7181F37B58C491407EE473A0
-:105CC0005323CBD086F65DFFA623F4671C37FF571E
-:105CD000BE9D47A1BFAB2A743FA6AE5DB56C5C8686
-:105CE0003696F109A13D21E8968DB444F9BA8BF1BD
-:105CF00073390E25807EE3B9EF1BA47F0756CC24B1
-:105D0000FFE25C725E3BE64F9CBB9BE701C00AAFC3
-:105D1000A01C0CDA931245FF07F8F88B383EFEC240
-:105D2000BACE58C73DF7956F7717F56788FEC0D094
-:105D3000C944B9E17FE7546E679F6BF4111C60168C
-:105D4000EEC7F5F472C7CB7658CFE901DEFB3B4CCA
-:105D500078CF75F449BF3C07A71F3DE3E9B7D0D919
-:105D6000908B725C156C2F47D7F4A385771523535E
-:105D7000BFA987AEC0F635733A8FF09CA18602DCCE
-:105D800067EB4D5F7E1E2B73CFBC263BC62B903E30
-:105D9000BEDE74BC6A993F43EB67A1EB5884FFAA4F
-:105DA0003D9FD9107E49CF87459E7FFCF7FFE85085
-:105DB000C4B8354D768C93ECD6C99E8D6F371D0FC8
-:105DC000558D8F958B9CC5346E968DC73B7AB7E702
-:105DD000EB5FAC5F279DCBEA8B1F8B0CDE1FE0FFD8
-:105DE0001B66FC7FAB6FFCCFC276807F7A7E0DFC9A
-:105DF000DF84EDFBC2BFB4A3AB855EA8C67D14E013
-:105E0000A30F03B33387C2F8E5AA9BE460F156956C
-:105E1000E40FDACFCCC98CE991C5931AF6E37C176D
-:105E20003FA610BF568873A69F8ABCFEF87CA88543
-:105E300073C2B4BFD32B2F2A12E7D7C5E5BBD7C790
-:105E4000F87630CF53E3E7B6542117A58B0A53D029
-:105E50001EDA67F7FD2BD9D9AFA86C5302FC6F444B
-:105E60002633D1755083CD9227CB2A522DFD962D06
-:105E70002AA47DEF251EDF45FDAAC1CBACEB765EE3
-:105E8000D87ACE6848ABF59CD1B0B6FE96F657AC42
-:105E9000CFB7D48F888CB4D45FB96D8CA53CAAFDE4
-:105EA0006A4BFBAB764FB1944747BF61693FF6E859
-:105EB0006C4B797CE72D96F6138ECFB7D44FEAAAB8
-:105EC000B2D45FF3F1124BF91FBA7F68B5536C8CF3
-:105ED000F4234B52485F1E6A9C988BF9D86C9C52F5
-:105EE00086F82C15F98487EED06D86179F0536034A
-:105EF000F4D681053369DD3F744766C047CFE200C1
-:105F0000FA354C9D3C2E51BEE6546352AE392FAA51
-:105F1000D469B7E8B7A986B5BCCB21F6FD0673BE38
-:105F2000F9659C7CD91B2647C13264FD170FCDC291
-:105F3000F140CEF6093DB7EFB2F45C6643319641CD
-:105F4000CE0E25923326D6D912C14FF00CE8981FF9
-:105F500059E6A1F538802F7DF43EAC81BC4C71FA36
-:105F6000071EC679D9FCE9C88465738287787F6289
-:105F70005D66C36D5F675D96729E6D13F96B693CDC
-:105F80007FED91050529CC84DF3F386CC28E6EE32E
-:105F90004FE3A8AB276F35DFFCFEE324CD942FA79A
-:105FA0002C9A49F922D97DE8453D3B7FC616D0C7DA
-:105FB0007A8E8F9EF27DCB1C5BC23CB06EA147A552
-:105FC000BD3522666F75233DCE64BFFE10E629D530
-:105FD000CDED267B2BDBD676C7119CD7ABAA885F8D
-:105FE000FAF8F92A61272F98F1C01D47705FFA5F10
-:105FF00086917E92E36C689C3E43339D231FD88735
-:10600000DF74A593C3F378E3F0191594B76DF0F33B
-:10601000A2A2FFDC706D39DACD8345BEE943B6C478
-:10602000F92E6ED14F16921CE135DC24276716BE7F
-:10603000E3D5601E8FC2EAE5C47DDBAB3A8BB91DA8
-:1060400016F0E339D4DCE8AD0F61FBDC6C8DF25D5A
-:10605000E3C7CF9A1B6ACD83F935A7D9FC6E2A779F
-:106060002BD8DEF123C6FA41FBE6FFAD123CCD078B
-:106070002651FE87C3DDC0703F55CEEB60DAA384A6
-:106080001FB52399D64126F6C565BCF5F3EC8A4EBB
-:10609000B4373E5F67A7F13E87391AD0FFE71D2A64
-:1060A000EDBB1E494B8ADAA0ACB67A68FDCE45DB63
-:1060B00013DA2FECF0447C7931BC68EB27D37918E4
-:1060C000C7403EFFE63477C49D47F34EC7794B384F
-:1060D000E5BC07F5E1679608B873AEE839A7C1904B
-:1060E0008F5543A37E17A4F2739891C689825ED61A
-:1060F000F9B464CFBEFE663C3FF486CA3035C4D7DF
-:10610000D546F35F08F3C7786F3C7ECFF8F2BEB098
-:10611000A9046709C2A9AE2FA779503BF8AEF6676C
-:106120000A7B340FF930349DE8DADF46E7027BD989
-:10613000074E2E5F339C3C2F57CF2E98B1A51F3EA4
-:1061400087925C7CD3D9E7BA1F74727D44CFAF715C
-:10615000BF00ADFF521FA9019BB073B95EEAB19FAA
-:10616000F4D0779D19B1B29AF2A322ECB76FFB6C11
-:10617000C77E1DED333723FB59EACDBEEC33B4CBDC
-:1061800090DFA45DB6386E9E30BF1A31BF9A44F3DB
-:10619000EBA56F6F699076CD12E745ECCA0C3DB167
-:1061A0003E7A52D0A1DED019C59B688D02BDB3D80E
-:1061B00046E78D99167199CF976F704ABB6ECF7E67
-:1061C0001DF10CF3463C6783FF5C4E7AC79E302F6F
-:1061D000FC52FE48FEEAC29D47B13FB07311FAF38C
-:1061E0006DBE94B48BD817F665AFBACC787DC02954
-:1061F000F2B963787C50E0F1C184784C073CDA2C2A
-:10620000F6E1AE021FE1F1A7CE8BD88767BEFD6E27
-:1062100031AE476705BEEA7AFC5CAE9FFBC32285C0
-:10622000F1AA5ACC5F76F232EE07ADC0263998DF7C
-:106230001C7C02FBAFDF6D3D77F863278F9331370E
-:106240003F372BFBCB14FA1EFCEA7FFCD0477AFFCA
-:106250009F703E31FFBAAB18FDAB152F5C91827673
-:1062600059D9AE9B0D7C9E4F1F4AEBD9995D8E008C
-:10627000C279268DE7EB9DD935E108C61F3E6D3CFE
-:106280009A6FD6F7679E3D566C877ECEEC3C56AC37
-:10629000517E70C46217D67EF59B623C8725F3AAB7
-:1062A0007BF8C5C9D789752E1ED7C8C8D45B305FA7
-:1062B000FC42522AE1EBC14CDBFD89E235A83E6984
-:1062C000DFDEA3D33EE59211BE156E8CD7E41994A0
-:1062D00087BB4209E42CC07D96594E3FEE03A4E7EC
-:1062E000B3E1792988C21073033E1D87DAE8B869E3
-:1062F00052A7B11FCD2319C7D14AB9BEEDBE41A7E0
-:10630000BCB164CDF7F05C2867CFD168BD93711D37
-:1063100047323F972CE33A3DF0BC62A77568495E6F
-:10632000A8AD04BE5B32298DBEF3CE7A8BF8E59C16
-:10633000CF16B6E37CB46E8AEFFCA47178C650C069
-:10634000A391639B4136CD5F005BA6FC7FAFC6C2C5
-:106350002960DFAC06FE1F0AFCDFD1E8A4F62D6041
-:106360001F1A69744F42EC9E0F93DCEC6C34A8DD6D
-:10637000CF1BB3E9BB071A7DF4ECB12318FF8ECA1B
-:1063800009F4EB7FD6F3BE467E9F882CFF711CD8A4
-:106390006940EFF4094055C04BBA387F2EEB1F6DB2
-:1063A0007C6548D950810CC067FF1A63E3AA8BC093
-:1063B0009BEE88A4E211E32B5D2C5C3611F3FCBA52
-:1063C000EF2F4FC5F311F794958D003CE2FEF6D503
-:1063D000402AD703CD783E35A7C6D78471BF9CDD50
-:1063E0004A3BAE5F39BBD796E03E02B4A37383B29B
-:1063F000DF0C17D773C9071F51F247E1E602DF9799
-:10640000677B932389CE978E73713DE777F1FDC14A
-:10641000D5625FBD7B969BF462F24117F14BCE9E35
-:106420002B697FCFDDC7BE727C3FC907FF4C71600F
-:10643000B7D2B61FF729D9026E7F4A7EEAEB3B6CD2
-:10644000AF5F46FB737E8DE2C260F6D2FCCECC1A03
-:1064500048F8C6F6663D7E4E4F6C9705049E56DAA8
-:1064600013C7E935C6C719D7D94DFB99786F13E221
-:106470003BE78D3605FDF5330ACFC7E80FF8D8099D
-:10648000E59CC96D74AFD373CE50B90BBEFB93714D
-:10649000BC602580E32AFC7D2E7E27F1A116E94E03
-:1064A000D427397BDEE3E77C6C5D3AE6BF2DBAF793
-:1064B000798A3FAA7A308F9757AEC4F8648637B886
-:1064C00011F984859F2F3B047CF2A038B78C6F5064
-:1064D000EFAD768972B8BD39007CB2DACECB8BEEE7
-:1064E0007D8EF866B53DB818CF3D63B919FA5F9D4A
-:1064F000DA9E6D83B2BBE999E6A383B02CDB3FD370
-:106500001C9E0C76A84BEAE7600EE2BDA76C4079B2
-:1065100094A9ACF13273F2A79C5FEDC13F1F190043
-:10652000FC52B787DF73D383B7DD6B155C8F7EDEDC
-:1065300078D4D7AC093991FA03D6F92BB219F929D5
-:106540007A4489E42B78DF476BA6395FE5BBC98ABB
-:10655000885BC0F7E6F863DCB9363A2A83EB73331D
-:10656000CF0B89A7EB9B49256D4919781E35B44A95
-:10657000453DF88CDDA0BCFA2E8DF4F6699957DF05
-:1065800060277BB0469C73B52F0FAD1A817271AB3B
-:10659000E6C7F842755E5B09DA43D52FE6F99B58EA
-:1065A0002C4FB73AB53D738C3B96A72BCB2B445C55
-:1065B0002A2BB52135B510F763D6E6E27E491D6B6F
-:1065C000BBED8708EF6B2A437EFF64FFA414BC7702
-:1065D000A816CA1807ABED38A687A0DDD549FCBEC2
-:1065E0009BBA0EE01B37BF872650C0D846CD484225
-:1065F0003DFFF340C348348937BB7E5DE6FA07C6EA
-:106600009EC80F1848E75FDD7BBCD98965DD18C1DE
-:106610004663F9DF9A91CFAA47DB28CF9285FFED39
-:106620005060A8D8EF8572AB6BD05473DC3B479CAD
-:1066300033ACDFE0A6F360B02E6F42FEAE5B6F0BB3
-:10664000E3FE99CDD949E7807EE562823ED6F353D9
-:10665000EB14AE0FC30B783C75E98CB46FD0F9A97D
-:1066600095F946F82271DDCA0B49744E4A96AF4E31
-:10667000F251FF955A98F6912A2F78E97CD5DF6F71
-:106680003CA7E5BC56EFF1DC048F1CAF26361ED1CB
-:10669000F5E098571F1A0A745BBAC36E7398F86EC8
-:1066A000E90EB13FEF0A64613F193AC733437F10E7
-:1066B000788DEEB8E1E5B0960DFA5FCA77F87C7395
-:1066C000D964A45BAC9E59E53F80FEF87D49B2FCDD
-:1066D0001FCD650313B44F8A6B9F2FFB575762FF83
-:1066E000F1F06424C5CA4E68AFFDD5D15346F8D643
-:1066F000DAE2FA4B9365F74A1C5FF255EBBDE98786
-:10670000C3C057F7A5B695A0FEEF5EC07C788F1684
-:10671000F2ABDFA46F5B5D5CAE2B2FE45BE81DC3C7
-:106720007B81852E1F35665BF63D17CD5D4AFBB339
-:10673000AD2E412F16E6E76C360C6011533CE8FF96
-:10674000C3F1B7C271751F70FCE37F311C3ECB787B
-:106750003138865AE0FB5BE1D87463C137F2A0C9D7
-:10676000834AD8998FEBC28F795E9C9A5AE66BC2A6
-:106770007D991F6B14D71FC678BE4BBEC68E6A6349
-:10678000507EDA02180761CBB9BD02EF5BED63689A
-:106790001D227F61C81EC73CCCDBC8AF0C2CC627AE
-:1067A0001B5848FB3E729F948938A1DCE71966B0FC
-:1067B00012BCF7EF44D23C5AA7F28373AB31AEAEB2
-:1067C0007AC625E17AF8A02D12C6F1C20FF0F13297
-:1067D0006C917627DA4BDEA106AE77195EAEFFD854
-:1067E000AA425AFF36D9F247DE0170AC544A925E93
-:1067F000413CA7E6537C1CDFE33D3B9BC4BAA5A606
-:10680000FA0D5CA73689756B85D0EFF27D725A70F0
-:106810001EDA113F59356DAA7312EAA1406B3F5839
-:106820006FEE5F356D65F6245C6F7CF94E585FEE58
-:106830004F9AB6D20993D9D4E4EB6FA4C6CAC3FE6B
-:106840000AAB35E989692B03A0779ADD4BAAD0CE34
-:1068500081FAC3E8273E9126F50EAFCF977A0AF565
-:1068600012E831B5A9A71C46BD94DFA377A691DE37
-:10687000D9F2B84AE5A5301EDA31308F30DE0FD6B6
-:106880003D4C23FFC805B02441D935229FF6CF6087
-:10689000DE2C09FDFF11BC5EEE77E8C36CB4DF812E
-:1068A000ED118FAE1CDE5E9FC5CF4BEB1E37F96D31
-:1068B00072FF4415FB7749224F453166911FEC5C0E
-:1068C000336609FA51CEA1D6FD693D2E9F458DCF85
-:1068D0006F7147C9EE6A4B12F1EB7E2C9BEE4D10A7
-:1068E000EFC1521E83CFCC9B9B4BE83E3D0F333014
-:1068F0009F3A3B1465667B493E1DB08EFA4C72E3AD
-:1069000070B340A27C8A85C9DC1E765FD0B89FA890
-:10691000807D83EBA847D8E1C23EB2CB7B8EE2D626
-:106920005D692FD9C57D7A4B674CC9C27349AA3BB3
-:10693000E0443B67BF3186F66954E6BFBEC464EFEE
-:10694000344767507C5233020CED9C57859DA31A47
-:106950007E66B6735A1AC10187B56A737101DD5F2D
-:10696000F3A82BEA1C82F47DD0E647BD71704C552C
-:1069700058C1F8E4324672BAB938730AEE336CD4AF
-:106980008229B7A2BCBC01E3F938DDF83EF70A055D
-:10699000E3E99F3B8329A80FEE4B65163FEAFA64B3
-:1069A000EE8F6C4DE2FA47FA092D004F14E0D02E1D
-:1069B0008CA4FB7C460BBB549F5B46F1324C03C25C
-:1069C000F8A78335840D77ECBE3A47B6CD92FFA881
-:1069D0005D28A278E2D6243E8E1CF71E71DFA02C23
-:1069E0003B59038F1B038F27F2DF6A059C0EB0878C
-:1069F0007C649FC4EDFFF7B68FC85E91F4E9B15394
-:106A0000147E2EB42FFBA8FE82CDA26763E7D97552
-:106A1000D2CB67C57D01320FC42DF4594B76A8ED5A
-:106A20009ABCD8FD009AC8075923EE0560D95AB719
-:106A3000F91C7E32C663A0BE59E48524C79DEB775E
-:106A4000B99792BFE01AAE59CE81395988BE73F812
-:106A5000ACEFB5ECF8FB02C23D796094B7A8B14742
-:106A600014BA1C80DBBB03441ED699E47729DE08E8
-:106A7000F6EE4127ED4BF073A2321EF675EDE357AB
-:106A8000D1AE22BF70FA68EC7711AE4718CF66C15D
-:106A90001CBEE9D8CE286F28C9DFC5F89D63646F96
-:106AA000A952CF859F6F463F2AC36CDF99ECB52B67
-:106AB000573FDFDC5C487E079517DDDB467A70A523
-:106AC0004B96575319D6AB28FA3D6C97C387FC04F5
-:106AD000DF07506ED88D05642FABF9E0D202DC657C
-:106AE00078FF21EE0FEC726C427B16FCDAF92E5324
-:106AF0009CEC8CE7782E2B4CD85FD8D25FEED7EB8E
-:106B00000FC6EFC03C23595FE65D1F55F9773EFC89
-:106B10008E0DEC7C370CFD3FF88283EE2591F72C2F
-:106B2000C7F3EB9464EEBFA3DE30E773EA732B0286
-:106B3000C89C523E1DD949963C7029AFDA85E124A4
-:106B40009FF2BB5793F8FEB1A60528AEA65D282498
-:106B5000F9DF2AE8DAD2685C629CB43EC61943FDCC
-:106B6000F43D4EB1D0134CEC8F6986F91E99BEE40A
-:106B7000357E3F305EBFC9A7D46FFB44FFF392ADB3
-:106B8000F1E5AAF5ED4790857E680B55248FC7BCCB
-:106B9000AF77BCB814D7D8A245286F77F67E5F8749
-:106BA00093FBBE8813146CBBE300B26B4372684363
-:106BB0001294AB92C53E4036AC6B2AAE5B3C6FE99B
-:106BC00011ACC7FC8690EFE1A9A8A7669553FCFA23
-:106BD000B9E4E06FF0BB7B671753AC40C2BDBA911C
-:106BE000E7DB497DE9467C417B87D6C0E39EEE40EA
-:106BF00014ED8B0792DF9CAA211F6A5C0E96AD3EB6
-:106C0000B012E3224ECD4F7CE574DB7CB8BE3BC1B5
-:106C1000BFC375AFC96DA378D20ABC07380FCF1BAD
-:106C2000CC34505E9778F2B3D845F4A3762153E87C
-:106C30005FEBBD3A7FFF71D2E9FB5EF7F71C9C1456
-:106C4000C5FE343FA3FC1944C2FB26BD2AD7F5F884
-:106C5000EFE2FB97F894F8756821C2AB8E76430299
-:106C6000B89E4CB6EEDB6649FD99FA564114DED665
-:106C70002A5D5EB44F402F3E897C5237AAFBD78AEB
-:106C80008FF46926B767C2F2BE02CBFD48322EAF41
-:106C9000BAB95D23E15FF2CA834EF3BE533CBCF147
-:106CA000EBA5BBD09A9FE11C9814775F70131F4728
-:106CB0000B12DFD827079C28274DC61803ED9566D1
-:106CC000CDF7DB00E595D8C96E063BDC32BE7CDE35
-:106CD00027EE073E26ECA8F87A8FB84F39FEFD67FD
-:106CE000C27EB86FFFCDA487FBA21F1EA846FA7A0A
-:106CF000F29981E773EC025EEF25FAED8B8FEEDF00
-:106D0000CFE3BADA4467045DACF8F1547B3080E736
-:106D1000C9D4D18CEC5D75101F1F6869605CD83BCD
-:106D20002E8D0D37ADB3F70E9DCDEF77CE30E87CCD
-:106D30009FEAB10513D999124F8792E53D159C6FD3
-:106D4000B225DF0CFB3DDD836EE29BEE447C7328B5
-:106D500099EB2B84C34CCF7B87E66725A24F4C2F42
-:106D600072BEBA145F7488FB126B1137E0DFD488EF
-:106D7000F3F6A7C53D41F393C57D4106B78BE5FD0D
-:106D8000171D5A2019EDAAF93DFBD4013A9752E399
-:106D90000AA44C42BE3CC6EDDE8F4AF8BD651FD941
-:106DA000032988E78F8EA94A13EDF3F3BC40996756
-:106DB000F591DDB77A24D4DFFE5335D044D5567B28
-:106DC000EE340B8CFD17B46F77ABB47F94F7C03CF7
-:106DD0007514B4AF00430FF9687EA93B8CEB6FC705
-:106DE000EF1BDE453D74FBE30EDF7218E7D0FAB10E
-:106DF0005F60F9E41A8FCF4171B27C05EF155FBA7D
-:106E000036CFA0FDA3654CD81943CB4B8732F6147F
-:106E1000FE53C69D9D74CFB8A80FB694C1FC4666BC
-:106E200074D8DC0053C41D6CC1734E2B9B82D9E80F
-:106E3000FF5DBFA6A005E38F999981CE6B411FAF7F
-:106E40005833BC1CFDC18E47457FE1112DE8EFFD95
-:106E5000D216CA53A0FEA93553CA292F7788ECFF52
-:106E600046AA9FFFB32BBE386E204E2BCB31665601
-:106E70003C57C2535B5E0ABA7DC164595EA2633956
-:106E80003D9959E260F6983F4971B68E1EFFF1AE0A
-:106E9000728C83DD3EA5A15483FEF33C3F6A290436
-:106EA000D198D0566204F0CA5CCF03E5C919786B5B
-:106EB0005EA01AD793919E75E5389FF47ED6FED3D7
-:106EC00055114F65EB5BB0BF1EF8C2DB5A30BE2ACE
-:106ED000DBBF7EDF5B2DE18131BEFF56EC7EA56F0F
-:106EE000BA33E8DEBA231862CB5DD6ADF37C5E918F
-:106EF0007F33B0AB88E71589F2F02E9E772DCBD982
-:106F0000BCDCB13CF13AFF132F97B78EA4C4F53F18
-:106F100076737D0170939E4F39CE02DB13C8518585
-:106F2000DB4DED0E839DE74C8BC9D3F50EC6266273
-:106F30007E9393C329FB89FFFE6E310E0B5F9F8604
-:106F40007C3C53F0F910BFC2F394762747F0F71852
-:106F5000C0CBD2BE0DF3D926E211DB5CEC7BB36073
-:106F6000E8CC2416C27B7332FA41B990BE0FEC70A4
-:106F7000C7FA7B8D8B309B3A24B805FB9B9A9533DF
-:106F80007A455EAC1F80BBD939C602B736310DEBEE
-:106F9000C3FD314ED283CF423E0FE013C2170CF334
-:106FA00034FE7E4047E7C87CD4BF2331E9C6A4E75E
-:106FB0008B3B67D3799AA55EB13FE2E3DF6794F23A
-:106FC000BC97EE1793F9FD99CECE02F37ED6C36E31
-:106FD000916770CFCC87E91C74A79DD1F9851D25D9
-:106FE00017CD3BACC1B89CC96EACD1A2E48FD560C3
-:106FF0005C6E2CF6F71A9D3FC47E7C22FE8C71B528
-:107000008C1589E92FD7C19A0B060BF7EBAD2F63CF
-:10701000FDA7B3F0D84BCF2BD69FD56FECDD9F2EBD
-:10702000E2F802EF9AC0BB9E18CE7D924F01DF3688
-:10703000137F2D10FC26F703CFEE1AB1C9BCFF2A2F
-:10704000CF0D817E7E1A7F1F21DC9944FE4AB11646
-:10705000B80EDB1777A6D1FE80E40FC91792AE1DDC
-:10706000690D146FE97E44A1735CF1701D9670ADDB
-:10707000E7F7F665CD0DA9E67BC6A53C40FF1DA24E
-:10708000FF7113497E1EE3F20072732BCA2FDEC319
-:1070900082F3F07715997F8F40C25F84BC389EE8F9
-:1070A000C8F1FF824BE4AF70BCF5C67FFF4BD03315
-:1070B00097E859DC7980E659D387DC5679BD3C8F57
-:1070C000ED78D4EB83766304FF77B4BF4FF78A750E
-:1070D000EC5699E2E3F346BD55DCA38FC7BF3C05F0
-:1070E000F471564F19F4A50FE9D0A33FA34E67AC36
-:1070F000FD77BDE3A735A3BE14F7F6A6AB7834370A
-:1071000006C79FDCDCBE9A184A1CC76AF07A2C7A44
-:10711000EC916553D8FB30FFABDD3CFF6A625798BA
-:107120007E5747CA75BC9EEAE7E174343CFF97F48A
-:1071300094EB127ACA25F5147F7F186DDE31B8BE44
-:10714000761529603757D80299E87F7D70EC8774EF
-:107150003E6591C8CF1985F939B86E1E0FD2BAF2C3
-:107160000956F23C9D819E0CCCD7B6E6E9B02DFCC9
-:107170005C6B3C5FC5F8282CEC370187580FAE7765
-:10718000743DCBE3195679966580B3CE36C454EF7F
-:10719000E6EB96A403D0BB99EE3916727C6257D603
-:1071A00046D4B7AF7B789E4DFA90C0689CBF944B95
-:1071B0005857059FD8BE37DBCDF5C6EC04FC3BD94C
-:1071C000C3F5EC82F59C6F3AFEBDF43AC47BC7EB85
-:1071D00069A9CB4D7AA24CC8B1EC57EA21F99DAC14
-:1071E0009F22FA9BE6E17251E6E67C877024CA276B
-:1071F0002833ADAFC43FAD9C7F60BE61337FBF2EEF
-:10720000FA8DE153ACAB02CFB53AE017F0B7CD1E23
-:10721000EE8FF949C59D36EAAF62B787F2322BDAB5
-:10722000391E2BDAF6DBAA4DF889EF6FA987CBD18F
-:1072300046710FED611BF01BE2DDCDE13BBB2B87FF
-:10724000F4E7220FB71B2EBD6E5C9E9ED928F2314B
-:1072500080BE94BF58FBD2808D563DCDFB4BEF17BF
-:107260005A81E7F0D21F667ECC29033C45F1DCFF52
-:10727000171EA177F4808EE76DBB1F61B41F3F6CB2
-:107280006E60B40FCAF541F71805FA2B68E37AB8B7
-:10729000781DD83128774EB92EBCB2DD3CDEDD1E1C
-:1072A0008FE51C61C57A8EBF6160FF3C8D4FE8E7BA
-:1072B00059B2E3393C271E6ABF06E34EF2FB564142
-:1072C000FF4BC1578CF08D8BC187FD53FE8A3BB8B5
-:1072D0001CFBADFBCDCE01E67E1FECE977FE14175B
-:1072E000EAF9B5B0EE9074860EE2B98B8A3DA90634
-:1072F000DE9300F26C437F478E5BA1C9DFCBE92AA6
-:10730000C67BC20B7AC69174FDDD33E6F96FF6B821
-:10731000FFAEF4EDD043349FEE1D00AF2F86978E65
-:10732000F679CB5DB84E1C677E5C2724BCC3E6763D
-:1073300079315FA45EAC1F305F1BFA2FE93FF5B1D6
-:107340001588B7CE29744F423C5F4B3A0D675C7E7F
-:10735000A49F361C03FC50DEE32912FA87919F7B21
-:10736000E2A5BD4FF37B2D385DEAE7723A767942AC
-:107370005F7832627208FA9CEE2FAE58D7A38FDA8C
-:10738000F9FBCEDCB980CF5F7BA49C5BE9921E6CDD
-:1073900077D125B382AFCFBC382AB28AD399C6EF52
-:1073A00068F7441405CFD13634A1BF2DF504C2636C
-:1073B000CE5792F0F4D091011D47C5DE0F9BCBFB59
-:1073C000AB0779473EAA511B941C85F400C557B3FF
-:1073D000500F4039AB9DB7637BF8FD0D124F353729
-:1073E00041A7E077FE9BA790E621F19535376AAB80
-:1073F00029C47CE503833F30D1F9A8D82F40BCCC09
-:10740000267F83EBEB1A353810FD5696E5A073A85E
-:10741000B00E917E39EC629A0BFA7B199EB82E4D14
-:1074200055EFA0734253872824C7A00164BC877E10
-:107430008FEBFA6B9379DED65FBE3F14E79991CC60
-:10744000F910FA718A7E9CB40E8AF5E05F73C1AEC2
-:1074500053627AF9B0A2503F87FFE1CA4D2B9418CE
-:107460005F627F683F1D56660DA4F5B22343240773
-:107470007559F2C97AAF675DB9586FF617D1BF8BEE
-:10748000F99BCA3DD380A7264C6F8FE295D34D61FF
-:1074900075DA3FC1B853C1DF74A1FEF472BE3E9CE1
-:1074A0001756BD08D73085EE573E92142AE4F7F4FC
-:1074B000F2713245DC2653E42BA3BD80CF8897EBD5
-:1074C000FF9129FCF903F1CCF4268EF3AC13F5F50A
-:1074D000E25EEB552589F3D9067A154BBCE57AB106
-:1074E0006F81F7FF7AB9DF29F26CF93E07D8F7848C
-:1074F000DFD27BE6D2BEDDE79D37A4F0FB1BB83EB2
-:10750000F85009FCFA26059F41BA3F2FFCA64AF91C
-:10751000EF1F18012FE637D52625CEC32E11F3AB6A
-:1075200015F3FFA891DFB7B000F7D3407F8CF5F2D9
-:10753000792C6AFB7639D27BD13A85F6D3E4BEBD8D
-:10754000A46FE506D5124F5F80FB69FDFE163FCAAA
-:10755000DF871F35CEE247C971E3FDA9138DD996A8
-:10756000B8FFFCB621E29E0BDEFE76E627B86F6F11
-:107570001D60D9FF63AD1997770F28F84FE184F0AC
-:10758000E9A46FE5FB138D4E1636C3F1F150CA7BAB
-:1075900018E80DDD8CF48DC191CCC26638D864FE3C
-:1075A000BB572E1E77053B9CFB2FF0DCE8263B9D4E
-:1075B000EEA9ED898381FE3052501F95CCF38E8F5A
-:1075C000F90D52BE6A2627F61FC6093F779C9BFB22
-:1075D000C729C7A53F9DE443BD28EDF1F8EF1A7A0E
-:1075E000F8D66A4F5E2AFE00FC1B36FB47F1FDB65B
-:1075F000887EBF3EBFE4F7C12F05FF257E77F1E40B
-:1076000010C5F7F0F221CC45995066F5831EF5F2CE
-:10761000F5FC516F327D2FEDEA8AB9D6768F63BBC8
-:10762000F1F84CBEAC788ED97E5786A0FEE3FDC93A
-:10763000DFDDC93BF53AE57FFE0EFD44E8EF584A31
-:10764000602BF2C71A912FBFF1AF07B36F477BE8EA
-:107650005FECB45F5FF2D8D21598CFEC6E570C3A5E
-:107660007FB4DB2A0FDF5CD63EB802F0D12EE8549F
-:10767000E3E7F3A8F147F5A16ECCAFE6E30F6CDFCB
-:10768000AF68267E1B58C9DBBDE4B55BE233FBB0B7
-:107690000CFDECF11AD26FD93F231DDB0734B40384
-:1076A000FAE3EFDD003CFD1B18D9D1FDC729D4FF5B
-:1076B00037C76D54F0F7B7E43C5B6DB30A0DF8AE15
-:1076C0003533D98FEBCD00237408E5ABE69D681404
-:1076D00097C709EF746AE85F8D320287F1BD9C9706
-:1076E0004F35FAA3DD9EFC0E87AFAD27AEC4D71B86
-:1076F000C6560B3B7413B7C7547694717B9CD6F572
-:10770000CCE5C369DD93F3C94C13EB46260B61FE50
-:1077100031B46F253BC5C9D7FDCCE5FCF7F2243D5C
-:10772000637EE68831E8670E5913D5E6C3772F6D7F
-:10773000B025BC5FE37D817798C7BBE6795C4A5F83
-:10774000C976F63EE28C92DF93A727F6DF19BB9F3E
-:10775000EA4B1E4BBF85E4B259A7FB1025FE471923
-:10776000C1CF109EFEED1B15C4CD0991577062D597
-:10777000D30ADA91DF5FCC0C35013FF5C8EBB29D3F
-:10778000832B4C7A13FA277A6C8CCB1397F116570C
-:107790000AF77FE61B4196329EF276C97F5EBC8572
-:1077A000FFEE469FF8B84C7C2995DC2EAF99C37F3D
-:1077B00077B4E4318DE85DDDCC7F77B066FB0E3ABF
-:1077C00067C77EC4FC28EF35ED3B940A18B77AFBF7
-:1077D0000E6581097F036A22945F7D8547EE3B44F5
-:1077E000C96E8EE76B8C17A09D72C4C5E5FD7489C8
-:1077F0003B8CFB10A7EDA11A6C773A27D98FFB942D
-:1078000012DF2FEF9846F71D78763AA2F86CB56D27
-:10781000CA7642BBD691BA1FF96894111A86784984
-:10782000D3821DF87D6ABAC78FFB183E071B43EB56
-:10783000F565E261421C3F4CF81197939B52BC42A4
-:107840002E18E53D5D9BE291F613E9A723763E8F66
-:107850009D8CC31BF106C6A5201F1EE5BF9BD0BF94
-:1078600026AA60BE48FCB8317E0A5C8DF05F3E9C63
-:10787000ED3AEAF56AA1674A1EDBA2BC6F827B067D
-:107880001A55C89FDB372A1827837AD233D09E61D6
-:107890005E52FFEDDC2FAD86FA0526BD22E7914052
-:1078A000BF04713EEE773A0F71FD12E5FB0202DE76
-:1078B000787ACE4DF1D1F8E5601ED07B3D3C1CFDC1
-:1078C000E223F949D49F94F778F99C2BF8BCFF8602
-:1078D0002D8ACD4DFB2764474AF864BB6329534288
-:1078E00088AF09D33B090FB51B349ACF543D38F408
-:1078F0000E933CD4A5703BEEC04DEFD2FD3FEB7E26
-:10790000718CF8B116FC69F227DA8EE937E0BA1209
-:107910007E52C5FDAEEBB849C21E12F7625DD7C1FB
-:10792000F56F6DC70E0DEF91947C9A77EA00DDA795
-:1079300055DBEE60E84701FF2D45FCC4F3A9C48F79
-:10794000D4AF7DD113F410F793C2BA88E785F2D093
-:10795000CF91FA3922EC51E6E6EFD78A79C5F827BC
-:10796000D49262D1AF2E928BBC53630E605E66AD33
-:107970005FA1F392E9A5E277C84C7099FDBE78FD4E
-:107980008871C320F7E373679BCEA9F5E879F1FD11
-:107990003AA4377F1FE5EF593EAED712FE78FA457D
-:1079A00053B85E4FC0678FE13CE2D731B9AEE73DD7
-:1079B000BE53C3FB9224FF5C877437F1CFF6147E6D
-:1079C000EFEEF6148DFA7FA884EF3B3E64E7EBD729
-:1079D000434D4ECAA37CF9669ED7E5B9458FE2F3C5
-:1079E000B06D7E0DD61FEECFE168B52DA773772061
-:1079F00097CF205D0FDCE4655C3F727DB8EE79AE19
-:107A0000CF6AC26EF2736B42DFA9A07CD774979FD6
-:107A1000EE010D1DD26FF0F4E62BDFCEFDF4FBC7B7
-:107A2000D7B573F99374007D4AFC25E541E23586AC
-:107A30004F8E77294F921E11B9CF03FCC2ED23EE72
-:107A400057158A739195CEC011BB0FFD161E7F2D61
-:107A500014E72365FC75BEA04B912DF81ACEB357E1
-:107A6000FCF532FD83EA65AF8EC0DF0FABCA3E4A3C
-:107A70004F29B7E0BF5AE4FB6D41F703C25F3C21D9
-:107A8000F444F5B87692CBEA0F1A489EDDD3B95E7E
-:107A900073BF63D5C78CDD27E6BB86BE9B9ADC5ED1
-:107AA0008EFBC7537FA618E8D7F705E7223C2F8641
-:107AB0007EDE8683DE79885FF13B52F25CCD1F85E6
-:107AC000DE39BD4D15BFABD9A05FCCFEBE547F2CB7
-:107AD000FA8642F79A08DFF0F4F6D2491FA27FBA7D
-:107AE0002D857EE7E4D3EDDFFEC187E9F83B22D7A1
-:107AF000FAD14E485F1124FEE9CE70F937F178ECE7
-:107B0000748C5735B51FF4E2399C4F9EBE6A0CEA5F
-:107B1000ED2483CBFDA9E7D5658897FF0324F17B8E
-:107B20003E008000000000001F8B080000000000E5
-:107B3000000BD57D097854D5D9F0B973670B9949F5
-:107B400066924C36B24C02045412262161916D9219
-:107B50001016599CB014906D640901421220ED87F3
-:107B6000D57E190CA5C823355A1770EB049762B55A
-:107B70003568B441830E0808553F47848A15EC8860
-:107B80001441423245DBE25F5AFFF3BEE79CCCDC96
-:107B90003B1350BFDAE7FFC3E3733CF7DC7B96F798
-:107BA000BCFBFB9E3377FEEAF9B1A38A0959ED9538
-:107BB000120D8490CE5DBFFC577A1221D54FD65955
-:107BC000245A6F7AF6757DC04488C6DBC29EEF8A60
-:107BD000B7C07BE79FB8772C194CDB5B9BB0FDF3FC
-:107BE000275AB0BEFF57CFBFF67FE87B35AE3807C8
-:107BF000BCF7F98BFBF4F0BCC6AD75B6D292B80FEA
-:107C0000E8679B69E9794626C9844C21ECEFC1DD20
-:107C1000FBF4F67C5A6FA5A3D2EFC95CBD77400E8A
-:107C2000FDAE75B776A909DEF0125242C7FDD5E266
-:107C3000916EA8B7DB08490B3DDFA2271E63022D1A
-:107C4000FB101243CB0BA5268F144FD75566DA02D3
-:107C5000E585DFC4CCF5D2EF6AF5813C2BCC6730EB
-:107C600071423DD5A2C1EF6B5AD7EA6A4DF83DF695
-:107C7000F3071D2150E6130F393B88AE9F9027BFB5
-:107C80001E0AE3FD96101BBE3722A68890390B3ED4
-:107C900091603EB183EB75AB719ECFB276BAEAF0DC
-:107CA000F6610D743C3AEED7F0372E5416594C3825
-:107CB0003E05087E97DE56996187F527191CB07E30
-:107CC000B1BEF46A7793993EBFA9C1ED90ED84BC33
-:107CD00072EEE884BEB4FEAB41D250195E97A5C5E2
-:107CE0002EDA7FADC784E3ACD950463EA5F31D0F15
-:107CF000BB48BF4FB690A41BE97A2AB424C9042517
-:107D000021C77445D0FF53D86E371027A178607F04
-:107D10007DCE531BE9270FEADC6925D0CF16BFDEE5
-:107D20000EE5936CFEF47B8BA908FBB3DC08DF1B2C
-:107D3000C93AF8AE7BE3D4A4AD12F6EBD72584E6BE
-:107D40004D48306B763EEBAF18E034C93317DE2771
-:107D5000763DAEEF737805F7D153B0301FCA6D6C26
-:107D6000BE1AE2067C49D6D312E1EACEA9A478B3C2
-:107D7000C452BAD052122A93FBB076355C5B78FBC2
-:107D800027162796645722212323DF13A580FFFEA1
-:107D9000395DFA001DF7FE573F41BCAD05BC85F1CA
-:107DA000DD67F4B00E81B7CBE013BA0F0FEEF90424
-:107DB000F17659BB84F0A96D2FD52FA5E58546270F
-:107DC000F9544BEB1CFF1E94025580D79E3D319613
-:107DD000A7289CBA047E367F7256A6CF73DBD3ECFD
-:107DE000123CDFC3F0F4A046E301381DDC79434BBD
-:107DF00093143ECF8D081FA99A209DD4D613AF812E
-:107E0000B6973ED6707432ADAFA9260E039D57AD1E
-:107E10000A8F721E3FBD19F0C55A438A63ECB0CE7B
-:107E20008F27F4A5FDD7D69012A0D3F4F1CE3D5004
-:107E300027ED121900F56AD73218FFA6A4950E99FE
-:107E4000F66F1DEF6A83F16E4A1AE390697F0F6641
-:107E5000B66E36D2764F05B13C0570D0359769695C
-:107E6000FDC10ABB854292C2EDC954682783F48ED6
-:107E7000A7008FDDCB6AA0BFDAD4F90EC09308FA51
-:107E8000DFB37110CCB7D6DEC71143DF9FD22E21EE
-:107E90005E118F89C0FC6B297CA13EC53BCA0BF3E8
-:107EA000B9C8E127E0D8A5F32F82F975BD64201E7B
-:107EB000DA3E653CC357EBF856E41F6FEE997858ED
-:107EC0002A08E1A5F965830FEA095A8BE400BE444C
-:107ED000661A603E4BF97C9A7564B18B7E679DC4CF
-:107EE000FAE977B784FCE259A0271B941A5EEA39B5
-:107EF0009E37B3D2E22970517CB8C8F71FD184F6FF
-:107F0000BB9AE3CB9A653EA4A79AE7587F490667D8
-:107F1000E1FA30FC4D2A2748C7BB62C8E24AFA7C26
-:107F20009795956A7C7D8FD375CEE3EB70DF97D202
-:107F30007D877D4DBF9B3E07B851BC00B8D17D44C5
-:107F40003CB8296905EEDBD2BBA55B701F3DC308B9
-:107F5000D46D896C9DEAFE8FF3F5ED8A71154BB4F3
-:107F6000BFA0CDECD829C17C9C9A18A8175A1D3BFC
-:107F7000097CEF7A12C6B3A5C4389AC2F81521AEAF
-:107F8000620D1DE75CB299EDB7F75DED8C7CA04703
-:107F90003BB6DB64E223C87F48AE2B3FF45D453F30
-:107FA000D65F05EF6F6AB3A780E43278205C383C77
-:107FB000BC1BFBCC0DE7A71F717878AF2373816FD3
-:107FC0001CD4139311FAB7D071687FC93B473DB1F8
-:107FD00015E7D784EB3A60B1605991E82AAEA7FD66
-:107FE000D9FAB91A002E629D6A782CE1F0D83F6761
-:107FF00051A106F07896C9017477FFABD212C46B19
-:108000008F911225E03DA34342F703E882B8B5B84B
-:108010001FB5F52E6F74BCAF443AAB4D8A71C4489E
-:1080200088F74E947F1E9397E13D937FB19398BC60
-:10803000023E59991FC90F049F01F906F82CE8A2C6
-:10804000766C200FF6F79BF2952E1DA3F32E0A07F0
-:10805000A0234137E65718BD6CDD682F85F6AD9437
-:10806000EEC3F7FB90DE83F47B28B78F03FA8579A4
-:10807000BACC21FEDED7E28AB752F8D56A7C9BB52E
-:1080800039217E5CFBCA5D79EE28F827F8B151CB27
-:10809000F89CD11BEB65FDB2F18C14DCE6222C3D83
-:1080A000208F623730F8A8FBC9B50AF96AB49CA1E1
-:1080B000727C3ADDA4F87E844CD2B873613E6B8C3E
-:1080C0008143746749D686A01EE6910CB20BE8671F
-:1080D00067AC17F856723271BF10A5DF242BE3038B
-:1080E000625F9A13181D25C7B1F7C75A995E516888
-:1080F00065783991BF2FE62FF0DFAE717F42E4DE65
-:10810000E598F88ECE0BDBC57CE8F75B0893BF38AB
-:10811000DFE43BF3766E0DDB8F101D5D5704FBD45F
-:10812000EF6E9F768929348E90A7EAFD87F903FDCB
-:10813000C07A2A07F7FE5EF33E468F6A7C9CCEF536
-:10814000299395B0F774BEBF225DAD35939D30BFC6
-:10815000EDC49948E755F7DA40460FCE601EF4FFAC
-:108160006682FB19D88FE1E3399ED3E733E8F3D574
-:108170005AE231D03D59BD4BE70D1819CD7C4DFF6A
-:108180001B97C0FAEF361B3D32C5F30F13DC0BAD66
-:10819000B4EE29230E1FC8A51F53FE01F4477C250A
-:1081A000C05FEA48200EE05C2BFBF308DDFF2BB13B
-:1081B000EE25F0FE698D3F0B9E1312407C3D191396
-:1081C0005740687F6D7A5FE67FC1BC8FC86427ED3A
-:1081D000E712714E81755CF26B123C741DA7DADFF9
-:1081E000FFCDABF4AB85AF5E5C783B40696BECA236
-:1081F0004768B9C0A8316A8786E071D21C9DBFFE6E
-:1082000098E385AD89E95DC18D062FC047FDDEE4A9
-:1082100004F65EDDE574E2490C7FCEF8689D36A871
-:108220000715B2EE7216F1D0714F6948756B143DA7
-:10823000F39495F1AF368AFAD1DA4F733CDBA5237C
-:1082400079DB613E2D940F02FCB476E417D5BFC8EC
-:10825000716CA5D5B6DCE021D023820F48C8FF4F52
-:10826000EA18DFA17FB38CC342F213D413D00FAB53
-:108270002D1E9F86F28DEA06B34F2EC0E7DAD1B0ED
-:10828000771E8B16F8E0122E1797D6BFF995144774
-:10829000DBB5C4389A7EF79969591C8885AA1FAE48
-:1082A0004F06E53B654133D22768B4A08F4BCEA97A
-:1082B000F2D7B157D3E7B4A8B723BED0FD9D96E05F
-:1082C000F2C27E2F8867F05EB03ED6EB09E37FB343
-:1082D00038BDAAF16C17E0289DEFC712932BEA7105
-:1082E0005E4C289B0AFDFEC3EC7A16F077C1FA8B30
-:1082F0000A7ED625059E7E04F071ADD9F114EB36C9
-:10830000CB15462F87C5B89735B87FDD85FEBC0DE8
-:108310003980F7C1AC0F289C5777182C1E3BB4EB63
-:1083200015FB7FBA9132BEBC30F974AEFF04620215
-:10833000F83B36033E2CDD124B3C8342EB00851BA1
-:10834000F0BBF632C17E9674BC7902F879AD368006
-:10835000F8B3C468C2FDA9BDACC579902DBACE8072
-:10836000F89ECADFC438E721589FE767A3AD676F5F
-:10837000A00F53E8735CBFFB6D78FE506C1C71322C
-:108380007AF10EA4F3BF64B4C7275078D5E9297EEB
-:108390000CC16E5CC630FD8A649895FBDF71E42BDE
-:1083A00098CF32A35B0FF27EF9DC7A3DD0E582787C
-:1083B0005F896570F8BE8F96BFBEE19BEFFB6ECE06
-:1083C000874EE9295D44A1C3D39C2E26034ED2F2E9
-:1083D000543AA39F5359A4FA0528AFA725FDEE549C
-:1083E0002EAF17B1BABA1F7D02A39F53054C5E7919
-:1083F000D631F9A17EEF32DFEF6909CE20C04D3CC6
-:108400001F93C09EBF98E0FC02F089F2C3BF737C4B
-:10841000F559697F0B5E3720BE924DC13CD8C79E8F
-:1084200075E5F1F926479F57DF04B63EDAEFBF60E6
-:108430003CFA9E13F5F6D762BC608790A9943F037F
-:108440003F5E9749801FD371F50936ECD767C5F7B2
-:108450000CB80EB285F2698AB7DD2576DC97ADA53A
-:10846000143F814FEC3558804F087C127814813FBF
-:108470009C8F09397C33C86119E570624209CA6171
-:108480003DD039ED51CFF4C1FEB8DF8867F237DF58
-:10849000EFBD46B68F94DE3313703C5F7E38BD0966
-:1084A000380B3E79AA8F122F9EE27C70007FAF07B7
-:1084B000CE09ECBDA47E4CEE09FBA084EFFB335645
-:1084C0006529E4D8F0494ABDE4198E6FCF58E3C45A
-:1084D000BE1402BC85FC8BD8EF47D97ED3F786C18A
-:1084E0007A1618828B12A9FCFA01D58BF445F8DDB7
-:1084F0006EF82EC24F319EC9DDBA7566027A81339D
-:10850000C1C2E05F1CCC82FEC8A020F2A12584F28B
-:108510001BE9DAFB073E81344A23D3E298DC9164FD
-:108520003A20D0CC206287FE28BCA784C35B3DDE06
-:108530004968A27AE0EC04497B16F6A89014C27E42
-:108540002D7AEF0BF342DAE5458BD1A3A172E487D4
-:108550001AF73CE8A7F3B623A8F79FD4FBF29A4D8D
-:1085600051DAF5BEC71F9242ED8B9F913D7ACA67E3
-:10857000DAFC9D0FCCA178B9C42F3B60C82577FCED
-:10858000F59DE1A04FFB750EB06BA93E71B796CE7D
-:10859000FBA486ED27A957FA051A38BD50BD4A4BF2
-:1085A0008685F893D00B5612DF00D01F9612A71EB7
-:1085B000CAD36B574C25145ECB4D0DC8B7CEAF9BBD
-:1085C0008CFA7215F160FBD22DBAD3E1F26479B363
-:1085D000B2BE62BBB2BED2ABAC5FF811C3B748BC8F
-:1085E000677A98AD3CBA7EF118A7B70BFAE8EDDBD5
-:1085F00038DE96FF6CEA4348FF7E1D31503C69D857
-:108600005B9A42A2BC2FCABACBB9C41B268742FAD6
-:10861000471EF10E85FEAEA03F10FA013BB721C602
-:108620009902F6C885B2E8F37880CFA3EE729F5E18
-:10863000FA8DC37E2FE45E7D9D75978DF85EE4F71D
-:1086400026EC97EA5951BFFFAD805342F4F65FF72D
-:10865000CC2F15E562E83BBB4AFFCA40B95A77D92F
-:10866000A290D3A1F6242657B99F80EEAB07F562FE
-:10867000AEF7518168391B1BE263BA3E6C3E826ED5
-:108680003E9588310DFD6AF7723BC25100FAF1A7A1
-:10869000A07F01DD4EB4BF16A0535D7AFBC83C6DD0
-:1086A0006E88AED4EBA1F8F879204C2FD89F604E9D
-:1086B000C2711DC401E30A7A58745B45BC9BEEDBB2
-:1086C0009FEE284F710F0EC73B0F8E5FAB177A9F3F
-:1086D0004921C7894ACE2F6D3F827ADD32A32B0F05
-:1086E00098D39FF7DE867452455CC9401FDD7B0737
-:1086F00066B9FF17F25DCC67A6E7561DD3E3295094
-:1087000029DDCEE0F399D9C1F44A8DD1A9C3719C7A
-:10871000C46E4946539DCD9732592DAD8FE9993F8F
-:10872000381D0919CDE72FC1F714BE63784996B8F3
-:108730005361DE0618978E1743BCA950368D74D846
-:10874000A11C27B9B46C1E5EDCE709A43E03DED78A
-:108750001803325B279D41327CDF032FAC9B797D70
-:10876000D3AC4B8B96C3739319F98F9ECF434EA412
-:108770007C7310F22523ACDB60F29D87759979E953
-:1087800029637ABA2797389AE86B7D482B81714D17
-:10879000A68B1E58AC855824A8C7582EF9C05EB9C0
-:1087A0006831793443909F1A12819F4A6F57C1BE36
-:1087B00050FECDFC57BDB56B7D682709FE98C0E71C
-:1087C000D7C4F9631A61704822AE7D4E8AD7F799F3
-:1087D000ABA6923810E36E1C7F47DCA4C3305F0069
-:1087E0003CCAF949DAD3E172C6E6D22AF85FCA5C1C
-:1087F000653DCDADAC1BC9490BE8A392CF95FA7589
-:1088000022DA7F83C09FA3E3FC66561F362F813F89
-:1088100079899CBF733DC4C5FD01B5097A827EC4C8
-:1088200064A3910C41BD242F91F9073EA63B4DED69
-:10883000C620F2F3C271CE010F50386F7E4F76DC46
-:1088400049F769B3D9BE510BFADE3C89E9F7DA562C
-:108850001FF8875A16591D5BA13DC679CF3FA1FD70
-:108860003D9980BE55077EF94478D1520ADFB56440
-:1088700059F0BDA4F220FA53837711D4A722F0F463
-:108880000A9D3F85F713880CB49F6596D5CFD1F725
-:10889000D35CB10E29ACFD4968A7F394385EC0F3F0
-:1088A00071C3C0FE657FFD3A0AFD4EF06F386594D6
-:1088B00087751D856F98E83CFAB90B1D80B6FD3BA6
-:1088C00078FC25C9E065F1074AB5741EB38D6C1EAE
-:1088D000751DA53797D0F6FEFEA104E210B187ED15
-:1088E000F36BA04943ED6EF8AE2C16FD5EC7B8FFE2
-:1088F00089707E305C456FA342F88FED85A24ED51E
-:1089000006E730E6D6C07A12A30307117F8C3E6FCC
-:1089100024A13FF8BE3CD41FF2A3F1A1E610BDD1C3
-:10892000A515191D4D35F4BD839513110FEBC0EE40
-:10893000A2FB315CEBDB07F43D8A9785BC244B9AA4
-:10894000119E5B37FAF6EB72C0D5E292A13ECC7273
-:108950005713F43746F2619935F7DE2640AB7DA018
-:108960009C217EB92B801E3757100BE85F4D231CCE
-:108970000E0B6D9A3397F96767CF357AC1DF3F5B8E
-:108980004B585C4CEBCEF901A5AB1F2C607E61A867
-:108990002F08F3BB8838C8316AC7EC8EA20FEC4BA6
-:1089A00064724A7C5FB749AF8837ED4D3461FB1381
-:1089B00089133C89A8A7B97380FE3627727D6C1095
-:1089C00019047C258CEEB722DD97BED51B5F50B60F
-:1089D00073BE30DBF90B1DEAF19C3F083EEC023A16
-:1089E000A4DFF925A70EE0F7611983FFD1D295C85E
-:1089F0001FE610373EA708A27385FB9B2685E94337
-:108A0000749CD92EA57E3467AEB22EF0558C3BCF28
-:108A1000AD6C9F21F4DB494AFD76C17F5DB1A21C9C
-:108A20004C797ACDD7D9185F413F411DDD27165FBC
-:108A3000D1B278CB26BD17F4A4BAF6B5076D40477E
-:108A400077104E47BBA56518FFD92D2D0FD323FAFC
-:108A5000D67825E0FB03E99AFCB8AF418C2B1DD3F7
-:108A600079F741BCE5D84ABA623ACF37F42C6E792F
-:108A7000208678C06F2DF0D33C83F95D291A63FC02
-:108A800024C312EB007CDAA229423FED9638B323CF
-:108A9000DC2FBA7523C5BB30FFACDDC0428CC77A72
-:108AA000B17F8F24323BE74189F9C93DF38C68EFF0
-:108AB000D9FAB91471099B4C4E80BFD19368473CD9
-:108AC0007A90FB4320AE3794965E89E9333DDFCB45
-:108AD0006413FA2755FCC796E8C0B8802D3E1FFDE9
-:108AE000FB733B0A9F447E638A710C9042FDCF75F5
-:108AF000B7689783FFA0A345BBCC14C2BB93025FAA
-:108B000063492CE06B8FBFEF0503FAFB7EA871056C
-:108B1000002F6BF4BE02A2C4E7C0D5E4D80A8E2FA2
-:108B2000BA32D7BCE5743EDDEFE899FFEB0E82F474
-:108B3000FAE21E2BFA2BB53308CA934DA504F1A116
-:108B4000BB4542FDED336B35DA019BA46694135DA2
-:108B5000091370FF56990EA05D5BFDA8EE74B8DE98
-:108B6000B5EA49657D35F1A35D5DF35C043E23FF05
-:108B700012FCB1B64DF91DE9AFE48F859CEF17B932
-:108B80001C332B60EA731DFD985D4D7C06BA8E92F6
-:108B9000B7F5DC4FBC80C94DF2B404FA56B7F99C66
-:108BA000CCE89CF1E312DE9F5A0E95707D6A2CE5AD
-:108BB0005B607F0AFD88BE8FF5039A0E3955139AC4
-:108BC0005731FF4EE865826F8B7D291D41C8088AA9
-:108BD000F7B9497C5F73492EEC2BED1FE901504238
-:108BE0009F80FD7BC06E1BC5C7A3FBEE0139EBD197
-:108BF00018BD80479BA57AE4D346C2F9B5E446BECA
-:108C0000FC3B8F4706B88E24F533A7D2F7461BFDF1
-:108C1000B1000F8A0F7949B6109E34115FD66E49A4
-:108C2000812FD8DE697D2B2ABE08F9E2FB90E91777
-:108C300053E88AA19F0A08F8D0F280C4ECC289A642
-:108C4000FBB5F0FD5B9AC9880F9388570BF3ABB067
-:108C500028F77962AAB23ED91E8107328CEBE4F084
-:108C60009C3248D9EE147C8D28F95A0EB982FB4CFF
-:108C7000EE3AF443F00BC46E208340EFA01A22D2E8
-:108C80009B9A1F4C4AEA355E3229294ABCA49BFBB9
-:108C90007F6F2481AAE7A4487CE93AB8414E0DC30E
-:108CA0002B81C7AFF0FC0AE9751E972D66FEC090B8
-:108CB0009C67F8328CD76E047CA3EFAF1478924D8A
-:108CC000B2014FC6B4C7F8640AD742DECF8D8037F1
-:108CD000452179EED398ECFA5CC00FC716598ED4B3
-:108CE000DB9313EC882743354EC49312E24884FD8E
-:108CF00019616C6DD2C2FCF70CEFEB3629F0620DF6
-:108D0000E28544F102E92A422E2ADB557823F6EF68
-:108D100030D79727124F7F188FB2B103A02FFB7265
-:108D200018DE541027E2C99BB99379DCDAADC57E11
-:108D300088521E961B9578A0C62B3AA2267C5C35DD
-:108D40009EF58637D98037421E265E1B6FEE49326C
-:108D500029F4EA30BCB927A9A477BC51E38BE027FA
-:108D6000BB632CE5A097D6554BC88787BED3BF09F8
-:108D7000EA03D7E460FECB6EAB03F5D6BA7AD65ED3
-:108D8000EC77CA901FD3AF81B7E7B8CAA15EB781AD
-:108D9000C5294A8EB1FC99FE77B0F6C23BEBDF30B5
-:108DA000837CF7B0EF5F39BF598EA3EDDECDFCFBBE
-:108DB000D2E672A8D76D61DF7F067126BABFC34EB7
-:108DC000789BE0F97577E73898F9C9F4D9711C4FA9
-:108DD000774B2FBC81DF35B3EF561C32F621A80745
-:108DE00033BD752C5FE7B847D93A933EBD69929D74
-:108DF000E2EFF2A007F5A6B39A9A61C86F7AB13391
-:108E00004BA5E60C2829DE209F711A295EE7B238AF
-:108E1000E44E3AC45B49CC9F21E277904F109E3FCD
-:108E2000F0561293F7E2BDE404C2E2CD0F9BD11FCE
-:108E30002CE28BBE87880474066BE4F23F6ABC7137
-:108E400062BF7A8C334ECC1671C68076091DB7F09E
-:108E5000EB2F2644F3A71C4D627AEA399E1F219E10
-:108E6000577B73348017BB0149D20148F5BF07BD5A
-:108E700009FDAF4C6878C808D857560F24D56CDD6B
-:108E8000428DF4159A7AAD07844C16B5BF68D7D3D6
-:108E9000FDC4171F1739FF895AE203F944B46CFE69
-:108EA000554D540E4A21BE345BB09DD103904E67A0
-:108EB000F17DBA28F8CD503214F8CD6CBE6F3F303A
-:108EC000D6EB98BC6CD6A9E8FF2F48FF3B7AD59B20
-:108ED00095ED2AFE50CDC7ADE2FAF24A1244BDE04C
-:108EE000ACE4C5F2DC0EA62FAF361D43BDA2FB617C
-:108EF000A627D69000EA1D6AFFE1EA5DCAFA9A56F3
-:108F000065BDAE5D59EFCEF7E038DD3BD60C03FF13
-:108F10005DF5F677D02F5C2DF88457C927A882C459
-:108F2000F8C443D7A3DF4663A47CA218C0D507F3D7
-:108F30004D86126722F00310B25FD3FA5DF0491A32
-:108F4000AD6B5C093694339312CF88F1658CE7BE24
-:108F5000E3B487F6A5C72E54F18942E18FE99F80DB
-:108F6000FE2AC1370AB95E4226A9EDC6FB91FE86EC
-:108F7000F25ABE8DFB53B8DD23F40CFA3DEA197E9C
-:108F80008DC9ABD184EB155EA4C72223951348424B
-:108F90000E23B3579A896A7F0B6D57B79B94EDAA3E
-:108FA000FD1776CB30BEFFF388BB2FECC72CE23A1F
-:108FB00008F2E1E887D50A7BE9C33F4E10FE14B4FE
-:108FC0009BBEBDBDE4FB4EF652CFBEC750FD919691
-:108FD000E533260F7800E2E36D3198F75927B17D2C
-:108FE0004E9E772C2BDC7F78B491D8B46174DF343B
-:108FF000D96084F860938ED91333A69C1AB6248C5A
-:109000006F3C6F2C9D0DF0DA2CF97FF411D81747C7
-:10901000648279351D36DCF74BCDF439C5B74B8FFB
-:10902000DEE0F0D0C717742CDEF899545F05A95024
-:10903000621E551B7E1FA3A5726C85EC7D2D00F171
-:1090400055C9FB720D6D3BAE772F85FE576B7C7A51
-:10905000E6B7F3639C54F4DFBB1FD2837C4CBF9F05
-:10906000C9C5A0D4C7C1FCB89EBCF078D39264E651
-:109070006FFA30C15507E308B927E20927D74E8CAC
-:1090800007D1F02571C6439C53D242CC2E723CC806
-:109090002BD814E6573E19133D2E70878DF1579843
-:1090A0003EF0F734ABF32736E0B7DCFE3BC7E35DB9
-:1090B000E7E258FC6B8B8DC9810EFEDDE3BC3CC73B
-:1090C000E363E7129476A378CFCBBF3BD368346ECB
-:1090D0000ADB4FFB43867A2FE653F1FC9106C2EC84
-:1090E000A43DD696AD61F1D0676DA51D000F5B3F25
-:1090F000A73E0DE0B787C961884743DC78A4C5FD6A
-:1091000020B4D7DA8913E2AEC41ED0CF84F823D8B6
-:109110009DA83F307CE98E61A598D7B3B6CA0E589A
-:109120006FF7DA00EE674FBD92F1C7676D2E1CB77F
-:109130007BB668E7F56D01BEFFCC7F20FCD9BDC5CD
-:10914000C3D4F12F2A38989E1DC3F8983AEEBD502B
-:10915000F0311EF75EC0F9D0C20EE61F5F64249B9B
-:10916000FBD2F6C51D29CC5E8CF3E429E2DE9ED845
-:109170006F95EF20F0B33BD3DF13AF7D382C5EBB90
-:1091800086C7FBD688F5B529D777C4D66BBCF688D9
-:109190002D4ABC569D17F032C8F7FE2178AEB3B009
-:1091A000F557C835E57AE013CB08E691AF3BB2B48A
-:1091B000C948EBEBEE02CF1FFC317D750D87576F71
-:1091C000F3B3B934C4AEF013F721F630BB38CD9DFC
-:1091D000A0A8A3061C9687D9B73A5DF17D667DAE3F
-:1091E000E2FDEC0DD72BDA733C458A7ABF2D372A86
-:1091F000DE1FD05CA6A80FDC7E93E2FD42D22F1EBC
-:10920000E3B18765F09590EBBC3314ED37ECBA45CC
-:10921000F1FD67A4FEC1D1F4BDB618260788C7E9E1
-:109220001F3C2C94779CDFBA44F17D93D43ACC4711
-:10923000DF5FE667FEF621EDAB14FD5D889BC0ECB9
-:10924000081E7FACA7FF181FB7CBA80FB54BE46172
-:1092500029321E59DD71EFE6BE2452AFA07F28E708
-:109260005751390F7A945ACF30279B93101FD24908
-:10927000FAD7617415C20313EA61971E95D19F5600
-:1092800048063E341AE1A3235E7BE47E5D22CCCF08
-:1092900073E939B303FC652B8E2C45FC33A42AF10A
-:1092A00020C6AEC483D8414A3C303B94FB1E3F42AB
-:1092B000B9EF6A385B9D4A3C107014704E9CA4C490
-:1092C0000B01DF11F41FC0B788040F619EB5577200
-:1092D000F84894786F7B0BAEE35A7ADB70153C87C5
-:1092E0001E703699104E2CEF4AE84906EE9F56FB49
-:1092F000CD85FE313199EB3DBC1FE1E7DE2C795085
-:10930000CFE989678DF065F97240DFA927CC5FE26C
-:109310009A926C8BEA57C3E7BDF9D5041C853EB31E
-:109320001AF4193ACE72E246BE7486EB332B4CF730
-:10933000635CF0C21F197CAB8917F9F5B78D978371
-:109340009E48C2FC8D6A384A1D92CF0C74C0F976D3
-:109350003AE9107CDB8D791314ED8CC314F105A56B
-:109360001E4A9C52387F127AA9184FC053F02D31F3
-:109370009E81D4CBA940072A3E4606A9F554A5DF15
-:1093800043F84970B0B038C6F09EF804B313437E7A
-:109390002FE6E790B3739A08E8DF16E1D7F0CF879E
-:1093A000E7C2AFA1B6EFAF15179DE991028FE44474
-:1093B000C643457C952EF3D38FE8C7A3257B268C27
-:1093C00037E3958136A289E697739C7895F6236BEF
-:1093D0008289E1FE32E1BF7E530AE0BC7F409C3FC0
-:1093E0002561FA422D699D303F07FC9F546EC541AF
-:1093F000C9FC3EA45DAD97B278A286AE04F07B3581
-:10940000098B17E684DAB12E47D6459ECBB5E4FB2F
-:109410000D2916EEEF60F93984F33761BFF5662F39
-:109420008978FE413D85495128AFE5E5646E6716B0
-:109430009002E89FD2D52BC9689F533A94C2E9AEF7
-:10944000270F06DB23E84EB57E11CF97CDC5E87711
-:10945000591ABEDE6F000FA147FC8BAE0DF6E7FE7A
-:10946000643BD6D7F439F907273417FB15F98C7507
-:109470007A963F4C5A95FAF3C7C91AAE4F38E56F42
-:1094800002A7DEF781E785F17DF8A6FA90C80B13F5
-:10949000F03B23F86008DEE7147CACC76EEB81F785
-:1094A000B9687C4EC0E36289FF69D827D97C2C1942
-:1094B000E0FC0FB3EB22BC9F79227056D284E655B4
-:1094C0002177623EE8A57619EDA4DA312C4FA87613
-:1094D0000F06CD49578701E382D5ED6FA07ED6D91F
-:1094E000481969FFDEE1D4B35E15BC7BB357C47A7B
-:1094F00074294A7C13F922749D312951F3017AE0D1
-:10950000A06CE77010794A15F2E0F840985D728817
-:10951000EF7B8CD6159F42C72F7E3F230EE0532151
-:10952000771C4A07383448785E699C8178C0DF9F91
-:10953000C6CFAD8D08D43B2C141EA919263C7F3410
-:10954000F087B20BE299A71AD627C0F9AACF1BE978
-:10955000D0D4EE1828695C886FE4858F7F5C0C712D
-:10956000B60598A7BCD0C0E2FF393F8AF5F5A37CC9
-:10957000E2753D3102BDE972EBF17C46D02AA3BD14
-:10958000912493F1805F02CE49B16C1DE279E963C9
-:109590004F4A90CF249E8F6B0A0E5D07F94CB0EFB7
-:1095A00025A1758E2B0F0EAD3785E02CF204893680
-:1095B0009835238C3E8E7078D4DAF49B411E761950
-:1095C000B91DC8ED4162D1221F69E0F1F69303A8ED
-:1095D000458AFDF8CC9097551BE38C1F0EFE2EC8D4
-:1095E00027A0C5971667BC15D76F47BDB981EB5744
-:1095F0005D3CCFBB6172590AD853BDE53F4D4D610B
-:109600007A7E0D8F838BE7355A1FE62DD540DE71AC
-:1096100058DED3B7CD3B16F9E6BDC2C1AA255A0A1A
-:10962000875A89B8AEF6DEABFF92A3DABBEB5334B0
-:1096300057CD835B952229F2DC6A21CF8D3E6AD813
-:10964000539A42A2F4D7236F2EDFA8C8271379D2EA
-:10965000B597C7623E59F9CF3AF19C20F46337853C
-:10966000F2DC7A83F3916406E75AC80F1B1AFE9C5A
-:10967000E151A8FF24DC875F0300C1DFD12EA35F87
-:10968000F6D7873593764699EF76BEFEEB6D5AA4F2
-:109690008F1B7CC4D912657CF19E38470270AECC1A
-:1096A0008F9C5F5B596011CC1FF257A38DB795E378
-:1096B0008B98775B42A08AE3399EE3E8A95B94FB31
-:1096C000F80CDFC7B69B0259781E6972F47C7AB138
-:1096D000DFC3B4F512C02360761F44BD730EAD0C1A
-:1096E0008173003E0DCBA36274D6DBBE87E0AD5123
-:1096F000E41546C25B8FFB2CFA1376C9F9ED32C62E
-:10970000FDCF1FE574499C2689D2D7AD5C6E9D279D
-:109710002C7E70BE59427B64899B900D94BFDCFA0D
-:10972000E46A8CDF543D357433882B787E07E5235B
-:10973000B7A6123296964B3629E3B7CBEE8E88D772
-:109740009070F948D54FB4AFABEE577E574DEEFE53
-:109750000BE83FD52AFD6620F777ED4DE1F6C230E4
-:10976000320CF8FBBAA7BED043EA6E6FF8FE39A5FB
-:10977000EBFE5AE083162CDF4D711E003EFF718A0E
-:10978000FB4DE0DBDDEF31385CAAB9C4F8FEA3493C
-:10979000286F0CC09CE9FF1AE6B338ECCF28BB80D9
-:1097A000F89BC1C0F41BA1D7C9F27A398EB68FFCE1
-:1097B000734302EC5FD2B3132781DE6F7B36D60989
-:1097C000F0DA5AEA2C043FC0D64A13E633180D2CBF
-:1097D000FEEBFDF5C8FD100EE8DF7A6F19D8A196F3
-:1097E0008E7D3EF0936CD1FC05CFA16C19CBF2DDE0
-:1097F000C438751D95BB613E59B398DCD89AE32CEB
-:10980000B484F54BB89E56CB61D6BD77E03D70FE73
-:10981000FD91C3A826D3F5E5A23FEE7AC2F653E444
-:1098200055C1D8E1FA6827953F909C27EAD7B74AF7
-:109830003E1D5DCF9AB6DD18C7A8B9D3973C1FE48B
-:10984000CC335A8C0389F925BD9E5606F11E215F43
-:10985000E64B1694FF42DF9E47C41F8B17CDE57879
-:10986000308FEBD9F363197C971047167C778B9177
-:10987000C4819F7A7E796B09CA9FD53A2BE835223D
-:10988000EED1BB3E10DD5F54FBB4999DA795827964
-:10989000D0C9E7D4FE20CC6F14F57C52522AE3AF36
-:1098A000B5795CEFEB4F9C1067AB7D6D600BF805F5
-:1098B0000C7D583C96F21DE38822D47B8D60CFACA2
-:1098C0007C35C6C7FCD65E7E6ED6590879217533C5
-:1098D000328A303FE104E51F66388F18C8423AA546
-:1098E0007C45A2B22D7FBB65AA16CE0DA653BD8ABC
-:1098F000D6E7A7664DD5527CAFCD0D546968BD69DA
-:10990000FB7056BF3E7016EADBB697B17A51A04A9B
-:10991000A6F55DDB5DEC7B30F02862BDB47DCE54F6
-:109920000FE813562EAF1D013C475CFBCA404DB8F3
-:10993000BFB22595F1A5CFB9DFF5F31CB27806C00B
-:109940007B5000CFA989F77E9A2AF45C96E72BD644
-:1099500029BE23A9D1FB1F9DCAFCC42BF9F9DF71D5
-:10996000B1644B0C8B5779E228FC0F740CC4785B04
-:109970004E6A028717EDA738D48F80A3E84F8CBBBF
-:109980000AE42AF05B1DF39B8AF6C9A98C3FD271C9
-:1099900036E1388319FC6B676414C2BED1FDD2F284
-:1099A000FDD232FBB385CD8FF66B2D40FE3E14FC0D
-:1099B000DE07AED0F77342F356E3C70F387EAC6CC8
-:1099C0006271C6A0B51FE2D1B858A6EF9162E53A20
-:1099D0007671F8B5A45A997DD5B31F29128ED3C4D8
-:1099E000E19841E19EFFEDD75DFD3DAD3B6CBF9C35
-:1099F000709EFF40FB753BC3D723F2B6453F9F6F78
-:109A0000547D3782E54FD526F4C3EF7E16438CF89C
-:109A10009CECECF92EA780E999A07F8AFB1D886752
-:109A20002C3A0B6A38D7E8B9AFA195E711F677B2AF
-:109A3000F3CA33A616F3F559F8FA2CC6B07B1A7A96
-:109A4000E8F158306B9639127F7BE0DED3DFE022FD
-:109A5000DE9F82AEA3F507F4D1DB7E3CCCF1E3DFE1
-:109A6000B61F629E2A78F6C059353F014FA067FCA9
-:109A70006EB0121FC53CB7A58ABC61155DE77CC7F7
-:109A8000F14AD9776B6EE3F9C076253EAF69CBD149
-:109A9000401C5D7C37097CEDB690DF6D6F2AB7DF27
-:109AA0003248462F7970FB52A3FBEBF0B9DA7EEB1C
-:109AB000B6B2FC67B5FFA0DBE6F0C3B93ECF457692
-:109AC0009E7D944ADF8038CC0BA6D0772179A2AC5A
-:109AD000C7A531F845FA838278FEB6D850F6A2DDE4
-:109AE00041C847DBD7207F2E8E2F5B9F43EB81ED54
-:109AF00075ACDEB7EC8B1CCABF4F6FAF67F51BCAE6
-:109B0000BEC8857AEA5A561FE77C51C608C2DAA950
-:109B1000E3D342FAC3A7A976A67F946B08E09141EC
-:109B20005EEB003929E0D95B596CD0D447D34F3B69
-:109B30007BE899C5294670F93C42D8E701ADC23EA1
-:109B4000EF8E63E793BB419ED2F5FE3DD5FD975462
-:109B5000D053623B17E5D0AEEE8CFD580FFA90E47F
-:109B6000A4FA06F83BEC16B200F2EA3AB7BA403F64
-:109B700022AB1C462DC293FB9FE8DABEA6FDBCFAC1
-:109B8000DA33B7F765C3B8601E2339FDD7BDF6D504
-:109B9000DF204E5AF7B9C901EEBD911D3BD6837E39
-:109BA00035B2E3ADAF98BC65E735C4BC47821F91C1
-:109BB0003E1FD16EC0F98FECB86E39BC3FEAFD8E06
-:109BC0007E801F634EFA9A801D74EFFD5D5FC5397C
-:109BD0000DF299F45DCE69F4C0E3CF54798A4778E9
-:109BE00024A6D9001E57305FAACB76747300F534D3
-:109BF000E57918AA97639CF512E9E380788138F734
-:109C0000ADF65B9EA8A4EBA3CFC704E90CC2F4E5B4
-:109C10007197A97D1FA6679712ABA25E6E4C53BCCD
-:109C20005F61C951B44F4CBD4ED13ED95EA8A84F1B
-:109C3000193452F1FE3447A9A27EF388C98AF72B62
-:109C40009D958A7AA1AF55F1FED0C3EDCAF6637631
-:109C5000DC87A1275DE5A0C73BFCEE262887773689
-:109C600097C7DB4984BFB638E06D82E7A3AED497CF
-:109C7000F84894732CABDCE8E78F38C752CACEC3E0
-:109C80007769D8390EE19FBD12EB9E9486FE590A82
-:109C9000760AECB1C66022EC57C5E26D983775299B
-:109CA00048D09FD5A60FFC7C14C8F98532EABD6D5B
-:109CB0003CDFA66D6EBE177C7A27A4C0CB10AFF731
-:109CC0002C64E704C6500D17D70DB14D09F6C9AD88
-:109CD00058772959A9DAA7B58A7A85E536C5FB13DD
-:109CE00053372ADA27DBEF52EDD3BD8AFA34C70E99
-:109CF000D53EB5A8F6E91945FB9833812620A37116
-:109D00009D1ED94CE77FE389E672D89751273D0B1A
-:109D1000815E8A7DEE2660872507EADF80D247EDE7
-:109D200029F053ED6F4CC5F240A31DFD4C871A0777
-:109D30006179B8D181CF7FDF3802CBB71B9D58FE48
-:109D40004FE3242CFD8D2E2C5B1B5BF1FD171ADBE2
-:109D5000B1A410CC04799194D8730F4326D8F35D45
-:109D60009A402D4452FF3B6D1FF2C5AE3E812EA896
-:109D7000DFE9791DF9E24A30A628BDB54049F7F37D
-:109D800067E94E299D96DBD2D873919FD0AA7116B0
-:109D9000827E7D5FDA91BBB59954AFDDE84AB55854
-:109DA00059DD48EBB8D998A775E46EE768427E03A1
-:109DB0002203832647A642BD3B86B56F4B3B82FA02
-:109DC000B58823CF0AC591EF03BA57C7917F73CEE9
-:109DD0006E067FCAD12B03CDB0AEA3DC7FE4248511
-:109DE000BA5B6959AA2DD4815C3CA1D2234459A7FE
-:109DF000297D04FA6DD53866637EF04D3A02F9E8A4
-:109E00003324668FF6E881E94C1E754F33A0BD738D
-:109E10004CE35C8E794F52F07180D78B3B3E44F817
-:109E2000759B83590087DD3B4EB0BA2DF8B8E40826
-:109E3000ABEBD83A7FBDE383A91E53D4753E9F1682
-:109E4000255EDE96C6CFC7FA9C99207F45FD58A5B2
-:109E5000730DC88963A5CE01309FA32E03D28FC78F
-:109E600065F642DE25D13A4B6687F9550AD275B8B8
-:109E70008E597A4667E41639EAB9F3A9E94CCFC29C
-:109E80007D037B6E5E2CEAE1C734D1CF8D2FE3F0EA
-:109E9000B9D027BA7F65793A93836533CDD85F7798
-:109EA000430CC671BB5D03510FEAAEA750A2F4D1BB
-:109EB0007DAEFEE24BD86E10212E8C57CEE77CEAA9
-:109EC000371DEBFF7A9CBEFF7143AC0379B8E57A8E
-:109ED000944FB7F09717261A516F593823B30CE4F3
-:109EE000D27C1EF75A64D62663F84B6BD5C39542D5
-:109EF000CB4C859B41FC572555EAADB45E9DB176B0
-:109F00003394ABFADFAB87A39A3583776F06F5718D
-:109F10000D25AD12B49702EF34D2792DDE20DB99F6
-:109F2000FD24CE1FAEFE567916020F8FF17C190A62
-:109F30005FB40BABD225855D52C5E1F5651AD7DB61
-:109F4000F249FED7CA78CE65C093CE85EFE4F5E23C
-:109F50007757B673BDED0F7A36AEFADE0A31EE0AE8
-:109F6000BEEFC7F4C429811E778B19F1A360EE17E9
-:109F70007796D0F517745834188F177CDCCFEE0F16
-:109F80002B39E3463E37BC33F0F4718278DE0E7431
-:109F9000722D3935D3B311E5C3C82FA9FC01BE78A2
-:109FA000C5FDF1716C4D8A7A2ED3D758CDF9633D3A
-:109FB000F2B5038D1BB07EA8D183E5E1C62D9C3F91
-:109FC0003663FBDB8DDB397FF472FEB80B9F773491
-:109FD000CEC5F2B5463796FF30BB32D3812E8C6E9C
-:109FE000CCD33CB8C3406488377418104F29053C63
-:109FF000FE4812E4C1182C70FE4E9D0FA3E6B73D3B
-:10A00000FBDF16712FC675304E4FFE0BE867D9BDCA
-:10A01000E3CF516237033F294DCF9C06FCE3A8DD17
-:10A020006E06BDB5EC615AA7DF1E75DACD3A5A2F20
-:10A030004FCF6275B7DD6CA0F5F10FF3BAC76E8E26
-:10A04000A1F58AF46CF6BD9760B0FAA6F4FED38051
-:10A05000CF9612E900D043B931673CA4CE56584A96
-:10A060000F001D4C4CBD753CD0C19E343BBBEFC2B4
-:10A07000BEF100D4A70C6AD1C2911BA7A970137CB2
-:10A08000579654A985EFC667ACDD04DF4DE87FAF76
-:10A0900036FCBB4983776F82FA54478B16F4C13D77
-:10A0A000692C0E2AFA1175D12EF8ABC8D71AD2E155
-:10A0B000423E5ED0EE423E2EE05236ABF2A7E0A723
-:10A0C000AB6B972C12CC6396D41384879CB8DA2B95
-:10A0D000945A289F9D973EC4BC917E5707F51BB1AB
-:10A0E000BE6D6374BEBB283D8A7CF980D329C84D00
-:10A0F000C88BFE40CFEEF5780DD687FEC35BCDB79B
-:10A10000627F6E33C8D703694C4E1EE6E5655EFE7E
-:10A110009397751A6735C8CFBA741E4F8CA4EBF5A8
-:10A12000E98C6E55E7057A69E774FDC3741E5FE636
-:10A13000F727AC21EC5CD1B5F2B65686DB6F3990CF
-:10A140009FD37A08F246D579103570DEA85F643E59
-:10A1500030E58B2CFFB15D9947DA637FF4617C0FAA
-:10A160008E3182D1F1F3DED77DDF35D67D5FB475D8
-:10A17000AF242CCF59BD0EE2B6216D89BCE7C8F5DE
-:10A1800004A2AF27621DFC9E3E55BE35D58376C224
-:10A190007C2A169B09F86FC2F9C4F1ABF00935DFD0
-:10A1A000F977F1B3ABF09BDFC13CD5FC469C7B5605
-:10A1B00097429F83F352907707F7BE809F7E63B2EA
-:10A1C0007B3FD0477759F06F1AB0CF92028867690A
-:10A1D00056F741E85FD2B3F8BBC8673DA7F1FC165C
-:10A1E000F4A2F7D25722DFE902E140E9F108AD839A
-:10A1F000DE33D2E27A0BFA238318FEF496A7799421
-:10A20000CBC5C89228F215BB5BBECA423FD635F01B
-:10A21000BD373854C8A303702EE0D2885854793A19
-:10A2200025E2938A20EF3A19F588CE4CBD16CA7FF5
-:10A23000B79DD8999987FDABEDC5CEB4114636EEE2
-:10A24000844950B6EBDDDB6F053B69A401EDA477D3
-:10A25000799EDFF4D35792405E4D977DC90552A495
-:10A260009DD979644199BD20D2DEA4EB1B0FEBBBD5
-:10A2700096DDE932FA13008C6AFBB366C3DF08E4AB
-:10A28000478FDA7085C0FD65D7B647890C6CA2E8A8
-:10A2900084E30D284BCE38311D67D8B9FA37A01C9E
-:10A2A000F92533CFAF955774E3E5D637D831F1C1EF
-:10A2B000CA7B1746BCC5EC555E46DCEBB6CAA3CCE0
-:10A2C000572BF595601E851C8883F2A21440BF971A
-:10A2D000AC61F731887B18A81D9BD3D706762FCBAE
-:10A2E0009B1A07F9467472153FFE70D1ED48F7319D
-:10A2F000A8FFF4D8B12F69304FA04DEB8C1F037627
-:10A30000EC86018E8DB4FE27BFED8157695967F940
-:10A310001B09BFEFAD66C32545BD7363E8BE20C80A
-:10A3200087AEF9978C72A786902DB05F3564BF7E9B
-:10A330005D981C24AD7FE981FB10CAE72A017028D3
-:10A34000078DD39DF4BB4A6E6F107217AB733B8BB6
-:10A3500078CE4DC3BA8DBFEF59C0DA3345FBC2E9A1
-:10A360004E3A4EE500D1DFDE69584F1375DEDF75DA
-:10A37000A2FE007B3F477CFF12ABE78BF1DF67E378
-:10A3800099D9FB373D72DB74E00382BFBBFA2AEF39
-:10A39000F9A1FC7E565FDB55F34A94ED5C1E887B89
-:10A3A0007D2A7E3C39F61DA0E7560973E06AEED09F
-:10A3B000A17FFB42426B41F839659187E22A373B26
-:10A3C00041DF5BF3F2C09D32CFCB017DE37E9E8FF8
-:10A3D0005F219B301E71E96EC6E77BD3D7AA36BCDE
-:10A3E000A2D8CF88767EEF3206EAE87817B7A56064
-:10A3F0009E3BE9EFC778F8BABE92B8BF11CFB98AD1
-:10A40000BCAFA47EC409F669D2EF62D8BD9667FCE2
-:10A41000C87FAB7EC7FCBD6B76BC81726E896C4712
-:10A420003C7E27C7BD01E0D36566F717566D780DF2
-:10A43000E9B5299BEB0996E0E070787AFA72B91CCD
-:10A4400082FFA6BE255785BFB2FD7B86BFDACF2C23
-:10A45000CE49AFFA96F9695D66160775F07D3AAD9B
-:10A46000B10FE3F07A1CD67371B93FCF2A43F2B033
-:10A470003F99E51DBD5D0276D0A57A33DE77B460E5
-:10A48000FDA982F0F329A254EBFF9D4047B610BC12
-:10A490009E8BC4EFD66BE077EB7F12BF53B401BD48
-:10A4A00003E2A627D8FD63C3FCA7F5E1F92EFEBEA3
-:10A4B0004CEEC6B7B338913A6FCBDFD7CCF4241E3D
-:10A4C0008F5933E3EDD1108F11F4302E96B4827F83
-:10A4D0009DE2B583E3B503F05AE06F282E43BF8BAE
-:10A4E000425F21FC25388E80D3079170FDE81A78F1
-:10A4F000FBD17F126FDBA8FE8B71CC9762D07FA25D
-:10A5000086F3BF385C05BCE333AE0EE7F88CEF078B
-:10A51000CEF11976A5FF81C3BB37F9A4DE1F31EF59
-:10A5200028745AF25DE8F4E7999C4F6903982FAAC2
-:10A53000DEF7E48C887D4FCFB8FABE2BDBBFE77D1A
-:10A5400057C34D5DD6F0F8A6FAF9888C5EF9DDBFE9
-:10A55000058EFFBFF9CF17D6EF53B42FDE7044D16D
-:10A560007EABE73D457D74C05F0E682EFCE163CF96
-:10A570000551BFFCAE7EF5DEFCE9D35F5CA18178BE
-:10A58000DB083FF3E7FF35D3BD2D83C2F95D8DB7FF
-:10A59000C94CE13AFC642BBBBFAB3A0FF387D6F34F
-:10A5A000397E31FAEF1FDF4EF1E60B62407FA76F75
-:10A5B000DF755A7B7E241E945ED61067581E5AA9FA
-:10A5C000D1AA75A2BF8638A3E1CD7D1C6F30FF876D
-:10A5D000D2FB5C23D125513A9F3B57C27CA7B9845B
-:10A5E000E545D3D2E7A6EDD3B5C407F724579AB40F
-:10A5F0003E03C6F994E79A0DFC1E659294A838DFD5
-:10A600002C3B65CC4B9B3D82C5076F31B5E2B9D27F
-:10A610007987EFBC783B6D279B3C252CEF5A9C43F8
-:10A62000FBA3E6DBC4FDEECB6074DE2DF138B2A4F3
-:10A63000C37BB222E44106F38F4E9737CA90EF12E4
-:10A640007C8FA0DE2DE88EAEEFB0A1889DB380DFB9
-:10A65000B1A8243ADF403CF77C6F39BC5F73CC8EE5
-:10A6600070A91BB1B100F6B16EBCF489A12064D70A
-:10A67000D46DF812FBA9909F6B82F72F9D60AEF00E
-:10A68000E19DD44EB187FB2B038B802EAF65FF88F5
-:10A69000799F6CF4213E7DDC7818CB77C7BE5502DC
-:10A6A0007A46A0D11FD52FF95DFD03C22F20FC04EF
-:10A6B000820F88FBF93A32385F304A7DF15E352DE2
-:10A6C0002B05BFDC1FC95F0F655C5D5F51B67FCF97
-:10A6D000FCF59BE2794D2A938B6AFC56E3B5C06783
-:10A6E000B8FF1B7EBFE016AAEF815C9D4F3CF93599
-:10A6F00094CFCE5DD1AC1B257D77BC5E653A93458A
-:10A70000A29C37F9F6FCDC8EEB97CB65B40F447E48
-:10A7100082D887AF3222F4F87F5E432EFEF33F29C2
-:10A720001723E5DA9945DF4DAE11853E909A1981E0
-:10A73000AF199957C75765FBF7BCEEB073308B6400
-:10A740004DE8DC07E40F831ED7ED65E71AAB739A7B
-:10A75000F1DE79322218077AE3CABD32E221D13A1A
-:10A76000B56961F74E7512DF1F001F578C5E81E7D8
-:10A77000E122EE8B32B5E1F938F5BD51225FB89692
-:10A78000F7A3BE3FAA96E709D7AAF2764A33797EA5
-:10A7900070112962F9154ABD545D763512855FB294
-:10A7A000EB4A23FA01263FF6D2CF3DA343FB707359
-:10A7B0006604BECECCBC3ABE2ADBFFC3F82A9B9F00
-:10A7C000C47351DF165F0D766735CC5BF0E1059001
-:10A7D000C345C75DF0AAC10BBF0F20EEC9EE96D8E6
-:10A7E000BD34DD9F10F41B5DEB9EE591C7DC78AEB8
-:10A7F00073F8DB4E99E511B07C03A1A708BD655441
-:10A80000675066F7E1F3F3503C2FE89BF22F87DFA8
-:10A81000827A8EF0BFFDBBFCD642CEED35DA919E3A
-:10A82000857FB038E0423DAE4BE72B817BED3D7B31
-:10A8300062A2EA013B323557BDCFF51F66F70E80A5
-:10A84000FB4CCEDFC5BDAE1532BBF7F9925F46FFBC
-:10A850005DC34FDEFFED23F66BDBF575964B51EDD7
-:10A860002251D669D87989A2723BE6ED81BD04FEFA
-:10A870003BE1CF53BF7F30BBEC59985F853C1AEF6B
-:10A88000D9BCB49DCDA7B77DA9DB10C4F17B6DE722
-:10A89000E3D7ED2DB184DF8BD199D9639F59CE1ABF
-:10A8A00043FBFA4DF77F4C70AE42BFF97FDD6E98E7
-:10A8B0002E53D591CAC77CC9CBF453C2F4D405C476
-:10A8C0008FE52212C4D24D583EFD12E2C0721971BA
-:10A8D000613927DB1DC8C4FC966032E643BEFC8F9D
-:10A8E000C1803717C78E6A86DCB9EF4B4FEB2EB4A9
-:10A8F000E3F8DD2FFD230BF25AAE794F7E9CF38BEC
-:10A90000CC28F1E4FF2995317E428AD721BFAFE4FC
-:10A91000B72590F12C2E767F720EE24388FFA5B406
-:10A9200008FE07F1D6FC4F342C3F64A584F7BAB675
-:10A930000734485AF9CB73BC704F4F7B1B6BCF5F0A
-:10A9400063F54AB49E3F3286B5AFB57AE1DCC342C7
-:10A9500012407A5C0CA71E643807C3F89BB8079DA9
-:10A960006AECB9A0672DEF30B2FC7D12E80F7CBC19
-:10A97000A017FBE6E62CA6EF0FC9657C7B4899D2B1
-:10A980000F61E3ED0DD965F559B4FC719633398B40
-:10A990002E7548827FEB2F8AD12F8FBFCBF2D9C87B
-:10A9A000DB307E28BE7B24BBAC2FBCFFBCC4F2CD09
-:10A9B0003D7BF9EF17906072F8BDA273B2CB73A024
-:10A9C000BF415984DF531F1DAEF0FB75AE28F69CC6
-:10A9D000C8671C023615FAC3D9FD54CF4BAC3E32C2
-:10A9E0002BF9E64D26F4E17B40AF7D24DB5D84F35B
-:10A9F000D7136282F93F66F0EE44FDB33E0BFC9143
-:10AA00002B1E3768402FF8908A553857F251A31102
-:10AA1000CB53D4CE85F24FD4CE85F2136AE742F9F8
-:10AA200029B573A15C7ED9419186906359CE29598D
-:10AA3000B650BC4D3DDFF1598CAFF68CBF578FE35C
-:10AA40003764BB11BE3DFBBD8778211EF2BC359833
-:10AA50009E70157CEB9DCF30B888F89FBAFD463EBE
-:10AA60008F82362DCAF182F6405C55D87BF3B2D87E
-:10AA7000EFA9E5BF7406CF8976597AE0EB94E892A6
-:10AA8000A76B587D5ED660846F43B6B31ED64DE982
-:10AA90007B219405EDEFDF07E77968FF9847D02D1C
-:10AAA000051F443D5FB50E351CC4BA9EB7FAB7C248
-:10AAB000F7CFBF940B2BA1FC8630BA013C92A2AD1C
-:10AAC0007723CEF76643B018CEA9DCFCB51C356FF2
-:10AAD000B821BB14E16C12F826E0C4F7EBBBD275C9
-:10AAE0004F3C9BE32911F76C00EFB4831CBA1207AB
-:10AAF0007A5D258FD7B7B7F57F17D6E7392C930145
-:10AB000076C45F05DD3DC1F74794F97BF52ED8A7E4
-:10AB1000E7F79EED0FF7B0D27DE90FF7B2FE226B9B
-:10AB200000B68BEFF2477EF5F02F92F07DFCDDD082
-:10AB300079A4A502F249E61BF71D84252DB47C52A9
-:10AB400001F9248B53A54350DE6ACF990079242262
-:10AB5000DF7DE9A0D243404A531D95A88F9502732B
-:10AB6000099307E5C6587E29B4903F898AFAC4D470
-:10AB7000BE8AF727DBFB29DAA70CBA41D12EC69D86
-:10AB8000EA18AA786F48423017EC2FBA0E760FF603
-:10AB90005332E6DDE5BF74ECA61B687DFAD3B3F152
-:10ABA000DEBFE779FBF417CAF1F708BB293CF5547F
-:10ABB000913A37E2AE077F019DA9F4FB9ABD4F1C85
-:10ABC00072DAAFA2DF5F43AF17FC757587B104F887
-:10ABD000EB37D5F3D5FBE2CB52EAFDBDE14B0F3DA0
-:10ABE0004876862FFCDE2D35BE107227C73F564EA5
-:10ABF0003FCACE817D5B3EF667E06361E7307B4A0A
-:10AC000095BF6D88DEF1EE7AF0BFBF23133C57C7C6
-:10AC1000CFE755C1FFCB213C27CB5A7E0AF74AD15B
-:10AC2000E71ED03FE11CA893F67F398BEB4D35FB37
-:10AC30007E9A561C6A270D9F28DE2777489B15F5BC
-:10AC40004D39CAFADDA59BC3BFEF8D1F566DBF55A9
-:10AC5000EFC6F39B52D4DF7F15F3A9D81F83F97990
-:10AC6000D320EF843EAA2D7E4F0BF1D569BDC84F8E
-:10AC7000C177E6C9A43E5ABB9CCDFA9DBA3F06F304
-:10AC800059BE6DBF1F525862BEE0EF98FCFC30DE2B
-:10AC9000AF0DDFF7B86C89DF7B70EF4FFE0671CF29
-:10ACA0003D04F3372F5A19DF2F68FB4CA301F9D766
-:10ACB00087E14B8125A00179D25D1DEB81FCFCBAB7
-:10ACC0009566CCEB1C921BFC83B190A2FA2FEFB9D6
-:10ACD000C748F7ED8F7098314C9E76838D43EBD942
-:10ACE000D9F720BF9FB23FC6A7F90EEBC9A63A1409
-:10ACF000EA1B658CBE1701DE70B902BEF3BA9F92E3
-:10AD00001E3903FC00D60FF5D9BFBCEFDDFB41FFB8
-:10AD10003EC2E81B32E5D476FBFC30BB9D3CCAE862
-:10AD2000D248FF813EB7EA40B31EECB96BD3772B14
-:10AD3000E6CD7C53BA1E99CD7FB7A3773A3E3A85CC
-:10AD4000EE4BDD1E76CFC4A58E0178AEB537F95D2A
-:10AD5000B75D83F427EA5D1DF224C057F539710110
-:10AD60004F62C953DCE7B46ECCDF67809C5CB75799
-:10AD7000CB923D7A1B678B86D8C3C679FE354335A7
-:10AD8000FB5D4B36FF6E219FF7FE35A174302B37EC
-:10AD9000469173542EEB92402E57B2DF5D38BE378A
-:10ADA000A50CE07F5C223E3B9EBB6279C63359779F
-:10ADB000F0DC84F788A40ED286DF7728ECC8D97B34
-:10ADC000670F003DF20F6D4B8E3B813D64F7C3F181
-:10ADD000E6100FEABDC7ADAE4CF0374CE7F1FEE32D
-:10ADE000D66027F0E3E363622588DFD3FE3791B0B6
-:10ADF0007BFB8EEB5C99EC3E0891577CFD77BABFEC
-:10AE0000AD42BEA3740AC4AB17100BD89137CB4C1C
-:10AE1000AF25AF33BA14FCAE4EF227C03CE764CF87
-:10AE2000F8EF6C3AEF940D3F47BBB2076E5AFEBB8A
-:10AE30004FDF50AFEDB15F7749EC9E1207D3F76B50
-:10AE4000475F78600E9C73A376B644E7B3A47D1F7A
-:10AE5000DEC7A3B6AB7BEC9BFFA57F34D23E726D01
-:10AE600087F509BFB7DA4EEAD1CB857EF714CB73ED
-:10AE70007F63CC435DAB69BDE1A95884E3F9C70D9D
-:10AE80001EE0DFE7771AD0DE399F103CB91EEA2FAB
-:10AE9000E43B3C385A1E9EEF12F8BD4263FF00E4CB
-:10AEA0000EF9BD0EEFDDF8EC3103FECEC7CA27AEBA
-:10AEB000DB09F6D36799F6679F03FFDEB336BC0F55
-:10AEC00080A4B2EFA7717A04FAB2D3FD907F6546F1
-:10AED000BD61E58B69C8BFC4FE9D7B2C06CFC19FB9
-:10AEE0003F3C331EFC609D9ADDEC7729659307F8A3
-:10AEF000F0EA9D31A8F711BDFB15587FF9AFA6CD3B
-:10AF0000190AE3BF6F23B09EEE8E17D1FF18DADF68
-:10AF1000E872FD52473FC6077AE42CCB9B5D1CBA12
-:10AF2000AFD907FDAF21E23E4496375B244BEC7767
-:10AF30002AB7453F07FE5E36B3D76A84BF2491180F
-:10AF400053810EDD84DDFFB86D20DEB77B3E3B41D3
-:10AF5000D0313FEF28F0ED64EDABE82F31B07CBD90
-:10AF60005EEEB73C95CDCE055719BF54F84D6A3704
-:10AF70005C56D607B3DF6D2E6AB20F5D4BCBF51C66
-:10AF8000CE9A5457209B7EBFAAF5DE97DF46B83C89
-:10AF9000FAA33FC2B8874DE8A7216F33F8A9ED9710
-:10AFA0002A6390C71D5A147AEFD91D1F60FEC8D9B5
-:10AFB000976EC0DF2B5B22FBCFC23D595D66FFC79A
-:10AFC000B7D3F285C347715FD4F38D88C34B8CAF81
-:10AFD000D4C03A8642FE8AEB6FD948B78CDE4F6FF9
-:10AFE000CD47F8093F6DF7F9E8F69598A7E85FCCEB
-:10AFF0004FF42FDED3DA997EFF7F0189AF015A002B
-:10B00000800000001F8B080000000000000BAD58FE
-:10B01000096C14E7157EFFCCEEEC18AFD7EB031FDD
-:10B02000F1C1EC1A8C898D3DF8AAB1A12C36A60489
-:10B03000A17639225CCA3169C25188E3950D154A5F
-:10B040009118675B2E11C555AB88B469BBA1224529
-:10B050002D515C07901B61BA0435E0364D17052968
-:10B0600034B5E8D46DA8D5D8D8A569232424F7BD74
-:10B070007F66588F316D137557F6F3FB8FF7BFF767
-:10B08000BDEBFF3D26252A332B007E56A400D401BC
-:10B090004CD26719C0982F5199E1A5713F1F1FCB62
-:10B0A000441ED701E800B301DAE8CF6AA432B8B38E
-:10B0B000B391B631350A7C5C874C4EE31ACE3F9D86
-:10B0C000F726B86A683184E51C80C7C1FA6467B99D
-:10B0D000A01E6003FD8D473FDEF09BBBCC07B0098F
-:10B0E0007ADD50027043E8DE278900A3BDDF716B73
-:10B0F0005E5AB4C27FAB0C80E91F0893E5493DA7B7
-:10B10000530017D03AFA4C8A497DF566288BA09CEB
-:10B1100031BF5717AA00E629CC754BC6E92228A2F1
-:10B120007538AFC66B91F679D428EAB34F082F5023
-:10B13000D0EEA7A5782588C97DFB048D8F8FB277C7
-:10B140007640908E8B5786D300C6332460E94867DB
-:10B15000AB8910E2A1FF13D4532867DC0D6D7D7815
-:10B160006E6D8B10E9E376B8860DD44F00C6F5AB53
-:10B170002DC771C475298DCB96DE011CAF72AE4F01
-:10B18000DAE3E42F2902B7AF364B88F4563C88C780
-:10B19000269A477DA310170957FC6C9011F7260BD0
-:10B1A00077809008E897672CFE19D91B172B516FF1
-:10B1B0009FAC8B684FD305F40BF24DAEF825A22C53
-:10B1C00004B01FFD0BFDEED1FB7A100E79E52E9237
-:10B1D000D368B997A1ACCDB8EE108B009D2B430F6F
-:10B1E000A7C75882EBF17998E034047E1751849F09
-:10B1F000D31510E6742544385D053D9CAE865E4E41
-:10B20000D740825378341E85009D74C07F2B15C9AA
-:10B21000633B8549A4B51B21D2EB7D108703164EF5
-:10B220000FC74167148F9F168795A0E57179D3F1F9
-:10B23000282CE3F13D1D0F0FC523FA2D056279443B
-:10B24000978221125D46818B729683E222BE05426F
-:10B250009C6FFD1F71683034975631031E2D33C724
-:10B26000C5B72C3C66118675493FF52B661DB0FDB0
-:10B2700005A86778E1837EB4C76B539BFFA1608903
-:10B280008829ABC2AEC5C8D734779520FFF3D8461E
-:10B29000936F6A7E2388FC1BCA97C3AE7C8AEBE659
-:10B2A0001AB70AD0CD36855720AFA5F82AA18A0A49
-:10B2B00047A940F1B3D76FE2AF75EF53FD98475AF6
-:10B2C000915725FB640F6286F889252234202D5E74
-:10B2D000157FCB8DEB5648DAF7291FDBE5B84F41D8
-:10B2E000DCF776B7E602DA7B5832D77B709F5C9D3D
-:10B2F000B40BC7F514E4FBFACABB58F0E1E7A3DCD2
-:10B30000D32457EB9EA703E9718EA9A6279B73DB75
-:10B31000B04E8C26DC704C499E7332577B4D413CBD
-:10B32000412E05F27B816CCA19ED2B2F27BFF42B20
-:10B33000661D85EC400DE136911BEEA7F5E36966CD
-:10B340007CF5530CCE7E383594D0796586F1F10FBB
-:10B350005101DC3FA8681768BE23F55E29D5A5DB3F
-:10B360008BDE3B64049271CAF0FCCD687734043103
-:10B3700089D79125FE5B5847017D3089FE1CDF8E01
-:10B38000721087DAB01675E3F0E7364FD463912276
-:10B39000B957B85CC9285E84FBBEBBFEA664C6591B
-:10B3A000A11967561D1AB838F88D02930DC394BCC5
-:10B3B000EAB878F75F7F40FC3AEE78555A9ECCA702
-:10B3C00097BAC0478BBC8EBA61E75963BF272EFA84
-:10B3D000885FB09DD62D7D6FA884EC5A366444D327
-:10B3E00048CEC0FB05A61E565F087DC23E4B5F6877
-:10B3F00015A93803749E13631EC4AB93452EA71181
-:10B40000FF1A5375D4FFAF32C6473AAD0F79F3D167
-:10B41000AE5D965DED83A70EA521DDF5F2936BA0E1
-:10B4200092D2C1CDEBB7825FCAFF3DA7DDC97ACE0C
-:10B430007FA323D0CE0EB03F7189E2A0BDD7B9AEB5
-:10B44000038EFF9DEA4EC7D43A8F7A7DA2A465731E
-:10B450007F59FD0AA885A0BC9DD65EB2C34B7A0F6A
-:10B4600048310F43FA832ED54FBC953F70E3391E08
-:10B4700097F67A78398BFBDECEA7AF1D41DDB3920C
-:10B480007855BDEA0911EE55AFE686C8BE2A09B661
-:10B490008539DE311EC755181B0CE3E9F58C89A0F0
-:10B4A00080E7BC3E50A6620585370F86E0CF7393D8
-:10B4B000FA755AF9D42A9E6991300EEE3C057E4CFD
-:10B4C00049E81CFC715446BEF328D00AB843BF506B
-:10B4D000CE9D112146721A076BF2C8DF67ADFCF4EE
-:10B4E000E409A04CC1294599054A5992B7F1F5588C
-:10B4F000FE492DCB74CCA7A98F38F6A737049DFB46
-:10B50000F550A2A29EEAB1B93F23F4A863FD61DF22
-:10B51000CAAB14974B133BD6102E59ABAA1DF3F5AB
-:10B5200020F3FB435DA1578DE17EF8D8ECE70DF8E1
-:10B53000E5FD002222D9D764007C0FFDD138EA72E4
-:10B54000F83DC5C078C47529D7A7F81D7F3C8A93FC
-:10B550006F08601C50221542E1D43848E2ECBD8FE0
-:10B56000238F83415C4438A74931BC723C80533DF2
-:10B57000CC4DA7F9BAAB22C438EE5D6A1CC7678709
-:10B580009D78E7B639F1CED79CF816EC72E25B14E1
-:10B5900071E23B67BF13CF80EEC4AFE448A363FD05
-:10B5A000BC9E66073FFFC46AC7FA05B1750EBEFCB4
-:10B5B000F426C7FA85BD5F75CC57F5EF76CCDB7105
-:10B5C00035DDEF8BE29D8E75D3FD5E73F559875C9B
-:10B5D000DBCF3A7EFF9F7EDE37CDCFDDA81BD5AB1C
-:10B5E000777D23C7290DBF986AD6A5567149224495
-:10B5F000FE5EE256C9A7BF53B25AD228DFAD3E1451
-:10B60000B6FA101C3864F2569CA809F532D5D1EA76
-:10B610001BE1161FF2B546E43295E3FA919E96744B
-:10B62000858789E2C73861162E5F6A60E072E40B95
-:10B63000F23949DCD6EBDD623A2E6EBA178BF27224
-:10B64000494185E7ADB3E6598359D7D78652C0350E
-:10B65000058FA5D63850D346794BCC29586FBD07F6
-:10B66000F05E0E12DDCB0539160DCC749F544F8859
-:10B67000FC9EA4F17BD315A6B9896E9013C5D4BFE7
-:10B680007E92A3FD2880F5EAB6A02AFC9EC58C28F0
-:10B6900019354E8651D3D1AF87435EBABFE3DF8FF2
-:10B6A00060DD7DEE5A58AFE0EAFB0DD45FB3F439AC
-:10B6B00013D04E0710FF61E63F54837BDF6DFCA87B
-:10B6C00098FA8F474424B00E66F9423FA579FDF001
-:10B6D000920C5EA773D13EACA386A0F0FB83FE2C38
-:10B6E000E3EF818F48D8E229797AC4CDFB0E58EF79
-:10B6F000A32D165EF6FB68B375FE308AD885757A81
-:10B700004BFF158ECB9EBC517065F178E3F7A427F3
-:10B710000BBDD5C7C8A6508DBA6E218DDBEFA50233
-:10B72000F1D3F4C556B122DD98E1BE68D33D79234B
-:10B73000FC3D777FFF19B38F3C5CBECEE33669B723
-:10B74000297FF8682AEF2FC3478B9A8926E5DFE621
-:10B75000F2B744AE39E264DBFEDF3BE2EF09FD4FB6
-:10B760008E79237BC25D80F61BE7F3577E05F11BC4
-:10B770003BE7A9A77723FAED8FE4175BBEF1FCFC4A
-:10B780001574DE7FB7F36F1CDFA1830970CD4DDA2E
-:10B7900079F3E00DCE1B070D4EA7DB69BF336D2A91
-:10B7A000BD05652EF4CF049BA59E0C3C78CECEA0A3
-:10B7B000F93E1B5A9ED34C7D76A8487299B4D4E4C6
-:10B7C000F31B64935FB98AE8B8DB7B84DE99430C92
-:10B7D000420CE361330BFFF009B4BB3B47BB477638
-:10B7E00076EC9EA874613E7454195B19FA333F439A
-:10B7F0009BA47186D7BBFC4CAE6729DD3B4604BDDC
-:10B8000092612D587CB2702DDDD34766E9B7A9133C
-:10B810002F0AE6ADA57BFA8864E6C7F293C25A1DEB
-:10B82000ED58ECD7528228E74326C6793CFF82C503
-:10B830004EF17833A475693C9FDAE8DD45EF5D7A17
-:10B840006F8CA798D41F64DCBE0CA2B393B49C6A1F
-:10B85000258E2FB768AB78BC94D1FDE08407281FF4
-:10B86000F09C9040E70C7862A790CF41DDE99EF212
-:10B870002BC9BCCF57FFD213A7BAB143FE98FB69BF
-:10B880006E30C0E5649760E5C27DD92F786251D2F1
-:10B89000CF4814AF45FD7ADC787FA1F7F4759CC7DB
-:10B8A000BC1B7B7EFEC96353FC313768BE87E02931
-:10B8B00000733EF7159A6F1F1CBE4975E4B701ADC2
-:10B8C0008CEC1F16947AAA23EDBE4B12D59FC6A00E
-:10B8D000C2F7A1BEDC7EAC07DF641C67D9FF178C02
-:10B8E000D76D586CD2E9FD26682AED6F970D89E473
-:10B8F0006144F0FBDFC3EC1FDB9E78B102E9ED345D
-:10B90000B598CEB1CF453D1A498E6DB7AD4752CEF1
-:10B910007F8EEB1DF284237F6FBD74B894F264C8F0
-:10B920006DDEEF10678DECA816D9B675C87FC1C261
-:10B93000C55EBFD5F2A790177E2C887477E4DBE74D
-:10B94000DF5192F3E3ACE7EB1F90DF06BDBCDE4DA9
-:10B950003FDFDE3FDDDEF68B831C17B4772BD93952
-:10B96000C5DE8D748E6DEFD8C0FB2F56289FDDCEBF
-:10B97000F1A2844472C75FB95BACE0FEF60B576E70
-:10B98000501CB55BEF7D38EB7CC77B66E17B317388
-:10B990004A5DA75A37874FB3A9F7288FBDBFD0E5B7
-:10B9A000DC8F176601CF3B6BBD23FA297F67786F69
-:10B9B0009E4D08BC659ECDC37B1AF503ECBF54FFBA
-:10B9C000EDFEBBF79AC0E3726F00F83CE94579C021
-:10B9D0008CB7793FB0FF9F1065D8E7301E3A25ED50
-:10B9E00020C509685DBC3F8873BC2AC573DFAF57AB
-:10B9F0005BEF26B3DFD459FDA58EE490FE15E9BCBC
-:10BA0000EFD45AE7D6CB789F0952E9D6ADFF9B58C1
-:10BA1000FF5F38FA367F6FFD1B3AD0569240140014
-:10BA200000000000000000001F8B08000000000064
-:10BA3000000BFB51CFC0F0038AEFCA3330C42B3167
-:10BA400030742B33307C03E20E79841CADB02A07AE
-:10BA500065FA5F303230BC02E23740FC8E9174FDF3
-:10BA60006AC208F6525E06067520BF02482B0A30ED
-:10BA700030B001D91A40BC0BC8BF05C4CF80D84133
-:10BA80008881819D8F81C110888580581328EF0996
-:10BA9000A43FF161375F4B18BFFD8F0550F9A282BB
-:10BAA000A8FC3FFCF8F5B709E2971717223D4CDEDA
-:10BAB000AB911F1FC6EAB44F33D4C4371950F91FD6
-:10BAC00065181898E51818DCE421FC6B48F2114061
-:10BAD000B14F3210F66D3160DC01D55D66C06EEE9F
-:10BAE0001DA0FC13A07C0AD41C0004EB50106803BA
-:10BAF00000000000000000001F8B08000000000094
-:10BB0000000BE57D09785445B670DDBEF7F696DE8C
-:10BB10004216C2163A2C0A08D86C21084A67C3A0FC
-:10BB2000019A454407B5598410C822E27C3CC77984
-:10BB3000345B061DE64D147518079C06C380F35050
-:10BB400003460D1A980682A3CF2DB8208E336F9A24
-:10BB50007D3190002EAD83E3AB73AA2A7D6FA79B46
-:10BB6000E08CFFFBE7FBFF2016756B3F75B63AE7ED
-:10BB70005445359808194BC877F043D32512212432
-:10BB80002D9AD29FBF7F974EC82433FD974C48A172
-:10BB90006C23643821136D2468A275268EA11F536F
-:10BBA0000979B7460ACAD086D60B6413524AD8CF51
-:10BBB0002485D44BD7137231E7C5AA216E4224AF36
-:10BBC000972C1D4A53B78BCC8474CCDEAF2507214C
-:10BBD000CE1C0321FD589BEFE8DF64AF15FB12F983
-:10BBE00094A24EBA7C9AAFABAE7EE719BD74E55D08
-:10BBF000FC0374E5DD4A86EAF23D2A6FD0D5EFB941
-:10BC0000344F97CF0ADCA2ABDF7BCD145DBE6FF55E
-:10BC10009DBAFAD7AE9FAD2BEF1F2CD5955FB76DB0
-:10BC2000B12E3FA8F6415DFDEBEB57E8CA87841EB5
-:10BC3000D1950F7BE3315D7E44D353BAFA230F6F66
-:10BC4000D6958F0AFF5E573EFAF44E5DFEC6D65774
-:10BC500075F5C746F6E9F2B9E42D5DFD7CF307BA48
-:10BC60007CA1EB535DFD9B338EE9CAC7BB3FD395E7
-:10BC70000B3CB8B5DF25DDF7099EBFE9DA29C447DB
-:10BC8000814D889154626A26D5985A492DA636D29C
-:10BC900084E9864CFF9D64046DF074A08A50BC5BFF
-:10BCA0001968FDEF149ABE9BD3DBE91F08BD790923
-:10BCB000A1783B91754D269A6D2199E299C94C0264
-:10BCC000168A0A8E08C5B7148A771182A92B42F109
-:10BCD0006D18C5BB8819D34E914EF83D25E2C2348C
-:10BCE00035D215BFA74532304D8FF4C2B473C48D21
-:10BCF00069466400A65D22FD30ED1A198AEDBA4549
-:10BD00003C98768FDC80DF7B447230CD8CE4E1F7A9
-:10BD10009E112FA6EEC82D9866458A30ED159982A2
-:10BD2000F57A477C98F689DC89DFFB4666607A4DB8
-:10BD30006436A6D746FC98F68B9462DA3F5282E9C5
-:10BD400080C8626C775DA412D3819107F1FBA0C813
-:10BD5000524C074756607A7D2480A927F208D61BEB
-:10BD6000125983E9D0C863F87D58A41AD3E191A78A
-:10BD7000F0FB88C87A4CB3239B311D1909629A13D2
-:10BD8000F93DA6A322DB30BD21B213DB8D8ED46238
-:10BD90003A26F22A7EBF31528FE94D806F29807793
-:10BDA000214CBD91FFC2EFB9913730CD8BBC8FDFF5
-:10BDB000F3234D981644FE84DF0B2387311D17397A
-:10BDC0008AE9CD9130A64591B3988E8F9CC6F496A2
-:10BDD000C8456C776BA415D3E2C837F87D4224823E
-:10BDE000A9E07724476D0E0BFCEB05FF9FE93A793C
-:10BDF0001DE54BC46FF88EA6C446F16054B47E6C4A
-:10BE00004AB91DF24995E25512C5EF64CA0B811F6C
-:10BE10004EAC9482376751FC480D37425ECD31B944
-:10BE20004D347F176955017FFF42C276E0A77B47FB
-:10BE30009DEA1EA6F8FA6E5AA807456EF8417EAB39
-:10BE4000C29C7A03BF6D56C2F4FBC4D47D697E1BCD
-:10BE5000B4A7B43114D09B8E0FF84DD111FAB94B61
-:10BE60002101079DEA41E86114D60B99687E66318D
-:10BE7000F10EA5F5AB46996604E93855437D253E9C
-:10BE80009AFE22CB3703D2FF02E2A1F3DFCFD383A6
-:10BE9000C480E98B9914EF297DCDBCAF2FA3A702F5
-:10BEA0000AC42E1DC36174BA8BC90D5B6BA66FD01B
-:10BEB000D5B753081B4FD47F96F83E82EF813CD212
-:10BEC000AFD216AD47BF1F867A71BE7F1AEF7BBD1A
-:10BED0008132020AFF402763700BC827E2764E8644
-:10BEE0007999DDCE29F6C4F3FAD932D740A58F76F9
-:10BEF0009E419CDFCF2432A396F1978C2983B07F9B
-:10BF0000948701AB05FB9739FC45BBCF019EB4DD9F
-:10BF1000FB165F0B93A7EEEE08179BEBAAE042DB44
-:10BF20007D897051683BFBD5B74B9C56333813AFB6
-:10BF30001BE7C1BF57984840A2EB68DD620F6ECE89
-:10BF4000021C7623FF2C7171069A4A8141E57A49D9
-:10BF5000322C8190C63D492103AD9FB7C5BE19F46F
-:10BF60008096BCC0933E80F366956CA15556ECF963
-:10BF7000F9A1DFD07CDE2695500D832C487A229BD8
-:10BF800050B85D2B496CFC80776F1FDABF9F881F0C
-:10BF9000AF04FDCF27ACFF1689D151608B13E17A36
-:10BFA000BAA0A66A344DC3BBCB8A09E5E3A72858DB
-:10BFB000BB50FC5E60250AA494831B113E01F578FA
-:10BFC00058C817A467259A97DBE7E7435ED03F5D23
-:10BFD000F782A01ACDD3BF0BB7E9F31A78E1BEB749
-:10BFE0005AD4E066C4AB6E0C3E025EDE6E0C7E1C64
-:10BFF0005E0516356048457805810F382537C2A1A2
-:10C00000C4A28664DA4F0985239060C9EE87D30104
-:10C010004E0BB7595CC735E396D526EBF215F55DA7
-:10C020005CC73572F4E21BCF38804E1767185CC7C7
-:10C03000297F6B5EE64D394EB7ECFCB2224C057E93
-:10C0400094D566B96CBA7EF4F98BD55211C36FB72B
-:10C0500073DAA0C478B638C3E83A4E49F5EC362610
-:10C060006FCF2E33BB609CE6652E171B3703530141
-:10C07000AF454BAD585FCC2F51BF3FF4FC08A9230F
-:10C08000C7CCC0CF6959EFC4F513D293F2B911E907
-:10C09000A441FD12F0C64CFF7E67403CC2BCE8B72D
-:10C0A000A2560E98AE87EFDB75E3D176EE931AF9C0
-:10C0B00092986E1572528397F7430748A766DC671C
-:10C0C0003FEDD149FB6B516C6B408F9AC0F1A702D9
-:10C0D000EA517E50660E1BFDF4D3B93AB61F89C6ED
-:10C0E00039BB6C5B37E06B25E66A2330AB92DAFE36
-:10C0F00005404FE7EA56A6837C59285FFCB12F4ED6
-:10C10000FB5F08BA0DAAAD7A7919E4F3A4FDEAE859
-:10C110008CD8DAD64DF3CD063A94AD7DBFBF929858
-:10C12000DC29DF7E70DC683AFFF2FA0B4698C70420
-:10C13000C9FF2B292DBA7E09D64FFB29DD76C4080D
-:10C14000EB3BAD06AEF949D615E0D96E9EB68C93A1
-:10C15000499AF905A82249E975760EA757E2BEFD6E
-:10C16000534A9F67DE52C923741EE432AD45CB3378
-:10C1700079E95CE27300BC66D72D44FE7306F80FC4
-:10C18000C861529D0DF8718E188A607DE7C8FB8EDC
-:10C19000611AF8ED938C1C3E5495A5FCC084432194
-:10C1A000DCBA00BF32955435C983E1BB12E07C494B
-:10C1B000FA0EF94950427E56C2BE07887939AE63FD
-:10C1C0000DE34701FA07F2F756EBF9D3FCF5FAFC59
-:10C1D0003C32255DA1FC65DEE32AED91F2372DFFAF
-:10C1E000A3F07B566272773EA9AC72D1F96F34D25C
-:10C1F0007DA2F39FED224A37BABEB2573666CFA270
-:10C20000F9372526C7CE2EA3D3BF86F6D389ADBF77
-:10C210007469D0E81DD87E7DC7EA864D1F4DB03FBA
-:10C22000261F4B85FC256E251BB925557213AFBF04
-:10C230005B9DECB538A01EFDAEE1CF73D6E8D7D735
-:10C24000D1FA63D74BC863886FA5DB2613C033B11F
-:10C250001EB15F623DEA36C91B8C4307618EAF8217
-:10C26000AFB572F809BDE38B98FC3731F9EF62F294
-:10C2700002BF554EDF14EFBF9046003DB78E637886
-:10C280001236B2F30CAB678CD6FBE64AF54C9C5EDB
-:10C2900068BDEFAE54CF12ED4F31A4B5AF57F6CA1B
-:10C2A000732F07287E97BEF08483507C3CA354A74D
-:10C2B0007BE8F7455B563B004EA7958003F0E64CC4
-:10C2C000502E8A07AF510649E81B3689EE7BB9C06C
-:10C2D000FF31CB27827CFF728BEA7A84EE4BC53626
-:10C2E00053C844F7BBBC6E4131198CF9232CFFB302
-:10C2F0000B801F15F5EA51EDBE966E7D22DD6DC7F0
-:10C300007DE866001D9884BA119A96D79C18077A22
-:10C31000740569457C8E6D07E3C3D18EF2EB5946F7
-:10C3200067FB72716EAC609F4845DDCF2FC0B9B11D
-:10C33000822847B5785402B84CF5BC01067B2A9C8C
-:10C3400017C8483212F88A800309A6215F5EF9EC0B
-:10C35000AF061FA1F368AE79CB2169E04335248491
-:10C36000CBC5DA397F4DB9825C384FF1935CA36D50
-:10C3700017C476EE7A3A81CE34DBC0D2456AC83132
-:10C380009AC273D126D54331932C7AEE99DF3D457D
-:10C39000E98E7C62F2F4A5F05EF8DC814337D0FCD4
-:10C3A000C21D6A6A315B864D4A8FEE4705FD0B76EA
-:10C3B0001901FFD2170F18DD83D8F7873A45F761C7
-:10C3C000E18EBD4632A83DDCF26BF71AC3B638FBEE
-:10C3D000517B641CE8332B9FFDCA08FB7D668F44AC
-:10C3E0003A67B56F5FB2E900EA2F0027DC3FBE3F36
-:10C3F0006DFBD56E9F42135F1D8EF55CC0AF13EDD4
-:10C40000931D64F508C4E3E75FA5E397FCC9E481E5
-:10C41000F5973C7FBF03D6714AA964F8BC7175BA21
-:10C42000978E5BA206D25D98B2EF254F3F8078369B
-:10C43000FFE003A89751FCE862409911E802EBBBCA
-:10C4400077C36DB8BE79C48FF856B251F605810F27
-:10C4500028A468471C7A7881D3C3A9CD9453D2F518
-:10C460009D02FE087AEEFB32E78FF7A11EF9005F0E
-:10C470002BD56430FF8599ED5395C120EC72661D74
-:10C480009ED6FC0CF9E8D91EDECEAE810807C13776
-:10C49000919FCA070B3BB3FD61FC17DB51BCCB87F7
-:10C4A000EF50BF49F55A06EBDA717EC9C65FC2C7C5
-:10C4B000A7F3B682FE712A9DC989D8F5FDC920F877
-:10C4C0002395AF1AFCD2D035A3F39A87195D0B3AA6
-:10C4D0000F4E2E82F2CF3F64F403ED40FED07985FB
-:10C4E0003A63F9DE6912F2011309C5A3E71A95D37D
-:10C4F000B3BE9C7268D4DFE8BC15C9A9C513DA7F46
-:10C5000027843FEA25F31EA7ED34FA74058C87F5DE
-:10C510008CD1EF5951BA9DCFE9FFF740FF4951FA4D
-:10C52000271BD2AEEA7CB6480DFEEE29A0574A9FE3
-:10C530000137D0ABEA83757FB67DFFA13B295E7FD3
-:10C54000562BE854CF3763E9B464E70304F033961D
-:10C550004E3FEB5E49E2D229FD1E974EBB87FF5747
-:10C56000F8A680DBC118B8513EF8DB57DD89E1172A
-:10C57000CB072B0CEEB87C90FE7C48B2DBE39DC071
-:10C58000378167A5FF59D613F84D1B3E0A7C6BC354
-:10C5900047816FB1EBD4C32DB67C03F01B8D7EA019
-:10C5A000AE20013BDDE7D6DD329E135BDCAD8E4E67
-:10C5B00074DCD516720FE8D92D2E9E4F66F9D6344D
-:10C5C0006315F005F1BDD54266007EB6F85A1DC967
-:10C5D0001AFDF94883EC70D3F2709014C5D3AB29DF
-:10C5E000C7C5F1C32451F972845FA16CCB5C3A1CBE
-:10C5F000CE55B20774B7B9CB6F7780C9A2A5A1F7A2
-:10C60000A419F4FBBD6FCA68D368B13A06C3BCE88D
-:10C61000B95DE942E13B87EFF3691278720C5DD7AF
-:10C620009C06A617CF5DAB87C73CDB1223F019AA87
-:10C630007F46F140832FC24F50B2415F5E4AD6E23F
-:10C640007E95C6E08F9F9F77BAC81C7F869021FC9D
-:10C65000BC6180FE16733E55280F9C3483C2BDE535
-:10C660000D999868FE62834CAA609DDBA520013A73
-:10C670000EA4211E9653FE4034E7C266C0336362A7
-:10C68000FA6D7EE92FD93FA15516BDFCE9E0DFD058
-:10C69000B4F9E54FAE790DF2AF7C9CF929695F3FA3
-:10C6A0007FCFD777037F6FD963226827D9F3C7CCB1
-:10C6B0009F40FE559307ED1C2B4C5ED48FF7D8831B
-:10C6C0007DA1BC07B32FADDCFDD5E030CA9B55B8CA
-:10C6D0004F05323B475C6CF8DB7F4BA990D255810C
-:10C6E0001CDD9384FA75C5AB96201C3A5B767F956A
-:10C6F000EDB7FD70EB2937123FE29F9DCCD809F8CA
-:10C700009ACCEC6915AF8D7A66391DBFAC6EAF71EE
-:10C710000E2DCFFFC3B78381AFB4EC64FAC1793576
-:10C72000FC34F11032497E62B94AF7EB3CE86A5DAD
-:10C73000295F920FE5066CF1E0C2E0D042E100EB28
-:10C74000A27029017E98081EF3FE65E171E16E1862
-:10C750007F51C348226769E12279D9777BD02CE1E8
-:10C76000FAD9F73D5F0D06BEFB59ED7294DF1DADA2
-:10C770007B35AC3BEDFFA5754BA1AB5977CDBFEC3D
-:10C78000BA19FE0F90993C8AA583F678FECA8F31BC
-:10C79000FFBCDD83F3BD4AFA6FFC975DFF3FB8EF46
-:10C7A0003B25F4C775B4EFC7FE65D7DDD1BEBFC961
-:10C7B000F7DDEE027B6FCBEE6F338966FD1DADDBDF
-:10C7C000A0FCABF2B72BAF5BE83D4D864AD7703A81
-:10C7D000BF4F48F56D59347DCF7B29158EA3940644
-:10C7E0007CF1CE0D4315766E30819D092ADE260937
-:10C7F0007B5193CE8FDBBD04F58C89DE5FA07E403C
-:10C8000094CAA65C5ABF296F8EE711AC31F4B01FF1
-:10C81000F2D36EE479FD79EA5D897825AAC74ECC1A
-:10C82000BBF50DD0EF267965D4FF688A7ADF47998A
-:10C83000E3D8F71CFD39E28E9873C0ED33F4E5B709
-:10C84000F1FEA693C5AEE1145ED3BB2BAE2005D19D
-:10C850001DB9952AACE78EBB2452ADB157DE16D375
-:10C860009F4321DC4EF28FC16F6E1BFC16233C48A8
-:10C87000AEECD942AE027E84C1BB69DA9020D861A9
-:10C8800088E261F09B5EE6413B283F67AABCBD6A37
-:10C890005BD30474AB12FDF9529C1313C199F0736E
-:10C8A00027F6D32B0A77D52BE3B953D31FC243EC1A
-:10C8B000C7F7DD07B17FFFEC7E64C37EC4F19F2D17
-:10C8C000309B6F03FF85B99F84E7F6496B658C83C6
-:10C8D000310F94108EBE1C15FD3B270CBE6C509C76
-:10C8E0008B878D2C7F9075EB01F82CE0709C472A8C
-:10C8F00051EF2497BFFB6E0CF88D1042B4DC4BC88F
-:10C90000047A0E9937460A59E9FAE72B24E01C0A03
-:10C91000764D891CD5DA3583FA3CFCDC941EEDA7F4
-:10C92000A3FA89F8C30F9DFE95F2A3A37DE87905CC
-:10C9300052058757B4E7C47B1A181C2B1649C15EF1
-:10C94000884721D5A7F1EB7CC2F1FAAF0F0D433E2A
-:10C9500097FBCB414E3CBF7A07A0BE5FC1F5FD8B74
-:10C9600001B713EC35171B7A3BC11E73F18D7C8721
-:10C97000962F8AF4203F477EB0CC8C694B81542D92
-:10C98000C3798BB44E44395C6021C07762DBED52D1
-:10C9900084DDA592F919E98F9C0DFBC87EE6D3A62C
-:10C9A000CE4E9A7D5B3BE18C32B8FD3EC0CF518DBF
-:10C9B0009FE49F852F9C5B01AE072DE171BE38EB94
-:10C9C0007D8BC3AF78DFD746B0134C69C852012EB8
-:10C9D000530A645DDCCD7E859FA786916130AFE20E
-:10C9E0007DE31DA3605FDE903D160ADF8A860B465D
-:10C9F0007F1C7F5B2C3CA17FB00B1F533DF3009E3F
-:10CA0000C77E6121014A0FEF70FF0F2DF202FFA2D6
-:10CA10005D79C13EF6A1C2FC0AFD5566179F5A9C7E
-:10CA2000ABA6D17107D6B9868088E9CAEBF757DD86
-:10CA300058DE8DB713F5BA2E62F58E185DE5F1D686
-:10CA40003FC1C8D63F9F787E9C23FDEBED5BEE2F68
-:10CA5000EDA13C90EF0512F291F6784D903E2E1626
-:10CA6000494190BF708EC57CB184F2FF1D032B0F2E
-:10CA70004C61F252E07D2C9C2595C1598C9FA532CA
-:10CA80007C36AA0C3E02CE02BEB1F315F529BF1AC0
-:10CA9000ABB5AF4CAA1FF23CE827E50D920B4C7FDB
-:10CAA000E54AD808745851FFA80AFE823BDCAC5F07
-:10CAB000A2F8066BFDB5FD5505E7B37FE868D41F06
-:10CAC0002FAD65FAB177EE0507E841EF183CEF8D21
-:10CAD000067A7C57C678824470FC74D9B669058A98
-:10CAE000B6DF2C9CE7D445B92A98837EB468AFDAC8
-:10CAF00059834FFDD54E582EBE775DE41E0ADFE9FF
-:10CB000078388FC07F98C816DAC5C0DAA6BC245A18
-:10CB1000FEA3CA64868725B57B8D98CFC2FA623C96
-:10CB2000314E2C3D4D2B4ED2E5E7E487BB035C8AAA
-:10CB30004DA1259E3878DAA80A3FC9F794135E8A7A
-:10CB4000B783FF7F901317C679E3C06D9DDA4E3E21
-:10CB5000748E271F162F777706F82FDEDDBB331074
-:10CB6000C7E2370BD3E3C9878F96317FE0C7949F25
-:10CB700041DA328DCA87EB35F2619A05F123B6DDD1
-:10CB80004FD5AB940F62BFFE97F9CC47201FE2D080
-:10CB900075B5AA970FD31B66A17C983E4D266E8D66
-:10CBA0003DEE672AF77325940FB9E977605EF524A7
-:10CBB000C5C19B8FF8B904E00A298C0372E20F9C6F
-:10CBC000EFC7CA8B44FC7C8A51E2FEEA0EF8F9FFFB
-:10CBD00025380B7EBE989E5F400F6C8F8704F9F559
-:10CBE000E23B283F97001F193F5F7C17B74BC6F009
-:10CBF000571FF0D7E15AFECADA97FB993CA8A8CF95
-:10CC0000FAD54C5A7E67B5EA31D3FA7746F96DB654
-:10CC100096DFFE81F35B0AE74C579CFD9D3133891B
-:10CC2000B8F5FCAA0FF0A96343FE38F045C0FB77C6
-:10CC300064F4239EE072FCED217F1C0EF6F354A3F6
-:10CC400082F87382F3AFF3CB82D30A281DE7CF6556
-:10CC5000FA70D97619E1505EC7F4BCF23ED6A09BBB
-:10CC6000E6C70DFD1AFD810B77337F20055471AEA9
-:10CC7000661F17BE13AEEA06E59B24F467CEF32CBD
-:10CC8000443B3E59CFECC466FA87C57578D18E5CBB
-:10CC9000C6E1B5A06113DA9B1704F576E8B23EB79A
-:10CCA0009C81F380E0BF0BB7C5947B1E467F45197E
-:10CCB000D89B35E71099EB0FF7CAA1812F426CE79B
-:10CCC0007BEC5C15BBFFA25EDBFA4BFEC9F51FA433
-:10CCD000EB1FFEC3AFFF6AD7AD1A39BD0F25C38165
-:10CCE0003E4E18BC48EF81FFA2EBA7E3CC7DB46FAA
-:10CCF000676D9C510AA7CB770CFEAA2E50AF5CC281
-:10CD00007AF337EC38904EF3336BC91030D3CF5FE2
-:10CD1000AF978B6D72B8CE8D727666E50E69F64070
-:10CD20008037A9043C9B33D4E4077FEA414B2BF2C4
-:10CD30002F8177371A193E8FE6E31EEBDA5A80E728
-:10CD4000887AC9857411B2B0730585BF85E6F78FFF
-:10CD5000FA6A1C8737DA632AEAD9FE54D0FD00BA92
-:10CD60001AD7C0F3DB981EF6232A6FD01FD6B05710
-:10CD7000857625B47E0AF29B013A3F17F8E772D315
-:10CD800035FBB6FB08C3DB2D9287C4D9B77EF44FC1
-:10CD9000DC7DFB81F055C0E34623D7E7F9FE1DB4E7
-:10CDA00034150F433F94E4D90C951B92D18F72BC7C
-:10CDB000BA37EEE3AD1C7F63F11AF47BB7C69E343D
-:10CDC00019260EF19645168C73C3717B31FD47CB46
-:10CDD0004F62CFCD15A409F5980992FF2F8A26AE90
-:10CDE0006D3A8F3F117E5A4DBD5FA957A847325CFF
-:10CDF00006E093F78B784B881F4EC7B825FCD9DF28
-:10CE000023FBE39974BD97D6C81EF0FFDC6E701F3C
-:10CE10001A03F4FB884A002F2FBDAD7A99DE99845E
-:10CE20007C77D63BC7543085CCA23081FD9EF5532C
-:10CE3000C65F8F4167F4DB9FA8DCF282AF9ED48E81
-:10CE400080F8E1699EBD856EBA2FB70D3FB81AFC18
-:10CE50007053F35D870E017C1F9609C0F7E89A7C3A
-:10CE60003C9FDC7F9F84787D98C211DADF362DEB02
-:10CE7000D0213AEE5D6BD2D0AF36D37BA010F06CF0
-:10CE8000CE24BB0DFC6BB7F693895F03C7BB48D3B9
-:10CE90006AE0D7332BEFBB0DE65B42E500D8594B78
-:10CEA0001A0E167686FC06C9E3A6FD5704FCC6CE0C
-:10CEB000740B9BD65F3082BD631EAD07DB53B1811F
-:10CEC000D5ABA8913C16C0C7864791EFCCAB9188F3
-:10CED0000BEA537DCFCCFA0D9A69BF4D1B687B9A44
-:10CEE0009F0FEDA1DF9AE4E9E047AB785B66ED7355
-:10CEF00096BF0E7C691E6D478B4953CD7DD8DF826E
-:10CF00000D12C9A0FD95E464FD470EF4F7B6EA8161
-:10CF1000F28FF7FEDA08F3BE9B8ED785F63F470EF9
-:10CF200017427DF213C9B505ED4D2C4EB685D301E0
-:10CF3000F9B00BA32F89E7B91E28E4E107C65E8884
-:10CF40004FF3962EAF8275850369597004AAA8BF66
-:10CF50006004BDEE3885B39FEA6DC7781CDBFEC068
-:10CF6000316358C3A75A8DBDB1FDDCFA5CA4EF7BD9
-:10CF7000890FFDDDFEE54C0E1F596D094AA07FA803
-:10CF80002E9493FB575FFB24ACFFFC732AFA47CF28
-:10CF9000F708A33DF6D4069504E81C576E90916FF0
-:10CFA0009CDACEEC40F24615F3F31F30627EFF862A
-:10CFB000A9E3801F9EA2F0073CCCDF586884FC7C6C
-:10CFC000CAD74D71F8C73C7729E31731FC61FE7A67
-:10CFD0003DFDB7E3174BC631FE1EC30FCABA57A1BA
-:10CFE0009D2F964F54109BE00F4321DF14EA82F8E7
-:10CFF0005BFEB64A409F2B575C77AF07BC9969012F
-:10D000004F31A58BD001E06B9782923B40CB7F7470
-:10D01000CFAE1100BF93006FA08BB529E84F9D17CD
-:10D020009C857015F184F3D7EBF159C42FDDE1979E
-:10D0300089572B074A92885753EFE39F52BCA4E3CA
-:10D04000DD532F052D12E48FBCFEC070CCBB000F4A
-:10D05000CB977279BAD68E78FBF1BF5D580D78798F
-:10D06000F74312CE9F04FC552057CAD74B6EB063CE
-:10D07000CE7F88B59F4FDB03BE7CFC6B863F148F51
-:10D08000DD80E7E51B1E7D1DEBD7486EE8FFE34D15
-:10D09000B350FE96046482E53547503FA67200E324
-:10D0A00080F607E474C0F3F2552617ECA3C017818D
-:10D0B0007F4754E6B72766CFE0A9B4DD26A31BD788
-:10D0C0001D8B77F28C2CC4AF8AED2AE2474580E1B4
-:10D0D000D391E764C4C3FDAB6F47FC39BF454A80B9
-:10D0E0007FF9C62E807F4156DE867FCF4A1CFF180F
-:10D0F0005E9F5AC2F0311FCA01FF5EE2FA29213653
-:10D10000ADDE21F04FE0534778D74E2E25C037AA29
-:10D110001B4F8779DDBFDA82F3CEAFDA357D29D2B6
-:10D120008D8AFEF9FCAA7F4B073A9DA7B0380C0107
-:10D13000C73285C5E9B49BC7E3CB8D5DAE663E3192
-:10D14000F3D81B958B43412E425C49888EF3C7ED83
-:10D15000CF60FCDAB9DF1FC1B8C485AFD17DA7F5B8
-:10D16000CF6FB79310EAD341E42FA57532C685126D
-:10D1700025943D55737F44C45B2C7CC18EF02DDD1E
-:10D18000690A16D3F6A52F1F1B8CFEF015ADAF0351
-:10D19000FD047E2F31BB7C203C782AC4552A2CEE1E
-:10D1A0002356EE8E32317B4DF3AEA419A0FF48DB3F
-:10D1B000F6A23FA9B4F676D5A4B14F7A4C2A8E4B8D
-:10D1C000EBB17B2E74DFC18F08F39B3C483BBFE57E
-:10D1D000ACBF6719DD94D6ABA817956EDB8476BD1E
-:10D1E0008A6D1730EE35FF85E71C00878A7A591F54
-:10D1F0000FB54D0E99305E4B3E6262FC4917975455
-:10D200005EC7EE6594D7F2B89F98B898852FEC7EEC
-:10D21000394041B3F0C5AD0EA0A3B34D5B1C004F28
-:10D22000DA1FC6134DCA49106FD4519C51EDC3711A
-:10D23000E38CCEC23F2882DC6DD2C767926D8C4FE3
-:10D24000D15DCFF6C5B1670A7D65E1735F3C0D71B5
-:10D25000AFCD3B3F7B1AE6BDE8EF979E86B80DB297
-:10D26000C7E202FDA1E2F71F61FCA068B7D4C4CFFA
-:10D270003FCF6EC5B8CBF39F9850FF3BBFFB542602
-:10D28000E807E7777C9D0EF1944B7617A2FD61C904
-:10D290004BF99D499CF3AD48012F835711F719BBFA
-:10D2A0000FFBEBE4908DCEF3DC6113D2775BBC58BF
-:10D2B0006D198BBF73F338B1EDF1E36A457C537997
-:10D2C000DDD44937027FAB6372BC2DDEA9A3F8B071
-:10D2D0000FE97E5E7F15FBB69DC7FFC5ECDB39F815
-:10D2E00007DD9F274CFAF8B02FEAEEFDED535056BC
-:10D2F00017FF3E99A0E38EE025E276E798BC411344
-:10D30000D0CDCEFFC4383CD8AF6237C8F92F32C178
-:10D310006E795A6D457B60EB6E930BE2B64A777F70
-:10D320008CF471FEA58318174B78FCEC79D2F6C308
-:10D33000E21DB94DA2A2C6CEE2CA38DC21EECCED88
-:10D34000C0EF3CBE8CE1AD883B4B146FF691A91742
-:10D35000BF77C1E2E2CADC4D4680BF360E4DCA81BE
-:10D360007D3AA28BDF13EB8EEDCF057018A98D9B54
-:10D370004C14CFC7F5F1B67D627CF8FC261E47D968
-:10D38000161F4948F7A110EFC3E45D4550FA98C451
-:10D39000A1471137D9144B8FC1AB8B97EC78BEFFE7
-:10D3A000183CF69B98FD49C0A5F9727C7EFC19A734
-:10D3B0006F7A2E396BD2DC4BB9879F4B441C9998FE
-:10D3C0006F552D93BBCDDB985E184BCFE5DCDE1E91
-:10D3D0003BCED77C9CF2FABD8381EF34EFDBC5F105
-:10D3E0008DE173F9F623C600E7CF412D7F86FEE27B
-:10D3F000F013D9CCFAA3E7D8B8FD556CBF10B7BF6E
-:10D40000B38AF77698FFD926A6679CAD958B827173
-:10D41000FA3FC7E54FDBBAED463C57C90E2BF29FEA
-:10D4200025F69CC3CE54488D18BFB072398F77F85B
-:10D43000A92703E0BCD27E0B81F9AC06F868CE992F
-:10D44000AACB4F40CF51337CC3E1FC24E62BCA8DDD
-:10D45000A90612D4EEBF12C0FB91137B7DA5807C80
-:10D46000695AA6BFD7D1A4B80EA4D0FE9A0A240F39
-:10D47000E8B3EDF14CDFFF64AFACB38781ED19D6B3
-:10D4800075D163C0FDB41B422E5A85D82D4D197835
-:10D49000907313B7928E21DDE8DF7E64D9B61E70DB
-:10D4A000CFCA413C1294DB3D6DF75BB03F27898DBD
-:10D4B000B3261FF6C926FC0A3094BBF6825DC2DA99
-:10D4C0008FF483FB3B2E62F5C0FB0AEBF8BDC7B5BA
-:10D4D000763FCADB8474E361F75E849DC899A3E854
-:10D4E000EEC5247BF5F994987B90825FE3153A0AA8
-:10D4F000FF71FCDD87E442B67EB057F54D8FCE3725
-:10D50000398D7842503EC186F1CC361B9B9F982FB7
-:10D510009D0FF2030A26369F81E100E8E1745E3137
-:10D52000744CF0DE139DDFD198F9E9F4B83BCC5C84
-:10D530003E2844013E623337110EE78BFA38D300A0
-:10D5400081B803671B5C6939ED274B9A6482B80583
-:10D55000179C827BE37831EDBABBB4F7C5EAE11FD3
-:10D56000A3D05FD468043FBF5982E333E90CB80607
-:10D5700040509A8C008C5FD9443E84FAA2AFEE20D2
-:10D580009E3FCB6A0F62B901F2344D497217741B8A
-:10D5900042C8C36B0A0A32FA43BD5919060FE61B8B
-:10D5A00015A0A3C9FE0CC310987EC1AAC631846C15
-:10D5B000259503C0A2645EE56D7CA307E01541A735
-:10D5C0001D09781B0137B78A3C6580F0BEC2566BD7
-:10D5D0005BDE6BA67C716BAFB67C00F23500FC1B8A
-:10D5E000603C6FE32A88F331FB5699E9B893371A08
-:10D5F00090EEC6466C78FE20E14EC89F09A9B4FAA9
-:10D60000E2DC976EB3F3F07A1DF1F1AD3C1E79B216
-:10D61000DFEF81ABDE23B93C26AEF030B88FDD62A0
-:10D620009EFDA4594B871B2FCABDE8FC9E84BDA755
-:10D63000ED9D45AE5BFAD1F939371858FCACD9FFEE
-:10D640001BA8DFF721BF01AA8C25E1FB25E0C37FE2
-:10D650004EC5F98871AA76B37355D56A437005E251
-:10D66000AF5B02F916DDBF70CCFEB5B2FDAB3F82F9
-:10D67000FB57DE7084ED5FFDA6BD466E8F8773CBD2
-:10D6800056E2D901A6A71D6B661428745F524CADF3
-:10D6900055B0AF2A995E50DC1FE1FA425CB8F2F94E
-:10D6A0007504D7ADA737FF7C30E8F5CD064F5F1284
-:10D6B0008597A877C8CCE2C4A659FD0D304EC5E3C6
-:10D6C000E12A38FFBE7AFA7DF403F76DBE181A4CD2
-:10D6D000E7DB770C37A7F071B7366F467FE656C0A9
-:10D6E0006337B8EEFD2B404E268607C3EF3678D45D
-:10D6F0001D41F818204FBFEFE4F728F2EA252FC8A4
-:10D7000089141395A3347DCFCCCE31C7CC324F9939
-:10D710009DD1D9DC4B01BD386F9A01CF534E9E4647
-:10D72000D7CFE3FFCC8A4EBE88FD147844487512EB
-:10D730009C730A9CFE3FEBF1E6B1A45EB47CECF175
-:10D74000A3F7835D4FB4DBB28C78E66AEE4353FCFB
-:10D75000D9A56B57F88015ECA1A23EE065BC730219
-:10D760006D7716DAC138B08E5DC72FCA00EFABDD1A
-:10D77000D7D8EF4DCBE8787D12D38F2F97DD2B8A4A
-:10D78000FDFE77B3F03B327DC41BBDF7F777C08752
-:10D790003273D8318DEE6F79EE2523C06145D2F911
-:10D7A000D1F1FC9E89E6D174F95A1BC8E97D115369
-:10D7B000DC7B04FD2D4CBF7877D90C0FF8E11F16E8
-:10D7C000F704B83C2BE07CB7A04F6931635A9AB894
-:10D7D00031305870B959085FE8FC8A727628203FCA
-:10D7E0000B89465E32F93801F49187F36482716ADD
-:10D7F0002E5527DF6E057BB903DE05A96C84E16F2A
-:10D80000CED0DF039D34E68802EF158CCFA1E2581D
-:10D8100082F769F4E5B7C6DC139DEC9DE529E0E5E8
-:10D8200097F0FF415CE7A49C3B3C055A39A154F7B3
-:10D83000837D3EF8AD1C576F7CA00D3E3E84EB2BE4
-:10D84000160A9FEB619DB35631305D191EB1708C85
-:10D85000854BC19FE7317B610C3C6EBE5CDD98124D
-:10D86000070EEDD75DDD0FE4A6805F2C1C9AA02E7D
-:10D87000EA4DA620E8814D4A18E1D844E118E07E3F
-:10D88000ABC274CD3E8BF970FDE156FE3D169EB1E4
-:10D8900070A4FA05EA0FE307D9D10EF636C00BE300
-:10D8A00000AA3F34D1EF6FF651C923C0FB42633168
-:10D8B000CEF02682B022AF489505E8977131FF0A75
-:10D8C00095E70C1FFECCEC57C51136FF716E162F75
-:10D8D00043E17134061E4763F040776E899DE72B64
-:10D8E000F08F5171F083E3C1220B3FDF641237DC0C
-:10D8F000FFCFFE64B893F185F8F2716CC4D7D60FF0
-:10D90000D33BD8FB1C12F1B77D77D17E425E15E385
-:10D910003FF3CD2EA48F7CE24D81F72020C810E686
-:10D9200029E6354CF2FDD49206EF378D4FD1BE0F6C
-:10D9300021C617FB92CFE1974F027BE11C9A4F94CF
-:10D94000CFB5EB16FD5559B89ED593F4443F391821
-:10D95000434744FB13EB4B4921217C3F4432E33DD9
-:10D9600027FA5FC0D8293A9E881FB5DBA7545B58B9
-:10D970009C0461711221DCCF3C5E9EC7DF6922E608
-:10D9800084EFF290EF92A2F37BDA2229F86E029FE5
-:10D99000DFB937CC0188D77850F26F86719AA5B776
-:10D9A0000703BCA83E760DDED38F29BF74B8B11C27
-:10D9B000CA69BD79588FAF6BA1CCEC64F4FC8FEFD2
-:10D9C000A1B4E7E3CC9E46C94D211AFACCB332FA92
-:10D9D000BE95B8BBE37B69C4AF40DA6861F7D06E2F
-:10D9E0003EFC18EEDF5BD69BDF007A2B224105DF81
-:10D9F000F971E9F1B0433CED177BFEE5EFBA28ADD4
-:10DA00009900D77D966BFB801C13FAC2FB16DF1FB3
-:10DA100060BDFB2C8C3F1FF58E7817E4C2ECDC61F7
-:10DA20008786D3D460F6E1BB0BF7025E5178E6003F
-:10DA30005ED1B6FBA0EB2E88576F5846C0FDFB1891
-:10DA4000BC32337BDA6CCAB6601D796BD46FB4F329
-:10DA50006A8317978B1DE987A4912AF4E9F0DE0207
-:10DA6000C3CF7D165300F4B6BC87597CC41CE27F3B
-:10DA7000BA5AC2770074FAFA5C0BB37BCFFDB505D6
-:10DA8000E99C36DE50097E2E0B7FCFA11F7B77A746
-:10DA90006DBC6A4D7BD877733AE2E15CEE3F3C2E79
-:10DAA000B173CB5C4B21BBF7BB5EBDA8C5C7D8F13A
-:10DAB00013F61BD36E9FC4EC24FB5437C6838976C0
-:10DAC000E72D4C8E5F34F7DD60B8C27DF079E64E0D
-:10DAD00003959468FEA4C532239E5E20FA6B3B97A3
-:10DAE0008BF30431AF6EEC1E3D4FAC5EA11ED09F98
-:10DAF00027D403FFCC79C2F5887A60156DFF848145
-:10DB0000F9DF88E2EB3F59A30775B1327DF080CD94
-:10DB1000DBC54AD327B8DE48359CFE5A7BB5A897AB
-:10DB2000BE348F1C1B167DB74D52E80CF1DD0DFF86
-:10DB3000729043CA0C827281F29F7BE2C50BD9EDD1
-:10DB4000793D601C41970F1BDC35D52C8E01FDC043
-:10DB5000BEA5B351CF9BBAB404D396A397AF01FA35
-:10DB6000CCE3701E60E5F69324463792E41F60858F
-:10DB7000F87CAF6C073FEBC27A99FBF1D87B575327
-:10DB800027C869F0FD9859C5F3E13E3BDBEF63849C
-:10DB9000BD5B9377D0E4ABA3E965923BC1AAD13BCF
-:10DBA0002F9302CC938C74F46B8B7B8CC748169BA1
-:10DBB000EF1AE637B8B8260BE39BF7A97A3BD5589E
-:10DBC0002BD393C75AD9BECFE6EFDB019EC13B13DF
-:10DBD000B31537DA0D67478CEC7D353A0FC4438BAC
-:10DBE000BE9F22DE4F515B3F04EBEFB3C4F6A3B000
-:10DBF000FE393EC7C2FD354B7E31ACE732F14EB047
-:10DC0000221EBA15804FDEF0C6C3C0F73AE6F30114
-:10DC100009F87CC56529D413EC68752A9EDB9AB98E
-:10DC2000DE7FAE6E7FFA6C9A96EDF8C001E7C3BB5B
-:10DC3000F93E9D539AF03D8A452FC9789F9AA26F6D
-:10DC4000FA8FB0FD9C6C761F84DD6710F2EF866F53
-:10DC50007B77F7613D763F41E85DF9E64010E6B736
-:10DC60006FB98CF62A2A1F75EF9314D6B17B0BB1CE
-:10DC7000FAD812ABCAE338D93E2E71B17112D17302
-:10DC80005EC44A821A7ACE53DC0ACC3F2FE220418E
-:10DC90000AF773A737AF9B48F13C90A1E2F98F4A8E
-:10DCA0009B46D407A3FEF1467847AB91AFE740DD32
-:10DCB000D469F0EECAEBA472D5205AA720EC4F65C8
-:10DCC000C44D4F6FD9517DACD0A5D70363F5C4A225
-:10DCD000864757C11B2DCDF001C6379B30BEB89D7E
-:10DCE000FE68BE39AEDE48C8A3883F37BCF4CCAD71
-:10DCF000F02EC50D670C2E98DF34AB9BD153DD257C
-:10DD00007C37A19C84A64379799DEC0AD1560748BB
-:10DD1000DD75202F857C1770095DDE6FF6801CB0E5
-:10DD2000C8AE15B04EF36D3688BF18DD323015E43D
-:10DD3000DC3EB38AF6C93C4B5FDB1C0D3EEF4B6506
-:10DD4000EF091C48EDADFF6E5E771DC8BB5D3C9EC4
-:10DD5000ADF1E49DB630D69B9A8AFA9A90EF317A6B
-:10DD6000ACB0838DEF2BB7D9C1B4FA2F91373C6E8D
-:10DD7000A1E5B75EABE27DB88230F3A7B693EF972B
-:10DD8000FDABF83945F7BD88EB0DEDE47D14CE3AD7
-:10DD9000FDF4552BD7CFDC6410E89BA1CBEB16E24A
-:10DDA0003DDA8624D70AB433307DA6E578E9BA098E
-:10DDB000F0FD6D99D94D2ECB4847FBF62CEC19D6CA
-:10DDC000D02F9514B86F5F0EB970FE35BA2F5F9ED5
-:10DDD000B07A028877B5D7C5F79705399C425D9927
-:10DDE000FD3DD095BD8FC1CEA33745CFA34DC00F0C
-:10DDF000E07D19101B191B8E18E1DC7C8EAAE888C7
-:10DE00005F74D1805F3779C3B24B339FE356662F7F
-:10DE10009866F51E023E122079DDA872424AACDEF9
-:10DE20005C880F6F9D4C5C9BE97A769FCE93549AE9
-:10DE30001FB325CB23D1FC4E5038816FBE24072160
-:10DE4000CE6427DC67A3FD2E68AA3666D171037500
-:10DE500032DAFB1770BBF969359099ACC18F5F2638
-:10DE6000B1714FABFEDF423FA73F31A11DFCF4096A
-:10DE70006B5C797B7B12E397AF71793624C98DF99E
-:10DE800050F3ABAF77A5F30A455C4300EEA5DB2E5C
-:10DE9000C8F09ED28D5C2F2B7EBC6915D86B266E88
-:10DEA000685580EFF882AE4210B553B6795490436E
-:10DEB000D3B6FB54D8DEE97595189F34A3BEFA009B
-:10DEC000E4EF0CD562FEBA24FFDF00AE37AD69DDAA
-:10DED0000FE8D2A79A28F8BECFE74CDF4AE3F3E871
-:10DEE00015F1EC732236E71A00BFDBC67FA84901A3
-:10DEF000957EE22A363EED4F4D82FE2A5BF341AE1F
-:10DF0000652E65FD6592BDCB9DEE68BF632F3749D9
-:10DF10005A3B42DE4F16211E3DFDE0A29E60670F78
-:10DF2000FCC944FA66719A4885EFDDF9FDB270FFCD
-:10DF3000293ABF74C8C4F08698592AF0C96B66782C
-:10DF4000E4B2825EF0E3272BAD4017A93EB7511B28
-:10DF50007798B7AE78C09B80A71613DAE3BE1CC2D1
-:10DF6000F4F62F1FB505F9F97400E0AD9053B363D3
-:10DF7000FC2E513A67784FBB08C23C444AA4152E88
-:10DF8000A2CD935006CCAB4712E3633546F74C184D
-:10DF9000AFC66A72C178B3CD7D8DC097DAEC9A3C7A
-:10DFA0002E6D34D72B779FDE9702FBFAE590E5992B
-:10DFB000A02F870CBF413ED4115E3D66F566273128
-:10DFC0007D0EF57B517FD749EB409083AF097DCB28
-:10DFD00033AB27AC57B49B9AC4F4A89DDC3F27E829
-:10DFE00020B58978370D445079776AE0313189C995
-:10DFF0005191EE54DD0146472C9E73A73D64EE0D12
-:10E00000F4BAAB37E6537DC4E681F895FABE1EF04C
-:10E01000D3503A9F98A489DBBB91D37F6A532BD20C
-:10E02000DDD59E034670F886945A4E3F04F910D011
-:10E030000FE3CFA16EFC1D1EF4FB015FE0FBD34597
-:10E04000CAC03870DC67B1EE544EF7F773BA0638C1
-:10E05000407939CF8BF2451C5E85F240A7366EAC15
-:10E060009DDC5E9A41403F2C5CDA15D3724E670B03
-:10E07000CC8FA29D7441EAA3681F4DF55663BAA0E8
-:10E08000A01ABF676C9885F8B1607DFCF7C5DEE229
-:10E090007AEFB9D306F68E94C1DA15F04F9437595A
-:10E0A00055CE0FFD0F023E9CA95BF7E46077D4DEEE
-:10E0B0007BA686C9C112AB5EAF5BC6F161F7E7FB19
-:10E0C00052005FBEB4544FBC13E8648BEC5A0EFB95
-:10E0D000585328B9E3E09F16CE00D78A9A2FD0AFC5
-:10E0E0005A4EC2E8573DC3F53137F79F0A3F6BB030
-:10E0F00086F1D7D32AE3EFA7A51409E803F83BF08C
-:10E10000D9D3271EC97C10F048B2A35E037C738765
-:10E11000063F166EDF54D595FEF3A6CBECDE4E48D7
-:10E1200021362D7F167822F86DECBC37F17D1578FD
-:10E13000383A2A87362571BB686FDA6FF9A317D191
-:10E140002EFA32DFBF1AC037A0E73502DF8618D8B3
-:10E150007B697A3A1EF903F1EF5D8F3D95897687E9
-:10E160001C4AB7F0BE1AD0751CBCD8C3F1F231AB53
-:10E170007F17CC3F96DF9F91FCBF4DE91D6DBFEB34
-:10E18000E42D03666BFA59CFE1F1A5EAEFE98A03C2
-:10E19000AF285C4957D8E712BA330007B241726919
-:10E1A000E3DD533730FBFE7B9C3F88EF222FE03DC1
-:10E1B00036FAAEDC7B494CEE1B4124670499DC2720
-:10E1C000865BBA821C5F60F5DE827696470D04DFBF
-:10E1D0005195F210DF536B9E38F9ED70482DBDD08C
-:10E1E0005F42DC06F0832E78D88DE7BD15BFB320E3
-:10E1F0009E9D4862F1112B6A54C4B7336A35C6E15B
-:10E200009D3951DA13FC2D814F981C4A044F813FF0
-:10E210003B39BF1178D76B2DC3BB1AC56B05BC1337
-:10E220007254E0E7992D370F057A13EDA378E31ABE
-:10E2300022F06616FDDE6B4D5886FDA1FBD60A70F6
-:10E24000E8BDB615F957A27D137E34B17F82AF0FBA
-:10E25000B319747E03838DCD3F3581DF3F2AD7F418
-:10E260007C98EE87641BA1C77FB85A29E8A9B90337
-:10E270003AB8C7C6DE77AEFACB1CF4DF0B3F8CF0A2
-:10E280008F8AF1536C0C1F12F9515ACCFE4EB618FE
-:10E290003F9F1BF93AF39B88DF33B0780B8B63DA2F
-:10E2A0000545C02F8E5B83DAFBB9D72AC4AB0CA51A
-:10E2B000D861CBC2795D0BAC82E653971A491F7ABD
-:10E2C0007EFA72D4DE4607AD3FA1355C7C3D5DDA57
-:10E2D0002E6378DA24B0EB126F29E8136883073CC9
-:10E2E0006F66FD1257AD6E9E03389CC5BE887527BC
-:10E2F000925B89F6E31E1BF77BF1F2583A37F2F294
-:10E30000D39C8E3AA6D38013E8F42612580EF1154A
-:10E31000F4A08D71696D744A0FDED07F01EF577CD8
-:10E3200017F938745A604BD3D06924CCE894D3A33E
-:10E33000B346F5C6D34FA6D8983C72D614E6823CB5
-:10E3400071FA30AC9CFE30BA5E40E91AE83500F450
-:10E35000D919E0C9E8AC97B71AE3197BD530BDFAF3
-:10E36000CB64B6DE05377AF7C27BC80BA85E2FD127
-:10E37000AAD59CAE13C33DE494987C72023FB96960
-:10E380004C381FE4AD1BEC169DF1575BE0A68C1DCD
-:10E39000438221BAEFEECB84F189134FDDFD20F0EB
-:10E3A00087476D78AF49C89FB424FF3CC0CB44F485
-:10E3B0004CF1D20B76A7C55FDBD8F92F81DF7BEC60
-:10E3C0005203E99382785EA1C5F3B1BE5619E09A73
-:10E3D00092E4CF5093E9F836EF38730FBABE2CAA07
-:10E3E000DFD2FC4F697E2D5DC7D64E61C2F355B6B4
-:10E3F00051FFB83D2EB0F6A6D7C1BFBF25C9FBEF70
-:10E40000308F16B32F00FB7C53B75619E395AED26D
-:10E410006F5F017638BA9EA3B70DF8DD2CFA75F65A
-:10E420001DBE2A2815F6E291DC5E5CD13004EDC8F1
-:10E430001ABBF12F6D57B01B7734AE83D33DC56F38
-:10E440003CC739725A65E08B82AF6CB475E2F81C38
-:10E450002670AE10F4057C09F45A113F00F6433BD8
-:10E46000FA2382887F90770E8DF29BB5D586B8F11E
-:10E470004DDB6DB6B87C9434FCEDE507C53B8A8C6A
-:10E48000AF6EB769F48A9AEAA3E94C4F65EF92DD63
-:10E49000CFCFF2EB5678DEEB931ABDD73CCA640CB3
-:10E4A000C07B8AF460E67669E223A506296487B812
-:10E4B000BB6F6811E0D137064CD7FDBBAF280BEC22
-:10E4C00025870D9E1504E310103E393D09BEB35358
-:10E4D000CFED9CB9C76C5EF0EFB74866E49F2D475F
-:10E4E000AC01909F2D7603DAC71B779B902E2EF5FB
-:10E4F000B1723B465067EF10FE9A4B6FCF4901BE99
-:10E50000FF24F75B3E79C735687F14765945A13003
-:10E51000EF04662976EF326F6957B49B0A3B6DBAF8
-:10E520007996C4828458FF8A99AD2B5DF14B60FFC8
-:10E53000DED4417CC35F6D46A1EF1E06F8563C1445
-:10E5400036C27955E8BB421EF76CEEB517E21C7A6D
-:10E550001631B3D8A6668301D6B789A25172567B0D
-:10E56000BC12F8B3A97D1CC1099B865F4E5ECDE24B
-:10E5700008DAF2BCDD6F791CC1D8E3475FC4F7F25B
-:10E58000CCFE8F74ED0AD3ACF1DEE19EBEF4416C9B
-:10E590009F08EFA71BD8FB3BB1DF4D76CEB795CADE
-:10E5A0006E78FFE9AF3F4E72C7B1C74CFFCB6CFC32
-:10E5B0003D11B1F6B3E8F8FFEE29A0FB26D9DBFC4C
-:10E5C0009499E037EBC84F193BEF43AABF473CF99A
-:10E5D000141B4727C66BDF9E9DBFDAEA19897F8728
-:10E5E0008DF53B54D36F8E9DE93DD32582F1EDE44B
-:10E5F0005B82725AE009857B373B2DCF7EE7D830AE
-:10E600002BFA715A65E003970EF7E98EFEF304E7E3
-:10E610004D311F42FC7DE3C5694C877776E2AC6FD4
-:10E62000849DC9E7E92AF3374877F4C5F3FF748B73
-:10E6300049D2C6E567D9251D3D097BF33ECB48BCD1
-:10E64000BF0876F978F08BF5C366818F348DC1C52C
-:10E6500013079F84DF4FC0B92AD79BAB30BB18DEAE
-:10E66000434BF532FE995A44D07F3652F2223C6E2B
-:10E67000B6337D69138F7FBBF4368B57CDCE75E3F0
-:10E68000EF71A272A2D03E02E3A95E3468E2A9044F
-:10E690009E543D47E5B1CE6EC8E84A9C9B93391F16
-:10E6A00076C17B129A7AEE87800744E540F755667B
-:10E6B0005D3E73898B281A3991ECCDD0E5BBFB5CAC
-:10E6C00056382F752F72EBDA09BC13F17CF8930AD8
-:10E6D000EB76A1DDA9139FCF48C98F78037C0DECA1
-:10E6E000C1F7F27DA2EB9D037834B6287C498B37C5
-:10E6F00062BD1DADEBE83237F2C2E3CBE87C295FA7
-:10E7000098B3366B7906C2DD45E01C71729919BF6A
-:10E71000DFCBDB273F3E0BEFC926AF72A33D36D9D7
-:10E720005BF93ADCE349AE74E3BD81B9D59204E705
-:10E7300074CA67B0DDC6652E4CC57EBB68B9648BF4
-:10E74000BE239E487EADB2DB74FADE15E4D72AFB09
-:10E7500088F6F2CB60F6BC097EFDB206D90D78B121
-:10E76000B2B813C6F7AEAB65F7D9F637B0B8BA751D
-:10E77000D3991C11E39E7FC989F2E2BCF87D29DEA2
-:10E780006FD2A7A0BFFF9B74E0B39B6CFEC7EC1ACF
-:10E790007EB9AE618485BFAFAC933FF4C705F71B6C
-:10E7A000D0C726819E34648DD21BE9FE29684FE6CE
-:10E7B0008587597A039EFA3F8077482F1DFE3C13C8
-:10E7C000F64FF8EB843F4F8C23FC7D92E47F463B71
-:10E7D0007E7B7F9EDE0F253BCC18879B23B3385C66
-:10E7E0008D9C25B08F2B411FA478B6F28815E1B11E
-:10E7F000F25B466F749E2FC0388DF66CC41F214F9C
-:10E80000E93C07BF4BA2F3AC30B4666ADF21D5CC3C
-:10E81000B3FECAF38C8953E5F392ED0ACEB785585F
-:10E820003D30AF7AA3E7B01FE4EC792BDAED5ABCA8
-:10E830003758E03DD916728305DE99DD6EF337C295
-:10E84000FECB3D5A1DA067EF6F18D61FE69BC8AFE1
-:10E85000DA6CCB7B03E645D7F716F20957F8D2F30B
-:10E86000EEE8FAAEE08F7D0FDA7D8FF51FFE3EEB0E
-:10E87000AF80DF8FC10CDDA84F499CEFC6E295D475
-:10E88000B0F76B880FA2F4837199814C125C49E157
-:10E89000543588E117994BF8EFC7D1E3C1269BEFB8
-:10E8A00034AC57D0DD15E0D30CF37EDCE63B0FF53E
-:10E8B000611E70CF83F299562EAF5E341AA27A543D
-:10E8C0004A0AE357ADC904E36762FDDD76FB94AF06
-:10E8D000A05D7A3FBFE41AF8BDF09C38AE08BF10C7
-:10E8E000C63D887BA665E09785F8AD3AB559FF7BB4
-:10E8F00074F470D86EF359A1DF401E7B2F0EF06ABE
-:10E9000025B9223C1C0E84873FD941E1615729BEBD
-:10E910000050726665009C5BCC2C1E60E772068717
-:10E920009677181C761D37201E3F410620DD0D35D9
-:10E930005CBC1BFAA7FCA31BF433A6B55682F36F8D
-:10E94000E712B701F86CB7568F6CB832DEF6743048
-:10E95000BCEDE560FB703FECC3B0B7995DE60A78AB
-:10E960007B0D8CF73DE07EBD63C4D5F3178A57C39A
-:10E970001C1ABCBADAB82889DF8F8CED8F9E87D03D
-:10E980004FB0779709F951F94E761FB47CCF293CE7
-:10E990007797BF6A42A42C78D5C2EE35D4B1F2F392
-:10E9A000B9F1FDF9631CEC9C55567B9F472F77030B
-:10E9B000F8FD97DE8BAE3E72D43F9A3281DD13585C
-:10E9C0006911F1A0CC4FEAE07896D2C3E705B9927D
-:10E9D0005248F0BE80C3C6E206DBDF0760749BC608
-:10E9E000DBB95C6E09E01D7B3F200DDE8B667E6E21
-:10E9F000C417D960F580DC4F298AA9672B423F6A8A
-:10EA00005ACC7D82390EEE4735920CE023B596F84C
-:10EA1000F7805A1D42AFB3E2B94EE1F36AB41BD995
-:10EA20003B2E7633AE7B71324929C6BC82F23CB6AE
-:10EA30001F91267B0DBA7B26294556DD3B0A69BE10
-:10EA40004EBA7CE7195D75F5BBF87BE9CABB950C3E
-:10EA5000D095F7A81CAACBF75C7A83AE7E16453812
-:10EA60006DBEF79A5B74F5FB564FD1E5AF5D7FA79E
-:10EA7000AE7EFFE06C5DF975DB4A75E5836A17EBE6
-:10EA8000F2D7D73FA8AB2F27D0B35F72B0F38E2C4D
-:10EA9000F46CFB703FDE2BB29B2593E63C57CDF721
-:10EAA00023D7519401FEC755F6711970DE6C4CCE18
-:10EAB0007686E3F42BD27FF41CF6BC436F3FCBE3A6
-:10EAC000F6B3F3FB281781DF57B19FE201FE7E26E4
-:10EAD000FFF30E6E0F98E586FAFCDD0AC583EB980E
-:10EAE000EE30A35D2CB6FF6A873BEEF94936785CC1
-:10EAF000C552627809BCEC085E2FF3F9FFB3F03A17
-:10EB00001413F723CE6FB1EDCE390C5CBFF637018D
-:10EB10007F6B3BA79156D987E7B4CFCF0708F05357
-:10EB2000827A4B223D408C2F49BE4FA09F587EEAEF
-:10EB30005B3A8F9D330D5EBC8F95E8FC76CE117BE2
-:10EB40007E2B9C81FB916CD4C1E9D3363AF7EACE97
-:10EB50006FAB92B3F1FCB64AF5665CCDF9ED5307A5
-:10EB600032270A77373BC78AFD347ADCEC1EA75E72
-:10EB70007F69AF6F53F947D7B90EF43809F4B2146F
-:10EB8000A67FEF64F7FDC5B857A16F13E755E8DB23
-:10EB900026E259A3C8B85F4627AC7F5EF87E8BFC9F
-:10EBA0000FE9D74EE7F7907FEFAB1E8CEF7F7F82A8
-:10EBB0004CE0DD954B4523F19E74227CFC90DB5F9D
-:10EBC000DE7532F87664BF787F59C915EF57BC3FC0
-:10EBD0009EC5514E89795F778493D1CB2427C7078F
-:10EBE00013B3439C7BD98EF1F0E76EF9087F2FD2E7
-:10EBF000B9BA61C303F87BC03C4B206E2660B3A357
-:10EC00007D6FCAF811C397DB3578C47FDF58FE2BC0
-:10EC1000EF38C07E336547EFB4802D31FE4CE2EB18
-:10EC2000234AF81A8C977EED0CFE3E9A29BBFAA671
-:10EC300031FBA23ECE2CD6EE33656939E29BC897F4
-:10EC40004508C695B5E515769FB82CA2601C5A17E5
-:10EC5000279783DC2E94105E5709CFD8EF029EEFE2
-:10EC60008F3FC3EEC55BE2EB1B3F71EAFD16B1F7C8
-:10EC70005212DDB798CDF7E952D128BC5F3FC5E805
-:10EC8000EE7B35762A01A7A6CBA792802FEC81FBDD
-:10EC90002E71FAFF9193F1B33DDE13296096CE35C4
-:10ECA000B7E603FEE7723B789C78FC0AA0BBB19103
-:10ECB000A21F241E7FA993DBED78BC7B81D3CDFD01
-:10ECC00092FA78FC8EEE134D36C6976FD3A2F0FB06
-:10ECD00008E8F5FE8D2AC6EDCDA7730880FD6D937B
-:10ECE0008AF6B70F2E9B08F8414E6D509F8138B3BE
-:10ECF000928DBD373E4EF325E34DE8B799BF89BDF0
-:10ED00003342C65B82E07F2DD9F4403ABC1BFE192A
-:10ED1000A5DB4554699ABFF1098C7BF9E0F823180B
-:10ED20005F7D06E8997E2FF9F667D301FEBB8CD58F
-:10ED3000D70DA1E9A2ED92EE7E44698D459717F1BA
-:10ED40007B62FF8814BD37E1A6726433DF2F21AFE9
-:10ED50008745FD5D9B9DCCDE8171F0E513D8FDA854
-:10ED6000FD27D9F9FD401F16DF171A7F7BF110BA76
-:10ED70008EF169EC7D96D8784002CE31783F85C718
-:10ED8000EB8EFF4469BBC7C2CABDB642CDFD80D77A
-:10ED90009755E2BE8CFF35B39B8CCF6271ED09E3D2
-:10EDA0000433DAC5F9F703B9D92E3E307A7FE76824
-:10EDB0003CBCF9430C5DEF3FC9E201E7BDCDDEC7C6
-:10EDC000EA886F7EC8E7FDC1F101773D4FE1F1416F
-:10EDD00011E3E21F5CBE7935BE3FE39308C4659E34
-:10EDE000BA1CFF9E58B253E84DFEB6FB34B03F53F9
-:10EDF0008B16B4E5812C6FF3DDA7BB6F73F5FCE6D2
-:10EE0000CAFC64A593F91162F97B2CDEFF9FE2EF47
-:10EE100053C61FC884FBF734FD1DDEC3DFC1F86392
-:10EE20002C9DC7F27331AFD8F996450CBAB8E16999
-:10EE3000C0074668F9B911F93C55EFD9BB30D94A3A
-:10EE400070A5847A80E4A270186E0BA6E4D221FE2D
-:10EE500007B1ADBCC8008000000000001F8B080097
-:10EE600000000000000BDD7D797C54D5F5F87DF3C2
-:10EE7000DE2C496692C96412929084093B15718018
-:10EE8000B008A82F04421482032AA2069D84256C90
-:10EE90002191AAC54A9B810444441AEA8614ED4094
-:10EEA00041F95AF41B116B6C834E04115C6345C528
-:10EEB0007E15C3229B2811AC1FEAC6F79C73EFCDC9
-:10EEC000CC9B4C58FCFAFBE7173FEDE5BEBB9FFD22
-:10EED0009CBB4CAD737D82BF2F632929EC369F9D6F
-:10EEE000B1B3F87755383D611F69760E62ECD138C1
-:10EEF000BFCD990AF5DECC1CC912191BF856BDE22C
-:10EF000087FA271536B93E46BB1FE34C8C41BB2D13
-:10EF1000665EBE05EBF50D97A739F37F8C83FEB6D1
-:10EF2000DA20857A8CD99C877A3396C74C2C496530
-:10EF3000AC58F1A7E17815B69695A5503A6FF7B79A
-:10EF40001628620F5BFCE95A1E63814C8B77636E57
-:10EF5000FB713D4EA804EDD2168C6407073266B5EE
-:10EF6000B140DC00C6148D05CC03701CFF2213B425
-:10EF7000D72633B65C61AC19E686F559EF74134BAE
-:10EF800063ECD736467F81910C27C30207E28335B5
-:10EF900030CE8F4CEF8970F889E9BD705E9F30BD2F
-:10EFA00037A672DC5AB14ECDC4FCCFC58047A953F9
-:10EFB000E1E3305F4F9F83B1E923993F121E321D79
-:10EFC000E7D4A85EFE2337E5B440F9E7FB6FCE61D6
-:10EFD00090EE787848524B8CFA32FD437595771451
-:10EFE00034BDBFDA4F6912633ACEE781EA99DE5148
-:10EFF000DD1973421EE735DDE2EB991CD1CF65CEFA
-:10F0000064C253E2E55B9ABBBA193BB442752A1E4F
-:10F010004899A908DB1F0C26156DEDCBDBB90DED6A
-:10F02000F83C55A633D60DD66DD7BE6B11B03BCB91
-:10F0300070BD8CFAED689DA5024F16E6B5617BCBDD
-:10F04000816B6CAC2BF4A7E84ECC4B7AB81C4640D5
-:10F050007AB8173F5D0E74A7F86F71523B3D459625
-:10F060009FCDC5F18B282FC767592EC6323A861718
-:10F0700053743FF67394E9A598365802973861BDEA
-:10F080000DF16C662C7A2E17F8EB21D6C598DD7938
-:10F09000F812311ECC6F63823E1BFB3969F3CDC57C
-:10F0A000F4CACEAD352AD24D9C53D46F61887728EF
-:10F0B000BF1DCB597A0BBB16E07D254C763964FF1A
-:10F0C00071F400F3009C125B0F310F8C9F88F88B5A
-:10F0D00001376B32E7ABBF3356149BEF142A5F281E
-:10F0E000E6B901F8C5E40EF3CB53D0EEB9BEC8774C
-:10F0F0007EC177FA350CCA37FCD1A52C87F2AEBA9F
-:10F10000C784F4E16E667A10E121E02EFBDFEBB4F8
-:10F11000101C900F9573F0E1AA8BE4C30D7F1C6760
-:10F120008AC379FE96797B78B0DCB3D806F927E6F6
-:10F130003BBDCB21DF6D05101AD4CF5E10BF5E85BD
-:10F14000FA6B9D7C9D5D1E628BE3A076EEDA560D18
-:10F15000E5C3B885CD9A0DEAE7D6B668289F5EFA72
-:10F16000ED9A1CA4AB639F5FA33AB0FFAF65FF00AD
-:10F1700020E0F7E14E8E4336B4B40BE267B393C39D
-:10F1800057AEE38FF1FEA7089F55AD0556A896B37D
-:10F190008069282F8F29FE3FA774C37EE32707FBD2
-:10F1A000227A39BDBD74F8789F32C8BF24F95D1941
-:10F1B00099C9D2191BB1C14CF01CB1E1E15B11DE60
-:10F1C00023368CD114A8F2841652345C6795AE05B0
-:10F1D00020FFA6D34CE31FFB7C761705E7FBB19518
-:10F1E000F58801DF9D62FD9B9D5C7EFDC3129B6ED9
-:10F1F0005F6D933B9C9F863345CAD757857C4DEC0A
-:10F2000006F09877F72992AF7F717AA8DF27B4FAD2
-:10F210009D99342FE60DC0A7D99BDE23792FC79186
-:10F22000F5E66C5EB714EB65DDE1ECAF7AB05D4BF3
-:10F230001CD2CFB7711C5FDFDE1D1F5CA410FDF771
-:10F24000F75D1A830F59C86A4A270CD878AADB4C95
-:10F250004301AFADADF928F7A0CBC5C89785C91E4E
-:10F26000035ED6B53AE3915FCEA70F0E087C5E2809
-:10F270001D6E4FE67C03F25F473C05066BC11AF832
-:10F28000BECEEE3F8AF23FCF1E4CC9872AB5E7D7E4
-:10F290009B2710BEA0374FFE2CBD29F4A5D49F6D2F
-:10F2A000E5029F35427FC6D09B3FC6D29B6E16BCFF
-:10F2B000BF1FAC879D307937B2F6E32E14FD9E8CCC
-:10F2C000D7D564187F84C27C386EE289034C89905C
-:10F2D00043F3045F6F1174F0948BDD3621C63A66F8
-:10F2E00009FA3495B45A5AB09F4685E8BFFD7AB9F9
-:10F2F0003C01B998928C7CD605E4A6D25E6EC6C05D
-:10F300004726CEB3F35BFA76249261C91B1200FD47
-:10F31000E7C2474E32E143EF82A984FF80B3EA6D32
-:10F32000BEBEEDE1DF3399CF7F9843EF81F54F0B00
-:10F330003EEB082F8392393E0A93B93DB3C521EACB
-:10F34000C519EBDD96CCE13C35D9C89711F81B9473
-:10F350001C037F520E9F8CF70DC575FFFDE89604C8
-:10F36000A4238927297FA2F115E6B345B41E807333
-:10F370003EB68FD63FB27DB41E0AB70FD07CD721E0
-:10F380001D21BF211D79B89E58D7373C3F49E7253D
-:10F39000627D67E3F5625C4FF43C9D274CCAB9E699
-:10F3A00099DCEA5690FF937527A5FF386A52705E84
-:10F3B000CE564DC17939857E8CD683202E04DDF062
-:10F3C0007EB6A3DC80F1977E39351DF1BC34DF9F1A
-:10F3D0005E05F5AF71E8FE64E223BD14E131C5A11D
-:10F3E0009761FA631CC7F3A0647D1AE693851D1527
-:10F3F0003DCFB9627D00CF39D84FE22816407D78E5
-:10F40000D5197B10442C8000E60DFA2151778E44EB
-:10F410003D96B89679914E53125A9BAC906F7D9859
-:10F4200079D743BE67C063B2A27EBB435F8CE9D28B
-:10F430002F55B23B97E6B3E062EA87DBA1ACB66B2F
-:10F4400090F437F05B24BDFE5ECCE3F7C99C2FC17E
-:10F450000EB92799E3F977984A3B44F2514776452C
-:10F46000041FD652BB0BE7C3FB71FD17C1877F4852
-:10F47000267F42AFA3799E870F1F0DF3E12358FF2C
-:10F480007C7CF8A4E0C3ED22ED880F5F13707B3322
-:10F49000B943FFE3C9587CE816F420E91DF910F5DB
-:10F4A0007DA39827C8CFBFC6A2F70BE0CBADB1F8BC
-:10F4B000329A1FDBFABB40FAEFC8FE1BE23AB7FDF7
-:10F4C000D76CE77897FC0CFCB253F0CBEB825F76FD
-:10F4D000717EE17A399ABFDAF44D2B97138CD525DA
-:10F4E00020FDC879EE97FC13AFBF17C967D24F91C3
-:10F4F000F093F5FF23E8FBA848135B0F30940B0053
-:10F50000B77F45EA8DA704BF048632E217F0B746FD
-:10F51000A25DF9D209B0232167777179306275F362
-:10F52000766475A6D5254C74740CA72B5D1E01CF8F
-:10F53000D87082F1BF8885B746C49BBDBD3D1F8D85
-:10F54000AFBD623D761787C7CF9D87841FCEE3325C
-:10F550009A87C7B43C42CF2B2E45D21973417AD536
-:10F56000A85695D1BC4209E042B5C9539605EDF3C2
-:10F57000DAB7B785DBDB5C30CFAB7468DF37DC1E16
-:10F58000C62779D7ED0E90676427EB26D44F4B73CF
-:10F59000393D44D3FD06B41FFA46E0AB2E93F0B5D7
-:10F5A000D2E64FC3F96DD03C26B4EB362C732A015A
-:10F5B000C263553CD28FCDAE135FC7904359AE8B1B
-:10F5C000B3073C2E2E87725D1720877A0BFC801CB8
-:10F5D000EA85F5EDE791434304BC86BACE6D0F0C86
-:10F5E00013FD5E29EAC790434370BC6839B4D5C6A1
-:10F5F000E110834F8763FD34A73E02F1047C7A85D6
-:10F600002B42AF41BBAB30BF52B45F5167EA4DF6FE
-:10F61000338BF7C6F233C6B9EC063BE50AE13FB0DF
-:10F62000C6EFFFF6DBC18C5562119FE738314FF210
-:10F630002736D41D4843FCC39F21AEF2E062EFBBE6
-:10F64000DD116FEFA80CEDD0077FDF62417837C482
-:10F6500027F6639785C7ADFC0E083205F0F29D8949
-:10F660005289C7798D8B0632F023F20FFE90837694
-:10F67000E5C9FDDF517CE484BDAC04C7DFB18DC7B3
-:10F68000494EBF353505ED7339FE7CC417CC6BB4DC
-:10F69000DAB73E04EB3DB5CBE2457DAB32CFA323D9
-:10F6A000603E95BBCC2C48728AD9B0BE994F9799D1
-:10F6B000772D6D561331AF05447C43394BFE8C27B3
-:10F6C00009E9D6BC4B65C887CCCDCB03CCB6E82CBA
-:10F6D000F89B49434DCC13110F49D6E39927223E9D
-:10F6E0009152E432E4537D9986FA9D2677359467EA
-:10F6F000F87F6528EF3C7380219F5D35CC50BF0BB0
-:10F70000F83B91F9DCC03586FADD964D34E47BD4C4
-:10F71000DD6CA8DF6B7599A1BC4F70B6A1BC7CF7FE
-:10F72000F316F4AB2FD934DFF0FDD2FADF1ADA0189
-:10F73000409ABB039D4C631CFE97352C36D49FD654
-:10F74000327B1CD26DFFD07263BB3AF3210ECF0027
-:10F7500043781E617E0BD299C65A777606B8CF0BD6
-:10F760002ADE10549BD590DB0DF9E18B378A762980
-:10F77000FD605EAB793BD9CFACA0313F47DD4CFC9F
-:10F78000138DE74AD635C9938774A0B2A012C6FB81
-:10F790009C4DC6F60CE35DD06E8E584F345D1C61F7
-:10F7A000558F8C40FA08E8CDDDD3C2EB36B3FAC1F1
-:10F7B00021FC2EE8C429E844AE5FCE5FAEDB09FF32
-:10F7C0006139287C0BD2D98C0685AD51DAAF6F66D2
-:10F7D000E3AAA59D63AC93B1A005FDEDE8F9875CB4
-:10F7E0000E37C5AD72580EC6AD583BFEB0933C3EC9
-:10F7F000B5560D5A81AED540EF28FE30AE3F1A8E79
-:10F8000017CB2F1E01076BBA915FE23CF1D1F436A2
-:10F8100038C4DAC335A1B7918F241C255C1DDECC1A
-:10F820009874E581FF387C75F64BC2F704C2372126
-:10F830000CDF9336FF4994C3A7F77EA312DDF95B73
-:10F8400006A21EEB482F391C234FA31C83FA3958FC
-:10F85000BF3201E46212F473E0879EC86FB29E6FFC
-:10F8600041997714C84545F1FFE08A888B34EBAAAB
-:10F87000230FF035A741F5A21E3EA9D9972997D1AC
-:10F88000323DCE3454D2126F1C8F126F4AE3F6FF12
-:10F8900028002F68E3B760FCB5C86BC3798227479F
-:10F8A000714E05DC9BB309A467E353283EA2338A5B
-:10F8B000FF9D62DE1AE8AFC6F1B74BCE130F494C7D
-:10F8C00021FFC29F118FF6436BCBE967B17BADD9A6
-:10F8D00089E34CF0FB693D43708260573327C029B0
-:10F8E000225E04EDD2B1FD84C7FF9880F6F04B870D
-:10F8F0004EA9A45F3E71933D2CED83F6F67580F41E
-:10F9000097B4D7C13FEA92C2ED985CECAFCD3F12FD
-:10F9100076B5F4733AEA07EC8EDE68CF74942AAFBA
-:10F92000AAA44F5B9578EFFA18FA342F4589A94FAE
-:10F93000417FE6A5A446C4E3EE3CBD13E51DC07BB4
-:10F94000087E7738C0AE512EC8AE198EF51F4D48CF
-:10F9500024BA6EDDAD067B418353364F920BE03601
-:10F9600052E85945031DE20AB7ABB2B9FA6A03B1CE
-:10F97000BC4F128BE1A7C87424D64B89882FC619B7
-:10F98000FDD1A503F8BC8A53B83D739FB09F4AC50B
-:10F99000BA2B310E97128EC3554EE671E687A3E25D
-:10F9A00097A5290EAABFC43EB214D7B3345721BBC2
-:10F9B00069A9A218F6919253F2A9FC16D17F29F4F5
-:10F9C0008DE33DD595CFCB1DE5BF678BFAD929BC1B
-:10F9D0005FE0A43E886F8BAAC684E78C143E7F69E3
-:10F9E0003F49BE192BF8A650C8CBAB7B80BC24E6A0
-:10F9F000D2C78D86F251A29CA96BF758A17C6C2FBF
-:10FA000033433A1B857209E5BCD37CA0A57758CE59
-:10FA100017F6AEDA81E2614C3A7C8F902745CCD75D
-:10FA200019E9E06A8FF1FBD83D85C7905FC7328D39
-:10FA3000FAA1EFB91CAE09AE30BDFF3EA54D1E794F
-:10FA4000CE025F87E2FD0F1663FCE16DD5BB9EB56C
-:10FA50005FEFFD026F2B849F82FB48E87FB844DA9A
-:10FA6000BE3E87CF6B76DFFD044F0DE0097C1BB2F5
-:10FA7000B4D424E1381F301A2773A6DE84F9413E3E
-:10FA80000FC338F1D25C66F7227DF637511CC4ED06
-:10FA9000778EB240DEBD963C1566D658C031202C1C
-:10FAA000179E4EC925F8AF60354D49503F69EDD7D7
-:10FAB000AC2BF90FCE514E9443D358CCB8E646B197
-:10FAC0009E098F77D5D00F4BB2297A30C63A368A45
-:10FAD00075805CD880F2E12ADBFE814AD7B05C41B8
-:10FAE0005796FEEF9029B85169DFDE662F781AD756
-:10FAF0003F6826EB20CEC9E731DDE6ABA77A7B3C39
-:10FB0000B43F512EE5F33413D3806E6E126473D379
-:10FB1000DAA6FF903DF0C3D9B3AAB4B319F5CF70FC
-:10FB2000BFA07CAE2388FB07E58DB9018A0FCD54B9
-:10FB3000685FA3B2F13D1FE6CBF3F29C24D7121409
-:10FB4000E5706F32D11997631A3B2CE945158B820A
-:10FB5000FE270BBD20FD79D0032B1200FEE56BD7ED
-:10FB600035654095FF01858F78DBABFAF7DE03FD45
-:10FB7000DE00CA69C1004C35564271F474EAE77A76
-:10FB8000D14FE03BA61CB685C7BDA17137AD67AFAD
-:10FB900099056C404CE6917C68F36F93687F15F48F
-:10FBA000298D3BC956371AF5DC494B6B3F2FFAD7E5
-:10FBB000DB3ECA0E003D7DFABBD30E0678F84C6BD7
-:10FBC00075E0F7A30BDF77E800BF4F17AA4588CF92
-:10FBD0005B85DE90F03E22F07EB9DBB70FE17D5B06
-:10FBE000F58F83FD91719205A924EF670561861158
-:10FBF000F6C39C4D0968D1B4E52BEA530C79A907EB
-:10FC00002AACAC2A565CB0B39BFBF3B336AFB374EB
-:10FC1000F6E0F8FE561CFF28C85BC4CBD1AD8E20A1
-:10FC2000FAB3723E659BFB5BD0BEF8ACD1CA42E82A
-:10FC3000AF68CD6666E77244017AF00BBC47CF73BC
-:10FC4000E7CB09D4DFF487B9DC2985B116005CFD68
-:10FC50008DB348BE44AF63FAA79EC24E00EFE9F7EA
-:10FC60008126F7F0FA0B016FFE05F77E8DF65AF448
-:10FC70003A4B034679337599312FE560B9C037B0F7
-:10FC8000DF32B47BA7D719EB9537DE4FFD97A39CE6
-:10FC900092DF61FDC96E61870E6643502ED5D8BBD9
-:10FCA00026F9CFA1774E548381DA93B1E3D5364A52
-:10FCB0008F56334AF7A5707A9DDBF8DE5D4837F33F
-:10FCC0001A9EB3603FB5C1D1CE6150C5DA081C851C
-:10FCD000F625EE1743D329B85F0CF3ACC18964E075
-:10FCE0007EB2AF9B1BDA9B9D51FBC7627D2502FE56
-:10FCF000CCEE22FA2AC1F5F4C3EFDA3791EB39B52D
-:10FD00006BA00DC7EDEB16F27608AC4BBDF075C9D4
-:10FD1000F5C8F5C9F20A15E82C467B49DFFB84DCFF
-:10FD20009AB661C2D24C0045CDB623E41733619731
-:10FD30006B023F9A7D39D9E51A03BB9BAF53D8E5D7
-:10FD40006C0FF2ADA4B3683A2A473820133B793BD5
-:10FD50009BB0D7DBE8A7F1018287C433F0473ADFD5
-:10FD6000C70BA5E33E1ED0D1A1283A32E4A7D7198C
-:10FD7000F35F995B7290BF815E0E45C2F7ABA8F34B
-:10FD800023321DEEEE4AFC36CDA3173AA17C3AF39E
-:10FD90002D75D2FAEB082E47B5BA9DF720DF6DE03E
-:10FDA00074FF99C07B83DB57EA267DA5F7437D3539
-:10FDB000727186EA867AA52B1427F2D3D4DAFE85EF
-:10FDC000C88703984EFD4DE9C0DEAA7173F89755B8
-:10FDD0009999059465198C8172AD6CAB1AE4712BFD
-:10FDE000DD5E0C789829F05071DF73960C486756E9
-:10FDF00095733B20C8F905E04A76C0EC154DE457F1
-:10FE0000835F1193DFA41EA8A8379657B215848785
-:10FE1000CA287BE0F792CFBCCC8BF4E8BFCB615310
-:10FE200092CEBF5ED63E6E42719553BB7A907D787E
-:10FE3000CAE3E984F5FC89FC0C8DA2F987E07780A0
-:10FE400013E9A3D6450941B47FF79F01BF0E6D3278
-:10FE5000A77F8805E0D2F2AF6CDA6795F429D75313
-:10FE6000695B41F459C98C7E63293828180F2DDD50
-:10FE70009812C4FD71E8BF5F03DA151BCD64370427
-:10FE8000D8FC740674E65B62267958D6904C7E6B7B
-:10FE9000592DDF4729DB9C1C54B93FBE07E31012E4
-:10FEA0000FFB6B0B2C1984A75C2FEA35D66036D07C
-:10FEB000B7C44FB4DF377B59D3CE744FC7718108B5
-:10FEC000FC1CEA003F8722F1B3250A3F6C610A97C8
-:10FED00033B7BFD603F78D4E55C579D5187E84D478
-:10FEE000432C0B08707038BE569429CE3469DE342A
-:10FEF000C4E7E91583085FD1782AFA692AE183FD0E
-:10FF0000CBC130EE3AA51BBB6D227CBF4DE1FC316D
-:10FF1000A5E6EA22D4D76FBAB99C7917E4936E614B
-:10FF2000EC3D904F3AC8A7F7416E61FE83EA74CA70
-:10FF30007F54EDA1F4E3EADE941E12F6BCE41B202C
-:10FF4000000BDA51EF09FDF89E5BFA4177A4A3E9B3
-:10FF500050F4D3FB834C406BA98159D78CCE66EC0F
-:10FF60005ADDA8EF265F6FD4672D6667613ADA7DA8
-:10FF7000F729B4BF50E61B6EA8CF348F6502FAAFE5
-:10FF8000BD0786BF933DE7B14C047EBF695C8AA183
-:10FF9000FEA4659D0DF9636E0FB71B8BBA19BEDF0A
-:10FFA0005C7289215F7A06803010A9D94578B8C380
-:10FFB000C6847FEDE2714F71BEE49BAA219D7E0352
-:10FFC000F3FDE62D339547E343E275DA6A13F3C395
-:10FFD000D4A6AE86B541BF87EA004FD0EE8BBD0EEA
-:10FFE0008674BC74F3C07786427EFF6633C52FF7F4
-:10FFF000D7A6AC44FB68FFE6D4448C8BFA97AAC220
-:020000021000EC
-:100000008E705A5884BC2AA85D44E74E4A83562F06
-:10001000D90B3B024FC8BC4741BE679C5FF6A84165
-:100020008C5301FEB87FFFB495E2F247C16E738234
-:100030005E38AAB05A4C51B12441F9BF9B5383C8D2
-:10004000CF453FA97A3AD2D3D37162DF45A1FE8E64
-:10005000BFD763FD72A22F4F7D88F8D64AFEC0D469
-:1000600016BE3EA60CE88CF83F9ACCF4649844C5C2
-:10007000FC8FF66980A7593D9BFB85A05D496E28E2
-:10008000F5466877628399CEA160BF4EC857FCD50C
-:10009000BA8ECB11BDD3844B23E119EC87EB9E6262
-:1000A000F265A7027D1D9F11EC47F26C612AF155A4
-:1000B00034DC0F59FC04DF00F28112968F613EE3BD
-:1000C000FB6920D43250CE4C357BD3503F1D5A6152
-:1000D00026BB13F447228E0F9C4C747C48F314E229
-:1000E000BA0F2DCB6528AFE4B8652B54F23B90FED8
-:1000F000A8FE2AD50F3602937A2AB04CF1B34EED02
-:10010000E9E6D7B70FE984EB89B66F65FA15F0AA6F
-:100110003FC25E98BD4DF5A1FFC1F25AB4EB2F8DE1
-:100120005C472DDF5F48E7FDDF21E4FADCAEAFEF8F
-:10013000B39B50AE774B42BFE2D81E95E8EC58D740
-:10014000BAC1E9DDF0B8C8AB837F03F92F8A038712
-:1001500035C83F61F55F930AFDCC31ADC841FFE87A
-:1001600064E3C195C3A1DDF167CC5E1C76F6D3B321
-:10017000BA50DC5DD8D7EDE55628539CF3C9500042
-:100180009E733CF5A4B73D9B61105A7F90FB49429A
-:100190008F3B1F52D096620707399663DC622AB004
-:1001A00047A4DD7DD0CCED8292542EA7A47E5F23A0
-:1001B000F2534D9CAED9CB0AF96DF067D003522EA5
-:1001C000CF49ED4AF5DBF432AB27793503CFB1C027
-:1001D000FAE66EB20683B9D4C6897C3E8BA3873D0E
-:1001E00095EA213936DBF2CC23C843E5AC99E67DAC
-:1001F000DC1C9CD19C8BEDD7D5BAA8BDD94BF15353
-:10020000A14F6CC040288FCA05DF55D429C110F119
-:100210000DD78BD345FF0CF54C84FC6AAF578CFA95
-:1002200064BAD0A3D35954FCB5CEA8DF7C09DCA9AD
-:100230009D0DE3A2BE0CCF0BEC6380D90C7F70E761
-:10024000789AB7E20DC69847396B0DA938EFCD3CC7
-:100250000E1F3DAFE8755CE83C6778278C4ACE8B73
-:1002600018376ADE12DE14C08DC08384FB8C0087D1
-:10027000E78C4685F0F5B9B0CBE08FE2C612EFE52A
-:10028000CC371ECFD7953F04F232374C076D7AFF3B
-:10029000B920ED377CC1EA12ED40F773573F37E9DB
-:1002A000726CB7F63DF22F4A5CA11EA664C65202DC
-:1002B0007B96175D11639F21CA3EF8A5E083B3D7F3
-:1002C000068B76008FE91B543DAE9FA11EB597F6B5
-:1002D000C1CC40C08271C99922DE77BE795662BD19
-:1002E000011732DFD8F6CCFF75DE7B5285FFD4CE06
-:1002F0001EEA11D38F6AB383CEA37F3F3187B251F9
-:10030000FFB6666BA47FBED1BC1FE5BB511FF720B3
-:10031000BFA023F93A43E8E1E9A897213DBCFAF9E7
-:1003200044F4DB3F7FE879DADFB43C333D11EDE2A2
-:10033000C3ABA7AE0C004B1DDE3C95F470F91AA9B7
-:1003400087FD9648FD5EB0BAF4CFBF43FADC144790
-:10035000F1F9193BFCC2EE0679877270359777EC9C
-:10036000212E0FCB515FF5257DD50BEBDD35C3DF9E
-:100370000BE93CE23BE9B1BBA6FA87507BE60CA156
-:10038000DF05923384FA4AEA53A9673593DF9486EE
-:100390007A407DEB83BB61FD5F6E51C9BDAB50D729
-:1003A000E53831EEDF81DCFEF9F036B5C13BF7020E
-:1003B000E05D86F026FB87C3FBC0320EE7832B3857
-:1003C000DC976EEE9688FEED8165DDC8EE39B0B93A
-:1003D00007C17BDA728037D9BD1EA3DDB30CE08D77
-:1003E000763EC21BC62DDBE111F0F672782F137A30
-:1003F00067054FA7B5836BE056942777FDC5EA459F
-:100400007D7E342E948AFEC8D1E75486E70EDAEC5E
-:100410002261BF4838FF9BD53D8176543B7B669572
-:100420009561BC72D60B8E2083FC7125BF1322E030
-:1004300044DDEB89385E78FC363B66705AA41D7348
-:1004400081F899C77C742E7F5EE3EB7BD18E577465
-:10045000EED7CFB3D943C8B7E0EF9C8894E78A07BB
-:10046000651AC649BC361BD24116F3F8C8AE91FBDB
-:100470003F7E86FB3FDFF6F8FAD6F9C4CFAD3D23C9
-:10048000F7492AE343668C2FB53EA710BE2BEEC872
-:100490004FCC67B8BF5445F3B82E8DEB6345D729D1
-:1004A0006E6805BA8987F126A579F8778F93C71109
-:1004B000D7C2B88EF07CA3BF8F47D2437D6E8F1D0D
-:1004C00087AD15E354A826F23BE65AB8FF21CF7753
-:1004D0004C15E553D3B8DF3E2B8D9F9F3889F17DB6
-:1004E000E8F7E4AA04715E7914C533DBE227126EE3
-:1004F0004EEDAB3679857C25E207FBB00DCC739AC7
-:1005000055C47341C562FB5B44FB5BEADEA6FD3567
-:10051000F05C1E47BD3B6581D58BF66B609B95E813
-:10052000EEDE78BE1FC2DC491AF2D1CD42CEDE52D9
-:1005300077BF0FF731A7D425E898C2380126E2A784
-:1005400079B89F9A69A1F86989ADE51974B36F4BC1
-:100550003F78A70D96B6C8C4ED96452E46E7632EA4
-:1005600003B31DE3B17874E46CCAB9E8C7181F9EE1
-:100570008B71DA618C13D65082AB210FF0A5FC9AF7
-:10058000B4D1631FCA62EC9FCC7329E27B2EC206F2
-:10059000E9A13489E200D762BCD885A946743651F6
-:1005A0006301134F9761684DC68FC78B75DF309419
-:1005B000859260BDA1DDCC10BFBE31640AF5023C5E
-:1005C0005CAB859A90AE4D368F19FD015F9132007C
-:1005D000FDE4B98B2F6CBECFA4F968BE734DFC50FF
-:1005E0005FEBDD4A703DC0E9166072A4CF5B35B6A3
-:1005F000431DC0F187F457E9F204A8DEED9CBE6507
-:10060000DC5CE2A93F741F09DF5BC4FCA09F658925
-:10061000D8DE123B7EF4529AF483B9BD3947F0EB31
-:100620001C496F9B8D7CFA31F20BD457D0AE05B8C4
-:10063000DD22D28EE8FD43D1FF8769DCEFDE7191C8
-:10064000E355585988D6BDCD4A7894E35E2BD23D08
-:10065000693CFE26E721E999893894092407D2D11B
-:10066000A1BA1AB29B6646C5815964BC4A8D956F82
-:10067000933FA6B3985A5AA7E17C942BE3BC48D782
-:10068000B758EA7B54D9DBD793FBB125ACD9CCEF73
-:1006900013897896D057A3557B6FF4774A94782FB7
-:1006A000DABF27F31D015312C65BCC84DA12A00710
-:1006B00094CF9FC4F1FDF72949778D47BBB024D172
-:1006C000A2617A1B6B76E4E686ED92A5F930D94CEF
-:1006D000A4B2C0581DF235284F78FE7E3D8BA24350
-:1006E00022BFE44DDCB7B8FE07C03FE5978ED54189
-:1006F0005E9C7C4D94B37BA9FDC925828E03F78F48
-:10070000C5FA271F96E575BCFC3E59FE10CF3F2069
-:10071000FB17F95551E58BA2CA1FE379CBA30F8DC7
-:100720000DA03D2BF6634A8629244F0A059D952C82
-:100730000E117C4B4CAFF274240BE17D89F3D51B79
-:10074000D0C957887A4B751C72A0DEBE3C432F443B
-:10075000BB6340AA3FB913A4B32728010BCAC93D04
-:10076000C19E42AEC73C675D28E8F6B274DE9F8446
-:1007700037F493D929F5E2FB7919E735C8D04FB79B
-:100780009FD3CFF2F6F3E9FB73FA3919D58FB48B07
-:10079000EECDD4C7209CD821B7E1FCDC9CDF7B9355
-:1007A000D0AE62787E0E403F67717DCE40E87FCE4E
-:1007B000B32FE5CC88F0BBE79D31311DECA7CA33E0
-:1007C0008CD22F9A3EB678603EF3B636590AA15EB7
-:1007D00025A40511F39A2BCF8FB2166D62845E1F8C
-:1007E000D7C924CE25AEA2F9CE79F618ED5BCE316D
-:1007F000D51F5E83F19E613CFE16BDBE3CD16E1FCF
-:10080000EE23C7B0DB2776E27AF8AE2C7D02AE731A
-:1008100020CA0C480B6A62EFC3FF49F45712CFE5B8
-:10082000DBD4C10E9BE732DC47F5D7E0BDAE196BD8
-:100830007307601CF786D491B710DC3A8C8BB6F244
-:10084000B868238F8B96B89AEF00E1CD1EE9B4F516
-:100850007E1BF871631F957C062C0B6D8BAC32FFF1
-:10086000E6D8515914E7A2FCDD8FEEB83F00FDEC4D
-:100870008AE7E70CA60CB9341EE5424B6E82C90923
-:10088000F2E25677E923388F2943AE28C4EFF956B0
-:1008900047CF521E5727BAB8D5EDBB1DE905EB630C
-:1008A0005CC36FE1712EFF1B2AC5B9FCFD12FCB1C0
-:1008B000F6A92B3B71BA79A49393D25D8066B43BC1
-:1008C000E43CE4F860A8DCD10CFD1D5A9CD11FEF7C
-:1008D000CF35B8F31F26B888F11BDCFEC59897E327
-:1008E000C372FBE1F70B9D47B5C0C7C3026FBE11D2
-:1008F0002AD323FCC589A3120CF9EBC7A5303D32DE
-:10090000DE7A7D67437E72493743FD9BA75D62288F
-:100910002FB636E7555D84FD5BE970C4A31DF6690B
-:10092000E3BF3FBC05EDBA0DAA5781F5CCDAB6F1AD
-:10093000C3E150EB141E2FA5A0A787E25EC7F15CB0
-:100940001AF29EA66B91FB355FB2663ACF17B11FC4
-:1009500060D87799E3DC41E7097FA9FD9AAD9DC492
-:100960007EC0003C8A8CFAE8038AB3CDB3F3F57CF1
-:10097000F9D27E0BDD0340FD01F43D061BAAC8E75A
-:10098000018A431734ECA7FB56933A71B93C2FEB1D
-:10099000760D2C32560929CAFD42904F49401FCD91
-:1009A0004DECD2AD780E37D741E7262ACE4C642CD9
-:1009B00005E928D0F776A837675911E5E79D89A79B
-:1009C0007EDF559B0BE9BCF58B0AED1714779EB2C1
-:1009D00018ED51ACFF6B18AFF8BFC714217CE66D62
-:1009E000E5E72B8AD57FE6613F73EB8AA87DB1CA24
-:1009F0007629601F8C2DE07AB618753BE4D5C18E40
-:100A0000E5A85F554BA8E79F509E581C244F92CEF7
-:100A1000DC4CE3579EB151FB4F84BC30B7F0798D6D
-:100A20003EE3A3EF12EF073A7535DC0F34A76ED023
-:100A3000CAEC589F51FD6BCEFC8A52B9CE377AFF73
-:100A4000C58D72CC9CFA4D219E277DC3AD38C9DC83
-:100A50008892B7A7AB8624B118F2A86D9C33FC7CB2
-:100A6000B2F50C3FAF7C20433F837C3D7E618B869B
-:100A7000FB37CC6E7322BCC60FEDEF9911C147EA6C
-:100A8000AB3759102FE687DEB3A07EB7425A10511C
-:100A90005E21CFE347C9E39FDAE4F1224AA57E61F4
-:100AA000E937913D7AABBCCF2AF8E40B212F64FBE8
-:100AB00066A471C4E30B56F29FBECFF027A7433F55
-:100AC000CDF96CF216928FCD39B86FF24BCD1FF085
-:100AD0006C53C8BE6FA1F3FAE3877A4CB81F9096A7
-:100AE0002ED7C1F9F57CEB50D3F93ADE55D902EC9B
-:100AF000F7DDABAE6AD6A1BFA67B060E44B92FC701
-:100B0000ED956EE1FD3A5B7F407FAEF2E5040FF2BA
-:100B100075313A4779613B16BE338CFF55BE6C5D2B
-:100B20008FE7682A13C19F85F10B5E890B211D3762
-:100B3000BD12A7A17E782ACBDF0BE153F04AAF515B
-:100B4000E8BFE98D568DE2079DF4DEE9833A9EEF1A
-:100B5000F9E453349D49BEF42FE3FC522AE8B44C27
-:100B6000F09F5FF0D1E9AA4EC487A717C2A4719F76
-:100B700073A172E956B4073C0E3AFF23F9B218FD8F
-:100B80001EF85E7C4932F97F117C477C38F78C93E4
-:100B9000FAAB38E3117CEEA2BCE4B732C12F566148
-:100BA000474C13F43D3CD37F633ACCBFB806F81DE5
-:100BB000C6F12FCEC8433E0AD38BC5897405F49283
-:100BC0003E23826F6A9A6E62687F58DD3EA2976903
-:100BD0009046DA1FD3DBEC0F67611ACC7B7C6DAEDD
-:100BE000E1FE4989C0FF85D2FDD582BECAECA11EB7
-:100BF00068AF9AABE2BC789FEE949BEFCFCCBF8FEF
-:100C0000C36FBED95780F6C3FCC7142F6086EC0AA9
-:100C1000944783F7565922E38D379DE9C73C0087F7
-:100C2000EBCE74A7F48654FF6C8443E99949025EC5
-:100C3000FD7ED63EE0209DC797CC41AB771DEEB33D
-:100C4000C5F955C4EFD16CE67C3022BE84F1308CFE
-:100C50008BC9FD41196FB2E27E6A849EFCB756973C
-:100C600083FE4EBBB853BE711F6D6ED33F079BA072
-:100C7000FC78AE4EF1A729267F2DD2F3EC89C1670F
-:100C8000CD909FF3C0F38918EF96F0ACD7423D505A
-:100C90004FD6031C310E56BF422D0A727B2681EFC0
-:100CA0007F71BA96741C4DDFB3CF74257A3A5D65B7
-:100CB00025BD731AE89545E81DA96FA47C977A476E
-:100CC000D27385C6E556853D89CE5584F5CD041F82
-:100CD000C671596FC5DB8345EA9BF52B8721FD9FC4
-:100CE000747BF1AC4F34FDBF589D4EE76CA41E8958
-:100CF000D637529E4BF92EF5D5DA0CFF8B88F7913B
-:100D00007FFDFEF97FC1A76B34AEB7AED11C443F67
-:100D1000172E37F70BB9B9DF2037E77520F71BD34C
-:100D20002F4EEE3F2DF805EC57B20B51AE47F6F7BC
-:100D30007DC6C87711DF7BD2793CE0979A7747F27E
-:100D40007E4F1BFF5E98BC6F12EB3D9FBC3F22E4C1
-:100D50007DB47CC70B6D28DF4F6EEB43FBD3FB18D4
-:100D6000E803D47B8D099E8D42FE937E884F0A9EB8
-:100D70004BFEDF9535F54807F2FFE8FF45FE4B7A5D
-:100D800094FC22F943F24334FF487E187B3FF87FFE
-:100D900088A777F9FDA90A2DB099F60F3D09FD91B5
-:100DA0002FDBECB6AD0AF1593BBD20F826CC274627
-:100DB0003D21F942F289E48F0AC10FD3A3F861BB48
-:100DC0005AFFE03068579DE1CFC81814E68BB95B35
-:100DD000A2F542877485114336DD5DC590AE2A20A9
-:100DE0008DA42B6B07FC90937171FC60CFB8307AA7
-:100DF000EA9FF1FF9C9EFA67C4A6A70119BFA03D18
-:100E000071BAEAA33CBCCF743A0FE46C6E98DEC6AC
-:100E1000BEC9B8BDD08DDBFDE037D2BC7759B22951
-:100E20009E33F62C3FD72AE952E259DA01D3453CEA
-:100E3000615EA66F52466AD85FB8503C5BDDCD1646
-:100E4000F443A6431AA9FF3BB2776FC9B848BD9FC8
-:100E5000716176E2DC0C7EDFFD17B4137F83F088CE
-:100E6000C62B73BA0C7108D07FD791FD16D2E888D3
-:100E70004C877EC56A0E67995F12D2A4BE4D417D34
-:100E80000BF4B200C7FBB9F4525CC0443C70D738D5
-:100E90007D04E0FD0F22CFDE1A877C3869A82CDFA5
-:100EA000BD42D750EE301947A7B8C8BBAAC807DE65
-:100EB000786B14AC7FEC832C1C6787F2D12392DA19
-:100EC000E2280A0BD77FF4B1D7DF5A4178E6E75E14
-:100ED00098BF45E3FB4C229F077947447E68547EC8
-:100EE0002DAF9FA8B5307E4E31C8F955C5AD374EF0
-:100EF0003FBE087B04305988E709C66F559C180728
-:100F0000B979C449DA8F0DAFFF9FE3303E3BAF5153
-:100F100011F90FDFC2F5DEBC95E7B73DF6AF15015D
-:100F20004DF497467132FA33D72B3A9E7F983B5453
-:100F30000976CD6D0FE76D1946FF06FF34637B869A
-:100F4000E7EF2EA63DE299DA77A5F621EB458C7FF7
-:100F5000E388D8F712DE96FC25E209D43FC0F2BA46
-:100F6000FAD8F7243E10F59B71DF84E0757205D244
-:100F70004FB345C2F3AB1508CFD18CE73F7BECAB49
-:100F80007181BE7CFA7AD4FACF35FFA60CA3BD805E
-:100F90007F1E63FBD0B9E0F77ABBF6827E661AE962
-:100FA0002949F3ED380DFD2481FF8F76F13C5FDC9C
-:100FB0000AB4FFC3F4F11FA28F6619CF6F47FFDF9A
-:100FC0008D1B6527FB47D4FF6105CA379FA9AD3E3E
-:100FD000E707495FD0BE377F9F8DDAFFE7B1EF5754
-:100FE000207C003F544E79ED1CFC501F951F11C50D
-:100FF0003F82FE897F51CE037C7AC49033E9999C6D
-:101000003EBE14E7AA9B47723BB159DC9B1A9AC9B2
-:10101000ED424F2687636F51BF393E020E1178862D
-:10102000BF10FA2111EB2638DDE496EBCE2A1ED74D
-:101030001DDABB78F980CCF4070259E17C747F7922
-:101040009959C5185F0DF79FF936C2F52601B7A16A
-:10105000999DDF0E7079A8205F561081005D6C5558
-:10106000022AFA09481731D6CD32DBF15520AABD44
-:101070006E3E477B4BFBF67A547B66CEBB98F602FE
-:101080006FE3A2F05A1485D75151F912990F1AE45F
-:101090009F948B650DAB96A4B9312EA9D09DCF300E
-:1010A0003DFFAA18E9798E53D2EF2504D7303DF7DA
-:1010B0007D1BE5FFC47A290F2F7D4007BC4D407989
-:1010C000382C9CBF0EE505E5FB15EB4991FAE2B221
-:1010D00007507EDEB84CD6F752FD9B6B657FFDA9AD
-:1010E0005CE291050614135EF384BE080C7C1BCBF6
-:1010F0006737F2F673D6E4BD1DE87E0E7EA88B82BC
-:10110000CBDAA87C20AAFE43E7D12FB551ED1746D4
-:1011100095AF88CAAF8ECA2F33B62F9DA6101F96E3
-:10112000023D2022CEC797F764B6D9A96DFA54B113
-:1011300093DD66E0ABB1353CBF644D7EF1B2BE11CC
-:10114000F9CC82E248BE90F77BAD6E467C61EE4002
-:101150005EFE3AB30379D93B5ADFF2F2CFF09F1922
-:10116000B4BF63B00BB6ABC67C932AE73DE1ED3B61
-:10117000EC11FBA0CC578CFE41C7FB2DE38B474500
-:10118000DA2581E262A44BB94E59BFF0C7B32A8E6B
-:10119000F7A7CCE2E20DB89F3352EC43BA780A7A53
-:1011A0004D45BD5929E23185783E16EBC5877ACC8D
-:1011B0008FB443587D4F5C67D33DFCDE40A006F002
-:1011C00083F135E6B5603CA5292969C193507FFBC1
-:1011D0003DEA02D4A3FB16A4D0B9A43399DC5FD8AE
-:1011E0009ED4256D3AE49B126EB3E0FDE4A67B47E6
-:1011F00053FAAAAA2F6D055E7B694D49B1BD0F96C2
-:1012000027117C5EC89C5CBC08E8BC012FED407BCC
-:10121000BFCB9986F71AD87233E3EFE5789F20BAEF
-:1012200079C0DA1FFDE7D24597D0BE55D9C3130A5E
-:10123000E9DEC21233ED67C01F9D3FF12F1F4DE75E
-:101240009EA6D58A343086D2577EFA4B4D22EEDFE9
-:101250003FAED07D892BBEA97F13DFE5295FD6CDB8
-:101260008BA87919EC7A3C8F7460752FBA2771308E
-:10127000AE8ACE7D427D86F5CB7FF0BC333E0FEB50
-:10128000AB4E3C5A7118BEA33D7CF83E75BD82F34F
-:101290004A74C4E379E9C33F7ADE41BB16CA9D8B29
-:1012A000E1FBE125B3D2D0CE3AAC78121558FF0756
-:1012B0006B6617A767E0FD7AABC0E76C4729ACBF48
-:1012C000D4D4462FA43F6624F3FC0799B38B37C2CE
-:1012D000FC0F3FD68BCE7D8DEBAC7F980970CAC8D2
-:1012E000D23FC2F4A0B877FCCA4F7CBFF01F27CA18
-:1012F000D2305EB75FF0CFCB67CAD2CA22EC9D195D
-:101300005F6A84F7572C9E3B709EAFC4672B743E78
-:101310009BD5A760BC7B9AF03F807E173C1FC3EE35
-:1013200069CC54A9DFA6FB5347205EC3747C37C940
-:101330004FF21B207F6ACD9DA4D70E5917B083288A
-:10134000B7C4F94586AF0D21FF6D8E0BC6E562FC73
-:10135000532FD4C98FA9EF39D111C177A2FEA701AC
-:101360007E3EF753A88FFEDBA781FF7144EE43C892
-:10137000FAE5898E001A13471C0E0DF1B04FAB3EF3
-:101380008CE7FA663C6E26B93FE3F1D485AD286F51
-:10139000805E303E16BDAE2B3B9B793CA2233E0CBB
-:1013A0002C35F2215B7A4E3EB4FF69C939F9B05C45
-:1013B000F829858F9BE99C7AF9208786FB8F231F6C
-:1013C0007F6D23DD5BBD3D6E00DE4F287FDC4AF87C
-:1013D0006A7138024EDC1F4D7468C9906676E6F873
-:1013E0001DDE99F34D81CA34DB004AE95E82DCD709
-:1013F0003BB6E0C147F018E571169C3404E0770A6B
-:101400001106703925EF6545EDF355EC7EDE92CF80
-:10141000CEB1CF779EFD3DBCF18C7C78A1FB7CFDED
-:101420003B8B73AE6DFB7CE69EB88F582EF6F90AA7
-:10143000D6F2F35BE50BF83B1C05293CDE7BA83AB2
-:10144000808FDFE27A034EBC9FFB10D72FE54C095B
-:10145000DAE09F63D6DE4EEF933E2DE44A29BEA329
-:10146000D517F9C59B837EFA8CC7E308AEE54FCC50
-:10147000FAF03168D7B2A8D81DE9178FE96C9670D9
-:1014800065784F57F67364D1EF7290EE0BFE0CFE49
-:101490002DDEF74B66CFDE948B78CAC8C1FD485964
-:1014A000AF7CF13D3D793DF08FC10F2EBD4FE5F78B
-:1014B000A65FB092BE031E4F6711F799A7D5EEB68F
-:1014C00058FA86EF7F1D803C5EA98FB80766417889
-:1014D000C97B49F8973E58D8DB1E921FF4BE70892D
-:1014E00049A1FB4B20B9E8DECF9D9DF97EE1ECCE12
-:1014F000DC8E2DCDF1D2FD978A9556EFE25CDE4F62
-:10150000DBBD6A3CE7646A9E41FB8F7FB3525CA4FB
-:10151000B2364E8F4BE4E722B6F4A573D19A05F7A5
-:101520004D3C5C4EDC29E8AFD233610CD20B94EF1A
-:10153000D5F01C9683CBC38A64F1FE1BB437C13847
-:1015400027F15FDD78BF19FD22C657C477E8C7933E
-:1015500018EE7797892DC3B80BD6EFD30FE19832E9
-:101560006932CEEF1995F81816BF7228DA77CFA82E
-:1015700003D1AF2DBD6F7BE16ACC3FD71F6F2CB07D
-:10158000D267DF277D3147E0BF459C072B833CBEF8
-:10159000AFB6B233D7F77E95C77B560A38493A9033
-:1015A000E515F7F1F350154BAC64BF542CFA88FAEB
-:1015B000AD7034A7A1DCAD78C14CF7985789799705
-:1015C0002DCA1EB117E8AACC9C44EF48CF0D145B7E
-:1015D000303FB74EA17CB85D6A0ED2E917B52F2611
-:1015E00022FD1C8C0BF5403DD47A7B9C17CFE1C9C2
-:1015F00078DB17B53DD6635C669AB3D981F791A6BF
-:10160000DDD1CD85727B9F3364C1F27DF5B926CCE7
-:10161000EB4EE708CCEBDA6594FF429C3BA13FA47C
-:101620001785E379EEE6ED96AE30DEDF047D7CF9DA
-:10163000CCFB3D514F55E434F7447D0274D0B333B5
-:10164000C2F96985F4F0BCCDFC9CBAA48379480743
-:10165000C077B3051DCCDBFAE26F901FE621FE07D1
-:10166000B4A723A0D31DF47DCBBA42C6DBEF403A2A
-:1016700091FA0BF2B56617C6DF441EC6C1FC8B0893
-:10168000CF542A1FC5CB037DF939B7163AB757296E
-:10169000EE2BB6C9A70EF0BC47E0B16C9195E4ED16
-:1016A0001E81E796FB5E48443C7EF9CCF69DB84F20
-:1016B00052B105B4B427065F08B854221C12691D44
-:1016C000645754E2BA13C37068A37FC18F958CAF7F
-:1016D00053AEBB52137090E5A2FD07826EE6320155
-:1016E000B7ADBD38FF097E437EA67776C4FAFC2EDF
-:1016F000E37BE2DF89F51D147A612ED005DECF622F
-:10170000783D51CA0928FAF2B97514F791F892F3A5
-:10171000B66779A4BCD3935D613CB69862BFA77CE1
-:101720005AC06FFF924E390D00B72FC0BFA273038E
-:1017300040AF5AC478926EE478057F9D700DAE1765
-:10174000FA0F61FF72DC7D81040DFBD9C7387F2061
-:101750007DA2FC947C595033E59AFE78EE37F0A5D3
-:10176000A35B5F5C2F1FDF9EC5CF2DEB6827407BFF
-:10177000BD41A1B8F37EE1CFEF5FF2626259049CF4
-:10178000E2B338BD4B3AC33F8C47C9F9EE72F1382A
-:101790006EF4BCA51C92F32EB8F7C66BF0BB9CBFD1
-:1017A000A457499F128E924EE5FDB7687A255A9349
-:1017B000FA5335C87BD28F63B2BEB6F8EDEDBF47A2
-:1017C000E7A51D74509CDF6E4D653C5E5F9BBE239C
-:1017D000F2BE0FFCD923F54E843E59A145E813A96A
-:1017E000FF2BDD3ABDAF322F8B9F2B39CEEA2DF97F
-:1017F000D0EFDCA3CD85899EB0DD79C5372115DF1B
-:101800003599BB959F3F93F09E7B6207D17D85B84C
-:1018100097547ADFFBC54390BEFFCB4CFB31A54B01
-:1018200046D3FDE3591BA70E46FAC1FB0C28CF8F08
-:101830006D1834903FCBE54C9B84F71A363C38E961
-:1018400066F83EAD41F5925C877E905F4BEF1CC819
-:10185000905E0EC6B5140F437BFD6ED589F6FAF087
-:101860008D831662FDE18E2EC9B81E7D430AE57593
-:101870002D89F482B473E5B9BC1A33A787C9599C82
-:101880008FAE6D4B399D15D4D4F4C4FDF3D675716C
-:10189000F49E518945DCE3DCD689FC894A0B5E293C
-:1018A000A47BA16487CDB4305B063FEF6CCB80EFA7
-:1018B000BBCDCD77A2FED87DA7A33F9DAB577F18A8
-:1018C0005CC6ED67BE5F98627C3F48CEE346317EE2
-:1018D000747FB2FD2E71DEF8A098FFB1DAFF9A8412
-:1018E000FAEFD8A61E2E5CF7916D71740EFF48D4E6
-:1018F000BB8C177B4F0BE836EA1ED4627E6F20CB81
-:1019000068BF493A3FEF3DA54FDC51FB01E73E5F21
-:1019100074A29AD17DEA4BC1A7C0F6A3127E7C1EA9
-:10192000CFF5CDA8B33AF13ECB21A47B3ACFA3F2B9
-:101930007BB736CE07879EEB1F44BF71C627FC7E60
-:10194000D18E55F7D2B982E96057E251AA363BF9F8
-:10195000A15593900D4E79FD4B33A0DDA94DFC1C94
-:1019600044BB770B763FBF33F2DD828BB58F2FD42C
-:101970002E96718587B38CF7C0245CA57FF40AE0AE
-:101980007FE880309CBEAA9E4976F1896A3FA527F0
-:1019900095FD2B8723DD3A92E8BCFE3F1A1E54F1D9
-:1019A0009D958AADFD7F40FF76983DC989FCFA552B
-:1019B000F502DAEF3C515D4569F8FDDC20A5576C76
-:1019C0006DA2765F350C6CC47BAE2FDB9384BC8F2D
-:1019D000DED7E178ECE8FEAE5CD7F1BB393EE5BC82
-:1019E0008F6F9A9A88EB6AFA534AE3E588C7842492
-:1019F00027DA77E5E29CC7E1D5DC7E3E6A4B7A7256
-:101A00001C9E0F597B5D1ABE8333BDE9FA49F87DF0
-:101A1000C636C58976BF77DB8444F4433FD75A1274
-:101A2000F15ED3E7ABE57DA820BDD33AAC88D1BE4B
-:101A3000D3B090C63CB97C8B19E9E4F2131ADD3BB4
-:101A4000FD02F7A330EEF1433CC53D98D8679AFEFE
-:101A5000128F97B4F9B1C28F1B2ED6DD8ABFB39116
-:101A60001AFE5E30947F3FB2F6F9F1D8DFB10D6611
-:101A700027CEFBAB0DFC7D86D9E07FE1D594A39BFF
-:101A8000B87F33BB5E217FF8D826D0CFB0AE8ADBDB
-:101A9000CD3ABFAF69A4BF0228C7738D92FE66EB33
-:101AA00041A2EBE8F73392593DDDEBFAA5E8F1707E
-:101AB00096F13C661B1D76847F0127E45BA4438975
-:101AC000E7D9ABF9BEB9ABBE7F3ED293C47BF4BBC2
-:101AD00072351646F71202A6787AFF7782DD6356D2
-:101AE00060FDD7B95B46A1F89C98CDF5B85A60D295
-:101AF000F11E1AABE1F7F3DBC98F2C6E0FD56433FF
-:101B0000EABF73363F2F2CEF63C91416924DEFEFE7
-:101B100025B8FEED812AF6C76BC76B30FF09C35DA0
-:101B20007776F3028A1E5F3E5E03BA9D30D0F5429F
-:101B300057C8A765DFC7F397B9069921BF68D1FDDC
-:101B4000E347E1EFB264EBF1D911E3C87EE1BB23D7
-:101B50001BE6B133C5EFC4B4D2C2EF479D545AFB64
-:101B60002DC80DD77F4F61FBFEA184F32D6646EF94
-:101B7000C074C6F90FEA38BD255BCFE0E31ABF9702
-:101B800031B684CEC705F8FD16F8F3D9D2F0FE11B0
-:101B9000A7A73279DF6599F1BE0BF3F2FB57F21E6E
-:101BA00092BC67D4277C7F6AEDC5DC9F3A6986F5D5
-:101BB00026B5BFCFA634BE4EEF61D504584B1CE10D
-:101BC000C1787FA52281BFD337FF852F772059CDDC
-:101BD00092F60A2ADBC1E1FBFB2C9DEFFBDF29E833
-:101BE000F04835EBDE1D58F9DAE6E6440F4CF6C452
-:101BF000F8504FE46F8FD59F8FF03FB2B6266BBE83
-:101C00001BEF7D5ABDE3A0FED120BF573957D89BAB
-:101C10006C43AAE073357415D4DB95DB87DE6F184F
-:101C20009BCDF5F289DC500EBEA713C8E5FE0DD49E
-:101C3000A3F36B458BC7A462BD13CFDDDB7D3AE018
-:101C4000CD8AEFB7B9286578FFE96A3BBE854CEFCE
-:101C5000BA3195F66983FC9D31A897887ADD3335D2
-:101C60009DC7D1F9BD39892709FF76788129A03D23
-:101C70006AB23133CEBF0F5BEB447D21F123DF31FC
-:101C80009DFF028F9FCC575A6A5330FF8C42E7DF8B
-:101C90008ED8F8BD9EF67A6EA305413D73ED54C310
-:101CA000FB3CF2BDD05F3A0E343F5BC897FEAC7F81
-:101CB000E47BACE5A2ED68B5C483EF49CE4FB5D166
-:101CC000BB1DF31FEF46FA041C6116598FAD4D2161
-:101CD000FA589AAB129C6735307A77A7B82193CE21
-:101CE0002B8E6B70519A78269DBE1F7BF2CD3C2EB9
-:101CF0007F381E8A9FEA44EF47173FD56B24FFD1F8
-:101D00008176EFFFF07793ED36BA473B7F37D74BBD
-:101D1000F36F50293EC9C4FD709F988ECFBE8CE2F0
-:101D2000393E16FB1D589F7C0756379FF31D5809F7
-:101D30005FABC04FF4BBB037EC1E988E7EAA7C1709
-:101D400056BE63D72CEE6D45BF0F7B6F6221BD0F72
-:101D50003B59E77A24FA7D582D10E745FBD69C6560
-:101D6000E7EF35F8A3DF8B6DD170DD9346F0F762B6
-:101D70006F981CF12E02FCCF3CE26B92D3E611ED82
-:101D8000DE0732237D5B7DC6FA5B24FEFBB03EE7B7
-:101D90007C8F37CB42EFBC69F85E35E42789F77852
-:101DA000D18E43FBFC94CEDF95B3C6F37537B3BC3D
-:101DB00074E4FBFFDFDFA13EDFFBD3D1EF4D47BF74
-:101DC000333D70D71F0DF941CD6B0CF587EC5D6F7E
-:101DD00028BFBCE56943F9F0A35B0CF92B5AFF6EF1
-:101DE000A87FD599570DF97CF6A6A17E81ED7D439C
-:101DF0007EB4F37F0CF5C7A41F34945FEDF9C25095
-:101E00003EB6F769E37A34FF59D487C5DEEF0DEDAE
-:101E1000C633CF1FF01DE71BDD267AAF43C911F68D
-:101E2000B5A0BB1FB384DEEECE72507E8D564784C4
-:101E300088EE1A14E2F7683DA67DE1D3311EC75E35
-:101E4000E4F7BF92C0EED322C64BD66DE01086F306
-:101E500029454E433ED5976EA8DF69B2C7509EE133
-:101E6000EF6D28EF3CD36BC867570D35D4EFB24008
-:101E700037E473034586FADD96F90CF91E75930D68
-:101E8000F57BADF61BCAFB04671ACA2FD95465C887
-:101E90005F5ABFC050FFB28680A1BC7F6899A17C09
-:101EA000E0AE3A437E50F36A43FD217B8386F2CB5A
-:101EB0005B3619CA871FAD37E4AF686D30D4BFEA0F
-:101EC0004CC890CF67BB0DF50B6CEF19F2A39D1FAB
-:101ED0001BEA8F49DF6F28BFDA73CC502EED96B125
-:101EE000BDBF367E17764CB1F73F86F68191E27D15
-:101EF000E82D0ABD0F7D5B4E57F9AE684B1CBE8BBB
-:101F000018F051DCC78507FB504EE1BD6B173F173A
-:101F10005342F12337D939A48A3C784E07EC8044E8
-:101F2000F4AE7273D14E4E08DB63596723CEC99D60
-:101F3000CF1EABC86144E76B73FC6539A9E87F3CF1
-:101F40005748EF7BB3C0529C877CE7EE9DA8778D06
-:101F5000657AB5ED288B7CFF78775C5DD68073F869
-:101F6000EF57DB4E307C57B9AD5F11AF50607DF35A
-:101F700023FA5F09FE82D69DB1BA6AE01BB091FEDA
-:101F800058EDA4FC43D5E9947FA4DA43E9EAEADEFC
-:101F900094AEA9F652F9DAEAA1947FA25AA77CB0CE
-:101FA000BA88D2F5D53EFABEA17A32E59F04BF18B1
-:101FB000D34DE02763FA34F8BB58BE19FC5FCC3F21
-:101FC0005B1DA0B4BE7A197DDF525D47F9ADD5AB7C
-:101FD00029FFB7EA20A50DD59B28FD7B753D9537D8
-:101FE000563750FEE5EA10E543D5BB28FF6A753346
-:101FF000E57754EFA5FCCEEA164A77551FA5F48D78
-:10200000EA562A7FABFA0CE56B4DFCF740D6E41894
-:10201000F721645EBEC720EDBFF168BF23710C35A8
-:102020007F65B0DFA3ECE8687C1C1771DDF0FB096D
-:102030003DD7D744F84F4F8AF1E47B0CD1EF2830DD
-:10204000619FCA774FE57B0D33C4BCCA053F0C4284
-:10205000FAEC4DF4F9D6C5F80BD21F1C90EAFF1B21
-:10206000D167B62940FEB09DDF27BE21D5FF52CEF5
-:1020700020DC2F9CBE93C6737A69DFB0D81A4ABDA4
-:10208000318FDEFBA6B85C47E3558A73DF1D96BF30
-:102090007C2C0BEDE9A29F547A67EB1DB3837EDFA6
-:1020A000F02D0197B7724C86F4E354FF9B38CF6F45
-:1020B0001D55B79A60FEDF5E79FB93BFCE0DFBC95D
-:1020C000D7A2AB09FECD04E631D3B942A6BF968BA9
-:1020D0007613185698BF910528BDD5EDDF83FDDC3A
-:1020E000040637E6FDC3AC39B1D6153DAFCF72B8A3
-:1020F0003FFC598EC9905AD3FCFB104EDF3A749ABC
-:10210000D73B978FE989EB92F32A12EF8E8C67AD5C
-:102110004FE0FCBEDDF6F561A55B18FED21FA77B84
-:10212000FD28C76E57C4BB76EDDE11A0F2923B15B9
-:10213000B2CFA6803F83FB43F2DD805355667A0F12
-:102140001EDF19C0FDB353559FDB919CA11EC3FD3B
-:102150008D1A3CA003E53577F3FBF425F82EC60075
-:102160007CB7C0C6FB5DA810DD0D4FCBE5F79FC166
-:10217000DE23FFC9DD4AF7F4804EBE273AB95CA5DD
-:102180007BE7EF98823D15DA4F9E6E51607EE56EDB
-:10219000AFE17703A2E9609EB82F20BF037D99BB12
-:1021A000C0385FBD34A437C5DF5FBEDC83F0AA3121
-:1021B000F1FB43813754F17B4E5C44ABC32FA53810
-:1021C00023D3BC5E8C17158BFB264D2A5B10EBBD11
-:1021D000F05E5D38BEDE49E7EFE7D544EDB374E964
-:1021E000C2E9AA4B174E6FC5AFEEA67784E6EDE2C3
-:1021F000EF1DB2BC96BEB1DEE7AF5CF0469FEE11BC
-:10220000EBA86CD8CFCF57B096BE91E7C975D1AFC8
-:10221000A423D5E2F0AFB347CE8FD30FD0754F8450
-:10222000C3B7C940D7DD88AE0FE3BEE278AB27E97C
-:1022300046057F25807D85EFFBF8FFECA4F341F296
-:102240009CD034E6A3B41CC800E9D8175845EFB9B0
-:10225000CE66F5F47DDED0A9F47BA495AC75543A36
-:10226000C0ED86658B5EC3E7F0AEAB5B351AE3ABC2
-:102270001383A5AF613A61837218FD54E08B215D31
-:10228000301EA2542DC12399376FCE5F825B66E367
-:10229000558E0FF626C707D08DAEBADAAF13F8E029
-:1022A0002A6CFF6DB24EEB50138B0C7C50B298E948
-:1022B0008A3B7CDEBD8D2F86CEF90CB7D498D64AEA
-:1022C000FBE6952F5B5D88E7D98CEBED703C43EA2C
-:1022D0006B46743E87C57BB1DE7141D7C7B319D158
-:1022E000F57185D13D756947B21C7FFA806E61BD7D
-:1022F0007BDC141C9CD88DF4F2249CEFCEF4EB3CD8
-:1023000018079BE3B6D1FBA7C793833951EF7CD065
-:102310007B44328EB5D2CCE34AD1F35286EEE4BF91
-:102320006B616101DC9FC0DF751E8CFC8CEFE628C1
-:10233000F40E740BF2BD79A4CF13ABFF5AD1EFAEFC
-:102340001FB9BF1B80F5E0FDC676E338C538F17CC8
-:102350001CA93FDA7E473A8D19C6FB4D975CC2CF68
-:102360003B0E9DE6BFC8944CF226C3E6BF0BE94E78
-:10237000C675A41FB82BF74877F2D77FA8C942FBD0
-:102380009CDE2140FBFB4A2E97DE317BE8DDDD77CA
-:10239000F273297E2FE5EDB54379FCEB5A19EF1A5C
-:1023A0001115EF8A8AB7B011B1E35F8C79CD386E21
-:1023B0001FF689840FC5595E1DA1197E3FEA55E1BC
-:1023C0007F9E2A72E7219DEFEFA2D23A1353F8BB0A
-:1023D00021AD0E95E86C7BC06BC7DFA3582EE2A43D
-:1023E0002BA2DEBD5E9E37DF89E702AC0EFE9EE5C6
-:1023F0000323E367469E477FAD073FB77463CFFC77
-:1024000077915EFADA8323493DEB9A07E7AF88F5C7
-:102410005CE204789BD0EEF48978A7FC5D9351A42C
-:102420009F259E2F543F3FAD0517C7E37ADD8CF8FB
-:10243000CEB1DA46F253ADD74378343AB5E7C4CDDE
-:10244000843FCDD71BC7691A1CCFEC50FFDB260B8E
-:10245000C5A15E3695FD19CFADB77E6C6578CEA16E
-:10246000DED1594323B7FEC75F8DA2D431BC90BFE4
-:102470003FC912F09DCCFE4EF697FF462489FB61C2
-:10248000F50ADBC51F6BD513F09DB77A133B7D159D
-:10249000CC6B8B7DC0839711A9F9545CE77BDDFD84
-:1024A000AFE03C06B32ACA3F60F1CD5C07E33EE0F3
-:1024B000B2117DCCEAEE7B95CF932D1907F3BBB219
-:1024C00040A1DFAD5B227E97CDE18D37BCB7EB3B02
-:1024D000D393F4C5DB423ED7A6EBCD78B1A343B886
-:1024E00039B556C33B592C8BE273128E91F8720E9C
-:1024F00036E0CB6F8EC4D750C0D7A591F8D2958B5C
-:10250000C1D7935D18CD57D26560A467D5A83CAEFE
-:10251000C76AA896338FCEB7B6A34FCFE67AC86FF7
-:10252000D72E217849FA94F41A834E6FDF8EF23851
-:10253000DBE4C4FDDD7BC7C5937E93742BE9D5D264
-:10254000959FAF02BAF57585748ADD371A654834F0
-:10255000DD62DC2B923E4B3AA463E68CE4D7F1605B
-:102560003F24B9D0DE39BAA13E823E4BAABED6B8CE
-:10257000FC387B55FCE0709CEE7F012DB720EB0012
-:10258000800000001F8B080000000000000BED7DA4
-:102590000D7854D5B5E83E33672633934972924C93
-:1025A00092811038934C424826302480FC552721D4
-:1025B000D0F0EBF05783243A58B4412193026DA335
-:1025C000D77B33908001EC2DA2F5A1F2EC808A68D4
-:1025D000B506A51ADB889320DC685107B52DB6DA5D
-:1025E00006DBCF9FB64A10AF175B5AEE5A6BEF93DC
-:1025F000CC994C10ED7D7DDFD7F7A27C3BFBEC7DC9
-:10260000F6CFDAEB7FAD7DB268A6C4DEB130FAB9A1
-:1026100000FFFCF0EF9D62F81D7F5CF85456DED59C
-:10262000DA8DE2F915434BE8C7DE2D1EEC675AB68A
-:10263000A9981918DBDAE264CCCC58BBE4F5E5C004
-:102640007872D3A90DF87C8B0C1D1D8C853CE6F0AF
-:1026500043388FEC2FF6A70C8E975554E550B318DE
-:102660004BB9EC4FC93740BF4FB30D2A93E03DF54E
-:10267000BA276C93E0BD93C90CDF4BCD8C363C0080
-:10268000EDFD6F8E65FB60984FD704C62876C6B601
-:10269000B5C03EDCB89A708E612A967D39062796C1
-:1026A000AA939701277FCE447B98EA7B5CF98C4DF7
-:1026B000C6BA4FF4EFA3FEDBCC3B2D369CC7655169
-:1026C000F64983EBBCC2C89A3A60BED92A6C0AD6D6
-:1026D000CBCEB7AA8B53B02E51FDCE96DDFEDFBB1D
-:1026E000713D612A33178459A08C315B71480D41CB
-:1026F0003FCB6616C0F7E3E179BF4BA675587AEE7B
-:10270000612AF4CB747BA500F4732C80F13438C3B8
-:10271000BF45008AB472E8B78FF9D824848F2D1C86
-:1027200092868EB728ABAA574E1DFEFC16C5E10156
-:102730001378A09DA7E56FC64087076B4E03CB6655
-:102740006C23F65519ABCE875F70DE66F3DE2498F6
-:10275000F75A359DF6FD89A32A8D79869FEF7E383D
-:102760009F501140BDC542E5BE168585004F1E0431
-:102770007CC1FAFE1695CA032DC5543EDAE2A5F6D1
-:10278000C75AA652FD472D3EAA77B4D450FDC916AC
-:102790003FD50FB5D452FDE99600959D2D0D54FE01
-:1027A000A4A589DABB5A9AA97E45129C1BEEA738CC
-:1027B000E45C02E7D17EB3D9A7027CEEC67304B80D
-:1027C0001FF1E5677AE1BCADC5069604DDACC777BD
-:1027D00031DC8FD569F085E11CB63A77B1AF43693A
-:1027E0009A92D22EA5C1FE1FB7B74B13A05DBE9320
-:1027F000A9F0FC7E29D4C0BC8CFD6B78865F9EC698
-:1028000098DBF9CDAA0CA8B7862B775A006F8BD42A
-:10281000C5B59B62EA6A4AF98D0795C1FA18CF5E81
-:10282000D906EDED6AF54E87C4D7C14632B62B3CCA
-:10283000C7BF09F02892CF4208F77E97398CF8B8C5
-:102840001ACF4BC6F52BB4FEF9ACD56980F58F5184
-:10285000CDE54837D03FC21C97DEFF6E55A5E7F1A6
-:10286000EF5DAC9F61D225F563C68B8C87EDD245B9
-:10287000C6B1484B2D5158FB0E93E01F5976E21F0D
-:10288000ED2676AD1FE0DE6EE5E5699744F3F5BA17
-:10289000AAAE724179958B9F6BBB35A454E1FC6560
-:1028A000062FF20BD6EC7A3D1FE6FBF64B32DBAE81
-:1028B0000EE2E7E3829E0BC7A4F8701EF62F967017
-:1028C00021CCF3D5318FB76540BDF001AFD708FDFE
-:1028D0007730AF0DF12474BB813D04F51F4E2AC83B
-:1028E000580CDD4B27FF382300F8922CD61166AC2C
-:1028F00006F16DD3961BC6F441F9E909CEA7BAC417
-:102900003C7B4DD1263ACFC97686FB666C6732F2A6
-:102910009D4D4E38A4CB18338CE0A5D9A45C8DFD19
-:10292000CC5BCC2C04EB31FFF5328B1FC66B3D9793
-:1029300054837C84B16832F231B335A0A4C3F39DD3
-:102940002103F18556D51E9660DC1DF6F25E15F961
-:10295000A762F016221C3D0682639BFD6B6123F289
-:10296000676953032B80F52A4F5A5CF03CEC312801
-:1029700048E761DF921AAC8702B2B750150C02DB50
-:102980000319E1ED382EEBFFD9046CAF635E84C30D
-:1029900096EC3FF72443BD75B9E235F2DEAA3C85DB
-:1029A000B111F81B4CD96AEADB9C8CEB58C1FBC314
-:1029B0006FDEC54087A949FCFCBED73D57C92F2310
-:1029C000B912EAE37C49BA0084289BBC162FB48F65
-:1029D000B797D7F8A09453CA2D2AECB34D29B7ACBA
-:1029E000A2FD333B83793219E74FAD8AA1262CDA59
-:1029F000BFEE2131F5827B0A9112B5B7D9777523E5
-:102A00003CE4EB1973A9B83E984FE37B000F4BC130
-:102A1000CC5E15F6D17E4306ED4396BC5467D7CB0A
-:102A2000B4EE91AA2DC2C6039F372FEC65C03F4676
-:102A30005A6E5A80F5110DF2EFFB62F8744E405F4A
-:102A4000CFAAD5D73319D42D31F30ABC89875B3C83
-:102A50003C46286D2770FD2302323D8C5FFF3DCA46
-:102A60005DE9950CD769A77566DBAFAB040801CAB1
-:102A7000F93721FEFDBDEB1CAF2CB1B860FEF10EA5
-:102A80000382934D60FD9B71DC1D02DFDB5DFC3C2E
-:102A900007E9CAA8D1A50FE9724CB3818562E48E1B
-:102AA0002B6463A198F90ADA3374F5C29D2375FD8E
-:102AB000C7EECED7B58F0B97E8DA4B0F94EBEA65EC
-:102AC0001DD375FD277456E9EA1323F374FD2B7AA1
-:102AD00097E8EA93A357EBFA5F76F23A5DFBB4BE50
-:102AE0001B75ED33DE5FAFAB7FA5FF165D7F20E387
-:102AF000868E047272BA8BF38536A72FEA4B20CFED
-:102B000007F42E45EE1F380FE09D494EC0EC98F9B2
-:102B100052BC3640A6C13A63A3947793459DE47AAC
-:102B2000ABBA19F139D54CF82CA33C87FAFA9BCDF6
-:102B3000E124C4C3CBBD2AF217AF8BEB336F17F977
-:102B4000BE8AE756996A21B920DB793FD93E87F4DE
-:102B500094D1BB812F55A0D6C806DA93913FB78494
-:102B6000FC6EF7E0BAADCA4E86F45B995AC3FAEC34
-:102B700083EFCB8A8F0552703E95E6B32821EA6732
-:102B800055E1FD987D1D3618981DF97837C809184C
-:102B9000BF23255746FAEBF86B4935952933E620D4
-:102BA000BE4F54D8034F40FF0E89F532D0933A0CF4
-:102BB000EC2CE86CEC497BF99D20AE8135FA8DC890
-:102BC000EFA6B0262A471B980DCBBD52DF0606FDA7
-:102BD0003C4D27AA72A0DF0977600DEEFBBBA04336
-:102BE000E0BEBE3B9EEB595BB2E7A9A897B5BB3AE6
-:102BF0007AF3713D592057901064BF17F50A6DBFE5
-:102C0000778AF394F3DBFB50FEAD4FB7A8A82FC92A
-:102C1000969DFEDF03BCEE37F53DD20AF5364959E5
-:102C2000DB817CF166BBF72186FA23879B9A62A839
-:102C3000D80CE3766CF2C9E9D0DEB18D79DB903E39
-:102C40001C959BD3E179E1A855860CA407F7A6CD86
-:102C5000586E413D16E61BE7D96BC884F6D24995FC
-:102C6000B50C65AF02F3650E8F4FC6D4DD0CF7C30C
-:102C7000DCF2BB8857A8755F80A55766C079C3BCD6
-:102C8000563C6F894A8283F59C3D6CC5BA9BC3C58F
-:102C9000EA93C2C95077B87D92CF83EFEDA6F3B522
-:102CA00046F47AEC1A77E04E84A76381FE5C65CB2C
-:102CB0005DB4BE1D064E17EDE9EA7194CFED2E7797
-:102CC00046AB3AB84E8DAFDC2FE4A7F65CE32B0A97
-:102CD000DA145983FA0DE0F96E4301EA673B19F201
-:102CE00027EBAD3B19E2B55509A90CF5F07F0B11A7
-:102CF0009E6BFAED064133D5F9B51694D7671DE5FD
-:102D0000A4CF5A9BF7D379C5C3CDDA6760BE8BC019
-:102D100035B5E85E92EFC080D542804F4FB6BD61B9
-:102D20006F02BD7FAAB01BB6011947495EF92DC8D5
-:102D3000AF4DC2CE004C30A07C3BAB30925FACC3F9
-:102D400045F50DE9BCAE8DB321AB3CE762FAB77532
-:102D5000B7850562F6B10DE641B86C39BFB806E13A
-:102D6000CA64220EB6E3AF9EBDDB1196C2AE992AAD
-:102D7000E03D1BE706B88E3633B20BBC8E053548F6
-:102D800077FE73F9247CFFE4CAA07EDE103336D1CF
-:102D9000BA4D9A5C325C98406B55CD9A1C26D596FC
-:102DA000CB2DF8BFFB82847C3F468EF182E4BA26AD
-:102DB000B70B77EADBC7EED6D7C78587BCFF06CA55
-:102DC000FDE5FC77900BFAF67B85FC5E8EF21B4AE4
-:102DD000B6CC4472CF022BBAC0E5EEA01C04BE9064
-:102DE000D711A944363A6A638C3C64B40F9D7C5C6D
-:102DF000E3E67CCCDF2B9BF01CFDE7C0F8A818CAEB
-:102E00009747277178F79853C29BE1BDDBC12E0A23
-:102E10001471FB3900A4F65DD9FBCB3AB4B37A8DBB
-:102E20005EC0D881738A3FD715F91C7F7A5DFEBFDB
-:102E3000BA487FE8AB40BB1AE70BC4CCD7634B1D45
-:102E4000CFC06E79B92860CC877E1FD73826217F06
-:102E5000481AC54C489F383F2B1AB4DFAF12F4B460
-:102E6000C3FB5AD31158C76D2793501D67B38DC745
-:102E70007B5BA0BE3E4F267EA65CB6F60768275752
-:102E8000FD1ADAE19DDB543587F4F45E13D9EB5576
-:102E9000028FAB84FD75B4D044E3E68A75E78812EF
-:102EA000DEB071FB3B62437DB6F400F062FD792633
-:102EB000F3761FE9BB651DF1ED3E86745C22F005DB
-:102EC000EAF64AA84F14F50E26652A708E136AFB9F
-:102ED0007AD094F0BC78D4867878D0CAF5B7470514
-:102EE0003E6433C91B81F5671FB07BC3D02FC5C8B3
-:102EF0000E46611FDE17E47762CF7D7C97BEEE61E0
-:102F0000317517AE435FBF5D6D92102EB7D7818EBE
-:102F10000E5BAEC84F71BC5BCA10E645885FB38DCF
-:102F2000F689684FADAFB433846BD2A9B1FF2B8A59
-:102F3000FCE38491A15C5092D53BAAE17DE56799C1
-:102F4000DE4DEAE0F93FDA82AC1BF8DE052F6B03B9
-:102F50009EFCDD2A5B03EABF8FC179A21CF911D860
-:102F6000D9D8DE01E78AF527C1CEC6F210D8D9F844
-:102F7000FC69B0B3B1DE097636963F013B1B9F7703
-:102F8000819D8DF5AB8A2ABF8AF8526FF7CF9610D4
-:102F9000AE3E595580AEA44138931F48627DD2059C
-:102FA00020903A85F525015CCF8DE17490841E2632
-:102FB000E0C32CE0B5205E7EFE383E6D9C8029D1BA
-:102FC0003853611CB2132C0AFA45F2E18D3478FEB5
-:102FD000E1CDBFDA8FF262A11458910FFDD74D7E7B
-:102FE000C7CCF5E77E33F6DF6305FC073E344AD0F5
-:102FF00041A80AE08972F725A3B7157A5D3EEBD4A4
-:10300000862CB0BF6FDA377931DAEF97DF74AA62B6
-:1030100034D40FEE0B2F964119BFFCE1534FE5025C
-:103020000FCE796015AFDF79EAEC28684F0BED58C9
-:103030005C3D0DFD525C3EED91586DAC7ED72CF0A1
-:103040003BD8BC8BE41CF077867068CDF6937C3C53
-:10305000EDE84F5D05FD8359FDD9D75D847F079B62
-:10306000EF2639D49AFA07D23F5A07E48597E485C8
-:1030700036AF262F3E16B8A7C98BF5565E1DE8174A
-:1030800028A0E7770ABF0E0B17523DD3CAEBFF5EAD
-:10309000A5BE8A760FC087ECDC23A925DF9B897645
-:1030A000658DEC4D82FA9DF6722BCA9B07F3B9DD54
-:1030B00002E386D08E0FCDB6841FC24375A8448F1D
-:1030C00019DAF80E372A5D2C43ACE385E9B608DA45
-:1030D000F9ADD5967DA84FEEB2E7D378AD53CD21AB
-:1030E000F4AF68F5CDD3A75B509F484FCD70615DBD
-:1030F000E34FDB01EFB1841F238E5B25B65B65B127
-:10310000478CC8CF2DA63FC5EAC9761625FCF11A13
-:10311000C020413E50C0F1AA82796BF1B9596A0AC8
-:103120002132EEC1B5E33E52849F92E5F2756BFB0E
-:10313000F0E5F27D69FB483187C43E484FDA6537D8
-:103140004450DFDB05FBC2F176E7AB049FF87D312D
-:1031500074BDC2B8B3A68A752B330FE13A661B7CE7
-:103160006DF8DED1CFEA1C805E6C0E6B92F17901B6
-:1031700058B4E89705946EBB7011BD23DE2F7BF920
-:10318000EF24DA0FBBC94CE7F24C215FCFBDE6B0AC
-:103190008B91811B1EB1246578FC7D6308FEFA18B3
-:1031A000D2536B868FE3AFD29FBA09F137BD3F7B15
-:1031B00033ED2B92F03CE2F138FE7C7E0BFF841C59
-:1031C00030227C3FEF3CB573D4F0205E7E4D28501A
-:1031D000B4F375D23E7DC59C0E343D8A819D9332F9
-:1031E000147E5B613CB568B06E76FA493F3639BCF7
-:1031F000C5E8BF6DFD9BB12191FF36AD80D3C1A65F
-:10320000541BE9CDADA95C6FEE4E9DA7B377AAC163
-:10321000FE91003F8C99AC03E9C8987635F9BF8CD4
-:1032200039A821E1BAE2F4D1B4055C1F55401F4D25
-:1032300030AF56CAA88F26D05307F4D18C795C1FC3
-:103240004D35933EBA27C55CBB3701BF792F9FEB45
-:103250007BDDB88F04F61ED879E487D4EC3CB3123A
-:10326000207B4DDBE77BF99CAEB4FE494A1343BF9C
-:1032700098D1EC5551DF34DAB8FE9804DB2C8E91EE
-:10328000DFDAFCEFE49B088E3D45FCFC0C16AE9F9C
-:103290005CFEAAD49408EE6A81A63F24C6BBBF0395
-:1032A0006F882F94DBCD3ED40FCAEDCE2AD40F8683
-:1032B0007B0F4CCDD0FB19837CC5FBB72946923FD1
-:1032C000B2D78978D661EA7BEA55B4E38EDA49DE73
-:1032D00074A48CAA8AD59FC15E0D15C32007FF0276
-:1032E0009468186AA782FD34BD00C6ED599F3D89D8
-:1032F0008F0B7A5ED950BD32DE1F3040EFA9FB5DE7
-:10330000FCBDF0087C4F5A3F3507F12A9EDEB532EE
-:10331000CFF952DE6A5857DE885E2AB5E7FF9B195F
-:10332000C9BF16DF7FF1C03970B93C0E264B33920E
-:103330003C5E8CEBFE70E36BD95E584AA37C86E45E
-:10334000F2C74D53D36E5339BF3D8072E69B32F1C5
-:10335000DB516BBAD33362CEF9DE96CE3CD98D7198
-:1033600083685EB59BEC015FA2F5FEABA03F16192A
-:1033700043FCD924F0407544E78E05B8AB7683173B
-:103380005DD2207C757CA0524EAF5660FEBC16E626
-:10339000B543DDC514F267E55D3012BEE51D594148
-:1033A000783CC6D12F853C31F3202B8E898B7CD283
-:1033B000544DF499973360C751FCE013476431D200
-:1033C000F72777F115E53DA06F07194BFEE61B3691
-:1033D000DAC2680A8EB95531603DEF07121BE5C2AB
-:1033E000751C71DD86FE9A6792C95F63DCED267FEE
-:1033F000CB0FA4C0F505B08E0FC3EAB7D1CEA51F81
-:10340000E8B7EE3BB67DDB498E45E7921CFB968123
-:103410003D94C09FD456C0FDE35B04BEE7395FC94D
-:103420005B5D81E5713AEF4BA5A783C8B7619CDB73
-:10343000D27652BC2B54C58AD1FE6B37015E25A0D3
-:10344000D73305226EA6F163013F2B5A2BB00FA391
-:1034500024F4BC038F3EFA6836CA6D864ADE00DD6E
-:1034600069E32417775063B2D7C7D0EF20293ECE47
-:103470006795903384F19DBF1A13E27544E3D3AE90
-:10348000AD4EEC5FEDF63A910EBA5D539CD701FC60
-:10349000EC76334B8AE1C31A9EBC903285F4106DF2
-:1034A0009CF529F917B5B7CDC08FD58BC86933FA0C
-:1034B000BD519FE999665161BD5BEDE551D4B7B649
-:1034C000DA1DE5E43FB703DF88F127D9EDC7080F20
-:1034D000ED5EEE67B323FF457F92D87FB7EB18ED23
-:1034E0005FEBB7A780D3BDDD1BE1F147B066B09FAE
-:1034F00055F687D0CEB03A18D995560BA7A76438A1
-:103500000E4B0C1FD1E6FD7E01B7D7B68E2A8F5623
-:10351000D2FA64F408B0ADCE7227C9438433EAA36B
-:103520002306F451F29BBC2EF881364E6B37DFA791
-:10353000BFD9E9ABCE443BD4FF22F285ADF6EB2CEC
-:1035400021940B29932E3ADEDBE2DC868ED73C4BAE
-:103550008CF73AD28331A55CC1F14CC82712E0DF69
-:103560001FC4BABEAC5F0C20AA90DDC6B87E051899
-:10357000EF4CA44768A545F8B786BEC7F9A44BD859
-:103580002FC0273FC5F5AF1BF5CEB14AEAC5ED9672
-:103590008CB972B10CE7F5319CA0511AB4E3E3F594
-:1035A000994A633FC9354D1E69F2E95ED467CC8301
-:1035B000F4A4F95F721BFC24B725879FF006F41B67
-:1035C00015E9C68871DF04709BEEE6709352A7AAD6
-:1035D000482FD5E7FB72F1BDC329EFE7B2183F9A38
-:1035E000C60F5FF86CBF15DB3F69A8BAA8DEA2C59D
-:1035F00085878B07A7DEF2876FC6EA2DC3C5873F95
-:103600002F2EDC936A26FFDBFD929E2F4D72733EB8
-:1036100038C1ADC50F0363DD59D8CFEF25BD51F8D3
-:1036200053DE2E0A94B8D1FFD56E662138CFC39FE2
-:103630004D71227E5C2A7C35FFF948A14F8DB4EF95
-:1036400097904E47368425F47FE7367448BE8BF456
-:10365000330ABF92D6DF24C6BF42EE37A2BCBA42BD
-:10366000D071EE399915C7E8817F2BE0FA9449E8CB
-:10367000EFA93D8F5871BC1E83BFBD08E543AA4129
-:103680007D2886DE4D6BCA2D5531F069C5B84E8256
-:10369000F3AB730FE85D641F69F2D6A4C90987AC68
-:1036A0009313C1648EB79ABE139CCEED21490A2CA8
-:1036B00047B89E9EFE8745C8B24E4B1D668C7F7FE5
-:1036C0005E5C6340AF31845769760CD28B57567E6F
-:1036D000DA07EF4F7CB892E861320B507919E37A40
-:1036E0001FE8515FC7F92A70C931E7CBD0F590FDCB
-:1036F000F9FBB812FDDE59E89F8B92FFF4BBE7257A
-:10370000E2E3F1F0D93F009F81F89DCE0F9A2BE4C0
-:103710005AAE6857D10FEAC27894DE4F59D1ABAF99
-:103720004F8EEAEB979D8CF37B867C3F7767F3782F
-:103730003F0EBA07E80AF9C16A11A71C150A572AF1
-:10374000B0DE3CD641F1C0DC860C1D5C2F378A3CD4
-:1037500009E69398B64EF8C995177E80EFDFE7D655
-:10376000F49F10E9593788F66F54AFFE761BDACE16
-:103770003B4DE40FB5C0E408AF6FCC5D321BCF7595
-:10378000883FB549EF47CD8D6D0738DCB0C7A46BD6
-:10379000F7FB26921DB054F86907F68BEBC8E2FBE5
-:1037A000CD2D1F3AFFE7CF0BFF3286CEAF8D7B2F9B
-:1037B000F01BE4A3EC3C9CEB14841B438F03CB93E2
-:1037C0002312C6A54736311FEAC3B91B992F917F33
-:1037D000FF6501AF7838B3D01504BF59E2D948BBB3
-:1037E00091ECF4911B0DA4078E047E807C60D15A6D
-:1037F0002017A8E7AE55498FBCB2C1C0500EB0F338
-:103800002DBAF761B9E4EFD4CEFD5E1C0FF5C87593
-:103810002C6CC0FD3495103DD1BAF207F101E0F5F2
-:103820000E879785E3F75493CEAF99877ECC18B86F
-:103830006878901BF7BCD1CDE32E1A5D803C7BD914
-:103840004D78C2E55C21CA3958D287D34EEEEF805D
-:10385000F55DBE99D17EFBD36D619EFF30102F3098
-:103860005E180BFCC932AB18FD2A3B149B01F31404
-:103870000EA7F7DDC7D219FB2DA8BFD533197BDE04
-:10388000D65F2A41FD8F0FFECBAE763894C3D6FEAD
-:103890001FA2B3D77EFBE6253531F5D47FBF9BEA67
-:1038A0006C2A5365808F0D67807DDA9479078C30A0
-:1038B000BFCD632727A48D0DD029EDA76DBA7A3B24
-:1038C000E679B4151A484F62B1EDB08FDA4245D0AF
-:1038D000B78FF2D8580D8FDBC78E2F3B2E32FE3CB0
-:1038E000187FD21718DFC2D79F8D8F40BE64E3FACE
-:1038F000D14F8DE3E3F9A2B328767E319ECC427B93
-:1039000031BE02F3D9253E9F827924D94C9F3730AE
-:10391000309F02F395FD03F6533BF43C4C173B8F6D
-:10392000ABBFD879B4197CB4DED0783BD93F0C9AC0
-:103930000D53D0CEE0F35965F6825CCEE1DA366500
-:1039400010AEA0EFD1B8D07DD305016713C25931B5
-:10395000139C87835B8FC2F398B629B6F026D7FFF6
-:1039600085F372F2F38A9D0FF5C64B9EEF6A98CFEE
-:1039700071E9F3217C917E06E00B67B239FBD2E15D
-:103980000BAB0A5D0A7C7B605C430C5C07F385EE45
-:103990005150FFB79AFC162FF0DFEB0B791EA2C730
-:1039A000B1C442F903594B2C9897B7C563AFC1FC1A
-:1039B000BD2DEE6516538C9CDEE2A9A376E84F7907
-:1039C0004E9E880DDD13AC8C45C9FEDF36B3DAB9E7
-:1039D0000AF1A789E74D6979449A3C64223E49FB84
-:1039E0008217D3BE72A8BF07FA6F6B9A44796269D7
-:1039F000E97FA6FCA81D0D5E2FB6DF67E571C6BB8B
-:103A0000459C091195FC68E3A73F80F1D6F2C2F509
-:103A100012C517D75E3CBE587E265A8579566C155E
-:103A2000CFA372D6C971F2504FB73B10AE3CDF291D
-:103A30002C71F8EAC6BBAF308BC79FDDFB18DA7775
-:103A40004FC158463D7D1930EF289E1E65B34FA9E2
-:103A500044BD7CBD81D6918BA17C1071E5650B9C2A
-:103A6000ABE0F9A8EB65AF04CF733CB752FE116829
-:103A7000F5A46F783CC7ABB03E649FABF5FB88DF25
-:103A800057FCBA417091BCD1CEABFC8C3719EDA874
-:103A9000F2C225941F463F1ABD1BE3F69389F6AF89
-:103AA000C16705396673C7EC8BE9FA093BED7FB650
-:103AB000BE0D9109E5627CFCEBDFFCB4CE24E6B5DB
-:103AC00098E9BD3AB217B5B8DA48A41D3CF7D18CD5
-:103AD000C725E2DF9FC2DF674E1E674BB281E9094F
-:103AE000F427DD6823FF655212D4E17C2433B38CC4
-:103AF00080E7F70ABFDF2689C9581F9C2FC270BE16
-:103B000056C9BFD3EBC292DB4BA6743FE517629850
-:103B100036D6EEECC1BC0D685FBFC695837EBB3464
-:103B2000208828DACD222EA5F949520BFA56A2FC9C
-:103B30007EFDA1BF2CB1A07C46C7D274D0BE0B3F86
-:103B4000DD159A39489749E7463235C67E49929B3A
-:103B5000287F23E9DC689D3F2522EC2EADEE73C85B
-:103B6000D538DF7FA15D00F85CC994367CAF128048
-:103B7000A2C6FA47CF3975E30C8E3F4A376F04EC83
-:103B8000E7D838C0F0E32733B53876FCFC61C62FA0
-:103B90008A1B5F4938FEE0B899BA71B7C89C5F8448
-:103BA0001CB670227F5E5651D57924E5E1F2CB1C1C
-:103BB00045DCCE057E2C53DC49E0CD6DCE26CA37E0
-:103BC00033DA787CD424E22547521A785EC4287D03
-:103BD000BE591553646CDF923AA75782F62ABB5E32
-:103BE0004FBFE2FC3B46E43B57C87A3DDDC79A082D
-:103BF0003F2F67FAE7A6517A3E7010E903FDFE29D0
-:103C000093A294979665A73C83E1FC076FB530CAF1
-:103C1000973225FB9B50C695ED4FCBDCE2847A1A98
-:103C2000C7AF19FBDD4BD11FF496C0E32D40F70859
-:103C3000C7BAF5397B8D31E3D69923852847EA0C3D
-:103C40003C3F9F7E60FEB7B246923F357E5ECAF033
-:103C50008DF147D537497E77CC3EDE12743130DFA7
-:103C600086DCBDA8C70ECC9714994CF30DE4F988F7
-:103C7000F9B2BFDC7C6F0B7AD6E6ABFFB67E7FF580
-:103C8000E628EDAFDEC0445E3F9FEF6DDC9FEB4B5F
-:103C9000CC27F2B506E6FB8E7E7FF54951DA5FFD53
-:103CA000803D29E6CBFE72F325999B281E7387C4BD
-:103CB000CF754351D99DE88F3FBB60BD8AF8A6D927
-:103CC000678BF005C0B345229FE9CA5166D21BB489
-:103CD000710FB44C653E33F7DB60593C53A2FCFED8
-:103CE0007153251FC6C3F600DDFB8AD02FA5507B7C
-:103CF000B8C549E5BE1695CA07C11EF4917FCACB67
-:103D0000EB45DCCEBF6384B26235EA0B95369EDFAD
-:103D10003C730668A283F61618603D56CC23FC1A45
-:103D20009BB81D6A45BB393C1CD5D9613C27DBC417
-:103D300017A22D504F9A6654316F3BC9C5FC89FCC0
-:103D40002E3F28E2FED8DBB47CF8AF483CDE0EFA0A
-:103D50004825ECFF5A016A665C20A15E75E577D2C2
-:103D6000491FA95BD697A2C03AAE9126FEDC0DF0A2
-:103D7000F8ADD047AE1DCDE938DE9E74A0649984BD
-:103D8000F97AC670187E5D9AB294ECD1A5CB19CBA6
-:103D900080F7AFC4F740AEBC2AF49957FA9218DA0C
-:103DA0006BA16A1E67BEE656BD1D798735A2A01EAF
-:103DB00077C74407C3F3A8DBA86FBF4DC40B96C6F3
-:103DC000D99557C6E5D180964978823C814D83F3D9
-:103DD0002A4A71507EABC8A3B9BA48E57C6E948379
-:103DE00092A833E6BAD330FE98644E7CEF461BEFC0
-:103DF000A8E03BCCE12338687967CCF8D8447A5FF7
-:103E0000CCA7BD77AFF4D8888BF935416F7BB7AFBE
-:103E100098CB67D4AF0FC6ADF3EC82FCEF55B3443B
-:103E200078DB2FA35F415BFFFF297CBD097D1AB0C2
-:103E3000EF57677D3289E22D6C14ED7B91863F222E
-:103E40009F6AE9405D66724C3E1D73F67BF0BCDFF5
-:103E5000F84AB2773BE19FD01F226F1A2E247FF1E0
-:103E6000F106D6E1F4E5717F5CB542F94062BCE150
-:103E7000E01C9FEFA0F96DE82726DFB0752FCF7704
-:103E80001CE9A8FA00EF45E1F3777478A5BFFFD4E9
-:103E9000DAFD8884F6C57D789F4B1E9C0FFDB4210A
-:103EA000D25FF5F7B2E2D7A5DDB7D1D6D36A66C542
-:103EB000648F1A803FC07C0BED7DB2A4A2DFBD5F92
-:103EC00046FC2A19CBFD449813CCEFB9703DCF982E
-:103ED0006BE0F91B6354AEF7B9FB47C7C685D2C682
-:103EE000F278DAC2E4D736AA20FF4C0F6F5E8AF967
-:103EF0004B0BD35EDBE882BAE5E1565ECF7DED1376
-:103F000017E86CB687DB78BDF4B54FF2A16E7F7809
-:103F1000CB52CC675A38831150521FDE4AF2326DB1
-:103F2000AC664F4747E17C0B254E1F5FB634261920
-:103F300012C6EF9D63353F2933E13CFEAEFF388961
-:103F4000FCC8AFF95F7DFA7823C3A66CBC27247E3A
-:103F50001CA9A4CFCCC3DF019EF3E54837BE6FB0E8
-:103F60004408AE63316FA69850E0AE0B17C98F8836
-:103F7000C72309D0B519F565556175A01FB736B3CC
-:103F800080B52006CF994FE039CFE3D1D6A3CD3FFE
-:103F9000645D70A47246ECBAF6D038DABA4E4F4C73
-:103FA0000AE17D322D7EAAADEBB4D47F3F3A23BE29
-:103FB000F9C3CEE5786EA753FA474B503FF1F0FBBB
-:103FC000748EA7B3FAEF97BC3175133FC7CB1FFEB2
-:103FD000C152948F1B25DFE563317FCE6CA77B6BCD
-:103FE000ED42CFDB91150831AEDF53BE63288FDF82
-:103FF00007A89E24F962E3FB3502BFFE632CD71F9E
-:104000006727ED6C3A01F8183C24B14DD03F78FE9B
-:10401000AC19EDF1855DA7CC6877371E3A6546BBD4
-:10402000BA11EB304EE31E33F1AB78781F1F6BD41F
-:10403000C5D1357BE2685ED11607ACA771B5E4C582
-:1040400014D9F5CFA6CFC6FAFA55B84BE0EF330F27
-:10405000CE4674A9F7776FC1F25AD67714E3052BD1
-:10406000027A3D7F65835E2FAF6FD2EBD3D7EE84AC
-:10407000D301F9756D73AEEE3D861A32AC678538A3
-:10408000CF15CEDBA3C6F1588FB987231159937F83
-:104090006725DF01947ABFC5C22E89E8B8B1D64240
-:1040A000FED7A3793C7F3EB8D6487941414407AC5E
-:1040B0003749C29FE523FEA8C9EFD99D678EE5E287
-:1040C000FB6B4D040716F245D1AF5F2BF0E9DADA4E
-:1040D0009A0F10CF6AD51BB91C1FB3DF44FE9500A1
-:1040E000D7C755E1FFAEEBBCA33A03F5CF8D12F96C
-:1040F000375636E8F5F57AFC05F5B766291C7121C7
-:104100009CF4EDD736EBEBDBC70A3956CA4A914E21
-:10411000BE375692896E44FD4F79BF78250213DD74
-:1041200022F97721DEAD3547C6A35CBB450A505D59
-:104130006B87E78D5CEE70796F008A22BE6BE27E42
-:1041400085D03A89F071E510F91FA31F1887D68F23
-:104150000A7ED26AF56F247BE93949417DA45AF67B
-:10416000C9199E417B361E1F8F093C7F85F57970EA
-:104170005D450874807FD1D2B430FAC38A9E5F4512
-:10418000F98D451592D740F46C60CDE558CAC41F2F
-:1041900050DFB4425964ECA8257E3DC1ACF0FC412F
-:1041A000278BE503BE479884797CB8749C77FEA87A
-:1041B000DECFF01C17EDBEFD0CF23B7781AFFC0E9D
-:1041C00058DF0E2B9F7FC7B312E9AF8D9E63C417D4
-:1041D00073004D70DE46A7E08F9DC01FB5FDC3790B
-:1041E000E720BFC20B210B3C34EF082D3EA0E5D7E2
-:1041F00046AA0C1780EFE488798F97A9B4EFEC1BDF
-:104200003B24DC771E0B6D423FD18FC7327AAE95CF
-:104210009A1F7FF960BCBA06CF739DB3CF4CFAB733
-:10422000885727E8B764ECE404FD7C4CE747986DB9
-:104230003C9F8A71E5F5CF155C34AFC26831E8E880
-:10424000D5A4D874743DBF584FE70BBD7AFABE723F
-:104250006A81AE7DB1AF54D7BEB4A642575FEE9F20
-:10426000A1EB7F55ED2CBDBDEF9CA7EB6F5597E8FB
-:10427000EAC9C557EBFAA778AFD3F31B4707E50F99
-:10428000982DA1BE808AF7E6199B9A31C8AF4B538F
-:10429000A13394B60AAB1DCBF68949113CB7F69110
-:1042A0003C9E9AF4E2B79C11847ADA63964A287F9E
-:1042B0002885AB305E6411765EC9AD4CC7CF1795CB
-:1042C000723CD74A5371401907E7E339A0E6F27C04
-:1042D000E968099E8F051D8888C74F5B48EF9810D5
-:1042E000A7FFBE5256692B467FEBADBEB9E497EAF5
-:1042F000640ADE97DD67E6F94CA1A779FEACA7B3A7
-:10430000CFE08BA1B7BB8B397D7EDF5F45F9498D4F
-:104310005D20CD10BF77BF6346BF5D6357772ACA64
-:104320008DF1FE77CCA85F0F3E17F244EEB761FC2B
-:10433000F2898EC47968738ACD34FE31C16FEBBFC8
-:10434000C5F92D20DC02B48F34FE597F90EFAF7E8B
-:10435000B999E85BE3A3C03F75F1B078BEBC726663
-:10436000780BD22EF0519DFD72EDB2391FA03DC4E5
-:104370005884F418E0A3FAF6515B89BEAF8DB36F91
-:1043800026150FF053CF05A097937E43C27D2D2DA8
-:1043900095695F2703B308DEDF07B8A1DDF8FD21CB
-:1043A00070E2F0FB3CF83C2EFC89DA39C5F7AB2D06
-:1043B000E5FAE8E3C3F0CB3DE21CF749D17264664D
-:1043C00041BF8DF074A5C5B21CF30C8EE57DBA1506
-:1043D000E309F53F96D09665BFEE7E311BF30ECC18
-:1043E000078F66633E44B0E368360338AD35A99B5A
-:1043F000502F063CF06E827369EC8CD0FAD775545E
-:1044000074E3F3759D92175961F0D09939B44FD682
-:10441000B715F5F87DC3ACEBBA62AEA7AC2B56A9C5
-:104420000C06604E94B38792C88EAD3F087C08D7C7
-:10443000F5AC44F730F66DB3D426D24FEA4BF9F71A
-:10444000185ED866661847590BEFE33E8EE51D33BC
-:104450005B106F0E4A6413063B4E2C477F7C70A3A3
-:104460008961DC565BDF8779D1DFE0FEDF5C6D625E
-:10447000786FB075358FC7BEB9D148E318AF3751E3
-:104480007DC51A9E277C64F5EFB6E6C2B86FAE957F
-:1044900028BF7ED6F5FF790CEB2BD6703D281E7F0A
-:1044A00007F0350E3F5704F47837044F1BBE1C9EAF
-:1044B0006E1BC4D3F12867E1DC67E720FEDCCCE8A3
-:1044C000DE62EDF923A61C586FFE56C58BA1DD32C6
-:1044D00063784B36F28523BC7DE2DABD12E72F2AE2
-:1044E000DD67CF6D3733CA532CE67C680F9E5716B5
-:1044F0006EAD5FC2BC362647F3717D2E91C7F5A421
-:1045000089D51E443F92CCF94BD933CEBDB17EA4A0
-:10451000F9021F35BE570AF6FE41F243778CC47B81
-:10452000E68F9BB87F6CB418AFB0A07FCE6228BB7B
-:1045300004BEEC17EBD0EADF10F8CF3AF6911C5D21
-:1045400068E1709FD71CA9C37DDC20071E43FEB71E
-:1045500060F42FD6A25C6BCF7FC913203F5709C9E7
-:10456000B5A0388F23D3DEDBB301F3EDC6D9E81C49
-:1045700017F7DC13C5736D74CB9467682D9C941387
-:10458000B8881F21784ED5DDDB6BEC3A33C79780B6
-:10459000AEAF13EB2D13F7F35817F71F003F96A795
-:1045A000960FF6D3F6AFF93DAC850FD2396DF826EC
-:1045B0009BC8EFEDDF417058B9F68484F752AE32F4
-:1045C000F94C7680F32FD2D872B4835F6A61744F4E
-:1045D000ED38DE570356F24A8B42F5A8B8B7F65AC3
-:1045E0008B4AE55566FFAB089FE52F341522BC8E3C
-:1045F000E4DDEDC7EF309C3E2EF459A6F07B8C0233
-:10460000F7CE76199905DACF1E92C2E43411EBBFCA
-:10461000E6DC4816007EF22B713F6E5DF3EBC4E7DB
-:10462000BC0D67E6A09D3171EDA9AD580F36FFE7CF
-:104630001CD41B7E037202F12BD82931278C5377AF
-:104640002E83DE5FD779C28CF6FCE386FE3908FF45
-:10465000D06189EE55059BCE10FFDC23FC2B69E36E
-:10466000781C31D835D140E7E92BE1F68938FFEEE7
-:10467000923FA722FFB234ABAFCEC073EC35D23934
-:104680006EAFEA4F55129CCB491817F3477E25F2BF
-:10469000F186F0597388FCB2B5026FE3DB93C7195A
-:1046A000343BDC24F2949804EBA913F8558FDF8394
-:1046B000C9403D5F8AD8806EEBBB66917FA3BEE99F
-:1046C000E2DF77190EDF2EB56C64DCBFA1D5D1FE19
-:1046D0008ACDD742FB4B7F0F3DC4EF71E5B9730222
-:1046E00017D1EF827D23297ED2D8CE285EB2EE5C30
-:1046F00009951F3D7B1BDD7BB2D8FAEF46B9C08A16
-:104700000CA4D7AF0BE9F59B4F4B381D7C5AC2E97F
-:10471000B8601CD8271636609F801D5284FA0ED8C8
-:1047200021A93D4C679FC43F27FBC422FC86A02ED5
-:10473000059E4CB0EEBF9454958ECB42BADA49F840
-:10474000CD00BF11AFE2F739651C5F9746CF2B7ADA
-:104750003E30A3BE1BEC4C4CCFE6D2CA2938EEB695
-:1047600061F2EFCE8B7DAEDBCD085EC1DD1904A713
-:104770000FD96E7F15E0E587B00EBC977EDAEF4F5C
-:104780004E87F74F07FCC9189FD3E8BF71B78DDE7E
-:10479000DBE65E9289DFD1982FF0FEA3CE59168416
-:1047A000F335BB39DD69F3FD26B22213E967B2A9FF
-:1047B000DF8CFEC9515DA75251AF9BFCECD24CA4DB
-:1047C000BFE1D639A384F3E575CD2397D3BD1FF898
-:1047D0003102DDDF24E4587073C48CF0BFA9991155
-:1047E000FE763FFDEB46A4DF8FBA921594931F3EF1
-:1047F000971C427E7FFA7052D80043AD15DF3FFA16
-:10480000D0D4B788F4C7678D94AF103CFCC7BB9178
-:104810001E834F27D13D9A9BBA6E3B83726E6DD734
-:10482000DC0F642C1FFBC7D2C3BAE6D1CB63F38B7A
-:10483000FFD8726024F2CF8F64CE276EEA7C8AF4B0
-:10484000D99BCE9F1D8FF9831F3EF79729C8CF8232
-:10485000CF9F9D827C2CF8D3B353B03DF84C72535C
-:1048600022FD646D29F79F68F2D1F586ACF3B3643D
-:104870000B79E06ADB5983DF29987C6219C501B4A2
-:10488000F6C985063FF69FFCF3EACCEB63DE6B8B43
-:10489000CA942F31E94475F2EA18BC4C2E35697E72
-:1048A000BA4BF38F883C04CD3FB22D2AF37B750DB4
-:1048B000C630E6F1AE8CF2F87BBCDF8431FFFC320F
-:1048C0003CEF35595EFC3E0FDE4BC7B8C8E99B0B89
-:1048D000C3742F3D6439EA8ED18356440D9124F47C
-:1048E00083742545501F5A11954F25C5F8457EA361
-:1048F0003CB905D5F81501BD1F23DE0F023F297213
-:104900004CFCA47E63C4A4C9A98530FF2FB6300532
-:10491000E33643FC23B55F253F4CBC9F448DDE65E9
-:10492000C1F75437FF9E8EA667E2791D4A40EF1506
-:10493000829E353A6A8B1AE81CDAA2551637941E05
-:10494000414787406C86302FA86BE94368A7B79D25
-:10495000BF2A19E1D5F6C61286DF8B38AD54590A45
-:10496000F1BDF35FB52CF70CE2C710FE318EF3C733
-:10497000017D601839F7A1E05BFF2879F7C13F8915
-:10498000BC03BBBA1FF937D8D52BB9DF83DBD5F110
-:104990007242E3BFDAB8AA38E7A1FCF703D25FC0DE
-:1049A000FE25FEAB96A8D46F54D7E24CB28BDF58ED
-:1049B00096A9DA878E5F207B0D199EA1E36BFA5AC8
-:1049C00030E43B6A413BC6C7F34F83CB24FA6E54B5
-:1049D000D02F919E1DAC3385B15D5B4F74198F0B49
-:1049E0002EF74AF41D104DFFD3F4C381F649D0EEE3
-:1049F0001AD41735BD30EAE77ED1653E13B55F6541
-:104A00000EE4944CC6FD59E9F9E4697C5CE0034787
-:104A1000D1FF79D5D724FA4E97A62F6AF819AF4F50
-:104A20007EDC5570D1EFCFED1178A9D1D7E838BA37
-:104A3000D0E4D47C81EF8D28A733514E7F66EEB34E
-:104A40000FAF77839C2E2DA1F718BD3FE9E7B23F4A
-:104A500091DD7D588C3B433BB7E80B95B8DE3C16A7
-:104A6000A5BCA8E1E467AEF0D30CD73EFF12E9F88D
-:104A700086927F2C1D5F57F2CF41C703FA9F39F111
-:104A80003EFF52527913E2AFCDD844F7A3D8CF4CB2
-:104A9000E4B78EEFA76AF6A4CC74787C34CF6C4070
-:104AA000BB27D8C0EDFEF674F555B24F5EE4F7EEC5
-:104AB0006F12F94A379E53A86CC70F8361FBB75C2E
-:104AC000E4B7B9F1C009930FDE5FB9519A88FEA02F
-:104AD000950DFAFDB467F9E6C6FAC1DB4774505C80
-:104AE00021F450818AE3D7E366D11FD23E328CB1E4
-:104AF000C746F4E34CC0E731F72D609E75E2F90C30
-:104B0000E1DF61717AC04FBBDF247F0FC685907EE5
-:104B1000CD5D12E585047BB9BFA3B18BF385F71B8F
-:104B200024E227EF8BFC8C60B395FCDB9A1EF181AD
-:104B3000E8B7E66689F4BD217A854F1F7759F7E01B
-:104B4000CF892FC6EB111987F838186F41BFCCD128
-:104B5000BC2912D6D7815D88DF250DAAEA95B97CDC
-:104B60007D2C4CFCC5A7F3A37CDCFB3BB223573E5A
-:104B70002BB14CD23BE2E22FEDF3E2E22FC78EE6FF
-:104B8000E23842CF50E03FF41FC6EB198D9D274C11
-:104B900068177C5E9CE59912BD5F708CCCFDAC63A0
-:104BA000BA2405FD4963049C2EDB662338CD797B4E
-:104BB0007526D2B9763E1F2DE6E7F5D19B9F54E2CC
-:104BC0007B53DE9615E4B73F7D73E3EBB9BCAE5A79
-:104BD000547C6F6332DA211FBDBD3E19E1F85328C2
-:104BE000F1FB48CF9C9413FA0F0B4B39BF01F976B8
-:104BF000BC84FCBFC26F2C837C4B19F4BFC4BF378D
-:104C00004BBCD78EDF2D42FC7B96C7B7DB4704E653
-:104C100051FD9E7C9E472C737C7DAA2B5D417DAF10
-:104C200014368B71D81FD9581BC657DAB3022F110F
-:104C30007DDC6320FC85F7F977270EAA24EFF08A44
-:104C40001DC63FC683ACB1505EA383FC37DA7761E3
-:104C500046801D2ABEA3B00CE3AEA5220E32DEC6EE
-:104C6000641C7F8729B07D1CC65DBA65EF267C4732
-:104C7000F666E27790E2E3315A7C588BCB6871E2BA
-:104C8000E1E23212CE339EE359EC774EB4F80BFBDF
-:104C90001ACFDF6C9DDA44F75F7B31469238EE32F3
-:104CA0007A5C82784AE938ADBF3E9EB6BDF849C20B
-:104CB000B72F1A47BBA164B8F9556E77C6CD3F2907
-:104CC000FDE36CB25FFEFA5FA924CFBACE92DC3965
-:104CD000DD9F24EE71F6713F759789ECF5D360077F
-:104CE00065C5C8B3F6717CDC9EAE59848F87A2D5AA
-:104CF000C9D8FF09F17CDB1BCB96A23E1D8ACA3CBA
-:104D00001F9B71BBE650549ECCF5832170BAAC2436
-:104D1000417CCA624B9C07F49EF017BC27F63DEB22
-:104D20004D6EAF0437F2F88122E82D5863267E726B
-:104D30002C2F5BD2FCC83989E20BCFF6139FAD5FF5
-:104D4000C3E3BB971C5FE8EC36B1FC047EDB9A3909
-:104D5000C46F2ED55FCBD00A9E32C89F2B4BC5F7B0
-:104D600086CAB8FFF6C5127E5F27A36962257EEF6B
-:104D7000EEBD61CF3B70B0F4D2E27CCF7B2EAD9F15
-:104D8000A138513C7068BFA997D86FCE25F6BBA15A
-:104D9000F8D2D6D77589E3EDBFC4F16E1997A8DFB5
-:104DA000FFA3F1CFF8F8667C3C343ECE99F4E2F5EF
-:104DB000216CBB4DBABD3F82D04D7DBA5602529593
-:104DC000D31FB4205F5B308DC703B6555BC27BA594
-:104DD000C1B8A806AF87CBB8DEA578CE84F0BB8873
-:104DE000A37DD1EA4CA0E3D3D318D90DA7ADE27BC4
-:104DF00048B23262319D9F42DFC369B7268E2FAD24
-:104E000014E30DC7475E29AB7CBC7432DD1F4AF842
-:104E10009D8AEA526E67289D8CFC354C56472CA122
-:104E200079D5112867D25EE0CF53238CF2FBA0DD49
-:104E3000B584F467D585EBDB25E25E19F38A5CE87F
-:104E4000A7CB00798B71913B303E427E7D85FA691C
-:104E5000F34DF2F0F97699988471ACD0389E57C131
-:104E6000D42788EF68718DE3A6C8EF574914D7E8B7
-:104E7000C5F5BF6C8878F6B9F8B9207C3D87148AEF
-:104E8000B7BC32EDE162BA172FE21C1B14DEE50855
-:104E9000DA19B08E0DCF5510FEAEEC99F6CB3AD4A0
-:104EA00007DD32C179881E2EECAB93C23ED4ECAB49
-:104EB0003EB41363EC8DB784DE9080AEDE2A4D40A5
-:104EC000A7BB246EFF865EE6F66F85D95B109B4F0D
-:104ED000F5BE80FFAA08F7C36A76ED785FD8900D1B
-:104EE00070A8B8D9184902395DB1B5CC8CFCBA624A
-:104EF0006B9E8DFC4AAB0F1A3478273AF78FC53A70
-:104F0000B7F5F6535CE2A9F87BE61E33B5EF15F86A
-:104F10003309CF16CA0D85722B8ADFB4998A319175
-:104F20005FBC1EF47E5CDFAA76BE5E2D0E521F5162
-:104F300067E13CA78EF66FC5B2BCC1358BFC866BB2
-:104F4000CF6C45B9193C7FF6D815E40730AB89EE34
-:104F50000B3C5B6624383C858A08C26BAE4C79BB3F
-:104F60001573653AEF8C7A2BD9E1192666C4EFAE3A
-:104F7000662CE672ACBCC6310BEB6C593AC9E1F257
-:104F80005E35FD7ACFA09D9F31776316C2E9F3E2CB
-:104F9000439ABFE02AB32FD333F98BC787D61D7F3F
-:104FA00083F2CCAEE9D3C787B478CF70F1212D3E20
-:104FB0001BACF944174F0ECAFD73D0AF52F1DC2978
-:104FC0008A0F073B25C5E91A8C1B050F9D31137C01
-:104FD00045BC08FA9BF1BD0A38F61119F8BD011E4F
-:104FE0003F7A1AF371CDF83D3D85F26E7F82F9B8B4
-:104FF00045F83D3D9E8F7B18F371CD78FF83E7E345
-:10500000F688FCDE60D7198A374DF30CC9A7A27861
-:10501000C42D927FA6479F4F45F5F87885D1C6ED00
-:10502000D060AF89BE771E3C6E213E5BD9B56A0C5D
-:10503000EA63DA77C81B315E10E35FFAC8E7B5E2CE
-:10504000FD9E8FFC5E2BC6092ABA3F30ABC4772287
-:10505000B998C2D42847CD68EF231C28CFAFABD274
-:105060008A70FD5CBF7EE7FFF7EB7F11BFFEE13288
-:10507000EED7D7F847B9DF40F7CACB7B7DD6EB63D5
-:10508000F8C3363FF70F6F73E713FDDDE5CF4F5FD2
-:105090001DEBC7AFE1F65BC65CB735F6B9713CFFF7
-:1050A0001E448694F87EC1768F61383D707B62FD28
-:1050B0002E713C605B0DE7239ABF7F687CC0FBA22A
-:1050C0003BC6CFFFD1CB16FA7B0ADDCF26913CFF42
-:1050D000F4B9A47DA87797D7AC1E9302F5F2934953
-:1050E000CCC5E5912EAEB0B2C6E0B3A6268A23F8B1
-:1050F00072E97BA1F1F1821A03F1F78178418D7C8D
-:105100008AEA423FBFE6CC7B29F8E9EBA7A4703BD3
-:10511000DA174FAD93BCDD6C68FC0006CE655361B9
-:105120001735DC4EF0D65AC82EF8BCB842DDA113B4
-:105130005BD04F3091ED6CC7EF4F4E741B14104590
-:1051400009E20A3CBFB35CE811F1FE01C40F94FB15
-:10515000F17EC1E7C5F93D2FE4FE5CD4F9B306C783
-:10516000D1DE8B3F77479974513FA32CE4565B4DBA
-:10517000F9363CB7D0020343FEDF56536571C78C46
-:10518000F79A87E7CDECC2388523364EC1E311F19B
-:10519000F1098D3F55747F3607CFFDAE2EEE3F0AE5
-:1051A0003AB93FB3E27025DD33195C27DFDF5DCE0E
-:1051B000817B86E98CEF8B59B89F8BFC0AE50B3E0F
-:1051C000E9C1BF37C0FCE9F4F70B82C7DDAD76E477
-:1051D000230BE4C9924AFEED017F37FAA396BEDAAB
-:1051E000300FF3812B964F3C81E7B2BCCE44794718
-:1051F0004B5FADA5EF8A6BF2AA62F9DECDF8F768D6
-:1052000096174B5EAB8AED3555D83EFFB1087AF65E
-:10521000D8425C1DD04BF438F4CE27FFF6C7483790
-:10522000158B85DFBB8ECBD5E55D8B4DFCE3567AC8
-:10523000397724EF53B29BCF7655903F3B13E3ADC4
-:105240009E413953F11CC89F9441F9F3F7CA1D4799
-:1052500019CFF39F00F207D793B198C705E3CFFFAB
-:10526000350F3FFFE1E4C970FC13E507FF7B3BA16D
-:105270005CC939287755B4A72F1B94BF4A27D4732C
-:1052800086C7BF7902AFD387D1BF660BFC1C365FE0
-:10529000A3F31FE3F7AE2CFB27F17B0BFB46F37F59
-:1052A0006BF6D07D02CE5AB947F08DBF3B5F1985B2
-:1052B00062C27CE58CC4F9CAD77448F41D1691AF5C
-:1052C0007CD4CC2A0F3A304F4FDC4B08FB49BF3916
-:1052D0007AEFAFB63EE2C07B09928262675DC70992
-:1052E00092CFEB409F213DA8EB8FDC2FD5C1F34B34
-:1052F000D775EAEF3F68E5112197AB613FE44716A8
-:10530000797C730E71BA0EFACC61D5857EA16FCB14
-:10531000B17EA1A01ACDD2F203C35C2E25CCE36BE3
-:1053200064FD94EFD7D82079511E7C693F918FE7B7
-:10533000F75DAA9FA8AD4CF885849FF99152CE0FD6
-:105340006A039284FAA8C5E05F4BF9BD8725255111
-:105350009EE8BD02DFE70B3FED7E33C783FDD3251B
-:10536000CAABC57B3178BEFB0FF3FCF9FDE53C7F92
-:105370005EF3CB6A79F1E306FDB2741F46CBA7D783
-:10538000F2E3B5FBA18B77DB22A85FEC3075389197
-:105390000EB5BCA2F9A88B601C467C673C7E9D5B69
-:1053A000CB2AE79751BF61F59BFD6509F49B33421A
-:1053B0007E3E56A6CF238AD1CB9F289BACD3CBA9C8
-:1053C0001EAF97FF4FF965E70CEF17365CA2FFEDB4
-:1053D0005B97D8AFA12C817DDD6A4DFCBDD0D4F1A7
-:1053E00082FFC6FDBD1136E47E0F976FED92FACBBA
-:1053F0001914E732519C4BE32FED297CFCB7055F74
-:10540000D1CA7382DF0CF75D49E378DE6FA3E47BDA
-:105410000BCFB1F480DE4F56D6A1F7934DE8CCD038
-:10542000D5274646EAFA57F4E6EBDA27474B74ED00
-:10543000979D2CD7D5A7F54DD7F59FF17E95AEFE5C
-:10544000957EBD9FEC8A734BE2EE1D71FCAE048C21
-:10545000887D6F96E5EBBA7EB90DFA7DE535E9F703
-:1054600035A659BF2F6D5C5748BFBF8276FDFE320F
-:10547000D07FEFF9F2FEFB4D1E55F8EF0BE8BB7F36
-:10548000BB6ADCF49D6BEDFE9FD6EFBF0137C3FC1A
-:10549000BB80700000000000000000000000000061
-:1054A0001F8B080000000000000B53E16760F851FB
-:1054B0000FC15BF918182EF021F8F4C01CCC0C0CAD
-:1054C0009C40ACC8C8C02001C4FC40CC06C49E0CA3
-:1054D0000C0CFF81F81B10BF05E22740EC0CC40741
-:1054E00058B09BE3C6CAC0E001C4DC40B3789889D9
-:1054F000B7DF8917C17ECCC3C0700E889FF1D0374B
-:105500000C061B5E27403FBB7E43ED3A2932F0FE7E
-:1055100006612131609A1447F0A78AA3CA0B8B2138
-:10552000D8C9D294D9950FD40F00F19321F08003FC
-:1055300000000000000000001F8B080000000000B9
-:10554000000BED7D0B7C94C5B5F87CBBDFBE92DD16
-:10555000CD26E44900370960501E4B80C84BDDF072
-:105560003252C40411828A2CAF10027914A9A5FF0B
-:10557000DABB0B2804AADE5851A37F6A17041B2D3F
-:10558000DA80D11B6DE02EA208D56A684551AB0DBB
-:10559000888808498C8F6AB57ACF3933DF66E7CBC4
-:1055A0002E89B6FE6FFFBF7BC3AF1DE79B993367A4
-:1055B000CE3973E6CC9999B3268385192E60EC1BFE
-:1055C000FCBB9C319B893136A62B6D573A86AB3993
-:1055D0005DE5B7F9BDCC6B66ACCE6FA5748B3F9D16
-:1055E0007907C3779FA1306867EC5EBF8BF2BFF08D
-:1055F00017525AEB2FA27A77FA4B287FBBDF47E985
-:10560000667F197DAFF157537E837F0DA59BD445EF
-:10561000692C05FA66458559C98C553D9393B71990
-:10562000725B668D4F504743FE15233366017C9FA6
-:105630004AFD31D5BD69E0E8AE7A1A9E9BD449FD9A
-:10564000104EED128E17B3325B8C7A5938CE3B97E1
-:105650000878F6D69A9CE4A8F50623BCDB4B00DE5E
-:1056600050287085AC39D1E15D8CF03697A8BC5ECE
-:1056700072B0263B3A3C0FD6ABB941C04B0F5863D2
-:10568000D41B83F536DC20F0EBE7ABC98ADEEF787C
-:10569000ACC75CEADF5AAD8CFEBEC9C6FFB7BB4ED5
-:1056A0005D2CF246CC263136AEAB9D3E652CC070EB
-:1056B0009C2AF315121FDC995F7F93CFD84D0813F6
-:1056C000DA0726B19011FA0F24B1E0FA2CA9FE4CAA
-:1056D000AADFDAF7EB6F52A5FA014394FA26D6A0B7
-:1056E00060F9CF518E80EFF7F97329DD28E4E7BE2A
-:1056F000A106C6B05DBA393808DADDE3F790BCDC44
-:10570000ED1F4BE5770939FC7721674121670FA22F
-:105710009C41BA15E5CC8CFDF95A4B014EFBDE7865
-:10572000B6D94DF2B598F05419C1DFB077C8F6CDAF
-:1057300000FFBE1B569DDE06F46F6B1EE63142BDB8
-:105740007B866AF2C5BC2CB9ABDE3DB34F38170D72
-:10575000257A97219CBB3D827F2A0C2CA2DEDD336B
-:10576000C2F52AB0DE5D9E30BC5064BF774D09D7CC
-:105770005B457C56584983BD3B5F763085E6230800
-:105780000AD1D784F48579F9EC80EB9456689F921E
-:105790009C97C6A0DDFD381FCD38EFDC4417AD3D2A
-:1057A000D2D907DF332CAC1AE10365F71B015FD3B5
-:1057B0006C7722D2E5F66B8B98328CB1BEA23C3569
-:1057C00050A464015CFB9C2205BF9B6643397C7737
-:1057D00089F2E435BCFC762C7774952762397C4FCE
-:1057E000AA8672C8DBE7F2F23BFCC089C15DF536E0
-:1057F000019F7DC4EF74FE1DD88AF4318DE6A98621
-:10580000F713282440BF83988EE9C27FD3A07B334F
-:1058100016DABBF0B50DAEA7BC86DFA6C17194D772
-:10582000F0B15DD82F6321A47D97F465DE5C311F54
-:1058300058773A277AB3A5F24CD593A0029D325FF0
-:1058400032B200B02013C413E1E9DB153103E1D912
-:10585000E3FC4BEEDDFC330D95E9A0A547053D3497
-:105860003A6CEC2FD3C13240A6C3C601321D2C17AF
-:105870009C9F0E3B989BE81C8B1E5ABF9B87C8FDC4
-:10588000C65D24F7BBF922B9DFB88BFF39FDD664BA
-:10589000C9FD5AB3E57E6BB2E57EAD39FF58BF4C0A
-:1058A000F5C064407DA5FD5D28E9B7AB99EF2CB646
-:1058B000473D87F349D373A6641FF3D9BBF809EBBF
-:1058C0001463F99170064B7A15E07C8AF5008EF727
-:1058D000FC705C3A3883F470BE16F8B0483DDD0DBC
-:1058E0000E1BA81F8749E1ED428688FE99EA6345B1
-:1058F0008EC8761E5DFF39FAFE9D8A1887E1BCFDD1
-:10590000BB7574CDD6E39326F06186F3D183B97469
-:1059100070B2F470DC029F90725E386EFD382E1407
-:10592000FD071469FD027A0CEB6AD70EF8D13A959F
-:105930006709EE04FD10DAF7E5295C07CE355EEB6A
-:10594000B640FDFD232DA1CBA1FC5CB0206881F207
-:10595000C94F1E75A21D53F1A451C572C33E1BADA4
-:105960002F6D3B142AAFB2B4DC3901CA3B9E34B26E
-:10597000EDD45DA601C7774AE81416E2F9521BCFB1
-:10598000566CDB7F23B62F6BB2301BC0AB787AD955
-:10599000CC09905F76C8C4B04AC5CEB5E6BE905F6C
-:1059A0001E541A300FF8D23A15C8B3057742FD7568
-:1059B000FBBE6C43FCCF359A06213E67609D70C3E9
-:1059C0003AF192A3257536D0A73CB87B1AB62FDFE3
-:1059D000A57840C301FE3B0F6620FE8F281E0BB04A
-:1059E00070457D3C7347CC97538D461AEFAA6D4A9C
-:1059F0009001BC65AC761AD2B302898378782C41C9
-:105A00009BD235DFCEF8EBA83F2D5FF108F407ED10
-:105A10002B1F573C38E44A03F3E13C6E7BDA56F225
-:105A2000901DC7BBD63CD881E3DC68C67ACB820B1D
-:105A30009FB2B911CF6DE66988EFD66DE6D2A14865
-:105A400047B6A06828E2F77F65FCEA8C5E1CEFAAE7
-:105A50009196ED46C083D943036739BAEBD933B089
-:105A60005EB923D6CF72067A9FD6EFA0B97858D701
-:105A7000F72F0D89A43F56D41B99DBDAD58F261F4B
-:105A80008123423EF63A88DE1A3F57B9F814D0F81F
-:105A9000B92A51F057EDC89F35AC3B3E77225FC81D
-:105AA0009E7651FA0B583731DD02EB3CD2EF5EB0F7
-:105AB0009FDC64977BE8FB03602761BA15EC244CFC
-:105AC0001F043BC92DEC24ACB71DEC244C77809D02
-:105AD00084DF1F067B1CD37AB0C7F1FBA3608F6302
-:105AE000BACB1FA0EF8FFB6B286DF0D752BA07F926
-:105AF0000669A33F48F59EF2D753DAE46FA0EFCFD3
-:105B0000F89B28BD5DD0D1399115E03AEAF43217FF
-:105B1000923D6986B7C004F9A4229E4FBD21506012
-:105B2000867CAA0FF24097BE2B430516C8F7ADE658
-:105B3000E5036E6193AC901F10E0E5D9B77B27D9E0
-:105B4000209F5DCBCB076F0D4C8A83FCE0202FBFDD
-:105B5000685768523CE42F6AE0E5C39BD9643BE494
-:105B60008787783EEF25EF6407E4F35A783EFFCF4E
-:105B700081C94EC8E7B7F2F6E3CF068DEE28EBEF0A
-:105B80001E937B31AA9C03CADB5E3503F266F74D98
-:105B9000A8128F2AA728DF68F252F9FB4ABB578563
-:105BA00075BED1ECA5F22F94CF29FF94C947E5F13A
-:105BB00006A580F2661F95F737C451BEC914A0F23E
-:105BC00011863E3C6F0E507981A15F01C27FC614E1
-:105BD000A4F26B0C8378DE1CA4F25FA8C30BA64072
-:105BE000FDC70DBEBDA8EFD62BBE32B40F99DA901B
-:105BF0008EFA4AB32B77E2E0D0CECC30D33CD8F348
-:105C000087FC87681EE05F32E64B1F46BB14E01C32
-:105C10002438268063EC194EDECB632538792F9724
-:105C200069705E2138B6DEC1D9F3F278199F97CB3F
-:105C30003538C7088EA377E3CA7B65A28CCF2B2BA0
-:105C40003538C7094E62EFF0693C2AD3A7F168984E
-:105C50003E67707D589FD23B7C46BF26D367F46B6E
-:105C600061FA7C4CF864F40E4EE36B327D1A5F0BE4
-:105C7000D3E72B82D3BF77E31AFDBA4C9FD1AF870E
-:105C8000E96332209CACDEC179EA6D993E4FBD1DBF
-:105C9000A68FD380F419D4BB71E5BF23D327FF9D12
-:105CA000307DD2089F21BD83F3D43B327D9E7A277D
-:105CB0004C1F37E133AC77E3CAFF8B4C9FFCBF84AA
-:105CC000E93384E08CEC1D3E4DEFC9F4697A2F4C2A
-:105CD0009F3C8233A677F88C3D25D367ECA9307DB5
-:105CE00026109C71BD83D3744AA64FD3A9307DA6DC
-:105CF000109D2FEDDDB8C6BE2FD367ECFB61FA5CBB
-:105D000045700A7CF5840F03388ED8709E3927D3EE
-:105D1000E7997361FACC213853014E4ECF70C6B764
-:105D2000C9F419DF16A6CF02827365EFE03CD326D3
-:105D3000D3E799B6307DCA88CE57F56E5CE3DB6554
-:105D4000FA8C6FE7F4A9B278263BD0BE4B649EED87
-:105D5000D0E492930D079C9037D99907C1BEA484D3
-:105D600076207C582BC92E543D9A9DE2616887CEDF
-:105D700070BA3DE8F7316AF6086BA1FD827D57A243
-:105D8000E40FFAD230E916C4D701565BA45D923015
-:105D9000364EB28712BD4952BE4F615FA97E4A514D
-:105DA000B6549E567291549EE1CB93F29965E3A549
-:105DB000FAFDAB2749F90BD64C97EA67056649F916
-:105DC0009C9AEBA4FA836A1749E517D6954BE543ED
-:105DD00082ABA4FCC5F5FF47AA3FAC619D543EA22F
-:105DE00069B3543E32F40B293FEAD00352FD312D02
-:105DF000DBA5F24B8E3D2A958F6BDD23E5279C7E3C
-:105E0000466707CAFBFFF5058CDB831966B20743BB
-:105E10000E33E5CDFB6C64FFEFC73CF0D3DC7706B7
-:105E2000E5CDCF2E7627E37E1A01C07A5FD0B7EC9E
-:105E300042F4F7DC3CDE77A10BBEDF6CF68D7045DB
-:105E4000F1477854DF3E03F98B5A14968EA9DB8014
-:105E5000699C51ECD72D5CBE3666E53F148890D323
-:105E60009AFE30FF207FD86026FB5593EF8DFD4BC7
-:105E7000D31746F4B3A1BFB964FB50FE7DB11DFB3F
-:105E80002B7A11E75995B96330E2A5EFC7923D56D9
-:105E9000EAC73AA08CFA790DFB89F07B590694E9A0
-:105EA000FAB1966C17DF453FC7705CB1FAD9983DDF
-:105EB0005E1ECF8072EAE75D5D3F1B0794EBFA89B7
-:105EC000E3E381EFA29FF7CE3B9E9C89F2782E58A8
-:105ED00049FD74E8E866B960A5AE1F3BF583DF179E
-:105EE000933F17760169C0674B4729C9C17FDA58CC
-:105EF00000E4C29C59FE6BCCB3B76C6C10F6E38621
-:105F00007EA11ECBE5FEA3A70D49349ECFE280FF04
-:105F100011766AD77E3640FBE2A5024516048C60F6
-:105F20007F5B296473C9AEE20137B9216D3A30F065
-:105F30006EEC678BC33308F26D4D93CD8BA3C8D342
-:105F4000D25AD3A9D648BF88B6BF99C472ABA1FFB5
-:105F50005D369794D7D2958A8B097F04E54FC0BEF2
-:105F600085C17EE0CFB02F6040AA774D7C9FF60EB2
-:105F7000EC6F30DF0AFB1B2C676C2DB53B21FCB4AA
-:105F8000276E578248EFCF7EF24313E9F1007B354D
-:105F90003D15FD6EFC6FC19A78F4F187F15B18E84E
-:105FA00023E5415D661AD2695F48FBDF8EA72DC1EC
-:105FB000ED48D79A4CA0A9A897CDD8EBB0C9CD4849
-:105FC000A26CA6612C63B3AB8BA7A6D12C52FAAFFF
-:105FD000023C67358E34410BD6666ABDD163EF82D1
-:105FE000CBBCA613481F2BFC4338D714423EA2FF5C
-:105FF0006B8BE4FC5CA676E581DF838DD9826FA292
-:106000005FB7D7847C2D4AE5F8CCC5340F8BB9BF78
-:10601000A3C4C5DB6AF8542D36B110ED4F03290C2B
-:10602000FDD18164AA779DB6CFD4E15762B27A8B55
-:1060300080AE250B8D44573DBE6FEE8BF71A86431D
-:106040005A73B7095D9B3DE13FCF2797B332DE9F7F
-:1060500046574D5E4E09FE9E40FE43FA3EF21FF04B
-:106060003E29F8DF25C79CFF5516DF4CE47FC7FDAE
-:106070004646FC127C9F23F8BEB456E6FB1CF49304
-:1060800043FD39ABB382EBB17E5D1F89BF307099A0
-:106090000EB5774D05B5DA0DFFB7851C5C57B3FB20
-:1060A0007964EFF565BAF1093EDC28F8305F478F77
-:1060B00039826FF305DF96B1C06D19E43F0A9AD0BB
-:1060C0002F36AF4C61A82FAA7EAAF1AD55E29B4FA7
-:1060D000E39B0EDF1B05DF6EFC09E79B1EEF56C13D
-:1060E000B7D6BA8F4D2CBB3BDE7A3C17ACD18D2B8B
-:1060F000A0E75BAD38777099D1DE29F616F439192F
-:1061000051FF9AC22BFB9C8CD00BD716154BF9B9BB
-:1061100025F3A4FAF37C0BA5F2EBCB964BE5F3AB9E
-:106120007F28E517ACF989547F6160AD54BEB8662D
-:106130009354BEB4F62E29BFACEE7EA9FEF2E03633
-:10614000A97C45FD23527945C36E295FD5F4B4542B
-:10615000DFB06FC8D5285F2F1D3532F4977DEA79FF
-:106160009FFC759F7A4C1EAC538932370EE5D94D92
-:10617000F27CCA9F4BE969BF87E4FD8C7F2CA56D3B
-:106180004D07ECE87FAC8A03BD9F0876B8F1CDB52A
-:1061900035FD70BD81F6E3196B36B6AE0D40FE00DD
-:1061A0001E46C1BC99516766A1510CA4BB6F589E95
-:1061B0003B8C11E5AD3D94D7A92CD4A77BF98CD6A7
-:1061C000E8DFDB958EC119E8277CC3C27646F8EB81
-:1061D000BA9F57B04CB42B62959F35B0B2C8F3ACA0
-:1061E00093467E4EE2344E3A698474A599CFFF956A
-:1061F0007B32263127E64383ABA3F85DC2FD350031
-:106200003269C8E71C69DE2FABBBB86B9E33EC2745
-:106210009BE476797094F47D45FD04A95DAEE27B44
-:10622000D708F5CEEE37D27ACD4207065C330CF1B3
-:10623000F39EC4EFAC2985ECAE16BFB7CFC9818CF5
-:10624000FDD15F48E9ABFE224A5FF397507ACCEF6D
-:10625000A3F44D7F19A57FF65753FA8E7F0DA5AD98
-:10626000FE00A527FC35949EF4D7527ACA5F47E911
-:10627000697F90D233FE7A4ACFFA1B286DF33751EB
-:10628000AAE9CF9EE4EFB4585FCFA0FC459133F369
-:10629000AD6C5DCDC42E398B532DEB50CE34FACE80
-:1062A000A8B308794895E42111D76192B31ECAEBCF
-:1062B0004C420E63B58F5E8EF2D6F77B9037C6D612
-:1062C000911CCC1472F75DE58DA1373E05E529538D
-:1062D000274FB21C6A72A4E9815CA568B83AA64B44
-:1062E000AE661AB99DA4C9D5CFD14E8C626FDDA020
-:1062F0002A62FDE3F611F36518D07E5B25FCFECC27
-:106300009D4EF94ED1F77A00D782F5D4602EAE2398
-:106310009DB97F1B8CFEF1CE6316867EF858E3D3C1
-:10632000CB4B6CBA7B69FF501A84456D54F7725B96
-:106330001CA7ABCDC00A591E9ECFE61FF3013FE359
-:10634000FEF3E23CDCD7C27795915D15F41447F17A
-:10635000B73394F1B49EE9ABD53FF5C097F9786EA9
-:106360003E53CCF3B803467EAE1D7AC8734DC4F9D4
-:106370000CECB7D3D1EFDC31C8EC22FB21D457A60B
-:1063800063B0AF44C703833E1B8CE71B9B400E7179
-:106390007E750E1C9CC0CE231F3DE9F99EE8B928EE
-:1063A000D8B797F434333C37027A6EC7FB2FBDA5BC
-:1063B000674F7AB227FD786233A7B353D8A7B1E805
-:1063C000DC3E09E65D1439BE475565396603F97947
-:1063D00087467FDC9746D0FF52BB9BEA3FB7EFADC5
-:1063E00001ADD04F67E385098C9FE7905DD7F1A49D
-:1063F000B0DBDD99321F5BFB125C0DCE734FBE3EEE
-:1064000000F7C9B76106E6D993F145BF5253BAE028
-:10641000F5F61C3ED6B8767FCBF9D99EAACDCF969D
-:1064200001284F9F093D10737C3DC9298E0FE05C08
-:10643000A5F0F16D3016FD0EF54C787CA3537A353E
-:10644000BEAA04335346007E0EB3992530B643F5F9
-:106450001D54691FE7690DA09F625FBC673DB0A432
-:10646000CA79E6E5901BDBC9FE8C15F536976C3FC3
-:1064700025BA64FB29C315693F751E7AC8E903FC78
-:1064800056A51B5C2747E13AE715EB1C5F5735FC27
-:106490002A1AB25C76098E9CEFAC550A1B489EDC2A
-:1064A00009B3A39C9769E9AA74B3EB24AC5767EAD4
-:1064B0007312B0DF337EAB8BAFAF2E17EF37DD1526
-:1064C000B9BEAE5C1347F535FC62C1FD67E3C75842
-:1064D000237BD78AEB2294E5C4AE1F939FEA2766FD
-:1064E0003A976E367D86F6BB2D57B3DF55CA6B7073
-:1064F000AB1A8C01CB08FCBE4BEA0FDAB9B5336698
-:106500006C175B6E54764AE327F0DF8A07EFB46FAF
-:10651000B5129F7D003101E0B5ABF61A94AB132A9A
-:106520009FCF55424E2BACAD669F9BC8DD82F2BC1F
-:10653000682CD326CCDCB7404F7FF0A289EE69B13E
-:10654000AF007A7ED7558125ACC8894ECF458D2BBB
-:1065500066E0BAFD8141DB0FD7E6E3B8CF314321D6
-:10656000EAA573EC8FCE5111F3758889FB63580D42
-:10657000DFE704E01F8E6F69ADBCEF595627E74B8C
-:10658000D9AC54D4B7A55B4C2C08B82FC77D933633
-:106590006ED0BF1926EED758C6AA37E03EFD5E136F
-:1065A000F7F72C72313513F0AAF88F5FE6A3DFC737
-:1065B00063E27687769EBC3C89E35D3E3B68F642AB
-:1065C000FD771B47CD018D0BED831BC8FE29669E11
-:1065D0009DAC3BDD17D7C8F8F584BF1E5FCD0EEA32
-:1065E00076AE2DF048AE57BCC1287AEE329322F633
-:1065F0007F7C7ECC36C9FE9C7926D9EFA3C9814920
-:10660000C8C109D577B5690CE73BF251513BCCBE07
-:10661000887AE6AE7AB3CF57CF82F58C546F9E2935
-:1066200005EB754CA3FD3103791ADA55CFD605EF8A
-:10663000460E4FAE57F11F8F3D15007929FFED3DF6
-:106640004E06EBE6076A6DAA07BEAFDC799BD30B5B
-:10665000E96935E0447E7E10341646A3C796303D86
-:10666000BC7605FD69423E594D80FC149FED34B95E
-:10667000C8CF5F6F0959404E2B1B97CF60C3297F4E
-:106680009CE7377E64C47C93CCAFF25FDF93EAE68D
-:10669000F76CB83F8985C8CEADDCF1DE345C2FAA3B
-:1066A0005807C999BE1DF6FF7912CDEB85E684EE39
-:1066B000E58027F913AAC42CAB6AFCF9474627E604
-:1066C00065F92813F62AD209F7F9B7991CC9A7E288
-:1066D000217B09BB04E7B9460F16E476EBFA47EED7
-:1066E0001B7E1CF039BBE345A73234523F7039EBB7
-:1066F0006C58FC2BAB21B61E6903398CB48F00306B
-:10670000B57337097BBB99A72B4D2127DE6759B994
-:10671000CDE40109642B1F3332BC07C0DEB004D1C5
-:106720002FBAE2B1E75F1B0F745FB1DB943C830FBC
-:10673000C7AEA476F1A50AFEB726AF8B0FE54F3C96
-:106740006F760FE3DF6F49EAE2C78ADDFBCD6C5855
-:1067500077FA4D6ED86F6EB547E14BC3F169B8CE8D
-:10676000AE7FE4AF66F4277EB04F616959DDDB97F9
-:106770006D7B9ED63BA413F151F029CCB76EFC0A79
-:10678000CD7C6634D573A11E8CC5AF6542EF823CCB
-:106790003FFE0CDEFF79D3E2C1F1973D7E9313C734
-:1067A000F1BE5ACDE5FA97B7A5E2FC2E3305525D4E
-:1067B00094F2EF650FFE88E46DD9911FA592BDC0DC
-:1067C000BC1906D2C5810C1CDFD2ADD7D2F84A99CC
-:1067D0008FE4AEEC97C622BC8FF8A9CA0A77479916
-:1067E00017716685F0797F3B183230BEF7717F896B
-:1067F000FAEC8F46BA17C5D80FE9DED88FC45861B6
-:10680000E5A3FCA756CEA7E3424FE24496E475C742
-:10681000C616E4CF99FEDE343CE7003A0404BD948A
-:106820006F00AEF1C8D434CE1FE656F3453BD0EF2F
-:1068300093F13BD66F31796DC3A576421FF2FE57B7
-:106840008BFE01EF385CAFDE4F8D6EEF8D11E38371
-:10685000BF1616215F11F39BCFF71D9BF8FCD6E600
-:106860007BB0B810CB3F7995CF1F6C87EB03E01559
-:106870004AA3F2FDB315D207B0AF8E36AF7798C4F6
-:10688000BC96CBC152A4F51EF0569584483901F848
-:1068900049447FDA07976E817611F65715F647F56A
-:1068A000CC5DDF23D68765420F98CC30FF2FEE9A60
-:1068B000FF6C2B9FF73DD9932B4DC1871FC0F9FA71
-:1068C00086C51370E37C3515E1B83FDC75E0B5EBA8
-:1068D00040AE3F6CD0E6A9AC3FF5F3B46CCF1816D0
-:1068E0006D9E7E6887FD55B4790ADFA3CE537B2B5E
-:1068F000C9F1F7AD3F35BA0D35CB7A13F5E033EE7C
-:10690000D8F4D3EBC1DF9BDC4447BD1E84BF57598D
-:106910007E77B9D3E44D93B3F2DF545C80FA262C32
-:106920008F9ABC85E5519337FD3865BAE9CBFF2ACC
-:10693000F4CDF5D6C26BD02EB67630DAAF14CC36A5
-:1069400006719F6CFD84D17C9F74433CE5E71A5B24
-:106950009F409BEFAD8AB9C3701DBF9E054CFCDC08
-:10696000BCD64476EA57DF7C3311C6739DA0EBF5A5
-:1069700040E6AB800F25AA128A033CE7A92C909031
-:1069800084FE62859D88C0E3FA32398F7F97A576B1
-:10699000C1E9A9FEB7B5ABBF6B7AC4CFCFAEFE8459
-:1069A00029ED2FC0708E90A3E2667E4E51355A09B4
-:1069B00066D3FC6B558B22F6098F99B99D7164CA19
-:1069C0003563907E05738725907CD70EA17D6095F9
-:1069D000D05B9D017702EAF3CEE61CDAF7751E5A0A
-:1069E000ECF045D15F07849C3D2FCE59DAED4AADDE
-:1069F00011E4BD9D7590DD12B0DBA2FADDEACC0694
-:106A000061EF08BEC19F11FA2F1172380F9A26E468
-:106A100045F06DF6551FA8CEEE7CC0BF1311FB8666
-:106A20007F94BE28D748DF03B6D6694551FC338F23
-:106A30000A7D7DD9B35F98719D9BD25CA0221DA772
-:106A4000D88D92BF63BB365F87B2A188D765CF2E42
-:106A5000BF630CC871D521A3C706E3AB6AFEC8ECBF
-:106A60008BB27FD3D313E1A3FDD86AE6F6F151537D
-:106A7000D152A4EBD16BF979EE9FCC9E8A6878CE87
-:106A8000B6723CE7B1A24F472BFF7AF42D98EB0882
-:106A90004D027A74DAF9FDE4EEF2C7E77DA74B09FF
-:106AA000AE55500E8D3C9FCCEFFF4E63BE3B262A69
-:106AB00034DF2F8FD45F054DC58FE17D96CA66C543
-:106AC0006580F24AB5D58C725CD5B45B45BBFC07DA
-:106AD0006EFECE82A9D5C36647F8B75ACDDC9F7447
-:106AE000E06FD7CD47FA7E3CDBC2102FEFD08F9CF2
-:106AF000B8DE7FDC3C8AE641AC71FDC1EFB9660AC5
-:106B0000FAE3CD5C9FE9E5615A72BC94BF7632EB43
-:106B100087E7BC97595A6FF244E1DF3A0B9FA7BD54
-:106B2000D66FD6FF61FA6D22E8372ED7A648FD361C
-:106B3000DDC2E53E42BFA545D36FABD6BAD3502EDA
-:106B400056EDCD4943BEAE3ABC34259A7E7B41EC2E
-:106B50006B0F8B7BD2EDFD40BF8D88D06FFD40BFAA
-:106B600045F1838FB66876670FFACDFADF33FF5EA3
-:106B700040FD1665BC5708B9D3F45B61F35AD26F78
-:106B800085FD8CD27DA4CB2CC28E8BA9DF16DE7343
-:106B90002DE54D9EF828F2837445FD7658E839ECD2
-:106BA00007F5DCCF2CDF4ECFCDB3727C7BD473FFE7
-:106BB0004D74D6F4DCAAFE0AD92FDDE590EBB95569
-:106BC000595CCFADDACBF5DCAA415CCFE9F5DBA4AB
-:106BD0006EFA8DB7AFCC85F6B44FCCBAEF06BCCF0A
-:106BE0005762F258A1FE0CB7F6BEA07A4CA4BEFBC9
-:106BF000992586BEF380BEB3F7ACEF5E417DA792C8
-:106C00001E1B88F3482F1FD307C64BF7D58E7E7106
-:106C1000EA37BFC5F9F20723DD077ADDC0F743FB8A
-:106C2000BE38350AE7DDCB880FCC979D42FEDAFCF3
-:106C300063499F4E1ECAE77BC5A1385A272A1B15F8
-:106C40003EDE5B94A01BD781BF7D4EFBE4F97BF950
-:106C50003E79AE85D383FDD8C8DF4500091646C806
-:106C600043C9E7E5E4E72B519915EDD70587A67FE2
-:106C70008076EB82CF6BC8DE5D80DFF17EC5EED61D
-:106C80000D99D0EFFCE50AED3798B80FA1DD97B864
-:106C9000BE793FDD5FD1DF83D0F4F9FC6AF9FB02F6
-:106CA0009D5D7F408C13EC59A20B7BC518D53F77B7
-:106CB000404F0F0F1F7FC56A6E1F87E901F4712BCC
-:106CC000DDE9011C9DB130B56BFCF39F8471257724
-:106CD0008D4BA3877E7CDAFE6481981BB1C6ABD155
-:106CE000AFDB78357AEAC6FDBC45D84517B36138C5
-:106CF000CF5E37F8EE188372F17B183FE03367DE22
-:106D0000A0B4483DFCA2D0E757F98E4F497523BD8A
-:106D1000F8FBBBEBCA763F9F0AE3B8DA9B9587572F
-:106D200011AEFD9BD9877E8403B60ED26B9A5C5D53
-:106D300068E572FE7701E7685FD7145A3F9A141727
-:106D4000CD97904E6F897B6155404F9C8F554D621A
-:106D5000BD0179C3F9364D5B7F90FEF09F573573C7
-:106D6000FA57552B44FF99ACE320D2B73259F1843E
-:106D700000D4B4A6DDB7E13DAA176CF01DE76D990C
-:106D8000E2D9CEC961CF488D2A976A34B964D54318
-:106D9000C8AFA0AD830BB05E12BE17793D05ED13F1
-:106DA000BDBD7199A5E528E271D98F4D6C1BEB6EC5
-:106DB0007F68FCCE857FDF44BBCFD383FC0E12F609
-:106DC000E50B486F3BD2B5C38C725F15E2EB86567C
-:106DD0005EA5BAA7107D347A37C1BA309AD31BDFCB
-:106DE0007DE9E979B5964779C6FACD8A09DB5F096D
-:106DF0007CE80345930D5F1CD4E417DF89E9E98241
-:106E0000FBFF8C88F98E7A29F2DCB1B2E908D165F2
-:106E1000FA6A30AB22E88EFAEA7CF4E9361F9AF679
-:106E200047BD07F56DE7C38556793EECB375BC38B1
-:106E300002FD5B7B15D207AC3951DADF5F61E5FB00
-:106E4000A603361FC96DC76113DDF7D6EB8DB1827E
-:106E5000FEB89F887C0737190782E7BB2E1B7B573C
-:106E6000C3239BCB4FA4BE7EC1E6233EC5823F4DCC
-:106E7000C08F652F85F1C5FEF03CC52DF7A75F2FAC
-:106E8000343F4F4FE3BA46ACF7DF755CE1F349D6C8
-:106E90006266DC9FBFDB1C71CE3447F8F9353F5882
-:106EA00044BD999631B1EBA1BF2504E37E61D74380
-:106EB000E4D73DF7E8F19928B72B7E676456E07375
-:106EC000DB2E070BF17B14665C57CB1B8D51CF4536
-:106ED000185B4FF8ADF8AD83F44AF91E4B7006B459
-:106EE0002F7FEADDE1E89F6A5BC7F54BE051211F88
-:106EF00081D6E1785E5EAEF2F3623DBC1F0B79395C
-:106F0000FB747C09EA47A59EBFEB2C6F986BB244DB
-:106F1000ECCB2BF1C08DD7A37BC8814714F28377CC
-:106F2000C76F2DAFF708D77BE54DA620BE0F2DAF5D
-:106F3000DF46FBD9AAFA8FCC68C74DFEED636447E4
-:106F4000543519653F61BD3164213FA6F138A67AF9
-:106F50007F5D656305CDC7CA06E10FD3F98B56FC8B
-:106F600076EF530120CD8A277EED443D73A665A7B9
-:106F700093FC70F5DCCFA6DAD5E87EB89EFC6F0DE9
-:106F80009BA2FADFCEE07FC0FCDB6A95FD6FACBE52
-:106F90004FAFCEC1573CF6E983782E7476CF870F7A
-:106FA00022DE2BBFFEF8C19FA27DB2CFE6C2F5AEB6
-:106FB000EAD1A3E457D7DA3D25E655DB23BF7EF8B7
-:106FC00001987F6D6F58E8FE55DBDEF707B8619CCE
-:106FD0006DBBBF4845FFE5EABD5369DFB2FAC9C9D9
-:106FE00069E7BB47827219ECC579889E0F071A8D35
-:106FF0000CDF419E3B66213B23EC476DA8E07E6998
-:10700000B7F09FEE8A7EEEA4F9FD2A1BAFB9FA52C3
-:107010005CF71A4D1E377D177EC09EFCA6AF023F5F
-:1070200047F4826FBB845F5CC7B773F81FC09F3F94
-:1070300059657FF3A78D4B7FF5009635F689E937C3
-:107040000DF5825EDAB9D636ABF71D2BCE873DBF84
-:1070500021FF34F20B6C6ED6F6D8A703D0DF70DABE
-:10706000D47123DDBFD86BA17B42E57B5FA7F9D14B
-:10707000F6E4113A2F62E25CA98D85FFF83980D8D9
-:10708000CB54ED70707FABA03BFA63DD4EFA2EFC63
-:10709000AE5C6E357F6C2C3F6C1F9BB8072ECED933
-:1070A0002A76BC65663ABFB63216F9745C3A17D4D4
-:1070B000C6AD87E7423A5C12799E10CBCF2DF468BB
-:1070C000984FFC1CA16D9B385F089F1B30D62F0F7B
-:1070D000EFBFF3F3EEAAA0F23A8B321FB5F304A789
-:1070E0004D371F83BD3B47E819DFEF460FC5C6F795
-:1070F000AD1A5DCE7E155D1F0FB129E2FD812FD740
-:1071000016B1EE2C10EB4925D08BBF27E3F89E1566
-:10711000FBBBB38F1A83B80FDED07080F4AA7E5EFB
-:1071200057B2E8F143C6DBB83EA96CDA3F1CF5CF95
-:10713000D9679F26B9ABDC75DC1C003807EB9F30A4
-:10714000B70EED9273D4D7C1087D7DF6F1FDC3F97A
-:107150003907DF47EAE15F21E05735CBF0AB767DB9
-:1071600024C15F116830BBEC3DF77346F5CEC5F125
-:107170009E6931515C94330DC6C268F14A86622023
-:10718000A9942E3A6D70F0F771C62433D991AB1DD6
-:10719000638F2524636A76E33E7AFD5A7E1F72FD73
-:1071A000CF3CE9C897F58973E81CA856474757B202
-:1071B000AB00F7D7AE2945A351ACF47A20D16B9040
-:1071C000F05EED284CC3F7DCB70A7B84A91E7ABFBA
-:1071D00067744E2BC471185D06972DEA3ACAE1997F
-:1071E000EC45142FC2E492DFD37DEFF11FDCFDE408
-:1071F000F80F817EFF68FC07467130FEDFC77F080D
-:10720000603FFF02F11F42E4B7D1E23F247FCFF19C
-:107210001FD63239FE83E06738FE83E0E7FFC67F82
-:10722000F8FF2BFE8331EEEF53303E8316FF21250E
-:10723000CE3C3532FEC38571095323E33F8C8B4B23
-:107240009F1A19FFE10771595323E33FCC8FBB68A5
-:107250006A64FC87AAB8515323E33FAC8D9B4879FD
-:107260002DFEC3DD7153A7CAF11F664E9D02F9B60C
-:1072700038DFDF71BD8A15FFE13D9C2C637A8EFFFC
-:107280000070CC716362C77FD0C38915FF01E02411
-:10729000109C18F11FBAE11323FE03C049273831AF
-:1072A000E23F74C32746FC078093457062C47FD0D9
-:1072B000C38915FF01E05C1497123BFE831E4EACA0
-:1072C000F80F006714E11323FE43377C62C47F008C
-:1072D0003813094E8CF80FDDF08911FF01E04CA541
-:1072E00071C588FFA087132BFE03C09949F8C48895
-:1072F000FFA087132BFE03C0994BF8C488FFD00D65
-:107300009F18F11F008E8FF08911FFA11B3E31E203
-:107310003F009CE5042746FC073D9C58F11F00CE2A
-:107320002A821323FE831E4EACF80F00E7A7042722
-:1073300046FC876EF8C488FF00706E253831E23F46
-:1073400074C32746FC07807307C18911FF410F27CB
-:1073500056FC0780732FC18911FF410F2756FC0788
-:1073600080F32B821323FE43377C62C47F0038F501
-:10737000248731E23F74C3E7BBC67FB085062A3954
-:1073800014FF81E24486E33F247FEBF80FCD88EFC2
-:10739000FFC67FF89F19FFE166BBEFEB38F2837EF3
-:1073A000B7F80FB6F86F17FFE1667B517C3CEE2F04
-:1073B000BF65FC87D4F86F17FF01FA498F1F13BB15
-:1073C0009F58F11F7274FDF414FF01FA1974DEF175
-:1073D000C488FFE0D1D1EDFB8AFFF045DCF9E33F43
-:1073E000FCCBC559806D0A9EFF149328B27F99B8D3
-:1073F0000BD7C6FF93E32E90B1F0AF1477417BBF5C
-:10740000DF60C2F5EA4DC1F7D7845CBC25E22F1CD2
-:107410008B197F217815F94597CBF117A60B3ECE36
-:10742000F3C9F2309DF1F386E953B278BCCC325DFA
-:10743000FC855CF9FC7A86EFC81400C7AEF2C8E39D
-:107440003822E46166C947CF217BAE1E1B3DFEC2D8
-:107450002CC18F621D5DA60BBE158BF47A7C920247
-:10746000F23CA3EC888A749DE96E55C9AFFD038D8B
-:107470007F6E897FB3055C3DBEB304FF665DC9F9CD
-:10748000A7C7FB55E49F13D2B251C43F3DDE7A3CFF
-:10749000F5FC6791FC8E889B51C0E4B80B93AD72EC
-:1074A000DC85A92E39EEC215E972DC852BDD72DC94
-:1074B000851FE4CA7117AEF2C87117AE1E2BC75DE7
-:1074C00028F6AED5C57DD8A48BFB70972EEEC3FDF4
-:1074D000BAB80FDB74711F1ED1C57DD8AD8BFBF020
-:1074E000B42EEEC37E29BFB8E6B0547F69ED1129F2
-:1074F000BFACEE0DA9FEF2E071A97C45FD07527903
-:1075000045C34752BEAAE90BA97E6FE33EBC2ADE03
-:1075100003BF26DE031F13EF81DF8C11F7E1AF3FBE
-:10752000FFE2B6C8F7F85FFEFC9BDBF03DBE41BC56
-:10753000838D15F7215C1E23EE4357FB6F1FF72148
-:1075400025F99FFF0E3FC7CECF3727C44FCAB1A73B
-:107550007CF777F8D716C9EF99E796C8EF9973ECDF
-:107560005C9FCFF3C9EF9AAF2F93DF3597D97CD9C2
-:1075700088873EEEC384786F8E1DF5A5789F1FC265
-:10758000F7A9B0363E8BEF53217D0EE33E407A10D3
-:10759000E33E407A08E33E40FA7B8CFB00E94B185F
-:1075A000F701D29731EE838A712302226E448D88CF
-:1075B0001B512BE246D489B811411137A25EC48D0C
-:1075C000681071239A44DC8810C139E13F44E949CD
-:1075D0007F0BA5A7FCC7283DED6FA5F48CFF34A554
-:1075E00067FD1D94B6F93FA7B4B7712334B9FC33D6
-:1075F000DA0D66EC9FCBB126A733EC033744CA699A
-:1076000091FDA20D28A7B1E245CC459AA6C48E17DC
-:10761000112E8F112FA2AB7DEC781169A3BFBF781B
-:1076200011FF16CFE5F51F8D1731BF5A8E67B06079
-:10763000CDF9E34594D98A56A35C6AF2F86FF1FC60
-:10764000BCAAA77811DBEC8A58AF812E6877015D60
-:1076500068BDEEE1BDFD738E8773713FD1997BD11B
-:1076600079E31CE8E52236BD795C83EBBEE738118F
-:107670003DD155ABFF66398F5FF06FF1E78F5FD07B
-:107680002D4E444FF105067D467AB2B771227A5AE3
-:10769000177AA2E7ACEF394E444F7AB5277DFAC787
-:1076A000E99CCE13E2CF1F8F231C17CEDA72901AFB
-:1076B000BBBC34B555F10EBC60B68BFC27EDBBC42A
-:1076C000BD312F73BB52F93B75B437DBF7240C6720
-:1076D000F47EDDC5BCC09F78F15DD9B57F3F9EA724
-:1076E000DFEA64DEC4248A07EF36E6E03E6CA415C8
-:1076F000FD29158D1FBDFC3B806B6B36D27DB276AC
-:10770000C0A185EC3E6F22F22D9EDD4EFB743CE362
-:10771000FAA64FE47B66DDEF37609588F39BA946B8
-:107720003BED9B3AB7F27B9E4676F17D1347D37DC6
-:107730006A167413FFC84E5D21F0ECC414EBFBAC69
-:10774000643F2E3BFC447E88F1F3CA48BF419F4210
-:10775000D94F5367730EC777952CE06D41FB7B893A
-:1077600080975224FB6F3E5C547808CFE997F84A23
-:10777000E91E425A89ECCF61E2DD386EC7C2F7E5F7
-:10778000009FD226853DA0747F475ED67CD706DC5D
-:10779000E72C0FEAED6F968B7256CEE23CB8EF5DA8
-:1077A000512F973B1CE23E879DD97B45B7D60BEF07
-:1077B0009B987C5EBA7942587F9783EEC32E3BBC80
-:1077C000D88CCCB2A4CB74B3B965BAC5E7CAF4D12E
-:1077D000D3CFE191E9A3A75FC258D9FFA5D14FBB91
-:1077E0006FA832715F34C8EF91767B87DFB48DF07C
-:1077F000D4D34F4FAF510E714FA28B5E45D654522A
-:10780000F98467861A22F9D6CF874C7B48C1FFEEF0
-:107810009F1C5C4BAD3C0E15F5563A07CD9425BC2C
-:107820005D3CCE078C2BCB3C341F70478FFEDD7840
-:10783000F66721F7EFB26F20BDA9F8B9E38BA0740A
-:107840002BCADB08FEFB0BE4AFD27E3781795CB834
-:107850008F6AF05BDD4B543C1764EE2503F13CD09E
-:1078600045E99DE2DD6FFB5046FBFE86D027A978F7
-:107870008E76675EC74CF43F542D6545B87EFDC8D3
-:10788000C9DF5D6C12E90827F7CF6C2E3230EF6844
-:10789000FC1D1E635041BFABCB7BF872B4479B4DC0
-:1078A0006E7A47ECEA78F97A2A1F45EFA3330CB5D4
-:1078B00023111FA84FEF6BDB9BDF752E8ED0C36D9E
-:1078C0004D770FC1FBC5F71BA2BFEB2D7568EFDB32
-:1078D000F8FD8E115D71064A1D63281EC19DD9D029
-:1078E0004F657127F15193CB0982FECF954E27FC4E
-:1078F0009E6C56DCE8AF9B66BCE107C300BF7147D6
-:1079000055AEBFC4BDEED1A2FED3CC938EF88EBBD4
-:107910009429387FC6BDC13C0124717529DDA7FBC0
-:107920009D73DA21E4D7946690279C0F67ED1EBC07
-:107930002A3FA645BE2F9738C57700EF175E728C99
-:10794000913EBBE498AABF1F63C4FDFEB856F9FB85
-:1079500004DDFE739D26774E968A72B7E52B23E1F0
-:10796000D5DEC13CEB006EFB92BE746EDBFE0923DC
-:107970003BB1FD2B6361B4FB25773BB8DFEB7E3376
-:1079800023FD7D7FA99DDE393C5B5A7E01DA179F7E
-:10799000FDC47741343F65849D96C0DF9F7B13D83B
-:1079A0005894C35B154EEFDA8CA228EB9626779A93
-:1079B0001C6AF297511AE78B765F33D9C9EDA34958
-:1079C000A5B98A19E5679FC290AE6DEB00AFF3AC25
-:1079D000DB01B62E13F1A96AFA98EE61599B95A8BE
-:1079E000BFCBF384C3C9EF03AE0BACC5FB1737C3E2
-:1079F00024423D9561AECD8A063FC0B6905DFA80C7
-:107A0000C3CDDF0D58451C21B53603EF23B4354DEA
-:107A1000BE7203E0F900CC07E4EFFD260FE11DA8DC
-:107A2000608CEE930A7F5DBF996CDBE608FB77AF55
-:107A3000A3E030CAED6107B71BFBF83C0AE2EDF9A1
-:107A4000FB5F9D08BFFD730BF1AFAFB037B5762775
-:107A50001D9C3E254EEF016CCFCA9249F9787C4EB1
-:107A6000F7923EE837077A47B1AFB4753DC9C7E82A
-:107A70007C22C96E089272F27ADD2EE9BE7780E62A
-:107A80008D360F584861F85E5FD36F4AB31272802B
-:107A9000DC8FB6DA4378FF2CA90CC69D8CF13CAC88
-:107AA0001C5E8B7A56F66B813CE6A371CFE8BD3F36
-:107AB0003A5211BEA6F7347D796B22D747B7DEA5BF
-:107AC000523CD0AD6AAB0DFDA9595EF7240C4D9325
-:107AD000A4BAE95E4AFF323E0FE3737E9918B603FB
-:107AE00060928FFCDAB820DA7BA60C94A714A497D6
-:107AF000EF4307A4C30F753C8BE682C7C6FAF0FBC1
-:107B000053424F08BB669A58EFC6BD67E0EF284363
-:107B100097B3C8F7457A3D0172FF27FCFD9EFBDF56
-:107B200053294E68583F944EA3F58919871E403952
-:107B30009BF022E3C751423FB8E01FD2E792977C07
-:107B4000EB118DEFAA17F4FC66216B388F3FCD3611
-:107B5000EA10CCB7C875D629D67BA1476E2A1EB8C5
-:107B60001EE797264717DCE231FA22E8A86F1FF6D6
-:107B7000532AD6F077770EEA91978C783FACBD0008
-:107B8000F80D747912E70BD03BF193E095C8F72D0F
-:107B9000CD57D850BE6F0D4D72CD803689D622623A
-:107BA0005E22F3923F270FA8837122D69350C07EA6
-:107BB0005D2DCA72A6E03DAE42C9DFA3FD2E1E0CAC
-:107BC00094F812E603C871E43D564D3EF5F2A8C99B
-:107BD000EF7ADC60E1F91D7ACC21352A0DC4200B47
-:107BE000DBEA423DABD997EBC3F65C22ED33560B93
-:107BF000BB68BD7D9A95D4C0FE645ACF57E3FA04A2
-:107C0000E35F9DC2681E68E3D0CB63D5E706168CA0
-:107C1000D81F54A91D748FAFEA73330BF6C171FBE3
-:107C200026E1B835BA8C1474D1D321DB29F69B82B6
-:107C30001EB1F1CC77E1FDD944AB976D243C27D13F
-:107C40003DE786509E15D7DBDB7478F602BF39D14D
-:107C5000F053ED31F013F1DB2630DFEF5A415EF3E4
-:107C60006FAACBE0EB057B353D827FFA7933B6A96D
-:107C7000FA803962BE687E5DFD3C19D1CCAE41BA56
-:107C80008F0BA90CCF5F7B9A2F9F88F156C5737A13
-:107C9000B5CFE9188CF2B943F5553BC9BE683560DC
-:107CA000DCDFF6A719CD67CFFE934E8A6FD4D2BB27
-:107CB000FBE99A1DA5D94FFA7A9AFDA4E95DED7EFC
-:107CC000F876A7CF8FFD2B4D209F30FEF52EBE2FCF
-:107CD000DAEBF0ADC3EFF130063C4A62B9A12CFEFD
-:107CE000FE5596FF58F21EAF93E706A013FD4E1601
-:107CF000E8FF414A773CB4FEA73813F9790BCC660C
-:107D0000D443FDF219EFAC92D1FDC97EC3990FD7D0
-:107D1000A77E79FCDE5F50ACDBDB84BED5D2BD8EA6
-:107D2000A2FB117F93CA0296BCEF8E37A28AF7B1ED
-:107D3000B73BBDF7A1FC590BBD348E4C17F3A0FD2A
-:107D400099A93628F86E3269A55BE1F7B059D73B9F
-:107D500026809739C35D80729289FB68ACDF1C3D39
-:107D60008ED6134E9364677A58384ED513D82FD8D1
-:107D70009907CD80779F195ADC2BEDDCC6A3209D97
-:107D8000DA1C7308E9B64F156E8F27727AE9F7038C
-:107D90004878C44F15F9DBCC4CB525B1AEDFE134E2
-:107DA00058C98E8F679E06D44B2F3BB3C5B9A8A781
-:107DB00006F3FFAE7658138776C9F19D13677954A1
-:107DC000A8E2BCB47338EE99409E0F23BE6D133BFE
-:107DD00007DF4AC4E818C0E5C66B94E2E268F46FB6
-:107DE0003249F4B7E13E3B520F3ACCB48F6C53E2C8
-:107DF0003C38CFDA962B1C4FC52AE206A9F2FE5F6B
-:107E0000E8234DBF763AB308FF7816A07D00B37A19
-:107E1000AC748F5DE08F7115C9AFB3373EB81DCF1D
-:107E2000A3747114F57116272FB6D3BD8B2D7B6DFE
-:107E3000B42FED2CE2E7F39DCD16D2BFB1E6691A5F
-:107E40002A83F3C40B04BA7520DDD24CD589A8F778
-:107E5000D2E6F3F9AFA7473B0E14F73B7F3005A3FB
-:107E6000BD57D7D2F4F4BEC56897A567A453AA7DC1
-:107E7000AFB3AB51EF611B1314294EDF10E851EC87
-:107E8000738C09F0FD9CEF8FAF7959D7BDF6BA38E6
-:107E90004EBF4EDFF8848751AE40E0E8F704B4737C
-:107EA0004DB19FD7E22769FD6CF15B8B31E467DD53
-:107EB000A2E9365C075298F7CA793829B798D84EA4
-:107EC0006A972BDD77BDD73FB218DF276726F07B97
-:107ED000B49F6C994AEF9953D93ADB60A0436991FA
-:107EE000C183FE80738BDE741A407E1665B6E4A3F0
-:107EF0009C26987C990963C87545FB8D6525E660CD
-:107F000008E8955C070A81E818B892E8B8D010D55F
-:107F10003F9C9DC0F79D6F89F5243D7D40F19251B6
-:107F200091F97E44574D8E60FE642C19DD150F13B8
-:107F3000F87951429479D06E624DF85E42D347C9C8
-:107F400042CC347DA8C97132CE0FB4E38A403F4998
-:107F5000E77D5035B5EBF70C95E617BE403BD6797B
-:107F6000E924D237306F6B48CE73B9FEB4A13E8B93
-:107F7000F05BB5EF7DBD3FBE637AFB671F3BF05DF5
-:107F8000CB5FD40E07EAAFD3B7FCC98171C0DEBEA8
-:107F900085EF936FD4D9FF5709F90826144D41BADC
-:107FA0002EF0FF3D3FD25E636BB8FF7979507EBF04
-:107FB0008AF7BF23FD80150DFAFB00011EA74CFCBC
-:107FC0003EA79E0FEB041F96EFDA66CE7463FFBEEA
-:107FD00039D8FF69B1BF39DDE8A0F7141A3E8B76B6
-:107FE0008D34A3CDFF97668B78A7D762E27AD93B11
-:107FF00003DFE7F804DDF4781EDC174FF096DEC3EC
-:10800000DFAF2E84BED6805EF435F3384AFA712C89
-:108010007DDB3D0DFDE84B3729B48FC3FAB7C03A7D
-:10802000E15BB391DEF1E8C7B93020FB73F4F11ADC
-:10803000B5FDC032C1FF25F86BBC3951E23836F3CB
-:10804000F774CB74F645E7A19C781CFF9A0461672E
-:10805000E7B34B306EE79E43D909D1E26168E95935
-:1080600071DE8FF7FA313DED67944E4970F3785D1C
-:10807000CD476E46B9AA6CDA4DF111F705DFEB3347
-:108080001EAA14347F6144A12A10F6D87C618FEDBA
-:10809000615C6EC08EDE8CF27FF9E73A3B5A8CF35E
-:1080A000064DEE0F2591DCDC80E31A8EDFD54FA262
-:1080B0008DEBEE04F9FD576FC7A58D471B9F565EEC
-:1080C00021DE9FEBDB69723E45C8DD921DC51BFAC0
-:1080D0000229D6EF7D7F8088234771B63439D2CB11
-:1080E000C932C1B7B03C34DF41E3D2F806F29E2E6C
-:1080F000DE25A5A33FA327B9D0F3BFCDD43A00E72F
-:10810000AB9EFF6D31CE7DB627F0738D256EEF34BB
-:10811000F4AF8079B8C115613F9C566B0FFE14E730
-:10812000D10E2EC791EB22194B2F9A689D5DE570F9
-:10813000A725DA05DFC6E1FB454B00EB69FD9CF2A4
-:10814000D7CC1A48E78DB5B3060EA4771B946AE521
-:10815000A5F77FEC44FBB43D97917FA1CD21E37B54
-:1081600004179B319872FAAF545BBE7E0B75D08EAC
-:10817000168ADF7AEA2BE19FF8CA52186D9C6713C2
-:10818000B81DA8DD3FB951CCA31B9BF97BBB455B58
-:108190008BCDE4075823DFD77849714DCB84A6BE39
-:1081A000869166E4B39E1F4B3D57D03BF06E7C61D9
-:1081B000B7135F97EADFB5897B4C0B847CCC74B92D
-:1081C000859DE6A377C44BEA8C64DF2F7357D3FEFB
-:1081D00066851AFD3DD61897E1BCE3D18F6361A394
-:1081E000427A4F8FFFB21D6B37F465387E3EBEEE8C
-:1081F000E308F5233D23C6C95A2FE7EF32C5BAFD80
-:108200005FB8D1C6A4008000000000001F8B0800EA
-:1082100000000000000BB57C0D7854D5B5E83E7326
-:10822000CEFC24334926FF21413C21111212E29059
-:1082300084000171F24BC4080301826075405184CF
-:1082400090207A5BEFABB79990682DFA7AA358CB60
-:108250006DEDFD062BAD0A4880A08126E9041403CC
-:10826000040D820A96D68014B1053280B5587D8FF0
-:10827000B7D6DAFB64664E92426F5F87D69D7DCE9D
-:108280003EFBACBDFED7DA6B9F65ECD94B720E633B
-:108290000FB7CB8CE53356FBACEC65A98C2D63CACC
-:1082A000E9BE0C46BF6BA9F85F67E59204C6EEC550
-:1082B0003F5568DB57553278AE5CAE9985CFF56F88
-:1082C00090995982EB1EEF53C971D036498E4618EA
-:1082D000C71E379EEEB33066817FD746D33C8C25D0
-:1082E000E0FCFCD723B1A75260FEB38AFFBD08783B
-:1082F000EE2CC0E181799678F873F47EF8FF32C7EE
-:108300008C2F2478DFFDEDF229730E5E5D6D32C097
-:10831000F8A52F496C1D8CBFFF69DD78B12EFD3AA1
-:108320001EDAF0A3B9E91981710F7B9F0BE9C3DA5B
-:108330005456C0D87D023EF6EA7F05EE73F84DAE86
-:1083400008C632ED117167B3A05BC0265D4B63AC0C
-:10835000CE1A99C3A2A03533C2233B64F46E02B88F
-:10836000D644C08201CE355BA3BD1EC4E3EA68C615
-:1083700046C0B8F68D26B70DE6C4DFED8C9DAB6F19
-:108380009E9B9E0EEBAF7F7A6EBAC2D82CBB9DB17E
-:1083900089408FB6E7685CB7E29A6487FE2A4BDFB4
-:1083A0008FEF5683F03899D363995C696286C07CFD
-:1083B000FA7659B3F1CBBEA0751621FC56F86312BC
-:1083C000C02FFF3DF8D5C4685B006EFDBC7FAADFFF
-:1083D0001002F74A85395B6C81F568E326DA0DB443
-:1083E0001EFDF37A7A30E6A5717ABAAC443A04D12C
-:1083F00017E15400AF3D1D56EF5A89F888E0F67436
-:108400008411DC1793D6CD3D93C7D8617C00E0AED4
-:108410001DF132F55F515C6E7B3C5EF48F728DC74F
-:108420006762199B323CDE6046C6607C2ECE0FE34D
-:10843000768539F3988CD75DB1C807D31BFAAA2C7F
-:1084400040AA3AFBA40A05DE33FDB9BEAA30E83FD4
-:10845000629FCCFB9BFA8E5A1C8C35B02915A5F077
-:10846000FC63700FE7BB5E9B6F762D66C05735804F
-:10847000534B0CB4C7C6BC8DF256D35B5921454251
-:10848000CB984FCA057E7046FAAC39D4678530AEBA
-:1084900033CAFD1FB8BE55579B2EC938EE98C2E5AA
-:1084A000A53B8EF0A000EC61F05C53B853B503BE61
-:1084B0009A622C8EC654BAEE098BC1BE535583AE58
-:1084C0006BF4C0E7108E2603734643DB75604C5493
-:1084D0005FF6F078EBAA57AB14A0FFBEFA0C6AF572
-:1084E000F78B4CF674073C5F6460EE16DBE0FBAF85
-:1084F00022BF109DD414A4736DB789E41C7F12F0C1
-:10850000FD2AA1876A81405100CFAA63CC171E893A
-:10851000E3CABF50B06D95D8E910BE6281BE3C3C45
-:10852000DC37DAD6E27C4A309F703C152BA9554ADD
-:10853000D07B4B6D99217D39D19081EB6172B8630D
-:1085400013E0574E31ACDE01EB976F8616F0A1D8E1
-:108550001DF212689B4BA6CB4BA16D34B2852DD872
-:108560001AD8F2603C750879D2DA4B76D76F90EE64
-:1085700017DEEF2DB0929E1A6927F916EB6D941C49
-:108580003ED4439E2EE6D804D79A6417E37CDCC21F
-:10859000908F7F2FE671980D3B55E0D7F7EC0F12C7
-:1085A000FF3AA20C8FA642FFA3E615150AF0AF23EF
-:1085B000C570251578F478F34ADECF325C190DFDCD
-:1085C0004F9A6B787F2A4C99CCD8C9E655159E6C8A
-:1085D0009C97EB31B6C59985EF510C12C9A9B2D75A
-:1085E000E46D843F9B22393F3519812F6370BC4A6B
-:1085F000E39F6A28DE6C05FE578A9DEA6A1BC73531
-:10860000F2C3FFB4D5F0285B0DAB118FD822BECFDB
-:1086100088756B7460ADCEAC39A8175A9C5973231A
-:1086200010AFEECF11AF793DBDD3510FB77EF049FA
-:10863000813B9BD30BE7C9EB612C12D673E1AD9B59
-:1086400036CA52803E97EC45E7515F4BA0A61F8784
-:108650007549AA9DDD0372D7E864AA09D695C85E5C
-:10866000B2A3FD30207D4005B532AE5F3AA35C5F1A
-:10867000E2736CA48FEC4CB5DDF515BE5FD3CFACC7
-:108680003766483DACD757A69CC765067C1093D289
-:10869000767C29EAF3DF9A1DB7A8088F933D0E7008
-:1086A0006C333085C5107B642870DFCAC21DEB5067
-:1086B000DE1D2CC903F2856823E0E01707F6D028F9
-:1086C00064485B073C5FCAA09D8470DD4AEB9291D1
-:1086D0009F2630978C7AAB8079ADD8F677BC95849D
-:1086E000F87A3E8CDDE782D6F22A737A83F4467EEE
-:1086F000B444F89F1563A436DCD83217F934FC1261
-:10870000B3A31FD0FF0B9382F38360DC89D71DFBDB
-:108710000D0CE1FCB5D16B8F82BE3F53515F66817A
-:10872000F9FA059DB5799F37A999D1D0AF8A9108FB
-:108730002FBF2EE2F6D8FF85C9FB722AE2C7B2DA54
-:108740001B2457E3A3F9B8BAB8E2B1D1F07C4B4788
-:1087500038C3F74FEA0C3720FE376FC90D433ED8B8
-:1087600086B881F5C798ED8FE07C315700DE54BAAA
-:10877000EE24BC2AEA8428C06BE14C9BBA0EF0FEC2
-:10878000EBB09699C8F7FEAD06F632BC629BC931D4
-:1087900007FBDB2EAB76D4B3BF4E6D09A7F56C3566
-:1087A000D07AB685FBC7AD01B8D7652815089F629A
-:1087B000650AEA5FC550AC3E02D7A74573FDA8E93C
-:1087C000E39A6895FACF4BF0FE5C1C57447253262F
-:1087D000DB48DEFAFDCC6B86F7C4CFEB95911EE14A
-:1087E00073809590DF159FCC703E17121A5A9BD15B
-:1087F000AB929E75DA9600DDA70B3D3BFD644D25DF
-:108800008BC48EE3D854986F9FCDC8705DB7B13ECE
-:10881000D902FDDBAE32870FF9E7AA427E981DFE32
-:1088200005FB7B65629E5F494C898271455FAA0AA0
-:10883000F257110BF5DBCA36947F81F6ADC4A2BBAB
-:108840008EFE5C24B64AE03ACCB3285AF861A3D82D
-:10885000A86BA4CF60D6046147555C7FF67FE1BA70
-:10886000FA2B4C0E5CFF769BF3E3A9A8077B8D6C7B
-:10887000131B5E8E7E550F1A7D0C08C7D570E68DD2
-:10888000253EB421FDC76D68F684C17AC7A5F3F90A
-:1088900091DF506F8CFD455C2CEAED8868AE4FB4DB
-:1088A00056E32FE4237B14E723FBAD01F9FB5E7451
-:1088B0002A8DD3E409F90BE7D963F42E760D6117FD
-:1088C000812FBF877CB9DDC62A90CF9F1961598857
-:1088D000F2A4BD67B7E07B7DFB54C39A2E23AEFBA9
-:1088E0002FA0FF01EED2E4ABA660FBDD15C7E12DA2
-:1088F00093BF25BFFA62BB44FE7C423BD7D7C17C05
-:10890000316268BE7801F17A3DBED0C7011A5FECD2
-:10891000B81E5F74FF637CF18B68E1DF0ECB17DF5D
-:1089200046E2FA1FEB2849647FC78F69137C30DC6D
-:10893000FD2956AED7F4D7DB053E779B9AEFCC41A5
-:10894000B9BFCBE040B906AAA7CC05FBB23B9C3F20
-:10895000C794D569D8DFAE703DB2BDDD4C7A64BB3B
-:10896000CDED267B9D6461E82730C5DDF77DD47FA2
-:10897000C916755D10DF3E2EF4408BD137E573F4D8
-:108980007F0F70FA4EBE2B5736C1B8110F70B9CE9B
-:108990003F67DA28C33CD53145BE6818DF17CDEDF7
-:1089A00062DD1918057C597BC644FAEDADCE23E58E
-:1089B0004E1BF9374EE4AF497B8E941767E378CEB0
-:1089C00047DDA2D5FA53704D3164768E25017E5D68
-:1089D000C24E4C615C0FB9903F72027DE634523C4E
-:1089E000A6F1413563596827E6F639CA908DAA2A5F
-:1089F00042E95BED9B4971DFFCE3CEB20858D77CBE
-:108A000097EEBEA07FB58EFEE007FF01E564D5E6D8
-:108A1000DE4E1BF2ADCAED698B697516F77B56A762
-:108A2000A1FFAFC911FD004F2DBFCF78795D901D1B
-:108A30005763F83A9F752874DFD367F2DE0297FE1A
-:108A400037E3CFB5087BF3AD90E3DCC7DE588CFC91
-:108A50009BB7DCB90FF1BF284EA6EBFFC97C96345B
-:108A6000A48F4321FFABC5A8967C2E05C631C595C2
-:108A70006183FB7BE2C3F3F0FDD531EE6B4827A6A3
-:108A8000F8BBF1B94985B9792857B6094DB1687F66
-:108A900034B801AE8A4DB6001C1A5CE785FEA98E7B
-:108AA00059720DF180CFA15E693B75D682CF6B7490
-:108AB0006FE9B8C4E91D447FA47780FED27DD8D782
-:108AC000F06011ADD6FFE7E9EF1B89F41896FE18A8
-:108AD000F747FE8FE83F2A6608FA833F958ED73521
-:108AE0007FAAC5047E7576A0AFD1BDDA5E44E31CD3
-:108AF000265819FA4F9D1057A21CBAA3D1B9613B51
-:108B0000EDFC5DFDBF3F3B0A5C4036292686CB93DA
-:108B1000C93F06FD8D093E89FCBE0920F0F7909FF4
-:108B20003592F49D43E0879D95A4B319DC05BF966B
-:108B300082FE9F2F16E56082B9D287FCBEC33A3D04
-:108B400005FDB75CEBB434E4A737331E3B8426E75E
-:108B5000CDE4E53B5F51037E8EA6D7F68969B5F774
-:108B600097C770FADF0E6A16FD3D740D83E1D0F4ED
-:108B7000379205E1907CD5866B56D2C7ED7D80AFEC
-:108B8000DB110EC06B97C45A517F17199C7125E8F1
-:108B90008FC5FB14EED77D3D4A05BEA96C7FF73823
-:108BA000C25B69B1F930DFC21CC6F37D41F912BD69
-:108BB0009FABF9259ADFAFF92D5A7C89FE0DDECFE8
-:108BC000C7EB00BFDD0C00A2FDF159BC0DF0FEE7C4
-:108BD0002FAB994E21AF0AACA352AC6336EB25B84C
-:108BE000D8B7D7AE4D03FACC12F8A8EC86B8300748
-:108BF000EF337617E0E12E85C78B7739203E0CE204
-:108C0000A3D99343FBF89B9E1098E77AE3F5FA7F8C
-:108C1000AAC817FCB371A6D676831D3A0D0C70B0A6
-:108C20009EC73485A3658F82F1803BD380FC582793
-:108C3000EC1A84C943DB2321AF8586BE1C07E0B74D
-:108C40006BCF3764FFF6EEF9E623F4E7A67CA1309C
-:108C5000333C5FF8457E14EA07E60A9DB7EE8FAD18
-:108C600056C6AF13FFD48AB5EFAFC78C18C267A141
-:108C7000F637E79F5F8FF37D7946E1BC2DDE5F6EAF
-:108C800072A7DB6DD8F2787FBFC4FD1DEDFE7E2399
-:108C9000C00DD737C568717FAF42F919F89983E8DD
-:108CA0007C17C6FBB901BADE75AEE20B2567307DD5
-:108CB000F0F7FF23DED7E2FCB744FCC0F69D30A9F5
-:108CC00000D78CD64714F4A36724C9CC19F4DE3B33
-:108CD000542B7306C5FB6FC4E8FC907DAFAD9F05B8
-:108CE00076A4AE477684A1BCB66F3F9483FD5ED96F
-:108CF000611D828FF4F89DD1FE8882FC9F10CBE528
-:108D0000E67AEF2F1C077C722BD29D911F77B14022
-:108D10002239D2D377EF9E9FC7F6650F8FEFE1E838
-:108D2000AFA7C36FCE1747215EAE470F3DDF76C2B8
-:108D30003A3DB03E1FACD303FED6DE7A3BF5DFAE44
-:108D40004FA2BEC6AF751DBF8C457F4DE3D3B25851
-:108D5000CE375376AF8F65B600BD347C5D1474ABEF
-:108D6000668EF9B3E0CF5D922382F48487F52615F1
-:108D700004EC55F5B172F233347B552D671B51FF6E
-:108D80006AF60AD3C2A8CFF4F6697E7A9111D5AA01
-:108D9000DE2EC1028DC8BFD50B43AF57F4342B1163
-:108DA000D433109D2449E043F8D51A3C1F3217C133
-:108DB000ABA7A7069F1E2ECD9FAE1674837596E1B6
-:108DC000D2E7AA45B48E417655ACF746EDA93936BF
-:108DD00034CEBA72AEF4FD9C21F87538BED5DFD71B
-:108DE000F44039BE20975A0FFA1109B10944AFF285
-:108DF000AB26E6047BC14686B1CF82F3EFAF649227
-:108E0000BD7B54D8DFE1F8A6F6AA81B96303FC6301
-:108E10006C7BCE8AFCB35B69B662DEF136DB9CC646
-:108E200028C053E91F8BE7A15F57D76760989A2A3C
-:108E30006BBFB40FE3F6BAE3CC81FAB0B8BDAB04B4
-:108E4000F9ED6DA557A638FA4BC69E0BF20FDBDA8B
-:108E50001BADE83FB5C5C914A7EF8FE6FCA8DD6FD1
-:108E600089E5FCD776E6F22CE710F73F13F74B4F76
-:108E7000E51AD148F6C74750BEA1FC6903ADBF54FF
-:108E8000B25755A2FF718791FC7A885BFEF07DCCCA
-:108E900037B599B763AABEACED878FD881102DFF87
-:108EA000E7B30633E60FE6488E97615CB9EAEFC296
-:108EB0007EF9BC54DA8799F47F65F25FFD774B94B5
-:108EC000F7280776C17EF93DA95ECC3FEC9178DFAB
-:108ED000D3C1F3FECCEE899D05EFF9A03276C23AFC
-:108EE000E229AD7F4BEE3A261838289E7A6C17DFC0
-:108EF0003F7AAC4CA2FDA3327B0AF304F155F9D3BF
-:108F000040CF3CE0C7F6C462E4DFAA0A997983F84F
-:108F10007ABECBCABC41E3F7877178FC92D98BF952
-:108F2000124D5E670AFEAE5E181B327E0EE37EE2D5
-:108F300042D66C44F9AE13F0D415013CF0FC4C1150
-:108F4000A7DEED4E09796F256641606856DC68B290
-:108F50008FB3BFEC23B33A473E796C31BC87657061
-:108F6000F9D0E4AC4CAE69223E48921C181FCF9752
-:108F7000C0AB9451DF85CAD1ECC9A1FD394EBD7E8D
-:108F8000089577BD1ED7E47C7E876CC4387A7E91C5
-:108F9000E46043E803BD3FADD703930C8E7730AE5A
-:108FA0009E7BD549FC35480F9CACF887F4C05B200C
-:108FB0005B93415E7FA4E9839BD84DA80FCAE42D43
-:108FC000EB913FFAC1AE9987E00FCD2E68F176396B
-:108FD000C827F2033BCFF725CAAE829CC606E2ED56
-:108FE00001FD007E8363087FE657B16921FB4903D9
-:108FF000FA22C86F3016FCF37E4319F88BA65C8406
-:109000006F24F3E4919EA2FC1EB43ECAB3255DA278
-:109010003C4A1DC4F114CFB35F125CA8D7A49800DA
-:10902000DFEBFD092D4F3B42E409F4FC3090B79B88
-:1090300067F4229F69FC506EE772513E4FA6FCB95F
-:109040009E3FB4F75D8F2F7C12F085F477F842C80D
-:10905000D38DF2C5218D1FD259FA8DF083C6071A20
-:109060005FE8EDC5415DDE65387B71F23AF6E29D61
-:109070000C23E965BD9DD0ECC28138AE7FC7C7F235
-:109080007D8A9999F36DE8578C407D80FE9EB037BC
-:109090000379A30D9C0FDEE95BAA486837500FA443
-:1090A00006E15DE44D35BEAB7D9A51FEB052E89FBE
-:1090B0008B1D3C9F56572A7B2DF06749FB73EB793C
-:1090C000DF48F9B622A54BB1C0BCB31D9203F335FE
-:1090D0004E917F9B75D5E455293F3FF47E7A95E00C
-:1090E0001B8C7370FC6CA7E4851074901EAABACA1E
-:1090F000EDBE5E1F5589FDF22ADD7EB9294ED0F501
-:109100006676F3BFD2EEC7C72570B919868EDAF33B
-:109110001A1D35FA4DC0B1283FFBBE36A911DC3F00
-:1091200046FACDB8AAD03CA3E242FD962FCFE7FE87
-:1091300027C574627C5DFB25937BFCF0F05FCF2F2D
-:10914000BD59F3C3855FAEBD7726C8780A3A863A23
-:10915000FBA1BDE7BAF6423CAFA7D3E4B8D0784252
-:10916000A387A64707E15BE8D9E1E8753D3DABE998
-:10917000B37FB59ED5E6D7EC80F65EBDFE1D2E3ED4
-:10918000D3F4E9531B0D9417B94DC4C1B7893CEB17
-:109190008342CE970B7DDBFF178B01FDAC6D9DDC11
-:1091A0001F7198ED87D06F08E4F3385D9F8C601EC7
-:1091B000DC2F674AAF85F62F8B81A4B87F99CCF757
-:1091C0002FB7283E17E96987C21A405EFE2AF216B9
-:1091D0004FEEF52C463DFDE4E93106DA47577CBDFC
-:1091E00018174FCA55683F28DAAC52BEF76287D9C4
-:1091F0008ECFF5EFFE5E9711E7F90B7360A8F67658
-:109200008779603F06F54299DC23635EBEDF0FBEBF
-:10921000388C9FB6D05782F1CE6DACB711E3EA42DD
-:10922000A4E310F47B55675FF479FB920EEE27956B
-:1092300044F0BA9FE980467CEFF43613F985D7CB2A
-:10924000DB177DC9C85F1A94AF6FE37A0606119FDA
-:10925000DC68DEBE107D3DE0E39FE8F40E1B267F58
-:10926000BFCDC4F773FC478C0CFD5E762E6EC8BC78
-:10927000CBF5F2F8BB3BC39D6A24EEBB71FF7C7754
-:1092800067B253CD197E7C4E9FBF18F395DBB6CCE9
-:1092900055284E14F9CF41FB223AFCED9058931516
-:1092A000F369ED8E528C3F86DBE728F63B69DE1BC7
-:1092B000C51B63CD9CCEA27EE9762163DBCE863BC7
-:1092C00091BFB79D4D76223CBB057F6AFCBEFBCCAF
-:1092D000E570DACF343955DC07F6475B1C2F13BF36
-:1092E000723E6F1931C68BFBADDB853C6C0BF71FF3
-:1092F000CC8A0BDECFE0FB179DF59EAA33E9B4DFE5
-:109300002D61BE51DB27F680BC505D4E0C237E32B2
-:10931000B21686EF6D74B29F633B7D9A1A85F8BED4
-:109320001CA7ED47AA519467F8F64A816BFC60BC14
-:10933000EFA877513D496BFDC22A05607CB3DE4D35
-:109340006D5BFD726AF7D4AFA6FB6B0F453E8E7660
-:10935000BFCEB9A04A09D21B9FC5F3FC526ED6E915
-:1093600012E473F60D6318EF4C7FA24F463D71FB7C
-:1093700055584748DD887219F14CF9CBB4403F5538
-:109380005A12867C79FB55E8078D97E2A3391D9A1E
-:1093900094A65B0A485A881FC2E29D17E3E0FA0FC1
-:1093A000ED2E7F5C3CF241F5BE0B8CFA97F1FA0E84
-:1093B000E96EF9028CCBF31551DE380FF3C6B934E0
-:1093C000ED62C4DFC42E13ED7B6BF9DB5C31AFF3D0
-:1093D000ABD03C729EC8DBBEC9FA289F9C6F81C08F
-:1093E000CA807071FA39A5F94912E6FBE24D0EAC5C
-:1093F000579898E6CAC37C6B573CA3FC695757C281
-:109400004815F0E054785ED7A9E575D9DFCFEB7643
-:109410007F1AE9217D057E0AEAA7EEA3910E1FEDD2
-:10942000FF59C8FFDB810F627D4338AF1760F3E659
-:10943000511EFD760B5F07D89FF878CAFBF9F61D21
-:1094400086E77E7B99F17DC4DE93B43F5D62C84CB4
-:10945000EC0338F74963A3B07DF1D3C86C6A8F463B
-:109460009E47FC741AAC2ABEF7C37A56857567CE40
-:10947000F76DB49F31FD7D9B82EDE1FA3EAA477BFB
-:10948000BFFE1CB547EAFDD41EADBF4AED3B701DC3
-:10949000F9E7103C8F6DEEE2087A6EC7A20813C29E
-:1094A000DB19C9B668EFC17A335FB8AF1593F9EF2E
-:1094B000C57FBECE7213D83BB37BBC3481B113F1F0
-:1094C0009FCF54A07F68C6A87FFF0BDCFFDD4F2E27
-:1094D000ACB3005CF38EDA5A7BA0FFE94F2EAEB33B
-:1094E000A19E3D140ECA0EF546FF41907496873634
-:1094F0003D9971053B19FAB1A2EFE99F590A245F22
-:1095000050D297C580B5A6FCC43FD302785C607585
-:10951000FF1BF64D9E976696DE847DE6C17A2EBFD0
-:1095200064A4F89E8D94E2B07E6599DD7D2C3EC8E2
-:109530007E3BA53FD2FE51815362D1714457DACFB1
-:1095400062F653B1C1F2B6CC5E760CE971473CDFEE
-:10955000BF9A384D7206D749E8C74D3CA396229D65
-:109560000ACE9537613BBB229AFAAE85939A509EFC
-:109570004B6DC33D5F42CF2F8837127F162B524869
-:109580007D887E5C1E3013FAC7FE03E1941798783D
-:10959000CCDD8875A36549A9B9B2D0798CFAD11B05
-:1095A000711F6D62E587A5B1283F36C981E6A180AC
-:1095B000F535C5C661FD231644E1BA9E2BC1FA9D5F
-:1095C00089AAE440B41539BB5AF1F9224784A308AB
-:1095D000FDF1636A299A9CA3CA84C3F9306E46BA26
-:1095E000ECB0C044477D774CBD00FDA28C28CAE397
-:1095F0001629ABAF1CA67E84A341C5756CFC792DE2
-:10960000CD63267BBE6356C97F20FF14BBA228E72B
-:10961000576A3B3537B82E0CD64D7017D9656F9801
-:1096200084FCFD83523BF4778C9218CACF515FE6DD
-:109630009FE97E77B81A0680EE30D94B71BE1D26A1
-:10964000C9BE96FAAE121CEF196354314F541EF77F
-:1096500045C8FC334AA5296710FEECA80978AD621D
-:10966000E4A590FB3D8BAC64272ADFCF267FA8675B
-:10967000510AD98BCAF7A71563DB63E07E7AE5FB55
-:10968000951574DFC0E3DFCAC5DF718A3EC5BB959F
-:109690008B5751BF4B4AFC777CDF95ECA85CCCA381
-:1096A000CD4CFF7AAE12ECFFADCE24F9CF1579BCCC
-:1096B0002243E6FA6900FFA307F83E4465B6145258
-:1096C00037372BFF54483DA86BDA1721FDB9A59712
-:1096D00042EA43E7557E1DD25F304FAA0A1E5F7AE9
-:1096E000209FEC6BBEA85FD2F24B458285DEA9CFEE
-:1096F000A82A05B93C00ED03A01F8A7A45DE55E192
-:10970000717506FC433D586AD3E577994AFBD91534
-:10971000DD7CDFBA3CCE783AD83E54C84F707F41EA
-:10972000B7FEDC0346B293B9D132E5AB34F82A4632
-:10973000863EAFF95F1502CE1D0677530CE5C79C38
-:10974000BDE87F68F06BEFD7E0AE90EF29A5EDBFE5
-:10975000EBC0AF87170025FF4D0FC78178118780B9
-:10976000BF41FE5937AF4B835FDC50765BF3CF2BA5
-:10977000414F4507EB299B1487F576C3E9296DDE38
-:10978000E1FC306DDE6576173DEFDCFAD9D1423968
-:10979000A89F7A2A3626B8FFDA67EB43EEC79FAA5E
-:1097A0008A0EEE6FFAAC0AEF4F57D4461BF0E34136
-:1097B00026393CC89F3DAA82FBCF25C79C4DD89631
-:1097C0009D746399299B71C6D384EDD4F3DE1E3357
-:1097D000ACEB8E0C59C5B85DF33FF4F09A13781CCE
-:1097E00072F0AA6AC5FDD31D1ED58AFEFB8E2754D2
-:1097F0002BFA1F3B9CAC02E331679A6135FAF3CE3A
-:109800002C5E677855E8E16FE2F9F35A7B5A717F75
-:10981000837A11EBC2D127A8FDDA4F75E007D1AFEB
-:10982000CA1EEC571D54BC367CDFC127BCB6E07D98
-:10983000C21BF5ABFE8C363A1EF96C4E887C9658EE
-:10984000EEAE0A96EF32FB9290FB9FC6A904FF8C06
-:10985000A48743C6DDA13E12D2077F3103FD9146A6
-:1098600013A33A598F81D7C9EAF1F8A8C0A3C366F8
-:1098700047378619E354AA6BD38F739470FCE9AF12
-:10988000A727F0B86823C80CB6F72470F8F475B1B0
-:10989000FA3EC47C0B713E983909F9DC61355C01F4
-:1098A0005797391392EEA47AD93CC3A369D0AF4E2F
-:1098B000C8E2FDA9869D581F7B774236EFDF6AC854
-:1098C00033821FF02B36FE4EAC07AF0D13759D0F84
-:1098D00024D27E9816DF2886532F2EC638738F9198
-:1098E00061FEFE1913D8BDDCC0BEB9D5CCE352ABC6
-:1098F00089D76D3F957AF429D41B6A987B7A02F94F
-:1099000051C52AE2EFBCDD42759D8FED2E4B44FA26
-:10991000DF93C0F35C593BA726A17EF917BC7F56A5
-:10992000C2C4E1DF8F75BE38CFF91D59E47F67DD12
-:109930000CE89502F887F098AE87419840E72598A3
-:109940003309F36C8DD1269AE79E04CE7F37DA0E69
-:10995000AAFB8D32ACDE0EEDFD82FE0FE07B095FCF
-:10996000FE51737063CEEE1F35773CEF237D653972
-:10997000D78F7EACFF3B11B4AFC246FA69FFE5E377
-:109980007BB21CE89F7E12CEF1B7D03BBAB14FC577
-:10999000FA0DEF4D582F9191E8AE453C2C327B6F7C
-:1099A00021FEB1AD8EC0F96FB41E78F07B2180042A
-:1099B000FA544FE1F4D1DE0B38B5A03DF8589C03C2
-:1099C000D1E080F7FF00F9408367000E5D5DB89637
-:1099D00067AEFBA381F20C7512E83DE8EF3CC91CB1
-:1099E0001E98E7A2E6AF8BBC266E45E17BA61C5E07
-:1099F0005A628336BF6D258F737B95903CD7A4E365
-:109A00008A7EBF83ECD654ED795D9E71AA886BA7E0
-:109A1000EAE2DA1713849D4966C9C1798035226E5E
-:109A2000B8DC333A0AFD4CD45132E0D5A4CA6C728A
-:109A30004C40CE5B21EE674171BFC667E38FD9EF23
-:109A400047B8C71F63F7915DD7E61DC82F70BC5C90
-:109A50003ECEF132A12FE3A7D3A06FEC3632AF1A7E
-:109A6000584F2107955DC6FFE078BBC98B75CB05C4
-:109A7000077E99E7834BE624035383F010A68633D1
-:109A800035482F5A336242FAB2866F61CFF3C4FC75
-:109A9000118EE49079F6C49477A37DCFB32D27FB84
-:109AA0001E357974C83CAC4709B1F3B028DABF9CC5
-:109AB0000840FD0CF05A704C09B1E793E23CB862E3
-:109AC00036F9A4A2B3FFCD32CA41E199D0EB0786A3
-:109AD000A3CB70F863393F45FFEE1FC55FB4331465
-:109AE0007FB115A1F88B7785E22F7161289E46B86A
-:109AF00043F192B27C5CC8FD9B56E786F46F7EBC56
-:109B000030647C2A18A4E07EDAD33343C6DFD23C2B
-:109B100037A43F76C3A290F199DEA521F7B35E5D2D
-:109B20007143F41EDFB226649C9EDEB7B6FDAF9093
-:109B300079357A7BE0DFBF82DEE6C4507AA70AFD82
-:109B40001AEDE4F565FD46DBD312E8234C13A15E64
-:109B50008B6E7FF76BCC43788A55AA9FF3CC64B4A5
-:109B60000FFD82EC92500FA5C0148634AA5FA7FAAD
-:109B7000BB1F1B0C21FBE28989DCBE2726F27CCDB2
-:109B8000CF4DFCDC520AF88F64870C2C102F031E7B
-:109B900022315EA678FAC7CF60BCDC14DD97A14203
-:109BA0007C6CC6FE4D017DB9C8AC36F6013E26C8B8
-:109BB0005C1F829E4C4B84F93F919E30723FC26382
-:109BC000443F22C5C23C91B9643F287F1CCDE224AA
-:109BD000ACC78F0AE869F51A106BDF8A2C3A07F5D3
-:109BE0001E4282FEAF2586ECE8DD9A7E5A9E49FA37
-:109BF000E9B22DD40FBBFC401A5D3F71AF99F6FB63
-:109C00004F883A446DFDE784DEFA53BD85DAF3F5FB
-:109C1000F6103DB67CE3FA08F41F4F64707F51BB29
-:109C20005E82789B88AD2CEC9AC58EF9AC7BC038EF
-:109C30004701BE5775F7452E62E43716E3BA6B3716
-:109C40005EB9F74DE8D719FC09DC3E7878BDCCC782
-:109C50008CFCCFEA6F5888FF343791C7E973C5FC95
-:109C60000BA0B1039E1600FEA3B17D775A39F227EF
-:109C70005CA7F369B3BB19D59FCC71A7D23EE35162
-:109C8000E6F8701780F89D4495E09CC75CB45FFFD0
-:109C9000D1BDAB2270DCC07CDA3CC028E86F7C1CF4
-:109CA000ED312660DC7F1BAF6F80F759F0BAEB9E79
-:109CB0009427D10E69EFFB88B92F7C88FBDDCC415E
-:109CC000F36AF3331613A29F762C5FF9692CBC6FED
-:109CD000CD0103E513D6749829EEEA5FF1D7AD2FD5
-:109CE000C2FDFB52FA6E42BBFCC98A6FC6203FDC44
-:109CF000BD01F410ACB130CAFD7062509C72E281BB
-:109D00002B11781FECEBA617D1386E36537DEF2759
-:109D10002B368F09F6471F4D2CAAC5E7D8E41B3B0D
-:109D20006F58F27A6622D563097E7A58F0D39AD7B3
-:109D3000C6921FB52662809F787F13AFEFD0D6F111
-:109D4000A1E0C715AF7F5D107CCE7407F0913A8615
-:109D5000EF6BA920533B7B2EE7E0FD57147713C22E
-:109D6000D779F57424F677BEF737829FCDBB31786B
-:109D700051063D0581FD65EDDCE5C2F6D83CA43B0E
-:109D8000C85933CEBFE837AF5DF81DE2A763F3A62D
-:109D9000EFE3981B3C7FC9847D71083C807DA1F86E
-:109DA000A09F85F3731D428F2AB8839E86E7991C76
-:109DB0002AF1B3931DC27D97C62E03C3BA9548DC22
-:109DC000B409CAB345CA06CD08392D49A09F855E9E
-:109DD0007925F1E49D4DE4E787FA3DF96FAF08F18D
-:109DE000775CF08FFC9D97DC8D9807BAAEDFE3338C
-:109DF0002C3145DDB8FF0381B0532A105B38F06B7E
-:109E00004B14FB22420F77A21C61FD3FCE85F97AED
-:109E10005F383F670CA602F5F80F604DF8B0294592
-:109E2000B4D2C50C0BE8C5BD897F78E669D093969E
-:109E300074BE5EEC37E2DFDD9CDF06FCABB7C7919A
-:109E40009E62DFC2DB100F225FA1A7533EC8078BC3
-:109E50000D9233F1BC6FFFDF22314FBB35467D1FC2
-:109E6000E9E03F20D33E4D98D2678A1E222E7B1315
-:109E7000F59E89FB4D546FDEC6F38116D5C9300EB1
-:109E800008B3DB27049FB36B17FA6ED5FE4F4699D4
-:109E9000800E170C3D91D9307FCDAE1D91E8C6DF05
-:109EA0006B747F8A7CB7F2C40705763ACFB671141B
-:109EB0009D03F08DA6BA83F10AF328B983E1A8DBEC
-:109EC000904BC6B8760325E3D9F8F6BC87501FD56A
-:109ED000F9F83A716E2CFCCB6C63D4BFD8D61883DA
-:109EE000F3D5FDB62319E567733C8F135FBF3A8E38
-:109EF0003FAF3005C77F99182DF8D96BC03863B3D1
-:109F0000884F2E5E35D038EDFDE3DB8A643BF043AD
-:109F1000B6AF792FC543ED6615E91AF60AE37868FE
-:109F20000F2339AFEB9CC1309FDF1FCD1C12DCDF4C
-:109F30001AEEFF039D33EB30AB981F0DB337B31808
-:109F4000987FABD80FCD048EC2F34ADA75ED7D61F0
-:109F5000ED3FC55802F981F2B4614A33BBCD168C8E
-:109F6000E708C2733CF2533CBEC767C0FC88FF16CB
-:109F7000C65E26B80270327AAF066726F9735B4D6B
-:109F8000FEB3787E05E0B223FD33198793B58F5574
-:109F900031BE0FB33B691D6176D5E19106C355977C
-:109FA000C3BC68BF7FBC960DC82BCA6F5D78A06F1D
-:109FB0000119D83A9A09F9B63F5B3A2DB80F8A646D
-:109FC00072E0F9711B629E6D1A49718347C638169B
-:109FD000DA88185CA7CACF3B636A2897E301F7C504
-:109FE000AD167E7F603CF0B70DFB363ECE1165B7F7
-:109FF000CE94484E28AF572BE4FD31C977F67690C2
-:10A00000D3BFF8F6E6A8004BCDBB7B884F571ADAD2
-:10A010005F1C0FF7375ADCF94980CFB74E1AE81C9E
-:10A02000E99F5E0BF35662FCB87B63827308F9D03C
-:10A03000CFFFC3E36B9F4F41FAEF9654CC9BF61BC7
-:10A04000FDA310DEDAF6CF4D548FD0768AEA938ED8
-:10A0500024B99DF89EC96D0DB46F3C8535D3BE7192
-:10A0600096387FDD92C4F5C7E563635E6E08C2FF74
-:10A070008349DC0F637EF7CD2837ED423E3BD12F7D
-:10A08000817697F08F7675DD9DA606E5FD1AD8DE00
-:10A0900014C4F75AF636B5DAF57E2F3FCF98F5910E
-:10A0A000E53E6710FFB993B89FE716EFF327B9179E
-:10A0B00024A1DC769D3645AA785EA56514DA911652
-:10A0C000F09FEC43E065406E757254A7F84D38BEC2
-:10A0D000EE1C3F770A746EC2FAFFCD1FB58D5B028E
-:10A0E000D77701AEB1DED373C24C758FBB8CAE1483
-:10A0F0001CDFF0E15739A8B72A1069F0BFAF3A5614
-:10A10000DE8C7803BE2F0E47F9DACE488F69F299BC
-:10A110008DF209CF6723DFE7633F93F4F056532FA7
-:10A120003FF7B98B9FFB04BE273900BEB7A39F90B2
-:10A130006D0739A0E7C7927C6FED35D0F9540FE871
-:10A14000F15BA85F5C85FDADBDA576926FCCC3E7E2
-:10A15000A29CFAF6D23C2D108320E924E60AF61FD1
-:10A16000DB1323898F35FD783091EBFF960C350A90
-:10A17000EBFFADB21C2217417690F7859DECDD50C8
-:10A18000FCEC0BD3D0DE09BB20FC27769CEBF94717
-:10A1900085AD5AF34EE1EC2DB0CE3587E5817A6E70
-:10A1A000F4577D824FF60AFF15ED849AC7EB67F0EE
-:10A1B000FAC40DBCCEB5C0B9BA04CB38265734EFBB
-:10A1C000C3B6D0D55282678EA72DECDDC7CF1EF364
-:10A1D000F3E3AD7BEFC8C27DEAFE136686FB24ADD8
-:10A1E0007FF3FFE175C0C3773B01FF43D825580ECD
-:10A1F000F11F58EA149634F87EBFA4E98FF9952828
-:10A200006F175BE5401FEC612D3038F67F9D54F5EC
-:10A21000AC07004B1BE17C1D59A230D94D6DFF915D
-:10A22000BF25A02DD8758CFB4DAD266716F24FEBE0
-:10A23000E8D0F3FA5AFB62123FE79C6F6643E625CB
-:10A240000F09BB37C6C39E413EAA6D95ED5EA0FBCC
-:10A250008556D96902FFE6ACD39D806765CE31CFC4
-:10A2600082A968E745DCA87D4F6519FA2760A71E1B
-:10A270007C61501EDF807CF450BBC47E066B5EFEAA
-:10A28000D2D0FB0A35629E87DB36EE4F013AAE78BC
-:10A2900025745C8DA813ABD1F92F8792447C98C6A6
-:10A2A000D2D02F01FE21BD605458B719F8F5C16412
-:10A2B0007707C61B9BC5770C407F921C7608BEDCD7
-:10A2C0002AEA04FC5B25DAD7CB7CD52B1BE0F942CC
-:10A2D000C52BA39D62D0E23EC164A7BB1CF10BEB72
-:10A2E0003E86FB35CB851E5CAEF9655EBE9F01E602
-:10A2F00096FCB229CCDB1889EB7E5572F854FC8EA3
-:10A30000C8A03A5C5A779D5877CD8623FB318C5B89
-:10A31000D5123AAE4EACBB4EB76E6D5FFBCF49BAAD
-:10A3200073C837B86FF16723F7133E10F368F7CDA2
-:10A3300023B83EAC05F0906E355ED9EBE57E9D0D01
-:10A34000BFC373BF80F77E41EF3AE633A5C0B8556F
-:10A350002FF075B26743EB3F1F6C7DC484F1959E6F
-:10A360002F966F31923F0A8833A1BFA8E78B156201
-:10A37000DD2B74EBAE754B3AB8B89F3C18AE960522
-:10A3800048D7555B8C0CEB11F5702D6B59528E7CB8
-:10A3900036985F395D5688F90270AEA6737C370A2D
-:10A3A000E7A811822FC7B17144978AD81BA28BDE10
-:10A3B0008FDDBE7F9C15E5FB72F7688ADF35BAEB4F
-:10A3C0009F2F177EF08C0D8CDA0B6D25D6F118A718
-:10A3D000F4181C924AF156E478C0475E87CC2AA153
-:10A3E000DFDF9EB6DE0378CF3D9C5F85F17CDE61CA
-:10A3F000039D77DBD99D4FFBC07907D263D3281F1C
-:10A40000EDA0EFCDC03C643FFB7B72D7E3B980FE8B
-:10A410009ED27C9C57827168E773851D68E8C9B538
-:10A42000069FEF2E18C1E3F5A7923EFB31FAE13308
-:10A43000B61BE97CC30CA3FF3DAC9FDAD9ADD0BEFF
-:10A4400075CDE1A56BC390AEAF49B46FBDBF774D7D
-:10A45000DC62E4AB76A31DF7A1FBDBFF6D2FDEF71B
-:10A460006C91E87B12751D65595BA19FBB31CF11C3
-:10A470007CDE2B375A25F8D8082BC5C3336E3292B1
-:10A480005D3C9F6CFD25FA372B9C1B498ECFEFD985
-:10A4900069A2FAB9AD1243D3BF3F69DF1B888FF3BE
-:10A4A0006F1E31A1935DD27AC4D4F777ECFD052FEE
-:10A4B00004FE1407379B304E59B551EBF799904E77
-:10A4C0002EE1FFD4BE728AFA2BDA24D2332B5E92AD
-:10A4D000E93CFBBE8EB74CC8C7B55B2496981A748E
-:10A4E0007F8314F21D84A58CF3C152A1675632EF0D
-:10A4F00053C9306E6533AF23604F87D6E5AEDC328B
-:10A5000087BEDBB4AC79687DF3B0E0EB87301EBC6E
-:10A5100015BF83143AEE61EDBB5C3A7E7E5CE3E7E7
-:10A520004C9689FCFC55911A950DD7BF3AB2E2E6DC
-:10A53000A1CEB1F7083BACD9C1CB3E03D911FDB8D0
-:10A540008B6D5708DEBA9ECB26B483E5ED9708EFF6
-:10A5500095ED5D54C7711773D7209EEE6AB7DA5137
-:10A560008E2BFBB85E9AD96EF67A25BCDFD284F4C6
-:10A57000ECEFE4758B9E3D12F92F9ABE7A48E0EF1E
-:10A580002181BF874041A7E4A21FCBE3DE8733369A
-:10A59000EE8F81FBB5E27ACD817D91E8EFCD6497B6
-:10A5A000EE457AC07B18BE87BD148AE73B1987E366
-:10A5B000CE2DBCDE596FAFFA4764CDA6FC23C49DF7
-:10A5C000084FCD96503CD7EAE2ED7523B87DDEA466
-:10A5D000C373A59F59B3110E5576786974AF82EF96
-:10A5E000EDCE9128BFDAADA6450DB5FFA8B5EF09B0
-:10A5F000BF59EBCF16E7AB5BECCDB6E038D894CCC7
-:10A60000EDFF8A29B207E934103FA4EFCB510D8149
-:10A61000F801E286DF8C88E771041674BC3B526651
-:10A62000717181F8E18749EB2B73A15FB785CBF995
-:10A63000C5C9301F7EDF4B61E45FD66D31D339C0B1
-:10A640003AA03BC509EDFC1C83AB5D2A437A83FF2E
-:10A65000FDEE888978AE8619E360DD73DA389FCF26
-:10A6600029BD447C72209DAFF7B2A2260EE58F6B08
-:10A670007E389EC35283CF3F805CE2F8DA765E0F6D
-:10A68000D4BAF7EB51A9A8D73AFE3A6A09B45746AB
-:10A69000F0F56B7E9E1FFCBCD1DCCF3986FEE783D4
-:10A6A0009ADCD8F93EDA83C2CE30A989F8BBD6D875
-:10A6B000F2760CFA4D5BF9BE3DDB6DC46F9CB18642
-:10A6C0000F5E6F8A81755F7C5DA27A347CFE09E043
-:10A6D000B38B4B5B4EA31FFDD5560BF98F0F828FAB
-:10A6E000383D77B03C6A72AB7D77AA81AD257F7229
-:10A6F0002D6BA27695E0E38B6D8D26CA9B79839EA8
-:10A700001F3DD8EF58A5E33B537228BF357C104E50
-:10A71000FE5FFF01D98EFB2780A7FF4E0EC687F094
-:10A720002F5AF786113DFB8FD8C85EFC49F0D979C6
-:10A7300091376E982CD3FA0D53789BD5F9D668A42F
-:10A740001FE21BEBDE3777BE358E9FA7F612DE5772
-:10A75000BE8A49F120385BAC94DBD3FA0D1F2CA2E2
-:10A76000EFF0D4ED19806B8C292E00D770FC2F49A7
-:10A770003C1E3448A1F160DD6ED9155CEF05EBB9E4
-:10A780000FF54F929003A6F813D02F1999AC92FDB4
-:10A790006A68E7F43474F016DEBF80E73B8CF4FEA1
-:10A7A00041F78B3D3578FFAB542BDF4FBEEAA9C490
-:10A7B000FE7747CB544FF9DD0F568C0DD69B0CE13D
-:10A7C000047AD619FD0914371E31107C75472E27DF
-:10A7D000A4DB501F6D2CB567A3DEE1FA6EFF68EBBA
-:10A7E00072E4630FBE373130CF6BC2DE325C6F1262
-:10A7F0007A152FF079C57AD7B2B9223EE67C942D2E
-:10A80000FC3D882B26264F1C1C57DCA83F09F6E090
-:10A81000E86209EB89140FC6B53B8F737DD0D0F188
-:10A82000D0A7C8E7759F98A9BEEABB9D0F8DA53A32
-:10A830005BB7FB56F42BBEEA7CF856CAF3496B09AA
-:10A840002E0FC29784FECB8709580FBAAAE3C30420
-:10A85000B2AFBB26AEF744A09F927B275E07BF81B5
-:10A86000F80FFC17E2BF9D3DF99ABF62C579571DED
-:10A87000505C889F5507F20F55A21F71B8381FD53D
-:10A88000B874389FFC953CF4576C01FF455B4F65ED
-:10A8900032AF77E9EF0AA33C81C44673FE61E92138
-:10A8A000FC53D3FA0ED9F59A3639A46E507BCE9D5F
-:10A8B000ACF07D7E8D7F5A2427F1C776DED6B4EDCD
-:10A8C000A4F5AD34B610BD1BB618F9FDADBCD5EA84
-:10A8D000AA3D2CC683F8388497800E334D5EFA6EFD
-:10A8E000C5C154EEBFEBE9F15932CF631C3CE1BE68
-:10A8F00019F9E560917BAC7D08FBE061C53C3E95B4
-:10A9000004BE5BF97925FDB853C93C8E8F8C0D3D93
-:10A910003F3A605F9239FFCC340DFD3DBD9F69F237
-:10A92000C4D83306E08BA39546FB3AE1B78F08FA0B
-:10A930005E42D55D46F20F8E32FB3B5867384BD3F3
-:10A94000AF93B95DD5F2DDAE0D2ADFD7197CAE919C
-:10A95000F4E47C6D3EFD7969E1D7CCD7F935EB3570
-:10A96000FD37868D41FDD722CEB9ADC90CF306E780
-:10A97000A3F4ED7EB18F81E775B06DC8FC98F23617
-:10A9800007BB4EBC41756627C2D8689E97A3FCF5ED
-:10A99000AA61F2D70D03F2382F84BF347A5C10DF3E
-:10A9A00055D1D3E30D81776D9F2D5CECB39D56DCC3
-:10A9B0006F24535DD67913FF8E9A9FE2AB864CEEDF
-:10A9C0001F5D2893685F1CE01C650ED2EB1746F0F4
-:10A9D000B8EABB0B24CA9B76E1788C9F5A24AAABB9
-:10A9E0005EE5EB35211F8D695DF224C9AB871D63E0
-:10A9F00041DFA9986DE17671806EDABA07EC568C6A
-:10AA000087EBE1386A713CDAC159C2EEE9CF218D9A
-:10AA100065BDE51857563B2507EEDBEBE93D77E1D1
-:10AA20008477E2FF013A9F4B761F21FDD67B7901A7
-:10AA3000E63F0F667E3E0AED65ED307CFB3BC1B71D
-:10AA4000DAF7591C63D546FC3EC98F12DD9F207E84
-:10AA5000FB0DDF468E63F87CDF7FAF91902E8CE894
-:10AA6000319C9C9C12F39D4A16DF258CE3FB24CB82
-:10AA7000B18FF26AF48EA4FC42F68DED4B35EC7E7C
-:10AA80003707F5D6C5AE0339A6203A9E5F03F28E8E
-:10AA9000F6A3635F826A0BE63303F1972469FCA691
-:10AAA00008BB18CA77E791EFB2B1FD30321DF5EE61
-:10AAB000F6A391B7E07CBB783BC09FED328D8378E5
-:10AAC00067CCFC8860F89E24F82EB4F07918EB1B54
-:10AAD00053353EF87EE3707C6B4CE1F584217CAB12
-:10AAE000ADB705BF8783FE7DA799BE8783F9E6E8EA
-:10AAF00020B9484DE1F230497CFF660AF3D0F700F7
-:10AB00002789EFE04C51984F89C17D2E9FCCF76586
-:10AB1000F9798602C1BF93145F17D6394C11FB3205
-:10AB200085AC97C64D677E6A9DCC4EE7148A9983A3
-:10AB3000DAC916DF9D9876C96E69A1FA3F5F821265
-:10AB40007DD622CE430C41B7C0FA15FAEE0DF1A521
-:10AB50008CE76186FE6E4A650A9773FA3807D2F76A
-:10AB600002A3FC147EDF0C5F325561155877749B8D
-:10AB7000C22CE100EFF6B70D24BF9D7DAA17EB4074
-:10AB80001DB1E2B92F18D5BB4E7272F944D382754C
-:10AB900012DA7AF5782884F9303F364981C892F084
-:10ABA000E8A3F7DDCEF8398D22A6D207566EC78FFF
-:10ABB00027935EF7539C54027112EA7583C543F8DC
-:10ABC00028C3E4CA44BEBF1109F314364BEC38EE77
-:10ABD00057A4F1F56AF3170223E0B9BD32B15E4C18
-:10ABE000811E8FE1FB1E9154385C6AE7DF094AA0A1
-:10ABF000EF04DD285EFB13F8772123EFF75FFC7E7F
-:10AC00007E60FFC781DF0D8A0C7C8FD281E74C30DC
-:10AC10007FE753CE07FBCD77A72CAD4E9918A897A9
-:10AC2000636EA6A25FA1AF9743F49D0B3ADFACD54C
-:10AC30007BBCEA9DABE2B9B98571163A4F9B6B19A3
-:10AC40009587762B23D15D9D42751F5B6EA14914BC
-:10AC5000EF44574480CFADCC3919F11CA8D7E3DFBE
-:10AC60004F1A38CF94C0E8FC9FD5CCEB199F01B99F
-:10AC7000C0EF178154A958D7C29E28A1FAC7A7A22E
-:10AC80002D0E3C87604678AD01781B2DA2EE47570C
-:10AC900077D96833D0F7381B59389DE79E15E6FE03
-:10ACA0001EAEFFB188623A2F9DB56D5A12F983B07E
-:10ACB000DE69DA7A0D83EB10B1FE0F9FD3D7FF69FF
-:10ACC000EBC2E3EBF85EBBC097B64EBB76DEC7A91E
-:10ACD000849CF7D1D6FF4C385FA71177E2D3E859AF
-:10ACE00015F5837E7D1A3FFC3FDDFB356D605C0012
-:10ACF00000000000000000001F8B080000000000A2
-:10AD0000000B7B2ACBC0F0A31E818565181826F1A5
-:10AD1000A18AD112CFE066607804C42C3C0C0C856B
-:10AD2000407B23807424101F01E2A340ACC2CBC03F
-:10AD3000100BC471403C07C89F0BC4A5409C05750F
-:10AD4000632B0B03433B107702713710EB3033302A
-:10AD5000E832136F7FBE0803C31309045F51126802
-:10AD6000A734FDFC3FD8F00A7DFADA276DC0C0B0E9
-:10AD7000D502C15703B2B759A0AAD96E81DF8C1D85
-:10AD800068F23BD1F8BBF0E83FAB87CAB7D540E5E6
-:10AD90004B693130782285899D067EB7A0E30AA0F1
-:10ADA000DE4A200600FB72DB43680300000000005F
-:10ADB00000000000000000001F8B080000000000E1
-:10ADC000000BE57D0B7854D5B5F03E731EF3C8CC6F
-:10ADD000641242483084092FA30D3821210D14DB61
-:10ADE0008140448A1AD42A54D4098F24E435011F9F
-:10ADF000176BDB0C04232060B058A2463B4150F097
-:10AE0000061D6890200107B034F4A206AFF5D1F614
-:10AE10007A8352400824E20BBDB6FE7BADBD4FE6FF
-:10AE20009C9319A07FFBFFB7FFFDE3D71EF639FB0C
-:10AE3000B1F67AEDB5D65E7B8F6C3213692821DFCF
-:10AE4000C2DF0F089926114206469EF6D7889BC49A
-:10AE500013529F4DCB4984A48D2041221032B986D4
-:10AE6000967309597B27099A3308D97FC484DF5721
-:10AE7000FA5899B60B99AEA1DF47B2F74F64D27674
-:10AE8000F4FD1317446C179841829B693981D0DE19
-:10AE900086133A840F9F933D0DD6D1B47ED39D2661
-:10AEA000627613F2381D868C27C441BC56429BAE95
-:10AEB0001CC1FA7B6C86E93951808FE19479B4BC6E
-:10AEC0006A4A49DE2A5A5A2D33B81A67973C17A0A6
-:10AED000FDBB4CC3711EB4DE13765AEFD1F74AC9DD
-:10AEE0002ADA6EC31C93509245EB352BB3825991ED
-:10AEF000F9ABCF3944E2ED0266533E3CBDFC195636
-:10AF0000E0F98B89261C674D0DC307ADA798520841
-:10AF100069ED3C60F1D1FED654B61E2DA4DF1F1999
-:10AF200061F2500C92473A0F58AFA4E307724D9E5E
-:10AF300091B4769A14165CF6C878E309057C1CADCA
-:10AF4000E7D96171DBFBD7A7FD4E8279AFA67817F1
-:10AF50003322EDC6029CB4DD1A4AB2101DF797B237
-:10AF6000E7308CFBCB1B12850089D4BB1E80847A12
-:10AF7000734C244CEB11A9D742E838AB26BE6519B7
-:10AF800049EBAF2A32C124C81A8FFADD6325D0DF1E
-:10AF9000D4518747005DAFA7DF611E598FCD8279FD
-:10AFA0003F3A452180FF5F0AB41E457163B1F24309
-:10AFB00080CF51435CF09E3EBDD1F0DA2658100E92
-:10AFC000B27A0321790440C0BF55DEE08A61C05FD8
-:10AFD000B9C403E5340F6D6FEFDFBE4B30235D1A4C
-:10AFE000E5402AE02F16FD46707CAECA5C6C057AFF
-:10AFF00010D29052349A90F580271854F2B9673ADB
-:10B0000022F557080C3FEB64E215E8FCE27295E08C
-:10B01000528A6753966B36CCD7EE53C875B4BC5280
-:10B0200008A48A4097D10AD9EC46BEB08EA4E53573
-:10B0300057257A80FFEA85508A04DF6FA0DF699781
-:10B04000078AC6CE06FE6CF228C8CF947F0E03BED8
-:10B05000D7F812C92A377EEFC4F6F6112E33628272
-:10B06000C243F13280F212E035FBA6FAEB87037D92
-:10B07000C6995C40A155C224F73C909F048B0BC637
-:10B0800097C7DD8CF49307260A4443EF9F03BD293D
-:10B090009ED6BA8B7E0ECFA7723F4C1849EBAFCE2F
-:10B0A0007EB911E8F4F4FD16A4DFD3E33A17815C0E
-:10B0B0003D7121E73D1FCAA5E2D94CFB7926FB442F
-:10B0C00006A1033E36EDC304C0DF90110DF7102733
-:10B0D0007DCEE8AD2563287CA4A1687E06F2897048
-:10B0E0000BC5EB90250A715B182DBF25F09D7843A9
-:10B0F00059AC6CA7F319C2E9DCDAF996A518FA9BEA
-:10B1000043C2A39CF8DE929C18D13343724938990C
-:10B11000F6FFC4824328E74F5F9DEC61729E82FC7C
-:10B1200092CEFB4983FA54BFA45848208E3E8774C0
-:10B13000F4DE0C700DC93C3107E0DCFFFA2101E8B8
-:10B14000F6CC986437E8A3045F27E9A2741F92F550
-:10B15000CE8350CF610FA6146561FDBF603B03FC39
-:10B160002D6EEF26C0DB36A1E630D027906DF23091
-:10B170007A333DB8FADEE420E89121B63FCD14875A
-:10B18000211F10924CE1731194937A216C190EEDEA
-:10B190001E60ED8692A000781E921958243AA1BE36
-:10B1A0004F2872F41FB7153422C807E574E0D7EDB5
-:10B1B0000A292F8A2207AF7279AE17C82CE46722BA
-:10B1C000FD15F8666802E31BB5FC0CC043C7DDFE45
-:10B1D0005AE20FB3283CBF5A322C5BA4F0AC857600
-:10B1E00051E4660D97035B07090814AFFB7FF73B3B
-:10B1F0002BE06DBB899441FD4999214B17A72BD0BA
-:10B20000630161FD37656DB4A0BE103291EF16E4A5
-:10B210002B5EEB1890BF65828FB64F7131BDECF09D
-:10B220002841D0CB8E948060A2F0B8B3886B6306BF
-:10B23000EB2E40F13717FE018C2EB1FAABD7240468
-:10B2400057D1EF73B3A8A001DE28AE4C74DCF984AB
-:10B25000CD73AEA77E11D08F902213E073958BD162
-:10B26000A709C6A153694A63FDACB98F0497011FB2
-:10B27000B958FB11D084D26D44EECBFF22D07ED3DF
-:10B28000783B907B68179712B498683B778D89203C
-:10B290007C52F8B000741F9DEC06789A523CFF3E39
-:10B2A00003E09F257936D2CF23000EDA4F538DC9A4
-:10B2B0008BFA225769063DBDCACBF4BC8AAF0C3E5F
-:10B2C0006E9A272CD0B9930CAA27114FDEB0D50562
-:10B2D000E52C064F462E9B571FFCA395E032DA382B
-:10B2E000CD1226504FC54309EFAF84CFC39E125CE9
-:10B2F0002101DCB90C6EBA2E233C69594A33C8418E
-:10B300005A0AEBCF4DF1A3E21DE0B2A970E5D2FAE3
-:10B31000A0873D4A33B0828DC35792C5E0D97FE400
-:10B32000AD0E81F5877265E3F0DAF8FC09C09BCCBD
-:10B33000F53AEDAF450E0B22AD1F1C47DC1BD9685B
-:10B340006E292FF2FDB11A8A075AB0F371C87A3309
-:10B35000CA037D15F896F2C1BC065ACE8CC8C7C880
-:10B3600015669DBCD8F9BC49039323CA366168971A
-:10B370004158D904653A8F924CBD9C118FA64CE17F
-:10B380007000BF53FDB374BCC2F8E72A66C710A2B1
-:10B39000A9077C3ECEFDEC6AFCAEE0BA9EFE5345AA
-:10B3A00007DF909AE4C922E8938E276F36015FDDAC
-:10B3B0004B4C623CF2B3D0A7BFE8783B1687AD3068
-:10B3C000495B475122E02DBD2671B20278ECF06155
-:10B3D000D9D651E3C5272C4D6309194C34E3648059
-:10B3E0007E7555B450BC921A2504FA7A9C164EFA12
-:10B3F0003DFDB5869940AF87171D4A05F94D36B416
-:10B400001F631A86723AE4355A0BC73FF133A8BF5F
-:10B4100092EB131B403C169FAFC173889DEA59AA5B
-:10B42000A7D3298295B1117DB1EAAA77B27D76CEF4
-:10B430003F89F80CC3D3A85734F5AFE2F503C245F2
-:10B44000EB9DC07A2A3CC6EFE70413EA2907D89996
-:10B4500014BF8F12D76C5C973D265C17E3F8FB9006
-:10B46000E7C064A4678878840CD0B77F356BF9E0B7
-:10B4700027F012F4AD14423951D26D681F52398E43
-:10B480008375AF49AA2983F7A1341B01BD7060EA17
-:10B490002101F099D6E61B0A72A8DAB9933DA114EE
-:10B4A00078FFC861DF95289F31EC46D54E34CEE752
-:10B4B0008A6B97A13E18EAEBED80F5DE5E2979AE46
-:10B4C00003FEF251B8ECA827DDE4BB147E4F6029DF
-:10B4D000E859B78F9607D167257F96B1EF2B6BCBD5
-:10B4E000728E4B917E578EA0F628D58BEB3BD75BA7
-:10B4F0006E003BA3C6E406BE5DE379CBE2B54379BB
-:10B50000F200C0736B916AF78505182FED6D2FDA85
-:10B5100079E35C8A0B94D6687338D5A5592F9AA61F
-:10B52000BE3316E020B75222A6C6A6239D2FF2599D
-:10B53000ACF504603169D691FD993B707D799D5CD5
-:10B54000857451D715751DC11EA97E99C7E5E811EF
-:10B5500077C822A0BEA2B24BE9338FEB113BD79B39
-:10B56000540F333DC7D793358B92713D51F527D892
-:10B57000D6A024E6717DBB26FBB9841B284C76D06F
-:10B58000B3A09752C864587F47829E01FD240504EA
-:10B5900018AF699C8BACC2754CAF4F47D6303DF8A5
-:10B5A000480A417EA2EB5033AC774D69A114E8A75D
-:10B5B000A9E680E0D3AC9FEA7AE7A8E924A007E7F0
-:10B5C000E6B2756E6E161BEF0F80A0710C5ED0ABED
-:10B5D000C675EF171377A0B28CE3F69611FF828938
-:10B5E000D9818FCE780BF1B866FE63F8240D1BB0BD
-:10B5F000BF140BA3C1CACC03F87EB5CF340DECEE5B
-:10B60000F552E78A1114FEF5D3E62A01FA7DB587D3
-:10B61000F95DAB26CE7D0ED635B3496170D594A1C8
-:10B62000BD1AC7E1DA007DA39FA8A05F74DF9D1B50
-:10B63000570CA3FDA4503F467043A5A0C54CBFDBEB
-:10B6400081A6A0BF7D6106BF874C2651E0FF0FC1D8
-:10B65000C6FC505F67C748A4A7C905F0C6797A2D14
-:10B66000E027BAA91FE67603BC6EEB6884D7E45ADC
-:10B67000EA8EB4FF3DF717EE82851FECFBD9EF4C45
-:10B6800003F95A7727F3CB8CF0DF3729D861C271E1
-:10B6900008BA758E18789D031A0CF48F27887039B4
-:10B6A00032195CC70546AF473B275F8F7E52117D3D
-:10B6B0004F3B7AAC739815E4DB68EF3D1DF74136DC
-:10B6C000DA3B8675E652E521067D3FDA1C9A8EFC50
-:10B6D000B6CD847A8A10A6E70462727F3B1C1611ED
-:10B6E0000617B21ED5DFCBE5F0ECF9B4FEF29D767D
-:10B6F00002F852F9218DF7B9AA86F24194797708B8
-:10B70000622CBA333B83D3BD13C61B7869FA5369E5
-:10B71000B682DD160AD60F2E07FFA386F9BBA1F06D
-:10B7200001D43F69536E433F654B73F2ECF9C05748
-:10B73000995E0FA0438507EC93687EE27493E5A2BF
-:10B74000FE7B2C3DDC58B91CFDDEC6CEE8F39F68BD
-:10B7500062FE7688EA494F56ECF1F34CCC8E4E30BF
-:10B7600071BE9B7A2845BB9EA9EBAABACE0E914822
-:10B7700040D4AC87B772FC19D74D22355846313EBC
-:10B7800047FFB1713E8B436C9868C2F88ACAE7B430
-:10B790005E0AE095CE03ED39CA8741B0E71E250D5C
-:10B7A000283701DA7E33E90FF79DC47459F39BC043
-:10B7B000E7D7371EF7AFEFE2FA6A5DF6FD56E88A83
-:10B7C0008E9702FCE177323D59E560766CC14E39C7
-:10B7D000FC030A4755B3807696699F15E13CB7890B
-:10B7E0009669D7618782F5CFBA2C58F69B3BD77EF6
-:10B7F0008F967B778A04EDC84C9B09F8F504E757D0
-:10B80000924BCB600F5B59B1AA79FF5DD05F599B1A
-:10B81000995869FF55BB4B6FFC1E2D9776C804AA3B
-:10B82000546D5EAA0CA6E585412104E59EC974A16C
-:10B8300002BC242A41F0DB7B9C9DC93FA2F33E5D04
-:10B840006B216E0A4A9DA333F9568A8FF2E0F642C5
-:10B850006857DE228046A4F3D87C2815E6B555F05B
-:10B86000807F5FB1254E670F9EA053F901FDBE9802
-:10B87000CE13E4B2943414C23A57B5799DE2D6C4DB
-:10B880001F4ED7BA701CB55CB5958E43DB55BF28EB
-:10B8900078608AD526E2033D746EB775D6B3769884
-:10B8A000DF52659403E6F5B002F54A83C52F5BDDF0
-:10B8B000005FB35248BF9737352B10DFF29BC9DDCD
-:10B8C000E0E7566C19A087AB5144795D9C60D908BC
-:10B8D000FA9CD8BD29378FEE4FE7D3B554C78E8A6F
-:10B8E00094CB411F221F0695999AFA43C504E4D7C9
-:10B8F0008A2DA2DECEE6EB7FE028A37F60AF03E3D4
-:10B900007E2AFD16737F59A5DFE2044E4FA9372F1B
-:10B910001A3C6B811E149E06C0177DAEE6F03927D7
-:10B9200092491077717A894B88C2D7C667834C8A4F
-:10B930008175FF75D9CC49522ABA0F8B20F2E45A8F
-:10B940003E7BD2145AFEBDA968B309F587C70D72B4
-:10B95000A4FAD9CF98985CD6A72A88BF86A979CFB0
-:10B96000B2F804C175AF616AC9736017D0F6DB4CD9
-:10B970002887B4FDE8D8ED5D85F9BAF6AEC232B5D8
-:10B98000FD4E6C6FB978FB86C209FAF10BCBD5F688
-:10B990007B117EFBC5E1775D37513FFE7595D8DEA3
-:10B9A0006F66F4EA4DB0A05DB3DCEAF14ACC8E0AD2
-:10B9B000C37B2971D446A827AAFC403ABD607FDB2F
-:10B9C0005B12C6AE225ABE98FC3AC0E1A0D2A2E5F4
-:10B9D0008BF87C9B8E1F13BC89BA32EDC975E23B94
-:10B9E000BC0C83382D088F3258417D3169B005E198
-:10B9F000BD7F9F15CBF74F60F0DE3FD88E72866B10
-:10BA00000BA5E3FD8AEF1AADDD0A2B138492DE103D
-:10BA10007D1F027E23EFDD26786F13490DEA673321
-:10BA2000417DF47046DEB3010D7E560CA1F4A5E510
-:10BA3000B360FF0C8CE0F5E1212529C59A71EA87F6
-:10BA400028B33666B1F7F3EC305E510FE0C1AFF4C6
-:10BA50008E02BBD2388E7958BE6E1C4B7A198EF38B
-:10BA6000B5611C737A99611CCBAC8DFC3D1FE71B43
-:10BA70009857AC711E1E36413F9FF4721CC72C1A9A
-:10BA8000E6935E6E18C7C6E643DFF371ACE2C5E627
-:10BA9000337CA27E3E432B719C2451D1C5ADCC4357
-:10BAA0002B0DE3D8711C780FE39034E6DF28E6DE37
-:10BAB00012A4FFAB5602F6B462F63D0FFD923F5A58
-:10BAC00009EA13371D7710E89544DC2FF80F53224D
-:10BAD000CEE70B1BA5BF5D4BE7806A17A0BDB38007
-:10BAE000834882F5E89F57731E9DDF32337D293CE2
-:10BAF000DB0A528AC1CF5EEFF040FCF45C5B81321E
-:10BB00002F8A5DB0A0413ED1A5E35FAEF72693CC6E
-:10BB10001AF0B3B81DA0964F50FD45A8DEFA90EA82
-:10BB20002F789E94A99EA6EF8F53FD46142DBC4BF3
-:10BB3000B1DD0989E1F144135B47BE587754C6383B
-:10BB40005F80BC9D49E7711B9FC6828638E62B70DB
-:10BB500038FC9C1EBDBBCDC18D480FEF1560F79022
-:10BB6000C6011457BCDE30C0171597442C5E01F691
-:10BB7000D18F576CFF0D547B47281EB298CE775655
-:10BB8000EB3AF90A5A3E2777DDE5B16BFA99257F42
-:10BB900008F3B6D0FFA09FD93E5AD68C7F4799BEF6
-:10BBA0007C279122654AB7A9E2304E0F3EAE3B2872
-:10BBB00003BD6E4B66F0DC09CFB1F0D985F4BACB8A
-:10BBC000C5DAAAF0F81F944918D7A3AE81CCB81DE6
-:10BBD00088F57CEABA6280EF2ED9E22DA2F4BCEBA4
-:10BBE0000111F16884B76B5F9CD744FDAAAEC64FC4
-:10BBF00065F02F2F05FFDD4BF4DF49808DA7E2555F
-:10BC0000E583DB674D1A705C536FB6EFFA01C735F9
-:10BC1000FC7247D94C5DF9CE9AD9BAFA772F29D65A
-:10BC20007D2F0E2CD47D9FB76291AEBCA0E1015D4B
-:10BC3000FDD2C6A5BAEF0B832B75DF2BB6ACD3951F
-:10BC4000AB424FE8EAFBDB9A75DF4DFBAEBA09E485
-:10BC5000B1EEF72201FBEC73FB89B5605F7D6E9757
-:10BC6000D0AFAA065EA37278AA3605F9FB74AD1BA5
-:10BC70009FE7DA72707FCC6FA3F24CD7FA0D75870D
-:10BC800097AE98087A84D6A73AFCA9BA379706A83F
-:10BC9000EFBE1182D494EFC546858407801F93D8E8
-:10BCA000C7D7BDA2E67BD725BE37D2052BA7FF7726
-:10BCB000B12BFAFB1EA17714D87781F7CDB87F138B
-:10BCC000CB7EA07F579028FE83FAEC86F88646EF5D
-:10BCD000BC2A32BBFA1A71F2AB227D562A4CDE2BFB
-:10BCE00077A44E867841A5121E5513C5CEEE1B2FA4
-:10BCF00044811904FD30795918BC2222BF48BFE1A4
-:10BD00003AB9BFC1E4DB07FAB97BBFC8F607C2077F
-:10BD1000D3619FE61AD1FB2ABC276D03717D7CA7F6
-:10BD2000D63BE0F80842DEAB9D86CF3FD4160D80AF
-:10BD3000F8D19F6A6761F9835A1F3EBB6ACBF0F95D
-:10BD4000616D0D7E3F5EBB04CB276A03F83C55BB9B
-:10BD5000029FA76B1BF07B776D2396CFD506F1A9C9
-:10BD6000CA816A8F92246EFF717B9DAE1C583ECFB4
-:10BD7000E720D27F77A25C7B5240AECFDBBF1805B5
-:10BD800076EEF9F7CC18448F852723BFC5A69F17F9
-:10BD9000D7FB9220A57F4EFFEF561BA38FD544A65D
-:10BDA000817FB672A44220AE6E7BF53B682FD3F73D
-:10BDB00012417D19F468F711FBFA87390FBA349DE7
-:10BDC000D4FA279EFCAFBCB959401F465FDB41B196
-:10BDD00086D1ED590FD04D833F6697EDE4FADC80B4
-:10BDE0004789CB9D119F6707AAF8EC4C87784B9544
-:10BDF000586492E8BBF3AD669CD7F9F638B68FED80
-:10BE00004ABAAC785EC516AB4BAB1FAA42092EBD31
-:10BE1000BE487569F5C5F98E679D20F78B534CAE0A
-:10BE2000E339C01F5ECE1F8CEFD4FEAB42192EBB90
-:10BE3000AE1F7DF97C83308DED2BBAE36F8DE21F51
-:10BE4000A8CFC5298AEB38D50BA7B70C8F8771A966
-:10BE50001FE78271BA6B5D2E366E8A4BCB97954B7E
-:10BE60006C585F852F56BFFF68F860C7EF230B8BB8
-:10BE700035419C2656FD98F4903E53C03F20EDF28C
-:10BE800017B0EED832D57547C2B2DAAF3F2406CC30
-:10BE9000D7C0FB16DD78B49D5BF5A1A15D6CBA4BF4
-:10BEA000E4844A4FAA27AFE3F921949991CE3EDA70
-:10BEB000633CEDAF47B2AF80386F86E4467DE787DD
-:10BEC00081283F5559BA149F1BD1DD8971CF7C550C
-:10BED000EEDDB7FF91B2DCC7FF26633C837C437B7A
-:10BEE000A7DF65FE753E2972829331B7B56206E819
-:10BEF000C98F4DAA3DD09007F33E4B4CB89F7F961B
-:10BF0000BCE5CCD1D86565128F4FAE60EB7380FE77
-:10BF100007F3A3769A6EBD2E6DD4974BC8CDC9207A
-:10BF20000F25EB65D8B1250B61BDD7EC9BCC925C9E
-:10BF300038EF5252530F76CA2A99EDA3CE7511E904
-:10BF40000A0A57D5AEA7F3C09EF54B4CDFABFEF304
-:10BF5000C2440677795250F1D2EF1FB5E6DCF63DC8
-:10BF600002ED83F5A0D7020EE289168F99B7420F32
-:10BF7000DFA5E037C24BC8321D1C6ABF2A1CE2167F
-:10BF8000216A9EC6CF2481C775987CAC91F4F6EBEC
-:10BF9000631C0F6A7983A1DC64A8AFF289CCF92411
-:10BFA00043F23D06FAA7CAD25B88761AA1FC911526
-:10BFB000A9A744EA6DB8583D33D413B15E93342E2B
-:10BFC000763D6BA4BFE668FD55EDDAF67280F2535C
-:10BFD000F94B8F3B21E8FBB1D4900CF1AFCACD0FE8
-:10BFE00039014FA7A48013E8FD71508C1A177CB754
-:10BFF0000F5F5EBB007E04B236C5FB0B8FDC08FA18
-:10C00000FA8BCD32E6C5F8B798C366CAC7D5AD0B73
-:10C010006740FC9E968FB1F2C39FC0BEA1BF4D4F3B
-:10C02000CFF2E71F4F863811C524B3B74918ED8EFC
-:10C03000EA4D7F2E043DEE27BDC887C67630FE85CB
-:10C040004494FB6225BEFF77355FC1CFE5CCDFFAB4
-:10C05000C8279097E037F04F59DF7AD2A5401CA14E
-:10C06000437224A15FFE5DF25DD0032A3E4890D961
-:10C0700013755B378C3946E1E9DEF46F4E41E777A3
-:10C08000333E3C1F9AF7AB57DCB1F5CC39EE0F4588
-:10C09000DA05B19DBB8DD93FA49D3D2BE5B013ECD6
-:10C0A000CDCA66D9433994546E7BF6B927C14F7B0C
-:10C0B000DF8C7E5AC5B6DFBC3381962BB6CB4933B5
-:10C0C000D874EC4272842E7EFABF2563237428FF55
-:10C0D000F56F14F768F6FEA789117A546CDFAF90FC
-:10C0E000D1FDF15710DAAF74D9A3D02574AC10ECA0
-:10C0F00095BAAD5F2AE0777DBC4F208332FAB72F27
-:10C100006BFE0DAE878027A423A7531FDDFAD12B2A
-:10C110007CE32BB958CF057A3216BD5EE07AB96A56
-:10C1200097832440FCF30FE6E00CA0E38BF7386123
-:10C130001E27A51AC6D74F3F940CFB7F657220D9E6
-:10C14000854FF6BEEC99FB90DF4A859A64B68FE97D
-:10C150004DE5F1F25498DF82A61FE1FC4A880FF901
-:10C16000AEEC69B108E2C39F4B64DAF628727183C2
-:10C17000CCF69F4E6E3443921F3909763ED8D76F66
-:10C18000891867256411EE83DDA7C671C9622C7F0B
-:10C19000CEF7A546C826D53FB4E8F875D3C39D4071
-:10C1A0009FD343BC83004E8A8700C79700FBFDE204
-:10C1B000D1A983187D58BE01B6A3FABF00DE43FDA6
-:10C1C0004E19F70935EDB8BE64E3DFCBC7A770DBC6
-:10C1D000603D3B99CCF62B8DF35BC2E747FF3A8974
-:10C1E00086BF34F2CDE47DD34A26DFAABC07674E72
-:10C1F00083EF9FBDCDE407DAC1FA41E10A0FC2EF38
-:10C20000FB6F15501F9849389A5C6F92B95CEBBF71
-:10C21000FBA99C425C80C22D413E43844F68FF894C
-:10C22000887FF44B4AD6D3761AFBCC0FE3613D25C9
-:10C23000F25EB37E94723D304DD6CB3F691A785989
-:10C24000F662A54C02605A56BE6F46BFBB729B5C3D
-:10C2500004F33ED372F09D1F53BE3E1352E554AF1C
-:10C260003F8D725AB663B300FC6994D3336574B5DD
-:10C270008E26A7F47D54392DEBFABFA23F55BCF9A9
-:10C280000D78A37A7068822936FE8C7AD021BBA300
-:10C29000EA41FAF736C9EBCF772ABFA97C462DB41D
-:10C2A000A1A0BFFBF851E5B73E7E54F9CD384F3D14
-:10C2B000DE8CDF2780A146E12ADA2DA35F52D9CE9A
-:10C2C000F66F68BB4357E4227EBCB87C9186435727
-:10C2D0002469CB41433964A8EF35948B0CF57D86F6
-:10C2E000728DAE7E65DB418525198575F5CC4B9E3B
-:10C2F000241F45B1EFD575C6DFFA8912007E48EBE1
-:10C300005540CFC9CBA86906F1B3BD22FA5B3DEE1B
-:10C310005E67227DFF9095F9B13D2E5E4E60E5DEB1
-:10C32000814A3DE839F57DAF95C5397B8A7A9D090B
-:10C330001AFFFE58BBE884FDE0AE20CB47ED0F4F5F
-:10C340001DCA4D1789F59DC505A78AF6F425E0BFDE
-:10C3500035881E700DE72FBDDD09FB6E3DEDC36F07
-:10C360009A45DF2F382C82F94C7A6CCE31001709B0
-:10C3700078A5D43C9E3F41FF4E91C02F2742DE441A
-:10C380003BB3AFE7AF36D8C3F67B15CC2F5BAF8995
-:10C390006B69F8BF9CF753D6A4FF5E4E5623FF95FA
-:10C3A0001BE4C1C7FD81A3AA3C64936CB6BF4D9842
-:10C3B0001FCBF5EE5431EBA65914EF3D1D22E6CD0F
-:10C3C0009E6F17493DCCB345C07D4E1218887255FB
-:10C3D0004D7A51DFA978E906B95162EBA3EE9DFFD2
-:10C3E00091F720F0C7CB7F1CF3147D76BFFCFEA82D
-:10C3F0003D50DEF56EFA1F49FFFA05FBBEC27DC453
-:10C400009E7D668C73F5ECFB6DFA83507EC58C7156
-:10C41000AE9E6566DC4709EC730447C2F721CC1F6A
-:10C42000A8DBFBE5189627B91CE9F48DCCFC91F349
-:10C43000EDFFF501E48F9C6FA7B302BB605F1CCAE0
-:10C440008DFF152BFADF3D7BBFCCF3D9FF71F3A92C
-:10C4500056880FF9CF4166ED007E4D60F160FF9E7A
-:10C46000F1CF427E7355EB7E05E2EC05AFFE650C25
-:10C47000E8C99E1DCCDE3927773D03FB6166E59355
-:10C480006532C5F339109EC1843CAB8C2D086445E0
-:10C49000C30BC3430FC503CC8BE2A50CF47B2C7CF0
-:10C4A000A42BFFACF8F8E42EA6C7BE8B79F611BC1E
-:10C4B000085EF6DE11B408387FF67EDF976340CF62
-:10C4C0009C092D457BE452F3BE5661FB2CFF73E6BD
-:10C4D0002D842F67DE73FE69E9CDF8FF43585F07AF
-:10C4E000F69783FE7CBEEB7E2CBFE8F020BC97293C
-:10C4F000FF3FFD9F46F71D94EECE4BD3FDA97FDA9B
-:10C50000795F8AEE8739DD1D2ED85FEED9FB178C57
-:10C510009BAAF3BFD4BC5FF97F74DEAABD3EDD5495
-:10C52000736426AD7F8484D71751385F4B9BFAF62E
-:10C530004CFAF5B731EC91D30A8B7FFC96B03CC135
-:10C54000408AC0F23CB85F5440D8BA5E90598A76AF
-:10C550004641E623681F10A9E64836C5C7F4F4052E
-:10C560001E960F3616CFA15C977AAD07E38106FFC2
-:10C57000F0A040BC900F5D70F5F51DE0AF4C499305
-:10C58000C3E631F83C06CF43CE69ECBD5DEF17CD75
-:10C5900000BF46E3E75DEFD67F2FE4FD4D238B8F91
-:10C5A000CCA4E34F4B135D416837A94182F9CCA07D
-:10C5B000C2DDA0D90F2A34F47708FC5A4DBCEC6FC9
-:10C5C000C55F9A99F991BFA5E36703FED2648C0712
-:10C5D0005E127F84E57F5D979A8DE75188E441FC88
-:10C5E0004D1F5CC5F1C9FC6689B797ECF59D20B776
-:10C5F00012A17E2FB3CBD05F56FDDE587826DC8F9C
-:10C6000096F8902ADEA53419F35535FD213E547A6B
-:10C61000FCAD7450E9F7F7D2E39C811E699FB92401
-:10C6200090CF026EFF4FF9AC53C4729A47C2FD28F7
-:10C630006EFF4FB2274860FF5F2B1D15412E4B2D1B
-:10C640006DD3214E6FF108C8D757769BD0BFB1E4A8
-:10C650000A88F7CC4609CB474DAE716068DFF8BD5C
-:10C660005D671E20101FF62A68789322169FFFE64A
-:10C67000DB6F27AAE735F03B213750FCCE6F2261F4
-:10C680001B9DE7028904E21321BE2B900F75F15D1B
-:10C690007D19FEBE9F1CE9E752F563E9917FF473B3
-:10C6A00017D55B1F52E6D80D4FDC57A12CA1F18F97
-:10C6B000BFDBCEF0E53F4282C3502F78C522CDBE0E
-:10C6C000D92366A63F76FD69470EC4C526F564C525
-:10C6D000337D3A02FD023FF70BCE13773CE41F9CFB
-:10C6E0006F1F1E8FFB821DA2C317252EB395FBCF94
-:10C6F000FF0AF914F4D9B38934C0398C1ED28BF1F6
-:10C70000D8C0264BD4FDDDFBCD6ABC89D38DFE8914
-:10C71000EA792337E68B04E2B574EB9EF1B134A6D7
-:10C720003F1DE0EF43CD7EC9DF8B5FF0D701BF5BDC
-:10C73000AD5D85D1CE83ADE0F8BBF1C05718C7BC65
-:10C74000BABDD904FC7BF526936EBF3160E67ED777
-:10C75000583216E0BAF180D5910B74E9103D903F44
-:10C76000E86FFF44F145D9B732E213FA87B8F83ED3
-:10C77000338BF3EF9143F300AF7BCE5A303F67B773
-:10C78000D250110DCE2BAD4CCF2D20A17BC664FC19
-:10C79000F3E177528F3D3C19FCCC4D84C7318CFCC2
-:10C7A00047908FCF6F21783E14FC52D00BE75BD8B7
-:10C7B00039608A9235E04F5379FF81362E7365DBFD
-:10C7C000F67F053BA0BA5D7041EA6CB5D4A540BCCC
-:10C7D000D5DF9620C2BA9BED56F32A5DA36FD5C86C
-:10C7E000C53E33CB373E3861CF1D30EEA7DD0A01A1
-:10C7F0007BC4FB5AAF13D6ED4FDB73E2A3E5CDABA1
-:10C80000CF5FD792E95324E88720DE8DFC90D56274
-:10C81000D395BF27FA06837CDD68EEBAD713857EF1
-:10C820003E0BE3B3CBD66FC1FFCFF4DBDBAA7EF3C5
-:10C8300089451A39CAB4F4D36F83A2E9B7C5827B9C
-:10C8400010E07DF1DEE18380AE8B0FCB03A3E9B76F
-:10C850006DB56C3FEF259E0FDBD34AF5DB351AFD36
-:10C86000D66AC1BC3863BB448B89AF8B97D06FC18C
-:10C87000FF1EF9DB06FA2DCA7C475A98DE50F5DB1D
-:10C8800098F663A8DFC6B49A7479A369964BE93722
-:10C8900061E0AD600F77C89EB828FCB38DDBDF2F59
-:10C8A000F13C3C1807F4DC1D16B6BF79B97A2ECBE3
-:10C8B000CAE87D493DF7DF846755CF2DDEA99E7319
-:10C8C00034F221D3738B77533D27003F323DB77845
-:10C8D0002FBBC7C1A8DF32FBE93782F5ABC3ACBDC4
-:10C8E000BF2D63C31CDADF58AFECB1D0FA6323FA73
-:10C8F0006E9C56DFDD6161F72EF4D3771D97A7EFAD
-:10C9000076727D47F5D830D0AF46FEF0B4EBF38EAB
-:10C91000F78C3FD9F26B9097D745DC373CCACFA54F
-:10C92000BD31FE642EF0578B85E9DF3ACE7FE76A92
-:10C9300003D87FC16B6C7E5576968F5CDDCAECC3E5
-:10C94000EA1621E8A6FF2C9CF09502F02FDC2B9034
-:10C9500041B43CD3CCEA93E7D57D2F32235BC30FA0
-:10C96000F3F32B306E3F5F221688CB57D80B3F86F0
-:10C97000787C453E8BE357F0F70B0F77D5433C7B34
-:10C98000E11302EE7B129E0FA0E63796B62FC57814
-:10C99000AD312F40D5E70B83FAF715867CC6663E8E
-:10C9A000CF996217E285BC2946CD4B6836E2A38356
-:10C9B000E3639388EB661F3E287EDC19FDF1412975
-:10C9C0003A233B3932FF85AFD379E546E6A5E2C38A
-:10C9D000383F35EE5CC1DBC59AAF8ABF7EF355F1B7
-:10C9E0006998F7B3A037402164931CC88BA17C8061
-:10C9F0007A23F03B11CFEF174D1A3948AB87B77246
-:10CA00007D9ED330A9209500BE480DF04D49E3A28C
-:10CA100043A974DEE3DE738F85E5F17B13CC3ED84A
-:10CA20001FDD6AED45BDA6F2D5D79CAFDEE178DC0F
-:10CA300033B806CFA9FADB0417D815FEB015F1E715
-:10CA4000A7F883F32B7E7E7ED14FF90BE4E9E01348
-:10CA50005F307CED15DC101F2F54D71FC03FAD9FFA
-:10CA6000D3CEF0EF0F0A88FF5CD28BFB23D58D82EB
-:10CA7000274CEB57B72DC2BC0755DFD23FBB961EE4
-:10CA80001A7E94A2F12356D2AC7F15BCDE8DE686C9
-:10CA900077803F6F7C5E26CD1AFECCA4FF7D1B8580
-:10CAA0004E2A3E2FC59717389EB6011EED80AF5E09
-:10CAB000663F85BFC27334EA77BF14D0E1B1E0C9E5
-:10CAC0000B17C5D338154FC0A7A0A7DA8B452897F9
-:10CAD000B409644046FF79C2FEA4566E17EE3DC607
-:10CAE000FA7F5AC07B4B8C7CABCEBB1FDFC6E057B6
-:10CAF0003897067ED1E5F2EDD706BE7DC3DA7B24FA
-:10CB000007F876AFC0E207ED09BAFDC5C156B6FE1B
-:10CB10006FB552FE867DADC3B267A3BBBF7CC7F1C4
-:10CB2000F50BEC7EEDB9A4AB602290F7B8C5827925
-:10CB30006408C73066576AF5EA362B19786B6EECD5
-:10CB4000FE5379FFB1EC1AB53C1AC6837CAF363A76
-:10CB50005E66643CA35E57FDFC4BCD6BD4DF39AF02
-:10CB6000BE3C4CD289FB4E1992EF51B3260FEE36E4
-:10CB70009E67442140FB4A532FCB72917A24C5858E
-:10CB8000E79FEE71A97CC6F2DD8B781EFB5471E243
-:10CB9000BBB07E7EEA65FB7CB926F2FB89A09F27AD
-:10CBA000CB788EEFD32332C66B3F9DC2F2386F7ABB
-:10CBB000FDA004719A9B4039517CDC344E407F05C6
-:10CBC0008E61C1BED92E6ADF7847E17C72E01C57C6
-:10CBD000F6A68602387F3C764BB00E9E9E82DEA47F
-:10CBE00037008F93440278ECF40E2880FB93EEF923
-:10CBF00033C1FB43E83A8BEDC7769081506F827763
-:10CC000020BA03E35BD717407C74E641BB1DEE6797
-:10CC1000C96C32519F2182BF09245807FBEDE38F75
-:10CC20007B6F0178CBA8BD0071E7B2F6E63A279496
-:10CC30009B048F9BF6EF0FF80A9D741EDB1A3F29A9
-:10CC4000FC0EC823AD07DDF89B583DFF26B87808D9
-:10CC5000DEAFC33C9B924D021EFCDA16148885F5AC
-:10CC60001BB4D07EB735D1F6B9B04ED0F6D0EFA612
-:10CC70004FDEBE05E4FD88C8DAB7B07DEA12DACE31
-:10CC80000D7CBB6911F6B7B0492029B4BFB216B606
-:10CC90000E941D913DF0BD75FF13B88ECDA0E3A598
-:10CCA0006680DE0F4F8132C9115C18EFAC1C8574B1
-:10CCB000EBE1724E268E64FA43E065EE37A876D338
-:10CCC0003B5696EF5BE259AA0CA0FDBC913F3003A6
-:10CCD000D202FC6D9FE0FEF3718A671FEDF228CF50
-:10CCE000DB3898FF91D2A559873EB5B2FBADE6B7C8
-:10CCF0004DC27C8605A408F3196E1CCFECB537AF86
-:10CD0000B506E18A8337E5DE34787FF05A33DABF3F
-:10CD1000E7B6C9C847E78674617CFA64938CE786F6
-:10CD2000EB9AD8FD5C275BD83A2E3ECDF6F54B1D2D
-:10CD30000A960F36DD5208EBDBC94DECBC63C1D35C
-:10CD400053152897360B1E767F11D38FAAFF56E214
-:10CD500062F908AAFEABE2F3EE97B768D07755EA1E
-:10CD60007A63D07755B0AFEC84A7FEBD9FD8991EEB
-:10CD700004BB1FE81EFE0AF9B7FA884CC0EE173E46
-:10CD8000EA2EC47CACBD02C6F3C7B70B5ED8D72F62
-:10CD90007BCF1C447B35587CF74F408FBF6F26827A
-:10CDA0001BF2DA29DEA97EC837F7FEE917F4FDC7C2
-:10CDB000472D900943F9A418F1ACE67FE66E667939
-:10CDC0002CB947D727C3794B326500EADBD24691AD
-:10CDD000F8347AE363C17BCB8F995EC6FB2954FAA2
-:10CDE000E52A0D25B08E0DB731BDE4DE2C438E084B
-:10CDF00039CCE324D49EC6F3B70B77AF4B5668BD4E
-:10CE00007A9EFFB170EFBA6491BEAF83F58BD65FA7
-:10CE1000A8B0FE17EE135CCD9AFED5F66A7F6A3F86
-:10CE2000CA6E7D3FC3F7F2F265F6A3C2A18E1FCB97
-:10CE30001ECFFFF70BEBE1BE98FC37454C3ACEFF17
-:10CE400068C670ED7E87FA54E3AF796F9B8857838D
-:10CE5000B7FC3FD98857C317ADE3A87C53BADDD0E0
-:10CE600026040194D671C794AA5C2CBB409EAB7972
-:10CE70009CB67A0ADBB76ACD3EBA1CE47B46AE802C
-:10CE80007C40023E654012DA416ED85F28CD65EDE8
-:10CE90004B697B90BBD627981C527DE0067D51DD07
-:10CEA000B4AE10EB6F12DCD07F6B7331AEF765F967
-:10CEB00022C1EF9B8EA1FD51D6762C09E495CAE7DD
-:10CEC0007A587FAB279AF13E2F55EE54397E53E6C0
-:10CED000F735595CA321AFFF41002A8AFC8A470835
-:10CEE000F3535B6494337F3E93CB37B78928CF07E6
-:10CEF000AFBD1DE5F0DC6621861C1728702EF96495
-:10CF0000907DEF93E3AD029763A61F4EDA995C170D
-:10CF1000C07790E39D02F707993D689463552E2FE3
-:10CF200025BF155B0CF21C436E3BA5AE5B61DC7B41
-:10CF3000AEB522DC05DFDFFDCE3DA87F64CCFB284B
-:10CF4000F8FE03C9A0EF4A2496AFA4E2B14A62F901
-:10CF50006CFDE058BF5449BD2C78F4703C657544B5
-:10CF6000F487087CCEEEE10A6C9291CF8D72F8F7CF
-:10CF7000CACF3F4A9E0F73FE51E111F7B2F6903FC0
-:10CF800016A678FA6DCBB398A77AF6856337029E1A
-:10CF90002BF650BEA5F33DD7E2E0F7BD04719D2905
-:10CFA0006F15310F9C48E1BC5B1C5AB96479481578
-:10CFB0002F39903FCA77B07CD2F2973F1A837922FB
-:10CFC000CB7A31BF2AF002B737035D6380AFCB2540
-:10CFD000960F6594F35B6DCCFEECDE1D370BE621FE
-:10CFE0006C61E7F4CB43B7CBC0876ABD1FDA64B589
-:10CFF0001EEE5F0628DFC2FE3AC0A73D77AEE641CF
-:10D00000756F65725FDE26A3BF54BEA519E3D8FE17
-:10D010002D9F609E7BC14BDB307EE06F13F5798FD7
-:10D020005B44DCC7A24FDCAF32E61F56B756E17E49
-:10D030005B7588E7F719F2DF2A5EDAFB7280A2A639
-:10D04000E2D7CF3B410F9CEEDCEC047CD2FE306F8C
-:10D05000F0FB9F49BABCA8D8F9BD5E7D3E6168650A
-:10D06000D47CC2D3F00FCAE00FD838BFAA79985B3E
-:10D0700006F03CED705E5194F87DDFB99D6D9F3FE9
-:10D080000379EEDD3BCE3C037057FEF5D367209F5E
-:10D0900089ECB3E2BAE47FE1F79827ACB6FB858D63
-:10D0A000FBF95B9FC7FCEA73EF9BD1CF39B7F764FD
-:10D0B0003AE4AF9DDBFE5532C4E3EEDD3B15E3956C
-:10D0C000F7EE2C1844A2E877F5097C19BC8CFC6EAD
-:10D0D000231D0EB61EC4BCABB3EF99519FF5E58579
-:10D0E00086AA589EAD9BE783B644CFA357F318ABEF
-:10D0F0005B6FB9E95AD0CFADCC9EEBCB6BBC541E65
-:10D10000E8DB949ED75C06DD5A789EAF816E67E1BE
-:10D110001F943E2103DD3E6F5DF0AB27E15BEB80AA
-:10D120009879A0E1CBC0979AA7FF739B778F0DCE1C
-:10D13000FDED880BA4307A05670860EF7D9E0EE751
-:10D140001A4EC9BD98EFD1BBD7EC827CC6F2BDEFB9
-:10D15000A27C9CDB7914E3AA84E7C99F237D7F2C02
-:10D16000AF59E0F3DBE460F9A31CEF905FEA76E2ED
-:10D170007B9E47CAF856CD2F8D9557DA6B1BC6E2BA
-:10D18000D0FCDC4015F593F8BD597DF9A6423ED0A0
-:10D19000E9982E4F579DB7B13F17D79B91FCE8E810
-:10D1A00079BB6ABE60844E6C1D51F39FCF35F3BCD2
-:10D1B00069FA3E6D2CE4C1B1F5DA1F14DE2551E4A5
-:10D1C00051CD8F3E6333E445072F2F2FFA52F0FEE7
-:10D1D000EFE2E3031B8B57AB78E9FE26BA3E56E23B
-:10D1E00098DD49FD53390EF705987F7A37F74F558B
-:10D1F0007CA9F0D68798DDD0BD85F9074679AE8E3B
-:10D20000715F52121FA7BA6DFF18D03BDD0776730E
-:10D210007E63FC5CDD728CE5DD52FD1CD4EA677E2A
-:10D22000BF84B1BF74DE9FBF3D7A7FFE964FA2F6EA
-:10D23000775AF2DE0EF09FEE6476D2E990382DDA5E
-:10D24000FD36963859973F50EF60F765884E1BDAE8
-:10D2500047F73AF2DF8B4F82A782793D754B791EF3
-:10D26000D0CF3C78AF689D633A01781E02FC68E23B
-:10D270000CB2CB47C04E93538A72457704DE3E7A98
-:10D28000249948504B7F299C06FAFC83EC9332F496
-:10D29000F79F86F8C87F4AA47E1085EB3F0382671C
-:10D2A000A93BB65DAD967D3F1575F18C6A73EF07AE
-:10D2B000609F9357ADB81F2EEEB306303EF60CBB01
-:10D2C00057E3E0CE2F9FC37B797E6526DC2E14408A
-:10D2D0001F94F238C5C99D5F3EF35F604742633AD1
-:10D2E0007EE933B43ED8CF2D7168EFF7EC881F0389
-:10D2F0007180D2571FBC11F44529E83EB0335F1A44
-:10D3000014ACA3FD9D18C8CA27B60DC17301153B07
-:10D310001C984F7870E7AE6AD0F7E75E8A23A0EFDB
-:10D32000CFCA5D7F85B27F4F3C6976A3DDE7D6AE7D
-:10D33000AB0B89E4D6DA731550D6E5B710CC6FC1C4
-:10D34000F81BE5E78AB6783CFFA1A9C7E539309814
-:10D35000DF133518E48EDA8D6E7DDE33FB3E3F8EB3
-:10D36000E92FBFB9F77E761F02ABEF577A4B58B95A
-:10D37000613093DB4EACBF48E557FEBD7FBFACBE0E
-:10D380003F8EC50322FDB0F6D56676BF8691BE3FBF
-:10D390008D13F879DCBF5C19EDFE8928F0B37BB9F9
-:10D3A000041280FB57C9762BE669552AE15190AFEC
-:10D3B000FEB2C2F63F2A9DE15190AFBE87EBBF4A55
-:10D3C0001B2DD3F783391C501FCAC4D2F522DEEBC4
-:10D3D000B4CB8AF7E155BDEAF0A29FF0F297279E01
-:10D3E000CA857CB538CC93AE7AF55F90FE55E6F0F1
-:10D3F0005DC0FFBDDBCD783F69F7F6C3E9603774E8
-:10D40000CBE1F4C48BECEB5485CCBA7D6A751EA7D6
-:10D410006B974C8073BCEA39C3F218FAE2F5389680
-:10D42000D7D11CE7FD15D373FAFB654ED7CED2DDFD
-:10D430009B586E89AEC75A402F68E27862E45C61FF
-:10D440000BF47B9674D50FA624A9127A717FBC7C4D
-:10D450004B461AF8BB07AC57E2BED501D98DFE206A
-:10D460003CB5FAF854AD2747C2F3F499391285A3B5
-:10D47000A7F99392C104F203ADB3A2E9A7BD7171FC
-:10D48000C84FE51673D4F39BBFE3FCB60DE46D1CE7
-:10D490001BCF931519F7801C54008E897637CEA7C1
-:10D4A0009CFA01EC9EA8D939DA73DB0BA506AC47D0
-:10D4B000E50BF1B190AC5772EDFDF5CAC225B93953
-:10D4C000520E2AACAFFBF84D8CD0890492D04E920C
-:10D4D000380DC9FA545DBEBF241759005F0A29727E
-:10D4E000492290BA01E5D44642F8B4533384AD439F
-:10D4F0003504E2E3A7F8FEAC59723F8AF7CD748891
-:10D50000A8CF2F85B777E39C08B759AA211EB43757
-:10D5100066B8C01E13023EF22DE587BADA6939EC0F
-:10D520005C38F142BE1BA6BE51F89CAE435F817DC4
-:10D5300040F98CDD63F57D12ACA3E3C131638CFF50
-:10D540004D66F7D91BC7FB86D38104F6EBEE3B870C
-:10D55000BF5EF5FE3CF0D7E3FF9A0FFB317617096B
-:10D5600083BD146727E1B831704F9E745A2BBF4EAC
-:10D57000C2CAC3283B835E734DD47F37F235F1486E
-:10D580009FF5E94511DB7F6668FFD9C5DAABF8F096
-:10D590005B367A8EE744F062E373084CF65CE8028F
-:10D5A0007C8C717AEA808E4AEF070F023EC6D899CA
-:10D5B0003F98D448B4FE5A8E9DE9ABE5FCFE69FA6B
-:10D5C0005764D7F4475C168C8FAEE478EFABAFC6E8
-:10D5D0004DFAD5B74A80D77EF5ADB1EADBA2D77751
-:10D5E000C482272E3A3C0931FA0F44AF5FFDEABBF3
-:10D5F0006F84DDF092E90D08CEF373CB3976F0AF8E
-:10D60000E23F482E665CC1F6030C74B301FF517E05
-:10D61000B08DD0BC87FFCBD2D06F5814FA9330F2C4
-:10D620005D31878796EDA914BE1F7370A76C62FBEE
-:10D630009573EE6571A21F5B587EE9317E1FD09C09
-:10D6400046E657CF59C2F61149193BE7E3A2FFC19D
-:10D650007877422794DE773608C17006DC5B63B0CA
-:10D660005FFBEEC759A840FD6243DC45E527F53C6A
-:10D67000D23C6E5F6770FE5C407A1D20F7C673EF88
-:10D68000AF71BDA6EAFDC03A9209E7F64593CD0316
-:10D69000FBA3223F674A9CEC3E3FE21DC2EE97533C
-:10D6A000F3B832DDF1B0BE91107FCFF759165FEFBE
-:10D6B0001EA43DA7255DB0E1FD2075B22705F4A0AD
-:10D6C0007C81DA75D455532E0C236ECD39326ACF56
-:10D6D000A170CB2E765FA2E42A22A56007F2FB019F
-:10D6E00048D2F43EBBEB4D8A87C5EBDC786E758182
-:10D6F0009DD999BF7014DD631F07F665BE87DD7382
-:10D70000ABA76360279B5F1DCC2FA33FDC758AC747
-:10D710008376E7746A31601CC783BFEF209ADDEF20
-:10D72000BA411EFF4D66BF57D00F0F8C7EE7931294
-:10D73000F15EF6F9CE551F009FAEE6F711AEA8CD0B
-:10D74000C4E7AADA14B43BEB6B3DF854F162F13450
-:10D75000E0BD6F9611AC3F8BCBC7EC0A6ACB403E65
-:10D7600085E4AA0943D9925643C0DEB5F6E1A70184
-:10D77000F1A3F4957D5836BBD8EF46C88D3310CF52
-:10D78000B43D29A5DF173B7C4F829C58DD57EBEE5B
-:10D790009133A78C35DC3768C09BCA1FDB18FED6D7
-:10D7A000088C3F8CF85B2377BA615F79CDF57DF704
-:10D7B000CE20FEA879CFF0F73BB6CF16137FAE444C
-:10D7C000B45FE7E7D5DF55475F3DC2F7171FAECD22
-:10D7D000477CADE4F7483E54EBC5A708F8A3F33304
-:10D7E000670508DC8FCE7E1B823EED455EB87F1656
-:10D7F0007817F027DA193ECD2935B8BF66B1337CEA
-:10D8000089F600E245B6337C8976C66F0A2F4B80D5
-:10D81000BF1C6C8FEF29FE0E007F59D226E8F0A5C1
-:10D82000244DBE3CFC3D41F147E148E2F265C44372
-:10D8300092C2EEA754E52A961DF7389D3FACDB1B3C
-:10D840006A093E07C6F0178739D8BA9964AAD92F52
-:10D85000033E12095F4F02242D8FB0D443F84B09C9
-:10D860001037940506076918A2BB57527449867B86
-:10D87000D9DC1B800FD61F964D902F2F2E99AE3BD3
-:10D880000F2ACEF226B8119F3EBCA7F9915A37D283
-:10D890006F1DD011EE01E5FED7439C9E0FF37B2850
-:10D8A0005772F958C3E5E5512E2775FCDEE4D5D350
-:10D8B000589E5552B689DF571626DA3CA6044F8883
-:10D8C00028142EB4A9DDF8C47B16C97BE6E048DA3B
-:10D8D0002E2E8B78814F12DE7B20C8EE6B2C4A05F2
-:10D8E0003B2841BD7F71A23B61361E840D4BCCEFBE
-:10D8F000A0AA10FD984E53B47BAAEA3C072C100F47
-:10D900008D054F9CC79BF1101D2FAED181F6FB00FA
-:10D910005FD1EC05B46C6F8CC3F85F1CFF7D163BC8
-:10D9200085BB5443EF58F7506F745C1FEFA0F4743D
-:10D93000018CF4F958E370FC5D96C7E522FC1D9755
-:10D94000C7F97AAADE73AEB6FB9AEB4767EED53A13
-:10D95000BF75BDECC576AE897AF95FCFF56DE2147F
-:10D960003D9FABFAF6789FBEF50D0378922F4C41A0
-:10D970003D96747374BD5B272B786F79DD6826E75D
-:10D980008162859D6BE9AF07304E7DDE376A23E803
-:10D990005195AF9611A67702C4E6C17588DF6FA3D3
-:10D9A000DAC12BE01E40AE5FE1298E60BF3F903CA4
-:10D9B00087DDE7BB9ADF63B596F215C17B4F3DF873
-:10D9C0009CEE60FB13CB2C63F13EB53ABB09F584AA
-:10D9D000F4BE39082687B47FBC0BE20592ECE9F46B
-:10D9E00042BCCF2185E0DEDC3A7B2EDEFB2E24E438
-:10D9F000BA80FE5F38E60FBD583E1D9D28DE97E9D0
-:10DA00004A2A221F66E16E009E5F915D3713881BD4
-:10DA10006E48AAB102DEC63B585CBFB1380FF14870
-:10DA2000F17B936360A49F41B3A6F7DD8305DD6EB0
-:10DA300088710EE60E07B397485A808CD0C879A338
-:10DA4000FA3B27EE00C9D4C8FBB2918504F687FAE9
-:10DA5000CB790C3DB699E9B1E542743DA6DA99AAB5
-:10DA60001E930DFA417DD60F9DA63BA7A524798074
-:10DA700077E1193079C0BE7BB9FE8E04C4430DE056
-:10DA800081A44CEFF35F7F300CECC7BCA8FC66D4DC
-:10DA90005FF3FBD6736F32D0E994EC1E341BF8E9C8
-:10DAA00070F4F57CD263573D0A7C30FF77A2A0DD8D
-:10DAB0004F29BDB002D7D3920BF9F82C6B9C867C12
-:10DAC0004F200AAEF1C34E36DDE704B84E36F23CC5
-:10DAD00080263908F919271BEFC3FB4A20CF5BD4F6
-:10DAE000ECEF935C37DA97EA3D632783F738B5FBB1
-:10DAF000BB25BFB07AC16E8DC55F254DD1FD7A586B
-:10DB000043217E4A01CC047B98DA37BD61B07F3671
-:10DB10009A3D011229071EB346CD4F5CEC98FA38A6
-:10DB2000E07DB1C3FB34C839B1B37B4163F3391B2A
-:10DB3000F7046C02C37ED3933C4F53F239B5F7BB65
-:10DB4000F5DDC7C9E324C412E3BB4DFD7D8318DFB7
-:10DB50009D2C9F83B8A27F57FD84B8889FD006F381
-:10DB6000A86A3C53FF3EE289FB091CEE533283FB5B
-:10DB7000D47366F63B3706BE38C5F347160A0CAFBA
-:10DB80002A7F9FEAB3777C780F8D91FF848D576D44
-:10DB9000184FFBFDB443C6385C25E51FE01B61E36D
-:10DBA00078CC5F171E1BFF28E4257D7644C4EFE583
-:10DBB000172CF8BDFB679E0D7320CEF3BA8CF7755A
-:10DBC0007FD631359EC579F471E8054EB6CE9FE615
-:10DBD000725F726115F2671F7F342C5040AE4A2E7F
-:10DBE000AC457BA6648B80F7449240EFA14912E7D5
-:10DBF000C309D0FE6CE132C0F7C406DCDF28DD6C5F
-:10DC0000F6AC12FAD3F9B4C3ADBB57BDB46B35F65D
-:10DC10004BA83D95A4D9EF3EC5F3804B2FB0FB0137
-:10DC2000892B405280EFB9DE89F0AFFEDED76E6BF4
-:10DC3000F438FBD7DC9E29B93041E73744E6F77D5D
-:10DC4000269F7C3D2FEDCA6770F5CD67C3F868F35A
-:10DC500089CC6322B6EF4E883E7E06C7F389DA325E
-:10DC600038B941CA1456AFA4E13E05F449495342BC
-:10DC7000A2A099576963852E0FA3B4A95899ABE95F
-:10DC8000374207DB6F278D88D02163AD7CDD323BC7
-:10DC9000ACF7450E278CB77161DE4FDCD01FD33F48
-:10DCA0001FCB0DE935A85FEE71463BD790E174EBD1
-:10DCB000E24AA58D9C3ED44ECED5D047A58BB1FD72
-:10DCC00089E6D2BC9F403CF909762B486CBD63A025
-:10DCD0005B4674BC4DE8C35B26E6035D1A6FDFD17B
-:10DCE000E5FDF4C31BA7AF8A17F53DB58F72005F42
-:10DCF0001320E03410FA61F4BF14BE22E372FA4F2D
-:10DD00008A3E0F5FDF3C969000B51FE65F721E0FE4
-:10DD10009280E522F350E94FAED6D1DFB776E475B5
-:10DD200020872ABDE71F7802F9773E9547D8973FAD
-:10DD3000D9709F6E7D88C01783EE2302242BEFFFDE
-:10DD40001CDD3F9603E990F71558C7D691531B1F6A
-:10DD500049D7E279B163D202A00BD934F0B2D68FA1
-:10DD6000C0644F871BD72519E361BB1D3EBF93BE1F
-:10DD70002FE37EF5F284C251D1D67DEA174E84F8A6
-:10DD8000735DEDB489106F93B9DD08BFAC05F6265D
-:10DD90005C811EED7EAD064ED7876A6B307E4D2CC2
-:10DDA00001E2D29EF725CC2EFA9AB0788BDA4E910A
-:10DDB0007D2E887F2A0229427B4EF2ADC8C8853865
-:10DDC0004652764083BFB54E66D7AD4E39E0827C71
-:10DDD0005233ED1FE2319634E9BC7E9F9295B385B4
-:10DDE000F132CC474E0A118C6766D1F71A7C2B4969
-:10DDF00014CE8BF89B92C589FB451261769A3A7FC7
-:10DE0000FA06D7B387F9BAB40CE2B849608799D05B
-:10DE10001F5ACFE394BFAC2DE27890701D3327B02A
-:10DE2000FA4A3C83DB0A716B11D6D530961D70C35C
-:10DE30008E885793E1EF8F261037FE4EDF0012AE2B
-:10DE4000C77B4C2675DD0FEFBD71BE2DC0075FA4EB
-:10DE5000767E20401CBAC87725ACBF8D6220DB4D92
-:10DE6000EBFF4AECCD867AF0FB5EEF25B2E750C8B7
-:10DE70005BF669F6A5D8BD9C6E6D5CCF581EBA44A2
-:10DE800032ECD77C73A5F67B739C7717C091F49125
-:10DE900080FB30755676AF4F9DE3B67858BF8F72D2
-:10DEA0007A21FD817F3A981D735E72C727627C33A9
-:10DEB00033E735DDF81E5D59E2FEDB26CA8F92E6B8
-:10DEC0005ED61192D704FC32B281BED7D22F4A5C03
-:10DED0002DD18ED7DF46DD8751E1A3E312C09F78B5
-:10DEE000A190ADAF063ED82330F8030EEE6F9180BF
-:10DEF00008F49CADDE172C2D6765F5F722808A1497
-:10DF00008EF7D5FD05B29C95F93EA57F2EDB8734B3
-:10DF1000C233BBFDE14E88EBCF6E4F9D07FB53B381
-:10DF2000EDA3FE0CCF3D72EF8138B003EF13F0FC90
-:10DF3000C78F7FFF9A1C479F3BDFDE88E78DCF723C
-:10DF4000B9BB8BF4E23DEC3EE2E2FBE4417C3F17DF
-:10DF50007E600ECB2119FCF439E1E08F6EA0A53B69
-:10DF60005F0BDE0066DB5D1DBDBF0135E00BB90A4E
-:10DF7000710F406DD7E639C4CAAC5D040F166E8FC1
-:10DF80005A705E91795B100FEFF7E58D07901E7D5B
-:10DF900078E2F72AA978E99B77FC6DD321CE1B4B59
-:10DFA0009FCDB667FE996D7E30B88C78FA0C3E51E5
-:10DFB0003BF233A7D71A4FF5DB474EAF0D9E959630
-:10DFC000DE746918CA8B13CAD5A26F6832C5C3D96B
-:10DFD00021BE2B07023E3A075C961EFDC0CAF40024
-:10DFE000C94DC7F9A8F7BE1F7CE0A403ECCEFA9D8B
-:10DFF000EFA6C3B34AEC5A733BC63745F487CEB796
-:10E000005E79D1F3611F40DC89AE7F23E3553E6426
-:10E01000F3BB9B9FAFB9BB350ECFD7DCBD44D4DD7E
-:10E02000DB7CF712967747A4CE31B7EAECF5E53101
-:10E03000FB813880B19F794B26938F06C03EAB6B36
-:10E0400012C6059E61FC356F8A57847CE4092B0457
-:10E050008CB78C3FEE6EEBA2E579C104FCBDA379D1
-:10E060000F2CCE817B08AA3B597C6F90B828FB67A8
-:10E07000103F39C0D671282F02F9B67BDD764DBC32
-:10E08000BF5BAEC9867BF70277DABDC03FC5B77A02
-:10E09000DFC7FB1C781C425D57773516631E6BF19A
-:10E0A0001C773ED0BD3864C5DF1F2CB610C946F5BD
-:10E0B00058B1442CF01CA410C90A4F1BB1C0336FD7
-:10E0C00019BB27BBA47126DA07CEFC2205EEBF2DB3
-:10E0D0006E7FFE73685F2A85F7B3732D0C3FC5ED25
-:10E0E00087BF02FE59E02DC2BCC3EF6C5174FEDF46
-:10E0F000E890BE7C4D9BBE9C1DD697733AF4E5AD6F
-:10E1000070C799C68E38B0D78CEB44C519764EEFE0
-:10E110001501D62688079B519E0A2ADAF3603FFA3A
-:10E12000CC8B0E137CDFF317E6F7F66EB5E27D6F4E
-:10E13000FBFF602336C82B7CC9BA11BE9FB185F2A4
-:10E14000200E47EBB3DFD92A0A8D02FFEDE5AB5570
-:10E150003F3D3806E6F5F25F599E4CEF5633FE7EA2
-:10E16000CA99DDCFBF08FB6267B65E8176D62B42C7
-:10E17000C004FD065632FA1BF9B4628BDE2FBE3F97
-:10E180009EE99B1E81E1FBCA46FDBCAF0AEACB3F7C
-:10E190008F67FED45CA2799F01FBF7EEFA14585703
-:10E1A0009F8D7EDFF0435C2E5E784151F956E4F797
-:10E1B000B311B7E6FCD29EC8FEDDBD57405E05E058
-:10E1C0006258E47D85615CB5FFA278B60F9FC4F705
-:10E1D000677A5F17113FA70DBF5BD867D7D5D6A465
-:10E1E0004ED1AC43258DFB938BC13F6ADA9F3C57E0
-:10E1F000B3BE546E3D987C07E62549F8BB4C95B3F9
-:10E200009F5B3B2109DE8B218017BE43DCAB3BF4D7
-:10E210001B27D4A3F6EE585183F7D2C6FB52A7684A
-:10E22000E4F46FE54B559E2AB97DB22BBFB310F2D3
-:10E23000C42B1AD9EF3755847E740BFCFE22696219
-:10E24000E74CF324522452F9A9DCFEA31FC2EF715C
-:10E25000F99F1EE701786817B7C2FB8A964FF03C1A
-:10E26000C12AC3EF08A8CF7D9CBEB47ED844EBAFD3
-:10E27000BACD5E06FA89F6FB1A940F646EC4FB4DA4
-:10E280009CA7589C96BE7F0F7E12E5D4E4C01B77F6
-:10E29000D0A66748E89D1B3260DE7A3EA37C2B80C7
-:10E2A000DDD5BB59C0DFB5A59656DECD60527B9754
-:10E2B00062DE2DFD7E77B4F3CE0B83FA7E8CF4FF05
-:10E2C00003E75FFA97A9E52363BD013302782EB116
-:10E2D0007209D5771A3BBFF27803DEE7681C078323
-:10E2E000709A7C03582FDD28DF56F5FE21C192C7B6
-:10E2F000F36687B332DE5B08FC4A19A5E26A32C5D1
-:10E300000DF8BE994C83E72B4278AD28323D8171E0
-:10E31000A06D71A827BA5D5DCF3D05FCD5321AE32B
-:10E320004F83F979CF6E7718EF79ECE1F1C96E1769
-:10E330002B97B75B310FE6CC5905F5E8D2D04127D2
-:10E34000D0A3FB45AB097E97F4CCF60193214FB2E5
-:10E350003BC4EEFF3D1D1A80BFFF1A6BDD32EA039E
-:10E36000759D3C06FF84F534DEFB35ACB76439CBD4
-:10E37000231D34A0263BDAEF49A8ED92949A6CF065
-:10E3800053FE17A753B28F00800000001F8B0800B8
-:10E3900000000000000BDD7D0B7854D5B5F03E7316
-:10E3A000CEBC92996466324926218F09841020E000
-:10E3B00024860814EB24040C187542D1A2B63880C8
-:10E3C0004080BC44DB46A55F2624424251428D0872
-:10E3D000087140B1F48A6DB0A8C106EF80F86AB543
-:10E3E00037DADE5EB5FDB92370295A1E23F452DBFD
-:10E3F000DBD67FADB5F799993349AABDF7B6FFF7DC
-:10E40000FDE9478FFBECC7597BADB5D75A7BADB55E
-:10E41000F744BE6EF1EC2D60F01728509C8C5DF235
-:10E42000BB3C9BA0BC4482573318333A7C465B3AD2
-:10E4300063D672C6BCF0CFF186BC5786FA53B2E7FA
-:10E440009BB6718CDDC57C0686CF72BF818D853E03
-:10E450009DD0388BB1650A0B290E782EF4BE2F4D56
-:10E46000A53263D07FD92E29D801FDEFDA6C64CCB8
-:10E47000C4E8EF33F8B7A217CAC5B1F22A16343090
-:10E4800019FE63575C3B187F95123A2AA530B6DA1D
-:10E49000C442C930EEEAA7B4FDD6B010C1D370E0D3
-:10E4A0003363FCF8303FC600B4FF64EABCBC6EDBEB
-:10E4B00034C69C0628C3BC236FEB838887FF907DFE
-:10E4C00034AF35CC4FE3DCDE5AC54EA531D67C5F88
-:10E4D0006BD65DF0BCD87A7FD65D57433DC201DF75
-:10E4E000B730DE9FC1BCF601CED654B3502EC0B7B4
-:10E4F0001CE69B5406E541293405CB26164829E342
-:10E50000EF53CBF87CBD71F0D5B31EFA5EFD2EED56
-:10E510007BF68B34C267031BA27AF6545C3DE0A302
-:10E5200041E0A1E100BC8FC3C3CC0352C07A159671
-:10E53000821D19005FD359C63641A9E9D06746CD7F
-:10E54000F8AC8731C04366126366A0D7A3125BD4D0
-:10E550005F42FD26D64D8136F8771D96DBA9DD0991
-:10E5600081BF476F5991E587765BEC50CE16089EC8
-:10E570000EDFD0E1C7A91C32C17792AE8E96A9BE3C
-:10E58000623D2FD7D98A6BB6E730B64DEFCFB201D7
-:10E590001297C9BED77480BF271DFE5B90DF96E936
-:10E5A000BC790ACE97798B7C00076BE57878ACACA8
-:10E5B00065624B490CAE187C9CBEDBA4FE900EF845
-:10E5C0002C7058F2EC7323DF46F47E4BAC5DB34DF8
-:10E5D000A279A41E0BBF3606E9FEBCC4F642BB1DE1
-:10E5E000D287AF8D817E3BE6B95907945D4027B94C
-:10E5F0000CDFB34E09F0527EA8EEEE5791CEE549FE
-:10E600009EF1F0683C5429375A68FE77FA009ECC98
-:10E61000E4963D3AA8CFBCB3B80CF91BE67DE702FF
-:10E62000787FAFCD4DDFCBB270BABBD6070AD69696
-:10E63000E0F77D77BF0ADF8B4C49F2E0F7330157F3
-:10E6400056073DBBCCD88EB54BD8EED1143E7EBA22
-:10E650004EBEB30ECB65BCEC582779F712F36DA50F
-:10E6600079671A590DC289EF8325B464BC07A93EA6
-:10E67000C8E93BBBA514C7CB1CC79F4E432807C79F
-:10E68000794BA5F760968E6520BCF0DF00CFBD0703
-:10E690002B331DD0FFAD732645970A4F176343D820
-:10E6A0004E0959183E0B8B797B93685F3A3B1317E1
-:10E6B00083334FDBEEA2DE9B7A35E025F08ECC90E3
-:10E6C0001EBFB37853EDD0EE4B063E8F443AF62191
-:10E6D0007D603ECD9F02E46971745B74C580E33553
-:10E6E0007FAAB0E0D5B1F7E7DA4C2C58142B37D419
-:10E6F0001F9B8BED1AD9D006E4ABC6FE64168CE3E3
-:10E70000F72F258DFC5D95BF9B3FD5B1401AB16FAA
-:10E710008ECF8AF8896C588EF01F91D83E86F50608
-:10E720001688FB7EF3A70E6D390A67068D136BC73B
-:10E73000B4ED067E4FEDD8F4700A7EE7822D9CE2A0
-:10E7400010F3C37ED9326B41BA5C0CEA027A58C727
-:10E7500017DCBCFE226335FD96587B75BC0B8B0C19
-:10E760002C44788FD0B8889700C8B69D839F18DC5A
-:10E77000506E183C4A7851F9211E3F8138B991D129
-:10E780003114D2C19AFE856D5557891948714C5D77
-:10E79000BF6BBABCB3A05ED669D6737279747D9331
-:10E7A000587954270B79D0D0553D2BBECCDBC7FA16
-:10E7B00037D654C3FA2F2FE1FD4FD89ADE58AFC495
-:10E7C000E411CC230FF1122D9B12CA16284F892B6E
-:10E7D000DB12EA9D09F5AE84720E6F7FCE1ACA93E2
-:10E7E0003D8C7D645B5BA3807C3997155A2C417905
-:10E7F00073C7BD35D520E71ACB87BC32CACF41C914
-:10E8000023B118FE9A3CCC1B04FC593C61C3B212E4
-:10E81000C4C3D06BB8FE1B06249B047C6EE93F1872
-:10E82000A232F673C7F5EB97A85F43FF87D46FD486
-:10E83000F18B75B48E37159FA4768000DB69A0D369
-:10E840005799C45201A5058AFF8FA8BF1AFB7FC341
-:10E85000F52E8B18F8FCB81CBC90E57D85E4E01122
-:10E86000C986EB2ECA7738AE25C6EF6AFB5F4D1915
-:10E87000FC571C26F9DE4FDA1568FF7F1A7F338DAF
-:10E8800001A97E854D66A05C0D4E447DBC93F927A1
-:10E89000A21EFA7AE3F8A33A6877421FDECD005F42
-:10E8A000C5F64D350AB43B610DE74A2043266DEDB0
-:10E8B000E5E5F4F06EC46760EBA384DF13B9E15CB7
-:10E8C0001D94A7DA43BC3C3EBC1BCBB76E7D86973C
-:10E8D000A7847365E83F3670A0A61ACAFB6C23AF05
-:10E8E000D77C3B97E32A7C97C779B3EDE9C8765C80
-:10E8F0004FECD603C6401E2E5EFDF1B3FB000F8B1E
-:10E90000EF4F2639B5EFDC57E6FB68FE019F520159
-:10E91000F290B33ED763248F15B203B250773962B9
-:10E92000F4B0E60DB949CE4F6A3988FA3E737109E1
-:10E93000C9F94F53BDEDF669B1E72719F00438DA8C
-:10E94000ED362E97659D97DA3F6025BB678B99CF93
-:10E9500007D60DD1D722E8512EE6536ED7D133CF4B
-:10E960003687C6FB40F2EE30C9F8640133D27355E6
-:10E9700012D91977EC01B90072B957C0DDBB7562C5
-:10E980003000E3DF21311FCA8D5EBB370BE5C30BBF
-:10E990007F91EFC4F9F69642199E3F16F2BEB7CEAC
-:10E9A0009B658FD38BBD7B78BD2A777A0B787F559B
-:10E9B000DF6476F0EF646E99B817E791AC302F966C
-:10E9C000972F2ADADB4E7A7B01CD9B79BD5912CC89
-:10E9D000F7F4AAB13AB42355FAA4157A6FC2F9DC58
-:10E9E0008EE35B627452BFDF8EF346BD2F83DE87FA
-:10E9F000F93EE0F0D3FCC10E984A76A0B003DA717C
-:10EA0000BED362F8654A781ABEFFFF084FF760FD73
-:10EA1000FF144F23C88B00B66B6C0579A18B93173D
-:10EA2000027FDBA4903E93CB0B0FEA397CBF00E45E
-:10EA3000E3ED36FF468447FDFEE2071AC9EE53E1D7
-:10EA40004AFED68B355F65C3D759A25D76E203D304
-:10EA500066067AEC84A19FE4E289F9CCD38EF24376
-:10EA6000C7EA118FAA5D5971FF9AB718D8B397ED0D
-:10EA700032D1B95BF266E1BCBA81AE26D4C37586E9
-:10EA8000E0BE82985EECB50777AC40BADE52E20990
-:10EA9000B8493FD27A0BB42653BB5E7B9829583FC6
-:10EAA000C36D034890CE448FC86D86E05E09E9CD02
-:10EAB000F9A577D5A4604022BA07A8FF6D9C7F7A9C
-:10EAC000EB18D9F7BDB7B9886FCC2C68467846E308
-:10EAD000838C0E467CC414EFD43A6B0C0F3F13EBBF
-:10EAE0003AB93CFCFCBFA11DB9D94C7624EA4CDCF8
-:10EAF00077B19E4C8217E8F902F187BA5F7A242B2E
-:10EB0000B889F6679E0AA4C746AB7709C1FFED64D2
-:10EB100037C2BFCBCCBA4C65B8FD609D24EF043C36
-:10EB2000ACE73186F6D99DC23EFBF7FA4B56B403EB
-:10EB30005EB573FB0A19C504F26F29E3F54BD725BF
-:10EB40007F88FB99A5EBE49011F62BAC6B8E371CFC
-:10EB5000B7CF208E82F1FC425EB2ED112BF28D1FF9
-:10EB6000FBA5E0F87FB4BA2D5886FE5391ECD0BFD8
-:10EB700038D6FF3DB16E17CB1C7ED696EC46FC26F0
-:10EB8000CAF5F754F87A1EF3C67F4FFD4EE2B8B0CF
-:10EB90008F7B1FF105780FA5A23DFF6D99E89A08BC
-:10EBA000AFD31079C80CF58BDB64FB7AC0A7BFD557
-:10EBB0004AF355E1BD3333722DEDAF12C63F93DCFE
-:10EBC00054A1E0FCC5FE83ADD3EEBF1833C4CAC068
-:10EBD00017CB5984F631C3DE8B7D6BE2BE8FB1BF9C
-:10EBE00018E3DBA9EB85B9A504F8055FB92505E9AC
-:10EBF000E69738DDA2F44E805BC5A7EC18199F4E4E
-:10EC0000433817E595BFD5487848ECAFEABDC7CC87
-:10EC1000B03E80AFB64B12F1E3F6FB92498F311351
-:10EC2000A763F3EA2437F2E74E43E4695A372F1912
-:10EC300019D2F5A239F202C9A342EE37B8F83379F6
-:10EC40000FB6BB90CEF9FAC2613DAD270E0CD83B92
-:10EC50003F93F752BDC4C7BDD09EECC6F5D88C9883
-:10EC600084EF3707FEAB8D01FE4EE9F83EB87940E0
-:10EC7000BBDFBD00FFEACB6272E122E3DF090C706B
-:10EC80003900335D45DFB923896D82719B7492171A
-:10EC9000EDA3A6D593821D9C5F4CB85E1A04484D27
-:10ECA0003AD8F795C5D67793EE6411EE9B1A4C9B34
-:10ECB00087E414AA3F8EFB2D86FB25E8B71A3B1587
-:10ECC0000CE7E7A6CDBFFD33C2DD74484BF78618CD
-:10ECD0007F489F49D83F8E5F0A627C40F635CA87DD
-:10ECE0006A161C2F713F0C96936B8682E887691613
-:10ECF000FE89F463E1B9C81FD6F27EB6149ECD67D3
-:10ED0000B97D317370CF2BB8CFB5D70CE5E2349B0A
-:10ED10005BD75E7DFAEA187D5538670C6E9571FFFA
-:10ED2000A6DA2571FBC7890BA6C43FD7533FDC8FFA
-:10ED3000E2F7C2F80AD785C2F5D936A1CF40EF91E4
-:10ED4000DC5DDE3381F41EEA25945FEA7E16E51968
-:10ED5000CA8F271D558B1C30CF92B4AAAF38A6F1AD
-:10ED6000EF901D8F9BA019C3F199A857D476B8AF27
-:10ED70006DB18CDE2EEAE7D991CAE583225179C5BF
-:10ED80004FF57B36117C0AF1CBDADD05246F557F18
-:10ED90004C83F043AD10FE9B15C27FB372BB91B99B
-:10EDA000E3FD55416DB941ACF74616E67EACFD502A
-:10EDB0001FEFB7A966212BD6A3FF069FFDDAFECD74
-:10EDC0002C385B41FA0E7C668C7FCF7AF97CEF148D
-:10EDD00074DF61E67E9B99EBF6C8DC19C5E79B5AA8
-:10EDE000E62D7810F5C49B7AF22FFC87A0938A1742
-:10EDF000A3A3EAEB88EF24DC8F61BB078D8497D354
-:10EE0000A08F0F0ABFC602DC67B6F9B30A0B113D2B
-:10EE1000B6BC05D6E1F8DDF492B91EF965B343A797
-:10EE2000E1A72A879ECAE4EF41BCB727935D0D682E
-:10EE30009E8A7C543156D5936C2AFA993ED483BD70
-:10EE400005E5A65B2D7E1C2F8C7601947708F9B51D
-:10EE5000C361A0F1D472741F27F805BE43E3A1DF9C
-:10EE6000C517C707C168FBADC25EE47261DBAA24A7
-:10EE7000924731BED531E2DB129F01FD452F0939A2
-:10EE8000F2122094F651FD662E47142E9F5E3A3BF7
-:10EE900089E4DE1B1FAF26B972695112334AD4DEF2
-:10EEA0002B61FDF3C6E07A28DF25FCA82F49DC0E94
-:10EEB0000C1CB1D2380D06FF0EF42B343C37DE03A8
-:10EEC00014632F1882DF7F1AEB5F3693DFAA218548
-:10EED000C3D9F0D21892933FD6079FF901F9218C3C
-:10EEE000649F3524B953A9FE27690CEBBB92FD83BF
-:10EEF00048CF6C23B71B1B0CA1223BE0F16490DBD5
-:10EF0000BF2751D0E0F88356B26B00CC2CFCFEA991
-:10EF1000EE4CCF26770C2FA71E9A4CFCBF4DCFE9A5
-:10EF20001638CCFD9A27F5BEB959503EF97CA90791
-:10EF3000768EECA2CF1032008CCD5BB8BDB64CE71C
-:10EF4000EE6B45D9F472B247B3DF7C78652DD637C6
-:10EF5000AF5E7713CAC1D1D633CAF3787FED0516F9
-:10EF6000C9A3FD66FDD8FE107CF7C2E0440FA94797
-:10EF7000E60262039FD878DBD37AC037F2D7113D1F
-:10EF8000F1EF171D1FE78BFB3FD42FF89D6690BF55
-:10EF9000513F32C9DFB8B23C5299D3B3F9A54C61A5
-:10EFA0009F69EBEF48F55F40B9D6F4DDDF9F682538
-:10EFB000FC4648FEB11EEE1F3FADF72E463EB5574C
-:10EFC000870C4BE3F6B78634BE8E9619855E6721B3
-:10EFD00043FCBA53EB2BAAB47CAE3EF5697C1F69A7
-:10EFE0001DE2727C78BD4EAC9BAF18516F71D70D8E
-:10EFF000ECA7CF727F8621CD4DF533CF860CCBA009
-:10F000009CBF2E6458219EB82E00DF2113CCFBF448
-:10F010000E2B5FCF80061C67C57446F6C80A19EC34
-:10F02000D0327CEF1E08035DCE3C6FE7FCF527C0B5
-:10F030000AE07B0913ED8C60B782DC7AB1530AA138
-:10F040005DBF64BB71AFB900D7B157B6223D774BF6
-:10F0500024B796745616ED80F2EA435388FE29D3FE
-:10F06000395FAE0EDA49FFCD147270993168203BDA
-:10F07000FA19EEA783F1C91E6E804E5965C3F1805F
-:10F08000F25BC30F416D9C6166BF90A7FBE3E20B8F
-:10F0900063E3E47A7F427FB0E3B4FC1150F50E974E
-:10F0A00073CC9D89724E95C34687AF348DE452610F
-:10F0B00026D217E8C9E5E44189F0DAC85AB8DE106B
-:10F0C000F23EFA5DA12FCEC801AE978C5BE93937CD
-:10F0D000AD80E8B61AF50DF9CDF9FE6E343E989B79
-:10F0E000A6137271643EB85EF041C35916BA16BEDB
-:10F0F000D7B08E851AA7F2A7752AE941AE0F4D2227
-:10F100009E61E2F18ECFD38B897A7098DE4BD077F7
-:10F110009906A1DF049DE3FDD9A8EF67AE0BCAE80D
-:10F12000D7CCB379AFCD4C8FD92FCDEF994CEEAB77
-:10F13000B0EC63632DE89FA97CC685FE5DD88FE3A4
-:10F14000BA4A06BCEC81F7BB55FBD6C5E7EB32707B
-:10F15000FED52B3E566A41BA0CD17E3592CE6CC894
-:10F160008F2A3E775BA15F19F6E3EB2DDADFC43A15
-:10F1700093E2FA57BD6426B97AE5B0356824BBC37B
-:10F180009F6F87F1327E65243BF4C24B56D29F17A6
-:10F1900084FE73AAFB7EB681E8D38A744D476EAABB
-:10F1A0001A83FE5326CD1F832250B5C31AEDA3F94F
-:10F1B000B3457DC1D0AD9CAF8CB45FBC620F7F13F3
-:10F1C000CB000F43FBBA05E98CFEF643B34B1F801F
-:10F1D000F7CD3E8B8763DF5F8AFC6A94EFBD15FD38
-:10F1E0002A73E57591FB601E8DB9169B11BA54E721
-:10F1F000FFFA97B741F9A3437A66443AEF9BBD887B
-:10F200008D1D5DFEAE0AEA4F86E3D6CB9AFDDA721B
-:10F2100063BFB6DCCC9493E13879FC589AD5796613
-:10F2200032C90ECF67C0DF4663CBD93D00AFF1C70F
-:10F2300046D2470D69FE5D69E837D5455E433C1B04
-:10F24000F3CF4D453F4555FE9F28AE73E5DBCC839C
-:10F25000705F315792FEBEB2C3EC0EC4C9AF66C137
-:10F26000FFBD79B554DFBBD3E896787DEDB40AB421
-:10F2700007E9DBF867D201FE9BB7CFFB88F64D6844
-:10F28000B543B917ED4BECF79C146C47FB713BD7BA
-:10F290007BE7C17E34A1FE14EBA9591E9C6B82FF53
-:10F2A000EC75D44C44F9A2FC59F121FD37E25071C0
-:10F2B000F6EEE1E8FAE47E9C1BD08F338EFC3887B3
-:10F2C000516E349AC2864A18E7BA3FFF8EE4F2CAFA
-:10F2D000D6A564D7C7EC5C23C99195F7F9E9FD2B56
-:10F2E0003BAEA7799D8179237ECEECE6FBB99539BB
-:10F2F0009620C2779D9DDBBF2BA19F240DC74B227B
-:10F300001E7EB3EB7A17D2FB378C7F2FD0CFED84E4
-:10F31000DFD8865248FEB85B52D0CE6BDE7EFD470A
-:10F3200028B756EE963DA8C7D9112BF93D56EE9E4B
-:10F330003371B905C7B99C568978EB9B6393E9BDD6
-:10F34000EC0B72FFC9D075F05EE9BBC68DEBE4F83B
-:10F350006E2387CF6E7A1AE1BFEECF32F1BDA26382
-:10F360007EB4577B0DDE89B8DEDCBBF6CD45BCFE36
-:10F37000A62E5B47ED9F95980DF1606FCDC0F72BE2
-:10F3800025C587EBAB7EFBAADA787BA4334D267CC0
-:10F3900057E6AFCB085B88DF6F453DD7B85B4F764C
-:10F3A000DDF1051FFCF236678CDF57CA3DB7CE8C06
-:10F3B000B3379A77DD28F8013436E069A5C0933178
-:10F3C0007F5D117EF7F3F87FE5FA96221E8FF9EB49
-:10F3D000EB20BABE77F1F5F007D0F7B45FCF7168D4
-:10F3E000ECFBD1F641AABFD9E461DE7D168A1B7A17
-:10F3F000719F9BE754A83ECFC9ED6CE50F6BF7BF3B
-:10F400000DF0F7A7F98D4E789FCFBCA5485777C46C
-:10F410005605E6244E89EC1FB6CBC8ED4985FBDDC9
-:10F42000B6A5B3A737C5C1998DE3A5D3FAB43961A1
-:10F43000DC0BEFFFE935C45F53DEB9A93C9EF63B18
-:10F440008A4F590679DCD2E2F131E48BE6C13A7693
-:10F4500057494C1E367BB8BC4E9CD77227DF6734A9
-:10F460003B23344E753A5F67AABF77676B12F9F595
-:10F47000763A8366BEBF0D3094E73795CB3CDE22EB
-:10F48000EC129FF09399BCAF308CC7308FEC190F02
-:10F49000E521EFA9CE3428BF5D3EC72343D9E27DE5
-:10F4A000B26B2CCEDBA317F5E3C85FF8D6AC4AB23B
-:10F4B0004F6EF2CAF45D569F42FBF521EFCF9D7768
-:10F4C000C1776F66DEB4D3F08D1A50D648C721FCE1
-:10F4D00036DA018ABFDC19E75FBDD1332FED74BC8A
-:10F4E000BEF472FD8FFBF17E113718090F25699567
-:10F4F0003311BFD77D99D3E1E367F9FEE36333F7B7
-:10F5000063ABED3EB6723D53EB94841DD89F87727A
-:10F510003E5AFE5AB1260EEC34F4E7E13AFBADA4B4
-:10F520001D6775978EE2B3ABBA18C5633FFEFE8BBD
-:10F5300079286F3FDAF762DED238F812FBA9CF5B89
-:10F540009D5ABF94EA87748AB8F4528F91FBFB46A8
-:10F55000F143AAEDD976BE1FBB08D21DF94EED7757
-:10F56000B13EC98B76E545662279B67450F835BD53
-:10F57000DE4227EE1FD4FE09E36F41FE01B8A4016D
-:10F5800089F6E7C9251192AFAB4CBED7C6B8312F6B
-:10F59000C54BF499877494905FBD069CB722F679A9
-:10F5A00046C5D788F45CDEA3A56396D326E2944EC5
-:10F5B000A2BBA1C9A2A07EC8E810F2FA1B3ADABF2A
-:10F5C00018B25D16944BD715257562DCDD9994321F
-:10F5D00015FDE6B9D9C5D43E50C5F93A90C1C86FFA
-:10F5E00095C55A2492B736EEE7CE99CE6C98E7F1DE
-:10F5F000A293DB832EE6D92E933DD82F91BF5FCC0B
-:10F600005F95EBC82F28E73E964CC42FD2A044F656
-:10F610009DACEB5F8CE38EC63FBD09FCD3FB0FE6D0
-:10F620009F3EF57BC3F8C74F71BAA52ED3C8FC2304
-:10F63000FCAA5FB8FD6871C26F98543FB384F3AD04
-:10F6400015E3D59A2C21792AC98773F1FED45D6020
-:10F6500067E27E448D2B8EE958E2E676FA5018F781
-:10F66000E5C9D79848CF7D47375480F67C629C1116
-:10F67000286B47798F3286FC8AAD55BED36971FA03
-:10F68000FE08DF3734DDE7A5F7B307B97E6F2E3408
-:10F6900090DDD93C200590CE4D3E43D0544071952D
-:10F6A00025A4B71F32BB799CC4DD4E71926FBB7924
-:10F6B0001C25EA470DF73D80FC566F21BF4362BC15
-:10F6C000E585BFC8FCFBE3197DBFB794C7777AE730
-:10F6D000B9C9AF911847635DDAF5ABC6512E5A012F
-:10F6E00031F0BDA59BCD44876C99E399A59AB87E6E
-:10F6F000192E07C85F9B315D1046C43BA2EB1A244C
-:10F700000396B345BD1A9FB196F80AD0C2BD3DED30
-:10F71000B93793D2FF967C86D6EFFCD57C8680B134
-:10F7200016F3194C683D8B7A041BF4AD5AF69ADD3A
-:10F7300018BF89D52B60379A0624F1BDE76F98531F
-:10F74000087890D4EFAFDFE4B550BC58F3BD78F83B
-:10F750009484F1F530BEC52DDA070ECC9BA3505C26
-:10F7600052D47FD68DF91B5BF4DAF108A5A23F16BF
-:10F77000D4EF1DCF9CFB9DCD3931BD0F7680297D07
-:10F780005A4CFF6FFCA0B6E72AF856B2EDB201F56D
-:10F79000AAAAC79B9D3CBF2171BD3AD2F97A05FB4D
-:10F7A000D5914E7283DBB5B5223E09F6EC5C5C5A0E
-:10F7B000CDEB7C0CE393602F64A4631EC3FBE7CE08
-:10F7C0001C45FA2DF898ECF9E64F15EE7701BB03CE
-:10F7D000ED7393E07336A0277DABF2C16A217F7A87
-:10F7E000EDA0EF915F8F48D302C4172D79B7000DBC
-:10F7F000EE4FF7BA697CB1EF4A8477463AF7933413
-:10F800001757ED28C2F19F9218EAFB4DC52733D058
-:10F810002E691EFC3063795CBF55038F121E56EDB6
-:10F82000D78F38FF19E9DCBE6C3AFC3CF9073F0E74
-:10F830004AB496EB9560F74C28D7D7EBD04263E5F6
-:10F84000C125B791BF7F91818D87F9E50B7DD4BC30
-:10F85000FF2B8199B83F837F12BCDAE95B417A6F55
-:10F86000E7229305E30ECDC54BEF263CD892BC882A
-:10F87000874DC55559F89DA6BAB9368A13807D853E
-:10F88000F54DF7DD4E7E1315AE4D03FA1AB4BB2AC3
-:10F89000C0CEFA11C09DEB985FE381F537463E5824
-:10F8A0007A8F05E3C223CBDF7FC9E0F4EC947C813F
-:10F8B0009BCBC94FC8E2FD7EF903DC9EAB4B37689A
-:10F8C000FCC275E9DCCE9C15189A8DBCF7B2124EBD
-:10F8D00046BBB799793FC1FD25F359DCFB884E5CE7
-:10F8E0008E38DBDCE43F3239C3DFB90AEB6729B479
-:10F8F0007F604AF811FCEE856EA7671313FC8BE559
-:10F90000FB4A822847FF39DDBF18F9AC42D88F1770
-:10F910000E5F5F8A7E36D53EEADE630E621CB0DB88
-:10F92000EAFE6E0DCAC13F283CEE6D8A0CCD467AC8
-:10F93000FCD141E3769B83DD48FFC0563DD51FB621
-:10F94000FA5721DF9CADAB29A2BC1B4BA008E3BC3E
-:10F950007A670F433B01B60BE44F30397D0CE3A1CE
-:10F96000B3034B1409E57C82DD315BE48F92F084B4
-:10F97000F755428C8D072E3863A225D0F9595ACC01
-:10F980000E79E34F0B157CA9DA273A138F67552FB1
-:10F990004A6232F2FD86C86B3AF45F3B87C87E6DDF
-:10F9A000EC97E83B8DC5CF513ED81A917714CDFF27
-:10F9B00051C2940FB53E3D59E8F14ECEEF6C88F63A
-:10F9C000CBEC00A7276361CA938AED23DAA99D3A9D
-:10F9D0009E41F8DD1B85DF053418D53F94AEDA076C
-:10F9E000EBC553CDEBE2DFDD260D7965C46BA9A431
-:10F9F000F117ABCFA7D2B97D987A2C3217D76FE425
-:10FA0000B09AA7C9F330774C9BE441D369589EE67E
-:10FA1000C02773916FC0D0A6F5DA34F0C5F234BFB9
-:10FA20002FF60DFFEB799A1EC9BB179E3F4AB7739D
-:10FA3000BF959AA7E9E1F853E36C89F99917B242A7
-:10FA40000ACFB70AF7ED43FE1C30521E57EDC0EB4C
-:10FA5000EFA17EAC35B17E8C4326DA196DB6AF0CC2
-:10FA600022DF5F3C7FA6EF418679BA2F78285F239B
-:10FA7000C17E48DC27ECC52659A3DB7BEF46E9C9EC
-:10FA8000EDBD68F97FDDDEE3F67C601FCF0F50E54A
-:10FA900079B3D89F5DACBF94827AE644149E843CCF
-:10FAA00086A7441EC3E0C8790C8AC807027B3D4084
-:10FAB0007C7290C775DE783A99E4C7259BB217ED42
-:10FAC000A5F3D6C83711598AB0933A8F18DD282F7D
-:10FAD00040DE91FC0E1CD4F3380DC66D308EF3F26F
-:10FAE0004411C711F1A29792C96E694871A7627F4C
-:10FAF000354EF363A16F1A92787CA62BD97F397D9E
-:10FB000084B8CD1E617FED81A16C38DE7B4611C7C4
-:10FB1000060181FB9D877279DC41C46D2E8AB8CDC8
-:10FB2000A9625DC8C0FD10E4A77277292C0BEADD3D
-:10FB3000EF99836EEECF32E940EF2F53E3362F7308
-:10FB40003FD532119F39B5602EE5072DC7FC7719D7
-:10FB5000FD18DCCF1CCDC767361DCE670D888B9D89
-:10FB600028620280F56BE0B5A493D09E707742992D
-:10FB70008C656F4F0D7C7769A78EF623CBBAB4FEE8
-:10FB8000F22B9BEEAE41FDBDB193C71F035D12E9A1
-:10FB9000EF65CCEB427B43E587828C34A273A053A4
-:10FBA000E7C5EFCCC8E0FE04407D90E6279E9D7A35
-:10FBB000E1671770B4335D089F3A893F37DA949A4A
-:10FBC00011F5B218AF53DF62AA443B3657477EDEC9
-:10FBD0002B06EF22F2933A8A886E9DD696AE1A5E75
-:10FBE0004F6BE58A39E2A3FA6B156EE831B703E58E
-:10FBF00064668688DF24CC77798FB69C187F581589
-:10FC0000D4969731FF842C3C87B05FFB3E3383CB87
-:10FC1000A92B9B0A849FDF437EFE4EBDFBDD029431
-:10FC200053DD0AC9C9F61C8E2F5D2E7F8EB5572F66
-:10FC300022FBC00E7605C1CBE11F7BAD53427DD9BF
-:10FC400069E77CF93F853B11DECA8C226E27A071E3
-:10FC500087EBA85B0A727C71B8BFA8BF626986F0A7
-:10FC60001708F9132DFFEFEF37393F76CB62BDD977
-:10FC700048FE2C15F1C65392E7E910BEB7805D002F
-:10FC8000702FEB96CBD03E99FD150BCDA3E9657394
-:10FC9000D008F58DEBC279B88E9AAAC2452D23E023
-:10FCA00015A15554B905ED963A617F80EBB64B1B13
-:10FCB000871A1E57F47E2B231DF721A70EBE8EF444
-:10FCC0003E6826BD04FF75D488FE8EC305642F4DA3
-:10FCD0004DF5B765A03E4F0AF57DAF00ED136E1FE1
-:10FCE000350E1AF7A0FDB7B4537B6E866DD6C6B934
-:10FCF000589783FC19AC57FB1ECFA768FA0D8B7B76
-:10FD0000713DBFCDE09F8876DD755FE6F1F5F3AB21
-:10FD1000740CE9BB4CF6AC403972DEACB5BBCF5BC2
-:10FD200039BDFAA274F614219DFB46A5B3A708E9D4
-:10FD3000BC4CC7FCF1E334229DAFC6EC734EE7F335
-:10FD4000CF5F5384743E77F09A22A4F3367D8F17E9
-:10FD5000D7CD930EFF5EC4CFE9393EB29BD4BCC968
-:10FD60002FCA8F8732B4FA305AFE3BF93F46D3830D
-:10FD7000A1281C5A3DE834B873501E2E3519FFAA2D
-:10FD80003EC4BF11FD692623F9235EFED3E58751EA
-:10FD9000BF050665B23FD4F15E56FCE3D05FF0F2DA
-:10FDA0007B2E4F401A7DFC066157B94C2C807E0F8C
-:10FDB000D5DE57EDC64479FC0B319FD319DE1AB45A
-:10FDC000B355FF6CBD18D314BCCCEDD3A724F2BF40
-:10FDD0009ADCFD3C7FFEC8121BFA67CF06B93FB61E
-:10FDE000E9F952F2D7AE0ABE12C2FC273628D97002
-:10FDF000DFB0EAA90F53309E0DFBD0531971F19576
-:10FE000039621F7A36782A05E3DEF0FD6AFC7EB29D
-:10FE1000336240FE6D82FD1934614D4A84CE0D354A
-:10FE20003919E9FBF201ED7E4D8D4FEEF41948DEF4
-:10FE3000ED1C9482B83FCB30F80B72503FB11CDB05
-:10FE400099E4D87AF924C36BCB9C161F17F65ECEC3
-:10FE500088CB570AEF48253E0CEB9997EC801D564E
-:10FE6000219778BCE63F77D9833C7F89B7FFCF6085
-:10FE70000195557DBD429CC35B21CEE1A1FC0E25C1
-:10FE8000C8EFF87234DEAC9E3703791E1A29FE1DC6
-:10FE900097B714DFBF8945447EDE6746CDB8D17C75
-:10FEA0009D965237C0BDE66B163A67D80C7CDD5A7A
-:10FEB00016E3C3063115950F9B845FB7B9FE24ED99
-:10FEC000039AF17C05DA551ECE870DB03FC2FCCDFA
-:10FED000C475CBFAB5F98CA3ADE329995ABD122D9F
-:10FEE000FF83FC98D333B5EB579DBFEA078FCE73E2
-:10FEF00050E2EB2B615E89FBCA44FFB5BA2FFCA22E
-:10FF000072EDE64CAD5C8B96FFC172ED8ECCD1E408
-:10FF10009A363EF037CBB5C4384121F77F639C0059
-:10FF2000E3B6FFD338C147EE9E0C1DCFC3D7C44FF5
-:10FF3000BBA4969B4CE330AEC8E3CB8D5623C56182
-:10FF400013E3AACDEEB9228E38F4CB19A8370FE906
-:10FF500019EAF37ACB4A8A5736CB070C78A4705843
-:10FF60003C51394A76FBDF1A575F9F198DAB1760FA
-:10FF70005CFD15CBE5347F1C3DAB4AC0C02F193D5D
-:10FF8000DF68B3A053B2C88B302901668FEB3F5AAC
-:10FF9000BFDE4C6E27BF22F2635C069EC7BEC50A59
-:10FFA000FB3098BF4BC7F377EE4FF76D43F968729C
-:10FFB00073FC3E71F8AB0CCF1D3DA1EF27391268E1
-:10FFC000B478501EAA7E17757C45F80FBE28DFFF57
-:10FFD0002081EF7FF077E6FB447C0CA872E76F8D01
-:10FFE000876D07DC68D607A3B8D75B18CF2918CE72
-:10FFF000C7A38D331A3FFF34D3F75A26C947EF54AE
-:020000022000DC
-:10000000CACBFD82F226B93C720AFD3BEC90D18D41
-:10001000FB0D933897C13667893C4A4F451DE51360
-:10002000F3730DEAF98FD1ECC20FA3729ADB851F2F
-:100030008E2AA7FF7B76E1030EDF299CE7E94A6F52
-:1000400011EACD8D56801FF77BDF378E78CE423D8B
-:100050000F00FCC4CF9B3CCBE3E0897CF58704FD1B
-:10006000F287BFB37E194D9EEA5D2A1C7F67795ADD
-:10007000FFC714F47B8E3E4E80E0A8A81AF28AB81F
-:1000800015C3B8913A8FE6219E7F9621F2AAD4F744
-:10009000116117DEE9F266BAA0FFB9F74D26960A9C
-:1000A0002610F218DA633E0BC5039AFA799E48D3FC
-:1000B0003A46715FF51C65D3401D43BBAF3FCD5F32
-:1000C0008079601B3FB004E454F4932F6068EF5DC7
-:1000D000789F971BD2FCE3294F6C5D581377A8F8E3
-:1000E000ECF206F46700BCE41F708AFC4C15BE3AC3
-:1000F000179767EAF32681EFE8BC9C1C4ED62F07C2
-:10010000D14E4C760F911FA9E91037DE2A642FF9E2
-:10011000EBD91A079D9F683A54594AE7CDFBCDA504
-:1001200068E756FCAAD686FE8973D73A29CF204FB6
-:100130000EAF423BEB9FD3FDB3105E6B79701EDABE
-:10014000A9F960A7A2DD7BEEE0BC527F9CBF7B1BC0
-:10015000FABB61DC6D56AD3F9B99789E78FD5E9E43
-:10016000077CD8EA9F8BF8DD66E6F006B68ABC67A6
-:10017000E1E74E5CFFEABA8F9E73BCC344716955D8
-:100180002E6CD3333FEA3D559E94883C39C007CF4F
-:10019000D31BACE3F91EA26C716AF3154F67CC292F
-:1001A00041784AD0D13B0DEF518848E8775F2EE285
-:1001B000F0D78B7C0A357FCAA8F8BE8EEDD9BA9AE3
-:1001C00058FC7D2CF617F177912793FC29B79FC730
-:1001D000DA0CC43756585FE41F01BE41FACC8A0CD2
-:1001E000CDC6F34485BDA15988CF973FD5113E9424
-:1001F000BAB7287E928A648371C66D0E774F403FEE
-:100200008AED17D7225DDC3DB62A445D7F9AAF9117
-:10021000E0505A8A715F59F5AF7A9E07782499FCAD
-:1002200003BD790D940778E103E388E746D467803E
-:10023000ADA7BCBFB1033F273FBEF59034623E6718
-:1002400097CBC2CF0D078628BF8CCD72123E942368
-:10025000BFA2B8AFD2AD9007A353EFD5E139A84004
-:100260003B23FFE5F85E9B0EE9922FF24B2EBEFC7E
-:100270005F53FDB44F51FDF6419E0FA40F6FC07D3B
-:1002800097D21EFE32AC60D678C8AE6B2AC1F1227E
-:100290004D3CAF3D99219FE40F8C5BFF2528E7770C
-:1002A000D99884F2E7A535F9E42F85798E1F619EF0
-:1002B00077BB78FE8E722459877A4BD9CA28FF50B3
-:1002C000B1675411DC8F4219C65923F8468D470295
-:1002D000B82ED44777BAFCBB11CFD17332AD49FCED
-:1002E0009C8C3877696DFDE0593C7FD267E0E70C64
-:1002F0008FBD3C7901F9EDBA1509E970C5BE24DF5F
-:1003000006EFF78B756B558698CD128FFF63946F50
-:1003100039F608CF4B53F49C4F946EE71EF40B7ED6
-:100320009AEAA7BCD26B3B4332C5B36CA71FA97135
-:10033000C7ED6BB6733DD2B49FEFA713F7319FA7FC
-:100340003F8EBAB47649B4FC0FB24BDE4AD01B7F65
-:10035000F3FE8469F77589F649E23E6E98DD9D30BB
-:10036000DE68768A9AD75115FB0EF1C32B56D50E4F
-:100370000A68F25EAA2CE2DC9B493BFE53224F47FF
-:10038000CD83C9E870B7635E79E4DB8CFC6C6A3EB0
-:100390004EA08AEF1B023A139D8773B11ECAC31980
-:1003A000C3429244F67F98CE7566623E0EF47BDFC0
-:1003B0003596E0DECD3C5D32C943B784709B318F0A
-:1003C00083F236833B56E0776EB1D077CC98C77115
-:1003D0003586E2BD3B507ECEAEE771886CD0B7C8A3
-:1003E000B7D9859C0FCD8B783E879AAFA1E657A8E9
-:1003F00078A812F8CD9EB0A200F707DD92FFFBEAC5
-:1004000079DAF873D2D1F3D1ABC6D27993E8F9B9DE
-:100410004226EABFD839E9447CAAF91D5536BF2DDA
-:100420002B7DF87959953FE2E84670ED3CC2EDF539
-:10043000AA7A03C17F71D57CF2235E5CA563B86E96
-:10044000AA068D9CDF12BEB7337A0F46D04CF75DFB
-:1004500008BA7F9EBD0AF42C463FEDB1B69AAB4F69
-:10046000036E8FB7F9E879D12CF5CB57D179C6C592
-:1004700028992E67EDACC57B0A2E5A237978CFC117
-:10048000E5EC076FA4727AE4049653761EBA11EF76
-:100490003DB8383ED287F71E14EEACE4F5C883D9D8
-:1004A0008C5D9555716380E6CDFD4EB363E7B3CBAC
-:1004B000113F8D2CBC6188FC3B3C7F1FF3FD900EEF
-:1004C0002E8B81EC1997C8B364D522EF12233050DC
-:1004D000EEC82AA578B585B90F0D617D0E3F2704BA
-:1004E000F5C4BF1DE3B95FD824E8CA72543F52383F
-:1004F00080F2A9A3C04EFDA372F49031C8FD59FC4F
-:10050000FBEF3C3F85E24B6AFE2863B6DC8553284F
-:10051000DF445356EF37608A2D17ED850EBDB04B83
-:1005200045392DD55F97156717BD33E75B25B80EA5
-:10053000CEBFF04021CAA5EB0D60B78F20877E9D0E
-:10054000CDE5D045BDA54B023BEDE729FEDB719C17
-:10055000F79217CFB5C3BC16A5551AEC086FE0FB90
-:1005600032CAC574416FFB420E9FBDDA272D8771D9
-:100570003BCCB07EA17FBA5FF1529EBD7FA1740BD0
-:10058000C0DD2171790B9D52695F52EC4EC5FCE5CF
-:1005900006715E5216EB7E46FF5619EDE977DB06D3
-:1005A000662A8531F87E2EE2CB3F2F6077D68DB05C
-:1005B000DF6DCDE2727B81EC9E827CB4411A78AB18
-:1005C000360BDFBBE9FD9C94D672CC3BBE3EB9A591
-:1005D0001CF5CFB0F7A9F0BE24AE6CE4ED1A4C9137
-:1005E0003C3C9FEC4DF6AFCBC2B8D0920F296EF9D0
-:1005F000CDEC774E60DEC13BFA9ED929A85F0AC4D4
-:10060000B97EE1377C6D82EA3734F1F264EE378CE3
-:10061000E6734DE1F964B50BF939C55A91AF30D79E
-:10062000C6CFF5CC2D2FF074008837B18882726F59
-:10063000EE7BBE14DCB7B385FE72DF94D1ED19E614
-:10064000D2BBE3D7EB3C775C19FEDD50AC2DDFE885
-:10065000D1966F9EFEE709F1E53DC9DE1D38EF1F1B
-:100660004B3CFF313083D9689E4E298076C7E41712
-:10067000B3C5F94E9EA7F74F625FF4E27446F519D1
-:10068000FB4D7B31FF5DF533CBA27EB28B99F21D22
-:10069000FCBE00D4571149E4FB392996C25EB8DB91
-:1006A000C6F1076D0D30CE0B4BDCB43E322C3AF662
-:1006B000655C43E526B2432AC69892906F8E09BEC8
-:1006C00053CFEBAA7C58A1301FE62FC0A717E2F347
-:1006D0001DBDED28FA97031F31C6E955A950FEA1AB
-:1006E000F81663ED547E4CF0F7310153E0DB0AADB0
-:1006F000E757AD06A2A7FC13790FEA098CCDA0DF5E
-:10070000F8D2E649049FBA7E6055173A33C8A52D42
-:10071000C655740844B1B02754FE460B08DB8DC1A2
-:10072000FF2C203E27791399C6EF4FF879019727C0
-:1007300091AD0E711E8CC7CB724DD171BD386E5606
-:10074000F43BFCBC51862843554807F3FE4D560147
-:1007500097CB83AFFF81F4B2C5E3C7EF18524C7457
-:100760004E465D37B6CEDFBE553B03E759F40D9AD2
-:10077000E77CAB0DE7590C6CBDC8414F6F1A8DC7B4
-:10078000D78F9CE471E33AF94ACDE1994A1CDF40E6
-:10079000FF46DE3F59DBDF05FD1D71FD53A07FC91C
-:1007A000F0FE4F594D21DD541CA7C21D26791EA213
-:1007B000C9CC17F3923378BFF9221FB43005DAA3FE
-:1007C000BE29D6E66BB0E91E13BFAF439B9F71BD38
-:1007D000B42E0BD7D53C53E36018C67B5DD0ED7AC1
-:1007E0009DFF77783FDDEB8B8B8EE37AAB31051580
-:1007F000DC0FDDC0421B9098172BFD4FD8C7913CF2
-:10080000F80BAE8B26D93FC101E5F3FA9EC2BB0BB4
-:1008100068BD7C96356D38BC2A5FA8F0227F209F8A
-:1008200045F92301EE289D6EEAA744B6DD60F7E0A6
-:1008300053B583186BE1F9C6EEDCD8BC8089E69A23
-:100840005A0AD10E79BD3D4072E37AFB2394D7F466
-:10085000E7317E6736C0B5E8AA4FE85E13E65A3244
-:1008600001ED7B80373D3BFDFF1DBCAABD372CDF72
-:10087000F6238326DF76B475A57EB799F1FB69660A
-:100880000FEEA1FCD9E685160F9E8368C6FCCF72D9
-:100890008A2F911D87E784E99E13C924ECAE2F9A15
-:1008A00097CBD7616FA39BECB7A81C1779E5BDA5C3
-:1008B0001CEEDEBBDDEA3D27DCBE5BC2F83D29EA6B
-:1008C0003D27CB6D54AFE69FF7EEE17EBCDEE72718
-:1008D000D07929B0DFC85E60A93A0E5F81F67E1537
-:1008E000FC933262F9D2DBF4DCDEDCA9F354209E07
-:1008F00077621CE8AFC47FBF9AADF59BA8E544BF03
-:10090000DE930EFFEDC817CB4BBC7912F0CF32034C
-:10091000F7DB017FEDC2B31535ACE529BC3F701E96
-:100920006BF9856E1CF1979FF86BF227FC5EC1187E
-:100930007F2DE1FC1520A1A4F25794AF8A13F3ABED
-:10094000FCABB17DAFBDFF574D68A70E1A892E6A6B
-:100950009E5CE23A8E83E7B49EC3E394658267EDC2
-:1009600048F07C113E8FE7AF4CC6F979347ECF5406
-:1009700058C05A16E3F73DC9FE76843FCAF71BF804
-:100980007E6418DCB285F8E3D6DB649E3F9ECCF52E
-:1009900015C62BB2E0FB75E2FBB776733EBAD56A9B
-:1009A00020BEAB1B6CA47C2256CDE30E1EF81FDFCD
-:1009B000077A09BF8B44BF85CE523DB2ECC25A6D57
-:1009C0007C6291458D7FF8F4B81E6F5DA83F19AF2A
-:1009D000EF17B1CD9F60DEDB228C63A8FDE0BB8FFB
-:1009E0006747E31813308E715CECD32F027F23FF2F
-:1009F000BF9ABE72D7DDC0B7131E2F29437FCE9C8E
-:100A00008C554F6D85F2F7764EA2F2AB1977DCFB71
-:100A10000ED6F71551B91A2F71C1FD4623EF5F5C51
-:100A200071DBFC02F8EE71B31817D715EEFB92FCE0
-:100A3000BD75D0CE35756C19E623560BF970F16E85
-:100A40009E0F7FC355569EE2B9D24D7EA3EA245134
-:100A5000FF753EEE5BA5FF568679A9D563238BE92A
-:100A60003EC6B21F4FC2F271E993C523C54D26178A
-:100A70004BA189809F6A076F5F5BF6FD6CDCC757EF
-:100A800057F1F2644F65F738ACD75D5A3CD2B9D014
-:100A90009F8AF5143DF724D6E98BDE0FE99C93CFAE
-:100AA0002479708ABEE91FF27B892C920DFD8F3E5E
-:100AB0006F81827ED2D95E9EB758656ACFC2FDEF44
-:100AC0004D7E4339E69FDA4CA5C7D1CE489D5E39AD
-:100AD0000DE93BDBC4F4A89780CFFF85F8FC9A4F63
-:100AE000F25290B92C5A3E57F9A84EE5EF6A2D1FE5
-:100AF000C3FAFCD7ECF4CF97AFA3F1317CFFDFB1A1
-:100B0000FFA22F69F54A74BC84F59638FE6872001E
-:100B1000FFE2E55C0C8E7E5A57399815360ED75D8C
-:100B20008FBAEE220887413744E73EF225CF243AB8
-:100B3000F0388AFE57E1CB05D9C6CA86C3857F8ABD
-:100B40006A9771086CB60CFC2EAF877E5EE688C192
-:100B500005DF676350EF6FE0F0EC965AB8DC107673
-:100B6000B1BA3F6E52E73BA09D6F45123FEFEC429A
-:100B7000FF05F673964EFA6B70370BBDB9D0E47B68
-:100B8000C80873B8C5BE8CF8E1AB2CF03CDA27C6B8
-:100B900054BF634C3AEEBB0247C205E4CFA5BC018B
-:100BA000A077DA9838FB44852B111F4DA3C8C344A6
-:100BB000B813F110A3CF10D957EAF9A9E8BC12E68F
-:100BC000D361E5EB3532CDA8DE5F528CEBE26D6987
-:100BD0009227DE9E7E3B416F27C2A5DA11AA5E55A1
-:100BE000E1417F11FF7EA41DCF90DD38662CD99D99
-:100BF0002ADF640AB80C3A69C438EA8D6374AA7FA4
-:100C00004E43C7C4734E2ABED4BCA0443CA9793D10
-:100C1000C3E23509F1C8D1DA49603F8F710CC79F33
-:100C20001AEF7144FD5C029FA512C93F87F073CD96
-:100C3000F6F0F309B5ADFC9C7C6D0D4C0070FFB671
-:100C4000F01FA8787EC8EEBF8DF347781AEED3BFA9
-:100C50003BEF698A73A8F7C825E267F928F8198D70
-:100C6000CF47833F2DD5B712BF7B5E1AAAC0CA2DCE
-:100C7000E9E2FE41E62FC07560B71554A21F02E4F9
-:100C8000EA679FE1660EAB80AEE50E7F33F2F9575F
-:100C9000996F0ED2D751E3D773FF3A23FFED5AB1C4
-:100CA000DF9A23F4EDA55D32C507AABD131F9B850E
-:100CB00076E21B7A16A4F5EE25FDB946C07F099FA2
-:100CC000D8DEC2F5EECA377F54012B864DD8AE8BE5
-:100CD000DDAF00FF26069334F72B4CDEEFD094A750
-:100CE000F4676BDA5F353056535F1A9AA4A9BFFADE
-:100CF0008D324D79DAD04C4DFB6BDEABD2946784EC
-:100D0000E76BDA7FE9EC024DF9DAC8ED9AF6A7C491
-:100D1000BE9805BC43C51978BF389FEF759F2ED587
-:100D2000F4FB6DCADC37900FEFDACCF3972B01336D
-:100D30009A7B267AB85DD102FFE374F52988AF1556
-:100D4000606F63DEF2CAED5ABBA37E70EB0694A51A
-:100D5000897915AB594B155E49979857516D5BA230
-:100D600043BEFBA731C2EEB8865D23EE85F9AB74B6
-:100D70002D62E3FF5B7435BAB47435BBB5744D2E88
-:100D8000D6D2D5EAD1D23575BA96AE76AF96AE69DF
-:100D9000355ABAA6FBB474CD5CA4A56B965F4BD74D
-:100DA00031F55ABAE6B668E99ADFAAA55F4160B59F
-:100DB000965E09F456E5E5B8AEB59A7651BAFBEA07
-:100DC000291F667CCFFD9A7155BA07E07F9CEE2DF6
-:100DD00094AFFEB7D29DB120F95F13E97E3681DE74
-:100DE000A0AF3E42B90076C6397C2E9A20EC79DF5E
-:100DF000C876862A7FE2F57AFCBE7534B9344C8F0A
-:100E0000897DECA87A2C611FFB3E66F1907DB49938
-:100E1000FC3CB709FEBC8CAF66A01FF507A49FDFA2
-:100E20000740A6035CEF23DCF09DF79326939FE138
-:100E30000E16D2D3BDBF98890883DE8989C932DEF8
-:100E4000E7E3A6E732A1BF970B3F8437D99F92C350
-:100E5000FD0FF919F8DD9C217EFFF25B695FE89ECA
-:100E60008293E887079D721AFDF0F0BC60E6FC7083
-:100E700046950F5EE676C6E16DE96C89F4323A7C00
-:100E8000703FBBF4AB12C51996FE9E3FC7E770BB1F
-:100E900037F1D9D1AAE28DEF876EC87193FECD618B
-:100EA000FDC27E637ECB381A87FBCD9FE4F78F3E71
-:100EB0002B3165BA838E49111D334D1CAE67F5CCBD
-:100EC00084F87B86F9DD8897EF28209A789EFE24A7
-:100ED000E487A5BF7F672CFAB164D97513DE2F3D77
-:100EE0001DBF0770CCF95A8B847EDD4C578B847EF6
-:100EF000A361EF0FDD2FE1F9C26899F176F88778E9
-:100F000050FD73C53A1EA78EDCCDF7174F7D9D911E
-:100F1000DFA9A3355019C0F8940C0607E6B1E8F92B
-:100F200079E41B72B8DF2D8B0DD1BDA6EC356117AE
-:100F30008AFBE04B44DEFB0511E759B1C7C4304FD3
-:100F4000A2E4E05107C67556002D87509F297EBA4E
-:100F50005FA364C7AB0E7ECFB8DE8EE7D8543D3AB0
-:100F60003ABD1576262E7F1CE8D832921E5F93CBB1
-:100F7000E3B31D6D35B3302EA3C2F3609B7716F239
-:100F800087AC7818C693F0DE9DF8FC338313EAE350
-:100F9000D6AF62A9D194F5161F5D66B1A1AD85F8F3
-:100FA0004C2FEE07DA98B3D616FFBB01AB7374E291
-:100FB0001EF200433B9B8B7A7C2A67503EFC91F1EA
-:100FC0007DA8D105E3C4CBB57BF358BC5FB9ABCDED
-:100FD00047F06E90FC7E1CC458C842E614CC5BC03F
-:100FE000B397F07EC7F56F601E8DC1BAD613728FAE
-:100FF0008E37A34BB9122F971EC801B9941C934B7F
-:10100000DF6D3B4B78EA685B44DF037C318C9F05E6
-:10101000B2B87DDAD1B684DEEBC0CE427E7A65C747
-:1010200084A36EA83F01FFF09E1CA393C3C5CAF31F
-:10103000483F2D167C803EAB5CE09F13AD7AE2B357
-:101040007B722D415C84F7BC3DFE28DEF369005EB7
-:1010500092FF06B8A3DF11783208B904FCE4C3F5A7
-:1010600066C856C8FFEBB02D203AFD77C753F16B29
-:101070003033BA87C6906B21BFCD1785F37B390912
-:101080007ABE3C8FE4E83D022FAFECE0794727EED3
-:101090006564BFDE731FF7BFDDD3C828FF9BB5C2F1
-:1010A0005F458C6F54799D8E3781C0CB9E3610344E
-:1010B000458C3DDC66C293572C19FD64E36274ECE9
-:1010C000F12A7674C76FAD76D6E1F3E1E9A77B50DC
-:1010D000AC6C99F5BB217CA28F1BBF6F6B6141B4D7
-:1010E0003329160BDFB7D74319BE9F22EA53FCBC46
-:1010F0009C2AEA5317F172AEF739A91A014B88837B
-:10110000E45A1CF30A51EEDDC5F8B95B71EE7EB707
-:1011100090BB632C8EBA6AACFF1AA37C7CB5FE71BF
-:10112000519F6539D9350EE5F2426DFF1D020F99C9
-:1011300096933DB3295EA2AD57E31BE9964B6F50E2
-:10114000FF126DFDA3A2BFD572696836D6176ABFBC
-:10115000FF90A84FB67079C87CFCFE54B5FE3BA248
-:10116000DE8CF5F87D8FB6BE5B7CBF430A127DE84E
-:101170008E585C3FE9DC5FDAD7C6AEC5F5D3D3162F
-:10118000A175F470DBA7442709992C3DB6AE6CAD70
-:101190006CC4F3E092906729EEB0D73B82BC53EB6E
-:1011A0001D367EDE5D7619888F8C16212FC43A8C11
-:1011B000CA0BA9C5C3998BFBB13F8F9F61815D416C
-:1011C000FB220FFE909F73EED5317F9CDCCA6E48E8
-:1011D00062FEB8F6AEBB1C9A72C6D7B235ED9D0B57
-:1011E000C76AEA2DE59334F5CC9B4BEB65ADE0ABDC
-:1011F000A492324DBD7A0E9FF5E46AEC677DE14C16
-:101200004DBB4BC56EFAFD9033F3D4DF19F1985006
-:101210002EACB58ECD44BDF34CDB7434B2D9B3B033
-:101220009EF0E8D4013BCF2F3E807159B4D7DBBC90
-:10123000F47E1FD483E5C29E84F5E686F67BDA6CE5
-:10124000547EA2CD45CFDD6D6E7A3EDE564CF53B29
-:10125000DA3C547E0CC6C7E7A3300EBE7FA4AD8631
-:10126000CA5BDB7C54DED2B688CA0FB5F9E9F99DBA
-:10127000B67A7ADFDDD642E58D6DADF47CB02D40D7
-:10128000CF8EB62EAABF46D0FB8038C778A0929FDB
-:101290004B4EA4E3AC5C49732F9835963F302B1727
-:1012A000F307FAC39AFBDD71DE349E99CF3F71BC20
-:1012B0003A1C0FBE3B890DB527F3754C71C7F1037E
-:1012C0009EF5C9C0EF635A381D0A0622549F55CFB8
-:1012D000695127E065CE00CBA9E0C750B1DD0569B3
-:1012E000A82A99C76129BF8CB9609E15E27E1C624D
-:1012F000BBA00EE152A673BDA9D2353A6F3B87134E
-:10130000E73F12BC5F13F397CBFBF9FD17353D2187
-:1013100064FB246F0BDD7F615AE40BE1EF57387DEE
-:101320007E3A8F3FE9D3B9B0B90139F3E997991BF8
-:101330009E390DDA7D4FF65D659AFD85FCE9C3CCDB
-:101340007D358C5BA2DD9F2415AED5F433E5DCAF93
-:10135000A93738D76BEA97AE29D8E0427C8E611462
-:101360009F316E6E6718525CDEBB95E0DA24F07E2A
-:101370004172D379DEC041353ECFEDF3EF09BDC2F6
-:101380004C9B693D4CB0F362516A40877AE1DC8F37
-:1013900052491E3DFD842E88FED7892CA8C3F53FF7
-:1013A00019CC3DAC9F8237E8CA74A58A8CE552E619
-:1013B00096B17C358BD0FE04ECF3F5B9DC3E7FC2F0
-:1013C0008CF1C15CFFF778DE5288F46691A06791DA
-:1013D000BA1FD9AE24FA65BB72890FB5E7993A8571
-:1013E0009DDE6EAFC8C4B8E88551F2CAACAE993381
-:1013F000F177B4AC59D3E9A9BE7FC8AD1BF19CEE1F
-:10140000E3025F2ADF4F0426177CFF38CEE37CF926
-:10141000BB19B8DD6B2A8C10FF5F90BCAE2588D756
-:101420003765CE878359342F45E0553958E95A023C
-:10143000F853DE1EE709B0D8779E6EF3CE54945869
-:10144000B948E445EE6FAB9B591DF7FE75014F316E
-:101450001BAA41FD545CA2F304696497467E990B74
-:101460007BBC78CE5C29631E146F1359CF7AD4D518
-:10147000CA5F64CA73518ECD606ED817582C21860E
-:101480007941AF47E7C934BFAFF43B5B752ADD173D
-:10149000981D957BA813F1F79486907F7ED7ABE7D4
-:1014A000F33AA6AD2FB6F0FC9D15C586A05BC2B081
-:1014B0007A0FDD8BA7F4490C4D7FE52FB3090FECB4
-:1014C0008564E2BFE4ED53E94AED9B14FF0F91BE42
-:1014D000E743EE1774E3042F42BBC6C986BD688F8D
-:1014E0004D40BCE0840A8B09AFCBC57CF7B72D21FA
-:1014F0003CFD5ACCA33337011EE6F1E2BD912B7AB5
-:1015000055FF87769E0F9557DD8CF7EC750CC9C299
-:1015100056D2E273937E682AFE36DDF930C0251379
-:101520009CBF46FACBDB2BE8F7954081D0FC1A9F95
-:1015300080FD7E01C9A31AD2DBD374949F9AC85749
-:10154000A7841C6BC9E5797F56D79767E2EFBCC5C6
-:10155000CAB3883F9FD1B162CA2FD1F1FDA59ABF0E
-:101560000186831BF775A579BAE83D1AF3515FDB55
-:101570007594F727EF49A2F389B25DA13CE34E4B86
-:10158000B56D358E635328AE32579E358476B3D110
-:10159000AEBB1AEDEEE37BEF1FC2FC12395761E8D8
-:1015A0002FEAB429DCEEC8D1513E9662AF36611CF9
-:1015B000A6C872BA12F17974CF37C9BF217F43E44C
-:1015C00088087F925E90AC93B5D0F8811C45DCE72B
-:1015D000E1AD2DCD10210437EE7F6A3E423FCA7146
-:1015E000DB2533DA2B6ECB0AF2A715E615D07CF497
-:1015F000186F83F213EB2ED9516EBDB96783A30028
-:10160000EDE7A0423648F19F3BB2E9DCF91E039DAD
-:101610008B57F19A1F503471BBDC566DD99810BFAF
-:10162000D3279C4BCACA2B107A6E110BC5CD47EF3E
-:10163000E2FB35E6B4D07EA7304F629FE962E53128
-:10164000A2BC5F1FC8F6007E8EED59918FF3BA726F
-:10165000D84F79BEA3D9FB1FE7BAD5DF4332EBE8F9
-:101660007ED59019F37E9F6A63E968DF99820AE567
-:101670005DEF13F2ACD0C2F9DF90CFF93CF159D84D
-:10168000C3D79D722029988C74B3F59705804F2697
-:10169000BF328FB941FF15DABCE43F2C6C35A4632F
-:1016A000FEC0DC1F5A884F2E5992C84FA8B4267925
-:1016B000F07DC7DE8A62771CDCC1365B3AE6E5EC7A
-:1016C0006D33A5A39C0A8E225FC7D97594AFECD663
-:1016D000F17CBAF9791CAEF979FCBE9779A2FCA429
-:1016E000125880703E09F4C43CE9A39BB93DBCB6D6
-:1016F000DD4470AC7D731CD955A3E1EDE936573A52
-:10170000DE0FBF77B32E1BFD4795DD859BF09E84D2
-:10171000B5567E4FAC9C3AE9314C45673FD533B462
-:10172000DF3B52667A96C5C97739755631F2952CEA
-:1017300007B2D12F7267DEFC9B315F12E8B713CB83
-:101740002BFB4A79D91AC8C6FCCAE6BE69BC9C1EE6
-:10175000D889F995DFEA9BC1CBB9816CFC1DA9B68C
-:10176000BE6B79797C60279637F655F232FA9E4047
-:10177000766EE99B7333CAD90E83A71E05F20F005C
-:10178000FE1280BF5F3CB70ABCA8F5CFE17BC0F377
-:1017900021F14CAC7F41F41B18A5FE25513F38CAFE
-:1017A000F82F8B7EA151FA1F13FD8E8FD2FF35D1FA
-:1017B000EF8D51EA7F22EADF1A65FC9F897E43A301
-:1017C000F47F57F4FBC528FD7F29FABD374AFD0792
-:1017D000A2FED709E39F10EDC3E2FD58EBE60F42EE
-:1017E000C07763418EA05C2AB66E76E03ADFDB55A7
-:1017F0004EFCDF51C1E33B2ABF8FC5DF6F827A5DAC
-:101800003EBF4F4A97CFE33CCF88F1810FB720DF2F
-:10181000AD7D5BA63C9B0E9DE76C10E5E8261DD9CF
-:10182000036BDFE4FBF3B5DD4A30FEFCC53309F0A2
-:101830006F10F0750A789FCCE3F139A3CB955E1B4E
-:10184000EF47B269CB9896857217E437E5ED1677C6
-:1018500057751597638C4C471688D2680AE17D0D41
-:101860008A55E8055B794F31C26751E89CBA6257E7
-:1018700042FBB1BFAB9CEC3B15BE4E8B42F775C92A
-:1018800056AE07E6FE70960DEDAC4EE61FF2627F97
-:101890009742F6FBD1AE321BCA3D83F52E1BAEDF5D
-:1018A00076379F5775537112CA6BF9211DC9EFE343
-:1018B00036BEDEFB5C3AF25B805EA1F32C20AF3DCE
-:1018C000A82326B0503B9D8F78F88525DCAFC7ACA8
-:1018D000A515745E448D434B4A9CFD7F59E0275FFC
-:1018E000E81105F50B3C9F2C17E71C02DCFF046494
-:1018F000738D893BAF79394FE6E740D438A25C4B12
-:10190000F716E5AD5334FEF79C7BB5654382DE5098
-:1019100012F4CAB82E9093717AA72060D3944FE640
-:1019200009BF8E8779D07E9DFBC3CD240F2FA17E6A
-:101930009346977B51F92BE4F193E21E9E2703FC1B
-:101940001CF1D1CD653F417AAFEDD6D1BDD35F5407
-:101950008E3E93C7B87FDA0F7A07ED198565E37E6F
-:10196000E9F3F0305EEF73D0BD0A9F838FF18F965D
-:101970003B50DE8EF72BA47786E98DCFC1D7B3928B
-:10198000E73D3FD2D19EC4ED6A1B9F77678693DF08
-:101990004724CE1FCAC25E7B50F8C195D4B96EFCF5
-:1019A00089904E7B0B9537489ECC1BA0FD46C96F96
-:1019B000C3F21B8E24AE777293880FF7A32D43F7E3
-:1019C0001C16F8D03FD21F34A8F71486F0FF0E6221
-:1019D0007E8E7A0FA28BEC33710F63EFCDD5D85E7C
-:1019E000B14D469373DA138F6DD1830D7AD0C0A2B7
-:1019F000EDF13CD533C775E29EC4DD5BD05E3D980A
-:101A0000C434F7401E443F3A8D17DC82F73EC2F7DC
-:101A10006E90610F767DFEF7B658B262F054B90F42
-:101A20006C69A73C59BE2FB1337E4FF779773805E3
-:101A3000970BEC4FAECAC77DF99ED3199ADF5D13A1
-:101A4000ED5345FBA6C148D30137B59F960FEBA0D8
-:101A50007120925242EB2B5211DF3E45ECF7E3DA54
-:101A60007F89C61FA57DB10ACF81776F2DE1ED2B50
-:101A700071FC0BEE7006E5BC24C093367CFCEBFFDA
-:101A80001A3C9344FBF3A177A9FD0516CE9852406A
-:101A9000FD6EC27E17DF7AB742CC3B03ED64908ABD
-:101AA00037E37B34B7F8EFB1B490FDDC6FEAB1A156
-:101AB000BD66D6F7F850EE16E2BD4ED363CF05F9FA
-:101AC00085DCAE4A78DF6F6269B5C88FAD3ADABFA0
-:101AD000F49B86CA4AD09E7ED102320FF5C23A0FDD
-:101AE000CAC181F05A4F09B4EBCB9945FB8A838672
-:101AF000967E3ADFBBC442E74FFB6C3D365C3F66E7
-:101B00007B8F0DE308F27DDC7E52965AFC4F213F1D
-:101B100085D6162F8F5BBF556E3DC1DFFDAA65339D
-:101B2000EE03BAF59E9E0968675B15CA3F57960E8D
-:101B3000CEA7F3823FD03192EF30AF2A287736EA32
-:101B4000E8BEFA87DD4BEF413C30C5E7AB827E79DA
-:101B5000E98A84E72F1E547C268C5F1885DDD6E742
-:101B6000E1BFF7AA7E7787B02F77E4F37BABBA9714
-:101B70001C287E0DFAF5B5AEEDC7EF99279A18E649
-:101B800099F5E59CE9C6F3A28FBB60C70B78B0342A
-:101B9000E8E8F75A1EAF8536A9E8CF3068FC15CFC4
-:101BA0004AFDD43ED0A8A37D82A5C4A0F16FA43580
-:101BB000E8BCE8773CE0F66F427EBBFA6DE506FCD8
-:101BC0009E6BBC6243FDF490EB17261DC09952AE8C
-:101BD0001DD7364B3B8EA35A5BEFACD5D6672CD4C2
-:101BE000D6BBBE6648F0D768CB29C8478847900166
-:101BF00016D04349BC8A2559AED0EF8575FB77F5E1
-:101C00004C8036C6E440E96B006FD2A424DAEF6F53
-:101C10007C3509171FC81F467267E3144679AFC7A2
-:101C200072BFE9427D9A889FBE1C03CDD75208F847
-:101C30002CC0FDFA59FA5D2F0B8B6B5780F8F13EE3
-:101C400093CFF7EFCC5581FE394672F059D57F7CA2
-:101C50000B3F4FD5D7CAFDD20F2DE2798134830ACD
-:101C60005CDFBC7D0AFECED854F4DB77DD8DF98EC7
-:101C70008978CDC4FC3239C61F1BD4F32B787AB2D5
-:101C8000828B655C7797DCFCFECD9705DF1C14F733
-:101C90002D44DB23FE3218DFCAC2786FE6ABFE07A5
-:101CA0007E1E609B1A8F1165BCC610CB078F3B6EE2
-:101CB000C0F5B46DA1A30CD7D3466197A5E618BCB7
-:101CC0001301DE47DE3004A4ABA0ACB0E37AD0E76A
-:101CD000071DFCBB86379302789EEA1157399DCFCA
-:101CE000FA389FFBF39EABF4FCBC96D6A342E7DF29
-:101CF0001E717ACC65DCDEC0BBAE19A51681697198
-:101D0000B4B68CF6A98F783D665CAF8FE478CC983A
-:101D10009F6CCE526CB88E1D2E85EED17AC4E4B77E
-:101D2000A1DDE2000588BF1F67C8ED9947E7920073
-:101D300087BA0A1E1260228F0FF3E8D204BEFA5C43
-:101D400077D9F0FCBAB3F0D0B7D0AF9E86E3A5F058
-:101D50007E8827BBC0D3A57C37CF4B16E3A7DDF524
-:101D60001CB5C7BFCE8AB8F13C9CBF0CF358907E1F
-:101D7000074D7C5F1D273A3EF392DF7EC34F38DE6E
-:101D8000DA73F9FD4186358CF661CF55FAF71F45B8
-:101D9000FC6425D13E3BDB955D85FC91FDC6CE05FF
-:101DA000780E61C34FB8FE342CE7F1A66C8599BE5E
-:101DB0008CF34EF7DB108F89EB30EB784F1D32DB65
-:101DC000FF054658D4C60080000000001F8B0800A5
-:101DD00000000000000BD57D0B7C94C5D5F73C7B43
-:101DE000CB26D9249B0B212124ECE646201736E193
-:101DF0002222EA7209A222DDC81D233E210102240B
-:101E00001040FB46CB6B161214156BA8A86851370F
-:101E10000A142B6AA88058D177B968A95A4DABBE6D
-:101E2000A55A692254416E31B4EF4B5B3FFBCDFFA5
-:101E3000CC4CB2CF9228EDFBF6F7FBBEF86B87795E
-:101E4000E676E69C3367CE9C7366765702BBCDE799
-:101E5000602C61A28DB9EC8CFEFECEFF976A61EB1F
-:101E6000CD098C254DE1DFF342BEA7248DCF2D6235
-:101E70002C79BAB17E0A0BC9BB79BD239D77B058C6
-:101E8000C6065419EB3D197DAC9899900BF96EFE7E
-:101E9000EE7C93D67EDFE0118CF9532D9E6D2EC61D
-:101EA000D2C3C663EC9B08E4356672FD3D8BB1F18D
-:101EB000AE78C6FAE17B9DCB57C8D82E9B738223A0
-:101EC00089B1CE15CCF30C6F3FFE950D73DFE1F9B0
-:101ED000FF4A77382378ADB423CD6D05FC3BDBA7F3
-:101EE0000F46FD2D16FDE9685EBEE5687FE6D71852
-:101EF0008B886675AD1C4F3613D391FE1D7FD7625C
-:101F00001C2B8D33DEC527359231DE45C094F2CFD0
-:101F1000A7AD0307E63B3DE8CFDD66E7FDB65A9C7B
-:101F2000F9169E1FF9F4630F59D3310F0EE3189A77
-:101F3000B6978D66ECF9C37CDC013CE77FF2A189A2
-:101F4000165E1ED55DEE47F92E9349E4FD81872686
-:101F50008E656CE0E1D6350E2763654FEF78C8CE0D
-:101F6000F116F92B51EEE379BF0578A919D4CEE724
-:101F700077306309CDBFF177112C82D72B347B36B4
-:101F800023CF3E8964DB787EC79EB1B35DBC5E63C0
-:101F9000CC28975EC0D8349746F32F43DAEFD27936
-:101FA000996D1EDDE3B8F4FB8D126F8C798EB670DF
-:101FB000FA163E6B63F7F3C23CC00D7AB544069E39
-:101FC000017D9B1FE34CC7589553D0BC6AEFFD19A8
-:101FD0000778FA6A4C59A58BB7AF8A99980C78D2D2
-:101FE0002E32A62772BA35D899CE719596F4338DD4
-:101FF00071F806261D1EC71CE09BB6354EA4755110
-:102000004C0FE1CBB48B16A60F477F5EEA0F7FF62D
-:102010006470A1F86B4AD0D91A0E8F9FE37A1BB86F
-:10202000D319D5A11581F1277ADBD5FAC8049FB25F
-:10203000D9AD05E03A81071BC7A9B584A70E4B307F
-:10204000A297FA77C87A66BB23681EC653E75B4738
-:10205000A95F87E54CBBBDA79E3D60217CB01A16E9
-:10206000C8D1084FFE08E4E31228CFBC5E575232B5
-:10207000F89F1172D32CEC70041F97B897AF9F5440
-:1020800016A4F4498E1E47162AA5C77F1ECDF089D7
-:10209000818F9F616C72285FABD434C844F065D7E0
-:1020A0009BFA9DE0F8C93F14497058D6B340241FED
-:1020B0002C1BF4E074CBDEC0021637EAD9FA9D4837
-:1020C000443B97E403A789D178AD43B1AE36BFE571
-:1020D000D8C0E288BE24773647B16AE04B8DC7D8B6
-:1020E0001AE28780E48B2D0D4EA2A32A1F5873306D
-:1020F0008C8E09063AAA7A691707103D7BFA0D50B3
-:102100007F69F5BB891FD22E66483E717D47FF99D6
-:102110007DF49F42EDFBEE7F208DFF64F0C3F8A9B4
-:102120001C153FEEDC1DEFE369A4B5D9E7E905CF47
-:1021300069B71BE5E4B07D46B9ABF01269F52695A9
-:1021400071FC47DE61F2B4F0FEAE386AAC37D9FDFF
-:10215000513CD6634FFD60D234D4AF15F5AF3A6928
-:10216000ACEF1BB727ACBE80EFDA8BC67AE1F4097F
-:102170008797C3D56F46085C13EC1186F6B32B2EF8
-:1021800081ABDFAC10B8AE4B31D6D7D7F40ED78DBC
-:102190007911DF0A97AAF7BDD197572F7C1ED32656
-:1021A00047F48177517FD6ECCBEBF796EA6FAF77A8
-:1021B0005B7DF8387EB95FF1B5C5D77122FEC19756
-:1021C0004062BDC91BC9F75127EB6458475D725D7A
-:1021D000253027AD67BEF035ACAB0FF0CF54C686C7
-:1021E000B87D5F437E4DB07BCB1FE15527CAFD8A8A
-:1021F0004DE13D5E89CE7D8537175ECA7F8CAD256A
-:10220000B85ED3749DD13E6BF76CE3EB3B3F8DD949
-:1022100053B91EC052029937C73016ED56F29A8B49
-:102220001A0EE75089BB1706B4AE8CA7751E48007E
-:102230003CFFE8B8FDDDDE0477BF9EFAE1F57AEAFF
-:102240000B3CD96CAD2B006767ADC383FDE1431434
-:10225000F176CFCE8C089A39BECE5B1DEB352E675A
-:102260008E46CF7BAB1FC7C307B1BA0BFDCF9E75A0
-:10227000FD3DC86B07135D2B397CE72BDA4701AFB7
-:10228000DE683DDBCDE1A8B1EB8392F914CFA6EB7C
-:1022900083E3805F5F22E195FFA3D0D72BFC029EF2
-:1022A000899AC07F629C5E8871269ADA9EF2E19BD1
-:1022B000A56D14DA31673F82EFAC8DCBBB5ED6BF24
-:1022C000C2C378D9CF01ABE7EB4E3EBF031BE33C63
-:1022D0008D1CDEAAC459F396F3A205265F72D06C5A
-:1022E00080FB2A8C57E3A818940AB8AD126E7B3F86
-:1022F00089776FF6B7C1DD88F1B0AFFDBB16D8E6C0
-:1023000016B444FE157F7CE07E9E8F305DF810F29F
-:10231000A3B3D0E4E17B04DBC2F50B3BDF57DE97D0
-:10232000F87E92AB3FF604FABE1EDF53A244FB9444
-:10233000474D8146DEDE37FE55A2D3B3CB1C1E339C
-:102340001FAB82B96CE0DB4AE6B501FE3F8EFBDBDA
-:10235000EBED7C7E73DCFA74CCE3B64453C68704A1
-:10236000879E5FC6F98D8D15F8FF2E7E606C838980
-:102370008D62EC66A91F2C90789CC6BC568C33836A
-:10238000E9568CFB9B73362FF4D2DF4007E5F0CE85
-:10239000627EFA3E870528BD8505A9FEADAC9DF29B
-:1023A000BF8E2E4AAFE7F0953D363807EB3104EF8C
-:1023B0004B24BFDC9624F8E58BFEC0FBA67E97C5B8
-:1023C000BF659AC0DF10B7BECA4DEBD595E4014C8E
-:1023D000CE09037D3121EB67623FC17F1667CEB71F
-:1023E000AD9FB6AED822368CE4812395E3E13A491D
-:1023F000CAEBBC4BA760BE902058AFDF93EBB5D4BF
-:10240000EC60499C2E6D2E732082C33279DC8A14D5
-:10241000CCF7176BD8AF8673FAFD629C9935524D95
-:102420002FB59B2AFB9B3A70D229E827EFB260D2E6
-:1024300008DEAEF4A27E388EE367AA796713D7B8B8
-:10244000D9E481D6CFDA43E4DAF549BB2C8CEB2F03
-:1024500037641BBF4F29E0F910B93B95597ACA3947
-:10246000FD0F003F903BACD90CFE7DCC1D93047D4D
-:10247000850D6543C5F9805323643E5DF66F6CE7B7
-:1024800079BBB7DDFA53E0A395F1E7E691DE611180
-:10249000F359F69E99F4CACF1A18388F9DE0FAA125
-:1024A0003797B1CFB97E81FCC986144ABFE4FA00E0
-:1024B000D2330D79547EAEC143F9AFDCBE9F804E5E
-:1024C000F3D77F65C1BE746FA4C2B7806395E4BBC8
-:1024D0007BD3473DF6578ED77BDFE50B83C353DDB8
-:1024E000DA3C0960AF4AFF6C2DF4E755CF691ED482
-:1024F0005BBADF6B737078161CD6EF019917BDDBE2
-:102500003E1562A216FA2BD71BEEB3FAF660BC9109
-:102510001F9D48D67905EFFE8EB71279FD2F1A461A
-:10252000135CA71ABC04D7E986C9944665FA5E43D2
-:102530007D2FFBCA86FA37EDECB0A4F1FAA55ECD8B
-:102540008BF5788D9705021C9ECD5621DF3773F9E8
-:102550008EF539AEF0E6276F6790BFFA9B683F2390
-:10256000A1B234917F9F3ABAC2827AB3BEE632CD2D
-:10257000DDC387DFBD0E053E6A255DCEBEA1119E7F
-:10258000CEEECDFFDE55BCBF378E989999C3D57579
-:10259000D14470751D8D0A406955F556EE31933E54
-:1025A000B932DD1600FE56EEC9EF0F7DEA34A71BE7
-:1025B000CBED19EFF40BFFE6D243E4E8E984D6FF54
-:1025C000FA1872EA5321A7B8BEF9F913906303070A
-:1025D0007840F77356AE9703D1AC2E1AFBD8329BD6
-:1025E0005C5F5CCE207F3A4A9C8347BD98361EEBE9
-:1025F00005E3B96C3D7228F7C5C7327FE0EA196F71
-:1026000047EB828F9FE0F9B30193DFCAF799B3AC30
-:10261000F5DCCF2147B73A3C381FDCAB7178B08F7F
-:102620006E1B40F93CCD12554FFC1CA0F59AA7B982
-:102630002CF55CFED4FCECF101E0A7D7380E46F394
-:10264000F2D73646937C7ACDEA39568FFE9E14FD3A
-:10265000FDE487777EB60FE983B5257702C999092E
-:1026600084EFAA1F2D1E8AF67C9F66A9BCBFE75F78
-:10267000D182917C7D166E3AB03695C3376C4B870C
-:1026800069004F8BB76A8D48F3D36F3862E6E5F681
-:102690004C17C1317CA7DB9C86653520F0F1B5B4C1
-:1026A0007F1BF7F5824D5F8DC7F152EDEF43B5D635
-:1026B0002F5B701ECE385AA213FE9AA99F3DFBA72E
-:1026C0007D700BC33CB8E600B82B6C1EDA4F02FEDF
-:1026D00016D0F9AC9EE7B91F6BDAE77F1CF43DAB6F
-:1026E000277BB0BFEC35F963C7A0FE310BCDF39566
-:1026F000ADBF8EB5F27CDC6E2B8BE4E5B5C59D934A
-:1027000050BF36DD45E7F0F4A7AE9B0CFC2CDBBDDB
-:10271000A785FAA9B17B34ACB33D17DE4AC379E88B
-:102720007AE6C901DFED16F907267A3DE0B7EA96A9
-:102730003F8B7C9B8FF23EB3DF6D41FD4AA1E73CAE
-:1027400026F731D65E44F28E58D9D543AF0778319B
-:10275000CA37BBFDA9758E9EFD8FEF5BF999BC3C16
-:10276000D526DB3BA765F8FE817DCB26F721D5DF9B
-:102770006336E68FE4FDA4F3EF1AF6559BD86FB7E6
-:1027800071F9027E51FB2D1FF7AA4CD1DE0B39994E
-:10279000C637D7623E9FB4C72202B4A75FE6F84AA5
-:1027A0004F5A1E25E499D23F662736BEDECEF1FA97
-:1027B000A758FD3ACC6F81DCAF99C59382F91D8F84
-:1027C000F54EC6F835F6CE0CCC81EF8753905F6698
-:1027D000E6FA535688FE64BFBCFD3022CE7B33DA66
-:1027E0005F6EFDB151BDCBDFB15DA349FEBE2EE5ED
-:1027F000EFAA3F9B5831CFAF7A2482E409ED69BD3F
-:10280000E0E575BEDE752E5FFE0376039E5EFDA7D6
-:1028100076339D3F0E9B6ADEE2FB290D9D89FFEB1F
-:102820006C8C1B41792FC87CCD9F4CBD9E0F55CA27
-:10283000E954877979BF36DA1BAEFDDA69A3FE1D4C
-:102840000997355F731FF335C78AF9EEC77C39EDF9
-:10285000567D5542F272FF65CE333DC2BB06F40D84
-:102860009F0787FB5E7C0F87BB9BBF3B2F0FEE3B19
-:1028700034E637619D7D650B609DEDE76062DDEEBE
-:102880005F5C10C07ADE6B13797FAC8DF4CFFD31C5
-:10289000CC0FF9B1BF2C39E077430E32A19FF6631C
-:1028A000A23C52B69F934CED074470FEE779764BFD
-:1028B00094ECBFEE9D4294AF49F37008B87E1B586C
-:1028C0009F49FAAD99EC8647A5BCDE141FBCC5CC68
-:1028D000BF6FFA2A97619CA32C98B61CF5AAA3484F
-:1028E0000E6D8AF7A626703CEEFDC64CFBC2A662B2
-:1028F0009E77909C26FBCEA6326F6A3CCFCF957414
-:10290000D9D412D8F628FA2BCBF3F8F93803CCAC8B
-:102910008EEAB9453F1F5B45BBDF49BAF0754CEB0A
-:10292000FC83CCF941E0599F1A6D815D84633C556D
-:10293000E3F03F5195C3485E4ABBD76C4983B93D2C
-:102940007CE0B58F825E2BFEE62CD81609793CA37D
-:102950003A92EC5247ABD7C6B8F87833747330026A
-:10296000FADFF45283DDE9834C2F8DCB0F16F29CF6
-:1029700010AC041EDFE8B433C8E5BEE859DB3A2EDC
-:10298000F144083F54DB84FC3829F5A15763F4F780
-:10299000C0EFCBF75D9F782244DFAB5A509A4B765D
-:1029A000DFAACB3BDF35824EC368BDFA4DE08FD640
-:1029B00048A2FFE49BED44EF2E87E919D8256F93D9
-:1029C000F2AA110761FEBD714F44602DFFB63C2293
-:1029D0003813F28AD3FFB9EDA0EBEB9144FF1A9BB9
-:1029E000E0A79A9FE7137FEDB579DDEBD0FF1B11D0
-:1029F00044F79A58571C95BF9DC824FF91DE501389
-:102A000015CC8DE7F85C1FAD9F02DE38DF913DB835
-:102A1000C626BE1F937C758CF70138FC7531C48FB8
-:102A20004CE6F51F24D2798AEBA3C4BFFA43F9948C
-:102A3000D76DDED405581F2BA309BE63D29E76AC9A
-:102A4000269EF8BBFCA1A5EF324ECF63BEEDF7E5A5
-:102A5000F27AC7F65B3DD8977E5F6F0EDA385DCFAE
-:102A6000AD3E3E6A33CFB7AFFD24430FB1A395AF60
-:102A7000AD9D8276E54B564FC57ED917BECB6B22F6
-:102A8000B8CCEDA1535296D79CC5F1EFC9D26D5980
-:102A90007C9ECB0BDA1742EE9DB3B53D85F3C1C7E3
-:102AA000717A24BE9F7FF58BED240F2D9DB9D0CF79
-:102AB0009759381F802FE5FEB95CF2E54B597A1C17
-:102AC000EA73FC913E1E5DD026E4DEEACB93F35F11
-:102AD000EEDFB657E3E32C8DDABF8C5273A008FD0E
-:102AE0009CD682B15A16F0C7F538DEDF196730166A
-:102AF00074D0E5B969E90EE3BCF007BBCA52FC83A8
-:102B0000B75BDA6A26BB0ADFDF6D807F292CBD0642
-:102B10007F82902BBC9F67681D3A7E3FEF071CFFAA
-:102B20004B9E1B52027D7269FCBE1F5E45F5783BD1
-:102B3000C5E7E64BF36A3E97C223E67746F2F919FA
-:102B400026E5E06C5BF7391C7AD0B917FA1BF8E67A
-:102B5000DC734328FFA5D6A94571B8CE4979C43C9A
-:102B6000ADA3CA7080F0B68E823EFBA8FCBE34B125
-:102B70007514E48F9247CCDE5A44E7EABCD6229C17
-:102B800027953C63BED65CFA1E68CD45FBBD266129
-:102B9000A7A03FCCFBF9B416C2835DACC725CFE735
-:102BA000135ED438E1F40B9FEFD42CE11FE0F0DE8C
-:102BB000E6E3F5076FB619CA87048CF999B2FEA04F
-:102BC00030BA0C30771E8880BC7F96D17A0D1FF703
-:102BD000D62C614FFFE94FBBE96096E745E652F41A
-:102BE00077097DDB0A7CFFAE1BDFB7A77179BA14CA
-:102BF00073CCEC99FFDE623D0D72FF9C49D8A9F7BA
-:102C0000C6F37C01F41C814F9557780CE7A3B5BF40
-:102C10005B98067FCAFAAC6E3F477FF05B23E425E2
-:102C200097178D56818F2F1BAA879FB0E03C5A972C
-:102C30005A65E999CFC2CDC576AC97455B8AEDF36D
-:102C400043CE3B8D3B861F7171BA9CD96121B34144
-:102C5000A325F043E8D18D3BCCAD7E46E5762FAF82
-:102C60007FC671F03DD45BB825BE047AAF6ABF68F9
-:102C7000F31DA95521F8CEDF61C47F61AB310F7B15
-:102C80007468FE47D00547FEE3ED8A83C6FCF02357
-:102C9000C6FC171FDE3E136CFCCA68C1EF27033168
-:102CA00001F8A9AA3F997404FBDAC9BDAFC4823EFA
-:102CB0004B3FAD7A0BE796459B8D7CC6E9A641AFAD
-:102CC000F76FD7883F1607C2D79D5CEF97ACC73523
-:102CD000CAAE9917CA27E1F43CCD5A677A393FD575
-:102CE000D4AF1C0E7F48F514CEB81C9E2B5B37DA90
-:102CF000E037081FAFAF75CF1C5E17EC5515A34525
-:102D0000D998FAF1EC388CBE1B7E3D09EBADE2019F
-:102D10008DF6FF8A97071F86FCEED835E7064A67CF
-:102D20004E263C28FBD9A2FD5A3086E79DA35DFBC9
-:102D3000DA79BB05018DF687F94D113D7288FFAF39
-:102D40006A43181C9B42CA39FC8BF61DF88BC6FBE4
-:102D5000AFDE626CB798E30B727FC9D6BF47847E43
-:102D600057E7BE31FB5BCC98F70205BFFF1A8679A7
-:102D7000091724171D525F39810C97F71109BE36C8
-:102D8000EC2F633689765C605560BEB50E9B0BF305
-:102D9000ADB5B3603487E3488CCDEBE4DF2F6C8EA8
-:102DA00021FBD4C208AE179650CA224BD0CE43FBAB
-:102DB000F4E7EF9B495FA9C5D8E8E7698DCE3FB539
-:102DC000303622FFACC82F66419A07F8C51B3ABFC0
-:102DD0008031CF9AC5B9A9C6123C007C2C61EDE2C6
-:102DE000DCC3E9E80DF1C7D5F0791E4D803E646C77
-:102DF000BF9CB552FDE5FBFE1E11FA3DC44E4AE7ED
-:102E00003975AE34DB9817FAB1F9EE28DAEFB9204C
-:102E10008E027FAED3BC8FDBCD48C5BCFC1B85FECC
-:102E200033B745EC175C3FCD057E366D1CE2819EC5
-:102E30003297EBD991D023164751BD4DF18CEC2B35
-:102E40009BE6E40A3DFB9B978318A7F3118DEC23C7
-:102E50009B8A45BF9B1E1C42E590871A8D13417AC1
-:102E6000CBA632559E4E7AD2C7002D157AAEFCDE27
-:102E7000CF45DF0798BDB9D0D7D9C39174DE577A53
-:102E8000EDB3097A6C76BF9EF92A3D98555F9EFE98
-:102E9000B74DEE779D1B85FFF784E67BCB14A29799
-:102EA0000ECA16FBC3A8F1DEEDB21EF901AA4C65ED
-:102EB000F75FCBE1A97AD4E46A74F7E09D79BDB9F4
-:102EC00098FF898D9125E0B351E385BDE758B19016
-:102ED000DBD1239837C0D3BC6CB17FE4659B0C6910
-:102EE0004A14E73FDECF8952611F8E19E1233B1B55
-:102EF000D7D9487E87CF638484AFCAE67BFBEA5E7E
-:102F0000E0E9E6838942CF38B1427B46C0C5E9CAD1
-:102F1000F3A37E1449F6B913725F51F8E77C33923C
-:102F2000F66929AF364A3ED908FA633F5B2CCE4199
-:102F30003D7C62E483B99AC02B7B50E8A79BE245B5
-:102F40005EF1013FEFB0BF824F4A19E1BDAF738F11
-:102F50009AE7A61651CEE93D05F40E3FF7287A33DD
-:102F60004B6024CE8D7DD17BFEE8F8519A89FCD64A
-:102F70007EF8ADB1D7115EEEB304D67238065A04AE
-:102F8000FED32D82BFB854F64795507DAF8DE72B09
-:102F90001E5EC4BCBC7E451A237B10AFCFE2509F9F
-:102FA00077833816EC1568571127FAADE8CFE89CFF
-:102FB000407F5C5E6523CDA47EBDA604D13EB68471
-:102FC000DAFB4DA2BDD7C2D34159429FEF5C171126
-:102FD0007806F2F9DEF45CF0C194F1463EF88F6CAD
-:102FE000B1DFAB74688E4B1A953C2958DFF39B8692
-:102FF000D07ED118E9ABDD03BABD20F4FF8A7B6E29
-:10300000BD6924E07B31D103F0BE9CBA8BFC0DF38B
-:103010009BE6DCF111CE0D3B22E9FB7539FA5DD957
-:1030200023A107BAE6EDE11FE6CF38644BE1EDF5E9
-:10303000D6B2B33FE7E954FFAEF7A00F4C9D6EA6A2
-:10304000FA5399B08FB22631CE4DFEAF2C29BCBFBA
-:103050009BC66A1433D011E9CC58C1E1AF90F4BBE0
-:1030600047F26F63249BFD3307E04ACFCDE4DF6F67
-:103070008286D98BFFEAB0AA3F4EDB02BD66D00440
-:10308000B1BE547DF4837EDF96EB69A3C48BCA7313
-:10309000BC52FDAAF5111D59B148ADC1C13CEDCCE2
-:1030A0001DFF08F86A4A269BB41978BFD38C5805CF
-:1030B0000E6F6705ADFB985C17F854672C48F1114B
-:1030C0008121C4D71DE33A3BEEE5F98E96C11EB2CD
-:1030D000F9C873F4029CAF5C2817724CC99763CE91
-:1030E000F618E25779AEAE94ACF1C7FA098F5EC11B
-:1030F000EB573A6C1DD80F163C322D167126959B56
-:10310000CC229E6383F15CCDCFBF2F812EE1E7E41B
-:10311000F0F33078067C54B541233E1CD4E8B1A5C9
-:10312000921CD39C985F9523980DF95EE589F4A0D5
-:10313000FC4C8337F14436FC119329655F73BC8FD7
-:10314000823D965110C7C11C7D3FF054D15C41E7D0
-:10315000C5E8029DE4D3DFB25D84E729B02742DEF3
-:1031600058DA53B10E6BD5F70467AE83F839920184
-:103170000F1D56672EE0EA581769C2BE3965ADE0EB
-:103180006BBECEEC16DEFE3E0B8BC27ABF5FB62F57
-:103190005F63F1B5F0FC403BB3C42480AF8A89AFD4
-:1031A0004B06EB1B818793FFCE4663FFAFDCB091EC
-:1031B000E0517CC12C6D1313A1DF6D7397DCCF7AC6
-:1031C000F8A864F0F80FD0AE9B1FA66BC4073C3D77
-:1031D0009045FC70F351944F191FCC5E59003F5637
-:1031E0000DF3C28F90C23CB00774B14ED227BAB86B
-:1031F0003E0179A6E489921B9C0FBC88EB51F455E3
-:10320000F2637B030789E37547839DD29F36389924
-:1032100085CB809D0D29947FB1C145696B431E7D8F
-:10322000FF598387F2BB1B46537E6F8397F2FB1ACD
-:103230002653FAF3061F7DE7782139A4E48A9247E2
-:103240008A9F945C0AE7A3791CBDD794507B927B3C
-:103250004ADE611EA6921E79A4E89BA9F9FC296E9C
-:10326000C8B1F6399017A5E6332FBC023B49B5C368
-:1032700013E1025E84DCEB72D849CE67D8D83E9C5D
-:10328000D71B57783BEE0DD9576FA9D69825844F99
-:103290006FAD8B6496103EBEAD3EDE902FAFFFE06B
-:1032A000CDFEBC7F2D5E77E470388EDDFDF993BFD7
-:1032B000E5DF9FBEFBCB1CD09BC3B1ED318CBB3A8D
-:1032C000AA1B8E04E49BACA43F0C8A12E720FC816D
-:1032D0002EF399589F4FDFFD575ADF1DF5112E33FE
-:1032E000AF37BF3E82F0F531E8C4F1FA7B49A78AD7
-:1032F00075C75F7805EB7CB58DE4DCFC26B92ED76D
-:10330000737C86E86B9FA532D2CB342F63F0C37CED
-:10331000F6EFB620DFF3D9679A3DA041F7E187A425
-:1033200072FE5D5FFF0B8ABFD2EA8F903EAC232E08
-:103330000B7602BFD5108FA5D5CB38ADF681863878
-:10334000AAE8115E1BE403781A749B9F7790615D75
-:10335000B366CD892DA04A7EAF5AAF91BED1AD2FB5
-:10336000E498898E75D9164ADFC31AA7FDA299F68B
-:1033700027C5AF5C5E78035817CDC5B68521727836
-:10338000BEFC5E9967A2547DAFCBB6513FEF41388A
-:10339000F07EEFCFCBB42D2039E7B2410EA8FAF37F
-:1033A000F34AEEC91C817EC625B190F5E8CDB15037
-:1033B000FB3A047AE17C6417F6FF9A3EF601A59782
-:1033C0009CC43FAF24F8E9BCB5E4C5E75F847F6CDB
-:1033D000C9271144A725C3A43DA220306A1AE933A6
-:1033E0005E87C6E7B94CD27FE2F39FC6B6F3F2E53B
-:1033F000BB85FD92A71D4897ADAE26BBD6320F5FA9
-:103400001F0990AB463FF2E1173F896DA773853FD7
-:103410000DF1857C5B486329F0171D9F04BBF87292
-:10342000D6790FE2BAC2DB2DD7BE8E15F67DE12725
-:1034300057FECBD2D7FF9C4C70ECB9900CB9B6FCC0
-:10344000F575C97A2FF35E1EE6BF567E7365075B7E
-:10345000CE367C05BF5B78BD9539D2AF7D05BB828A
-:10346000EC141646710C2BED020F5D819C38D6CB07
-:1034700078DDE36EE6829D9F43BB2CAE380F87F369
-:103480007C1F717CAFE488FDF9ACF4A39EDF692654
-:10349000BDF0FCCE18E2FF653B1F7EEB2A9E5FB6B7
-:1034A00055C3B0AC96B5119E96ED36337BE8F90660
-:1034B000769BC4BEE15CFA7C4C1DF86971ABE6DD1D
-:1034C0005600BFBC2BAE5FA8BE28F9696944EB2843
-:1034D000A28384FF7EA91FA97A8BF73F6C03BD7876
-:1034E000BD73A4B7BC140D5D9BFF75BE07384F6F4D
-:1034F000194E7EDDC5ADBB96D1BEBF33DA89297EBC
-:103500006935DAA30239623D057284BE715ADA7FE9
-:103510004FBF6826F90338B10EBFD4849D57B5DB81
-:103520002EDB6D9778BB2947AC47557F716B476C95
-:1035300036AFFFC5BE0F286D95F35AEC682BC27EDF
-:10354000F9C5EEE8C9014A7F3CE9353EDED9D671BE
-:10355000495AC8BA7A3D47C40D9FDD629E0C7CB1C2
-:10356000808A336AA5F99CDE99A6D1B916F8E6F8E7
-:1035700039BDFBE55813AD5BBF6827E968B20B7B2B
-:10358000AADBE292F60BBB137AC65CAED5C57179A5
-:1035900057BB5BC403847F57F569BDA582DF3B6DD4
-:1035A00082FFA5FF5EFA97102742FEF8185B00FB2A
-:1035B000EBBC61AE59B7409EBD6315F418E87A0CB8
-:1035C000E7AA79EF2792BD62A5D5D51FF93FBD6B5C
-:1035D00025FBF9BCE1729DA7B48F847DB2C32DF6A3
-:1035E000F59AF57C85F0290FE0F4F7F3F9D5044C52
-:1035F000144F793C2793E07AA2DAE4B5919F23989F
-:103600000B3BE5311BF39BA127FF2C92F4BB9A4C9B
-:1036100061777F02FCCED39A84606E22EC5D928E3D
-:103620003537F3F2107AD63C13CC85DE72C626EC21
-:10363000782877222D11F51A25DFA01FF4DBE1761B
-:103640009E23FD724F0C839E6F7A2546D8137E12FF
-:10365000497E07D5EF05C9578DD2CFE5DF26E003B8
-:103660005CD09B17DB9A73A157AA7117C736D37822
-:1036700067E4788BA39A85FF40C685A13E8D6F6570
-:103680005E9CC73B9F8B20FDF4CBD4B6BD18FFCB0F
-:10369000E786901FBCC31D58B88FCAB9DEC6E9B013
-:1036A000E4A71141C07BEAB918F2739EB20A3DE863
-:1036B000544C32E94147621E9D87FEBAB64668B057
-:1036C000A79CD2982D05E5DBFA91BF6A49433DF9E5
-:1036D0000996F0E50E7F344F27C3AF7C6ADB10B24A
-:1036E000B39CFAA599FC8BFCFB7A7CD759F3BCBB45
-:1036F000B0EE7644939DEDCB9FFE6D48A8FF41A5AB
-:103700004BB61AED498AFEAA3C2957ACAFA45C819E
-:10371000C7945CB1CFD446B73E9A49F314EB95D326
-:1037200081CE5B7C7D24C33E7DACF5D564CD013C70
-:1037300007737F0CBCEF10E79A2F775AC92FB2E4BA
-:1037400095182FD96FEEBDC284FD628959E8BF4B31
-:1037500038BB8954D88796C4E6927D88E39BCE8F88
-:103760009DDBCC721C31EEA9EDE9C2FE1E94F9BDC1
-:103770008501F0F9940476DBCDA4DF6C29025E2F7D
-:103780006C8D36812FF8385EF8ED97DCF50381CF2C
-:10379000B885A48F33C4418F82BF5CC8CBDA7BAFBE
-:1037A0008A433C0C7BDFCC20FA2E583CFD210FC312
-:1037B000F1B52857CACBBD4FDAE03FABE1EB05F1DD
-:1037C000414BA5DF74E94F35D2E796DE73D563240C
-:1037D00007DFB3B21C0EC799D6876343E95126FBB6
-:1037E000E969EFA1FA4B797DD1FE9D588267BBD57F
-:1037F0000378C2E978D9ED7F6ABEACF6DDFCD1CAA8
-:10380000F7F5A24BE77D81B57DFF13C8919D911E11
-:103810003F7D6D25BFF3696BEB42CCFBF40B91242C
-:103820005F4EC78BF5FE0597877E1BE0B8F121B28E
-:103830006FFC661A83E85E1430F6ABC69D992BE4E4
-:103840006F6DA2270EFE8C5A4E07F4C7E9F23D6A4F
-:10385000FFBE95DA87CF63A46CD7BD3E5F88267E16
-:10386000393D40D0E3F48B83695FE988177CCEE172
-:10387000CDC039E574BC487153067CB0449E434FBB
-:103880008F6BA573F7696D17A51D56D16E49BDF4F1
-:10389000DB72BE4B01DF8027E1B7B26F68831E0188
-:1038A000FBF4A8124A83110997DA99C19FD8875E61
-:1038B000CC15F62CA83590EBE4DF20FDA4D50679D5
-:1038C000AC4B3DAE66E7A5FE32F283EED4C8EFF313
-:1038D000A05CA7803A49D9C7393F2EF56B5EC41B5F
-:1038E0002D6D5AB118FCBEB46EE32DE077358FA56F
-:1038F000163619E7AB0ECD4CF07444F275033C84D8
-:103900008E97D983DFCD0A5E809C4C7A2629D75BBF
-:1039100072C57E857C33EFAFA649DB40E3B8D5792D
-:1039200052CC4FE189A3C5063B193FE78BF23EE637
-:10393000AFE00C9FBF82A73557D8273ADCAE87C6C9
-:1039400082DEBF3293FDF4C2D7C3E312BE452FC35C
-:1039500089ADDB5ECCE17F9DEFD5E8C70FF986F539
-:103960000C7B348733778BD1FF91B7D5981FBAD3AF
-:10397000982FD86DCC17ED37E63D878DF96D725CC9
-:1039800085279C7311D786732E529C735DB9E29C78
-:103990008B3CCEB94871CEC5779C7391C7391779E6
-:1039A0009C7391C7391729CEB9F87E4ECAEF1A69B0
-:1039B00077041D28BEEAD548E507A7F5727E4E328A
-:1039C000C94FE5CF3CBFB880F2DDF69C323BD973DE
-:1039D000549CCE2D71FAD15CF21BB6DD930ABA5914
-:1039E000DAC98EBBFCE7C28E5B5312E9807DA17DF4
-:1039F000DD17F7407D2A8AD33FCDA5B8A6CEED22AC
-:103A00005E294872A37D8DEBFD6B05FDC8CEA1E25A
-:103A10006E2AB0DF25F44DC7703F0ADB60F49B844B
-:103A2000FB51C2FD27E17CA0FC264F5B3B5321EFFD
-:103A30008F3F67DF00F88F4BFB189BED24FD4BE9B0
-:103A4000D5DDFAD783DA33D8B7BFC94DA0F65D47C5
-:103A5000B8BEDDCB7EABD2CA8B25A43776E73768FC
-:103A6000268A1B4989A57D6895842943EBECB81704
-:103A7000F22EC644FBF8058789CE05173E34931E07
-:103A80003118FA79C87C8604A20CFC95BF2321CC9E
-:103A9000FF37C0507FD8BECC30FFDF50A35F6AFA3B
-:103AA0009A03385F4FDB30DC50AFCA7755181E25BC
-:103AB000DC522F6D5CBD3903F267554C17C1BF6AEC
-:103AC0004F24C5D5567178BDF0CB21C351506DF749
-:103AD0004E05FEAA5BADF1D8E72BE5FEC3EA8DFBF0
-:103AE00071B585F99D093D7C57ED64DE78DEFE6C8D
-:103AF00071F37613A7DB59D39647C7BAE0576AC963
-:103B00007072BEBA5D6B4DBE92F7F7378B5E309820
-:103B1000F35B8635F8C372C8CB5D596C0DAF777C0B
-:103B2000C3CBB1A4774B3ECBB03AA340EF966633FC
-:103B30009D0B60973227F4F0434B736254B6A36732
-:103B40009E3DF4FF9AE6C7E9E2C13DC52EC7C1819B
-:103B5000ABA0C7B58AF9568FD3FCA427CBF9AC9498
-:103B6000FB0ACB16FDDC2EF327E47941CDEFCC9098
-:103B700003452EF8311BF6659821C74D3BB7E3FE90
-:103B8000C0DD51FA758347225E32E7B763F9B84B5F
-:103B90003E12F1BA7FDC3421F64AE89F2F583D539C
-:103BA00078FEDEE6676D38172FB1046C3877563F24
-:103BB000D762F3F2F4BA1D2DF47DE18E0A3A6F2F2D
-:103BC0006275748E3CA9E26F253EAAC76B5B9C1C94
-:103BD000EE17070BB9511D25E2364ACD63DF445C71
-:103BE000FA851D5A31E63BDDB7CB5601FBB3AC1766
-:103BF000BE3EBADE9D56DA0FF6A456E1F7EC6B3DF9
-:103C0000CC08E6D17A9876D145E9F48B43E91CFBE0
-:103C100011F315929C28083BCFBE2BE290BBF68B8C
-:103C200075506D0B264DC33A79C34AEBA496CBAFC2
-:103C3000D1253827333686A7BEB16603BF2E9F181D
-:103C40006DE0E7D92CC1E0479E894B9B21F9E953F0
-:103C5000B20CF5674DCF0FE3FF929E729223630C77
-:103C60007126B5ABFD2E8DE259C61BBFF37435F13D
-:103C7000D90D86F6B5ECE69E7A38076FFD35E199E9
-:103C8000B1361BCE5BD5261157335BEF90DFDBE9F6
-:103C90003B9F88611D0ECAF2FC56EC8B56B2CB2BB3
-:103CA000BBF46CFC3BABB77D91135A8E8BF850D8AC
-:103CB000170CF1851C003A7F3241875A69EFA9CD74
-:103CC00013F69E5A7F9B0DF1B71CFF96348E9265BA
-:103CD000CD1AD9F3787D7B5A82C8AFC6F7DDC6FB13
-:103CE00006E8EF22CA8F982BB05EC2CB97F17943DA
-:103CF000CF58063B0DEC4CAA7FD9AFE2CF459B8D48
-:103D000076A365B0E784D0F1ABC12EE2D3253B7634
-:103D1000BD3580E3659A2FBE18EBA7A6B5CC5A51E6
-:103D200070299F29F97EA1DA447EEEAE770F119FAC
-:103D300075555B889FBF0B1FCBBCC29E19CE7F0BF6
-:103D4000F97CE0975DB85BF30434510F781900BE3D
-:103D50000CC34B5A2FF85278EAC65B58F922FC6321
-:103D600004E206B440D0DD1B5E241E55FF6178627C
-:103D7000A38D7858A8BBDE87BC5978C4CC02973194
-:103D8000EF45981FC6E7F3C3F8375F147612E5379F
-:103D90009879D142F96E3EF189F8E9E9538CEBB29A
-:103DA0009B6F7C629DCCB8984CEDFEB7F9E7BBF8F1
-:103DB00046C11D1E9FACEEF7FCF76069271CC94683
-:103DC000D2FABFCCB861B5DF2B3C0FBA7B34C51338
-:103DD000753932497FE8DE6F9CC6F29531991447F8
-:103DE000AC4BFB9C92BBBAACA7C6A9E0E5AEE1E048
-:103DF000E381C9B0BBDED39495D11EA297E8EBACAA
-:103E00006437CD5893486945A43319FB45C51AB3A7
-:103E10000FFBE067F7F54F1E0D3BFC3A6BD214DE4B
-:103E2000F567778EC86085C897527A7C63C4EC507A
-:103E30007BB64A5D79623FA8BDFB28ED5F674DEF19
-:103E4000C6CEC63A5BB7271621354BD77D30CAC9D7
-:103E5000558F168B3E280F71845ACB7627F0E66C6F
-:103E600029823D7A1868D7AF474F58B2AEB43FECBD
-:103E70005F35DF1C7A0AFBBBBEC69A0C3DF3D487C4
-:103E80007CFFD368FF22FDE024E28F93E0B78AA68F
-:103E9000FB6D2735E685FF66B1F94091D3B09FEE03
-:103EA0009F09385E8DD287E5919F36B03D05E37B53
-:103EB000FC142FA9AFC989EBCD5EA2D2E59B85FE8C
-:103EC000B65DD96BA55D177A3BF2D0DBE11482DEDB
-:103ED0008E3CF476A4D0DBF1BD4CDAEB07357616D8
-:103EE000E3DCE91FCFF2EA687F75E4412F5FA54567
-:103EF00079206F56699EFEB083B1ADA9625F0DA3B4
-:103F0000AF4AAFEEE4BA5508BF5F7BD1CE42E3C7FC
-:103F1000C6B178437E823DD550BFD4E936945F97D1
-:103F200032C4507EBDABD890BF31EF4A43FD9B3CBD
-:103F3000E30CF9EF8DBEDE50BFCC5B66C84F9B3CF7
-:103F4000C7507F86AFC2503E6BF66243F91C7D8539
-:103F5000217F4BF59D86FAB7D6AD31947B99D382FC
-:103F6000FD6D3FCE531CEF6FE03CC5D355BFCA710A
-:103F700084D275EC04535D6FF6F8EF4BFEDD3CC464
-:103F8000BB02FC992EEF81A4CBFB1C4D792EE2CF16
-:103F900034DCDBA7F36C5B2AF826BC5E78F9D8E842
-:103FA00083175C9C867FD83173BA85CB87B1571C49
-:103FB0001C9EC5F309431E986EE17265EC55075FC0
-:103FC000CEE4F90143DE14E5C30E5E40F903431E5F
-:103FD00012F9698C548BCC21E3A7FBF93CC65E9B9C
-:103FE000B9C123EC21BDC65BAA147840DC22F08065
-:103FF00034C8F913E941CE9F480F73FEACCA66EC92
-:104000002DCE9F488FF07325BEBFCDCF9548DFE5FD
-:10401000E74AA4EFF17325D2367EAE44FA9B86D9E7
-:10402000947ED8A053BBFF6CA8A6F468431D7DFF07
-:10403000B8A19ED2DF37F8E97B204FD90F826467A1
-:1040400051FEA465F0E3C10EB7CF7A26D4CFAAFC07
-:1040500081CAFFD758C7DAA3B14EDB2DF19FDB7BB6
-:10406000FC7A7DCB590BFB3C44DF6A89F63E9F47C7
-:104070007692814E92D7F2FB786D5A7A094FFFE221
-:10408000D27781DE334A2AD7C5B9710FA4CE0A7E12
-:10409000F9C8D4FBBDE0A63C617F5839C4BB97F892
-:1040A00044FAB1951FB93B3E25C4CF6D0A898BA157
-:1040B000BF90F816E56F56F134D7D8457C9EF227AD
-:1040C000ABB819D55FE94546F2EEEAF516D24F6274
-:1040D0002C2C88FE557CCCD5F6D662C40B5C5DE3F7
-:1040E000A038B4FEFCBBAD84EA79CD3CDDFA675E56
-:1040F000BFA8C77FDD5FC2CFCB09FED28B3AD95DA7
-:10410000AF96FE7BB4B78B723FDA23760A7A064FFE
-:10411000C9AEF624E29C4A7AFCE9A81F2DEA07D131
-:104120005FF67FF1F1627BD64F7A426B31E2A9D222
-:104130009739289E6ACBB820DDDF5AEED63F039D23
-:104140007C11CE4FA369FD64A5C34E5026F5DE6FEA
-:10415000A1C31768A7F0A3F0ACE8A2F01B12774444
-:1041600078ED8B4EE1F409A78BA247E9C51E3C030D
-:104170004F97D2A1874EB0C7FEBF4287119656BA5D
-:10418000FF175163F700AEEFA2CB6D9D6C12EE13DB
-:104190000FCED49B80E78A8BAEB790AF64E32661E5
-:1041A0006B52E59EEF289F85F27E7D97DFD147F920
-:1041B0003B912A1EC1EB28E6749920E5C7AA5281DB
-:1041C000DFC96E33E17742C122D2479943E8752EA9
-:1041D000FE1FE4C9A4AF7D4DE86F5292513F54FEDB
-:1041E000E01B647F93C3FCC03748BDF18630BD70CF
-:1041F000D410A9F7B9995B9CFBC43DF789729F4E17
-:104200009374CEE287F9B1A023D32D105A8771CFD2
-:10421000BD08F7C0FD94BF9E0528BD910569DFBAB2
-:10422000890B38E4BFC718C5331E8A9E5ABE9CF757
-:104230003761F8846C7C0FB9D777DD907E74AFEF6F
-:104240000FCE907B7D0727BA486F3868CF223D0696
-:10425000EBC01A6247FB2597FB086538C4F705A435
-:104260006FF27D219B33F92FF8BE80FC0D796B181E
-:10427000DA4D7219E34D54FB1B9DE3996578DF72AB
-:10428000F7C6A25707C2BEF24EFCE089B03BBF138F
-:104290007FC544CCF79DF8FE269146D8282D7C2575
-:1042A000BB373D4BF161CF78939825F152FC2A7CC6
-:1042B00086E351E1F79FC0E78ADEF0D9041CC0AE67
-:1042C00067FF20362513FE2FB1FE6B5F29EC0FF838
-:1042D0004F0134C425DB055EC2ED3B5F34B081C0C5
-:1042E0002FDB1A47DFEF903C7475FD18AA7F4DFD58
-:1042F000689ADF5551FADA217C9C3325C15CAE39CE
-:10430000B02FB634D2FDDBB32F9A3DD0BF6BCCAE0D
-:104310000D1EACF577C47D39F6F5A10CF8DBD8D6C7
-:10432000DEE3766BEC0A6F7EC2A737D3DB24F63F61
-:10433000718F58EDBF032344BCABBACFDAD77E3CB4
-:104340002A4AC8958111420E2A3AF176944FE3FD2C
-:104350008CE27223EDA128D2BF4724781F073ED5F7
-:10436000391AF14DD8A7AE09E6C7213F19E7499E92
-:104370007F5BDE4F7B7B685D5226C7F7219BFE2C5F
-:10438000DA31F3D766ACEBC61C8DEEB9771DC94A9E
-:1043900002BEB7A97557C48A42DF1B50FA71F7787D
-:1043A0004966F28BAF847F3409E7263BD98BAE6137
-:1043B000B9E4379D28C72FFD6525BD83A0EE7D4458
-:1043C000A4988CEFE7B8A20CEFC144E72518F231AE
-:1043D0009E0186FA71A3330DE5F1DEA186F2C4C910
-:1043E00025867C3FDF1843FDFEB3C71BDF75D36F07
-:1043F00030D44FABBED99057F22B4D7C62E9757328
-:104400000DED07D5CF37D477FB9718DFB7F17BDBFE
-:10441000F29221F7C45FD6FA9586F21FC78A7B0D08
-:10442000931D0BE9BD8A9CE6BB8CE34B3AA5C509FD
-:104430003A319790AF7EFE1FF8A634C5286F273813
-:104440008DE76DAE0F6AD8DFD3EA2C86EF9FFD0FA4
-:10445000E91C8E972EBE3505511FFA10CF5FA30FB2
-:104460007D08768D8949564F80097B7AE8BC604F7C
-:104470000FC503ECE9A179D8D38DEF4219E90E7B82
-:104480007A68F9F02346BA8F6C33D2FD8AA346BA14
-:104490002B7E0CA7CF95ED467E08A7CF5527C3F8F6
-:1044A00043D26336FFEFEFE29E34D16B9243634F0A
-:1044B000B8FF79FA240FE5F4C9EFA1CFFF49D35330
-:1044C00087F6C3FDF40B1936D0AB53BCD7B742CA3D
-:1044D0004F154FC8CFBBE23EDD5D66F2EF1F3335AF
-:1044E000D37B49079DBA1BED6F2BA8D3E03F4861F2
-:1044F000BE5D0B397CF3FE2382FC09F306897B9DAC
-:10450000ACA09DE2EC959C9B9726E258860C95E723
-:104510000B8F886729182AF4C2188F93E25E2B0A42
-:10452000C43D027E2CC8985708FE793712EF1676E4
-:104530006D12F6FB76ABB85FEAE77C04BF18F44473
-:10454000E871E9528F6AFC9DDD0EF8076F66867D83
-:104550007148C06E88BBCCDFE134E40B5B530CF5D3
-:1045600087ED7319CA8B837986F2E1473C86FCC8D4
-:10457000B6D186FA571CF51AF257B64F36D4BFEAB1
-:10458000A4CF904F639D8F03BF8334711EAD1A2A51
-:10459000E278F81A227FD2BC7BE3C5FD41794E5503
-:1045A0007AB08AC7D525DF85EBD3836C3AC5F73659
-:1045B000A6320FDD03B0CBF30933EAD9BA8CA75585
-:1045C000FA28F31BE369551C6DB73E2EF56FA50F56
-:1045D00087C4D17A43E368E7C97BBEE1FB5E9DA453
-:1045E0007B38FC836C62BE8D77DAE8DE82822B1C1E
-:1045F0009EBFC9F8CE6DF6DEEF8FDC3D54F8DB7F51
-:1046000099E5FB3EF8F529888FACDEC6F3B4FB399B
-:104610007F35FEBBCDB3D6F5DDE3CD1B26E6536E6D
-:1046200032DD565640714BB37F1632FE0FE5B8AB04
-:104630000AB45EE7372F4EC415B1389B0BFCDBF78D
-:1046400078029F2936D644F75C64DCF9AD1B5A1F0B
-:104650008489BCDCD66C15EF9705ACE08729E3B9FB
-:10466000FE540CBBD5370F3BB89EF154BD85EC1002
-:104670008F0CBD69863FBBE71EC1207EBE007F4018
-:1046800057C1B9C45E20E266F70E15EBBFD4FC75C6
-:1046900077FC37D9D31993F25B9C5B7AE137E2431D
-:1046A000358F7F751C78389ED4B990C97D275BC241
-:1046B000A5F0D77D8E97F853F1F8AE1556DF330E7F
-:1046C0008AEB9F8C782645BF8105822F4F0E15F40B
-:1046D000463DC8A3BEEA959A0BE260AFED62AE38E4
-:1046E000E7B7D823FF557851F8EFEB7E4F5FF2E143
-:1046F00012B9D0C77D9FBEF893FEFE817B3F21F2A9
-:1047000041C497487A04B24DE4CFBD37C6B88EFB9A
-:10471000E70BFCEE57FB859F9F278D7282C1BEDCA5
-:10472000B8CE2CE584D857A16FE0FB827556D237FE
-:1047300058BD8847AE96B298315FF29811F0C75ACB
-:10474000E93DAB6BBC8CF491F90E5BA085D7AFF063
-:1047500087EFAB5E6A4FFE1A17DE2DF1DC03FB7BA1
-:10476000E57A63BD450EF1AED782B073E922792EAA
-:104770005D14762E8DCC97FBB28779486F92FE67D9
-:104780000567375F05B2282E18E754B3B09750BCC1
-:1047900052B71D1FFE85907734393EA3F2B06F37B4
-:1047A000597A8D23EBC6671F7EF233F093BBB0FEC0
-:1047B000BBE8FE4FD7EE48E14753FE0B59FF8CFF95
-:1047C0000295A33E7A3B5BDC56043F52B7BF23CC35
-:1047D0006FD2E530C58E467F3BC5FB0B2A0E60C904
-:1047E0005F0345CE103FA7DE6E32C45D84A7FA9A00
-:1047F0003D1417D062D14BF2F93C4E5B3C76BC17AE
-:10480000799FE36032EE6B4F91F69A7078BBF5D0EA
-:10481000B19AF013FA851EDA3559233D94CB4586BB
-:1048200075A4FCD9652C988454F90FF4F5A309CF2D
-:10483000CA7F50111C4D70CE685C64C5937DED8FAE
-:10484000AF2E8D72F5F815DAD3453C4A5FFE8569C7
-:10485000173DD4DFF48B63A89FB27CB7B8C7D5F4FB
-:10486000E00AF0D1D01DCC8A79B687C563ABF4409D
-:10487000BEB07F1FCB57725BC6B9ACD1849EAD3141
-:1048800015F742725BE52F34CB7CA9C8AF5A27F2EB
-:10489000EDF21DA3EDD2DE807922C57C702EDE29DB
-:1048A000ED11980752CC03DF21A790879C421E721E
-:1048B0000A79C829A49053F83E9FF9328ACDC20FD5
-:1048C000323164DDC00F3231440F821F24340F3F78
-:1048D00048687DF84142CBE107092D871F24340F3A
-:1048E0003F48687DF84142F36CF4F53D79C8356F77
-:1048F00099213F8DEBE31343D62DFC20A1FDC30F7F
-:1049000062E84F5F61687F0BAB37B4871F24B4FE4A
-:104910006DF59AC14F729BBC975EB93981F8638E71
-:10492000DBF7C37C4EDF3F447F738715E734F3FE2C
-:10493000C5747EAA8DF2083A374F1674373141E7B5
-:10494000CE3944E7D536912F1571B1BDF91B2666D6
-:104950000B7F0352F81B90C2DF8014FE06BC870D4C
-:104960007F0352F81BF01DFE06A4F0372085BF011F
-:1049700029FC0D48E16F400A7F03DAC1DF8014FE95
-:10498000067C87BF0129FC0DF87E0C7E8FEC1EB8DB
-:10499000A0B7671BCE779C0F0DE73BA7210FBD3D4E
-:1049A000B43EF4F6D072E8EDA1E5D0DB43F3D0DB02
-:1049B00043EB436F0FCDB70D75D1BA84FE1EDA0EEF
-:1049C000FA7B68BEB0D9FF266C4C376D3977186911
-:1049D0007B8CF694C645C1FBCF1F9F01BF517BA4C2
-:1049E0009611CF97BC553B356322D7CF74195F56CC
-:1049F000C43AE97D675DBE5BA30719C5C316FE25F2
-:104A000045C805756F087F9CEEC5BB199D03CAE4B8
-:104A10007EAADA7B98D34C724BD6EFC9F75E2F7C17
-:104A20007C558FE465081CFC80588C3888E2D58E54
-:104A300012C4716F3769220E72AD88430DE72B7374
-:104A400081904BDB4DBB0E4621AEA542A3F7E2732E
-:104A50002DEC08DEF12E6CAE2B81BE703A3F5ECE9F
-:104A6000AB6E0CE26214DCCA0EC8E504DDAB1ADBE7
-:104A7000C96C5505784F8CD91640BEDB849E807674
-:104A8000383FE6FB35EF3321FCFDE77CB1BFE9FEA3
-:104A90001563AAF8F7FC9D7563705F6B4A9468F71D
-:104AA00093A763098F539BB467702F6EEC4EE6C5D6
-:104AB000FDCB6FA43CCDDFE9B455D1B84EBAE7A524
-:104AC000FAADD89241F7D22A58FBC414B2E56BF480
-:104AD0008EB9C21B9FDF61CC8F8BF82356D247C59E
-:104AE0007D9128795F44DD13715B7CC1A1237BEE4E
-:104AF0008B5C3D22BE14F15A6CBF7877EFA611157E
-:104B0000EBFAF1FEF5807877EFEA3FD5BD49F9ADD4
-:104B1000E2DD3D628351340EED6B83FD1ABDF7304B
-:104B2000D5DF624A72E1FEE81A6B32EAEF641EA832
-:104B30003F8399B807A9E02B606D26BC3BCEB798A0
-:104B40004389217CC425C074D0BDD863A5F720CA91
-:104B50002C4E2BE446F83E7E693C5D989E10160F65
-:104B6000D1B8FA68863913F61E932708B9B5279A83
-:104B7000F405A5EF54C838A80B4D6FD27BD615BBF2
-:104B8000847EA0733900F9A7E2236AB3021926E8EC
-:104B90000B035A8A12CC62FF2FC07D24FFCB334710
-:104BA000BB708FF14D8AD7AF5837324EDCD711FE2C
-:104BB000872A89A72A19FFC20A9CC9D03BD53BA6E0
-:104BC000A5E6B17174DFAD59E873CAFE52F1ABE1ED
-:104BD0006F81CE154FCAF740D657D03DA0F038149C
-:104BE000A51FAAF74E16375929BE6571981EB854ED
-:104BF000EA814BC3F4C01B0AC2F440F53E9DAC539E
-:104C0000F1AB4333484FA913EFF195AF117A0BDBAA
-:104C100025DEB12F5F33C184772BCAF7783D5A2F39
-:104C2000FCF1BED45FA660D044C4F90CA074E6C504
-:104C3000144A675DCC233980BB18A07FFBAB8CF492
-:104C4000E90FA4BE3203717EB81FE78F90F17C8C10
-:104C5000F4A562E62C85DC18EAD50EC17C3DC5AA18
-:104C6000AF431CE1941646F7616E825EC30B664348
-:104C7000CF190E3E7797D2BD80C91ADDAFB869C48F
-:104C80000AC9D79CCF19F8DC2FF9D647F9EEFD40B9
-:104C9000F2B7EEEFB0D0BBAC7ECD8677D974799EFB
-:104CA00055FC1BCEE7F3E4EF4D3087B03375DBA145
-:104CB000002C3DAE72CD4CE88BF360BB1B2009C9C4
-:104CC00051145320CA9B0AAE99D984C3CDFFD03E5C
-:104CD00051AE7E8781EB5990A7B7DE5E6C9B1F2299
-:104CE00057CA8AC63F5BD8AF87EEF3BBEF8D15F48A
-:104CF00087FEBFF2BE9CFEDF767FB192E319EB63C5
-:104D00005E5CFB1D7819776B01F34E1C8DF798D50F
-:104D10003C5910F16A7365FED7058BFE737D01E186
-:104D200087F2819D5366FA69BD0879750BE4951980
-:104D3000724A7FAA00F73BECED93408FE8824E79F0
-:104D40001F5EEE4761F6885F17083A84DB252A0B61
-:104D5000841C671657C62D744FD545763D05FF67F1
-:104D600056E3BD4195FE52ED230DFF9A78FBAF92BD
-:104D7000F59F437E3C6A12F7B707989B99B40F8959
-:104D8000DFC990EB87C9F70C7AE8CFA506E87F9FCB
-:104D9000E60CA5BFBE5E13F7A6FBB0E3B0BCCEC762
-:104DA000B7C18ED7207E9FE3E95CC1474FDF652303
-:104DB000FDBBDCD6F626DE695278FCA4FE4756F130
-:104DC0003B2FC11CBC3F35B72E92DE7B2D2BF2B59D
-:104DD000812ED1051EA2C7B38829E5F5DB9DBE0F44
-:104DE000309FDA0D079EC2FDF1E5FBDD74AFB162C5
-:104DF0005FF13D78D7A2AC483F8AF20A87D386FD9F
-:104E00007B59533CED67F3FACBFB85AC93FC540A1A
-:104E1000FF9D05C28EB5BD48F47F5E9E432028CB22
-:104E20000CF5645C71D83A51F6C1703B43F87B02D3
-:104E30007DAD1F654F80FDC016625F54F6096BDEC5
-:104E40006773B07F96DB8CF7E154EA2E94E75C79C8
-:104E50000E5CD0BD7F154CEA0F7D79A346BF5B5336
-:104E6000E570CDBA92E7AB8E581129C8A624B8C414
-:104E70003B12F7897724E6F3F50A79532EE386AAE5
-:104E8000368FA6F55615E06962DFEBF2968D87D274
-:104E90005F05FF04BD744FBCCAE9B52584ACFBCAED
-:104EA00066CD70CF5CE5E30B853DAE1C4F98974017
-:104EB0005EB86D78CBA59CAB1588437317BA0C7E92
-:104EC000575E8FE218A664B2B7C43B3E1C6EB7189B
-:104ED000AF24A4FFF9CDC6FBF2BCBE7897A2308602
-:104EE000FAAB70F279C3FEE174129C1C0F84A7CE5A
-:104EF00007797F2E1A87E851190C5871DE2E47FC6E
-:104F000004CFCF7506AC18677E9378B742DF20C612
-:104F1000D1D7C7DB0AA12F599CB674E04FBE6BCF27
-:104F2000E1233958C5F182FB3FEA1E60387E2A240E
-:104F3000BC55CDF1463DAC79A315F498D3C7FDF926
-:104F40009B24DDE7378DA3FBCF55162FC5D7EB127A
-:104F5000BF7F5C11793FFC0373363D6675F3FCD56A
-:104F600085827F6F92789D9219CCA1F76956447A19
-:104F700000E71C6733CDAF1BBF8F707C687807C517
-:104F800047F8E57CE1471C59D526233D7BE011F825
-:104F9000ADDA5441EB6DA145B73943E1D87C200728
-:104FA000F77AE6F0F58D77779853A7FB369F3F3277
-:104FB0002B83E6C9E1045E633CAE49786F86F30952
-:104FC000F1B1E217753F588DB7A050DC135C50D893
-:104FD000BB7DBD675D7A49BF69E4F485DDBBAF7514
-:104FE00069C345233EAEAD4ABC0316BE4ED5FA5446
-:104FF000EB52AD53B57E9FB2FA82295A8F9CE1FBEA
-:105000006DDDCF7AC1D3B312DEB992AE1CAF874348
-:10501000EF156D2814F2A83CD3B8DED11FFABD4BB2
-:10502000958F0FE6E01EA0AAAFC62D97BFD305BE91
-:1050300007BFDD25E98EFA2BA9BEF17E4465B7BC1A
-:10504000D8B92E19F2629746FAEECA070FA5FF1BD0
-:10505000F4D817841E7BBA66DBB254D80D2C818C31
-:10506000D0F799AA82423E2CE0FA0FE4C542B94F2C
-:105070005F97A3DF573832A4DEC32FE4EA42BE04B1
-:10508000215F7EFFC26B1F8D71F5EC9F0AFEF9EB6D
-:105090007F6DAD7084E24BF0F9FD795D74EFABD2BA
-:1050A000617321CEB6B2A982E42D4BE1E7092D242C
-:1050B0004E2A8C0F2A9A347A37ABB27E54C0FCBF8A
-:1050C00028972B3794D1DB3C8A4EEAFD0DB59F2AF9
-:1050D000F8774AF8E74A3E7E49AEBFB9D56EDB4263
-:1050E0005AF76E5B25F85F96CFA9327EEFA653B7CD
-:1050F0009FB9E09E14798F85CE251BACC2BEB73315
-:1051000086F4D5D32B5F796F26AFF7E5A32D19D0A1
-:105110004F141C8BA41D6F81B4C72D947A2BA7D379
-:105120001B85217276D1D3824E952FFEEA53BC0F98
-:10513000559E29E5D983E27EF9FCD65D44B739EB6B
-:10514000375ADDBCDE7B856E839CAEAC2B76C23ECF
-:105150003D777D8B1572E0BD4281B7707E2F9771D0
-:10516000A90AAFD877B410FF85AA0FF9B78B8F7350
-:10517000FB8AC858C465A871FE5BF271655D7C024C
-:10518000C6ABACABF821CE3D4ADE87AFBBE3916244
-:105190003DCCE7FD615D1E1FE7A17BB6E5F2F7A5FB
-:1051A000C2EB9F9374FBB155BC239816DDFA1CC566
-:1051B000152C8FF2403E6467B707302EF81970DB6C
-:1051C0004CE2DDC1EC9AF6AF0007578B293E05296A
-:1051D000DE3B829A9CCCF3CF98C47D20C496204DB0
-:1051E0002A12FC00D314CA59523BBD7F16129F6984
-:1051F000E0571BDBBA1EEFAFD89218FDDE8BE24FF3
-:10520000D58FE24FC5BF7DCDCF517479F33BEE967C
-:1052100076883C4F06EE51CC7B6830BDCFFF5DF306
-:10522000B4C977F0BAE71B217EB7E092F9668B73B9
-:105230004BDFF3DD549ADCCB7CC3E7A9D6898ABD6A
-:10524000EEF62B340BBFC2718DEF5FBCDDF1159113
-:1052500014F7A5E6A5ECDE971B2FEF294A9076847C
-:10526000F618E891E5F2F7205850E4F1BD2CE4BBC4
-:10527000DAF7D5BB614A3E9FA893FB226B7F10EB08
-:1052800099D567D13B19C79A8FC7E0FD8EE3E30438
-:105290007CAADDED5671EF95C5D85C783F919FAF44
-:1052A000E8771F1634F5A773E4ADF55924176EF5AA
-:1052B000C70BBB83D4EF174A39187D7BC53D57A078
-:1052C000FE66B753E3E32C70783EDF4CEDF33DD040
-:1052D00007A33795D93249EF15E700E507BA5D63B3
-:1052E0003EBACF043989F5653A908D7D67D16671F4
-:1052F0000E986262EBE12F1CD4E89B940A39F1B856
-:105300007837926D31BEAB7430C7776311F016F603
-:105310001ED9EDD6566F7FC871AE6FC0CEB4C0E156
-:1053200023BDFD6D29278F6DEAA0F7C9155E2FB942
-:10533000A76213F7523B634C647FBBDCFB2A55D258
-:105340009FA4F846F9A39EC0FF5D093C99685F2BB6
-:105350003597D3BB3EF76C9A4069D5C6D247FD85D9
-:10536000B80FEB4B1E43705BC93E56553B41DC1FEB
-:105370007D26221EE79B0CAB3F23542FAD6AB997C5
-:10538000EEA99C6C89A47B2A139D6513E393E8BD69
-:105390005DBAF7A5EAFD40AECB25B5130CF74C1668
-:1053A000F03E1107FBE7D6688A2B55F747EE8ED201
-:1053B000BF5FD44FDC23B9D225EE8FA4527D57AF07
-:1053C000F670957EDE20EE2384DC8B993A87B7AFAA
-:1053D000A97D3916FD2C7DE483511C33B03FAD050A
-:1053E000DDBAEFC56C16F7621A715E821E99E09BFA
-:1053F0003907F8FFA599F0DFD778D5F85192907367
-:10540000C4AD8138D25BF520B3C19FAC3B19E9C56F
-:1054100027CDAC1E7A80D25FD4F747255E4EC635C5
-:1054200067803F166F7F2C03FBCBA918912FDF3EBF
-:10543000EB6DC82B7D6B84D0CF2D8CF4E14ABFD0AF
-:10544000AF5975827A1733721EFCB145D1E21D1E29
-:10545000797F46C1A5DE5B3D6511EFC5E05E0CF8C6
-:10546000FD134B7001E8FB09D75F718EFD819463DA
-:105470009F349BE97747FC7CA1400FF9A4F9E5181C
-:10548000DCCF55FA5AA9F9F75EBC47B3728FB8A7BB
-:105490008A77CDE9CD4A69075926ED202B5FB54EB5
-:1054A000C2EF8E70FD8BBED45882B6DEE8B744EAF8
-:1054B00057DDF9DDBBE8DC56B353E80F35AD1DA46D
-:1054C0003F287D44DD8B5BBAB383F409D56ED96E7A
-:1054D0008197DADDE27B05E2D6E5EF856AD9384FC0
-:1054E0006B94FFB460FEAC3596D07C05E53F2D5043
-:1054F000F6914ED207EFCFFB0D9DC36B9B64BF3C73
-:105500006F0D19EF4D30693FF13DCB81F662DF57EA
-:10551000E5B5BBE3A97DB0366A3DF679EF32870584
-:105520006963AD83F6FD2D75A63CCB080017E581B8
-:105530001EB75FC66FF55BFA9F91B01FA4B2CE4352
-:1055400078F7F5A0533F0A7E55BF67A9EEBD9C7F53
-:10555000FD8BE1E8FF9A41ED17F0C683754DED2C08
-:10556000F827DA8BE43C0ADA8783AFFB1D14F2F9E3
-:10557000492B5B4FEF075B7C0C76FBA0F42BFAFF0B
-:105580006212BF2FA1059F0DD5AF9286093DDC1792
-:1055900021FC8B5EB77E0A707C4FB31616E34CED90
-:1055A00032E7A07FF53B2A4A4F1D2FE573BA3C5FD7
-:1055B000D906A438C0C79AD74BF710D7161CACC46D
-:1055C000BEFC40A79D7E5F55C5E18DEF8C22BD35A9
-:1055D0007DC064DACF34978595F3FA070B4C41DC34
-:1055E000DB7A80D9455C803D4CAF3545523CB2B644
-:1055F000FF177F813C4F337F7508BF5392F66F1AB8
-:10560000BD7F39AFEBF327F11B33E52C504CEFE0B6
-:10561000C5EBA66190C35D933B744EB2079CAD761B
-:105620008FD8275828FCFBEFFC4B6C82A907AEF300
-:105630009D9FD3BB82E73BED64AF1DBF5FBEB71735
-:1056400006CFF91417C545F37AA4679E7798E89DAD
-:10565000B1F1FB0FD1BB79E3D5BB7A76E3BB7ACC52
-:10566000951E0F7B32D950B95290DC28E8764D9CBC
-:10567000F19C98334C9CB7728609F9A1F0D7653F2D
-:10568000F78EAEF5ACC3E5CA7FAF7E6FAA3A827ED5
-:105690006FAA6B7FD6B7BE9FF001F407AE176CC838
-:1056A000F4160EEBD7B37FCE907851FBB059F63F8E
-:1056B00043E26786C324F011F67B1B8A3F14FD1575
-:1056C000BCEADE91A21BBBABED4DDC0BE2F42A7C05
-:1056D00088119DAE203AFDE5DD75B8E63FC0ECEDE2
-:1056E000D0DDFF123A05F10ECE65D3A92D9C4EC137
-:1056F000C8C1D0131E11BFBF151ED7C8F218ADF315
-:1057000079E628B203EAF25D70BEBEDFC4FA56EB5A
-:105710007AD0E4F642EC8FC7F8D11B70B59B5AE9FA
-:10572000FBF7878978C281AC2D55C6DF8C845ED6A5
-:1057300028DF3FEEFE1DC3C50E7A6FE47C40BD7FBF
-:105740001C787C211F77D38C02B2EB9F6772BD5708
-:1057500077BF932DDE3FEE7E27DBEC273BC99C28ED
-:10576000B2F374BF939D23DEBB7E4D63B97887D6B9
-:105770005F66A7F8F8F077B2F93EF31CFC194F54B6
-:1057800047911F4ABD8F3CDEA9D7818EE1EF233FB1
-:10579000AAF9E62C407F850EEAAF7D4ED48BDB055F
-:1057A0009A83B0E31CAB8FA177A1155F2AFBF5208C
-:1057B0007FC7E3C093BAD7F907C95F0AEFEA5E9BD8
-:1057C000C2BFE233BF95D1FD4FD001EFCAAAF7D9CE
-:1057D000B5D5526EA8FB846F785C481F8CD7D70371
-:1057E000EEC6155C6E905DBCFD0ECCF7C93B63BC8C
-:1057F00080EB98C9F8FBBD2A7D7898C9F03BA1F3EE
-:10580000E47E354FC5FDD71BE3FEC3DFD14C8CF3DF
-:105810003D328CB73FAB7D300A1FDFFD3FE65EE3D4
-:10582000489E92EB7F44B4FE24EAABFB0F4A3F7CD8
-:10583000B7F88B74FABD91AF0FD1EF2ACE75FA028B
-:10584000A817992DFC017F486DA7FB1A7F98F3D705
-:1058500074B227AF16EF7F5E2E9C97DEA715FCB0C3
-:105860006A8188374C6375C4BF293DF7342301C76B
-:10587000FF6FF7697BEEBB4E1E7E82E22E7CF47BCF
-:1058800015E1F4181B71F065173FA9FC76D897B3A2
-:10589000E83E69DCC1556E9E3FF6D239914F3B78A8
-:1058A000C1CD69D3FED27991CF3F7801F7513F7BCB
-:1058B000A953E4AF62E4CF3AF1D257B370FFB4BF5B
-:1058C0005BFF23E835F362DD9BD85E3F5A73F3023A
-:1058D00037DDA72C4BCF13F7293F41F98CE4F9EBC7
-:1058E000E2B49EFB94268FEF8FE0DBF35F09FE7638
-:1058F0007358C127FF6CAAEE932A79DB975C54EBAF
-:10590000EE5F751F56AD63B6DDB3DE0A26F4FFD336
-:10591000F7549987CFEBFF021C7874630080000076
-:10592000000000001F8B080000000000000BB57C89
-:105930000B7854D5B5F03E73E6994C9249C80B02EA
-:10594000E104420C18D299BCC05BEA1D2089015ABF
-:105950001B6CB52018068D90D76442A82DB5D80CC5
-:105960000611A8DE0B5754B06827400035E8A001A7
-:105970002718EA00922252BF98FB37F2FD5FE10B35
-:105980003E90979310B557EF55B96BADBD4FE641BB
-:1059900022DAFE7FF8DAEDDAEFBDD77BAD7D86B196
-:1059A000B196F3D18CFEAEC98C1D3FFC9EA249641A
-:1059B0006C4681D16A90A034772BC6020EBB01DE03
-:1059C0007595F935B1BC9F36B45FA2D766C17E75B7
-:1059D00066EA973908FD72B1DF9F476BB1BE416F30
-:1059E000356430F6B48EB94D098CC5688EC8B84E92
-:1059F000CC2063CDD07FAC8131631E63297AC6B0E1
-:105A00001DFA312394BB06F97AE3121A56309867CF
-:105A10005C85D9DA9C81BBF53056C858DA28FF6816
-:105A2000DC5FDA4A3DD5C7687A940633638126FF86
-:105A3000DC0F33192B8E8ACD653F8052CFB2711F98
-:105A40004C13656D85F54AE4AFBAD2006EEC906CEC
-:105A5000B0342B36946F671319ABD7029088FF339D
-:105A6000795A711D6D77F51EE8D7939C66DD08E0C5
-:105A7000D8D4832C331FC6BBCA72D804C68E5A1C16
-:105A800039D62468679B241C1F9DC3C7FFAC2C7AA2
-:105A9000870CE3FB0FDF54E880BA3B0CCA01666554
-:105AA0002CDF3B7A81F61680E39442C902B075EC94
-:105AB00002ED688053940312B41BDDA31714DF8238
-:105AC000E7335A3ECC66EC174C627180970CAD639D
-:105AD000BA15CEEB2CFB44CF34D83EA02F9F0AF74B
-:105AE0006A854960FDA4A3704FB0CF8139319E1DF6
-:105AF000703E96A314627BBA6E20D602F7D1FF9552
-:105B0000B6CC63A671B13F87FA6BF8F7AF8C3DD77F
-:105B10002953BD0AABE5375689EED795697E0CEF60
-:105B2000AF3ED568A4B2F36A29C379B4E59977C0CA
-:105B30003C763D5B529E73FDF801AB86F695B10E47
-:105B4000103A86C8CBCE14F8BF28A6C26E369DB1D7
-:105B5000965F41C5BFF0763809D34FD208F896ADAD
-:105B6000C5DAB0FE76EC1F6C6776230B8E775AA7EA
-:105B70006E5D9B29D6433C2F639E49708434D620AA
-:105B800031B8BF54E627FCBC644BA073D11FE0E9D9
-:105B9000D94453CB46A45719E8328F4A6681322D37
-:105BA0001AD683F6B4374C1EA4AB5D264EB7991AAD
-:105BB0005EEED2F0FEFA28E6463A1D073083F26D1B
-:105BC0009BE377B6249AC74FF3C8FB6D488FA39920
-:105BD00097D64F616EDA8FDA6F2CEB3621CCB40397
-:105BE00059844F5933EC7D26D9666E463A0B34D929
-:105BF000D947DA607D203A765528FEEA71BC3974BF
-:105C0000DC2C1AA78E77AED2B08F46E1E1FD443F7F
-:105C1000CE4C8DDD9383E3D89B521ED677EBCB63BE
-:105C200082E37A9B8CEC23B8D7FFD3C4A83CDD6415
-:105C3000A1F5FF6F532A957F6B52A8FE6C533695E2
-:105C40007D4D56AA7FBF693A95772D8A2940FA770C
-:105C5000F966B28F8C42CEC0FF9C5E9DA32F04EEEE
-:105C60009D393C1DBD26E8A83763F8F66E6C077CAD
-:105C7000F6DECAF1D97F3FF3ECC820BA5C6B49B8B5
-:105C80001EFF30C284E7EB8F610BBC704F6F17486B
-:105C9000347FFF680EEFB7EA683EBB866DC5F16FD3
-:105CA00017E8F9FC133455D86E4FE0F3F666010C93
-:105CB000FB59307DE6CBC897F664A8CF0BC2BD5325
-:105CC00078BB7D0CAF57F7ABB6FFCE66E17428F01A
-:105CD000DEAF83F57388DE697EB5FFD7459C0F2361
-:105CE000FB7B3235659E61EE23C1C6FB135FC07D31
-:105CF000B8910F3242F8A25E21BE50E950A5BF977D
-:105D00006CFC9E330D82CE4127D0FDA16E40F99AE6
-:105D1000027C20D1BDD8199C679724F825921FA03A
-:105D20004439AEF283CA072ABDA7019F4909C1734E
-:105D3000FC28825ED5F2B495E3A53B39E601C26B3F
-:105D4000A7CE02A210FA03221310BEB3C00EE34A7C
-:105D50001E35370C27BFE2FED97B50E5C108F7702E
-:105D6000DDF9F5BCFCBEE727F986721BE9761879E8
-:105D7000F5B53581F6A3D26D92CDFE5F483FFD9219
-:105D8000492BC54169E2741379FEB70BF83954FA0F
-:105D900079C9C6B8BEC4734EBC5EDEA9E7193AE73E
-:105DA0007246722F338AD747E2573D5788DC8BB152
-:105DB0001506EF93316E0F8C057B606346907E0372
-:105DC000495F2E43FDB5CDAAD0FEFEA09109FFAAE2
-:105DD0003E19AA97E425F373C2F40CB3001E070E14
-:105DE0001B88BFFD1A56F50A8C6B2555113CF76DC3
-:105DF000362E0F06174CD2AC827D05FE6E76A3DEE2
-:105E00000A8C19382BC1F8C0563040C87EB0FF58F4
-:105E10004A66EC7ED029A897AE809C63598CC9DB7A
-:105E20003E3F2BC1BE976D9319DA350110DB328CE2
-:105E3000733D19E331F2718CC1B83A31AE79EBA7F9
-:105E400077217D9D07FA44FBE62353FD040676CFB8
-:105E5000EC6D3ABAC765317A0FD61FDBFAC48945B3
-:105E6000009F6F9714B4374A6533B5D73C2F7B70CA
-:105E70009D3A73E94509EC9C407BCB535150EFDCD4
-:105E8000AB63261857DA2E59FD30FF726F0CDE0C0B
-:105E90005BB645F77E5F76506EDE26F458D52EC988
-:105EA0000314C3AAB687B7D7EC0A87EB983608C3A2
-:105EB000FCB36C318964FF4D6636B4FFD896045448
-:105EC0005643723B92AE506D237EEC8D5C1E33F6D2
-:105ED00059F21D4097F2E1CFD3DF377378BE80CF00
-:105EE00001FCC9E7FCFED57BAB1732FF93D1ACC0F8
-:105EF0000BE7AC3F6CB2B8E160F51D329D23E08D3D
-:105F0000A37B7645F5DD4E7C7A48B6A01DB6C12749
-:105F1000BBB1DDD969DAA98173D61F9018DA9F4E1B
-:105F20009FC1C3EFE9EA326C5FEE3359146C3F64F2
-:105F300060328C0F00DE4C88C7717D847FC42BDA01
-:105F4000A7F0F763A928887F19F19518C457F3566D
-:105F5000BE9FF37B397E4AE5D55AC2578BC4524265
-:105F6000F0FC67CD8B43F8C27EB3B7FDB50BF1BC37
-:105F70000CF6675010EF32E1F93CE007E7D51FFE61
-:105F800028BDCF1CC4B70CF8FEAD3A1EFA2FBF01D6
-:105F9000BEAB987B1DDA73DF17CF69C8FF4964F782
-:105FA0009EFF03DABD31608F23E908FB38A9B6F7FD
-:105FB00078222C589170D9B902EA27A5BEC232C105
-:105FC0004E90E21D8F225F9F9DF39747101D3D73FA
-:105FD0005FB4215D34EBFA5A9F860A777CB4157959
-:105FE000B03F63FEF6D7609DE2842FD3F723BFFC5A
-:105FF000C96041727A42F023FE1901FF4EC6EF1BC1
-:10600000F0780ECFEFEC34F80D708FACBDC43E6469
-:106010000F4C407DECD5A39C2AD10F54AC407B1C87
-:10602000E6C375242023E4EBDACE3F9F96609CA460
-:1060300024B2C5081BCD7E19E769D35D193A37CC68
-:106040002359FE42FDDA6C13E8FC13537EA4A0FC36
-:10605000695EC81C5113BF4DCE3392F3CF0A7F65E2
-:1060600044FB6F0479AFDA7DCC3D361EF90BEF822D
-:10607000F30F973BCBA733F127F842C0556BDCB148
-:1060800046E8BCFC666B2A9EFF63A4B358A4BF53CA
-:10609000DA51B0AFBA5689F0568FF483FE15EA375D
-:1060A000A8EFF70A39F27C77F1A8442C252B702A47
-:1060B000ABEE94AD7E68AFF6717ABA8E6E84FCA8B2
-:1060C00069E3F2E33A3A6A0338C44EAB47BA526125
-:1060D000C0F7C9A0FC987A0DF6FBF23426F4955B64
-:1060E000D05B4E5C1FD0CB2053E22C39217A4BE29F
-:1060F000F6962A576EDA0AA23E64DDC91E23D386BD
-:10610000AC7BF35E4B183CD59B1AD6FF073E25AC03
-:10611000DDE6CF0E6BCF3F610D830BBBA787F59FED
-:1061200076DA1E06DFD25716D6FF8717CAC3E0C13C
-:106130001C38CF3076C7901E4A95C2FACF514C61B9
-:10614000F3CFCB8E0F8307CDE27E841DA8DAA75F45
-:10615000D8B81D1459AAF7FB136BF83AAA5FFCD301
-:10616000E9E1EBCDB787AFF75DF1B21BEC7E2DD83F
-:10617000F57B413F62F902D8FF5AB0EBDBC0FE4726
-:10618000F825B0FFB1F482FD8FF5AF80FD8F703B35
-:10619000D8FF081F047F05615F531995879ACAA924
-:1061A000FE46F7D725D63D21D63D29D6FD47EF49F6
-:1061B0002D9D6593345F009FCE4CB8A847396C6F16
-:1061C000EC2BC538C0C05B32DB810CE2F09C684A26
-:1061D000447D348AA1DDC2CA07DEC63845FD818907
-:1061E000968D0AEAA1FF7C07DB03EDB282F2FCA8E0
-:1061F000EF83589CE7CA17C087F938EE8358F48FAD
-:10620000EBBE64046F847605E039FB4130903D03BA
-:10621000720DFB67AAB047CFA02C6FDBAF477CD4D1
-:10622000EEDD4FED6F7975E1ED7B5BC2DA2DD81FA6
-:10623000CA5AAD87FCFB4B3E753E3FF5AFCB94ECA5
-:1062400068175FDAFB9FC9CBB05FDBBBC9F77DCBBB
-:106250007D7F72F0C51C94EB4ED0C37E73701E67B9
-:10626000874EC07CDF7599FB4B135011B4496C12FB
-:106270001457D826B60AE45DADAFB50EE5506DF6FD
-:10628000221DCB207924E20D206DD15E42E71EEE67
-:10629000EF8AF7D3D8FB60DE37BCC76FB723FE3A6F
-:1062A0008FC5E2BAFDED72983F73771EB75BEFCEF4
-:1062B000D313DEAEB41F8B55A07D83F718BF6FAD2F
-:1062C0009FCE7D54C0FD50D23DFB643A77F5171A3E
-:1062D000BA7F75BEFBF3649A678E6F520C9EABC794
-:1062E000CBD773E529B4CE9CCCA595B8FF93A90B69
-:1062F0000B65B2F34030A35C9D32AF15E303B55E8E
-:10630000D93E9CBFB546CCDBA5E374F856E6AB5D41
-:1063100063803E4E968DB291CC17FD7E93C7EDF112
-:1063200052BD2313F5428F5989413A7EB86C620CF5
-:10633000E2F52896585FB653EF80B2A69DAFD763BB
-:10634000E98E457AEB69CF97D16E51E75B89EB1601
-:1063500086D0F510DEDC84A72A4F8B19E709E28F7F
-:10636000D7BBF2B81D7ED2F3EE5D68A7F464475B3D
-:10637000112F5D7A46FE6D2DE015F5414F675A0BE2
-:10638000DE83BA9E4BE0A33F5B43780DF874A2DF37
-:10639000A25616D64FC7F1B52B7C3F16CFB97F5BFF
-:1063A000847AE959B0ABA1BA4ED7908CE7FF787BDD
-:1063B000F8FEAAC43DD7E9FCC9C921F45AD731C4B3
-:1063C0002F66A2EF0E953F14C2A78AC79E6C6EB7C8
-:1063D000F5A41A3CE82FD6ED6F25BABE3EBED39D7C
-:1063E00081767EDAAF8D1437BC913FABDA01217E26
-:1063F0000F433F4E5736B1503321A8EFAFD9EC2FA2
-:10640000E615A23F544EFE5E0F1B5886CADF897602
-:10641000701CCADDBF3D85EB0EB683BD07EB3A8D20
-:10642000BEB91F829D35680546817D0F6ED7798480
-:106430007F6246FB7499B04F3F561C4532E857E7E0
-:106440001A0D9DAF2E278ADBB5424E7EB23FE3A7E1
-:1064500048AF7527648B11ED50F05B086EE3764111
-:10646000BD37E3DF67A0BDDDA6233B40B53B9CC243
-:10647000EE382FECD9F36B06F464AF1E96D813B048
-:106480008F2ADFE6AE346877E6CC257BD529B75175
-:10649000FC71F9D670BBA0DA130ED7EE0D879D11F3
-:1064A0007683EAB7F5E40DD90F93D1FF289167A45D
-:1064B000201F7C2CF0A9FA232BA75A5390DF3768B2
-:1064C00095B96A3C00EFC975F8D56ADCAFA72ECA4A
-:1064D0004A7EC1AA43749FFD9F71BFA33F9571FB84
-:1064E00088F17BEDF771FA76E924EE6700B9D27C8A
-:1064F00046C9B3069AFADD83B12497182B437E6808
-:106500005CC8FD483BC65CA1DC9727E24511FAF266
-:10651000566D9F1C1F221F3ECB9B40FB2FD633077F
-:10652000EAA9953156D25BE38DDCDE2E59EDB5211B
-:106530001D8C07FFD81012CF1E6F1E90B0DFAE87E4
-:1065400078FC5CF5EFE76B2DBAF810BD0792276C6D
-:106550007E90247CFC8DE6B7C0FCE6E0FC70DF7129
-:1065600078DF9F1658491FA7CF67AC9BF8B181F819
-:10657000513DCF15A0B362A0338C9920DEEAB61F3F
-:10658000A138B09375933F521ACBF7518AFB41382B
-:106590008A97967C2E37CAF3F9BD350B58955B6FF9
-:1065A000E5DBE3F3A1DC9BEF48CAA77A0BD1E54A10
-:1065B000412B60A7A4F40D23771BFFC2FDAA4F81D6
-:1065C0000F90CFEF699094CC303B88D3B78B57B105
-:1065D000CBCCDB3B03EFC16DEFCE4E463F8AF3D50C
-:1065E0009255262533844E5D48E7702F5596EA1F55
-:1065F000A3DDED5895AC60BCDF85743F01AF91D34E
-:106600007522FC43FFE23A3AF786C3F0B71DE9ABC7
-:106610009E19ACA8475CBEC876AB16E33AF9F9C040
-:10662000073707F9205DD0658B43F2A0DC6FF94A8C
-:10663000CBE3588B258A5BDD09954897F487FDAA43
-:10664000667A70FE3B01447F886D4924BEA1469066
-:10665000233F17E7BD53EB3F827C7C5CE7CDC078DE
-:10666000CA7127CFEB2C646070807C59CCBAA9EC3E
-:106670008DAE3FE0A7C9DDE3D06F7ECF61A0384E7D
-:10668000CBDA1D31284F73D95ACBF96C54EE6CEF2D
-:10669000B5FC91ED0A2024765EC50BC5853611FE4A
-:1066A00055BCEECDB7CF47FC8F34BEF6AF076E4773
-:1066B00097A2F681567D0A279BEEECA220FE5CCCC9
-:1066C0009B8DFB55F135843FD8F358B887056CA0F6
-:1066D00008FD1A156F46F8371CDED4FB4CD70DFCAD
-:1066E0000CAF0CF412C997487CAAF75BCF1A743C24
-:1066F000CED5F0CE42E87FF75A8D82F6E175F8BD2F
-:10670000011EFC26DEE48F91C8DF1C092F2A3E54AF
-:10671000FC9C8EE7E34EDF23539CEEFF355EDECA22
-:10672000773CFA6DFC18C97F23F1DB9255117C1977
-:10673000C17F2ABE1CAB6289CF543CD6298CFCD6C3
-:10674000BACE18AB8705F167867F883FCC53503CA3
-:10675000A65D62CF48DF850FFB28AF11891FA00D12
-:106760003BCAF59D11FCA7E26D24F9A3CAAF33CC57
-:106770007FDC22517E80F3E7AF0C1ECC2FAAF901FB
-:10678000350F704CC8BFC8F20CD81D9877D998DD6A
-:106790009384F65AAF5E9D87E71FCFACE91EB70220
-:1067A000C69F99C9CB5EB4D342607B148FC39D1939
-:1067B0006D70E3BD9D9126CF423D7E46FAF5ED1CFE
-:1067C0004ED12B082F4C996501B857A7C6ED1E1660
-:1067D00072D843E59985D38AA99FC4DEC4FB5024AF
-:1067E000564EEB48524219ECE7CC0393F29A59F01B
-:1067F000FCAFE4737BD62BE4F9501CFB3712C5B118
-:1068000097800AB060BC7DD6D36513A0FEEC8313DD
-:106810006D94FF6B0C5F1FF56806C50737D37CB717
-:106820007E31A05B9A13DCD790FE2BBECAEB2B27E0
-:10683000913F512570684F98CCFD58CFC438D4474C
-:10684000AA7E1A3CF1AA39347E7911F417D387C095
-:10685000931F4F0FD56F4776FF3E0BE7A9D2BB734F
-:10686000AD507FA1E50FE9680754ED7E348BECD283
-:10687000DD1BB2D0BFA8DAF1FB2C3BC1D10EF26F09
-:10688000B4FCDC97F7DDB27363881DFC6021F70B65
-:10689000161B8F94A07D3AF7E64F1EC178F8A40727
-:1068A000258A8BDDC3BA1F41BD5991CDF9886D3161
-:1068B000925C87F928EFD83AF927BB509E9FCCFE0F
-:1068C000405709FD4C055ABA8F0AE6792C05E36159
-:1068D000EB258A8705FB8FA33CE6D2B5923E3511A6
-:1068E000F561BC4D56705C3CEDE3DEF5B62EACAF09
-:1068F00058CDEBE71A3CED3D38CFD37A6BAB821322
-:10690000954F280FC90B9B0AB8DFB5E43189EC71AC
-:10691000759D494F25B7849ED35420F4F98C6EE2BF
-:10692000FF9F0ABCFC78F5BB6FA62A984F72C4156E
-:1069300040FB3B4F9ECF44F9559C703107E97C9258
-:10694000DEF14C359E7B8781E28705B969720AF4D6
-:10695000CFFBE5CC27B05CB27AE933D51807DD6A06
-:10696000243F4ADD5FA3A468D0DF3CD6F28B7BF1E5
-:10697000DE2E3C69243BBAB1E5A614360C9FAAE58D
-:106980001EC0BF92C5D8F34D462A5F6CB230058E4B
-:10699000B8AF2995E0979B142AD9024E5F8DC25F4C
-:1069A0001D69BE7CF0F715905705EB613EB0376D61
-:1069B00026FB143CE7A429CE1D1BC4B926C1789B35
-:1069C0003B6336DE43C186155D688A2617F0FCE21C
-:1069D000DB3DEBD3C98E5E7DEEB96A685F5A509E8F
-:1069E0005F00F76DDC7E95FCFC631D8F56505C7F6D
-:1069F00087819F4F9CFBC2935929CF60DCF52D1DE9
-:106A0000F9DFAEEDE79EDB00E57D8FADD087D2FBF1
-:106A1000773DAF4DECE7467C35D23D7C7FBEFA7DBD
-:106A20003AF1CF0EE0AB9C7F9CAF5CABD7D0FD3D85
-:106A30005A507E37DEFB059D3B1DF9E9C2E41F116C
-:106A40009DBB0F4B74FFAA1C57C72F10E7ADD5781D
-:106A50001F237B50C8F1CFC1F3C3FB3DD2F17116A8
-:106A6000DAC39FFB167EEBB90F3661061DE35A466B
-:106A70002A23DB8BF48E8956385F9186DBC191ED3A
-:106A80000F17A871719E6FC73F8C0BD709FDE98462
-:106A90008DC525A0FE93FC51B998E7B8EDA216FD6F
-:106AA0002FF0EBDE0FB72FD9FB217A7CA4FDDEA8F7
-:106AB000ACC779B441B93BEDB486F943F4F62D7D0A
-:106AC00051CC1FB2EE90DF01757ACCB3748C26B92D
-:106AD0008078C3BC4CA063F20E842FEA391E0307F2
-:106AE000C1BFE27115261705CF79B1E3722ECAD95D
-:106AF000C8F3D61FBA4CF451E77BF4AA44E79F735E
-:106B0000519B7BE3F31FD97D3917F17751D7578418
-:106B10007E5440DF978B78A87F9DCBF3EF7B0F6A85
-:106B20007DF57A3D8FEF4916F2074BE42BE4C7075A
-:106B30004E703FBEBE6327C9D3C14E1E4F7169BAA6
-:106B40004B5330FED070AE0BE5D9602AF7AF607EB4
-:106B50003BDEDB8C89420F6A07D2E7835C3B2AF27B
-:106B6000B5AA5F7701F9578FF378EBE83D526E34A1
-:106B700043BBE212F233D457ACCA5887747EC19338
-:106B8000849120F676EEFFD453FCED8D688B4C7625
-:106B90002BD486E06FE81C1E993F9C61AA9F1ECDF6
-:106BA000EC21FD5C7AE5A7E41F9FE47932D714CE8F
-:106BB0004FEC10E727E7DA23FAD490F95E52E58725
-:106BC000B01FE7BEF13FC497A76CF65328CFA25180
-:106BD00016E27CA9711E4912FD8A82794073A7F0E2
-:106BE000C7CB646A77F964361AC7A4C650BEBE8C98
-:106BF0006DD2A2BD3B977967F077327DFFF643688F
-:106C00009FF7869C8FEFB1C07EA6FC71699423B379
-:106C100011ED238D24EED55B303F549F15727B6BB5
-:106C2000862C911E1B181D4D76CA9C05CEC5B85FDB
-:106C3000B55F9996EB339887EC2CE619C8C57C268E
-:106C4000F30FE4629E53ED77D71BD10DA41799B7CC
-:106C5000E0AE9075C61472BDF929E69F419EB84416
-:106C6000FEB344FEEA29F4A31A0FF33C61AF26E316
-:106C70003D7CAFE5867B46BC5E06BCDA51FF3898AA
-:106C8000DD8EFC3335C983FCE3DA27317CB756DF70
-:106C900061D881719D7A5D5F32D2F306DF5FF5487E
-:106CA000CFAE03EFEA95A9389EC781C05ED7E0FD5D
-:106CB000BA84FE72FA6E7A0FE36ECE135C8B3AB52D
-:106CC000EF925F5FDBBE9FFCF73AE627FFBDAE2D7C
-:106CD0009C5E0653799C3D923FC6142A617C3167C5
-:106CE0002BE78BBB64D680728E89B8E99CD414B232
-:106CF0004782E3849D285F7E04ED97FE09925582CA
-:106D0000A9FAA3DC6BD12E7267717BA6FF4F2F16F9
-:106D10002C23B9E229F819BE8B11F6EE9CF59BB530
-:106D200072C87EE674F238617F14AB3A48F8768C0C
-:106D3000453CA4E7958F2DE4EF6472E99D8F86C7EB
-:106D40003523CFF1AC88E39CC4384F4E70DFF3D2CB
-:106D5000D2B81C631EA29F2E0D5F5F7DF7A28E5FCF
-:106D600021E869C81F92787C6A24B98279944A9193
-:106D700047A91479944A9147A91479944A9147A94B
-:106D80001479944A9147A91479944A9147A914799E
-:106D900014AC3F895BA5F7703B9F417AE8421E1B0C
-:106DA00013847B1322E031E1FD7B13A470788C44C3
-:106DB000FD8B0B773EE3CEC138A645C8252506EDF1
-:106DC000AF0B261E5FEA8871CC2D84FACA39CDBB81
-:106DD000F97B443BBD67294E58B818F96B30D1C0D8
-:106DE000500EB90B1DF3111F274ECCCEDC4CF2D147
-:106DF00064C53C77EFDD37C7515CEE2D99C9B0E42F
-:106E0000CCECFCB50500CF344B44B720277E50AE08
-:106E1000FA9330CFEC4E9ECF2891EB2A71FEC6D16B
-:106E2000A67C8A6BE53B161586C40F4AC72CCF4457
-:106E30003BA84BA7BC87F154F75F740CFD2835FEC7
-:106E4000A6F6EBCD9B598DFB9A933D716D1ECA1B27
-:106E5000602E946F763D6BC37DD935D15233C92BEB
-:106E6000458BFC5F2DF03D4BE1F6B05FAF6813D072
-:106E70006F8F9A99E85678BEAA52E4AB2A45BE0AAB
-:106E8000F1730AE36650BE03F55876433D9691EFE1
-:106E9000B9761794AF24BA6503E9A1EFC1E6225F82
-:106EA0007139938EF4FC8288C367178A7769F9E594
-:106EB0000FF2715E9AA756C4DF2EEBC2F378EAB8E0
-:106EC000E07846E51D3FE0F299C5E9F97BD7B1CC02
-:106ED0008DEF69EF786D34C593021E8D5B17073017
-:106EE000F038CA2FF61AF76F592AE7973B5E4DA183
-:106EF0007ECD220EEA4CE8CE4A40BD2BF84A850FE3
-:106F00007EC3DFF938F30086F275899FCF79477722
-:106F1000563CC001C9A4C1F8B873076FEF117CE7F4
-:106F20009C20E613E761466F3AE2A3FFF06BE9F7B6
-:106F300002BCD1EC5FC6E5BD3F8BE434F367E17B77
-:106F4000A1CB92F72CBEB7FDF5C17F5984EF6B2F13
-:106F5000EBBCCF21FCDB8333382CED3F6B096D4F4D
-:106F6000F2A6E37BDC5F1FFCE1227C9F7B3969FF9B
-:106F700073F1D61058F7CA596CD73F3C635131F4BE
-:106F80009F67F09C6842BA7999D39769DF81F3785B
-:106F90003FB51DDC5E9FB5EFC09557501F1F88A100
-:106FA0007CBDAF3083EEBBB963CF63486F81FD3AE0
-:106FB000E2838D6D7F7DEEB7D4CF40619479066F0B
-:106FC00001865CDC457FBB1BF7352FDAFB19C29BC2
-:106FD0008B6EA37DCE1BC5F9F9A9A2B98B903F0397
-:106FE00007F6FD0AF96F5E1C18B2B89F174D849F13
-:106FF0009A572717631C2010D35D81F3D7BF60B069
-:10700000229DD6BC9A320BE302C70B797CBA7ACAAE
-:10701000A674D4AF9A43CFEFFE2DC6295F30517EC0
-:10702000C695C0EDBB1AB9A56805E16FE76E7C3760
-:107030001278DE4479D26A9803D7ABDE3D89E2EA62
-:10704000AF7FFD4105E2A144DEBE1BEB3FDB65D215
-:10705000E03DF4E8ED713F423EECD1919F592DE0C7
-:10706000EADE517C3FD17DA584BFC44DE9A85F6BAA
-:1070700046FDE676DCF73C79D373E8E7B03D06CA17
-:10708000155C7C1EEE0DC65D6CD5D12BD5C0F331E1
-:107090005AA497CBD2A68A6770FE56DEEFB2691368
-:1070A000DDA7BBF52686EB413F86F2EAB2B439ACE8
-:1070B000FE62EB9E5CF4432FBD308FFC5195CE55A4
-:1070C0007EA9D96508D387240992C57B0952B36E7E
-:1070D00066063D5B2DC04B07B7059E61C1F197DA8F
-:1070E000747E3DDC51B581ADC5F7C12A3FD4A4DD26
-:1070F0005686E7ABD1B464A1BD529DDF57817C7148
-:10710000D1C48CA9F88E4EE8AB9AF635F3D1EE1DBA
-:10711000693FB1E25DDFE7820F3FF7993CA1F9C11A
-:10712000C8F26F4D4C3915F26EF89E0603D9EEEA9F
-:107130007C6FEBBD75E89FD52770F97116FAB781A2
-:107140001C331771B9B76455787FA988BF4BACD78A
-:10715000F765A1DE53E7FFA650956B7D5928AF2256
-:10716000C7CD9385BC7951227953D32E9D93E19E4F
-:107170006A8C6E0FBEDFA94167929F537B4DE2E39D
-:10718000528BC4BDC3D8A78B3268DD9A3693DD0419
-:10719000E36AA3FA62D11EAA8BE98B453B277048AC
-:1071A000663B04BA1293057E26089485C41DABBDC8
-:1071B0003ABB2977183CA3DD84EF73F0BF61FDB6BD
-:1071C00022CE2755BE685A8F59FA8A904EABB687A1
-:1071D0008FC3735942F82FE0DB991CEA8FDBC4BEE2
-:1071E000FBA573C427FD5FBF9F8E78AFD1B0B59864
-:1071F00047BC24F1EF1E00A6EF1E2E897C64CDDF74
-:10720000CD51482F973EAF23BE0D487D24D7CE1CCD
-:107210005C407229A0EB23B9D6535441F22110DF10
-:10722000578172EACCC17ADE3EBAAF4281F64E8413
-:10723000B17D1C237D7FB9E801921FF364FEBE81FE
-:10724000EDD459781C687D6F13F9153A25D4EFBE3B
-:1072500052A4E66DF4C173CB41BE0930655F3BF2C9
-:10726000619599E239603FB5BD8276DEC2642BC676
-:10727000C5AB701CA7037D68FE2F31E1CB65889FED
-:1072800045718E3B8B308F9DD347FE035035D9E936
-:10729000F57F32901FD9AF1BD88D722A37CEB1B08F
-:1072A00008F651A7EF5E87A1A72BBABE2ECCFBCD67
-:1072B00095B93C627B385D057276F2EF2444FEB0EE
-:1072C000BA88CB5FD05BAC05E942E2F83DE67BF5DE
-:1072D00014CA9540F74492C7917C73D1F7442CCAE5
-:1072E00087D3A0C7DD217EFEE9A57B284FBF00DF45
-:1072F000654079EFDA707A18FCEA67E4EFB1C742CB
-:10730000EA910EB784C3917484F4E80F933B6EA2A4
-:107310009B3D82AF6A6775D7E33D0CC177002C8730
-:10732000C04723E088FEAC9CDB097BF0BF61DEBA7E
-:1073300071FE5EF2CFF7F177B1CDA0BF083E104DE0
-:107340007963CD3ED04F895C3FA15EA88DEDA6B894
-:1073500054E08081F2230F777C4CEF19810E29FED7
-:1073600052DBF15A32FAED3EF41392480F26D33B2A
-:1073700095031DC9E86FA8F5751A6F96788F4F763B
-:10738000BA5AEF94FD59B8FF5AA93B17DB7D851611
-:10739000D11F60196146E7A89338BFB30E99E4790D
-:1073A00024DEF60A7A05B9904BEF2C0EF1B8802A4C
-:1073B00007AA853C398AF5399CEF2D6A5E49C2F7E8
-:1073C00072D1C3CA879B8A547BB881E236BB8A14C8
-:1073D0007EAF623CCDCBE34AD45EFFFAE5DC0939EF
-:1073E000384E11E342E4D0C4A05C41FE4F25FE7F3D
-:1073F00058970CE7AA794EB236A39C5ABCA614BA89
-:10740000B3E5DA15A5142F13EF3F23F7154947F617
-:10741000228EDF1A4D7C4962C87C97C05D4FCD2318
-:107420003943EFE8EF4F7CBC14E313BF58BC99E835
-:107430007948DF84F2399E673B97E3C836D734D763
-:10744000D3F1F286967529C3EC23729FD58E96D21E
-:1074500064E5FA7A75BF974CEAFE66E99242EF61FD
-:10746000C19AD22428971BFFD17BE0E7BDD461F0FD
-:10747000A35EAD5EBC625DDC3074739D3ED81EA21F
-:10748000BF26207E3D94D71869FF91659DE4EFC526
-:10749000381103BE6A25FE027E09D10B6542BF0E7C
-:1074A000C51BAA968E47BF9339968E473D037C55E0
-:1074B000611DC6AFC42F4B34F476C34D65E47E3EE8
-:1074C0002BE271D2B222CE2FA76CF66F50BE8EF493
-:1074D000BD85619AF4ADDF5BA46906DF417E4B4B4D
-:1074E0008E51300F54323B9AF73B6CB260DCA6FFF2
-:1074F000F09714D7ED7FC4BC80E70BCC6C34B47725
-:10750000A54EDD11AA473CD3385F461770BBC59521
-:10751000ADFBF6B8504ECC505C88EC869C68CA93A4
-:10752000047C9F92DEEAEF2CB4603E23D00DDE2176
-:10753000F093EBEBFF4A46FD1AE8FC88DE8305BEBC
-:10754000FA98DE896D10EFF48EFAC43BAB6E258697
-:10755000BE8B2BFBA014FB6D1465303EC0E35A6A52
-:10756000A9FAFF21FEEF946985C3FABF090E73687B
-:107570005C4049192E8E121A17C8D4F2B80096181A
-:1075800017C8CCE4710184312E8025C605B01EE3F6
-:107590000208635C00618C0B208C71012C312E8001
-:1075A000F59F89EF1FFA4130F178A599E4FA4A7CFA
-:1075B000DF0EF7B7F230CF3BAD6C95297F8BDF3F05
-:1075C000A07EBBEEDD4CBB7837E3DD4C793CD701C8
-:1075D000D98A2872E9068E631CC7B55FB2AE41B97D
-:1075E000D2B480D6DFD059F8DE62AC6FD559350AF7
-:1075F000D111C7638B44EFF46B3A5B29EE549C7254
-:10760000584FF56D12C338E95D06EEE73A65A8CD2F
-:10761000A33C28D9C14E4337F91FB57B25A532F4C9
-:107620009DC6F4AB2407D47CF232DEC49C5E935238
-:1076300039CC3B90A177E7E2DDF432CC33E37B71C8
-:10764000F92B7AD7EF04877414D2E156FEFED902E3
-:10765000FF88DF23DE35D574EE5F87EFA122F3CDFF
-:1076600043DFD345E49DEBA789BCB28D7F5F51F624
-:1076700064E5BE03B0DEE02603D91BEE42C703D3A8
-:107680009230EF6FA7F8C8F1C326F28B3EDC7C5333
-:10769000587C84E53B1E9C46F9F9B114AF68D44987
-:1076A000A48F67974D4CC17B9C7D42477AA737AF2B
-:1076B0007C35F66B9CAA503CAAC4C01EA079C47B42
-:1076C00029151F25CD924703F05266A577F64BE0AA
-:1076D0009A305ED9AF33AFC7774D4B187FE7A0D252
-:1076E0004DE36689E8060304789F15E23E9774FE31
-:1076F000F94B7CC7709F81DBAD691A9EBF4EDBC81A
-:10770000DF33DCCF1C7AD4B3CB91BA64D28F7FEA5B
-:10771000837A47F4D8746E972B2938FFD2933A7A3C
-:107720006F5B92F2932C07E9E9627AC720F917C9D7
-:10773000D76E1E997F22DF311CD771B902F748FE40
-:107740005017D225C5651C549E6CAAA2F277E27B25
-:1077500088EBDFFF0F9C453F312D25C68A726EC432
-:10776000EFDDA2BEFD7BAF17C4FBB5344D4FBE822B
-:10777000F7F177B315EF437D2778CA56BE1FF16442
-:107780008F656E0B7D0F061210EEB5140F22615C33
-:10779000DB6BC7EF8E060E4B167A977C9D7CDCFC6C
-:1077A00008BE1371654A1649C1F8F7A69264D877E6
-:1077B000E9840CDAB7CBC7E3A37443C9183FE7F8F1
-:1077C0004ACF731C9B5618AC9F27F82600FD399DA5
-:1077D000FCD083F4F61DE2A6BBB0BF9B99E87B6AA0
-:1077E000FA83FDCCBB791CC54F55BA196C4BD981B6
-:1077F00074F39E90FB8B17BFAB43FDDF9BEFE8C19B
-:107800007D54545E7D2499CE377CFC4A7DA71E1999
-:10781000BF0A959FFF3FDEA79F6A6AA0F29DA6550B
-:10782000547637B9A93D44FE5F1A41FE47C63FAFC3
-:10783000227F47C63F99518923FD09FCCDE3CD1135
-:10784000F1CEB251F7AE87FB9BBD456FC52A35FE21
-:1078500089EF87579A491EFCF7B461E39EEABD9908
-:10786000294E3AC84C7978FFB3B2276A35D0AE9D1D
-:10787000CEF1A7C61D913FF07CC81F58227F68B586
-:1078800041FE78560F2C5CC0F5BC9BF4BC89F0BA65
-:107890006E0DC80F80EF639630F97125427E80C36C
-:1078A00071377D57D56960182754DF51CE82E28B3E
-:1078B000BC61E48997CB937151DEE7E97BFFFA283D
-:1078C0007A9F7B5CBC873BBE81BF87AB64E5B4EE2F
-:1078D00030722516F171DFA881B37F80FEF7FDDEDF
-:1078E0004CF6CABAD1CB8AFE19B9724D7CD7F234A4
-:1078F000FEAE80F6DB7E57E03109F3A18DF7301B39
-:10790000E259FD5D811491CFFE1EBF2B306D7AE1EF
-:1079100077FF5D815BA78F5F1CFABB02B7FA323835
-:10792000ACFEAE001BBF7884DF15983D3DE9FADF61
-:1079300015B86D3AF71747FA5D01B027CB705C9226
-:10794000CD3E07CB34B1CFC8EF694F8AFC5D97C6F7
-:10795000B118CBD258B796EA359E02FA0E5EE3FD17
-:1079600025F981F98E9FE3794B9FB04DC90638CD3B
-:10797000E02539D99B67BF13EBAFD9EC77E13A919A
-:107980007173C42DFAF7B09FBBB13DF2DD958ACF7C
-:1079900015D3B9DC6814E58CE6E1BF276F9CCEF304
-:1079A000F237DA37ECB706D71BDAFFA6A505B81F02
-:1079B000D86F2DD6C37EEBB064E684B0EF53AFA78B
-:1079C0003337D155E3744E5F20CFE67DC8ED412AB1
-:1079D000B3B49E78B41FC73CE489C7FD8E691930E3
-:1079E000E177107F740F9850BFFF71F58009EBFFAE
-:1079F00068E7EF9523E77F793AF703B2660CD0F892
-:107A0000F168E3937D3E108FF65356D587EB28DF60
-:107A1000B27732E997F142BF8C7F6882AF0FE86D91
-:107A2000FCB638CA67B3E2446AAF31723EAD79A89A
-:107A3000F2E00185BEDB9AF76188BD33D903FB0E06
-:107A4000B3BFB483FCDD25C0784F7B750423CDA282
-:107A50007DE564FCDDE5182137D04E5B0C72C15921
-:107A6000F5E69794F7C7F1381FE66891FE7CBA41B6
-:107A7000F17D9A05FDD0E50BD674915FB875A85ECF
-:107A8000F899FBD7A1DF0CF65B587D4DE5912ED41C
-:107A900037B57BC3EB9D0D57C97F05FB2DACFE9E13
-:107AA0005F9ED3F3DF2F08AF07FCEE45BA54F17B9E
-:107AB0005CE79D8C7EDE71679495BFDFF7D2EF9512
-:107AC000EC10DF3FEFFC8F599C6E04BE61BC377435
-:107AD000FCC8F4D14CFDDDB35836F2C38D4A552EA7
-:107AE0000DFDFE899EB929BE373786E48E4BF855C9
-:107AF000F59516D2F369F546925F25729415E1A1CA
-:107B0000DF3F2993859CF212FFF7DC1E4F713C3A50
-:107B100000C2095329EF93DCCCE1812403C9871209
-:107B20004D79DD1E28DFD4847FC7FE2CCA0719F9E2
-:107B3000977F87E9D27BF977E25AA510FDDC66C909
-:107B4000BE0DBF7B6C96441CB1DA4CF9827E8C2F43
-:107B5000C279B6C47BB62D8375B6DC9943F6713F06
-:107B6000E3F2D4BD80E7ADB6C4972F5E81ED0BA7DD
-:107B700050FBC16F263E5E80F653759415EDA72D20
-:107B8000366E5F6F999F4DEDAF4BCA1A3CB7FB2124
-:107B900046EB6C99CFCFBDE5F171E2FB0B8F09F994
-:107BA000794B8B7D34E6A366591C17105F63443E06
-:107BB0006E4B06D443F99454BEF07E9C672ADFEFE7
-:107BC000EF6C0AC98FE30BA73CBE5B2135E2C7BC53
-:107BD000906B6E0CF9C1FF0BB81F749470470000D6
-:107BE0000000000000000000050207000000000087
-:00000001FF
diff --git a/firmware/bnx2x-e1h-5.2.7.0.fw.ihex b/firmware/bnx2x-e1h-5.2.7.0.fw.ihex
deleted file mode 100644
index 280bbcf4f2a..00000000000
--- a/firmware/bnx2x-e1h-5.2.7.0.fw.ihex
+++ /dev/null
@@ -1,12847 +0,0 @@
-:1000000000003BE8000000600000068800003C5053
-:1000100000001968000042E0000000AC00005C50E5
-:1000200000008DE400005D00000000EC0000EAE844
-:100030000000E3000000EBD8000000940001CEE0D7
-:10004000000058E80001CF78000000C400022868D2
-:100050000000F9700002293000000004000322A80B
-:10006000020400480000000F020400540000004594
-:1000700002040058000000840204005C0000000636
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040004000000FF02040008000000FF79
-:100170000204000C000000FF02040010000000FF59
-:1001800002040014000000FF02040018000000FF39
-:100190000204001C000000FF02040020000000FF19
-:1001A000020400240000003E0204002800000000B9
-:1001B0000204002C0000003F020400300000003F59
-:1001C000020400340000003F020400380000003F39
-:1001D0000204003C0000003F020400400000003F19
-:1001E000020400440000003F020404CC00000001AF
-:1001F00002042008000002110204200C000002008A
-:10020000020420100000020402042014000002195D
-:100210000204201C0000FFFF020420200000FFFF5A
-:10022000020420240000FFFF020420280000FFFF3A
-:1002300002042038000000200204203C00000000DE
-:100240000204204000000034020420440000003575
-:10025000060420480000001C020420B80000000131
-:10026000060420BC0000005F0204223807FFFFFFE5
-:100270000204223C0000003F0204224007FFFFFF6F
-:10028000020422440000000F010422480000000084
-:100290000104224C00000000010422500000000074
-:1002A0000104225400000000010422580000000054
-:1002B0000104225C00000000010422600000000034
-:1002C0000104226400000000010422680000000014
-:1002D0000104226C000000000104227000000000F4
-:1002E00001042274000000000104227800000000D4
-:1002F0000104227C000000000C042000000003E840
-:100300000A042000000000010B0420000000000A85
-:1003100002050044000000200205004800000032F1
-:10032000020500900215002002050094021500202D
-:1003300002050098000000300205009C0810000033
-:10034000020500A000000033020500A400000030F8
-:10035000020500A800000031020500AC0000000208
-:10036000020500B000000005020500B40000000610
-:10037000020500B800000002020500BC00000002F7
-:10038000020500C000000000020500C400000005D6
-:10039000020500C800000002020500CC00000002B7
-:1003A000020500D000000002020500D40000000198
-:1003B00002050114000000010205011C00000001FB
-:1003C00002050120000000020205020400000001F5
-:1003D0000205020C0000004002050210000000406F
-:1003E0000205021C0000002002050220000000138C
-:1003F0000205022400000020060502400000000A59
-:1004000004050280002000000205005000000007E3
-:100410000205005400000007020500580000000813
-:100420000205005C000000080205006000000001F9
-:100430000605006400000003020500D80000000665
-:100440000205000400000001020500080000000190
-:100450000205000C00000001020500100000000170
-:100460000205001400000001020500180000000150
-:100470000205001C00000001020500200000000130
-:100480000205002400000001020500280000000110
-:100490000205002C000000010205003000000001F0
-:1004A00002050034000000010205003800000001D0
-:1004B0000205003C000000010205004000000001B0
-:1004C000020500E00000000D020500E80000000742
-:1004D000020500F000000007020500F80000000718
-:1004E000020500E40000002D020500EC00000027DA
-:1004F000020500F400000027020500FC00000027B0
-:10050000020500E00000001D020500E800000017E1
-:10051000020500F000000017020500F800000017B7
-:10052000020500E40000003D020500EC0000003779
-:10053000020500F400000037020500FC000000374F
-:10054000020500E00000004D020500E80000004741
-:10055000020500F000000047020500F80000004717
-:10056000020500E40000006D020500EC00000067D9
-:10057000020500F400000067020500FC00000067AF
-:10058000020500E00000005D020500E800000057E1
-:10059000020500F000000057020500F800000057B7
-:1005A000020500E40000007D020500EC0000007779
-:1005B000020500F400000077020500FC000000774F
-:1005C0000406100002000020020600DC000000010A
-:1005D000010600D80000000004060200000302200B
-:1005E000020600DC00000000010600B80000000068
-:1005F000010600C800000000010600BC0000000069
-:10060000010600CC000000000718040000A900004B
-:10061000081807C800070223071C00002C2100004F
-:10062000071C800038930B09071D0000292B192E89
-:10063000081D685052F60225011800000000000055
-:10064000011800040000000001180008000000006C
-:100650000118000C0000000001180010000000004C
-:100660000118001400000000021800200000000122
-:1006700002180024000000020218002800000003F5
-:100680000218002C000000000218003000000004D6
-:1006900002180034000000010218003800000000B9
-:1006A0000218003C00000001021800400000000495
-:1006B0000218004400000000021800480000000179
-:1006C0000218004C00000003021800500000000057
-:1006D0000218005400000001021800580000000435
-:1006E0000218005C00000000021800600000000119
-:1006F00002180064000000030218006800000000F7
-:100700000218006C000000010218007000000004D4
-:1007100002180074000000000218007800000004B5
-:100720000218007C00000003061800800000000290
-:10073000021800A400003FFF021800A8000003FFF9
-:100740000218022400000000021802340000000019
-:100750000218024C00000000021802E4000000FF32
-:100760000618100000000400021B8BC000000001EE
-:10077000021B800000000034021B804000000018B3
-:10078000021B80800000000C021B80C000000020C3
-:100790000C1B83000007A1200A1B83000000013806
-:1007A0000B1B830000001388021B83C0000001F4B0
-:1007B000021B1480000000010A1B148000000000CE
-:1007C000061A1000000003B3041A1ECC0001022711
-:1007D000061AA020000000C8061AA00000000002AF
-:1007E000021A1ED000000000061A1ED800000006E3
-:1007F000061A36E800000004061A36E0000000027F
-:10080000061A500000000002061A500800000004FA
-:10081000061A501800000004061A502800000004B0
-:10082000061A503800000004061A50480000000460
-:10083000061A505800000004061A50680000000410
-:10084000061A507800000002041A404000020228F4
-:10085000061A400000000002061A400800000002CC
-:10086000041A62C00020022A061AD1000000000209
-:10087000061A200000000124061AB000000000281B
-:10088000061AB1400000000C061A330000000014E4
-:10089000061A33A000000068061A81080000000252
-:1008A000061AD1C800000002061AD1D800000020A4
-:1008B000061A249000000124061AB0A000000028A7
-:1008C000061AB1700000000C061A33500000001424
-:1008D000061A354000000068061A81100000000268
-:1008E000061AD1D000000002061AD25800000020DB
-:1008F000021A292000000000061A30000000000241
-:10090000041A30080005024A061A301C00000009CB
-:10091000061A320000000008061A5000000000020B
-:10092000061A508000000012061A40000000000263
-:10093000061AD0C000000002021A2924000000009C
-:10094000061A304000000002041A30480005024F29
-:10095000061A305C00000009061A32200000000868
-:10096000061A501000000002061A50C800000012BB
-:10097000061A400800000002061AD0C80000000253
-:10098000021A292800000000061A30800000000228
-:10099000041A308800050254061A309C0000000931
-:1009A000061A324000000008061A5020000000021B
-:1009B000061A511000000012041A401000020259D9
-:1009C000061AD0D000000002021A292C00000000F4
-:1009D000061A30C000000002041A30C80005025B8D
-:1009E000061A30DC00000009061A32600000000818
-:1009F000061A503000000002061A5158000000127A
-:100A0000041A401800020260061AD0D80000000242
-:100A1000021A293000000000061A3100000000020E
-:100A2000041A310800050262061A311C0000000990
-:100A3000061A328000000008061A5040000000022A
-:100A4000061A51A000000012041A4020000202679A
-:100A5000061AD0E000000002021A2934000000004B
-:100A6000061A314000000002041A314800050269EC
-:100A7000061A315C00000009061A32A000000008C6
-:100A8000061A505000000002061A51E80000001239
-:100A9000041A40280002026E061AD0E80000000284
-:100AA000021A293800000000061A318000000002F6
-:100AB000041A318800050270061A319C00000009F2
-:100AC000061A32C000000008061A5060000000023A
-:100AD000061A523000000012041A4030000202755B
-:100AE000061AD0F000000002021A293C00000000A3
-:100AF000061A31C000000002041A31C8000502774E
-:100B0000061A31DC00000009061A32E00000000875
-:100B1000061A507000000002061A527800000012F7
-:100B2000041A40380002027C061AD0F800000002C5
-:100B30000200A294071D29110200A29800000000E3
-:100B40000200A29C009C04240200A2A0000000005D
-:100B50000200A2A4000002090200A270000000002E
-:100B60000200A274000000000200A2700000000059
-:100B70000200A274000000000200A2700000000049
-:100B80000200A274000000000200A2700000000039
-:100B90000200A27400000000020100B40000000185
-:100BA000020100B800000001020100DC00000001A9
-:100BB0000201010000000001020101040000000127
-:100BC0000201007C003000000201008400000028C7
-:100BD0000201008C0000000002010130000000044E
-:100BE0000201025C00000001020103280000000075
-:100BF0000201607000000007020160800000000137
-:100C00000201055400000030020100C40000000190
-:100C1000020100CC00000001020100F80000000108
-:100C2000020100F00000000102010080003000001D
-:100C3000020100880000002802010090000000006E
-:100C40000201013400000004020102DC0000000186
-:100C50000201032C00000000020160740000000784
-:100C60000201608400000001020105640000003000
-:100C7000020100C800000001020100D000000001D4
-:100C8000020100FC00000001020100F4000000016C
-:100C9000020C100000000020020C200800000211CD
-:100CA000020C200C00000200020C201000000204C4
-:100CB000020C201C0000FFFF020C20200000FFFFA0
-:100CC000020C20240000FFFF020C20280000FFFF80
-:100CD000060C203800000002020C20400000003406
-:100CE000020C204400000035020C204800000020C7
-:100CF000020C204C00000021020C205000000022B9
-:100D0000020C205400000023020C20580000002494
-:100D1000020C205C00000025020C20600000002670
-:100D2000020C206400000027020C2068000000284C
-:100D3000020C206C00000029020C20700000002A28
-:100D4000020C20740000002B060C207800000056D6
-:100D5000020C21D000000001020C21D4000000018F
-:100D6000020C21D800000001020C21DC000000016F
-:100D7000020C21E000000001020C21E4000000014F
-:100D8000020C21E800000001020C21EC000000012F
-:100D9000020C21F000000001020C21F4000000010F
-:100DA000060C21F800000010020C223807FFFFFF9C
-:100DB000020C223C0000003F020C224007FFFFFF14
-:100DC000020C22440000000F010C22480000000029
-:100DD000010C224C00000000010C22500000000019
-:100DE000010C225400000000010C225800000000F9
-:100DF000010C225C00000000010C226000000000D9
-:100E0000010C226400000000010C226800000000B8
-:100E1000010C226C00000000010C22700000000098
-:100E2000010C227400000000010C22780000000078
-:100E3000010C227C000000000C0C2000000003E8E4
-:100E40000A0C2000000000010B0C20000000000A2A
-:100E5000020C400800000411020C400C00000400C9
-:100E6000020C401000000404020C40140000042195
-:100E7000020C401C0000FFFF020C40200000FFFF9E
-:100E8000020C40240000FFFF020C40280000FFFF7E
-:100E9000020C403800000046020C403C00000005F7
-:100EA000060C404000000002020C40480000000A0E
-:100EB000020C404C000000F0060C40500000001FE7
-:100EC000020C40CC00000001060C40D00000003AAB
-:100ED000020C41B800000001060C41BC00000003F8
-:100EE000020C41C800000001020C41CC00000001CE
-:100EF000060C41D00000001A020C423807FFFFFF29
-:100F0000020C423C0000003F020C424007FFFFFF82
-:100F1000020C42440000000F010C42480000000097
-:100F2000010C424C00000000010C42500000000087
-:100F3000010C425400000000010C42580000000067
-:100F4000010C425C00000000010C42600000000047
-:100F5000010C426400000000010C42680000000027
-:100F6000010C426C00000000010C42700000000007
-:100F7000010C427400000000010C427800000000E7
-:100F8000010C427C00000000010C428000000000C7
-:100F90000C0C4000000003E80A0C400000000001B7
-:100FA0000B0C40000000000A020D0044000000325B
-:100FB000020D008C02150020020D00900215002089
-:100FC000020D009408100000020D0098000000338C
-:100FD000020D009C00000002020D00A000000000B5
-:100FE000020D00A400000005020D00A8000000058D
-:100FF000060D00AC00000002020D00B4000000026B
-:10100000020D00B800000003020D00BC0000000249
-:10101000020D00C000000001020D00C80000000227
-:10102000020D00CC00000002020D010800000001CA
-:10103000020D015C00000001020D016400000001CE
-:10104000020D016800000002020D02040000000110
-:10105000020D020C00000020020D021000000040F2
-:10106000020D021400000040020D022000000003E7
-:10107000020D022400000018060D0280000000127C
-:10108000040D03000024027E020D004C000000014C
-:10109000020D005000000002020D00540000000884
-:1010A000020D005800000008060D005C000000045E
-:1010B000020D00C400000004020D00040000000145
-:1010C000020D000800000001020D000C00000001EC
-:1010D000020D001000000001020D001400000001CC
-:1010E000020D001800000001020D001C00000001AC
-:1010F000020D002000000001020D0024000000018C
-:10110000020D002800000001020D002C000000016B
-:10111000020D003000000001020D0034000000014B
-:10112000020D003800000001020D003C000000012B
-:10113000020D011400000009020D011C0000000A4C
-:10114000020D012400000007020D012C0000000721
-:10115000020D01340000000C020D013C0000000BE8
-:10116000020D014400000007020D011800000029D3
-:10117000020D01200000002A020D012800000027B6
-:10118000020D013000000027020D01380000002C84
-:10119000020D01400000002B020D01480000002755
-:1011A000020D011400000019020D011C0000001ABC
-:1011B000020D012400000017020D012C0000001791
-:1011C000020D01340000001C020D013C0000001B58
-:1011D000020D014400000017020D01180000003943
-:1011E000020D01200000003A020D01280000003726
-:1011F000020D013000000037020D01380000003CF4
-:10120000020D01400000003B020D014800000037C4
-:10121000020D011400000049020D011C0000004AEB
-:10122000020D012400000047020D012C00000047C0
-:10123000020D01340000004C020D013C0000004B87
-:10124000020D014400000047020D01180000006972
-:10125000020D01200000006A020D01280000006755
-:10126000020D013000000067020D01380000006C23
-:10127000020D01400000006B020D014800000067F4
-:10128000020D011400000059020D011C0000005A5B
-:10129000020D012400000057020D012C0000005730
-:1012A000020D01340000005C020D013C0000005BF7
-:1012B000020D014400000057020D011800000079E2
-:1012C000020D01200000007A020D012800000077C5
-:1012D000020D013000000077020D01380000007C93
-:1012E000020D01400000007B020D01480000007764
-:1012F000020E004C00000032020E00940215002085
-:10130000020E009802150020020E009C0000003022
-:10131000020E00A008100000020E00A4000000331E
-:10132000020E00A800000030020E00AC00000031E8
-:10133000020E00B000000002020E00B40000000423
-:10134000020E00B800000000020E00BC0000000207
-:10135000020E00C000000002020E00C400000000E7
-:10136000020E00C800000002020E00CC00000007C0
-:10137000020E00D000000002020E00D400000002A5
-:10138000020E00D800000001020E00E4000000017F
-:10139000020E014400000001020E014C0000000199
-:1013A000020E015000000002020E020400000001C3
-:1013B000020E020C00000040020E0210000000406D
-:1013C000020E021C00000004020E02200000002099
-:1013D000020E02240000000E020E02280000001B74
-:1013E000060E030000000012040E0280001B02A281
-:1013F000020E00540000000C020E0058000000090C
-:10140000020E005C0000000F020E006000000010E1
-:10141000020E00640000000B060E006800000003CE
-:10142000020E00DC00000003020E000400000001B8
-:10143000020E000800000001020E000C0000000176
-:10144000020E001000000001020E00140000000156
-:10145000020E001800000001020E001C0000000136
-:10146000020E002000000001020E00240000000116
-:10147000020E002800000001020E002C00000001F6
-:10148000020E003000000001020E003400000001D6
-:10149000020E003800000001020E003C00000001B6
-:1014A000020E004000000001020E00440000000196
-:1014B000020E01100000000F020E01180000000EC5
-:1014C000020E012000000000020E012800000000B2
-:1014D000020E01140000002F020E011C0000002E5D
-:1014E000020E012400000000020E012C000000008A
-:1014F000020E01100000001F020E01180000001E65
-:10150000020E012000000000020E01280000000071
-:10151000020E01140000003F020E011C0000003EFC
-:10152000020E012400000000020E012C0000000049
-:10153000020E01100000004F020E01180000004EC4
-:10154000020E012000000000020E01280000000031
-:10155000020E01140000006F020E011C0000006E5C
-:10156000020E012400000000020E012C0000000009
-:10157000020E01100000005F020E01180000005E64
-:10158000020E012000000000020E012800000000F1
-:10159000020E01140000007F020E011C0000007EFC
-:1015A000020E012400000000020E012C00000000C9
-:1015B0000730040000E80000083007D8000502BD2D
-:1015C000073400002EAA000007348000312D0BAB39
-:1015D00007350000358217F707358000396D25582B
-:1015E00007360000142D33B40836321039BE02BF5E
-:1015F0000130000000000000013000040000000085
-:1016000001300008000000000130000C0000000064
-:101610000130001000000000013000140000000044
-:10162000023000200000000102300024000000020F
-:1016300002300028000000030230002C00000000EF
-:1016400002300030000000040230003400000001CD
-:1016500002300038000000000230003C00000001B1
-:10166000023000400000000402300044000000008E
-:1016700002300048000000010230004C000000036E
-:101680000230005000000000023000540000000151
-:1016900002300058000000040230005C000000002E
-:1016A000023000600000000102300064000000030E
-:1016B00002300068000000000230006C00000001F1
-:1016C00002300070000000040230007400000000CE
-:1016D00002300078000000040230007C00000003AB
-:1016E0000630008000000002023000A400003FFF2E
-:1016F000023000A8000003FF0230022400000000B6
-:1017000002300234000000000230024C00000000F1
-:10171000023002E40000FFFF063020000000080055
-:1017200002338BC000000001023380000000001A69
-:10173000023380400000004E023380800000001021
-:10174000023380C0000000200C3383000007A1207A
-:101750000A338300000001380B3383000000138834
-:10176000023383C0000001F40C3383801DCD65007B
-:101770000A3383800004C4B40B338380004C4B4095
-:101780000A331480000000000233148000000001BE
-:10179000063220000000010206328020000000C84E
-:1017A000063280000000000206323DA8000000045E
-:1017B00006323D800000000904323DA4000102C150
-:1017C00006323D00000000200632500000000400F8
-:1017D0000632400000000004063240D00000000243
-:1017E00006326B680000000204326B70000202C215
-:1017F00006326B1000000002043274C0000202C402
-:101800000632DA40000000020632E0000000080064
-:10181000023308000100000004330C00001002C66F
-:10182000023308000000000004330C40001002D610
-:1018300006322450000000B406322AD00000000214
-:1018400006321000000001A002323DB80000000086
-:101850000632500000000020063251000000002037
-:101860000632520000000020063253000000002023
-:10187000063254000000002006325500000000200F
-:1018800006325600000000200632570000000020FB
-:1018900006325800000000200632590000000020E7
-:1018A00006325A000000002006325B0000000020D3
-:1018B00006325C000000002006325D0000000020BF
-:1018C00006325E000000002006325F0000000020AB
-:1018D00006326B780000005206326E080000000CE1
-:1018E0000632DA880000000206322720000000B429
-:1018F00006322AD80000000206321680000001A03D
-:1019000002323DBC00000000063250800000002082
-:101910000632518000000020063252800000002074
-:101920000632538000000020063254800000002060
-:10193000063255800000002006325680000000204C
-:101940000632578000000020063258800000002038
-:10195000063259800000002006325A800000002024
-:1019600006325B800000002006325C800000002010
-:1019700006325D800000002006325E8000000020FC
-:1019800006325F800000002006326CC0000000526A
-:1019900006326E380000000C0632DA9000000002B9
-:1019A00002322A300000000006324010000000021F
-:1019B0000632D0000000000602322A340000000087
-:1019C00006324020000000020632D0180000000657
-:1019D00002322A38000000000632403000000002C7
-:1019E0000632D0300000000602322A3C000000001F
-:1019F00006324040000000020632D04800000006D7
-:101A000002322A400000000006324050000000026E
-:101A10000632D0600000000602322A4400000000B6
-:101A200006324060000000020632D0780000000656
-:101A300002322A4800000000063240700000000216
-:101A40000632D0900000000602322A4C000000004E
-:101A500006324080000000020632D0A800000006D6
-:101A6000072004000093000008200780001002E611
-:101A7000072400002ADE0000072480002E050AB893
-:101A80000824E4A061D202E8012000000000000068
-:101A900001200004000000000120000800000000F8
-:101AA0000120000C000000000120001000000000D8
-:101AB00001200014000000000220002000000001AE
-:101AC0000220002400000002022000280000000381
-:101AD0000220002C00000000022000300000000462
-:101AE0000220003400000001022000380000000045
-:101AF0000220003C00000001022000400000000421
-:101B00000220004400000000022000480000000104
-:101B10000220004C000000030220005000000000E2
-:101B200002200054000000010220005800000004C0
-:101B30000220005C000000000220006000000001A4
-:101B40000220006400000003022000680000000082
-:101B50000220006C00000001022000700000000460
-:101B60000220007400000000022000780000000441
-:101B70000220007C0000000306200080000000021C
-:101B8000022000A400003FFF022000A8000003FF85
-:101B900002200224000000000220023400000000A5
-:101BA0000220024C00000000022002E40000FFFFBF
-:101BB000062020000000080002238BC00000000166
-:101BC0000223800000000010022380400000001269
-:101BD0000223808000000030022380C00000000E3D
-:101BE000022383C0000001F40223148000000001DE
-:101BF0000A231480000000000622100000000042AA
-:101C000006227020000000C80622700000000002BA
-:101C1000022211E80000000006223000000000C08F
-:101C2000062240700000008006225280000000045E
-:101C30000622670000000100062290000000040058
-:101C400004226B08002002EA02230800013FFFFF84
-:101C500004230C000010030A022308000000000007
-:101C600004230C400010031A06228100000000A08B
-:101C7000062286000000004006228C000000003C86
-:101C80000622B0000000020006228800000000804A
-:101C900006228DE00000003C0622404000000006C5
-:101CA00006228380000000A006228700000000407A
-:101CB00006228CF00000003C0622B8000000020062
-:101CC00006228A000000008006228ED00000003C20
-:101CD000062240580000000606228000000000088E
-:101CE000022211480000000006223300000000021A
-:101CF000062260400000003006228020000000081C
-:101D00000222114C000000000622330800000002ED
-:101D1000062261000000003006228040000000081A
-:101D200002221150000000000622331000000002C1
-:101D3000062261C00000003006228060000000081A
-:101D40000222115400000000062233180000000295
-:101D50000622628000000030062280800000000819
-:101D60000222115800000000062233200000000269
-:101D70000622634000000030062280A00000000818
-:101D80000222115C0000000006223328000000023D
-:101D90000622640000000030062280C00000000817
-:101DA0000222116000000000062233300000000211
-:101DB000062264C000000030062280E00000000817
-:101DC00002221164000000000622333800000002E5
-:101DD0000622658000000030021610000000002876
-:101DE00002170008000000020217002C0000000388
-:101DF0000217003C00000004021700440000000825
-:101E000002170048000000020217004C000000907A
-:101E1000021700500000009002170054008000904C
-:101E20000217005808140000021700600000008A22
-:101E300002170064000000800217006800000081A3
-:101E40000217006C000000800217007000000006FE
-:101E500002170078000007D00217007C0000076C12
-:101E600002170038007C1004021700040000000F65
-:101E70000616402400000002021640700000001CFC
-:101E80000216420800000001021642100000000184
-:101E90000216422000000001021642280000000144
-:101EA0000216423000000001021642380000000114
-:101EB00002164260000000020C16401C0003D09085
-:101EC0000A16401C0000009C0B16401C000009C4B0
-:101ED0000216403000000008021640340000000CDA
-:101EE0000216403800000010021640440000002096
-:101EF0000216400000000001021640D80000000158
-:101F000002164008000000010216400C000000010B
-:101F100002164010000000010216424000000000BE
-:101F2000021642480000000006164270000000023F
-:101F30000216425000000000021642580000000045
-:101F40000616428000000002021660080000042409
-:101F50000216600C00000410021660100000041449
-:101F60000216601C0000FFFF021660200000FFFF49
-:101F7000021660240000FFFF021660280000FFFF29
-:101F800002166038000000200216603C00000020AD
-:101F90000216604000000034021660440000003564
-:101FA00002166048000000230216604C0000002466
-:101FB0000216605000000025021660540000002642
-:101FC00002166058000000270216605C000000291D
-:101FD000021660600000002A021660640000002BF8
-:101FE000021660680000002C0216606C0000002DD4
-:101FF0000616607000000052021661B80000000171
-:10200000061661BC0000001F0216623807FFFFFFC2
-:102010000216623C0000003F0216624007FFFFFF0D
-:10202000021662440000000F011662480000000022
-:102030000116624C00000000011662500000000012
-:1020400001166254000000000116625800000000F2
-:102050000116625C000000000116626000000000D2
-:1020600001166264000000000116626800000000B2
-:102070000116626C00000000011662700000000092
-:102080000116627400000000011662780000000072
-:102090000116627C000000000C166000000003E8DE
-:1020A0000A166000000000010B1660000000000A24
-:1020B0000216804000000006021680440000000561
-:1020C000021680480000000A0216804C000000053D
-:1020D0000216805400000002021680CC00000004AA
-:1020E000021680D000000004021680D40000000414
-:1020F000021680D800000004021680DC00000004F4
-:10210000021680E000000004021680E400000004D3
-:10211000021680E800000004021688040000000493
-:10212000021680300000007C021680340000003D62
-:10213000021680380000003F0216803C0000009C20
-:10214000021680F000000007061680F4000000056B
-:102150000216880C0101010102168108000000002E
-:102160000216810C00000004021681100000000419
-:1021700002168114000000020216881008012004D3
-:1021800002168118000000050216811C00000005DF
-:1021900002168120000000050216812400000005BF
-:1021A0000216882C20081001021681280000000861
-:1021B0000216812C00000006021681300000000784
-:1021C000021681340000000002168830010101204F
-:1021D000061681380000000402168834010101014E
-:1021E00002168148000000000216814C0000000425
-:1021F0000216815000000004021681540000000203
-:1022000002168838080120040216815800000005D3
-:102210000216815C000000050216816000000005C6
-:1022200002168164000000050216883C2008100197
-:1022300002168168000000080216816C000000068A
-:102240000216817000000007021681740000000170
-:102250000216884001010120021681780000000169
-:102260000216817C0000000102168180000000013E
-:102270000216818400000001021688440101010158
-:1022800002168188000000010216818C0000000403
-:1022900002168190000000040216819400000002E2
-:1022A00002168848080120040216819800000005E3
-:1022B0000216819C00000005021681A000000005A6
-:1022C000021681A4000000050216881420081001DF
-:1022D000021681A800000008021681AC000000066A
-:1022E000021681B000000007021681B40000000150
-:1022F0000216881801010120021681B800000001B1
-:10230000021681BC00000001021681C0000000011D
-:10231000021681C4000000010216881C010101019F
-:10232000021681C800000001021681CC00000004E2
-:10233000021681D000000004021681D400000002C1
-:102340000216882008012004021681D8000000052A
-:10235000021681DC00000005021681E00000000585
-:10236000021681E4000000050216882420081001EE
-:10237000021681E800000008021681EC0000000649
-:10238000021681F0000000070216E40C00000000B5
-:1023900002168828010101200616E410000000043E
-:1023A0000216E000010101010216E4200000000015
-:1023B0000216E424000000040216E42800000004D1
-:1023C0000216E42C000000020216E00408012004BA
-:1023D0000216E430000000050216E4340000000597
-:1023E0000216E438000000050216E43C0000000577
-:1023F0000216E008200810010216E4400000000860
-:102400000216E444000000060216E448000000073B
-:102410000216E44C000000000216E00C010101204D
-:102420000616E450000000040216E010010101014C
-:102430000216E460000000000216E46400000004DC
-:102440000216E468000000040216E46C00000002BA
-:102450000216E014080120040216E47000000005D2
-:102460000216E474000000050216E478000000057E
-:102470000216E47C000000050216E0182008100196
-:102480000216E480000000080216E4840000000642
-:102490000216E488000000070216E48C0000000128
-:1024A0000216E01C010101200216E4900000000168
-:1024B0000216E494000000010216E49800000001F6
-:1024C0000216E49C000000010216E0200101010157
-:1024D0000216E4A0000000010216E4A400000004BB
-:1024E0000216E4A8000000040216E4AC000000029A
-:1024F0000216E024080120040216E4B000000005E2
-:102500000216E4B4000000050216E4B8000000055D
-:102510000216E4BC000000050216E02820081001A5
-:102520000216E4C0000000080216E4C40000000621
-:102530000216E4C8000000070216E4CC0000000107
-:102540000216E02C010101200216E4D00000000177
-:102550000216E4D4000000010216E4D800000001D5
-:102560000216E4DC000000010216E0300101010166
-:102570000216E4E0000000010216E4E4000000049A
-:102580000216E4E8000000040216E4EC0000000279
-:102590000216E034080120040216E4F000000005F1
-:1025A0000216E4F4000000050216E4F8000000053D
-:1025B0000216E4FC000000050216E03820081001B5
-:1025C0000216E500000000080216E50400000006FF
-:1025D0000216E508000000070216E03C0101012098
-:1025E00002168240003F003F0216824400000000B5
-:1025F0000216E524003F003F0216E5280000000017
-:1026000002168248000000000216824C003F003F84
-:102610000216E52C000000000216E530003F003FE6
-:1026200002168250010001000216825401000100CE
-:102630000216E534010001000216E5380100010030
-:1026400006168258000000020216E53C0000000059
-:102650000216E540000000000216826000C000C0C3
-:102660000216826400C000C00216E54400C000C02B
-:102670000216E54800C000C0021682681E001E0057
-:102680000216826C1E001E000216E54C1E001E0083
-:102690000216E5501E001E00021682704000400027
-:1026A00002168274400040000216E55440004000CB
-:1026B0000216E55840004000021682788000800033
-:1026C0000216827C800080000216E55C800080009B
-:1026D0000216E56080008000021682802000200043
-:1026E00002168284200020000216E56420002000EB
-:1026F0000216E5682000200006168288000000020D
-:102700000216E56C000000000216E57000000000F3
-:102710000216829000000000021682940000000061
-:102720000216E574000000000216E57800000000C3
-:1027300002168298000000000216829C0000000031
-:102740000216E57C000000000216E5800000000093
-:10275000021682A000000000021682A40000000100
-:10276000061682A80000000A021681F400000C0878
-:10277000021681F800000040021681FC00000100F2
-:1027800002168200000000200216820400000017DA
-:1027900002168208000000800216820C000002006F
-:1027A00002168210000000000216821801FF01FFCD
-:1027B0000216821401FF01FF0216E51001FF01FF5E
-:1027C0000216E50C01FF01FF0216823C0000001317
-:1027D000021680900000013F021680600000014058
-:1027E00002168064000001400616806800000002A6
-:1027F00002168070000000C00616807400000007FA
-:102800000216809C00000048021680A000000048CC
-:10281000061680A400000002021680AC00000048EA
-:10282000061680B000000007021682380000800003
-:1028300002168234000025E40216809400007FFF17
-:1028400002168220000F000F0216821C000F000FDC
-:102850000216E518000F000F0216E514000F000F16
-:10286000021682280000000002168224FFFFFFFFEC
-:102870000216E520000000000216E51CFFFFFFFF26
-:102880000216E6BC000000000216E6C000000002CE
-:102890000216E6C4000000010216E6C800000003AC
-:1028A0000216E6CC000000040216E6D00000000686
-:1028B0000216E6D4000000050216E6D80000000764
-:1028C000021680EC000000FF02140000000000016E
-:1028D0000214000C0000000102140040000000017E
-:1028E0000214004400007FFF0214000C00000000EE
-:1028F00002140000000000000214006C0000000040
-:102900000214000400000001021400300000000165
-:1029100002140004000000000214005C000000002B
-:10292000021400080000000102140034000000013D
-:102930000214000800000000021400600000000003
-:102940000202005800000032020200A0031500201D
-:10295000020200A403150020020200A801000030BA
-:10296000020200AC08100000020200B000000033B8
-:10297000020200B400000030020200B80000003182
-:10298000020200BC00000003020200C000000006BA
-:10299000020200C400000003020200C8000000039D
-:1029A000020200CC00000002020200D00000000081
-:1029B000020200D400000002020200DC000000005D
-:1029C000020200E000000006020200E40000000431
-:1029D000020200E800000002020200EC0000000217
-:1029E000020200F000000001020200FC00000006EC
-:1029F0000202012000000000020201340000000277
-:102A0000020201B0000000010202020C00000001FD
-:102A1000020202140000000102020218000000027B
-:102A200002020404000000010202040C0000004045
-:102A300002020410000000400202041C0000000416
-:102A40000202042000000020020204240000000210
-:102A50000202042800000020060205000000001207
-:102A600004020480001F032A020200600000000F1D
-:102A70000202006400000007020200680000000B70
-:102A80000202006C0000000E020200700000000E46
-:102A90000602007400000003020200F400000004BB
-:102AA0000202000400000001020200080000000110
-:102AB0000202000C000000010202001000000001F0
-:102AC00002020014000000010202001800000001D0
-:102AD0000202001C000000010202002000000001B0
-:102AE0000202002400000001020200280000000190
-:102AF0000202002C00000001020200300000000170
-:102B0000020200340000000102020038000000014F
-:102B10000202003C0000000102020040000000012F
-:102B2000020200440000000102020048000000010F
-:102B30000202004C000000010202005000000001EF
-:102B400002020108000000C8020201180000000291
-:102B5000020201C400000000020201CC00000000DB
-:102B6000020201D400000002020201DC00000002A7
-:102B7000020201E4000000FF020201EC000000FF7D
-:102B800002020100000000000202010C000000C867
-:102B90000202011C00000002020201C80000000045
-:102BA000020201D000000000020201D80000000271
-:102BB000020201E000000002020201E8000000FF42
-:102BC000020201F0000000FF020201040000000008
-:102BD00002020108000000C8020201180000000201
-:102BE000020201C400000000020201CC000000004B
-:102BF000020201D400000002020201DC0000000217
-:102C0000020201E4000000FF020201EC000000FFEC
-:102C100002020100000000000202010C000000C8D6
-:102C20000202011C00000002020201C800000000B4
-:102C3000020201D000000000020201D800000002E0
-:102C4000020201E000000002020201E8000000FFB1
-:102C5000020201F0000000FF020201040000000077
-:102C600002020108000000C8020201180000000270
-:102C7000020201C400000000020201CC00000000BA
-:102C8000020201D400000002020201DC0000000286
-:102C9000020201E4000000FF020201EC000000FF5C
-:102CA00002020100000000000202010C000000C846
-:102CB0000202011C00000002020201C80000000024
-:102CC000020201D000000000020201D80000000250
-:102CD000020201E000000002020201E8000000FF21
-:102CE000020201F0000000FF0202010400000000E7
-:102CF00002020108000000C80202011800000002E0
-:102D0000020201C400000000020201CC0000000029
-:102D1000020201D400000002020201DC00000002F5
-:102D2000020201E4000000FF020201EC000000FFCB
-:102D300002020100000000000202010C000000C8B5
-:102D40000202011C00000002020201C80000000093
-:102D5000020201D000000000020201D800000002BF
-:102D6000020201E000000002020201E8000000FF90
-:102D7000020201F0000000FF020201040000000056
-:102D80000728040000C00000082807A8000B03491A
-:102D9000072C000032FC0000072C800035790CC0A5
-:102DA000072D00003AC11A1F072D800039EF28D0E7
-:102DB000072E00001C3E374C082E3710391E034BDF
-:102DC00001280000000000000128000400000000AD
-:102DD00001280008000000000128000C000000008D
-:102DE000012800100000000001280014000000006D
-:102DF0000228002000000001022800240000000238
-:102E000002280028000000030228002C0000000017
-:102E100002280030000000040228003400000001F5
-:102E200002280038000000000228003C00000001D9
-:102E300002280040000000040228004400000000B6
-:102E400002280048000000010228004C0000000396
-:102E50000228005000000000022800540000000179
-:102E600002280058000000040228005C0000000056
-:102E70000228006000000001022800640000000336
-:102E800002280068000000000228006C0000000119
-:102E900002280070000000040228007400000000F6
-:102EA00002280078000000040228007C00000003D3
-:102EB0000628008000000002022800A400003FFF56
-:102EC000022800A8000003FF0228022400000000DE
-:102ED00002280234000000000228024C000000001A
-:102EE000022802E40000FFFF06282000000008007E
-:102EF000022B8BC000000001022B800000000000AC
-:102F0000022B804000000018022B80800000000C83
-:102F1000022B80C0000000660C2B83000007A1205C
-:102F20000A2B8300000001380B2B8300000013885C
-:102F3000022B83C0000001F40C2B8340000001F43D
-:102F40000A2B8340000000000B2B8340000000058B
-:102F50000A2B83800004C4B40C2B83801DCD650034
-:102F60000A2B1480000000000B2B8380004C4B4088
-:102F7000022B148000000001062A29C8000000046A
-:102F8000042A29D80002034D062A208000000048A8
-:102F9000062A9020000000C8062A900000000002C7
-:102FA000062A21A800000086062A20000000002032
-:102FB000022A23C800000000042A23D00002034F85
-:102FC000042A249800040351022A2C500000000017
-:102FD000022A2C1000000000042A2C0800020355CD
-:102FE000042A300000020357062A300800000100BE
-:102FF000062A404000000010042A40000010035937
-:10300000062A6AC000000002062A6B0000000004C5
-:10301000042A840800020369022B08000000000053
-:10302000042B0C000010036B022B080001000000B1
-:10303000042B0C400008037B022B08000200000058
-:10304000042B0C6000080383062AC000000000D88F
-:10305000062A24A800000014062A254800000022A1
-:10306000042A25D00002038B062A266800000022CD
-:10307000042A26F00002038D062A27880000002279
-:10308000042A28100002038F062A28A80000002224
-:10309000042A293000020391062AA000000000281B
-:1030A000062AA1400000000C042A29E00002039334
-:1030B000062A502000000002062A503000000002BC
-:1030C000062A500000000002062A501000000002EC
-:1030D000022A520800000001042A6AC8000203956F
-:1030E000062A6B1000000042062A6D200000000432
-:1030F000062ABCD000000002062AC360000000D8E7
-:10310000062A24F800000014062A25D80000002210
-:10311000042A266000020397062A26F800000022EF
-:10312000042A278000020399062A2818000000229A
-:10313000042A28A00002039B062A29380000002246
-:10314000042A29C00002039D062AA0A0000000282E
-:10315000062AA1700000000C042A29E80002039F3F
-:10316000062A502800000002062A503800000002FB
-:10317000062A500800000002062A5018000000022B
-:10318000022A520C00000001042A6AD0000203A1A6
-:10319000062A6C1800000042062A6D300000000468
-:1031A000062ABCD800000002022AC6C000000000A7
-:1031B000042A29F0001003A3062A50480000000E3C
-:1031C000062AB00000000006022AC6C40000000063
-:1031D000042A2A30001003B3062A50800000000E93
-:1031E000062AB01800000006022AC6C80000000027
-:1031F000042A2A70001003C3062A50B80000000EEB
-:10320000062AB03000000006022AC6CC00000000EA
-:10321000042A2AB0001003D3062A50F00000000E42
-:10322000062AB04800000006022AC6D000000000AE
-:10323000042A2AF0001003E3062A51280000000E99
-:10324000062AB06000000006022AC6D40000000072
-:10325000042A2B30001003F3062A51600000000EF0
-:10326000062AB07800000006022AC6D80000000036
-:10327000042A2B7000100403062A51980000000E47
-:10328000062AB09000000006022AC6DC00000000FA
-:10329000042A2BB000100413062A51D00000000E9F
-:1032A000062AB0A800000006021010080000000165
-:1032B0000210105000000001021010000003D000A6
-:1032C000021010040000003D091018000200042341
-:1032D0000910110000280623061011A00000001894
-:1032E00006102400000000E00210201C0000000076
-:1032F0000210202000000001021020C00000000287
-:10330000021020040000000102102008000000014B
-:1033100009103C000005064B091038000005065056
-:10332000091038200005065506104C000000010069
-:1033300002104028000000100210404400003FFF2F
-:103340000210405800280000021040840084924A75
-:1033500002104058000000000210800000001080A1
-:10336000021080AC00000000021080380000001045
-:103370000210810000000000061081200000000201
-:1033800002108008000002B502108010000000004A
-:10339000061082000000004A021081080001FFFFB1
-:1033A00006108140000000020210800000001A8018
-:1033B0000610900000000024061091200000004A32
-:1033C000061093700000004A061095C00000004AE5
-:1033D0000210800400001080021080B00000000184
-:1033E0000210803C00000010021081040000000068
-:1033F00006108128000000020210800C000002B5B7
-:103400000210801400000000061084000000004A32
-:103410000210810C0001FFFF06108148000000022D
-:103420000210800400001A80061090900000002412
-:10343000061092480000004A061094980000004AC6
-:10344000061096E80000004A02108000000010807C
-:10345000021080AC00000002021080380000001052
-:103460000210810000000000061081200000000210
-:1034700002108008000002B5021080100000000059
-:10348000061082000000004A021081080001FFFFC0
-:1034900006108140000000020210800000001A8027
-:1034A0000610900000000024061091200000004A41
-:1034B000061093700000004A061095C00000004AF4
-:1034C0000210800400001080021080B00000000391
-:1034D0000210803C00000010021081040000000077
-:1034E00006108128000000020210800C000002B5C6
-:1034F0000210801400000000061084000000004A42
-:103500000210810C0001FFFF06108148000000023C
-:103510000210800400001A80061090900000002421
-:10352000061092480000004A061094980000004AD5
-:10353000061096E80000004A02108000000010808B
-:10354000021080AC0000000402108038000000105F
-:10355000021081000000000006108120000000021F
-:1035600002108008000002B5021080100000000068
-:10357000061082000000004A021081080001FFFFCF
-:1035800006108140000000020210800000001A8036
-:103590000610900000000024061091200000004A50
-:1035A000061093700000004A061095C00000004A03
-:1035B0000210800400001080021080B0000000059E
-:1035C0000210803C00000010021081040000000086
-:1035D00006108128000000020210800C000002B5D5
-:1035E0000210801400000000061084000000004A51
-:1035F0000210810C0001FFFF06108148000000024C
-:103600000210800400001A80061090900000002430
-:10361000061092480000004A061094980000004AE4
-:10362000061096E80000004A02108000000010809A
-:10363000021080AC0000000602108038000000106C
-:10364000021081000000000006108120000000022E
-:1036500002108008000002B5021080100000000077
-:10366000061082000000004A021081080001FFFFDE
-:1036700006108140000000020210800000001A8045
-:103680000610900000000024061091200000004A5F
-:10369000061093700000004A061095C00000004A12
-:1036A0000210800400001080021080B000000007AB
-:1036B0000210803C00000010021081040000000095
-:1036C00006108128000000020210800C000002B5E4
-:1036D0000210801400000000061084000000004A60
-:1036E0000210810C0001FFFF06108148000000025B
-:1036F0000210800400001A80061090900000002440
-:10370000061092480000004A061094980000004AF3
-:10371000061096E80000004A021205B00000000101
-:103720000212049000E383400212051400003C10D2
-:103730000212066C00000001021206700000000078
-:1037400002120494FFFFFFFF02120498FFFFFFFF25
-:103750000212049CFFFFFFFF021204A0FFFFFFFF05
-:10376000021204A4FFFFFFFF021204A8FFFFFFFFE5
-:10377000021204ACFFFFFFFF021204B0FFFFFFFFC5
-:10378000021204BCFFFFFFFF021204C0FFFFFFFF95
-:10379000021204C4FFFFFFFF021204C8FFFFFFFF75
-:1037A000021204CCFFFFFFFF021204D0FFFFFFFF55
-:1037B000021204D8FFFFFFFF021204DCFFFFFFFF2D
-:1037C000021204E0FFFFFFFF021204E4FFFFFFFF0D
-:1037D000021204E8FFFFFFFF021204ECFFFFFFFFED
-:1037E000021204F0FFFFFFFF021204F4FFFFFFFFCD
-:1037F000021204F8FFFFFFFF021204FCFFFFFFFFAD
-:1038000002120500FFFFFFFF02120504FFFFFFFF8A
-:1038100002120508FFFFFFFF0212050CFFFFFFFF6A
-:1038200002120510FFFFFFFF021204D4FF802000E8
-:10383000021204B4F0005000021204B8F0001000AC
-:1038400002120390000000080212039C000000080E
-:10385000021203A000000008021203A400000002EC
-:10386000021203BC00000004021203C000000005A5
-:10387000021203C400000004021203D00000000082
-:103880000212036C00000001021203680000003FF6
-:10389000021201BC00000040021201C00000180822
-:1038A000021201C400000803021201C8000008034C
-:1038B000021201CC00000040021201D000000003FF
-:1038C000021201D400000803021201D8000008030C
-:1038D000021201DC00000803021201E000010003F3
-:1038E000021201E400000803021201E800000803CC
-:1038F000021201EC00000003021201F000000003BC
-:10390000021201F400000003021201F8000000039B
-:10391000021201FC0000000302120200000000037A
-:103920000212020400000003021202080000000359
-:103930000212020C00000003021202100000000339
-:103940000212021400000003021202180000000319
-:103950000212021C000000030212022000000003F9
-:1039600002120224000000030212022800002403B5
-:103970000212022C0000002F021202300000000987
-:103980000212023400000019021202380000018401
-:103990000212023C000001830212024000000306F2
-:1039A0000212024400000019021202480000000640
-:1039B0000212024C0000030602120250000003062D
-:1039C00002120254000003060212025800000C8684
-:1039D0000212025C000003060212026000000306ED
-:1039E00002120264000000060212026800000006D3
-:1039F0000212026C000000060212027000000006B3
-:103A00000212027400000006021202780000000692
-:103A10000212027C00000006021202800000000672
-:103A20000212028400000006021202880000000652
-:103A30000212028C00000006021202900000000632
-:103A40000212029400000006021202980000000612
-:103A50000212029C00000006021202A000000306EF
-:103A6000021202A400000013021202A800000006C5
-:103A7000021202B000001004021202B4000010048E
-:103A80000212032400106440021203280010644054
-:103A9000021205B400000001021201B00000000192
-:103AA0000600A000000000160200A0EC5554000023
-:103AB0000200A0F0555555550200A0F400005555E0
-:103AC0000200A0F8F00000000200A0FC5554000025
-:103AD0000200A100555555550200A104000055559E
-:103AE0000200A108F00000000200A18C5554000063
-:103AF0000200A190555555550200A194000055555E
-:103B00000200A198F00000000200A19C000000004B
-:103B10000200A1A0000100000200A1A400005014B6
-:103B20000200A1A8000000000200A45C00000C003C
-:103B30000200A61C000000030200A06CFF5C000055
-:103B40000200A070FFF55FFF0200A0740000FFFFFD
-:103B50000200A078F00003E00200A07C000000005A
-:103B60000200A0800000A0000600A0840000000564
-:103B70000200A0980FE000000600A09C00000007D3
-:103B80000200A0B8000004000600A0BC0000000372
-:103B90000200A0C8000010000600A0CC0000000336
-:103BA0000200A0D8000040000600A0DC00000003D6
-:103BB0000200A0E8000100000600A22C00000004A2
-:103BC0000200A10CFF5C00000200A110FFF55FFFE6
-:103BD0000200A1140000FFFF0200A118F00003E0A2
-:103BE0000200A11C000000000200A1200000A000B3
-:103BF0000600A124000000050200A1380FE000002B
-:103C00000600A13C000000070200A15800000800C7
-:103C10000600A15C000000030200A1680000200073
-:103C20000600A16C000000030200A17800008000E3
-:103C30000600A17C000000030200A1880002000031
-:103C40000600A23C0000000400000000000000008C
-:103C50000000003100000000000000000000000033
-:103C60000000000000000000000000000000000054
-:103C700000000000000000000000000000310032E1
-:103C80000000000000000000000000000000000034
-:103C90000000000000000000000000000000000024
-:103CA000000000000000000000320056000000008C
-:103CB0000000000000000000000000000000000004
-:103CC00000000000000000000000000000000000F4
-:103CD000000000000056008C000000000000000002
-:103CE000008C009000900094009400980098009C34
-:103CF000009C00A000A000A400A400A800A800ACA4
-:103D000000AC00B100B100B300B300B5000000008A
-:103D100000000000000000000000000000000000A3
-:103D200000000000000000000000000000B50102DB
-:103D30000102010A010A01120112011B011B0124E7
-:103D40000124012D012D01360136013F013F0148BB
-:103D5000014801510151015A00000000000000001B
-:103D60000000000000000000000000000000000053
-:103D70000000000000000000000000000000000043
-:103D80000000000000000000000000000000000033
-:103D90000000000000000000000000000000000023
-:103DA0000000000000000000000000000000000013
-:103DB0000000000000000000000000000000000003
-:103DC00000000000000000000000000000000000F3
-:103DD00000000000000000000000000000000000E3
-:103DE00000000000000000000000000000000000D3
-:103DF00000000000000000000000000000000000C3
-:103E00000000000000000000015A015F00000000F7
-:103E100000000000015F0160016001610161016259
-:103E2000016201630163016401640165016501666A
-:103E300001660167000000000000000000000000B3
-:103E40000000000000000000000000000000000072
-:103E50000000000000000000000000000000000062
-:103E60000167016C016C0179017901860000000095
-:103E70000000000000000000000000000000000042
-:103E80000000000000000000000000000000000032
-:103E90000000000000000000000000000000000022
-:103EA0000000000000000000000000000000000012
-:103EB00000000000000000000186018700000000F3
-:103EC00000000000000000000000000000000000F2
-:103ED00000000000000000000000000000000000E2
-:103EE00000000000018701BE00000000000000008B
-:103EF00000000000000000000000000000000000C2
-:103F000000000000000000000000000000000000B1
-:103F100001BE01E9000000000000000000000000F8
-:103F20000000000000000000000000000000000091
-:103F300000000000000000000000000001E9021A7B
-:103F40000000000000000000021A022102210228E5
-:103F50000228022F022F02360236023D023D0244A1
-:103F60000244024B024B02520252028A000000003D
-:103F700000000000028A028E028E029202920296D5
-:103F80000296029A029A029E029E02A202A202A631
-:103F900002A602AA02AA02FA02FA031103110328D6
-:103FA0000328032B032B032E032E03310331033489
-:103FB000033403370337033A033A033D033D034019
-:103FC00003400381038103880388038F038F0393D6
-:103FD000039303970397039B039B039F039F03A3F1
-:103FE00003A303A703A703AB03AB03AF03AF03B064
-:103FF00000000000000000000000000000000000C1
-:1040000000000000000000000000000000000000B0
-:10401000000000000000000003B003C20000000028
-:104020000000000000000000000000000000000090
-:104030000000000000000000000000000000000080
-:104040000000000003C203D703D703DA03DA03DD5D
-:104050000000000000000000000000000000000060
-:104060000000000000000000000000000000000050
-:1040700003DD040A00000000000000000000000052
-:104080000000000000000000000000000000000030
-:10409000000000000000000000000000040A050D00
-:1040A0000000000000000000000000000000000010
-:1040B0000000000000000000000000000000000000
-:1040C0000000000000000000050D0514051405188F
-:1040D0000518051C000000000000000000000000A2
-:1040E00000000000000000000000000000000000D0
-:1040F00000000000051C055C00000000000000003E
-:10410000055C05650565056E056E05770577058017
-:1041100005800589058905920592059B059B05A4E7
-:1041200005A405FD05FD0613061306290629062D1F
-:10413000062D063106310635063506390639063DA7
-:10414000063D064106410645064506490649065014
-:10415000000000000000000000000000000000005F
-:10416000000000000000000000000000000000004F
-:10417000000000000000000006500656000000008D
-:10418000000000000000000000000000000000002F
-:10419000000000000000000000000000000000001F
-:1041A0000000000006560659000000000000000054
-:1041B00000000000000000000000000000000000FF
-:1041C00000000000000000000000000000000000EF
-:1041D0000659065F0000000000000000000000001B
-:1041E00000000000000000000000000000000000CF
-:1041F00000000000000000000000000000000000BF
-:104200000000000000000000065F066E066E067DDE
-:10421000067D068C068C069B069B06AA06AA06B996
-:1042200006B906C806C806D706D70748000000002A
-:10423000000000000000000000000000000000007E
-:10424000000000000000000000000000000000006E
-:10425000000000000748075B075B076C076C077DE1
-:10426000000000000000000000000000000000004E
-:10427000000000000000000000000000000000003E
-:10428000000000000000000000000000000000002E
-:10429000000000000000000000000000000000001E
-:1042A000000000000000000000000000000000000E
-:1042B00000000000000000000000000000000000FE
-:1042C00000000000000000000000000000000000EE
-:1042D00000000000000000000000000000000000DE
-:1042E00000010000000204C00003098000040E4029
-:1042F00000051300000617C000071C8000082140BD
-:1043000000092600000A2AC0000B2F80000C344050
-:10431000000D3900000E3DC0000F428000104740E4
-:1043200000114C00001250C00013558000145A4078
-:1043300000155F00001663C00017688000186D400C
-:1043400000197200001A76C0001B7B80001C8040A0
-:10435000001D8500001E89C0001F8E800020934034
-:10436000000020000000400000006000000080000D
-:104370000000A0000000C0000000E00000010000FC
-:1043800000012000000140000001600000018000E9
-:104390000001A0000001C0000001E00000020000D8
-:1043A00000022000000240000002600000028000C5
-:1043B0000002A0000002C0000002E00000030000B4
-:1043C00000032000000340000003600000038000A1
-:1043D0000003A0000003C0000003E0000004000090
-:1043E000000420000004400000046000000480007D
-:1043F0000004A0000004C0000004E000000500006C
-:104400000005200000054000000560000005800058
-:104410000005A0000005C0000005E0000006000047
-:104420000006200000064000000660000006800034
-:104430000006A0000006C0000006E0000007000023
-:104440000007200000074000000760000007800010
-:104450000007A0000007C0000007E00000080000FF
-:1044600000082000000840000008600000088000EC
-:104470000008A0000008C0000008E00000090000DB
-:1044800000092000000940000009600000098000C8
-:104490000009A0000009C0000009E000000A0000B7
-:1044A000000A2000000A4000000A6000000A8000A4
-:1044B000000AA000000AC000000AE000000B000093
-:1044C000000B2000000B4000000B6000000B800080
-:1044D000000BA000000BC000000BE000000C00006F
-:1044E000000C2000000C4000000C6000000C80005C
-:1044F000000CA000000CC000000CE000000D00004B
-:10450000000D2000000D4000000D6000000D800037
-:10451000000DA000000DC000000DE000000E000026
-:10452000000E2000000E4000000E6000000E800013
-:10453000000EA000000EC000000EE000000F000002
-:10454000000F2000000F4000000F6000000F8000EF
-:10455000000FA000000FC000000FE00000100000DE
-:1045600000102000001040000010600000108000CB
-:104570000010A0000010C0000010E00000110000BA
-:1045800000112000001140000011600000118000A7
-:104590000011A0000011C0000011E0000012000096
-:1045A0000012200000124000001260000012800083
-:1045B0000012A0000012C0000012E0000013000072
-:1045C000001320000013400000136000001380005F
-:1045D0000013A0000013C0000013E000001400004E
-:1045E000001420000014400000146000001480003B
-:1045F0000014A0000014C0000014E000001500002A
-:104600000015200000154000001560000015800016
-:104610000015A0000015C0000015E0000016000005
-:1046200000162000001640000016600000168000F2
-:104630000016A0000016C0000016E00000170000E1
-:1046400000172000001740000017600000178000CE
-:104650000017A0000017C0000017E00000180000BD
-:1046600000182000001840000018600000188000AA
-:104670000018A0000018C0000018E0000019000099
-:104680000019200000194000001960000019800086
-:104690000019A0000019C0000019E000001A000075
-:1046A000001A2000001A4000001A6000001A800062
-:1046B000001AA000001AC000001AE000001B000051
-:1046C000001B2000001B4000001B6000001B80003E
-:1046D000001BA000001BC000001BE000001C00002D
-:1046E000001C2000001C4000001C6000001C80001A
-:1046F000001CA000001CC000001CE000001D000009
-:10470000001D2000001D4000001D6000001D8000F5
-:10471000001DA000001DC000001DE000001E0000E4
-:10472000001E2000001E4000001E6000001E8000D1
-:10473000001EA000001EC000001EE000001F0000C0
-:10474000001F2000001F4000001F6000001F8000AD
-:10475000001FA000001FC000001FE000002000009C
-:104760000020200000204000002060000020800089
-:104770000020A0000020C0000020E0000021000078
-:104780000021200000214000002160000021800065
-:104790000021A0000021C0000021E0000022000054
-:1047A0000022200000224000002260000022800041
-:1047B0000022A0000022C0000022E0000023000030
-:1047C000002320000023400000236000002380001D
-:1047D0000023A0000023C0000023E000002400000C
-:1047E00000242000002440000024600000248000F9
-:1047F0000024A0000024C0000024E00000250000E8
-:1048000000252000002540000025600000258000D4
-:104810000025A0000025C0000025E00000260000C3
-:1048200000262000002640000026600000268000B0
-:104830000026A0000026C0000026E000002700009F
-:10484000002720000027400000276000002780008C
-:104850000027A0000027C0000027E000002800007B
-:104860000028200000284000002860000028800068
-:104870000028A0000028C0000028E0000029000057
-:104880000029200000294000002960000029800044
-:104890000029A0000029C0000029E000002A000033
-:1048A000002A2000002A4000002A6000002A800020
-:1048B000002AA000002AC000002AE000002B00000F
-:1048C000002B2000002B4000002B6000002B8000FC
-:1048D000002BA000002BC000002BE000002C0000EB
-:1048E000002C2000002C4000002C6000002C8000D8
-:1048F000002CA000002CC000002CE000002D0000C7
-:10490000002D2000002D4000002D6000002D8000B3
-:10491000002DA000002DC000002DE000002E0000A2
-:10492000002E2000002E4000002E6000002E80008F
-:10493000002EA000002EC000002EE000002F00007E
-:10494000002F2000002F4000002F6000002F80006B
-:10495000002FA000002FC000002FE000003000005A
-:104960000030200000304000003060000030800047
-:104970000030A0000030C0000030E0000031000036
-:104980000031200000314000003160000031800023
-:104990000031A0000031C0000031E0000032000012
-:1049A00000322000003240000032600000328000FF
-:1049B0000032A0000032C0000032E00000330000EE
-:1049C00000332000003340000033600000338000DB
-:1049D0000033A0000033C0000033E00000340000CA
-:1049E00000342000003440000034600000348000B7
-:1049F0000034A0000034C0000034E00000350000A6
-:104A00000035200000354000003560000035800092
-:104A10000035A0000035C0000035E0000036000081
-:104A2000003620000036400000366000003680006E
-:104A30000036A0000036C0000036E000003700005D
-:104A4000003720000037400000376000003780004A
-:104A50000037A0000037C0000037E0000038000039
-:104A60000038200000384000003860000038800026
-:104A70000038A0000038C0000038E0000039000015
-:104A80000039200000394000003960000039800002
-:104A90000039A0000039C0000039E000003A0000F1
-:104AA000003A2000003A4000003A6000003A8000DE
-:104AB000003AA000003AC000003AE000003B0000CD
-:104AC000003B2000003B4000003B6000003B8000BA
-:104AD000003BA000003BC000003BE000003C0000A9
-:104AE000003C2000003C4000003C6000003C800096
-:104AF000003CA000003CC000003CE000003D000085
-:104B0000003D2000003D4000003D6000003D800071
-:104B1000003DA000003DC000003DE000003E000060
-:104B2000003E2000003E4000003E6000003E80004D
-:104B3000003EA000003EC000003EE000003F00003C
-:104B4000003F2000003F4000003F6000003F800029
-:104B5000003FA000003FC000003FE000003FE00138
-:104B600000000000000001FF0000020000007FF8CC
-:104B700000007FF800000CDF0000150000000001BD
-:104B80000000000100000001FFFFFFFFFFFFFFFF2B
-:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
-:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
-:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
-:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
-:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
-:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5
-:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5
-:104C0000FFFFFFFFFFFFFFFFFFFFFFFF00000000B0
-:104C1000FFFFFFFF00000000FFFFFFFFFFFFFFFFA0
-:104C200000000000FFFFFFFF00000000FFFFFFFF8C
-:104C3000FFFFFFFF00000000FFFFFFFF000000007C
-:104C4000FFFFFFFF0000000300BEBC20FFFFFFFFCF
-:104C500000000000FFFFFFFF00000000FFFFFFFF5C
-:104C60000000000300BEBC20FFFFFFFF00000000AB
-:104C7000FFFFFFFF00000000FFFFFFFF0000000339
-:104C800000BEBC20FFFFFFFF00000000FFFFFFFF92
-:104C900000000000FFFFFFFF0000000300BEBC207B
-:104CA000FFFFFFFF00000000FFFFFFFF000000000C
-:104CB000FFFFFFFF0000000300BEBC20FFFFFFFF5F
-:104CC00000000000FFFFFFFF00000000FFFFFFFFEC
-:104CD0000000000300BEBC2000002000000040C017
-:104CE00000006180000082400000A3000000C3C0FB
-:104CF0000000E4800001054000012600000146C0DC
-:104D000000016780000188400001A9000001C9C0BE
-:104D10000001EA8000020B4000022C0000024CC09F
-:104D200000026D8000028E400002AF000002CFC082
-:104D30000002F0800003114000033200000352C063
-:104D400000037380000394400003B5000003D5C046
-:104D50000003F6800004174000043800000458C027
-:104D60000004798000049A40000080000001038064
-:104D70000001870000020A8000028E0000031180FB
-:104D8000000395000004188000049C0000051F80AB
-:104D90000005A300000626800006AA0000072D805B
-:104DA0000007B100000834800008B80000093B800B
-:104DB0000009BF00000A4280000AC600000B4980BB
-:104DC000000BCD00000C5080000CD400000D57806B
-:104DD000000DDB0000007FF800007FF80000193EA6
-:104DE0000000350000001900001000000000000065
-:104DF00000000000FFFFFFFF400000004000000037
-:104E000040000000400000004000000040000000A2
-:104E10004000000040000000400000004000000092
-:104E20004000000040000000400000004000000082
-:104E30004000000040000000400000004000000072
-:104E40004000000040000000400000004000000062
-:104E50004000000040000000400000004000000052
-:104E60004000000040000000400000004000000042
-:104E7000400000004000000000007FF800007FF8C4
-:104E8000000005C700001500FFFFFFFFFFFFFFFF49
-:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
-:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
-:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
-:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
-:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2
-:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2
-:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2
-:104F0000FFFFFFFFFFFFFFFF400000004000000029
-:104F10004000000040000000400000004000000091
-:104F20004000000040000000400000004000000081
-:104F30004000000040000000400000004000000071
-:104F40004000000040000000400000004000000061
-:104F50004000000040000000400000004000000051
-:104F60004000000040000000400000004000000041
-:104F70004000000040000000400000004000000031
-:104F800040000000400000000000100000002080F1
-:104F900000003100000041800000520000006280EB
-:104FA0000000730000008380000094000000A480D3
-:104FB0000000B5000000C5800000D6000000E680BB
-:104FC0000000F700000107800001180000012880A0
-:104FD000000139000001498000015A0000016A8087
-:104FE00000017B0000018B8000019C000001AC806F
-:104FF0000001BD000001CD800001DE000001EE8057
-:105000000001FF0000007FF800007FF80000112E73
-:105010000000350010000000000028AD0000000076
-:105020000001000100070205CCCCCCC5FFFFFFFF4B
-:10503000FFFFFFFF7058103C000000000000000060
-:1050400000000001CCCC0201CCCCCCCCCCCC0201F9
-:10505000CCCCCCCCCCCC0201CCCCCCCCCCCC0201BA
-:10506000CCCCCCCCCCCC0201CCCCCCCCCCCC0201AA
-:10507000CCCCCCCCCCCC0201CCCCCCCCCCCC02019A
-:10508000CCCCCCCC00000000FFFFFFFF40000000B4
-:105090004000000040000000400000004000000010
-:1050A0004000000040000000400000004000000000
-:1050B00040000000400000004000000040000000F0
-:1050C00040000000400000004000000040000000E0
-:1050D00040000000400000004000000040000000D0
-:1050E00040000000400000004000000040000000C0
-:1050F00040000000400000004000000040000000B0
-:10510000400000004000000040000000002625A0F4
-:1051100000000000002625A000000000002625A0B9
-:1051200000000000002625A000000000000E023252
-:10513000011600D60010000000000000002625A087
-:1051400000000000002625A000000000002625A089
-:1051500000000000002625A00000000000720236BA
-:10516000012300F300100000000000000000FFFF1A
-:10517000000000000000FFFF000000000000FFFF33
-:10518000000000000000FFFF000000000000FFFF23
-:10519000000000000000FFFF000000000000FFFF13
-:1051A000000000000000FFFF000000000000FFFF03
-:1051B000000000000000FFFF000000000000FFFFF3
-:1051C000000000000000FFFF000000000000FFFFE3
-:1051D000000000000000FFFF000000000000FFFFD3
-:1051E000000000000000FFFF000000000000FFFFC3
-:1051F000000000000000FFFF000000000000FFFFB3
-:10520000000000000000FFFF000000000000FFFFA2
-:10521000000000000000FFFF000000000000FFFF92
-:10522000000000000000FFFF000000000000FFFF82
-:10523000000000000000FFFF000000000000FFFF72
-:10524000000000000000FFFF000000000000FFFF62
-:10525000000000000000FFFF000000000000FFFF52
-:10526000000000000000FFFF000000000000FFFF42
-:10527000000000000000FFFF000000000000FFFF32
-:10528000000000000000FFFF000000000000FFFF22
-:10529000000000000000FFFF000000000000FFFF12
-:1052A000000000000000FFFF000000000000FFFF02
-:1052B000000000000000FFFF000000000000FFFFF2
-:1052C000000000000000FFFF000000000000FFFFE2
-:1052D000000000000000FFFF000000000000FFFFD2
-:1052E000000000000000FFFF000000000000FFFFC2
-:1052F000000000000000FFFF000000000000FFFFB2
-:10530000000000000000FFFF000000000000FFFFA1
-:10531000000000000000FFFF000000000000FFFF91
-:10532000000000000000FFFF000000000000FFFF81
-:10533000000000000000FFFF000000000000FFFF71
-:10534000000000000000FFFF000000000000FFFF61
-:10535000000000000000FFFF000000000000FFFF51
-:10536000000000000000FFFF00000000FFFFFFF34F
-:10537000318FFFFF0C30C30CC30C30C3CF3CF300A4
-:10538000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FF
-:1053900030EFFFFF0C30C30CC30C30C3CF3CF30025
-:1053A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D9
-:1053B000305FFFFF0C30C30CC30C30C3CF3CF30095
-:1053C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B3
-:1053D0001CBFFFFF0C30C305C30C30C3CF3000141B
-:1053E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF29A
-:1053F000304FFFFF0C30C30CC30C30C3CF3CF30065
-:10540000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6D
-:10541000302FFFFF0C30C30CC30C30C3CF3CF30064
-:10542000F3CF3CF30010CF3CCDCDCDCDFFFFFFF748
-:1054300031EFFFFF0C30C30CC30C30C3CF3CF30083
-:10544000F3CF3CF30020CF3CCDCDCDCDFFFFFFF51A
-:10545000302FFFFF0C30C30CC30C30C3CF3CF30024
-:10546000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DC
-:10547000318FFFFF0C30C30CC30C30C3CF3CF300A3
-:10548000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FE
-:10549000310FFFFF0C30C30CC30C30C3CF3CF30003
-:1054A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D8
-:1054B000305FFFFF0C30C30CC30C30C3CF3CF30094
-:1054C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B2
-:1054D0001CBFFFFF0C30C305C30C30C3CF3000141A
-:1054E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF299
-:1054F000304FFFFF0C30C30CC30C30C3CF3CF30064
-:10550000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6C
-:10551000302FFFFF0C30C30CC30C30C3CF3CF30063
-:10552000F3CF3CF30010CF3CCDCDCDCDFFFFFFF747
-:1055300030EFFFFF0C30C30CC30C30C3CF3CF30083
-:10554000F3CF3CF30020CF3CCDCDCDCDFFFFFFF519
-:10555000304FFFFF0C30C30CC30C30C3CF3CF30003
-:10556000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DB
-:1055700031EFFFFF0C30C30CC30C30C3CF3CF30042
-:10558000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FD
-:10559000310FFFFF0C30C30CC30C30C3CF3CF30002
-:1055A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D7
-:1055B000305FFFFF0C30C30CC30C30C3CF3CF30093
-:1055C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B1
-:1055D0001CBFFFFF0C30C305C30C30C3CF30001419
-:1055E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF298
-:1055F000304FFFFF0C30C30CC30C30C3CF3CF30063
-:10560000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6B
-:10561000302FFFFF0C30C30CC30C30C3CF3CF30062
-:10562000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A6
-:10563000056FFFFF0C30C30CC30C30C3CF3CC00060
-:10564000F3CF3CF30020CF3CCDCDCDCDFFFFFFF518
-:10565000310FFFFF0C30C30CC30C30C3CF3CF30041
-:10566000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DA
-:10567000320FFFFF0C30C30CC30C30C3CF3CF30020
-:10568000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FC
-:10569000310FFFFF0C30C30CC30C30C3CF3CF30001
-:1056A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D6
-:1056B000305FFFFF0C30C30CC30C30C3CF3CF30092
-:1056C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B0
-:1056D0001CBFFFFF0C30C305C30C30C3CF30001418
-:1056E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF297
-:1056F000304FFFFF0C30C30CC30C30C3CF3CF30062
-:10570000F3CF3CF30008CF3CCDCDCDCDFFFFFF8ADA
-:10571000042FFFFF0C30C30CC30C30C3CF3CC000C0
-:10572000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A5
-:1057300005CFFFFF0C30C30CC30C30C3CF3CC000FF
-:10574000F3CF3CF30020CF3CCDCDCDCDFFFFFFF517
-:10575000310FFFFF0C30C30CC30C30C3CF3CF30040
-:10576000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3D9
-:10577000316FFFFF0C30C30CC30C30C3CF3CF300C0
-:10578000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FB
-:10579000302FFFFF0C30C30CC30C30C3CF3CF300E1
-:1057A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D5
-:1057B000305FFFFF0C30C30CC30C30C3CF3CF30091
-:1057C000F3CF3CF30002CF3CCDCDCDCDFFFFFFF6B4
-:1057D00030BFFFFF0C30C30CC30C30C3CF3CF314FD
-:1057E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF296
-:1057F000304FFFFF0C30C30CC30C30C3CF3CF30061
-:10580000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA69
-:10581000302FFFFF0C30C30CC30C30C3CF3CF30060
-:10582000F3CF3CF30010CF3CCDCDCDCDFFFFFFF744
-:1058300031CFFFFF0C30C30CC30C30C3CF3CF3009F
-:10584000F3CF3CF30020CF3CCDCDCDCDFFFFFFF01B
-:10585000307FFFFF0C30C30CC30C30C3CF3CF300D0
-:10586000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCC
-:1058700030CFFFFF0C30C30CC30C30C3CF3CF3CC94
-:10588000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEC
-:1058900030CFFFFF0C30C30CC30C30C3CF3CF3CC74
-:1058A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCB
-:1058B00030CFFFFF0C30C30CC30C30C3CF3CF3CC54
-:1058C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFAA
-:1058D00030CFFFFF0C30C30CC30C30C3CF3CF3CC34
-:1058E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF88
-:1058F00030CFFFFF0C30C30CC30C30C3CF3CF3CC14
-:10590000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF63
-:1059100030CFFFFF0C30C30CC30C30C3CF3CF3CCF3
-:10592000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3B
-:1059300030CFFFFF0C30C30CC30C30C3CF3CF3CCD3
-:10594000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0B
-:1059500030CFFFFF0C30C30CC30C30C3CF3CF3CCB3
-:10596000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCB
-:1059700030CFFFFF0C30C30CC30C30C3CF3CF3CC93
-:10598000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEB
-:1059900030CFFFFF0C30C30CC30C30C3CF3CF3CC73
-:1059A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCA
-:1059B00030CFFFFF0C30C30CC30C30C3CF3CF3CC53
-:1059C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA9
-:1059D00030CFFFFF0C30C30CC30C30C3CF3CF3CC33
-:1059E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF87
-:1059F00030CFFFFF0C30C30CC30C30C3CF3CF3CC13
-:105A0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF62
-:105A100030CFFFFF0C30C30CC30C30C3CF3CF3CCF2
-:105A2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3A
-:105A300030CFFFFF0C30C30CC30C30C3CF3CF3CCD2
-:105A4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0A
-:105A500030CFFFFF0C30C30CC30C30C3CF3CF3CCB2
-:105A6000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCA
-:105A700030CFFFFF0C30C30CC30C30C3CF3CF3CC92
-:105A8000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEA
-:105A900030CFFFFF0C30C30CC30C30C3CF3CF3CC72
-:105AA000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFC9
-:105AB00030CFFFFF0C30C30CC30C30C3CF3CF3CC52
-:105AC000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA8
-:105AD00030CFFFFF0C30C30CC30C30C3CF3CF3CC32
-:105AE000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF86
-:105AF00030CFFFFF0C30C30CC30C30C3CF3CF3CC12
-:105B0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF61
-:105B100030CFFFFF0C30C30CC30C30C3CF3CF3CCF1
-:105B2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF39
-:105B300030CFFFFF0C30C30CC30C30C3CF3CF3CCD1
-:105B4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF09
-:105B500030CFFFFF0C30C30CC30C30C3CF3CF3CCB1
-:105B6000F3CF3CF30040CF3CCDCDCDCD000C0000B9
-:105B7000000700C000028130000B815800020210B3
-:105B800000010230000F024000010330000C000051
-:105B9000000800C000028140000B81680002022062
-:105BA0000001024000070250000202C0000F000086
-:105BB000000800F000028170000B81980002025082
-:105BC00000010270000B8280000803380010000002
-:105BD0000008010000028180000B81A80002026021
-:105BE00000018280000E829800080380000B0000F4
-:105BF000000100B0000280C0000580E80002014002
-:105C000000010160000E017000038250CCCCCCCCAE
-:105C1000CCCCCCCCCCCCCCCCCCCCCCCC00002000D4
-:105C2000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB4
-:105C300000002000CCCCCCCCCCCCCCCCCCCCCCCCB4
-:105C4000CCCCCCCC04002000000000000000000000
-:105C50001F8B080000000000000BFB51CFC0F003B9
-:105C60008A59051918AC84117C7A607E4ECAF43BBF
-:105C7000F232303803B12B103700F1616E06862303
-:105C8000DCC4EBBF2C8F6087CA32303402F11E694E
-:105C900006063B3984B8B90203C30A203F0B2AF633
-:105CA0001E4897CA53E6EEC182B55531C5349411EA
-:105CB0006C1D2CF2C858174DBE5D1995AF4740FFBB
-:105CC00040E32C1D54FE742D08FD4D1B4267A3C9F3
-:105CD000CF80CAFB40FD95A383DD5C5F22FD9DCA9A
-:105CE00082CA8F47E3B731A2F2CD3850F94950F557
-:105CF00000CDA28F7AC80300000000000000000061
-:105D00001F8B080000000000000BED7D0D7854D5BE
-:105D1000B5E83A73CEFC25672693908409093009CB
-:105D200021441B700C3F0D16EB097F8636D70E14ED
-:105D3000696C150744881048A4D6874FFD3291003E
-:105D4000E17F504B43413CFC29BD97B691A2A596FB
-:105D5000D2019F165BDFF782CF7AB5B5BD23A5F8D8
-:105D6000539498774BEDBBDEFAF65A7B9FCC3927DC
-:105D7000332448BDED7BEFC6AF3DEC73F6CFFADBC5
-:105D80006BAFB5F6DA7B9C0E37148E04F818FF6EF5
-:105D900000F81715000A524FA70762D9D700E4E6AA
-:105DA0006BB16415C0D07C2D0113D8FB802BE49619
-:105DB00052ED8CE789DC9941ACD75EA00581F5D125
-:105DC0009E3B0FA2D857B411A01040F100FD19F569
-:105DD0009D81391EA8A2577FF9D8F82E03AC0994EB
-:105DE000E5603B7BFF003AC04473D90160F4C9DA37
-:105DF000790D78CBD98B7C80AC090EFDC652067725
-:105E0000B99EC0727688C1CDCA274A5FF08C62788D
-:105E10006CB8DE117653EBBB012601ACC4BE42EC7C
-:105E2000FDD884F8AE84B13C433ED4E662E5EC7222
-:105E3000A0FABEB1B1848BDA696A116B1700DE2E4D
-:105E400050B9B81EC601E468AE145CBC1EE19F2DBB
-:105E5000EA79CAADDFB361D307B21F4B4988F8585E
-:105E6000FF35EC7BA5E97BE5CCB7B0DF6C30B563E3
-:105E7000786CC37F14017C0E7CF9E7B0F3CFC26766
-:105E8000910E303D0F60727FFAA5E81623FE027076
-:105E9000BE78A1EF8FF8E0117CB8717AB2C1C1F081
-:105EA00056A73800F19E297FE4296374DC7C4A26DA
-:105EB0003A6C6E60FFC7BE6FAE73E8B152C2B3BE3C
-:105EC00088B51F29F0CC9BF8B2842C5AD7CACAEEE9
-:105ED000FE747687131ACA891A8E513F6EF66E08C1
-:105EE000932B77490FC9CDC81A464FA4CB031CEF9B
-:105EF00018FBEFE3B2143DDD063DA758E9E916F4BF
-:105F0000CCBBC74A47770DA3A31FBF5BE9A8E33FFC
-:105F100018BD1619742C80D144C7581ED177B0749F
-:105F2000CCB5D13160D031966C5050FE908E0CDEE5
-:105F3000AD9A03B259B9F735B72E23DD625A77907F
-:105F4000D5574563B586CBD16601D77AA4DF18FA59
-:105F5000E4700419BFAABA343E6F121296B3AB7440
-:105F600092772F23CB905294575552183D37563283
-:105F7000790D119C92A3A63F5CEC8FDA6F64F0A8B8
-:105F80002678367ABA3C122B6F63F0C624AC76388A
-:105F9000807269E0ED0E392CF45682593679E7703B
-:105FA0001AF06DD3F87C36C141EFA1BBAB436270F0
-:105FB0005E9CE1800DD2C0FD6EEDEBC7DABFBDDFA8
-:105FC00001E14B06BCE50CBF8B2FCAE10D8C3E1BDB
-:105FD000435D1D28E75BA7737CFBF3F90AC7EBE978
-:105FE000F1944F308D17EEF104D2EAB72B1C0772F3
-:105FF000AD78D504BC81AA2B1F07020B4622FF33C4
-:10600000F1E3AF067F88C16FA293B73C2061FFDE4A
-:10601000B10F7B80E6FD610FC2611FA71FBCB67187
-:10602000EDE32895314DA1924D1F057400937EA19B
-:106030003A217C727D921DB6EA196FA54DBF84ACE2
-:106040006545E81BC5A66F3EB0EBEB0983D4335A18
-:1060500023C11B12708198CFA3C47C9E762819F4AB
-:1060600030FA95EF32F4F5033FAF64F27040E8EB9D
-:10607000039D407AF64017D3D734AFB9BE1EC7414F
-:1060800083AA6FBEEC40FCF7F6E91B2B7DCAE2DA6F
-:1060900054D43BE5F1B003FB29DBC4F54D59478BE4
-:1060A00003F9344EE82D38CAE9E061FF99F5759996
-:1060B0001867D42E2B1DCB90BEAC5DD511DBFB1A1F
-:1060C000BEEE958189AE6CBCADF80F46AF6112A3F0
-:1060D000E367D8BF474305D171CA20D73D4147BBCD
-:1060E000BE2EC3B147313A3ECAF435C36F6480D384
-:1060F000B1BDC3010ED48FBB1CA41FC794461C584E
-:10610000CFD0DB0234A814F8EF13EB9D01E7A8070A
-:106110007A6A51B99743CF0937EB27771384132154
-:10612000D4D325B538CEE371AEA7CBE3E0889AECA3
-:10613000A15C01CFE3D37B5F1CC3EAF5C69530A217
-:10614000B91F420E4F698AAEC67A3B52C8E93F601A
-:106150002D931CDAF93852C8A59D3E6374ABFC96AA
-:106160003F6AE3C7266B79A44DAEEB0D7E18723DF6
-:10617000487EB81588B9F3B0AC937DE761342A60E6
-:1061800065F907CF6928D76A277F97DBE1D04B995C
-:10619000DCFADA7959E950F45A36EE6D6880B1F2DA
-:1061A000E818E86897CAD33548327A8F0E244066DB
-:1061B000EF474E87B06C9A2F869D69F06F94A0DFF1
-:1061C00028616FE43CD8EB45397F3CC0E88E7C7F8A
-:1061D0004011ED7BBC91B129BADBF5C3571AAC7401
-:1061E000BF39926DA1D7ACD0104B79FCA96197E46F
-:1061F00093A13F0C3932E8D68F0F312BDF7CD3AD22
-:10620000DFEDFAA74DB2E99F41F2C975122AD18E8E
-:1062100019E3C80AEF2DED5FEF61C921EC218F7EF4
-:10622000968DB70024C861FD2F87E408A4F7513587
-:1062300044DF5738928558BE003DDB878F4AF53FD3
-:106240004281A3520E53DA8CBCAB1848C33C90C8B1
-:1062500026BB18229E422201D14562FFBB95E44530
-:106260007120BD8A03FC3DC472142C07C1F80B5980
-:10627000ECC4A2552FFC5962F353124F19F9C8C64A
-:10628000774294E4C103712A6741173D55E8A6A7F8
-:106290001F7AE819808084CF3C08D313AED69F4A7A
-:1062A000901E7D2040F4F4FE0E3ECE4EE1B346F04B
-:1062B0006D1844BE2F4D443E24C023A7E4D02BE6E6
-:1062C00037B3D7482F7B2A99FC96A27FC0D6D52A10
-:1062D0009AFFDC9F99DE134379CE51615884BDDF6C
-:1062E000D81A20FDBCB9D543CF0EA16F4AAE796153
-:1062F000C71DEC9F8F8CAD79732F7B9E68DBAEA1A1
-:106300005DD33196EB97A1D3BBEB46A19D58AF70FF
-:10631000BBB09DDBAD39825A1DA393FA6A567FCB81
-:10632000DD9EB0797D31F4D096EB9307F7B1EF7A2B
-:106330004B167DD7A70B7BEC23C67FC30F42FA8594
-:1063400005DFEA136487B2F7311FABEFF990213F05
-:106350009E7D0FF6B4A6D33F1D6559A4FF3A4EAEFD
-:1063600087105BE7435A4C23BB760A33594BC9BEAF
-:1063700075C4AA70F6457F2531FAE6C40292A622BA
-:106380007D40C2761E740891BE4A3C68B657FBFA3F
-:106390001F1E0B2E64FDC5AE77850F90F88063DE5F
-:1063A000D8CC72BFBEEDDEAF6A69EC27BF4322FED8
-:1063B0009EBCBEB008FD5D17048AB227E03C72C1E6
-:1063C000015C9FAE5F3C329AA65D6A3E19F651FAB7
-:1063D00067A6766E195ABA4CFD963B1CA42FC1E1F4
-:1063E000A1676E09979750A5909B18687A1A3BF39E
-:1063F000F3027E8F128380B0A73F4D7ABD2D713896
-:10640000D74BD0D095061E1DE19988F3A02986FEB2
-:10641000404E1B9757A6B534AC1F52F8D3A87FA3A4
-:10642000A8FFA4C0E332F44DE1A3386FF307A9EF4E
-:1064300070DC34F884C5F89733EED651688C062C9E
-:1064400074B7F3B36F7C8797EA5DBC7E7B10FDE782
-:106450004C70865A58DDA1EC592F9E55E25949BA25
-:10646000BDDF7897DBDF144788F0B4F70BFBB9FD8D
-:106470009423D6A913935D34CF873F00229E62D523
-:106480001BC3991F89FA4D3FC8167809F5062F3F9F
-:10649000B61FC89EEABDE721B23B4B50AFCA18E712
-:1064A00088D23C2E8510950DFDB616F51D7B5E84B9
-:1064B000C82D8E02D42B5D27515FD64FB87B6ABAA8
-:1064C00078D11DC6FCB88CF5E8F3ECB9C013B9134C
-:1064D000FB57C3A735B66243EE5C29969DD37F5E1A
-:1064E00031F10CCE31CF873EB9E0F3A91DE5BD8A6D
-:1064F000CF9BD9AC5C579E1E4EBDED6291B0FB8622
-:10650000917FA3C0B039A6F9A83FC8E6156BF7B8CC
-:10651000E8CF78BF5DE017FB04F3A08E3D03615D1B
-:106520004375394F6F7122DF6E96A26B10EFB9F58C
-:1065300091E791F5EAC16E2D2B44EF3B1C6C9CBAA0
-:10654000501C3907AAD61DC3E763F72CD4908FBD22
-:106550004C67C969FC66E399A539AC7E92DDEF1BF7
-:10656000E47CBC3A1C9F8A765865C3891388EE0286
-:106570004F7427C23524F2945680F0864E6B7926EC
-:106580007E8D14FC5AE6E0F8E73E20F8A66841E468
-:10659000C75D10D98BED039AB0BB07094726F947B1
-:1065A0003B13E93812E59DE9CDF63093F7D2D47C60
-:1065B000C811F3A15DCC87DE095CFEDB03D58174D5
-:1065C000EB8521EF86FC1BFAD05E2FF109E4FC2A53
-:1065D000F6AC8000F9311721FADF900E0C7BB26B1C
-:1065E00072A777913F67CCABFAF0E9E943183EEA2E
-:1065F000845035D2DF18F7BC90BB051EEDE7241F91
-:10660000E56D4A1EC36BCC3D101EC5EACD2ACF9561
-:10661000CCF2FE6A5FFDC8699A5FF7746B4A68E066
-:1066200076FF43E077B31479CD2C87AC9F5F615937
-:106630000D75A384F5D13924EC7BB96D21D90F4CAC
-:106640003E0348E7792D2DCFE37873AB226BB0BEC4
-:10665000D1FFAC90CD6E97A26F61BF7639AD83B894
-:106660000297B17E8C94A217B09FFA5037C19B3B22
-:106670003D4272C6E0FEE05382FB2F48D74C70BF0C
-:10668000858D516F86F7905E63F0C9328363F403A2
-:1066900009258FE87E5A41BA333A3BE582149D07BB
-:1066A0003BCFB7897936D07C6FC77F4C46BB383A31
-:1066B00004C7CF13762E244F00F7AFAC71CA19F27E
-:1066C00079403B2BB72E09181F1A724A0EDFC83EBD
-:1066D0000DAD0309ED62C38ECD13F3D180674B9FDF
-:1066E0009D1CA4F933444D06232ACED74964B73DF7
-:1066F000529B0CA29FB7B63544DF033593D6DF110A
-:10670000C2E1A304C786D6B0B0AF6BE819AFEB3DCA
-:1067100085FB025B820EB27F37B5561A71598237FC
-:10672000CFB093EBCE909DDC1BCC127EA315BE7830
-:10673000DD19CBBE87D10E82A6385619F623ECEBB5
-:1067400010D73703B5574BAC74EF6BAF0DAE7DD69A
-:10675000046BFB5A2DD981F1C400C68F100FA1F72D
-:10676000FC02C6408D83FC6483DE9E2A6B1C2E5E79
-:10677000977E1FA76F5DB08D07E559A932068B6222
-:106780008D04DF4A015FA67ED6887895517666D063
-:10679000934DB25827C57E5440C0FA88C6E8A1A6DA
-:1067A000E83144C8DD967AEE874180C7E70C3FC7E1
-:1067B00009FC7B6A3C8E379549DFC7F83836F88D7F
-:1067C000F62ED13E131C2E7B7F67593F934CFDD88C
-:1067D000E0CC049F7D7F0CDEB6F693597FD9DA9D1D
-:1067E0001F1C1FFAB503133FA99C672B0FB3D52FAE
-:1067F000B37DBFDAF6BDDA56BECE567FAAADFC0534
-:106800005BFD39B6F2576DF517DABE2FB57D5F69BE
-:106810002BFF576BFDAABB3E197DFF3FA39331AF02
-:10682000FAD345B7ECEFDAE75519244624D8736F4D
-:10683000EE4B8BF1D3BFC892728EFB243C8E058940
-:106840007111933DFE7B357A06D7B1BD1F6959A8FA
-:10685000F7F7C75FF6A33E32DE9F97DEF05F156263
-:106860007AC19558C1E33E719A3759A09C49562286
-:1068700097248A9779D44544724F397B6FD26F6ED3
-:1068800088109F5D25D6F710E7F3B01C7D7AD65FA0
-:106890006C9B8BECC15811E8A3315E94CFFBA7FA37
-:1068A000652978AB15AE9F8291782DCEE1610D5DA3
-:1068B00027F069A753705AECDA1730DEF008F7CBEF
-:1068C000F7CFB0FAD5B728DC0FB94DB96CBFE0D51A
-:1068D000F172AAFFFD0FAAE13656653F02C1CAB1A7
-:1068E000073D3AC63746605C8E6F1A505C6E38883A
-:1068F0003F117F2BC17FB376C3D55314670B350689
-:106900004EA2CE9BA354D0788F4B3D57E1788EECAE
-:10691000F3D7F2FDBCBF7C4CF17741AFE0C649C96B
-:1069200018A3176C758547139DC34467B702EDEE36
-:106930006A14134EDFD5ECB578AFF8F2D06D12FCC7
-:1069400040FD3B0AF7B575E0FE6482CA3E48523905
-:1069500047D8B9639452EE17083F9379F612FA5F5D
-:10696000C12F32BF3CCDFA315BAA1DA314A4E29320
-:106970005288C721A54D2FFC59C278572584F8FEAF
-:10698000948807AE97A58F311E1E18DCFE4EF06B63
-:1069900056BE821285D92679FE5A1F3F39BD46055B
-:1069A00039FEC1ADAE16F46BF6CFB2CA81515F5657
-:1069B0002E3B5EB17DDCA84F4F0E729551044F7F88
-:1069C00039B83580FB07528CD12D7BF074CB91B553
-:1069D000AF2A13114FA0F22149BB5529489515D074
-:1069E000E69BBFBF2A4716E0F7D854A86C5153FD69
-:1069F000B0F78B32BC5F92EE7DA961B79EE5EB7874
-:106A0000B1B0AF86B6C7C92E2D6ACACB32DB59C525
-:106A1000625DD8D3B4D08BF86E6F48AF078DE74670
-:106A2000E1F765AAA74A5D11D42B3056810369ECC2
-:106A3000F26751BE4DFA54ADB2DA5BD317C56AB1F5
-:106A4000BDBFCE01B86FC2D679B2EF8A842E7B78F3
-:106A50004A4CC2BC97F872083FC4F0F22F2AF3A642
-:106A6000B3931ED6B6D3FB1DF5876791DFC2EC3A10
-:106A700099E2E25DEBB13CA4C6011BD2EC173C21CC
-:106A8000F0DB5CCFE964FF5EE18268BA79F8AC22A2
-:106A9000F61994980485A9FD92274E147DA192C100
-:106AA0005B1C7684BDA1149CA57D765382E855516C
-:106AB000AD0430DF80297E8BBDB9A3BD7AC71D68C8
-:106AC000B7B3F768B7EFBC3E300CD78D3DB515B303
-:106AD0001A517FDFE980D1A1141C633AADF43CD197
-:106AE000373FADE3B27E6BC97FAA67E44A43872B89
-:106AF000A547A71837939CD8D755BB1C5CCEFA7016
-:106B0000937CE5F8FD00E7E144921F8AD30CAD6762
-:106B10007E5C556A1E197E8A5DCE02750B49CEB623
-:106B2000D7977911CFDEBA6AC9C5EA6DC19A69FCF7
-:106B30007163BC4CF05438A3DE00CDC385523ABA21
-:106B40001546D3C7CF35A7883F2B5109DB67AA3736
-:106B5000C229E441CCAB4231AF82535AE6D0BCD813
-:106B6000A5C0438C5E0FD755B78D26FA3948EEA6DF
-:106B70006B5CCF164EE0FB993E46AF67D9BAF7483B
-:106B8000038413ECFD23135C96FD9942411FBB3C2B
-:106B90003E32807E01B3FFC5E45F71AA7CFFB61C64
-:106BA000CAD19E7AB8EED2ED074BDF608343D39112
-:106BB000BF35D503C44DDA2E779D9A773DCA63CD94
-:106BC00020F3276CFA029EBB6BFD68C607DF2EA67A
-:106BD0002F201D7D5C167F7C207AD8E93F0EE99935
-:106BE000FDE9D1D3FE7D8853C40107498F27EBCB44
-:106BF000B6968732D7B7E363B4DB28E6DBE7A14775
-:106C0000C6F9AF4180E24B53214CCFE910A167B7E1
-:106C100012FD9293D59F092D5436E2508D0ADF97CD
-:106C2000802A3EAEB1BFAD4C03B293C78C077D2F17
-:106C3000EAE72973C4A6AFA29DF3A0D1C6E048E35A
-:106C400057013C447817DBD663234E31B4295E5F8D
-:106C5000CDFA2DAE77501CA3B8E6B0D7BC2EFBC53D
-:106C6000FC31FADBC9BEE3FABCB36970FC32EA3D21
-:106C7000A12429AFEB899A87DA70B951F2DE0EA60A
-:106C80006B6FA7EB968FBABC9134F0EC5C7494F206
-:106C9000B776D65C3A8E3290DC8C91D3DBB39F779B
-:106CA0007B896E3B733DB7F0E49C5596FC0390D511
-:106CB00052F3B83B3F82DCC8A5F489669D2F5B9CEC
-:106CC000221FC4073E94FF4CF4309E9F361D9E9CAD
-:106CD000DAB23492A67D859BDB136B722186F92292
-:106CE0004FBEAEE898DFC00496E471D22D211DEDB1
-:106CF00097355EAE979FAC05FA3E29577C7F2C44B2
-:106D0000F954C59D1073B1F5ACF8B5458FE4B27A6E
-:106D10009B16310FB234F57E53F86407EE133FF340
-:106D20008A2380F6D1246FC2136678D5887570E700
-:106D3000A29394771CDBA58447937E97409A44DE08
-:106D4000BC25AE79DCA910BC3BC30F7B716F6E47CD
-:106D50002849FD7C63F2494F88E1B7A9A4DB837819
-:106D60006EAE7998D6CBC38BCABE5C4164B5E6974C
-:106D7000CC94A7746B98BFBB88EF5BE426BB3D98AF
-:106D80009FE46F50E046069F5FE5F86E5A033AAE07
-:106D900053D5228F4482D9E41717D9F2B80A6D79F6
-:106DA0002681F0CC77709F9FF6FF1109B9E991B168
-:106DB000184F6C7688F4538DE6A94FE0E70B6B54BF
-:106DC0007FA67CCC8B790B3BDA9500AE7F015BBF55
-:106DD000763C02103DA149D40F8DB3E351BE4E065F
-:106DE000265266316B2AE00E30B887B021DBAD70D9
-:106DF0001B74B58FE3B395DF36E4B91846A31E3292
-:106E0000E2CE06FC76B9CD9FA41F7999E1BBF315BC
-:106E100095D6EB9D352F7FAD19D7F94A37E5717DB2
-:106E2000E1E2C1A6EFB3E72F3E385A8ECF2F16ED21
-:106E30009FD08C74107912463CAF107B26FB55E82E
-:106E40003563BCAA3DEDCE7C7A45F9159B4FBEDE7D
-:106E50008871E7A22620FBB748E1F2E96B77E86D7D
-:106E60000CFEFCEBE2240FC50D09025A6DE892629C
-:106E7000267B5E15F69CAF292AE13EFE8D0D712F13
-:106E8000E68BF844FCD737214E76D20CF90D4F52E1
-:106E90004DF1CFC87F37E69F9D3F158B78DE497156
-:106EA000BB1246B08B9B5A1C6487D7F07CEF8ACE0E
-:106EB0002E89FB7F3C9F9E87D4D933D2C8F30977B4
-:106EC000713BDDC8FFF63759F917E8CB9F8FD2BE6B
-:106ED0006B69A7ED7BA4EE2D2E87567E96B9043FF5
-:106EE0002B44FEA0CD4FDBDC24F6E9548F7E29BB7A
-:106EF000F6159187F32AE23FA6FFF79B33E8DF9B65
-:106F0000DC7C9F5F767477901F779D83FC383B1CF9
-:106F10005B9AB8DEDBEF7258ECF82B1DFF36A1FF51
-:106F20006547F26F327E531FFE7F9BF1EFFF1B8F91
-:106F3000BFE16F4CFF1D7F63FC0FFE07E33FAF52C5
-:106F4000B2F8697B5D1EEAEF87EEBEBC0D8BFE9644
-:106F50001DE9FDED332E87258FD8C84B9CD6A02D7B
-:106F600070A1BE0CF3731EF6FE66C82F75A01EDC62
-:106F700021F2B1991ED564CC779A6C9CD3E0FAAF1C
-:106F80004EE8BF3AA1FF0E67D0ABD5355CBF33FBEF
-:106F9000420F95E292119F5581EBF72985F28B0FF5
-:106FA000035B6650AF85DC69F3B10B05DC767D5A77
-:106FB00028F469F54BB6F7428FDAD7F9D2BEF82933
-:106FC00050FCF4BFBB447EA94DAF1A74D851C3ED39
-:106FD000E5FC39E9EDC14D363EAA135A280FC1CE62
-:106FE0008F332EEE5F1BFC58E0D17EED2AC8CCEF2C
-:106FF000A4E0F70D82DFBF7405E869E48D64E277F1
-:107000008D9B8FF359DFD9601B6213A9253EC8827F
-:107010004F326CEAA6F82F7C03CCFEE5968F981DC4
-:1070200082EBBFAA52FCECB3F9E03092ED3F32F6AE
-:10703000E9D89FB39BC751E57C97CDDFB2DBC11E7A
-:10704000CA8FDBA9F1F3563B6BF6EE5C81EBD32BD9
-:107050007C9F79676EE74B78F40DE2E31584C3B04B
-:107060001B41C467D1A4E0F928F6FD27ABDDBFF3CF
-:10707000A3AE04DA5F815229CC3C2BE8083D9C9FEB
-:10708000F63C9ECDDE57DD3E8BBF0B370ECE6E5FDE
-:107090002DF8CDFCC502B7697EAFF6CD1CCFF3A2AB
-:1070A000A607709F47D2663A309E9EA91F8CF49E19
-:1070B00033ED3B352ADA70EC4F42FFB132E53F0247
-:1070C00094F0F8BC81FF60CF0D34DDC5F7BF055DDE
-:1070D000F3AFEBFAABF891469CD7A8A72A094877FB
-:1070E0003EC81EB7BBD1A94D46FC060BFF6E143837
-:1070F000F6FCE72AB92E5DFC2029F4AB1A79EAC523
-:107100009B59D50973251EDF67669B795F6D53BE5A
-:1071100052972EDEF533314F7E894139D2EB09C8C3
-:107120009328AF04102F633EDAC7BF568C7BED1552
-:107130008EFF8A98D7D78A790D10A6FD984CE3D692
-:107140000ABD613C3FE9B8498177AD4BC4350618AB
-:1071500077B6C073F615E27B5E8C3B7B90F82E1001
-:10716000E32DB8C2713F14E32E18E4B8770BFADEB2
-:107170007D8574563C92E86770746E13E3B55DE1EB
-:10718000B801316EDB20C7DD26E8BBED0AE95C22E1
-:10719000C6DD66A373A6F9BBF70AC7ABF4F0F9B373
-:1071A0005FCC5FBB5E33C6578B1C116CBF3368ED81
-:1071B000E78B6E3EBEF184C4C7E4BF168B7DDDC98C
-:1071C0002BEE5DA8A519D7A86F5F8F338DF335110E
-:1071D000AF319EC6387EB11F3AF93A364E1AFA18C8
-:1071E000F5AF75713D98A9FFA5029EA597898751B6
-:1071F000BF16FB9F98B9FFFB041CF7D9E01FA87FBF
-:10720000A3FEEC01E0EF1070745C26FC46FD050364
-:10721000F4FF2D01C7B72E137EA3FEDD03D0E709CF
-:1072200001C7139709BF51BF6D80FE9F16703C7D4B
-:1072300099F01BF5B70D409FE7041CCF5D26FC4677
-:10724000FDFD7DF3DD3AFF54E33C50182A31DF7831
-:10725000046485E97E8370F204FA01EA2A7EBF01A4
-:1072600074D9CF4199CE4FB1297EE2BE8A18D6DFBC
-:107270007D178FFBEDBE16C88FD85D20F295455C5B
-:107280004B15F6E0EE6B791C647790E7EF832D5E8B
-:10729000B49BF93BB4EF5BC2F399D5AA3899983403
-:1072A0005CA13011439857C3CF5319F69E71AE6A53
-:1072B000B58853EDD680E254BBAB7879E774D01D26
-:1072C000A5A6F3569509CA4345C316E3B1A9F362CF
-:1072D0001AACAA36E563AC4A50BE8122F246184188
-:1072E000C09297613BA765DCA37073589B816AAE1F
-:1072F0007402DFCF2B8D58FD87263CBCC5EAFF56B4
-:10730000E8C900D64BA3670E7914CE3F91B7395721
-:10731000E06FD0AD5AF073CBEC0FBAA7313C5F9C55
-:10732000E2C44C1678F194A0E31459E7FBE7E0348B
-:10733000EBED3E39CFE00FAA9D2D27BD8C3E37BF28
-:10734000046164A36F97B6264471B58F48FE28AEDA
-:10735000C6C6BD79575C41F99BD5199A86F1C0B96B
-:107360002F8556AB987FDD09610DC9FBD1D7A99F49
-:10737000BC7608EB9C556D01B2736DF139E3BCAF7F
-:1073800088CF61B8DAEC5FCE127857B707D6E0D66F
-:107390005DF574B7C57E9D25FCCC2F696EEB394930
-:1073A00071EE7196CDCFECF458E3756A676406C64A
-:1073B000BFE5B9A7353CF73C26220586B2CFB745D5
-:1073C000B629189F9CB5AB85E7F567B80F23E7B1E1
-:1073D000393EB3FD3E46C8F32F775DDA5E37E20CE7
-:1073E00046DCE114E619BBD14F0F0ABE70B932E496
-:1073F000236FAE6491934E0FD7239D1E1EC7FF4F80
-:1074000039F9EBCAC96F3CD6F843277E63F3B12242
-:107410009C7E9FBED1E3FACFF9FA29F0C1EF4DCFA0
-:107420000768CAB1E4131B795576BA19F7C618650F
-:107430000FA43F8F57E215EBACDDAF7F235A8B785B
-:1074400019711A80FB6DFB9B53C2978A4BC8C6BD4E
-:10745000038E3764C4A7D22BF48F020AF56FC3835F
-:10746000E67D61EA3E1D7B7F6BC4791E032F677941
-:1074700044C37B56D818B4DF8779EB87AB707D0C9B
-:1074800058F0D6BC7CBDD950C9E56D43A5A2679321
-:10749000BC45ADF71695EFF5A4B32B8C2798EFAB51
-:1074A00028EB0FAFAB3C1A33C3E312F0D8FB999330
-:1074B000119E464BFCEB72E1715F05D08D72AB30D3
-:1074C0002926F9FDBAA53F47A54EE7FA33F58367AC
-:1074D00064082F1B5F328DEF29B19E5770E5675905
-:1074E000E45D51F36CF78AD8E4AB2F2E34B8F1EC9D
-:1074F000E718DBC5F9147B7BAF1287701ABA7B43A0
-:10750000F67C0C9DF8603F5FE30CD8E0B6F5BF0950
-:10751000DFA5C9F730EE195A27D6B5F58A4EF656CB
-:107520008C8189F99E6B845C2A019DEE67FAA657CF
-:107530004A8B3F84D3AFB74A797AF83D2556BABB18
-:10754000F2F3AC7C50D29FE7586FCCFBC07ECD7C71
-:10755000BF56FF797E2C7CA9F5BCEF5E2DE937F292
-:10756000C70CA5035EDB3D1683E4AFF2E11080217A
-:10757000A632D3AB18AF657384F279EDF54F1BF4E7
-:107580007B632FC16FE8E9EC5D465EED27C3439254
-:1075900040EC935BDB679C8742CFC942AE9F1F00E4
-:1075A000FF4CFCCD2A77D8E6CBE0F8EBC5798FEB22
-:1075B0009EA2894BB0ACF33ED37810E0F85EEEBCEF
-:1075C000FFA4700EA98B02EA3357300A51B6CE17CA
-:1075D00005E3B44FAE4A3D31F4C7D89C0A219F77EA
-:1075E0000E09F1F3E3A67A53593B67A923E6C43C9D
-:1075F00010089FC0FAB12074617D8CC7ECAD4AD5EC
-:10760000532588A0BCAB054A04DF1BFDE54CB1F651
-:10761000C7CC04D97C1ECBC817205787E1EF9CCC80
-:10762000FC53D6DEC5ECD03DE9F44916B743B39F11
-:10763000F3D279435F44D551248B26E894175CD468
-:107640000861F4E72A3ABB21CA3AFD26C23111BFCC
-:10765000C7E9DE85A25D71DAB7CF77F373EC454DEC
-:10766000716981699CCA2C2EDF53E778689DF87A8E
-:107670002DBFDFA23BB8305E8BE3D5F07D2F5FBE20
-:1076800002C3183D7CAFB9B9FF392109E67B23DE7F
-:107690006E85EA45A301DE6DF5D0F37C6B809E819B
-:1076A0008FFE279DE75B33715208F3472FFA1A4785
-:1076B000E2BAF17E6B90BE6F7E301CC27C22F9E490
-:1076C000EB749F444ADE6332D430BA4D486AC83FF7
-:1076D00013FE7BBDA67DFE3EBC18BE0BD8381B2515
-:1076E000C7ED381E9617929C7A649729FFC325FC34
-:1076F00046E71A883C5585F797E8D2DD55A6F75E30
-:1077000066B7E1FA3A31407C4FD1536F13F4BE169D
-:10771000FDDDA297045DE7D45C72DF64536BA27B4E
-:10772000FAE85459CD70EE6DB673EA0D591837C2A8
-:10773000439F6CBC69732A8722BD1E755ACF931B69
-:107740004F39303E5C8E7563450E9A87E27E959583
-:10775000578586E69AFA9F2DE4523EF923A26F766A
-:1077600015CF0F617FF545A6FCFF926823BFC7AF19
-:10777000859F9331F62147DE9A6CC32D8991ABAC7E
-:10778000E767668AFB504AD73828FFB57432E9505C
-:10779000286D03CAB3DA2787AB51BE1F835772F136
-:1077A000007B09836F389BAAA5316B3FFB16D7BFBF
-:1077B000807100E37E95D5EDBCBF11A1F0A910C684
-:1077C0004FAA1C642F8F84B007FB1FA93A00CF1764
-:1077D0008D02533FAC3CBCC5DAAF1DDE529FC38166
-:1077E000F10E039E1170C4A3E553FFA0B3F625CCA0
-:1077F000CD2B4E039F7D9C5146BDB1D5D509483355
-:107800002EF4B4E1BE50BFF107E8B7354BD8E13EE6
-:10781000F0A33EDF2571FC632FCAE103C8D7BB0F7D
-:1078200052BCA6646527ADEB9D59DCBE5BCBEC0179
-:10783000D589760A7B8ECE2C877280112E87D68FC3
-:10784000B4F2F76456EDD62C8C87654DDD8A7298BC
-:10785000A584BE82FCC83AE504DCC7CCD2E234FF82
-:10786000A09CDB191BABCA7270BE65B5B8D2FA6BAF
-:10787000ED594E826F5796A4605E28932DC24B69D6
-:107880000A7D6B262B7617688FE3387F2E88D2D33C
-:10789000781F5CD81042F99CB6A48AE25FBD9D12A5
-:1078A000C5BFDE927417A66A2F9BDB32EE46468F69
-:1078B000D9B9D127B0DD1239B1D6C9E0597E6B4BA9
-:1078C00005D2A71EF3FD0A70B818F7074BCE841532
-:1078D0003C1756A2249C4CBE3D8193AFF167AC1679
-:1078E000E5DD832761183FFDE5DA3BE837F9C43968
-:1078F00024197A629817E89F0270C6C437F4E9CC5D
-:1079000065DCD3359733D17FA0E722D6F6CC685C0F
-:10791000E5C39A4476814EF47305C2E3104E39787C
-:10792000AAB0DCB4CEB9057EEE690BC5FD489AF06D
-:107930006FC260F66FDD022FD4E1674CED9D416BA5
-:10794000590EFC75F130EC6EE9A7FF7E0EF9B8FA1E
-:107950006927C53DA73DED4CDCC0CACBF748B4CE86
-:10796000388E73BDFEFE7E89E67DC2E7223DF05E65
-:10797000C043E56677F796CFB172CFD332EC25B22C
-:1079800034D07D52E78CF5F4282F2F160ED2F23D1D
-:1079900027E6637F8D47DD80EBC4F21F2DB9E973C5
-:1079A000ACBC84C93156597EA0CD358C95EFD2A59B
-:1079B0002E2C5F980A2467B13C978E792D17FCDD39
-:1079C0008537ABB48E41680CEE6F7717CE65F2B891
-:1079D000547F6A26B65B7A48C2482AC3E3C00B4587
-:1079E0000CAEE5DF91687D5C76309BDFBD22E877E9
-:1079F0008EA17203FBBE92E189FA7009C46722BFAF
-:107A0000961FD8E632AF73EFB65652EA87515EFE44
-:107A10001D360E6BB7E27B5218515C81F90EB85ED1
-:107A2000FEC8DBB04F45FCDA5C153EC46B9D0BEB2A
-:107A30002DD1173CE30D217C7B5C33D9F7A5BBF638
-:107A4000B8165721DDE0765C57971DFC0CBFB3C01C
-:107A500080AB53267F6165AE672FDD6BAADAEE47F8
-:107A6000E9830B2C702D157A83F97D2EF379B76796
-:107A7000B273494E971D942DE318FC8F9D067E1E10
-:107A8000ED273E3A8F66F0CF58AF0CFEAD342EFA9C
-:107A9000537A26A583670BF283C11367FE0D3E1F41
-:107AA0006E0DD2F3D1D610F1693BD2710CCF4BC120
-:107AB000F76CDED6E23D687E0D2F0403C8ABD76AB3
-:107AC000310F332FC2CB85B746A5D025EC74E3B96F
-:107AD000DD195D8046CE94EC6FCF50983FB6DD1532
-:107AE000BD1B43D60165EF8CE96CCD6BCA8E4CCAC9
-:107AF00036EDFBAD15F7275D931D22FCD716B9882F
-:107B0000DEDB6F9BB44FC49F689DDC7EDBE22730D9
-:107B10003ECEDA7F3E1BFD0BB1FF97A97DE1FC1A3B
-:107B20004BFBC2F98D46FB99D4DE73E9F6DBE75FC8
-:107B3000671D7FFE52A3FD4D04BF7A69F80B6F9F4E
-:107B4000621DFFF6266ADFECE6FCEDC9F550BE7556
-:107B5000BB379C407D4C17A94DC07CF28ABD58CFE5
-:107B6000587798E6D7307F5B3D945BBD01CC72348B
-:107B7000753EC28179596639CAA9C9B2CCAB5C2DB0
-:107B8000CF521E5237CC52BF205266F93EB4E16A42
-:107B90009B5CAA747E91CA08141AE60C4ED7301763
-:107BA000E9A3DA61DC0EBEF7B897CAF75EC7F1BB8E
-:107BB00077984AF3186146BFFC5E57F41AF3BDADDF
-:107BC0000C2F093773EE54A3F7211EA9F72107BE26
-:107BD000CF12F94E596E207DB7AE74D2BE98899EF1
-:107BE0001DC3993CB0727BB68BD35DF061DDF0C5EF
-:107BF00041B3BDBE76B8AB01FD0D7C7F878AE345FE
-:107C0000D6E278CDAE9E0AB43BECE3B8CB6A2CE367
-:107C1000784634D238DBB2793CD518C73DA2D1368C
-:107C20008EA761AF782FC67904E52CD338EBCAAEA6
-:107C3000B3E23362298DB3DB36CEBA114B6DE36408
-:107C4000717CD87B318E7EA971DCA3A658F119D93D
-:107C500044E3FC931D9F914DB671541A07DFE3383E
-:107C6000CCF00DE17D592E77CF62E2FF4FBD64E786
-:107C7000B8DCD127C9CEF9B597EC1C564BC37A5066
-:107C8000C9FDDB7BB2F3F8BD5F598CFFAA99CF31F8
-:107C900091771023BFF84E0122E80C22A6DF560888
-:107CA000195C7468F688367C1E9D165C80FEE8A31D
-:107CB0003E8AE3BD7F749AEB8E34FAE8CEB8F35C6B
-:107CC000D224CF7D7A55C46383D97C1FD2289F13D9
-:107CD000F19F33182762CFB79C40FED059112F4A2D
-:107CE000C1DB46EDCE897DBD73BBF83A7571DB69AA
-:107CF00027BF37155EA96270CF1368DC19B7DE9312
-:107D0000D92CF8D1F323373F07045A31DD8FD73907
-:107D1000C4122FFCCDF17F7881E7DD4131DEF7FB26
-:107D2000D58EA79EC76AAF4A0B86AF64F8361CD9BA
-:107D3000E62C66E5F79DC9F961D5D44F8393CEDF74
-:107D40001B7EC82D51A7C57EFE5AA3B57C9BCD9E38
-:107D50007E23BBCCD89FE5E3867427F26B1EEEB181
-:107D60003216DE864F4ABE0B10BFE607785B039ED5
-:107D7000E6FB9D90A0F52E594071CE5801C569A231
-:107D8000C6BA65836FBED3A345183FE7DF27131D2F
-:107D9000EDF0268F676B0EE6E7243BFF9713CFF1DC
-:107DA0000C04FFEDABACDF21E6B4DC4760C8C15783
-:107DB0001A6AF79D35C9C72DD159FBCE5AE834DB75
-:107DC00052BEADE5164BFDDB572DB07C5F10BBCB33
-:107DD000F2FD8E8EBB2DE53BE3F759EA2FE96CB33C
-:107DE0007CBF4B5F6FF9BEECE0364B7979D70E4B19
-:107DF000FDE6A37B2CDF1DC7AFFA12F981BF94E922
-:107E0000BCF31FD5735BD07EFB6340A1FD9CB7C55F
-:107E1000FEDDBBE23EA015287B9371FE8CF7A0DF50
-:107E2000D09CC5E633B325C6A9056B3BA6A01E01B1
-:107E3000BA5AA35A2D5E1B63CEEE64713E51EE74A6
-:107E40004162086EAFA4E2B03D72EABB9264DFC744
-:107E500067FE2E772A69BF2B49256DBF17A49E0A9E
-:107E6000B41F63AFBBD39E034FCD4B28864BDC2F93
-:107E700079DE018D66FF6D9ECAE3432F644F9DA797
-:107E800016D071699AEF4D878BA6A2DFD0E44A54D1
-:107E9000A4DBB7E91BAF4BA27B03E7A97CBEDCA543
-:107EA000175BE269CB0E8EB2CCFBD7B2A237ABAC7C
-:107EB000DEF91332E959483C37E2CB63717C6D1E21
-:107EC000BE87A305B43EBEDAAAED3BCBFC80D75AF1
-:107ED000EBE8F9ABD6C8BEB3CC257CA3B581CABF4D
-:107EE0006D8DD233D9DA48CF33AD2DF4FD6CEB2A4A
-:107EF0002A9F6B8DD1F3EDD60E7ABEDB1AA7EFE782
-:107F00005B3BA9FC7EAB4E4F631E18F62E44843DAE
-:107F1000D9F78309BCDC2B70900B8D386698EE95F1
-:107F2000EA552F56A01DDDFB9A9BF26E33D1C92E68
-:107F30007799F9A7D17ABF58B7C6998DA7378BF330
-:107F4000C7EB803ACC91583FDA4571B4AC9F7E863E
-:107F5000EC71F65E017ECF7278769AFB3ED1FF46D9
-:107F60007E0DC427A3FEB96FFFDBA48555C89F32E1
-:107F70007EEFD773720BE7DBBEF097C70E4C3FB2B4
-:107F8000F98AFAD351FAE96F46607CEABD02839E12
-:107F9000DD2330B8A5A8911D2887BD47DC8457EFA5
-:107FA000B16C9E8F8241B541E4BF2E3BE8D5CDFA3E
-:107FB000617957AE6ED51745BA595FF49EDAE7C7B7
-:107FC00079BF3228EB67C7A37C68423EB8DC19FD55
-:107FD0002FEF2AD5554B3FD6726F5CAAA37B202189
-:107FE0009433F712F7A7AE0CBA689C770F8EA2FCF9
-:107FF00003E627EA6779BC53E7E30675B35C36AD61
-:10800000CAD6CF0E49C197A9DFBF367C0047E077BB
-:108010009ECCE771077A82F2AF2EBAE7ED98F32291
-:10802000AE3B6EF6BF8F295F48A1B2D16F73971C2C
-:1080300073E3795E3864198FB50B193EBAF9FE9C6B
-:10804000FE7CB7E683FF166589D66D7EBE3C8AE767
-:10805000CB597F1714B543BA2675BEBC59C8E57213
-:108060004FD21565AFDE3B32EA92F920EFB69E0A99
-:1080700028A3318F20EE4267A4B1EBAAE9A81FDF45
-:108080003BB2BA10E369CBE4DE7BD39D9BFD50E5A8
-:108090007136D09D3D49133E467C0680F5EB49C1C3
-:1080A0008F927ECE54B6EB6BE3E9F0F1B8FB8A43D6
-:1080B000A7677E8EC1BFE2E8072E84E3A81A75F891
-:1080C0004CF84BE27CFDD2836FBA10BFB79DB18AEA
-:1080D000FB2FA1A7FAC3A9062DFBA131E8C679BCE5
-:1080E00090FFF602CAD3577ECDA6E63BBF7002FED4
-:1080F0009E83B15F619C7B5804113FD26BE1916517
-:10810000141F7EE7992F0A7B2E3E09E5E33D70D4CC
-:10811000217EEFC1CBFEF126FA95FBB81F031DDCD3
-:108120008E31CE05327BD662D72CE9B49617C39C2C
-:1081300042D41B8B1F75822EE1FD9FA67B9818DE13
-:10814000F93E6EEF2E8196B568CF296EEE1F2C0C8E
-:108150008052CCF4E9F21F3E3609EDFECFF8F8BEAE
-:10816000A311C7B82B8FDB7B4BF37517EE27FCEE03
-:10817000C8F8799F43E973EB6B715D869CF4FB7FD4
-:10818000777458E11B087E3BBCC6B9F77EF1140139
-:10819000877C504A9B9F36D927E44EE891877C56CE
-:1081A0003B7F9DAD5CEF1371561964E4F37B014F87
-:1081B000CC9143DFE99C6DECB03BBC3A84F76A4557
-:1081C00022285FCC2E1807A67ABF57A3F4FEBCF472
-:1081D000D2623A67AE24C6513E9E07284FD125E4AD
-:1081E00041CEF28F836B304EDA424EFD6AAF7F2F65
-:1081F00096D7FAF839A8669CA7ACBFCDFE99A730F0
-:10820000AEEF8178422BC5FD6F6BFCDB1BB296B3E2
-:10821000713EA13EC117C88F3050BC28BBD25ACF87
-:1082200017B69697F6D129219BCF7DF83D6A027F3C
-:10823000AF026A94F366BB798587C30F78AF2AAB28
-:108240007F8FB0E757402846798B412E07F7CCE265
-:108250007913F7F842E118FB2E291A9D8F58874DA4
-:108260004DEB58F38712E826BDDEACF4B8502E9BD8
-:108270003F54E8FD6E35FA20D2D5051AD9B91E460D
-:1082800034DCBF56D43A8BDD0B25E27E405BFEC268
-:10829000265FC0E2EF197AC129F422D317EB7C05DF
-:1082A000A8077B66F27DF5A48BEFEFF07AAE54BDA4
-:1082B0004D0847A67ADE54BD6DE9EA2DFFE1779FB0
-:1082C00089B1F9BEF4FBDFF4E366DA3B4ABC10F394
-:1082D0001F9A0EACF1A31CBFADC4FC88F73B7AFA21
-:1082E000BCF79F097D87F94E785E7E85E0D3BBFFA2
-:1082F000B8F126A4FBC5034E3A6FDF7CD09D7033E6
-:1083000026AE38721797A783EE3779791DFDFE48A0
-:10831000F351EB7C5BFAE4370B43B4B9172B16F738
-:10832000B393FDBC62FFEF67A23DD20C3DA427ECE6
-:10833000ED70FC0FF368FD5A80E7FEEDDF8D7CAB3E
-:108340006621F7CD4736525E55F391599447D56C67
-:108350009BE78DC20F39EAB3FE6E83410FD0B95D42
-:10836000BCFA3BDF1AF72683E7FCFE5FF8254BFCDF
-:1083700088EB89DEAE3B1E7F369459BFBF2FFCFAD7
-:10838000543B9DDFFF7D94DBF1708C3F9B9C093F4C
-:10839000FA4D4D7B9C61A641A0E9BBFB9EF836CA15
-:1083A000F7EB6E8A372CFBEEF3AF5EC7CACB9E723B
-:1083B000E6D7733454CC0336F88267DC315FD7E0FC
-:1083C000C3D21F3CEF0A8DE5EF1FC84BF163D953B1
-:1083D000275C30B63FFDA6759D70F1F3E736BE749D
-:1083E000BD3913EDEED5DFF9930BE7D73BC7251861
-:1083F0005ADABF7DE39EE7C9AE433A111F059FFAE3
-:10840000F8D68F5F899B9E9D40F502B88E0DC4AF54
-:108410006FA3CC14905C7FEF59DC2FF8953B8C74E4
-:1084200068FCDED7FD88CF5B4A0B97EFC7D614E216
-:108430003E7AA3335618A0277FDFB8FB1B24774B67
-:108440004E7FA390E7416945FCF78C62451407DC39
-:108450007533E1B918A2247F8D8FC99487FE470533
-:10846000EA9E4A333F6EF0733DF6D65E375D7EF787
-:10847000162A5CF4175F96757EDE96E7257EC3D8D4
-:10848000F7C0FB1B59F98F1ECEAF02BFC3B8D7CAC6
-:108490006391DBFDEBBA914FEF0ED78662BC92D1B0
-:1084A0002126E826A11E924FCF18CAF90421659211
-:1084B00068C7F4E4347C8FF5BB9D9A779CA59D58E2
-:1084C000D7F8F8F788F119DC59689FBD55C8EC9DBD
-:1084D00034F82DF31BF39FD91F263933CD733EEFAC
-:1084E000F7AFE7F3DC98F7FAEC3AFCFEAFAFF079C0
-:1084F00084ED709D67702586D2F7137325D20B6EBD
-:1085000048A49BDFFB9D627E5BBF33AF9CEC5B436B
-:108510004E18FC0AAE5B2979E1FBBC8C0F64BF2DC1
-:108520007E94B537DBE7382ED573A5DE9BD6FB25C9
-:10853000421F5CE7B7FD8ECBAE8241DDFBD3E4D4B6
-:108540009FF836CE5F365F71FD69FAAE93F244FE56
-:1085500070E8B957BFCAE4FC0F5DC6BCB5EA53FB6F
-:10856000BC6D3C3C11D2CDDB3FA861483B6FD9FBD1
-:10857000B4F3564D923CFF47E953837E0BFDD63C46
-:1085800027433F66A2A35D3FFEC517227ADAF52393
-:10859000FB7B0526F5974343FE0CB95BFA4FCBE90D
-:1085A0007742FAE4D390BF3EF934E4CF8EAF957EA4
-:1085B000F6EF9F4143C58817B3A7F32188F9309E92
-:1085C000FA1399E2A917184C6B199F2F1C2AA5734F
-:1085D000C46BBCDC3FBF10E8F1E755D13D3854EE29
-:1085E0002970AD457D61BCEFF1F2F8F785488FDF6A
-:1085F0009C07F2E631D98FFB5D491DEAD2F9234C85
-:1086000023131C49C8F49DC78B2FA0FD87E3658DFC
-:10861000D0916F336475C42AF4F3E3FCBCFCA2B6BA
-:10862000AFF8711FFEC2B1515B517FDDF9A20CE2C0
-:10863000F71315CC37B943F0FF6D886D9FC2F0BCBE
-:10864000E318F72B166D4A2F2F4B45FDC5EA3D2E3B
-:10865000D44BCC2F38638E872F15BF4BD6B8CBF6B3
-:10866000FED81749AE96DAE42A2AFCC6EF1A7275CC
-:108670002D5C2BFC3687399F6D865CB515ED920B12
-:10868000A7781CB2F7984CFCE83D24F1FC278C0736
-:108690004F4679E87199F3D8CEA3FCA5B9DFA0EFD6
-:1086A000FBD3BF99743FABD2F4CCAFC7ED64CFF32B
-:1086B000CFBC5EF1632CFFF09F47FC1AFAD79F7680
-:1086C000FCCFB49F7DE1B89BE0B870FC6723EEC798
-:1086D000F2B36EBAAFE6C2436E9EFF79DC47F7D6BF
-:1086E0005E18CEF38556FFE44FE3E8BE3EBCC99D5D
-:1086F000F1ED353FF7C77A8FFDDB6F317FB8F79823
-:108700003B8478341FCFA6FDADE667BD14A7B9F052
-:10871000933F4D32E7335D293E2BC47D88177CD0D3
-:108720008079CA1772F9BE41F38F27EFC37344CB28
-:108730008F9C70E17ECCB49FFEFB38D43B170E7348
-:108740007BE27D677237EEB3FECE7FFB3A27C677BA
-:1087500071BD1E06D09AA3DF88F7E1F4A70BA7C36B
-:10876000054607C48BD1A511F565267AFCEFBF5BE2
-:108770007A7C301FC76F3AF6599A3729BA481A7F60
-:10878000EFD3F16813C39FBF3FFEA771681FFDA120
-:10879000AB8DD6F981F02ECAF97F0D6F293118BC47
-:1087A0006BFE6EF1E6F27FDC1FE2797FB679D05F77
-:1087B000CE7F782F95BFE70B13BC839CFF0D7FB74F
-:1087C000F87F42BE1F667CF70FCCF7FF92C3F78598
-:1087D000FFFEF01E88EF2F0ABEFB02988770E1278C
-:1087E000FF4EF17503FF81F0DEFE7F29DE863DB48A
-:1087F000C1118E9795621E76A23BC4E05C53392767
-:108800008E612959E45DDBE17A2187FB17B2C4E36D
-:1088100036309CC78F40F81B7DBF03A9F2F3558A01
-:10882000BA96DF47A684E97EBD0D572F0C536E071D
-:1088300054BF16C572C914FA7D5BBBDFD52E8126E5
-:1088400031FB4FB9FA0BA7D0FE77563A12EE71F40E
-:108850007C139FEB44DCCB197059FC0DD5E62778CF
-:1088600043D6EF6ED19F07AAE3F8FBDD1E5509E85A
-:108870006C7CB5364EF8606E67DCB46F88BF8F9D38
-:1088800030F9637BF107024DF6E4E5D2EF4F39DCB6
-:10889000FF94A5EA6ECC8B85AB1CFC7E73E0E78A67
-:1088A00037948475BA8F59F897297AAEED463A2AEB
-:1088B000C0FC438E1FF99520FC494574A1543A34FD
-:1088C000AFB59EF09706E40FE7C78826C19F9516BF
-:1088D0007E18F44FC3170B3F0CFA5E2E5FECFCB012
-:1088E000D3FDE7393C3E67E793251FA480FB2509AC
-:1088F0006620FFECD03E8A8BBCF78F6FDE84F59745
-:10890000FD5806FCDDC4F70FF92081F357D15DE86F
-:10891000672D3D22535CF8FF002820961900800047
-:10892000000000001F8B080000000000000BED7D20
-:108930007B7C54D5B5F03E73CE4C6692C964F29AF6
-:10894000CCE4C524811834E0244040419D104010FF
-:10895000EE754011B451470810CC13A4BDB4D51F17
-:1089600003C1343C6C43E5A5453A202AAD5803A623
-:108970005E50D4411E62AB6DB4DC5BB46883A280F0
-:10898000F24869F5C3FB79CBB7D6DA7B67CE994C51
-:1089900040FBF577BF7FBEFC73B2CFD967EFB5D789
-:1089A0007BADBDCE9E4B97E0EF26C62E892B632D67
-:1089B0008C653256F77C3263198CDDBF2B213CA5C8
-:1089C00000AE2F7E3C940D61ECDCB29E4339703FCB
-:1089D000F44BC5F714760F750FBD0DEEDFAFB17B0D
-:1089E00003A5D171E435CD69626C046367F624CDCB
-:1089F0000CDB1953B6EFBB87C6ED98614E50A2FD54
-:108A00006C4E33CD0BFDFCF83CF40B253C48E93BA8
-:108A10001E634BF978BF50387CBBCD611BC2B77D5C
-:108A20008B250870346DFF8BC50F70543DFF9CA3E0
-:108A30001BE66BDAADB24809A3BF4B0C9FAB918428
-:108A4000A1743D8E57C6FC76A582B146FCD70BD7E4
-:108A5000CE8629CC01D78E557F511DF8BEF9A36E65
-:108A60006BF4FDBAE75F793104A8A97BE119871798
-:108A7000AE9F753DE560A534DE7D9614C634BB66B9
-:108A8000E88FE35E4CEB3B0ECCCB980BEEF35BAC8C
-:108A9000A963059FAFF35F4E32848FC138126E58C1
-:108AA000DF67F88F87B151CEE48C4FAF81FF47B2BB
-:108AB000919754B86E4F67ECBABE788AE22BC4E93E
-:108AC000F9DC179B43809F33BB3EDF8CF0D7FFFD63
-:108AD000AF9B7F08F863AFDA9C4FC1BA9B7EF91F4A
-:108AE0000EA4AF7C6F9A53A1F7CEE5B19007FA9D23
-:108AF0007B2F211C825BE75E3999EF85F59EDBF9C0
-:108B000095CB0BFD17BD323E0BD7BFE8D75559CCDF
-:108B1000DE3F1CE79630164ED0C315263A7A77C34F
-:108B2000A059D0DC2BAE31F4D8DFB93F1FE13C7B3C
-:108B300034C1978078827B8BCB913E40A7A1BCFD4E
-:108B400020E0B771C78FFEA20E8D87E7508EC98DCA
-:108B500074FD7802C2C9582487B911BF3DAD4E7B60
-:108B6000DFFEBDF43A02F4BCF61BD06DC70A3E6FBF
-:108B700007D0CDD1976E67F11FA04F13D22D294A90
-:108B8000B72F58F0E79E226877A6135DE3E12BF23A
-:108B90000DF055ABF0F16F70FA7FE044F9D995D440
-:108BA0004BAF2948AFE7BEC86740EF53E69E7BD87E
-:108BB00070C67A5E49706E85FBF7BFF24792937379
-:108BC000BF7EC78274843FBB02EB3AC77AFFBA709C
-:108BD0009D8D8A58E7B6E44882238AF7C6F0D48987
-:108BE0005E07DD3F4EF7C39C7F117F39489FF0BE83
-:108BF000DB9538F4E87016D23A583893D6DDB0EDEC
-:108C00004F16E41B4927A48F320AE9757C02DE97D0
-:108C10007492EB8E1DCF897818A9A3DB362E877D41
-:108C2000E9DA636145F1E805F0E27B082FB4CF6D26
-:108C300049D094147E3F17D671CECC6676201C6145
-:108C4000E58FF1E8CBD8325ACFB3B17229D6772568
-:108C5000B9BC12DCFF285E9E703A697C899F335F45
-:108C6000C7D7CF8750CE01FEDDF6E041E41FC6AC8A
-:108C7000E11330CEBD4C61294551BC4978CF688C99
-:108C8000F4EE995FAAE110ACBFB5633FE9D958F99A
-:108C90008675F93BE2CCF747315FE3EE7D43510F38
-:108CA0009D797D0FF15FE38EE396108C7368FB0B6B
-:108CB00096EED228BFA3FE0EEBF4F7995FED1B4AA8
-:108CC000FA16C78FA36F4E88F19BF61AC76FDAF1B9
-:108CD00017C3F875A10E8BD37EE5793ED3FC3370B4
-:108CE000BD9F759919EABFCF3AD489E138F3BE29FF
-:108CF000EC97C453EB3B16B263C3DF4D0C27009EC9
-:108D000016BD33F14F291978B57801B5AC7329E751
-:108D1000ABCE87FC394897CE77EE52D19EBC88788F
-:108D2000BC2A3A6EC591E6AA6490DB8A6381E1C8E9
-:108D300056B1FA60E45193016E98270BF5F372185F
-:108D4000C70BE330CDE70EC0B8AA63C244844775B1
-:108D50009A9CB6B876958F67B6075810E03283DDD7
-:108D6000F6EAF8C93DCD3194A5E0F23C26D40B0BD0
-:108D700081BD503FBB2DAC4403F89829D1F7148C2A
-:108D8000BB70B0BFEC20B417CE71FB42F0DC731B9C
-:108D90007FEFACD31E325D8BEDFC30CA51D24595CE
-:108DA0007941F59D51DE9ACB40252409BECAE94898
-:108DB000223B93A4793754433BA956F30146D92764
-:108DC000F6605E6A26BE67A1F73CA98AF629AEDB8B
-:108DD000C11C286F727CD94F8ECBB4C8505C3FB396
-:108DE000328D815DC9651C6E55ACA7887529C8DFB9
-:108DF0002D531D5BB1BD29B996EC7F3EEBD9E7073A
-:108E0000BA3DE9987018F518FC6BC27E79CD46FB27
-:108E10003E60B1B15D10D262E4D76B0A00FF15B5B8
-:108E200019EF6754552E18E063EC9ED4CE891AE8EA
-:108E3000EF8C19953B7300A79357BECBDBCF5496AD
-:108E400079A0FD1F6B1A2669A047327E5F59960FE5
-:108E5000ED0B69DF9F44CFEB0049D783EA5F3374A2
-:108E600052A8342AB79900668A4AF27C23E2E16C60
-:108E7000E04C2B3E6D98FEA5051EE15F00F190379A
-:108E80008AE321D77E6C2783FE034CDD4B912F7F35
-:108E9000FECAFF4AC57E5EE6A4F53AD972E7A75638
-:108EA0005C3C1B7569D8E5F499C63E957CA846E5FF
-:108EB00020C515BC3515F8AA7556C98609A86BEBEF
-:108EC0007DC45F30B393ECA1ECEFCC20FAD408FA68
-:108ED000209C56E0B339BC0BAB65ED420F8D73E2BD
-:108EE0003C4AA85EBD74CDB7876796E49B64968CB8
-:108EF000F7B57A2FC1D595E99F83F8FA2A334857F9
-:108F000079DF3D6BA63708F8BD3135300FD7E199D1
-:108F10007B311FE19F92CA68BCAA79763FDAD50BF4
-:108F20007B41FDC5912B79DDBA84F9B441FD3F9FAA
-:108F30009616FC2E8E5FF89A77D76118EFDA1A8BA7
-:108F4000CF06535CBB78B84F4B677C41E87708BAD3
-:108F5000B991962877DF636194BBF3098ADF0FED3F
-:108F6000F30F38492FE7D64C398CF6EC7C52414749
-:108F700004EFFFD04BF2081E8082F290B7372562D3
-:108F800073103F7F19C3CF5F1AF9D738EFF94BDE63
-:108F9000DDDD349E538C070E113CCF13743AAF7253
-:108FA000BFFCFC122FC101EEE33EB4B7DF74BEB5C7
-:108FB000A9C24F12F479C8E65F87F400FC6FD0E3D2
-:108FC000FF67FDD37133F6033AD235968E73ADCD7C
-:108FD000F9A817EE0F744C008DCD4ECEFD5E053214
-:108FE000F7D4D4E036EC5F3FB3EB9099A0692E46FE
-:108FF000B9ED4B6785F4B96BEF7D4BCDD06E423A3E
-:1090000079FBD2F3DAC56544371D7D3B70FC6BF705
-:10901000FEC584F04BBA6E50B81D887DFFE55445FF
-:10902000CC5BBFD40CF8BCB0DB42FE6F6CBF83A935
-:109030005EEA27DB43AD153E0DE434CBC482F1C6B6
-:109040003DD8675CAB2F210EFCBDE339F97880FF7A
-:1090500037F4F8FF6DFFF8FF9DC0FFEFBE25FE8FD0
-:10906000209DFBC3BFF4BBEB847EA863ABC9DFFCD0
-:10907000C43FCD3510E69FA0DA491EE63FA5921CFD
-:1090800042FF291E57549FCCBFAE791FAE77FE1307
-:109090000AF16D4D90EBF9CFE74E3984FA7D4EBB66
-:1090A000D17F9A3B33644138E76D34DE9F1F8E8950
-:1090B00007994EAF035F9C89F2EF00AE77DC642F17
-:1090C00055211F55F34A53D05F7AD5ECFD3DF9E3A6
-:1090D0006FAA6C6B1CFCE7A715903D96EDBC664033
-:1090E00092CECEB31A9B09F5A51C77DCBCD22CF42A
-:1090F0006B16267B2F1B870D586CB4EB05A144E63D
-:10910000D58D5BD49666680F6ACF36F4BF6A63A1CB
-:10911000E1F9E0F0D586E7D76C2F37B487745C6F40
-:10912000E87FEDEEB1867659E41643FF6187A71913
-:10913000DA23BAEE32F41F797496E1F975DDF71B84
-:109140009E8F3EB5D0D0BEA1E707463FC6C4484F6C
-:10915000B24485F4E68125A72A4E20C30D57C621C7
-:109160003EAB46F1BE0716584C4E075E8B4D4EE0A7
-:109170008FD7E74C213FE0C00297DF4BD70A3FC6AD
-:109180003F4C1D333C18C7CF1DEF3C5D7142376F1C
-:1091900095D56CD073E39DC6F6B034113F0CE07CDE
-:1091A000332ACD285F6AF39488059AD9F30766E1DC
-:1091B0007C2067A3D3B89CD1F58A72E668AEC0362E
-:1091C000C859655A1C3963C2DE560A7E82ABDF522B
-:1091D0008E8C954C76D98F37BD743FA441BC32D666
-:1091E000EACB3D88EB32F9329009C7CD0C1CE0E3A5
-:1091F00009FBCC4A4CDFC63E4B39779BBC21B26B96
-:10920000698CF24B8FCD294E613AFCDE956612FADD
-:10921000A09DC791CEEDC33489C742FDFD8923B41B
-:1092200092E87D65DE942C943B773F7AD1E22E1A4A
-:10923000BC0DF4B1C553405779BF75A66962380EAD
-:109240007D1BD2789C21FDAEC151BFAB01F17BD615
-:10925000FDEEFA4180AFC6EA1EF2BBDCA6F605873A
-:10926000705DBF5179DE0C3C2BD40B73841F3D67BE
-:10927000D24F171C02FD34E7ED41A49FE43C9B96BE
-:109280004406EBFD86DC7EE2AAED029ECD4BFC831C
-:109290006B06115CA41FA49F9E1F6A9880F1CE00EC
-:1092A000D64C71E37A13AB8D37CE0A314E16921C31
-:1092B000E175DA494ECECE3DE6D0601D89C9C115B3
-:1092C000C86FB3AEEDAAE0FE98DF370DF8273F7206
-:1092D000F77AEC9FEFD65858E93B7F5675B0AD0052
-:1092E000D6B73CCDE4B353BB47C1FE090F32960E4F
-:1092F000FD97FF5D257896BF7E1DC3782DC1DECC1E
-:10930000D0AF95EBDA9FF638E147ED4C223BC8D061
-:109310002505FC7D57D0FE0B774D17FA1D5FAC3548
-:10932000D37C5FC01A9D30FE179D6A189DF7436974
-:10933000891113B4D5B664B2DFF9E88342FFB99D51
-:10934000C9616F41142FDAC6312C02F62E2197AF76
-:109350007F799A3D6C2FA075AFC1754B38E5BAF394
-:10936000FA89432369DCCE327F8981CE1E88C9BA4F
-:10937000706E0D9C7F18475D6BA638714EAA9DE0FC
-:109380000C2F090DAE31F75D5FAB7BDAAD77023C98
-:109390002D4754A6C238DEEE76C2C75CC047D8DB84
-:1093A00017DF67BD055F9A54823B82FCA86E9C4024
-:1093B000EB62E8D7C37B0D3F57D8E305C897C18957
-:1093C00044E76C137BAAA0EF3ADE48E3F9DBC369FC
-:1093D0004EBA5ADCC55C4EDC03076F83F1DE423DBA
-:1093E0006565F1FC80DFA7717F9AAEB1FA09EC6088
-:1093F00008E1B8B051217A9E54C21633A0ACEEF603
-:1094000066F207A47E52FD2AF91F524F49B8408FD9
-:10941000BD9FA6B38F6ACA834371DCFEFDB59DFB79
-:109420002CE8AF3919F96B528FF6E7AFA19F86FC94
-:1094300027FDB45331EB84F57D2ED6F779BCF5F5D5
-:10944000D1BF77354B3FE72F6997F133332DF1F5D6
-:10945000D355E99C0E4D4E0BA3FC14C6CBE83FCC74
-:109460003785B7621E4A0BDBA6EAF0939D2EFD3CC2
-:10947000EE6FF4A7F7AE149714AE2A25FD7BA1CBAF
-:109480009B9206D78C8F95E678E3A88B9F1D8674F8
-:109490009A6FAB4C4A07389DE9467C3DB6A28FFDDA
-:1094A0004A4FE7F8A36B1FFCD9017F26839FF86220
-:1094B000B197F0E749BF8C9F78F6B60F2BD02E9D61
-:1094C00013786AEC8D7BB99ECE06638579AD06E68E
-:1094D0007FF244096F5F5268D783F2759BED81413B
-:1094E000387ED3EE494FEAEDF7D7693C9FC6EC6969
-:1094F000946F95E3B984DE8738FBC64FBCA4FFBFE9
-:1095000044FA46E3EDEE0A8CB75A7E7D550AFA67B7
-:10951000E35EBCD389D70B190309AF675F4CF02317
-:109520009C67D3401FDBB13DF210E6213E5F7238ED
-:109530004D4F97B3BF7AA7C20CE39CDDF54E8586ED
-:10954000F90C91AFE9B54797FE501180F743635985
-:1095500049B35DC727566E2FD6DA78BE23D3656927
-:1095600065D7423C92994AEFAF73997E8CF755EBE1
-:109570001FF24FA09CC5E477D69ABD2D76E03388C4
-:10958000E57CB84FB070B0DF3307F33B53DD949701
-:109590006951B81E0DCDE1716846212B2980F1CCAF
-:1095A0002655C5F77A3CCCB715BA241C688FA0DACB
-:1095B0004BECEAF023F8C313D3089FA3CF38158CE4
-:1095C00027643E48ABE2E3F54CB784B7EAF240EEDD
-:1095D000991AD9C524AD83A19EBE2F338DE097F98A
-:1095E000A0AA6933039508D7C3268A6740F12AA841
-:1095F0000F73C43A0A3CBB5648DF4673215B324CBA
-:10960000FEB055C0FF0301CF0EAFC98FF957476EAB
-:10961000E4A819FCBB9CE58C7DA4F323932C42DECB
-:10962000DE5649DE92BFBEC93A13FCA3A4449E573E
-:1096300075045A17605E1CEF7FA71CE9C2DF27FA8A
-:10964000A898A662A11400397994715C49BFCE250F
-:1096500056DF4060E85D4B9C747D7A899BE0FAE9B7
-:10966000122F5D7FB2A484EEF727A757BA3EB2044B
-:10967000E6D5F153C648C00AAC37436524CF8F8C7A
-:10968000A8489915C71F90D7C7971C768D1B241023
-:1096900008F4C8AE776E59594074462182D5BDBDD5
-:1096A000C23F86B187CDFE050C586B4DFAD7E3302B
-:1096B0006FB54A31519EEAA7E96FAC08E5E2D54B98
-:1096C000744FDAFF1EC37CA76778BB82F2EEA96FE6
-:1096D000273E18DED5C582E2BE1FDA9E23FCFEC3FC
-:1096E000368EE7D58C4D4478ED0A0BE0F59C8DFB6A
-:1096F000839FDAB87E3C2DAE43D2839B518EFFE62A
-:109700003C5AFC3080672B7D3F1FF73B92F67F452C
-:10971000F96075A8C58AF2E1D97B9CF6415453B72C
-:109720008581497EEDD13F537E4DB5040A78FBD744
-:109730002BB19DE9086C41978D85FE3CE9801BE4C7
-:1097400006F9E17AC24608E578954DB443C7080F9B
-:10975000ABCCBCFDDAA37FA275AF3207E6235EB0C7
-:10976000BD1CC65B95DAE13641DBBEF4BD15876FE3
-:10977000C0B6ECFFDE8A10BCFF52BAD437010FEA44
-:109780008FDEB613DA43746D8DB799955FE5FA1ADB
-:10979000F67F752807F8B571AFD281A079F6AE5182
-:1097A000709D9EDD6B08DFF407F281CBA03CA935EC
-:1097B00064C1F79F5E72D8B91CE8ACA5B5B910EFCB
-:1097C00057B9837E7FBCFC44A6F47FA1BF3ECF1671
-:1097D00036F774EBFC710FE372C396837E88E35F08
-:1097E0000CCDAC3C9D01E3AC55822B55D433CF99C5
-:1097F0009DA8475817D74367C4582C9C4DFE4DBDB4
-:109800008D37CDCB822B07A39EB85BF361FC5C57F1
-:10981000D05E89F6BD6E4F816F298BF24B5D6A87F2
-:10982000AB1CF927D5D86E117997ACD4E6D4D452B5
-:10983000DC8F58938FFB058DACFD9E1F20BC6FA95C
-:109840000CFDF4D3FBAE4B190DED0668A3DFD0D0B1
-:10985000F98E05F9F3D10CAE3F1B3B817F609CD59F
-:10986000205F7E7064B668CE44D44F4FFB9BAF46FA
-:1098700017EFEB47FF6B920DE8FB4CA1DF89F47605
-:109880006798575AC1697CC6E21CCCCAB06D27FEE6
-:10989000AA2B33713962F6DFF835B1FF09EDE38F9A
-:1098A0004EBA459FDFF5E0BE0CE0B969933D644ACE
-:1098B000217BF3BFD1DE366E3485507F99AC5D16C7
-:1098C000A4AF1BF776893E4EC2DB22A9CF63F4F525
-:1098D000A24969B7607BD1C385CED065F297B51731
-:1098E000935858E71F3D9AC1E5B8560BD13E4AED53
-:1098F00045073DFFE7CD6763E161979BCF4ECFE51D
-:109900007CF5D1F988AEFBCB7FB37E20D06DD14EF4
-:10991000B32941C7778B768AFD6A9B3F0BC7C9B4D1
-:10992000308177F0F701BF5A416F3BA4819C3FD251
-:109930002BE703568E1B83748B3E67A30C7AC08F74
-:10994000F1E62389520F5C15BF7F624CFF42D9F6C6
-:10995000AD1C97DB179ECCC468DB0AFDB5FF4EE853
-:109960006D237C6B4C31E3A5C9F947D17892AF8E5A
-:10997000A757FE2634109EA7B65762FD46CF1CE6B9
-:1099800045BB8CFCEAD3E9FDE3E95CAE6B2F16190D
-:10999000E81DC57BB1E1FEC9256EC3BEDFBCEA454B
-:1099A000B43F791CF53C8EC3421457D56ECA616131
-:1099B0009D3FF5FFE1F847E118DD0F1C37FE0FC3AF
-:1099C000516090CF281C030DF7FF5138B6DE517C53
-:1099D0004B017459A784AC8568171E3251DE444D83
-:1099E0001DE75D8AFB0F0F69E4E7A14B82F51F8538
-:1099F0001A3BAC95A3FCB4FB31CE67CB78FE08EEE6
-:109A0000B799CBC90E911F5CB437E13EF4D30A6B12
-:109A1000FDF3F1CA724B697F43EE0B32910793FB62
-:109A200019839CAC5203E76D74E67D64A70A03D5E5
-:109A300075E8CCA9C9C313D13EAE338543385FE87E
-:109A4000A77CBE4C53B8C38ABAD731D089F62ED37F
-:109A5000C1F51F5B594AF66FABA9F0EA0500C7C311
-:109A60004A65E29B88E7D442CAFFE2FD85707FAB7E
-:109A7000B05B6AAACF89766AABB05B2D42BFCBFBE5
-:109A8000496981FBD09F3895B1E816EB75A887FC32
-:109A90006DE9606F4E662C5AE9F6A0BDF1165AC109
-:109AA000BE9C5CFB00D99BAD4BBDD9CED4687BD0AE
-:109AB0007F83B5263DF1C04AF45796DB17DE8FFE53
-:109AC0000E3CFF8D15F4EC336942EF88E785BD7AD3
-:109AD0000AF412E83175696F3B847AA9B057EF3CFC
-:109AE000407A67DB6695DA6FC37CE8FFC03A422AAA
-:109AF000AE7790467EBD0D604984B66D7021ED1342
-:109B0000C1BA5922FAD783F97399CFB70C32513EB3
-:109B10001FFB231E6D1EDEDF3295F9705FCB926C4A
-:109B2000A73844EE0FA8629F2A51D46928CEA91401
-:109B3000DF5957972FC478CC3AD0B80F6B89A9E773
-:109B40005063EB3BEC11F2BF4E6788BC7E3A735F0B
-:109B50002A8ADE07BD5D8E57D79DCB2B11DE85C9C6
-:109B6000CCA9625E2518A17DCE58BB66053BEAD51F
-:109B7000C987D5CEFCF1EA090E65723FD67E51A3A6
-:109B8000F866AD02FE0DDAD164CE67D23F323B25D6
-:109B9000DF1AEDAEF497CCA97C2D8B268DCDC2F8C3
-:109BA0005DB5FBADE8E7EC7396535E4065BE5B2B9D
-:109BB00075FECEF2C824CABF694E3FF9E145224E78
-:109BC000549D3EA6F7735A9740607915634F56141B
-:109BD0008F457978DC16B116217DD79928DEDB5FB9
-:109BE0007E7F48C1FCDB624672FA64856B2CE6D14D
-:109BF000B7688194BB515E8EC07C5E4E37BE9FDBE2
-:109C0000A260BEF80B6B2005F5C123C8F73ABC3C37
-:109C10002FF0F1F70CAE7F1E3673B968057822007D
-:109C20008776F11ACA6FADC9E4790F4BF538CAFFD0
-:109C300058001F98DF4B60CD2127AD97E7EB12DC72
-:109C400026435DA0767128BDFFF70C9321AE6E838D
-:109C5000757A75FACBC64294AF431C3F15C77F791E
-:109C60003B93C72356F087BCE49FC4EC73F7F58F92
-:109C7000C85F91F4E9F55314F04F2E138F3541BCB2
-:109C8000ACD7F74D5A0FE9DF268887F1FE39A79543
-:109C9000FC4359F76017FAACD51D6C1F8D7C9EE80C
-:109CA000188A79008D7510525663DD03EA43B7D6E2
-:109CB000D3CBFF20F32D36C756ECB75CD44124F943
-:109CC0008CF293C8DA237E94CF129DDC30C477885F
-:109CD000C64DF01AEF331664186768EED83A89500B
-:109CE0006F3D14D5F369EC31DCBF967E6F8EA847CB
-:109CF0003A9BF421E5D1C0EFAD4CA77D801E8A5B75
-:109D000064BEE7DBFAC9453806E61116FFB5E20482
-:109D1000CAD9D40905783F49E37C02AEB896508E83
-:109D2000E1D584F9A9B0FE3B85FDCB50DBA96EE4FB
-:109D30003511CFFECD39D3437114E093EA6D127D16
-:109D4000DD142F0A3F4DEDD58F7F5EE137FA9D215F
-:109D5000BD9FB76ADD9F572CE7F10AB55F7B3442A0
-:109D6000FAF3619B6CBF4C6DB073118C97D88B0963
-:109D70005EE44378DF8FF2C6EE28263F5B2D64D980
-:109D8000888F710E2BE94DF5C584ADE807435CFC67
-:109D900052BA6EBFF86CF2D17CF487E38C17328C28
-:109DA00097FFEDC683F93BB11E473E1FE7D8185118
-:109DB000F97B5E7C8FE5767D1882F1D7FD3A81AD27
-:109DC00004143E6E36CABBBC6E15F28CFA465F0FA9
-:109DD00069A9AEF123534BB94E7027B2888E9FA468
-:109DE0009C6B1707B3884E4E8A32F9BEAAA6F92992
-:109DF0008FA45D2CA5E77F4799A6799C579827AD3E
-:109E00009F798691FEE87F9E0AA15F98D8BFD2A86D
-:109E1000AE46EA85FEE43C769F2C562FCAABD48B27
-:109E200059997CFC7D99C6FCEBFD1B3B0E210B7DFB
-:109E3000660F1EC8A4FAA8630E34E1F5A6C850E464
-:109E4000E34FFADE6FC4C5BD95CEF3FEC5DB17BC8C
-:109E50008EECDA9519FC02FDA0DF648AFD4937D843
-:109E60004315ED1DD88B52CAE77E9181F9DCA077AE
-:109E7000C37886F27407E573535C81521CBF755A30
-:109E800005E51C24DCAB96F03A35A967ED5A90F055
-:109E900065D542FCEA0C820D67EC42A679B2A62099
-:109EA0003EB91C1D5D7781E4C0A6F989AF6C4E9365
-:109EB00017FD021BC485A877973A4D7CFFC66DA598
-:109EC000FC7FAB021122E88D85A98597DD1FB75C69
-:109ED0007491BD0548DC7ABDFDCF9F2743D807E3C9
-:109EE0003C9A93FB0D6C3FB7C388848F75FA58FA80
-:109EF00003B1EFC58E2FF129F16B45BC96923D8CD5
-:109F0000EB6FD85CC6FDCC2CA96F338F1647E06E83
-:109F100083D2ED40BF06F4A8CD857A7A488FC3E49A
-:109F200025FDEBE27E5048F035B3EBF95AE6A9E5A2
-:109F3000BA24FC0BDF9C63D5EFBFC4C21B6B67ED7B
-:109F4000A5C6BA059BD758B720BF0B50B500F18DF9
-:109F5000798CDF8A72B2D459EE443F67B9E6FDA32B
-:109F60009FEA2DCCE46F83FF6E985F5E1F01F94777
-:109F700038CA5C26435D8DBC26E33E4A9CF7A6BAF0
-:109F8000B89E7A64DF9DA487351FDF678AA51F63AB
-:109F9000EDC42FC9C5CC49F95301AFE30AE3F6C7B5
-:109FA000473FDE67233F591B650D635D67EC7CAA65
-:109FB00039E05750EF9631F293D53C3EBF3A885185
-:109FC0001DB863781A2BD1E1B1D53D8D9E2FCC748D
-:109FD00032A4B79A6C0AC4E31789A7812E93816FC4
-:109FE000DC926F3CEF17A31CE8F826108F6F06BABF
-:109FF000B8BE4238F4F46D751766C5A34F542F727E
-:10A00000BEBA125FCC4AE27E4EA785EBCD06C411E4
-:10A01000C44BF5999656CC7F9FB1F2E7CC5FC2FD59
-:10A02000322BE7B95949F961F4873A357F12FA655D
-:10A03000B37AF76DFDF4BD47BDCD9F721DDAC777CA
-:10A04000B8DF7CB2D2DEA6C03827CDFE14C4F7C973
-:10A0500077546529ED83F3FA39598774D2EC5D752D
-:10A06000353C9FFD33D5BF941E1BFDC133CC3FEC67
-:10A070006DF48F77ABB4DF52F0D3FBD421D0BF06A1
-:10A080001C45E4A75955F610DAE1CEF79B3F447D15
-:10A09000347B73827719D6B16C1CF625B63F5D9D73
-:10A0A000EC4DA03C5BA1E2C1FCD79A0227ED9B2CB2
-:10A0B00066229EBB7D7215E8D05FE2D4327F0D6BC5
-:10A0C000FE94C9E7A155E3609D5767769AEC00932B
-:10A0D000B221B4CA0AF47B7869C08DF163876BC67C
-:10A0E0002A8C1F5D2E7FD74D102F9E70DD3919DB16
-:10A0F0009D8FCBF1EE5AE507BDFCB22958A0C0F305
-:10A10000A4AC072653FD6A911CBF959ECFFAF95562
-:10A110005F1E85F1CB366C9C8C39B78A6AF17EE87C
-:10A1200009826FCE18D9DE9A543510DE4F62863C14
-:10A130009A391A8F529EAEB3D7BF7A7A32C69FB37E
-:10A14000C736576930FEB20D3B569582888C6CAF8E
-:10A1500074FAA1FDA30DAF4F4E027EEB64FE3A8C64
-:10A1600077576D3830D97A038C9F6E1C3F4315F9B1
-:10A17000D8D0E15598C7EB858FBDB7CA3F30DA7F9D
-:10A18000983B61752837CAFFFF2AF81FF8FD572E44
-:10A19000DC07B4761FC2145DFEE21E0BAF7B15F523
-:10A1A00029B9DD4379DD8D689774F33A65D976F383
-:10A1B00076E7B2F8F6FE2F6E2E779D89F19F7F2805
-:10A1C000F439C0EDC7FA9594A3CCBF238E3C1D741F
-:10A1D000D949FE0E82BF674D8BCAD5AD20DBA3B037
-:10A1E000FEC7CAE194E3C4BE7F4CE82716BA350D1A
-:10A1F000F9788AE0F3229FC2EB7876278507A1BF22
-:10A20000C722DA6DB09EED229FB1DDC6EE9D0A53E6
-:10A21000BB12597027FA9FE9D02EA5F7FD3BEDD16F
-:10A22000F1DEE2A2CCC61705B6E178E3B33C652DBA
-:10A2300005D17100EEE5D67203DCDAA8347C1ECAC3
-:10A240005E50AAC367295F07F009E10BA679F626DD
-:10A250009097CEAEAB0B57C21256B9BC86B8AFA220
-:10A260006B1A7D97F29F6EEEFF302F7F3FB38AD738
-:10A2700085F4EC49A23C05B37615239DE47B1705D4
-:10A280003EAA7E346503F6ABEF3233AAFFDF59797D
-:10A29000597FA01EF37A3AFFB15E8B503C578F79FD
-:10A2A000BD6138DE5B16B463388E57E4AF312F974B
-:10A2B000D9129FFED21ED65F4C65A1617DF56674F2
-:10A2C000FC0C7A7EA57545C733C69D7DC7B3887DD6
-:10A2D0000081774DE0DD121FCE0159824F01DF264C
-:10A2E0001D7FCD11FC06DA93FC80732F0EDEBAB20F
-:10A2F000403F2FFFEE06F4F3B337A1BEEC4AA4B8FB
-:10A30000A542F34FC6FE155D69B4BF20F943F2853F
-:10A31000A46B675A33E56B7A1E53C80EC6C2552C20
-:10A32000E1DAA8101C59D541F53E1D7C521E60FC97
-:10A330004E31FEF051243F4F707900B9B91BE5173B
-:10A34000F72B711DBEEEA1D386F485FF2768FF466B
-:10A35000101D39FE7F6D13F51C1C6F7DF19F730579
-:10A360007AE6D3F38AAED7699DF5FDC8ED5B6E073B
-:10A37000C1997534E2F042BF4705FF77767CEC184F
-:10A380008D72B15B658A97AF1BF55685D4C76CEEAD
-:10A390005B6341FF65F5B6415F7A910EBDFA3362AA
-:10A3A000B546FBBFE29E3B65393CCB48E0F29AA143
-:10A3B00082B5298FC2313D8BFB59A382F1FDD27743
-:10A3C000DDC9F45CE2FBB1C555EC6358DFCF5C7CC2
-:10A3D000FF7354774841BA48B98ED5538BB2B83C15
-:10A3E0002EC8FA7FA4A76C57D05336A9A7F8FD83CF
-:10A3F000101C613F97AB7BA802FE738DC9EFC2387A
-:10A40000ECC43B3FA0EF38E689BA952158B7827675
-:10A41000F36880ECCA697CC8EB571EC218704EBB4B
-:10A42000B17E856DE3DF89C6F255948F42C27F17F6
-:10A4300070087B706B42F7AF7891B1519E651BE05D
-:10A440006C3415E99EDBB9DD9274007A2F6769518F
-:10A4500039FEE8C5AC2DA86F87B9795E31A3C85F16
-:10A4600086EB9772097655F089E9DE6976AE37A6F4
-:10A47000C5E1DF27847CCED9C8F9A6F3BFAA26237D
-:10A48000DE3BDF4D4B5DA6D3134F093B28C7957AC2
-:10A4900048BE279F3F29F8637B9683DA4FB99245E0
-:10A4A0009EC714F7BBB9A774F695F8A78DF30FAC48
-:10A4B00037A4E7EF616EC5605F7BEDAAC0738305CB
-:10A4C000F00BF8DB6E0E6563DD4E459789C6ABD9A0
-:10A4D0009D4CF580351D1C8F35EDFB4C753AFCC449
-:10A4E0008EF71F59DC1FD862E27544074DC06F8894
-:10A4F000773B87EFDC8B1ED29F8745BF2BDB8D6FB1
-:10A50000A667B658781D29D097EAF91A5ECAD962AB
-:10A51000D4D34B05FE832DF81D5BC606E6C35A2B2C
-:10A52000C0534401B867B885DEB1F82DF8DD6ACFB5
-:10A53000638CF6F30755FBCBBCD06E0AD8CB15184D
-:10A54000AFB89DEBE18AB5E0C7A0DC59A55D787393
-:10A55000877EBE6359C9221EE1FC5CB391E36F1094
-:10A56000F83FCFE215C6F915F9F11C9E8FD6778C0E
-:10A57000C6FC937CFFB4A0FF95E0AB40F88647E1B2
-:10A58000C3F1919F983DB00CC76DFCC3AE1CFDB8E4
-:10A590005F66717D9BA1CE1A6B433DBF06EC0E49F1
-:10A5A00067703F7E9750B337D5B992913C9B30EEA0
-:10A5B00091F3D6883C24C85DC554585A71EF3C923B
-:10A5C000AEEF3DA75FBFE6E6FEDC3F8BBE9D96206B
-:10A5D000ADA76727C0EB8DE2A5B3E3BE6536B41324
-:10A5E00047990FED8484775075B703EB4E9A84FD3D
-:10A5F00080F59A307EC9F89997B520DEBAC65A30F0
-:10A600007E8AE56B49A712C6E547C66925B84100B1
-:10A61000ED3CF750A17F18C5BB1FBDF4CAB32B2971
-:10A62000BEE27469AAE674AC740767B833A3720813
-:10A63000FABC02F555CDDA5E7DD4C1EF77E557035C
-:10A640003EAF754B3937D22523D061C37D0DC9D7B5
-:10A6500067F70C09AFE474A6F93B3B92C38A82DF2B
-:10A66000A1362FC5B85BEA0984475F8729E1E9A5D0
-:10A6700023033A0E89DE1F54CDC76B0279473EAAE9
-:10A68000579B158F427A80F2AC59A807A09DD5C17F
-:10A69000FBB1BDFC5C0489A7FA193028C49D7E7704
-:10A6A00029AD43E22BAB3A62AA875B13AD55FE138B
-:10A6B0003A7FEDB0D86F40BC4CA37883EBEB7A3592
-:10A6C000908B712BCB4AA0EF38C10E917E39686315
-:10A6D0009A0DC67B03AE6897C6AB0BE83B9AF14573
-:10A6E0000AC931680099F789A03F7DEB4D4924FFE5
-:10A6F000ECEB0706E23A3393381FC23856318E9599
-:10A70000ECA0B007BFCF07BF4E89EAE5838A42E3DA
-:10A710001CBCE19AAD545B28F812C743FFE9A03294
-:10A720003597EC6567A6282EE2F0F76FCFBAF3F104
-:10A73000B93E5EC4F82E1A6F96ADBE19786AE4C4AD
-:10A740008E88C989D2317CCABF01FCE321DEB4C145
-:10A75000FAEF137C7DB020A43A10AE41B06EB8750C
-:10A76000283158DA6C8FCEE312F91B97A8DF457FAA
-:10A7700001AF260FD7FF3FF6707BF181B8BA1CF10D
-:10A78000F33D1745FF3FDBB99E5E5919FFBBED87CF
-:10A79000845D9171E7AD62BF03E2CE87DC3CEE14CD
-:10A7A000F5A77C7F04FC7BC26FD58FAA69DFEF8B96
-:10A7B000AEE929FC3C04AE0FE688FACF7B1F9AFE77
-:10A7C00013E4B31358670E78F844F0CB09A7DF8180
-:10A7D00075520D89F1EB889F14F034083C9C5CC2E3
-:10A7E000CF2F9883FB72C07FEBDCDCCF9BD77EDB67
-:10A7F00004A4FBBCB50AEDCBC9FD7F49E7DA4DAA3D
-:10A8000021BF3E07F7E5D2FF9178AAAC9F786AB8DE
-:10A81000219E92F3C6C6551F2D711BF60166B51712
-:10A8200089F32378FFD9CC4770CF6ECB31EC23B2BC
-:10A83000B6CC6FF4DD3FC651A1B8F0590CF73F5AC2
-:10A840006265213D1CA70652FDC443EEE0CB6E03BA
-:10A850001C492C64C8878E71D2F744369E87057FC9
-:10A860009CC73170DD62277F7D22FAB3BDF930D0FD
-:10A8700023CE14D44B95FBDD23A2F18394B3FA319C
-:10A88000F1E38875C20F5AE7E27172CA511957276E
-:10A890007A513F4ABF3CF6BD777BF9D7E8575E292E
-:10A8A0000F017C1CD2C749B1E39E72FFA3F177511F
-:10A8B0003FFC52FC3F127F578C09529E8FB52B54A0
-:10A8C000D332729C311EFA1AEDFA08BC2619E2A1A5
-:10A8D0009A6A633FE6E1F69F79920C7E7C7FF8D41A
-:10A8E000FBF14A11EA413E5EA3E08B82CFDEA57AFE
-:10A8F000D2311EEE178DC8F62778E0BA5AD493AF3E
-:10A90000B6F1EFF9B7FCF77EF76CF48FDE36D3FEC5
-:10A910003FDBCDF9A6F289452D783E80BD4371EA33
-:10A92000BF5FFD97C58ABF06E43A5DE8BB7A1F5F4B
-:10A930004FBD2F621968C7FA620E476EC73E45D3F6
-:10A94000F15D6E2DEF97E7311BF2E205A23DC0E30A
-:10A950009471CCBE4919D8DFAFA15F90DDA190FD05
-:10A96000CC6E66E457670F5768FC7F19BE45995D4A
-:10A970001A5D6F9B696AA913DE6B7325F9D0FE2CF3
-:10A98000C90E5EE541F88E4522682E471EEBD23097
-:10A99000DE5A93ED2F413CC8757A556736FAF14976
-:10A9A000C7387CEDBD79266E7F185B25FCD2ADDC07
-:10A9B0003F53D961C6FD73B2F3AE65256407E57AEE
-:10A9C0005C69C28EB85870979DFAB791DF62E57ED8
-:10A9D000806B5931F9F392AED1B8737039C69D4589
-:10A9E000AB23DA2C78EFA54DA6B8E7554C10788745
-:10A9F0007554EAD77125BD25FB99FBC93B4ABE4F6B
-:10AA00009A183F9E074B48CF2B9FC8B88BE473B969
-:10AA10008561BE5AE27F4D76E0768427BB638B82E8
-:10AA2000B8F948D4297C94C8F3F11FAD7C5641FF96
-:10AA3000F281F9CCA9B2FEE1AE5FACFA6BF4F2BCE4
-:10AA4000DC427491F14A141E9E8769F070FB7428F1
-:10AA50003B5083F46EDCBD86E2EAF9DB8E5B2EBBF5
-:10AA60000FF10DF1A6D4727FBD7EA695EA992A9FBB
-:10AA7000D088EE75CB2DB46F58BF63277D9FC61E5F
-:10AA8000643E94FFFA8E9D4A0DCC5BB763A73247B4
-:10AA900087C79CFA30D56F5F952CF72322E44FC708
-:10AAA000F237E611D07F3964E3F27FA6D21EC2FDF1
-:10AAB0008933E6603DF63BE349F2E13EA6C4FB1B69
-:10AAC0003B6FA6F30292772544F0DA66DAEAB642E3
-:10AAD000BFB6AB2D3EE4A735D9C1154897342DD06C
-:10AAE00089EFA76624FB707FC39BC0CAC97E7F43E2
-:10AAF0003C8C8CE18B910F72797959E817F8A37A25
-:10AB0000AA273DDC2FC7ED25D45787CC7C1DBB1869
-:10AB100087D7E4F16F443AB1C369346F767D44C19D
-:10AB2000FA8BD879A37CE5DFECC9FC3670765850F7
-:10AB3000CFD7097D53F9C436E5631DDCCF79548244
-:10AB40002F7BC71605F367F09CF40DF46758EF945C
-:10AB5000BD83C7AB75F07C8E4EBFC875C4D1339D25
-:10AB6000089FFD58D701AE67227CBF40C01B4BCF6A
-:10AB700088C74BF34F007781EE5B4225182F1F2AC1
-:10AB80004CA4F1A4DCC7CA69C4C3FDCAEC4DDB14F4
-:10AB9000939DF655C8BF94F0C97E23B2C71EF0102E
-:10ABA0001EBA080F0D9B345ACF784B60E0029D3CD3
-:10ABB000BC2BC67B7DC68774AECEDA7F7F87F8B1AB
-:10ABC00001E26C8A33DADFB14C473B13FA858AFB2A
-:10ABD0006093B98BC2D68B73A72677723DDCD0B950
-:10ABE000539B6D8FF269C167AFD379550D1D090C69
-:10ABF000E32BE0BFA3084F2C9F4AFC483DDB1F3DE1
-:10AC0000411FF1F829641179BE6001C63F524F9B84
-:10AC100084FC333BBFFF855857947F829F790C7A21
-:10AC2000D6467251F059F9EB58EFD9E053E8BC8E93
-:10AC30008C2A8E4F3D5CFA7830564F623E31C0E32D
-:10AC4000FBFC69BAEFBA7AF5BD78FF22D29BDB8DA7
-:10AC500008BFCF0AD17E4BF863E937309BFB6571A3
-:10AC6000F84CC91ED1D79E493B5FB0799786DFE586
-:10AC700048FE998C74D7F18F33DB42E33AB33582C7
-:10AC8000677D25DF8F5C6FE6766CFD522BD567BE46
-:10AC90007127AF174BBECB12C1EB41D3AC7A7C7E90
-:10ACA000309BC3D1665A46DFA9815CA66613FF3884
-:10ACB00018D78F5C1FAE7D81EBB3FA909DE2DFFA6F
-:10ACC000E0ED35540F9061F3611D2D0B1EB04C4F1C
-:10ACD000EECB57DE5DFB2C08FFE40E2E7F920EA01C
-:10ACE0004F89BFA43C48BC46F11936C893A487A934
-:10ACF000D79F0816707F89C75BA5E23BC25AABFF9E
-:10AD000090D98B710CCFCB968AEF09655E7696A0B1
-:10AD1000CB667BC087EBEC9397FD86F142DDE2DFEB
-:10AD2000527C76BFFB4DBA4AB985B8D620DF3709C9
-:10AD3000BA176773FB3E219BF34DDDF00E92CBBA41
-:10AD400013CD24CFF6895CAFD98FC5F88FEC11A154
-:10AD50008757D37BE3933A26E0BEF2F89F2B4E8CC5
-:10AD6000F7FB83731E7E8F8571DFA6FD8EFB10BF00
-:10AD70005F43D4A1FB5E67463697AF33DB01E1C486
-:10AD8000EFCD96CBF9E3571A8F458E28741E88C0F5
-:10AD9000E5991D55D77D82FB40DB537CF8DDFDE74F
-:10ADA0003B6EFBFE2700F7996D37F9D04FC8680955
-:10ADB00010FFF464DA7C5B799E7622E6B19676EC3D
-:10ADC00077E0F73DA79FBDB61CF576A380F3B317D8
-:10ADD000D4C5889765CF3C7F233EAF0B2BE9E8BFF6
-:10ADE0009ED9FEF3BF67C338B5DB9AF0A431D6F223
-:10ADF000EC6B141798C25BF8FDED29E4E79E7E72B8
-:10AE0000CD8D88EF968E167AFED9935BA8FDFA3326
-:10AE1000CFBFFA5FD0AF3EE0A0EF9E3F7B611FD176
-:10AE2000A53EA8517D7A7F7CBD7EE73EAE2FD1CE78
-:10AE3000A31CCCE47A4CF2B5E4DFD3CFDC7B9DDEFF
-:10AE40006EC8FB6D229FD396C8EDC8E7426EEBC675
-:10AE5000DADBF0FAF973363A9FB3D1D25D8C717EAA
-:10AE60007D29E78B07053EEA3B16981BEDF43E8DE6
-:10AE7000F39F20EF781D02FC897560D06BDB25AA5B
-:10AE800067FA15F5877EA330DF33A3FA38FFBEB328
-:10AE9000B4D95C47703ECB9FC3AAF5CF2B16C58FA4
-:10AEA0002FD767DB0DE7AA65774ECDF5921E48F0E8
-:10AEB0000DD2F9BFD9B5C19664B87FCBA2A00FBFA0
-:10AEC0008F7FE9D4BB13F03B86674A9461447F557A
-:10AED000E1762E64A7791A701F09E28FED424E20A9
-:10AEE0007CCDB81ED6335E6319F889EF78C68E988C
-:10AEF000492F3C45E3839F43FE9BF7B5194FA1DFE4
-:10AF0000B3DE1CF48CC071DA847DDCC6E187F79D6A
-:10AF1000F6721ACF793DF7D717E27BE7974EC94013
-:10AF2000FF1EC6ED32EBE231E0C87CB48F38DE7034
-:10AF3000C4D3C4D04CB2535E0BAD4F9EFB09EB1F84
-:10AF40007AF790A87CC6E69B503F617EF85076E584
-:10AF5000BEECCCE8D5D54FBEC69C03CFD19EE5F85C
-:10AF6000E9FA4DCF117D7DC6396EE75F3E4E7CDB41
-:10AF7000887C8BF3074F18ECBCAC7759BFE738F1EE
-:10AF80006DCD6EAE8F1B77575A30DEFA7C899F7D70
-:10AF90000C8E6EA3E0BFF54AF75CFA4E6C8F8DBE47
-:10AFA000FF3B27F9B3FDF8A7A87F0A777B289F709E
-:10AFB0006E0FE7D3832613E5010E6EBD664B8BD271
-:10AFC000D7AE82BF4D72D2D8CC84BFBDE85DF4CF7E
-:10AFD0001A6A793D7A630C1F156CFEA815F92515C0
-:10AFE000BC63ACB3017F66027D3F59CF46A09C662F
-:10AFF0008FF3EFC9A17D421E9F67D7823E81F62D58
-:10B0000019F37D78E455EA38F08B91FF326EF061E8
-:10B01000DE6C7D5E472BFACFA1F18CCE575D6F6E53
-:10B020001F8B71F0FAF15E276012F0B68DFC6B5643
-:10B030006211F6AC86FCF246F7777C94D78E95FFCA
-:10B040003D4BC9BF6BF426FAF0BCDBC9BB9585DC70
-:10B050009FB13384BF11F08BEDC9E1D16184E7ACBE
-:10B06000C09FC4E33973179DBB7BEED709748EE193
-:10B07000E4719C5F53C77590FE7863CFCD64AF25B4
-:10B080005F26BF9840763B4D732A98E760ECB60484
-:10B090008467B680A75DD4EBA60A3B52B49AFB71D5
-:10B0A00029395C9E52724CE26A117C2ECF6509519F
-:10B0B000DEE1ACA03FB189EE5CA7869A08C953FDDA
-:10B0C0000E3E5E4682BFEC011DFF4AFF4AEECBE218
-:10B0D0003EEDD438FC3D42C051B07921D17D76ADF2
-:10B0E00038F76135F72B18F005E20DE8487C704B16
-:10B0F000C63CA2DBECD5CA5D44C75005E53FA57F41
-:10B10000163BFE75627DDB6D81E158EFD79399ECBC
-:10B11000C33A82EDA97E13ED2394A5521E24339DDC
-:10B12000FB8B99C25F8CCA7D60B809E639E54AE6B7
-:10B13000F40EFF5EC3FCF6F81CAFF4FF0C7E5EDF7E
-:10B14000389F8F37A53D3414E31EB9CF2CF1115E23
-:10B150009A3853AF4F6F12F8080F6633516F403C67
-:10B1600061A73CBC13E6C17CC2D6D14FF27C023F42
-:10B17000FFB92487FB3DE3D303C3D14FCB2C0A2C6B
-:10B18000E2F693AF33161F87B2651C704F19C6B134
-:10B190008DB7DB7D28776B5F5666115F87AC7828AB
-:10B1A00010F03D97437098A8BE8D0535A247637394
-:10B1B000201C9FEFA7929C3582DF8771C064E4F367
-:10B1C0000CE2FB30E77B6EFF64BE01F5A4DEDF9688
-:10B1D000FA40EA19B46FC8CF522E1A6FEC2E46FA15
-:10B1E0007E53BD72CECCE5FC1CE001E548CA4DF2B1
-:10B1F0004B5C5E562EF556E2F39520F77A7AC7C679
-:10B20000670827C62B52BF2FC90E3C90837907537E
-:10B21000A495BE4115FAB8F1A515C5F1BE2392FA61
-:10B22000D82ACECDB48693C2FAFD12ACC1482EA75F
-:10B230006B08ED51D2E2F8F998D61C695FFBD4AFE8
-:10B24000B5223CB1F56B2EB45D283F5B93E87B36AD
-:10B25000999F8A1D77B1E037491719A7E0BE07F615
-:10B26000DF9AC3F9659DE8F76C8E22E4226CE07FDB
-:10B27000AF29781CEB0FFAB363F2BD7F56BE4CCEFC
-:10B2800023ED692CFDE5BE0DAE676A69FFFDDAF7B7
-:10B29000893830861F77093969CE61B4EE7673E458
-:10B2A0000B92AB05C98CEA7E36327F3AEE07BE7A46
-:10B2B0001597077F4F318E3F342FE8C81D11CD0BF6
-:10B2C000E37D8C4FEA34164A009AD46D3787F5DF58
-:10B2D000D33C95CBC73F9F6C0DA9C0E7FEBCE0BE39
-:10B2E0009C11743E087D3717FA818DF6B1C0911E0E
-:10B2F00081FAA589753B10CF8D6A5731E631AB5D78
-:10B30000C14348FF8F4C5DF9BCFE83EFB31D137939
-:10B31000DF6322EFDB6989E4FD5B46F41CBB0B8C29
-:10B32000D75F5DE832A5611CF8C1EE3F3CF732BC47
-:10B330007DF7CB67EFFE21626B65D23D3F836BB536
-:10B34000550D68BAFCDCB1E4F87AF6CF82BEBDF5E3
-:10B35000514B13E2E6FD9FCFE5FD9A62F6B59FCF14
-:10B36000E5FA34FA7D14DFD7FEA09FF3AFAA72B9D5
-:10B370005EEF14755BB1CF278A79B69B59F146848D
-:10B38000674B32D503308D9F5B56FB68810FF7F119
-:10B390003B0BF939F93DEB14B203C7CC5CFFC0DFBE
-:10B3A000EDD68AA81D453705FDC45A67286202FDFF
-:10B3B00051BB283982E765C27D6D0CCA5AC849F570
-:10B3C000C3B3847D9CDDFCC65798F7A8D598750C4F
-:10B3D000BC77D25EE340F330F7BB0FE051342CABC7
-:10B3E000BA5DD4998A73D8FC53D44B4997F3EB8C4C
-:10B3F000DF97BC901B30E7C2FAAB5338BEAB1FE0FF
-:10B40000E7F1CAFEBB85DD8BE5B7EDC8AB00EF8782
-:10B410000AB72FB1F364E78DED40FEAB76079CC809
-:10B42000C7D50F9C35E8B5734AF7D33F43BE5C9050
-:10B430002CCE4763F9FA3AA521B95C6EEA70DF0CAD
-:10B4400054E3F9B2AEE2C505C8FF3DF97FC4BCDBE9
-:10B45000DE04AA73AEC3FD33DD7E777FFB67FDEFAD
-:10B460009B792DC8E78D1715E293597BDF388A7ACF
-:10B47000BD51EB26FE9965B5137D1A2F6AF49CB574
-:10B4800099CFE8BF975BE4F65F83EB0BFD684C2A2E
-:10B49000EDBF65C17DC273099DB7B150D49767E711
-:10B4A00005CB11CF1B921CF7627C78C1CACF576ABB
-:10B4B000B2F03A7226BE43967CC272938D7CB0F78E
-:10B4C000CDAF10AE1A6B90CEA99C3313E26915E98B
-:10B4D0001619E12CD5D37FCCB73A27D7857A03E06C
-:10B4E000FFC0C2EB88FAF23FA7C3F342BF7C90CD06
-:10B4F000E5E8837C56BB0BAF57C315DEFBA050B409
-:10B50000CB793B769C7A21471F0CE5F62BB430298A
-:10B51000EEF920F708797C21D77F07E255DE7F52CC
-:10B52000C0919DE7BF13F108FAF16EE2AB14164922
-:10B5300085F1AA5FE3BF57C096F7501D6BEFBA8A3B
-:10B5400005BCAEF8702D8D8E5B83E3413F3FF9F172
-:10B55000AFDAE83B383605F435EAE785790CF533A0
-:10B56000CC5B8FF3C3B89154EA9740EB606DA0B702
-:10B57000817FCF8FF0125D5656029F0E17E7EF7B4B
-:10B58000A37C25F929968FBE9FABF4B7BFFF7D84BE
-:10B590002B767F9FB181446FE2B76FF13DD9E8749C
-:10B5A0008E1790FB965CB2BF91217AB9937896FA88
-:10B5B000F28344235F240A3AAE12FD7AF12CCEB313
-:10B5C000CA28E27650C60B3F13EB72C45CA55D8BB4
-:10B5D000DD1F7008FA3B7279FD14D06503C229EDB6
-:10B5E000611F7A6FE2F4867E9B488F25F4DC930E10
-:10B5F000F6EC0EF093F03C4B78CF85EFF5C95B8C01
-:10B60000E376B8696132433FE1E95C51F73DBC87BD
-:10B61000EFDF95F4903E9AC540EF2857A61FE60845
-:10B620003CA00F9FC7FA118043C17AA43452035E35
-:10B630001C0FF0BD3337338AEFD8F98EE123F00BBE
-:10B640005FCE15DFD995B132A4D73DEFFC35F96E49
-:10B650002F9E77CEBFEFFDC41E7C0DC739F3FD379B
-:10B66000290E38668914B7DBE33CB744366F50A225
-:10B67000CFEFFD851AC2DFB7E8EC3AB36E06F0E50E
-:10B68000AC2ED58753CE7AF08BB747A27FDD65A667
-:10B690007D28F02F56E3799FC7445D216B36E6097C
-:10B6A000FE24E82EBF3396FA49FA09F3998FEBA5E9
-:10B6B000447EBEFA470BE6D177C6352C7008CF57CB
-:10B6C0003FBD7012F9CFF35890CEF79EDD663C5F18
-:10B6D00037F65CDED8F37831A18FF88A3D97F7F31F
-:10B6E000EFC5AF9BE9CDBB57C5F737B43CCECF9F75
-:10B6F000F753AFFE37C1AFB2BEA049D617BC72F93F
-:10B70000FA82A698FA82A83F22EB0BBEE6F505AFB7
-:10B7100018EB0B3E1F1B1F8EAF7BFD9DA47EC675D5
-:10B72000D0FDCF0B2FBFCE263C6727EE77E476BA4D
-:10B73000DF5F7D43A6C4533FF51DA9791C4F4D170C
-:10B740003D067B9C99E78DF1C772E979534C9D4486
-:10B75000F439AF8F90F903A02BD5E3493F30F6FBC6
-:10B760007A99DF97F2F3B1C2AC1ECAB7AD11FAD421
-:10B770003714FDE68FD11F43F9BDD9FB6A37803AF4
-:10B78000FB87D7156B8551F98A5D0FF0E567FAEFF6
-:10B79000D807E789F3207CCC47DF390AB9B8E7FB43
-:10B7A000E353707FF6CF0F5619BE5FEBFDBEDD226F
-:10B7B000FD40BBC19EB3187B3F7BF79BE4E7D558A8
-:10B7C00003F41DDD27AF7C9FECFC5C1670A19C9CF4
-:10B7D0007FE5AAFCE0FF859D97F0DC16BACFCCFD93
-:10B7E000FB0CF24FA609786EDBCBFD4C93D56FA610
-:10B7F00079FCCCEB745108CFE105658BE7E8DDD02F
-:10B800000B7F299DBF3146C0AFE0FB80DF1BC49595
-:10B81000CD0ABA116E792E00709D1BAF2DD7F9BCE1
-:10B8200078BD4909684CF7BDE804D69C8BFD4DD620
-:10B830006E559C5746E7CC2744F145ED64D15E7EBA
-:10B84000FB857BE6E07D3B3FAFD822E0B83F4F7CF5
-:10B85000076D65565C77823D729AF60FC535349652
-:10B86000FBEDA1425E979C88E721C0BC76FBD91016
-:10B870002ED6C99CF49DBFCD792182F18BEE77261F
-:10B880001AF346E87E678245785EABBFE731BF4377
-:10B890009126E06B117AD283E71516D1B90CA42753
-:10B8A0007F9A3C97CE27CFB42FA27DEDC71C13699A
-:10B8B000DFD38588C77AFB89BA7315E07966C078CB
-:10B8C0009E42D64C63DB1334B6ADEC18D587299174
-:10B8D00080FB527AF4DC48B3D037B72772B86E4F8A
-:10B8E000E471DE237926833F1290BF0F93C6CF5DAC
-:10B8F00038E7B25AB14E03FC9347F2B87FF22150B9
-:10B900001AE249FEFB316537F907AD1B8EBF8BA2EA
-:10B91000FA96019D5A93BD4B35F4FBEE14BF23A656
-:10B920007550FDC3967B527D58AFD36A735662BE85
-:10B930003494C7F3444DE2BB0FA048DD0E786FCBC3
-:10B94000B41CEA9751D54379D69E158CFCAA3E7C4F
-:10B95000FA35F03FE0FB496CE3791035BE2EFC0E62
-:10B96000D8E357A96E593EDF86CF014E45F005DE7C
-:10B97000BFA922FA3B4F457BCBF6E379962CA8F87A
-:10B9800078DAD24BFC3E5DF8F34D7B2B6F1D0170D6
-:10B9900015750D23361EB857ECD3642488FD667EDA
-:10B9A0009E6F6CFF81D81FDA4987BDDFA9C7472684
-:10B9B00088CFF1BDB149B4EE23224FC5847E18195A
-:10B9C000237FA3A3F240CFCB44BB49D417E2191481
-:10B9D000FE0A9E06A17E195C3E7C4CFE71B9BD9E9E
-:10B9E00045FF709CAAE8B8A4A7C6451F47E5109676
-:10B9F000586EF5B5D443BF8353F9BEFC482DB20F42
-:10BA0000E57DB4B896892B9BD54EF85DB934F2BA72
-:10BA1000B90053320115DB15CE152D38CE0D4A84F1
-:10BA2000AEF933D7B4209B5D9D5F24F241C1F1286C
-:10BA30009FADE3F9F7D22DA37C3E273C9A3193E7E3
-:10BA400071A7CFB4521DF6748D9FEFC4B460C11DB1
-:10BA500020677754F3FC31B6AB75F919B95F7204FE
-:10BA6000E29B9D71FC83ABF3B95D93EF3789BA21FB
-:10BA7000F9BC389FE7CBECF9134EE771F8685FF833
-:10BA80007C9EF0D34A5849CCEFD1FC350FFDAFCAAC
-:10BA9000DFF6A7278CCF859E98EE7FD44CFEBDD0D5
-:10BAA00017522F07443D54973897E5BDB11CEFEF6F
-:10BAB00056CE277D713B6B267D7E070B9911BFBD4E
-:10BAC000FA7FA2CE3F8279A6078CFED28C99B17EF6
-:10BAD00015E75739EF9D41E3F369D2EF9D68F47B99
-:10BAE000ABFFEDEB54B28B594F375C1A10AD7B6A4C
-:10BAF0008AA97B6A14754F4DBB171CCCD4D53D3534
-:10BB0000EDE5754F8DBBAF54F7D443FB4F47CCE108
-:10BB10007DB82F73643E8804C0B95FD4C91CC03A95
-:10BB200099F2285F264FE3F959605FDA67C97526F5
-:10BB3000F9909FDA4CE594CF6D7324FBF4F9D3951B
-:10BB40004B81EF74795C59E774A49FB8B83C9FFBB4
-:10BB5000C1EB159E4F0FDD69A53830B32860D8BF03
-:10BB6000C854D951CC4B9E167ED07A912FC1FDBFBF
-:10BB700061700D2BDCBFE97D1FBF9FC23C668C3E10
-:10BB8000CA4CF7D1FE4166CA10DA0798B9B76C1BE8
-:10BB9000E91BBBCD87DF07C8F16706B768587FD4BC
-:10BBA000B4778B56638FF2DDF87CC1AF492C09F96D
-:10BBB000B5372FB82B81F2829FD80393F2E1FD7A3B
-:10BBC0004B642833F233DDEFCFAECD13FC621E1B86
-:10BBD000B8730EC073FE6D0BCF8F3DC8485E5FD843
-:10BBE000934A794D6D1A23FBB2BC92F1DF8BD9A237
-:10BBF000903F7732959F43B47C2A233B782E6D0289
-:10BC0000D16F3E0B1FC273866A37990DE709DDBFFE
-:10BC1000CDD8AE671D646FEA77F4E167D25B523F1F
-:10BC20003630AF8A7AA8B1D3F83E1B68D48F65C28C
-:10BC30001E0C9B3EAE05EB3C8699B8DE620FFA7295
-:10BC4000A651DC5DCDED287B9ACEAF3A9F7C4AE5CC
-:10BC500072CEF5F188A8D634D8A511C2BFBA51E387
-:10BC6000BFB320FDA511E277170E98F6AAF41B3F8B
-:10BC7000029EE1E23DE9A7497D2DE952390A7F3371
-:10BC800002E2F07CE1EF14B242A42B8C4FF2A060F0
-:10BC9000A0C48F4CA6DF6F182DE603BAF3F3EB4C6C
-:10BCA000D630F251ABD24C7ADACA84BE5682A4970F
-:10BCB000FF3D1452910FAE63CDB7E1EF818EB176A7
-:10BCC00025915F6A0FFE44CF272D2C92BF5331F090
-:10BCD0000B3D3F93FADBB8FC22ED4AE43DEE6F4C9E
-:10BCE00066E007C2BCFEF7B91F7440E1F122F88399
-:10BCF00007305EFCAD6912F1C3245806F61BEF3421
-:10BD0000D2F966B7B13DC9DB870F54FDEF5980C446
-:10BD10006908CFE412633FBFD46FCCA8DF0AD8D73D
-:10BD2000BCAE7EC5A1EF62DE2069312B413F063CEF
-:10BD3000475FBCDF2BDD85F68298A0CFFECAAEFC44
-:10BD4000117DF757CE8B3CF1F5AC7BEE0EA52FDFC6
-:10BD50009C3BB85875EBF84BF2F34BA21E43794D60
-:10BD6000ECE30EE7F9C2A89DE77C53215AD723DF05
-:10BD700041FF3F483D207E77E486DDB608FEAE4EAB
-:10BD80009918E77AE49FF2A85D8F98EC5E4B21F258
-:10BD900089AF4D55FBFAF3AE342FF1CB30939FF8BA
-:10BDA0006504F3A5239D46593B5A34847FCFC89C34
-:10BDB000A0DDC01F7FCC47FBA7007F503EAB8F7D2F
-:10BDC000343E8FE11F49C7C3C28FBE9979298E982F
-:10BDD00028FCE84801E79F2AFBED1ABEFF4621CF69
-:10BDE000378CC38D47FA6ED56817ABAC463E88E5F5
-:10BDF0002F98D1A49F3796DFFAE39B01C837D22E44
-:10BE0000A65F996FBEEA9F6FBEBA1CDFC4F28BD4E7
-:10BE10002B3B6DCE2A3BE6B76A15D2C7C3DE1ED8D0
-:10BE200082EDAB1A0AA85E6667AA6F3F3D6FE6CF48
-:10BE30008777F955ACA7295A249E1704AAB0DDB418
-:10BE400098EF678C38C2EB6D063EC89F972D6BDE6E
-:10BE50008FDF093685F8FB2F9D6EA5EFA5C2ADE2F9
-:10BE6000FDCAF62A6C37B5F1F74FE2BED4B55827B4
-:10BE7000176EC1FB835717F87858CAFDDA9B049FE9
-:10BE8000EE5476EDA7F7DAF97BF30E5913E977084C
-:10BE900085DF7AA358E74D9BF83A333EBE857E97FF
-:10BEA000744E4F88FCA74F4DF5F4BB37FDC59F95E9
-:10BEB0004A7B2E5E6F467D8287795981AF0BF9BE32
-:10BEC000E5569862C400EE0FCAFD3EAC3FD0D71BCA
-:10BED0008C18C0EDBEECE74AE3DFB5B1C793295F2C
-:10BEE0002CF723231B98827A19D728FC80B8FB9360
-:10BEF000371735D3BEE4CD03E4BE64B786E7B29707
-:10BF00005DFAEB847879963162DE53A29E42DEAF11
-:10BF10000D17D0EF8CED4426A1EFF29FFA3DB5C589
-:10BF200039E34C7C07B7B380B76F19B0E5276D10C4
-:10BF3000BCCF33356B782E1BCB57E83BC07FED620F
-:10BF40009114475FF86FD658C4C2BFE323F8E7B631
-:10BF500058B6F2EF31B95E9A2ED5CE984124A7B7E4
-:10BF60000B3ACD1820ECD330360CF5CD7441B73BED
-:10BF7000ACE0B7925E6B37C7C8FF7706A0FC3FD630
-:10BF8000AFFF6C7C1EA31F6AC5BC7385DF3C1F7F9F
-:10BF9000CF54C5F3E2B9FF7CEA31EE37DFCF3A2860
-:10BFA0001F79FE71EE2F36C0F2905FFAFCDED77675
-:10BFB00063BBA123F6776643347E9FDF712DE5795D
-:10BFC000DDF38F3554607EAF76E3DB943FAE95FAB8
-:10BFD000226CD417E060707DB1E16ACAEB98ACFCCA
-:10BFE00077368781BEC0BA9461586F0AE30F15E7B0
-:10BFF00000ACC057C4F7FF03486F4CA47A541A4FE3
-:10C00000A57DE0B7FDDE287DA4DD88D51765325F0C
-:10C0100033308DF259527F94093F854D8C8D1FD757
-:10C02000921C0E13AD8D92BE220E927E07BC4F7EE7
-:10C030004797C91E3699F47E4698E4B2DC0AF68228
-:10C0400044C96765E23C81183A6FC2755D268E323D
-:10C050003E8FE10319C754083EB893F9293E7A513F
-:10C06000F0C1BBEFF1DF839B6E5F447CF8DEFBDC4D
-:10C07000EF9471D4B78F9F22FF50FCD44B771BF8FD
-:10C080009349F8BB169306ADC3FDF44E1BFFFD6B41
-:10C0900085D3D975E7917C7D7EF15DFC1D17DDEFC1
-:10C0A00043B44C4AB0E23E628B99C717D3267F5007
-:10C0B000314BA73F86A45746105FAD4AD7F7FE84A1
-:10C0C000F1C69BE23CD6BD9944F70B5DFCFE854D65
-:10C0D000D7F84270FB73B338DF4A699E8B25541240
-:10C0E0008EB9E2775FE6A9E157BB713F5609BF58A9
-:10C0F000AFD0EFB4FC0EE5B2CE14B1F0BC5E17E5E4
-:10C10000E9E5F8FDE72943145F5B5EE7F6B14749CF
-:10C11000F4F13C6FC8F0FB3FBFF3F27C943F2FF08B
-:10C120003ECE23ED5F6C7DC2B10537D377AE7F6322
-:10C13000FE14DC175534FE7BCFB1F3623DC2725D55
-:10C140009EFA982DFEFEC129A16F4B105730EF4388
-:10C1500039FED338FF2911179E12FB63A71C7CBF41
-:10C16000EC6F03781EBCC4CBDF4B14D753623FED9A
-:10C17000549A319E94FDECE27A628935B05C47575F
-:10C18000EF868466CC4B641689FA93458CC74F7B47
-:10C19000520DE72E64792B4BBCB8CF5124CE2DD84D
-:10C1A000C3ED32EE63E33EF313D941133EFF3FFD8F
-:10C1B0002524DF00800000001F8B08000000000025
-:10C1C000000BD57D09785445D668DDBEBD857487E2
-:10C1D000CE06618B9D7D0F9D0DC3269D8428B86082
-:10C1E0002780A06C0D0804C8C6E27CCCE8BC3406ED
-:10C1F00011F95CE2382AFE2E7F83E0EF366384A0DB
-:10C200005103D32A8330EAD820286A465B46013599
-:10C21000242D2E836F783FAFCEA9AA74DFDBDD6CAF
-:10C22000BFFABD47FCACD4ADBA75EB9C3A7BD5A93F
-:10C23000345A897D7B3E21C4EAD34F2D20A44F225E
-:10C2400033DB4DB4D4D1923EEF8B6265B65522A458
-:10C250008C90C1D69A6C6B227DBEC2A7277250BD4E
-:10C2600086D6D3A0EEC8B6D27E7DD3453BAFDFC322
-:10C27000EAF49F860C226401FC66A5A5D1E4910B2B
-:10C28000E9EF1B743DBE6C6C276753099164E22291
-:10C2900071B4924DAC0E333C1D673996478B28DA4A
-:10C2A0004EC769D29B364823B1BBC348C79BC3C79F
-:10C2B00023C3CD5A187F361B8ACCE9DAFF93144387
-:10C2C000C85C23593F8CB6CFEB1AACA7332075312D
-:10C2D000AE4C0BC04D265A8ED1EF4AAE68F96C3485
-:10C2E0001D1BFE4D082D09D19263627E08878B10BD
-:10C2F000807B8417E1DA58E14FFE8F5242FCBB0C81
-:10C30000962DF43B0D5D6F1D91285C0D02BE0E2530
-:10C310007C651C9F8418DD5F1809B99E4864201D48
-:10C32000A7D3E42C037C36187D384F3AA2DE41D7E0
-:10C33000C575E7B858847F307D9FCEE7A5163BF9D9
-:10C34000A72E80CF9516067FB55C5FA54F20E4D45D
-:10C35000CDC462A08F56EE5FD86AA4F59577110B15
-:10C36000FBBA5D4346D1F139BE22CD2FD1A1215672
-:10C3700023AFC367670E20D6EC407D88334E51A7AC
-:10C38000E31298C7723EEEB0BAA18AF74734A72AE3
-:10C39000FA5FB62657D19EE22A56D4D3368C51F492
-:10C3A000CF68AB54D4B3365DADE85F44D206120A11
-:10C3B00067D33E99B8296A73DCB58AF6BCA76F5279
-:10C3C000BC7F9C343F348EF6EB888A2924948E5AA5
-:10C3D000A362B640495C766F3EC5CFCD1C8E82F617
-:10C3E000058A71BE89B9721FACEBCDDEC5D7124A82
-:10C3F00057233B9729C65D2ED7B3756BD31DF5D157
-:10C40000F79AE90FE0B398F8F70EA3F4D1E8966C29
-:10C410001EDABC64136B17EF2DEDDC8CEF2D752B42
-:10C420009F2F7F5A59775592EC66CA9FBFB59A13D2
-:10C43000901E8692A16783F82A4007B413FDDEA9F7
-:10C44000C764B72105F093F5F038C48F8EB8ADA15D
-:10C45000EB758A109B07FA3F6FB6B9687DC9FE85F8
-:10C46000381F4392920EA2AC4A3A88CE56D281D956
-:10C47000A65CF781E5CA7557E337D69E7B4EFCC6AE
-:10C480004F52D285C06B39FDF939F1FA24E0333AC5
-:10C4900080CF923DF65613E2894C338E02FCB1F9FF
-:10C4A0001A884306394712A89CA1CF6D6C0872D236
-:10C4B00062726928FDECB04ADA63C6C038455ACFCB
-:10C4C000EB00CF7AC945E0BD28E24E0279D15AEEA1
-:10C4D00049F6D075293636C3CA912F4D8E97414EF5
-:10C4E000D6EB3D85D02EC6FBD2E4C4E73DD23B8BD4
-:10C4F000098597683D85280F8D04BF2FF0386A00A5
-:10C50000A3E3E5C48172F8254ECF5F7C5487785C45
-:10C510004C9AF7DAE9F7BEF998E177297161BF45DE
-:10C520006D4A3C84E04F85374A3656F86E13877B58
-:10C5300019216E4D5A283EA52EC9632E0434740964
-:10C54000B9ED3C5BC2C80EF03986F4FF43F92DF01B
-:10C550004B3B48C1F209BE671914F89EC0A7905B17
-:10C56000E23B06D22C27011FA8E418C956AE1301DE
-:10C5700021310AFFC37FAF52196A8CE31F1B04E30A
-:10C58000C0E409B99C7F872C7026019E8CA40DD72E
-:10C590006FA364DB20D3EFC897A5B4128ACF128BA8
-:10C5A0005D86F52A23DE59F0BCDCD8DEAAA5435D02
-:10C5B00046CE58909E063FD570363E008724E072E6
-:10C5C00049444BEBE3797DAA4BF23D9A02F0BCF56E
-:10C5D000137C773C2FA74249D78F82F9CF4FE8CB06
-:10C5E000E324EB08F85EEDAB59894037EBA566A272
-:10C5F0009ADF91D7E838B2C61F0FFDAA8953CBF452
-:10C60000AE1BF5CD5B920FE77D03B1DF01A5D06FC7
-:10C610008DA4FDCA59B4DED841F5560C94511E992B
-:10C6200096A453854FA23D0A750D8504E87B39D445
-:10C63000C5BAA704DAB12E87D6D7521886C49D5F33
-:10C64000BF3F9C62E1FAD19FC9DA997CABE3F8AABB
-:10C65000137ACBAD9C5F37FC328490BFEA294E8AB7
-:10C66000818F8C2ECD40425253385F169242189FD4
-:10C67000F255660A1D7F501CE5432998EF587FD17B
-:10C680001EC2772AF849335DDCD114DFE652BD9330
-:10C690008ADC85C1F05E003E841DB10CFA02BC2923
-:10C6A00056AC370CE8FEC00ECDA5DE64D0FF629D0F
-:10C6B0009AF4C409F618694FC4EF8AE757A7683897
-:10C6C000BE283D5E009E22AF433ADA43621D2ED45F
-:10C6D0001E1A1BCFE62FF0E708C5F734053E09C543
-:10C6E000678102DFD3C2E29BE3E36499F72958270D
-:10C6F000D97C6810E0797692E346E83FE288EF98CB
-:10C70000A409CCAB5AEE79EA51D0639DB20D78B949
-:10C71000713C93738DAFC8C8FABD5D06B744C7A915
-:10C72000EB7C13EDB39E162A487591F1D40FAF0A36
-:10C73000DFA1F860EB28E059A1827FEE81EFCC7396
-:10C74000AC08E72DE7C1C32DE1F0F0CD6FC83C4741
-:10C750003EC0973FD0971FF86E315FF7DFC7386E46
-:10C760004DA1DF2F7D7F780CE0A75AEEDA3B14F065
-:10C77000B05AB219E8772718882B8AAEF39035554E
-:10C78000E49F74ADCA7DCD360BC547D270934DA6DC
-:10C79000F8C8BA4576B8E9B8FF58BD2A6E212DBF52
-:10C7A0006EA19FCEA0CF258D03E98D6CFFF4777429
-:10C7B000BC2CF36CDB465A9B63A0F3A1DF49F94D17
-:10C7C000B4278DCA89BFE88911F84D97DA7C703299
-:10C7D0001DD71F2BDBC00E4E90C944A02F81E784CC
-:10C7E000680687785EF1F856C9670A3C9FD0EA2F41
-:10C7F0005949CB19B0EE6501382754F94BC0EE11F9
-:10C80000784E4863FD89D69F5C1BC41F65800FDA94
-:10C81000DE0D761DC56763A27E3DE8C15E23AB13C6
-:10C820007B36DABFAB8D8C3FBAA392DDA01FBB294C
-:10C83000AC5E1CCF6326A620B918651F7839859B8E
-:10C840001C90C9365A7C6FB10F8C457C58D838DCA7
-:10C85000DEEA256412E069F5E4CAC171B44C6C6586
-:10C86000F851D3C9AB29CCEEAF3F4D19AF24F0BC82
-:10C870005EEBD15B4CF05CAF787E94E2CD6508D482
-:10C88000179C48BF92A09CB1AD87FE0B374413574D
-:10C89000907DD5C1E711092F8DB15AA2A5F86894F2
-:10C8A00088E35CFD5EFB6F19F1AB9EFFE7BC3DB119
-:10C8B0002A3C7C47003EDA5E75E7B50F83FDD9E878
-:10C8C000D511037DB4FA958AC124CC78FD783E3D1C
-:10C8D00096B8E383EA5A1FE2A3F1F415F8BCEACE56
-:10C8E0001E3DD03D8C63A5CF5747D907DBCE81E7EE
-:10C8F000323E8FC6D3B1C4151FFC9CC993C0F80942
-:10C90000D8FE2C2090D2ADAB53766FA3AF3EBB4F79
-:10C9100033694B98F9EA5319FCB9895AE4973C0FEB
-:10C92000B16F0EF37DD16F501C95D72686E79A82A2
-:10C93000D0F97554FAE6C2FC2F9F48ECE1BE779A15
-:10C94000D38B9877479C6F31A7FBCC1A7350DDA22D
-:10C950005CC7442E173AAEF625C3F8BD93991F1F46
-:10C960008A2736CF51DA6609F05191E42C02395208
-:10C970003F8356289D0C9EEDD138F3037C1769DD6B
-:10C9800003F8A6FE57C9B9F0ADC77631DE570739AF
-:10C990005F12BB49A2FC349FEBADF95B975F4B651F
-:10C9A00067BF1FF3D526EAC7D04F7C459ADF3443D3
-:10C9B000BD4D423F658193903554EE2CDE56B21E3C
-:10C9C000D4C5FC2442AE8863CF6F83729D2EA06FC6
-:10C9D000F1FF7612AC1FC5F76FBE5B69BFD691BB86
-:10C9E000BF05FBE7AB834C3E508D867EF8E23F2AC5
-:10C9F000C7ABDB7ACD7198679DCA0ECA02438FDA46
-:10CA00002185A9DC4F1B4546811E58B9ED3B7D8C25
-:10CA100035321F7C4DF93D3D03E4A505CB8A547B9F
-:10CA2000592AC4190EB0793A529DA353219E72809F
-:10CA3000CDEB54FD29A6271E4B40FD6400614E7FBF
-:10CA400035CC32BA5BE93CEEA4E2248AE2C76060EE
-:10CA5000F690B0036579951C43DB477FB93A0ED653
-:10CA600037E1B9AB26C17889CF45DB019E8D15F63C
-:10CA700022881B6CAC31D95AE99046FA3EE80FF790
-:10CA8000B3A3DF180A5642FBFD95C380ECBA5EF7EC
-:10CA9000405C6583E6DBBDC368FF0D57105B2B0967
-:10CAA0007CA7A9ABE645984FF234A66736A6D88B8B
-:10CAB0002C41E3126ED73572DCF5EDCABA6F2C5DEE
-:10CAC000DF47F7A1594DE14B1D08722397B075263A
-:10CAD00067289E289DC0B783EDD71EAAAF4856A0F1
-:10CAE0009EDB2E7974149E868E1735A00FEB6FF7A0
-:10CAF0000C9A057AE919AD6D4BD0FC12FE32A4D226
-:10CB00001A13D047B3240BDA0BC23EBF91887FF9CA
-:10CB100048373339DDDCC8EDF259D10CBF0B882D15
-:10CB200019DEBBC948623494A56655B597A1BE5AB3
-:10CB3000AE8B053B096009B7DEA28C145F6A7CCA24
-:10CB4000EC92E8BAF74AFE4C18E46B88F9B03893D7
-:10CB50007B4B4AE838EB5399BC68CCE476623AB137
-:10CB60009B29DC8DBBB3366FA44D8601741D8B51A0
-:10CB70002E19CB8BD14E3682FFB3F4B5288F141308
-:10CB8000C00BB1D88B34102FA81D5EBC116CD32301
-:10CB900054BE5006EBD5F992918FA9DC91A8EEFB1B
-:10CBA000CF2D936BB494EE1A87523B8CD6DF4D9DFC
-:10CBB000C1EAA9BEC51A5AFF614B33ABE7FA8E41F1
-:10CBC000FDEC965B6BB4942F1A8B7D8B655A1FFA24
-:10CBD000E45DAC1D1C424A58594FB6D5B8E8F85F21
-:10CBE000C772FD6EF3CD05FA697C354BB33108DEB3
-:10CBF000F83426B7BE8E62FDBE4E21F36A01DFD93E
-:10CC0000BE4C98A7E8F7AF546117B76129E014EF5D
-:10CC100091A4F0E3FF99BFB7B48ADB25D16403E0A8
-:10CC20008D2E932B86E27F4F57D616E8FF406A1C65
-:10CC3000C7171DA734308EC0A3184F7C7719E85D45
-:10CC400090C73A166715EDAFA532F949BFB30EBFCD
-:10CC500093CFF0DF583BBC08D68DAE9796AF979632
-:10CC6000F9AB9BB13F8C1B5B88F2BF444BFBEF39A8
-:10CC700043FBA704E6ADA68F7D9C3E96B652418845
-:10CC8000765A1AD2D18468661F9252251C43399E67
-:10CC9000E3D362199CFDEB3158C2EFB4723C0EA78E
-:10CCA000782FB878B83FE6F3F9B9E10E5A2FBB0CEC
-:10CCB000ED9D395B82E121E47EC5385FAF55BD57FC
-:10CCC0004E1910E6119786EFDD19458CF89C6CE93A
-:10CCD0007F2FA590D9A560AF3670BB9AB8AEC0E0E3
-:10CCE000423D971A0D1BBC7A2BB4B74B7637D067F1
-:10CCF0003A850FF05B7B6D2987CFC2E1B330F8DC5A
-:10CD00000A3A2587FCC9D3CCA1F4DB8FF7FEF1F2F8
-:10CD10008BF9780ABE0E371EF047A4F530A5FDCC7E
-:10CD2000EB21E6A9C2673F9E55F313F8047EC6F7D0
-:10CD3000F295F4D84FCFA9621D557C9D7289DFAB67
-:10CD400060EF35FC96AE23D82756253D3774A4688E
-:10CD500016E407DEEB84B52C0BC4E946A6717F6FA1
-:10CD600038190EF2DB55C9E2A9AEED065BAB15E34F
-:10CD70007B2569E1E37BF85CEDEFF5C5EA89847614
-:10CD80009132DED09768F3DAC14E3D496CDBE8B8EA
-:10CD900063557607ECDB6C3705DE0BE81365DDC504
-:10CDA000F920347EE44F86F9951A2A77586D845C11
-:10CDB000F7E453289F4B0756AE4AA1F5DA279F6642
-:10CDC000F56195DF418866DA93CFA03C2FCDABFCAF
-:10CDD0002E15EA69CFB2F609F61D32EE383C5B3308
-:10CDE0007148C07E989E6665F6479586001D19E4D9
-:10CDF0001536D093029F91CA5283A6399CFD3AB74B
-:10CE00009F9FD9BE4639D7CFE5C29FF76915FE7CF3
-:10CE10005F8CD1250F847D2EAA4F29BC4BD39C0B50
-:10CE200001FF4DD13D73C114BE3DFA533DD843922D
-:10CE30009DDA1B101FB15AC86C3A4FA967A303EDC6
-:10CE4000C06536A316F1C9E35514B6B3749CD77602
-:10CE50003F73EB30F61907CC6334E7FFA6DD3FFDE7
-:10CE6000F809E8D1AF4D3608078EEE7A6415D85729
-:10CE7000A3BBDEFE89E95B13EE5789798F86B82361
-:10CE80007D5EDE69C0F98FEECA5904FDC7BEDF952D
-:10CE900006F431BEDBD30AE2A06FD7CBC39CC1FB43
-:10CEA00057E4B87436EFE2ED8B7E7C7CA927605F97
-:10CEB000527CDC919608F838B318E28BBD8907D70D
-:10CEC000FBD04E1BCEE299FC7D6A9767039F9F22A1
-:10CED000036CB0BFD06766E3A8E39C476A287CF484
-:10CEE000F9783F9D4190DD3CE1B4910A9040BD82CC
-:10CEF000C42AEA55C6218AFED5961445FB55493900
-:10CF00008AF6C9D62245FD9AECD18AFED7D92A14D1
-:10CF1000F5EBCB272BFAD7D86B14F5224FBBA27FAA
-:10CF2000C9BE4E65FB212BAE4349B7A30AEC799BE2
-:10CF3000D7D90AE5E53D6D5503AD2424BE5BEA7300
-:10CF4000B7C2F3B1679ACB3C2434CE4B9639715FAC
-:10CF5000C000EB2207ED135478911F7B35366B70C0
-:10CF60003C77F620E7ABB04E6F4914ED14D9571853
-:10CF7000FDF1B05ED5F3EE9163605DFC04E35F1DEF
-:10CF80007ADFBD6341CFCF91D1EEEDD012B41F3B1C
-:10CF90006616B821067844F2BDF409C8A939D1282B
-:10CFA0004FC6530B17E186BD5009D6C9A980BB8275
-:10CFB0002C55ADD30A45BDDAF25B45FFAB92D62ABC
-:10CFC000DA275BEF52ADD3FD8AFA75B64754EBB45E
-:10CFD00059B54ECF28DAC77FE16B05369AD0E39278
-:10CFE000CD74FE638EB455C1BA8CED76CD017E2929
-:10CFF000F5385B5184EC697E134A0FF5AB20AEF532
-:10D00000464B12967B5AAC1897DADB928DE5BE162A
-:10D010001B3EFF5B4B3996EFB4D8B1FC7BCB242C85
-:10D02000BD2D0E2CDB5BDAB1FFF6964E2C290647A0
-:10D0300080BE4888E7FA87D6C1DFEFD5F81A61E7E6
-:10D04000D59FF6BF514EF60EF0F542FD76D76994A6
-:10D050008B9FA413946FF119ACFC29DDBE2ABD8C03
-:10D06000C914E44F9D6903E881768DBD08EC6B6DB2
-:10D07000BAE60FDA1184DCB1D6916489657523AD07
-:10D08000E362836346347FB00F27E44FA03270938E
-:10D0900045530BF5BE28D67E364D53EB42FDC0F608
-:10D0A0009DA705F69DB5E961F69DFF74C26A867875
-:10D0B000CBC133596680EB208F2FD949916E3E2D1D
-:10D0C0002BB4453AD08B47547684283F335598018A
-:10D0D0009E768D6D3AD829AEAB75641B9517B51247
-:10D0E000F347FBEDC074666FF75D67407FE790C65E
-:10D0F000BE08E89CCAE927005F195BE36A41AFF408
-:10D1000099FDC98087B4ADB1AC9EE87F42B205D528
-:10D11000750CCEE15B2DB5AEFCB070A6C07CD470B2
-:10D1200066A6F3FD068F7D04E85F513F54636F00F0
-:10D130003D71A8C29E01F339E83020FFB81C667724
-:10D14000060839ADBD6C7A50DCC59DAEC3F7A6E9C3
-:10D15000199F919B64F7B6307EDAEE7466EFE3BAFE
-:10D16000813F776334DAE18734A46E7B183C7EC05C
-:10D17000F1F3CD80F0F1970FD3991EAC9C6AC6F104
-:10D18000FA5647E1BE6F9F230BEDA0BE668A25CA03
-:10D190001F7D279A4FEEC47683D812C3FDCD595C0C
-:10D1A0004EFDA96BD50F8769FF4F5747DB50865B54
-:10D1B00072513FDDC43BCF8937A2DD32A7764425CB
-:10D1C000E8A5597C9F6CAE593B08B7CBB4B17A0B3C
-:10D1D0001DE76653D17A50FF8B136AF4B1B45E3702
-:10D1E0007CC57A2897A5DFAF8FA3657DFE8BEBC149
-:10D1F0007C6CA0AC5586FE92EFDD163AAF796B647D
-:10D200002BF39FB85EB32FBFA87319820E018F4016
-:10D21000A714BFE8171EE1F816EF1DE1F85A9CCEDF
-:10D22000EDB602527056B9FFB30CF8A167CEBB99A8
-:10D2300011E2F4CA766EB77DA067DF5DFEB4CE1D45
-:10D240001C4F12DFFD289DD9D787F4C42E811D778E
-:10D250009319E9A370E677B79751F80BBB2C1ADC4A
-:10D26000BF1772DC4B307E5FF68513E5DCE53DBE13
-:10D27000A70E13A4F34EE093F3E9A9A9AEB5A81F36
-:10D28000467F4FF50FC8C533CE4F0FA31CACE372DA
-:10D29000B019E5D79E963558DFDBE2C2725FCB0648
-:10D2A0002E07DBB0FD9D964D5C0EBAB91C7C1A9F13
-:10D2B00077B5CCC472778B93CB41B6BF5ACBE969B3
-:10D2C0007692F33EC093D8C79C6674EA005F7F7D78
-:10D2D000C44064D89FE832209D520E78E2D10438D1
-:10D2E0003763B06CB4869E9F51CBDBFEF557EDF7EC
-:10D2F000AE4EB23F0AFCDD7F5E06ECB3CB22D3CF4D
-:10D30000416235833CD9917E432DC8E78356AB19E2
-:10D31000ECD68EADBC6EB79A75B4BE337D06CA9797
-:10D32000834EABD940EB2F6D9DC1DA5D567314ADC2
-:10D33000BF9C3E93D5DD0437B7BBD2E7A09CAD20A0
-:10D34000D21EE0872A63CA442AAEA97EACD8037CE9
-:10D350007055D2FC89C00779E956A4C3C9D6B57BFC
-:10D36000A07E4DF6666DBC15A2A145EBE0BDCA845A
-:10D370001A2DBC3771F88A75F0DE95E9F76B83DFFB
-:10D380009B94FFE23AA85F6BDBAC057B300FE45661
-:10D3900062601C5117ED42BE8AF35D23BB1C28C797
-:10D3A0000B3B1D28C7055E2AA7D5DC0171BAA64E26
-:10D3B000C922C13CA649FD9BF612B5211ACF506E79
-:10D3C000A172F6EDF4BAB8B514CE26A88FC1FA1F33
-:10D3D000D68697BBDE70FAE543CEA7A0376BE83858
-:10D3E0001F52FE81F368360E5F53D77CF37CD4570F
-:10D3F0004E33E8D7515C5F8EE1E5325E36F1F233B1
-:10D4000093FD63F8CEE791F9FA4BA00FCAB78BD919
-:10D410003C42F85AD9CEF9FA38C72329F52743BD3B
-:10D4200081B4619CF07CE7BC9606FB6F29705EA21C
-:10D430001DCF61A8CF4BD4132F1BAF5D75DE82F8D3
-:10D44000F4B80FDA19F41CE511F73F0630B93713B9
-:10D450008435381D1914EEECB0706B3312CF09B758
-:10D46000B29DC3BD94B8F17C9B1A0EE24C44DE5AC7
-:10D470006E3A84EB190A8F2F3C3C217030FF5D9C83
-:10D48000671171796A07256494811C341388DF045D
-:10D49000CB89C3E790136A79F473C9B973C89B1C2D
-:10D4A000C09B5ADE88735AEA52D873B4EE82737AFC
-:10D4B000AEDD5118A73F697596C2387D95FE1F35C0
-:10D4C000E09F25F890CE7E3FCC7939E041D2B3FD84
-:10D4D0007AFA4626ACDB098DEBCF601755656C41B7
-:10D4E000B9D30BCA81F2E3585A07BBE7F1A18EF119
-:10D4F000F01EC966F413E95CE7C40CA68F424BA288
-:10D5000038DFD8B7F9A7648C639D87DE23E1A15A81
-:10D510001EE77381BC2F8F4693A747221E89DA7FAF
-:10D520003D1583D08EE819A1D742F973FB893D23BD
-:10D5300032717CB5BFD833A4DCC8BE7BE524283B60
-:10D54000F5CE4DF3C14F1A6D403FE93D7E2E704A36
-:10D55000343B47F51EEC13D37E538E9E4900FDA548
-:10D56000F6377BF6CFAEB41686FA9D14CE890067E7
-:10D57000FDE79A3BE0D9C5FAA1F56B7E24DA78BACB
-:10D58000AE6BCE106DC985F8A5440671517CC4F60A
-:10D590002694655F78E30AADE07F0AFB81FBA7E78D
-:10D5A000398F54EE67F6C28433245B5B0A71A6019F
-:10D5B000B87F2395BFCDFC565E8A7D91716C0A645D
-:10D5C000AEC6E4D6A72ACE23256969395BF68D82DB
-:10D5D0007A2FF1E23E89DA9F7D8BC7A1A85FFB20FD
-:10D5E000D0ED7A7E4E89AE483CD06FF5EF3E9A7B07
-:10D5F0002BCA8128B487FAFDDA9D1A3C67D0A1B501
-:10D600000F1C0F7EED9A0CDB5A5AFFCC9BF8E06B97
-:10D61000B46CB2FC887813FC5BBFE63BC4A7A8F7E8
-:10D62000F0B86F9B8EEA1F5AD6FFB78C7AA89E90EF
-:10D630000DB86EE40DFDCA20BD48DABFEDC7FF4846
-:10D640002AF76A0081A8172BA7DA69BF1AEE7F10A4
-:10D65000F226AB73BF8BB852A7DAE9B83589BCBFE5
-:10D66000EB21561F21DA1F66FD33C478FFAAC5FAE5
-:10D670001051E7E3E588FA7BAC9E22BEE767F5022E
-:10D680005137B3F1CDACFFEE6D3BA6823D22E4FDF8
-:10D690009E0CAE1F8B48113F9FB30FE57FE47329AB
-:10D6A000CA76AE1FE63D23BBF423617D2647BF0B40
-:10D6B000FCDD2EE119BAFADB7418EFFE26AEBD7060
-:10D6C0005590BF22CEB138AACC76B0FF1A5ECADA26
-:10D6D00022F3733D607F10BE1F5D2D9B707FE2D4EF
-:10D6E000DD4CEE47B2DF16AF794DB19E21EDB2C4ED
-:10D6F000FC71D8B8A3DF3B79CFE0CDE85FA47B71A4
-:10D70000FFFC588624F6E949795CE0DC58421AB1FE
-:10D7100083BF9AF03295CFB0C65F78511E2F7E99A5
-:10D72000C57F1B1E7913F5DE02D98AF1DCEBF29D71
-:10D730003D809F5EB317E38A8BD7ECC679FD9F1CB3
-:10D740006E3758FCF9C1F8FC3E14FFA7CF83FFD316
-:10D75000BF26FED571E765A63D08EFB28B3CDFD64C
-:10D760006B66FBA236BE4E4735D6511C5F719910D1
-:10D770003F5FE4CD8C95E1F0B177103BB7F44E19E3
-:10D78000F845A79ACD04D67DF6AA7F143AC3C47D86
-:10D79000D5FEC0CDF0CDC400BEAC9921F84DCF2C44
-:10D7A0003B277E95EDBF307E076B7D7A1BECA31E79
-:10D7B0002138CE28EF517DF0F99889994C0F0FEC64
-:10D7C00064FB46EA735F1333CDCC6EE2FB330DB5D9
-:10D7D000EF8C83FD19C10F13A2493BC4DB295DDB2C
-:10D7E000385DDB80AE05FD06F669E87B61F82B400D
-:10D7F000BF4471AEEF9A4C6E5F06F07A7DE6B9E9F0
-:10D8000056D9FE0BE3B583DAC3B8AFB9330AE329BF
-:10D810006A3CAFE47815F86ECD64FC1F09CFAD808B
-:10D82000E7C49F1FCFAD9956453C42E03B927E52E4
-:10D83000AF8F9877183E2DBB143ED5677339A5F589
-:10D84000E17953F5BA6F0CE5A77BCFC34FF7FE9A8A
-:10D85000FCA4C69BBAACE7FB9DEAE7CF678AF3015D
-:10D86000BF0C1EFF7F8BA7CF697E5DD13E6FCD7E43
-:10D8700045FB7CD701457D9CCF5B05642EE2E357D9
-:10D880009CF0BF09F54B8DB3478AAF4FD9B1440324
-:10D89000FB6FE55E16DF6FC8764A5974DDDED3B8DC
-:10D8A0005BCD14AF9777B7CBB81FE62EC27DC055BE
-:10D8B0007C8EDF8DFBD7A7B752BAF98E1830FEE900
-:10D8C000793D476B2D08A5838AD332B107D98915D5
-:10D8D000C6582DD85315D4520E4737FA2C467778B0
-:10D8E0001E88F2FB4C23D125503E9F3953C2F34F83
-:10D8F00033093B574D4B8F93B64FD1128F81D66B67
-:10D900004C5A8F01F7FD58DEC374364D62D01217A2
-:10D91000B4938478F483A7C1433A5FD92EE379B6F0
-:10D92000E9E56CBFF02653BB0EF4E98DFB6E3F7941
-:10D930002B6D27EB5C65ECDCB6C863FB587331FBE1
-:10D9400080FA2CC6E77D12DF5796743638E7AA7E38
-:10D95000EFE34C06EF1479AD0CE75FFC0708DADD66
-:10D9600082EF287CFB0CC52C4F630CC049749EAC25
-:10D9700018B09FEFAF82FEF587AC8897A6F2B58509
-:10D98000B08E4D13A5CF0D8501FFA669CDF768A711
-:10D9900057CBCFB742FF53475868FCF21E970CFE97
-:10D9A0004A207EE99B0B7C793E3F48CCBBBBC583BC
-:10D9B000F4F469CB3E2CDFBBE2ED32B0337C2DDEDC
-:10D9C000B0F1CB4B8D17883881881B0839F0D96DA1
-:10D9D0005583812E6D595C2E18A561201788969568
-:10D9E000425E8ECA0A91AF63B2CEAD5795EDBFB01D
-:10D9F0007CBD503AAF4F627A514DDF6ABA16F44C93
-:10DA00005F2B93E8776FA2F61EE8D559C455504FA7
-:10DA1000E5ECCC256DBAB1D2A5D3F532D317C92424
-:10DA20004CBECAC5CB732BC22F57C9E81F88F30A57
-:10DA3000621D1AB242ECA115E759B715BFE6BA85C7
-:10DA4000EAB52FE65E9A5E230A7BE0EE50B8DBCEA5
-:10DA50000377DBAF0A778A55E4D1CC953581BC11C9
-:10DA6000384F0C765C9F9BE545D6A5B4C5E0E1CC6C
-:10DA7000727F0CD88D4B77C94887446BD70EA1F4C1
-:10DA8000BA84D36B0FF17C00F4B864DC12CCA7AB82
-:10DA90007B2CFCB9E246DE7F99A9430F702EDBAAEE
-:10DAA000ECD7C8CF15D73FAF8C8B368EBBEA388CFE
-:10DAB000DBA83ACFF35216CF4B2C26C5ECDC85D22F
-:10DAC0003E5597BD2D4411AFEC3DD382F180DD5919
-:10DAD000FE075CC383FCFFD0F5DB97756E7B4ED9E8
-:10DAE000FE2BD3AD6CDE8AF955174BB76B73EDFF88
-:10DAF00080790B793C1B6413FDEEECD70C6E17ECB0
-:10DB00008F9659597C5372B7C27E5BDF4F04E3474F
-:10DB10000B789C33527EBA386F30FA90BB959D37A4
-:10DB2000B0CB902F3A6A9FA30AB62B4ADE69467B98
-:10DB300024E2BE95C8B3E2E7872E54AE89B8DEA8CA
-:10DB400013CD6867D9BC16B487C69C6E7F13F4E307
-:10DB5000CF15EF16FA706C3CC35BA9CF81765EAF30
-:10DB6000CE53F621D809AF4485B51362B3D9FA4D27
-:10DB700075CDD7B1BCC390FDC0D86CBA1E53B9FCEB
-:10DB8000D718ED3AC053B5DCF3E00CA01FAF8CF111
-:10DB9000BDD5BF7FFFCF8F5ACFEFF73759BE43BBFD
-:10DBA0002192FDDFA461F917C555563CE707FE1425
-:10DBB000C4F744BC4FDD7F426E651ACCAF5A1EE7F6
-:10DBC000B5C37C36B1F9445A9FA635DF2AE28B9162
-:10DBD000BEDFB4ABCCB220880F6ECE9684DF613945
-:10DBE000660CACEF85D2C178FF4C85FDF3FFBA5FC0
-:10DBF0003145A6A625D59F05929BD9AF84D9B1B34F
-:10DC00008917CBB9C48FA593B0F3F70B880DCB9BC5
-:10DC1000793EF3811CE74C58973E9D7F109E9F7C78
-:10DC2000E9DFF9403727AF18DB06DB5EBF941DD76D
-:10DC30005764C5EFF7EDFC77329C83399F5C589DA4
-:10DC4000645F9E1D66FFF9EF15F24C966FF518EABA
-:10DC5000891A7E1B0399C8F6D1484A0AD243402E3E
-:10DC60000EDE2CE422ECCF167CAE61E749964AEE3C
-:10DC70000CDAB5D3A741D62A5894E296A1DEC1DAD0
-:10DC80000B1A62DD12AD178C8E62ED2B62DD104730
-:10DC90009F437CC88FF3A82884723E61726F21B1C4
-:10DCA000B37C07E24F053B6C5197919DF727BE74FB
-:10DCB00090EF8511FC9FB7B299DF3C3295C9F39183
-:10DCC00095CA38C53D5C0EF4E6549EC8A6E5A96C1D
-:10DCD000FBBD80979171DE8D0F9462DC9E80FF709A
-:10DCE0007CF46F71BF51BC97985BF900F47B416283
-:10DCF000E7D35DBB0C783E82BE31C81174AEFF40E5
-:10DD00004ED523D0CFCDED928878257E45FE6C8010
-:10DD10009F5C38BF91E07361BC9C3E28C7EF62FDF9
-:10DD2000C5ECDA69EB4C18E37781DD9B98EB7C1648
-:10DD3000E7AF27C404F37FDCE0DE82F6697332C408
-:10DD40002B973C61D080DDF01155B79087F2498B5D
-:10DD500011CB7F503F18CACFA81F0CE5E7D40F8620
-:10DD6000F29FD40F8672D1E922AA2C283FE5D8DF92
-:10DD700064F41D3E4FAB4BE05B7C7F971EBFDF9B87
-:10DD8000E344FCF6AFF72BC40D9B3A2FC4FA87C6C9
-:10DD90009D83DE22CB198617B15FA86EDFCED7B583
-:10DDA000B0438BFABDB0D317B338A8DF816C3DCE3A
-:10DDB000B360E7179887DA6BE9C7AF5DA2204FD150
-:10DDC000B0FA81EC3AC46F6F8EFD04C04DF9FB30A0
-:10DDD00094859DEFFF01F27FE8F878EEA04FF23FC7
-:10DDE000847E800A0E351E045C2FC47A37C2FB2F56
-:10DDF000EC4C0548A8BC218C6F808EA470F0AEC599
-:10DE0000F95E6FF097425ECBF567E5B0E78C7B7308
-:10DE10002A10CFEB04BD093CF1F5BA54BEEEDFFF8A
-:10DE2000E6744AC43D1E203BADA087CEC480BD57DA
-:10DE3000C3F7F73B3BD2DF03F85CFB64926145FA22
-:10DE400055F0DDB01C4627A22CD8A577C03ABDB04E
-:10DE5000EB58FACD265C97F445B47F744E8622FECB
-:10DE60005830FAA7FF782001FB5BE0533792CDD5FD
-:10DE700070FE6496F1F5BF0248732C9F57C3F99367
-:10DE80007949D25E28E75B53AE847327E27CFCC2FB
-:10DE9000EC8ABDC04AD7DA6AD04EAB00E112A40FBB
-:10DEA000AA8CD1B029D85FAFB6C42BEA57250D5341
-:10DEB000F49F6C4D53B45F939DA76817DFBDD65692
-:10DEC000A2E83732CE9F0AFE198503F9816C93F1DF
-:10DED0009C5EC1CE4357E7D1FA94A7A6DBC02C794C
-:10DEE00081B74FD95EE586F5E8A3F8D45303EA4439
-:10DEF000F95D0F3D0083A9ECFFFA5D4FEEB55B2F96
-:10DF0000C2FE8F60F70B39BBBCCB580672F642FDE0
-:10DF100000F5FA8CCE51FA0591E8A69F2F242BA389
-:10DF20009BFD32D916866E08B99DD3212BA71C64A0
-:10DF3000F963172BCFBE0479161FE08FFE52159799
-:10DF40001BA9B7BDB70AE2F4EFCA04F3F1785EDFAC
-:10DF500062F85D0ED03BB979F31D4312F0B90BECBA
-:10DF60005CC82FB5D3F157E470FBA9FEF53B86944E
-:10DF700006DAC9EACF15FDC96DD27A457D5D8AB250
-:10DF80007E77C5FAE0F723C9C5C59BE6EB9D98FFF0
-:10DF900029D9DD61E483984FF51B5178AEEF3A380B
-:10DFA000AF421F35961ED0C23EEC7511F4A8903FCB
-:10DFB00037CAA4395CFB6D392CCE7FED1B51780E2E
-:10DFC000E662C7FD88E212CF19BECCF4E84703BD74
-:10DFD000DAE075BF93CFFB64D9FDBFFF11F6475F51
-:10DFE0002178EEF3642C93FF851DC7351AD0830387
-:10DFF00018BD145A7C1AD02B7D75D12E38D7DFB4BA
-:10E00000D4CCF25F52FD1F18E9D2DF97F3CE1F8DFB
-:10E0100074DD3E8624C820BDDA074E11AD6F7AE666
-:10E02000ED69EBE8FBD7BC11E5D15C023C9BF8BE87
-:10E03000C4C84AC6E773816EB87E81187BD31DA41D
-:10E040005FDF805C00F8A1FE5ECE7B87FE0876F87D
-:10E050007EC6E770C24EEDDFCF0AF2EFC9638C2FA8
-:10E060008DF4879D5352F1F79E36BDE99C7CDE8E80
-:10E07000E76E2E94BF77E4F03CE1C8FC7CF01ABA5E
-:10E080003E4DAFB07B2D4E7565605E6C247DDEB479
-:10E0900049463EECD75F5DF22437EA29651EBAC0D7
-:10E0A0002BB1DB903FC5FD512BC7FFAB16F4E6CA81
-:10E0B0005D5A764824D27736C8C41AF49D17761B69
-:10E0C000EA30CF8DCFBF4FE8EB5D3FC455E4B3726C
-:10E0D0006D18BD47F5B42E01F4748D847EE5E15DC5
-:10E0E000832B014F8725E2B162DE163BA73C950DDD
-:10E0F00007CF4D786F4952369E4F16FEA5F02BA7DD
-:10E10000EF9A9E0176E5071D0B0ED39523C772D2B9
-:10E11000908F661017DAC187631D23202E31859FEB
-:10E120000F381CEBEF01B97C787CB404FBFD74FC68
-:10E130007530BE80EBB0CE3182DD3F21CE25E75E6B
-:10E14000D27D71D5F26D15D7C0FEF66C6201BFF2BB
-:10E150007A99D9B9E42F8C3F85DC6B92BC7130CFB2
-:10E160000339B5A773289E06AFB997C75539DEB4F2
-:10E17000EC1CE285DAB9FDFEECD312BB17C5C6EC88
-:10E18000FFC671DF3C3803F2E4A8DF2DD1F92CE89B
-:10E190007C1DEFFF51FBD9FDFECEFF309E1AEA2F0A
-:10E1A00039E27283E2E46ABFA9DF4E17F6DE367603
-:10E1B0004EFECDF10FF72EA7F5D5DBA2118F5F3DF7
-:10E1C0006170811CFF6A8B01FD9FAFE2FCDDABA09B
-:10E1D000BEBDC0E6C2AFD914F7A32DD1583F04FD90
-:10E1E00043FEA6C37B3D8E3F6EF0C0798FA54FE600
-:10E1F0006C017FEAF808EB73CF433CF0B944BC678D
-:10E200008038D9FBD7717E04FEB252D343FE2F3340
-:10E21000DA114B770C413926D6EFC4E3519847FF0A
-:10E22000D5BEA903215ED6A37911F378886C7281DB
-:10E230003C5EBE250AEDC035166729C05FF55FD785
-:10E24000CD2881EFBF9F48009EBEAE1D18AF0CAC1D
-:10E250006F78FD7EAA2B8DC9817E7DCBCEDDCE83EE
-:10E2600073B76978EE760C8CDF40C4FD8BECDC6D07
-:10E27000B12CD931EFE09EF079E4D7E432FBB15E06
-:10E28000C44FE2893109F8D04910DEBE7BB2B680B6
-:10E29000BFB330378E7FD7CFF32505BD7537BE8628
-:10E2A000F113033BEF17157E1F7B462ECB2B5E6CC5
-:10E2B000FC5E11BF695CF39322AED2984F50EF160B
-:10E2C000B75A4B56D07215C7F3EA54C74D00DFB2A8
-:10E2D000F6FB5F7A07F1F2D86F3E86EFEE3361DC32
-:10E2E00086BCC3F0A7F667161BBFE5FCB4596107EF
-:10E2F0001F7BE4433C6F726C675E21ACDB02D97B11
-:10E300000CEEE5EA357B3FBD9596DBF71DC47551F4
-:10E31000CF3764DF5E6272A51EE08887F32E8EE63B
-:10E320005CDC1766FC7E746301E24FC473FBBE0ABB
-:10E33000EF6F89798AF1C5FCC4F8A2DFFFE2EB75C3
-:10E3400052EF2D04FD9C06FB166581F69331DEC26B
-:10E3500058133C67792D27E3683D886E7EA9FD9DA3
-:10E360009B789CE78866ED2D7A4A7F3DED0FE89C0F
-:10E37000C172F422F775C47CC5B9529147FB9FB9AD
-:10E380003C9E3D828C88907FFB646E59D8FC5B7C00
-:10E390001E29FFB63FDFF607966F2BF26B4BAB34AF
-:10E3A000CDC179B6421E96E6D1E7F9B0EFAFD4EF12
-:10E3B000A52395FD23C9C7F1796C1D4BE3C3E7BBCA
-:10E3C0001EE2EBDC4A3CEC1E42AE17C772BC8BFB74
-:10E3D000BF849DD2C8E5B6C8F31CDBC5CE6D8EE503
-:10E3E000793B540A609E6BC83D6F4979A857C53D7B
-:10E3F0007D121D6B765CB87C612FCEE30AE2C7D23A
-:10E400004E2C5A2829FAB19C481C585E499AB19C56
-:10E4100044DAB0BC9AB463792DF16249723DFCBC18
-:10E42000E76D2CCF74F2120DE8D7D219E1EDE21F9F
-:10E43000CF8B0717DE2378B178B892B0FBFE42F09D
-:10E44000313C1BE95B8D0F75BEE678E2C38B4B2632
-:10E4500000E1A6811F6CC5F3AD55C48EF5EA0BC46F
-:10E4600043B9CFA965F9BD2A7C5485A78BB31C1F7E
-:10E470001B40779605D6A9348FC901B15ED4114BE4
-:10E4800002F9AF5E47F1BC34BAF23B2B1511C3F26F
-:10E49000EE988E79DC2595ABD268BDE0B907597D41
-:10E4A0006CE50EC8F31E99F7F074CCFB1E5959A207
-:10E4B000B3C17D729BA64FA4ED4E7E6EDAC9CF4BE1
-:10E4C000136791E29E2CE7DA5BF0DE31E708930DEB
-:10E4D000E01479E1721ADB5F4D9EE4794347FBED6E
-:10E4E000B23807E595C139734F8C15EC84B5D578F2
-:10E4F0007FD49D7AD65FDC6723E013F7DC6CDF9E68
-:10E50000B74A4A3DFF3CE8F8E97989309F0CCC8F47
-:10E5100073EE94783E5CE5E099546EF4787504F2FD
-:10E520000BC4F72CA9CE1C980F81A478CA17C3B8C6
-:10E530001EEED99E9707EB549AC7F30713524A0071
-:10E540008F0B521DA5D05FE44597C2BA24462E67B3
-:10E55000E7D98BA1BFFAB9C8CBAECE7396437B5334
-:10E56000F419CC37EB2D7A7FBD2F25344FBDD54E16
-:10E57000DC7A942BCAFCF4BE457ABCCFA9D4E16CFA
-:10E580008523CA97CFF68FC27CE13C67158EABF727
-:10E590002517D1F7FE3895E5BFABF3BD77EDDEAFBC
-:10E5A000C86F177CD69FDF7E8AE5B707F8EB9155D9
-:10E5B0002428BF5DF08DE0BB3190DF1E03F59C4544
-:10E5C000D06FFCFBDD98DF3EA1DBC7F3DB3F54E6F9
-:10E5D000B7DBFF7549F9EDC7F9BD6FC78DECBE24F8
-:10E5E000719FD4CA9D6CFF77A5C4EE935AF9277624
-:10E5F0009F94F00BEB387C0DFBB7AD877DBEBAC79F
-:10E6000016E27D5484DF876AA53FC17EA1B89F547E
-:10E610009D07D304FE20DACD1EB4BBD4F9304D8F54
-:10E6200055A13FD8A4B2A36FC9E3F11DAECF08B77F
-:10E63000FF96F077010E13FA677AB43B573EBECAD5
-:10E6400066813AE72BB2EF7912DC9F3C168FB4203B
-:10E65000F86CE90609ED5781BF914F19EC789FF1ED
-:10E660005383D16EA5F636CF6376337F9BD20A9C57
-:10E67000877F21D69F0A76F20BBBB26D54C29257A8
-:10E6800023DE43FDBCEA1EEA2715F7509F82FF8177
-:10E690009D7642E386714691ECFBC6D17AD909ADED
-:10E6A000CD6D0DDCCB7CBEFB8705FE0D7CBD2EF653
-:10E6B0003E62F5BDCF22FF417D2FF19DFC5EE2F170
-:10E6C00011EE2536C85D32DA0FDF6B15F7135FCE1A
-:10E6D000E12CB71237DCF73BA647AB58FF725F1B44
-:10E6E000017B28EA90561147305895F597F3787CCE
-:10E6F00080DF2F128A6F533F3E0D88CFF487119F22
-:10E70000AAFB9E059EFAEF7B1E6E42BA1FB37F875F
-:10E710000CF2E062EFFDFEB5EFF93EDFBDDEEAFB95
-:10E72000BAD5F77347BAEF5BAC7B9167A5A2BF7A06
-:10E73000DD4BF6FD4E791F355F6F17FDF939D7FBBD
-:10E7400007D57AFF1B2E40A37CF8F7981377035B5D
-:10E750004E896672ADDFAF1FA7433FEB3D6B7C95E3
-:10E7600019F89FEB2907D753E4B676DC8777707AE0
-:10E77000B179D93982E223ECFE8A521F3B4F30EA4D
-:10E7800044F8FCA0EBCB25C5FE6EE8FDC52CCF7888
-:10E79000EC19764E4FBDEF2FF2866AEC51CAFB1B87
-:10E7A00022E41189380EB5E3891EEC780DBBCF2E1B
-:10E7B000CC7DC79BE4B4E03C2227C677A619BDC92F
-:10E7C00040CFF129CECBF21303F9461320AF4842D4
-:10E7D0007F90E7E124DC0071C73E48B21D4AC8675C
-:10E7E00077C7DE80F70624108B6F1473777176F984
-:10E7F000CE6C18E7A864595F42DFFDFB986F924129
-:10E800003F19605FBB18F77D73A15D7D4FBF4F63FC
-:10E8100045FBC2F53B09FD876F60B0D141FCBA41B1
-:10E82000C7F31A557FC780FB53E2EF181CA543D4EA
-:10E8300051B93DA793E5512F4FEAE17E18BBC7754B
-:10E84000E17013DEFF44EC2536E6870BFF6A987C07
-:10E85000317AF37CE78B96277DA5F073C9F3F11726
-:10E86000B49F18809B8D7FF4AE68D43747EF1A8130
-:10E8700071BEC0F8BDE8F7CF69569E339EB7E62358
-:10E8800005FDCD777DAE68F725F875C328FCBE97EA
-:10E89000865C398BE2EFE44EC328E033BA6EF3F2C4
-:10E8A00083FC7BDF3D5913991D703E38BFC17974DD
-:10E8B000F373A202CE4F5B8E60DDD7E2539DE7710A
-:10E8C00029FC5251EADF20784F8E5F1A600B1767E0
-:10E8D000399ECFECF66E9E07D9CDF320BB79DE6270
-:10E8E00037CF53ECE6798A227FB45B2276384F31FA
-:10E8F0005B723C315FC2FCD1DB00CEA665FE42C834
-:10E90000B76B1AE99B2BC9983FDA925F16367FB432
-:10E9100010F2DE5F797EF60D60D79F18E0C27B496A
-:10E920005ECC9F7903D8F527F48C3F5E7FBEF2065C
-:10E93000C81B7B7CA8F32E18E74B49F6203DBF226D
-:10E94000E17E2AB1FBF4B5E7C82F6DCB67FB0BF76F
-:10E95000E7B37D0C513E97CFE4D9EBBCAC96EFCE3C
-:10E96000C4BC9F4D06CCFBA1DFB16B82F6FFD5F98D
-:10E9700059C57F3178406E8838CCD67CB6CF0A79BD
-:10E980005B30BF84FB0C2C6FCBE74D863C2F38EF00
-:10E9900003F7669043C4CEF2C0D8FD7D621DB6E693
-:10E9A000F3736770A17E69204FAC61FFD14F418E38
-:10E9B0005C97EF7C1AF99FE72F35C4BC8EE7265E83
-:10E9C000CDB7E27B74BE083F9507EB24C473481CA7
-:10E9D000AE3DBF2C34FF3D12FC2717791FCA4F09EB
-:10E9E000E44F05E54DBD0AF310708B7904C6393745
-:10E9F0005D8B785220DE756726F049B78ED97BE2B1
-:10EA0000BEDA62599A574BEB6F71BC88FE9FF2F5E4
-:10EA10005C9DEAD80FF358D6CCE26EA2BD4F6AFBDC
-:10EA2000CDC7B06EFB4D28EFD4DF17EFABE16DD84B
-:10EA3000BD1FF142E19D0B7006C1FB617E507CF071
-:10EA4000E4AE0F1F02945F2A9C179BCF6C18C0EE98
-:10EA5000450C8D4BD3850DB2A70CE2FDE1CAFBC678
-:10EA60000CF0F711E8F73AB81FD2C1FD904E1DFF28
-:10EA7000FB352ABFB4C3CBCEF57424E9F1DC0EE13B
-:10EA80007F6F41E8E1D507D8399FD52904DB617E46
-:10EA9000C00F926F2FEA85FE7BA324AAEF285D7C2E
-:10EAA00063719202A06BE72AD413F265261BD0F59E
-:10EAB000F6BF5DCDFD2BA677CAB89E298371008E67
-:10EAC000FC81A87F4AF97747199BD1BE1D4D5C3C5C
-:10EAD000DEC2E31277ED55F865FF17386EB02750A8
-:10EAE00068000000000000001F8B0800000000000C
-:10EAF000000BFB51CFC0F0038AAF9B3330E4593198
-:10EB000030CCB1666060B56160683047C8BD114700
-:10EB1000B0A9897FCB53A67F932403C31620DE06BA
-:10EB2000C43B2449D7CFAD8D6037AB3230F000F90C
-:10EB300021409A558381E1B51603032F903F03C806
-:10EB4000DF03C42780580528F612480BAB31307C10
-:10EB500001D27C40796D20FB8A1A76F3F9B5F1DB9E
-:10EB60007F5C0395FF138DFF401DBFFE2C4D02E11E
-:10EB70004B401E1BE6B3273F3E8228D03B10F830A7
-:10EB80005ABA7E6CC2C0F0CB9481C10E9AF60F20A7
-:10EB9000C90700C59E9840E34D8F81E1961903C3D4
-:10EBA0005E1CF9E20450FE36503EC61CBFFD0ACC86
-:10EBB000A87C615E4C35DF9810ECC942A872C7840E
-:10EBC00031D5F38A323000002621667DD80300005B
-:10EBD00000000000000000001F8B08000000000083
-:10EBE000000BE57D0D7C54D599F7B973EFDC99499D
-:10EBF0006E269310C24002CE2411A2243040C09849
-:10EC00004CE0E68B041270F87829565A27E8226DFA
-:10EC10004111DDAEEF2E2DC347435454D8A26BAD46
-:10EC2000BFDD812AEDEE6BFB0B162D9B049D8480CE
-:10EC300068F88868B5AE6D376AD7061B6C88C1D294
-:10EC4000DF4BCB7B9EE79C93997B33930475B7FB9B
-:10EC5000BEAFFCFCDDDC7BCF3D1FCF799EE7FC9F88
-:10EC60008F73C66AB111D775845C85FF1610327F29
-:10EC70002221646EF42A9E57D8492879262169F604
-:10EC8000435D33320859A8C9BE1A0F2113EC0D9DFC
-:10EC9000A488903262F3D8BC84B44B3FEB9A41EF26
-:10ECA0004FA4587D3602FFDD4BC83C4236DBE99F5E
-:10ECB000B4FC894BF44ABF3FF1474B98488454CB8E
-:10ECC000F54482EFED122FAF6B4B3209A922ECBF56
-:10ECD000F99748152D46AADC77D593198454BA685C
-:10ECE000293B7B7795952784962F25AC7EDD6E7C1E
-:10ECF0005F4A765F949D70D72F070A697D5754E36A
-:10ED00007B77CD6F8913CAC53C8771C01F940653AA
-:10ED1000494AC687C9F4EF9BC84D57657A55C61155
-:10ED20007273942EE62B212142C613D2C2BF5748DC
-:10ED30006006DC13F23CB69F2EE858DB43DC74DC43
-:10ED400019C5C457430738A1566F07BA9456A91E70
-:10ED50001BBD6FAF9E37B14723E4BB179AB3480181
-:10ED6000FD3CBC01E998C1E9D87EE1C577EFA6DF9B
-:10ED7000FB6B89CF46EF5BADBE898182E1FDF1D7A8
-:10ED8000A63B08AD676FA02319EB21E4CF57337979
-:10ED90003DB984B40572528371BE13D7C7B6BA08A1
-:10EDA000B145EFF7E8A4B6591B5EEE4598CCB950D3
-:10EDB000FD1AEC6729A7E57725B2BA19DB5D8DF35B
-:10EDC000D4CAFBDFA97724F714C0FB48B2858E2391
-:10EDD00074D1429EA555B4F55524417FB7EB9608F2
-:10EDE0003C6FEB53C3400FE26ECE5A5638BCFFADBA
-:10EDF00017D7CEC671053718DAFDFB3E3A5E0DC651
-:10EE0000F77CF2425ACF409FC525D379DDCB9FB71F
-:10EE1000069B935DF05D6F3ACEE7635BE9DFD3124B
-:10EE2000D3E3B1F95FCF096A50CE6EA447DFC0C902
-:10EE30005C3A6F6DFB141F8C6B347AFE3D6F47DCC0
-:10EE4000A7FB22952E5AAFBFDF27811CA5F71132F1
-:10EE5000CE0B72D176CC09F35B4F502EFC810AC7E2
-:10EE6000F56C1C3ED903EF4FC9C01F7E5704C73154
-:10EE7000D41FE8DF34E8A71BAF4FF2F69E8079C4B9
-:10EE8000F16D774CA5FD1D2856B09E03FAF672056C
-:10EE9000EBBB1291811F37307ECAF004B75981FE57
-:10EEA00077125FC803F5121CF73FF2F13FCDEB1369
-:10EEB000EDB4F5A5972BD0BFD5C40762522D6F696D
-:10EEC00087EFFDEB59FFA73CB04902FA5DB7A507F4
-:10EED000AF61DECF3DF03D2D90BDA95F02BA4DBEC2
-:10EEE0003F82D77DDB7ED90EFD4BDD491CA00BF6A2
-:10EEF0005659D2E0BBBD0B2739E0BD3340059FEA30
-:10EF000003BFCF756F271DCFBE2A05FBB9AF8FD2C8
-:10EF10009F9673865C3E906B67C8C3AF3E1F946F2D
-:10EF2000E5E338CADB7D998FC719D279B94D055011
-:10EF3000CE190AE135CCC7493C1B91EF360BBEB365
-:10EF4000066F8479CB18246E42E5F9E8A78B274237
-:10EF5000BBA27E73F9834FB5CC817E8F1F24EF59FE
-:10EF600067C035D200ED4D837138E1BEBB41423DF3
-:10EF7000154639F2F75908C98FEAA90CB2ECD55BEE
-:10EF8000F0AE1AE548E881D23ED522A5C6CA591589
-:10EF9000CAC13E2E07557D11E4132A67C72C944E33
-:10EFA000A10B54CE287FB5062C38DFCFF4ABA88751
-:10EFB000497E246B59CA70396ABBB86E36F45BC897
-:10EFC000D370FDF1FF867CEDA3E308C6D16BA23DB3
-:10EFD000216FE6F7A3CA9B2B84F2D646E52D04F4F5
-:10EFE0000C581C79207F4D1694137755733B9397DB
-:10EFF0000D286F1977B2FE4C58134639184DEEF6AE
-:10F00000795CE50AD4BF9AC9695BDFFBDB6C301F12
-:10F010006B08D71357DAE1DEFF00936BB39C99E5D9
-:10F0200030D5DF8DF2E9DDD94FE0EAD9518F7C4D43
-:10F030005B71A0FC2590C33690C3A2FF7FE4B012A1
-:10F04000D6712A7769DAAC4E171DF7A27EC2F0900E
-:10F05000B6B713D6F1EA6C1B5BC727BF7DDB3DF467
-:10F06000FEA43519E97F723C7D5804F732CA5DBBB6
-:10F070007757F666FA7E518684EF09598FF25D2341
-:10F08000F0123CA2F253DE239179E950EE833D95D4
-:10F09000F4FB577B890F5EBD9A2D637DC7FA0893F9
-:10F0A000632E9F357CBCC7F8FB81CB240CF2B900E2
-:10F0B00020097DFEE9F9FE2976FAEAF7962B8524E8
-:10F0C00087AEC79C6F05CEA8E6F2FF6A86AC83DEEA
-:10F0D00038B625254CBC585F04F8EDD5076C61990E
-:10F0E000B6379097FB5C8400FEEB9FBA99BEEF7435
-:10F0F0007D92122B9FBD7C1E3EE2F3DBC7F144CB19
-:10F10000F4C03289E2A257F37251BE06F23E994230
-:10F1100028A9EFC9FDC3877025A4590DA40CAF47DA
-:10F120007CDFE50E7E59A2F3D31BFEC009F37DE11F
-:10F13000F02733E04ADCE310778D86CF4A040EEBEC
-:10F140006DDE01388454513E9917E59309BDCDC752
-:10F15000806E257D0C8F91DA8D0C67BA185D28FEC4
-:10F16000CA82EF5EE2FD6A3D4F719A86E50CF5B406
-:10F170005A7BD60458FDF87D898BCDEB907EE174E7
-:10F180007F529208C3896CFE4AF8F77EA5F9BB80CE
-:10F19000B7FD2765DF36FA9DFF724F1589A3870EED
-:10F1A0004869C8AF65FD467E6DBD705006BAD0FE99
-:10F1B000CAD0DFD2DE6699E971C66725621DE97D96
-:10F1C000DEA0DF45FBADBDCF239E1FE855505F2578
-:10F1D000A26B071FC74B5C9FB4F179A20C85FD3F62
-:10F1E00046FBFFD008DF570233C6F45BC8DF82CB93
-:10F1F0004906BC5ED69F6EC2FFC6FECE57587BF353
-:10F20000815E2431BDB648E9BCFECF462FB35E1106
-:10F21000F5B6021D0B86F78B00538B7ECBFFFDE905
-:10F22000DA067F30FBE504C819E93924833C56CB64
-:10F230001AEA93D22A89E1723ECE7AF89636552B95
-:10F24000E4CA23A19DB7D82F856B006FF87E807626
-:10F25000E24091CD037A688267AFD213C36F8BF916
-:10F26000F7A2DF47B7EA38DEF6B96F6741B9A3D72F
-:10F270006FCB867958E4793B7933A5FF092E772D3A
-:10F280005B6BB15CE965F2C82C98973C2667F3F993
-:10F29000583AB9DEE9E0747B99AF9B6F6D0DE2F5EA
-:10F2A000CDADEBF17A6EEB26BCBE7AF9790DE6AF07
-:10F2B0002B3F17D7AF5AA5598967579598D6859789
-:10F2C0003C14EFD0F2757D6B77CFA2E33E75D98207
-:10F2D000FAF9547EEE8878A585CFAF28F78AFB0728
-:10F2E0009540B7FA5EDA5DEFF0F2A5BDC6764B89C0
-:10F2F000D40CF8AFD4F7BA42A87DB4A468BF168B7B
-:10F30000635A2F641642BDADD2AF56CCF124EE47FE
-:10F31000A9BF1BC7B924F28EE249495CEEB4D25DA5
-:10F320003F07ED54A68F4A7DEF55E9B4BD9A82FDA3
-:10F33000F5C817838A05F8A2BEE0109F5F17CEC7F5
-:10F3400012B19E15C9B561E84FDF00F6B3AB401EA0
-:10F350000FFD7BC822235F2EF1D810CF266C7F5083
-:10F360002111902F2582F3748AD6037C719ACA31B9
-:10F370007BDECDEE69BDF0BEDD6BD37C404FB7F0D8
-:10F3800047AC37F0477DDE9C53BE22584F64C4978C
-:10F390005D972B94347A7F1AD6574F943F4B397F21
-:10F3A0009E8679073E0ECBB8FE09BC2CEA3B7A3923
-:10F3B000E79122DADEE9B035EEF7812AA33CDEE2FE
-:10F3C0004E36DC57658F33DC9FEE9BFD6600DAA37B
-:10F3D000FD073C47421B0CFD3F0AFA0BDA7349B8A4
-:10F3E000FE9FB852D5770F940B1BFB65EE47D7E510
-:10F3F0009CC757D27A4F1D96914FABDCC67E555EA7
-:10F400007AF314E8A73AAA5F806E2FE98A0EE33EEA
-:10F410007D3825BC8DF2E54B05AF27036EA0FF6953
-:10F420004B683B9584CD6F4586B19E537DEF3F3C45
-:10F4300013F0AE5D463D57F1C78E9D00AFCE16DD91
-:10F44000D709746E2512D2A9ECC20119EA5B1536F0
-:10F450007EBF728D913E1B578E33E97FA37FA9D269
-:10F46000C3FC44F37D17B1BE12F0FFD0FB0ACDE818
-:10F47000179A0FCA20A6DE32935FA8C4C3FC4225A8
-:10F48000E01712E5BC6498DEA7F7D8BEDFB4AE9BE8
-:10F49000E53BA1FC5BC87AF0A790FEE5A3E096ED02
-:10F4A000DCBF62D4B744D927C5E28A166B7332E257
-:10F4B00086594C7F91FEF4B8FE2AB31E21E43EE447
-:10F4C0002B4147E20A918C79307E5EC6ACFF385DF5
-:10F4D0009AE8745CC57520C4F18B27AEBC9BBFCF86
-:10F4E000E6F2BEB097EA4D58AF7DB20BF4C6A9CB99
-:10F4F0004403793C4BF99DB5DC7335966FEB7A9BF1
-:10F50000912F69795C064F5DF6A1FC062632F96DF4
-:10F51000F7D628694C7FC69577B31CF492D0134573
-:10F52000745E4FE5E53EBE927ED77558E8018B8E3E
-:10F53000727598E1DED37D9B915F0728BF02D98762
-:10F54000CBFD392D76DDFFAF9277B39C0FC9FF302D
-:10F5500079677AEBD4A005C7537949C17AEAAE102E
-:10F560005CC7CDF27F9ADB6F2FE96F6A3E580F0BB5
-:10F570003E40FB987C66796776486B2FC1F6CB2EB0
-:10F58000BC2FD3917F61F22EE45CC8ED35CBFB7FBD
-:10F59000919C9B9F7FD3C2717F02398DCA7F08CB1C
-:10F5A000ED4821F9E0676B91927CDBBD20EFCCEF59
-:10F5B000632E3F4E16FE587BE837745C0D9459520B
-:10F5C00029A937929E29C00F13267AF0FDDD969E59
-:10F5D0004CB8FF3DE9CF9C4EAF250A3902EBAFA4F2
-:10F5E00013F200ED92E4719135B309794C0EDA65AE
-:10F5F0005A5EEA8DFC51A27426F7130FE0C16952DE
-:10F6000030199EDB289D345A9E28E710271212419C
-:10F610007A2DE542B7D4AE45D00F5F6CEDEB117497
-:10F62000C7F5638DEBC3E9B45E1291AE4E8F8EF3D6
-:10F63000A0359CE5D3609CE1EFDF0D7EABEFA9BE6A
-:10F6400067E3D0DDF219C709EA07E96961F40C59EB
-:10F65000927CCFC6C15B8BAEBDFEB792E8B514E815
-:10F660003873381DA53E4A3FA083F2E7AB6027966A
-:10F67000BA197FC9BF5775F0D310D91EBE3E4E3F91
-:10F6800036F27E3C26EB37516443E4CA66A44F2B26
-:10F69000CCBF06F4CB20DF8CE1AF85B28AE393EBDD
-:10F6A000C8265C5F48C4027A64B4F9B02A44916108
-:10F6B0001EBBAFA2DE6DE4FDB3D1E7DAECC4F325E7
-:10F6C000D7F9FA23749EC8EFD93CB52E32F2E5166D
-:10F6D000DEFFFB78BF403DA17D04F5537AC9BF53DF
-:10F6E00037C55B27760BFA737A99CBB7DECAC62F7C
-:10F6F000CAEF92993C85AE7DDE564DC84D3C6F8277
-:10F70000DFA5BE1389E66F53388E7CCF932D7CBC6A
-:10F7100021692CF2B090F3A55C49E70DC6576DA4A2
-:10F72000E30E3EAE35BCDEDB25FD7F023F4C93028F
-:10F730007F075752D58DF2073C0EE5A613FD5BFC03
-:10F74000FD569053526B7C4F9F6FC7EF5677637C8B
-:10F750004A3C3F26E93B65F6BE11BFD38DEF291F1A
-:10F7600036C173CA2F449E0DCF3DD81FCA27C44E41
-:10F77000EF1BF7DFF165A02BFDFE51AC9F9C337CA6
-:10F780006F050591CEAED26C767D0AF88EDBA73B75
-:10F7900056EB4857956CE2F6335BCFE6F3F5CCFEBB
-:10F7A00047B60E0EB854F46B290E3D1CA1D7745702
-:10F7B0004407BFF338D21D027B6CD54AD9A0E75766
-:10F7C0009BD6972FDF695C7FD76CC832DC7FF5FE54
-:10F7D0005CC37D70CB74437D6B77CE31DCDFB9BB0E
-:10F7E000D470BF6E5FA5E1FBF54FD719DE7FFD99A1
-:10F7F0001586FB0DCFDD1637BE29D6BB072DEF6D65
-:10F8000008D071ED805731785189C62F2D0C8F1992
-:10F81000BFA3ECE751E6413982AE08339F2AA6F830
-:10F8200067CF90FC6C36ACB71D216F064005DDAB91
-:10F830006888FF437A775E66140F547AD6D5C75B23
-:10F840007F457F145EAE9CF454C2BCE98AB19CC271
-:10F85000E3B59AAF1FFD30E678ADE25988EBBBB94E
-:10F86000BFEFCA2919A09768DD1E8CD36A635B4F6E
-:10F87000471D1FD584631A1F6FAF1CC6999B785C08
-:10F88000F38BFA65E8DE58C715EDA711F78838F94C
-:10F8900012569494789F417B6C09F40FD6E7228628
-:10F8A00077ECF41F5B6719FDEB78F9C0FD2E2BE0B8
-:10F8B000E34095B19F751C47513954404F94E49BE8
-:10F8C000DE433F674039235EEAE4FCA8293C5E3E04
-:10F8D0008FCCC379E072BB4CC86D35F3731057FC05
-:10F8E00038FAE2CBB4D01C6CDF907FF05A7E6E12F7
-:10F8F0007CB7A489786C149F3C38779BAB0270BEB0
-:10F900006EF5D5D2D2953EEE6FD265C4B3D7E5B3CE
-:10F91000FBFA2AE67F5A1CEC463F60FD9DE16D70C4
-:10F920009DB43EA2603F4C747DCA134E436CC0E947
-:10F930009BC5E99525E8CAE928F4F8A40DC679AC79
-:10F940002F32D26B29A7A799CE4B391D979AE87809
-:10F9500014FEA074999B808E4B381EB5CFE5F6DD62
-:10F96000607A5CBBF129EE1F13FCA398D635A13F4A
-:10F9700086D637CEBF8F811E079CE7E23885AF7BE6
-:10F9800089E4A83CAF614F39F8C933AC86F8C54269
-:10F990003ED6923C16EF28C99011F797B8DF88EB56
-:10F9A00067067A57CF8BF2E7D15E667F34BACFC94C
-:10F9B000304F75790CE7EFE4F411FEBF56EE1735C2
-:10F9C000F7EBC4945036E0A3939742D99B8BC0FFCA
-:10F9D00023219FB4CDBA379BE50BB07EFA797BAF7C
-:10F9E0005C0CA1FD76B277E4F8A2C0F966BE29F1FD
-:10F9F0008531CE5802FE62DA5E6D3F5D83E8D01736
-:10FA000046FE59F61402AE8E28D09F7AF75A05FDAD
-:10FA100065EE0605FCCBB5EEFD95400F3F09EF7096
-:10FA2000825FCD23F92240C70226BFEBE9BF58F918
-:10FA300015FDADE90B2A20EF351EA35DE3E7FC566B
-:10FA4000ED363DCFAB417EF39BF86DBBE0B3EBC928
-:10FA5000F5B17CE6E7F3A25ECCE1F21A9FCF44FC5D
-:10FA6000E2DFB99FF5573C4EF72E8FEBBDB3D58340
-:10FA7000D757B6E6E3F3E35B7D78FFF6D662BCFFCB
-:10FA800039F879E9FD1BDC8FFBFAD600DE9FDDBA81
-:10FA90001AEFBBB89F56F0F12E1E4FA996DBD0BFD0
-:10FAA00058E70BDA5D31FC54C7FB8DAC0F38A4204E
-:10FAB000BEFFD536E58802FC756E484E08EA8BE538
-:10FAC000F5DE030F51BAD8BE4D82802B6D1DFFAA03
-:10FAD0004CA5FC5F57EBB5AE83F642CDCA1CE0C720
-:10FAE000C8BF2AB9F0BC7E96F58E38ED8B7612B57C
-:10FAF0006FD66F2B6A8D76B05FF8D1FB832118E744
-:10FB000084FE6004FAE777AB9E787EE1F689EBDC51
-:10FB1000C04F8D17836EE0A7C689276466AF337F19
-:10FB2000B8CAF95494F7BB8DF17C95F7BB8D3E872D
-:10FB3000FEB6F58F4D0E44B952A559766989C7674F
-:10FB4000F637ED94E2DBAD4956866B9D3CBE4A75B7
-:10FB5000A60272062C0AFD9F40D906E44BD398DF1B
-:10FB600022D917E47AD9B88EA7150702A097B40C4A
-:10FB7000E2AB01F5A6F5B8816FE4E285E7619D256A
-:10FB800005317A1BEC1EB3FD1F7B2FE3D2154A49CA
-:10FB900087ABB91CA3AFC659A86916EBDFA3DCCFAE
-:10FBA00021E8AB71FA96784EFE02F4EAA33EE68FA6
-:10FBB000793483C565078AD7222E2BE176818DECB7
-:10FBC000C1F249A419AF3B38BD078ACF11907B59C8
-:10FBD000A1B83903FA630F87E8F74E937E573423B1
-:10FBE000BD254A933580AF7B1583BD2115333D6F0D
-:10FBF000077B1DEC188E5FA2765E905C05E28F118C
-:10FC00004FEDB41AED3171ED552CC80F2EAB299F75
-:10FC1000EEFF7AFA9DF842E927ECC4219C77EC6B61
-:10FC200004E231229F50947FC5E46F52B3591CC641
-:10FC30005CEF2D5646F705568E8F059EF09BDB71C7
-:10FC400084809E2AB5A71CD2F07A12B5477A678FB6
-:10FC5000E2B7DE86ED9F555CCC9EE0F940D42C9750
-:10FC60000CF6895D77837D38EC7BB7C520A7C3FB95
-:10FC7000CDE8F345F777093548E1BA54E8E1628603
-:10FC8000279779289EA47F2ED3189F9E2997C2DBA1
-:10FC9000914F7583BD555B5C731EF512B547D479E2
-:10FCA0001CA7D3FE3741BDB49ED7278AEF86F489BF
-:10FCB000E5EACCE1F504AA18EE21A17F5914EB3F47
-:10FCC000085076C99F0DF5B2EF69D1F6ABF1FAC1D4
-:10FCD000F556A0F8DEA59A13EE75E949C07B05310B
-:10FCE000F800E89A6733D2D9A4FFAA86E93DA3BEFB
-:10FCF0005D48F9F7086DA756DE540F2EEF9ABD6BDD
-:10FD00000FBF8ADD117688276EBDA7E08F9B01FDAE
-:10FD100019F10AF1B13C8ECA90A71EE99E2191B05B
-:10FD200017FA6FECC7C26C931D96611EC71E9CC765
-:10FD30000E85AE2374BE3AE83CEE41FB38BE3D254D
-:10FD4000ECBC05DE41B4A784BD47B8BDE7A2FF62A5
-:10FD5000F158192F5F7EBF4701FC5B6E37F9998719
-:10FD6000F28F09DA530B88B1BF65DCEE2B33D97DF6
-:10FD700042DE5F14FA52D8B55C1FDE22ECA9B291C4
-:10FD8000E3CB9DA67CBA2ADAF1E66B900302BD8232
-:10FD9000781319A29381BFDABD539B2394AEB7F8B1
-:10FDA0001C2CDE42FBA9087D8E7462387B292F7FD4
-:10FDB0008B4745FEF76B2C7E513F8ADFC25FCCE25A
-:10FDC0000667ED125B0F42E44D12931F5EE961FA84
-:10FDD0005A33F145B627500571204D917C61329C14
-:10FDE0005FABB83D07DF6FA1A4A8CAA336F9EC78D2
-:10FDF000F9E5DDE05A2565B40F4F7913CFAFEEEB8F
-:10FE0000AF84E919EBFC1213CE3EDBFF3EE6750D25
-:10FE1000144818F769F77E8AF68188EF44E977027B
-:10FE2000F351FCC59FA0BD3294B7C5EB5B2AEA2B0A
-:10FE30003E86F19AEFB88E25433CE60CC471E9F793
-:10FE400067947E0DEC9045025F518A46043DBDD11A
-:10FE50007C9308B7ABCEDADF4806BDF912C7F54789
-:10FE6000FD726D3C3FE70299F999C5F54695AD3BAA
-:10FE7000F35486E7C4BD98DF217E924F15313BFCD9
-:10FE80006F0DF36EAE1FCAAF46FF60A460247BB453
-:10FE9000DE44E7292A5FF738DE180DD78A719AE920
-:10FEA000601EA7F93BA7CAFC65775AF5E9EADC684A
-:10FEB0003B62BD33975F96202FA7BCD8E89F5C704C
-:10FEC000D9989773A73558A2527A562AD2CE540F92
-:10FED000EA3594A78E2B1AE29881FE8E9D30ADC72D
-:10FEE00007997FB48CC8611B5B17EA216E27E44633
-:10FEF000F0BFB91FA3B55F36D883F678F9E5FE2ABF
-:10FF0000E0BF5BFCEDA8579750BD3A2E8E5E5D2892
-:10FF1000F7ED1C07F2EB63FB3BCEFEB2BB0AEF35FD
-:10FF200009F361F5B25C651CF0812BBEBF6A3EE748
-:10FF300093E1F13CA1575D0AE006B3BF6D3E97BB6C
-:10FF4000F9267E08AA4338E8A6ABB9A3CF53227E90
-:10FF500018E81FB82F9E1F555C13E55DDD4D4CF46E
-:10FF60006D33FA9FCDF5087F1091DBB2419E85FD80
-:10FF70006B2ED7A4B2B8C7F1C2BB486C5E95D00750
-:10FF80006A71B3067EF1AEE291D70B733E5C39F431
-:10FF90003786AE9576633CF609457F10F8318A9333
-:10FFA0001A98BD5ADC80F6EAD202BE2FA8F02EB411
-:10FFB0004F855DDD78F321CCE712F95AC23E35F763
-:10FFC000BB6BE2F398CF335ABF851D7FCA26B33887
-:10FFD00004B5DB3D68B753DC17E7BB576C8C5E3F5D
-:10FFE00055F4FD20AF3BADBABB01E28C8536DFB3E3
-:10FFF00071E6A1D7C6E4BB2B41BCF55710F8988B2E
-:020000021000EC
-:10000000E3403A98D71B61C78A7D4A13DC4C6EEBFC
-:10001000B81D5B5AD080F298E6A6762BD0CDC7ECFF
-:1000200056D267B453976ADD5930FFE6F54E1EE4A9
-:1000300076ED18EDD65D0EC6474117B1BBE97B875B
-:1000400042A1295DFF1E972B8E013D76A511B407B5
-:10005000CEA4A9E10371FC0D6F737EAB963718F83F
-:10006000AD8CE312B5AA47037FC09941E6C74B3474
-:100070006F0F99707A4E3E29B739E1DA5F0EF4A01E
-:10008000F7BA0DAFFD989FFD70E1BA9C78F51D6839
-:1000900052E2AE4BBFE3F3B65CE46BD7327FE4DDF4
-:1000A000052AFA8527D4BE7702F9B49EF3E9121B1C
-:1000B0008EBBAB50C179E9BAD9DB0C71CDAE423BF6
-:1000C000E6A3B417FEEC9790AF5D562C19F24B04E3
-:1000D000FF9601AE86FAEDCCDF79B79BE9E12E8D74
-:1000E000E3179E37B291CFE999C31F3863F34656A1
-:1000F00008BEAFE77E72137EA26A246E1C47E4211D
-:100100007F5CCFFCC2778BF11E39B413E4AE8EF363
-:100110004DFBA5756E94CF232C3FAFB1B001FD45CB
-:10012000ED13DF52E17EA3FB4315EECDB842CCEBDD
-:10013000DDC53F65F9917C5E37823F9EF2FB4B99AE
-:10014000D3AD1E7ABF3C72B315FC9DC23F3B2C0E53
-:10015000C5E329356CF8A4C6CDF0F589CC6492943A
-:1001600001F492C312D02DE22049907FE6B6861D9D
-:10017000F4BE4EE99902B825D984173F7EE1503686
-:10018000C8F7F119BF55A0DDEB8ADF6B84714C2AEB
-:100190003E84FEFEAC23873AD3693D4BF3894FF78B
-:1001A0000CEF4F355F9FEECE60F94277FBC221D84E
-:1001B0007776E10ADB4F51F1C21B95B0AC0D8FCBC6
-:1001C000E804708888EB286E1E17E1F10972E5AA31
-:1001D000143B6F754AD00EFAB7B1F80D27F4773992
-:1001E000A75BCE61B901F8BBEA85395F013E2137D3
-:1001F000DB5CD7D3062FB87EEE9CAAB1F777B17A35
-:10020000E70769F9BA8243D9EB0A87EB9721F92905
-:10021000F8C3D620EDCF99453FCB06DCF606D5BB1B
-:100220001E6897EB2DB3BD645E57CD7931E67167DB
-:100230002ACB6A6D7361BEBFEFF6C6F019D5036BAA
-:10024000A1FF1B9FB4631E57DA91D75519F41BC544
-:10025000EF3552948F36723EAAD398FE6B2C24E170
-:10026000ED12F0DF87F5A52077AFB27CC30947DE3A
-:1002700063F9A3A6F5A18BAF1BC2EFDC35F17D942A
-:100280009F8F0F73790959A4587F9256DCBF12E6ED
-:10029000C52C27E27E7E7F4FDCF5E15D1BF79B0CD2
-:1002A000B2F71AD5DF10D736BFF7737BAA0CAE3181
-:1002B000F5DC6763B8575CAF210FE1896F53F96FC5
-:1002C000DFDDE1BE03F59486B87DE39143F910B319
-:1002D000C93C7CA88AEB0BB4CB643ECE09C4837ABC
-:1002E0006AA96667F103139F5B8BF747003E8B7526
-:1002F0001A0C722533AA47E4583F441C3B8C84F403
-:1003000037F362F2BEE8FA4E40AF54BA99FFD5CC4B
-:100310002769C554EFE024502E8C89FB9AF9B64E1C
-:100320000BBA219E4DE5E73C8B7FD2F50AFC137298
-:10033000BD0FE793F3A785FE83F52FD967E44F6BD5
-:10034000BE6AC02BE67EFCA3CD88FFC5FA9CE6EE14
-:10035000C1FE2DD59AB3A1FD09EE1EB4B7A87ECF7C
-:1003600086ABE033A1AF87F8AFF0A6C5A0DF81AFC1
-:1003700021447EA6784E12E8C13A37C329C4E44F1F
-:10038000EF728F6C6F749AD6BF332E665FD515935C
-:1003900024572AC83BF33B753D92BE3F39C62FF721
-:1003A0004FD6608B2DC6BFEE2CF8D2629713F40C9B
-:1003B000CBDF2AA1EACB9A1BF5670ABFA988F70908
-:1003C0003FE9307F66413BE6775945DE058FFF0DFB
-:1003D000CBFB4910771457E1CFB46D6F567C3C5E70
-:1003E0008278AC9EFBE106678FE20F65FE078ACF3D
-:1003F0007E6E1B3F3A3E3BC8EDCC5E501EF4BADE2B
-:10040000E6C2AB06F928B4AB5D8EF8B8ED656EB701
-:100410005D8B7C9E94E13BD6CE4726FE12CFA3781F
-:1004200098C9C184E2439DB178B8AC89D286CE9395
-:10043000DA44A690D4C47CB77448EFFDD4C05F43BF
-:10044000F878145C2CF8EB92ACFF19E898A85C1DC6
-:10045000EF47A2F78D85B6D5906F45CB9109A9ECF2
-:100460003A8D5E3B671CCAB6D0E7AF01FE8AE9470A
-:10047000D7F78EE0387EA5B27D365D97D6E5003E93
-:1004800038ABE8A9F6F163E71FB33CD9E7EA9E6D04
-:1004900054FE8E66DB717D3EEA6638E4752819C32A
-:1004A0004F9BD5E075F6B9A8EA7592CE959CE0739E
-:1004B000509A5563DB27767B72CFFD81185CB91BA0
-:1004C0005E4D84381FE39B07D51ECCC7B99DD66E01
-:1004D000A3ED1CD3E4CCB5F47EB69DF1E3B1903529
-:1004E0006EFEF36C3BC3CF9BD5C06CE82769DE84FE
-:1004F00072D620C901907FE21B9B7F6E474BFCBCEC
-:10050000D2CA68FDF3B1FEC3B47EC00D3EEE7F27B4
-:10051000AECCB8FE763EEE0821B5202F8FA619EDA1
-:100520004DBF9DAD7BF3A3F52F8EAD1FF3B3E6E278
-:10053000F32538CFCFB1E7F9762617E5B92CAF4DC3
-:10054000D051D4BB325ADF4AACEF08FB2ECFCEE3FA
-:1005500006BCDF02E79BF39F163AD87C44E3A6046F
-:10056000F56689C6FCF513FAC3C7E0BE9CF07D9919
-:10057000D2DBB87FEFA8D58BF900ED8E694F6FCA3B
-:10058000803C0923AEB7719E51EC3F946371BACEA3
-:10059000714C49760EE2E10E923BA29D237087904A
-:1005A000EB05C27F7AE500EE176BE1DF8B76CB4D72
-:1005B000B82EBA5FB11BF72B4EE8EDC6FD89152E9C
-:1005C0007E5E44DA37D1BEDEE5B897E1F9C99FE235
-:1005D0007EE505D907E5787E4245F45F7903DB3F88
-:1005E000EA62EBD402815F4D76C64B995D32E0C87A
-:1005F00044B8FE84147C26C2FC9A067CEF8F7C6D86
-:10060000C3214A57BD97B81CF4BE24C2E24C151C46
-:10061000D75728E12C581F6AB2993FAAE54FDD59F8
-:10062000B03E1CFF3413D78BEB94FD38DE498A179C
-:10063000F1FC4213FEAFB01FDA0679138B14898CDC
-:1006400023C3FB05FBD5C08E2871B3BCA0126AC5BD
-:10065000819DF1326D1FFC65157FA2F3678987EFDD
-:100660008D38A5562927AC1CC7FBD9CCBF341A9EA0
-:10067000AE30D903625E2B943D556097B4809D41A6
-:100680001FB5283B9474DAAF5D8304229BC4CFBFAF
-:10069000CBC9B630FB60B2650DD08D58997DB0CB1B
-:1006A000F5D776B40FE87BB00F2AB87D5061F7A27A
-:1006B0007D301A8ECFB1333BA1FDE254B49F228E20
-:1006C0001F66817E16F9E402DF0BFECB54CA4F8011
-:1006D0003C2FE07C28F0BE4DE0FD2B9B089C275072
-:1006E000A118F1BE8DF35905C7FB2D10F7027E3D11
-:1006F0009F79CA0BF11881F7AFB898BF9BE37DB122
-:10070000CFB203E43306EF779C1FC0BC8597B39943
-:10071000DE17787FC89EFC8C78BF4CE80F8EE76BA5
-:10072000386E10EFFBB9DE33E37CF3FB6BC5F98465
-:10073000E3F8283E36F26FFBEE1C8CAF94B8EC6801
-:10074000072CE80D0EDE4BAF995736FD662FCA51C8
-:10075000B20F3EB3713B6CD43C5013EEA776C34E40
-:10076000D87F539EC7F28ED2B25D55B09FBDC223D3
-:10077000A1FF69985C98ED806C17DA69954A83C887
-:100780008F1B11EF57682EC4DB8A523326BC6F963D
-:10079000AFDA3CDB887C9DED30E617940BBDA9DC1D
-:1007A0001B42BDA9DC1B01392AB7737F8FE36FDCC5
-:1007B000B1E73AECE2EB81D0D3425E3B1CD39460CC
-:1007C0000CFE1AE26B25578BDD5FDCC1F9F2078A5C
-:1007D00007FDAD1D76661F98F1D850798EF72B383E
-:1007E000DEAFB033BCDF311CEF173B62F09BD3CEE2
-:1007F000F0FE58F30A841D5B63B263DFB71BEDD8CC
-:10080000447CFD215FD7A3F4F4325CAB7811D70AA6
-:100810007A2A1CD7DA004FCEC4751571AD90E3610A
-:1008200074B5E61A706D39C7791DCA9871EDADB10E
-:1008300074315F2B46C1B5BB1C14D76A580E716D5D
-:1008400085C0B5495E03AE251AC3631DDFCBC771F2
-:1008500074A4313C6BC66389F107D76F265C21BE57
-:100860006F4921D9E89F1BC225D3E2E2924438C4E4
-:100870003CAE16C025DA5F029778709C663E3F9AC0
-:10088000A2A39D1FC529BFFDC6212A87BB2E123CEE
-:100890005141E0157FE48FC71A8A102F1087273A3D
-:1008A0004E8157043E11EB638BC2F249057E49E449
-:1008B0001F15D76BC52F2732FF17E21E336E117835
-:1008C000C55C7F8795E199963FBDF59F8A6316EEDB
-:1008D000A7DC47E5A45CD9867AC9AC075BC05B4D51
-:1008E000CBBFEC22E110D4FFA773727A1C7D6CC6DB
-:1008F00033669C32567CB328EF22E61B8E863B3A49
-:100900009430EE936F51EEB3833E32E31A333D736E
-:10091000B24903C40304DE49C4C750EE2E6714076E
-:10092000252A47F538E2A384F5D82F5E2B2E3AEF1F
-:10093000181117313D50E1667A20115ED9E57369CF
-:10094000B179AC627D69CFCEF925EE37EF55F1DC98
-:1009500084F6F353519F26C24B6D26B9EB003DA29E
-:1009600045D7AF8474E91D407917B86A347D21EE0C
-:1009700013E129B1AE9401E81F9F386E392589D95A
-:100980007D0FE6303BDAFC3E9A8762C45524A31003
-:10099000F9F81EBE1F3311CEA22B9893F9AF42D89F
-:1009A000CE2A6E87A2CF701ECF43A05D0DE4913C8E
-:1009B00058270276263767E64A2837CBE0399DD795
-:1009C000F22A16373A5728613CFD4CB90DE7F5D4A9
-:1009D000C72C4FB13D85F95FCFCC72F80ED02E7C7D
-:1009E0000CF5D275F99CA3BB0870C0AC24EE2F485F
-:1009F00067E35C921CD98071F339D32D21EF7079B4
-:100A00007F3089F7235DC3F85B1DC7A3103FCC9AE5
-:100A10003D7C9FC1D3495EAC1FF2E7B368B99D9698
-:100A2000EE8773E8238785C55BCD74FD98D31D08D9
-:100A3000638BA1437D9E5D7750FE77DCC8E256470D
-:100A4000AB6C98A7E380103BADF7A1FC9C9478FCBD
-:100A500021C6657EBE9F8FFBDCE47E5CDFCEF2BCF0
-:100A6000DF8D8A14027AA3A22E82631527ED7F8878
-:100A700016FD4A521AF6EBEC0BAF23DF9E4EE374E1
-:100A8000D025B4D7CE78983C855C5A18F66BD2EF57
-:100A9000ADAB46C807E92EAFC9677134422488AFB1
-:100AA000C11F39C3E9BDA256C671AF70EDBE17E4D0
-:100AB000F15CED1BC9702EE5D2410B01B95BE12A57
-:100AC000B90B9EB7A7303E063A038E5A51F5A56F73
-:100AD000C0F3FA7AE37C9C4CCAC171942A6C3E60E4
-:100AE000FEB2660F6F97AE7E41353386FEFE9FFDE8
-:100AF0008D14B3AE887C167B82FCBE44E39662F50F
-:100B0000AE1CF5474E28DEBF07F6CD048AD879180B
-:100B1000751E1282F86F9D8F44BC9CBF30CFA633E8
-:100B20008FED17E2F29556BCBF2907FC97830A8B1D
-:100B30004B9BD691523A57D9E9E04F67F37366AEB3
-:100B40008C765E6931C3F9A51CE7D7E90D18EFABC8
-:100B50007FA473770EBC97B3ABCB3D3C6E1A433F7B
-:100B60007284F9E79699F83CC5E4FF2FF599F206EF
-:100B700079BEDFD1FC675CC03F0FA673FE992DA143
-:100B80001CBD2E791E01B910745A9224E233C4633D
-:100B90008DE18F217EE0F36BA67B227A9AE964E6F1
-:100BA0000B33BDCFA498E89580FE89E85D5A5CFEC2
-:100BB00017A5EF05ABCD0A7CDB6EFD6D36B78F88D0
-:100BC0001CA34FCC74BBA07952404F9C1B3C87B8F0
-:100BD000EDF464CF57F07C2C2AC778BE279787E8BE
-:100BE0003C507970C6CAF3DB53409E299F59A19EA1
-:100BF0007A5DD21D207F8777DD8BE306397546E568
-:100C0000C84CFF61F247FF57447F7387CB91399FF0
-:100C1000ECB3CADFB7409F53BA2D4CF2E055E8D38E
-:100C20007AE2FA4AECFE5611676FF73606605F7A91
-:100C30005DAF05CF016A197C5E590BFB5D6B255CCE
-:100C4000D634D28DFDD59A58BEC4D4A71E2090CFDD
-:100C5000FEC864E2037DA535B1FC09FA1EF3270442
-:100C60007E17E73AD2F73ACB17319EBF94E233E6CC
-:100C7000FF2CEFAB403BA2939F8724EC0491F74AF3
-:100C80004CFB5E1AE1C9C4E8FE90A64B616647249E
-:100C9000D80723AE667BC17C3DDEF1CFDF003F622B
-:100CA000599E8A7EC4B2C1881DEA7BB8A0A316F300
-:100CB000DC6A2517C4E38E7FDABC03CE415A5EF0AE
-:100CC0007E5C5CD27AE1091F8CA3D5BAC7970EFA75
-:100CD000613B5BB71CD30A26AF1D01F7046BCB6BDE
-:100CE000BD3312E799DC93CCD7F7F6AF1D7810E24D
-:100CF000DE7DAA0FEC97C53CCE5FA7EC59BD96CE22
-:100D000067E722C9B78D3EEFBC61EFA60E88639CF2
-:100D100057D1DFD775E96036D819AF7DCF8EF6E8A9
-:100D2000F14F0F3E8D79267DEA3C18EF50FFAFD78B
-:100D3000D8FB8F5F3C097A6679FEF22268C7A190E2
-:100D40003DC04FD70D36BF0BE725D4F5AA7341FF41
-:100D50002CAFDD6FFF2BA053ED4FEDD783FD31E8B6
-:100D6000A986F9BC2E2958994CF55E5681F73B1996
-:100D7000D08E8FF874A46B3701BA8AFC04610F948B
-:100D800071BE6959E44D2131743D3798930274CE98
-:100D9000A9E5790C8BE400D8CBE75CD7A7A07FB29C
-:100DA00096E52F98E9B51C707A2AF4CF3B795D9CC3
-:100DB000F53BA7F60F5B83E00FBE81D9E7E6F77737
-:100DC000707A3B7EB7EE008CD7F17DBB0BE0B5238C
-:100DD000417EE6D464AEE7DD63F397083C43E96AFD
-:100DE000B7C6F80129DE5F9F1C1377BDD6F6BF9A00
-:100DF000CCF4C02539B819E85FCAFD2565DC5F92DF
-:100E0000A85F25A3F831281F219D96831F6326BB69
-:100E10004EA3D7CEC5DEC9063F06D1DDA067CF41C0
-:100E20007C0EF098B26C3BF4A3EB02F36724E2DF94
-:100E3000E579076FEB88D1775D563D1BECDCCE1B67
-:100E4000DECE82F9FFCFE2DF213EABFD69139CAB22
-:100E5000F550C1F2F1A0FF62F8F869988F6BE56375
-:100E600033FD5A16E5A6102DCACF828F87F3A584CD
-:100E7000F6A8E0EF44F301E5C01E157C9EA8DCB99E
-:100E800045D3E2F27FB49E8B23CAC16ACE57770066
-:100E90005F8D07BDACBB400F2FCC7A17EDD657B88E
-:100EA0003E1EE29394EEDBEEA17A27F4AC1DE3E85C
-:100EB000472FA978FEFAD167D6FF00D68DCEC10A9A
-:100EC000D787B88E97BB56D07EDD00F64301CE4F54
-:100ED000A712E337BC902CE2E6C67CDF9FB87E9376
-:100EE0005ECED659AD9CD27B265F276EF43E93042E
-:100EF000EBF94CBE9F62469B1A775DE61082146444
-:100F0000BC6E01E85F70D8584E1BDA9FDE6C81F82A
-:100F1000E08DCF99DEF37DD5E6FCC87F4F36ED7FBF
-:100F200032ADB7F64B23E769FC0BB77B9FE3F9BF04
-:100F30003FE1E70936F3F3049F877DAEF47A18F6B4
-:100F4000B9D2E72FC23E577A7F84EF7325D9633B2E
-:100F5000375E9CF7A4723A344D0C1BF6698AFDDFAC
-:100F60002D709E12E001B7CACEA17351B405792A43
-:100F70001C2F5A92FD7615F6737D44304FE5AFCFA6
-:100F800077233FECE6EBAC19C788F31ECDFD52A3E7
-:100F90007454C04F7574727075A0804F18F0CDDC1A
-:100FA00009FB1F8AC1D3A91AB32B1BB9DD16BA449A
-:100FB000C2CF4AD1F2A72F91830F313F5B4806DCA5
-:100FC000017F51165EDC4B10C72D2EDA85F617E037
-:100FD00040C06578FE580EF8BD5E443CB77870DEC0
-:100FE0005D0CB7E8C370DC10DD64A413C3E745AF44
-:100FF000A35F71716F7C7E8BE637ADEECC8BD9979A
-:10100000503F18ACE7F8C8157B6E826AE22B733D3F
-:101010006945CC7FBF249FFB7B783C44CCE78E4D59
-:10102000DDE82FEF2AB279C0BF60C689669CAF1693
-:10103000B17D64CACD6C3FEBE24B2C5E880C9319FA
-:101040003D9F4DE579BE2DAEA00FFC98753E13EE89
-:10105000E5E74B95E51BF1BC19EFABBDAA09EF879E
-:10106000D87AB89DCDE7998F09DA51CFEE63FE812A
-:1010700056B787F11F09A3DDB3C06D99F59007E25C
-:10108000566C7F66C920417F4949AF07FD4F0BFA77
-:101090004864EA0C3C87B809CF1932D16F01B87A9D
-:1010A000D3A11E4FE7784AFF050AD909E7CB64DAD6
-:1010B0001B749003D5BD09F7E3407EC338C647F6DD
-:1010C00058FAAA49A77680082CE07E35F1BB1513A3
-:1010D000EC87900F62E66FC4F898CAF94EC4BBCA99
-:1010E00079FDE57D2CDFCDCC0769F68BEFC239CFDA
-:1010F00015831A9E036D9EF7E171B0FE0F1E8338B3
-:10110000CFA524DF7698673B9B67318FAADC26C387
-:10111000FE0EA2B0F912F130B37FB5D4B46FCEDCBD
-:101120002F715EC256CDB48F8CE3F80ADEBB26C7A2
-:1011300021C3B9B5155CCF0CADDBF65C1ED762E7F9
-:101140009CB6F6CD1E31AED5EA62E7FE11D7F2515C
-:10115000F4DE76B68EF0F3054A8B4912E09CD23E5F
-:10116000C2F8EB114B38D91B5B3E6CD857EEEC5BE9
-:10117000B518CF6974B9AAC0CF564A58FC52EF25AA
-:1011800018CFD4C9213918332E112F51B95F4C957E
-:10119000D8B8049DCCFDBB7DD0680F7D2564DC0FE5
-:1011A00071DB03C6FD1BB76ECA32BCAF599F6B78AB
-:1011B0005FED996EB8FF92DB787ED0FF081ACF0FF3
-:1011C0005AB1BAD2507E59C0787ED02DB5C6F383BD
-:1011D000EAF4DB4CF2AB1BF8FBA8D4FD5D18BF258D
-:1011E000F997B923F979CB468B2387D879426807D9
-:1011F000C689B398F7BB7DA409BC609483CE5039EF
-:101200003B6FA7D7B3AFDC03F12A9F82062E3F576F
-:10121000A89AB072D56E166FA9CA886FCF0B3D68B9
-:101220008E4F8873014BFBBA910FCA4CE70096B8FA
-:1012300017C63DE7F33F34D3B91809CEBF18B67EC1
-:101240008F757C3CCE34EAF878BB25A4FB98D39B01
-:10125000787C631DD7507E179C4748E9D10D8F26B7
-:10126000B2F71A95B79D69F978FE4586BD424919CE
-:101270001FF577127DCE98F2D1DAB91F9FE82BC601
-:10128000749E6986DDC3F84267F868A7A487E1FC0D
-:101290003C731C55CD177154E339188E9D442FA013
-:1012A000240A55108CEB8772ECE11D12E493B37D98
-:1012B000A68D375870FD69BCA8EF81FC94A61B145D
-:1012C000DCE7582D6B585ECD66EB931F72EF217FE4
-:1012D000E2357DB5E1FC0EF77617C889FA347B9FBD
-:1012E000683C6D13D5D5F1EC859B52181E3AAB04C2
-:1012F00066A6207FE86E168F08E37968222F3751A3
-:101300003E2E058E2EE44322F0019BBFEF403C258C
-:101310008EFC56A53039F31748612BE497AE246153
-:10132000EB0876659BDB12D79F5198C2F359AE5CF0
-:10133000C573EE5471EE5E163B77AFDD749E65218A
-:101340006FF7788A9DF181F7A021DEEDE7F2B0D842
-:10135000B38EC4E25971FE8FDAFF3EFA99CE8C72D9
-:10136000FE8E886FEDE6FB9A2B2F5902F1FA3F9023
-:10137000A2209D9ED5AC71C7F700EF6FDB141F9EB6
-:10138000B7DAF8B8859D17EF6E9C84FBBE53FE8AD2
-:10139000307F17EBFF622EA77E777807498138F5FB
-:1013A0003B4FC2EF87A8C536F0E591333734E0797B
-:1013B000B1BBFB295EF446C797C2D71BFFBE8EDACE
-:1013C0005CC0432765F4F7D4F4B27CF3A5C5FBF900
-:1013D000392D3DB88FD1FCFB2525B5411DD6E5A59E
-:1013E000F5911D887F7C9E72FC3D13E2DB86BFAFCA
-:1013F000326CBFA586B8AB6D90F17DDB8F7CEDF8CC
-:10140000FB206E811BF5FAEACCE8B96165173B76E3
-:101410004208C67C6E98F9DC216197A9265C29EC0C
-:10142000B13A123EA648C3FDCC89ECB1BD29DC1E01
-:10143000BB81DA6374FE6FB7B13C5BFF16A9188CF1
-:1014400046C7166922E8AFA7F83CBD5916C4F35B3E
-:101450001A13ECBFFBDF5CCEDE2C8BE03EA7366FB1
-:10146000D0ED1BA17C610ADB27A85E61E77EA87630
-:1014700096D73574E5F93082AFE7396D782D75323E
-:101480007B7BC1D5E7B2465A3F4BFC4102E3A1FA50
-:10149000256EBED80BD03EEC178CB0F32BD4A6F73C
-:1014A000ABE2C9B390C3CD6AE067A03F764A9BC266
-:1014B0000ED403633FD772A6FCF9F5CD554D3F918D
-:1014C00042EB7DCDFA0F1E908F1D41E3EF4E89EB6D
-:1014D0006B5AD08EF477772483BD7931297836859D
-:1014E000FBBB617F615BFFF376D4A726BA9BEBB9A8
-:1014F000CFC9E653F5B0F7E417BA67798C9FA4CE4D
-:1015000029F1F5437F07EA9F6DD5FF0DAE0F56C455
-:101510008F43662A15BF06FA556B811EB8B6F51FB4
-:1015200040FF714A92FE1EDC9729FAFBF0FD3F59FD
-:10153000F50F989EAE727D981FDDEF90689E21702A
-:10154000F1617E2CBD3E1F9D33EC814136CF7A5038
-:10155000BBC67976D2EB1A585BE8F73D65F1E3ED4F
-:101560004F717EA27286F982623F8CDF4DF478EB78
-:1015700097284FE75F7562BE7B2800FBBACE4CB25E
-:101580009003317A4E9C63D0D8CFECC281FBA50387
-:10159000CC2E2478FFA3AF790F407C77E5142EC7BB
-:1015A0007C3FC61DF71BF7498B766F4E95C6249F6F
-:1015B0000FF3728DA94C3E1F4FBD46F9CC60F50864
-:1015C000395515765DEB62F57E98CAF82C294D12D7
-:1015D000F9E9F94E26873D29D7363F4FACC8FDFCC7
-:1015E000FC21E441F519F3F51EE1F220F415ED6755
-:1015F00019CC17ED6730E9DAFA9959F205F0B1D84C
-:101600009720274B067F78C0C9F8E90EDEDFB38A42
-:10161000BECCC9E477B97364F95DE564F2BBDA69FD
-:1016200094DF5B9D4C7EBFEC64F27B9BF373C8EF51
-:1016300047203F90E7C8FDF8E49451EF505C7C17D9
-:10164000D4BF5891F83E6FF21B29C6FE58DC1B240C
-:101650003A5B2C9F89C50D14BFEAB8AFE34D637D9B
-:10166000EFF0758BEAB1CD50EF3BBCFD1DFFC6E836
-:1016700007747C3E8E5C0A3ACAB60637EC8B4DB4D2
-:10168000CE059C6C9D2BB7B17D17E4246DBFD03087
-:101690009E6D40B7A1F184A865177F3CA1B8E3E92E
-:1016A00036D617339EDD50AF18CF82ABA74694478E
-:1016B000BF904757448675DBAFC45F17CE38D9BAA1
-:1016C0003990AC3F09F432F397B886397F25DA1F99
-:1016D0007356A90843FF4A14A6078916E99163C601
-:1016E0005792DF20C61DB4C4FAD97AE3EBC9E79C50
-:1016F0004372F71CF2DF3EB69F87F2F58FA19DDBA8
-:10170000C7B956E1FEAF4F98DE7CEB4F5BAC69B4D6
-:101710009DD5197BBF03D75F3B59DE4BC3C51C2743
-:101720004C434F19DB17D938919DA7D62819CF55AF
-:10173000FBB59077AEFFAE41BEDFCA913FBB7C7C6C
-:101740005EBD40E9D3CDF5528F23F7DAF4D2DC2F1A
-:10175000A0FD955308E2E3C6FD2A9EBF25E4E67688
-:10176000985B760E820E79145FA5F7167A3F0846CD
-:1017700037ED47309B10F76C2C1752F19C04BD17C6
-:10178000C651ADE9E7E14AF5D04770A57AE8775C44
-:101790000FF57D1E3D7402C644BF6FA23CD40D7C84
-:1017A000A88479DE2FB747F8584BF28FC5FDBDA945
-:1017B000B6DE035A08F206F3D93ED544ED46C0DE44
-:1017C00080C49504BF6725AEE58FAFB58311B083A4
-:1017D000E23AF0A3BECCED9436685F83F62CF8FBBA
-:1017E0003FAF1119E3F0E6FA1A27F3753F85F3F3DB
-:1017F000C475685FE9578CFEB54A7778F7EC22F834
-:10180000BDB33BD83EAC2B77905585804F8204CE3C
-:10181000E154E915F23745BFBDA953193EE5FD5422
-:1018200089A42C2C88EA91CA7E12595084F806F3B8
-:1018300066A11E0FAF275808EB7D9A02F1BED712A2
-:10184000FC4ED3E372303F35C6DF584E8C7885CEE0
-:10185000FF0DA9E371FE6F4C65EBD074B8D2F92F80
-:1018600080EFFA9C4CFF3D2E0766C2F360060B41E9
-:10187000D3F2BE54C62FB352E77E7E3ED941D8EF95
-:10188000F202FFC6C6AB9FE5FAE1E8F8A00EED5400
-:10189000FD6859E724FAC986E6063CFF78C175FD64
-:1018A0009F9C85FCDB2C15E3818D8F18D7911F72CF
-:1018B000FCF3D2B5EB19C41154FF2D81767710A635
-:1018C000FF426EF6FBA30D13731E65F0911A9899F3
-:1018D000D1736DAB5CCBF0DCAEAF3FE79D0DE76045
-:1018E000A95C3F2F74B7AB6B615E21DF348E3E0F76
-:1018F0000EF58F6A6FC33A15FFFC97CD1C2752393E
-:101900006E4865F2BB16E6E785F1FA1DA97F41FC3A
-:101910002FF4505061FA86DA4D21B09B565DDE748B
-:101920001C96A9D5646F35C437285FFE2DF4F3CB20
-:10193000F643C7D94F12862641BB941FFF8E8F678F
-:101940000BE7C76F717EFCF6E719D7D753191F272E
-:10195000C29F02870BFC4DF5FC23A94CCF7B9C5FFB
-:10196000CCBAF10FA90C77079DD7B86EDCFA05B495
-:101970004FF1C641685F4F2523E2DBE7F8F87F9C13
-:101980003A846F7F0CDF2DB5EB3F81EB10DE2838FA
-:10199000F91BC8938BE28D7699E30D25D69FEDA7B1
-:1019A000F88BE7D5DD6999179513B53F3E0EA94F22
-:1019B0001DC2214751AFEC6638A47EA8DFBEDE30E1
-:1019C000C8E1242EEFEF307DDCA0F6DC09FA594D9A
-:1019D00067F3A8A4337CF92A9FD7F7A494B8FECD67
-:1019E000AE687B5DC85F5B587B72F22CF67B204251
-:1019F000AF58256C47F887EBD3D977A29D45FC2AD1
-:101A000070AAB99D5FA40ED95FBFC071DD2FF60724
-:101A1000EBEF40BBFE285D23B17405FD62991743CF
-:101A20004F8EEB12E1B818FAFD078EA789B5334443
-:101A3000BF607C3D7BAB4B167CF2BBD411F8A39FFF
-:101A4000F3C7C5287F5CE4FC31908AF884CDC3EDF0
-:101A5000E38CFBCEFF90CAE8B39BD349CC97B9FF88
-:101A60000FF2F743F4F09C7C2616D7FAF3D356AD69
-:101A700006BF6593ECB3D0FBFF032FADAD0C008028
-:101A8000000000001F8B080000000000000BE57D37
-:101A90000B6014D5B9F0999DD9D94DB29B4C924D9C
-:101AA000B281246C20D858032E21C42841264F022D
-:101AB000448C88888ABA014C42802422B6B6D5CBA1
-:101AC0006242785A637D142DB60B420B16DB88A94F
-:101AD000A518700382F80EB68AD6DB1AC4F25084B9
-:101AE00005B55D5A5AEFF9BE73263BB3D905D4B696
-:101AF000B7F7FFE3ED3D9C33E7F9BDBFEF7C334B18
-:101B00000891482A215790FEBF1C13AD17F38A7C19
-:101B1000D42779F208991420AACF46C817F0373E87
-:101B200054C629022129842C946BE29431744079A3
-:101B30008BAB6604213DA57DF36B22F4BF2789F5AD
-:101B4000BF21635D798A8BF6F7D27658DF49FF2D86
-:101B5000127263438FE8D18DBBE1A3C373D408F342
-:101B60007C37C944085DAF75A67B9FAB804EE334DC
-:101B7000B9379281FD1E4C94B1DF84A13E2981F6D4
-:101B80007BFD1451D6D37E374E13541F3D57253F4E
-:101B90005702DF578E2261FF32A8C338B96F4EA4B7
-:101BA000735CC69F57B988DA49E7A95288BA3542AB
-:101BB000BFB17C9F136223CF73139F672261F384AD
-:101BC0003FBF95EF6B4269E4F157F2F967389FAE7A
-:101BD0004822B09F7566805FBE592D56E8B81551F2
-:101BE000F0902A95AA80AF180A3A733E21B7D0B177
-:101BF000263AC1AD80735A3E2C7A2AE1B98782C356
-:101C0000990F94E01D0478ADB0A913605E7BAC5AC7
-:101C100005E538499D08E54FCCEA242809F113521F
-:101C200048C8144E3F53AC36BF184FFF51643EDED8
-:101C300067656D5F0C85FF3F53397C092102F10B0D
-:101C40005F5C02759F08F35FE1DAF78E40FB5FA1EE
-:101C50008D3B2A858DCB500EC7F1BA88FB42F86CBC
-:101C600037FFD065330D3CA7566EB779AC0087536C
-:101C7000B19E5AD867AB73BDCD45E1FDB2A7D3EA9B
-:101C8000A6ED1F271084E3E93875369CBB753B69C8
-:101C9000E8A4ED629CD0D2A9835F8362C2F5E62AF4
-:101CA0000C6F6F48EA5C986F8A556D84725A16C53E
-:101CB000139DF7D6E4BE457AB8DFC1F1343F898D74
-:101CC000BF4566FDC2F739973F2F96046F1CECC9DC
-:101CD000B6EF4331027F4E827F51FE293EAA4C9FD0
-:101CE000E1A0385B2EBA4DB42EE70A11F9D41BE2FD
-:101CF000532FF2A98BF2A99DD2871C993E82BC7FFB
-:101D00004514BA1CC3F7590ECF238C1FC1E9B6DCAA
-:101D1000D123123ABE98F35B78BFBA2491F1B19BFC
-:101D200054459AE787A17DFF10F7ADB07DE79B6B27
-:101D30001E85FA4C657F45226D2EB9CF319D380046
-:101D40001E2662C946385941AE491C4E749B04EAAE
-:101D50000BADAC2EC5CE2709B4CC72FA568D04F863
-:101D6000B599DD2E5AFFE0E80722A174B6F1A1D3A0
-:101D700002A1F2627B8090E46C98478619E1CFF46F
-:101D80008530703EFACC2569EB51D05C7994A81669
-:101D90004ABF571605A69278C378F2059DCF16E87C
-:101DA000F50A803F2BF1C65D8A64FCBB9C549C15F0
-:101DB000E74BA3EBC279E4CF880FCEA33A3DD564BD
-:101DC00024218981BE1F3563BBCD3D01CF456CC049
-:101DD0006FA1732E44FED3F625DBFA9EB89FF6EF73
-:101DE000FE3CD67D2F9C3B50798CED8778EDC0D79B
-:101DF00062B51BE43B2116DC9F89FE077C362E482A
-:101E0000F79BCBF70B8B14E8F64F069EE761B1E624
-:101E100015C0C7AD56A2C6E7A37C7815F86198999E
-:101E200076A0706C57049F97F66B7F68CEF26C902B
-:101E3000D7AB25F77002744EB60994CEC7D275EFB2
-:101E4000A272472E223685D665273B7FFB7D8E7595
-:101E500071023C97C84CFA7C6CC07F46A0708877B2
-:101E6000D6552BF41C321F2F50C0C178C1A59099B4
-:101E7000F940B7BD2241F9E0447868FCA37E8308AD
-:101E800087ADA86A08D057B944BC56DA5F70B279FA
-:101E9000AF2401910C033C504540CB52E2C6F27E88
-:101EA000D1730CCE6395295EE9FEAD26AB6F890038
-:101EB000F8AB79B50AE15EAE1CCE0DC9B368720805
-:101EC00020775883ABF8F5E55EC5A2C87CF58F1086
-:101ED000DFFC03F98630BD3C6D28933B7BEC7D3302
-:101EE000F57CBF5C61F26939976B44627CB65056F1
-:101EF000CD89E7E0F3D55C1E8E4862F2B39544E6E7
-:101F0000E36712D9BCD3EEF5B50FA2F09B9224B8CB
-:101F1000410F576CA99506BB42FD06717D989CAA9E
-:101F20003A60DDD6EDEEA33E07681F19F57BFBBBDB
-:101F30006406CC5FCBE5E7DFF8BC6712D93E86F0DC
-:101F4000FA41C13E23125CB213FBE1929D08E7F413
-:101F500030B88871A3027EBA0E19CCD7310BB84EB7
-:101F6000CF50261F872719D719CAE51F95FB1727BA
-:101F7000A2DCF76540BF97CD6C7FE1EBBA43EBBACB
-:101F800071DDF96CDD4920E781FF5DFB5E10757640
-:101F9000D7A4808780DD033C6C2A0CC97BD9E51768
-:101FA0005B687B7114393F8E9F9FAE330EF6455AA6
-:101FB000181EFDA9EA9550A776C17858BF67A88278
-:101FC000F2F2F54126B29EF2656DFAD0EF83D8D4D5
-:101FD000E6F95522A3879EEC76E72C8A2F3940DC60
-:101FE00016A4F306947BC55CBEB46EF71078EE1DA4
-:101FF0004465A66EBC1C986525363CCA3FBED0FA27
-:10200000533E6A0F0C4DF044C08B56AE5ACC44116F
-:10201000712DC0710BF9B8F07EB68777C5C1FC2B66
-:10202000A1FF370899CAF1430F8CFB9BC479A735F0
-:10203000B03EAE8FF6DB9E3BDBB01F7C4EF9A83D79
-:10204000F78938B097BA33A91E0039F5928872B271
-:10205000DDCEF0D89E5E47F4F66899D32F1E8679C0
-:10206000CECE26D329FE8A9D1E72913DB4EFE2DCCE
-:102070003AAFE0C0F66763E83CDF4EBC08F12EE7FC
-:102080007948A50DE0D249EAE8F965C52FBA695942
-:102090001620FEF105D09FCA7981CDE7B2EBE7218A
-:1020A0009D308FECA6F400E3027EDCCFF6A3E7863A
-:1020B000A32DCF6490DF1A5F52BBEE5EC07FB97272
-:1020C0004D79229DBF714B76BE48E7AF74F6C8B319
-:1020D000F2506EB7029DFC2A456D4BFC5FB4E7667B
-:1020E000109F19F03E218BE981294D826F3D854F6C
-:1020F0007B989DF018E7C7B12179B716F9AB48B3C3
-:1021000013D4C713CF6D07AF83E7E7B0837F06CF44
-:1021100023D8C19B12991DBC19D6A376F09389CC04
-:102120000EFE39AEFF15E1768D42343BB40BE673FB
-:102130002472B9FA7B668F86EFFF1E7EFEE5F4AC53
-:10214000BD4097924F6274CEF8F40ACEA7938E5298
-:102150007EC91B48FFDD94FEBD94FE4E53BB49CCA7
-:102160008E4E4FFE0BE4CB928719DFB73A7721DF13
-:102170003DCFF9B39BAFDF9D2B56033E5F26A222D6
-:102180000A03E76BCFF43841AE87F39F7AD648CF86
-:10219000654EDFEA7CE09B7DB3DDB0AD707E946977
-:1021A000593722B4EFC3C0876374F2890852E5053A
-:1021B000F021CCE319017646A204FCD74AD8BADE56
-:1021C0007D22EA89687C44E9E624E0AF1F2E006C9A
-:1021D000DDFE29DD04804E289F9DFA3AF4B28AD3B1
-:1021E00007F543FE0AF3E4F27A6D14FF4248EAD79A
-:1021F0000F4212F0F74CA687B2135D4847B5C421D1
-:10220000837E51C5CC2C902F745E7312EDFF66C295
-:10221000B9E7B525F5F39F0DFA93BBD8BCAF809114
-:102220003D66E0BC1392A8FD11619E0CBEBF1BA3CE
-:10223000F80B399A7D92D76F9FA4C37A39C037744F
-:10224000FD1D29EA60A86B7C53CCED961705A35EB3
-:10225000BEA4DFDF677A2E8DDB2F644EFFBC390012
-:102260001F0D9E9A1D50CBE583364F2EE7BF614967
-:102270000A1BDFC0C63BA04EDB2BB9FF44E172292D
-:10228000C2DBCA9E9FCF2F7A4061718B3ABE2F2945
-:1022900051D1F41BC2B52A9ADFA584F43FAEE7669C
-:1022A000FD4770F8D07615DBABD93EC62A0CEFE1BE
-:1022B000F18368F8D1E0EFE4E723B96C7EE2ED87C3
-:1022C000DB64985FA39768707B3381C16D9206B71A
-:1022D000363E4F983C5825755A9508E7BC91D3ABCC
-:1022E000568FCB35CA8768F1943121F8D4221C0A65
-:1022F000D8BEA3C5572EE7FDAF4CEA875F038EB368
-:10230000B1FD3EC0E5356D9F87ED196CBE3B42EDDA
-:102310004DD8EE64FDA3F9FD7770FD3537A97FDC5C
-:102320009D38CEC1C685C713B4B299EF6F7E68DC05
-:10233000DD382E878D7386F0BE18DBAB58FBD78D4A
-:10234000BF39F9BADF0DC16515F2BDCACEFFB7843A
-:10235000FEF6EF637B315B379AFCF85B029B6F05FF
-:102360009FEF4AF08BE91C8941922B39C06B8A752B
-:102370004FA05DD282AA1FF447E967B20BE47485CF
-:1023800068F30A541E4B2E2BFAC9311251C1AFED1E
-:10239000F9FC5BCEBE3CACFB41AF2F8B29B182DF99
-:1023A000B93C5B72833E2C794062FEF57113CAFB27
-:1023B0004A713ECEB34BD1ECDCDB0D7EB44B715594
-:1023C000C7C03EAC227131FFBFFA2AFA7C3C97D7D6
-:1023D000BBACC926986F6C268B178C77D5A1BF4EE6
-:1023E000CE323F5AA5FF31F9ADA25E96F93829A346
-:1023F0008508581AFD6D99AC3E258E44BD8076D473
-:10240000D880D1FF965D9547607E99E8C6D175BBAF
-:1024100093EC0EB4A772C8F02F28FF58720562A182
-:10242000FE4585E4F1031E26BAEA94527A1E4B86D5
-:10243000C70A7238C7EC1F0CF184B60CD9ED05360B
-:102440007CA8DC9A0DFE5607F5CF110E6AD2352313
-:102450004278B214AB04E890E204F9ABBFB4B132F5
-:102460002599D1F1F1240BE2B382D7B5E7E1782FBA
-:102470004C8E65728458BD1FE6829C104802A5C32D
-:1024800005A42F0BE8312D9DE98F26535F2AD44FE9
-:102490009240AA8396AD1D525524FFE727DC2F5B9F
-:1024A000618A6C2FFDC43CF17D80830471834B31C4
-:1024B0002EE0B10C0BC50F347B558B2344B35BEF7F
-:1024C000176B8EC13C82E23F03FD07DABF5E76EEFA
-:1024D0000C26A7B552DB472D87CBE0642B9E6FE718
-:1024E000DD6564960BF1F439C7D3BECB002AD973EE
-:1024F00014C0D34BD98FE4405CCA9AFD9003F8B363
-:102500008A30FBB4C205B29890476D9EB3493AFB3E
-:1025100066624E2DDA4DC5592D684F2D8BE2977EA0
-:1025200047C38F4627368F39790CC4BF165A61BC12
-:10253000A4D4C442B93338154B6AF75AE0F9B20C47
-:10254000563F1F1EDEE37229DAFE27805E80784D3B
-:1025500046FF3952607EFADC2BE787CEA1DB5F7A3B
-:1025600072CAC0FD5993993ED2F625E570BACC35B2
-:10257000D25D4D32933397246BFEE205D3DDDB173A
-:102580004277E1E79D98BDA8EA6212DABF765EED78
-:10259000FCF4BCA3E13C15123BFF46C5A3C21414D6
-:1025A000CE05008701E7B246D6FBAE64D397E5A31C
-:1025B0004792865DF879BEC4BCD393BF049CF68C69
-:1025C000539D204FDA52287D523CB509ACD4FADB3A
-:1025D000397D3EC3CB2F2327867F89F39538851716
-:1025E000401F8EF71C2C8365CA8B4781DA017EACB5
-:1025F000073C94E63D20CDA2F5F6BB67A3FCDC3397
-:10260000AE05F7BDCC6EDCAF56A6707C1467A9C8CA
-:102610007F6D9CFF2A08F323B57ECFF37385F347C4
-:10262000F87CE17CFDA84DBD0BF69592CCF61FF22F
-:10263000FF7A45BDFF57CAF5D738EB1D86F8C73876
-:10264000EEFF2DFB6CA8CD4B0F7A9AEAB57F8AFF7F
-:1026500077863E013F29A3D4AAF7FFDAAC65D8BE3E
-:102660002C53ADBAD401FA5874DF4B107EE80F7AC0
-:102670000551D918C11F5C9629FBC7D3E71685FC05
-:1026800014F65746F525C45F2C8A4A2E1A31D02FEE
-:10269000DC652D23103739AD9067C11F3BDF7936DC
-:1026A000271BFD4209FC423E3FFA854A0BE9C378ED
-:1026B0004F1901BB06DA5D2340EEA8C463073D4213
-:1026C000FD429D7C3A6DBD03F93D7C3D2AB79E06D7
-:1026D0007CB5298C8FC3FD413999D9C19A9C0DA72E
-:1026E000870A27A39B18BA7533931BDB9323C8FB78
-:1026F0002F2F9FE694830B703D59B2075CB5EB8298
-:1027000001095C9E6F27337EAAB13DDD06CFB5F986
-:10271000C3F1434FAE423C1DEC1916BFA1F61AB5EA
-:10272000A3CCD45E5B2984D65FC6E11D0D1FCB40D0
-:102730005F47E0A303C9262E7FC2E3447718EF5F0B
-:10274000142F7114B2B83E89007F91DB49CB29BFA9
-:10275000C0FDCD32B3DBA9009D6616BFE3017F3E0D
-:1027600053C6FB0822B538AFB10F3CE772889F45CE
-:10277000D8DF9F939310AED60C93C13E23E41E8303
-:10278000FD18EDDC84EFCBCCCF25003C73F5F00CCD
-:102790003B77B982E706B31EE68D37B9899FF245CC
-:1027A0007C1671A3C08A37611C56E37385F3B92682
-:1027B0000F6C0A1B77B56318B3CF445B40A4E75F87
-:1027C000E5A0F6349DA755DD857A551B9FC0CF6FD8
-:1027D0001BC7E28D36BB5F5122C0E17ECEE7D1CE72
-:1027E000D9A14A89E5747FF72BCCFE96C6996A7CFD
-:1027F000188F62F15A85C34E2C29B082DD3E091C28
-:10280000F814D8CF56451FB712F97EE2EC743FE7B3
-:1028100090932BC2F61393DB570EFB97B2552551BD
-:10282000B7FF0A876607F4227F479BEF3E2EE763D8
-:1028300072DCA40EEC0D9BDB0FF75A316A5D218828
-:10284000C5D85C3799AD6B8F550B475B7474D891C5
-:102850002947BC8FF82F0793FF7649AD81717645E4
-:1028600022704F66E7F672B479A3EDE37CEBDDC42A
-:10287000CF3B603D5764BB62A883C90D69DCD61AA3
-:1028800090D36484448647D013290EC6A7F1729F63
-:102890000BFC754A8F9E48F3890E99C3FB5FC41FDA
-:1028A0009ADD5DD2B56F28DD6FAB4D720B20BF8A0C
-:1028B0008EF6BA74F0A17A7D9643173F106D1E9480
-:1028C0006FA28BDDBB575998BFBD679CF19EAC8151
-:1028D000C3EF7D5E46930BE31D9A3DF6AF39E79754
-:1028E000C55F05E04E07970E800B01FEFA415B6B5A
-:1028F000047949E1D3FE55E0B39AC3E5694ED7D1D7
-:10290000E033CA61FA97D241387CCEC7D7213EF373
-:10291000914311E0D86A97D3671BF8BF03ED904845
-:10292000FDEA74E78DC6871A7DDCC4F14205A42157
-:102930002E203BBCBDCCAFBCD3A8E7C4F96E2E9F04
-:10294000C9590AB744DE3FD146FC71F1A1F9E572DD
-:10295000633CE179078F0BC4901880CF69F754016D
-:10296000F2142CA699A394A1B04487007A2215E60C
-:102970001949C8035C7E86EBC11495F9C983498B5C
-:10298000C0F44A06EECFC1F711AE07D3A95F03F139
-:10299000183822F8D38369DD0A360851F11E5CF03D
-:1029A0009AD05F76129F00F367903E2C87402A02F0
-:1029B0009D3F9BF40A39147F0F54D48D02F9FD0E0C
-:1029C0009CE392D039CE678F6AA5667FACFE37C193
-:1029D000FB93B07DFE1F82F792321DBCE51423DD10
-:1029E0007C597837707887C7F38A219E970DF13C20
-:1029F000FF6EE053F92CB33F7AFE2E637CAF2D9B24
-:102A0000C5F32AC4EA35780FEA92D1FD9072FB56DD
-:102A1000419E936677A2CE1B168AFB594FFD4082DA
-:102A2000380A918E229CF06EC885F22C3B05E53168
-:102A3000B323C6F3FDCBD973AC70EF1DF29FFC221C
-:102A4000B33798BD24733A287696A2FFD276F6DC87
-:102A500076C785FA493BA53D787FADF947AD8159E9
-:102A6000E82F858FF34BFEF7E0FCFE80EC827C9331
-:102A70006E7E2FD67D6AAF214E1BEE076976D57824
-:102A8000BEFFB28067DFA570BFA5CC222CBEC9E017
-:102A900020F375DA9CA7F11EFCF9B326F4B74E7348
-:102AA0007FAB18FC2C3BF377EAEC03CF794DCA459A
-:102AB0008638BCE63FC138C8AB2B53FC22D8739A8A
-:102AC000FF04ED2EFB40FFA9CA127805F637E51585
-:102AD00011F342A2C137DC6F0AD73F335398FEF996
-:102AE000560A8F1784C1538BF785DF4BB76BFC27D2
-:102AF00079053DFF87AF2FEF9A88FB278A2E1E3B73
-:102B000034144F14542FB92B3F143F8C10376C01E1
-:102B10003AD4E2869A1ED3E8D842FB5AF19E397223
-:102B20003CB13B7BEF30E617BE900CFC59A1B0B82E
-:102B300091B63FEA17DE93A2C3477180E96DCB7F60
-:102B4000B5F42DA1F02549C4CDFC83169795D62B5D
-:102B50001592BC12F9CC86795AC50E01F94EF2C70E
-:102B600060BDF2B8DB1743EB965D2F89A203D69BBD
-:102B700045628410FD68791D6D810F5601FE4E1F60
-:102B800097DCE7F2BB2B218866F0936243F844F9A7
-:102B90009664A83F22791E4D413B6150689C08F91C
-:102BA00060430DF967CF48EA63D06FBA55FD11F65F
-:102BB000FFCFC3FB2F53305EBCF72BE13DB40ED3E8
-:102BC0000760B39174DD7A36DA7839ACE342FAEF14
-:102BD0008F4B2F22781FB309700671964F880FE232
-:102BE0002CCF995F14411FB5F379AE201D2E7918B3
-:102BF000DB2FF4DBBCD1B90EE8E2AD946C9CEF396D
-:102C00009B67F528DABE6F83340AE236ADAE67AC57
-:102C1000903FBB6B637B469F8EFFF66DF60C89E49D
-:102C20001F6A25FD4B3015E1B9E259A98A2627B65E
-:102C30008B501F609F6DE852609DCD1BAD3322C548
-:102C400035E454C6EF576C60766D55AEC90DE2ADF4
-:102C50009878A524B88F7113B79F36C48DD8DA5BE6
-:102C60000ABA285BC47B0D5ADF1D4FEB716354F425
-:102C70000F2E1EB115C75FFC49A99BE5517A6DF96E
-:102C8000B4BE2AB774CC4A5A1F12EB39067C45F5FC
-:102C90004C8784FAB4330EF200E2464C4D59496B2E
-:102CA0007102A98964E7FE3D85D9799BCD1A5C251F
-:102CB000CC83DCB55146FEDA972EE2FD1385DB7C32
-:102CC000A8FF393D8E504A24E5AAB71CE058413A86
-:102CD0005BC19F2A775DF3423CF90AF02BD8AA002A
-:102CE000FFAF8A6287BFC5F7874284D2CFDE0D6D02
-:102CF00037920879D4FD79D671AA2515EE57F8BD1B
-:102D00002E714E45FA898EEF7B99BFD9E96F8DA55B
-:102D100070BC624BC720FDFCEF42D0356520BE2160
-:102D2000FF995C0AF9B71ECCA76D3D6A42F8BD9CBD
-:102D300027F8040A9FBDB922B5D9E8AE72ACBEE14E
-:102D4000B4BE9AD371F596FD6D8380E5531DB8EE40
-:102D5000CBB94F58597EEB85C7AF47533E6884FBCC
-:102D6000648A8F094AACCF45F1350FA6A0F5718A68
-:102D7000D5E7A7EBF5D87BCB12E812CFA508EEF587
-:102D8000402FB94401F9812E8889214AA175101973
-:102D9000484F0E82F95CAB0AF3D6435C6C6586AB98
-:102DA00013F20D778CB062BE59783EF10EA1E58525
-:102DB00044884B250A28AFF7E6BE89F7747B332C8D
-:102DC00004E815137EE9F3B624C6A7710546FBB3E4
-:102DD0002A359BFB9FC46B290CED2B2EC7AAC6502E
-:102DE000427A31918DDF9723F880DEF6B9B87CA066
-:102DF000E7DD080691D4214D1F111DAF2F0D9FE077
-:102E0000D2EC62413BA769E0399E137CCB87C23983
-:102E10002EA6E7A0757BAE80EBDB9595B7132C8BC8
-:102E2000EAE11E337CFFF7A632FF50A664970BF24F
-:102E3000AD73F9447D7E8C5C74FB145B3CE631A180
-:102E40005D99962BE079261E65F7B903F2B315E27A
-:102E5000910DF8A156476A68BEB8CF9EFD36E4FFD3
-:102E60004E2E12FC31B01F9EDF4CFFAF07F48B9C3F
-:102E700053CBF2AF73D7E179261599DD709733C93B
-:102E8000E6EB28A5F5978E4918CF9E9C3301F3AB4E
-:102E9000C3D75FA9107F1585EF4B7912C23BE6A21D
-:102EA00027709ED7F34C286F26433E36E42FEBF372
-:102EB000AA511F1AF3B9278BFFAD9640B39BF12B94
-:102EC00091BC8340BE4F711AE1673F6ABC2FAE2EA2
-:102ED000B018EA93F3E4303DEC457A793193D1C5EB
-:102EE0008B170BBEF5D9213A9B7434C90774067F42
-:102EF00062A1018E8673C6056415E0B7EFE29F3DBF
-:102F000008F72471AE65B7E33D3887BF4627711CCB
-:102F1000EFF68C5F7F1BF49406FF703AB870FC5F8D
-:102F2000535302F82FD0EEEFC3F01F866F8C416A27
-:102F3000E7183610EFB87EF6407C6B7430E0DCF7B3
-:102F4000752D1F4AF1FAB29D3E003CAF937DF70A02
-:102F5000213C9D17AF392548372B950E1BC8FD988E
-:102F60008B0ED9C03FD0E88288DD057A7BFF9F8534
-:102F7000EFD2D5027326DD820FE27A6FC0A3CB4376
-:102F8000EBBC98DA9FD7F5622AD855352C8FA3551C
-:102F9000CD67EF5D15307D1A2E1FFE902AE2B81E18
-:102FA000F38B19E7CA53ADB67908DC8FB542BE1D65
-:102FB0003D9FBCBA16DE6820F2B45A949764B5C03F
-:102FC000F2108A7F8BF27D8ED3B75488B01E5A32AE
-:102FD000B84F17937BC5C9D89FCCD0F2926ADEC791
-:102FE000FD4F63F50BDDD76BFFA47DFD9ED20A8BF1
-:102FF0007731BBF96A1E97D7ECEE2936967738A55C
-:1030000058447CBCBE41F0617E24EDE7A574D2C873
-:10301000C9F66A6E079E2E7AA67D940BEC41D560A8
-:10302000770AC53D68F7251419FDC14435D680FFE0
-:10303000E4AA24433DA56690A17FDA8CA1C6B8829C
-:10304000E79B86E7831BF20DF5CC962B0CFD87DC06
-:10305000556AA8677B2719FA0F5B3ED5501FDE71B2
-:10306000A3A1FF37D6CC323CBFD8D768787EC9A69B
-:103070008586FA88CEEF1AFA5FBAED5EC3F351FE89
-:103080009586E7A3F7FDC0501FD3FB98A1FF65EF1E
-:10309000AC373CBFBCEF49C3F3B147B71AEAE30210
-:1030A000DB0DFDC7077719EA25E41543FF32EB6F07
-:1030B0000DF50AE53D43FF09CE4386E7135D1F1B6F
-:1030C0009E6B743039F75343FB55EEBF85BDA75354
-:1030D000C3E21C100F18068F3AB08C259DEC5E875A
-:1030E000F462F960A1A73C0DE8F3C7DE7648486AB0
-:1030F000F506FE0857D3AF170D4B60F6934AF4F26E
-:1031000053CB4FA57E8B378692427C90D2ED684A96
-:103110007741014B2548256B32C47B62B04C0A26AF
-:10312000637B7230114B477030B6A704D3B14C0D9E
-:103130000EC3322D988DA533780996E9C18BB11C49
-:10314000141C8DE30607476199111C8BED99C1CBC7
-:10315000B1CC0A9661FB90600996AEE0642CB38313
-:1031600013B11C1ABC16FB0D0B5E83654EF0266C6A
-:103170001F1EBC01CB8B82B3B1FC46B016CBDCE08A
-:103180003C2C2F0ECEC5F29BC13B70DC25C1DBB1C0
-:10319000CC0B7E0FDB4704BF83E5C8602B969706F8
-:1031A0009760E90EAEC27EA3822BB0CC0F3E88EDB5
-:1031B000A3830F605910FC11B68F093E8A6561F038
-:1031C000092C2F0BAEC3B228F8732C2F0F6EC6F24A
-:1031D0008AE033386E6CF0692C8B83CF61FBB8E0EA
-:1031E0006FB0BC32B81BDBC7077BB05483AF607BCA
-:1031F00049F0252C4B83BFC5F6B2E07E2CCB83EF84
-:10320000617B45F05D2C2B8387B09C103C88655515
-:10321000F0632C27068F613929F8298E9B1C3C8589
-:103220006575F06FD87E55F00C96FDF22E6ABEB231
-:10323000C784FE2CF753A3FB0B5E949766FE5E1CBF
-:10324000E45663FE7F8BE0C378A1A3EF05A89B8BB8
-:103250002C182FBC9904F03D813F903E3BC8D39E73
-:10326000CB8F6440BCE9F5147FA63EDFC1CCE30000
-:1032700015E27109FCD5298E5D29A04F6FA6CD906E
-:103280006744D42F300F720ACF83BC59A20E16DDCB
-:10329000EA7E98E172ECE7B7D0FACC6AA2E6D3FEF8
-:1032A000ED975B30AEDF9E4FFD205ADE97CDF26585
-:1032B000BBD298BE7C2A8DF9A5CFA531FFEAC942C1
-:1032C00096C733F3F6E18C9FCA93CFE33731387C4E
-:1032D0006324CFB3B505B2303FF602C79D48E57908
-:1032E000B5BCFF836935CFA7D1766F29C96DB1858C
-:1032F000FAD1F65D51DAF7803C086FDF6562F8F0CD
-:10330000BE2D723FA12661EA39FC84D717F77EF300
-:1033100085E1A1FA1B51FC504296B0FBC35DC7AAE0
-:10332000AFA7FAF0EA22D14D2507F9EFC5DBC67D3C
-:10333000389CAD0BF999DE5211E317338BF7EF4947
-:10334000A6F5998B1231EFBE7F5FA5667C3EC5F96D
-:10335000F6375FA047BFB9E537E33E34C4453D6863
-:1033600077DDC16994A8E6BFF669CF915E59DCF7B5
-:103370000E58DC05F2CF8CF3F6AA66DFB9F263884B
-:103380006A21AA81EE19BC56C1FEC1F7275613ACBB
-:103390001BCFFB50B8A2DEF7C6CBBE56019C7757B9
-:1033A00002D05D5C5E809C2BBE0CF0943051A1CFAE
-:1033B00006764C3478A63819FD2514AB4E2FC54F30
-:1033C000DBDF45BCE7DA9D58A800FD7FDF9693065A
-:1033D000FCE174327A6DEB7917E35B090501E2B524
-:1033E000B1FB739705E2F8562C972E7663D9B6B8E1
-:1033F00008CB95193FB042BC444C91201398C4644B
-:10340000CEC17890B6BE397196B5C44DE75B63A95D
-:103410008610920871066A2224D2FA12EA539C4D51
-:103420006374FDBAF3431BF0C3D93417D64513BBFD
-:10343000378E2BF0AB909710E7564A2557A81DFF03
-:103440001CD8BE1EFC91D749DFEA6B018E2A7B1F78
-:10345000A395BF6FDA5A329CC3551B1786F7303CD1
-:103460008BB21BEFADC558DA3F2F3A5EF39C2C2F81
-:1034700001E84BA2F4F529DF3751E34C309F86DF9A
-:10348000D35200F3A95A85C87997851ADC155539A6
-:10349000D73D0A51A4BFEAE5A92D6F5B183DDB506B
-:1034A000BE621DF2B9B8BCDA9BA6163BE9FC8BAE36
-:1034B000E472202309E5006D9F7E056DDF66627E64
-:1034C0008A3749467EA14048803C5F6275254C3D65
-:1034D000471EC4B2C58A2A99E17EC09500F05AC63B
-:1034E000F3F5E00D65BD1CF857F50BC90B1F9E2BBE
-:1034F000BCFF3613E7ABD8183C97C8E1A18D9BEF12
-:10350000E4F238BBA6D689F1115706C8555A9FED8B
-:103510001C83E7CF00BEA2F5DBB0AEF4D7EBB1BFA2
-:1035200093F5C7449A0B90C3745C138E93FAE769C2
-:10353000C1BAAD7FDD85B88EA3BFBE08EB19ACFF65
-:1035400085AEA395FDE77F93C9C9CF24352189C2F4
-:10355000A7E6AED935E5546F5F7BD75C2C3F58DCCE
-:10356000AB825C3D4CE5491B856B4DC93007F83992
-:10357000D75E35CCE6D2D16B3D8F6BEE5A6EAE0284
-:103580007D57BA42ACD980FCB4C49037B7CA69E65B
-:10359000FE0DDB471DE5F1BB29C9D5AFD9FFCD36FF
-:1035A0009D3D3A8BB865A0F7D9CBCD21BA263AFE1E
-:1035B0005458DB3693E7FB37C039568AFCBE82F39A
-:1035C0006B22E1FEBC2BB5E61C7A872CB7104F04AA
-:1035D000793C103E84FC95F2C167B61C8CCB524BF3
-:1035E000CD1A695E0D4ED1D6AB8F12FFD5E0A4C1C6
-:1035F0005B6B3FB47AB4C2EC6A9F018EB3EF1B835E
-:10360000F1CA7A1EAF278956CE9FAC5F1D5D672B2E
-:103610008C935417D03BD423C9176DDD3AFAAFBB56
-:10362000F323C197C361A599E9F130F81E5E333CDD
-:103630001EF45038FE2E14CECD1682EF530436DA27
-:10364000591CC93103E76FE0EB13C74CDC4F035F34
-:10365000EF859D717E13ED5FBAD1BE1EFCE093A590
-:10366000DE476A403EAD37633EDBBD3B57BDFD23C1
-:1036700078EF639D19EF4CE6C63D5C08F7B1A7B83B
-:103680009EA30AA007BE9FE021DA9F2AC0FCF58412
-:10369000CD7F52BBFFD89880F03C5ABEA17D2C2D27
-:1036A000FB762CA886B8CB919D57ED05BF796E2C83
-:1036B00091D231BEAFC8C87F5EF38746FB400AD5C2
-:1036C000C581F57AA8EBE247737DE60FF5743E6F8E
-:1036D00093B1AE8797490F2F57B9115EAE0A03BC5D
-:1036E00084E7ED7E5107AFF298E10ED0EBEF3A5D43
-:1036F000088F8698A5A9009F861D2BB09CB729C668
-:10370000FBA16EDD059D89867AF3B674AF5EAF9C32
-:10371000DEF7443CD0E142A7E8FD90EAB9E38BD55F
-:1037200056B0634E2CAEC252C3FF82CE6CAFCD30CA
-:103730008FB17EBA43A862F2D99530ED1CFCBAD0A5
-:1037400029E33A1F6D62FEE6478BAD5E58E7F862EB
-:10375000C5CBD6757A991DC5E035FFAE38EF87A386
-:1037600043FB8B36EF3F7B7FD4C22787AC04DFD986
-:10377000F9E21C7A3BAA5C923E93517F749BFF0C4A
-:103780007463A5FFFB02E3A812D6B5799B3B452FD6
-:10379000E41313B2C5B01E1DE73AACE3B7E87AC133
-:1037A000F89D8971100B43F9CCEE413C700F42E754
-:1037B0003B29D996431C41BB0769868568DF05D63E
-:1037C0003ED9439B3EE91A76CEF7CC299EB2412FD3
-:1037D00037583B6450B60D9D1797033F7DD2D59A5D
-:1037E0000AF2639E78FA5B91DEF7BA3E9DDFCFFB6B
-:1037F000CC01A3BFE8D3F6992D19F88CD8FACF4D98
-:10380000EBC7A3BCDF53CBE76DDAB2BF722CDD7F11
-:10381000D3B65332EC232DDD539B9E123ABFC0EF3B
-:10382000811A371D94E17C47CDDE8BBE772EFB7E5F
-:10383000C03E6D4E43DEA197F4027FCE2A221AC30A
-:103840005EFF1E9537C75E3113B83F2467692FFAB4
-:103850003C8B3F9D436AE2015EB3BAE6A1FC39F6B8
-:10386000ECE4BD2CFFA8A310E8E31362C2F7DC3F31
-:10387000216FC68FD6C16F75BA963FC9BE6FA3E5DB
-:10388000B7D00DA6637E7A437B2FBC376621929713
-:10389000CB25817DAFC627A03C6B60ED5E625D826B
-:1038A000E758CEE49197FE07F5DB3A8CF2A97E8DBE
-:1038B000B15E47A6A6427E77DD4366C8202273F537
-:1038C000F28FC2EF8E7466D7D7939676B0E71E97C5
-:1038D000595EF72C854883A91E5AF0EBC70B6B691C
-:1038E000FDC17476BFF311F733E0BDC774FABCF1C4
-:1038F0002E9FACE60D3CDFA1AED1D3C7129C8FE961
-:10390000AD46CD6E252E88E30F867F0D8D7EFEC1E0
-:103910005D22DE3B0D86769D7C9EBDDC78BEF39DF0
-:103920003FFCBC84FC00CFDBB8E91AF4DBB4F368DD
-:10393000F8D2CE63DE14F93DDF27D30583DDB49DD5
-:10394000C34FF3BB9F0FABBF10567F299DD9F72103
-:103950003F9DD1B799F337A5FBE781EE1758039543
-:103960008C4EFA64FD7DA81CEAF7C2B9FA5938BF3B
-:10397000D07E2FA58F89DE2F2634DFEB91E65BF01A
-:10398000EBA79E057FB4F1970FC7C365D031A9237C
-:1039900015DEB398BF71693CC0E9A8E48D07BA3958
-:1039A000E613AB22C14B1AC4E506516D02C57B93E9
-:1039B00046FFC54BA6807EFFF346B3027E61F32629
-:1039C0008B1FBEBFD4D43517EF6B68FD20AB2FC360
-:1039D000F72A9BB7993FD0E3B5F1670FA7627E073F
-:1039E000F10E66F7E9FEC1F0E9A0A60D7FAA043F3B
-:1039F000B99904909EC3C7C1FAC12494D7B572C2C5
-:103A0000C0E75ADCB4993591E6AE55A7206EDADCF2
-:103A100035F108F07D33913ED0D35303D034F557C0
-:103A20003E4FE779779791CB40BE68F020BE149463
-:103A3000CFAD9B7F38F220DDCFF10DAFC40B7A7F85
-:103A400095DFB79FEE9CFD7EF239F4C3094AA7FAD1
-:103A5000F73134B9EBDA46379046ABDDAC9C6FF604
-:103A6000C78FA5709DBFCE8CEF87CE7FEA899F3E22
-:103A7000067944EF5AF0FE63DE537BDEBE82D6E762
-:103A80003D6D7654B363D8E03E58C34B33FD1FDC25
-:103A90004F6878687C668F0CEFCF403BF8071A3E82
-:103AA000E63DDD23931103E157D6D923F7D922E070
-:103AB000A5F36025BE67B4F92F32E0FDD84E81A48E
-:103AC000650F1CDFB06E0FDA310027C423C7533FE8
-:103AD000DE06E0CB3F657B01F653406E9F0F5F072C
-:103AE00040AFA6205DFF623BDD47C3EF2D6E8043F4
-:103AF000C32FEE8887F31C915A187D3FBE3415F210
-:103B0000DC1ACCDE54054BD6DEF0E33B91EEEAF74F
-:103B1000DF99CAF20ED5749EDF910EE7BC6DED758C
-:103B200078CE3AE241FA6B785CAC813C98CF255272
-:103B3000F57404FEB89BF3C791F514B9F49C4740A3
-:103B40005E3A42FE8EF65EF39DFD7110760FF939F6
-:103B5000BF879C3A48CB5B67F2B79F6E372C43B95F
-:103B6000FA51A69A06F793140E9A1C45F92AEEAF5D
-:103B700048637862F218C751FA2B8376E8DF6BC688
-:103B80007B61DD382E3FD9FA8BF8FA74DFB1608F94
-:103B90001C498DFC3ED0A67EFEA7FA5647673A3EEA
-:103BA000677CBF6105E3738DEF7DD754C1F3CF7E92
-:103BB000C7F808C6813EA2FBF2A7E1F39E6902CADC
-:103BC000050BF147E2EF0D66CEDFC6E7D462477B17
-:103BD0004EA313BA7F09BE4716A217BA4E12E201CE
-:103BE000ED95BA87E8789D9DDD0CEB623F39D49E58
-:103BF0001DE2E37A2E0FBE3DC8280FC8DA940B8A67
-:103C00000BCC37FB7EFA18F02FE557AF0BF8D78CAB
-:103C1000EFDD7CBC65F7DB37523AFFB853E35BA3BB
-:103C20003C0DE7DB86AD77627C309C6F3FCE682130
-:103C300011F93683BF3717CEB7197DFF5679AAC160
-:103C4000EF2761F0A3F2F127DB5DD1E1182E1FC74A
-:103C50000E72213CC3E523FDFB1D291C48871AFD7C
-:103C60006974D7F8F30543400EF5D3A7467FFDF4FA
-:103C7000A9D15FF8798DF01B20DF20D949673F98E3
-:103C8000EF255E3BC577608788DF4B3AE90AC4437E
-:103C9000FC67690CB915ECF0930AAF27B27A20459E
-:103CA0006E0739A1B5076258BCF2644D203E5167DA
-:103CB0005F1FEC16E321BEDBE78BFC7D37CC48A40D
-:103CC000EBF745F9FE9B168F38191B3F12D78BCDAA
-:103CD000F201BE2A445BD65D9037DA21E2777CE6BA
-:103CE0002CB93E1EF2434E760FBB7A066DBFED2512
-:103CF000FE193FAF2AA55338CFE6783F4ABC8F1450
-:103D0000D3F3CDEE66F6F39CD591E944BB37AFB360
-:103D10002D92411E51BB35441F049EB3EF2C34AC91
-:103D20000D6BEF9E8CF4D418464F1EEE1F1D1BC466
-:103D3000F3FB479151DC3F31E9F3412AC4BCABE1CD
-:103D4000BB9C27F789986F7DBA5B24ED70CE2D82DE
-:103D50008F007F7B53902E9BA8FCD0C77F8F03DD05
-:103D60009DE33DBAE3BFFA43E1F76897F9CFBE3769
-:103D7000F247B43CFEECBB173D07F55F1FC87A8FD6
-:103D80000CEC5FB6F3CC2D20FF4FEEB4108CABECF7
-:103D90007C31EB7B50DF6EC1BCA393F75A54B4A7C0
-:103DA00077DA318FEE64268BA7B6EEF8CB48CCDB02
-:103DB000266D8837C760E6779CEEFEDB1FF1FDDAE3
-:103DC0006E7A2AD0B73BE3D01E6FDE1EE30327F5E1
-:103DD000E48EBF14EAEF2FBEEE799A6416BF3F69F6
-:103DE000273320EE753291C5AD9B9FBBFC892574AE
-:103DF000FD055D3D32BCB753F6FCDF4782BC39B9E7
-:103E000095D91127CC7D3F266E42860CBEE73E3306
-:103E1000C5D709B0ED28AF3C3778E755DEBC487010
-:103E200061703849E100E7A270690039190D1E85FB
-:103E3000FFB1F038750BAC3FBFFB32BC7F08C1450A
-:103E40005059BBDD6715F0FCAC7DE75F46823CFE58
-:103E5000B87309EAF7F39DFBBAFFE7CE2DF82FE41C
-:103E6000DC8BFE63CFCDE8FFAFA09FC60CE483815F
-:103E700074FEEB6F61FD177637EEF702F9FF21381C
-:103E80007FCA7FE2F9BF22DEB70A98BF723EBC3F0D
-:103E9000F31F7BEEF3E1FD258E77BB0279122777C6
-:103EA000FC3D8BE8CE7FBE73BFF97F94DE353BA827
-:103EB000D7D4A214D0FDBD4B3AAECBA6E51BEAA7E2
-:103EC0000E705B2D51EE694C19CCAFB0082CEF9BF6
-:103ED0005C2768F1A55E43DE534603DA1B53D4FB2F
-:103EE000D8F799A4965EC83BED2D9DED5E893DF215
-:103EF000F17B02BDD3C6F1BAD1DF7A5D20AA40EDD5
-:103F0000DB29A593F781BD77B52AA23D484BB403C1
-:103F1000DFCAAA64ED45463FE38630FFE0FA19C6E2
-:103F2000E7D7F1F9A693854A0185D7F40C49F151F9
-:103F300010DD50D26286F3DC70B3403A74F1CDEB01
-:103F4000C2E6FB2304D07476E497855F413FFC16FC
-:103F5000223C4889766F771EF81106EFDE69A35878
-:103F60007EB1E466F09BBEC08D7153EE879AF978FE
-:103F7000B36D792FF0AD9918FD4FCD8F8C0667C2C8
-:103F8000FD529C676808EE665544BF54371FC24314
-:103F9000C3C797C58386BFAF8B0F398318EE75B53E
-:103FA00072AEB5761EDC435821DF9DCE7BF56AF6F6
-:103FB000FE88354F4038D61499F1FDAD3F996A0A15
-:103FC000C170AE1E7D59D377D9B46E80CF5C0EC759
-:103FD0003AD282762739FBC517C58578FB8776EB01
-:103FE0005C9590ABA85F52572CF863E9F9EB25E29A
-:103FF0004DC88738A8403ED0C7417DC63AFC5D9980
-:104000001A9AE77CFDA3C9877F76F93E95471F5032
-:10401000A41F8412F366D8EF5D68FEE3ADDD0C8E5D
-:10402000CDF305DF50A423BF597FFFBB3983C5679C
-:10403000DFBF7B34CAB992FB472430BFB600F379A7
-:104040009AB9BD7FDAEB4A8078CEE9EE610910AF0C
-:1040500039BDAF2C3E521ECF7EEE57FE76B115CB4A
-:1040600093E542879880EF9D4C413D5C1E4340EEB6
-:10407000848F5B91A1C5655AD8BD246179F875FC20
-:104080001CF5746842920E6FABAF3A268D1C880700
-:10409000F8FB4077AFF275E10B7E2CC0757F4C5F6B
-:1040A00065A4EF13FE88CB85EA5D6764881F4CED3D
-:1040B000CEC6EF4B4E2D37BE07F86006F7CF4793BD
-:1040C000D1B0AFEA5D13E32F07BCEC13DD3114BEB2
-:1040D000CDDDA7644F84FBB97078C2FC10473E6405
-:1040E00076D7013C0FDD1783EFFFBFC6EF8BF2F8E9
-:1040F0007721E1D341103FDBC0E17A2683C5D1AF00
-:10410000AD2E31A7D075F3BA945190573688F73F4A
-:1041100093E1C2E783F938ADDFA0F9ACDF4159691B
-:104120008A74FE21598C7EEA89FB5B45C27F1EDEC4
-:104130004AEEB7FBE1BDB8D3E5027F6F269CAE091E
-:10414000F2C7E92AC107FA17FC58AC570BA8FF5F62
-:10415000D3F2EEA6327DA9D17D389CF767980C7911
-:104160000EA738DCDFE6F4A1C159836FF87EB5FEF7
-:10417000545E8DD7C75BAEDE36EA17609F34750B91
-:104180008A894ED524F5C9C087CDDB1E30C3FDC258
-:104190000DFCF759885433527FBF7B2683FDCECB6D
-:1041A000EEFCB1683F7EBA9AD9C7EA9C53F160072A
-:1041B000BD6672BF3116F8F175D1F05DF3F0F2BD56
-:1041C000C54A63B9593F6F36EEF3DAF92566080F31
-:1041D000DD34BFC79CA6A3A73319EC7B415AFBA0D3
-:1041E000F92ECC5FA4EBE13EBCDFB710C8C7C8EB2B
-:1041F000EC2D8DA3CF6F6A496474D8D0D923639D09
-:104200007D67585B4F5B279C9FA655C719EAB3CBC8
-:10421000FA32002ED516FF2277043A7D2853BB8749
-:10422000FA927A42A5743BF2FF073D71AA32D27727
-:1042300050676732FAD5E987B448FA61E112571A34
-:10424000C07FE18E6169C01C0B5FAA488DA41FDE90
-:104250005ACCEE0F0FF0BCCB93D3A87EB854A71F57
-:10426000A6C5207D848FBB2AF302F58386AF7FB37A
-:104270009C790BF44304BEF6641AF5C3F4EE5AD4E9
-:104280000FD3A789C4A58BC75D9F793EFD50927A55
-:1042900003D6CDEEB80874F316F74B00AE50C23A11
-:1042A000A027EECF64723F5C5F4493E7395902BFA9
-:1042B000DF3E8F3CFF5F82B326CF175EC7DEE31F72
-:1042C000488704E5F5C21B04FCFD92853B983C5FE2
-:1042D00078338F4B86C9D71A90AF057AF9CAC6379B
-:1042E00079983E68DE96FDC399F4F98D1D66B79501
-:1042F000F6BF31246F0BF5F2F6FE4C49837396122C
-:1043000001BF3366C61197515EE5809C3A34EAC519
-:10431000BC6780EE5F63EF99FD89EBF15747BD58AD
-:1043200000F1F4C37CDE67B9FC3AB1983496533897
-:1043300094CD61F6F0822D22C2A1A98BD9794D9B33
-:10434000047C9FB732FF0CDE1BCEDBC1EE0DE17BA0
-:10435000BE253A3CCE7BADAF7D303C5F27E0BD67EC
-:104360009D7B1E7BEF6F0D8B135BE97F902FB1223E
-:10437000367E3DC13C1D15E3CD0B38DCAA2D81BD39
-:1043800030BEFA67827B1DCA35637C7A41CEA46356
-:10439000E01FCCDB14D6EE5E81F7190B20EEACF3F8
-:1043A00047DEE2E7BB4DF4E73D0379816F88117F7B
-:1043B000EFECAD7038347C4D38ECA77028F8EA701B
-:1043C00068EE7E00F36FBEEEF90F64F2787B3E2953
-:1043D000007EF9934945FEF7BE2CE27BC5731E189B
-:1043E0009EA6CF53FA1387C36B264F7B3AF46B62BA
-:1043F000EF1FD7AF7D7A0FBC1A3EB3938C82B07D8E
-:10440000FD1AA39EECD7CB5D2ED4BB335B9E16E08A
-:104410007BFEB789047F076C76BEC503F7AFFB63ED
-:104420000228CF343A4CC892D877DCB8BD776850B0
-:10443000A01CFD8A6D82827C02DFD3803AC5037C9A
-:104440004F63F7E57FA9E470C7F84CF33686A7669B
-:104450008A17E0B34A6AEF821EB989EA1DBC2FEBC6
-:10446000EE3143FF06DA2F19E58E1BFD5D4D3FC18E
-:10447000FD5D49AA0E6F3B0E32FADD28B84904BC37
-:10448000E5D2FFCE85B768F8D2EC870BC59B068FC7
-:10449000842C23FEF6C7F4568FC67B2AF63B40A435
-:1044A0003B11EF553EEC188678CCE472369CBEC1C9
-:1044B000DE77E9E24BD7C0C6F1C3F531982787EB29
-:1044C0000E65F6905EBE84FBD1CDA417ED9AB47450
-:1044D000CF5319BABCB0E93C7FA5FF5E37D4AF3EDD
-:1044E000734CF47EC4598AF73F5A7E2DFC7214E651
-:1044F00083F1FAEECCC20333E9793F5D2EE2FBC9CA
-:10450000D79B5C6F17031FAF3413A0CB4F5F35AB46
-:10451000CC0E8D43395CFBDA213384466A21BF809F
-:10452000F6ABBD87C9DB4330196DFB3DD5632A7CF3
-:10453000B784748E81BCFD69EE9E0AC8DBBEAE6096
-:10454000FF52B8A7BBB64C79FB6D80EF0A91007C97
-:104550003F585E86FECA1DB70B48D7EF2CC6DFC298
-:1045600022D74DCB7EFB6DBAEECDCB53F09E6DA620
-:10457000BAA702E86DF6D5761BDCD34DCE15894778
-:1045800007C79B49EF5290DF335B6EBF0EF6DB40EF
-:10459000F502C45D1BBAF757A4417DAD80BFA3D619
-:1045A000ECF5C8F00A54EF9A5332C43FEA683F4032
-:1045B0004FF35AD6AF798380EFF7D451F900E7ABC8
-:1045C000DB20107891A497DA7F5636AF0F3ECCD41B
-:1045D000BB968EA7F57A180FF36E48C4DFBB6B7ECF
-:1045E00095BD1F5457B4642FC8A73A3A8E3E26BDD6
-:1045F0001B6EC7F9E6AE1508A4063714657FBF0821
-:10460000E67BD58CDF0539D0F3A80CFBBE85AE97D1
-:104610004EE79F2DF655609EF5F70405F3A0ABBF5E
-:104620008B783BC9F980647C87F199C0EBDC2ED490
-:10463000F4E3C6ACA12CCFFAAE25ED70AE3E6F4AC6
-:1046400036B844CDDB4EC960E77DB8183E3C43F137
-:10465000C6F3E0767B0FC97D3A39B52B6B188E9F78
-:10466000B3AD04F9FC365283F7E29E254C2F1F5C54
-:104670001AE313C01E312BA837772FFDC62370FE17
-:10468000134F99F1BEF444661FC6678FAC35E377CC
-:10469000435AD78A28478E6C617121F1F1EB2AD3F6
-:1046A000017E540E00DDED5E5B26833C3CE2137020
-:1046B0007CD9E377A6B2B8AF517ED4B91A515E3C2B
-:1046C0001EC3E443FD9AC8F7AB51E5C5A24A26DFF5
-:1046D000C3E4C1828C768CFB85CB89666263F65D10
-:1046E0003EC9877AAF3F1DE9B7E9553301FBAE49B3
-:1046F000526E5903743333066E92295FF8F7807C4B
-:10470000FBD427B8BCF4F94DB7FE660CC0EF30C03F
-:104710001BF8627532DEAFD6F96A11AE5A3E62FD01
-:104720001A233D6B794F3778C4D07B3EF47F373501
-:10473000C41155D7EFC03D942EE97AB76E137CF0C3
-:10474000FDA303F71CDC7B6701D615A0C3A6BBB88D
-:104750005E5D6D47BA3DF09D534B812E6FB95BC0D6
-:10476000FD13AFA71DF44AD31AC10571CDFABBD909
-:10477000F87A3A1EE8E5C0A38C7E281DBB80CE9B4C
-:10478000D63EB017FB6F105C30FF8175B5A8871B54
-:10479000BC22C1E71B0EA2BD4CF501E60DEDF68A69
-:1047A000A940E74D6D1605F0AAD18B467F07F9F7B2
-:1047B000A789D53DF25AF87D8A2C5744BA1367640D
-:1047C000237D356F3123BD347B193D1D7C4A443A2E
-:1047D000DCBDF4FA4AA09F131B8528F447E9AB20FF
-:1047E000445FE2E3661C5FBF99C51776AF65747DD1
-:1047F000A48BD9A7658F0F47BFA6FE353361F1079C
-:1048000062D3DB1FE7A3C370BA1BA097381D46A372
-:104810003B8FB9733AE41FD4FE82EEDF15825759FD
-:10482000FB77300E50D67E039E57E31F78AF05F21C
-:1048300036E6742C61F98C12CBEFF9D2FB0ADBC798
-:104840008321FD980FFA11F24FFC741F2F6E79022D
-:10485000ED804F9E3C88F98DF39EA3F8A7FD4F6C29
-:10486000B1133FDAD93E94338D5D22E69712C95FCA
-:1048700078ADEEFD2D2D2F63DE2FED08F7C6AD16BA
-:104880005F351DDFF8ECA191784F7E2FB353BD4FFC
-:10489000B2EFCC106FDFC86B213F5362F921E1FA10
-:1048A000D73684C5718EFF260EBFC7246CEAC17B44
-:1048B000A6C6CEEBCD165DDC521C6266BF03F19B33
-:1048C00038F69E19C53FDC2FC2FEF4BF27A1E5854F
-:1048D0001CDFCCF8A7719B19EDA3C64DEB30DED7DA
-:1048E000BCE914E6CF96FDF2A9788043F336D1985F
-:1048F0003FB549F45B30CF4B3C6861DFE530E431D4
-:104900003575B1F73B9A3A799E5058FECCBC5FEEB4
-:1049100078D64B4133EF999FC5033F7DD4BB311E01
-:10492000E049E7C3FCA3AB8BA2E4279D2F2FA9731B
-:1049300005CF4BBA0A7FA7233C2FE923F807D5E31D
-:10494000F94338DEB5BCAE4D4C6E51EC17467A0FCC
-:1049500049B35FE63DF5F98F218FF6F8D68F7F0CCE
-:10496000FB9FFF8F4F7F0C791D64678C02F644F329
-:10497000936F61FEA136AE7A08B3A74E6CFE19E6BE
-:104980006F9E78D78276E1891D47B2C05E38F1F418
-:104990009954C8CB5CB4A302E3138B7E5586EF8792
-:1049A00046F337813E7D17903F1A8E8FDD5DA2DF83
-:1049B00046F7F9C93B16E4FFFE3CB3CE052C7FCF8A
-:1049C000C5F3CBB644CED3D5F2A19ABAAEBD7A1C0C
-:1049D000C8BB2EA6D7FBF3A3CE9757F63B8AD74B7F
-:1049E0002F007F5B78FE60E75511F3CA3E817F5050
-:1049F0003C350E31E6957DDE75DB4F1E83675D919C
-:104A0000DFD3D6F8FA7C70D3F2802F1BA2DE3904F4
-:104A1000F868EBCF318F0FF056ED02FDFF7916C429
-:104A2000378F9A0318370CECB02890EFD5B8E30015
-:104A3000F2CB895FEDC73C5BC2F3714F90FE3F96AE
-:104A400037C96317CD1BEC2C1F8DC31FF2D55CF14A
-:104A5000D8CEF3D2181D6BF96AD1F2D47E3E84D938
-:104A6000415A7EF20257AFACD842F802FC084580AA
-:104A7000AF8386FC3FEDDCE1F3290087CBF4F997A7
-:104A8000D1F201B99D3E005F4C2E9F58C7F331FB18
-:104A9000F32CA949970FF9414C1F36FB840391F081
-:104AA000ABE55FFE340CBFDAF9A2F185C69FE7DF04
-:104AB000F75783CB9A212CFF5F83CFF1B391E57435
-:104AC0000FE777EAB7F887E8FC965BB9DFA2E59DC8
-:104AD00069FB6DEF647AF9F826663786F3775394AD
-:104AE000DFD37A6308F3EF9AB6F58C0439747CD778
-:104AF0006F38DD31BA6EDA7250F672B9EDD3CBEDA4
-:104B000028BF5FF62EDF37F57723CED7BCE554C438
-:104B1000F93E92D4EB61FF1FF5323BE4A34E31E244
-:104B2000EF20ECE67AA9FFDC7619FD2E313E16E582
-:104B3000D1227BD13BF05DB7457619F31D5A97F032
-:104B4000FC887BDCF83B1EADF649F8FB0F4B013EC1
-:104B50003A3FD4AC78F07727CCCE9A02F0AFC2DFE0
-:104B6000EB941D26E2D3E35FF2E2FBBD5386FE45E4
-:104B700002BDD3BBD8F8DE48AFA4EC49A6F3F59646
-:104B80000B6EB07707D29971FE6B54D1103F8358EA
-:104B9000359CEBB49B7D0FCD6EF22BB40BB1C7F4FB
-:104BA0003AD1D173B1DFABFE1F05EC5EF50080009A
-:104BB000000000001F8B080000000000000BB57D06
-:104BC0000B7C54C5B9F89C3D67379B6437D990047A
-:104BD000121EE1ECE64D4258C2534539092426F233
-:104BE00070414554D4253CC23389F8B8D4D2B24080
-:104BF0008C88B40D824A7BD12E34A87F4B5B40BC9D
-:104C0000050DFE170816ADB551D16AFFDA06880802
-:104C10001A6005CBCDF542B9F37D33933DE764438C
-:104C2000D0DB7FFCB5C39C7366E69BEF3DDF7C3336
-:104C30009B48E89F8790752BED598A959004E295E3
-:104C4000884C88D3AB04DAF208FE5DA1FF4B24B494
-:104C50006EE775371647B34613E2608FE87BD701DE
-:104C60008B44485C1EC9534612E222715E99D637C6
-:104C700026686F4A0984AC77FA27D3CEC915F81B8A
-:104C8000DFBD245EA51DC6B3D3FFAE507812C7D2D8
-:104C9000BA3D327E9266AC27135D1DE1D108E90B67
-:104CA000CFE99F4A48B94C21A3702495598231120B
-:104CB000BE9F9CDD37026F522AF186E0FD148737D4
-:104CC00040BF7738187C025E0ACF718047A5FF216C
-:104CD0003C856D010B41B88EEBE1A07F92CF89F04E
-:104CE0001D37C1775C0FDF30D59972B2805614A2A0
-:104CF0005CA1F875D85B09C7F3793D9E0909106579
-:104D000034E053E095BEA7FDB8A54DCA1509F0EAF9
-:104D10009248268E676A37D075329ED769BF7BE18D
-:104D20001FD711D27F89DA62A3F3F4D92517A0A186
-:104D30001F85B51590A0B4DA0019CF3A443D64231D
-:104D400085F4BB3DEFD9DA68B974E77BF8DE02750C
-:104D50005A26C7AB13070C27E4FEE0305F5A3E7CAF
-:104D6000373BCDE2C57AAB924A48C3347F9A653867
-:104D7000803FACB16520212F92BA21127D6FAF2FF9
-:104D8000683D7223F015FDEB0FEF0B5AB54278CF5B
-:104D9000EB8484089DC78B715D75CD9E46EB9EAEFE
-:104DA0007A00EA4D80FCEB61BC82D67ADAFEB0EA8A
-:104DB000BB5B1D45C8B4E72C444A21647CA723286B
-:104DC000011FB4F521241D9AD5C5015DBAF119C59D
-:104DD0002F498D7CD7233FF2EF289C153BE9FCA798
-:104DE000F967FB268E20648CC4F04A5C6D23A63BD9
-:104DF000018EAA256A6AA4DDB4E7CECB1E0ADF12B3
-:104E0000CA53D03EB1C2754B1E852F710BC5960A91
-:104E1000DFFB1F00B8B357F82DC01EE349DB831238
-:104E2000A527F93405E111E334EC97917F1B1EB3FC
-:104E3000045723FFAA926FA89E7E6D26FA8519FD5E
-:104E4000F61E43FAD5341F63F4DBBBF500D0BFA6D2
-:104E50005972C5A8301FEF2ECA44E4F1E0049F3216
-:104E600088D23526DC0074B59212DFE47CC4EB6393
-:104E7000309F6E78E5F0F586D7174F6D7BB2887E50
-:104E80001AE8B078B349045FE2BB1DAA0DBF2BF24C
-:104E9000F89F023CD46E6A6B88A570BD76EAFD046B
-:104EA0003F8537BBE37CA888C29B3D0EC5B86BDC51
-:104EB000173BB61DB0D17FBE087C4C5FE410FF6A83
-:104EC00097E36AF860FCDD858F3DC7103F16A8D3D5
-:104ED000E7BB6D6401D0B574AFA40581BF63C8FDA5
-:104EE0003E5A6E5729A351B8F6A9322F2546C70E50
-:104EF0008FA2D2F6A5B75BB4202D137919997F3D07
-:104F0000FF5E61FCC5F121E829F88890C6F8699434
-:104F10008E79B9FEDD46BE792ADE43DF8F6F3FFE14
-:104F200020B144DA6D5F497C73AD91EF28FFFCCC72
-:104F3000D0AEECE1387F61E47BE04BE013337D6879
-:104F4000BB109397A7E2611EFBDACFCB80EF6BA576
-:104F5000ABF979EB4ABF6FA2B567F9F195C83EC0CE
-:104F6000ABF9F9518E5FAA1902ED79A0B5259248E7
-:104F700051DD2FDD7F14E05B6A6F4BB89DD2B7A681
-:104F8000E4820DF0B03AFEEC0DFE28FDF40447EB90
-:104F9000A55C878FCEEF60670CE2BB5B3BA0271D53
-:104FA000E7DD95337D1329833E119750C4952DDAA3
-:104FB000B3895CEF4ECC5A349929AD2EBB275D895D
-:104FC000216810146A47CAE00985AF62EC2E05EC2F
-:104FD0006719D1D94B37F6BB8D0C037A580D766D16
-:104FE00052D62DA7C1BEB42A6D6B1229EA5BD32419
-:104FF000B43F375F6A6C01DB75739AD560E72A5559
-:10500000637D126176528C334DA374E7EF2FE0FF7E
-:1050100007717E53558A5ADAFFD4ACB860804EF9D6
-:10502000D6B177F926EAECC57B97E5FB7D85DDF106
-:1050300033D92DF0E343BCFE3E96E26718CC73767D
-:105040003D43D3D5F161C6A3192F133F9D3F99145A
-:1050500075C7CBB5CEBF0BAF84FC04E6374993C907
-:105060003A7704AF66FCD0BF29F0DD7B25F43B091D
-:10507000FC820EC542EB95D74944F805657D7574F1
-:10508000E7F099F16AC69FF03726F176EF00BE2867
-:105090003F4D92B738801F2A7FD43A3199EAB1CA7E
-:1050A000418CBE2444914BF17213419C015EB721A7
-:1050B000DFB9ACE86750BBCEF8E3D3F2D3121D7F63
-:1050C00072277D47E12C57A5201511C0CB71135EC7
-:1050D0008E9BF8E2B87EDE66787F0FFFB82E0ABF9F
-:1050E000288D7920F713DCD43F01FF2183A857A82E
-:1050F0003D1AFDC9C844A61FA2DBC9F19DBEAE7E04
-:10510000183E1A916F24E2EF7AEEA2FD84346B0A06
-:105110004503996077A19C4C20DA9A763BA04246E1
-:1051200038055C97D37CB7BB69FB1252B9A65D8F7B
-:10513000E74F853D67F89EC0F13781040EC80950DE
-:105140002ADFE8E72DFABB57CC6730190CFED08771
-:10515000AACAF432EF4FCC2F399984240A6058B28E
-:1051600007B749003F09D8FA44C6B372FA9ECE9AEF
-:105170005EED46BD5E47005FE0B6003D4BF9FB5279
-:10518000BB2304F010BBB5A38B2EE0C390592EF0C7
-:10519000FB285EC895F8087C0FBB25E5645E04BE5D
-:1051A0003347EC0199F2F5C474FF0F000F1DD23B99
-:1051B00045802FEA97E5803E37BFBFF0714B0DBCAD
-:1051C000A7DFCDC7EFF8BC1683D34DF926BC3F2629
-:1051D000B8CD1D4D9FAF62FAD74E3D519D9C96C6EE
-:1051E00031399F447C0AF8970763999CB5C42E44D3
-:1051F00079282775F543697F7F8CBBF908C8592545
-:1052000009E077652E231FF6C6A7B790F07DE0F77B
-:105210004ECAB39AFCE800D2E7606C6E16D8B3832E
-:10522000B14C2F0BFFE165B7EF5937BECF08825E57
-:105230003EAE8D7A17EC4455C9888F46D2D262F7BC
-:10524000D9809EF380BF285EC7027FD1B607A1EB4D
-:1052500074E4AF20B49FB3D6C45FF664ECDF47D5E7
-:1052600018C055AA59BFD5FBD55D78E376B2377F14
-:1052700091B428248FE2752EE7D383B13101F0E396
-:105280004A9FA0724CF13787F89F6F94000EABC114
-:105290007F9F1B6B457F6FEECF6351DE69E32D75FA
-:1052A00074C8F9F4F93ADA0FC95307EAED3A69D448
-:1052B000B507FADB55E4C7B92EF6AC9DF691DE07CB
-:1052C000FAA5DA8DE2936CB69ED7F3A579FC1EFBA6
-:1052D00035B53B28919960570F5AD5815E9DFD7871
-:1052E000D36DC1F99FB7676FB1787AC6D37C7BB2B3
-:1052F000A68C88D44FC6C6CE8CE62788FE045EBB3B
-:10530000D617E49BC6967191F5C563ABBF6E3D326F
-:1053100048BFBEF8BA55737CFFF5C5A9AD5FE3FA87
-:10532000E2690BF50F016F8A2F7F9ACE2FFADACD43
-:10533000FC976096F635C8E1D3DC8FA41C943F6DD2
-:1053400068F7EFFA2E9F404E50168BB193406C31A8
-:10535000D5030A09588BE17BFF2A0BA5B73293A02E
-:105360005DA27A08FD4F331E4E6795FE03F856C8BE
-:1053700067691CE57F2A8F4F58D4A646F0B3DF96A5
-:10538000A9CF4A475F3E07FDBFDB962FC4F2DCF191
-:105390004B39A0174A39BE150FB3EBB5F14CAE6AC5
-:1053A000E3991CFD31CDAF78E8F3564D768EA4FD20
-:1053B0002DDE2B7B63102DE10CE0B7DBA6C8A9F036
-:1053C000FC84DD8AEBC7834E46FF1344AA00FC949D
-:1053D000BE17E3DB43CB47D34A723D3A3FF1D1B42A
-:1053E00089582715D4E1A37CB9CCCEE4E10471330C
-:1053F000B8D74ADEEDF4D1F9B5EE44E0CF8356627A
-:10540000F047D23D0AC29BEE6178ACEAA4C2398271
-:10541000F15D1D1DBF4A516DE0FF5775DAF039C0CF
-:10542000817C196BECC7E361FEB8C7C3F8A9AA5326
-:10543000C220C1C158733F0A7BCEF9DB4C87A7DC81
-:105440001372603E8FA669B91EF45F5505F0533A9A
-:10545000B2E563D087BDEBFF8004FABFF692141A61
-:105460004CE7DFB1C78AEBBA0EBE2E38B3E750DF88
-:105470002A5A2EDDF54102AC1FC7727A9D515A138C
-:1054800000BE25AF527FBA10D9B9EF3DD87ECEE825
-:10549000756C18BBDE2E5E7F3973A00FBFA3008E24
-:1054A0008EF86513EC8120C07770953C13E846EDCB
-:1054B000A6F0CB24D093657B642DB6A8BBBF36D5B0
-:1054C00063E5FE3AA3E3432E364E4FF25DDA194F01
-:1054D000823AF92E555405E02FED4CC0E7674E6D2A
-:1054E000DB3895F27D20CD8AEB436A855AD05F94F4
-:1054F000085FF0D13A9D4F0B9FCFE13DB7DD7E03B2
-:10550000FDE79B607FE83713DBFC294CD8E9EA6EA6
-:1055100074C4FF2A7319FD44B31F29EC5945F3865F
-:10552000FA0104F01EBCED06E0C3530A013EECE6AE
-:1055300067DB6FEEC19FDC807CF4DA9E5FE13AAA04
-:10554000C8A362BD76CF8572E0E31A129A01FDD638
-:10555000EC915D21FAF561B2A700EC8AB0FB022F55
-:10556000A14B87EC5EB00BB1B26B35CCD37E8743D9
-:10557000A578BAE15C610ADA3FBBB502F462696CF6
-:10558000B6638E8E9F0FA6C815C0078753328DCF86
-:10559000ED1B0BC0FEEDB3307DD472F26E471B7E67
-:1055A000775B0AFA71C2EE9BFC561127ABCC96834F
-:1055B000D1FC61226FD9144BDF4FCAB51219FCF729
-:1055C000B645E80F74B3FB97FCB83E30DB7F8177BC
-:1055D0008A6994976E7E6B04CF06FFF5690F8F97EB
-:1055E000A96428F8A3A14B1B17039CE79AE35DABC2
-:1055F000311EC1FC9D73ED8B364E81E7EFC8185FFD
-:1056000039774946793AF8C6E2C16D3A39A61604A7
-:10561000E97471F8D7675FA7F4B9F8799C3780FC13
-:10562000B7B320DA7A59ACA3E8C8FD2D69087F7FAB
-:10563000CB5814375CB7DE1459B7FEDA83EBD6705B
-:10564000399893B42DC76CC01767A80B0FF00628C4
-:10565000F1B753BCDEA4B5C92E1D3CFF97CB7791A3
-:1056600047DB057A25404A0750A7852C88D34A6E28
-:10567000007F741A716DA3F3D97FAA54B2D2FAB81D
-:10568000ED6EAF44EBBBC12105BE7D550E6EA77814
-:10569000D84DF5F16EDAEFC2D6469B9B8E1BD843F0
-:1056A000811A43EB9490808753D64046928E4F16D2
-:1056B00065B2714F59FDBF847E4E7D1243607D7887
-:1056C000EAF3B8A876B83893E9CDD7B99D7364AA40
-:1056D000D83ED4F1DA9BFD295CA14ED770C0FBA265
-:1056E00097BE9667D3716EE4FEDAE44DADF510D740
-:1056F00099BA25AC80FEF1055D656082A7BFE4B56F
-:10570000825DBA7D87CF0AEEF98C3D7556783F737E
-:105710006FE361A8DF1DDA89755BA6FF23C0EB4D3F
-:105720006BC387805DB21A89027241BE617E589850
-:10573000CB9DA7D37B3011B9BAC4027CDE35FE8A7B
-:1057400056055CA2A9F56C7CDA5F1BF657179E0024
-:10575000F62D6339EB2F831C5895A846FA1D7FA9B7
-:1057600055D2C71B4A7FB804F9E8F947970C4E0693
-:10577000BCFF358664BBB96CA4C0F38141587F126D
-:10578000A52D7FBADE3F23A118C637C4CE4AC14F2C
-:105790009A9DF1912B0EFC85479EA98B03FD90E20B
-:1057A000536D7E1D9D4A374E1EF216F0696C0CC675
-:1057B000ED2E0E677EFDC50D8E6080C5BB8700DFB8
-:1057C0000A7B5505F436C4A384BC33BEA75D04012F
-:1057D0000E511269B58BE8EB24940670757A187D2A
-:1057E0009B6CEA2C18AF292EC605E355D9B36DA0E2
-:1057F0009FBAE29F1044A47AE206EE6FEE3F753046
-:1058000019E87A71F8AA0C5817842CFF8EFAA83779
-:10581000BE5AE2D1923211CE4006ACABC4F7FB4E79
-:10582000C615823D7C5DF861DED98361BEA25D5103
-:1058300026F30BA83CE0FC851CA4B4126D6B21A2DE
-:105840004ADBADC3477E268BE38972B7550D3039ED
-:10585000A27E08C8953364CF0479DD9789F5141FBB
-:105860007178E9FBDABDD95E594539CFCF4C8DC887
-:10587000FF8D5CFE535AC32877D7BA3E706532BE9F
-:105880000D293BB9FC10D443203F4C4F870630FE16
-:10589000080C00BA805EE0F449976859CDE92CE61F
-:1058A0009DC2E57E2A976BC003BCAFE4F314EF6F93
-:1058B000E6F82A930B13DBA2C47DBAF86E793A019D
-:1058C0007FB16CF9002C2B39BC0BED1B309EBA302C
-:1058D0006503C65153B4462C174E6CC4E7695B662A
-:1058E000237F2CDC2C19E2A2A27C81FB5F674E593E
-:1058F000D07E114B5C7FE03FF1FED7E067B0B8F09F
-:105900001D80E7D37B363E53A446E2C2A79B983D59
-:105910005C1067F4EFEEE6F3DAFFCDC164E0978B3D
-:10592000B18D53EF0639D92EBB56011D9BCA2435C4
-:105930000AFFE9F10C78AD6DFA4739CCA386B4358E
-:10594000809E3ECDFD32B559427DAAEEA5653F2A27
-:105950002C4D4CBF9EB232FD7E4A4A96403E40BF1F
-:10596000839E3DF5F9BA8C47818F2427FA37A037FB
-:1059700077E9F863F18EAD0DFDE93F6FBAE41A0ED9
-:105980007C15528843AF9F059F087D6B867B05A7DA
-:10599000ABE0C31B22766805E00DE2A740B29A0D8A
-:1059A000E7317EBA81D3AF09F80DE479ADE0B7E114
-:1059B00016D4A726391EF32FD2DFFB9EFA4506C662
-:1059C00025C652B9A5727D1AE43A0A5FFC9CD36FD2
-:1059D00089C7BF29338ABE3F2DF97F999C1969BFBA
-:1059E000EFE42D43AA74FD3CC8F171D1EA1FEC8AA3
-:1059F00082AF085E497FA0F3024A19C003D922B9D9
-:105A0000C0EF13EF53B6B07D8097B91C89E7A22E83
-:105A1000F03D1EF09D89F87E3993D97D1B98E4B442
-:105A200020B3FBC4724B7FB0E30BE3B45B300EB327
-:105A3000C14220AE44A452E4F794A6A74F5E1E09CB
-:105A400065AC07F755A85F0DFBA50B9F50711DB8FE
-:105A5000FA8558E4B350A607E7B5BAC98AFC76DAE6
-:105A6000DA98817CF9F9A2C1B02F13F884D9A19EEC
-:105A7000F029F8E727DC5E0BBEF3AC677CD7A4689F
-:105A800071C077C28E0AFE3CBDFDE6629037D13E02
-:105A9000C237AEE1826F66D3E79EB56D32D087D252
-:105AA000ED8F8087CCF561D45F3DD14DECB709FA1D
-:105AB00009BD9E906531E0FB330E7F0AF75FBAD3D4
-:105AC0007195811E3746F8FF5333FF5BD5883CFD47
-:105AD000A11739B83ECBC5E20C9FCD4903FD22F694
-:105AE0006BC43EAA18FF2CE7879EF65B0EABFE3315
-:105AF00099BAF9C07EA08A7A9DEDAF94717F7BD967
-:105B0000F698600CA5DF3E7805FAA23D2E087EA22D
-:105B10006897AB104D2926E4BF33DD385E2EA80A06
-:105B20005A4F596E235974DC8BD71D6849A0DF4F3B
-:105B300009B74D1E46A7B6CFD676FBAD10F725DACE
-:105B400022F02730560F7CDEC1FA25AE9D0638AD17
-:105B50005916C33EA898774F76AB277A5C9FC5F756
-:105B6000C7F87BB39C1FE3F83AC4CBDEE53490085A
-:105B7000727A1309AC82FD117289B8C01E77C9E927
-:105B80002582F6657096514E453D8A9C0ECED2CB4D
-:105B900069671B93532E8F894D562D9A7F32348B14
-:105BA000AD7B139BCA4AC09E24FA08C63FE8345115
-:105BB000AE1752B906790D807CF6037C32FEF2688E
-:105BC0008DF7C17B4F13F3AB2F26B1F92EBC513BA0
-:105BD00020839C53BF5EA29F3672B9EE19EFA14499
-:105BE00089D9A744D027378D6B9B00F656857D81D8
-:105BF0007E303F46DFF1E3483044E9AE5E224C4F51
-:105C00007CFE8BFB1E05FDB0C1E1CD5623F627ECD3
-:105C1000F197001E7A9267CA971AC4A396FD9783DC
-:105C2000AD037BD81F1FBF5C46FEA37C7E4B960E48
-:105C3000FFE37D6119F09A1CEF4FB32611724FD329
-:105C4000D0E9F641747E6EEADFD2FA4C5A5F0F71EA
-:105C5000B73E6D84D79F72A47FFF38DD3D5985EF35
-:105C6000D753B80399DA5D59A9B86F7D0FC073D3C4
-:105C700080B00CFEE7B5EEEFD7427C8ECEE7F81D84
-:105C8000435E984D9F56DDE56B80B7228E3C86C7FC
-:105C9000916B9B87637C59174F5E94759578726FF3
-:105CA000E32670B9A7FC8DEBB884B16119F4A2D0DA
-:105CB0002BCBB3FA707E6E23B0AE10F2057A09FCDE
-:105CC0005A916700714527EE5704F17BA8271647C4
-:105CD000F4CDFA464B4534FE7E3CCB11558F92E60F
-:105CE000FFFE8F4747D3F9C22BA6571FCFD2E9D566
-:105CF000A6C6E37D999F4AAD3CF51B1EE46BF98D6A
-:105D0000ABBD7FCE02BE7B57C678CA7531B6800464
-:105D1000EB7E8DA8AEBEBC3F10BB6629E42CA2F57D
-:105D20006F25A2419CF25B19CB8D3FF655B8216ED1
-:105D3000F2B1C5BB9A60BE02E267EC6012B4D37FD9
-:105D4000EEE5F1CF92130E0DF200CE4976D49FE727
-:105D50008EC505C07E9E735A306EDEB23F06E5E208
-:105D600042561C8F67040D710FB19F73E19D39C9B5
-:105D7000A0F79FE1FB9BCFC4B2B8EA3377E5603C64
-:105D800052C46D1585E2BE0F84A9285EFB807F3C5E
-:105D900000E3A9228EDBD73E5B6249456C1CC5CE71
-:105DA000E6D757F14B101FDFDA4B3EC4EB59361ED6
-:105DB00007F0EF01FEAD5DD1668375ABF07B855DCD
-:105DC0001EDCE139007911832B58986C6B87C50272
-:105DD000F3DC4AD929C9DD9DBF041F6DED9E7770A4
-:105DE000204B17A79DF618CB3BE8AAF376BFE479C2
-:105DF00007E3DB8FBF02FE1C95F75D867665A97110
-:105E0000FE287A6BC6F21F62FB9EF87F8685F8A398
-:105E1000D99113427F2B7503C04E91BF3F12AF46FD
-:105E200089CBCCF8AC2A15F0628EA745C6FF318E1F
-:105E3000FF59168F1F65900CD85FEB6D3FD30CF7A1
-:105E40004756FFA068764AD0D93C5EF7F66C1DD65F
-:105E5000F59D8DF8773958BFC5BA7E53B299BF33D7
-:105E60004362FBF5E432417B2DF884E2FD3F812F54
-:105E700046FFE9C48838DCE709CBA00F2E7C9C35AF
-:105E800010F7DB7B58770A7808F16747CBEBA0E384
-:105E9000F9A2D121299BD1618695ED4748776563A9
-:105EA0001C60466C8C14A3F34F2E77D95BCDB02FBA
-:105EB0007B3076CC488C5F5AD581D1F067DEAFBDA0
-:105EC0009C45905F012FDE28FC24F695059E1B4A19
-:105ED000B41285C5C7C83630811AD3A3291504F773
-:105EE000D7C6481AE223339BF94D5B79BEDC857730
-:105EF00064D40BA34BD4206C91527BE1CE1E85F968
-:105F000057AF5874F957824F1A7E43EDB2217EC8BD
-:105F1000E44AAC9F93B83EA65EA3B64BF79DBA0287
-:105F20007440C41E0CACB71BEA190FB988A2B31792
-:105F3000495A9AA13ED0E78A8375D3C00AD5D04E7C
-:105F4000F09DC8FFC3BF1498B70BE34F7D383C6387
-:105F5000243FF20DE837880F97707AD2F98EC7F98F
-:105F600056B45DD0F38D986F6FF33ABE92C243156D
-:105F700058FB4A0A2FD50B73D6BB57A521DE5D040B
-:105F8000D6132757DAF1F93CDE3E69D3EC86743A32
-:105F90004452BD8A71D924ADEECD74C8B7ACA37597
-:105FA000FA37B7519260BD4EF50CB67B6EA50B4B20
-:105FB000416F177D2F817D2F2579B04FD3931DF32E
-:105FC000673B0CEBE1ABD8317FF6A8EE76CC62F7FD
-:105FD000BE05FBFF4B9B6515F862CDE43E1AF0D37E
-:105FE000C69D9217E26E879A591EDEC619CC9E880E
-:105FF00071CFBE9A8876E3ACC4E49CB424A11CD4CF
-:106000002671DAD427E17EEC39BEAE5E91E5AFCBE6
-:10601000D6E9CF8DCDA362715FD66497E89F4BA27E
-:10602000ED700F4E02FF69F85A2513F5C072809F7C
-:10603000CC6F1B119B097CEBFF609C047AE09B0CEE
-:10604000A0A7795F4FECFF897DC13FA6F95765EBAB
-:10605000F456F7FD3EE33E959C60C73CDEB132CB83
-:10606000E3D5D95F02745D037E22E5BB35C7E2103C
-:106070003F6B2E33F9A370FE04C669718E467E1203
-:106080007696C259F42EE90E67AD258CF1421D9C1F
-:10609000CF5C1D4E539E2B87AB0BFF7C7F4A762A2D
-:1060A00008FF3912E70538F7DABC1FFBC10E9F8DD8
-:1060B000C3F89EA04F0D97B173941E1285F3DCDEDA
-:1060C00011B11607F847FE17805EF2A07002F8E7DC
-:1060D000879A47E4C37C7ADAA73D9255FA7236CAAA
-:1060E00099FF37D06EBCABEDC26FD5C8FCAFB2BF65
-:1060F000BB0BDA7D07FCBCA6E7A3DEF053AB38D6BA
-:106100004A2C408E7E98C4F5B499EFA4E603FF05AF
-:10611000794754DE30EF339041826B28DE1A8632A5
-:10612000FE2373898A76D9C4272BB27C6F03FC4285
-:106130004EAF829F7701EEDA2C5F2B7C0F700C281C
-:1061400046BDF47E36B36FAFD82CD89EE5AF241190
-:10615000CCC731EF9F9FCEAAFA04DB0BFF2BCF2FCA
-:10616000B90ABF931C1CBF3A7F85902F96723C2DB5
-:10617000857D5DC857DB63ED30E44598F0F0789697
-:10618000AF83E181F2D948C6676BC855F11186EF3C
-:106190006BB3FC17002F4E2BE51740CAD8D9698086
-:1061A000E7C3AAF635ECFBEF5EC5F071EE4F0C1FAE
-:1061B000FBDA2DC8D74F93212897C596F3F741FFF7
-:1061C00054BF5C867EC685774AB06EEEB740B58018
-:1061D0005E1E10F6CA96ABF3AD9483EB27BF022583
-:1061E000A5C383408711EFB078CE55F8D60EDF7F78
-:1061F00007BC27E57C07FD43F92A15FA177C75AD26
-:10620000F956942FC8803EDDFBA3EB28DC5F38B045
-:106210002F06F555CD6E09F579CD1B5FE07ABDE609
-:10622000B51864CA89AFC5E2FBF37BD8FBB325D1AF
-:10623000F3013272FAA0DD59BAF3019FD14E07F093
-:10624000F9CFB4F3AE2C39B2BF9A3C859D435813B5
-:106250002BF24DD93E6B02E7B3E4413E0DEC507298
-:1062600019C17CC10407CB43EC7EDE80C96D2A6F67
-:10627000E772A912E0D97CFE408E63F985A964FD1E
-:10628000D780A7E40AE3FB544705EEBBA69ACE29C4
-:10629000087C97E570FFD946D2408FEC34E55588ED
-:1062A000F2FD1CEE07D627E17A50E170B5386DC8D3
-:1062B000B7CB9C769CF7B224923C19EB0ADA7F7339
-:1062C0003F5DFEA76621AAFE1C45451C5175FE5187
-:1062D000AAAF8FA1DE6F667FC3F7E97E8FE1FD80F5
-:1062E00005430CEF07D5151BEA83975F6FF8DE4D6A
-:1062F00011A0AF67AEBDC5F07D76E374433D77F383
-:10630000DD86EFF3835586F7052F2D32BC1FBA7358
-:1063100099A13E6CEFA386EFE51EFCF26773589CD3
-:106320004D167EB973A41FF84A76DAA518DDFA6F08
-:1063300019A7474942451AEC5BD63BCBD3607DDABF
-:106340009244EDF155E26EDF77DDD628E8CFFDAF60
-:10635000521E773B7B906A11CA7F3587281F0C43FA
-:10636000FFAB3187FB5FB355F83E6C437BA278717E
-:106370001E3312EC184F33F7BF2C478DBADE922D27
-:106380005ED764A9677C09BEEC0D5F9B395EFFB7E1
-:10639000F8FAC8943724D67BE6767FCEB1707FDCDE
-:1063A000BF3B47BFAE2361D987EBBA6FCE0608E883
-:1063B00051827E4D6DBC0BE312663F408CFFC734AB
-:1063C000DFEBD08F599FFA96CF67DF59E80243EE93
-:1063D00079BDF7E71CF37AAF6C26D223C966C0D328
-:1063E000FE2E3A6B86F55E7DD2685CEFD55BB5B468
-:1063F0006B59EFEDCF2188EFCD40D7541D3D6D5E39
-:10640000D5857ADEE8BF74F7CFA9FDA3F3DC087E5B
-:106410009D047E5932F3D7774B386F31EEF7F0CFCA
-:10642000DBF5F6A927FF3C8678D72A32D2EF4BB0AE
-:106430004FD41F7F3056FE5EFEF885EF620FDFB748
-:106440007A318FFDFD29325945F178A1624C3F1216
-:10645000451F8BF2288FDFECCE2548B7DEE21FEF19
-:10646000AF5C70D5F31CEF57B23CCDE9C047BA71B1
-:10647000D373195F8CC8E5FB92312C8E71E63F9C7B
-:1064800078EEE0CC2D1F261027E4B78D1819803C3C
-:1064900066E27D08F26F020E27C609A7578E1AB969
-:1064A000CAA9E3ABB10CCF137EFFA70488FF4CDF72
-:1064B00095991A70F4CC4F23F8FC88D2968379D939
-:1064C000AF9FEEABD272FABEEC5416A734E6AD998C
-:1064D000E346D397D718E47869A74482C9BABAD2F9
-:1064E0008AF9814B3B157C7E39C71857EA115FD773
-:1064F000884FF37381CFF72B4F67403CFD6C6C7472
-:10650000FFE37E8EEF2EFE319D83E9E97C4739EF74
-:10651000FF42C575FD40CF4DB7A9D9D712E7127814
-:106520006ABDF4453CE88937E07C4D94FEC7E7B28C
-:106530007DA537B4CFE1F80329B1872700DF97F0B5
-:10654000787A94BCFFDB7261BDD459F12FC9FB9FEF
-:1065500095CBE9C3F3EAF372D5A879FFBD9D5F9AA5
-:10656000668B6EEFC646F0F721C8EB83CF595D000E
-:106570005735F84E10BFDB6AC5F8DD07976208ECA7
-:10658000A77CB1C5FA2BC8575BF05CE6739B687DAE
-:1065900041650CEEFF546FB5B2FDB9CAD82084AA8C
-:1065A000166C7DB8EF1C3ADE57546E9764D3F7CF64
-:1065B0003D8DF9331FB4AFC3FCEDD320CFF4F98286
-:1065C000CB8FCF00FCEFB335160CA7E5921D92E1FF
-:1065D0001CC6A2A658435DE4030AFA1129723E4381
-:1065E000A5F6A421D7781E6B4464DFAC2197D96B44
-:1065F000CCB3AF99C2CE631D3AC9D6FB87B358BEA0
-:1066000060A8F2CEC9C3E93C2A53AD182F31E71771
-:1066100012824427F379FE6FE5270A9EBBAD1CEA80
-:10662000443FF0CD95754807DACE51A63B8F50F91F
-:10663000731677A974B3BCF91EF30E4DF986E27C8C
-:1066400050B73CC3C8F9A0E3D1F8E657B946B93E04
-:106650007492E515CE7F4766F3EA456F1EE5F3F8C1
-:10666000A07DC8BDBFA5F8F8A08269F10F2EDDFCA2
-:1066700018C4BDBEF04904F23CBFB814FD5CDA3F5B
-:10668000BAECABBFEBDC0ED0E7B68A855D7510CBFC
-:106690003B7C0F18CEF55CBBBEB9BA3EA9CE65E710
-:1066A00032CDFADDCCF7FFBFF4FBF4CAC3190127E2
-:1066B000962F40D9B18BE947B39C9BF5B980CB0CA1
-:1066C000EFD24ED990873C16F4C028BD3EB7E17B8F
-:1066D000EAEEE37C02A395E01A09FD80CF81EF4743
-:1066E0003A82C92574887AD7B6F8ABC56FE8FAF94B
-:1066F000347C5FE3F6774099FCC7FEA560EF47BCAA
-:10670000B313F308CFF5904FFEA1DB94BF2619F722
-:106710000BBECD2DF910D6FFEB54560AF91C498556
-:1067200090E73B7C9BCBF6E57E0AFB96356F5D449C
-:10673000F97CDAE64F83F840A0BFCDBB3D4A7E88A6
-:1067400092F7DDCE25EC80F83CD03D2FCFB0DF07AF
-:106750007122CC5B381E8771A2E7D3B4B83CFADD56
-:106760002B695A7C1EE8F334CD91A7B34FF57C9E7C
-:106770008A25BA5F5C9627F8DF87767C5E29D5BFCD
-:1067800051F8D09BC7F2F94B9EB92B03E2719F1FC2
-:10679000BB3B03F463CBD363AE9AD7F633904FAAD7
-:1067A0003F9F04BD9F1DD94FFD09971B11EF9E67A9
-:1067B000F3E5E8F3B192F392D87EED75BB5B3D94BF
-:1067C0004FDAD7CBA8BFDB1D2C8FED8443A9682AF5
-:1067D00064ED520CEDD8F90519F89ECAB1E250BE2D
-:1067E000D5EBA332E0E9D49EE759C6E964235E3BCA
-:1067F000B4B71DBFC50E76549634178BFF337EB8E1
-:106800008E8E00FCF038D76397D3FCE301EF366E31
-:106810006FAFE3F6567198ECEBC0ABEF8FEF4DD353
-:1068200026423F77A7696540D7BDB64001C8CDDE97
-:10683000B8E8796993F2983F129BC7F98538D07F01
-:10684000C5F164DCA79F9AC7F6E97D50DE3420BC11
-:1068500006F2C93F74BBBAF6B97D789EDE7707BCF5
-:1068600027696DE456C893A3C0C23987D74F1D2747
-:10687000A0BF12C2ED04F269124CF9AEA2FC2A8F3D
-:10688000F91FAFF17DCFEE72C7F8CCCFE16CA2F269
-:1068900002E74185BCC0FE3AE44BAC53FD5CEE58C8
-:1068A000BE47D3537D24D867F168AA05F803F24C9C
-:1068B000413F99F3839AF3981E053994AE22870FCE
-:1068C0007F47396C7A6AB22516E07C94605E075582
-:1068D0007EABEDB4FEFC329717CE8765AE27B80EBF
-:1068E0001AB43C6E1BAC93025C9E066F22AB63E94C
-:1068F000D76E9EC727F2A2DDF56D0A9E177894E544
-:10690000E99DFEFC16D909FD7F2DFA37E6058A3C84
-:10691000BE468E5F318F251EFF93C01FE6BCEA9EE8
-:10692000F3BFBECC873C87E784BCF33C9C713C0F33
-:10693000675CD3D3188F1BD774B322D14F9E5742B5
-:1069400012ACF79EAFD314B037BFCB637939BDE536
-:10695000C1BDCCF9B191D3B9A77CCA17F87751F270
-:10696000295FC84BD5E593FD80E5533E9EA7E2F72E
-:10697000CFF33C9AE7EB58BC6ED14BEF49FABC39E8
-:10698000F19DC8BB1BF810CBBB7B5E698B05FEB9C4
-:1069900018CBE875F10771C15518946F1B1EFD1CCB
-:1069A00082398F9CE58F0F0E874B301F8810BC07F4
-:1069B0006148BE6AA0CBD6B02B0EE4A5377BF0268B
-:1069C000A7E7B5F2E18BF90C9F51ECE63B80AFEF06
-:1069D00060375BF398DDFC20EFFBD84D6E2F85FD13
-:1069E00014EF8F717A56E751BBA9F36B7576F358A4
-:1069F0005E14BB99428298A7413A2C5E7D5EA8281E
-:106A0000FDBCDFB73DDA17D07E1C8FA724741C278E
-:106A1000924E0F4DE7722DEE9778B10FB97F5A94D1
-:106A2000794CE1FD596685F13E8A8466296A1EDA51
-:106A3000876EA64FA85EFC4F94B3C1546F4ADDF534
-:106A400066147AFC13BE1FF08E760898E4FAA4A6AA
-:106A500078709FAE420F4B7E2AD04393A114F82F3B
-:106A6000BE625C470AFCC7E533F9ED9BADC5E6D3D2
-:106A7000F22F5CCE7AA24B7A3EF36386F052E4A901
-:106A8000EF36F9A313F2195E6ECE37C61575F44BC7
-:106A9000CF8F423FA187DFF6F806023CAF9DDA1D9B
-:106AA0000F7C24E824F48F995E11395B25F6C9B375
-:106AB000F3A3D81FD1DE6C8722ED0308F756E0A3BD
-:106AC000912CDF07CF11F0F308023EC1E71A9FE7D0
-:106AD0005F3DDA7080D70CA7ABC3225D0DCEA470EA
-:106AE0008A04F29FA4B9B07CFD944502B85C6105AC
-:106AF000F3DD5DDC3E9AED2055171CAFAC9F17B956
-:106B0000DE6838C3F2101B4AFC6910FFCFC9D626D5
-:106B1000025CD5795A1994D7656BE5507EE8667E9C
-:106B20004B7ABE560175912F6086D397DF957770AB
-:106B30002BE033612209803D84FB64609F2581E75F
-:106B4000312468AE52B063095B08E60924C7870F99
-:106B5000C4C0FEDFD3C40BE79F7202AA05D65F99BB
-:106B60000F69ABA16C38C3EFC52921787EB22B8F9A
-:106B7000AEDE837974206F7A7EADE278AECA677A32
-:106B80008EFA21F7E733B866E7EBFC1021473DF9B1
-:106B9000153A395C80EDAE5D0E6BF3BF9B1C3EC8B1
-:106BA000E5F0A16B91C31F46E4F051F8BE37395CA4
-:106BB000C7E5EFC55EE4F0FFF07E7F97DFA31E5DC3
-:106BC000174D0E459EB0E0779043B0F741DE1FD5DC
-:106BD0009F3FCB4FFD5E72B9399A5C9AE5B1ABBF6E
-:106BE0006BE4FF9EFCBF0143FC7CDED1FDBF1D3C7E
-:106BF0005F5CC833959797B9BCFC9ACBCB0E80F7F6
-:106C000043B78AE398E5ABCBDE84999E80FC3C7D5C
-:106C10009ED6E108BE5E857ECC7939E34CF1FCCF8F
-:106C2000F2193FBCC3CB84F071027A81E2ED8D7C16
-:106C30009DDD7891CB4B602CCB3BA5925A0A7EE52B
-:106C4000BE0EEA470238F90CDE719B5B0F81DF480C
-:106C500094C678B8E7AA273C7986A8625F202A9E66
-:106C6000E8F87F86F1CD746B06BA39BAFBF3667A21
-:106C70003573B90D737C7C5F3804FE008E61088724
-:106C80006A59A7B3F39F733D41E16D0778C74F0C75
-:106C9000CB04E10AC5C3FE89D0A764206D3FB27B57
-:106CA000FB8E48FB0EA0D7788DB62F8CB44F825048
-:106CB0007E26E831AACFD04FD6F0BC62839BF18309
-:106CC00099EF9B6CEC7C4417BD1AFB23BDE6AAFE32
-:106CD0006FA1FF26859D1B695AEB92D8794096EFEC
-:106CE0007B225343BE8DA287C890EFA68794214C88
-:106CF0000F59875C831E720CE9D243F1F07D38F79F
-:106D0000EA7A6800FF7EE090ABEBA10CFE9D67483D
-:106D10008FFEC0009897590FAD53191EA2C8E960A5
-:106D200080EFDB5C4D8592CAA97B486AC4AED17600
-:106D300099509FCBDBAF6F64F9160112E78DB6CE89
-:106D4000F00E715C6BFE9997C3F99DF2A837FEB8FF
-:106D5000CD06F816794E625C73FEB4A0634DF3AABB
-:106D6000116428E4695DCA00BFF2DCB16F313E7284
-:106D700024AB4A83F15BF68F31E46589F197F178B2
-:106D80005A995CB813E2B3E78FD830EE2913F5D9DE
-:106D900071149EDA235612443DC5EE1B10FB61D6DA
-:106DA000230DAD108FB712DDBD50B89E5113816F0A
-:106DB000AD47D8FD4C2485BD0F10FB2A76BFA371CB
-:106DC0009F3F4933EEF32757F431EDFB1BF7F9FBF7
-:106DD000CD34EEF3A7FB8DFBFC0316149BF6FD8D63
-:106DE000FBFC8397979AF6FD8DFBFC996BA79BF6AE
-:106DF000FD8DFBFCB99B8DFBFCF941E33E7FF55B10
-:106E0000AFD8605D5DF0D232D3FEBF71BF9F22A4C8
-:106E1000354B775FCCB0BDAB0DDFCF6D63F7900D19
-:106E20000FAD33B66B64F71504E87F80CF2F88DF92
-:106E3000067CA690F09B0320BF25287943F4B385F8
-:106E40007B778D86B298C7C5AB371BEF395818349E
-:106E5000D6BF7ABBE208E481D58210D17E6A5F9208
-:106E6000824177CF745FFC92B1BD88F32EE6F3398F
-:106E7000CF9D82F35B643CB76CE693EAB76E63F731
-:106E80008605B456B8F741E041F08B8BF38B804B0D
-:106E9000E063B1BC04E55CE041DC9F55639A7FB7D9
-:106EA000F9EEDD8AEDCCF336CF63FB90AEFBB0702C
-:106EB0003F8074931307CB13A2F3827D72399067DE
-:106EC0009213231E7AC2DFB5CA8DCAF1109366945D
-:106ED0009B5835CECC77486F333EE3F38CF264C6D3
-:106EE000A7D3DB3F2A7F89FB4F713EB01FB25722E9
-:106EF000BF90BAE37541F386860151F8897A7E988E
-:106F0000E761C6EF7B26FC1E56FD47413F5DF8F862
-:106F10001B19E9EA6F1B01F6EC2AF9671FF3EFAFC3
-:106F200075BFFD187C2FDA9BF7DBCF419EA4EEBC2A
-:106F30008AD44537CD942779E8BF601F89B6F1DB45
-:106F4000200E5BE1B5B3FBC0CCF96BFE736047026A
-:106F5000A51AC138E079E25D43FB5BE3FC8F825EFA
-:106F6000E2221786A0BFEBC7FB85C687DB2EFC1687
-:106F7000BA575A5D304EB47B484DE70F2FC3B8DF88
-:106F8000F79E47E1B7D3759252C0FC6E5B817E9D40
-:106F9000D475BF2A5BEFF4D48FC823EBA9940ECA33
-:106FA0006857C3529C37DA3D65E905467BAF3BE73E
-:106FB000995EA0B3A3350F5F7813F41EC5F7407830
-:106FC000EE7452FF46BA26FF4685EF9F8D4F40BEB6
-:106FD0000EBF250773DD707F959AD8A7B0FB7D4B58
-:106FE00022AFB00EEE534A86E7F98957CBBF28355A
-:106FF000DD7365BE97A8A198C155CCE7E9E7F75DB9
-:1070000095F3BA389726E271B53359BCF969531C28
-:10701000B3BCC0C9DA679596039D1ADC12FA4F0D0E
-:107020009264D84FBA38A4A41CE6ABF1FECB21364B
-:107030009F8AE7EB10AE14D33ADE52C0BEB7149469
-:1070400062092B7AA0B74D96A3E2735201835FF8D1
-:1070500051DFE39E99A33123BBDF3363BE1FB13CF5
-:10706000AFAE05D48379DFF7D5DEEE99395A1E75B8
-:10707000FF17F01BDF27C2F7730B8CF72086E2FCAB
-:107080001BA7403CE24FB217CE9B98E7FD4001F3AF
-:10709000FBD7F3750BEC2BC17AA40F2FBB7FCFF07E
-:1070A00014CCF23D807855285E29BC211BBB0F34DF
-:1070B000FC21C171FA2FD00E407D944FC5F3150D00
-:1070C0006EE280FB82C2C32D181749F1BB26C2BDF8
-:1070D000BE295BA43E804EA117AC0A093829BF34F3
-:1070E00016B891CEEBC99A0370BF49E296AF8907F3
-:1070F000D713AE892ED0477349D438E7937C3ED35B
-:107100009EF328B02E4BB447BFCFE1493E0FAA1FD4
-:10711000D6C13CC6DB8F8D903C11FD024B5BFCBFA2
-:10712000768BE15CB3284F644E68047E1DB580F415
-:1071300010F7647C7A83EA7B06FA1F7554C5FD8AD2
-:107140006AA1A7E75A08DC3B7A17679FBBB6B0FC79
-:107150007572E9CA1559F8DD04FB27B07F50BDC42C
-:107160001984FD84EA6637DEC7471648B8CF51DB7D
-:10717000FC9E0FEAD52347BA50BFC54B12DCCB08A3
-:10718000269FE933859C14FC22F349D1FE6772FBEC
-:1071900020D6F7D41EAC8FA778AFDEB2F5009C8F57
-:1071A000F87FD4F003DD3E96FD1FFF90F67B073598
-:1071B00052CB8BA154C82C8CABA7613FB7F37E0296
-:1071C000DF12E9A43D32EE1DCD6FE17C3EB6928028
-:1071D0009D3293B5940D6D7D3411F75B457ECE0CD9
-:1071E0007B6319D8B973B670119C9F3AB7FF2F8390
-:1071F000601FFEB31F5D70C2BEFCDF95B0139E9F83
-:107200005AF18113EEC5FB6C05BB3FEA3E6E3F04AD
-:10721000BEFFC4F5825AE86B01BADCBFF2F268FD2A
-:107220003D3864792AEAFD854119533A845C2D7E04
-:10723000291E3C9BAEFAD29DC986BAB0074B634863
-:107240005DB438A1A590F1D1C21D5B6D035418DF68
-:10725000FF118C7F0A1289295D4EED71A2DF28E0B3
-:10726000A9DA31DC067EC6DF9B634808D62F4AAB1D
-:10727000959DBFD4264B941FFC9CEE6638DF7C2383
-:107280001EFB9BF734D33FB3E958CB295EFDCDEC11
-:107290007E4BF33CE67DA696F7A3F89EF704B5E88F
-:1072A0002AFB7E05A59B7FF9E3984F6D9EE7EC8056
-:1072B000F93E4B0DF55F35A7EF9CB5C6F7D5CD4F21
-:1072C000623F7389BA1EF206E7359ADF577E017E68
-:1072D0004CB5293FBB53E8A7D1640CE8A783F6CC93
-:1072E000C468E73045D9B1D285CCF9E54A3B96A7C9
-:1072F00056122C5B0A18DF2E697EEF11E09F9ABDB3
-:10730000BBF0FEA143C15129D7D34F263557E27EAA
-:10731000E124BE8F7C6FF7FB34E30A69FB890ED34F
-:10732000F9673EEF599C0EE23CF42C986F113C57E4
-:10733000BED1CFE7FC914C07FA43853CFF660C9D1C
-:10734000977CEDF312F311F313EF97CA94DFA2B415
-:10735000177CDE52C0E216739BA635F4A7A858B37B
-:10736000FF0B5C2F13D37D7A13EC4FB6F27C33C343
-:107370007D79F4EF28C8AFE0B76AE2C5FB43CD7C66
-:1073800025E84C1CD600BFEF18FDF82E7E6AFE09DA
-:10739000E245D01B6EC6D3DFC744F9CAE037533E7F
-:1073A00032D4E7351AEB67AD6D1920EFD5A6DF476C
-:1073B000386BCA2F11A5A7D083F23757D5CAE11C65
-:1073C000CD3CE26B6079B8EC1CDE29A5F1CD1F82C3
-:1073D0001C363139F83BA7FFB6425F6521DA2FAD85
-:1073E00008EF415C9D2EC345BFB3D74B2E90AF39FC
-:1073F000F5C3F13E9D62A2617FF7F6E0872D296417
-:1074000074A8AAB3121B359E55740CD073557B64B7
-:1074100071CF95634A5FB8B785D163E913BB6CE957
-:10742000B45C5057CDFC8320931B718FB4E03FA117
-:10743000FF17AD3F80EB70BAFE30C8572D9C8B28EC
-:107440000239363DAFBB19E9506BF213AA057F7ABA
-:107450008917F8D3FF88D30EE7AA7A9B37E91E5F16
-:10746000C1F8CBF923D9E83F9E57D57EF09D3F81E7
-:10747000DD5B2F29FE31F09CE20BED5478553CDEAC
-:10748000E37BAC53262ADE37E21F03E7DFDBFE3A5D
-:1074900008F76305BF8AF9D6DAD723BFD612E3BA55
-:1074A00072365DC040DC74F6F664CCDBA2FD17EDED
-:1074B000057F63BB15FD8900599606F74CF81E63DE
-:1074C000F7D056ED4DC2756D553DDB6FA9DA91844D
-:1074D000E766E9BA12EFF716F438563FC1968EF414
-:1074E00072E33D5964AF91CF059DBAAF0B4D745A0D
-:1074F0007BE0CD34B5FB3A5147A7F61EE864B89F50
-:10750000714B21D78F9C4E6405D73F0F1CCE867DD3
-:10751000A6F375B15E39CA7AA3EBFEDEB9D7637EF6
-:107520009988C755F417BF27E0ED0B74BDB07E14E2
-:10753000D2CD4CAF8A7FCE41BA90BF3A09C469EF31
-:10754000CD24F74FA7CFEF9798BCDCBBA6B202ECD7
-:10755000F9AB85CCBFFA33D55B5A2E5D0753BDA579
-:1075600051BDF501D56750FF70651AD6FFB252C5FF
-:10757000F293957958B673BF5FC81165041BF8592B
-:10758000AF73F979BD50AC971E4A03D7A2E29F1F93
-:107590008CB240E83370DF8CB24184DCAA19EDE193
-:1075A000CCDB8DF6AECDEA2A87F3BC8127D87D6887
-:1075B00055BE1B0CDF1345B5C13DB8246F44E439FB
-:1075C000CA9B6A83F3E8774D4E367C3F63ED0043F8
-:1075D000FD834295F995159986E777CF2A30D467D0
-:1075E000F3FB5C893A16E5E6219E374AC8584617F0
-:1075F0009E8FF24DDD987EFF46E1FDE61D2BBE37E6
-:10760000D343D075EE6699F8697F733653FD4541D3
-:107610006C6FA474A2EDBEFAD809674748C38E11F7
-:10762000EF8EA5F5633B58FEEAB1FAE49F82FF7442
-:107630006C476A02C451FD0D32F7335C78CF99E88C
-:107640007742FD2ACC53991D8CC17308B35B02CFDE
-:107650008B3AFCC400BA78203747E5604842FAB15B
-:1076600038C0CB3118C73F45FD3A571FB83F8CD4BF
-:10767000430907A712E9FB7FB4A60641AE2BFE29FA
-:107680006B69C04F2FC7F27D1A09FBFBF2BDEC6D91
-:10769000EB90BFD49D2194DF185C2FCC6963F3235A
-:1076A00052F100A0FFA924A2255120962EFBCBDF8A
-:1076B000144AA78539AD45704FCC2C7728F54EDAA2
-:1076C000AEA3C9CAEEA5A7FDBA687DE9AF63B6321D
-:1076D0007DA2F5837B2222F80C16C1BCF3FBFB6272
-:1076E0008652FA7D393F58847A6D452ACA9519EF3A
-:1076F000ED363FE23700722045F46444CED8FE1BDD
-:10770000556EE9A06FE658BD7DC15EB5AFB7B27BDF
-:10771000E1142D611A9E33DD8D7CDCAEA8E530EFDF
-:10772000F6B56EBC4F478C5BB55ED6D87DB8942F4E
-:10773000E1FB0DB21FEEBF11762BB056F2C33D39FF
-:1077400066BE79F0813198F76EF67F457996CAAAC0
-:107750005FE7472CDA2FE3EF5890916DCAED86FB77
-:107760001DD9EF7D10FF58433EEA12CF1FFEE6B051
-:10777000A05F9308EB8ED34765E4B3D39EC6D1696F
-:1077800099905E7270F4BFD1FA57530227E15CED15
-:107790008383FD2301AF8B2DEB3360FD74AEF9C401
-:1077A0004FE1FED82F7F63F5C2B08B5E5E3818E3E1
-:1077B000F4DCFFEEAEB7C4FDA45A3ADC17B458DDD2
-:1077C00089765CDD211136FF20C229ECBA6B9384E7
-:1077D000F7049D18E55C07EBE539A6735D27F8BD56
-:1077E00015E543993E11F6FE315E9F63617C4DDEE7
-:1077F00090D8BD52FCF71E843D10FA5AE8FD19439B
-:107800003D2C9EC1F535213B516FCD87DB94E83C83
-:1078100097BC14C3E2CB2A5DE08FC67B4BF16FE3CC
-:1078200050A62F16D97EF30CC852356945F8BFB45F
-:1078300006E7B7BAA1FDD6FA3ED8DEEAC5782BB77F
-:107840002F70AD3DE8A56A2E7F4B1B25BC1F8970AC
-:107850003B398FF74F5EB246EC86278A7D31D9954A
-:1078600079DCAECE23A6786DA3D1DEF9E2D9E2773A
-:10787000111D17EC67042EEA3F53DCCDF707DF9CA0
-:107880008A704BDE601438AA493804F7442DDDC1F4
-:10789000E2D766B8CCF3B85638E77BA74D4C1AA9A7
-:1078A0001BD704B7C037067C757410789F1F60F82B
-:1078B0009CDFCCF6033EE7FE1AFDC338B399FED534
-:1078C000C43715F2F3AA3751FDE98EF083E08385C2
-:1078D000BB82B85FF115694C70503958B279D78CBA
-:1078E000EB54583FBF87EB90597D42D99624BA2E6E
-:1078F00008BCFD4CC5A0DEE3F5FF2A3C117E6F36C7
-:10790000B6A37899D7C4EEC5D67DC7F3D00388AFA8
-:107910000581800DE2990B787CB037386B1576EED7
-:10792000BD7778191EFFD57087861AFDD8887F9499
-:107930001D75BDD5E517F5628F3FB58606813D0EF5
-:107940000F52D01E7DA378FF529202F6391BD70D3D
-:107950003DE9DBF9DC2ECF033B4DCB939B5FC17B35
-:107960008F3EDFF40AEE8FDA7E332F01FCE5939B26
-:10797000E7FC14CE059CDC3107ED72F52F845DF633
-:10798000DBF4F67EC2E6D9BFFC11F0E94BB118D7A3
-:107990009FDFE2E7FE38D57FA0173733FD4736314A
-:1079A000FD580DF6AB10ED572E7CF7C87C7F2EF0FE
-:1079B000BBEE39DAB547E6F8C7607BE20AF1FB7B3C
-:1079C0004360BF847D1576F7DD74FFD9A16017E4AD
-:1079D000773EFC019DFF99DD32C67496CA5B33E0A9
-:1079E000F7507AD2E3DF1FDF962E7CBBAF01DF5565
-:1079F000806FF48718BE8FAF65783EB19EE1BD61A0
-:107A0000476602AC838FAFCD443FE8F88E6CC4F775
-:107A1000DC7514DFE807AB463F682DC537F8FF80FB
-:107A20006F3A6E558BCAF1ED65F85ECBEDD07A56A4
-:107A3000CEED86D7C07DA0571EF9558C17EFA18ECD
-:107A40000DA5C23AE5D42E9940DE42979FC4FD1998
-:107A500081E77F90C6E7C1AFEAE6DF6C882110DFDF
-:107A60005CF8AA13CF0D7D2995F403027434FE212E
-:107A700001C68B8CDFE5D7788A46E9FC9A6BA44F68
-:107A80000DF1615E7F4DF31F3E06BF1EAE1D827578
-:107A90007F8DB82F62AFF1BE0849059D86E747ED9F
-:107AA00076E08381E6FB34FCF8FB3017B3BFBE6F92
-:107AB00019CA733847BFBF521B17B2423C2ABC4B8E
-:107AC000427A2F7DA824A184C0BE541DC231BE8835
-:107AD000AD2B244DC338630CE59B38B8AF0C2ED1C9
-:107AE00085E7AA8BC51DB7D0719D1178CDCFA78230
-:107AF0002202FBEE881EB7AD2B627EC052D982EB0C
-:107B0000902536B61E11F921B7F2F7B716B175C92F
-:107B10001D452CFFE21C2413D17ECF6D88E7F9CEE2
-:107B20001331FE29EE0B5004DE5CCA59C3EF27F077
-:107B3000F8C2DFA00D85736E0C8FFFC24FB6D0F672
-:107B4000F7F0F6F734FE09F7E5E84AE639B0BFF793
-:107B50002E8FF1E2FD8C701F1CE5BBC7E3D83E0AF7
-:107B600049495440AEEEE67AF69EC6277D608FEE18
-:107B70006D8CD7A0A4E304088FB78E847DD8FE3621
-:107B80008CB7CEB2B7FD06DCEBFBD34E3C6CA753F3
-:107B90005B6561FECBAA3E04F36B8651371EE2B7EC
-:107BA000F4D59E2BC957E31F633C7909C475AF27F1
-:107BB0008CB1C6225E0D758A5FAC3714DD70E7A606
-:107BC0007184BC4FD4A140EF25801BE087D9891870
-:107BD0001FB815E2CB7DA05490CFA62B246061E5A1
-:107BE0005A07DE87C1E2CD53F9BCEF184B428974C6
-:107BF000BEA1B78821DE7D67C812CAA574B8550931
-:107C00001D00BEB6D8552BAC0F7C155231AC9B97DE
-:107C1000ACBE36787F5E547EE7A681B46E61FBFF12
-:107C2000E11F48787FC93D54C8813FEF53488B5CC2
-:107C3000CCE807FC57DB87DDC71D7E80F1B788B332
-:107C40000B3A0DA7DDEBF17B0F878FF6B33601DA28
-:107C5000DBA2C797B673B9107EE7622EAF8B05BF64
-:107C6000ED30CAE961212FE0E752BCDDC3CB9EF8BD
-:107C7000FD20E7F7839CDF77168975F8B58DB7345B
-:107C80008684F4BFD724C6BD9597A122E63F0B3862
-:107C9000043F131E9FB250CD017CD4DEB806FDA672
-:107CA00005A67831D1C7B1E468F52EFD63B902A508
-:107CB0002D3C17E0916E8AF5025FDF63DB99CDEE14
-:107CC0005F317E27F6716791562BBF8F8CC5B9B88F
-:107CD000BD2A931D784E7F96C4EE5F3A57E20C584A
-:107CE000A8BFF829BFFFE47C1D3BFF3AEB07EC7C03
-:107CF000E7BD898F4C05FF7056824D81F253FE3BE4
-:107D00004FF79356A7DB1DF14F1A4A647E1FE8BF59
-:107D1000DD09FB196B40AFB0FAB3DA388C2AF1FAFF
-:107D20008ABFC0FBDB2F513EC0FA8FEED4E8B8E724
-:107D30000EF3F7015A87FD92C7043FAFC6FECE3D52
-:107D40002DDE37B0FA13E2FD93ACFE13D13FAF6FD7
-:107D500030BD5F657AFF7356BF50F4E49D70CE71FD
-:107D600016DFC79975BD847AA518F88DD277D6EA43
-:107D700010E27996E5202B4B4908CE5DF4F6DDE064
-:107D800061BEE2A254B8D7A2DD09F63B77B886F50A
-:107D90008143FDFF04BBB6689A14B081BE3C1ACC87
-:107DA000E1FA3D6ABE7631E7DF415ED69FC037ED2E
-:107DB000276658EA77EF6707C035CAD08FEBFBF428
-:107DC000B3BC3B3CE9DFA79FCF4CFD08FFE8E16275
-:107DD0006D24F44726DE6088FB2DFEB13711FC2BA5
-:107DE000F22EFB7DA5C5AB77668CA0FD2FFEEDBE08
-:107DF0008CF9BAF5784DA74C34AA8F6A3B252CBF75
-:107E00003AF0890DEE1FA8D973C0565E08BF0B73F8
-:107E1000C0364107D71291874ADA94E93AFB7EDDF2
-:107E2000300BD71BECF76516FFF634EE772EB6EC69
-:107E30003CF90B88035DCFE272E6F9B979BBBFC1AB
-:107E4000FE7314FF7DFC30A68FE68FD46E1A06FBFE
-:107E50007B80335A4E58137D1F7F2DEF6F561CD3F6
-:107E60007373463BEDD066D451FF1A381F367F8BB3
-:107E7000BB18E2BCE38796560CBB6ABC34CCE2A5C7
-:107E8000CD2C5E3AAB4FEB4354899335BF7BF95908
-:107E9000FB8D844C7A9674DDF30B71483C2E8D7209
-:107EA00077E0CE890331FE85F5F9C35E7F3640DB8E
-:107EB0001FE1F7FEDF3B66681CE8873677BCC545E7
-:107EC000E5B9BC70F61A80E3DE313796C3F3921839
-:107ED00067CE6C167747BE282FF4DD07F386EF21B7
-:107EE000DEE1B7B1F897FF6D19E35FFEA2787FB4CA
-:107EF000FDED591C0F6B8631FFE58885C2591C8149
-:107F0000438C4F1D96875A697FEDABD387C339BC2D
-:107F10006D8525AB112F7CFC6D85FE5AA88BF1E990
-:107F2000748BE0F9B5C2B184C3B11ADAD27E7CE3B6
-:107F300028BFE9D68DD327C61BEAB74F4E269A3EF7
-:107F40000E7BFB00437DE6AC4CC3F777CF2D30BCF6
-:107F50009F12D33AB2EE3BF8C1B54E671CF8639F4F
-:107F600035FFE3A37BC0BF6B92F1776A16EEDFFEAD
-:107F700011FC6ED3793AE1640C86AA180FFBF20863
-:107F8000FB1D4EEAD729FA7D9D33A4F519D807D5F4
-:107F9000ED1744DD4F15FB058B5D2D98C7F7BFDD51
-:107FA000D7D9368CAF878B21B519ECD2871887AB20
-:107FB00071B0799DD9770C7FD702F20AAE503EBFDF
-:107FC000191AC2BD7A9DABF0F7C226F0DF139E00EE
-:107FD00097B0C3BA60E0030A9C6BAFA525D897722F
-:107FE000AAA712299FB41E2043F7405EAFDB897910
-:107FF000174B3B6FC338F791B840E103F4BBC56B37
-:108000002BB15ED3198FFDFE596E2DC7FCEDDF4BF2
-:10801000B89F3065C0BDAB017EF8FE413ADE94DF0B
-:10802000DD5C0178AAD9C3F233A6C8EF8F847E96AF
-:10803000345662FB29323922517F21B1F31EEC778D
-:108040000AD87A5A97473BD781FD956DA19C7F0747
-:10805000BD6273A25EA9ED8CC5769326303BFD36DA
-:10806000D71BD636065759E7347C2FE8DF3ACC6366
-:1080700038776F4D6D52E03E4F6B9B84DFDFD259F6
-:1080800080A598E7DB79BFC2DFA1B2A67E530EF9C7
-:10809000996FA7482E743F4C7AF742DD98441245F9
-:1080A0002F758DD3C9F29D633A59FE73EB70ED24A1
-:1080B000C8D7D4156D0AECEF1087DD05F89A3A762B
-:1080C000B83A5F274FF2C1BB6C4017EBA6F76C6064
-:1080D0009763683941F77EA9C8EF37E9E58E6116E5
-:1080E000EE3FAEC2F90A3B438EEC457EBC4F9C8FFF
-:1080F000E5F2F209FFBE0B4FC0EB40C75763703D7E
-:10810000757AB8FF0AC0DB5AC27EAF8628AD19B0B7
-:10811000AFF2AF829FD2D92EA1BFDFC67EFF77AC70
-:108120006A81FD02C52BEC0B935B318FFF017C0252
-:1081300054430080000000001F8B08000000000076
-:10814000000BC57D0B7854D5B5F03E73CEBC92992B
-:10815000C9E43D210F4E208420012643124208C964
-:10816000242408486080AA840699208F8804424409
-:108170001BAFF6CF842410042D8AB7372AD2019181
-:10818000A2D53620B6698B382168E3B5D7467BDBAC
-:10819000E2ADB5F151048B3580D72FB62A77ADB556
-:1081A000CFC9CC9924886DEFFDA37C27EBEC7DF63D
-:1081B00063ADB5D76BAFBDC37ABB184B60EC163B54
-:1081C000E33F8DF18C253176719A8E31F8F5572287
-:1081D0006BECCC866749499F3B8EB1EE7BA64F176F
-:1081E00065C6AEE04F0954711AA81EB30F7CCE725B
-:1081F00019DB7C3252BE4F60AC3216DE013CF0829D
-:10820000D17F309DDE33210E9FC68302946FB60D61
-:10821000647A2C8CCD79D11C6053A1DD17CD1283EB
-:108220007E3A72BDF1CE787C3FB15CB031E63E6102
-:108230009418D41B3BCD9DE0CC83364719AF3A9EB2
-:10824000F027633E3EBEF2593A96CFD81D26FED99E
-:10825000DC25822F2A8A316FFB7CC660AC3583CB4C
-:10826000189BCED8EAC14882BD7BF8FBCBF5897359
-:10827000198CFBF2BD306898C7EA7B8529C7615E1F
-:108280004CB63A27001E2A93576E6330CE4A5147A8
-:10829000F3AD9C1CED6F81AA1B07A3E9FB4A91F586
-:1082A0000A318CD50DA653FB9B0663E9FDE64133ED
-:1082B0003D570F4EA6F7C64191B9015E33283037BE
-:1082C000C037CCB1FA7430BE492E6F05E2A3B2E5D7
-:1082D000FA79D88F775B52AE17F0B1E8DE7EC90429
-:1082E000E3621683FD49E86F51418E639D2538EFA7
-:1082F00096EE2A1822B41BE731B8E1FD1A78CE09B0
-:10830000295F0BA8EDB42026EC731360DC8B5AD3E5
-:1083100075F7B160F90227CC07F1CD9AE9B948ADFC
-:108320003F0AFE6728F5575B021374D09EBEDEEC51
-:10833000DC06E3BA1427CF45BC34ECE4F86BD07B01
-:10834000E65861DC0D8F084EA00CBB35DF6A623049
-:10835000CFFC33F5066F76B0FFAAC1A94C063C2CC2
-:108360001BCCA067C914EF72C443CDE04D0A9DA693
-:10837000D293C9053A1CCF56A4AB8C032AE074569D
-:10838000C6F749FD8CC46F41FF9FFC524FE5796EE3
-:10839000DF2D381EBDDFE83C00E33967F68A48DF91
-:1083A00073A9CCBE1786784ECF7C76A0D7AD1D22A0
-:1083B000F341FB6BE0E985E7B968E68E76213E6123
-:1083C0009E59BCED2BF0EFBFA53D696C3CD0B7E1E9
-:1083D000776F4BE318BB2DB36F6A00DAAD2E0DC477
-:1083E000DF0CED5E38A477FAA0DF8DDD6FE4EBA043
-:1083F000FCC37477221381AE63BC0DC8CF1B96FA01
-:108400007FA807F8F6FB9FB3CD9483F8EC94021392
-:1084100024F8BE13F0E8837175EE16E7F9895E2C37
-:1084200072C994205FAB7C1CCEDF1B06C7137E2E67
-:10843000D71BA71C47FE057EC5F7750A9FDF8E7CFC
-:108440000F4F7DFF7C852F39DFABFC5C274165F842
-:10845000AECE12E5F7C17C2A7F04FC0728DF747CCE
-:1084600089A714F92E4B704E80C746659D548A0724
-:108470001F2844FEFF38CED902EF7FD2E400640506
-:10848000F9BF627009D58B1AFC26F5A7F2BF51E13E
-:10849000773DF27F08DFC3778CC177F7E5789F449B
-:1084A0003C95FDE06FCFFD17BC5A2005321F8BC3F2
-:1084B000A795F827B80E4CF627D3691DC8EB42F8EC
-:1084C000483C556590015FFA87DFA1756084E79CA1
-:1084D00090F24DC8D7D988997E69A935F8FE6927E9
-:1084E000977FD7CAFF1D0AFFCF33B2551E6C4FEAE4
-:1084F0004B0B6DEF7C4ED90B388F534E81B7F74F36
-:108500001A37E0C984F885F1BB915E8B0A64DD7D82
-:10851000E9D88FBA7E399F7CD5F87FE4BC3679FFE5
-:108520001B45DE87CB7706EDA17CFFF885497E945D
-:10853000FF6F33D00700FB4E44CA4F2AF29FF4432B
-:108540004494FF6AF27F5DEEADBF413C8D20FF7F1A
-:10855000FB8FC87F95AFD4F5A2AE0F753D84AF1FDA
-:10856000753DDCB0CB19F52DA41320E6495C3F9294
-:10857000EF199C479D1C9983EB525D479B8E0BB472
-:10858000CE86E90565DD04D789564F8CB64EEA9450
-:1085900075B1565917EA7AE8113BF716C277753963
-:1085A0005E634EC8BAD8782C5C2F8CCA570CF96A17
-:1085B0006D5C3D43BEAA8367285F1947590F969C9F
-:1085C000AFA70FFE7A8DFC3436C740EDFD2FF2D3F6
-:1085D000D89C91ED0919DFFFB3EC89CBF5BFCB95A2
-:1085E000613C977341CEA607F9ED865719B717C6B8
-:1085F0005B9DC83FBD117C9EBD86547F0BD6BBC220
-:10860000EA118FAAFE5F8B748F0DF269B5CB5B8E7A
-:108610007456E9DF1BE1CBDE927DED7436C6F519A9
-:10862000DCD948EF3E8DFEAF1B85CEF373BE9EDCDA
-:108630009B91736D745E91F34FB713D78E4457E6D9
-:10864000E6F640902EC66564BF0540A109A3D35548
-:10865000DFC1F1AEC26D0149D5B7B1A86F815FD658
-:10866000E5FC03F2A7720EFC3A06C11797BB8B809C
-:10867000EEDF5160D6B31CD7E14D056A79A0C32D5A
-:10868000A1DC81DF0BA9073733117E39ECEB3E53B8
-:108690000EF56FD83B54EEC3F28AA228A53DE6162C
-:1086A00058B07EDBD1936776D33CF6F0F5EBED97CF
-:1086B0003C5342E05C80AD21704118BC8FD7B74974
-:1086C000FDCC4EEDF8F97A85F60517E71F4F883D8A
-:1086D00002949C1B8DF6E471C17E1FD07F45D1C7EB
-:1086E00006A45770FEAF2C77A780BC3C2128F07FF2
-:1086F0009CC1F9AE38CEE11F1C7DBDC32729ED0119
-:108700009E372A68D6770A6E11DADD5820F8C7A599
-:108710000FC7F30F86F8561D07A860EDF7CC10F7CA
-:10872000F5BEC7F54DDF8FA3EF03C6AFD1FFCD4533
-:10873000CCEDB70CAFF773558E7E0EB0DA3EE0721B
-:1087400019CCCF9F3DBC7E8F52BF4FA753F075B65B
-:1087500003F9A7CFA0E2F34F0457300EFFC7D13F74
-:108760002DF771BE65EEB0F95F6DFC3FCAD1DA0B33
-:10877000F8236BBF0F5C0D7FCF0FC39FC23FB55A6D
-:108780007E8A923CA72F433B5171821DEDE24D1E24
-:10879000F36EB4FF83FC3140FCD1676643FCACE56B
-:1087A000FF8BCBCBB3C9FE51EA5FEE40F9E6D10DAA
-:1087B000D5E7EB41E52FF83E0BF8094D64FCFE834D
-:1087C000A3973A7CD9441F2A2758BACA7AE80C835F
-:1087D0008BC2D68FC2FFB47E51CE037E268C20671B
-:1087E0000C2E8EDF8F04B61CE5645F19B713FBC631
-:1087F000F167A64B20BCD95C1C8F09CAB32F220499
-:108800000F29413AC34F00FD909079139EAAE2D4FC
-:1088100079C7562DCC80EF6378B9EC8A7AC4971269
-:1088200084C3DB1BE78AAD42BC04DB8F7E13E552B9
-:108830009582B74C57CC9B0A5F09B82EEB884180D4
-:108840002F8E0B3E11FD04E48B11E6FD97E17CE5D4
-:108850000BFBDEADBFCAF79F0C5F97EEB0EF993E02
-:10886000F7EB7CAFD06D61185DE785D1B53C0CAE00
-:108870005661BF46FEA9727175D7836D09308FDBD3
-:108880008F08A86642F839BD0AD7E7ED76957FC70D
-:10889000BD89FC1AE4E7F184E7A59DAA3CCC78C425
-:1088A0000D745B82F2B030082F437941F0842AF7CF
-:1088B000B4507D91F908CACF9BDBD5FA13A9FE8A83
-:1088C00056B5BD2C82553A32DFA42AECBF2A57D1C7
-:1088D00017BEEBDEC4F20D27F8F755C726BFE9CB6C
-:1088E000B8CA7AD81386977D61B02FACFEC35FA15A
-:1088F0005F5AC3BEBF37AC7C7718DC1106B76BBFBD
-:10890000AF5923D03AAC017E40427CD5BABC4D5918
-:108910009743F480190816B2DB34EBEA86160EDFB3
-:1089200071ACA0AADD1202BB0A69DDA8EB42CFF848
-:108930008F318ED1BAD08F222F6B5CA3F06556B8E1
-:10894000BEE5E57FC45F93D00E661ABBA047D4C2D4
-:10895000DDA23AEE796F6ECDC6972A7C7D15FA07B7
-:1089600037FC9B765EE0AF2A704555794A885DE218
-:108970002BAF7287CC53AD3FF78B2B22F6B7D35575
-:108980005E7508DAAF2E0B4CA8877AD531FC097AD0
-:108990004D44BDB95989C7CC7D41F4A05EAB8E086A
-:1089A0004C68C80E9927EBCCC47976DF23127D7C06
-:1089B0002D401F8CAF317030C135EB8E8A6A3C0C74
-:1089C000F57BEE111B518FBEDD189B80E33FEBE280
-:1089D000FE424FD4D884B5007747AE32C850AF7B43
-:1089E00047053D4F89EEED03B0D6BE7F6C599565C6
-:1089F000129647117E9E702DAE6A06BE3EEC92E93D
-:108A00007B6F8C3DA10BEDE7FBF4EC4919C7E3DC70
-:108A10004F7C73BF3107FDE79AE6C909684FAEFE88
-:108A2000D7257393A0DEEA36BD53A07A6C2A8EDB7D
-:108A30007B5F8501CBD7B42A4FDFF5F47CF1CB27E0
-:108A40005A6C507FE071C17910EACFFEA4F3D5A92A
-:108A500000AF6F1FEF44D29C1CD4313BF4F36EC7C0
-:108A600044BF08FCF89EB9FEE545BC3EC3FAEB3FA7
-:108A7000975F5B948BF545FB36A87F16DEA33D7CA4
-:108A800076A77850C071D9AC11024CE9EC17F26BA3
-:108A900068D742B97D1BBC3FDB765B02DA596705BC
-:108AA000D926C0FC7B8ED55439805FD67718157ACD
-:108AB000D624D5C0FC6B7443FC42FA635D34877BDB
-:108AC0005C35554F227E1F9968433CCF9AEE3EEDB0
-:108AD000023C9972DD2FE1F33D33D7532F7E29AE4F
-:108AE000427BFCE717562760BCEE57CAFA3939B803
-:108AF0003A617588BDB3EE2389E8FEA241DE8AE3C0
-:108B00007C312255407F19E81EBB04D6EF1AC5FF01
-:108B100000FE6D7C6E04BBE76997487CDFBD2BBE11
-:108B200048D6F0713DC94FF21B00EE3FB6F1111F60
-:108B3000C8D7F78D8DEC3D5C7CF742C14C78F69838
-:108B4000297EA57FC6EC37A763FCD33D17F9993979
-:108B50003A33975A43D69D52FF0F3E2BD5FF03D48D
-:108B600047FFED0FBEDF5B9965B81DBFDE66F5A15F
-:108B700031F181D52A211DDE969ACEDE0DDFAD7B47
-:108B80005C4F727FDDE3F1F70EA0BC017EC1F858A7
-:108B9000F8BCA64CD713BE465D87BE6F6BD721FBD2
-:108BA00036C9EBD1D6E15F8FDD5B75C832FA3A5C2E
-:108BB000AFF829731FD77B701DADCFB34A0CF447B4
-:108BC000D9E32F3D89FCBE7E8BD9658481AF7FDCE4
-:108BD00048F4EAB75A7D7628F7DAAC52343C4DD3E4
-:108BE000397DAF9BCED7CD1C914926173D5B314EC9
-:108BF0007A09C6130BF0F9C6BDDF9D01FD7CC8FCE8
-:108C000037CD00FC5D4282015E2E1D17297EC824EF
-:108C1000B75409F2B19671B950F7CA738652F8B5D4
-:108C2000B67EFD42F4EB6EF3EBDFED577CB62BCA5C
-:108C300034519E6EE6AF40AF6ACB37B3DD17C5A99E
-:108C4000C4C6065C8F759D61E5F5D77F80F197CD31
-:108C50004C7AB75F8DD7C238E4E9D6B8B39100B883
-:108C6000980B30C42ED5EB33194C71BD05D615CCFD
-:108C700077CE3E81C6BDBE51F41BA1FE9C581EF7A7
-:108C80007DBF09E83F91E6EDB303BCFE61AE67D658
-:108C900033C16F825FAFDFB745C2F5D081F205E324
-:108CA000D402F3207FBF6776A6A1BFBEEE7133E189
-:108CB00077FDFEDB7EFB087CD7DF5C1917EA1FE738
-:108CC0002B7C01ED33534CB09D0F9ABF9D86FC3F2A
-:108CD000E77BE0E7C27CD747B31F56A523BD92D2FE
-:108CE000644BB0DEFA6DF764F27AE027C3BC6B76B2
-:108CF0008A340FF6BC91F41EAC7507C965059F6BED
-:108D00005A5F3118B2514EEFEE13A1FEBB008B1625
-:108D1000C2974FC1A301F1B50ABF4DE2DF38F2158A
-:108D2000BB5B2639E2C5F955EB84554B49AE0F18AC
-:108D3000685D4FE7F1CDAAE9DC9EAD4973DE427173
-:108D4000E4078C4E9453F823AAE300BFAA4ED7B78A
-:108D50000EE3B9ECC7468A8F6C6E35BBCD36F23B5D
-:108D6000DCC7707C12930C808F8D3297176B143E8A
-:108D7000DC2C2FB91EF906CACF48B8BF62E572B124
-:108D80002E1AF0CEED54B70EFAF9187F1BCFDB4D3B
-:108D90009A1AD2BFA0BC8776645BB0DD5E1D6BC73C
-:108DA000380BD69F3415F1187BD3721CDFB322AD7C
-:108DB0006798FC030568E73D2B4E47FFB66667CF13
-:108DC000DC0E848FE6D8B1C99A1FFE9AF4C6ED0A6C
-:108DD000FDFBD1DE473D02F051787E7B3AD7FB5E4A
-:108DE00091C77DBEADE049E503B5BC6EA79EC7DF68
-:108DF000DB8C64C7D435FF8EDAADB3F625A0FCADAD
-:108E00007B5E9F8F72DAA78C7B75736AD119E0AB9A
-:108E1000D5FA28BB00AF36FA2A0D086FDC23101CE8
-:108E2000FC2E3E0DF9F4CFAD3FB121FFBC670E4CD7
-:108E3000407D34B0C5EC3C881350E26E7F6E9D706F
-:108E400010E3336BEC7D5601CAD76C1D1F83F2FB18
-:108E50006D7BC080E56F77A6EB1076DBED4508BB38
-:108E6000A56904FF1944198F2B31F29F37099CCE55
-:108E70001B9FE9318C83FE9E54E6FBD1B3BFCE44E9
-:108E80007D5597D697897A05F8203319F1FCB440BF
-:108E9000FA78D333A2DB3C35C8079B900F60DD6DB9
-:108EA00050F860D3F19F7C0BD7C326A4BF6B381F4B
-:108EB000019F9EA6F7C70ECC65FCFBD3C827AA1E50
-:108EC00003B8558FF1348302433F081F9ECED7135A
-:108ED0009497F3725F36C953D66F40BB737397DEB6
-:108EE000D71FB2FF331A9D7B143AAE6E3692DCED7B
-:108EF00051E6DDBFF3791BD2F1A3677B5EC6FD921D
-:108F0000BA63A0ADE511D6858297CD88071BCD83C6
-:108F1000EC8BCD386F5B100F43FCAFACC7CD8CCF63
-:108F2000539DF76649C1835AAE7C7F5AE19B8D4CB5
-:108F3000C1DBF1897CFD29EB0DD733CA55757EDE87
-:108F400018FEBDCAA7E715BDF08632CF8DC017CE7B
-:108F50006CE21FB741951350F4D1D10314FF51E9CE
-:108F6000A58EFB6F417DE28E8E09D2B15FC76A3B51
-:108F700047889BBCABE0EF9DB6C4B42EC0DB9FC15D
-:108F8000CF427B0AF9550AE94FE51BB5BF393F5877
-:108F9000B200E70BED07B07DB5DFB77D9112B6F3F8
-:108FA00036E3EB03F913E5A7BA2EE7B4AC5C9063A4
-:108FB000C37A1F59C767E37CB95CFBDB743B3DDDBB
-:108FC000682FC0F7EE2E81E2CFEF287EFD3B6D3F8C
-:108FD000B1AD0EC1D367CAB8553EC31F8C4BA9E3D0
-:108FE000ED8DE1F1DCF071AB72481DF79C1D372F60
-:108FF000C0F7EAF8557E55F953C5A3CAA7ECDE7849
-:10900000B26BC2F995784DD5ABA246DE937EBC3EDD
-:10901000E5A2C16B19FE3E1C56EDA1F7304E83F25E
-:10902000E329D14FF2A3D5713A2344CFC38F2554FE
-:10903000EF346FB9DE5E8AFBAFCF084E347942F46D
-:10904000CB6E2944BFA876C12DB9E3B8BC8F739FFE
-:10905000473A6E3CD737D72607EDD0D99F04C428AE
-:109060008C4B1D4F7785EAD38D174E13FFD7B1BEBA
-:10907000EDE847D5ECFC75E50CE4F3A7F4B43F53F9
-:10908000D3566140BBFEB6276FCD473E7AB77D3CD5
-:10909000C9F5F387F2A6135F317BC24DC0FF6B0E9B
-:1090A000EDBD6905BC5FD3253A49BE433BB86E6B45
-:1090B000EE9CCE906FDE33F75716A2FD7EB7684761
-:1090C000FB7DD69379F762FD59D6B1D1380FF7A160
-:1090D0005882DD5214E907D5EE7D5B91932D7ACE4F
-:1090E00017F372F97A2A197A727E9BD3D29289FB8E
-:1090F000E90307403EE3BEB241EE0C607F2F2492AD
-:109100007FB119DC2107D0FD9CC0EDB25A03332595
-:10911000B9E8BD2909DEBFA2EFBB13F5C82B775A0A
-:10912000739A7100E2E7F9ABB93DCDF70F6379FFB0
-:109130002ADED4715CAFF41FDE9EFA7D2FFA11286F
-:109140004F95F19F6F7DEA26D483E78F4C88C179D4
-:109150007FF082B91DEDA90FF45C2E0EF9DB7EFDC8
-:10916000FBA1761AD8751A18EC380D0CFCFBBED68C
-:109170002EDCC6ED8B5CAD1DA7F27BF5960951A1E7
-:109180007904E1F63BCB08DFB79911C5469037EA81
-:10919000F34213200A1835156D7AF8BE3CF28BE7BE
-:1091A000FAD0DEDF63B41B619EEF23FFE3BED4F38E
-:1091B000A21FF761D036C7F5F0FED11C3FFA91EB44
-:1091C000DEF2CEC5F64F3FB883F20CD6827D9928E9
-:1091D00084D8CD0F3F7813B2FF25A7777B127C7719
-:1091E000E908CF8B80624B98BDFC7292FC8FDBCB81
-:1091F000D76A27ABF186ED88E7C9F0BB933911CF69
-:109200002A7E55BFE945E083025748BCAFA996ECDA
-:10921000E40B4D5E7A7E2CBCF3C02CE45F6B94F3C0
-:10922000207CF6F3AEBD6232D2F978CEE7E8F716CD
-:109230005AA2ECB86EFFD2D4489B8F179AEAE9A9DC
-:10924000D2598DB7CD3EDE4DDFFDA56BFA8959F0C1
-:10925000DD494B1497FFC3F67B383DC3F340EED88E
-:10926000322311DFABF3FAF06E4E5775DC1F1EB9D7
-:10927000D586F3EA7E2CF6C44CA46764941DEDBD3C
-:10928000F54AFEC7D90E6E4F9F33451D5E88792380
-:10929000FB96253090B36BBBBF7113BE5FF7826046
-:1092A000473FC0F9C2121BFA6B7F92FA6D767CC2FF
-:1092B00077011C8FE417511E15CE63B41F5518900B
-:1092C000989C4E5BBDC42F332F487ECC1BF933EEE8
-:1092D00053613CE4F3088A873065FF69ED4F791CE0
-:1092E00065C8BF55FCBB59CABCDFCD8DE1FCADBC28
-:1092F0009F53C0DF7FB0EFB945D8DEF9437A3B8E8C
-:10930000FB2F87F4D4FE06F0CB7430DE7347B8BF72
-:10931000B3A153203FF9FC11D0D730AFBA2D7AB7A3
-:10932000216A381FCE81F27E4B900F37B8FDC4DF23
-:109330004CE14713FC7765DC707E8C669DDB111F6A
-:10934000FF285F9E095BF743FC381A1F28F8C27597
-:109350008CFCA8D27B4307DF578FE9CC2945BE524E
-:10936000E9AFCA095F19CB42BDDA6260599887E359
-:10937000D34538717D2FB1C87A01F0B02CAEBF1C37
-:10938000C569451E9793E21C9D5B87FAA5C5487287
-:10939000205C8E5CCCE5765223F234FCB3E6713B64
-:1093A00042CFEAC90F519FA07752517F2F898CF984
-:1093B0006F19AA7C79FCDB2B2418FF925931778E28
-:1093C000778253F67CCB0A09F877C9F498E7C7018E
-:1093D0006CCADBC6CBA7C5E4E9016E6E6E5D510EAB
-:1093E000F0843CF7E7B9F1C17ED476E1FD157CFF4E
-:1093F000CC64AF2E2F1EE5BA85E4F4C7C2C0D4C634
-:10940000F460FDD705F6F6CF8520DCAF676968DF2D
-:1094100059B1ADF8D19F8BF2DC917979C3DFAF669A
-:10942000AC8DF2E77CBF3823703FCC63027A2D56B7
-:10943000F86AB5C912207FBE5D7F6188DEC847CE5D
-:109440002809E9BA48E1A3C552A01BBF9FC45AED41
-:10945000674D6442EDBB123BBAFC8685C7CEAAEDD0
-:1094600001BF7CAC87F9025F0BC09E8DB0640440E5
-:109470007235C82FE1C42F3EC3765B7CACDF4C74E1
-:10948000A8B6A3DC13985777059E7591B6A918372F
-:10949000A98B4CF323DF373CFFD16964AFDB54FB6E
-:1094A000C55B40FCBED5CEE7C3BC85C48F772AFC24
-:1094B000F84113ABCF80A5B7B8AFCF26C3A02F2CF0
-:1094C0000A64E27ABF9CE6CD453A7CB0AF25A5019F
-:1094D000F8E7A36346E742A87FCEFF1CC5E1362A22
-:1094E000F6283B14AFAC7B315002F57AD3271D44EC
-:1094F000FD529CC7F5F585F440DA3D2837D2B9FF17
-:1095000003F528CF6DDEB6EBE3B1DE85A33B32D6A3
-:1095100002FD8C12F35963E8C96C30EFF9D0760183
-:10952000C07A8045DACFF5537B58CF86FA5EBED538
-:10953000C1E3EDCC837245A5974A8761F48121A0F0
-:10954000BDAA33313D8E7F12DB67C7F5AAD2E9038E
-:1095500013E011E36726C023ACEF0A0C3AE4223E85
-:1095600079BCA541E86F8D45F85981F2E686EBC1DB
-:10957000270D88F2DA7DB792FC51E58E0CFF8D2421
-:1095800077BE76DC68DF9C11E5CEFA3C45EEE4B0B0
-:109590009C2BDC4024FAAE57BEAD10AB6509C71D4D
-:1095A0006F72623CADE1F1F1A46F58F67FB2D07AF0
-:1095B0006C5F2CD7ABE922E1FDB62E81F21B2BBBF1
-:1095C00092990C450BBB62E9691B4CA2F7E70FBFF0
-:1095D0009ACBE512A74BE5F713CB28AFE8FB13E9CD
-:1095E000A98EA341E1BB0A31BB3380768405C60155
-:1095F00070C32B5C6F35DC28525C93A1884E4062AF
-:10960000F21F8FA59DE23F1E3664DF0B57284E2BBD
-:1096100047215D3CBD2243FE016FC3C7F16C6A4622
-:109620003C1B1D3A268F607F18153A99E50826875E
-:10963000F81D926FD2778A301EFB0DBDD30FE52D3A
-:1096400066DB415C4FCCE7EE437F61B9F25D9F99E9
-:10965000F34764568CE6FB1DB6B9BDC86FCBDD5C25
-:10966000EF589D6334FD1BC58D7A6432E6E5F6A2A2
-:10967000CA0FC497D0EF628F40FAF5C6E5501ED2EC
-:10968000AEBEE822C9717D91D6CE347AB4F5BEAFB4
-:10969000D27F129B144AFF20DE2D6EB4D32FB9ADBA
-:1096A000C4C7A0DDFFAD08E09B7AF50CE76B8CE04A
-:1096B000F3BA8498C2B8A85BF463BC6407E201DE25
-:1096C000471568F119EDD6E22F769E161FF11EEDB3
-:1096D000FC13978FD3942779AFD39427D7BA3470DC
-:1096E0006A7DA1A6FED8C6320D9CEE5BA0A93FBE46
-:1096F0007DA9069EB06785A6FEC48ED59AF249FE66
-:109700000D9AF2C9471A34F094CE7FD1D49FD6B5C2
-:109710004D539E13B84F533EBDF7210D9CD7F7A86C
-:10972000A6FE8C330735E533FB9FD694CF3A774CB2
-:1097300003CF1EF899A67EC9E0290D5CCA5ED5D478
-:109740009F63FAB506AEB0FF5E53FF7AC77B9AF20D
-:10975000F9F29F35E537645DD6F26B04977F95CEBD
-:10976000BF69BE1353BC9FA23E60E20509F9B6650E
-:10977000A5C062319EDEBBCC847260308C0F3FCEC0
-:10978000B52B7E0D4B43795621160570DD5EEA122E
-:1097900068FD87EB3BE9CF1E37C6F3D84F0427C6D9
-:1097A000D9A2406D4921FD47BB4DE04806E1D8797B
-:1097B000760D1CEF7168EA272E9735E549DE2C4DB2
-:1097C0007972AD5303A7D61768EA8F6D746BE07496
-:1097D000DF3C4DFDF1ED1E0D3C61CF724DFD891D4D
-:1097E0005E4DF9247FADA67CF2917A0D3CA5B35174
-:1097F000537F5A974F539E1368D7944FEFDDA38141
-:10980000F3FA3A34F5679CF16BCA67F61FD194CF2F
-:109810003AD7A981670F7469EA970C063470297BDF
-:1098200045537F8EE9750D5C617F5353FF7AC73BCB
-:109830009AF2F9F2794DB96ADFDC907551FB5EB1AD
-:10984000772A9D9F69BEF795B919F287EF98E06C6A
-:1098500091417EE5F3F80BC8F57EB388F69187E277
-:1098600046319820087C1905420CF90A5D856A8A00
-:109870003FC551DC9754938CF93E60270010A34BF1
-:109880004F477B3A3268B7A55C997EED76DB1A6864
-:1098900013F97C6FBEB72A3F0FFD95A373D16EBF3E
-:1098A0008DF9B6E33840EF45F5C3FA78CDAC8D6756
-:1098B000A8CFF926C04B487FAF98F7A4B8AEE2F71F
-:1098C000CF375DA0FA43ED2A710E01E6D710D2FE24
-:1098D00003E0574860D7ED698275030EE3434D7688
-:1098E000821F6E7210FCDD26999E1D4D59F47CB4CA
-:1098F000C949E5FB9A0A08DEDFE426D8DF348F9EEB
-:10990000079B3CF4FE50D372820F831F8DCF23E060
-:1099100057E3F369F08FB1FC19F09711FE61938F53
-:109920009E9D4DEDF4FE58D31E828F377510FCE3DB
-:10993000263F3DBB9A8ED0F3674D9D547EA2A98BE6
-:10994000E0934D0182034DBD049F6AEA23F874D36E
-:1099500019825F6EEAA7676FD3397AFE7BD30095D1
-:10996000FFB26990E0568CD7023E1ECCE77E908A0B
-:10997000171566AC9CF841B50F17A19D8FCC51A06F
-:10998000FF8BC6CE0FB3B7C3E9F1A11217D69781EB
-:10999000B988F1C33199075B42FCACC795FE7644A8
-:1099A000309F19F8BD59C7FDDAE6184679D64CB193
-:1099B0005FD72B7CC9E2B8DDBA4E19D77A653DE492
-:1099C000217F66117FFEF2EBF815AADF9832C5FB06
-:1099D0002CF167AACE47FEB3C59F89F673C9146FF1
-:1099E000677E3CEE37AE7D99FAB33B69DFB1D218A2
-:1099F00088BF19E323AF8814CF1BADBFCD4AFEF853
-:109A0000A8E527CFA7A0BD3DEF4BD18B787A4D6F4E
-:109A10005D8EF1829E7C1E7FEEC9D7699E2F4DF12F
-:109A20009EC2F17C6AADBF4507E3FFB478CBE13B52
-:109A3000D283FEF4627449C10F5AC2643DE52732F5
-:109A4000F74BE9D0D48D6060217C33F3D1736EB6CF
-:109A5000F7556CA70A0C7184BD85C6B491E6153E16
-:109A6000AEDF2AF4FA6DBE4EF3BC3CC5FB1B3E2EA6
-:109A7000378DEBB599D767E2BCD471E54E9595BCAF
-:109A8000E481FD38BE4F5FB87856181FC4BFEAB7EF
-:109A90006F2F55F24AB6083C2EA7DA6B4A5E8AEA67
-:109AA0007754DF29F8D15E5F09FE0EEE2FBDA5D8F1
-:109AB0009F6F99B97EBE54AFCF42BBBE5A8870E249
-:109AC0003EDCA5FA3F5950DD427D86FB242D98737C
-:109AD00000E52D770B94CF5D0DEDE8A09D6A0C0499
-:109AE000E277F70AC47F13A7A6D3B8ABC1FC233F24
-:109AF0002B6E200DF74B815F2EE37C37CC147D0657
-:109B0000B0875FD3F93305DA975E6B10609CEBE3A7
-:109B1000804FC68DCE0F9B94F307EA7BE0B32FB046
-:109B2000BDBFFC744616C5F14FCE94116F2D3A7E21
-:109B30001EC9F7EFA293E7BB70512DCE9A42714A2E
-:109B400026399D1867AA54CEAF748BACF1E8087221
-:109B500074EC0CCE4FAF39F4F3FCD4AE76BF267163
-:109B600006A763E20C4EDFCA53AFA4E2F9AB4DBDCA
-:109B70007AB247586E7FB6C73AC27C1A77DD951124
-:109B8000C2DF9BBBDEE1F91AAC3F3B343FBD40E98D
-:109B90005FE527D160F51EB0848E6F88BFD3662045
-:109BA0001F45037F8F27FE3E8BF6F622A31C7533DD
-:109BB0003CFB014501787ABF67A77C2335EF680D30
-:109BC000F3D0733DB003F2B3C7F7A001F1BF8175C5
-:109BD000D2FB4D05B7A621BC990D943BD09F686F71
-:109BE0007EC901A35CB6E7C10A8CCF2EF5D7BC8431
-:109BF000CF258784B3E8BFC2FA983603E327427DB6
-:109C0000DB18E86FC533A56DC9F07E91C8E9C15E68
-:109C1000E5F400BE718B31C3E709EB61067EFF6995
-:109C2000B49BE621DAE669D643F536E616E282F918
-:109C3000F343EBA3E0F63F26A33F240DD0FEFBE663
-:109C400093C618A4F306C6F57730FEA1EA6D467CEC
-:109C50007E3B8B7062BD0F15BEFE3095115F7F2875
-:109C60008083E70ADA932CCDEB708D0FEADF0F7556
-:109C7000FE7CDB78D2CF8B10EF2F3B96C91837BB19
-:109C80003DCEE414B13CDA9FC6F75187E43CBB12E9
-:109C9000198C7B3DA0E771A8F07109052F7F86F62E
-:109CA00083D1C07CB8BF01EB9BE5E3BA1E63A0750E
-:109CB000D582A8C5F85999471EA9FD56A5DDDE2F06
-:109CC000B81FEC83F9E079C961FDD8957E22783F11
-:109CD000AA1EC1FE488E24304D7F9B31C905D78115
-:109CE000D54DE36FD64593DCF978AC7713D24B8D25
-:109CF000FFA8FE616FFA0719E4C77FDE9282763A09
-:109D0000F02FCF4B2CE6F2E935BDEC43F8B5D27419
-:109D10008AFFAB727771018F972D56E3634561F12E
-:109D2000B1B0B80C2B1A395EC698538FFD4E626FD6
-:109D3000A9F8A178CCA92289E8EE03BA63BCF9940A
-:109D4000E2A7964672FFFCF73362899F62E66710CE
-:109D5000BFD9625980F6A3AC22F15B0FCBB1C484AA
-:109D6000C889FB9438EB6EB08758487CFDBEDC0692
-:109D700013E61BECB0F0738CF79745D486E6BBFF77
-:109D80006EB69EF0797B71E92BC83FD9167F19A971
-:109D90006DB724E37C04657E93ED807F1D36ED5125
-:109DA000E2A54E138F4F9593DE56E97EAD7AFB699F
-:109DB000C9BF2D02E71FC7681D5A3BCC244FC54EB3
-:109DC000770053AF27152F3D4CF4943C59D84F776B
-:109DD0007E04B340FD4FBB0DE4E79FD4ADFE1EE60D
-:109DE000C50FBC6964B8FFD9694D96506F747E7118
-:109DF0005D393DADB3E6321EEF8CD481A0C8B1B35E
-:109E0000277E844453CE9F750AAC9751DCCD1DA9A3
-:109E1000035FAC53C72E97C0B88E595C7BA711EB7C
-:109E200079449CE77B45DE9F225EF2593DC1F71BDA
-:109E30003CB507A0DFFB634CC42FF714794EF071DB
-:109E4000B2B68530BEE23902C3F3BC6D066E9F59CF
-:109E50009D117C6F8A713BDF339849FDFF429197DA
-:109E6000AD0E771F1E1C19156F766960283E427C67
-:109E70009742713D158FA1F4B2E76BE8E5D587D223
-:109E8000AB00E83525945E6EE1EBD0CB8F4966F1EF
-:109E9000C3F9D457263F589ECBF51BA6CA85F36954
-:109EA000A971B605F35CBA6DA20EE9D61D919C8D21
-:109EB000F139954F55BE1D815FB7F4A0DC4891EC98
-:109EC000B86F6CAC8CA07D18957F55BEB514F2FCB4
-:109ED0002DE0DF5585F05C69F154A06C09E75F8CDB
-:109EE0009385F269F5A8FCCCECA1EB7811D815515B
-:109EF00031680F9D3BD419C2A7D5F517252E57AE53
-:109F00009444E407E37A8B8A04F66E28BDE1DFBB54
-:109F100059CAFCC81E92C80F53F17AADF8D77FA377
-:109F2000390BEDBBED786E11F0D52E38DD8918EFC9
-:109F3000AA7FE70E7CDFA69C1BF6651BB8DDA5ACEF
-:109F40001BB5BD49C5655105B82F30E342E43AA8B9
-:109F5000F769824E46E4B4C9AB7F44EBF04C24C3AE
-:109F6000EF6CB17DB54FD0BA9AC870DFF0D3DBBCCF
-:109F700063711F7F27D0E95D4AB2F627EA688FAB8D
-:109F80003F11D71520D7C19F5E077FCF94723FC185
-:109F900087668E53F2ACDD4AFD7EAABFD3B0C714EC
-:109FA00081FDA49BEC0743F8BF4489BB5716A8E783
-:109FB000755A64B4D72A0BB85DB3B7E9C8ECF72774
-:109FC000E0783A67BF0FE3895DE8675EE0EB882CD5
-:109FD0009F8CA921A62FE70878AE815DC73A311E74
-:109FE0008FEF9BA704DB7715F07567423B06E867A8
-:109FF000DAE69343E5A849277847CA83393C53E218
-:10A00000DF6D63546E3AF5089DF38FCD700A980F9B
-:10A010006DDAB687E13E8D39C0DFC765B885352179
-:10A02000EDC62D847187F005F0972F0AE48FE920A3
-:10A0300030662ED22182E292E1FD2E8A2FEB956CC2
-:10A04000A3F34938BF3185DF54BE51E74927564253
-:10A05000CEEB978FE376725BA3E100E5A116441384
-:10A060007E3F892B8B6223D89FEA733FF081CF8894
-:10A070007EB3899E07C1EFF64D44BFD941F061F030
-:10A08000BBF17904FC6E7C3E0D7E37963F037E3734
-:10A09000C23F04BF1BE14EF0BB113E067E37C2C774
-:10A0A000C1EF46F8C7E077E3B30BFC6E7CFE0CFC17
-:10A0B0006E2C3F017E37C22546E00F9C4F96CFB1F4
-:10A0C00014E8DA7EB7C18D7984FB15BAF6B8C7C536
-:10A0D0003A81FEE62C1DC5C4CDBF7C88E17CCC0E48
-:10A0E0001D9D0BDBEE7888DD8AFE6CBE95ECA9B673
-:10A0F00067B99D6296F632943BFB055F2D73C2FBF8
-:10A10000AE926ADCDFCB706C298B01785757C53E65
-:10A1100013AC8F4C79C9F2E61058B6BA361CB507A5
-:10A12000E1B1D90724F058D89E8279FBF048108E0F
-:10A1300003F3871FED5A50DD0C2C1418C7C8DE1826
-:10A14000483750DECE1AA417C6230A783CF106D64B
-:10A15000E2C0FDCCB132784502D50FB0B86BAFBFCD
-:10A16000BF40A6F7E1DF5DAD9E2EF79AEA31F12AF6
-:10A17000ED61B97095764CC232531F8C7D975E911C
-:10A1800053F1169253ED18DF01BCB79BF9F3BF678B
-:10A190002A7ECECCB25533E1B96A26A76BBBD9670C
-:10A1A0002FC3FEA7E8289F8135A6FF7A1CF477D736
-:10A1B000BF4B0CF34155FE7C5EE1830963AD742E09
-:10A1C0009FDD63A2FDFCEBC73EDB1A03F084279CF6
-:10A1D0004ECC7BD8C59C11C827BEDD3ACA7BFC415A
-:10A1E000EEF89825507D72DEF33128D763677279D7
-:10A1F000E357F2859ADBD68DC578D4A7AF7379780B
-:10A200005AE9E780BEAF9EE89967213B04284FF6E4
-:10A2100046B303880D3A5397C49F06BD7D05D633D8
-:10A2200080618079D9862F6698D0DF6B1934CEE3B0
-:10A2300079B37D648718CC5E7B34BCDFE3D3915C5B
-:10A2400068912D94E7B6CBE2EAC573CE3EBB8EF2A1
-:10A25000617765EB088FAD969BFC68E74B42732DE9
-:10A26000EA31BFFD98291DDEFBB37594DFE8772F37
-:10A270009D87B0CF2B51FE15FD60B93786CE77EFA5
-:10A280006203AF4EC3F26A6E87B525FCF55424C64F
-:10A29000BF6FB43BF9760B93313F8C52C574E877AE
-:10A2A000F76F8BC4715431C59FF591FF6A3372FA11
-:10A2B0007DA77BBE7D1CD91921FB5A468CD5394D13
-:10A2C0004E289F6A71CD43FF52B2BA4C98F7D76AB5
-:10A2D00077996A68FE3C5F8DF232A0DD16BB8EFC7A
-:10A2E0005C2CBF359BD4E1E98C7C25155FC6793F9A
-:10A2F000D48DF890D632962EE3F8245FE8BEA1699B
-:10A300007C51AF0CF3685F1743F3900427C16CAD29
-:10A3100044E31E2347D0B9E6BD86CA5EB417C7988A
-:10A320006EA7FDADA45A49B3FF94E8D5C2F1CBB5F1
-:10A33000702C9382FB57D0AF7DA61A7FD3E22D1CE1
-:10A340001F49F6D6D771FC495E3A04396CFC8FD8A8
-:10A350001F8E2E65384E0B8D33C1B2BA14EDA67820
-:10A36000E66946FEFB47C739D5BED4940EFD4F8D36
-:10A37000D39179348D0D6CC3767729FCDE9ECEE9BE
-:10A38000195C5722CD0BD6E53C5C97631B75E0B09A
-:10A3900005DB4FF781E3A6D93F88D1C013F68CD1F6
-:10A3A000D49FD8314E533EC97F9DA67CF2119706AB
-:10A3B0009ED259A8A93FADAB4C03E7041668EA4FFB
-:10A3C000EF5DAA81F3FA5668EACF38B35A533EB329
-:10A3D0007F83A67CD6B9060D3C7BE05F34F555FB48
-:10A3E0003E5C3F96CDFCFBEC7AA3638CE67E9B70D3
-:10A3F000BF21DCEE377DD9226F437EB619889F25B9
-:10A40000D4E7B8DF7C37F78F4CC54E19E54B81C2D6
-:10A410008F9F15BB1723DD4A6D26D20B9285D793EC
-:10A420002C73C95E49EB30D0BD3B929D0D9547A280
-:10A430007C6EF2CDCE98101CB7D9BE87EEAF28B592
-:10A44000CD63988FA47E2FD9DDCC6BC5FE64EACF97
-:10A4500064F7513DB30CDF87CCE3A44EC72C28C76B
-:10A46000C18F43FF6034BF4DF5D7543F6D34FF4C6F
-:10A47000F5CBD2742C029F0784FE3BD07FCFAE7FFA
-:10A48000BD2C9191FFB605E77D3F9EDB46BF6D2A4F
-:10A49000B7B3DA1216C818CF694FEFEC1D87E389FE
-:10A4A000D751BC14EC66E7D2107BF1B199DC0E9564
-:10A4B000C6B5F7A3FE6B8836C9682F49A603B3DF7C
-:10A4C000077CEDD7F73F85F18956C1BEB113E5E2B0
-:10A4D000DD16CA03D9ABE04DB6EAA66F83763B9B87
-:10A4E000DD129ECFEFDCC99CADB83EE24AB745C352
-:10A4F000FB0929353A0C034DCC68DE86CFFB67F2A9
-:10A500007D9F49D90774B1503E39B77439C6BD44EF
-:10A510003BF4779538B468EB60381F96219D45BEB3
-:10A5200042EBFE0A0CBD34C644FB9266A4B7404F12
-:10A53000C28379D0E237239CC1F162760BFE488159
-:10A54000DBAD9847571AD341F455ED59B473B1FDBB
-:10A550007B8ABC8F213EE3166AE92A990E113E766A
-:10A5600029FB12EDD1F22F513FB7A767C4E07E96C9
-:10A570003A4E55AE1C56EC7BF5BD2A571C986B9392
-:10A5800017B46F80CF3B30FE6696F6D0B94CF3BD62
-:10A590007B18F2B5194FB193BDEF933DA43F3C9AA0
-:10A5A0003CB4F271CB4DA8AF2FC7B9C89E3537FE6A
-:10A5B00098C6178E37733FCF471B0DAFB6CC4749B0
-:10A5C000BF830096F13CCFA9044B6D68DC537DBA84
-:10A5D0000BB8DDA257F386C093407D7659CD4B7200
-:10A5E00047F2F14573B82773058DEF8E7857E2D5A2
-:10A5F000EC6D33F89BDE10BAEF943C26C443DBE7E6
-:10A600004BE6D1BC255A0C6CD717D907289EACF85D
-:10A610004B6EC53EA9445F0C9E69067E8EC019B77D
-:10A6200090EE3353E3209766F2FC45A78F893C8E6A
-:10A630003794B7AEBB328DC62A1B54BD4BA62CD760
-:10A6400053F07F37E6AB8C6F97B479EE8A1E57F5DF
-:10A65000F4843DDAF2891D5A78927FD8F7FF897A1F
-:10A66000FE46FE3BE8016DF9A38ABEBE11F535EE4C
-:10A67000677D83E78B98604457B89E0DEA3D900351
-:10A68000A99D8152149B295B254D9EC998307D78E8
-:10A690004F914C78F0F44A7AD4B36A9C265C0E0B46
-:10A6A000F75CD882EBA534325246F989710CAF9130
-:10A6B000FBE55EF053EE979CBFAB46BFAA57A43CA8
-:10A6C0002A954EE174AD2D14147DEA110BC93FEEAD
-:10A6D0009F8EFE3AF6E70DE94F8DB79C2FF69A3123
-:10A6E000BEA1C65D2ECD935E12E4601C458D0BAC01
-:10A6F00052D6CF2EE71BF53D308E9E33468A8154CD
-:10A7000088BFEC6DC23CA95489E4977DC6C6EFA111
-:10A71000FF5DF67B28C778A22C27925DDEABA738B9
-:10A720004099C2C7658ABFA5C65BD20B399FA72ACD
-:10A730004FF82282FBF58108B45F271F01D9ABA532
-:10A7400067242FE771B6299DE1E56ECA5FBA4EE135
-:10A7500017CC3B2B4DC0742F0E773221D60E749C34
-:10A76000B6BCFF14BA0ED9AFBC14817C78D4CCED42
-:10A77000B5A7157E48608213F3F3138E589C7EA80C
-:10A780006715D9D13E9887F3B4A4C9339B7A420B9D
-:10A7900067B310381DC7A18577CBF5B8F5CC7657D0
-:10A7A000834D0E539E59A8E46567B24CE4AF0AD1BD
-:10A7B0009283FE5343A985215E8DEF4CFCB73E94F6
-:10A7C00017AFF37BABEC91F283E5F0BDFDD5586795
-:10A7D000B31CA4FFD3E047A37EF8EE15276BD50783
-:10A7E000E35ACF003D33687FD94EE59D4057848FB3
-:10A7F000815F9D41FBCB59F4FEC7E05723DC057E0A
-:10A80000353E7F067E35BE3F017E35C2B71797DEE7
-:10A8100084FCF216D443BE88C8396E1A8F716E8BD1
-:10A8200048E76EC2F97147FD7B969B4156153BC6C2
-:10A830002E8C477ED82AD2F9E49B0AC72EC4F3DBBC
-:10A84000A171B5D0386330AED62FA8713523D0E7CB
-:10A85000F20C59C95F50E26B5E1E5FFBEA76DC6A60
-:10A860003B14BF1CD6CE501CD3E47B3F0B8F6C092E
-:10A870002C0ADE7F74F77F1D463D9398E4ADC579C1
-:10A88000D7E5BD6BE076373F4F95A2ACA37D669EC2
-:10A890004F9AA2E40185C72F8BE7BC73473CA0EC1D
-:10A8A0009E9FCD5E89FE7FF1EDEF4C4F03F854E1A2
-:10A8B000532B31FFB7F8FBEF3C970C78CA9AB58160
-:10A8C000C37BDFB99CE2C43C8C875762FEAF2D96F8
-:10A8D000EBB77DCAB9A421BDA7AC97CD8D4F901E13
-:10A8E000073B83213E5A123CA45F3F8E1BB0D540EC
-:10A8F000FDCDF10309ABAFA20F36371EA6EFF70966
-:10A90000CE737E1CF74C13CF3B55F4CD2585775580
-:10A910007DD360E6A03A1ED0B0F47EAF120762EE9F
-:10A9200064FA2ED6CCE11E5B21E9A507CAE45FC913
-:10A930007CDF92FCE31EDB75DFC1BCBA967912EDB9
-:10A9400027EEB5B8CCA8B79E53E418B4EFA3FC9596
-:10A950000A13EDF3B0B8E5B4AE63D47EE2AA291FC2
-:10A96000214619CFE9C28800C6075ACA4D07518E41
-:10A970003E641947EDB514187C189751E16D853088
-:10A980001EC067B42D261D6155CEA9716386BB6AB2
-:10A99000D06E9932ED3235CFC1A4BF106A5F5B58DB
-:10A9A0001FF18F53278B681FBA67C9448FE9CCB951
-:10A9B0001CDF1B847A1F3223CE43173A0FB95C3B4E
-:10A9C0000FB942330FA1C11440BBB0A502E601F597
-:10A9D0004F5BF369BCE17453E7F3FD42CECFE1F383
-:10A9E00064CA7E927A7EA0CC5E741CC755A173B7F0
-:10A9F000E2B85EFAAC3A0E2F929CCBEA257C3F3E41
-:10AA000098CFD3FA75F2258ADF13F8FED7ED069AB0
-:10AA1000DF2BB3F9781E35F8D3E96087E44FC27DA8
-:10AA2000DFD1F8F84F0ABD837CEC66B8BE5A62DC11
-:10AA30009C8FED03B666E4E3E881846D34AFC08893
-:10AA4000F409E7E7707A0DE05D09E447FB44C4FFD1
-:10AA500057D157A56BF83E98CA2FEE597695DE0E62
-:10AA60009A67204DB34F082DC823ED8F6F87F6E40A
-:10AA700090FD3483C34376B63ECE9985F1E6962F9A
-:10AA8000C511CF4DCAB3F87A6FB64590FDDD62E3CC
-:10AA9000F677B76D81C66F2A073F0AF791C558D67A
-:10AAA00089EB4A8C5A41713431112D2F620BAD5D07
-:10AAB0001BB590DBB576D755CF4F49FDA2E65EB505
-:10AAC00061766DCC026ED7DA0C64D7EEB31A961F9E
-:10AAD0001841EE0C16723BBD1BE73182DF08FE22E7
-:10AAE000C533557FD160F792DFA7CE7350E177B5BC
-:10AAF000BED15ECF30BE261A9C32DAB1A272BE152C
-:10AB0000F39AB342EC02B5FFCBCAFECEDBC5FC3CE8
-:10AB1000849ADF5EFC2BA17E24BCE7CC52ED92919F
-:10AB2000F9EE1FE01B92132E8BC18D7687CBE2A02E
-:10AB30003CF0D1BEC32DEC73314139E3FC325F24CC
-:10AB40007D243929AFBF53DFFFDCAFD01F7CC94262
-:10AB50007AA7D39A52166A9783D14AF9C9E0FFFAC5
-:10AB6000B2A0B1A37F8315A90BFABDE087DD302B1E
-:10AB7000645FF254C359DA070AB757C3E30A43EBD9
-:10AB8000DD76389D8FC79F84EB5768284844BE0AFE
-:10AB90005FEFEA33D531FDBA3530AED4A41C7AAAC2
-:10ABA000EF1F67E2BC91EE4F5B3D4407AEA7274124
-:10ABB000675122E9E7D538EE8FB6BE91E094F19C5B
-:10ABC000ED45D2D397EA0BA27620BF67C5907C4DA6
-:10ABD00051CE8FA9E349B9AD3B3AC682797C039344
-:10ABE00030FFCDDFE4B9AE5C4F7E867BA4F13E3012
-:10ABF0004B89C305C6B2D0FB81E4B8BEF91301EF9F
-:10AC0000B245E794697DD949FFA972A0548A2EB74D
-:10AC1000039FA73631A745C6AB93ED14174BBD2252
-:10AC200012BFA5F6F0FB9DC7C60D0878FFD0503FB8
-:10AC30004A9E93BABFF2497D39ADCFD444C6FA28B3
-:10AC40007EE9A17D884FE2024B707D7FF2301F517B
-:10AC5000EA13DA72D0B914B75EB735C22F43D363A3
-:10AC6000EF85F1E178BE27B094741C474FFA0E8C43
-:10AC7000FBFC2492E23E624706C56D6E4BF2DE4558
-:10AC800078F5CB77E9C62B93857A75DF8AA0FB042C
-:10AC9000F6097DF3299FE24E1D7B7284B8D4BFCEA6
-:10ACA000E2EBFCBBB3F83A4B75E4737A3B72AF5BF3
-:10ACB000137BEDEBE914CA6D18C7AE283FEDD3A99D
-:10ACC0007961BBF523F3152BE27EEA903C56F067E1
-:10ACD000422F08F8451414BBEFC8D34F3F9DC0F86E
-:10ACE00011C3717C3F3274DF3822C34F85114E3758
-:10ACF000C91FC1EEE672D65EEFF0017FEFF8421C8D
-:10AD0000B1FFD715FA35A7DEE5C0FAE5B2939EDDAF
-:10AD1000A9F9676A007F168B811943E4B0CA27E15D
-:10AD20007ABEC13AEEAA7EBC01E4B17C953883417B
-:10AD3000C9FFDA7E6AA609EF0FDD6E71F5A1FDB5D8
-:10AD4000DD12E7A238BC05E446485CCA627999F88E
-:10AD5000D0E2E4F13A0BCA5F8C4BE1FCB371FC2FFB
-:10AD6000D3FCD57ACF2A72C8E20CD07EA9D9B98794
-:10AD7000EA99240F9D9F33C531CA6730D9F9BDA325
-:10AD800011193A661A411E1F9EC5FDC0EDD9AEBE0F
-:10AD9000321A9F84C7AAD87687CB41FA10F10CDF0C
-:10ADA000F758F3A342F1F39E220F5ABAF9FC3C8DF7
-:10ADB00049F6723C6753ECF9AF5979D8CE6A13DE85
-:10ADC00073275A73AFDACE8561ED3C92501E4BED7E
-:10ADD000BC87ED8856971DDBD12BF7A786E3F933A7
-:10ADE00085DE7F6F3C0D3048793C8417224C404310
-:10ADF00097F0A705E362B1237DC7E562BAE2BF80A1
-:10AE00005CD417C1BCEAB2DF7D99AF31EEB7C4CCD8
-:10AE1000E779429780B3F1DEAAF0FC8B703B46D510
-:10AE20003FAA3E8276446CE751B4632606D7911A56
-:10AE3000CF49AEF5F0F512E7217E01BB46C6F522FB
-:10AE40002A797EE1F3B9A188E35FB015C8A82FCABB
-:10AE50003FEF4FC6EF4E5ACF25733B56BBCF7CFA20
-:10AE6000B3C3662CFFA4B6ECAAF68ABAAF3CDA7E6E
-:10AE7000B2ED5F3EDC126AAF8CB6BFFC55FBCAA7D1
-:10AE80006C068ADFED17B4E7E32B8AB8FC7317A9C9
-:10AE90007119EF8C228C430A1E273FF0CCE3339FBD
-:10AEA000157B0B914E69ED06E603BA9EFC2CDFE1A3
-:10AEB0000D69E75AF1ACC6E1C728F6D418CB610199
-:10AEC000D7E9985ABF8071F4E4DA4EC17D957AB122
-:10AED000455C8FABF5F54AFB25D28088FAAAC4CE33
-:10AEE000F562F2A0C4B242E48EAD88AF5FBD62BF2E
-:10AEF000DB4E3D65C6F64EE93CED99A81F6C3AF96C
-:10AF0000C990F5AEBFCD652A0B995F0BEE0F8D4052
-:10AF1000C74D45AA1E0C90FE56F5AD5ED513719235
-:10AF2000464F6C8EE47CACDA3B9B0BB93FB4399254
-:10AF3000FBE5AF3ABCEB11FF1F177EB868BC8CE78E
-:10AF4000643B0DB89FFE55FB2443F68DCE5FA3FAFC
-:10AF500033C8FF4EC9FEF37EF83EE7FBA564EFE57C
-:10AF6000E18D23226ECD72FB0FECA93B8BE2F9D56C
-:10AF7000FCA1F46661F70B8E361F2FDE6B9A87F10A
-:10AF8000BF3E8ACFDEFFB930E27988AE22D52E1AD5
-:10AF9000DA0FD4C4599315FD96AC94CB18674DC7FE
-:10AFA000FD2D6D1C747AAF16CEEBD3C233CE84C5A3
-:10AFB000557DEEDFE0793FCC1FC046F7C13A4339FB
-:10AFC000B146D9F74CF1F94BF19C782AEBA4FDC5B9
-:10AFD000E4DA180D5E8B4525EF02AF3956C7093FFD
-:10AFE000C952E579FCFED921FAFB9826BFBF7CCD7A
-:10AFF0005D782526DBC3CFF999A073C4D7FAF94B46
-:10B000002B90AEC3E2B5F5DA386D726839E061DDD8
-:10B010003EED79418F3B87FC8165DFD09E1B54F369
-:10B02000D271BEC9AEE1FD7F75BFF02F6678FF6AB1
-:10B03000BB8F82FC21F9AADC279C8A45D88E14108C
-:10B04000709F7B4C3DA37B8593B732F748FB057F10
-:10B0500054F0158E67E62B21FCCD51DE8DB1F07CCE
-:10B06000D5315B75640F8E01B9407F6F6023C800D6
-:10B07000809337CA644F2EAED531D40FECF326CD72
-:10B08000F7305C8AA7AA747FD4C2F37153EB985F40
-:10B0900087F3A9BF8ED6138D6B5C901F005F9A7BE0
-:10B0A00005161768CFEBA6869DD355F92039ECBD60
-:10B0B000AFC8AE5917A0E7FE58447CC2F5DF04D4F0
-:10B0C0007F30A48F669E398CF975C5DB18BFD726F3
-:10B0D0003A82DF6B13DC8F10AF00BF9E32CDC942C6
-:10B0E0007B65973D4287790F27A3FB1F63D18C5D5A
-:10B0F0002C62BEF222BCEF7060B200F017275AF744
-:10B10000B7CF8672F3C00F30986CD9BDEB9679A992
-:10B1100041D8F6C0F70866054CC67B8130E714D7E6
-:10B120005D847DC111BCEF3A22DB42C1C908A6BDD6
-:10B130007FA7B550DE8D7923AD1374CA39E99072BB
-:10B1400098C786D9EAB97F37E5DFB1793C0F20B4DB
-:10B150007DCCCF1EB5FD05D07EEED768DFC4C79F7E
-:10B1600080AF40CF24E0F8310E8EED237D3168149E
-:10B17000DABFD29EC47C0770FF06FAB308BC3F3B1F
-:10B18000E6A524306D1EC2507F76E86FCAFFC17CF1
-:10B19000960FA787FE6AF458F1F5E8D1AA73D37821
-:10B1A0007D532DE407E13D56785F9D59E9CFACDC36
-:10B1B000DB85786DCD0FE215EC406A17AA375F5139
-:10B1C000F08C7986097603E17934BC9DB2F3BCA892
-:10B1D0009DF6087F73FAFF077A3938BD42FB437B3F
-:10B1E000F29AFB5B01FDC55D7B7F885F5C3F43F8A6
-:10B1F000059A6C4BB876FCC2A87CD782DF53D0AEE0
-:10B200002E04AFC1FCA347ECE81798F51E13E663C4
-:10B210007E6B7634C9EBECB8A526CA47885F4AF93D
-:10B22000C56DD916CA876FCBF886491FA2A7DBB2B6
-:10B23000ABA91CEA53DE54762002C3146C0AEBA3BC
-:10B2400038C0CEA27207FA85BE7A9E87A5E625A9E8
-:10B25000FA9029FB9F342FF8306AF6F18153507F22
-:10B26000677D2EE59D4545FF95F2AD76D53A9D5813
-:10B27000FE9899EF637E57D9C74246A578DAD4C2C3
-:10B2800027703FD735A141A0FDCB8D57DFBF745D3F
-:10B29000EC2BC3BC2D56C3F3B21CD552983ED4AE92
-:10B2A000DB5D88579E3FE517387E35ED3D3B3B9E85
-:10B2B000F0B633E320C3BF3BF41CB4256AD7970E26
-:10B2C000F398C2D7A36470D33D63AC4147E348C64B
-:10B2D000D4005071AE290B1D35F03E65AD44F7F931
-:10B2E0002666DF4BF94C60E593BD919DFDCB328422
-:10B2F00087CD738D761EE1F30A1FB77ACFB14A2F3F
-:10B30000D7456724FA57AE094B29DF8C7ED4F52E3A
-:10B3100086CD07EC61739C8EEE838BC8089917D39A
-:10B32000D453FCB77F2EFC18E82A5A47E1FB62FF92
-:10B330008F9F1B3232A7C940DFA9E76CF87EDB186C
-:10B340005C3B48F734C6F3BEC3BFCFE7DF3307DF4C
-:10B350007F334630139EB3113644501CD368041813
-:10B36000CFE128F78D3DAAC4DB9A052625B942FB1B
-:10B370000B50DEBC68BA2103FD8653A665763ADF22
-:10B38000A6F851FA680FE52DB2AC188D3F7A4A390C
-:10B39000A7D6705B7A22C6EFA2A0AC0FFD6AC9697E
-:10B3A000427AAB7113DBF8FE6FA21E3F3B5BBFCA54
-:10B3B000847A1B9DE042C62EBF70653FDE33ACAE83
-:10B3C0004FE320BFAF630896EA292FC43898A679C7
-:10B3D0001F50FC301576C749E5141F2A9609CFA5E2
-:10B3E000CCDE8ADF95027234F70328F77F0C6F3FBB
-:10B3F00045F33E00FE75E8BEC0E8ED476AEE193041
-:10B4000082BF3372FB9961EDDB476C3FD86EACA60F
-:10B41000DD3689CB0D5F5C847FA4F81EE6FF17C77D
-:10B420008F9EB79655ACE4DB9B40A2E13E94C23FB1
-:10B430003B1CF594C72646F07D533D8811E4A71EBA
-:10B440006B2DCFBF48D1E6B1A9F78BB4E1BD215038
-:10B450005E66D1DAEBA56CA0679A807EAAD65E2FD5
-:10B4600046498AFB532CDC8EAFA77D527D8A562E2F
-:10B47000F4E07A81F9E8ACB97D94F7166FA1BC8647
-:10B48000D1E20B6F3531CAC7D2477AEA51E7959EB0
-:10B490004C1ADB56007014E7B3C527A7AEC2B8D16B
-:10B4A0005B0A3FB7811CA073A40D8907C49076ABDB
-:10B4B0000D8109A857AA75FC1C00FD40FF6FC58FC0
-:10B4C000A1386B78BFEAFD312ABCB25E989D11327B
-:10B4D000BFB794F531D4DF1DC907D0AE1DEACF1830
-:10B4E000C8A3FE86F28A94FE12FEBEFEFEA0AC6FDA
-:10B4F000B5BF957769E7B7D2D047F35BA9DC5BAA04
-:10B50000F6F7079C5FFADFD19F920F36D4DFB7B40E
-:10B51000F35B69ECA3F9AD1CF22F95FE12FEBEFEA3
-:10B52000D47C07A3B1BE16F969B4BC0735DFA1D03E
-:10B5300091AAC97700CF6661A9C4D88302E78BEFCF
-:10B5400014CFFA1EF2C5E5850D4EB253147F8FCE8F
-:10B550000789743E88F4E8E2146E87A8ED1F692A13
-:10B5600060EE893C1E84CFAC2281CE1F4C2A10DCB9
-:10B57000B8CFB60FE407DE83B71FD63996FB9B1C06
-:10B58000F43CD824D3F310F8976E8A7F39090E144F
-:10B59000737FF1C1247BD51AB43F4A2378FE75D15D
-:10B5A0002CB06C83FE1BAC975366CC73BC89E5E072
-:10B5B00039B4CC0E8ECFB8F204BAF73E22E7745FEE
-:10B5C00013C03B0A4419F3CA77C823C7737E5ECC05
-:10B5D000E3443B94BC491F9E9724A502FE24CC7FE4
-:10B5E00095422A262EA4F3368BBF154DF64DF5371E
-:10B5F000FAAD7618C72D42CE6F32001F7F54EC9BF8
-:10B6000055690B481E84FBA771A8A972319F50F49D
-:10B61000FBE1D765D665E4DF2EBB91B118F87E312A
-:10B620007E077AEA578A7DF45ABF91A1FFE72BE79C
-:10B63000FBD7B7DCABF54B1F3407EC68173E98130C
-:10B64000C7901ED55BB5E53B0C7CBD2D0BF35317A6
-:10B6500087E5FDA8F720EEC05F6732D655ACDCFF6A
-:10B66000A2E4FDDC85721EE338293194E4AD9ED35B
-:10B67000341AD988FB926A7BBF53E4168B73131E6E
-:10B68000D43C39263E9383DFABFDA9DF3D2A3C93B2
-:10B6900074B5B829D88167FBB3B8BE477BFD3F8A34
-:10B6A000B5F94997178EFB4E391B896F07248C53C8
-:10B6B000A8E3FFDFE2D71DC57CBEBF9AF3492E3F4A
-:10B6C0006797C242CFD7A9F95FCB866089EE15563E
-:10B6D000F3FF9863201BE9FD9FB3239DF711FF291A
-:10B6E000F648E04DDD95C8AFDFDED0381CEE54CD16
-:10B6F000F955A5BDD1F03CDABD13F413921FD9D290
-:10B70000EC74D079BA78BECF3626AEEC3C9EDFC260
-:10B71000F27735FCA53DA7D5D2FD94807ECB63782A
-:10B72000BE4D1FEC17E3C06D166CD7CFE34A81A75F
-:10B7300028FE9B521B105AB383E781C2E562CA46BA
-:10B74000ED79B3F0FB142B2DFD922063BC7F80CEEE
-:10B7500031CE2FE1F4A23B3BB05E3CB727C5641D60
-:10B76000CF17192B73FB3263202D74BF636A899244
-:10B77000671AF9C65619446F46C943AB306FAA32EF
-:10B78000EA8DADE9288A4BF6AEC23CA9CAE4373E41
-:10B790004907793BA9E4610E4F7EE39371004F2E78
-:10B7A000F9570ECF6284A42925DF5D85FBAA534B90
-:10B7B00094FB95581F9DDB4E4CE27CF4F73E45A36D
-:10B7C0006EC47539A3448D5B323AA7ED39F18B33E2
-:10B7D00028A73C6A9CD7ADDDDF64CAFD8937A8EC99
-:10B7E0001567237B6901FE0EF8BC41B97747670AEC
-:10B7F000105E2706EF3579F8EBDCBB133C27CFEF63
-:10B80000116A69645EEDFD886E85FF79DE903A1EEF
-:10B81000B5FF61E3C2FB016342C7B58FDA51C7F5DB
-:10B82000718ED1274C0BEED7AAE3FA5818D88F4166
-:10B830008F033D7D3548D78FAD0369F8774E60990A
-:10B8400079098E1FD82F3843603DA7E3CA921F9114
-:10B850003D559CE45E5982F97B067E7F41BB624781
-:10B86000EE8AF7FAD0AF077EA3BC4D5F2A3FC750E0
-:10B870009EABFD7B6CEB4BB85DFA27E55961DC5361
-:10B88000FF7A2EDEA72EB066A8BFF9F3CB06F4FB35
-:10B890002B4FF0BFD7BAE9F83B06F4DF37210CEDA8
-:10B8A0006CDA6718F1EFC17D888709F8FAD5F82BB3
-:10B8B0002FA566B6C5C17836ADE1F76437FC34BA5A
-:10B8C00002E1861A9A255B5174B4023F5BE9E96E86
-:10B8D000C3E72AD6FF12EE4B5479B57EC4376BB559
-:10B8E00076FFCA7AADBDBE6A0F5007F4DAAAC6E485
-:10B8F000B0FBFCF83D81550A3DAB1CBBFBF0FE8163
-:10B900002A16764FA08FC791BEC967004F6D7CA4E1
-:10B9100012FFAE14CE63A34871DE9752B74B78FE88
-:10B920006D733DBF9FACA2EBA281CAA11EEE2B2579
-:10B930008CE1F7E1A9F253D5EFDF7CE1801EE3054E
-:10B94000E1F705AE5A3E8FEE055F2E6FE0FA7DEC13
-:10B950006F2B62E07DF83D80D55D5CBF57370A7E76
-:10B96000BC77F79BB55A7F6025EB6B437F6665BD5F
-:10B97000F6FDAA462D7CA444D1BF93D9645C1FCFA9
-:10B98000960812AD1705BE90FADBD702C83F499E54
-:10B990004EE4B78D86C054D473E5495E82D5727883
-:10B9A000BF89EB21AEFF75B09248FEEA79DCC25741
-:10B9B000C7EF67FBE6307B20C45E1087C3EFA9F2B8
-:10B9C000D3ECD94A7ED80B02FD7DF072C92DC58417
-:10B9D000F8C9E17CF8BE223F5F63FDD938AE4C6404
-:10B9E0003AA04BE632FEF79F335FACA1BCCACCE96C
-:10B9F000825347EB58C71AF15E3190172817D0FED3
-:10BA0000C4FB3232C5CEE524A7A719ECFCDE1D0726
-:10BA10000B5DFFEEA79880F9823874DAC74DE9A56F
-:10BA20007B371675ECBE88722E63BCDBF5208C6FFD
-:10BA30009772AFF6AE9F0A64CF6ECA7E99E4612218
-:10BA4000B005F6BBC9A1C8C52EED7D188928A7F0A1
-:10BA500000CBC26CEA3749DD7F50F37A036574BFCF
-:10BA600054A2D2EF971532FF7B7B1B3A059C772AB5
-:10BA7000F335631CEAD7280BE3834F759FE0C6E0DC
-:10BA80003EF97AA4679DA39FEE8751F7C947A8B7EF
-:10BA9000A5247E78BDD1E4EFFFF5F37F007E0B583F
-:10BAA000CA008000000000001F8B0800000000009A
-:10BAB000000BED5A7B7054559AFF4EF7ED4E7712FE
-:10BAC0004227813C0C819BD72C90109B8420E8EE70
-:10BAD00078BB3BC984D7D8E1310642A49909BB5150
-:10BAE00092741474A3656D1A616207DD2AA1D045B2
-:10BAF000CB3F1A4A5CA756778366B1D186ED80A109
-:10BB000050519B151D184B2AB0AC23C50089382E07
-:10BB1000CEB0C37EDF39F7D27D3B378A535356ED23
-:10BB2000EC26953A39F73CEE39DFFBFB7D171430F4
-:10BB3000C15C80071C002003D499AF650C5760FFDF
-:10BB400040492E607B9D7EEE1CDB9A6D26906DC079
-:10BB50007FAEE39FC5910AF2F4787FD1F46C5D7FEC
-:10BB600089B34037FFAE7925BAF146A55C37BEAC44
-:10BB7000A15AD75FE1BD4337FFEE268FAE9F92B744
-:10BB80005037DF2E2FD5F5D3A6AFD2CD9FE0FCA93D
-:10BB90006E1C26F5E7792700586D81611FD221C8F8
-:10BBA00000E665E1BED6F4209B08509E8193B14D1E
-:10BBB000ADB6A7531B9C9D126519D8DE925149FD65
-:10BBC00094B71FCC8BE236B6892FDB5CD8FE130B03
-:10BBD000B9B3710F2493AF1FE938F351504209F400
-:10BBE000FC3B8F09A026DECE517C77BAB0AD7849F8
-:10BBF0002E408EE04F6CA67716AE4FC57FE7E0DF94
-:10BC00003E5B684F11C0ADB827CC8FEF03F5AEF99E
-:10BC10000AAD7B54590093B01F064719CEDB6D0562
-:10BC200085FA817D56BEAE223C6C52D2E3EB86147F
-:10BC3000C6DFFBB4D7BD80F6EF8C3007E0BCCE9DED
-:10BC400067AD7205F50733146C2BBD67AD909EF898
-:10BC5000FC8C959E774A23A90E6CFFA5DFDC103281
-:10BC6000909307152BDFFF4821B6788E9607CDA15C
-:10BC7000143A3B288B5D286F4D20E4AD65EF48D426
-:10BC80008CEF6FE960CE003E6A92EF5B0C4857F094
-:10BC900059CE0E23C96DF87BBD18CF999FB11B6E8D
-:10BCA000E5EB017200D608D6C1AA79510BD1ABB928
-:10BCB0004DCCD7F8B96679FD795689FB76253D9F3D
-:10BCC000D23B6ACEA0F5D2D9614D1EF0DE3F53269D
-:10BCD0004CFA2C0D3BE55071BD04E0A4D76478AF5D
-:10BCE000CD1E0960328EFB3C9CDE4F23DDCC8CE800
-:10BCF000984C2741BF6FA3CF2BC4EB043E25CF0B3D
-:10BD00007A049F5E61D0D49F3E76FC5DE2239E67FD
-:10BD1000378B558119C0EF4DE572DA6C5BBBFE5C69
-:10BD200035D1FFAB5E46F4FF570629B8FF27836F76
-:10BD3000E7C824E77B877286713F7FFF500EA09C87
-:10BD4000B55BE44DD2242E07CE4DC897CE70949F9C
-:10BD5000BFA3BF7A909E778499D38E47F50F8CD678
-:10BD6000F37BC270AF239DDE6B7CAE6D8A899FEB47
-:10BD70007945E6E7F7FBF09D93687D4A28C488EF94
-:10BD8000C3562E17FB193C85FDDD7DB6A690C13E3E
-:10BD90007F4FF4C6F56FF55941423969C7F5748F85
-:10BDA000238547AC36929BBD782F46F738BE228D4F
-:10BDB000F6DF680199C5CF77B130769AEE7FAAD5C4
-:10BDC00002017CBEB9D5CCE97D6AA399EF635EF729
-:10BDD0009FBD05D85F89F29782473DDC7AE548012F
-:10BDE000EE7BAA0DFB785FCF3A0BD7BF95F7333EBA
-:10BDF0003F597E35797D4E95CF953EBDBC25CBEB29
-:10BE000018396DFB6E721A8ECB69E57533E77B5D71
-:10BE10002EC9CFC3E0DC43FA73EDB02517CF5BDC4E
-:10BE2000EB703E86FD59E6D0CF73C82E1C16E3B3E7
-:10BE3000DB7731615FE45574AF82A015B63292238F
-:10BE4000C1AF77895F93E96A232C8DF4558A1593E6
-:10BE50001DC2572BC4E7572DD0B4B7829E0BFB32BF
-:10BE6000EBF5BC5D5B13E4F611551E35BB576E0553
-:10BE7000DFDE749ADF7F4B23EEF30AAEA7E753D5DC
-:10BE8000FDCA4A46EA1BB1BDA0083BF8917A0EAD47
-:10BE9000FF0F1EB11FB4A396211D97D804DD17769E
-:10BEA0004757D33DE64EF17D42F66FF1D48FDB016B
-:10BEB000ED44B0F89D0A1F9D0F9C269AEF57E97E2E
-:10BEC00078FEAF9FDF80F7B5CF48E57C6D3CF46C22
-:10BED0008CF8DC592A01F1DD5E3627D767207F5ABE
-:10BEE000EBBF5A04BEEC78BF33325AAF18E8F57690
-:10BEF000F5BCB3ACE2FE104122E5737B2CCDAB8ADE
-:10BF0000CFD3EE0FF018BFA7BDEC05CEA70DF7C33A
-:10BF10006C333FF136BE4F73FB71B616F7B9DBA237
-:10BF200058D291CE1F4F6C5A7FAE0CE09D1E3491BB
-:10BF30007891633D36F0FD05C0FB3D0EDE8FF5E4E4
-:10BF4000F1FEBFF7C8BC9D31D5FB0705F759F15687
-:10BF50005719D1EB70E1335E37BEE7F2310BA7031F
-:10BF6000809BD369832A7B572266B0E1F89501163E
-:10BF700002163FFF3D570BC087F6E457F43E5CD8EE
-:10BF8000D1FD21B773CEB6D17A399DE4EA4C2FF5B5
-:10BF9000FDDDBFADA7B8E134FA09922F7F98411EAD
-:10BFA000EEB3FA6A365FDF113E6E95490E4C23F50B
-:10BFB00044FFC041062497FEAE516E3F9FC77B29C8
-:10BFC00078EE1FBA32F9FDFD91D926C1CF39224E44
-:10BFD00051F93F38F3771964BF6CDDF20777101F12
-:10BFE0008F9A391FB7BA47321C067C3989FB428ABF
-:10BFF000383FB5C9E34DD6409913D735A9729B3C5C
-:10C000007EBB4BC82552D8427102FD30A4DB6A5575
-:10C01000BE5AF02A13315E581D66D154D4DB96887F
-:10C02000E7BC446D1783B33A7B007056D367F3F8CF
-:10C03000F276B36D27ED5716EFAFF4E1A609714E16
-:10C04000735B1A39D184F707F83D520A4B737DDFD1
-:10C0500010DFF987315E437E75622024A3DC775CB4
-:10C060002DE7EDA5FD8FCBA427B6D49167C82FC0CF
-:10C070000F4C8E3DC8DF8E803EBE2953F5A0CC23E9
-:10C08000E8B6D4C5A4CFA673BB554EF7AECDF7AD79
-:10C0900070E1F3DF147E9C7188D4DB1AAD04E3E712
-:10C0A0009D80FED846FA84EF2D47FEBC6A70EE995B
-:10C0B0001EF72A8A9FA6C2535CBE01E59BE42AF9BB
-:10C0C0009EEB5CE25C9A3EAF3C74DE4AF1AE3F6CA4
-:10C0D000ACCF351ED73A3A4F1F4083919F2B57FD67
-:10C0E00073C74EC6E9E5DF99CDE97411767ADD288C
-:10C0F0009717F11CBB512E2F7BBD6999B8FEB2CFAB
-:10C100009B96951ED7FFCE9D697C5D5FE9D2ECB50D
-:10C11000D87F4495FB4B618F8DE87CCF4EA177DAB9
-:10C12000FB4E47576693FED45846AC4E1C9F1239BF
-:10C130009341715DCDFE65D9A47FE39DF33EB7B811
-:10C140007747F786F5E7B2853C98519FD6AB7ECC12
-:10C15000FF58D44AF45FDF0D5C7E07F77DD249FAC1
-:10C160007B2992E620BF77F1405A80ECFDE58329D8
-:10C1700021136ED54EF28EF6ECA265F8C73C7EDC3C
-:10C180006F7604709EFFE08567481FFDFB501B71B2
-:10C19000DFF591C747C9BFB547169C97A87DF9FB46
-:10C1A000D5878EEE87F87DB5FE851E9B4CF6F39203
-:10C1B00024ECC4FAF06B3C9E5D7FED4AA5B782EE9D
-:10C1C000F9FBB964CFFCFF76652ED931FF9B57E6AA
-:10C1D000D2B8FFF5B42EA3F8E4798F99D355F38F35
-:10C1E00045272425715E9DAA07455B9E6A2846FA6D
-:10C1F000D51C5FEE34CB09F25566F2D2FC9A8F6AF9
-:10C20000B3D725ACDB12931AE8F99CE3B569AD0905
-:10C210007279BBC7A2DA21D46AB43F2B551AAECCCF
-:10C220007B3266AEA4BE1450E308769DC7DB204B7C
-:10C23000C8E766FA0F55B12F26F17826D0660E951D
-:10C24000E17873CCA4D82B691CD725C41900DE452E
-:10C25000B388DFF74E766E95B9BF871EEA3F5C164E
-:10C26000227F0F01DB5069421CB432668AA6A0DC33
-:10C27000344552A2140FAD8C4967785F8D8F4E3BC9
-:10C280005EFD7931F0F8E85C629C83F1D0397DBCC9
-:10C290000413E8BC5ABCF431C55518CFB66C8C5A9F
-:10C2A000C85F619CA49BBFA6E947E7290F5BD3AD9C
-:10C2B0007F5E14934C4BF09E4568EE880C7DB11D5B
-:10C2C00036D20F2DCE247E0D18E8FB4FDD429F3570
-:10C2D0003DDA1233713E6C89B96DA5D836ABE303F4
-:10C2E0000E130470FF2D91657B186EB6E5DADD69DB
-:10C2F00044AF2D2796C263A4EF0EB7AD8CD65DFB7D
-:10C30000916D45455C3EC6D80FB7B08FF178C0D867
-:10C31000CF4D51DFFB7DF9BB3CF79F87BFC3BC7A94
-:10C320009A7B32CFAB9B293ED4F2EA643FA1D95F1E
-:10C330006DDFBB547A8FB5BFE779FC82F92FB7BFA9
-:10C3400077B9653E6F4AA4319BE7C5279667CBE96D
-:10C3500063F72F919CA6AC8AB1FB6BF19A3FA00CBE
-:10C36000D9288F51CC5C3FFDCB598851DFCB789CCD
-:10C37000ED5F6D09D1B8769ED872C6E7AD70B29008
-:10C380009DC5E33F2D3EBC313E07C78BE2F1A216AF
-:10C3900017C6BC8CE741CB150B1F9F31D557EFAEAD
-:10C3A000A1FBD9F9F39AF9625FB40343941FDDFD51
-:10C3B0001306DC0EA8F1A2269FC9F1E41791928919
-:10C3C000DF841B3DAFCAA5A65F5393F442F3538F9E
-:10C3D000B8047D3AC94F57939FFEDA4A7A305EDC43
-:10C3E0008D7E7A959BAF03BE7ECE4792D728EFBE57
-:10C3F000A8FAFFFB886FD84E89BDE5A2F316426C00
-:10C4000013E58BE3F9CF856A1C33DEF8232E91AF59
-:10C410007C9B1E3FADDEEFFBD2E36D6E71AEFFED98
-:10C420007A7C23FEB31ADF73A6C7F51CC96FAAB9BD
-:10C430002BE622BD7B17F54E1E3BEF2E2D9F944021
-:10C44000C79FA142AB89F21E7F9BC0018299F20770
-:10C450003C3F79DB0CB4CFFAABF93C4EBBEF6A261C
-:10C460006F83F920FCE883451CB7B9EFA5E31605F7
-:10C47000D7376F64B3090F6A6ED3DF273859E138B5
-:10C480005BE000E3F17230BFFF08E955604F894C73
-:10C49000FBB7D065090F69CB0C6D26FC82709C5BE5
-:10C4A000E9796A9C0EF89E0EF5F91D2ABE034971C2
-:10C4B000C09B83A738DEE31F6040FA6B8DA0FD2090
-:10C4C0007B7254E01D9D1161173EEFB6737BF2B98C
-:10C4D00024EEE1EF66A14D2C1E479C8F6CCB213DD5
-:10C4E0001B134F28184FE4C4E3898E173EE2F63041
-:10C4F000397EC81A10EFF1B79B4384C70C15CE657F
-:10C50000D4EFC07C3097E24459BEAB409C0B42DC78
-:10C51000AE283A9C64F72DC2EF7F71F43F781ED9A4
-:10C52000BC9F41368F3B9458694E3CEE58135CC813
-:10C53000FDBF1667AC997664A880F653E30C07FE3E
-:10C54000127E981C6774868F5B282F18134F24C5A2
-:10C55000119FB9F5B8E03449E0ACD322CC4178D290
-:10C5600034959EB7F5A5F2B8B8FED3D66CD2738DCC
-:10C570003F971A05BF2E9DFAD245EBE67E2A39C8B1
-:10C58000DEBE796AE38705A22FDB645AB7318DF2EC
-:10C59000904B9F3E9046F47C135B407D7DFDA464F0
-:10C5A000881F2E57ED11FAB7DF73FFF6A88A1B4BD1
-:10C5B000E8DF26C4F197E4751BD475414C3338EE9F
-:10C5C000B81FB8FC06F37D0B79FFD962D8C3711F81
-:10C5D00021AFAF45321D14EF95E365BBD14EFC731F
-:10C5E0002A6CB157913CFBDEE1FAF1AC89CB2FAE5E
-:10C5F0000F30EAEF95B9BF2BC7BFD538BFD28A67D6
-:10C60000A902F132D4B7992ADFF2310FFDCCC64529
-:10C6100068F975A453F994A35F131F2B5341A2FD2E
-:10C620009FB0F8B6CEC0254F0C4ACE4DB4467266C8
-:10C6300037E2BD9EB08BAD9ED88FF28AE742E9E625
-:10C64000E7EAAC387292D633D901AB717D675E7A76
-:10C6500094F033085B7E73432E510E18BDA752C869
-:10C660001BE5A30C14761DF9FB873A59D8859F78F2
-:10C6700081F2A0CDF3BA80F2CEDFD5811A07D902BC
-:10C68000E770FE0A5C31119FE7E6FB96505ED89199
-:10C69000376C1571C58895E28A55E47FB8BD15B829
-:10C6A0009D09E793BDDC3AFD552E6FCDF43C419FCB
-:10C6B0002111DF338FED3FEDD6F64B7EBF2CF2CE4E
-:10C6C000A4F7CFC9FC2287E72FFFFD5F19DC9F4548
-:10C6D000AE70BF73792405621CB71B163875C4C2CF
-:10C6E000F3F5CB98074D4EF067AFBB041D0E453CEC
-:10C6F0005C1E0762B56934FFB4FABCEFC4F2654B47
-:10C70000484E6292B38C9F52E4350331A946C40768
-:10C7100063E8F4D76E033AD952853D4F96CF1C5546
-:10C720003E733CE2DE9E53225FF16F14F50387AA4D
-:10C730006FFE2EC6EDCA91C21CA6E1C8B946F585AA
-:10C74000FD23DCCEB6DCCB9C0179FCFAC27635CF7A
-:10C7500048B6439DE1BD826FC9B86D433DB73B37D5
-:10C760008BDB0265C373E376FA7E8F6A5766091C1A
-:10C77000F7AADBC1EF9BD535DB950BF1FB1BD0F3A3
-:10C780008CC780EF06F3466A0DE86E306FB67273A1
-:10C79000F3FEE626E73D7893F39E566EEE1E176E87
-:10C7A00072DE4737F9DE5F18E92DFC1FAD8326D70F
-:10C7B0003993EBA2C9F5CE94B7D70568EC71F6E4CE
-:10C7C0004894A89BB1AF89A1CA4A992FD8484F165F
-:10C7D000CF177581BE5A5B68178BD747357A9DAAEC
-:10C7E00013F197A36234908D749EAAC46AB3519FCB
-:10C7F0002FCF079E3F5CB68BFA00488EFC46CE3F9B
-:10C8000047FE52B4FB41BB719DE94975BFF1EC098C
-:10C81000D4BB3E257D71505C6EC0C78D2A7EE70873
-:10C8200003C76D4092F397F2F7CAF9E46F26BE256D
-:10C830009E674441D9C5CF25172DE571B45C44E707
-:10C84000DBAED6BFB216FEA088F0BA2CF4BB541FE4
-:10C85000D94675129E0738F83CED7DADB5E27DDB1B
-:10C860002DC0A89E1598C1789C0AC31319C99F565C
-:10C87000DF3866899E5BCB787DE3AA07EFF79E29B8
-:10C880005AB1BB48F085E85B31E0E07597F7E7FF08
-:10C89000E3741F7F8FA8776C7088298729DFC073A6
-:10C8A0006C3850CDE5B7F9D0FC5FAEA6B8B054E215
-:10C8B000741E138FAB79D649354FD4F2AC61CA17C9
-:10C8C00013F28EF45AD378FE30DDC8DE6C67220F87
-:10C8D0000EBC27F2E06AABB3A42B814F79B5827FFF
-:10C8E0006BA3028FD5F2DB4A2564CA413A543F6CF0
-:10C8F0008EA6A0BFAEEE9D6525BB5DDD5B98CAF13F
-:10C90000A5D6BD268DDE467C2F56CFD9777484D729
-:10C91000275E4BAA53B6D65AF9F887AAFCB4D602BA
-:10C920006F3794499BC90D4FFC4B87D9081F6FC1C6
-:10C93000F89FCEB73628CEABD5435AA2B287DE7366
-:10C940006668A497DAAAB6220FC70FDB477BC97FB8
-:10C95000FAAF5D397227C703AC32C557C9FB5EA871
-:10C960001338E26B149010BD1648219A57BD40E26F
-:10C97000FCCE6AB1F37C3CCB02E674EA370A7F5600
-:10C98000D530C9437D589EC9FD71D55139735D4578
-:10C990003CDFCF5AB07132D1E9DBEA441A6E306322
-:10C9A000AAE2213E7ED73A51C7B11356BAF73DC32A
-:10C9B000FA3A9156F719AF4EA4D569FD0D5FEAEA30
-:10C9C000CA7E69A49EF095EA0367789DD81F668E9B
-:10C9D000BCA278FDC83F306AE5F455EB4638DF4A23
-:10C9E000EB067A44FD681FBE9FDA30DE57C173BC88
-:10C9F00081F7A53682F7A5E7077BA6F336DAE3E4ED
-:10CA0000EDA19E79BCAD46B1C9CFA2BAD328AF3B48
-:10CA1000DD5BCB248A53B5BA855697A8CDF7B613FC
-:10CA20009D12EA16BC9F5CB730A78A7CD47FD4E203
-:10CA3000DC8DCFFDC76CDCCEBA226BA7515CF6D57E
-:10CA400071DF3407AF0364F3BC5293874B8AD39EE4
-:10CA500049F980D769A77A41F5E079ABCCED4EB4BE
-:10CA600000F2087F8A5929EF273A283C9E73D9891A
-:10CA7000AEDF8AEF87FF1FDFFF2EF8FE485C2FB97D
-:10CA8000FDA8F29A945DD41E55ECEB12EC439F572F
-:10CA9000E0C47DA5C55CFF76788B335B13F1FC06A3
-:10CAA00091C7652D28B5273EAFA917787E1603AF2D
-:10CAB000911D7BA3D6345E1CF846AD615C645C17A7
-:10CAC000E86B107644C3FDC7D6099C6F9726E0FD3E
-:10CAD00097DE4339C5BC75707F0AF7E75F1D48D9FB
-:10CAE0004DF1775543EBB409D8AF3A990245C21FCF
-:10CAF000E9EA0BCD0D26C59E61544F500A4C28B76C
-:10CB000063EA060D266EDF6FD40D1AA433BCAFC6E0
-:10CB1000E9F78CFE7A421123FA87829467BCD6C16A
-:10CB20009C8330B68E801B17C03CBC45C3095E5742
-:10CB3000767631A72C7F7B7D2147C5193AC399664C
-:10CB400092F396B700E8BBADB17586061EEF57C1EC
-:10CB500053C15AFA1EABD4E4207F968C17909C9058
-:10CB6000FF4FC60947547F34A2FABB87D5F8BE4AA7
-:10CB70008D4BB475C9FCAF53FDD378B8634D9D8818
-:10CB800027B63454F511FF028B4D407E604B83DB9A
-:10CB9000569AB09FB94E7C47B39DEA169312EB1696
-:10CBA000A23E915CAFD0EC54F5E0D7F5C4FF1D1167
-:10CBB0008127F9F304BE597DD07594F43E7E4E7101
-:10CBC000BF1DC8E3188FA39C9920EE0536817B71A9
-:10CBD0009CA16AF19787D2887E5EF45764978E9500
-:10CBE0006E4E277BB258AA6132C7BB6FE0DF844F1D
-:10CBF0002DFBA06D2190FF5F31FB38D17DC56A0B05
-:10CC0000FF0E49F357CB3E68AA17E3BB1E4BA5F1B5
-:10CC1000E9CC6997E979839B9E2F7A394A481F2C82
-:10CC2000A1D3A1DEC48E9D93485F664CF595D4E1F7
-:10CC300079AB1B551C7CB5F0AF2B228D16481FEB32
-:10CC4000EF0E177EC5F3E82B916A8E6F6753FDB523
-:10CC500022EE2FAA0FA01F9AF0A7F34375750E4E70
-:10CC6000CF5BD10FD179B21A459D3099FF6695FF00
-:10CC7000E3F995F1EC28F911D33CA1372C2FEE7F85
-:10CC800065CAAF6F8BFB614718FBB9DF807BABF6E2
-:10CC900029739C38EC21557EC7FD7E23FCFDE0E026
-:10CCA0000FD4FD99E0E06A9EA3E1E15A5EF49E4A4A
-:10CCB00067AD7D5F6D93F1320D27CB5500BABF0193
-:10CCC00027CB251C2D8BCC7605C7EDF2D533DCC0E8
-:10CCD000CDA259A6EBE5384FC5ED34FC2CE79E7E7E
-:10CCE000467146210436917D19B2826BEF24FA6EAB
-:10CCF0008FC126D2EF50238F73869EFB55EF2FE80E
-:10CD00007BC301E620F7D3D17F9CFBE90E8C6B78C7
-:10CD10003C14B92070AA7EF1BD694798294638E8CD
-:10CD20006F55FF5CAB00B71B1DEA777DF50342AF83
-:10CD3000E338D14352224EE4976393B5EF0543C2E3
-:10CD40003F197ED7D70923FC7BC0CE36E68CE2F3B1
-:10CD500064DC28192F7A4AFD0E705CDC48F96EDF1E
-:10CD6000FBEDAB9B30E933025355FCF99447D88572
-:10CD7000261F63B4BFCDE46DE7DFFD1E640EA3EF95
-:10CD8000478FA972BF48C56F5FB40A7978F17616EC
-:10CD9000A2786E11089CF6C5836B397EFB62157311
-:10CDA0009AE89E2A5EBB50A5C78C385EBB83F0DA3A
-:10CDB0001FA33B219C7691CA7F80107F4FE3CED486
-:10CDC00028C51B4F58FAF3481FB5EF8D1EAD13FE53
-:10CDD0002E3505BA8CF4335CE77AB48ECF1B37BF9F
-:10CDE0003C596710EF14D58A7D4FD7E9BF2F4A8889
-:10CDF000D3CFD0BA84389DF793E3F43F155EFBB7E9
-:10CE0000E3E3C555C6F1DA98797B6E12B77BD68815
-:10CE10001E9B55FC2499BE4ABD6687A73838EE781C
-:10CE2000E3FC20EAB92AEE35A4FAB920937F79070A
-:10CE3000AF7F5978FD4BB333C10962FF89F5C2EF6B
-:10CE400068ED4C75FFA0C518A7A951E7FD305FC973
-:10CE5000A8C779E52FE971B359FD7ADCECD6709655
-:10CE6000AE3F3B7A8B6E7EF5D162DD784D6CA66E5F
-:10CE7000FCB69355BAFEFCE1DB75F3EFF8DCADEBE5
-:10CE8000FFD5881E37BBF3AA1E37D3E4DB8512918A
-:10CE9000B8CE63FB996E5E419BFE5E855DFA7B4D6D
-:10CEA000EBD6DF4BDBB728A0BF5F49507FBF2CC25A
-:10CEB000F52BFE785C7F6FADACE2FA25765AB7BDF4
-:10CEC000A1D44E714C6EBE90576DDEFF0085A782D7
-:10CED000721032000000000000000000000000009E
-:10CEE0001F8B080000000000000BE3146060F85185
-:10CEF0000FC1D3F9191836F323F8F4C0C7981918DD
-:10CF00008E83302303C33E20DE0AC46B80F83D03CA
-:10CF100003C352203D07882703711710BF048AD529
-:10CF2000B1623787858D81810D884F02CD3AC54C1E
-:10CF3000BCFD8A7C08F6215E0686B5407C9497BECF
-:10CF40006130D8F00C41FAD9F50C6AD76ED181F76F
-:10CF50003708B38A3330304A20F8FD12A8F26CE269
-:10CF60000876960C65769501F50300295128158001
-:10CF700003000000000000001F8B080000000000FC
-:10CF8000000BED7D09785445B670DDEE7B7B49BA28
-:10CF90003B9D9095257480202A4BCB1201113B219B
-:10CFA00089010306440928D26C2184249D01661E50
-:10CFB0003EFDFF6E0842C4D1898A1AFC195F83E0E6
-:10CFC00004079DE0A0139DC0348B8833E804C70597
-:10CFD00097795F401E204212A338E8F3C9AB73AAC9
-:10CFE0006EBAEB763769B7FFF97FFF840F8ABA55BF
-:10CFF000F7D4A9B3D5A953754F149D9124DD40C82A
-:10D0000025F8A1E5AB0A2124255876489DC3E58182
-:10D01000C1F6B55E1771190979C06BC272BD379D33
-:10D02000B8AEA0CF47EB8AFC1642EEF7DAF1F9E38F
-:10D03000DE122C1FF59662F988D78DFD1EF29663DD
-:10D04000F92B6F0D96F77A8BB0BDCEBB0AEB372A62
-:10D050000BD2605C425CA6AC64423C2F0F1CB981D1
-:10D06000D6D6678E4F9047D3FA5FF5449F45DF1BB6
-:10D070002D17F987D206B9A4286B74B09F8AE78D63
-:10D080004A5E5F80F3F8581DEB67AA792D3B72BFAB
-:10D090002C3286E2395646FC89A564727672C47ECB
-:10D0A0008301DE2343D93C89DDF9DAA0C8F0AE065E
-:10D0B000780F0DE5F825DB270F8A0CCF09FD7EE5FB
-:10D0C000E4F0D23B0F0F8CDC6F0CF4AB7372787D05
-:10D0D0007DA60191C71D0FFD62E013C589105F8B0E
-:10D0E000D19F9DF5FDF9455CF42FC5A763AF79EBA2
-:10D0F0000609F9370DE8B4D6BEFCCC163A4E7BCB08
-:10D1000030A7DE41C8672E6782DD1213DF6E81799A
-:10D11000C4C0B752182706BECD8D916F0BA05F0C0F
-:10D120007C5B02FD62E05B658C7CFBD94F846FF712
-:10D13000021EDF836F1B62D4B75FC5C8B78D31F2A3
-:10D140006D538CFAF6648C7C7B2A946FEA73B5DCA1
-:10D150004124B48B372A253BA09F27B3CD3620EB43
-:10D1600027C1BF3DDF53EFF6C7C8BF5763E4DF11E8
-:10D17000A04F0CFC3B1A23FFDE89917F1FC4A877C8
-:10D180006DB8CE58E4AFDA8610FCB93400FEB5D8DD
-:10D190004F5DCDEB7AC03B89908C7039504BCA51B2
-:10D1A000940799B8DBD9BA55F0CDA51C425698E83A
-:10D1B0007FE9FBBE3C12D0D3F17D36E2AF9584FE11
-:10D1C0009F039E84E47F732955E8EFD345EC4F74A9
-:10D1D000D0FE30C815E5FF66EF102CEBB91C6D2EA4
-:10D1E000D2A13CF8920D285F4F789DD8DEE01D8BD0
-:10D1F000E5635C2E3772397A00E4EE0A90C3522E52
-:10D20000574CEE0829719453BA76EC89271B1C28D9
-:10D21000576609F09499BCDDBBE7CAAD1B28FCCD6D
-:10D2200035BA2BB785C8D91345AA7C51C94C0EF61F
-:10D230007BA2FC846DC150A4B70DE03414EBD47E06
-:10D24000BED07E0DEEEE7EBDA0DF63C55CBE641277
-:10D25000081DF7B1D2EE7EE912A5CBBD12296DB241
-:10D2600084F3658AC4F4942A0AF243E6F4DD9F77D6
-:10D2700096B4D1F76DF6916984964F827EA2FE39FD
-:10D28000B054DFAFA77476537A641A494D13E04B5C
-:10D290005A2585E22B8F7524821C3D34CE45242BE4
-:10D2A00021FDA19D8EDF67741BC9A265E2F83622BD
-:10D2B0000D837EB49DD653787BC650DA4EE13C0494
-:10D2C000EDD6607B2A6F4F73F0F7AF63ED0F7B09EC
-:10D2D0008EAFF6BB8FF2D94DF15B47F1C5E7C5C400
-:10D2E000057494293BFD21F39F2DE971DE95BC5413
-:10D2F000F1BF2FFB54C6FCA1417CCD832F66CC0F20
-:10D30000C1EFBEC173B0AEE263BEA212EBFD57F532
-:10D31000A69E18D707124EE7D49903847687EC446B
-:10D320003FCD71444F7C945F0E2A9E91F8F3051512
-:10D33000E71F54FF5C8C1EDAF6BB3574589721D278
-:10D34000C1D05BA4C3BADE221D0C7D2E4F8729926B
-:10D3500003E147A3873AEE862BC571E3AE12C7DD22
-:10D360007095386EDCD53FCCB8EBFB89E31A33C53A
-:10D3700071D7678AE31AFB7FBF7189ECA40F99B953
-:10D38000200EF8679E60DF2E10F7C3A0DF60E7F481
-:10D39000C9413B27DB4B88DB12E42791E9CB39A15C
-:10D3A00070EE14EC2A85F37F381CD7E5E1D8357090
-:10D3B000E66AE16CE37048A89D0E8343EED0CEE3AD
-:10D3C000B7FCBD802E647CBABE92126BE87B4ECD5A
-:10D3D000F8B76BC7DF0D760CE6A1BBECF80E0D5D60
-:10D3E000E768F1D9C3E110DDE5E841EC1A38B3B5DF
-:10D3F000700E713801E9B2704AB5F3785DE5AB247F
-:10D40000AC5F941EC382EF75E4759E423FE845C54C
-:10D41000B19DB64B7FB2066EA0FD8F6C91FC465A53
-:10D420000FEC8DC7F5E3FCB6E958DF778D11D7898E
-:10D43000F3CEC97E23B527935E78DB06F6A5EA0511
-:10D44000BD0C75DDDE8F6D6D142F8FB1F5C1EBE86E
-:10D45000F3CE17F4642B4A63A10EE87E8ACB2659DB
-:10D46000C5EA656656ADDAB2EF4E805BDE6C2466C7
-:10D470000AA7EAA525D3AEA3F5258715025DAAB6AE
-:10D48000AF36F4A6F5A57EA909EA1D79A41CF469B6
-:10D49000CDDEFF6C87F5E8FC6E251BC63F4BD70938
-:10D4A00007B5C747ACADA933291E15FE5D85F05EF3
-:10D4B000C54EC9492D1CC577FBA10CC07787E43444
-:10D4C000527A2F6B8C270ED5DED1BFA776EB71FE7B
-:10D4D000CBE9FC0985B784D417023DAB803830BE58
-:10D4E000D3E8374B417D3BEB3D8CE3A9F5AA1D7496
-:10D4F0003CFA7EF5739213A65AAD236EC0B3FD2598
-:10D5000073E9531698E76AC3602BCC6FBD01FA2DFF
-:10D51000F1CF7FD1EC003CB7180A01DFCD5B0C6581
-:10D5200043817E645EC950C0EF2F227E0D7A17CCF6
-:10D5300077F935C6AD7AE0A72530688635DCCE9E12
-:10D54000A5EB952364FDAC20CCEE13D96F983E2C4F
-:10D55000F8FC257D22CAC1B2463D7184DA0D2E1F2A
-:10D56000BEA384F9317BACFEED59413E2EB77379F1
-:10D57000E57C5C9EC8F92A77E6CC18168ECF83C06E
-:10D580001723F38FA07C98AE9B0EF47F1C48BFC777
-:10D59000A8FFE440FFC889CF9FA07E12949BA99F5B
-:10D5A00004E593D44F82D24FFD24E8B795FA495051
-:10D5B0006EA37E123C7F9AFAE7503652FF1C9E3FC4
-:10D5C00043FD7228777A7DF8FC396F1D964DDE7A1F
-:10D5D0002C9FF73660B9DBEBC77E2F7A1BB16CF658
-:10D5E00036E1F397BDCD58B6780358EE053ED332F9
-:10D5F000E06DC572BFF7189607BD6DF8DE21EF1913
-:10D600002C7FC9E96E9B4072652A2F3617B1039BA8
-:10D61000928A5DB9E0AF2495B07AEA1DBE5C03AD95
-:10D62000A7BA699DD2B1776520D748EBBD6B587B0F
-:10D63000E63D24CF44EB993ED63EE097AE3C33AD79
-:10D640000FA867ED8337FBF2E2687DB09FB55FB549
-:10D650003390174FEB5735B1F6E12D649285D6879D
-:10D6600007587DE411D7242BAD8F6C65F59C0F7D99
-:10D67000936CB49ED3C6DE1F7F2E302981D6C77728
-:10D68000B2F6895F937C3BAD4F2412D6F32CB9F9E7
-:10D6900089B49E6767F5C2BEF3654784F57DAFD256
-:10D6A000B6104CDACF7539B932F513F61ADA56805E
-:10D6B000C95DAFBB21571E47E9A79045D0BE49576A
-:10D6C000C4EA06B212DA7FAB9B8EF5FD8A03DBF764
-:10D6D000E8E6B0BAC181ED7FD52DC4FA41C585ED2C
-:10D6E000C77595AC6E7061FB67BA9FE37887143796
-:10D6F000B62BFAFFCDEA0637B63F2CAFCFCDA7FD4C
-:10D700002BF56E8F8ECA75ADE42E2703415E9BD23A
-:10D71000C11EAEE37EEB2C9D03E57E5D8601F56CBC
-:10D72000EF7FE53C857A063FC9502F7B1AFC5E0AE5
-:10D730006715C251281C7DCF70267E33568033F189
-:10D740009B7215CE6A84638E0DCEDE6FC68BF87C1D
-:10D7500053A1C2D9A0A3F6BED61ADBBC265E9A207E
-:10D76000E273A95285F308E293181B3E01E55A01C2
-:10D770004E4059A2C2D98C705262C3C7651827C0E7
-:10D78000711996AA70B6239C8CD8E0040CD789F83E
-:10D790001896A9709E43FAF48B6D5E2EE3F5223E37
-:10D7A000C62A15CE1F109FACD8E0ECB78AF4D96F0B
-:10D7B000EDA64F00E164C736AF3C9B489F3C5B370A
-:10D7C0007D5E433857C60667BF4DA4CF7E5B377D6D
-:10D7D000DE4438C3629B575E82489FBC846EFA7CED
-:10D7E0008070AE890D9F8329227D0EA674D3E72415
-:10D7F000C219131B3EF9A9227DF253BBE9731EE146
-:10D800008C8B0DCEC154913E0753BBE9F305C2B9D1
-:10D810003EB679E5A789F4C94FEBA6CF258493EBF3
-:10D820006E447C0885638D0EE7503F913E87FA7504
-:10D83000D3C7A407380514CEC09EE114668AF42924
-:10D84000CCECA64FA21EF462726C700E658AF4399D
-:10D8500094D94D9FDE88CFD4D8E655D85FA44F61C8
-:10D860007F461F8FB173921DFCC644E2DC4A5F996C
-:10D8700094FCB383B0EE2816E204B047A4C036800F
-:10D880004FD756F44B65A7EA073909F8B9C536876B
-:10D8900013E2017AD5DF21ADB81FB1EC4C14E24D93
-:10D8A0002FE9F38603BE56EA1586FA3D0963E304C1
-:10D8B0007F2BD19524D47B15F516FAA7940C10DA9A
-:10D8C000D34AAF12DA33DC23857A9FF2F142FF7E2E
-:10D8D000357942BDFFAA2942FF2CDF0CA13EB06E74
-:10D8E0008ED03FBB7E81D07E454385D07EA57FB95B
-:10D8F00050BFBAF15F85FEC39AD608ED239A370868
-:10D90000EDD7041E16EAA30E3F21F41FD3BA5568C3
-:10D91000BFF6D83342FBB8B6E785FA75675E16FAEC
-:10D920005FDFB95FA8DF70F1CF42FF5CF237A13E45
-:10D93000C9F481D0BFC0FE91D07E63FA271A3F564A
-:10D940008C5FD4E612E6CF6618D09F0D580D58377D
-:10D95000EC35B3FD0DD493210E518C75C3FE858E2D
-:10D960006488070000EA4FE4F62EBF02E255BF18B4
-:10D97000EFBE02E2B8BF30B847D823F841EDB2FBA2
-:10D980001E3DC6135B25920EA54307659C9EC713DB
-:10D990008C4C7ED767E53CE50BD183BA7ED4BFA023
-:10D9A000F5F57A8AC798A0FEACEF57963E3F649C87
-:10D9B00075FD0CA55B87B2E70B2D305EC97D309EEF
-:10D9C000C7D03918F0D28E631C305618C794598EC0
-:10D9D000E36C84715282E31833CB35E3984AB7F293
-:10D9E000E77C9CC7406FA28DB37EC078713E9915CD
-:10D9F00038CE16CD38EB332B34E3C4B1F9D0E77C05
-:10DA00009CA72E378E71E004713EFD2B719CE7B40C
-:10DA1000F3E95FA919C782E3C0731887F4A5BB981F
-:10DA200034CA67636719CAC19FCC182733F4A9F8B1
-:10DA30000DD4C90766920DE338E8B8B41F199244B3
-:10DA4000859A907FD127217FBE88A3FC0F89A705E7
-:10DA5000F7E33EDCD72FE628123FC588EE93AAB93C
-:10DA60006C2EDA393D73858396CD07063D02E36C53
-:10DA7000B43AB369BDBD7992616104795A5CAF9CD7
-:10DA80006A0B91F3EEFD591E195243C75F116747A8
-:10DA90007CD4BA5A26E9C4E727E8BE8BD0FDC987F3
-:10DAA000749F42E87EE52385ED33FF9DEECFA0DE37
-:10DAB00046F767D04EC86A7CEF048F339FF8A5E421
-:10DAC000077A7F71D7CF145C277CE4ADF4548826A5
-:10DAD000B09F79ABE2291382F8CDF7F512EAD41C96
-:10DAE000F7D1A5E3BE16E3079D2F19FD5B81AE7547
-:10DAF0007D284D79BF0184BCBB77EA21C986D53E1C
-:10DB0000BAB184CCAC995E90865A24F55B4EF19CF8
-:10DB1000B1FB1A85BE41DA95B63B9D96205CE25278
-:10DB20004E007D4CF40FC0B9A588D643C6BFB5449E
-:10DB3000ACCF2272B04EF97D523F80B0F83F1FD774
-:10DB4000E15280AF25748E1994D5B3A01C09CD2C59
-:10DB50005E536A67EFAAF878162A2480FB6B5F0A87
-:10DB6000C4B1892F19FBCD51F7C91AFC4A1593ABE3
-:10DB700084D2B574BE1EE9AAC5F7FDBDF12EDD70D5
-:10DB80005AD63DA24068B627FC67BBC57652CEC6C2
-:10DB900053E9AACACB29CEDF13C07F5A9E06FE5393
-:10DBA000BC4F72FE07E598F1DF63744F03FE776E9A
-:10DBB000D213E417E7FB6D9CEF8BEB45BEDF06E766
-:10DBC00071B4FF6D2BB358BCA9A197C05F3A719196
-:10DBD0000EF50F1550B31A86FFDFB91CCCA9DBF583
-:10DBE0000AB0F7F672CDFC381FEEE47C98ABA1C703
-:10DBF0006D9C6F7339DF9610DFBD1918BFF02B10C5
-:10DC0000D79B5D2E11B0179EBB55BEB5097C73AB7B
-:10DC10007CD3E07B27E7DB9D7731BE69F16EE37C47
-:10DC20006B6BF84C2103C2F1D6E2396F95665E3E0C
-:10DC30002DDFEAB95CDA0DE04F4D77E5AE3819D249
-:10DC4000FF96A2C92B4E86D8855B4BA60BF559A52E
-:10DC5000B385FEB3DDF385F6DBCB970AED736B7E00
-:10DC600026D4E7ADBA4BE83FDFB75A685F58779FD5
-:10DC7000D0BEB8FE21A1BEA46193D07FA97F8BD076
-:10DC8000BEAC7187D05ED5B44BA87B9A5F12FAEB1D
-:10DC9000F65E7933C8D791B7F504E27D179CA731BA
-:10DCA000CE78C1A938A1CF49AF03E5F8947708969B
-:10DCB00067BC4E94F3B3DEB15856834C8E033B7B66
-:10DCC000C002F1534F1CB5FB89741D97C7ADA99BCA
-:10DCD00000EB0D6D1F4FC8BFCA37ACF1F5A55A0058
-:10DCE000716F4AFFE20603098C2254BA7B77CB732B
-:10DCF000A73EA4BDAD87F60699047A85B717B74548
-:10DD00007EDE21750ECE80B8EC7B46B23D24DE1857
-:10DD10007EDE42FA805F11ADFD9C8E94879EF76C8B
-:10DD200095D939CF117DDE5699E2556960FA5FF9D0
-:10DD30007C461EB1413D30B8C67299F19A283269CD
-:10DD4000C0E78182DE2F69B83AA8E704C661F6749D
-:10DD5000A97F94F07C59E375C27B6F48EE2D80C794
-:10DD6000B97D7A5CAF49E040E62DC3003FD7561934
-:10DD7000D6D1E614F4BB5ABDAE15271542DEF41613
-:10DD800061F996B704CB77BCA5581EF3BAB17CDF16
-:10DD90005B8EE587DE1A2CFFDDBB0ACB36AF0FCBDF
-:10DDA00013DE3A2C4F7AEBB13CE56DC0F28CD78F85
-:10DDB000E5596F2396E7BC4D58B67B9BB154ED6790
-:10DDC0004FF27786AFAF67410E8DE1727670EDBC92
-:10DDD00035757D837276582E433953E95BDC60E4F8
-:10DDE000F2902AC8C35F611D4E0179E9A1BD41E1EE
-:10DDF0007218EDFDC8ED206FBD7F047923640DCA54
-:10DE00008105E4EE7BC81B8153841490A73E1A79E8
-:10DE100012E550952355CFDF904ACE817CA97265DB
-:10DE200091993FA4CAD5FDE02746F0B77A2B125F3F
-:10DE3000FF987F4402B93A20D9727E5E417C2EACB5
-:10DE400077F1B16B29B856E827FB87C03AD235E4A1
-:10DE5000ABC110DFEF3A4685202BFAFCB4F2129DDD
-:10DE6000EE2EDC3F94F929F37B85B79BE3185DCD5B
-:10DE70003A524446C2F972CE3137E567DC9FAE1E96
-:10DE800009FB66FA5C264900C7EF9C1EE1BC800CCA
-:10DE90002248E79EE8ABF63FF5C47FE6C0B9BF0570
-:10DEA000F49CCE3DEE80BE86E9EF53CE5B42CE972A
-:10DEB0003C46673AC4C13BB30D76E63F4C12E94895
-:10DEC00026E1F9814AC703D95F0C86F399FBA81CA8
-:10DED000827E750D1A9C402E231F3DD9FB9EE8B90A
-:10DEE00000E61B133D0D04CEB9283DB7C27DC758CF
-:10DEF000E9D9939DECC93E9ED8C0E87C84FBA7D1AC
-:10DF0000E8AC9E8769F1B84591391FB81C933B3442
-:10DF1000F42F15E8DFD7EAC0FE07F77E9009E7780F
-:10DF20005DBBAF48204343DF2F60E73DDDEFE70BEC
-:10DF30007A20FDE9EF99B03F3EF8C2BB58AE254CC0
-:10DF40000F375A4AE62A6382F062BD47106D5E1EA3
-:10DF50004512E7D5837E76A4AAFAD99A09F2B49B32
-:10DF6000DB81B0F9F5209FEAFC0EC0FC289CA920BB
-:10DF7000D3741EF972C95DC2FC46A7E0BC7B9A9FB0
-:10DF800027C140A411143FABC14012A83C2AEEB5F2
-:10DF90000AEEEB9C6D3E8853EC8D77D65296786CEA
-:10DFA00067DF0838E03D319EB1ACD15C23FA4F8980
-:10DFB00035A2FF945113EA3F751D7ECAE6A6F82DDF
-:10DFC0004FD7D79CEC05EB9C8BAF736C5D55F1ABD9
-:10DFD0006ACAAAB10870C47A57BD54C4EEE13812B7
-:10DFE000664638EF53CBE5E9061CE76CE3C004183E
-:10DFF000F7ACD754C3D6577B0D1B37BD26747DAD08
-:10E000005C155F73725410BF68707F68FCA8449001
-:10E010008F4CB02ED2B681D1FB47E5A7FCB901CF1A
-:10E02000D55B942FC07F370F51FD7719EB2A5C4FDA
-:10E0300093DE671C01CF770AE3D1F71CEAD938BC1D
-:10E04000175D6E64724AE5A71ECEBB08DF1F98906D
-:10E05000CF6E0A3181C2EB902D7520577E85E9B3D2
-:10E0600087CB6995A9CDE07620B95B41AE178C5579
-:10E07000E5DC31EB036AA73FFE8B82F7CCC8D714EF
-:10E080007A4EF0AAC322526283A0EA82DDCB8A6173
-:10E09000DDFEF8C59BF83EBD3E07E67D9EE88AC0E2
-:10E0A0002E9D276FDA4685E8EB6985C5B1481DDBF3
-:10E0B000E7F8E81F98DFE27A71DFB3A441AC9791EB
-:10E0C00019A9606FCB362AC44F715F0AFB2675DE33
-:10E0D000D4FEBEABD811B925A4661DECD31F53588E
-:10E0E000BC67819DC87DA8BDAEFAC3AF7320EED3D7
-:10E0F000AE307F573D0F5F9AC4F6831533FD061788
-:10E10000EDFFD1EE51B7518B4BDFF7AF43FF673ACD
-:10E11000716E27E1745F5827E2D713FE5A7C553F92
-:10E1200028EC5C9EE391DC2845BC2FF535B773AA3B
-:10E130007E2419EC42DC274D5357E540E172E0574D
-:10E14000DC56430AE33BF051923B0DEE907E866035
-:10E15000BF24C398E8FD8CD04F8FFDD258BFCE426C
-:10E16000DC1F132A4F4383FDCC41787DD9B862BFB1
-:10E17000AA3F3CFBA28FCA4BC5EF1EB511BA6E7EFB
-:10E180002CD7A73AE9F3CAEDF7DA5CB43C23FB6C71
-:10E19000C0CF8FFDFA88F77D6F31A8F470592488BD
-:10E1A000A771F924753E8C537CB15DB1E33942A36C
-:10E1B0003160A4F259BD7B6931198EF5E3ACBEFE26
-:10E1C000533DD49B457E55FCE6D15407BB27C4E2A2
-:10E1D0004924807E6EF5B6FF2884F5C2433A51CEBD
-:10E1E000B4EFC1F8179350AFE71B12C2DBF16270B6
-:10E1F0002ABCCF7E3CBBEFFF546F8372F269D02301
-:10E200008F464ECAB9DF0AF482FD7EBEC19A8CF6F3
-:10E21000FE5A722DE8BB4A17E267FE6BED8EC78788
-:10E220001FA7789DDBF6179B3434D44E3079EB6A08
-:10E230005AF86F265D747BD24EE531D44FA280F13F
-:10E240003D4733F7BB5B5859A9046C701FA7728B0D
-:10E25000E2A492482A9FD513B89F40DE33FA213EAC
-:10E26000BAECD957DE194FE9BF6C97925CCCA66324
-:10E27000915283FCF1D0BFAB4606F951F1FB570C2C
-:10E280008E61ECF93D4941BE2CDBB5CF408685D38C
-:10E290007152D33E439B25027F9A8E17C27A5BBB95
-:10E2A000E31F06882B7EBC57226959E1EF976F79EF
-:10E2B00005D73DA013F293F3AB9B7F617C0B4C7BA6
-:10E2C0007934F6B3833DEC896FD9B09F4B41F97E29
-:10E2D000EE65B8C7F4BED10974287F6E850DE6736C
-:10E2E0005AAE6172FEEB7B5341DFCB155FAA1D4B2B
-:10E2F000F6BCFCC99FA3FC2D39FAF354F41F882BFC
-:10E300004387B6D99701F35CBCF9569C671971A392
-:10E310001C96FF5A5F02F74C2FC8A46857043DF9BA
-:10E320008B81ED5F4E6FA5CCA5F33C0DF8817D7B15
-:10E3300053EFDF8E71F39FE13DB89FF339D3951012
-:10E34000EB174C8C5F5B0C3A351E6A12E477DBFAF4
-:10E3500056E0D3D97EAE3438F7A074F071BA49973D
-:10E36000285CFDD18234C627E29073F87BD4DE4F5F
-:10E3700082E7D0BF557199870BEF71FBC8C65FC9A3
-:10E38000C7A778C7C1FA753A35B2FFF70F3E3FFA13
-:10E39000D34A42E42C44DF99FE6FBB8FE9BBAAFF4E
-:10E3A000FEE945D0FEF95B4C8FE03D582F285E8199
-:10E3B000346CDF375342FB40F7D991F47C9BC2F5B4
-:10E3C0005C6CA73B1C5CFF5539A1F8CB5242A8BC42
-:10E3D000D07192900FB83F2EDB48DF0FF1CB3C306D
-:10E3E0002EF633049F87AC1B4BB85D38A4B107648D
-:10E3F000734A4C7E74A5E27FFA09D0DFF78C4E9FFA
-:10E4000003F4572981F97FB2F3C03B73A89C7FD2F4
-:10E41000A4EAAD6857B57A5BFEFC1812496F3FB1AC
-:10E42000D07D5724BDA5CF23EAADA50DE5F9FF9614
-:10E430005D55E9D7AEA11FD8C7971DD1E9A8B58F03
-:10E440001B0C8E88F691FEBC4572C2E550953F5577
-:10E45000EE2A7E5BD51FEC50B77CAAF2D72D9FAA7F
-:10E46000FC69E72BD24FDBFE07D06F8AD7EDA64DB4
-:10E47000D3C07F3675128CC3E7CED4E33D4DD3E7CE
-:10E4800084DDD3B8231EEBB3F46DBF079FF083AADE
-:10E4900059C3609DBF9DF814766E5FAFA01FFBF55A
-:10E4A000A54B13E87CE670FADE4EC93D95F2A35405
-:10E4B00096027114CFD932F12524413C59222742CA
-:10E4C000F0B8BD5CACC3CFC4D4209C9EFA7F5BBFC8
-:10E4D000FBBB9647295F4F6413F2372871FF411D3C
-:10E4E000EB10799ADEC2CE313CA325FF00D4C336AF
-:10E4F000B924641FE13132FB7334FF963140BFDC35
-:10E5000059C312989C0FC6FDA287DBB12E9F230131
-:10E51000EC7B57CB40DC17761D5E687547B067070C
-:10E52000B89CBDC2CF613A2C52BD9ECA7D07E9445A
-:10E53000BFC66731478CCBCD31AA769AF38DFEE802
-:10E54000E9F8A55C0E67D357134686F06DE6D48FC5
-:10E55000655B381FE0E744C8BEE2FBD217E41AE867
-:10E560007BC0DC565812217E53C9E93771FF9706EC
-:10E5700058F7F25B7265A063BE452FC4431619B904
-:10E58000BE0E254301AF89FB973E3086CAB1E7B086
-:10E59000DE69A6F3F3B47C6A7047D8DF69E909F055
-:10E5A000C1BFDC6A64FEF2DB4AC962A0EBDBB7B232
-:10E5B000F3DEBF199C5591F04C37337F733629B980
-:10E5C000305AFAE9D1377796359047E9D16561F746
-:10E5D000B5C3E58FE97D975DF2AF96400EF5AC9E31
-:10E5E000CCEE371712F7031324D4F71B42ED576E06
-:10E5F000F3F467E13E4D758B64D7D1F66AB9CD006F
-:10E6000072EC69DE2583DF7E9383B8707F2DD70C93
-:10E610009B1912FFA2CB1ED2EBC05773E6027D3FBF
-:10E620009B692480976BE8A73658FF3F6B19857A62
-:10E63000106D5EAF7BC9B47C05E0307BA69587C2C8
-:10E64000E478A17EEB24D217CE81271ADB5638233B
-:10E65000F02FDFC4E42C66FB66FAFFCCBE4DA0F6BB
-:10E660008DC9B5126ADF2CA630FB9616C9BE2D5F88
-:10E67000ED4803B958BE67207EBFB5FCB5C52991EA
-:10E68000ECDBAB7CDFFB1ABF07DED197DAB71121D9
-:10E69000F6AD2FB56F11E2E45FC46ADF4CFF33FAC9
-:10E6A000F72AD8B708F3359B44FB56D4B21AED5B72
-:10E6B000515FBD705F8998A87D8BBF9C7D9BFFE8F3
-:10E6C000AD58579CF111E407E80AF6ED356EE760A6
-:10E6D0001CB0733798587C33563BD72F563BF73FC7
-:10E6E0004467D5CE2DEF27A1FF122E87CCCE2DCF9C
-:10E6F00062766EF91E66E79667333BA7B56F796160
-:10E70000F68DBD5F3D84BE8FFBC7ACC7EF80FB8439
-:10E71000A58AD344FB173BD4EF276AC684DABB1B18
-:10E720004C32D239CCDE393FC5EF607AB2777F0503
-:10E730007B978D766C10E891563EA60C8A17EEB347
-:10E74000BDFDE5A9DFFE0EF4E5753DDE177A57C77E
-:10E75000F6477BBF3C350AF4EE2113B3BF4B4C8C1C
-:10E760009FED5E1FDAD3494399BE57DDC3E857BD1D
-:10E770005B62F35DA9F73B601DF8EA22EE9FE7EECE
-:10E7800061FBE759C6D69478B897F42F0A61DF7D0C
-:10E7900090E2F921F2507AB102E380CFC7D9B6C234
-:10E7A000FEB2542626F063E71D9EF231F8AFF32E39
-:10E7B000D6A1DF3B0F9EC33909BF27A1DEA398D3A3
-:10E7C000BCEB953E24FC7EC44423E3C3C415927F76
-:10E7D0004B16DC4710DBE769FCFA757C9ED49F453D
-:10E7E000BA90BFEA23C6EFD669E9E164F3AF5AA94C
-:10E7F00017E9512345A407E568F1FCD4E0FCE7BE26
-:10E80000D0B6AE0FB42F95703FA5D2433B4F953E87
-:10E81000EA7E651ED7114FCB2E05F8A59DBF4ABFD6
-:10E82000B079ABF4D4CCBF4EB51F579361A06FEF56
-:10E83000EADC0F8C01F9F833A503C5EBB6D9D96929
-:10E84000A1F6F8416E97A6BA8FE7A73A806EECBBA7
-:10E85000C439E5BB5E49A5F3B9D9953512BE1FBED3
-:10E86000F52B831BE20B07CC9D68DF54F9FA84CBB0
-:10E870007B80C379BBB73D1FD79166C98E7A13D011
-:10E88000D82F7E7FCC730FD3AB03D23FD6F5198D33
-:10E890007485658014AAEB10F081FE776A0BE38320
-:10E8A00007F840FF3B8D741E023A57274BCE00F409
-:10E8B0006FDE752FC8CDAB66FA1CF4B75C72B2EF91
-:10E8C000CB882523F5B2F22947924F0C4EE404D7AA
-:10E8D000C579D02F29DCEF98686C7D1BF09848F53E
-:10E8E000610B09F74354BE0FA17F2E45BAF7D383BE
-:10E8F0001C7FCCE5F355A0B705E8DA69007FC613A5
-:10E9000060EB87DAEE911DF9481F95DECD747D1816
-:10E91000CDE8AD8B40CF9BD53AA7A7A74552E0FDE8
-:10E92000C974FFDA4B82D3AD2F0FA9720CDFC36914
-:10E93000E901F1808C10BD07FB147A3E59DD7C148F
-:10E94000E932652575AF42E80E76EB72F489A617B9
-:10E95000D5CD3F8C5E7CA2D18BBDE6CEBF8C80F83E
-:10E96000D71E09ED03694914F6FBF166E6671C3012
-:10E97000BB517E3B5F53F0FEB9D68E7CCDE51EF6D3
-:10E9800017A1DFFD4D8289809DB39BC9472A1E03D5
-:10E99000981C85DAEF57CD6EE45734F8717C1D8EE4
-:10E9A000E63FA9F51B613CB88FE810C70BF32F7841
-:10E9B000FCA7A779A5F171BFEBBCBACF3349AB81F6
-:10E9C000B0F8FF0A63C8B9D46DFC5CA03B4E16ECEE
-:10E9D00067375DA61FC45F0274DEAFEE7C0AE3BF3B
-:10E9E000E79F393E0DE477D91FF5C444F9DCBED367
-:10E9F0004A02ECDE8501D6D98ADDFA88E72884D47C
-:10EA0000B2EF1C7F6745FB52F1BCD15F4CDFAF78A2
-:10EA1000F1A3E110B76A5FC3EC8CEF192E1FBEB6ED
-:10EA2000E170BE5E21B373612DBCEBB8BC9C7B2949
-:10EA3000BE14ECA4D4C8BE5FAD689AA51843F6E92D
-:10EA400023CD0A8E4BFBE1BD65DF0E09E3E5E1F85E
-:10EA5000AD66F07630FB57D1ACF8E13BD88AC62DD5
-:10EA6000B8BFF5347E6A00BF6ED2EF9E65DFD73641
-:10EA7000EBC5F861A33E60C438A7FEB87138D35B1C
-:10EA800049884755A15E5637F13899267EB4EC7710
-:10EA90007B5EF451D22CFBFD6F6C606FCEB66EB70F
-:10EAA000617CAE91C5DF648B1C393ED7535CAEE907
-:10EAB0003E1E979B7A9A0C0F8FCB9D85FF503D9CF5
-:10EAC0006FE6FAAAC6351B7BC5747EBEECD90B4F28
-:10EAD000C279D2B9E73F7912F0AFFCE6B327EF86EF
-:10EAE0007389BD663BAC7F9E67DEC6F8BBFADEDD90
-:10EAF0005CCEDB77FCE6E927A81EB6BF67C47B5B6C
-:10EB0000ED7B4E67C2F78CEDBBBE4C85F8E6CA3D87
-:10EB100005B89F59F9C2A4B4CBDD3F01F9F4C77021
-:10EB20007EA2E5C781DD7A02DF739E3F6644FFA3C4
-:10EB30003BCEDA54C5E2D70E1E5FDD19F9BC4A8D13
-:10EB40000756EFBEE5E6EB611DDCAD381DF89CC74E
-:10EB5000077B8AABBE45F93A2206FEEDE4F1F3A647
-:10EB6000A911E3AAE7E13F944F9BCC625CF5C2EEAA
-:10EB7000C5FFF604B4EDEE1535AE1A88816EEA795C
-:10EB80005899D9B5CD0CFAF1FC6F318E0D7CA33EAE
-:10EB900039697FF64226C423CE289D77E23DE53DC4
-:10EBA00046BC6754B1E75DD497F6178EE23913E19E
-:10EBB000E751EDA4FB879D1BF0BD8E679B95C56358
-:10EBC00039FD215EEBB0E1731E976572ACC66BA395
-:10EBD000C569DF37B3FB50EAF95CD5B60F0C4413B7
-:10EBE000FF96C602BF8E0BE78AEABCB5F0EC408701
-:10EBF0006B43CF1FA2C5C3B95D0DE3173B7768DF39
-:10EC0000C2CF23BACF1908E93B12CEC7D9B9B9C7C9
-:10EC10002FBD1B89BFEAF9C3DB5AFDF4C776EED0DE
-:10EC200033DEDF8D2EAF9AD9FE56A5CFB9AF23DBE9
-:10EC3000E94EAEEF749DE930E3B9315B67E6F175FB
-:10EC4000A69AD28D7DF7C6F03DC7F781E79ED1FB2E
-:10EC500061BFBCAEE900DA5BAD9E571316FFD28EE2
-:10EC600027C531FFA0BA79DF70B047E7F6BF84F25D
-:10EC700057BDF3B8C147E11C6AFCBDA16D6850DE09
-:10EC8000C18EFB43ECF8B9E7F60D67E72291F3B4C8
-:10EC9000D8387C4F8B08DFB3F35301FE325F93C14A
-:10ECA0006EE9799CB3B26B16CCF76CAB42E03EFBDD
-:10ECB000D9267D913FC2B89FC13A362648A77556DE
-:10ECC000F61D9F3EC9807EE64AEBD863F0FDF84A08
-:10ECD000ABC101FBEDDAD5EC5E65EDFF72A6035F1B
-:10ECE0006A136FC373A37A0D1DEDC9F65CD887DB79
-:10ECF000F34B46835869ED41A24B27E0BDD25A94AD
-:10ED0000E6B0405E2FE6A710D989DF19EA6D854588
-:10ED1000300FBD5D6737475C5F193CC5C2F266289E
-:10ED200076F1BBBFEF900783403E8E6F9D07A353E4
-:10ED30009307A3FCC6FFD7F260F8609C9F401E8C2F
-:10ED400000C677D43C18C93F721E0C882F8D0EC99F
-:10ED500083D1A9C983C1F9F8CF3C18FFCC8301A5A1
-:10ED60009A07E39D0D650590A742CD83716683A741
-:10ED700000F252A87930BEDAB08AD5791E0CCBFDEC
-:10ED8000AB0B42F36064DEBF01DBD53C18CEFB1F4A
-:10ED90002908CD839177FFE682D03C1833EFDF5E00
-:10EDA000109A07A3ECFEE70A843C186BFF50007929
-:10EDB000305E8F77B7C6A544CF83D11CE788290F73
-:10EDC0000685F31EC2899207430B275A1E0C0AE7D9
-:10EDD00044DC98E87930C2F089920783C2F904E1F3
-:10EDE00044C98311864F943C1814CEE738AF287974
-:10EDF00030B470A2E5C1A070FE0BE144C983A185C7
-:10EE0000132D0F068563884F899E07230C9F287951
-:10EE100030289C048413250F46183E51F260503868
-:10EE2000E908274A1E0C2D9C687930289C2C8413F5
-:10EE3000250F86164EB43C1814CE55F163A2E7C1D7
-:10EE400008C3274A1E0C0A6714E213250F46183E12
-:10EE500051F260503813104E943C185A38D1F26079
-:10EE600050380538AF287930B470A2E5C1A070A63B
-:10EE7000213E51F26084E113250F0685330BF189A1
-:10EE80009207230C9F287930281C37E213250F8620
-:10EE9000164EB43C1814CE528413250F86164EB469
-:10EEA0003C1814CE728413250F46183E51F2605060
-:10EEB0003877239C287930C2F0F9AE7930CC814183
-:10EEC000D240CC8381F938BBF360247FEB3C18BF80
-:10EED000027CFF9907E39F79307E8C3C18B75ADD9E
-:10EEE0007F8FC77DE377CB8371265E9337A2873C04
-:10EEF00018B75A4BCE823C7FDB3C1817E2BF5D1E31
-:10EF00000C3ACE3F2E374EB43C183ACBB7CB8341A8
-:10EF1000C7912D632E339F287930122C62FE901FEB
-:10EF20002B0FC6B1F8249C4FB43C183FB97C137426
-:10EF30009B05FBB4E9288AE427937F62B485C70D5B
-:10EF40007FA8FC1330E99C9F52FE09358F41930244
-:10EF5000EBE1FB9CEFEF70B9F880E7A13816350FB5
-:10EF6000857F2AC677978A7928A6703ECE768BF25F
-:10EF70003085B0739429F959FE5AD8AF976BF25087
-:10EF80000C11CFE98BDD47F3293832D529CEE328A0
-:10EF9000978769A59F1E04F6DC3C36721E8A199C71
-:10EFA0001FD3357499C2F9369D97B7C3A739549EBC
-:10EFB0008BCB8FCA40D7698E3619E3F437A9FC731F
-:10EFC00008FC9BC9E16AF19DC1F9376332E39F16E2
-:10EFD000EFB7807F14EFB7CA4721FFB4786BF1D445
-:10EFE000F29F84F23B247F482E11F34F4C3289F973
-:10EFF000270AEC62FE891BD3C5FC13931D62FE89B0
-:10F000009B8688F927A63AC5FC13378F15F34F4C1A
-:10F0100077ADD6E4BFB84F93FFE2214DFE8B4D9AFA
-:10F02000FC175B34F92F7668F25FECD2E4BF7849C5
-:10F0300093FF629F505F58F79AD07F71FD51A1BE38
-:10F04000A4E13DA1FF52FF71A17D59E3C7427B5569
-:10F05000D3A742DDD3FCA5D0BFA7FC036FF1EFA17E
-:10F06000DFE1DF431FE3DF43BFDF43FE8B772C4B42
-:10F07000D785E6BF78DFE2590779098E5B1C3CAF84
-:10F0800040E4FC16DDED51F25F04DFFFF6F92F528C
-:10F09000927FF87C043A2BFB1EB0B7254F674DF9E1
-:10F0A000EEF9086E2D11BFEB9E552A7ED7ADB3B297
-:10F0B000EFB567BBC5EFBB6F2F17BFEF1E11E7960C
-:10F0C000000F6DFE8BDE1697CE0AF692E72908C078
-:10F0D00077BAD9106F2BC2F220E4BFC886785B29BB
-:10F0E000968721FF052DFF0CF92F687904F25FD078
-:10F0F000F20DC87F910DF9337C3C7F461DCF9F51A7
-:10F10000CFF36734F0FC197E9E3FA391E7CF68E20E
-:10F11000F9339A79FE8C00C239E13D8CE5496F2BB9
-:10F1200096A7BCC7B03CE36DC3F2ACF70C96E7BC46
-:10F130009D58B67B2F62196BFE0C552E3F04BFE124
-:10F140000A189FC9B32AA7573FF0C8BAD0FC1923A1
-:10F150001ED884721A2D6F460E7CD397123D6F46CF
-:10F16000777B94BC19C1F7A3E7CD481BFDE3E5CD40
-:10F17000986BF961F266CCAD11F33ACC5B75F9BCD2
-:10F180001923E24A6E41F9E3F238D7125BDE0C9F95
-:10F1900055E2DFE553BA80DF45E982EB750F790769
-:10F1A0000E5A9F1E02FB89AE21575D36DF83562E15
-:10F1B000A2D39BE57798F323E7CBE889AE6AFFF704
-:10F1C0002B581E87B9966F992FA3877C0B07B3BF67
-:10F1D000403B196BBE8C9ED6879EE839E347CE979D
-:10F1E000D1935DEDC99EBE3985D1B9770F7456BFF5
-:10F1F00097AE34B51EC297ED2E546D997F0F9F3B8D
-:10F20000D38EF1998E9DFC5E9C8B38ECA9EC7B7DB6
-:10F21000F0373B9E4F184EF03B7E3B7151FEC4F3DE
-:10F22000E7D2CE7DFBE05EC05A1B71252681B34735
-:10F230001CFA81B00FBBC604F19AAADD9FBEF1474C
-:10F240000AD7DCA2C7FB721D148756F4FB5C89C089
-:10F25000B778F24BDCA7C319DDA55EA1DF756B7E25
-:10F260000F0774490D9E3F15E82DB86FEADACCEE12
-:10F27000B3EAC9D58F4F188DF7C689DF81FC433FAC
-:10F280007519C7B38B106700FAEFB4E2FDD525AF4F
-:10F290002D34C0A070DE1A1A37E85524C6811ACC66
-:10F2A000B6E1706F2F5DBDBFE773B5821FBE88C327
-:10F2B0004D2911E3449F2C283A0CFEF3227719DEE6
-:10F2C000AB482B15E346847F470FDB32F03365C232
-:10F2D000EF75FAD97DCFB0EFEA9BB7209E4BFD9A30
-:10F2E000FB4B8D625DA5DB392BBF9762219698E8B9
-:10F2F000D676C5E31392BF3DDD8CE922DDCC0E91BD
-:10F300006EF14344BA68E966758A74D1D22D61AC56
-:10F31000185F53E9A6DEA7FCA1E89664E3F73C82F8
-:10F32000F42A31A5A2C9473C33E400CAB7561FFAF4
-:10F330005802F01B7E48BF64FF6A7CCB6995C16EA2
-:10F34000A533D0445AC4DE8B077D80FCBDC489FA46
-:10F35000A0FE3E8A78F22197FB8FC8255AAE987E90
-:10F36000F0F802DABA19E46D04FB3D1A18AF4A222C
-:10F37000B89F5388D30EFBA826AFC9B94881734DF7
-:10F38000E25C940DE799762C1FE4DF3B770C25B8FF
-:10F39000EF6F0A7C9E0AF7061E1CD9390DE20F9EFC
-:10F3A000C5A404D6AF59096C7D5DC64B5B028BCFFB
-:10F3B0006C28D111D768F87D4A7ABF44C76BB7BBB8
-:10F3C0005EBB01FCD116763F80D83BDFB81DDB4722
-:10F3D000E1F7E119BAFA6B001FDA1FBF2BEE68F9EB
-:10F3E000C8B630C40EB7373F7225DC6BDDA48BFC8A
-:10F3F0003D73818DFFFE1D7E3F654430DF42816D90
-:10F400000CE6657870001DA77A7A17F25195CBEB60
-:10F4100038FD0F964D41FC5E68911C10AF2BD4DF78
-:10F4200071D3308ADFB8B7657EAF97DD5F1FCDFB44
-:10F43000D79AA9FEA2FDAAFF1BFC9E95974ECA98DB
-:10F440000F71744D19DE13FCA3ADF030F02BC7D54E
-:10F45000340AE429BF2511CF713D1F12277E9AD5AA
-:10F460002ADE07CCE1F7B673DA881F84E2DA63623A
-:10F47000FBB836B17E9D66FF39DFC6F5D4465241F2
-:10F48000EE367EAD9760FDE8E824CE3514DF8E457C
-:10F49000BD71FC8ECF09FA891D5FEB8B22DD8F5980
-:10F4A0006E63FCDB642068BF379559F0DEF9FEB26D
-:10F4B0008AFEE05F7C7197BB7FA43865889F96C009
-:10F4C000BEBB772590B120876B2546EFFA8C92085A
-:10F4D000EB962A77AA1CAAF2975116E78E740FF5BD
-:10F4E000339B8472965736443280FCEC9530FCD5C1
-:10F4F000BE86E2759975DB47D6F4017C3CCD9FE171
-:10F500007D32538BE48A744FE7619B8DDD6F5CE342
-:10F510005B0DF7467E419508EC5486A13E2B127C8C
-:10F520001FD9887EE95D36077BCFC4F320C9F51962
-:10F53000709FA2BD79D2E47514CF27A83EC07AB5DA
-:10F54000497122DEBE2A42F09E2C8FD7F59D46B629
-:10F550006C08F17F37DB721B6D145EA38D7D6FD954
-:10F56000CBED94006FE77FFDC306F03B2E1A917F31
-:10F57000BDB9BFA9BE7780D3675C826B2BBC4FE05F
-:10F58000979F51E3E374DB9C8B46415C9ED23BC466
-:10F590000E06F9E663F951DC04CF3F922C3A94430E
-:10F5A000E27239ECC27D761FEA8DAA07242011C8C9
-:10F5B00053A0DA37A9450A58A9DC8F365902708F53
-:10F5C0002EA99CCE3B19F29A9818BC56F99C18D7D4
-:10F5D000A2F29803CE3DC1ABF3104805F8AADD5363
-:10F5E000EDE5DA44668FD63E24635ED4CD729B1976
-:10F5F000E2A9592E471EA4884C921D78AFA65F3908
-:10F6000071520C49FCC05F2776FB0154C9AFF94623
-:10F610003F2FD2775B176DCCDF1E97E0FE33D06BA8
-:10F62000F8E1CEFDE02E38CDA417BBFFC5ED04F701
-:10F630006B0AF97A37EE3F74EC7BD1C00D24F43BB2
-:10F640002AAD9DD86466EBFCB8EBD9BA37EEBC05A1
-:10F65000D7BD6E3B515688EBD4C8965107E09EC586
-:10F66000C80F997E126E1FECF40FD029E7B04F0F30
-:10F67000F4F9B67641CB6F123075D787EAE01C8675
-:10F68000EA5BC8FB67357664C5F441B5185EE6727F
-:10F69000D4FF1EA7DE1D4247EDFBDD714AC9D4FD34
-:10F6A000DC3110ECC8113DDC0BE9C8A5F3A3F3DF96
-:10F6B000C8F525F173FF6498D7C6961BCD20DF6B84
-:10F6C0000379F662FA4EA2A9049997485C18CF19FB
-:10F6D000493D32C88F518B4241FD41A58424A4C0CD
-:10F6E0003DB42221DE432C493CFF4B00F9D22DA72B
-:10F6F000548E43EFE5AAF2A99547557E6BE1A0052C
-:10F70000CE0721624E4BBDD484878146B2D90EEB21
-:10F71000BBEA5FD6727FAED69CE9C7EF977C19E84B
-:10F720001FADE4FE51ADA5D084E6605F32AEEB2B99
-:10F73000217E42E9B03285D979753E5AB9F45CD45C
-:10F74000137FC83EC12377E27D44CF45033E5FA7C8
-:10F75000B807C0FC55FA5CC3E9A3A58794C0F79D20
-:10F760009C2E3DE39B63877BC1892617598FF8E662
-:10F77000E13DEEA6C04813ACBFF76AF08D01CF6B38
-:10F7800013C684E3295BA2E099CCF0BC8EB8FFD805
-:10F7900046E53767455D6D3CEA15792B3D275CAF43
-:10F7A000B47AA4EA8D1AE7BDB6B2FE005EBBED41A5
-:10F7B0006F3CF18C2E4EA504EF5739F7C4A31DD131
-:10F7C000EAD3E77CFE9E7846BF058A7B06CCCFA3B2
-:10F7D000EBCC043919EE20BD8A2992C39BF5A8E72A
-:10F7E000A435B67BF8AA7FA5FA55DA7EAA5FA5DA1A
-:10F7F00063F51EFCDA04F77C9003A999CA2DC5A70E
-:10F80000D6CEF64B9B6DEE4580573CC53D0EF68D32
-:10F81000430259ECFB5F512FA2E941BC46CE9B024B
-:10F8200032AE0B3EBA2E644BE178A8E30F4A48642F
-:10F830007CA45A0EEB7DDF1CC206AB269837A7EFDF
-:10F8400070E28675ABEF48769F714D02B3BFB50984
-:10F850006CDD52CBCDB692BB51BF65E2338EFCEE70
-:10F860007803AA70DF7C6D82EB2EA087A9C885F390
-:10F87000E863274EF04BFBC84D127C379A54E99051
-:10F88000D83D7312FC7E8BC2EB53ECC8057DED03B3
-:10F89000FB6BE8DF1239CFD8A309EAFD5EE67F3AB9
-:10F8A00049771EAF471398FF7908529FF42A56F301
-:10F8B00082A9E7394E09E8D46EBD0D916EBF2031A3
-:10F8C0003F3D91D14BBB4F00C287FEFEBD7B0D4437
-:10F8D000362791E0EF59D599D0BF8F27CE26B05764
-:10F8E000BB1206F0734C671DD47F25779A128706EA
-:10F8F000E55D95E30727CC70422A52DBF55DC361D5
-:10F900004F45E57A27D0BF7D42D760CC41493A3395
-:10F9100099FCB8F442BE20950FCD8AC00733ECC3E2
-:10F9200043EDA4D53004FCD17629CE09F72CDA9723
-:10F930004A0C5FC9C4F329C9C23CD3E3997FDDC136
-:10F94000EDD53B09592827AA3DA6F3AB83523B0FBF
-:10F950008F11EF7490CE3DF1FEAD706EA5C93FA939
-:10F96000CD4F3969A105EF7F6CDC63C6FD6B57098C
-:10F970003BC7EF6A31A27D8EA6B7696DE688711C20
-:10F98000B5A4F47B0BE897A6D424823D4C9B7BD294
-:10F99000067CD7D2A543F25D7308F645AF2B11BFA5
-:10F9A000BB55CBF4F49B1217D1FEE91993B1549FC8
-:10F9B0003758E488F7CD4F73BD52E5F14A3A22DF5C
-:10F9C0000F9D06793CEF7EF31D1709DEDF6F88631C
-:10F9D000746C886374EC728F4F781AE4CD9781FA57
-:10F9E000B0583D07E5FB7F35CF943ADE46AF29514D
-:10F9F000A62AD0B0608A19D68914E29A3C1B947565
-:10FA0000A342E03BA2C7BC3B12F3318E6D12EFF96B
-:10FA1000DAD9BDE1CF3716E077DEA9648D7930A55C
-:10FA2000475989CE09F183F30BDEB7E9A83C2DE8ED
-:10FA3000D39A03F2FBBAE226F63118EAC2FDC99264
-:10FA400052833F40F996DC400D05A5CB7F03F9D4E6
-:10FA500012800080000000001F8B080000000000E2
-:10FA6000000BB57D0B7854D5B5F03E73CE3C929922
-:10FA70002433794E1EC009E19D108724BC1F4E9E81
-:10FA8000448830BC0485EA8028CF2488D6DFB6DEDF
-:10FA9000CBC444F4A2B745E9AFF4D6DB7FB0A2A84B
-:10FAA000200182069AA41340E4113408A8A8AD519D
-:10FAB00029620BC908EAC5D67BFDD75A7B9FCCCCFF
-:10FAC0004922D8DE4E3EBFED3E8FBDD75EEFB5F684
-:10FAD000DA872EC977134B64CCB7D8C0B64A8C7D71
-:10FAE00087BF1B43ADD96E602C89B196383BB54EAC
-:10FAF000E70CC7D284F07E8563693E63D5D6D85CB7
-:10FB000016876D7F3F8B85F18A58EAD202685BAC1D
-:10FB1000AE5A95B12546AFDD0ECF774EBA3CA48ED6
-:10FB2000E12FD8DF3392B12E236B94E2B01F606CCB
-:10FB30000C4350F8CFED56EDD097F0FFE1FD448B2C
-:10FB40002D20C3B8CCA35CECB0F047BE1B281E4DE3
-:10FB500066CC285E939ADEF846CA652C76721163ED
-:10FB600070DFCA5C8FB22CB8318CA99E18C6A2D89F
-:10FB700033F6F3D98C19F07D584757F3BBFD7C0061
-:10FB8000C71FFEE54A0C83FB1F29C118570E6317D8
-:10FB90001E3C15E3B6C1F507E5723FF46F4740C65A
-:10FBA00087F0926F870BA3197BC4EE1981EBBA63C0
-:10FBB000DD7F8FF1DA42F7D903703195B1157E19E7
-:10FBC000E7E6F0C27FABB65919B384FA95F509118F
-:10FBD0007DC018E1B5D2CCD6D4DB7AD26305D2038E
-:10FBE000E65DB17D8B295DC5F9BD93ECD0BFA0C0AA
-:10FBF000AB80EF0B0D317E5F66089E25DB4799D207
-:10FC0000E1D6474D6616807530A5DDC86C84B50A0F
-:10FC100009F0E61578D3C379B8C54AE3DDF57F6509
-:10FC2000BF1996BA18E67A201E9E6F5A51C1727B90
-:10FC3000AEE3AE3FA8652940BCBBFE4D623E953F9A
-:10FC4000FF601E3CFFC0235F20DDF4EB5CEC337EE5
-:10FC5000D211B16E376300CF3241EF3B1F8DBCBF75
-:10FC6000ACE9311A6729F39A909E776DD4DFBFE92A
-:10FC700033E4BB654C095D073C5C3E9265453CDC6A
-:10FC8000618F493C0F20038F8DFD0EDEDF7D6460A8
-:10FC90009C37A7277EB5F6E23AE06F33637F5E6755
-:10FCA000A1F6C23A46ED08BB4AF459DD74F27EE48F
-:10FCB000AFAAC65D261CA7C5FFA78409F04861D37B
-:10FCC000373232572173DF7B0EF0F92326B3EF0072
-:10FCD0007FBB19E79FF546CF3D48AF1BAF96D37D5D
-:10FCE000FDFA1769FC7F249EF86711AE3B17AF2B16
-:10FCF0005FF6B6AE9FE2BA809FD95858977CFDEB6D
-:10FD0000D2D6A3AD4FBB5F2903DFF5F2BEC6EF230A
-:10FD1000843E58FADCACF569808ADAE6CFFA7710CF
-:10FD20003FB1D328BF1A3F2D1374D2F38D46C76E4F
-:10FD3000FE68FA775A9F463FE07FA7C1896DC06988
-:10FD400018D7934FF47CA1E7834E63477F945F3DC0
-:10FD50001F744A6C416FEBFA37FB405AD752D55D9E
-:10FD60006687FB7731CF7A3BAD67235DBFA06C3CE4
-:10FD7000FC3394ABE7385F77EB3933973776DCE8C1
-:10FD800047BDB936464D71D804FD80CE9DBBCC3EF3
-:10FD90007C4E9BE7FC3AB77B9011F15E4EED9FD70E
-:10FDA00079DC830687EEDFFDAB2BB12ABCDF358C17
-:10FDB00095A3DC77C644C2BBCF2E133CFB900EC884
-:10FDC0007F4AFBFF7C803AE9B9F631A847CF7FFB39
-:10FDD0005FB11E78BEEB5B73796FEB3C2DE807EAF1
-:10FDE000E5B413F8EC762167B73755125D963C33CE
-:10FDF000CB84FCCC1EE0F8B4C01FEAD7B6A8D86705
-:10FE0000711D8B1B24D2237A7ADCE59AFA39EADB5E
-:10FE10003BFD85F47E0FFAB0C789BE77213D86850C
-:10FE2000E831D6A1727854F803BEB943F0CD7965B4
-:10FE30008DC9007AE4FC33806F007995C2DCBDE99E
-:10FE4000C1FE0ECE877DAD47BF8EBEE05FF65CCDB6
-:10FE5000FA3486EB1F654AEB45EF68EBBF8BB9625E
-:10FE600049EF88F5B28E1B495EAB2D7C5E6D9D2BF4
-:10FE70009AEE9C817C51B519E895D973DDA8771766
-:10FE8000F7026F997CD16881F7BA1E905CA86FFB6E
-:10FE9000A283A627EE12F85AB96DF10C349A8B6141
-:10FEA0003E3913F5D1176FC624A25C415FFA1E7A62
-:10FEB00035C91F9B711D8CE37B09E07B8374FDF4C6
-:10FEC0005BB6B9D03D28ECB915FE9BDC83C2F59931
-:10FED0008EAE6CDBACD0F364B7DD26B4C7F10EA1F7
-:10FEE000BF845EEE5BBE60E100E7DA1D0EB26F6CB0
-:10FEF0008D83F46375D31653B8DDD5E44B93B7B156
-:10FF00000E3BF15955E313F41CE85FD501FD4A4B54
-:10FF1000C7CF6F55C3F0394ED051AE30A1FEEE4B76
-:10FF20007F82BEF9B2236C9D231CC2AE08FD7B2DDF
-:10FF3000FDA0C1AD1F57D3071ADC1ADF6BEBD1F35D
-:10FF40007D5FF0E9E9C2989FFB0B3AFAAC427A84F4
-:10FF5000F5115E05F0DBD66CF53F04F0B6491C7E6A
-:10FF60005F7314C1DFE92C769F033FAF2A7521B57B
-:10FF700027F0C554F4EB3CD3109F9A3FC70A1222D6
-:10FF8000FC247DABF93779C29FDA1BE5CE07130954
-:10FF90003F4F02F2C3949A8E391620D9AD8EEDE50B
-:10FFA0000A8C3FE5898E3951D05FE8D8C1FB5B3BB5
-:10FFB0004E595C8CD5B057CA4BA07F3BA013C7BB32
-:10FFC000565B60F62C44F95D0D7E9205ECD1EAD3C8
-:10FFD000430EA1DCAD6EAF2897C0EEAC0683238143
-:10FFE0003DAA74C706ACB9D46713E0B9E7EDDE6586
-:10FFF000C42F57EBC86EAD3EAD70B9399248EB5780
-:020000022000DC
-:1000000000F62878AF2E1AFC55C0575DBCC5559B2D
-:1000100049D77D51F1D877AB6AD8758D1EF81EC2CD
-:100020005167606E07B4AD4787C4757C8FDD6E5D28
-:10003000C72A14E08383EB2CD4EAEF179AEC83D021
-:10004000EE151A98B7377DF9A483FB8DC0E4E94813
-:10005000E7AA23269277FCA11F5829F451151028EE
-:100060000EE0A93CCD02D1B1F85CD9E70AB60D1279
-:10007000FB24C25F61A1BEDC37DCD7DB56E17883AD
-:10008000C3F984E3A948912A94B0794B6C51117D4E
-:1000900039C5300CD7C3E468D756C0AF9C6E58B38F
-:1000A0001BD62F0F8016F0A1D85DF2626837164F6D
-:1000B0009197405B6BE476B5D6C09687E3E90581FE
-:1000C0001FADFDC0E1D98A74BFF456FB182BE9AB14
-:1000D0000C3BC9B9586FADE40A50DCD4CA5C5BE193
-:1000E0005A9DEC619C8FEB19F2F11B621C97D9B001
-:1000F00047057E6D747C40FCEB8A33DC9B09FDC0B8
-:10010000131FF17EBAE14A26F0F781273ACA15900B
-:100110000757B6E1CA40E81F7AE2637E7F220C09E6
-:1001200006EAF0139F94FB6C382ED7676CBB3B1B21
-:10013000E7510C12C9A972C0E4AF85FFAD8BE5FC95
-:1001400054073C82FCF786B0B3EB6B8A5EB602FFC5
-:100150002B456E750D8CE3C78069F4DFDF6A7894F8
-:10016000AD068A53B0457CBF29D6ADD18135B8B331
-:1001700067A15EA87767CF8E41BC7A4F225EF3DB22
-:10018000DAA7A03E6E78FBFD31E8AF22BD709CFC83
-:100190003688DD603D975EEBB7450E8B473F7014A8
-:1001A000BEE3003996DCDC9F94543B5B047257EB52
-:1001B00066AA09D695A28BEB1A18D72FCFDB3D7F05
-:1001C000C4F7584680EC4DA1C3FB31CEAF8F5759D1
-:1001D0007B7CAF7A59AFB74CB90FC8E8E7C4A737F3
-:1001E000BEB704F5FBEFCDAEC12AC2E5660F003CF9
-:1001F0003B0D4C61F1C426C394028C3FA35D1B50A0
-:10020000EE5DCCE90339C3308D80845FE298B0B8ED
-:1002100055AC07DE2F61D08E45F86EA0F5C9C857E2
-:10022000A3984746FD3586F9ADD87635BFE644BC80
-:100230003D19C5EE40BFCFB28DB9FD61FA63403CB8
-:10024000F7F726251809EE6863FD6CE4D7E82F98C8
-:100250001DFDAAAEFF3429383E08C874BCEE3A6CC6
-:100260006008E70B46BF3D0EFAC1E18AFA2C0B8D00
-:10027000D725E8AD8DFBA4491DEE407D93C0FB2F33
-:100280001472FB1CFCDCE47F3613F16359E30F931B
-:100290002F673CF75BBD4945F1F1D0D63747339C1A
-:1002A0007F6C4BB401E9F0F2F6BC28E4879D881B13
-:1002B000587FBCD97E0F8E177F05E0CDA4EB6EC2B0
-:1002C000ABA28E8A03BC4E9866533700DE5F88AAC5
-:1002D0009F86FC1FDC6160CFC2143B4DAE59D8DF56
-:1002E0007959B5A3BE7D21B33E9AD6B3C340EBD9AD
-:1002F000191D1CB116E0DE304C2947F8142B535061
-:100300000F2B8622F51EB83E349EDB574D2F2F88CB
-:10031000E7F2F3A404F3E7E17385243FA5B28DE48B
-:10032000AE2BC8FC669827696EBB8CF4889E05AC22
-:10033000847CAF046406FD491E46498D4936A35F9F
-:10034000257DEBB62D06BA4F11FA76CA87AB2B780E
-:10035000DCE33A3D11C63B6833325CD764D621A357
-:100360003F38F92A7305907FAEF278C60E7FE83FDA
-:100370003DAFF3074BC578EEA0BD042F17B2483F41
-:10038000AE7473D9E712CDA32A68A78B2DBAFBE808
-:10039000E7C5621B193795C50BFFA63FEBFF1DE9AB
-:1003A00037E05E98EF3E3B9FAF54CEF915AEAFAB52
-:1003B000DCE4423CECB2B9DF9D887AB1DDC8B6B26C
-:1003C000BEE5E979883FFDE0730CBB6A65FE7CE21F
-:1003D000471BAE67C4E68DBE2858F788417C7CE495
-:1003E0003BD42343FF333101F5F855A15FB456E305
-:1003F00033E4277B1CE727FB0D2139BC333E939E5A
-:10040000D3E40AF90CC7D96FF42FF4F46227813FC3
-:10041000EF44FEDC656314473D966A598072A5CDB2
-:10042000F3BCE0637DBBBE666DAB11D7FD15D80391
-:1004300080BB24EDAA29DC9EEF49E27C552A7F4B44
-:10044000FE766793C4D0CF4F6EE2FA3B9C3F527B5F
-:10045000E78F5F225EAFC51F5ABCB0FB87F2C79122
-:10046000BF8F3F365C933FBE8D453CDCD75C9CC262
-:10047000BEC7BF6914FCD0D7FDF156AEE7F4D75F15
-:100480001178DD67DA383D17F5C0CD0617CA395047
-:100490003F7D36AC635F347F8F296BB2B0BF4BE1D9
-:1004A0007A65579399F4CA2E9BD74B76DC6961E83D
-:1004B0003F30C5DBF133D4876916754318FF2E8DA5
-:1004C000E7FC566F0C8CFF0CFDE2A39CCEE36ECED6
-:1004D000934DF05CEA522EE705174C5B300E2B4D26
-:1004E00028DC817C74027516B4D5E7E029407CD500
-:1004F0003913E9BBD75A4E96617E11FC1E37F2D9EB
-:10050000D8FD27CB8A72F079AE4FF78A56EB8FC7AA
-:1005100035C5B3EE78D723ECC678C6F59207F92433
-:1005200037D4676E23C56B1A3FD447033F805CCC3A
-:1005300067AA3116869C73CEF330984336A73C9257
-:10054000CEF303D3283E9C7BBAFD55D0CC6C9E479E
-:10055000775FF0C17C1D1F809D3D1E8FFED2F18014
-:10056000C980F399D664737F684D16F293264FF4D1
-:10057000033CD5FF61D8B31BC2EC7B6C0297A3C7C9
-:100580005D0ADDF77598FC83E1D2BF33FE5EBDB036
-:100590003F9FA33C63FC70DF2B0BD18EE62F771FB0
-:1005A00044FC4F4F92E9FA2F58C09285F47129E428
-:1005B00097D51BD5E2CFA4D0734CF10CB3C1FDFD90
-:1005C00049D1F9387F6982F722D28929C123F8DE1F
-:1005D000D80979F9285FB6517509688F34B801AE2A
-:1005E000F2ADB6101C1A5C67055F94262CBE88EB32
-:1005F000C7F750BF347E7CDE82EF6B74AF6FFE8234
-:10060000D33B8CFE48EF10FDA53BB0AFE1E12BA141
-:1006100057B4FE3F4A7F2D7F704DFA637E20F6EF80
-:10062000A2BF352129447FF0B3E2B1AFF7B3EA4D61
-:10063000E077E7F4BC5EE828A4E75D265821FA5588
-:100640002D1077A23C7A1DB42FB0C7CEE7EAFAC3CB
-:10065000F9FEE022B2C109F184F76A537008FA2169
-:10066000A30212F985A340F01791FF95417ACF2597
-:10067000F0C4CE4BD2F961DC45FF2E1DFDC3400214
-:10068000FA51A3CC1501E4F7DDD629E9E8D7E559FD
-:100690002765215FBD3AECBEE368825E4D5BBEE735
-:1006A0003935E4FF68FAEDA018569BBF2081EBA115
-:1006B0001B41DDA21F882E63381C9A3E47F2201C86
-:1006C0005260BEE13B2BE9E5A60EA0C78D0807E00E
-:1006D000A155620DA8CF0B0DEEC462F4D392020AAD
-:1006E000F7F7BEE98FF9C18AA637DE43782B703F52
-:1006F00004E35097F162773E62604F3F58F357B47E
-:10070000B840F367B4F813FD1EBC3F405CB79B01D3
-:1007100040B447018BBF06E67FF2B23ADC2DE456C7
-:100720008175548875CC64ED0417FBF6BBEF260188
-:100730007D66087C541C81B83117EF337633E0E1D5
-:100740006685C79337BB207E0CE3A399E322FBF8B1
-:100750009B921C1AE75ACFEBEDC044DDFECC3FDA8A
-:100760001E017BF409B8CEC7D6F1B874C240D9A730
-:10077000A0E11C9769407EAC16F60DC2E85EEDD292
-:100780004BC22F9E60E8C875017E5BF7FF8DECE0E1
-:1007900081FD7F7B07FDBCF19F2BCC0CEF4FF8BC9C
-:1007A000200EF5041BA7125F69E356FFA9C1CAF822
-:1007B00075E2FF2AB1F6C3008F7B28C267A1F677E6
-:1007C000179FDC84E37D794EE1BC2DE62F3379075A
-:1007D000611EBBCCC4F3018725EEFF68F70F1B0138
-:1007E0006EB8BE2941CB0BB493DDC79F398CCE3791
-:1007F000633E202F44D79B2F947FAEE4F6A40FFED8
-:10080000FE37F2015A1E60ABC01F3B78D6A4025CD3
-:10081000531BEE51D0BF9EEA94993B6CDE9B542B48
-:100820007387E5039E49D0F923075FDC3403EC4965
-:10083000759BEC8A42796DDA753C17FBEDB2CBDA29
-:100840000B1FE9F13BB5E91E05F9DF98A8927C5F23
-:100850006BFE0923804F6E40BA33F2EB3AC748244F
-:10086000477AFA1ED8FFEB848E9CBEF1DD17FDF5AA
-:1008700074F8DDC522DAEFB9163DF47CDB02EBF447
-:10088000C1FA02B04E1FF85D07D6D9A97F689D93C3
-:10089000FA1ABF5637FF3601FD368D4F4B1338DF3E
-:1008A0008CDFB72981D942F4D2F0F5A1B0577BA3F0
-:1008B000347FC3356F065C3A05768718D4C7DA9D56
-:1008C0006342F66BFEE932F23734FB355F5E544A21
-:1008D0006A53D82F4C23A35ED3DBA9B9EA6223EB7A
-:1008E000CD3E2D88EC97B76D5462A867203A4992A7
-:1008F000C087F0B33538CE300FC1A9A7A706971E21
-:100900001E6D7D9A7F3D5FD06FCEA04C23C2DFC3AA
-:10091000AE8A75E2409887B85EBBFAB58E9FAF5C31
-:1009200028792BB717BEED8B7FF5F7357D508613F1
-:10093000E451EB43BFC298984C742BBB6A626EB013
-:100940001B2C238A7D1A665758C550E29F7B851D54
-:10095000EE8B7FAAAECACC9B1FE22363E31356E45F
-:10096000A37DCA462BE62727DB66D5C6019E4AFE35
-:10097000543417FDBCEA0E03C3145669D31707316C
-:10098000AEAF7E8FB9502F1635B51623DF1D52DA64
-:10099000658AB3BF64EC89307FB1B1A9D68AFE54B1
-:1009A00063A24C71FC6107E74BEDFE9644AE3F1A23
-:1009B000CF5D9EE1EEE5FE1971BFE4E33CE2A3B238
-:1009C0004741AE310E4D8AA1BC4489649F53817E5C
-:1009D000C84D46F2F3218EF923EE035E6A34EFC26E
-:1009E000D47E69E323F7D88110F5FFFD698D19F3F3
-:1009F0000BB324D7B3F05C991A6CC57ED9DC4CAA32
-:100A00007B18FB3F32F9B3C15B25CA8B9401BB60F5
-:100A1000BF6C51A61FF313FB25DEF735F37D02668D
-:100A2000F725CC8079DEAE4818B581784AEB0FCE39
-:100A3000DBC0042387C557F7ED9549CFDC572AF96A
-:100A400071BFA9D49ECE7C617C55F6A889D635BBF2
-:100A500029A508F9784EB9CCFC61FC1D107EE13C5B
-:100A60000FC4E161EF1D8EE270051703DC52486E82
-:100A7000A7093E9FC5B89F387F4142C47BF0C62D71
-:100A8000688F6E6D8238157AD344FC7AAB373D623D
-:100A90005E0FE37ECD09162C8983F1FB250D24FE24
-:100AA0009B11B48F0EA8A877CE24A25E63C3B89C16
-:100AB0006872572AAFAE237E70F27DB279124893E6
-:100AC0008CFA2F529E668E8BECCF72F7A8378890E7
-:100AD0007FBD5ED7E47E5EB34CFB72F30A2517EB55
-:100AE000453FE8FDECB1D17DE8856FD587E37AD34A
-:100AF0000B1F96FF5D7AE135082BC681FCFE345151
-:100B0000E8877EAC1FEA875279FB26E4972EB07700
-:100B1000E65EF845B3175A3C5E06F24AF27E91EF64
-:100B200067945E4D65BEFC503CDEAD2FC09F70F5F6
-:100B3000E2E73C9D984572D4AD5F34FD11E64F1855
-:100B4000C7FCE3FE4429F891A63C842F83E02B6385
-:100B50003C1F588685439897737E41F9966A88F3BF
-:100B600029DE67BF25B850CF49F12139D0FB195A8A
-:100B70005ED72AF2087ABEE8CEF3CD35521D8CC678
-:100B80001765762E1F657365CABBEBF9449B4FCF83
-:100B90001F015D5EE69AFC21E4EC87F24773A2D860
-:100BA000571DC4065D0F5F68FCA0F187DE8E1CD365
-:100BB000E567FAB2236FA21D19DDB71D797D989103
-:100BC000F4B5DE7E68F6E277495C2F6724F27D8E0D
-:100BD00069C3E7D9D0EFB026F13A0DCD0E75E7978E
-:100BE00036737E78BD638922A13D41BD9019867F11
-:100BF000916FD5F8AFEA5189F28D15422F7536F312
-:100C0000FC5B7589ECB7C0FF16373DB189F78D9451
-:100C10009F2B545A150B8C3BD325B930AFE316F9F3
-:100C2000BA196E89E7EB5C91FBF42D3AFACE117C90
-:100C3000349305EBD01FD7EBA53957B95FA0D74F39
-:100C400073C4BEFB1CDDBEFB554DDE07B001FF4C7F
-:100C50007FC09CF4FDFE80F6BE46478D7E2AEEC521
-:100C6000A11C1DFCC6A4C670FF19E937F5AA42E312
-:100C7000D893045F0A7FE6CB8B79BFA0984F3C5F87
-:100C8000DDF485C93BB26FF8AFE5B7C6A29F3E3A27
-:100C9000E4B76BF34E53184B47C74C674F6689EB6D
-:100CA0003FD47E0CD7AD43A383A6477BE059E8D958
-:100CB000BEE8742D3DABE9B37FB69ED5C6D7EC80B8
-:100CC00036AF5EFFF615B769FA74FD1603E54B26DD
-:100CD0008BF878B2C8C3CE4FE2F1C1AD493CEEEC1F
-:100CE000FACA62407BB9B385FB272EB3FD38FA05FB
-:100CF000A17C1FA7E7C331CC87FBEC4C69B7D0BE02
-:100D000067119012F73DD3F8BEE77625E0213DED5F
-:100D100052580DC8C9397C0FE679F8806F21EAE98D
-:100D2000873F1962A0FD7725D08EFEC9D83C85F695
-:100D30008F1C6695F2C19DCD663BBED7B5EFFFB463
-:100D40001A719CAF980B43B843CDE6EEFD1BD40758
-:100D5000A5729B8CF9FBAE20C8083C3F6941A018E6
-:100D6000E3A0C9ACBD16E57B02D2B117FAFD2A4952
-:100D70008BB37BCFEF1737733FAE3846263F6E8A73
-:100D8000AFBD18F7ADA62892AB169FD5E5F75FD19A
-:100D9000C51FA1FCBEAAF0FA435DFEBE91EB99EB24
-:100DA000CDEB4F40DD067CBC5EE373A16F581FF9AD
-:100DB000FD9D26BEEF133C6964E807B30B89BDE6D1
-:100DC00063AE95E7DFD712ED5663719F8EFBEBFBA9
-:100DD0005AD2DC6A6EDFCFE776048BD03CEEDC3E85
-:100DE0005BA1FA35911FEDB17FD2C7FE88BBD17EE2
-:100DF00008D5695FFB21C55FAA94F6B95EBC697529
-:100E00000B4CD43FDDC8B49F9BE474E7F96837F21C
-:100E1000F9CEF3696E84EB79C1A71ADFEF3B77391E
-:100E20009AF6414D6E15F78F830E8BEB59E25BCE30
-:100E3000EFF5A943FCB84FFB1B21173BA383C7B2B7
-:100E400013C3F73DF83E47CBBA47679F33D27EB90D
-:100E500084F9486D7FD9077243753DF18CE20F2309
-:100E6000AB67386FAD9BFD1ADB2993D438C4FBE523
-:100E7000446D1F538DA33CC4B757A8CE508FFFDDE0
-:100E8000EB9807EB511AD6593C0AC8FFABEBECD4F0
-:100E90006F5CE7A476FF3A95DA878EC73E8076BF0F
-:100EA000DA6DF22861FAE39D64EE77E5657F524CD6
-:100EB000C5DF7F6354873EE5C10E19F5C58D5761C7
-:100EC0001D117527CA65C437E537B342FD4C6971FA
-:100ED0000CF66FBC0AFDB0E7AF2439B83DAA53EA5F
-:100EE000462793B4105FFC2DC9DD9104D7EF7178CC
-:100EF0003EC176B734FFE02546FD73BC7FAB7C096D
-:100F00009ECB0F14525E391FF3CA7934EC42C4DF12
-:100F1000E85613ED976BF9DD3C4DFEBE8ECC33E702
-:100F20008BBCEEABAC83F2CD051608B40C0817A74A
-:100F30009F5B9AE794301F98647261BDC3E82C4FA1
-:100F40003EE6635B9318C547ADADC9196A0E720FD3
-:100F5000CFFBBAB5BC2FFBFEBCEF918F627DA4B76F
-:100F6000AE9A687FFAC8A9585780F60B2DE4FF693E
-:100F7000F5C82DD1BCCE80652CA03CD38DA29ED1CE
-:100F800062F69A93495F050E9E80F77E7F99F17D08
-:100F9000C7F60F695FBBD8303C05EB7E0F4A43E3D1
-:100FA000B07DEAA3D81C6A4FC55E44FCB418AC2AD5
-:100FB000CE7B669D5A82756D27D6B112AC637B6B72
-:100FC0009D85DA93EBECD49E5AE7A4F675B88EFCB7
-:100FD000731C9E477E71BF65A37D92296FD9146CE7
-:100FE000F316C650BBFBB61813C2DB12CBB66BF3BD
-:100FF00060BD5A203AD080C9FED6A7BC8F59FA816D
-:10100000DD337B474AA3186B7BCA3B5D990CE34EEB
-:10101000EDFF93AFE0FE9BC9CB1EB3005C734FD9CD
-:101020001ADAA0FF76F2F2C76CA86F8F4783D2C39B
-:10103000F5AE38EE1E047443A590C605978D837EE9
-:1010400082D65F31BD641263B71477643360ADEC50
-:10105000E495D32D80C75BACDE1F63DFE44B9A5E63
-:10106000D20FFBCC87F56041C948713FCB9012B1DC
-:10107000FE65A6C3FB467258FD9E5BFA13ED338DE9
-:10108000714BCC41871F8CB4EFC5EC1F2784CBDBA1
-:101090004C47E91B488F89C9BC0E78F424C91D5EF2
-:1010A0005FA17F6EF439B504E934E642591DB633C9
-:1010B000CB1DD4F72C185B87F25C62EBEBFD627AF8
-:1010C000BF3C99D78D142952445D89FEB97C6026B6
-:1010D000F48F8347A3294F30FAB4B716EB4F4B9DDB
-:1010E0009979B2A6FAA8EFD882FB6DA32BCE9424EF
-:1010F000A0FCD824179A8931ACA32E01EE17DAB1DF
-:10110000A00AD7F54431D6FF8C562517A2ADD0DD05
-:10111000DA80EF17BA625C85E88F9F564BD0F49C5B
-:1011200052469D2880E7A60E925D1618E854E0A668
-:101130008997A05F382C8EF2BC85CA9A2B27A81FEE
-:10114000E3AA51711D5B7E5D45E398C9AEEF9E51E8
-:10115000FC2FC83F459E38CA09023E4AC2EBCA600E
-:10116000DD0477A15DF64749C8DFFF5A6287FEEECE
-:10117000FE1296CBC37CC3FF42F78F44AB5100E80D
-:101180006E93BD04C7DB6D92EC0F51DF538CCFFB28
-:10119000861855CC1F952546458C3FB5441A7F0EC1
-:1011A000E1CF891B85D7CA331C11F7DB6EB3929D43
-:1011B000A8782B87FCA2B6DBD2C95E54BC35A9083F
-:1011C000DB3603F7D32BDEAA28A7FB061E07572C16
-:1011D000FC915BF429EEAD585849FD5629E52738B6
-:1011E000DF959CB83CCCAF4D1B945AA244F88103C8
-:1011F00049FEF3447EAFD0307CD32480FFDEA37C55
-:101200009FA2222733E2F91905524978FDA86752B7
-:1012100054447F7689A324BC0E756E456A44FF96BC
-:10122000B99911FD92A30564BF410F5494801E38F3
-:101230000AED5260C1025107A5E59F0A054B15B69C
-:101240008BBCACC2E3EB61F0877AB0C41669A777B8
-:1012500047733B5FCED6D00649F911BEBF5D966895
-:10126000FC24DC4E94CB15365E97158987BCA346CB
-:10127000B2977931921FE3FA92A34BEBD0F49667C1
-:1012800044BEAFF961E5023E6D5EE673B7A33FA2CF
-:10129000C1ADCDAFC15F2E2F2AA17CF735D6A18776
-:1012A00097C17A503FE8E1684A16FE1AF81FE4AF8A
-:1012B000897324F04BECCD7E6BFE7A05E82B47B8A2
-:1012C000BEB2498958B7D797BED2C6EDCB2FD3C689
-:1012D0009DE9F0D0FBEE1D9F9E9A2087F5333F4E8F
-:1012E000880FEFBFF8E9A688FB491FCF7184F7B7D5
-:1012F0007E3A07EF4F51D45A1BF0E53126B97CC82E
-:10130000076DAA1203F4283EEDAEC3B6F4432F9640
-:10131000ABB2A9E77C75D84EBCE86F33C3BA6E1A7E
-:1013200026AB18BF6B7E881EDEBF26F3BCC3B1ABF5
-:10133000AA15F75977FB542BFAF3BB1F54ADE88776
-:10134000EC76F37319EE2C039D8F7167F37AC5BFAA
-:1013500024F3BA834EF1BED6FA8DDE4E841BEBCC5D
-:10136000D137A8FA264875E5C7D0BFCAE9E95F1D9D
-:1013700053FC369CEFD8837E5BF87EE2F5FA577F0C
-:10138000041E43380A99E409D723C596284FB8DCD0
-:1013900096DA1D11FD93C20F99EA4C8D78EF263530
-:1013A00033E239F01B87A15F526B62546FEB33F06D
-:1013B0007A5B3D1E57A4F0F8CE65B3A33B83FB6672
-:1013C000726FE7915CC5865ECFB7A5A4707FF03FD2
-:1013D0005218C1352B85C3A7AFAFD5F76BF17C0F82
-:1013E000E293B99CC8E72EABE10AB8BCACE0E927B0
-:1013F000A6535D6DBEE1DE2CE8573CBD753AAFAB40
-:1014000035ECC13ADB194F3FCFEFDF60C837823F81
-:10141000B0CDF7C274AC2BAF8AE2F5095551A23EAC
-:10142000B46E7444DCA3183E7E6A21C69FFB8D0C0B
-:10143000F3FC8F99C00EE685F6D9AD661EAF5A4D06
-:10144000BC0E7C7DE6A9F5A83F3E8BF2E6A5509E3A
-:10145000B148453C5EB45BA83EF4BE7DA529C807F3
-:10146000B35278DE2B7BCF44279D2FFBE7C151FC85
-:101470007D7060FD308E73717736F9E5D903189D64
-:1014800027D1E801E1335D8F82F081CE6330B7135D
-:10149000F36FB50E138D332B85F3E3F5B63DEA8973
-:1014A000E30C6B7641BB2085C7CDB7E2BC046FB0BF
-:1014B000FF2CDCD0B307FBCF1EC9FB486F59CE0B06
-:1014C000A27F1BFC510CEDC3BC1FCDF1C63282B410
-:1014D0006FF3EEA26CD706BACEF1B8C03FB0B643F8
-:1014E000C5FA0F7F3FACB718E8F42E457CDC66F6F2
-:1014F0000F26BEB2AD89C179AEB7DEB8EFF921E0F3
-:10150000047B327F3CA797363FE0D882747C579C9F
-:101510003BD1E001387E8C70687075C3A3AB3FEFA0
-:10152000147E7B278E971BCA5357FFC940798A6A5E
-:1015300009F424F4F77CC85C3E95E8437950DCD28A
-:10154000C2F9C69F58526C83B6A071158F8FDB9578
-:1015500088BC9866CF268AE7C7BEA744D8A389224D
-:10156000FE1DAFCB4F4E6C9C4EE7F826EAE2E25FE1
-:10157000A488BC651A4B0BCF23AC15F1C6E5B68128
-:1015800071E89F2A10E7CA806F932AB371F121BDD9
-:10159000D0B08E459C53D4F870E469FB9D38DFC809
-:1015A000D3EC0EF207B471BBF3131C2F97DFE37873
-:1015B00019D531ECE949D0371E3132BF1A5AE70448
-:1015C0000E2A833087E2A4CB176C645FC61C9D4350
-:1015D000F5DE66A781A961EB8F52A3991AA62FADFC
-:1015E000C3E223FAB2A04F5D54A41F902FE6897185
-:1015F000A5458CB73FBEEC08FA05F9B6E5E417C47B
-:101600008D1B18311E6B5322FC833CE67163DCE8B2
-:1016100002FAE27ED998D34A841F302EB091CEA12F
-:101620008EFB30F2FA847391FD037DD1A52FFCB1BE
-:10163000DCA7D12FFCA1F873B823F197501E89BF06
-:10164000244F24FE521644E227D51B898FF4E5234C
-:1016500022EEF75B9317D11FF0C08488E733C18077
-:1016600085F7B31E9D16F1FCE08DB323FA4337DFF7
-:1016700016F1FC70FF9288FBD9DB56FE207A8FAC06
-:101680005F1BF1BC9EDE3734FE34627C8DDE3EF89B
-:10169000FBDFA437730AFF50D03B51D859879BD743
-:1016A000AD75196D8FE2797C3C3682FACE81E7E91F
-:1016B00063D1FEAB5497E79BC6685FFB97B2474286
-:1016C000BD940EA8356451BD3CD5F5FDDC6088D8CD
-:1016D00067B73BB93F6477723DFE6B133F2F950EA2
-:1016E000FE26D929030BC5D916AC77648299AC8F35
-:1016F000639C5DE7E818A63A306F07FDC921BDAAD3
-:10170000E9D1DBCC6A6D07E8975132D793A03FFB54
-:1017100039619EF7A5078DDCFFF019D1FF48B7307E
-:101720005F6C1ED919CA433B58A284E700E2427A93
-:101730005CFD0E88757065369DC37A134140BF59B4
-:1017400075D17ED3AD9A9E5A3E9CF4D4655BA4FFBE
-:10175000767969165D3F7BBB99EA07CE8A3A470DD9
-:101760000FFAF3D6DA396CEDFEF22D9B62D0EF3C26
-:101770002BCEFF6AD7270BFC4D76CAC2FE59D66026
-:101780003E6C1118F138C07BE5918ED8DB18F99BBF
-:101790009370DD555BAEDCFE2AF4AB0DC1646E3791
-:1017A0007CF4DEFC77F9B9EEF97F8BFCAE408593D3
-:1017B000C7F91562FC5BA0B1039E6E013A38B07D9B
-:1017C000635219F2275CA7F371338F3023CAF32CCD
-:1017D0006F26D54D9C62AE337B01C4F94E95E09CDB
-:1017E000CB3C46CC5BBD737B650C3ED73D9E360E35
-:1017F000300CFA25EF3A7CC664CC1B4CE6751330EE
-:101800009F05AF7B16A53F8C76499BEF1DE6BD7407
-:1018100006E83B9BB9685C6D7C86E9F9303DB57B99
-:10182000F9AA8F1260BEB5470D948F58DB6CA6786D
-:10183000AD6BE57FED780AEEDF91DED10FEDF6FBC3
-:101840002BFF3604F9E1D6CD325381DEAADD7BA72A
-:10185000336C5FE5ECD22B31781FECEED6A7D05875
-:10186000BE6CA63AE2F757BE3C24DC8FAD74162E50
-:10187000C7F7D8B8EB3BEF58FCD2F014AAF712FC2C
-:10188000B442F0D3DA178792BFB536A69B9F787F14
-:101890002BAF1BD1D67146F0E3CA97BE89F8CEC4F0
-:1018A0006EE023D5CCF7C5D4A160EFDB2EE7D2776D
-:1018B0001F8CDE7F75C2BC2D573F89C5FE9E37FF4A
-:1018C0004AF0B3B9D7072FCAA26F4C687F5A3BEFD3
-:1018D000B9A029211FE90E72B601C7BFED772F5EAF
-:1018E000FA00F1D3FCF2D69FE133D779FE739796D5
-:1018F0007714F6C625F001F686E28B2E16CDCF932F
-:1019000008FF46C11DF92CFA9E874A7CED66C77117
-:101910001FA7B6D5407526B1B8091496AF8B950DA3
-:101920009A51725B9CA0AF859EF97FCEDB2AEAA814
-:101930003E20D21F2A38B432C20FF2C05FAF7ED031
-:1019400033DE5ACC2FE9FDA1F101C36253DCF7F875
-:101950004587A6F5EA174140ED96C688AD21F835D2
-:10196000E8F4F37E2157F53816E6FF03D1FCFC338B
-:10197000980EF47B7F9ACAF5B72D83F1F36952E78D
-:10198000300BE8CB16E7A2C71F856B96417CDDD8EC
-:10199000AFA53335F9C47FDD7ED7A111A4B7D8B781
-:1019A000301BE243E43DF4742BC0F3ECF961722781
-:1019B000DE0F1CFE6B2CE67D77C4AB6F213D8247AA
-:1019C00065DAFF89523A4C8E5EE2BB57510F029F97
-:1019D000CAA9DC1E581A797ED1A2BA19C60F51764F
-:1019E000FBA8F0737F8D4E1E4F561E7EBFBF09E8C9
-:1019F00071C9D0169B03E3AFDEBB3B16DDFF0C9332
-:101A0000F703E4C35567DF1E63A7FCCD96FE180FEE
-:101A1000D607F87730462ACCA7E4F584A37A332C8E
-:101A20002601CFE927503BB2297F19F2597580AFC3
-:101A300013C7C642BEE18D12F53B1B6BE371BCEAD6
-:101A4000DF37A7A13CBD9CC4E3CD97AE66F3F71585
-:101A5000A6E0F341A74310D36FC0F8E46511D77433
-:101A60005E95E9396DFE918D85B21DF82127B0F1A3
-:101A700000C5514D6615E91AF51CE378688A22B94C
-:101A8000AF6E99CAD0EE7739984B82FB3BA2837F29
-:101A9000A4F36ECD6615F3AD51F68D2C1EC6DF2175
-:101AA000F659870347E17929EDBA365F54D3D31845
-:101AB00073203F50DE374AD9C826DBC2F11C437879
-:101AC00076A4723EDA111D30609E253898B1670900
-:101AD000AE109C8CE6D5E01CEEC7F3843B4CC1F302
-:101AE000786E06E0B223FD87330E276B1AAA629E3A
-:101AF00020CAEEA67544D955974FEA0957752EF3BB
-:101B0000A35DFFF943AC5B6E518EABA3437D0BC865
-:101B1000C08E814CC8F9CF1F2FC908EF83621917F7
-:101B20007A7FC8AF363E5E3789E2099F8CF12FB4C9
-:101B300031F1B84E95D6A7608A298FE301F7DBAD66
-:101B4000167EBFFB79E06F1BF66DFC39579CDD3AC2
-:101B50004D2239E1F5B8421FDC2705CEDF08A4FD90
-:101B60002A702057055856BFB19FF87495A1E9A96E
-:101B70009170FFEE28AF2B15E67BED43039D6BFDC7
-:101B8000F38B51FE0AC0C7B07D5B92DDBDC8877E76
-:101B9000FC47DE7BE8C974A4FF3E49C53C6C973125
-:101BA00048DF37A96AFACC44F50D8D1F53DDD39B6E
-:101BB000A9DE4938CFB8C61ADA8F1ECF36D27E7466
-:101BC000B6380F5EEFE4FAE3F2E921CFD684E17F85
-:101BD000492A972F16F40E40B96912F2D9827E0A6B
-:101BE000B47B85BFB4B7F5D62C352C7F58C30EA473
-:101BF00023BE1F6287A8D5AE77F9F9B9CAEC772C56
-:101C000077B8C3F86F9190F745A9224F96EA9D8D5A
-:101C1000F0AE6AFDC414ABE23999FAFE6857EAC126
-:101C20009FB2F782976EB9D5C951B51234E1F3D599
-:101C300017F8F957A0731D9E3778F99DC6118BE1EF
-:101C4000FA5EC035D695FACE9AA9BE72AFD1938E00
-:101C5000CFD79CF93A17F556090201F07CDDBC6A32
-:101C600000E20DF8BE281AE56B17233DA6C9670EE2
-:101C7000CA27BC9F837C5F80FDE1A4877798DAF94F
-:101C8000F9D3BDFCFC29F03DC901F0BD1DFD861C4A
-:101C90003BC801BD3F94E47B47BB81CEC9FA408F6E
-:101CA0000FA67ED11CECEF682FB1937C635E3F0FD3
-:101CB000E5347080C6A987D8044927314FB83FD989
-:101CC000E88C25BA69FAF1B093093BA1C6E1790322
-:101CD000AB2C47C845983DE47D612F4FFC2AF0F8B6
-:101CE0002FD176B8855D10FE14F3E6939EBF57D8CA
-:101CF000AAB5AF4F98B91DD6B9F684DC5D3F8EFE0C
-:101D00006B40F0C901E1CFA29D5013783D0E5E1FDC
-:101D1000BD99D7D58E71AF29C6B3CFE3CA371EC4DC
-:101D20007682A7BE18CF3E4F5AD07E909F81E6E7BD
-:101D3000D91B0EDC948DFBDE5D67CD0CF75D1AFEC2
-:101D40001AFCE34B8087FB5B00FFBDD825580EF1E2
-:101D50001F58EC74E6EC79BF4BD2F4C7A90AE4C76C
-:101D6000CE0639D40740AA80C1B1FFDBD4938FFBE4
-:101D7000A09F95E67E3E15FDED742FB55D27FF9A79
-:101D80008CB660EF69EE473598DCD9C83F0D032368
-:101D9000BF1FA0B54FA61A890E057D7CBFEB482A50
-:101DA000CF6F0EF1B1C7908FAA1A64BB1FE87EA94E
-:101DB00041769BC01F3AEFF626E3D99C0BCC77CB3C
-:101DC00044B4F3228ED4BEF77217FA2960A7EEFE50
-:101DD00065EFFB0FAB99F65B6340BE5AD624B1FFAB
-:101DE000001C2C7F26F2F9D5DAF76A1AB71CC6EF69
-:101DF00088AD7C4E771FFD15FA0E46A41F7324553F
-:101E0000F827592C0BFD13E023D20F46851D310313
-:101E1000DFAE48F7EE437BFCB2F8BE02E85192C752
-:101E20007D4E615744FD417007AF2B1EBECD2F1B69
-:101E3000E0FD098A5F467BC5A0C57D87716E6F197D
-:101E40007D87C9E73E8DFB3ECB853E5CAEF9697E62
-:101E5000BE3F026637C24FAB16AB1FCFFCB5B1B861
-:101E6000FE6D12C5CBABB645EEA7548BF5AFDE7C4D
-:101E7000F2309ABCCA7ADD7DB1FE6ADDFAB57DF337
-:101E8000CF5323EBBFAE773FE42F46EE37BC2DC6D2
-:101E9000D1EE9BD2B87EAC826520DD56FB65BF9F3C
-:101EA000FB7936FC5ED09D625D770AFAD33AE1B9E0
-:101EB000CA6D923F803CFE78649DE95DF58BCB90C6
-:101EC000AE7A3E5929D6BD7CBB91FC55FCFE0FCAAB
-:101ED0009D9E3F568AF5AFD4ADBFCA2BE9E0E37EA5
-:101EE000744FF8EA6F413A576E37B2DEE0D3E8B587
-:101EF00052E3EB3EE0D5E0D4E0FEA1F0F64F13F95B
-:101F0000AD116C04D1A93CE1BAE8A4F773771D1EAA
-:101F100041DF5BBB7C6420C5FB1A1FE8DF2F137E0B
-:101F2000F2D4CDDC6FBCD4586C1D89F14C9BC1251B
-:101F3000A9149FC58E04BCE437CBAC02FA5D4D59A1
-:101F40009BF0FB8379270AE660FC9F7FC240E7EFA6
-:101F5000F61C29A07DE7FCA38312B228CFEDA2EFE7
-:101F6000E3C038645FBBDAF236E1F984AEB69202C0
-:101F70001C5782E7D00FC81376A2A62DCF1A7EFE7B
-:101F80007C4C1A8FEFD73B3FFD39FAE9537719E9BB
-:101F90009CC55463F04DACDBDA7344A17DF2D527C8
-:101FA000963C1485F47D51A27DF2C3ED6B1317228C
-:101FB0009F3519EDB8EFDDD5F4E30378DFB75DA207
-:101FC000EF5E54379766EF807EDE967C57F8F9B364
-:101FD0003C874AF0B1542BC5CF53FB19C96E5E4CF8
-:101FE000B3FE16FD9F95EE2D24DF17F7EF3151DD7F
-:101FF000DE0E89A1293BEC3CF80AE2E3E2AB274D77
-:10200000E88417379C34757C8F3F70C92FB300C5A7
-:10201000CD1B4D18C7546ED1FA1D26A49347F8471F
-:1020200055CF7D4CFD95E8CFC37C2B9F91A97EF7C2
-:1020300060F36B26E4E7AAED124BC90CBBBF598ACB
-:10204000F85EC312C6F96089D03FAB987F7D1A3C19
-:10205000B76A23AF5B608F46D6016BFCBD42F0F7D9
-:10206000AAEDB3E8FB533DBE5B8871E30DF81CE7B6
-:10207000EF659B23EFAF107CBD42C7D73F4913FAF2
-:1020800067381B8E7CFD75A11A9703D7BF3EB972C6
-:10209000406FE7ECDB84BDD6ECE5E58081EC8DFE9E
-:1020A000B9CEC62B046775DB6513FAA7654D5F10C3
-:1020B000FE2B9A5AA97EE466E65D8DF8BAB9C96A24
-:1020C00047B9AEE8E07A685A93D9EF97F07E3DD5EC
-:1020D0003977B5F0BA49DF7E89FC1C4D8F69DF770F
-:1020E0005C26F0B80C14787A1EFABB3C6EAE127106
-:1020F000F28A615B0EE33E7B95B8BFFAE8C158F403
-:102100000FA7B12F6E47FAC07C0CE763CF44E27D86
-:10211000BAD08BD3B773BDA8B76B5DA9D933298F5C
-:1021200009712AC2B57A7B24BEAB74F1F963693CAC
-:102130003FF6820EDF154166CD413854D9E5A7A799
-:10214000DB159CF7482ED85BB4936AD6F77E87F1EF
-:102150004DE1676BFD99E21C78BD7DA32D3C6E8E31
-:102160004AE7FEC2CAF1B20FE9D51D6F0C3A98AB2F
-:102170001A42F106C419CD69493CEEC08292373249
-:10218000649698188A371E716EAAC8837EF5762EDB
-:10219000F79DE3603C3C7FAD30F247ABB79BE99CD9
-:1021A0006235D09FE28A267E9EC2D3249522DDC16D
-:1021B0005F3F9A86FBB198528575CF6AE47C3FAB4E
-:1021C000E40BE297A383F87A2F2B6A4A6FFEBBE6F3
-:1021D000B7E3F93035CC7FAF0239C5E7AB9A783D2C
-:1021E00052C3816FFA67A29E6BFEAFFE8BA1FD5AB0
-:1021F000D845CD2F0C825F3890FB45F4BDC9BB8517
-:102200007C2DB3F37DBABB85FD61521DF17995B18B
-:10221000FE503CFA593B78BD00DB871F8503FDF873
-:10222000F64B75F1B0EECE9724AA87C3F7F17B94F5
-:102230009D4BEA3F41BFFBEB1D16F237EF06BF6532
-:102240004A5E4FB9D4E45BFB6E560D7B88FCCF87AA
-:10225000581DB595829F3B1B6BE9FBA09ABF42EFCF
-:102260000FECE98F540ABEAFD4F15F547A24DFD566
-:10227000BC1D4D7E63D751D98EFB3180AFDFA48565
-:10228000E345F8210D07A288AE5D276D6447FE2C5B
-:10229000F8EDA2C83FD78C93090F86F1BCCD6E79BB
-:1022A0006D20D211F18EF5F72FB7BC36829FFBF669
-:1022B00013FE576D9323BE0F5B591FF9FDD79AB7D5
-:1022C0006FA3EF0855EFEF866B88293104575F72D3
-:1022D00020493C8E3448917164F53ED9135E7706EF
-:1022E000EBB903F551BA9007A6049331FF35009D71
-:1022F0000680AFA689D3D5D0CC5B98FF169E273138
-:10230000D2FC3DEE17F956E3FDAF33AD7CFFFAAAE0
-:10231000AF02FBF70F94A9AEF3FEB7570E0DD7A38C
-:102320000CE104BA561B83C9146F9E34107CD52768
-:102330002F270FB2A15EDA5282DF0F9D2EF4DFE16C
-:1023400081D6E5C8CF3E9C372534CECB69BC7E8F85
-:10235000E17A9DE86DFC928F2BD6FB109B2DE26AF3
-:10236000CE4F39697CBD108F8C4BEF251EB95EBFF7
-:1023700013ECC3A98512D633293E8C87F7BCC7F569
-:10238000424DF3B28F90DFABDF37539DD7FD2DCB9E
-:102390008652BDAFD77B03FA1B5FB7ACB881F2831F
-:1023A000D24304970FE173A25F732619EB522B9B64
-:1023B000CF2493DDDD3B7A932F06FD97BCE9781D92
-:1023C000FC09E23FF06B88FFF6B415687E8C15C7F8
-:1023D000AD3CAA78103F95470B8E57A07F71A2A8FD
-:1023E00000D5B974A280FC987CF4636C21BFA65B15
-:1023F0004FA6733FA6AB358AF20B121BC8F9870DA7
-:102400008AE09FD50DAF93BD5FDD2847D42F6AEFDB
-:10241000DD99AED038CB34FEA997DCC41FBB78BBA6
-:10242000BA710FAD6F95B19EE85DB3DDC8EFEFE017
-:10243000ADF67D581F8BF7213E8EE325A0C3349364
-:102440003F03F3D3C732B99FAFA7C7E7E93CFF719A
-:10245000ECAC7700F2CBB142EF507B2F76C2C78A4B
-:10246000785C2B097C37F07353FAE73E4B97C477BF
-:102470004222CFB76AEDA974AE3FA7997AFF2EE04A
-:102480006FD2B57309EC31430146C546FB06E1D76F
-:10249000A7867DD761CECD46F2174E31FBEB58EFC4
-:1024A0003843D3B3E3B87DD5E7CBE789F73C9B55F9
-:1024B000BE5FA43B3F334F3BDFA43BEF364FF83BBF
-:1024C000F374FECED3E9C28F1FC286A01EAC17E7FD
-:1024D000EFD60E8FF287E7B3F4ED61B12F82E78775
-:1024E000B0AD19FE2EE57D8EB59E7D85EADDCE462A
-:1024F000B1813CAF47F9EFCA3EF2DF35DD723937C3
-:1025000082CF34BA5C12DF83D1D365B7A6AFC4BE25
-:102510005DB4D8B7F31BBDBB519E2B2D174DBCEE40
-:102520003068427D56339CFB4D974A25DA6F073859
-:10253000FB9BC3F4FBA5541E7FDD7F8B4479D756EC
-:102540007C1EE3AC7A89EABC2B03ED26E4A7210DBF
-:102550008B1F26B9F5B1D32CECBB1A332DDC4E768C
-:10256000D34F5B77B71D8BF7717D9C482D3E8F76DF
-:102570007186B083FA735143597B593AC033DF2DCA
-:10258000B9B01EA02F3ACF5E30EA7544C3F5D2BB76
-:1025900033DDFB4E3ACA79FBE55B308F7A6CF86726
-:1025A000FDD18E56F5C1C71F0B3CEBBF2BE31AAA1A
-:1025B000D6E2F7556A9DDE0ED29F866F6347301CC8
-:1025C000A7E3376B25A41323FEEF4B7E3E13E37E78
-:1025D00096CEBF770FB8A77D9755E9BC4EEB98D143
-:1025E0009F41798A9CEBDBF7AAD9F7462EEAB3CE56
-:1025F000D6A3B9A630BA5E5C0B7A00ED4AF3C1648B
-:10260000D516CE7706E23749D2F84F11F632920F3F
-:102610002F221FE6607B267610EAE35DA76207E3C0
-:10262000787B79DBCDAF4DFC7BF6101F0D9917132E
-:102630000EDFC304DFA57A3E0E631D43E68C0CBF9C
-:102640005FDB171F5B33888F3B22F8585B6F3D7E43
-:10265000CF07E38016337DCF07F3D78E3039199A31
-:10266000C1F5CF58F1FD9EF1CC47DF391C2BBEE3FD
-:10267000335E6101251EF7CD0232DFF7E5E72DC697
-:10268000087E1EAB045AB18E62BCD8E799C0DAE965
-:10269000B9292C48AD9BD9E91C451173513BCE1289
-:1026A000988EEE544E7D3DD525069215C7798B3810
-:1026B000AFD10BDD42EB57E8BB3DC49F329ED7E95B
-:1026C000FDBB2FB333B8DCD3C74590BE9718E5B92F
-:1026D000F07B6D38C9448595637DD3648559A2012B
-:1026E000DE5D870C24CF2D1DAA1FEB535D09E2BDD3
-:1026F000CF19D5E18E757379459383F518DA7AF59C
-:10270000789800E3619E6DAC029128E13140F3DDE1
-:10271000C8F8399242A652FD736946A6D0F7418A9D
-:10272000A38A218E427D6FB0F8081FD33354BA8F2D
-:10273000FB25B130CE848D127B0FF73FB2F87AB50E
-:10274000F1270023E0F9C2E919DC9E614AF5BD7862
-:10275000BE8F124B05CD2576FE9DA364FACED1F532
-:10276000E2B52B997FEF32F6CE60E7CF0A42FB4904
-:102770002EFCEE516CE83B9B2EEDDF830844FE7B84
-:102780001077642CF911F2A356AFC7BCFCDF7DD0E3
-:10279000D7EB85D5E7B10B61E7B0B5BA926DFED93D
-:1027A0002A9EF35B9068A173BF7996FEF968C7060D
-:1027B0003ABD34FEFBD2F6C13498E21FED8909F12F
-:1027C000BB95B9C721BE437583FC3B50DDE7AE9294
-:1027D000199D57B49A797DE563201FF81D26902E28
-:1027E00015EB68D883C5548FB9DE6171E17909337F
-:1027F000C26D0DC15D6B11DF05B5F07D717D3D686A
-:10280000ADCD40DF1DAD65D1740E3D29DABB2E0381
-:10281000E0BA2FA688CE7767EF9CE444BF317CFDF9
-:1028200093B4F51B7AD647C27A1FC9E8A51E515B3F
-:10283000A7F6EF76D805FEB475DBB5734A6E25E2D0
-:102840009C92868FC7A2F9BA8DB8F39F45EFAAA8CC
-:1028500037F4EBFDFFDC29BC16A06400000000008B
-:1028600000000000000000001F8B080000000000B6
-:10287000000BB3D36660F8518FC0C19A0C0C5DD2C7
-:10288000A862B4C41D120C0C9780F80B106702EDFF
-:10289000F5926460F006E26D40BC1D88C5A518186D
-:1028A0000280381088FB80FC7E204E07E224A81BA3
-:1028B000B30519187281381F880B815848808141EF
-:1028C000588078FB8B1519185EAB22F85A6A0C0CED
-:1028D000C91AF4F3FF60C381B6F4B5EF16D0BEE5B4
-:1028E0006E08BE0490BDC20D55CD4A37FC66AC42A1
-:1028F000935F8DC65F83477F810D2A7FAB292A7F37
-:10290000AF3903C3072435DB4CF1BB051D2B00FD9C
-:10291000A788274C9730A2F22732A1F2F9A17C00B8
-:10292000BE1E313CA80300000000000000000000B3
-:102930001F8B080000000000000BED7D0D7854D5C2
-:1029400099F0B93F7367269999DC24433260126E7F
-:102950007ED0A001879860B0586E20E147A30E0892
-:102960002CB440262888166DC49FC6DD500609BFCA
-:102970000921E14F70D11D105DEA63FBC5565B75FF
-:10298000BB7682D646AB3568D787767765A015BF0C
-:10299000BA761BD96D976EBBF57BDFF79CCBCCBDB0
-:1029A0009900FEECB7BBDFF3C5C7E770EE3D3FEF24
-:1029B00079CFFB7FDE73C725BB59701A631FE31FF6
-:1029C0009413731963B5A9B2C5C362D9398CE5767E
-:1029D000488CD530B6B25D89CF827F1676B4BC8282
-:1029E000F5E56D6EC35DCA58FF036E7F0DD44F6F62
-:1029F00057C26EE8DAA8F8A8BEACCB15761BF07CFF
-:102A0000EB472FE7E3FB8D5298419DB1BB199BCC5F
-:102A1000D81A0FFC13EACB2A921DF8FEDD2D52388E
-:102A200086AF99E99B04EF6F65FC7DF3038AC6646A
-:102A3000A8EFBBAD894D64EC961E98C5430DD9C770
-:102A4000BC3D63058C45F823D6B205DE57A6DE47AC
-:102A500058D7470AF46B8E399EEF9BF53E0BE07B0F
-:102A60002DF51CD6730CFF3185B14B993F783A1B7D
-:102A7000FE1D66E18F15281BF2191B9DC297B364DA
-:102A80000CA01FC5D85CC65CAC1CC6A9BDCCC5CA11
-:102A9000607D161EDB381E97354984C7653E46F5B6
-:102AA00077E74AF1074BA91F9B5E0D253C2FC88392
-:102AB00032C8CC4228231E96C806F8E7B65DF61E3B
-:102AC000AE7F034E359ADA2702F07E018BBA18C02A
-:102AD000F7672C46E56216A7F2CB2C41702C6543B4
-:102AE000252AD4EF52129B18CC130E45A7E3FEFE05
-:102AF000AEFED8BB12BCBFBF5AAA9D0225F3E5D1DA
-:102B0000BA2FB43E6B7E9545AEC37118935D113FED
-:102B100063E3AD751E66B18A20637A8F8FD3CB6174
-:102B2000D6CFA03EBE41D04BE3FB7208D6DDF33CCE
-:102B30000B633D049B3905EAA1AEACF806A8F73C4F
-:102B40001EAB47BC1C6B01CC43FF638D6E295A053D
-:102B5000A54B7745A00CA98C2980A7FA86F592028F
-:102B6000EDE646F938E34D4D665742FD704C52C5CF
-:102B700073ECAFEB314987FA78A83F28E17BDDC5DC
-:102B8000609C86865C57B20AF1DD334687B2E2B0BC
-:102B9000969001BFF5A64ECF195B4474355ED0DA2E
-:102BA0005C93F79B7B38CFCFE83DFBD3C7D67BC088
-:102BB000EF25457CDF8E1D2ECB417859D4DEBF48F2
-:102BC00065314F5E0ACF3BD7C10B770ABFBB0E976B
-:102BD0006D45BC1DEB53C382946DE3C3B8BD0DF0CE
-:102BE000FE4C951C560CE4B3220E7F85EED77DA9D2
-:102BF0007176AE83F697A5E06854A6F6133E4C4670
-:102C0000FC38B706DA57A5DA3F81ED018E3D080F93
-:102C1000F55B73D48BF34418CD33123DBCB04EA793
-:102C20007E83621DD7FCEF30EDD3DC861689CF2B77
-:102C3000E06BB0C36795167C238D7F4CC0658D6FAC
-:102C4000CDF7C4BA10958D4AD523F7E2BA8E687CC9
-:102C50005DF38DC77723FE8E78C231A83F79DDDF23
-:102C60008CB91786B862FAF3973FC370BEE50FDFE1
-:102C70008EEB7A2E8BD6F5D487675EBB910D9FF7CE
-:102C80002D81879F9E9B3F44756BFEB9A6344602FB
-:102C90003AAB34A5840BE8E558FD571EBED7C07A81
-:102CA000BF89F2A4D23C664A504E846168BF99FA4B
-:102CB000A78F419E554277E4C7490D520BB67BE280
-:102CC000C687BE741F3CFAA98BC37DC55F72B82F3F
-:102CD000BB7EED9308EF6537AEFDF93350BF02853B
-:102CE00020F0DDA537ED5FF377F0CF6F2CFCCBE55F
-:102CF0007B18C9855836C0916B4A0CF777D9F7DD38
-:102D000036B972EC793FC99542B33486FCB7AC4F03
-:102D100022F9DCDF08721FDFFFCC1D77237F3D2007
-:102D200099D4FE59771CE5C3311763288F971DF797
-:102D3000C6915FD8AA6524AF2396BC36F397DE0B05
-:102D4000E3BDDB60C9734EA7F41ED6F7AEF98BED79
-:102D50005743FF33A62B8C62D392174E3CBF2BF008
-:102D60001BA92F273A58A6265DE10CF4D0DCA6D883
-:102D7000E4767DC349A2AB6550B2343E9D2BF86C1E
-:102D800059C32F047FEA24979CF0BC515B589C895F
-:102D9000EE4E09789282DEDEC5FDBE0CE1835E4810
-:102DA000375D4A5C4993D3F0E78A4CA07A0C59FA14
-:102DB000962D76382DB9DD12CBB6E92B90BFFF8268
-:102DC00072B3B92DDFF67C6E0EAB9DFAE9E4F01F0D
-:102DD000480E27258207F42FED7F242EC5512E5A49
-:102DE000FB7387D89F4805A3F5FCEA80148FC1FECA
-:102DF000FEEA8858DF3E29AE4844AFE6690F8E0BE5
-:102E00007396A7F6FF76B1FFA9FDE3F8B1F095D26E
-:102E100073B99B9200428B2F5282F2DAE21F0BBFF2
-:102E2000FD7B7E5482FB57D856DA5D87701E508832
-:102E30007F3FAC3F598CFBF6AE0BF00AFD23871F9A
-:102E40000B305F0AFE1621073FE8007A81E712C2C5
-:102E5000599906A780DB857568777B83D4877CFAD0
-:102E60004B31AFD5EF475B66CC44FCDCD12331C49A
-:102E7000CFED477A97FD39AC7F753C3B8C53FCAA6C
-:102E8000B1387009C0B3A2C7BE9FA7B6DC1C40BA58
-:102E9000F9B02FBF00C7B97D6A42433857275ED5C6
-:102EA0000CA0B35966AF96CC40571FF66D0860FB77
-:102EB0000FD59E1BAFC179F629E1F530FEEA23A5B7
-:102EC000334D4EA744BFAB057E4FAA3D33C7007CB0
-:102ED0002DDF282779F05E9F323B9E417E7E5D523A
-:102EE000880E56B7B9655CE748F4F261878B2570A8
-:102EF0001E3541F81CA9DD077D2DF4BEFF81C21BE4
-:102F0000D07EBBBDDD45F2E2F63637D1D3EA0629E5
-:102F1000CEA414BFAD10F0AEDEADD0FB93A644F24C
-:102F2000C3DAAFDB05BD9D3C7CD52BA8EFCF80FC81
-:102F300041B93B63E30FB54B000F2BB67079747248
-:102F400077EED27B508E087D798718F7B6B862E3AA
-:102F50008F95EDD9B6FD8876E5DBEAA78FE4DF58DB
-:102F60008774DDA590FEBC65E3635A88E493DDDEDB
-:102F7000440E9B5490B22F4FB0A105D748297AB286
-:102F8000E8E7D636B03703C3EDCD962312D9A317A1
-:102F90006D67B6819D3971B89D69C99108DA67E599
-:102FA000293962C98DBB94E8D820C0F16B57F4B2BF
-:102FB000FC72921B0F48B54827FA6FD1AE6431A559
-:102FC00016E5DBC5CA0B5AACC547F0F75E07D0550E
-:102FD000067A9D817405F3CCECE9CF48CF33248386
-:102FE000C64BD1CD2D01E25B1C14E068F6985D085C
-:102FF000E72530B1B79A4AA6E4F15285FA668419FA
-:10300000E8E1D45A297EA894B7F3A13C05B8AE8173
-:10301000E7CD5D97C7B7496817C21FEACF366E770D
-:10302000433BD39F47CF4D09CAA2F6D297717F2E5B
-:103030000101A055F3F6380FD8598412689F7057D4
-:1030400053D75800CA62E827F3FEF41EDB05488E0A
-:10305000C769BD383E8E53A1C4D7A09CB1E878990A
-:10306000903B20572B55A0AF66961546BDD9DC5630
-:103070007E5EFBE586B05D7EDC5467D703734DBB97
-:10308000FCBF79F625B6F60B22E5B6F77FB6E80A5F
-:10309000DBFBC5D1AB6CF52FAFFA82ADFDD2D619F3
-:1030A000763FE9A7B9B49E35822F4782FB75212F61
-:1030B0007FE2B04FADB2E9FA44CDDBB04F6C9D3B3F
-:1030C000FC381427E6B0457D6972C5274B84CFDFF5
-:1030D000009B70FFE04F1F131E437CDEA6BF70B73E
-:1030E00066A23B4DF4437309ED2567FB138B619E8C
-:1030F000B47EFF26494487E7FA314FCF2F01E4160B
-:10310000E0E41C40FD9D2C5982FBE6CE35E8FD5DD8
-:1031100072B200EBBF61437BF3717F7DC962E49FB4
-:1031200066953D27E560BFB0C70DF38135C4DA80F1
-:103130003E5ADA7E741CED38C908B22558F7F812E9
-:10314000C8DFACC3F561D2C23BF0616F28FAA104BD
-:103150007048EDFDBF97F0FDF799817A98258B7245
-:10316000D17FC4A9D2F9B069066B457C9D68B4E3F0
-:10317000CD2BD6F17349A676CF31F3B7C8472725B3
-:103180009DAF4FC0BB4D32CFE27C16DCEFE6EA1AB2
-:10319000FB74702B722DC2FD23827B432B4B662B5D
-:1031A00023C37D0533DDF2A8E1F09C656656A6E7F2
-:1031B000B3805D333DBFDCCD2AD15E3D216585D72F
-:1031C000976239F48F5F03BE8A7DC3177EDC184E89
-:1031D0001753E55C9ABF59D8BB85ED52221BED53BE
-:1031E000E621FB95F53C647A50AE0911D7D2269DB5
-:1031F000C4F5B38E4633E949AD9719124B6F776E1C
-:10320000DFDBDCD4DE923796DCB2F069C9154B7E89
-:103210005978758E3F929CC1F1D43C843F3A494E17
-:10322000A7131DF03101E131AB71FFAC7D033732E3
-:10323000E6A91E79DF2C3905ED18FAFF23ED17E01A
-:1032400089EC3A5798119EDE0D0E2D7D0AD63DD0A1
-:10325000C6F5F5BB458CECC3336D570DE4207E3CC1
-:103260009E0AC44F219F8A150687D6A17CF5A9899D
-:103270007E84AB50E82F2FE3FAAB90193BAE46FFAC
-:10328000BEFDE4126C67ED4FAED89F66D81FF447C1
-:103290009A7D43C56827B951AF413B37C85D94CB90
-:1032A00085EDEFFF07EAC542875E4448583A1C594E
-:1032B000553BAE36D2C7FF6823DA97D6B8D4217D06
-:1032C000FF83DA49C46F61FBE6BB95806D7CE963DF
-:1032D000C48390DB68769D9BA714ED5539E10EA45D
-:1032E000E8C20997D56F243A61E9F394DBEA644FA9
-:1032F00038EBEEB06693CFEFFEB13CA7D5771E7AE0
-:10330000738EE7A46F271F083C7C0A3ADDC4E9945A
-:10331000CB058B6FFFB3E8346AED6B2CF78E23A8D7
-:103320005FBBB4F02C03ED84A11F723BC16D1C4246
-:103330003A8B495995F03EDAA192DD68D915FD6BBB
-:10334000FF7A4B193C3F512B931F71623DA7FB3D08
-:103350000F707BD4D2DB51A1B7D12E40BC82DD30BF
-:10336000E0E6A507C7F1AFBFB95402B83DC650BFEC
-:103370001BDBB71964AFE6D4C5F54628E315873CD7
-:10338000E38C945C4AC6F2F396C37E7D2BD7581625
-:1033900021FB3A3A7AAE3FF5FEC732D74FD34A58AF
-:1033A000DE6C182FB9550E3F08FD932EBB1EB3CA15
-:1033B000350AD797492F2B413F78A476438AA557E2
-:1033C000758DF665FEC071DCA791F6017640A738D1
-:1033D000E6393AE478877968FCA4DFAE874E0A3D87
-:1033E00064C1FF09F4EAC262A08FBD5266B83F1201
-:1033F000E3459F030060BFA32A3333B573AEFB1FC1
-:1034000044BF84ACD27C3B2A76CEC6FD8EC5947078
-:10341000FA7E58E55F285C7FE6CC6DC86D84766CDB
-:103420007DE67679A2DD63F7652D42FF0A50A7623B
-:10343000BC2614D3E7CDC678E4D4BC49E863FF18B2
-:10344000F50FCCBB3B72466FF17D227C14849491C6
-:10345000F1F1A62CF37D74F0ED1E70D7507E262579
-:103460000FC55F5A62EE8C7C6CC929A73C72EA39A1
-:10347000C934595BF570B9628DFB49F519C8872CC1
-:103480006554CA6E3FA7CF2E961E47900325328BF8
-:10349000F665F04FAF56389EFA633C4EA19A32E97A
-:1034A000AD994A1393004F1B828CE4411EEE35F216
-:1034B0006D038B030A583E0B0FF8509E046596204F
-:1034C000BFD5E9079A4DE8070639684C1F55D65F06
-:1034D00008CF83F357D239038B7079ABC37F9C8FAE
-:1034E0004CD2176E81D7686C12C539F39AEC72DC36
-:1034F0008D7E20C847BDC1F17CFE4C3A6F70B3B4DD
-:10350000E7B08EAB147FF03498F6AC9AD5207F5696
-:10351000EFBF6AD76218BFE6919BDFC672F2C17B2C
-:10352000F2BF0465DDE3BB6EC6B2E4B5E8D84CF18A
-:1035300054AB044E61721DC0E763863B67E476C6F8
-:103540007A25827635EC6307D24332569E85F4BDE8
-:103550004AE1FCDFBF400B607C46DDC2E5AA3A1FB2
-:103560009047F4CFFDF4E6943F4D7E852AFC24A5D8
-:103570005DA13842522FA378CBA12DB28625C8D9A0
-:1035800018CE63CDDF2BE2D49D22DEEA84AFB76490
-:10359000A818E5E089F51F917DA8E859E1D9305FC9
-:1035A000979F95101C225ED02CF62FB9B6DE931E85
-:1035B0002F52849FD37174CE80817430A084BD0655
-:1035C000F18D86E346B74C67187F99A58719DA1302
-:1035D0009DC2EF517C26C37DCDD6D94CF46BE195CD
-:1035E00016C2FE552C9CC0FEEDFD885B58AF793BA2
-:1035F000F2C10FAEE576C88952BBDC0612EA823D05
-:1036000065B38AD6AB489B4DC1495721CDFF5E2992
-:10361000107295D3EB1BB5531EDB0674F09CDBBC1C
-:103620004719F509F8C821D77F006C82FBF6A8641A
-:1036300097E75679D0C9476D12D985AAC9D73953AA
-:10364000F9B011F5E446B01B0B8DE1FCB2F1754603
-:1036500076E346E0BF586926FEA99650465C2CFFEB
-:10366000E4B5E74A18C7F8ACFCF3978A38A713FC0F
-:10367000037496403BE651C9E89C02EBFBCEBEC604
-:103680001F4F81D7CF1E58917D0D94DF8B6FBCFEED
-:103690001A98FFF6C7F764E33E3FFA2AF0D379FCA5
-:1036A000788B9F9AD1863D4F9CCD586BE727637DE1
-:1036B00005F1D35B0AD75FFD0B7EF7C6D5FF9F9F51
-:1036C000CEC74F6F2B409FD3FE74B6387A1EF9D603
-:1036D0005CC434B4B7A08D89741E0DDA4B9F9A4533
-:1036E000F85EE7E272CCEFF272BB23C4DF3BC7FBAC
-:1036F0001BF593C70F16947F763E5DE7333FFA3C88
-:10370000F81DE40EC99B13E3EC7CDFE9E274F72BB0
-:10371000D7275EDF3B5FF81CD607763DD977D7A960
-:10372000CC403F60E20B1E1216AF8EDB780459626C
-:103730001A3C0FE5F1F7EE3C929771B46386944A18
-:10374000EA6F326EC737D56C3EC2CF25062B168185
-:10375000BF3C07FE85F6C8753EEE57C0382C04E323
-:10376000AFF6468BD551341EF997AF3EBF2F88F286
-:10377000E5758F5982CF5952CDC5F301CBEE18991B
-:10378000DF55763ACDCF7A5A6304C7A94B358A57AD
-:10379000A2180B407D6BE9A514A764E1D87109EB71
-:1037A000A37486725C094616931DD2E63666417D87
-:1037B0002B1850B120D12DC94DA5BD37144039006B
-:1037C0007609BE5763733D1AFA2FA3640C42337710
-:1037D000DB47E4779F28E6F2B6630AA3739A810772
-:1037E000FE6DA98CF64EBB9BCE2DC06E247E8D0A3D
-:1037F000B9910C4E0FB5A09F51A48525A86F8AFDE5
-:10380000E2F8D7B83C313D93D3E3233CDED112E25A
-:10381000FEAED3EEDBFCF5CBDE3470BC1FBED6753E
-:103820003994AF3FF9F3D72F87776F7CEBB51A8CBC
-:103830007BBBEB345BDCD1CD8C37D1DE029F29A181
-:10384000A17C8E9D5C829B99F2EBA418E2275AE33F
-:103850008FE37A91B7113FC9290A3F5F84BF10C037
-:103860001710F075074F55D13CB1F7FF2393BCA754
-:10387000BFC9428F40BBCD79F7C7518EA4E69B44A8
-:10388000F2290AF209FDC8A8AF67C91A9ACF1F7EAC
-:1038900010FBFC11767572EABCF0D096792D88E7A2
-:1038A000B90B3C3AD2993BB6F96EA473E73ACFF81C
-:1038B0001EBC144373B6F9814FDC159AE925FB97BA
-:1038C0001DA6FD104D2CB8755020187780FECB56E4
-:1038D000B00CFD0DE88FEB047986F6B6D50FC8D88D
-:1038E000C4F59EF14DBF94E2FD225E61F5BB292631
-:1038F000D139C14DE5C006E5C3F1B4C127FFE46B82
-:1039000078EE12537485D341A8220D6FF8678F9B10
-:1039100071BAB86C9F5DEFC2FC0B4BF17D4C217A04
-:1039200071F2CBF8B8BDFD06DFF9CFF587EF27C7F9
-:10393000F344C16F567F0B3E8257CA145FB79FCBCB
-:10394000DC5467AFCF1D868FF3C3355DB59FDB3485
-:10395000F8ECE3CD0CDADFCF2EB2D73760FCE6937C
-:10396000ACDBC1774F8F31BFA37E06BFDE92BBEFCA
-:103970007B227F4BE3A86186E3F42FD83B7F1ED0E8
-:1039800041A1CEED8EC2F90B1B726B504E31916787
-:1039900092D9FE2814FA5E697F49C9417FD4E4EDCB
-:1039A000934BDE9A9183E7C5758CCED3A3EA3DB1E4
-:1039B0001C23658FF4ABE55988E7CFDF1EB9DB9B8D
-:1039C0009E7793B2471E78D5A8C9608FA8F748267E
-:1039D0008C336B09D82355E9F648AB8432287B0930
-:1039E000D823647744DF437C8D6497FCD8B2EFFD25
-:1039F00099EDEA3FA85CCF829EF9A7CFA267C6796E
-:103A0000CD7F513F077B605A89B13292810E3F5082
-:103A100079BCC3D29F8DC1848267E7A03755173C1C
-:103A2000BFB62EF9128AE30E7D6710D70DEB71B980
-:103A30006A3FFD7ACEA81C9E892ACF8319A9DFB7D9
-:103A400046F057BC9A57D82DF6FDEE5FF08E2EA3A8
-:103A5000FF027E0CFA2F495FD9368C0B9E89A91480
-:103A6000AF53E7AFDC3D17E909EC6C4ECFE7B7AFDA
-:103A7000AF1D926D7C3CED6C968DEFEB99FD9C6ECD
-:103A800086C77E4ED7A8DBCFE96685ECE774730C5A
-:103A9000FB39DDF595F6733AA77D3F73B4EBBFA70D
-:103AA0007D1F6A64C44F17B0EF819F6E427A1A89F6
-:103AB0009FAECB37EE8F64D8EF6A8DDBA9ABBD919B
-:103AC000054877D30C6ED74563EB291F302F0AF2D8
-:103AD000A694E28614F7B2E25A56DCCBCA0BB4E2E3
-:103AE00059CEF89515F7B2E258528CC7AD9A3DD130
-:103AF00015086F73FB4919E588FE1CCC838C609D0B
-:103B0000E30D8BCF7179D0D29E392EE78CBF8DD843
-:103B1000EE53F2D5E7A01FD6E37A2DFD007CFEE040
-:103B200067E173905BDB70BC7F417E1F45F2A49B15
-:103B3000F6AF02708D763AEC838671FA05A7F763CB
-:103B40003C4E3DEE26BEBD58FF17131D64D8B42869
-:103B5000F8E018CF8AC64A49BF587C63F189D33F41
-:103B60001EC61FFFD5FC7391FE31F0CFF75CE7D185
-:103B700047C01FCF23BEA75572FC3AF9C1A27F20D0
-:103B80008984548DFB1D4D607B8BDED98B6113E1E5
-:103B90009C28FC9A13A335F22F4E3CFFEFFC1CF639
-:103BA000794F789C5823BE9FD85D10DF569AE23338
-:103BB0008B9FDA3DD11FBBD2F240AC7CC7C31EF352
-:103BC000757C1E52FB12E8AF8466B3F00683F8ECF6
-:103BD000187FCEF9D41766143FFDCC7ED95E571CF2
-:103BE000CF875AA4A1A58CFC56A621DFAA429EBC71
-:103BF00098153D89F86C9E1E29E1F43434CE077087
-:103C0000FDA243217FEDB3F253F348F83F878FE8DD
-:103C100090AB76787E40BADC42F9160A69F10D5213
-:103C2000067925F01567E131B83ED8CF7F473CE6ED
-:103C30005531899623F8B8D963FEC1F5D9EC0F4503
-:103C4000AB4DF131E0CDA3A15CAC06BC950FC7DB59
-:103C500049175FBF93FE426A5246FA0F811CDD206E
-:103C6000A59D930ABC58EB19493E5B749A76DE1009
-:103C7000D2D2D7FBFFA85CB6E4E5E59EE864DC079A
-:103C8000B71911F2CFA4FD75CA99E176904CE78C73
-:103C900067C0EEC16E172B5FA79DF5E261099B7AA5
-:103CA00056A1F2DAB37478C2BE78369B4AF36C3E02
-:103CB00095F56773A99C7EF6122A679C1D4D65C316
-:103CC0005900064C9CC6B3A554CE3C7B0595B3CE9B
-:103CD0008EA772F6D9ABA8DD9CB393A8BCEEEC1707
-:103CE000A8BCFEEC142A9DF68FB15E25F96DC92F94
-:103CF0004BBE3BE5B725FFFEAFC9EF58C345D93FE3
-:103D0000A0FFBEAA9D477E8F242F80AFEFD3D2E5C0
-:103D1000444A3FDFAF7D06BE3E2EF814F8F73D8CD7
-:103D2000C378C08BA3385598C7A9028666609EC623
-:103D30003E6C025BEA2F8D9CC4B841F3028F1E03D8
-:103D4000B8074A35924FDB821A9DBB6D96F4D15C61
-:103D50001E2413487F3B431A8DB7ED8F8A17F31744
-:103D60005E1A5510C079BAFDB28EEDBF959BDC7717
-:103D70000B9EE34F61E14330DE8A3D7B3CE97EF8F8
-:103D80007E340E00BE40EC69C680AF378EFADD523D
-:103D90009CCF3795513C064A3353BED837DDE27C81
-:103DA0005A1D0A219EB6FA64D207DDBA47E4A1265D
-:103DB000075AD0CFAD93D9369877C3E877B620D8D5
-:103DC000EAB8B21D6550DF5957E6C54D7AFA950F2E
-:103DD00042644FC03B0405CA8428CD1CD89F4E6F57
-:103DE000D838DF799B620CAD4362C5FEEEEA91DB09
-:103DF0006DF20F84903E3A264DAEBC05E6EF9D5421
-:103E0000301AE7DF5E73D4860F45B7C753140C38FA
-:103E1000A21F5E97A4B8DA06D9D85106EB0B887CAE
-:103E20006B00B33292967760C1A184611D1CAE8491
-:103E3000C2D7C30AE0796E5D2296E4EB3531EEEA33
-:103E4000F32543E82F2A75A729DED6E94F2EA2BA1B
-:103E5000030E6BFCDF6A565E00E71B9FE09BE649A2
-:103E6000DF5E4479E4551AED5BB76B6801D6636B8E
-:103E70005DECF10CF19B0D829FB7559E3F2EA3FA8E
-:103E8000EC70747BEDFEA205CFFBA274C2D1EC1ADC
-:103E90001A9569FF3EEDFC175AF7E73D5FE708F911
-:103EA0000397BBEDFB1010F2BC79CAB743782E6EB6
-:103EB000C1D329C13ED47CFEFBD03C85CBEBCF7B6C
-:103EC000BDFFD3C6FDBDC6E32AC0A7B3CB31CE38F4
-:103ED000667208E3B53E2B1E1D8E537E5200E3D161
-:103EE000D4CB203DA4EA7C0C456509E44339FBC3EF
-:103EF00004EE9352AD190AC9D9CCFBAE8437515E9A
-:103F00009B933F2DB8E96FB2301DE8FCD06BC5A77D
-:103F10000D7532BF2F81F15F8559E7B33C3E6DF5DA
-:103F2000572B648A4753203B6D1C15F4309EE328C1
-:103F300018A7CE1B3EFF7753F4689FBF88C7C715ED
-:103F400095FB81EF491C1FB15715CAF7EC7A9ECB40
-:103F500037769C91FCEEAA35E85C6507FC8FFE4342
-:103F6000ACD61747BA551CF978672AA787508E5ADE
-:103F700071719A8F9F0F509C1BF314296E6EB00ABB
-:103F80007CDF2D40B3C651ADB87CE59A49D8CE6FE1
-:103F900030CF73B03E7F1D4B5C02F006DDAD5B2F72
-:103FA0002FCD100FAF5CF38D2761DEDD4F4DFFD5B8
-:103FB0009350DF25875FAD8376F95FAE23BC3AE38C
-:103FC000E1DB2A655347F9E0F31DC27D051B9AE842
-:103FD000E2D61E2986CFB37DBE837CBF5B430AE257
-:103FE00005F424E2C5EBCC8B4CC77719C2B17360E2
-:103FF0001EFCDBBB75DE329C17E1C6FCCA15BDF5A5
-:104000001AEA99E012FBF985BFC95EF756D9E1DCDF
-:104010002AF6EF42F4EFCC43EC31E72D42BA3D13E0
-:10402000D418CA9B8D6BAFBE91E4FE76858D2BCDE7
-:1040300040BF8E75756A2ED2FFDD46FDDE0AD41BA9
-:104040000D1AE5F574C7BD714CF1DE5E973A37B1D4
-:10405000D9EF86C6CFB16AE4843B931D2FCEC70249
-:10406000E219739C8375CF96C9AEE9EEE1F358E38C
-:1040700075D7BDE5413931D2B84F8F318FB8D19E58
-:104080008AE65DD4BD8BFB36BA385D4FD1E252294A
-:10409000DAA3FAC24550DF3C4E267B8809FFAFFB0E
-:1040A0005A7E9EF8B066D8EE576C9AB292EC869B18
-:1040B000DCBAE02FB00B27A4EE5B1CF09A2FB8E11E
-:1040C000B9FA1C8C04F6C07BB9E11B912E1A831F30
-:1040D000911D756B91AC237DADD8D348EBDAACCB99
-:1040E0002C8176AFDA4A466A136B35F13C00133502
-:1040F00091EEE6C01B99EE45240F75029C73C61520
-:104100004EDA063577512BE5B1341A12F961D70131
-:1041100066501EB4144754A90AFBCD7F07EDBE3983
-:10412000C15219FDFDEB54D6A0A5D9E760171F7346
-:10413000A7ADEBC4B83D41B90AE7877970FE451ECB
-:10414000BA4FE046FBF8CA947D3C1111996627FFEF
-:104150001A8D4A8C6714257E4F79DEDF4FCA382FBF
-:104160007B81556F933EB95F0DFEE52F713FE3CC28
-:10417000E8C754C3CF1A97F8BA26F649DC5B39EC86
-:1041800089FC06C7B7E20113357EBF79730B0BC7F5
-:10419000D2E22A9B9FFFF3E368AF5AF197737977D6
-:1041A000024E0BEE4D12CB223DEF89FEC19DEE1764
-:1041B000B364D9DC099F1FDC19F2E57CB5C04F63FD
-:1041C00005FFE4D55678516E8EC57C1FDC87762EB0
-:1041D0004F4CF82F3DDF4711CC170CB7F6CBC6700C
-:1041E000B9A4887B5340D712DAB1CE7C2005F37E88
-:1041F000260E971B0704FD5FE211F93F93D964EE89
-:1042000087DBCFAFFC4BB9DE67AD7919EFA17E5FDD
-:10421000E8FD17855F9910F71A8F8A7B8B2FAF33D4
-:10422000C8CF7B655D259503EBC2F4FCB57575546D
-:10423000A6EE57F179F3851DA662500DCFF97D2CBE
-:104240006E00BCFE516B064A91CFEBF8FDEEEEA678
-:10425000535BCAC96EE4E7169B8BAA1385E8BF00BF
-:10426000ACF95077F9FA3CFC9E97395859C0D51CE7
-:10427000E2FDBFFABCC24917BAB5FF8EFDF6B156D2
-:1042800086F22E60DAF73B3BECF46FF8FEBB8A2E29
-:104290006EDF7BF11FB08F5FB2F6FD6A7635FF3EB1
-:1042A000C3C5C963E4A34A2107C6003F1D007FDEE2
-:1042B000ADF07CF57C9EE76A8638BF992AAFC7C609
-:1042C0008BF62E4E426C208FE7B517F3F304EA8786
-:1042D00079E5F81EC3922FF0F816CB11F9EF63C5FC
-:1042E00038ABC5B813ABE9DE2E3FFF677D3A963E8B
-:1042F00096A47A2EF0019641D62A2132C7B041F217
-:10430000B78BA521AA1B929E85F532295CC6FDF0CC
-:1043100038E9CF72C5FC7605213F22F3785172311E
-:10432000D993A097512EC6D5C822942F1BDAB4304A
-:1043300060E25C9E1CDE9FC372435FCD009E7FC423
-:104340006232C91FE53996A55F49F61EE9AF0DEB4C
-:10435000F30E6653BE4692F2DCF77B4A6D7A6AA290
-:104360006FE1753AECD746914FE782FE2C43FEA9E8
-:10437000954F07E396647A6F951BFDDAA24C7EFF9A
-:10438000C31E49C43392A3290E28F6353E55CE7874
-:104390009F719F87DB358F9666B6A7197B90C6DB2A
-:1043A000EFD11DE3265BE8FE8CCEE31B592E93F282
-:1043B0006B36B6F17BFA16FE46835D8BF6F0C6BE11
-:1043C000F9B391BF63952AE59BC3FA7D883F97C8EF
-:1043D0004BDE383E78309BC7254A514EF723FE6AA4
-:1043E000D3F0175CD984F8EB7895E7F7823EF7B104
-:1043F0000CF98616FE5C3EF6C54CEFADB26394B682
-:1044000028D3BDE1A31ECB4E4F96723AE1F8CBBA4A
-:10441000568D646A9F10F82E2963D1F3E1AFDFA3B4
-:10442000DBC6B5CE7D9511E25D922F4171AE891A42
-:10443000B733362CE678DDF0FC35C7A369E710BF4B
-:10444000C421A7A4E2C156DCD8D29BED9EE83F7AF6
-:1044500046A5F425FB3E23B9CB5EF01CC47DCB7092
-:104460000E71CA539BE11CA2E7E2BEEF3256F0ED9B
-:10447000A12D47E7E13C7F55C7C8BE0A3CC3E7CD45
-:10448000D5595C2EC5EF149812C659AE89E8F56867
-:10449000BFB9DA9989F9336345DCA6B0BD4F41BA9B
-:1044A00008C25E164A78AF2919C3EF998CDDCDC8D2
-:1044B0004F540B67AE5A6F08519A961FA5B0A17E54
-:1044C0005A5FBB663C5E4A60FD14F5C318F13ED0EE
-:1044D0003EF3572837C744A294870BFD627EB42F62
-:1044E000041E0BBC9C6F9737842509DA0783498A21
-:1044F0004F3AE5FA18C0CF2569F65B40D4D92A2E89
-:10450000A765F80FF57C7EC42EB7C739EE45071CAA
-:10451000792FB95E91EF6EC9ED22BEA913D441394E
-:10452000935F9ED2AF0EF8508655A7FA07ACFA6794
-:10453000840F0881E8D98207AF52A2DCDDE3D2BF45
-:10454000F214EAE77A8DE79189FB72D902EF3E74A3
-:1045500098A1DDC094574CDCD71D61FE5D9A3353A2
-:10456000E7911F9A5D67DDA7E3F795A18C619C2E0B
-:104570005BCC6FDDABCB66C69BE5400FD96692EE98
-:10458000D5E9D677154C96C03C1CDD27531E9DEE11
-:104590008B907CEA59E0D1F13B1F9AB8A7E712F75C
-:1045A000C7B3CDD374BF2E7BD8FAF8FD3A0BEEEC2F
-:1045B000ACAA37CB0DDB3CEB31BE0D6B1F9DF17E02
-:1045C0005D1DF793B24D1E87481B9FEED7ED985A9D
-:1045D00066BB5F47F3A01F27E8CFBA67E784EB5CB1
-:1045E000BF9ACC76DA84B0DD8EB8D0FD3A57C8DEFB
-:1045F0007EC705F2B33EF1FD3A818761ED1CF6A05E
-:10460000CBB24347C90CF7EF4C834CDF11C9FD28EF
-:10461000199921515C82F4BD65E7E5F1A1FEDBD972
-:104620007979565EBFC3CEB3ECB7DCD9767C3BED6F
-:104630003E775584FA5CAC9DB70BFF01F4F290D73E
-:1046400061E73565A60FA7BCC86783BBAF84718ED1
-:10465000D6FE48C17CB55DB9FCFB476C987FF0D6AF
-:104660000CDA171FFFDED1AE29FD2A7EFFE6774B5D
-:1046700019D949561CC12D60DE5524AFA7B07BD790
-:1046800043849FA0C043137E80AC8670151F477C77
-:10469000667A316F21BF8951A3C28A30ED3B7E9685
-:1046A00040A64B5B3115F5783D62250D4F333CF646
-:1046B000EF0434EAF98E7DB4EFF3B973F007F9F73C
-:1046C00014E618F67DB7FC24346771BEEB2BED744D
-:1046D00070428A0C2AD0E5E9AC5261FF0CEAA82F9F
-:1046E000BBD7BAC86E7C6849D9D62BD15F0DCA3A00
-:1046F0003F8E1C1A87F651F351D38B76DEF6C874C1
-:10470000EF3878FF50871246F3F0A9256B5EC57A23
-:104710006CB78BECA0A7FAE615AC48E3BBCDBB1792
-:104720002C5C8CEF3B5CA4DF57ECB96FA03488FDA8
-:104730005DB5E9DF9B6AD9789F8E7EDB1BB5DE8C89
-:1047400076CCD559DC2ED9A82529FEB4719EC6D0C9
-:10475000E5DA58523F7A05DA0FD76819EF93DF95FB
-:10476000E5E6F7F95CAD12CAF7C268E67B0156BB15
-:10477000B135BFA5738CE06C99A11FE7BA7E9E8C02
-:10478000F587605F7529454F79829E3616DDBBB58A
-:1047900002D73790F9DEA155AECD1AC7E93462E7EA
-:1047A000735761D3685CB7CB1D19A847E22A94758B
-:1047B0008C8BB8DCAD919BD11EBDDA8514CE3677DB
-:1047C000FCB06111EE4B58D2259827A84656119D92
-:1047D00005B318EA8386259156C44B21E83F0CEDBA
-:1047E0001516FD92CE290AEB34E685BA67494FC209
-:1047F00005EF3D15D1AB10EF2FADE5DF79290CFAB0
-:10480000E85E5061849FC315B6BB199A0C1BC105A5
-:1048100076917F20519CC8C947D6BA9A977239BE03
-:104820007BED6F4765FADE4C455619E1D56BD8D75D
-:10483000ED41BD0BE34C35079710BE6BDC2C4EFCF5
-:10484000EB26FADE55EB22B8764D39F91584EB7775
-:10485000BFCFA2FDBE969912C2953FC4CF59AD7984
-:10486000F29B06151E0FE77CE8E43B8B1F9CF0EDE6
-:104870009C3D8FCEE336B3C1F988EFD85999E868EB
-:1048800073D11A6F7A5CB455D01FEC03C99798CED8
-:1048900068BF957F65EB311F76E3172395C81F6FBF
-:1048A0007BF9BDD5FB966AB48E87E66A146F7CC827
-:1048B000DF4A747F6AA32B7C08C151F585B89FBB82
-:1048C0008B2BC2186FFB3B3C7C4EF30F768FFA525A
-:1048D00025E2F38B7FC8E2E34C51AD717E46F45E76
-:1048E000EB25386728ED3F5B8176E8127932E54E9B
-:1048F000AF5A42F2CB25E4F8CB4BF2EAD14F09DCB8
-:10490000B09C7179C8E31481B5D5FC3E8343EE2792
-:10491000EAD4DD33689778FCA75EC8BBB1374CAFEB
-:10492000C775D60BBD60AA99BFCB982BDA170E4579
-:10493000D0241B16FFC915FA63EC6EC773A117725A
-:1049400087C5C1072B6E06F9F3A52C61478E10F7BA
-:10495000D9B5641EF1C319E0078A4B979C24FA8FDE
-:10496000819C40BBF90D29195A91761E667D67EE30
-:1049700027221E14314B294FF82D110FFAA9F8EEFA
-:10498000DC3B221E745CC4837E2EE241FF80F1205A
-:10499000FC7E98F772DAB771751FF5631C6767CDF7
-:1049A000028F01E34CD5075F4220BF680EFA44FE38
-:1049B0003DC11BB4F4D0DCF3C7A91208971BE35226
-:1049C0001CCE97C5F7E85E11700D08B85E137059DC
-:1049D0007A10E506D2191BABEA99E461506D95F0A7
-:1049E000BC17E5457F90E405CF130FAE918C09C34A
-:1049F000E5048C373ADD4EB7E8EFD4281FD1B17308
-:104A0000FC47B3F8BDC397D6CEDACF8269F228B29D
-:104A10007015D25D3EEC0FCAA3681397E351BC77C3
-:104A2000912657AD781AEC4898F4CE0D1C4F23C947
-:104A3000970BC99542875CD98D7205EABB51AE04CC
-:104A4000D3E54A6B3FAE3B887285A5F45030F2C97E
-:104A5000E4CACFBC65B63889255FAE0636263B3141
-:104A60000CFAD4FFE9F5E9DB424E5C48AF5AF91F76
-:104A70000193915EDF837921E8CF8C67740F473112
-:104A800007299F28B7DDC5301F642B76198DFECC12
-:104A900042CA07D931DFA3235D3C2C254288CF7D54
-:104AA000528F97EF8BDE8FF6C2B6093C4EB2E38F82
-:104AB000F778D1CE7EE9F682009EE3F4E65A7920BB
-:104AC000FAE25BA17EAA91119DACD8B3C296F7F031
-:104AD000F3AC3CC2476E0CE40FE0E3E1DBB9FED17E
-:104AE0000D9E070265C63C10B74FC483D45808E931
-:104AF000639B14F5501CA651263DD51BE6F92BBD32
-:104B0000E097E3F9606FC3CE39A89F37DC2A33CA38
-:104B100017AFECB907E54CC7848506F2A56B74D9CD
-:104B20009B688E6FF0C9DEF43C523C4ED0AAF9B9B6
-:104B3000A128CD1C0079B3D734CE777F54157E1FC2
-:104B4000F6779F270FBE3337341AE304BD8D0B432E
-:104B5000386FEFA848288FF253C6903DB071D4A6A5
-:104B6000C5187FEA58AEB1743B69D87C41BB7D6DF6
-:104B7000C519D5069E3FD22173FF32579C4F035F64
-:104B80005522DED2D78970AA26CF1FC1F52A7CBD57
-:104B9000F47DD3DC06F00FABF8FAD17FD57DFA684F
-:104BA000941F6A03CF1FD9ECD717A3DFE884C31A79
-:104BB000FFDA6CC9E61FE956DE42FD1A7E8E58C444
-:104BC000F3167A5DE7CF5BE810F2D0F21B47C2879D
-:104BD000CB714EDDEBB5C7012D78AE14A5138E91C8
-:104BE000F2053EEDFC175AF7E73DDF4879046BB25A
-:104BF00025DBFD8A5C2B9FA5714D08E58405CFE67A
-:104C00000BE48F7C5AB89A1B79FBCF7BBDFFD3C6D0
-:104C1000ADCFE6FA11F87400EF51764C9C19423989
-:104C2000948AC70C0D94A33D27EE335AF9232E9D89
-:104C3000FF5355F977EEE4EC22FACEB23A9DE78FB6
-:104C4000D05F863C904D8CCD467F4715F11B279F4A
-:104C50005E087E67DEC8CD3EE137461DF3893C1114
-:104C6000E6C83B51433CBFC4CA27E992607DC154AA
-:104C70003EC888F33AF0365EC8FDF71CFD87AD3BB1
-:104C8000CCEF575AF927C3F248A6CAFB710B86E549
-:104C900091887C949E5C23CEF3C4795E09AA4D8CE6
-:104CA000E70DCB23993A3D84DF949C5622FADDC070
-:104CB000E8FBBB3D5E5EEF9DC3E2F8BDB35EAC2397
-:104CC0003FD532CA6B19965F32750DE14963916524
-:104CD000FC7C879FF75B7870E6975C90DE2E9047B0
-:104CE00012F459DFA388D03C3DFEF04FEA083E990C
-:104CF000CEE30BBE743C9C3EFE253E2E277B441E1D
-:104D00005E4FAE3D1FEF3EB12F15A29D737FF52282
-:104D10004ED75DF53AC5DDDD0D3C5E39EC3B103517
-:104D2000767FC019CF3B21E4F585D6EF8CEB6D1B68
-:104D3000E1BED9021FCFE37A68C921CA8B3DB30A0D
-:104D4000F42CE0EB61CC67A9B9F87C96D7B3783E38
-:104D50004BAF51BFF052D463518DA13CEDC57C16D1
-:104D600078BFA161847C16114FB4E2A323E5B3E4BC
-:104D70009E3B8FB7E7B3F4DECAF3597A7BF83CD693
-:104D800078BD0DD564678D34EED3634CD987FB5F56
-:104D90007171E7A7D34A227F86F92B3DA59AFEA021
-:104DA00081F4C2E9B9AB5123FAEE72713F36369AFB
-:104DB000FBCD4C8D8716429B2DFEC4228A278BBCCF
-:104DC0008C5E717FFEEFB30C9B7DDCD9F8DD10DAD1
-:104DD000F540872FEB9C4F689C7CB5743DD880CC08
-:104DE000ADB798E8530E64F338822B746CA02E8D07
-:104DF0004EB7087D87F891013FB9D2397C45E5026D
-:104E00008AEED3DF1A419F6F64F3F92D3A64EAA466
-:104E1000303FFF631528472CFF75583B0F6F374C09
-:104E2000FE38E4480FE6B761C592273758F2C44E02
-:104E30009796FC600E39734E9ECCE176FA39790272
-:104E4000F2033F75E69443BD5EAE2F2C78DC2898C4
-:104E5000418EBCE70ADBE2344EB973213EFABCE571
-:104E6000CE4BD9F9C2FEE0722788B4817C936D9D48
-:104E700023F27B0F67A63E48F2D0A3F2757B228C0B
-:104E80007E2700EB28CF3D788E9251AE574B146FA2
-:104E900010E722F9E2FB830FBBC2949FF630F03398
-:104EA000FA79130CA77D76FE7305E779D2C36BBF41
-:104EB000C6FD33C037FA5D172B872C39F161365F99
-:104EC000F739FA32399C167DA5D1337D5FC0A25FD8
-:104ED0006B5C8B8E193268C179E855D03586A32971
-:104EE0004E1D93E21807B1F2C8ACF1DEF0717B649D
-:104EF000A4FB5556BBEF587ED7B978B01ED0299F7A
-:104F0000AC87EE9BB32E4E7F73D86E754D15E513AF
-:104F1000A88CF2092225E8CF1CF6D9FD622B1F6C64
-:104F20005A493884726283B0D3AD3C322B2FEDB036
-:104F30002FD73A67B6E5A76D18E17EF69BE7F073C9
-:104F4000F1DF3FC1EFB6ADF69A8FA35C047C99E226
-:104F50007B4E9487668DFB5D81A7D73DE693BECFE0
-:104F6000707FF2C52C7BDE55A7CF70C405385E2755
-:104F7000EAB17ABA8F17E5F7AA9CE7EA23DD7F75D5
-:104F8000DEDB3B77FF559CBF377BA22F13FC2FF254
-:104F9000FC373D1C3DD8C93EBFF51CF09A3FC1F11E
-:104FA0003B057F4F0BF27B3BEF7BA26FE3F3EB18EC
-:104FB000F7AB2D3BE730B683FEFE97416A03BD6C2D
-:104FC000AAE5F45A54C9E8FBE3D35B797DC752FEE6
-:104FD0005DD3FED7F9BD8F6D51FE3D53E8D7270352
-:104FE0005E768CE7FA707F15EFB71FEF37219F567B
-:104FF00070BB2B0FA3F70A8AEB2895D36B7ABC13EF
-:10500000E0FD81A532C545F708BE083093E21CDB00
-:105010002AF93CBB2AE427C4F76816DD02F5CED98D
-:105020002B27E3FD92ED229EB26FF1CA2730AFEF3E
-:105030008340B9A0BB04DD7BED397E1BC5471E5AFA
-:105040009227AD8435EE3B9839BFA5CAAF8A7E3131
-:10505000B788278932A161B9D51479ABAD4C7C8F63
-:105060003DA661FCE999419EB7DABDFA99633351D7
-:105070001F57CA9467D63578D47B19AEBB8EE7F537
-:1050800014A90929DD7FF1FA5DDC4EAB39EA31AABA
-:1050900086B77F66F028D1DD76C0BB92E6FFC902F5
-:1050A000CE6EF427A0DF5E57CFC04C68B7775C9E0A
-:1050B000143352ED46FB39FF752F91C577E8197D02
-:1050C000C7A1D33CE541B9D989E71FD0BEBBC6CA49
-:1050D0004BEDA17B597BE74C9E8379E2DB6EE0C10F
-:1050E000D2AEF021F2937B6673BB6CAF04ED605FD0
-:1050F000F6B568D7D33DA6561E278232639CA81703
-:10510000138111AFE2DC8E525F60DECE86BE019C61
-:10511000A7A88E7FDFA2A82673FF17026EEABFCF73
-:1051200015A3F8E748FBF7AF3E8ECFCE2A7E5EC0D0
-:10513000589CE252BB85DFC5D4A891FE9DD0960055
-:10514000C7CF4E1733315EE6ABD348AFCB6183ECAC
-:10515000503FD88F188FDB26C516637E486C92C6E9
-:105160001E278C98DE7118BF9B901746FADB24250A
-:1051700042F85DE5D8381EDF3E1AD949F7AE0E80F9
-:105180001D4DE16096203DD51DCDA3FB504723D595
-:1051900083D4DF57A1BB2D8D8279F3F4A148C626B5
-:1051A0005DB6692BDA359D53641DF3363BA5FA28AD
-:1051B0008E17CBF5501CD935651EED9F6B549E9410
-:1051C000AE8F6EF473BD30342172A31FD6159A7260
-:1051D0002A17E396DB6B5FD987FBF7C8FD1EA2A3F6
-:1051E000476A07EFC679F69FBDEA7894F8929FD791
-:1051F0003D5A7BBA14ED9E5D4DA772117FC5189F75
-:10520000037D585CC1E368A801C93E537BD8CD80BB
-:10521000C7E2368D1969FAD8CBF8791EFEF92693C4
-:10522000DCA3BF67064F795A70BC252C7169809E3C
-:105230007B309E65C999E23A96280079B87FC53BD4
-:1052400031CC937B646201DDA32C12EF4972C278EA
-:105250002562BCFE375E598FED1EAD2E30505E14B8
-:105260000F0CCD4325515C759AE26C21EBFE47D4BF
-:10527000D87F2BD1A74CDFA92C0EBFF317B88E8097
-:10528000AF8FF41CB4A7B899731D8189E67D7EC0E9
-:10529000E337A5D657C70553FE18FD213FDECBEFF8
-:1052A000651767FDC35C252DDFB644C40536498309
-:1052B000B3C92E7D80DBE163599CE45C7155EC6ED3
-:1052C0009E6F1BA57C5BE7BCDBFDE7F4AB44F7A856
-:1052D000F39BC4BD12FE3B3625E2776C9C741F0A1B
-:1052E000E557755C95AAEF8B9E22FA7F5A33EECA7A
-:1052F000F4BD877D422E6C12FE9835FED85C3EBE12
-:10530000557F54E7F4F8F4CB79D757C17AFEAAADAC
-:105310006C12C63F778CE0C7AD0C70FACB1E000B49
-:1053200007F440FF6BAF79319FE56999AD4239557C
-:105330005F95F024AB041E617CF2C560FC03E16F55
-:105340007B502E7D35504970AD98CAE3069D550FB0
-:10535000D2395048E77A07F913E5BB2F149330EEA2
-:10536000BDBC86E98744BC2506F8A7BBF3324BE5F4
-:10537000F56FCF253F077885DFABC1DCA4C9E2F725
-:1053800027CAF19C68D3DD227F56467C778A7980D4
-:105390006F699E0345629CFBB8FD8FFE05F62F17D3
-:1053A000F394D77DF76BA8C78B744E1729F8FA3C96
-:1053B000045FABCC083E35F12AFAA1DB271518486B
-:1053C000370742E1B79BA0BE7C914AF1F8F21A0E72
-:1053D000C78156997E0FC85FA71DA4FB6326E88B83
-:1053E000347C1962DEA29A8484E75A462B5F17B494
-:1053F000F3A25C34C2000FD40DB1AE73F04FD208EB
-:10540000FE22CF20E6169DC3C34A1C0FE877651D18
-:10541000EFE70FF56D4139B6BC8EC30DFA9DE0295B
-:105420000A6B0751DF1785F878CB013F87A4145C1E
-:10543000D9165C7532E55F15D56807D10FCE16F029
-:10544000AD0C7378FA5F3F3520F1F10C1C2F5BC077
-:105450009B2DD64F09BB05423FC0784FB912F57856
-:105460002FE7D414661CE2B3513CCB7ABFAB15F0E6
-:1054700000F8F18B79D86E37F1132C31F6B1CC7F6F
-:105480003FC4488B5B54ECD66C75BFD83FD6C59FE4
-:10549000931F472A91D765E1D7ADACB2F763356961
-:1054A000F532BC5FC6E97DFDB5FCBCE3C0046E1FF0
-:1054B000A1DF718EBF91CEA7188F7505F1BD46FA99
-:1054C000AEA4DD3E6E716BC174940FC5030FCF9314
-:1054D000613D45F73259C9217A96CEC93F98EFDB35
-:1054E0006B12747F367B209287F2AEA4356F3A7EC2
-:1054F000FF2D7B204AF5EC815693E79F810B938724
-:10550000F97A69F394A29CE6F974AC55EB43B95669
-:105510009B0E27BC2F79B9672EF6DF7CF72BA39162
-:105520007F0B1CFD3D39DC7F287E195A0570FED3A8
-:105530006BB1BD15DFC94688F3A87C19CB621FC8C3
-:1055400063284B44FE9D252F3A27BC3329EA13F4E8
-:1055500043F9782C916EE73B4B683F5EB48F49E787
-:105560006D779ADA8D146F1A08F0785340D8AB3DF6
-:10557000CCD84FFABD86E77BF8F039E88FBE9AA306
-:10558000D3693FFB5818E9B9B8ED4FEE74797D73D4
-:10559000A054DC834E10DD6B255974BE077C4CDFB4
-:1055A000373DA0B6D2396B5F113FD73C3AE71509BA
-:1055B000F159F41CCFD3B6ECE5E93589103EEF7A0A
-:1055C000357A19F1E708F6A7656F3AD77349FD8375
-:1055D000240FC6469917CFD7FCAB55CA632D890255
-:1055E0005C55281780A40B01FE9AD87AA41B23CA05
-:1055F000EBC66A51AE82F26AB06FD70D94FFD295B6
-:105600001A776B05D8B5683F0DEEF6DC80F64A2BAD
-:10561000582306DA8BA73CF83D95EED6E9F988E7E2
-:105620006722967D999070FCA29F9A642FD6EA9A81
-:105630008E719809EEC4E8F473BA0373DEA9A6EF7D
-:1056400089CDBFB87CB291F409C222A7E991FEAA24
-:10565000A3A45F9EF08F273D64E9154B8FD088206F
-:105660005F6E117CD465243C12C92BE05D80F3167B
-:10567000942340C7FE222ECF410E733967E993BBB6
-:10568000B9DEB7E4678518E71694B7D0AFBBF689E3
-:10569000DC1B50AE0839EB0F1933F17CAE42C85712
-:1056A000A6C6249CEFC014FEBDCA80439E56B4F229
-:1056B00071BA428CE809F4D041A49B034509BA278A
-:1056C0007EA0F5A8947ECFD4D27781D624C3FD1FC7
-:1056D00057C7E5E0382157BFE337387D7AB85C3DDE
-:1056E000A7F784BCDD6A1E65E2BBB019F3B0FE5EAD
-:1056F000E8F39E8A43E4176CBBF514E1D38A8786EE
-:10570000443CB4BBEA2D7ABF3DCAEF01EC32A7CFCF
-:1057100021F823CB35CA3FAD393AA70CFD8DA6E55C
-:105720001ADA75270305D6F9977721DA93ADABC856
-:10573000FEF5897D7C28CC84DFA9919F75DFD26F2F
-:105740000F60FF10F84592818DFA3C6EA473FC9EA9
-:1057500002E23B3A489D7D35067D07C2B98EEF05D2
-:10576000F87769FDD1E4C038DA5799AEF4F86A18D1
-:10577000F99DCBC1AFC36177AB61EF0478BFBB4983
-:10578000D6D7B354FFFF15E0F96813FDFC9EC2CED7
-:10579000C5A7B7609C6FE752F19D3307FCF735F65C
-:1057A00079149A07630294C79CF17BFB55FE2CFE8B
-:1057B000FD859ABE01B4E703551CAE170306C7FB6F
-:1057C00020C7634F44263EDA3558ED457DE7B41BCC
-:1057D0001FC97E7712CF6BB1EB9B0BD58B1D727FF0
-:1057E00082BBEF3A9277DF94495E31C6E59DC4648F
-:1057F000037F57A325C0E9A94AC8EB0E57623FE6CD
-:1058000015743CEB63EB8D145D1489313B5BE58CC7
-:10581000BF9F7628A0F0FD1FBEEFDC7E10FBFEA42C
-:10582000C0C385F61FC32C684FF7C5378DB903E594
-:10583000782BF79FFB126F51DE51D1EC85E4F71CFA
-:10584000397829F9034555A6EDF735B347F05B2BB9
-:10585000723CE78D078C248FF7ADEE203F7BDF6035
-:10586000E67B3105393C2FAD0FE4257EDF64A4F9DA
-:10587000F51CCE7FFF14107437E71DFA5E469A9E22
-:105880007D59E859D2B7C52A8B2969790E1304FED0
-:105890009CFA93A971CFA53544E784BF7DE2FCE271
-:1058A000215326BC5B748EE7078857588729E890F8
-:1058B000CE377A58DC837C136BE2791E4EB827F81A
-:1058C000E58B5A5F3087FB21E7E613FEFA443F87FA
-:1058D0007B67EDFD74CF11E60B217D483FF88FD338
-:1058E000741FEA5917FD9EED8C675D098C69DD799F
-:1058F00090FFDEA2FCA297E0FCE7C3FCFBEA093FB5
-:10590000B7C77EADF3DF2BFAAA7BB0FB0B501F7A33
-:105910005661644FC6417101BD9E16F4CA9EE3F5FF
-:10592000955E5EBDF360FF321C6FD5733C0FF3CE06
-:10593000E76FBBF10B50BF6DC0457706EE7C7CBDB9
-:105940003606EAB7C7A53EACFF663AA3DFFB8CE597
-:105950006914E7FA4D60B06001E0FB83751E665C78
-:105960008671D2C182F980873BE24FCFC47E773CFB
-:105970002585916D673CFBF82BA301AE3BBF215100
-:10598000FED7578E64DBECC2D3B09469F07ECD4174
-:10599000FEBB91B7B19E99888F3B1FEFA5DF3FB447
-:1059A000F0F9C1BA4A66A4FD6ED89DDF789A7ECF21
-:1059B000F0AE6F49F4FB8A77C9FC1ED13F3FEF5D23
-:1059C000F4980FD7B75EBBD48FEBDAAC61BBDBE2E8
-:1059D0002DDFC594A63BE207B599F0FE8E0307B50F
-:1059E00095E897B95933EA9FAF1CB9C226774EEFB5
-:1059F00053C83F5893EBA1FBF5CC6786E64D18BE24
-:105A0000CF1FAC6336B8EEB0E2046A5C9B9BD6DE77
-:105A1000A573FFF72B4714DB3C961D103BC6F542E0
-:105A2000EC6FFD143FB7F66F8DF0BBADFD5B63050A
-:105A3000E2D5A1C999E0E9C6FD00787AD6E954EE2D
-:105A40005C17A272F73A83F6692FE211CA2E01772A
-:105A5000602AABC7EFF3074C9E769CD764D6E3DD94
-:105A6000B2BC08AF172C89921F32921D63957B5DE3
-:105A7000D116F4213B77F4CF52C1EED9AB45EFC636
-:105A8000C897DEF1EAAC06A8FF4D4E64630EC99BD1
-:105A9000B0817C67F9E75FCFE17277D3688DF0BDA5
-:105AA00077E9E4C714CBFFC2B8DFD2954FA03D0120
-:105AB000FDB7E710DF86E93B5D23F52F585667EB0E
-:105AC0005FB06C95D57F0FF5F79CBFFFDE65D7D82B
-:105AD000E75F7687D5FF1182DF777EF80B9AA7DA2A
-:105AE000E76F5E4DFDBFEAE6FB3B94EBA17CFA0E4F
-:105AF0006F38E122FF99D1F739D4BC4B0FD1F7931E
-:105B0000CEC599064DD4B3BEA772AB518EA5E86839
-:105B1000FA37711D7EE0AE743ACAA9CBB2F155AE28
-:105B20009967ABE7CF1E636B3F2A52667B5FB8E88D
-:105B300072075DFA74CA83655C9F9A18E70438B5EA
-:105B400031FC7B4DF5633CB4BEFB5FF452FDFE6B54
-:105B5000F8FAEE1FE3233E26DD05FB7EBF16BD32BD
-:105B6000DD3E86754918F27A468F0EE4D4A63F379B
-:105B7000647C9EA5F0DFB1CB72737DB9B974F2631A
-:105B8000B1347C6E29067A80FADB399A2DCEB3B90E
-:105B90007865A8256D9E4DC5DAA24355FCF92D68A0
-:105BA000C7EB91BFC3F9BEAA0D5D8AF6AB731E7732
-:105BB000599D6D1E4FC92A9A27E998C75DB2CA310F
-:105BC0008F67D121F15CCC730AE964A47936975DC3
-:105BD000635F4FC91D34CFAF719EDAB4F594DCE139
-:105BE00098278BAF079E8B797E73DEF5944FB5AF08
-:105BF00067EC6A9AE7DF1DF3B8C7AE76CCE3A3790A
-:105C0000F039CEC38AB81FA5B98756D2FEFFC0CBE4
-:105C1000300EA4B9A37F4D9754FEDE4B71616865C9
-:105C200062BBFF03D8CCA6FA008000000000000091
-:105C30001F8B080000000000000BE57D097854452B
-:105C4000B670DDBEF7F69274773AFB4208378010E3
-:105C500034C40E840C203A0D41061DC0E00A2ED03B
-:105C600061C99E74449C87A34E1AA28888DA286A68
-:105C700050601A04071CD0C0040810B001757006EB
-:105C800035BEE7B8CC82CD2241884983A8F866F1B9
-:105C9000AF73AA6EFADE4E079837F3FF6FDEFBE3B1
-:105CA0003753D4ADFD6C75CEA953D52427819051BF
-:105CB000841C8CA3E90842BE89715FEDB012F23DED
-:105CC000FCFD90D03F2F21C93C4D21642EE17FFE89
-:105CD000C5022924A4D6CCB273364FCD5A08694BDD
-:105CE000515A4901FDC70A9BF30A8590CE9622E3DB
-:105CF000ECDC707F6A3AD7279F0CE6B0B6DF93F0F2
-:105D000038DE7124A78E8E5F16E7C0F9A8F993F5E7
-:105D1000346F22E4583DC1B45D26338BE9F713F5A7
-:105D2000740283B5F35D88ED4E4AF49F49345D25D6
-:105D3000F8BD025DD7F20F64320087F93087AEE319
-:105D400076BE8CB9BE5842CCE179784CC405ED42A0
-:105D5000BB4CFE75027C75F531A4D1A43191107550
-:105D6000BEFD09F9D3BEC96F0B76CCF6318C24E4A5
-:105D7000CE255BDF826A1F09257DE7D1F54E6B5E7C
-:105D80002EF7A1F94E3938C369D5F4334D3E06EBF1
-:105D900036D3FFA09FE96E9AD78C7F57B93E7F0F0D
-:105DA00091C2F96C42AE72F4E7F8E0E32A7E19F092
-:105DB000753B5D533A45E13D900E836207E26B8689
-:105DC00083B555E7E379502601988F144C26B950D6
-:105DD000928CF5DC504FE939BF19B2D9554CF139E5
-:105DE000E30111E11839DFE0BE5897218FA68D5FDE
-:105DF000C9A4FFA5E73F7381BE9C78D9782A5C557A
-:105E00003AB863DAD8674F68E863BAFB86674FE849
-:105E1000E0345597BFA76EBAAEFECC0525BAF21294
-:105E20006F85AE7CF6927B75F9B9BE0774F5CB1A17
-:105E300017EACA2BFC8FEBCAAB362ED7E56B9A5606
-:105E4000EAEA7B5AD6EACA0DFB86DC44281C1B7E94
-:105E500027121385E3D7D6934F5D9304A9E404B8C2
-:105E60009FAA4F43BA3E5DAF605A0BB4370AF8673A
-:105E7000B8D94DF1E48909959278421EF68D59B250
-:105E8000640CCD1B69F9684AEDBE714BBC99842C3A
-:105E9000712848F762A3910428A90A24A19BAE4364
-:105EA000A2A63C7889F246890486F72C1783D1BFD5
-:105EB0007709A14119741DDE4F4D6483D093CFC380
-:105EC0007C49FA90B4DECB3B0CA4BC49237736382E
-:105ED0000C389F64C7B80D0E4A0FD546C6EFD5DB08
-:105EE000D2C7113BE40383EAAC1719AF894E2615DC
-:105EF000FA61FC52E1EF13E65FC4DF001DDF0F8E95
-:105F000073AF77D0F13AF68BD3601E247030EB96E6
-:105F1000A130BE6B037C272DB49374CADFF5AE6746
-:105F20004F5C41C827F51331FD7D7DF1B3276442F5
-:105F3000FE583F0DF347EADD9806EBCB313D565F47
-:105F400087E527EA1760FE64BD17D353F54B303D54
-:105F50005DEFC3F28EFA46CC77D6FB3155F980CA95
-:105F6000A399C5C0A7C5C506E0D37916C2FF58FEE0
-:105F70001C5F8348FFDD867CED4C03BE3E67FD66FB
-:105F80005006A5B7739F5062CAEE1D4E9174D73B61
-:105F9000FE5C06C05FA99F124F62CF724B0CC38F8D
-:105FA000C54026122A7F1EBFC248243A7ECC1B570A
-:105FB000AD13B3F1BB04A443370EE7545B94FE0763
-:105FC00012C4D7A5F0A4D63FF9E29F0B67E5027E85
-:105FD000FA239DC41C14EB18DE5E7602DE2E053F0C
-:105FE00089F357241C8537FE9415A4F5BF4C56E160
-:105FF000D99645687A8BA3F814D0C1B96613AEEB75
-:106000005C6BAC9F401F8E24A48BDEE1C6E651B5CD
-:10601000D1E2D3CA879AA6789F5E5EA4FBB4F2E26F
-:10602000DCA197EDC0F7F3D244DF89E1401F2E4E8B
-:106030001F8CEED4FE6B9AB27D565D3FFAFC399F01
-:1060400030B109E5BC1277EBD0DEE7392FCD88E31C
-:106050009CDE38200EC63D5D6FF6C1381DF50E1F63
-:106060001B37CDA7A5CBEA05B1BE1389E1F9F5D65B
-:10607000EF3F7B7E843493E36682A0FF7E40EFF5A2
-:106080007BC58774DE580CF4D12A7F03FB4E4C8EFF
-:10609000BAEF489857FBF534895ED3D5F07DB36EDF
-:1060A0003CDA4E39A9E2A9FFC5F02E9193EA3AA94C
-:1060B0009C1C4A6537D0292566C4B39BF61847FB5C
-:1060C000EB92AC4B043A8E295EC1720F0C44E9A9E5
-:1060D000C61C34BA1504771BE859B346AA7CAFDC5A
-:1060E000F1074A725FFC56264BA1FC2FB4775A2E5B
-:1060F000F3D239A4D84EE878B39AAB26819CFC62DF
-:10610000C78FB99EE22B84757F490C13814FBE2443
-:10611000FF6E1FAED1CBA6C41BD9FC96B0FDD94BE8
-:10612000FF83F5513D4DB75F9735EAF3A5E4E614DB
-:10613000E087D21532F1D3B957C07EAFAE9BF2FDE6
-:1061400075F14C8F2B23758B414F592A936980EF42
-:10615000590E22F5A172A266E7EAC2129ABF2DDE9D
-:106160008074759AEA770A954315094C8FA94CF209
-:106170001B5DB4FC78F3F0DBAF21D0DEBF18E49AEE
-:10618000D7469C1B484FB8CF5EA29FDFA5E61F39BC
-:106190005F4216E17CD579A8FDAAF310370A2E7F5D
-:1061A000147D7676BC10D693697A5FBC5E7F5D0005
-:1061B000798D7EFB70447E51445EA51399D3892965
-:1061C000DEBD203E19E8223401F53442E923375C74
-:1061D000CF18AEF7F0C5EA99A09E88F5165DAC9E83
-:1061E00025DCDF63D1EAD5ECDCB2C34BE9A9F2F5DB
-:1061F000E7EC84CAF32F245F8A937EAFDEF0A81DFC
-:10620000E0744AF2DA01DF5FF8C589D1E0B5AF1B6F
-:106210005E2EAB007604923685FBAB4F4C013DE918
-:106220009B0DB243A4553C1B4D0113A5DFDAE68A52
-:1062300049240FF34759FEB1B322E45BF4F8ACFCF8
-:10624000C573298A0DF1C0F46D1240BDA376FDE738
-:1062500013408E7B4808E930B21D8C7F2101F9BEC6
-:10626000C418D7B39CCE13F5640FE7334FF313670D
-:10627000453BA437B4039F7922E8A8BC7B7F091A69
-:106280008BE97C5E8FB7259DBC8A667F407E00F2DD
-:1062900040850BF133BDA261D30B7947E9BC3AD6F7
-:1062A000FFD62EE46AE508A3C7734DB37FBE5BE952
-:1062B0005DDE7472BB28DCCE8FED9416A607915676
-:1062C0009656CB013BE89DD56B6527A55452BDE59D
-:1062D000E5575E047BED5313DA6B555BDEFA6834E9
-:1062E000CD576D959326B1E5588594307E3CF47F6B
-:1062F0000B8685F151F9ABB78CCA50F6FDA18430FD
-:106300005EAAB6EE3792A13DE158D4B4DF18B44688
-:10631000C14FD3D109A0B7346CFAD608F6D717FB12
-:1063200004929ADDB37DF9DAB7705F0438213E3903
-:10633000BEBAF1D7036F8129BB0BB09E03E4E5A57C
-:10634000F0E6E372BA66A78DC4D37994FFDEE49FCA
-:1063500004F87CED3E3BACA75DAA6374BEFAD11491
-:10636000171DBF5CF6A6383065DFCBD7DC8FF4573E
-:1063700026D4A538909F5CE90694DDDE7458E7DCEE
-:1063800055B7E13A4B891BE9B07CB558ECA7E9D782
-:106390001299B8350A9F1426303E695F47914BD752
-:1063A000D90E7A3FE8DBFF2EFA37A07D7A2F01F96C
-:1063B0007F3F5F33DD2931FFB599E1CB9A6050ED26
-:1063C00045B38E7ED73FD606783ADDD7950AF3A43B
-:1063D00070F072B809DFD37EC50FAE4F6578228AA0
-:1063E00054C8DBD1FDA008BE43FD36D965C9D3B57D
-:1063F000E3F2938D3F9F8F4FE71D03FB5B7B0AD535
-:10640000EFA3AC6F16AC0FF745BACF69E84CC3EFFA
-:106410008CFFD73FCEF85DE57FFFD489507EFE43E9
-:10642000C647D00EF6133AAF402A96EFBF5540F953
-:10643000602281687CBE5EE67CAE2FF7507E053F11
-:10644000814A2774FE9210A7A5173A4E02E201ED89
-:1064500095D215B4BD56BF8171B19E31FC5DB3AF0D
-:106460009471B9909F40E5416C581E9055C997A50D
-:106470004756CBC40B2A67F5A726B4C7ABB7C8C528
-:10648000B0FE339B0F7E7427A5F3334D2ADFEAE578
-:106490006A24DF966FDB20009D46F2ED9972BA8B7D
-:1064A00047E35BFA3D2ADF9607FF9FCA55157ED367
-:1064B00013F4F294CAC77EA042F406C748F9F8352F
-:1064C000E85BC93DE523FDFB9014F6A44395FE541B
-:1064D000BAA31A5C3F90EBDDF4A9D25F377DAAF432
-:1064E00017B95E3DFC22CBFB838D44E9A47817D518
-:1064F000E8283EAB5B05BF09F9DCFB769F0284937D
-:106500000BB737E27BBB4F9236EF8FC83745D47756
-:1065100045E48B23EABB23F275BAFAD52D078D0427
-:10652000F11FD0D5332D78891C8F620FAAFB8FA75E
-:10653000F9ACD10B7491193282DC931751D50DFC53
-:106540006B7B45F4AF7529217B02FDFEA885D969D7
-:106550005D0E9E8F67F950B27131C83DF57BC84220
-:10656000D03EEF2A0ED9E335F6FFD156D1AED0F2A8
-:10657000A09F4CD4FA11C2F369407C07496FE5CC67
-:106580006FD81563CFC3F162B2FC407FD78BD6AC16
-:106590000560EFF94427251F3267E11D7642E9AC1B
-:1065A000AB75C04DD3E8F7B9EF88A06E53F4B8A42B
-:1065B000744A37B3391D9F22DEE7C7D0F5CD6E652B
-:1065C0007AF89C65D1E9BE92D72FB5CE37827CA5EB
-:1065D0007AF431AD5FB4922C43BA2B5F15F1BDF55F
-:1065E000C7C81F9511FCE1E6F6C35E953FF2493E30
-:1065F000CA174298FDCBE5F2F562EE4DD3281EBADC
-:106600000E89C4A4803D2B92C5B0CECD821FFC055F
-:10661000C49B8C7C564B42280F553875001F0DEEDD
-:106620005D4E756CFF53E183402F3BFE90F7124D9A
-:106630003B767C3A680FE4777E9CF507D2B37ED137
-:10664000BEEF66C07ED6B5CF847EB1AE7DBFCE7ABA
-:1066500010F2BB4DE817EB5A6472011F78F7D9FCB2
-:106660005740795F663F34ECFD362F88FBEB23887B
-:10667000B75309CC7E39D7FAE7234212A47455A048
-:106680003FEC8B453EF2ECB6A0BDDEB5F7DB42B782
-:10669000F59FB79E5A2371233DDAC8B46D40BFF110
-:1066A000CC7FECD933EAE58574FC9AE6FDC6D9B413
-:1066B000BCE88DBFE681FCECDAC6F4A24E39B886A0
-:1066C0003809F92AA1EC7119FC7CC04C19843C9D55
-:1066D000B8F1066F6E34B83038745138C0BA285CDF
-:1066E000CA41EEF7068F984423D2FBBF1E3CCECEA4
-:1066F0006072ED0704FC4261B8082EF6DDE6370B48
-:10670000B87EF67DDFB7792077CE342D447DE55213
-:10671000EB1E92F8AF4A07FFD5750B81CB59F7C432
-:106720007F597C33FA7F2F41C17946F2414F3ADFDE
-:10673000F913CCBF6673E27C2F93FFCBFFB7E17DEB
-:106740001BC5BBFDD2787FEC7F2CDEDFE178B7394B
-:106750004C20CFF6FE15FDACEAFA2FB5EE57FE87BA
-:10676000AE5BD5E36F34D41D9E4AEB1F268115C561
-:10677000749E6F665EFFE1545AFAEB5EF4938F12DB
-:10678000991DF86B503EC0FE4B13FC1BD0AE6076DB
-:10679000531161FB7A514E19EA1B45394FA0DE4077
-:1067A000A4BAC3F9141E3766CD752EC5EAC33E716F
-:1067B000D3FC8FD2AF75A2FF30C27E3C2810974029
-:1067C000F5D8A22B6F380476CCF84C3960CAC3F4E4
-:1067D00028A46FDB27B2EF56BDDD3409EC1D8D1DFB
-:1067E0007883A22F9FC0FB9B48E61D9E4AC79F98B7
-:1067F000293AFCD06EAC4F82F54CA2CCEDD39C1F55
-:106800004D88E86F1BD531B5FEB5BF177EE624660F
-:1068100067FE9A8E9F0FF0CB94D17F7849F801BC28
-:10682000115EF9FEA5A05B494E84DF8D19351C9ED3
-:10683000CCAE96787BC9BAB80DF85622D42E667ABB
-:1068400019DAD3AA5DDC1B9C09B7B3253EA40A77ED
-:106850002993DAD9FAFE101E2A3EFE5E3CA8F8FB08
-:1068600047F1F17BC0C788303E32CF3B24E0CF22D6
-:106870006E0F8C3FDF26623ED329E1F90BB707C6C6
-:106880005AE325B007AE953E10812FCBCCBB2AE151
-:106890001CC1EC1490AE077718D0DE31170808F74A
-:1068A0009C4609F31F181C2340D19E72CDCE330F96
-:1068B00010F027BB8C4CF12E66FEFCBF7CFFFD98D0
-:1068C00042F0ABB0BF32FABFC914BE735691400C50
-:1068D0005DE75C897821C4612E5DD4319D3F589F6E
-:1068E00087BFEB52C2FD5CAA7E6F72E49F9DEEA44F
-:1068F00072EBD81584EC829439FB25ADDDFC835610
-:10690000062FCF61E2EF8F72C125166BCED9FE2D17
-:1069100089C98F9D7FDC361CFC6763BB72E3983CA2
-:106920002D30005D7AB85D708E287110AF70AE7535
-:10693000401C9E231E126DEE287E9B4DDC9EFE6544
-:106940003D3A9549D77AE213C16E2221F4DF7AD716
-:106950009BA39E07CF4A3270BAE178A37F62219C45
-:106960005BB0F1E7D2A6715ABC754CFA42CAEB890A
-:1069700007F83BA6395FF947E10BF63BC077932553
-:1069800038A1388AFC98CFE137E5C077E8EFBCB290
-:1069900075AD01E8F7CAF506DDF9647512B7BB8677
-:1069A000916130AF29072CB602C0CB21D169A1EB90
-:1069B000F3B49E35BAA39C7345C213FA073FFAABF2
-:1069C00049EC5C608FDC341BE0BAE74B33F152FCDE
-:1069D000EE32FAAAA2CD332985C9B9B9A4E9BEBC61
-:1069E000EC7F3DF88EEDB206C6819DB99E70BF4624
-:1069F00024FD11A4E3731B891FF653B04B412E9C59
-:106A0000DB4C703FA7207912EC6ACAEF3FD4FA69D9
-:106A100006B76CFD25E801B5AD82C340CB6BA5A0E0
-:106A200011FCB19E967811F6DD7C85B8F07C587229
-:106A30000CBD55C317AF264908DF83A3F7DC05E378
-:106A40007ED56124A08FB8DE0CD961DFFEAA75382F
-:106A5000F2416FEBFA553DA91C2F433F4C1E46D225
-:106A600043EEE6185DFE1AD19D01FC35C5149CEF7E
-:106A70008C82BF49C98CCE2E5BBEF9FF3F936F1F3E
-:106A8000AAF2CD2D166BF8282999D1BD46BEA54690
-:106A9000936FF3042515E03E6FEF8054C0EBBC7795
-:106AA000E4E468F26D4B3D3BFF7B9DF223A45DCD9A
-:106AB00054BE5DAD916FCD54BE65F76CF7B7CB9505
-:106AC0006FFEFF1EFEDB02F22DCA7AE339FC54F999
-:106AD00096D77A14E55B5EB381281ABF9339F952D1
-:106AE000F24D48BE15F4E143B233360AFD6CE1FACB
-:106AF000F7EB3C6E0FC60139F7A364765E7AB97284
-:106B00002E3D85F1C925E5DC7F139C5539376F3B58
-:106B10009573D9D1E890C9B979BBA89C13801E9907
-:106B20009C9BB79730FF5B847CCBE921DF08D6AF15
-:106B30000DB0F69E96EC17EEA6FD0D73C94E33AD63
-:106B40003F2C2CEF4668E5DD8F922584730F797713
-:106B5000E8F2E4DD762EEFA81CEB0FF235923E9CB6
-:106B6000AD31BAFC9E51ED9B7F05FCF2AE88E78B00
-:106B70001F18D839D07BA3DA0B80BE56F2F97838CB
-:106B8000FD75D67BB1FFA237D9FA6A3633FF776D30
-:106B900033D30F6BD78B7E85FE73C2E8EF8C30FF4B
-:106BA0008ABD0249A5F9A926DFF35690C1BF900915
-:106BB0003B172393F235F430676415FAF11B2CF67A
-:106BC0007584F2F11C8998C15F5F659DF005F8E955
-:106BD000AB4632FF7E15FF4E78DC801A0759DA7219
-:106BE000EFDB7D48CFF881292686C7292F0BFEB51C
-:106BF000D910BFA42FAF8A887F7C8AAF73AA1844AC
-:106C0000B890F7C5A8710C4F45C2E31087075DBF68
-:106C10000E1E7E212A3C284627E5A784D75FF16E09
-:106C20007031F8F32B560A78EEABC223729D2A7CA2
-:106C300054FF74156FEF69BD17CFFD23D7AFC2AFF7
-:106C4000C7BA557846ACDF97CCCFBDF2C97088A7DC
-:106C5000A1F480F2C3FB1B0A073A4EF1D82B52B5C0
-:106C6000F2F8790E87E1BEB145E904E046EA807E9C
-:106C70004A1BEF7D3B9DAE7FC427CA30D826AF1993
-:106C80006D72C339EA264B08E59B4A5FED2ABDF3D6
-:106C90007EF664D48D437BBD4570807EE10958103B
-:106CA0008E1E4A67165AE5E0CA6F2670383A4CC8FD
-:106CB000577CDFA17037D0FA13D47D88C21DF866E7
-:106CC00078EB593CCF2D20213C2FA96D149C01BAA3
-:106CD0008EDA16062F55DED23FAB161F51E8518AC9
-:106CE000468F049CC485E17DB08AD79B62F27D0407
-:106CF000E7305328BDAF25613CE6D0FF008F917887
-:106D000052E17929FAFC9CEB1F5B008E5680578874
-:106D1000E95101BA2FD8C2E51EC9AB8363D18B17E5
-:106D2000187DED1514384FE88613D02B2D1FD1CACE
-:106D3000E815E0A600DC5B4B44C89752F82666F7DE
-:106D40005C279C5F6AF9B762EF51D6FF6AC149A21E
-:106D5000D0AFBAEEDEE8F71FA5DBF608BA7DCF129A
-:106D60003A3C1CE876AFC0FC08ADF1BA7347530A51
-:106D70003B77DF64A1F40DE75DEFC8CE754A4F3E67
-:106D8000BFC0E109FABFA2F14B0D8105C059E04631
-:106D900033C69FE13CFA33FD522B5FB75848F2AD42
-:106DA00005BDF76FE4F6406FFA8D9A1F0AE381DCA8
-:106DB0006BA1E3E584C78B94EFAABD7FA97525A6D7
-:106DC000FC63EBEA8EDF246D78FE648A773F98845B
-:106DD000FE1F169F743B8F4FA233403D4B532F2D08
-:106DE0007944EFF5489A19F7E1FB785CFCF5A29538
-:106DF00078E93ABE72C948A77497FEDD1890CBE3D4
-:106E0000E83E4293AF0E8FF8F86E2C17F13CEAA6DD
-:106E100077136BE09CEE261046F4FB4DF902EEBFB3
-:106E20001F4067A3408F3513978993302D1FF98337
-:106E300078F41BE5AFF71529949F866DF43740EA87
-:106E40002C0A25BD07F01B2B12805F9B2BB108F687
-:106E5000AFFB3E27F9A282FB2CF633EC1049867A71
-:106E6000A35DC9680E8C6A5E5104FED1A907AD56B8
-:106E7000A0F39C5506E2D6D0EF68E26F8073F8511C
-:106E8000275CB700FF95537D01FCCEE5AD6B1BEC95
-:106E9000905F253815DABFC7EB9E60A7F3DAD2788A
-:106EA00076C255C087B41E74E359C5EA79D60B4E35
-:106EB00008952D6D5D8EF138A5EB05E280FA7E8197
-:106EC0009859BF7E33ED77CB2ADA9EE6CBA03DF40E
-:106ED000BBFEEC87B7009F1F1659FBCDECDCBA94C4
-:106EE000B653805ED7DF8BFD55AC12481AEDAF7CF0
-:106EF0003393FFE58765279437EF5F89FBD8243A02
-:106F00005E7A36C8FBC078C893E18203FD9D99770D
-:106F1000225F7771BE261DD398DC10789EDB0DAA08
-:106F2000DE742085C507973A171A13693FEF8D4C19
-:106F3000CE8630014FCB593C8F3E41E1ECA670FE2E
-:106F400080C7731C1C79DC18D4EC3F9FA50C403A19
-:106F50009CD33216E31CE692628C7398328AE96BFA
-:106F6000EF5F6BF10B745EEFCBA14CF87EF05A1320
-:106F7000EABF9D5B643C2FEEEC1B44FF74FB2A9937
-:106F800040BC46C32A11E562FB66B68F8BAB6F9B94
-:106F9000900EF0DB2038416E1E5C5564847DADDDC3
-:106FA0002F60FBA2D5F7A7303B86C943D56E2B7562
-:106FB00054E8F68F48F9A6CABF1A0E87483957A376
-:106FC000EE331172AE06CE9BED90EABF7B8895C979
-:106FD0003FD0FB01EF81EF907E6B0FCB04F47EE19D
-:106FE00078C7048CDB827D93968F6A155C70CE5FC8
-:106FF000FE89C98FFAAABF64E64F417E7F6A22826A
-:107000000271F014EE542E8C3485FEF82CFDFEC572
-:1070100007668890A17452827056E3450B36B0F82B
-:1070200096820F56A494021CC627A29C2D6B14892D
-:107030005B232FBE105CB7DCC9E4B16383461E1529
-:10704000187DA5B07F3952991C5436C8103342B60A
-:1070500073F944F56917E80D15BB96A71869BDC506
-:107060003C1EA462EFF2142A1A4803EC5BB47E853E
-:1070700091F55FB14F70ACD5F4AFB657FB53FB3110
-:10708000EED2F733602FCF5F663FEA3CD4F17BD37B
-:10709000C747FEC7851502ED6FE4FB2206298F3C2A
-:1070A0003E6980F6BC434D55FF6BE18706E2D2C0D6
-:1070B0006DE41F63884B4317CD23287F53BC4D6E6F
-:1070C00061FA50F388A3C69A02CC3B809F6BB99FAC
-:1070D000B6763C3BB76ACEFFE011E0EF490502D23D
-:1070E00001F1BA8D8949A8072970BE5056C0DA97B8
-:1070F000D1F6C077CD2B191F5279A080BCA85DB501
-:107100007C02D65F2F28D07FF3DA12DCE7CB478AE8
-:1071100004CBD71F45BDA3BCE56812F02BE5CF1506
-:10712000B0EFD68E3139803F54BE53F9F87D99C502
-:107130008710B36328DC03284B51A2F2AF78983054
-:107140003B75B38C7CE719C9F8F2FD2D22F2F3C12F
-:107150006BEF98007CD8B941E8858F299F1684F998
-:10716000545CCDE275CA36317BE5E02A261FDA9BF6
-:10717000999E58B45A9E0CF9B27765C2FC5E4C1FBA
-:10718000BC5C7EEEA1A76C8CCECFBDF1EF14B9E94B
-:10719000A3FBE8FC6E7A8DCE5F09C3ABE8BA07ECBF
-:1071A000E8A7BF6E3AAE579543A5128B679AE35B8B
-:1071B000C8E27D2516F7F677CF2B621E8FA5D8C2C1
-:1071C0007244047A8F6771D2EB65A4F7487EFC475E
-:1071D000F9E89FC5D7DB391DA9F311F7B2F61057AF
-:1071E00016A070FCF5E69731AEF5CB578F4E013CFB
-:1071F00057EDA1F44BD7DBB9D9460220B7243FEEB7
-:107200003795CD22C68F132950788B4DCB9F2C3EBE
-:10721000A9EA751BD24DE53616775AB9E3781EC632
-:107220008B2C0A61DC95F755AE6F7A837940DF9538
-:10723000128B938AE4F7B1A94CFFECD8153B0DD61D
-:10724000216CDC8FE7AD954D77C8407FDDF223558B
-:1072500056EBE139A697D22F9CB3C3FCA60ED5CE30
-:107260006F21E2A96313E3FFCA16D96F81F96D5C40
-:107270008BFE6CCFC6B3181F5FF4FA16F423785A4E
-:10728000447D5CE44611CFB3688AE75691F189B535
-:10729000CD3578EE56DBC4E3FF22E2E2AA5EDFBB27
-:1072A000C34B4153F5AB5FD8411E9C6EDB60077842
-:1072B000D2FE30AEF0BAF3922E3EAAF77860973E37
-:1072C000DEB0E9711E6F38B99DE4F58C373C0DFFD7
-:1072D00080FD2635225E7363228FEF0E141647F170
-:1072E000E777DFFBD9F2F51A8893EFD876660DCCF5
-:1072F000BFFA6F5FAD81F826B2CF82FB94E7D5DF8E
-:10730000615CB1DA6E612AA3B7CE4DBFC0B8ECCED6
-:107310004F4D68EF74EE6DCF82F8B6CEADDFA5802D
-:107320007F6EFEDEEBD17F397F7B512A8922EFD53C
-:1073300014E8D37F1971E191F838D87C10E3B0BE1E
-:10734000FCC484F2AD3B7EB4A986C5E52A3C6E74CC
-:1073500073F4387C35CEB1B6F9969BAE0579DDCCA9
-:10736000F4BBEEB8C74BC58B7E48F17AF565E06F8C
-:10737000338F0B6E9A1C355EF44BF807C5D3CF5391
-:10738000F5F1A25F37CFFDF98B50D69CD86BBC6866
-:10739000E032E0A6C6F957A7BA5E4D053EDA16EB15
-:1073A0004D6378F34F12400FFC3A0BEE479C92432B
-:1073B000180712DA6B7240DC63E5DE8F915F3AB733
-:1073C0007F80FE56C2E3EC3B49F71F8B8716F83AE5
-:1073D000D7DB589C29873FC4A12A76FCCEE34D1900
-:1073E0001DAB71A8BDC59F0653F9FD617EEFA08658
-:1073F000DA4D2C4E3D1C972A8C047C1DD5C5F5AA70
-:10740000EB8EECCFC1E56838AE3A7A9CAF1A47D81C
-:10741000135F6C5F51E3A63BD7F2786BFA3D7318AC
-:10742000C4C9B1FDDCE3173E8E865F35AEFA0F119D
-:10743000F855D7D71B5FA8FC79A979FF57E1F26E01
-:107440002AF367ABF0E9F84B7439FD0DE7776AB7BB
-:107450007E9DAAB16F6772BB55859B3ADFC54D4CC7
-:10746000AFE8D8C8EC8748FEA6EB71458BB397D23E
-:1074700098FE5BDBB23F0FE450C7815D9CEE185D68
-:10748000D76E3ECAE274A9DCF66BE536617EE4C8CD
-:10749000FEECBC3F4F6BF4FE3C9BCF46EDEFB4E4FB
-:1074A000BA03E67FBA8DE951A79BC489FE28FD5F28
-:1074B000E0FB52F7BA6D468C9712ED31A84FCDB76D
-:1074C0008DFC242E095223C6FD342CE471420F3B5F
-:1074D000D300CE0DB61B09CCE751808FC6FF203BF1
-:1074E000DC04F43839ADB84054C2F355CB8D4906AD
-:1074F000E2D7E25F0A64827C3F92DF2E437F9F45A2
-:10750000F84D3E93C8E2543AAFCFBC8273A1D2BBD0
-:10751000DEADE6DD0F893A3F47AD297404F477F21A
-:107520008605FDD6E23E8B17FD666B2CB8CE83DB5D
-:10753000BF7D05E0D5F9731361E7089430A85C2896
-:10754000E3FE8BF6EDDFAEF933E899D0988E5FB6A7
-:1075500086D607FD7A732CDA035DDBE2F2509F7C5E
-:10756000E3C1292037CA600F033DEFF5547F03EDD7
-:10757000EF6432CB9FDCD217EF13546DB361BCE1E3
-:10758000C1ED3B6B41FE77BE1E0BC7D1E44B39F812
-:1075900037C87BF6C491B50AEA818A76BFAD2092DE
-:1075A000A2D5F3AA20AF8B7F2168A7A33F8ED27309
-:1075B000554B1CDE1FD1D4E3FCECCD60F7650219FE
-:1075C000C077549FD48DA396DF9AD69FDFEF0DFD31
-:1075D00084BDAFC0EA7B8CA15296F76530BE6DC307
-:1075E000FA252ABDF2F29EFDB2FA33D3FAEBEAA9EC
-:1075F000ED6B4DA42E1A1F54A709FC7EEF5F0747C1
-:107600007BCF22CAFCF1FBFD02F11A400FD86AC100
-:1076100038AE6A636010C4B7EF30B2F3916A7B6032
-:1076200010C4B7EFE1F2AF3A86E6E9F70C3E0FA8D7
-:107630000F79620EBE06F8AED969214BC17E7FC3B9
-:10764000E6023CD7ECF8F6E44B0510CF168B7EAB88
-:107650009A37FE0DF15F630ACC00FA0F6D35917514
-:10766000B47EC7D677B2408FE8900359091739F72F
-:10767000A96932E9CEB1D5759CAEF70F84FBEBEA70
-:10768000BDC5CA5EE4C5DE34A68F2E4F733D9D8610
-:107690007C6D75A0BC86FE44E8A76580F65E73A588
-:1076A000125D8EAD4A9375F768C5F03DC555D0EFB4
-:1076B0009724B83883A2A44608E1F979E5C6B34314
-:1076C000C11EFEEC6757E1B9D667C6D05090DB9F6C
-:1076D0006585866AE5F1A97AB322C9E897C0B46BDB
-:1076E000EDD9D20C02F1839669D1E4D396B4589CBB
-:1076F00047E543B151EF83EEE6F4B61A6830998D51
-:107700000B7E0875DCCF8C7E23CC23375DC1F2CA9B
-:107710004CBF11BE576DDC3540F7EE84E4C37A945C
-:10772000BF101E156485B1C0DA53AE542CB02A12B6
-:10773000DE8F96FEB39BDEC4309ED0C909716A1CF1
-:10774000877467423FA87A1F40928BCD002F232970
-:10775000764822A0DA877C1A439A30B5527584EDB8
-:10776000437504E28A4EF1F35B93A43C0DF2C374BB
-:107770004844797E29B8FD3ACD8EF3364975C489DF
-:107780007AC72407E8D582D74DBEA7F4D050BF7181
-:10779000C00976FEEF8278380C8DA3F3B33BDEFE92
-:1077A0000EF4034A6768677BAF23FE063A9E646463
-:1077B00079328EF8A39DC777703C10EF7E943F56C8
-:1077C00012FE0BD17C2C4A283A6EDCDF46829D6B80
-:1077D000759000E84DB1561288A5A935573AADE528
-:1077E0005F3B61F9FE949C41AE39C6E8CB23E99A30
-:1077F00038A5F3DD7251C4F6E723DA9FBF587B1535
-:107800001E1EF3806C76FF9DC12586AFC13BCE79ED
-:107810002108F0C8B33B1B008FC6D09107011E7929
-:10782000566627263512AD1D37209DC9AB4704B6D5
-:107830005FD2BF62ABA63FE230A3FFF4710EF7EE5A
-:10784000FAAA5FA5477D8B0470ED51DFD25BFD98EE
-:10785000E8F56DBDCD2736FA7CE27BE9DF1BBD7E06
-:10786000ED1B1FBF1750E023931B1231A8F7A00791
-:10787000A483BD157724A58451053B2788C05B0CE4
-:10788000D01FA58798819AEFF07FB91AFCF58F82F7
-:107890007F1240BA2BE1F3A1796B3A9DDF9D7CBA50
-:1078A000E3D7B373CCBBE7333FD29D0FB1FB424765
-:1078B0007FC6EEEDDFDDC8ECEDBB17B0733352CE03
-:1078C000EE0139E87F30DE3DD009C5F73D3EC11FEE
-:1078D000C886777022F4D7EEF776EE97A07E4984BB
-:1078E0003F46A527F5DED26CAE5F6773FA9C4B422C
-:1078F00036E0FBC87BF4CD692C2E8D9A632E58DFC1
-:107900005D7C7DEA3EE05D4E72E05D00D110E38477
-:10791000F31191DF5B257623BBB77A6B824EFE9C19
-:10792000CB51E260BF236FF2EFFC3DA2793728A96B
-:10793000DA7B5ED285587C7FA44176A6815C942F49
-:10794000FC9828942F8C17061045730F8DEA77C882
-:10795000ECB283A01F4772149332D00BE3399D25FC
-:10796000DDD8AD87BD4FE1326FB982F760EF486770
-:10797000FBCBD28CE2B94017A27DA4D36DED895721
-:10798000EF76B6BE06585F76CF7937189D4ED44352
-:107990006FA41A04FA7B9C66988F68523E56803F0B
-:1079A0007F2B13B0FF7BC281E1F35C52821FE25F49
-:1079B000E6D8971E01BA5D56EFC073B425F5399825
-:1079C0002EAD4F433D7471BD1353152E66A7CF25C1
-:1079D00052389B07B2FECC0E37D333E83E04F11782
-:1079E00092A32E007973661D01FDD7D20D1F1FC211
-:1079F000C7D89D7763DE04799ACA8D9310BEB43DD3
-:107A000029033F6A867B19C0C7A25C49140D5D98A3
-:107A1000D286E9F23DE0A6D2C71606BF2705461F6B
-:107A200091F07B526E53E0FCF9C91BBADFB541F807
-:107A300051759FC1EF37EC7CAE57F83912509F9DBE
-:107A400053B8784603FDF4043F877CAC7E24C2EB38
-:107A50007188EB1A0CF6810B5311E047E9C894EBDF
-:107A600025226D6F52D89C4DD66297A180D12EC031
-:107A70004FB432789AD2EAF03CCE6C65F012AD5E2B
-:107A8000848B6C65F012AD8CDE8C3C2F01FC866320
-:107A90007BFC4EE1D79C3E02F0305A072F63D2B8F0
-:107AA000CB83DF4A0A3F3A8F24CE5F917048827BB6
-:107AB0000AB961BEEA4DAF7B8EAE1FF6F117287C86
-:107AC000204DEEC57E4CCE607234C950B75F06784B
-:107AD0002410BEBF7849662161A18AF097E6250A85
-:107AE000E405360FB25E8F57D12145BCFBA6BC0022
-:107AF00074B0E21DD900E7A4E2821FEBEE938AD3B3
-:107B00005CF10AC2D32DC0FEFC44BD82F85B0E7846
-:107B10001C0CFB23B3C71EE5F87C0CF804F1CBF872
-:107B2000E349CE2F4F733E6970B2FB13CB26B2B838
-:107B3000ACA47C037F0F2D40B4714FF1CE2662A41C
-:107B4000F3421D5BC134807AC62726FF15B45D6CF5
-:107B50002E71019DC47FF2801FD74A8AD3412F8A9C
-:107B6000E7FA2F19A3C44FC78BB40189D921541444
-:107B7000A25DD36688F60E5683F38019FCA6BDCDB0
-:107B800067FFD41D4897A5576378304974174F9FF6
-:107B90004BF3D6C658F40FC63ADD858F029F37DA0D
-:107BA000904EAD74FE651ABCC7F682D717336E309F
-:107BB00064503A144169A3F87DA6718005E0FC9CED
-:107BC0005C9C0EF2F539BECF521C28DA73A80E2E3B
-:107BD00027ED0557EAECD915B20BDB39C6E8E5C04D
-:107BE0000A2E7713C6EBE95D95BB1F75CB5D773227
-:107BF000CC27E5C278E4C7A49BA3CBDF06D9E885F0
-:107C000077051A86327EF79618D97D989EF200FD88
-:107C1000DAE7DC83D6813C55E96B1161F2C74B6230
-:107C20009CB81FF1777454FD7809BC37C8E52CA4C3
-:107C3000E24023D24DCADD068CCF5BC6DFCB7A8A09
-:107C4000D217A43E4A5F905E9BC1CE33169987E15E
-:107C5000BB6D0D5603CA0BE95393DF0AFAEAFE51D6
-:107C60000EF02348B2B3CD05FE409BD4B48E40BD88
-:107C70000233BC2721C41738800EBEB1CDE977B1DD
-:107C8000383C8A4E01E8C891544C8EE5E2E901DEA9
-:107C90007B911D3713F02BBE90546701B8E5663019
-:107CA000BBABB1A410E148E13B2E2339DC4FEAB471
-:107CB0001BBBDFDB826E5FE8E5FECC940CAE476752
-:107CC0007AC9400DBF370A5C0F53BC2447C3F78BFA
-:107CD000AE9840E05CA927BFF722CF363079F6880E
-:107CE000105D9EA9FAA72ACFE40839A1A68BFB4D07
-:107CF000D4DDEF322639817621F51A288A24EFD592
-:107D00004FDE158F70980D7020693776DBB53FEC2C
-:107D10000F7A6561547A8B946373BAF775570AE0EA
-:107D2000E994ACA44E077A7AA7B77DDD558A74E84A
-:107D3000EBA3C0BEB4FF991FA35FE7C4333605E4CD
-:107D400050D985C7717F28BD300AD3F2C61B703F5A
-:107D5000179E9D5C08F4D0BEEAFABC4FC1CFE3B3D6
-:107D6000E1BEDDDE583408CF237DB10AC477B437D5
-:107D7000D2F2827039C48B8B9A780102DE77CDFD06
-:107D80006F52A0A05EAABE7B46ED3AFB68F00BAD39
-:107D900016F15E58E9B33617E89FBDD15FE9AAE84E
-:107DA000FE00D86BC1EF4A07CC013D7ABF7D742835
-:107DB00040FB9DB38E9D2334185D2703A0373D63A0
-:107DC000C173C88684E8EF82CCCDB87E19C881B96A
-:107DD00019AEE7104F56F64E69EFFCC0C63F098753
-:107DE000CC708EF5227F1F4572DBA7EACED9D83939
-:107DF000D649EE6721E65ECA6378B9D24BB99DC514
-:107E00008B1047F472D5CE880DDB194DB08E9AC613
-:107E1000338B3F4578713B83CFFB94CCE67DEA15ED
-:107E2000937F5114FA3FC5E3532A04065F950F4E22
-:107E300075EB476E7C0F27924E8575435E1845FBA8
-:107E4000FDEA908CFB4635A52FA4AB75A3303E5EB2
-:107E50007866D4D310377CFEB088E595172C58DEB1
-:107E6000F1B0F305887B0ABD2B13904FE70F5D1F20
-:107E7000C7FC447A3FF63D7D985C38C6E543E9850A
-:107E800027907EBBE9C437D708FC577AE12946DF43
-:107E90001B057CB79278ABDF1D3B90D3E768685F2A
-:107EA000317911C07B8C0FCF49CA36989CA00F4402
-:107EB000E2F95886A2F37B94059761BF84EA5F4993
-:107EC0009AF3F4533CCEB8EC027BAF9038BC240D4F
-:107ED000F881CBA7301DEBDFA1EDB044F7D39FE3D2
-:107EE000FA4FE9856B747646787DD7E1F752BEFF8D
-:107EF000970547613EBC9E1746455B4F781D63B0B2
-:107F00007E477CF4F1D3399C4FD6971317956FE5D4
-:107F10004656AFD477BF11E44EE9AAF80441B3AE98
-:107F2000B2C62A5D9C47D9AA12E32C4DBF613C2CF6
-:107F30007E77AC14C643FA4B0B272FB2825E502CCF
-:107F4000F7017E5A5751F85305FA63F2E90BD997B6
-:107F500005F2BABDF13E7BB47B13E97D22F0D3C8B4
-:107F6000F143F5EA020D7E54BC44B63FB9B6ACF01D
-:107F7000A7E08F5EC95E21E95DFE44E02D3B3ADC5F
-:107F80008675C32D07E38D2E0DB7AB7471453DE0AB
-:107F9000C6F1ABC245FD4EF5A8ABFA8C80F108BB2B
-:107FA000BFD3C8F07F297885C7E5F81F1B7D1DD397
-:107FB000BAD7B1807829A3CEB9E43A1E245EF3453E
-:107FC000D6A1E29FBCA2C3FFB497D6221FAAF89EF7
-:107FD000736025D2EF1CCA8F70DEDFEEBBDF1E2D73
-:107FE000BE685A6F781FE825B985FFF7F0FE85EC6B
-:107FF000CD82B832EF720BDA23A7D63D91A585F377
-:10800000DC8CB1F7005EC8FAE4CBDA3FBCE39C87B6
-:10801000C0BEF43E23A33F6D6B86BB0CDA97733B67
-:10802000FC91F80983A2E9078FD61F1A027EBA864F
-:10803000FA364C65AE5F12D02FB3515F72457BDFCD
-:108040006B491F26571EAD6F637E4FB39738B4F749
-:108050008909D39FFE93307F8DDACE28BB1DE03F88
-:10806000350AA418F53EC9BD24BB00FC1E49F95EC3
-:108070000DFC16F761F79196A51D70C0BD6213ED5A
-:108080001FFC39E64CE99CFE9C93E5F3854F45883F
-:108090006F96939A08FA4373E9770DBC8D496D3A50
-:1080A000FF74241C24B31DCF9B24C2F43975FDF446
-:1080B0000BEE4B8FF17D6905F76B3E5FDF847EFF32
-:1080C00045B176DCFF16F733307BCA2CE17B35A651
-:1080D0007856DF18C7E66D01BFB708FB6A00F336B4
-:1080E00078D147C4A7D104C8C71345807C22092C86
-:1080F000C67752C6067F02DF9D696E3FE0F19BF4B2
-:10810000B62302F8B18BDD8361FF6D14BDF90AADB2
-:10811000FF7331940FF5B268D127092CED07F1D028
-:108120006ECDB9167B2754D1FA0523F3FD164811FD
-:10813000E73D7F19AC2D5F9EE67A1DE6D16061EFC9
-:108140000C251D17F03CA7C1C2DE1B6AB0DD1E075F
-:10815000FBF86FFA30BD1DE900E8E810D367CE499F
-:108160004A5C02F3932A6FEAFCFC66E54DCD3812B7
-:10817000B7F7D653BA9434E72A03259701E8E60AFD
-:108180001FFDAE9D67147F5C82159FE58D7A9EA3CF
-:10819000CE0FE2F6018EE2850968AF45D2C39E6E2E
-:1081A0003FB357047C4E57DF2F961E61F978A2FE2D
-:1081B000A1FDF569B73EFA08CBF3734ECF2C768E4E
-:1081C000D9501287F171EA3CA6B73ED6067AEAF496
-:1081D000D6F4D970BE35DD3AE87348F7C8A103B1CB
-:1081E000A007DE2FE0BD923B7FF7A61C4BD3ED1F0F
-:1081F000AEC3FBCC9F73793A8384F05D783771F01E
-:1082000073763F7E9F459C3CDF24835D7F77C07FF4
-:10821000DB649ABBE74DFF6450DB661C0ABD056258
-:10822000C0DDE4988067086ABB16E7DB2CCFDA75FF
-:10823000AF5F32E37AC2EB35E3FAD5F5D19922FC90
-:10824000BBE1C3DF6B52E121CEA2EBA6F4323DEEDF
-:10825000F61BC945F4F2E9D69CCFD9A1099B4F245E
-:108260007CCE4311D51F3BFAB84826C5DF1FFAB8AC
-:108270000448ABCDA12CA93FF2890CF95AD1DD0FEE
-:10828000429FBFECEB1E9C0C70684BBC2CF979C470
-:10829000C2F8FF08D033C4795D48C275A9EFD01F7A
-:1082A0007CA0DD067AE7E2ED1FE33BCB3562F0C947
-:1082B0003BD01F2AA2DD74AE79F045EF9F1D013F30
-:1082C00015DDFFFA66AAF72CD93A674A8C4F663655
-:1082D000C7623CFECC05A2EE1DE9990B583C1F91EC
-:1082E000DAF26ED5E9EB8FF4DA0FF80B22FB99BDC9
-:1082F000A0881C1F0EE7B48EB1E83F58C3E86BF6A8
-:10830000789708F1CEA3970878DE3AEA84D212A4CF
-:10831000F9D9FE7827B0E7EC07FE6300BC7350DBA9
-:10832000C6FC81A9E2BDF90F839FE500DBC7217F71
-:108330002FD089D5A55835E7051D725D3EBCF7E7FE
-:10834000BDC7EA02FE2FB9D5F529BE17C1FD15EA52
-:10835000BEBAB3B104E3644BEE564602FE4B9A2C10
-:108360002E4CCD448AA172AC44226648538D44B24F
-:10837000401A43CC90162E62EF7697364E45FDC0DC
-:108380003EB2D808EFF196B4FEE26B685F2605F6C0
-:108390000B7961F894B4BEF31DE075AEAB18E31928
-:1083A000AFDA68D4D981439BF4F9AB5BF4F9FC8074
-:1083B0003E3FFC903EBF2193201DCD32DF920BF05B
-:1083C0003AB0D744F72288FF3361BCCB3181E1C793
-:1083D000BBC982F2B0A8AAB510ECE033AFD90C60EB
-:1083E00047EFF9EBAFF03C3CB42596409CD5FEDF5F
-:1083F000C7901888577CDDB20ECAAB28EEC07F59F3
-:10840000F5BA652DD8E13BAE54ED787F1EAC67C759
-:10841000DF587C4D6893C90FE7E36776FDE2353896
-:108420004F3BB3A90FEA57C704AF2106C6FF82F935
-:108430003F83FCBDB8207F2FAE6AA3DE2E9E97C976
-:10844000E44C70D13571D1F42635CD494BCC1D4F5C
-:10845000E7D6F5B86926F8810637EAE1A2D61BE22D
-:10846000D77F7F90F73F9A18C3749A0D7102FE066A
-:108470003BECBF2F477F277911E79F575FED6E27B2
-:10848000F277E288A2B9371596DF647E1F88DF0095
-:10849000F8F70F7FAF229AF968F49389BCFFAFCC4D
-:1084A0002C9E3989BFDF7FBAFE10EEFBDD7A5FBDFF
-:1084B000CB355E932F6DDC9F5202F6D3AAFD29B314
-:1084C00034F0AADE7430E52E8C7B92C0834BAAA7D1
-:1084D000BFF214F82BAA37894D304F2807B87534EE
-:1084E000BD65877A541F1E067E90B03E7ABD6BBC78
-:1084F000868FFF5EBA55F9AD9AEB2F3B47B64D809C
-:1085000038F5AA46C109D5AA9A6EBB6532C07B155B
-:10851000BBE75A28916291F257F5D6DB7E3C14E214
-:1085200066568F70C27C6817B7C2F7AACD67F13E56
-:10853000C3D288DF3D50D3DD994C2FA4F503065AF2
-:108540007FE9EDD672905FB4DF37217F20671DBED3
-:10855000AF623FC5CE1FE8F74F0C546F3935CEFBE5
-:10856000DE5DB4E919D2F4D164F02B35EAE991D299
-:10857000B7007A596883E05C875F1715DE0C2AB76D
-:108580006B21C6FBD2F299D1EE5B57F8F5FD44E2C0
-:10859000FD233E5FFA97A3A59FC87A8993BC184F25
-:1085A0005EBD80CA438D9FA0FA840FDF978C1C8725
-:1085B00068E99AE913440179B8C5A2BE7F24980BF3
-:1085C000799CEE0096C77715814E29A1545D49C666
-:1085D0002B00EF9BC9444847835C81F7F44736E59D
-:1085E00041FDDD42F09597B03F1BCAF10E4700DF19
-:1085F00099CCE0F74C3B1496EFE27E4EB5BCB2D579
-:1086000082713667BE34A29C5DD87410E3E83B5E8D
-:10861000B3180C541E9CD99A380EE2313B9AD83BC1
-:10862000C5A79B12C7192FB26F47CA0D753F3D0AE8
-:10863000FFA4FBEE9F335DDF64C23EF5088B574D10
-:108640004DACCB8FF6FB176ABB24635D3ED831A1DE
-:108650007BACCE7508276FB6847EF03427C40995AD
-:1086600008AC5F63BF62B12FAD6FA375C11F9D7072
-:1086700048C4DF6B382E3A7FE21880EFC9A31E345E
-:10868000A7C08DEF539247585CE56C8904244A6F6C
-:10869000B3613FCAC33CCAE5D9AB048C2B9BB34C36
-:1086A000BF1E782757BB8F56103F7BDF42EB47EC4E
-:1086B0000FF12E74BF81772DCD2CFEA272BDBE5D51
-:1086C0001509E07CAA377F6F8A06AFAF89BA2E57AB
-:1086D00026AC4BB8D98CF3BAEFB93876DE63242ECA
-:1086E000D84F43CFD950BE571137F67727DFD73D44
-:1086F0000F94B8E6801C5E30DB352711EEDBB2FD4F
-:108700000F4D3EE46F01F79DAAF124D097BDBB4108
-:10871000605FAD6A150243216F265EFB30F61DDEF9
-:108720001F80756BEFD794131F8E57BE4AFF9D7C39
-:10873000C8F05ACDEF3192F59AF2FEA09F317854ED
-:108740006F36E9FC3AA3370B5E1BDE77F537A4D012
-:10875000F9D59EA2B282409CEAF7265DFF10CF3386
-:1087600002F77D62A1787BAE5BAEFB87448BF33F63
-:10877000C2E1F8DC6DA5E9C0AF4F83DE9AC1013DCF
-:1087800012E516F71F9080998E1333BC3B8FE58559
-:108790008B587ECAEA57A6348EA1769EECC673A18A
-:1087A000D962F1DB701FECE57EEE9BFBD271661B9C
-:1087B0005C5912F2AD6B10FA43173038BC30AC6E16
-:1087C000485D143D50C5F3F3425300CE65BDBB98E0
-:1087D000FE652B08C9DAFDB5BA2F93477107827879
-:1087E0006F22B45DC07B962B85A3781F71E50D0ABF
-:1087F00001FB3E8DE209E4F14A813C2250B8143479
-:108800004FBDF72DC073418C137EEEA2A679AC58F4
-:1088100063C5F5333D2DB66E2D9CE7A4CECC19066D
-:10882000744ED73DF366FAFDDEBE0A8E976E65780C
-:108830004F5BE4CD86DF818A3B507CEF5BC0874392
-:1088400063F09E6C2A85952D01D325A07FA5918587
-:1088500002D47BCECEFA4F368833A7427E18CB2780
-:108860003C24B8D621F12DC7FE534D6422CC13BE53
-:10887000831E6906BF0296FB197E8BEAF2A1BFD464
-:10888000012C4D320632A19FC3DDF876A35D319FE6
-:10889000EF63F3B78E4D053BEF700735B8A9DC3AAF
-:1088A0009CA6EA43012BFE3ED4C01C569FDB85F3F9
-:1088B000F3D97D83A42C7DBD2ED915371CE4E807A0
-:1088C0004C8F3F6F75A17FFA1A63747FD64B7D99E9
-:1088D000DEE2B92010BF661FF04CFB06F54ACF055B
-:1088E00049F7BDA3DEAC8B73AE2E3F80F7EE6B482D
-:1088F0001BC661D734C5EAE276AF89893EAE4ADF4E
-:108900009E0B22F1461DD7A8FF7E21917813A3D597
-:108910004BD17FA7EBD0E55BBEED5E077C272383C1
-:1089200076B0072771BDB6CB6FF0CA5787F1D2E991
-:1089300008EAF69D4E85E5BBF8799C5AAEF6DF391C
-:10894000CDC8EF15B17795013EDEC184BCD87A164B
-:10895000FDD1D5ADFB27B0DFF76274A18593572316
-:108960003F521ADA0206CADBFFDEF7D453B94328B6
-:10897000891D50F9F8F4532ECAB729A241C7D7B1BF
-:1089800005DD7C8EE2E53983C8E5C299A7C68FD1A3
-:10899000E659FD70FB8E29E3A96E5F90CBDAFFB13B
-:1089A000EF97EF2D1A18964B741D59C5364DDE1CE6
-:1089B00091B7D2FC504DDE11519E14519E1691CFAD
-:1089C00064F53B6C812CD149487BDFB353A45170D3
-:1089D0008E1D98012F0A2C6BF86ACA789AAF296805
-:1089E000C3F899DA56C189C7FA6A7CBC93E959562B
-:1089F00067107FCF2EB6A0ED6D9003D52D8243A0DA
-:108A0000F46E6DDA8A7135D5D04ED1B46B6276676B
-:108A100075D3516CD76BFF3906E4E7A539C7B09E13
-:108A20007A7E7407E9FEBD8E0B202F6B9ADAD93E51
-:108A30001C717ED499EE3A88F230E2FEAB07FAB5AB
-:108A400086E95EADFF87A1ADBF836E62E79F5D28BB
-:108A5000D1FA7FAA691F01FA12BC710972FF79C1AC
-:108A60003F04F6E717897B08EC47F7D45CB1DF4099
-:108A7000EB1D9183ABE1A9864159969B242AA78FD0
-:108A8000D8827D052A4B72D624DE04F03C921CC4A9
-:108A9000171A7EB6268995F70DF68573D7DCAC1FBD
-:108AA000B2FC15C1D590BF75CD952C3F34D857A4D5
-:108AB000EDFB7BAFBA09E0BFC1119D6FFB66317959
-:108AC000AECEAF2CDF959605FA6635DB2FE0FAA522
-:108AD00099CAC51995A7B76CA07098F1D358945747
-:108AE0001B3A6EB9B118D7EF2D863837F6C43BDF85
-:108AF000CF502E4BA807A4C31E9610C6872DAB4D92
-:108B000041797F65DD56D8F75367E4A2BC3F9FE902
-:108B1000AACF1A114EBF1DC0D2FA2C76DF235534CE
-:108B200060BC41EA8336D4839EE6E749946F10BF68
-:108B3000568E8F61594CFE0DCB62765246DFEBEBC1
-:108B4000613D7772FD74C5E3FE4D160AFFDF0391A8
-:108B500024A17F1BF5DDBBD652B91107F114AE7409
-:108B600090077781FF37379C57F5F715F9346F0D6C
-:108B7000DB692BA6BAD2B571402BD6B27255DEACEA
-:108B8000C866EDD57D27B581C127F5E921EB601DCC
-:108B9000B112C1FB1773A70D5AB710F7EF9B71BE47
-:108BA000C4E54A07FBFB44457F03E8952A7E1ECBBC
-:108BB000774DC2F5882C5E5DC5933A7E3D5FF76CBC
-:108BC00091EEFF749D0FF673231CA93E90C7820B94
-:108BD000983E500F8ED8E4307C89141C01DFFF17BB
-:108BE000C1E95E58F73F0AA728F2E267306ECD026E
-:108BF0002A2F0C1A79C1E1F7BC1090530B34EF9770
-:108C0000D0EF6007DED1D7FD6896E61C67C68335D6
-:108C1000A8FFA9F38AFDB79D13EF203DF92C523F21
-:108C20003BF27BF332F4031A9B502E1EB991381796
-:108C300082FCE0E7B2AA7E59F8D3AAC360479DCB75
-:108C400012B19D45C5AB50BCB594C2E971BAADC275
-:108C50007D74EF5416DFA3EE9B2BF8BBBB2B1EB825
-:108C60000AE3FCBA48107F97CD3B92A0FCEB2E9F05
-:108C70003E08CB29BEBD16E0F78A18FCDD8115F948
-:108C800004EFD9AC987E2596EF51FD4AD3CD38CE6E
-:108C90008AA98C9E5654B0384CD847006EBDD1433B
-:108CA0004A03F36F10C995A78D077897E32FB62075
-:108CB000B8FD63D02B975950AF84BD13CF477CA923
-:108CC000381EC5EBF62CA46F368FD9CFA6FB97E2E2
-:108CD000B84EB4CF1FB3B94A505E3D1CABC0FC5771
-:108CE00059C812F3303047C82328F7F87C88EF05BD
-:108CF0008CF398C9F5B5CFCACFD9401F7893CB1B59
-:108D00002018B0976711563EEBA1D8A360DFCC7A4C
-:108D100048C4FB8564C9F52EFD79079D6B0AF8C729
-:108D2000F95F63C8067070433B3BF4FF9F3678CF12
-:108D3000C4FD10BBDF4BBCB4BD261EFA63E05FF080
-:108D4000B38B6CFEA43E5689F62EE8C75CBED3F901
-:108D5000BBB4E3A9E344F64BEDBB4F005E14EE0158
-:108D6000B807167A58E4BFD7AA9F6F9231F4A4854A
-:108D700096CFA817E3175178BA17D870BDEA7C6769
-:108D8000A686AE65BF0BABEFFF646C6D21F8C355D3
-:108D90007B843CA4B7C7C02FD19D17314E1AED9AE2
-:108DA0001EDFB93D1B690712F23793B65EF73D0D22
-:108DB0004588983FA72B4590006F6E1EBFD08DEF62
-:108DC0008879ABF034F48B0ECF2463B02FC82DF725
-:108DD0000213C221B2BDBAFFBD60215EB0131B05F4
-:108DE00001E9B1F18158DCCF8899E1D15319A30091
-:108DF0007DBE680C611C937737FBFDCF2E4B680757
-:108E0000CAA581CC9FD0F59EB816EA752633BAEE76
-:108E1000DC25737E22EC1D89F7C475582EB07E3B8D
-:108E200017C6627C14DCFF34C2BD4CEF9FEBC1BFA0
-:108E3000A2DAF1C777B0F714E0777BB47630DC9B29
-:108E40002D1F16960FF83E0CF0734B2CF713B92B11
-:108E500070BCBB6208C461D41A048CEBADADBC120B
-:108E6000EF9110FE8E73359F5AAD81DA83C3C27CB9
-:108E70005E6B383608ECA96AF3327CDF9996BF093D
-:108E80007618FCCC6EF7EF7864F7A4EBDA6567FE32
-:108E90008AF7DA9BF5F8AF0ED309DE8FABD4D24D4B
-:108EA00076981E50DF0639319EE0BD7C1BCFC74E41
-:108EB0006CF3839FC6C3FD16C907D8BBB5B682261F
-:108EC000027E53CF29A66F8C6E5D7B10ECDFF88994
-:108ED0006D6071D1FACCEF16797F6854EB7211ECAA
-:108EE0003A554FD1D895436E1EAA4DD97D5BB053EC
-:108EF00061BC207C02FE90D8FEF63CDFDFE83E88B5
-:108F0000F278AE6F30EE83B04F811C53ED5C906B06
-:108F100020475EEE376E5A3FBACE3C65DC2DFDD859
-:108F200039CC10D4EBBD9777DEA4D6037BF7E2FEF5
-:108F30003006B7D0CA382627E00740C14FFC5B791E
-:108F40002DBEEB0D8297CE77DEEA6C94BBAA9FA66E
-:108F50009AFBA94AB95FA794FB75C0AFAA8D7B05A0
-:108F6000BFA5365FCDF9BE067E4F0ADF0B3085E325
-:108F70005EC19F339E046C500E7E1D3BBB5FA76D90
-:108F8000EF21FE2209E9FC7B93EE5DAC156CBD334D
-:108F900039DE575A983F67F4436B45E6A462EB8D80
-:108FA0001BE6CA7EB420FC3ED7E71C4F2A5C8CFD32
-:108FB000C6DD03708F11D9FBE6A147D9EF5D9FA0F5
-:108FC000FBF356EEEFB8D98AF78B5D03212E417281
-:108FD00064DD1CE5775B97EEB6E03BFDCBFAB1F3C1
-:108FE00060F5FBB87EECFE2EFA8100EE0B6351CFEC
-:108FF000A660CE033A2AECAFEE97240FFC4F4779D8
-:109000007C67EDED5637F417E47EF195FDD8BEB5DB
-:10901000B21F7BEF5FCD77DB759C5ED4732CF0C7FE
-:1090200068FDD7FEEEFACC7FA2EEAFCF57C4A05CAE
-:109030000AD3AD01EF4FC6E6161BC18FB49BCB918F
-:10904000126EAFEF86035A90274DDCEF2C3966C0C5
-:10905000EF02ED3E958BF1924946265F76DF19438C
-:10906000207EEFD0E9579F788F969F3B65C4F7F03D
-:10907000E6707FEB6E78F71DE4E57613FA11AB8DA1
-:109080004C5FACDE3794E92946F74A88EBF66E93DD
-:10909000D1AF556DF76F7A05CBD39D14B3701F9484
-:1090A000E9B9BB6259FB18FF2F5F03BB735FAAD3FB
-:1090B0004BEB2F4873EF03BC66989438A29EAB0A23
-:1090C000E1FBA2C7FC4C2F3E068207C669B5F1DF63
-:1090D0009173A5CFA5FD1C7F3C15D743E52DEA4F25
-:1090E000C79F32E1B9D9F3DDE332FFE731B918DFC9
-:1090F0008B39B63DDF492D4BD2556C0C807FDBF3AD
-:1091000034D3E7661B9435001FB22FD6A9B3479F0F
-:109110002A63EF47543E34E562E7D820DFB5FEDD31
-:109120004E12CA427BB4BC7F13C49376B60E71B2A2
-:10913000E3AA343C24A9E5E7CB276406DFD05E1917
-:10914000E9F972FB07BAE8FE9D3B91E0EFB769CF02
-:10915000D322CF217AE6191E3DBB53B9DEA62FBF1D
-:1091600025D31D02F956FBCCB7471628305E08E51B
-:1091700021F1317FFA09D93503E8367E7C4017A703
-:109180006556185FCD36F1FD9E048C5A3E54CB0BCC
-:10919000C791A8E7362685E901367EEE1C59FE7F89
-:1091A00000F2988AEC008000000000001F8B08008D
-:1091B00000000000000BC57D0B7854D5B5F03E7360
-:1091C000CEBC92996426992493F7C93BE4014308E5
-:1091D000112DEA24040C98D209A062B538BC41C90B
-:1091E00043B0BDB1C566201102A2861A1128E084E1
-:1091F0008762D5367801A346EF8048B1D5FBC747D3
-:109200005BB4F7F78B4A29528188964BEFB5F55F2F
-:109210006BED7D92394322D8DBDB3F7CB0D967BF51
-:10922000D65E6BEDB5D65E7BED1DB36A602C81C159
-:10923000CF4C334B64EC1AC67F324F316FD0C69897
-:109240004555A9FC9A5321D37CC867AE0C99168961
-:10925000D40FE909230B59CA21DD620FEECCC29667
-:109260005E86FD2C9A00FF85A68B64D66629C3EF27
-:109270006A4FBF8BB193079C9EF5F09D7DF995CC0D
-:109280002A189BCB443D336BB7C431F67C9B14B298
-:1092900040BDB99BCD3BADD05FC56AAF6C87FCC00C
-:1092A00076C9B313EACD6DABCCDF02F93BF7977A01
-:1092B00064681A83E3603EE80CCA50FF9AE649EC02
-:1092C000E3718CCD37074D0A7C674F4B6C0FA3FEC3
-:1092D000DBB0FF65D02819E0F90A7FAE1F4A176F8F
-:1092E00036C364F9DCBFC27F8261F96CE8B7BB4B5F
-:1092F00066305FB617BE170E7D5FA6840E49318CAF
-:10930000D57747B4677F330FD643405980F0E832B2
-:10931000B13B7C369A74525D29637FC0FF26336669
-:10932000CAF48D53C763263769861DE65DC5E735E8
-:10933000B04F22BCD6B32613C37E3AE319BB3A6CB6
-:109340005C0B0B45437A520E50F922F3464A6BD41C
-:109350002C1AEF4ED66F6239D8EF80C907E3D9FBDC
-:1093600080AE2597CEBF06F960FCC87C3055F0C1B1
-:10937000B2532C742D8CB76C250BD58FE6A91DD25A
-:10938000450A0BC4005E17010E62451A55C6F1AAC4
-:10939000160EE16569509F477CAA6178463C869726
-:1093A00037F67C650ECF279918B3C60DD11908453D
-:1093B00070274D6A1ADB04705EB3322833985F4A17
-:1093C000BA77522EC01B5DCEE7DB78DC6251C760F6
-:1093D000DEC7B2A1DE176995CFE54179A3C2BCDD36
-:1093E000501E0D78E982EFDBAD2C80FD3F9EA75229
-:1093F000BF6E13E75FA3E263636D4897BE9001E918
-:1094000092C01CC88F1A3EB7DBA15D19B693A8DDC8
-:10941000607B0B6B8B0A6B5FF5A29531582F175E43
-:10942000B007CD509529FE4C27F497F87B335B0F9E
-:10943000F9B32FDA97607F678D6C7637D477C9AC34
-:10944000A99BF8650DE1FF8748D7F1C84D55A90CD8
-:10945000795F9A96CADC58BE9ABED73B81BF86A177
-:10946000EF607956DFCD9CAFCCEA4E18EF82B3FFA8
-:10947000079807785800F2CB550E77E3FE49637FD3
-:1094800004DF1B7D360FC7BE7F2CF2AB59BEE766EB
-:109490000BF0D71479E5C0BD308FFA749BC30C4D27
-:1094A000AA33FFE3B7B742FE93FD4666463AEF990B
-:1094B000349B655F0A87962E0D1A3FEA0F5B2F7764
-:1094C000EDD5E7EBBBF5F946A67CD4AFF101A06082
-:1094D0008B6A779D8C26D9E1F90AF8DB6C6E3AD558
-:1094E00005F09A5F327B56C1E706D5BF03D7538399
-:1094F00061E028E2D99CF9E9683FE0A52AF3CBA313
-:10950000A988FFFB9807E1BE60AD9C4BF4D862557B
-:109510000361F2AB51F07F67462D95776E35AB1244
-:109520002FAF1D0F726B092D61AA623100FE1B3730
-:109530004FFD441A4DE516A44727F029B57B4E0A86
-:10954000AE82764B362FAE65507E86054D1680E78F
-:109550000F623D35CABD532CF0DFCEB89A51285F5B
-:1095600094BF2A3EA4FF5AECEAEA217CBD34B83EFF
-:109570002D1D27002F373289C5E2BC9DFE97709EB6
-:10958000F5967E5325F473FD5FBF20B9BCB8F9D5BD
-:109590009C13E350DE78E712BD617E284716DF7B1F
-:1095A00088BE4B332C04DFC9745BD00CDF5FDD62F7
-:1095B000E679A789F227B74B945FDC2D052D595822
-:1095C000FF627C25CAEFED4687995D8AA748BCFCFF
-:1095D00071DBEF621880FC47102DB8BE98A329C636
-:1095E00067C7B2A69819A588AF1B3E41F9B578BBED
-:1095F000EC09A19C7ED9EEC963989F3C6AA10DDB62
-:109600007F1E5F89F8DB31D921D377D9877288290A
-:10961000DEBEEBE1BBB2E32A15D7CB91ED1CEEC564
-:109620004ECB1348E7EBFF2A13FF2B06E6DF674319
-:109630003A7847E1BA53B7ED9982F8FD635D8A81C4
-:10964000EA3F2B3107E2C3D99C88DF174B8A0FD73B
-:10965000D992CD4B6B59CC10DED7A832E1BD327315
-:109660006562BF8DF8FE66D477F5DB81CF71FC199A
-:10967000EFFFF656D710DF4B33364FBF06FB7FD2D6
-:1096800048FCA5F5D3B8EDDB823F180B019E160B05
-:109690003C993357E6E3F8975B0F8B5737E53B6C04
-:1096A000975F1783EB7D1BAC8F62C6FEAA4AEC2B3B
-:1096B000A0034B8B233D33D27AD4F493ADD0C0F5C5
-:1096C000BE8779F7409A64665E09E457769642E56C
-:1096D000D95926C287F297E57BDF04F89F53FDD165
-:1096E0005990CF64DEB1A867D40147552CF4664386
-:1096F00006294738CCC13D24E7200F78DA94C09E74
-:10970000581F066786E80FD6AB0BFB39FBDE974781
-:10971000118F0D199F8E46BDDD78F10B930AF4B4BD
-:10972000F54A24676D1E1F43FE68ECAD630B4A8645
-:10973000E463A387CBEF4BE44C9691CB33D700F592
-:1097400033359BCBB74E275F9F5B9BA38228F7B631
-:10975000BA8256043ABA3CC050BE4F2F973D08B665
-:1097600066A7F82C9C5E16EFAB4C467EF5C81E141F
-:10977000F17DDE8FDBE221FF66F9648F0C799B7748
-:10978000577B36CEDB6314E539019CF71B132BC9DD
-:109790005E99EE95695CB6242688AAA2CFFB8E6BF3
-:1097A000018CFB1DE67DE404D0B1069437D2B10FE5
-:1097B000C7067A9D71F827205EB4F97CDB33F591FA
-:1097C00013E1768697DB03F089EBB1F2E1F1305AD1
-:1097D000ADBC0EFBB9FE3A4E87D3CF9A83AB61FC8A
-:1097E000D356D03361FAE2B49DEB1D5F9624ECC2F0
-:1097F000EE0C94FB8379659401D7FD3D0E8E0F9797
-:10980000A93B03D7DB9F247D3F77B6CB2C0872663C
-:1098100069BBC48200E2E9A79ECF40F9FBC99EE77D
-:1098200033E685C117D94E4BBFAB8DD7F198D70220
-:10983000E3CD63DA78A1341C6F9EC7FC21CA0FD632
-:109840003ED9DB1F663F90840CABCF367B497E9FB1
-:1098500083D5887CA7B53BB724CA8B76E6396609E1
-:109860004A30D4BC5E3964C6FEBCDE5C17D0BB4156
-:109870006B1FD17FA7E01FA9470AD9A17E74C90039
-:10988000C9DBA516DFD154285A8A7484FA53918E05
-:1098900012F2ABD784F356242ECFCF387C7767C132
-:1098A000BC1676E8E9989EE5E0F375B8B83DD86057
-:1098B00053505F24B6326E077EDF10447DED8A8AF6
-:1098C00019CDC08E31A5B86D28A7AECF8F6A33C42D
-:1098D000E2F78C20D64F4F29A476812ACEDF81442F
-:1098E000166C95B0CB2689EC40473F53E07BDA04F9
-:1098F000E6580FD9DE2C6E27BA9967B34C7662B75B
-:109900008476A286074DBE23DFA0DC3B2D59886FED
-:10991000A45E89EC3ED9D03D07FB1D898FB644F08B
-:10992000D1967F321FED1A918FFC2AF191DB323CE8
-:109930001F81DCFC46F559C0A700BE9204BE1E166E
-:10994000F265E0FB16A21BFC4838DF5AD15FADC5BB
-:10995000169247939CF874507E433FDBC0FEC47D53
-:109960004A32DACF90A6B6CE55B9FDDED72F417F69
-:10997000D1575948EF3D60E8CB423B3FA9A8691F4A
-:10998000F247D29C92B256B24FD29C28F751D6E001
-:10999000FC1B9A27F9B81D00FD221FD599683FD1FD
-:1099A000706FA58FDB0135B43E1A375855D46793D5
-:1099B0007AB356217F34AE04FB08E56F4FD7964546
-:1099C000906F9865F3A09D62B5CC2CC176AC5DBF5D
-:1099D000CED649DD641707A6320FCAED734143C0E6
-:1099E0003806E56CFF8E1FA11E5F5AE209A8B8DE9B
-:1099F000045FE632D20B9D4E6F721CE0F5E0DF642F
-:109A0000DA17758E853CA42F097A76D679939D90C6
-:109A10009FB7C14A78EFECE2E5E7EC8020E83F45EC
-:109A2000E6FDB1580BD73397CA030BE23D7102D361
-:109A30007E36633E45CB773C46768CB6DE3BB3380C
-:109A40003CF6125F165ABEB7ABE3FAA260BD27CA56
-:109A5000066D531440BB3B1AC7E4792F0EF7A801DB
-:109A60000049C1EC7F6FAC9E189EE7F587DA3F3066
-:109A7000A33A8DF4EB6039820D7A57CB7BAD00C7EA
-:109A80005AFB50B902F6A4A54712ED27CC980CAAB0
-:109A9000F89C24C60F281BBD808F87AD4C375E38DD
-:109AA0007C4A44FF46E8DFA68AFA8152DFE45C8004
-:109AB000B74C6BBFAAC30BF03D6CD4F7472815ED2C
-:109AC00031A38DF7EBDCD7376E481BD2FF600FD880
-:109AD000B3C70FD9016BDFAFED180363453B3E37CA
-:109AE000A17ED5F479A34B223B2372BD2665F3F505
-:109AF0000A766D5236C90D6EEFD6A2BD2B939D3BF3
-:109B0000059756E34A1F43FB12EC86D46CB21B3E0A
-:109B10003D7908BE77CE384D767EE34585EC8F469D
-:109B2000B03FD06EB7F4727B96F51849EF6A74BFF8
-:109B300053C89F4E27E87DE4D397A5F1C8A78C357D
-:109B400065DC043468C9F6E6211CDA7E2C12DEEBF3
-:109B5000B2B95DDE5858B5251FFBDF2D31D4FBEBC4
-:109B60000B3F4A44FBA4B1F7C3C48561ED96F63CB4
-:109B70004A7858BAD738ECFCAFCB9669FE0D2F1C4B
-:109B8000F0E27A3F1D94682D2F5182EBD0AE5CB28B
-:109B9000C480961A2B0FCEBD15D73D9B6D627930D0
-:109BA000BF5CD44BB89FD83B33700DEEDBE0AF0405
-:109BB0009FB6FA16D1FADE3ADB62635908E7BCBBFE
-:109BC000090F8E282FE2617D6155328ED35037C543
-:109BD00081FE9346B0B3B0BCE1DEEF923F45836BAC
-:109BE0007D8FB106EDAF0AB0B7FE15E04E8F9B56E4
-:109BF000E381F5982AEF1BBB02F29B4690BFBFC9D9
-:109C0000E1F46C937C81EFE0BA7F41627BD4A1F2F6
-:109C1000CC1E6ED7DD9CCDED40EDFBCDD9DCDE9CBE
-:109C200018E89B84BCF78AD21F8DF66F23F37E86DB
-:109C3000FB4EE6B3A97B884E5CEEB85A54F22B5922
-:109C40005CFD0F8CC1F2890AED2798D2FF088E7B4C
-:109C5000769DCBB39E09FEC5FCBD2541DA3F64FB72
-:109C6000E7237D2B841D79F6851BC6CE2B19B29375
-:109C7000D6755983AB010FEBECEA4F6A50BEFD4538
-:109C800021F9C62C037D93901EFF1547FDAEB30648
-:109C9000D721FD031B8D54BE2FC5DF807C79AAAE72
-:109CA000261FF7C1CC16C8AF037E32BA3A18DA0BBA
-:109CB000B07D203F83C5E5632AE42705E62A12CA62
-:109CC000F908FB6312FA7968DF0083C3F72A21B62B
-:109CD000F2800B4E5A6809B47D153F648F1CFB72ED
-:109CE00096821F353BC560F12FC5A6D5B3A3988CCE
-:109CF0007CBF66E0A801E613EDEA233BB6BE5BA29B
-:109D000071EA0B9F33A1DFE4AE6EBE2E1BC53E0091
-:109D1000F09781F6C0DAEC68A1C7DB38BFB33EDA52
-:109D200047B367383D19837AF6F0FDC42AAAA7F530
-:109D3000675ACDFD5EF5C21F037290CA7F922D89CE
-:109D40007DED6A9176F0548CBB49EAF3CA88D7B1AD
-:109D500092279C6FB4F429212F620F0F4CC1F53B61
-:109D600000FC857E992D52DDDDAFC1FCB68C2FF253
-:109D7000A009E5067692CBF03BB022E0BDBCE7B38C
-:109D800029C8376070D37A6DE8A994EB6DA4B769E0
-:109D9000FF9814DDD485E5497714925E8D1AC7EEDD
-:109DA0009801DF7F2EF09A6CE37E2EF7EA40D6F220
-:109DB000121CDF77F76B387E6914F929938036F629
-:109DC000384ADBD12FE466AB24ACF7680CEF3FC117
-:109DD00020DF5157427297F2711EC9BB13D29E6C9D
-:109DE00027F76799590DC289DF693F069C81FB59A6
-:109DF000F473613F49393C3D9B1C5250406C65FDFA
-:109E00003BF6207FF6981D88A7DA9E5F1E477D5996
-:109E10006B61DD32DA2B1176C6CAF49987903FCF99
-:109E20009D39B9E37EF8F6E84D073D7EA28BDE7ED4
-:109E300088DC2FECC42AC923DB7BBFCBD6DB7B833A
-:109E4000F97FB8BDC7EDFAC09E68754F983C6F1496
-:109E5000FBB4734BCEC7A09EF97890BF404F570C10
-:109E6000D92BF376477F88EB6AD0EE8FB01B8E3DFF
-:109E7000111D40FA9FEFB6929F4E41BB07E0396338
-:109E80001FF80122C765F27925DC3FEC337A56438F
-:109E90007F8D779EFEB901D69DD205764F2CDAFBD9
-:109EA0006A2CC9D9D765B607ED32C5EB40BF870626
-:109EB000BFE29CE2F696A05CE4F35F660AE5931DC0
-:109EC00064624B281F13CA47BBE725A1779645411B
-:109ED0001EBE37BBFD7F41BAA598B9BCC276F8BD9E
-:109EE0004BD85B5D801207E2E538ECBBB384FEC65D
-:109EF000FDCF83E9C1F5E4C7B1103D3F7EC5BC137A
-:109F0000FD3C1F171A4226EE97203F96DAAEB0644A
-:109F1000A8AF1EB70655EEEFB21840FFCF7FF8AEE0
-:109F200037705F31FF15EEC79A7FE7CAE9B8FFF8CF
-:109F300078C61413CA9B85CC4F7EE7C58CFBA197CE
-:109F4000B220F757338701C7BB0BC4C6561435017F
-:109F5000C0FE55F05932486857A86D9027A3D9DB49
-:109F60005103E3CE6B33D0BE647EBBDE9F7E61FDCA
-:109F7000DD35A8C7D7B619B8FDD82E911E9FCFBC26
-:109F80006EB43B34BC16E4C473FF689BC18BE35CC6
-:109F90009F6322FE031205697E226D330A3FBC8057
-:109FA000631533843035483C5DEB506A86D3CF5A15
-:109FB0007F6DC6260BFAC306D20DE407BE60F2CE53
-:109FC000263F6A5C3E433F629BBDA9BD8697D39AFC
-:109FD000B9601DF051F9B50A37F8981A87F2323D89
-:109FE00087DB0F91F35DD8A1CF479E4F2C0DEAF38D
-:109FF000F399BF203907FD46FAEFE9395C5E5D58F9
-:10A000009F25CE013C740ED06654DFCE4279B54E0A
-:10A010002179B92A8DE3CB90CED36C67F56CE25FE2
-:10A0200027D817042F873FFB5A97847AB3CDC9F9F5
-:10A03000F27F0A7724BC37E4E413BC6D68E4C1788E
-:10A040006DEBA420C71787FB4AFD174B72F47268AB
-:10A0500030FF8FDF77727E5C278BF5E6203934CFB7
-:10A06000C1E7F4B1E4792284DF6D601F00DCF3D72F
-:10A07000C96568A74C9A69A37934BC62257F6BFDDA
-:10A08000CAFE0CB267ABFAF39B86C12B42AB68F2F7
-:10A090000BEACD73C13E01D76DBBFE9C0A342D0B7C
-:10A0A0003F779A99E6BD2F2701F7231FEFFB25D2B3
-:10A0B0007B9F95F413FCEF9019E5D70B596437E5B6
-:10A0C000A7F9EFCF41BD1E15DAF16416DA29DC4E8F
-:10A0D000AAEF3577A11D38AF2DECDC0BFFD9A03FDF
-:10A0E0000763ED71E4DF609DFAEF4BB645B4BBE466
-:10A0F0005C8CEBFB4D26FF28B4EFAEBFCE9B8C7281
-:10A10000F5CC520343FACE973D8B508E9CB1EAEDCD
-:10A11000EF33764EAFDD8374F6E4239D778F486787
-:10A120004F3ED279BE81F9C3FBA9473A037D970917
-:10A130003A9F3970553ED2F9D37D57E5239D3719A3
-:10A140003BBCB86E7665FAF7221E4F4CF691FD04C3
-:10A15000F22AFF9BF0E38B11FCF8E2FF1E3F52BB9B
-:10A1600091F4E1D19CE1F5A1CBA4A6A13C9C67317F
-:10A170007FAD5EC49F61FD6B1633F9255EF9F2F386
-:10A18000879E403BA457263B44EBEF15C59F837E3B
-:10A1900085578EBB3D0169E4FEEF16FB18B78505B8
-:10A1A000D0FFA1D9FD9AFD18298FDF17783C9DE3D8
-:10A1B000FD36ED1785BF7689E8D312FC9CDBA9BB81
-:10A1C00025F2C75AD46E2FDABD0D2FCF75A0BFF67A
-:10A1D0005490FB671B0E8C25FFEDD2E0ABA154B46D
-:10A1E0000B7B2507EE1F96EEFE3006CFBB613FFAD4
-:10A1F000494ED87E74B2D88F9E0A7E1C83E7E23027
-:10A20000FE54D4CBD1AE0113F26F03ECD3A00A6B92
-:10A2100050068E627F0D2EE609A0A8E8D1EFDBB4D0
-:10A22000F3CBAD3E13C9BBADBD5210F76989267F94
-:10A23000561AEA2796E6A0732EB15EFE33C79B98A6
-:10A240003B3EFCDCD8FB971C7EAE4CEDFBB7C4124A
-:10A250001FF61B9997EC802D7621971492537FDE81
-:10A26000E6A47D0FFD40FD3F07B328AFE9EB450AAB
-:10A270000B2980F745B3BCEF21DD507E8722E477C0
-:10A28000787EF03C9AF571FD02F23C34DCF9B83886
-:10A29000A7C6F3DDF0F60D6C80DAE139AFAE5F6D85
-:10A2A0001FC09AC6AA00F75DB7DB3C68BF34025FE7
-:10A2B00037970DF1E13231158D0F1B849FB771C9AE
-:10A2C00047B41F68EC911CE8DF5DE6E17CB80CF652
-:10A2D00049E6D197AE5BD60D7C1806F748EB785C63
-:10A2E000AE7E1D0FE6FF49FECCEB72F5EB579BBF30
-:10A2F000E6171F9C67AFC4D757C4BC22F79791FEDF
-:10A300006C6D7F78A572EDA6087CDCF4BF8C8F9114
-:10A31000E4DADCDC91E49AFEBCE01BCBB5C87383C5
-:10A320005CEE07C773033CD7FD9F9E1B7CA276247F
-:10A330001A480F7A75E7A968A7E338EDDB65B20F15
-:10A34000A6C8FC1CBADE6E263F6DE4796BA33A45C5
-:10A350009C2FF6FDF66AD49FFB8D0CF5FA12DB629A
-:10A360003ACF6C949F3139D461CE19954364BF7F45
-:10A37000D3F3F775B983E7EF5978FEFEAAEDF378CA
-:10A380007F185DAB4AC0D02FA1389661E5F62382D5
-:10A390004FA245FC844509306758FB91DAFD34979C
-:10A3A000DBCBAF8A381AB789B5637CC6C3F6682F92
-:10A3B000EE4BDC061EE7D392EDDB8E72D2A2723C2E
-:10A3C0003FFEC22DCC00F37FDCD84DF224506FF35A
-:10A3D000A05CD4FC305AFF56B15FBD52FE3F30C87E
-:10A3E000779CFF07F3FF2479F06FDA78DFF49C6C39
-:10A3F00033E046B74E189D87BD81E73B5997F2F38E
-:10A4000048FD8CC4D76FE7FADECC25B9E01D4DE7D7
-:10A41000FE572877A2CB073E467F0FDB6F5671DFD2
-:10A42000817E0FD2971B92B91E533C158867B0F7F7
-:10A430002A304EEA03FCEFD523DB87A706E513B7E6
-:10A440000F4F8D289FFE3EFBF04799BED3C867276C
-:10A450002ABDF9A83FD7DA017EDCF73DC5E36BB62C
-:10A4600059397F6E93385FB2E678CD7F42F30A3C6C
-:10A47000CBCFC723F98AE5E9F96A30FF4F96ABB62F
-:10A480004138FE97E5EA92FF8A413FE8C8FD04881B
-:10A490006E15557D84B7819725B633CC3FDDD8C77F
-:10A4A000E3D4D205BCDAF70BC2DE5D94E7CDC07809
-:10A4B000AF4FDFB358582C9842C8636897F96C7453
-:10A4C0003ED0D0CDE3481A56323A0F6E40FF6709AE
-:10A4D000FA05EB18DA7FCFA9FEC2BCF1789E610BBA
-:10A4E000C8B1E8379FC1D0EE3BFB1ECF37A8FE12A4
-:10A4F0002C6F5CD9AF3B87A8F8EAF335E8D7007832
-:10A50000C94FE042BF4D189D66E7F1F84B2DBD29BC
-:10A51000027EF4E313FF77CB41B417A3D53E3A177D
-:10A5200068D8CF8DB80AD94BFE7B76571C433E6A5C
-:10A53000D85F39F635AA6F1D8BF66EC5EF6B1DE837
-:10A54000A7F8F45A17C51F64C8FD4BD1DE3A92ED47
-:10A550009F84F8B09707A7A2BD9A09F62ADABF9F91
-:10A56000EE9B3A16E1D6E4DF26F47F43BF9BEC7AFC
-:10A57000FF36B378B3EE47FFF7CE24DA3FEE4BF168
-:10A580007F1BE7BFC9CAE10D6CB4F2F52AFCDE916E
-:10A59000EB5F5BF749B281C649BACD42E7D49A5C1A
-:10A5A000D864647E4BCE903C1927E2E9001F3C9EA4
-:10A5B000AFB78EC78188BCCDA58F6B3C9D33791C0E
-:10A5C000C2332E4FA1760B2D0312FAE1178AF3F94D
-:10A5D0001B449C85166775C6E15B80F8602B6B8613
-:10A5E000CEE5B3B1BD83F3BF889F89BEC8EDE86CEB
-:10A5F0008789F8C6DECEF8B912F00DD267E240DFE7
-:10A60000A458984F6E676822E2F3958B06C2875272
-:10A61000F7069DA7C422D9A09F9C0DFDEB0AD09FF1
-:10A62000E278F75AA48BDAE1A842D43DA7FAEEC942
-:10A63000A375DE5488FBCBAADF1879BCE0CBD164CC
-:10A640000774662CA378C1B3EF03BF665DAA0FB48D
-:10A6500034C056537C6076CF3BE4D7B7EF97868DF6
-:10A66000FB7C38CFC6E36F027D1487C626BA081F6D
-:10A67000CACBBF0FA0FDA1AC53C893D166F41AACEE
-:10A6800048D7558CFCF0799D0E03D22553C49D9C70
-:10A690007BE5BF47FB69BFA2F9F1833C4EC8D8BF39
-:10A6A00006F75FCAAAFEEB6005B3FAFD4E4303FA54
-:10A6B0003D8D030DE43779399AFCA3993D39ABBF41
-:10A6C00005F9CC76079350FEBC785726F27500E664
-:10A6D0009937CC3C9BF38CB45E9497A30DA8B794A8
-:10A6E0008D8CE21415676215C1FD28E4A19FE582F7
-:10A6F0006FB4F34900D78DFA68519E7F37D23B5A29
-:10A70000C801D61C45FE44BBC2FD1EF6E6F79F5DA0
-:10A7100005F91DC21F7BF895E219E4BF5BA7484805
-:10A72000870BCEB9990EF8FE8B3C6E8FD8953EE61E
-:10A73000B085E3FF30C56566BFCCE3D61423E713CD
-:10A74000659DAB0BFD835FA4F929FEF4DAB6904C4E
-:10A75000E75B8E138FD4A861FB9BCD5C8F34ECE557
-:10A76000FBEAC8FDCCE5F4C7B13CBD5D3E98FF27D0
-:10A77000D925EF0C8EFF77EE53987E7F17699F44A3
-:10A78000EEE72EB1BF23FA1BC94ED1E23CAA86C622
-:10A79000217E78D5AED941015D1C4C958D8FCB2C97
-:10A7A000FAFE9F12F13B5A5C4C62ABBA0AE3CF0748
-:10A7B000EE63E46FD3E276B4389D4015DF47040CB6
-:10A7C00020F7B2F07CA883E27352594892683FD0D8
-:10A7D000CFB07D12C6E940FBFEBC6C827F3BF3B478
-:10A7E000CB24175509E1B7627C473CC21DDCB20897
-:10A7F000C7BBC946E35931BE239EF611B48E537CC4
-:10A800003CAE73D2121E0F9A02FA17F329B99C2F8D
-:10A81000ADB34D14E7A9C56D68F11D1A5EAA04BE5B
-:10A82000530A1665E17E418B03D914157CCA2A634D
-:10A83000FC8790FB4B0D24F7B5F8BACE3C3588FC6D
-:10A840007E0EE3406D571EEF11895F2DEEE3FA7423
-:10A850007F72FE788AFB203DAAC56B68FC1246C752
-:10A860008015C6DFFA32B7DFAB969808FE734BA7A8
-:10A87000917FF1DC5203C37554D56BE6FC1731DED2
-:10A88000D6D92616C27E95A015E5A7C60797B35F51
-:10A8900081AE85E8BF3DDCB237E704ACF9232DDD9E
-:10A8A000949EB34ADDF2184C07E6A0A41AFD64C6D4
-:10A8B0004CE56A8C6319C8908075CAF6E6CEA27C16
-:10A8C000C2C007989FF6E4AC590AE8897379033B44
-:10A8D00024A8EF2FF87026E5912753189BF0C46F3A
-:10A8E000660668DEDC1F3549F8A3CC4EFFB5F909D2
-:10A8F000785FA07F4D1FF97D78DC3FC605223DDCE7
-:10A900003613D9376E118FC9AA457C269ECC40BE1E
-:10A9100035792C9D67DB98BABF0FCBD3CC5CDF3386
-:10A92000CECFAD79DC5F4C2A1265679AE65FEA0FFD
-:10A93000A0BC6ACD7252FB41B9BADF1CE47E2E3E48
-:10A94000FE5B074AE91C4A8B3365CC913EAB94E22F
-:10A950005174F987ADFC5C94298E74B41F5A8DC272
-:10A960004E15F9A834FF77F3C3ECA4B726FF4B09C3
-:10A97000AE8733077F948B72EA0613D8F1C3C8A55C
-:10A98000D4422E97CE196DED12D86D6FA4FAE7233D
-:10A99000BE8E47CF99E28479CD8EAF343911DEC0B7
-:10A9A0005332CAC904416FE72C0E9FB3DA272D84B6
-:10A9B0007E5BADB09EA17D825FF192BDEE9F25DDF5
-:10A9C0000470B74AC27E676A2CD9ED856A2C9EFB5B
-:10A9D0002D6B7E87E2AE652107642107DE6EE9CF2D
-:10A9E00055F240E5766F94D1DE7E479C3FBF93C51C
-:10A9F000EEA81B66FFBB299FDB873364B514F9C83B
-:10AA000075FFC4776A812F64932748F44BB7ABC8AE
-:10AA1000EF87EC15EE7EE847CABCAF1CE3965BD32C
-:10AA2000EF2BC7B81339CEE3F685E537E5733EAEB5
-:10AA3000C67A88B7E8A672D463FFB0FE62A1BF925F
-:10AA4000BFBFBFC17ECC1CAE6596810C05D6A7C723
-:10AA5000EDDF8A74BB30F7433A8FFD41CA5B1F605C
-:10AA6000FCC45BC68E49312887B224C1B7DC5E3B8B
-:10AA70005AA0F93D79DCFBD162EEF70439C4E32B2F
-:10AA80004BF93D9BDA598CD673AD88BB98E2E0F761
-:10AA900096A69467795A616AD3D98082727ACA710C
-:10AAA0005F0CD28FCDF297FB4A47B6C398DBA886DE
-:10AAB000CB95A96A581EFEDE58A8CF7FDBA3CF7FB7
-:10AAC00067C25F0BC2F31BDDDEE771DE2F493C8EF0
-:10AAD00033703573D03C5D5200EDA5E2E753BA8484
-:10AAE0007F97E20D7F26F673CF4F60549EB8D7B2A2
-:10AAF00013EF1F687E72599417BB9925338EF0416E
-:10AB00007A764012718B2E3A0B6207EF7670FC4119
-:10AB10005D13F47370AE4AEB38D16660D7E15A2FFB
-:10AB2000B790FDA4AD8B562BF037E0B122D512853E
-:10AB3000FCDE6AF46CC6BEE428B38A7AB532C6423B
-:10AB40007DCB3F56482FADB29A29F4F5F08351944E
-:10AB5000AF50980FE33500C45998BE65F4049B705C
-:10AB6000BE500FE7DBEA6424AFE40A13E969E89713
-:10AB7000E87A78A321C868FE950AC5630A98B57576
-:10AB80000723D1F7C7C4BA960D2C44722CC5427264
-:10AB9000EC08F48FFD1E7E5DEE223F5BA17A3B96B2
-:10ABA0009FB714D0FD9CC6C17B478A01812B1476C8
-:10ABB00094B397DF0FD3D6B3265F22D73348C15C57
-:10ABC0005722E320AAF80F4C2311F53E237B5E3B6E
-:10ABD0003F4CB768E58A17C7491EACCFEF67258A97
-:10ABE0007C6A4116AD37A8123294A1FDF1CBBF208B
-:10ABF000DF6AF261C7DA1F937CB814FF85DFA7FC18
-:10AC000034BB83E3BF200DD7A11C559086FAAED587
-:10AC1000E9517D61F9425846B3E3103F500FF233DA
-:10AC20006B3ECC55C2FC83A9052A094BA8E78D07CA
-:10AC3000380E5BD5345CAFC38C5BCFC78DFEC78E3F
-:10AC4000EB8671A1DE613B8C0BF5765BCD2143CCAD
-:10AC500070E34F5071BCCB8D0BE824A44E137806E3
-:10AC6000BE08A05FEAB0DD40FC394DC4EF1E4EE0E7
-:10AC7000E3B1427D7C4D6E148C4FFE587D3CCD0D72
-:10AC8000D2B636D4CB8F596376223FFE52F0C9D16B
-:10AC9000E81FE7A25DF5CB39F94750AE4C895DD589
-:10ACA000864C328D7593BCD1E4DE85E40F2B300FDA
-:10ACB000F2EF9A02A0FB0FB2DF9A839D1F713E96BE
-:10ACC0008BFA0FE4C3B70A122E855FE3470D6EE4DB
-:10ACD000435C07837C1801BFC6476C7A3705206E3A
-:10ACE00007BB1453CD4E65AC89C789ABE943F30369
-:10ACF000269E6269E2F3581520B86F703E42F168F3
-:10AD0000D78EF2FB10DED9633ECB50B0B27B6E0122
-:10AD1000EEC300DEBAFF9FF046DAE5978B97D6E0E8
-:10AD20008A5CC7DAF8D28CBD142FDD38CB46F1D35C
-:10AD30009344DC69E31203C511C1FE8DECFE066687
-:10AD400009A21CBE46D8D15A1CFF8B12F77F060EF3
-:10AD500098D53D61F6F8A571D42AC5690756F278F1
-:10AD6000EB417BBB9EDBDB837A4DDC1BE81CCB65B8
-:10AD700079E7DD2AC553BC24F1FA81B98CDBEB7588
-:10AD8000A27CA143C45BC05C1287E2D93BBB18F133
-:10AD90007FA73D9BCA5364AE7FD8B7B8FEE9CCE22B
-:10ADA000F664E7ADF9540EFB825188F7F932D8CF3B
-:10ADB000FCFC9EEF0FF2F878917EDA4D05DC2E1B3D
-:10ADC000B473443ED22FBB2BD3BF05F965618937DD
-:10ADD0004302BE9A6FE27E57E0BB6D7867A6863568
-:10ADE000ED5672F0FE45D3BB861CE2BBC789EF8AE5
-:10ADF00081EF72747C172C18CFE52F0A538DEF0664
-:10AE0000F9AD30325ECEFF148EDBE9ECFE7D03EE51
-:10AE10002B7ACD44072DEE31729D87C173C2C8E1F4
-:10AE200071C932C1B36F3878AE84FFC3F92D89710F
-:10AE30003E1F691D24292C602F1B5A071BDDFE10A5
-:10AE4000C23FB81ED6F07DE42570CB36E28B9B6FF7
-:10AE50009539BF46737D8EE74DC9307E9D18FFE65C
-:10AE600075BE6A27D6AB93080F75BDF51417C6AA31
-:10AE7000F9B99107FE203CAD42CE69E75BB345FBD3
-:10AE8000998E3A23FAE366D5EACF9966DBF839D68C
-:10AE9000CDB38C1F85DB3DB3D986CF308E71369E06
-:10AEA0004369F5818FDE2F183C872AC073A823C21F
-:10AEB000CF720EF81AF9FEB584C5DBEE06BE2BF88C
-:10AEC000694919FAE326272EDDBD11F24F6E2DA236
-:10AED000FC6B89B7DDF31696EFC8A77CB541223E1F
-:10AEE0003D57CFDB1756DC3A2D2B06E5BFE817D7C9
-:10AEF00013EED7A3FC9D7550CF3D3ABB0CE34BAB93
-:10AF000085DFE0DCDD8CCA6F1C63E721BB8B55F26B
-:10AF1000FB554789F2EFF17EDF18FBBB328C33AE75
-:10AF2000CE1E9883FCFD46D94B45983F227D36675F
-:10AF3000B873AFE24229340AF0521DC7EBD7963DF1
-:10AF400095827E98EA2A9E2FF654AECBC172C3F941
-:10AF500039C3DDFF8D12FB9EC1FB6C625D3FEFFDCF
-:10AF600090EEAFF92C9207A7E89BF021F91D984DC0
-:10AF700072A0EBCCE7CD52D0CF3DC9CBE350AB2C88
-:10AF8000AB92517E4DF79BCA319ED861197B04E389
-:10AF90000C6227548E47BA4EB230A22BF0794C2166
-:10AFA000FAB5AFFA2C230699CBA6E7738D8FEA3456
-:10AFB000FEAED6F331AC4F57E1F8CBCBDB91F818AE
-:10AFC000C6CFC0F6B3BFA5D73783FD45ACB7C8FE23
-:10AFD000479203F8132E1787E0E8A6759586D17D72
-:10AFE00039B8EE3AB4753706E13019FAE81E4FA6C3
-:10AFF000E429A20BAD133C16D24711706BF0A58368
-:10B000006C636597C2853F8A662F72081C8E441C4C
-:10B010009797433B2F8B1B820BC6BF1EE9C0D67090
-:10B0200078B64B4D5C6E88FD81E6CF68D0E6DBA339
-:10B030009F6F4514BFD7EE46BF13B6738D2DFA3AF6
-:10B04000B81B853E9D65F13D688639DCE49C4FFC6C
-:10B05000700B683427CCFF6FA9FE3AC447AB147855
-:10B06000B93F8BFCF114FF01F49E5118660768701C
-:10B0700045E2A3610479180977241E86E8D3978CEA
-:10B08000A9761F6E705E11F369B5F3F53A30DECC28
-:10B09000DFB550C01485FC9B5211C5A16870BD2955
-:10B0A00071BF6440E2F78F347B2212BEC87B7A1AEC
-:10B0B0005CE8EFE3700CACC23B820F166A7E3E4E3A
-:10B0C000AF24019FC9200D7B1EFE60A141F3B3EAAE
-:10B0D000E819797F4DC39B16E715892F2D4EEB920A
-:10B0E00073B78873E591EA4960A7A7C65D8A47ED03
-:10B0F000DC2E6ED04FC9FD4003F7DA490EC60DFABB
-:10B10000298F2968DF4FF21C52D02EAFAD81090084
-:10B110000DDE147E1F0DDF0F64F8B71492DEEE1FF4
-:10B120008FFE959F4C7D82CEAB3E30703F7D247E5E
-:10B13000F68C809F91F87D24F8A3D27C4FE2B8670B
-:10B14000A4BE0A2CECCC16E742CC9F85EBC1E9C823
-:10B15000AA44FF11C8D7AFBEC24D2B16015DCB3339
-:10B16000FDBFC076B730DF64A46F5C8DDFC8CF4908
-:10B1700018F9E1978BFDE364A177CF6FE3F11ED55A
-:10B18000DE518F4D44BBF198910569DD7B497FDE2F
-:10B1900025E03F0F2A3684F59FB193FE5DFCFA7CD3
-:10B1A0008AE328D86C187A4F03FE8E0A46E9DED36C
-:10B1B00028DE1BA7CB9776A7E8EA8FE9C9D6958F3B
-:10B1C0000D15E9CAC71D2BD3E5C7F75DA3AB7FD526
-:10B1D000F12A5DFEEAFE69BAFADF3A354397BF7697
-:10B1E000E0BBBAFA1F0FFA0F84DD10F0F615C2BCEF
-:10B1F0001788795F7F719EAEFD9F62A61C437E5CBF
-:10B20000B081C7A557028674EF8B7470FBA209FE4C
-:10B21000207D27B3018A076C084A9E10C3F836BD0B
-:10B22000FDB1B4A78BF078B9FBF805AEB90634B917
-:10B230004F170AFBE32A76158F67FD7ABAE6B3BC8F
-:10B24000BF8BAE66B79EAE56554FD7E8423D5DED1B
-:10B250001E3D5D6327E8E9EAF4EAE91A5FA3A76BFC
-:10B26000824F4FD7A4D97ABA26FBF5744D5DA2A7B9
-:10B270006B7A939EAE99CD7ABA6505EED4958F44DC
-:10B280006F4D9EE6B42FD7D51FA4BB6F09C537E518
-:10B2900075FC50D7BF46F700FC41BA17301187F94B
-:10B2A0003FA47BE1283DBD416F8D1A359EEC8D1288
-:10B2B0004C671708BBDE37BCBDA1C99F70FD1EBE21
-:10B2C000AF1D492E5DA2CFC43E77447D16B1CF7D20
-:10B2D0008F81BEA5413690DFEA56C19F87A338DE35
-:10B2E0003FC7A2ABA11ED4990070BD8770C338EFD1
-:10B2F0004515933FE2BBACDB88FDDFCEFA289DC34A
-:10B300000628F53307E9EF79CC43E902E63309FF74
-:10B31000C4F45109E8B7E8AF40FD7F61EE5B1FD090
-:10B32000B9D61BF157F40EC547787E92C7D849218C
-:10B330000F4EE0390AE4CF5A07F5ABEA0AC3DB49FE
-:10B34000E16F9C3749223DCDE4288AEF9A778B4400
-:10B35000E744F3FE93A78B46493C1E24226D6DD62D
-:10B36000F0C7F7473B47A904471AEB16F61CF3DB77
-:10B3700072A81F7EEEB1CB44FB58B785C3F7ACC4AF
-:10B38000940971741D8EE8EAB670789E35320BE22E
-:10B39000F369E65791180F2820A2F83D8C22E48F1C
-:10B3A00079FFF95636FAE9A2A25E98557D359ECB13
-:10B3B0000456919FFC7B4CEF27BFBD49223FF9F714
-:10B3C000004E48DD0E8F1BED7C2DFFB080B71AEBD1
-:10B3D000C1F7247793847EA97F587FFB7FC8EBFD5C
-:10B3E0009DFD0DF6C3385CF883F4D3FC9E85061EE4
-:10B3F00027317037DF1FEDFE1EE3FEBBE640650020
-:10B40000CF45653094308ECAC8EFC7EF1CC5FD9E8E
-:10B41000C9AC8FFC0BECA866D7FA49FE9688FB17DF
-:10B4200067C5B9E2A22E0BC3389D927D87E2F01C5E
-:10B430007111F0601FEA61C54FEFBF946C792D8EDA
-:10B44000FBFD8C4EBC57A9E9FF91F9546127C3EE6F
-:10B450003100DF350D677FBC5AC4E3035A5BFA46FF
-:10B46000E139A006CFFD2DC7282F2B1E86E797F8C0
-:10B470003E5478FCA3C905E561F24EB141FB303979
-:10B4800064B4F9E89195352D7D74BE6814EF58AD1C
-:10B490004D5BEEF087D989874609FBC71260B84F2C
-:10B4A000E02A0A53E524CAB5FF627C1F6D76433F4C
-:10B4B000E1F2F362020B3F1F686F394EF0AE91FC70
-:10B4C0007EECC49CCB4256A08F59C1BBC0F07DCB53
-:10B4D0000DC7308ECB645FEE09A923E3CDEC562E69
-:10B4E00084CBD3B723E4E94F5A068A719CD6967E63
-:10B4F0000D5F0CCF6B03C9DCBE6E6DF984BE1BC043
-:10B500003E447E7B754BC12115CA3F80BFF8DE8E5D
-:10B51000D9C5E162175DA457E7083E405F5C3AF089
-:10B52000CF07CD46E2B315E9363A2758F166DE215A
-:10B530002FAC67134C57FE06700F8DC3F16412F2E7
-:10B5400014F8C987F2C194A2D079419C6306D1E96D
-:10B55000EFED4FC3AFC9CAE89D2453BA8DEC822BDF
-:10B5600085F36FA3F83B4083F6C94517C9FF150261
-:10B570002FDABB4F1FDCC3C8DFB3E25EEE375C518E
-:10B58000CFE81E026B869F8A21BED1F44C02BE50CA
-:10B59000031F3B5A60C541170FB55898BF00EC1008
-:10B5A0008CDBCF19A2638757716288C1C66A571DA9
-:10B5B000A60F4D38D181E2EFE1895FF4618A67041B
-:10B5C00038BEA38905D13EA6B37F18DFB904F23097
-:10B5D0007E8C288FF1F37CAC288F9DCDF3E9DEE7DC
-:10B5E000A46A042CE23C2BDD16373517E5F402C6BD
-:10B5F000EF818B7720B60B7D916A8BABABC6F2DB0C
-:10B6000019DD0BD1CA7F2ACA936D1FB5E7A01E9919
-:10B61000A56FBF45E021C9F651C7243AF7D2976B11
-:10B62000E74A09B6F3C7A87D89BEFC51D1DE6E3B5F
-:10B63000DF3709CB73F5E33F28CAA36D5C1E321FC9
-:10B64000E3EF1588F20744B915CB717C0F2F97B53E
-:10B65000773944BD75020E8CA923BFEB28EE77DD48
-:10B66000D1622921BAB45C24FA3CD4C2287F6B5140
-:10B670001CC909430DC7779C8BF383A3990DFB4E1F
-:10B68000C1AD42AEC5A8FD5EEF30724F2B8F73F097
-:10B69000771864B789F8C96C137243ACC741B921F4
-:10B6A00035793893713FFDE5F81A16DA05B48F3213
-:10B6B000E007F93AED1E03F387C9CB946551CC1F1F
-:10B6C00056DFBD204E974FBC3D4557DF352B5B57AE
-:10B6D0006E2B2FD295B35971B46E960BFE8A2A2920
-:10B6E000D3956BEF43B0DDA29E58BFC6DC6B74F5FB
-:10B6F000CE17AAB1C8E327A782FEA178068F05E579
-:10B70000C3727B7612EA9FA75B2610729E85750531
-:10B71000462B7BC6C9E3DC9FC1F34328FF598B97B7
-:10B72000BEEF817215D25DB0EE54A8DFD5E2A0FC69
-:10B73000E32D6E4AB7B7A894FEB4A590CAB7B47803
-:10B7400028FF18F48FE9A3D00F7E7FA4A586F21BF3
-:10B750005B7C947FB86536E51F6CF153FA40CB12E1
-:10B76000FABEAEA589F26B5B9A29BDBF2540696B15
-:10B770004B3B6F57C4F5CC33E25EED3395FCBE7C9A
-:10B78000241D3B8B841F52C4ADD887E2563A8B30C0
-:10B790006EA5BB9FEC702D6E05E74DFD59F9FC239E
-:10B7A000FB7BAA88DB6F45AC6F55345FCF743E9C42
-:10B7B000D7E3591D0D7C9FDAC4E990D53340E5C924
-:10B7C0004B382D9E12FCC95C01965641510254EF34
-:10B7D000ACD45715CDCFD529CE91B9619E15E2FDD8
-:10B7E0002662BBA001E1522670FDA9D17570DE4E24
-:10B7F0000E27CE7F3878F70B78E5F26EFE2E4B4D94
-:10B800004708D93ECADB44EFB25866FB420AA42E71
-:10B810009F9FDE8928BA38053667206F2E5EC75491
-:10B8200048D396E9F76D290BCA74FB22F9E2434C21
-:10B830000539602BD1EFAFA27297EBDA59D27EA80F
-:10B840002B37B956EBCAE7DD95B5C68DF84CE5E761
-:10B850004BE60DAB5832C0B5B07323C1F59198C714
-:10B860005949A5FBE5817D5ABC05DF5F3C29F40BF6
-:10B87000B36C207BACC0C9B3F9B10103EA874FFFB9
-:10B880003596E4D2138F1B82E84706F164C0F55F5A
-:10B890000C661F9697B27ECA63A80CE6C73255C6DF
-:10B8A000FC383640FB2BD85FBC5F8471ABB2FF71B4
-:10B8B0002BE4CFA4FB9FE4717321D29FF9829EF900
-:10B8C000DA7E6AB312E95FEE2F22FF8DFE7E5D9B6A
-:10B8D000D85FB459B99F6E95B32209EDD6B323C48E
-:10B8E00039DADDAF1E5D00F8B6271FA274D02FA78E
-:10B8F0001A86BD3FFE4504FF8F026617FCFF05F266
-:10B90000FF99F2B713D10DD5903B40EBE0ACE47555
-:10B91000CF45FCBE2E737E841D17CE4F11F855F611
-:10B9200055BAE7021E9537733C013634CE132DC746
-:10B9300073300E41CBE78B38DDBD2DC9B9D561DF42
-:10B94000D5624EC742D65783FAAAB0C4E00962C78F
-:10B950005E87CE8F61CDEDF0E27B084A19F3A098A7
-:10B960001BC53A56A3EE56FE26539C9572F86AA65E
-:10B97000C27EC6660B318C4BD3FA65C21F728F90A4
-:10B980009B5F38AA63E99DCB9441F9873A927D6128
-:10B99000F3F6211F7DD169E4F33AAC2F2FB471BFC8
-:10B9A000E1A242535095F05DB50E7AC751D921B14D
-:10B9B000B42C846312E1811D8C263E8CDE3C9A05FA
-:10B9C00060BD943BFD9662F4DB85D483861CC193F5
-:10B9D00050AFBED8B413EDB302C48B0DF1726B6ED1
-:10B9E000350E9D5B48F85D28E63DBE98D3AB2D3DF6
-:10B9F000021EE6F1E27BA78B3A353F8E7E9E0F96C4
-:10BA0000577D07DF856CED93B95A8BC0E77A63DF0A
-:10BA1000E8B9D0F5997E804B2638C717A30DBAB97F
-:10BA20008205488FF3F9D53F2EB1AD5924976A4866
-:10BA30008F8F37B0F0F3532D9D58CCE5EFB1221E18
-:10BA4000876A771F257E1CCA1F39BA00F0F1B481BE
-:10BA500015D2B9B181EF8FB5781D19FD0078AFA16E
-:10BA600058C845D6C6A6A1DE761A28FE54EE8AA28C
-:10BA70007BB3B253A1B8F7365BB5E34EECC7A1D0A8
-:10BA800039D11479621FDAD166A7611CDAE14776F1
-:10BA9000FEB00FE386E47485A1DFABCDA1703B243B
-:10BAA000CD40F1808AB3DA82E74AF9B6139588CFA0
-:10BAB000435D3FA07722E4EF8B981DE117330A9294
-:10BAC000B5B126EA3F90A688F766BCB56313C59169
-:10BAD000888AFBA19A4F70BF7DC471DE8AFB02D5B4
-:10BAE000B688FC81F715F37DA211CF0F21FFF8CAAC
-:10BAF000F34E945FAF77AD89CB427B3AA8902D523D
-:10BB0000F8D7D6147A0FA1CB44EF356878CD0C283E
-:10BB1000BA73C8F4667DDE1C711E698CB827B75CE9
-:10BB20008C8F2797A1B0F918DD7CFFC65C36DAFF51
-:10BB3000DC572CDEE914F97B447EAF3190E201FC46
-:10BB40001CEE5A9489F3BAF0829FE2CE47B2FF27E7
-:10BB500015AB62BC80D540EF0287AC1887BEBB85B1
-:10BB600079D0CEB30415BA07B047C8B35C1BE7FF62
-:10BB70003B4AF87A8D4C733BF8BA539E890A4623A8
-:10BB8000DD1CDD650158E7C5AF4E652AE8C15C875D
-:10BB9000D780FEF7DC669307EDCF29BFB0119F9CDD
-:10BBA000B7F1382EA5F90115BFB7EEAC2854C3E0A4
-:10BBB0000EB6383C289F76B6583C181B1F1C41BE59
-:10BBC000E6380D143FAF1A783CE72EB11E7715F317
-:10BBD000F788760A39B34B09CC403877013D316E8E
-:10BBE000FFD0066E1F2F5F65213896BF9E43F6D5A6
-:10BBF00048787BA2C5EDC94578361852D05F55B953
-:10BC00002E773DBEDFB1DCCEDF3796638B1EC3AB34
-:10BC100011ECD74686F67C6BCC359EF961F25D8ED1
-:10BC20009D58887C25CB8114F4E7F43C7DE1268C7B
-:10BC3000E705FA6DC57CA8F8839B307E77AF3D9011
-:10BC400082F1BDC78A3FE2E50981AD18DFDB577C91
-:10BC50009297A707520C903F5E7C9A97E705B662D1
-:10BC6000BEBFF82CCFE3D91BC8CE53C5E76F0AA0DF
-:10BC7000BFC5E4598202F9E7007F092CB16E919E9D
-:10BC80001678D1CA9FC3EFB001DB2FD2C8F283A2CE
-:10BC90005DCF08E52F8AF2DE11FA7F45B40B8DD017
-:10BCA000FEB068776484F64745BB632394FF4A94EB
-:10BCB000BF3142FFFF2EDAF58DD0FE6DD1EEDD11E2
-:10BCC000DAFF56B43B3E42F9FBA2FC3F22FAFF40AA
-:10BCD000D4EF17DFB3ED1BDE47FF7D36C811944B61
-:10BCE00085F60D71B8CE77B69713FFB756F0732A65
-:10BCF0008DDFB32546EF0EDF56C2DF3BBBAD84CBF5
-:10BD000071A584F339F0E1C3C877CBDF94299EA8ED
-:10BD1000D5E039154439BADE40F6C0F2D7F97E7D58
-:10BD2000F93A25187E1F486BAFC1BF06E103C66D07
-:10BD3000C314D6DB97C5FC9CD1EC767B6AC3E4992F
-:10BD4000D1A1CF83BC602877417E53DC78E1BAAAC9
-:10BD5000F6C2723CEB339005A2D45B42F88E886247
-:10BD6000177AC151DE5188F0D9147A3F4193F3CC50
-:10BD7000E6D6F935DA6C0ABD2727DB79F9945F4CF2
-:10BD800074A09DD5C6FC7D5E6CEF56C88E3FD45E18
-:10BD9000E640B967B22F70E0FAFDB894E3BDBAA1EE
-:10BDA000300AE5B5FCA081E4F711075FEF3BDC3C0E
-:10BDB000CE0AF40ADDAF0279ED411D51C042AB500D
-:10BDC0006EEE7DE8E05CEEE763F6B115747F493B0B
-:10BDD000579794B07D406D09C74FA6D0230AEA1744
-:10BDE0004877958B7B3701EE8FCA54983B35ECFE34
-:10BDF000706D89CCEF3D69E7A1722DBDAB95B15255
-:10BE0000D19D23A4DDA3CF9B22F48612A15772DA21
-:10BE1000414EEACE4F1CBAFCB74A849FC7C33C6868
-:10BE2000C74EF9C5069287E751BF4923CBBD41F9FB
-:10BE30002BE4F12E4400CAD100BFDF7E6843D9AFA6
-:10BE400090DECBD719E83DEB2B95A30AE218F090D2
-:10BE5000E797482FC0845270DF74393CE4197D7134
-:10BE6000F4DEC765F091F768791CCADB3CBF42FD80
-:10BE70005FA2372E83AF6725CF713FD2D11925EC52
-:10BE80006A6000F4DBC54575E1F9BE49F853B43882
-:10BE9000652549E1EFF58B7BB2B2E0E3FB99578D65
-:10BEA000CBC1F78A9AC8BFBF62DF3D6EB4DBD71A39
-:10BEB000FC0ECC1F8B9B3680E32C874D3FE26F2F0F
-:10BEC000F641EF72BE7D33FA4DBA8326ED5DCD109B
-:10BED000FEB30FE38FB4773BDD64AF897CD5CDD55E
-:10BEE00030DF6EC5518C266847C9E44D46B049F72E
-:10BEF00099D8607DBCEFF7F41183E8EFC64DD520EB
-:10BF000097F64531DDBBA5FBD0CF4EF9E99BF09DFF
-:10BF10005218EF4619F6663B9F99B5C976F5103C65
-:10BF2000BB9FFDEEA655E8B013FB1427E3EFCD9FB2
-:10BF300051FB6390B4B05F595F82FBF5AE1389E1AA
-:10BF4000FB75AD7EACA8DFD03BD0F08C4AF53B4A08
-:10BF5000801FEA7B06624A08DF0315E1F563841F50
-:10BF600020ACFEA6AFAB5FA8C1F3CCDB3797F0FAED
-:10BF7000DBB0FE59B53F91627A22E089BFB4FF9DE4
-:10BF800004FF08FD1789FA67426F53FDB3AC3FB158
-:10BF9000348BDA3D85E39C7BE3ED0A31EF443CC70B
-:10BFA00079D7E6FD197E6FC13E707FA734A9F8BD31
-:10BFB000DBD2E140FBCD6AECF0A11CCEC5F7C72671
-:10BFC0000CA5CFA2F2187FE9F7487EEEB6B0F85A7A
-:10BFD000E4D76603ED6F7AFA0D0F205FEE489BE819
-:10BFE000C0FDF33E535F5909DAAF076C64BF1A32E4
-:10BFF0003FB5A2DFDC5CC0D7BFD5D9E42981BC3511
-:10C00000BD84DE0F95EF5DDE4DEF98DFC7DFF752A1
-:10C010007E6CF2EF46FE0A2D2F5C18B6BE7797F2C3
-:10C020007B96EB5EB36DC0FDC13AA3A7A300ED7094
-:10C03000BB42719FCA8F0F4E23FBF0E70646F21FEB
-:10C04000E65905FDB6CD55E8F7300C94CEEB2B2123
-:10C050007CF87C55502F234191F07ED0FD8ACF8211
-:10C06000E71D6661D7EDF0F0FB61DAB81784FD7962
-:10C07000A184BFB7B623EDC27B8B5DF8FE8389EE4A
-:10C0800075DA961942A618BCE7B6F3D462A46774B1
-:10C09000FF3ABCE71C95A238707E3FAD85323A97D7
-:10C0A000EBA6EF817A03ED1BE29719BCE87F8CCAFF
-:10C0B00035E9FC1D361827DC1F1233DAFF47A4E7E9
-:10C0C000B837951B11CFEEBB0DF43EEA83EE772D0A
-:10C0D000068033A65CDFDE3151DF3EAE5A5FEEAA4A
-:10C0E000D59727CED297BB6F3745F875F4F9268DD3
-:10C0F000AF4026D8404F45F1221665BBD082FB9E4B
-:10C10000B5AF4531A2CFCA4D1D05B83EA307085FA4
-:10C11000514551E417589B6C22B9BEB694FBF50FFC
-:10C12000A79B6EA43CCC0BF96347DA51DA8F5C8293
-:10C1300017DBA9BF62FF3616F61DFDF2A3BD9652AE
-:10C140001E57C3DC15E8C763240F9F95BC9E438828
-:10C15000EFB7B8BF624733F7633F388BC741D20CA4
-:10C160002A70BDF3FA31960D7DB82F8BB1B5DF8DF6
-:10C17000F19D91784D14E70D3BF0762FF29D9FBF16
-:10C180001BBD46BB6785DF2BE8D604BD8B366BB481
-:10C1900078EF4FD809B1EEF892B6B0FB1A89C26FAA
-:10C1A000F2F0C47956D41FFBC43B2283FDA9342886
-:10C1B0000F79457F54A9E6AFE1ED3769E73C229F4F
-:10C1C000E0E4F97D47E26EC4F5B569565C19EEF717
-:10C1D000D70AFB2E36CDE41D05F37AE49829208D8D
-:10C1E00081BCC28E18C12ED817C7C735BD1E15C059
-:10C1F0007B818FB8CBE99E61AD80FBB94ACF3BB85C
-:10C20000DE07601DED84FE1F7179AC65E2DC340051
-:10C21000F051A8159828876ACB68BFFB88D763457B
-:10C22000BDF9489AC78A71DAD664C581716B716E9F
-:10C2300085DE897BC4E277A0FD13078AD484E749B1
-:10C24000E91D53E97E1DE0DA50C18F1A98886FC44A
-:10C25000F8C27881CF1DEE050E7C97C195BBFF5FBC
-:10C26000D04F1F8FFDC5F0768827A7C0D3AC52955D
-:10C27000E07689FEE3173C47F5F1A7AD22AC3F41DC
-:10C2800047D35416C47D9A36BED6CF60FFCC4BE759
-:10C29000006B7EC5F1B62A9DBF8F65BA8BD17EEE4D
-:10C2A000B94AFF5EE4B381E428927729EE942AE448
-:10C2B000A394635B67E0BD8B35BF8AE2E32CE4FCAB
-:10C2C0009EA230CB7538EF04BF03F118B95E938F8F
-:10C2D00074D421536A74895CBFC90A6B97E32E5DDD
-:10C2E000C7C96E5755FEE861D673C47A493E36F029
-:10C2F0007DEC3F725D6F8FFE602CD72361DFE5CB55
-:10C30000E7DBA4FE75248793155A67E911E3E13B47
-:10C310007B98979841C5B8E8DDA54EC1C7A0974A5C
-:10C3200091EF1D936CFCBC9DF8ABEAF90DDFFD3578
-:10C33000E42FE0EFF3815AA9C73AFA482FF6F80B39
-:10C34000B0FE36C5FF38FAD3B71D4FA2F72BCDD1BB
-:10C35000FCFD5153C47B299ABED85DCAFD486AC40E
-:10C36000BB9BDF34ED4E4B2B7678B0BFB77F6B496C
-:10C37000F8C7DB3F6947BA57D9604D3F5372F32680
-:10C38000BCFF6C7D93973F0DF980827859467E976C
-:10C39000C31977D2FC5BDF33933FAB54F66CC63CDA
-:10C3A000FBBD95FC717B0F4C9C8DEBA4D55EA1A2CF
-:10C3B000BD7F40ACE37F1569E4BC6493C78FF64052
-:10C3C000E4F7674B35FF9BE77817D0B7749789DEA2
-:10C3D000711A8C8FE8B2F2785461872E10F26CC11A
-:10C3E000C1F5198718BEC351F75A29B45F60AF4E23
-:10C3F0004478522F4ACC0FF26F9B389F4D753D27E2
-:10C40000A19C49731DA944799FCEFA56A1DC486FBF
-:10C41000D29F97A55E54A8DDBE142FF5873F18075D
-:10C420006A62624DC7F9D92A94F329FCBCC5E48835
-:10C43000E271A1EE6ADD3D6AED7DDBB7851C350159
-:10C440004E8D6590DA147E6F3FA2FEEF443D19FDDC
-:10C45000F6E8FC771C3D4EFDDA944FC3E34D715F67
-:10C460004A426B193FFF043C05701FCA62E3F8792A
-:10C47000A9D7AB86C7DFA682DC359761FC4980E28D
-:10C480004492C5BD082DAE0730E044BF9B16F7B1FE
-:10C4900093E9ED112DD5F6E7B9CD32ED3B8A5FB5C5
-:10C4A000F2FD413B0B5A25F48731923BB91BF8F959
-:10C4B000B4E617BB0D1713EA257C0F97C6EBA63819
-:10C4C0006ACDAE02FA92DC5917F1CE94F68EB661BF
-:10C4D00034E78B6D2D0EA2A3569EE68FA4A3FE9C7F
-:10C4E00053AB977A3195F9E3C3FB0D527FA9CDFB8E
-:10C4F000891F522F6650F9B616F532FD678FD07F2F
-:10C5000032F1CBC8FDA751F9F6D0BBCEE9808A9FA6
-:10C510000EEC77FA54942BA1A99E61F09C7A8F5E61
-:10C520004E8EE9D1CB5D0D2FDB14AFAB0EF0BDED20
-:10C530001E83A78B61FCA9BE5E4DD66F9CFC5D6B14
-:10C54000AD7EC83513EB2FE3F5BF754A5FDF577932
-:10C5500020B23EC177FD457DBD48FA44C20B70252F
-:10C56000DC1406D7248BFEF7DACD9E7B095C09B775
-:10C5700084C175835B5FDFBF6A78B86E2C347F2D12
-:10C580005C5ABDEF4CB8B27A91F39859631E01EF33
-:10C59000BCFE2DB3AFACDFDB967C7DBD3B9A23C7E1
-:10C5A000096871DB3A7B24BE99DBEF0E36407126B9
-:10C5B0009ADD11C71C22FE8BDB0DEFE07F93197B08
-:10C5C00060B46FCEE804C4BFF7F64755BC1FC3F58F
-:10C5D00015ABE5EF56C2BEA434FC5DEE21B8565350
-:10C5E000BF2F61BC13E9598B07EDCEE25466494673
-:10C5F000E3CB1DCCC6F7C7EA476BF29AC79717097A
-:10C60000DC3D9BD2BDDC49EB3C1887F07CD371EF5D
-:10C610001DEDBD67F4F8A1FA23F95B343C994CDDBC
-:10C62000F47B1D06EA6D1ED40FEF6211B4DB75B307
-:10C63000398476B516877A3C7ACED10495DE3D589A
-:10C640008DFDCFBE65EA1ACC4B87E3D5E536BC3706
-:10C65000D5AFDD2F5D83785B66F167261AE87CB580
-:10C6600000F7C3CC172F2E23FB4A878BD3D0E0A92A
-:10C670009638FEA3D2FC0FE338D586BE1D3EFCA63D
-:10C68000F4F17DB62381BFBB84EFEB0CB3FE353CE8
-:10C6900054897E0E193D5F0EC0FC0E6D8CA57BF893
-:10C6A0000BE26F99836FB22C34F812F1003D0CEE5F
-:10C6B000ED04B76D6E6632C26D14705B1204DEBDA0
-:10C6C000B95F07F760BCCC7D92F67E3AE59F0F38E4
-:10C6D000E9BEBBD9F0F9BB33510F971A3C68776EAE
-:10C6E00003FB02DF77FB3F02DFDBF18C258EBED33D
-:10C6F000BB6F6E71EFCBBDC940EFBCF8AA5E203AAC
-:10C70000ED6AB07970DF3E97A9F4EEEA7C710FE62E
-:10C710000F95FFFD723FCCEFA5D1FE83388F3BE232
-:10C720000D19EF121CFE627A476BE295C5CF6AE7DE
-:10C73000F033847DB050E07126F352DCEE4DCC6FC7
-:10C74000C471DF3E6BF2A25DFAB68847BE8505E88C
-:10C75000FBAD2C48E96D2C44F5BF872FCA42FEADD6
-:10C76000E8D1E9CD005FDD630579B81EC3F0FE06B0
-:10C77000D219F8E50E17E7973F2621DE3B13AE8866
-:10C780007FEB248EBF0746FB7FC3D7ABEAF2204C7A
-:10C790008E4969E847195C3FD5099CFF1447DED7ED
-:10C7A000AD9FBEF3DA7D7FAF2DB902DFFBE23F37ED
-:10C7B00078EFA278718CCB77011DFA547ECF11C42B
-:10C7C000863D0074AAA994296E6FED67E27E363A21
-:10C7D00031A0DE2FC7CAF43E99762E395DF4373D7D
-:10C7E0008DDF57ACAD9CD9160B7899F2657F79082F
-:10C7F000D29A34FDFDC5A9AE2E7AD27C5AAEFEFB8C
-:10C800008DAC830E886B4BF471E6D323FC9F87704D
-:10C810006CE0AB8BA345BC64112B0ABF6FF01DD13C
-:10C82000F67CEDE7A673307EC918FF57488FE5DF29
-:10C83000FEC31CDAD729ECCD7130BF867F97C99E25
-:10C84000FCA80566528071D516E60583FF24D8152D
-:10C85000983FD5E2A6F434D801987EDA5248E567CD
-:10C860005B3C949F35C6671903FDCE6BFF4C417D41
-:10C87000B4568BC716706871856B45FCC40AFBF211
-:10C88000E318BFB08202DE192CF68E2908FE9D3D0A
-:10C89000DD473185EF32EE43566C94C8AFB3F08874
-:10C8A0007F0D9279F11BFDD3514C8CFFCD8944DC77
-:10C8B000A7D7A31D0BACBF22CE9B340658C0DBFB11
-:10C8C000E1D178A8FFC7960904DF272D5E82EF4FDC
-:10C8D0002D3594D68FF1A5533DF619BDF3F4ED67D0
-:10C8E0003E54F0F7B34DF64AE4BFBFCECB8241C011
-:10C8F000EB662397EF9B41BEE3FAAC2C9DB1FD1E86
-:10C9000086F2D75F80F3BC296EFEE478F83E7DC2E4
-:10C910005C05EBDDF225E8A0AC213EBC1C5F9F79F5
-:10C920004522FC9C79C549F8D0F0542FE875E660A3
-:10C93000F177F0DDB3578EC9147F7AFEA281E03B18
-:10C940007F3C8AE25323DB2F3F909384F6D89F806D
-:10C950007E78F0B1FC4031F9E3FFF4ECBFA8E1715F
-:10C96000BF7F8AEBBEF03ECAA9FFCBE514D89B2758
-:10C97000B7A21C4B4BA1F77B06E3D5585334EAB161
-:10C980000693585F206730FFA728BE0FAEF8796A7C
-:10C9900015AE171C0FE3BDCCE2F760407F1FFC1003
-:10C9A000FA3BB8D54DEFFD7CBAEFB16C1C7F6FF749
-:10C9B000C2F7B742FF6782FCF7609C61DD675F44A6
-:10C9C00079BADB467ECBB512C085FA744F0AE50B07
-:10C9D0002525AA999C19411E8722A90ABE7FB6EC7B
-:10C9E000B92D29C85F784F1DE3EA5FDA184D72EA66
-:10C9F00025A3E78366EC6F3BEFEFC987EEFDA80741
-:10CA0000D307EBCBEE45393786C7312EF8C9D22292
-:10CA10006C0FFA9A7EDFF3D3CF4B21F48394761E0A
-:10CA20005A8D714C63B67D68488174EC6EA915D33C
-:10CA3000E2F469C7D07F70D71895DA8F7B264BC692
-:10CA4000D8F4A294E0FBD7F3B8119D7E2FE9FCAC9B
-:10CA50000AB7999A9E2F92BA4F77E1BE38E37819B8
-:10CA6000BFDFC5DFAF3ED03BF39DDB18CE032C0804
-:10CA7000847BAE89E22E5830D085743EE32FF4D00B
-:10CA8000BB2ABEC016E4AF33FE44BA5F78D010882C
-:10CA9000C1DFE314F880FFBEA1E777BF1583F1146F
-:10CAA000B1FB8D0C7F2F76FDD88129141F92AED259
-:10CAB0007E3C7DC70D35889F86FD07BAA89F651609
-:10CAC0000FFA63971CF89CEEBDB0A93C0EF5CC7E26
-:10CAD0009E7FA0DA4BEF9D2FE9FA33CFF7F928EFCD
-:10CAE000930359747F623EB7771E13FA8CF58F66F5
-:10CAF000E1EF2169F47A008AB17C73562019DFBD19
-:10CB0000D2F420E8AF8770FDA1DB91DA3B66F27BBF
-:10CB1000F257A8BF4C421F69FD3D66E2EFF4A21830
-:10CB2000C1DF8BB3CDC4F5EE1E9037C82F9ADE85DA
-:10CB30007177E0BA3589FB32A9A064C7C27C521F65
-:10CB40003373F97D85E347DE67D5EC90D9F1AD7499
-:10CB50006FF5D354FFCF701CEDFE2A533CF4AEE0CA
-:10CB6000EF53BD4F8F49E0EF75E01C402FFE02F3FD
-:10CB70000D32D85139617694E5CAF4E2DF52BD072F
-:10CB8000709C2BAD1F2987270AF857D80D8487156D
-:10CB90008F9AC91F3651DC439D78FE7834CA9315AD
-:10CBA0007F2E23B9D2CAD8B0F879B985C779FF1BCF
-:10CBB000FA1120BDF68B7E99F623470CCB8E827E30
-:10CBC0002510C87F38D01A5B4E792F92FBBA2F0CF4
-:10CBD000C3EE17B514E8F52EC9E92FF5FE87EBBFB4
-:10CBE00074D0EFCD64B6B82B9AF7D0FB3EFAF96B50
-:10CBF000EF6CC1FCFA51BFAFF8CC40FCBBE2B332E2
-:10CC0000929BBD57385FABCB7B12E18C9C0FC0FF72
-:10CC100029D22712FE417E1FB832F8BF2F31FA7D8C
-:10CC200043A0AEC8BFDD2BDE31E85D5A42EF691C80
-:10CC3000C4F748506ECEE0F78E7AC5FDE4DE0407F7
-:10CC4000BDF7F19291E703B78AF6E27DC8DE5B5348
-:10CC5000F87B1DE6A65F9762FFAD3C3EAED718A4F9
-:10CC6000DF53FBFF00D94A3097008000000000002E
-:10CC70001F8B080000000000000BE57D7B7CD4C505
-:10CC8000D5F7FCF696DD64936C42C88590B0B91078
-:10CC90008206DCDCB806582041B468038802C6B8B6
-:10CCA0002101426E844BFBC4969AC500A2C51A1E90
-:10CCB00011D1A22E14282ADA50115183CF0A4269C9
-:10CCC000BDA5D5FAD86A692278E59210B40FF6E1CD
-:10CCD0006DDFF99E99C9EE6F49D4F67DFAC7F379F5
-:10CCE000E347C7F9CDFD9C33E79C3967CE6CFB8FDA
-:10CCF00006B9BC4EC68CD6B939A7F3197BCF67F0FD
-:10CD00009AA3196BD1FCB71A0B18F35EB0B0DD69AA
-:10CD10008C6D89F1272FE7F92DCBAEA2FAEF3136D2
-:10CD2000B32D07DFDD49B13C3DF837E3EDA5769E35
-:10CD3000CFE5799EBEA4B1F9543EDB9D14C3F30B3D
-:10CD4000C3A346B36B787E876FF7D6387CCFA67EB9
-:10CD500086185923D54B13FDFCD12CDAFD81F1BF88
-:10CD600024C61E3533AF2D96B1F1AE45C35D858C1B
-:10CD7000796E8C30B16814BA93343E9F47AA86B35B
-:10CD80007B359E6D7D88B178C6E65B19FDA9F150B3
-:10CD9000D13A86B179E2335BB078B7CDC3E733AF30
-:10CDA000DAD6A58DE6EBA8BE2BD2C9C79BE731FA30
-:10CDB000C3A278859B4ADC9DD9A2EEDFD331AE9B1E
-:10CDC000C66555837886A7267F25E3E3BEDC6365C9
-:10CDD000F772B8FC1D7F5302298718638319FBD4AF
-:10CDE00026C6AF6F9BFAC069D51FFFB7DA62DFA80E
-:10CDF00045A33CD5C7F8F8FB87780AD0FFF243D7A4
-:10CE00003D70DA1AA857B5B8248B1902E3868E1341
-:10CE10003A5E0BF0C6C71B063CF2262DBCC000FCD8
-:10CE2000B5D97CC01F33F5FC6129CFB7CCBFCA751B
-:10CE30002FCFCE9C63756B1C0FBD07C27C611ABEE1
-:10CE400087BBB1AE96C3913E03CFDFAE09F8B7689A
-:10CE50008CBE7BF79B7DBBF9B73A8BEF893DBC5D00
-:10CE6000DDCB235D7C6476D0C2FF83F21723447947
-:10CE7000943B6D7D01CA1308BF2F999DD154FE6B61
-:10CE800023A3F2707F560C877753A2678E8BCF7BDC
-:10CE90004818C7BF1DFD8AEF2725FD9DE4DD02BFB1
-:10CEA000DEC648EA97C9BCE787837CF7D27ADC49BB
-:10CEB0008B915F7535ADC78379F079B1068DD67BDF
-:10CEC000D2E1BB278B979F6C1F4CF38893F470B211
-:10CED000F42F6F8CE5F54E1E32BAD0E7074D46BFF2
-:10CEE000250AE5021FDA1C6BD636DEEED48B91AE36
-:10CEF000305E5E767FEDEBF85E7657FD2C4A6BD6A2
-:10CF0000DCC878FDCEBBDE4FF5E45C898FB23ADE3B
-:10CF10002A088F77BADCF5C0EF232E4F23D6BB3C0F
-:10CF2000A77309E37475DED2F1183332F6EE50CFF1
-:10CF30002A7CEF7EE1933DF8CEF194553A8A2FC3D7
-:10CF4000C4E904F4DB399AE87AB9A4DFF45CCF1DB4
-:10CF5000E88FC3B19C65301691D361C13CD89AC1AA
-:10CF6000DF8A4E3E6FDF7D50E3E3D486B737506AE9
-:10CF7000F48D463F67347F94964170F460FF9D7551
-:10CF8000F8A3800F8F81E7397E6AF7EAD7853F13D0
-:10CF90009F572DFE87B7AB6D33BA6DD83FCC67C1B5
-:10CFA000FC6B9925503F4DEC43D001EF6727ED57BF
-:10CFB000FB07E53FE478A8796264DEBD1C3FB5312C
-:10CFC000877E3291EAF1766ABF18AFCCABF55C3957
-:10CFD0001FB1BEB3721F9CE55FCCA09F7D6182FE36
-:10CFE00099A08FF34F2449FA11747BFE89113ECC2E
-:10CFF000275EEE9BF39AD7108E763F62AEDD7C5EA5
-:10D00000CCD53666F628CCBE6DCC9C48C6B64ABE9A
-:10D01000563BA86D0CF895E25FCCDA367A362F676E
-:10D02000D96DA3E78C0AF03F56DA9645DF7D6D593E
-:10D03000687FD0C0AA014F359F9AA79277103CAC69
-:10D0400062BFD63C7535C1478DD3023E027E0C7E51
-:10D050001175E5BA5F766962FF478E49005F1B086C
-:10D06000FFD9898372C04ACE2FB0DCEEE6FD8ED8A0
-:10D0700066D1F5A3EA8DF4E9BFFF0AFD737A1B16AA
-:10D0800082CF21C69E57C2F87CD9CF389CD895E371
-:10D09000BD29DB3DF9641FFE8C029F8C3915DD38FC
-:10D0A000094E024F7FB0283CAD4EE6FCBA1630491F
-:10D0B0000FC0EB60AE271972E53CF29037313CCFE0
-:10D0C000D306097F9557700FA5BFBBFEB024B99357
-:10D0D000B7FF6F9781E6150AD7B51C7E286F31B36D
-:10D0E000DB4B79FBCF9B4F649C3607D6F371B3DBE8
-:10D0F000CD454D5F7EC9B65C2BF6DDD2EDB9D64588
-:10D1000041706FD99B7FC2C9F17A76AF0923B116FE
-:10D1100093EF2713E2F0DDD8E665546E75F3FA67F6
-:10D12000ED47DE44BD25DB63F28CCE40FBA5DB4A38
-:10D13000DC5541F0BF7AAF1E1FA3DAF4F96B0EE99C
-:10D14000F3E65C46F4F08FB6CBF5EBF3F927F4F990
-:10D150004FDE597D33B6C1F3E3C4BEF9D417E9B34A
-:10D1600072B856BF3FE304E4E8A7079F8F02BE6A88
-:10D17000FF54753C99611D7A3AE578D44C7CBDDE4C
-:10D180003D1AD1CB325FE8FE957CE38A7DBD96F0F7
-:10D19000859D154C37A1F83DC3DA6E7673FAAA6BFC
-:10D1A0007A3B037A4CF52C4EC890DF6D9B2DCC7EDC
-:10D1B000E57803F10F66773B19A7BF8A71A26C422D
-:10D1C000D374768AF7C736FD7606F66BC58F35D2EF
-:10D1D000372A9E1DF12AE8A66BFF82EB29BD79262E
-:10D1E000C1A192B92DE0874BDB357F24CF3BC639F7
-:10D1F0000F75F2768B7D9A0BF35EB42E2CC0CFF8B0
-:10D20000BF559B42E6B125A89CCF7FE9A157BED26E
-:10D2100078FFD5DBF5ED967178417ED4ECFA7B583A
-:10D22000F077AE0811BC26B4EF3062DD8BE5FC95DB
-:10D23000FC63DEC90CEB9B209AB0D3F80F971B96CA
-:10D24000619EE2DCC2801C9CB045B4E78CAF02EB6F
-:10D25000AEB75B9C5877BD95F923F87C4E445ADCF9
-:10D260000EFEFDE2B648D21F968431AF358F52666E
-:10D27000CB433B5734DA7DFC9691F4A47ACE7BA85D
-:10D280009FC7355F0BFA316A22FF33915FC6FCB44A
-:10D290001ED08D3B789D3E7D9EB50E22BDA4CEE472
-:10D2A0007F0570A9619D046FC6F1E95670E470AB0B
-:10D2B000E3EB7C2F16FA97BEFD72D646F5971FFA60
-:10D2C0007B58F077AE67322BAFBF3D9CA7347F1FF2
-:10D2D000C1D168616E039FA7F1CE709F97F490D281
-:10D2E00070D0A959EACB5BEE716761DEEB357796BA
-:10D2F000037C6CB3CD053EB6708790435B62B8FE8D
-:10D300001A477A33B55F087D0A7ACA02C1EFB6C4FC
-:10D31000B4F9C1F7B73C9826F4A9BF19092E3DF717
-:10D32000D97C3B35E8D342EFD9B27904B507BF24A5
-:10D330007DEABE48D17EB680EB96C10E9F97E7FF8F
-:10D3400088292641CF766759A91DD7D3D202724AC0
-:10D35000E9D33F1BE6B90BF856EB55FA37ABFE762F
-:10D36000FAE66E293F7B36F379F2FE4F6BA5C70DC7
-:10D3700041FAF003B982FF8F99E6DE23EBB950AF93
-:10D38000CA30FBDE297CBE555B0DCE96B400DC991D
-:10D39000DB9D05389FDE6CCB039D8D99C6E83C7103
-:10D3A0003257F0F38802E6F6F174BBEC777BAE41BE
-:10D3B00097268673FAE3FD9C2EF19B81DFC882528B
-:10D3C0000BE42197E1C4CF43D7B13757C8CD2A4BDF
-:10D3D000E96F26F5339F3E3A28167ACBE915DA4EE7
-:10D3E000312F81E731FF6E73B5D0BAC5FC14DC393B
-:10D3F000DD1492BC977C2BA68F4E7C4FD8386A37B1
-:10D400002B7D1AF8D7747442F0DC72DF28C2E34235
-:10D410008967769F4DD209637F45798993CABFE9B1
-:10D42000BCA5D6C9E980CA39BEFDC077E8794BE111
-:10D430009B997C85A59103E37BD1B898311A077538
-:10D44000B28979C3385C20F3082EF7987C77F1F91C
-:10D450000C3509F8A798047D71EEEC0DCFA3FA6E98
-:10D460000BCF573CB094B979FD8A64E6D2447D165F
-:10D470008DFABC1B234F2133D0AE225AF45B91C0EE
-:10D480007C7749BD1FFC2A13693AF5EB36C48AF64E
-:10D490005179D4DE6B10EDDD269E0ECB10FBA56717
-:10D4A0007D18ED9F8ABB53B24007B3A6E9E9203F40
-:10D4B0004FD08D4A1FCF734A39E34AC4FE5EB46E23
-:10D4C00024C98D165B69FD73C0D7D311A40F566CA8
-:10D4D000B8ED8642CCEF9941D070D8E737EE1F0304
-:10D4E0007A5BB46EC1F77E8FF3C85E1B7D6FCFF39E
-:10D4F0009CCF85BEAD39CB9FE31F16CD3B6A49E477
-:10D50000ED3D6DB3CFBDC8D31BBDFBDF845E70E3C3
-:10D510004D46AA7F236BFBCB1FC117D689716EF0D6
-:10D520005E3025F2FE6E28D218CABB6C8ED4157CF4
-:10D53000FE15127F7F95FBA0C5C6E6FFD28E79A5AA
-:10D5400064A5F3EF374053ED470F1C9727F5C4A9A7
-:10D55000DA76E83DC3A68BFDA5EAA31FF43B19F0DC
-:10D56000E0F5CC122E2ACFE14AF5AB36867565443C
-:10D570002135FB47F07471C1345B1EAF372B9DCD55
-:10D58000C0B9A9E70E23DB49F3EDA9A07D1F99E5FA
-:10D59000C4BEF730E627BEE71B4974DF35B5A7EBFD
-:10D5A0006E9EEFDA31C2D5427C5D9CDF173B18C915
-:10D5B000F7AEA982AF29FE72D2D11949F42ACFF36E
-:10D5C0009592343E6A9ABE752CAF5F69B774411E5E
-:10D5D0002C7E706E9493CFB3720B3FCF7339C636E7
-:10D5E000E9CFF3FCBC9D9137F8CA7379E8F91B3495
-:10D5F000033AAADAA4111D0E6B715992888F690E35
-:10D60000ACAFCAEECF84FCAB72D95C283FDBEC7EBA
-:10D61000E034D70FCF37CFA4945DE670E7F3BC0AB0
-:10D62000C8E3FB7E6CBEC7053855B456D0793222AC
-:10D63000C743FC69B9A4BB591CCC1AF88DA933099E
-:10D64000FBB02B577E8F7564D9899E6D0C70E832C4
-:10D650003BB230AFAEF53603E4E6ACBB045DF37D20
-:10D660006635F1F6F7985838F6FBDFD09EAFB36C0D
-:10D67000ADA97407CF0FB53253642CE82A97E8FAA6
-:10D68000E7051E33E0F0E98FD838E805959B36D3DF
-:10D690007C145D305347F120E879BBD3F270BE565D
-:10D6A00074F4F38269D7E605D3C34D1AD1014F5FF5
-:10D6B000C9207A98338BE8619A3F73259F5789B1C7
-:10D6C0008EB961674864AE303EFF5ED643FA442FA0
-:10D6D000D72720CF143F517C83D381DB1A1FC0EFA3
-:10D6E0009E663E15CE93F7365B297DB2D9C14C1CA0
-:10D6F000BEFB9A1329FF4CB393D2B6E66CFAFECB6D
-:10D700006617E50F348FA3FCC16637E50F35CFA44C
-:10D71000F4C5E652FAAEF812870BF121C557143F53
-:10D7200052F4A4F852281D953BB137A83DF13DC5F0
-:10D73000EFB00E435E801F29FCA66BA5DEC434F05B
-:10D74000B1CE05E01725C6B34F3FCFE1DB5B6D7768
-:10D7500085390117C1F77AED5692F3A9167608E7D5
-:10D76000FF9615EEAEBB83E4EAADD51A3305D1EDD5
-:10D770006D8D36660AA2DBDB9B6274F9B2A6B78FA9
-:10D7800025F0FEFF9EE2F1022F27EFFCF8D1FFE427
-:10D79000DF1FBFF3F3E1C0379FC7EE8730EE9AF08B
-:10D7A000BE79C422BFCE4C726658B838270D0B170D
-:10D7B000E724FC013F8B98D8A78FDFF957DAE75DA4
-:10D7C0004D614E23F40FE08BC3F70389AF454D61E4
-:10D7D00004C78AF5A79E7E1EFB7D8D85F8DDA275A8
-:10D7E000727F6EE4700DD2DB3E4C62A49F696EC600
-:10D7F0009A38FC3EFC91C5CF653FFB50B3FA34DE4E
-:10D8000050E387A632FEDDB3F157EF41DFD69A4EE3
-:10D81000907EECB1DAFD46CCCF6B3E1BDC9FD6741C
-:10D820009CEAB1CEA1311F47D0566480634481DBAE
-:10D83000023E01DA06FE16651F61D8DFAC55730C97
-:10D84000E7EBAA92DFAB366AA47728F83F9167A48A
-:10D850007D753AD744789D863D3B981818C929456F
-:10D86000B79C6FB87DD81FADB9962541FC7891FC67
-:10D870005E996DA0547D3FCDB725FA9986CDC5FB45
-:10D88000BD373BDDB298F89DD3027EA0EA2FCACE09
-:10D89000DB905E807EA6C6B1A07DF95C9E49CECBB2
-:10D8A00021E49895CB31DEAE6E0079A0F4934FF170
-:10D8B000BFE369FE74FEAA79E6A9675E845DE2FDB6
-:10D8C00030C253CD35D2BE91E31B3397F41AB75D06
-:10D8D000E3EB6C90F82F7EEA4F519DBC7CF901611F
-:10D8E0003FE56917D28635D5642F6B70F17D827D57
-:10D8F00070C8FC6167105DBEFACCFB519D74BEF030
-:10D90000261B1291FA93194F1B0E9C9AC1D01FEB44
-:10D91000D9E0B05FD96EB97699CE996A1D2587BFD7
-:10D920008CA7F1B54BF154FFF0FAF8FEEC20CB993F
-:10D93000E9C3BEFD4B7606B7CEAEB69C6DBA60E4C9
-:10D94000F35DBE66E627A0F3D0FA9FE445C6817E6C
-:10D95000D8583696EC18266600BE575A051C7A7DB4
-:10D96000C3A3D9D7D85F966FE38DB8AAD56B72469B
-:10D97000BBF87CBB613FEFA77E4EBE90EBE7F83E65
-:10D9800062FC2CD5BDCF48E785EE7D9144FF0DFBB1
-:10D990001E383E91E71B76691896D5B30E8253C3A5
-:10D9A0000123B306CB33D877060D3CCFDAA7221B71
-:10D9B000414FCBDA34F76E3E9F5EAB337A70D07C4A
-:10D9C0006CF9829E6AC3DAC6105CE5FCFF2EF999F9
-:10D9D000AAB7ACFD010BF0C5EB9D27FDE517118C37
-:10D9E000EC66ACE74DCCF3CCF67C17EC7BCBDAF6EF
-:10D9F0003790FCDF17E118CED7F1B9B4F3AB7E0650
-:10DA0000E78BFD34385FE81D67A43DF7CC3346E271
-:10DA1000439827F6E1E7D07383E6992CE7999C2F8A
-:10DA2000F49B23D88F8581FACBDABAA23279FD4FE5
-:10DA30000EBD4DE97039CE327BC768C8CD4F0E445C
-:10DA4000CCF451FAD3192FF1F1CEB54D8DD382F626
-:10DA5000555EBE99FA3DB7DD3813F062BE4152CF34
-:10DA60006FA3F59CD997ACD1F916F0E67AFE99032D
-:10DA7000CF461968DF7A453B89478355D869C36229
-:10DA80009C52CFB4B642DF58C8B5BB68CEEFEA0FA0
-:10DA90005C20F91BFA5DD5A7FD9684F3770FD93585
-:10DAA000F89F01F45BEF10382F31E624601F945F7C
-:10DAB000E3BCE556F0B1D7CC020F439D0FE15C55B6
-:10DAC000FED620B25BAC343B1390FFE2757E10E4CF
-:10DAD000F32ECF97FB3BB1B31076CEAE3421D7EB0C
-:10DAE00036F2830A5FCF108E772F5F729DCFC83CCE
-:10DAF000F9013FD1FCFC745ADF23D506B785FC2C15
-:10DB0000FE2CD83D4F5A9897FC46BFB4097F40BAC7
-:10DB1000B0EB3F22FD4575B1FEAC41B07F493CD62C
-:10DB2000CDE1E541F8ACDBE9CF82FE72D622EC7C98
-:10DB3000287720CD13F55A24DDA01FF4DB95E638B5
-:10DB40004F7AE673910CFABEE1F9486157F8B96D66
-:10DB5000675890DCAC9674C575262FD6EFDD2DE6A0
-:10DB60008779417F5E6669CD827EA9C65D16D54AFA
-:10DB7000E39D95E32D0B6F15FE098BB047A23E8DFB
-:10DB80006F66E447E979228CF4D4CF933A0E62FCB5
-:10DB9000CF9F18C920C7BBD27C4B0E5139D7DF3875
-:10DBA0003E6A9E0CF363BE9F3D11E963BCFE67664F
-:10DBB000A10F7D16194FFAD089C8ADE5E497D915A4
-:10DBC000A6C1AEF299C62C8928DF2DFC1835CD4DA3
-:10DBD000E47FA8E1DB9DE5513A93C5A27C24D95BA3
-:10DBE0003EFB35DFA71A7DDF88EF1ED65AFE03EC19
-:10DBF000BBBD116477FBFCC9FF1ED99FDFA26697EE
-:10DC0000DEBEA4E84095DF23F9D23D128EF7E53B56
-:10DC100008FFF5116D5BD3699D62BF723CD0B98B73
-:10DC2000EF8F78D8BB4FB6BD10AFD901677FD64F05
-:10DC300001F7BDE27CF3F93E33F95D6A9E8F749380
-:10DC40001DE7EEB106C88B1AA3D0836B0C1C7C3C7D
-:10DC5000D5EEDC9B053DBBE5095B1EE0C1E14DE770
-:10DC6000C89EDD46398E18F7B33D29C2AEEF97F94D
-:10DC700083A3C8AE3F2B96DD3E87F49CEDA301D76E
-:10DC80008BBB220CA00B3E8E5BE3F0A9F9C10F0504
-:10DC90003CA397905ECEF71FF1CB3AC92FEBEF9ED6
-:10DCA000183D11FBE92D23835E70D1E44A003F0C3F
-:10DCB00085D70792AFD41E7CD402BF5D1DDF371E0F
-:10DCC000BE6F6AA57FACF6498DF4BADA0D131F2238
-:10DCD0003EF8A6990DE7F338DBF64054303E8E4B04
-:10DCE0007E1668EFA2FAB5BCBE68FF5A14CD678FE6
-:10DCF000D985F984E2F15BB77FD2F8ADDAF7D14785
-:10DD00001B97EBA3AF5CF745D6F1FDF7C14FF6D9F2
-:10DD1000C87EC5F19E0ABDE38CB96D09D67DE66962
-:10DD20001BF199333162BF7FC2F9A17704E6F19DFF
-:10DD3000FBC9BEF1BBB90CF260A94FDFAF1AF735D2
-:10DD4000C97FEB07B9A26127ABE778407F1C2FDFC3
-:10DD5000A5F66F99A97DE83A9E44BBC2A0FDF9746F
-:10DD600004D1CB9921021F679E194172A52B46D081
-:10DD7000399F6F2ACE2B676244CAA08C703AA89153
-:10DD8000E7D13353DBE8FC7D46DB4F699759B4ABF1
-:10DD900069927E634E7789A01BD024FC61D64D1D0D
-:10DDA000D02760AF1E9347A93F2CF64ABB33E81338
-:10DDB0007228A340C82F86F1E2A5FF83F494360BA6
-:10DDC000F8B247EA7175FBAEF4C301BF75FB34F2DC
-:10DDD0002319543F7CD671CA5ECEE9B1D6ABB96D7A
-:10DDE00098CFBA15CBC88FD4B8F956D0BB5A47AD27
-:10DDF00089CDC479A84B33D27CBA6C7CDF000EC1CC
-:10DE0000E305E95D91817198239EF44C52AE630A5B
-:10DE100084BC42BE95F757B74EDB44E3A4A973A573
-:10DE2000589F8213078B05F6327EDE17E503AC5F41
-:10DE3000CD3374FD6A3EC30B849DA22BCD797F1137
-:10DE4000F0FD86D18573FAC5CBF9D1B15FA397E117
-:10DE5000E4D66737E6F3CF034DF1F97F29F95B2D5F
-:10DE6000ECD27C9E59DBF5FE90EC5DFAFC55FBF4A0
-:10DE7000F99C03FAFCE8767DDEF5AA3E3F448EABC2
-:10DE8000E08473AF738438F722C5B9D71926CEBDA5
-:10DE9000C8E3DC8B14E75E7CC7B917799C7B91C71C
-:10DEA000B917799C7B91E2DC8BEF9505827FD7498E
-:10DEB000BB23F000BF0C7BC1A6FCECB45FBA17C457
-:10DEC00013FF547ED2EE653994EFB3EBCCB6925D7E
-:10DED000876C375C2F993BD473434121FCA71D1BF2
-:10DEE0009280375327D97397BF28ECB97579363BA1
-:10DEF000EC0C9DEB3FD900F5296BA8670EEA779BE8
-:10DF00007BF6101D98FCC4373AD73ADF9A22F047C7
-:10DF1000F60E668FA5F34905E45DECC0780CF5AB11
-:10DF2000B04D7A3F4AA85F25D49F124A07CA8FF2A4
-:10DF3000B8B92709FCFED413D64D98FF2969276389
-:10DF4000F3ADA47F29BDBAC4682738ADBC4FDB0947
-:10DF500039B5AA2096DAF79EE0FA763FF256A595F3
-:10DF600097F2855EADF29B3403F9693C6E9243AB48
-:10DF7000E49C52B59EAEBB4123910692E317ED0699
-:10DF80003A175C7CC7487AC4886D06DD7A46FAC2C7
-:10DF900075F475F5DED8107FE0105DFD6B0EA5877A
-:10DFA000F803AFD2FBA96E5AFB0ACED77337E5EB65
-:10DFB000EA55954E0C81A39CB7D44B5BD66C4B05B0
-:10DFC000FF5915D94BF35FF59C8DEE5D5471F9E265
-:10DFD000E6EBAE4686F3C76AABFB46C0AFBACD1CD4
-:10DFE00003BB56A5943FAC492F8FAB4DCCEB880DAE
-:10DFF000D05DB583B96378FB73B9AD7B0C1C6FE75B
-:10E000000CDBB71639E15FDA91EAE074B55A6B8B35
-:10E010001FCFFB3B15E3D951C0F773AAD9FF933249
-:10E02000F0CBFD196C2DAF776AD3B351A4774B3A7F
-:10E030004B353BC281EF1DAD463A17C03E057B9084
-:10E04000A2871DAD83C233ED817506F07F99D6C7D7
-:10E05000F142F7467AED4786AE821ED726D65B3D63
-:10E0600055F3929E2CD7B352CA15B64EF4B35AE666
-:10E070004FCBF3825ADFD991AF8C76C2AFD97C28CF
-:10E08000D5083E6ED8B72709FA4582A71DFBA77AA7
-:10E09000C7F0FF2CE2E3D6FCDEC8E047FE68CBF415
-:10E0A000A8F1D03F9F36BB66F1FCDDAD3FB3E05C2D
-:10E0B0005063F25970EEAC7E628705FEFF6BF7EE9F
-:10E0C000A0EF4BF656D0797B296BA473E4A76621A9
-:10E0D000A7153CAAA769DB1D7CDE998582BF568700
-:10E0E0008BFB2025C6A2637158EF5E2D17EBBDA9EF
-:10E0F00074BFA5827F7F57F2E1D0FDD1FBFADC929D
-:10E10000C1B02BB5093FE840FB619E7F24ED87B984
-:10E1100097D228BDE9D2D574AEFA3D2B1D457C229D
-:10E1200027E43CFBBA51D8CDDAC53EA8B6F8E3E601
-:10E13000629FBC6CA67D526F82ED1BE764C626F021
-:10E14000B4B4C8A8A3D7E5C5113A7A9ECF62757E4C
-:10E15000E59BD9105DFEA65919BAFAB7DC747508AB
-:10E16000FDE705CA898F4CD0DD5FA95FE3756A645E
-:10E17000479BA6FFCED3354467D7EBDAD7B33981B7
-:10E180007A3807EFFA2DC199B10E0BCE5BD5067127
-:10E190005F67BEA74B7EEFA4EF7C21BA7D382CC30E
-:10E1A000F59F422E9AC93EAFECD3F3F1FF19FDC99A
-:10E1B000458E68396EB451D8173C7ABDA383CE9F83
-:10E1C0004CE0A15EDA7BEAB385BDA7DEDB6169B412
-:10E1D00013FC4DC91C240DAD1AD9F3787D6B72ACBC
-:10E1E000C8AFC1F703E6809D8589FE2EA1FC84B1EE
-:10E1F00002FB25B4BC81AF1B7A4603EC3564679AF9
-:10E20000F909D999D438B27F45A74BB7E9ED470D45
-:10E21000B0EB04E17359A193E8B566EFFEE3433830
-:10E220007CE696C6E4621FD5B5CD3657E45C496FEF
-:10E230008ACF5FAC3690DFBBF7F5A3446FBDD52620
-:10E24000A2EB6F824B835BD83543E970095F9795EA
-:10E250008FBFE480E6F269A21EE03304F419029F46
-:10E26000E47EE0A6E0D507BF90F2A5F89F02DC2788
-:10E27000D07CFEB4FEE012024F354E08BCD8383DCB
-:10E280003C96789C6F81FF2C396164BE6FB1FEA50E
-:10E290005827E6C1D78979CCB924EC26CA9F70F3F8
-:10E2A0002513E5FBE8A694C32B0FFB4EBF4FFBE8FD
-:10E2B000A854EC9B7997E2A9DDBF8A9EBE898ED4D3
-:10E2C000FC15DF0EECA3BB486E2C2F8C8CFB98B397
-:10E2D0000AFEFF85C417247F1D582FF50A3EEAD198
-:10E2E000CB9961778EA37B47BDF674D22BFAE4906D
-:10E2F000435FBE32323D01E51E69B753FCD823EBC4
-:10E30000A9712A78B97310E87A683CECB11BD6651C
-:10E31000A47606E92B9EF5E678D80B53D70EA2B467
-:10E32000C2E688871CA9586B2C857CFCF09E84F87B
-:10E3300071B0CFAF37C7CDE25D7F7847412A1B85EB
-:10E340007C09A5A73687CD0FB673AB745BA1D0430C
-:10E35000EBEF7C8FE4DA39C3EB51F3B1EFD63F1723
-:10E3600085AB37B5EBDF1EE3E02AC9DD319E870AB6
-:10E37000C98FBA638F037073EC180D3BF5CF6143FF
-:10E380001B1CD01F6AD69724C02E56F7B7A38F4107
-:10E39000EE7BD69AE3A17F7EF60E978B1AC935D213
-:10E3A0001B3EB5313A2F7DBA3BC207FFFDA71A735A
-:10E3B000C3BFB3CCF8CA68874ECEB6DF8C79EC4DBC
-:10E3C000F0FCBCB010E3FBF624627C9797EE677A12
-:10E3D000D60E8FEECF8EA2D2E5DB845EB747D97121
-:10E3E000A5BD17FA3CF2D0E7D908A1CF230F7D1EB7
-:10E3F00029F4797C3F26EDF8C35A7A72711EF54EE6
-:10E4000063D98D2477EDD9D0D75769E12ED2333532
-:10E410005702EC63EC9D18216F43F0ABD2493D5C91
-:10E42000E70AA2FB2997AC2CF89ED95416A3CB4F30
-:10E43000B726E9EA9738D274E5D7268ED4955FE7F8
-:10E44000CCD5E5BF933D5E57FF06D7545DFEBBE3D9
-:10E45000AED3D59FED9EADCBCF9DB940577F5E69C2
-:10E4600085AEFC96F9CB74E50B3C2B74F95BABEFF6
-:10E47000D0D5BFAD71ADAEDCCD1C26C8BD769CB38A
-:10E4800038DC5FC6398BA7ABDE186E0FC66BD17454
-:10E4900043637F76FAF3521F9A38D6FD19E823C5F5
-:10E4A00020E890A76EA81097A55C49667E4D9C73E6
-:10E4B0003B924037A1F542CB8B228E5C74721C2EAE
-:10E4C00039187BAB89F391A2B147F23378FE9931C9
-:10E4D0000B447EE29167D379FEE0C1ADB79A38FF75
-:10E4E00028BAE6C845948F1E5B2EF27319A91C4703
-:10E4F000C6FC6DA197AFA3684AFA2697B093F47B48
-:10E500004F53A58003EE37020E48FD9C3E911EE15D
-:10E51000F489F4554E9F5566C68E73FA447A829FED
-:10E5200037F1FD37FCBC89F4757EDE44FA263F6F77
-:10E5300022EDE0E74DA4BF6B9E4FE93BCD1E6AF78D
-:10E540006E7335A5EF3537D2F73F363751FA41B301
-:10E5500097BE278E5176053FD95F949FA901FE3D56
-:10E56000D8E70E99CF06FB61959F50F9055B1A59C4
-:10E570006704F669A729E6636BC0DF37309F35B1C2
-:10E580008F83F4B0CD89EE8C3134FE5007F97BE4F3
-:10E59000F769DADC14B8FE6E1DED193986E37B5E8F
-:10E5A0005EE5FA68CE3FA65C6E34835E7E2FEFA9EF
-:10E5B00086F67F59D249DC58F768B49B6C15F7F0A2
-:10E5C000265BC53DBBC9A6CE16F0A3962F9913F7BF
-:10E5D000685E89B4107F6AB9C7E4839D52FB82519B
-:10E5E0007E521CA37CCB971D742F6FB2C39548F24B
-:10E5F00046E6FBFCE7F80BBA2FA3FCD9EA9E4CF1E8
-:10E60000179DD3A1074CB25B9C6121FE77F8AD5FEB
-:10E61000897C57CD87613CE527DFF525F31B46074D
-:10E62000FCE193AD1D69B0134C5A6D7505DFFF51C8
-:10E630007E6FED8B0E23E489BAE7A3C651F38D34C8
-:10E64000F1FEF202F778263BDA7271AFA1A5DE4E39
-:10E65000FD25F0EF963CAAE73652BBB65CD8812781
-:10E66000D5D95DB06F2B7F7B825C37AF47EB2CFE3B
-:10E67000C243F70D26C9FB06E8C72ACABDE86752A0
-:10E680009C3FC984F5375A5CB0873EAAF1F6790100
-:10E69000FF3FEA4704ED5FCC13FD66FE85CF177A96
-:10E6A000BBDB4DF09DABCE6F4E9997F29959A79178
-:10E6B000FDCA28F3BF1DED590EBC978639FE1441E3
-:10E6C000FB3C2305768ED9526FFF1A7A59FD3F43E2
-:10E6D0002F6E81EFA18CEC69A174A3F0A2F03C1025
-:10E6E0001D29BC07DDD7223CF7DDBF92FD84D2D7C0
-:10E6F0004074A5E869B255E01D78C53D1A4547DA72
-:10E70000176D3B681D755692738A8E42E9E04A3A4E
-:10E710001274D9F23D2BF577251D05F00F78FCF327
-:10E7200074D46184DCFD47E9E7F61E36239A17DDD1
-:10E730007B8DE732E446C525E771E42BD9D4192057
-:10E740002955FE00CA075F591E4A5FAAFE8B03F4D3
-:10E75000E7F9A2C71C1D449793A40CFCC300F55F06
-:10E7600093F7E25FB3A9FB1E6E7B2EA783E9920F9E
-:10E77000AF2A11F43533CD48FE8CE9394B49BF67D8
-:10E7800076A11F3BF93F646F93FEF5EB65BB1997CC
-:10E790004BD7619C19717AFDFB7AA977CF0CF1B741
-:10E7A0005F9F732DE9E1D787E8D9EF8D917A741ACD
-:10E7B0004B13E7EB4DA4FF16CBFD982CF19DE134F4
-:10E7C000B2220EF712E6314108BC7ADEE2467FD76C
-:10E7D000322FE5AF633E4ABFC3FCA407DCC0050689
-:10E7E000F2DF658CEE8F1E8DB8B16C39EF6F7AFE5B
-:10E7F000F44C7CAFB3F6A45A0CB81DE8F90CF2A1A6
-:10E80000C1E8F933F4CC73299E11381F1F29769281
-:10E810001E76C49A417A21F69339C85EF96B2E4769
-:10E8200033B99C3BCAE52CD2635CCE667279F72B78
-:10E830002E6791BF3E7B2D43BB194EFDFD1ED5FEBD
-:10E840003B8EE9CC34686039F69DD12F0C851DEBE9
-:10E85000B59811C5C0DB6B31638BB1DED762120C8A
-:10E86000220DB3503AEAF9CCFEF45645AF81F16679
-:10E87000D078A1F055F00C85A382EF3F01CF416322
-:10E880000BAF84E765E8F7B09F5ADF8E4A4C879F4D
-:10E8900051C6D345083E58FFFCA804ACA3CE2AE0DD
-:10E8A00032A96922A5939BC633533EF999BC80EFE8
-:10E8B0006758020CCE217636669A46F9EF49DACAD5
-:10E8C0004EF00CC73CCEE6F9B3B846C63ED9DE12D0
-:10E8D00085FB99E79E31BA70AEA9333A37B9602704
-:10E8E0007FCD28E2822E1F4D857F93EDEAFFBE7417
-:10E8F0009D55C1CF4B70FDD9356EDA6F0CDED9F85E
-:10E90000805E33344CDC3326F742DEC07ACE98701A
-:10E91000C167868609FEA8F0C5DB09B9CBFB19C320
-:10E92000F95AF2FDE174AE2918E62EC27AF879811F
-:10E93000E28A7AB323C85EF11B199738D97F35C5AF
-:10E94000E5CDC4B99D7F378647EDC4BEFF8D8C4BA6
-:10E95000FCC520CFB5687F6D5A5E22E0318509BFC6
-:10E96000CA7556B3CBCFE774DD58B90F47B3D13270
-:10E97000AE4777FE507692DE3823C9A1C92CEB2131
-:10E98000D8098A4F98C94ED077DF2D51F8457B4F73
-:10E990005C3482AF94446A6C505A203E272CD1C01C
-:10E9A0009C417ABBCD19CE9C41FB23223B56978FCD
-:10E9B000740DD1D58F1E97AE2B8F715FA52B1F3491
-:10E9C000334F971F5C3A41573F61FE345D3EC97338
-:10E9D000BDAE7E72F51C5D5EF1BD64F189A5342E7D
-:10E9E000D4B51FD6B448573FCD5BA32B5778605E94
-:10E9F0007747763CF8A2F8CBD8B85257EFA7512208
-:10EA0000DE64A67DC92CECF7E1AD3FD0CFCBF8BAE0
-:10EA100046F1A34EC16FBDFC1FD05149A29EFF4ECF
-:10EA200077E8ED1AC98D265D7EC33F8A67CF553AD8
-:10EA30003C87C283E3DDE5477D2EBFBD3C5FF2EB43
-:10EA40004A13F40BF82F82E70FFF45F07AE1BF0875
-:10EA5000CEC37F115C1FFE8BE072F82F82CBF34F89
-:10EA6000E8F15CD8A1C7F3D8F7F47856F437103E34
-:10EA7000C677EAE920141F133F0DA10B8987F9FC23
-:10EA80009FFEF04047114EFFD31B19D9E7BE092F57
-:10EA90002F84E065D2484F3BF6EBFC4117532DC065
-:10EAA000538F6704CE939F493B49E83D4E2F57074C
-:10EAB000280EE107468ABF396968D5C097FD299EAF
-:10EAC000636379FDDB731A897E1259E9FE257C3E6A
-:10EAD000E5FF11467E9CF261225E97E574529C83AD
-:10EAE000E277E5C9E21ED11B63E5F9CD25EE13758A
-:10EAF0008C15FA6CA4CB41F78E2B72441C073F7621
-:10EB0000A5968F02FDBC6E1B017AD822FC269D883B
-:10EB1000178E0BC40B43DF847E9722F5AB963F58CC
-:10EB2000AD58C7886D4C272747FAACBA7BAF57EF73
-:10EB300075E8F2A3DA1275F5AF39E4D495E7FAB3C4
-:10EB400075E5F9275CBA7C61C7385DFDB1EFB97531
-:10EB5000F9F19D3375F5277E5AAACB27B39E87011D
-:10EB6000DF619A38EF5B395FA27B604E110F547EF4
-:10EB7000778C8803957600A54FABFBD01E4977A113
-:10EB80007AFA308BD0535B9298388759E5798BE9C4
-:10EB9000F5758FBCCFACF454E6D5DF6756F798FB1C
-:10EBA000F47AA9B72BFD38E81EB33BF81E73B98C75
-:10EBB000DF0E957F71E3847D2F74FEC32C62BD2D23
-:10EBC0007758286E44CD2B743ECBF304DDEEB6F6B9
-:10EBD0001FBF933E4EA3FE8B724B878CE3F51E3313
-:10EBE000BB7C6447B9623C57A717E7CA1F595C77DB
-:10EBF00039BF79BCF26BC47ACA0C86DB67E7D07D7B
-:10EC0000B1F9BF0C1A3F6F9CA0EFF8095ABFEB2B6C
-:10EC10008F16F7B958B4C509FA1D783C01CF440BDB
-:10EC20005B477146F2DEFF6D9BDAEE1BC18BCA2C8F
-:10EC3000AD66325E309F19F4306B1AD7A772611738
-:10EC40007CF1113BD7371E6B32919D67FCB8616533
-:10EC50005C13EB8BE318C6CF1BA00FE82C38A73C46
-:10EC600039DE48E32C1C27D65762BCDC77FF9EFCBC
-:10EC7000178C49FECDE83E4C3FF44674A8D6F1AF60
-:10EC8000BA8FAFE836144EEA7CC9A4DCC994F352BB
-:10EC9000F053FB41C14FC5433857984B77DA29AE43
-:10ECA0006226EE9129FCBD3C5EF0A34D8047A1A8F1
-:10ECB000077E3450BD12634E34ECE1BDCC19EDF843
-:10ECC0001A7BEFBF304E81E03F507CD540FCE10A1B
-:10ECD000BE3040BCD540F4497FFF40DC55107F106A
-:10ECE000F77A243E7C9906F2A3DF1DA9DFC72F8C9B
-:10ECF00013F0F5C87DCCE5AB3D57CF2718ECF72DC9
-:10ED0000EB8D924F08B90A7D03DF17AF3793BEC171
-:10ED100058E956C4117DB4C54CF75B27BB9D335CE5
-:10ED2000C23F4F7A07F9BDF8D42ABC7A79CAE5FB0D
-:10ED30004EE8C153986B03FC19951BF5E54BED3379
-:10ED40003E833C5F1C722E5D2ACFAB4B43CEA54F5A
-:10ED50008D93F2D8C55CA427493F7FB5ACD3474714
-:10ED6000BE8C686977A1FDC953BA17A6E0E284BFDB
-:10ED7000263F90E7F00BCF869C5E67EAF7BE5E1FEA
-:10ED8000FC06B88F7016F7119CD8EFBD146FD57BB9
-:10ED9000C026FC94CA1F24EB9FF55EA472D4476F73
-:10EDA000E7723B46430FE9F31F85F8A17AED86A889
-:10EDB00071E86F9F99FA53F72D6AFEEA1BED08F28E
-:10EDC000277B3A8DBAFB2D57CC7FED7374FFE2EEB3
-:10EDD00018CF3BE0E3674C2E2BF0778FFD483CE2E9
-:10EDE000E46749BB4DE87CFBF4CE224DF861BD22BF
-:10EDF0006EB677A646F700381F64D837EADEC06CD7
-:10EE0000E68F43AAFC319E8DE309CECA1F53E11F52
-:10EE10004FF39CD7B2D41CCEAB743EBCA624DC19F5
-:10EE2000F0D374A6887B3F03F96BE65ECAA5FE6E3D
-:10EE3000BA3491FAB9382E4DE85DEBEE5B013ABA7F
-:10EE40006A2F33639D9D21F7DE555A29F98D77BCD2
-:10EE5000E2D3F23ED15A8DE87CA5C6D4FD22E2D39E
-:10EE60002A7FB155E64B447ED57A91EF348B776695
-:10EE7000F6487B03D68914EBC1B9789FB447601D6F
-:10EE800048B10E7C075F421E7C0979F025E4C197EA
-:10EE900090822FE1FB22569A9A6B147EA5E2A07D08
-:10EEA00003BF527190DE03BF52701E7EA5E0FAF0E0
-:10EEB0002B0597C3AF145C0EBF52701E7EA5E0FAFF
-:10EEC000F02B05E7D9B8EB0279F031F76C5D7E2EB7
-:10EED000D7BF8B83F62DFC4AC1FDC3AFA4EBCFB3E4
-:10EEE00042D7FE56D6A46B0FBF5270FDDB9B349DFC
-:10EEF000DFE976F91E40E5B641441F2F8D2E758D52
-:10EF0000E7FBF5CF117FFB9E19E70063FB32D0EDE5
-:10EF1000CAFA7097C073EB4C8177031378EE5940AF
-:10EF2000785E6311F91271FFB83FFF4DB159F86F68
-:10EF300090C27F8314FE1BA4F0DF140F17FE1BA4E6
-:10EF4000F0DFE03BFC3748E1BF410AFF0D52F86FAC
-:10EF500090C27F8314FE1BB483FF0629FC37F80E92
-:10EF6000FF0D52F86FF0FD24FC4841EF66404FCF93
-:10EF7000D49DEB381DEACE750E5D1E7A7A707DE861
-:10EF8000E9C1E5D0D383CBA1A707E7A1A707D7871E
-:10EF90009E1E9C5F3DCE49FC12FA7A703BE8EBC1A5
-:10EFA000F951ADDE63B01DDDB0FDFCAB483B23B5D0
-:10EFB000C734CE0A56BC70A00C7EB64E9B961AC3C0
-:10EFC00039A5597BB1AC98E73DF21EDF68D66300E6
-:10EFD000BEC9CFCEF1E6F133BA773CEAAB242A576B
-:10EFE0007E5DFAE378CF3DC048EF3F26E33D557B99
-:10EFF00017731891AAFA817CFFF542C757F5885F0D
-:10F0000006CD831F0C7371CF24778D3D0FF7E5F785
-:10F01000183471DFF42E71DF3794AE764BBEB4C76F
-:10F02000B0FF4838EE0F55682EC4316499D8097383
-:10F030001EE0D49807FDE0BEF131725D8D1370FFC4
-:10F0400048CD5BD901399FA0F8B5A21E66A9E2E3BD
-:10F050004CFA82591683BF5B845E8076382F5EED52
-:10F06000D5DC3B83E8FBA1F142BE79BC2B2654F1F1
-:10F07000EF57EF6B9C80B8B859E1A2DDCF1F8F220C
-:10F0800038DEB84EDB89F8C3A27DCC8D78579F9CC3
-:10F09000F7D5FB1C962A1AD741F174AADF8AEDA98D
-:10F0A00014FF57C13A8B115FC10A3406FFA8821BB7
-:10F0B0005FDFAB585F16DF2A66D23F455C4EB88CE7
-:10F0C000CB51F1386131A555905B2A2E6752414CE6
-:10F0D00009EEC5B176E64218F00D0515EB07F3FE13
-:10F0E0003D3EB70BF78A267DD1788CF2BB4A294F7B
-:10F0F000643086C621B936C2ABD1FB1A377A77188D
-:10F10000E29C88D75D6B8E47FD7DCC0575878B1A99
-:10F110008A3B55F3CB611D069B06BCB3A38382E8F3
-:10F120008873809B80F75C9799DEDF986D7298C139
-:10F130003742E5F895F71643F48490FB252D6BDEF6
-:10F140004B35A6E37E89C1E507DF7A2E82F405A55B
-:10F15000EF54C8FB6617D71D1B7C0B2FAFD82FF4BD
-:10F1600003CF368DF89FBA6F529FE14B35405F1841
-:10F17000B26374AC51C87FF0C533DE676FC616AD9D
-:10F18000587F8CE2222AD617468BB828E187A892AE
-:10F1900070AA92F78A588E231E7AE6879CEFB847AA
-:10F1A000D0BDC4688A2B6C15FA9CB2B7287D50BDBF
-:10F1B0001F53F146FE71E0BDE251F92ECBC60A8A1B
-:10F1C000BF0ABDE7532BF5BD65EBCC747F6859884A
-:10F1D0003E582BEF0BD586E883E7C687E883F2FC21
-:10F1E000A2EEF356BC71741EE92B8D66F2CB95AD81
-:10F1F00015FA0BDBCF7C8867285B3BDD807743CA41
-:10F200009E73BBB47EE8E42DA9C7CCEAB4115CE7D9
-:10F210005C4AA6F4E64B4994DE7249DCA344EC0B4D
-:10F22000E8A0F305467AF4DB526F99877B9588470F
-:10F23000F486C9FB938CF4A65CE62801FFB8CAAD3E
-:10F240001D85DA37CBEC598F7B9BB376308A3FBA7A
-:10F2500001FA0DE2BFA0EFC0EE5E90564271183386
-:10F26000358A67B9A16085A46F4EEF0CF4EE95F472
-:10F270005B4AF93EB920E9DCE3ED3201EE3778353F
-:10F280000BDEE1F3C873ACA2E3507A2F8F90F62720
-:10F29000BBB02FF5D99F30593C6AE38DBE0DF75BAB
-:10F2A000CB61B31BC204E239CC237344F98817A3A2
-:10F2B0006F5B8743CDFFA35DA2CC6010F14E5CDF96
-:10F2C000025FBD6D75AE6551107FF962E2B419132E
-:10F2D0000B03785F1412A7B7F29EE1095F172F5A4C
-:10F2E000C9E18C7D521EDDF93D4EA1ECDA09CC5D01
-:10F2F000CCCFAC0B18538FF7F8712F70A1CCAF7E29
-:10F3000071DC9F36DA093E949F3E21F5362FF15588
-:10F31000C1B76E05DF32825F79A64E207ED53903F4
-:10F32000F888C8E991EF1048B9146287583DC1299F
-:10F33000D61B628FA8CC11FC9C999CA9B7525CB0DB
-:10F3400093EC796AFE1F9AF5719A7D7E9109529E1F
-:10F3500034FF6BE21BFE2BC3731BD6B7D520E2E64E
-:10F3600087185B99B40BD1FE57FC83C9772402F848
-:10F37000E77A1AF9D1354730FE3D1B3511A73E809B
-:10F38000FD8665F73CBC1BF6BB660B439CEBE35963
-:10F39000828E1EFF8185F4F0324BC731BC93A5E00D
-:10F3A000F87ED3BF9BC92ECFFCC3F1FED7C2469BCC
-:10F3B0000BFCF98B89A5AB30EF881C17E16306DFE6
-:10F3C00066E8FF644AE9F7095F9B5E790C71FBCB45
-:10F3D000DBD3288EB4E250EE06BC27F2C544CF0F33
-:10F3E00027C08F6B775820C71BD6C5905C2B4F90DA
-:10F3F000719DAC87FC540AFE0F4C10F6ABEB8A04EF
-:10F400001D77CBF30818E66C5D3D798F3B649F2830
-:10F41000BB60A87D21F41D8781F68FB223C06E608A
-:10F4200009B22B2ABB8439FBC30590A365167DFC6A
-:10F43000A14A5F557637791E5CDC27C77266244087
-:10F440006FDEAC3920C7AAECCE5BC6F37CD509339E
-:10F450006E60B259B14EF17EC73DE2FD8E457CBF74
-:10F4600082DF94C9FB5855DBC6D37EABF2F1347F03
-:10F47000E07D79EBE6A3292F807EFC6E8ACBAF720C
-:10F48000B82DB141FBBEB255D3C5F5ABFC8109C265
-:10F490000E57C6D574C0EFB6D56916BCA153C6D5F4
-:10F4A0000BDCEF7B7582531757CDEBD1BD8659E945
-:10F4B000ECB8783F89CF3B4D8C9717D4FFA256FD0F
-:10F4C000FB04BC3EE9452F4F8824FC5538F8BAD3DD
-:10F4D000903A689E1C0E04A79EFB787F4E1A87F018
-:10F4E00051E9F79971EE2EC37D0A9E5FE8F09931DC
-:10F4F000CEA275E2BD10CF26318E67638C6514F401
-:10F500002693C39202F8E1B01C47F3233E58C5E1AD
-:10F5100082782B1577190A9F0A39DFAAD618BD3EC3
-:10F52000D6BAD90C7C2C18E0BD821E49B78BD64DBB
-:10F53000A578F32A939BE2193C12BE1FADB0DD0BF8
-:10F54000BFC0822D0F99D370CE9E20ECCF3D72DFCD
-:10F55000CD4AF70FA7778156D85C98E702472BADC5
-:10F56000AF0FBE0F727868787FA694E0CBE9C28BAC
-:10F57000FB79555BF4F80CCC47C0B76A4B05EDB787
-:10F5800025268FC5113C8F6DAF0CC73D94057C7F40
-:10F59000E3BD23E6F0507CD3C70FDE924AEBE4F3E1
-:10F5A000A47B502EE70CBCF3C3E984E858D18B8AC6
-:10F5B000CB56E359278AB84CEBC46FDA976ED26BFF
-:10F5C0005A387E61EF1E685F5A10D8C5C7B5548996
-:10F5D000F7D742F7A9DA9F6A5FAA7DAAF6EF63E63A
-:10F5E000527FA216E0335CDE36FEB21F38CD90F3B8
-:10F5F0005D28F1CAE1FA6A701CD73513055ECBD2DB
-:10F60000F5FB1DFDA1DF948962BF974DF30F47DC29
-:10F61000A5AAAFC62D8B15ED40F7A0B7948986BE7D
-:10F62000FA2BA9BE3E1EA5B28F5FEC5B1F0F7EB109
-:10F630005F23BD77E57D4753FE0DFAECD3429F3D36
-:10F6400053B7BB21097AA3C9971AFC2E56955FF0D0
-:10F6500087C55CFF01BF5822E5747B9E276762D097
-:10F66000FEAD7AE0E92C8FE02F7EF0970F9E7EE9C9
-:10F67000F7139C01F9A9E6BF68E36FCD15F6607832
-:10F6800089F5DD9BDD4B717695768B13F7972BD73C
-:10F690005510BF6589FC5CA105F01D4A0715EB34C8
-:10F6A0007A5FACB2698CCFF83FC8972B37CDA637BD
-:10F6B00091149ED47B274A9EAAF97F57CE7FA1A49E
-:10F6C000E33913C5FE5B589D665942FB3ECD520996
-:10F6D000FA97E50BAAF4DFFBF0D4E75FCED980FD03
-:10F6E00081B8213A9F6C320B3BDFBE48D257CFAC7A
-:10F6F0007CFECD9B79BDCFB7EE48857EA2E6B154A6
-:10F70000DAF3164BBBDC12A9B7723C5504E369E986
-:10F71000E3024F95CFBCF127BCCB55962EF9D97D8E
-:10F72000229E7F51DB7EC2DB828D9BCD69BCDE8A4F
-:10F730008969BA7B32958DFCA0CBE1B970E30E33B9
-:10F74000F8C08A89026EA1F45E26EFFB2AB842EE69
-:10F7500068417E0B551FFC6F3F1F67F50A5B14EC79
-:10F76000D36A9C47245D5736C6C462BCCAC68A9F0A
-:10F77000E0DCA1F87DE8BE3B6513FB6111EF0FFBF8
-:10F78000F2D45417C535C3AFD59F5CDD2CF1F653C9
-:10F79000B378BF3139A2ED09C0217979B80BFC21CA
-:10F7A00033B393FCC6A067CCDB6210EF3D66D67521
-:10F7B0005EC03CB84A4DF75390E29D29A8D8F13C71
-:10F7C000BFD320E2AFD28D227D5EC28797FB51CEA0
-:10F7D000E23AE9DDB9BE779342E8D5C2766DC47BE3
-:10F7E000379638E66A7106E853F5A3E853D1EF403F
-:10F7F000EBFB85E423DFB4BE5369D21E91ED4A458D
-:10F800009C4AF9FD235CB0CF7CD33A2DF2FDC1BEFA
-:10F81000F572621D17DBCF7A33C5B965E0F56E2945
-:10F8200089EF67BDA1EB54FB44DD69EFF32FB40A08
-:10F83000FFC2298DCB2FDEEED40A1BDDFF52EB5227
-:10F84000F6EF6F1B87F0F6C458694FE88C841E5999
-:10F85000162EF7BF5FE4F17D76D07725F7D57B6D67
-:10F860008A3F9F6E94729175DE87FDCC9A32E87D57
-:10F870009293ADA722F15ECAA9A9627EAADD6AB3FE
-:10F88000883366911627DE3FE4E7AB934DF0FBAC7F
-:10F890004BA073E46D4D19C4176EF3C608FB83D4F7
-:10F8A000EF97483E18B1BA6203DEF95EBC2DCDA1D8
-:10F8B000F17116DB5D1F6FA3F657BBA00F466C9965
-:10F8C0006D4927BD579C03949F68B5C64A296E0CA5
-:10F8D0007C12FBCBF04A26E4CED26DE21C30CBC0CA
-:10F8E00036C24F38ACA5744612F8C4C31AC599B3D2
-:10F8F000EDFA77ACC6E6979EA7F35FC83B70ABCD39
-:10F900006DEE04F071AE6FC0DEB4D85E4A7A7BBD96
-:10F91000E49327B774D17BF40AAE57C4FF58441C54
-:10F92000704FA481EC70DF360EA84AFA9514DD28DA
-:10F93000BFD423F8CF78C0C94872ADC45846EF2968
-:10F940006DD8329DD2AACD255BBDA3107F5C1A3F36
-:10F9500081E66D263B5955FD7411AFBB332C06E78C
-:10F960009B54B33735582FADDA7137C5FF7CBAC316
-:10F9700046F13FC58ED9C53171F4DE31C5D7A97ABC
-:10F98000A94582EFD4D44FD7C5EF2CE67DE29DCDBB
-:10F990002FDB22E87E988ACBA94BF024150D16F1B7
-:10F9A00039E39D222E2789EA3BFBB58BABF4E36656
-:10F9B00011E711146F74E302DEBEAEFED928F453D2
-:10F9C000FBE0DB631C06B2430D47FF7DF146DB44E1
-:10F9D000BC51963C2FCD8A2DBD7901E0FF6B23C130
-:10F9E0007FA0F1AA0F693A3FDE6DBE68D25B3D7E13
-:10F9F00066811FD9E360A4177F6A644DD00394FE2B
-:10FA0000A2BE8F9770F934BA3515F4B16CCF43A903
-:10FA1000902F9F458A7CD99E5B7E037EE5D9152673
-:10FA2000F47313237DB8D22BF46B561DABDE23B5D4
-:10FA300095733A9A5E1421DE3DDAA68F3757EFDCD4
-:10FA40007E6612EFF320DE08F4FEBEC9BF18F87D13
-:10FA50009FEBAF38C7A61609FA7CBFD53883EE0DE9
-:10FA6000F18D023DE4FDD66723110FADF4B512E32D
-:10FA7000076EBCFFB3F23911178CF7E9E9AD506995
-:10FA80000769907690952F986724C791FE455FEAA5
-:10FA90004C7E4B7FF8AB91FA555FFEC07E3AB7D5EE
-:10FAA000ED13FA435D5B17E90F4A1F517187B5FBF0
-:10FAB000BA489F50ED1A0E08B8D41F10DF2BB20DB4
-:10FAC000CA8EE2D632719ED628EF7D31BF7CAD2939
-:10FAD000389F57BE16CC7E82B28FF4903E786FF678
-:10FAE000EFE81C5EBF4EF6CBF3E6A0F1AA414485D9
-:10FAF000E27B861DED9DBAF35DFD81186AEFAF0FC5
-:10FB0000DF0839EF6EB09B90B6D4DB49EE6F6F34EF
-:10FB100064E39EBA5B0B77418F6B97F7B706D7BE4E
-:10FB20006B83FD2089F51CC57BBBFE14CF0F8B7842
-:10FB3000BF0978DDC5188827EA3EFC493EFA9F3C9C
-:10FB4000ACF322DED4306B53CAE1A7682992EBC82C
-:10FB5000E9CC075D0F3E22F8F3A366B691DE6D3661
-:10FB60009532D8EFFDD2BFE8FDCA40EFCFB66BFEAD
-:10FB70009F05EB5787247D9686093FE3CED19E4DA6
-:10FB800098C77735F3A85CBA77681C8EFEBBA51FB3
-:10FB900052E9A9D3247F4E91E72BCB90443BE85800
-:10FBA000DDB7D3DC6E8AF7BC2BE74825E4F38F7B07
-:10FBB000AC142F30AD279CF4D6942133499EA977FD
-:10FBC000DB35A78995F1FA47720C7EC4C5FD9859BB
-:10FBD000C5BD006B887E6BB0D1FD64ADFD575F8104
-:10FBE000AF271B2F1C8DC67DD97FD3E8FDD1F2DE58
-:10FBF0008F1F7D8BE13CECCBA578E814CF1EACE7E2
-:10FC000064EFCC2E0F47DD8F1D6D569790172C7823
-:10FC10001DED777C15156B08CCAFBBE7637AD7B1C8
-:10FC2000BBC74A76DB69EDF29DC390F974273AE9C8
-:10FC30009E34AF47FA66B7DD40EFBB4D6B3F4AEFEE
-:10FC4000154E53EF195AF5EF1932674A0CECCA6496
-:10FC50004BE5CA417C8BC0DFE468FD79F1B522A198
-:10FC60002FBE56A4F5FBDEBD8A5B5172E565FB9E97
-:10FC7000DB845D4AECD3E5CACF7F299DF489DEF6AB
-:10FC80008CAF7DC7E26DE8155C5FB8708DFBEDA2AF
-:10FC9000C2805C9D27E1A4E4B38A5B9827E135CF5D
-:10FCA0006E10F009F9DD154537A17411C0BB88F756
-:10FCB00052F8643FE83886782C8EC751F733C2DF9C
-:10FCC00049C2DF57AFAFC7B30B438CEE2E4FDABF3D
-:10FCD000047FF47EF7B7C65F4728FEFCB611D02339
-:10FCE0001E34901EA1EE3B7AE47BEDEADE23CB6668
-:10FCF000C40FCA8DE1642FF4C877DA391F38063E85
-:10FD0000A0F6FFB0999DA320474FF2233AE6D769AA
-:10FD100068A3EFA993D269BF0E651D49F27E4E21FB
-:10FD2000F43763E07D6AA2FB16CDF7F012DCBF9CCE
-:10FD300067A77BEEDDBE90F7A9E53BE6DD4CF287D9
-:10FD4000F9EA1D73BE9F79BB2D0B4479DF3BE6C3F7
-:10FD5000199DA3B6E4B22CE85FEA777F067CC77CE6
-:10FD6000592CD94D1F79C43712F240BD5F3D25C5CE
-:10FD7000933869F095EF576FD54A17E07760BCA3C9
-:10FD8000C47C3B17843FB34780DB0F7BCFC9A648B9
-:10FD90007AB75BD1A9B2730FF3763D0C38A9B8DA04
-:10FDA0003F4B7A53F05771857121785074E73533A2
-:10FDB0008AC3053E1067D4F7FB316B247F51719DD8
-:10FDC0002FBB9C487F9CEAC99D847DB882C399EC77
-:10FDD000E89DDFC37A1FBD23D28DF99D94BF6B11BF
-:10FDE000BAAF8A261994BF98E206CAA57C2B577130
-:10FDF000024DFA3881D0774EC387964E06DCCE6925
-:10FE00006F8FC1C7D7FF8FB1DFFB27D74E127C2280
-:10FE100033D1336312C9B9693A7DF2F5DC4F52E848
-:10FE200077662E1F1D0AF9774B4AE975E8D79629A0
-:10FE3000FC077F4EEAA4388F3F2FF86B0AD99FD773
-:10FE400088F759BFED3CAF8C6B16F4B06AB1B89728
-:10FE500098CC1A898E1303F1B236CCE37F5B5C73C6
-:10FE600020EE782FFDBEC8CBCD6D19A787F783F79D
-:10FE7000B023CF3AF9C9C67BF8E5728AFB8D3EB252
-:10FE80002A8DE7371E3E5A4E71BEC9472EA671DC39
-:10FE9000DC7BF85591BFFAC845C4056F3A7C4CD459
-:10FEA00087FF6008633F397CBCDCCBF171C768CF4A
-:10FEB000FDC0D7CD971A8F411CFF7EED9CC56914FC
-:10FEC000D73A3B255BC4B5AE03DEE7C52F5A1FAD5D
-:10FED00005E25AF74D12EDBA2F887DD07D41D079D9
-:10FEE00018F8C1E07F3E55F1BD8A0F0FC42FD53EF3
-:10FEF000FC57C527ABFDCCF6B8369A418CDE7F3A6D
-:10FF00006EF8C949B42E7DDC70B7B9E731F22B5DCC
-:10FF1000604EF0895722DF75425EB4148AB846AD50
-:10FF2000A7C389FB18450522DF72A1C3093E8F3C98
-:10FF3000EC5BDD3122DE51C5C5B65CF027619F1454
-:10FF4000217E91D72FEEE929071F2DC27DDE34F4E3
-:10FF50007FFCA81C8FA1BF5D1744DC61B7ADC3E96E
-:10FF600090E3A01F3E6E1AF863D16A2BDD3B6AB99D
-:10FF7000D0B882FA29B3F78DAB858C6BFDFA71A7E7
-:10FF80006B41E366F68AF84E8CEBD48DEBA7B86034
-:10FF9000DE1FC59F76C7B81271EE57F96294F3FC65
-:10FFA00043F2772A8A9C7E23E4808A934AB0C8F77A
-:10FFB000B8E5B985D7A3B8CC5DBD629DE79BFD359B
-:10FFC000D84FC5926F175B84DC64867017EE639719
-:10FFD000182F1F4FC6F9E405713E290E2BDD8EFD4B
-:10FFE000D86012FC86C5A9DF4BEB58F6735EEF773D
-:10FFF000F1C9F4FB6243130FB24C9C8F97CFCC81B5
-:020000023000CC
-:10000000DCE07AF719E0FB77AC5513BFC325DACFF4
-:100010009D1941F750BA0F8F28C4FE9913E67C8EC4
-:10002000F17DDB3BE92BDAA773A29D8538F1F41E45
-:10003000FE6F914F703E07FFAE957D45FAB9F2D73E
-:10004000DE12F0D7FE17C6A99F79CE22F4B31E7A2E
-:10005000A7F9BF2789F7E9B8FE4EFA47CF75F2DD59
-:10006000CD1C6721CA53CD3D51805BF7659378B7AE
-:1000700096F544DD14E49F7DAC5DBC671B4AD787D1
-:10008000270B39B03CD34EEF9D35245AAD94B65F63
-:100090009841BF07632ACDC4F9C06DE9DFEEF88B44
-:1000A000C9425EA56DB004FCEF5C7EB8C399CA7B03
-:1000B000D938C6767C3FBCEFFC051163192ECF639F
-:1000C000DEC4C78B4DBAFA6ED4EF2B67E29936D5F2
-:1000D0003EE765FBE3EB4C723CE07989B83F112ABF
-:1000E0002F1AA6C4F6BD57487237CE46F7AE328DEA
-:1000F000D29EC7EB3AC82E28FCB7C9FF61A338BA15
-:100100005D364187990691EE32C8785F69EF53E713
-:10011000981F4FF14C9A3298FAF1533FC6FDB9D06F
-:100120002B92581B8DAFF433558FEB61366232F250
-:10013000F7DE8A8C867EE1F9CEE4A9A5930B41D740
-:100140005EF651909C381F11D5148CBF06A3DEEECD
-:10015000F9CEE469D44EB5AF6F9ACE3EA278443F53
-:10016000D14F7DA681CEAD0D46F62AFDEE00EB20E7
-:100170007FA66AF72EE7931FD1BB0D6E4ADFE3FC23
-:10018000F223BAEF379FD20F9A3DF4FD647335A581
-:100190009DCD8DF4FDC3E6264A6FBE35B200F4BF97
-:1001A000FCD05AF651907CAC6F337B82EFD7BC3BCE
-:1001B000B57F3AFAFE64E1B77937ADFFF2FB55F946
-:1001C0006481CFEEC542CFE474B9CE113BB0BED04E
-:1001D0001D29EE25BC344D9C5FBB9344BE71B278A3
-:1001E0002FD46D60DBD0FEA56916CABF9B6EA077C9
-:1001F0001DDCB1A2DF77B30CA4A75D3F636A03E007
-:10020000E48EE7DFF302F977AF12E5EE21E2BB9A65
-:10021000AF2A9F34A5CF8E9025CEC7C2FFCEE99DD1
-:10022000FAEFC36FB1985F687D759F3E141EBF954E
-:10023000FB96F605F477EC83B4A07DD1E0A47DA114
-:10024000E850D15FC314B15F33C3249D73D945F027
-:10025000830CC3F938C146FE4137FC177C3DBB64B3
-:10026000BCFB15FB41FA03D47E50FB40D17B32DF4F
-:1002700067C2DF21D631C9D8BF9DFEA1C962DD1D8D
-:10028000F191A41F77B79B1D9037938CC2EFD0DDFF
-:100290003EAF00F7C24BEEB637F6C7BFDE94EDFFB8
-:1002A0006938287E30001CAE58BF45DAEDFFC1F535
-:1002B000137F03DF5E2CEE6586D26BFB64657717D8
-:1002C00074FBCE64F741D04FB76633E19CD26DEB3F
-:1002D000FF1EF94BD3C4BE50F4D33085C97768F8FC
-:1002E0003A33AEE4776A3D7DEB5CCA88EF65CA7845
-:1002F000E350FCAA7505F1BDD7270F0EC09331AEB0
-:10030000AFF07E86D6D9E99CAAE8F7FCE0AF96402C
-:100310007ECD9FEC147E268351BE072BE449DF7708
-:10032000CD487157417286416FE9392CFC717E7E50
-:100330004E823F0B36E8E0B86BCB14B1EEDEF985A8
-:1003400006D809CEFFC5EE85DC3A3FA4E724F49237
-:10035000F3DBC47BE7BCC7591AEE8D20FEC789DFEB
-:100360006D117E10E3C35F9E843EB4E46123E92FE8
-:10037000E7716CE6ED963F287EE74EDD1FAC93ED0E
-:100380005AB65DBC997EDF8CD327F49F8F6C0DE944
-:10039000D08BA73FFCE009BCBFBEE4390DE6667612
-:1003A0001476779EFF78AF51FCCEAA8C3B9921EF53
-:1003B000F7D7EC16F7FBEB106F02FDE5C08EADF83A
-:1003C000FDC9FABD6666E3DF67E09D343ECED2B676
-:1003D000487E90E4FD6ED1C78D5ECBBC1B604FAEF6
-:1003E000DEAEFF5EB34B9FAF0BB9B7A84D91BF67B1
-:1003F0003092E5D2FDC42DC25EACF8F695FAAE9708
-:10040000E0EB5EA9EEEB7E41EF7B1B0F7F99FAA13B
-:100410005DE467CB7C17CF9FFB52C05FC1AD41F25B
-:10042000FC7349ACA08DAFAFE1B0CD013B40C30B35
-:10043000C24E70BE2D9AE0BC3CBC93FC0AEC45A3B6
-:10044000037AD83D878C6457A86FB7FD0CBF4BDB90
-:10045000F09C46EFD5D61F0AF309F85C5882F2A546
-:10046000876C0E27CA5F0C63B03F9FE778C3BDD887
-:10047000F3299D847FE0157609FE370BBF5FA1F05D
-:100480006F7C58F893973C21F1B36D9589F0EAD3CE
-:100490005842DA95785278FE95E1A93E3CA1DDF408
-:1004A000877F7F5CE29D21DEE6E8B64AFA5D0C8537
-:1004B0006FCBE18F52A1F72A3C1B399E7FA8DA3B14
-:1004C000E57B785F83E76AE0D9FE8FE3F98F908F51
-:1004D00085A4F77EFC53E8BD9116F2A32BBB86B230
-:1004E0005B0CAE7DF7581C1F7878E2B3A4E796C783
-:1004F0009EA95FC1C88E76ED14D8D1AE7B033FEBC9
-:10050000CB7E77FD53B9A08F167327FD6E8C3746CF
-:10051000BC2BDF9D367BFBF37CBCE2D8AF52F7638C
-:10052000DFBC1C46EE93B9725FE2CF1AFC2E60BBB3
-:100530008DEC6DF5ED61C2BE7640EF3FEB4E12BF24
-:10054000D35762E9295F01BD9CF78771D479B0B6B2
-:100550005DFEFE8B3CBFD52A3BC3BE90F7A11C6F4E
-:1005600050BDBA2922DE36236192137CA86501F3BF
-:1005700084677C1DBF67C4EFD5EFE50DA8070EC0EB
-:10058000F795FEC7BC7A3B87E23F4BE5EF4BF6EDB4
-:100590000F99AF5EEB8DB21A89EEE8DD86BA47C5DA
-:1005A000EF2B7E02BA8B0AD053838C4F3BF6FDDFD4
-:1005B00098F03B4DDDBBC4FD08CE21B7E29EFED9CD
-:1005C00036110F5753D035C6EFC4EF74083EB46CE4
-:1005D0009FE673A6F54347CCB741BC6B1F424FFB68
-:1005E000BEFEDDC37B037C64D4DF393C77943029C5
-:1005F000B7BCFDC64FF6C9AF90DFF1F8DF16CFDD0F
-:100600009BC3D7F335FEC66B13F5EFB85CE7D4FF99
-:100610004ED377B2F5BFD3D46B97F091FAA0D253F3
-:100620000F4D11723C3455F0BDC1A51F479D8BBFC6
-:100630003B4E3FDE6CB77EBC6F8B977F555CEB37D4
-:10064000C1EFB81CF7841CF73772DC7F164E2A1DE9
-:1006500068BCFF5FD3FF0B8D21EA0800800000001B
-:100660001F8B080000000000000BB55B0B7C94D5CD
-:1006700095BFDF7CF3CC7308210904C224242160D8
-:10068000880324542B94C9D300D6065C2D688401BA
-:1006900052C83B80B5D2D6FE3208222F5BA8D1A229
-:1006A000224E82E1A1613B118289863A286411AD14
-:1006B0001B698BFDFD56DCF828F23213A374E55755
-:1006C0005DF6FCCFFD3E321942B5DDDDE4A737E72C
-:1006D000BEBE73CFFB9C7BA929CE317C394588DC1B
-:1006E0009873E69E08215CAB7A8A12B385E87B4357
-:1006F000154D0E2184DB7BBC3E5688DA8EE16253B9
-:1007000032C1257D6F1A00B78DB36FA2F18DED7FD9
-:10071000781BE3BD07558785C65F6BFF280AFB5C26
-:10072000FC325C88E158F7519420B8FAB2C2F02646
-:100730001A77103CAB5515FE4CDACFE83363FC62F8
-:10074000AA0E7BCD82DA929656730FB5557B5B79F4
-:10075000FC0D9F69F0F8DEC641E376CCA7B6CAE887
-:100760008DB2537BBE5DDFCFCFF3AB53159717FD33
-:100770007BFF10B70CF35ADE895B4AED15FCCCBC4D
-:10078000B6FDF4D00B996E5A57D341FB440CEC5391
-:10079000D361D2608977756A6B510CD14BB4282232
-:1007A0008D9A8B62AB584DF4AC6A6FAE16D45F95E0
-:1007B000718F49105D023EB518DFA71F8388A375AE
-:1007C00076FA8BE877D1F779D452DAF755DFB1DBD7
-:1007D0005DD4063A5F8FC2770307697EE6003ED399
-:1007E0005D44BF1CB4662146D0BA83AF4739687CEC
-:1007F000A3EF75496FA39FCFFD9A0607A8653AB787
-:10080000AB7CEE8A2F55A6BFBEDFAD2E95F799D5EE
-:100810009E1689739DF4C9EFCD7539647FEAE23283
-:10082000E07F2261418E9ACC78BB000726CE69DE3C
-:1008300044A854F968DFCC6BE9B654DBB7CB24E6A7
-:10084000FBC0B7D4035DA3483E4E140F9F4C235703
-:10085000E7DDE332F0BC22B33B7505CD3B19E188FF
-:10086000B4D37E0F158F8B045F5F438BFEE25D6612
-:1008700037B59507E5F74EDABBA3206F270F4E5526
-:100880003DCAC07E776ADF15C2C3ED00DF3CCCA74E
-:10089000726F6304F619E09FEC9FEBB2F3FC13DE7A
-:1008A00077EEBA87CE773223DC09BE749945B98FCB
-:1008B000E5843E82EF752636820EFAF7E6821FB493
-:1008C0002E906160BEF6B69BB479F7348B41F34C41
-:1008D000CCB78BCF0DC6C7EEFDE097F7D0FCEA672B
-:1008E0005461A1EE6AD38A389CFF931D83F12BD704
-:1008F000E85C6DF2C7C505C96B75C7557D8960F9A0
-:10090000EED0F5C3C1FCD4F978324395782558BCB4
-:100910008250AE6E6D66B92675F3D8A6702BECD4F6
-:10092000268677272B74FEC407ACCEB584FF738A66
-:10093000366EA03686608384CDD45AA97DC624FB4A
-:10094000A1B6583F86D8A9106C2A1E976348A17D8E
-:10095000D4D6C9E0EBAB335D8FBA088FCD334B668D
-:10096000CC043EA26F99A06FD65C8AF08868210AF9
-:10097000D5F79EC077FB0F9A04EC478DB5A3F263C1
-:1009800092D37E27290AE1DDBFC3E4F5B0FCB9228A
-:100990009469422CBB49EACD270EF734751CCD5F14
-:1009A00063E0F355B7A85E1BCDEBAD271210C93F2E
-:1009B0006D4DFE01E4B5FAB86AB7D2B9F37DC9BF8F
-:1009C0009A0EB8C5E4B4D0FA5A1F75125CBB57F141
-:1009D0003AE4FE027A597313CBBA3863AB4D11591E
-:1009E000D4AEE93363DE99C38A788CE66D0E8B6AE8
-:1009F00002DE3599B3CF2951D4AA5BD627D27ECB5C
-:100A0000B79B3EECB1CAB557E8BFBACE6D2CB7154F
-:100A1000DEC1FD557B07C335C23800D3FECDF8E3F8
-:100A20006621DA5C91B1676EA0BF2788095754D060
-:100A3000697A3CF4E104F84AF2241A88D82385B88C
-:100A40006F92331E7ABFD1E8980D3A043A4D76D0B2
-:100A5000ABEEF0810AE0EDAD0E731AE8A8B5AB5F1E
-:100A600061BA06BE20BADF486D82E0F30784A46F46
-:100A7000A05DCA799D49F15AB19E68C8FB5915EF2E
-:100A80001A1A0A78FAA3D83E09510CBD58B520C7E6
-:100A9000003B07351684CAAF747D506C46251AADED
-:100AA000D4FFEF197BD4614176E23F5D298C7F81D1
-:100AB00059B87DD47F5FA4331A723FD61A9505BC0E
-:100AC000C65A93BCA0FB5863DF1A7C7FF328C5F19C
-:100AD000106D7D24EBE5C90AE0DA0827E4444958A3
-:100AE0006C043D368F5A6C84BC8FB5FB324A32079A
-:100AF000E0028C431F8497BF5714E136E23BCF8D51
-:100B000054FC06DA3F6023FCA02746BB09F8054CDD
-:100B1000121662CD20FCC82231FCFF8E9F9DF08B07
-:100B200018C08FF81D8DF59F67137DA84D9A2B4433
-:100B300037DB85156C17747A5E24792F205EA52922
-:100B4000526EAA771C29C2788DE85E8F754551F2E6
-:100B50001C45380FE030D9AAB9925FB95A7B7FAEF5
-:100B6000F42FBAFDECC8751973A9DD9E5B62465B74
-:100B7000A866C6F70C61EF5729569693CF49FF60D8
-:100B80008FEF5DA1D8533306E45BD7AB3AD97555E7
-:100B90007FAA7EBFCB2C52F0395777068D970BA9D1
-:100BA000D78B56DBECA9C17A043D237A94DB2B6EFC
-:100BB00013A46FEED571F6D4A9D4AF5E340BC89EE2
-:100BC000A65FB1F47B256508FDF285E865FB60D87A
-:100BD0006F9372EE8F54BC6B09FFD4DCC17A97A47B
-:100BE000E941A35BE1F3357E6564D853AA7841F30C
-:100BF0003BA973758C7638CC2BCFF5C23FDE4960AC
-:100C000029FA1B62594F7990ECD7BF68E7BCD3E84B
-:100C10003F02FB71CCE44BB6D3D0B11AAB13FB2F20
-:100C20001014E8905D2B15DDDC9E0AAF6DF3F3E642
-:100C30009E3190AF77DD1627E2B0C6754D91B0E3D7
-:100C400059629DFD4C06820AB1F7CAD4EBC7332422
-:100C500038E28CCE1738628A53C06F9DAFDB735D6C
-:100C600079B939D75F5FF5A7B6DBBF03FB757FB3F3
-:100C7000395E8A4977C6B401BEE97CAD131EC65BF6
-:100C8000E7D755FE11EEA3410FF5E25CB633CFAACC
-:100C900082E30A8D7F56FA1D8A7F3A7D676A7C5807
-:100CA000DE21ED51285F757AFF9036C4F7C98FEECB
-:100CB000607E080BDBBF50BE7F135F28C22CC5507F
-:100CC0007EAC45809F8906691F1397919C10DEF7C3
-:100CD00008F7E11E6AEF0A7FCBC472A8F1E75EF065
-:100CE00087A6BE2BBCDFCF48FEBFE34F476EC903CC
-:100CF000C17A18AA77D7D3B36A87F3DF75BF47964F
-:100D000086F42B443F43F44FE7977B7514EBD9559A
-:100D10003EAA2D525F357E45D0EF90FA863FE87BA4
-:100D200035ED8AD79FFC2DF44F21C4896F8F85E85C
-:100D30009DCE9FEBD91DDD4E9D16FE63763AFFA931
-:100D4000141907787E62F136034E3794C3EE9D9AEC
-:100D500028DB039A7D0B6D4F539CA3901FDB94718E
-:100D60007204FCF529B3BE8FCDDB4CF89F5ED33DFA
-:100D70006625AD3F9D2BDB53880B83605798580445
-:100D8000BB7E7AA4C5033A9D5626E4C13F9C561EFD
-:100D9000B85DC2F16607E005F17976824F99E47C8F
-:100DA000DDAFE8F6FFF482EF14F03C451C053D1C76
-:100DB0008A28E1EF284A4C31E173FAFEB4296BC569
-:100DC000C0F99B720DBCCEABD96FC283E9DEF7537D
-:100DD000C5DB445D8BE05208FFE4BCDF14A750FF85
-:100DE000FB3F1B3719FC75AD1AFC7DF8EBE41B01CA
-:100DF0006FE37DBEF7659F6971905FBAEA270B3E8E
-:100E000093FD653906E84BB9C64357CC8468F0A713
-:100E1000DF3B2E1A7E47F743FDC70F44B883F876B1
-:100E20008EFC94181F044F783429D88F1DD9BD39F2
-:100E30001DFB949B3D594EEA3FDBF87412E28DF2A4
-:100E4000DD8FA4731CBC7B633AF299F2A6CDE92E28
-:100E500086C3DD9C4F19E5B92FECBF79D7A6A0B8A2
-:100E6000BB2A5F65FC4BAD470AE16F67DFF0E9C362
-:100E7000769A97F633C50EF1BA57743F0CFFB81047
-:100E8000F131F2B7062BDB73DACF05FE374FF8FEF0
-:100E900073D0E313191F99CA68DEE55C23D367A1F9
-:100EA000F06E89A771B141B1378BE0F9631A317FD8
-:100EB000F13AC59C003BB062D864D58175C3188FE8
-:100EC000251B2677A17FE183B27FB6C57BF024F690
-:100ED000F98DD9D9EC607B9352326900FFCBB966AA
-:100EE0005EB7688BC2F1BFFE9DB427E21A83CF794B
-:100EF00059E3BFF8CAA2802F3FD0F872DB83EF1C02
-:100F00004DA07DEDB1EE2BB01B6F3F7E26D54FFD82
-:100F10000531E73221E76966F75315387793C589BC
-:100F200073646725AAF1347FCA8F731F43BBE8C17E
-:100F3000C54F55C0DE6EB772DEA6E3B74A711A60C0
-:100F40008F5F6FFCE112D0EDECE3568EDB57358EF0
-:100F50008F1743E8A9DEEE21FE3B28D1D9576FE574
-:100F6000F6857ABB70903CECAF4F60F8B7F50E6E2B
-:100F7000C57C295FABB4FCF87AFB4DFD325C3828A8
-:100F80009ECDDE60130EB2534971AE517974CEB46A
-:100F900089354D1BB573A5D1FAC99EE47CD0217B60
-:100FA000E3CA2E84BCE63C998FBD797243128CF261
-:100FB000F2073FD85941E373F34AC6E551BF75C7FD
-:100FC000675C5778BDE39185A0777993459E4F3B49
-:100FD000F7D9C7D3E39FA2FD3D6F9838DFAFDBF1B0
-:100FE000C1CE8DD42EDDB2D21C2CEFDFF6BCC91AD7
-:100FF0003EDFA457D7A3C33FAE579B93587F9A4871
-:10100000AF32FF79BDAA7B700DD3EF81BC92D9A01E
-:10101000FB59932709FA7476C20C9673CF6185E960
-:10102000AFDB717D7DB176DE2A836FCBF4E4013BCB
-:101030007E4964337D8F747C928EB8F752FB82BFF9
-:101040007BEE43746E3F9DBB9DE8EB1F7FEDF83454
-:10105000B37B9C93CE37CD20E3DD6BE2D63C835649
-:101060002FE83697444A9A2BA8CB68FE93FC982722
-:101070009AF0A9EE54FC6159F067B79E3322DFA3C2
-:10108000BCF1C3E038827E3E0CF2DBD7C3F79BDABB
-:101090005AEC93366077BFF36783F007F9E99B7BDF
-:1010A000C2843FE8BB57F313EA33139F7A3B46B23F
-:1010B0005D00DF8CA8C7754C68027CCE2CF9D87B0C
-:1010C00088E22659C711EAB481739EEBB890053BBC
-:1010D0001B7ADEDA972FB07C54B73FF299C2E79FB4
-:1010E00075CE98F5CDE73FB2FB4216F877CED433F4
-:1010F0000DF956AFB9270B7CA87D45DAF37F940E26
-:101100007A7FC5063A08E979AD62653929542F72AC
-:10111000DDA0F7B8AC1BD476EC627BDADF29EB37C5
-:101120007586EEA278D43B567CD0057BD69F20F303
-:1011300028DADF05BA4D1FA7F941635FD25CB26BB5
-:101140002F5E950799FF9D85FE8EC73EBE6AD8012A
-:1011500091152E10579C873E53FFC2D5C9EB21E74E
-:1011600067BD23A6C03EBE99F5B75AAEF7BD1A6E4D
-:101170005739EEA1DE20FE5D3D875715AE41F58063
-:1011800070E10A9A576776FC80E3E313AA405C5744
-:101190003751EA937859EA53CDBA23E684A0FD7615
-:1011A000429F186F192FCE7EF56FAC975B66BA3AE7
-:1011B000A197E1B085D82F21DAAB28DA3CE27FADE8
-:1011C000864344A796F717AB3C5ED7AE8A915893F7
-:1011D00010E94DA373148BAD46C4D3B3856F3AEABF
-:1011E00036C2D8F3CB5B687CCEABEAD44D82F3A792
-:1011F00045259C57BA5357213E32281A5D7DD97335
-:1012000083FD599EF453D35585FD58DFC8708E5326
-:1012100066CDAF2905BEFABCAC61721EEDC37196F6
-:10122000F0F665CD857EFAFBB2E6450ECCBBEBD57C
-:10123000F015EC17852FFBAEA0EF84E5CBFAE8E7BD
-:10124000E4472027759764BDA350FDEA09C4E7ABC6
-:101250000E93BC203E3424BF6B801D273A83AF170A
-:1012600088AF2EF81FB770B9A03F934678A13F759D
-:10127000FB1561449DA8C3D2843A52ADA9270EF252
-:10128000BCB1FD4F66C8735DDB3B66C724AC977588
-:10129000275248B6E3759AFFAA691FFF2EEA7C35EC
-:1012A000C7A517AD31BEC3F97BD5C156CED3AB852B
-:1012B0009FF3F4EA96C1F2D29FE0E0BA48A87E8498
-:1012C000E53B06E9C5ACED522FEE52C50AD839A16F
-:1012D000D5696725C4733C32B04EC6BB2EF5C2C378
-:1012E000885F02298A53A1AD02619E75888B3CE913
-:1012F000329E09FCEE85EC656C57BCD977D0B902FB
-:101300005ABC3B6BC336A31A84CFAC4E59970C849E
-:1013100089F243CC6FF768F041B84A22F27358AFB4
-:10132000B26057030659470D3D47BD562F3A817AA3
-:1013300052E600DE731213A51D135E969F2E83FCEA
-:10134000BECB40E35306D62FC997EB07F2215907CE
-:10135000BB9E5DD94DFC2923FEEC253EA37D9EFC62
-:101360007119D99916F2C780FF95FC315A5F7D0635
-:10137000F7BF58EF64F860FD4D0C1FAA7731DC5EB3
-:101380005FCCEDCBF525DC7F02A87E17FF7BBA1181
-:10139000F2D0051D1B35009F8A0981470D9E7F2ACB
-:1013A00046190C8F52787E76FED38D1ED48B66DA6A
-:1013B00035FD764422FE3A6B9375A8B33659876A99
-:1013C0001DE5BE259FC6CB66ADDD2DF350573AE631
-:1013D00015C42CE0FCB59FF257D8A395F9EE3CF06C
-:1013E000E5F8F1FCD46D6C276D5C073D75F70DD108
-:1013F0005C077C83F271FA746EC6D475D904E74633
-:10140000282CBF642F6E2CD1F34ADA27BF53DEA3FA
-:1014100014AAD565D87FD548DB54D8DFCF5DEEDB85
-:1014200080874EEFA251CB53110F75991CEFA28EFE
-:10143000EBF9BD49209FD2EB7DFABC0E57EEDD588B
-:10144000372B63DCBA29B03BA464B0732EB36801B8
-:101450005E2E43B8B296ED96C3083B70B726C779A7
-:101460000E1917FBCD0E630CEA3761B9B11E5AD7BE
-:10147000A5F1F9B8C6E7131A9FDF429D8CDAB7A928
-:101480001F6D37F5A39D01FA4A7965BA3D91575210
-:10149000C6F22BFA9200EB75C1D9D02F696F92205A
-:1014A000D75B34F94DD0EC4D576E49955CE7E37D41
-:1014B000AAB47ADB05ED1E443FAFBE6E60BDE07698
-:1014C000DE8DC263859D7F49E69D6234C52304CFCE
-:1014D0007B299EED906ABD23F363D2F37953651E99
-:1014E000200E58E4BC04470EF464AD566FEDF51AB7
-:1014F0003C26D4A763BAD363E07F35FDD2E143FF36
-:10150000ADB2BDAE994230B5AF28F27C35F3BAD357
-:101510008761BD6233707DBB498E9FD4F4AF264591
-:10152000DB4F3B8FB0FA92C08FC0E197929610BC10
-:1015300029C2BF4CDA7D7F3ADB6BE14F9F07BBA826
-:10154000F8DE174E8A2B0BA62E318E043D7C3B0114
-:101550005717E42C31DE8CF1D6F7EDC1E3237C493B
-:101560008A1D70B61C1FD1BA7398330836BDF83E79
-:10157000C6CD869C250504CFB1788FD7436E7E2BD0
-:10158000E5CBB6BFED0CE856D521E3F6BCFD6D17F3
-:101590005F845F6E8B74C2BCEFCB4F667AAFEDD8C1
-:1015A000B305F2D6DB2AEF0336B5FC69E7CF799EA7
-:1015B00005D724B4AF2F5BD077561EFDE362E0352C
-:1015C00027DCF705E0878ECE643CE70C977AFDC8F0
-:1015D000D1BC25D0D3DEB6FD3F81FECD89A68016D5
-:1015E000F8BC60E33A44E5810905D0D3DEC8EE8556
-:1015F000D8BFF6798B13725A79203E0FF58143F9E3
-:10160000B21E5E31716B12FCACE1E57DBB7F8EFBDF
-:10161000D5E76D7C2F541723E3BC4AB571DA4AE64F
-:10162000DFAEDD4F03EF7D36BE9FAD40AD8AE08A71
-:10163000DD695CC77FE5EB8F16820F85EA8EDDE8FA
-:10164000FFE2399B017438697645CF801E9E347164
-:10165000BE59A1C115A7864B7CC27B8A987FB15B1E
-:1016600093E0672B87FFF476E03D47DDBA13F98EF0
-:10167000D863E1BB8973FB886EB4EE5CB3690AB8CA
-:10168000DCBB2FD20879B9A06C5DF814F66F96F325
-:101690002ED8B6323D3DCDE305BE47F304ECD6056A
-:1016A00065DBA0FE73CD7BB2908F9E7F7E0EE7A59B
-:1016B000BAFCEAFA52F99C65905F644B40F6A85276
-:1016C000FB5BD83D2282FC6D85069E3FF464EF53A0
-:1016D0006260FDF91693DF4C34AAB08875D6980184
-:1016E0007DA84CBCB518E7AB3434A6236EA998DAB4
-:1016F000B3107A71CE26AC0934EF4DCD6F551E5C18
-:101700003317F1EFF5F0B9A2D9A34B09D27F5D6A87
-:10171000B77983EF2543DBF7EA85FDADB401F8DE49
-:1017200015168EE1F5FDDE34FBAA91A7D5C648FB60
-:10173000F13ECD6F213BF6B5E6EF16AD1E3CBF3F47
-:101740003F86BF5F6BEE4987FFD3F70FE46B7EC325
-:10175000D8930E7B15BA6E0EC211D8911714B6230A
-:101760009507950F54A253A5D5E355411761D6CFE0
-:1017700069BCA2C87509D334BAD3DA0D05C9FCDD3A
-:10178000CA169BCB46EBAAC27AA210175547F6445D
-:1017900021DEE97D59154D1ABB62E334FEA4682CA5
-:1017A0000BAA3756F84C2E5BD6107C46FC44F396B9
-:1017B000E36FFAFE3305297C9EF2F670FE9EB0F7C9
-:1017C0004C839C96EF18BC0EE7B207E95F6FFBAE47
-:1017D000B8E0BC3C45C33BA07CC07A12F8FAC324F5
-:1017E000F0BDD220D6E1FEF23CADC1BD26C1C22A79
-:1017F00061BEF7ACFC6B4418E4E5FCA56AD6DB5E81
-:10180000A587EDDADB0573D92EF59A7AD8AEBD7EC1
-:10181000F42EB60FBDC37A16C24EBD5DB05C8E8F7E
-:10182000EC59E8A0F1FD3A3C46B0DF7FEF680DDBF4
-:101830008F39AA7C57217699ECB21EB4E1543DE76A
-:1018400017264770FE7DBA40ABF70CF087F32E5D8C
-:101850006F7A8563FF41E8617904D775288E6A79CC
-:1018600011F1DE823827DE6B94639D940373F07D63
-:10187000636CCCE565E0CF1DA3DD450539B8DFEC31
-:10188000E13C82A49AFD4DEDEF2C9C4F064C7DBBB4
-:1018900061A7D247BB6717101ED5E6EEF5D984D2F3
-:1018A00045534F174AE4B355698FC41E2957BD9954
-:1018B000BBE43D8D765F79B7467F41494C23E442D6
-:1018C00091FC7DBDFDC05BB02BBDDDE3D81E87EA7A
-:1018D000CDB9F6C7A2601FFE4C7EDC1394EFFF79F2
-:1018E000F11EBE679D8FF720D42E5937581EFABFC0
-:1018F000BA83F33EB125A81F72D830180E9523C8BD
-:10190000A37F90DDF130DDB76B7A5595D75D0B3A4B
-:101910005C85E711AC06C1AF85C021F345898C1306
-:10192000B6C3FF133DAAC7F84F719EBEDF2460C740
-:10193000D792FF62B82DDC8B7CC5B09FFC53ACF412
-:101940004FF00B5551DD5C9FEA6DB3F07DEF431D09
-:101950009F24E1FC24875C87A9EA78290EF9FB3EE5
-:101960002D5F203F18C7EF63DA3AE29077E8FDD5A4
-:10197000065F3AF0A28888E375BDBF46F5A703FF6E
-:101980002AA53B0BE3FBF2EDDA7C8255C082CF51F6
-:10199000AD487D171D2ADBF350BE3DA9C92BD98563
-:1019A0002C7EDFF1B2AC0FE876A042B327AFA13FA7
-:1019B00053EABD5DBF57A2A515D0F721EC43428184
-:1019C0001E17AFE0FACDE3050E096BEB795F595FA7
-:1019D000E2F1DA572E64A564629D362FD80E8D1B76
-:1019E000B02BD0FF04D6FF874C7174AECA9D8A73AA
-:1019F0002DEC54E99A229A2E961B571671DD4C78DD
-:101A0000386F0BC52B548E2617483A551A8615C6C3
-:101A100006ED779E6C7AC214B6337ED89D1FC53E04
-:101A20005A843AC50F4BE5BB81ABFE2658CF719E59
-:101A30001DD28E436DAE18AE95E3E52B1AD7C70FB6
-:101A40008147289E15EEC6A238C7B5FD3ABEE76DA0
-:101A50003A7E79A611C17498BFA66804B5CBADFFD4
-:101A60002C1DE479CF7758FCF0AB15A52BD7470F89
-:101A70002137D7F8831D41FE2B05FCF5F2FDC6F595
-:101A8000F00F6DAB15FF29D48B04E95533EB17E943
-:101A90004B905FB8B920A4EE50BE782CE26AE15EAC
-:101AA0003C167E86F46AA17388FC920CE42803BF7E
-:101AB00019F1701B8ACF5F0AE4BBA49B0BA49E6F35
-:101AC00099E90AC06ECE500D1C8787EEF765818CB0
-:101AD00027BAE322EFD7DF7380D9335449B74443A1
-:101AE000FFDBD0B7C4B84807EE830AF3C3E5BCC335
-:101AF000363BEA3781C397B9BE1B783862BEBC3724
-:101B000088102369BC2B615253B01FF975A13C6F3B
-:101B100078B68C5BEA324C7FBF3E941979B53EC4EF
-:101B200071436638DF97F4B67FCE7E2BD09963C7BA
-:101B3000BD466F376587A44F755FFF571CFC6B6F01
-:101B4000E75FF81D5AEF579FF0FBB48DDAFBC0D763
-:101B5000DAB5F75DDD8E48F4078A3F2AC2BC4D5ADC
-:101B60003B502790F562BDD5F35FBD1E1094078FE3
-:101B70002E1C3A0F8E714704D7091CF143D55582AC
-:101B8000EB04A969B24E801675825493AC130046DB
-:101B90009D002DEA04E8479D0030EA0480512700AB
-:101BA0008C3A015AD409D0FFC57CF95E2640422CFC
-:101BB000EB97116CDFEF6B56BD88CFEF3B2CEFA19D
-:101BC000EE6B54F89DD645FA3EFCDC35EF750E6A97
-:101BD000EF757CDBF85EAFAE4D75825575A6BE63C2
-:101BE000A8EBD4B52ACE35B02FF5F3F9FB1B3B7328
-:101BF000DE2D457FB3C96970804F97E250AFAAECE4
-:101C00006CE6FA5341FC6133F3B74511A897DE65E2
-:101C100091796E8D4ABD53F83E94E3E01A4B37E755
-:101C20001F557B157B59F07DEE4D9FB11D586B8B79
-:101C30006A029E353E9BBD6C88F71F7C2FEC1057C7
-:101C4000EF9B97C929A226A288EF9B97E19E995AFC
-:101C5000A17E65E4FB634A4C87431EF1AE2A03660E
-:101C6000DD2EF53EE43D556567EBFA4471ED3D34FC
-:101C70002A03E07FE8FDB3BB3032F64C380C859880
-:101C80008CB8A9F8F1B2FD6DF4BDFEAD168E3B56D1
-:101C9000E6BB97438E8E995C5C273976D8C6F9D11E
-:101CA000C7DBC60FAA937CEE725717F2FDFC68AE35
-:101CB0005BAC3229EC97F38BC7C5F3BB81E326F607
-:101CC0003F1DAE925ACC5B35C9C1F5A9428BB89F76
-:101CD000F7D1DE6951CBFA54B856F11A085E2C9C44
-:101CE00066E8CF22221BCB8B296203DE532D12F232
-:101CF0007D832E37ABB6291C1770A1200EF7929268
-:101D0000BE8B3AFFED32DE2F2CB5C8F835D120EF6F
-:101D1000B31337C9F72D3F126E33FCED72F28B68A7
-:101D2000C94FFEAE87FADDE1A393647CEE88C7FE5F
-:101D30008B4F98F8BD6F61FCF7D3DDECAF0BF81D4E
-:101D400083E2BF47BD72C3F5F527F41DC33193B4D9
-:101D50002F4447CE8BBA20975C9F71737BA2BE9CA9
-:101D6000DB1933A59DBEFA2E91786407FEE17DEF65
-:101D7000235F4C8C8F74C2DEE97A7FCDFBC430D9EF
-:101D8000EAEF13C7502B82DE276E713978FF44C308
-:101D9000C9A90ED0E3AF114ED0437FA7B86566C97D
-:101DA0002EF0C915253CF82EEE51B6125D8B701041
-:101DB00005756E9F4B45DDFAB062E777D1D7D8C97C
-:101DC0006D0FE31D4F5DAA62571CA8876F2D8C23F2
-:101DD000BC8B529219EFBA76592F650AC5A19EAEF7
-:101DE000E983CBDD563862A07F8EA617BD345FCA6B
-:101DF000C92D5EC8DBB7A8A33E87F91E6173366B99
-:101E0000F91AF83EE786315C4FD5E5A6BF25BE0935
-:101E100072F346A1F433A5A5EF98100774E5BA8FC5
-:101E2000E2FC0BCB3E7B388ECF37741D8BEC28DF6A
-:101E30004B86D6B174BBBC5BAB83C37E1AB53AABE1
-:101E400051ABB31AB53AAB51ABB31AB53AAB51ABD0
-:101E5000B31AB53AAB51ABB31AB53AAB91EB772B9A
-:101E6000B87DBB7E35B7DDF51E1E0FB2FFEF5DC737
-:101E7000FE87D6413FC2BCD03AA8B03AA2D98F92D1
-:101E80007ECBFA7348DDB378F8920D44BFFC06B3FD
-:101E9000135D7A1D14EF97EF8B607B70B170C8FAF9
-:101EA000A74EB708AE97F60BDB14D03F2F639CD13B
-:101EB00040E37FD5F8A0D71FA11F381FF4032DF4EE
-:101EC000C39836A01FCF984985B3A5BFF7B0BFB759
-:101ED000315FD7AF21FB41F052611F643F2E86D89E
-:101EE0000F4A3CEE061ECB3AE5BB26FDFD661E35CD
-:101EF0005F4E19C29EF8A43D1913E6DB87EF8CA94B
-:101F00000DE3F7C1C7B4F758C736CA777165A28425
-:101F1000BF3B845D89023F960EEF7BFF699ABF74D9
-:101F20007304C72DEB472E9BF6BFB12B9F150AA656
-:101F3000DB6FEAFD951F132E056152FE0ACC2203CA
-:101F4000F735C210C67A50A86E51703FBAEA5E31BA
-:101F5000197C2EB094EC009EF1DAFDB688D5EAAD7E
-:101F6000C6EE8A3D049F8C4B74E25E6B74C2218185
-:101F7000F74F8575C599B08BFE31EE09453978BFAD
-:101F8000BC55C1FAF04C79FE3B8AC39B205781C3F4
-:101F9000E373C0EF7916471BEA00CEA284A5C8F30D
-:101FA000E7453B72500770768D9270BCA34D71224D
-:101FB000944D585AC0EFCFAC5B3FB6E2DD9A22A2F7
-:101FC000E95C9661EE1C7CA7A6F85399378B3EF628
-:101FD000633717C9FC6BC46BC28F7BABBE59917C56
-:101FE0007F26321D3918A7B8F2BB45241F7FFC9EFF
-:101FF000EB16AC4FD4F08CC72DA20AAE76DBD09E88
-:10200000D0EEF3BA0CEE52B445511E23F71BBCD9E7
-:1020100068DF34F87E8C7E92E722EC57F4D8E489AE
-:102020001904275A7C6C273B5CAE5BB1FFAB335D78
-:10203000C5180FAD9F83B7C8F3099FDB302FF41D80
-:1020400096CECFA54552EECB8AA4FD98BE56DEC7EC
-:1020500086F2BDACC8A0D9B7BF8F37E15B8AEFE984
-:10206000F88BAD8BB3810FE17B2FF0247C17625C82
-:1020700044C470BDE3FA72E6E1EF951549F9227B9D
-:1020800056F5B1B467DCA61BBDC3103F8EFA857749
-:1020900018F01DD5D867C3BFC378D6D367837F7FB9
-:1020A000F6C13E1BFA9F75C977D2A1FB3716C9F757
-:1020B00013E9D3FB78FD58FA5637C7E97DC31047BB
-:1020C000A5977FBC5EDEBB64B07F19ABF997B1BF4B
-:1020D0004869EF21791BFB6434DF6F8B82581EAF98
-:1020E000B44A3DADFC45D9A1366AC76F277C83E26F
-:1020F000AF095EC27B505C64EC97EF2D09069DF63C
-:102100009A1886CC22BEAA11F2BDE528CD6E206EAB
-:102110002B25BB50537EF432BF03C07AEC8F3B5B60
-:10212000C85FBB49C2E4AE918F2E9FBFA68BF3C39D
-:10213000ED57FBB57CB3753DF2678ADF06F5579620
-:102140001DE982BFA9DA3BB8BF66C5679CC752FCD0
-:1021500036A8FFDE1F7FC0EF6CEADA07F7137F9F18
-:10216000029F75FE1E33F92620DF3B5613E694FFCF
-:102170007EC0B712FADE541DC1EF6777FD3A8FE5D6
-:1021800046E737AD6FFA76F2B196E77BF24406F494
-:10219000E19BDA5ED8A7B441F6C9C375BED9916C8C
-:1021A00077EAB4FCAAB6CCCE7E3EB1D6CAF6AB5026
-:1021B0000D7302AE354A3B238A55CD4EF958FF4F79
-:1021C000DE3E8CEB797C00C03193F8DD71DC5A097E
-:1021D000F78DB0B07D28349454EFA1F6A86105DBEB
-:1021E0008104BCB824BE3F03FBA0427F655DB5CE31
-:1021F000EC53E4FDBE2307F9AE7EDFD4B0D1DB7A29
-:1022000010F9B2E27D7219EA8A7746F0FD4100F5D5
-:10221000463A4FC33069471B16A4B31F088892D2B1
-:10222000958843E68771FDB16198E351DC27365408
-:102230004CE438FAD07F4BBFDB37D7EA441CD530AB
-:10224000D9B106EF551A7EE1E0F15714B99FE75175
-:10225000499F86B9F2FC0D15319CF7E87C686874DB
-:102260008DC4FDD4CC31EEFF00DF4769F7730DC993
-:10227000D44FED134AC9821F619F4912DF19331DE4
-:10228000AC77C7164C7C74B783DD891FF74475B3F0
-:102290002307E5C5FF033C759D8B10370000000048
-:1022A0000000000000000000050207000000000020
-:00000001FF
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index e777961939f..0dbe0d139ac 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -22,6 +22,7 @@
#include <linux/jiffies.h>
#include <linux/file.h>
+#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/fs.h>
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 14d94420457..7317b39b281 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/idr.h>
#include <net/9p/9p.h>
@@ -110,7 +111,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
{
int i, n, l, clone, any, access;
u32 uid;
- struct p9_fid *fid;
+ struct p9_fid *fid, *old_fid = NULL;
struct dentry *d, *ds;
struct v9fs_session_info *v9ses;
char **wnames, *uname;
@@ -151,7 +152,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
if (access == V9FS_ACCESS_SINGLE)
return ERR_PTR(-EPERM);
- if (v9fs_extended(v9ses))
+ if (v9fs_proto_dotu(v9ses))
uname = NULL;
else
uname = v9ses->uname;
@@ -183,10 +184,18 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
l = min(n - i, P9_MAXWELEM);
fid = p9_client_walk(fid, l, &wnames[i], clone);
if (IS_ERR(fid)) {
+ if (old_fid) {
+ /*
+ * If we fail, clunk fid which are mapping
+ * to path component and not the last component
+ * of the path.
+ */
+ p9_client_clunk(old_fid);
+ }
kfree(wnames);
return fid;
}
-
+ old_fid = fid;
i += l;
clone = 0;
}
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 7d6c2139891..f8b86e92cd6 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -29,6 +29,7 @@
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/idr.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
@@ -237,11 +238,18 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
return ERR_PTR(-ENOMEM);
}
+ rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
+ if (rc) {
+ __putname(v9ses->aname);
+ __putname(v9ses->uname);
+ return ERR_PTR(rc);
+ }
+
spin_lock(&v9fs_sessionlist_lock);
list_add(&v9ses->slist, &v9fs_sessionlist);
spin_unlock(&v9fs_sessionlist_lock);
- v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER;
+ v9ses->flags = V9FS_ACCESS_USER;
strcpy(v9ses->uname, V9FS_DEFUSER);
strcpy(v9ses->aname, V9FS_DEFANAME);
v9ses->uid = ~0;
@@ -262,13 +270,15 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
goto error;
}
- if (!v9ses->clnt->dotu)
- v9ses->flags &= ~V9FS_EXTENDED;
+ if (p9_is_proto_dotl(v9ses->clnt))
+ v9ses->flags |= V9FS_PROTO_2000L;
+ else if (p9_is_proto_dotu(v9ses->clnt))
+ v9ses->flags |= V9FS_PROTO_2000U;
v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
/* for legacy mode, fall back to V9FS_ACCESS_ANY */
- if (!v9fs_extended(v9ses) &&
+ if (!v9fs_proto_dotu(v9ses) &&
((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
v9ses->flags &= ~V9FS_ACCESS_MASK;
@@ -298,6 +308,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
return fid;
error:
+ bdi_destroy(&v9ses->bdi);
return ERR_PTR(retval);
}
@@ -323,6 +334,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
__putname(v9ses->uname);
__putname(v9ses->aname);
+ bdi_destroy(&v9ses->bdi);
+
spin_lock(&v9fs_sessionlist_lock);
list_del(&v9ses->slist);
spin_unlock(&v9fs_sessionlist_lock);
@@ -340,6 +353,19 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
p9_client_disconnect(v9ses->clnt);
}
+/**
+ * v9fs_session_begin_cancel - Begin terminate of a session
+ * @v9ses: session to terminate
+ *
+ * After this call we don't allow any request other than clunk.
+ */
+
+void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
+{
+ P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
+ p9_client_begin_disconnect(v9ses->clnt);
+}
+
extern int v9fs_error_init(void);
static struct kobject *v9fs_kobj;
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 019f4ccb70c..bec4d0bcb45 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -20,10 +20,12 @@
* Boston, MA 02111-1301 USA
*
*/
+#include <linux/backing-dev.h>
/**
* enum p9_session_flags - option flags for each 9P session
- * @V9FS_EXTENDED: whether or not to use 9P2000.u extensions
+ * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
+ * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
* @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
* @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
* @V9FS_ACCESS_ANY: use a single attach for all users
@@ -32,11 +34,12 @@
* Session flags reflect options selected by users at mount time
*/
enum p9_session_flags {
- V9FS_EXTENDED = 0x01,
- V9FS_ACCESS_SINGLE = 0x02,
- V9FS_ACCESS_USER = 0x04,
- V9FS_ACCESS_ANY = 0x06,
- V9FS_ACCESS_MASK = 0x06,
+ V9FS_PROTO_2000U = 0x01,
+ V9FS_PROTO_2000L = 0x02,
+ V9FS_ACCESS_SINGLE = 0x04,
+ V9FS_ACCESS_USER = 0x08,
+ V9FS_ACCESS_ANY = 0x0C,
+ V9FS_ACCESS_MASK = 0x0C,
};
/* possible values of ->cache */
@@ -100,12 +103,14 @@ struct v9fs_session_info {
u32 uid; /* if ACCESS_SINGLE, the uid that has access */
struct p9_client *clnt; /* 9p client */
struct list_head slist; /* list of sessions registered with v9fs */
+ struct backing_dev_info bdi;
};
struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
char *);
void v9fs_session_close(struct v9fs_session_info *v9ses);
void v9fs_session_cancel(struct v9fs_session_info *v9ses);
+void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
#define V9FS_MAGIC 0x01021997
@@ -121,7 +126,12 @@ static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
return (inode->i_sb->s_fs_info);
}
-static inline int v9fs_extended(struct v9fs_session_info *v9ses)
+static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
{
- return v9ses->flags & V9FS_EXTENDED;
+ return v9ses->flags & V9FS_PROTO_2000U;
+}
+
+static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
+{
+ return v9ses->flags & V9FS_PROTO_2000L;
}
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index d74325295b1..cbf4e50f393 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -34,6 +34,7 @@
#include <linux/namei.h>
#include <linux/idr.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 15cce53bf61..0adfd64dfce 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -32,6 +32,7 @@
#include <linux/sched.h>
#include <linux/inet.h>
#include <linux/idr.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
@@ -76,6 +77,15 @@ static inline int dt_type(struct p9_wstat *mistat)
return rettype;
}
+static void p9stat_init(struct p9_wstat *stbuf)
+{
+ stbuf->name = NULL;
+ stbuf->uid = NULL;
+ stbuf->gid = NULL;
+ stbuf->muid = NULL;
+ stbuf->extension = NULL;
+}
+
/**
* v9fs_dir_readdir - read a directory
* @filp: opened file structure
@@ -121,6 +131,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
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 = v9fs_file_readn(filp, rdir->buf, NULL,
@@ -131,11 +143,11 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
rdir->head = 0;
rdir->tail = err;
}
-
while (rdir->head < rdir->tail) {
+ p9stat_init(&st);
err = p9stat_read(rdir->buf + rdir->head,
buflen - rdir->head, &st,
- fid->clnt->dotu);
+ fid->clnt->proto_version);
if (err) {
P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err);
err = -EIO;
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 74a0461a9ac..df52d488d2a 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -61,7 +61,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file);
v9ses = v9fs_inode2v9ses(inode);
- omode = v9fs_uflags2omode(file->f_flags, v9fs_extended(v9ses));
+ omode = v9fs_uflags2omode(file->f_flags, v9fs_proto_dotu(v9ses));
fid = file->private_data;
if (!fid) {
fid = v9fs_fid_clone(file->f_path.dentry);
@@ -77,7 +77,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
i_size_write(inode, 0);
inode->i_blocks = 0;
}
- if ((file->f_flags & O_APPEND) && (!v9fs_extended(v9ses)))
+ if ((file->f_flags & O_APPEND) && (!v9fs_proto_dotu(v9ses)))
generic_file_llseek(file, 0, SEEK_END);
}
@@ -114,7 +114,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
/* No mandatory locks */
- if (__mandatory_lock(inode))
+ if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
return -ENOLCK;
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
@@ -215,7 +215,7 @@ v9fs_file_write(struct file *filp, const char __user * data,
struct p9_fid *fid;
struct p9_client *clnt;
struct inode *inode = filp->f_path.dentry->d_inode;
- int origin = *offset;
+ loff_t origin = *offset;
unsigned long pg_start, pg_end;
P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index a407fa3388c..f2434fc9d2c 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -34,6 +34,7 @@
#include <linux/namei.h>
#include <linux/idr.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
@@ -60,7 +61,7 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
res = mode & 0777;
if (S_ISDIR(mode))
res |= P9_DMDIR;
- if (v9fs_extended(v9ses)) {
+ if (v9fs_proto_dotu(v9ses)) {
if (S_ISLNK(mode))
res |= P9_DMSYMLINK;
if (v9ses->nodev == 0) {
@@ -102,21 +103,21 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
if ((mode & P9_DMDIR) == P9_DMDIR)
res |= S_IFDIR;
- else if ((mode & P9_DMSYMLINK) && (v9fs_extended(v9ses)))
+ else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses)))
res |= S_IFLNK;
- else if ((mode & P9_DMSOCKET) && (v9fs_extended(v9ses))
+ else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFSOCK;
- else if ((mode & P9_DMNAMEDPIPE) && (v9fs_extended(v9ses))
+ else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFIFO;
- else if ((mode & P9_DMDEVICE) && (v9fs_extended(v9ses))
+ else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFBLK;
else
res |= S_IFREG;
- if (v9fs_extended(v9ses)) {
+ if (v9fs_proto_dotu(v9ses)) {
if ((mode & P9_DMSETUID) == P9_DMSETUID)
res |= S_ISUID;
@@ -265,7 +266,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
case S_IFBLK:
case S_IFCHR:
case S_IFSOCK:
- if (!v9fs_extended(v9ses)) {
+ if (!v9fs_proto_dotu(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR,
"special files without extended mode\n");
err = -EINVAL;
@@ -278,7 +279,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
inode->i_fop = &v9fs_file_operations;
break;
case S_IFLNK:
- if (!v9fs_extended(v9ses)) {
+ if (!v9fs_proto_dotu(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR,
"extended modes used w/o 9P2000.u\n");
err = -EINVAL;
@@ -288,7 +289,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
break;
case S_IFDIR:
inc_nlink(inode);
- if (v9fs_extended(v9ses))
+ if (v9fs_proto_dotu(v9ses))
inode->i_op = &v9fs_dir_inode_operations_ext;
else
inode->i_op = &v9fs_dir_inode_operations;
@@ -431,6 +432,7 @@ error:
static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
{
+ int retval;
struct inode *file_inode;
struct v9fs_session_info *v9ses;
struct p9_fid *v9fid;
@@ -444,7 +446,10 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
if (IS_ERR(v9fid))
return PTR_ERR(v9fid);
- return p9_client_remove(v9fid);
+ retval = p9_client_remove(v9fid);
+ if (!retval)
+ drop_nlink(file_inode);
+ return retval;
}
static int
@@ -575,7 +580,8 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
flags = O_RDWR;
fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
- v9fs_uflags2omode(flags, v9fs_extended(v9ses)));
+ v9fs_uflags2omode(flags,
+ v9fs_proto_dotu(v9ses)));
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
fid = NULL;
@@ -655,6 +661,9 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
dir, dentry->d_name.name, dentry, nameidata);
+ if (dentry->d_name.len > NAME_MAX)
+ return ERR_PTR(-ENAMETOOLONG);
+
sb = dir->i_sb;
v9ses = v9fs_inode2v9ses(dir);
dfid = v9fs_fid_lookup(dentry->d_parent);
@@ -858,7 +867,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
if (iattr->ia_valid & ATTR_SIZE)
wstat.length = iattr->ia_size;
- if (v9fs_extended(v9ses)) {
+ if (v9fs_proto_dotu(v9ses)) {
if (iattr->ia_valid & ATTR_UID)
wstat.n_uid = iattr->ia_uid;
@@ -886,6 +895,8 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
struct super_block *sb)
{
char ext[32];
+ char tag_name[14];
+ unsigned int i_nlink;
struct v9fs_session_info *v9ses = sb->s_fs_info;
inode->i_nlink = 1;
@@ -897,11 +908,26 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
inode->i_uid = v9ses->dfltuid;
inode->i_gid = v9ses->dfltgid;
- if (v9fs_extended(v9ses)) {
+ if (v9fs_proto_dotu(v9ses)) {
inode->i_uid = stat->n_uid;
inode->i_gid = stat->n_gid;
}
-
+ if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) {
+ if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) {
+ /*
+ * Hadlink support got added later to
+ * to the .u extension. So there can be
+ * server out there that doesn't support
+ * this even with .u extension. So check
+ * for non NULL stat->extension
+ */
+ strncpy(ext, stat->extension, sizeof(ext));
+ /* HARDLINKCOUNT %u */
+ sscanf(ext, "%13s %u", tag_name, &i_nlink);
+ if (!strncmp(tag_name, "HARDLINKCOUNT", 13))
+ inode->i_nlink = i_nlink;
+ }
+ }
inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
char type = 0;
@@ -976,7 +1002,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
if (IS_ERR(fid))
return PTR_ERR(fid);
- if (!v9fs_extended(v9ses))
+ if (!v9fs_proto_dotu(v9ses))
return -EBADF;
st = p9_client_stat(fid);
@@ -1066,7 +1092,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
struct p9_fid *fid;
v9ses = v9fs_inode2v9ses(dir);
- if (!v9fs_extended(v9ses)) {
+ if (!v9fs_proto_dotu(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n");
return -EPERM;
}
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 69357c0d989..806da5d3b3a 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -37,6 +37,7 @@
#include <linux/mount.h>
#include <linux/idr.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
@@ -76,6 +77,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
sb->s_blocksize = 1 << sb->s_blocksize_bits;
sb->s_magic = V9FS_MAGIC;
sb->s_op = &v9fs_super_ops;
+ sb->s_bdi = &v9ses->bdi;
sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
MS_NOATIME;
@@ -193,6 +195,7 @@ static void v9fs_kill_super(struct super_block *s)
kill_anon_super(s);
+ v9fs_session_cancel(v9ses);
v9fs_session_close(v9ses);
kfree(v9ses);
s->s_fs_info = NULL;
@@ -205,7 +208,7 @@ v9fs_umount_begin(struct super_block *sb)
struct v9fs_session_info *v9ses;
v9ses = sb->s_fs_info;
- v9fs_session_cancel(v9ses);
+ v9fs_session_begin_cancel(v9ses);
}
static const struct super_operations v9fs_super_ops = {
diff --git a/fs/Kconfig b/fs/Kconfig
index 64d44efad7a..5f85b594761 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -177,6 +177,7 @@ source "fs/efs/Kconfig"
source "fs/jffs2/Kconfig"
# UBIFS File system configuration
source "fs/ubifs/Kconfig"
+source "fs/logfs/Kconfig"
source "fs/cramfs/Kconfig"
source "fs/squashfs/Kconfig"
source "fs/freevxfs/Kconfig"
@@ -234,6 +235,7 @@ config NFS_COMMON
source "net/sunrpc/Kconfig"
source "fs/smbfs/Kconfig"
+source "fs/ceph/Kconfig"
source "fs/cifs/Kconfig"
source "fs/ncpfs/Kconfig"
source "fs/coda/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index af6d04700d9..97f340f14ba 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs/
obj-$(CONFIG_UFS_FS) += ufs/
obj-$(CONFIG_EFS_FS) += efs/
obj-$(CONFIG_JFFS2_FS) += jffs2/
+obj-$(CONFIG_LOGFS) += logfs/
obj-$(CONFIG_UBIFS_FS) += ubifs/
obj-$(CONFIG_AFFS_FS) += affs/
obj-$(CONFIG_ROMFS_FS) += romfs/
@@ -124,3 +125,4 @@ obj-$(CONFIG_OCFS2_FS) += ocfs2/
obj-$(CONFIG_BTRFS_FS) += btrfs/
obj-$(CONFIG_GFS2_FS) += gfs2/
obj-$(CONFIG_EXOFS_FS) += exofs/
+obj-$(CONFIG_CEPH_FS) += ceph/
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index 9cc18775b83..2ff622f6f54 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -121,7 +121,7 @@ struct adfs_discmap {
/* Inode stuff */
struct inode *adfs_iget(struct super_block *sb, struct object_info *obj);
-int adfs_write_inode(struct inode *inode,int unused);
+int adfs_write_inode(struct inode *inode, struct writeback_control *wbc);
int adfs_notify_change(struct dentry *dentry, struct iattr *attr);
/* map.c */
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index 3f57ce4bee5..0f5e3097813 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -9,6 +9,7 @@
*/
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
+#include <linux/writeback.h>
#include "adfs.h"
/*
@@ -360,7 +361,7 @@ out:
* The adfs-specific inode data has already been updated by
* adfs_notify_change()
*/
-int adfs_write_inode(struct inode *inode, int wait)
+int adfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct super_block *sb = inode->i_sb;
struct object_info obj;
@@ -375,7 +376,7 @@ int adfs_write_inode(struct inode *inode, int wait)
obj.attr = ADFS_I(inode)->attr;
obj.size = inode->i_size;
- ret = adfs_dir_update(sb, &obj, wait);
+ ret = adfs_dir_update(sb, &obj, wbc->sync_mode == WB_SYNC_ALL);
unlock_kernel();
return ret;
}
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 6910a98bd73..4a3af7075c1 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -13,6 +13,7 @@
#include <linux/parser.h>
#include <linux/mount.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/statfs.h>
#include "adfs.h"
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index 0e40caaba45..861dae68ac1 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -175,7 +175,8 @@ extern void affs_delete_inode(struct inode *inode);
extern void affs_clear_inode(struct inode *inode);
extern struct inode *affs_iget(struct super_block *sb,
unsigned long ino);
-extern int affs_write_inode(struct inode *inode, int);
+extern int affs_write_inode(struct inode *inode,
+ struct writeback_control *wbc);
extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type);
/* file.c */
diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c
index dc5ef14bdc1..3e262711ae0 100644
--- a/fs/affs/bitmap.c
+++ b/fs/affs/bitmap.c
@@ -7,6 +7,7 @@
* block allocation, deallocation, calculation of free space.
*/
+#include <linux/slab.h>
#include "affs.h"
/* This is, of course, shamelessly stolen from fs/minix */
@@ -128,7 +129,7 @@ err_range:
/*
* Allocate a block in the given allocation zone.
* Since we have to byte-swap the bitmap on little-endian
- * machines, this is rather expensive. Therefor we will
+ * machines, this is rather expensive. Therefore we will
* preallocate up to 16 blocks from the same word, if
* possible. We are not doing preallocations in the
* header zone, though.
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 3c4ec7d864c..f4b2a4ee4f9 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -10,6 +10,7 @@
* (C) 1991 Linus Torvalds - minix filesystem
*/
#include <linux/sched.h>
+#include <linux/gfp.h>
#include "affs.h"
extern const struct inode_operations affs_symlink_inode_operations;
@@ -166,7 +167,7 @@ bad_inode:
}
int
-affs_write_inode(struct inode *inode, int unused)
+affs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct super_block *sb = inode->i_sb;
struct buffer_head *bh;
diff --git a/fs/affs/super.c b/fs/affs/super.c
index d41e9673cd9..16a3e4765f6 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -17,6 +17,7 @@
#include <linux/magic.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include "affs.h"
extern struct timezone sys_tz;
diff --git a/fs/afs/cache.c b/fs/afs/cache.c
index e2b1d3f1651..0fb315dd4d2 100644
--- a/fs/afs/cache.c
+++ b/fs/afs/cache.c
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/slab.h>
#include <linux/sched.h>
#include "internal.h"
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index eb765489164..a3bcec75c54 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/ip.h>
#include "internal.h"
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 88067f36e5e..adc1cb771b5 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/ctype.h>
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 39b301662f2..0df9bc2b724 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -12,10 +12,10 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/writeback.h>
+#include <linux/gfp.h>
#include "internal.h"
static int afs_readpage(struct file *file, struct page *page);
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 023b95b0d9d..4bd0218473a 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -10,6 +10,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/circ_buf.h>
#include "internal.h"
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index c048f065875..d00b312e311 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/sched.h>
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 6ece2a13bf7..a10f2582844 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -19,6 +19,7 @@
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/fscache.h>
+#include <linux/backing-dev.h>
#include "afs.h"
#include "afs_vl.h"
@@ -313,6 +314,7 @@ struct afs_volume {
unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */
struct afs_server *servers[8]; /* servers on which volume resides (ordered) */
struct rw_semaphore server_sem; /* lock for accessing current server */
+ struct backing_dev_info bdi;
};
/*
@@ -733,7 +735,6 @@ extern int afs_write_end(struct file *file, struct address_space *mapping,
struct page *page, void *fsdata);
extern int afs_writepage(struct page *, struct writeback_control *);
extern int afs_writepages(struct address_space *, struct writeback_control *);
-extern int afs_write_inode(struct inode *, int);
extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
extern ssize_t afs_file_write(struct kiocb *, const struct iovec *,
unsigned long, loff_t);
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 5ffb570cd3a..b3feddc4f7d 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -12,11 +12,11 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/namei.h>
+#include <linux/gfp.h>
#include "internal.h"
@@ -138,9 +138,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
{
struct afs_super_info *super;
struct vfsmount *mnt;
- struct page *page = NULL;
+ struct page *page;
size_t size;
- char *buf, *devname = NULL, *options = NULL;
+ char *buf, *devname, *options;
int ret;
_enter("{%s}", mntpt->d_name.name);
@@ -150,22 +150,22 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
ret = -EINVAL;
size = mntpt->d_inode->i_size;
if (size > PAGE_SIZE - 1)
- goto error;
+ goto error_no_devname;
ret = -ENOMEM;
devname = (char *) get_zeroed_page(GFP_KERNEL);
if (!devname)
- goto error;
+ goto error_no_devname;
options = (char *) get_zeroed_page(GFP_KERNEL);
if (!options)
- goto error;
+ goto error_no_options;
/* read the contents of the AFS special symlink */
page = read_mapping_page(mntpt->d_inode->i_mapping, 0, NULL);
if (IS_ERR(page)) {
ret = PTR_ERR(page);
- goto error;
+ goto error_no_page;
}
ret = -EIO;
@@ -196,12 +196,12 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
return mnt;
error:
- if (page)
- page_cache_release(page);
- if (devname)
- free_page((unsigned long) devname);
- if (options)
- free_page((unsigned long) options);
+ page_cache_release(page);
+error_no_page:
+ free_page((unsigned long) options);
+error_no_options:
+ free_page((unsigned long) devname);
+error_no_devname:
_leave(" = %d", ret);
return ERR_PTR(ret);
}
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index bde3f19c099..67cf810e0fd 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -9,6 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <rxrpc/packet.h>
diff --git a/fs/afs/security.c b/fs/afs/security.c
index 3ef50437003..bb4ed144d0e 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -189,8 +189,9 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, long acl_order)
if (!permits)
goto out_unlock;
- memcpy(permits->permits, xpermits->permits,
- count * sizeof(struct afs_permit));
+ if (xpermits)
+ memcpy(permits->permits, xpermits->permits,
+ count * sizeof(struct afs_permit));
_debug("key %x access %x",
key_serial(key), vnode->status.caller_access);
diff --git a/fs/afs/super.c b/fs/afs/super.c
index e1ea1c240b6..e932e5a3a0c 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -48,7 +48,6 @@ struct file_system_type afs_fs_type = {
static const struct super_operations afs_super_ops = {
.statfs = afs_statfs,
.alloc_inode = afs_alloc_inode,
- .write_inode = afs_write_inode,
.destroy_inode = afs_destroy_inode,
.clear_inode = afs_clear_inode,
.put_super = afs_put_super,
@@ -312,6 +311,7 @@ static int afs_fill_super(struct super_block *sb, void *data)
sb->s_magic = AFS_FS_MAGIC;
sb->s_op = &afs_super_ops;
sb->s_fs_info = as;
+ sb->s_bdi = &as->volume->bdi;
/* allocate the root inode and dentry */
fid.vid = as->volume->vid;
diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c
index 36c1306e09e..340afd0cd18 100644
--- a/fs/afs/vlclient.c
+++ b/fs/afs/vlclient.c
@@ -9,6 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/sched.h>
#include "internal.h"
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c
index 6e689208def..9ac260d1361 100644
--- a/fs/afs/vlocation.c
+++ b/fs/afs/vlocation.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/sched.h>
#include "internal.h"
diff --git a/fs/afs/vnode.c b/fs/afs/vnode.c
index 2f05c4fc2a7..25cf4c3f4ff 100644
--- a/fs/afs/vnode.c
+++ b/fs/afs/vnode.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include "internal.h"
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index a353e69e239..401eeb21869 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -106,6 +106,10 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
volume->cell = params->cell;
volume->vid = vlocation->vldb.vid[params->type];
+ ret = bdi_setup_and_register(&volume->bdi, "afs", BDI_CAP_MAP_COPY);
+ if (ret)
+ goto error_bdi;
+
init_rwsem(&volume->server_sem);
/* look up all the applicable server records */
@@ -151,6 +155,8 @@ error:
return ERR_PTR(ret);
error_discard:
+ bdi_destroy(&volume->bdi);
+error_bdi:
up_write(&params->cell->vl_sem);
for (loop = volume->nservers - 1; loop >= 0; loop--)
@@ -200,6 +206,7 @@ void afs_put_volume(struct afs_volume *volume)
for (loop = volume->nservers - 1; loop >= 0; loop--)
afs_put_server(volume->servers[loop]);
+ bdi_destroy(&volume->bdi);
kfree(volume);
_leave(" [destroyed]");
diff --git a/fs/afs/write.c b/fs/afs/write.c
index 5e15a21dbf9..3bed54a294d 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -585,27 +585,6 @@ int afs_writepages(struct address_space *mapping,
}
/*
- * write an inode back
- */
-int afs_write_inode(struct inode *inode, int sync)
-{
- struct afs_vnode *vnode = AFS_FS_I(inode);
- int ret;
-
- _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
-
- ret = 0;
- if (sync) {
- ret = filemap_fdatawait(inode->i_mapping);
- if (ret < 0)
- __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
- }
-
- _leave(" = %d", ret);
- return ret;
-}
-
-/*
* completion of write to server
*/
void afs_pages_written_back(struct afs_vnode *vnode, struct afs_call *call)
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index 9f0bf13291e..e4b75d6eda8 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -12,7 +12,6 @@
#include <linux/file.h>
#include <linux/poll.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/mount.h>
@@ -209,6 +208,7 @@ static struct inode *anon_inode_mkinode(void)
inode->i_mode = S_IRUSR | S_IWUSR;
inode->i_uid = current_fsuid();
inode->i_gid = current_fsgid();
+ inode->i_flags |= S_PRIVATE;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
return inode;
}
diff --git a/fs/attr.c b/fs/attr.c
index 96d394bdadd..0815e93bb48 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -12,7 +12,6 @@
#include <linux/capability.h>
#include <linux/fsnotify.h>
#include <linux/fcntl.h>
-#include <linux/quotaops.h>
#include <linux/security.h>
/* Taken over from the old code... */
@@ -82,7 +81,7 @@ int inode_newsize_ok(const struct inode *inode, loff_t offset)
if (inode->i_size < offset) {
unsigned long limit;
- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+ limit = rlimit(RLIMIT_FSIZE);
if (limit != RLIM_INFINITY && offset > limit)
goto out_sig;
if (offset > inode->i_sb->s_maxbytes)
@@ -212,14 +211,8 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
error = inode->i_op->setattr(dentry, attr);
} else {
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 = vfs_dq_transfer(inode, attr) ?
- -EDQUOT : 0;
- if (!error)
- error = inode_setattr(inode, attr);
- }
+ if (!error)
+ error = inode_setattr(inode, attr);
}
if (ia_valid & ATTR_SIZE)
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index 4a1401cea0a..8713c7cfbc7 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -13,6 +13,7 @@
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/stat.h>
+#include <linux/slab.h>
#include <linux/param.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index c8a80dffb45..d29b7f6df86 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -22,6 +22,7 @@
#include <linux/magic.h>
#include <linux/dcache.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include "autofs_i.h"
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index a015b49891d..109a6c606d9 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -15,6 +15,7 @@
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/stat.h>
+#include <linux/slab.h>
#include <linux/param.h>
#include <linux/time.h>
#include "autofs_i.h"
diff --git a/fs/befs/datastream.c b/fs/befs/datastream.c
index e3287d0d1a5..59096b5e0fc 100644
--- a/fs/befs/datastream.c
+++ b/fs/befs/datastream.c
@@ -11,7 +11,6 @@
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/buffer_head.h>
#include <linux/string.h>
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 8f3d9fd8960..f22a7d3dc36 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -15,6 +15,7 @@
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
+#include <linux/writeback.h>
#include <asm/uaccess.h>
#include "bfs.h"
@@ -98,7 +99,7 @@ error:
return ERR_PTR(-EIO);
}
-static int bfs_write_inode(struct inode *inode, int wait)
+static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct bfs_sb_info *info = BFS_SB(inode->i_sb);
unsigned int ino = (u16)inode->i_ino;
@@ -147,7 +148,7 @@ static int bfs_write_inode(struct inode *inode, int wait)
di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
mark_buffer_dirty(bh);
- if (wait) {
+ if (wbc->sync_mode == WB_SYNC_ALL) {
sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh))
err = -EIO;
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index fdd39709917..f96eff04e11 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -20,10 +20,11 @@
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/user.h>
-#include <linux/slab.h>
#include <linux/binfmts.h>
#include <linux/personality.h>
#include <linux/init.h>
+#include <linux/coredump.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -60,26 +61,6 @@ static int set_brk(unsigned long start, unsigned long end)
}
/*
- * These are the only things you should do on a core-file: use only these
- * macros to write out all the necessary info.
- */
-
-static int dump_write(struct file *file, const void *addr, int nr)
-{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
-
-#define DUMP_WRITE(addr, nr) \
- if (!dump_write(file, (void *)(addr), (nr))) \
- goto end_coredump;
-
-#define DUMP_SEEK(offset) \
-if (file->f_op->llseek) { \
- if (file->f_op->llseek(file,(offset),0) != (offset)) \
- goto end_coredump; \
-} else file->f_pos = (offset)
-
-/*
* Routine writes a core dump image in the current directory.
* Currently only a stub-function.
*
@@ -94,14 +75,16 @@ static int aout_core_dump(struct coredump_params *cprm)
struct file *file = cprm->file;
mm_segment_t fs;
int has_dumped = 0;
- unsigned long dump_start, dump_size;
+ void __user *dump_start;
+ int dump_size;
struct user dump;
#ifdef __alpha__
-# define START_DATA(u) (u.start_data)
+# define START_DATA(u) ((void __user *)u.start_data)
#else
-# define START_DATA(u) ((u.u_tsize << PAGE_SHIFT) + u.start_code)
+# define START_DATA(u) ((void __user *)((u.u_tsize << PAGE_SHIFT) + \
+ u.start_code))
#endif
-# define START_STACK(u) (u.start_stack)
+# define START_STACK(u) ((void __user *)u.start_stack)
fs = get_fs();
set_fs(KERNEL_DS);
@@ -123,33 +106,38 @@ static int aout_core_dump(struct coredump_params *cprm)
/* make sure we actually have a data and stack area to dump */
set_fs(USER_DS);
- if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
+ if (!access_ok(VERIFY_READ, START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
dump.u_dsize = 0;
- if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
+ if (!access_ok(VERIFY_READ, START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
dump.u_ssize = 0;
set_fs(KERNEL_DS);
/* struct user */
- DUMP_WRITE(&dump,sizeof(dump));
+ if (!dump_write(file, &dump, sizeof(dump)))
+ goto end_coredump;
/* Now dump all of the user data. Include malloced stuff as well */
- DUMP_SEEK(PAGE_SIZE);
+ if (!dump_seek(cprm->file, PAGE_SIZE - sizeof(dump)))
+ goto end_coredump;
/* now we start writing out the user space info */
set_fs(USER_DS);
/* Dump the data area */
if (dump.u_dsize != 0) {
dump_start = START_DATA(dump);
dump_size = dump.u_dsize << PAGE_SHIFT;
- DUMP_WRITE(dump_start,dump_size);
+ if (!dump_write(file, dump_start, dump_size))
+ goto end_coredump;
}
/* Now prepare to dump the stack area */
if (dump.u_ssize != 0) {
dump_start = START_STACK(dump);
dump_size = dump.u_ssize << PAGE_SHIFT;
- DUMP_WRITE(dump_start,dump_size);
+ if (!dump_write(file, dump_start, dump_size))
+ goto end_coredump;
}
/* Finally dump the task struct. Not be used by gdb, but could be useful */
set_fs(KERNEL_DS);
- DUMP_WRITE(current,sizeof(*current));
+ if (!dump_write(file, current, sizeof(*current)))
+ goto end_coredump;
end_coredump:
set_fs(fs);
return has_dumped;
@@ -247,7 +235,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
* size limits imposed on them by creating programs with large
* arrays in the data or bss.
*/
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+ rlim = rlimit(RLIMIT_DATA);
if (rlim >= RLIM_INFINITY)
rlim = ~0;
if (ex.a_data + ex.a_bss > rlim)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index fd5b2ea5d29..535e763ab1a 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -31,6 +31,7 @@
#include <linux/random.h>
#include <linux/elf.h>
#include <linux/utsname.h>
+#include <linux/coredump.h>
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/page.h>
@@ -1085,36 +1086,6 @@ out:
* Modelled on fs/exec.c:aout_core_dump()
* Jeremy Fitzhardinge <jeremy@sw.oz.au>
*/
-/*
- * These are the only things you should do on a core-file: use only these
- * functions to write out all the necessary info.
- */
-static int dump_write(struct file *file, const void *addr, int nr)
-{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
-
-static int dump_seek(struct file *file, loff_t off)
-{
- if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
- if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
- return 0;
- } else {
- char *buf = (char *)get_zeroed_page(GFP_KERNEL);
- if (!buf)
- return 0;
- while (off > 0) {
- unsigned long n = off;
- if (n > PAGE_SIZE)
- n = PAGE_SIZE;
- if (!dump_write(file, buf, n))
- return 0;
- off -= n;
- }
- free_page((unsigned long)buf);
- }
- return 1;
-}
/*
* Decide what to dump of a segment, part, all or none.
@@ -1249,11 +1220,6 @@ static int writenote(struct memelfnote *men, struct file *file,
}
#undef DUMP_WRITE
-#define DUMP_WRITE(addr, nr) \
- if ((size += (nr)) > cprm->limit || \
- !dump_write(cprm->file, (addr), (nr))) \
- goto end_coredump;
-
static void fill_elf_header(struct elfhdr *elf, int segs,
u16 machine, u32 flags, u8 osabi)
{
@@ -1872,6 +1838,34 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
return gate_vma;
}
+static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
+ elf_addr_t e_shoff, int segs)
+{
+ elf->e_shoff = e_shoff;
+ elf->e_shentsize = sizeof(*shdr4extnum);
+ elf->e_shnum = 1;
+ elf->e_shstrndx = SHN_UNDEF;
+
+ memset(shdr4extnum, 0, sizeof(*shdr4extnum));
+
+ shdr4extnum->sh_type = SHT_NULL;
+ shdr4extnum->sh_size = elf->e_shnum;
+ shdr4extnum->sh_link = elf->e_shstrndx;
+ shdr4extnum->sh_info = segs;
+}
+
+static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
+ unsigned long mm_flags)
+{
+ struct vm_area_struct *vma;
+ size_t size = 0;
+
+ for (vma = first_vma(current, gate_vma); vma != NULL;
+ vma = next_vma(vma, gate_vma))
+ size += vma_dump_size(vma, mm_flags);
+ return size;
+}
+
/*
* Actual dumper
*
@@ -1888,8 +1882,11 @@ static int elf_core_dump(struct coredump_params *cprm)
struct vm_area_struct *vma, *gate_vma;
struct elfhdr *elf = NULL;
loff_t offset = 0, dataoff, foffset;
- unsigned long mm_flags;
struct elf_note_info info;
+ struct elf_phdr *phdr4note = NULL;
+ struct elf_shdr *shdr4extnum = NULL;
+ Elf_Half e_phnum;
+ elf_addr_t e_shoff;
/*
* We no longer stop all VM operations.
@@ -1912,20 +1909,25 @@ static int elf_core_dump(struct coredump_params *cprm)
* Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
*/
segs = current->mm->map_count;
-#ifdef ELF_CORE_EXTRA_PHDRS
- segs += ELF_CORE_EXTRA_PHDRS;
-#endif
+ segs += elf_core_extra_phdrs();
gate_vma = get_gate_vma(current);
if (gate_vma != NULL)
segs++;
+ /* for notes section */
+ segs++;
+
+ /* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
+ * this, kernel supports extended numbering. Have a look at
+ * include/linux/elf.h for further information. */
+ e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
+
/*
* Collect all the non-memory information about the process for the
* notes. This also sets up the file header.
*/
- if (!fill_note_info(elf, segs + 1, /* including notes section */
- &info, cprm->signr, cprm->regs))
+ if (!fill_note_info(elf, e_phnum, &info, cprm->signr, cprm->regs))
goto cleanup;
has_dumped = 1;
@@ -1934,31 +1936,47 @@ static int elf_core_dump(struct coredump_params *cprm)
fs = get_fs();
set_fs(KERNEL_DS);
- DUMP_WRITE(elf, sizeof(*elf));
offset += sizeof(*elf); /* Elf header */
- offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */
+ offset += segs * sizeof(struct elf_phdr); /* Program headers */
foffset = offset;
/* Write notes phdr entry */
{
- struct elf_phdr phdr;
size_t sz = get_note_info_size(&info);
sz += elf_coredump_extra_notes_size();
- fill_elf_note_phdr(&phdr, sz, offset);
+ phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
+ if (!phdr4note)
+ goto end_coredump;
+
+ fill_elf_note_phdr(phdr4note, sz, offset);
offset += sz;
- DUMP_WRITE(&phdr, sizeof(phdr));
}
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
- /*
- * We must use the same mm->flags while dumping core to avoid
- * inconsistency between the program headers and bodies, otherwise an
- * unusable core file can be generated.
- */
- mm_flags = current->mm->flags;
+ offset += elf_core_vma_data_size(gate_vma, cprm->mm_flags);
+ offset += elf_core_extra_data_size();
+ e_shoff = offset;
+
+ if (e_phnum == PN_XNUM) {
+ shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
+ if (!shdr4extnum)
+ goto end_coredump;
+ fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
+ }
+
+ offset = dataoff;
+
+ size += sizeof(*elf);
+ if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
+ goto end_coredump;
+
+ size += sizeof(*phdr4note);
+ if (size > cprm->limit
+ || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
+ goto end_coredump;
/* Write program headers for segments dump */
for (vma = first_vma(current, gate_vma); vma != NULL;
@@ -1969,7 +1987,7 @@ static int elf_core_dump(struct coredump_params *cprm)
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
- phdr.p_filesz = vma_dump_size(vma, mm_flags);
+ phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags);
phdr.p_memsz = vma->vm_end - vma->vm_start;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -1979,12 +1997,14 @@ static int elf_core_dump(struct coredump_params *cprm)
phdr.p_flags |= PF_X;
phdr.p_align = ELF_EXEC_PAGESIZE;
- DUMP_WRITE(&phdr, sizeof(phdr));
+ size += sizeof(phdr);
+ if (size > cprm->limit
+ || !dump_write(cprm->file, &phdr, sizeof(phdr)))
+ goto end_coredump;
}
-#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
- ELF_CORE_WRITE_EXTRA_PHDRS;
-#endif
+ if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
+ goto end_coredump;
/* write out the notes section */
if (!write_note_info(&info, cprm->file, &foffset))
@@ -2002,7 +2022,7 @@ static int elf_core_dump(struct coredump_params *cprm)
unsigned long addr;
unsigned long end;
- end = vma->vm_start + vma_dump_size(vma, mm_flags);
+ end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags);
for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
struct page *page;
@@ -2023,15 +2043,24 @@ static int elf_core_dump(struct coredump_params *cprm)
}
}
-#ifdef ELF_CORE_WRITE_EXTRA_DATA
- ELF_CORE_WRITE_EXTRA_DATA;
-#endif
+ if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
+ goto end_coredump;
+
+ if (e_phnum == PN_XNUM) {
+ size += sizeof(*shdr4extnum);
+ if (size > cprm->limit
+ || !dump_write(cprm->file, shdr4extnum,
+ sizeof(*shdr4extnum)))
+ goto end_coredump;
+ }
end_coredump:
set_fs(fs);
cleanup:
free_note_info(&info);
+ kfree(shdr4extnum);
+ kfree(phdr4note);
kfree(elf);
out:
return has_dumped;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 18d77297ccc..2c5f9a0e5d7 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -34,6 +34,7 @@
#include <linux/elf.h>
#include <linux/elf-fdpic.h>
#include <linux/elfcore.h>
+#include <linux/coredump.h>
#include <asm/uaccess.h>
#include <asm/param.h>
@@ -1004,15 +1005,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
}
} else if (!mm->start_data) {
mm->start_data = seg->addr;
-#ifndef CONFIG_MMU
mm->end_data = seg->addr + phdr->p_memsz;
-#endif
}
-
-#ifdef CONFIG_MMU
- if (seg->addr + phdr->p_memsz > mm->end_data)
- mm->end_data = seg->addr + phdr->p_memsz;
-#endif
}
seg++;
@@ -1216,26 +1210,6 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
#ifdef CONFIG_ELF_CORE
/*
- * These are the only things you should do on a core-file: use only these
- * functions to write out all the necessary info.
- */
-static int dump_write(struct file *file, const void *addr, int nr)
-{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
-
-static int dump_seek(struct file *file, loff_t off)
-{
- if (file->f_op->llseek) {
- if (file->f_op->llseek(file, off, SEEK_SET) != off)
- return 0;
- } else {
- file->f_pos = off;
- }
- return 1;
-}
-
-/*
* Decide whether a segment is worth dumping; default is yes to be
* sure (missing info is worse than too much; etc).
* Personally I'd include everything, and use the coredump limit...
@@ -1313,35 +1287,35 @@ static int notesize(struct memelfnote *en)
/* #define DEBUG */
-#define DUMP_WRITE(addr, nr) \
- do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
-#define DUMP_SEEK(off) \
- do { if (!dump_seek(file, (off))) return 0; } while(0)
+#define DUMP_WRITE(addr, nr, foffset) \
+ do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0)
-static int writenote(struct memelfnote *men, struct file *file)
+static int alignfile(struct file *file, loff_t *foffset)
{
- struct elf_note en;
+ static const char buf[4] = { 0, };
+ DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset);
+ return 1;
+}
+static int writenote(struct memelfnote *men, struct file *file,
+ loff_t *foffset)
+{
+ struct elf_note en;
en.n_namesz = strlen(men->name) + 1;
en.n_descsz = men->datasz;
en.n_type = men->type;
- DUMP_WRITE(&en, sizeof(en));
- DUMP_WRITE(men->name, en.n_namesz);
- /* XXX - cast from long long to long to avoid need for libgcc.a */
- DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
- DUMP_WRITE(men->data, men->datasz);
- DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
+ DUMP_WRITE(&en, sizeof(en), foffset);
+ DUMP_WRITE(men->name, en.n_namesz, foffset);
+ if (!alignfile(file, foffset))
+ return 0;
+ DUMP_WRITE(men->data, men->datasz, foffset);
+ if (!alignfile(file, foffset))
+ return 0;
return 1;
}
#undef DUMP_WRITE
-#undef DUMP_SEEK
-
-#define DUMP_WRITE(addr, nr) \
- if ((size += (nr)) > cprm->limit || \
- !dump_write(cprm->file, (addr), (nr))) \
- goto end_coredump;
static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs)
{
@@ -1393,7 +1367,7 @@ static inline void fill_note(struct memelfnote *note, const char *name, int type
/*
* fill up all the fields in prstatus from the given task struct, except
- * registers which need to be filled up seperately.
+ * registers which need to be filled up separately.
*/
static void fill_prstatus(struct elf_prstatus *prstatus,
struct task_struct *p, long signr)
@@ -1524,6 +1498,22 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
return sz;
}
+static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
+ elf_addr_t e_shoff, int segs)
+{
+ elf->e_shoff = e_shoff;
+ elf->e_shentsize = sizeof(*shdr4extnum);
+ elf->e_shnum = 1;
+ elf->e_shstrndx = SHN_UNDEF;
+
+ memset(shdr4extnum, 0, sizeof(*shdr4extnum));
+
+ shdr4extnum->sh_type = SHT_NULL;
+ shdr4extnum->sh_size = elf->e_shnum;
+ shdr4extnum->sh_link = elf->e_shstrndx;
+ shdr4extnum->sh_info = segs;
+}
+
/*
* dump the segments for an MMU process
*/
@@ -1552,7 +1542,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
err = -EIO;
kunmap(page);
page_cache_release(page);
- } else if (!dump_seek(file, file->f_pos + PAGE_SIZE))
+ } else if (!dump_seek(file, PAGE_SIZE))
err = -EFBIG;
if (err)
goto out;
@@ -1588,6 +1578,17 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
}
#endif
+static size_t elf_core_vma_data_size(unsigned long mm_flags)
+{
+ struct vm_area_struct *vma;
+ size_t size = 0;
+
+ for (vma = current->mm->mmap; vma; vma = vma->vm_next)
+ if (maydump(vma, mm_flags))
+ size += vma->vm_end - vma->vm_start;
+ return size;
+}
+
/*
* Actual dumper
*
@@ -1605,7 +1606,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
int i;
struct vm_area_struct *vma;
struct elfhdr *elf = NULL;
- loff_t offset = 0, dataoff;
+ loff_t offset = 0, dataoff, foffset;
int numnote;
struct memelfnote *notes = NULL;
struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
@@ -1618,7 +1619,10 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
#endif
int thread_status_size = 0;
elf_addr_t *auxv;
- unsigned long mm_flags;
+ struct elf_phdr *phdr4note = NULL;
+ struct elf_shdr *shdr4extnum = NULL;
+ Elf_Half e_phnum;
+ elf_addr_t e_shoff;
/*
* We no longer stop all VM operations.
@@ -1683,12 +1687,18 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
segs = current->mm->map_count;
-#ifdef ELF_CORE_EXTRA_PHDRS
- segs += ELF_CORE_EXTRA_PHDRS;
-#endif
+ segs += elf_core_extra_phdrs();
+
+ /* for notes section */
+ segs++;
+
+ /* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
+ * this, kernel supports extended numbering. Have a look at
+ * include/linux/elf.h for further information. */
+ e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
/* Set up header */
- fill_elf_fdpic_header(elf, segs + 1); /* including notes section */
+ fill_elf_fdpic_header(elf, e_phnum);
has_dumped = 1;
current->flags |= PF_DUMPCORE;
@@ -1727,13 +1737,12 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
fs = get_fs();
set_fs(KERNEL_DS);
- DUMP_WRITE(elf, sizeof(*elf));
offset += sizeof(*elf); /* Elf header */
- offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */
+ offset += segs * sizeof(struct elf_phdr); /* Program headers */
+ foffset = offset;
/* Write notes phdr entry */
{
- struct elf_phdr phdr;
int sz = 0;
for (i = 0; i < numnote; i++)
@@ -1741,20 +1750,38 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
sz += thread_status_size;
- fill_elf_note_phdr(&phdr, sz, offset);
+ phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
+ if (!phdr4note)
+ goto end_coredump;
+
+ fill_elf_note_phdr(phdr4note, sz, offset);
offset += sz;
- DUMP_WRITE(&phdr, sizeof(phdr));
}
/* Page-align dumped data */
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
- /*
- * We must use the same mm->flags while dumping core to avoid
- * inconsistency between the program headers and bodies, otherwise an
- * unusable core file can be generated.
- */
- mm_flags = current->mm->flags;
+ offset += elf_core_vma_data_size(cprm->mm_flags);
+ offset += elf_core_extra_data_size();
+ e_shoff = offset;
+
+ if (e_phnum == PN_XNUM) {
+ shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
+ if (!shdr4extnum)
+ goto end_coredump;
+ fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
+ }
+
+ offset = dataoff;
+
+ size += sizeof(*elf);
+ if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
+ goto end_coredump;
+
+ size += sizeof(*phdr4note);
+ if (size > cprm->limit
+ || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
+ goto end_coredump;
/* write program headers for segments dump */
for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
@@ -1767,7 +1794,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
- phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0;
+ phdr.p_filesz = maydump(vma, cprm->mm_flags) ? sz : 0;
phdr.p_memsz = sz;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -1777,16 +1804,18 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
phdr.p_flags |= PF_X;
phdr.p_align = ELF_EXEC_PAGESIZE;
- DUMP_WRITE(&phdr, sizeof(phdr));
+ size += sizeof(phdr);
+ if (size > cprm->limit
+ || !dump_write(cprm->file, &phdr, sizeof(phdr)))
+ goto end_coredump;
}
-#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
- ELF_CORE_WRITE_EXTRA_PHDRS;
-#endif
+ if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
+ goto end_coredump;
/* write out the notes section */
for (i = 0; i < numnote; i++)
- if (!writenote(notes + i, cprm->file))
+ if (!writenote(notes + i, cprm->file, &foffset))
goto end_coredump;
/* write out the thread status notes section */
@@ -1795,20 +1824,27 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
list_entry(t, struct elf_thread_status, list);
for (i = 0; i < tmp->num_notes; i++)
- if (!writenote(&tmp->notes[i], cprm->file))
+ if (!writenote(&tmp->notes[i], cprm->file, &foffset))
goto end_coredump;
}
- if (!dump_seek(cprm->file, dataoff))
+ if (!dump_seek(cprm->file, dataoff - foffset))
goto end_coredump;
if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit,
- mm_flags) < 0)
+ cprm->mm_flags) < 0)
goto end_coredump;
-#ifdef ELF_CORE_WRITE_EXTRA_DATA
- ELF_CORE_WRITE_EXTRA_DATA;
-#endif
+ if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
+ goto end_coredump;
+
+ if (e_phnum == PN_XNUM) {
+ size += sizeof(*shdr4extnum);
+ if (size > cprm->limit
+ || !dump_write(cprm->file, shdr4extnum,
+ sizeof(*shdr4extnum)))
+ goto end_coredump;
+ }
if (cprm->file->f_pos != offset) {
/* Sanity check */
@@ -1826,7 +1862,7 @@ cleanup:
list_del(tmp);
kfree(list_entry(tmp, struct elf_thread_status, list));
}
-
+ kfree(phdr4note);
kfree(elf);
kfree(prstatus);
kfree(psinfo);
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index 32fb00b52cd..b8e8b0acf9b 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/stat.h>
-#include <linux/slab.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
#include <linux/init.h>
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 42c6b4a5444..49566c1687d 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -355,7 +355,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp)
if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)",
- (int) r,(int)(start_brk-start_code),(int)text_len);
+ (int) r,(int)(start_brk-start_data+text_len),(int)text_len);
goto failed;
}
@@ -501,7 +501,7 @@ static int load_flat_file(struct linux_binprm * bprm,
* size limits imposed on them by creating programs with large
* arrays in the data or bss.
*/
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+ rlim = rlimit(RLIMIT_DATA);
if (rlim >= RLIM_INFINITY)
rlim = ~0;
if (data_len + bss_len > rlim) {
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 08343505e18..aca9d55afb2 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -8,7 +8,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/stat.h>
-#include <linux/slab.h>
#include <linux/binfmts.h>
#include <linux/init.h>
#include <linux/file.h>
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index a16f29e888c..612a5c38d3c 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -24,6 +24,7 @@
#include <linux/mempool.h>
#include <linux/bio.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
struct integrity_slab {
struct kmem_cache *slab;
diff --git a/fs/bio.c b/fs/bio.c
index dc17afd672e..e7bf6ca64dc 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -264,13 +264,12 @@ EXPORT_SYMBOL(bio_init);
* bio_alloc_bioset - allocate a bio for I/O
* @gfp_mask: the GFP_ mask given to the slab allocator
* @nr_iovecs: number of iovecs to pre-allocate
- * @bs: the bio_set to allocate from. If %NULL, just use kmalloc
+ * @bs: the bio_set to allocate from.
*
* Description:
- * bio_alloc_bioset will first try its own mempool to satisfy the allocation.
+ * bio_alloc_bioset will try its own mempool to satisfy the allocation.
* If %__GFP_WAIT is set then we will block on the internal pool waiting
- * for a &struct bio to become free. If a %NULL @bs is passed in, we will
- * fall back to just using @kmalloc to allocate the required memory.
+ * for a &struct bio to become free.
*
* Note that the caller must set ->bi_destructor on successful return
* of a bio, to do the appropriate freeing of the bio once the reference
@@ -555,7 +554,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
.bi_rw = bio->bi_rw,
};
- if (q->merge_bvec_fn(q, &bvm, prev) < len) {
+ if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) {
prev->bv_len -= len;
return 0;
}
@@ -608,7 +607,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
* merge_bvec_fn() returns number of bytes it can accept
* at this offset
*/
- if (q->merge_bvec_fn(q, &bvm, bvec) < len) {
+ if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) {
bvec->bv_page = NULL;
bvec->bv_len = 0;
bvec->bv_offset = 0;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index d11d0289f3d..6dcee88c2e5 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -404,20 +404,28 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
* NULL first argument is nfsd_sync_dir() and that's not a directory.
*/
-static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync)
{
- struct block_device *bdev = I_BDEV(filp->f_mapping->host);
+ struct inode *bd_inode = filp->f_mapping->host;
+ struct block_device *bdev = I_BDEV(bd_inode);
int error;
- error = sync_blockdev(bdev);
- if (error)
- return error;
-
+ /*
+ * There is no need to serialise calls to blkdev_issue_flush with
+ * i_mutex and doing so causes performance issues with concurrent
+ * O_SYNC writers to a block device.
+ */
+ mutex_unlock(&bd_inode->i_mutex);
+
error = blkdev_issue_flush(bdev, NULL);
if (error == -EOPNOTSUPP)
error = 0;
+
+ mutex_lock(&bd_inode->i_mutex);
+
return error;
}
+EXPORT_SYMBOL(blkdev_fsync);
/*
* pseudo-fs
@@ -1481,7 +1489,7 @@ const struct file_operations def_blk_fops = {
.aio_read = generic_file_aio_read,
.aio_write = blkdev_aio_write,
.mmap = generic_file_mmap,
- .fsync = block_fsync,
+ .fsync = blkdev_fsync,
.unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_blkdev_ioctl,
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 6df6d6ed74f..6ef7b26724e 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -22,6 +22,7 @@
#include <linux/posix_acl_xattr.h>
#include <linux/posix_acl.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include "ctree.h"
#include "btrfs_inode.h"
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index c0861e781cd..462859a3014 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -17,6 +17,7 @@
*/
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/freezer.h>
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 3f1f50d9d91..7a4dee19983 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -153,6 +153,11 @@ struct btrfs_inode {
unsigned ordered_data_close:1;
unsigned dummy_inode:1;
+ /*
+ * always compress this one file
+ */
+ unsigned force_compress:1;
+
struct inode vfs_inode;
};
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index a11a32058b5..396039b3a8a 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -31,7 +31,7 @@
#include <linux/swap.h>
#include <linux/writeback.h>
#include <linux/bit_spinlock.h>
-#include <linux/pagevec.h>
+#include <linux/slab.h>
#include "compat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -445,7 +445,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
unsigned long nr_pages = 0;
struct extent_map *em;
struct address_space *mapping = inode->i_mapping;
- struct pagevec pvec;
struct extent_map_tree *em_tree;
struct extent_io_tree *tree;
u64 end;
@@ -461,7 +460,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
end_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
- pagevec_init(&pvec, 0);
while (last_offset < compressed_end) {
page_index = last_offset >> PAGE_CACHE_SHIFT;
@@ -478,26 +476,17 @@ static noinline int add_ra_bio_pages(struct inode *inode,
goto next;
}
- page = alloc_page(mapping_gfp_mask(mapping) | GFP_NOFS);
+ page = __page_cache_alloc(mapping_gfp_mask(mapping) &
+ ~__GFP_FS);
if (!page)
break;
- page->index = page_index;
- /*
- * what we want to do here is call add_to_page_cache_lru,
- * but that isn't exported, so we reproduce it here
- */
- if (add_to_page_cache(page, mapping,
- page->index, GFP_NOFS)) {
+ if (add_to_page_cache_lru(page, mapping, page_index,
+ GFP_NOFS)) {
page_cache_release(page);
goto next;
}
- /* open coding of lru_cache_add, also not exported */
- page_cache_get(page);
- if (!pagevec_add(&pvec, page))
- __pagevec_lru_add_file(&pvec);
-
end = last_offset + PAGE_CACHE_SIZE - 1;
/*
* at this point, we have a locked page in the page cache
@@ -551,8 +540,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
next:
last_offset += PAGE_CACHE_SIZE;
}
- if (pagevec_count(&pvec))
- __pagevec_lru_add_file(&pvec);
return 0;
}
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index c4bc570a396..6795a713b20 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
@@ -3040,6 +3041,10 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0]))
goto err;
+ /* the leaf has changed, it now has room. return now */
+ if (btrfs_leaf_free_space(root, path->nodes[0]) >= ins_len)
+ goto err;
+
if (key.type == BTRFS_EXTENT_DATA_KEY) {
fi = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 2aa8ec6a098..746a7248678 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -26,6 +26,7 @@
#include <linux/completion.h>
#include <linux/backing-dev.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <asm/kmap_types.h>
#include "extent_io.h"
#include "extent_map.h"
@@ -373,11 +374,13 @@ struct btrfs_super_block {
* ones specified below then we will fail to mount
*/
#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
+#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (2ULL << 0)
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
#define BTRFS_FEATURE_INCOMPAT_SUPP \
- BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF
+ (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
+ BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
/*
* A leaf is full of items. offset and size tell us where to find
@@ -832,7 +835,6 @@ struct btrfs_fs_info {
u64 last_trans_log_full_commit;
u64 open_ioctl_trans;
unsigned long mount_opt;
- u64 max_extent;
u64 max_inline;
u64 alloc_start;
struct btrfs_transaction *running_transaction;
@@ -1182,7 +1184,6 @@ struct btrfs_root {
#define BTRFS_INODE_NOATIME (1 << 9)
#define BTRFS_INODE_DIRSYNC (1 << 10)
-
/* some macros to generate set/get funcs for the struct fields. This
* assumes there is a lefoo_to_cpu for every type, so lets make a simple
* one for u8:
@@ -1842,7 +1843,7 @@ BTRFS_SETGET_STACK_FUNCS(super_num_devices, struct btrfs_super_block,
BTRFS_SETGET_STACK_FUNCS(super_compat_flags, struct btrfs_super_block,
compat_flags, 64);
BTRFS_SETGET_STACK_FUNCS(super_compat_ro_flags, struct btrfs_super_block,
- compat_flags, 64);
+ compat_ro_flags, 64);
BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block,
incompat_flags, 64);
BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block,
@@ -2310,7 +2311,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
u32 min_type);
int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
-int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end);
+int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
+ struct extent_state **cached_state);
int btrfs_writepages(struct address_space *mapping,
struct writeback_control *wbc);
int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
@@ -2326,7 +2328,7 @@ 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_put_inode(struct inode *inode);
-int btrfs_write_inode(struct inode *inode, int wait);
+int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc);
void btrfs_dirty_inode(struct inode *inode);
struct inode *btrfs_alloc_inode(struct super_block *sb);
void btrfs_destroy_inode(struct inode *inode);
@@ -2335,7 +2337,7 @@ int btrfs_init_cachep(void);
void btrfs_destroy_cachep(void);
long btrfs_ioctl_trans_end(struct file *file);
struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
- struct btrfs_root *root);
+ struct btrfs_root *root, int *was_new);
int btrfs_commit_write(struct file *file, struct page *page,
unsigned from, unsigned to);
struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
@@ -2386,7 +2388,6 @@ void btrfs_sysfs_del_super(struct btrfs_fs_info *root);
ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
/* super.c */
-u64 btrfs_parse_size(char *str);
int btrfs_parse_options(struct btrfs_root *root, char *options);
int btrfs_sync_fs(struct super_block *sb, int wait);
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index 84e6781413b..902ce507c4e 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/sort.h>
#include "ctree.h"
#include "delayed-ref.h"
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 2b59201b955..feca04197d0 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -27,6 +27,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/crc32c.h>
+#include <linux/slab.h>
#include "compat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -43,8 +44,6 @@ static struct extent_io_ops btree_extent_io_ops;
static void end_workqueue_fn(struct btrfs_work *work);
static void free_fs_root(struct btrfs_root *root);
-static atomic_t btrfs_bdi_num = ATOMIC_INIT(0);
-
/*
* end_io_wq structs are used to do processing in task context when an IO is
* complete. This is used during reads to verify checksums, and it is used
@@ -263,13 +262,15 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
static int verify_parent_transid(struct extent_io_tree *io_tree,
struct extent_buffer *eb, u64 parent_transid)
{
+ struct extent_state *cached_state = NULL;
int ret;
if (!parent_transid || btrfs_header_generation(eb) == parent_transid)
return 0;
- lock_extent(io_tree, eb->start, eb->start + eb->len - 1, GFP_NOFS);
- if (extent_buffer_uptodate(io_tree, eb) &&
+ lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1,
+ 0, &cached_state, GFP_NOFS);
+ if (extent_buffer_uptodate(io_tree, eb, cached_state) &&
btrfs_header_generation(eb) == parent_transid) {
ret = 0;
goto out;
@@ -282,10 +283,10 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
(unsigned long long)btrfs_header_generation(eb));
}
ret = 1;
- clear_extent_buffer_uptodate(io_tree, eb);
+ clear_extent_buffer_uptodate(io_tree, eb, &cached_state);
out:
- unlock_extent(io_tree, eb->start, eb->start + eb->len - 1,
- GFP_NOFS);
+ unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1,
+ &cached_state, GFP_NOFS);
return ret;
}
@@ -901,7 +902,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
root->highest_objectid = 0;
root->name = NULL;
root->in_sysfs = 0;
- root->inode_tree.rb_node = NULL;
+ root->inode_tree = RB_ROOT;
INIT_LIST_HEAD(&root->dirty_list);
INIT_LIST_HEAD(&root->orphan_list);
@@ -1372,19 +1373,11 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
{
int err;
- bdi->name = "btrfs";
bdi->capabilities = BDI_CAP_MAP_COPY;
- err = bdi_init(bdi);
+ err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY);
if (err)
return err;
- err = bdi_register(bdi, NULL, "btrfs-%d",
- atomic_inc_return(&btrfs_bdi_num));
- if (err) {
- bdi_destroy(bdi);
- return err;
- }
-
bdi->ra_pages = default_backing_dev_info.ra_pages;
bdi->unplug_io_fn = btrfs_unplug_io_fn;
bdi->unplug_io_data = info;
@@ -1632,7 +1625,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
atomic_set(&fs_info->async_submit_draining, 0);
atomic_set(&fs_info->nr_async_bios, 0);
fs_info->sb = sb;
- fs_info->max_extent = (u64)-1;
fs_info->max_inline = 8192 * 1024;
fs_info->metadata_ratio = 0;
@@ -1673,7 +1665,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
insert_inode_hash(fs_info->btree_inode);
spin_lock_init(&fs_info->block_group_cache_lock);
- fs_info->block_group_cache_tree.rb_node = NULL;
+ fs_info->block_group_cache_tree = RB_ROOT;
extent_io_tree_init(&fs_info->freed_extents[0],
fs_info->btree_inode->i_mapping, GFP_NOFS);
@@ -1920,7 +1912,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
csum_root->track_dirty = 1;
- btrfs_read_block_groups(extent_root);
+ ret = btrfs_read_block_groups(extent_root);
+ if (ret) {
+ printk(KERN_ERR "Failed to read block groups: %d\n", ret);
+ goto fail_block_groups;
+ }
fs_info->generation = generation;
fs_info->last_trans_committed = generation;
@@ -1930,7 +1926,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
"btrfs-cleaner");
if (IS_ERR(fs_info->cleaner_kthread))
- goto fail_csum_root;
+ goto fail_block_groups;
fs_info->transaction_kthread = kthread_run(transaction_kthread,
tree_root,
@@ -2018,7 +2014,8 @@ fail_cleaner:
filemap_write_and_wait(fs_info->btree_inode->i_mapping);
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
-fail_csum_root:
+fail_block_groups:
+ btrfs_free_block_groups(fs_info);
free_extent_buffer(csum_root->node);
free_extent_buffer(csum_root->commit_root);
fail_dev_root:
@@ -2497,7 +2494,8 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid)
int ret;
struct inode *btree_inode = buf->first_page->mapping->host;
- ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf);
+ ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf,
+ NULL);
if (!ret)
return ret;
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index ba5c3fd5ab8..951ef09b82f 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -95,7 +95,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
key.offset = 0;
- inode = btrfs_iget(sb, &key, root);
+ inode = btrfs_iget(sb, &key, root, NULL);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto fail;
@@ -223,7 +223,7 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
- dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root));
+ dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL));
if (!IS_ERR(dentry))
dentry->d_op = &btrfs_dentry_operations;
return dentry;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 559f72489b3..b34d32fdaae 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -22,6 +22,7 @@
#include <linux/sort.h>
#include <linux/rcupdate.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include "compat.h"
#include "hash.h"
#include "ctree.h"
@@ -2676,6 +2677,8 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
INIT_LIST_HEAD(&found->block_groups);
init_rwsem(&found->groups_sem);
+ init_waitqueue_head(&found->flush_wait);
+ init_waitqueue_head(&found->allocate_wait);
spin_lock_init(&found->lock);
found->flags = flags;
found->total_bytes = total_bytes;
@@ -2846,7 +2849,7 @@ int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
}
spin_unlock(&BTRFS_I(inode)->accounting_lock);
- BTRFS_I(inode)->reserved_extents--;
+ BTRFS_I(inode)->reserved_extents -= num_items;
BUG_ON(BTRFS_I(inode)->reserved_extents < 0);
if (meta_sinfo->bytes_delalloc < num_bytes) {
@@ -2944,12 +2947,10 @@ static void flush_delalloc(struct btrfs_root *root,
spin_lock(&info->lock);
- if (!info->flushing) {
+ if (!info->flushing)
info->flushing = 1;
- init_waitqueue_head(&info->flush_wait);
- } else {
+ else
wait = true;
- }
spin_unlock(&info->lock);
@@ -3011,7 +3012,6 @@ static int maybe_allocate_chunk(struct btrfs_root *root,
if (!info->allocating_chunk) {
info->force_alloc = 1;
info->allocating_chunk = 1;
- init_waitqueue_head(&info->allocate_wait);
} else {
wait = true;
}
@@ -3111,7 +3111,7 @@ again:
return -ENOSPC;
}
- BTRFS_I(inode)->reserved_extents++;
+ BTRFS_I(inode)->reserved_extents += num_items;
check_force_delalloc(meta_sinfo);
spin_unlock(&meta_sinfo->lock);
@@ -3235,7 +3235,8 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
u64 bytes)
{
struct btrfs_space_info *data_sinfo;
- int ret = 0, committed = 0;
+ u64 used;
+ int ret = 0, committed = 0, flushed = 0;
/* make sure bytes are sectorsize aligned */
bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
@@ -3247,12 +3248,21 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
again:
/* make sure we have enough space to handle the data first */
spin_lock(&data_sinfo->lock);
- if (data_sinfo->total_bytes - data_sinfo->bytes_used -
- data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved -
- data_sinfo->bytes_pinned - data_sinfo->bytes_readonly -
- data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) {
+ used = data_sinfo->bytes_used + data_sinfo->bytes_delalloc +
+ data_sinfo->bytes_reserved + data_sinfo->bytes_pinned +
+ data_sinfo->bytes_readonly + data_sinfo->bytes_may_use +
+ data_sinfo->bytes_super;
+
+ if (used + bytes > data_sinfo->total_bytes) {
struct btrfs_trans_handle *trans;
+ if (!flushed) {
+ spin_unlock(&data_sinfo->lock);
+ flush_delalloc(root, data_sinfo);
+ flushed = 1;
+ goto again;
+ }
+
/*
* if we don't have enough free bytes in this space then we need
* to alloc a new chunk.
@@ -4170,6 +4180,10 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
ins->offset = 0;
space_info = __find_space_info(root->fs_info, data);
+ if (!space_info) {
+ printk(KERN_ERR "No space info for %d\n", data);
+ return -ENOSPC;
+ }
if (orig_root->ref_cows || empty_size)
allowed_chunk_alloc = 1;
@@ -5205,6 +5219,8 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
next = btrfs_find_tree_block(root, bytenr, blocksize);
if (!next) {
next = btrfs_find_create_tree_block(root, bytenr, blocksize);
+ if (!next)
+ return -ENOMEM;
reada = 1;
}
btrfs_tree_lock(next);
@@ -5417,7 +5433,8 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans,
if (ret > 0) {
path->slots[level]++;
continue;
- }
+ } else if (ret < 0)
+ return ret;
level = wc->level;
}
return 0;
@@ -6561,6 +6578,7 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root,
struct btrfs_key key;
struct inode *inode = NULL;
struct btrfs_file_extent_item *fi;
+ struct extent_state *cached_state = NULL;
u64 num_bytes;
u64 skip_objectid = 0;
u32 nritems;
@@ -6589,12 +6607,14 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root,
}
num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
- lock_extent(&BTRFS_I(inode)->io_tree, key.offset,
- key.offset + num_bytes - 1, GFP_NOFS);
+ lock_extent_bits(&BTRFS_I(inode)->io_tree, key.offset,
+ key.offset + num_bytes - 1, 0, &cached_state,
+ GFP_NOFS);
btrfs_drop_extent_cache(inode, key.offset,
key.offset + num_bytes - 1, 1);
- unlock_extent(&BTRFS_I(inode)->io_tree, key.offset,
- key.offset + num_bytes - 1, GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, key.offset,
+ key.offset + num_bytes - 1, &cached_state,
+ GFP_NOFS);
cond_resched();
}
iput(inode);
@@ -7366,7 +7386,6 @@ static int find_first_block_group(struct btrfs_root *root,
}
path->slots[0]++;
}
- ret = -ENOENT;
out:
return ret;
}
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index b177ed31961..d2d03684fab 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2,7 +2,6 @@
#include <linux/slab.h>
#include <linux/bio.h>
#include <linux/mm.h>
-#include <linux/gfp.h>
#include <linux/pagemap.h>
#include <linux/page-flags.h>
#include <linux/module.h>
@@ -104,8 +103,8 @@ void extent_io_exit(void)
void extent_io_tree_init(struct extent_io_tree *tree,
struct address_space *mapping, gfp_t mask)
{
- tree->state.rb_node = NULL;
- tree->buffer.rb_node = NULL;
+ tree->state = RB_ROOT;
+ tree->buffer = RB_ROOT;
tree->ops = NULL;
tree->dirty_bytes = 0;
spin_lock_init(&tree->lock);
@@ -513,7 +512,10 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
u64 last_end;
int err;
int set = 0;
+ int clear = 0;
+ if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY))
+ clear = 1;
again:
if (!prealloc && (mask & __GFP_WAIT)) {
prealloc = alloc_extent_state(mask);
@@ -524,14 +526,20 @@ again:
spin_lock(&tree->lock);
if (cached_state) {
cached = *cached_state;
- *cached_state = NULL;
- cached_state = NULL;
+
+ if (clear) {
+ *cached_state = NULL;
+ cached_state = NULL;
+ }
+
if (cached && cached->tree && cached->start == start) {
- atomic_dec(&cached->refs);
+ if (clear)
+ atomic_dec(&cached->refs);
state = cached;
goto hit_next;
}
- free_extent_state(cached);
+ if (clear)
+ free_extent_state(cached);
}
/*
* this search will find the extents that end after
@@ -946,11 +954,11 @@ int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
}
int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
- gfp_t mask)
+ struct extent_state **cached_state, gfp_t mask)
{
return set_extent_bit(tree, start, end,
EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE,
- 0, NULL, NULL, mask);
+ 0, NULL, cached_state, mask);
}
int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
@@ -984,10 +992,11 @@ int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end,
}
static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start,
- u64 end, gfp_t mask)
+ u64 end, struct extent_state **cached_state,
+ gfp_t mask)
{
return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0,
- NULL, mask);
+ cached_state, mask);
}
int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end)
@@ -1171,7 +1180,8 @@ out:
* 1 is returned if we find something, 0 if nothing was in the tree
*/
static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
- u64 *start, u64 *end, u64 max_bytes)
+ u64 *start, u64 *end, u64 max_bytes,
+ struct extent_state **cached_state)
{
struct rb_node *node;
struct extent_state *state;
@@ -1203,8 +1213,11 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
*end = state->end;
goto out;
}
- if (!found)
+ if (!found) {
*start = state->start;
+ *cached_state = state;
+ atomic_inc(&state->refs);
+ }
found++;
*end = state->end;
cur_start = state->end + 1;
@@ -1336,10 +1349,11 @@ again:
delalloc_start = *start;
delalloc_end = 0;
found = find_delalloc_range(tree, &delalloc_start, &delalloc_end,
- max_bytes);
+ max_bytes, &cached_state);
if (!found || delalloc_end <= *start) {
*start = delalloc_start;
*end = delalloc_end;
+ free_extent_state(cached_state);
return found;
}
@@ -1722,7 +1736,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
}
if (!uptodate) {
- clear_extent_uptodate(tree, start, end, GFP_NOFS);
+ clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS);
ClearPageUptodate(page);
SetPageError(page);
}
@@ -1750,7 +1764,8 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
static void end_bio_extent_readpage(struct bio *bio, int err)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
- struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+ struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1;
+ struct bio_vec *bvec = bio->bi_io_vec;
struct extent_io_tree *tree;
u64 start;
u64 end;
@@ -1773,7 +1788,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
else
whole_page = 0;
- if (--bvec >= bio->bi_io_vec)
+ if (++bvec <= bvec_end)
prefetchw(&bvec->bv_page->flags);
if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {
@@ -1818,7 +1833,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
}
check_page_locked(tree, page);
}
- } while (bvec >= bio->bi_io_vec);
+ } while (bvec <= bvec_end);
bio_put(bio);
}
@@ -2663,33 +2678,20 @@ int extent_readpages(struct extent_io_tree *tree,
{
struct bio *bio = NULL;
unsigned page_idx;
- struct pagevec pvec;
unsigned long bio_flags = 0;
- pagevec_init(&pvec, 0);
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
struct page *page = list_entry(pages->prev, struct page, lru);
prefetchw(&page->flags);
list_del(&page->lru);
- /*
- * what we want to do here is call add_to_page_cache_lru,
- * but that isn't exported, so we reproduce it here
- */
- if (!add_to_page_cache(page, mapping,
+ if (!add_to_page_cache_lru(page, mapping,
page->index, GFP_KERNEL)) {
-
- /* open coding of lru_cache_add, also not exported */
- page_cache_get(page);
- if (!pagevec_add(&pvec, page))
- __pagevec_lru_add_file(&pvec);
__extent_read_full_page(tree, page, get_extent,
&bio, 0, &bio_flags);
}
page_cache_release(page);
}
- if (pagevec_count(&pvec))
- __pagevec_lru_add_file(&pvec);
BUG_ON(!list_empty(pages));
if (bio)
submit_one_bio(READ, bio, 0, bio_flags);
@@ -2704,6 +2706,7 @@ int extent_readpages(struct extent_io_tree *tree,
int extent_invalidatepage(struct extent_io_tree *tree,
struct page *page, unsigned long offset)
{
+ struct extent_state *cached_state = NULL;
u64 start = ((u64)page->index << PAGE_CACHE_SHIFT);
u64 end = start + PAGE_CACHE_SIZE - 1;
size_t blocksize = page->mapping->host->i_sb->s_blocksize;
@@ -2712,12 +2715,12 @@ int extent_invalidatepage(struct extent_io_tree *tree,
if (start > end)
return 0;
- lock_extent(tree, start, end, GFP_NOFS);
+ lock_extent_bits(tree, start, end, 0, &cached_state, GFP_NOFS);
wait_on_page_writeback(page);
clear_extent_bit(tree, start, end,
EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
EXTENT_DO_ACCOUNTING,
- 1, 1, NULL, GFP_NOFS);
+ 1, 1, &cached_state, GFP_NOFS);
return 0;
}
@@ -2920,16 +2923,17 @@ sector_t extent_bmap(struct address_space *mapping, sector_t iblock,
get_extent_t *get_extent)
{
struct inode *inode = mapping->host;
+ struct extent_state *cached_state = NULL;
u64 start = iblock << inode->i_blkbits;
sector_t sector = 0;
size_t blksize = (1 << inode->i_blkbits);
struct extent_map *em;
- lock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
- GFP_NOFS);
+ lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
+ 0, &cached_state, GFP_NOFS);
em = get_extent(inode, NULL, 0, start, blksize, 0);
- unlock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
- GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, start,
+ start + blksize - 1, &cached_state, GFP_NOFS);
if (!em || IS_ERR(em))
return 0;
@@ -2951,6 +2955,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u32 flags = 0;
u64 disko = 0;
struct extent_map *em = NULL;
+ struct extent_state *cached_state = NULL;
int end = 0;
u64 em_start = 0, em_len = 0;
unsigned long emflags;
@@ -2959,8 +2964,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
if (len == 0)
return -EINVAL;
- lock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
- GFP_NOFS);
+ lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0,
+ &cached_state, GFP_NOFS);
em = get_extent(inode, NULL, 0, off, max - off, 0);
if (!em)
goto out;
@@ -3023,8 +3028,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
out_free:
free_extent_map(em);
out:
- unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
- GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len,
+ &cached_state, GFP_NOFS);
return ret;
}
@@ -3264,7 +3269,8 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree,
}
int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
- struct extent_buffer *eb)
+ struct extent_buffer *eb,
+ struct extent_state **cached_state)
{
unsigned long i;
struct page *page;
@@ -3274,7 +3280,7 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
- GFP_NOFS);
+ cached_state, GFP_NOFS);
for (i = 0; i < num_pages; i++) {
page = extent_buffer_page(eb, i);
if (page)
@@ -3334,7 +3340,8 @@ int extent_range_uptodate(struct extent_io_tree *tree,
}
int extent_buffer_uptodate(struct extent_io_tree *tree,
- struct extent_buffer *eb)
+ struct extent_buffer *eb,
+ struct extent_state *cached_state)
{
int ret = 0;
unsigned long num_pages;
@@ -3346,7 +3353,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree,
return 1;
ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
- EXTENT_UPTODATE, 1, NULL);
+ EXTENT_UPTODATE, 1, cached_state);
if (ret)
return ret;
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 36de250a7b2..bbab4813646 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -163,6 +163,8 @@ int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask);
int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
int bits, struct extent_state **cached, gfp_t mask);
int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask);
+int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end,
+ struct extent_state **cached, gfp_t mask);
int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end,
gfp_t mask);
int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
@@ -196,7 +198,7 @@ int clear_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end,
int clear_extent_ordered_metadata(struct extent_io_tree *tree, u64 start,
u64 end, gfp_t mask);
int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
- gfp_t mask);
+ struct extent_state **cached_state, gfp_t mask);
int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end,
gfp_t mask);
int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
@@ -281,9 +283,11 @@ int test_extent_buffer_dirty(struct extent_io_tree *tree,
int set_extent_buffer_uptodate(struct extent_io_tree *tree,
struct extent_buffer *eb);
int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
- struct extent_buffer *eb);
+ struct extent_buffer *eb,
+ struct extent_state **cached_state);
int extent_buffer_uptodate(struct extent_io_tree *tree,
- struct extent_buffer *eb);
+ struct extent_buffer *eb,
+ struct extent_state *cached_state);
int map_extent_buffer(struct extent_buffer *eb, unsigned long offset,
unsigned long min_len, char **token, char **map,
unsigned long *map_start,
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 428fcac45f9..454ca52d645 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -1,5 +1,4 @@
#include <linux/err.h>
-#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spinlock.h>
@@ -35,7 +34,7 @@ void extent_map_exit(void)
*/
void extent_map_tree_init(struct extent_map_tree *tree, gfp_t mask)
{
- tree->map.rb_node = NULL;
+ tree->map = RB_ROOT;
rwlock_init(&tree->lock);
}
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 9b99886562d..54a255065aa 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -17,6 +17,7 @@
*/
#include <linux/bio.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include "ctree.h"
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 6ed434ac037..29ff749ff4c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -28,6 +28,7 @@
#include <linux/writeback.h>
#include <linux/statfs.h>
#include <linux/compat.h>
+#include <linux/slab.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
@@ -123,7 +124,8 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
end_of_last_block = start_pos + num_bytes - 1;
- err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
+ err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
+ NULL);
if (err)
return err;
@@ -753,6 +755,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
loff_t pos, unsigned long first_index,
unsigned long last_index, size_t write_bytes)
{
+ struct extent_state *cached_state = NULL;
int i;
unsigned long index = pos >> PAGE_CACHE_SHIFT;
struct inode *inode = fdentry(file)->d_inode;
@@ -781,16 +784,18 @@ again:
}
if (start_pos < inode->i_size) {
struct btrfs_ordered_extent *ordered;
- lock_extent(&BTRFS_I(inode)->io_tree,
- start_pos, last_pos - 1, GFP_NOFS);
+ lock_extent_bits(&BTRFS_I(inode)->io_tree,
+ start_pos, last_pos - 1, 0, &cached_state,
+ GFP_NOFS);
ordered = btrfs_lookup_first_ordered_extent(inode,
last_pos - 1);
if (ordered &&
ordered->file_offset + ordered->len > start_pos &&
ordered->file_offset < last_pos) {
btrfs_put_ordered_extent(ordered);
- unlock_extent(&BTRFS_I(inode)->io_tree,
- start_pos, last_pos - 1, GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+ start_pos, last_pos - 1,
+ &cached_state, GFP_NOFS);
for (i = 0; i < num_pages; i++) {
unlock_page(pages[i]);
page_cache_release(pages[i]);
@@ -802,12 +807,13 @@ again:
if (ordered)
btrfs_put_ordered_extent(ordered);
- clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos,
+ clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos,
last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
- EXTENT_DO_ACCOUNTING,
+ EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
GFP_NOFS);
- unlock_extent(&BTRFS_I(inode)->io_tree,
- start_pos, last_pos - 1, GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+ start_pos, last_pos - 1, &cached_state,
+ GFP_NOFS);
}
for (i = 0; i < num_pages; i++) {
clear_page_dirty_for_io(pages[i]);
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index cb2849f0325..f488fac04d9 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -18,6 +18,7 @@
#include <linux/pagemap.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/math64.h>
#include "ctree.h"
#include "free-space-cache.h"
@@ -870,7 +871,7 @@ __btrfs_return_cluster_to_free_space(
tree_insert_offset(&block_group->free_space_offset,
entry->offset, &entry->offset_index, 0);
}
- cluster->root.rb_node = NULL;
+ cluster->root = RB_ROOT;
out:
spin_unlock(&cluster->lock);
@@ -1355,7 +1356,7 @@ void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster)
{
spin_lock_init(&cluster->lock);
spin_lock_init(&cluster->refill_lock);
- cluster->root.rb_node = NULL;
+ cluster->root = RB_ROOT;
cluster->max_size = 0;
cluster->points_to_bitmap = false;
INIT_LIST_HEAD(&cluster->block_group_list);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4deb280f896..2bfdc641d4e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -36,6 +36,7 @@
#include <linux/xattr.h>
#include <linux/posix_acl.h>
#include <linux/falloc.h>
+#include <linux/slab.h>
#include "compat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -379,7 +380,8 @@ again:
* change at any time if we discover bad compression ratios.
*/
if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) &&
- btrfs_test_opt(root, COMPRESS)) {
+ (btrfs_test_opt(root, COMPRESS) ||
+ (BTRFS_I(inode)->force_compress))) {
WARN_ON(pages);
pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
@@ -483,8 +485,10 @@ again:
nr_pages_ret = 0;
/* flag the file so we don't compress in the future */
- if (!btrfs_test_opt(root, FORCE_COMPRESS))
+ if (!btrfs_test_opt(root, FORCE_COMPRESS) &&
+ !(BTRFS_I(inode)->force_compress)) {
BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
+ }
}
if (will_compress) {
*num_added += 1;
@@ -570,8 +574,8 @@ retry:
unsigned long nr_written = 0;
lock_extent(io_tree, async_extent->start,
- async_extent->start +
- async_extent->ram_size - 1, GFP_NOFS);
+ async_extent->start +
+ async_extent->ram_size - 1, GFP_NOFS);
/* allocate blocks */
ret = cow_file_range(inode, async_cow->locked_page,
@@ -793,7 +797,7 @@ static noinline int cow_file_range(struct inode *inode,
while (disk_num_bytes > 0) {
unsigned long op;
- cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent);
+ cur_alloc_size = disk_num_bytes;
ret = btrfs_reserve_extent(trans, root, cur_alloc_size,
root->sectorsize, 0, alloc_hint,
(u64)-1, &ins, 1);
@@ -1211,7 +1215,8 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
else if (BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC)
ret = run_delalloc_nocow(inode, locked_page, start, end,
page_started, 0, nr_written);
- else if (!btrfs_test_opt(root, COMPRESS))
+ else if (!btrfs_test_opt(root, COMPRESS) &&
+ !(BTRFS_I(inode)->force_compress))
ret = cow_file_range(inode, locked_page, start, end,
page_started, nr_written, 1);
else
@@ -1223,30 +1228,9 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
static int btrfs_split_extent_hook(struct inode *inode,
struct extent_state *orig, u64 split)
{
- struct btrfs_root *root = BTRFS_I(inode)->root;
- u64 size;
-
if (!(orig->state & EXTENT_DELALLOC))
return 0;
- size = orig->end - orig->start + 1;
- if (size > root->fs_info->max_extent) {
- u64 num_extents;
- u64 new_size;
-
- new_size = orig->end - split + 1;
- num_extents = div64_u64(size + root->fs_info->max_extent - 1,
- root->fs_info->max_extent);
-
- /*
- * if we break a large extent up then leave oustanding_extents
- * be, since we've already accounted for the large extent.
- */
- if (div64_u64(new_size + root->fs_info->max_extent - 1,
- root->fs_info->max_extent) < num_extents)
- return 0;
- }
-
spin_lock(&BTRFS_I(inode)->accounting_lock);
BTRFS_I(inode)->outstanding_extents++;
spin_unlock(&BTRFS_I(inode)->accounting_lock);
@@ -1264,38 +1248,10 @@ static int btrfs_merge_extent_hook(struct inode *inode,
struct extent_state *new,
struct extent_state *other)
{
- struct btrfs_root *root = BTRFS_I(inode)->root;
- u64 new_size, old_size;
- u64 num_extents;
-
/* not delalloc, ignore it */
if (!(other->state & EXTENT_DELALLOC))
return 0;
- old_size = other->end - other->start + 1;
- if (new->start < other->start)
- new_size = other->end - new->start + 1;
- else
- new_size = new->end - other->start + 1;
-
- /* we're not bigger than the max, unreserve the space and go */
- if (new_size <= root->fs_info->max_extent) {
- spin_lock(&BTRFS_I(inode)->accounting_lock);
- BTRFS_I(inode)->outstanding_extents--;
- spin_unlock(&BTRFS_I(inode)->accounting_lock);
- return 0;
- }
-
- /*
- * If we grew by another max_extent, just return, we want to keep that
- * reserved amount.
- */
- num_extents = div64_u64(old_size + root->fs_info->max_extent - 1,
- root->fs_info->max_extent);
- if (div64_u64(new_size + root->fs_info->max_extent - 1,
- root->fs_info->max_extent) > num_extents)
- return 0;
-
spin_lock(&BTRFS_I(inode)->accounting_lock);
BTRFS_I(inode)->outstanding_extents--;
spin_unlock(&BTRFS_I(inode)->accounting_lock);
@@ -1324,6 +1280,7 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
BTRFS_I(inode)->outstanding_extents++;
spin_unlock(&BTRFS_I(inode)->accounting_lock);
btrfs_delalloc_reserve_space(root, inode, end - start + 1);
+
spin_lock(&root->fs_info->delalloc_lock);
BTRFS_I(inode)->delalloc_bytes += end - start + 1;
root->fs_info->delalloc_bytes += end - start + 1;
@@ -1352,6 +1309,7 @@ static int btrfs_clear_bit_hook(struct inode *inode,
if (bits & EXTENT_DO_ACCOUNTING) {
spin_lock(&BTRFS_I(inode)->accounting_lock);
+ WARN_ON(!BTRFS_I(inode)->outstanding_extents);
BTRFS_I(inode)->outstanding_extents--;
spin_unlock(&BTRFS_I(inode)->accounting_lock);
btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
@@ -1508,12 +1466,13 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
return 0;
}
-int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end)
+int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
+ struct extent_state **cached_state)
{
if ((end & (PAGE_CACHE_SIZE - 1)) == 0)
WARN_ON(1);
return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end,
- GFP_NOFS);
+ cached_state, GFP_NOFS);
}
/* see btrfs_writepage_start_hook for details on why this is required */
@@ -1526,6 +1485,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
{
struct btrfs_writepage_fixup *fixup;
struct btrfs_ordered_extent *ordered;
+ struct extent_state *cached_state = NULL;
struct page *page;
struct inode *inode;
u64 page_start;
@@ -1544,7 +1504,8 @@ again:
page_start = page_offset(page);
page_end = page_offset(page) + PAGE_CACHE_SIZE - 1;
- lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS);
+ lock_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, 0,
+ &cached_state, GFP_NOFS);
/* already ordered? We're done */
if (PagePrivate2(page))
@@ -1552,17 +1513,18 @@ again:
ordered = btrfs_lookup_ordered_extent(inode, page_start);
if (ordered) {
- unlock_extent(&BTRFS_I(inode)->io_tree, page_start,
- page_end, GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start,
+ page_end, &cached_state, GFP_NOFS);
unlock_page(page);
btrfs_start_ordered_extent(inode, ordered, 1);
goto again;
}
- btrfs_set_extent_delalloc(inode, page_start, page_end);
+ btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state);
ClearPageChecked(page);
out:
- unlock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
+ &cached_state, GFP_NOFS);
out_page:
unlock_page(page);
page_cache_release(page);
@@ -1691,14 +1653,14 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
struct btrfs_trans_handle *trans;
struct btrfs_ordered_extent *ordered_extent = NULL;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+ struct extent_state *cached_state = NULL;
int compressed = 0;
int ret;
- ret = btrfs_dec_test_ordered_pending(inode, start, end - start + 1);
+ ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start,
+ end - start + 1);
if (!ret)
return 0;
-
- ordered_extent = btrfs_lookup_ordered_extent(inode, start);
BUG_ON(!ordered_extent);
if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
@@ -1713,9 +1675,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
goto out;
}
- lock_extent(io_tree, ordered_extent->file_offset,
- ordered_extent->file_offset + ordered_extent->len - 1,
- GFP_NOFS);
+ lock_extent_bits(io_tree, ordered_extent->file_offset,
+ ordered_extent->file_offset + ordered_extent->len - 1,
+ 0, &cached_state, GFP_NOFS);
trans = btrfs_join_transaction(root, 1);
@@ -1742,9 +1704,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
ordered_extent->len);
BUG_ON(ret);
}
- unlock_extent(io_tree, ordered_extent->file_offset,
- ordered_extent->file_offset + ordered_extent->len - 1,
- GFP_NOFS);
+ unlock_extent_cached(io_tree, ordered_extent->file_offset,
+ ordered_extent->file_offset +
+ ordered_extent->len - 1, &cached_state, GFP_NOFS);
+
add_pending_csums(trans, inode, ordered_extent->file_offset,
&ordered_extent->list);
@@ -2153,7 +2116,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
found_key.objectid = found_key.offset;
found_key.type = BTRFS_INODE_ITEM_KEY;
found_key.offset = 0;
- inode = btrfs_iget(root->fs_info->sb, &found_key, root);
+ inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL);
if (IS_ERR(inode))
break;
@@ -3081,6 +3044,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
struct btrfs_root *root = BTRFS_I(inode)->root;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
struct btrfs_ordered_extent *ordered;
+ struct extent_state *cached_state = NULL;
char *kaddr;
u32 blocksize = root->sectorsize;
pgoff_t index = from >> PAGE_CACHE_SHIFT;
@@ -3127,12 +3091,14 @@ again:
}
wait_on_page_writeback(page);
- lock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state,
+ GFP_NOFS);
set_page_extent_mapped(page);
ordered = btrfs_lookup_ordered_extent(inode, page_start);
if (ordered) {
- unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ unlock_extent_cached(io_tree, page_start, page_end,
+ &cached_state, GFP_NOFS);
unlock_page(page);
page_cache_release(page);
btrfs_start_ordered_extent(inode, ordered, 1);
@@ -3140,13 +3106,15 @@ again:
goto again;
}
- clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+ clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
- GFP_NOFS);
+ 0, 0, &cached_state, GFP_NOFS);
- ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+ ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
+ &cached_state);
if (ret) {
- unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ unlock_extent_cached(io_tree, page_start, page_end,
+ &cached_state, GFP_NOFS);
goto out_unlock;
}
@@ -3159,7 +3127,8 @@ again:
}
ClearPageChecked(page);
set_page_dirty(page);
- unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ unlock_extent_cached(io_tree, page_start, page_end, &cached_state,
+ GFP_NOFS);
out_unlock:
if (ret)
@@ -3177,6 +3146,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
struct btrfs_root *root = BTRFS_I(inode)->root;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
struct extent_map *em;
+ struct extent_state *cached_state = NULL;
u64 mask = root->sectorsize - 1;
u64 hole_start = (inode->i_size + mask) & ~mask;
u64 block_end = (size + mask) & ~mask;
@@ -3192,11 +3162,13 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
struct btrfs_ordered_extent *ordered;
btrfs_wait_ordered_range(inode, hole_start,
block_end - hole_start);
- lock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+ lock_extent_bits(io_tree, hole_start, block_end - 1, 0,
+ &cached_state, GFP_NOFS);
ordered = btrfs_lookup_ordered_extent(inode, hole_start);
if (!ordered)
break;
- unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+ unlock_extent_cached(io_tree, hole_start, block_end - 1,
+ &cached_state, GFP_NOFS);
btrfs_put_ordered_extent(ordered);
}
@@ -3241,7 +3213,8 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
break;
}
- unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+ unlock_extent_cached(io_tree, hole_start, block_end - 1, &cached_state,
+ GFP_NOFS);
return err;
}
@@ -3639,6 +3612,7 @@ static noinline void init_btrfs_i(struct inode *inode)
bi->index_cnt = (u64)-1;
bi->last_unlink_trans = 0;
bi->ordered_data_close = 0;
+ bi->force_compress = 0;
extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS);
extent_io_tree_init(&BTRFS_I(inode)->io_tree,
inode->i_mapping, GFP_NOFS);
@@ -3687,7 +3661,7 @@ static struct inode *btrfs_iget_locked(struct super_block *s,
* Returns in *is_new if the inode was read from disk
*/
struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
- struct btrfs_root *root)
+ struct btrfs_root *root, int *new)
{
struct inode *inode;
@@ -3702,6 +3676,8 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
inode_tree_add(inode);
unlock_new_inode(inode);
+ if (new)
+ *new = 1;
}
return inode;
@@ -3754,7 +3730,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
return NULL;
if (location.type == BTRFS_INODE_ITEM_KEY) {
- inode = btrfs_iget(dir->i_sb, &location, root);
+ inode = btrfs_iget(dir->i_sb, &location, root, NULL);
return inode;
}
@@ -3769,7 +3745,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
else
inode = new_simple_dir(dir->i_sb, &location, sub_root);
} else {
- inode = btrfs_iget(dir->i_sb, &location, sub_root);
+ inode = btrfs_iget(dir->i_sb, &location, sub_root, NULL);
}
srcu_read_unlock(&root->fs_info->subvol_srcu, index);
@@ -3968,7 +3944,7 @@ err:
return ret;
}
-int btrfs_write_inode(struct inode *inode, int wait)
+int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_trans_handle *trans;
@@ -3977,7 +3953,7 @@ int btrfs_write_inode(struct inode *inode, int wait)
if (root->fs_info->btree_inode == inode)
return 0;
- if (wait) {
+ if (wbc->sync_mode == WB_SYNC_ALL) {
trans = btrfs_join_transaction(root, 1);
btrfs_set_trans_block_group(trans, inode);
ret = btrfs_commit_transaction(trans, root);
@@ -4501,7 +4477,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
if (err) {
err = -ENOSPC;
- goto out_unlock;
+ goto out_fail;
}
inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
@@ -4979,6 +4955,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
{
struct extent_io_tree *tree;
struct btrfs_ordered_extent *ordered;
+ struct extent_state *cached_state = NULL;
u64 page_start = page_offset(page);
u64 page_end = page_start + PAGE_CACHE_SIZE - 1;
@@ -4997,7 +4974,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
btrfs_releasepage(page, GFP_NOFS);
return;
}
- lock_extent(tree, page_start, page_end, GFP_NOFS);
+ lock_extent_bits(tree, page_start, page_end, 0, &cached_state,
+ GFP_NOFS);
ordered = btrfs_lookup_ordered_extent(page->mapping->host,
page_offset(page));
if (ordered) {
@@ -5008,7 +4986,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
clear_extent_bit(tree, page_start, page_end,
EXTENT_DIRTY | EXTENT_DELALLOC |
EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0,
- NULL, GFP_NOFS);
+ &cached_state, GFP_NOFS);
/*
* whoever cleared the private bit is responsible
* for the finish_ordered_io
@@ -5018,11 +4996,13 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
page_start, page_end);
}
btrfs_put_ordered_extent(ordered);
- lock_extent(tree, page_start, page_end, GFP_NOFS);
+ cached_state = NULL;
+ lock_extent_bits(tree, page_start, page_end, 0, &cached_state,
+ GFP_NOFS);
}
clear_extent_bit(tree, page_start, page_end,
EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
- EXTENT_DO_ACCOUNTING, 1, 1, NULL, GFP_NOFS);
+ EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS);
__btrfs_releasepage(page, GFP_NOFS);
ClearPageChecked(page);
@@ -5055,6 +5035,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
struct btrfs_root *root = BTRFS_I(inode)->root;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
struct btrfs_ordered_extent *ordered;
+ struct extent_state *cached_state = NULL;
char *kaddr;
unsigned long zero_start;
loff_t size;
@@ -5093,7 +5074,8 @@ again:
}
wait_on_page_writeback(page);
- lock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state,
+ GFP_NOFS);
set_page_extent_mapped(page);
/*
@@ -5102,7 +5084,8 @@ again:
*/
ordered = btrfs_lookup_ordered_extent(inode, page_start);
if (ordered) {
- unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ unlock_extent_cached(io_tree, page_start, page_end,
+ &cached_state, GFP_NOFS);
unlock_page(page);
btrfs_start_ordered_extent(inode, ordered, 1);
btrfs_put_ordered_extent(ordered);
@@ -5116,13 +5099,15 @@ again:
* is probably a better way to do this, but for now keep consistent with
* prepare_pages in the normal write path.
*/
- clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+ clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
- GFP_NOFS);
+ 0, 0, &cached_state, GFP_NOFS);
- ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+ ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
+ &cached_state);
if (ret) {
- unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ unlock_extent_cached(io_tree, page_start, page_end,
+ &cached_state, GFP_NOFS);
ret = VM_FAULT_SIGBUS;
btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
goto out_unlock;
@@ -5148,7 +5133,7 @@ again:
BTRFS_I(inode)->last_trans = root->fs_info->generation;
BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
- unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS);
out_unlock:
btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
@@ -5353,7 +5338,6 @@ free:
void btrfs_drop_inode(struct inode *inode)
{
struct btrfs_root *root = BTRFS_I(inode)->root;
-
if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0)
generic_delete_inode(inode);
else
@@ -5757,18 +5741,15 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end,
struct btrfs_trans_handle *trans;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_key ins;
- u64 alloc_size;
u64 cur_offset = start;
u64 num_bytes = end - start;
int ret = 0;
u64 i_size;
while (num_bytes > 0) {
- alloc_size = min(num_bytes, root->fs_info->max_extent);
-
trans = btrfs_start_transaction(root, 1);
- ret = btrfs_reserve_extent(trans, root, alloc_size,
+ ret = btrfs_reserve_extent(trans, root, num_bytes,
root->sectorsize, 0, alloc_hint,
(u64)-1, &ins, 1);
if (ret) {
@@ -5827,6 +5808,7 @@ stop_trans:
static long btrfs_fallocate(struct inode *inode, int mode,
loff_t offset, loff_t len)
{
+ struct extent_state *cached_state = NULL;
u64 cur_offset;
u64 last_byte;
u64 alloc_start;
@@ -5865,16 +5847,17 @@ static long btrfs_fallocate(struct inode *inode, int mode,
/* the extent lock is ordered inside the running
* transaction
*/
- lock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
- GFP_NOFS);
+ lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start,
+ locked_end, 0, &cached_state, GFP_NOFS);
ordered = btrfs_lookup_first_ordered_extent(inode,
alloc_end - 1);
if (ordered &&
ordered->file_offset + ordered->len > alloc_start &&
ordered->file_offset < alloc_end) {
btrfs_put_ordered_extent(ordered);
- unlock_extent(&BTRFS_I(inode)->io_tree,
- alloc_start, locked_end, GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+ alloc_start, locked_end,
+ &cached_state, GFP_NOFS);
/*
* we can't wait on the range with the transaction
* running or with the extent lock held
@@ -5916,8 +5899,8 @@ static long btrfs_fallocate(struct inode *inode, int mode,
break;
}
}
- unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
- GFP_NOFS);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
+ &cached_state, GFP_NOFS);
btrfs_free_reserved_data_space(BTRFS_I(inode)->root, inode,
alloc_end - alloc_start);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 645a17927a8..e84ef60ffe3 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -39,6 +39,7 @@
#include <linux/security.h>
#include <linux/xattr.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include "compat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -474,7 +475,79 @@ out_unlock:
return error;
}
-static int btrfs_defrag_file(struct file *file)
+static int should_defrag_range(struct inode *inode, u64 start, u64 len,
+ int thresh, u64 *last_len, u64 *skip,
+ u64 *defrag_end)
+{
+ struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+ struct extent_map *em = NULL;
+ struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+ int ret = 1;
+
+
+ if (thresh == 0)
+ thresh = 256 * 1024;
+
+ /*
+ * make sure that once we start defragging and extent, we keep on
+ * defragging it
+ */
+ if (start < *defrag_end)
+ return 1;
+
+ *skip = 0;
+
+ /*
+ * hopefully we have this extent in the tree already, try without
+ * the full extent lock
+ */
+ read_lock(&em_tree->lock);
+ em = lookup_extent_mapping(em_tree, start, len);
+ read_unlock(&em_tree->lock);
+
+ if (!em) {
+ /* get the big lock and read metadata off disk */
+ lock_extent(io_tree, start, start + len - 1, GFP_NOFS);
+ em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
+ unlock_extent(io_tree, start, start + len - 1, GFP_NOFS);
+
+ if (IS_ERR(em))
+ return 0;
+ }
+
+ /* this will cover holes, and inline extents */
+ if (em->block_start >= EXTENT_MAP_LAST_BYTE)
+ ret = 0;
+
+ /*
+ * we hit a real extent, if it is big don't bother defragging it again
+ */
+ if ((*last_len == 0 || *last_len >= thresh) && em->len >= thresh)
+ ret = 0;
+
+ /*
+ * last_len ends up being a counter of how many bytes we've defragged.
+ * every time we choose not to defrag an extent, we reset *last_len
+ * so that the next tiny extent will force a defrag.
+ *
+ * The end result of this is that tiny extents before a single big
+ * extent will force at least part of that big extent to be defragged.
+ */
+ if (ret) {
+ *last_len += len;
+ *defrag_end = extent_map_end(em);
+ } else {
+ *last_len = 0;
+ *skip = extent_map_end(em);
+ *defrag_end = 0;
+ }
+
+ free_extent_map(em);
+ return ret;
+}
+
+static int btrfs_defrag_file(struct file *file,
+ struct btrfs_ioctl_defrag_range_args *range)
{
struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -486,37 +559,96 @@ static int btrfs_defrag_file(struct file *file)
unsigned long total_read = 0;
u64 page_start;
u64 page_end;
+ u64 last_len = 0;
+ u64 skip = 0;
+ u64 defrag_end = 0;
unsigned long i;
int ret;
- ret = btrfs_check_data_free_space(root, inode, inode->i_size);
- if (ret)
- return -ENOSPC;
+ if (inode->i_size == 0)
+ return 0;
+
+ if (range->start + range->len > range->start) {
+ last_index = min_t(u64, inode->i_size - 1,
+ range->start + range->len - 1) >> PAGE_CACHE_SHIFT;
+ } else {
+ last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT;
+ }
+
+ i = range->start >> PAGE_CACHE_SHIFT;
+ while (i <= last_index) {
+ if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT,
+ PAGE_CACHE_SIZE,
+ range->extent_thresh,
+ &last_len, &skip,
+ &defrag_end)) {
+ unsigned long next;
+ /*
+ * the should_defrag function tells us how much to skip
+ * bump our counter by the suggested amount
+ */
+ next = (skip + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+ i = max(i + 1, next);
+ continue;
+ }
- mutex_lock(&inode->i_mutex);
- last_index = inode->i_size >> PAGE_CACHE_SHIFT;
- for (i = 0; i <= last_index; i++) {
if (total_read % ra_pages == 0) {
btrfs_force_ra(inode->i_mapping, &file->f_ra, file, i,
min(last_index, i + ra_pages - 1));
}
total_read++;
+ mutex_lock(&inode->i_mutex);
+ if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
+ BTRFS_I(inode)->force_compress = 1;
+
+ ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
+ if (ret) {
+ ret = -ENOSPC;
+ break;
+ }
+
+ ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+ if (ret) {
+ btrfs_free_reserved_data_space(root, inode,
+ PAGE_CACHE_SIZE);
+ ret = -ENOSPC;
+ break;
+ }
again:
+ if (inode->i_size == 0 ||
+ i > ((inode->i_size - 1) >> PAGE_CACHE_SHIFT)) {
+ ret = 0;
+ goto err_reservations;
+ }
+
page = grab_cache_page(inode->i_mapping, i);
if (!page)
- goto out_unlock;
+ goto err_reservations;
+
if (!PageUptodate(page)) {
btrfs_readpage(NULL, page);
lock_page(page);
if (!PageUptodate(page)) {
unlock_page(page);
page_cache_release(page);
- goto out_unlock;
+ goto err_reservations;
}
}
+ if (page->mapping != inode->i_mapping) {
+ unlock_page(page);
+ page_cache_release(page);
+ goto again;
+ }
+
wait_on_page_writeback(page);
+ if (PageDirty(page)) {
+ btrfs_free_reserved_data_space(root, inode,
+ PAGE_CACHE_SIZE);
+ goto loop_unlock;
+ }
+
page_start = (u64)page->index << PAGE_CACHE_SHIFT;
page_end = page_start + PAGE_CACHE_SIZE - 1;
lock_extent(io_tree, page_start, page_end, GFP_NOFS);
@@ -537,18 +669,54 @@ again:
* page if it is dirtied again later
*/
clear_page_dirty_for_io(page);
+ clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start,
+ page_end, EXTENT_DIRTY | EXTENT_DELALLOC |
+ EXTENT_DO_ACCOUNTING, GFP_NOFS);
- btrfs_set_extent_delalloc(inode, page_start, page_end);
+ btrfs_set_extent_delalloc(inode, page_start, page_end, NULL);
+ ClearPageChecked(page);
set_page_dirty(page);
unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+
+loop_unlock:
unlock_page(page);
page_cache_release(page);
+ mutex_unlock(&inode->i_mutex);
+
+ btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1);
+ i++;
+ }
+
+ if ((range->flags & BTRFS_DEFRAG_RANGE_START_IO))
+ filemap_flush(inode->i_mapping);
+
+ if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
+ /* the filemap_flush will queue IO into the worker threads, but
+ * we have to make sure the IO is actually started and that
+ * ordered extents get created before we return
+ */
+ atomic_inc(&root->fs_info->async_submit_draining);
+ while (atomic_read(&root->fs_info->nr_async_submits) ||
+ atomic_read(&root->fs_info->async_delalloc_pages)) {
+ wait_event(root->fs_info->async_submit_wait,
+ (atomic_read(&root->fs_info->nr_async_submits) == 0 &&
+ atomic_read(&root->fs_info->async_delalloc_pages) == 0));
+ }
+ atomic_dec(&root->fs_info->async_submit_draining);
+
+ mutex_lock(&inode->i_mutex);
+ BTRFS_I(inode)->force_compress = 0;
+ mutex_unlock(&inode->i_mutex);
}
-out_unlock:
- mutex_unlock(&inode->i_mutex);
return 0;
+
+err_reservations:
+ mutex_unlock(&inode->i_mutex);
+ btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+ btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
+ return ret;
}
static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
@@ -608,7 +776,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
mod = 1;
sizestr++;
}
- new_size = btrfs_parse_size(sizestr);
+ new_size = memparse(sizestr, NULL);
if (new_size == 0) {
ret = -EINVAL;
goto out_unlock;
@@ -743,6 +911,330 @@ out:
return ret;
}
+static noinline int key_in_sk(struct btrfs_key *key,
+ struct btrfs_ioctl_search_key *sk)
+{
+ struct btrfs_key test;
+ int ret;
+
+ test.objectid = sk->min_objectid;
+ test.type = sk->min_type;
+ test.offset = sk->min_offset;
+
+ ret = btrfs_comp_cpu_keys(key, &test);
+ if (ret < 0)
+ return 0;
+
+ test.objectid = sk->max_objectid;
+ test.type = sk->max_type;
+ test.offset = sk->max_offset;
+
+ ret = btrfs_comp_cpu_keys(key, &test);
+ if (ret > 0)
+ return 0;
+ return 1;
+}
+
+static noinline int copy_to_sk(struct btrfs_root *root,
+ struct btrfs_path *path,
+ struct btrfs_key *key,
+ struct btrfs_ioctl_search_key *sk,
+ char *buf,
+ unsigned long *sk_offset,
+ int *num_found)
+{
+ u64 found_transid;
+ struct extent_buffer *leaf;
+ struct btrfs_ioctl_search_header sh;
+ unsigned long item_off;
+ unsigned long item_len;
+ int nritems;
+ int i;
+ int slot;
+ int found = 0;
+ int ret = 0;
+
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ nritems = btrfs_header_nritems(leaf);
+
+ if (btrfs_header_generation(leaf) > sk->max_transid) {
+ i = nritems;
+ goto advance_key;
+ }
+ found_transid = btrfs_header_generation(leaf);
+
+ for (i = slot; i < nritems; i++) {
+ item_off = btrfs_item_ptr_offset(leaf, i);
+ item_len = btrfs_item_size_nr(leaf, i);
+
+ if (item_len > BTRFS_SEARCH_ARGS_BUFSIZE)
+ item_len = 0;
+
+ if (sizeof(sh) + item_len + *sk_offset >
+ BTRFS_SEARCH_ARGS_BUFSIZE) {
+ ret = 1;
+ goto overflow;
+ }
+
+ btrfs_item_key_to_cpu(leaf, key, i);
+ if (!key_in_sk(key, sk))
+ continue;
+
+ sh.objectid = key->objectid;
+ sh.offset = key->offset;
+ sh.type = key->type;
+ sh.len = item_len;
+ sh.transid = found_transid;
+
+ /* copy search result header */
+ memcpy(buf + *sk_offset, &sh, sizeof(sh));
+ *sk_offset += sizeof(sh);
+
+ if (item_len) {
+ char *p = buf + *sk_offset;
+ /* copy the item */
+ read_extent_buffer(leaf, p,
+ item_off, item_len);
+ *sk_offset += item_len;
+ }
+ found++;
+
+ if (*num_found >= sk->nr_items)
+ break;
+ }
+advance_key:
+ ret = 0;
+ if (key->offset < (u64)-1 && key->offset < sk->max_offset)
+ key->offset++;
+ else if (key->type < (u8)-1 && key->type < sk->max_type) {
+ key->offset = 0;
+ key->type++;
+ } else if (key->objectid < (u64)-1 && key->objectid < sk->max_objectid) {
+ key->offset = 0;
+ key->type = 0;
+ key->objectid++;
+ } else
+ ret = 1;
+overflow:
+ *num_found += found;
+ return ret;
+}
+
+static noinline int search_ioctl(struct inode *inode,
+ struct btrfs_ioctl_search_args *args)
+{
+ struct btrfs_root *root;
+ struct btrfs_key key;
+ struct btrfs_key max_key;
+ struct btrfs_path *path;
+ struct btrfs_ioctl_search_key *sk = &args->key;
+ struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info;
+ int ret;
+ int num_found = 0;
+ unsigned long sk_offset = 0;
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+
+ if (sk->tree_id == 0) {
+ /* search the root of the inode that was passed */
+ root = BTRFS_I(inode)->root;
+ } else {
+ key.objectid = sk->tree_id;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = (u64)-1;
+ root = btrfs_read_fs_root_no_name(info, &key);
+ if (IS_ERR(root)) {
+ printk(KERN_ERR "could not find root %llu\n",
+ sk->tree_id);
+ btrfs_free_path(path);
+ return -ENOENT;
+ }
+ }
+
+ key.objectid = sk->min_objectid;
+ key.type = sk->min_type;
+ key.offset = sk->min_offset;
+
+ max_key.objectid = sk->max_objectid;
+ max_key.type = sk->max_type;
+ max_key.offset = sk->max_offset;
+
+ path->keep_locks = 1;
+
+ while(1) {
+ ret = btrfs_search_forward(root, &key, &max_key, path, 0,
+ sk->min_transid);
+ if (ret != 0) {
+ if (ret > 0)
+ ret = 0;
+ goto err;
+ }
+ ret = copy_to_sk(root, path, &key, sk, args->buf,
+ &sk_offset, &num_found);
+ btrfs_release_path(root, path);
+ if (ret || num_found >= sk->nr_items)
+ break;
+
+ }
+ ret = 0;
+err:
+ sk->nr_items = num_found;
+ btrfs_free_path(path);
+ return ret;
+}
+
+static noinline int btrfs_ioctl_tree_search(struct file *file,
+ void __user *argp)
+{
+ struct btrfs_ioctl_search_args *args;
+ struct inode *inode;
+ int ret;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ args = kmalloc(sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+
+ if (copy_from_user(args, argp, sizeof(*args))) {
+ kfree(args);
+ return -EFAULT;
+ }
+ inode = fdentry(file)->d_inode;
+ ret = search_ioctl(inode, args);
+ if (ret == 0 && copy_to_user(argp, args, sizeof(*args)))
+ ret = -EFAULT;
+ kfree(args);
+ return ret;
+}
+
+/*
+ * Search INODE_REFs to identify path name of 'dirid' directory
+ * in a 'tree_id' tree. and sets path name to 'name'.
+ */
+static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
+ u64 tree_id, u64 dirid, char *name)
+{
+ struct btrfs_root *root;
+ struct btrfs_key key;
+ char *ptr;
+ int ret = -1;
+ int slot;
+ int len;
+ int total_len = 0;
+ struct btrfs_inode_ref *iref;
+ struct extent_buffer *l;
+ struct btrfs_path *path;
+
+ if (dirid == BTRFS_FIRST_FREE_OBJECTID) {
+ name[0]='\0';
+ return 0;
+ }
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+
+ ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX];
+
+ key.objectid = tree_id;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = (u64)-1;
+ root = btrfs_read_fs_root_no_name(info, &key);
+ if (IS_ERR(root)) {
+ printk(KERN_ERR "could not find root %llu\n", tree_id);
+ ret = -ENOENT;
+ goto out;
+ }
+
+ key.objectid = dirid;
+ key.type = BTRFS_INODE_REF_KEY;
+ key.offset = (u64)-1;
+
+ while(1) {
+ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ if (ret < 0)
+ goto out;
+
+ l = path->nodes[0];
+ slot = path->slots[0];
+ if (ret > 0 && slot > 0)
+ slot--;
+ btrfs_item_key_to_cpu(l, &key, slot);
+
+ if (ret > 0 && (key.objectid != dirid ||
+ key.type != BTRFS_INODE_REF_KEY)) {
+ ret = -ENOENT;
+ goto out;
+ }
+
+ iref = btrfs_item_ptr(l, slot, struct btrfs_inode_ref);
+ len = btrfs_inode_ref_name_len(l, iref);
+ ptr -= len + 1;
+ total_len += len + 1;
+ if (ptr < name)
+ goto out;
+
+ *(ptr + len) = '/';
+ read_extent_buffer(l, ptr,(unsigned long)(iref + 1), len);
+
+ if (key.offset == BTRFS_FIRST_FREE_OBJECTID)
+ break;
+
+ btrfs_release_path(root, path);
+ key.objectid = key.offset;
+ key.offset = (u64)-1;
+ dirid = key.objectid;
+
+ }
+ if (ptr < name)
+ goto out;
+ memcpy(name, ptr, total_len);
+ name[total_len]='\0';
+ ret = 0;
+out:
+ btrfs_free_path(path);
+ return ret;
+}
+
+static noinline int btrfs_ioctl_ino_lookup(struct file *file,
+ void __user *argp)
+{
+ struct btrfs_ioctl_ino_lookup_args *args;
+ struct inode *inode;
+ int ret;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ args = kmalloc(sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+
+ if (copy_from_user(args, argp, sizeof(*args))) {
+ kfree(args);
+ return -EFAULT;
+ }
+ inode = fdentry(file)->d_inode;
+
+ if (args->treeid == 0)
+ args->treeid = BTRFS_I(inode)->root->root_key.objectid;
+
+ ret = btrfs_search_path_in_tree(BTRFS_I(inode)->root->fs_info,
+ args->treeid, args->objectid,
+ args->name);
+
+ if (ret == 0 && copy_to_user(argp, args, sizeof(*args)))
+ ret = -EFAULT;
+
+ kfree(args);
+ return ret;
+}
+
static noinline int btrfs_ioctl_snap_destroy(struct file *file,
void __user *arg)
{
@@ -849,10 +1341,11 @@ out:
return err;
}
-static int btrfs_ioctl_defrag(struct file *file)
+static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
{
struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root;
+ struct btrfs_ioctl_defrag_range_args *range;
int ret;
ret = mnt_want_write(file->f_path.mnt);
@@ -873,7 +1366,31 @@ static int btrfs_ioctl_defrag(struct file *file)
ret = -EINVAL;
goto out;
}
- btrfs_defrag_file(file);
+
+ range = kzalloc(sizeof(*range), GFP_KERNEL);
+ if (!range) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (argp) {
+ if (copy_from_user(range, argp,
+ sizeof(*range))) {
+ ret = -EFAULT;
+ kfree(range);
+ goto out;
+ }
+ /* compression requires us to start the IO */
+ if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
+ range->flags |= BTRFS_DEFRAG_RANGE_START_IO;
+ range->extent_thresh = (u32)-1;
+ }
+ } else {
+ /* the rest are all set to zero by kzalloc */
+ range->len = (u64)-1;
+ }
+ btrfs_defrag_file(file, range);
+ kfree(range);
break;
}
out:
@@ -1274,6 +1791,157 @@ out:
return ret;
}
+static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
+{
+ struct inode *inode = fdentry(file)->d_inode;
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ struct btrfs_root *new_root;
+ struct btrfs_dir_item *di;
+ struct btrfs_trans_handle *trans;
+ struct btrfs_path *path;
+ struct btrfs_key location;
+ struct btrfs_disk_key disk_key;
+ struct btrfs_super_block *disk_super;
+ u64 features;
+ u64 objectid = 0;
+ u64 dir_id;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (copy_from_user(&objectid, argp, sizeof(objectid)))
+ return -EFAULT;
+
+ if (!objectid)
+ objectid = root->root_key.objectid;
+
+ location.objectid = objectid;
+ location.type = BTRFS_ROOT_ITEM_KEY;
+ location.offset = (u64)-1;
+
+ new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
+ if (IS_ERR(new_root))
+ return PTR_ERR(new_root);
+
+ if (btrfs_root_refs(&new_root->root_item) == 0)
+ return -ENOENT;
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+ path->leave_spinning = 1;
+
+ trans = btrfs_start_transaction(root, 1);
+ if (!trans) {
+ btrfs_free_path(path);
+ return -ENOMEM;
+ }
+
+ dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+ di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
+ dir_id, "default", 7, 1);
+ if (!di) {
+ btrfs_free_path(path);
+ btrfs_end_transaction(trans, root);
+ printk(KERN_ERR "Umm, you don't have the default dir item, "
+ "this isn't going to work\n");
+ return -ENOENT;
+ }
+
+ btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
+ btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
+ btrfs_mark_buffer_dirty(path->nodes[0]);
+ btrfs_free_path(path);
+
+ disk_super = &root->fs_info->super_copy;
+ features = btrfs_super_incompat_flags(disk_super);
+ if (!(features & BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)) {
+ features |= BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL;
+ btrfs_set_super_incompat_flags(disk_super, features);
+ }
+ btrfs_end_transaction(trans, root);
+
+ return 0;
+}
+
+long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
+{
+ struct btrfs_ioctl_space_args space_args;
+ struct btrfs_ioctl_space_info space;
+ struct btrfs_ioctl_space_info *dest;
+ struct btrfs_ioctl_space_info *dest_orig;
+ struct btrfs_ioctl_space_info *user_dest;
+ struct btrfs_space_info *info;
+ int alloc_size;
+ int ret = 0;
+ int slot_count = 0;
+
+ if (copy_from_user(&space_args,
+ (struct btrfs_ioctl_space_args __user *)arg,
+ sizeof(space_args)))
+ return -EFAULT;
+
+ /* first we count slots */
+ rcu_read_lock();
+ list_for_each_entry_rcu(info, &root->fs_info->space_info, list)
+ slot_count++;
+ rcu_read_unlock();
+
+ /* space_slots == 0 means they are asking for a count */
+ if (space_args.space_slots == 0) {
+ space_args.total_spaces = slot_count;
+ goto out;
+ }
+ alloc_size = sizeof(*dest) * slot_count;
+ /* we generally have at most 6 or so space infos, one for each raid
+ * level. So, a whole page should be more than enough for everyone
+ */
+ if (alloc_size > PAGE_CACHE_SIZE)
+ return -ENOMEM;
+
+ space_args.total_spaces = 0;
+ dest = kmalloc(alloc_size, GFP_NOFS);
+ if (!dest)
+ return -ENOMEM;
+ dest_orig = dest;
+
+ /* now we have a buffer to copy into */
+ rcu_read_lock();
+ list_for_each_entry_rcu(info, &root->fs_info->space_info, list) {
+ /* make sure we don't copy more than we allocated
+ * in our buffer
+ */
+ if (slot_count == 0)
+ break;
+ slot_count--;
+
+ /* make sure userland has enough room in their buffer */
+ if (space_args.total_spaces >= space_args.space_slots)
+ break;
+
+ space.flags = info->flags;
+ space.total_bytes = info->total_bytes;
+ space.used_bytes = info->bytes_used;
+ memcpy(dest, &space, sizeof(space));
+ dest++;
+ space_args.total_spaces++;
+ }
+ rcu_read_unlock();
+
+ user_dest = (struct btrfs_ioctl_space_info *)
+ (arg + sizeof(struct btrfs_ioctl_space_args));
+
+ if (copy_to_user(user_dest, dest_orig, alloc_size))
+ ret = -EFAULT;
+
+ kfree(dest_orig);
+out:
+ if (ret == 0 && copy_to_user(arg, &space_args, sizeof(space_args)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
/*
* there are many ways the trans_start and trans_end ioctls can lead
* to deadlocks. They should only be used by applications that
@@ -1320,8 +1988,12 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_snap_create(file, argp, 1);
case BTRFS_IOC_SNAP_DESTROY:
return btrfs_ioctl_snap_destroy(file, argp);
+ case BTRFS_IOC_DEFAULT_SUBVOL:
+ return btrfs_ioctl_default_subvol(file, argp);
case BTRFS_IOC_DEFRAG:
- return btrfs_ioctl_defrag(file);
+ return btrfs_ioctl_defrag(file, NULL);
+ case BTRFS_IOC_DEFRAG_RANGE:
+ return btrfs_ioctl_defrag(file, argp);
case BTRFS_IOC_RESIZE:
return btrfs_ioctl_resize(root, argp);
case BTRFS_IOC_ADD_DEV:
@@ -1338,6 +2010,12 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_trans_start(file);
case BTRFS_IOC_TRANS_END:
return btrfs_ioctl_trans_end(file);
+ case BTRFS_IOC_TREE_SEARCH:
+ return btrfs_ioctl_tree_search(file, argp);
+ case BTRFS_IOC_INO_LOOKUP:
+ return btrfs_ioctl_ino_lookup(file, argp);
+ case BTRFS_IOC_SPACE_INFO:
+ return btrfs_ioctl_space_info(root, argp);
case BTRFS_IOC_SYNC:
btrfs_sync_fs(file->f_dentry->d_sb, 1);
return 0;
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index bc49914475e..424694aa517 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -30,12 +30,114 @@ struct btrfs_ioctl_vol_args {
char name[BTRFS_PATH_NAME_MAX + 1];
};
+#define BTRFS_INO_LOOKUP_PATH_MAX 4080
+struct btrfs_ioctl_ino_lookup_args {
+ __u64 treeid;
+ __u64 objectid;
+ char name[BTRFS_INO_LOOKUP_PATH_MAX];
+};
+
+struct btrfs_ioctl_search_key {
+ /* which root are we searching. 0 is the tree of tree roots */
+ __u64 tree_id;
+
+ /* keys returned will be >= min and <= max */
+ __u64 min_objectid;
+ __u64 max_objectid;
+
+ /* keys returned will be >= min and <= max */
+ __u64 min_offset;
+ __u64 max_offset;
+
+ /* max and min transids to search for */
+ __u64 min_transid;
+ __u64 max_transid;
+
+ /* keys returned will be >= min and <= max */
+ __u32 min_type;
+ __u32 max_type;
+
+ /*
+ * how many items did userland ask for, and how many are we
+ * returning
+ */
+ __u32 nr_items;
+
+ /* align to 64 bits */
+ __u32 unused;
+
+ /* some extra for later */
+ __u64 unused1;
+ __u64 unused2;
+ __u64 unused3;
+ __u64 unused4;
+};
+
+struct btrfs_ioctl_search_header {
+ __u64 transid;
+ __u64 objectid;
+ __u64 offset;
+ __u32 type;
+ __u32 len;
+};
+
+#define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key))
+/*
+ * the buf is an array of search headers where
+ * each header is followed by the actual item
+ * the type field is expanded to 32 bits for alignment
+ */
+struct btrfs_ioctl_search_args {
+ struct btrfs_ioctl_search_key key;
+ char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
+};
+
struct btrfs_ioctl_clone_range_args {
__s64 src_fd;
__u64 src_offset, src_length;
__u64 dest_offset;
};
+/* flags for the defrag range ioctl */
+#define BTRFS_DEFRAG_RANGE_COMPRESS 1
+#define BTRFS_DEFRAG_RANGE_START_IO 2
+
+struct btrfs_ioctl_defrag_range_args {
+ /* start of the defrag operation */
+ __u64 start;
+
+ /* number of bytes to defrag, use (u64)-1 to say all */
+ __u64 len;
+
+ /*
+ * flags for the operation, which can include turning
+ * on compression for this one defrag
+ */
+ __u64 flags;
+
+ /*
+ * any extent bigger than this will be considered
+ * already defragged. Use 0 to take the kernel default
+ * Use 1 to say every single extent must be rewritten
+ */
+ __u32 extent_thresh;
+
+ /* spare for later */
+ __u32 unused[5];
+};
+
+struct btrfs_ioctl_space_info {
+ __u64 flags;
+ __u64 total_bytes;
+ __u64 used_bytes;
+};
+
+struct btrfs_ioctl_space_args {
+ __u64 space_slots;
+ __u64 total_spaces;
+ struct btrfs_ioctl_space_info spaces[0];
+};
+
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -67,4 +169,13 @@ struct btrfs_ioctl_clone_range_args {
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \
struct btrfs_ioctl_vol_args)
+#define BTRFS_IOC_DEFRAG_RANGE _IOW(BTRFS_IOCTL_MAGIC, 16, \
+ struct btrfs_ioctl_defrag_range_args)
+#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \
+ struct btrfs_ioctl_search_args)
+#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \
+ struct btrfs_ioctl_ino_lookup_args)
+#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
+#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
+ struct btrfs_ioctl_space_args)
#endif
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index 1c36e5cd8f5..6151f2ea38b 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -16,7 +16,6 @@
* Boston, MA 021110-1307, USA.
*/
#include <linux/sched.h>
-#include <linux/gfp.h>
#include <linux/pagemap.h>
#include <linux/spinlock.h>
#include <linux/page-flags.h>
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 5c2a9e78a94..a127c0ebb2d 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -16,7 +16,6 @@
* Boston, MA 021110-1307, USA.
*/
-#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/writeback.h>
@@ -174,7 +173,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
if (!entry)
return -ENOMEM;
- mutex_lock(&tree->mutex);
entry->file_offset = file_offset;
entry->start = start;
entry->len = len;
@@ -190,16 +188,17 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
INIT_LIST_HEAD(&entry->list);
INIT_LIST_HEAD(&entry->root_extent_list);
+ spin_lock(&tree->lock);
node = tree_insert(&tree->tree, file_offset,
&entry->rb_node);
BUG_ON(node);
+ spin_unlock(&tree->lock);
spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
list_add_tail(&entry->root_extent_list,
&BTRFS_I(inode)->root->fs_info->ordered_extents);
spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
- mutex_unlock(&tree->mutex);
BUG_ON(node);
return 0;
}
@@ -216,9 +215,9 @@ int btrfs_add_ordered_sum(struct inode *inode,
struct btrfs_ordered_inode_tree *tree;
tree = &BTRFS_I(inode)->ordered_tree;
- mutex_lock(&tree->mutex);
+ spin_lock(&tree->lock);
list_add_tail(&sum->list, &entry->list);
- mutex_unlock(&tree->mutex);
+ spin_unlock(&tree->lock);
return 0;
}
@@ -232,15 +231,16 @@ int btrfs_add_ordered_sum(struct inode *inode,
* to make sure this function only returns 1 once for a given ordered extent.
*/
int btrfs_dec_test_ordered_pending(struct inode *inode,
+ struct btrfs_ordered_extent **cached,
u64 file_offset, u64 io_size)
{
struct btrfs_ordered_inode_tree *tree;
struct rb_node *node;
- struct btrfs_ordered_extent *entry;
+ struct btrfs_ordered_extent *entry = NULL;
int ret;
tree = &BTRFS_I(inode)->ordered_tree;
- mutex_lock(&tree->mutex);
+ spin_lock(&tree->lock);
node = tree_search(tree, file_offset);
if (!node) {
ret = 1;
@@ -264,7 +264,11 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
else
ret = 1;
out:
- mutex_unlock(&tree->mutex);
+ if (!ret && cached && entry) {
+ *cached = entry;
+ atomic_inc(&entry->refs);
+ }
+ spin_unlock(&tree->lock);
return ret == 0;
}
@@ -291,13 +295,14 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
/*
* remove an ordered extent from the tree. No references are dropped
- * and you must wake_up entry->wait. You must hold the tree mutex
+ * and you must wake_up entry->wait. You must hold the tree lock
* while you call this function.
*/
static int __btrfs_remove_ordered_extent(struct inode *inode,
struct btrfs_ordered_extent *entry)
{
struct btrfs_ordered_inode_tree *tree;
+ struct btrfs_root *root = BTRFS_I(inode)->root;
struct rb_node *node;
tree = &BTRFS_I(inode)->ordered_tree;
@@ -307,12 +312,13 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags);
spin_lock(&BTRFS_I(inode)->accounting_lock);
+ WARN_ON(!BTRFS_I(inode)->outstanding_extents);
BTRFS_I(inode)->outstanding_extents--;
spin_unlock(&BTRFS_I(inode)->accounting_lock);
btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root,
inode, 1);
- spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
+ spin_lock(&root->fs_info->ordered_extent_lock);
list_del_init(&entry->root_extent_list);
/*
@@ -324,7 +330,7 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
!mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) {
list_del_init(&BTRFS_I(inode)->ordered_operations);
}
- spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
+ spin_unlock(&root->fs_info->ordered_extent_lock);
return 0;
}
@@ -340,9 +346,9 @@ int btrfs_remove_ordered_extent(struct inode *inode,
int ret;
tree = &BTRFS_I(inode)->ordered_tree;
- mutex_lock(&tree->mutex);
+ spin_lock(&tree->lock);
ret = __btrfs_remove_ordered_extent(inode, entry);
- mutex_unlock(&tree->mutex);
+ spin_unlock(&tree->lock);
wake_up(&entry->wait);
return ret;
@@ -567,7 +573,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
struct btrfs_ordered_extent *entry = NULL;
tree = &BTRFS_I(inode)->ordered_tree;
- mutex_lock(&tree->mutex);
+ spin_lock(&tree->lock);
node = tree_search(tree, file_offset);
if (!node)
goto out;
@@ -578,7 +584,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
if (entry)
atomic_inc(&entry->refs);
out:
- mutex_unlock(&tree->mutex);
+ spin_unlock(&tree->lock);
return entry;
}
@@ -594,7 +600,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
struct btrfs_ordered_extent *entry = NULL;
tree = &BTRFS_I(inode)->ordered_tree;
- mutex_lock(&tree->mutex);
+ spin_lock(&tree->lock);
node = tree_search(tree, file_offset);
if (!node)
goto out;
@@ -602,7 +608,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
atomic_inc(&entry->refs);
out:
- mutex_unlock(&tree->mutex);
+ spin_unlock(&tree->lock);
return entry;
}
@@ -629,7 +635,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
else
offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
- mutex_lock(&tree->mutex);
+ spin_lock(&tree->lock);
disk_i_size = BTRFS_I(inode)->disk_i_size;
/* truncate file */
@@ -735,7 +741,7 @@ out:
*/
if (ordered)
__btrfs_remove_ordered_extent(inode, ordered);
- mutex_unlock(&tree->mutex);
+ spin_unlock(&tree->lock);
if (ordered)
wake_up(&ordered->wait);
return ret;
@@ -762,7 +768,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
if (!ordered)
return 1;
- mutex_lock(&tree->mutex);
+ spin_lock(&tree->lock);
list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
if (disk_bytenr >= ordered_sum->bytenr) {
num_sectors = ordered_sum->len / sectorsize;
@@ -777,7 +783,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
}
}
out:
- mutex_unlock(&tree->mutex);
+ spin_unlock(&tree->lock);
btrfs_put_ordered_extent(ordered);
return ret;
}
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index 1fe1282ef47..c82f76a9f04 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -21,7 +21,7 @@
/* one of these per inode */
struct btrfs_ordered_inode_tree {
- struct mutex mutex;
+ spinlock_t lock;
struct rb_root tree;
struct rb_node *last;
};
@@ -128,8 +128,8 @@ static inline int btrfs_ordered_sum_size(struct btrfs_root *root,
static inline void
btrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t)
{
- mutex_init(&t->mutex);
- t->tree.rb_node = NULL;
+ spin_lock_init(&t->lock);
+ t->tree = RB_ROOT;
t->last = NULL;
}
@@ -137,7 +137,8 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry);
int btrfs_remove_ordered_extent(struct inode *inode,
struct btrfs_ordered_extent *entry);
int btrfs_dec_test_ordered_pending(struct inode *inode,
- u64 file_offset, u64 io_size);
+ struct btrfs_ordered_extent **cached,
+ u64 file_offset, u64 io_size);
int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
u64 start, u64 len, u64 disk_len, int tyep);
int btrfs_add_ordered_sum(struct inode *inode,
diff --git a/fs/btrfs/ref-cache.c b/fs/btrfs/ref-cache.c
index d0cc62bccb9..a97314cf6bd 100644
--- a/fs/btrfs/ref-cache.c
+++ b/fs/btrfs/ref-cache.c
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/sort.h>
#include "ctree.h"
#include "ref-cache.h"
diff --git a/fs/btrfs/ref-cache.h b/fs/btrfs/ref-cache.h
index bc283ad2db7..e2a55cb2072 100644
--- a/fs/btrfs/ref-cache.h
+++ b/fs/btrfs/ref-cache.h
@@ -52,7 +52,7 @@ static inline size_t btrfs_leaf_ref_size(int nr_extents)
static inline void btrfs_leaf_ref_tree_init(struct btrfs_leaf_ref_tree *tree)
{
- tree->root.rb_node = NULL;
+ tree->root = RB_ROOT;
INIT_LIST_HEAD(&tree->list);
spin_lock_init(&tree->lock);
}
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index ab7ab531874..e558dd941de 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -21,6 +21,7 @@
#include <linux/writeback.h>
#include <linux/blkdev.h>
#include <linux/rbtree.h>
+#include <linux/slab.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
@@ -170,14 +171,14 @@ struct async_merge {
static void mapping_tree_init(struct mapping_tree *tree)
{
- tree->rb_root.rb_node = NULL;
+ tree->rb_root = RB_ROOT;
spin_lock_init(&tree->lock);
}
static void backref_cache_init(struct backref_cache *cache)
{
int i;
- cache->rb_root.rb_node = NULL;
+ cache->rb_root = RB_ROOT;
for (i = 0; i < BTRFS_MAX_LEVEL; i++)
INIT_LIST_HEAD(&cache->pending[i]);
spin_lock_init(&cache->lock);
@@ -2659,7 +2660,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
EXTENT_BOUNDARY, GFP_NOFS);
nr++;
}
- btrfs_set_extent_delalloc(inode, page_start, page_end);
+ btrfs_set_extent_delalloc(inode, page_start, page_end, NULL);
set_page_dirty(page);
dirty_page++;
@@ -3487,7 +3488,7 @@ static struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
key.objectid = objectid;
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
- inode = btrfs_iget(root->fs_info->sb, &key, root);
+ inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
BUG_ON(IS_ERR(inode) || is_bad_inode(inode));
BTRFS_I(inode)->index_cnt = group->key.objectid;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 8a1ea6e6457..1866dff0538 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -38,6 +38,7 @@
#include <linux/namei.h>
#include <linux/miscdevice.h>
#include <linux/magic.h>
+#include <linux/slab.h>
#include "compat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -63,22 +64,21 @@ static void btrfs_put_super(struct super_block *sb)
}
enum {
- Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
- Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
- Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl,
- Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio,
- Opt_flushoncommit,
+ Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
+ Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd,
+ Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,
+ Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
Opt_discard, Opt_err,
};
static match_table_t tokens = {
{Opt_degraded, "degraded"},
{Opt_subvol, "subvol=%s"},
+ {Opt_subvolid, "subvolid=%d"},
{Opt_device, "device=%s"},
{Opt_nodatasum, "nodatasum"},
{Opt_nodatacow, "nodatacow"},
{Opt_nobarrier, "nobarrier"},
- {Opt_max_extent, "max_extent=%s"},
{Opt_max_inline, "max_inline=%s"},
{Opt_alloc_start, "alloc_start=%s"},
{Opt_thread_pool, "thread_pool=%d"},
@@ -95,31 +95,6 @@ static match_table_t tokens = {
{Opt_err, NULL},
};
-u64 btrfs_parse_size(char *str)
-{
- u64 res;
- int mult = 1;
- char *end;
- char last;
-
- res = simple_strtoul(str, &end, 10);
-
- last = end[0];
- if (isalpha(last)) {
- last = tolower(last);
- switch (last) {
- case 'g':
- mult *= 1024;
- case 'm':
- mult *= 1024;
- case 'k':
- mult *= 1024;
- }
- res = res * mult;
- }
- return res;
-}
-
/*
* Regular mount options parser. Everything that is needed only when
* reading in a new superblock is parsed here.
@@ -128,7 +103,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
{
struct btrfs_fs_info *info = root->fs_info;
substring_t args[MAX_OPT_ARGS];
- char *p, *num;
+ char *p, *num, *orig;
int intarg;
int ret = 0;
@@ -143,6 +118,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
if (!options)
return -ENOMEM;
+ orig = options;
while ((p = strsep(&options, ",")) != NULL) {
int token;
@@ -156,6 +132,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
btrfs_set_opt(info->mount_opt, DEGRADED);
break;
case Opt_subvol:
+ case Opt_subvolid:
case Opt_device:
/*
* These are parsed by btrfs_parse_early_options
@@ -210,22 +187,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
info->thread_pool_size);
}
break;
- case Opt_max_extent:
- num = match_strdup(&args[0]);
- if (num) {
- info->max_extent = btrfs_parse_size(num);
- kfree(num);
-
- info->max_extent = max_t(u64,
- info->max_extent, root->sectorsize);
- printk(KERN_INFO "btrfs: max_extent at %llu\n",
- (unsigned long long)info->max_extent);
- }
- break;
case Opt_max_inline:
num = match_strdup(&args[0]);
if (num) {
- info->max_inline = btrfs_parse_size(num);
+ info->max_inline = memparse(num, NULL);
kfree(num);
if (info->max_inline) {
@@ -240,7 +205,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
case Opt_alloc_start:
num = match_strdup(&args[0]);
if (num) {
- info->alloc_start = btrfs_parse_size(num);
+ info->alloc_start = memparse(num, NULL);
kfree(num);
printk(KERN_INFO
"btrfs: allocations start at %llu\n",
@@ -280,7 +245,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
}
}
out:
- kfree(options);
+ kfree(orig);
return ret;
}
@@ -291,12 +256,13 @@ out:
* only when we need to allocate a new super block.
*/
static int btrfs_parse_early_options(const char *options, fmode_t flags,
- void *holder, char **subvol_name,
+ void *holder, char **subvol_name, u64 *subvol_objectid,
struct btrfs_fs_devices **fs_devices)
{
substring_t args[MAX_OPT_ARGS];
char *opts, *p;
int error = 0;
+ int intarg;
if (!options)
goto out;
@@ -319,6 +285,18 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
case Opt_subvol:
*subvol_name = match_strdup(&args[0]);
break;
+ case Opt_subvolid:
+ intarg = 0;
+ error = match_int(&args[0], &intarg);
+ if (!error) {
+ /* we want the original fs_tree */
+ if (!intarg)
+ *subvol_objectid =
+ BTRFS_FS_TREE_OBJECTID;
+ else
+ *subvol_objectid = intarg;
+ }
+ break;
case Opt_device:
error = btrfs_scan_one_device(match_strdup(&args[0]),
flags, holder, fs_devices);
@@ -346,6 +324,110 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
return error;
}
+static struct dentry *get_default_root(struct super_block *sb,
+ u64 subvol_objectid)
+{
+ struct btrfs_root *root = sb->s_fs_info;
+ struct btrfs_root *new_root;
+ struct btrfs_dir_item *di;
+ struct btrfs_path *path;
+ struct btrfs_key location;
+ struct inode *inode;
+ struct dentry *dentry;
+ u64 dir_id;
+ int new = 0;
+
+ /*
+ * We have a specific subvol we want to mount, just setup location and
+ * go look up the root.
+ */
+ if (subvol_objectid) {
+ location.objectid = subvol_objectid;
+ location.type = BTRFS_ROOT_ITEM_KEY;
+ location.offset = (u64)-1;
+ goto find_root;
+ }
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return ERR_PTR(-ENOMEM);
+ path->leave_spinning = 1;
+
+ /*
+ * Find the "default" dir item which points to the root item that we
+ * will mount by default if we haven't been given a specific subvolume
+ * to mount.
+ */
+ dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+ di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
+ if (!di) {
+ /*
+ * Ok the default dir item isn't there. This is weird since
+ * it's always been there, but don't freak out, just try and
+ * mount to root most subvolume.
+ */
+ btrfs_free_path(path);
+ dir_id = BTRFS_FIRST_FREE_OBJECTID;
+ new_root = root->fs_info->fs_root;
+ goto setup_root;
+ }
+
+ btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
+ btrfs_free_path(path);
+
+find_root:
+ new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
+ if (IS_ERR(new_root))
+ return ERR_PTR(PTR_ERR(new_root));
+
+ if (btrfs_root_refs(&new_root->root_item) == 0)
+ return ERR_PTR(-ENOENT);
+
+ dir_id = btrfs_root_dirid(&new_root->root_item);
+setup_root:
+ location.objectid = dir_id;
+ location.type = BTRFS_INODE_ITEM_KEY;
+ location.offset = 0;
+
+ inode = btrfs_iget(sb, &location, new_root, &new);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * If we're just mounting the root most subvol put the inode and return
+ * a reference to the dentry. We will have already gotten a reference
+ * to the inode in btrfs_fill_super so we're good to go.
+ */
+ if (!new && sb->s_root->d_inode == inode) {
+ iput(inode);
+ return dget(sb->s_root);
+ }
+
+ if (new) {
+ const struct qstr name = { .name = "/", .len = 1 };
+
+ /*
+ * New inode, we need to make the dentry a sibling of s_root so
+ * everything gets cleaned up properly on unmount.
+ */
+ dentry = d_alloc(sb->s_root, &name);
+ if (!dentry) {
+ iput(inode);
+ return ERR_PTR(-ENOMEM);
+ }
+ d_splice_alias(inode, dentry);
+ } else {
+ /*
+ * We found the inode in cache, just find a dentry for it and
+ * put the reference to the inode we just got.
+ */
+ dentry = d_find_alias(inode);
+ iput(inode);
+ }
+
+ return dentry;
+}
+
static int btrfs_fill_super(struct super_block *sb,
struct btrfs_fs_devices *fs_devices,
void *data, int silent)
@@ -379,7 +461,7 @@ static int btrfs_fill_super(struct super_block *sb,
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
- inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root);
+ inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto fail_close;
@@ -391,12 +473,6 @@ static int btrfs_fill_super(struct super_block *sb,
err = -ENOMEM;
goto fail_close;
}
-#if 0
- /* this does the super kobj at the same time */
- err = btrfs_sysfs_add_super(tree_root->fs_info);
- if (err)
- goto fail_close;
-#endif
sb->s_root = root_dentry;
@@ -440,9 +516,6 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
seq_puts(seq, ",nodatacow");
if (btrfs_test_opt(root, NOBARRIER))
seq_puts(seq, ",nobarrier");
- if (info->max_extent != (u64)-1)
- seq_printf(seq, ",max_extent=%llu",
- (unsigned long long)info->max_extent);
if (info->max_inline != 8192 * 1024)
seq_printf(seq, ",max_inline=%llu",
(unsigned long long)info->max_inline);
@@ -488,19 +561,22 @@ static int btrfs_test_super(struct super_block *s, void *data)
static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt)
{
- char *subvol_name = NULL;
struct block_device *bdev = NULL;
struct super_block *s;
struct dentry *root;
struct btrfs_fs_devices *fs_devices = NULL;
fmode_t mode = FMODE_READ;
+ char *subvol_name = NULL;
+ u64 subvol_objectid = 0;
int error = 0;
+ int found = 0;
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
error = btrfs_parse_early_options(data, mode, fs_type,
- &subvol_name, &fs_devices);
+ &subvol_name, &subvol_objectid,
+ &fs_devices);
if (error)
return error;
@@ -529,6 +605,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
goto error_close_devices;
}
+ found = 1;
btrfs_close_devices(fs_devices);
} else {
char b[BDEVNAME_SIZE];
@@ -546,25 +623,35 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
s->s_flags |= MS_ACTIVE;
}
- if (!strcmp(subvol_name, "."))
- root = dget(s->s_root);
- else {
- mutex_lock(&s->s_root->d_inode->i_mutex);
- root = lookup_one_len(subvol_name, s->s_root,
+ root = get_default_root(s, subvol_objectid);
+ if (IS_ERR(root)) {
+ error = PTR_ERR(root);
+ deactivate_locked_super(s);
+ goto error;
+ }
+ /* if they gave us a subvolume name bind mount into that */
+ if (strcmp(subvol_name, ".")) {
+ struct dentry *new_root;
+ mutex_lock(&root->d_inode->i_mutex);
+ new_root = lookup_one_len(subvol_name, root,
strlen(subvol_name));
- mutex_unlock(&s->s_root->d_inode->i_mutex);
+ mutex_unlock(&root->d_inode->i_mutex);
- if (IS_ERR(root)) {
+ if (IS_ERR(new_root)) {
deactivate_locked_super(s);
- error = PTR_ERR(root);
- goto error_free_subvol_name;
+ error = PTR_ERR(new_root);
+ dput(root);
+ goto error_close_devices;
}
- if (!root->d_inode) {
+ if (!new_root->d_inode) {
dput(root);
+ dput(new_root);
deactivate_locked_super(s);
error = -ENXIO;
- goto error_free_subvol_name;
+ goto error_close_devices;
}
+ dput(root);
+ root = new_root;
}
mnt->mnt_sb = s;
@@ -579,6 +666,7 @@ error_close_devices:
btrfs_close_devices(fs_devices);
error_free_subvol_name:
kfree(subvol_name);
+error:
return error;
}
@@ -623,14 +711,37 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct btrfs_root *root = btrfs_sb(dentry->d_sb);
struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
+ struct list_head *head = &root->fs_info->space_info;
+ struct btrfs_space_info *found;
+ u64 total_used = 0;
+ u64 data_used = 0;
int bits = dentry->d_sb->s_blocksize_bits;
__be32 *fsid = (__be32 *)root->fs_info->fsid;
+ rcu_read_lock();
+ list_for_each_entry_rcu(found, head, list) {
+ if (found->flags & (BTRFS_BLOCK_GROUP_DUP|
+ BTRFS_BLOCK_GROUP_RAID10|
+ BTRFS_BLOCK_GROUP_RAID1)) {
+ total_used += found->bytes_used;
+ if (found->flags & BTRFS_BLOCK_GROUP_DATA)
+ data_used += found->bytes_used;
+ else
+ data_used += found->total_bytes;
+ }
+
+ total_used += found->bytes_used;
+ if (found->flags & BTRFS_BLOCK_GROUP_DATA)
+ data_used += found->bytes_used;
+ else
+ data_used += found->total_bytes;
+ }
+ rcu_read_unlock();
+
buf->f_namelen = BTRFS_NAME_LEN;
buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
- buf->f_bfree = buf->f_blocks -
- (btrfs_super_bytes_used(disk_super) >> bits);
- buf->f_bavail = buf->f_bfree;
+ buf->f_bfree = buf->f_blocks - (total_used >> bits);
+ buf->f_bavail = buf->f_blocks - (data_used >> bits);
buf->f_bsize = dentry->d_sb->s_blocksize;
buf->f_type = BTRFS_SUPER_MAGIC;
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index a240b6fa81d..4ce16ef702a 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -164,12 +164,12 @@ static void btrfs_root_release(struct kobject *kobj)
complete(&root->kobj_unregister);
}
-static struct sysfs_ops btrfs_super_attr_ops = {
+static const struct sysfs_ops btrfs_super_attr_ops = {
.show = btrfs_super_attr_show,
.store = btrfs_super_attr_store,
};
-static struct sysfs_ops btrfs_root_attr_ops = {
+static const struct sysfs_ops btrfs_root_attr_ops = {
.show = btrfs_root_attr_show,
.store = btrfs_root_attr_store,
};
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index b2acc79f1b3..2cb116099b9 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -17,6 +17,7 @@
*/
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/writeback.h>
#include <linux/pagemap.h>
@@ -69,7 +70,7 @@ static noinline int join_transaction(struct btrfs_root *root)
cur_trans->commit_done = 0;
cur_trans->start_time = get_seconds();
- cur_trans->delayed_refs.root.rb_node = NULL;
+ cur_trans->delayed_refs.root = RB_ROOT;
cur_trans->delayed_refs.num_entries = 0;
cur_trans->delayed_refs.num_heads_ready = 0;
cur_trans->delayed_refs.num_heads = 0;
@@ -147,18 +148,13 @@ static void wait_current_trans(struct btrfs_root *root)
while (1) {
prepare_to_wait(&root->fs_info->transaction_wait, &wait,
TASK_UNINTERRUPTIBLE);
- if (cur_trans->blocked) {
- mutex_unlock(&root->fs_info->trans_mutex);
- schedule();
- mutex_lock(&root->fs_info->trans_mutex);
- finish_wait(&root->fs_info->transaction_wait,
- &wait);
- } else {
- finish_wait(&root->fs_info->transaction_wait,
- &wait);
+ if (!cur_trans->blocked)
break;
- }
+ mutex_unlock(&root->fs_info->trans_mutex);
+ schedule();
+ mutex_lock(&root->fs_info->trans_mutex);
}
+ finish_wait(&root->fs_info->transaction_wait, &wait);
put_transaction(cur_trans);
}
}
@@ -760,10 +756,17 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
struct btrfs_root_item *new_root_item;
struct btrfs_root *tree_root = fs_info->tree_root;
struct btrfs_root *root = pending->root;
+ struct btrfs_root *parent_root;
+ struct inode *parent_inode;
struct extent_buffer *tmp;
struct extent_buffer *old;
int ret;
u64 objectid;
+ int namelen;
+ u64 index = 0;
+
+ parent_inode = pending->dentry->d_parent->d_inode;
+ parent_root = BTRFS_I(parent_inode)->root;
new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
if (!new_root_item) {
@@ -774,79 +777,59 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
if (ret)
goto fail;
- record_root_in_trans(trans, root);
- btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
- memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
-
key.objectid = objectid;
/* record when the snapshot was created in key.offset */
key.offset = trans->transid;
btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
- old = btrfs_lock_root_node(root);
- btrfs_cow_block(trans, root, old, NULL, 0, &old);
- btrfs_set_lock_blocking(old);
-
- btrfs_copy_root(trans, root, old, &tmp, objectid);
- btrfs_tree_unlock(old);
- free_extent_buffer(old);
-
- btrfs_set_root_node(new_root_item, tmp);
- ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
- new_root_item);
- btrfs_tree_unlock(tmp);
- free_extent_buffer(tmp);
- if (ret)
- goto fail;
-
- key.offset = (u64)-1;
memcpy(&pending->root_key, &key, sizeof(key));
-fail:
- kfree(new_root_item);
- return ret;
-}
-
-static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
- struct btrfs_pending_snapshot *pending)
-{
- int ret;
- int namelen;
- u64 index = 0;
- struct btrfs_trans_handle *trans;
- struct inode *parent_inode;
- struct btrfs_root *parent_root;
-
- parent_inode = pending->dentry->d_parent->d_inode;
- parent_root = BTRFS_I(parent_inode)->root;
- trans = btrfs_join_transaction(parent_root, 1);
+ pending->root_key.offset = (u64)-1;
+ record_root_in_trans(trans, parent_root);
/*
* insert the directory item
*/
namelen = strlen(pending->name);
ret = btrfs_set_inode_index(parent_inode, &index);
+ BUG_ON(ret);
ret = btrfs_insert_dir_item(trans, parent_root,
pending->name, namelen,
parent_inode->i_ino,
&pending->root_key, BTRFS_FT_DIR, index);
-
- if (ret)
- goto fail;
+ BUG_ON(ret);
btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2);
ret = btrfs_update_inode(trans, parent_root, parent_inode);
BUG_ON(ret);
+ record_root_in_trans(trans, root);
+ btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
+ memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
+
+ old = btrfs_lock_root_node(root);
+ btrfs_cow_block(trans, root, old, NULL, 0, &old);
+ btrfs_set_lock_blocking(old);
+
+ btrfs_copy_root(trans, root, old, &tmp, objectid);
+ btrfs_tree_unlock(old);
+ free_extent_buffer(old);
+
+ btrfs_set_root_node(new_root_item, tmp);
+ ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
+ new_root_item);
+ BUG_ON(ret);
+ btrfs_tree_unlock(tmp);
+ free_extent_buffer(tmp);
+
ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root,
pending->root_key.objectid,
parent_root->root_key.objectid,
parent_inode->i_ino, index, pending->name,
namelen);
-
BUG_ON(ret);
fail:
- btrfs_end_transaction(trans, fs_info->fs_root);
+ kfree(new_root_item);
return ret;
}
@@ -867,25 +850,6 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
return 0;
}
-static noinline int finish_pending_snapshots(struct btrfs_trans_handle *trans,
- struct btrfs_fs_info *fs_info)
-{
- struct btrfs_pending_snapshot *pending;
- struct list_head *head = &trans->transaction->pending_snapshots;
- int ret;
-
- while (!list_empty(head)) {
- pending = list_entry(head->next,
- struct btrfs_pending_snapshot, list);
- ret = finish_pending_snapshot(fs_info, pending);
- BUG_ON(ret);
- list_del(&pending->list);
- kfree(pending->name);
- kfree(pending);
- }
- return 0;
-}
-
static void update_super_roots(struct btrfs_root *root)
{
struct btrfs_root_item *root_item;
@@ -997,13 +961,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
mutex_unlock(&root->fs_info->trans_mutex);
- if (flush_on_commit) {
+ if (flush_on_commit || snap_pending) {
btrfs_start_delalloc_inodes(root, 1);
ret = btrfs_wait_ordered_extents(root, 0, 1);
BUG_ON(ret);
- } else if (snap_pending) {
- ret = btrfs_wait_ordered_extents(root, 0, 1);
- BUG_ON(ret);
}
/*
@@ -1100,9 +1061,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
btrfs_finish_extent_commit(trans, root);
- /* do the directory inserts of any pending snapshot creations */
- finish_pending_snapshots(trans, root->fs_info);
-
mutex_lock(&root->fs_info->trans_mutex);
cur_trans->commit_done = 1;
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 4a9434b622e..af57dd2b43d 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include "ctree.h"
#include "transaction.h"
#include "disk-io.h"
@@ -445,7 +446,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root,
key.objectid = objectid;
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
- inode = btrfs_iget(root->fs_info->sb, &key, root);
+ inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
if (IS_ERR(inode)) {
inode = NULL;
} else if (is_bad_inode(inode)) {
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 41ecbb2347f..8db7b14bbae 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
#include <linux/bio.h>
+#include <linux/slab.h>
#include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include <linux/random.h>
@@ -256,13 +257,13 @@ loop_lock:
wake_up(&fs_info->async_submit_wait);
BUG_ON(atomic_read(&cur->bi_cnt) == 0);
- submit_bio(cur->bi_rw, cur);
- num_run++;
- batch_run++;
if (bio_rw_flagged(cur, BIO_RW_SYNCIO))
num_sync_run++;
+ submit_bio(cur->bi_rw, cur);
+ num_run++;
+ batch_run++;
if (need_resched()) {
if (num_sync_run) {
blk_run_backing_dev(bdi, NULL);
@@ -325,16 +326,6 @@ loop_lock:
num_sync_run = 0;
blk_run_backing_dev(bdi, NULL);
}
-
- cond_resched();
- if (again)
- goto loop;
-
- spin_lock(&device->io_lock);
- if (device->pending_bios.head || device->pending_sync_bios.head)
- goto loop_lock;
- spin_unlock(&device->io_lock);
-
/*
* IO has already been through a long path to get here. Checksumming,
* async helper threads, perhaps compression. We've done a pretty
@@ -346,6 +337,16 @@ loop_lock:
* cared about found its way down here.
*/
blk_run_backing_dev(bdi, NULL);
+
+ cond_resched();
+ if (again)
+ goto loop;
+
+ spin_lock(&device->io_lock);
+ if (device->pending_bios.head || device->pending_sync_bios.head)
+ goto loop_lock;
+ spin_unlock(&device->io_lock);
+
done:
return 0;
}
@@ -365,6 +366,7 @@ static noinline int device_list_add(const char *path,
struct btrfs_device *device;
struct btrfs_fs_devices *fs_devices;
u64 found_transid = btrfs_super_generation(disk_super);
+ char *name;
fs_devices = find_fsid(disk_super->fsid);
if (!fs_devices) {
@@ -411,6 +413,12 @@ static noinline int device_list_add(const char *path,
device->fs_devices = fs_devices;
fs_devices->num_devices++;
+ } else if (strcmp(device->name, path)) {
+ name = kstrdup(path, GFP_NOFS);
+ if (!name)
+ return -ENOMEM;
+ kfree(device->name);
+ device->name = name;
}
if (found_transid > fs_devices->latest_trans) {
@@ -592,7 +600,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
goto error_close;
disk_super = (struct btrfs_super_block *)bh->b_data;
- devid = le64_to_cpu(disk_super->dev_item.devid);
+ devid = btrfs_stack_device_id(&disk_super->dev_item);
if (devid != device->devid)
goto error_brelse;
@@ -694,7 +702,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
goto error_close;
}
disk_super = (struct btrfs_super_block *)bh->b_data;
- devid = le64_to_cpu(disk_super->dev_item.devid);
+ devid = btrfs_stack_device_id(&disk_super->dev_item);
transid = btrfs_super_generation(disk_super);
if (disk_super->label[0])
printk(KERN_INFO "device label %s ", disk_super->label);
@@ -1187,7 +1195,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
goto error_close;
}
disk_super = (struct btrfs_super_block *)bh->b_data;
- devid = le64_to_cpu(disk_super->dev_item.devid);
+ devid = btrfs_stack_device_id(&disk_super->dev_item);
dev_uuid = disk_super->dev_item.uuid;
device = btrfs_find_device(root, devid, dev_uuid,
disk_super->fsid);
@@ -2191,9 +2199,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
min_stripes = 2;
}
if (type & (BTRFS_BLOCK_GROUP_RAID1)) {
- num_stripes = min_t(u64, 2, fs_devices->rw_devices);
- if (num_stripes < 2)
+ if (fs_devices->rw_devices < 2)
return -ENOSPC;
+ num_stripes = 2;
min_stripes = 2;
}
if (type & (BTRFS_BLOCK_GROUP_RAID10)) {
@@ -2237,8 +2245,16 @@ again:
do_div(calc_size, stripe_len);
calc_size *= stripe_len;
}
+
/* we don't want tiny stripes */
- calc_size = max_t(u64, min_stripe_size, calc_size);
+ if (!looped)
+ calc_size = max_t(u64, min_stripe_size, calc_size);
+
+ /*
+ * we're about to do_div by the stripe_len so lets make sure
+ * we end up with something bigger than a stripe
+ */
+ calc_size = max_t(u64, calc_size, stripe_len * 4);
do_div(calc_size, stripe_len);
calc_size *= stripe_len;
@@ -3382,6 +3398,8 @@ int btrfs_read_chunk_tree(struct btrfs_root *root)
key.type = 0;
again:
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ if (ret < 0)
+ goto error;
while (1) {
leaf = path->nodes[0];
slot = path->slots[0];
diff --git a/fs/buffer.c b/fs/buffer.c
index 6fa530256bf..c9c266db062 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2893,7 +2893,7 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block,
/*
* The page straddles i_size. It must be zeroed out on each and every
- * writepage invokation because it may be mmapped. "A file is mapped
+ * writepage invocation because it may be mmapped. "A file is mapped
* in multiples of the page size. For a file that is not a multiple of
* the page size, the remaining memory is zeroed when mapped, and
* writes to that region are not written out to the file."
@@ -3265,7 +3265,7 @@ static void recalc_bh_state(void)
struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
{
- struct buffer_head *ret = kmem_cache_alloc(bh_cachep, gfp_flags);
+ struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
if (ret) {
INIT_LIST_HEAD(&ret->b_assoc_buffers);
get_cpu_var(bh_accounting).nr++;
@@ -3352,15 +3352,6 @@ int bh_submit_read(struct buffer_head *bh)
}
EXPORT_SYMBOL(bh_submit_read);
-static void
-init_buffer_head(void *data)
-{
- struct buffer_head *bh = data;
-
- memset(bh, 0, sizeof(*bh));
- INIT_LIST_HEAD(&bh->b_assoc_buffers);
-}
-
void __init buffer_init(void)
{
int nrpages;
@@ -3369,7 +3360,7 @@ void __init buffer_init(void)
sizeof(struct buffer_head), 0,
(SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
SLAB_MEM_SPREAD),
- init_buffer_head);
+ NULL);
/*
* Limit the bh occupancy to 10% of ZONE_NORMAL
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 27089311fbe..37fe101a4e0 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -9,6 +9,7 @@
* 2 of the Licence, or (at your option) any later version.
*/
+#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/buffer_head.h>
#include "internal.h"
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index eeb4986ea7d..d5db84a1ee0 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -19,6 +19,7 @@
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/security.h>
+#include <linux/slab.h>
#include "internal.h"
#define CACHEFILES_KEYBUF_SIZE 512
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index 1d833256386..0f0d41fbb03 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -10,6 +10,7 @@
*/
#include <linux/mount.h>
+#include <linux/slab.h>
#include <linux/file.h>
#include "internal.h"
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index f3e7a0bf068..e18b183b47e 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -16,6 +16,7 @@
#include <linux/fsnotify.h>
#include <linux/quotaops.h>
#include <linux/xattr.h>
+#include <linux/slab.h>
#include "internal.h"
static const char cachefiles_xattr_cache[] =
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig
new file mode 100644
index 00000000000..04b8280582a
--- /dev/null
+++ b/fs/ceph/Kconfig
@@ -0,0 +1,27 @@
+config CEPH_FS
+ tristate "Ceph distributed file system (EXPERIMENTAL)"
+ depends on INET && EXPERIMENTAL
+ select LIBCRC32C
+ select CONFIG_CRYPTO_AES
+ help
+ Choose Y or M here to include support for mounting the
+ experimental Ceph distributed file system. Ceph is an extremely
+ scalable file system designed to provide high performance,
+ reliable access to petabytes of storage.
+
+ More information at http://ceph.newdream.net/.
+
+ If unsure, say N.
+
+config CEPH_FS_PRETTYDEBUG
+ bool "Include file:line in ceph debug output"
+ depends on CEPH_FS
+ default n
+ help
+ If you say Y here, debug output will include a filename and
+ line to aid debugging. This icnreases kernel size and slows
+ execution slightly when debug call sites are enabled (e.g.,
+ via CONFIG_DYNAMIC_DEBUG).
+
+ If unsure, say N.
+
diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile
new file mode 100644
index 00000000000..6a660e610be
--- /dev/null
+++ b/fs/ceph/Makefile
@@ -0,0 +1,39 @@
+#
+# Makefile for CEPH filesystem.
+#
+
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_CEPH_FS) += ceph.o
+
+ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \
+ export.o caps.o snap.o xattr.o \
+ messenger.o msgpool.o buffer.o pagelist.o \
+ mds_client.o mdsmap.o \
+ mon_client.o \
+ osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \
+ debugfs.o \
+ auth.o auth_none.o \
+ crypto.o armor.o \
+ auth_x.o \
+ ceph_fs.o ceph_strings.o ceph_hash.o ceph_frag.o
+
+else
+#Otherwise we were called directly from the command
+# line; invoke the kernel build system.
+
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+
+default: all
+
+all:
+ $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules
+
+modules_install:
+ $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules_install
+
+clean:
+ $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
+
+endif
diff --git a/fs/ceph/README b/fs/ceph/README
new file mode 100644
index 00000000000..18352fab37c
--- /dev/null
+++ b/fs/ceph/README
@@ -0,0 +1,20 @@
+#
+# The following files are shared by (and manually synchronized
+# between) the Ceph userland and kernel client.
+#
+# userland kernel
+src/include/ceph_fs.h fs/ceph/ceph_fs.h
+src/include/ceph_fs.cc fs/ceph/ceph_fs.c
+src/include/msgr.h fs/ceph/msgr.h
+src/include/rados.h fs/ceph/rados.h
+src/include/ceph_strings.cc fs/ceph/ceph_strings.c
+src/include/ceph_frag.h fs/ceph/ceph_frag.h
+src/include/ceph_frag.cc fs/ceph/ceph_frag.c
+src/include/ceph_hash.h fs/ceph/ceph_hash.h
+src/include/ceph_hash.cc fs/ceph/ceph_hash.c
+src/crush/crush.c fs/ceph/crush/crush.c
+src/crush/crush.h fs/ceph/crush/crush.h
+src/crush/mapper.c fs/ceph/crush/mapper.c
+src/crush/mapper.h fs/ceph/crush/mapper.h
+src/crush/hash.h fs/ceph/crush/hash.h
+src/crush/hash.c fs/ceph/crush/hash.c
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
new file mode 100644
index 00000000000..412593703d1
--- /dev/null
+++ b/fs/ceph/addr.c
@@ -0,0 +1,1193 @@
+#include "ceph_debug.h"
+
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/writeback.h> /* generic_writepages */
+#include <linux/slab.h>
+#include <linux/pagevec.h>
+#include <linux/task_io_accounting_ops.h>
+
+#include "super.h"
+#include "osd_client.h"
+
+/*
+ * Ceph address space ops.
+ *
+ * There are a few funny things going on here.
+ *
+ * The page->private field is used to reference a struct
+ * ceph_snap_context for _every_ dirty page. This indicates which
+ * snapshot the page was logically dirtied in, and thus which snap
+ * context needs to be associated with the osd write during writeback.
+ *
+ * Similarly, struct ceph_inode_info maintains a set of counters to
+ * count dirty pages on the inode. In the absense of snapshots,
+ * i_wrbuffer_ref == i_wrbuffer_ref_head == the dirty page count.
+ *
+ * When a snapshot is taken (that is, when the client receives
+ * notification that a snapshot was taken), each inode with caps and
+ * with dirty pages (dirty pages implies there is a cap) gets a new
+ * ceph_cap_snap in the i_cap_snaps list (which is sorted in ascending
+ * order, new snaps go to the tail). The i_wrbuffer_ref_head count is
+ * moved to capsnap->dirty. (Unless a sync write is currently in
+ * progress. In that case, the capsnap is said to be "pending", new
+ * writes cannot start, and the capsnap isn't "finalized" until the
+ * write completes (or fails) and a final size/mtime for the inode for
+ * that snap can be settled upon.) i_wrbuffer_ref_head is reset to 0.
+ *
+ * On writeback, we must submit writes to the osd IN SNAP ORDER. So,
+ * we look for the first capsnap in i_cap_snaps and write out pages in
+ * that snap context _only_. Then we move on to the next capsnap,
+ * eventually reaching the "live" or "head" context (i.e., pages that
+ * are not yet snapped) and are writing the most recently dirtied
+ * pages.
+ *
+ * Invalidate and so forth must take care to ensure the dirty page
+ * accounting is preserved.
+ */
+
+#define CONGESTION_ON_THRESH(congestion_kb) (congestion_kb >> (PAGE_SHIFT-10))
+#define CONGESTION_OFF_THRESH(congestion_kb) \
+ (CONGESTION_ON_THRESH(congestion_kb) - \
+ (CONGESTION_ON_THRESH(congestion_kb) >> 2))
+
+
+
+/*
+ * Dirty a page. Optimistically adjust accounting, on the assumption
+ * that we won't race with invalidate. If we do, readjust.
+ */
+static int ceph_set_page_dirty(struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+ struct inode *inode;
+ struct ceph_inode_info *ci;
+ int undo = 0;
+ struct ceph_snap_context *snapc;
+
+ if (unlikely(!mapping))
+ return !TestSetPageDirty(page);
+
+ if (TestSetPageDirty(page)) {
+ dout("%p set_page_dirty %p idx %lu -- already dirty\n",
+ mapping->host, page, page->index);
+ return 0;
+ }
+
+ inode = mapping->host;
+ ci = ceph_inode(inode);
+
+ /*
+ * Note that we're grabbing a snapc ref here without holding
+ * any locks!
+ */
+ snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context);
+
+ /* dirty the head */
+ spin_lock(&inode->i_lock);
+ if (ci->i_wrbuffer_ref_head == 0)
+ ci->i_head_snapc = ceph_get_snap_context(snapc);
+ ++ci->i_wrbuffer_ref_head;
+ if (ci->i_wrbuffer_ref == 0)
+ igrab(inode);
+ ++ci->i_wrbuffer_ref;
+ dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d "
+ "snapc %p seq %lld (%d snaps)\n",
+ mapping->host, page, page->index,
+ ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref_head-1,
+ ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
+ snapc, snapc->seq, snapc->num_snaps);
+ spin_unlock(&inode->i_lock);
+
+ /* now adjust page */
+ spin_lock_irq(&mapping->tree_lock);
+ if (page->mapping) { /* Race with truncate? */
+ WARN_ON_ONCE(!PageUptodate(page));
+
+ if (mapping_cap_account_dirty(mapping)) {
+ __inc_zone_page_state(page, NR_FILE_DIRTY);
+ __inc_bdi_stat(mapping->backing_dev_info,
+ BDI_RECLAIMABLE);
+ task_io_account_write(PAGE_CACHE_SIZE);
+ }
+ radix_tree_tag_set(&mapping->page_tree,
+ page_index(page), PAGECACHE_TAG_DIRTY);
+
+ /*
+ * Reference snap context in page->private. Also set
+ * PagePrivate so that we get invalidatepage callback.
+ */
+ page->private = (unsigned long)snapc;
+ SetPagePrivate(page);
+ } else {
+ dout("ANON set_page_dirty %p (raced truncate?)\n", page);
+ undo = 1;
+ }
+
+ spin_unlock_irq(&mapping->tree_lock);
+
+ if (undo)
+ /* whoops, we failed to dirty the page */
+ ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+
+ __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
+
+ BUG_ON(!PageDirty(page));
+ return 1;
+}
+
+/*
+ * If we are truncating the full page (i.e. offset == 0), adjust the
+ * dirty page counters appropriately. Only called if there is private
+ * data on the page.
+ */
+static void ceph_invalidatepage(struct page *page, unsigned long offset)
+{
+ struct inode *inode;
+ struct ceph_inode_info *ci;
+ struct ceph_snap_context *snapc = (void *)page->private;
+
+ BUG_ON(!PageLocked(page));
+ BUG_ON(!page->private);
+ BUG_ON(!PagePrivate(page));
+ BUG_ON(!page->mapping);
+
+ inode = page->mapping->host;
+
+ /*
+ * We can get non-dirty pages here due to races between
+ * set_page_dirty and truncate_complete_page; just spit out a
+ * warning, in case we end up with accounting problems later.
+ */
+ if (!PageDirty(page))
+ pr_err("%p invalidatepage %p page not dirty\n", inode, page);
+
+ if (offset == 0)
+ ClearPageChecked(page);
+
+ ci = ceph_inode(inode);
+ if (offset == 0) {
+ dout("%p invalidatepage %p idx %lu full dirty page %lu\n",
+ inode, page, page->index, offset);
+ ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+ ceph_put_snap_context(snapc);
+ page->private = 0;
+ ClearPagePrivate(page);
+ } else {
+ dout("%p invalidatepage %p idx %lu partial dirty page\n",
+ inode, page, page->index);
+ }
+}
+
+/* just a sanity check */
+static int ceph_releasepage(struct page *page, gfp_t g)
+{
+ struct inode *inode = page->mapping ? page->mapping->host : NULL;
+ dout("%p releasepage %p idx %lu\n", inode, page, page->index);
+ WARN_ON(PageDirty(page));
+ WARN_ON(page->private);
+ WARN_ON(PagePrivate(page));
+ return 0;
+}
+
+/*
+ * read a single page, without unlocking it.
+ */
+static int readpage_nounlock(struct file *filp, struct page *page)
+{
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc;
+ int err = 0;
+ u64 len = PAGE_CACHE_SIZE;
+
+ dout("readpage inode %p file %p page %p index %lu\n",
+ inode, filp, page, page->index);
+ err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
+ page->index << PAGE_CACHE_SHIFT, &len,
+ ci->i_truncate_seq, ci->i_truncate_size,
+ &page, 1);
+ if (err == -ENOENT)
+ err = 0;
+ if (err < 0) {
+ SetPageError(page);
+ goto out;
+ } else if (err < PAGE_CACHE_SIZE) {
+ /* zero fill remainder of page */
+ zero_user_segment(page, err, PAGE_CACHE_SIZE);
+ }
+ SetPageUptodate(page);
+
+out:
+ return err < 0 ? err : 0;
+}
+
+static int ceph_readpage(struct file *filp, struct page *page)
+{
+ int r = readpage_nounlock(filp, page);
+ unlock_page(page);
+ return r;
+}
+
+/*
+ * Build a vector of contiguous pages from the provided page list.
+ */
+static struct page **page_vector_from_list(struct list_head *page_list,
+ unsigned *nr_pages)
+{
+ struct page **pages;
+ struct page *page;
+ int next_index, contig_pages = 0;
+
+ /* build page vector */
+ pages = kmalloc(sizeof(*pages) * *nr_pages, GFP_NOFS);
+ if (!pages)
+ return ERR_PTR(-ENOMEM);
+
+ BUG_ON(list_empty(page_list));
+ next_index = list_entry(page_list->prev, struct page, lru)->index;
+ list_for_each_entry_reverse(page, page_list, lru) {
+ if (page->index == next_index) {
+ dout("readpages page %d %p\n", contig_pages, page);
+ pages[contig_pages] = page;
+ contig_pages++;
+ next_index++;
+ } else {
+ break;
+ }
+ }
+ *nr_pages = contig_pages;
+ return pages;
+}
+
+/*
+ * Read multiple pages. Leave pages we don't read + unlock in page_list;
+ * the caller (VM) cleans them up.
+ */
+static int ceph_readpages(struct file *file, struct address_space *mapping,
+ struct list_head *page_list, unsigned nr_pages)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc;
+ int rc = 0;
+ struct page **pages;
+ struct pagevec pvec;
+ loff_t offset;
+ u64 len;
+
+ dout("readpages %p file %p nr_pages %d\n",
+ inode, file, nr_pages);
+
+ pages = page_vector_from_list(page_list, &nr_pages);
+ if (IS_ERR(pages))
+ return PTR_ERR(pages);
+
+ /* guess read extent */
+ offset = pages[0]->index << PAGE_CACHE_SHIFT;
+ len = nr_pages << PAGE_CACHE_SHIFT;
+ rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
+ offset, &len,
+ ci->i_truncate_seq, ci->i_truncate_size,
+ pages, nr_pages);
+ if (rc == -ENOENT)
+ rc = 0;
+ if (rc < 0)
+ goto out;
+
+ /* set uptodate and add to lru in pagevec-sized chunks */
+ pagevec_init(&pvec, 0);
+ for (; !list_empty(page_list) && len > 0;
+ rc -= PAGE_CACHE_SIZE, len -= PAGE_CACHE_SIZE) {
+ struct page *page =
+ list_entry(page_list->prev, struct page, lru);
+
+ list_del(&page->lru);
+
+ if (rc < (int)PAGE_CACHE_SIZE) {
+ /* zero (remainder of) page */
+ int s = rc < 0 ? 0 : rc;
+ zero_user_segment(page, s, PAGE_CACHE_SIZE);
+ }
+
+ if (add_to_page_cache(page, mapping, page->index, GFP_NOFS)) {
+ page_cache_release(page);
+ dout("readpages %p add_to_page_cache failed %p\n",
+ inode, page);
+ continue;
+ }
+ dout("readpages %p adding %p idx %lu\n", inode, page,
+ page->index);
+ flush_dcache_page(page);
+ SetPageUptodate(page);
+ unlock_page(page);
+ if (pagevec_add(&pvec, page) == 0)
+ pagevec_lru_add_file(&pvec); /* add to lru */
+ }
+ pagevec_lru_add_file(&pvec);
+ rc = 0;
+
+out:
+ kfree(pages);
+ return rc;
+}
+
+/*
+ * Get ref for the oldest snapc for an inode with dirty data... that is, the
+ * only snap context we are allowed to write back.
+ */
+static struct ceph_snap_context *get_oldest_context(struct inode *inode,
+ u64 *snap_size)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_snap_context *snapc = NULL;
+ struct ceph_cap_snap *capsnap = NULL;
+
+ spin_lock(&inode->i_lock);
+ list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+ dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap,
+ capsnap->context, capsnap->dirty_pages);
+ if (capsnap->dirty_pages) {
+ snapc = ceph_get_snap_context(capsnap->context);
+ if (snap_size)
+ *snap_size = capsnap->size;
+ break;
+ }
+ }
+ if (!snapc && ci->i_head_snapc) {
+ snapc = ceph_get_snap_context(ci->i_head_snapc);
+ dout(" head snapc %p has %d dirty pages\n",
+ snapc, ci->i_wrbuffer_ref_head);
+ }
+ spin_unlock(&inode->i_lock);
+ return snapc;
+}
+
+/*
+ * Write a single page, but leave the page locked.
+ *
+ * If we get a write error, set the page error bit, but still adjust the
+ * dirty page accounting (i.e., page is no longer dirty).
+ */
+static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
+{
+ struct inode *inode;
+ struct ceph_inode_info *ci;
+ struct ceph_client *client;
+ struct ceph_osd_client *osdc;
+ loff_t page_off = page->index << PAGE_CACHE_SHIFT;
+ int len = PAGE_CACHE_SIZE;
+ loff_t i_size;
+ int err = 0;
+ struct ceph_snap_context *snapc, *oldest;
+ u64 snap_size = 0;
+ long writeback_stat;
+
+ dout("writepage %p idx %lu\n", page, page->index);
+
+ if (!page->mapping || !page->mapping->host) {
+ dout("writepage %p - no mapping\n", page);
+ return -EFAULT;
+ }
+ inode = page->mapping->host;
+ ci = ceph_inode(inode);
+ client = ceph_inode_to_client(inode);
+ osdc = &client->osdc;
+
+ /* verify this is a writeable snap context */
+ snapc = (void *)page->private;
+ if (snapc == NULL) {
+ dout("writepage %p page %p not dirty?\n", inode, page);
+ goto out;
+ }
+ oldest = get_oldest_context(inode, &snap_size);
+ if (snapc->seq > oldest->seq) {
+ dout("writepage %p page %p snapc %p not writeable - noop\n",
+ inode, page, (void *)page->private);
+ /* we should only noop if called by kswapd */
+ WARN_ON((current->flags & PF_MEMALLOC) == 0);
+ ceph_put_snap_context(oldest);
+ goto out;
+ }
+ ceph_put_snap_context(oldest);
+
+ /* is this a partial page at end of file? */
+ if (snap_size)
+ i_size = snap_size;
+ else
+ i_size = i_size_read(inode);
+ if (i_size < page_off + len)
+ len = i_size - page_off;
+
+ dout("writepage %p page %p index %lu on %llu~%u\n",
+ inode, page, page->index, page_off, len);
+
+ writeback_stat = atomic_long_inc_return(&client->writeback_count);
+ if (writeback_stat >
+ CONGESTION_ON_THRESH(client->mount_args->congestion_kb))
+ set_bdi_congested(&client->backing_dev_info, BLK_RW_ASYNC);
+
+ set_page_writeback(page);
+ err = ceph_osdc_writepages(osdc, ceph_vino(inode),
+ &ci->i_layout, snapc,
+ page_off, len,
+ ci->i_truncate_seq, ci->i_truncate_size,
+ &inode->i_mtime,
+ &page, 1, 0, 0, true);
+ if (err < 0) {
+ dout("writepage setting page/mapping error %d %p\n", err, page);
+ SetPageError(page);
+ mapping_set_error(&inode->i_data, err);
+ if (wbc)
+ wbc->pages_skipped++;
+ } else {
+ dout("writepage cleaned page %p\n", page);
+ err = 0; /* vfs expects us to return 0 */
+ }
+ page->private = 0;
+ ClearPagePrivate(page);
+ end_page_writeback(page);
+ ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+ ceph_put_snap_context(snapc); /* page's reference */
+out:
+ return err;
+}
+
+static int ceph_writepage(struct page *page, struct writeback_control *wbc)
+{
+ int err;
+ struct inode *inode = page->mapping->host;
+ BUG_ON(!inode);
+ igrab(inode);
+ err = writepage_nounlock(page, wbc);
+ unlock_page(page);
+ iput(inode);
+ return err;
+}
+
+
+/*
+ * lame release_pages helper. release_pages() isn't exported to
+ * modules.
+ */
+static void ceph_release_pages(struct page **pages, int num)
+{
+ struct pagevec pvec;
+ int i;
+
+ pagevec_init(&pvec, 0);
+ for (i = 0; i < num; i++) {
+ if (pagevec_add(&pvec, pages[i]) == 0)
+ pagevec_release(&pvec);
+ }
+ pagevec_release(&pvec);
+}
+
+
+/*
+ * async writeback completion handler.
+ *
+ * If we get an error, set the mapping error bit, but not the individual
+ * page error bits.
+ */
+static void writepages_finish(struct ceph_osd_request *req,
+ struct ceph_msg *msg)
+{
+ struct inode *inode = req->r_inode;
+ struct ceph_osd_reply_head *replyhead;
+ struct ceph_osd_op *op;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ unsigned wrote;
+ struct page *page;
+ int i;
+ struct ceph_snap_context *snapc = req->r_snapc;
+ struct address_space *mapping = inode->i_mapping;
+ struct writeback_control *wbc = req->r_wbc;
+ __s32 rc = -EIO;
+ u64 bytes = 0;
+ struct ceph_client *client = ceph_inode_to_client(inode);
+ long writeback_stat;
+ unsigned issued = __ceph_caps_issued(ci, NULL);
+
+ /* parse reply */
+ replyhead = msg->front.iov_base;
+ WARN_ON(le32_to_cpu(replyhead->num_ops) == 0);
+ op = (void *)(replyhead + 1);
+ rc = le32_to_cpu(replyhead->result);
+ bytes = le64_to_cpu(op->extent.length);
+
+ if (rc >= 0) {
+ /*
+ * Assume we wrote the pages we originally sent. The
+ * osd might reply with fewer pages if our writeback
+ * raced with a truncation and was adjusted at the osd,
+ * so don't believe the reply.
+ */
+ wrote = req->r_num_pages;
+ } else {
+ wrote = 0;
+ mapping_set_error(mapping, rc);
+ }
+ dout("writepages_finish %p rc %d bytes %llu wrote %d (pages)\n",
+ inode, rc, bytes, wrote);
+
+ /* clean all pages */
+ for (i = 0; i < req->r_num_pages; i++) {
+ page = req->r_pages[i];
+ BUG_ON(!page);
+ WARN_ON(!PageUptodate(page));
+
+ writeback_stat =
+ atomic_long_dec_return(&client->writeback_count);
+ if (writeback_stat <
+ CONGESTION_OFF_THRESH(client->mount_args->congestion_kb))
+ clear_bdi_congested(&client->backing_dev_info,
+ BLK_RW_ASYNC);
+
+ if (i >= wrote) {
+ dout("inode %p skipping page %p\n", inode, page);
+ wbc->pages_skipped++;
+ }
+ ceph_put_snap_context((void *)page->private);
+ page->private = 0;
+ ClearPagePrivate(page);
+ dout("unlocking %d %p\n", i, page);
+ end_page_writeback(page);
+
+ /*
+ * We lost the cache cap, need to truncate the page before
+ * it is unlocked, otherwise we'd truncate it later in the
+ * page truncation thread, possibly losing some data that
+ * raced its way in
+ */
+ if ((issued & CEPH_CAP_FILE_CACHE) == 0)
+ generic_error_remove_page(inode->i_mapping, page);
+
+ unlock_page(page);
+ }
+ dout("%p wrote+cleaned %d pages\n", inode, wrote);
+ ceph_put_wrbuffer_cap_refs(ci, req->r_num_pages, snapc);
+
+ ceph_release_pages(req->r_pages, req->r_num_pages);
+ if (req->r_pages_from_pool)
+ mempool_free(req->r_pages,
+ ceph_client(inode->i_sb)->wb_pagevec_pool);
+ else
+ kfree(req->r_pages);
+ ceph_osdc_put_request(req);
+}
+
+/*
+ * allocate a page vec, either directly, or if necessary, via a the
+ * mempool. we avoid the mempool if we can because req->r_num_pages
+ * may be less than the maximum write size.
+ */
+static void alloc_page_vec(struct ceph_client *client,
+ struct ceph_osd_request *req)
+{
+ req->r_pages = kmalloc(sizeof(struct page *) * req->r_num_pages,
+ GFP_NOFS);
+ if (!req->r_pages) {
+ req->r_pages = mempool_alloc(client->wb_pagevec_pool, GFP_NOFS);
+ req->r_pages_from_pool = 1;
+ WARN_ON(!req->r_pages);
+ }
+}
+
+/*
+ * initiate async writeback
+ */
+static int ceph_writepages_start(struct address_space *mapping,
+ struct writeback_control *wbc)
+{
+ struct inode *inode = mapping->host;
+ struct backing_dev_info *bdi = mapping->backing_dev_info;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_client *client;
+ pgoff_t index, start, end;
+ int range_whole = 0;
+ int should_loop = 1;
+ pgoff_t max_pages = 0, max_pages_ever = 0;
+ struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc;
+ struct pagevec pvec;
+ int done = 0;
+ int rc = 0;
+ unsigned wsize = 1 << inode->i_blkbits;
+ struct ceph_osd_request *req = NULL;
+ int do_sync;
+ u64 snap_size = 0;
+
+ /*
+ * Include a 'sync' in the OSD request if this is a data
+ * integrity write (e.g., O_SYNC write or fsync()), or if our
+ * cap is being revoked.
+ */
+ do_sync = wbc->sync_mode == WB_SYNC_ALL;
+ if (ceph_caps_revoking(ci, CEPH_CAP_FILE_BUFFER))
+ do_sync = 1;
+ dout("writepages_start %p dosync=%d (mode=%s)\n",
+ inode, do_sync,
+ wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
+ (wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD"));
+
+ client = ceph_inode_to_client(inode);
+ if (client->mount_state == CEPH_MOUNT_SHUTDOWN) {
+ pr_warning("writepage_start %p on forced umount\n", inode);
+ return -EIO; /* we're in a forced umount, don't write! */
+ }
+ if (client->mount_args->wsize && client->mount_args->wsize < wsize)
+ wsize = client->mount_args->wsize;
+ if (wsize < PAGE_CACHE_SIZE)
+ wsize = PAGE_CACHE_SIZE;
+ max_pages_ever = wsize >> PAGE_CACHE_SHIFT;
+
+ pagevec_init(&pvec, 0);
+
+ /* ?? */
+ if (wbc->nonblocking && bdi_write_congested(bdi)) {
+ dout(" writepages congested\n");
+ wbc->encountered_congestion = 1;
+ goto out_final;
+ }
+
+ /* where to start/end? */
+ if (wbc->range_cyclic) {
+ start = mapping->writeback_index; /* Start from prev offset */
+ end = -1;
+ dout(" cyclic, start at %lu\n", start);
+ } else {
+ start = wbc->range_start >> PAGE_CACHE_SHIFT;
+ end = wbc->range_end >> PAGE_CACHE_SHIFT;
+ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+ range_whole = 1;
+ should_loop = 0;
+ dout(" not cyclic, %lu to %lu\n", start, end);
+ }
+ index = start;
+
+retry:
+ /* find oldest snap context with dirty data */
+ ceph_put_snap_context(snapc);
+ snapc = get_oldest_context(inode, &snap_size);
+ if (!snapc) {
+ /* hmm, why does writepages get called when there
+ is no dirty data? */
+ dout(" no snap context with dirty data?\n");
+ goto out;
+ }
+ dout(" oldest snapc is %p seq %lld (%d snaps)\n",
+ snapc, snapc->seq, snapc->num_snaps);
+ if (last_snapc && snapc != last_snapc) {
+ /* if we switched to a newer snapc, restart our scan at the
+ * start of the original file range. */
+ dout(" snapc differs from last pass, restarting at %lu\n",
+ index);
+ index = start;
+ }
+ last_snapc = snapc;
+
+ while (!done && index <= end) {
+ unsigned i;
+ int first;
+ pgoff_t next;
+ int pvec_pages, locked_pages;
+ struct page *page;
+ int want;
+ u64 offset, len;
+ struct ceph_osd_request_head *reqhead;
+ struct ceph_osd_op *op;
+ long writeback_stat;
+
+ next = 0;
+ locked_pages = 0;
+ max_pages = max_pages_ever;
+
+get_more_pages:
+ first = -1;
+ want = min(end - index,
+ min((pgoff_t)PAGEVEC_SIZE,
+ max_pages - (pgoff_t)locked_pages) - 1)
+ + 1;
+ pvec_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+ PAGECACHE_TAG_DIRTY,
+ want);
+ dout("pagevec_lookup_tag got %d\n", pvec_pages);
+ if (!pvec_pages && !locked_pages)
+ break;
+ for (i = 0; i < pvec_pages && locked_pages < max_pages; i++) {
+ page = pvec.pages[i];
+ dout("? %p idx %lu\n", page, page->index);
+ if (locked_pages == 0)
+ lock_page(page); /* first page */
+ else if (!trylock_page(page))
+ break;
+
+ /* only dirty pages, or our accounting breaks */
+ if (unlikely(!PageDirty(page)) ||
+ unlikely(page->mapping != mapping)) {
+ dout("!dirty or !mapping %p\n", page);
+ unlock_page(page);
+ break;
+ }
+ if (!wbc->range_cyclic && page->index > end) {
+ dout("end of range %p\n", page);
+ done = 1;
+ unlock_page(page);
+ break;
+ }
+ if (next && (page->index != next)) {
+ dout("not consecutive %p\n", page);
+ unlock_page(page);
+ break;
+ }
+ if (wbc->sync_mode != WB_SYNC_NONE) {
+ dout("waiting on writeback %p\n", page);
+ wait_on_page_writeback(page);
+ }
+ if ((snap_size && page_offset(page) > snap_size) ||
+ (!snap_size &&
+ page_offset(page) > i_size_read(inode))) {
+ dout("%p page eof %llu\n", page, snap_size ?
+ snap_size : i_size_read(inode));
+ done = 1;
+ unlock_page(page);
+ break;
+ }
+ if (PageWriteback(page)) {
+ dout("%p under writeback\n", page);
+ unlock_page(page);
+ break;
+ }
+
+ /* only if matching snap context */
+ pgsnapc = (void *)page->private;
+ if (pgsnapc->seq > snapc->seq) {
+ dout("page snapc %p %lld > oldest %p %lld\n",
+ pgsnapc, pgsnapc->seq, snapc, snapc->seq);
+ unlock_page(page);
+ if (!locked_pages)
+ continue; /* keep looking for snap */
+ break;
+ }
+
+ if (!clear_page_dirty_for_io(page)) {
+ dout("%p !clear_page_dirty_for_io\n", page);
+ unlock_page(page);
+ break;
+ }
+
+ /* ok */
+ if (locked_pages == 0) {
+ /* prepare async write request */
+ offset = page->index << PAGE_CACHE_SHIFT;
+ len = wsize;
+ req = ceph_osdc_new_request(&client->osdc,
+ &ci->i_layout,
+ ceph_vino(inode),
+ offset, &len,
+ CEPH_OSD_OP_WRITE,
+ CEPH_OSD_FLAG_WRITE |
+ CEPH_OSD_FLAG_ONDISK,
+ snapc, do_sync,
+ ci->i_truncate_seq,
+ ci->i_truncate_size,
+ &inode->i_mtime, true, 1);
+ max_pages = req->r_num_pages;
+
+ alloc_page_vec(client, req);
+ req->r_callback = writepages_finish;
+ req->r_inode = inode;
+ req->r_wbc = wbc;
+ }
+
+ /* note position of first page in pvec */
+ if (first < 0)
+ first = i;
+ dout("%p will write page %p idx %lu\n",
+ inode, page, page->index);
+
+ writeback_stat = atomic_long_inc_return(&client->writeback_count);
+ if (writeback_stat > CONGESTION_ON_THRESH(client->mount_args->congestion_kb)) {
+ set_bdi_congested(&client->backing_dev_info, BLK_RW_ASYNC);
+ }
+
+ set_page_writeback(page);
+ req->r_pages[locked_pages] = page;
+ locked_pages++;
+ next = page->index + 1;
+ }
+
+ /* did we get anything? */
+ if (!locked_pages)
+ goto release_pvec_pages;
+ if (i) {
+ int j;
+ BUG_ON(!locked_pages || first < 0);
+
+ if (pvec_pages && i == pvec_pages &&
+ locked_pages < max_pages) {
+ dout("reached end pvec, trying for more\n");
+ pagevec_reinit(&pvec);
+ goto get_more_pages;
+ }
+
+ /* shift unused pages over in the pvec... we
+ * will need to release them below. */
+ for (j = i; j < pvec_pages; j++) {
+ dout(" pvec leftover page %p\n",
+ pvec.pages[j]);
+ pvec.pages[j-i+first] = pvec.pages[j];
+ }
+ pvec.nr -= i-first;
+ }
+
+ /* submit the write */
+ offset = req->r_pages[0]->index << PAGE_CACHE_SHIFT;
+ len = min((snap_size ? snap_size : i_size_read(inode)) - offset,
+ (u64)locked_pages << PAGE_CACHE_SHIFT);
+ dout("writepages got %d pages at %llu~%llu\n",
+ locked_pages, offset, len);
+
+ /* revise final length, page count */
+ req->r_num_pages = locked_pages;
+ reqhead = req->r_request->front.iov_base;
+ op = (void *)(reqhead + 1);
+ op->extent.length = cpu_to_le64(len);
+ op->payload_len = cpu_to_le32(len);
+ req->r_request->hdr.data_len = cpu_to_le32(len);
+
+ ceph_osdc_start_request(&client->osdc, req, true);
+ req = NULL;
+
+ /* continue? */
+ index = next;
+ wbc->nr_to_write -= locked_pages;
+ if (wbc->nr_to_write <= 0)
+ done = 1;
+
+release_pvec_pages:
+ dout("pagevec_release on %d pages (%p)\n", (int)pvec.nr,
+ pvec.nr ? pvec.pages[0] : NULL);
+ pagevec_release(&pvec);
+
+ if (locked_pages && !done)
+ goto retry;
+ }
+
+ if (should_loop && !done) {
+ /* more to do; loop back to beginning of file */
+ dout("writepages looping back to beginning of file\n");
+ should_loop = 0;
+ index = 0;
+ goto retry;
+ }
+
+ if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+ mapping->writeback_index = index;
+
+out:
+ if (req)
+ ceph_osdc_put_request(req);
+ if (rc > 0)
+ rc = 0; /* vfs expects us to return 0 */
+ ceph_put_snap_context(snapc);
+ dout("writepages done, rc = %d\n", rc);
+out_final:
+ return rc;
+}
+
+
+
+/*
+ * See if a given @snapc is either writeable, or already written.
+ */
+static int context_is_writeable_or_written(struct inode *inode,
+ struct ceph_snap_context *snapc)
+{
+ struct ceph_snap_context *oldest = get_oldest_context(inode, NULL);
+ int ret = !oldest || snapc->seq <= oldest->seq;
+
+ ceph_put_snap_context(oldest);
+ return ret;
+}
+
+/*
+ * We are only allowed to write into/dirty the page if the page is
+ * clean, or already dirty within the same snap context.
+ *
+ * called with page locked.
+ * return success with page locked,
+ * or any failure (incl -EAGAIN) with page unlocked.
+ */
+static int ceph_update_writeable_page(struct file *file,
+ loff_t pos, unsigned len,
+ struct page *page)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+ loff_t page_off = pos & PAGE_CACHE_MASK;
+ int pos_in_page = pos & ~PAGE_CACHE_MASK;
+ int end_in_page = pos_in_page + len;
+ loff_t i_size;
+ int r;
+ struct ceph_snap_context *snapc, *oldest;
+
+retry_locked:
+ /* writepages currently holds page lock, but if we change that later, */
+ wait_on_page_writeback(page);
+
+ /* check snap context */
+ BUG_ON(!ci->i_snap_realm);
+ down_read(&mdsc->snap_rwsem);
+ BUG_ON(!ci->i_snap_realm->cached_context);
+ snapc = (void *)page->private;
+ if (snapc && snapc != ci->i_head_snapc) {
+ /*
+ * this page is already dirty in another (older) snap
+ * context! is it writeable now?
+ */
+ oldest = get_oldest_context(inode, NULL);
+ up_read(&mdsc->snap_rwsem);
+
+ if (snapc->seq > oldest->seq) {
+ ceph_put_snap_context(oldest);
+ dout(" page %p snapc %p not current or oldest\n",
+ page, snapc);
+ /*
+ * queue for writeback, and wait for snapc to
+ * be writeable or written
+ */
+ snapc = ceph_get_snap_context(snapc);
+ unlock_page(page);
+ ceph_queue_writeback(inode);
+ r = wait_event_interruptible(ci->i_cap_wq,
+ context_is_writeable_or_written(inode, snapc));
+ ceph_put_snap_context(snapc);
+ if (r == -ERESTARTSYS)
+ return r;
+ return -EAGAIN;
+ }
+ ceph_put_snap_context(oldest);
+
+ /* yay, writeable, do it now (without dropping page lock) */
+ dout(" page %p snapc %p not current, but oldest\n",
+ page, snapc);
+ if (!clear_page_dirty_for_io(page))
+ goto retry_locked;
+ r = writepage_nounlock(page, NULL);
+ if (r < 0)
+ goto fail_nosnap;
+ goto retry_locked;
+ }
+
+ if (PageUptodate(page)) {
+ dout(" page %p already uptodate\n", page);
+ return 0;
+ }
+
+ /* full page? */
+ if (pos_in_page == 0 && len == PAGE_CACHE_SIZE)
+ return 0;
+
+ /* past end of file? */
+ i_size = inode->i_size; /* caller holds i_mutex */
+
+ if (i_size + len > inode->i_sb->s_maxbytes) {
+ /* file is too big */
+ r = -EINVAL;
+ goto fail;
+ }
+
+ if (page_off >= i_size ||
+ (pos_in_page == 0 && (pos+len) >= i_size &&
+ end_in_page - pos_in_page != PAGE_CACHE_SIZE)) {
+ dout(" zeroing %p 0 - %d and %d - %d\n",
+ page, pos_in_page, end_in_page, (int)PAGE_CACHE_SIZE);
+ zero_user_segments(page,
+ 0, pos_in_page,
+ end_in_page, PAGE_CACHE_SIZE);
+ return 0;
+ }
+
+ /* we need to read it. */
+ up_read(&mdsc->snap_rwsem);
+ r = readpage_nounlock(file, page);
+ if (r < 0)
+ goto fail_nosnap;
+ goto retry_locked;
+
+fail:
+ up_read(&mdsc->snap_rwsem);
+fail_nosnap:
+ unlock_page(page);
+ return r;
+}
+
+/*
+ * We are only allowed to write into/dirty the page if the page is
+ * clean, or already dirty within the same snap context.
+ */
+static int ceph_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct page *page;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ int r;
+
+ do {
+ /* get a page */
+ page = grab_cache_page_write_begin(mapping, index, 0);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
+
+ dout("write_begin file %p inode %p page %p %d~%d\n", file,
+ inode, page, (int)pos, (int)len);
+
+ r = ceph_update_writeable_page(file, pos, len, page);
+ } while (r == -EAGAIN);
+
+ return r;
+}
+
+/*
+ * we don't do anything in here that simple_write_end doesn't do
+ * except adjust dirty page accounting and drop read lock on
+ * mdsc->snap_rwsem.
+ */
+static int ceph_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ceph_client *client = ceph_inode_to_client(inode);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+ int check_cap = 0;
+
+ dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
+ inode, page, (int)pos, (int)copied, (int)len);
+
+ /* zero the stale part of the page if we did a short copy */
+ if (copied < len)
+ zero_user_segment(page, from+copied, len);
+
+ /* did file size increase? */
+ /* (no need for i_size_read(); we caller holds i_mutex */
+ if (pos+copied > inode->i_size)
+ check_cap = ceph_inode_set_size(inode, pos+copied);
+
+ if (!PageUptodate(page))
+ SetPageUptodate(page);
+
+ set_page_dirty(page);
+
+ unlock_page(page);
+ up_read(&mdsc->snap_rwsem);
+ page_cache_release(page);
+
+ if (check_cap)
+ ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, NULL);
+
+ return copied;
+}
+
+/*
+ * we set .direct_IO to indicate direct io is supported, but since we
+ * intercept O_DIRECT reads and writes early, this function should
+ * never get called.
+ */
+static ssize_t ceph_direct_io(int rw, struct kiocb *iocb,
+ const struct iovec *iov,
+ loff_t pos, unsigned long nr_segs)
+{
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+const struct address_space_operations ceph_aops = {
+ .readpage = ceph_readpage,
+ .readpages = ceph_readpages,
+ .writepage = ceph_writepage,
+ .writepages = ceph_writepages_start,
+ .write_begin = ceph_write_begin,
+ .write_end = ceph_write_end,
+ .set_page_dirty = ceph_set_page_dirty,
+ .invalidatepage = ceph_invalidatepage,
+ .releasepage = ceph_releasepage,
+ .direct_IO = ceph_direct_io,
+};
+
+
+/*
+ * vm ops
+ */
+
+/*
+ * Reuse write_begin here for simplicity.
+ */
+static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct inode *inode = vma->vm_file->f_dentry->d_inode;
+ struct page *page = vmf->page;
+ struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+ loff_t off = page->index << PAGE_CACHE_SHIFT;
+ loff_t size, len;
+ int ret;
+
+ size = i_size_read(inode);
+ if (off + PAGE_CACHE_SIZE <= size)
+ len = PAGE_CACHE_SIZE;
+ else
+ len = size & ~PAGE_CACHE_MASK;
+
+ dout("page_mkwrite %p %llu~%llu page %p idx %lu\n", inode,
+ off, len, page, page->index);
+
+ lock_page(page);
+
+ ret = VM_FAULT_NOPAGE;
+ if ((off > size) ||
+ (page->mapping != inode->i_mapping))
+ goto out;
+
+ ret = ceph_update_writeable_page(vma->vm_file, off, len, page);
+ if (ret == 0) {
+ /* success. we'll keep the page locked. */
+ set_page_dirty(page);
+ up_read(&mdsc->snap_rwsem);
+ ret = VM_FAULT_LOCKED;
+ } else {
+ if (ret == -ENOMEM)
+ ret = VM_FAULT_OOM;
+ else
+ ret = VM_FAULT_SIGBUS;
+ }
+out:
+ dout("page_mkwrite %p %llu~%llu = %d\n", inode, off, len, ret);
+ if (ret != VM_FAULT_LOCKED)
+ unlock_page(page);
+ return ret;
+}
+
+static struct vm_operations_struct ceph_vmops = {
+ .fault = filemap_fault,
+ .page_mkwrite = ceph_page_mkwrite,
+};
+
+int ceph_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct address_space *mapping = file->f_mapping;
+
+ if (!mapping->a_ops->readpage)
+ return -ENOEXEC;
+ file_accessed(file);
+ vma->vm_ops = &ceph_vmops;
+ vma->vm_flags |= VM_CAN_NONLINEAR;
+ return 0;
+}
diff --git a/fs/ceph/armor.c b/fs/ceph/armor.c
new file mode 100644
index 00000000000..67b2c030924
--- /dev/null
+++ b/fs/ceph/armor.c
@@ -0,0 +1,99 @@
+
+#include <linux/errno.h>
+
+/*
+ * base64 encode/decode.
+ */
+
+const char *pem_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int encode_bits(int c)
+{
+ return pem_key[c];
+}
+
+static int decode_bits(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A';
+ if (c >= 'a' && c <= 'z')
+ return c - 'a' + 26;
+ if (c >= '0' && c <= '9')
+ return c - '0' + 52;
+ if (c == '+')
+ return 62;
+ if (c == '/')
+ return 63;
+ if (c == '=')
+ return 0; /* just non-negative, please */
+ return -EINVAL;
+}
+
+int ceph_armor(char *dst, const char *src, const char *end)
+{
+ int olen = 0;
+ int line = 0;
+
+ while (src < end) {
+ unsigned char a, b, c;
+
+ a = *src++;
+ *dst++ = encode_bits(a >> 2);
+ if (src < end) {
+ b = *src++;
+ *dst++ = encode_bits(((a & 3) << 4) | (b >> 4));
+ if (src < end) {
+ c = *src++;
+ *dst++ = encode_bits(((b & 15) << 2) |
+ (c >> 6));
+ *dst++ = encode_bits(c & 63);
+ } else {
+ *dst++ = encode_bits((b & 15) << 2);
+ *dst++ = '=';
+ }
+ } else {
+ *dst++ = encode_bits(((a & 3) << 4));
+ *dst++ = '=';
+ *dst++ = '=';
+ }
+ olen += 4;
+ line += 4;
+ if (line == 64) {
+ line = 0;
+ *(dst++) = '\n';
+ olen++;
+ }
+ }
+ return olen;
+}
+
+int ceph_unarmor(char *dst, const char *src, const char *end)
+{
+ int olen = 0;
+
+ while (src < end) {
+ int a, b, c, d;
+
+ if (src < end && src[0] == '\n')
+ src++;
+ if (src + 4 > end)
+ return -EINVAL;
+ a = decode_bits(src[0]);
+ b = decode_bits(src[1]);
+ c = decode_bits(src[2]);
+ d = decode_bits(src[3]);
+ if (a < 0 || b < 0 || c < 0 || d < 0)
+ return -EINVAL;
+
+ *dst++ = (a << 2) | (b >> 4);
+ if (src[2] == '=')
+ return olen + 1;
+ *dst++ = ((b & 15) << 4) | (c >> 2);
+ if (src[3] == '=')
+ return olen + 2;
+ *dst++ = ((c & 3) << 6) | d;
+ olen += 3;
+ src += 4;
+ }
+ return olen;
+}
diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c
new file mode 100644
index 00000000000..f6394b94b86
--- /dev/null
+++ b/fs/ceph/auth.c
@@ -0,0 +1,258 @@
+#include "ceph_debug.h"
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#include "types.h"
+#include "auth_none.h"
+#include "auth_x.h"
+#include "decode.h"
+#include "super.h"
+
+#include "messenger.h"
+
+/*
+ * get protocol handler
+ */
+static u32 supported_protocols[] = {
+ CEPH_AUTH_NONE,
+ CEPH_AUTH_CEPHX
+};
+
+int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
+{
+ switch (protocol) {
+ case CEPH_AUTH_NONE:
+ return ceph_auth_none_init(ac);
+ case CEPH_AUTH_CEPHX:
+ return ceph_x_init(ac);
+ default:
+ return -ENOENT;
+ }
+}
+
+/*
+ * setup, teardown.
+ */
+struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
+{
+ struct ceph_auth_client *ac;
+ int ret;
+
+ dout("auth_init name '%s' secret '%s'\n", name, secret);
+
+ ret = -ENOMEM;
+ ac = kzalloc(sizeof(*ac), GFP_NOFS);
+ if (!ac)
+ goto out;
+
+ ac->negotiating = true;
+ if (name)
+ ac->name = name;
+ else
+ ac->name = CEPH_AUTH_NAME_DEFAULT;
+ dout("auth_init name %s secret %s\n", ac->name, secret);
+ ac->secret = secret;
+ return ac;
+
+out:
+ return ERR_PTR(ret);
+}
+
+void ceph_auth_destroy(struct ceph_auth_client *ac)
+{
+ dout("auth_destroy %p\n", ac);
+ if (ac->ops)
+ ac->ops->destroy(ac);
+ kfree(ac);
+}
+
+/*
+ * Reset occurs when reconnecting to the monitor.
+ */
+void ceph_auth_reset(struct ceph_auth_client *ac)
+{
+ dout("auth_reset %p\n", ac);
+ if (ac->ops && !ac->negotiating)
+ ac->ops->reset(ac);
+ ac->negotiating = true;
+}
+
+int ceph_entity_name_encode(const char *name, void **p, void *end)
+{
+ int len = strlen(name);
+
+ if (*p + 2*sizeof(u32) + len > end)
+ return -ERANGE;
+ ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT);
+ ceph_encode_32(p, len);
+ ceph_encode_copy(p, name, len);
+ return 0;
+}
+
+/*
+ * Initiate protocol negotiation with monitor. Include entity name
+ * and list supported protocols.
+ */
+int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
+{
+ struct ceph_mon_request_header *monhdr = buf;
+ void *p = monhdr + 1, *end = buf + len, *lenp;
+ int i, num;
+ int ret;
+
+ dout("auth_build_hello\n");
+ monhdr->have_version = 0;
+ monhdr->session_mon = cpu_to_le16(-1);
+ monhdr->session_mon_tid = 0;
+
+ ceph_encode_32(&p, 0); /* no protocol, yet */
+
+ lenp = p;
+ p += sizeof(u32);
+
+ ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
+ ceph_encode_8(&p, 1);
+ num = ARRAY_SIZE(supported_protocols);
+ ceph_encode_32(&p, num);
+ ceph_decode_need(&p, end, num * sizeof(u32), bad);
+ for (i = 0; i < num; i++)
+ ceph_encode_32(&p, supported_protocols[i]);
+
+ ret = ceph_entity_name_encode(ac->name, &p, end);
+ if (ret < 0)
+ return ret;
+ ceph_decode_need(&p, end, sizeof(u64), bad);
+ ceph_encode_64(&p, ac->global_id);
+
+ ceph_encode_32(&lenp, p - lenp - sizeof(u32));
+ return p - buf;
+
+bad:
+ return -ERANGE;
+}
+
+int ceph_build_auth_request(struct ceph_auth_client *ac,
+ void *msg_buf, size_t msg_len)
+{
+ struct ceph_mon_request_header *monhdr = msg_buf;
+ void *p = monhdr + 1;
+ void *end = msg_buf + msg_len;
+ int ret;
+
+ monhdr->have_version = 0;
+ monhdr->session_mon = cpu_to_le16(-1);
+ monhdr->session_mon_tid = 0;
+
+ ceph_encode_32(&p, ac->protocol);
+
+ ret = ac->ops->build_request(ac, p + sizeof(u32), end);
+ if (ret < 0) {
+ pr_err("error %d building request\n", ret);
+ return ret;
+ }
+ dout(" built request %d bytes\n", ret);
+ ceph_encode_32(&p, ret);
+ return p + ret - msg_buf;
+}
+
+/*
+ * Handle auth message from monitor.
+ */
+int ceph_handle_auth_reply(struct ceph_auth_client *ac,
+ void *buf, size_t len,
+ void *reply_buf, size_t reply_len)
+{
+ void *p = buf;
+ void *end = buf + len;
+ int protocol;
+ s32 result;
+ u64 global_id;
+ void *payload, *payload_end;
+ int payload_len;
+ char *result_msg;
+ int result_msg_len;
+ int ret = -EINVAL;
+
+ dout("handle_auth_reply %p %p\n", p, end);
+ ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
+ protocol = ceph_decode_32(&p);
+ result = ceph_decode_32(&p);
+ global_id = ceph_decode_64(&p);
+ payload_len = ceph_decode_32(&p);
+ payload = p;
+ p += payload_len;
+ ceph_decode_need(&p, end, sizeof(u32), bad);
+ result_msg_len = ceph_decode_32(&p);
+ result_msg = p;
+ p += result_msg_len;
+ if (p != end)
+ goto bad;
+
+ dout(" result %d '%.*s' gid %llu len %d\n", result, result_msg_len,
+ result_msg, global_id, payload_len);
+
+ payload_end = payload + payload_len;
+
+ if (global_id && ac->global_id != global_id) {
+ dout(" set global_id %lld -> %lld\n", ac->global_id, global_id);
+ ac->global_id = global_id;
+ }
+
+ if (ac->negotiating) {
+ /* server does not support our protocols? */
+ if (!protocol && result < 0) {
+ ret = result;
+ goto out;
+ }
+ /* set up (new) protocol handler? */
+ if (ac->protocol && ac->protocol != protocol) {
+ ac->ops->destroy(ac);
+ ac->protocol = 0;
+ ac->ops = NULL;
+ }
+ if (ac->protocol != protocol) {
+ ret = ceph_auth_init_protocol(ac, protocol);
+ if (ret) {
+ pr_err("error %d on auth protocol %d init\n",
+ ret, protocol);
+ goto out;
+ }
+ }
+
+ ac->negotiating = false;
+ }
+
+ ret = ac->ops->handle_reply(ac, result, payload, payload_end);
+ if (ret == -EAGAIN) {
+ return ceph_build_auth_request(ac, reply_buf, reply_len);
+ } else if (ret) {
+ pr_err("authentication error %d\n", ret);
+ return ret;
+ }
+ return 0;
+
+bad:
+ pr_err("failed to decode auth msg\n");
+out:
+ return ret;
+}
+
+int ceph_build_auth(struct ceph_auth_client *ac,
+ void *msg_buf, size_t msg_len)
+{
+ if (!ac->protocol)
+ return ceph_auth_build_hello(ac, msg_buf, msg_len);
+ BUG_ON(!ac->ops);
+ if (!ac->ops->is_authenticated(ac))
+ return ceph_build_auth_request(ac, msg_buf, msg_len);
+ return 0;
+}
+
+int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
+{
+ if (!ac->ops)
+ return 0;
+ return ac->ops->is_authenticated(ac);
+}
diff --git a/fs/ceph/auth.h b/fs/ceph/auth.h
new file mode 100644
index 00000000000..ca4f57cfb26
--- /dev/null
+++ b/fs/ceph/auth.h
@@ -0,0 +1,84 @@
+#ifndef _FS_CEPH_AUTH_H
+#define _FS_CEPH_AUTH_H
+
+#include "types.h"
+#include "buffer.h"
+
+/*
+ * Abstract interface for communicating with the authenticate module.
+ * There is some handshake that takes place between us and the monitor
+ * to acquire the necessary keys. These are used to generate an
+ * 'authorizer' that we use when connecting to a service (mds, osd).
+ */
+
+struct ceph_auth_client;
+struct ceph_authorizer;
+
+struct ceph_auth_client_ops {
+ /*
+ * true if we are authenticated and can connect to
+ * services.
+ */
+ int (*is_authenticated)(struct ceph_auth_client *ac);
+
+ /*
+ * build requests and process replies during monitor
+ * handshake. if handle_reply returns -EAGAIN, we build
+ * another request.
+ */
+ int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end);
+ int (*handle_reply)(struct ceph_auth_client *ac, int result,
+ void *buf, void *end);
+
+ /*
+ * Create authorizer for connecting to a service, and verify
+ * the response to authenticate the service.
+ */
+ int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type,
+ struct ceph_authorizer **a,
+ void **buf, size_t *len,
+ void **reply_buf, size_t *reply_len);
+ int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a, size_t len);
+ void (*destroy_authorizer)(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a);
+ void (*invalidate_authorizer)(struct ceph_auth_client *ac,
+ int peer_type);
+
+ /* reset when we (re)connect to a monitor */
+ void (*reset)(struct ceph_auth_client *ac);
+
+ void (*destroy)(struct ceph_auth_client *ac);
+};
+
+struct ceph_auth_client {
+ u32 protocol; /* CEPH_AUTH_* */
+ void *private; /* for use by protocol implementation */
+ const struct ceph_auth_client_ops *ops; /* null iff protocol==0 */
+
+ bool negotiating; /* true if negotiating protocol */
+ const char *name; /* entity name */
+ u64 global_id; /* our unique id in system */
+ const char *secret; /* our secret key */
+ unsigned want_keys; /* which services we want */
+};
+
+extern struct ceph_auth_client *ceph_auth_init(const char *name,
+ const char *secret);
+extern void ceph_auth_destroy(struct ceph_auth_client *ac);
+
+extern void ceph_auth_reset(struct ceph_auth_client *ac);
+
+extern int ceph_auth_build_hello(struct ceph_auth_client *ac,
+ void *buf, size_t len);
+extern int ceph_handle_auth_reply(struct ceph_auth_client *ac,
+ void *buf, size_t len,
+ void *reply_buf, size_t reply_len);
+extern int ceph_entity_name_encode(const char *name, void **p, void *end);
+
+extern int ceph_build_auth(struct ceph_auth_client *ac,
+ void *msg_buf, size_t msg_len);
+
+extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac);
+
+#endif
diff --git a/fs/ceph/auth_none.c b/fs/ceph/auth_none.c
new file mode 100644
index 00000000000..8cd9e3af07f
--- /dev/null
+++ b/fs/ceph/auth_none.c
@@ -0,0 +1,122 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+
+#include "auth_none.h"
+#include "auth.h"
+#include "decode.h"
+
+static void reset(struct ceph_auth_client *ac)
+{
+ struct ceph_auth_none_info *xi = ac->private;
+
+ xi->starting = true;
+ xi->built_authorizer = false;
+}
+
+static void destroy(struct ceph_auth_client *ac)
+{
+ kfree(ac->private);
+ ac->private = NULL;
+}
+
+static int is_authenticated(struct ceph_auth_client *ac)
+{
+ struct ceph_auth_none_info *xi = ac->private;
+
+ return !xi->starting;
+}
+
+/*
+ * the generic auth code decode the global_id, and we carry no actual
+ * authenticate state, so nothing happens here.
+ */
+static int handle_reply(struct ceph_auth_client *ac, int result,
+ void *buf, void *end)
+{
+ struct ceph_auth_none_info *xi = ac->private;
+
+ xi->starting = false;
+ return result;
+}
+
+/*
+ * build an 'authorizer' with our entity_name and global_id. we can
+ * reuse a single static copy since it is identical for all services
+ * we connect to.
+ */
+static int ceph_auth_none_create_authorizer(
+ struct ceph_auth_client *ac, int peer_type,
+ struct ceph_authorizer **a,
+ void **buf, size_t *len,
+ void **reply_buf, size_t *reply_len)
+{
+ struct ceph_auth_none_info *ai = ac->private;
+ struct ceph_none_authorizer *au = &ai->au;
+ void *p, *end;
+ int ret;
+
+ if (!ai->built_authorizer) {
+ p = au->buf;
+ end = p + sizeof(au->buf);
+ ceph_encode_8(&p, 1);
+ ret = ceph_entity_name_encode(ac->name, &p, end - 8);
+ if (ret < 0)
+ goto bad;
+ ceph_decode_need(&p, end, sizeof(u64), bad2);
+ ceph_encode_64(&p, ac->global_id);
+ au->buf_len = p - (void *)au->buf;
+ ai->built_authorizer = true;
+ dout("built authorizer len %d\n", au->buf_len);
+ }
+
+ *a = (struct ceph_authorizer *)au;
+ *buf = au->buf;
+ *len = au->buf_len;
+ *reply_buf = au->reply_buf;
+ *reply_len = sizeof(au->reply_buf);
+ return 0;
+
+bad2:
+ ret = -ERANGE;
+bad:
+ return ret;
+}
+
+static void ceph_auth_none_destroy_authorizer(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a)
+{
+ /* nothing to do */
+}
+
+static const struct ceph_auth_client_ops ceph_auth_none_ops = {
+ .reset = reset,
+ .destroy = destroy,
+ .is_authenticated = is_authenticated,
+ .handle_reply = handle_reply,
+ .create_authorizer = ceph_auth_none_create_authorizer,
+ .destroy_authorizer = ceph_auth_none_destroy_authorizer,
+};
+
+int ceph_auth_none_init(struct ceph_auth_client *ac)
+{
+ struct ceph_auth_none_info *xi;
+
+ dout("ceph_auth_none_init %p\n", ac);
+ xi = kzalloc(sizeof(*xi), GFP_NOFS);
+ if (!xi)
+ return -ENOMEM;
+
+ xi->starting = true;
+ xi->built_authorizer = false;
+
+ ac->protocol = CEPH_AUTH_NONE;
+ ac->private = xi;
+ ac->ops = &ceph_auth_none_ops;
+ return 0;
+}
+
diff --git a/fs/ceph/auth_none.h b/fs/ceph/auth_none.h
new file mode 100644
index 00000000000..56c05533a31
--- /dev/null
+++ b/fs/ceph/auth_none.h
@@ -0,0 +1,28 @@
+#ifndef _FS_CEPH_AUTH_NONE_H
+#define _FS_CEPH_AUTH_NONE_H
+
+#include "auth.h"
+
+/*
+ * null security mode.
+ *
+ * we use a single static authorizer that simply encodes our entity name
+ * and global id.
+ */
+
+struct ceph_none_authorizer {
+ char buf[128];
+ int buf_len;
+ char reply_buf[0];
+};
+
+struct ceph_auth_none_info {
+ bool starting;
+ bool built_authorizer;
+ struct ceph_none_authorizer au; /* we only need one; it's static */
+};
+
+extern int ceph_auth_none_init(struct ceph_auth_client *ac);
+
+#endif
+
diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c
new file mode 100644
index 00000000000..d9001a4dc8c
--- /dev/null
+++ b/fs/ceph/auth_x.c
@@ -0,0 +1,680 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+
+#include "auth_x.h"
+#include "auth_x_protocol.h"
+#include "crypto.h"
+#include "auth.h"
+#include "decode.h"
+
+struct kmem_cache *ceph_x_ticketbuf_cachep;
+
+#define TEMP_TICKET_BUF_LEN 256
+
+static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed);
+
+static int ceph_x_is_authenticated(struct ceph_auth_client *ac)
+{
+ struct ceph_x_info *xi = ac->private;
+ int need;
+
+ ceph_x_validate_tickets(ac, &need);
+ dout("ceph_x_is_authenticated want=%d need=%d have=%d\n",
+ ac->want_keys, need, xi->have_keys);
+ return (ac->want_keys & xi->have_keys) == ac->want_keys;
+}
+
+static int ceph_x_encrypt_buflen(int ilen)
+{
+ return sizeof(struct ceph_x_encrypt_header) + ilen + 16 +
+ sizeof(u32);
+}
+
+static int ceph_x_encrypt(struct ceph_crypto_key *secret,
+ void *ibuf, int ilen, void *obuf, size_t olen)
+{
+ struct ceph_x_encrypt_header head = {
+ .struct_v = 1,
+ .magic = cpu_to_le64(CEPHX_ENC_MAGIC)
+ };
+ size_t len = olen - sizeof(u32);
+ int ret;
+
+ ret = ceph_encrypt2(secret, obuf + sizeof(u32), &len,
+ &head, sizeof(head), ibuf, ilen);
+ if (ret)
+ return ret;
+ ceph_encode_32(&obuf, len);
+ return len + sizeof(u32);
+}
+
+static int ceph_x_decrypt(struct ceph_crypto_key *secret,
+ void **p, void *end, void *obuf, size_t olen)
+{
+ struct ceph_x_encrypt_header head;
+ size_t head_len = sizeof(head);
+ int len, ret;
+
+ len = ceph_decode_32(p);
+ if (*p + len > end)
+ return -EINVAL;
+
+ dout("ceph_x_decrypt len %d\n", len);
+ ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen,
+ *p, len);
+ if (ret)
+ return ret;
+ if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC)
+ return -EPERM;
+ *p += len;
+ return olen;
+}
+
+/*
+ * get existing (or insert new) ticket handler
+ */
+struct ceph_x_ticket_handler *get_ticket_handler(struct ceph_auth_client *ac,
+ int service)
+{
+ struct ceph_x_ticket_handler *th;
+ struct ceph_x_info *xi = ac->private;
+ struct rb_node *parent = NULL, **p = &xi->ticket_handlers.rb_node;
+
+ while (*p) {
+ parent = *p;
+ th = rb_entry(parent, struct ceph_x_ticket_handler, node);
+ if (service < th->service)
+ p = &(*p)->rb_left;
+ else if (service > th->service)
+ p = &(*p)->rb_right;
+ else
+ return th;
+ }
+
+ /* add it */
+ th = kzalloc(sizeof(*th), GFP_NOFS);
+ if (!th)
+ return ERR_PTR(-ENOMEM);
+ th->service = service;
+ rb_link_node(&th->node, parent, p);
+ rb_insert_color(&th->node, &xi->ticket_handlers);
+ return th;
+}
+
+static void remove_ticket_handler(struct ceph_auth_client *ac,
+ struct ceph_x_ticket_handler *th)
+{
+ struct ceph_x_info *xi = ac->private;
+
+ dout("remove_ticket_handler %p %d\n", th, th->service);
+ rb_erase(&th->node, &xi->ticket_handlers);
+ ceph_crypto_key_destroy(&th->session_key);
+ if (th->ticket_blob)
+ ceph_buffer_put(th->ticket_blob);
+ kfree(th);
+}
+
+static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
+ struct ceph_crypto_key *secret,
+ void *buf, void *end)
+{
+ struct ceph_x_info *xi = ac->private;
+ int num;
+ void *p = buf;
+ int ret;
+ char *dbuf;
+ char *ticket_buf;
+ u8 struct_v;
+
+ dbuf = kmem_cache_alloc(ceph_x_ticketbuf_cachep, GFP_NOFS | GFP_ATOMIC);
+ if (!dbuf)
+ return -ENOMEM;
+
+ ret = -ENOMEM;
+ ticket_buf = kmem_cache_alloc(ceph_x_ticketbuf_cachep,
+ GFP_NOFS | GFP_ATOMIC);
+ if (!ticket_buf)
+ goto out_dbuf;
+
+ ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
+ struct_v = ceph_decode_8(&p);
+ if (struct_v != 1)
+ goto bad;
+ num = ceph_decode_32(&p);
+ dout("%d tickets\n", num);
+ while (num--) {
+ int type;
+ u8 struct_v;
+ struct ceph_x_ticket_handler *th;
+ void *dp, *dend;
+ int dlen;
+ char is_enc;
+ struct timespec validity;
+ struct ceph_crypto_key old_key;
+ void *tp, *tpend;
+ struct ceph_timespec new_validity;
+ struct ceph_crypto_key new_session_key;
+ struct ceph_buffer *new_ticket_blob;
+ unsigned long new_expires, new_renew_after;
+ u64 new_secret_id;
+
+ ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
+
+ type = ceph_decode_32(&p);
+ dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
+
+ struct_v = ceph_decode_8(&p);
+ if (struct_v != 1)
+ goto bad;
+
+ th = get_ticket_handler(ac, type);
+ if (IS_ERR(th)) {
+ ret = PTR_ERR(th);
+ goto out;
+ }
+
+ /* blob for me */
+ dlen = ceph_x_decrypt(secret, &p, end, dbuf,
+ TEMP_TICKET_BUF_LEN);
+ if (dlen <= 0) {
+ ret = dlen;
+ goto out;
+ }
+ dout(" decrypted %d bytes\n", dlen);
+ dend = dbuf + dlen;
+ dp = dbuf;
+
+ struct_v = ceph_decode_8(&dp);
+ if (struct_v != 1)
+ goto bad;
+
+ memcpy(&old_key, &th->session_key, sizeof(old_key));
+ ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
+ if (ret)
+ goto out;
+
+ ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
+ ceph_decode_timespec(&validity, &new_validity);
+ new_expires = get_seconds() + validity.tv_sec;
+ new_renew_after = new_expires - (validity.tv_sec / 4);
+ dout(" expires=%lu renew_after=%lu\n", new_expires,
+ new_renew_after);
+
+ /* ticket blob for service */
+ ceph_decode_8_safe(&p, end, is_enc, bad);
+ tp = ticket_buf;
+ if (is_enc) {
+ /* encrypted */
+ dout(" encrypted ticket\n");
+ dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf,
+ TEMP_TICKET_BUF_LEN);
+ if (dlen < 0) {
+ ret = dlen;
+ goto out;
+ }
+ dlen = ceph_decode_32(&tp);
+ } else {
+ /* unencrypted */
+ ceph_decode_32_safe(&p, end, dlen, bad);
+ ceph_decode_need(&p, end, dlen, bad);
+ ceph_decode_copy(&p, ticket_buf, dlen);
+ }
+ tpend = tp + dlen;
+ dout(" ticket blob is %d bytes\n", dlen);
+ ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
+ struct_v = ceph_decode_8(&tp);
+ new_secret_id = ceph_decode_64(&tp);
+ ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
+ if (ret)
+ goto out;
+
+ /* all is well, update our ticket */
+ ceph_crypto_key_destroy(&th->session_key);
+ if (th->ticket_blob)
+ ceph_buffer_put(th->ticket_blob);
+ th->session_key = new_session_key;
+ th->ticket_blob = new_ticket_blob;
+ th->validity = new_validity;
+ th->secret_id = new_secret_id;
+ th->expires = new_expires;
+ th->renew_after = new_renew_after;
+ dout(" got ticket service %d (%s) secret_id %lld len %d\n",
+ type, ceph_entity_type_name(type), th->secret_id,
+ (int)th->ticket_blob->vec.iov_len);
+ xi->have_keys |= th->service;
+ }
+
+ ret = 0;
+out:
+ kmem_cache_free(ceph_x_ticketbuf_cachep, ticket_buf);
+out_dbuf:
+ kmem_cache_free(ceph_x_ticketbuf_cachep, dbuf);
+ return ret;
+
+bad:
+ ret = -EINVAL;
+ goto out;
+}
+
+static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
+ struct ceph_x_ticket_handler *th,
+ struct ceph_x_authorizer *au)
+{
+ int maxlen;
+ struct ceph_x_authorize_a *msg_a;
+ struct ceph_x_authorize_b msg_b;
+ void *p, *end;
+ int ret;
+ int ticket_blob_len =
+ (th->ticket_blob ? th->ticket_blob->vec.iov_len : 0);
+
+ dout("build_authorizer for %s %p\n",
+ ceph_entity_type_name(th->service), au);
+
+ maxlen = sizeof(*msg_a) + sizeof(msg_b) +
+ ceph_x_encrypt_buflen(ticket_blob_len);
+ dout(" need len %d\n", maxlen);
+ if (au->buf && au->buf->alloc_len < maxlen) {
+ ceph_buffer_put(au->buf);
+ au->buf = NULL;
+ }
+ if (!au->buf) {
+ au->buf = ceph_buffer_new(maxlen, GFP_NOFS);
+ if (!au->buf)
+ return -ENOMEM;
+ }
+ au->service = th->service;
+
+ msg_a = au->buf->vec.iov_base;
+ msg_a->struct_v = 1;
+ msg_a->global_id = cpu_to_le64(ac->global_id);
+ msg_a->service_id = cpu_to_le32(th->service);
+ msg_a->ticket_blob.struct_v = 1;
+ msg_a->ticket_blob.secret_id = cpu_to_le64(th->secret_id);
+ msg_a->ticket_blob.blob_len = cpu_to_le32(ticket_blob_len);
+ if (ticket_blob_len) {
+ memcpy(msg_a->ticket_blob.blob, th->ticket_blob->vec.iov_base,
+ th->ticket_blob->vec.iov_len);
+ }
+ dout(" th %p secret_id %lld %lld\n", th, th->secret_id,
+ le64_to_cpu(msg_a->ticket_blob.secret_id));
+
+ p = msg_a + 1;
+ p += ticket_blob_len;
+ end = au->buf->vec.iov_base + au->buf->vec.iov_len;
+
+ get_random_bytes(&au->nonce, sizeof(au->nonce));
+ msg_b.struct_v = 1;
+ msg_b.nonce = cpu_to_le64(au->nonce);
+ ret = ceph_x_encrypt(&th->session_key, &msg_b, sizeof(msg_b),
+ p, end - p);
+ if (ret < 0)
+ goto out_buf;
+ p += ret;
+ au->buf->vec.iov_len = p - au->buf->vec.iov_base;
+ dout(" built authorizer nonce %llx len %d\n", au->nonce,
+ (int)au->buf->vec.iov_len);
+ BUG_ON(au->buf->vec.iov_len > maxlen);
+ return 0;
+
+out_buf:
+ ceph_buffer_put(au->buf);
+ au->buf = NULL;
+ return ret;
+}
+
+static int ceph_x_encode_ticket(struct ceph_x_ticket_handler *th,
+ void **p, void *end)
+{
+ ceph_decode_need(p, end, 1 + sizeof(u64), bad);
+ ceph_encode_8(p, 1);
+ ceph_encode_64(p, th->secret_id);
+ if (th->ticket_blob) {
+ const char *buf = th->ticket_blob->vec.iov_base;
+ u32 len = th->ticket_blob->vec.iov_len;
+
+ ceph_encode_32_safe(p, end, len, bad);
+ ceph_encode_copy_safe(p, end, buf, len, bad);
+ } else {
+ ceph_encode_32_safe(p, end, 0, bad);
+ }
+
+ return 0;
+bad:
+ return -ERANGE;
+}
+
+static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)
+{
+ int want = ac->want_keys;
+ struct ceph_x_info *xi = ac->private;
+ int service;
+
+ *pneed = ac->want_keys & ~(xi->have_keys);
+
+ for (service = 1; service <= want; service <<= 1) {
+ struct ceph_x_ticket_handler *th;
+
+ if (!(ac->want_keys & service))
+ continue;
+
+ if (*pneed & service)
+ continue;
+
+ th = get_ticket_handler(ac, service);
+
+ if (!th) {
+ *pneed |= service;
+ continue;
+ }
+
+ if (get_seconds() >= th->renew_after)
+ *pneed |= service;
+ if (get_seconds() >= th->expires)
+ xi->have_keys &= ~service;
+ }
+}
+
+
+static int ceph_x_build_request(struct ceph_auth_client *ac,
+ void *buf, void *end)
+{
+ struct ceph_x_info *xi = ac->private;
+ int need;
+ struct ceph_x_request_header *head = buf;
+ int ret;
+ struct ceph_x_ticket_handler *th =
+ get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
+
+ ceph_x_validate_tickets(ac, &need);
+
+ dout("build_request want %x have %x need %x\n",
+ ac->want_keys, xi->have_keys, need);
+
+ if (need & CEPH_ENTITY_TYPE_AUTH) {
+ struct ceph_x_authenticate *auth = (void *)(head + 1);
+ void *p = auth + 1;
+ struct ceph_x_challenge_blob tmp;
+ char tmp_enc[40];
+ u64 *u;
+
+ if (p > end)
+ return -ERANGE;
+
+ dout(" get_auth_session_key\n");
+ head->op = cpu_to_le16(CEPHX_GET_AUTH_SESSION_KEY);
+
+ /* encrypt and hash */
+ get_random_bytes(&auth->client_challenge, sizeof(u64));
+ tmp.client_challenge = auth->client_challenge;
+ tmp.server_challenge = cpu_to_le64(xi->server_challenge);
+ ret = ceph_x_encrypt(&xi->secret, &tmp, sizeof(tmp),
+ tmp_enc, sizeof(tmp_enc));
+ if (ret < 0)
+ return ret;
+
+ auth->struct_v = 1;
+ auth->key = 0;
+ for (u = (u64 *)tmp_enc; u + 1 <= (u64 *)(tmp_enc + ret); u++)
+ auth->key ^= *u;
+ dout(" server_challenge %llx client_challenge %llx key %llx\n",
+ xi->server_challenge, le64_to_cpu(auth->client_challenge),
+ le64_to_cpu(auth->key));
+
+ /* now encode the old ticket if exists */
+ ret = ceph_x_encode_ticket(th, &p, end);
+ if (ret < 0)
+ return ret;
+
+ return p - buf;
+ }
+
+ if (need) {
+ void *p = head + 1;
+ struct ceph_x_service_ticket_request *req;
+
+ if (p > end)
+ return -ERANGE;
+ head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY);
+
+ BUG_ON(!th);
+ ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer);
+ if (ret)
+ return ret;
+ ceph_encode_copy(&p, xi->auth_authorizer.buf->vec.iov_base,
+ xi->auth_authorizer.buf->vec.iov_len);
+
+ req = p;
+ req->keys = cpu_to_le32(need);
+ p += sizeof(*req);
+ return p - buf;
+ }
+
+ return 0;
+}
+
+static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
+ void *buf, void *end)
+{
+ struct ceph_x_info *xi = ac->private;
+ struct ceph_x_reply_header *head = buf;
+ struct ceph_x_ticket_handler *th;
+ int len = end - buf;
+ int op;
+ int ret;
+
+ if (result)
+ return result; /* XXX hmm? */
+
+ if (xi->starting) {
+ /* it's a hello */
+ struct ceph_x_server_challenge *sc = buf;
+
+ if (len != sizeof(*sc))
+ return -EINVAL;
+ xi->server_challenge = le64_to_cpu(sc->server_challenge);
+ dout("handle_reply got server challenge %llx\n",
+ xi->server_challenge);
+ xi->starting = false;
+ xi->have_keys &= ~CEPH_ENTITY_TYPE_AUTH;
+ return -EAGAIN;
+ }
+
+ op = le32_to_cpu(head->op);
+ result = le32_to_cpu(head->result);
+ dout("handle_reply op %d result %d\n", op, result);
+ switch (op) {
+ case CEPHX_GET_AUTH_SESSION_KEY:
+ /* verify auth key */
+ ret = ceph_x_proc_ticket_reply(ac, &xi->secret,
+ buf + sizeof(*head), end);
+ break;
+
+ case CEPHX_GET_PRINCIPAL_SESSION_KEY:
+ th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
+ BUG_ON(!th);
+ ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
+ buf + sizeof(*head), end);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ if (ret)
+ return ret;
+ if (ac->want_keys == xi->have_keys)
+ return 0;
+ return -EAGAIN;
+}
+
+static int ceph_x_create_authorizer(
+ struct ceph_auth_client *ac, int peer_type,
+ struct ceph_authorizer **a,
+ void **buf, size_t *len,
+ void **reply_buf, size_t *reply_len)
+{
+ struct ceph_x_authorizer *au;
+ struct ceph_x_ticket_handler *th;
+ int ret;
+
+ th = get_ticket_handler(ac, peer_type);
+ if (IS_ERR(th))
+ return PTR_ERR(th);
+
+ au = kzalloc(sizeof(*au), GFP_NOFS);
+ if (!au)
+ return -ENOMEM;
+
+ ret = ceph_x_build_authorizer(ac, th, au);
+ if (ret) {
+ kfree(au);
+ return ret;
+ }
+
+ *a = (struct ceph_authorizer *)au;
+ *buf = au->buf->vec.iov_base;
+ *len = au->buf->vec.iov_len;
+ *reply_buf = au->reply_buf;
+ *reply_len = sizeof(au->reply_buf);
+ return 0;
+}
+
+static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a, size_t len)
+{
+ struct ceph_x_authorizer *au = (void *)a;
+ struct ceph_x_ticket_handler *th;
+ int ret = 0;
+ struct ceph_x_authorize_reply reply;
+ void *p = au->reply_buf;
+ void *end = p + sizeof(au->reply_buf);
+
+ th = get_ticket_handler(ac, au->service);
+ if (!th)
+ return -EIO; /* hrm! */
+ ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply));
+ if (ret < 0)
+ return ret;
+ if (ret != sizeof(reply))
+ return -EPERM;
+
+ if (au->nonce + 1 != le64_to_cpu(reply.nonce_plus_one))
+ ret = -EPERM;
+ else
+ ret = 0;
+ dout("verify_authorizer_reply nonce %llx got %llx ret %d\n",
+ au->nonce, le64_to_cpu(reply.nonce_plus_one), ret);
+ return ret;
+}
+
+static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a)
+{
+ struct ceph_x_authorizer *au = (void *)a;
+
+ ceph_buffer_put(au->buf);
+ kfree(au);
+}
+
+
+static void ceph_x_reset(struct ceph_auth_client *ac)
+{
+ struct ceph_x_info *xi = ac->private;
+
+ dout("reset\n");
+ xi->starting = true;
+ xi->server_challenge = 0;
+}
+
+static void ceph_x_destroy(struct ceph_auth_client *ac)
+{
+ struct ceph_x_info *xi = ac->private;
+ struct rb_node *p;
+
+ dout("ceph_x_destroy %p\n", ac);
+ ceph_crypto_key_destroy(&xi->secret);
+
+ while ((p = rb_first(&xi->ticket_handlers)) != NULL) {
+ struct ceph_x_ticket_handler *th =
+ rb_entry(p, struct ceph_x_ticket_handler, node);
+ remove_ticket_handler(ac, th);
+ }
+
+ kmem_cache_destroy(ceph_x_ticketbuf_cachep);
+
+ kfree(ac->private);
+ ac->private = NULL;
+}
+
+static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
+ int peer_type)
+{
+ struct ceph_x_ticket_handler *th;
+
+ th = get_ticket_handler(ac, peer_type);
+ if (th && !IS_ERR(th))
+ remove_ticket_handler(ac, th);
+}
+
+
+static const struct ceph_auth_client_ops ceph_x_ops = {
+ .is_authenticated = ceph_x_is_authenticated,
+ .build_request = ceph_x_build_request,
+ .handle_reply = ceph_x_handle_reply,
+ .create_authorizer = ceph_x_create_authorizer,
+ .verify_authorizer_reply = ceph_x_verify_authorizer_reply,
+ .destroy_authorizer = ceph_x_destroy_authorizer,
+ .invalidate_authorizer = ceph_x_invalidate_authorizer,
+ .reset = ceph_x_reset,
+ .destroy = ceph_x_destroy,
+};
+
+
+int ceph_x_init(struct ceph_auth_client *ac)
+{
+ struct ceph_x_info *xi;
+ int ret;
+
+ dout("ceph_x_init %p\n", ac);
+ xi = kzalloc(sizeof(*xi), GFP_NOFS);
+ if (!xi)
+ return -ENOMEM;
+
+ ret = -ENOMEM;
+ ceph_x_ticketbuf_cachep = kmem_cache_create("ceph_x_ticketbuf",
+ TEMP_TICKET_BUF_LEN, 8,
+ (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
+ NULL);
+ if (!ceph_x_ticketbuf_cachep)
+ goto done_nomem;
+ ret = -EINVAL;
+ if (!ac->secret) {
+ pr_err("no secret set (for auth_x protocol)\n");
+ goto done_nomem;
+ }
+
+ ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret);
+ if (ret)
+ goto done_nomem;
+
+ xi->starting = true;
+ xi->ticket_handlers = RB_ROOT;
+
+ ac->protocol = CEPH_AUTH_CEPHX;
+ ac->private = xi;
+ ac->ops = &ceph_x_ops;
+ return 0;
+
+done_nomem:
+ kfree(xi);
+ if (ceph_x_ticketbuf_cachep)
+ kmem_cache_destroy(ceph_x_ticketbuf_cachep);
+ return ret;
+}
+
+
diff --git a/fs/ceph/auth_x.h b/fs/ceph/auth_x.h
new file mode 100644
index 00000000000..ff6f8180e68
--- /dev/null
+++ b/fs/ceph/auth_x.h
@@ -0,0 +1,49 @@
+#ifndef _FS_CEPH_AUTH_X_H
+#define _FS_CEPH_AUTH_X_H
+
+#include <linux/rbtree.h>
+
+#include "crypto.h"
+#include "auth.h"
+#include "auth_x_protocol.h"
+
+/*
+ * Handle ticket for a single service.
+ */
+struct ceph_x_ticket_handler {
+ struct rb_node node;
+ unsigned service;
+
+ struct ceph_crypto_key session_key;
+ struct ceph_timespec validity;
+
+ u64 secret_id;
+ struct ceph_buffer *ticket_blob;
+
+ unsigned long renew_after, expires;
+};
+
+
+struct ceph_x_authorizer {
+ struct ceph_buffer *buf;
+ unsigned service;
+ u64 nonce;
+ char reply_buf[128]; /* big enough for encrypted blob */
+};
+
+struct ceph_x_info {
+ struct ceph_crypto_key secret;
+
+ bool starting;
+ u64 server_challenge;
+
+ unsigned have_keys;
+ struct rb_root ticket_handlers;
+
+ struct ceph_x_authorizer auth_authorizer;
+};
+
+extern int ceph_x_init(struct ceph_auth_client *ac);
+
+#endif
+
diff --git a/fs/ceph/auth_x_protocol.h b/fs/ceph/auth_x_protocol.h
new file mode 100644
index 00000000000..671d30576c4
--- /dev/null
+++ b/fs/ceph/auth_x_protocol.h
@@ -0,0 +1,90 @@
+#ifndef __FS_CEPH_AUTH_X_PROTOCOL
+#define __FS_CEPH_AUTH_X_PROTOCOL
+
+#define CEPHX_GET_AUTH_SESSION_KEY 0x0100
+#define CEPHX_GET_PRINCIPAL_SESSION_KEY 0x0200
+#define CEPHX_GET_ROTATING_KEY 0x0400
+
+/* common bits */
+struct ceph_x_ticket_blob {
+ __u8 struct_v;
+ __le64 secret_id;
+ __le32 blob_len;
+ char blob[];
+} __attribute__ ((packed));
+
+
+/* common request/reply headers */
+struct ceph_x_request_header {
+ __le16 op;
+} __attribute__ ((packed));
+
+struct ceph_x_reply_header {
+ __le16 op;
+ __le32 result;
+} __attribute__ ((packed));
+
+
+/* authenticate handshake */
+
+/* initial hello (no reply header) */
+struct ceph_x_server_challenge {
+ __u8 struct_v;
+ __le64 server_challenge;
+} __attribute__ ((packed));
+
+struct ceph_x_authenticate {
+ __u8 struct_v;
+ __le64 client_challenge;
+ __le64 key;
+ /* ticket blob */
+} __attribute__ ((packed));
+
+struct ceph_x_service_ticket_request {
+ __u8 struct_v;
+ __le32 keys;
+} __attribute__ ((packed));
+
+struct ceph_x_challenge_blob {
+ __le64 server_challenge;
+ __le64 client_challenge;
+} __attribute__ ((packed));
+
+
+
+/* authorize handshake */
+
+/*
+ * The authorizer consists of two pieces:
+ * a - service id, ticket blob
+ * b - encrypted with session key
+ */
+struct ceph_x_authorize_a {
+ __u8 struct_v;
+ __le64 global_id;
+ __le32 service_id;
+ struct ceph_x_ticket_blob ticket_blob;
+} __attribute__ ((packed));
+
+struct ceph_x_authorize_b {
+ __u8 struct_v;
+ __le64 nonce;
+} __attribute__ ((packed));
+
+struct ceph_x_authorize_reply {
+ __u8 struct_v;
+ __le64 nonce_plus_one;
+} __attribute__ ((packed));
+
+
+/*
+ * encyption bundle
+ */
+#define CEPHX_ENC_MAGIC 0xff009cad8826aa55ull
+
+struct ceph_x_encrypt_header {
+ __u8 struct_v;
+ __le64 magic;
+} __attribute__ ((packed));
+
+#endif
diff --git a/fs/ceph/buffer.c b/fs/ceph/buffer.c
new file mode 100644
index 00000000000..c67535d70aa
--- /dev/null
+++ b/fs/ceph/buffer.c
@@ -0,0 +1,81 @@
+
+#include "ceph_debug.h"
+
+#include <linux/slab.h>
+
+#include "buffer.h"
+#include "decode.h"
+
+struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
+{
+ struct ceph_buffer *b;
+
+ b = kmalloc(sizeof(*b), gfp);
+ if (!b)
+ return NULL;
+
+ b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN);
+ if (b->vec.iov_base) {
+ b->is_vmalloc = false;
+ } else {
+ b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL);
+ if (!b->vec.iov_base) {
+ kfree(b);
+ return NULL;
+ }
+ b->is_vmalloc = true;
+ }
+
+ kref_init(&b->kref);
+ b->alloc_len = len;
+ b->vec.iov_len = len;
+ dout("buffer_new %p\n", b);
+ return b;
+}
+
+void ceph_buffer_release(struct kref *kref)
+{
+ struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref);
+
+ dout("buffer_release %p\n", b);
+ if (b->vec.iov_base) {
+ if (b->is_vmalloc)
+ vfree(b->vec.iov_base);
+ else
+ kfree(b->vec.iov_base);
+ }
+ kfree(b);
+}
+
+int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp)
+{
+ b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN);
+ if (b->vec.iov_base) {
+ b->is_vmalloc = false;
+ } else {
+ b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL);
+ b->is_vmalloc = true;
+ }
+ if (!b->vec.iov_base)
+ return -ENOMEM;
+ b->alloc_len = len;
+ b->vec.iov_len = len;
+ return 0;
+}
+
+int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end)
+{
+ size_t len;
+
+ ceph_decode_need(p, end, sizeof(u32), bad);
+ len = ceph_decode_32(p);
+ dout("decode_buffer len %d\n", (int)len);
+ ceph_decode_need(p, end, len, bad);
+ *b = ceph_buffer_new(len, GFP_NOFS);
+ if (!*b)
+ return -ENOMEM;
+ ceph_decode_copy(p, (*b)->vec.iov_base, len);
+ return 0;
+bad:
+ return -EINVAL;
+}
diff --git a/fs/ceph/buffer.h b/fs/ceph/buffer.h
new file mode 100644
index 00000000000..58d19014068
--- /dev/null
+++ b/fs/ceph/buffer.h
@@ -0,0 +1,39 @@
+#ifndef __FS_CEPH_BUFFER_H
+#define __FS_CEPH_BUFFER_H
+
+#include <linux/kref.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/types.h>
+#include <linux/uio.h>
+
+/*
+ * a simple reference counted buffer.
+ *
+ * use kmalloc for small sizes (<= one page), vmalloc for larger
+ * sizes.
+ */
+struct ceph_buffer {
+ struct kref kref;
+ struct kvec vec;
+ size_t alloc_len;
+ bool is_vmalloc;
+};
+
+extern struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp);
+extern void ceph_buffer_release(struct kref *kref);
+
+static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b)
+{
+ kref_get(&b->kref);
+ return b;
+}
+
+static inline void ceph_buffer_put(struct ceph_buffer *b)
+{
+ kref_put(&b->kref, ceph_buffer_release);
+}
+
+extern int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end);
+
+#endif
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
new file mode 100644
index 00000000000..aa2239fa9a3
--- /dev/null
+++ b/fs/ceph/caps.c
@@ -0,0 +1,2955 @@
+#include "ceph_debug.h"
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <linux/writeback.h>
+
+#include "super.h"
+#include "decode.h"
+#include "messenger.h"
+
+/*
+ * Capability management
+ *
+ * The Ceph metadata servers control client access to inode metadata
+ * and file data by issuing capabilities, granting clients permission
+ * to read and/or write both inode field and file data to OSDs
+ * (storage nodes). Each capability consists of a set of bits
+ * indicating which operations are allowed.
+ *
+ * If the client holds a *_SHARED cap, the client has a coherent value
+ * that can be safely read from the cached inode.
+ *
+ * In the case of a *_EXCL (exclusive) or FILE_WR capabilities, the
+ * client is allowed to change inode attributes (e.g., file size,
+ * mtime), note its dirty state in the ceph_cap, and asynchronously
+ * flush that metadata change to the MDS.
+ *
+ * In the event of a conflicting operation (perhaps by another
+ * client), the MDS will revoke the conflicting client capabilities.
+ *
+ * In order for a client to cache an inode, it must hold a capability
+ * with at least one MDS server. When inodes are released, release
+ * notifications are batched and periodically sent en masse to the MDS
+ * cluster to release server state.
+ */
+
+
+/*
+ * Generate readable cap strings for debugging output.
+ */
+#define MAX_CAP_STR 20
+static char cap_str[MAX_CAP_STR][40];
+static DEFINE_SPINLOCK(cap_str_lock);
+static int last_cap_str;
+
+static char *gcap_string(char *s, int c)
+{
+ if (c & CEPH_CAP_GSHARED)
+ *s++ = 's';
+ if (c & CEPH_CAP_GEXCL)
+ *s++ = 'x';
+ if (c & CEPH_CAP_GCACHE)
+ *s++ = 'c';
+ if (c & CEPH_CAP_GRD)
+ *s++ = 'r';
+ if (c & CEPH_CAP_GWR)
+ *s++ = 'w';
+ if (c & CEPH_CAP_GBUFFER)
+ *s++ = 'b';
+ if (c & CEPH_CAP_GLAZYIO)
+ *s++ = 'l';
+ return s;
+}
+
+const char *ceph_cap_string(int caps)
+{
+ int i;
+ char *s;
+ int c;
+
+ spin_lock(&cap_str_lock);
+ i = last_cap_str++;
+ if (last_cap_str == MAX_CAP_STR)
+ last_cap_str = 0;
+ spin_unlock(&cap_str_lock);
+
+ s = cap_str[i];
+
+ if (caps & CEPH_CAP_PIN)
+ *s++ = 'p';
+
+ c = (caps >> CEPH_CAP_SAUTH) & 3;
+ if (c) {
+ *s++ = 'A';
+ s = gcap_string(s, c);
+ }
+
+ c = (caps >> CEPH_CAP_SLINK) & 3;
+ if (c) {
+ *s++ = 'L';
+ s = gcap_string(s, c);
+ }
+
+ c = (caps >> CEPH_CAP_SXATTR) & 3;
+ if (c) {
+ *s++ = 'X';
+ s = gcap_string(s, c);
+ }
+
+ c = caps >> CEPH_CAP_SFILE;
+ if (c) {
+ *s++ = 'F';
+ s = gcap_string(s, c);
+ }
+
+ if (s == cap_str[i])
+ *s++ = '-';
+ *s = 0;
+ return cap_str[i];
+}
+
+/*
+ * Cap reservations
+ *
+ * Maintain a global pool of preallocated struct ceph_caps, referenced
+ * by struct ceph_caps_reservations. This ensures that we preallocate
+ * memory needed to successfully process an MDS response. (If an MDS
+ * sends us cap information and we fail to process it, we will have
+ * problems due to the client and MDS being out of sync.)
+ *
+ * Reservations are 'owned' by a ceph_cap_reservation context.
+ */
+static spinlock_t caps_list_lock;
+static struct list_head caps_list; /* unused (reserved or unreserved) */
+static int caps_total_count; /* total caps allocated */
+static int caps_use_count; /* in use */
+static int caps_reserve_count; /* unused, reserved */
+static int caps_avail_count; /* unused, unreserved */
+static int caps_min_count; /* keep at least this many (unreserved) */
+
+void __init ceph_caps_init(void)
+{
+ INIT_LIST_HEAD(&caps_list);
+ spin_lock_init(&caps_list_lock);
+}
+
+void ceph_caps_finalize(void)
+{
+ struct ceph_cap *cap;
+
+ spin_lock(&caps_list_lock);
+ while (!list_empty(&caps_list)) {
+ cap = list_first_entry(&caps_list, struct ceph_cap, caps_item);
+ list_del(&cap->caps_item);
+ kmem_cache_free(ceph_cap_cachep, cap);
+ }
+ caps_total_count = 0;
+ caps_avail_count = 0;
+ caps_use_count = 0;
+ caps_reserve_count = 0;
+ caps_min_count = 0;
+ spin_unlock(&caps_list_lock);
+}
+
+void ceph_adjust_min_caps(int delta)
+{
+ spin_lock(&caps_list_lock);
+ caps_min_count += delta;
+ BUG_ON(caps_min_count < 0);
+ spin_unlock(&caps_list_lock);
+}
+
+int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need)
+{
+ int i;
+ struct ceph_cap *cap;
+ int have;
+ int alloc = 0;
+ LIST_HEAD(newcaps);
+ int ret = 0;
+
+ dout("reserve caps ctx=%p need=%d\n", ctx, need);
+
+ /* first reserve any caps that are already allocated */
+ spin_lock(&caps_list_lock);
+ if (caps_avail_count >= need)
+ have = need;
+ else
+ have = caps_avail_count;
+ caps_avail_count -= have;
+ caps_reserve_count += have;
+ BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+ caps_avail_count);
+ spin_unlock(&caps_list_lock);
+
+ for (i = have; i < need; i++) {
+ cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
+ if (!cap) {
+ ret = -ENOMEM;
+ goto out_alloc_count;
+ }
+ list_add(&cap->caps_item, &newcaps);
+ alloc++;
+ }
+ BUG_ON(have + alloc != need);
+
+ spin_lock(&caps_list_lock);
+ caps_total_count += alloc;
+ caps_reserve_count += alloc;
+ list_splice(&newcaps, &caps_list);
+
+ BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+ caps_avail_count);
+ spin_unlock(&caps_list_lock);
+
+ ctx->count = need;
+ dout("reserve caps ctx=%p %d = %d used + %d resv + %d avail\n",
+ ctx, caps_total_count, caps_use_count, caps_reserve_count,
+ caps_avail_count);
+ return 0;
+
+out_alloc_count:
+ /* we didn't manage to reserve as much as we needed */
+ pr_warning("reserve caps ctx=%p ENOMEM need=%d got=%d\n",
+ ctx, need, have);
+ return ret;
+}
+
+int ceph_unreserve_caps(struct ceph_cap_reservation *ctx)
+{
+ dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count);
+ if (ctx->count) {
+ spin_lock(&caps_list_lock);
+ BUG_ON(caps_reserve_count < ctx->count);
+ caps_reserve_count -= ctx->count;
+ caps_avail_count += ctx->count;
+ ctx->count = 0;
+ dout("unreserve caps %d = %d used + %d resv + %d avail\n",
+ caps_total_count, caps_use_count, caps_reserve_count,
+ caps_avail_count);
+ BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+ caps_avail_count);
+ spin_unlock(&caps_list_lock);
+ }
+ return 0;
+}
+
+static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx)
+{
+ struct ceph_cap *cap = NULL;
+
+ /* temporary, until we do something about cap import/export */
+ if (!ctx)
+ return kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
+
+ spin_lock(&caps_list_lock);
+ dout("get_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n",
+ ctx, ctx->count, caps_total_count, caps_use_count,
+ caps_reserve_count, caps_avail_count);
+ BUG_ON(!ctx->count);
+ BUG_ON(ctx->count > caps_reserve_count);
+ BUG_ON(list_empty(&caps_list));
+
+ ctx->count--;
+ caps_reserve_count--;
+ caps_use_count++;
+
+ cap = list_first_entry(&caps_list, struct ceph_cap, caps_item);
+ list_del(&cap->caps_item);
+
+ BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+ caps_avail_count);
+ spin_unlock(&caps_list_lock);
+ return cap;
+}
+
+void ceph_put_cap(struct ceph_cap *cap)
+{
+ spin_lock(&caps_list_lock);
+ dout("put_cap %p %d = %d used + %d resv + %d avail\n",
+ cap, caps_total_count, caps_use_count,
+ caps_reserve_count, caps_avail_count);
+ caps_use_count--;
+ /*
+ * Keep some preallocated caps around (ceph_min_count), to
+ * avoid lots of free/alloc churn.
+ */
+ if (caps_avail_count >= caps_reserve_count + caps_min_count) {
+ caps_total_count--;
+ kmem_cache_free(ceph_cap_cachep, cap);
+ } else {
+ caps_avail_count++;
+ list_add(&cap->caps_item, &caps_list);
+ }
+
+ BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+ caps_avail_count);
+ spin_unlock(&caps_list_lock);
+}
+
+void ceph_reservation_status(struct ceph_client *client,
+ int *total, int *avail, int *used, int *reserved,
+ int *min)
+{
+ if (total)
+ *total = caps_total_count;
+ if (avail)
+ *avail = caps_avail_count;
+ if (used)
+ *used = caps_use_count;
+ if (reserved)
+ *reserved = caps_reserve_count;
+ if (min)
+ *min = caps_min_count;
+}
+
+/*
+ * Find ceph_cap for given mds, if any.
+ *
+ * Called with i_lock held.
+ */
+static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
+{
+ struct ceph_cap *cap;
+ struct rb_node *n = ci->i_caps.rb_node;
+
+ while (n) {
+ cap = rb_entry(n, struct ceph_cap, ci_node);
+ if (mds < cap->mds)
+ n = n->rb_left;
+ else if (mds > cap->mds)
+ n = n->rb_right;
+ else
+ return cap;
+ }
+ return NULL;
+}
+
+/*
+ * Return id of any MDS with a cap, preferably FILE_WR|WRBUFFER|EXCL, else
+ * -1.
+ */
+static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq)
+{
+ struct ceph_cap *cap;
+ int mds = -1;
+ struct rb_node *p;
+
+ /* prefer mds with WR|WRBUFFER|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;
+ if (mseq)
+ *mseq = cap->mseq;
+ if (cap->issued & (CEPH_CAP_FILE_WR |
+ CEPH_CAP_FILE_BUFFER |
+ CEPH_CAP_FILE_EXCL))
+ break;
+ }
+ return mds;
+}
+
+int ceph_get_cap_mds(struct inode *inode)
+{
+ int mds;
+ spin_lock(&inode->i_lock);
+ mds = __ceph_get_cap_mds(ceph_inode(inode), NULL);
+ spin_unlock(&inode->i_lock);
+ return mds;
+}
+
+/*
+ * Called under i_lock.
+ */
+static void __insert_cap_node(struct ceph_inode_info *ci,
+ struct ceph_cap *new)
+{
+ struct rb_node **p = &ci->i_caps.rb_node;
+ struct rb_node *parent = NULL;
+ struct ceph_cap *cap = NULL;
+
+ while (*p) {
+ parent = *p;
+ cap = rb_entry(parent, struct ceph_cap, ci_node);
+ if (new->mds < cap->mds)
+ p = &(*p)->rb_left;
+ else if (new->mds > cap->mds)
+ p = &(*p)->rb_right;
+ else
+ BUG();
+ }
+
+ rb_link_node(&new->ci_node, parent, p);
+ rb_insert_color(&new->ci_node, &ci->i_caps);
+}
+
+/*
+ * (re)set cap hold timeouts, which control the delayed release
+ * of unused caps back to the MDS. Should be called on cap use.
+ */
+static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
+ struct ceph_inode_info *ci)
+{
+ struct ceph_mount_args *ma = mdsc->client->mount_args;
+
+ ci->i_hold_caps_min = round_jiffies(jiffies +
+ ma->caps_wanted_delay_min * HZ);
+ ci->i_hold_caps_max = round_jiffies(jiffies +
+ ma->caps_wanted_delay_max * HZ);
+ dout("__cap_set_timeouts %p min %lu max %lu\n", &ci->vfs_inode,
+ ci->i_hold_caps_min - jiffies, ci->i_hold_caps_max - jiffies);
+}
+
+/*
+ * (Re)queue cap at the end of the delayed cap release list.
+ *
+ * If I_FLUSH is set, leave the inode at the front of the list.
+ *
+ * Caller holds i_lock
+ * -> we take mdsc->cap_delay_lock
+ */
+static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
+ struct ceph_inode_info *ci)
+{
+ __cap_set_timeouts(mdsc, ci);
+ dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode,
+ ci->i_ceph_flags, ci->i_hold_caps_max);
+ if (!mdsc->stopping) {
+ spin_lock(&mdsc->cap_delay_lock);
+ if (!list_empty(&ci->i_cap_delay_list)) {
+ if (ci->i_ceph_flags & CEPH_I_FLUSH)
+ goto no_change;
+ list_del_init(&ci->i_cap_delay_list);
+ }
+ list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
+no_change:
+ spin_unlock(&mdsc->cap_delay_lock);
+ }
+}
+
+/*
+ * Queue an inode for immediate writeback. Mark inode with I_FLUSH,
+ * indicating we should send a cap message to flush dirty metadata
+ * asap, and move to the front of the delayed cap list.
+ */
+static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc,
+ struct ceph_inode_info *ci)
+{
+ dout("__cap_delay_requeue_front %p\n", &ci->vfs_inode);
+ spin_lock(&mdsc->cap_delay_lock);
+ ci->i_ceph_flags |= CEPH_I_FLUSH;
+ if (!list_empty(&ci->i_cap_delay_list))
+ list_del_init(&ci->i_cap_delay_list);
+ list_add(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
+ spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Cancel delayed work on cap.
+ *
+ * Caller must hold i_lock.
+ */
+static void __cap_delay_cancel(struct ceph_mds_client *mdsc,
+ struct ceph_inode_info *ci)
+{
+ dout("__cap_delay_cancel %p\n", &ci->vfs_inode);
+ if (list_empty(&ci->i_cap_delay_list))
+ return;
+ spin_lock(&mdsc->cap_delay_lock);
+ list_del_init(&ci->i_cap_delay_list);
+ spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Common issue checks for add_cap, handle_cap_grant.
+ */
+static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
+ unsigned issued)
+{
+ unsigned had = __ceph_caps_issued(ci, NULL);
+
+ /*
+ * Each time we receive FILE_CACHE anew, we increment
+ * i_rdcache_gen.
+ */
+ if ((issued & CEPH_CAP_FILE_CACHE) &&
+ (had & CEPH_CAP_FILE_CACHE) == 0)
+ ci->i_rdcache_gen++;
+
+ /*
+ * if we are newly issued FILE_SHARED, clear I_COMPLETE; we
+ * don't know what happened to this directory while we didn't
+ * have the cap.
+ */
+ if ((issued & CEPH_CAP_FILE_SHARED) &&
+ (had & CEPH_CAP_FILE_SHARED) == 0) {
+ ci->i_shared_gen++;
+ if (S_ISDIR(ci->vfs_inode.i_mode)) {
+ dout(" marking %p NOT complete\n", &ci->vfs_inode);
+ ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+ }
+ }
+}
+
+/*
+ * Add a capability under the given MDS session.
+ *
+ * Caller should hold session snap_rwsem (read) and s_mutex.
+ *
+ * @fmode is the open file mode, if we are opening a file, otherwise
+ * it is < 0. (This is so we can atomically add the cap and add an
+ * open file reference to it.)
+ */
+int ceph_add_cap(struct inode *inode,
+ struct ceph_mds_session *session, u64 cap_id,
+ int fmode, unsigned issued, unsigned wanted,
+ unsigned seq, unsigned mseq, u64 realmino, int flags,
+ struct ceph_cap_reservation *caps_reservation)
+{
+ struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_cap *new_cap = NULL;
+ struct ceph_cap *cap;
+ int mds = session->s_mds;
+ int actual_wanted;
+
+ dout("add_cap %p mds%d cap %llx %s seq %d\n", inode,
+ session->s_mds, cap_id, ceph_cap_string(issued), seq);
+
+ /*
+ * If we are opening the file, include file mode wanted bits
+ * in wanted.
+ */
+ if (fmode >= 0)
+ wanted |= ceph_caps_for_mode(fmode);
+
+retry:
+ spin_lock(&inode->i_lock);
+ cap = __get_cap_for_mds(ci, mds);
+ if (!cap) {
+ if (new_cap) {
+ cap = new_cap;
+ new_cap = NULL;
+ } else {
+ spin_unlock(&inode->i_lock);
+ new_cap = get_cap(caps_reservation);
+ if (new_cap == NULL)
+ return -ENOMEM;
+ goto retry;
+ }
+
+ cap->issued = 0;
+ cap->implemented = 0;
+ cap->mds = mds;
+ cap->mds_wanted = 0;
+
+ cap->ci = ci;
+ __insert_cap_node(ci, cap);
+
+ /* clear out old exporting info? (i.e. on cap import) */
+ if (ci->i_cap_exporting_mds == mds) {
+ ci->i_cap_exporting_issued = 0;
+ ci->i_cap_exporting_mseq = 0;
+ ci->i_cap_exporting_mds = -1;
+ }
+
+ /* add to session cap list */
+ cap->session = session;
+ spin_lock(&session->s_cap_lock);
+ list_add_tail(&cap->session_caps, &session->s_caps);
+ session->s_nr_caps++;
+ spin_unlock(&session->s_cap_lock);
+ }
+
+ if (!ci->i_snap_realm) {
+ /*
+ * add this inode to the appropriate snap realm
+ */
+ struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc,
+ realmino);
+ if (realm) {
+ ceph_get_snap_realm(mdsc, realm);
+ spin_lock(&realm->inodes_with_caps_lock);
+ ci->i_snap_realm = realm;
+ list_add(&ci->i_snap_realm_item,
+ &realm->inodes_with_caps);
+ spin_unlock(&realm->inodes_with_caps_lock);
+ } else {
+ pr_err("ceph_add_cap: couldn't find snap realm %llx\n",
+ realmino);
+ }
+ }
+
+ __check_cap_issue(ci, cap, issued);
+
+ /*
+ * If we are issued caps we don't want, or the mds' wanted
+ * value appears to be off, queue a check so we'll release
+ * later and/or update the mds wanted value.
+ */
+ actual_wanted = __ceph_caps_wanted(ci);
+ if ((wanted & ~actual_wanted) ||
+ (issued & ~actual_wanted & CEPH_CAP_ANY_WR)) {
+ dout(" issued %s, mds wanted %s, actual %s, queueing\n",
+ ceph_cap_string(issued), ceph_cap_string(wanted),
+ ceph_cap_string(actual_wanted));
+ __cap_delay_requeue(mdsc, ci);
+ }
+
+ if (flags & CEPH_CAP_FLAG_AUTH)
+ ci->i_auth_cap = cap;
+ else if (ci->i_auth_cap == cap)
+ ci->i_auth_cap = NULL;
+
+ dout("add_cap inode %p (%llx.%llx) cap %p %s now %s seq %d mds%d\n",
+ inode, ceph_vinop(inode), cap, ceph_cap_string(issued),
+ ceph_cap_string(issued|cap->issued), seq, mds);
+ cap->cap_id = cap_id;
+ cap->issued = issued;
+ cap->implemented |= issued;
+ cap->mds_wanted |= wanted;
+ cap->seq = seq;
+ cap->issue_seq = seq;
+ cap->mseq = mseq;
+ cap->cap_gen = session->s_cap_gen;
+
+ if (fmode >= 0)
+ __ceph_get_fmode(ci, fmode);
+ spin_unlock(&inode->i_lock);
+ wake_up(&ci->i_cap_wq);
+ return 0;
+}
+
+/*
+ * Return true if cap has not timed out and belongs to the current
+ * generation of the MDS session (i.e. has not gone 'stale' due to
+ * us losing touch with the mds).
+ */
+static int __cap_is_valid(struct ceph_cap *cap)
+{
+ unsigned long ttl;
+ u32 gen;
+
+ spin_lock(&cap->session->s_cap_lock);
+ gen = cap->session->s_cap_gen;
+ ttl = cap->session->s_cap_ttl;
+ spin_unlock(&cap->session->s_cap_lock);
+
+ if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) {
+ dout("__cap_is_valid %p cap %p issued %s "
+ "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode,
+ cap, ceph_cap_string(cap->issued), cap->cap_gen, gen);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Return set of valid cap bits issued to us. Note that caps time
+ * out, and may be invalidated in bulk if the client session times out
+ * and session->s_cap_gen is bumped.
+ */
+int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented)
+{
+ int have = ci->i_snap_caps | ci->i_cap_exporting_issued;
+ struct ceph_cap *cap;
+ struct rb_node *p;
+
+ if (implemented)
+ *implemented = 0;
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ cap = rb_entry(p, struct ceph_cap, ci_node);
+ if (!__cap_is_valid(cap))
+ continue;
+ dout("__ceph_caps_issued %p cap %p issued %s\n",
+ &ci->vfs_inode, cap, ceph_cap_string(cap->issued));
+ have |= cap->issued;
+ if (implemented)
+ *implemented |= cap->implemented;
+ }
+ return have;
+}
+
+/*
+ * Get cap bits issued by caps other than @ocap
+ */
+int __ceph_caps_issued_other(struct ceph_inode_info *ci, struct ceph_cap *ocap)
+{
+ int have = ci->i_snap_caps;
+ struct ceph_cap *cap;
+ struct rb_node *p;
+
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ cap = rb_entry(p, struct ceph_cap, ci_node);
+ if (cap == ocap)
+ continue;
+ if (!__cap_is_valid(cap))
+ continue;
+ have |= cap->issued;
+ }
+ return have;
+}
+
+/*
+ * Move a cap to the end of the LRU (oldest caps at list head, newest
+ * at list tail).
+ */
+static void __touch_cap(struct ceph_cap *cap)
+{
+ struct ceph_mds_session *s = cap->session;
+
+ spin_lock(&s->s_cap_lock);
+ if (s->s_cap_iterator == NULL) {
+ dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap,
+ s->s_mds);
+ list_move_tail(&cap->session_caps, &s->s_caps);
+ } else {
+ dout("__touch_cap %p cap %p mds%d NOP, iterating over caps\n",
+ &cap->ci->vfs_inode, cap, s->s_mds);
+ }
+ spin_unlock(&s->s_cap_lock);
+}
+
+/*
+ * Check if we hold the given mask. If so, move the cap(s) to the
+ * front of their respective LRUs. (This is the preferred way for
+ * callers to check for caps they want.)
+ */
+int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
+{
+ struct ceph_cap *cap;
+ struct rb_node *p;
+ int have = ci->i_snap_caps;
+
+ if ((have & mask) == mask) {
+ dout("__ceph_caps_issued_mask %p snap issued %s"
+ " (mask %s)\n", &ci->vfs_inode,
+ ceph_cap_string(have),
+ ceph_cap_string(mask));
+ return 1;
+ }
+
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ cap = rb_entry(p, struct ceph_cap, ci_node);
+ if (!__cap_is_valid(cap))
+ continue;
+ if ((cap->issued & mask) == mask) {
+ dout("__ceph_caps_issued_mask %p cap %p issued %s"
+ " (mask %s)\n", &ci->vfs_inode, cap,
+ ceph_cap_string(cap->issued),
+ ceph_cap_string(mask));
+ if (touch)
+ __touch_cap(cap);
+ return 1;
+ }
+
+ /* does a combination of caps satisfy mask? */
+ have |= cap->issued;
+ if ((have & mask) == mask) {
+ dout("__ceph_caps_issued_mask %p combo issued %s"
+ " (mask %s)\n", &ci->vfs_inode,
+ ceph_cap_string(cap->issued),
+ ceph_cap_string(mask));
+ if (touch) {
+ struct rb_node *q;
+
+ /* touch this + preceeding caps */
+ __touch_cap(cap);
+ for (q = rb_first(&ci->i_caps); q != p;
+ q = rb_next(q)) {
+ cap = rb_entry(q, struct ceph_cap,
+ ci_node);
+ if (!__cap_is_valid(cap))
+ continue;
+ __touch_cap(cap);
+ }
+ }
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Return true if mask caps are currently being revoked by an MDS.
+ */
+int ceph_caps_revoking(struct ceph_inode_info *ci, int mask)
+{
+ struct inode *inode = &ci->vfs_inode;
+ struct ceph_cap *cap;
+ struct rb_node *p;
+ int ret = 0;
+
+ spin_lock(&inode->i_lock);
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ cap = rb_entry(p, struct ceph_cap, ci_node);
+ if (__cap_is_valid(cap) &&
+ (cap->implemented & ~cap->issued & mask)) {
+ ret = 1;
+ break;
+ }
+ }
+ spin_unlock(&inode->i_lock);
+ dout("ceph_caps_revoking %p %s = %d\n", inode,
+ ceph_cap_string(mask), ret);
+ return ret;
+}
+
+int __ceph_caps_used(struct ceph_inode_info *ci)
+{
+ int used = 0;
+ if (ci->i_pin_ref)
+ used |= CEPH_CAP_PIN;
+ if (ci->i_rd_ref)
+ used |= CEPH_CAP_FILE_RD;
+ if (ci->i_rdcache_ref || ci->i_rdcache_gen)
+ used |= CEPH_CAP_FILE_CACHE;
+ if (ci->i_wr_ref)
+ used |= CEPH_CAP_FILE_WR;
+ if (ci->i_wrbuffer_ref)
+ used |= CEPH_CAP_FILE_BUFFER;
+ return used;
+}
+
+/*
+ * wanted, by virtue of open file modes
+ */
+int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
+{
+ int want = 0;
+ int mode;
+ for (mode = 0; mode < 4; mode++)
+ if (ci->i_nr_by_mode[mode])
+ want |= ceph_caps_for_mode(mode);
+ return want;
+}
+
+/*
+ * Return caps we have registered with the MDS(s) as 'wanted'.
+ */
+int __ceph_caps_mds_wanted(struct ceph_inode_info *ci)
+{
+ struct ceph_cap *cap;
+ struct rb_node *p;
+ int mds_wanted = 0;
+
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ cap = rb_entry(p, struct ceph_cap, ci_node);
+ if (!__cap_is_valid(cap))
+ continue;
+ mds_wanted |= cap->mds_wanted;
+ }
+ return mds_wanted;
+}
+
+/*
+ * called under i_lock
+ */
+static int __ceph_is_any_caps(struct ceph_inode_info *ci)
+{
+ return !RB_EMPTY_ROOT(&ci->i_caps) || ci->i_cap_exporting_mds >= 0;
+}
+
+/*
+ * caller should hold i_lock.
+ * caller will not hold session s_mutex if called from destroy_inode.
+ */
+void __ceph_remove_cap(struct ceph_cap *cap)
+{
+ struct ceph_mds_session *session = cap->session;
+ struct ceph_inode_info *ci = cap->ci;
+ struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+
+ dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
+
+ /* remove from inode list */
+ rb_erase(&cap->ci_node, &ci->i_caps);
+ cap->ci = NULL;
+ if (ci->i_auth_cap == cap)
+ ci->i_auth_cap = NULL;
+
+ /* remove from session list */
+ spin_lock(&session->s_cap_lock);
+ if (session->s_cap_iterator == cap) {
+ /* not yet, we are iterating over this very cap */
+ dout("__ceph_remove_cap delaying %p removal from session %p\n",
+ cap, cap->session);
+ } else {
+ list_del_init(&cap->session_caps);
+ session->s_nr_caps--;
+ cap->session = NULL;
+ }
+ spin_unlock(&session->s_cap_lock);
+
+ if (cap->session == NULL)
+ ceph_put_cap(cap);
+
+ if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) {
+ struct ceph_snap_realm *realm = ci->i_snap_realm;
+ spin_lock(&realm->inodes_with_caps_lock);
+ list_del_init(&ci->i_snap_realm_item);
+ ci->i_snap_realm_counter++;
+ ci->i_snap_realm = NULL;
+ spin_unlock(&realm->inodes_with_caps_lock);
+ ceph_put_snap_realm(mdsc, realm);
+ }
+ if (!__ceph_is_any_real_caps(ci))
+ __cap_delay_cancel(mdsc, ci);
+}
+
+/*
+ * Build and send a cap message to the given MDS.
+ *
+ * Caller should be holding s_mutex.
+ */
+static int send_cap_msg(struct ceph_mds_session *session,
+ u64 ino, u64 cid, int op,
+ int caps, int wanted, int dirty,
+ u32 seq, u64 flush_tid, u32 issue_seq, u32 mseq,
+ u64 size, u64 max_size,
+ struct timespec *mtime, struct timespec *atime,
+ u64 time_warp_seq,
+ uid_t uid, gid_t gid, mode_t mode,
+ u64 xattr_version,
+ struct ceph_buffer *xattrs_buf,
+ u64 follows)
+{
+ struct ceph_mds_caps *fc;
+ struct ceph_msg *msg;
+
+ dout("send_cap_msg %s %llx %llx caps %s wanted %s dirty %s"
+ " seq %u/%u mseq %u follows %lld size %llu/%llu"
+ " xattr_ver %llu xattr_len %d\n", ceph_cap_op_name(op),
+ cid, ino, ceph_cap_string(caps), ceph_cap_string(wanted),
+ ceph_cap_string(dirty),
+ seq, issue_seq, mseq, follows, size, max_size,
+ xattr_version, xattrs_buf ? (int)xattrs_buf->vec.iov_len : 0);
+
+ msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), 0, 0, NULL);
+ if (IS_ERR(msg))
+ return PTR_ERR(msg);
+
+ msg->hdr.tid = cpu_to_le64(flush_tid);
+
+ fc = msg->front.iov_base;
+ memset(fc, 0, sizeof(*fc));
+
+ fc->cap_id = cpu_to_le64(cid);
+ fc->op = cpu_to_le32(op);
+ fc->seq = cpu_to_le32(seq);
+ fc->issue_seq = cpu_to_le32(issue_seq);
+ fc->migrate_seq = cpu_to_le32(mseq);
+ fc->caps = cpu_to_le32(caps);
+ fc->wanted = cpu_to_le32(wanted);
+ fc->dirty = cpu_to_le32(dirty);
+ fc->ino = cpu_to_le64(ino);
+ fc->snap_follows = cpu_to_le64(follows);
+
+ fc->size = cpu_to_le64(size);
+ fc->max_size = cpu_to_le64(max_size);
+ if (mtime)
+ ceph_encode_timespec(&fc->mtime, mtime);
+ if (atime)
+ ceph_encode_timespec(&fc->atime, atime);
+ fc->time_warp_seq = cpu_to_le32(time_warp_seq);
+
+ fc->uid = cpu_to_le32(uid);
+ fc->gid = cpu_to_le32(gid);
+ fc->mode = cpu_to_le32(mode);
+
+ fc->xattr_version = cpu_to_le64(xattr_version);
+ if (xattrs_buf) {
+ msg->middle = ceph_buffer_get(xattrs_buf);
+ fc->xattr_len = cpu_to_le32(xattrs_buf->vec.iov_len);
+ msg->hdr.middle_len = cpu_to_le32(xattrs_buf->vec.iov_len);
+ }
+
+ ceph_con_send(&session->s_con, msg);
+ return 0;
+}
+
+/*
+ * Queue cap releases when an inode is dropped from our cache. Since
+ * inode is about to be destroyed, there is no need for i_lock.
+ */
+void ceph_queue_caps_release(struct inode *inode)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct rb_node *p;
+
+ p = rb_first(&ci->i_caps);
+ while (p) {
+ struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node);
+ struct ceph_mds_session *session = cap->session;
+ struct ceph_msg *msg;
+ struct ceph_mds_cap_release *head;
+ struct ceph_mds_cap_item *item;
+
+ spin_lock(&session->s_cap_lock);
+ BUG_ON(!session->s_num_cap_releases);
+ msg = list_first_entry(&session->s_cap_releases,
+ struct ceph_msg, list_head);
+
+ dout(" adding %p release to mds%d msg %p (%d left)\n",
+ inode, session->s_mds, msg, session->s_num_cap_releases);
+
+ BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE);
+ head = msg->front.iov_base;
+ head->num = cpu_to_le32(le32_to_cpu(head->num) + 1);
+ item = msg->front.iov_base + msg->front.iov_len;
+ item->ino = cpu_to_le64(ceph_ino(inode));
+ item->cap_id = cpu_to_le64(cap->cap_id);
+ item->migrate_seq = cpu_to_le32(cap->mseq);
+ item->seq = cpu_to_le32(cap->issue_seq);
+
+ session->s_num_cap_releases--;
+
+ msg->front.iov_len += sizeof(*item);
+ if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) {
+ dout(" release msg %p full\n", msg);
+ list_move_tail(&msg->list_head,
+ &session->s_cap_releases_done);
+ } else {
+ dout(" release msg %p at %d/%d (%d)\n", msg,
+ (int)le32_to_cpu(head->num),
+ (int)CEPH_CAPS_PER_RELEASE,
+ (int)msg->front.iov_len);
+ }
+ spin_unlock(&session->s_cap_lock);
+ p = rb_next(p);
+ __ceph_remove_cap(cap);
+ }
+}
+
+/*
+ * Send a cap msg on the given inode. Update our caps state, then
+ * drop i_lock and send the message.
+ *
+ * Make note of max_size reported/requested from mds, revoked caps
+ * that have now been implemented.
+ *
+ * Make half-hearted attempt ot to invalidate page cache if we are
+ * dropping RDCACHE. Note that this will leave behind locked pages
+ * that we'll then need to deal with elsewhere.
+ *
+ * Return non-zero if delayed release, or we experienced an error
+ * such that the caller should requeue + retry later.
+ *
+ * called with i_lock, then drops it.
+ * caller should hold snap_rwsem (read), s_mutex.
+ */
+static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
+ int op, int used, int want, int retain, int flushing,
+ unsigned *pflush_tid)
+ __releases(cap->ci->vfs_inode->i_lock)
+{
+ struct ceph_inode_info *ci = cap->ci;
+ struct inode *inode = &ci->vfs_inode;
+ u64 cap_id = cap->cap_id;
+ int held, revoking, dropping, keep;
+ u64 seq, issue_seq, mseq, time_warp_seq, follows;
+ u64 size, max_size;
+ struct timespec mtime, atime;
+ int wake = 0;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+ struct ceph_mds_session *session;
+ u64 xattr_version = 0;
+ int delayed = 0;
+ u64 flush_tid = 0;
+ int i;
+ int ret;
+
+ held = cap->issued | cap->implemented;
+ revoking = cap->implemented & ~cap->issued;
+ retain &= ~revoking;
+ dropping = cap->issued & ~retain;
+
+ dout("__send_cap %p cap %p session %p %s -> %s (revoking %s)\n",
+ inode, cap, cap->session,
+ ceph_cap_string(held), ceph_cap_string(held & retain),
+ ceph_cap_string(revoking));
+ BUG_ON((retain & CEPH_CAP_PIN) == 0);
+
+ session = cap->session;
+
+ /* don't release wanted unless we've waited a bit. */
+ if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0 &&
+ time_before(jiffies, ci->i_hold_caps_min)) {
+ dout(" delaying issued %s -> %s, wanted %s -> %s on send\n",
+ ceph_cap_string(cap->issued),
+ ceph_cap_string(cap->issued & retain),
+ ceph_cap_string(cap->mds_wanted),
+ ceph_cap_string(want));
+ want |= cap->mds_wanted;
+ retain |= cap->issued;
+ delayed = 1;
+ }
+ ci->i_ceph_flags &= ~(CEPH_I_NODELAY | CEPH_I_FLUSH);
+
+ cap->issued &= retain; /* drop bits we don't want */
+ if (cap->implemented & ~cap->issued) {
+ /*
+ * Wake up any waiters on wanted -> needed transition.
+ * This is due to the weird transition from buffered
+ * to sync IO... we need to flush dirty pages _before_
+ * allowing sync writes to avoid reordering.
+ */
+ wake = 1;
+ }
+ cap->implemented &= cap->issued | used;
+ cap->mds_wanted = want;
+
+ if (flushing) {
+ /*
+ * assign a tid for flush operations so we can avoid
+ * flush1 -> dirty1 -> flush2 -> flushack1 -> mark
+ * clean type races. track latest tid for every bit
+ * so we can handle flush AxFw, flush Fw, and have the
+ * first ack clean Ax.
+ */
+ flush_tid = ++ci->i_cap_flush_last_tid;
+ if (pflush_tid)
+ *pflush_tid = flush_tid;
+ dout(" cap_flush_tid %d\n", (int)flush_tid);
+ for (i = 0; i < CEPH_CAP_BITS; i++)
+ if (flushing & (1 << i))
+ ci->i_cap_flush_tid[i] = flush_tid;
+ }
+
+ keep = cap->implemented;
+ seq = cap->seq;
+ issue_seq = cap->issue_seq;
+ mseq = cap->mseq;
+ size = inode->i_size;
+ ci->i_reported_size = size;
+ max_size = ci->i_wanted_max_size;
+ ci->i_requested_max_size = max_size;
+ mtime = inode->i_mtime;
+ atime = inode->i_atime;
+ time_warp_seq = ci->i_time_warp_seq;
+ follows = ci->i_snap_realm->cached_context->seq;
+ uid = inode->i_uid;
+ gid = inode->i_gid;
+ mode = inode->i_mode;
+
+ if (dropping & CEPH_CAP_XATTR_EXCL) {
+ __ceph_build_xattrs_blob(ci);
+ xattr_version = ci->i_xattrs.version + 1;
+ }
+
+ spin_unlock(&inode->i_lock);
+
+ ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id,
+ op, keep, want, flushing, seq, flush_tid, issue_seq, mseq,
+ size, max_size, &mtime, &atime, time_warp_seq,
+ uid, gid, mode,
+ xattr_version,
+ (flushing & CEPH_CAP_XATTR_EXCL) ? ci->i_xattrs.blob : NULL,
+ follows);
+ if (ret < 0) {
+ dout("error sending cap msg, must requeue %p\n", inode);
+ delayed = 1;
+ }
+
+ if (wake)
+ wake_up(&ci->i_cap_wq);
+
+ return delayed;
+}
+
+/*
+ * When a snapshot is taken, clients accumulate dirty metadata on
+ * inodes with capabilities in ceph_cap_snaps to describe the file
+ * state at the time the snapshot was taken. This must be flushed
+ * asynchronously back to the MDS once sync writes complete and dirty
+ * data is written out.
+ *
+ * Called under i_lock. Takes s_mutex as needed.
+ */
+void __ceph_flush_snaps(struct ceph_inode_info *ci,
+ struct ceph_mds_session **psession)
+{
+ struct inode *inode = &ci->vfs_inode;
+ int mds;
+ struct ceph_cap_snap *capsnap;
+ u32 mseq;
+ struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+ struct ceph_mds_session *session = NULL; /* if session != NULL, we hold
+ session->s_mutex */
+ u64 next_follows = 0; /* keep track of how far we've gotten through the
+ i_cap_snaps list, and skip these entries next time
+ around to avoid an infinite loop */
+
+ if (psession)
+ session = *psession;
+
+ dout("__flush_snaps %p\n", inode);
+retry:
+ list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+ /* avoid an infiniute loop after retry */
+ if (capsnap->follows < next_follows)
+ continue;
+ /*
+ * we need to wait for sync writes to complete and for dirty
+ * pages to be written out.
+ */
+ if (capsnap->dirty_pages || capsnap->writing)
+ continue;
+
+ /*
+ * if cap writeback already occurred, we should have dropped
+ * the capsnap in ceph_put_wrbuffer_cap_refs.
+ */
+ BUG_ON(capsnap->dirty == 0);
+
+ /* pick mds, take s_mutex */
+ mds = __ceph_get_cap_mds(ci, &mseq);
+ if (session && session->s_mds != mds) {
+ dout("oops, wrong session %p mutex\n", session);
+ mutex_unlock(&session->s_mutex);
+ ceph_put_mds_session(session);
+ session = NULL;
+ }
+ if (!session) {
+ spin_unlock(&inode->i_lock);
+ mutex_lock(&mdsc->mutex);
+ session = __ceph_lookup_mds_session(mdsc, mds);
+ mutex_unlock(&mdsc->mutex);
+ if (session) {
+ dout("inverting session/ino locks on %p\n",
+ session);
+ mutex_lock(&session->s_mutex);
+ }
+ /*
+ * if session == NULL, we raced against a cap
+ * deletion. retry, and we'll get a better
+ * @mds value next time.
+ */
+ spin_lock(&inode->i_lock);
+ goto retry;
+ }
+
+ capsnap->flush_tid = ++ci->i_cap_flush_last_tid;
+ atomic_inc(&capsnap->nref);
+ if (!list_empty(&capsnap->flushing_item))
+ list_del_init(&capsnap->flushing_item);
+ list_add_tail(&capsnap->flushing_item,
+ &session->s_cap_snaps_flushing);
+ spin_unlock(&inode->i_lock);
+
+ dout("flush_snaps %p cap_snap %p follows %lld size %llu\n",
+ inode, capsnap, next_follows, capsnap->size);
+ send_cap_msg(session, ceph_vino(inode).ino, 0,
+ CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0,
+ capsnap->dirty, 0, capsnap->flush_tid, 0, mseq,
+ capsnap->size, 0,
+ &capsnap->mtime, &capsnap->atime,
+ capsnap->time_warp_seq,
+ capsnap->uid, capsnap->gid, capsnap->mode,
+ 0, NULL,
+ capsnap->follows);
+
+ next_follows = capsnap->follows + 1;
+ ceph_put_cap_snap(capsnap);
+
+ spin_lock(&inode->i_lock);
+ goto retry;
+ }
+
+ /* we flushed them all; remove this inode from the queue */
+ spin_lock(&mdsc->snap_flush_lock);
+ list_del_init(&ci->i_snap_flush_item);
+ spin_unlock(&mdsc->snap_flush_lock);
+
+ if (psession)
+ *psession = session;
+ else if (session) {
+ mutex_unlock(&session->s_mutex);
+ ceph_put_mds_session(session);
+ }
+}
+
+static void ceph_flush_snaps(struct ceph_inode_info *ci)
+{
+ struct inode *inode = &ci->vfs_inode;
+
+ spin_lock(&inode->i_lock);
+ __ceph_flush_snaps(ci, NULL);
+ spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Mark caps dirty. If inode is newly dirty, add to the global dirty
+ * list.
+ */
+void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
+{
+ struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+ struct inode *inode = &ci->vfs_inode;
+ int was = ci->i_dirty_caps;
+ int dirty = 0;
+
+ dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode,
+ ceph_cap_string(mask), ceph_cap_string(was),
+ ceph_cap_string(was | mask));
+ ci->i_dirty_caps |= mask;
+ if (was == 0) {
+ dout(" inode %p now dirty\n", &ci->vfs_inode);
+ BUG_ON(!list_empty(&ci->i_dirty_item));
+ spin_lock(&mdsc->cap_dirty_lock);
+ list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
+ spin_unlock(&mdsc->cap_dirty_lock);
+ if (ci->i_flushing_caps == 0) {
+ igrab(inode);
+ dirty |= I_DIRTY_SYNC;
+ }
+ }
+ BUG_ON(list_empty(&ci->i_dirty_item));
+ if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
+ (mask & CEPH_CAP_FILE_BUFFER))
+ dirty |= I_DIRTY_DATASYNC;
+ if (dirty)
+ __mark_inode_dirty(inode, dirty);
+ __cap_delay_requeue(mdsc, ci);
+}
+
+/*
+ * 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.
+ */
+static int __mark_caps_flushing(struct inode *inode,
+ struct ceph_mds_session *session)
+{
+ struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int flushing;
+
+ BUG_ON(ci->i_dirty_caps == 0);
+ BUG_ON(list_empty(&ci->i_dirty_item));
+
+ flushing = ci->i_dirty_caps;
+ dout("__mark_caps_flushing flushing %s, flushing_caps %s -> %s\n",
+ ceph_cap_string(flushing),
+ ceph_cap_string(ci->i_flushing_caps),
+ ceph_cap_string(ci->i_flushing_caps | flushing));
+ ci->i_flushing_caps |= flushing;
+ ci->i_dirty_caps = 0;
+ dout(" inode %p now !dirty\n", inode);
+
+ spin_lock(&mdsc->cap_dirty_lock);
+ list_del_init(&ci->i_dirty_item);
+
+ ci->i_cap_flush_seq = ++mdsc->cap_flush_seq;
+ if (list_empty(&ci->i_flushing_item)) {
+ list_add_tail(&ci->i_flushing_item, &session->s_cap_flushing);
+ mdsc->num_cap_flushing++;
+ dout(" inode %p now flushing seq %lld\n", inode,
+ ci->i_cap_flush_seq);
+ } else {
+ list_move_tail(&ci->i_flushing_item, &session->s_cap_flushing);
+ dout(" inode %p now flushing (more) seq %lld\n", inode,
+ ci->i_cap_flush_seq);
+ }
+ spin_unlock(&mdsc->cap_dirty_lock);
+
+ return flushing;
+}
+
+/*
+ * try to invalidate mapping pages without blocking.
+ */
+static int mapping_is_empty(struct address_space *mapping)
+{
+ struct page *page = find_get_page(mapping, 0);
+
+ if (!page)
+ return 1;
+
+ put_page(page);
+ return 0;
+}
+
+static int try_nonblocking_invalidate(struct inode *inode)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ u32 invalidating_gen = ci->i_rdcache_gen;
+
+ spin_unlock(&inode->i_lock);
+ invalidate_mapping_pages(&inode->i_data, 0, -1);
+ spin_lock(&inode->i_lock);
+
+ if (mapping_is_empty(&inode->i_data) &&
+ invalidating_gen == ci->i_rdcache_gen) {
+ /* success. */
+ dout("try_nonblocking_invalidate %p success\n", inode);
+ ci->i_rdcache_gen = 0;
+ ci->i_rdcache_revoking = 0;
+ return 0;
+ }
+ dout("try_nonblocking_invalidate %p failed\n", inode);
+ return -1;
+}
+
+/*
+ * Swiss army knife function to examine currently used and wanted
+ * versus held caps. Release, flush, ack revoked caps to mds as
+ * appropriate.
+ *
+ * CHECK_CAPS_NODELAY - caller is delayed work and we should not delay
+ * cap release further.
+ * CHECK_CAPS_AUTHONLY - we should only check the auth cap
+ * CHECK_CAPS_FLUSH - we should flush any dirty caps immediately, without
+ * further delay.
+ */
+void ceph_check_caps(struct ceph_inode_info *ci, int flags,
+ struct ceph_mds_session *session)
+ __releases(session->s_mutex)
+{
+ struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct inode *inode = &ci->vfs_inode;
+ struct ceph_cap *cap;
+ int file_wanted, used;
+ int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */
+ int issued, implemented, want, retain, revoking, flushing = 0;
+ int mds = -1; /* keep track of how far we've gone through i_caps list
+ to avoid an infinite loop on retry */
+ struct rb_node *p;
+ int tried_invalidate = 0;
+ int delayed = 0, sent = 0, force_requeue = 0, num;
+ int queue_invalidate = 0;
+ int is_delayed = flags & CHECK_CAPS_NODELAY;
+
+ /* if we are unmounting, flush any unused caps immediately. */
+ if (mdsc->stopping)
+ is_delayed = 1;
+
+ spin_lock(&inode->i_lock);
+
+ if (ci->i_ceph_flags & CEPH_I_FLUSH)
+ flags |= CHECK_CAPS_FLUSH;
+
+ /* flush snaps first time around only */
+ if (!list_empty(&ci->i_cap_snaps))
+ __ceph_flush_snaps(ci, &session);
+ goto retry_locked;
+retry:
+ spin_lock(&inode->i_lock);
+retry_locked:
+ file_wanted = __ceph_caps_file_wanted(ci);
+ used = __ceph_caps_used(ci);
+ want = file_wanted | used;
+ issued = __ceph_caps_issued(ci, &implemented);
+ revoking = implemented & ~issued;
+
+ retain = want | CEPH_CAP_PIN;
+ if (!mdsc->stopping && inode->i_nlink > 0) {
+ if (want) {
+ retain |= CEPH_CAP_ANY; /* be greedy */
+ } else {
+ retain |= CEPH_CAP_ANY_SHARED;
+ /*
+ * keep RD only if we didn't have the file open RW,
+ * because then the mds would revoke it anyway to
+ * journal max_size=0.
+ */
+ if (ci->i_max_size == 0)
+ retain |= CEPH_CAP_ANY_RD;
+ }
+ }
+
+ dout("check_caps %p file_want %s used %s dirty %s flushing %s"
+ " issued %s revoking %s retain %s %s%s%s\n", inode,
+ ceph_cap_string(file_wanted),
+ ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps),
+ ceph_cap_string(ci->i_flushing_caps),
+ ceph_cap_string(issued), ceph_cap_string(revoking),
+ ceph_cap_string(retain),
+ (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "",
+ (flags & CHECK_CAPS_NODELAY) ? " NODELAY" : "",
+ (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : "");
+
+ /*
+ * If we no longer need to hold onto old our caps, and we may
+ * have cached pages, but don't want them, then try to invalidate.
+ * If we fail, it's because pages are locked.... try again later.
+ */
+ if ((!is_delayed || mdsc->stopping) &&
+ 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 */
+ !tried_invalidate) {
+ dout("check_caps trying to invalidate on %p\n", inode);
+ if (try_nonblocking_invalidate(inode) < 0) {
+ if (revoking & CEPH_CAP_FILE_CACHE) {
+ dout("check_caps queuing invalidate\n");
+ queue_invalidate = 1;
+ ci->i_rdcache_revoking = ci->i_rdcache_gen;
+ } else {
+ dout("check_caps failed to invalidate pages\n");
+ /* we failed to invalidate pages. check these
+ caps again later. */
+ force_requeue = 1;
+ __cap_set_timeouts(mdsc, ci);
+ }
+ }
+ tried_invalidate = 1;
+ goto retry_locked;
+ }
+
+ num = 0;
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ cap = rb_entry(p, struct ceph_cap, ci_node);
+ num++;
+
+ /* avoid looping forever */
+ if (mds >= cap->mds ||
+ ((flags & CHECK_CAPS_AUTHONLY) && cap != ci->i_auth_cap))
+ continue;
+
+ /* NOTE: no side-effects allowed, until we take s_mutex */
+
+ revoking = cap->implemented & ~cap->issued;
+ if (revoking)
+ dout(" mds%d revoking %s\n", cap->mds,
+ ceph_cap_string(revoking));
+
+ if (cap == ci->i_auth_cap &&
+ (cap->issued & CEPH_CAP_FILE_WR)) {
+ /* request larger max_size from MDS? */
+ if (ci->i_wanted_max_size > ci->i_max_size &&
+ ci->i_wanted_max_size > ci->i_requested_max_size) {
+ dout("requesting new max_size\n");
+ goto ack;
+ }
+
+ /* approaching file_max? */
+ if ((inode->i_size << 1) >= ci->i_max_size &&
+ (ci->i_reported_size << 1) < ci->i_max_size) {
+ dout("i_size approaching max_size\n");
+ goto ack;
+ }
+ }
+ /* flush anything dirty? */
+ if (cap == ci->i_auth_cap && (flags & CHECK_CAPS_FLUSH) &&
+ ci->i_dirty_caps) {
+ dout("flushing dirty caps\n");
+ goto ack;
+ }
+
+ /* completed revocation? going down and there are no caps? */
+ if (revoking && (revoking & used) == 0) {
+ dout("completed revocation of %s\n",
+ ceph_cap_string(cap->implemented & ~cap->issued));
+ goto ack;
+ }
+
+ /* want more caps from mds? */
+ if (want & ~(cap->mds_wanted | cap->issued))
+ goto ack;
+
+ /* things we might delay */
+ if ((cap->issued & ~retain) == 0 &&
+ cap->mds_wanted == want)
+ continue; /* nope, all good */
+
+ if (is_delayed)
+ goto ack;
+
+ /* delay? */
+ if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0 &&
+ time_before(jiffies, ci->i_hold_caps_max)) {
+ dout(" delaying issued %s -> %s, wanted %s -> %s\n",
+ ceph_cap_string(cap->issued),
+ ceph_cap_string(cap->issued & retain),
+ ceph_cap_string(cap->mds_wanted),
+ ceph_cap_string(want));
+ delayed++;
+ continue;
+ }
+
+ack:
+ if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
+ dout(" skipping %p I_NOFLUSH set\n", inode);
+ continue;
+ }
+
+ if (session && session != cap->session) {
+ dout("oops, wrong session %p mutex\n", session);
+ mutex_unlock(&session->s_mutex);
+ session = NULL;
+ }
+ if (!session) {
+ session = cap->session;
+ if (mutex_trylock(&session->s_mutex) == 0) {
+ dout("inverting session/ino locks on %p\n",
+ session);
+ spin_unlock(&inode->i_lock);
+ if (took_snap_rwsem) {
+ up_read(&mdsc->snap_rwsem);
+ took_snap_rwsem = 0;
+ }
+ mutex_lock(&session->s_mutex);
+ goto retry;
+ }
+ }
+ /* take snap_rwsem after session mutex */
+ if (!took_snap_rwsem) {
+ if (down_read_trylock(&mdsc->snap_rwsem) == 0) {
+ dout("inverting snap/in locks on %p\n",
+ inode);
+ spin_unlock(&inode->i_lock);
+ down_read(&mdsc->snap_rwsem);
+ took_snap_rwsem = 1;
+ goto retry;
+ }
+ took_snap_rwsem = 1;
+ }
+
+ if (cap == ci->i_auth_cap && ci->i_dirty_caps)
+ flushing = __mark_caps_flushing(inode, session);
+
+ mds = cap->mds; /* remember mds, so we don't repeat */
+ sent++;
+
+ /* __send_cap drops i_lock */
+ delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want,
+ retain, flushing, NULL);
+ goto retry; /* retake i_lock and restart our cap scan. */
+ }
+
+ /*
+ * Reschedule delayed caps release if we delayed anything,
+ * otherwise cancel.
+ */
+ if (delayed && is_delayed)
+ force_requeue = 1; /* __send_cap delayed release; requeue */
+ if (!delayed && !is_delayed)
+ __cap_delay_cancel(mdsc, ci);
+ else if (!is_delayed || force_requeue)
+ __cap_delay_requeue(mdsc, ci);
+
+ spin_unlock(&inode->i_lock);
+
+ if (queue_invalidate)
+ ceph_queue_invalidate(inode);
+
+ if (session)
+ mutex_unlock(&session->s_mutex);
+ if (took_snap_rwsem)
+ up_read(&mdsc->snap_rwsem);
+}
+
+/*
+ * Try to flush dirty caps back to the auth mds.
+ */
+static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session,
+ unsigned *flush_tid)
+{
+ struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int unlock_session = session ? 0 : 1;
+ int flushing = 0;
+
+retry:
+ spin_lock(&inode->i_lock);
+ if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
+ dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode);
+ goto out;
+ }
+ if (ci->i_dirty_caps && ci->i_auth_cap) {
+ struct ceph_cap *cap = ci->i_auth_cap;
+ int used = __ceph_caps_used(ci);
+ int want = __ceph_caps_wanted(ci);
+ int delayed;
+
+ if (!session) {
+ spin_unlock(&inode->i_lock);
+ session = cap->session;
+ mutex_lock(&session->s_mutex);
+ goto retry;
+ }
+ BUG_ON(session != cap->session);
+ if (cap->session->s_state < CEPH_MDS_SESSION_OPEN)
+ goto out;
+
+ flushing = __mark_caps_flushing(inode, session);
+
+ /* __send_cap drops i_lock */
+ delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, used, want,
+ cap->issued | cap->implemented, flushing,
+ flush_tid);
+ if (!delayed)
+ goto out_unlocked;
+
+ spin_lock(&inode->i_lock);
+ __cap_delay_requeue(mdsc, ci);
+ }
+out:
+ spin_unlock(&inode->i_lock);
+out_unlocked:
+ if (session && unlock_session)
+ mutex_unlock(&session->s_mutex);
+ return flushing;
+}
+
+/*
+ * Return true if we've flushed caps through the given flush_tid.
+ */
+static int caps_are_flushed(struct inode *inode, unsigned tid)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int dirty, i, ret = 1;
+
+ spin_lock(&inode->i_lock);
+ dirty = __ceph_caps_dirty(ci);
+ for (i = 0; i < CEPH_CAP_BITS; i++)
+ if ((ci->i_flushing_caps & (1 << i)) &&
+ ci->i_cap_flush_tid[i] <= tid) {
+ /* still flushing this bit */
+ ret = 0;
+ break;
+ }
+ spin_unlock(&inode->i_lock);
+ return ret;
+}
+
+/*
+ * Wait on any unsafe replies for the given inode. First wait on the
+ * newest request, and make that the upper bound. Then, if there are
+ * more requests, keep waiting on the oldest as long as it is still older
+ * than the original request.
+ */
+static void sync_write_wait(struct inode *inode)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct list_head *head = &ci->i_unsafe_writes;
+ struct ceph_osd_request *req;
+ u64 last_tid;
+
+ spin_lock(&ci->i_unsafe_lock);
+ if (list_empty(head))
+ goto out;
+
+ /* set upper bound as _last_ entry in chain */
+ req = list_entry(head->prev, struct ceph_osd_request,
+ r_unsafe_item);
+ last_tid = req->r_tid;
+
+ do {
+ ceph_osdc_get_request(req);
+ spin_unlock(&ci->i_unsafe_lock);
+ dout("sync_write_wait on tid %llu (until %llu)\n",
+ req->r_tid, last_tid);
+ wait_for_completion(&req->r_safe_completion);
+ spin_lock(&ci->i_unsafe_lock);
+ ceph_osdc_put_request(req);
+
+ /*
+ * from here on look at first entry in chain, since we
+ * only want to wait for anything older than last_tid
+ */
+ if (list_empty(head))
+ break;
+ req = list_entry(head->next, struct ceph_osd_request,
+ r_unsafe_item);
+ } while (req->r_tid < last_tid);
+out:
+ spin_unlock(&ci->i_unsafe_lock);
+}
+
+int ceph_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ unsigned flush_tid;
+ int ret;
+ int dirty;
+
+ dout("fsync %p%s\n", inode, datasync ? " datasync" : "");
+ sync_write_wait(inode);
+
+ ret = filemap_write_and_wait(inode->i_mapping);
+ if (ret < 0)
+ return ret;
+
+ dirty = try_flush_caps(inode, NULL, &flush_tid);
+ dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));
+
+ /*
+ * only wait on non-file metadata writeback (the mds
+ * can recover size and mtime, so we don't need to
+ * wait for that)
+ */
+ if (!datasync && (dirty & ~CEPH_CAP_ANY_FILE_WR)) {
+ dout("fsync waiting for flush_tid %u\n", flush_tid);
+ ret = wait_event_interruptible(ci->i_cap_wq,
+ caps_are_flushed(inode, flush_tid));
+ }
+
+ dout("fsync %p%s done\n", inode, datasync ? " datasync" : "");
+ return ret;
+}
+
+/*
+ * Flush any dirty caps back to the mds. If we aren't asked to wait,
+ * queue inode for flush but don't do so immediately, because we can
+ * get by with fewer MDS messages if we wait for data writeback to
+ * complete first.
+ */
+int ceph_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ unsigned flush_tid;
+ int err = 0;
+ int dirty;
+ int wait = wbc->sync_mode == WB_SYNC_ALL;
+
+ dout("write_inode %p wait=%d\n", inode, wait);
+ if (wait) {
+ dirty = try_flush_caps(inode, NULL, &flush_tid);
+ if (dirty)
+ err = wait_event_interruptible(ci->i_cap_wq,
+ caps_are_flushed(inode, flush_tid));
+ } else {
+ struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+
+ spin_lock(&inode->i_lock);
+ if (__ceph_caps_dirty(ci))
+ __cap_delay_requeue_front(mdsc, ci);
+ spin_unlock(&inode->i_lock);
+ }
+ return err;
+}
+
+/*
+ * After a recovering MDS goes active, we need to resend any caps
+ * we were flushing.
+ *
+ * Caller holds session->s_mutex.
+ */
+static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session)
+{
+ struct ceph_cap_snap *capsnap;
+
+ dout("kick_flushing_capsnaps mds%d\n", session->s_mds);
+ list_for_each_entry(capsnap, &session->s_cap_snaps_flushing,
+ flushing_item) {
+ struct ceph_inode_info *ci = capsnap->ci;
+ struct inode *inode = &ci->vfs_inode;
+ struct ceph_cap *cap;
+
+ spin_lock(&inode->i_lock);
+ cap = ci->i_auth_cap;
+ if (cap && cap->session == session) {
+ dout("kick_flushing_caps %p cap %p capsnap %p\n", inode,
+ cap, capsnap);
+ __ceph_flush_snaps(ci, &session);
+ } else {
+ pr_err("%p auth cap %p not mds%d ???\n", inode,
+ cap, session->s_mds);
+ spin_unlock(&inode->i_lock);
+ }
+ }
+}
+
+void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session)
+{
+ struct ceph_inode_info *ci;
+
+ kick_flushing_capsnaps(mdsc, session);
+
+ dout("kick_flushing_caps mds%d\n", session->s_mds);
+ list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) {
+ struct inode *inode = &ci->vfs_inode;
+ struct ceph_cap *cap;
+ int delayed = 0;
+
+ spin_lock(&inode->i_lock);
+ cap = ci->i_auth_cap;
+ if (cap && cap->session == session) {
+ dout("kick_flushing_caps %p cap %p %s\n", inode,
+ cap, ceph_cap_string(ci->i_flushing_caps));
+ delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH,
+ __ceph_caps_used(ci),
+ __ceph_caps_wanted(ci),
+ cap->issued | cap->implemented,
+ ci->i_flushing_caps, NULL);
+ if (delayed) {
+ spin_lock(&inode->i_lock);
+ __cap_delay_requeue(mdsc, ci);
+ spin_unlock(&inode->i_lock);
+ }
+ } else {
+ pr_err("%p auth cap %p not mds%d ???\n", inode,
+ cap, session->s_mds);
+ spin_unlock(&inode->i_lock);
+ }
+ }
+}
+
+
+/*
+ * Take references to capabilities we hold, so that we don't release
+ * them to the MDS prematurely.
+ *
+ * Protected by i_lock.
+ */
+static void __take_cap_refs(struct ceph_inode_info *ci, int got)
+{
+ if (got & CEPH_CAP_PIN)
+ ci->i_pin_ref++;
+ if (got & CEPH_CAP_FILE_RD)
+ ci->i_rd_ref++;
+ if (got & CEPH_CAP_FILE_CACHE)
+ ci->i_rdcache_ref++;
+ if (got & CEPH_CAP_FILE_WR)
+ ci->i_wr_ref++;
+ if (got & CEPH_CAP_FILE_BUFFER) {
+ if (ci->i_wrbuffer_ref == 0)
+ igrab(&ci->vfs_inode);
+ ci->i_wrbuffer_ref++;
+ dout("__take_cap_refs %p wrbuffer %d -> %d (?)\n",
+ &ci->vfs_inode, ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref);
+ }
+}
+
+/*
+ * Try to grab cap references. Specify those refs we @want, and the
+ * minimal set we @need. Also include the larger offset we are writing
+ * to (when applicable), and check against max_size here as well.
+ * Note that caller is responsible for ensuring max_size increases are
+ * requested from the MDS.
+ */
+static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
+ int *got, loff_t endoff, int *check_max, int *err)
+{
+ struct inode *inode = &ci->vfs_inode;
+ int ret = 0;
+ int have, implemented;
+ int file_wanted;
+
+ dout("get_cap_refs %p need %s want %s\n", inode,
+ ceph_cap_string(need), ceph_cap_string(want));
+ spin_lock(&inode->i_lock);
+
+ /* make sure file is actually open */
+ file_wanted = __ceph_caps_file_wanted(ci);
+ if ((file_wanted & need) == 0) {
+ dout("try_get_cap_refs need %s file_wanted %s, EBADF\n",
+ ceph_cap_string(need), ceph_cap_string(file_wanted));
+ *err = -EBADF;
+ ret = 1;
+ goto out;
+ }
+
+ if (need & CEPH_CAP_FILE_WR) {
+ if (endoff >= 0 && endoff > (loff_t)ci->i_max_size) {
+ dout("get_cap_refs %p endoff %llu > maxsize %llu\n",
+ inode, endoff, ci->i_max_size);
+ if (endoff > ci->i_wanted_max_size) {
+ *check_max = 1;
+ ret = 1;
+ }
+ goto out;
+ }
+ /*
+ * If a sync write is in progress, we must wait, so that we
+ * can get a final snapshot value for size+mtime.
+ */
+ if (__ceph_have_pending_cap_snap(ci)) {
+ dout("get_cap_refs %p cap_snap_pending\n", inode);
+ goto out;
+ }
+ }
+ have = __ceph_caps_issued(ci, &implemented);
+
+ /*
+ * disallow writes while a truncate is pending
+ */
+ if (ci->i_truncate_pending)
+ have &= ~CEPH_CAP_FILE_WR;
+
+ if ((have & need) == need) {
+ /*
+ * Look at (implemented & ~have & not) so that we keep waiting
+ * on transition from wanted -> needed caps. This is needed
+ * for WRBUFFER|WR -> WR to avoid a new WR sync write from
+ * going before a prior buffered writeback happens.
+ */
+ int not = want & ~(have & need);
+ int revoking = implemented & ~have;
+ dout("get_cap_refs %p have %s but not %s (revoking %s)\n",
+ inode, ceph_cap_string(have), ceph_cap_string(not),
+ ceph_cap_string(revoking));
+ if ((revoking & not) == 0) {
+ *got = need | (have & want);
+ __take_cap_refs(ci, *got);
+ ret = 1;
+ }
+ } else {
+ dout("get_cap_refs %p have %s needed %s\n", inode,
+ ceph_cap_string(have), ceph_cap_string(need));
+ }
+out:
+ spin_unlock(&inode->i_lock);
+ dout("get_cap_refs %p ret %d got %s\n", inode,
+ ret, ceph_cap_string(*got));
+ return ret;
+}
+
+/*
+ * Check the offset we are writing up to against our current
+ * max_size. If necessary, tell the MDS we want to write to
+ * a larger offset.
+ */
+static void check_max_size(struct inode *inode, loff_t endoff)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int check = 0;
+
+ /* do we need to explicitly request a larger max_size? */
+ spin_lock(&inode->i_lock);
+ if ((endoff >= ci->i_max_size ||
+ endoff > (inode->i_size << 1)) &&
+ endoff > ci->i_wanted_max_size) {
+ dout("write %p at large endoff %llu, req max_size\n",
+ inode, endoff);
+ ci->i_wanted_max_size = endoff;
+ check = 1;
+ }
+ spin_unlock(&inode->i_lock);
+ if (check)
+ ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+}
+
+/*
+ * Wait for caps, and take cap references. If we can't get a WR cap
+ * due to a small max_size, make sure we check_max_size (and possibly
+ * ask the mds) so we don't get hung up indefinitely.
+ */
+int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, int *got,
+ loff_t endoff)
+{
+ int check_max, ret, err;
+
+retry:
+ if (endoff > 0)
+ check_max_size(&ci->vfs_inode, endoff);
+ check_max = 0;
+ err = 0;
+ ret = wait_event_interruptible(ci->i_cap_wq,
+ try_get_cap_refs(ci, need, want,
+ got, endoff,
+ &check_max, &err));
+ if (err)
+ ret = err;
+ if (check_max)
+ goto retry;
+ return ret;
+}
+
+/*
+ * Take cap refs. Caller must already know we hold at least one ref
+ * on the caps in question or we don't know this is safe.
+ */
+void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps)
+{
+ spin_lock(&ci->vfs_inode.i_lock);
+ __take_cap_refs(ci, caps);
+ spin_unlock(&ci->vfs_inode.i_lock);
+}
+
+/*
+ * Release cap refs.
+ *
+ * If we released the last ref on any given cap, call ceph_check_caps
+ * to release (or schedule a release).
+ *
+ * If we are releasing a WR cap (from a sync write), finalize any affected
+ * cap_snap, and wake up any waiters.
+ */
+void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
+{
+ struct inode *inode = &ci->vfs_inode;
+ int last = 0, put = 0, flushsnaps = 0, wake = 0;
+ struct ceph_cap_snap *capsnap;
+
+ spin_lock(&inode->i_lock);
+ if (had & CEPH_CAP_PIN)
+ --ci->i_pin_ref;
+ if (had & CEPH_CAP_FILE_RD)
+ if (--ci->i_rd_ref == 0)
+ last++;
+ if (had & CEPH_CAP_FILE_CACHE)
+ if (--ci->i_rdcache_ref == 0)
+ last++;
+ if (had & CEPH_CAP_FILE_BUFFER) {
+ if (--ci->i_wrbuffer_ref == 0) {
+ last++;
+ put++;
+ }
+ dout("put_cap_refs %p wrbuffer %d -> %d (?)\n",
+ inode, ci->i_wrbuffer_ref+1, ci->i_wrbuffer_ref);
+ }
+ if (had & CEPH_CAP_FILE_WR)
+ if (--ci->i_wr_ref == 0) {
+ last++;
+ if (!list_empty(&ci->i_cap_snaps)) {
+ capsnap = list_first_entry(&ci->i_cap_snaps,
+ struct ceph_cap_snap,
+ ci_item);
+ if (capsnap->writing) {
+ capsnap->writing = 0;
+ flushsnaps =
+ __ceph_finish_cap_snap(ci,
+ capsnap);
+ wake = 1;
+ }
+ }
+ }
+ spin_unlock(&inode->i_lock);
+
+ dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had),
+ last ? " last" : "", put ? " put" : "");
+
+ if (last && !flushsnaps)
+ ceph_check_caps(ci, 0, NULL);
+ else if (flushsnaps)
+ ceph_flush_snaps(ci);
+ if (wake)
+ wake_up(&ci->i_cap_wq);
+ if (put)
+ iput(inode);
+}
+
+/*
+ * Release @nr WRBUFFER refs on dirty pages for the given @snapc snap
+ * context. Adjust per-snap dirty page accounting as appropriate.
+ * Once all dirty data for a cap_snap is flushed, flush snapped file
+ * metadata back to the MDS. If we dropped the last ref, call
+ * ceph_check_caps.
+ */
+void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
+ struct ceph_snap_context *snapc)
+{
+ struct inode *inode = &ci->vfs_inode;
+ int last = 0;
+ int complete_capsnap = 0;
+ int drop_capsnap = 0;
+ int found = 0;
+ struct ceph_cap_snap *capsnap = NULL;
+
+ spin_lock(&inode->i_lock);
+ ci->i_wrbuffer_ref -= nr;
+ last = !ci->i_wrbuffer_ref;
+
+ if (ci->i_head_snapc == snapc) {
+ ci->i_wrbuffer_ref_head -= nr;
+ if (!ci->i_wrbuffer_ref_head) {
+ ceph_put_snap_context(ci->i_head_snapc);
+ ci->i_head_snapc = NULL;
+ }
+ dout("put_wrbuffer_cap_refs on %p head %d/%d -> %d/%d %s\n",
+ inode,
+ ci->i_wrbuffer_ref+nr, ci->i_wrbuffer_ref_head+nr,
+ ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
+ last ? " LAST" : "");
+ } else {
+ list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+ if (capsnap->context == snapc) {
+ found = 1;
+ break;
+ }
+ }
+ BUG_ON(!found);
+ capsnap->dirty_pages -= nr;
+ if (capsnap->dirty_pages == 0) {
+ complete_capsnap = 1;
+ if (capsnap->dirty == 0)
+ /* cap writeback completed before we created
+ * the cap_snap; no FLUSHSNAP is needed */
+ drop_capsnap = 1;
+ }
+ dout("put_wrbuffer_cap_refs on %p cap_snap %p "
+ " snap %lld %d/%d -> %d/%d %s%s%s\n",
+ inode, capsnap, capsnap->context->seq,
+ ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr,
+ ci->i_wrbuffer_ref, capsnap->dirty_pages,
+ last ? " (wrbuffer last)" : "",
+ complete_capsnap ? " (complete capsnap)" : "",
+ drop_capsnap ? " (drop capsnap)" : "");
+ if (drop_capsnap) {
+ ceph_put_snap_context(capsnap->context);
+ list_del(&capsnap->ci_item);
+ list_del(&capsnap->flushing_item);
+ ceph_put_cap_snap(capsnap);
+ }
+ }
+
+ spin_unlock(&inode->i_lock);
+
+ if (last) {
+ ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+ iput(inode);
+ } else if (complete_capsnap) {
+ ceph_flush_snaps(ci);
+ wake_up(&ci->i_cap_wq);
+ }
+ if (drop_capsnap)
+ iput(inode);
+}
+
+/*
+ * Handle a cap GRANT message from the MDS. (Note that a GRANT may
+ * actually be a revocation if it specifies a smaller cap set.)
+ *
+ * caller holds s_mutex and i_lock, we drop both.
+ *
+ * return value:
+ * 0 - ok
+ * 1 - check_caps on auth cap only (writeback)
+ * 2 - check_caps (ack revoke)
+ */
+static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
+ struct ceph_mds_session *session,
+ struct ceph_cap *cap,
+ struct ceph_buffer *xattr_buf)
+ __releases(inode->i_lock)
+ __releases(session->s_mutex)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int mds = session->s_mds;
+ int seq = le32_to_cpu(grant->seq);
+ int newcaps = le32_to_cpu(grant->caps);
+ int issued, implemented, used, wanted, dirty;
+ u64 size = le64_to_cpu(grant->size);
+ u64 max_size = le64_to_cpu(grant->max_size);
+ struct timespec mtime, atime, ctime;
+ int check_caps = 0;
+ int wake = 0;
+ int writeback = 0;
+ int revoked_rdcache = 0;
+ int queue_invalidate = 0;
+
+ dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
+ inode, cap, mds, seq, ceph_cap_string(newcaps));
+ dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
+ inode->i_size);
+
+ /*
+ * If CACHE is being revoked, and we have no dirty buffers,
+ * try to invalidate (once). (If there are dirty buffers, we
+ * will invalidate _after_ writeback.)
+ */
+ if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) &&
+ !ci->i_wrbuffer_ref) {
+ if (try_nonblocking_invalidate(inode) == 0) {
+ revoked_rdcache = 1;
+ } else {
+ /* there were locked pages.. invalidate later
+ in a separate thread. */
+ if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
+ queue_invalidate = 1;
+ ci->i_rdcache_revoking = ci->i_rdcache_gen;
+ }
+ }
+ }
+
+ /* side effects now are allowed */
+
+ issued = __ceph_caps_issued(ci, &implemented);
+ issued |= implemented | __ceph_caps_dirty(ci);
+
+ cap->cap_gen = session->s_cap_gen;
+
+ __check_cap_issue(ci, cap, newcaps);
+
+ if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
+ inode->i_mode = le32_to_cpu(grant->mode);
+ inode->i_uid = le32_to_cpu(grant->uid);
+ inode->i_gid = le32_to_cpu(grant->gid);
+ dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
+ inode->i_uid, inode->i_gid);
+ }
+
+ if ((issued & CEPH_CAP_LINK_EXCL) == 0)
+ inode->i_nlink = le32_to_cpu(grant->nlink);
+
+ if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && grant->xattr_len) {
+ int len = le32_to_cpu(grant->xattr_len);
+ u64 version = le64_to_cpu(grant->xattr_version);
+
+ if (version > ci->i_xattrs.version) {
+ dout(" got new xattrs v%llu on %p len %d\n",
+ version, inode, len);
+ if (ci->i_xattrs.blob)
+ ceph_buffer_put(ci->i_xattrs.blob);
+ ci->i_xattrs.blob = ceph_buffer_get(xattr_buf);
+ ci->i_xattrs.version = version;
+ }
+ }
+
+ /* size/ctime/mtime/atime? */
+ ceph_fill_file_size(inode, issued,
+ le32_to_cpu(grant->truncate_seq),
+ le64_to_cpu(grant->truncate_size), size);
+ ceph_decode_timespec(&mtime, &grant->mtime);
+ ceph_decode_timespec(&atime, &grant->atime);
+ ceph_decode_timespec(&ctime, &grant->ctime);
+ ceph_fill_file_time(inode, issued,
+ le32_to_cpu(grant->time_warp_seq), &ctime, &mtime,
+ &atime);
+
+ /* max size increase? */
+ if (max_size != ci->i_max_size) {
+ dout("max_size %lld -> %llu\n", ci->i_max_size, max_size);
+ ci->i_max_size = max_size;
+ if (max_size >= ci->i_wanted_max_size) {
+ ci->i_wanted_max_size = 0; /* reset */
+ ci->i_requested_max_size = 0;
+ }
+ wake = 1;
+ }
+
+ /* check cap bits */
+ wanted = __ceph_caps_wanted(ci);
+ used = __ceph_caps_used(ci);
+ dirty = __ceph_caps_dirty(ci);
+ dout(" my wanted = %s, used = %s, dirty %s\n",
+ ceph_cap_string(wanted),
+ ceph_cap_string(used),
+ ceph_cap_string(dirty));
+ if (wanted != le32_to_cpu(grant->wanted)) {
+ dout("mds wanted %s -> %s\n",
+ ceph_cap_string(le32_to_cpu(grant->wanted)),
+ ceph_cap_string(wanted));
+ grant->wanted = cpu_to_le32(wanted);
+ }
+
+ cap->seq = seq;
+
+ /* file layout may have changed */
+ ci->i_layout = grant->layout;
+
+ /* revocation, grant, or no-op? */
+ if (cap->issued & ~newcaps) {
+ dout("revocation: %s -> %s\n", ceph_cap_string(cap->issued),
+ ceph_cap_string(newcaps));
+ if ((used & ~newcaps) & CEPH_CAP_FILE_BUFFER)
+ 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 ||
+ revoked_rdcache)
+ check_caps = 2; /* send revoke ack in check_caps */
+ cap->issued = newcaps;
+ cap->implemented |= newcaps;
+ } else if (cap->issued == newcaps) {
+ dout("caps unchanged: %s -> %s\n",
+ ceph_cap_string(cap->issued), ceph_cap_string(newcaps));
+ } else {
+ dout("grant: %s -> %s\n", ceph_cap_string(cap->issued),
+ ceph_cap_string(newcaps));
+ cap->issued = newcaps;
+ cap->implemented |= newcaps; /* add bits only, to
+ * avoid stepping on a
+ * pending revocation */
+ wake = 1;
+ }
+ BUG_ON(cap->issued & ~cap->implemented);
+
+ spin_unlock(&inode->i_lock);
+ if (writeback)
+ /*
+ * queue inode for writeback: we can't actually call
+ * filemap_write_and_wait, etc. from message handler
+ * context.
+ */
+ ceph_queue_writeback(inode);
+ if (queue_invalidate)
+ ceph_queue_invalidate(inode);
+ if (wake)
+ wake_up(&ci->i_cap_wq);
+
+ if (check_caps == 1)
+ ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY,
+ session);
+ else if (check_caps == 2)
+ ceph_check_caps(ci, CHECK_CAPS_NODELAY, session);
+ else
+ mutex_unlock(&session->s_mutex);
+}
+
+/*
+ * Handle FLUSH_ACK from MDS, indicating that metadata we sent to the
+ * MDS has been safely committed.
+ */
+static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
+ struct ceph_mds_caps *m,
+ struct ceph_mds_session *session,
+ struct ceph_cap *cap)
+ __releases(inode->i_lock)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+ unsigned seq = le32_to_cpu(m->seq);
+ int dirty = le32_to_cpu(m->dirty);
+ int cleaned = 0;
+ int drop = 0;
+ int i;
+
+ for (i = 0; i < CEPH_CAP_BITS; i++)
+ if ((dirty & (1 << i)) &&
+ flush_tid == ci->i_cap_flush_tid[i])
+ cleaned |= 1 << i;
+
+ dout("handle_cap_flush_ack inode %p mds%d seq %d on %s cleaned %s,"
+ " flushing %s -> %s\n",
+ inode, session->s_mds, seq, ceph_cap_string(dirty),
+ ceph_cap_string(cleaned), ceph_cap_string(ci->i_flushing_caps),
+ ceph_cap_string(ci->i_flushing_caps & ~cleaned));
+
+ if (ci->i_flushing_caps == (ci->i_flushing_caps & ~cleaned))
+ goto out;
+
+ ci->i_flushing_caps &= ~cleaned;
+
+ spin_lock(&mdsc->cap_dirty_lock);
+ if (ci->i_flushing_caps == 0) {
+ list_del_init(&ci->i_flushing_item);
+ if (!list_empty(&session->s_cap_flushing))
+ dout(" mds%d still flushing cap on %p\n",
+ session->s_mds,
+ &list_entry(session->s_cap_flushing.next,
+ struct ceph_inode_info,
+ i_flushing_item)->vfs_inode);
+ mdsc->num_cap_flushing--;
+ wake_up(&mdsc->cap_flushing_wq);
+ dout(" inode %p now !flushing\n", inode);
+
+ if (ci->i_dirty_caps == 0) {
+ dout(" inode %p now clean\n", inode);
+ BUG_ON(!list_empty(&ci->i_dirty_item));
+ drop = 1;
+ } else {
+ BUG_ON(list_empty(&ci->i_dirty_item));
+ }
+ }
+ spin_unlock(&mdsc->cap_dirty_lock);
+ wake_up(&ci->i_cap_wq);
+
+out:
+ spin_unlock(&inode->i_lock);
+ if (drop)
+ iput(inode);
+}
+
+/*
+ * Handle FLUSHSNAP_ACK. MDS has flushed snap data to disk and we can
+ * throw away our cap_snap.
+ *
+ * Caller hold s_mutex.
+ */
+static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid,
+ struct ceph_mds_caps *m,
+ struct ceph_mds_session *session)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ u64 follows = le64_to_cpu(m->snap_follows);
+ struct ceph_cap_snap *capsnap;
+ int drop = 0;
+
+ dout("handle_cap_flushsnap_ack inode %p ci %p mds%d follows %lld\n",
+ inode, ci, session->s_mds, follows);
+
+ spin_lock(&inode->i_lock);
+ list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+ if (capsnap->follows == follows) {
+ if (capsnap->flush_tid != flush_tid) {
+ dout(" cap_snap %p follows %lld tid %lld !="
+ " %lld\n", capsnap, follows,
+ flush_tid, capsnap->flush_tid);
+ break;
+ }
+ WARN_ON(capsnap->dirty_pages || capsnap->writing);
+ dout(" removing %p cap_snap %p follows %lld\n",
+ inode, capsnap, follows);
+ ceph_put_snap_context(capsnap->context);
+ list_del(&capsnap->ci_item);
+ list_del(&capsnap->flushing_item);
+ ceph_put_cap_snap(capsnap);
+ drop = 1;
+ break;
+ } else {
+ dout(" skipping cap_snap %p follows %lld\n",
+ capsnap, capsnap->follows);
+ }
+ }
+ spin_unlock(&inode->i_lock);
+ if (drop)
+ iput(inode);
+}
+
+/*
+ * Handle TRUNC from MDS, indicating file truncation.
+ *
+ * caller hold s_mutex.
+ */
+static void handle_cap_trunc(struct inode *inode,
+ struct ceph_mds_caps *trunc,
+ struct ceph_mds_session *session)
+ __releases(inode->i_lock)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int mds = session->s_mds;
+ int seq = le32_to_cpu(trunc->seq);
+ u32 truncate_seq = le32_to_cpu(trunc->truncate_seq);
+ u64 truncate_size = le64_to_cpu(trunc->truncate_size);
+ u64 size = le64_to_cpu(trunc->size);
+ int implemented = 0;
+ int dirty = __ceph_caps_dirty(ci);
+ int issued = __ceph_caps_issued(ceph_inode(inode), &implemented);
+ int queue_trunc = 0;
+
+ issued |= implemented | dirty;
+
+ dout("handle_cap_trunc inode %p mds%d seq %d to %lld seq %d\n",
+ inode, mds, seq, truncate_size, truncate_seq);
+ queue_trunc = ceph_fill_file_size(inode, issued,
+ truncate_seq, truncate_size, size);
+ spin_unlock(&inode->i_lock);
+
+ if (queue_trunc)
+ ceph_queue_vmtruncate(inode);
+}
+
+/*
+ * Handle EXPORT from MDS. Cap is being migrated _from_ this mds to a
+ * different one. If we are the most recent migration we've seen (as
+ * indicated by mseq), make note of the migrating cap bits for the
+ * duration (until we see the corresponding IMPORT).
+ *
+ * caller holds s_mutex
+ */
+static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
+ struct ceph_mds_session *session)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int mds = session->s_mds;
+ unsigned mseq = le32_to_cpu(ex->migrate_seq);
+ struct ceph_cap *cap = NULL, *t;
+ struct rb_node *p;
+ int remember = 1;
+
+ dout("handle_cap_export inode %p ci %p mds%d mseq %d\n",
+ inode, ci, mds, mseq);
+
+ spin_lock(&inode->i_lock);
+
+ /* make sure we haven't seen a higher mseq */
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ t = rb_entry(p, struct ceph_cap, ci_node);
+ if (ceph_seq_cmp(t->mseq, mseq) > 0) {
+ dout(" higher mseq on cap from mds%d\n",
+ t->session->s_mds);
+ remember = 0;
+ }
+ if (t->session->s_mds == mds)
+ cap = t;
+ }
+
+ if (cap) {
+ if (remember) {
+ /* make note */
+ ci->i_cap_exporting_mds = mds;
+ ci->i_cap_exporting_mseq = mseq;
+ ci->i_cap_exporting_issued = cap->issued;
+ }
+ __ceph_remove_cap(cap);
+ }
+ /* else, we already released it */
+
+ spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Handle cap IMPORT. If there are temp bits from an older EXPORT,
+ * clean them up.
+ *
+ * caller holds s_mutex.
+ */
+static void handle_cap_import(struct ceph_mds_client *mdsc,
+ struct inode *inode, struct ceph_mds_caps *im,
+ struct ceph_mds_session *session,
+ void *snaptrace, int snaptrace_len)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int mds = session->s_mds;
+ unsigned issued = le32_to_cpu(im->caps);
+ unsigned wanted = le32_to_cpu(im->wanted);
+ unsigned seq = le32_to_cpu(im->seq);
+ unsigned mseq = le32_to_cpu(im->migrate_seq);
+ u64 realmino = le64_to_cpu(im->realm);
+ u64 cap_id = le64_to_cpu(im->cap_id);
+
+ if (ci->i_cap_exporting_mds >= 0 &&
+ ceph_seq_cmp(ci->i_cap_exporting_mseq, mseq) < 0) {
+ dout("handle_cap_import inode %p ci %p mds%d mseq %d"
+ " - cleared exporting from mds%d\n",
+ inode, ci, mds, mseq,
+ ci->i_cap_exporting_mds);
+ ci->i_cap_exporting_issued = 0;
+ ci->i_cap_exporting_mseq = 0;
+ ci->i_cap_exporting_mds = -1;
+ } else {
+ dout("handle_cap_import inode %p ci %p mds%d mseq %d\n",
+ inode, ci, mds, mseq);
+ }
+
+ down_write(&mdsc->snap_rwsem);
+ ceph_update_snap_trace(mdsc, snaptrace, snaptrace+snaptrace_len,
+ false);
+ downgrade_write(&mdsc->snap_rwsem);
+ ceph_add_cap(inode, session, cap_id, -1,
+ issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH,
+ NULL /* no caps context */);
+ try_flush_caps(inode, session, NULL);
+ up_read(&mdsc->snap_rwsem);
+}
+
+/*
+ * Handle a caps message from the MDS.
+ *
+ * Identify the appropriate session, inode, and call the right handler
+ * based on the cap op.
+ */
+void ceph_handle_caps(struct ceph_mds_session *session,
+ struct ceph_msg *msg)
+{
+ struct ceph_mds_client *mdsc = session->s_mdsc;
+ struct super_block *sb = mdsc->client->sb;
+ struct inode *inode;
+ struct ceph_cap *cap;
+ struct ceph_mds_caps *h;
+ int mds = session->s_mds;
+ int op;
+ u32 seq;
+ struct ceph_vino vino;
+ u64 cap_id;
+ u64 size, max_size;
+ u64 tid;
+ void *snaptrace;
+
+ dout("handle_caps from mds%d\n", mds);
+
+ /* decode */
+ tid = le64_to_cpu(msg->hdr.tid);
+ if (msg->front.iov_len < sizeof(*h))
+ goto bad;
+ h = msg->front.iov_base;
+ snaptrace = h + 1;
+ op = le32_to_cpu(h->op);
+ vino.ino = le64_to_cpu(h->ino);
+ vino.snap = CEPH_NOSNAP;
+ cap_id = le64_to_cpu(h->cap_id);
+ seq = le32_to_cpu(h->seq);
+ size = le64_to_cpu(h->size);
+ max_size = le64_to_cpu(h->max_size);
+
+ mutex_lock(&session->s_mutex);
+ session->s_seq++;
+ dout(" mds%d seq %lld cap seq %u\n", session->s_mds, session->s_seq,
+ (unsigned)seq);
+
+ /* lookup ino */
+ inode = ceph_find_inode(sb, vino);
+ dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino,
+ vino.snap, inode);
+ if (!inode) {
+ dout(" i don't have ino %llx\n", vino.ino);
+ goto done;
+ }
+
+ /* these will work even if we don't have a cap yet */
+ switch (op) {
+ case CEPH_CAP_OP_FLUSHSNAP_ACK:
+ handle_cap_flushsnap_ack(inode, tid, h, session);
+ goto done;
+
+ case CEPH_CAP_OP_EXPORT:
+ handle_cap_export(inode, h, session);
+ goto done;
+
+ case CEPH_CAP_OP_IMPORT:
+ handle_cap_import(mdsc, inode, h, session,
+ snaptrace, le32_to_cpu(h->snap_trace_len));
+ ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY,
+ session);
+ goto done_unlocked;
+ }
+
+ /* the rest require a cap */
+ spin_lock(&inode->i_lock);
+ cap = __get_cap_for_mds(ceph_inode(inode), mds);
+ if (!cap) {
+ dout("no cap on %p ino %llx.%llx from mds%d, releasing\n",
+ inode, ceph_ino(inode), ceph_snap(inode), mds);
+ spin_unlock(&inode->i_lock);
+ goto done;
+ }
+
+ /* note that each of these drops i_lock for us */
+ switch (op) {
+ case CEPH_CAP_OP_REVOKE:
+ case CEPH_CAP_OP_GRANT:
+ handle_cap_grant(inode, h, session, cap, msg->middle);
+ goto done_unlocked;
+
+ case CEPH_CAP_OP_FLUSH_ACK:
+ handle_cap_flush_ack(inode, tid, h, session, cap);
+ break;
+
+ case CEPH_CAP_OP_TRUNC:
+ handle_cap_trunc(inode, h, session);
+ break;
+
+ default:
+ spin_unlock(&inode->i_lock);
+ pr_err("ceph_handle_caps: unknown cap op %d %s\n", op,
+ ceph_cap_op_name(op));
+ }
+
+done:
+ mutex_unlock(&session->s_mutex);
+done_unlocked:
+ if (inode)
+ iput(inode);
+ return;
+
+bad:
+ pr_err("ceph_handle_caps: corrupt message\n");
+ ceph_msg_dump(msg);
+ return;
+}
+
+/*
+ * Delayed work handler to process end of delayed cap release LRU list.
+ */
+void ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
+{
+ struct ceph_inode_info *ci;
+ int flags = CHECK_CAPS_NODELAY;
+
+ dout("check_delayed_caps\n");
+ while (1) {
+ spin_lock(&mdsc->cap_delay_lock);
+ if (list_empty(&mdsc->cap_delay_list))
+ break;
+ ci = list_first_entry(&mdsc->cap_delay_list,
+ struct ceph_inode_info,
+ i_cap_delay_list);
+ if ((ci->i_ceph_flags & CEPH_I_FLUSH) == 0 &&
+ time_before(jiffies, ci->i_hold_caps_max))
+ break;
+ list_del_init(&ci->i_cap_delay_list);
+ spin_unlock(&mdsc->cap_delay_lock);
+ dout("check_delayed_caps on %p\n", &ci->vfs_inode);
+ ceph_check_caps(ci, flags, NULL);
+ }
+ spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Flush all dirty caps to the mds
+ */
+void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc)
+{
+ struct ceph_inode_info *ci, *nci = NULL;
+ struct inode *inode, *ninode = NULL;
+ struct list_head *p, *n;
+
+ dout("flush_dirty_caps\n");
+ spin_lock(&mdsc->cap_dirty_lock);
+ list_for_each_safe(p, n, &mdsc->cap_dirty) {
+ if (nci) {
+ ci = nci;
+ inode = ninode;
+ ci->i_ceph_flags &= ~CEPH_I_NOFLUSH;
+ dout("flush_dirty_caps inode %p (was next inode)\n",
+ inode);
+ } else {
+ ci = list_entry(p, struct ceph_inode_info,
+ i_dirty_item);
+ inode = igrab(&ci->vfs_inode);
+ BUG_ON(!inode);
+ dout("flush_dirty_caps inode %p\n", inode);
+ }
+ if (n != &mdsc->cap_dirty) {
+ nci = list_entry(n, struct ceph_inode_info,
+ i_dirty_item);
+ ninode = igrab(&nci->vfs_inode);
+ BUG_ON(!ninode);
+ nci->i_ceph_flags |= CEPH_I_NOFLUSH;
+ dout("flush_dirty_caps next inode %p, noflush\n",
+ ninode);
+ } else {
+ nci = NULL;
+ ninode = NULL;
+ }
+ spin_unlock(&mdsc->cap_dirty_lock);
+ if (inode) {
+ ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH,
+ NULL);
+ iput(inode);
+ }
+ spin_lock(&mdsc->cap_dirty_lock);
+ }
+ spin_unlock(&mdsc->cap_dirty_lock);
+}
+
+/*
+ * Drop open file reference. If we were the last open file,
+ * we may need to release capabilities to the MDS (or schedule
+ * their delayed release).
+ */
+void ceph_put_fmode(struct ceph_inode_info *ci, int fmode)
+{
+ struct inode *inode = &ci->vfs_inode;
+ int last = 0;
+
+ spin_lock(&inode->i_lock);
+ dout("put_fmode %p fmode %d %d -> %d\n", inode, fmode,
+ ci->i_nr_by_mode[fmode], ci->i_nr_by_mode[fmode]-1);
+ BUG_ON(ci->i_nr_by_mode[fmode] == 0);
+ if (--ci->i_nr_by_mode[fmode] == 0)
+ last++;
+ spin_unlock(&inode->i_lock);
+
+ if (last && ci->i_vino.snap == CEPH_NOSNAP)
+ ceph_check_caps(ci, 0, NULL);
+}
+
+/*
+ * Helpers for embedding cap and dentry lease releases into mds
+ * requests.
+ *
+ * @force is used by dentry_release (below) to force inclusion of a
+ * record for the directory inode, even when there aren't any caps to
+ * drop.
+ */
+int ceph_encode_inode_release(void **p, struct inode *inode,
+ int mds, int drop, int unless, int force)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_cap *cap;
+ struct ceph_mds_request_release *rel = *p;
+ int ret = 0;
+ int used = 0;
+
+ spin_lock(&inode->i_lock);
+ used = __ceph_caps_used(ci);
+
+ dout("encode_inode_release %p mds%d used %s drop %s unless %s\n", inode,
+ mds, ceph_cap_string(used), ceph_cap_string(drop),
+ ceph_cap_string(unless));
+
+ /* only drop unused caps */
+ drop &= ~used;
+
+ cap = __get_cap_for_mds(ci, mds);
+ if (cap && __cap_is_valid(cap)) {
+ if (force ||
+ ((cap->issued & drop) &&
+ (cap->issued & unless) == 0)) {
+ if ((cap->issued & drop) &&
+ (cap->issued & unless) == 0) {
+ dout("encode_inode_release %p cap %p %s -> "
+ "%s\n", inode, cap,
+ ceph_cap_string(cap->issued),
+ ceph_cap_string(cap->issued & ~drop));
+ cap->issued &= ~drop;
+ cap->implemented &= ~drop;
+ if (ci->i_ceph_flags & CEPH_I_NODELAY) {
+ int wanted = __ceph_caps_wanted(ci);
+ dout(" wanted %s -> %s (act %s)\n",
+ ceph_cap_string(cap->mds_wanted),
+ ceph_cap_string(cap->mds_wanted &
+ ~wanted),
+ ceph_cap_string(wanted));
+ cap->mds_wanted &= wanted;
+ }
+ } else {
+ dout("encode_inode_release %p cap %p %s"
+ " (force)\n", inode, cap,
+ ceph_cap_string(cap->issued));
+ }
+
+ rel->ino = cpu_to_le64(ceph_ino(inode));
+ rel->cap_id = cpu_to_le64(cap->cap_id);
+ rel->seq = cpu_to_le32(cap->seq);
+ rel->issue_seq = cpu_to_le32(cap->issue_seq),
+ rel->mseq = cpu_to_le32(cap->mseq);
+ rel->caps = cpu_to_le32(cap->issued);
+ rel->wanted = cpu_to_le32(cap->mds_wanted);
+ rel->dname_len = 0;
+ rel->dname_seq = 0;
+ *p += sizeof(*rel);
+ ret = 1;
+ } else {
+ dout("encode_inode_release %p cap %p %s\n",
+ inode, cap, ceph_cap_string(cap->issued));
+ }
+ }
+ spin_unlock(&inode->i_lock);
+ return ret;
+}
+
+int ceph_encode_dentry_release(void **p, struct dentry *dentry,
+ int mds, int drop, int unless)
+{
+ struct inode *dir = dentry->d_parent->d_inode;
+ struct ceph_mds_request_release *rel = *p;
+ struct ceph_dentry_info *di = ceph_dentry(dentry);
+ int force = 0;
+ int ret;
+
+ /*
+ * force an record for the directory caps if we have a dentry lease.
+ * this is racy (can't take i_lock and d_lock together), but it
+ * doesn't have to be perfect; the mds will revoke anything we don't
+ * release.
+ */
+ spin_lock(&dentry->d_lock);
+ if (di->lease_session && di->lease_session->s_mds == mds)
+ force = 1;
+ spin_unlock(&dentry->d_lock);
+
+ ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force);
+
+ spin_lock(&dentry->d_lock);
+ if (ret && di->lease_session && di->lease_session->s_mds == mds) {
+ dout("encode_dentry_release %p mds%d seq %d\n",
+ dentry, mds, (int)di->lease_seq);
+ rel->dname_len = cpu_to_le32(dentry->d_name.len);
+ memcpy(*p, dentry->d_name.name, dentry->d_name.len);
+ *p += dentry->d_name.len;
+ rel->dname_seq = cpu_to_le32(di->lease_seq);
+ }
+ spin_unlock(&dentry->d_lock);
+ return ret;
+}
diff --git a/fs/ceph/ceph_debug.h b/fs/ceph/ceph_debug.h
new file mode 100644
index 00000000000..1818c230561
--- /dev/null
+++ b/fs/ceph/ceph_debug.h
@@ -0,0 +1,37 @@
+#ifndef _FS_CEPH_DEBUG_H
+#define _FS_CEPH_DEBUG_H
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#ifdef CONFIG_CEPH_FS_PRETTYDEBUG
+
+/*
+ * wrap pr_debug to include a filename:lineno prefix on each line.
+ * this incurs some overhead (kernel size and execution time) due to
+ * the extra function call at each call site.
+ */
+
+# if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+extern const char *ceph_file_part(const char *s, int len);
+# define dout(fmt, ...) \
+ pr_debug(" %12.12s:%-4d : " fmt, \
+ ceph_file_part(__FILE__, sizeof(__FILE__)), \
+ __LINE__, ##__VA_ARGS__)
+# else
+/* faux printk call just to see any compiler warnings. */
+# define dout(fmt, ...) do { \
+ if (0) \
+ printk(KERN_DEBUG fmt, ##__VA_ARGS__); \
+ } while (0)
+# endif
+
+#else
+
+/*
+ * or, just wrap pr_debug
+ */
+# define dout(fmt, ...) pr_debug(" " fmt, ##__VA_ARGS__)
+
+#endif
+
+#endif
diff --git a/fs/ceph/ceph_frag.c b/fs/ceph/ceph_frag.c
new file mode 100644
index 00000000000..ab6cf35c409
--- /dev/null
+++ b/fs/ceph/ceph_frag.c
@@ -0,0 +1,21 @@
+/*
+ * Ceph 'frag' type
+ */
+#include "types.h"
+
+int ceph_frag_compare(__u32 a, __u32 b)
+{
+ unsigned va = ceph_frag_value(a);
+ unsigned vb = ceph_frag_value(b);
+ if (va < vb)
+ return -1;
+ if (va > vb)
+ return 1;
+ va = ceph_frag_bits(a);
+ vb = ceph_frag_bits(b);
+ if (va < vb)
+ return -1;
+ if (va > vb)
+ return 1;
+ return 0;
+}
diff --git a/fs/ceph/ceph_frag.h b/fs/ceph/ceph_frag.h
new file mode 100644
index 00000000000..793f50cb7c2
--- /dev/null
+++ b/fs/ceph/ceph_frag.h
@@ -0,0 +1,109 @@
+#ifndef _FS_CEPH_FRAG_H
+#define _FS_CEPH_FRAG_H
+
+/*
+ * "Frags" are a way to describe a subset of a 32-bit number space,
+ * using a mask and a value to match against that mask. Any given frag
+ * (subset of the number space) can be partitioned into 2^n sub-frags.
+ *
+ * Frags are encoded into a 32-bit word:
+ * 8 upper bits = "bits"
+ * 24 lower bits = "value"
+ * (We could go to 5+27 bits, but who cares.)
+ *
+ * We use the _most_ significant bits of the 24 bit value. This makes
+ * values logically sort.
+ *
+ * Unfortunately, because the "bits" field is still in the high bits, we
+ * can't sort encoded frags numerically. However, it does allow you
+ * to feed encoded frags as values into frag_contains_value.
+ */
+static inline __u32 ceph_frag_make(__u32 b, __u32 v)
+{
+ return (b << 24) |
+ (v & (0xffffffu << (24-b)) & 0xffffffu);
+}
+static inline __u32 ceph_frag_bits(__u32 f)
+{
+ return f >> 24;
+}
+static inline __u32 ceph_frag_value(__u32 f)
+{
+ return f & 0xffffffu;
+}
+static inline __u32 ceph_frag_mask(__u32 f)
+{
+ return (0xffffffu << (24-ceph_frag_bits(f))) & 0xffffffu;
+}
+static inline __u32 ceph_frag_mask_shift(__u32 f)
+{
+ return 24 - ceph_frag_bits(f);
+}
+
+static inline int ceph_frag_contains_value(__u32 f, __u32 v)
+{
+ return (v & ceph_frag_mask(f)) == ceph_frag_value(f);
+}
+static inline int ceph_frag_contains_frag(__u32 f, __u32 sub)
+{
+ /* is sub as specific as us, and contained by us? */
+ return ceph_frag_bits(sub) >= ceph_frag_bits(f) &&
+ (ceph_frag_value(sub) & ceph_frag_mask(f)) == ceph_frag_value(f);
+}
+
+static inline __u32 ceph_frag_parent(__u32 f)
+{
+ return ceph_frag_make(ceph_frag_bits(f) - 1,
+ ceph_frag_value(f) & (ceph_frag_mask(f) << 1));
+}
+static inline int ceph_frag_is_left_child(__u32 f)
+{
+ return ceph_frag_bits(f) > 0 &&
+ (ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 0;
+}
+static inline int ceph_frag_is_right_child(__u32 f)
+{
+ return ceph_frag_bits(f) > 0 &&
+ (ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 1;
+}
+static inline __u32 ceph_frag_sibling(__u32 f)
+{
+ return ceph_frag_make(ceph_frag_bits(f),
+ ceph_frag_value(f) ^ (0x1000000 >> ceph_frag_bits(f)));
+}
+static inline __u32 ceph_frag_left_child(__u32 f)
+{
+ return ceph_frag_make(ceph_frag_bits(f)+1, ceph_frag_value(f));
+}
+static inline __u32 ceph_frag_right_child(__u32 f)
+{
+ return ceph_frag_make(ceph_frag_bits(f)+1,
+ ceph_frag_value(f) | (0x1000000 >> (1+ceph_frag_bits(f))));
+}
+static inline __u32 ceph_frag_make_child(__u32 f, int by, int i)
+{
+ int newbits = ceph_frag_bits(f) + by;
+ return ceph_frag_make(newbits,
+ ceph_frag_value(f) | (i << (24 - newbits)));
+}
+static inline int ceph_frag_is_leftmost(__u32 f)
+{
+ return ceph_frag_value(f) == 0;
+}
+static inline int ceph_frag_is_rightmost(__u32 f)
+{
+ return ceph_frag_value(f) == ceph_frag_mask(f);
+}
+static inline __u32 ceph_frag_next(__u32 f)
+{
+ return ceph_frag_make(ceph_frag_bits(f),
+ ceph_frag_value(f) + (0x1000000 >> ceph_frag_bits(f)));
+}
+
+/*
+ * comparator to sort frags logically, as when traversing the
+ * number space in ascending order...
+ */
+int ceph_frag_compare(__u32 a, __u32 b);
+
+#endif
diff --git a/fs/ceph/ceph_fs.c b/fs/ceph/ceph_fs.c
new file mode 100644
index 00000000000..79d76bc4303
--- /dev/null
+++ b/fs/ceph/ceph_fs.c
@@ -0,0 +1,74 @@
+/*
+ * Some non-inline ceph helpers
+ */
+#include "types.h"
+
+/*
+ * return true if @layout appears to be valid
+ */
+int ceph_file_layout_is_valid(const struct ceph_file_layout *layout)
+{
+ __u32 su = le32_to_cpu(layout->fl_stripe_unit);
+ __u32 sc = le32_to_cpu(layout->fl_stripe_count);
+ __u32 os = le32_to_cpu(layout->fl_object_size);
+
+ /* stripe unit, object size must be non-zero, 64k increment */
+ if (!su || (su & (CEPH_MIN_STRIPE_UNIT-1)))
+ return 0;
+ if (!os || (os & (CEPH_MIN_STRIPE_UNIT-1)))
+ return 0;
+ /* object size must be a multiple of stripe unit */
+ if (os < su || os % su)
+ return 0;
+ /* stripe count must be non-zero */
+ if (!sc)
+ return 0;
+ return 1;
+}
+
+
+int ceph_flags_to_mode(int flags)
+{
+#ifdef O_DIRECTORY /* fixme */
+ if ((flags & O_DIRECTORY) == O_DIRECTORY)
+ return CEPH_FILE_MODE_PIN;
+#endif
+#ifdef O_LAZY
+ if (flags & O_LAZY)
+ return 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;
+}
+
+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 |
+ 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 |
+ 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;
+}
diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h
new file mode 100644
index 00000000000..0c2241ef365
--- /dev/null
+++ b/fs/ceph/ceph_fs.h
@@ -0,0 +1,650 @@
+/*
+ * ceph_fs.h - Ceph constants and data types to share between kernel and
+ * user space.
+ *
+ * Most types in this file are defined as little-endian, and are
+ * primarily intended to describe data structures that pass over the
+ * wire or that are stored on disk.
+ *
+ * LGPL2
+ */
+
+#ifndef _FS_CEPH_CEPH_FS_H
+#define _FS_CEPH_CEPH_FS_H
+
+#include "msgr.h"
+#include "rados.h"
+
+/*
+ * Ceph release version
+ */
+#define CEPH_VERSION_MAJOR 0
+#define CEPH_VERSION_MINOR 19
+#define CEPH_VERSION_PATCH 0
+
+#define _CEPH_STRINGIFY(x) #x
+#define CEPH_STRINGIFY(x) _CEPH_STRINGIFY(x)
+#define CEPH_MAKE_VERSION(x, y, z) CEPH_STRINGIFY(x) "." CEPH_STRINGIFY(y) \
+ "." CEPH_STRINGIFY(z)
+#define CEPH_VERSION CEPH_MAKE_VERSION(CEPH_VERSION_MAJOR, \
+ CEPH_VERSION_MINOR, CEPH_VERSION_PATCH)
+
+/*
+ * subprotocol versions. when specific messages types or high-level
+ * protocols change, bump the affected components. we keep rev
+ * internal cluster protocols separately from the public,
+ * client-facing protocol.
+ */
+#define CEPH_OSD_PROTOCOL 8 /* cluster internal */
+#define CEPH_MDS_PROTOCOL 9 /* cluster internal */
+#define CEPH_MON_PROTOCOL 5 /* cluster internal */
+#define CEPH_OSDC_PROTOCOL 24 /* server/client */
+#define CEPH_MDSC_PROTOCOL 32 /* server/client */
+#define CEPH_MONC_PROTOCOL 15 /* server/client */
+
+
+#define CEPH_INO_ROOT 1
+#define CEPH_INO_CEPH 2 /* hidden .ceph dir */
+
+/* arbitrary limit on max # of monitors (cluster of 3 is typical) */
+#define CEPH_MAX_MON 31
+
+
+/*
+ * feature bits
+ */
+#define CEPH_FEATURE_SUPPORTED 0
+#define CEPH_FEATURE_REQUIRED 0
+
+
+/*
+ * ceph_file_layout - describe data layout for a file/inode
+ */
+struct ceph_file_layout {
+ /* file -> object mapping */
+ __le32 fl_stripe_unit; /* stripe unit, in bytes. must be multiple
+ of page size. */
+ __le32 fl_stripe_count; /* over this many objects */
+ __le32 fl_object_size; /* until objects are this big, then move to
+ new objects */
+ __le32 fl_cas_hash; /* 0 = none; 1 = sha256 */
+
+ /* pg -> disk layout */
+ __le32 fl_object_stripe_unit; /* for per-object parity, if any */
+
+ /* object -> pg layout */
+ __le32 fl_pg_preferred; /* preferred primary for pg (-1 for none) */
+ __le32 fl_pg_pool; /* namespace, crush ruleset, rep level */
+} __attribute__ ((packed));
+
+#define CEPH_MIN_STRIPE_UNIT 65536
+
+int ceph_file_layout_is_valid(const struct ceph_file_layout *layout);
+
+
+/* crypto algorithms */
+#define CEPH_CRYPTO_NONE 0x0
+#define CEPH_CRYPTO_AES 0x1
+
+/* security/authentication protocols */
+#define CEPH_AUTH_UNKNOWN 0x0
+#define CEPH_AUTH_NONE 0x1
+#define CEPH_AUTH_CEPHX 0x2
+
+
+/*********************************************
+ * message layer
+ */
+
+/*
+ * message types
+ */
+
+/* misc */
+#define CEPH_MSG_SHUTDOWN 1
+#define CEPH_MSG_PING 2
+
+/* client <-> monitor */
+#define CEPH_MSG_MON_MAP 4
+#define CEPH_MSG_MON_GET_MAP 5
+#define CEPH_MSG_STATFS 13
+#define CEPH_MSG_STATFS_REPLY 14
+#define CEPH_MSG_MON_SUBSCRIBE 15
+#define CEPH_MSG_MON_SUBSCRIBE_ACK 16
+#define CEPH_MSG_AUTH 17
+#define CEPH_MSG_AUTH_REPLY 18
+
+/* client <-> mds */
+#define CEPH_MSG_MDS_MAP 21
+
+#define CEPH_MSG_CLIENT_SESSION 22
+#define CEPH_MSG_CLIENT_RECONNECT 23
+
+#define CEPH_MSG_CLIENT_REQUEST 24
+#define CEPH_MSG_CLIENT_REQUEST_FORWARD 25
+#define CEPH_MSG_CLIENT_REPLY 26
+#define CEPH_MSG_CLIENT_CAPS 0x310
+#define CEPH_MSG_CLIENT_LEASE 0x311
+#define CEPH_MSG_CLIENT_SNAP 0x312
+#define CEPH_MSG_CLIENT_CAPRELEASE 0x313
+
+/* osd */
+#define CEPH_MSG_OSD_MAP 41
+#define CEPH_MSG_OSD_OP 42
+#define CEPH_MSG_OSD_OPREPLY 43
+
+struct ceph_mon_request_header {
+ __le64 have_version;
+ __le16 session_mon;
+ __le64 session_mon_tid;
+} __attribute__ ((packed));
+
+struct ceph_mon_statfs {
+ struct ceph_mon_request_header monhdr;
+ struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+struct ceph_statfs {
+ __le64 kb, kb_used, kb_avail;
+ __le64 num_objects;
+} __attribute__ ((packed));
+
+struct ceph_mon_statfs_reply {
+ struct ceph_fsid fsid;
+ __le64 version;
+ struct ceph_statfs st;
+} __attribute__ ((packed));
+
+struct ceph_osd_getmap {
+ struct ceph_mon_request_header monhdr;
+ struct ceph_fsid fsid;
+ __le32 start;
+} __attribute__ ((packed));
+
+struct ceph_mds_getmap {
+ struct ceph_mon_request_header monhdr;
+ struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+struct ceph_client_mount {
+ struct ceph_mon_request_header monhdr;
+} __attribute__ ((packed));
+
+struct ceph_mon_subscribe_item {
+ __le64 have_version; __le64 have;
+ __u8 onetime;
+} __attribute__ ((packed));
+
+struct ceph_mon_subscribe_ack {
+ __le32 duration; /* seconds */
+ struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+/*
+ * mds states
+ * > 0 -> in
+ * <= 0 -> out
+ */
+#define CEPH_MDS_STATE_DNE 0 /* down, does not exist. */
+#define CEPH_MDS_STATE_STOPPED -1 /* down, once existed, but no subtrees.
+ empty log. */
+#define CEPH_MDS_STATE_BOOT -4 /* up, boot announcement. */
+#define CEPH_MDS_STATE_STANDBY -5 /* up, idle. waiting for assignment. */
+#define CEPH_MDS_STATE_CREATING -6 /* up, creating MDS instance. */
+#define CEPH_MDS_STATE_STARTING -7 /* up, starting previously stopped mds */
+#define CEPH_MDS_STATE_STANDBY_REPLAY -8 /* up, tailing active node's journal */
+
+#define CEPH_MDS_STATE_REPLAY 8 /* up, replaying journal. */
+#define CEPH_MDS_STATE_RESOLVE 9 /* up, disambiguating distributed
+ operations (import, rename, etc.) */
+#define CEPH_MDS_STATE_RECONNECT 10 /* up, reconnect to clients */
+#define CEPH_MDS_STATE_REJOIN 11 /* up, rejoining distributed cache */
+#define CEPH_MDS_STATE_CLIENTREPLAY 12 /* up, replaying client operations */
+#define CEPH_MDS_STATE_ACTIVE 13 /* up, active */
+#define CEPH_MDS_STATE_STOPPING 14 /* up, but exporting metadata */
+
+extern const char *ceph_mds_state_name(int s);
+
+
+/*
+ * metadata lock types.
+ * - these are bitmasks.. we can compose them
+ * - they also define the lock ordering by the MDS
+ * - a few of these are internal to the mds
+ */
+#define CEPH_LOCK_DN 1
+#define CEPH_LOCK_ISNAP 2
+#define CEPH_LOCK_IVERSION 4 /* mds internal */
+#define CEPH_LOCK_IFILE 8 /* mds internal */
+#define CEPH_LOCK_IAUTH 32
+#define CEPH_LOCK_ILINK 64
+#define CEPH_LOCK_IDFT 128 /* dir frag tree */
+#define CEPH_LOCK_INEST 256 /* mds internal */
+#define CEPH_LOCK_IXATTR 512
+#define CEPH_LOCK_INO 2048 /* immutable inode bits; not a lock */
+
+/* client_session ops */
+enum {
+ CEPH_SESSION_REQUEST_OPEN,
+ CEPH_SESSION_OPEN,
+ CEPH_SESSION_REQUEST_CLOSE,
+ CEPH_SESSION_CLOSE,
+ CEPH_SESSION_REQUEST_RENEWCAPS,
+ CEPH_SESSION_RENEWCAPS,
+ CEPH_SESSION_STALE,
+ CEPH_SESSION_RECALL_STATE,
+};
+
+extern const char *ceph_session_op_name(int op);
+
+struct ceph_mds_session_head {
+ __le32 op;
+ __le64 seq;
+ struct ceph_timespec stamp;
+ __le32 max_caps, max_leases;
+} __attribute__ ((packed));
+
+/* client_request */
+/*
+ * metadata ops.
+ * & 0x001000 -> write op
+ * & 0x010000 -> follow symlink (e.g. stat(), not lstat()).
+ & & 0x100000 -> use weird ino/path trace
+ */
+#define CEPH_MDS_OP_WRITE 0x001000
+enum {
+ CEPH_MDS_OP_LOOKUP = 0x00100,
+ CEPH_MDS_OP_GETATTR = 0x00101,
+ CEPH_MDS_OP_LOOKUPHASH = 0x00102,
+ CEPH_MDS_OP_LOOKUPPARENT = 0x00103,
+
+ CEPH_MDS_OP_SETXATTR = 0x01105,
+ CEPH_MDS_OP_RMXATTR = 0x01106,
+ CEPH_MDS_OP_SETLAYOUT = 0x01107,
+ CEPH_MDS_OP_SETATTR = 0x01108,
+
+ CEPH_MDS_OP_MKNOD = 0x01201,
+ CEPH_MDS_OP_LINK = 0x01202,
+ CEPH_MDS_OP_UNLINK = 0x01203,
+ CEPH_MDS_OP_RENAME = 0x01204,
+ CEPH_MDS_OP_MKDIR = 0x01220,
+ CEPH_MDS_OP_RMDIR = 0x01221,
+ CEPH_MDS_OP_SYMLINK = 0x01222,
+
+ CEPH_MDS_OP_CREATE = 0x01301,
+ CEPH_MDS_OP_OPEN = 0x00302,
+ CEPH_MDS_OP_READDIR = 0x00305,
+
+ CEPH_MDS_OP_LOOKUPSNAP = 0x00400,
+ CEPH_MDS_OP_MKSNAP = 0x01400,
+ CEPH_MDS_OP_RMSNAP = 0x01401,
+ CEPH_MDS_OP_LSSNAP = 0x00402,
+};
+
+extern const char *ceph_mds_op_name(int op);
+
+
+#define CEPH_SETATTR_MODE 1
+#define CEPH_SETATTR_UID 2
+#define CEPH_SETATTR_GID 4
+#define CEPH_SETATTR_MTIME 8
+#define CEPH_SETATTR_ATIME 16
+#define CEPH_SETATTR_SIZE 32
+#define CEPH_SETATTR_CTIME 64
+
+union ceph_mds_request_args {
+ struct {
+ __le32 mask; /* CEPH_CAP_* */
+ } __attribute__ ((packed)) getattr;
+ struct {
+ __le32 mode;
+ __le32 uid;
+ __le32 gid;
+ struct ceph_timespec mtime;
+ struct ceph_timespec atime;
+ __le64 size, old_size; /* old_size needed by truncate */
+ __le32 mask; /* CEPH_SETATTR_* */
+ } __attribute__ ((packed)) setattr;
+ struct {
+ __le32 frag; /* which dir fragment */
+ __le32 max_entries; /* how many dentries to grab */
+ } __attribute__ ((packed)) readdir;
+ struct {
+ __le32 mode;
+ __le32 rdev;
+ } __attribute__ ((packed)) mknod;
+ struct {
+ __le32 mode;
+ } __attribute__ ((packed)) mkdir;
+ struct {
+ __le32 flags;
+ __le32 mode;
+ __le32 stripe_unit; /* layout for newly created file */
+ __le32 stripe_count; /* ... */
+ __le32 object_size;
+ __le32 file_replication;
+ __le32 preferred;
+ } __attribute__ ((packed)) open;
+ struct {
+ __le32 flags;
+ } __attribute__ ((packed)) setxattr;
+ struct {
+ struct ceph_file_layout layout;
+ } __attribute__ ((packed)) setlayout;
+} __attribute__ ((packed));
+
+#define CEPH_MDS_FLAG_REPLAY 1 /* this is a replayed op */
+#define CEPH_MDS_FLAG_WANT_DENTRY 2 /* want dentry in reply */
+
+struct ceph_mds_request_head {
+ __le64 oldest_client_tid;
+ __le32 mdsmap_epoch; /* on client */
+ __le32 flags; /* CEPH_MDS_FLAG_* */
+ __u8 num_retry, num_fwd; /* count retry, fwd attempts */
+ __le16 num_releases; /* # include cap/lease release records */
+ __le32 op; /* mds op code */
+ __le32 caller_uid, caller_gid;
+ __le64 ino; /* use this ino for openc, mkdir, mknod,
+ etc. (if replaying) */
+ union ceph_mds_request_args args;
+} __attribute__ ((packed));
+
+/* cap/lease release record */
+struct ceph_mds_request_release {
+ __le64 ino, cap_id; /* ino and unique cap id */
+ __le32 caps, wanted; /* new issued, wanted */
+ __le32 seq, issue_seq, mseq;
+ __le32 dname_seq; /* if releasing a dentry lease, a */
+ __le32 dname_len; /* string follows. */
+} __attribute__ ((packed));
+
+/* client reply */
+struct ceph_mds_reply_head {
+ __le32 op;
+ __le32 result;
+ __le32 mdsmap_epoch;
+ __u8 safe; /* true if committed to disk */
+ __u8 is_dentry, is_target; /* true if dentry, target inode records
+ are included with reply */
+} __attribute__ ((packed));
+
+/* one for each node split */
+struct ceph_frag_tree_split {
+ __le32 frag; /* this frag splits... */
+ __le32 by; /* ...by this many bits */
+} __attribute__ ((packed));
+
+struct ceph_frag_tree_head {
+ __le32 nsplits; /* num ceph_frag_tree_split records */
+ struct ceph_frag_tree_split splits[];
+} __attribute__ ((packed));
+
+/* capability issue, for bundling with mds reply */
+struct ceph_mds_reply_cap {
+ __le32 caps, wanted; /* caps issued, wanted */
+ __le64 cap_id;
+ __le32 seq, mseq;
+ __le64 realm; /* snap realm */
+ __u8 flags; /* CEPH_CAP_FLAG_* */
+} __attribute__ ((packed));
+
+#define CEPH_CAP_FLAG_AUTH 1 /* cap is issued by auth mds */
+
+/* inode record, for bundling with mds reply */
+struct ceph_mds_reply_inode {
+ __le64 ino;
+ __le64 snapid;
+ __le32 rdev;
+ __le64 version; /* inode version */
+ __le64 xattr_version; /* version for xattr blob */
+ struct ceph_mds_reply_cap cap; /* caps issued for this inode */
+ struct ceph_file_layout layout;
+ struct ceph_timespec ctime, mtime, atime;
+ __le32 time_warp_seq;
+ __le64 size, max_size, truncate_size;
+ __le32 truncate_seq;
+ __le32 mode, uid, gid;
+ __le32 nlink;
+ __le64 files, subdirs, rbytes, rfiles, rsubdirs; /* dir stats */
+ struct ceph_timespec rctime;
+ struct ceph_frag_tree_head fragtree; /* (must be at end of struct) */
+} __attribute__ ((packed));
+/* followed by frag array, then symlink string, then xattr blob */
+
+/* reply_lease follows dname, and reply_inode */
+struct ceph_mds_reply_lease {
+ __le16 mask; /* lease type(s) */
+ __le32 duration_ms; /* lease duration */
+ __le32 seq;
+} __attribute__ ((packed));
+
+struct ceph_mds_reply_dirfrag {
+ __le32 frag; /* fragment */
+ __le32 auth; /* auth mds, if this is a delegation point */
+ __le32 ndist; /* number of mds' this is replicated on */
+ __le32 dist[];
+} __attribute__ ((packed));
+
+/* file access modes */
+#define CEPH_FILE_MODE_PIN 0
+#define CEPH_FILE_MODE_RD 1
+#define CEPH_FILE_MODE_WR 2
+#define CEPH_FILE_MODE_RDWR 3 /* RD | WR */
+#define CEPH_FILE_MODE_LAZY 4 /* lazy io */
+#define CEPH_FILE_MODE_NUM 8 /* bc these are bit fields.. mostly */
+
+int ceph_flags_to_mode(int flags);
+
+
+/* capability bits */
+#define CEPH_CAP_PIN 1 /* no specific capabilities beyond the pin */
+
+/* generic cap bits */
+#define CEPH_CAP_GSHARED 1 /* client can reads */
+#define CEPH_CAP_GEXCL 2 /* client can read and update */
+#define CEPH_CAP_GCACHE 4 /* (file) client can cache reads */
+#define CEPH_CAP_GRD 8 /* (file) client can read */
+#define CEPH_CAP_GWR 16 /* (file) client can write */
+#define CEPH_CAP_GBUFFER 32 /* (file) client can buffer writes */
+#define CEPH_CAP_GWREXTEND 64 /* (file) client can extend EOF */
+#define CEPH_CAP_GLAZYIO 128 /* (file) client can perform lazy io */
+
+/* per-lock shift */
+#define CEPH_CAP_SAUTH 2
+#define CEPH_CAP_SLINK 4
+#define CEPH_CAP_SXATTR 6
+#define CEPH_CAP_SFILE 8 /* goes at the end (uses >2 cap bits) */
+
+#define CEPH_CAP_BITS 16
+
+/* composed values */
+#define CEPH_CAP_AUTH_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SAUTH)
+#define CEPH_CAP_AUTH_EXCL (CEPH_CAP_GEXCL << CEPH_CAP_SAUTH)
+#define CEPH_CAP_LINK_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SLINK)
+#define CEPH_CAP_LINK_EXCL (CEPH_CAP_GEXCL << CEPH_CAP_SLINK)
+#define CEPH_CAP_XATTR_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SXATTR)
+#define CEPH_CAP_XATTR_EXCL (CEPH_CAP_GEXCL << CEPH_CAP_SXATTR)
+#define CEPH_CAP_FILE(x) (x << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_EXCL (CEPH_CAP_GEXCL << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_CACHE (CEPH_CAP_GCACHE << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_RD (CEPH_CAP_GRD << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_WR (CEPH_CAP_GWR << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_BUFFER (CEPH_CAP_GBUFFER << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_WREXTEND (CEPH_CAP_GWREXTEND << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_LAZYIO (CEPH_CAP_GLAZYIO << CEPH_CAP_SFILE)
+
+/* cap masks (for getattr) */
+#define CEPH_STAT_CAP_INODE CEPH_CAP_PIN
+#define CEPH_STAT_CAP_TYPE CEPH_CAP_PIN /* mode >> 12 */
+#define CEPH_STAT_CAP_SYMLINK CEPH_CAP_PIN
+#define CEPH_STAT_CAP_UID CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_GID CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_MODE CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_NLINK CEPH_CAP_LINK_SHARED
+#define CEPH_STAT_CAP_LAYOUT CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_MTIME CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_SIZE CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_ATIME CEPH_CAP_FILE_SHARED /* fixme */
+#define CEPH_STAT_CAP_XATTR CEPH_CAP_XATTR_SHARED
+#define CEPH_STAT_CAP_INODE_ALL (CEPH_CAP_PIN | \
+ CEPH_CAP_AUTH_SHARED | \
+ CEPH_CAP_LINK_SHARED | \
+ CEPH_CAP_FILE_SHARED | \
+ CEPH_CAP_XATTR_SHARED)
+
+#define CEPH_CAP_ANY_SHARED (CEPH_CAP_AUTH_SHARED | \
+ CEPH_CAP_LINK_SHARED | \
+ CEPH_CAP_XATTR_SHARED | \
+ CEPH_CAP_FILE_SHARED)
+#define CEPH_CAP_ANY_RD (CEPH_CAP_ANY_SHARED | CEPH_CAP_FILE_RD | \
+ CEPH_CAP_FILE_CACHE)
+
+#define CEPH_CAP_ANY_EXCL (CEPH_CAP_AUTH_EXCL | \
+ CEPH_CAP_LINK_EXCL | \
+ CEPH_CAP_XATTR_EXCL | \
+ CEPH_CAP_FILE_EXCL)
+#define CEPH_CAP_ANY_FILE_WR (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER | \
+ 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)
+
+#define CEPH_CAP_LOCKS (CEPH_LOCK_IFILE | CEPH_LOCK_IAUTH | CEPH_LOCK_ILINK | \
+ CEPH_LOCK_IXATTR)
+
+int ceph_caps_for_mode(int mode);
+
+enum {
+ CEPH_CAP_OP_GRANT, /* mds->client grant */
+ CEPH_CAP_OP_REVOKE, /* mds->client revoke */
+ CEPH_CAP_OP_TRUNC, /* mds->client trunc notify */
+ CEPH_CAP_OP_EXPORT, /* mds has exported the cap */
+ CEPH_CAP_OP_IMPORT, /* mds has imported the cap */
+ CEPH_CAP_OP_UPDATE, /* client->mds update */
+ CEPH_CAP_OP_DROP, /* client->mds drop cap bits */
+ CEPH_CAP_OP_FLUSH, /* client->mds cap writeback */
+ CEPH_CAP_OP_FLUSH_ACK, /* mds->client flushed */
+ CEPH_CAP_OP_FLUSHSNAP, /* client->mds flush snapped metadata */
+ CEPH_CAP_OP_FLUSHSNAP_ACK, /* mds->client flushed snapped metadata */
+ CEPH_CAP_OP_RELEASE, /* client->mds release (clean) cap */
+ CEPH_CAP_OP_RENEW, /* client->mds renewal request */
+};
+
+extern const char *ceph_cap_op_name(int op);
+
+/*
+ * caps message, used for capability callbacks, acks, requests, etc.
+ */
+struct ceph_mds_caps {
+ __le32 op; /* CEPH_CAP_OP_* */
+ __le64 ino, realm;
+ __le64 cap_id;
+ __le32 seq, issue_seq;
+ __le32 caps, wanted, dirty; /* latest issued/wanted/dirty */
+ __le32 migrate_seq;
+ __le64 snap_follows;
+ __le32 snap_trace_len;
+
+ /* authlock */
+ __le32 uid, gid, mode;
+
+ /* linklock */
+ __le32 nlink;
+
+ /* xattrlock */
+ __le32 xattr_len;
+ __le64 xattr_version;
+
+ /* filelock */
+ __le64 size, max_size, truncate_size;
+ __le32 truncate_seq;
+ struct ceph_timespec mtime, atime, ctime;
+ struct ceph_file_layout layout;
+ __le32 time_warp_seq;
+} __attribute__ ((packed));
+
+/* cap release msg head */
+struct ceph_mds_cap_release {
+ __le32 num; /* number of cap_items that follow */
+} __attribute__ ((packed));
+
+struct ceph_mds_cap_item {
+ __le64 ino;
+ __le64 cap_id;
+ __le32 migrate_seq, seq;
+} __attribute__ ((packed));
+
+#define CEPH_MDS_LEASE_REVOKE 1 /* mds -> client */
+#define CEPH_MDS_LEASE_RELEASE 2 /* client -> mds */
+#define CEPH_MDS_LEASE_RENEW 3 /* client <-> mds */
+#define CEPH_MDS_LEASE_REVOKE_ACK 4 /* client -> mds */
+
+extern const char *ceph_lease_op_name(int o);
+
+/* lease msg header */
+struct ceph_mds_lease {
+ __u8 action; /* CEPH_MDS_LEASE_* */
+ __le16 mask; /* which lease */
+ __le64 ino;
+ __le64 first, last; /* snap range */
+ __le32 seq;
+ __le32 duration_ms; /* duration of renewal */
+} __attribute__ ((packed));
+/* followed by a __le32+string for dname */
+
+/* client reconnect */
+struct ceph_mds_cap_reconnect {
+ __le64 cap_id;
+ __le32 wanted;
+ __le32 issued;
+ __le64 size;
+ struct ceph_timespec mtime, atime;
+ __le64 snaprealm;
+ __le64 pathbase; /* base ino for our path to this ino */
+} __attribute__ ((packed));
+/* followed by encoded string */
+
+struct ceph_mds_snaprealm_reconnect {
+ __le64 ino; /* snap realm base */
+ __le64 seq; /* snap seq for this snap realm */
+ __le64 parent; /* parent realm */
+} __attribute__ ((packed));
+
+/*
+ * snaps
+ */
+enum {
+ CEPH_SNAP_OP_UPDATE, /* CREATE or DESTROY */
+ CEPH_SNAP_OP_CREATE,
+ CEPH_SNAP_OP_DESTROY,
+ CEPH_SNAP_OP_SPLIT,
+};
+
+extern const char *ceph_snap_op_name(int o);
+
+/* snap msg header */
+struct ceph_mds_snap_head {
+ __le32 op; /* CEPH_SNAP_OP_* */
+ __le64 split; /* ino to split off, if any */
+ __le32 num_split_inos; /* # inos belonging to new child realm */
+ __le32 num_split_realms; /* # child realms udner new child realm */
+ __le32 trace_len; /* size of snap trace blob */
+} __attribute__ ((packed));
+/* followed by split ino list, then split realms, then the trace blob */
+
+/*
+ * encode info about a snaprealm, as viewed by a client
+ */
+struct ceph_mds_snap_realm {
+ __le64 ino; /* ino */
+ __le64 created; /* snap: when created */
+ __le64 parent; /* ino: parent realm */
+ __le64 parent_since; /* snap: same parent since */
+ __le64 seq; /* snap: version */
+ __le32 num_snaps;
+ __le32 num_prior_parent_snaps;
+} __attribute__ ((packed));
+/* followed by my snap list, then prior parent snap list */
+
+#endif
diff --git a/fs/ceph/ceph_hash.c b/fs/ceph/ceph_hash.c
new file mode 100644
index 00000000000..bd570015d14
--- /dev/null
+++ b/fs/ceph/ceph_hash.c
@@ -0,0 +1,118 @@
+
+#include "types.h"
+
+/*
+ * Robert Jenkin's hash function.
+ * http://burtleburtle.net/bob/hash/evahash.html
+ * This is in the public domain.
+ */
+#define mix(a, b, c) \
+ do { \
+ a = a - b; a = a - c; a = a ^ (c >> 13); \
+ b = b - c; b = b - a; b = b ^ (a << 8); \
+ c = c - a; c = c - b; c = c ^ (b >> 13); \
+ a = a - b; a = a - c; a = a ^ (c >> 12); \
+ b = b - c; b = b - a; b = b ^ (a << 16); \
+ c = c - a; c = c - b; c = c ^ (b >> 5); \
+ a = a - b; a = a - c; a = a ^ (c >> 3); \
+ b = b - c; b = b - a; b = b ^ (a << 10); \
+ c = c - a; c = c - b; c = c ^ (b >> 15); \
+ } while (0)
+
+unsigned ceph_str_hash_rjenkins(const char *str, unsigned length)
+{
+ const unsigned char *k = (const unsigned char *)str;
+ __u32 a, b, c; /* the internal state */
+ __u32 len; /* how many key bytes still need mixing */
+
+ /* Set up the internal state */
+ len = length;
+ a = 0x9e3779b9; /* the golden ratio; an arbitrary value */
+ b = a;
+ c = 0; /* variable initialization of internal state */
+
+ /* handle most of the key */
+ while (len >= 12) {
+ a = a + (k[0] + ((__u32)k[1] << 8) + ((__u32)k[2] << 16) +
+ ((__u32)k[3] << 24));
+ b = b + (k[4] + ((__u32)k[5] << 8) + ((__u32)k[6] << 16) +
+ ((__u32)k[7] << 24));
+ c = c + (k[8] + ((__u32)k[9] << 8) + ((__u32)k[10] << 16) +
+ ((__u32)k[11] << 24));
+ mix(a, b, c);
+ k = k + 12;
+ len = len - 12;
+ }
+
+ /* handle the last 11 bytes */
+ c = c + length;
+ switch (len) { /* all the case statements fall through */
+ case 11:
+ c = c + ((__u32)k[10] << 24);
+ case 10:
+ c = c + ((__u32)k[9] << 16);
+ case 9:
+ c = c + ((__u32)k[8] << 8);
+ /* the first byte of c is reserved for the length */
+ case 8:
+ b = b + ((__u32)k[7] << 24);
+ case 7:
+ b = b + ((__u32)k[6] << 16);
+ case 6:
+ b = b + ((__u32)k[5] << 8);
+ case 5:
+ b = b + k[4];
+ case 4:
+ a = a + ((__u32)k[3] << 24);
+ case 3:
+ a = a + ((__u32)k[2] << 16);
+ case 2:
+ a = a + ((__u32)k[1] << 8);
+ case 1:
+ a = a + k[0];
+ /* case 0: nothing left to add */
+ }
+ mix(a, b, c);
+
+ return c;
+}
+
+/*
+ * linux dcache hash
+ */
+unsigned ceph_str_hash_linux(const char *str, unsigned length)
+{
+ unsigned long hash = 0;
+ unsigned char c;
+
+ while (length--) {
+ c = *str++;
+ hash = (hash + (c << 4) + (c >> 4)) * 11;
+ }
+ return hash;
+}
+
+
+unsigned ceph_str_hash(int type, const char *s, unsigned len)
+{
+ switch (type) {
+ case CEPH_STR_HASH_LINUX:
+ return ceph_str_hash_linux(s, len);
+ case CEPH_STR_HASH_RJENKINS:
+ return ceph_str_hash_rjenkins(s, len);
+ default:
+ return -1;
+ }
+}
+
+const char *ceph_str_hash_name(int type)
+{
+ switch (type) {
+ case CEPH_STR_HASH_LINUX:
+ return "linux";
+ case CEPH_STR_HASH_RJENKINS:
+ return "rjenkins";
+ default:
+ return "unknown";
+ }
+}
diff --git a/fs/ceph/ceph_hash.h b/fs/ceph/ceph_hash.h
new file mode 100644
index 00000000000..5ac470c433c
--- /dev/null
+++ b/fs/ceph/ceph_hash.h
@@ -0,0 +1,13 @@
+#ifndef _FS_CEPH_HASH_H
+#define _FS_CEPH_HASH_H
+
+#define CEPH_STR_HASH_LINUX 0x1 /* linux dcache hash */
+#define CEPH_STR_HASH_RJENKINS 0x2 /* robert jenkins' */
+
+extern unsigned ceph_str_hash_linux(const char *s, unsigned len);
+extern unsigned ceph_str_hash_rjenkins(const char *s, unsigned len);
+
+extern unsigned ceph_str_hash(int type, const char *s, unsigned len);
+extern const char *ceph_str_hash_name(int type);
+
+#endif
diff --git a/fs/ceph/ceph_strings.c b/fs/ceph/ceph_strings.c
new file mode 100644
index 00000000000..8e4be6a80c6
--- /dev/null
+++ b/fs/ceph/ceph_strings.c
@@ -0,0 +1,176 @@
+/*
+ * Ceph string constants
+ */
+#include "types.h"
+
+const char *ceph_entity_type_name(int type)
+{
+ switch (type) {
+ case CEPH_ENTITY_TYPE_MDS: return "mds";
+ case CEPH_ENTITY_TYPE_OSD: return "osd";
+ case CEPH_ENTITY_TYPE_MON: return "mon";
+ case CEPH_ENTITY_TYPE_CLIENT: return "client";
+ case CEPH_ENTITY_TYPE_ADMIN: return "admin";
+ case CEPH_ENTITY_TYPE_AUTH: return "auth";
+ default: return "unknown";
+ }
+}
+
+const char *ceph_osd_op_name(int op)
+{
+ switch (op) {
+ case CEPH_OSD_OP_READ: return "read";
+ case CEPH_OSD_OP_STAT: return "stat";
+
+ case CEPH_OSD_OP_MASKTRUNC: return "masktrunc";
+
+ case CEPH_OSD_OP_WRITE: return "write";
+ case CEPH_OSD_OP_DELETE: return "delete";
+ case CEPH_OSD_OP_TRUNCATE: return "truncate";
+ case CEPH_OSD_OP_ZERO: return "zero";
+ case CEPH_OSD_OP_WRITEFULL: return "writefull";
+
+ case CEPH_OSD_OP_APPEND: return "append";
+ case CEPH_OSD_OP_STARTSYNC: return "startsync";
+ case CEPH_OSD_OP_SETTRUNC: return "settrunc";
+ case CEPH_OSD_OP_TRIMTRUNC: return "trimtrunc";
+
+ case CEPH_OSD_OP_TMAPUP: return "tmapup";
+ case CEPH_OSD_OP_TMAPGET: return "tmapget";
+ case CEPH_OSD_OP_TMAPPUT: return "tmapput";
+
+ case CEPH_OSD_OP_GETXATTR: return "getxattr";
+ case CEPH_OSD_OP_GETXATTRS: return "getxattrs";
+ case CEPH_OSD_OP_SETXATTR: return "setxattr";
+ case CEPH_OSD_OP_SETXATTRS: return "setxattrs";
+ case CEPH_OSD_OP_RESETXATTRS: return "resetxattrs";
+ case CEPH_OSD_OP_RMXATTR: return "rmxattr";
+
+ case CEPH_OSD_OP_PULL: return "pull";
+ case CEPH_OSD_OP_PUSH: return "push";
+ case CEPH_OSD_OP_BALANCEREADS: return "balance-reads";
+ case CEPH_OSD_OP_UNBALANCEREADS: return "unbalance-reads";
+ case CEPH_OSD_OP_SCRUB: return "scrub";
+
+ case CEPH_OSD_OP_WRLOCK: return "wrlock";
+ case CEPH_OSD_OP_WRUNLOCK: return "wrunlock";
+ case CEPH_OSD_OP_RDLOCK: return "rdlock";
+ case CEPH_OSD_OP_RDUNLOCK: return "rdunlock";
+ case CEPH_OSD_OP_UPLOCK: return "uplock";
+ case CEPH_OSD_OP_DNLOCK: return "dnlock";
+
+ case CEPH_OSD_OP_CALL: return "call";
+
+ case CEPH_OSD_OP_PGLS: return "pgls";
+ }
+ return "???";
+}
+
+const char *ceph_mds_state_name(int s)
+{
+ switch (s) {
+ /* down and out */
+ case CEPH_MDS_STATE_DNE: return "down:dne";
+ case CEPH_MDS_STATE_STOPPED: return "down:stopped";
+ /* up and out */
+ case CEPH_MDS_STATE_BOOT: return "up:boot";
+ case CEPH_MDS_STATE_STANDBY: return "up:standby";
+ case CEPH_MDS_STATE_STANDBY_REPLAY: return "up:standby-replay";
+ case CEPH_MDS_STATE_CREATING: return "up:creating";
+ case CEPH_MDS_STATE_STARTING: return "up:starting";
+ /* up and in */
+ case CEPH_MDS_STATE_REPLAY: return "up:replay";
+ case CEPH_MDS_STATE_RESOLVE: return "up:resolve";
+ case CEPH_MDS_STATE_RECONNECT: return "up:reconnect";
+ case CEPH_MDS_STATE_REJOIN: return "up:rejoin";
+ case CEPH_MDS_STATE_CLIENTREPLAY: return "up:clientreplay";
+ case CEPH_MDS_STATE_ACTIVE: return "up:active";
+ case CEPH_MDS_STATE_STOPPING: return "up:stopping";
+ }
+ return "???";
+}
+
+const char *ceph_session_op_name(int op)
+{
+ switch (op) {
+ case CEPH_SESSION_REQUEST_OPEN: return "request_open";
+ case CEPH_SESSION_OPEN: return "open";
+ case CEPH_SESSION_REQUEST_CLOSE: return "request_close";
+ case CEPH_SESSION_CLOSE: return "close";
+ case CEPH_SESSION_REQUEST_RENEWCAPS: return "request_renewcaps";
+ case CEPH_SESSION_RENEWCAPS: return "renewcaps";
+ case CEPH_SESSION_STALE: return "stale";
+ case CEPH_SESSION_RECALL_STATE: return "recall_state";
+ }
+ return "???";
+}
+
+const char *ceph_mds_op_name(int op)
+{
+ switch (op) {
+ case CEPH_MDS_OP_LOOKUP: return "lookup";
+ case CEPH_MDS_OP_LOOKUPHASH: return "lookuphash";
+ case CEPH_MDS_OP_LOOKUPPARENT: return "lookupparent";
+ case CEPH_MDS_OP_GETATTR: return "getattr";
+ case CEPH_MDS_OP_SETXATTR: return "setxattr";
+ case CEPH_MDS_OP_SETATTR: return "setattr";
+ case CEPH_MDS_OP_RMXATTR: return "rmxattr";
+ case CEPH_MDS_OP_READDIR: return "readdir";
+ case CEPH_MDS_OP_MKNOD: return "mknod";
+ case CEPH_MDS_OP_LINK: return "link";
+ case CEPH_MDS_OP_UNLINK: return "unlink";
+ case CEPH_MDS_OP_RENAME: return "rename";
+ case CEPH_MDS_OP_MKDIR: return "mkdir";
+ case CEPH_MDS_OP_RMDIR: return "rmdir";
+ case CEPH_MDS_OP_SYMLINK: return "symlink";
+ case CEPH_MDS_OP_CREATE: return "create";
+ case CEPH_MDS_OP_OPEN: return "open";
+ case CEPH_MDS_OP_LOOKUPSNAP: return "lookupsnap";
+ case CEPH_MDS_OP_LSSNAP: return "lssnap";
+ case CEPH_MDS_OP_MKSNAP: return "mksnap";
+ case CEPH_MDS_OP_RMSNAP: return "rmsnap";
+ }
+ return "???";
+}
+
+const char *ceph_cap_op_name(int op)
+{
+ switch (op) {
+ case CEPH_CAP_OP_GRANT: return "grant";
+ case CEPH_CAP_OP_REVOKE: return "revoke";
+ case CEPH_CAP_OP_TRUNC: return "trunc";
+ case CEPH_CAP_OP_EXPORT: return "export";
+ case CEPH_CAP_OP_IMPORT: return "import";
+ case CEPH_CAP_OP_UPDATE: return "update";
+ case CEPH_CAP_OP_DROP: return "drop";
+ case CEPH_CAP_OP_FLUSH: return "flush";
+ case CEPH_CAP_OP_FLUSH_ACK: return "flush_ack";
+ case CEPH_CAP_OP_FLUSHSNAP: return "flushsnap";
+ case CEPH_CAP_OP_FLUSHSNAP_ACK: return "flushsnap_ack";
+ case CEPH_CAP_OP_RELEASE: return "release";
+ case CEPH_CAP_OP_RENEW: return "renew";
+ }
+ return "???";
+}
+
+const char *ceph_lease_op_name(int o)
+{
+ switch (o) {
+ case CEPH_MDS_LEASE_REVOKE: return "revoke";
+ case CEPH_MDS_LEASE_RELEASE: return "release";
+ case CEPH_MDS_LEASE_RENEW: return "renew";
+ case CEPH_MDS_LEASE_REVOKE_ACK: return "revoke_ack";
+ }
+ return "???";
+}
+
+const char *ceph_snap_op_name(int o)
+{
+ switch (o) {
+ case CEPH_SNAP_OP_UPDATE: return "update";
+ case CEPH_SNAP_OP_CREATE: return "create";
+ case CEPH_SNAP_OP_DESTROY: return "destroy";
+ case CEPH_SNAP_OP_SPLIT: return "split";
+ }
+ return "???";
+}
diff --git a/fs/ceph/crush/crush.c b/fs/ceph/crush/crush.c
new file mode 100644
index 00000000000..fabd302e577
--- /dev/null
+++ b/fs/ceph/crush/crush.c
@@ -0,0 +1,151 @@
+
+#ifdef __KERNEL__
+# include <linux/slab.h>
+#else
+# include <stdlib.h>
+# include <assert.h>
+# define kfree(x) do { if (x) free(x); } while (0)
+# define BUG_ON(x) assert(!(x))
+#endif
+
+#include "crush.h"
+
+const char *crush_bucket_alg_name(int alg)
+{
+ switch (alg) {
+ case CRUSH_BUCKET_UNIFORM: return "uniform";
+ case CRUSH_BUCKET_LIST: return "list";
+ case CRUSH_BUCKET_TREE: return "tree";
+ case CRUSH_BUCKET_STRAW: return "straw";
+ default: return "unknown";
+ }
+}
+
+/**
+ * crush_get_bucket_item_weight - Get weight of an item in given bucket
+ * @b: bucket pointer
+ * @p: item index in bucket
+ */
+int crush_get_bucket_item_weight(struct crush_bucket *b, int p)
+{
+ if (p >= b->size)
+ return 0;
+
+ switch (b->alg) {
+ case CRUSH_BUCKET_UNIFORM:
+ return ((struct crush_bucket_uniform *)b)->item_weight;
+ case CRUSH_BUCKET_LIST:
+ return ((struct crush_bucket_list *)b)->item_weights[p];
+ case CRUSH_BUCKET_TREE:
+ if (p & 1)
+ return ((struct crush_bucket_tree *)b)->node_weights[p];
+ return 0;
+ case CRUSH_BUCKET_STRAW:
+ return ((struct crush_bucket_straw *)b)->item_weights[p];
+ }
+ return 0;
+}
+
+/**
+ * crush_calc_parents - Calculate parent vectors for the given crush map.
+ * @map: crush_map pointer
+ */
+void crush_calc_parents(struct crush_map *map)
+{
+ int i, b, c;
+
+ for (b = 0; b < map->max_buckets; b++) {
+ if (map->buckets[b] == NULL)
+ continue;
+ for (i = 0; i < map->buckets[b]->size; i++) {
+ c = map->buckets[b]->items[i];
+ BUG_ON(c >= map->max_devices ||
+ c < -map->max_buckets);
+ if (c >= 0)
+ map->device_parents[c] = map->buckets[b]->id;
+ else
+ map->bucket_parents[-1-c] = map->buckets[b]->id;
+ }
+ }
+}
+
+void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b)
+{
+ kfree(b->h.perm);
+ kfree(b->h.items);
+ kfree(b);
+}
+
+void crush_destroy_bucket_list(struct crush_bucket_list *b)
+{
+ kfree(b->item_weights);
+ kfree(b->sum_weights);
+ kfree(b->h.perm);
+ kfree(b->h.items);
+ kfree(b);
+}
+
+void crush_destroy_bucket_tree(struct crush_bucket_tree *b)
+{
+ kfree(b->node_weights);
+ kfree(b);
+}
+
+void crush_destroy_bucket_straw(struct crush_bucket_straw *b)
+{
+ kfree(b->straws);
+ kfree(b->item_weights);
+ kfree(b->h.perm);
+ kfree(b->h.items);
+ kfree(b);
+}
+
+void crush_destroy_bucket(struct crush_bucket *b)
+{
+ switch (b->alg) {
+ case CRUSH_BUCKET_UNIFORM:
+ crush_destroy_bucket_uniform((struct crush_bucket_uniform *)b);
+ break;
+ case CRUSH_BUCKET_LIST:
+ crush_destroy_bucket_list((struct crush_bucket_list *)b);
+ break;
+ case CRUSH_BUCKET_TREE:
+ crush_destroy_bucket_tree((struct crush_bucket_tree *)b);
+ break;
+ case CRUSH_BUCKET_STRAW:
+ crush_destroy_bucket_straw((struct crush_bucket_straw *)b);
+ break;
+ }
+}
+
+/**
+ * crush_destroy - Destroy a crush_map
+ * @map: crush_map pointer
+ */
+void crush_destroy(struct crush_map *map)
+{
+ int b;
+
+ /* buckets */
+ if (map->buckets) {
+ for (b = 0; b < map->max_buckets; b++) {
+ if (map->buckets[b] == NULL)
+ continue;
+ crush_destroy_bucket(map->buckets[b]);
+ }
+ kfree(map->buckets);
+ }
+
+ /* rules */
+ if (map->rules) {
+ for (b = 0; b < map->max_rules; b++)
+ kfree(map->rules[b]);
+ kfree(map->rules);
+ }
+
+ kfree(map->bucket_parents);
+ kfree(map->device_parents);
+ kfree(map);
+}
+
+
diff --git a/fs/ceph/crush/crush.h b/fs/ceph/crush/crush.h
new file mode 100644
index 00000000000..dcd7e752370
--- /dev/null
+++ b/fs/ceph/crush/crush.h
@@ -0,0 +1,180 @@
+#ifndef _CRUSH_CRUSH_H
+#define _CRUSH_CRUSH_H
+
+#include <linux/types.h>
+
+/*
+ * CRUSH is a pseudo-random data distribution algorithm that
+ * efficiently distributes input values (typically, data objects)
+ * across a heterogeneous, structured storage cluster.
+ *
+ * The algorithm was originally described in detail in this paper
+ * (although the algorithm has evolved somewhat since then):
+ *
+ * http://www.ssrc.ucsc.edu/Papers/weil-sc06.pdf
+ *
+ * LGPL2
+ */
+
+
+#define CRUSH_MAGIC 0x00010000ul /* for detecting algorithm revisions */
+
+
+#define CRUSH_MAX_DEPTH 10 /* max crush hierarchy depth */
+#define CRUSH_MAX_SET 10 /* max size of a mapping result */
+
+
+/*
+ * CRUSH uses user-defined "rules" to describe how inputs should be
+ * mapped to devices. A rule consists of sequence of steps to perform
+ * to generate the set of output devices.
+ */
+struct crush_rule_step {
+ __u32 op;
+ __s32 arg1;
+ __s32 arg2;
+};
+
+/* step op codes */
+enum {
+ CRUSH_RULE_NOOP = 0,
+ CRUSH_RULE_TAKE = 1, /* arg1 = value to start with */
+ CRUSH_RULE_CHOOSE_FIRSTN = 2, /* arg1 = num items to pick */
+ /* arg2 = type */
+ CRUSH_RULE_CHOOSE_INDEP = 3, /* same */
+ CRUSH_RULE_EMIT = 4, /* no args */
+ CRUSH_RULE_CHOOSE_LEAF_FIRSTN = 6,
+ CRUSH_RULE_CHOOSE_LEAF_INDEP = 7,
+};
+
+/*
+ * for specifying choose num (arg1) relative to the max parameter
+ * passed to do_rule
+ */
+#define CRUSH_CHOOSE_N 0
+#define CRUSH_CHOOSE_N_MINUS(x) (-(x))
+
+/*
+ * The rule mask is used to describe what the rule is intended for.
+ * Given a ruleset and size of output set, we search through the
+ * rule list for a matching rule_mask.
+ */
+struct crush_rule_mask {
+ __u8 ruleset;
+ __u8 type;
+ __u8 min_size;
+ __u8 max_size;
+};
+
+struct crush_rule {
+ __u32 len;
+ struct crush_rule_mask mask;
+ struct crush_rule_step steps[0];
+};
+
+#define crush_rule_size(len) (sizeof(struct crush_rule) + \
+ (len)*sizeof(struct crush_rule_step))
+
+
+
+/*
+ * A bucket is a named container of other items (either devices or
+ * other buckets). Items within a bucket are chosen using one of a
+ * few different algorithms. The table summarizes how the speed of
+ * each option measures up against mapping stability when items are
+ * added or removed.
+ *
+ * Bucket Alg Speed Additions Removals
+ * ------------------------------------------------
+ * uniform O(1) poor poor
+ * list O(n) optimal poor
+ * tree O(log n) good good
+ * straw O(n) optimal optimal
+ */
+enum {
+ CRUSH_BUCKET_UNIFORM = 1,
+ CRUSH_BUCKET_LIST = 2,
+ CRUSH_BUCKET_TREE = 3,
+ CRUSH_BUCKET_STRAW = 4
+};
+extern const char *crush_bucket_alg_name(int alg);
+
+struct crush_bucket {
+ __s32 id; /* this'll be negative */
+ __u16 type; /* non-zero; type=0 is reserved for devices */
+ __u8 alg; /* one of CRUSH_BUCKET_* */
+ __u8 hash; /* which hash function to use, CRUSH_HASH_* */
+ __u32 weight; /* 16-bit fixed point */
+ __u32 size; /* num items */
+ __s32 *items;
+
+ /*
+ * cached random permutation: used for uniform bucket and for
+ * the linear search fallback for the other bucket types.
+ */
+ __u32 perm_x; /* @x for which *perm is defined */
+ __u32 perm_n; /* num elements of *perm that are permuted/defined */
+ __u32 *perm;
+};
+
+struct crush_bucket_uniform {
+ struct crush_bucket h;
+ __u32 item_weight; /* 16-bit fixed point; all items equally weighted */
+};
+
+struct crush_bucket_list {
+ struct crush_bucket h;
+ __u32 *item_weights; /* 16-bit fixed point */
+ __u32 *sum_weights; /* 16-bit fixed point. element i is sum
+ of weights 0..i, inclusive */
+};
+
+struct crush_bucket_tree {
+ struct crush_bucket h; /* note: h.size is _tree_ size, not number of
+ actual items */
+ __u8 num_nodes;
+ __u32 *node_weights;
+};
+
+struct crush_bucket_straw {
+ struct crush_bucket h;
+ __u32 *item_weights; /* 16-bit fixed point */
+ __u32 *straws; /* 16-bit fixed point */
+};
+
+
+
+/*
+ * CRUSH map includes all buckets, rules, etc.
+ */
+struct crush_map {
+ struct crush_bucket **buckets;
+ struct crush_rule **rules;
+
+ /*
+ * Parent pointers to identify the parent bucket a device or
+ * bucket in the hierarchy. If an item appears more than
+ * once, this is the _last_ time it appeared (where buckets
+ * are processed in bucket id order, from -1 on down to
+ * -max_buckets.
+ */
+ __u32 *bucket_parents;
+ __u32 *device_parents;
+
+ __s32 max_buckets;
+ __u32 max_rules;
+ __s32 max_devices;
+};
+
+
+/* crush.c */
+extern int crush_get_bucket_item_weight(struct crush_bucket *b, int pos);
+extern void crush_calc_parents(struct crush_map *map);
+extern void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b);
+extern void crush_destroy_bucket_list(struct crush_bucket_list *b);
+extern void crush_destroy_bucket_tree(struct crush_bucket_tree *b);
+extern void crush_destroy_bucket_straw(struct crush_bucket_straw *b);
+extern void crush_destroy_bucket(struct crush_bucket *b);
+extern void crush_destroy(struct crush_map *map);
+
+#endif
diff --git a/fs/ceph/crush/hash.c b/fs/ceph/crush/hash.c
new file mode 100644
index 00000000000..5873aed694b
--- /dev/null
+++ b/fs/ceph/crush/hash.c
@@ -0,0 +1,149 @@
+
+#include <linux/types.h>
+#include "hash.h"
+
+/*
+ * Robert Jenkins' function for mixing 32-bit values
+ * http://burtleburtle.net/bob/hash/evahash.html
+ * a, b = random bits, c = input and output
+ */
+#define crush_hashmix(a, b, c) do { \
+ a = a-b; a = a-c; a = a^(c>>13); \
+ b = b-c; b = b-a; b = b^(a<<8); \
+ c = c-a; c = c-b; c = c^(b>>13); \
+ a = a-b; a = a-c; a = a^(c>>12); \
+ b = b-c; b = b-a; b = b^(a<<16); \
+ c = c-a; c = c-b; c = c^(b>>5); \
+ a = a-b; a = a-c; a = a^(c>>3); \
+ b = b-c; b = b-a; b = b^(a<<10); \
+ c = c-a; c = c-b; c = c^(b>>15); \
+ } while (0)
+
+#define crush_hash_seed 1315423911
+
+static __u32 crush_hash32_rjenkins1(__u32 a)
+{
+ __u32 hash = crush_hash_seed ^ a;
+ __u32 b = a;
+ __u32 x = 231232;
+ __u32 y = 1232;
+ crush_hashmix(b, x, hash);
+ crush_hashmix(y, a, hash);
+ return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_2(__u32 a, __u32 b)
+{
+ __u32 hash = crush_hash_seed ^ a ^ b;
+ __u32 x = 231232;
+ __u32 y = 1232;
+ crush_hashmix(a, b, hash);
+ crush_hashmix(x, a, hash);
+ crush_hashmix(b, y, hash);
+ return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_3(__u32 a, __u32 b, __u32 c)
+{
+ __u32 hash = crush_hash_seed ^ a ^ b ^ c;
+ __u32 x = 231232;
+ __u32 y = 1232;
+ crush_hashmix(a, b, hash);
+ crush_hashmix(c, x, hash);
+ crush_hashmix(y, a, hash);
+ crush_hashmix(b, x, hash);
+ crush_hashmix(y, c, hash);
+ return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_4(__u32 a, __u32 b, __u32 c, __u32 d)
+{
+ __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d;
+ __u32 x = 231232;
+ __u32 y = 1232;
+ crush_hashmix(a, b, hash);
+ crush_hashmix(c, d, hash);
+ crush_hashmix(a, x, hash);
+ crush_hashmix(y, b, hash);
+ crush_hashmix(c, x, hash);
+ crush_hashmix(y, d, hash);
+ return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_5(__u32 a, __u32 b, __u32 c, __u32 d,
+ __u32 e)
+{
+ __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e;
+ __u32 x = 231232;
+ __u32 y = 1232;
+ crush_hashmix(a, b, hash);
+ crush_hashmix(c, d, hash);
+ crush_hashmix(e, x, hash);
+ crush_hashmix(y, a, hash);
+ crush_hashmix(b, x, hash);
+ crush_hashmix(y, c, hash);
+ crush_hashmix(d, x, hash);
+ crush_hashmix(y, e, hash);
+ return hash;
+}
+
+
+__u32 crush_hash32(int type, __u32 a)
+{
+ switch (type) {
+ case CRUSH_HASH_RJENKINS1:
+ return crush_hash32_rjenkins1(a);
+ default:
+ return 0;
+ }
+}
+
+__u32 crush_hash32_2(int type, __u32 a, __u32 b)
+{
+ switch (type) {
+ case CRUSH_HASH_RJENKINS1:
+ return crush_hash32_rjenkins1_2(a, b);
+ default:
+ return 0;
+ }
+}
+
+__u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c)
+{
+ switch (type) {
+ case CRUSH_HASH_RJENKINS1:
+ return crush_hash32_rjenkins1_3(a, b, c);
+ default:
+ return 0;
+ }
+}
+
+__u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d)
+{
+ switch (type) {
+ case CRUSH_HASH_RJENKINS1:
+ return crush_hash32_rjenkins1_4(a, b, c, d);
+ default:
+ return 0;
+ }
+}
+
+__u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d, __u32 e)
+{
+ switch (type) {
+ case CRUSH_HASH_RJENKINS1:
+ return crush_hash32_rjenkins1_5(a, b, c, d, e);
+ default:
+ return 0;
+ }
+}
+
+const char *crush_hash_name(int type)
+{
+ switch (type) {
+ case CRUSH_HASH_RJENKINS1:
+ return "rjenkins1";
+ default:
+ return "unknown";
+ }
+}
diff --git a/fs/ceph/crush/hash.h b/fs/ceph/crush/hash.h
new file mode 100644
index 00000000000..ff48e110e4b
--- /dev/null
+++ b/fs/ceph/crush/hash.h
@@ -0,0 +1,17 @@
+#ifndef _CRUSH_HASH_H
+#define _CRUSH_HASH_H
+
+#define CRUSH_HASH_RJENKINS1 0
+
+#define CRUSH_HASH_DEFAULT CRUSH_HASH_RJENKINS1
+
+extern const char *crush_hash_name(int type);
+
+extern __u32 crush_hash32(int type, __u32 a);
+extern __u32 crush_hash32_2(int type, __u32 a, __u32 b);
+extern __u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c);
+extern __u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d);
+extern __u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d,
+ __u32 e);
+
+#endif
diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c
new file mode 100644
index 00000000000..9ba54efb654
--- /dev/null
+++ b/fs/ceph/crush/mapper.c
@@ -0,0 +1,596 @@
+
+#ifdef __KERNEL__
+# include <linux/string.h>
+# include <linux/slab.h>
+# include <linux/bug.h>
+# include <linux/kernel.h>
+# ifndef dprintk
+# define dprintk(args...)
+# endif
+#else
+# include <string.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <assert.h>
+# define BUG_ON(x) assert(!(x))
+# define dprintk(args...) /* printf(args) */
+# define kmalloc(x, f) malloc(x)
+# define kfree(x) free(x)
+#endif
+
+#include "crush.h"
+#include "hash.h"
+
+/*
+ * Implement the core CRUSH mapping algorithm.
+ */
+
+/**
+ * crush_find_rule - find a crush_rule id for a given ruleset, type, and size.
+ * @map: the crush_map
+ * @ruleset: the storage ruleset id (user defined)
+ * @type: storage ruleset type (user defined)
+ * @size: output set size
+ */
+int crush_find_rule(struct crush_map *map, int ruleset, int type, int size)
+{
+ int i;
+
+ for (i = 0; i < map->max_rules; i++) {
+ if (map->rules[i] &&
+ map->rules[i]->mask.ruleset == ruleset &&
+ map->rules[i]->mask.type == type &&
+ map->rules[i]->mask.min_size <= size &&
+ map->rules[i]->mask.max_size >= size)
+ return i;
+ }
+ return -1;
+}
+
+
+/*
+ * bucket choose methods
+ *
+ * For each bucket algorithm, we have a "choose" method that, given a
+ * crush input @x and replica position (usually, position in output set) @r,
+ * will produce an item in the bucket.
+ */
+
+/*
+ * Choose based on a random permutation of the bucket.
+ *
+ * We used to use some prime number arithmetic to do this, but it
+ * wasn't very random, and had some other bad behaviors. Instead, we
+ * calculate an actual random permutation of the bucket members.
+ * Since this is expensive, we optimize for the r=0 case, which
+ * captures the vast majority of calls.
+ */
+static int bucket_perm_choose(struct crush_bucket *bucket,
+ int x, int r)
+{
+ unsigned pr = r % bucket->size;
+ unsigned i, s;
+
+ /* start a new permutation if @x has changed */
+ if (bucket->perm_x != x || bucket->perm_n == 0) {
+ dprintk("bucket %d new x=%d\n", bucket->id, x);
+ bucket->perm_x = x;
+
+ /* optimize common r=0 case */
+ if (pr == 0) {
+ s = crush_hash32_3(bucket->hash, x, bucket->id, 0) %
+ bucket->size;
+ bucket->perm[0] = s;
+ bucket->perm_n = 0xffff; /* magic value, see below */
+ goto out;
+ }
+
+ for (i = 0; i < bucket->size; i++)
+ bucket->perm[i] = i;
+ bucket->perm_n = 0;
+ } else if (bucket->perm_n == 0xffff) {
+ /* clean up after the r=0 case above */
+ for (i = 1; i < bucket->size; i++)
+ bucket->perm[i] = i;
+ bucket->perm[bucket->perm[0]] = 0;
+ bucket->perm_n = 1;
+ }
+
+ /* calculate permutation up to pr */
+ for (i = 0; i < bucket->perm_n; i++)
+ dprintk(" perm_choose have %d: %d\n", i, bucket->perm[i]);
+ while (bucket->perm_n <= pr) {
+ unsigned p = bucket->perm_n;
+ /* no point in swapping the final entry */
+ if (p < bucket->size - 1) {
+ i = crush_hash32_3(bucket->hash, x, bucket->id, p) %
+ (bucket->size - p);
+ if (i) {
+ unsigned t = bucket->perm[p + i];
+ bucket->perm[p + i] = bucket->perm[p];
+ bucket->perm[p] = t;
+ }
+ dprintk(" perm_choose swap %d with %d\n", p, p+i);
+ }
+ bucket->perm_n++;
+ }
+ for (i = 0; i < bucket->size; i++)
+ dprintk(" perm_choose %d: %d\n", i, bucket->perm[i]);
+
+ s = bucket->perm[pr];
+out:
+ dprintk(" perm_choose %d sz=%d x=%d r=%d (%d) s=%d\n", bucket->id,
+ bucket->size, x, r, pr, s);
+ return bucket->items[s];
+}
+
+/* uniform */
+static int bucket_uniform_choose(struct crush_bucket_uniform *bucket,
+ int x, int r)
+{
+ return bucket_perm_choose(&bucket->h, x, r);
+}
+
+/* list */
+static int bucket_list_choose(struct crush_bucket_list *bucket,
+ int x, int r)
+{
+ int i;
+
+ for (i = bucket->h.size-1; i >= 0; i--) {
+ __u64 w = crush_hash32_4(bucket->h.hash,x, bucket->h.items[i],
+ r, bucket->h.id);
+ w &= 0xffff;
+ dprintk("list_choose i=%d x=%d r=%d item %d weight %x "
+ "sw %x rand %llx",
+ i, x, r, bucket->h.items[i], bucket->item_weights[i],
+ bucket->sum_weights[i], w);
+ w *= bucket->sum_weights[i];
+ w = w >> 16;
+ /*dprintk(" scaled %llx\n", w);*/
+ if (w < bucket->item_weights[i])
+ return bucket->h.items[i];
+ }
+
+ BUG_ON(1);
+ return 0;
+}
+
+
+/* (binary) tree */
+static int height(int n)
+{
+ int h = 0;
+ while ((n & 1) == 0) {
+ h++;
+ n = n >> 1;
+ }
+ return h;
+}
+
+static int left(int x)
+{
+ int h = height(x);
+ return x - (1 << (h-1));
+}
+
+static int right(int x)
+{
+ int h = height(x);
+ return x + (1 << (h-1));
+}
+
+static int terminal(int x)
+{
+ return x & 1;
+}
+
+static int bucket_tree_choose(struct crush_bucket_tree *bucket,
+ int x, int r)
+{
+ int n, l;
+ __u32 w;
+ __u64 t;
+
+ /* start at root */
+ n = bucket->num_nodes >> 1;
+
+ while (!terminal(n)) {
+ /* pick point in [0, w) */
+ w = bucket->node_weights[n];
+ t = (__u64)crush_hash32_4(bucket->h.hash, x, n, r,
+ bucket->h.id) * (__u64)w;
+ t = t >> 32;
+
+ /* descend to the left or right? */
+ l = left(n);
+ if (t < bucket->node_weights[l])
+ n = l;
+ else
+ n = right(n);
+ }
+
+ return bucket->h.items[n >> 1];
+}
+
+
+/* straw */
+
+static int bucket_straw_choose(struct crush_bucket_straw *bucket,
+ int x, int r)
+{
+ int i;
+ int high = 0;
+ __u64 high_draw = 0;
+ __u64 draw;
+
+ for (i = 0; i < bucket->h.size; i++) {
+ draw = crush_hash32_3(bucket->h.hash, x, bucket->h.items[i], r);
+ draw &= 0xffff;
+ draw *= bucket->straws[i];
+ if (i == 0 || draw > high_draw) {
+ high = i;
+ high_draw = draw;
+ }
+ }
+ return bucket->h.items[high];
+}
+
+static int crush_bucket_choose(struct crush_bucket *in, int x, int r)
+{
+ dprintk("choose %d x=%d r=%d\n", in->id, x, r);
+ switch (in->alg) {
+ case CRUSH_BUCKET_UNIFORM:
+ return bucket_uniform_choose((struct crush_bucket_uniform *)in,
+ x, r);
+ case CRUSH_BUCKET_LIST:
+ return bucket_list_choose((struct crush_bucket_list *)in,
+ x, r);
+ case CRUSH_BUCKET_TREE:
+ return bucket_tree_choose((struct crush_bucket_tree *)in,
+ x, r);
+ case CRUSH_BUCKET_STRAW:
+ return bucket_straw_choose((struct crush_bucket_straw *)in,
+ x, r);
+ default:
+ BUG_ON(1);
+ return in->items[0];
+ }
+}
+
+/*
+ * true if device is marked "out" (failed, fully offloaded)
+ * of the cluster
+ */
+static int is_out(struct crush_map *map, __u32 *weight, int item, int x)
+{
+ if (weight[item] >= 0x1000)
+ return 0;
+ if (weight[item] == 0)
+ return 1;
+ if ((crush_hash32_2(CRUSH_HASH_RJENKINS1, x, item) & 0xffff)
+ < weight[item])
+ return 0;
+ return 1;
+}
+
+/**
+ * crush_choose - choose numrep distinct items of given type
+ * @map: the crush_map
+ * @bucket: the bucket we are choose an item from
+ * @x: crush input value
+ * @numrep: the number of items to choose
+ * @type: the type of item to choose
+ * @out: pointer to output vector
+ * @outpos: our position in that vector
+ * @firstn: true if choosing "first n" items, false if choosing "indep"
+ * @recurse_to_leaf: true if we want one device under each item of given type
+ * @out2: second output vector for leaf items (if @recurse_to_leaf)
+ */
+static int crush_choose(struct crush_map *map,
+ struct crush_bucket *bucket,
+ __u32 *weight,
+ int x, int numrep, int type,
+ int *out, int outpos,
+ int firstn, int recurse_to_leaf,
+ int *out2)
+{
+ int rep;
+ int ftotal, flocal;
+ int retry_descent, retry_bucket, skip_rep;
+ struct crush_bucket *in = bucket;
+ int r;
+ int i;
+ int item = 0;
+ int itemtype;
+ int collide, reject;
+ const int orig_tries = 5; /* attempts before we fall back to search */
+ dprintk("choose bucket %d x %d outpos %d\n", bucket->id, x, outpos);
+
+ for (rep = outpos; rep < numrep; rep++) {
+ /* keep trying until we get a non-out, non-colliding item */
+ ftotal = 0;
+ skip_rep = 0;
+ do {
+ retry_descent = 0;
+ in = bucket; /* initial bucket */
+
+ /* choose through intervening buckets */
+ flocal = 0;
+ do {
+ collide = 0;
+ retry_bucket = 0;
+ r = rep;
+ if (in->alg == CRUSH_BUCKET_UNIFORM) {
+ /* be careful */
+ if (firstn || numrep >= in->size)
+ /* r' = r + f_total */
+ r += ftotal;
+ else if (in->size % numrep == 0)
+ /* r'=r+(n+1)*f_local */
+ r += (numrep+1) *
+ (flocal+ftotal);
+ else
+ /* r' = r + n*f_local */
+ r += numrep * (flocal+ftotal);
+ } else {
+ if (firstn)
+ /* r' = r + f_total */
+ r += ftotal;
+ else
+ /* r' = r + n*f_local */
+ r += numrep * (flocal+ftotal);
+ }
+
+ /* bucket choose */
+ if (in->size == 0) {
+ reject = 1;
+ goto reject;
+ }
+ if (flocal >= (in->size>>1) &&
+ flocal > orig_tries)
+ item = bucket_perm_choose(in, x, r);
+ else
+ item = crush_bucket_choose(in, x, r);
+ BUG_ON(item >= map->max_devices);
+
+ /* desired type? */
+ if (item < 0)
+ itemtype = map->buckets[-1-item]->type;
+ else
+ itemtype = 0;
+ dprintk(" item %d type %d\n", item, itemtype);
+
+ /* keep going? */
+ if (itemtype != type) {
+ BUG_ON(item >= 0 ||
+ (-1-item) >= map->max_buckets);
+ in = map->buckets[-1-item];
+ continue;
+ }
+
+ /* collision? */
+ for (i = 0; i < outpos; i++) {
+ if (out[i] == item) {
+ collide = 1;
+ break;
+ }
+ }
+
+ if (recurse_to_leaf &&
+ item < 0 &&
+ crush_choose(map, map->buckets[-1-item],
+ weight,
+ x, outpos+1, 0,
+ out2, outpos,
+ firstn, 0, NULL) <= outpos) {
+ reject = 1;
+ } else {
+ /* out? */
+ if (itemtype == 0)
+ reject = is_out(map, weight,
+ item, x);
+ else
+ reject = 0;
+ }
+
+reject:
+ if (reject || collide) {
+ ftotal++;
+ flocal++;
+
+ if (collide && flocal < 3)
+ /* retry locally a few times */
+ retry_bucket = 1;
+ else if (flocal < in->size + orig_tries)
+ /* exhaustive bucket search */
+ retry_bucket = 1;
+ else if (ftotal < 20)
+ /* then retry descent */
+ retry_descent = 1;
+ else
+ /* else give up */
+ skip_rep = 1;
+ dprintk(" reject %d collide %d "
+ "ftotal %d flocal %d\n",
+ reject, collide, ftotal,
+ flocal);
+ }
+ } while (retry_bucket);
+ } while (retry_descent);
+
+ if (skip_rep) {
+ dprintk("skip rep\n");
+ continue;
+ }
+
+ dprintk("choose got %d\n", item);
+ out[outpos] = item;
+ outpos++;
+ }
+
+ dprintk("choose returns %d\n", outpos);
+ return outpos;
+}
+
+
+/**
+ * crush_do_rule - calculate a mapping with the given input and rule
+ * @map: the crush_map
+ * @ruleno: the rule id
+ * @x: hash input
+ * @result: pointer to result vector
+ * @result_max: maximum result size
+ * @force: force initial replica choice; -1 for none
+ */
+int crush_do_rule(struct crush_map *map,
+ int ruleno, int x, int *result, int result_max,
+ int force, __u32 *weight)
+{
+ int result_len;
+ int force_context[CRUSH_MAX_DEPTH];
+ int force_pos = -1;
+ int a[CRUSH_MAX_SET];
+ int b[CRUSH_MAX_SET];
+ int c[CRUSH_MAX_SET];
+ int recurse_to_leaf;
+ int *w;
+ int wsize = 0;
+ int *o;
+ int osize;
+ int *tmp;
+ struct crush_rule *rule;
+ int step;
+ int i, j;
+ int numrep;
+ int firstn;
+ int rc = -1;
+
+ BUG_ON(ruleno >= map->max_rules);
+
+ rule = map->rules[ruleno];
+ result_len = 0;
+ w = a;
+ o = b;
+
+ /*
+ * determine hierarchical context of force, if any. note
+ * that this may or may not correspond to the specific types
+ * referenced by the crush rule.
+ */
+ if (force >= 0) {
+ if (force >= map->max_devices ||
+ map->device_parents[force] == 0) {
+ /*dprintk("CRUSH: forcefed device dne\n");*/
+ rc = -1; /* force fed device dne */
+ goto out;
+ }
+ if (!is_out(map, weight, force, x)) {
+ while (1) {
+ force_context[++force_pos] = force;
+ if (force >= 0)
+ force = map->device_parents[force];
+ else
+ force = map->bucket_parents[-1-force];
+ if (force == 0)
+ break;
+ }
+ }
+ }
+
+ for (step = 0; step < rule->len; step++) {
+ firstn = 0;
+ switch (rule->steps[step].op) {
+ case CRUSH_RULE_TAKE:
+ w[0] = rule->steps[step].arg1;
+ if (force_pos >= 0) {
+ BUG_ON(force_context[force_pos] != w[0]);
+ force_pos--;
+ }
+ wsize = 1;
+ break;
+
+ case CRUSH_RULE_CHOOSE_LEAF_FIRSTN:
+ case CRUSH_RULE_CHOOSE_FIRSTN:
+ firstn = 1;
+ case CRUSH_RULE_CHOOSE_LEAF_INDEP:
+ case CRUSH_RULE_CHOOSE_INDEP:
+ BUG_ON(wsize == 0);
+
+ recurse_to_leaf =
+ rule->steps[step].op ==
+ CRUSH_RULE_CHOOSE_LEAF_FIRSTN ||
+ rule->steps[step].op ==
+ CRUSH_RULE_CHOOSE_LEAF_INDEP;
+
+ /* reset output */
+ osize = 0;
+
+ for (i = 0; i < wsize; i++) {
+ /*
+ * see CRUSH_N, CRUSH_N_MINUS macros.
+ * basically, numrep <= 0 means relative to
+ * the provided result_max
+ */
+ numrep = rule->steps[step].arg1;
+ if (numrep <= 0) {
+ numrep += result_max;
+ if (numrep <= 0)
+ continue;
+ }
+ j = 0;
+ if (osize == 0 && force_pos >= 0) {
+ /* skip any intermediate types */
+ while (force_pos &&
+ force_context[force_pos] < 0 &&
+ rule->steps[step].arg2 !=
+ map->buckets[-1 -
+ force_context[force_pos]]->type)
+ force_pos--;
+ o[osize] = force_context[force_pos];
+ if (recurse_to_leaf)
+ c[osize] = force_context[0];
+ j++;
+ force_pos--;
+ }
+ osize += crush_choose(map,
+ map->buckets[-1-w[i]],
+ weight,
+ x, numrep,
+ rule->steps[step].arg2,
+ o+osize, j,
+ firstn,
+ recurse_to_leaf, c+osize);
+ }
+
+ if (recurse_to_leaf)
+ /* copy final _leaf_ values to output set */
+ memcpy(o, c, osize*sizeof(*o));
+
+ /* swap t and w arrays */
+ tmp = o;
+ o = w;
+ w = tmp;
+ wsize = osize;
+ break;
+
+
+ case CRUSH_RULE_EMIT:
+ for (i = 0; i < wsize && result_len < result_max; i++) {
+ result[result_len] = w[i];
+ result_len++;
+ }
+ wsize = 0;
+ break;
+
+ default:
+ BUG_ON(1);
+ }
+ }
+ rc = result_len;
+
+out:
+ return rc;
+}
+
+
diff --git a/fs/ceph/crush/mapper.h b/fs/ceph/crush/mapper.h
new file mode 100644
index 00000000000..98e90046fd9
--- /dev/null
+++ b/fs/ceph/crush/mapper.h
@@ -0,0 +1,20 @@
+#ifndef _CRUSH_MAPPER_H
+#define _CRUSH_MAPPER_H
+
+/*
+ * CRUSH functions for find rules and then mapping an input to an
+ * output set.
+ *
+ * LGPL2
+ */
+
+#include "crush.h"
+
+extern int crush_find_rule(struct crush_map *map, int pool, int type, int size);
+extern int crush_do_rule(struct crush_map *map,
+ int ruleno,
+ int x, int *result, int result_max,
+ int forcefeed, /* -1 for none */
+ __u32 *weights);
+
+#endif
diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c
new file mode 100644
index 00000000000..f704b3b6242
--- /dev/null
+++ b/fs/ceph/crypto.c
@@ -0,0 +1,409 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <crypto/hash.h>
+
+#include "crypto.h"
+#include "decode.h"
+
+int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
+{
+ if (*p + sizeof(u16) + sizeof(key->created) +
+ sizeof(u16) + key->len > end)
+ return -ERANGE;
+ ceph_encode_16(p, key->type);
+ ceph_encode_copy(p, &key->created, sizeof(key->created));
+ ceph_encode_16(p, key->len);
+ ceph_encode_copy(p, key->key, key->len);
+ return 0;
+}
+
+int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
+{
+ ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
+ key->type = ceph_decode_16(p);
+ ceph_decode_copy(p, &key->created, sizeof(key->created));
+ key->len = ceph_decode_16(p);
+ ceph_decode_need(p, end, key->len, bad);
+ key->key = kmalloc(key->len, GFP_NOFS);
+ if (!key->key)
+ return -ENOMEM;
+ ceph_decode_copy(p, key->key, key->len);
+ return 0;
+
+bad:
+ dout("failed to decode crypto key\n");
+ return -EINVAL;
+}
+
+int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
+{
+ int inlen = strlen(inkey);
+ int blen = inlen * 3 / 4;
+ void *buf, *p;
+ int ret;
+
+ dout("crypto_key_unarmor %s\n", inkey);
+ buf = kmalloc(blen, GFP_NOFS);
+ if (!buf)
+ return -ENOMEM;
+ blen = ceph_unarmor(buf, inkey, inkey+inlen);
+ if (blen < 0) {
+ kfree(buf);
+ return blen;
+ }
+
+ p = buf;
+ ret = ceph_crypto_key_decode(key, &p, p + blen);
+ kfree(buf);
+ if (ret)
+ return ret;
+ dout("crypto_key_unarmor key %p type %d len %d\n", key,
+ key->type, key->len);
+ return 0;
+}
+
+
+
+#define AES_KEY_SIZE 16
+
+static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
+{
+ return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
+}
+
+const u8 *aes_iv = "cephsageyudagreg";
+
+int ceph_aes_encrypt(const void *key, int key_len, void *dst, size_t *dst_len,
+ const void *src, size_t src_len)
+{
+ struct scatterlist sg_in[2], sg_out[1];
+ struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+ struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
+ int ret;
+ void *iv;
+ int ivsize;
+ size_t zero_padding = (0x10 - (src_len & 0x0f));
+ char pad[16];
+
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
+ memset(pad, zero_padding, zero_padding);
+
+ *dst_len = src_len + zero_padding;
+
+ crypto_blkcipher_setkey((void *)tfm, key, key_len);
+ sg_init_table(sg_in, 2);
+ sg_set_buf(&sg_in[0], src, src_len);
+ sg_set_buf(&sg_in[1], pad, zero_padding);
+ sg_init_table(sg_out, 1);
+ sg_set_buf(sg_out, dst, *dst_len);
+ iv = crypto_blkcipher_crt(tfm)->iv;
+ ivsize = crypto_blkcipher_ivsize(tfm);
+
+ memcpy(iv, aes_iv, ivsize);
+ /*
+ print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
+ key, key_len, 1);
+ print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
+ src, src_len, 1);
+ print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
+ pad, zero_padding, 1);
+ */
+ ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+ src_len + zero_padding);
+ crypto_free_blkcipher(tfm);
+ if (ret < 0)
+ pr_err("ceph_aes_crypt failed %d\n", ret);
+ /*
+ print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
+ dst, *dst_len, 1);
+ */
+ return 0;
+}
+
+int ceph_aes_encrypt2(const void *key, int key_len, void *dst, size_t *dst_len,
+ const void *src1, size_t src1_len,
+ const void *src2, size_t src2_len)
+{
+ struct scatterlist sg_in[3], sg_out[1];
+ struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+ struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
+ int ret;
+ void *iv;
+ int ivsize;
+ size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f));
+ char pad[16];
+
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
+ memset(pad, zero_padding, zero_padding);
+
+ *dst_len = src1_len + src2_len + zero_padding;
+
+ crypto_blkcipher_setkey((void *)tfm, key, key_len);
+ sg_init_table(sg_in, 3);
+ sg_set_buf(&sg_in[0], src1, src1_len);
+ sg_set_buf(&sg_in[1], src2, src2_len);
+ sg_set_buf(&sg_in[2], pad, zero_padding);
+ sg_init_table(sg_out, 1);
+ sg_set_buf(sg_out, dst, *dst_len);
+ iv = crypto_blkcipher_crt(tfm)->iv;
+ ivsize = crypto_blkcipher_ivsize(tfm);
+
+ memcpy(iv, aes_iv, ivsize);
+ /*
+ print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
+ key, key_len, 1);
+ print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
+ src1, src1_len, 1);
+ print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
+ src2, src2_len, 1);
+ print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
+ pad, zero_padding, 1);
+ */
+ ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+ src1_len + src2_len + zero_padding);
+ crypto_free_blkcipher(tfm);
+ if (ret < 0)
+ pr_err("ceph_aes_crypt2 failed %d\n", ret);
+ /*
+ print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
+ dst, *dst_len, 1);
+ */
+ return 0;
+}
+
+int ceph_aes_decrypt(const void *key, int key_len, void *dst, size_t *dst_len,
+ const void *src, size_t src_len)
+{
+ struct scatterlist sg_in[1], sg_out[2];
+ struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+ struct blkcipher_desc desc = { .tfm = tfm };
+ char pad[16];
+ void *iv;
+ int ivsize;
+ int ret;
+ int last_byte;
+
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
+ crypto_blkcipher_setkey((void *)tfm, key, key_len);
+ sg_init_table(sg_in, 1);
+ sg_init_table(sg_out, 2);
+ sg_set_buf(sg_in, src, src_len);
+ sg_set_buf(&sg_out[0], dst, *dst_len);
+ sg_set_buf(&sg_out[1], pad, sizeof(pad));
+
+ iv = crypto_blkcipher_crt(tfm)->iv;
+ ivsize = crypto_blkcipher_ivsize(tfm);
+
+ memcpy(iv, aes_iv, ivsize);
+
+ /*
+ print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
+ key, key_len, 1);
+ print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
+ src, src_len, 1);
+ */
+
+ ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
+ crypto_free_blkcipher(tfm);
+ if (ret < 0) {
+ pr_err("ceph_aes_decrypt failed %d\n", ret);
+ return ret;
+ }
+
+ if (src_len <= *dst_len)
+ last_byte = ((char *)dst)[src_len - 1];
+ else
+ last_byte = pad[src_len - *dst_len - 1];
+ if (last_byte <= 16 && src_len >= last_byte) {
+ *dst_len = src_len - last_byte;
+ } else {
+ pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
+ last_byte, (int)src_len);
+ return -EPERM; /* bad padding */
+ }
+ /*
+ print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
+ dst, *dst_len, 1);
+ */
+ return 0;
+}
+
+int ceph_aes_decrypt2(const void *key, int key_len,
+ void *dst1, size_t *dst1_len,
+ void *dst2, size_t *dst2_len,
+ const void *src, size_t src_len)
+{
+ struct scatterlist sg_in[1], sg_out[3];
+ struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+ struct blkcipher_desc desc = { .tfm = tfm };
+ char pad[16];
+ void *iv;
+ int ivsize;
+ int ret;
+ int last_byte;
+
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
+ sg_init_table(sg_in, 1);
+ sg_set_buf(sg_in, src, src_len);
+ sg_init_table(sg_out, 3);
+ sg_set_buf(&sg_out[0], dst1, *dst1_len);
+ sg_set_buf(&sg_out[1], dst2, *dst2_len);
+ sg_set_buf(&sg_out[2], pad, sizeof(pad));
+
+ crypto_blkcipher_setkey((void *)tfm, key, key_len);
+ iv = crypto_blkcipher_crt(tfm)->iv;
+ ivsize = crypto_blkcipher_ivsize(tfm);
+
+ memcpy(iv, aes_iv, ivsize);
+
+ /*
+ print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
+ key, key_len, 1);
+ print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
+ src, src_len, 1);
+ */
+
+ ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
+ crypto_free_blkcipher(tfm);
+ if (ret < 0) {
+ pr_err("ceph_aes_decrypt failed %d\n", ret);
+ return ret;
+ }
+
+ if (src_len <= *dst1_len)
+ last_byte = ((char *)dst1)[src_len - 1];
+ else if (src_len <= *dst1_len + *dst2_len)
+ last_byte = ((char *)dst2)[src_len - *dst1_len - 1];
+ else
+ last_byte = pad[src_len - *dst1_len - *dst2_len - 1];
+ if (last_byte <= 16 && src_len >= last_byte) {
+ src_len -= last_byte;
+ } else {
+ pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
+ last_byte, (int)src_len);
+ return -EPERM; /* bad padding */
+ }
+
+ if (src_len < *dst1_len) {
+ *dst1_len = src_len;
+ *dst2_len = 0;
+ } else {
+ *dst2_len = src_len - *dst1_len;
+ }
+ /*
+ print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1,
+ dst1, *dst1_len, 1);
+ print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1,
+ dst2, *dst2_len, 1);
+ */
+
+ return 0;
+}
+
+
+int ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+ const void *src, size_t src_len)
+{
+ switch (secret->type) {
+ case CEPH_CRYPTO_NONE:
+ if (*dst_len < src_len)
+ return -ERANGE;
+ memcpy(dst, src, src_len);
+ *dst_len = src_len;
+ return 0;
+
+ case CEPH_CRYPTO_AES:
+ return ceph_aes_decrypt(secret->key, secret->len, dst,
+ dst_len, src, src_len);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+int ceph_decrypt2(struct ceph_crypto_key *secret,
+ void *dst1, size_t *dst1_len,
+ void *dst2, size_t *dst2_len,
+ const void *src, size_t src_len)
+{
+ size_t t;
+
+ switch (secret->type) {
+ case CEPH_CRYPTO_NONE:
+ if (*dst1_len + *dst2_len < src_len)
+ return -ERANGE;
+ t = min(*dst1_len, src_len);
+ memcpy(dst1, src, t);
+ *dst1_len = t;
+ src += t;
+ src_len -= t;
+ if (src_len) {
+ t = min(*dst2_len, src_len);
+ memcpy(dst2, src, t);
+ *dst2_len = t;
+ }
+ return 0;
+
+ case CEPH_CRYPTO_AES:
+ return ceph_aes_decrypt2(secret->key, secret->len,
+ dst1, dst1_len, dst2, dst2_len,
+ src, src_len);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+ const void *src, size_t src_len)
+{
+ switch (secret->type) {
+ case CEPH_CRYPTO_NONE:
+ if (*dst_len < src_len)
+ return -ERANGE;
+ memcpy(dst, src, src_len);
+ *dst_len = src_len;
+ return 0;
+
+ case CEPH_CRYPTO_AES:
+ return ceph_aes_encrypt(secret->key, secret->len, dst,
+ dst_len, src, src_len);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+ const void *src1, size_t src1_len,
+ const void *src2, size_t src2_len)
+{
+ switch (secret->type) {
+ case CEPH_CRYPTO_NONE:
+ if (*dst_len < src1_len + src2_len)
+ return -ERANGE;
+ memcpy(dst, src1, src1_len);
+ memcpy(dst + src1_len, src2, src2_len);
+ *dst_len = src1_len + src2_len;
+ return 0;
+
+ case CEPH_CRYPTO_AES:
+ return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len,
+ src1, src1_len, src2, src2_len);
+
+ default:
+ return -EINVAL;
+ }
+}
diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h
new file mode 100644
index 00000000000..40b502e6bd8
--- /dev/null
+++ b/fs/ceph/crypto.h
@@ -0,0 +1,48 @@
+#ifndef _FS_CEPH_CRYPTO_H
+#define _FS_CEPH_CRYPTO_H
+
+#include "types.h"
+#include "buffer.h"
+
+/*
+ * cryptographic secret
+ */
+struct ceph_crypto_key {
+ int type;
+ struct ceph_timespec created;
+ int len;
+ void *key;
+};
+
+static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
+{
+ kfree(key->key);
+}
+
+extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
+ void **p, void *end);
+extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
+ void **p, void *end);
+extern int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in);
+
+/* crypto.c */
+extern int ceph_decrypt(struct ceph_crypto_key *secret,
+ void *dst, size_t *dst_len,
+ const void *src, size_t src_len);
+extern int ceph_encrypt(struct ceph_crypto_key *secret,
+ void *dst, size_t *dst_len,
+ const void *src, size_t src_len);
+extern int ceph_decrypt2(struct ceph_crypto_key *secret,
+ void *dst1, size_t *dst1_len,
+ void *dst2, size_t *dst2_len,
+ const void *src, size_t src_len);
+extern int ceph_encrypt2(struct ceph_crypto_key *secret,
+ void *dst, size_t *dst_len,
+ const void *src1, size_t src1_len,
+ const void *src2, size_t src2_len);
+
+/* armor.c */
+extern int ceph_armor(char *dst, const void *src, const void *end);
+extern int ceph_unarmor(void *dst, const char *src, const char *end);
+
+#endif
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
new file mode 100644
index 00000000000..f7048da92ac
--- /dev/null
+++ b/fs/ceph/debugfs.c
@@ -0,0 +1,484 @@
+#include "ceph_debug.h"
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include "super.h"
+#include "mds_client.h"
+#include "mon_client.h"
+#include "auth.h"
+
+#ifdef CONFIG_DEBUG_FS
+
+/*
+ * Implement /sys/kernel/debug/ceph fun
+ *
+ * /sys/kernel/debug/ceph/client* - an instance of the ceph client
+ * .../osdmap - current osdmap
+ * .../mdsmap - current mdsmap
+ * .../monmap - current monmap
+ * .../osdc - active osd requests
+ * .../mdsc - active mds requests
+ * .../monc - mon client state
+ * .../dentry_lru - dump contents of dentry lru
+ * .../caps - expose cap (reservation) stats
+ * .../bdi - symlink to ../../bdi/something
+ */
+
+static struct dentry *ceph_debugfs_dir;
+
+static int monmap_show(struct seq_file *s, void *p)
+{
+ int i;
+ struct ceph_client *client = s->private;
+
+ if (client->monc.monmap == NULL)
+ return 0;
+
+ seq_printf(s, "epoch %d\n", client->monc.monmap->epoch);
+ for (i = 0; i < client->monc.monmap->num_mon; i++) {
+ struct ceph_entity_inst *inst =
+ &client->monc.monmap->mon_inst[i];
+
+ seq_printf(s, "\t%s%lld\t%s\n",
+ ENTITY_NAME(inst->name),
+ pr_addr(&inst->addr.in_addr));
+ }
+ return 0;
+}
+
+static int mdsmap_show(struct seq_file *s, void *p)
+{
+ int i;
+ struct ceph_client *client = s->private;
+
+ if (client->mdsc.mdsmap == NULL)
+ return 0;
+ seq_printf(s, "epoch %d\n", client->mdsc.mdsmap->m_epoch);
+ seq_printf(s, "root %d\n", client->mdsc.mdsmap->m_root);
+ seq_printf(s, "session_timeout %d\n",
+ client->mdsc.mdsmap->m_session_timeout);
+ seq_printf(s, "session_autoclose %d\n",
+ client->mdsc.mdsmap->m_session_autoclose);
+ for (i = 0; i < client->mdsc.mdsmap->m_max_mds; i++) {
+ struct ceph_entity_addr *addr =
+ &client->mdsc.mdsmap->m_info[i].addr;
+ int state = client->mdsc.mdsmap->m_info[i].state;
+
+ seq_printf(s, "\tmds%d\t%s\t(%s)\n", i, pr_addr(&addr->in_addr),
+ ceph_mds_state_name(state));
+ }
+ return 0;
+}
+
+static int osdmap_show(struct seq_file *s, void *p)
+{
+ int i;
+ struct ceph_client *client = s->private;
+ struct rb_node *n;
+
+ if (client->osdc.osdmap == NULL)
+ return 0;
+ seq_printf(s, "epoch %d\n", client->osdc.osdmap->epoch);
+ seq_printf(s, "flags%s%s\n",
+ (client->osdc.osdmap->flags & CEPH_OSDMAP_NEARFULL) ?
+ " NEARFULL" : "",
+ (client->osdc.osdmap->flags & CEPH_OSDMAP_FULL) ?
+ " FULL" : "");
+ for (n = rb_first(&client->osdc.osdmap->pg_pools); n; n = rb_next(n)) {
+ struct ceph_pg_pool_info *pool =
+ rb_entry(n, struct ceph_pg_pool_info, node);
+ seq_printf(s, "pg_pool %d pg_num %d / %d, lpg_num %d / %d\n",
+ pool->id, pool->v.pg_num, pool->pg_num_mask,
+ pool->v.lpg_num, pool->lpg_num_mask);
+ }
+ for (i = 0; i < client->osdc.osdmap->max_osd; i++) {
+ struct ceph_entity_addr *addr =
+ &client->osdc.osdmap->osd_addr[i];
+ int state = client->osdc.osdmap->osd_state[i];
+ char sb[64];
+
+ seq_printf(s, "\tosd%d\t%s\t%3d%%\t(%s)\n",
+ i, pr_addr(&addr->in_addr),
+ ((client->osdc.osdmap->osd_weight[i]*100) >> 16),
+ ceph_osdmap_state_str(sb, sizeof(sb), state));
+ }
+ return 0;
+}
+
+static int monc_show(struct seq_file *s, void *p)
+{
+ struct ceph_client *client = s->private;
+ struct ceph_mon_statfs_request *req;
+ struct ceph_mon_client *monc = &client->monc;
+ struct rb_node *rp;
+
+ mutex_lock(&monc->mutex);
+
+ if (monc->have_mdsmap)
+ seq_printf(s, "have mdsmap %u\n", (unsigned)monc->have_mdsmap);
+ if (monc->have_osdmap)
+ seq_printf(s, "have osdmap %u\n", (unsigned)monc->have_osdmap);
+ if (monc->want_next_osdmap)
+ seq_printf(s, "want next osdmap\n");
+
+ for (rp = rb_first(&monc->statfs_request_tree); rp; rp = rb_next(rp)) {
+ req = rb_entry(rp, struct ceph_mon_statfs_request, node);
+ seq_printf(s, "%lld statfs\n", req->tid);
+ }
+
+ mutex_unlock(&monc->mutex);
+ return 0;
+}
+
+static int mdsc_show(struct seq_file *s, void *p)
+{
+ struct ceph_client *client = s->private;
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ struct rb_node *rp;
+ int pathlen;
+ u64 pathbase;
+ char *path;
+
+ mutex_lock(&mdsc->mutex);
+ for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) {
+ req = rb_entry(rp, struct ceph_mds_request, r_node);
+
+ if (req->r_request)
+ seq_printf(s, "%lld\tmds%d\t", req->r_tid, req->r_mds);
+ else
+ seq_printf(s, "%lld\t(no request)\t", req->r_tid);
+
+ seq_printf(s, "%s", ceph_mds_op_name(req->r_op));
+
+ if (req->r_got_unsafe)
+ seq_printf(s, "\t(unsafe)");
+ else
+ seq_printf(s, "\t");
+
+ if (req->r_inode) {
+ seq_printf(s, " #%llx", ceph_ino(req->r_inode));
+ } else if (req->r_dentry) {
+ path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
+ &pathbase, 0);
+ spin_lock(&req->r_dentry->d_lock);
+ seq_printf(s, " #%llx/%.*s (%s)",
+ ceph_ino(req->r_dentry->d_parent->d_inode),
+ req->r_dentry->d_name.len,
+ req->r_dentry->d_name.name,
+ path ? path : "");
+ spin_unlock(&req->r_dentry->d_lock);
+ kfree(path);
+ } else if (req->r_path1) {
+ seq_printf(s, " #%llx/%s", req->r_ino1.ino,
+ req->r_path1);
+ }
+
+ if (req->r_old_dentry) {
+ path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen,
+ &pathbase, 0);
+ spin_lock(&req->r_old_dentry->d_lock);
+ seq_printf(s, " #%llx/%.*s (%s)",
+ ceph_ino(req->r_old_dentry->d_parent->d_inode),
+ req->r_old_dentry->d_name.len,
+ req->r_old_dentry->d_name.name,
+ path ? path : "");
+ spin_unlock(&req->r_old_dentry->d_lock);
+ kfree(path);
+ } else if (req->r_path2) {
+ if (req->r_ino2.ino)
+ seq_printf(s, " #%llx/%s", req->r_ino2.ino,
+ req->r_path2);
+ else
+ seq_printf(s, " %s", req->r_path2);
+ }
+
+ seq_printf(s, "\n");
+ }
+ mutex_unlock(&mdsc->mutex);
+
+ return 0;
+}
+
+static int osdc_show(struct seq_file *s, void *pp)
+{
+ struct ceph_client *client = s->private;
+ struct ceph_osd_client *osdc = &client->osdc;
+ struct rb_node *p;
+
+ mutex_lock(&osdc->request_mutex);
+ for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+ struct ceph_osd_request *req;
+ struct ceph_osd_request_head *head;
+ struct ceph_osd_op *op;
+ int num_ops;
+ int opcode, olen;
+ int i;
+
+ req = rb_entry(p, struct ceph_osd_request, r_node);
+
+ seq_printf(s, "%lld\tosd%d\t%d.%x\t", req->r_tid,
+ req->r_osd ? req->r_osd->o_osd : -1,
+ le32_to_cpu(req->r_pgid.pool),
+ le16_to_cpu(req->r_pgid.ps));
+
+ head = req->r_request->front.iov_base;
+ op = (void *)(head + 1);
+
+ num_ops = le16_to_cpu(head->num_ops);
+ olen = le32_to_cpu(head->object_len);
+ seq_printf(s, "%.*s", olen,
+ (const char *)(head->ops + num_ops));
+
+ if (req->r_reassert_version.epoch)
+ seq_printf(s, "\t%u'%llu",
+ (unsigned)le32_to_cpu(req->r_reassert_version.epoch),
+ le64_to_cpu(req->r_reassert_version.version));
+ else
+ seq_printf(s, "\t");
+
+ for (i = 0; i < num_ops; i++) {
+ opcode = le16_to_cpu(op->op);
+ seq_printf(s, "\t%s", ceph_osd_op_name(opcode));
+ op++;
+ }
+
+ seq_printf(s, "\n");
+ }
+ mutex_unlock(&osdc->request_mutex);
+ return 0;
+}
+
+static int caps_show(struct seq_file *s, void *p)
+{
+ struct ceph_client *client = p;
+ int total, avail, used, reserved, min;
+
+ ceph_reservation_status(client, &total, &avail, &used, &reserved, &min);
+ seq_printf(s, "total\t\t%d\n"
+ "avail\t\t%d\n"
+ "used\t\t%d\n"
+ "reserved\t%d\n"
+ "min\t%d\n",
+ total, avail, used, reserved, min);
+ return 0;
+}
+
+static int dentry_lru_show(struct seq_file *s, void *ptr)
+{
+ struct ceph_client *client = s->private;
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_dentry_info *di;
+
+ spin_lock(&mdsc->dentry_lru_lock);
+ list_for_each_entry(di, &mdsc->dentry_lru, lru) {
+ struct dentry *dentry = di->dentry;
+ seq_printf(s, "%p %p\t%.*s\n",
+ di, dentry, dentry->d_name.len, dentry->d_name.name);
+ }
+ spin_unlock(&mdsc->dentry_lru_lock);
+
+ return 0;
+}
+
+#define DEFINE_SHOW_FUNC(name) \
+static int name##_open(struct inode *inode, struct file *file) \
+{ \
+ struct seq_file *sf; \
+ int ret; \
+ \
+ ret = single_open(file, name, NULL); \
+ sf = file->private_data; \
+ sf->private = inode->i_private; \
+ return ret; \
+} \
+ \
+static const struct file_operations name##_fops = { \
+ .open = name##_open, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+};
+
+DEFINE_SHOW_FUNC(monmap_show)
+DEFINE_SHOW_FUNC(mdsmap_show)
+DEFINE_SHOW_FUNC(osdmap_show)
+DEFINE_SHOW_FUNC(monc_show)
+DEFINE_SHOW_FUNC(mdsc_show)
+DEFINE_SHOW_FUNC(osdc_show)
+DEFINE_SHOW_FUNC(dentry_lru_show)
+DEFINE_SHOW_FUNC(caps_show)
+
+static int congestion_kb_set(void *data, u64 val)
+{
+ struct ceph_client *client = (struct ceph_client *)data;
+
+ if (client)
+ client->mount_args->congestion_kb = (int)val;
+
+ return 0;
+}
+
+static int congestion_kb_get(void *data, u64 *val)
+{
+ struct ceph_client *client = (struct ceph_client *)data;
+
+ if (client)
+ *val = (u64)client->mount_args->congestion_kb;
+
+ return 0;
+}
+
+
+DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
+ congestion_kb_set, "%llu\n");
+
+int __init ceph_debugfs_init(void)
+{
+ ceph_debugfs_dir = debugfs_create_dir("ceph", NULL);
+ if (!ceph_debugfs_dir)
+ return -ENOMEM;
+ return 0;
+}
+
+void ceph_debugfs_cleanup(void)
+{
+ debugfs_remove(ceph_debugfs_dir);
+}
+
+int ceph_debugfs_client_init(struct ceph_client *client)
+{
+ int ret = 0;
+ char name[80];
+
+ snprintf(name, sizeof(name), FSID_FORMAT ".client%lld",
+ PR_FSID(&client->fsid), client->monc.auth->global_id);
+
+ client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
+ if (!client->debugfs_dir)
+ goto out;
+
+ client->monc.debugfs_file = debugfs_create_file("monc",
+ 0600,
+ client->debugfs_dir,
+ client,
+ &monc_show_fops);
+ if (!client->monc.debugfs_file)
+ goto out;
+
+ client->mdsc.debugfs_file = debugfs_create_file("mdsc",
+ 0600,
+ client->debugfs_dir,
+ client,
+ &mdsc_show_fops);
+ if (!client->mdsc.debugfs_file)
+ goto out;
+
+ client->osdc.debugfs_file = debugfs_create_file("osdc",
+ 0600,
+ client->debugfs_dir,
+ client,
+ &osdc_show_fops);
+ if (!client->osdc.debugfs_file)
+ goto out;
+
+ client->debugfs_monmap = debugfs_create_file("monmap",
+ 0600,
+ client->debugfs_dir,
+ client,
+ &monmap_show_fops);
+ if (!client->debugfs_monmap)
+ goto out;
+
+ client->debugfs_mdsmap = debugfs_create_file("mdsmap",
+ 0600,
+ client->debugfs_dir,
+ client,
+ &mdsmap_show_fops);
+ if (!client->debugfs_mdsmap)
+ goto out;
+
+ client->debugfs_osdmap = debugfs_create_file("osdmap",
+ 0600,
+ client->debugfs_dir,
+ client,
+ &osdmap_show_fops);
+ if (!client->debugfs_osdmap)
+ goto out;
+
+ client->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
+ 0600,
+ client->debugfs_dir,
+ client,
+ &dentry_lru_show_fops);
+ if (!client->debugfs_dentry_lru)
+ goto out;
+
+ client->debugfs_caps = debugfs_create_file("caps",
+ 0400,
+ client->debugfs_dir,
+ client,
+ &caps_show_fops);
+ if (!client->debugfs_caps)
+ goto out;
+
+ client->debugfs_congestion_kb = debugfs_create_file("writeback_congestion_kb",
+ 0600,
+ client->debugfs_dir,
+ client,
+ &congestion_kb_fops);
+ if (!client->debugfs_congestion_kb)
+ goto out;
+
+ sprintf(name, "../../bdi/%s", dev_name(client->sb->s_bdi->dev));
+ client->debugfs_bdi = debugfs_create_symlink("bdi", client->debugfs_dir,
+ name);
+
+ return 0;
+
+out:
+ ceph_debugfs_client_cleanup(client);
+ return ret;
+}
+
+void ceph_debugfs_client_cleanup(struct ceph_client *client)
+{
+ debugfs_remove(client->debugfs_bdi);
+ debugfs_remove(client->debugfs_caps);
+ debugfs_remove(client->debugfs_dentry_lru);
+ debugfs_remove(client->debugfs_osdmap);
+ debugfs_remove(client->debugfs_mdsmap);
+ debugfs_remove(client->debugfs_monmap);
+ debugfs_remove(client->osdc.debugfs_file);
+ debugfs_remove(client->mdsc.debugfs_file);
+ debugfs_remove(client->monc.debugfs_file);
+ debugfs_remove(client->debugfs_congestion_kb);
+ debugfs_remove(client->debugfs_dir);
+}
+
+#else // CONFIG_DEBUG_FS
+
+int __init ceph_debugfs_init(void)
+{
+ return 0;
+}
+
+void ceph_debugfs_cleanup(void)
+{
+}
+
+int ceph_debugfs_client_init(struct ceph_client *client)
+{
+ return 0;
+}
+
+void ceph_debugfs_client_cleanup(struct ceph_client *client)
+{
+}
+
+#endif // CONFIG_DEBUG_FS
diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h
new file mode 100644
index 00000000000..65b3e022eaf
--- /dev/null
+++ b/fs/ceph/decode.h
@@ -0,0 +1,194 @@
+#ifndef __CEPH_DECODE_H
+#define __CEPH_DECODE_H
+
+#include <asm/unaligned.h>
+#include <linux/time.h>
+
+#include "types.h"
+
+/*
+ * in all cases,
+ * void **p pointer to position pointer
+ * void *end pointer to end of buffer (last byte + 1)
+ */
+
+static inline u64 ceph_decode_64(void **p)
+{
+ u64 v = get_unaligned_le64(*p);
+ *p += sizeof(u64);
+ return v;
+}
+static inline u32 ceph_decode_32(void **p)
+{
+ u32 v = get_unaligned_le32(*p);
+ *p += sizeof(u32);
+ return v;
+}
+static inline u16 ceph_decode_16(void **p)
+{
+ u16 v = get_unaligned_le16(*p);
+ *p += sizeof(u16);
+ return v;
+}
+static inline u8 ceph_decode_8(void **p)
+{
+ u8 v = *(u8 *)*p;
+ (*p)++;
+ return v;
+}
+static inline void ceph_decode_copy(void **p, void *pv, size_t n)
+{
+ memcpy(pv, *p, n);
+ *p += n;
+}
+
+/*
+ * bounds check input.
+ */
+#define ceph_decode_need(p, end, n, bad) \
+ do { \
+ if (unlikely(*(p) + (n) > (end))) \
+ goto bad; \
+ } while (0)
+
+#define ceph_decode_64_safe(p, end, v, bad) \
+ do { \
+ ceph_decode_need(p, end, sizeof(u64), bad); \
+ v = ceph_decode_64(p); \
+ } while (0)
+#define ceph_decode_32_safe(p, end, v, bad) \
+ do { \
+ ceph_decode_need(p, end, sizeof(u32), bad); \
+ v = ceph_decode_32(p); \
+ } while (0)
+#define ceph_decode_16_safe(p, end, v, bad) \
+ do { \
+ ceph_decode_need(p, end, sizeof(u16), bad); \
+ v = ceph_decode_16(p); \
+ } while (0)
+#define ceph_decode_8_safe(p, end, v, bad) \
+ do { \
+ ceph_decode_need(p, end, sizeof(u8), bad); \
+ v = ceph_decode_8(p); \
+ } while (0)
+
+#define ceph_decode_copy_safe(p, end, pv, n, bad) \
+ do { \
+ ceph_decode_need(p, end, n, bad); \
+ ceph_decode_copy(p, pv, n); \
+ } while (0)
+
+/*
+ * struct ceph_timespec <-> struct timespec
+ */
+static inline void ceph_decode_timespec(struct timespec *ts,
+ const struct ceph_timespec *tv)
+{
+ ts->tv_sec = le32_to_cpu(tv->tv_sec);
+ ts->tv_nsec = le32_to_cpu(tv->tv_nsec);
+}
+static inline void ceph_encode_timespec(struct ceph_timespec *tv,
+ const struct timespec *ts)
+{
+ tv->tv_sec = cpu_to_le32(ts->tv_sec);
+ tv->tv_nsec = cpu_to_le32(ts->tv_nsec);
+}
+
+/*
+ * sockaddr_storage <-> ceph_sockaddr
+ */
+static inline void ceph_encode_addr(struct ceph_entity_addr *a)
+{
+ a->in_addr.ss_family = htons(a->in_addr.ss_family);
+}
+static inline void ceph_decode_addr(struct ceph_entity_addr *a)
+{
+ a->in_addr.ss_family = ntohs(a->in_addr.ss_family);
+ WARN_ON(a->in_addr.ss_family == 512);
+}
+
+/*
+ * encoders
+ */
+static inline void ceph_encode_64(void **p, u64 v)
+{
+ put_unaligned_le64(v, (__le64 *)*p);
+ *p += sizeof(u64);
+}
+static inline void ceph_encode_32(void **p, u32 v)
+{
+ put_unaligned_le32(v, (__le32 *)*p);
+ *p += sizeof(u32);
+}
+static inline void ceph_encode_16(void **p, u16 v)
+{
+ put_unaligned_le16(v, (__le16 *)*p);
+ *p += sizeof(u16);
+}
+static inline void ceph_encode_8(void **p, u8 v)
+{
+ *(u8 *)*p = v;
+ (*p)++;
+}
+static inline void ceph_encode_copy(void **p, const void *s, int len)
+{
+ memcpy(*p, s, len);
+ *p += len;
+}
+
+/*
+ * filepath, string encoders
+ */
+static inline void ceph_encode_filepath(void **p, void *end,
+ u64 ino, const char *path)
+{
+ u32 len = path ? strlen(path) : 0;
+ BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end);
+ ceph_encode_8(p, 1);
+ ceph_encode_64(p, ino);
+ ceph_encode_32(p, len);
+ if (len)
+ memcpy(*p, path, len);
+ *p += len;
+}
+
+static inline void ceph_encode_string(void **p, void *end,
+ const char *s, u32 len)
+{
+ BUG_ON(*p + sizeof(len) + len > end);
+ ceph_encode_32(p, len);
+ if (len)
+ memcpy(*p, s, len);
+ *p += len;
+}
+
+#define ceph_encode_need(p, end, n, bad) \
+ do { \
+ if (unlikely(*(p) + (n) > (end))) \
+ goto bad; \
+ } while (0)
+
+#define ceph_encode_64_safe(p, end, v, bad) \
+ do { \
+ ceph_encode_need(p, end, sizeof(u64), bad); \
+ ceph_encode_64(p, v); \
+ } while (0)
+#define ceph_encode_32_safe(p, end, v, bad) \
+ do { \
+ ceph_encode_need(p, end, sizeof(u32), bad); \
+ ceph_encode_32(p, v); \
+ } while (0)
+#define ceph_encode_16_safe(p, end, v, bad) \
+ do { \
+ ceph_encode_need(p, end, sizeof(u16), bad); \
+ ceph_encode_16(p, v); \
+ } while (0)
+
+#define ceph_encode_copy_safe(p, end, pv, n, bad) \
+ do { \
+ ceph_encode_need(p, end, n, bad); \
+ ceph_encode_copy(p, pv, n); \
+ } while (0)
+
+
+#endif
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
new file mode 100644
index 00000000000..ea8ee2e526a
--- /dev/null
+++ b/fs/ceph/dir.c
@@ -0,0 +1,1224 @@
+#include "ceph_debug.h"
+
+#include <linux/spinlock.h>
+#include <linux/fs_struct.h>
+#include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+#include "super.h"
+
+/*
+ * Directory operations: readdir, lookup, create, link, unlink,
+ * rename, etc.
+ */
+
+/*
+ * Ceph MDS operations are specified in terms of a base ino and
+ * relative path. Thus, the client can specify an operation on a
+ * specific inode (e.g., a getattr due to fstat(2)), or as a path
+ * relative to, say, the root directory.
+ *
+ * Normally, we limit ourselves to strict inode ops (no path component)
+ * or dentry operations (a single path component relative to an ino). The
+ * exception to this is open_root_dentry(), which will open the mount
+ * point by name.
+ */
+
+const struct inode_operations ceph_dir_iops;
+const struct file_operations ceph_dir_fops;
+struct dentry_operations ceph_dentry_ops;
+
+/*
+ * Initialize ceph dentry state.
+ */
+int ceph_init_dentry(struct dentry *dentry)
+{
+ struct ceph_dentry_info *di;
+
+ if (dentry->d_fsdata)
+ return 0;
+
+ if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP)
+ dentry->d_op = &ceph_dentry_ops;
+ else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR)
+ dentry->d_op = &ceph_snapdir_dentry_ops;
+ else
+ dentry->d_op = &ceph_snap_dentry_ops;
+
+ di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS);
+ if (!di)
+ return -ENOMEM; /* oh well */
+
+ spin_lock(&dentry->d_lock);
+ if (dentry->d_fsdata) /* lost a race */
+ goto out_unlock;
+ di->dentry = dentry;
+ di->lease_session = NULL;
+ dentry->d_fsdata = di;
+ dentry->d_time = jiffies;
+ ceph_dentry_lru_add(dentry);
+out_unlock:
+ spin_unlock(&dentry->d_lock);
+ return 0;
+}
+
+
+
+/*
+ * for readdir, we encode the directory frag and offset within that
+ * frag into f_pos.
+ */
+static unsigned fpos_frag(loff_t p)
+{
+ return p >> 32;
+}
+static unsigned fpos_off(loff_t p)
+{
+ return p & 0xffffffff;
+}
+
+/*
+ * When possible, we try to satisfy a readdir by peeking at the
+ * dcache. We make this work by carefully ordering dentries on
+ * d_u.d_child when we initially get results back from the MDS, and
+ * falling back to a "normal" sync readdir if any dentries in the dir
+ * are dropped.
+ *
+ * I_COMPLETE tells indicates we have all dentries in the dir. It is
+ * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by
+ * the MDS if/when the directory is modified).
+ */
+static int __dcache_readdir(struct file *filp,
+ void *dirent, filldir_t filldir)
+{
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct ceph_file_info *fi = filp->private_data;
+ struct dentry *parent = filp->f_dentry;
+ struct inode *dir = parent->d_inode;
+ struct list_head *p;
+ struct dentry *dentry, *last;
+ struct ceph_dentry_info *di;
+ int err = 0;
+
+ /* claim ref on last dentry we returned */
+ last = fi->dentry;
+ fi->dentry = NULL;
+
+ dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos,
+ last);
+
+ spin_lock(&dcache_lock);
+
+ /* start at beginning? */
+ if (filp->f_pos == 2 || (last &&
+ filp->f_pos < ceph_dentry(last)->offset)) {
+ if (list_empty(&parent->d_subdirs))
+ goto out_unlock;
+ p = parent->d_subdirs.prev;
+ dout(" initial p %p/%p\n", p->prev, p->next);
+ } else {
+ p = last->d_u.d_child.prev;
+ }
+
+more:
+ dentry = list_entry(p, struct dentry, d_u.d_child);
+ di = ceph_dentry(dentry);
+ while (1) {
+ dout(" p %p/%p d_subdirs %p/%p\n", p->prev, p->next,
+ parent->d_subdirs.prev, parent->d_subdirs.next);
+ if (p == &parent->d_subdirs) {
+ fi->at_end = 1;
+ goto out_unlock;
+ }
+ if (!d_unhashed(dentry) && dentry->d_inode &&
+ ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
+ ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
+ filp->f_pos <= di->offset)
+ break;
+ dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry,
+ dentry->d_name.len, dentry->d_name.name, di->offset,
+ filp->f_pos, d_unhashed(dentry) ? " unhashed" : "",
+ !dentry->d_inode ? " null" : "");
+ p = p->prev;
+ dentry = list_entry(p, struct dentry, d_u.d_child);
+ di = ceph_dentry(dentry);
+ }
+
+ atomic_inc(&dentry->d_count);
+ spin_unlock(&dcache_lock);
+ spin_unlock(&inode->i_lock);
+
+ dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos,
+ dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+ filp->f_pos = di->offset;
+ err = filldir(dirent, dentry->d_name.name,
+ dentry->d_name.len, di->offset,
+ dentry->d_inode->i_ino,
+ dentry->d_inode->i_mode >> 12);
+
+ if (last) {
+ if (err < 0) {
+ /* remember our position */
+ fi->dentry = last;
+ fi->next_offset = di->offset;
+ } else {
+ dput(last);
+ }
+ last = NULL;
+ }
+
+ spin_lock(&inode->i_lock);
+ spin_lock(&dcache_lock);
+
+ last = dentry;
+
+ if (err < 0)
+ goto out_unlock;
+
+ p = p->prev;
+ filp->f_pos++;
+
+ /* make sure a dentry wasn't dropped while we didn't have dcache_lock */
+ if ((ceph_inode(dir)->i_ceph_flags & CEPH_I_COMPLETE))
+ goto more;
+ dout(" lost I_COMPLETE on %p; falling back to mds\n", dir);
+ err = -EAGAIN;
+
+out_unlock:
+ spin_unlock(&dcache_lock);
+
+ if (last) {
+ spin_unlock(&inode->i_lock);
+ dput(last);
+ spin_lock(&inode->i_lock);
+ }
+
+ return err;
+}
+
+/*
+ * make note of the last dentry we read, so we can
+ * continue at the same lexicographical point,
+ * regardless of what dir changes take place on the
+ * server.
+ */
+static int note_last_dentry(struct ceph_file_info *fi, const char *name,
+ int len)
+{
+ kfree(fi->last_name);
+ fi->last_name = kmalloc(len+1, GFP_NOFS);
+ if (!fi->last_name)
+ return -ENOMEM;
+ memcpy(fi->last_name, name, len);
+ fi->last_name[len] = 0;
+ dout("note_last_dentry '%s'\n", fi->last_name);
+ return 0;
+}
+
+static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ struct ceph_file_info *fi = filp->private_data;
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_client *client = ceph_inode_to_client(inode);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ unsigned frag = fpos_frag(filp->f_pos);
+ int off = fpos_off(filp->f_pos);
+ int err;
+ u32 ftype;
+ struct ceph_mds_reply_info_parsed *rinfo;
+ const int max_entries = client->mount_args->max_readdir;
+
+ dout("readdir %p filp %p frag %u off %u\n", inode, filp, frag, off);
+ if (fi->at_end)
+ return 0;
+
+ /* always start with . and .. */
+ if (filp->f_pos == 0) {
+ /* note dir version at start of readdir so we can tell
+ * if any dentries get dropped */
+ fi->dir_release_count = ci->i_release_count;
+
+ dout("readdir off 0 -> '.'\n");
+ if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0),
+ inode->i_ino, inode->i_mode >> 12) < 0)
+ return 0;
+ filp->f_pos = 1;
+ off = 1;
+ }
+ if (filp->f_pos == 1) {
+ dout("readdir off 1 -> '..'\n");
+ if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1),
+ filp->f_dentry->d_parent->d_inode->i_ino,
+ inode->i_mode >> 12) < 0)
+ return 0;
+ filp->f_pos = 2;
+ off = 2;
+ }
+
+ /* can we use the dcache? */
+ spin_lock(&inode->i_lock);
+ if ((filp->f_pos == 2 || fi->dentry) &&
+ !ceph_test_opt(client, NOASYNCREADDIR) &&
+ (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
+ __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
+ err = __dcache_readdir(filp, dirent, filldir);
+ if (err != -EAGAIN) {
+ spin_unlock(&inode->i_lock);
+ return err;
+ }
+ }
+ spin_unlock(&inode->i_lock);
+ if (fi->dentry) {
+ err = note_last_dentry(fi, fi->dentry->d_name.name,
+ fi->dentry->d_name.len);
+ if (err)
+ return err;
+ dput(fi->dentry);
+ fi->dentry = NULL;
+ }
+
+ /* proceed with a normal readdir */
+
+more:
+ /* do we have the correct frag content buffered? */
+ if (fi->frag != frag || fi->last_readdir == NULL) {
+ struct ceph_mds_request *req;
+ int op = ceph_snap(inode) == CEPH_SNAPDIR ?
+ CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR;
+
+ /* discard old result, if any */
+ if (fi->last_readdir) {
+ ceph_mdsc_put_request(fi->last_readdir);
+ fi->last_readdir = NULL;
+ }
+
+ /* requery frag tree, as the frag topology may have changed */
+ frag = ceph_choose_frag(ceph_inode(inode), frag, NULL, NULL);
+
+ dout("readdir fetching %llx.%llx frag %x offset '%s'\n",
+ ceph_vinop(inode), frag, fi->last_name);
+ req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+ req->r_inode = igrab(inode);
+ req->r_dentry = dget(filp->f_dentry);
+ /* hints to request -> mds selection code */
+ req->r_direct_mode = USE_AUTH_MDS;
+ req->r_direct_hash = ceph_frag_value(frag);
+ req->r_direct_is_hash = true;
+ req->r_path2 = kstrdup(fi->last_name, GFP_NOFS);
+ req->r_readdir_offset = fi->next_offset;
+ req->r_args.readdir.frag = cpu_to_le32(frag);
+ req->r_args.readdir.max_entries = cpu_to_le32(max_entries);
+ req->r_num_caps = max_entries + 1;
+ err = ceph_mdsc_do_request(mdsc, NULL, req);
+ if (err < 0) {
+ ceph_mdsc_put_request(req);
+ return err;
+ }
+ dout("readdir got and parsed readdir result=%d"
+ " on frag %x, end=%d, complete=%d\n", err, frag,
+ (int)req->r_reply_info.dir_end,
+ (int)req->r_reply_info.dir_complete);
+
+ if (!req->r_did_prepopulate) {
+ dout("readdir !did_prepopulate");
+ fi->dir_release_count--; /* preclude I_COMPLETE */
+ }
+
+ /* note next offset and last dentry name */
+ fi->offset = fi->next_offset;
+ fi->last_readdir = req;
+
+ if (req->r_reply_info.dir_end) {
+ kfree(fi->last_name);
+ fi->last_name = NULL;
+ fi->next_offset = 0;
+ } else {
+ rinfo = &req->r_reply_info;
+ err = note_last_dentry(fi,
+ rinfo->dir_dname[rinfo->dir_nr-1],
+ rinfo->dir_dname_len[rinfo->dir_nr-1]);
+ if (err)
+ return err;
+ fi->next_offset += rinfo->dir_nr;
+ }
+ }
+
+ rinfo = &fi->last_readdir->r_reply_info;
+ dout("readdir frag %x num %d off %d chunkoff %d\n", frag,
+ rinfo->dir_nr, off, fi->offset);
+ while (off - fi->offset >= 0 && off - fi->offset < rinfo->dir_nr) {
+ u64 pos = ceph_make_fpos(frag, off);
+ struct ceph_mds_reply_inode *in =
+ rinfo->dir_in[off - fi->offset].in;
+ dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
+ off, off - fi->offset, rinfo->dir_nr, pos,
+ rinfo->dir_dname_len[off - fi->offset],
+ rinfo->dir_dname[off - fi->offset], in);
+ BUG_ON(!in);
+ ftype = le32_to_cpu(in->mode) >> 12;
+ if (filldir(dirent,
+ rinfo->dir_dname[off - fi->offset],
+ rinfo->dir_dname_len[off - fi->offset],
+ pos,
+ le64_to_cpu(in->ino),
+ ftype) < 0) {
+ dout("filldir stopping us...\n");
+ return 0;
+ }
+ off++;
+ filp->f_pos = pos + 1;
+ }
+
+ if (fi->last_name) {
+ ceph_mdsc_put_request(fi->last_readdir);
+ fi->last_readdir = NULL;
+ goto more;
+ }
+
+ /* more frags? */
+ if (!ceph_frag_is_rightmost(frag)) {
+ frag = ceph_frag_next(frag);
+ off = 0;
+ filp->f_pos = ceph_make_fpos(frag, off);
+ dout("readdir next frag is %x\n", frag);
+ goto more;
+ }
+ fi->at_end = 1;
+
+ /*
+ * if dir_release_count still matches the dir, no dentries
+ * were released during the whole readdir, and we should have
+ * the complete dir contents in our cache.
+ */
+ spin_lock(&inode->i_lock);
+ if (ci->i_release_count == fi->dir_release_count) {
+ dout(" marking %p complete\n", inode);
+ ci->i_ceph_flags |= CEPH_I_COMPLETE;
+ ci->i_max_offset = filp->f_pos;
+ }
+ spin_unlock(&inode->i_lock);
+
+ dout("readdir %p filp %p done.\n", inode, filp);
+ return 0;
+}
+
+static void reset_readdir(struct ceph_file_info *fi)
+{
+ if (fi->last_readdir) {
+ ceph_mdsc_put_request(fi->last_readdir);
+ fi->last_readdir = NULL;
+ }
+ kfree(fi->last_name);
+ fi->next_offset = 2; /* compensate for . and .. */
+ if (fi->dentry) {
+ dput(fi->dentry);
+ fi->dentry = NULL;
+ }
+ fi->at_end = 0;
+}
+
+static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int origin)
+{
+ struct ceph_file_info *fi = file->private_data;
+ struct inode *inode = file->f_mapping->host;
+ loff_t old_offset = offset;
+ loff_t retval;
+
+ mutex_lock(&inode->i_mutex);
+ switch (origin) {
+ case SEEK_END:
+ offset += inode->i_size + 2; /* FIXME */
+ break;
+ case SEEK_CUR:
+ offset += file->f_pos;
+ }
+ retval = -EINVAL;
+ if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
+ if (offset != file->f_pos) {
+ file->f_pos = offset;
+ file->f_version = 0;
+ fi->at_end = 0;
+ }
+ retval = offset;
+
+ /*
+ * discard buffered readdir content on seekdir(0), or
+ * seek to new frag, or seek prior to current chunk.
+ */
+ if (offset == 0 ||
+ fpos_frag(offset) != fpos_frag(old_offset) ||
+ fpos_off(offset) < fi->offset) {
+ dout("dir_llseek dropping %p content\n", file);
+ reset_readdir(fi);
+ }
+
+ /* bump dir_release_count if we did a forward seek */
+ if (offset > old_offset)
+ fi->dir_release_count--;
+ }
+ mutex_unlock(&inode->i_mutex);
+ return retval;
+}
+
+/*
+ * Process result of a lookup/open request.
+ *
+ * Mainly, make sure we return the final req->r_dentry (if it already
+ * existed) in place of the original VFS-provided dentry when they
+ * differ.
+ *
+ * Gracefully handle the case where the MDS replies with -ENOENT and
+ * no trace (which it may do, at its discretion, e.g., if it doesn't
+ * care to issue a lease on the negative dentry).
+ */
+struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
+ struct dentry *dentry, int err)
+{
+ struct ceph_client *client = ceph_client(dentry->d_sb);
+ struct inode *parent = dentry->d_parent->d_inode;
+
+ /* .snap dir? */
+ if (err == -ENOENT &&
+ ceph_vino(parent).ino != CEPH_INO_ROOT && /* no .snap in root dir */
+ strcmp(dentry->d_name.name,
+ client->mount_args->snapdir_name) == 0) {
+ struct inode *inode = ceph_get_snapdir(parent);
+ dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n",
+ dentry, dentry->d_name.len, dentry->d_name.name, inode);
+ BUG_ON(!d_unhashed(dentry));
+ d_add(dentry, inode);
+ err = 0;
+ }
+
+ if (err == -ENOENT) {
+ /* no trace? */
+ err = 0;
+ if (!req->r_reply_info.head->is_dentry) {
+ dout("ENOENT and no trace, dentry %p inode %p\n",
+ dentry, dentry->d_inode);
+ if (dentry->d_inode) {
+ d_drop(dentry);
+ err = -ENOENT;
+ } else {
+ d_add(dentry, NULL);
+ }
+ }
+ }
+ if (err)
+ dentry = ERR_PTR(err);
+ else if (dentry != req->r_dentry)
+ dentry = dget(req->r_dentry); /* we got spliced */
+ else
+ dentry = NULL;
+ return dentry;
+}
+
+static int is_root_ceph_dentry(struct inode *inode, struct dentry *dentry)
+{
+ return ceph_ino(inode) == CEPH_INO_ROOT &&
+ strncmp(dentry->d_name.name, ".ceph", 5) == 0;
+}
+
+/*
+ * Look up a single dir entry. If there is a lookup intent, inform
+ * the MDS so that it gets our 'caps wanted' value in a single op.
+ */
+static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ int op;
+ int err;
+
+ dout("lookup %p dentry %p '%.*s'\n",
+ dir, dentry, dentry->d_name.len, dentry->d_name.name);
+
+ if (dentry->d_name.len > NAME_MAX)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ err = ceph_init_dentry(dentry);
+ if (err < 0)
+ return ERR_PTR(err);
+
+ /* open (but not create!) intent? */
+ if (nd &&
+ (nd->flags & LOOKUP_OPEN) &&
+ (nd->flags & LOOKUP_CONTINUE) == 0 && /* only open last component */
+ !(nd->intent.open.flags & O_CREAT)) {
+ int mode = nd->intent.open.create_mode & ~current->fs->umask;
+ return ceph_lookup_open(dir, dentry, nd, mode, 1);
+ }
+
+ /* can we conclude ENOENT locally? */
+ if (dentry->d_inode == NULL) {
+ struct ceph_inode_info *ci = ceph_inode(dir);
+ struct ceph_dentry_info *di = ceph_dentry(dentry);
+
+ spin_lock(&dir->i_lock);
+ dout(" dir %p flags are %d\n", dir, ci->i_ceph_flags);
+ if (strncmp(dentry->d_name.name,
+ client->mount_args->snapdir_name,
+ dentry->d_name.len) &&
+ !is_root_ceph_dentry(dir, dentry) &&
+ (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
+ (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) {
+ di->offset = ci->i_max_offset++;
+ spin_unlock(&dir->i_lock);
+ dout(" dir %p complete, -ENOENT\n", dir);
+ d_add(dentry, NULL);
+ di->lease_shared_gen = ci->i_shared_gen;
+ return NULL;
+ }
+ spin_unlock(&dir->i_lock);
+ }
+
+ op = ceph_snap(dir) == CEPH_SNAPDIR ?
+ CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
+ req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
+ if (IS_ERR(req))
+ return ERR_PTR(PTR_ERR(req));
+ req->r_dentry = dget(dentry);
+ req->r_num_caps = 2;
+ /* we only need inode linkage */
+ req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
+ req->r_locked_dir = dir;
+ err = ceph_mdsc_do_request(mdsc, NULL, req);
+ dentry = ceph_finish_lookup(req, dentry, err);
+ ceph_mdsc_put_request(req); /* will dput(dentry) */
+ dout("lookup result=%p\n", dentry);
+ return dentry;
+}
+
+/*
+ * If we do a create but get no trace back from the MDS, follow up with
+ * a lookup (the VFS expects us to link up the provided dentry).
+ */
+int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry)
+{
+ struct dentry *result = ceph_lookup(dir, dentry, NULL);
+
+ if (result && !IS_ERR(result)) {
+ /*
+ * We created the item, then did a lookup, and found
+ * it was already linked to another inode we already
+ * had in our cache (and thus got spliced). Link our
+ * dentry to that inode, but don't hash it, just in
+ * case the VFS wants to dereference it.
+ */
+ BUG_ON(!result->d_inode);
+ d_instantiate(dentry, result->d_inode);
+ return 0;
+ }
+ return PTR_ERR(result);
+}
+
+static int ceph_mknod(struct inode *dir, struct dentry *dentry,
+ int mode, dev_t rdev)
+{
+ struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ int err;
+
+ if (ceph_snap(dir) != CEPH_NOSNAP)
+ return -EROFS;
+
+ dout("mknod in dir %p dentry %p mode 0%o rdev %d\n",
+ dir, dentry, mode, rdev);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, USE_AUTH_MDS);
+ if (IS_ERR(req)) {
+ d_drop(dentry);
+ return PTR_ERR(req);
+ }
+ req->r_dentry = dget(dentry);
+ req->r_num_caps = 2;
+ req->r_locked_dir = dir;
+ req->r_args.mknod.mode = cpu_to_le32(mode);
+ req->r_args.mknod.rdev = cpu_to_le32(rdev);
+ req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+ req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+ err = ceph_mdsc_do_request(mdsc, dir, req);
+ if (!err && !req->r_reply_info.head->is_dentry)
+ err = ceph_handle_notrace_create(dir, dentry);
+ ceph_mdsc_put_request(req);
+ if (err)
+ d_drop(dentry);
+ return err;
+}
+
+static int ceph_create(struct inode *dir, struct dentry *dentry, int mode,
+ struct nameidata *nd)
+{
+ dout("create in dir %p dentry %p name '%.*s'\n",
+ dir, dentry, dentry->d_name.len, dentry->d_name.name);
+
+ if (ceph_snap(dir) != CEPH_NOSNAP)
+ return -EROFS;
+
+ if (nd) {
+ BUG_ON((nd->flags & LOOKUP_OPEN) == 0);
+ dentry = ceph_lookup_open(dir, dentry, nd, mode, 0);
+ /* hrm, what should i do here if we get aliased? */
+ if (IS_ERR(dentry))
+ return PTR_ERR(dentry);
+ return 0;
+ }
+
+ /* fall back to mknod */
+ return ceph_mknod(dir, dentry, (mode & ~S_IFMT) | S_IFREG, 0);
+}
+
+static int ceph_symlink(struct inode *dir, struct dentry *dentry,
+ const char *dest)
+{
+ struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ int err;
+
+ if (ceph_snap(dir) != CEPH_NOSNAP)
+ return -EROFS;
+
+ dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS);
+ if (IS_ERR(req)) {
+ d_drop(dentry);
+ return PTR_ERR(req);
+ }
+ req->r_dentry = dget(dentry);
+ req->r_num_caps = 2;
+ req->r_path2 = kstrdup(dest, GFP_NOFS);
+ req->r_locked_dir = dir;
+ req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+ req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+ err = ceph_mdsc_do_request(mdsc, dir, req);
+ if (!err && !req->r_reply_info.head->is_dentry)
+ err = ceph_handle_notrace_create(dir, dentry);
+ ceph_mdsc_put_request(req);
+ if (err)
+ d_drop(dentry);
+ return err;
+}
+
+static int ceph_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ int err = -EROFS;
+ int op;
+
+ if (ceph_snap(dir) == CEPH_SNAPDIR) {
+ /* mkdir .snap/foo is a MKSNAP */
+ op = CEPH_MDS_OP_MKSNAP;
+ dout("mksnap dir %p snap '%.*s' dn %p\n", dir,
+ dentry->d_name.len, dentry->d_name.name, dentry);
+ } else if (ceph_snap(dir) == CEPH_NOSNAP) {
+ dout("mkdir dir %p dn %p mode 0%o\n", dir, dentry, mode);
+ op = CEPH_MDS_OP_MKDIR;
+ } else {
+ goto out;
+ }
+ req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto out;
+ }
+
+ req->r_dentry = dget(dentry);
+ req->r_num_caps = 2;
+ req->r_locked_dir = dir;
+ req->r_args.mkdir.mode = cpu_to_le32(mode);
+ req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+ req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+ err = ceph_mdsc_do_request(mdsc, dir, req);
+ if (!err && !req->r_reply_info.head->is_dentry)
+ err = ceph_handle_notrace_create(dir, dentry);
+ ceph_mdsc_put_request(req);
+out:
+ if (err < 0)
+ d_drop(dentry);
+ return err;
+}
+
+static int ceph_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ int err;
+
+ if (ceph_snap(dir) != CEPH_NOSNAP)
+ return -EROFS;
+
+ dout("link in dir %p old_dentry %p dentry %p\n", dir,
+ old_dentry, dentry);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK, USE_AUTH_MDS);
+ if (IS_ERR(req)) {
+ d_drop(dentry);
+ return PTR_ERR(req);
+ }
+ req->r_dentry = dget(dentry);
+ req->r_num_caps = 2;
+ req->r_old_dentry = dget(old_dentry); /* or inode? hrm. */
+ req->r_locked_dir = dir;
+ req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+ req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+ err = ceph_mdsc_do_request(mdsc, dir, req);
+ if (err)
+ d_drop(dentry);
+ else if (!req->r_reply_info.head->is_dentry)
+ d_instantiate(dentry, igrab(old_dentry->d_inode));
+ ceph_mdsc_put_request(req);
+ return err;
+}
+
+/*
+ * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps. If it
+ * looks like the link count will hit 0, drop any other caps (other
+ * than PIN) we don't specifically want (due to the file still being
+ * open).
+ */
+static int drop_caps_for_unlink(struct inode *inode)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
+
+ spin_lock(&inode->i_lock);
+ if (inode->i_nlink == 1) {
+ drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN);
+ ci->i_ceph_flags |= CEPH_I_NODELAY;
+ }
+ spin_unlock(&inode->i_lock);
+ return drop;
+}
+
+/*
+ * rmdir and unlink are differ only by the metadata op code
+ */
+static int ceph_unlink(struct inode *dir, struct dentry *dentry)
+{
+ struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct inode *inode = dentry->d_inode;
+ struct ceph_mds_request *req;
+ int err = -EROFS;
+ int op;
+
+ if (ceph_snap(dir) == CEPH_SNAPDIR) {
+ /* rmdir .snap/foo is RMSNAP */
+ dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len,
+ dentry->d_name.name, dentry);
+ op = CEPH_MDS_OP_RMSNAP;
+ } else if (ceph_snap(dir) == CEPH_NOSNAP) {
+ dout("unlink/rmdir dir %p dn %p inode %p\n",
+ dir, dentry, inode);
+ op = ((dentry->d_inode->i_mode & S_IFMT) == S_IFDIR) ?
+ CEPH_MDS_OP_RMDIR : CEPH_MDS_OP_UNLINK;
+ } else
+ goto out;
+ req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto out;
+ }
+ req->r_dentry = dget(dentry);
+ req->r_num_caps = 2;
+ req->r_locked_dir = dir;
+ req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+ req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+ req->r_inode_drop = drop_caps_for_unlink(inode);
+ err = ceph_mdsc_do_request(mdsc, dir, req);
+ if (!err && !req->r_reply_info.head->is_dentry)
+ d_delete(dentry);
+ ceph_mdsc_put_request(req);
+out:
+ return err;
+}
+
+static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct ceph_client *client = ceph_sb_to_client(old_dir->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ int err;
+
+ if (ceph_snap(old_dir) != ceph_snap(new_dir))
+ return -EXDEV;
+ if (ceph_snap(old_dir) != CEPH_NOSNAP ||
+ ceph_snap(new_dir) != CEPH_NOSNAP)
+ return -EROFS;
+ dout("rename dir %p dentry %p to dir %p dentry %p\n",
+ old_dir, old_dentry, new_dir, new_dentry);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+ req->r_dentry = dget(new_dentry);
+ req->r_num_caps = 2;
+ req->r_old_dentry = dget(old_dentry);
+ req->r_locked_dir = new_dir;
+ req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED;
+ req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL;
+ req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+ req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+ /* release LINK_RDCACHE on source inode (mds will lock it) */
+ req->r_old_inode_drop = CEPH_CAP_LINK_SHARED;
+ if (new_dentry->d_inode)
+ req->r_inode_drop = drop_caps_for_unlink(new_dentry->d_inode);
+ err = ceph_mdsc_do_request(mdsc, old_dir, req);
+ if (!err && !req->r_reply_info.head->is_dentry) {
+ /*
+ * Normally d_move() is done by fill_trace (called by
+ * do_request, above). If there is no trace, we need
+ * to do it here.
+ */
+ d_move(old_dentry, new_dentry);
+ }
+ ceph_mdsc_put_request(req);
+ return err;
+}
+
+
+/*
+ * Check if dentry lease is valid. If not, delete the lease. Try to
+ * renew if the least is more than half up.
+ */
+static int dentry_lease_is_valid(struct dentry *dentry)
+{
+ struct ceph_dentry_info *di;
+ struct ceph_mds_session *s;
+ int valid = 0;
+ u32 gen;
+ unsigned long ttl;
+ struct ceph_mds_session *session = NULL;
+ struct inode *dir = NULL;
+ u32 seq = 0;
+
+ spin_lock(&dentry->d_lock);
+ di = ceph_dentry(dentry);
+ if (di && di->lease_session) {
+ s = di->lease_session;
+ spin_lock(&s->s_cap_lock);
+ gen = s->s_cap_gen;
+ ttl = s->s_cap_ttl;
+ spin_unlock(&s->s_cap_lock);
+
+ if (di->lease_gen == gen &&
+ time_before(jiffies, dentry->d_time) &&
+ time_before(jiffies, ttl)) {
+ valid = 1;
+ if (di->lease_renew_after &&
+ time_after(jiffies, di->lease_renew_after)) {
+ /* we should renew */
+ dir = dentry->d_parent->d_inode;
+ session = ceph_get_mds_session(s);
+ seq = di->lease_seq;
+ di->lease_renew_after = 0;
+ di->lease_renew_from = jiffies;
+ }
+ }
+ }
+ spin_unlock(&dentry->d_lock);
+
+ if (session) {
+ ceph_mdsc_lease_send_msg(session, dir, dentry,
+ CEPH_MDS_LEASE_RENEW, seq);
+ ceph_put_mds_session(session);
+ }
+ dout("dentry_lease_is_valid - dentry %p = %d\n", dentry, valid);
+ return valid;
+}
+
+/*
+ * Check if directory-wide content lease/cap is valid.
+ */
+static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry)
+{
+ struct ceph_inode_info *ci = ceph_inode(dir);
+ struct ceph_dentry_info *di = ceph_dentry(dentry);
+ int valid = 0;
+
+ spin_lock(&dir->i_lock);
+ if (ci->i_shared_gen == di->lease_shared_gen)
+ valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1);
+ spin_unlock(&dir->i_lock);
+ dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n",
+ dir, (unsigned)ci->i_shared_gen, dentry,
+ (unsigned)di->lease_shared_gen, valid);
+ return valid;
+}
+
+/*
+ * Check if cached dentry can be trusted.
+ */
+static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+ struct inode *dir = dentry->d_parent->d_inode;
+
+ dout("d_revalidate %p '%.*s' inode %p\n", dentry,
+ dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+
+ /* always trust cached snapped dentries, snapdir dentry */
+ if (ceph_snap(dir) != CEPH_NOSNAP) {
+ dout("d_revalidate %p '%.*s' inode %p is SNAPPED\n", dentry,
+ dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+ goto out_touch;
+ }
+ if (dentry->d_inode && ceph_snap(dentry->d_inode) == CEPH_SNAPDIR)
+ goto out_touch;
+
+ if (dentry_lease_is_valid(dentry) ||
+ dir_lease_is_valid(dir, dentry))
+ goto out_touch;
+
+ dout("d_revalidate %p invalid\n", dentry);
+ d_drop(dentry);
+ return 0;
+out_touch:
+ ceph_dentry_lru_touch(dentry);
+ return 1;
+}
+
+/*
+ * When a dentry is released, clear the dir I_COMPLETE if it was part
+ * of the current dir gen.
+ */
+static void ceph_dentry_release(struct dentry *dentry)
+{
+ struct ceph_dentry_info *di = ceph_dentry(dentry);
+ struct inode *parent_inode = dentry->d_parent->d_inode;
+
+ if (parent_inode) {
+ struct ceph_inode_info *ci = ceph_inode(parent_inode);
+
+ spin_lock(&parent_inode->i_lock);
+ if (ci->i_shared_gen == di->lease_shared_gen) {
+ dout(" clearing %p complete (d_release)\n",
+ parent_inode);
+ ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+ ci->i_release_count++;
+ }
+ spin_unlock(&parent_inode->i_lock);
+ }
+ if (di) {
+ ceph_dentry_lru_del(dentry);
+ if (di->lease_session)
+ ceph_put_mds_session(di->lease_session);
+ kmem_cache_free(ceph_dentry_cachep, di);
+ dentry->d_fsdata = NULL;
+ }
+}
+
+static int ceph_snapdir_d_revalidate(struct dentry *dentry,
+ struct nameidata *nd)
+{
+ /*
+ * Eventually, we'll want to revalidate snapped metadata
+ * too... probably...
+ */
+ return 1;
+}
+
+
+
+/*
+ * read() on a dir. This weird interface hack only works if mounted
+ * with '-o dirstat'.
+ */
+static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
+ loff_t *ppos)
+{
+ struct ceph_file_info *cf = file->private_data;
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int left;
+
+ if (!ceph_test_opt(ceph_client(inode->i_sb), DIRSTAT))
+ return -EISDIR;
+
+ if (!cf->dir_info) {
+ cf->dir_info = kmalloc(1024, GFP_NOFS);
+ if (!cf->dir_info)
+ return -ENOMEM;
+ cf->dir_info_len =
+ sprintf(cf->dir_info,
+ "entries: %20lld\n"
+ " files: %20lld\n"
+ " subdirs: %20lld\n"
+ "rentries: %20lld\n"
+ " rfiles: %20lld\n"
+ " rsubdirs: %20lld\n"
+ "rbytes: %20lld\n"
+ "rctime: %10ld.%09ld\n",
+ ci->i_files + ci->i_subdirs,
+ ci->i_files,
+ ci->i_subdirs,
+ ci->i_rfiles + ci->i_rsubdirs,
+ ci->i_rfiles,
+ ci->i_rsubdirs,
+ ci->i_rbytes,
+ (long)ci->i_rctime.tv_sec,
+ (long)ci->i_rctime.tv_nsec);
+ }
+
+ if (*ppos >= cf->dir_info_len)
+ return 0;
+ size = min_t(unsigned, size, cf->dir_info_len-*ppos);
+ left = copy_to_user(buf, cf->dir_info + *ppos, size);
+ if (left == size)
+ return -EFAULT;
+ *ppos += (size - left);
+ return size - left;
+}
+
+/*
+ * an fsync() on a dir will wait for any uncommitted directory
+ * operations to commit.
+ */
+static int ceph_dir_fsync(struct file *file, struct dentry *dentry,
+ int datasync)
+{
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct list_head *head = &ci->i_unsafe_dirops;
+ struct ceph_mds_request *req;
+ u64 last_tid;
+ int ret = 0;
+
+ dout("dir_fsync %p\n", inode);
+ spin_lock(&ci->i_unsafe_lock);
+ if (list_empty(head))
+ goto out;
+
+ req = list_entry(head->prev,
+ struct ceph_mds_request, r_unsafe_dir_item);
+ last_tid = req->r_tid;
+
+ do {
+ ceph_mdsc_get_request(req);
+ spin_unlock(&ci->i_unsafe_lock);
+ dout("dir_fsync %p wait on tid %llu (until %llu)\n",
+ inode, req->r_tid, last_tid);
+ if (req->r_timeout) {
+ ret = wait_for_completion_timeout(
+ &req->r_safe_completion, req->r_timeout);
+ if (ret > 0)
+ ret = 0;
+ else if (ret == 0)
+ ret = -EIO; /* timed out */
+ } else {
+ wait_for_completion(&req->r_safe_completion);
+ }
+ spin_lock(&ci->i_unsafe_lock);
+ ceph_mdsc_put_request(req);
+
+ if (ret || list_empty(head))
+ break;
+ req = list_entry(head->next,
+ struct ceph_mds_request, r_unsafe_dir_item);
+ } while (req->r_tid < last_tid);
+out:
+ spin_unlock(&ci->i_unsafe_lock);
+ return ret;
+}
+
+/*
+ * We maintain a private dentry LRU.
+ *
+ * FIXME: this needs to be changed to a per-mds lru to be useful.
+ */
+void ceph_dentry_lru_add(struct dentry *dn)
+{
+ struct ceph_dentry_info *di = ceph_dentry(dn);
+ struct ceph_mds_client *mdsc;
+
+ dout("dentry_lru_add %p %p '%.*s'\n", di, dn,
+ dn->d_name.len, dn->d_name.name);
+ if (di) {
+ mdsc = &ceph_client(dn->d_sb)->mdsc;
+ spin_lock(&mdsc->dentry_lru_lock);
+ list_add_tail(&di->lru, &mdsc->dentry_lru);
+ mdsc->num_dentry++;
+ spin_unlock(&mdsc->dentry_lru_lock);
+ }
+}
+
+void ceph_dentry_lru_touch(struct dentry *dn)
+{
+ struct ceph_dentry_info *di = ceph_dentry(dn);
+ struct ceph_mds_client *mdsc;
+
+ dout("dentry_lru_touch %p %p '%.*s'\n", di, dn,
+ dn->d_name.len, dn->d_name.name);
+ if (di) {
+ mdsc = &ceph_client(dn->d_sb)->mdsc;
+ spin_lock(&mdsc->dentry_lru_lock);
+ list_move_tail(&di->lru, &mdsc->dentry_lru);
+ spin_unlock(&mdsc->dentry_lru_lock);
+ }
+}
+
+void ceph_dentry_lru_del(struct dentry *dn)
+{
+ struct ceph_dentry_info *di = ceph_dentry(dn);
+ struct ceph_mds_client *mdsc;
+
+ dout("dentry_lru_del %p %p '%.*s'\n", di, dn,
+ dn->d_name.len, dn->d_name.name);
+ if (di) {
+ mdsc = &ceph_client(dn->d_sb)->mdsc;
+ spin_lock(&mdsc->dentry_lru_lock);
+ list_del_init(&di->lru);
+ mdsc->num_dentry--;
+ spin_unlock(&mdsc->dentry_lru_lock);
+ }
+}
+
+const struct file_operations ceph_dir_fops = {
+ .read = ceph_read_dir,
+ .readdir = ceph_readdir,
+ .llseek = ceph_dir_llseek,
+ .open = ceph_open,
+ .release = ceph_release,
+ .unlocked_ioctl = ceph_ioctl,
+ .fsync = ceph_dir_fsync,
+};
+
+const struct inode_operations ceph_dir_iops = {
+ .lookup = ceph_lookup,
+ .permission = ceph_permission,
+ .getattr = ceph_getattr,
+ .setattr = ceph_setattr,
+ .setxattr = ceph_setxattr,
+ .getxattr = ceph_getxattr,
+ .listxattr = ceph_listxattr,
+ .removexattr = ceph_removexattr,
+ .mknod = ceph_mknod,
+ .symlink = ceph_symlink,
+ .mkdir = ceph_mkdir,
+ .link = ceph_link,
+ .unlink = ceph_unlink,
+ .rmdir = ceph_unlink,
+ .rename = ceph_rename,
+ .create = ceph_create,
+};
+
+struct dentry_operations ceph_dentry_ops = {
+ .d_revalidate = ceph_d_revalidate,
+ .d_release = ceph_dentry_release,
+};
+
+struct dentry_operations ceph_snapdir_dentry_ops = {
+ .d_revalidate = ceph_snapdir_d_revalidate,
+};
+
+struct dentry_operations ceph_snap_dentry_ops = {
+};
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
new file mode 100644
index 00000000000..9d67572fb32
--- /dev/null
+++ b/fs/ceph/export.c
@@ -0,0 +1,224 @@
+#include "ceph_debug.h"
+
+#include <linux/exportfs.h>
+#include <linux/slab.h>
+#include <asm/unaligned.h>
+
+#include "super.h"
+
+/*
+ * NFS export support
+ *
+ * NFS re-export of a ceph mount is, at present, only semireliable.
+ * The basic issue is that the Ceph architectures doesn't lend itself
+ * well to generating filehandles that will remain valid forever.
+ *
+ * So, we do our best. If you're lucky, your inode will be in the
+ * client's cache. If it's not, and you have a connectable fh, then
+ * the MDS server may be able to find it for you. Otherwise, you get
+ * ESTALE.
+ *
+ * There are ways to this more reliable, but in the non-connectable fh
+ * case, we won't every work perfectly, and in the connectable case,
+ * some changes are needed on the MDS side to work better.
+ */
+
+/*
+ * Basic fh
+ */
+struct ceph_nfs_fh {
+ u64 ino;
+} __attribute__ ((packed));
+
+/*
+ * Larger 'connectable' fh that includes parent ino and name hash.
+ * Use this whenever possible, as it works more reliably.
+ */
+struct ceph_nfs_confh {
+ u64 ino, parent_ino;
+ u32 parent_name_hash;
+} __attribute__ ((packed));
+
+static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
+ int connectable)
+{
+ struct ceph_nfs_fh *fh = (void *)rawfh;
+ struct ceph_nfs_confh *cfh = (void *)rawfh;
+ struct dentry *parent = dentry->d_parent;
+ struct inode *inode = dentry->d_inode;
+ int type;
+
+ /* don't re-export snaps */
+ if (ceph_snap(inode) != CEPH_NOSNAP)
+ return -EINVAL;
+
+ if (*max_len >= sizeof(*cfh)) {
+ dout("encode_fh %p connectable\n", dentry);
+ cfh->ino = ceph_ino(dentry->d_inode);
+ cfh->parent_ino = ceph_ino(parent->d_inode);
+ cfh->parent_name_hash = parent->d_name.hash;
+ *max_len = sizeof(*cfh);
+ type = 2;
+ } else if (*max_len > sizeof(*fh)) {
+ if (connectable)
+ return -ENOSPC;
+ dout("encode_fh %p\n", dentry);
+ fh->ino = ceph_ino(dentry->d_inode);
+ *max_len = sizeof(*fh);
+ type = 1;
+ } else {
+ return -ENOSPC;
+ }
+ return type;
+}
+
+/*
+ * convert regular fh to dentry
+ *
+ * FIXME: we should try harder by querying the mds for the ino.
+ */
+static struct dentry *__fh_to_dentry(struct super_block *sb,
+ struct ceph_nfs_fh *fh)
+{
+ struct inode *inode;
+ struct dentry *dentry;
+ struct ceph_vino vino;
+ int err;
+
+ dout("__fh_to_dentry %llx\n", fh->ino);
+ vino.ino = fh->ino;
+ vino.snap = CEPH_NOSNAP;
+ inode = ceph_find_inode(sb, vino);
+ if (!inode)
+ return ERR_PTR(-ESTALE);
+
+ dentry = d_obtain_alias(inode);
+ if (!dentry) {
+ pr_err("fh_to_dentry %llx -- inode %p but ENOMEM\n",
+ fh->ino, inode);
+ iput(inode);
+ return ERR_PTR(-ENOMEM);
+ }
+ err = ceph_init_dentry(dentry);
+
+ if (err < 0) {
+ iput(inode);
+ return ERR_PTR(err);
+ }
+ dout("__fh_to_dentry %llx %p dentry %p\n", fh->ino, inode, dentry);
+ return dentry;
+}
+
+/*
+ * convert connectable fh to dentry
+ */
+static struct dentry *__cfh_to_dentry(struct super_block *sb,
+ struct ceph_nfs_confh *cfh)
+{
+ struct ceph_mds_client *mdsc = &ceph_client(sb)->mdsc;
+ struct inode *inode;
+ struct dentry *dentry;
+ struct ceph_vino vino;
+ int err;
+
+ dout("__cfh_to_dentry %llx (%llx/%x)\n",
+ cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
+
+ vino.ino = cfh->ino;
+ vino.snap = CEPH_NOSNAP;
+ inode = ceph_find_inode(sb, vino);
+ if (!inode) {
+ struct ceph_mds_request *req;
+
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH,
+ USE_ANY_MDS);
+ if (IS_ERR(req))
+ return ERR_PTR(PTR_ERR(req));
+
+ req->r_ino1 = vino;
+ req->r_ino2.ino = cfh->parent_ino;
+ req->r_ino2.snap = CEPH_NOSNAP;
+ req->r_path2 = kmalloc(16, GFP_NOFS);
+ snprintf(req->r_path2, 16, "%d", cfh->parent_name_hash);
+ req->r_num_caps = 1;
+ err = ceph_mdsc_do_request(mdsc, NULL, req);
+ ceph_mdsc_put_request(req);
+ inode = ceph_find_inode(sb, vino);
+ if (!inode)
+ return ERR_PTR(err ? err : -ESTALE);
+ }
+
+ dentry = d_obtain_alias(inode);
+ if (!dentry) {
+ pr_err("cfh_to_dentry %llx -- inode %p but ENOMEM\n",
+ cfh->ino, inode);
+ iput(inode);
+ return ERR_PTR(-ENOMEM);
+ }
+ err = ceph_init_dentry(dentry);
+ if (err < 0) {
+ iput(inode);
+ return ERR_PTR(err);
+ }
+ dout("__cfh_to_dentry %llx %p dentry %p\n", cfh->ino, inode, dentry);
+ return dentry;
+}
+
+static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ if (fh_type == 1)
+ return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw);
+ else
+ return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw);
+}
+
+/*
+ * get parent, if possible.
+ *
+ * FIXME: we could do better by querying the mds to discover the
+ * parent.
+ */
+static struct dentry *ceph_fh_to_parent(struct super_block *sb,
+ struct fid *fid,
+ int fh_len, int fh_type)
+{
+ struct ceph_nfs_confh *cfh = (void *)fid->raw;
+ struct ceph_vino vino;
+ struct inode *inode;
+ struct dentry *dentry;
+ int err;
+
+ if (fh_type == 1)
+ return ERR_PTR(-ESTALE);
+
+ pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
+ cfh->parent_name_hash);
+
+ vino.ino = cfh->ino;
+ vino.snap = CEPH_NOSNAP;
+ inode = ceph_find_inode(sb, vino);
+ if (!inode)
+ return ERR_PTR(-ESTALE);
+
+ dentry = d_obtain_alias(inode);
+ if (!dentry) {
+ pr_err("fh_to_parent %llx -- inode %p but ENOMEM\n",
+ cfh->ino, inode);
+ iput(inode);
+ return ERR_PTR(-ENOMEM);
+ }
+ err = ceph_init_dentry(dentry);
+ if (err < 0) {
+ iput(inode);
+ return ERR_PTR(err);
+ }
+ dout("fh_to_parent %llx %p dentry %p\n", cfh->ino, inode, dentry);
+ return dentry;
+}
+
+const struct export_operations ceph_export_ops = {
+ .encode_fh = ceph_encode_fh,
+ .fh_to_dentry = ceph_fh_to_dentry,
+ .fh_to_parent = ceph_fh_to_parent,
+};
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
new file mode 100644
index 00000000000..4add3d5da2c
--- /dev/null
+++ b/fs/ceph/file.c
@@ -0,0 +1,938 @@
+#include "ceph_debug.h"
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/writeback.h>
+
+#include "super.h"
+#include "mds_client.h"
+
+/*
+ * Ceph file operations
+ *
+ * Implement basic open/close functionality, and implement
+ * read/write.
+ *
+ * We implement three modes of file I/O:
+ * - buffered uses the generic_file_aio_{read,write} helpers
+ *
+ * - synchronous is used when there is multi-client read/write
+ * sharing, avoids the page cache, and synchronously waits for an
+ * ack from the OSD.
+ *
+ * - direct io takes the variant of the sync path that references
+ * user pages directly.
+ *
+ * fsync() flushes and waits on dirty pages, but just queues metadata
+ * for writeback: since the MDS can recover size and mtime there is no
+ * need to wait for MDS acknowledgement.
+ */
+
+
+/*
+ * Prepare an open request. Preallocate ceph_cap to avoid an
+ * inopportune ENOMEM later.
+ */
+static struct ceph_mds_request *
+prepare_open_request(struct super_block *sb, int flags, int create_mode)
+{
+ struct ceph_client *client = ceph_sb_to_client(sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ int want_auth = USE_ANY_MDS;
+ int op = (flags & O_CREAT) ? CEPH_MDS_OP_CREATE : CEPH_MDS_OP_OPEN;
+
+ if (flags & (O_WRONLY|O_RDWR|O_CREAT|O_TRUNC))
+ want_auth = USE_AUTH_MDS;
+
+ req = ceph_mdsc_create_request(mdsc, op, want_auth);
+ if (IS_ERR(req))
+ goto out;
+ req->r_fmode = ceph_flags_to_mode(flags);
+ req->r_args.open.flags = cpu_to_le32(flags);
+ req->r_args.open.mode = cpu_to_le32(create_mode);
+ req->r_args.open.preferred = cpu_to_le32(-1);
+out:
+ return req;
+}
+
+/*
+ * initialize private struct file data.
+ * if we fail, clean up by dropping fmode reference on the ceph_inode
+ */
+static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
+{
+ struct ceph_file_info *cf;
+ int ret = 0;
+
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFREG:
+ case S_IFDIR:
+ dout("init_file %p %p 0%o (regular)\n", inode, file,
+ inode->i_mode);
+ cf = kmem_cache_alloc(ceph_file_cachep, GFP_NOFS | __GFP_ZERO);
+ if (cf == NULL) {
+ ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+ return -ENOMEM;
+ }
+ cf->fmode = fmode;
+ cf->next_offset = 2;
+ file->private_data = cf;
+ BUG_ON(inode->i_fop->release != ceph_release);
+ break;
+
+ case S_IFLNK:
+ dout("init_file %p %p 0%o (symlink)\n", inode, file,
+ inode->i_mode);
+ ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+ break;
+
+ default:
+ dout("init_file %p %p 0%o (special)\n", inode, file,
+ inode->i_mode);
+ /*
+ * we need to drop the open ref now, since we don't
+ * have .release set to ceph_release.
+ */
+ ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+ BUG_ON(inode->i_fop->release == ceph_release);
+
+ /* call the proper open fop */
+ ret = inode->i_fop->open(inode, file);
+ }
+ return ret;
+}
+
+/*
+ * If the filp already has private_data, that means the file was
+ * already opened by intent during lookup, and we do nothing.
+ *
+ * If we already have the requisite capabilities, we can satisfy
+ * the open request locally (no need to request new caps from the
+ * MDS). We do, however, need to inform the MDS (asynchronously)
+ * if our wanted caps set expands.
+ */
+int ceph_open(struct inode *inode, struct file *file)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_client *client = ceph_sb_to_client(inode->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ struct ceph_file_info *cf = file->private_data;
+ struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
+ int err;
+ int flags, fmode, wanted;
+
+ if (cf) {
+ dout("open file %p is already opened\n", file);
+ return 0;
+ }
+
+ /* filter out O_CREAT|O_EXCL; vfs did that already. yuck. */
+ flags = file->f_flags & ~(O_CREAT|O_EXCL);
+ if (S_ISDIR(inode->i_mode))
+ flags = O_DIRECTORY; /* mds likes to know */
+
+ dout("open inode %p ino %llx.%llx file %p flags %d (%d)\n", inode,
+ ceph_vinop(inode), file, flags, file->f_flags);
+ fmode = ceph_flags_to_mode(flags);
+ wanted = ceph_caps_for_mode(fmode);
+
+ /* snapped files are read-only */
+ if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE))
+ return -EROFS;
+
+ /* trivially open snapdir */
+ if (ceph_snap(inode) == CEPH_SNAPDIR) {
+ spin_lock(&inode->i_lock);
+ __ceph_get_fmode(ci, fmode);
+ spin_unlock(&inode->i_lock);
+ return ceph_init_file(inode, file, fmode);
+ }
+
+ /*
+ * No need to block if we have any caps. Update wanted set
+ * asynchronously.
+ */
+ spin_lock(&inode->i_lock);
+ if (__ceph_is_any_real_caps(ci)) {
+ int mds_wanted = __ceph_caps_mds_wanted(ci);
+ int issued = __ceph_caps_issued(ci, NULL);
+
+ dout("open %p fmode %d want %s issued %s using existing\n",
+ inode, fmode, ceph_cap_string(wanted),
+ ceph_cap_string(issued));
+ __ceph_get_fmode(ci, fmode);
+ spin_unlock(&inode->i_lock);
+
+ /* adjust wanted? */
+ if ((issued & wanted) != wanted &&
+ (mds_wanted & wanted) != wanted &&
+ ceph_snap(inode) != CEPH_SNAPDIR)
+ ceph_check_caps(ci, 0, NULL);
+
+ return ceph_init_file(inode, file, fmode);
+ } else if (ceph_snap(inode) != CEPH_NOSNAP &&
+ (ci->i_snap_caps & wanted) == wanted) {
+ __ceph_get_fmode(ci, fmode);
+ spin_unlock(&inode->i_lock);
+ return ceph_init_file(inode, file, fmode);
+ }
+ spin_unlock(&inode->i_lock);
+
+ dout("open fmode %d wants %s\n", fmode, ceph_cap_string(wanted));
+ req = prepare_open_request(inode->i_sb, flags, 0);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto out;
+ }
+ req->r_inode = igrab(inode);
+ req->r_num_caps = 1;
+ err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+ if (!err)
+ err = ceph_init_file(inode, file, req->r_fmode);
+ ceph_mdsc_put_request(req);
+ dout("open result=%d on %llx.%llx\n", err, ceph_vinop(inode));
+out:
+ return err;
+}
+
+
+/*
+ * Do a lookup + open with a single request.
+ *
+ * If this succeeds, but some subsequent check in the vfs
+ * may_open() fails, the struct *file gets cleaned up (i.e.
+ * ceph_release gets called). So fear not!
+ */
+/*
+ * flags
+ * path_lookup_open -> LOOKUP_OPEN
+ * path_lookup_create -> LOOKUP_OPEN|LOOKUP_CREATE
+ */
+struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd, int mode,
+ int locked_dir)
+{
+ struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct file *file = nd->intent.open.file;
+ struct inode *parent_inode = get_dentry_parent_inode(file->f_dentry);
+ struct ceph_mds_request *req;
+ int err;
+ int flags = nd->intent.open.flags - 1; /* silly vfs! */
+
+ dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n",
+ dentry, dentry->d_name.len, dentry->d_name.name, flags, mode);
+
+ /* do the open */
+ req = prepare_open_request(dir->i_sb, flags, mode);
+ if (IS_ERR(req))
+ return ERR_PTR(PTR_ERR(req));
+ req->r_dentry = dget(dentry);
+ req->r_num_caps = 2;
+ if (flags & O_CREAT) {
+ req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+ req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+ }
+ req->r_locked_dir = dir; /* caller holds dir->i_mutex */
+ err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+ dentry = ceph_finish_lookup(req, dentry, err);
+ if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
+ err = ceph_handle_notrace_create(dir, dentry);
+ if (!err)
+ err = ceph_init_file(req->r_dentry->d_inode, file,
+ req->r_fmode);
+ ceph_mdsc_put_request(req);
+ dout("ceph_lookup_open result=%p\n", dentry);
+ return dentry;
+}
+
+int ceph_release(struct inode *inode, struct file *file)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_file_info *cf = file->private_data;
+
+ dout("release inode %p file %p\n", inode, file);
+ ceph_put_fmode(ci, cf->fmode);
+ if (cf->last_readdir)
+ ceph_mdsc_put_request(cf->last_readdir);
+ kfree(cf->last_name);
+ kfree(cf->dir_info);
+ dput(cf->dentry);
+ kmem_cache_free(ceph_file_cachep, cf);
+
+ /* wake up anyone waiting for caps on this inode */
+ wake_up(&ci->i_cap_wq);
+ return 0;
+}
+
+/*
+ * build a vector of user pages
+ */
+static struct page **get_direct_page_vector(const char __user *data,
+ int num_pages,
+ loff_t off, size_t len)
+{
+ struct page **pages;
+ int rc;
+
+ pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS);
+ if (!pages)
+ return ERR_PTR(-ENOMEM);
+
+ down_read(&current->mm->mmap_sem);
+ rc = get_user_pages(current, current->mm, (unsigned long)data,
+ num_pages, 0, 0, pages, NULL);
+ up_read(&current->mm->mmap_sem);
+ if (rc < 0)
+ goto fail;
+ return pages;
+
+fail:
+ kfree(pages);
+ return ERR_PTR(rc);
+}
+
+static void put_page_vector(struct page **pages, int num_pages)
+{
+ int i;
+
+ for (i = 0; i < num_pages; i++)
+ put_page(pages[i]);
+ kfree(pages);
+}
+
+void ceph_release_page_vector(struct page **pages, int num_pages)
+{
+ int i;
+
+ for (i = 0; i < num_pages; i++)
+ __free_pages(pages[i], 0);
+ kfree(pages);
+}
+
+/*
+ * allocate a vector new pages
+ */
+static struct page **alloc_page_vector(int num_pages)
+{
+ struct page **pages;
+ int i;
+
+ pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS);
+ if (!pages)
+ return ERR_PTR(-ENOMEM);
+ for (i = 0; i < num_pages; i++) {
+ pages[i] = alloc_page(GFP_NOFS);
+ if (pages[i] == NULL) {
+ ceph_release_page_vector(pages, i);
+ return ERR_PTR(-ENOMEM);
+ }
+ }
+ return pages;
+}
+
+/*
+ * copy user data into a page vector
+ */
+static int copy_user_to_page_vector(struct page **pages,
+ const char __user *data,
+ loff_t off, size_t len)
+{
+ int i = 0;
+ int po = off & ~PAGE_CACHE_MASK;
+ int left = len;
+ int l, bad;
+
+ while (left > 0) {
+ l = min_t(int, PAGE_CACHE_SIZE-po, left);
+ bad = copy_from_user(page_address(pages[i]) + po, data, l);
+ if (bad == l)
+ return -EFAULT;
+ data += l - bad;
+ left -= l - bad;
+ po += l - bad;
+ if (po == PAGE_CACHE_SIZE) {
+ po = 0;
+ i++;
+ }
+ }
+ return len;
+}
+
+/*
+ * copy user data from a page vector into a user pointer
+ */
+static int copy_page_vector_to_user(struct page **pages, char __user *data,
+ loff_t off, size_t len)
+{
+ int i = 0;
+ int po = off & ~PAGE_CACHE_MASK;
+ int left = len;
+ int l, bad;
+
+ while (left > 0) {
+ l = min_t(int, left, PAGE_CACHE_SIZE-po);
+ bad = copy_to_user(data, page_address(pages[i]) + po, l);
+ if (bad == l)
+ return -EFAULT;
+ data += l - bad;
+ left -= l - bad;
+ if (po) {
+ po += l - bad;
+ if (po == PAGE_CACHE_SIZE)
+ po = 0;
+ }
+ i++;
+ }
+ return len;
+}
+
+/*
+ * Zero an extent within a page vector. Offset is relative to the
+ * start of the first page.
+ */
+static void zero_page_vector_range(int off, int len, struct page **pages)
+{
+ int i = off >> PAGE_CACHE_SHIFT;
+
+ off &= ~PAGE_CACHE_MASK;
+
+ dout("zero_page_vector_page %u~%u\n", off, len);
+
+ /* leading partial page? */
+ if (off) {
+ int end = min((int)PAGE_CACHE_SIZE, off + len);
+ dout("zeroing %d %p head from %d\n", i, pages[i],
+ (int)off);
+ zero_user_segment(pages[i], off, end);
+ len -= (end - off);
+ i++;
+ }
+ while (len >= PAGE_CACHE_SIZE) {
+ dout("zeroing %d %p len=%d\n", i, pages[i], len);
+ zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE);
+ len -= PAGE_CACHE_SIZE;
+ i++;
+ }
+ /* trailing partial page? */
+ if (len) {
+ dout("zeroing %d %p tail to %d\n", i, pages[i], (int)len);
+ zero_user_segment(pages[i], 0, len);
+ }
+}
+
+
+/*
+ * Read a range of bytes striped over one or more objects. Iterate over
+ * objects we stripe over. (That's not atomic, but good enough for now.)
+ *
+ * If we get a short result from the OSD, check against i_size; we need to
+ * only return a short read to the caller if we hit EOF.
+ */
+static int striped_read(struct inode *inode,
+ u64 off, u64 len,
+ struct page **pages, int num_pages,
+ int *checkeof)
+{
+ struct ceph_client *client = ceph_inode_to_client(inode);
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ u64 pos, this_len;
+ int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */
+ int left, pages_left;
+ int read;
+ struct page **page_pos;
+ int ret;
+ bool hit_stripe, was_short;
+
+ /*
+ * we may need to do multiple reads. not atomic, unfortunately.
+ */
+ pos = off;
+ left = len;
+ page_pos = pages;
+ pages_left = num_pages;
+ read = 0;
+
+more:
+ this_len = left;
+ ret = ceph_osdc_readpages(&client->osdc, ceph_vino(inode),
+ &ci->i_layout, pos, &this_len,
+ ci->i_truncate_seq,
+ ci->i_truncate_size,
+ page_pos, pages_left);
+ hit_stripe = this_len < left;
+ was_short = ret >= 0 && ret < this_len;
+ if (ret == -ENOENT)
+ ret = 0;
+ dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
+ ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
+
+ if (ret > 0) {
+ int didpages =
+ ((pos & ~PAGE_CACHE_MASK) + ret) >> PAGE_CACHE_SHIFT;
+
+ if (read < pos - off) {
+ dout(" zero gap %llu to %llu\n", off + read, pos);
+ zero_page_vector_range(page_off + read,
+ pos - off - read, pages);
+ }
+ pos += ret;
+ read = pos - off;
+ left -= ret;
+ page_pos += didpages;
+ pages_left -= didpages;
+
+ /* hit stripe? */
+ if (left && hit_stripe)
+ goto more;
+ }
+
+ if (was_short) {
+ /* was original extent fully inside i_size? */
+ if (pos + left <= inode->i_size) {
+ dout("zero tail\n");
+ zero_page_vector_range(page_off + read, len - read,
+ pages);
+ read = len;
+ goto out;
+ }
+
+ /* check i_size */
+ *checkeof = 1;
+ }
+
+out:
+ if (ret >= 0)
+ ret = read;
+ dout("striped_read returns %d\n", ret);
+ return ret;
+}
+
+/*
+ * Completely synchronous read and write methods. Direct from __user
+ * buffer to osd, or directly to user pages (if O_DIRECT).
+ *
+ * If the read spans object boundary, just do multiple reads.
+ */
+static ssize_t ceph_sync_read(struct file *file, char __user *data,
+ unsigned len, loff_t *poff, int *checkeof)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct page **pages;
+ u64 off = *poff;
+ int num_pages = calc_pages_for(off, len);
+ int ret;
+
+ dout("sync_read on file %p %llu~%u %s\n", file, off, len,
+ (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
+
+ if (file->f_flags & O_DIRECT) {
+ pages = get_direct_page_vector(data, num_pages, off, len);
+
+ /*
+ * flush any page cache pages in this range. this
+ * will make concurrent normal and O_DIRECT io slow,
+ * but it will at least behave sensibly when they are
+ * in sequence.
+ */
+ } else {
+ pages = alloc_page_vector(num_pages);
+ }
+ if (IS_ERR(pages))
+ return PTR_ERR(pages);
+
+ ret = filemap_write_and_wait(inode->i_mapping);
+ if (ret < 0)
+ goto done;
+
+ ret = striped_read(inode, off, len, pages, num_pages, checkeof);
+
+ if (ret >= 0 && (file->f_flags & O_DIRECT) == 0)
+ ret = copy_page_vector_to_user(pages, data, off, ret);
+ if (ret >= 0)
+ *poff = off + ret;
+
+done:
+ if (file->f_flags & O_DIRECT)
+ put_page_vector(pages, num_pages);
+ else
+ ceph_release_page_vector(pages, num_pages);
+ dout("sync_read result %d\n", ret);
+ return ret;
+}
+
+/*
+ * Write commit callback, called if we requested both an ACK and
+ * ONDISK commit reply from the OSD.
+ */
+static void sync_write_commit(struct ceph_osd_request *req,
+ struct ceph_msg *msg)
+{
+ struct ceph_inode_info *ci = ceph_inode(req->r_inode);
+
+ dout("sync_write_commit %p tid %llu\n", req, req->r_tid);
+ spin_lock(&ci->i_unsafe_lock);
+ list_del_init(&req->r_unsafe_item);
+ spin_unlock(&ci->i_unsafe_lock);
+ ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR);
+}
+
+/*
+ * Synchronous write, straight from __user pointer or user pages (if
+ * O_DIRECT).
+ *
+ * If write spans object boundary, just do multiple writes. (For a
+ * correct atomic write, we should e.g. take write locks on all
+ * objects, rollback on failure, etc.)
+ */
+static ssize_t ceph_sync_write(struct file *file, const char __user *data,
+ size_t left, loff_t *offset)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_client *client = ceph_inode_to_client(inode);
+ struct ceph_osd_request *req;
+ struct page **pages;
+ int num_pages;
+ long long unsigned pos;
+ u64 len;
+ int written = 0;
+ int flags;
+ int do_sync = 0;
+ int check_caps = 0;
+ int ret;
+ struct timespec mtime = CURRENT_TIME;
+
+ if (ceph_snap(file->f_dentry->d_inode) != CEPH_NOSNAP)
+ return -EROFS;
+
+ dout("sync_write on file %p %lld~%u %s\n", file, *offset,
+ (unsigned)left, (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
+
+ if (file->f_flags & O_APPEND)
+ pos = i_size_read(inode);
+ else
+ pos = *offset;
+
+ ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
+ if (ret < 0)
+ return ret;
+
+ ret = invalidate_inode_pages2_range(inode->i_mapping,
+ pos >> PAGE_CACHE_SHIFT,
+ (pos + left) >> PAGE_CACHE_SHIFT);
+ if (ret < 0)
+ dout("invalidate_inode_pages2_range returned %d\n", ret);
+
+ flags = CEPH_OSD_FLAG_ORDERSNAP |
+ CEPH_OSD_FLAG_ONDISK |
+ CEPH_OSD_FLAG_WRITE;
+ if ((file->f_flags & (O_SYNC|O_DIRECT)) == 0)
+ flags |= CEPH_OSD_FLAG_ACK;
+ else
+ do_sync = 1;
+
+ /*
+ * we may need to do multiple writes here if we span an object
+ * boundary. this isn't atomic, unfortunately. :(
+ */
+more:
+ len = left;
+ req = ceph_osdc_new_request(&client->osdc, &ci->i_layout,
+ ceph_vino(inode), pos, &len,
+ CEPH_OSD_OP_WRITE, flags,
+ ci->i_snap_realm->cached_context,
+ do_sync,
+ ci->i_truncate_seq, ci->i_truncate_size,
+ &mtime, false, 2);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+ num_pages = calc_pages_for(pos, len);
+
+ if (file->f_flags & O_DIRECT) {
+ pages = get_direct_page_vector(data, num_pages, pos, len);
+ if (IS_ERR(pages)) {
+ ret = PTR_ERR(pages);
+ goto out;
+ }
+
+ /*
+ * throw out any page cache pages in this range. this
+ * may block.
+ */
+ truncate_inode_pages_range(inode->i_mapping, pos, pos+len);
+ } else {
+ pages = alloc_page_vector(num_pages);
+ if (IS_ERR(pages)) {
+ ret = PTR_ERR(pages);
+ goto out;
+ }
+ ret = copy_user_to_page_vector(pages, data, pos, len);
+ if (ret < 0) {
+ ceph_release_page_vector(pages, num_pages);
+ goto out;
+ }
+
+ if ((file->f_flags & O_SYNC) == 0) {
+ /* get a second commit callback */
+ req->r_safe_callback = sync_write_commit;
+ req->r_own_pages = 1;
+ }
+ }
+ req->r_pages = pages;
+ req->r_num_pages = num_pages;
+ req->r_inode = inode;
+
+ ret = ceph_osdc_start_request(&client->osdc, req, false);
+ if (!ret) {
+ if (req->r_safe_callback) {
+ /*
+ * Add to inode unsafe list only after we
+ * start_request so that a tid has been assigned.
+ */
+ spin_lock(&ci->i_unsafe_lock);
+ list_add(&ci->i_unsafe_writes, &req->r_unsafe_item);
+ spin_unlock(&ci->i_unsafe_lock);
+ ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);
+ }
+ ret = ceph_osdc_wait_request(&client->osdc, req);
+ }
+
+ if (file->f_flags & O_DIRECT)
+ put_page_vector(pages, num_pages);
+ else if (file->f_flags & O_SYNC)
+ ceph_release_page_vector(pages, num_pages);
+
+out:
+ ceph_osdc_put_request(req);
+ if (ret == 0) {
+ pos += len;
+ written += len;
+ left -= len;
+ if (left)
+ goto more;
+
+ ret = written;
+ *offset = pos;
+ if (pos > i_size_read(inode))
+ check_caps = ceph_inode_set_size(inode, pos);
+ if (check_caps)
+ ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY,
+ NULL);
+ }
+ return ret;
+}
+
+/*
+ * Wrap generic_file_aio_read with checks for cap bits on the inode.
+ * Atomically grab references, so that those bits are not released
+ * back to the MDS mid-read.
+ *
+ * Hmm, the sync read case isn't actually async... should it be?
+ */
+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;
+ 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 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 (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 ||
+ (iocb->ki_filp->f_flags & O_DIRECT) ||
+ (inode->i_sb->s_flags & MS_SYNCHRONOUS))
+ /* hmm, this isn't really async... */
+ ret = ceph_sync_read(filp, base, len, ppos, &checkeof);
+ else
+ ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+
+out:
+ dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n",
+ inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret);
+ ceph_put_cap_refs(ci, got);
+
+ if (checkeof && ret >= 0) {
+ int statret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
+
+ /* hit EOF or hole? */
+ if (statret == 0 && *ppos < inode->i_size) {
+ dout("aio_read sync_read hit hole, reading more\n");
+ read += ret;
+ base += ret;
+ len -= ret;
+ checkeof = 0;
+ goto again;
+ }
+ }
+ if (ret >= 0)
+ ret += read;
+
+ return ret;
+}
+
+/*
+ * Take cap references to avoid releasing caps to MDS mid-write.
+ *
+ * If we are synchronous, and write with an old snap context, the OSD
+ * may return EOLDSNAPC. In that case, retry the write.. _after_
+ * dropping our cap refs and allowing the pending snap to logically
+ * complete _before_ this write occurs.
+ *
+ * If we are near ENOSPC, write synchronously.
+ */
+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 inode *inode = file->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc;
+ loff_t endoff = pos + iov->iov_len;
+ int got = 0;
+ int ret, err;
+
+ if (ceph_snap(inode) != CEPH_NOSNAP)
+ return -EROFS;
+
+retry_snap:
+ if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL))
+ return -ENOSPC;
+ __ceph_do_pending_vmtruncate(inode);
+ 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 (ret < 0)
+ goto out;
+
+ dout("aio_write %p %llx.%llx %llu~%u got cap refs on %s\n",
+ inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
+ ceph_cap_string(got));
+
+ if ((got & CEPH_CAP_FILE_BUFFER) == 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,
+ &iocb->ki_pos);
+ } else {
+ ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
+
+ if ((ret >= 0 || ret == -EIOCBQUEUED) &&
+ ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host)
+ || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) {
+ err = vfs_fsync_range(file, file->f_path.dentry,
+ pos, pos + ret - 1, 1);
+ if (err < 0)
+ ret = err;
+ }
+ }
+ if (ret >= 0) {
+ spin_lock(&inode->i_lock);
+ __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
+ spin_unlock(&inode->i_lock);
+ }
+
+out:
+ dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n",
+ inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
+ ceph_cap_string(got));
+ ceph_put_cap_refs(ci, got);
+
+ if (ret == -EOLDSNAPC) {
+ dout("aio_write %p %llx.%llx %llu~%u got EOLDSNAPC, retrying\n",
+ inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len);
+ goto retry_snap;
+ }
+
+ return ret;
+}
+
+/*
+ * llseek. be sure to verify file size on SEEK_END.
+ */
+static loff_t ceph_llseek(struct file *file, loff_t offset, int origin)
+{
+ struct inode *inode = file->f_mapping->host;
+ int ret;
+
+ mutex_lock(&inode->i_mutex);
+ __ceph_do_pending_vmtruncate(inode);
+ switch (origin) {
+ case SEEK_END:
+ ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
+ if (ret < 0) {
+ offset = ret;
+ goto out;
+ }
+ offset += inode->i_size;
+ break;
+ case SEEK_CUR:
+ /*
+ * Here we special-case the lseek(fd, 0, SEEK_CUR)
+ * position-querying operation. Avoid rewriting the "same"
+ * f_pos value back to the file because a concurrent read(),
+ * write() or lseek() might have altered it
+ */
+ if (offset == 0) {
+ offset = file->f_pos;
+ goto out;
+ }
+ offset += file->f_pos;
+ break;
+ }
+
+ if (offset < 0 || offset > inode->i_sb->s_maxbytes) {
+ offset = -EINVAL;
+ goto out;
+ }
+
+ /* Special lock needed here? */
+ if (offset != file->f_pos) {
+ file->f_pos = offset;
+ file->f_version = 0;
+ }
+
+out:
+ mutex_unlock(&inode->i_mutex);
+ return offset;
+}
+
+const struct file_operations ceph_file_fops = {
+ .open = ceph_open,
+ .release = ceph_release,
+ .llseek = ceph_llseek,
+ .read = do_sync_read,
+ .write = do_sync_write,
+ .aio_read = ceph_aio_read,
+ .aio_write = ceph_aio_write,
+ .mmap = ceph_mmap,
+ .fsync = ceph_fsync,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+ .unlocked_ioctl = ceph_ioctl,
+ .compat_ioctl = ceph_ioctl,
+};
+
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
new file mode 100644
index 00000000000..26f883c275e
--- /dev/null
+++ b/fs/ceph/inode.c
@@ -0,0 +1,1774 @@
+#include "ceph_debug.h"
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/namei.h>
+#include <linux/writeback.h>
+#include <linux/vmalloc.h>
+#include <linux/pagevec.h>
+
+#include "super.h"
+#include "decode.h"
+
+/*
+ * Ceph inode operations
+ *
+ * Implement basic inode helpers (get, alloc) and inode ops (getattr,
+ * setattr, etc.), xattr helpers, and helpers for assimilating
+ * metadata returned by the MDS into our cache.
+ *
+ * Also define helpers for doing asynchronous writeback, invalidation,
+ * and truncation for the benefit of those who can't afford to block
+ * (typically because they are in the message handler path).
+ */
+
+static const struct inode_operations ceph_symlink_iops;
+
+static void ceph_invalidate_work(struct work_struct *work);
+static void ceph_writeback_work(struct work_struct *work);
+static void ceph_vmtruncate_work(struct work_struct *work);
+
+/*
+ * find or create an inode, given the ceph ino number
+ */
+struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
+{
+ struct inode *inode;
+ ino_t t = ceph_vino_to_ino(vino);
+
+ inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino);
+ if (inode == NULL)
+ return ERR_PTR(-ENOMEM);
+ if (inode->i_state & I_NEW) {
+ dout("get_inode created new inode %p %llx.%llx ino %llx\n",
+ inode, ceph_vinop(inode), (u64)inode->i_ino);
+ unlock_new_inode(inode);
+ }
+
+ dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino,
+ vino.snap, inode);
+ return inode;
+}
+
+/*
+ * get/constuct snapdir inode for a given directory
+ */
+struct inode *ceph_get_snapdir(struct inode *parent)
+{
+ struct ceph_vino vino = {
+ .ino = ceph_ino(parent),
+ .snap = CEPH_SNAPDIR,
+ };
+ struct inode *inode = ceph_get_inode(parent->i_sb, vino);
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ BUG_ON(!S_ISDIR(parent->i_mode));
+ if (IS_ERR(inode))
+ return ERR_PTR(PTR_ERR(inode));
+ inode->i_mode = parent->i_mode;
+ inode->i_uid = parent->i_uid;
+ inode->i_gid = parent->i_gid;
+ inode->i_op = &ceph_dir_iops;
+ inode->i_fop = &ceph_dir_fops;
+ ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */
+ ci->i_rbytes = 0;
+ return inode;
+}
+
+const struct inode_operations ceph_file_iops = {
+ .permission = ceph_permission,
+ .setattr = ceph_setattr,
+ .getattr = ceph_getattr,
+ .setxattr = ceph_setxattr,
+ .getxattr = ceph_getxattr,
+ .listxattr = ceph_listxattr,
+ .removexattr = ceph_removexattr,
+};
+
+
+/*
+ * We use a 'frag tree' to keep track of the MDS's directory fragments
+ * for a given inode (usually there is just a single fragment). We
+ * need to know when a child frag is delegated to a new MDS, or when
+ * it is flagged as replicated, so we can direct our requests
+ * accordingly.
+ */
+
+/*
+ * find/create a frag in the tree
+ */
+static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci,
+ u32 f)
+{
+ struct rb_node **p;
+ struct rb_node *parent = NULL;
+ struct ceph_inode_frag *frag;
+ int c;
+
+ p = &ci->i_fragtree.rb_node;
+ while (*p) {
+ parent = *p;
+ frag = rb_entry(parent, struct ceph_inode_frag, node);
+ c = ceph_frag_compare(f, frag->frag);
+ if (c < 0)
+ p = &(*p)->rb_left;
+ else if (c > 0)
+ p = &(*p)->rb_right;
+ else
+ return frag;
+ }
+
+ frag = kmalloc(sizeof(*frag), GFP_NOFS);
+ if (!frag) {
+ pr_err("__get_or_create_frag ENOMEM on %p %llx.%llx "
+ "frag %x\n", &ci->vfs_inode,
+ ceph_vinop(&ci->vfs_inode), f);
+ return ERR_PTR(-ENOMEM);
+ }
+ frag->frag = f;
+ frag->split_by = 0;
+ frag->mds = -1;
+ frag->ndist = 0;
+
+ rb_link_node(&frag->node, parent, p);
+ rb_insert_color(&frag->node, &ci->i_fragtree);
+
+ dout("get_or_create_frag added %llx.%llx frag %x\n",
+ ceph_vinop(&ci->vfs_inode), f);
+ return frag;
+}
+
+/*
+ * find a specific frag @f
+ */
+struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci, u32 f)
+{
+ struct rb_node *n = ci->i_fragtree.rb_node;
+
+ while (n) {
+ struct ceph_inode_frag *frag =
+ rb_entry(n, struct ceph_inode_frag, node);
+ int c = ceph_frag_compare(f, frag->frag);
+ if (c < 0)
+ n = n->rb_left;
+ else if (c > 0)
+ n = n->rb_right;
+ else
+ return frag;
+ }
+ return NULL;
+}
+
+/*
+ * Choose frag containing the given value @v. If @pfrag is
+ * specified, copy the frag delegation info to the caller if
+ * it is present.
+ */
+u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
+ struct ceph_inode_frag *pfrag,
+ int *found)
+{
+ u32 t = ceph_frag_make(0, 0);
+ struct ceph_inode_frag *frag;
+ unsigned nway, i;
+ u32 n;
+
+ if (found)
+ *found = 0;
+
+ mutex_lock(&ci->i_fragtree_mutex);
+ while (1) {
+ WARN_ON(!ceph_frag_contains_value(t, v));
+ frag = __ceph_find_frag(ci, t);
+ if (!frag)
+ break; /* t is a leaf */
+ if (frag->split_by == 0) {
+ if (pfrag)
+ memcpy(pfrag, frag, sizeof(*pfrag));
+ if (found)
+ *found = 1;
+ break;
+ }
+
+ /* choose child */
+ nway = 1 << frag->split_by;
+ dout("choose_frag(%x) %x splits by %d (%d ways)\n", v, t,
+ frag->split_by, nway);
+ for (i = 0; i < nway; i++) {
+ n = ceph_frag_make_child(t, frag->split_by, i);
+ if (ceph_frag_contains_value(n, v)) {
+ t = n;
+ break;
+ }
+ }
+ BUG_ON(i == nway);
+ }
+ dout("choose_frag(%x) = %x\n", v, t);
+
+ mutex_unlock(&ci->i_fragtree_mutex);
+ return t;
+}
+
+/*
+ * Process dirfrag (delegation) info from the mds. Include leaf
+ * fragment in tree ONLY if ndist > 0. Otherwise, only
+ * branches/splits are included in i_fragtree)
+ */
+static int ceph_fill_dirfrag(struct inode *inode,
+ struct ceph_mds_reply_dirfrag *dirinfo)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_inode_frag *frag;
+ u32 id = le32_to_cpu(dirinfo->frag);
+ int mds = le32_to_cpu(dirinfo->auth);
+ int ndist = le32_to_cpu(dirinfo->ndist);
+ int i;
+ int err = 0;
+
+ mutex_lock(&ci->i_fragtree_mutex);
+ if (ndist == 0) {
+ /* no delegation info needed. */
+ frag = __ceph_find_frag(ci, id);
+ if (!frag)
+ goto out;
+ if (frag->split_by == 0) {
+ /* tree leaf, remove */
+ dout("fill_dirfrag removed %llx.%llx frag %x"
+ " (no ref)\n", ceph_vinop(inode), id);
+ rb_erase(&frag->node, &ci->i_fragtree);
+ kfree(frag);
+ } else {
+ /* tree branch, keep and clear */
+ dout("fill_dirfrag cleared %llx.%llx frag %x"
+ " referral\n", ceph_vinop(inode), id);
+ frag->mds = -1;
+ frag->ndist = 0;
+ }
+ goto out;
+ }
+
+
+ /* find/add this frag to store mds delegation info */
+ frag = __get_or_create_frag(ci, id);
+ if (IS_ERR(frag)) {
+ /* this is not the end of the world; we can continue
+ with bad/inaccurate delegation info */
+ pr_err("fill_dirfrag ENOMEM on mds ref %llx.%llx fg %x\n",
+ ceph_vinop(inode), le32_to_cpu(dirinfo->frag));
+ err = -ENOMEM;
+ goto out;
+ }
+
+ frag->mds = mds;
+ frag->ndist = min_t(u32, ndist, CEPH_MAX_DIRFRAG_REP);
+ for (i = 0; i < frag->ndist; i++)
+ frag->dist[i] = le32_to_cpu(dirinfo->dist[i]);
+ dout("fill_dirfrag %llx.%llx frag %x ndist=%d\n",
+ ceph_vinop(inode), frag->frag, frag->ndist);
+
+out:
+ mutex_unlock(&ci->i_fragtree_mutex);
+ return err;
+}
+
+
+/*
+ * initialize a newly allocated inode.
+ */
+struct inode *ceph_alloc_inode(struct super_block *sb)
+{
+ struct ceph_inode_info *ci;
+ int i;
+
+ ci = kmem_cache_alloc(ceph_inode_cachep, GFP_NOFS);
+ if (!ci)
+ return NULL;
+
+ dout("alloc_inode %p\n", &ci->vfs_inode);
+
+ ci->i_version = 0;
+ ci->i_time_warp_seq = 0;
+ ci->i_ceph_flags = 0;
+ ci->i_release_count = 0;
+ ci->i_symlink = NULL;
+
+ ci->i_fragtree = RB_ROOT;
+ mutex_init(&ci->i_fragtree_mutex);
+
+ ci->i_xattrs.blob = NULL;
+ ci->i_xattrs.prealloc_blob = NULL;
+ ci->i_xattrs.dirty = false;
+ ci->i_xattrs.index = RB_ROOT;
+ ci->i_xattrs.count = 0;
+ ci->i_xattrs.names_size = 0;
+ ci->i_xattrs.vals_size = 0;
+ ci->i_xattrs.version = 0;
+ ci->i_xattrs.index_version = 0;
+
+ ci->i_caps = RB_ROOT;
+ ci->i_auth_cap = NULL;
+ ci->i_dirty_caps = 0;
+ ci->i_flushing_caps = 0;
+ INIT_LIST_HEAD(&ci->i_dirty_item);
+ INIT_LIST_HEAD(&ci->i_flushing_item);
+ ci->i_cap_flush_seq = 0;
+ ci->i_cap_flush_last_tid = 0;
+ memset(&ci->i_cap_flush_tid, 0, sizeof(ci->i_cap_flush_tid));
+ init_waitqueue_head(&ci->i_cap_wq);
+ ci->i_hold_caps_min = 0;
+ ci->i_hold_caps_max = 0;
+ INIT_LIST_HEAD(&ci->i_cap_delay_list);
+ ci->i_cap_exporting_mds = 0;
+ ci->i_cap_exporting_mseq = 0;
+ ci->i_cap_exporting_issued = 0;
+ INIT_LIST_HEAD(&ci->i_cap_snaps);
+ ci->i_head_snapc = NULL;
+ ci->i_snap_caps = 0;
+
+ for (i = 0; i < CEPH_FILE_MODE_NUM; i++)
+ ci->i_nr_by_mode[i] = 0;
+
+ ci->i_truncate_seq = 0;
+ ci->i_truncate_size = 0;
+ ci->i_truncate_pending = 0;
+
+ ci->i_max_size = 0;
+ ci->i_reported_size = 0;
+ ci->i_wanted_max_size = 0;
+ ci->i_requested_max_size = 0;
+
+ ci->i_pin_ref = 0;
+ ci->i_rd_ref = 0;
+ ci->i_rdcache_ref = 0;
+ ci->i_wr_ref = 0;
+ ci->i_wrbuffer_ref = 0;
+ ci->i_wrbuffer_ref_head = 0;
+ ci->i_shared_gen = 0;
+ ci->i_rdcache_gen = 0;
+ ci->i_rdcache_revoking = 0;
+
+ INIT_LIST_HEAD(&ci->i_unsafe_writes);
+ INIT_LIST_HEAD(&ci->i_unsafe_dirops);
+ spin_lock_init(&ci->i_unsafe_lock);
+
+ ci->i_snap_realm = NULL;
+ INIT_LIST_HEAD(&ci->i_snap_realm_item);
+ INIT_LIST_HEAD(&ci->i_snap_flush_item);
+
+ INIT_WORK(&ci->i_wb_work, ceph_writeback_work);
+ INIT_WORK(&ci->i_pg_inv_work, ceph_invalidate_work);
+
+ INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work);
+
+ return &ci->vfs_inode;
+}
+
+void ceph_destroy_inode(struct inode *inode)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_inode_frag *frag;
+ struct rb_node *n;
+
+ dout("destroy_inode %p ino %llx.%llx\n", inode, ceph_vinop(inode));
+
+ ceph_queue_caps_release(inode);
+
+ /*
+ * we may still have a snap_realm reference if there are stray
+ * caps in i_cap_exporting_issued or i_snap_caps.
+ */
+ if (ci->i_snap_realm) {
+ struct ceph_mds_client *mdsc =
+ &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+ struct ceph_snap_realm *realm = ci->i_snap_realm;
+
+ dout(" dropping residual ref to snap realm %p\n", realm);
+ spin_lock(&realm->inodes_with_caps_lock);
+ list_del_init(&ci->i_snap_realm_item);
+ spin_unlock(&realm->inodes_with_caps_lock);
+ ceph_put_snap_realm(mdsc, realm);
+ }
+
+ kfree(ci->i_symlink);
+ while ((n = rb_first(&ci->i_fragtree)) != NULL) {
+ frag = rb_entry(n, struct ceph_inode_frag, node);
+ rb_erase(n, &ci->i_fragtree);
+ kfree(frag);
+ }
+
+ __ceph_destroy_xattrs(ci);
+ if (ci->i_xattrs.blob)
+ ceph_buffer_put(ci->i_xattrs.blob);
+ if (ci->i_xattrs.prealloc_blob)
+ ceph_buffer_put(ci->i_xattrs.prealloc_blob);
+
+ kmem_cache_free(ceph_inode_cachep, ci);
+}
+
+
+/*
+ * Helpers to fill in size, ctime, mtime, and atime. We have to be
+ * careful because either the client or MDS may have more up to date
+ * info, depending on which capabilities are held, and whether
+ * time_warp_seq or truncate_seq have increased. (Ordinarily, mtime
+ * and size are monotonically increasing, except when utimes() or
+ * truncate() increments the corresponding _seq values.)
+ */
+int ceph_fill_file_size(struct inode *inode, int issued,
+ u32 truncate_seq, u64 truncate_size, u64 size)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int queue_trunc = 0;
+
+ if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 ||
+ (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
+ dout("size %lld -> %llu\n", inode->i_size, size);
+ inode->i_size = size;
+ inode->i_blocks = (size + (1<<9) - 1) >> 9;
+ ci->i_reported_size = size;
+ if (truncate_seq != ci->i_truncate_seq) {
+ dout("truncate_seq %u -> %u\n",
+ ci->i_truncate_seq, truncate_seq);
+ ci->i_truncate_seq = truncate_seq;
+ /*
+ * If we hold relevant caps, or in the case where we're
+ * not the only client referencing this file and we
+ * don't hold those caps, then we need to check whether
+ * 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)) ||
+ mapping_mapped(inode->i_mapping) ||
+ __ceph_caps_file_wanted(ci)) {
+ ci->i_truncate_pending++;
+ queue_trunc = 1;
+ }
+ }
+ }
+ if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) >= 0 &&
+ ci->i_truncate_size != truncate_size) {
+ dout("truncate_size %lld -> %llu\n", ci->i_truncate_size,
+ truncate_size);
+ ci->i_truncate_size = truncate_size;
+ }
+ return queue_trunc;
+}
+
+void ceph_fill_file_time(struct inode *inode, int issued,
+ u64 time_warp_seq, struct timespec *ctime,
+ struct timespec *mtime, struct timespec *atime)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int warn = 0;
+
+ if (issued & (CEPH_CAP_FILE_EXCL|
+ CEPH_CAP_FILE_WR|
+ CEPH_CAP_FILE_BUFFER)) {
+ if (timespec_compare(ctime, &inode->i_ctime) > 0) {
+ dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+ ctime->tv_sec, ctime->tv_nsec);
+ inode->i_ctime = *ctime;
+ }
+ if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
+ /* the MDS did a utimes() */
+ dout("mtime %ld.%09ld -> %ld.%09ld "
+ "tw %d -> %d\n",
+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+ mtime->tv_sec, mtime->tv_nsec,
+ ci->i_time_warp_seq, (int)time_warp_seq);
+
+ inode->i_mtime = *mtime;
+ inode->i_atime = *atime;
+ ci->i_time_warp_seq = time_warp_seq;
+ } else if (time_warp_seq == ci->i_time_warp_seq) {
+ /* nobody did utimes(); take the max */
+ if (timespec_compare(mtime, &inode->i_mtime) > 0) {
+ dout("mtime %ld.%09ld -> %ld.%09ld inc\n",
+ inode->i_mtime.tv_sec,
+ inode->i_mtime.tv_nsec,
+ mtime->tv_sec, mtime->tv_nsec);
+ inode->i_mtime = *mtime;
+ }
+ if (timespec_compare(atime, &inode->i_atime) > 0) {
+ dout("atime %ld.%09ld -> %ld.%09ld inc\n",
+ inode->i_atime.tv_sec,
+ inode->i_atime.tv_nsec,
+ atime->tv_sec, atime->tv_nsec);
+ inode->i_atime = *atime;
+ }
+ } else if (issued & CEPH_CAP_FILE_EXCL) {
+ /* we did a utimes(); ignore mds values */
+ } else {
+ warn = 1;
+ }
+ } else {
+ /* we have no write caps; whatever the MDS says is true */
+ if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
+ inode->i_ctime = *ctime;
+ inode->i_mtime = *mtime;
+ inode->i_atime = *atime;
+ ci->i_time_warp_seq = time_warp_seq;
+ } else {
+ warn = 1;
+ }
+ }
+ if (warn) /* time_warp_seq shouldn't go backwards */
+ dout("%p mds time_warp_seq %llu < %u\n",
+ inode, time_warp_seq, ci->i_time_warp_seq);
+}
+
+/*
+ * Populate an inode based on info from mds. May be called on new or
+ * existing inodes.
+ */
+static int fill_inode(struct inode *inode,
+ struct ceph_mds_reply_info_in *iinfo,
+ struct ceph_mds_reply_dirfrag *dirinfo,
+ struct ceph_mds_session *session,
+ unsigned long ttl_from, int cap_fmode,
+ struct ceph_cap_reservation *caps_reservation)
+{
+ struct ceph_mds_reply_inode *info = iinfo->in;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int i;
+ int issued, implemented;
+ struct timespec mtime, atime, ctime;
+ u32 nsplits;
+ struct ceph_buffer *xattr_blob = NULL;
+ int err = 0;
+ int queue_trunc = 0;
+
+ dout("fill_inode %p ino %llx.%llx v %llu had %llu\n",
+ inode, ceph_vinop(inode), le64_to_cpu(info->version),
+ ci->i_version);
+
+ /*
+ * prealloc xattr data, if it looks like we'll need it. only
+ * if len > 4 (meaning there are actually xattrs; the first 4
+ * bytes are the xattr count).
+ */
+ if (iinfo->xattr_len > 4) {
+ xattr_blob = ceph_buffer_new(iinfo->xattr_len, GFP_NOFS);
+ if (!xattr_blob)
+ pr_err("fill_inode ENOMEM xattr blob %d bytes\n",
+ iinfo->xattr_len);
+ }
+
+ spin_lock(&inode->i_lock);
+
+ /*
+ * provided version will be odd if inode value is projected,
+ * even if stable. skip the update if we have a newer info
+ * (e.g., due to inode info racing form multiple MDSs), or if
+ * we are getting projected (unstable) inode info.
+ */
+ if (le64_to_cpu(info->version) > 0 &&
+ (ci->i_version & ~1) > le64_to_cpu(info->version))
+ goto no_change;
+
+ issued = __ceph_caps_issued(ci, &implemented);
+ issued |= implemented | __ceph_caps_dirty(ci);
+
+ /* update inode */
+ ci->i_version = le64_to_cpu(info->version);
+ inode->i_version++;
+ inode->i_rdev = le32_to_cpu(info->rdev);
+
+ if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
+ inode->i_mode = le32_to_cpu(info->mode);
+ inode->i_uid = le32_to_cpu(info->uid);
+ inode->i_gid = le32_to_cpu(info->gid);
+ dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
+ inode->i_uid, inode->i_gid);
+ }
+
+ if ((issued & CEPH_CAP_LINK_EXCL) == 0)
+ inode->i_nlink = le32_to_cpu(info->nlink);
+
+ /* be careful with mtime, atime, size */
+ ceph_decode_timespec(&atime, &info->atime);
+ ceph_decode_timespec(&mtime, &info->mtime);
+ ceph_decode_timespec(&ctime, &info->ctime);
+ queue_trunc = ceph_fill_file_size(inode, issued,
+ le32_to_cpu(info->truncate_seq),
+ le64_to_cpu(info->truncate_size),
+ le64_to_cpu(info->size));
+ ceph_fill_file_time(inode, issued,
+ le32_to_cpu(info->time_warp_seq),
+ &ctime, &mtime, &atime);
+
+ ci->i_max_size = le64_to_cpu(info->max_size);
+ ci->i_layout = info->layout;
+ inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
+
+ /* xattrs */
+ /* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */
+ if ((issued & CEPH_CAP_XATTR_EXCL) == 0 &&
+ le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) {
+ if (ci->i_xattrs.blob)
+ ceph_buffer_put(ci->i_xattrs.blob);
+ ci->i_xattrs.blob = xattr_blob;
+ if (xattr_blob)
+ memcpy(ci->i_xattrs.blob->vec.iov_base,
+ iinfo->xattr_data, iinfo->xattr_len);
+ ci->i_xattrs.version = le64_to_cpu(info->xattr_version);
+ }
+
+ inode->i_mapping->a_ops = &ceph_aops;
+ inode->i_mapping->backing_dev_info =
+ &ceph_client(inode->i_sb)->backing_dev_info;
+
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFIFO:
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFSOCK:
+ init_special_inode(inode, inode->i_mode, inode->i_rdev);
+ inode->i_op = &ceph_file_iops;
+ break;
+ case S_IFREG:
+ inode->i_op = &ceph_file_iops;
+ inode->i_fop = &ceph_file_fops;
+ break;
+ case S_IFLNK:
+ inode->i_op = &ceph_symlink_iops;
+ if (!ci->i_symlink) {
+ int symlen = iinfo->symlink_len;
+ char *sym;
+
+ BUG_ON(symlen != inode->i_size);
+ spin_unlock(&inode->i_lock);
+
+ err = -ENOMEM;
+ sym = kmalloc(symlen+1, GFP_NOFS);
+ if (!sym)
+ goto out;
+ memcpy(sym, iinfo->symlink, symlen);
+ sym[symlen] = 0;
+
+ spin_lock(&inode->i_lock);
+ if (!ci->i_symlink)
+ ci->i_symlink = sym;
+ else
+ kfree(sym); /* lost a race */
+ }
+ break;
+ case S_IFDIR:
+ inode->i_op = &ceph_dir_iops;
+ inode->i_fop = &ceph_dir_fops;
+
+ ci->i_files = le64_to_cpu(info->files);
+ ci->i_subdirs = le64_to_cpu(info->subdirs);
+ ci->i_rbytes = le64_to_cpu(info->rbytes);
+ ci->i_rfiles = le64_to_cpu(info->rfiles);
+ ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
+ ceph_decode_timespec(&ci->i_rctime, &info->rctime);
+
+ /* set dir completion flag? */
+ if (ci->i_files == 0 && ci->i_subdirs == 0 &&
+ ceph_snap(inode) == CEPH_NOSNAP &&
+ (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED)) {
+ dout(" marking %p complete (empty)\n", inode);
+ ci->i_ceph_flags |= CEPH_I_COMPLETE;
+ ci->i_max_offset = 2;
+ }
+
+ /* it may be better to set st_size in getattr instead? */
+ if (ceph_test_opt(ceph_client(inode->i_sb), RBYTES))
+ inode->i_size = ci->i_rbytes;
+ break;
+ default:
+ pr_err("fill_inode %llx.%llx BAD mode 0%o\n",
+ ceph_vinop(inode), inode->i_mode);
+ }
+
+no_change:
+ spin_unlock(&inode->i_lock);
+
+ /* queue truncate if we saw i_size decrease */
+ if (queue_trunc)
+ ceph_queue_vmtruncate(inode);
+
+ /* populate frag tree */
+ /* FIXME: move me up, if/when version reflects fragtree changes */
+ nsplits = le32_to_cpu(info->fragtree.nsplits);
+ mutex_lock(&ci->i_fragtree_mutex);
+ for (i = 0; i < nsplits; i++) {
+ u32 id = le32_to_cpu(info->fragtree.splits[i].frag);
+ struct ceph_inode_frag *frag = __get_or_create_frag(ci, id);
+
+ if (IS_ERR(frag))
+ continue;
+ frag->split_by = le32_to_cpu(info->fragtree.splits[i].by);
+ dout(" frag %x split by %d\n", frag->frag, frag->split_by);
+ }
+ mutex_unlock(&ci->i_fragtree_mutex);
+
+ /* were we issued a capability? */
+ if (info->cap.caps) {
+ if (ceph_snap(inode) == CEPH_NOSNAP) {
+ ceph_add_cap(inode, session,
+ le64_to_cpu(info->cap.cap_id),
+ cap_fmode,
+ le32_to_cpu(info->cap.caps),
+ le32_to_cpu(info->cap.wanted),
+ le32_to_cpu(info->cap.seq),
+ le32_to_cpu(info->cap.mseq),
+ le64_to_cpu(info->cap.realm),
+ info->cap.flags,
+ caps_reservation);
+ } else {
+ spin_lock(&inode->i_lock);
+ dout(" %p got snap_caps %s\n", inode,
+ ceph_cap_string(le32_to_cpu(info->cap.caps)));
+ ci->i_snap_caps |= le32_to_cpu(info->cap.caps);
+ if (cap_fmode >= 0)
+ __ceph_get_fmode(ci, cap_fmode);
+ spin_unlock(&inode->i_lock);
+ }
+ }
+
+ /* update delegation info? */
+ if (dirinfo)
+ ceph_fill_dirfrag(inode, dirinfo);
+
+ err = 0;
+
+out:
+ if (xattr_blob)
+ ceph_buffer_put(xattr_blob);
+ return err;
+}
+
+/*
+ * caller should hold session s_mutex.
+ */
+static void update_dentry_lease(struct dentry *dentry,
+ struct ceph_mds_reply_lease *lease,
+ struct ceph_mds_session *session,
+ unsigned long from_time)
+{
+ struct ceph_dentry_info *di = ceph_dentry(dentry);
+ long unsigned duration = le32_to_cpu(lease->duration_ms);
+ long unsigned ttl = from_time + (duration * HZ) / 1000;
+ long unsigned half_ttl = from_time + (duration * HZ / 2) / 1000;
+ struct inode *dir;
+
+ /* only track leases on regular dentries */
+ if (dentry->d_op != &ceph_dentry_ops)
+ return;
+
+ spin_lock(&dentry->d_lock);
+ dout("update_dentry_lease %p mask %d duration %lu ms ttl %lu\n",
+ dentry, le16_to_cpu(lease->mask), duration, ttl);
+
+ /* make lease_rdcache_gen match directory */
+ dir = dentry->d_parent->d_inode;
+ di->lease_shared_gen = ceph_inode(dir)->i_shared_gen;
+
+ if (lease->mask == 0)
+ goto out_unlock;
+
+ if (di->lease_gen == session->s_cap_gen &&
+ time_before(ttl, dentry->d_time))
+ goto out_unlock; /* we already have a newer lease. */
+
+ if (di->lease_session && di->lease_session != session)
+ goto out_unlock;
+
+ ceph_dentry_lru_touch(dentry);
+
+ if (!di->lease_session)
+ di->lease_session = ceph_get_mds_session(session);
+ di->lease_gen = session->s_cap_gen;
+ di->lease_seq = le32_to_cpu(lease->seq);
+ di->lease_renew_after = half_ttl;
+ di->lease_renew_from = 0;
+ dentry->d_time = ttl;
+out_unlock:
+ spin_unlock(&dentry->d_lock);
+ return;
+}
+
+/*
+ * splice a dentry to an inode.
+ * caller must hold directory i_mutex for this to be safe.
+ *
+ * we will only rehash the resulting dentry if @prehash is
+ * true; @prehash will be set to false (for the benefit of
+ * the caller) if we fail.
+ */
+static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
+ bool *prehash)
+{
+ struct dentry *realdn;
+
+ /* dn must be unhashed */
+ if (!d_unhashed(dn))
+ d_drop(dn);
+ realdn = d_materialise_unique(dn, in);
+ if (IS_ERR(realdn)) {
+ pr_err("splice_dentry error %p inode %p ino %llx.%llx\n",
+ dn, in, ceph_vinop(in));
+ if (prehash)
+ *prehash = false; /* don't rehash on error */
+ dn = realdn; /* note realdn contains the error */
+ goto out;
+ } else if (realdn) {
+ dout("dn %p (%d) spliced with %p (%d) "
+ "inode %p ino %llx.%llx\n",
+ dn, atomic_read(&dn->d_count),
+ realdn, atomic_read(&realdn->d_count),
+ realdn->d_inode, ceph_vinop(realdn->d_inode));
+ dput(dn);
+ dn = realdn;
+ } else {
+ BUG_ON(!ceph_dentry(dn));
+
+ dout("dn %p attached to %p ino %llx.%llx\n",
+ dn, dn->d_inode, ceph_vinop(dn->d_inode));
+ }
+ if ((!prehash || *prehash) && d_unhashed(dn))
+ d_rehash(dn);
+out:
+ return dn;
+}
+
+/*
+ * Set dentry's directory position based on the current dir's max, and
+ * order it in d_subdirs, so that dcache_readdir behaves.
+ */
+static void ceph_set_dentry_offset(struct dentry *dn)
+{
+ struct dentry *dir = dn->d_parent;
+ struct inode *inode = dn->d_parent->d_inode;
+ struct ceph_dentry_info *di;
+
+ BUG_ON(!inode);
+
+ di = ceph_dentry(dn);
+
+ spin_lock(&inode->i_lock);
+ di->offset = ceph_inode(inode)->i_max_offset++;
+ spin_unlock(&inode->i_lock);
+
+ spin_lock(&dcache_lock);
+ spin_lock(&dn->d_lock);
+ list_move_tail(&dir->d_subdirs, &dn->d_u.d_child);
+ dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset,
+ dn->d_u.d_child.prev, dn->d_u.d_child.next);
+ spin_unlock(&dn->d_lock);
+ spin_unlock(&dcache_lock);
+}
+
+/*
+ * Incorporate results into the local cache. This is either just
+ * one inode, or a directory, dentry, and possibly linked-to inode (e.g.,
+ * after a lookup).
+ *
+ * A reply may contain
+ * a directory inode along with a dentry.
+ * and/or a target inode
+ *
+ * Called with snap_rwsem (read).
+ */
+int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
+ struct ceph_mds_session *session)
+{
+ struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+ struct inode *in = NULL;
+ struct ceph_mds_reply_inode *ininfo;
+ struct ceph_vino vino;
+ struct ceph_client *client = ceph_sb_to_client(sb);
+ int i = 0;
+ int err = 0;
+
+ dout("fill_trace %p is_dentry %d is_target %d\n", req,
+ rinfo->head->is_dentry, rinfo->head->is_target);
+
+#if 0
+ /*
+ * Debugging hook:
+ *
+ * If we resend completed ops to a recovering mds, we get no
+ * trace. Since that is very rare, pretend this is the case
+ * to ensure the 'no trace' handlers in the callers behave.
+ *
+ * Fill in inodes unconditionally to avoid breaking cap
+ * invariants.
+ */
+ if (rinfo->head->op & CEPH_MDS_OP_WRITE) {
+ pr_info("fill_trace faking empty trace on %lld %s\n",
+ req->r_tid, ceph_mds_op_name(rinfo->head->op));
+ if (rinfo->head->is_dentry) {
+ rinfo->head->is_dentry = 0;
+ err = fill_inode(req->r_locked_dir,
+ &rinfo->diri, rinfo->dirfrag,
+ session, req->r_request_started, -1);
+ }
+ if (rinfo->head->is_target) {
+ rinfo->head->is_target = 0;
+ ininfo = rinfo->targeti.in;
+ vino.ino = le64_to_cpu(ininfo->ino);
+ vino.snap = le64_to_cpu(ininfo->snapid);
+ in = ceph_get_inode(sb, vino);
+ err = fill_inode(in, &rinfo->targeti, NULL,
+ session, req->r_request_started,
+ req->r_fmode);
+ iput(in);
+ }
+ }
+#endif
+
+ if (!rinfo->head->is_target && !rinfo->head->is_dentry) {
+ dout("fill_trace reply is empty!\n");
+ if (rinfo->head->result == 0 && req->r_locked_dir) {
+ struct ceph_inode_info *ci =
+ ceph_inode(req->r_locked_dir);
+ dout(" clearing %p complete (empty trace)\n",
+ req->r_locked_dir);
+ ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+ ci->i_release_count++;
+ }
+ return 0;
+ }
+
+ if (rinfo->head->is_dentry) {
+ struct inode *dir = req->r_locked_dir;
+
+ err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
+ session, req->r_request_started, -1,
+ &req->r_caps_reservation);
+ if (err < 0)
+ return err;
+ }
+
+ /*
+ * ignore null lease/binding on snapdir ENOENT, or else we
+ * will have trouble splicing in the virtual snapdir later
+ */
+ if (rinfo->head->is_dentry && !req->r_aborted &&
+ (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name,
+ client->mount_args->snapdir_name,
+ req->r_dentry->d_name.len))) {
+ /*
+ * lookup link rename : null -> possibly existing inode
+ * mknod symlink mkdir : null -> new inode
+ * unlink : linked -> null
+ */
+ struct inode *dir = req->r_locked_dir;
+ struct dentry *dn = req->r_dentry;
+ bool have_dir_cap, have_lease;
+
+ BUG_ON(!dn);
+ BUG_ON(!dir);
+ BUG_ON(dn->d_parent->d_inode != dir);
+ BUG_ON(ceph_ino(dir) !=
+ le64_to_cpu(rinfo->diri.in->ino));
+ BUG_ON(ceph_snap(dir) !=
+ le64_to_cpu(rinfo->diri.in->snapid));
+
+ /* do we have a lease on the whole dir? */
+ have_dir_cap =
+ (le32_to_cpu(rinfo->diri.in->cap.caps) &
+ CEPH_CAP_FILE_SHARED);
+
+ /* do we have a dn lease? */
+ have_lease = have_dir_cap ||
+ (le16_to_cpu(rinfo->dlease->mask) &
+ CEPH_LOCK_DN);
+
+ if (!have_lease)
+ dout("fill_trace no dentry lease or dir cap\n");
+
+ /* rename? */
+ if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) {
+ dout(" src %p '%.*s' dst %p '%.*s'\n",
+ req->r_old_dentry,
+ req->r_old_dentry->d_name.len,
+ req->r_old_dentry->d_name.name,
+ dn, dn->d_name.len, dn->d_name.name);
+ dout("fill_trace doing d_move %p -> %p\n",
+ req->r_old_dentry, dn);
+ d_move(req->r_old_dentry, dn);
+ dout(" src %p '%.*s' dst %p '%.*s'\n",
+ req->r_old_dentry,
+ req->r_old_dentry->d_name.len,
+ req->r_old_dentry->d_name.name,
+ dn, dn->d_name.len, dn->d_name.name);
+ /* ensure target dentry is invalidated, despite
+ rehashing bug in vfs_rename_dir */
+ dn->d_time = jiffies;
+ ceph_dentry(dn)->lease_shared_gen = 0;
+ /* take overwritten dentry's readdir offset */
+ ceph_dentry(req->r_old_dentry)->offset =
+ ceph_dentry(dn)->offset;
+ dn = req->r_old_dentry; /* use old_dentry */
+ in = dn->d_inode;
+ }
+
+ /* null dentry? */
+ if (!rinfo->head->is_target) {
+ dout("fill_trace null dentry\n");
+ if (dn->d_inode) {
+ dout("d_delete %p\n", dn);
+ d_delete(dn);
+ } else {
+ dout("d_instantiate %p NULL\n", dn);
+ d_instantiate(dn, NULL);
+ if (have_lease && d_unhashed(dn))
+ d_rehash(dn);
+ update_dentry_lease(dn, rinfo->dlease,
+ session,
+ req->r_request_started);
+ }
+ goto done;
+ }
+
+ /* attach proper inode */
+ ininfo = rinfo->targeti.in;
+ vino.ino = le64_to_cpu(ininfo->ino);
+ vino.snap = le64_to_cpu(ininfo->snapid);
+ if (!dn->d_inode) {
+ in = ceph_get_inode(sb, vino);
+ if (IS_ERR(in)) {
+ pr_err("fill_trace bad get_inode "
+ "%llx.%llx\n", vino.ino, vino.snap);
+ err = PTR_ERR(in);
+ d_delete(dn);
+ goto done;
+ }
+ dn = splice_dentry(dn, in, &have_lease);
+ if (IS_ERR(dn)) {
+ err = PTR_ERR(dn);
+ goto done;
+ }
+ req->r_dentry = dn; /* may have spliced */
+ ceph_set_dentry_offset(dn);
+ igrab(in);
+ } else if (ceph_ino(in) == vino.ino &&
+ ceph_snap(in) == vino.snap) {
+ igrab(in);
+ } else {
+ dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
+ dn, in, ceph_ino(in), ceph_snap(in),
+ vino.ino, vino.snap);
+ have_lease = false;
+ in = NULL;
+ }
+
+ if (have_lease)
+ update_dentry_lease(dn, rinfo->dlease, session,
+ req->r_request_started);
+ dout(" final dn %p\n", dn);
+ i++;
+ } else if (req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
+ req->r_op == CEPH_MDS_OP_MKSNAP) {
+ struct dentry *dn = req->r_dentry;
+
+ /* fill out a snapdir LOOKUPSNAP dentry */
+ BUG_ON(!dn);
+ BUG_ON(!req->r_locked_dir);
+ BUG_ON(ceph_snap(req->r_locked_dir) != CEPH_SNAPDIR);
+ ininfo = rinfo->targeti.in;
+ vino.ino = le64_to_cpu(ininfo->ino);
+ vino.snap = le64_to_cpu(ininfo->snapid);
+ in = ceph_get_inode(sb, vino);
+ if (IS_ERR(in)) {
+ pr_err("fill_inode get_inode badness %llx.%llx\n",
+ vino.ino, vino.snap);
+ err = PTR_ERR(in);
+ d_delete(dn);
+ goto done;
+ }
+ dout(" linking snapped dir %p to dn %p\n", in, dn);
+ dn = splice_dentry(dn, in, NULL);
+ if (IS_ERR(dn)) {
+ err = PTR_ERR(dn);
+ goto done;
+ }
+ ceph_set_dentry_offset(dn);
+ req->r_dentry = dn; /* may have spliced */
+ igrab(in);
+ rinfo->head->is_dentry = 1; /* fool notrace handlers */
+ }
+
+ if (rinfo->head->is_target) {
+ vino.ino = le64_to_cpu(rinfo->targeti.in->ino);
+ vino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
+
+ if (in == NULL || ceph_ino(in) != vino.ino ||
+ ceph_snap(in) != vino.snap) {
+ in = ceph_get_inode(sb, vino);
+ if (IS_ERR(in)) {
+ err = PTR_ERR(in);
+ goto done;
+ }
+ }
+ req->r_target_inode = in;
+
+ err = fill_inode(in,
+ &rinfo->targeti, NULL,
+ session, req->r_request_started,
+ (le32_to_cpu(rinfo->head->result) == 0) ?
+ req->r_fmode : -1,
+ &req->r_caps_reservation);
+ if (err < 0) {
+ pr_err("fill_inode badness %p %llx.%llx\n",
+ in, ceph_vinop(in));
+ goto done;
+ }
+ }
+
+done:
+ dout("fill_trace done err=%d\n", err);
+ return err;
+}
+
+/*
+ * Prepopulate our cache with readdir results, leases, etc.
+ */
+int ceph_readdir_prepopulate(struct ceph_mds_request *req,
+ struct ceph_mds_session *session)
+{
+ struct dentry *parent = req->r_dentry;
+ struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+ struct qstr dname;
+ struct dentry *dn;
+ struct inode *in;
+ int err = 0, i;
+ struct inode *snapdir = NULL;
+ struct ceph_mds_request_head *rhead = req->r_request->front.iov_base;
+ u64 frag = le32_to_cpu(rhead->args.readdir.frag);
+ struct ceph_dentry_info *di;
+
+ if (le32_to_cpu(rinfo->head->op) == CEPH_MDS_OP_LSSNAP) {
+ snapdir = ceph_get_snapdir(parent->d_inode);
+ parent = d_find_alias(snapdir);
+ dout("readdir_prepopulate %d items under SNAPDIR dn %p\n",
+ rinfo->dir_nr, parent);
+ } else {
+ dout("readdir_prepopulate %d items under dn %p\n",
+ rinfo->dir_nr, parent);
+ if (rinfo->dir_dir)
+ ceph_fill_dirfrag(parent->d_inode, rinfo->dir_dir);
+ }
+
+ for (i = 0; i < rinfo->dir_nr; i++) {
+ struct ceph_vino vino;
+
+ dname.name = rinfo->dir_dname[i];
+ dname.len = rinfo->dir_dname_len[i];
+ dname.hash = full_name_hash(dname.name, dname.len);
+
+ vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino);
+ vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid);
+
+retry_lookup:
+ dn = d_lookup(parent, &dname);
+ dout("d_lookup on parent=%p name=%.*s got %p\n",
+ parent, dname.len, dname.name, dn);
+
+ if (!dn) {
+ dn = d_alloc(parent, &dname);
+ dout("d_alloc %p '%.*s' = %p\n", parent,
+ dname.len, dname.name, dn);
+ if (dn == NULL) {
+ dout("d_alloc badness\n");
+ err = -ENOMEM;
+ goto out;
+ }
+ err = ceph_init_dentry(dn);
+ if (err < 0)
+ goto out;
+ } else if (dn->d_inode &&
+ (ceph_ino(dn->d_inode) != vino.ino ||
+ ceph_snap(dn->d_inode) != vino.snap)) {
+ dout(" dn %p points to wrong inode %p\n",
+ dn, dn->d_inode);
+ d_delete(dn);
+ dput(dn);
+ goto retry_lookup;
+ } else {
+ /* reorder parent's d_subdirs */
+ spin_lock(&dcache_lock);
+ spin_lock(&dn->d_lock);
+ list_move(&dn->d_u.d_child, &parent->d_subdirs);
+ spin_unlock(&dn->d_lock);
+ spin_unlock(&dcache_lock);
+ }
+
+ di = dn->d_fsdata;
+ di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset);
+
+ /* inode */
+ if (dn->d_inode) {
+ in = dn->d_inode;
+ } else {
+ in = ceph_get_inode(parent->d_sb, vino);
+ if (in == NULL) {
+ dout("new_inode badness\n");
+ d_delete(dn);
+ dput(dn);
+ err = -ENOMEM;
+ goto out;
+ }
+ dn = splice_dentry(dn, in, NULL);
+ }
+
+ if (fill_inode(in, &rinfo->dir_in[i], NULL, session,
+ req->r_request_started, -1,
+ &req->r_caps_reservation) < 0) {
+ pr_err("fill_inode badness on %p\n", in);
+ dput(dn);
+ continue;
+ }
+ update_dentry_lease(dn, rinfo->dir_dlease[i],
+ req->r_session, req->r_request_started);
+ dput(dn);
+ }
+ req->r_did_prepopulate = true;
+
+out:
+ if (snapdir) {
+ iput(snapdir);
+ dput(parent);
+ }
+ dout("readdir_prepopulate done\n");
+ return err;
+}
+
+int ceph_inode_set_size(struct inode *inode, loff_t size)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int ret = 0;
+
+ spin_lock(&inode->i_lock);
+ dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size);
+ inode->i_size = size;
+ inode->i_blocks = (size + (1 << 9) - 1) >> 9;
+
+ /* tell the MDS if we are approaching max_size */
+ if ((size << 1) >= ci->i_max_size &&
+ (ci->i_reported_size << 1) < ci->i_max_size)
+ ret = 1;
+
+ spin_unlock(&inode->i_lock);
+ return ret;
+}
+
+/*
+ * Write back inode data in a worker thread. (This can't be done
+ * in the message handler context.)
+ */
+void ceph_queue_writeback(struct inode *inode)
+{
+ if (queue_work(ceph_inode_to_client(inode)->wb_wq,
+ &ceph_inode(inode)->i_wb_work)) {
+ dout("ceph_queue_writeback %p\n", inode);
+ igrab(inode);
+ } else {
+ dout("ceph_queue_writeback %p failed\n", inode);
+ }
+}
+
+static void ceph_writeback_work(struct work_struct *work)
+{
+ struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+ i_wb_work);
+ struct inode *inode = &ci->vfs_inode;
+
+ dout("writeback %p\n", inode);
+ filemap_fdatawrite(&inode->i_data);
+ iput(inode);
+}
+
+/*
+ * queue an async invalidation
+ */
+void ceph_queue_invalidate(struct inode *inode)
+{
+ if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
+ &ceph_inode(inode)->i_pg_inv_work)) {
+ dout("ceph_queue_invalidate %p\n", inode);
+ igrab(inode);
+ } else {
+ dout("ceph_queue_invalidate %p failed\n", inode);
+ }
+}
+
+/*
+ * invalidate any pages that are not dirty or under writeback. this
+ * includes pages that are clean and mapped.
+ */
+static void ceph_invalidate_nondirty_pages(struct address_space *mapping)
+{
+ struct pagevec pvec;
+ pgoff_t next = 0;
+ int i;
+
+ pagevec_init(&pvec, 0);
+ while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i];
+ pgoff_t index;
+ int skip_page =
+ (PageDirty(page) || PageWriteback(page));
+
+ if (!skip_page)
+ skip_page = !trylock_page(page);
+
+ /*
+ * We really shouldn't be looking at the ->index of an
+ * unlocked page. But we're not allowed to lock these
+ * pages. So we rely upon nobody altering the ->index
+ * of this (pinned-by-us) page.
+ */
+ index = page->index;
+ if (index > next)
+ next = index;
+ next++;
+
+ if (skip_page)
+ continue;
+
+ generic_error_remove_page(mapping, page);
+ unlock_page(page);
+ }
+ pagevec_release(&pvec);
+ cond_resched();
+ }
+}
+
+/*
+ * Invalidate inode pages in a worker thread. (This can't be done
+ * in the message handler context.)
+ */
+static void ceph_invalidate_work(struct work_struct *work)
+{
+ struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+ i_pg_inv_work);
+ struct inode *inode = &ci->vfs_inode;
+ u32 orig_gen;
+ int check = 0;
+
+ spin_lock(&inode->i_lock);
+ dout("invalidate_pages %p gen %d revoking %d\n", inode,
+ ci->i_rdcache_gen, ci->i_rdcache_revoking);
+ if (ci->i_rdcache_gen == 0 ||
+ ci->i_rdcache_revoking != ci->i_rdcache_gen) {
+ BUG_ON(ci->i_rdcache_revoking > ci->i_rdcache_gen);
+ /* nevermind! */
+ ci->i_rdcache_revoking = 0;
+ spin_unlock(&inode->i_lock);
+ goto out;
+ }
+ orig_gen = ci->i_rdcache_gen;
+ spin_unlock(&inode->i_lock);
+
+ ceph_invalidate_nondirty_pages(inode->i_mapping);
+
+ spin_lock(&inode->i_lock);
+ if (orig_gen == ci->i_rdcache_gen) {
+ dout("invalidate_pages %p gen %d successful\n", inode,
+ ci->i_rdcache_gen);
+ ci->i_rdcache_gen = 0;
+ ci->i_rdcache_revoking = 0;
+ check = 1;
+ } else {
+ dout("invalidate_pages %p gen %d raced, gen now %d\n",
+ inode, orig_gen, ci->i_rdcache_gen);
+ }
+ spin_unlock(&inode->i_lock);
+
+ if (check)
+ ceph_check_caps(ci, 0, NULL);
+out:
+ iput(inode);
+}
+
+
+/*
+ * called by trunc_wq; take i_mutex ourselves
+ *
+ * We also truncate in a separate thread as well.
+ */
+static void ceph_vmtruncate_work(struct work_struct *work)
+{
+ struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+ i_vmtruncate_work);
+ struct inode *inode = &ci->vfs_inode;
+
+ dout("vmtruncate_work %p\n", inode);
+ mutex_lock(&inode->i_mutex);
+ __ceph_do_pending_vmtruncate(inode);
+ mutex_unlock(&inode->i_mutex);
+ iput(inode);
+}
+
+/*
+ * Queue an async vmtruncate. If we fail to queue work, we will handle
+ * the truncation the next time we call __ceph_do_pending_vmtruncate.
+ */
+void ceph_queue_vmtruncate(struct inode *inode)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ if (queue_work(ceph_client(inode->i_sb)->trunc_wq,
+ &ci->i_vmtruncate_work)) {
+ dout("ceph_queue_vmtruncate %p\n", inode);
+ igrab(inode);
+ } else {
+ dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
+ inode, ci->i_truncate_pending);
+ }
+}
+
+/*
+ * called with i_mutex held.
+ *
+ * Make sure any pending truncation is applied before doing anything
+ * that may depend on it.
+ */
+void __ceph_do_pending_vmtruncate(struct inode *inode)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ u64 to;
+ int wrbuffer_refs, wake = 0;
+
+retry:
+ spin_lock(&inode->i_lock);
+ if (ci->i_truncate_pending == 0) {
+ dout("__do_pending_vmtruncate %p none pending\n", inode);
+ spin_unlock(&inode->i_lock);
+ return;
+ }
+
+ /*
+ * make sure any dirty snapped pages are flushed before we
+ * possibly truncate them.. so write AND block!
+ */
+ if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) {
+ dout("__do_pending_vmtruncate %p flushing snaps first\n",
+ inode);
+ spin_unlock(&inode->i_lock);
+ filemap_write_and_wait_range(&inode->i_data, 0,
+ inode->i_sb->s_maxbytes);
+ goto retry;
+ }
+
+ to = ci->i_truncate_size;
+ wrbuffer_refs = ci->i_wrbuffer_ref;
+ dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode,
+ ci->i_truncate_pending, to);
+ spin_unlock(&inode->i_lock);
+
+ truncate_inode_pages(inode->i_mapping, to);
+
+ spin_lock(&inode->i_lock);
+ ci->i_truncate_pending--;
+ if (ci->i_truncate_pending == 0)
+ wake = 1;
+ spin_unlock(&inode->i_lock);
+
+ if (wrbuffer_refs == 0)
+ ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+ if (wake)
+ wake_up(&ci->i_cap_wq);
+}
+
+
+/*
+ * symlinks
+ */
+static void *ceph_sym_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ struct ceph_inode_info *ci = ceph_inode(dentry->d_inode);
+ nd_set_link(nd, ci->i_symlink);
+ return NULL;
+}
+
+static const struct inode_operations ceph_symlink_iops = {
+ .readlink = generic_readlink,
+ .follow_link = ceph_sym_follow_link,
+};
+
+/*
+ * setattr
+ */
+int ceph_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct inode *parent_inode = dentry->d_parent->d_inode;
+ const unsigned int ia_valid = attr->ia_valid;
+ struct ceph_mds_request *req;
+ struct ceph_mds_client *mdsc = &ceph_client(dentry->d_sb)->mdsc;
+ int issued;
+ int release = 0, dirtied = 0;
+ int mask = 0;
+ int err = 0;
+
+ if (ceph_snap(inode) != CEPH_NOSNAP)
+ return -EROFS;
+
+ __ceph_do_pending_vmtruncate(inode);
+
+ err = inode_change_ok(inode, attr);
+ if (err != 0)
+ return err;
+
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETATTR,
+ USE_AUTH_MDS);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+ spin_lock(&inode->i_lock);
+ issued = __ceph_caps_issued(ci, NULL);
+ dout("setattr %p issued %s\n", inode, ceph_cap_string(issued));
+
+ if (ia_valid & ATTR_UID) {
+ dout("setattr %p uid %d -> %d\n", inode,
+ inode->i_uid, attr->ia_uid);
+ if (issued & CEPH_CAP_AUTH_EXCL) {
+ inode->i_uid = attr->ia_uid;
+ dirtied |= CEPH_CAP_AUTH_EXCL;
+ } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+ attr->ia_uid != inode->i_uid) {
+ req->r_args.setattr.uid = cpu_to_le32(attr->ia_uid);
+ mask |= CEPH_SETATTR_UID;
+ release |= CEPH_CAP_AUTH_SHARED;
+ }
+ }
+ if (ia_valid & ATTR_GID) {
+ dout("setattr %p gid %d -> %d\n", inode,
+ inode->i_gid, attr->ia_gid);
+ if (issued & CEPH_CAP_AUTH_EXCL) {
+ inode->i_gid = attr->ia_gid;
+ dirtied |= CEPH_CAP_AUTH_EXCL;
+ } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+ attr->ia_gid != inode->i_gid) {
+ req->r_args.setattr.gid = cpu_to_le32(attr->ia_gid);
+ mask |= CEPH_SETATTR_GID;
+ release |= CEPH_CAP_AUTH_SHARED;
+ }
+ }
+ if (ia_valid & ATTR_MODE) {
+ dout("setattr %p mode 0%o -> 0%o\n", inode, inode->i_mode,
+ attr->ia_mode);
+ if (issued & CEPH_CAP_AUTH_EXCL) {
+ inode->i_mode = attr->ia_mode;
+ dirtied |= CEPH_CAP_AUTH_EXCL;
+ } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+ attr->ia_mode != inode->i_mode) {
+ req->r_args.setattr.mode = cpu_to_le32(attr->ia_mode);
+ mask |= CEPH_SETATTR_MODE;
+ release |= CEPH_CAP_AUTH_SHARED;
+ }
+ }
+
+ if (ia_valid & ATTR_ATIME) {
+ dout("setattr %p atime %ld.%ld -> %ld.%ld\n", inode,
+ inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
+ attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
+ if (issued & CEPH_CAP_FILE_EXCL) {
+ ci->i_time_warp_seq++;
+ inode->i_atime = attr->ia_atime;
+ dirtied |= CEPH_CAP_FILE_EXCL;
+ } else if ((issued & CEPH_CAP_FILE_WR) &&
+ timespec_compare(&inode->i_atime,
+ &attr->ia_atime) < 0) {
+ inode->i_atime = attr->ia_atime;
+ dirtied |= CEPH_CAP_FILE_WR;
+ } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+ !timespec_equal(&inode->i_atime, &attr->ia_atime)) {
+ ceph_encode_timespec(&req->r_args.setattr.atime,
+ &attr->ia_atime);
+ mask |= CEPH_SETATTR_ATIME;
+ release |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD |
+ CEPH_CAP_FILE_WR;
+ }
+ }
+ if (ia_valid & ATTR_MTIME) {
+ dout("setattr %p mtime %ld.%ld -> %ld.%ld\n", inode,
+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+ attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
+ if (issued & CEPH_CAP_FILE_EXCL) {
+ ci->i_time_warp_seq++;
+ inode->i_mtime = attr->ia_mtime;
+ dirtied |= CEPH_CAP_FILE_EXCL;
+ } else if ((issued & CEPH_CAP_FILE_WR) &&
+ timespec_compare(&inode->i_mtime,
+ &attr->ia_mtime) < 0) {
+ inode->i_mtime = attr->ia_mtime;
+ dirtied |= CEPH_CAP_FILE_WR;
+ } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+ !timespec_equal(&inode->i_mtime, &attr->ia_mtime)) {
+ ceph_encode_timespec(&req->r_args.setattr.mtime,
+ &attr->ia_mtime);
+ mask |= CEPH_SETATTR_MTIME;
+ release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
+ CEPH_CAP_FILE_WR;
+ }
+ }
+ if (ia_valid & ATTR_SIZE) {
+ dout("setattr %p size %lld -> %lld\n", inode,
+ inode->i_size, attr->ia_size);
+ if (attr->ia_size > inode->i_sb->s_maxbytes) {
+ err = -EINVAL;
+ goto out;
+ }
+ if ((issued & CEPH_CAP_FILE_EXCL) &&
+ attr->ia_size > inode->i_size) {
+ inode->i_size = attr->ia_size;
+ inode->i_blocks =
+ (attr->ia_size + (1 << 9) - 1) >> 9;
+ inode->i_ctime = attr->ia_ctime;
+ ci->i_reported_size = attr->ia_size;
+ dirtied |= CEPH_CAP_FILE_EXCL;
+ } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+ attr->ia_size != inode->i_size) {
+ req->r_args.setattr.size = cpu_to_le64(attr->ia_size);
+ req->r_args.setattr.old_size =
+ cpu_to_le64(inode->i_size);
+ mask |= CEPH_SETATTR_SIZE;
+ release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
+ CEPH_CAP_FILE_WR;
+ }
+ }
+
+ /* these do nothing */
+ if (ia_valid & ATTR_CTIME) {
+ bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME|
+ ATTR_MODE|ATTR_UID|ATTR_GID)) == 0;
+ dout("setattr %p ctime %ld.%ld -> %ld.%ld (%s)\n", inode,
+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+ attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
+ only ? "ctime only" : "ignored");
+ inode->i_ctime = attr->ia_ctime;
+ if (only) {
+ /*
+ * if kernel wants to dirty ctime but nothing else,
+ * we need to choose a cap to dirty under, or do
+ * a almost-no-op setattr
+ */
+ if (issued & CEPH_CAP_AUTH_EXCL)
+ dirtied |= CEPH_CAP_AUTH_EXCL;
+ else if (issued & CEPH_CAP_FILE_EXCL)
+ dirtied |= CEPH_CAP_FILE_EXCL;
+ else if (issued & CEPH_CAP_XATTR_EXCL)
+ dirtied |= CEPH_CAP_XATTR_EXCL;
+ else
+ mask |= CEPH_SETATTR_CTIME;
+ }
+ }
+ if (ia_valid & ATTR_FILE)
+ dout("setattr %p ATTR_FILE ... hrm!\n", inode);
+
+ if (dirtied) {
+ __ceph_mark_dirty_caps(ci, dirtied);
+ inode->i_ctime = CURRENT_TIME;
+ }
+
+ release &= issued;
+ spin_unlock(&inode->i_lock);
+
+ if (mask) {
+ req->r_inode = igrab(inode);
+ req->r_inode_drop = release;
+ req->r_args.setattr.mask = cpu_to_le32(mask);
+ req->r_num_caps = 1;
+ err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+ }
+ dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
+ ceph_cap_string(dirtied), mask);
+
+ ceph_mdsc_put_request(req);
+ __ceph_do_pending_vmtruncate(inode);
+ return err;
+out:
+ spin_unlock(&inode->i_lock);
+ ceph_mdsc_put_request(req);
+ return err;
+}
+
+/*
+ * Verify that we have a lease on the given mask. If not,
+ * do a getattr against an mds.
+ */
+int ceph_do_getattr(struct inode *inode, int mask)
+{
+ struct ceph_client *client = ceph_sb_to_client(inode->i_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req;
+ int err;
+
+ if (ceph_snap(inode) == CEPH_SNAPDIR) {
+ dout("do_getattr inode %p SNAPDIR\n", inode);
+ return 0;
+ }
+
+ dout("do_getattr inode %p mask %s\n", inode, ceph_cap_string(mask));
+ if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
+ return 0;
+
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+ req->r_inode = igrab(inode);
+ req->r_num_caps = 1;
+ req->r_args.getattr.mask = cpu_to_le32(mask);
+ err = ceph_mdsc_do_request(mdsc, NULL, req);
+ ceph_mdsc_put_request(req);
+ dout("do_getattr result=%d\n", err);
+ return err;
+}
+
+
+/*
+ * Check inode permissions. We verify we have a valid value for
+ * the AUTH cap, then call the generic handler.
+ */
+int ceph_permission(struct inode *inode, int mask)
+{
+ int err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED);
+
+ if (!err)
+ err = generic_permission(inode, mask, NULL);
+ return err;
+}
+
+/*
+ * Get all attributes. Hopefully somedata we'll have a statlite()
+ * and can limit the fields we require to be accurate.
+ */
+int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int err;
+
+ err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL);
+ if (!err) {
+ generic_fillattr(inode, stat);
+ stat->ino = inode->i_ino;
+ if (ceph_snap(inode) != CEPH_NOSNAP)
+ stat->dev = ceph_snap(inode);
+ else
+ stat->dev = 0;
+ if (S_ISDIR(inode->i_mode)) {
+ stat->size = ci->i_rbytes;
+ stat->blocks = 0;
+ stat->blksize = 65536;
+ }
+ }
+ return err;
+}
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c
new file mode 100644
index 00000000000..8a5bcae6284
--- /dev/null
+++ b/fs/ceph/ioctl.c
@@ -0,0 +1,160 @@
+#include <linux/in.h>
+
+#include "ioctl.h"
+#include "super.h"
+#include "ceph_debug.h"
+
+
+/*
+ * ioctls
+ */
+
+/*
+ * get and set the file layout
+ */
+static long ceph_ioctl_get_layout(struct file *file, void __user *arg)
+{
+ struct ceph_inode_info *ci = ceph_inode(file->f_dentry->d_inode);
+ struct ceph_ioctl_layout l;
+ int err;
+
+ err = ceph_do_getattr(file->f_dentry->d_inode, CEPH_STAT_CAP_LAYOUT);
+ if (!err) {
+ l.stripe_unit = ceph_file_layout_su(ci->i_layout);
+ l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout);
+ l.object_size = ceph_file_layout_object_size(ci->i_layout);
+ l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool);
+ l.preferred_osd =
+ (s32)le32_to_cpu(ci->i_layout.fl_pg_preferred);
+ if (copy_to_user(arg, &l, sizeof(l)))
+ return -EFAULT;
+ }
+
+ return err;
+}
+
+static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
+ struct ceph_mds_client *mdsc = &ceph_sb_to_client(inode->i_sb)->mdsc;
+ struct ceph_mds_request *req;
+ struct ceph_ioctl_layout l;
+ int err, i;
+
+ /* copy and validate */
+ if (copy_from_user(&l, arg, sizeof(l)))
+ return -EFAULT;
+
+ if ((l.object_size & ~PAGE_MASK) ||
+ (l.stripe_unit & ~PAGE_MASK) ||
+ !l.stripe_unit ||
+ (l.object_size &&
+ (unsigned)l.object_size % (unsigned)l.stripe_unit))
+ return -EINVAL;
+
+ /* make sure it's a valid data pool */
+ if (l.data_pool > 0) {
+ mutex_lock(&mdsc->mutex);
+ err = -EINVAL;
+ for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++)
+ if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) {
+ err = 0;
+ break;
+ }
+ mutex_unlock(&mdsc->mutex);
+ if (err)
+ return err;
+ }
+
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT,
+ USE_AUTH_MDS);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+ req->r_inode = igrab(inode);
+ req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL;
+
+ req->r_args.setlayout.layout.fl_stripe_unit =
+ cpu_to_le32(l.stripe_unit);
+ req->r_args.setlayout.layout.fl_stripe_count =
+ cpu_to_le32(l.stripe_count);
+ req->r_args.setlayout.layout.fl_object_size =
+ cpu_to_le32(l.object_size);
+ req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool);
+ req->r_args.setlayout.layout.fl_pg_preferred =
+ cpu_to_le32(l.preferred_osd);
+
+ err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+ ceph_mdsc_put_request(req);
+ return err;
+}
+
+/*
+ * Return object name, size/offset information, and location (OSD
+ * number, network address) for a given file offset.
+ */
+static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
+{
+ struct ceph_ioctl_dataloc dl;
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc;
+ u64 len = 1, olen;
+ u64 tmp;
+ struct ceph_object_layout ol;
+ struct ceph_pg pgid;
+
+ /* copy and validate */
+ if (copy_from_user(&dl, arg, sizeof(dl)))
+ return -EFAULT;
+
+ down_read(&osdc->map_sem);
+ ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len,
+ &dl.object_no, &dl.object_offset, &olen);
+ dl.file_offset -= dl.object_offset;
+ dl.object_size = ceph_file_layout_object_size(ci->i_layout);
+ dl.block_size = ceph_file_layout_su(ci->i_layout);
+
+ /* block_offset = object_offset % block_size */
+ tmp = dl.object_offset;
+ dl.block_offset = do_div(tmp, dl.block_size);
+
+ snprintf(dl.object_name, sizeof(dl.object_name), "%llx.%08llx",
+ ceph_ino(inode), dl.object_no);
+ ceph_calc_object_layout(&ol, dl.object_name, &ci->i_layout,
+ osdc->osdmap);
+
+ pgid = ol.ol_pgid;
+ dl.osd = ceph_calc_pg_primary(osdc->osdmap, pgid);
+ if (dl.osd >= 0) {
+ struct ceph_entity_addr *a =
+ ceph_osd_addr(osdc->osdmap, dl.osd);
+ if (a)
+ memcpy(&dl.osd_addr, &a->in_addr, sizeof(dl.osd_addr));
+ } else {
+ memset(&dl.osd_addr, 0, sizeof(dl.osd_addr));
+ }
+ up_read(&osdc->map_sem);
+
+ /* send result back to user */
+ if (copy_to_user(arg, &dl, sizeof(dl)))
+ return -EFAULT;
+
+ 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);
+ switch (cmd) {
+ case CEPH_IOC_GET_LAYOUT:
+ return ceph_ioctl_get_layout(file, (void __user *)arg);
+
+ case CEPH_IOC_SET_LAYOUT:
+ return ceph_ioctl_set_layout(file, (void __user *)arg);
+
+ case CEPH_IOC_GET_DATALOC:
+ return ceph_ioctl_get_dataloc(file, (void __user *)arg);
+ }
+ return -ENOTTY;
+}
diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h
new file mode 100644
index 00000000000..25e4f1a9d05
--- /dev/null
+++ b/fs/ceph/ioctl.h
@@ -0,0 +1,40 @@
+#ifndef FS_CEPH_IOCTL_H
+#define FS_CEPH_IOCTL_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define CEPH_IOCTL_MAGIC 0x97
+
+/* just use u64 to align sanely on all archs */
+struct ceph_ioctl_layout {
+ __u64 stripe_unit, stripe_count, object_size;
+ __u64 data_pool;
+ __s64 preferred_osd;
+};
+
+#define CEPH_IOC_GET_LAYOUT _IOR(CEPH_IOCTL_MAGIC, 1, \
+ struct ceph_ioctl_layout)
+#define CEPH_IOC_SET_LAYOUT _IOW(CEPH_IOCTL_MAGIC, 2, \
+ struct ceph_ioctl_layout)
+
+/*
+ * Extract identity, address of the OSD and object storing a given
+ * file offset.
+ */
+struct ceph_ioctl_dataloc {
+ __u64 file_offset; /* in+out: file offset */
+ __u64 object_offset; /* out: offset in object */
+ __u64 object_no; /* out: object # */
+ __u64 object_size; /* out: object size */
+ char object_name[64]; /* out: object name */
+ __u64 block_offset; /* out: offset in block */
+ __u64 block_size; /* out: block length */
+ __s64 osd; /* out: osd # */
+ struct sockaddr_storage osd_addr; /* out: osd address */
+};
+
+#define CEPH_IOC_GET_DATALOC _IOWR(CEPH_IOCTL_MAGIC, 3, \
+ struct ceph_ioctl_dataloc)
+
+#endif
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
new file mode 100644
index 00000000000..60a9a4ae47b
--- /dev/null
+++ b/fs/ceph/mds_client.c
@@ -0,0 +1,3043 @@
+#include "ceph_debug.h"
+
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+#include "mds_client.h"
+#include "mon_client.h"
+#include "super.h"
+#include "messenger.h"
+#include "decode.h"
+#include "auth.h"
+#include "pagelist.h"
+
+/*
+ * A cluster of MDS (metadata server) daemons is responsible for
+ * managing the file system namespace (the directory hierarchy and
+ * inodes) and for coordinating shared access to storage. Metadata is
+ * partitioning hierarchically across a number of servers, and that
+ * partition varies over time as the cluster adjusts the distribution
+ * in order to balance load.
+ *
+ * The MDS client is primarily responsible to managing synchronous
+ * metadata requests for operations like open, unlink, and so forth.
+ * If there is a MDS failure, we find out about it when we (possibly
+ * request and) receive a new MDS map, and can resubmit affected
+ * requests.
+ *
+ * For the most part, though, we take advantage of a lossless
+ * communications channel to the MDS, and do not need to worry about
+ * timing out or resubmitting requests.
+ *
+ * We maintain a stateful "session" with each MDS we interact with.
+ * Within each session, we sent periodic heartbeat messages to ensure
+ * any capabilities or leases we have been issues remain valid. If
+ * the session times out and goes stale, our leases and capabilities
+ * are no longer valid.
+ */
+
+static void __wake_requests(struct ceph_mds_client *mdsc,
+ struct list_head *head);
+
+const static struct ceph_connection_operations mds_con_ops;
+
+
+/*
+ * mds reply parsing
+ */
+
+/*
+ * parse individual inode info
+ */
+static int parse_reply_info_in(void **p, void *end,
+ struct ceph_mds_reply_info_in *info)
+{
+ int err = -EIO;
+
+ info->in = *p;
+ *p += sizeof(struct ceph_mds_reply_inode) +
+ sizeof(*info->in->fragtree.splits) *
+ le32_to_cpu(info->in->fragtree.nsplits);
+
+ ceph_decode_32_safe(p, end, info->symlink_len, bad);
+ ceph_decode_need(p, end, info->symlink_len, bad);
+ info->symlink = *p;
+ *p += info->symlink_len;
+
+ ceph_decode_32_safe(p, end, info->xattr_len, bad);
+ ceph_decode_need(p, end, info->xattr_len, bad);
+ info->xattr_data = *p;
+ *p += info->xattr_len;
+ return 0;
+bad:
+ return err;
+}
+
+/*
+ * parse a normal reply, which may contain a (dir+)dentry and/or a
+ * target inode.
+ */
+static int parse_reply_info_trace(void **p, void *end,
+ struct ceph_mds_reply_info_parsed *info)
+{
+ int err;
+
+ if (info->head->is_dentry) {
+ err = parse_reply_info_in(p, end, &info->diri);
+ if (err < 0)
+ goto out_bad;
+
+ if (unlikely(*p + sizeof(*info->dirfrag) > end))
+ goto bad;
+ info->dirfrag = *p;
+ *p += sizeof(*info->dirfrag) +
+ sizeof(u32)*le32_to_cpu(info->dirfrag->ndist);
+ if (unlikely(*p > end))
+ goto bad;
+
+ ceph_decode_32_safe(p, end, info->dname_len, bad);
+ ceph_decode_need(p, end, info->dname_len, bad);
+ info->dname = *p;
+ *p += info->dname_len;
+ info->dlease = *p;
+ *p += sizeof(*info->dlease);
+ }
+
+ if (info->head->is_target) {
+ err = parse_reply_info_in(p, end, &info->targeti);
+ if (err < 0)
+ goto out_bad;
+ }
+
+ if (unlikely(*p != end))
+ goto bad;
+ return 0;
+
+bad:
+ err = -EIO;
+out_bad:
+ pr_err("problem parsing mds trace %d\n", err);
+ return err;
+}
+
+/*
+ * parse readdir results
+ */
+static int parse_reply_info_dir(void **p, void *end,
+ struct ceph_mds_reply_info_parsed *info)
+{
+ u32 num, i = 0;
+ int err;
+
+ info->dir_dir = *p;
+ if (*p + sizeof(*info->dir_dir) > end)
+ goto bad;
+ *p += sizeof(*info->dir_dir) +
+ sizeof(u32)*le32_to_cpu(info->dir_dir->ndist);
+ if (*p > end)
+ goto bad;
+
+ ceph_decode_need(p, end, sizeof(num) + 2, bad);
+ num = ceph_decode_32(p);
+ info->dir_end = ceph_decode_8(p);
+ info->dir_complete = ceph_decode_8(p);
+ if (num == 0)
+ goto done;
+
+ /* alloc large array */
+ info->dir_nr = num;
+ info->dir_in = kcalloc(num, sizeof(*info->dir_in) +
+ sizeof(*info->dir_dname) +
+ sizeof(*info->dir_dname_len) +
+ sizeof(*info->dir_dlease),
+ GFP_NOFS);
+ if (info->dir_in == NULL) {
+ err = -ENOMEM;
+ goto out_bad;
+ }
+ info->dir_dname = (void *)(info->dir_in + num);
+ info->dir_dname_len = (void *)(info->dir_dname + num);
+ info->dir_dlease = (void *)(info->dir_dname_len + num);
+
+ while (num) {
+ /* dentry */
+ ceph_decode_need(p, end, sizeof(u32)*2, bad);
+ info->dir_dname_len[i] = ceph_decode_32(p);
+ ceph_decode_need(p, end, info->dir_dname_len[i], bad);
+ info->dir_dname[i] = *p;
+ *p += info->dir_dname_len[i];
+ dout("parsed dir dname '%.*s'\n", info->dir_dname_len[i],
+ info->dir_dname[i]);
+ info->dir_dlease[i] = *p;
+ *p += sizeof(struct ceph_mds_reply_lease);
+
+ /* inode */
+ err = parse_reply_info_in(p, end, &info->dir_in[i]);
+ if (err < 0)
+ goto out_bad;
+ i++;
+ num--;
+ }
+
+done:
+ if (*p != end)
+ goto bad;
+ return 0;
+
+bad:
+ err = -EIO;
+out_bad:
+ pr_err("problem parsing dir contents %d\n", err);
+ return err;
+}
+
+/*
+ * parse entire mds reply
+ */
+static int parse_reply_info(struct ceph_msg *msg,
+ struct ceph_mds_reply_info_parsed *info)
+{
+ void *p, *end;
+ u32 len;
+ int err;
+
+ info->head = msg->front.iov_base;
+ p = msg->front.iov_base + sizeof(struct ceph_mds_reply_head);
+ end = p + msg->front.iov_len - sizeof(struct ceph_mds_reply_head);
+
+ /* trace */
+ ceph_decode_32_safe(&p, end, len, bad);
+ if (len > 0) {
+ err = parse_reply_info_trace(&p, p+len, info);
+ if (err < 0)
+ goto out_bad;
+ }
+
+ /* dir content */
+ ceph_decode_32_safe(&p, end, len, bad);
+ if (len > 0) {
+ err = parse_reply_info_dir(&p, p+len, info);
+ if (err < 0)
+ goto out_bad;
+ }
+
+ /* snap blob */
+ ceph_decode_32_safe(&p, end, len, bad);
+ info->snapblob_len = len;
+ info->snapblob = p;
+ p += len;
+
+ if (p != end)
+ goto bad;
+ return 0;
+
+bad:
+ err = -EIO;
+out_bad:
+ pr_err("mds parse_reply err %d\n", err);
+ return err;
+}
+
+static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info)
+{
+ kfree(info->dir_in);
+}
+
+
+/*
+ * sessions
+ */
+static const char *session_state_name(int s)
+{
+ switch (s) {
+ case CEPH_MDS_SESSION_NEW: return "new";
+ case CEPH_MDS_SESSION_OPENING: return "opening";
+ case CEPH_MDS_SESSION_OPEN: return "open";
+ case CEPH_MDS_SESSION_HUNG: return "hung";
+ case CEPH_MDS_SESSION_CLOSING: return "closing";
+ case CEPH_MDS_SESSION_RESTARTING: return "restarting";
+ case CEPH_MDS_SESSION_RECONNECTING: return "reconnecting";
+ default: return "???";
+ }
+}
+
+static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
+{
+ if (atomic_inc_not_zero(&s->s_ref)) {
+ dout("mdsc get_session %p %d -> %d\n", s,
+ atomic_read(&s->s_ref)-1, atomic_read(&s->s_ref));
+ return s;
+ } else {
+ dout("mdsc get_session %p 0 -- FAIL", s);
+ return NULL;
+ }
+}
+
+void ceph_put_mds_session(struct ceph_mds_session *s)
+{
+ dout("mdsc put_session %p %d -> %d\n", s,
+ atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1);
+ if (atomic_dec_and_test(&s->s_ref)) {
+ if (s->s_authorizer)
+ s->s_mdsc->client->monc.auth->ops->destroy_authorizer(
+ s->s_mdsc->client->monc.auth, s->s_authorizer);
+ kfree(s);
+ }
+}
+
+/*
+ * called under mdsc->mutex
+ */
+struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc,
+ int mds)
+{
+ struct ceph_mds_session *session;
+
+ if (mds >= mdsc->max_sessions || mdsc->sessions[mds] == NULL)
+ return NULL;
+ session = mdsc->sessions[mds];
+ dout("lookup_mds_session %p %d\n", session,
+ atomic_read(&session->s_ref));
+ get_session(session);
+ return session;
+}
+
+static bool __have_session(struct ceph_mds_client *mdsc, int mds)
+{
+ if (mds >= mdsc->max_sessions)
+ return false;
+ return mdsc->sessions[mds];
+}
+
+static int __verify_registered_session(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *s)
+{
+ if (s->s_mds >= mdsc->max_sessions ||
+ mdsc->sessions[s->s_mds] != s)
+ return -ENOENT;
+ return 0;
+}
+
+/*
+ * create+register a new session for given mds.
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
+ int mds)
+{
+ struct ceph_mds_session *s;
+
+ s = kzalloc(sizeof(*s), GFP_NOFS);
+ if (!s)
+ return ERR_PTR(-ENOMEM);
+ s->s_mdsc = mdsc;
+ s->s_mds = mds;
+ s->s_state = CEPH_MDS_SESSION_NEW;
+ s->s_ttl = 0;
+ s->s_seq = 0;
+ mutex_init(&s->s_mutex);
+
+ ceph_con_init(mdsc->client->msgr, &s->s_con);
+ s->s_con.private = s;
+ s->s_con.ops = &mds_con_ops;
+ s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS;
+ s->s_con.peer_name.num = cpu_to_le64(mds);
+
+ spin_lock_init(&s->s_cap_lock);
+ s->s_cap_gen = 0;
+ s->s_cap_ttl = 0;
+ s->s_renew_requested = 0;
+ s->s_renew_seq = 0;
+ INIT_LIST_HEAD(&s->s_caps);
+ s->s_nr_caps = 0;
+ s->s_trim_caps = 0;
+ atomic_set(&s->s_ref, 1);
+ INIT_LIST_HEAD(&s->s_waiting);
+ INIT_LIST_HEAD(&s->s_unsafe);
+ s->s_num_cap_releases = 0;
+ s->s_cap_iterator = NULL;
+ INIT_LIST_HEAD(&s->s_cap_releases);
+ INIT_LIST_HEAD(&s->s_cap_releases_done);
+ INIT_LIST_HEAD(&s->s_cap_flushing);
+ INIT_LIST_HEAD(&s->s_cap_snaps_flushing);
+
+ dout("register_session mds%d\n", mds);
+ if (mds >= mdsc->max_sessions) {
+ int newmax = 1 << get_count_order(mds+1);
+ struct ceph_mds_session **sa;
+
+ dout("register_session realloc to %d\n", newmax);
+ sa = kcalloc(newmax, sizeof(void *), GFP_NOFS);
+ if (sa == NULL)
+ goto fail_realloc;
+ if (mdsc->sessions) {
+ memcpy(sa, mdsc->sessions,
+ mdsc->max_sessions * sizeof(void *));
+ kfree(mdsc->sessions);
+ }
+ mdsc->sessions = sa;
+ mdsc->max_sessions = newmax;
+ }
+ mdsc->sessions[mds] = s;
+ atomic_inc(&s->s_ref); /* one ref to sessions[], one to caller */
+
+ ceph_con_open(&s->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds));
+
+ return s;
+
+fail_realloc:
+ kfree(s);
+ return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static void __unregister_session(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *s)
+{
+ dout("__unregister_session mds%d %p\n", s->s_mds, s);
+ BUG_ON(mdsc->sessions[s->s_mds] != s);
+ mdsc->sessions[s->s_mds] = NULL;
+ ceph_con_close(&s->s_con);
+ ceph_put_mds_session(s);
+}
+
+/*
+ * drop session refs in request.
+ *
+ * should be last request ref, or hold mdsc->mutex
+ */
+static void put_request_session(struct ceph_mds_request *req)
+{
+ if (req->r_session) {
+ ceph_put_mds_session(req->r_session);
+ req->r_session = NULL;
+ }
+}
+
+void ceph_mdsc_release_request(struct kref *kref)
+{
+ struct ceph_mds_request *req = container_of(kref,
+ struct ceph_mds_request,
+ r_kref);
+ if (req->r_request)
+ ceph_msg_put(req->r_request);
+ if (req->r_reply) {
+ ceph_msg_put(req->r_reply);
+ destroy_reply_info(&req->r_reply_info);
+ }
+ if (req->r_inode) {
+ ceph_put_cap_refs(ceph_inode(req->r_inode),
+ CEPH_CAP_PIN);
+ iput(req->r_inode);
+ }
+ if (req->r_locked_dir)
+ ceph_put_cap_refs(ceph_inode(req->r_locked_dir),
+ CEPH_CAP_PIN);
+ if (req->r_target_inode)
+ iput(req->r_target_inode);
+ if (req->r_dentry)
+ dput(req->r_dentry);
+ if (req->r_old_dentry) {
+ ceph_put_cap_refs(
+ ceph_inode(req->r_old_dentry->d_parent->d_inode),
+ CEPH_CAP_PIN);
+ dput(req->r_old_dentry);
+ }
+ kfree(req->r_path1);
+ kfree(req->r_path2);
+ put_request_session(req);
+ ceph_unreserve_caps(&req->r_caps_reservation);
+ kfree(req);
+}
+
+/*
+ * lookup session, bump ref if found.
+ *
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_request *__lookup_request(struct ceph_mds_client *mdsc,
+ u64 tid)
+{
+ struct ceph_mds_request *req;
+ struct rb_node *n = mdsc->request_tree.rb_node;
+
+ while (n) {
+ req = rb_entry(n, struct ceph_mds_request, r_node);
+ if (tid < req->r_tid)
+ n = n->rb_left;
+ else if (tid > req->r_tid)
+ n = n->rb_right;
+ else {
+ ceph_mdsc_get_request(req);
+ return req;
+ }
+ }
+ return NULL;
+}
+
+static void __insert_request(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *new)
+{
+ struct rb_node **p = &mdsc->request_tree.rb_node;
+ struct rb_node *parent = NULL;
+ struct ceph_mds_request *req = NULL;
+
+ while (*p) {
+ parent = *p;
+ req = rb_entry(parent, struct ceph_mds_request, r_node);
+ if (new->r_tid < req->r_tid)
+ p = &(*p)->rb_left;
+ else if (new->r_tid > req->r_tid)
+ p = &(*p)->rb_right;
+ else
+ BUG();
+ }
+
+ rb_link_node(&new->r_node, parent, p);
+ rb_insert_color(&new->r_node, &mdsc->request_tree);
+}
+
+/*
+ * Register an in-flight request, and assign a tid. Link to directory
+ * are modifying (if any).
+ *
+ * Called under mdsc->mutex.
+ */
+static void __register_request(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req,
+ struct inode *dir)
+{
+ req->r_tid = ++mdsc->last_tid;
+ if (req->r_num_caps)
+ ceph_reserve_caps(&req->r_caps_reservation, req->r_num_caps);
+ dout("__register_request %p tid %lld\n", req, req->r_tid);
+ ceph_mdsc_get_request(req);
+ __insert_request(mdsc, req);
+
+ if (dir) {
+ struct ceph_inode_info *ci = ceph_inode(dir);
+
+ spin_lock(&ci->i_unsafe_lock);
+ req->r_unsafe_dir = dir;
+ list_add_tail(&req->r_unsafe_dir_item, &ci->i_unsafe_dirops);
+ spin_unlock(&ci->i_unsafe_lock);
+ }
+}
+
+static void __unregister_request(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req)
+{
+ dout("__unregister_request %p tid %lld\n", req, req->r_tid);
+ rb_erase(&req->r_node, &mdsc->request_tree);
+ RB_CLEAR_NODE(&req->r_node);
+
+ if (req->r_unsafe_dir) {
+ struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir);
+
+ spin_lock(&ci->i_unsafe_lock);
+ list_del_init(&req->r_unsafe_dir_item);
+ spin_unlock(&ci->i_unsafe_lock);
+ }
+
+ ceph_mdsc_put_request(req);
+}
+
+/*
+ * Choose mds to send request to next. If there is a hint set in the
+ * request (e.g., due to a prior forward hint from the mds), use that.
+ * Otherwise, consult frag tree and/or caps to identify the
+ * appropriate mds. If all else fails, choose randomly.
+ *
+ * Called under mdsc->mutex.
+ */
+static int __choose_mds(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req)
+{
+ struct inode *inode;
+ struct ceph_inode_info *ci;
+ struct ceph_cap *cap;
+ int mode = req->r_direct_mode;
+ int mds = -1;
+ u32 hash = req->r_direct_hash;
+ bool is_hash = req->r_direct_is_hash;
+
+ /*
+ * is there a specific mds we should try? ignore hint if we have
+ * no session and the mds is not up (active or recovering).
+ */
+ if (req->r_resend_mds >= 0 &&
+ (__have_session(mdsc, req->r_resend_mds) ||
+ ceph_mdsmap_get_state(mdsc->mdsmap, req->r_resend_mds) > 0)) {
+ dout("choose_mds using resend_mds mds%d\n",
+ req->r_resend_mds);
+ return req->r_resend_mds;
+ }
+
+ if (mode == USE_RANDOM_MDS)
+ goto random;
+
+ inode = NULL;
+ if (req->r_inode) {
+ inode = req->r_inode;
+ } else if (req->r_dentry) {
+ if (req->r_dentry->d_inode) {
+ inode = req->r_dentry->d_inode;
+ } else {
+ inode = req->r_dentry->d_parent->d_inode;
+ hash = req->r_dentry->d_name.hash;
+ is_hash = true;
+ }
+ }
+ dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash,
+ (int)hash, mode);
+ if (!inode)
+ goto random;
+ ci = ceph_inode(inode);
+
+ if (is_hash && S_ISDIR(inode->i_mode)) {
+ struct ceph_inode_frag frag;
+ int found;
+
+ ceph_choose_frag(ci, hash, &frag, &found);
+ if (found) {
+ if (mode == USE_ANY_MDS && frag.ndist > 0) {
+ u8 r;
+
+ /* choose a random replica */
+ get_random_bytes(&r, 1);
+ r %= frag.ndist;
+ mds = frag.dist[r];
+ dout("choose_mds %p %llx.%llx "
+ "frag %u mds%d (%d/%d)\n",
+ inode, ceph_vinop(inode),
+ frag.frag, frag.mds,
+ (int)r, frag.ndist);
+ return mds;
+ }
+
+ /* since this file/dir wasn't known to be
+ * replicated, then we want to look for the
+ * authoritative mds. */
+ mode = USE_AUTH_MDS;
+ if (frag.mds >= 0) {
+ /* choose auth mds */
+ mds = frag.mds;
+ dout("choose_mds %p %llx.%llx "
+ "frag %u mds%d (auth)\n",
+ inode, ceph_vinop(inode), frag.frag, mds);
+ return mds;
+ }
+ }
+ }
+
+ spin_lock(&inode->i_lock);
+ cap = NULL;
+ if (mode == USE_AUTH_MDS)
+ cap = ci->i_auth_cap;
+ if (!cap && !RB_EMPTY_ROOT(&ci->i_caps))
+ cap = rb_entry(rb_first(&ci->i_caps), struct ceph_cap, ci_node);
+ if (!cap) {
+ spin_unlock(&inode->i_lock);
+ goto random;
+ }
+ mds = cap->session->s_mds;
+ dout("choose_mds %p %llx.%llx mds%d (%scap %p)\n",
+ inode, ceph_vinop(inode), mds,
+ cap == ci->i_auth_cap ? "auth " : "", cap);
+ spin_unlock(&inode->i_lock);
+ return mds;
+
+random:
+ mds = ceph_mdsmap_get_random_mds(mdsc->mdsmap);
+ dout("choose_mds chose random mds%d\n", mds);
+ return mds;
+}
+
+
+/*
+ * session messages
+ */
+static struct ceph_msg *create_session_msg(u32 op, u64 seq)
+{
+ struct ceph_msg *msg;
+ struct ceph_mds_session_head *h;
+
+ msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h), 0, 0, NULL);
+ if (IS_ERR(msg)) {
+ pr_err("create_session_msg ENOMEM creating msg\n");
+ return ERR_PTR(PTR_ERR(msg));
+ }
+ h = msg->front.iov_base;
+ h->op = cpu_to_le32(op);
+ h->seq = cpu_to_le64(seq);
+ return msg;
+}
+
+/*
+ * send session open request.
+ *
+ * called under mdsc->mutex
+ */
+static int __open_session(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session)
+{
+ struct ceph_msg *msg;
+ int mstate;
+ int mds = session->s_mds;
+ int err = 0;
+
+ /* wait for mds to go active? */
+ mstate = ceph_mdsmap_get_state(mdsc->mdsmap, mds);
+ dout("open_session to mds%d (%s)\n", mds,
+ ceph_mds_state_name(mstate));
+ session->s_state = CEPH_MDS_SESSION_OPENING;
+ session->s_renew_requested = jiffies;
+
+ /* send connect message */
+ msg = create_session_msg(CEPH_SESSION_REQUEST_OPEN, session->s_seq);
+ if (IS_ERR(msg)) {
+ err = PTR_ERR(msg);
+ goto out;
+ }
+ ceph_con_send(&session->s_con, msg);
+
+out:
+ return 0;
+}
+
+/*
+ * session caps
+ */
+
+/*
+ * Free preallocated cap messages assigned to this session
+ */
+static void cleanup_cap_releases(struct ceph_mds_session *session)
+{
+ struct ceph_msg *msg;
+
+ spin_lock(&session->s_cap_lock);
+ while (!list_empty(&session->s_cap_releases)) {
+ msg = list_first_entry(&session->s_cap_releases,
+ struct ceph_msg, list_head);
+ list_del_init(&msg->list_head);
+ ceph_msg_put(msg);
+ }
+ while (!list_empty(&session->s_cap_releases_done)) {
+ msg = list_first_entry(&session->s_cap_releases_done,
+ struct ceph_msg, list_head);
+ list_del_init(&msg->list_head);
+ ceph_msg_put(msg);
+ }
+ spin_unlock(&session->s_cap_lock);
+}
+
+/*
+ * Helper to safely iterate over all caps associated with a session.
+ *
+ * caller must hold session s_mutex
+ */
+static int iterate_session_caps(struct ceph_mds_session *session,
+ int (*cb)(struct inode *, struct ceph_cap *,
+ void *), void *arg)
+{
+ struct list_head *p;
+ struct ceph_cap *cap;
+ struct inode *inode, *last_inode = NULL;
+ struct ceph_cap *old_cap = NULL;
+ int ret;
+
+ dout("iterate_session_caps %p mds%d\n", session, session->s_mds);
+ spin_lock(&session->s_cap_lock);
+ p = session->s_caps.next;
+ while (p != &session->s_caps) {
+ cap = list_entry(p, struct ceph_cap, session_caps);
+ inode = igrab(&cap->ci->vfs_inode);
+ if (!inode) {
+ p = p->next;
+ continue;
+ }
+ session->s_cap_iterator = cap;
+ spin_unlock(&session->s_cap_lock);
+
+ if (last_inode) {
+ iput(last_inode);
+ last_inode = NULL;
+ }
+ if (old_cap) {
+ ceph_put_cap(old_cap);
+ old_cap = NULL;
+ }
+
+ ret = cb(inode, cap, arg);
+ last_inode = inode;
+
+ spin_lock(&session->s_cap_lock);
+ p = p->next;
+ if (cap->ci == NULL) {
+ dout("iterate_session_caps finishing cap %p removal\n",
+ cap);
+ BUG_ON(cap->session != session);
+ list_del_init(&cap->session_caps);
+ session->s_nr_caps--;
+ cap->session = NULL;
+ old_cap = cap; /* put_cap it w/o locks held */
+ }
+ if (ret < 0)
+ goto out;
+ }
+ ret = 0;
+out:
+ session->s_cap_iterator = NULL;
+ spin_unlock(&session->s_cap_lock);
+
+ if (last_inode)
+ iput(last_inode);
+ if (old_cap)
+ ceph_put_cap(old_cap);
+
+ return ret;
+}
+
+static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
+ void *arg)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ dout("removing cap %p, ci is %p, inode is %p\n",
+ cap, ci, &ci->vfs_inode);
+ ceph_remove_cap(cap);
+ return 0;
+}
+
+/*
+ * caller must hold session s_mutex
+ */
+static void remove_session_caps(struct ceph_mds_session *session)
+{
+ dout("remove_session_caps on %p\n", session);
+ iterate_session_caps(session, remove_session_caps_cb, NULL);
+ BUG_ON(session->s_nr_caps > 0);
+ cleanup_cap_releases(session);
+}
+
+/*
+ * wake up any threads waiting on this session's caps. if the cap is
+ * old (didn't get renewed on the client reconnect), remove it now.
+ *
+ * caller must hold s_mutex.
+ */
+static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
+ void *arg)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ wake_up(&ci->i_cap_wq);
+ if (arg) {
+ spin_lock(&inode->i_lock);
+ ci->i_wanted_max_size = 0;
+ ci->i_requested_max_size = 0;
+ spin_unlock(&inode->i_lock);
+ }
+ return 0;
+}
+
+static void wake_up_session_caps(struct ceph_mds_session *session,
+ int reconnect)
+{
+ dout("wake_up_session_caps %p mds%d\n", session, session->s_mds);
+ iterate_session_caps(session, wake_up_session_cb,
+ (void *)(unsigned long)reconnect);
+}
+
+/*
+ * Send periodic message to MDS renewing all currently held caps. The
+ * ack will reset the expiration for all caps from this session.
+ *
+ * caller holds s_mutex
+ */
+static int send_renew_caps(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session)
+{
+ struct ceph_msg *msg;
+ int state;
+
+ if (time_after_eq(jiffies, session->s_cap_ttl) &&
+ time_after_eq(session->s_cap_ttl, session->s_renew_requested))
+ pr_info("mds%d caps stale\n", session->s_mds);
+ session->s_renew_requested = jiffies;
+
+ /* do not try to renew caps until a recovering mds has reconnected
+ * with its clients. */
+ state = ceph_mdsmap_get_state(mdsc->mdsmap, session->s_mds);
+ if (state < CEPH_MDS_STATE_RECONNECT) {
+ dout("send_renew_caps ignoring mds%d (%s)\n",
+ session->s_mds, ceph_mds_state_name(state));
+ return 0;
+ }
+
+ dout("send_renew_caps to mds%d (%s)\n", session->s_mds,
+ ceph_mds_state_name(state));
+ msg = create_session_msg(CEPH_SESSION_REQUEST_RENEWCAPS,
+ ++session->s_renew_seq);
+ if (IS_ERR(msg))
+ return PTR_ERR(msg);
+ ceph_con_send(&session->s_con, msg);
+ return 0;
+}
+
+/*
+ * Note new cap ttl, and any transition from stale -> not stale (fresh?).
+ *
+ * Called under session->s_mutex
+ */
+static void renewed_caps(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session, int is_renew)
+{
+ int was_stale;
+ int wake = 0;
+
+ spin_lock(&session->s_cap_lock);
+ was_stale = is_renew && (session->s_cap_ttl == 0 ||
+ time_after_eq(jiffies, session->s_cap_ttl));
+
+ session->s_cap_ttl = session->s_renew_requested +
+ mdsc->mdsmap->m_session_timeout*HZ;
+
+ if (was_stale) {
+ if (time_before(jiffies, session->s_cap_ttl)) {
+ pr_info("mds%d caps renewed\n", session->s_mds);
+ wake = 1;
+ } else {
+ pr_info("mds%d caps still stale\n", session->s_mds);
+ }
+ }
+ dout("renewed_caps mds%d ttl now %lu, was %s, now %s\n",
+ session->s_mds, session->s_cap_ttl, was_stale ? "stale" : "fresh",
+ time_before(jiffies, session->s_cap_ttl) ? "stale" : "fresh");
+ spin_unlock(&session->s_cap_lock);
+
+ if (wake)
+ wake_up_session_caps(session, 0);
+}
+
+/*
+ * send a session close request
+ */
+static int request_close_session(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session)
+{
+ struct ceph_msg *msg;
+ int err = 0;
+
+ dout("request_close_session mds%d state %s seq %lld\n",
+ session->s_mds, session_state_name(session->s_state),
+ session->s_seq);
+ msg = create_session_msg(CEPH_SESSION_REQUEST_CLOSE, session->s_seq);
+ if (IS_ERR(msg))
+ err = PTR_ERR(msg);
+ else
+ ceph_con_send(&session->s_con, msg);
+ return err;
+}
+
+/*
+ * Called with s_mutex held.
+ */
+static int __close_session(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session)
+{
+ if (session->s_state >= CEPH_MDS_SESSION_CLOSING)
+ return 0;
+ session->s_state = CEPH_MDS_SESSION_CLOSING;
+ return request_close_session(mdsc, session);
+}
+
+/*
+ * Trim old(er) caps.
+ *
+ * Because we can't cache an inode without one or more caps, we do
+ * this indirectly: if a cap is unused, we prune its aliases, at which
+ * point the inode will hopefully get dropped to.
+ *
+ * Yes, this is a bit sloppy. Our only real goal here is to respond to
+ * memory pressure from the MDS, though, so it needn't be perfect.
+ */
+static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
+{
+ struct ceph_mds_session *session = arg;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int used, oissued, mine;
+
+ if (session->s_trim_caps <= 0)
+ return -1;
+
+ spin_lock(&inode->i_lock);
+ mine = cap->issued | cap->implemented;
+ used = __ceph_caps_used(ci);
+ oissued = __ceph_caps_issued_other(ci, cap);
+
+ dout("trim_caps_cb %p cap %p mine %s oissued %s used %s\n",
+ inode, cap, ceph_cap_string(mine), ceph_cap_string(oissued),
+ ceph_cap_string(used));
+ if (ci->i_dirty_caps)
+ goto out; /* dirty caps */
+ if ((used & ~oissued) & mine)
+ goto out; /* we need these caps */
+
+ session->s_trim_caps--;
+ if (oissued) {
+ /* we aren't the only cap.. just remove us */
+ __ceph_remove_cap(cap);
+ } else {
+ /* try to drop referring dentries */
+ spin_unlock(&inode->i_lock);
+ d_prune_aliases(inode);
+ dout("trim_caps_cb %p cap %p pruned, count now %d\n",
+ inode, cap, atomic_read(&inode->i_count));
+ return 0;
+ }
+
+out:
+ spin_unlock(&inode->i_lock);
+ return 0;
+}
+
+/*
+ * Trim session cap count down to some max number.
+ */
+static int trim_caps(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session,
+ int max_caps)
+{
+ int trim_caps = session->s_nr_caps - max_caps;
+
+ dout("trim_caps mds%d start: %d / %d, trim %d\n",
+ session->s_mds, session->s_nr_caps, max_caps, trim_caps);
+ if (trim_caps > 0) {
+ session->s_trim_caps = trim_caps;
+ iterate_session_caps(session, trim_caps_cb, session);
+ dout("trim_caps mds%d done: %d / %d, trimmed %d\n",
+ session->s_mds, session->s_nr_caps, max_caps,
+ trim_caps - session->s_trim_caps);
+ session->s_trim_caps = 0;
+ }
+ return 0;
+}
+
+/*
+ * Allocate cap_release messages. If there is a partially full message
+ * in the queue, try to allocate enough to cover it's remainder, so that
+ * we can send it immediately.
+ *
+ * Called under s_mutex.
+ */
+static int add_cap_releases(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session,
+ int extra)
+{
+ struct ceph_msg *msg;
+ struct ceph_mds_cap_release *head;
+ int err = -ENOMEM;
+
+ if (extra < 0)
+ extra = mdsc->client->mount_args->cap_release_safety;
+
+ spin_lock(&session->s_cap_lock);
+
+ if (!list_empty(&session->s_cap_releases)) {
+ msg = list_first_entry(&session->s_cap_releases,
+ struct ceph_msg,
+ list_head);
+ head = msg->front.iov_base;
+ extra += CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num);
+ }
+
+ while (session->s_num_cap_releases < session->s_nr_caps + extra) {
+ spin_unlock(&session->s_cap_lock);
+ msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPRELEASE, PAGE_CACHE_SIZE,
+ 0, 0, NULL);
+ if (!msg)
+ goto out_unlocked;
+ dout("add_cap_releases %p msg %p now %d\n", session, msg,
+ (int)msg->front.iov_len);
+ head = msg->front.iov_base;
+ head->num = cpu_to_le32(0);
+ msg->front.iov_len = sizeof(*head);
+ spin_lock(&session->s_cap_lock);
+ list_add(&msg->list_head, &session->s_cap_releases);
+ session->s_num_cap_releases += CEPH_CAPS_PER_RELEASE;
+ }
+
+ if (!list_empty(&session->s_cap_releases)) {
+ msg = list_first_entry(&session->s_cap_releases,
+ struct ceph_msg,
+ list_head);
+ head = msg->front.iov_base;
+ if (head->num) {
+ dout(" queueing non-full %p (%d)\n", msg,
+ le32_to_cpu(head->num));
+ list_move_tail(&msg->list_head,
+ &session->s_cap_releases_done);
+ session->s_num_cap_releases -=
+ CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num);
+ }
+ }
+ err = 0;
+ spin_unlock(&session->s_cap_lock);
+out_unlocked:
+ return err;
+}
+
+/*
+ * flush all dirty inode data to disk.
+ *
+ * returns true if we've flushed through want_flush_seq
+ */
+static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq)
+{
+ int mds, ret = 1;
+
+ dout("check_cap_flush want %lld\n", want_flush_seq);
+ mutex_lock(&mdsc->mutex);
+ for (mds = 0; ret && mds < mdsc->max_sessions; mds++) {
+ struct ceph_mds_session *session = mdsc->sessions[mds];
+
+ if (!session)
+ continue;
+ get_session(session);
+ mutex_unlock(&mdsc->mutex);
+
+ mutex_lock(&session->s_mutex);
+ if (!list_empty(&session->s_cap_flushing)) {
+ struct ceph_inode_info *ci =
+ list_entry(session->s_cap_flushing.next,
+ struct ceph_inode_info,
+ i_flushing_item);
+ struct inode *inode = &ci->vfs_inode;
+
+ spin_lock(&inode->i_lock);
+ if (ci->i_cap_flush_seq <= want_flush_seq) {
+ dout("check_cap_flush still flushing %p "
+ "seq %lld <= %lld to mds%d\n", inode,
+ ci->i_cap_flush_seq, want_flush_seq,
+ session->s_mds);
+ ret = 0;
+ }
+ spin_unlock(&inode->i_lock);
+ }
+ mutex_unlock(&session->s_mutex);
+ ceph_put_mds_session(session);
+
+ if (!ret)
+ return ret;
+ mutex_lock(&mdsc->mutex);
+ }
+
+ mutex_unlock(&mdsc->mutex);
+ dout("check_cap_flush ok, flushed thru %lld\n", want_flush_seq);
+ return ret;
+}
+
+/*
+ * called under s_mutex
+ */
+static void send_cap_releases(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session)
+{
+ struct ceph_msg *msg;
+
+ dout("send_cap_releases mds%d\n", session->s_mds);
+ while (1) {
+ spin_lock(&session->s_cap_lock);
+ if (list_empty(&session->s_cap_releases_done))
+ break;
+ msg = list_first_entry(&session->s_cap_releases_done,
+ struct ceph_msg, list_head);
+ list_del_init(&msg->list_head);
+ spin_unlock(&session->s_cap_lock);
+ msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+ dout("send_cap_releases mds%d %p\n", session->s_mds, msg);
+ ceph_con_send(&session->s_con, msg);
+ }
+ spin_unlock(&session->s_cap_lock);
+}
+
+/*
+ * requests
+ */
+
+/*
+ * Create an mds request.
+ */
+struct ceph_mds_request *
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
+{
+ struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
+
+ if (!req)
+ return ERR_PTR(-ENOMEM);
+
+ req->r_started = jiffies;
+ req->r_resend_mds = -1;
+ INIT_LIST_HEAD(&req->r_unsafe_dir_item);
+ req->r_fmode = -1;
+ kref_init(&req->r_kref);
+ INIT_LIST_HEAD(&req->r_wait);
+ init_completion(&req->r_completion);
+ init_completion(&req->r_safe_completion);
+ INIT_LIST_HEAD(&req->r_unsafe_item);
+
+ req->r_op = op;
+ req->r_direct_mode = mode;
+ return req;
+}
+
+/*
+ * return oldest (lowest) request, tid in request tree, 0 if none.
+ *
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_request *__get_oldest_req(struct ceph_mds_client *mdsc)
+{
+ if (RB_EMPTY_ROOT(&mdsc->request_tree))
+ return NULL;
+ return rb_entry(rb_first(&mdsc->request_tree),
+ struct ceph_mds_request, r_node);
+}
+
+static u64 __get_oldest_tid(struct ceph_mds_client *mdsc)
+{
+ struct ceph_mds_request *req = __get_oldest_req(mdsc);
+
+ if (req)
+ return req->r_tid;
+ return 0;
+}
+
+/*
+ * Build a dentry's path. Allocate on heap; caller must kfree. Based
+ * on build_path_from_dentry in fs/cifs/dir.c.
+ *
+ * If @stop_on_nosnap, generate path relative to the first non-snapped
+ * inode.
+ *
+ * Encode hidden .snap dirs as a double /, i.e.
+ * foo/.snap/bar -> foo//bar
+ */
+char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
+ int stop_on_nosnap)
+{
+ struct dentry *temp;
+ char *path;
+ int len, pos;
+
+ if (dentry == NULL)
+ return ERR_PTR(-EINVAL);
+
+retry:
+ len = 0;
+ for (temp = dentry; !IS_ROOT(temp);) {
+ struct inode *inode = temp->d_inode;
+ if (inode && ceph_snap(inode) == CEPH_SNAPDIR)
+ len++; /* slash only */
+ else if (stop_on_nosnap && inode &&
+ ceph_snap(inode) == CEPH_NOSNAP)
+ break;
+ else
+ len += 1 + temp->d_name.len;
+ temp = temp->d_parent;
+ if (temp == NULL) {
+ pr_err("build_path_dentry corrupt dentry %p\n", dentry);
+ return ERR_PTR(-EINVAL);
+ }
+ }
+ if (len)
+ len--; /* no leading '/' */
+
+ path = kmalloc(len+1, GFP_NOFS);
+ if (path == NULL)
+ return ERR_PTR(-ENOMEM);
+ pos = len;
+ path[pos] = 0; /* trailing null */
+ for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) {
+ struct inode *inode = temp->d_inode;
+
+ if (inode && ceph_snap(inode) == CEPH_SNAPDIR) {
+ dout("build_path_dentry path+%d: %p SNAPDIR\n",
+ pos, temp);
+ } else if (stop_on_nosnap && inode &&
+ ceph_snap(inode) == CEPH_NOSNAP) {
+ break;
+ } else {
+ pos -= temp->d_name.len;
+ if (pos < 0)
+ break;
+ strncpy(path + pos, temp->d_name.name,
+ temp->d_name.len);
+ dout("build_path_dentry path+%d: %p '%.*s'\n",
+ pos, temp, temp->d_name.len, path + pos);
+ }
+ if (pos)
+ path[--pos] = '/';
+ temp = temp->d_parent;
+ if (temp == NULL) {
+ pr_err("build_path_dentry corrupt dentry\n");
+ kfree(path);
+ return ERR_PTR(-EINVAL);
+ }
+ }
+ if (pos != 0) {
+ pr_err("build_path_dentry did not end path lookup where "
+ "expected, namelen is %d, pos is %d\n", len, pos);
+ /* presumably this is only possible if racing with a
+ rename of one of the parent directories (we can not
+ lock the dentries above us to prevent this, but
+ retrying should be harmless) */
+ kfree(path);
+ goto retry;
+ }
+
+ *base = ceph_ino(temp->d_inode);
+ *plen = len;
+ dout("build_path_dentry on %p %d built %llx '%.*s'\n",
+ dentry, atomic_read(&dentry->d_count), *base, len, path);
+ return path;
+}
+
+static int build_dentry_path(struct dentry *dentry,
+ const char **ppath, int *ppathlen, u64 *pino,
+ int *pfreepath)
+{
+ char *path;
+
+ if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) {
+ *pino = ceph_ino(dentry->d_parent->d_inode);
+ *ppath = dentry->d_name.name;
+ *ppathlen = dentry->d_name.len;
+ return 0;
+ }
+ path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+ *ppath = path;
+ *pfreepath = 1;
+ return 0;
+}
+
+static int build_inode_path(struct inode *inode,
+ const char **ppath, int *ppathlen, u64 *pino,
+ int *pfreepath)
+{
+ struct dentry *dentry;
+ char *path;
+
+ if (ceph_snap(inode) == CEPH_NOSNAP) {
+ *pino = ceph_ino(inode);
+ *ppathlen = 0;
+ return 0;
+ }
+ dentry = d_find_alias(inode);
+ path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1);
+ dput(dentry);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+ *ppath = path;
+ *pfreepath = 1;
+ return 0;
+}
+
+/*
+ * request arguments may be specified via an inode *, a dentry *, or
+ * an explicit ino+path.
+ */
+static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry,
+ const char *rpath, u64 rino,
+ const char **ppath, int *pathlen,
+ u64 *ino, int *freepath)
+{
+ int r = 0;
+
+ if (rinode) {
+ r = build_inode_path(rinode, ppath, pathlen, ino, freepath);
+ dout(" inode %p %llx.%llx\n", rinode, ceph_ino(rinode),
+ ceph_snap(rinode));
+ } else if (rdentry) {
+ r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath);
+ dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen,
+ *ppath);
+ } else if (rpath) {
+ *ino = rino;
+ *ppath = rpath;
+ *pathlen = strlen(rpath);
+ dout(" path %.*s\n", *pathlen, rpath);
+ }
+
+ return r;
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req,
+ int mds)
+{
+ struct ceph_msg *msg;
+ struct ceph_mds_request_head *head;
+ const char *path1 = NULL;
+ const char *path2 = NULL;
+ u64 ino1 = 0, ino2 = 0;
+ int pathlen1 = 0, pathlen2 = 0;
+ int freepath1 = 0, freepath2 = 0;
+ int len;
+ u16 releases;
+ void *p, *end;
+ int ret;
+
+ ret = set_request_path_attr(req->r_inode, req->r_dentry,
+ req->r_path1, req->r_ino1.ino,
+ &path1, &pathlen1, &ino1, &freepath1);
+ if (ret < 0) {
+ msg = ERR_PTR(ret);
+ goto out;
+ }
+
+ ret = set_request_path_attr(NULL, req->r_old_dentry,
+ req->r_path2, req->r_ino2.ino,
+ &path2, &pathlen2, &ino2, &freepath2);
+ if (ret < 0) {
+ msg = ERR_PTR(ret);
+ goto out_free1;
+ }
+
+ len = sizeof(*head) +
+ pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64));
+
+ /* calculate (max) length for cap releases */
+ len += sizeof(struct ceph_mds_request_release) *
+ (!!req->r_inode_drop + !!req->r_dentry_drop +
+ !!req->r_old_inode_drop + !!req->r_old_dentry_drop);
+ if (req->r_dentry_drop)
+ len += req->r_dentry->d_name.len;
+ if (req->r_old_dentry_drop)
+ len += req->r_old_dentry->d_name.len;
+
+ msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, 0, 0, NULL);
+ if (IS_ERR(msg))
+ goto out_free2;
+
+ msg->hdr.tid = cpu_to_le64(req->r_tid);
+
+ head = msg->front.iov_base;
+ p = msg->front.iov_base + sizeof(*head);
+ end = msg->front.iov_base + msg->front.iov_len;
+
+ head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch);
+ head->op = cpu_to_le32(req->r_op);
+ head->caller_uid = cpu_to_le32(current_fsuid());
+ head->caller_gid = cpu_to_le32(current_fsgid());
+ head->args = req->r_args;
+
+ ceph_encode_filepath(&p, end, ino1, path1);
+ ceph_encode_filepath(&p, end, ino2, path2);
+
+ /* cap releases */
+ releases = 0;
+ if (req->r_inode_drop)
+ releases += ceph_encode_inode_release(&p,
+ req->r_inode ? req->r_inode : req->r_dentry->d_inode,
+ mds, req->r_inode_drop, req->r_inode_unless, 0);
+ if (req->r_dentry_drop)
+ releases += ceph_encode_dentry_release(&p, req->r_dentry,
+ mds, req->r_dentry_drop, req->r_dentry_unless);
+ if (req->r_old_dentry_drop)
+ releases += ceph_encode_dentry_release(&p, req->r_old_dentry,
+ mds, req->r_old_dentry_drop, req->r_old_dentry_unless);
+ if (req->r_old_inode_drop)
+ releases += ceph_encode_inode_release(&p,
+ req->r_old_dentry->d_inode,
+ mds, req->r_old_inode_drop, req->r_old_inode_unless, 0);
+ head->num_releases = cpu_to_le16(releases);
+
+ BUG_ON(p > end);
+ msg->front.iov_len = p - msg->front.iov_base;
+ msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+
+ msg->pages = req->r_pages;
+ msg->nr_pages = req->r_num_pages;
+ msg->hdr.data_len = cpu_to_le32(req->r_data_len);
+ msg->hdr.data_off = cpu_to_le16(0);
+
+out_free2:
+ if (freepath2)
+ kfree((char *)path2);
+out_free1:
+ if (freepath1)
+ kfree((char *)path1);
+out:
+ return msg;
+}
+
+/*
+ * called under mdsc->mutex if error, under no mutex if
+ * success.
+ */
+static void complete_request(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req)
+{
+ if (req->r_callback)
+ req->r_callback(mdsc, req);
+ else
+ complete(&req->r_completion);
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static int __prepare_send_request(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req,
+ int mds)
+{
+ struct ceph_mds_request_head *rhead;
+ struct ceph_msg *msg;
+ int flags = 0;
+
+ req->r_mds = mds;
+ req->r_attempts++;
+ dout("prepare_send_request %p tid %lld %s (attempt %d)\n", req,
+ req->r_tid, ceph_mds_op_name(req->r_op), req->r_attempts);
+
+ if (req->r_request) {
+ ceph_msg_put(req->r_request);
+ req->r_request = NULL;
+ }
+ msg = create_request_message(mdsc, req, mds);
+ if (IS_ERR(msg)) {
+ req->r_reply = ERR_PTR(PTR_ERR(msg));
+ complete_request(mdsc, req);
+ return -PTR_ERR(msg);
+ }
+ req->r_request = msg;
+
+ rhead = msg->front.iov_base;
+ rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc));
+ if (req->r_got_unsafe)
+ flags |= CEPH_MDS_FLAG_REPLAY;
+ if (req->r_locked_dir)
+ flags |= CEPH_MDS_FLAG_WANT_DENTRY;
+ rhead->flags = cpu_to_le32(flags);
+ rhead->num_fwd = req->r_num_fwd;
+ rhead->num_retry = req->r_attempts - 1;
+
+ dout(" r_locked_dir = %p\n", req->r_locked_dir);
+
+ if (req->r_target_inode && req->r_got_unsafe)
+ rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode));
+ else
+ rhead->ino = 0;
+ return 0;
+}
+
+/*
+ * send request, or put it on the appropriate wait list.
+ */
+static int __do_request(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req)
+{
+ struct ceph_mds_session *session = NULL;
+ int mds = -1;
+ int err = -EAGAIN;
+
+ if (req->r_reply)
+ goto out;
+
+ if (req->r_timeout &&
+ time_after_eq(jiffies, req->r_started + req->r_timeout)) {
+ dout("do_request timed out\n");
+ err = -EIO;
+ goto finish;
+ }
+
+ mds = __choose_mds(mdsc, req);
+ if (mds < 0 ||
+ ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
+ dout("do_request no mds or not active, waiting for map\n");
+ list_add(&req->r_wait, &mdsc->waiting_for_map);
+ goto out;
+ }
+
+ /* get, open session */
+ session = __ceph_lookup_mds_session(mdsc, mds);
+ if (!session) {
+ session = register_session(mdsc, mds);
+ if (IS_ERR(session)) {
+ err = PTR_ERR(session);
+ goto finish;
+ }
+ }
+ dout("do_request mds%d session %p state %s\n", mds, session,
+ session_state_name(session->s_state));
+ if (session->s_state != CEPH_MDS_SESSION_OPEN &&
+ session->s_state != CEPH_MDS_SESSION_HUNG) {
+ if (session->s_state == CEPH_MDS_SESSION_NEW ||
+ session->s_state == CEPH_MDS_SESSION_CLOSING)
+ __open_session(mdsc, session);
+ list_add(&req->r_wait, &session->s_waiting);
+ goto out_session;
+ }
+
+ /* send request */
+ req->r_session = get_session(session);
+ req->r_resend_mds = -1; /* forget any previous mds hint */
+
+ if (req->r_request_started == 0) /* note request start time */
+ req->r_request_started = jiffies;
+
+ err = __prepare_send_request(mdsc, req, mds);
+ if (!err) {
+ ceph_msg_get(req->r_request);
+ ceph_con_send(&session->s_con, req->r_request);
+ }
+
+out_session:
+ ceph_put_mds_session(session);
+out:
+ return err;
+
+finish:
+ req->r_reply = ERR_PTR(err);
+ complete_request(mdsc, req);
+ goto out;
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static void __wake_requests(struct ceph_mds_client *mdsc,
+ struct list_head *head)
+{
+ struct ceph_mds_request *req, *nreq;
+
+ list_for_each_entry_safe(req, nreq, head, r_wait) {
+ list_del_init(&req->r_wait);
+ __do_request(mdsc, req);
+ }
+}
+
+/*
+ * Wake up threads with requests pending for @mds, so that they can
+ * resubmit their requests to a possibly different mds. If @all is set,
+ * wake up if their requests has been forwarded to @mds, too.
+ */
+static void kick_requests(struct ceph_mds_client *mdsc, int mds, int all)
+{
+ struct ceph_mds_request *req;
+ struct rb_node *p;
+
+ dout("kick_requests mds%d\n", mds);
+ for (p = rb_first(&mdsc->request_tree); p; p = rb_next(p)) {
+ req = rb_entry(p, struct ceph_mds_request, r_node);
+ if (req->r_got_unsafe)
+ continue;
+ if (req->r_session &&
+ req->r_session->s_mds == mds) {
+ dout(" kicking tid %llu\n", req->r_tid);
+ put_request_session(req);
+ __do_request(mdsc, req);
+ }
+ }
+}
+
+void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req)
+{
+ dout("submit_request on %p\n", req);
+ mutex_lock(&mdsc->mutex);
+ __register_request(mdsc, req, NULL);
+ __do_request(mdsc, req);
+ mutex_unlock(&mdsc->mutex);
+}
+
+/*
+ * Synchrously perform an mds request. Take care of all of the
+ * session setup, forwarding, retry details.
+ */
+int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
+ struct inode *dir,
+ struct ceph_mds_request *req)
+{
+ int err;
+
+ dout("do_request on %p\n", req);
+
+ /* take CAP_PIN refs for r_inode, r_locked_dir, r_old_dentry */
+ if (req->r_inode)
+ ceph_get_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
+ if (req->r_locked_dir)
+ ceph_get_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN);
+ if (req->r_old_dentry)
+ ceph_get_cap_refs(
+ ceph_inode(req->r_old_dentry->d_parent->d_inode),
+ CEPH_CAP_PIN);
+
+ /* issue */
+ mutex_lock(&mdsc->mutex);
+ __register_request(mdsc, req, dir);
+ __do_request(mdsc, req);
+
+ /* wait */
+ if (!req->r_reply) {
+ mutex_unlock(&mdsc->mutex);
+ if (req->r_timeout) {
+ err = (long)wait_for_completion_interruptible_timeout(
+ &req->r_completion, req->r_timeout);
+ if (err == 0)
+ req->r_reply = ERR_PTR(-EIO);
+ else if (err < 0)
+ req->r_reply = ERR_PTR(err);
+ } else {
+ err = wait_for_completion_interruptible(
+ &req->r_completion);
+ if (err)
+ req->r_reply = ERR_PTR(err);
+ }
+ mutex_lock(&mdsc->mutex);
+ }
+
+ if (IS_ERR(req->r_reply)) {
+ err = PTR_ERR(req->r_reply);
+ req->r_reply = NULL;
+
+ if (err == -ERESTARTSYS) {
+ /* aborted */
+ req->r_aborted = true;
+
+ if (req->r_locked_dir &&
+ (req->r_op & CEPH_MDS_OP_WRITE)) {
+ struct ceph_inode_info *ci =
+ ceph_inode(req->r_locked_dir);
+
+ dout("aborted, clearing I_COMPLETE on %p\n",
+ req->r_locked_dir);
+ spin_lock(&req->r_locked_dir->i_lock);
+ ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+ ci->i_release_count++;
+ spin_unlock(&req->r_locked_dir->i_lock);
+ }
+ } else {
+ /* clean up this request */
+ __unregister_request(mdsc, req);
+ if (!list_empty(&req->r_unsafe_item))
+ list_del_init(&req->r_unsafe_item);
+ complete(&req->r_safe_completion);
+ }
+ } else if (req->r_err) {
+ err = req->r_err;
+ } else {
+ err = le32_to_cpu(req->r_reply_info.head->result);
+ }
+ mutex_unlock(&mdsc->mutex);
+
+ dout("do_request %p done, result %d\n", req, err);
+ return err;
+}
+
+/*
+ * Handle mds reply.
+ *
+ * We take the session mutex and parse and process the reply immediately.
+ * This preserves the logical ordering of replies, capabilities, etc., sent
+ * by the MDS as they are applied to our local cache.
+ */
+static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
+{
+ struct ceph_mds_client *mdsc = session->s_mdsc;
+ struct ceph_mds_request *req;
+ struct ceph_mds_reply_head *head = msg->front.iov_base;
+ struct ceph_mds_reply_info_parsed *rinfo; /* parsed reply info */
+ u64 tid;
+ int err, result;
+ int mds = session->s_mds;
+
+ if (msg->front.iov_len < sizeof(*head)) {
+ pr_err("mdsc_handle_reply got corrupt (short) reply\n");
+ ceph_msg_dump(msg);
+ return;
+ }
+
+ /* get request, session */
+ tid = le64_to_cpu(msg->hdr.tid);
+ mutex_lock(&mdsc->mutex);
+ req = __lookup_request(mdsc, tid);
+ if (!req) {
+ dout("handle_reply on unknown tid %llu\n", tid);
+ mutex_unlock(&mdsc->mutex);
+ return;
+ }
+ dout("handle_reply %p\n", req);
+
+ /* correct session? */
+ if (req->r_session != session) {
+ pr_err("mdsc_handle_reply got %llu on session mds%d"
+ " not mds%d\n", tid, session->s_mds,
+ req->r_session ? req->r_session->s_mds : -1);
+ mutex_unlock(&mdsc->mutex);
+ goto out;
+ }
+
+ /* dup? */
+ if ((req->r_got_unsafe && !head->safe) ||
+ (req->r_got_safe && head->safe)) {
+ pr_warning("got a dup %s reply on %llu from mds%d\n",
+ head->safe ? "safe" : "unsafe", tid, mds);
+ mutex_unlock(&mdsc->mutex);
+ goto out;
+ }
+
+ result = le32_to_cpu(head->result);
+
+ /*
+ * Tolerate 2 consecutive ESTALEs from the same mds.
+ * FIXME: we should be looking at the cap migrate_seq.
+ */
+ if (result == -ESTALE) {
+ req->r_direct_mode = USE_AUTH_MDS;
+ req->r_num_stale++;
+ if (req->r_num_stale <= 2) {
+ __do_request(mdsc, req);
+ mutex_unlock(&mdsc->mutex);
+ goto out;
+ }
+ } else {
+ req->r_num_stale = 0;
+ }
+
+ if (head->safe) {
+ req->r_got_safe = true;
+ __unregister_request(mdsc, req);
+ complete(&req->r_safe_completion);
+
+ if (req->r_got_unsafe) {
+ /*
+ * We already handled the unsafe response, now do the
+ * cleanup. No need to examine the response; the MDS
+ * doesn't include any result info in the safe
+ * response. And even if it did, there is nothing
+ * useful we could do with a revised return value.
+ */
+ dout("got safe reply %llu, mds%d\n", tid, mds);
+ list_del_init(&req->r_unsafe_item);
+
+ /* last unsafe request during umount? */
+ if (mdsc->stopping && !__get_oldest_req(mdsc))
+ complete(&mdsc->safe_umount_waiters);
+ mutex_unlock(&mdsc->mutex);
+ goto out;
+ }
+ }
+
+ BUG_ON(req->r_reply);
+
+ if (!head->safe) {
+ req->r_got_unsafe = true;
+ list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe);
+ }
+
+ dout("handle_reply tid %lld result %d\n", tid, result);
+ rinfo = &req->r_reply_info;
+ err = parse_reply_info(msg, rinfo);
+ mutex_unlock(&mdsc->mutex);
+
+ mutex_lock(&session->s_mutex);
+ if (err < 0) {
+ pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds);
+ ceph_msg_dump(msg);
+ goto out_err;
+ }
+
+ /* snap trace */
+ if (rinfo->snapblob_len) {
+ down_write(&mdsc->snap_rwsem);
+ ceph_update_snap_trace(mdsc, rinfo->snapblob,
+ rinfo->snapblob + rinfo->snapblob_len,
+ le32_to_cpu(head->op) == CEPH_MDS_OP_RMSNAP);
+ downgrade_write(&mdsc->snap_rwsem);
+ } else {
+ down_read(&mdsc->snap_rwsem);
+ }
+
+ /* insert trace into our cache */
+ err = ceph_fill_trace(mdsc->client->sb, req, req->r_session);
+ if (err == 0) {
+ if (result == 0 && rinfo->dir_nr)
+ ceph_readdir_prepopulate(req, req->r_session);
+ ceph_unreserve_caps(&req->r_caps_reservation);
+ }
+
+ up_read(&mdsc->snap_rwsem);
+out_err:
+ if (err) {
+ req->r_err = err;
+ } else {
+ req->r_reply = msg;
+ ceph_msg_get(msg);
+ }
+
+ add_cap_releases(mdsc, req->r_session, -1);
+ mutex_unlock(&session->s_mutex);
+
+ /* kick calling process */
+ complete_request(mdsc, req);
+out:
+ ceph_mdsc_put_request(req);
+ return;
+}
+
+
+
+/*
+ * handle mds notification that our request has been forwarded.
+ */
+static void handle_forward(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session,
+ struct ceph_msg *msg)
+{
+ struct ceph_mds_request *req;
+ u64 tid = le64_to_cpu(msg->hdr.tid);
+ u32 next_mds;
+ u32 fwd_seq;
+ int err = -EINVAL;
+ void *p = msg->front.iov_base;
+ void *end = p + msg->front.iov_len;
+
+ ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+ next_mds = ceph_decode_32(&p);
+ fwd_seq = ceph_decode_32(&p);
+
+ mutex_lock(&mdsc->mutex);
+ req = __lookup_request(mdsc, tid);
+ if (!req) {
+ dout("forward %llu to mds%d - req dne\n", tid, next_mds);
+ goto out; /* dup reply? */
+ }
+
+ if (fwd_seq <= req->r_num_fwd) {
+ dout("forward %llu to mds%d - old seq %d <= %d\n",
+ tid, next_mds, req->r_num_fwd, fwd_seq);
+ } else {
+ /* resend. forward race not possible; mds would drop */
+ dout("forward %llu to mds%d (we resend)\n", tid, next_mds);
+ req->r_num_fwd = fwd_seq;
+ req->r_resend_mds = next_mds;
+ put_request_session(req);
+ __do_request(mdsc, req);
+ }
+ ceph_mdsc_put_request(req);
+out:
+ mutex_unlock(&mdsc->mutex);
+ return;
+
+bad:
+ pr_err("mdsc_handle_forward decode error err=%d\n", err);
+}
+
+/*
+ * handle a mds session control message
+ */
+static void handle_session(struct ceph_mds_session *session,
+ struct ceph_msg *msg)
+{
+ struct ceph_mds_client *mdsc = session->s_mdsc;
+ u32 op;
+ u64 seq;
+ int mds = session->s_mds;
+ struct ceph_mds_session_head *h = msg->front.iov_base;
+ int wake = 0;
+
+ /* decode */
+ if (msg->front.iov_len != sizeof(*h))
+ goto bad;
+ op = le32_to_cpu(h->op);
+ seq = le64_to_cpu(h->seq);
+
+ mutex_lock(&mdsc->mutex);
+ if (op == CEPH_SESSION_CLOSE)
+ __unregister_session(mdsc, session);
+ /* FIXME: this ttl calculation is generous */
+ session->s_ttl = jiffies + HZ*mdsc->mdsmap->m_session_autoclose;
+ mutex_unlock(&mdsc->mutex);
+
+ mutex_lock(&session->s_mutex);
+
+ dout("handle_session mds%d %s %p state %s seq %llu\n",
+ mds, ceph_session_op_name(op), session,
+ session_state_name(session->s_state), seq);
+
+ if (session->s_state == CEPH_MDS_SESSION_HUNG) {
+ session->s_state = CEPH_MDS_SESSION_OPEN;
+ pr_info("mds%d came back\n", session->s_mds);
+ }
+
+ switch (op) {
+ case CEPH_SESSION_OPEN:
+ session->s_state = CEPH_MDS_SESSION_OPEN;
+ renewed_caps(mdsc, session, 0);
+ wake = 1;
+ if (mdsc->stopping)
+ __close_session(mdsc, session);
+ break;
+
+ case CEPH_SESSION_RENEWCAPS:
+ if (session->s_renew_seq == seq)
+ renewed_caps(mdsc, session, 1);
+ break;
+
+ case CEPH_SESSION_CLOSE:
+ remove_session_caps(session);
+ wake = 1; /* for good measure */
+ complete(&mdsc->session_close_waiters);
+ kick_requests(mdsc, mds, 0); /* cur only */
+ break;
+
+ case CEPH_SESSION_STALE:
+ pr_info("mds%d caps went stale, renewing\n",
+ session->s_mds);
+ spin_lock(&session->s_cap_lock);
+ session->s_cap_gen++;
+ session->s_cap_ttl = 0;
+ spin_unlock(&session->s_cap_lock);
+ send_renew_caps(mdsc, session);
+ break;
+
+ case CEPH_SESSION_RECALL_STATE:
+ trim_caps(mdsc, session, le32_to_cpu(h->max_caps));
+ break;
+
+ default:
+ pr_err("mdsc_handle_session bad op %d mds%d\n", op, mds);
+ WARN_ON(1);
+ }
+
+ mutex_unlock(&session->s_mutex);
+ if (wake) {
+ mutex_lock(&mdsc->mutex);
+ __wake_requests(mdsc, &session->s_waiting);
+ mutex_unlock(&mdsc->mutex);
+ }
+ return;
+
+bad:
+ pr_err("mdsc_handle_session corrupt message mds%d len %d\n", mds,
+ (int)msg->front.iov_len);
+ ceph_msg_dump(msg);
+ return;
+}
+
+
+/*
+ * called under session->mutex.
+ */
+static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session)
+{
+ struct ceph_mds_request *req, *nreq;
+ int err;
+
+ dout("replay_unsafe_requests mds%d\n", session->s_mds);
+
+ mutex_lock(&mdsc->mutex);
+ list_for_each_entry_safe(req, nreq, &session->s_unsafe, r_unsafe_item) {
+ err = __prepare_send_request(mdsc, req, session->s_mds);
+ if (!err) {
+ ceph_msg_get(req->r_request);
+ ceph_con_send(&session->s_con, req->r_request);
+ }
+ }
+ mutex_unlock(&mdsc->mutex);
+}
+
+/*
+ * Encode information about a cap for a reconnect with the MDS.
+ */
+static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
+ void *arg)
+{
+ struct ceph_mds_cap_reconnect rec;
+ struct ceph_inode_info *ci;
+ struct ceph_pagelist *pagelist = arg;
+ char *path;
+ int pathlen, err;
+ u64 pathbase;
+ struct dentry *dentry;
+
+ ci = cap->ci;
+
+ dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
+ inode, ceph_vinop(inode), cap, cap->cap_id,
+ ceph_cap_string(cap->issued));
+ err = ceph_pagelist_encode_64(pagelist, ceph_ino(inode));
+ if (err)
+ return err;
+
+ dentry = d_find_alias(inode);
+ if (dentry) {
+ path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, 0);
+ if (IS_ERR(path)) {
+ err = PTR_ERR(path);
+ BUG_ON(err);
+ }
+ } else {
+ path = NULL;
+ pathlen = 0;
+ }
+ err = ceph_pagelist_encode_string(pagelist, path, pathlen);
+ if (err)
+ goto out;
+
+ spin_lock(&inode->i_lock);
+ cap->seq = 0; /* reset cap seq */
+ cap->issue_seq = 0; /* and issue_seq */
+ rec.cap_id = cpu_to_le64(cap->cap_id);
+ rec.pathbase = cpu_to_le64(pathbase);
+ rec.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
+ rec.issued = cpu_to_le32(cap->issued);
+ rec.size = cpu_to_le64(inode->i_size);
+ ceph_encode_timespec(&rec.mtime, &inode->i_mtime);
+ ceph_encode_timespec(&rec.atime, &inode->i_atime);
+ rec.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
+ spin_unlock(&inode->i_lock);
+
+ err = ceph_pagelist_append(pagelist, &rec, sizeof(rec));
+
+out:
+ kfree(path);
+ dput(dentry);
+ return err;
+}
+
+
+/*
+ * If an MDS fails and recovers, clients need to reconnect in order to
+ * reestablish shared state. This includes all caps issued through
+ * this session _and_ the snap_realm hierarchy. Because it's not
+ * clear which snap realms the mds cares about, we send everything we
+ * know about.. that ensures we'll then get any new info the
+ * recovering MDS might have.
+ *
+ * This is a relatively heavyweight operation, but it's rare.
+ *
+ * called with mdsc->mutex held.
+ */
+static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
+{
+ struct ceph_mds_session *session = NULL;
+ struct ceph_msg *reply;
+ struct rb_node *p;
+ int err;
+ struct ceph_pagelist *pagelist;
+
+ pr_info("reconnect to recovering mds%d\n", mds);
+
+ pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+ if (!pagelist)
+ goto fail_nopagelist;
+ ceph_pagelist_init(pagelist);
+
+ reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, 0, 0, NULL);
+ if (IS_ERR(reply)) {
+ err = PTR_ERR(reply);
+ goto fail_nomsg;
+ }
+
+ /* find session */
+ session = __ceph_lookup_mds_session(mdsc, mds);
+ mutex_unlock(&mdsc->mutex); /* drop lock for duration */
+
+ if (session) {
+ mutex_lock(&session->s_mutex);
+
+ session->s_state = CEPH_MDS_SESSION_RECONNECTING;
+ session->s_seq = 0;
+
+ ceph_con_open(&session->s_con,
+ ceph_mdsmap_get_addr(mdsc->mdsmap, mds));
+
+ /* replay unsafe requests */
+ replay_unsafe_requests(mdsc, session);
+ } else {
+ dout("no session for mds%d, will send short reconnect\n",
+ mds);
+ }
+
+ down_read(&mdsc->snap_rwsem);
+
+ if (!session)
+ goto send;
+ dout("session %p state %s\n", session,
+ session_state_name(session->s_state));
+
+ /* traverse this session's caps */
+ err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps);
+ if (err)
+ goto fail;
+ err = iterate_session_caps(session, encode_caps_cb, pagelist);
+ if (err < 0)
+ goto out;
+
+ /*
+ * snaprealms. we provide mds with the ino, seq (version), and
+ * parent for all of our realms. If the mds has any newer info,
+ * it will tell us.
+ */
+ for (p = rb_first(&mdsc->snap_realms); p; p = rb_next(p)) {
+ struct ceph_snap_realm *realm =
+ rb_entry(p, struct ceph_snap_realm, node);
+ struct ceph_mds_snaprealm_reconnect sr_rec;
+
+ dout(" adding snap realm %llx seq %lld parent %llx\n",
+ realm->ino, realm->seq, realm->parent_ino);
+ sr_rec.ino = cpu_to_le64(realm->ino);
+ sr_rec.seq = cpu_to_le64(realm->seq);
+ sr_rec.parent = cpu_to_le64(realm->parent_ino);
+ err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec));
+ if (err)
+ goto fail;
+ }
+
+send:
+ reply->pagelist = pagelist;
+ reply->hdr.data_len = cpu_to_le32(pagelist->length);
+ reply->nr_pages = calc_pages_for(0, pagelist->length);
+ ceph_con_send(&session->s_con, reply);
+
+ if (session) {
+ session->s_state = CEPH_MDS_SESSION_OPEN;
+ __wake_requests(mdsc, &session->s_waiting);
+ }
+
+out:
+ up_read(&mdsc->snap_rwsem);
+ if (session) {
+ mutex_unlock(&session->s_mutex);
+ ceph_put_mds_session(session);
+ }
+ mutex_lock(&mdsc->mutex);
+ return;
+
+fail:
+ ceph_msg_put(reply);
+fail_nomsg:
+ ceph_pagelist_release(pagelist);
+ kfree(pagelist);
+fail_nopagelist:
+ pr_err("ENOMEM preparing reconnect for mds%d\n", mds);
+ goto out;
+}
+
+
+/*
+ * compare old and new mdsmaps, kicking requests
+ * and closing out old connections as necessary
+ *
+ * called under mdsc->mutex.
+ */
+static void check_new_map(struct ceph_mds_client *mdsc,
+ struct ceph_mdsmap *newmap,
+ struct ceph_mdsmap *oldmap)
+{
+ int i;
+ int oldstate, newstate;
+ struct ceph_mds_session *s;
+
+ dout("check_new_map new %u old %u\n",
+ newmap->m_epoch, oldmap->m_epoch);
+
+ for (i = 0; i < oldmap->m_max_mds && i < mdsc->max_sessions; i++) {
+ if (mdsc->sessions[i] == NULL)
+ continue;
+ s = mdsc->sessions[i];
+ oldstate = ceph_mdsmap_get_state(oldmap, i);
+ newstate = ceph_mdsmap_get_state(newmap, i);
+
+ dout("check_new_map mds%d state %s -> %s (session %s)\n",
+ i, ceph_mds_state_name(oldstate),
+ ceph_mds_state_name(newstate),
+ session_state_name(s->s_state));
+
+ if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
+ ceph_mdsmap_get_addr(newmap, i),
+ sizeof(struct ceph_entity_addr))) {
+ if (s->s_state == CEPH_MDS_SESSION_OPENING) {
+ /* the session never opened, just close it
+ * out now */
+ __wake_requests(mdsc, &s->s_waiting);
+ __unregister_session(mdsc, s);
+ } else {
+ /* just close it */
+ mutex_unlock(&mdsc->mutex);
+ mutex_lock(&s->s_mutex);
+ mutex_lock(&mdsc->mutex);
+ ceph_con_close(&s->s_con);
+ mutex_unlock(&s->s_mutex);
+ s->s_state = CEPH_MDS_SESSION_RESTARTING;
+ }
+
+ /* kick any requests waiting on the recovering mds */
+ kick_requests(mdsc, i, 1);
+ } else if (oldstate == newstate) {
+ continue; /* nothing new with this mds */
+ }
+
+ /*
+ * send reconnect?
+ */
+ if (s->s_state == CEPH_MDS_SESSION_RESTARTING &&
+ newstate >= CEPH_MDS_STATE_RECONNECT)
+ send_mds_reconnect(mdsc, i);
+
+ /*
+ * kick requests on any mds that has gone active.
+ *
+ * kick requests on cur or forwarder: we may have sent
+ * the request to mds1, mds1 told us it forwarded it
+ * to mds2, but then we learn mds1 failed and can't be
+ * sure it successfully forwarded our request before
+ * it died.
+ */
+ if (oldstate < CEPH_MDS_STATE_ACTIVE &&
+ newstate >= CEPH_MDS_STATE_ACTIVE) {
+ pr_info("mds%d reconnect completed\n", s->s_mds);
+ kick_requests(mdsc, i, 1);
+ ceph_kick_flushing_caps(mdsc, s);
+ wake_up_session_caps(s, 1);
+ }
+ }
+}
+
+
+
+/*
+ * leases
+ */
+
+/*
+ * caller must hold session s_mutex, dentry->d_lock
+ */
+void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry)
+{
+ struct ceph_dentry_info *di = ceph_dentry(dentry);
+
+ ceph_put_mds_session(di->lease_session);
+ di->lease_session = NULL;
+}
+
+static void handle_lease(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session,
+ struct ceph_msg *msg)
+{
+ struct super_block *sb = mdsc->client->sb;
+ struct inode *inode;
+ struct ceph_inode_info *ci;
+ struct dentry *parent, *dentry;
+ struct ceph_dentry_info *di;
+ int mds = session->s_mds;
+ struct ceph_mds_lease *h = msg->front.iov_base;
+ struct ceph_vino vino;
+ int mask;
+ struct qstr dname;
+ int release = 0;
+
+ dout("handle_lease from mds%d\n", mds);
+
+ /* decode */
+ if (msg->front.iov_len < sizeof(*h) + sizeof(u32))
+ goto bad;
+ vino.ino = le64_to_cpu(h->ino);
+ vino.snap = CEPH_NOSNAP;
+ mask = le16_to_cpu(h->mask);
+ dname.name = (void *)h + sizeof(*h) + sizeof(u32);
+ dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32);
+ if (dname.len != get_unaligned_le32(h+1))
+ goto bad;
+
+ mutex_lock(&session->s_mutex);
+ session->s_seq++;
+
+ /* lookup inode */
+ inode = ceph_find_inode(sb, vino);
+ dout("handle_lease '%s', mask %d, ino %llx %p\n",
+ ceph_lease_op_name(h->action), mask, vino.ino, inode);
+ if (inode == NULL) {
+ dout("handle_lease no inode %llx\n", vino.ino);
+ goto release;
+ }
+ ci = ceph_inode(inode);
+
+ /* dentry */
+ parent = d_find_alias(inode);
+ if (!parent) {
+ dout("no parent dentry on inode %p\n", inode);
+ WARN_ON(1);
+ goto release; /* hrm... */
+ }
+ dname.hash = full_name_hash(dname.name, dname.len);
+ dentry = d_lookup(parent, &dname);
+ dput(parent);
+ if (!dentry)
+ goto release;
+
+ spin_lock(&dentry->d_lock);
+ di = ceph_dentry(dentry);
+ switch (h->action) {
+ case CEPH_MDS_LEASE_REVOKE:
+ if (di && di->lease_session == session) {
+ h->seq = cpu_to_le32(di->lease_seq);
+ __ceph_mdsc_drop_dentry_lease(dentry);
+ }
+ release = 1;
+ break;
+
+ case CEPH_MDS_LEASE_RENEW:
+ if (di && di->lease_session == session &&
+ di->lease_gen == session->s_cap_gen &&
+ di->lease_renew_from &&
+ di->lease_renew_after == 0) {
+ unsigned long duration =
+ le32_to_cpu(h->duration_ms) * HZ / 1000;
+
+ di->lease_seq = le32_to_cpu(h->seq);
+ dentry->d_time = di->lease_renew_from + duration;
+ di->lease_renew_after = di->lease_renew_from +
+ (duration >> 1);
+ di->lease_renew_from = 0;
+ }
+ break;
+ }
+ spin_unlock(&dentry->d_lock);
+ dput(dentry);
+
+ if (!release)
+ goto out;
+
+release:
+ /* let's just reuse the same message */
+ h->action = CEPH_MDS_LEASE_REVOKE_ACK;
+ ceph_msg_get(msg);
+ ceph_con_send(&session->s_con, msg);
+
+out:
+ iput(inode);
+ mutex_unlock(&session->s_mutex);
+ return;
+
+bad:
+ pr_err("corrupt lease message\n");
+ ceph_msg_dump(msg);
+}
+
+void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
+ struct inode *inode,
+ struct dentry *dentry, char action,
+ u32 seq)
+{
+ struct ceph_msg *msg;
+ struct ceph_mds_lease *lease;
+ int len = sizeof(*lease) + sizeof(u32);
+ int dnamelen = 0;
+
+ dout("lease_send_msg inode %p dentry %p %s to mds%d\n",
+ inode, dentry, ceph_lease_op_name(action), session->s_mds);
+ dnamelen = dentry->d_name.len;
+ len += dnamelen;
+
+ msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, 0, 0, NULL);
+ if (IS_ERR(msg))
+ return;
+ lease = msg->front.iov_base;
+ lease->action = action;
+ lease->mask = cpu_to_le16(CEPH_LOCK_DN);
+ lease->ino = cpu_to_le64(ceph_vino(inode).ino);
+ lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap);
+ lease->seq = cpu_to_le32(seq);
+ put_unaligned_le32(dnamelen, lease + 1);
+ memcpy((void *)(lease + 1) + 4, dentry->d_name.name, dnamelen);
+
+ /*
+ * if this is a preemptive lease RELEASE, no need to
+ * flush request stream, since the actual request will
+ * soon follow.
+ */
+ msg->more_to_follow = (action == CEPH_MDS_LEASE_RELEASE);
+
+ ceph_con_send(&session->s_con, msg);
+}
+
+/*
+ * Preemptively release a lease we expect to invalidate anyway.
+ * Pass @inode always, @dentry is optional.
+ */
+void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode,
+ struct dentry *dentry, int mask)
+{
+ struct ceph_dentry_info *di;
+ struct ceph_mds_session *session;
+ u32 seq;
+
+ BUG_ON(inode == NULL);
+ BUG_ON(dentry == NULL);
+ BUG_ON(mask != CEPH_LOCK_DN);
+
+ /* is dentry lease valid? */
+ spin_lock(&dentry->d_lock);
+ di = ceph_dentry(dentry);
+ if (!di || !di->lease_session ||
+ di->lease_session->s_mds < 0 ||
+ di->lease_gen != di->lease_session->s_cap_gen ||
+ !time_before(jiffies, dentry->d_time)) {
+ dout("lease_release inode %p dentry %p -- "
+ "no lease on %d\n",
+ inode, dentry, mask);
+ spin_unlock(&dentry->d_lock);
+ return;
+ }
+
+ /* we do have a lease on this dentry; note mds and seq */
+ session = ceph_get_mds_session(di->lease_session);
+ seq = di->lease_seq;
+ __ceph_mdsc_drop_dentry_lease(dentry);
+ spin_unlock(&dentry->d_lock);
+
+ dout("lease_release inode %p dentry %p mask %d to mds%d\n",
+ inode, dentry, mask, session->s_mds);
+ ceph_mdsc_lease_send_msg(session, inode, dentry,
+ CEPH_MDS_LEASE_RELEASE, seq);
+ ceph_put_mds_session(session);
+}
+
+/*
+ * drop all leases (and dentry refs) in preparation for umount
+ */
+static void drop_leases(struct ceph_mds_client *mdsc)
+{
+ int i;
+
+ dout("drop_leases\n");
+ mutex_lock(&mdsc->mutex);
+ for (i = 0; i < mdsc->max_sessions; i++) {
+ struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i);
+ if (!s)
+ continue;
+ mutex_unlock(&mdsc->mutex);
+ mutex_lock(&s->s_mutex);
+ mutex_unlock(&s->s_mutex);
+ ceph_put_mds_session(s);
+ mutex_lock(&mdsc->mutex);
+ }
+ mutex_unlock(&mdsc->mutex);
+}
+
+
+
+/*
+ * delayed work -- periodically trim expired leases, renew caps with mds
+ */
+static void schedule_delayed(struct ceph_mds_client *mdsc)
+{
+ int delay = 5;
+ unsigned hz = round_jiffies_relative(HZ * delay);
+ schedule_delayed_work(&mdsc->delayed_work, hz);
+}
+
+static void delayed_work(struct work_struct *work)
+{
+ int i;
+ struct ceph_mds_client *mdsc =
+ container_of(work, struct ceph_mds_client, delayed_work.work);
+ int renew_interval;
+ int renew_caps;
+
+ dout("mdsc delayed_work\n");
+ ceph_check_delayed_caps(mdsc);
+
+ mutex_lock(&mdsc->mutex);
+ renew_interval = mdsc->mdsmap->m_session_timeout >> 2;
+ renew_caps = time_after_eq(jiffies, HZ*renew_interval +
+ mdsc->last_renew_caps);
+ if (renew_caps)
+ mdsc->last_renew_caps = jiffies;
+
+ for (i = 0; i < mdsc->max_sessions; i++) {
+ struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i);
+ if (s == NULL)
+ continue;
+ if (s->s_state == CEPH_MDS_SESSION_CLOSING) {
+ dout("resending session close request for mds%d\n",
+ s->s_mds);
+ request_close_session(mdsc, s);
+ ceph_put_mds_session(s);
+ continue;
+ }
+ if (s->s_ttl && time_after(jiffies, s->s_ttl)) {
+ if (s->s_state == CEPH_MDS_SESSION_OPEN) {
+ s->s_state = CEPH_MDS_SESSION_HUNG;
+ pr_info("mds%d hung\n", s->s_mds);
+ }
+ }
+ if (s->s_state < CEPH_MDS_SESSION_OPEN) {
+ /* this mds is failed or recovering, just wait */
+ ceph_put_mds_session(s);
+ continue;
+ }
+ mutex_unlock(&mdsc->mutex);
+
+ mutex_lock(&s->s_mutex);
+ if (renew_caps)
+ send_renew_caps(mdsc, s);
+ else
+ ceph_con_keepalive(&s->s_con);
+ add_cap_releases(mdsc, s, -1);
+ send_cap_releases(mdsc, s);
+ mutex_unlock(&s->s_mutex);
+ ceph_put_mds_session(s);
+
+ mutex_lock(&mdsc->mutex);
+ }
+ mutex_unlock(&mdsc->mutex);
+
+ schedule_delayed(mdsc);
+}
+
+
+int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client)
+{
+ mdsc->client = client;
+ mutex_init(&mdsc->mutex);
+ mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS);
+ init_completion(&mdsc->safe_umount_waiters);
+ init_completion(&mdsc->session_close_waiters);
+ INIT_LIST_HEAD(&mdsc->waiting_for_map);
+ mdsc->sessions = NULL;
+ mdsc->max_sessions = 0;
+ mdsc->stopping = 0;
+ init_rwsem(&mdsc->snap_rwsem);
+ mdsc->snap_realms = RB_ROOT;
+ INIT_LIST_HEAD(&mdsc->snap_empty);
+ spin_lock_init(&mdsc->snap_empty_lock);
+ mdsc->last_tid = 0;
+ mdsc->request_tree = RB_ROOT;
+ INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work);
+ mdsc->last_renew_caps = jiffies;
+ INIT_LIST_HEAD(&mdsc->cap_delay_list);
+ spin_lock_init(&mdsc->cap_delay_lock);
+ INIT_LIST_HEAD(&mdsc->snap_flush_list);
+ spin_lock_init(&mdsc->snap_flush_lock);
+ mdsc->cap_flush_seq = 0;
+ INIT_LIST_HEAD(&mdsc->cap_dirty);
+ mdsc->num_cap_flushing = 0;
+ spin_lock_init(&mdsc->cap_dirty_lock);
+ init_waitqueue_head(&mdsc->cap_flushing_wq);
+ spin_lock_init(&mdsc->dentry_lru_lock);
+ INIT_LIST_HEAD(&mdsc->dentry_lru);
+ return 0;
+}
+
+/*
+ * Wait for safe replies on open mds requests. If we time out, drop
+ * all requests from the tree to avoid dangling dentry refs.
+ */
+static void wait_requests(struct ceph_mds_client *mdsc)
+{
+ struct ceph_mds_request *req;
+ struct ceph_client *client = mdsc->client;
+
+ mutex_lock(&mdsc->mutex);
+ if (__get_oldest_req(mdsc)) {
+ mutex_unlock(&mdsc->mutex);
+
+ dout("wait_requests waiting for requests\n");
+ wait_for_completion_timeout(&mdsc->safe_umount_waiters,
+ client->mount_args->mount_timeout * HZ);
+
+ /* tear down remaining requests */
+ mutex_lock(&mdsc->mutex);
+ while ((req = __get_oldest_req(mdsc))) {
+ dout("wait_requests timed out on tid %llu\n",
+ req->r_tid);
+ __unregister_request(mdsc, req);
+ }
+ }
+ mutex_unlock(&mdsc->mutex);
+ dout("wait_requests done\n");
+}
+
+/*
+ * called before mount is ro, and before dentries are torn down.
+ * (hmm, does this still race with new lookups?)
+ */
+void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc)
+{
+ dout("pre_umount\n");
+ mdsc->stopping = 1;
+
+ drop_leases(mdsc);
+ ceph_flush_dirty_caps(mdsc);
+ wait_requests(mdsc);
+}
+
+/*
+ * wait for all write mds requests to flush.
+ */
+static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid)
+{
+ struct ceph_mds_request *req = NULL, *nextreq;
+ struct rb_node *n;
+
+ mutex_lock(&mdsc->mutex);
+ dout("wait_unsafe_requests want %lld\n", want_tid);
+restart:
+ req = __get_oldest_req(mdsc);
+ while (req && req->r_tid <= want_tid) {
+ /* find next request */
+ n = rb_next(&req->r_node);
+ if (n)
+ nextreq = rb_entry(n, struct ceph_mds_request, r_node);
+ else
+ nextreq = NULL;
+ if ((req->r_op & CEPH_MDS_OP_WRITE)) {
+ /* write op */
+ ceph_mdsc_get_request(req);
+ if (nextreq)
+ ceph_mdsc_get_request(nextreq);
+ mutex_unlock(&mdsc->mutex);
+ dout("wait_unsafe_requests wait on %llu (want %llu)\n",
+ req->r_tid, want_tid);
+ wait_for_completion(&req->r_safe_completion);
+ mutex_lock(&mdsc->mutex);
+ ceph_mdsc_put_request(req);
+ if (!nextreq)
+ break; /* next dne before, so we're done! */
+ if (RB_EMPTY_NODE(&nextreq->r_node)) {
+ /* next request was removed from tree */
+ ceph_mdsc_put_request(nextreq);
+ goto restart;
+ }
+ ceph_mdsc_put_request(nextreq); /* won't go away */
+ }
+ req = nextreq;
+ }
+ mutex_unlock(&mdsc->mutex);
+ dout("wait_unsafe_requests done\n");
+}
+
+void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
+{
+ u64 want_tid, want_flush;
+
+ dout("sync\n");
+ mutex_lock(&mdsc->mutex);
+ want_tid = mdsc->last_tid;
+ want_flush = mdsc->cap_flush_seq;
+ mutex_unlock(&mdsc->mutex);
+ dout("sync want tid %lld flush_seq %lld\n", want_tid, want_flush);
+
+ ceph_flush_dirty_caps(mdsc);
+
+ wait_unsafe_requests(mdsc, want_tid);
+ wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush));
+}
+
+
+/*
+ * called after sb is ro.
+ */
+void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
+{
+ struct ceph_mds_session *session;
+ int i;
+ int n;
+ struct ceph_client *client = mdsc->client;
+ unsigned long started, timeout = client->mount_args->mount_timeout * HZ;
+
+ dout("close_sessions\n");
+
+ mutex_lock(&mdsc->mutex);
+
+ /* close sessions */
+ started = jiffies;
+ while (time_before(jiffies, started + timeout)) {
+ dout("closing sessions\n");
+ n = 0;
+ for (i = 0; i < mdsc->max_sessions; i++) {
+ session = __ceph_lookup_mds_session(mdsc, i);
+ if (!session)
+ continue;
+ mutex_unlock(&mdsc->mutex);
+ mutex_lock(&session->s_mutex);
+ __close_session(mdsc, session);
+ mutex_unlock(&session->s_mutex);
+ ceph_put_mds_session(session);
+ mutex_lock(&mdsc->mutex);
+ n++;
+ }
+ if (n == 0)
+ break;
+
+ if (client->mount_state == CEPH_MOUNT_SHUTDOWN)
+ break;
+
+ dout("waiting for sessions to close\n");
+ mutex_unlock(&mdsc->mutex);
+ wait_for_completion_timeout(&mdsc->session_close_waiters,
+ timeout);
+ mutex_lock(&mdsc->mutex);
+ }
+
+ /* tear down remaining sessions */
+ for (i = 0; i < mdsc->max_sessions; i++) {
+ if (mdsc->sessions[i]) {
+ session = get_session(mdsc->sessions[i]);
+ __unregister_session(mdsc, session);
+ mutex_unlock(&mdsc->mutex);
+ mutex_lock(&session->s_mutex);
+ remove_session_caps(session);
+ mutex_unlock(&session->s_mutex);
+ ceph_put_mds_session(session);
+ mutex_lock(&mdsc->mutex);
+ }
+ }
+
+ WARN_ON(!list_empty(&mdsc->cap_delay_list));
+
+ mutex_unlock(&mdsc->mutex);
+
+ ceph_cleanup_empty_realms(mdsc);
+
+ cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */
+
+ dout("stopped\n");
+}
+
+void ceph_mdsc_stop(struct ceph_mds_client *mdsc)
+{
+ dout("stop\n");
+ cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */
+ if (mdsc->mdsmap)
+ ceph_mdsmap_destroy(mdsc->mdsmap);
+ kfree(mdsc->sessions);
+}
+
+
+/*
+ * handle mds map update.
+ */
+void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
+{
+ u32 epoch;
+ u32 maplen;
+ void *p = msg->front.iov_base;
+ void *end = p + msg->front.iov_len;
+ struct ceph_mdsmap *newmap, *oldmap;
+ struct ceph_fsid fsid;
+ int err = -EINVAL;
+
+ ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad);
+ ceph_decode_copy(&p, &fsid, sizeof(fsid));
+ if (ceph_check_fsid(mdsc->client, &fsid) < 0)
+ return;
+ epoch = ceph_decode_32(&p);
+ maplen = ceph_decode_32(&p);
+ dout("handle_map epoch %u len %d\n", epoch, (int)maplen);
+
+ /* do we need it? */
+ ceph_monc_got_mdsmap(&mdsc->client->monc, epoch);
+ mutex_lock(&mdsc->mutex);
+ if (mdsc->mdsmap && epoch <= mdsc->mdsmap->m_epoch) {
+ dout("handle_map epoch %u <= our %u\n",
+ epoch, mdsc->mdsmap->m_epoch);
+ mutex_unlock(&mdsc->mutex);
+ return;
+ }
+
+ newmap = ceph_mdsmap_decode(&p, end);
+ if (IS_ERR(newmap)) {
+ err = PTR_ERR(newmap);
+ goto bad_unlock;
+ }
+
+ /* swap into place */
+ if (mdsc->mdsmap) {
+ oldmap = mdsc->mdsmap;
+ mdsc->mdsmap = newmap;
+ check_new_map(mdsc, newmap, oldmap);
+ ceph_mdsmap_destroy(oldmap);
+ } else {
+ mdsc->mdsmap = newmap; /* first mds map */
+ }
+ mdsc->client->sb->s_maxbytes = mdsc->mdsmap->m_max_file_size;
+
+ __wake_requests(mdsc, &mdsc->waiting_for_map);
+
+ mutex_unlock(&mdsc->mutex);
+ schedule_delayed(mdsc);
+ return;
+
+bad_unlock:
+ mutex_unlock(&mdsc->mutex);
+bad:
+ pr_err("error decoding mdsmap %d\n", err);
+ return;
+}
+
+static struct ceph_connection *con_get(struct ceph_connection *con)
+{
+ struct ceph_mds_session *s = con->private;
+
+ if (get_session(s)) {
+ dout("mdsc con_get %p ok (%d)\n", s, atomic_read(&s->s_ref));
+ return con;
+ }
+ dout("mdsc con_get %p FAIL\n", s);
+ return NULL;
+}
+
+static void con_put(struct ceph_connection *con)
+{
+ struct ceph_mds_session *s = con->private;
+
+ ceph_put_mds_session(s);
+ dout("mdsc con_put %p (%d)\n", s, atomic_read(&s->s_ref));
+}
+
+/*
+ * if the client is unresponsive for long enough, the mds will kill
+ * the session entirely.
+ */
+static void peer_reset(struct ceph_connection *con)
+{
+ struct ceph_mds_session *s = con->private;
+
+ pr_err("mds%d gave us the boot. IMPLEMENT RECONNECT.\n",
+ s->s_mds);
+}
+
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+ struct ceph_mds_session *s = con->private;
+ struct ceph_mds_client *mdsc = s->s_mdsc;
+ int type = le16_to_cpu(msg->hdr.type);
+
+ mutex_lock(&mdsc->mutex);
+ if (__verify_registered_session(mdsc, s) < 0) {
+ mutex_unlock(&mdsc->mutex);
+ goto out;
+ }
+ mutex_unlock(&mdsc->mutex);
+
+ switch (type) {
+ case CEPH_MSG_MDS_MAP:
+ ceph_mdsc_handle_map(mdsc, msg);
+ break;
+ case CEPH_MSG_CLIENT_SESSION:
+ handle_session(s, msg);
+ break;
+ case CEPH_MSG_CLIENT_REPLY:
+ handle_reply(s, msg);
+ break;
+ case CEPH_MSG_CLIENT_REQUEST_FORWARD:
+ handle_forward(mdsc, s, msg);
+ break;
+ case CEPH_MSG_CLIENT_CAPS:
+ ceph_handle_caps(s, msg);
+ break;
+ case CEPH_MSG_CLIENT_SNAP:
+ ceph_handle_snap(mdsc, s, msg);
+ break;
+ case CEPH_MSG_CLIENT_LEASE:
+ handle_lease(mdsc, s, msg);
+ break;
+
+ default:
+ pr_err("received unknown message type %d %s\n", type,
+ ceph_msg_type_name(type));
+ }
+out:
+ ceph_msg_put(msg);
+}
+
+/*
+ * authentication
+ */
+static int get_authorizer(struct ceph_connection *con,
+ void **buf, int *len, int *proto,
+ void **reply_buf, int *reply_len, int force_new)
+{
+ struct ceph_mds_session *s = con->private;
+ struct ceph_mds_client *mdsc = s->s_mdsc;
+ struct ceph_auth_client *ac = mdsc->client->monc.auth;
+ int ret = 0;
+
+ if (force_new && s->s_authorizer) {
+ ac->ops->destroy_authorizer(ac, s->s_authorizer);
+ s->s_authorizer = NULL;
+ }
+ if (s->s_authorizer == NULL) {
+ if (ac->ops->create_authorizer) {
+ ret = ac->ops->create_authorizer(
+ ac, CEPH_ENTITY_TYPE_MDS,
+ &s->s_authorizer,
+ &s->s_authorizer_buf,
+ &s->s_authorizer_buf_len,
+ &s->s_authorizer_reply_buf,
+ &s->s_authorizer_reply_buf_len);
+ if (ret)
+ return ret;
+ }
+ }
+
+ *proto = ac->protocol;
+ *buf = s->s_authorizer_buf;
+ *len = s->s_authorizer_buf_len;
+ *reply_buf = s->s_authorizer_reply_buf;
+ *reply_len = s->s_authorizer_reply_buf_len;
+ return 0;
+}
+
+
+static int verify_authorizer_reply(struct ceph_connection *con, int len)
+{
+ struct ceph_mds_session *s = con->private;
+ struct ceph_mds_client *mdsc = s->s_mdsc;
+ struct ceph_auth_client *ac = mdsc->client->monc.auth;
+
+ return ac->ops->verify_authorizer_reply(ac, s->s_authorizer, len);
+}
+
+static int invalidate_authorizer(struct ceph_connection *con)
+{
+ struct ceph_mds_session *s = con->private;
+ struct ceph_mds_client *mdsc = s->s_mdsc;
+ struct ceph_auth_client *ac = mdsc->client->monc.auth;
+
+ if (ac->ops->invalidate_authorizer)
+ ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS);
+
+ return ceph_monc_validate_auth(&mdsc->client->monc);
+}
+
+const static struct ceph_connection_operations mds_con_ops = {
+ .get = con_get,
+ .put = con_put,
+ .dispatch = dispatch,
+ .get_authorizer = get_authorizer,
+ .verify_authorizer_reply = verify_authorizer_reply,
+ .invalidate_authorizer = invalidate_authorizer,
+ .peer_reset = peer_reset,
+};
+
+
+
+
+/* eof */
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
new file mode 100644
index 00000000000..961cc6f6587
--- /dev/null
+++ b/fs/ceph/mds_client.h
@@ -0,0 +1,335 @@
+#ifndef _FS_CEPH_MDS_CLIENT_H
+#define _FS_CEPH_MDS_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/rbtree.h>
+#include <linux/spinlock.h>
+
+#include "types.h"
+#include "messenger.h"
+#include "mdsmap.h"
+
+/*
+ * Some lock dependencies:
+ *
+ * session->s_mutex
+ * mdsc->mutex
+ *
+ * mdsc->snap_rwsem
+ *
+ * inode->i_lock
+ * mdsc->snap_flush_lock
+ * mdsc->cap_delay_lock
+ *
+ */
+
+struct ceph_client;
+struct ceph_cap;
+
+/*
+ * parsed info about a single inode. pointers are into the encoded
+ * on-wire structures within the mds reply message payload.
+ */
+struct ceph_mds_reply_info_in {
+ struct ceph_mds_reply_inode *in;
+ u32 symlink_len;
+ char *symlink;
+ u32 xattr_len;
+ char *xattr_data;
+};
+
+/*
+ * parsed info about an mds reply, including information about the
+ * target inode and/or its parent directory and dentry, and directory
+ * contents (for readdir results).
+ */
+struct ceph_mds_reply_info_parsed {
+ struct ceph_mds_reply_head *head;
+
+ struct ceph_mds_reply_info_in diri, targeti;
+ struct ceph_mds_reply_dirfrag *dirfrag;
+ char *dname;
+ u32 dname_len;
+ struct ceph_mds_reply_lease *dlease;
+
+ struct ceph_mds_reply_dirfrag *dir_dir;
+ int dir_nr;
+ char **dir_dname;
+ u32 *dir_dname_len;
+ struct ceph_mds_reply_lease **dir_dlease;
+ struct ceph_mds_reply_info_in *dir_in;
+ u8 dir_complete, dir_end;
+
+ /* encoded blob describing snapshot contexts for certain
+ operations (e.g., open) */
+ void *snapblob;
+ int snapblob_len;
+};
+
+
+/*
+ * cap releases are batched and sent to the MDS en masse.
+ */
+#define CEPH_CAPS_PER_RELEASE ((PAGE_CACHE_SIZE - \
+ sizeof(struct ceph_mds_cap_release)) / \
+ sizeof(struct ceph_mds_cap_item))
+
+
+/*
+ * state associated with each MDS<->client session
+ */
+enum {
+ CEPH_MDS_SESSION_NEW = 1,
+ CEPH_MDS_SESSION_OPENING = 2,
+ CEPH_MDS_SESSION_OPEN = 3,
+ CEPH_MDS_SESSION_HUNG = 4,
+ CEPH_MDS_SESSION_CLOSING = 5,
+ CEPH_MDS_SESSION_RESTARTING = 6,
+ CEPH_MDS_SESSION_RECONNECTING = 7,
+};
+
+struct ceph_mds_session {
+ struct ceph_mds_client *s_mdsc;
+ int s_mds;
+ int s_state;
+ unsigned long s_ttl; /* time until mds kills us */
+ u64 s_seq; /* incoming msg seq # */
+ struct mutex s_mutex; /* serialize session messages */
+
+ struct ceph_connection s_con;
+
+ struct ceph_authorizer *s_authorizer;
+ void *s_authorizer_buf, *s_authorizer_reply_buf;
+ size_t s_authorizer_buf_len, s_authorizer_reply_buf_len;
+
+ /* protected by s_cap_lock */
+ spinlock_t s_cap_lock;
+ u32 s_cap_gen; /* inc each time we get mds stale msg */
+ unsigned long s_cap_ttl; /* when session caps expire */
+ struct list_head s_caps; /* all caps issued by this session */
+ int s_nr_caps, s_trim_caps;
+ int s_num_cap_releases;
+ struct list_head s_cap_releases; /* waiting cap_release messages */
+ struct list_head s_cap_releases_done; /* ready to send */
+ struct ceph_cap *s_cap_iterator;
+
+ /* protected by mutex */
+ struct list_head s_cap_flushing; /* inodes w/ flushing caps */
+ struct list_head s_cap_snaps_flushing;
+ unsigned long s_renew_requested; /* last time we sent a renew req */
+ u64 s_renew_seq;
+
+ atomic_t s_ref;
+ struct list_head s_waiting; /* waiting requests */
+ struct list_head s_unsafe; /* unsafe requests */
+};
+
+/*
+ * modes of choosing which MDS to send a request to
+ */
+enum {
+ USE_ANY_MDS,
+ USE_RANDOM_MDS,
+ USE_AUTH_MDS, /* prefer authoritative mds for this metadata item */
+};
+
+struct ceph_mds_request;
+struct ceph_mds_client;
+
+/*
+ * request completion callback
+ */
+typedef void (*ceph_mds_request_callback_t) (struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req);
+
+/*
+ * an in-flight mds request
+ */
+struct ceph_mds_request {
+ u64 r_tid; /* transaction id */
+ struct rb_node r_node;
+
+ int r_op; /* mds op code */
+ int r_mds;
+
+ /* operation on what? */
+ struct inode *r_inode; /* arg1 */
+ struct dentry *r_dentry; /* arg1 */
+ struct dentry *r_old_dentry; /* arg2: rename from or link from */
+ char *r_path1, *r_path2;
+ struct ceph_vino r_ino1, r_ino2;
+
+ struct inode *r_locked_dir; /* dir (if any) i_mutex locked by vfs */
+ struct inode *r_target_inode; /* resulting inode */
+
+ union ceph_mds_request_args r_args;
+ int r_fmode; /* file mode, if expecting cap */
+
+ /* for choosing which mds to send this request to */
+ int r_direct_mode;
+ u32 r_direct_hash; /* choose dir frag based on this dentry hash */
+ bool r_direct_is_hash; /* true if r_direct_hash is valid */
+
+ /* data payload is used for xattr ops */
+ struct page **r_pages;
+ int r_num_pages;
+ int r_data_len;
+
+ /* what caps shall we drop? */
+ int r_inode_drop, r_inode_unless;
+ int r_dentry_drop, r_dentry_unless;
+ int r_old_dentry_drop, r_old_dentry_unless;
+ struct inode *r_old_inode;
+ int r_old_inode_drop, r_old_inode_unless;
+
+ struct ceph_msg *r_request; /* original request */
+ struct ceph_msg *r_reply;
+ struct ceph_mds_reply_info_parsed r_reply_info;
+ int r_err;
+ bool r_aborted;
+
+ unsigned long r_timeout; /* optional. jiffies */
+ unsigned long r_started; /* start time to measure timeout against */
+ unsigned long r_request_started; /* start time for mds request only,
+ used to measure lease durations */
+
+ /* link unsafe requests to parent directory, for fsync */
+ struct inode *r_unsafe_dir;
+ struct list_head r_unsafe_dir_item;
+
+ struct ceph_mds_session *r_session;
+
+ int r_attempts; /* resend attempts */
+ int r_num_fwd; /* number of forward attempts */
+ int r_num_stale;
+ int r_resend_mds; /* mds to resend to next, if any*/
+
+ struct kref r_kref;
+ struct list_head r_wait;
+ struct completion r_completion;
+ struct completion r_safe_completion;
+ ceph_mds_request_callback_t r_callback;
+ struct list_head r_unsafe_item; /* per-session unsafe list item */
+ bool r_got_unsafe, r_got_safe;
+
+ bool r_did_prepopulate;
+ u32 r_readdir_offset;
+
+ struct ceph_cap_reservation r_caps_reservation;
+ int r_num_caps;
+};
+
+/*
+ * mds client state
+ */
+struct ceph_mds_client {
+ struct ceph_client *client;
+ struct mutex mutex; /* all nested structures */
+
+ struct ceph_mdsmap *mdsmap;
+ struct completion safe_umount_waiters, session_close_waiters;
+ struct list_head waiting_for_map;
+
+ struct ceph_mds_session **sessions; /* NULL for mds if no session */
+ int max_sessions; /* len of s_mds_sessions */
+ int stopping; /* true if shutting down */
+
+ /*
+ * snap_rwsem will cover cap linkage into snaprealms, and
+ * realm snap contexts. (later, we can do per-realm snap
+ * contexts locks..) the empty list contains realms with no
+ * references (implying they contain no inodes with caps) that
+ * should be destroyed.
+ */
+ struct rw_semaphore snap_rwsem;
+ struct rb_root snap_realms;
+ struct list_head snap_empty;
+ spinlock_t snap_empty_lock; /* protect snap_empty */
+
+ u64 last_tid; /* most recent mds request */
+ struct rb_root request_tree; /* pending mds requests */
+ struct delayed_work delayed_work; /* delayed work */
+ unsigned long last_renew_caps; /* last time we renewed our caps */
+ struct list_head cap_delay_list; /* caps with delayed release */
+ spinlock_t cap_delay_lock; /* protects cap_delay_list */
+ struct list_head snap_flush_list; /* cap_snaps ready to flush */
+ spinlock_t snap_flush_lock;
+
+ u64 cap_flush_seq;
+ struct list_head cap_dirty; /* inodes with dirty caps */
+ int num_cap_flushing; /* # caps we are flushing */
+ spinlock_t cap_dirty_lock; /* protects above items */
+ wait_queue_head_t cap_flushing_wq;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_file;
+#endif
+
+ spinlock_t dentry_lru_lock;
+ struct list_head dentry_lru;
+ int num_dentry;
+};
+
+extern const char *ceph_mds_op_name(int op);
+
+extern struct ceph_mds_session *
+__ceph_lookup_mds_session(struct ceph_mds_client *, int mds);
+
+static inline struct ceph_mds_session *
+ceph_get_mds_session(struct ceph_mds_session *s)
+{
+ atomic_inc(&s->s_ref);
+ return s;
+}
+
+extern void ceph_put_mds_session(struct ceph_mds_session *s);
+
+extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,
+ struct ceph_msg *msg, int mds);
+
+extern int ceph_mdsc_init(struct ceph_mds_client *mdsc,
+ struct ceph_client *client);
+extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc);
+extern void ceph_mdsc_stop(struct ceph_mds_client *mdsc);
+
+extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc);
+
+extern void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc,
+ struct inode *inode,
+ struct dentry *dn, int mask);
+
+extern struct ceph_mds_request *
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode);
+extern void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
+ struct ceph_mds_request *req);
+extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
+ struct inode *dir,
+ struct ceph_mds_request *req);
+static inline void ceph_mdsc_get_request(struct ceph_mds_request *req)
+{
+ kref_get(&req->r_kref);
+}
+extern void ceph_mdsc_release_request(struct kref *kref);
+static inline void ceph_mdsc_put_request(struct ceph_mds_request *req)
+{
+ kref_put(&req->r_kref, ceph_mdsc_release_request);
+}
+
+extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
+
+extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
+ int stop_on_nosnap);
+
+extern void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry);
+extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
+ struct inode *inode,
+ struct dentry *dentry, char action,
+ u32 seq);
+
+extern void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc,
+ struct ceph_msg *msg);
+
+#endif
diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c
new file mode 100644
index 00000000000..c4c498e6dfe
--- /dev/null
+++ b/fs/ceph/mdsmap.c
@@ -0,0 +1,174 @@
+#include "ceph_debug.h"
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "mdsmap.h"
+#include "messenger.h"
+#include "decode.h"
+
+#include "super.h"
+
+
+/*
+ * choose a random mds that is "up" (i.e. has a state > 0), or -1.
+ */
+int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
+{
+ int n = 0;
+ int i;
+ char r;
+
+ /* count */
+ for (i = 0; i < m->m_max_mds; i++)
+ if (m->m_info[i].state > 0)
+ n++;
+ if (n == 0)
+ return -1;
+
+ /* pick */
+ get_random_bytes(&r, 1);
+ n = r % n;
+ i = 0;
+ for (i = 0; n > 0; i++, n--)
+ while (m->m_info[i].state <= 0)
+ i++;
+
+ return i;
+}
+
+/*
+ * Decode an MDS map
+ *
+ * Ignore any fields we don't care about (there are quite a few of
+ * them).
+ */
+struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
+{
+ struct ceph_mdsmap *m;
+ const void *start = *p;
+ int i, j, n;
+ int err = -EINVAL;
+ u16 version;
+
+ m = kzalloc(sizeof(*m), GFP_NOFS);
+ if (m == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ ceph_decode_16_safe(p, end, version, bad);
+
+ ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad);
+ m->m_epoch = ceph_decode_32(p);
+ m->m_client_epoch = ceph_decode_32(p);
+ m->m_last_failure = ceph_decode_32(p);
+ m->m_root = ceph_decode_32(p);
+ m->m_session_timeout = ceph_decode_32(p);
+ m->m_session_autoclose = ceph_decode_32(p);
+ m->m_max_file_size = ceph_decode_64(p);
+ m->m_max_mds = ceph_decode_32(p);
+
+ m->m_info = kcalloc(m->m_max_mds, sizeof(*m->m_info), GFP_NOFS);
+ if (m->m_info == NULL)
+ goto badmem;
+
+ /* pick out active nodes from mds_info (state > 0) */
+ n = ceph_decode_32(p);
+ for (i = 0; i < n; i++) {
+ u64 global_id;
+ u32 namelen;
+ s32 mds, inc, state;
+ u64 state_seq;
+ u8 infoversion;
+ struct ceph_entity_addr addr;
+ u32 num_export_targets;
+ void *pexport_targets = NULL;
+
+ ceph_decode_need(p, end, sizeof(u64)*2 + 1 + sizeof(u32), bad);
+ global_id = ceph_decode_64(p);
+ infoversion = ceph_decode_8(p);
+ *p += sizeof(u64);
+ namelen = ceph_decode_32(p); /* skip mds name */
+ *p += namelen;
+
+ ceph_decode_need(p, end,
+ 4*sizeof(u32) + sizeof(u64) +
+ sizeof(addr) + sizeof(struct ceph_timespec),
+ bad);
+ mds = ceph_decode_32(p);
+ inc = ceph_decode_32(p);
+ state = ceph_decode_32(p);
+ state_seq = ceph_decode_64(p);
+ ceph_decode_copy(p, &addr, sizeof(addr));
+ ceph_decode_addr(&addr);
+ *p += sizeof(struct ceph_timespec);
+ *p += sizeof(u32);
+ ceph_decode_32_safe(p, end, namelen, bad);
+ *p += namelen;
+ if (infoversion >= 2) {
+ ceph_decode_32_safe(p, end, num_export_targets, bad);
+ pexport_targets = *p;
+ *p += num_export_targets * sizeof(u32);
+ } else {
+ num_export_targets = 0;
+ }
+
+ dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n",
+ i+1, n, global_id, mds, inc, pr_addr(&addr.in_addr),
+ ceph_mds_state_name(state));
+ if (mds >= 0 && mds < m->m_max_mds && state > 0) {
+ m->m_info[mds].global_id = global_id;
+ m->m_info[mds].state = state;
+ m->m_info[mds].addr = addr;
+ m->m_info[mds].num_export_targets = num_export_targets;
+ if (num_export_targets) {
+ m->m_info[mds].export_targets =
+ kcalloc(num_export_targets, sizeof(u32),
+ GFP_NOFS);
+ for (j = 0; j < num_export_targets; j++)
+ m->m_info[mds].export_targets[j] =
+ ceph_decode_32(&pexport_targets);
+ } else {
+ m->m_info[mds].export_targets = NULL;
+ }
+ }
+ }
+
+ /* pg_pools */
+ ceph_decode_32_safe(p, end, n, bad);
+ m->m_num_data_pg_pools = n;
+ m->m_data_pg_pools = kcalloc(n, sizeof(u32), GFP_NOFS);
+ if (!m->m_data_pg_pools)
+ goto badmem;
+ ceph_decode_need(p, end, sizeof(u32)*(n+1), bad);
+ for (i = 0; i < n; i++)
+ m->m_data_pg_pools[i] = ceph_decode_32(p);
+ m->m_cas_pg_pool = ceph_decode_32(p);
+
+ /* ok, we don't care about the rest. */
+ dout("mdsmap_decode success epoch %u\n", m->m_epoch);
+ return m;
+
+badmem:
+ err = -ENOMEM;
+bad:
+ pr_err("corrupt mdsmap\n");
+ print_hex_dump(KERN_DEBUG, "mdsmap: ",
+ DUMP_PREFIX_OFFSET, 16, 1,
+ start, end - start, true);
+ ceph_mdsmap_destroy(m);
+ return ERR_PTR(-EINVAL);
+}
+
+void ceph_mdsmap_destroy(struct ceph_mdsmap *m)
+{
+ int i;
+
+ for (i = 0; i < m->m_max_mds; i++)
+ kfree(m->m_info[i].export_targets);
+ kfree(m->m_info);
+ kfree(m->m_data_pg_pools);
+ kfree(m);
+}
diff --git a/fs/ceph/mdsmap.h b/fs/ceph/mdsmap.h
new file mode 100644
index 00000000000..eacc131aa5c
--- /dev/null
+++ b/fs/ceph/mdsmap.h
@@ -0,0 +1,54 @@
+#ifndef _FS_CEPH_MDSMAP_H
+#define _FS_CEPH_MDSMAP_H
+
+#include "types.h"
+
+/*
+ * mds map - describe servers in the mds cluster.
+ *
+ * we limit fields to those the client actually xcares about
+ */
+struct ceph_mds_info {
+ u64 global_id;
+ struct ceph_entity_addr addr;
+ s32 state;
+ int num_export_targets;
+ u32 *export_targets;
+};
+
+struct ceph_mdsmap {
+ u32 m_epoch, m_client_epoch, m_last_failure;
+ u32 m_root;
+ u32 m_session_timeout; /* seconds */
+ u32 m_session_autoclose; /* seconds */
+ u64 m_max_file_size;
+ u32 m_max_mds; /* size of m_addr, m_state arrays */
+ struct ceph_mds_info *m_info;
+
+ /* which object pools file data can be stored in */
+ int m_num_data_pg_pools;
+ u32 *m_data_pg_pools;
+ u32 m_cas_pg_pool;
+};
+
+static inline struct ceph_entity_addr *
+ceph_mdsmap_get_addr(struct ceph_mdsmap *m, int w)
+{
+ if (w >= m->m_max_mds)
+ return NULL;
+ return &m->m_info[w].addr;
+}
+
+static inline int ceph_mdsmap_get_state(struct ceph_mdsmap *m, int w)
+{
+ BUG_ON(w < 0);
+ if (w >= m->m_max_mds)
+ return CEPH_MDS_STATE_DNE;
+ return m->m_info[w].state;
+}
+
+extern int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m);
+extern struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end);
+extern void ceph_mdsmap_destroy(struct ceph_mdsmap *m);
+
+#endif
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c
new file mode 100644
index 00000000000..cdaaa131add
--- /dev/null
+++ b/fs/ceph/messenger.c
@@ -0,0 +1,2249 @@
+#include "ceph_debug.h"
+
+#include <linux/crc32c.h>
+#include <linux/ctype.h>
+#include <linux/highmem.h>
+#include <linux/inet.h>
+#include <linux/kthread.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+#include <linux/string.h>
+#include <net/tcp.h>
+
+#include "super.h"
+#include "messenger.h"
+#include "decode.h"
+#include "pagelist.h"
+
+/*
+ * Ceph uses the messenger to exchange ceph_msg messages with other
+ * hosts in the system. The messenger provides ordered and reliable
+ * delivery. We tolerate TCP disconnects by reconnecting (with
+ * exponential backoff) in the case of a fault (disconnection, bad
+ * crc, protocol error). Acks allow sent messages to be discarded by
+ * the sender.
+ */
+
+/* static tag bytes (protocol control messages) */
+static char tag_msg = CEPH_MSGR_TAG_MSG;
+static char tag_ack = CEPH_MSGR_TAG_ACK;
+static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE;
+
+#ifdef CONFIG_LOCKDEP
+static struct lock_class_key socket_class;
+#endif
+
+
+static void queue_con(struct ceph_connection *con);
+static void con_work(struct work_struct *);
+static void ceph_fault(struct ceph_connection *con);
+
+const char *ceph_name_type_str(int t)
+{
+ switch (t) {
+ case CEPH_ENTITY_TYPE_MON: return "mon";
+ case CEPH_ENTITY_TYPE_MDS: return "mds";
+ case CEPH_ENTITY_TYPE_OSD: return "osd";
+ case CEPH_ENTITY_TYPE_CLIENT: return "client";
+ case CEPH_ENTITY_TYPE_ADMIN: return "admin";
+ default: return "???";
+ }
+}
+
+/*
+ * nicely render a sockaddr as a string.
+ */
+#define MAX_ADDR_STR 20
+static char addr_str[MAX_ADDR_STR][40];
+static DEFINE_SPINLOCK(addr_str_lock);
+static int last_addr_str;
+
+const char *pr_addr(const struct sockaddr_storage *ss)
+{
+ int i;
+ char *s;
+ struct sockaddr_in *in4 = (void *)ss;
+ unsigned char *quad = (void *)&in4->sin_addr.s_addr;
+ struct sockaddr_in6 *in6 = (void *)ss;
+
+ spin_lock(&addr_str_lock);
+ i = last_addr_str++;
+ if (last_addr_str == MAX_ADDR_STR)
+ last_addr_str = 0;
+ spin_unlock(&addr_str_lock);
+ s = addr_str[i];
+
+ switch (ss->ss_family) {
+ case AF_INET:
+ sprintf(s, "%u.%u.%u.%u:%u",
+ (unsigned int)quad[0],
+ (unsigned int)quad[1],
+ (unsigned int)quad[2],
+ (unsigned int)quad[3],
+ (unsigned int)ntohs(in4->sin_port));
+ break;
+
+ case AF_INET6:
+ sprintf(s, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u",
+ in6->sin6_addr.s6_addr16[0],
+ in6->sin6_addr.s6_addr16[1],
+ in6->sin6_addr.s6_addr16[2],
+ in6->sin6_addr.s6_addr16[3],
+ in6->sin6_addr.s6_addr16[4],
+ in6->sin6_addr.s6_addr16[5],
+ in6->sin6_addr.s6_addr16[6],
+ in6->sin6_addr.s6_addr16[7],
+ (unsigned int)ntohs(in6->sin6_port));
+ break;
+
+ default:
+ sprintf(s, "(unknown sockaddr family %d)", (int)ss->ss_family);
+ }
+
+ return s;
+}
+
+static void encode_my_addr(struct ceph_messenger *msgr)
+{
+ memcpy(&msgr->my_enc_addr, &msgr->inst.addr, sizeof(msgr->my_enc_addr));
+ ceph_encode_addr(&msgr->my_enc_addr);
+}
+
+/*
+ * work queue for all reading and writing to/from the socket.
+ */
+struct workqueue_struct *ceph_msgr_wq;
+
+int __init ceph_msgr_init(void)
+{
+ ceph_msgr_wq = create_workqueue("ceph-msgr");
+ if (IS_ERR(ceph_msgr_wq)) {
+ int ret = PTR_ERR(ceph_msgr_wq);
+ pr_err("msgr_init failed to create workqueue: %d\n", ret);
+ ceph_msgr_wq = NULL;
+ return ret;
+ }
+ return 0;
+}
+
+void ceph_msgr_exit(void)
+{
+ destroy_workqueue(ceph_msgr_wq);
+}
+
+/*
+ * socket callback functions
+ */
+
+/* data available on socket, or listen socket received a connect */
+static void ceph_data_ready(struct sock *sk, int count_unused)
+{
+ struct ceph_connection *con =
+ (struct ceph_connection *)sk->sk_user_data;
+ if (sk->sk_state != TCP_CLOSE_WAIT) {
+ dout("ceph_data_ready on %p state = %lu, queueing work\n",
+ con, con->state);
+ queue_con(con);
+ }
+}
+
+/* socket has buffer space for writing */
+static void ceph_write_space(struct sock *sk)
+{
+ struct ceph_connection *con =
+ (struct ceph_connection *)sk->sk_user_data;
+
+ /* only queue to workqueue if there is data we want to write. */
+ if (test_bit(WRITE_PENDING, &con->state)) {
+ dout("ceph_write_space %p queueing write work\n", con);
+ queue_con(con);
+ } else {
+ dout("ceph_write_space %p nothing to write\n", con);
+ }
+
+ /* since we have our own write_space, clear the SOCK_NOSPACE flag */
+ clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+}
+
+/* socket's state has changed */
+static void ceph_state_change(struct sock *sk)
+{
+ struct ceph_connection *con =
+ (struct ceph_connection *)sk->sk_user_data;
+
+ dout("ceph_state_change %p state = %lu sk_state = %u\n",
+ con, con->state, sk->sk_state);
+
+ if (test_bit(CLOSED, &con->state))
+ return;
+
+ switch (sk->sk_state) {
+ case TCP_CLOSE:
+ dout("ceph_state_change TCP_CLOSE\n");
+ case TCP_CLOSE_WAIT:
+ dout("ceph_state_change TCP_CLOSE_WAIT\n");
+ if (test_and_set_bit(SOCK_CLOSED, &con->state) == 0) {
+ if (test_bit(CONNECTING, &con->state))
+ con->error_msg = "connection failed";
+ else
+ con->error_msg = "socket closed";
+ queue_con(con);
+ }
+ break;
+ case TCP_ESTABLISHED:
+ dout("ceph_state_change TCP_ESTABLISHED\n");
+ queue_con(con);
+ break;
+ }
+}
+
+/*
+ * set up socket callbacks
+ */
+static void set_sock_callbacks(struct socket *sock,
+ struct ceph_connection *con)
+{
+ struct sock *sk = sock->sk;
+ sk->sk_user_data = (void *)con;
+ sk->sk_data_ready = ceph_data_ready;
+ sk->sk_write_space = ceph_write_space;
+ sk->sk_state_change = ceph_state_change;
+}
+
+
+/*
+ * socket helpers
+ */
+
+/*
+ * initiate connection to a remote socket.
+ */
+static struct socket *ceph_tcp_connect(struct ceph_connection *con)
+{
+ struct sockaddr *paddr = (struct sockaddr *)&con->peer_addr.in_addr;
+ struct socket *sock;
+ int ret;
+
+ BUG_ON(con->sock);
+ ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+ if (ret)
+ return ERR_PTR(ret);
+ con->sock = sock;
+ sock->sk->sk_allocation = GFP_NOFS;
+
+#ifdef CONFIG_LOCKDEP
+ lockdep_set_class(&sock->sk->sk_lock, &socket_class);
+#endif
+
+ set_sock_callbacks(sock, con);
+
+ dout("connect %s\n", pr_addr(&con->peer_addr.in_addr));
+
+ ret = sock->ops->connect(sock, paddr, sizeof(*paddr), O_NONBLOCK);
+ if (ret == -EINPROGRESS) {
+ dout("connect %s EINPROGRESS sk_state = %u\n",
+ pr_addr(&con->peer_addr.in_addr),
+ sock->sk->sk_state);
+ ret = 0;
+ }
+ if (ret < 0) {
+ pr_err("connect %s error %d\n",
+ pr_addr(&con->peer_addr.in_addr), ret);
+ sock_release(sock);
+ con->sock = NULL;
+ con->error_msg = "connect error";
+ }
+
+ if (ret < 0)
+ return ERR_PTR(ret);
+ return sock;
+}
+
+static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
+{
+ struct kvec iov = {buf, len};
+ struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
+
+ return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags);
+}
+
+/*
+ * write something. @more is true if caller will be sending more data
+ * shortly.
+ */
+static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov,
+ size_t kvlen, size_t len, int more)
+{
+ struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
+
+ if (more)
+ msg.msg_flags |= MSG_MORE;
+ else
+ msg.msg_flags |= MSG_EOR; /* superfluous, but what the hell */
+
+ return kernel_sendmsg(sock, &msg, iov, kvlen, len);
+}
+
+
+/*
+ * Shutdown/close the socket for the given connection.
+ */
+static int con_close_socket(struct ceph_connection *con)
+{
+ int rc;
+
+ dout("con_close_socket on %p sock %p\n", con, con->sock);
+ if (!con->sock)
+ return 0;
+ set_bit(SOCK_CLOSED, &con->state);
+ rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR);
+ sock_release(con->sock);
+ con->sock = NULL;
+ clear_bit(SOCK_CLOSED, &con->state);
+ return rc;
+}
+
+/*
+ * Reset a connection. Discard all incoming and outgoing messages
+ * and clear *_seq state.
+ */
+static void ceph_msg_remove(struct ceph_msg *msg)
+{
+ list_del_init(&msg->list_head);
+ ceph_msg_put(msg);
+}
+static void ceph_msg_remove_list(struct list_head *head)
+{
+ while (!list_empty(head)) {
+ struct ceph_msg *msg = list_first_entry(head, struct ceph_msg,
+ list_head);
+ ceph_msg_remove(msg);
+ }
+}
+
+static void reset_connection(struct ceph_connection *con)
+{
+ /* reset connection, out_queue, msg_ and connect_seq */
+ /* discard existing out_queue and msg_seq */
+ ceph_msg_remove_list(&con->out_queue);
+ ceph_msg_remove_list(&con->out_sent);
+
+ if (con->in_msg) {
+ ceph_msg_put(con->in_msg);
+ con->in_msg = NULL;
+ }
+
+ con->connect_seq = 0;
+ con->out_seq = 0;
+ if (con->out_msg) {
+ ceph_msg_put(con->out_msg);
+ con->out_msg = NULL;
+ }
+ con->in_seq = 0;
+ con->in_seq_acked = 0;
+}
+
+/*
+ * mark a peer down. drop any open connections.
+ */
+void ceph_con_close(struct ceph_connection *con)
+{
+ dout("con_close %p peer %s\n", con, pr_addr(&con->peer_addr.in_addr));
+ set_bit(CLOSED, &con->state); /* in case there's queued work */
+ clear_bit(STANDBY, &con->state); /* avoid connect_seq bump */
+ clear_bit(LOSSYTX, &con->state); /* so we retry next connect */
+ clear_bit(KEEPALIVE_PENDING, &con->state);
+ clear_bit(WRITE_PENDING, &con->state);
+ mutex_lock(&con->mutex);
+ reset_connection(con);
+ cancel_delayed_work(&con->work);
+ mutex_unlock(&con->mutex);
+ queue_con(con);
+}
+
+/*
+ * Reopen a closed connection, with a new peer address.
+ */
+void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr)
+{
+ dout("con_open %p %s\n", con, pr_addr(&addr->in_addr));
+ set_bit(OPENING, &con->state);
+ clear_bit(CLOSED, &con->state);
+ memcpy(&con->peer_addr, addr, sizeof(*addr));
+ con->delay = 0; /* reset backoff memory */
+ queue_con(con);
+}
+
+/*
+ * return true if this connection ever successfully opened
+ */
+bool ceph_con_opened(struct ceph_connection *con)
+{
+ return con->connect_seq > 0;
+}
+
+/*
+ * generic get/put
+ */
+struct ceph_connection *ceph_con_get(struct ceph_connection *con)
+{
+ dout("con_get %p nref = %d -> %d\n", con,
+ atomic_read(&con->nref), atomic_read(&con->nref) + 1);
+ if (atomic_inc_not_zero(&con->nref))
+ return con;
+ return NULL;
+}
+
+void ceph_con_put(struct ceph_connection *con)
+{
+ dout("con_put %p nref = %d -> %d\n", con,
+ atomic_read(&con->nref), atomic_read(&con->nref) - 1);
+ BUG_ON(atomic_read(&con->nref) == 0);
+ if (atomic_dec_and_test(&con->nref)) {
+ BUG_ON(con->sock);
+ kfree(con);
+ }
+}
+
+/*
+ * initialize a new connection.
+ */
+void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con)
+{
+ dout("con_init %p\n", con);
+ memset(con, 0, sizeof(*con));
+ atomic_set(&con->nref, 1);
+ con->msgr = msgr;
+ mutex_init(&con->mutex);
+ INIT_LIST_HEAD(&con->out_queue);
+ INIT_LIST_HEAD(&con->out_sent);
+ INIT_DELAYED_WORK(&con->work, con_work);
+}
+
+
+/*
+ * We maintain a global counter to order connection attempts. Get
+ * a unique seq greater than @gt.
+ */
+static u32 get_global_seq(struct ceph_messenger *msgr, u32 gt)
+{
+ u32 ret;
+
+ spin_lock(&msgr->global_seq_lock);
+ if (msgr->global_seq < gt)
+ msgr->global_seq = gt;
+ ret = ++msgr->global_seq;
+ spin_unlock(&msgr->global_seq_lock);
+ return ret;
+}
+
+
+/*
+ * Prepare footer for currently outgoing message, and finish things
+ * off. Assumes out_kvec* are already valid.. we just add on to the end.
+ */
+static void prepare_write_message_footer(struct ceph_connection *con, int v)
+{
+ struct ceph_msg *m = con->out_msg;
+
+ dout("prepare_write_message_footer %p\n", con);
+ con->out_kvec_is_msg = true;
+ con->out_kvec[v].iov_base = &m->footer;
+ con->out_kvec[v].iov_len = sizeof(m->footer);
+ con->out_kvec_bytes += sizeof(m->footer);
+ con->out_kvec_left++;
+ con->out_more = m->more_to_follow;
+ con->out_msg_done = true;
+}
+
+/*
+ * Prepare headers for the next outgoing message.
+ */
+static void prepare_write_message(struct ceph_connection *con)
+{
+ struct ceph_msg *m;
+ int v = 0;
+
+ con->out_kvec_bytes = 0;
+ con->out_kvec_is_msg = true;
+ con->out_msg_done = false;
+
+ /* Sneak an ack in there first? If we can get it into the same
+ * TCP packet that's a good thing. */
+ if (con->in_seq > con->in_seq_acked) {
+ con->in_seq_acked = con->in_seq;
+ con->out_kvec[v].iov_base = &tag_ack;
+ con->out_kvec[v++].iov_len = 1;
+ con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
+ con->out_kvec[v].iov_base = &con->out_temp_ack;
+ con->out_kvec[v++].iov_len = sizeof(con->out_temp_ack);
+ con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
+ }
+
+ m = list_first_entry(&con->out_queue,
+ struct ceph_msg, list_head);
+ con->out_msg = m;
+ if (test_bit(LOSSYTX, &con->state)) {
+ list_del_init(&m->list_head);
+ } else {
+ /* put message on sent list */
+ ceph_msg_get(m);
+ list_move_tail(&m->list_head, &con->out_sent);
+ }
+
+ m->hdr.seq = cpu_to_le64(++con->out_seq);
+
+ dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n",
+ m, con->out_seq, le16_to_cpu(m->hdr.type),
+ le32_to_cpu(m->hdr.front_len), le32_to_cpu(m->hdr.middle_len),
+ le32_to_cpu(m->hdr.data_len),
+ m->nr_pages);
+ BUG_ON(le32_to_cpu(m->hdr.front_len) != m->front.iov_len);
+
+ /* tag + hdr + front + middle */
+ con->out_kvec[v].iov_base = &tag_msg;
+ con->out_kvec[v++].iov_len = 1;
+ con->out_kvec[v].iov_base = &m->hdr;
+ con->out_kvec[v++].iov_len = sizeof(m->hdr);
+ con->out_kvec[v++] = m->front;
+ if (m->middle)
+ con->out_kvec[v++] = m->middle->vec;
+ con->out_kvec_left = v;
+ con->out_kvec_bytes += 1 + sizeof(m->hdr) + m->front.iov_len +
+ (m->middle ? m->middle->vec.iov_len : 0);
+ con->out_kvec_cur = con->out_kvec;
+
+ /* fill in crc (except data pages), footer */
+ con->out_msg->hdr.crc =
+ cpu_to_le32(crc32c(0, (void *)&m->hdr,
+ sizeof(m->hdr) - sizeof(m->hdr.crc)));
+ con->out_msg->footer.flags = CEPH_MSG_FOOTER_COMPLETE;
+ con->out_msg->footer.front_crc =
+ cpu_to_le32(crc32c(0, m->front.iov_base, m->front.iov_len));
+ if (m->middle)
+ con->out_msg->footer.middle_crc =
+ cpu_to_le32(crc32c(0, m->middle->vec.iov_base,
+ m->middle->vec.iov_len));
+ else
+ con->out_msg->footer.middle_crc = 0;
+ con->out_msg->footer.data_crc = 0;
+ dout("prepare_write_message front_crc %u data_crc %u\n",
+ le32_to_cpu(con->out_msg->footer.front_crc),
+ le32_to_cpu(con->out_msg->footer.middle_crc));
+
+ /* is there a data payload? */
+ if (le32_to_cpu(m->hdr.data_len) > 0) {
+ /* initialize page iterator */
+ con->out_msg_pos.page = 0;
+ con->out_msg_pos.page_pos =
+ le16_to_cpu(m->hdr.data_off) & ~PAGE_MASK;
+ con->out_msg_pos.data_pos = 0;
+ con->out_msg_pos.did_page_crc = 0;
+ con->out_more = 1; /* data + footer will follow */
+ } else {
+ /* no, queue up footer too and be done */
+ prepare_write_message_footer(con, v);
+ }
+
+ set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Prepare an ack.
+ */
+static void prepare_write_ack(struct ceph_connection *con)
+{
+ dout("prepare_write_ack %p %llu -> %llu\n", con,
+ con->in_seq_acked, con->in_seq);
+ con->in_seq_acked = con->in_seq;
+
+ con->out_kvec[0].iov_base = &tag_ack;
+ con->out_kvec[0].iov_len = 1;
+ con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
+ con->out_kvec[1].iov_base = &con->out_temp_ack;
+ con->out_kvec[1].iov_len = sizeof(con->out_temp_ack);
+ con->out_kvec_left = 2;
+ con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
+ con->out_kvec_cur = con->out_kvec;
+ con->out_more = 1; /* more will follow.. eventually.. */
+ set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Prepare to write keepalive byte.
+ */
+static void prepare_write_keepalive(struct ceph_connection *con)
+{
+ dout("prepare_write_keepalive %p\n", con);
+ con->out_kvec[0].iov_base = &tag_keepalive;
+ con->out_kvec[0].iov_len = 1;
+ con->out_kvec_left = 1;
+ con->out_kvec_bytes = 1;
+ con->out_kvec_cur = con->out_kvec;
+ set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Connection negotiation.
+ */
+
+static void prepare_connect_authorizer(struct ceph_connection *con)
+{
+ void *auth_buf;
+ int auth_len = 0;
+ int auth_protocol = 0;
+
+ mutex_unlock(&con->mutex);
+ if (con->ops->get_authorizer)
+ con->ops->get_authorizer(con, &auth_buf, &auth_len,
+ &auth_protocol, &con->auth_reply_buf,
+ &con->auth_reply_buf_len,
+ con->auth_retry);
+ mutex_lock(&con->mutex);
+
+ con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol);
+ con->out_connect.authorizer_len = cpu_to_le32(auth_len);
+
+ con->out_kvec[con->out_kvec_left].iov_base = auth_buf;
+ con->out_kvec[con->out_kvec_left].iov_len = auth_len;
+ con->out_kvec_left++;
+ con->out_kvec_bytes += auth_len;
+}
+
+/*
+ * We connected to a peer and are saying hello.
+ */
+static void prepare_write_banner(struct ceph_messenger *msgr,
+ struct ceph_connection *con)
+{
+ int len = strlen(CEPH_BANNER);
+
+ con->out_kvec[0].iov_base = CEPH_BANNER;
+ con->out_kvec[0].iov_len = len;
+ con->out_kvec[1].iov_base = &msgr->my_enc_addr;
+ con->out_kvec[1].iov_len = sizeof(msgr->my_enc_addr);
+ con->out_kvec_left = 2;
+ con->out_kvec_bytes = len + sizeof(msgr->my_enc_addr);
+ con->out_kvec_cur = con->out_kvec;
+ con->out_more = 0;
+ set_bit(WRITE_PENDING, &con->state);
+}
+
+static void prepare_write_connect(struct ceph_messenger *msgr,
+ struct ceph_connection *con,
+ int after_banner)
+{
+ unsigned global_seq = get_global_seq(con->msgr, 0);
+ int proto;
+
+ switch (con->peer_name.type) {
+ case CEPH_ENTITY_TYPE_MON:
+ proto = CEPH_MONC_PROTOCOL;
+ break;
+ case CEPH_ENTITY_TYPE_OSD:
+ proto = CEPH_OSDC_PROTOCOL;
+ break;
+ case CEPH_ENTITY_TYPE_MDS:
+ proto = CEPH_MDSC_PROTOCOL;
+ break;
+ default:
+ BUG();
+ }
+
+ dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
+ con->connect_seq, global_seq, proto);
+
+ con->out_connect.features = CEPH_FEATURE_SUPPORTED;
+ con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT);
+ con->out_connect.connect_seq = cpu_to_le32(con->connect_seq);
+ con->out_connect.global_seq = cpu_to_le32(global_seq);
+ con->out_connect.protocol_version = cpu_to_le32(proto);
+ con->out_connect.flags = 0;
+
+ if (!after_banner) {
+ con->out_kvec_left = 0;
+ con->out_kvec_bytes = 0;
+ }
+ con->out_kvec[con->out_kvec_left].iov_base = &con->out_connect;
+ con->out_kvec[con->out_kvec_left].iov_len = sizeof(con->out_connect);
+ con->out_kvec_left++;
+ con->out_kvec_bytes += sizeof(con->out_connect);
+ con->out_kvec_cur = con->out_kvec;
+ con->out_more = 0;
+ set_bit(WRITE_PENDING, &con->state);
+
+ prepare_connect_authorizer(con);
+}
+
+
+/*
+ * write as much of pending kvecs to the socket as we can.
+ * 1 -> done
+ * 0 -> socket full, but more to do
+ * <0 -> error
+ */
+static int write_partial_kvec(struct ceph_connection *con)
+{
+ int ret;
+
+ dout("write_partial_kvec %p %d left\n", con, con->out_kvec_bytes);
+ while (con->out_kvec_bytes > 0) {
+ ret = ceph_tcp_sendmsg(con->sock, con->out_kvec_cur,
+ con->out_kvec_left, con->out_kvec_bytes,
+ con->out_more);
+ if (ret <= 0)
+ goto out;
+ con->out_kvec_bytes -= ret;
+ if (con->out_kvec_bytes == 0)
+ break; /* done */
+ while (ret > 0) {
+ if (ret >= con->out_kvec_cur->iov_len) {
+ ret -= con->out_kvec_cur->iov_len;
+ con->out_kvec_cur++;
+ con->out_kvec_left--;
+ } else {
+ con->out_kvec_cur->iov_len -= ret;
+ con->out_kvec_cur->iov_base += ret;
+ ret = 0;
+ break;
+ }
+ }
+ }
+ con->out_kvec_left = 0;
+ con->out_kvec_is_msg = false;
+ ret = 1;
+out:
+ dout("write_partial_kvec %p %d left in %d kvecs ret = %d\n", con,
+ con->out_kvec_bytes, con->out_kvec_left, ret);
+ return ret; /* done! */
+}
+
+/*
+ * Write as much message data payload as we can. If we finish, queue
+ * up the footer.
+ * 1 -> done, footer is now queued in out_kvec[].
+ * 0 -> socket full, but more to do
+ * <0 -> error
+ */
+static int write_partial_msg_pages(struct ceph_connection *con)
+{
+ struct ceph_msg *msg = con->out_msg;
+ unsigned data_len = le32_to_cpu(msg->hdr.data_len);
+ size_t len;
+ int crc = con->msgr->nocrc;
+ int ret;
+
+ dout("write_partial_msg_pages %p msg %p page %d/%d offset %d\n",
+ con, con->out_msg, con->out_msg_pos.page, con->out_msg->nr_pages,
+ con->out_msg_pos.page_pos);
+
+ while (con->out_msg_pos.page < con->out_msg->nr_pages) {
+ struct page *page = NULL;
+ void *kaddr = NULL;
+
+ /*
+ * if we are calculating the data crc (the default), we need
+ * to map the page. if our pages[] has been revoked, use the
+ * zero page.
+ */
+ if (msg->pages) {
+ page = msg->pages[con->out_msg_pos.page];
+ if (crc)
+ kaddr = kmap(page);
+ } else if (msg->pagelist) {
+ page = list_first_entry(&msg->pagelist->head,
+ struct page, lru);
+ if (crc)
+ kaddr = kmap(page);
+ } else {
+ page = con->msgr->zero_page;
+ if (crc)
+ kaddr = page_address(con->msgr->zero_page);
+ }
+ len = min((int)(PAGE_SIZE - con->out_msg_pos.page_pos),
+ (int)(data_len - con->out_msg_pos.data_pos));
+ if (crc && !con->out_msg_pos.did_page_crc) {
+ void *base = kaddr + con->out_msg_pos.page_pos;
+ u32 tmpcrc = le32_to_cpu(con->out_msg->footer.data_crc);
+
+ BUG_ON(kaddr == NULL);
+ con->out_msg->footer.data_crc =
+ cpu_to_le32(crc32c(tmpcrc, base, len));
+ con->out_msg_pos.did_page_crc = 1;
+ }
+
+ ret = kernel_sendpage(con->sock, page,
+ con->out_msg_pos.page_pos, len,
+ MSG_DONTWAIT | MSG_NOSIGNAL |
+ MSG_MORE);
+
+ if (crc && (msg->pages || msg->pagelist))
+ kunmap(page);
+
+ if (ret <= 0)
+ goto out;
+
+ con->out_msg_pos.data_pos += ret;
+ con->out_msg_pos.page_pos += ret;
+ if (ret == len) {
+ con->out_msg_pos.page_pos = 0;
+ con->out_msg_pos.page++;
+ con->out_msg_pos.did_page_crc = 0;
+ if (msg->pagelist)
+ list_move_tail(&page->lru,
+ &msg->pagelist->head);
+ }
+ }
+
+ dout("write_partial_msg_pages %p msg %p done\n", con, msg);
+
+ /* prepare and queue up footer, too */
+ if (!crc)
+ con->out_msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC;
+ con->out_kvec_bytes = 0;
+ con->out_kvec_left = 0;
+ con->out_kvec_cur = con->out_kvec;
+ prepare_write_message_footer(con, 0);
+ ret = 1;
+out:
+ return ret;
+}
+
+/*
+ * write some zeros
+ */
+static int write_partial_skip(struct ceph_connection *con)
+{
+ int ret;
+
+ while (con->out_skip > 0) {
+ struct kvec iov = {
+ .iov_base = page_address(con->msgr->zero_page),
+ .iov_len = min(con->out_skip, (int)PAGE_CACHE_SIZE)
+ };
+
+ ret = ceph_tcp_sendmsg(con->sock, &iov, 1, iov.iov_len, 1);
+ if (ret <= 0)
+ goto out;
+ con->out_skip -= ret;
+ }
+ ret = 1;
+out:
+ return ret;
+}
+
+/*
+ * Prepare to read connection handshake, or an ack.
+ */
+static void prepare_read_banner(struct ceph_connection *con)
+{
+ dout("prepare_read_banner %p\n", con);
+ con->in_base_pos = 0;
+}
+
+static void prepare_read_connect(struct ceph_connection *con)
+{
+ dout("prepare_read_connect %p\n", con);
+ con->in_base_pos = 0;
+}
+
+static void prepare_read_ack(struct ceph_connection *con)
+{
+ dout("prepare_read_ack %p\n", con);
+ con->in_base_pos = 0;
+}
+
+static void prepare_read_tag(struct ceph_connection *con)
+{
+ dout("prepare_read_tag %p\n", con);
+ con->in_base_pos = 0;
+ con->in_tag = CEPH_MSGR_TAG_READY;
+}
+
+/*
+ * Prepare to read a message.
+ */
+static int prepare_read_message(struct ceph_connection *con)
+{
+ dout("prepare_read_message %p\n", con);
+ BUG_ON(con->in_msg != NULL);
+ con->in_base_pos = 0;
+ con->in_front_crc = con->in_middle_crc = con->in_data_crc = 0;
+ return 0;
+}
+
+
+static int read_partial(struct ceph_connection *con,
+ int *to, int size, void *object)
+{
+ *to += size;
+ while (con->in_base_pos < *to) {
+ int left = *to - con->in_base_pos;
+ int have = size - left;
+ int ret = ceph_tcp_recvmsg(con->sock, object + have, left);
+ if (ret <= 0)
+ return ret;
+ con->in_base_pos += ret;
+ }
+ return 1;
+}
+
+
+/*
+ * Read all or part of the connect-side handshake on a new connection
+ */
+static int read_partial_banner(struct ceph_connection *con)
+{
+ int ret, to = 0;
+
+ dout("read_partial_banner %p at %d\n", con, con->in_base_pos);
+
+ /* peer's banner */
+ ret = read_partial(con, &to, strlen(CEPH_BANNER), con->in_banner);
+ if (ret <= 0)
+ goto out;
+ ret = read_partial(con, &to, sizeof(con->actual_peer_addr),
+ &con->actual_peer_addr);
+ if (ret <= 0)
+ goto out;
+ ret = read_partial(con, &to, sizeof(con->peer_addr_for_me),
+ &con->peer_addr_for_me);
+ if (ret <= 0)
+ goto out;
+out:
+ return ret;
+}
+
+static int read_partial_connect(struct ceph_connection *con)
+{
+ int ret, to = 0;
+
+ dout("read_partial_connect %p at %d\n", con, con->in_base_pos);
+
+ ret = read_partial(con, &to, sizeof(con->in_reply), &con->in_reply);
+ if (ret <= 0)
+ goto out;
+ ret = read_partial(con, &to, le32_to_cpu(con->in_reply.authorizer_len),
+ con->auth_reply_buf);
+ if (ret <= 0)
+ goto out;
+
+ dout("read_partial_connect %p tag %d, con_seq = %u, g_seq = %u\n",
+ con, (int)con->in_reply.tag,
+ le32_to_cpu(con->in_reply.connect_seq),
+ le32_to_cpu(con->in_reply.global_seq));
+out:
+ return ret;
+
+}
+
+/*
+ * Verify the hello banner looks okay.
+ */
+static int verify_hello(struct ceph_connection *con)
+{
+ if (memcmp(con->in_banner, CEPH_BANNER, strlen(CEPH_BANNER))) {
+ pr_err("connect to %s got bad banner\n",
+ pr_addr(&con->peer_addr.in_addr));
+ con->error_msg = "protocol error, bad banner";
+ return -1;
+ }
+ return 0;
+}
+
+static bool addr_is_blank(struct sockaddr_storage *ss)
+{
+ switch (ss->ss_family) {
+ case AF_INET:
+ return ((struct sockaddr_in *)ss)->sin_addr.s_addr == 0;
+ case AF_INET6:
+ return
+ ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[0] == 0 &&
+ ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[1] == 0 &&
+ ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[2] == 0 &&
+ ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[3] == 0;
+ }
+ return false;
+}
+
+static int addr_port(struct sockaddr_storage *ss)
+{
+ switch (ss->ss_family) {
+ case AF_INET:
+ return ntohs(((struct sockaddr_in *)ss)->sin_port);
+ case AF_INET6:
+ return ntohs(((struct sockaddr_in6 *)ss)->sin6_port);
+ }
+ return 0;
+}
+
+static void addr_set_port(struct sockaddr_storage *ss, int p)
+{
+ switch (ss->ss_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)ss)->sin_port = htons(p);
+ case AF_INET6:
+ ((struct sockaddr_in6 *)ss)->sin6_port = htons(p);
+ }
+}
+
+/*
+ * Parse an ip[:port] list into an addr array. Use the default
+ * monitor port if a port isn't specified.
+ */
+int ceph_parse_ips(const char *c, const char *end,
+ struct ceph_entity_addr *addr,
+ int max_count, int *count)
+{
+ int i;
+ const char *p = c;
+
+ dout("parse_ips on '%.*s'\n", (int)(end-c), c);
+ for (i = 0; i < max_count; i++) {
+ const char *ipend;
+ struct sockaddr_storage *ss = &addr[i].in_addr;
+ struct sockaddr_in *in4 = (void *)ss;
+ struct sockaddr_in6 *in6 = (void *)ss;
+ int port;
+
+ memset(ss, 0, sizeof(*ss));
+ if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr,
+ ',', &ipend)) {
+ ss->ss_family = AF_INET;
+ } else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr,
+ ',', &ipend)) {
+ ss->ss_family = AF_INET6;
+ } else {
+ goto bad;
+ }
+ p = ipend;
+
+ /* port? */
+ if (p < end && *p == ':') {
+ port = 0;
+ p++;
+ while (p < end && *p >= '0' && *p <= '9') {
+ port = (port * 10) + (*p - '0');
+ p++;
+ }
+ if (port > 65535 || port == 0)
+ goto bad;
+ } else {
+ port = CEPH_MON_PORT;
+ }
+
+ addr_set_port(ss, port);
+
+ dout("parse_ips got %s\n", pr_addr(ss));
+
+ if (p == end)
+ break;
+ if (*p != ',')
+ goto bad;
+ p++;
+ }
+
+ if (p != end)
+ goto bad;
+
+ if (count)
+ *count = i + 1;
+ return 0;
+
+bad:
+ pr_err("parse_ips bad ip '%s'\n", c);
+ return -EINVAL;
+}
+
+static int process_banner(struct ceph_connection *con)
+{
+ dout("process_banner on %p\n", con);
+
+ if (verify_hello(con) < 0)
+ return -1;
+
+ ceph_decode_addr(&con->actual_peer_addr);
+ ceph_decode_addr(&con->peer_addr_for_me);
+
+ /*
+ * Make sure the other end is who we wanted. note that the other
+ * end may not yet know their ip address, so if it's 0.0.0.0, give
+ * them the benefit of the doubt.
+ */
+ if (memcmp(&con->peer_addr, &con->actual_peer_addr,
+ sizeof(con->peer_addr)) != 0 &&
+ !(addr_is_blank(&con->actual_peer_addr.in_addr) &&
+ con->actual_peer_addr.nonce == con->peer_addr.nonce)) {
+ pr_warning("wrong peer, want %s/%lld, got %s/%lld\n",
+ pr_addr(&con->peer_addr.in_addr),
+ le64_to_cpu(con->peer_addr.nonce),
+ pr_addr(&con->actual_peer_addr.in_addr),
+ le64_to_cpu(con->actual_peer_addr.nonce));
+ con->error_msg = "wrong peer at address";
+ return -1;
+ }
+
+ /*
+ * did we learn our address?
+ */
+ if (addr_is_blank(&con->msgr->inst.addr.in_addr)) {
+ int port = addr_port(&con->msgr->inst.addr.in_addr);
+
+ memcpy(&con->msgr->inst.addr.in_addr,
+ &con->peer_addr_for_me.in_addr,
+ sizeof(con->peer_addr_for_me.in_addr));
+ addr_set_port(&con->msgr->inst.addr.in_addr, port);
+ encode_my_addr(con->msgr);
+ dout("process_banner learned my addr is %s\n",
+ pr_addr(&con->msgr->inst.addr.in_addr));
+ }
+
+ set_bit(NEGOTIATING, &con->state);
+ prepare_read_connect(con);
+ return 0;
+}
+
+static void fail_protocol(struct ceph_connection *con)
+{
+ reset_connection(con);
+ set_bit(CLOSED, &con->state); /* in case there's queued work */
+
+ mutex_unlock(&con->mutex);
+ if (con->ops->bad_proto)
+ con->ops->bad_proto(con);
+ mutex_lock(&con->mutex);
+}
+
+static int process_connect(struct ceph_connection *con)
+{
+ u64 sup_feat = CEPH_FEATURE_SUPPORTED;
+ u64 req_feat = CEPH_FEATURE_REQUIRED;
+ u64 server_feat = le64_to_cpu(con->in_reply.features);
+
+ dout("process_connect on %p tag %d\n", con, (int)con->in_tag);
+
+ switch (con->in_reply.tag) {
+ case CEPH_MSGR_TAG_FEATURES:
+ pr_err("%s%lld %s feature set mismatch,"
+ " my %llx < server's %llx, missing %llx\n",
+ ENTITY_NAME(con->peer_name),
+ pr_addr(&con->peer_addr.in_addr),
+ sup_feat, server_feat, server_feat & ~sup_feat);
+ con->error_msg = "missing required protocol features";
+ fail_protocol(con);
+ return -1;
+
+ case CEPH_MSGR_TAG_BADPROTOVER:
+ pr_err("%s%lld %s protocol version mismatch,"
+ " my %d != server's %d\n",
+ ENTITY_NAME(con->peer_name),
+ pr_addr(&con->peer_addr.in_addr),
+ le32_to_cpu(con->out_connect.protocol_version),
+ le32_to_cpu(con->in_reply.protocol_version));
+ con->error_msg = "protocol version mismatch";
+ fail_protocol(con);
+ return -1;
+
+ case CEPH_MSGR_TAG_BADAUTHORIZER:
+ con->auth_retry++;
+ dout("process_connect %p got BADAUTHORIZER attempt %d\n", con,
+ con->auth_retry);
+ if (con->auth_retry == 2) {
+ con->error_msg = "connect authorization failure";
+ reset_connection(con);
+ set_bit(CLOSED, &con->state);
+ return -1;
+ }
+ con->auth_retry = 1;
+ prepare_write_connect(con->msgr, con, 0);
+ prepare_read_connect(con);
+ break;
+
+ case CEPH_MSGR_TAG_RESETSESSION:
+ /*
+ * If we connected with a large connect_seq but the peer
+ * has no record of a session with us (no connection, or
+ * connect_seq == 0), they will send RESETSESION to indicate
+ * that they must have reset their session, and may have
+ * dropped messages.
+ */
+ dout("process_connect got RESET peer seq %u\n",
+ le32_to_cpu(con->in_connect.connect_seq));
+ pr_err("%s%lld %s connection reset\n",
+ ENTITY_NAME(con->peer_name),
+ pr_addr(&con->peer_addr.in_addr));
+ reset_connection(con);
+ prepare_write_connect(con->msgr, con, 0);
+ prepare_read_connect(con);
+
+ /* Tell ceph about it. */
+ mutex_unlock(&con->mutex);
+ pr_info("reset on %s%lld\n", ENTITY_NAME(con->peer_name));
+ if (con->ops->peer_reset)
+ con->ops->peer_reset(con);
+ mutex_lock(&con->mutex);
+ break;
+
+ case CEPH_MSGR_TAG_RETRY_SESSION:
+ /*
+ * If we sent a smaller connect_seq than the peer has, try
+ * again with a larger value.
+ */
+ dout("process_connect got RETRY my seq = %u, peer_seq = %u\n",
+ le32_to_cpu(con->out_connect.connect_seq),
+ le32_to_cpu(con->in_connect.connect_seq));
+ con->connect_seq = le32_to_cpu(con->in_connect.connect_seq);
+ prepare_write_connect(con->msgr, con, 0);
+ prepare_read_connect(con);
+ break;
+
+ case CEPH_MSGR_TAG_RETRY_GLOBAL:
+ /*
+ * If we sent a smaller global_seq than the peer has, try
+ * again with a larger value.
+ */
+ dout("process_connect got RETRY_GLOBAL my %u peer_gseq %u\n",
+ con->peer_global_seq,
+ le32_to_cpu(con->in_connect.global_seq));
+ get_global_seq(con->msgr,
+ le32_to_cpu(con->in_connect.global_seq));
+ prepare_write_connect(con->msgr, con, 0);
+ prepare_read_connect(con);
+ break;
+
+ case CEPH_MSGR_TAG_READY:
+ if (req_feat & ~server_feat) {
+ pr_err("%s%lld %s protocol feature mismatch,"
+ " my required %llx > server's %llx, need %llx\n",
+ ENTITY_NAME(con->peer_name),
+ pr_addr(&con->peer_addr.in_addr),
+ req_feat, server_feat, req_feat & ~server_feat);
+ con->error_msg = "missing required protocol features";
+ fail_protocol(con);
+ return -1;
+ }
+ clear_bit(CONNECTING, &con->state);
+ con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
+ con->connect_seq++;
+ dout("process_connect got READY gseq %d cseq %d (%d)\n",
+ con->peer_global_seq,
+ le32_to_cpu(con->in_reply.connect_seq),
+ con->connect_seq);
+ WARN_ON(con->connect_seq !=
+ le32_to_cpu(con->in_reply.connect_seq));
+
+ if (con->in_reply.flags & CEPH_MSG_CONNECT_LOSSY)
+ set_bit(LOSSYTX, &con->state);
+
+ prepare_read_tag(con);
+ break;
+
+ case CEPH_MSGR_TAG_WAIT:
+ /*
+ * If there is a connection race (we are opening
+ * connections to each other), one of us may just have
+ * to WAIT. This shouldn't happen if we are the
+ * client.
+ */
+ pr_err("process_connect peer connecting WAIT\n");
+
+ default:
+ pr_err("connect protocol error, will retry\n");
+ con->error_msg = "protocol error, garbage tag during connect";
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * read (part of) an ack
+ */
+static int read_partial_ack(struct ceph_connection *con)
+{
+ int to = 0;
+
+ return read_partial(con, &to, sizeof(con->in_temp_ack),
+ &con->in_temp_ack);
+}
+
+
+/*
+ * We can finally discard anything that's been acked.
+ */
+static void process_ack(struct ceph_connection *con)
+{
+ struct ceph_msg *m;
+ u64 ack = le64_to_cpu(con->in_temp_ack);
+ u64 seq;
+
+ while (!list_empty(&con->out_sent)) {
+ m = list_first_entry(&con->out_sent, struct ceph_msg,
+ list_head);
+ seq = le64_to_cpu(m->hdr.seq);
+ if (seq > ack)
+ break;
+ dout("got ack for seq %llu type %d at %p\n", seq,
+ le16_to_cpu(m->hdr.type), m);
+ ceph_msg_remove(m);
+ }
+ prepare_read_tag(con);
+}
+
+
+
+
+static int read_partial_message_section(struct ceph_connection *con,
+ struct kvec *section, unsigned int sec_len,
+ u32 *crc)
+{
+ int left;
+ int ret;
+
+ BUG_ON(!section);
+
+ while (section->iov_len < sec_len) {
+ BUG_ON(section->iov_base == NULL);
+ left = sec_len - section->iov_len;
+ ret = ceph_tcp_recvmsg(con->sock, (char *)section->iov_base +
+ section->iov_len, left);
+ if (ret <= 0)
+ return ret;
+ section->iov_len += ret;
+ if (section->iov_len == sec_len)
+ *crc = crc32c(0, section->iov_base,
+ section->iov_len);
+ }
+
+ return 1;
+}
+
+static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
+ struct ceph_msg_header *hdr,
+ int *skip);
+/*
+ * read (part of) a message.
+ */
+static int read_partial_message(struct ceph_connection *con)
+{
+ struct ceph_msg *m = con->in_msg;
+ void *p;
+ int ret;
+ int to, left;
+ unsigned front_len, middle_len, data_len, data_off;
+ int datacrc = con->msgr->nocrc;
+ int skip;
+
+ dout("read_partial_message con %p msg %p\n", con, m);
+
+ /* header */
+ while (con->in_base_pos < sizeof(con->in_hdr)) {
+ left = sizeof(con->in_hdr) - con->in_base_pos;
+ ret = ceph_tcp_recvmsg(con->sock,
+ (char *)&con->in_hdr + con->in_base_pos,
+ left);
+ if (ret <= 0)
+ return ret;
+ con->in_base_pos += ret;
+ if (con->in_base_pos == sizeof(con->in_hdr)) {
+ u32 crc = crc32c(0, (void *)&con->in_hdr,
+ sizeof(con->in_hdr) - sizeof(con->in_hdr.crc));
+ if (crc != le32_to_cpu(con->in_hdr.crc)) {
+ pr_err("read_partial_message bad hdr "
+ " crc %u != expected %u\n",
+ crc, con->in_hdr.crc);
+ return -EBADMSG;
+ }
+ }
+ }
+ front_len = le32_to_cpu(con->in_hdr.front_len);
+ if (front_len > CEPH_MSG_MAX_FRONT_LEN)
+ return -EIO;
+ middle_len = le32_to_cpu(con->in_hdr.middle_len);
+ if (middle_len > CEPH_MSG_MAX_DATA_LEN)
+ return -EIO;
+ data_len = le32_to_cpu(con->in_hdr.data_len);
+ if (data_len > CEPH_MSG_MAX_DATA_LEN)
+ return -EIO;
+ data_off = le16_to_cpu(con->in_hdr.data_off);
+
+ /* allocate message? */
+ if (!con->in_msg) {
+ dout("got hdr type %d front %d data %d\n", con->in_hdr.type,
+ con->in_hdr.front_len, con->in_hdr.data_len);
+ con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip);
+ if (skip) {
+ /* skip this message */
+ dout("alloc_msg returned NULL, skipping message\n");
+ con->in_base_pos = -front_len - middle_len - data_len -
+ sizeof(m->footer);
+ con->in_tag = CEPH_MSGR_TAG_READY;
+ return 0;
+ }
+ if (IS_ERR(con->in_msg)) {
+ ret = PTR_ERR(con->in_msg);
+ con->in_msg = NULL;
+ con->error_msg =
+ "error allocating memory for incoming message";
+ return ret;
+ }
+ m = con->in_msg;
+ m->front.iov_len = 0; /* haven't read it yet */
+ if (m->middle)
+ m->middle->vec.iov_len = 0;
+
+ con->in_msg_pos.page = 0;
+ con->in_msg_pos.page_pos = data_off & ~PAGE_MASK;
+ con->in_msg_pos.data_pos = 0;
+ }
+
+ /* front */
+ ret = read_partial_message_section(con, &m->front, front_len,
+ &con->in_front_crc);
+ if (ret <= 0)
+ return ret;
+
+ /* middle */
+ if (m->middle) {
+ ret = read_partial_message_section(con, &m->middle->vec, middle_len,
+ &con->in_middle_crc);
+ if (ret <= 0)
+ return ret;
+ }
+
+ /* (page) data */
+ while (con->in_msg_pos.data_pos < data_len) {
+ left = min((int)(data_len - con->in_msg_pos.data_pos),
+ (int)(PAGE_SIZE - con->in_msg_pos.page_pos));
+ BUG_ON(m->pages == NULL);
+ p = kmap(m->pages[con->in_msg_pos.page]);
+ ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
+ left);
+ if (ret > 0 && datacrc)
+ con->in_data_crc =
+ crc32c(con->in_data_crc,
+ p + con->in_msg_pos.page_pos, ret);
+ kunmap(m->pages[con->in_msg_pos.page]);
+ if (ret <= 0)
+ return ret;
+ con->in_msg_pos.data_pos += ret;
+ con->in_msg_pos.page_pos += ret;
+ if (con->in_msg_pos.page_pos == PAGE_SIZE) {
+ con->in_msg_pos.page_pos = 0;
+ con->in_msg_pos.page++;
+ }
+ }
+
+ /* footer */
+ to = sizeof(m->hdr) + sizeof(m->footer);
+ while (con->in_base_pos < to) {
+ left = to - con->in_base_pos;
+ ret = ceph_tcp_recvmsg(con->sock, (char *)&m->footer +
+ (con->in_base_pos - sizeof(m->hdr)),
+ left);
+ if (ret <= 0)
+ return ret;
+ con->in_base_pos += ret;
+ }
+ dout("read_partial_message got msg %p %d (%u) + %d (%u) + %d (%u)\n",
+ m, front_len, m->footer.front_crc, middle_len,
+ m->footer.middle_crc, data_len, m->footer.data_crc);
+
+ /* crc ok? */
+ if (con->in_front_crc != le32_to_cpu(m->footer.front_crc)) {
+ pr_err("read_partial_message %p front crc %u != exp. %u\n",
+ m, con->in_front_crc, m->footer.front_crc);
+ return -EBADMSG;
+ }
+ if (con->in_middle_crc != le32_to_cpu(m->footer.middle_crc)) {
+ pr_err("read_partial_message %p middle crc %u != exp %u\n",
+ m, con->in_middle_crc, m->footer.middle_crc);
+ return -EBADMSG;
+ }
+ if (datacrc &&
+ (m->footer.flags & CEPH_MSG_FOOTER_NOCRC) == 0 &&
+ con->in_data_crc != le32_to_cpu(m->footer.data_crc)) {
+ pr_err("read_partial_message %p data crc %u != exp. %u\n", m,
+ con->in_data_crc, le32_to_cpu(m->footer.data_crc));
+ return -EBADMSG;
+ }
+
+ return 1; /* done! */
+}
+
+/*
+ * Process message. This happens in the worker thread. The callback should
+ * be careful not to do anything that waits on other incoming messages or it
+ * may deadlock.
+ */
+static void process_message(struct ceph_connection *con)
+{
+ struct ceph_msg *msg;
+
+ msg = con->in_msg;
+ con->in_msg = NULL;
+
+ /* if first message, set peer_name */
+ if (con->peer_name.type == 0)
+ con->peer_name = msg->hdr.src.name;
+
+ con->in_seq++;
+ mutex_unlock(&con->mutex);
+
+ dout("===== %p %llu from %s%lld %d=%s len %d+%d (%u %u %u) =====\n",
+ msg, le64_to_cpu(msg->hdr.seq),
+ ENTITY_NAME(msg->hdr.src.name),
+ le16_to_cpu(msg->hdr.type),
+ ceph_msg_type_name(le16_to_cpu(msg->hdr.type)),
+ le32_to_cpu(msg->hdr.front_len),
+ le32_to_cpu(msg->hdr.data_len),
+ con->in_front_crc, con->in_middle_crc, con->in_data_crc);
+ con->ops->dispatch(con, msg);
+
+ mutex_lock(&con->mutex);
+ prepare_read_tag(con);
+}
+
+
+/*
+ * Write something to the socket. Called in a worker thread when the
+ * socket appears to be writeable and we have something ready to send.
+ */
+static int try_write(struct ceph_connection *con)
+{
+ struct ceph_messenger *msgr = con->msgr;
+ int ret = 1;
+
+ dout("try_write start %p state %lu nref %d\n", con, con->state,
+ atomic_read(&con->nref));
+
+ mutex_lock(&con->mutex);
+more:
+ dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
+
+ /* open the socket first? */
+ if (con->sock == NULL) {
+ /*
+ * if we were STANDBY and are reconnecting _this_
+ * connection, bump connect_seq now. Always bump
+ * global_seq.
+ */
+ if (test_and_clear_bit(STANDBY, &con->state))
+ con->connect_seq++;
+
+ prepare_write_banner(msgr, con);
+ prepare_write_connect(msgr, con, 1);
+ prepare_read_banner(con);
+ set_bit(CONNECTING, &con->state);
+ clear_bit(NEGOTIATING, &con->state);
+
+ BUG_ON(con->in_msg);
+ con->in_tag = CEPH_MSGR_TAG_READY;
+ dout("try_write initiating connect on %p new state %lu\n",
+ con, con->state);
+ con->sock = ceph_tcp_connect(con);
+ if (IS_ERR(con->sock)) {
+ con->sock = NULL;
+ con->error_msg = "connect error";
+ ret = -1;
+ goto out;
+ }
+ }
+
+more_kvec:
+ /* kvec data queued? */
+ if (con->out_skip) {
+ ret = write_partial_skip(con);
+ if (ret <= 0)
+ goto done;
+ if (ret < 0) {
+ dout("try_write write_partial_skip err %d\n", ret);
+ goto done;
+ }
+ }
+ if (con->out_kvec_left) {
+ ret = write_partial_kvec(con);
+ if (ret <= 0)
+ goto done;
+ }
+
+ /* msg pages? */
+ if (con->out_msg) {
+ if (con->out_msg_done) {
+ ceph_msg_put(con->out_msg);
+ con->out_msg = NULL; /* we're done with this one */
+ goto do_next;
+ }
+
+ ret = write_partial_msg_pages(con);
+ if (ret == 1)
+ goto more_kvec; /* we need to send the footer, too! */
+ if (ret == 0)
+ goto done;
+ if (ret < 0) {
+ dout("try_write write_partial_msg_pages err %d\n",
+ ret);
+ goto done;
+ }
+ }
+
+do_next:
+ if (!test_bit(CONNECTING, &con->state)) {
+ /* is anything else pending? */
+ if (!list_empty(&con->out_queue)) {
+ prepare_write_message(con);
+ goto more;
+ }
+ if (con->in_seq > con->in_seq_acked) {
+ prepare_write_ack(con);
+ goto more;
+ }
+ if (test_and_clear_bit(KEEPALIVE_PENDING, &con->state)) {
+ prepare_write_keepalive(con);
+ goto more;
+ }
+ }
+
+ /* Nothing to do! */
+ clear_bit(WRITE_PENDING, &con->state);
+ dout("try_write nothing else to write.\n");
+done:
+ ret = 0;
+out:
+ mutex_unlock(&con->mutex);
+ dout("try_write done on %p\n", con);
+ return ret;
+}
+
+
+
+/*
+ * Read what we can from the socket.
+ */
+static int try_read(struct ceph_connection *con)
+{
+ struct ceph_messenger *msgr;
+ int ret = -1;
+
+ if (!con->sock)
+ return 0;
+
+ if (test_bit(STANDBY, &con->state))
+ return 0;
+
+ dout("try_read start on %p\n", con);
+ msgr = con->msgr;
+
+ mutex_lock(&con->mutex);
+
+more:
+ dout("try_read tag %d in_base_pos %d\n", (int)con->in_tag,
+ con->in_base_pos);
+ if (test_bit(CONNECTING, &con->state)) {
+ if (!test_bit(NEGOTIATING, &con->state)) {
+ dout("try_read connecting\n");
+ ret = read_partial_banner(con);
+ if (ret <= 0)
+ goto done;
+ if (process_banner(con) < 0) {
+ ret = -1;
+ goto out;
+ }
+ }
+ ret = read_partial_connect(con);
+ if (ret <= 0)
+ goto done;
+ if (process_connect(con) < 0) {
+ ret = -1;
+ goto out;
+ }
+ goto more;
+ }
+
+ if (con->in_base_pos < 0) {
+ /*
+ * skipping + discarding content.
+ *
+ * FIXME: there must be a better way to do this!
+ */
+ static char buf[1024];
+ int skip = min(1024, -con->in_base_pos);
+ dout("skipping %d / %d bytes\n", skip, -con->in_base_pos);
+ ret = ceph_tcp_recvmsg(con->sock, buf, skip);
+ if (ret <= 0)
+ goto done;
+ con->in_base_pos += ret;
+ if (con->in_base_pos)
+ goto more;
+ }
+ if (con->in_tag == CEPH_MSGR_TAG_READY) {
+ /*
+ * what's next?
+ */
+ ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1);
+ if (ret <= 0)
+ goto done;
+ dout("try_read got tag %d\n", (int)con->in_tag);
+ switch (con->in_tag) {
+ case CEPH_MSGR_TAG_MSG:
+ prepare_read_message(con);
+ break;
+ case CEPH_MSGR_TAG_ACK:
+ prepare_read_ack(con);
+ break;
+ case CEPH_MSGR_TAG_CLOSE:
+ set_bit(CLOSED, &con->state); /* fixme */
+ goto done;
+ default:
+ goto bad_tag;
+ }
+ }
+ if (con->in_tag == CEPH_MSGR_TAG_MSG) {
+ ret = read_partial_message(con);
+ if (ret <= 0) {
+ switch (ret) {
+ case -EBADMSG:
+ con->error_msg = "bad crc";
+ ret = -EIO;
+ goto out;
+ case -EIO:
+ con->error_msg = "io error";
+ goto out;
+ default:
+ goto done;
+ }
+ }
+ if (con->in_tag == CEPH_MSGR_TAG_READY)
+ goto more;
+ process_message(con);
+ goto more;
+ }
+ if (con->in_tag == CEPH_MSGR_TAG_ACK) {
+ ret = read_partial_ack(con);
+ if (ret <= 0)
+ goto done;
+ process_ack(con);
+ goto more;
+ }
+
+done:
+ ret = 0;
+out:
+ mutex_unlock(&con->mutex);
+ dout("try_read done on %p\n", con);
+ return ret;
+
+bad_tag:
+ pr_err("try_read bad con->in_tag = %d\n", (int)con->in_tag);
+ con->error_msg = "protocol error, garbage tag";
+ ret = -1;
+ goto out;
+}
+
+
+/*
+ * Atomically queue work on a connection. Bump @con reference to
+ * avoid races with connection teardown.
+ *
+ * There is some trickery going on with QUEUED and BUSY because we
+ * only want a _single_ thread operating on each connection at any
+ * point in time, but we want to use all available CPUs.
+ *
+ * The worker thread only proceeds if it can atomically set BUSY. It
+ * clears QUEUED and does it's thing. When it thinks it's done, it
+ * clears BUSY, then rechecks QUEUED.. if it's set again, it loops
+ * (tries again to set BUSY).
+ *
+ * To queue work, we first set QUEUED, _then_ if BUSY isn't set, we
+ * try to queue work. If that fails (work is already queued, or BUSY)
+ * we give up (work also already being done or is queued) but leave QUEUED
+ * set so that the worker thread will loop if necessary.
+ */
+static void queue_con(struct ceph_connection *con)
+{
+ if (test_bit(DEAD, &con->state)) {
+ dout("queue_con %p ignoring: DEAD\n",
+ con);
+ return;
+ }
+
+ if (!con->ops->get(con)) {
+ dout("queue_con %p ref count 0\n", con);
+ return;
+ }
+
+ set_bit(QUEUED, &con->state);
+ if (test_bit(BUSY, &con->state)) {
+ dout("queue_con %p - already BUSY\n", con);
+ con->ops->put(con);
+ } else if (!queue_work(ceph_msgr_wq, &con->work.work)) {
+ dout("queue_con %p - already queued\n", con);
+ con->ops->put(con);
+ } else {
+ dout("queue_con %p\n", con);
+ }
+}
+
+/*
+ * Do some work on a connection. Drop a connection ref when we're done.
+ */
+static void con_work(struct work_struct *work)
+{
+ struct ceph_connection *con = container_of(work, struct ceph_connection,
+ work.work);
+ int backoff = 0;
+
+more:
+ if (test_and_set_bit(BUSY, &con->state) != 0) {
+ dout("con_work %p BUSY already set\n", con);
+ goto out;
+ }
+ dout("con_work %p start, clearing QUEUED\n", con);
+ clear_bit(QUEUED, &con->state);
+
+ if (test_bit(CLOSED, &con->state)) { /* e.g. if we are replaced */
+ dout("con_work CLOSED\n");
+ con_close_socket(con);
+ goto done;
+ }
+ if (test_and_clear_bit(OPENING, &con->state)) {
+ /* reopen w/ new peer */
+ dout("con_work OPENING\n");
+ con_close_socket(con);
+ }
+
+ if (test_and_clear_bit(SOCK_CLOSED, &con->state) ||
+ try_read(con) < 0 ||
+ try_write(con) < 0) {
+ backoff = 1;
+ ceph_fault(con); /* error/fault path */
+ }
+
+done:
+ clear_bit(BUSY, &con->state);
+ dout("con->state=%lu\n", con->state);
+ if (test_bit(QUEUED, &con->state)) {
+ if (!backoff || test_bit(OPENING, &con->state)) {
+ dout("con_work %p QUEUED reset, looping\n", con);
+ goto more;
+ }
+ dout("con_work %p QUEUED reset, but just faulted\n", con);
+ clear_bit(QUEUED, &con->state);
+ }
+ dout("con_work %p done\n", con);
+
+out:
+ con->ops->put(con);
+}
+
+
+/*
+ * Generic error/fault handler. A retry mechanism is used with
+ * exponential backoff
+ */
+static void ceph_fault(struct ceph_connection *con)
+{
+ pr_err("%s%lld %s %s\n", ENTITY_NAME(con->peer_name),
+ pr_addr(&con->peer_addr.in_addr), con->error_msg);
+ dout("fault %p state %lu to peer %s\n",
+ con, con->state, pr_addr(&con->peer_addr.in_addr));
+
+ if (test_bit(LOSSYTX, &con->state)) {
+ dout("fault on LOSSYTX channel\n");
+ goto out;
+ }
+
+ mutex_lock(&con->mutex);
+ if (test_bit(CLOSED, &con->state))
+ goto out_unlock;
+
+ con_close_socket(con);
+
+ if (con->in_msg) {
+ ceph_msg_put(con->in_msg);
+ con->in_msg = NULL;
+ }
+
+ /* Requeue anything that hasn't been acked */
+ list_splice_init(&con->out_sent, &con->out_queue);
+
+ /* If there are no messages in the queue, place the connection
+ * in a STANDBY state (i.e., don't try to reconnect just yet). */
+ if (list_empty(&con->out_queue) && !con->out_keepalive_pending) {
+ dout("fault setting STANDBY\n");
+ set_bit(STANDBY, &con->state);
+ } else {
+ /* retry after a delay. */
+ if (con->delay == 0)
+ con->delay = BASE_DELAY_INTERVAL;
+ else if (con->delay < MAX_DELAY_INTERVAL)
+ con->delay *= 2;
+ dout("fault queueing %p delay %lu\n", con, con->delay);
+ con->ops->get(con);
+ if (queue_delayed_work(ceph_msgr_wq, &con->work,
+ round_jiffies_relative(con->delay)) == 0)
+ con->ops->put(con);
+ }
+
+out_unlock:
+ mutex_unlock(&con->mutex);
+out:
+ /*
+ * in case we faulted due to authentication, invalidate our
+ * current tickets so that we can get new ones.
+ */
+ if (con->auth_retry && con->ops->invalidate_authorizer) {
+ dout("calling invalidate_authorizer()\n");
+ con->ops->invalidate_authorizer(con);
+ }
+
+ if (con->ops->fault)
+ con->ops->fault(con);
+}
+
+
+
+/*
+ * create a new messenger instance
+ */
+struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr)
+{
+ struct ceph_messenger *msgr;
+
+ msgr = kzalloc(sizeof(*msgr), GFP_KERNEL);
+ if (msgr == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ spin_lock_init(&msgr->global_seq_lock);
+
+ /* the zero page is needed if a request is "canceled" while the message
+ * is being written over the socket */
+ msgr->zero_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ if (!msgr->zero_page) {
+ kfree(msgr);
+ return ERR_PTR(-ENOMEM);
+ }
+ kmap(msgr->zero_page);
+
+ if (myaddr)
+ msgr->inst.addr = *myaddr;
+
+ /* select a random nonce */
+ msgr->inst.addr.type = 0;
+ get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce));
+ encode_my_addr(msgr);
+
+ dout("messenger_create %p\n", msgr);
+ return msgr;
+}
+
+void ceph_messenger_destroy(struct ceph_messenger *msgr)
+{
+ dout("destroy %p\n", msgr);
+ kunmap(msgr->zero_page);
+ __free_page(msgr->zero_page);
+ kfree(msgr);
+ dout("destroyed messenger %p\n", msgr);
+}
+
+/*
+ * Queue up an outgoing message on the given connection.
+ */
+void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg)
+{
+ if (test_bit(CLOSED, &con->state)) {
+ dout("con_send %p closed, dropping %p\n", con, msg);
+ ceph_msg_put(msg);
+ return;
+ }
+
+ /* set src+dst */
+ msg->hdr.src.name = con->msgr->inst.name;
+ msg->hdr.src.addr = con->msgr->my_enc_addr;
+ msg->hdr.orig_src = msg->hdr.src;
+
+ BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len));
+
+ /* queue */
+ mutex_lock(&con->mutex);
+ BUG_ON(!list_empty(&msg->list_head));
+ list_add_tail(&msg->list_head, &con->out_queue);
+ dout("----- %p to %s%lld %d=%s len %d+%d+%d -----\n", msg,
+ ENTITY_NAME(con->peer_name), le16_to_cpu(msg->hdr.type),
+ ceph_msg_type_name(le16_to_cpu(msg->hdr.type)),
+ le32_to_cpu(msg->hdr.front_len),
+ le32_to_cpu(msg->hdr.middle_len),
+ le32_to_cpu(msg->hdr.data_len));
+ mutex_unlock(&con->mutex);
+
+ /* if there wasn't anything waiting to send before, queue
+ * new work */
+ if (test_and_set_bit(WRITE_PENDING, &con->state) == 0)
+ queue_con(con);
+}
+
+/*
+ * Revoke a message that was previously queued for send
+ */
+void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg)
+{
+ mutex_lock(&con->mutex);
+ if (!list_empty(&msg->list_head)) {
+ dout("con_revoke %p msg %p\n", con, msg);
+ list_del_init(&msg->list_head);
+ ceph_msg_put(msg);
+ msg->hdr.seq = 0;
+ if (con->out_msg == msg) {
+ ceph_msg_put(con->out_msg);
+ con->out_msg = NULL;
+ }
+ if (con->out_kvec_is_msg) {
+ con->out_skip = con->out_kvec_bytes;
+ con->out_kvec_is_msg = false;
+ }
+ } else {
+ dout("con_revoke %p msg %p - not queued (sent?)\n", con, msg);
+ }
+ mutex_unlock(&con->mutex);
+}
+
+/*
+ * Revoke a message that we may be reading data into
+ */
+void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg)
+{
+ mutex_lock(&con->mutex);
+ if (con->in_msg && con->in_msg == msg) {
+ unsigned front_len = le32_to_cpu(con->in_hdr.front_len);
+ unsigned middle_len = le32_to_cpu(con->in_hdr.middle_len);
+ unsigned data_len = le32_to_cpu(con->in_hdr.data_len);
+
+ /* skip rest of message */
+ dout("con_revoke_pages %p msg %p revoked\n", con, msg);
+ con->in_base_pos = con->in_base_pos -
+ sizeof(struct ceph_msg_header) -
+ front_len -
+ middle_len -
+ data_len -
+ sizeof(struct ceph_msg_footer);
+ ceph_msg_put(con->in_msg);
+ con->in_msg = NULL;
+ con->in_tag = CEPH_MSGR_TAG_READY;
+ } else {
+ dout("con_revoke_pages %p msg %p pages %p no-op\n",
+ con, con->in_msg, msg);
+ }
+ mutex_unlock(&con->mutex);
+}
+
+/*
+ * Queue a keepalive byte to ensure the tcp connection is alive.
+ */
+void ceph_con_keepalive(struct ceph_connection *con)
+{
+ if (test_and_set_bit(KEEPALIVE_PENDING, &con->state) == 0 &&
+ test_and_set_bit(WRITE_PENDING, &con->state) == 0)
+ queue_con(con);
+}
+
+
+/*
+ * construct a new message with given type, size
+ * the new msg has a ref count of 1.
+ */
+struct ceph_msg *ceph_msg_new(int type, int front_len,
+ int page_len, int page_off, struct page **pages)
+{
+ struct ceph_msg *m;
+
+ m = kmalloc(sizeof(*m), GFP_NOFS);
+ if (m == NULL)
+ goto out;
+ kref_init(&m->kref);
+ INIT_LIST_HEAD(&m->list_head);
+
+ m->hdr.type = cpu_to_le16(type);
+ m->hdr.front_len = cpu_to_le32(front_len);
+ m->hdr.middle_len = 0;
+ m->hdr.data_len = cpu_to_le32(page_len);
+ m->hdr.data_off = cpu_to_le16(page_off);
+ m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT);
+ m->footer.front_crc = 0;
+ m->footer.middle_crc = 0;
+ m->footer.data_crc = 0;
+ m->front_max = front_len;
+ m->front_is_vmalloc = false;
+ m->more_to_follow = false;
+ m->pool = NULL;
+
+ /* front */
+ if (front_len) {
+ if (front_len > PAGE_CACHE_SIZE) {
+ m->front.iov_base = __vmalloc(front_len, GFP_NOFS,
+ PAGE_KERNEL);
+ m->front_is_vmalloc = true;
+ } else {
+ m->front.iov_base = kmalloc(front_len, GFP_NOFS);
+ }
+ if (m->front.iov_base == NULL) {
+ pr_err("msg_new can't allocate %d bytes\n",
+ front_len);
+ goto out2;
+ }
+ } else {
+ m->front.iov_base = NULL;
+ }
+ m->front.iov_len = front_len;
+
+ /* middle */
+ m->middle = NULL;
+
+ /* data */
+ m->nr_pages = calc_pages_for(page_off, page_len);
+ m->pages = pages;
+ m->pagelist = NULL;
+
+ dout("ceph_msg_new %p page %d~%d -> %d\n", m, page_off, page_len,
+ m->nr_pages);
+ return m;
+
+out2:
+ ceph_msg_put(m);
+out:
+ pr_err("msg_new can't create type %d len %d\n", type, front_len);
+ return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * Allocate "middle" portion of a message, if it is needed and wasn't
+ * allocated by alloc_msg. This allows us to read a small fixed-size
+ * per-type header in the front and then gracefully fail (i.e.,
+ * propagate the error to the caller based on info in the front) when
+ * the middle is too large.
+ */
+static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg)
+{
+ int type = le16_to_cpu(msg->hdr.type);
+ int middle_len = le32_to_cpu(msg->hdr.middle_len);
+
+ dout("alloc_middle %p type %d %s middle_len %d\n", msg, type,
+ ceph_msg_type_name(type), middle_len);
+ BUG_ON(!middle_len);
+ BUG_ON(msg->middle);
+
+ msg->middle = ceph_buffer_new(middle_len, GFP_NOFS);
+ if (!msg->middle)
+ return -ENOMEM;
+ return 0;
+}
+
+/*
+ * Generic message allocator, for incoming messages.
+ */
+static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
+ struct ceph_msg_header *hdr,
+ int *skip)
+{
+ int type = le16_to_cpu(hdr->type);
+ int front_len = le32_to_cpu(hdr->front_len);
+ int middle_len = le32_to_cpu(hdr->middle_len);
+ struct ceph_msg *msg = NULL;
+ int ret;
+
+ if (con->ops->alloc_msg) {
+ mutex_unlock(&con->mutex);
+ msg = con->ops->alloc_msg(con, hdr, skip);
+ mutex_lock(&con->mutex);
+ if (IS_ERR(msg))
+ return msg;
+
+ if (*skip)
+ return NULL;
+ }
+ if (!msg) {
+ *skip = 0;
+ msg = ceph_msg_new(type, front_len, 0, 0, NULL);
+ if (!msg) {
+ pr_err("unable to allocate msg type %d len %d\n",
+ type, front_len);
+ return ERR_PTR(-ENOMEM);
+ }
+ }
+ memcpy(&msg->hdr, &con->in_hdr, sizeof(con->in_hdr));
+
+ if (middle_len) {
+ ret = ceph_alloc_middle(con, msg);
+
+ if (ret < 0) {
+ ceph_msg_put(msg);
+ return msg;
+ }
+ }
+
+ return msg;
+}
+
+
+/*
+ * Free a generically kmalloc'd message.
+ */
+void ceph_msg_kfree(struct ceph_msg *m)
+{
+ dout("msg_kfree %p\n", m);
+ if (m->front_is_vmalloc)
+ vfree(m->front.iov_base);
+ else
+ kfree(m->front.iov_base);
+ kfree(m);
+}
+
+/*
+ * Drop a msg ref. Destroy as needed.
+ */
+void ceph_msg_last_put(struct kref *kref)
+{
+ struct ceph_msg *m = container_of(kref, struct ceph_msg, kref);
+
+ dout("ceph_msg_put last one on %p\n", m);
+ WARN_ON(!list_empty(&m->list_head));
+
+ /* drop middle, data, if any */
+ if (m->middle) {
+ ceph_buffer_put(m->middle);
+ m->middle = NULL;
+ }
+ m->nr_pages = 0;
+ m->pages = NULL;
+
+ if (m->pagelist) {
+ ceph_pagelist_release(m->pagelist);
+ kfree(m->pagelist);
+ m->pagelist = NULL;
+ }
+
+ if (m->pool)
+ ceph_msgpool_put(m->pool, m);
+ else
+ ceph_msg_kfree(m);
+}
+
+void ceph_msg_dump(struct ceph_msg *msg)
+{
+ pr_debug("msg_dump %p (front_max %d nr_pages %d)\n", msg,
+ msg->front_max, msg->nr_pages);
+ print_hex_dump(KERN_DEBUG, "header: ",
+ DUMP_PREFIX_OFFSET, 16, 1,
+ &msg->hdr, sizeof(msg->hdr), true);
+ print_hex_dump(KERN_DEBUG, " front: ",
+ DUMP_PREFIX_OFFSET, 16, 1,
+ msg->front.iov_base, msg->front.iov_len, true);
+ if (msg->middle)
+ print_hex_dump(KERN_DEBUG, "middle: ",
+ DUMP_PREFIX_OFFSET, 16, 1,
+ msg->middle->vec.iov_base,
+ msg->middle->vec.iov_len, true);
+ print_hex_dump(KERN_DEBUG, "footer: ",
+ DUMP_PREFIX_OFFSET, 16, 1,
+ &msg->footer, sizeof(msg->footer), true);
+}
diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h
new file mode 100644
index 00000000000..a343dae73cd
--- /dev/null
+++ b/fs/ceph/messenger.h
@@ -0,0 +1,255 @@
+#ifndef __FS_CEPH_MESSENGER_H
+#define __FS_CEPH_MESSENGER_H
+
+#include <linux/kref.h>
+#include <linux/mutex.h>
+#include <linux/net.h>
+#include <linux/radix-tree.h>
+#include <linux/uio.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#include "types.h"
+#include "buffer.h"
+
+struct ceph_msg;
+struct ceph_connection;
+
+extern struct workqueue_struct *ceph_msgr_wq; /* receive work queue */
+
+/*
+ * Ceph defines these callbacks for handling connection events.
+ */
+struct ceph_connection_operations {
+ struct ceph_connection *(*get)(struct ceph_connection *);
+ void (*put)(struct ceph_connection *);
+
+ /* handle an incoming message. */
+ void (*dispatch) (struct ceph_connection *con, struct ceph_msg *m);
+
+ /* authorize an outgoing connection */
+ int (*get_authorizer) (struct ceph_connection *con,
+ void **buf, int *len, int *proto,
+ void **reply_buf, int *reply_len, int force_new);
+ int (*verify_authorizer_reply) (struct ceph_connection *con, int len);
+ int (*invalidate_authorizer)(struct ceph_connection *con);
+
+ /* protocol version mismatch */
+ void (*bad_proto) (struct ceph_connection *con);
+
+ /* there was some error on the socket (disconnect, whatever) */
+ void (*fault) (struct ceph_connection *con);
+
+ /* a remote host as terminated a message exchange session, and messages
+ * we sent (or they tried to send us) may be lost. */
+ void (*peer_reset) (struct ceph_connection *con);
+
+ struct ceph_msg * (*alloc_msg) (struct ceph_connection *con,
+ struct ceph_msg_header *hdr,
+ int *skip);
+};
+
+extern const char *ceph_name_type_str(int t);
+
+/* use format string %s%d */
+#define ENTITY_NAME(n) ceph_name_type_str((n).type), le64_to_cpu((n).num)
+
+struct ceph_messenger {
+ struct ceph_entity_inst inst; /* my name+address */
+ struct ceph_entity_addr my_enc_addr;
+ struct page *zero_page; /* used in certain error cases */
+
+ bool nocrc;
+
+ /*
+ * the global_seq counts connections i (attempt to) initiate
+ * in order to disambiguate certain connect race conditions.
+ */
+ u32 global_seq;
+ spinlock_t global_seq_lock;
+};
+
+/*
+ * a single message. it contains a header (src, dest, message type, etc.),
+ * footer (crc values, mainly), a "front" message body, and possibly a
+ * data payload (stored in some number of pages).
+ */
+struct ceph_msg {
+ struct ceph_msg_header hdr; /* header */
+ struct ceph_msg_footer footer; /* footer */
+ struct kvec front; /* unaligned blobs of message */
+ struct ceph_buffer *middle;
+ struct page **pages; /* data payload. NOT OWNER. */
+ unsigned nr_pages; /* size of page array */
+ struct ceph_pagelist *pagelist; /* instead of pages */
+ struct list_head list_head;
+ struct kref kref;
+ bool front_is_vmalloc;
+ bool more_to_follow;
+ int front_max;
+
+ struct ceph_msgpool *pool;
+};
+
+struct ceph_msg_pos {
+ int page, page_pos; /* which page; offset in page */
+ int data_pos; /* offset in data payload */
+ int did_page_crc; /* true if we've calculated crc for current page */
+};
+
+/* ceph connection fault delay defaults, for exponential backoff */
+#define BASE_DELAY_INTERVAL (HZ/2)
+#define MAX_DELAY_INTERVAL (5 * 60 * HZ)
+
+/*
+ * ceph_connection state bit flags
+ *
+ * QUEUED and BUSY are used together to ensure that only a single
+ * thread is currently opening, reading or writing data to the socket.
+ */
+#define LOSSYTX 0 /* we can close channel or drop messages on errors */
+#define CONNECTING 1
+#define NEGOTIATING 2
+#define KEEPALIVE_PENDING 3
+#define WRITE_PENDING 4 /* we have data ready to send */
+#define QUEUED 5 /* there is work queued on this connection */
+#define BUSY 6 /* work is being done */
+#define STANDBY 8 /* no outgoing messages, socket closed. we keep
+ * the ceph_connection around to maintain shared
+ * state with the peer. */
+#define CLOSED 10 /* we've closed the connection */
+#define SOCK_CLOSED 11 /* socket state changed to closed */
+#define OPENING 13 /* open connection w/ (possibly new) peer */
+#define DEAD 14 /* dead, about to kfree */
+
+/*
+ * A single connection with another host.
+ *
+ * We maintain a queue of outgoing messages, and some session state to
+ * ensure that we can preserve the lossless, ordered delivery of
+ * messages in the case of a TCP disconnect.
+ */
+struct ceph_connection {
+ void *private;
+ atomic_t nref;
+
+ const struct ceph_connection_operations *ops;
+
+ struct ceph_messenger *msgr;
+ struct socket *sock;
+ unsigned long state; /* connection state (see flags above) */
+ const char *error_msg; /* error message, if any */
+
+ struct ceph_entity_addr peer_addr; /* peer address */
+ struct ceph_entity_name peer_name; /* peer name */
+ struct ceph_entity_addr peer_addr_for_me;
+ u32 connect_seq; /* identify the most recent connection
+ attempt for this connection, client */
+ u32 peer_global_seq; /* peer's global seq for this connection */
+
+ int auth_retry; /* true if we need a newer authorizer */
+ void *auth_reply_buf; /* where to put the authorizer reply */
+ int auth_reply_buf_len;
+
+ struct mutex mutex;
+
+ /* out queue */
+ struct list_head out_queue;
+ struct list_head out_sent; /* sending or sent but unacked */
+ u64 out_seq; /* last message queued for send */
+ u64 out_seq_sent; /* last message sent */
+ bool out_keepalive_pending;
+
+ u64 in_seq, in_seq_acked; /* last message received, acked */
+
+ /* connection negotiation temps */
+ char in_banner[CEPH_BANNER_MAX_LEN];
+ union {
+ struct { /* outgoing connection */
+ struct ceph_msg_connect out_connect;
+ struct ceph_msg_connect_reply in_reply;
+ };
+ struct { /* incoming */
+ struct ceph_msg_connect in_connect;
+ struct ceph_msg_connect_reply out_reply;
+ };
+ };
+ struct ceph_entity_addr actual_peer_addr;
+
+ /* message out temps */
+ struct ceph_msg *out_msg; /* sending message (== tail of
+ out_sent) */
+ bool out_msg_done;
+ struct ceph_msg_pos out_msg_pos;
+
+ struct kvec out_kvec[8], /* sending header/footer data */
+ *out_kvec_cur;
+ int out_kvec_left; /* kvec's left in out_kvec */
+ int out_skip; /* skip this many bytes */
+ int out_kvec_bytes; /* total bytes left */
+ bool out_kvec_is_msg; /* kvec refers to out_msg */
+ int out_more; /* there is more data after the kvecs */
+ __le64 out_temp_ack; /* for writing an ack */
+
+ /* message in temps */
+ struct ceph_msg_header in_hdr;
+ struct ceph_msg *in_msg;
+ struct ceph_msg_pos in_msg_pos;
+ u32 in_front_crc, in_middle_crc, in_data_crc; /* calculated crc */
+
+ char in_tag; /* protocol control byte */
+ int in_base_pos; /* bytes read */
+ __le64 in_temp_ack; /* for reading an ack */
+
+ struct delayed_work work; /* send|recv work */
+ unsigned long delay; /* current delay interval */
+};
+
+
+extern const char *pr_addr(const struct sockaddr_storage *ss);
+extern int ceph_parse_ips(const char *c, const char *end,
+ struct ceph_entity_addr *addr,
+ int max_count, int *count);
+
+
+extern int ceph_msgr_init(void);
+extern void ceph_msgr_exit(void);
+
+extern struct ceph_messenger *ceph_messenger_create(
+ struct ceph_entity_addr *myaddr);
+extern void ceph_messenger_destroy(struct ceph_messenger *);
+
+extern void ceph_con_init(struct ceph_messenger *msgr,
+ struct ceph_connection *con);
+extern void ceph_con_open(struct ceph_connection *con,
+ struct ceph_entity_addr *addr);
+extern bool ceph_con_opened(struct ceph_connection *con);
+extern void ceph_con_close(struct ceph_connection *con);
+extern void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg);
+extern void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg);
+extern void ceph_con_revoke_message(struct ceph_connection *con,
+ struct ceph_msg *msg);
+extern void ceph_con_keepalive(struct ceph_connection *con);
+extern struct ceph_connection *ceph_con_get(struct ceph_connection *con);
+extern void ceph_con_put(struct ceph_connection *con);
+
+extern struct ceph_msg *ceph_msg_new(int type, int front_len,
+ int page_len, int page_off,
+ struct page **pages);
+extern void ceph_msg_kfree(struct ceph_msg *m);
+
+
+static inline struct ceph_msg *ceph_msg_get(struct ceph_msg *msg)
+{
+ kref_get(&msg->kref);
+ return msg;
+}
+extern void ceph_msg_last_put(struct kref *kref);
+static inline void ceph_msg_put(struct ceph_msg *msg)
+{
+ kref_put(&msg->kref, ceph_msg_last_put);
+}
+
+extern void ceph_msg_dump(struct ceph_msg *msg);
+
+#endif
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c
new file mode 100644
index 00000000000..8fdc011ca95
--- /dev/null
+++ b/fs/ceph/mon_client.c
@@ -0,0 +1,835 @@
+#include "ceph_debug.h"
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include "mon_client.h"
+#include "super.h"
+#include "auth.h"
+#include "decode.h"
+
+/*
+ * Interact with Ceph monitor cluster. Handle requests for new map
+ * versions, and periodically resend as needed. Also implement
+ * statfs() and umount().
+ *
+ * A small cluster of Ceph "monitors" are responsible for managing critical
+ * cluster configuration and state information. An odd number (e.g., 3, 5)
+ * of cmon daemons use a modified version of the Paxos part-time parliament
+ * algorithm to manage the MDS map (mds cluster membership), OSD map, and
+ * list of clients who have mounted the file system.
+ *
+ * We maintain an open, active session with a monitor at all times in order to
+ * receive timely MDSMap updates. We periodically send a keepalive byte on the
+ * TCP socket to ensure we detect a failure. If the connection does break, we
+ * randomly hunt for a new monitor. Once the connection is reestablished, we
+ * resend any outstanding requests.
+ */
+
+const static struct ceph_connection_operations mon_con_ops;
+
+static int __validate_auth(struct ceph_mon_client *monc);
+
+/*
+ * Decode a monmap blob (e.g., during mount).
+ */
+struct ceph_monmap *ceph_monmap_decode(void *p, void *end)
+{
+ struct ceph_monmap *m = NULL;
+ int i, err = -EINVAL;
+ struct ceph_fsid fsid;
+ u32 epoch, num_mon;
+ u16 version;
+ u32 len;
+
+ ceph_decode_32_safe(&p, end, len, bad);
+ ceph_decode_need(&p, end, len, bad);
+
+ dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p));
+
+ ceph_decode_16_safe(&p, end, version, bad);
+
+ ceph_decode_need(&p, end, sizeof(fsid) + 2*sizeof(u32), bad);
+ ceph_decode_copy(&p, &fsid, sizeof(fsid));
+ epoch = ceph_decode_32(&p);
+
+ num_mon = ceph_decode_32(&p);
+ ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad);
+
+ if (num_mon >= CEPH_MAX_MON)
+ goto bad;
+ m = kmalloc(sizeof(*m) + sizeof(m->mon_inst[0])*num_mon, GFP_NOFS);
+ if (m == NULL)
+ return ERR_PTR(-ENOMEM);
+ m->fsid = fsid;
+ m->epoch = epoch;
+ m->num_mon = num_mon;
+ ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0]));
+ for (i = 0; i < num_mon; i++)
+ ceph_decode_addr(&m->mon_inst[i].addr);
+
+ dout("monmap_decode epoch %d, num_mon %d\n", m->epoch,
+ m->num_mon);
+ for (i = 0; i < m->num_mon; i++)
+ dout("monmap_decode mon%d is %s\n", i,
+ pr_addr(&m->mon_inst[i].addr.in_addr));
+ return m;
+
+bad:
+ dout("monmap_decode failed with %d\n", err);
+ kfree(m);
+ return ERR_PTR(err);
+}
+
+/*
+ * return true if *addr is included in the monmap.
+ */
+int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr)
+{
+ int i;
+
+ for (i = 0; i < m->num_mon; i++)
+ if (memcmp(addr, &m->mon_inst[i].addr, sizeof(*addr)) == 0)
+ return 1;
+ return 0;
+}
+
+/*
+ * Send an auth request.
+ */
+static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
+{
+ monc->pending_auth = 1;
+ monc->m_auth->front.iov_len = len;
+ monc->m_auth->hdr.front_len = cpu_to_le32(len);
+ ceph_msg_get(monc->m_auth); /* keep our ref */
+ ceph_con_send(monc->con, monc->m_auth);
+}
+
+/*
+ * Close monitor session, if any.
+ */
+static void __close_session(struct ceph_mon_client *monc)
+{
+ if (monc->con) {
+ dout("__close_session closing mon%d\n", monc->cur_mon);
+ ceph_con_revoke(monc->con, monc->m_auth);
+ ceph_con_close(monc->con);
+ monc->cur_mon = -1;
+ monc->pending_auth = 0;
+ ceph_auth_reset(monc->auth);
+ }
+}
+
+/*
+ * Open a session with a (new) monitor.
+ */
+static int __open_session(struct ceph_mon_client *monc)
+{
+ char r;
+ int ret;
+
+ if (monc->cur_mon < 0) {
+ get_random_bytes(&r, 1);
+ monc->cur_mon = r % monc->monmap->num_mon;
+ dout("open_session num=%d r=%d -> mon%d\n",
+ monc->monmap->num_mon, r, monc->cur_mon);
+ monc->sub_sent = 0;
+ monc->sub_renew_after = jiffies; /* i.e., expired */
+ monc->want_next_osdmap = !!monc->want_next_osdmap;
+
+ dout("open_session mon%d opening\n", monc->cur_mon);
+ monc->con->peer_name.type = CEPH_ENTITY_TYPE_MON;
+ monc->con->peer_name.num = cpu_to_le64(monc->cur_mon);
+ ceph_con_open(monc->con,
+ &monc->monmap->mon_inst[monc->cur_mon].addr);
+
+ /* initiatiate authentication handshake */
+ ret = ceph_auth_build_hello(monc->auth,
+ monc->m_auth->front.iov_base,
+ monc->m_auth->front_max);
+ __send_prepared_auth_request(monc, ret);
+ } else {
+ dout("open_session mon%d already open\n", monc->cur_mon);
+ }
+ return 0;
+}
+
+static bool __sub_expired(struct ceph_mon_client *monc)
+{
+ return time_after_eq(jiffies, monc->sub_renew_after);
+}
+
+/*
+ * Reschedule delayed work timer.
+ */
+static void __schedule_delayed(struct ceph_mon_client *monc)
+{
+ unsigned delay;
+
+ if (monc->cur_mon < 0 || __sub_expired(monc))
+ delay = 10 * HZ;
+ else
+ delay = 20 * HZ;
+ dout("__schedule_delayed after %u\n", delay);
+ schedule_delayed_work(&monc->delayed_work, delay);
+}
+
+/*
+ * Send subscribe request for mdsmap and/or osdmap.
+ */
+static void __send_subscribe(struct ceph_mon_client *monc)
+{
+ dout("__send_subscribe sub_sent=%u exp=%u want_osd=%d\n",
+ (unsigned)monc->sub_sent, __sub_expired(monc),
+ monc->want_next_osdmap);
+ if ((__sub_expired(monc) && !monc->sub_sent) ||
+ monc->want_next_osdmap == 1) {
+ struct ceph_msg *msg;
+ struct ceph_mon_subscribe_item *i;
+ void *p, *end;
+
+ msg = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, 0, 0, NULL);
+ if (!msg)
+ return;
+
+ p = msg->front.iov_base;
+ end = p + msg->front.iov_len;
+
+ dout("__send_subscribe to 'mdsmap' %u+\n",
+ (unsigned)monc->have_mdsmap);
+ if (monc->want_next_osdmap) {
+ dout("__send_subscribe to 'osdmap' %u\n",
+ (unsigned)monc->have_osdmap);
+ ceph_encode_32(&p, 3);
+ ceph_encode_string(&p, end, "osdmap", 6);
+ i = p;
+ i->have = cpu_to_le64(monc->have_osdmap);
+ i->onetime = 1;
+ p += sizeof(*i);
+ monc->want_next_osdmap = 2; /* requested */
+ } else {
+ ceph_encode_32(&p, 2);
+ }
+ ceph_encode_string(&p, end, "mdsmap", 6);
+ i = p;
+ i->have = cpu_to_le64(monc->have_mdsmap);
+ i->onetime = 0;
+ p += sizeof(*i);
+ ceph_encode_string(&p, end, "monmap", 6);
+ i = p;
+ i->have = 0;
+ i->onetime = 0;
+ p += sizeof(*i);
+
+ msg->front.iov_len = p - msg->front.iov_base;
+ msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+ ceph_con_send(monc->con, msg);
+
+ monc->sub_sent = jiffies | 1; /* never 0 */
+ }
+}
+
+static void handle_subscribe_ack(struct ceph_mon_client *monc,
+ struct ceph_msg *msg)
+{
+ unsigned seconds;
+ struct ceph_mon_subscribe_ack *h = msg->front.iov_base;
+
+ if (msg->front.iov_len < sizeof(*h))
+ goto bad;
+ seconds = le32_to_cpu(h->duration);
+
+ mutex_lock(&monc->mutex);
+ if (monc->hunting) {
+ pr_info("mon%d %s session established\n",
+ monc->cur_mon, pr_addr(&monc->con->peer_addr.in_addr));
+ monc->hunting = false;
+ }
+ dout("handle_subscribe_ack after %d seconds\n", seconds);
+ monc->sub_renew_after = monc->sub_sent + (seconds >> 1)*HZ - 1;
+ monc->sub_sent = 0;
+ mutex_unlock(&monc->mutex);
+ return;
+bad:
+ pr_err("got corrupt subscribe-ack msg\n");
+ ceph_msg_dump(msg);
+}
+
+/*
+ * Keep track of which maps we have
+ */
+int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 got)
+{
+ mutex_lock(&monc->mutex);
+ monc->have_mdsmap = got;
+ mutex_unlock(&monc->mutex);
+ return 0;
+}
+
+int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 got)
+{
+ mutex_lock(&monc->mutex);
+ monc->have_osdmap = got;
+ monc->want_next_osdmap = 0;
+ mutex_unlock(&monc->mutex);
+ return 0;
+}
+
+/*
+ * Register interest in the next osdmap
+ */
+void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc)
+{
+ dout("request_next_osdmap have %u\n", monc->have_osdmap);
+ mutex_lock(&monc->mutex);
+ if (!monc->want_next_osdmap)
+ monc->want_next_osdmap = 1;
+ if (monc->want_next_osdmap < 2)
+ __send_subscribe(monc);
+ mutex_unlock(&monc->mutex);
+}
+
+/*
+ *
+ */
+int ceph_monc_open_session(struct ceph_mon_client *monc)
+{
+ if (!monc->con) {
+ monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL);
+ if (!monc->con)
+ return -ENOMEM;
+ ceph_con_init(monc->client->msgr, monc->con);
+ monc->con->private = monc;
+ monc->con->ops = &mon_con_ops;
+ }
+
+ mutex_lock(&monc->mutex);
+ __open_session(monc);
+ __schedule_delayed(monc);
+ mutex_unlock(&monc->mutex);
+ return 0;
+}
+
+/*
+ * The monitor responds with mount ack indicate mount success. The
+ * included client ticket allows the client to talk to MDSs and OSDs.
+ */
+static void ceph_monc_handle_map(struct ceph_mon_client *monc,
+ struct ceph_msg *msg)
+{
+ struct ceph_client *client = monc->client;
+ struct ceph_monmap *monmap = NULL, *old = monc->monmap;
+ void *p, *end;
+
+ mutex_lock(&monc->mutex);
+
+ dout("handle_monmap\n");
+ p = msg->front.iov_base;
+ end = p + msg->front.iov_len;
+
+ monmap = ceph_monmap_decode(p, end);
+ if (IS_ERR(monmap)) {
+ pr_err("problem decoding monmap, %d\n",
+ (int)PTR_ERR(monmap));
+ goto out;
+ }
+
+ if (ceph_check_fsid(monc->client, &monmap->fsid) < 0) {
+ kfree(monmap);
+ goto out;
+ }
+
+ client->monc.monmap = monmap;
+ kfree(old);
+
+out:
+ mutex_unlock(&monc->mutex);
+ wake_up(&client->auth_wq);
+}
+
+/*
+ * statfs
+ */
+static struct ceph_mon_statfs_request *__lookup_statfs(
+ struct ceph_mon_client *monc, u64 tid)
+{
+ struct ceph_mon_statfs_request *req;
+ struct rb_node *n = monc->statfs_request_tree.rb_node;
+
+ while (n) {
+ req = rb_entry(n, struct ceph_mon_statfs_request, node);
+ if (tid < req->tid)
+ n = n->rb_left;
+ else if (tid > req->tid)
+ n = n->rb_right;
+ else
+ return req;
+ }
+ return NULL;
+}
+
+static void __insert_statfs(struct ceph_mon_client *monc,
+ struct ceph_mon_statfs_request *new)
+{
+ struct rb_node **p = &monc->statfs_request_tree.rb_node;
+ struct rb_node *parent = NULL;
+ struct ceph_mon_statfs_request *req = NULL;
+
+ while (*p) {
+ parent = *p;
+ req = rb_entry(parent, struct ceph_mon_statfs_request, node);
+ if (new->tid < req->tid)
+ p = &(*p)->rb_left;
+ else if (new->tid > req->tid)
+ p = &(*p)->rb_right;
+ else
+ BUG();
+ }
+
+ rb_link_node(&new->node, parent, p);
+ rb_insert_color(&new->node, &monc->statfs_request_tree);
+}
+
+static void handle_statfs_reply(struct ceph_mon_client *monc,
+ struct ceph_msg *msg)
+{
+ struct ceph_mon_statfs_request *req;
+ struct ceph_mon_statfs_reply *reply = msg->front.iov_base;
+ u64 tid;
+
+ if (msg->front.iov_len != sizeof(*reply))
+ goto bad;
+ tid = le64_to_cpu(msg->hdr.tid);
+ dout("handle_statfs_reply %p tid %llu\n", msg, tid);
+
+ mutex_lock(&monc->mutex);
+ req = __lookup_statfs(monc, tid);
+ if (req) {
+ *req->buf = reply->st;
+ req->result = 0;
+ }
+ mutex_unlock(&monc->mutex);
+ if (req)
+ complete(&req->completion);
+ return;
+
+bad:
+ pr_err("corrupt statfs reply, no tid\n");
+ ceph_msg_dump(msg);
+}
+
+/*
+ * (re)send a statfs request
+ */
+static int send_statfs(struct ceph_mon_client *monc,
+ struct ceph_mon_statfs_request *req)
+{
+ struct ceph_msg *msg;
+ struct ceph_mon_statfs *h;
+
+ dout("send_statfs tid %llu\n", req->tid);
+ msg = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL);
+ if (IS_ERR(msg))
+ return PTR_ERR(msg);
+ req->request = msg;
+ msg->hdr.tid = cpu_to_le64(req->tid);
+ h = msg->front.iov_base;
+ h->monhdr.have_version = 0;
+ h->monhdr.session_mon = cpu_to_le16(-1);
+ h->monhdr.session_mon_tid = 0;
+ h->fsid = monc->monmap->fsid;
+ ceph_con_send(monc->con, msg);
+ return 0;
+}
+
+/*
+ * Do a synchronous statfs().
+ */
+int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf)
+{
+ struct ceph_mon_statfs_request req;
+ int err;
+
+ req.buf = buf;
+ init_completion(&req.completion);
+
+ /* allocate memory for reply */
+ err = ceph_msgpool_resv(&monc->msgpool_statfs_reply, 1);
+ if (err)
+ return err;
+
+ /* register request */
+ mutex_lock(&monc->mutex);
+ req.tid = ++monc->last_tid;
+ req.last_attempt = jiffies;
+ req.delay = BASE_DELAY_INTERVAL;
+ __insert_statfs(monc, &req);
+ monc->num_statfs_requests++;
+ mutex_unlock(&monc->mutex);
+
+ /* send request and wait */
+ err = send_statfs(monc, &req);
+ if (!err)
+ err = wait_for_completion_interruptible(&req.completion);
+
+ mutex_lock(&monc->mutex);
+ rb_erase(&req.node, &monc->statfs_request_tree);
+ monc->num_statfs_requests--;
+ ceph_msgpool_resv(&monc->msgpool_statfs_reply, -1);
+ mutex_unlock(&monc->mutex);
+
+ if (!err)
+ err = req.result;
+ return err;
+}
+
+/*
+ * Resend pending statfs requests.
+ */
+static void __resend_statfs(struct ceph_mon_client *monc)
+{
+ struct ceph_mon_statfs_request *req;
+ struct rb_node *p;
+
+ for (p = rb_first(&monc->statfs_request_tree); p; p = rb_next(p)) {
+ req = rb_entry(p, struct ceph_mon_statfs_request, node);
+ send_statfs(monc, req);
+ }
+}
+
+/*
+ * Delayed work. If we haven't mounted yet, retry. Otherwise,
+ * renew/retry subscription as needed (in case it is timing out, or we
+ * got an ENOMEM). And keep the monitor connection alive.
+ */
+static void delayed_work(struct work_struct *work)
+{
+ struct ceph_mon_client *monc =
+ container_of(work, struct ceph_mon_client, delayed_work.work);
+
+ dout("monc delayed_work\n");
+ mutex_lock(&monc->mutex);
+ if (monc->hunting) {
+ __close_session(monc);
+ __open_session(monc); /* continue hunting */
+ } else {
+ ceph_con_keepalive(monc->con);
+
+ __validate_auth(monc);
+
+ if (monc->auth->ops->is_authenticated(monc->auth))
+ __send_subscribe(monc);
+ }
+ __schedule_delayed(monc);
+ mutex_unlock(&monc->mutex);
+}
+
+/*
+ * On startup, we build a temporary monmap populated with the IPs
+ * provided by mount(2).
+ */
+static int build_initial_monmap(struct ceph_mon_client *monc)
+{
+ struct ceph_mount_args *args = monc->client->mount_args;
+ struct ceph_entity_addr *mon_addr = args->mon_addr;
+ int num_mon = args->num_mon;
+ int i;
+
+ /* build initial monmap */
+ monc->monmap = kzalloc(sizeof(*monc->monmap) +
+ num_mon*sizeof(monc->monmap->mon_inst[0]),
+ GFP_KERNEL);
+ if (!monc->monmap)
+ return -ENOMEM;
+ for (i = 0; i < num_mon; i++) {
+ monc->monmap->mon_inst[i].addr = mon_addr[i];
+ monc->monmap->mon_inst[i].addr.nonce = 0;
+ monc->monmap->mon_inst[i].name.type =
+ CEPH_ENTITY_TYPE_MON;
+ monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
+ }
+ monc->monmap->num_mon = num_mon;
+ monc->have_fsid = false;
+
+ /* release addr memory */
+ kfree(args->mon_addr);
+ args->mon_addr = NULL;
+ args->num_mon = 0;
+ return 0;
+}
+
+int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
+{
+ int err = 0;
+
+ dout("init\n");
+ memset(monc, 0, sizeof(*monc));
+ monc->client = cl;
+ monc->monmap = NULL;
+ mutex_init(&monc->mutex);
+
+ err = build_initial_monmap(monc);
+ if (err)
+ goto out;
+
+ monc->con = NULL;
+
+ /* authentication */
+ monc->auth = ceph_auth_init(cl->mount_args->name,
+ cl->mount_args->secret);
+ if (IS_ERR(monc->auth))
+ return PTR_ERR(monc->auth);
+ monc->auth->want_keys =
+ CEPH_ENTITY_TYPE_AUTH | CEPH_ENTITY_TYPE_MON |
+ CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MDS;
+
+ /* msg pools */
+ err = ceph_msgpool_init(&monc->msgpool_subscribe_ack,
+ sizeof(struct ceph_mon_subscribe_ack), 1, false);
+ if (err < 0)
+ goto out_monmap;
+ err = ceph_msgpool_init(&monc->msgpool_statfs_reply,
+ sizeof(struct ceph_mon_statfs_reply), 0, false);
+ if (err < 0)
+ goto out_pool1;
+ err = ceph_msgpool_init(&monc->msgpool_auth_reply, 4096, 1, false);
+ if (err < 0)
+ goto out_pool2;
+
+ monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, 0, 0, NULL);
+ monc->pending_auth = 0;
+ if (IS_ERR(monc->m_auth)) {
+ err = PTR_ERR(monc->m_auth);
+ monc->m_auth = NULL;
+ goto out_pool3;
+ }
+
+ monc->cur_mon = -1;
+ monc->hunting = true;
+ monc->sub_renew_after = jiffies;
+ monc->sub_sent = 0;
+
+ INIT_DELAYED_WORK(&monc->delayed_work, delayed_work);
+ monc->statfs_request_tree = RB_ROOT;
+ monc->num_statfs_requests = 0;
+ monc->last_tid = 0;
+
+ monc->have_mdsmap = 0;
+ monc->have_osdmap = 0;
+ monc->want_next_osdmap = 1;
+ return 0;
+
+out_pool3:
+ ceph_msgpool_destroy(&monc->msgpool_auth_reply);
+out_pool2:
+ ceph_msgpool_destroy(&monc->msgpool_subscribe_ack);
+out_pool1:
+ ceph_msgpool_destroy(&monc->msgpool_statfs_reply);
+out_monmap:
+ kfree(monc->monmap);
+out:
+ return err;
+}
+
+void ceph_monc_stop(struct ceph_mon_client *monc)
+{
+ dout("stop\n");
+ cancel_delayed_work_sync(&monc->delayed_work);
+
+ mutex_lock(&monc->mutex);
+ __close_session(monc);
+ if (monc->con) {
+ monc->con->private = NULL;
+ monc->con->ops->put(monc->con);
+ monc->con = NULL;
+ }
+ mutex_unlock(&monc->mutex);
+
+ ceph_auth_destroy(monc->auth);
+
+ ceph_msg_put(monc->m_auth);
+ ceph_msgpool_destroy(&monc->msgpool_subscribe_ack);
+ ceph_msgpool_destroy(&monc->msgpool_statfs_reply);
+ ceph_msgpool_destroy(&monc->msgpool_auth_reply);
+
+ kfree(monc->monmap);
+}
+
+static void handle_auth_reply(struct ceph_mon_client *monc,
+ struct ceph_msg *msg)
+{
+ int ret;
+
+ mutex_lock(&monc->mutex);
+ monc->pending_auth = 0;
+ ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base,
+ msg->front.iov_len,
+ monc->m_auth->front.iov_base,
+ monc->m_auth->front_max);
+ if (ret < 0) {
+ monc->client->auth_err = ret;
+ wake_up(&monc->client->auth_wq);
+ } else if (ret > 0) {
+ __send_prepared_auth_request(monc, ret);
+ } else if (monc->auth->ops->is_authenticated(monc->auth)) {
+ dout("authenticated, starting session\n");
+
+ monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
+ monc->client->msgr->inst.name.num = monc->auth->global_id;
+
+ __send_subscribe(monc);
+ __resend_statfs(monc);
+ }
+ mutex_unlock(&monc->mutex);
+}
+
+static int __validate_auth(struct ceph_mon_client *monc)
+{
+ int ret;
+
+ if (monc->pending_auth)
+ return 0;
+
+ ret = ceph_build_auth(monc->auth, monc->m_auth->front.iov_base,
+ monc->m_auth->front_max);
+ if (ret <= 0)
+ return ret; /* either an error, or no need to authenticate */
+ __send_prepared_auth_request(monc, ret);
+ return 0;
+}
+
+int ceph_monc_validate_auth(struct ceph_mon_client *monc)
+{
+ int ret;
+
+ mutex_lock(&monc->mutex);
+ ret = __validate_auth(monc);
+ mutex_unlock(&monc->mutex);
+ return ret;
+}
+
+/*
+ * handle incoming message
+ */
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+ struct ceph_mon_client *monc = con->private;
+ int type = le16_to_cpu(msg->hdr.type);
+
+ if (!monc)
+ return;
+
+ switch (type) {
+ case CEPH_MSG_AUTH_REPLY:
+ handle_auth_reply(monc, msg);
+ break;
+
+ case CEPH_MSG_MON_SUBSCRIBE_ACK:
+ handle_subscribe_ack(monc, msg);
+ break;
+
+ case CEPH_MSG_STATFS_REPLY:
+ handle_statfs_reply(monc, msg);
+ break;
+
+ case CEPH_MSG_MON_MAP:
+ ceph_monc_handle_map(monc, msg);
+ break;
+
+ case CEPH_MSG_MDS_MAP:
+ ceph_mdsc_handle_map(&monc->client->mdsc, msg);
+ break;
+
+ case CEPH_MSG_OSD_MAP:
+ ceph_osdc_handle_map(&monc->client->osdc, msg);
+ break;
+
+ default:
+ pr_err("received unknown message type %d %s\n", type,
+ ceph_msg_type_name(type));
+ }
+ ceph_msg_put(msg);
+}
+
+/*
+ * Allocate memory for incoming message
+ */
+static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
+ struct ceph_msg_header *hdr,
+ int *skip)
+{
+ struct ceph_mon_client *monc = con->private;
+ int type = le16_to_cpu(hdr->type);
+ int front_len = le32_to_cpu(hdr->front_len);
+ struct ceph_msg *m = NULL;
+
+ *skip = 0;
+
+ switch (type) {
+ case CEPH_MSG_MON_SUBSCRIBE_ACK:
+ m = ceph_msgpool_get(&monc->msgpool_subscribe_ack, front_len);
+ break;
+ case CEPH_MSG_STATFS_REPLY:
+ m = ceph_msgpool_get(&monc->msgpool_statfs_reply, front_len);
+ break;
+ case CEPH_MSG_AUTH_REPLY:
+ m = ceph_msgpool_get(&monc->msgpool_auth_reply, front_len);
+ break;
+ case CEPH_MSG_MON_MAP:
+ case CEPH_MSG_MDS_MAP:
+ case CEPH_MSG_OSD_MAP:
+ m = ceph_msg_new(type, front_len, 0, 0, NULL);
+ break;
+ }
+
+ if (!m) {
+ pr_info("alloc_msg unknown type %d\n", type);
+ *skip = 1;
+ }
+ return m;
+}
+
+/*
+ * If the monitor connection resets, pick a new monitor and resubmit
+ * any pending requests.
+ */
+static void mon_fault(struct ceph_connection *con)
+{
+ struct ceph_mon_client *monc = con->private;
+
+ if (!monc)
+ return;
+
+ dout("mon_fault\n");
+ mutex_lock(&monc->mutex);
+ if (!con->private)
+ goto out;
+
+ if (monc->con && !monc->hunting)
+ pr_info("mon%d %s session lost, "
+ "hunting for new mon\n", monc->cur_mon,
+ pr_addr(&monc->con->peer_addr.in_addr));
+
+ __close_session(monc);
+ if (!monc->hunting) {
+ /* start hunting */
+ monc->hunting = true;
+ __open_session(monc);
+ } else {
+ /* already hunting, let's wait a bit */
+ __schedule_delayed(monc);
+ }
+out:
+ mutex_unlock(&monc->mutex);
+}
+
+const static struct ceph_connection_operations mon_con_ops = {
+ .get = ceph_con_get,
+ .put = ceph_con_put,
+ .dispatch = dispatch,
+ .fault = mon_fault,
+ .alloc_msg = mon_alloc_msg,
+};
diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h
new file mode 100644
index 00000000000..b958ad5afa0
--- /dev/null
+++ b/fs/ceph/mon_client.h
@@ -0,0 +1,119 @@
+#ifndef _FS_CEPH_MON_CLIENT_H
+#define _FS_CEPH_MON_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/rbtree.h>
+
+#include "messenger.h"
+#include "msgpool.h"
+
+struct ceph_client;
+struct ceph_mount_args;
+struct ceph_auth_client;
+
+/*
+ * The monitor map enumerates the set of all monitors.
+ */
+struct ceph_monmap {
+ struct ceph_fsid fsid;
+ u32 epoch;
+ u32 num_mon;
+ struct ceph_entity_inst mon_inst[0];
+};
+
+struct ceph_mon_client;
+struct ceph_mon_statfs_request;
+
+
+/*
+ * Generic mechanism for resending monitor requests.
+ */
+typedef void (*ceph_monc_request_func_t)(struct ceph_mon_client *monc,
+ int newmon);
+
+/* a pending monitor request */
+struct ceph_mon_request {
+ struct ceph_mon_client *monc;
+ struct delayed_work delayed_work;
+ unsigned long delay;
+ ceph_monc_request_func_t do_request;
+};
+
+/*
+ * statfs() is done a bit differently because we need to get data back
+ * to the caller
+ */
+struct ceph_mon_statfs_request {
+ u64 tid;
+ struct rb_node node;
+ int result;
+ struct ceph_statfs *buf;
+ struct completion completion;
+ unsigned long last_attempt, delay; /* jiffies */
+ struct ceph_msg *request; /* original request */
+};
+
+struct ceph_mon_client {
+ struct ceph_client *client;
+ struct ceph_monmap *monmap;
+
+ struct mutex mutex;
+ struct delayed_work delayed_work;
+
+ struct ceph_auth_client *auth;
+ struct ceph_msg *m_auth;
+ int pending_auth;
+
+ bool hunting;
+ int cur_mon; /* last monitor i contacted */
+ unsigned long sub_sent, sub_renew_after;
+ struct ceph_connection *con;
+ bool have_fsid;
+
+ /* msg pools */
+ struct ceph_msgpool msgpool_subscribe_ack;
+ struct ceph_msgpool msgpool_statfs_reply;
+ struct ceph_msgpool msgpool_auth_reply;
+
+ /* pending statfs requests */
+ struct rb_root statfs_request_tree;
+ int num_statfs_requests;
+ u64 last_tid;
+
+ /* mds/osd map */
+ int want_next_osdmap; /* 1 = want, 2 = want+asked */
+ u32 have_osdmap, have_mdsmap;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_file;
+#endif
+};
+
+extern struct ceph_monmap *ceph_monmap_decode(void *p, void *end);
+extern int ceph_monmap_contains(struct ceph_monmap *m,
+ struct ceph_entity_addr *addr);
+
+extern int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl);
+extern void ceph_monc_stop(struct ceph_mon_client *monc);
+
+/*
+ * The model here is to indicate that we need a new map of at least
+ * epoch @want, and also call in when we receive a map. We will
+ * periodically rerequest the map from the monitor cluster until we
+ * get what we want.
+ */
+extern int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 have);
+extern int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 have);
+
+extern void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc);
+
+extern int ceph_monc_do_statfs(struct ceph_mon_client *monc,
+ struct ceph_statfs *buf);
+
+extern int ceph_monc_open_session(struct ceph_mon_client *monc);
+
+extern int ceph_monc_validate_auth(struct ceph_mon_client *monc);
+
+
+
+#endif
diff --git a/fs/ceph/msgpool.c b/fs/ceph/msgpool.c
new file mode 100644
index 00000000000..ca3b44a89f2
--- /dev/null
+++ b/fs/ceph/msgpool.c
@@ -0,0 +1,186 @@
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include "msgpool.h"
+
+/*
+ * We use msg pools to preallocate memory for messages we expect to
+ * receive over the wire, to avoid getting ourselves into OOM
+ * conditions at unexpected times. We take use a few different
+ * strategies:
+ *
+ * - for request/response type interactions, we preallocate the
+ * memory needed for the response when we generate the request.
+ *
+ * - for messages we can receive at any time from the MDS, we preallocate
+ * a pool of messages we can re-use.
+ *
+ * - for writeback, we preallocate some number of messages to use for
+ * requests and their replies, so that we always make forward
+ * progress.
+ *
+ * The msgpool behaves like a mempool_t, but keeps preallocated
+ * ceph_msgs strung together on a list_head instead of using a pointer
+ * vector. This avoids vector reallocation when we adjust the number
+ * of preallocated items (which happens frequently).
+ */
+
+
+/*
+ * Allocate or release as necessary to meet our target pool size.
+ */
+static int __fill_msgpool(struct ceph_msgpool *pool)
+{
+ struct ceph_msg *msg;
+
+ while (pool->num < pool->min) {
+ dout("fill_msgpool %p %d/%d allocating\n", pool, pool->num,
+ pool->min);
+ spin_unlock(&pool->lock);
+ msg = ceph_msg_new(0, pool->front_len, 0, 0, NULL);
+ spin_lock(&pool->lock);
+ if (IS_ERR(msg))
+ return PTR_ERR(msg);
+ msg->pool = pool;
+ list_add(&msg->list_head, &pool->msgs);
+ pool->num++;
+ }
+ while (pool->num > pool->min) {
+ msg = list_first_entry(&pool->msgs, struct ceph_msg, list_head);
+ dout("fill_msgpool %p %d/%d releasing %p\n", pool, pool->num,
+ pool->min, msg);
+ list_del_init(&msg->list_head);
+ pool->num--;
+ ceph_msg_kfree(msg);
+ }
+ return 0;
+}
+
+int ceph_msgpool_init(struct ceph_msgpool *pool,
+ int front_len, int min, bool blocking)
+{
+ int ret;
+
+ dout("msgpool_init %p front_len %d min %d\n", pool, front_len, min);
+ spin_lock_init(&pool->lock);
+ pool->front_len = front_len;
+ INIT_LIST_HEAD(&pool->msgs);
+ pool->num = 0;
+ pool->min = min;
+ pool->blocking = blocking;
+ init_waitqueue_head(&pool->wait);
+
+ spin_lock(&pool->lock);
+ ret = __fill_msgpool(pool);
+ spin_unlock(&pool->lock);
+ return ret;
+}
+
+void ceph_msgpool_destroy(struct ceph_msgpool *pool)
+{
+ dout("msgpool_destroy %p\n", pool);
+ spin_lock(&pool->lock);
+ pool->min = 0;
+ __fill_msgpool(pool);
+ spin_unlock(&pool->lock);
+}
+
+int ceph_msgpool_resv(struct ceph_msgpool *pool, int delta)
+{
+ int ret;
+
+ spin_lock(&pool->lock);
+ dout("msgpool_resv %p delta %d\n", pool, delta);
+ pool->min += delta;
+ ret = __fill_msgpool(pool);
+ spin_unlock(&pool->lock);
+ return ret;
+}
+
+struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len)
+{
+ wait_queue_t wait;
+ struct ceph_msg *msg;
+
+ if (front_len && front_len > pool->front_len) {
+ pr_err("msgpool_get pool %p need front %d, pool size is %d\n",
+ pool, front_len, pool->front_len);
+ WARN_ON(1);
+
+ /* try to alloc a fresh message */
+ msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+ if (!IS_ERR(msg))
+ return msg;
+ }
+
+ if (!front_len)
+ front_len = pool->front_len;
+
+ if (pool->blocking) {
+ /* mempool_t behavior; first try to alloc */
+ msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+ if (!IS_ERR(msg))
+ return msg;
+ }
+
+ while (1) {
+ spin_lock(&pool->lock);
+ if (likely(pool->num)) {
+ msg = list_entry(pool->msgs.next, struct ceph_msg,
+ list_head);
+ list_del_init(&msg->list_head);
+ pool->num--;
+ dout("msgpool_get %p got %p, now %d/%d\n", pool, msg,
+ pool->num, pool->min);
+ spin_unlock(&pool->lock);
+ return msg;
+ }
+ pr_err("msgpool_get %p now %d/%d, %s\n", pool, pool->num,
+ pool->min, pool->blocking ? "waiting" : "may fail");
+ spin_unlock(&pool->lock);
+
+ if (!pool->blocking) {
+ WARN_ON(1);
+
+ /* maybe we can allocate it now? */
+ msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+ if (!IS_ERR(msg))
+ return msg;
+
+ pr_err("msgpool_get %p empty + alloc failed\n", pool);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init_wait(&wait);
+ prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);
+ schedule();
+ finish_wait(&pool->wait, &wait);
+ }
+}
+
+void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
+{
+ spin_lock(&pool->lock);
+ if (pool->num < pool->min) {
+ /* reset msg front_len; user may have changed it */
+ msg->front.iov_len = pool->front_len;
+ msg->hdr.front_len = cpu_to_le32(pool->front_len);
+
+ kref_set(&msg->kref, 1); /* retake a single ref */
+ list_add(&msg->list_head, &pool->msgs);
+ pool->num++;
+ dout("msgpool_put %p reclaim %p, now %d/%d\n", pool, msg,
+ pool->num, pool->min);
+ spin_unlock(&pool->lock);
+ wake_up(&pool->wait);
+ } else {
+ dout("msgpool_put %p drop %p, at %d/%d\n", pool, msg,
+ pool->num, pool->min);
+ spin_unlock(&pool->lock);
+ ceph_msg_kfree(msg);
+ }
+}
diff --git a/fs/ceph/msgpool.h b/fs/ceph/msgpool.h
new file mode 100644
index 00000000000..bc834bfcd72
--- /dev/null
+++ b/fs/ceph/msgpool.h
@@ -0,0 +1,27 @@
+#ifndef _FS_CEPH_MSGPOOL
+#define _FS_CEPH_MSGPOOL
+
+#include "messenger.h"
+
+/*
+ * we use memory pools for preallocating messages we may receive, to
+ * avoid unexpected OOM conditions.
+ */
+struct ceph_msgpool {
+ spinlock_t lock;
+ int front_len; /* preallocated payload size */
+ struct list_head msgs; /* msgs in the pool; each has 1 ref */
+ int num, min; /* cur, min # msgs in the pool */
+ bool blocking;
+ wait_queue_head_t wait;
+};
+
+extern int ceph_msgpool_init(struct ceph_msgpool *pool,
+ int front_len, int size, bool blocking);
+extern void ceph_msgpool_destroy(struct ceph_msgpool *pool);
+extern int ceph_msgpool_resv(struct ceph_msgpool *, int delta);
+extern struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *,
+ int front_len);
+extern void ceph_msgpool_put(struct ceph_msgpool *, struct ceph_msg *);
+
+#endif
diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h
new file mode 100644
index 00000000000..8aaab414f3f
--- /dev/null
+++ b/fs/ceph/msgr.h
@@ -0,0 +1,158 @@
+#ifndef __MSGR_H
+#define __MSGR_H
+
+/*
+ * Data types for message passing layer used by Ceph.
+ */
+
+#define CEPH_MON_PORT 6789 /* default monitor port */
+
+/*
+ * client-side processes will try to bind to ports in this
+ * range, simply for the benefit of tools like nmap or wireshark
+ * that would like to identify the protocol.
+ */
+#define CEPH_PORT_FIRST 6789
+#define CEPH_PORT_START 6800 /* non-monitors start here */
+#define CEPH_PORT_LAST 6900
+
+/*
+ * tcp connection banner. include a protocol version. and adjust
+ * whenever the wire protocol changes. try to keep this string length
+ * constant.
+ */
+#define CEPH_BANNER "ceph v027"
+#define CEPH_BANNER_MAX_LEN 30
+
+
+/*
+ * Rollover-safe type and comparator for 32-bit sequence numbers.
+ * Comparator returns -1, 0, or 1.
+ */
+typedef __u32 ceph_seq_t;
+
+static inline __s32 ceph_seq_cmp(__u32 a, __u32 b)
+{
+ return (__s32)a - (__s32)b;
+}
+
+
+/*
+ * entity_name -- logical name for a process participating in the
+ * network, e.g. 'mds0' or 'osd3'.
+ */
+struct ceph_entity_name {
+ __u8 type; /* CEPH_ENTITY_TYPE_* */
+ __le64 num;
+} __attribute__ ((packed));
+
+#define CEPH_ENTITY_TYPE_MON 0x01
+#define CEPH_ENTITY_TYPE_MDS 0x02
+#define CEPH_ENTITY_TYPE_OSD 0x04
+#define CEPH_ENTITY_TYPE_CLIENT 0x08
+#define CEPH_ENTITY_TYPE_ADMIN 0x10
+#define CEPH_ENTITY_TYPE_AUTH 0x20
+
+#define CEPH_ENTITY_TYPE_ANY 0xFF
+
+extern const char *ceph_entity_type_name(int type);
+
+/*
+ * entity_addr -- network address
+ */
+struct ceph_entity_addr {
+ __le32 type;
+ __le32 nonce; /* unique id for process (e.g. pid) */
+ struct sockaddr_storage in_addr;
+} __attribute__ ((packed));
+
+struct ceph_entity_inst {
+ struct ceph_entity_name name;
+ struct ceph_entity_addr addr;
+} __attribute__ ((packed));
+
+
+/* used by message exchange protocol */
+#define CEPH_MSGR_TAG_READY 1 /* server->client: ready for messages */
+#define CEPH_MSGR_TAG_RESETSESSION 2 /* server->client: reset, try again */
+#define CEPH_MSGR_TAG_WAIT 3 /* server->client: wait for racing
+ incoming connection */
+#define CEPH_MSGR_TAG_RETRY_SESSION 4 /* server->client + cseq: try again
+ with higher cseq */
+#define CEPH_MSGR_TAG_RETRY_GLOBAL 5 /* server->client + gseq: try again
+ with higher gseq */
+#define CEPH_MSGR_TAG_CLOSE 6 /* closing pipe */
+#define CEPH_MSGR_TAG_MSG 7 /* message */
+#define CEPH_MSGR_TAG_ACK 8 /* message ack */
+#define CEPH_MSGR_TAG_KEEPALIVE 9 /* just a keepalive byte! */
+#define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */
+#define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */
+#define CEPH_MSGR_TAG_FEATURES 12 /* insufficient features */
+
+
+/*
+ * connection negotiation
+ */
+struct ceph_msg_connect {
+ __le64 features; /* supported feature bits */
+ __le32 host_type; /* CEPH_ENTITY_TYPE_* */
+ __le32 global_seq; /* count connections initiated by this host */
+ __le32 connect_seq; /* count connections initiated in this session */
+ __le32 protocol_version;
+ __le32 authorizer_protocol;
+ __le32 authorizer_len;
+ __u8 flags; /* CEPH_MSG_CONNECT_* */
+} __attribute__ ((packed));
+
+struct ceph_msg_connect_reply {
+ __u8 tag;
+ __le64 features; /* feature bits for this session */
+ __le32 global_seq;
+ __le32 connect_seq;
+ __le32 protocol_version;
+ __le32 authorizer_len;
+ __u8 flags;
+} __attribute__ ((packed));
+
+#define CEPH_MSG_CONNECT_LOSSY 1 /* messages i send may be safely dropped */
+
+
+/*
+ * message header
+ */
+struct ceph_msg_header {
+ __le64 seq; /* message seq# for this session */
+ __le64 tid; /* transaction id */
+ __le16 type; /* message type */
+ __le16 priority; /* priority. higher value == higher priority */
+ __le16 version; /* version of message encoding */
+
+ __le32 front_len; /* bytes in main payload */
+ __le32 middle_len;/* bytes in middle payload */
+ __le32 data_len; /* bytes of data payload */
+ __le16 data_off; /* sender: include full offset;
+ receiver: mask against ~PAGE_MASK */
+
+ struct ceph_entity_inst src, orig_src;
+ __le32 reserved;
+ __le32 crc; /* header crc32c */
+} __attribute__ ((packed));
+
+#define CEPH_MSG_PRIO_LOW 64
+#define CEPH_MSG_PRIO_DEFAULT 127
+#define CEPH_MSG_PRIO_HIGH 196
+#define CEPH_MSG_PRIO_HIGHEST 255
+
+/*
+ * follows data payload
+ */
+struct ceph_msg_footer {
+ __le32 front_crc, middle_crc, data_crc;
+ __u8 flags;
+} __attribute__ ((packed));
+
+#define CEPH_MSG_FOOTER_COMPLETE (1<<0) /* msg wasn't aborted */
+#define CEPH_MSG_FOOTER_NOCRC (1<<1) /* no data crc */
+
+
+#endif
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c
new file mode 100644
index 00000000000..c7b4dedaace
--- /dev/null
+++ b/fs/ceph/osd_client.c
@@ -0,0 +1,1550 @@
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "super.h"
+#include "osd_client.h"
+#include "messenger.h"
+#include "decode.h"
+#include "auth.h"
+
+#define OSD_OP_FRONT_LEN 4096
+#define OSD_OPREPLY_FRONT_LEN 512
+
+const static struct ceph_connection_operations osd_con_ops;
+static int __kick_requests(struct ceph_osd_client *osdc,
+ struct ceph_osd *kickosd);
+
+static void kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *osd);
+
+/*
+ * Implement client access to distributed object storage cluster.
+ *
+ * All data objects are stored within a cluster/cloud of OSDs, or
+ * "object storage devices." (Note that Ceph OSDs have _nothing_ to
+ * do with the T10 OSD extensions to SCSI.) Ceph OSDs are simply
+ * remote daemons serving up and coordinating consistent and safe
+ * access to storage.
+ *
+ * Cluster membership and the mapping of data objects onto storage devices
+ * are described by the osd map.
+ *
+ * We keep track of pending OSD requests (read, write), resubmit
+ * requests to different OSDs when the cluster topology/data layout
+ * change, or retry the affected requests when the communications
+ * channel with an OSD is reset.
+ */
+
+/*
+ * calculate the mapping of a file extent onto an object, and fill out the
+ * request accordingly. shorten extent as necessary if it crosses an
+ * object boundary.
+ *
+ * fill osd op in request message.
+ */
+static void calc_layout(struct ceph_osd_client *osdc,
+ struct ceph_vino vino, struct ceph_file_layout *layout,
+ u64 off, u64 *plen,
+ struct ceph_osd_request *req)
+{
+ struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
+ struct ceph_osd_op *op = (void *)(reqhead + 1);
+ u64 orig_len = *plen;
+ u64 objoff, objlen; /* extent in object */
+ u64 bno;
+
+ reqhead->snapid = cpu_to_le64(vino.snap);
+
+ /* object extent? */
+ ceph_calc_file_object_mapping(layout, off, plen, &bno,
+ &objoff, &objlen);
+ if (*plen < orig_len)
+ dout(" skipping last %llu, final file extent %llu~%llu\n",
+ orig_len - *plen, off, *plen);
+
+ sprintf(req->r_oid, "%llx.%08llx", vino.ino, bno);
+ req->r_oid_len = strlen(req->r_oid);
+
+ op->extent.offset = cpu_to_le64(objoff);
+ op->extent.length = cpu_to_le64(objlen);
+ req->r_num_pages = calc_pages_for(off, *plen);
+
+ dout("calc_layout %s (%d) %llu~%llu (%d pages)\n",
+ req->r_oid, req->r_oid_len, objoff, objlen, req->r_num_pages);
+}
+
+/*
+ * requests
+ */
+void ceph_osdc_release_request(struct kref *kref)
+{
+ struct ceph_osd_request *req = container_of(kref,
+ struct ceph_osd_request,
+ r_kref);
+
+ if (req->r_request)
+ ceph_msg_put(req->r_request);
+ if (req->r_reply)
+ ceph_msg_put(req->r_reply);
+ if (req->r_con_filling_msg) {
+ dout("release_request revoking pages %p from con %p\n",
+ req->r_pages, req->r_con_filling_msg);
+ ceph_con_revoke_message(req->r_con_filling_msg,
+ req->r_reply);
+ ceph_con_put(req->r_con_filling_msg);
+ }
+ if (req->r_own_pages)
+ ceph_release_page_vector(req->r_pages,
+ req->r_num_pages);
+ ceph_put_snap_context(req->r_snapc);
+ if (req->r_mempool)
+ mempool_free(req, req->r_osdc->req_mempool);
+ else
+ kfree(req);
+}
+
+/*
+ * build new request AND message, calculate layout, and adjust file
+ * extent as needed.
+ *
+ * if the file was recently truncated, we include information about its
+ * old and new size so that the object can be updated appropriately. (we
+ * avoid synchronously deleting truncated objects because it's slow.)
+ *
+ * if @do_sync, include a 'startsync' command so that the osd will flush
+ * data quickly.
+ */
+struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
+ struct ceph_file_layout *layout,
+ struct ceph_vino vino,
+ u64 off, u64 *plen,
+ int opcode, int flags,
+ struct ceph_snap_context *snapc,
+ int do_sync,
+ u32 truncate_seq,
+ u64 truncate_size,
+ struct timespec *mtime,
+ bool use_mempool, int num_reply)
+{
+ struct ceph_osd_request *req;
+ struct ceph_msg *msg;
+ struct ceph_osd_request_head *head;
+ struct ceph_osd_op *op;
+ void *p;
+ int num_op = 1 + do_sync;
+ size_t msg_size = sizeof(*head) + num_op*sizeof(*op);
+ int i;
+
+ if (use_mempool) {
+ req = mempool_alloc(osdc->req_mempool, GFP_NOFS);
+ memset(req, 0, sizeof(*req));
+ } else {
+ req = kzalloc(sizeof(*req), GFP_NOFS);
+ }
+ if (req == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ req->r_osdc = osdc;
+ req->r_mempool = use_mempool;
+ kref_init(&req->r_kref);
+ init_completion(&req->r_completion);
+ init_completion(&req->r_safe_completion);
+ INIT_LIST_HEAD(&req->r_unsafe_item);
+ req->r_flags = flags;
+
+ WARN_ON((flags & (CEPH_OSD_FLAG_READ|CEPH_OSD_FLAG_WRITE)) == 0);
+
+ /* create reply message */
+ if (use_mempool)
+ msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
+ else
+ msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY,
+ OSD_OPREPLY_FRONT_LEN, 0, 0, NULL);
+ if (IS_ERR(msg)) {
+ ceph_osdc_put_request(req);
+ return ERR_PTR(PTR_ERR(msg));
+ }
+ req->r_reply = msg;
+
+ /* create request message; allow space for oid */
+ msg_size += 40;
+ if (snapc)
+ msg_size += sizeof(u64) * snapc->num_snaps;
+ if (use_mempool)
+ msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
+ else
+ msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, 0, 0, NULL);
+ if (IS_ERR(msg)) {
+ ceph_osdc_put_request(req);
+ return ERR_PTR(PTR_ERR(msg));
+ }
+ msg->hdr.type = cpu_to_le16(CEPH_MSG_OSD_OP);
+ memset(msg->front.iov_base, 0, msg->front.iov_len);
+ head = msg->front.iov_base;
+ op = (void *)(head + 1);
+ p = (void *)(op + num_op);
+
+ req->r_request = msg;
+ req->r_snapc = ceph_get_snap_context(snapc);
+
+ head->client_inc = cpu_to_le32(1); /* always, for now. */
+ head->flags = cpu_to_le32(flags);
+ if (flags & CEPH_OSD_FLAG_WRITE)
+ ceph_encode_timespec(&head->mtime, mtime);
+ head->num_ops = cpu_to_le16(num_op);
+ op->op = cpu_to_le16(opcode);
+
+ /* calculate max write size */
+ calc_layout(osdc, vino, layout, off, plen, req);
+ req->r_file_layout = *layout; /* keep a copy */
+
+ if (flags & CEPH_OSD_FLAG_WRITE) {
+ req->r_request->hdr.data_off = cpu_to_le16(off);
+ req->r_request->hdr.data_len = cpu_to_le32(*plen);
+ op->payload_len = cpu_to_le32(*plen);
+ }
+ op->extent.truncate_size = cpu_to_le64(truncate_size);
+ op->extent.truncate_seq = cpu_to_le32(truncate_seq);
+
+ /* fill in oid */
+ head->object_len = cpu_to_le32(req->r_oid_len);
+ memcpy(p, req->r_oid, req->r_oid_len);
+ p += req->r_oid_len;
+
+ if (do_sync) {
+ op++;
+ op->op = cpu_to_le16(CEPH_OSD_OP_STARTSYNC);
+ }
+ if (snapc) {
+ head->snap_seq = cpu_to_le64(snapc->seq);
+ head->num_snaps = cpu_to_le32(snapc->num_snaps);
+ for (i = 0; i < snapc->num_snaps; i++) {
+ put_unaligned_le64(snapc->snaps[i], p);
+ p += sizeof(u64);
+ }
+ }
+
+ BUG_ON(p > msg->front.iov_base + msg->front.iov_len);
+ msg_size = p - msg->front.iov_base;
+ msg->front.iov_len = msg_size;
+ msg->hdr.front_len = cpu_to_le32(msg_size);
+ return req;
+}
+
+/*
+ * We keep osd requests in an rbtree, sorted by ->r_tid.
+ */
+static void __insert_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *new)
+{
+ struct rb_node **p = &osdc->requests.rb_node;
+ struct rb_node *parent = NULL;
+ struct ceph_osd_request *req = NULL;
+
+ while (*p) {
+ parent = *p;
+ req = rb_entry(parent, struct ceph_osd_request, r_node);
+ if (new->r_tid < req->r_tid)
+ p = &(*p)->rb_left;
+ else if (new->r_tid > req->r_tid)
+ p = &(*p)->rb_right;
+ else
+ BUG();
+ }
+
+ rb_link_node(&new->r_node, parent, p);
+ rb_insert_color(&new->r_node, &osdc->requests);
+}
+
+static struct ceph_osd_request *__lookup_request(struct ceph_osd_client *osdc,
+ u64 tid)
+{
+ struct ceph_osd_request *req;
+ struct rb_node *n = osdc->requests.rb_node;
+
+ while (n) {
+ req = rb_entry(n, struct ceph_osd_request, r_node);
+ if (tid < req->r_tid)
+ n = n->rb_left;
+ else if (tid > req->r_tid)
+ n = n->rb_right;
+ else
+ return req;
+ }
+ return NULL;
+}
+
+static struct ceph_osd_request *
+__lookup_request_ge(struct ceph_osd_client *osdc,
+ u64 tid)
+{
+ struct ceph_osd_request *req;
+ struct rb_node *n = osdc->requests.rb_node;
+
+ while (n) {
+ req = rb_entry(n, struct ceph_osd_request, r_node);
+ if (tid < req->r_tid) {
+ if (!n->rb_left)
+ return req;
+ n = n->rb_left;
+ } else if (tid > req->r_tid) {
+ n = n->rb_right;
+ } else {
+ return req;
+ }
+ }
+ return NULL;
+}
+
+
+/*
+ * If the osd connection drops, we need to resubmit all requests.
+ */
+static void osd_reset(struct ceph_connection *con)
+{
+ struct ceph_osd *osd = con->private;
+ struct ceph_osd_client *osdc;
+
+ if (!osd)
+ return;
+ dout("osd_reset osd%d\n", osd->o_osd);
+ osdc = osd->o_osdc;
+ down_read(&osdc->map_sem);
+ kick_requests(osdc, osd);
+ up_read(&osdc->map_sem);
+}
+
+/*
+ * Track open sessions with osds.
+ */
+static struct ceph_osd *create_osd(struct ceph_osd_client *osdc)
+{
+ struct ceph_osd *osd;
+
+ osd = kzalloc(sizeof(*osd), GFP_NOFS);
+ if (!osd)
+ return NULL;
+
+ atomic_set(&osd->o_ref, 1);
+ osd->o_osdc = osdc;
+ INIT_LIST_HEAD(&osd->o_requests);
+ INIT_LIST_HEAD(&osd->o_osd_lru);
+ osd->o_incarnation = 1;
+
+ ceph_con_init(osdc->client->msgr, &osd->o_con);
+ osd->o_con.private = osd;
+ osd->o_con.ops = &osd_con_ops;
+ osd->o_con.peer_name.type = CEPH_ENTITY_TYPE_OSD;
+
+ INIT_LIST_HEAD(&osd->o_keepalive_item);
+ return osd;
+}
+
+static struct ceph_osd *get_osd(struct ceph_osd *osd)
+{
+ if (atomic_inc_not_zero(&osd->o_ref)) {
+ dout("get_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref)-1,
+ atomic_read(&osd->o_ref));
+ return osd;
+ } else {
+ dout("get_osd %p FAIL\n", osd);
+ return NULL;
+ }
+}
+
+static void put_osd(struct ceph_osd *osd)
+{
+ dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref),
+ atomic_read(&osd->o_ref) - 1);
+ if (atomic_dec_and_test(&osd->o_ref))
+ kfree(osd);
+}
+
+/*
+ * remove an osd from our map
+ */
+static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
+{
+ dout("__remove_osd %p\n", osd);
+ BUG_ON(!list_empty(&osd->o_requests));
+ rb_erase(&osd->o_node, &osdc->osds);
+ list_del_init(&osd->o_osd_lru);
+ ceph_con_close(&osd->o_con);
+ put_osd(osd);
+}
+
+static void __move_osd_to_lru(struct ceph_osd_client *osdc,
+ struct ceph_osd *osd)
+{
+ dout("__move_osd_to_lru %p\n", osd);
+ BUG_ON(!list_empty(&osd->o_osd_lru));
+ list_add_tail(&osd->o_osd_lru, &osdc->osd_lru);
+ osd->lru_ttl = jiffies + osdc->client->mount_args->osd_idle_ttl * HZ;
+}
+
+static void __remove_osd_from_lru(struct ceph_osd *osd)
+{
+ dout("__remove_osd_from_lru %p\n", osd);
+ if (!list_empty(&osd->o_osd_lru))
+ list_del_init(&osd->o_osd_lru);
+}
+
+static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all)
+{
+ struct ceph_osd *osd, *nosd;
+
+ dout("__remove_old_osds %p\n", osdc);
+ mutex_lock(&osdc->request_mutex);
+ list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) {
+ if (!remove_all && time_before(jiffies, osd->lru_ttl))
+ break;
+ __remove_osd(osdc, osd);
+ }
+ mutex_unlock(&osdc->request_mutex);
+}
+
+/*
+ * reset osd connect
+ */
+static int __reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
+{
+ struct ceph_osd_request *req;
+ int ret = 0;
+
+ dout("__reset_osd %p osd%d\n", osd, osd->o_osd);
+ if (list_empty(&osd->o_requests)) {
+ __remove_osd(osdc, osd);
+ } else if (memcmp(&osdc->osdmap->osd_addr[osd->o_osd],
+ &osd->o_con.peer_addr,
+ sizeof(osd->o_con.peer_addr)) == 0 &&
+ !ceph_con_opened(&osd->o_con)) {
+ dout(" osd addr hasn't changed and connection never opened,"
+ " letting msgr retry");
+ /* touch each r_stamp for handle_timeout()'s benfit */
+ list_for_each_entry(req, &osd->o_requests, r_osd_item)
+ req->r_stamp = jiffies;
+ ret = -EAGAIN;
+ } else {
+ ceph_con_close(&osd->o_con);
+ ceph_con_open(&osd->o_con, &osdc->osdmap->osd_addr[osd->o_osd]);
+ osd->o_incarnation++;
+ }
+ return ret;
+}
+
+static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new)
+{
+ struct rb_node **p = &osdc->osds.rb_node;
+ struct rb_node *parent = NULL;
+ struct ceph_osd *osd = NULL;
+
+ while (*p) {
+ parent = *p;
+ osd = rb_entry(parent, struct ceph_osd, o_node);
+ if (new->o_osd < osd->o_osd)
+ p = &(*p)->rb_left;
+ else if (new->o_osd > osd->o_osd)
+ p = &(*p)->rb_right;
+ else
+ BUG();
+ }
+
+ rb_link_node(&new->o_node, parent, p);
+ rb_insert_color(&new->o_node, &osdc->osds);
+}
+
+static struct ceph_osd *__lookup_osd(struct ceph_osd_client *osdc, int o)
+{
+ struct ceph_osd *osd;
+ struct rb_node *n = osdc->osds.rb_node;
+
+ while (n) {
+ osd = rb_entry(n, struct ceph_osd, o_node);
+ if (o < osd->o_osd)
+ n = n->rb_left;
+ else if (o > osd->o_osd)
+ n = n->rb_right;
+ else
+ return osd;
+ }
+ return NULL;
+}
+
+static void __schedule_osd_timeout(struct ceph_osd_client *osdc)
+{
+ schedule_delayed_work(&osdc->timeout_work,
+ osdc->client->mount_args->osd_keepalive_timeout * HZ);
+}
+
+static void __cancel_osd_timeout(struct ceph_osd_client *osdc)
+{
+ cancel_delayed_work(&osdc->timeout_work);
+}
+
+/*
+ * Register request, assign tid. If this is the first request, set up
+ * the timeout event.
+ */
+static void register_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req)
+{
+ mutex_lock(&osdc->request_mutex);
+ req->r_tid = ++osdc->last_tid;
+ req->r_request->hdr.tid = cpu_to_le64(req->r_tid);
+ INIT_LIST_HEAD(&req->r_req_lru_item);
+
+ dout("register_request %p tid %lld\n", req, req->r_tid);
+ __insert_request(osdc, req);
+ ceph_osdc_get_request(req);
+ osdc->num_requests++;
+
+ if (osdc->num_requests == 1) {
+ dout(" first request, scheduling timeout\n");
+ __schedule_osd_timeout(osdc);
+ }
+ mutex_unlock(&osdc->request_mutex);
+}
+
+/*
+ * called under osdc->request_mutex
+ */
+static void __unregister_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req)
+{
+ dout("__unregister_request %p tid %lld\n", req, req->r_tid);
+ rb_erase(&req->r_node, &osdc->requests);
+ osdc->num_requests--;
+
+ if (req->r_osd) {
+ /* make sure the original request isn't in flight. */
+ ceph_con_revoke(&req->r_osd->o_con, req->r_request);
+
+ list_del_init(&req->r_osd_item);
+ if (list_empty(&req->r_osd->o_requests))
+ __move_osd_to_lru(osdc, req->r_osd);
+ req->r_osd = NULL;
+ }
+
+ ceph_osdc_put_request(req);
+
+ list_del_init(&req->r_req_lru_item);
+ if (osdc->num_requests == 0) {
+ dout(" no requests, canceling timeout\n");
+ __cancel_osd_timeout(osdc);
+ }
+}
+
+/*
+ * Cancel a previously queued request message
+ */
+static void __cancel_request(struct ceph_osd_request *req)
+{
+ if (req->r_sent) {
+ ceph_con_revoke(&req->r_osd->o_con, req->r_request);
+ req->r_sent = 0;
+ }
+ list_del_init(&req->r_req_lru_item);
+}
+
+/*
+ * Pick an osd (the first 'up' osd in the pg), allocate the osd struct
+ * (as needed), and set the request r_osd appropriately. If there is
+ * no up osd, set r_osd to NULL.
+ *
+ * Return 0 if unchanged, 1 if changed, or negative on error.
+ *
+ * Caller should hold map_sem for read and request_mutex.
+ */
+static int __map_osds(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req)
+{
+ struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
+ struct ceph_pg pgid;
+ int o = -1;
+ int err;
+
+ dout("map_osds %p tid %lld\n", req, req->r_tid);
+ err = ceph_calc_object_layout(&reqhead->layout, req->r_oid,
+ &req->r_file_layout, osdc->osdmap);
+ if (err)
+ return err;
+ pgid = reqhead->layout.ol_pgid;
+ req->r_pgid = pgid;
+
+ o = ceph_calc_pg_primary(osdc->osdmap, pgid);
+
+ if ((req->r_osd && req->r_osd->o_osd == o &&
+ req->r_sent >= req->r_osd->o_incarnation) ||
+ (req->r_osd == NULL && o == -1))
+ return 0; /* no change */
+
+ dout("map_osds tid %llu pgid %d.%x osd%d (was osd%d)\n",
+ req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o,
+ req->r_osd ? req->r_osd->o_osd : -1);
+
+ if (req->r_osd) {
+ __cancel_request(req);
+ list_del_init(&req->r_osd_item);
+ req->r_osd = NULL;
+ }
+
+ req->r_osd = __lookup_osd(osdc, o);
+ if (!req->r_osd && o >= 0) {
+ err = -ENOMEM;
+ req->r_osd = create_osd(osdc);
+ if (!req->r_osd)
+ goto out;
+
+ dout("map_osds osd %p is osd%d\n", req->r_osd, o);
+ req->r_osd->o_osd = o;
+ req->r_osd->o_con.peer_name.num = cpu_to_le64(o);
+ __insert_osd(osdc, req->r_osd);
+
+ ceph_con_open(&req->r_osd->o_con, &osdc->osdmap->osd_addr[o]);
+ }
+
+ if (req->r_osd) {
+ __remove_osd_from_lru(req->r_osd);
+ list_add(&req->r_osd_item, &req->r_osd->o_requests);
+ }
+ err = 1; /* osd changed */
+
+out:
+ return err;
+}
+
+/*
+ * caller should hold map_sem (for read) and request_mutex
+ */
+static int __send_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req)
+{
+ struct ceph_osd_request_head *reqhead;
+ int err;
+
+ err = __map_osds(osdc, req);
+ if (err < 0)
+ return err;
+ if (req->r_osd == NULL) {
+ dout("send_request %p no up osds in pg\n", req);
+ ceph_monc_request_next_osdmap(&osdc->client->monc);
+ return 0;
+ }
+
+ dout("send_request %p tid %llu to osd%d flags %d\n",
+ req, req->r_tid, req->r_osd->o_osd, req->r_flags);
+
+ reqhead = req->r_request->front.iov_base;
+ reqhead->osdmap_epoch = cpu_to_le32(osdc->osdmap->epoch);
+ reqhead->flags |= cpu_to_le32(req->r_flags); /* e.g., RETRY */
+ reqhead->reassert_version = req->r_reassert_version;
+
+ req->r_stamp = jiffies;
+ list_move_tail(&osdc->req_lru, &req->r_req_lru_item);
+
+ ceph_msg_get(req->r_request); /* send consumes a ref */
+ ceph_con_send(&req->r_osd->o_con, req->r_request);
+ req->r_sent = req->r_osd->o_incarnation;
+ return 0;
+}
+
+/*
+ * Timeout callback, called every N seconds when 1 or more osd
+ * requests has been active for more than N seconds. When this
+ * happens, we ping all OSDs with requests who have timed out to
+ * ensure any communications channel reset is detected. Reset the
+ * request timeouts another N seconds in the future as we go.
+ * Reschedule the timeout event another N seconds in future (unless
+ * there are no open requests).
+ */
+static void handle_timeout(struct work_struct *work)
+{
+ struct ceph_osd_client *osdc =
+ container_of(work, struct ceph_osd_client, timeout_work.work);
+ struct ceph_osd_request *req, *last_req = NULL;
+ struct ceph_osd *osd;
+ unsigned long timeout = osdc->client->mount_args->osd_timeout * HZ;
+ unsigned long keepalive =
+ osdc->client->mount_args->osd_keepalive_timeout * HZ;
+ unsigned long last_stamp = 0;
+ struct rb_node *p;
+ struct list_head slow_osds;
+
+ dout("timeout\n");
+ down_read(&osdc->map_sem);
+
+ ceph_monc_request_next_osdmap(&osdc->client->monc);
+
+ mutex_lock(&osdc->request_mutex);
+ for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+ req = rb_entry(p, struct ceph_osd_request, r_node);
+
+ if (req->r_resend) {
+ int err;
+
+ dout("osdc resending prev failed %lld\n", req->r_tid);
+ err = __send_request(osdc, req);
+ if (err)
+ dout("osdc failed again on %lld\n", req->r_tid);
+ else
+ req->r_resend = false;
+ continue;
+ }
+ }
+
+ /*
+ * reset osds that appear to be _really_ unresponsive. this
+ * is a failsafe measure.. we really shouldn't be getting to
+ * this point if the system is working properly. the monitors
+ * should mark the osd as failed and we should find out about
+ * it from an updated osd map.
+ */
+ while (!list_empty(&osdc->req_lru)) {
+ req = list_entry(osdc->req_lru.next, struct ceph_osd_request,
+ r_req_lru_item);
+
+ if (time_before(jiffies, req->r_stamp + timeout))
+ break;
+
+ BUG_ON(req == last_req && req->r_stamp == last_stamp);
+ last_req = req;
+ last_stamp = req->r_stamp;
+
+ osd = req->r_osd;
+ BUG_ON(!osd);
+ pr_warning(" tid %llu timed out on osd%d, will reset osd\n",
+ req->r_tid, osd->o_osd);
+ __kick_requests(osdc, osd);
+ }
+
+ /*
+ * ping osds that are a bit slow. this ensures that if there
+ * is a break in the TCP connection we will notice, and reopen
+ * a connection with that osd (from the fault callback).
+ */
+ INIT_LIST_HEAD(&slow_osds);
+ list_for_each_entry(req, &osdc->req_lru, r_req_lru_item) {
+ if (time_before(jiffies, req->r_stamp + keepalive))
+ break;
+
+ osd = req->r_osd;
+ BUG_ON(!osd);
+ dout(" tid %llu is slow, will send keepalive on osd%d\n",
+ req->r_tid, osd->o_osd);
+ list_move_tail(&osd->o_keepalive_item, &slow_osds);
+ }
+ while (!list_empty(&slow_osds)) {
+ osd = list_entry(slow_osds.next, struct ceph_osd,
+ o_keepalive_item);
+ list_del_init(&osd->o_keepalive_item);
+ ceph_con_keepalive(&osd->o_con);
+ }
+
+ __schedule_osd_timeout(osdc);
+ mutex_unlock(&osdc->request_mutex);
+
+ up_read(&osdc->map_sem);
+}
+
+static void handle_osds_timeout(struct work_struct *work)
+{
+ struct ceph_osd_client *osdc =
+ container_of(work, struct ceph_osd_client,
+ osds_timeout_work.work);
+ unsigned long delay =
+ osdc->client->mount_args->osd_idle_ttl * HZ >> 2;
+
+ dout("osds timeout\n");
+ down_read(&osdc->map_sem);
+ remove_old_osds(osdc, 0);
+ up_read(&osdc->map_sem);
+
+ schedule_delayed_work(&osdc->osds_timeout_work,
+ round_jiffies_relative(delay));
+}
+
+/*
+ * handle osd op reply. either call the callback if it is specified,
+ * or do the completion to wake up the waiting thread.
+ */
+static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
+ struct ceph_connection *con)
+{
+ struct ceph_osd_reply_head *rhead = msg->front.iov_base;
+ struct ceph_osd_request *req;
+ u64 tid;
+ int numops, object_len, flags;
+
+ tid = le64_to_cpu(msg->hdr.tid);
+ if (msg->front.iov_len < sizeof(*rhead))
+ goto bad;
+ numops = le32_to_cpu(rhead->num_ops);
+ object_len = le32_to_cpu(rhead->object_len);
+ if (msg->front.iov_len != sizeof(*rhead) + object_len +
+ numops * sizeof(struct ceph_osd_op))
+ goto bad;
+ dout("handle_reply %p tid %llu\n", msg, tid);
+
+ /* lookup */
+ mutex_lock(&osdc->request_mutex);
+ req = __lookup_request(osdc, tid);
+ if (req == NULL) {
+ dout("handle_reply tid %llu dne\n", tid);
+ mutex_unlock(&osdc->request_mutex);
+ return;
+ }
+ ceph_osdc_get_request(req);
+ flags = le32_to_cpu(rhead->flags);
+
+ /*
+ * if this connection filled our message, drop our reference now, to
+ * avoid a (safe but slower) revoke later.
+ */
+ if (req->r_con_filling_msg == con && req->r_reply == msg) {
+ dout(" dropping con_filling_msg ref %p\n", con);
+ req->r_con_filling_msg = NULL;
+ ceph_con_put(con);
+ }
+
+ if (!req->r_got_reply) {
+ unsigned bytes;
+
+ req->r_result = le32_to_cpu(rhead->result);
+ bytes = le32_to_cpu(msg->hdr.data_len);
+ dout("handle_reply result %d bytes %d\n", req->r_result,
+ bytes);
+ if (req->r_result == 0)
+ req->r_result = bytes;
+
+ /* in case this is a write and we need to replay, */
+ req->r_reassert_version = rhead->reassert_version;
+
+ req->r_got_reply = 1;
+ } else if ((flags & CEPH_OSD_FLAG_ONDISK) == 0) {
+ dout("handle_reply tid %llu dup ack\n", tid);
+ mutex_unlock(&osdc->request_mutex);
+ goto done;
+ }
+
+ dout("handle_reply tid %llu flags %d\n", tid, flags);
+
+ /* either this is a read, or we got the safe response */
+ if ((flags & CEPH_OSD_FLAG_ONDISK) ||
+ ((flags & CEPH_OSD_FLAG_WRITE) == 0))
+ __unregister_request(osdc, req);
+
+ mutex_unlock(&osdc->request_mutex);
+
+ if (req->r_callback)
+ req->r_callback(req, msg);
+ else
+ complete(&req->r_completion);
+
+ if (flags & CEPH_OSD_FLAG_ONDISK) {
+ if (req->r_safe_callback)
+ req->r_safe_callback(req, msg);
+ complete(&req->r_safe_completion); /* fsync waiter */
+ }
+
+done:
+ ceph_osdc_put_request(req);
+ return;
+
+bad:
+ pr_err("corrupt osd_op_reply got %d %d expected %d\n",
+ (int)msg->front.iov_len, le32_to_cpu(msg->hdr.front_len),
+ (int)sizeof(*rhead));
+ ceph_msg_dump(msg);
+}
+
+
+static int __kick_requests(struct ceph_osd_client *osdc,
+ struct ceph_osd *kickosd)
+{
+ struct ceph_osd_request *req;
+ struct rb_node *p, *n;
+ int needmap = 0;
+ int err;
+
+ dout("kick_requests osd%d\n", kickosd ? kickosd->o_osd : -1);
+ if (kickosd) {
+ err = __reset_osd(osdc, kickosd);
+ if (err == -EAGAIN)
+ return 1;
+ } else {
+ for (p = rb_first(&osdc->osds); p; p = n) {
+ struct ceph_osd *osd =
+ rb_entry(p, struct ceph_osd, o_node);
+
+ n = rb_next(p);
+ if (!ceph_osd_is_up(osdc->osdmap, osd->o_osd) ||
+ memcmp(&osd->o_con.peer_addr,
+ ceph_osd_addr(osdc->osdmap,
+ osd->o_osd),
+ sizeof(struct ceph_entity_addr)) != 0)
+ __reset_osd(osdc, osd);
+ }
+ }
+
+ for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+ req = rb_entry(p, struct ceph_osd_request, r_node);
+
+ if (req->r_resend) {
+ dout(" r_resend set on tid %llu\n", req->r_tid);
+ __cancel_request(req);
+ goto kick;
+ }
+ if (req->r_osd && kickosd == req->r_osd) {
+ __cancel_request(req);
+ goto kick;
+ }
+
+ err = __map_osds(osdc, req);
+ if (err == 0)
+ continue; /* no change */
+ if (err < 0) {
+ /*
+ * FIXME: really, we should set the request
+ * error and fail if this isn't a 'nofail'
+ * request, but that's a fair bit more
+ * complicated to do. So retry!
+ */
+ dout(" setting r_resend on %llu\n", req->r_tid);
+ req->r_resend = true;
+ continue;
+ }
+ if (req->r_osd == NULL) {
+ dout("tid %llu maps to no valid osd\n", req->r_tid);
+ needmap++; /* request a newer map */
+ continue;
+ }
+
+kick:
+ dout("kicking %p tid %llu osd%d\n", req, req->r_tid,
+ req->r_osd ? req->r_osd->o_osd : -1);
+ req->r_flags |= CEPH_OSD_FLAG_RETRY;
+ err = __send_request(osdc, req);
+ if (err) {
+ dout(" setting r_resend on %llu\n", req->r_tid);
+ req->r_resend = true;
+ }
+ }
+
+ return needmap;
+}
+
+/*
+ * Resubmit osd requests whose osd or osd address has changed. Request
+ * a new osd map if osds are down, or we are otherwise unable to determine
+ * how to direct a request.
+ *
+ * Close connections to down osds.
+ *
+ * If @who is specified, resubmit requests for that specific osd.
+ *
+ * Caller should hold map_sem for read and request_mutex.
+ */
+static void kick_requests(struct ceph_osd_client *osdc,
+ struct ceph_osd *kickosd)
+{
+ int needmap;
+
+ mutex_lock(&osdc->request_mutex);
+ needmap = __kick_requests(osdc, kickosd);
+ mutex_unlock(&osdc->request_mutex);
+
+ if (needmap) {
+ dout("%d requests for down osds, need new map\n", needmap);
+ ceph_monc_request_next_osdmap(&osdc->client->monc);
+ }
+
+}
+/*
+ * Process updated osd map.
+ *
+ * The message contains any number of incremental and full maps, normally
+ * indicating some sort of topology change in the cluster. Kick requests
+ * off to different OSDs as needed.
+ */
+void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
+{
+ void *p, *end, *next;
+ u32 nr_maps, maplen;
+ u32 epoch;
+ struct ceph_osdmap *newmap = NULL, *oldmap;
+ int err;
+ struct ceph_fsid fsid;
+
+ dout("handle_map have %u\n", osdc->osdmap ? osdc->osdmap->epoch : 0);
+ p = msg->front.iov_base;
+ end = p + msg->front.iov_len;
+
+ /* verify fsid */
+ ceph_decode_need(&p, end, sizeof(fsid), bad);
+ ceph_decode_copy(&p, &fsid, sizeof(fsid));
+ if (ceph_check_fsid(osdc->client, &fsid) < 0)
+ return;
+
+ down_write(&osdc->map_sem);
+
+ /* incremental maps */
+ ceph_decode_32_safe(&p, end, nr_maps, bad);
+ dout(" %d inc maps\n", nr_maps);
+ while (nr_maps > 0) {
+ ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+ epoch = ceph_decode_32(&p);
+ maplen = ceph_decode_32(&p);
+ ceph_decode_need(&p, end, maplen, bad);
+ next = p + maplen;
+ if (osdc->osdmap && osdc->osdmap->epoch+1 == epoch) {
+ dout("applying incremental map %u len %d\n",
+ epoch, maplen);
+ newmap = osdmap_apply_incremental(&p, next,
+ osdc->osdmap,
+ osdc->client->msgr);
+ if (IS_ERR(newmap)) {
+ err = PTR_ERR(newmap);
+ goto bad;
+ }
+ BUG_ON(!newmap);
+ if (newmap != osdc->osdmap) {
+ ceph_osdmap_destroy(osdc->osdmap);
+ osdc->osdmap = newmap;
+ }
+ } else {
+ dout("ignoring incremental map %u len %d\n",
+ epoch, maplen);
+ }
+ p = next;
+ nr_maps--;
+ }
+ if (newmap)
+ goto done;
+
+ /* full maps */
+ ceph_decode_32_safe(&p, end, nr_maps, bad);
+ dout(" %d full maps\n", nr_maps);
+ while (nr_maps) {
+ ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+ epoch = ceph_decode_32(&p);
+ maplen = ceph_decode_32(&p);
+ ceph_decode_need(&p, end, maplen, bad);
+ if (nr_maps > 1) {
+ dout("skipping non-latest full map %u len %d\n",
+ epoch, maplen);
+ } else if (osdc->osdmap && osdc->osdmap->epoch >= epoch) {
+ dout("skipping full map %u len %d, "
+ "older than our %u\n", epoch, maplen,
+ osdc->osdmap->epoch);
+ } else {
+ dout("taking full map %u len %d\n", epoch, maplen);
+ newmap = osdmap_decode(&p, p+maplen);
+ if (IS_ERR(newmap)) {
+ err = PTR_ERR(newmap);
+ goto bad;
+ }
+ BUG_ON(!newmap);
+ oldmap = osdc->osdmap;
+ osdc->osdmap = newmap;
+ if (oldmap)
+ ceph_osdmap_destroy(oldmap);
+ }
+ p += maplen;
+ nr_maps--;
+ }
+
+done:
+ downgrade_write(&osdc->map_sem);
+ ceph_monc_got_osdmap(&osdc->client->monc, osdc->osdmap->epoch);
+ if (newmap)
+ kick_requests(osdc, NULL);
+ up_read(&osdc->map_sem);
+ return;
+
+bad:
+ pr_err("osdc handle_map corrupt msg\n");
+ ceph_msg_dump(msg);
+ up_write(&osdc->map_sem);
+ return;
+}
+
+
+/*
+ * A read request prepares specific pages that data is to be read into.
+ * When a message is being read off the wire, we call prepare_pages to
+ * find those pages.
+ * 0 = success, -1 failure.
+ */
+static int __prepare_pages(struct ceph_connection *con,
+ struct ceph_msg_header *hdr,
+ struct ceph_osd_request *req,
+ u64 tid,
+ struct ceph_msg *m)
+{
+ struct ceph_osd *osd = con->private;
+ struct ceph_osd_client *osdc;
+ int ret = -1;
+ int data_len = le32_to_cpu(hdr->data_len);
+ unsigned data_off = le16_to_cpu(hdr->data_off);
+
+ int want = calc_pages_for(data_off & ~PAGE_MASK, data_len);
+
+ if (!osd)
+ return -1;
+
+ osdc = osd->o_osdc;
+
+ dout("__prepare_pages on msg %p tid %llu, has %d pages, want %d\n", m,
+ tid, req->r_num_pages, want);
+ if (unlikely(req->r_num_pages < want))
+ goto out;
+ m->pages = req->r_pages;
+ m->nr_pages = req->r_num_pages;
+ ret = 0; /* success */
+out:
+ BUG_ON(ret < 0 || m->nr_pages < want);
+
+ return ret;
+}
+
+/*
+ * Register request, send initial attempt.
+ */
+int ceph_osdc_start_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req,
+ bool nofail)
+{
+ int rc = 0;
+
+ req->r_request->pages = req->r_pages;
+ req->r_request->nr_pages = req->r_num_pages;
+
+ register_request(osdc, req);
+
+ down_read(&osdc->map_sem);
+ mutex_lock(&osdc->request_mutex);
+ /*
+ * a racing kick_requests() may have sent the message for us
+ * while we dropped request_mutex above, so only send now if
+ * the request still han't been touched yet.
+ */
+ if (req->r_sent == 0) {
+ rc = __send_request(osdc, req);
+ if (rc) {
+ if (nofail) {
+ dout("osdc_start_request failed send, "
+ " marking %lld\n", req->r_tid);
+ req->r_resend = true;
+ rc = 0;
+ } else {
+ __unregister_request(osdc, req);
+ }
+ }
+ }
+ mutex_unlock(&osdc->request_mutex);
+ up_read(&osdc->map_sem);
+ return rc;
+}
+
+/*
+ * wait for a request to complete
+ */
+int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req)
+{
+ int rc;
+
+ rc = wait_for_completion_interruptible(&req->r_completion);
+ if (rc < 0) {
+ mutex_lock(&osdc->request_mutex);
+ __cancel_request(req);
+ __unregister_request(osdc, req);
+ mutex_unlock(&osdc->request_mutex);
+ dout("wait_request tid %llu canceled/timed out\n", req->r_tid);
+ return rc;
+ }
+
+ dout("wait_request tid %llu result %d\n", req->r_tid, req->r_result);
+ return req->r_result;
+}
+
+/*
+ * sync - wait for all in-flight requests to flush. avoid starvation.
+ */
+void ceph_osdc_sync(struct ceph_osd_client *osdc)
+{
+ struct ceph_osd_request *req;
+ u64 last_tid, next_tid = 0;
+
+ mutex_lock(&osdc->request_mutex);
+ last_tid = osdc->last_tid;
+ while (1) {
+ req = __lookup_request_ge(osdc, next_tid);
+ if (!req)
+ break;
+ if (req->r_tid > last_tid)
+ break;
+
+ next_tid = req->r_tid + 1;
+ if ((req->r_flags & CEPH_OSD_FLAG_WRITE) == 0)
+ continue;
+
+ ceph_osdc_get_request(req);
+ mutex_unlock(&osdc->request_mutex);
+ dout("sync waiting on tid %llu (last is %llu)\n",
+ req->r_tid, last_tid);
+ wait_for_completion(&req->r_safe_completion);
+ mutex_lock(&osdc->request_mutex);
+ ceph_osdc_put_request(req);
+ }
+ mutex_unlock(&osdc->request_mutex);
+ dout("sync done (thru tid %llu)\n", last_tid);
+}
+
+/*
+ * init, shutdown
+ */
+int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
+{
+ int err;
+
+ dout("init\n");
+ osdc->client = client;
+ osdc->osdmap = NULL;
+ init_rwsem(&osdc->map_sem);
+ init_completion(&osdc->map_waiters);
+ osdc->last_requested_map = 0;
+ mutex_init(&osdc->request_mutex);
+ osdc->last_tid = 0;
+ osdc->osds = RB_ROOT;
+ INIT_LIST_HEAD(&osdc->osd_lru);
+ osdc->requests = RB_ROOT;
+ INIT_LIST_HEAD(&osdc->req_lru);
+ osdc->num_requests = 0;
+ INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout);
+ INIT_DELAYED_WORK(&osdc->osds_timeout_work, handle_osds_timeout);
+
+ schedule_delayed_work(&osdc->osds_timeout_work,
+ round_jiffies_relative(osdc->client->mount_args->osd_idle_ttl * HZ));
+
+ err = -ENOMEM;
+ osdc->req_mempool = mempool_create_kmalloc_pool(10,
+ sizeof(struct ceph_osd_request));
+ if (!osdc->req_mempool)
+ goto out;
+
+ err = ceph_msgpool_init(&osdc->msgpool_op, OSD_OP_FRONT_LEN, 10, true);
+ if (err < 0)
+ goto out_mempool;
+ err = ceph_msgpool_init(&osdc->msgpool_op_reply,
+ OSD_OPREPLY_FRONT_LEN, 10, true);
+ if (err < 0)
+ goto out_msgpool;
+ return 0;
+
+out_msgpool:
+ ceph_msgpool_destroy(&osdc->msgpool_op);
+out_mempool:
+ mempool_destroy(osdc->req_mempool);
+out:
+ return err;
+}
+
+void ceph_osdc_stop(struct ceph_osd_client *osdc)
+{
+ cancel_delayed_work_sync(&osdc->timeout_work);
+ cancel_delayed_work_sync(&osdc->osds_timeout_work);
+ if (osdc->osdmap) {
+ ceph_osdmap_destroy(osdc->osdmap);
+ osdc->osdmap = NULL;
+ }
+ remove_old_osds(osdc, 1);
+ mempool_destroy(osdc->req_mempool);
+ ceph_msgpool_destroy(&osdc->msgpool_op);
+ ceph_msgpool_destroy(&osdc->msgpool_op_reply);
+}
+
+/*
+ * Read some contiguous pages. If we cross a stripe boundary, shorten
+ * *plen. Return number of bytes read, or error.
+ */
+int ceph_osdc_readpages(struct ceph_osd_client *osdc,
+ struct ceph_vino vino, struct ceph_file_layout *layout,
+ u64 off, u64 *plen,
+ u32 truncate_seq, u64 truncate_size,
+ struct page **pages, int num_pages)
+{
+ struct ceph_osd_request *req;
+ int rc = 0;
+
+ dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino,
+ vino.snap, off, *plen);
+ req = ceph_osdc_new_request(osdc, layout, vino, off, plen,
+ CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
+ NULL, 0, truncate_seq, truncate_size, NULL,
+ false, 1);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+ /* it may be a short read due to an object boundary */
+ req->r_pages = pages;
+ num_pages = calc_pages_for(off, *plen);
+ req->r_num_pages = num_pages;
+
+ dout("readpages final extent is %llu~%llu (%d pages)\n",
+ off, *plen, req->r_num_pages);
+
+ rc = ceph_osdc_start_request(osdc, req, false);
+ if (!rc)
+ rc = ceph_osdc_wait_request(osdc, req);
+
+ ceph_osdc_put_request(req);
+ dout("readpages result %d\n", rc);
+ return rc;
+}
+
+/*
+ * do a synchronous write on N pages
+ */
+int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
+ struct ceph_file_layout *layout,
+ struct ceph_snap_context *snapc,
+ u64 off, u64 len,
+ u32 truncate_seq, u64 truncate_size,
+ struct timespec *mtime,
+ struct page **pages, int num_pages,
+ int flags, int do_sync, bool nofail)
+{
+ struct ceph_osd_request *req;
+ int rc = 0;
+
+ BUG_ON(vino.snap != CEPH_NOSNAP);
+ req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
+ CEPH_OSD_OP_WRITE,
+ flags | CEPH_OSD_FLAG_ONDISK |
+ CEPH_OSD_FLAG_WRITE,
+ snapc, do_sync,
+ truncate_seq, truncate_size, mtime,
+ nofail, 1);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+ /* it may be a short write due to an object boundary */
+ req->r_pages = pages;
+ req->r_num_pages = calc_pages_for(off, len);
+ dout("writepages %llu~%llu (%d pages)\n", off, len,
+ req->r_num_pages);
+
+ rc = ceph_osdc_start_request(osdc, req, nofail);
+ if (!rc)
+ rc = ceph_osdc_wait_request(osdc, req);
+
+ ceph_osdc_put_request(req);
+ if (rc == 0)
+ rc = len;
+ dout("writepages result %d\n", rc);
+ return rc;
+}
+
+/*
+ * handle incoming message
+ */
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+ struct ceph_osd *osd = con->private;
+ struct ceph_osd_client *osdc;
+ int type = le16_to_cpu(msg->hdr.type);
+
+ if (!osd)
+ return;
+ osdc = osd->o_osdc;
+
+ switch (type) {
+ case CEPH_MSG_OSD_MAP:
+ ceph_osdc_handle_map(osdc, msg);
+ break;
+ case CEPH_MSG_OSD_OPREPLY:
+ handle_reply(osdc, msg, con);
+ break;
+
+ default:
+ pr_err("received unknown message type %d %s\n", type,
+ ceph_msg_type_name(type));
+ }
+ ceph_msg_put(msg);
+}
+
+/*
+ * lookup and return message for incoming reply
+ */
+static struct ceph_msg *get_reply(struct ceph_connection *con,
+ struct ceph_msg_header *hdr,
+ int *skip)
+{
+ struct ceph_osd *osd = con->private;
+ struct ceph_osd_client *osdc = osd->o_osdc;
+ struct ceph_msg *m;
+ struct ceph_osd_request *req;
+ int front = le32_to_cpu(hdr->front_len);
+ int data_len = le32_to_cpu(hdr->data_len);
+ u64 tid;
+ int err;
+
+ tid = le64_to_cpu(hdr->tid);
+ mutex_lock(&osdc->request_mutex);
+ req = __lookup_request(osdc, tid);
+ if (!req) {
+ *skip = 1;
+ m = NULL;
+ pr_info("get_reply unknown tid %llu from osd%d\n", tid,
+ osd->o_osd);
+ goto out;
+ }
+
+ if (req->r_con_filling_msg) {
+ dout("get_reply revoking msg %p from old con %p\n",
+ req->r_reply, req->r_con_filling_msg);
+ ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply);
+ ceph_con_put(req->r_con_filling_msg);
+ }
+
+ if (front > req->r_reply->front.iov_len) {
+ pr_warning("get_reply front %d > preallocated %d\n",
+ front, (int)req->r_reply->front.iov_len);
+ m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, 0, 0, NULL);
+ if (IS_ERR(m))
+ goto out;
+ ceph_msg_put(req->r_reply);
+ req->r_reply = m;
+ }
+ m = ceph_msg_get(req->r_reply);
+
+ if (data_len > 0) {
+ err = __prepare_pages(con, hdr, req, tid, m);
+ if (err < 0) {
+ *skip = 1;
+ ceph_msg_put(m);
+ m = ERR_PTR(err);
+ }
+ }
+ *skip = 0;
+ req->r_con_filling_msg = ceph_con_get(con);
+ dout("get_reply tid %lld %p\n", tid, m);
+
+out:
+ mutex_unlock(&osdc->request_mutex);
+ return m;
+
+}
+
+static struct ceph_msg *alloc_msg(struct ceph_connection *con,
+ struct ceph_msg_header *hdr,
+ int *skip)
+{
+ struct ceph_osd *osd = con->private;
+ int type = le16_to_cpu(hdr->type);
+ int front = le32_to_cpu(hdr->front_len);
+
+ switch (type) {
+ case CEPH_MSG_OSD_MAP:
+ return ceph_msg_new(type, front, 0, 0, NULL);
+ case CEPH_MSG_OSD_OPREPLY:
+ return get_reply(con, hdr, skip);
+ default:
+ pr_info("alloc_msg unexpected msg type %d from osd%d\n", type,
+ osd->o_osd);
+ *skip = 1;
+ return NULL;
+ }
+}
+
+/*
+ * Wrappers to refcount containing ceph_osd struct
+ */
+static struct ceph_connection *get_osd_con(struct ceph_connection *con)
+{
+ struct ceph_osd *osd = con->private;
+ if (get_osd(osd))
+ return con;
+ return NULL;
+}
+
+static void put_osd_con(struct ceph_connection *con)
+{
+ struct ceph_osd *osd = con->private;
+ put_osd(osd);
+}
+
+/*
+ * authentication
+ */
+static int get_authorizer(struct ceph_connection *con,
+ void **buf, int *len, int *proto,
+ void **reply_buf, int *reply_len, int force_new)
+{
+ struct ceph_osd *o = con->private;
+ struct ceph_osd_client *osdc = o->o_osdc;
+ struct ceph_auth_client *ac = osdc->client->monc.auth;
+ int ret = 0;
+
+ if (force_new && o->o_authorizer) {
+ ac->ops->destroy_authorizer(ac, o->o_authorizer);
+ o->o_authorizer = NULL;
+ }
+ if (o->o_authorizer == NULL) {
+ ret = ac->ops->create_authorizer(
+ ac, CEPH_ENTITY_TYPE_OSD,
+ &o->o_authorizer,
+ &o->o_authorizer_buf,
+ &o->o_authorizer_buf_len,
+ &o->o_authorizer_reply_buf,
+ &o->o_authorizer_reply_buf_len);
+ if (ret)
+ return ret;
+ }
+
+ *proto = ac->protocol;
+ *buf = o->o_authorizer_buf;
+ *len = o->o_authorizer_buf_len;
+ *reply_buf = o->o_authorizer_reply_buf;
+ *reply_len = o->o_authorizer_reply_buf_len;
+ return 0;
+}
+
+
+static int verify_authorizer_reply(struct ceph_connection *con, int len)
+{
+ struct ceph_osd *o = con->private;
+ struct ceph_osd_client *osdc = o->o_osdc;
+ struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+ return ac->ops->verify_authorizer_reply(ac, o->o_authorizer, len);
+}
+
+static int invalidate_authorizer(struct ceph_connection *con)
+{
+ struct ceph_osd *o = con->private;
+ struct ceph_osd_client *osdc = o->o_osdc;
+ struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+ if (ac->ops->invalidate_authorizer)
+ ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD);
+
+ return ceph_monc_validate_auth(&osdc->client->monc);
+}
+
+const static struct ceph_connection_operations osd_con_ops = {
+ .get = get_osd_con,
+ .put = put_osd_con,
+ .dispatch = dispatch,
+ .get_authorizer = get_authorizer,
+ .verify_authorizer_reply = verify_authorizer_reply,
+ .invalidate_authorizer = invalidate_authorizer,
+ .alloc_msg = alloc_msg,
+ .fault = osd_reset,
+};
diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h
new file mode 100644
index 00000000000..b0759911e7c
--- /dev/null
+++ b/fs/ceph/osd_client.h
@@ -0,0 +1,166 @@
+#ifndef _FS_CEPH_OSD_CLIENT_H
+#define _FS_CEPH_OSD_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/mempool.h>
+#include <linux/rbtree.h>
+
+#include "types.h"
+#include "osdmap.h"
+#include "messenger.h"
+
+struct ceph_msg;
+struct ceph_snap_context;
+struct ceph_osd_request;
+struct ceph_osd_client;
+struct ceph_authorizer;
+
+/*
+ * completion callback for async writepages
+ */
+typedef void (*ceph_osdc_callback_t)(struct ceph_osd_request *,
+ struct ceph_msg *);
+
+/* a given osd we're communicating with */
+struct ceph_osd {
+ atomic_t o_ref;
+ struct ceph_osd_client *o_osdc;
+ int o_osd;
+ int o_incarnation;
+ struct rb_node o_node;
+ struct ceph_connection o_con;
+ struct list_head o_requests;
+ struct list_head o_osd_lru;
+ struct ceph_authorizer *o_authorizer;
+ void *o_authorizer_buf, *o_authorizer_reply_buf;
+ size_t o_authorizer_buf_len, o_authorizer_reply_buf_len;
+ unsigned long lru_ttl;
+ int o_marked_for_keepalive;
+ struct list_head o_keepalive_item;
+};
+
+/* an in-flight request */
+struct ceph_osd_request {
+ u64 r_tid; /* unique for this client */
+ struct rb_node r_node;
+ struct list_head r_req_lru_item;
+ struct list_head r_osd_item;
+ struct ceph_osd *r_osd;
+ struct ceph_pg r_pgid;
+
+ struct ceph_connection *r_con_filling_msg;
+
+ struct ceph_msg *r_request, *r_reply;
+ int r_result;
+ int r_flags; /* any additional flags for the osd */
+ u32 r_sent; /* >0 if r_request is sending/sent */
+ int r_got_reply;
+
+ struct ceph_osd_client *r_osdc;
+ struct kref r_kref;
+ bool r_mempool;
+ struct completion r_completion, r_safe_completion;
+ ceph_osdc_callback_t r_callback, r_safe_callback;
+ struct ceph_eversion r_reassert_version;
+ struct list_head r_unsafe_item;
+
+ struct inode *r_inode; /* for use by callbacks */
+ struct writeback_control *r_wbc; /* ditto */
+
+ char r_oid[40]; /* object name */
+ int r_oid_len;
+ unsigned long r_stamp; /* send OR check time */
+ bool r_resend; /* msg send failed, needs retry */
+
+ struct ceph_file_layout r_file_layout;
+ struct ceph_snap_context *r_snapc; /* snap context for writes */
+ unsigned r_num_pages; /* size of page array (follows) */
+ struct page **r_pages; /* pages for data payload */
+ int r_pages_from_pool;
+ int r_own_pages; /* if true, i own page list */
+};
+
+struct ceph_osd_client {
+ struct ceph_client *client;
+
+ struct ceph_osdmap *osdmap; /* current map */
+ struct rw_semaphore map_sem;
+ struct completion map_waiters;
+ u64 last_requested_map;
+
+ struct mutex request_mutex;
+ struct rb_root osds; /* osds */
+ struct list_head osd_lru; /* idle osds */
+ u64 timeout_tid; /* tid of timeout triggering rq */
+ u64 last_tid; /* tid of last request */
+ struct rb_root requests; /* pending requests */
+ struct list_head req_lru; /* pending requests lru */
+ int num_requests;
+ struct delayed_work timeout_work;
+ struct delayed_work osds_timeout_work;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_file;
+#endif
+
+ mempool_t *req_mempool;
+
+ struct ceph_msgpool msgpool_op;
+ struct ceph_msgpool msgpool_op_reply;
+};
+
+extern int ceph_osdc_init(struct ceph_osd_client *osdc,
+ struct ceph_client *client);
+extern void ceph_osdc_stop(struct ceph_osd_client *osdc);
+
+extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc,
+ struct ceph_msg *msg);
+extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc,
+ struct ceph_msg *msg);
+
+extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *,
+ struct ceph_file_layout *layout,
+ struct ceph_vino vino,
+ u64 offset, u64 *len, int op, int flags,
+ struct ceph_snap_context *snapc,
+ int do_sync, u32 truncate_seq,
+ u64 truncate_size,
+ struct timespec *mtime,
+ bool use_mempool, int num_reply);
+
+static inline void ceph_osdc_get_request(struct ceph_osd_request *req)
+{
+ kref_get(&req->r_kref);
+}
+extern void ceph_osdc_release_request(struct kref *kref);
+static inline void ceph_osdc_put_request(struct ceph_osd_request *req)
+{
+ kref_put(&req->r_kref, ceph_osdc_release_request);
+}
+
+extern int ceph_osdc_start_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req,
+ bool nofail);
+extern int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
+ struct ceph_osd_request *req);
+extern void ceph_osdc_sync(struct ceph_osd_client *osdc);
+
+extern int ceph_osdc_readpages(struct ceph_osd_client *osdc,
+ struct ceph_vino vino,
+ struct ceph_file_layout *layout,
+ u64 off, u64 *plen,
+ u32 truncate_seq, u64 truncate_size,
+ struct page **pages, int nr_pages);
+
+extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
+ struct ceph_vino vino,
+ struct ceph_file_layout *layout,
+ struct ceph_snap_context *sc,
+ u64 off, u64 len,
+ u32 truncate_seq, u64 truncate_size,
+ struct timespec *mtime,
+ struct page **pages, int nr_pages,
+ int flags, int do_sync, bool nofail);
+
+#endif
+
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c
new file mode 100644
index 00000000000..2e2c15eed82
--- /dev/null
+++ b/fs/ceph/osdmap.c
@@ -0,0 +1,1062 @@
+
+#include "ceph_debug.h"
+
+#include <linux/slab.h>
+#include <asm/div64.h>
+
+#include "super.h"
+#include "osdmap.h"
+#include "crush/hash.h"
+#include "crush/mapper.h"
+#include "decode.h"
+
+char *ceph_osdmap_state_str(char *str, int len, int state)
+{
+ int flag = 0;
+
+ if (!len)
+ goto done;
+
+ *str = '\0';
+ if (state) {
+ if (state & CEPH_OSD_EXISTS) {
+ snprintf(str, len, "exists");
+ flag = 1;
+ }
+ if (state & CEPH_OSD_UP) {
+ snprintf(str, len, "%s%s%s", str, (flag ? ", " : ""),
+ "up");
+ flag = 1;
+ }
+ } else {
+ snprintf(str, len, "doesn't exist");
+ }
+done:
+ return str;
+}
+
+/* maps */
+
+static int calc_bits_of(unsigned t)
+{
+ int b = 0;
+ while (t) {
+ t = t >> 1;
+ b++;
+ }
+ return b;
+}
+
+/*
+ * the foo_mask is the smallest value 2^n-1 that is >= foo.
+ */
+static void calc_pg_masks(struct ceph_pg_pool_info *pi)
+{
+ pi->pg_num_mask = (1 << calc_bits_of(le32_to_cpu(pi->v.pg_num)-1)) - 1;
+ pi->pgp_num_mask =
+ (1 << calc_bits_of(le32_to_cpu(pi->v.pgp_num)-1)) - 1;
+ pi->lpg_num_mask =
+ (1 << calc_bits_of(le32_to_cpu(pi->v.lpg_num)-1)) - 1;
+ pi->lpgp_num_mask =
+ (1 << calc_bits_of(le32_to_cpu(pi->v.lpgp_num)-1)) - 1;
+}
+
+/*
+ * decode crush map
+ */
+static int crush_decode_uniform_bucket(void **p, void *end,
+ struct crush_bucket_uniform *b)
+{
+ dout("crush_decode_uniform_bucket %p to %p\n", *p, end);
+ ceph_decode_need(p, end, (1+b->h.size) * sizeof(u32), bad);
+ b->item_weight = ceph_decode_32(p);
+ return 0;
+bad:
+ return -EINVAL;
+}
+
+static int crush_decode_list_bucket(void **p, void *end,
+ struct crush_bucket_list *b)
+{
+ int j;
+ dout("crush_decode_list_bucket %p to %p\n", *p, end);
+ b->item_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+ if (b->item_weights == NULL)
+ return -ENOMEM;
+ b->sum_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+ if (b->sum_weights == NULL)
+ return -ENOMEM;
+ ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad);
+ for (j = 0; j < b->h.size; j++) {
+ b->item_weights[j] = ceph_decode_32(p);
+ b->sum_weights[j] = ceph_decode_32(p);
+ }
+ return 0;
+bad:
+ return -EINVAL;
+}
+
+static int crush_decode_tree_bucket(void **p, void *end,
+ struct crush_bucket_tree *b)
+{
+ int j;
+ dout("crush_decode_tree_bucket %p to %p\n", *p, end);
+ ceph_decode_32_safe(p, end, b->num_nodes, bad);
+ b->node_weights = kcalloc(b->num_nodes, sizeof(u32), GFP_NOFS);
+ if (b->node_weights == NULL)
+ return -ENOMEM;
+ ceph_decode_need(p, end, b->num_nodes * sizeof(u32), bad);
+ for (j = 0; j < b->num_nodes; j++)
+ b->node_weights[j] = ceph_decode_32(p);
+ return 0;
+bad:
+ return -EINVAL;
+}
+
+static int crush_decode_straw_bucket(void **p, void *end,
+ struct crush_bucket_straw *b)
+{
+ int j;
+ dout("crush_decode_straw_bucket %p to %p\n", *p, end);
+ b->item_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+ if (b->item_weights == NULL)
+ return -ENOMEM;
+ b->straws = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+ if (b->straws == NULL)
+ return -ENOMEM;
+ ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad);
+ for (j = 0; j < b->h.size; j++) {
+ b->item_weights[j] = ceph_decode_32(p);
+ b->straws[j] = ceph_decode_32(p);
+ }
+ return 0;
+bad:
+ return -EINVAL;
+}
+
+static struct crush_map *crush_decode(void *pbyval, void *end)
+{
+ struct crush_map *c;
+ int err = -EINVAL;
+ int i, j;
+ void **p = &pbyval;
+ void *start = pbyval;
+ u32 magic;
+
+ dout("crush_decode %p to %p len %d\n", *p, end, (int)(end - *p));
+
+ c = kzalloc(sizeof(*c), GFP_NOFS);
+ if (c == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ ceph_decode_need(p, end, 4*sizeof(u32), bad);
+ magic = ceph_decode_32(p);
+ if (magic != CRUSH_MAGIC) {
+ pr_err("crush_decode magic %x != current %x\n",
+ (unsigned)magic, (unsigned)CRUSH_MAGIC);
+ goto bad;
+ }
+ c->max_buckets = ceph_decode_32(p);
+ c->max_rules = ceph_decode_32(p);
+ c->max_devices = ceph_decode_32(p);
+
+ c->device_parents = kcalloc(c->max_devices, sizeof(u32), GFP_NOFS);
+ if (c->device_parents == NULL)
+ goto badmem;
+ c->bucket_parents = kcalloc(c->max_buckets, sizeof(u32), GFP_NOFS);
+ if (c->bucket_parents == NULL)
+ goto badmem;
+
+ c->buckets = kcalloc(c->max_buckets, sizeof(*c->buckets), GFP_NOFS);
+ if (c->buckets == NULL)
+ goto badmem;
+ c->rules = kcalloc(c->max_rules, sizeof(*c->rules), GFP_NOFS);
+ if (c->rules == NULL)
+ goto badmem;
+
+ /* buckets */
+ for (i = 0; i < c->max_buckets; i++) {
+ int size = 0;
+ u32 alg;
+ struct crush_bucket *b;
+
+ ceph_decode_32_safe(p, end, alg, bad);
+ if (alg == 0) {
+ c->buckets[i] = NULL;
+ continue;
+ }
+ dout("crush_decode bucket %d off %x %p to %p\n",
+ i, (int)(*p-start), *p, end);
+
+ switch (alg) {
+ case CRUSH_BUCKET_UNIFORM:
+ size = sizeof(struct crush_bucket_uniform);
+ break;
+ case CRUSH_BUCKET_LIST:
+ size = sizeof(struct crush_bucket_list);
+ break;
+ case CRUSH_BUCKET_TREE:
+ size = sizeof(struct crush_bucket_tree);
+ break;
+ case CRUSH_BUCKET_STRAW:
+ size = sizeof(struct crush_bucket_straw);
+ break;
+ default:
+ err = -EINVAL;
+ goto bad;
+ }
+ BUG_ON(size == 0);
+ b = c->buckets[i] = kzalloc(size, GFP_NOFS);
+ if (b == NULL)
+ goto badmem;
+
+ ceph_decode_need(p, end, 4*sizeof(u32), bad);
+ b->id = ceph_decode_32(p);
+ b->type = ceph_decode_16(p);
+ b->alg = ceph_decode_8(p);
+ b->hash = ceph_decode_8(p);
+ b->weight = ceph_decode_32(p);
+ b->size = ceph_decode_32(p);
+
+ dout("crush_decode bucket size %d off %x %p to %p\n",
+ b->size, (int)(*p-start), *p, end);
+
+ b->items = kcalloc(b->size, sizeof(__s32), GFP_NOFS);
+ if (b->items == NULL)
+ goto badmem;
+ b->perm = kcalloc(b->size, sizeof(u32), GFP_NOFS);
+ if (b->perm == NULL)
+ goto badmem;
+ b->perm_n = 0;
+
+ ceph_decode_need(p, end, b->size*sizeof(u32), bad);
+ for (j = 0; j < b->size; j++)
+ b->items[j] = ceph_decode_32(p);
+
+ switch (b->alg) {
+ case CRUSH_BUCKET_UNIFORM:
+ err = crush_decode_uniform_bucket(p, end,
+ (struct crush_bucket_uniform *)b);
+ if (err < 0)
+ goto bad;
+ break;
+ case CRUSH_BUCKET_LIST:
+ err = crush_decode_list_bucket(p, end,
+ (struct crush_bucket_list *)b);
+ if (err < 0)
+ goto bad;
+ break;
+ case CRUSH_BUCKET_TREE:
+ err = crush_decode_tree_bucket(p, end,
+ (struct crush_bucket_tree *)b);
+ if (err < 0)
+ goto bad;
+ break;
+ case CRUSH_BUCKET_STRAW:
+ err = crush_decode_straw_bucket(p, end,
+ (struct crush_bucket_straw *)b);
+ if (err < 0)
+ goto bad;
+ break;
+ }
+ }
+
+ /* rules */
+ dout("rule vec is %p\n", c->rules);
+ for (i = 0; i < c->max_rules; i++) {
+ u32 yes;
+ struct crush_rule *r;
+
+ ceph_decode_32_safe(p, end, yes, bad);
+ if (!yes) {
+ dout("crush_decode NO rule %d off %x %p to %p\n",
+ i, (int)(*p-start), *p, end);
+ c->rules[i] = NULL;
+ continue;
+ }
+
+ dout("crush_decode rule %d off %x %p to %p\n",
+ i, (int)(*p-start), *p, end);
+
+ /* len */
+ ceph_decode_32_safe(p, end, yes, bad);
+#if BITS_PER_LONG == 32
+ err = -EINVAL;
+ if (yes > ULONG_MAX / sizeof(struct crush_rule_step))
+ goto bad;
+#endif
+ r = c->rules[i] = kmalloc(sizeof(*r) +
+ yes*sizeof(struct crush_rule_step),
+ GFP_NOFS);
+ if (r == NULL)
+ goto badmem;
+ dout(" rule %d is at %p\n", i, r);
+ r->len = yes;
+ ceph_decode_copy_safe(p, end, &r->mask, 4, bad); /* 4 u8's */
+ ceph_decode_need(p, end, r->len*3*sizeof(u32), bad);
+ for (j = 0; j < r->len; j++) {
+ r->steps[j].op = ceph_decode_32(p);
+ r->steps[j].arg1 = ceph_decode_32(p);
+ r->steps[j].arg2 = ceph_decode_32(p);
+ }
+ }
+
+ /* ignore trailing name maps. */
+
+ dout("crush_decode success\n");
+ return c;
+
+badmem:
+ err = -ENOMEM;
+bad:
+ dout("crush_decode fail %d\n", err);
+ crush_destroy(c);
+ return ERR_PTR(err);
+}
+
+/*
+ * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
+ * to a set of osds)
+ */
+static int pgid_cmp(struct ceph_pg l, struct ceph_pg r)
+{
+ u64 a = *(u64 *)&l;
+ u64 b = *(u64 *)&r;
+
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+}
+
+static int __insert_pg_mapping(struct ceph_pg_mapping *new,
+ struct rb_root *root)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct ceph_pg_mapping *pg = NULL;
+ int c;
+
+ while (*p) {
+ parent = *p;
+ pg = rb_entry(parent, struct ceph_pg_mapping, node);
+ c = pgid_cmp(new->pgid, pg->pgid);
+ if (c < 0)
+ p = &(*p)->rb_left;
+ else if (c > 0)
+ p = &(*p)->rb_right;
+ else
+ return -EEXIST;
+ }
+
+ rb_link_node(&new->node, parent, p);
+ rb_insert_color(&new->node, root);
+ return 0;
+}
+
+static struct ceph_pg_mapping *__lookup_pg_mapping(struct rb_root *root,
+ struct ceph_pg pgid)
+{
+ struct rb_node *n = root->rb_node;
+ struct ceph_pg_mapping *pg;
+ int c;
+
+ while (n) {
+ pg = rb_entry(n, struct ceph_pg_mapping, node);
+ c = pgid_cmp(pgid, pg->pgid);
+ if (c < 0)
+ n = n->rb_left;
+ else if (c > 0)
+ n = n->rb_right;
+ else
+ return pg;
+ }
+ return NULL;
+}
+
+/*
+ * rbtree of pg pool info
+ */
+static int __insert_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *new)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct ceph_pg_pool_info *pi = NULL;
+
+ while (*p) {
+ parent = *p;
+ pi = rb_entry(parent, struct ceph_pg_pool_info, node);
+ if (new->id < pi->id)
+ p = &(*p)->rb_left;
+ else if (new->id > pi->id)
+ p = &(*p)->rb_right;
+ else
+ return -EEXIST;
+ }
+
+ rb_link_node(&new->node, parent, p);
+ rb_insert_color(&new->node, root);
+ return 0;
+}
+
+static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id)
+{
+ struct ceph_pg_pool_info *pi;
+ struct rb_node *n = root->rb_node;
+
+ while (n) {
+ pi = rb_entry(n, struct ceph_pg_pool_info, node);
+ if (id < pi->id)
+ n = n->rb_left;
+ else if (id > pi->id)
+ n = n->rb_right;
+ else
+ return pi;
+ }
+ return NULL;
+}
+
+static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
+{
+ rb_erase(&pi->node, root);
+ kfree(pi->name);
+ kfree(pi);
+}
+
+void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
+{
+ ceph_decode_copy(p, &pi->v, sizeof(pi->v));
+ calc_pg_masks(pi);
+ *p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64);
+ *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2;
+}
+
+static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
+{
+ struct ceph_pg_pool_info *pi;
+ u32 num, len, pool;
+
+ ceph_decode_32_safe(p, end, num, bad);
+ dout(" %d pool names\n", num);
+ while (num--) {
+ ceph_decode_32_safe(p, end, pool, bad);
+ ceph_decode_32_safe(p, end, len, bad);
+ dout(" pool %d len %d\n", pool, len);
+ pi = __lookup_pg_pool(&map->pg_pools, pool);
+ if (pi) {
+ kfree(pi->name);
+ pi->name = kmalloc(len + 1, GFP_NOFS);
+ if (pi->name) {
+ memcpy(pi->name, *p, len);
+ pi->name[len] = '\0';
+ dout(" name is %s\n", pi->name);
+ }
+ }
+ *p += len;
+ }
+ return 0;
+
+bad:
+ return -EINVAL;
+}
+
+/*
+ * osd map
+ */
+void ceph_osdmap_destroy(struct ceph_osdmap *map)
+{
+ dout("osdmap_destroy %p\n", map);
+ if (map->crush)
+ crush_destroy(map->crush);
+ while (!RB_EMPTY_ROOT(&map->pg_temp)) {
+ struct ceph_pg_mapping *pg =
+ rb_entry(rb_first(&map->pg_temp),
+ struct ceph_pg_mapping, node);
+ rb_erase(&pg->node, &map->pg_temp);
+ kfree(pg);
+ }
+ while (!RB_EMPTY_ROOT(&map->pg_pools)) {
+ struct ceph_pg_pool_info *pi =
+ rb_entry(rb_first(&map->pg_pools),
+ struct ceph_pg_pool_info, node);
+ __remove_pg_pool(&map->pg_pools, pi);
+ }
+ kfree(map->osd_state);
+ kfree(map->osd_weight);
+ kfree(map->osd_addr);
+ kfree(map);
+}
+
+/*
+ * adjust max osd value. reallocate arrays.
+ */
+static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
+{
+ u8 *state;
+ struct ceph_entity_addr *addr;
+ u32 *weight;
+
+ state = kcalloc(max, sizeof(*state), GFP_NOFS);
+ addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
+ weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
+ if (state == NULL || addr == NULL || weight == NULL) {
+ kfree(state);
+ kfree(addr);
+ kfree(weight);
+ return -ENOMEM;
+ }
+
+ /* copy old? */
+ if (map->osd_state) {
+ memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
+ memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
+ memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
+ kfree(map->osd_state);
+ kfree(map->osd_addr);
+ kfree(map->osd_weight);
+ }
+
+ map->osd_state = state;
+ map->osd_weight = weight;
+ map->osd_addr = addr;
+ map->max_osd = max;
+ return 0;
+}
+
+/*
+ * decode a full map.
+ */
+struct ceph_osdmap *osdmap_decode(void **p, void *end)
+{
+ struct ceph_osdmap *map;
+ u16 version;
+ u32 len, max, i;
+ u8 ev;
+ int err = -EINVAL;
+ void *start = *p;
+ struct ceph_pg_pool_info *pi;
+
+ dout("osdmap_decode %p to %p len %d\n", *p, end, (int)(end - *p));
+
+ map = kzalloc(sizeof(*map), GFP_NOFS);
+ if (map == NULL)
+ return ERR_PTR(-ENOMEM);
+ map->pg_temp = RB_ROOT;
+
+ ceph_decode_16_safe(p, end, version, bad);
+ if (version > CEPH_OSDMAP_VERSION) {
+ pr_warning("got unknown v %d > %d of osdmap\n", version,
+ CEPH_OSDMAP_VERSION);
+ goto bad;
+ }
+
+ ceph_decode_need(p, end, 2*sizeof(u64)+6*sizeof(u32), bad);
+ ceph_decode_copy(p, &map->fsid, sizeof(map->fsid));
+ map->epoch = ceph_decode_32(p);
+ ceph_decode_copy(p, &map->created, sizeof(map->created));
+ ceph_decode_copy(p, &map->modified, sizeof(map->modified));
+
+ ceph_decode_32_safe(p, end, max, bad);
+ while (max--) {
+ ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
+ pi = kzalloc(sizeof(*pi), GFP_NOFS);
+ if (!pi)
+ goto bad;
+ pi->id = ceph_decode_32(p);
+ ev = ceph_decode_8(p); /* encoding version */
+ if (ev > CEPH_PG_POOL_VERSION) {
+ pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
+ ev, CEPH_PG_POOL_VERSION);
+ goto bad;
+ }
+ __decode_pool(p, pi);
+ __insert_pg_pool(&map->pg_pools, pi);
+ }
+
+ if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+ goto bad;
+
+ ceph_decode_32_safe(p, end, map->pool_max, bad);
+
+ ceph_decode_32_safe(p, end, map->flags, bad);
+
+ max = ceph_decode_32(p);
+
+ /* (re)alloc osd arrays */
+ err = osdmap_set_max_osd(map, max);
+ if (err < 0)
+ goto bad;
+ dout("osdmap_decode max_osd = %d\n", map->max_osd);
+
+ /* osds */
+ err = -EINVAL;
+ ceph_decode_need(p, end, 3*sizeof(u32) +
+ map->max_osd*(1 + sizeof(*map->osd_weight) +
+ sizeof(*map->osd_addr)), bad);
+ *p += 4; /* skip length field (should match max) */
+ ceph_decode_copy(p, map->osd_state, map->max_osd);
+
+ *p += 4; /* skip length field (should match max) */
+ for (i = 0; i < map->max_osd; i++)
+ map->osd_weight[i] = ceph_decode_32(p);
+
+ *p += 4; /* skip length field (should match max) */
+ ceph_decode_copy(p, map->osd_addr, map->max_osd*sizeof(*map->osd_addr));
+ for (i = 0; i < map->max_osd; i++)
+ ceph_decode_addr(&map->osd_addr[i]);
+
+ /* pg_temp */
+ ceph_decode_32_safe(p, end, len, bad);
+ for (i = 0; i < len; i++) {
+ int n, j;
+ struct ceph_pg pgid;
+ struct ceph_pg_mapping *pg;
+
+ ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
+ ceph_decode_copy(p, &pgid, sizeof(pgid));
+ n = ceph_decode_32(p);
+ ceph_decode_need(p, end, n * sizeof(u32), bad);
+ err = -ENOMEM;
+ pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS);
+ if (!pg)
+ goto bad;
+ pg->pgid = pgid;
+ pg->len = n;
+ for (j = 0; j < n; j++)
+ pg->osds[j] = ceph_decode_32(p);
+
+ err = __insert_pg_mapping(pg, &map->pg_temp);
+ if (err)
+ goto bad;
+ dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, len);
+ }
+
+ /* crush */
+ ceph_decode_32_safe(p, end, len, bad);
+ dout("osdmap_decode crush len %d from off 0x%x\n", len,
+ (int)(*p - start));
+ ceph_decode_need(p, end, len, bad);
+ map->crush = crush_decode(*p, end);
+ *p += len;
+ if (IS_ERR(map->crush)) {
+ err = PTR_ERR(map->crush);
+ map->crush = NULL;
+ goto bad;
+ }
+
+ /* ignore the rest of the map */
+ *p = end;
+
+ dout("osdmap_decode done %p %p\n", *p, end);
+ return map;
+
+bad:
+ dout("osdmap_decode fail\n");
+ ceph_osdmap_destroy(map);
+ return ERR_PTR(err);
+}
+
+/*
+ * decode and apply an incremental map update.
+ */
+struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+ struct ceph_osdmap *map,
+ struct ceph_messenger *msgr)
+{
+ struct crush_map *newcrush = NULL;
+ struct ceph_fsid fsid;
+ u32 epoch = 0;
+ struct ceph_timespec modified;
+ u32 len, pool;
+ __s32 new_pool_max, new_flags, max;
+ void *start = *p;
+ int err = -EINVAL;
+ u16 version;
+ struct rb_node *rbp;
+
+ ceph_decode_16_safe(p, end, version, bad);
+ if (version > CEPH_OSDMAP_INC_VERSION) {
+ pr_warning("got unknown v %d > %d of inc osdmap\n", version,
+ CEPH_OSDMAP_INC_VERSION);
+ goto bad;
+ }
+
+ ceph_decode_need(p, end, sizeof(fsid)+sizeof(modified)+2*sizeof(u32),
+ bad);
+ ceph_decode_copy(p, &fsid, sizeof(fsid));
+ epoch = ceph_decode_32(p);
+ BUG_ON(epoch != map->epoch+1);
+ ceph_decode_copy(p, &modified, sizeof(modified));
+ new_pool_max = ceph_decode_32(p);
+ new_flags = ceph_decode_32(p);
+
+ /* full map? */
+ ceph_decode_32_safe(p, end, len, bad);
+ if (len > 0) {
+ dout("apply_incremental full map len %d, %p to %p\n",
+ len, *p, end);
+ return osdmap_decode(p, min(*p+len, end));
+ }
+
+ /* new crush? */
+ ceph_decode_32_safe(p, end, len, bad);
+ if (len > 0) {
+ dout("apply_incremental new crush map len %d, %p to %p\n",
+ len, *p, end);
+ newcrush = crush_decode(*p, min(*p+len, end));
+ if (IS_ERR(newcrush))
+ return ERR_PTR(PTR_ERR(newcrush));
+ }
+
+ /* new flags? */
+ if (new_flags >= 0)
+ map->flags = new_flags;
+ if (new_pool_max >= 0)
+ map->pool_max = new_pool_max;
+
+ ceph_decode_need(p, end, 5*sizeof(u32), bad);
+
+ /* new max? */
+ max = ceph_decode_32(p);
+ if (max >= 0) {
+ err = osdmap_set_max_osd(map, max);
+ if (err < 0)
+ goto bad;
+ }
+
+ map->epoch++;
+ map->modified = map->modified;
+ if (newcrush) {
+ if (map->crush)
+ crush_destroy(map->crush);
+ map->crush = newcrush;
+ newcrush = NULL;
+ }
+
+ /* new_pool */
+ ceph_decode_32_safe(p, end, len, bad);
+ while (len--) {
+ __u8 ev;
+ struct ceph_pg_pool_info *pi;
+
+ ceph_decode_32_safe(p, end, pool, bad);
+ ceph_decode_need(p, end, 1 + sizeof(pi->v), bad);
+ ev = ceph_decode_8(p); /* encoding version */
+ if (ev > CEPH_PG_POOL_VERSION) {
+ pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
+ ev, CEPH_PG_POOL_VERSION);
+ goto bad;
+ }
+ pi = __lookup_pg_pool(&map->pg_pools, pool);
+ if (!pi) {
+ pi = kzalloc(sizeof(*pi), GFP_NOFS);
+ if (!pi) {
+ err = -ENOMEM;
+ goto bad;
+ }
+ pi->id = pool;
+ __insert_pg_pool(&map->pg_pools, pi);
+ }
+ __decode_pool(p, pi);
+ }
+ if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+ goto bad;
+
+ /* old_pool */
+ ceph_decode_32_safe(p, end, len, bad);
+ while (len--) {
+ struct ceph_pg_pool_info *pi;
+
+ ceph_decode_32_safe(p, end, pool, bad);
+ pi = __lookup_pg_pool(&map->pg_pools, pool);
+ if (pi)
+ __remove_pg_pool(&map->pg_pools, pi);
+ }
+
+ /* new_up */
+ err = -EINVAL;
+ ceph_decode_32_safe(p, end, len, bad);
+ while (len--) {
+ u32 osd;
+ struct ceph_entity_addr addr;
+ ceph_decode_32_safe(p, end, osd, bad);
+ ceph_decode_copy_safe(p, end, &addr, sizeof(addr), bad);
+ ceph_decode_addr(&addr);
+ pr_info("osd%d up\n", osd);
+ BUG_ON(osd >= map->max_osd);
+ map->osd_state[osd] |= CEPH_OSD_UP;
+ map->osd_addr[osd] = addr;
+ }
+
+ /* new_down */
+ ceph_decode_32_safe(p, end, len, bad);
+ while (len--) {
+ u32 osd;
+ ceph_decode_32_safe(p, end, osd, bad);
+ (*p)++; /* clean flag */
+ pr_info("osd%d down\n", osd);
+ if (osd < map->max_osd)
+ map->osd_state[osd] &= ~CEPH_OSD_UP;
+ }
+
+ /* new_weight */
+ ceph_decode_32_safe(p, end, len, bad);
+ while (len--) {
+ u32 osd, off;
+ ceph_decode_need(p, end, sizeof(u32)*2, bad);
+ osd = ceph_decode_32(p);
+ off = ceph_decode_32(p);
+ pr_info("osd%d weight 0x%x %s\n", osd, off,
+ off == CEPH_OSD_IN ? "(in)" :
+ (off == CEPH_OSD_OUT ? "(out)" : ""));
+ if (osd < map->max_osd)
+ map->osd_weight[osd] = off;
+ }
+
+ /* new_pg_temp */
+ rbp = rb_first(&map->pg_temp);
+ ceph_decode_32_safe(p, end, len, bad);
+ while (len--) {
+ struct ceph_pg_mapping *pg;
+ int j;
+ struct ceph_pg pgid;
+ u32 pglen;
+ ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
+ ceph_decode_copy(p, &pgid, sizeof(pgid));
+ pglen = ceph_decode_32(p);
+
+ /* remove any? */
+ while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping,
+ node)->pgid, pgid) <= 0) {
+ struct rb_node *cur = rbp;
+ rbp = rb_next(rbp);
+ dout(" removed pg_temp %llx\n",
+ *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
+ node)->pgid);
+ rb_erase(cur, &map->pg_temp);
+ }
+
+ if (pglen) {
+ /* insert */
+ ceph_decode_need(p, end, pglen*sizeof(u32), bad);
+ pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS);
+ if (!pg) {
+ err = -ENOMEM;
+ goto bad;
+ }
+ pg->pgid = pgid;
+ pg->len = pglen;
+ for (j = 0; j < pglen; j++)
+ pg->osds[j] = ceph_decode_32(p);
+ err = __insert_pg_mapping(pg, &map->pg_temp);
+ if (err)
+ goto bad;
+ dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid,
+ pglen);
+ }
+ }
+ while (rbp) {
+ struct rb_node *cur = rbp;
+ rbp = rb_next(rbp);
+ dout(" removed pg_temp %llx\n",
+ *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
+ node)->pgid);
+ rb_erase(cur, &map->pg_temp);
+ }
+
+ /* ignore the rest */
+ *p = end;
+ return map;
+
+bad:
+ pr_err("corrupt inc osdmap epoch %d off %d (%p of %p-%p)\n",
+ epoch, (int)(*p - start), *p, start, end);
+ print_hex_dump(KERN_DEBUG, "osdmap: ",
+ DUMP_PREFIX_OFFSET, 16, 1,
+ start, end - start, true);
+ if (newcrush)
+ crush_destroy(newcrush);
+ return ERR_PTR(err);
+}
+
+
+
+
+/*
+ * calculate file layout from given offset, length.
+ * fill in correct oid, logical length, and object extent
+ * offset, length.
+ *
+ * for now, we write only a single su, until we can
+ * pass a stride back to the caller.
+ */
+void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+ u64 off, u64 *plen,
+ u64 *ono,
+ u64 *oxoff, u64 *oxlen)
+{
+ u32 osize = le32_to_cpu(layout->fl_object_size);
+ u32 su = le32_to_cpu(layout->fl_stripe_unit);
+ u32 sc = le32_to_cpu(layout->fl_stripe_count);
+ u32 bl, stripeno, stripepos, objsetno;
+ u32 su_per_object;
+ u64 t, su_offset;
+
+ dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen,
+ osize, su);
+ su_per_object = osize / su;
+ dout("osize %u / su %u = su_per_object %u\n", osize, su,
+ su_per_object);
+
+ BUG_ON((su & ~PAGE_MASK) != 0);
+ /* bl = *off / su; */
+ t = off;
+ do_div(t, su);
+ bl = t;
+ dout("off %llu / su %u = bl %u\n", off, su, bl);
+
+ stripeno = bl / sc;
+ stripepos = bl % sc;
+ objsetno = stripeno / su_per_object;
+
+ *ono = objsetno * sc + stripepos;
+ dout("objset %u * sc %u = ono %u\n", objsetno, sc, (unsigned)*ono);
+
+ /* *oxoff = *off % layout->fl_stripe_unit; # offset in su */
+ t = off;
+ su_offset = do_div(t, su);
+ *oxoff = su_offset + (stripeno % su_per_object) * su;
+
+ /*
+ * Calculate the length of the extent being written to the selected
+ * object. This is the minimum of the full length requested (plen) or
+ * the remainder of the current stripe being written to.
+ */
+ *oxlen = min_t(u64, *plen, su - su_offset);
+ *plen = *oxlen;
+
+ dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);
+}
+
+/*
+ * calculate an object layout (i.e. pgid) from an oid,
+ * file_layout, and osdmap
+ */
+int ceph_calc_object_layout(struct ceph_object_layout *ol,
+ const char *oid,
+ struct ceph_file_layout *fl,
+ struct ceph_osdmap *osdmap)
+{
+ unsigned num, num_mask;
+ struct ceph_pg pgid;
+ s32 preferred = (s32)le32_to_cpu(fl->fl_pg_preferred);
+ int poolid = le32_to_cpu(fl->fl_pg_pool);
+ struct ceph_pg_pool_info *pool;
+ unsigned ps;
+
+ BUG_ON(!osdmap);
+
+ pool = __lookup_pg_pool(&osdmap->pg_pools, poolid);
+ if (!pool)
+ return -EIO;
+ ps = ceph_str_hash(pool->v.object_hash, oid, strlen(oid));
+ if (preferred >= 0) {
+ ps += preferred;
+ num = le32_to_cpu(pool->v.lpg_num);
+ num_mask = pool->lpg_num_mask;
+ } else {
+ num = le32_to_cpu(pool->v.pg_num);
+ num_mask = pool->pg_num_mask;
+ }
+
+ pgid.ps = cpu_to_le16(ps);
+ pgid.preferred = cpu_to_le16(preferred);
+ pgid.pool = fl->fl_pg_pool;
+ if (preferred >= 0)
+ dout("calc_object_layout '%s' pgid %d.%xp%d\n", oid, poolid, ps,
+ (int)preferred);
+ else
+ dout("calc_object_layout '%s' pgid %d.%x\n", oid, poolid, ps);
+
+ ol->ol_pgid = pgid;
+ ol->ol_stripe_unit = fl->fl_object_stripe_unit;
+ return 0;
+}
+
+/*
+ * Calculate raw osd vector for the given pgid. Return pointer to osd
+ * array, or NULL on failure.
+ */
+static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+ int *osds, int *num)
+{
+ struct ceph_pg_mapping *pg;
+ struct ceph_pg_pool_info *pool;
+ int ruleno;
+ unsigned poolid, ps, pps;
+ int preferred;
+
+ /* pg_temp? */
+ pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid);
+ if (pg) {
+ *num = pg->len;
+ return pg->osds;
+ }
+
+ /* crush */
+ poolid = le32_to_cpu(pgid.pool);
+ ps = le16_to_cpu(pgid.ps);
+ preferred = (s16)le16_to_cpu(pgid.preferred);
+
+ /* don't forcefeed bad device ids to crush */
+ if (preferred >= osdmap->max_osd ||
+ preferred >= osdmap->crush->max_devices)
+ preferred = -1;
+
+ pool = __lookup_pg_pool(&osdmap->pg_pools, poolid);
+ if (!pool)
+ return NULL;
+ ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset,
+ pool->v.type, pool->v.size);
+ if (ruleno < 0) {
+ pr_err("no crush rule pool %d type %d size %d\n",
+ poolid, pool->v.type, pool->v.size);
+ return NULL;
+ }
+
+ if (preferred >= 0)
+ pps = ceph_stable_mod(ps,
+ le32_to_cpu(pool->v.lpgp_num),
+ pool->lpgp_num_mask);
+ else
+ pps = ceph_stable_mod(ps,
+ le32_to_cpu(pool->v.pgp_num),
+ pool->pgp_num_mask);
+ pps += poolid;
+ *num = crush_do_rule(osdmap->crush, ruleno, pps, osds,
+ min_t(int, pool->v.size, *num),
+ preferred, osdmap->osd_weight);
+ return osds;
+}
+
+/*
+ * Return primary osd for given pgid, or -1 if none.
+ */
+int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid)
+{
+ int rawosds[10], *osds;
+ int i, num = ARRAY_SIZE(rawosds);
+
+ osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
+ if (!osds)
+ return -1;
+
+ /* primary is first up osd */
+ for (i = 0; i < num; i++)
+ if (ceph_osd_is_up(osdmap, osds[i])) {
+ return osds[i];
+ break;
+ }
+ return -1;
+}
diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h
new file mode 100644
index 00000000000..8bc9f1e4f56
--- /dev/null
+++ b/fs/ceph/osdmap.h
@@ -0,0 +1,126 @@
+#ifndef _FS_CEPH_OSDMAP_H
+#define _FS_CEPH_OSDMAP_H
+
+#include <linux/rbtree.h>
+#include "types.h"
+#include "ceph_fs.h"
+#include "crush/crush.h"
+
+/*
+ * The osd map describes the current membership of the osd cluster and
+ * specifies the mapping of objects to placement groups and placement
+ * groups to (sets of) osds. That is, it completely specifies the
+ * (desired) distribution of all data objects in the system at some
+ * point in time.
+ *
+ * Each map version is identified by an epoch, which increases monotonically.
+ *
+ * The map can be updated either via an incremental map (diff) describing
+ * the change between two successive epochs, or as a fully encoded map.
+ */
+struct ceph_pg_pool_info {
+ struct rb_node node;
+ int id;
+ struct ceph_pg_pool v;
+ int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask;
+ char *name;
+};
+
+struct ceph_pg_mapping {
+ struct rb_node node;
+ struct ceph_pg pgid;
+ int len;
+ int osds[];
+};
+
+struct ceph_osdmap {
+ struct ceph_fsid fsid;
+ u32 epoch;
+ u32 mkfs_epoch;
+ struct ceph_timespec created, modified;
+
+ u32 flags; /* CEPH_OSDMAP_* */
+
+ u32 max_osd; /* size of osd_state, _offload, _addr arrays */
+ u8 *osd_state; /* CEPH_OSD_* */
+ u32 *osd_weight; /* 0 = failed, 0x10000 = 100% normal */
+ struct ceph_entity_addr *osd_addr;
+
+ struct rb_root pg_temp;
+ struct rb_root pg_pools;
+ u32 pool_max;
+
+ /* the CRUSH map specifies the mapping of placement groups to
+ * the list of osds that store+replicate them. */
+ struct crush_map *crush;
+};
+
+/*
+ * file layout helpers
+ */
+#define ceph_file_layout_su(l) ((__s32)le32_to_cpu((l).fl_stripe_unit))
+#define ceph_file_layout_stripe_count(l) \
+ ((__s32)le32_to_cpu((l).fl_stripe_count))
+#define ceph_file_layout_object_size(l) ((__s32)le32_to_cpu((l).fl_object_size))
+#define ceph_file_layout_cas_hash(l) ((__s32)le32_to_cpu((l).fl_cas_hash))
+#define ceph_file_layout_object_su(l) \
+ ((__s32)le32_to_cpu((l).fl_object_stripe_unit))
+#define ceph_file_layout_pg_preferred(l) \
+ ((__s32)le32_to_cpu((l).fl_pg_preferred))
+#define ceph_file_layout_pg_pool(l) \
+ ((__s32)le32_to_cpu((l).fl_pg_pool))
+
+static inline unsigned ceph_file_layout_stripe_width(struct ceph_file_layout *l)
+{
+ return le32_to_cpu(l->fl_stripe_unit) *
+ le32_to_cpu(l->fl_stripe_count);
+}
+
+/* "period" == bytes before i start on a new set of objects */
+static inline unsigned ceph_file_layout_period(struct ceph_file_layout *l)
+{
+ return le32_to_cpu(l->fl_object_size) *
+ le32_to_cpu(l->fl_stripe_count);
+}
+
+
+static inline int ceph_osd_is_up(struct ceph_osdmap *map, int osd)
+{
+ return (osd < map->max_osd) && (map->osd_state[osd] & CEPH_OSD_UP);
+}
+
+static inline bool ceph_osdmap_flag(struct ceph_osdmap *map, int flag)
+{
+ return map && (map->flags & flag);
+}
+
+extern char *ceph_osdmap_state_str(char *str, int len, int state);
+
+static inline struct ceph_entity_addr *ceph_osd_addr(struct ceph_osdmap *map,
+ int osd)
+{
+ if (osd >= map->max_osd)
+ return NULL;
+ return &map->osd_addr[osd];
+}
+
+extern struct ceph_osdmap *osdmap_decode(void **p, void *end);
+extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+ struct ceph_osdmap *map,
+ struct ceph_messenger *msgr);
+extern void ceph_osdmap_destroy(struct ceph_osdmap *map);
+
+/* calculate mapping of a file extent to an object */
+extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+ u64 off, u64 *plen,
+ u64 *bno, u64 *oxoff, u64 *oxlen);
+
+/* calculate mapping of object to a placement group */
+extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
+ const char *oid,
+ struct ceph_file_layout *fl,
+ struct ceph_osdmap *osdmap);
+extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap,
+ struct ceph_pg pgid);
+
+#endif
diff --git a/fs/ceph/pagelist.c b/fs/ceph/pagelist.c
new file mode 100644
index 00000000000..5f8dbf7c745
--- /dev/null
+++ b/fs/ceph/pagelist.c
@@ -0,0 +1,55 @@
+
+#include <linux/gfp.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+
+#include "pagelist.h"
+
+int ceph_pagelist_release(struct ceph_pagelist *pl)
+{
+ if (pl->mapped_tail)
+ kunmap(pl->mapped_tail);
+ while (!list_empty(&pl->head)) {
+ struct page *page = list_first_entry(&pl->head, struct page,
+ lru);
+ list_del(&page->lru);
+ __free_page(page);
+ }
+ return 0;
+}
+
+static int ceph_pagelist_addpage(struct ceph_pagelist *pl)
+{
+ struct page *page = alloc_page(GFP_NOFS);
+ if (!page)
+ return -ENOMEM;
+ pl->room += PAGE_SIZE;
+ list_add_tail(&page->lru, &pl->head);
+ if (pl->mapped_tail)
+ kunmap(pl->mapped_tail);
+ pl->mapped_tail = kmap(page);
+ return 0;
+}
+
+int ceph_pagelist_append(struct ceph_pagelist *pl, void *buf, size_t len)
+{
+ while (pl->room < len) {
+ size_t bit = pl->room;
+ int ret;
+
+ memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK),
+ buf, bit);
+ pl->length += bit;
+ pl->room -= bit;
+ buf += bit;
+ len -= bit;
+ ret = ceph_pagelist_addpage(pl);
+ if (ret)
+ return ret;
+ }
+
+ memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), buf, len);
+ pl->length += len;
+ pl->room -= len;
+ return 0;
+}
diff --git a/fs/ceph/pagelist.h b/fs/ceph/pagelist.h
new file mode 100644
index 00000000000..e8a4187e108
--- /dev/null
+++ b/fs/ceph/pagelist.h
@@ -0,0 +1,54 @@
+#ifndef __FS_CEPH_PAGELIST_H
+#define __FS_CEPH_PAGELIST_H
+
+#include <linux/list.h>
+
+struct ceph_pagelist {
+ struct list_head head;
+ void *mapped_tail;
+ size_t length;
+ size_t room;
+};
+
+static inline void ceph_pagelist_init(struct ceph_pagelist *pl)
+{
+ INIT_LIST_HEAD(&pl->head);
+ pl->mapped_tail = NULL;
+ pl->length = 0;
+ pl->room = 0;
+}
+extern int ceph_pagelist_release(struct ceph_pagelist *pl);
+
+extern int ceph_pagelist_append(struct ceph_pagelist *pl, void *d, size_t l);
+
+static inline int ceph_pagelist_encode_64(struct ceph_pagelist *pl, u64 v)
+{
+ __le64 ev = cpu_to_le64(v);
+ return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_32(struct ceph_pagelist *pl, u32 v)
+{
+ __le32 ev = cpu_to_le32(v);
+ return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_16(struct ceph_pagelist *pl, u16 v)
+{
+ __le16 ev = cpu_to_le16(v);
+ return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_8(struct ceph_pagelist *pl, u8 v)
+{
+ return ceph_pagelist_append(pl, &v, 1);
+}
+static inline int ceph_pagelist_encode_string(struct ceph_pagelist *pl,
+ char *s, size_t len)
+{
+ int ret = ceph_pagelist_encode_32(pl, len);
+ if (ret)
+ return ret;
+ if (len)
+ return ceph_pagelist_append(pl, s, len);
+ return 0;
+}
+
+#endif
diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h
new file mode 100644
index 00000000000..a1fc1d017b5
--- /dev/null
+++ b/fs/ceph/rados.h
@@ -0,0 +1,376 @@
+#ifndef __RADOS_H
+#define __RADOS_H
+
+/*
+ * Data types for the Ceph distributed object storage layer RADOS
+ * (Reliable Autonomic Distributed Object Store).
+ */
+
+#include "msgr.h"
+
+/*
+ * osdmap encoding versions
+ */
+#define CEPH_OSDMAP_INC_VERSION 5
+#define CEPH_OSDMAP_INC_VERSION_EXT 5
+#define CEPH_OSDMAP_VERSION 5
+#define CEPH_OSDMAP_VERSION_EXT 5
+
+/*
+ * fs id
+ */
+struct ceph_fsid {
+ unsigned char fsid[16];
+};
+
+static inline int ceph_fsid_compare(const struct ceph_fsid *a,
+ const struct ceph_fsid *b)
+{
+ return memcmp(a, b, sizeof(*a));
+}
+
+/*
+ * ino, object, etc.
+ */
+typedef __le64 ceph_snapid_t;
+#define CEPH_SNAPDIR ((__u64)(-1)) /* reserved for hidden .snap dir */
+#define CEPH_NOSNAP ((__u64)(-2)) /* "head", "live" revision */
+#define CEPH_MAXSNAP ((__u64)(-3)) /* largest valid snapid */
+
+struct ceph_timespec {
+ __le32 tv_sec;
+ __le32 tv_nsec;
+} __attribute__ ((packed));
+
+
+/*
+ * object layout - how objects are mapped into PGs
+ */
+#define CEPH_OBJECT_LAYOUT_HASH 1
+#define CEPH_OBJECT_LAYOUT_LINEAR 2
+#define CEPH_OBJECT_LAYOUT_HASHINO 3
+
+/*
+ * pg layout -- how PGs are mapped onto (sets of) OSDs
+ */
+#define CEPH_PG_LAYOUT_CRUSH 0
+#define CEPH_PG_LAYOUT_HASH 1
+#define CEPH_PG_LAYOUT_LINEAR 2
+#define CEPH_PG_LAYOUT_HYBRID 3
+
+
+/*
+ * placement group.
+ * we encode this into one __le64.
+ */
+struct ceph_pg {
+ __le16 preferred; /* preferred primary osd */
+ __le16 ps; /* placement seed */
+ __le32 pool; /* object pool */
+} __attribute__ ((packed));
+
+/*
+ * pg_pool is a set of pgs storing a pool of objects
+ *
+ * pg_num -- base number of pseudorandomly placed pgs
+ *
+ * pgp_num -- effective number when calculating pg placement. this
+ * is used for pg_num increases. new pgs result in data being "split"
+ * into new pgs. for this to proceed smoothly, new pgs are intiially
+ * colocated with their parents; that is, pgp_num doesn't increase
+ * until the new pgs have successfully split. only _then_ are the new
+ * pgs placed independently.
+ *
+ * lpg_num -- localized pg count (per device). replicas are randomly
+ * selected.
+ *
+ * lpgp_num -- as above.
+ */
+#define CEPH_PG_TYPE_REP 1
+#define CEPH_PG_TYPE_RAID4 2
+#define CEPH_PG_POOL_VERSION 2
+struct ceph_pg_pool {
+ __u8 type; /* CEPH_PG_TYPE_* */
+ __u8 size; /* number of osds in each pg */
+ __u8 crush_ruleset; /* crush placement rule */
+ __u8 object_hash; /* hash mapping object name to ps */
+ __le32 pg_num, pgp_num; /* number of pg's */
+ __le32 lpg_num, lpgp_num; /* number of localized pg's */
+ __le32 last_change; /* most recent epoch changed */
+ __le64 snap_seq; /* seq for per-pool snapshot */
+ __le32 snap_epoch; /* epoch of last snap */
+ __le32 num_snaps;
+ __le32 num_removed_snap_intervals;
+ __le64 uid;
+} __attribute__ ((packed));
+
+/*
+ * stable_mod func is used to control number of placement groups.
+ * similar to straight-up modulo, but produces a stable mapping as b
+ * increases over time. b is the number of bins, and bmask is the
+ * containing power of 2 minus 1.
+ *
+ * b <= bmask and bmask=(2**n)-1
+ * e.g., b=12 -> bmask=15, b=123 -> bmask=127
+ */
+static inline int ceph_stable_mod(int x, int b, int bmask)
+{
+ if ((x & bmask) < b)
+ return x & bmask;
+ else
+ return x & (bmask >> 1);
+}
+
+/*
+ * object layout - how a given object should be stored.
+ */
+struct ceph_object_layout {
+ struct ceph_pg ol_pgid; /* raw pg, with _full_ ps precision. */
+ __le32 ol_stripe_unit; /* for per-object parity, if any */
+} __attribute__ ((packed));
+
+/*
+ * compound epoch+version, used by storage layer to serialize mutations
+ */
+struct ceph_eversion {
+ __le32 epoch;
+ __le64 version;
+} __attribute__ ((packed));
+
+/*
+ * osd map bits
+ */
+
+/* status bits */
+#define CEPH_OSD_EXISTS 1
+#define CEPH_OSD_UP 2
+
+/* osd weights. fixed point value: 0x10000 == 1.0 ("in"), 0 == "out" */
+#define CEPH_OSD_IN 0x10000
+#define CEPH_OSD_OUT 0
+
+
+/*
+ * osd map flag bits
+ */
+#define CEPH_OSDMAP_NEARFULL (1<<0) /* sync writes (near ENOSPC) */
+#define CEPH_OSDMAP_FULL (1<<1) /* no data writes (ENOSPC) */
+#define CEPH_OSDMAP_PAUSERD (1<<2) /* pause all reads */
+#define CEPH_OSDMAP_PAUSEWR (1<<3) /* pause all writes */
+#define CEPH_OSDMAP_PAUSEREC (1<<4) /* pause recovery */
+
+/*
+ * osd ops
+ */
+#define CEPH_OSD_OP_MODE 0xf000
+#define CEPH_OSD_OP_MODE_RD 0x1000
+#define CEPH_OSD_OP_MODE_WR 0x2000
+#define CEPH_OSD_OP_MODE_RMW 0x3000
+#define CEPH_OSD_OP_MODE_SUB 0x4000
+
+#define CEPH_OSD_OP_TYPE 0x0f00
+#define CEPH_OSD_OP_TYPE_LOCK 0x0100
+#define CEPH_OSD_OP_TYPE_DATA 0x0200
+#define CEPH_OSD_OP_TYPE_ATTR 0x0300
+#define CEPH_OSD_OP_TYPE_EXEC 0x0400
+#define CEPH_OSD_OP_TYPE_PG 0x0500
+
+enum {
+ /** data **/
+ /* read */
+ CEPH_OSD_OP_READ = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 1,
+ CEPH_OSD_OP_STAT = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 2,
+
+ /* fancy read */
+ CEPH_OSD_OP_MASKTRUNC = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 4,
+
+ /* write */
+ CEPH_OSD_OP_WRITE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 1,
+ CEPH_OSD_OP_WRITEFULL = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 2,
+ CEPH_OSD_OP_TRUNCATE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 3,
+ CEPH_OSD_OP_ZERO = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 4,
+ CEPH_OSD_OP_DELETE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 5,
+
+ /* fancy write */
+ CEPH_OSD_OP_APPEND = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 6,
+ CEPH_OSD_OP_STARTSYNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 7,
+ CEPH_OSD_OP_SETTRUNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 8,
+ CEPH_OSD_OP_TRIMTRUNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 9,
+
+ CEPH_OSD_OP_TMAPUP = CEPH_OSD_OP_MODE_RMW | CEPH_OSD_OP_TYPE_DATA | 10,
+ CEPH_OSD_OP_TMAPPUT = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 11,
+ CEPH_OSD_OP_TMAPGET = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 12,
+
+ CEPH_OSD_OP_CREATE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 13,
+
+ /** attrs **/
+ /* read */
+ CEPH_OSD_OP_GETXATTR = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 1,
+ CEPH_OSD_OP_GETXATTRS = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 2,
+
+ /* write */
+ CEPH_OSD_OP_SETXATTR = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 1,
+ CEPH_OSD_OP_SETXATTRS = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 2,
+ CEPH_OSD_OP_RESETXATTRS = CEPH_OSD_OP_MODE_WR|CEPH_OSD_OP_TYPE_ATTR | 3,
+ CEPH_OSD_OP_RMXATTR = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 4,
+
+ /** subop **/
+ CEPH_OSD_OP_PULL = CEPH_OSD_OP_MODE_SUB | 1,
+ CEPH_OSD_OP_PUSH = CEPH_OSD_OP_MODE_SUB | 2,
+ CEPH_OSD_OP_BALANCEREADS = CEPH_OSD_OP_MODE_SUB | 3,
+ CEPH_OSD_OP_UNBALANCEREADS = CEPH_OSD_OP_MODE_SUB | 4,
+ CEPH_OSD_OP_SCRUB = CEPH_OSD_OP_MODE_SUB | 5,
+
+ /** lock **/
+ CEPH_OSD_OP_WRLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 1,
+ CEPH_OSD_OP_WRUNLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 2,
+ CEPH_OSD_OP_RDLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 3,
+ CEPH_OSD_OP_RDUNLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 4,
+ CEPH_OSD_OP_UPLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 5,
+ CEPH_OSD_OP_DNLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 6,
+
+ /** exec **/
+ CEPH_OSD_OP_CALL = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_EXEC | 1,
+
+ /** pg **/
+ CEPH_OSD_OP_PGLS = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_PG | 1,
+};
+
+static inline int ceph_osd_op_type_lock(int op)
+{
+ return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_LOCK;
+}
+static inline int ceph_osd_op_type_data(int op)
+{
+ return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_DATA;
+}
+static inline int ceph_osd_op_type_attr(int op)
+{
+ return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_ATTR;
+}
+static inline int ceph_osd_op_type_exec(int op)
+{
+ return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_EXEC;
+}
+static inline int ceph_osd_op_type_pg(int op)
+{
+ return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_PG;
+}
+
+static inline int ceph_osd_op_mode_subop(int op)
+{
+ return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_SUB;
+}
+static inline int ceph_osd_op_mode_read(int op)
+{
+ return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_RD;
+}
+static inline int ceph_osd_op_mode_modify(int op)
+{
+ return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_WR;
+}
+
+#define CEPH_OSD_TMAP_HDR 'h'
+#define CEPH_OSD_TMAP_SET 's'
+#define CEPH_OSD_TMAP_RM 'r'
+
+extern const char *ceph_osd_op_name(int op);
+
+
+/*
+ * osd op flags
+ *
+ * An op may be READ, WRITE, or READ|WRITE.
+ */
+enum {
+ CEPH_OSD_FLAG_ACK = 1, /* want (or is) "ack" ack */
+ CEPH_OSD_FLAG_ONNVRAM = 2, /* want (or is) "onnvram" ack */
+ CEPH_OSD_FLAG_ONDISK = 4, /* want (or is) "ondisk" ack */
+ CEPH_OSD_FLAG_RETRY = 8, /* resend attempt */
+ CEPH_OSD_FLAG_READ = 16, /* op may read */
+ CEPH_OSD_FLAG_WRITE = 32, /* op may write */
+ CEPH_OSD_FLAG_ORDERSNAP = 64, /* EOLDSNAP if snapc is out of order */
+ CEPH_OSD_FLAG_PEERSTAT = 128, /* msg includes osd_peer_stat */
+ CEPH_OSD_FLAG_BALANCE_READS = 256,
+ CEPH_OSD_FLAG_PARALLELEXEC = 512, /* execute op in parallel */
+ CEPH_OSD_FLAG_PGOP = 1024, /* pg op, no object */
+ CEPH_OSD_FLAG_EXEC = 2048, /* op may exec */
+};
+
+enum {
+ CEPH_OSD_OP_FLAG_EXCL = 1, /* EXCL object create */
+};
+
+#define EOLDSNAPC ERESTART /* ORDERSNAP flag set; writer has old snapc*/
+#define EBLACKLISTED ESHUTDOWN /* blacklisted */
+
+/*
+ * an individual object operation. each may be accompanied by some data
+ * payload
+ */
+struct ceph_osd_op {
+ __le16 op; /* CEPH_OSD_OP_* */
+ __le32 flags; /* CEPH_OSD_FLAG_* */
+ union {
+ struct {
+ __le64 offset, length;
+ __le64 truncate_size;
+ __le32 truncate_seq;
+ } __attribute__ ((packed)) extent;
+ struct {
+ __le32 name_len;
+ __le32 value_len;
+ } __attribute__ ((packed)) xattr;
+ struct {
+ __u8 class_len;
+ __u8 method_len;
+ __u8 argc;
+ __le32 indata_len;
+ } __attribute__ ((packed)) cls;
+ struct {
+ __le64 cookie, count;
+ } __attribute__ ((packed)) pgls;
+ };
+ __le32 payload_len;
+} __attribute__ ((packed));
+
+/*
+ * osd request message header. each request may include multiple
+ * ceph_osd_op object operations.
+ */
+struct ceph_osd_request_head {
+ __le32 client_inc; /* client incarnation */
+ struct ceph_object_layout layout; /* pgid */
+ __le32 osdmap_epoch; /* client's osdmap epoch */
+
+ __le32 flags;
+
+ struct ceph_timespec mtime; /* for mutations only */
+ struct ceph_eversion reassert_version; /* if we are replaying op */
+
+ __le32 object_len; /* length of object name */
+
+ __le64 snapid; /* snapid to read */
+ __le64 snap_seq; /* writer's snap context */
+ __le32 num_snaps;
+
+ __le16 num_ops;
+ struct ceph_osd_op ops[]; /* followed by ops[], obj, ticket, snaps */
+} __attribute__ ((packed));
+
+struct ceph_osd_reply_head {
+ __le32 client_inc; /* client incarnation */
+ __le32 flags;
+ struct ceph_object_layout layout;
+ __le32 osdmap_epoch;
+ struct ceph_eversion reassert_version; /* for replaying uncommitted */
+
+ __le32 result; /* result code */
+
+ __le32 object_len; /* length of object name */
+ __le32 num_ops;
+ struct ceph_osd_op ops[0]; /* ops[], object */
+} __attribute__ ((packed));
+
+
+#endif
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
new file mode 100644
index 00000000000..2b881262ef6
--- /dev/null
+++ b/fs/ceph/snap.c
@@ -0,0 +1,907 @@
+#include "ceph_debug.h"
+
+#include <linux/sort.h>
+#include <linux/slab.h>
+
+#include "super.h"
+#include "decode.h"
+
+/*
+ * Snapshots in ceph are driven in large part by cooperation from the
+ * client. In contrast to local file systems or file servers that
+ * implement snapshots at a single point in the system, ceph's
+ * distributed access to storage requires clients to help decide
+ * whether a write logically occurs before or after a recently created
+ * snapshot.
+ *
+ * This provides a perfect instantanous client-wide snapshot. Between
+ * clients, however, snapshots may appear to be applied at slightly
+ * different points in time, depending on delays in delivering the
+ * snapshot notification.
+ *
+ * Snapshots are _not_ file system-wide. Instead, each snapshot
+ * applies to the subdirectory nested beneath some directory. This
+ * effectively divides the hierarchy into multiple "realms," where all
+ * of the files contained by each realm share the same set of
+ * snapshots. An individual realm's snap set contains snapshots
+ * explicitly created on that realm, as well as any snaps in its
+ * parent's snap set _after_ the point at which the parent became it's
+ * parent (due to, say, a rename). Similarly, snaps from prior parents
+ * during the time intervals during which they were the parent are included.
+ *
+ * The client is spared most of this detail, fortunately... it must only
+ * maintains a hierarchy of realms reflecting the current parent/child
+ * realm relationship, and for each realm has an explicit list of snaps
+ * inherited from prior parents.
+ *
+ * A snap_realm struct is maintained for realms containing every inode
+ * with an open cap in the system. (The needed snap realm information is
+ * provided by the MDS whenever a cap is issued, i.e., on open.) A 'seq'
+ * version number is used to ensure that as realm parameters change (new
+ * snapshot, new parent, etc.) the client's realm hierarchy is updated.
+ *
+ * The realm hierarchy drives the generation of a 'snap context' for each
+ * realm, which simply lists the resulting set of snaps for the realm. This
+ * is attached to any writes sent to OSDs.
+ */
+/*
+ * Unfortunately error handling is a bit mixed here. If we get a snap
+ * update, but don't have enough memory to update our realm hierarchy,
+ * it's not clear what we can do about it (besides complaining to the
+ * console).
+ */
+
+
+/*
+ * increase ref count for the realm
+ *
+ * caller must hold snap_rwsem for write.
+ */
+void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+{
+ dout("get_realm %p %d -> %d\n", realm,
+ atomic_read(&realm->nref), atomic_read(&realm->nref)+1);
+ /*
+ * since we _only_ increment realm refs or empty the empty
+ * list with snap_rwsem held, adjusting the empty list here is
+ * safe. we do need to protect against concurrent empty list
+ * additions, however.
+ */
+ if (atomic_read(&realm->nref) == 0) {
+ spin_lock(&mdsc->snap_empty_lock);
+ list_del_init(&realm->empty_item);
+ spin_unlock(&mdsc->snap_empty_lock);
+ }
+
+ atomic_inc(&realm->nref);
+}
+
+static void __insert_snap_realm(struct rb_root *root,
+ struct ceph_snap_realm *new)
+{
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+ struct ceph_snap_realm *r = NULL;
+
+ while (*p) {
+ parent = *p;
+ r = rb_entry(parent, struct ceph_snap_realm, node);
+ if (new->ino < r->ino)
+ p = &(*p)->rb_left;
+ else if (new->ino > r->ino)
+ p = &(*p)->rb_right;
+ else
+ BUG();
+ }
+
+ rb_link_node(&new->node, parent, p);
+ rb_insert_color(&new->node, root);
+}
+
+/*
+ * create and get the realm rooted at @ino and bump its ref count.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+static struct ceph_snap_realm *ceph_create_snap_realm(
+ struct ceph_mds_client *mdsc,
+ u64 ino)
+{
+ struct ceph_snap_realm *realm;
+
+ realm = kzalloc(sizeof(*realm), GFP_NOFS);
+ if (!realm)
+ return ERR_PTR(-ENOMEM);
+
+ atomic_set(&realm->nref, 0); /* tree does not take a ref */
+ realm->ino = ino;
+ INIT_LIST_HEAD(&realm->children);
+ INIT_LIST_HEAD(&realm->child_item);
+ INIT_LIST_HEAD(&realm->empty_item);
+ INIT_LIST_HEAD(&realm->inodes_with_caps);
+ spin_lock_init(&realm->inodes_with_caps_lock);
+ __insert_snap_realm(&mdsc->snap_realms, realm);
+ dout("create_snap_realm %llx %p\n", realm->ino, realm);
+ return realm;
+}
+
+/*
+ * lookup the realm rooted at @ino.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
+ u64 ino)
+{
+ struct rb_node *n = mdsc->snap_realms.rb_node;
+ struct ceph_snap_realm *r;
+
+ while (n) {
+ r = rb_entry(n, struct ceph_snap_realm, node);
+ if (ino < r->ino)
+ n = n->rb_left;
+ else if (ino > r->ino)
+ n = n->rb_right;
+ else {
+ dout("lookup_snap_realm %llx %p\n", r->ino, r);
+ return r;
+ }
+ }
+ return NULL;
+}
+
+static void __put_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm);
+
+/*
+ * called with snap_rwsem (write)
+ */
+static void __destroy_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+{
+ dout("__destroy_snap_realm %p %llx\n", realm, realm->ino);
+
+ rb_erase(&realm->node, &mdsc->snap_realms);
+
+ if (realm->parent) {
+ list_del_init(&realm->child_item);
+ __put_snap_realm(mdsc, realm->parent);
+ }
+
+ kfree(realm->prior_parent_snaps);
+ kfree(realm->snaps);
+ ceph_put_snap_context(realm->cached_context);
+ kfree(realm);
+}
+
+/*
+ * caller holds snap_rwsem (write)
+ */
+static void __put_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+{
+ dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+ atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
+ if (atomic_dec_and_test(&realm->nref))
+ __destroy_snap_realm(mdsc, realm);
+}
+
+/*
+ * caller needn't hold any locks
+ */
+void ceph_put_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+{
+ dout("put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+ atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
+ if (!atomic_dec_and_test(&realm->nref))
+ return;
+
+ if (down_write_trylock(&mdsc->snap_rwsem)) {
+ __destroy_snap_realm(mdsc, realm);
+ up_write(&mdsc->snap_rwsem);
+ } else {
+ spin_lock(&mdsc->snap_empty_lock);
+ list_add(&mdsc->snap_empty, &realm->empty_item);
+ spin_unlock(&mdsc->snap_empty_lock);
+ }
+}
+
+/*
+ * Clean up any realms whose ref counts have dropped to zero. Note
+ * that this does not include realms who were created but not yet
+ * used.
+ *
+ * Called under snap_rwsem (write)
+ */
+static void __cleanup_empty_realms(struct ceph_mds_client *mdsc)
+{
+ struct ceph_snap_realm *realm;
+
+ spin_lock(&mdsc->snap_empty_lock);
+ while (!list_empty(&mdsc->snap_empty)) {
+ realm = list_first_entry(&mdsc->snap_empty,
+ struct ceph_snap_realm, empty_item);
+ list_del(&realm->empty_item);
+ spin_unlock(&mdsc->snap_empty_lock);
+ __destroy_snap_realm(mdsc, realm);
+ spin_lock(&mdsc->snap_empty_lock);
+ }
+ spin_unlock(&mdsc->snap_empty_lock);
+}
+
+void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc)
+{
+ down_write(&mdsc->snap_rwsem);
+ __cleanup_empty_realms(mdsc);
+ up_write(&mdsc->snap_rwsem);
+}
+
+/*
+ * adjust the parent realm of a given @realm. adjust child list, and parent
+ * pointers, and ref counts appropriately.
+ *
+ * return true if parent was changed, 0 if unchanged, <0 on error.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm,
+ u64 parentino)
+{
+ struct ceph_snap_realm *parent;
+
+ if (realm->parent_ino == parentino)
+ return 0;
+
+ parent = ceph_lookup_snap_realm(mdsc, parentino);
+ if (!parent) {
+ parent = ceph_create_snap_realm(mdsc, parentino);
+ if (IS_ERR(parent))
+ return PTR_ERR(parent);
+ }
+ dout("adjust_snap_realm_parent %llx %p: %llx %p -> %llx %p\n",
+ realm->ino, realm, realm->parent_ino, realm->parent,
+ parentino, parent);
+ if (realm->parent) {
+ list_del_init(&realm->child_item);
+ ceph_put_snap_realm(mdsc, realm->parent);
+ }
+ realm->parent_ino = parentino;
+ realm->parent = parent;
+ ceph_get_snap_realm(mdsc, parent);
+ list_add(&realm->child_item, &parent->children);
+ return 1;
+}
+
+
+static int cmpu64_rev(const void *a, const void *b)
+{
+ if (*(u64 *)a < *(u64 *)b)
+ return 1;
+ if (*(u64 *)a > *(u64 *)b)
+ return -1;
+ return 0;
+}
+
+/*
+ * build the snap context for a given realm.
+ */
+static int build_snap_context(struct ceph_snap_realm *realm)
+{
+ struct ceph_snap_realm *parent = realm->parent;
+ struct ceph_snap_context *snapc;
+ int err = 0;
+ int i;
+ int num = realm->num_prior_parent_snaps + realm->num_snaps;
+
+ /*
+ * build parent context, if it hasn't been built.
+ * conservatively estimate that all parent snaps might be
+ * included by us.
+ */
+ if (parent) {
+ if (!parent->cached_context) {
+ err = build_snap_context(parent);
+ if (err)
+ goto fail;
+ }
+ num += parent->cached_context->num_snaps;
+ }
+
+ /* do i actually need to update? not if my context seq
+ matches realm seq, and my parents' does to. (this works
+ because we rebuild_snap_realms() works _downward_ in
+ hierarchy after each update.) */
+ if (realm->cached_context &&
+ realm->cached_context->seq == realm->seq &&
+ (!parent ||
+ realm->cached_context->seq >= parent->cached_context->seq)) {
+ dout("build_snap_context %llx %p: %p seq %lld (%d snaps)"
+ " (unchanged)\n",
+ realm->ino, realm, realm->cached_context,
+ realm->cached_context->seq,
+ realm->cached_context->num_snaps);
+ return 0;
+ }
+
+ /* alloc new snap context */
+ err = -ENOMEM;
+ if (num > ULONG_MAX / sizeof(u64) - sizeof(*snapc))
+ goto fail;
+ snapc = kzalloc(sizeof(*snapc) + num*sizeof(u64), GFP_NOFS);
+ if (!snapc)
+ goto fail;
+ atomic_set(&snapc->nref, 1);
+
+ /* build (reverse sorted) snap vector */
+ num = 0;
+ snapc->seq = realm->seq;
+ if (parent) {
+ /* include any of parent's snaps occuring _after_ my
+ parent became my parent */
+ for (i = 0; i < parent->cached_context->num_snaps; i++)
+ if (parent->cached_context->snaps[i] >=
+ realm->parent_since)
+ snapc->snaps[num++] =
+ parent->cached_context->snaps[i];
+ if (parent->cached_context->seq > snapc->seq)
+ snapc->seq = parent->cached_context->seq;
+ }
+ memcpy(snapc->snaps + num, realm->snaps,
+ sizeof(u64)*realm->num_snaps);
+ num += realm->num_snaps;
+ memcpy(snapc->snaps + num, realm->prior_parent_snaps,
+ sizeof(u64)*realm->num_prior_parent_snaps);
+ num += realm->num_prior_parent_snaps;
+
+ sort(snapc->snaps, num, sizeof(u64), cmpu64_rev, NULL);
+ snapc->num_snaps = num;
+ dout("build_snap_context %llx %p: %p seq %lld (%d snaps)\n",
+ realm->ino, realm, snapc, snapc->seq, snapc->num_snaps);
+
+ if (realm->cached_context)
+ ceph_put_snap_context(realm->cached_context);
+ realm->cached_context = snapc;
+ return 0;
+
+fail:
+ /*
+ * if we fail, clear old (incorrect) cached_context... hopefully
+ * we'll have better luck building it later
+ */
+ if (realm->cached_context) {
+ ceph_put_snap_context(realm->cached_context);
+ realm->cached_context = NULL;
+ }
+ pr_err("build_snap_context %llx %p fail %d\n", realm->ino,
+ realm, err);
+ return err;
+}
+
+/*
+ * rebuild snap context for the given realm and all of its children.
+ */
+static void rebuild_snap_realms(struct ceph_snap_realm *realm)
+{
+ struct ceph_snap_realm *child;
+
+ dout("rebuild_snap_realms %llx %p\n", realm->ino, realm);
+ build_snap_context(realm);
+
+ list_for_each_entry(child, &realm->children, child_item)
+ rebuild_snap_realms(child);
+}
+
+
+/*
+ * helper to allocate and decode an array of snapids. free prior
+ * instance, if any.
+ */
+static int dup_array(u64 **dst, __le64 *src, int num)
+{
+ int i;
+
+ kfree(*dst);
+ if (num) {
+ *dst = kcalloc(num, sizeof(u64), GFP_NOFS);
+ if (!*dst)
+ return -ENOMEM;
+ for (i = 0; i < num; i++)
+ (*dst)[i] = get_unaligned_le64(src + i);
+ } else {
+ *dst = NULL;
+ }
+ return 0;
+}
+
+
+/*
+ * When a snapshot is applied, the size/mtime inode metadata is queued
+ * in a ceph_cap_snap (one for each snapshot) until writeback
+ * completes and the metadata can be flushed back to the MDS.
+ *
+ * However, if a (sync) write is currently in-progress when we apply
+ * the snapshot, we have to wait until the write succeeds or fails
+ * (and a final size/mtime is known). In this case the
+ * cap_snap->writing = 1, and is said to be "pending." When the write
+ * finishes, we __ceph_finish_cap_snap().
+ *
+ * Caller must hold snap_rwsem for read (i.e., the realm topology won't
+ * change).
+ */
+void ceph_queue_cap_snap(struct ceph_inode_info *ci)
+{
+ struct inode *inode = &ci->vfs_inode;
+ struct ceph_cap_snap *capsnap;
+ int used;
+
+ capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS);
+ if (!capsnap) {
+ pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode);
+ return;
+ }
+
+ spin_lock(&inode->i_lock);
+ used = __ceph_caps_used(ci);
+ if (__ceph_have_pending_cap_snap(ci)) {
+ /* there is no point in queuing multiple "pending" cap_snaps,
+ as no new writes are allowed to start when pending, so any
+ writes in progress now were started before the previous
+ cap_snap. lucky us. */
+ dout("queue_cap_snap %p already pending\n", inode);
+ kfree(capsnap);
+ } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) {
+ struct ceph_snap_context *snapc = ci->i_head_snapc;
+
+ igrab(inode);
+
+ atomic_set(&capsnap->nref, 1);
+ capsnap->ci = ci;
+ INIT_LIST_HEAD(&capsnap->ci_item);
+ INIT_LIST_HEAD(&capsnap->flushing_item);
+
+ capsnap->follows = snapc->seq - 1;
+ capsnap->issued = __ceph_caps_issued(ci, NULL);
+ capsnap->dirty = __ceph_caps_dirty(ci);
+
+ capsnap->mode = inode->i_mode;
+ capsnap->uid = inode->i_uid;
+ capsnap->gid = inode->i_gid;
+
+ /* fixme? */
+ capsnap->xattr_blob = NULL;
+ capsnap->xattr_len = 0;
+
+ /* dirty page count moved from _head to this cap_snap;
+ all subsequent writes page dirties occur _after_ this
+ snapshot. */
+ capsnap->dirty_pages = ci->i_wrbuffer_ref_head;
+ ci->i_wrbuffer_ref_head = 0;
+ capsnap->context = snapc;
+ ci->i_head_snapc = NULL;
+ list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps);
+
+ if (used & CEPH_CAP_FILE_WR) {
+ dout("queue_cap_snap %p cap_snap %p snapc %p"
+ " seq %llu used WR, now pending\n", inode,
+ capsnap, snapc, snapc->seq);
+ capsnap->writing = 1;
+ } else {
+ /* note mtime, size NOW. */
+ __ceph_finish_cap_snap(ci, capsnap);
+ }
+ } else {
+ dout("queue_cap_snap %p nothing dirty|writing\n", inode);
+ kfree(capsnap);
+ }
+
+ spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Finalize the size, mtime for a cap_snap.. that is, settle on final values
+ * to be used for the snapshot, to be flushed back to the mds.
+ *
+ * If capsnap can now be flushed, add to snap_flush list, and return 1.
+ *
+ * Caller must hold i_lock.
+ */
+int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
+ struct ceph_cap_snap *capsnap)
+{
+ struct inode *inode = &ci->vfs_inode;
+ struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+
+ BUG_ON(capsnap->writing);
+ capsnap->size = inode->i_size;
+ capsnap->mtime = inode->i_mtime;
+ capsnap->atime = inode->i_atime;
+ capsnap->ctime = inode->i_ctime;
+ capsnap->time_warp_seq = ci->i_time_warp_seq;
+ if (capsnap->dirty_pages) {
+ dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu "
+ "still has %d dirty pages\n", inode, capsnap,
+ capsnap->context, capsnap->context->seq,
+ ceph_cap_string(capsnap->dirty), capsnap->size,
+ capsnap->dirty_pages);
+ return 0;
+ }
+ dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n",
+ inode, capsnap, capsnap->context,
+ capsnap->context->seq, ceph_cap_string(capsnap->dirty),
+ capsnap->size);
+
+ spin_lock(&mdsc->snap_flush_lock);
+ list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list);
+ spin_unlock(&mdsc->snap_flush_lock);
+ return 1; /* caller may want to ceph_flush_snaps */
+}
+
+
+/*
+ * Parse and apply a snapblob "snap trace" from the MDS. This specifies
+ * the snap realm parameters from a given realm and all of its ancestors,
+ * up to the root.
+ *
+ * Caller must hold snap_rwsem for write.
+ */
+int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+ void *p, void *e, bool deletion)
+{
+ struct ceph_mds_snap_realm *ri; /* encoded */
+ __le64 *snaps; /* encoded */
+ __le64 *prior_parent_snaps; /* encoded */
+ struct ceph_snap_realm *realm;
+ int invalidate = 0;
+ int err = -ENOMEM;
+
+ dout("update_snap_trace deletion=%d\n", deletion);
+more:
+ ceph_decode_need(&p, e, sizeof(*ri), bad);
+ ri = p;
+ p += sizeof(*ri);
+ ceph_decode_need(&p, e, sizeof(u64)*(le32_to_cpu(ri->num_snaps) +
+ le32_to_cpu(ri->num_prior_parent_snaps)), bad);
+ snaps = p;
+ p += sizeof(u64) * le32_to_cpu(ri->num_snaps);
+ prior_parent_snaps = p;
+ p += sizeof(u64) * le32_to_cpu(ri->num_prior_parent_snaps);
+
+ realm = ceph_lookup_snap_realm(mdsc, le64_to_cpu(ri->ino));
+ if (!realm) {
+ realm = ceph_create_snap_realm(mdsc, le64_to_cpu(ri->ino));
+ if (IS_ERR(realm)) {
+ err = PTR_ERR(realm);
+ goto fail;
+ }
+ }
+
+ if (le64_to_cpu(ri->seq) > realm->seq) {
+ dout("update_snap_trace updating %llx %p %lld -> %lld\n",
+ realm->ino, realm, realm->seq, le64_to_cpu(ri->seq));
+ /*
+ * if the realm seq has changed, queue a cap_snap for every
+ * inode with open caps. we do this _before_ we update
+ * the realm info so that we prepare for writeback under the
+ * _previous_ snap context.
+ *
+ * ...unless it's a snap deletion!
+ */
+ if (!deletion) {
+ struct ceph_inode_info *ci;
+ struct inode *lastinode = NULL;
+
+ spin_lock(&realm->inodes_with_caps_lock);
+ list_for_each_entry(ci, &realm->inodes_with_caps,
+ i_snap_realm_item) {
+ struct inode *inode = igrab(&ci->vfs_inode);
+ if (!inode)
+ continue;
+ spin_unlock(&realm->inodes_with_caps_lock);
+ if (lastinode)
+ iput(lastinode);
+ lastinode = inode;
+ ceph_queue_cap_snap(ci);
+ spin_lock(&realm->inodes_with_caps_lock);
+ }
+ spin_unlock(&realm->inodes_with_caps_lock);
+ if (lastinode)
+ iput(lastinode);
+ dout("update_snap_trace cap_snaps queued\n");
+ }
+
+ } else {
+ dout("update_snap_trace %llx %p seq %lld unchanged\n",
+ realm->ino, realm, realm->seq);
+ }
+
+ /* ensure the parent is correct */
+ err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent));
+ if (err < 0)
+ goto fail;
+ invalidate += err;
+
+ if (le64_to_cpu(ri->seq) > realm->seq) {
+ /* update realm parameters, snap lists */
+ realm->seq = le64_to_cpu(ri->seq);
+ realm->created = le64_to_cpu(ri->created);
+ realm->parent_since = le64_to_cpu(ri->parent_since);
+
+ realm->num_snaps = le32_to_cpu(ri->num_snaps);
+ err = dup_array(&realm->snaps, snaps, realm->num_snaps);
+ if (err < 0)
+ goto fail;
+
+ realm->num_prior_parent_snaps =
+ le32_to_cpu(ri->num_prior_parent_snaps);
+ err = dup_array(&realm->prior_parent_snaps, prior_parent_snaps,
+ realm->num_prior_parent_snaps);
+ if (err < 0)
+ goto fail;
+
+ invalidate = 1;
+ } else if (!realm->cached_context) {
+ invalidate = 1;
+ }
+
+ dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino,
+ realm, invalidate, p, e);
+
+ if (p < e)
+ goto more;
+
+ /* invalidate when we reach the _end_ (root) of the trace */
+ if (invalidate)
+ rebuild_snap_realms(realm);
+
+ __cleanup_empty_realms(mdsc);
+ return 0;
+
+bad:
+ err = -EINVAL;
+fail:
+ pr_err("update_snap_trace error %d\n", err);
+ return err;
+}
+
+
+/*
+ * Send any cap_snaps that are queued for flush. Try to carry
+ * s_mutex across multiple snap flushes to avoid locking overhead.
+ *
+ * Caller holds no locks.
+ */
+static void flush_snaps(struct ceph_mds_client *mdsc)
+{
+ struct ceph_inode_info *ci;
+ struct inode *inode;
+ struct ceph_mds_session *session = NULL;
+
+ dout("flush_snaps\n");
+ spin_lock(&mdsc->snap_flush_lock);
+ while (!list_empty(&mdsc->snap_flush_list)) {
+ ci = list_first_entry(&mdsc->snap_flush_list,
+ struct ceph_inode_info, i_snap_flush_item);
+ inode = &ci->vfs_inode;
+ igrab(inode);
+ spin_unlock(&mdsc->snap_flush_lock);
+ spin_lock(&inode->i_lock);
+ __ceph_flush_snaps(ci, &session);
+ spin_unlock(&inode->i_lock);
+ iput(inode);
+ spin_lock(&mdsc->snap_flush_lock);
+ }
+ spin_unlock(&mdsc->snap_flush_lock);
+
+ if (session) {
+ mutex_unlock(&session->s_mutex);
+ ceph_put_mds_session(session);
+ }
+ dout("flush_snaps done\n");
+}
+
+
+/*
+ * Handle a snap notification from the MDS.
+ *
+ * This can take two basic forms: the simplest is just a snap creation
+ * or deletion notification on an existing realm. This should update the
+ * realm and its children.
+ *
+ * The more difficult case is realm creation, due to snap creation at a
+ * new point in the file hierarchy, or due to a rename that moves a file or
+ * directory into another realm.
+ */
+void ceph_handle_snap(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session,
+ struct ceph_msg *msg)
+{
+ struct super_block *sb = mdsc->client->sb;
+ int mds = session->s_mds;
+ u64 split;
+ int op;
+ int trace_len;
+ struct ceph_snap_realm *realm = NULL;
+ void *p = msg->front.iov_base;
+ void *e = p + msg->front.iov_len;
+ struct ceph_mds_snap_head *h;
+ int num_split_inos, num_split_realms;
+ __le64 *split_inos = NULL, *split_realms = NULL;
+ int i;
+ int locked_rwsem = 0;
+
+ /* decode */
+ if (msg->front.iov_len < sizeof(*h))
+ goto bad;
+ h = p;
+ op = le32_to_cpu(h->op);
+ split = le64_to_cpu(h->split); /* non-zero if we are splitting an
+ * existing realm */
+ num_split_inos = le32_to_cpu(h->num_split_inos);
+ num_split_realms = le32_to_cpu(h->num_split_realms);
+ trace_len = le32_to_cpu(h->trace_len);
+ p += sizeof(*h);
+
+ dout("handle_snap from mds%d op %s split %llx tracelen %d\n", mds,
+ ceph_snap_op_name(op), split, trace_len);
+
+ mutex_lock(&session->s_mutex);
+ session->s_seq++;
+ mutex_unlock(&session->s_mutex);
+
+ down_write(&mdsc->snap_rwsem);
+ locked_rwsem = 1;
+
+ if (op == CEPH_SNAP_OP_SPLIT) {
+ struct ceph_mds_snap_realm *ri;
+
+ /*
+ * A "split" breaks part of an existing realm off into
+ * a new realm. The MDS provides a list of inodes
+ * (with caps) and child realms that belong to the new
+ * child.
+ */
+ split_inos = p;
+ p += sizeof(u64) * num_split_inos;
+ split_realms = p;
+ p += sizeof(u64) * num_split_realms;
+ ceph_decode_need(&p, e, sizeof(*ri), bad);
+ /* we will peek at realm info here, but will _not_
+ * advance p, as the realm update will occur below in
+ * ceph_update_snap_trace. */
+ ri = p;
+
+ realm = ceph_lookup_snap_realm(mdsc, split);
+ if (!realm) {
+ realm = ceph_create_snap_realm(mdsc, split);
+ if (IS_ERR(realm))
+ goto out;
+ }
+ ceph_get_snap_realm(mdsc, realm);
+
+ dout("splitting snap_realm %llx %p\n", realm->ino, realm);
+ for (i = 0; i < num_split_inos; i++) {
+ struct ceph_vino vino = {
+ .ino = le64_to_cpu(split_inos[i]),
+ .snap = CEPH_NOSNAP,
+ };
+ struct inode *inode = ceph_find_inode(sb, vino);
+ struct ceph_inode_info *ci;
+
+ if (!inode)
+ continue;
+ ci = ceph_inode(inode);
+
+ spin_lock(&inode->i_lock);
+ if (!ci->i_snap_realm)
+ goto skip_inode;
+ /*
+ * If this inode belongs to a realm that was
+ * created after our new realm, we experienced
+ * a race (due to another split notifications
+ * arriving from a different MDS). So skip
+ * this inode.
+ */
+ if (ci->i_snap_realm->created >
+ le64_to_cpu(ri->created)) {
+ dout(" leaving %p in newer realm %llx %p\n",
+ inode, ci->i_snap_realm->ino,
+ ci->i_snap_realm);
+ goto skip_inode;
+ }
+ dout(" will move %p to split realm %llx %p\n",
+ inode, realm->ino, realm);
+ /*
+ * Remove the inode from the realm's inode
+ * list, but don't add it to the new realm
+ * yet. We don't want the cap_snap to be
+ * queued (again) by ceph_update_snap_trace()
+ * below. Queue it _now_, under the old context.
+ */
+ spin_lock(&realm->inodes_with_caps_lock);
+ list_del_init(&ci->i_snap_realm_item);
+ spin_unlock(&realm->inodes_with_caps_lock);
+ spin_unlock(&inode->i_lock);
+
+ ceph_queue_cap_snap(ci);
+
+ iput(inode);
+ continue;
+
+skip_inode:
+ spin_unlock(&inode->i_lock);
+ iput(inode);
+ }
+
+ /* we may have taken some of the old realm's children. */
+ for (i = 0; i < num_split_realms; i++) {
+ struct ceph_snap_realm *child =
+ ceph_lookup_snap_realm(mdsc,
+ le64_to_cpu(split_realms[i]));
+ if (!child)
+ continue;
+ adjust_snap_realm_parent(mdsc, child, realm->ino);
+ }
+ }
+
+ /*
+ * update using the provided snap trace. if we are deleting a
+ * snap, we can avoid queueing cap_snaps.
+ */
+ ceph_update_snap_trace(mdsc, p, e,
+ op == CEPH_SNAP_OP_DESTROY);
+
+ if (op == CEPH_SNAP_OP_SPLIT) {
+ /*
+ * ok, _now_ add the inodes into the new realm.
+ */
+ for (i = 0; i < num_split_inos; i++) {
+ struct ceph_vino vino = {
+ .ino = le64_to_cpu(split_inos[i]),
+ .snap = CEPH_NOSNAP,
+ };
+ struct inode *inode = ceph_find_inode(sb, vino);
+ struct ceph_inode_info *ci;
+
+ if (!inode)
+ continue;
+ ci = ceph_inode(inode);
+ spin_lock(&inode->i_lock);
+ if (!ci->i_snap_realm)
+ goto split_skip_inode;
+ ceph_put_snap_realm(mdsc, ci->i_snap_realm);
+ spin_lock(&realm->inodes_with_caps_lock);
+ list_add(&ci->i_snap_realm_item,
+ &realm->inodes_with_caps);
+ ci->i_snap_realm = realm;
+ spin_unlock(&realm->inodes_with_caps_lock);
+ ceph_get_snap_realm(mdsc, realm);
+split_skip_inode:
+ spin_unlock(&inode->i_lock);
+ iput(inode);
+ }
+
+ /* we took a reference when we created the realm, above */
+ ceph_put_snap_realm(mdsc, realm);
+ }
+
+ __cleanup_empty_realms(mdsc);
+
+ up_write(&mdsc->snap_rwsem);
+
+ flush_snaps(mdsc);
+ return;
+
+bad:
+ pr_err("corrupt snap message from mds%d\n", mds);
+ ceph_msg_dump(msg);
+out:
+ if (locked_rwsem)
+ up_write(&mdsc->snap_rwsem);
+ return;
+}
+
+
+
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
new file mode 100644
index 00000000000..75d02eaa127
--- /dev/null
+++ b/fs/ceph/super.c
@@ -0,0 +1,1031 @@
+
+#include "ceph_debug.h"
+
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/inet.h>
+#include <linux/in6.h>
+#include <linux/module.h>
+#include <linux/mount.h>
+#include <linux/parser.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+
+#include "decode.h"
+#include "super.h"
+#include "mon_client.h"
+#include "auth.h"
+
+/*
+ * Ceph superblock operations
+ *
+ * Handle the basics of mounting, unmounting.
+ */
+
+
+/*
+ * find filename portion of a path (/foo/bar/baz -> baz)
+ */
+const char *ceph_file_part(const char *s, int len)
+{
+ const char *e = s + len;
+
+ while (e != s && *(e-1) != '/')
+ e--;
+ return e;
+}
+
+
+/*
+ * super ops
+ */
+static void ceph_put_super(struct super_block *s)
+{
+ struct ceph_client *cl = ceph_client(s);
+
+ dout("put_super\n");
+ ceph_mdsc_close_sessions(&cl->mdsc);
+ return;
+}
+
+static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+ struct ceph_client *client = ceph_inode_to_client(dentry->d_inode);
+ struct ceph_monmap *monmap = client->monc.monmap;
+ struct ceph_statfs st;
+ u64 fsid;
+ int err;
+
+ dout("statfs\n");
+ err = ceph_monc_do_statfs(&client->monc, &st);
+ if (err < 0)
+ return err;
+
+ /* fill in kstatfs */
+ buf->f_type = CEPH_SUPER_MAGIC; /* ?? */
+
+ /*
+ * express utilization in terms of large blocks to avoid
+ * overflow on 32-bit machines.
+ */
+ buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;
+ buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
+ buf->f_bfree = (le64_to_cpu(st.kb) - le64_to_cpu(st.kb_used)) >>
+ (CEPH_BLOCK_SHIFT-10);
+ buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
+
+ buf->f_files = le64_to_cpu(st.num_objects);
+ buf->f_ffree = -1;
+ buf->f_namelen = PATH_MAX;
+ buf->f_frsize = PAGE_CACHE_SIZE;
+
+ /* leave fsid little-endian, regardless of host endianness */
+ fsid = *(u64 *)(&monmap->fsid) ^ *((u64 *)&monmap->fsid + 1);
+ buf->f_fsid.val[0] = fsid & 0xffffffff;
+ buf->f_fsid.val[1] = fsid >> 32;
+
+ return 0;
+}
+
+
+static int ceph_syncfs(struct super_block *sb, int wait)
+{
+ dout("sync_fs %d\n", wait);
+ ceph_osdc_sync(&ceph_client(sb)->osdc);
+ ceph_mdsc_sync(&ceph_client(sb)->mdsc);
+ dout("sync_fs %d done\n", wait);
+ return 0;
+}
+
+
+/**
+ * ceph_show_options - Show mount options in /proc/mounts
+ * @m: seq_file to write to
+ * @mnt: mount descriptor
+ */
+static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+ struct ceph_client *client = ceph_sb_to_client(mnt->mnt_sb);
+ struct ceph_mount_args *args = client->mount_args;
+
+ if (args->flags & CEPH_OPT_FSID)
+ seq_printf(m, ",fsidmajor=%llu,fsidminor%llu",
+ le64_to_cpu(*(__le64 *)&args->fsid.fsid[0]),
+ le64_to_cpu(*(__le64 *)&args->fsid.fsid[8]));
+ if (args->flags & CEPH_OPT_NOSHARE)
+ seq_puts(m, ",noshare");
+ if (args->flags & CEPH_OPT_DIRSTAT)
+ seq_puts(m, ",dirstat");
+ if ((args->flags & CEPH_OPT_RBYTES) == 0)
+ seq_puts(m, ",norbytes");
+ if (args->flags & CEPH_OPT_NOCRC)
+ seq_puts(m, ",nocrc");
+ if (args->flags & CEPH_OPT_NOASYNCREADDIR)
+ seq_puts(m, ",noasyncreaddir");
+ if (strcmp(args->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT))
+ seq_printf(m, ",snapdirname=%s", args->snapdir_name);
+ if (args->name)
+ seq_printf(m, ",name=%s", args->name);
+ if (args->secret)
+ seq_puts(m, ",secret=<hidden>");
+ return 0;
+}
+
+/*
+ * caches
+ */
+struct kmem_cache *ceph_inode_cachep;
+struct kmem_cache *ceph_cap_cachep;
+struct kmem_cache *ceph_dentry_cachep;
+struct kmem_cache *ceph_file_cachep;
+
+static void ceph_inode_init_once(void *foo)
+{
+ struct ceph_inode_info *ci = foo;
+ inode_init_once(&ci->vfs_inode);
+}
+
+static int default_congestion_kb(void)
+{
+ int congestion_kb;
+
+ /*
+ * Copied from NFS
+ *
+ * congestion size, scale with available memory.
+ *
+ * 64MB: 8192k
+ * 128MB: 11585k
+ * 256MB: 16384k
+ * 512MB: 23170k
+ * 1GB: 32768k
+ * 2GB: 46340k
+ * 4GB: 65536k
+ * 8GB: 92681k
+ * 16GB: 131072k
+ *
+ * This allows larger machines to have larger/more transfers.
+ * Limit the default to 256M
+ */
+ congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10);
+ if (congestion_kb > 256*1024)
+ congestion_kb = 256*1024;
+
+ return congestion_kb;
+}
+
+static int __init init_caches(void)
+{
+ ceph_inode_cachep = kmem_cache_create("ceph_inode_info",
+ sizeof(struct ceph_inode_info),
+ __alignof__(struct ceph_inode_info),
+ (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
+ ceph_inode_init_once);
+ if (ceph_inode_cachep == NULL)
+ return -ENOMEM;
+
+ ceph_cap_cachep = KMEM_CACHE(ceph_cap,
+ SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+ if (ceph_cap_cachep == NULL)
+ goto bad_cap;
+
+ ceph_dentry_cachep = KMEM_CACHE(ceph_dentry_info,
+ SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+ if (ceph_dentry_cachep == NULL)
+ goto bad_dentry;
+
+ ceph_file_cachep = KMEM_CACHE(ceph_file_info,
+ SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+ if (ceph_file_cachep == NULL)
+ goto bad_file;
+
+ return 0;
+
+bad_file:
+ kmem_cache_destroy(ceph_dentry_cachep);
+bad_dentry:
+ kmem_cache_destroy(ceph_cap_cachep);
+bad_cap:
+ kmem_cache_destroy(ceph_inode_cachep);
+ return -ENOMEM;
+}
+
+static void destroy_caches(void)
+{
+ kmem_cache_destroy(ceph_inode_cachep);
+ kmem_cache_destroy(ceph_cap_cachep);
+ kmem_cache_destroy(ceph_dentry_cachep);
+ kmem_cache_destroy(ceph_file_cachep);
+}
+
+
+/*
+ * ceph_umount_begin - initiate forced umount. Tear down down the
+ * mount, skipping steps that may hang while waiting for server(s).
+ */
+static void ceph_umount_begin(struct super_block *sb)
+{
+ struct ceph_client *client = ceph_sb_to_client(sb);
+
+ dout("ceph_umount_begin - starting forced umount\n");
+ if (!client)
+ return;
+ client->mount_state = CEPH_MOUNT_SHUTDOWN;
+ return;
+}
+
+static const struct super_operations ceph_super_ops = {
+ .alloc_inode = ceph_alloc_inode,
+ .destroy_inode = ceph_destroy_inode,
+ .write_inode = ceph_write_inode,
+ .sync_fs = ceph_syncfs,
+ .put_super = ceph_put_super,
+ .show_options = ceph_show_options,
+ .statfs = ceph_statfs,
+ .umount_begin = ceph_umount_begin,
+};
+
+
+const char *ceph_msg_type_name(int type)
+{
+ switch (type) {
+ case CEPH_MSG_SHUTDOWN: return "shutdown";
+ case CEPH_MSG_PING: return "ping";
+ case CEPH_MSG_AUTH: return "auth";
+ case CEPH_MSG_AUTH_REPLY: return "auth_reply";
+ case CEPH_MSG_MON_MAP: return "mon_map";
+ case CEPH_MSG_MON_GET_MAP: return "mon_get_map";
+ case CEPH_MSG_MON_SUBSCRIBE: return "mon_subscribe";
+ case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack";
+ case CEPH_MSG_STATFS: return "statfs";
+ case CEPH_MSG_STATFS_REPLY: return "statfs_reply";
+ case CEPH_MSG_MDS_MAP: return "mds_map";
+ case CEPH_MSG_CLIENT_SESSION: return "client_session";
+ case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect";
+ case CEPH_MSG_CLIENT_REQUEST: return "client_request";
+ case CEPH_MSG_CLIENT_REQUEST_FORWARD: return "client_request_forward";
+ case CEPH_MSG_CLIENT_REPLY: return "client_reply";
+ case CEPH_MSG_CLIENT_CAPS: return "client_caps";
+ case CEPH_MSG_CLIENT_CAPRELEASE: return "client_cap_release";
+ case CEPH_MSG_CLIENT_SNAP: return "client_snap";
+ case CEPH_MSG_CLIENT_LEASE: return "client_lease";
+ case CEPH_MSG_OSD_MAP: return "osd_map";
+ case CEPH_MSG_OSD_OP: return "osd_op";
+ case CEPH_MSG_OSD_OPREPLY: return "osd_opreply";
+ default: return "unknown";
+ }
+}
+
+
+/*
+ * mount options
+ */
+enum {
+ Opt_fsidmajor,
+ Opt_fsidminor,
+ Opt_monport,
+ Opt_wsize,
+ Opt_rsize,
+ Opt_osdtimeout,
+ Opt_osdkeepalivetimeout,
+ Opt_mount_timeout,
+ Opt_osd_idle_ttl,
+ Opt_caps_wanted_delay_min,
+ Opt_caps_wanted_delay_max,
+ Opt_readdir_max_entries,
+ Opt_congestion_kb,
+ Opt_last_int,
+ /* int args above */
+ Opt_snapdirname,
+ Opt_name,
+ Opt_secret,
+ Opt_last_string,
+ /* string args above */
+ Opt_ip,
+ Opt_noshare,
+ Opt_dirstat,
+ Opt_nodirstat,
+ Opt_rbytes,
+ Opt_norbytes,
+ Opt_nocrc,
+ Opt_noasyncreaddir,
+};
+
+static match_table_t arg_tokens = {
+ {Opt_fsidmajor, "fsidmajor=%ld"},
+ {Opt_fsidminor, "fsidminor=%ld"},
+ {Opt_monport, "monport=%d"},
+ {Opt_wsize, "wsize=%d"},
+ {Opt_rsize, "rsize=%d"},
+ {Opt_osdtimeout, "osdtimeout=%d"},
+ {Opt_osdkeepalivetimeout, "osdkeepalive=%d"},
+ {Opt_mount_timeout, "mount_timeout=%d"},
+ {Opt_osd_idle_ttl, "osd_idle_ttl=%d"},
+ {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"},
+ {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"},
+ {Opt_readdir_max_entries, "readdir_max_entries=%d"},
+ {Opt_congestion_kb, "write_congestion_kb=%d"},
+ /* int args above */
+ {Opt_snapdirname, "snapdirname=%s"},
+ {Opt_name, "name=%s"},
+ {Opt_secret, "secret=%s"},
+ /* string args above */
+ {Opt_ip, "ip=%s"},
+ {Opt_noshare, "noshare"},
+ {Opt_dirstat, "dirstat"},
+ {Opt_nodirstat, "nodirstat"},
+ {Opt_rbytes, "rbytes"},
+ {Opt_norbytes, "norbytes"},
+ {Opt_nocrc, "nocrc"},
+ {Opt_noasyncreaddir, "noasyncreaddir"},
+ {-1, NULL}
+};
+
+
+static struct ceph_mount_args *parse_mount_args(int flags, char *options,
+ const char *dev_name,
+ const char **path)
+{
+ struct ceph_mount_args *args;
+ const char *c;
+ int err = -ENOMEM;
+ substring_t argstr[MAX_OPT_ARGS];
+
+ args = kzalloc(sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return ERR_PTR(-ENOMEM);
+ args->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*args->mon_addr),
+ GFP_KERNEL);
+ if (!args->mon_addr)
+ goto out;
+
+ dout("parse_mount_args %p, dev_name '%s'\n", args, dev_name);
+
+ /* start with defaults */
+ args->sb_flags = flags;
+ args->flags = CEPH_OPT_DEFAULT;
+ args->osd_timeout = CEPH_OSD_TIMEOUT_DEFAULT;
+ args->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
+ args->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */
+ args->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT; /* seconds */
+ args->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
+ args->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
+ args->rsize = CEPH_MOUNT_RSIZE_DEFAULT;
+ args->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
+ args->cap_release_safety = CEPH_CAPS_PER_RELEASE * 4;
+ args->max_readdir = 1024;
+ args->congestion_kb = default_congestion_kb();
+
+ /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */
+ err = -EINVAL;
+ if (!dev_name)
+ goto out;
+ *path = strstr(dev_name, ":/");
+ if (*path == NULL) {
+ pr_err("device name is missing path (no :/ in %s)\n",
+ dev_name);
+ goto out;
+ }
+
+ /* get mon ip(s) */
+ err = ceph_parse_ips(dev_name, *path, args->mon_addr,
+ CEPH_MAX_MON, &args->num_mon);
+ if (err < 0)
+ goto out;
+
+ /* path on server */
+ *path += 2;
+ dout("server path '%s'\n", *path);
+
+ /* parse mount options */
+ while ((c = strsep(&options, ",")) != NULL) {
+ int token, intval, ret;
+ if (!*c)
+ continue;
+ err = -EINVAL;
+ token = match_token((char *)c, arg_tokens, argstr);
+ if (token < 0) {
+ pr_err("bad mount option at '%s'\n", c);
+ goto out;
+ }
+ if (token < Opt_last_int) {
+ ret = match_int(&argstr[0], &intval);
+ if (ret < 0) {
+ pr_err("bad mount option arg (not int) "
+ "at '%s'\n", c);
+ continue;
+ }
+ dout("got int token %d val %d\n", token, intval);
+ } else if (token > Opt_last_int && token < Opt_last_string) {
+ dout("got string token %d val %s\n", token,
+ argstr[0].from);
+ } else {
+ dout("got token %d\n", token);
+ }
+ switch (token) {
+ case Opt_fsidmajor:
+ *(__le64 *)&args->fsid.fsid[0] = cpu_to_le64(intval);
+ break;
+ case Opt_fsidminor:
+ *(__le64 *)&args->fsid.fsid[8] = cpu_to_le64(intval);
+ break;
+ case Opt_ip:
+ err = ceph_parse_ips(argstr[0].from,
+ argstr[0].to,
+ &args->my_addr,
+ 1, NULL);
+ if (err < 0)
+ goto out;
+ args->flags |= CEPH_OPT_MYIP;
+ break;
+
+ case Opt_snapdirname:
+ kfree(args->snapdir_name);
+ args->snapdir_name = kstrndup(argstr[0].from,
+ argstr[0].to-argstr[0].from,
+ GFP_KERNEL);
+ break;
+ case Opt_name:
+ args->name = kstrndup(argstr[0].from,
+ argstr[0].to-argstr[0].from,
+ GFP_KERNEL);
+ break;
+ case Opt_secret:
+ args->secret = kstrndup(argstr[0].from,
+ argstr[0].to-argstr[0].from,
+ GFP_KERNEL);
+ break;
+
+ /* misc */
+ case Opt_wsize:
+ args->wsize = intval;
+ break;
+ case Opt_rsize:
+ args->rsize = intval;
+ break;
+ case Opt_osdtimeout:
+ args->osd_timeout = intval;
+ break;
+ case Opt_osdkeepalivetimeout:
+ args->osd_keepalive_timeout = intval;
+ break;
+ case Opt_mount_timeout:
+ args->mount_timeout = intval;
+ break;
+ case Opt_caps_wanted_delay_min:
+ args->caps_wanted_delay_min = intval;
+ break;
+ case Opt_caps_wanted_delay_max:
+ args->caps_wanted_delay_max = intval;
+ break;
+ case Opt_readdir_max_entries:
+ args->max_readdir = intval;
+ break;
+ case Opt_congestion_kb:
+ args->congestion_kb = intval;
+ break;
+
+ case Opt_noshare:
+ args->flags |= CEPH_OPT_NOSHARE;
+ break;
+
+ case Opt_dirstat:
+ args->flags |= CEPH_OPT_DIRSTAT;
+ break;
+ case Opt_nodirstat:
+ args->flags &= ~CEPH_OPT_DIRSTAT;
+ break;
+ case Opt_rbytes:
+ args->flags |= CEPH_OPT_RBYTES;
+ break;
+ case Opt_norbytes:
+ args->flags &= ~CEPH_OPT_RBYTES;
+ break;
+ case Opt_nocrc:
+ args->flags |= CEPH_OPT_NOCRC;
+ break;
+ case Opt_noasyncreaddir:
+ args->flags |= CEPH_OPT_NOASYNCREADDIR;
+ break;
+
+ default:
+ BUG_ON(token);
+ }
+ }
+ return args;
+
+out:
+ kfree(args->mon_addr);
+ kfree(args);
+ return ERR_PTR(err);
+}
+
+static void destroy_mount_args(struct ceph_mount_args *args)
+{
+ dout("destroy_mount_args %p\n", args);
+ kfree(args->snapdir_name);
+ args->snapdir_name = NULL;
+ kfree(args->name);
+ args->name = NULL;
+ kfree(args->secret);
+ args->secret = NULL;
+ kfree(args);
+}
+
+/*
+ * create a fresh client instance
+ */
+static struct ceph_client *ceph_create_client(struct ceph_mount_args *args)
+{
+ struct ceph_client *client;
+ int err = -ENOMEM;
+
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
+ if (client == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ mutex_init(&client->mount_mutex);
+
+ init_waitqueue_head(&client->auth_wq);
+
+ client->sb = NULL;
+ client->mount_state = CEPH_MOUNT_MOUNTING;
+ client->mount_args = args;
+
+ client->msgr = NULL;
+
+ client->auth_err = 0;
+ atomic_long_set(&client->writeback_count, 0);
+
+ err = bdi_init(&client->backing_dev_info);
+ if (err < 0)
+ goto fail;
+
+ err = -ENOMEM;
+ client->wb_wq = create_workqueue("ceph-writeback");
+ if (client->wb_wq == NULL)
+ goto fail_bdi;
+ client->pg_inv_wq = create_singlethread_workqueue("ceph-pg-invalid");
+ if (client->pg_inv_wq == NULL)
+ goto fail_wb_wq;
+ client->trunc_wq = create_singlethread_workqueue("ceph-trunc");
+ if (client->trunc_wq == NULL)
+ goto fail_pg_inv_wq;
+
+ /* set up mempools */
+ err = -ENOMEM;
+ client->wb_pagevec_pool = mempool_create_kmalloc_pool(10,
+ client->mount_args->wsize >> PAGE_CACHE_SHIFT);
+ if (!client->wb_pagevec_pool)
+ goto fail_trunc_wq;
+
+ /* caps */
+ client->min_caps = args->max_readdir;
+ ceph_adjust_min_caps(client->min_caps);
+
+ /* subsystems */
+ err = ceph_monc_init(&client->monc, client);
+ if (err < 0)
+ goto fail_mempool;
+ err = ceph_osdc_init(&client->osdc, client);
+ if (err < 0)
+ goto fail_monc;
+ err = ceph_mdsc_init(&client->mdsc, client);
+ if (err < 0)
+ goto fail_osdc;
+ return client;
+
+fail_osdc:
+ ceph_osdc_stop(&client->osdc);
+fail_monc:
+ ceph_monc_stop(&client->monc);
+fail_mempool:
+ mempool_destroy(client->wb_pagevec_pool);
+fail_trunc_wq:
+ destroy_workqueue(client->trunc_wq);
+fail_pg_inv_wq:
+ destroy_workqueue(client->pg_inv_wq);
+fail_wb_wq:
+ destroy_workqueue(client->wb_wq);
+fail_bdi:
+ bdi_destroy(&client->backing_dev_info);
+fail:
+ kfree(client);
+ return ERR_PTR(err);
+}
+
+static void ceph_destroy_client(struct ceph_client *client)
+{
+ dout("destroy_client %p\n", client);
+
+ /* unmount */
+ ceph_mdsc_stop(&client->mdsc);
+ ceph_monc_stop(&client->monc);
+ ceph_osdc_stop(&client->osdc);
+
+ ceph_adjust_min_caps(-client->min_caps);
+
+ ceph_debugfs_client_cleanup(client);
+ destroy_workqueue(client->wb_wq);
+ destroy_workqueue(client->pg_inv_wq);
+ destroy_workqueue(client->trunc_wq);
+
+ if (client->msgr)
+ ceph_messenger_destroy(client->msgr);
+ mempool_destroy(client->wb_pagevec_pool);
+
+ destroy_mount_args(client->mount_args);
+
+ kfree(client);
+ dout("destroy_client %p done\n", client);
+}
+
+/*
+ * Initially learn our fsid, or verify an fsid matches.
+ */
+int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
+{
+ if (client->have_fsid) {
+ if (ceph_fsid_compare(&client->fsid, fsid)) {
+ pr_err("bad fsid, had " FSID_FORMAT " got " FSID_FORMAT,
+ PR_FSID(&client->fsid), PR_FSID(fsid));
+ return -1;
+ }
+ } else {
+ pr_info("client%lld fsid " FSID_FORMAT "\n",
+ client->monc.auth->global_id, PR_FSID(fsid));
+ memcpy(&client->fsid, fsid, sizeof(*fsid));
+ ceph_debugfs_client_init(client);
+ client->have_fsid = true;
+ }
+ return 0;
+}
+
+/*
+ * true if we have the mon map (and have thus joined the cluster)
+ */
+static int have_mon_map(struct ceph_client *client)
+{
+ return client->monc.monmap && client->monc.monmap->epoch;
+}
+
+/*
+ * Bootstrap mount by opening the root directory. Note the mount
+ * @started time from caller, and time out if this takes too long.
+ */
+static struct dentry *open_root_dentry(struct ceph_client *client,
+ const char *path,
+ unsigned long started)
+{
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct ceph_mds_request *req = NULL;
+ int err;
+ struct dentry *root;
+
+ /* open dir */
+ dout("open_root_inode opening '%s'\n", path);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
+ if (IS_ERR(req))
+ return ERR_PTR(PTR_ERR(req));
+ req->r_path1 = kstrdup(path, GFP_NOFS);
+ req->r_ino1.ino = CEPH_INO_ROOT;
+ req->r_ino1.snap = CEPH_NOSNAP;
+ req->r_started = started;
+ req->r_timeout = client->mount_args->mount_timeout * HZ;
+ req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
+ req->r_num_caps = 2;
+ err = ceph_mdsc_do_request(mdsc, NULL, req);
+ if (err == 0) {
+ dout("open_root_inode success\n");
+ if (ceph_ino(req->r_target_inode) == CEPH_INO_ROOT &&
+ client->sb->s_root == NULL)
+ root = d_alloc_root(req->r_target_inode);
+ else
+ root = d_obtain_alias(req->r_target_inode);
+ req->r_target_inode = NULL;
+ dout("open_root_inode success, root dentry is %p\n", root);
+ } else {
+ root = ERR_PTR(err);
+ }
+ ceph_mdsc_put_request(req);
+ return root;
+}
+
+/*
+ * mount: join the ceph cluster, and open root directory.
+ */
+static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt,
+ const char *path)
+{
+ struct ceph_entity_addr *myaddr = NULL;
+ int err;
+ unsigned long timeout = client->mount_args->mount_timeout * HZ;
+ unsigned long started = jiffies; /* note the start time */
+ struct dentry *root;
+
+ dout("mount start\n");
+ mutex_lock(&client->mount_mutex);
+
+ /* initialize the messenger */
+ if (client->msgr == NULL) {
+ if (ceph_test_opt(client, MYIP))
+ myaddr = &client->mount_args->my_addr;
+ client->msgr = ceph_messenger_create(myaddr);
+ if (IS_ERR(client->msgr)) {
+ err = PTR_ERR(client->msgr);
+ client->msgr = NULL;
+ goto out;
+ }
+ client->msgr->nocrc = ceph_test_opt(client, NOCRC);
+ }
+
+ /* open session, and wait for mon, mds, and osd maps */
+ err = ceph_monc_open_session(&client->monc);
+ if (err < 0)
+ goto out;
+
+ while (!have_mon_map(client)) {
+ err = -EIO;
+ if (timeout && time_after_eq(jiffies, started + timeout))
+ goto out;
+
+ /* wait */
+ dout("mount waiting for mon_map\n");
+ err = wait_event_interruptible_timeout(client->auth_wq,
+ have_mon_map(client) || (client->auth_err < 0),
+ timeout);
+ if (err == -EINTR || err == -ERESTARTSYS)
+ goto out;
+ if (client->auth_err < 0) {
+ err = client->auth_err;
+ goto out;
+ }
+ }
+
+ dout("mount opening root\n");
+ root = open_root_dentry(client, "", started);
+ if (IS_ERR(root)) {
+ err = PTR_ERR(root);
+ goto out;
+ }
+ if (client->sb->s_root)
+ dput(root);
+ else
+ client->sb->s_root = root;
+
+ if (path[0] == 0) {
+ dget(root);
+ } else {
+ dout("mount opening base mountpoint\n");
+ root = open_root_dentry(client, path, started);
+ if (IS_ERR(root)) {
+ err = PTR_ERR(root);
+ dput(client->sb->s_root);
+ client->sb->s_root = NULL;
+ goto out;
+ }
+ }
+
+ mnt->mnt_root = root;
+ mnt->mnt_sb = client->sb;
+
+ client->mount_state = CEPH_MOUNT_MOUNTED;
+ dout("mount success\n");
+ err = 0;
+
+out:
+ mutex_unlock(&client->mount_mutex);
+ return err;
+}
+
+static int ceph_set_super(struct super_block *s, void *data)
+{
+ struct ceph_client *client = data;
+ int ret;
+
+ dout("set_super %p data %p\n", s, data);
+
+ s->s_flags = client->mount_args->sb_flags;
+ s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */
+
+ s->s_fs_info = client;
+ client->sb = s;
+
+ s->s_op = &ceph_super_ops;
+ s->s_export_op = &ceph_export_ops;
+
+ s->s_time_gran = 1000; /* 1000 ns == 1 us */
+
+ ret = set_anon_super(s, NULL); /* what is that second arg for? */
+ if (ret != 0)
+ goto fail;
+
+ return ret;
+
+fail:
+ s->s_fs_info = NULL;
+ client->sb = NULL;
+ return ret;
+}
+
+/*
+ * share superblock if same fs AND options
+ */
+static int ceph_compare_super(struct super_block *sb, void *data)
+{
+ struct ceph_client *new = data;
+ struct ceph_mount_args *args = new->mount_args;
+ struct ceph_client *other = ceph_sb_to_client(sb);
+ int i;
+
+ dout("ceph_compare_super %p\n", sb);
+ if (args->flags & CEPH_OPT_FSID) {
+ if (ceph_fsid_compare(&args->fsid, &other->fsid)) {
+ dout("fsid doesn't match\n");
+ return 0;
+ }
+ } else {
+ /* do we share (a) monitor? */
+ for (i = 0; i < new->monc.monmap->num_mon; i++)
+ if (ceph_monmap_contains(other->monc.monmap,
+ &new->monc.monmap->mon_inst[i].addr))
+ break;
+ if (i == new->monc.monmap->num_mon) {
+ dout("mon ip not part of monmap\n");
+ return 0;
+ }
+ dout("mon ip matches existing sb %p\n", sb);
+ }
+ if (args->sb_flags != other->mount_args->sb_flags) {
+ dout("flags differ\n");
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * construct our own bdi so we can control readahead, etc.
+ */
+static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client)
+{
+ int err;
+
+ sb->s_bdi = &client->backing_dev_info;
+
+ /* set ra_pages based on rsize mount option? */
+ if (client->mount_args->rsize >= PAGE_CACHE_SIZE)
+ client->backing_dev_info.ra_pages =
+ (client->mount_args->rsize + PAGE_CACHE_SIZE - 1)
+ >> PAGE_SHIFT;
+ err = bdi_register_dev(&client->backing_dev_info, sb->s_dev);
+ return err;
+}
+
+static int ceph_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data,
+ struct vfsmount *mnt)
+{
+ struct super_block *sb;
+ struct ceph_client *client;
+ int err;
+ int (*compare_super)(struct super_block *, void *) = ceph_compare_super;
+ const char *path = NULL;
+ struct ceph_mount_args *args;
+
+ dout("ceph_get_sb\n");
+ args = parse_mount_args(flags, data, dev_name, &path);
+ if (IS_ERR(args)) {
+ err = PTR_ERR(args);
+ goto out_final;
+ }
+
+ /* create client (which we may/may not use) */
+ client = ceph_create_client(args);
+ if (IS_ERR(client)) {
+ err = PTR_ERR(client);
+ goto out_final;
+ }
+
+ if (client->mount_args->flags & CEPH_OPT_NOSHARE)
+ compare_super = NULL;
+ sb = sget(fs_type, compare_super, ceph_set_super, client);
+ if (IS_ERR(sb)) {
+ err = PTR_ERR(sb);
+ goto out;
+ }
+
+ if (ceph_client(sb) != client) {
+ ceph_destroy_client(client);
+ client = ceph_client(sb);
+ dout("get_sb got existing client %p\n", client);
+ } else {
+ dout("get_sb using new client %p\n", client);
+ err = ceph_register_bdi(sb, client);
+ if (err < 0)
+ goto out_splat;
+ }
+
+ err = ceph_mount(client, mnt, path);
+ if (err < 0)
+ goto out_splat;
+ dout("root %p inode %p ino %llx.%llx\n", mnt->mnt_root,
+ mnt->mnt_root->d_inode, ceph_vinop(mnt->mnt_root->d_inode));
+ return 0;
+
+out_splat:
+ ceph_mdsc_close_sessions(&client->mdsc);
+ up_write(&sb->s_umount);
+ deactivate_super(sb);
+ goto out_final;
+
+out:
+ ceph_destroy_client(client);
+out_final:
+ dout("ceph_get_sb fail %d\n", err);
+ return err;
+}
+
+static void ceph_kill_sb(struct super_block *s)
+{
+ struct ceph_client *client = ceph_sb_to_client(s);
+ dout("kill_sb %p\n", s);
+ ceph_mdsc_pre_umount(&client->mdsc);
+ kill_anon_super(s); /* will call put_super after sb is r/o */
+ if (s->s_bdi == &client->backing_dev_info)
+ bdi_unregister(&client->backing_dev_info);
+ bdi_destroy(&client->backing_dev_info);
+ ceph_destroy_client(client);
+}
+
+static struct file_system_type ceph_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "ceph",
+ .get_sb = ceph_get_sb,
+ .kill_sb = ceph_kill_sb,
+ .fs_flags = FS_RENAME_DOES_D_MOVE,
+};
+
+#define _STRINGIFY(x) #x
+#define STRINGIFY(x) _STRINGIFY(x)
+
+static int __init init_ceph(void)
+{
+ int ret = 0;
+
+ ret = ceph_debugfs_init();
+ if (ret < 0)
+ goto out;
+
+ ret = ceph_msgr_init();
+ if (ret < 0)
+ goto out_debugfs;
+
+ ret = init_caches();
+ if (ret)
+ goto out_msgr;
+
+ ceph_caps_init();
+
+ ret = register_filesystem(&ceph_fs_type);
+ if (ret)
+ goto out_icache;
+
+ pr_info("loaded %d.%d.%d (mon/mds/osd proto %d/%d/%d)\n",
+ CEPH_VERSION_MAJOR, CEPH_VERSION_MINOR, CEPH_VERSION_PATCH,
+ CEPH_MONC_PROTOCOL, CEPH_MDSC_PROTOCOL, CEPH_OSDC_PROTOCOL);
+ return 0;
+
+out_icache:
+ destroy_caches();
+out_msgr:
+ ceph_msgr_exit();
+out_debugfs:
+ ceph_debugfs_cleanup();
+out:
+ return ret;
+}
+
+static void __exit exit_ceph(void)
+{
+ dout("exit_ceph\n");
+ unregister_filesystem(&ceph_fs_type);
+ ceph_caps_finalize();
+ destroy_caches();
+ ceph_msgr_exit();
+ ceph_debugfs_cleanup();
+}
+
+module_init(init_ceph);
+module_exit(exit_ceph);
+
+MODULE_AUTHOR("Sage Weil <sage@newdream.net>");
+MODULE_AUTHOR("Yehuda Sadeh <yehuda@hq.newdream.net>");
+MODULE_AUTHOR("Patience Warnick <patience@newdream.net>");
+MODULE_DESCRIPTION("Ceph filesystem for Linux");
+MODULE_LICENSE("GPL");
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
new file mode 100644
index 00000000000..e30dfbb056c
--- /dev/null
+++ b/fs/ceph/super.h
@@ -0,0 +1,901 @@
+#ifndef _FS_CEPH_SUPER_H
+#define _FS_CEPH_SUPER_H
+
+#include "ceph_debug.h"
+
+#include <asm/unaligned.h>
+#include <linux/backing-dev.h>
+#include <linux/completion.h>
+#include <linux/exportfs.h>
+#include <linux/fs.h>
+#include <linux/mempool.h>
+#include <linux/pagemap.h>
+#include <linux/wait.h>
+#include <linux/writeback.h>
+#include <linux/slab.h>
+
+#include "types.h"
+#include "messenger.h"
+#include "msgpool.h"
+#include "mon_client.h"
+#include "mds_client.h"
+#include "osd_client.h"
+#include "ceph_fs.h"
+
+/* f_type in struct statfs */
+#define CEPH_SUPER_MAGIC 0x00c36400
+
+/* large granularity for statfs utilization stats to facilitate
+ * large volume sizes on 32-bit machines. */
+#define CEPH_BLOCK_SHIFT 20 /* 1 MB */
+#define CEPH_BLOCK (1 << CEPH_BLOCK_SHIFT)
+
+/*
+ * mount options
+ */
+#define CEPH_OPT_FSID (1<<0)
+#define CEPH_OPT_NOSHARE (1<<1) /* don't share client with other sbs */
+#define CEPH_OPT_MYIP (1<<2) /* specified my ip */
+#define CEPH_OPT_DIRSTAT (1<<4) /* funky `cat dirname` for stats */
+#define CEPH_OPT_RBYTES (1<<5) /* dir st_bytes = rbytes */
+#define CEPH_OPT_NOCRC (1<<6) /* no data crc on writes */
+#define CEPH_OPT_NOASYNCREADDIR (1<<7) /* no dcache readdir */
+
+#define CEPH_OPT_DEFAULT (CEPH_OPT_RBYTES)
+
+#define ceph_set_opt(client, opt) \
+ (client)->mount_args->flags |= CEPH_OPT_##opt;
+#define ceph_test_opt(client, opt) \
+ (!!((client)->mount_args->flags & CEPH_OPT_##opt))
+
+
+struct ceph_mount_args {
+ int sb_flags;
+ int num_mon;
+ struct ceph_entity_addr *mon_addr;
+ int flags;
+ int mount_timeout;
+ int osd_idle_ttl;
+ int caps_wanted_delay_min, caps_wanted_delay_max;
+ struct ceph_fsid fsid;
+ struct ceph_entity_addr my_addr;
+ int wsize;
+ int rsize; /* max readahead */
+ int max_readdir; /* max readdir size */
+ int congestion_kb; /* max readdir size */
+ int osd_timeout;
+ int osd_keepalive_timeout;
+ char *snapdir_name; /* default ".snap" */
+ char *name;
+ char *secret;
+ int cap_release_safety;
+};
+
+/*
+ * defaults
+ */
+#define CEPH_MOUNT_TIMEOUT_DEFAULT 60
+#define CEPH_OSD_TIMEOUT_DEFAULT 60 /* seconds */
+#define CEPH_OSD_KEEPALIVE_DEFAULT 5
+#define CEPH_OSD_IDLE_TTL_DEFAULT 60
+#define CEPH_MOUNT_RSIZE_DEFAULT (512*1024) /* readahead */
+
+#define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024)
+#define CEPH_MSG_MAX_DATA_LEN (16*1024*1024)
+
+#define CEPH_SNAPDIRNAME_DEFAULT ".snap"
+#define CEPH_AUTH_NAME_DEFAULT "guest"
+
+/*
+ * Delay telling the MDS we no longer want caps, in case we reopen
+ * the file. Delay a minimum amount of time, even if we send a cap
+ * message for some other reason. Otherwise, take the oppotunity to
+ * update the mds to avoid sending another message later.
+ */
+#define CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT 5 /* cap release delay */
+#define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT 60 /* cap release delay */
+
+
+/* mount state */
+enum {
+ CEPH_MOUNT_MOUNTING,
+ CEPH_MOUNT_MOUNTED,
+ CEPH_MOUNT_UNMOUNTING,
+ CEPH_MOUNT_UNMOUNTED,
+ CEPH_MOUNT_SHUTDOWN,
+};
+
+/*
+ * subtract jiffies
+ */
+static inline unsigned long time_sub(unsigned long a, unsigned long b)
+{
+ BUG_ON(time_after(b, a));
+ return (long)a - (long)b;
+}
+
+/*
+ * per-filesystem client state
+ *
+ * possibly shared by multiple mount points, if they are
+ * mounting the same ceph filesystem/cluster.
+ */
+struct ceph_client {
+ struct ceph_fsid fsid;
+ bool have_fsid;
+
+ struct mutex mount_mutex; /* serialize mount attempts */
+ struct ceph_mount_args *mount_args;
+
+ struct super_block *sb;
+
+ unsigned long mount_state;
+ wait_queue_head_t auth_wq;
+
+ int auth_err;
+
+ int min_caps; /* min caps i added */
+
+ struct ceph_messenger *msgr; /* messenger instance */
+ struct ceph_mon_client monc;
+ struct ceph_mds_client mdsc;
+ struct ceph_osd_client osdc;
+
+ /* writeback */
+ mempool_t *wb_pagevec_pool;
+ struct workqueue_struct *wb_wq;
+ struct workqueue_struct *pg_inv_wq;
+ struct workqueue_struct *trunc_wq;
+ atomic_long_t writeback_count;
+
+ struct backing_dev_info backing_dev_info;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_monmap;
+ struct dentry *debugfs_mdsmap, *debugfs_osdmap;
+ struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps;
+ struct dentry *debugfs_congestion_kb;
+ struct dentry *debugfs_bdi;
+#endif
+};
+
+static inline struct ceph_client *ceph_client(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+
+/*
+ * File i/o capability. This tracks shared state with the metadata
+ * server that allows us to cache or writeback attributes or to read
+ * and write data. For any given inode, we should have one or more
+ * capabilities, one issued by each metadata server, and our
+ * cumulative access is the OR of all issued capabilities.
+ *
+ * Each cap is referenced by the inode's i_caps rbtree and by per-mds
+ * session capability lists.
+ */
+struct ceph_cap {
+ struct ceph_inode_info *ci;
+ struct rb_node ci_node; /* per-ci cap tree */
+ struct ceph_mds_session *session;
+ struct list_head session_caps; /* per-session caplist */
+ int mds;
+ u64 cap_id; /* unique cap id (mds provided) */
+ int issued; /* latest, from the mds */
+ int implemented; /* implemented superset of issued (for revocation) */
+ int mds_wanted;
+ u32 seq, issue_seq, mseq;
+ u32 cap_gen; /* active/stale cycle */
+ unsigned long last_used;
+ struct list_head caps_item;
+};
+
+#define CHECK_CAPS_NODELAY 1 /* do not delay any further */
+#define CHECK_CAPS_AUTHONLY 2 /* only check auth cap */
+#define CHECK_CAPS_FLUSH 4 /* flush any dirty caps */
+
+/*
+ * Snapped cap state that is pending flush to mds. When a snapshot occurs,
+ * we first complete any in-process sync writes and writeback any dirty
+ * data before flushing the snapped state (tracked here) back to the MDS.
+ */
+struct ceph_cap_snap {
+ atomic_t nref;
+ struct ceph_inode_info *ci;
+ struct list_head ci_item, flushing_item;
+
+ u64 follows, flush_tid;
+ int issued, dirty;
+ struct ceph_snap_context *context;
+
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+
+ void *xattr_blob;
+ int xattr_len;
+ u64 xattr_version;
+
+ u64 size;
+ struct timespec mtime, atime, ctime;
+ u64 time_warp_seq;
+ int writing; /* a sync write is still in progress */
+ int dirty_pages; /* dirty pages awaiting writeback */
+};
+
+static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap)
+{
+ if (atomic_dec_and_test(&capsnap->nref))
+ kfree(capsnap);
+}
+
+/*
+ * The frag tree describes how a directory is fragmented, potentially across
+ * multiple metadata servers. It is also used to indicate points where
+ * metadata authority is delegated, and whether/where metadata is replicated.
+ *
+ * A _leaf_ frag will be present in the i_fragtree IFF there is
+ * delegation info. That is, if mds >= 0 || ndist > 0.
+ */
+#define CEPH_MAX_DIRFRAG_REP 4
+
+struct ceph_inode_frag {
+ struct rb_node node;
+
+ /* fragtree state */
+ u32 frag;
+ int split_by; /* i.e. 2^(split_by) children */
+
+ /* delegation and replication info */
+ int mds; /* -1 if same authority as parent */
+ int ndist; /* >0 if replicated */
+ int dist[CEPH_MAX_DIRFRAG_REP];
+};
+
+/*
+ * We cache inode xattrs as an encoded blob until they are first used,
+ * at which point we parse them into an rbtree.
+ */
+struct ceph_inode_xattr {
+ struct rb_node node;
+
+ const char *name;
+ int name_len;
+ const char *val;
+ int val_len;
+ int dirty;
+
+ int should_free_name;
+ int should_free_val;
+};
+
+struct ceph_inode_xattrs_info {
+ /*
+ * (still encoded) xattr blob. we avoid the overhead of parsing
+ * this until someone actually calls getxattr, etc.
+ *
+ * blob->vec.iov_len == 4 implies there are no xattrs; blob ==
+ * NULL means we don't know.
+ */
+ struct ceph_buffer *blob, *prealloc_blob;
+
+ struct rb_root index;
+ bool dirty;
+ int count;
+ int names_size;
+ int vals_size;
+ u64 version, index_version;
+};
+
+/*
+ * Ceph inode.
+ */
+#define CEPH_I_COMPLETE 1 /* we have complete directory cached */
+#define CEPH_I_NODELAY 4 /* do not delay cap release */
+#define CEPH_I_FLUSH 8 /* do not delay flush of dirty metadata */
+#define CEPH_I_NOFLUSH 16 /* do not flush dirty caps */
+
+struct ceph_inode_info {
+ struct ceph_vino i_vino; /* ceph ino + snap */
+
+ u64 i_version;
+ u32 i_time_warp_seq;
+
+ unsigned i_ceph_flags;
+ unsigned long i_release_count;
+
+ struct ceph_file_layout i_layout;
+ char *i_symlink;
+
+ /* for dirs */
+ struct timespec i_rctime;
+ u64 i_rbytes, i_rfiles, i_rsubdirs;
+ u64 i_files, i_subdirs;
+ u64 i_max_offset; /* largest readdir offset, set with I_COMPLETE */
+
+ struct rb_root i_fragtree;
+ struct mutex i_fragtree_mutex;
+
+ struct ceph_inode_xattrs_info i_xattrs;
+
+ /* capabilities. protected _both_ by i_lock and cap->session's
+ * s_mutex. */
+ struct rb_root i_caps; /* cap list */
+ struct ceph_cap *i_auth_cap; /* authoritative cap, if any */
+ unsigned i_dirty_caps, i_flushing_caps; /* mask of dirtied fields */
+ struct list_head i_dirty_item, i_flushing_item;
+ u64 i_cap_flush_seq;
+ /* we need to track cap writeback on a per-cap-bit basis, to allow
+ * overlapping, pipelined cap flushes to the mds. we can probably
+ * reduce the tid to 8 bits if we're concerned about inode size. */
+ u16 i_cap_flush_last_tid, i_cap_flush_tid[CEPH_CAP_BITS];
+ wait_queue_head_t i_cap_wq; /* threads waiting on a capability */
+ unsigned long i_hold_caps_min; /* jiffies */
+ unsigned long i_hold_caps_max; /* jiffies */
+ struct list_head i_cap_delay_list; /* for delayed cap release to mds */
+ int i_cap_exporting_mds; /* to handle cap migration between */
+ unsigned i_cap_exporting_mseq; /* mds's. */
+ unsigned i_cap_exporting_issued;
+ struct ceph_cap_reservation i_cap_migration_resv;
+ struct list_head i_cap_snaps; /* snapped state pending flush to mds */
+ struct ceph_snap_context *i_head_snapc; /* set if wr_buffer_head > 0 */
+ unsigned i_snap_caps; /* cap bits for snapped files */
+
+ int i_nr_by_mode[CEPH_FILE_MODE_NUM]; /* open file counts */
+
+ u32 i_truncate_seq; /* last truncate to smaller size */
+ u64 i_truncate_size; /* and the size we last truncated down to */
+ int i_truncate_pending; /* still need to call vmtruncate */
+
+ u64 i_max_size; /* max file size authorized by mds */
+ u64 i_reported_size; /* (max_)size reported to or requested of mds */
+ u64 i_wanted_max_size; /* offset we'd like to write too */
+ u64 i_requested_max_size; /* max_size we've requested */
+
+ /* held references to caps */
+ int i_pin_ref;
+ int i_rd_ref, i_rdcache_ref, i_wr_ref;
+ int i_wrbuffer_ref, i_wrbuffer_ref_head;
+ u32 i_shared_gen; /* increment each time we get FILE_SHARED */
+ u32 i_rdcache_gen; /* we increment this each time we get
+ FILE_CACHE. If it's non-zero, we
+ _may_ have cached pages. */
+ u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */
+
+ struct list_head i_unsafe_writes; /* uncommitted sync writes */
+ struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */
+ spinlock_t i_unsafe_lock;
+
+ struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */
+ int i_snap_realm_counter; /* snap realm (if caps) */
+ struct list_head i_snap_realm_item;
+ struct list_head i_snap_flush_item;
+
+ struct work_struct i_wb_work; /* writeback work */
+ struct work_struct i_pg_inv_work; /* page invalidation work */
+
+ struct work_struct i_vmtruncate_work;
+
+ struct inode vfs_inode; /* at end */
+};
+
+static inline struct ceph_inode_info *ceph_inode(struct inode *inode)
+{
+ return container_of(inode, struct ceph_inode_info, vfs_inode);
+}
+
+static inline void ceph_i_clear(struct inode *inode, unsigned mask)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ spin_lock(&inode->i_lock);
+ ci->i_ceph_flags &= ~mask;
+ spin_unlock(&inode->i_lock);
+}
+
+static inline void ceph_i_set(struct inode *inode, unsigned mask)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ spin_lock(&inode->i_lock);
+ ci->i_ceph_flags |= mask;
+ spin_unlock(&inode->i_lock);
+}
+
+static inline bool ceph_i_test(struct inode *inode, unsigned mask)
+{
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ bool r;
+
+ smp_mb();
+ r = (ci->i_ceph_flags & mask) == mask;
+ return r;
+}
+
+
+/* find a specific frag @f */
+extern struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci,
+ u32 f);
+
+/*
+ * choose fragment for value @v. copy frag content to pfrag, if leaf
+ * exists
+ */
+extern u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
+ struct ceph_inode_frag *pfrag,
+ int *found);
+
+/*
+ * Ceph dentry state
+ */
+struct ceph_dentry_info {
+ struct ceph_mds_session *lease_session;
+ u32 lease_gen, lease_shared_gen;
+ u32 lease_seq;
+ unsigned long lease_renew_after, lease_renew_from;
+ struct list_head lru;
+ struct dentry *dentry;
+ u64 time;
+ u64 offset;
+};
+
+static inline struct ceph_dentry_info *ceph_dentry(struct dentry *dentry)
+{
+ return (struct ceph_dentry_info *)dentry->d_fsdata;
+}
+
+static inline loff_t ceph_make_fpos(unsigned frag, unsigned off)
+{
+ return ((loff_t)frag << 32) | (loff_t)off;
+}
+
+/*
+ * ino_t is <64 bits on many architectures, blech.
+ *
+ * don't include snap in ino hash, at least for now.
+ */
+static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
+{
+ ino_t ino = (ino_t)vino.ino; /* ^ (vino.snap << 20); */
+#if BITS_PER_LONG == 32
+ ino ^= vino.ino >> (sizeof(u64)-sizeof(ino_t)) * 8;
+ if (!ino)
+ ino = 1;
+#endif
+ return ino;
+}
+
+static inline int ceph_set_ino_cb(struct inode *inode, void *data)
+{
+ ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
+ inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
+ return 0;
+}
+
+static inline struct ceph_vino ceph_vino(struct inode *inode)
+{
+ return ceph_inode(inode)->i_vino;
+}
+
+/* for printf-style formatting */
+#define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap
+
+static inline u64 ceph_ino(struct inode *inode)
+{
+ return ceph_inode(inode)->i_vino.ino;
+}
+static inline u64 ceph_snap(struct inode *inode)
+{
+ return ceph_inode(inode)->i_vino.snap;
+}
+
+static inline int ceph_ino_compare(struct inode *inode, void *data)
+{
+ struct ceph_vino *pvino = (struct ceph_vino *)data;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ return ci->i_vino.ino == pvino->ino &&
+ ci->i_vino.snap == pvino->snap;
+}
+
+static inline struct inode *ceph_find_inode(struct super_block *sb,
+ struct ceph_vino vino)
+{
+ ino_t t = ceph_vino_to_ino(vino);
+ return ilookup5(sb, t, ceph_ino_compare, &vino);
+}
+
+
+/*
+ * caps helpers
+ */
+static inline bool __ceph_is_any_real_caps(struct ceph_inode_info *ci)
+{
+ return !RB_EMPTY_ROOT(&ci->i_caps);
+}
+
+extern int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented);
+extern int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int t);
+extern int __ceph_caps_issued_other(struct ceph_inode_info *ci,
+ struct ceph_cap *cap);
+
+static inline int ceph_caps_issued(struct ceph_inode_info *ci)
+{
+ int issued;
+ spin_lock(&ci->vfs_inode.i_lock);
+ issued = __ceph_caps_issued(ci, NULL);
+ spin_unlock(&ci->vfs_inode.i_lock);
+ return issued;
+}
+
+static inline int ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask,
+ int touch)
+{
+ int r;
+ spin_lock(&ci->vfs_inode.i_lock);
+ r = __ceph_caps_issued_mask(ci, mask, touch);
+ spin_unlock(&ci->vfs_inode.i_lock);
+ return r;
+}
+
+static inline int __ceph_caps_dirty(struct ceph_inode_info *ci)
+{
+ return ci->i_dirty_caps | ci->i_flushing_caps;
+}
+extern void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask);
+
+extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask);
+extern int __ceph_caps_used(struct ceph_inode_info *ci);
+
+extern int __ceph_caps_file_wanted(struct ceph_inode_info *ci);
+
+/*
+ * wanted, by virtue of open file modes AND cap refs (buffered/cached data)
+ */
+static inline int __ceph_caps_wanted(struct ceph_inode_info *ci)
+{
+ int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci);
+ if (w & CEPH_CAP_FILE_BUFFER)
+ w |= CEPH_CAP_FILE_EXCL; /* we want EXCL if dirty data */
+ return w;
+}
+
+/* what the mds thinks we want */
+extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci);
+
+extern void ceph_caps_init(void);
+extern void ceph_caps_finalize(void);
+extern void ceph_adjust_min_caps(int delta);
+extern int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need);
+extern int ceph_unreserve_caps(struct ceph_cap_reservation *ctx);
+extern void ceph_reservation_status(struct ceph_client *client,
+ int *total, int *avail, int *used,
+ int *reserved, int *min);
+
+static inline struct ceph_client *ceph_inode_to_client(struct inode *inode)
+{
+ return (struct ceph_client *)inode->i_sb->s_fs_info;
+}
+
+static inline struct ceph_client *ceph_sb_to_client(struct super_block *sb)
+{
+ return (struct ceph_client *)sb->s_fs_info;
+}
+
+
+/*
+ * we keep buffered readdir results attached to file->private_data
+ */
+struct ceph_file_info {
+ int fmode; /* initialized on open */
+
+ /* readdir: position within the dir */
+ u32 frag;
+ struct ceph_mds_request *last_readdir;
+ int at_end;
+
+ /* readdir: position within a frag */
+ unsigned offset; /* offset of last chunk, adjusted for . and .. */
+ u64 next_offset; /* offset of next chunk (last_name's + 1) */
+ char *last_name; /* last entry in previous chunk */
+ struct dentry *dentry; /* next dentry (for dcache readdir) */
+ unsigned long dir_release_count;
+
+ /* used for -o dirstat read() on directory thing */
+ char *dir_info;
+ int dir_info_len;
+};
+
+
+
+/*
+ * snapshots
+ */
+
+/*
+ * A "snap context" is the set of existing snapshots when we
+ * write data. It is used by the OSD to guide its COW behavior.
+ *
+ * The ceph_snap_context is refcounted, and attached to each dirty
+ * page, indicating which context the dirty data belonged when it was
+ * dirtied.
+ */
+struct ceph_snap_context {
+ atomic_t nref;
+ u64 seq;
+ int num_snaps;
+ u64 snaps[];
+};
+
+static inline struct ceph_snap_context *
+ceph_get_snap_context(struct ceph_snap_context *sc)
+{
+ /*
+ printk("get_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref),
+ atomic_read(&sc->nref)+1);
+ */
+ if (sc)
+ atomic_inc(&sc->nref);
+ return sc;
+}
+
+static inline void ceph_put_snap_context(struct ceph_snap_context *sc)
+{
+ if (!sc)
+ return;
+ /*
+ printk("put_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref),
+ atomic_read(&sc->nref)-1);
+ */
+ if (atomic_dec_and_test(&sc->nref)) {
+ /*printk(" deleting snap_context %p\n", sc);*/
+ kfree(sc);
+ }
+}
+
+/*
+ * A "snap realm" describes a subset of the file hierarchy sharing
+ * the same set of snapshots that apply to it. The realms themselves
+ * are organized into a hierarchy, such that children inherit (some of)
+ * the snapshots of their parents.
+ *
+ * All inodes within the realm that have capabilities are linked into a
+ * per-realm list.
+ */
+struct ceph_snap_realm {
+ u64 ino;
+ atomic_t nref;
+ struct rb_node node;
+
+ u64 created, seq;
+ u64 parent_ino;
+ u64 parent_since; /* snapid when our current parent became so */
+
+ u64 *prior_parent_snaps; /* snaps inherited from any parents we */
+ int num_prior_parent_snaps; /* had prior to parent_since */
+ u64 *snaps; /* snaps specific to this realm */
+ int num_snaps;
+
+ struct ceph_snap_realm *parent;
+ struct list_head children; /* list of child realms */
+ struct list_head child_item;
+
+ struct list_head empty_item; /* if i have ref==0 */
+
+ /* the current set of snaps for this realm */
+ struct ceph_snap_context *cached_context;
+
+ struct list_head inodes_with_caps;
+ spinlock_t inodes_with_caps_lock;
+};
+
+
+
+/*
+ * calculate the number of pages a given length and offset map onto,
+ * if we align the data.
+ */
+static inline int calc_pages_for(u64 off, u64 len)
+{
+ return ((off+len+PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT) -
+ (off >> PAGE_CACHE_SHIFT);
+}
+
+
+
+/* snap.c */
+struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
+ u64 ino);
+extern void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm);
+extern void ceph_put_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm);
+extern int ceph_update_snap_trace(struct ceph_mds_client *m,
+ void *p, void *e, bool deletion);
+extern void ceph_handle_snap(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session,
+ struct ceph_msg *msg);
+extern void ceph_queue_cap_snap(struct ceph_inode_info *ci);
+extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
+ struct ceph_cap_snap *capsnap);
+extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc);
+
+/*
+ * a cap_snap is "pending" if it is still awaiting an in-progress
+ * sync write (that may/may not still update size, mtime, etc.).
+ */
+static inline bool __ceph_have_pending_cap_snap(struct ceph_inode_info *ci)
+{
+ return !list_empty(&ci->i_cap_snaps) &&
+ list_entry(ci->i_cap_snaps.prev, struct ceph_cap_snap,
+ ci_item)->writing;
+}
+
+
+/* super.c */
+extern struct kmem_cache *ceph_inode_cachep;
+extern struct kmem_cache *ceph_cap_cachep;
+extern struct kmem_cache *ceph_dentry_cachep;
+extern struct kmem_cache *ceph_file_cachep;
+
+extern const char *ceph_msg_type_name(int type);
+extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
+
+#define FSID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \
+ "%02x%02x%02x%02x%02x%02x"
+#define PR_FSID(f) (f)->fsid[0], (f)->fsid[1], (f)->fsid[2], (f)->fsid[3], \
+ (f)->fsid[4], (f)->fsid[5], (f)->fsid[6], (f)->fsid[7], \
+ (f)->fsid[8], (f)->fsid[9], (f)->fsid[10], (f)->fsid[11], \
+ (f)->fsid[12], (f)->fsid[13], (f)->fsid[14], (f)->fsid[15]
+
+/* inode.c */
+extern const struct inode_operations ceph_file_iops;
+
+extern struct inode *ceph_alloc_inode(struct super_block *sb);
+extern void ceph_destroy_inode(struct inode *inode);
+
+extern struct inode *ceph_get_inode(struct super_block *sb,
+ struct ceph_vino vino);
+extern struct inode *ceph_get_snapdir(struct inode *parent);
+extern int ceph_fill_file_size(struct inode *inode, int issued,
+ u32 truncate_seq, u64 truncate_size, u64 size);
+extern void ceph_fill_file_time(struct inode *inode, int issued,
+ u64 time_warp_seq, struct timespec *ctime,
+ struct timespec *mtime, struct timespec *atime);
+extern int ceph_fill_trace(struct super_block *sb,
+ struct ceph_mds_request *req,
+ struct ceph_mds_session *session);
+extern int ceph_readdir_prepopulate(struct ceph_mds_request *req,
+ struct ceph_mds_session *session);
+
+extern int ceph_inode_holds_cap(struct inode *inode, int mask);
+
+extern int ceph_inode_set_size(struct inode *inode, loff_t size);
+extern void __ceph_do_pending_vmtruncate(struct inode *inode);
+extern void ceph_queue_vmtruncate(struct inode *inode);
+
+extern void ceph_queue_invalidate(struct inode *inode);
+extern void ceph_queue_writeback(struct inode *inode);
+
+extern int ceph_do_getattr(struct inode *inode, int mask);
+extern int ceph_permission(struct inode *inode, int mask);
+extern int ceph_setattr(struct dentry *dentry, struct iattr *attr);
+extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat);
+
+/* xattr.c */
+extern int ceph_setxattr(struct dentry *, const char *, const void *,
+ size_t, int);
+extern ssize_t ceph_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t ceph_listxattr(struct dentry *, char *, size_t);
+extern int ceph_removexattr(struct dentry *, const char *);
+extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci);
+extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci);
+
+/* caps.c */
+extern const char *ceph_cap_string(int c);
+extern void ceph_handle_caps(struct ceph_mds_session *session,
+ struct ceph_msg *msg);
+extern int ceph_add_cap(struct inode *inode,
+ struct ceph_mds_session *session, u64 cap_id,
+ int fmode, unsigned issued, unsigned wanted,
+ unsigned cap, unsigned seq, u64 realmino, int flags,
+ struct ceph_cap_reservation *caps_reservation);
+extern void __ceph_remove_cap(struct ceph_cap *cap);
+static inline void ceph_remove_cap(struct ceph_cap *cap)
+{
+ struct inode *inode = &cap->ci->vfs_inode;
+ spin_lock(&inode->i_lock);
+ __ceph_remove_cap(cap);
+ spin_unlock(&inode->i_lock);
+}
+extern void ceph_put_cap(struct ceph_cap *cap);
+
+extern void ceph_queue_caps_release(struct inode *inode);
+extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc);
+extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync);
+extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
+ struct ceph_mds_session *session);
+extern int ceph_get_cap_mds(struct inode *inode);
+extern void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps);
+extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had);
+extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
+ struct ceph_snap_context *snapc);
+extern void __ceph_flush_snaps(struct ceph_inode_info *ci,
+ struct ceph_mds_session **psession);
+extern void ceph_check_caps(struct ceph_inode_info *ci, int flags,
+ struct ceph_mds_session *session);
+extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc);
+extern void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc);
+
+extern int ceph_encode_inode_release(void **p, struct inode *inode,
+ int mds, int drop, int unless, int force);
+extern int ceph_encode_dentry_release(void **p, struct dentry *dn,
+ int mds, int drop, int unless);
+
+extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
+ int *got, loff_t endoff);
+
+/* for counting open files by mode */
+static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode)
+{
+ ci->i_nr_by_mode[mode]++;
+}
+extern void ceph_put_fmode(struct ceph_inode_info *ci, int mode);
+
+/* addr.c */
+extern const struct address_space_operations ceph_aops;
+extern int ceph_mmap(struct file *file, struct vm_area_struct *vma);
+
+/* file.c */
+extern const struct file_operations ceph_file_fops;
+extern const struct address_space_operations ceph_aops;
+extern int ceph_open(struct inode *inode, struct file *file);
+extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd, int mode,
+ int locked_dir);
+extern int ceph_release(struct inode *inode, struct file *filp);
+extern void ceph_release_page_vector(struct page **pages, int num_pages);
+
+/* dir.c */
+extern const struct file_operations ceph_dir_fops;
+extern const struct inode_operations ceph_dir_iops;
+extern struct dentry_operations ceph_dentry_ops, ceph_snap_dentry_ops,
+ ceph_snapdir_dentry_ops;
+
+extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry);
+extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
+ struct dentry *dentry, int err);
+
+extern void ceph_dentry_lru_add(struct dentry *dn);
+extern void ceph_dentry_lru_touch(struct dentry *dn);
+extern void ceph_dentry_lru_del(struct dentry *dn);
+
+/*
+ * our d_ops vary depending on whether the inode is live,
+ * snapshotted (read-only), or a virtual ".snap" directory.
+ */
+int ceph_init_dentry(struct dentry *dentry);
+
+
+/* ioctl.c */
+extern long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+/* export.c */
+extern const struct export_operations ceph_export_ops;
+
+/* debugfs.c */
+extern int ceph_debugfs_init(void);
+extern void ceph_debugfs_cleanup(void);
+extern int ceph_debugfs_client_init(struct ceph_client *client);
+extern void ceph_debugfs_client_cleanup(struct ceph_client *client);
+
+static inline struct inode *get_dentry_parent_inode(struct dentry *dentry)
+{
+ if (dentry && dentry->d_parent)
+ return dentry->d_parent->d_inode;
+
+ return NULL;
+}
+
+#endif /* _FS_CEPH_SUPER_H */
diff --git a/fs/ceph/types.h b/fs/ceph/types.h
new file mode 100644
index 00000000000..28b35a005ec
--- /dev/null
+++ b/fs/ceph/types.h
@@ -0,0 +1,29 @@
+#ifndef _FS_CEPH_TYPES_H
+#define _FS_CEPH_TYPES_H
+
+/* needed before including ceph_fs.h */
+#include <linux/in.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+
+#include "ceph_fs.h"
+#include "ceph_frag.h"
+#include "ceph_hash.h"
+
+/*
+ * Identify inodes by both their ino AND snapshot id (a u64).
+ */
+struct ceph_vino {
+ u64 ino;
+ u64 snap;
+};
+
+
+/* context for the caps reservation mechanism */
+struct ceph_cap_reservation {
+ int count;
+};
+
+
+#endif
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
new file mode 100644
index 00000000000..2845422907f
--- /dev/null
+++ b/fs/ceph/xattr.c
@@ -0,0 +1,845 @@
+#include "ceph_debug.h"
+#include "super.h"
+#include "decode.h"
+
+#include <linux/xattr.h>
+#include <linux/slab.h>
+
+static bool ceph_is_valid_xattr(const char *name)
+{
+ return !strncmp(name, XATTR_SECURITY_PREFIX,
+ XATTR_SECURITY_PREFIX_LEN) ||
+ !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
+ !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
+}
+
+/*
+ * These define virtual xattrs exposing the recursive directory
+ * statistics and layout metadata.
+ */
+struct ceph_vxattr_cb {
+ bool readonly;
+ char *name;
+ size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
+ size_t size);
+};
+
+/* directories */
+
+static size_t ceph_vxattrcb_entries(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs);
+}
+
+static size_t ceph_vxattrcb_files(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ return snprintf(val, size, "%lld", ci->i_files);
+}
+
+static size_t ceph_vxattrcb_subdirs(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ return snprintf(val, size, "%lld", ci->i_subdirs);
+}
+
+static size_t ceph_vxattrcb_rentries(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs);
+}
+
+static size_t ceph_vxattrcb_rfiles(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ return snprintf(val, size, "%lld", ci->i_rfiles);
+}
+
+static size_t ceph_vxattrcb_rsubdirs(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ return snprintf(val, size, "%lld", ci->i_rsubdirs);
+}
+
+static size_t ceph_vxattrcb_rbytes(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ return snprintf(val, size, "%lld", ci->i_rbytes);
+}
+
+static size_t ceph_vxattrcb_rctime(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ return snprintf(val, size, "%ld.%ld", (long)ci->i_rctime.tv_sec,
+ (long)ci->i_rctime.tv_nsec);
+}
+
+static struct ceph_vxattr_cb ceph_dir_vxattrs[] = {
+ { true, "user.ceph.dir.entries", ceph_vxattrcb_entries},
+ { true, "user.ceph.dir.files", ceph_vxattrcb_files},
+ { true, "user.ceph.dir.subdirs", ceph_vxattrcb_subdirs},
+ { true, "user.ceph.dir.rentries", ceph_vxattrcb_rentries},
+ { true, "user.ceph.dir.rfiles", ceph_vxattrcb_rfiles},
+ { true, "user.ceph.dir.rsubdirs", ceph_vxattrcb_rsubdirs},
+ { true, "user.ceph.dir.rbytes", ceph_vxattrcb_rbytes},
+ { true, "user.ceph.dir.rctime", ceph_vxattrcb_rctime},
+ { true, NULL, NULL }
+};
+
+/* files */
+
+static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
+ size_t size)
+{
+ int ret;
+
+ ret = snprintf(val, size,
+ "chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n",
+ (unsigned long long)ceph_file_layout_su(ci->i_layout),
+ (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
+ (unsigned long long)ceph_file_layout_object_size(ci->i_layout));
+ if (ceph_file_layout_pg_preferred(ci->i_layout))
+ ret += snprintf(val + ret, size, "preferred_osd=%lld\n",
+ (unsigned long long)ceph_file_layout_pg_preferred(
+ ci->i_layout));
+ return ret;
+}
+
+static struct ceph_vxattr_cb ceph_file_vxattrs[] = {
+ { true, "user.ceph.layout", ceph_vxattrcb_layout},
+ { NULL, NULL }
+};
+
+static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode)
+{
+ if (S_ISDIR(inode->i_mode))
+ return ceph_dir_vxattrs;
+ else if (S_ISREG(inode->i_mode))
+ return ceph_file_vxattrs;
+ return NULL;
+}
+
+static struct ceph_vxattr_cb *ceph_match_vxattr(struct ceph_vxattr_cb *vxattr,
+ const char *name)
+{
+ do {
+ if (strcmp(vxattr->name, name) == 0)
+ return vxattr;
+ vxattr++;
+ } while (vxattr->name);
+ return NULL;
+}
+
+static int __set_xattr(struct ceph_inode_info *ci,
+ const char *name, int name_len,
+ const char *val, int val_len,
+ int dirty,
+ int should_free_name, int should_free_val,
+ struct ceph_inode_xattr **newxattr)
+{
+ struct rb_node **p;
+ struct rb_node *parent = NULL;
+ struct ceph_inode_xattr *xattr = NULL;
+ int c;
+ int new = 0;
+
+ p = &ci->i_xattrs.index.rb_node;
+ while (*p) {
+ parent = *p;
+ xattr = rb_entry(parent, struct ceph_inode_xattr, node);
+ c = strncmp(name, xattr->name, min(name_len, xattr->name_len));
+ if (c < 0)
+ p = &(*p)->rb_left;
+ else if (c > 0)
+ p = &(*p)->rb_right;
+ else {
+ if (name_len == xattr->name_len)
+ break;
+ else if (name_len < xattr->name_len)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+ xattr = NULL;
+ }
+
+ if (!xattr) {
+ new = 1;
+ xattr = *newxattr;
+ xattr->name = name;
+ xattr->name_len = name_len;
+ xattr->should_free_name = should_free_name;
+
+ ci->i_xattrs.count++;
+ dout("__set_xattr count=%d\n", ci->i_xattrs.count);
+ } else {
+ kfree(*newxattr);
+ *newxattr = NULL;
+ if (xattr->should_free_val)
+ kfree((void *)xattr->val);
+
+ if (should_free_name) {
+ kfree((void *)name);
+ name = xattr->name;
+ }
+ ci->i_xattrs.names_size -= xattr->name_len;
+ ci->i_xattrs.vals_size -= xattr->val_len;
+ }
+ if (!xattr) {
+ pr_err("__set_xattr ENOMEM on %p %llx.%llx xattr %s=%s\n",
+ &ci->vfs_inode, ceph_vinop(&ci->vfs_inode), name,
+ xattr->val);
+ return -ENOMEM;
+ }
+ ci->i_xattrs.names_size += name_len;
+ ci->i_xattrs.vals_size += val_len;
+ if (val)
+ xattr->val = val;
+ else
+ xattr->val = "";
+
+ xattr->val_len = val_len;
+ xattr->dirty = dirty;
+ xattr->should_free_val = (val && should_free_val);
+
+ if (new) {
+ rb_link_node(&xattr->node, parent, p);
+ rb_insert_color(&xattr->node, &ci->i_xattrs.index);
+ dout("__set_xattr_val p=%p\n", p);
+ }
+
+ dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n",
+ ceph_vinop(&ci->vfs_inode), xattr, name, val_len, val);
+
+ return 0;
+}
+
+static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci,
+ const char *name)
+{
+ struct rb_node **p;
+ struct rb_node *parent = NULL;
+ struct ceph_inode_xattr *xattr = NULL;
+ int c;
+
+ p = &ci->i_xattrs.index.rb_node;
+ while (*p) {
+ parent = *p;
+ xattr = rb_entry(parent, struct ceph_inode_xattr, node);
+ c = strncmp(name, xattr->name, xattr->name_len);
+ if (c < 0)
+ p = &(*p)->rb_left;
+ else if (c > 0)
+ p = &(*p)->rb_right;
+ else {
+ dout("__get_xattr %s: found %.*s\n", name,
+ xattr->val_len, xattr->val);
+ return xattr;
+ }
+ }
+
+ dout("__get_xattr %s: not found\n", name);
+
+ return NULL;
+}
+
+static void __free_xattr(struct ceph_inode_xattr *xattr)
+{
+ BUG_ON(!xattr);
+
+ if (xattr->should_free_name)
+ kfree((void *)xattr->name);
+ if (xattr->should_free_val)
+ kfree((void *)xattr->val);
+
+ kfree(xattr);
+}
+
+static int __remove_xattr(struct ceph_inode_info *ci,
+ struct ceph_inode_xattr *xattr)
+{
+ if (!xattr)
+ return -EOPNOTSUPP;
+
+ rb_erase(&xattr->node, &ci->i_xattrs.index);
+
+ if (xattr->should_free_name)
+ kfree((void *)xattr->name);
+ if (xattr->should_free_val)
+ kfree((void *)xattr->val);
+
+ ci->i_xattrs.names_size -= xattr->name_len;
+ ci->i_xattrs.vals_size -= xattr->val_len;
+ ci->i_xattrs.count--;
+ kfree(xattr);
+
+ return 0;
+}
+
+static int __remove_xattr_by_name(struct ceph_inode_info *ci,
+ const char *name)
+{
+ struct rb_node **p;
+ struct ceph_inode_xattr *xattr;
+ int err;
+
+ p = &ci->i_xattrs.index.rb_node;
+ xattr = __get_xattr(ci, name);
+ err = __remove_xattr(ci, xattr);
+ return err;
+}
+
+static char *__copy_xattr_names(struct ceph_inode_info *ci,
+ char *dest)
+{
+ struct rb_node *p;
+ struct ceph_inode_xattr *xattr = NULL;
+
+ p = rb_first(&ci->i_xattrs.index);
+ dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count);
+
+ while (p) {
+ xattr = rb_entry(p, struct ceph_inode_xattr, node);
+ memcpy(dest, xattr->name, xattr->name_len);
+ dest[xattr->name_len] = '\0';
+
+ dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name,
+ xattr->name_len, ci->i_xattrs.names_size);
+
+ dest += xattr->name_len + 1;
+ p = rb_next(p);
+ }
+
+ return dest;
+}
+
+void __ceph_destroy_xattrs(struct ceph_inode_info *ci)
+{
+ struct rb_node *p, *tmp;
+ struct ceph_inode_xattr *xattr = NULL;
+
+ p = rb_first(&ci->i_xattrs.index);
+
+ dout("__ceph_destroy_xattrs p=%p\n", p);
+
+ while (p) {
+ xattr = rb_entry(p, struct ceph_inode_xattr, node);
+ tmp = p;
+ p = rb_next(tmp);
+ dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p,
+ xattr->name_len, xattr->name);
+ rb_erase(tmp, &ci->i_xattrs.index);
+
+ __free_xattr(xattr);
+ }
+
+ ci->i_xattrs.names_size = 0;
+ ci->i_xattrs.vals_size = 0;
+ ci->i_xattrs.index_version = 0;
+ ci->i_xattrs.count = 0;
+ ci->i_xattrs.index = RB_ROOT;
+}
+
+static int __build_xattrs(struct inode *inode)
+{
+ u32 namelen;
+ u32 numattr = 0;
+ void *p, *end;
+ u32 len;
+ const char *name, *val;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int xattr_version;
+ struct ceph_inode_xattr **xattrs = NULL;
+ int err = 0;
+ int i;
+
+ dout("__build_xattrs() len=%d\n",
+ ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0);
+
+ if (ci->i_xattrs.index_version >= ci->i_xattrs.version)
+ return 0; /* already built */
+
+ __ceph_destroy_xattrs(ci);
+
+start:
+ /* updated internal xattr rb tree */
+ if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) {
+ p = ci->i_xattrs.blob->vec.iov_base;
+ end = p + ci->i_xattrs.blob->vec.iov_len;
+ ceph_decode_32_safe(&p, end, numattr, bad);
+ xattr_version = ci->i_xattrs.version;
+ spin_unlock(&inode->i_lock);
+
+ xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *),
+ GFP_NOFS);
+ err = -ENOMEM;
+ if (!xattrs)
+ goto bad_lock;
+ memset(xattrs, 0, numattr*sizeof(struct ceph_xattr *));
+ for (i = 0; i < numattr; i++) {
+ xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr),
+ GFP_NOFS);
+ if (!xattrs[i])
+ goto bad_lock;
+ }
+
+ spin_lock(&inode->i_lock);
+ if (ci->i_xattrs.version != xattr_version) {
+ /* lost a race, retry */
+ for (i = 0; i < numattr; i++)
+ kfree(xattrs[i]);
+ kfree(xattrs);
+ goto start;
+ }
+ err = -EIO;
+ while (numattr--) {
+ ceph_decode_32_safe(&p, end, len, bad);
+ namelen = len;
+ name = p;
+ p += len;
+ ceph_decode_32_safe(&p, end, len, bad);
+ val = p;
+ p += len;
+
+ err = __set_xattr(ci, name, namelen, val, len,
+ 0, 0, 0, &xattrs[numattr]);
+
+ if (err < 0)
+ goto bad;
+ }
+ kfree(xattrs);
+ }
+ ci->i_xattrs.index_version = ci->i_xattrs.version;
+ ci->i_xattrs.dirty = false;
+
+ return err;
+bad_lock:
+ spin_lock(&inode->i_lock);
+bad:
+ if (xattrs) {
+ for (i = 0; i < numattr; i++)
+ kfree(xattrs[i]);
+ kfree(xattrs);
+ }
+ ci->i_xattrs.names_size = 0;
+ return err;
+}
+
+static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size,
+ int val_size)
+{
+ /*
+ * 4 bytes for the length, and additional 4 bytes per each xattr name,
+ * 4 bytes per each value
+ */
+ int size = 4 + ci->i_xattrs.count*(4 + 4) +
+ ci->i_xattrs.names_size +
+ ci->i_xattrs.vals_size;
+ dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n",
+ ci->i_xattrs.count, ci->i_xattrs.names_size,
+ ci->i_xattrs.vals_size);
+
+ if (name_size)
+ size += 4 + 4 + name_size + val_size;
+
+ return size;
+}
+
+/*
+ * If there are dirty xattrs, reencode xattrs into the prealloc_blob
+ * and swap into place.
+ */
+void __ceph_build_xattrs_blob(struct ceph_inode_info *ci)
+{
+ struct rb_node *p;
+ struct ceph_inode_xattr *xattr = NULL;
+ void *dest;
+
+ dout("__build_xattrs_blob %p\n", &ci->vfs_inode);
+ if (ci->i_xattrs.dirty) {
+ int need = __get_required_blob_size(ci, 0, 0);
+
+ BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len);
+
+ p = rb_first(&ci->i_xattrs.index);
+ dest = ci->i_xattrs.prealloc_blob->vec.iov_base;
+
+ ceph_encode_32(&dest, ci->i_xattrs.count);
+ while (p) {
+ xattr = rb_entry(p, struct ceph_inode_xattr, node);
+
+ ceph_encode_32(&dest, xattr->name_len);
+ memcpy(dest, xattr->name, xattr->name_len);
+ dest += xattr->name_len;
+ ceph_encode_32(&dest, xattr->val_len);
+ memcpy(dest, xattr->val, xattr->val_len);
+ dest += xattr->val_len;
+
+ p = rb_next(p);
+ }
+
+ /* adjust buffer len; it may be larger than we need */
+ ci->i_xattrs.prealloc_blob->vec.iov_len =
+ dest - ci->i_xattrs.prealloc_blob->vec.iov_base;
+
+ if (ci->i_xattrs.blob)
+ ceph_buffer_put(ci->i_xattrs.blob);
+ ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob;
+ ci->i_xattrs.prealloc_blob = NULL;
+ ci->i_xattrs.dirty = false;
+ }
+}
+
+ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value,
+ size_t size)
+{
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+ int err;
+ struct ceph_inode_xattr *xattr;
+ struct ceph_vxattr_cb *vxattr = NULL;
+
+ if (!ceph_is_valid_xattr(name))
+ return -ENODATA;
+
+ /* let's see if a virtual xattr was requested */
+ if (vxattrs)
+ vxattr = ceph_match_vxattr(vxattrs, name);
+
+ spin_lock(&inode->i_lock);
+ dout("getxattr %p ver=%lld index_ver=%lld\n", inode,
+ ci->i_xattrs.version, ci->i_xattrs.index_version);
+
+ if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) &&
+ (ci->i_xattrs.index_version >= ci->i_xattrs.version)) {
+ goto get_xattr;
+ } else {
+ spin_unlock(&inode->i_lock);
+ /* get xattrs from mds (if we don't already have them) */
+ err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR);
+ if (err)
+ return err;
+ }
+
+ spin_lock(&inode->i_lock);
+
+ if (vxattr && vxattr->readonly) {
+ err = vxattr->getxattr_cb(ci, value, size);
+ goto out;
+ }
+
+ err = __build_xattrs(inode);
+ if (err < 0)
+ goto out;
+
+get_xattr:
+ err = -ENODATA; /* == ENOATTR */
+ xattr = __get_xattr(ci, name);
+ if (!xattr) {
+ if (vxattr)
+ err = vxattr->getxattr_cb(ci, value, size);
+ goto out;
+ }
+
+ err = -ERANGE;
+ if (size && size < xattr->val_len)
+ goto out;
+
+ err = xattr->val_len;
+ if (size == 0)
+ goto out;
+
+ memcpy(value, xattr->val, xattr->val_len);
+
+out:
+ spin_unlock(&inode->i_lock);
+ return err;
+}
+
+ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
+{
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+ u32 vir_namelen = 0;
+ u32 namelen;
+ int err;
+ u32 len;
+ int i;
+
+ spin_lock(&inode->i_lock);
+ dout("listxattr %p ver=%lld index_ver=%lld\n", inode,
+ ci->i_xattrs.version, ci->i_xattrs.index_version);
+
+ if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) &&
+ (ci->i_xattrs.index_version > ci->i_xattrs.version)) {
+ goto list_xattr;
+ } else {
+ spin_unlock(&inode->i_lock);
+ err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR);
+ if (err)
+ return err;
+ }
+
+ spin_lock(&inode->i_lock);
+
+ err = __build_xattrs(inode);
+ if (err < 0)
+ goto out;
+
+list_xattr:
+ vir_namelen = 0;
+ /* include virtual dir xattrs */
+ if (vxattrs)
+ for (i = 0; vxattrs[i].name; i++)
+ vir_namelen += strlen(vxattrs[i].name) + 1;
+ /* adding 1 byte per each variable due to the null termination */
+ namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
+ err = -ERANGE;
+ if (size && namelen > size)
+ goto out;
+
+ err = namelen;
+ if (size == 0)
+ goto out;
+
+ names = __copy_xattr_names(ci, names);
+
+ /* virtual xattr names, too */
+ if (vxattrs)
+ for (i = 0; vxattrs[i].name; i++) {
+ len = sprintf(names, "%s", vxattrs[i].name);
+ names += len + 1;
+ }
+
+out:
+ spin_unlock(&inode->i_lock);
+ return err;
+}
+
+static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
+ const char *value, size_t size, int flags)
+{
+ struct ceph_client *client = ceph_client(dentry->d_sb);
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct inode *parent_inode = dentry->d_parent->d_inode;
+ struct ceph_mds_request *req;
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ int err;
+ int i, nr_pages;
+ struct page **pages = NULL;
+ void *kaddr;
+
+ /* copy value into some pages */
+ nr_pages = calc_pages_for(0, size);
+ if (nr_pages) {
+ pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS);
+ if (!pages)
+ return -ENOMEM;
+ err = -ENOMEM;
+ for (i = 0; i < nr_pages; i++) {
+ pages[i] = alloc_page(GFP_NOFS);
+ if (!pages[i]) {
+ nr_pages = i;
+ goto out;
+ }
+ kaddr = kmap(pages[i]);
+ memcpy(kaddr, value + i*PAGE_CACHE_SIZE,
+ min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE));
+ }
+ }
+
+ dout("setxattr value=%.*s\n", (int)size, value);
+
+ /* do request */
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR,
+ USE_AUTH_MDS);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto out;
+ }
+ req->r_inode = igrab(inode);
+ req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
+ req->r_num_caps = 1;
+ req->r_args.setxattr.flags = cpu_to_le32(flags);
+ req->r_path2 = kstrdup(name, GFP_NOFS);
+
+ req->r_pages = pages;
+ req->r_num_pages = nr_pages;
+ req->r_data_len = size;
+
+ dout("xattr.ver (before): %lld\n", ci->i_xattrs.version);
+ err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+ ceph_mdsc_put_request(req);
+ dout("xattr.ver (after): %lld\n", ci->i_xattrs.version);
+
+out:
+ if (pages) {
+ for (i = 0; i < nr_pages; i++)
+ __free_page(pages[i]);
+ kfree(pages);
+ }
+ return err;
+}
+
+int ceph_setxattr(struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags)
+{
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+ int err;
+ int name_len = strlen(name);
+ int val_len = size;
+ char *newname = NULL;
+ char *newval = NULL;
+ struct ceph_inode_xattr *xattr = NULL;
+ int issued;
+ int required_blob_size;
+
+ if (ceph_snap(inode) != CEPH_NOSNAP)
+ return -EROFS;
+
+ if (!ceph_is_valid_xattr(name))
+ return -EOPNOTSUPP;
+
+ if (vxattrs) {
+ struct ceph_vxattr_cb *vxattr =
+ ceph_match_vxattr(vxattrs, name);
+ if (vxattr && vxattr->readonly)
+ return -EOPNOTSUPP;
+ }
+
+ /* preallocate memory for xattr name, value, index node */
+ err = -ENOMEM;
+ newname = kmalloc(name_len + 1, GFP_NOFS);
+ if (!newname)
+ goto out;
+ memcpy(newname, name, name_len + 1);
+
+ if (val_len) {
+ newval = kmalloc(val_len + 1, GFP_NOFS);
+ if (!newval)
+ goto out;
+ memcpy(newval, value, val_len);
+ newval[val_len] = '\0';
+ }
+
+ xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS);
+ if (!xattr)
+ goto out;
+
+ spin_lock(&inode->i_lock);
+retry:
+ issued = __ceph_caps_issued(ci, NULL);
+ if (!(issued & CEPH_CAP_XATTR_EXCL))
+ goto do_sync;
+ __build_xattrs(inode);
+
+ required_blob_size = __get_required_blob_size(ci, name_len, val_len);
+
+ if (!ci->i_xattrs.prealloc_blob ||
+ required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) {
+ struct ceph_buffer *blob = NULL;
+
+ spin_unlock(&inode->i_lock);
+ dout(" preaallocating new blob size=%d\n", required_blob_size);
+ blob = ceph_buffer_new(required_blob_size, GFP_NOFS);
+ if (!blob)
+ goto out;
+ spin_lock(&inode->i_lock);
+ if (ci->i_xattrs.prealloc_blob)
+ ceph_buffer_put(ci->i_xattrs.prealloc_blob);
+ ci->i_xattrs.prealloc_blob = blob;
+ goto retry;
+ }
+
+ dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
+ err = __set_xattr(ci, newname, name_len, newval,
+ val_len, 1, 1, 1, &xattr);
+ __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
+ ci->i_xattrs.dirty = true;
+ inode->i_ctime = CURRENT_TIME;
+ spin_unlock(&inode->i_lock);
+
+ return err;
+
+do_sync:
+ spin_unlock(&inode->i_lock);
+ err = ceph_sync_setxattr(dentry, name, value, size, flags);
+out:
+ kfree(newname);
+ kfree(newval);
+ kfree(xattr);
+ return err;
+}
+
+static int ceph_send_removexattr(struct dentry *dentry, const char *name)
+{
+ struct ceph_client *client = ceph_client(dentry->d_sb);
+ struct ceph_mds_client *mdsc = &client->mdsc;
+ struct inode *inode = dentry->d_inode;
+ struct inode *parent_inode = dentry->d_parent->d_inode;
+ struct ceph_mds_request *req;
+ int err;
+
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR,
+ USE_AUTH_MDS);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+ req->r_inode = igrab(inode);
+ req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
+ req->r_num_caps = 1;
+ req->r_path2 = kstrdup(name, GFP_NOFS);
+
+ err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+ ceph_mdsc_put_request(req);
+ return err;
+}
+
+int ceph_removexattr(struct dentry *dentry, const char *name)
+{
+ struct inode *inode = dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+ int issued;
+ int err;
+
+ if (ceph_snap(inode) != CEPH_NOSNAP)
+ return -EROFS;
+
+ if (!ceph_is_valid_xattr(name))
+ return -EOPNOTSUPP;
+
+ if (vxattrs) {
+ struct ceph_vxattr_cb *vxattr =
+ ceph_match_vxattr(vxattrs, name);
+ if (vxattr && vxattr->readonly)
+ return -EOPNOTSUPP;
+ }
+
+ spin_lock(&inode->i_lock);
+ __build_xattrs(inode);
+ issued = __ceph_caps_issued(ci, NULL);
+ dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued));
+
+ if (!(issued & CEPH_CAP_XATTR_EXCL))
+ goto do_sync;
+
+ err = __remove_xattr_by_name(ceph_inode(inode), name);
+ __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
+ ci->i_xattrs.dirty = true;
+ inode->i_ctime = CURRENT_TIME;
+
+ spin_unlock(&inode->i_lock);
+
+ return err;
+do_sync:
+ spin_unlock(&inode->i_lock);
+ err = ceph_send_removexattr(dentry, name);
+ return err;
+}
+
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 20692fbfdb2..a20bea59893 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -136,7 +136,7 @@ asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val)
return 0;
}
- ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to lenght octet */
+ ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to length octet */
if ((ch) == ASN1_ENUM) /* if ch value is ENUM, 0xa */
*val = *(++(ctx->pointer)); /* value has enum value */
else
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index b44ce0a0711..78e4d2a3a68 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -15,6 +15,7 @@
#include <linux/dcache.h>
#include <linux/mount.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#include <linux/vfs.h>
#include <linux/fs.h>
#include "cifsglob.h"
@@ -54,7 +55,7 @@ void cifs_dfs_release_automount_timer(void)
* Extracts sharename form full UNC.
* i.e. strips from UNC trailing path that is not part of share
* name and fixup missing '\' in the begining of DFS node refferal
- * if neccessary.
+ * if necessary.
* Returns pointer to share name on success or ERR_PTR on error.
* Caller is responsible for freeing returned string.
*/
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 4797787c6a4..246a167cb91 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -18,6 +18,8 @@
#ifndef _CIFS_FS_SB_H
#define _CIFS_FS_SB_H
+#include <linux/backing-dev.h>
+
#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */
#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
@@ -50,5 +52,6 @@ struct cifs_sb_info {
#ifdef CONFIG_CIFS_DFS_UPCALL
char *mountdata; /* mount options received at mount time */
#endif
+ struct backing_dev_info bdi;
};
#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 8ec7736ce95..310d12f69a9 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -20,6 +20,7 @@
*/
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <keys/user-type.h>
#include <linux/key-type.h>
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 714a542cbaf..d07676bd76d 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
+#include <linux/slab.h>
#include "cifs_unicode.h"
#include "cifs_uniupr.h"
#include "cifspdu.h"
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 7dfe0842a6f..9b716d044bb 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -22,6 +22,7 @@
*/
#include <linux/fs.h>
+#include <linux/slab.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsacl.h"
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 7efe1745494..fbe986430d0 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -20,6 +20,7 @@
*/
#include <linux/fs.h>
+#include <linux/slab.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifs_debug.h"
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8c6a0362717..ad235d604a0 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -103,6 +103,12 @@ cifs_read_super(struct super_block *sb, void *data,
if (cifs_sb == NULL)
return -ENOMEM;
+ rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
+ if (rc) {
+ kfree(cifs_sb);
+ return rc;
+ }
+
#ifdef CONFIG_CIFS_DFS_UPCALL
/* copy mount params to sb for use in submounts */
/* BB: should we move this after the mount so we
@@ -115,6 +121,7 @@ cifs_read_super(struct super_block *sb, void *data,
int len = strlen(data);
cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
if (cifs_sb->mountdata == NULL) {
+ bdi_destroy(&cifs_sb->bdi);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
return -ENOMEM;
@@ -135,6 +142,7 @@ cifs_read_super(struct super_block *sb, void *data,
sb->s_magic = CIFS_MAGIC_NUMBER;
sb->s_op = &cifs_super_ops;
+ sb->s_bdi = &cifs_sb->bdi;
/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
sb->s_blocksize =
cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
@@ -183,6 +191,7 @@ out_mount_failed:
}
#endif
unload_nls(cifs_sb->local_nls);
+ bdi_destroy(&cifs_sb->bdi);
kfree(cifs_sb);
}
return rc;
@@ -214,6 +223,7 @@ cifs_put_super(struct super_block *sb)
#endif
unload_nls(cifs_sb->local_nls);
+ bdi_destroy(&cifs_sb->bdi);
kfree(cifs_sb);
unlock_kernel();
@@ -312,6 +322,7 @@ cifs_alloc_inode(struct super_block *sb)
cifs_inode->clientCanCacheRead = false;
cifs_inode->clientCanCacheAll = false;
cifs_inode->delete_pending = false;
+ cifs_inode->invalid_mapping = false;
cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
cifs_inode->server_eof = 0;
@@ -638,7 +649,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
setting the revalidate time to zero */
CIFS_I(file->f_path.dentry->d_inode)->time = 0;
- retval = cifs_revalidate(file->f_path.dentry);
+ retval = cifs_revalidate_file(file);
if (retval < 0)
return (loff_t)retval;
}
@@ -807,6 +818,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
.release = cifs_close,
.fsync = cifs_fsync,
.flush = cifs_flush,
+ .mmap = cifs_file_mmap,
.splice_read = generic_file_splice_read,
#ifdef CONFIG_CIFS_POSIX
.unlocked_ioctl = cifs_ioctl,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 78c1b86d55f..7aa57ecdc43 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -61,7 +61,8 @@ extern int cifs_mkdir(struct inode *, struct dentry *, int);
extern int cifs_rmdir(struct inode *, struct dentry *);
extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
struct dentry *);
-extern int cifs_revalidate(struct dentry *);
+extern int cifs_revalidate_file(struct file *filp);
+extern int cifs_revalidate_dentry(struct dentry *);
extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int cifs_setattr(struct dentry *, struct iattr *);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index a1c817eb291..ecf0ffbe2b6 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -18,6 +18,7 @@
*/
#include <linux/in.h>
#include <linux/in6.h>
+#include <linux/slab.h>
#include <linux/slow-work.h>
#include "cifs_fs_sb.h"
#include "cifsacl.h"
@@ -389,6 +390,7 @@ struct cifsInodeInfo {
bool clientCanCacheRead:1; /* read oplock */
bool clientCanCacheAll:1; /* read and writebehind oplock */
bool delete_pending:1; /* DELETE_ON_CLOSE is set */
+ bool invalid_mapping:1; /* pagecache is invalid */
u64 server_eof; /* current file size on server */
u64 uniqueid; /* server inode number */
struct inode vfs_inode;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 88e2bc44ac5..39e47f46dea 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -104,10 +104,12 @@ extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
extern struct inode *cifs_iget(struct super_block *sb,
struct cifs_fattr *fattr);
+extern int cifs_get_file_info(struct file *filp);
extern int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path,
FILE_ALL_INFO *pfile_info,
struct super_block *sb, int xid, const __u16 *pfid);
+extern int cifs_get_file_info_unix(struct file *filp);
extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path,
struct super_block *sb, int xid);
@@ -142,6 +144,8 @@ extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
const __u16 search_handle);
+extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
+ u16 netfid, FILE_ALL_INFO *pFindData);
extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
FILE_ALL_INFO *findData,
@@ -152,6 +156,8 @@ extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
FILE_ALL_INFO *findData,
const struct nls_table *nls_codepage, int remap);
+extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
+ u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
extern int CIFSSMBUnixQPathInfo(const int xid,
struct cifsTconInfo *tcon,
const unsigned char *searchName,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 9d17df3e076..5d3f29fef53 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -30,6 +30,7 @@
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/vfs.h>
+#include <linux/slab.h>
#include <linux/posix_acl_xattr.h>
#include <asm/uaccess.h>
#include "cifspdu.h"
@@ -500,7 +501,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
} else if (pSMBr->hdr.WordCount == 13) {
cERROR(1, ("mount failed, cifs module not built "
"with CIFS_WEAK_PW_HASH support"));
- rc = -EOPNOTSUPP;
+ rc = -EOPNOTSUPP;
#endif /* WEAK_PW_HASH */
goto neg_err_exit;
} else if (pSMBr->hdr.WordCount != 17) {
@@ -1430,6 +1431,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
__u32 bytes_sent;
__u16 byte_count;
+ *nbytes = 0;
+
/* cFYI(1, ("write at %lld %d bytes", offset, count));*/
if (tcon->ses == NULL)
return -ECONNABORTED;
@@ -1512,11 +1515,18 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
cifs_stats_inc(&tcon->num_writes);
if (rc) {
cFYI(1, ("Send error in write = %d", rc));
- *nbytes = 0;
} else {
*nbytes = le16_to_cpu(pSMBr->CountHigh);
*nbytes = (*nbytes) << 16;
*nbytes += le16_to_cpu(pSMBr->Count);
+
+ /*
+ * Mask off high 16 bits when bytes written as returned by the
+ * server is greater than bytes requested by the client. Some
+ * OS/2 servers are known to set incorrect CountHigh values.
+ */
+ if (*nbytes > count)
+ *nbytes &= 0xFFFF;
}
cifs_buf_release(pSMB);
@@ -1605,6 +1615,14 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
*nbytes = le16_to_cpu(pSMBr->CountHigh);
*nbytes = (*nbytes) << 16;
*nbytes += le16_to_cpu(pSMBr->Count);
+
+ /*
+ * Mask off high 16 bits when bytes written as returned by the
+ * server is greater than bytes requested by the client. OS/2
+ * servers are known to set incorrect CountHigh values.
+ */
+ if (*nbytes > count)
+ *nbytes &= 0xFFFF;
}
/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
@@ -1793,8 +1811,21 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
}
parm_data = (struct cifs_posix_lock *)
((char *)&pSMBr->hdr.Protocol + data_offset);
- if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
+ if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
pLockData->fl_type = F_UNLCK;
+ else {
+ if (parm_data->lock_type ==
+ __constant_cpu_to_le16(CIFS_RDLCK))
+ pLockData->fl_type = F_RDLCK;
+ else if (parm_data->lock_type ==
+ __constant_cpu_to_le16(CIFS_WRLCK))
+ pLockData->fl_type = F_WRLCK;
+
+ pLockData->fl_start = parm_data->start;
+ pLockData->fl_end = parm_data->start +
+ parm_data->length - 1;
+ pLockData->fl_pid = parm_data->pid;
+ }
}
plk_err_exit:
@@ -3230,8 +3261,72 @@ QInfRetry:
return rc;
}
+int
+CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
+ u16 netfid, FILE_ALL_INFO *pFindData)
+{
+ struct smb_t2_qfi_req *pSMB = NULL;
+ struct smb_t2_qfi_rsp *pSMBr = NULL;
+ int rc = 0;
+ int bytes_returned;
+ __u16 params, byte_count;
+
+QFileInfoRetry:
+ rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ params = 2 /* level */ + 2 /* fid */;
+ pSMB->t2.TotalDataCount = 0;
+ pSMB->t2.MaxParameterCount = cpu_to_le16(4);
+ /* BB find exact max data count below from sess structure BB */
+ pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
+ pSMB->t2.MaxSetupCount = 0;
+ pSMB->t2.Reserved = 0;
+ pSMB->t2.Flags = 0;
+ pSMB->t2.Timeout = 0;
+ pSMB->t2.Reserved2 = 0;
+ pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
+ Fid) - 4);
+ pSMB->t2.DataCount = 0;
+ pSMB->t2.DataOffset = 0;
+ pSMB->t2.SetupCount = 1;
+ pSMB->t2.Reserved3 = 0;
+ pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
+ byte_count = params + 1 /* pad */ ;
+ pSMB->t2.TotalParameterCount = cpu_to_le16(params);
+ pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
+ pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
+ pSMB->Pad = 0;
+ pSMB->Fid = netfid;
+ pSMB->hdr.smb_buf_length += byte_count;
+
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ if (rc) {
+ cFYI(1, ("Send error in QPathInfo = %d", rc));
+ } else { /* decode response */
+ rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+ if (rc) /* BB add auto retry on EOPNOTSUPP? */
+ rc = -EIO;
+ else if (pSMBr->ByteCount < 40)
+ rc = -EIO; /* bad smb */
+ else if (pFindData) {
+ __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+ memcpy((char *) pFindData,
+ (char *) &pSMBr->hdr.Protocol +
+ data_offset, sizeof(FILE_ALL_INFO));
+ } else
+ rc = -ENOMEM;
+ }
+ cifs_buf_release(pSMB);
+ if (rc == -EAGAIN)
+ goto QFileInfoRetry;
+ return rc;
+}
int
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3335,6 +3430,75 @@ QPathInfoRetry:
}
int
+CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
+ u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
+{
+ struct smb_t2_qfi_req *pSMB = NULL;
+ struct smb_t2_qfi_rsp *pSMBr = NULL;
+ int rc = 0;
+ int bytes_returned;
+ __u16 params, byte_count;
+
+UnixQFileInfoRetry:
+ rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ params = 2 /* level */ + 2 /* fid */;
+ pSMB->t2.TotalDataCount = 0;
+ pSMB->t2.MaxParameterCount = cpu_to_le16(4);
+ /* BB find exact max data count below from sess structure BB */
+ pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
+ pSMB->t2.MaxSetupCount = 0;
+ pSMB->t2.Reserved = 0;
+ pSMB->t2.Flags = 0;
+ pSMB->t2.Timeout = 0;
+ pSMB->t2.Reserved2 = 0;
+ pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
+ Fid) - 4);
+ pSMB->t2.DataCount = 0;
+ pSMB->t2.DataOffset = 0;
+ pSMB->t2.SetupCount = 1;
+ pSMB->t2.Reserved3 = 0;
+ pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
+ byte_count = params + 1 /* pad */ ;
+ pSMB->t2.TotalParameterCount = cpu_to_le16(params);
+ pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
+ pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
+ pSMB->Pad = 0;
+ pSMB->Fid = netfid;
+ pSMB->hdr.smb_buf_length += byte_count;
+
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ if (rc) {
+ cFYI(1, ("Send error in QPathInfo = %d", rc));
+ } else { /* decode response */
+ rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+
+ if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
+ cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n"
+ "Unix Extensions can be disabled on mount "
+ "by specifying the nosfu mount option."));
+ rc = -EIO; /* bad smb */
+ } else {
+ __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+ memcpy((char *) pFindData,
+ (char *) &pSMBr->hdr.Protocol +
+ data_offset,
+ sizeof(FILE_UNIX_BASIC_INFO));
+ }
+ }
+
+ cifs_buf_release(pSMB);
+ if (rc == -EAGAIN)
+ goto UnixQFileInfoRetry;
+
+ return rc;
+}
+
+int
CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
FILE_UNIX_BASIC_INFO *pFindData,
@@ -3886,7 +4050,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
goto parse_DFS_referrals_exit;
}
- /* collect neccessary data from referrals */
+ /* collect necessary data from referrals */
for (i = 0; i < *num_of_nodes; i++) {
char *temp;
int max_len;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 45eb6cba793..d9566bf8f91 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -23,6 +23,7 @@
#include <linux/string.h>
#include <linux/list.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/ctype.h>
#include <linux/utsname.h>
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 6ccf7262d1b..e9f7ecc2714 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -739,7 +739,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
int isValid = 1;
if (direntry->d_inode) {
- if (cifs_revalidate(direntry))
+ if (cifs_revalidate_dentry(direntry))
return 0;
} else {
cFYI(1, ("neg dentry 0x%p name = %s",
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index 87948147d7e..6f8a0e3fb25 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -23,6 +23,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/slab.h>
#include <keys/user-type.h>
#include "dns_resolve.h"
#include "cifsglob.h"
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 3d8f8a96f5a..9b11a8f56f3 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -31,6 +31,7 @@
#include <linux/task_io_accounting_ops.h>
#include <linux/delay.h>
#include <linux/mount.h>
+#include <linux/slab.h>
#include <asm/div64.h>
#include "cifsfs.h"
#include "cifspdu.h"
@@ -219,8 +220,8 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
cFYI(1, ("inode unchanged on server"));
} else {
if (file->f_path.dentry->d_inode->i_mapping) {
- /* BB no need to lock inode until after invalidate
- since namei code should already have it locked? */
+ /* BB no need to lock inode until after invalidate
+ since namei code should already have it locked? */
rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
if (rc != 0)
CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
@@ -838,8 +839,32 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
} else {
/* if rc == ERR_SHARING_VIOLATION ? */
- rc = 0; /* do not change lock type to unlock
- since range in use */
+ rc = 0;
+
+ if (lockType & LOCKING_ANDX_SHARED_LOCK) {
+ pfLock->fl_type = F_WRLCK;
+ } else {
+ rc = CIFSSMBLock(xid, tcon, netfid, length,
+ pfLock->fl_start, 0, 1,
+ lockType | LOCKING_ANDX_SHARED_LOCK,
+ 0 /* wait flag */);
+ if (rc == 0) {
+ rc = CIFSSMBLock(xid, tcon, netfid,
+ length, pfLock->fl_start, 1, 0,
+ lockType |
+ LOCKING_ANDX_SHARED_LOCK,
+ 0 /* wait flag */);
+ pfLock->fl_type = F_RDLCK;
+ if (rc != 0)
+ cERROR(1, ("Error unlocking "
+ "previously locked range %d "
+ "during test of lock", rc));
+ rc = 0;
+ } else {
+ pfLock->fl_type = F_WRLCK;
+ rc = 0;
+ }
+ }
}
FreeXid(xid);
@@ -1890,11 +1915,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct dentry *dentry = file->f_path.dentry;
int rc, xid;
xid = GetXid();
- rc = cifs_revalidate(dentry);
+ rc = cifs_revalidate_file(file);
if (rc) {
cFYI(1, ("Validation prior to mmap failed, error=%d", rc));
FreeXid(xid);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8bdbc818164..35ec1171621 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -20,6 +20,7 @@
*/
#include <linux/fs.h>
#include <linux/stat.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
#include <asm/div64.h>
#include "cifsfs.h"
@@ -77,6 +78,41 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
}
}
+/* check inode attributes against fattr. If they don't match, tag the
+ * inode for cache invalidation
+ */
+static void
+cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
+{
+ struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+
+ cFYI(1, ("%s: revalidating inode %llu", __func__, cifs_i->uniqueid));
+
+ if (inode->i_state & I_NEW) {
+ cFYI(1, ("%s: inode %llu is new", __func__, cifs_i->uniqueid));
+ return;
+ }
+
+ /* don't bother with revalidation if we have an oplock */
+ if (cifs_i->clientCanCacheRead) {
+ cFYI(1, ("%s: inode %llu is oplocked", __func__,
+ cifs_i->uniqueid));
+ return;
+ }
+
+ /* revalidate if mtime or size have changed */
+ if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
+ cifs_i->server_eof == fattr->cf_eof) {
+ cFYI(1, ("%s: inode %llu is unchanged", __func__,
+ cifs_i->uniqueid));
+ return;
+ }
+
+ cFYI(1, ("%s: invalidating inode %llu mapping", __func__,
+ cifs_i->uniqueid));
+ cifs_i->invalid_mapping = true;
+}
+
/* populate an inode with info from a cifs_fattr struct */
void
cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
@@ -85,6 +121,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
unsigned long oldtime = cifs_i->time;
+ cifs_revalidate_cache(inode, fattr);
+
inode->i_atime = fattr->cf_atime;
inode->i_mtime = fattr->cf_mtime;
inode->i_ctime = fattr->cf_ctime;
@@ -231,6 +269,31 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
}
+int cifs_get_file_info_unix(struct file *filp)
+{
+ int rc;
+ int xid;
+ FILE_UNIX_BASIC_INFO find_data;
+ struct cifs_fattr fattr;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ struct cifsTconInfo *tcon = cifs_sb->tcon;
+ struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
+
+ xid = GetXid();
+ rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
+ if (!rc) {
+ cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
+ } else if (rc == -EREMOTE) {
+ cifs_create_dfs_fattr(&fattr, inode->i_sb);
+ rc = 0;
+ }
+
+ cifs_fattr_to_inode(inode, &fattr);
+ FreeXid(xid);
+ return rc;
+}
+
int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *full_path,
struct super_block *sb, int xid)
@@ -432,6 +495,47 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
fattr->cf_gid = cifs_sb->mnt_gid;
}
+int cifs_get_file_info(struct file *filp)
+{
+ int rc;
+ int xid;
+ FILE_ALL_INFO find_data;
+ struct cifs_fattr fattr;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ struct cifsTconInfo *tcon = cifs_sb->tcon;
+ struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
+
+ xid = GetXid();
+ rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
+ if (rc == -EOPNOTSUPP || rc == -EINVAL) {
+ /*
+ * FIXME: legacy server -- fall back to path-based call?
+ * for now, just skip revalidating and mark inode for
+ * immediate reval.
+ */
+ rc = 0;
+ CIFS_I(inode)->time = 0;
+ goto cgfi_exit;
+ } else if (rc == -EREMOTE) {
+ cifs_create_dfs_fattr(&fattr, inode->i_sb);
+ rc = 0;
+ } else if (rc)
+ goto cgfi_exit;
+
+ /*
+ * don't bother with SFU junk here -- just mark inode as needing
+ * revalidation.
+ */
+ cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
+ fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
+ fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
+ cifs_fattr_to_inode(inode, &fattr);
+cgfi_exit:
+ FreeXid(xid);
+ return rc;
+}
+
int cifs_get_inode_info(struct inode **pinode,
const unsigned char *full_path, FILE_ALL_INFO *pfindData,
struct super_block *sb, int xid, const __u16 *pfid)
@@ -1389,135 +1493,103 @@ cifs_rename_exit:
return rc;
}
-int cifs_revalidate(struct dentry *direntry)
+static bool
+cifs_inode_needs_reval(struct inode *inode)
{
- int xid;
- int rc = 0, wbrc = 0;
- char *full_path;
- struct cifs_sb_info *cifs_sb;
- struct cifsInodeInfo *cifsInode;
- loff_t local_size;
- struct timespec local_mtime;
- bool invalidate_inode = false;
+ struct cifsInodeInfo *cifs_i = CIFS_I(inode);
- if (direntry->d_inode == NULL)
- return -ENOENT;
+ if (cifs_i->clientCanCacheRead)
+ return false;
- cifsInode = CIFS_I(direntry->d_inode);
+ if (!lookupCacheEnabled)
+ return true;
- if (cifsInode == NULL)
- return -ENOENT;
+ if (cifs_i->time == 0)
+ return true;
- /* no sense revalidating inode info on file that no one can write */
- if (CIFS_I(direntry->d_inode)->clientCanCacheRead)
- return rc;
+ /* FIXME: the actimeo should be tunable */
+ if (time_after_eq(jiffies, cifs_i->time + HZ))
+ return true;
+
+ return false;
+}
+
+/* check invalid_mapping flag and zap the cache if it's set */
+static void
+cifs_invalidate_mapping(struct inode *inode)
+{
+ int rc;
+ struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+
+ cifs_i->invalid_mapping = false;
+
+ /* write back any cached data */
+ if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
+ rc = filemap_write_and_wait(inode->i_mapping);
+ if (rc)
+ cifs_i->write_behind_rc = rc;
+ }
+ invalidate_remote_inode(inode);
+}
+
+int cifs_revalidate_file(struct file *filp)
+{
+ int rc = 0;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+
+ if (!cifs_inode_needs_reval(inode))
+ goto check_inval;
+
+ if (CIFS_SB(inode->i_sb)->tcon->unix_ext)
+ rc = cifs_get_file_info_unix(filp);
+ else
+ rc = cifs_get_file_info(filp);
+
+check_inval:
+ if (CIFS_I(inode)->invalid_mapping)
+ cifs_invalidate_mapping(inode);
+
+ return rc;
+}
+
+/* revalidate a dentry's inode attributes */
+int cifs_revalidate_dentry(struct dentry *dentry)
+{
+ int xid;
+ int rc = 0;
+ char *full_path = NULL;
+ struct inode *inode = dentry->d_inode;
+ struct super_block *sb = dentry->d_sb;
+
+ if (inode == NULL)
+ return -ENOENT;
xid = GetXid();
- cifs_sb = CIFS_SB(direntry->d_sb);
+ if (!cifs_inode_needs_reval(inode))
+ goto check_inval;
/* can not safely grab the rename sem here if rename calls revalidate
since that would deadlock */
- full_path = build_path_from_dentry(direntry);
+ full_path = build_path_from_dentry(dentry);
if (full_path == NULL) {
rc = -ENOMEM;
- FreeXid(xid);
- return rc;
- }
- cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
- "jiffies %ld", full_path, direntry->d_inode,
- direntry->d_inode->i_count.counter, direntry,
- direntry->d_time, jiffies));
-
- if (cifsInode->time == 0) {
- /* was set to zero previously to force revalidate */
- } else if (time_before(jiffies, cifsInode->time + HZ) &&
- lookupCacheEnabled) {
- if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
- (direntry->d_inode->i_nlink == 1)) {
- kfree(full_path);
- FreeXid(xid);
- return rc;
- } else {
- cFYI(1, ("Have to revalidate file due to hardlinks"));
- }
- }
-
- /* save mtime and size */
- local_mtime = direntry->d_inode->i_mtime;
- local_size = direntry->d_inode->i_size;
-
- if (cifs_sb->tcon->unix_ext) {
- rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
- direntry->d_sb, xid);
- if (rc) {
- cFYI(1, ("error on getting revalidate info %d", rc));
-/* if (rc != -ENOENT)
- rc = 0; */ /* BB should we cache info on
- certain errors? */
- }
- } else {
- rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
- direntry->d_sb, xid, NULL);
- if (rc) {
- cFYI(1, ("error on getting revalidate info %d", rc));
-/* if (rc != -ENOENT)
- rc = 0; */ /* BB should we cache info on
- certain errors? */
- }
+ goto check_inval;
}
- /* should we remap certain errors, access denied?, to zero */
- /* if not oplocked, we invalidate inode pages if mtime or file size
- had changed on server */
+ cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
+ "jiffies %ld", full_path, inode, inode->i_count.counter,
+ dentry, dentry->d_time, jiffies));
- if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
- (local_size == direntry->d_inode->i_size)) {
- cFYI(1, ("cifs_revalidate - inode unchanged"));
- } else {
- /* file may have changed on server */
- if (cifsInode->clientCanCacheRead) {
- /* no need to invalidate inode pages since we were the
- only ones who could have modified the file and the
- server copy is staler than ours */
- } else {
- invalidate_inode = true;
- }
- }
+ if (CIFS_SB(sb)->tcon->unix_ext)
+ rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
+ else
+ rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
+ xid, NULL);
- /* can not grab this sem since kernel filesys locking documentation
- indicates i_mutex may be taken by the kernel on lookup and rename
- which could deadlock if we grab the i_mutex here as well */
-/* mutex_lock(&direntry->d_inode->i_mutex);*/
- /* need to write out dirty pages here */
- if (direntry->d_inode->i_mapping) {
- /* do we need to lock inode until after invalidate completes
- below? */
- wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
- if (wbrc)
- CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
- }
- if (invalidate_inode) {
- /* shrink_dcache not necessary now that cifs dentry ops
- are exported for negative dentries */
-/* if (S_ISDIR(direntry->d_inode->i_mode))
- shrink_dcache_parent(direntry); */
- if (S_ISREG(direntry->d_inode->i_mode)) {
- if (direntry->d_inode->i_mapping) {
- wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
- if (wbrc)
- CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
- }
- /* may eventually have to do this for open files too */
- if (list_empty(&(cifsInode->openFileList))) {
- /* changed on server - flush read ahead pages */
- cFYI(1, ("Invalidating read ahead data on "
- "closed file"));
- invalidate_remote_inode(direntry->d_inode);
- }
- }
- }
-/* mutex_unlock(&direntry->d_inode->i_mutex); */
+check_inval:
+ if (CIFS_I(inode)->invalid_mapping)
+ cifs_invalidate_mapping(inode);
kfree(full_path);
FreeXid(xid);
@@ -1527,7 +1599,7 @@ int cifs_revalidate(struct dentry *direntry)
int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
- int err = cifs_revalidate(dentry);
+ int err = cifs_revalidate_dentry(dentry);
if (!err) {
generic_fillattr(dentry->d_inode, stat);
stat->blksize = CIFS_MAX_MSGSIZE;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index fc1e0487eae..c1a9d4236a8 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -20,6 +20,7 @@
*/
#include <linux/fs.h>
#include <linux/stat.h>
+#include <linux/slab.h>
#include <linux/namei.h>
#include "cifsfs.h"
#include "cifspdu.h"
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index c343b14ba2d..18e0bc1fb59 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -22,6 +22,7 @@
*/
#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <linux/stat.h>
#include "cifspdu.h"
#include "cifsglob.h"
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index aaa9c1c5a5b..7c3fd7463f4 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -29,6 +29,7 @@
#include "ntlmssp.h"
#include "nterr.h"
#include <linux/utsname.h>
+#include <linux/slab.h>
#include "cifs_spnego.h"
extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 93fb09a99c6..192ea51af20 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -24,6 +24,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 07b8e71544e..ad081fe7eb1 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -22,6 +22,7 @@
#include <linux/fs.h>
#include <linux/list.h>
+#include <linux/gfp.h>
#include <linux/wait.h>
#include <linux/net.h>
#include <linux/delay.h>
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 3e2ef0de120..f555ce077d4 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/posix_acl_xattr.h>
+#include <linux/slab.h>
#include "cifsfs.h"
#include "cifspdu.h"
#include "cifsglob.h"
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 4bb9d0a5dec..ccd98b0f2b0 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/errno.h>
diff --git a/fs/coda/file.c b/fs/coda/file.c
index ffd42815fda..4c813f2cdc5 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -17,6 +17,7 @@
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/coda.h>
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 830f51abb97..d97f9935a02 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -18,6 +18,7 @@
#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/vfs.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -166,6 +167,10 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
return -EBUSY;
}
+ error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY);
+ if (error)
+ goto bdi_err;
+
vc->vc_sb = sb;
sb->s_fs_info = vc;
@@ -174,6 +179,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
sb->s_blocksize_bits = 12;
sb->s_magic = CODA_SUPER_MAGIC;
sb->s_op = &coda_super_operations;
+ sb->s_bdi = &vc->bdi;
/* get root fid from Venus: this needs the root inode */
error = venus_rootfid(sb, &fid);
@@ -199,6 +205,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
return 0;
error:
+ bdi_destroy(&vc->bdi);
+ bdi_err:
if (root)
iput(root);
if (vc)
@@ -209,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
static void coda_put_super(struct super_block *sb)
{
+ bdi_destroy(&coda_vcp(sb)->bdi);
coda_vcp(sb)->vc_sb = NULL;
sb->s_fs_info = NULL;
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index c274d949179..f09c5ed76f6 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -26,6 +26,7 @@
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/vfs.h>
diff --git a/fs/compat.c b/fs/compat.c
index 00d90c2e66f..4b6ed03cc47 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -49,6 +49,7 @@
#include <linux/mm.h>
#include <linux/eventpoll.h>
#include <linux/fs_struct.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -1795,6 +1796,24 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
return ret;
}
+struct compat_sel_arg_struct {
+ compat_ulong_t n;
+ compat_uptr_t inp;
+ compat_uptr_t outp;
+ compat_uptr_t exp;
+ compat_uptr_t tvp;
+};
+
+asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg)
+{
+ struct compat_sel_arg_struct a;
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ return -EFAULT;
+ return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
+ compat_ptr(a.exp), compat_ptr(a.tvp));
+}
+
#ifdef HAVE_SET_RESTORE_SIGMASK
static long do_compat_pselect(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c
index 0adced2f296..112e45a17e9 100644
--- a/fs/compat_binfmt_elf.c
+++ b/fs/compat_binfmt_elf.c
@@ -28,10 +28,12 @@
#undef elfhdr
#undef elf_phdr
+#undef elf_shdr
#undef elf_note
#undef elf_addr_t
#define elfhdr elf32_hdr
#define elf_phdr elf32_phdr
+#define elf_shdr elf32_shdr
#define elf_note elf32_note
#define elf_addr_t Elf32_Addr
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 0ca9ec4a79c..641640dc7ae 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -23,7 +23,6 @@
#include <linux/ioctl.h>
#include <linux/if.h>
#include <linux/if_bridge.h>
-#include <linux/slab.h>
#include <linux/raid/md_u.h>
#include <linux/kd.h>
#include <linux/route.h>
@@ -60,6 +59,7 @@
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/atalk.h>
+#include <linux/gfp.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h>
@@ -102,7 +102,6 @@
#include <linux/nbd.h>
#include <linux/random.h>
#include <linux/filter.h>
-#include <linux/pktcdvd.h>
#include <linux/hiddev.h>
@@ -545,7 +544,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, void __user *argp)
kcmd = MTIOCPOS;
karg = &pos;
break;
- case MTIOCGET32:
+ default: /* MTIOCGET32 */
kcmd = MTIOCGET;
karg = &get;
break;
@@ -663,7 +662,7 @@ static int raw_ioctl(unsigned fd, unsigned cmd,
switch (cmd) {
case RAW_SETBIND:
- case RAW_GETBIND: {
+ default: { /* RAW_GETBIND */
struct raw_config_request req;
mm_segment_t oldfs = get_fs();
@@ -1126,8 +1125,6 @@ COMPATIBLE_IOCTL(PPGETMODE)
COMPATIBLE_IOCTL(PPGETPHASE)
COMPATIBLE_IOCTL(PPGETFLAGS)
COMPATIBLE_IOCTL(PPSETFLAGS)
-/* pktcdvd */
-COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
/* Big A */
/* sparc only */
/* Big Q for sound/OSS */
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index a2f746066c5..c8af2d91174 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -34,6 +34,7 @@
#include <linux/capability.h>
#include <linux/sched.h>
#include <linux/lockdep.h>
+#include <linux/slab.h>
#include <linux/configfs.h>
#include "configfs_internal.h"
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index 8421cea7d8c..8c8d64230c2 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -29,6 +29,7 @@
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/configfs.h>
#include "configfs_internal.h"
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index 32a5f46b115..0f3eb41d920 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -27,6 +27,7 @@
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#include <linux/configfs.h>
#include "configfs_internal.h"
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 049d6c36da0..30a87b3dbca 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -27,6 +27,7 @@
#include <linux/fsnotify.h>
#include <linux/string.h>
#include <linux/magic.h>
+#include <linux/slab.h>
static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 8882ecc0f1b..0120247b41c 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -15,6 +15,7 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/tty.h>
#include <linux/mutex.h>
diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index 0df24385081..b54bca03d92 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/configfs.h>
+#include <linux/slab.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <net/ipv6.h>
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c
index 29d6139c35f..c6cf2515874 100644
--- a/fs/dlm/debug_fs.c
+++ b/fs/dlm/debug_fs.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include "dlm_internal.h"
#include "lock.h"
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 46ffd3eeaaf..17903b49129 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -56,6 +56,7 @@
L: receive_xxxx_reply() <- R: send_xxxx_reply()
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include "dlm_internal.h"
#include <linux/dlm_device.h>
#include "memory.h"
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 26a8bd40400..f994a7dfda8 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -148,7 +148,7 @@ static void lockspace_kobj_release(struct kobject *k)
kfree(ls);
}
-static struct sysfs_ops dlm_attr_ops = {
+static const struct sysfs_ops dlm_attr_ops = {
.show = dlm_attr_show,
.store = dlm_attr_store,
};
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 52cab160893..c0d35c62052 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -51,6 +51,7 @@
#include <linux/file.h>
#include <linux/mutex.h>
#include <linux/sctp.h>
+#include <linux/slab.h>
#include <net/sctp/user.h>
#include <net/ipv6.h>
diff --git a/fs/dlm/member.c b/fs/dlm/member.c
index 84f70bfb0ba..b12532e553f 100644
--- a/fs/dlm/member.c
+++ b/fs/dlm/member.c
@@ -312,7 +312,7 @@ int dlm_ls_stop(struct dlm_ls *ls)
/*
* This in_recovery lock does two things:
* 1) Keeps this function from returning until all threads are out
- * of locking routines and locking is truely stopped.
+ * of locking routines and locking is truly stopped.
* 2) Keeps any new requests from being processed until it's unlocked
* when recovery is complete.
*/
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c
index 052095cd592..2c6ad518100 100644
--- a/fs/dlm/netlink.c
+++ b/fs/dlm/netlink.c
@@ -9,6 +9,7 @@
#include <net/genetlink.h>
#include <linux/dlm.h>
#include <linux/dlm_netlink.h>
+#include <linux/gfp.h>
#include "dlm_internal.h"
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
index b5f89aef3b2..d45c02db694 100644
--- a/fs/dlm/plock.c
+++ b/fs/dlm/plock.c
@@ -11,6 +11,7 @@
#include <linux/poll.h>
#include <linux/dlm.h>
#include <linux/dlm_plock.h>
+#include <linux/slab.h>
#include "dlm_internal.h"
#include "lockspace.h"
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index a4bfd31ac45..8b6e73c4743 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -17,6 +17,7 @@
#include <linux/spinlock.h>
#include <linux/dlm.h>
#include <linux/dlm_device.h>
+#include <linux/slab.h>
#include "dlm_internal.h"
#include "lockspace.h"
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 7cb0a59f4b9..1cc087635a5 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -33,6 +33,7 @@
#include <linux/crypto.h>
#include <linux/file.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "ecryptfs_kernel.h"
@@ -381,8 +382,8 @@ out:
static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
struct ecryptfs_crypt_stat *crypt_stat)
{
- (*offset) = (crypt_stat->num_header_bytes_at_front
- + (crypt_stat->extent_size * extent_num));
+ (*offset) = ecryptfs_lower_header_size(crypt_stat)
+ + (crypt_stat->extent_size * extent_num);
}
/**
@@ -834,13 +835,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
set_extent_mask_and_shift(crypt_stat);
crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
- crypt_stat->num_header_bytes_at_front = 0;
+ crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
else {
if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
- crypt_stat->num_header_bytes_at_front =
+ crypt_stat->metadata_size =
ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
else
- crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE;
+ crypt_stat->metadata_size = PAGE_CACHE_SIZE;
}
}
@@ -1107,9 +1108,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written)
(*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
}
-static void
-write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
- size_t *written)
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+ struct ecryptfs_crypt_stat *crypt_stat,
+ size_t *written)
{
u32 flags = 0;
int i;
@@ -1237,8 +1238,7 @@ ecryptfs_write_header_metadata(char *virt,
header_extent_size = (u32)crypt_stat->extent_size;
num_header_extents_at_front =
- (u16)(crypt_stat->num_header_bytes_at_front
- / crypt_stat->extent_size);
+ (u16)(crypt_stat->metadata_size / crypt_stat->extent_size);
put_unaligned_be32(header_extent_size, virt);
virt += 4;
put_unaligned_be16(num_header_extents_at_front, virt);
@@ -1291,7 +1291,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
offset = ECRYPTFS_FILE_SIZE_BYTES;
write_ecryptfs_marker((page_virt + offset), &written);
offset += written;
- write_ecryptfs_flags((page_virt + offset), crypt_stat, &written);
+ ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat,
+ &written);
offset += written;
ecryptfs_write_header_metadata((page_virt + offset), crypt_stat,
&written);
@@ -1381,7 +1382,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
rc = -EINVAL;
goto out;
}
- virt_len = crypt_stat->num_header_bytes_at_front;
+ virt_len = crypt_stat->metadata_size;
order = get_order(virt_len);
/* Released in this function */
virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order);
@@ -1427,16 +1428,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
header_extent_size = get_unaligned_be32(virt);
virt += sizeof(__be32);
num_header_extents_at_front = get_unaligned_be16(virt);
- crypt_stat->num_header_bytes_at_front =
- (((size_t)num_header_extents_at_front
- * (size_t)header_extent_size));
+ crypt_stat->metadata_size = (((size_t)num_header_extents_at_front
+ * (size_t)header_extent_size));
(*bytes_read) = (sizeof(__be32) + sizeof(__be16));
if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
- && (crypt_stat->num_header_bytes_at_front
+ && (crypt_stat->metadata_size
< ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
rc = -EINVAL;
printk(KERN_WARNING "Invalid header size: [%zd]\n",
- crypt_stat->num_header_bytes_at_front);
+ crypt_stat->metadata_size);
}
return rc;
}
@@ -1451,8 +1451,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
*/
static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
{
- crypt_stat->num_header_bytes_at_front =
- ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
+ crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
}
/**
@@ -1606,6 +1605,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
ecryptfs_dentry,
ECRYPTFS_VALIDATE_HEADER_SIZE);
if (rc) {
+ memset(page_virt, 0, PAGE_CACHE_SIZE);
rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
if (rc) {
printk(KERN_DEBUG "Valid eCryptfs headers not found in "
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
index 8f006a0d607..906e803f7f7 100644
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -26,6 +26,7 @@
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/fs_stack.h>
+#include <linux/slab.h>
#include "ecryptfs_kernel.h"
/**
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 542f625312f..bfc2e0f78f0 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -35,6 +35,7 @@
#include <linux/scatterlist.h>
#include <linux/hash.h>
#include <linux/nsproxy.h>
+#include <linux/backing-dev.h>
/* Version verification for shared data structures w/ userspace */
#define ECRYPTFS_VERSION_MAJOR 0x00
@@ -273,7 +274,7 @@ struct ecryptfs_crypt_stat {
u32 flags;
unsigned int file_version;
size_t iv_bytes;
- size_t num_header_bytes_at_front;
+ size_t metadata_size;
size_t extent_size; /* Data extent size; default is 4096 */
size_t key_size;
size_t extent_shift;
@@ -393,6 +394,7 @@ struct ecryptfs_mount_crypt_stat {
struct ecryptfs_sb_info {
struct super_block *wsi_sb;
struct ecryptfs_mount_crypt_stat mount_crypt_stat;
+ struct backing_dev_info bdi;
};
/* file private data. */
@@ -464,6 +466,14 @@ struct ecryptfs_daemon {
extern struct mutex ecryptfs_daemon_hash_mux;
+static inline size_t
+ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat)
+{
+ if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
+ return 0;
+ return crypt_stat->metadata_size;
+}
+
static inline struct ecryptfs_file_info *
ecryptfs_file_to_private(struct file *file)
{
@@ -651,6 +661,9 @@ int ecryptfs_decrypt_page(struct page *page);
int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+ struct ecryptfs_crypt_stat *crypt_stat,
+ size_t *written);
int ecryptfs_read_and_validate_header_region(char *data,
struct inode *ecryptfs_inode);
int ecryptfs_read_and_validate_xattr_region(char *page_virt,
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 678172b61be..e7440a6f5eb 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -25,6 +25,7 @@
#include <linux/file.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/security.h>
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 4a430ab4115..e2d4418affa 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -31,6 +31,7 @@
#include <linux/mount.h>
#include <linux/crypto.h>
#include <linux/fs_stack.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "ecryptfs_kernel.h"
@@ -323,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
rc = ecryptfs_read_and_validate_header_region(page_virt,
ecryptfs_dentry->d_inode);
if (rc) {
+ memset(page_virt, 0, PAGE_CACHE_SIZE);
rc = ecryptfs_read_and_validate_xattr_region(page_virt,
ecryptfs_dentry);
if (rc) {
@@ -335,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
ecryptfs_dentry->d_sb)->mount_crypt_stat;
if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
- file_size = (crypt_stat->num_header_bytes_at_front
+ file_size = (crypt_stat->metadata_size
+ i_size_read(lower_dentry->d_inode));
else
file_size = i_size_read(lower_dentry->d_inode);
@@ -387,9 +389,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
if (IS_ERR(lower_dentry)) {
rc = PTR_ERR(lower_dentry);
- printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
- "lower_dentry = [%s]\n", __func__, rc,
- ecryptfs_dentry->d_name.name);
+ ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+ "[%d] on lower_dentry = [%s]\n", __func__, rc,
+ encrypted_and_encoded_name);
goto out_d_drop;
}
if (lower_dentry->d_inode)
@@ -416,9 +418,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
if (IS_ERR(lower_dentry)) {
rc = PTR_ERR(lower_dentry);
- printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
- "lower_dentry = [%s]\n", __func__, rc,
- encrypted_and_encoded_name);
+ ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+ "[%d] on lower_dentry = [%s]\n", __func__, rc,
+ encrypted_and_encoded_name);
goto out_d_drop;
}
lookup_and_interpose:
@@ -455,8 +457,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
if (rc)
goto out_lock;
- fsstack_copy_attr_times(dir, lower_new_dentry->d_inode);
- fsstack_copy_inode_size(dir, lower_new_dentry->d_inode);
+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
+ fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
old_dentry->d_inode->i_nlink =
ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
i_size_write(new_dentry->d_inode, file_size_save);
@@ -647,38 +649,17 @@ out_lock:
return rc;
}
-static int
-ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
+ size_t *bufsiz)
{
+ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
char *lower_buf;
- size_t lower_bufsiz;
- struct dentry *lower_dentry;
- struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
- char *plaintext_name;
- size_t plaintext_name_size;
+ size_t lower_bufsiz = PATH_MAX;
mm_segment_t old_fs;
int rc;
- lower_dentry = ecryptfs_dentry_to_lower(dentry);
- if (!lower_dentry->d_inode->i_op->readlink) {
- rc = -EINVAL;
- goto out;
- }
- mount_crypt_stat = &ecryptfs_superblock_to_private(
- dentry->d_sb)->mount_crypt_stat;
- /*
- * If the lower filename is encrypted, it will result in a significantly
- * longer name. If needed, truncate the name after decode and decrypt.
- */
- if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
- lower_bufsiz = PATH_MAX;
- else
- lower_bufsiz = bufsiz;
- /* Released in this function */
lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
- if (lower_buf == NULL) {
- printk(KERN_ERR "%s: Out of memory whilst attempting to "
- "kmalloc [%zd] bytes\n", __func__, lower_bufsiz);
+ if (!lower_buf) {
rc = -ENOMEM;
goto out;
}
@@ -688,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
(char __user *)lower_buf,
lower_bufsiz);
set_fs(old_fs);
- if (rc >= 0) {
- rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
- &plaintext_name_size,
- dentry, lower_buf,
- rc);
- if (rc) {
- printk(KERN_ERR "%s: Error attempting to decode and "
- "decrypt filename; rc = [%d]\n", __func__,
- rc);
- goto out_free_lower_buf;
- }
- /* Check for bufsiz <= 0 done in sys_readlinkat() */
- rc = copy_to_user(buf, plaintext_name,
- min((size_t) bufsiz, plaintext_name_size));
- if (rc)
- rc = -EFAULT;
- else
- rc = plaintext_name_size;
- kfree(plaintext_name);
- fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
- }
-out_free_lower_buf:
+ if (rc < 0)
+ goto out;
+ lower_bufsiz = rc;
+ rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
+ lower_buf, lower_bufsiz);
+out:
kfree(lower_buf);
+ return rc;
+}
+
+static int
+ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+{
+ char *kbuf;
+ size_t kbufsiz, copied;
+ int rc;
+
+ rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz);
+ if (rc)
+ goto out;
+ copied = min_t(size_t, bufsiz, kbufsiz);
+ rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
+ kfree(kbuf);
+ fsstack_copy_attr_atime(dentry->d_inode,
+ ecryptfs_dentry_to_lower(dentry)->d_inode);
out:
return rc;
}
@@ -768,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
{
loff_t lower_size;
- lower_size = crypt_stat->num_header_bytes_at_front;
+ lower_size = ecryptfs_lower_header_size(crypt_stat);
if (upper_size != 0) {
loff_t num_extents;
@@ -1015,6 +998,28 @@ out:
return rc;
}
+int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+ int rc = 0;
+
+ mount_crypt_stat = &ecryptfs_superblock_to_private(
+ dentry->d_sb)->mount_crypt_stat;
+ generic_fillattr(dentry->d_inode, stat);
+ if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
+ char *target;
+ size_t targetsiz;
+
+ rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz);
+ if (!rc) {
+ kfree(target);
+ stat->size = targetsiz;
+ }
+ }
+ return rc;
+}
+
int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
@@ -1039,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
lower_dentry = ecryptfs_dentry_to_lower(dentry);
if (!lower_dentry->d_inode->i_op->setxattr) {
- rc = -ENOSYS;
+ rc = -EOPNOTSUPP;
goto out;
}
mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1057,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
int rc = 0;
if (!lower_dentry->d_inode->i_op->getxattr) {
- rc = -ENOSYS;
+ rc = -EOPNOTSUPP;
goto out;
}
mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1084,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
lower_dentry = ecryptfs_dentry_to_lower(dentry);
if (!lower_dentry->d_inode->i_op->listxattr) {
- rc = -ENOSYS;
+ rc = -EOPNOTSUPP;
goto out;
}
mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1101,7 +1106,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
lower_dentry = ecryptfs_dentry_to_lower(dentry);
if (!lower_dentry->d_inode->i_op->removexattr) {
- rc = -ENOSYS;
+ rc = -EOPNOTSUPP;
goto out;
}
mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1132,6 +1137,7 @@ const struct inode_operations ecryptfs_symlink_iops = {
.put_link = ecryptfs_put_link,
.permission = ecryptfs_permission,
.setattr = ecryptfs_setattr,
+ .getattr = ecryptfs_getattr_link,
.setxattr = ecryptfs_setxattr,
.getxattr = ecryptfs_getxattr,
.listxattr = ecryptfs_listxattr,
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index a0a7847567e..89c5476506e 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -32,6 +32,7 @@
#include <linux/random.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include "ecryptfs_kernel.h"
/**
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index e14cf7e588d..d8c3a373aaf 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -22,6 +22,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/mount.h>
#include "ecryptfs_kernel.h"
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index ea2f92101df..760983d0f25 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -35,6 +35,7 @@
#include <linux/key.h>
#include <linux/parser.h>
#include <linux/fs_stack.h>
+#include <linux/slab.h>
#include "ecryptfs_kernel.h"
/**
@@ -496,17 +497,25 @@ struct kmem_cache *ecryptfs_sb_info_cache;
static int
ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent)
{
+ struct ecryptfs_sb_info *esi;
int rc = 0;
/* Released in ecryptfs_put_super() */
ecryptfs_set_superblock_private(sb,
kmem_cache_zalloc(ecryptfs_sb_info_cache,
GFP_KERNEL));
- if (!ecryptfs_superblock_to_private(sb)) {
+ esi = ecryptfs_superblock_to_private(sb);
+ if (!esi) {
ecryptfs_printk(KERN_WARNING, "Out of memory\n");
rc = -ENOMEM;
goto out;
}
+
+ rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY);
+ if (rc)
+ goto out;
+
+ sb->s_bdi = &esi->bdi;
sb->s_op = &ecryptfs_sops;
/* Released through deactivate_super(sb) from get_sb_nodev */
sb->s_root = d_alloc(NULL, &(const struct qstr) {
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index f1c17e87c5f..2d8dbce9d48 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -20,6 +20,7 @@
* 02111-1307, USA.
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/user_namespace.h>
#include <linux/nsproxy.h>
#include "ecryptfs_kernel.h"
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
index 4ec8f61ccf5..3745f612bcd 100644
--- a/fs/ecryptfs/miscdev.c
+++ b/fs/ecryptfs/miscdev.c
@@ -24,6 +24,7 @@
#include <linux/random.h>
#include <linux/miscdevice.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/module.h>
#include "ecryptfs_kernel.h"
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index df4ce99d059..2ee9a3a7b68 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -32,6 +32,7 @@
#include <linux/file.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "ecryptfs_kernel.h"
@@ -82,6 +83,19 @@ out:
return rc;
}
+static void strip_xattr_flag(char *page_virt,
+ struct ecryptfs_crypt_stat *crypt_stat)
+{
+ if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
+ size_t written;
+
+ crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR;
+ ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat,
+ &written);
+ crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
+ }
+}
+
/**
* Header Extent:
* Octets 0-7: Unencrypted file size (big-endian)
@@ -97,19 +111,6 @@ out:
* (big-endian)
* Octet 26: Begin RFC 2440 authentication token packet set
*/
-static void set_header_info(char *page_virt,
- struct ecryptfs_crypt_stat *crypt_stat)
-{
- size_t written;
- size_t save_num_header_bytes_at_front =
- crypt_stat->num_header_bytes_at_front;
-
- crypt_stat->num_header_bytes_at_front =
- ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
- ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
- crypt_stat->num_header_bytes_at_front =
- save_num_header_bytes_at_front;
-}
/**
* ecryptfs_copy_up_encrypted_with_header
@@ -135,8 +136,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
* num_extents_per_page)
+ extent_num_in_page);
size_t num_header_extents_at_front =
- (crypt_stat->num_header_bytes_at_front
- / crypt_stat->extent_size);
+ (crypt_stat->metadata_size / crypt_stat->extent_size);
if (view_extent_num < num_header_extents_at_front) {
/* This is a header extent */
@@ -146,9 +146,14 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
memset(page_virt, 0, PAGE_CACHE_SIZE);
/* TODO: Support more than one header extent */
if (view_extent_num == 0) {
+ size_t written;
+
rc = ecryptfs_read_xattr_region(
page_virt, page->mapping->host);
- set_header_info(page_virt, crypt_stat);
+ strip_xattr_flag(page_virt + 16, crypt_stat);
+ ecryptfs_write_header_metadata(page_virt + 20,
+ crypt_stat,
+ &written);
}
kunmap_atomic(page_virt, KM_USER0);
flush_dcache_page(page);
@@ -161,7 +166,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
/* This is an encrypted data extent */
loff_t lower_offset =
((view_extent_num * crypt_stat->extent_size)
- - crypt_stat->num_header_bytes_at_front);
+ - crypt_stat->metadata_size);
rc = ecryptfs_read_lower_page_segment(
page, (lower_offset >> PAGE_CACHE_SHIFT),
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index b15a43a80ab..0c0ae491d23 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -26,6 +26,7 @@
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/key.h>
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/file.h>
@@ -85,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode)
if (lower_dentry->d_inode) {
fput(inode_info->lower_file);
inode_info->lower_file = NULL;
- d_drop(lower_dentry);
}
}
ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
@@ -122,6 +122,7 @@ static void ecryptfs_put_super(struct super_block *sb)
lock_kernel();
ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
+ bdi_destroy(&sb_info->bdi);
kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
ecryptfs_set_superblock_private(sb, NULL);
diff --git a/fs/eventfd.c b/fs/eventfd.c
index 7758cc382ef..6bd3f76fdf8 100644
--- a/fs/eventfd.c
+++ b/fs/eventfd.c
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/anon_inodes.h>
diff --git a/fs/exec.c b/fs/exec.c
index cce6bbdbdbb..49cdaa19e5b 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -195,7 +195,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
* to work from.
*/
rlim = current->signal->rlim;
- if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
+ if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
put_page(page);
return NULL;
}
@@ -246,6 +246,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
vma->vm_start = vma->vm_end - PAGE_SIZE;
vma->vm_flags = VM_STACK_FLAGS;
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ INIT_LIST_HEAD(&vma->anon_vma_chain);
err = insert_vm_struct(mm, vma);
if (err)
goto err;
@@ -516,7 +517,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
/*
* cover the whole range: [new_start, old_end)
*/
- vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL);
+ if (vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL))
+ return -ENOMEM;
/*
* move the page tables downwards, on failure we rely on
@@ -547,15 +549,13 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
tlb_finish_mmu(tlb, new_end, old_end);
/*
- * shrink the vma to just the new range.
+ * Shrink the vma to just the new range. Always succeeds.
*/
vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL);
return 0;
}
-#define EXTRA_STACK_VM_PAGES 20 /* random */
-
/*
* Finalizes the stack vm_area_struct. The flags and permissions are updated,
* the stack is optionally relocated, and some extra space is added.
@@ -577,7 +577,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
#ifdef CONFIG_STACK_GROWSUP
/* Limit stack size to 1GB */
- stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max;
+ stack_base = rlimit_max(RLIMIT_STACK);
if (stack_base > (1 << 30))
stack_base = 1 << 30;
@@ -630,7 +630,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
goto out_unlock;
}
- stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE;
+ stack_expand = 131072UL; /* randomly 32*4k (or 2*64k) pages */
stack_size = vma->vm_end - vma->vm_start;
/*
* Align this down to a page boundary as expand_stack
@@ -718,6 +718,7 @@ static int exec_mmap(struct mm_struct *mm)
/* Notify parent that we're no longer interested in the old VM */
tsk = current;
old_mm = current->mm;
+ sync_mm_rss(tsk, old_mm);
mm_release(tsk, old_mm);
if (old_mm) {
@@ -1532,7 +1533,7 @@ static int format_corename(char *corename, long signr)
/* core limit size */
case 'c':
rc = snprintf(out_ptr, out_end - out_ptr,
- "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur);
+ "%lu", rlimit(RLIMIT_CORE));
if (rc > out_end - out_ptr)
goto out;
out_ptr += rc;
@@ -1560,12 +1561,13 @@ out:
return ispipe;
}
-static int zap_process(struct task_struct *start)
+static int zap_process(struct task_struct *start, int exit_code)
{
struct task_struct *t;
int nr = 0;
start->signal->flags = SIGNAL_GROUP_EXIT;
+ start->signal->group_exit_code = exit_code;
start->signal->group_stop_count = 0;
t = start;
@@ -1590,8 +1592,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
spin_lock_irq(&tsk->sighand->siglock);
if (!signal_group_exit(tsk->signal)) {
mm->core_state = core_state;
- tsk->signal->group_exit_code = exit_code;
- nr = zap_process(tsk);
+ nr = zap_process(tsk, exit_code);
}
spin_unlock_irq(&tsk->sighand->siglock);
if (unlikely(nr < 0))
@@ -1640,7 +1641,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
if (p->mm) {
if (unlikely(p->mm == mm)) {
lock_task_sighand(p, &flags);
- nr += zap_process(p);
+ nr += zap_process(p, exit_code);
unlock_task_sighand(p, &flags);
}
break;
@@ -1747,14 +1748,19 @@ void set_dumpable(struct mm_struct *mm, int value)
}
}
-int get_dumpable(struct mm_struct *mm)
+static int __get_dumpable(unsigned long mm_flags)
{
int ret;
- ret = mm->flags & 0x3;
+ ret = mm_flags & MMF_DUMPABLE_MASK;
return (ret >= 2) ? 2 : ret;
}
+int get_dumpable(struct mm_struct *mm)
+{
+ return __get_dumpable(mm->flags);
+}
+
static void wait_for_dump_helpers(struct file *file)
{
struct pipe_inode_info *pipe;
@@ -1797,7 +1803,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
struct coredump_params cprm = {
.signr = signr,
.regs = regs,
- .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur,
+ .limit = rlimit(RLIMIT_CORE),
+ /*
+ * We must use the same mm->flags while dumping core to avoid
+ * inconsistency of bit flags, since this flag is not protected
+ * by any locks.
+ */
+ .mm_flags = mm->flags,
};
audit_core_dumps(signr);
@@ -1816,7 +1828,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
/*
* If another thread got here first, or we are not dumpable, bail out.
*/
- if (mm->core_state || !get_dumpable(mm)) {
+ if (mm->core_state || !__get_dumpable(cprm.mm_flags)) {
up_write(&mm->mmap_sem);
put_cred(cred);
goto fail;
@@ -1827,7 +1839,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
* process nor do we know its entire history. We only know it
* was tainted so we dump it as root in mode 2.
*/
- if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
+ if (__get_dumpable(cprm.mm_flags) == 2) {
+ /* Setuid core dump mode */
flag = O_EXCL; /* Stop rewrite attacks */
cred->fsuid = 0; /* Dump root private */
}
@@ -1923,8 +1936,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
/*
* Dont allow local users get cute and trick others to coredump
* into their pre-created files:
+ * Note, this is not relevant for pipes
*/
- if (inode->i_uid != current_fsuid())
+ if (!ispipe && (inode->i_uid != current_fsuid()))
goto close_fail;
if (!cprm.file->f_op)
goto close_fail;
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 59b8bf2825c..22721b2fd89 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -35,6 +35,7 @@
#include <linux/fs.h>
#include <linux/time.h>
+#include <linux/backing-dev.h>
#include "common.h"
/* FIXME: Remove once pnfs hits mainline
@@ -84,6 +85,7 @@ struct exofs_sb_info {
u32 s_next_generation; /* next gen # to use */
atomic_t s_curr_pending; /* number of pending commands */
uint8_t s_cred[OSD_CAP_LEN]; /* credential for the fscb */
+ struct backing_dev_info bdi; /* register our bdi with VFS */
struct pnfs_osd_data_map data_map; /* Default raid to use
* FIXME: Needed ?
@@ -261,7 +263,7 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
struct page **pagep, void **fsdata);
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 *, int);
+extern int exofs_write_inode(struct inode *, struct writeback_control *wbc);
extern void exofs_delete_inode(struct inode *);
/* dir.c: */
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index 5514f3c2c2f..76d2a79ef93 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -31,6 +31,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/slab.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h>
#include <scsi/scsi_device.h>
@@ -1280,9 +1281,9 @@ out:
return ret;
}
-int exofs_write_inode(struct inode *inode, int wait)
+int exofs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
- return exofs_update_inode(inode, wait);
+ return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
}
/*
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index 5293bc411d1..4337cad7777 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -22,6 +22,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/slab.h>
#include <scsi/scsi_device.h>
#include <asm/div64.h>
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 6cf5e4e84d6..03149b9a517 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -37,6 +37,7 @@
#include <linux/vfs.h>
#include <linux/random.h>
#include <linux/exportfs.h>
+#include <linux/slab.h>
#include "exofs.h"
@@ -301,6 +302,7 @@ static void exofs_put_super(struct super_block *sb)
_exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0],
sbi->layout.s_pid);
+ bdi_destroy(&sbi->bdi);
exofs_free_sbi(sbi);
sb->s_fs_info = NULL;
}
@@ -545,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
if (!sbi)
return -ENOMEM;
+ ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY);
+ if (ret)
+ goto free_bdi;
+
/* use mount options to fill superblock */
od = osduld_path_lookup(opts->dev_name);
if (IS_ERR(od)) {
@@ -611,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
}
/* set up operation vectors */
+ sb->s_bdi = &sbi->bdi;
sb->s_fs_info = sbi;
sb->s_op = &exofs_sops;
sb->s_export_op = &exofs_export_ops;
@@ -642,6 +649,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
return 0;
free_sbi:
+ bdi_destroy(&sbi->bdi);
+free_bdi:
EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
opts->dev_name, sbi->layout.s_pid, ret);
exofs_free_sbi(sbi);
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 7f8d2e5a7ea..3cf038c055d 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -13,6 +13,7 @@
#include "ext2.h"
#include <linux/quotaops.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/buffer_head.h>
#include <linux/capability.h>
@@ -570,7 +571,7 @@ do_more:
error_return:
brelse(bitmap_bh);
release_blocks(sb, freed);
- vfs_dq_free_block(inode, freed);
+ dquot_free_block(inode, freed);
}
/**
@@ -1236,6 +1237,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
unsigned short windowsz = 0;
unsigned long ngroups;
unsigned long num = *count;
+ int ret;
*errp = -ENOSPC;
sb = inode->i_sb;
@@ -1247,8 +1249,9 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
/*
* Check quota for allocation of this block.
*/
- if (vfs_dq_alloc_block(inode, num)) {
- *errp = -EDQUOT;
+ ret = dquot_alloc_block(inode, num);
+ if (ret) {
+ *errp = ret;
return 0;
}
@@ -1409,7 +1412,7 @@ allocated:
*errp = 0;
brelse(bitmap_bh);
- vfs_dq_free_block(inode, *count-num);
+ dquot_free_block(inode, *count-num);
*count = num;
return ret_block;
@@ -1420,7 +1423,7 @@ out:
* Undo the block allocation
*/
if (!performed_allocation)
- vfs_dq_free_block(inode, *count);
+ dquot_free_block(inode, *count);
brelse(bitmap_bh);
return 0;
}
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 061914add3c..0b038e47ad2 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -118,7 +118,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 *, int);
+extern int ext2_write_inode (struct inode *, struct writeback_control *);
extern void ext2_delete_inode (struct inode *);
extern int ext2_sync_inode (struct inode *);
extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 586e3589d4c..5d198d0697f 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -20,6 +20,7 @@
#include <linux/time.h>
#include <linux/pagemap.h>
+#include <linux/quotaops.h>
#include "ext2.h"
#include "xattr.h"
#include "acl.h"
@@ -70,7 +71,7 @@ const struct file_operations ext2_file_operations = {
.compat_ioctl = ext2_compat_ioctl,
#endif
.mmap = generic_file_mmap,
- .open = generic_file_open,
+ .open = dquot_file_open,
.release = ext2_release_file,
.fsync = ext2_fsync,
.splice_read = generic_file_splice_read,
@@ -87,7 +88,7 @@ const struct file_operations ext2_xip_file_operations = {
.compat_ioctl = ext2_compat_ioctl,
#endif
.mmap = xip_file_mmap,
- .open = generic_file_open,
+ .open = dquot_file_open,
.release = ext2_release_file,
.fsync = ext2_fsync,
};
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 15387c9c17d..ad7d572ee8d 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -121,8 +121,8 @@ void ext2_free_inode (struct inode * inode)
if (!is_bad_inode(inode)) {
/* Quota is already initialized in iput() */
ext2_xattr_delete_inode(inode);
- vfs_dq_free_inode(inode);
- vfs_dq_drop(inode);
+ dquot_free_inode(inode);
+ dquot_drop(inode);
}
es = EXT2_SB(sb)->s_es;
@@ -586,10 +586,10 @@ got:
goto fail_drop;
}
- if (vfs_dq_alloc_inode(inode)) {
- err = -EDQUOT;
+ dquot_initialize(inode);
+ err = dquot_alloc_inode(inode);
+ if (err)
goto fail_drop;
- }
err = ext2_init_acl(inode, dir);
if (err)
@@ -605,10 +605,10 @@ got:
return inode;
fail_free_drop:
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
fail_drop:
- vfs_dq_drop(inode);
+ dquot_drop(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
unlock_new_inode(inode);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 71b032c65a0..fc13cc119aa 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -41,6 +41,8 @@ MODULE_AUTHOR("Remy Card and others");
MODULE_DESCRIPTION("Second Extended Filesystem");
MODULE_LICENSE("GPL");
+static int __ext2_write_inode(struct inode *inode, int do_sync);
+
/*
* Test whether an inode is a fast symlink.
*/
@@ -58,13 +60,15 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode)
*/
void ext2_delete_inode (struct inode * inode)
{
+ if (!is_bad_inode(inode))
+ dquot_initialize(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));
+ __ext2_write_inode(inode, inode_needs_sync(inode));
inode->i_size = 0;
if (inode->i_blocks)
@@ -1335,7 +1339,7 @@ bad_inode:
return ERR_PTR(ret);
}
-int ext2_write_inode(struct inode *inode, int do_sync)
+static int __ext2_write_inode(struct inode *inode, int do_sync)
{
struct ext2_inode_info *ei = EXT2_I(inode);
struct super_block *sb = inode->i_sb;
@@ -1440,6 +1444,11 @@ int ext2_write_inode(struct inode *inode, int do_sync)
return err;
}
+int ext2_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
+}
+
int ext2_sync_inode(struct inode *inode)
{
struct writeback_control wbc = {
@@ -1457,9 +1466,12 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
error = inode_change_ok(inode, iattr);
if (error)
return error;
+
+ if (iattr->ia_valid & ATTR_SIZE)
+ dquot_initialize(inode);
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
- error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0;
+ error = dquot_transfer(inode, iattr);
if (error)
return error;
}
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index dd7175ce560..71efb0e9a3f 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -31,6 +31,7 @@
*/
#include <linux/pagemap.h>
+#include <linux/quotaops.h>
#include "ext2.h"
#include "xattr.h"
#include "acl.h"
@@ -99,24 +100,27 @@ struct dentry *ext2_get_parent(struct dentry *child)
*/
static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd)
{
- struct inode * inode = ext2_new_inode (dir, mode);
- int err = PTR_ERR(inode);
- if (!IS_ERR(inode)) {
- inode->i_op = &ext2_file_inode_operations;
- if (ext2_use_xip(inode->i_sb)) {
- inode->i_mapping->a_ops = &ext2_aops_xip;
- inode->i_fop = &ext2_xip_file_operations;
- } else if (test_opt(inode->i_sb, NOBH)) {
- inode->i_mapping->a_ops = &ext2_nobh_aops;
- inode->i_fop = &ext2_file_operations;
- } else {
- inode->i_mapping->a_ops = &ext2_aops;
- inode->i_fop = &ext2_file_operations;
- }
- mark_inode_dirty(inode);
- err = ext2_add_nondir(dentry, inode);
+ struct inode *inode;
+
+ dquot_initialize(dir);
+
+ inode = ext2_new_inode(dir, mode);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+ inode->i_op = &ext2_file_inode_operations;
+ if (ext2_use_xip(inode->i_sb)) {
+ inode->i_mapping->a_ops = &ext2_aops_xip;
+ inode->i_fop = &ext2_xip_file_operations;
+ } else if (test_opt(inode->i_sb, NOBH)) {
+ inode->i_mapping->a_ops = &ext2_nobh_aops;
+ inode->i_fop = &ext2_file_operations;
+ } else {
+ inode->i_mapping->a_ops = &ext2_aops;
+ inode->i_fop = &ext2_file_operations;
}
- return err;
+ mark_inode_dirty(inode);
+ return ext2_add_nondir(dentry, inode);
}
static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
@@ -127,6 +131,8 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_
if (!new_valid_dev(rdev))
return -EINVAL;
+ dquot_initialize(dir);
+
inode = ext2_new_inode (dir, mode);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
@@ -151,6 +157,8 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry,
if (l > sb->s_blocksize)
goto out;
+ dquot_initialize(dir);
+
inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
err = PTR_ERR(inode);
if (IS_ERR(inode))
@@ -194,6 +202,8 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
if (inode->i_nlink >= EXT2_LINK_MAX)
return -EMLINK;
+ dquot_initialize(dir);
+
inode->i_ctime = CURRENT_TIME_SEC;
inode_inc_link_count(inode);
atomic_inc(&inode->i_count);
@@ -216,6 +226,8 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
if (dir->i_nlink >= EXT2_LINK_MAX)
goto out;
+ dquot_initialize(dir);
+
inode_inc_link_count(dir);
inode = ext2_new_inode (dir, S_IFDIR | mode);
@@ -262,6 +274,8 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry)
struct page * page;
int err = -ENOENT;
+ dquot_initialize(dir);
+
de = ext2_find_entry (dir, &dentry->d_name, &page);
if (!de)
goto out;
@@ -304,6 +318,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
struct ext2_dir_entry_2 * old_de;
int err = -ENOENT;
+ dquot_initialize(old_dir);
+ dquot_initialize(new_dir);
+
old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
if (!old_de)
goto out;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index f9cb54a585c..42e4a303b67 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -194,6 +194,8 @@ static void destroy_inodecache(void)
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))
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index 4e2426e22bb..565cf817bbf 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -32,6 +32,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = page_follow_link_light,
.put_link = page_put_link,
+ .setattr = ext2_setattr,
#ifdef CONFIG_EXT2_FS_XATTR
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
@@ -43,6 +44,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
const struct inode_operations ext2_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = ext2_follow_link,
+ .setattr = ext2_setattr,
#ifdef CONFIG_EXT2_FS_XATTR
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index 904f00642f8..e44dc92609b 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -644,8 +644,8 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
the inode. */
ea_bdebug(new_bh, "reusing block");
- error = -EDQUOT;
- if (vfs_dq_alloc_block(inode, 1)) {
+ error = dquot_alloc_block(inode, 1);
+ if (error) {
unlock_buffer(new_bh);
goto cleanup;
}
@@ -702,7 +702,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
* as if nothing happened and cleanup the unused block */
if (error && error != -ENOSPC) {
if (new_bh && new_bh != old_bh)
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
goto cleanup;
}
} else
@@ -734,7 +734,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
le32_add_cpu(&HDR(old_bh)->h_refcount, -1);
if (ce)
mb_cache_entry_release(ce);
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
mark_buffer_dirty(old_bh);
ea_bdebug(old_bh, "refcount now=%d",
le32_to_cpu(HDR(old_bh)->h_refcount));
@@ -797,7 +797,7 @@ ext2_xattr_delete_inode(struct inode *inode)
mark_buffer_dirty(bh);
if (IS_SYNC(inode))
sync_dirty_buffer(bh);
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
}
EXT2_I(inode)->i_file_acl = 0;
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index c8155845ac0..b118c6383c6 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -4,6 +4,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/ext2_fs.h>
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 27967f92e82..a177122a1b2 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -14,6 +14,7 @@
#include <linux/time.h>
#include <linux/capability.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/jbd.h>
#include <linux/ext3_fs.h>
#include <linux/ext3_jbd.h>
@@ -676,7 +677,7 @@ void ext3_free_blocks(handle_t *handle, struct inode *inode,
}
ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
if (dquot_freed_blocks)
- vfs_dq_free_block(inode, dquot_freed_blocks);
+ dquot_free_block(inode, dquot_freed_blocks);
return;
}
@@ -1502,8 +1503,9 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode,
/*
* Check quota for allocation of this block.
*/
- if (vfs_dq_alloc_block(inode, num)) {
- *errp = -EDQUOT;
+ err = dquot_alloc_block(inode, num);
+ if (err) {
+ *errp = err;
return 0;
}
@@ -1713,7 +1715,7 @@ allocated:
*errp = 0;
brelse(bitmap_bh);
- vfs_dq_free_block(inode, *count-num);
+ dquot_free_block(inode, *count-num);
*count = num;
return ret_block;
@@ -1728,7 +1730,7 @@ out:
* Undo the block allocation
*/
if (!performed_allocation)
- vfs_dq_free_block(inode, *count);
+ dquot_free_block(inode, *count);
brelse(bitmap_bh);
return 0;
}
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 388bbdfa0b4..f55df0e61cb 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -21,6 +21,7 @@
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/jbd.h>
+#include <linux/quotaops.h>
#include <linux/ext3_fs.h>
#include <linux/ext3_jbd.h>
#include "xattr.h"
@@ -33,9 +34,9 @@
*/
static int ext3_release_file (struct inode * inode, struct file * filp)
{
- if (EXT3_I(inode)->i_state & EXT3_STATE_FLUSH_ON_CLOSE) {
+ if (ext3_test_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE)) {
filemap_flush(inode->i_mapping);
- EXT3_I(inode)->i_state &= ~EXT3_STATE_FLUSH_ON_CLOSE;
+ ext3_clear_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE);
}
/* if we are the last writer on the inode, drop the block reservation */
if ((filp->f_mode & FMODE_WRITE) &&
@@ -62,7 +63,7 @@ const struct file_operations ext3_file_operations = {
.compat_ioctl = ext3_compat_ioctl,
#endif
.mmap = generic_file_mmap,
- .open = generic_file_open,
+ .open = dquot_file_open,
.release = ext3_release_file,
.fsync = ext3_sync_file,
.splice_read = generic_file_splice_read,
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index b3999128513..0d0e97ed3ff 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -123,10 +123,10 @@ void ext3_free_inode (handle_t *handle, 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.
*/
- vfs_dq_init(inode);
+ dquot_initialize(inode);
ext3_xattr_delete_inode(handle, inode);
- vfs_dq_free_inode(inode);
- vfs_dq_drop(inode);
+ dquot_free_inode(inode);
+ dquot_drop(inode);
is_directory = S_ISDIR(inode->i_mode);
@@ -582,16 +582,18 @@ got:
inode->i_generation = sbi->s_next_generation++;
spin_unlock(&sbi->s_next_gen_lock);
- ei->i_state = EXT3_STATE_NEW;
+ ei->i_state_flags = 0;
+ ext3_set_inode_state(inode, EXT3_STATE_NEW);
+
ei->i_extra_isize =
(EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
ret = inode;
- if (vfs_dq_alloc_inode(inode)) {
- err = -EDQUOT;
+ dquot_initialize(inode);
+ err = dquot_alloc_inode(inode);
+ if (err)
goto fail_drop;
- }
err = ext3_init_acl(handle, inode, dir);
if (err)
@@ -619,10 +621,10 @@ really_out:
return ret;
fail_free_drop:
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
fail_drop:
- vfs_dq_drop(inode);
+ dquot_drop(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
unlock_new_inode(inode);
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 455e6e6e5cb..ea33bdf0a30 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -196,6 +196,9 @@ void ext3_delete_inode (struct inode * inode)
{
handle_t *handle;
+ if (!is_bad_inode(inode))
+ dquot_initialize(inode);
+
truncate_inode_pages(&inode->i_data, 0);
if (is_bad_inode(inode))
@@ -1378,7 +1381,7 @@ static int ext3_journalled_write_end(struct file *file,
*/
if (pos + len > inode->i_size && ext3_can_truncate(inode))
ext3_orphan_add(handle, inode);
- EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
+ ext3_set_inode_state(inode, EXT3_STATE_JDATA);
if (inode->i_size > EXT3_I(inode)->i_disksize) {
EXT3_I(inode)->i_disksize = inode->i_size;
ret2 = ext3_mark_inode_dirty(handle, inode);
@@ -1417,7 +1420,7 @@ static sector_t ext3_bmap(struct address_space *mapping, sector_t block)
journal_t *journal;
int err;
- if (EXT3_I(inode)->i_state & EXT3_STATE_JDATA) {
+ if (ext3_test_inode_state(inode, EXT3_STATE_JDATA)) {
/*
* This is a REALLY heavyweight approach, but the use of
* bmap on dirty files is expected to be extremely rare:
@@ -1436,7 +1439,7 @@ static sector_t ext3_bmap(struct address_space *mapping, sector_t block)
* everything they get.
*/
- EXT3_I(inode)->i_state &= ~EXT3_STATE_JDATA;
+ ext3_clear_inode_state(inode, EXT3_STATE_JDATA);
journal = EXT3_JOURNAL(inode);
journal_lock_updates(journal);
err = journal_flush(journal);
@@ -1528,6 +1531,7 @@ static int ext3_ordered_writepage(struct page *page,
int err;
J_ASSERT(PageLocked(page));
+ WARN_ON_ONCE(IS_RDONLY(inode));
/*
* We give up here if we're reentered, because it might be for a
@@ -1600,6 +1604,9 @@ static int ext3_writeback_writepage(struct page *page,
int ret = 0;
int err;
+ J_ASSERT(PageLocked(page));
+ WARN_ON_ONCE(IS_RDONLY(inode));
+
if (ext3_journal_current_handle())
goto out_fail;
@@ -1642,6 +1649,9 @@ static int ext3_journalled_writepage(struct page *page,
int ret = 0;
int err;
+ J_ASSERT(PageLocked(page));
+ WARN_ON_ONCE(IS_RDONLY(inode));
+
if (ext3_journal_current_handle())
goto no_write;
@@ -1670,7 +1680,7 @@ static int ext3_journalled_writepage(struct page *page,
PAGE_CACHE_SIZE, NULL, write_end_fn);
if (ret == 0)
ret = err;
- EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
+ ext3_set_inode_state(inode, EXT3_STATE_JDATA);
unlock_page(page);
} else {
/*
@@ -1785,8 +1795,9 @@ retry:
handle = ext3_journal_start(inode, 2);
if (IS_ERR(handle)) {
/* This is really bad luck. We've written the data
- * but cannot extend i_size. Bail out and pretend
- * the write failed... */
+ * but cannot extend i_size. Truncate allocated blocks
+ * and pretend the write failed... */
+ ext3_truncate(inode);
ret = PTR_ERR(handle);
goto out;
}
@@ -2402,7 +2413,7 @@ void ext3_truncate(struct inode *inode)
goto out_notrans;
if (inode->i_size == 0 && ext3_should_writeback_data(inode))
- ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE;
+ ext3_set_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE);
/*
* We have to lock the EOF page here, because lock_page() nests
@@ -2721,7 +2732,7 @@ int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
{
/* We have all inode data except xattrs in memory here. */
return __ext3_get_inode_loc(inode, iloc,
- !(EXT3_I(inode)->i_state & EXT3_STATE_XATTR));
+ !ext3_test_inode_state(inode, EXT3_STATE_XATTR));
}
void ext3_set_inode_flags(struct inode *inode)
@@ -2800,7 +2811,7 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
- ei->i_state = 0;
+ ei->i_state_flags = 0;
ei->i_dir_start_lookup = 0;
ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
/* We now have enough fields to check if the inode was active or not.
@@ -2893,7 +2904,7 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
EXT3_GOOD_OLD_INODE_SIZE +
ei->i_extra_isize;
if (*magic == cpu_to_le32(EXT3_XATTR_MAGIC))
- ei->i_state |= EXT3_STATE_XATTR;
+ ext3_set_inode_state(inode, EXT3_STATE_XATTR);
}
} else
ei->i_extra_isize = 0;
@@ -2955,7 +2966,7 @@ again:
/* For fields not not tracking in the in-memory inode,
* initialise them to zero for new inodes. */
- if (ei->i_state & EXT3_STATE_NEW)
+ if (ext3_test_inode_state(inode, EXT3_STATE_NEW))
memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
ext3_get_inode_flags(ei);
@@ -3052,7 +3063,7 @@ again:
rc = ext3_journal_dirty_metadata(handle, bh);
if (!err)
err = rc;
- ei->i_state &= ~EXT3_STATE_NEW;
+ ext3_clear_inode_state(inode, EXT3_STATE_NEW);
atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid);
out_brelse:
@@ -3096,7 +3107,7 @@ out_brelse:
* `stuff()' is running, and the new i_size will be lost. Plus the inode
* will no longer be on the superblock's dirty inode list.
*/
-int ext3_write_inode(struct inode *inode, int wait)
+int ext3_write_inode(struct inode *inode, struct writeback_control *wbc)
{
if (current->flags & PF_MEMALLOC)
return 0;
@@ -3107,7 +3118,7 @@ int ext3_write_inode(struct inode *inode, int wait)
return -EIO;
}
- if (!wait)
+ if (wbc->sync_mode != WB_SYNC_ALL)
return 0;
return ext3_force_commit(inode->i_sb);
@@ -3140,6 +3151,8 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
if (error)
return error;
+ if (ia_valid & ATTR_SIZE)
+ dquot_initialize(inode);
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
handle_t *handle;
@@ -3152,7 +3165,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
error = PTR_ERR(handle);
goto err_out;
}
- error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+ error = dquot_transfer(inode, attr);
if (error) {
ext3_journal_stop(handle);
return error;
@@ -3237,7 +3250,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode)
ret = 2 * (bpp + indirects) + 2;
#ifdef CONFIG_QUOTA
- /* We know that structure was already allocated during vfs_dq_init so
+ /* We know that structure was already allocated during dquot_initialize so
* we will be updating only the data blocks + inodes */
ret += EXT3_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
#endif
@@ -3328,7 +3341,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode)
* i_size has been changed by generic_commit_write() and we thus need
* to include the updated inode in the current transaction.
*
- * Also, vfs_dq_alloc_space() will always dirty the inode when blocks
+ * Also, dquot_alloc_space() will always dirty the inode when blocks
* are allocated to the file.
*
* If the inode is marked synchronous, we don't honour that here - doing
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 7b0e44f7d66..ee184084ca4 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1696,6 +1696,8 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode,
struct inode * inode;
int err, retries = 0;
+ dquot_initialize(dir);
+
retry:
handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -1730,6 +1732,8 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
if (!new_valid_dev(rdev))
return -EINVAL;
+ dquot_initialize(dir);
+
retry:
handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -1766,6 +1770,8 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
if (dir->i_nlink >= EXT3_LINK_MAX)
return -EMLINK;
+ dquot_initialize(dir);
+
retry:
handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -2060,7 +2066,9 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
/* Initialize quotas before so that eventual writes go in
* separate transaction */
- vfs_dq_init(dentry->d_inode);
+ dquot_initialize(dir);
+ dquot_initialize(dentry->d_inode);
+
handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -2119,7 +2127,9 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry)
/* Initialize quotas before so that eventual writes go
* in separate transaction */
- vfs_dq_init(dentry->d_inode);
+ dquot_initialize(dir);
+ dquot_initialize(dentry->d_inode);
+
handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -2174,6 +2184,8 @@ static int ext3_symlink (struct inode * dir,
if (l > dir->i_sb->s_blocksize)
return -ENAMETOOLONG;
+ dquot_initialize(dir);
+
retry:
handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 +
@@ -2228,6 +2240,9 @@ static int ext3_link (struct dentry * old_dentry,
if (inode->i_nlink >= EXT3_LINK_MAX)
return -EMLINK;
+
+ dquot_initialize(dir);
+
/*
* Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing
* otherwise has the potential to corrupt the orphan inode list.
@@ -2278,12 +2293,15 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
struct ext3_dir_entry_2 * old_de, * new_de;
int retval, flush_file = 0;
+ dquot_initialize(old_dir);
+ dquot_initialize(new_dir);
+
old_bh = new_bh = dir_bh = NULL;
/* Initialize quotas before so that eventual writes go
* in separate transaction */
if (new_dentry->d_inode)
- vfs_dq_init(new_dentry->d_inode);
+ dquot_initialize(new_dentry->d_inode);
handle = ext3_journal_start(old_dir, 2 *
EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) +
EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index afa2b569da1..1bee604cc6c 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -164,7 +164,7 @@ void ext3_msg(struct super_block *sb, const char *prefix,
* write out the superblock safely.
*
* We'll just use the journal_abort() error code to record an error in
- * the journal instead. On recovery, the journal will compain about
+ * the journal instead. On recovery, the journal will complain about
* that error until we've noted it down and cleared it.
*/
@@ -181,7 +181,7 @@ static void ext3_handle_error(struct super_block *sb)
if (!test_opt (sb, ERRORS_CONT)) {
journal_t *journal = EXT3_SB(sb)->s_journal;
- EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
+ set_opt(EXT3_SB(sb)->s_mount_opt, ABORT);
if (journal)
journal_abort(journal, -EIO);
}
@@ -296,7 +296,7 @@ void ext3_abort (struct super_block * sb, const char * function,
"error: remounting filesystem read-only");
EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
sb->s_flags |= MS_RDONLY;
- EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT;
+ set_opt(EXT3_SB(sb)->s_mount_opt, ABORT);
if (EXT3_SB(sb)->s_journal)
journal_abort(EXT3_SB(sb)->s_journal, -EIO);
}
@@ -528,6 +528,8 @@ static void destroy_inodecache(void)
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))
@@ -562,10 +564,10 @@ static inline void ext3_show_quota_options(struct seq_file *seq, struct super_bl
if (sbi->s_qf_names[GRPQUOTA])
seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
- if (sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA)
+ if (test_opt(sb, USRQUOTA))
seq_puts(seq, ",usrquota");
- if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)
+ if (test_opt(sb, GRPQUOTA))
seq_puts(seq, ",grpquota");
#endif
}
@@ -656,8 +658,7 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
if (test_opt(sb, NOBH))
seq_puts(seq, ",nobh");
- seq_printf(seq, ",data=%s", data_mode_string(sbi->s_mount_opt &
- EXT3_MOUNT_DATA_FLAGS));
+ 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");
@@ -751,13 +752,6 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
const char *data, size_t len, loff_t off);
static const struct dquot_operations ext3_quota_operations = {
- .initialize = dquot_initialize,
- .drop = dquot_drop,
- .alloc_space = dquot_alloc_space,
- .alloc_inode = dquot_alloc_inode,
- .free_space = dquot_free_space,
- .free_inode = dquot_free_inode,
- .transfer = dquot_transfer,
.write_dquot = ext3_write_dquot,
.acquire_dquot = ext3_acquire_dquot,
.release_dquot = ext3_release_dquot,
@@ -896,6 +890,63 @@ static ext3_fsblk_t get_sb_block(void **data, struct super_block *sb)
return sb_block;
}
+#ifdef CONFIG_QUOTA
+static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
+{
+ struct ext3_sb_info *sbi = EXT3_SB(sb);
+ char *qname;
+
+ if (sb_any_quota_loaded(sb) &&
+ !sbi->s_qf_names[qtype]) {
+ ext3_msg(sb, KERN_ERR,
+ "Cannot change journaled "
+ "quota options when quota turned on");
+ return 0;
+ }
+ qname = match_strdup(args);
+ if (!qname) {
+ ext3_msg(sb, KERN_ERR,
+ "Not enough memory for storing quotafile name");
+ return 0;
+ }
+ if (sbi->s_qf_names[qtype] &&
+ strcmp(sbi->s_qf_names[qtype], qname)) {
+ ext3_msg(sb, KERN_ERR,
+ "%s quota file already specified", QTYPE2NAME(qtype));
+ kfree(qname);
+ return 0;
+ }
+ sbi->s_qf_names[qtype] = qname;
+ if (strchr(sbi->s_qf_names[qtype], '/')) {
+ ext3_msg(sb, KERN_ERR,
+ "quotafile must be on filesystem root");
+ kfree(sbi->s_qf_names[qtype]);
+ sbi->s_qf_names[qtype] = NULL;
+ return 0;
+ }
+ set_opt(sbi->s_mount_opt, QUOTA);
+ return 1;
+}
+
+static int clear_qf_name(struct super_block *sb, int qtype) {
+
+ struct ext3_sb_info *sbi = EXT3_SB(sb);
+
+ if (sb_any_quota_loaded(sb) &&
+ sbi->s_qf_names[qtype]) {
+ ext3_msg(sb, KERN_ERR, "Cannot change journaled quota options"
+ " when quota turned on");
+ return 0;
+ }
+ /*
+ * The space will be released later when all options are confirmed
+ * to be correct
+ */
+ sbi->s_qf_names[qtype] = NULL;
+ return 1;
+}
+#endif
+
static int parse_options (char *options, struct super_block *sb,
unsigned int *inum, unsigned long *journal_devnum,
ext3_fsblk_t *n_blocks_count, int is_remount)
@@ -906,8 +957,7 @@ static int parse_options (char *options, struct super_block *sb,
int data_opt = 0;
int option;
#ifdef CONFIG_QUOTA
- int qtype, qfmt;
- char *qname;
+ int qfmt;
#endif
if (!options)
@@ -1065,20 +1115,19 @@ static int parse_options (char *options, struct super_block *sb,
data_opt = EXT3_MOUNT_WRITEBACK_DATA;
datacheck:
if (is_remount) {
- if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS)
- == data_opt)
+ if (test_opt(sb, DATA_FLAGS) == data_opt)
break;
ext3_msg(sb, KERN_ERR,
"error: cannot change "
"data mode on remount. The filesystem "
"is mounted in data=%s mode and you "
"try to remount it in data=%s mode.",
- data_mode_string(sbi->s_mount_opt &
- EXT3_MOUNT_DATA_FLAGS),
+ data_mode_string(test_opt(sb,
+ DATA_FLAGS)),
data_mode_string(data_opt));
return 0;
} else {
- sbi->s_mount_opt &= ~EXT3_MOUNT_DATA_FLAGS;
+ clear_opt(sbi->s_mount_opt, DATA_FLAGS);
sbi->s_mount_opt |= data_opt;
}
break;
@@ -1090,62 +1139,20 @@ static int parse_options (char *options, struct super_block *sb,
break;
#ifdef CONFIG_QUOTA
case Opt_usrjquota:
- qtype = USRQUOTA;
- goto set_qf_name;
- case Opt_grpjquota:
- qtype = GRPQUOTA;
-set_qf_name:
- if (sb_any_quota_loaded(sb) &&
- !sbi->s_qf_names[qtype]) {
- ext3_msg(sb, KERN_ERR,
- "error: cannot change journaled "
- "quota options when quota turned on.");
- return 0;
- }
- qname = match_strdup(&args[0]);
- if (!qname) {
- ext3_msg(sb, KERN_ERR,
- "error: not enough memory for "
- "storing quotafile name.");
+ if (!set_qf_name(sb, USRQUOTA, &args[0]))
return 0;
- }
- if (sbi->s_qf_names[qtype] &&
- strcmp(sbi->s_qf_names[qtype], qname)) {
- ext3_msg(sb, KERN_ERR,
- "error: %s quota file already "
- "specified.", QTYPE2NAME(qtype));
- kfree(qname);
- return 0;
- }
- sbi->s_qf_names[qtype] = qname;
- if (strchr(sbi->s_qf_names[qtype], '/')) {
- ext3_msg(sb, KERN_ERR,
- "error: quotafile must be on "
- "filesystem root.");
- kfree(sbi->s_qf_names[qtype]);
- sbi->s_qf_names[qtype] = NULL;
+ break;
+ case Opt_grpjquota:
+ if (!set_qf_name(sb, GRPQUOTA, &args[0]))
return 0;
- }
- set_opt(sbi->s_mount_opt, QUOTA);
break;
case Opt_offusrjquota:
- qtype = USRQUOTA;
- goto clear_qf_name;
+ if (!clear_qf_name(sb, USRQUOTA))
+ return 0;
+ break;
case Opt_offgrpjquota:
- qtype = GRPQUOTA;
-clear_qf_name:
- if (sb_any_quota_loaded(sb) &&
- sbi->s_qf_names[qtype]) {
- ext3_msg(sb, KERN_ERR, "error: cannot change "
- "journaled quota options when "
- "quota turned on.");
+ if (!clear_qf_name(sb, GRPQUOTA))
return 0;
- }
- /*
- * The space will be released later when all options
- * are confirmed to be correct
- */
- sbi->s_qf_names[qtype] = NULL;
break;
case Opt_jqfmt_vfsold:
qfmt = QFMT_VFS_OLD;
@@ -1244,18 +1251,12 @@ set_qf_format:
}
#ifdef CONFIG_QUOTA
if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
- if ((sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA) &&
- sbi->s_qf_names[USRQUOTA])
+ if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
clear_opt(sbi->s_mount_opt, USRQUOTA);
-
- if ((sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) &&
- sbi->s_qf_names[GRPQUOTA])
+ if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
clear_opt(sbi->s_mount_opt, GRPQUOTA);
- if ((sbi->s_qf_names[USRQUOTA] &&
- (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)) ||
- (sbi->s_qf_names[GRPQUOTA] &&
- (sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA))) {
+ if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) {
ext3_msg(sb, KERN_ERR, "error: old and new quota "
"format mixing.");
return 0;
@@ -1478,7 +1479,7 @@ static void ext3_orphan_cleanup (struct super_block * sb,
}
list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);
- vfs_dq_init(inode);
+ dquot_initialize(inode);
if (inode->i_nlink) {
printk(KERN_DEBUG
"%s: truncating inode %lu to %Ld bytes\n",
@@ -1671,11 +1672,11 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
set_opt(sbi->s_mount_opt, POSIX_ACL);
#endif
if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA)
- sbi->s_mount_opt |= EXT3_MOUNT_JOURNAL_DATA;
+ set_opt(sbi->s_mount_opt, JOURNAL_DATA);
else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED)
- sbi->s_mount_opt |= EXT3_MOUNT_ORDERED_DATA;
+ set_opt(sbi->s_mount_opt, ORDERED_DATA);
else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_WBACK)
- sbi->s_mount_opt |= EXT3_MOUNT_WRITEBACK_DATA;
+ set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC)
set_opt(sbi->s_mount_opt, ERRORS_PANIC);
@@ -1694,7 +1695,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
goto failed_mount;
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
- ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+ (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV &&
(EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||
@@ -2561,11 +2562,11 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
goto restore_opts;
}
- if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
+ if (test_opt(sb, ABORT))
ext3_abort(sb, __func__, "Abort forced by user");
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
- ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+ (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
es = sbi->s_es;
@@ -2573,7 +2574,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
- if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) {
+ if (test_opt(sb, ABORT)) {
err = -EROFS;
goto restore_opts;
}
@@ -2734,7 +2735,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
* Process 1 Process 2
* ext3_create() quota_sync()
* journal_start() write_dquot()
- * vfs_dq_init() down(dqio_mutex)
+ * dquot_initialize() down(dqio_mutex)
* down(dqio_mutex) journal_start()
*
*/
@@ -2942,9 +2943,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
int err = 0;
int offset = off & (sb->s_blocksize - 1);
- int tocopy;
int journal_quota = EXT3_SB(sb)->s_qf_names[type] != NULL;
- size_t towrite = len;
struct buffer_head *bh;
handle_t *handle = journal_current_handle();
@@ -2955,53 +2954,54 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
(unsigned long long)off, (unsigned long long)len);
return -EIO;
}
+
+ /*
+ * Since we account only one data block in transaction credits,
+ * then it is impossible to cross a block boundary.
+ */
+ if (sb->s_blocksize - offset < len) {
+ ext3_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)"
+ " cancelled because not block aligned",
+ (unsigned long long)off, (unsigned long long)len);
+ return -EIO;
+ }
mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
- while (towrite > 0) {
- tocopy = sb->s_blocksize - offset < towrite ?
- sb->s_blocksize - offset : towrite;
- bh = ext3_bread(handle, inode, blk, 1, &err);
- if (!bh)
+ bh = ext3_bread(handle, inode, blk, 1, &err);
+ if (!bh)
+ goto out;
+ if (journal_quota) {
+ err = ext3_journal_get_write_access(handle, bh);
+ if (err) {
+ brelse(bh);
goto out;
- if (journal_quota) {
- err = ext3_journal_get_write_access(handle, bh);
- if (err) {
- brelse(bh);
- goto out;
- }
- }
- lock_buffer(bh);
- memcpy(bh->b_data+offset, data, tocopy);
- flush_dcache_page(bh->b_page);
- unlock_buffer(bh);
- if (journal_quota)
- err = ext3_journal_dirty_metadata(handle, bh);
- else {
- /* Always do at least ordered writes for quotas */
- err = ext3_journal_dirty_data(handle, bh);
- mark_buffer_dirty(bh);
}
- brelse(bh);
- if (err)
- goto out;
- offset = 0;
- towrite -= tocopy;
- data += tocopy;
- blk++;
}
+ lock_buffer(bh);
+ memcpy(bh->b_data+offset, data, len);
+ flush_dcache_page(bh->b_page);
+ unlock_buffer(bh);
+ if (journal_quota)
+ err = ext3_journal_dirty_metadata(handle, bh);
+ else {
+ /* Always do at least ordered writes for quotas */
+ err = ext3_journal_dirty_data(handle, bh);
+ mark_buffer_dirty(bh);
+ }
+ brelse(bh);
out:
- if (len == towrite) {
+ if (err) {
mutex_unlock(&inode->i_mutex);
return err;
}
- if (inode->i_size < off+len-towrite) {
- i_size_write(inode, off+len-towrite);
+ if (inode->i_size < off + len) {
+ i_size_write(inode, off + len);
EXT3_I(inode)->i_disksize = inode->i_size;
}
inode->i_version++;
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
ext3_mark_inode_dirty(handle, inode);
mutex_unlock(&inode->i_mutex);
- return len - towrite;
+ return len;
}
#endif
diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c
index ff7b4ccd898..7c489820777 100644
--- a/fs/ext3/symlink.c
+++ b/fs/ext3/symlink.c
@@ -34,6 +34,7 @@ const struct inode_operations ext3_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = page_follow_link_light,
.put_link = page_put_link,
+ .setattr = ext3_setattr,
#ifdef CONFIG_EXT3_FS_XATTR
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
@@ -45,6 +46,7 @@ const struct inode_operations ext3_symlink_inode_operations = {
const struct inode_operations ext3_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = ext3_follow_link,
+ .setattr = ext3_setattr,
#ifdef CONFIG_EXT3_FS_XATTR
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 66895ccf76c..534a94c3a93 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -274,7 +274,7 @@ ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
void *end;
int error;
- if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR))
+ if (!ext3_test_inode_state(inode, EXT3_STATE_XATTR))
return -ENODATA;
error = ext3_get_inode_loc(inode, &iloc);
if (error)
@@ -403,7 +403,7 @@ ext3_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
void *end;
int error;
- if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR))
+ if (!ext3_test_inode_state(inode, EXT3_STATE_XATTR))
return 0;
error = ext3_get_inode_loc(inode, &iloc);
if (error)
@@ -500,7 +500,7 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode,
error = ext3_journal_dirty_metadata(handle, bh);
if (IS_SYNC(inode))
handle->h_sync = 1;
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
ea_bdebug(bh, "refcount now=%d; releasing",
le32_to_cpu(BHDR(bh)->h_refcount));
if (ce)
@@ -775,8 +775,8 @@ inserted:
else {
/* The old block is released after updating
the inode. */
- error = -EDQUOT;
- if (vfs_dq_alloc_block(inode, 1))
+ error = dquot_alloc_block(inode, 1);
+ if (error)
goto cleanup;
error = ext3_journal_get_write_access(handle,
new_bh);
@@ -850,7 +850,7 @@ cleanup:
return error;
cleanup_dquot:
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
goto cleanup;
bad_block:
@@ -882,7 +882,7 @@ ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i,
is->s.base = is->s.first = IFIRST(header);
is->s.here = is->s.first;
is->s.end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
- if (EXT3_I(inode)->i_state & EXT3_STATE_XATTR) {
+ if (ext3_test_inode_state(inode, EXT3_STATE_XATTR)) {
error = ext3_xattr_check_names(IFIRST(header), is->s.end);
if (error)
return error;
@@ -914,10 +914,10 @@ ext3_xattr_ibody_set(handle_t *handle, struct inode *inode,
header = IHDR(inode, ext3_raw_inode(&is->iloc));
if (!IS_LAST_ENTRY(s->first)) {
header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
- EXT3_I(inode)->i_state |= EXT3_STATE_XATTR;
+ ext3_set_inode_state(inode, EXT3_STATE_XATTR);
} else {
header->h_magic = cpu_to_le32(0);
- EXT3_I(inode)->i_state &= ~EXT3_STATE_XATTR;
+ ext3_clear_inode_state(inode, EXT3_STATE_XATTR);
}
return 0;
}
@@ -967,10 +967,10 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
if (error)
goto cleanup;
- if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) {
+ if (ext3_test_inode_state(inode, EXT3_STATE_NEW)) {
struct ext3_inode *raw_inode = ext3_raw_inode(&is.iloc);
memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
- EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW;
+ ext3_clear_inode_state(inode, EXT3_STATE_NEW);
}
error = ext3_xattr_ibody_find(inode, &i, &is);
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index 474348788dd..3af91f476df 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -4,6 +4,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/ext3_jbd.h>
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 22bc7435d91..d2f37a5516c 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -97,8 +97,8 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
/* If checksum is bad mark all blocks used to prevent allocation
* essentially implementing a per-group read-only flag. */
if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
- ext4_error(sb, __func__,
- "Checksum bad for group %u", block_group);
+ ext4_error(sb, "Checksum bad for group %u",
+ block_group);
ext4_free_blks_set(sb, gdp, 0);
ext4_free_inodes_set(sb, gdp, 0);
ext4_itable_unused_set(sb, gdp, 0);
@@ -130,8 +130,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
* to make sure we calculate the right free blocks
*/
group_blocks = ext4_blocks_count(sbi->s_es) -
- le32_to_cpu(sbi->s_es->s_first_data_block) -
- (EXT4_BLOCKS_PER_GROUP(sb) * (ngroups - 1));
+ ext4_group_first_block_no(sb, ngroups - 1);
} else {
group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
}
@@ -189,9 +188,6 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
* when a file system is mounted (see ext4_fill_super).
*/
-
-#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
-
/**
* ext4_get_group_desc() -- load group descriptor from disk
* @sb: super block
@@ -210,10 +206,8 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
struct ext4_sb_info *sbi = EXT4_SB(sb);
if (block_group >= ngroups) {
- ext4_error(sb, "ext4_get_group_desc",
- "block_group >= groups_count - "
- "block_group = %u, groups_count = %u",
- block_group, ngroups);
+ ext4_error(sb, "block_group >= groups_count - block_group = %u,"
+ " groups_count = %u", block_group, ngroups);
return NULL;
}
@@ -221,8 +215,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
if (!sbi->s_group_desc[group_desc]) {
- ext4_error(sb, "ext4_get_group_desc",
- "Group descriptor not loaded - "
+ ext4_error(sb, "Group descriptor not loaded - "
"block_group = %u, group_desc = %u, desc = %u",
block_group, group_desc, offset);
return NULL;
@@ -282,9 +275,7 @@ static int ext4_valid_block_bitmap(struct super_block *sb,
return 1;
err_out:
- ext4_error(sb, __func__,
- "Invalid block bitmap - "
- "block_group = %d, block = %llu",
+ ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu",
block_group, bitmap_blk);
return 0;
}
@@ -311,8 +302,7 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
bitmap_blk = ext4_block_bitmap(sb, desc);
bh = sb_getblk(sb, bitmap_blk);
if (unlikely(!bh)) {
- ext4_error(sb, __func__,
- "Cannot read block bitmap - "
+ ext4_error(sb, "Cannot read block bitmap - "
"block_group = %u, block_bitmap = %llu",
block_group, bitmap_blk);
return NULL;
@@ -354,8 +344,7 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
set_bitmap_uptodate(bh);
if (bh_submit_read(bh) < 0) {
put_bh(bh);
- ext4_error(sb, __func__,
- "Cannot read block bitmap - "
+ ext4_error(sb, "Cannot read block bitmap - "
"block_group = %u, block_bitmap = %llu",
block_group, bitmap_blk);
return NULL;
@@ -419,8 +408,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
in_range(block + count - 1, ext4_inode_table(sb, desc),
sbi->s_itb_per_group)) {
- ext4_error(sb, __func__,
- "Adding blocks in system zones - "
+ ext4_error(sb, "Adding blocks in system zones - "
"Block = %llu, count = %lu",
block, count);
goto error_return;
@@ -453,8 +441,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
BUFFER_TRACE(bitmap_bh, "clear bit");
if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
bit + i, bitmap_bh->b_data)) {
- ext4_error(sb, __func__,
- "bit already cleared for block %llu",
+ ext4_error(sb, "bit already cleared for block %llu",
(ext4_fsblk_t)(block + i));
BUFFER_TRACE(bitmap_bh, "bit already cleared");
} else {
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
index a60ab9aad57..538c4865508 100644
--- a/fs/ext4/block_validity.c
+++ b/fs/ext4/block_validity.c
@@ -18,6 +18,7 @@
#include <linux/pagemap.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include "ext4.h"
struct ext4_system_zone {
@@ -205,14 +206,14 @@ void ext4_release_system_zone(struct super_block *sb)
entry = rb_entry(n, struct ext4_system_zone, node);
kmem_cache_free(ext4_system_zone_cachep, entry);
if (!parent)
- EXT4_SB(sb)->system_blks.rb_node = NULL;
+ EXT4_SB(sb)->system_blks = RB_ROOT;
else if (parent->rb_left == n)
parent->rb_left = NULL;
else if (parent->rb_right == n)
parent->rb_right = NULL;
n = parent;
}
- EXT4_SB(sb)->system_blks.rb_node = NULL;
+ EXT4_SB(sb)->system_blks = RB_ROOT;
}
/*
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 9dc93168e26..86cb6d86a04 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -83,10 +83,12 @@ int ext4_check_dir_entry(const char *function, struct inode *dir,
error_msg = "inode out of bounds";
if (error_msg != NULL)
- ext4_error(dir->i_sb, function,
- "bad entry in directory #%lu: %s - "
- "offset=%u, inode=%u, rec_len=%d, name_len=%d",
- dir->i_ino, error_msg, offset,
+ __ext4_error(dir->i_sb, function,
+ "bad entry in directory #%lu: %s - block=%llu"
+ "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d",
+ dir->i_ino, error_msg,
+ (unsigned long long) bh->b_blocknr,
+ (unsigned) (offset%bh->b_size), offset,
le32_to_cpu(de->inode),
rlen, de->name_len);
return error_msg == NULL ? 1 : 0;
@@ -150,7 +152,7 @@ static int ext4_readdir(struct file *filp,
*/
if (!bh) {
if (!dir_has_error) {
- ext4_error(sb, __func__, "directory #%lu "
+ ext4_error(sb, "directory #%lu "
"contains a hole at offset %Lu",
inode->i_ino,
(unsigned long long) filp->f_pos);
@@ -303,7 +305,7 @@ static void free_rb_tree_fname(struct rb_root *root)
kfree(old);
}
if (!parent)
- root->rb_node = NULL;
+ *root = RB_ROOT;
else if (parent->rb_left == n)
parent->rb_left = NULL;
else if (parent->rb_right == n)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 4cedc91ec59..bf938cf7c5f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -53,6 +53,12 @@
#define ext4_debug(f, a...) do {} while (0)
#endif
+#define EXT4_ERROR_INODE(inode, fmt, a...) \
+ ext4_error_inode(__func__, (inode), (fmt), ## a);
+
+#define EXT4_ERROR_FILE(file, fmt, a...) \
+ ext4_error_file(__func__, (file), (fmt), ## a);
+
/* data type for block offset of block group */
typedef int ext4_grpblk_t;
@@ -133,14 +139,14 @@ struct mpage_da_data {
int pages_written;
int retval;
};
-#define DIO_AIO_UNWRITTEN 0x1
+#define EXT4_IO_UNWRITTEN 0x1
typedef struct ext4_io_end {
struct list_head list; /* per-file finished AIO list */
struct inode *inode; /* file being written to */
unsigned int flag; /* unwritten or not */
- int error; /* I/O error code */
- ext4_lblk_t offset; /* offset in the file */
- size_t size; /* size of the extent */
+ struct page *page; /* page struct for buffer write */
+ loff_t offset; /* offset in the file */
+ ssize_t size; /* size of the extent */
struct work_struct work; /* data work queue */
} ext4_io_end_t;
@@ -284,10 +290,12 @@ struct flex_groups {
#define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
+#define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
+#define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
-#define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */
-#define EXT4_FL_USER_MODIFIABLE 0x000B80FF /* User modifiable flags */
+#define EXT4_FL_USER_VISIBLE 0x004BDFFF /* User visible flags */
+#define EXT4_FL_USER_MODIFIABLE 0x004B80FF /* User modifiable flags */
/* Flags that should be inherited by new inodes from their parent. */
#define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
@@ -313,17 +321,6 @@ static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)
return flags & EXT4_OTHER_FLMASK;
}
-/*
- * Inode dynamic state flags
- */
-#define EXT4_STATE_JDATA 0x00000001 /* journaled data exists */
-#define EXT4_STATE_NEW 0x00000002 /* inode is newly created */
-#define EXT4_STATE_XATTR 0x00000004 /* has in-inode xattrs */
-#define EXT4_STATE_NO_EXPAND 0x00000008 /* No space for expansion */
-#define EXT4_STATE_DA_ALLOC_CLOSE 0x00000010 /* Alloc DA blks on close */
-#define EXT4_STATE_EXT_MIGRATE 0x00000020 /* Inode is migrating */
-#define EXT4_STATE_DIO_UNWRITTEN 0x00000040 /* need convert on dio done*/
-
/* Used to pass group descriptor data when online resize is done */
struct ext4_new_group_input {
__u32 group; /* Group number for this data */
@@ -364,19 +361,20 @@ struct ext4_new_group_data {
/* caller is from the direct IO path, request to creation of an
unitialized extents if not allocated, split the uninitialized
extent if blocks has been preallocated already*/
-#define EXT4_GET_BLOCKS_DIO 0x0008
+#define EXT4_GET_BLOCKS_PRE_IO 0x0008
#define EXT4_GET_BLOCKS_CONVERT 0x0010
-#define EXT4_GET_BLOCKS_DIO_CREATE_EXT (EXT4_GET_BLOCKS_DIO|\
+#define EXT4_GET_BLOCKS_IO_CREATE_EXT (EXT4_GET_BLOCKS_PRE_IO|\
+ EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
+ /* Convert extent to initialized after IO complete */
+#define EXT4_GET_BLOCKS_IO_CONVERT_EXT (EXT4_GET_BLOCKS_CONVERT|\
EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
- /* Convert extent to initialized after direct IO complete */
-#define EXT4_GET_BLOCKS_DIO_CONVERT_EXT (EXT4_GET_BLOCKS_CONVERT|\
- EXT4_GET_BLOCKS_DIO_CREATE_EXT)
/*
* Flags used by ext4_free_blocks
*/
#define EXT4_FREE_BLOCKS_METADATA 0x0001
#define EXT4_FREE_BLOCKS_FORGET 0x0002
+#define EXT4_FREE_BLOCKS_VALIDATED 0x0004
/*
* ioctl commands
@@ -630,7 +628,7 @@ struct ext4_inode_info {
* near to their parent directory's inode.
*/
ext4_group_t i_block_group;
- __u32 i_state; /* Dynamic state flags for ext4 */
+ unsigned long i_state_flags; /* Dynamic state flags */
ext4_lblk_t i_dir_start_lookup;
#ifdef CONFIG_EXT4_FS_XATTR
@@ -708,8 +706,9 @@ struct ext4_inode_info {
qsize_t i_reserved_quota;
#endif
- /* completed async DIOs that might need unwritten extents handling */
- struct list_head i_aio_dio_complete_list;
+ /* completed IOs that might need unwritten extents handling */
+ struct list_head i_completed_io_list;
+ spinlock_t i_completed_io_lock;
/* current io_end structure for async DIO write*/
ext4_io_end_t *cur_aio_dio;
@@ -760,6 +759,7 @@ struct ext4_inode_info {
#define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
#define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
#define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
+#define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */
#define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
#define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
#define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */
@@ -1050,6 +1050,34 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
(ino >= EXT4_FIRST_INO(sb) &&
ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
}
+
+/*
+ * Inode dynamic state flags
+ */
+enum {
+ EXT4_STATE_JDATA, /* journaled data exists */
+ EXT4_STATE_NEW, /* inode is newly created */
+ EXT4_STATE_XATTR, /* has in-inode xattrs */
+ EXT4_STATE_NO_EXPAND, /* No space for expansion */
+ EXT4_STATE_DA_ALLOC_CLOSE, /* Alloc DA blks on close */
+ EXT4_STATE_EXT_MIGRATE, /* Inode is migrating */
+ EXT4_STATE_DIO_UNWRITTEN, /* need convert on dio done*/
+};
+
+static inline int ext4_test_inode_state(struct inode *inode, int bit)
+{
+ return test_bit(bit, &EXT4_I(inode)->i_state_flags);
+}
+
+static inline void ext4_set_inode_state(struct inode *inode, int bit)
+{
+ set_bit(bit, &EXT4_I(inode)->i_state_flags);
+}
+
+static inline void ext4_clear_inode_state(struct inode *inode, int bit)
+{
+ clear_bit(bit, &EXT4_I(inode)->i_state_flags);
+}
#else
/* Assume that user mode programs are passing in an ext4fs superblock, not
* a kernel struct super_block. This will allow us to call the feature-test
@@ -1126,6 +1154,8 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
+#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400 /* EA in inode */
+#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 /* data in dirent */
#define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
#define EXT4_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \
@@ -1416,7 +1446,7 @@ int ext4_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create);
extern struct inode *ext4_iget(struct super_block *, unsigned long);
-extern int ext4_write_inode(struct inode *, int);
+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);
@@ -1439,7 +1469,7 @@ extern int ext4_block_truncate_page(handle_t *handle,
struct address_space *mapping, loff_t from);
extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
extern qsize_t *ext4_get_reserved_space(struct inode *inode);
-extern int flush_aio_dio_completed_IO(struct inode *inode);
+extern int flush_completed_IO(struct inode *inode);
extern void ext4_da_update_reserve_space(struct inode *inode,
int used, int quota_claim);
/* ioctl.c */
@@ -1465,13 +1495,20 @@ extern int ext4_group_extend(struct super_block *sb,
ext4_fsblk_t n_blocks_count);
/* super.c */
-extern void ext4_error(struct super_block *, const char *, const char *, ...)
+extern void __ext4_error(struct super_block *, const char *, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#define ext4_error(sb, message...) __ext4_error(sb, __func__, ## message)
+extern void ext4_error_inode(const char *, struct inode *, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern void ext4_error_file(const char *, struct file *, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
extern void __ext4_std_error(struct super_block *, const char *, int);
extern void ext4_abort(struct super_block *, const char *, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
-extern void ext4_warning(struct super_block *, const char *, const char *, ...)
+extern void __ext4_warning(struct super_block *, const char *,
+ const char *, ...)
__attribute__ ((format (printf, 3, 4)));
+#define ext4_warning(sb, message...) __ext4_warning(sb, __func__, ## message)
extern void ext4_msg(struct super_block *, const char *, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
extern void ext4_grp_locked_error(struct super_block *, ext4_group_t,
@@ -1744,7 +1781,7 @@ extern void ext4_ext_release(struct super_block *);
extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
loff_t len);
extern int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
- loff_t len);
+ ssize_t len);
extern int ext4_get_blocks(handle_t *handle, struct inode *inode,
sector_t block, unsigned int max_blocks,
struct buffer_head *bh, int flags);
@@ -1756,6 +1793,15 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
__u64 len, __u64 *moved_len);
+/* BH_Uninit flag: blocks are allocated but uninitialized on disk */
+enum ext4_state_bits {
+ BH_Uninit /* blocks are allocated but uninitialized on disk */
+ = BH_JBDPrivateStart,
+};
+
+BUFFER_FNS(Uninit, uninit)
+TAS_BUFFER_FNS(Uninit, uninit)
+
/*
* Add new method to test wether block and inode bitmaps are properly
* initialized. With uninit_bg reading the block from disk is not enough
@@ -1773,6 +1819,8 @@ static inline void set_bitmap_uptodate(struct buffer_head *bh)
set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
}
+#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
+
#endif /* __KERNEL__ */
#endif /* _EXT4_H */
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index b57e5c711b6..53d2764d71c 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -125,14 +125,14 @@ int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
ext4_journal_abort_handle(where, __func__, bh,
handle, err);
} else {
- if (inode && bh)
+ if (inode)
mark_buffer_dirty_inode(bh, inode);
else
mark_buffer_dirty(bh);
if (inode && inode_needs_sync(inode)) {
sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh)) {
- ext4_error(inode->i_sb, __func__,
+ ext4_error(inode->i_sb,
"IO error syncing inode, "
"inode=%lu, block=%llu",
inode->i_ino,
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index 05eca817d70..b79ad512646 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -304,4 +304,28 @@ static inline int ext4_should_writeback_data(struct inode *inode)
return 0;
}
+/*
+ * This function controls whether or not we should try to go down the
+ * dioread_nolock code paths, which makes it safe to avoid taking
+ * i_mutex for direct I/O reads. This only works for extent-based
+ * files, and it doesn't work for nobh or if data journaling is
+ * enabled, since the dioread_nolock code uses b_private to pass
+ * information back to the I/O completion handler, and this conflicts
+ * with the jbd's use of b_private.
+ */
+static inline int ext4_should_dioread_nolock(struct inode *inode)
+{
+ if (!test_opt(inode->i_sb, DIOREAD_NOLOCK))
+ return 0;
+ if (test_opt(inode->i_sb, NOBH))
+ return 0;
+ if (!S_ISREG(inode->i_mode))
+ return 0;
+ if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
+ return 0;
+ if (ext4_should_journal_data(inode))
+ return 0;
+ return 1;
+}
+
#endif /* _EXT4_JBD2_H */
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 765a4826b11..236b834b4ca 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -195,8 +195,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
if (S_ISREG(inode->i_mode))
block_group++;
}
- bg_start = (block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) +
- le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block);
+ bg_start = ext4_group_first_block_no(inode->i_sb, block_group);
last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1;
/*
@@ -440,7 +439,7 @@ static int __ext4_ext_check(const char *function, struct inode *inode,
return 0;
corrupted:
- ext4_error(inode->i_sb, function,
+ __ext4_error(inode->i_sb, function,
"bad header/extent in inode #%lu: %s - magic %x, "
"entries %u, max %u(%u), depth %u(%u)",
inode->i_ino, error_msg, le16_to_cpu(eh->eh_magic),
@@ -703,7 +702,12 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
}
eh = ext_block_hdr(bh);
ppos++;
- BUG_ON(ppos > depth);
+ if (unlikely(ppos > depth)) {
+ put_bh(bh);
+ EXT4_ERROR_INODE(inode,
+ "ppos %d > depth %d", ppos, depth);
+ goto err;
+ }
path[ppos].p_bh = bh;
path[ppos].p_hdr = eh;
i--;
@@ -749,7 +753,12 @@ int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
if (err)
return err;
- BUG_ON(logical == le32_to_cpu(curp->p_idx->ei_block));
+ if (unlikely(logical == le32_to_cpu(curp->p_idx->ei_block))) {
+ EXT4_ERROR_INODE(inode,
+ "logical %d == ei_block %d!",
+ logical, le32_to_cpu(curp->p_idx->ei_block));
+ return -EIO;
+ }
len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx;
if (logical > le32_to_cpu(curp->p_idx->ei_block)) {
/* insert after */
@@ -779,9 +788,17 @@ int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
ext4_idx_store_pblock(ix, ptr);
le16_add_cpu(&curp->p_hdr->eh_entries, 1);
- BUG_ON(le16_to_cpu(curp->p_hdr->eh_entries)
- > le16_to_cpu(curp->p_hdr->eh_max));
- BUG_ON(ix > EXT_LAST_INDEX(curp->p_hdr));
+ if (unlikely(le16_to_cpu(curp->p_hdr->eh_entries)
+ > le16_to_cpu(curp->p_hdr->eh_max))) {
+ EXT4_ERROR_INODE(inode,
+ "logical %d == ei_block %d!",
+ logical, le32_to_cpu(curp->p_idx->ei_block));
+ return -EIO;
+ }
+ if (unlikely(ix > EXT_LAST_INDEX(curp->p_hdr))) {
+ EXT4_ERROR_INODE(inode, "ix > EXT_LAST_INDEX!");
+ return -EIO;
+ }
err = ext4_ext_dirty(handle, inode, curp);
ext4_std_error(inode->i_sb, err);
@@ -819,7 +836,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
/* if current leaf will be split, then we should use
* border from split point */
- BUG_ON(path[depth].p_ext > EXT_MAX_EXTENT(path[depth].p_hdr));
+ if (unlikely(path[depth].p_ext > EXT_MAX_EXTENT(path[depth].p_hdr))) {
+ EXT4_ERROR_INODE(inode, "p_ext > EXT_MAX_EXTENT!");
+ return -EIO;
+ }
if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) {
border = path[depth].p_ext[1].ee_block;
ext_debug("leaf will be split."
@@ -860,7 +880,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
/* initialize new leaf */
newblock = ablocks[--a];
- BUG_ON(newblock == 0);
+ if (unlikely(newblock == 0)) {
+ EXT4_ERROR_INODE(inode, "newblock == 0!");
+ err = -EIO;
+ goto cleanup;
+ }
bh = sb_getblk(inode->i_sb, newblock);
if (!bh) {
err = -EIO;
@@ -880,7 +904,14 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
ex = EXT_FIRST_EXTENT(neh);
/* move remainder of path[depth] to the new leaf */
- BUG_ON(path[depth].p_hdr->eh_entries != path[depth].p_hdr->eh_max);
+ if (unlikely(path[depth].p_hdr->eh_entries !=
+ path[depth].p_hdr->eh_max)) {
+ EXT4_ERROR_INODE(inode, "eh_entries %d != eh_max %d!",
+ path[depth].p_hdr->eh_entries,
+ path[depth].p_hdr->eh_max);
+ err = -EIO;
+ goto cleanup;
+ }
/* start copy from next extent */
/* TODO: we could do it by single memmove */
m = 0;
@@ -927,7 +958,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
/* create intermediate indexes */
k = depth - at - 1;
- BUG_ON(k < 0);
+ if (unlikely(k < 0)) {
+ EXT4_ERROR_INODE(inode, "k %d < 0!", k);
+ err = -EIO;
+ goto cleanup;
+ }
if (k)
ext_debug("create %d intermediate indices\n", k);
/* insert new index into current index block */
@@ -964,8 +999,14 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
ext_debug("cur 0x%p, last 0x%p\n", path[i].p_idx,
EXT_MAX_INDEX(path[i].p_hdr));
- BUG_ON(EXT_MAX_INDEX(path[i].p_hdr) !=
- EXT_LAST_INDEX(path[i].p_hdr));
+ if (unlikely(EXT_MAX_INDEX(path[i].p_hdr) !=
+ EXT_LAST_INDEX(path[i].p_hdr))) {
+ EXT4_ERROR_INODE(inode,
+ "EXT_MAX_INDEX != EXT_LAST_INDEX ee_block %d!",
+ le32_to_cpu(path[i].p_ext->ee_block));
+ err = -EIO;
+ goto cleanup;
+ }
while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) {
ext_debug("%d: move %d:%llu in new index %llu\n", i,
le32_to_cpu(path[i].p_idx->ei_block),
@@ -1203,7 +1244,10 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
struct ext4_extent *ex;
int depth, ee_len;
- BUG_ON(path == NULL);
+ if (unlikely(path == NULL)) {
+ EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical);
+ return -EIO;
+ }
depth = path->p_depth;
*phys = 0;
@@ -1217,15 +1261,33 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
ex = path[depth].p_ext;
ee_len = ext4_ext_get_actual_len(ex);
if (*logical < le32_to_cpu(ex->ee_block)) {
- BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
+ if (unlikely(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex)) {
+ EXT4_ERROR_INODE(inode,
+ "EXT_FIRST_EXTENT != ex *logical %d ee_block %d!",
+ *logical, le32_to_cpu(ex->ee_block));
+ return -EIO;
+ }
while (--depth >= 0) {
ix = path[depth].p_idx;
- BUG_ON(ix != EXT_FIRST_INDEX(path[depth].p_hdr));
+ if (unlikely(ix != EXT_FIRST_INDEX(path[depth].p_hdr))) {
+ EXT4_ERROR_INODE(inode,
+ "ix (%d) != EXT_FIRST_INDEX (%d) (depth %d)!",
+ ix != NULL ? ix->ei_block : 0,
+ EXT_FIRST_INDEX(path[depth].p_hdr) != NULL ?
+ EXT_FIRST_INDEX(path[depth].p_hdr)->ei_block : 0,
+ depth);
+ return -EIO;
+ }
}
return 0;
}
- BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
+ if (unlikely(*logical < (le32_to_cpu(ex->ee_block) + ee_len))) {
+ EXT4_ERROR_INODE(inode,
+ "logical %d < ee_block %d + ee_len %d!",
+ *logical, le32_to_cpu(ex->ee_block), ee_len);
+ return -EIO;
+ }
*logical = le32_to_cpu(ex->ee_block) + ee_len - 1;
*phys = ext_pblock(ex) + ee_len - 1;
@@ -1251,7 +1313,10 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
int depth; /* Note, NOT eh_depth; depth from top of tree */
int ee_len;
- BUG_ON(path == NULL);
+ if (unlikely(path == NULL)) {
+ EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical);
+ return -EIO;
+ }
depth = path->p_depth;
*phys = 0;
@@ -1265,17 +1330,32 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
ex = path[depth].p_ext;
ee_len = ext4_ext_get_actual_len(ex);
if (*logical < le32_to_cpu(ex->ee_block)) {
- BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
+ if (unlikely(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex)) {
+ EXT4_ERROR_INODE(inode,
+ "first_extent(path[%d].p_hdr) != ex",
+ depth);
+ return -EIO;
+ }
while (--depth >= 0) {
ix = path[depth].p_idx;
- BUG_ON(ix != EXT_FIRST_INDEX(path[depth].p_hdr));
+ if (unlikely(ix != EXT_FIRST_INDEX(path[depth].p_hdr))) {
+ EXT4_ERROR_INODE(inode,
+ "ix != EXT_FIRST_INDEX *logical %d!",
+ *logical);
+ return -EIO;
+ }
}
*logical = le32_to_cpu(ex->ee_block);
*phys = ext_pblock(ex);
return 0;
}
- BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
+ if (unlikely(*logical < (le32_to_cpu(ex->ee_block) + ee_len))) {
+ EXT4_ERROR_INODE(inode,
+ "logical %d < ee_block %d + ee_len %d!",
+ *logical, le32_to_cpu(ex->ee_block), ee_len);
+ return -EIO;
+ }
if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
/* next allocated block in this leaf */
@@ -1414,8 +1494,12 @@ static int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode,
eh = path[depth].p_hdr;
ex = path[depth].p_ext;
- BUG_ON(ex == NULL);
- BUG_ON(eh == NULL);
+
+ if (unlikely(ex == NULL || eh == NULL)) {
+ EXT4_ERROR_INODE(inode,
+ "ex %p == NULL or eh %p == NULL", ex, eh);
+ return -EIO;
+ }
if (depth == 0) {
/* there is no tree at all */
@@ -1538,8 +1622,9 @@ int ext4_ext_try_to_merge(struct inode *inode,
merge_done = 1;
WARN_ON(eh->eh_entries == 0);
if (!eh->eh_entries)
- ext4_error(inode->i_sb, "ext4_ext_try_to_merge",
- "inode#%lu, eh->eh_entries = 0!", inode->i_ino);
+ ext4_error(inode->i_sb,
+ "inode#%lu, eh->eh_entries = 0!",
+ inode->i_ino);
}
return merge_done;
@@ -1612,13 +1697,19 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
ext4_lblk_t next;
unsigned uninitialized = 0;
- BUG_ON(ext4_ext_get_actual_len(newext) == 0);
+ if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
+ EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
+ return -EIO;
+ }
depth = ext_depth(inode);
ex = path[depth].p_ext;
- BUG_ON(path[depth].p_hdr == NULL);
+ if (unlikely(path[depth].p_hdr == NULL)) {
+ EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
+ return -EIO;
+ }
/* try to insert block into found extent and return */
- if (ex && (flag != EXT4_GET_BLOCKS_DIO_CREATE_EXT)
+ if (ex && !(flag & EXT4_GET_BLOCKS_PRE_IO)
&& ext4_can_extents_be_merged(inode, ex, newext)) {
ext_debug("append [%d]%d block to %d:[%d]%d (from %llu)\n",
ext4_ext_is_uninitialized(newext),
@@ -1739,7 +1830,7 @@ has_space:
merge:
/* try to merge extents to the right */
- if (flag != EXT4_GET_BLOCKS_DIO_CREATE_EXT)
+ if (!(flag & EXT4_GET_BLOCKS_PRE_IO))
ext4_ext_try_to_merge(inode, path, nearex);
/* try to merge extents to the left */
@@ -1787,7 +1878,11 @@ int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
}
depth = ext_depth(inode);
- BUG_ON(path[depth].p_hdr == NULL);
+ if (unlikely(path[depth].p_hdr == NULL)) {
+ EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
+ err = -EIO;
+ break;
+ }
ex = path[depth].p_ext;
next = ext4_ext_next_allocated_block(path);
@@ -1838,7 +1933,11 @@ int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
cbex.ec_type = EXT4_EXT_CACHE_EXTENT;
}
- BUG_ON(cbex.ec_len == 0);
+ if (unlikely(cbex.ec_len == 0)) {
+ EXT4_ERROR_INODE(inode, "cbex.ec_len == 0");
+ err = -EIO;
+ break;
+ }
err = func(inode, path, &cbex, ex, cbdata);
ext4_ext_drop_refs(path);
@@ -1952,7 +2051,7 @@ ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP &&
cex->ec_type != EXT4_EXT_CACHE_EXTENT);
- if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) {
+ if (in_range(block, cex->ec_block, cex->ec_len)) {
ex->ee_block = cpu_to_le32(cex->ec_block);
ext4_ext_store_pblock(ex, cex->ec_start);
ex->ee_len = cpu_to_le16(cex->ec_len);
@@ -1981,7 +2080,10 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
/* free index block */
path--;
leaf = idx_pblock(path->p_idx);
- BUG_ON(path->p_hdr->eh_entries == 0);
+ if (unlikely(path->p_hdr->eh_entries == 0)) {
+ EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0");
+ return -EIO;
+ }
err = ext4_ext_get_access(handle, inode, path);
if (err)
return err;
@@ -2119,8 +2221,10 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
if (!path[depth].p_hdr)
path[depth].p_hdr = ext_block_hdr(path[depth].p_bh);
eh = path[depth].p_hdr;
- BUG_ON(eh == NULL);
-
+ if (unlikely(path[depth].p_hdr == NULL)) {
+ EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
+ return -EIO;
+ }
/* find where to start removing */
ex = EXT_LAST_EXTENT(eh);
@@ -2983,7 +3087,7 @@ fix_extent_len:
ext4_ext_dirty(handle, inode, path + depth);
return err;
}
-static int ext4_convert_unwritten_extents_dio(handle_t *handle,
+static int ext4_convert_unwritten_extents_endio(handle_t *handle,
struct inode *inode,
struct ext4_ext_path *path)
{
@@ -3063,8 +3167,8 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
flags, allocated);
ext4_ext_show_leaf(inode, path);
- /* DIO get_block() before submit the IO, split the extent */
- if (flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) {
+ /* get_block() before submit the IO, split the extent */
+ if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
ret = ext4_split_unwritten_extents(handle,
inode, path, iblock,
max_blocks, flags);
@@ -3074,14 +3178,16 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
* completed
*/
if (io)
- io->flag = DIO_AIO_UNWRITTEN;
+ io->flag = EXT4_IO_UNWRITTEN;
else
- EXT4_I(inode)->i_state |= EXT4_STATE_DIO_UNWRITTEN;
+ ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN);
+ if (ext4_should_dioread_nolock(inode))
+ set_buffer_uninit(bh_result);
goto out;
}
- /* async DIO end_io complete, convert the filled extent to written */
- if (flags == EXT4_GET_BLOCKS_DIO_CONVERT_EXT) {
- ret = ext4_convert_unwritten_extents_dio(handle, inode,
+ /* IO end_io complete, convert the filled extent to written */
+ if ((flags & EXT4_GET_BLOCKS_CONVERT)) {
+ ret = ext4_convert_unwritten_extents_endio(handle, inode,
path);
if (ret >= 0)
ext4_update_inode_fsync_trans(handle, inode, 1);
@@ -3185,7 +3291,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
{
struct ext4_ext_path *path = NULL;
struct ext4_extent_header *eh;
- struct ext4_extent newex, *ex;
+ struct ext4_extent newex, *ex, *last_ex;
ext4_fsblk_t newblock;
int err = 0, depth, ret, cache_type;
unsigned int allocated = 0;
@@ -3237,10 +3343,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
* this situation is possible, though, _during_ tree modification;
* this is why assert can't be put in ext4_ext_find_extent()
*/
- if (path[depth].p_ext == NULL && depth != 0) {
- ext4_error(inode->i_sb, __func__, "bad extent address "
- "inode: %lu, iblock: %d, depth: %d",
- inode->i_ino, iblock, depth);
+ if (unlikely(path[depth].p_ext == NULL && depth != 0)) {
+ EXT4_ERROR_INODE(inode, "bad extent address "
+ "iblock: %d, depth: %d pblock %lld",
+ iblock, depth, path[depth].p_block);
err = -EIO;
goto out2;
}
@@ -3258,7 +3364,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
*/
ee_len = ext4_ext_get_actual_len(ex);
/* if found extent covers block, simply return it */
- if (iblock >= ee_block && iblock < ee_block + ee_len) {
+ if (in_range(iblock, ee_block, ee_len)) {
newblock = iblock - ee_block + ee_start;
/* number of remaining blocks in the extent */
allocated = ee_len - (iblock - ee_block);
@@ -3350,21 +3456,35 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
if (flags & EXT4_GET_BLOCKS_UNINIT_EXT){
ext4_ext_mark_uninitialized(&newex);
/*
- * io_end structure was created for every async
- * direct IO write to the middle of the file.
- * To avoid unecessary convertion for every aio dio rewrite
- * to the mid of file, here we flag the IO that is really
- * need the convertion.
+ * io_end structure was created for every IO write to an
+ * uninitialized extent. To avoid unecessary conversion,
+ * here we flag the IO that really needs the conversion.
* For non asycn direct IO case, flag the inode state
* that we need to perform convertion when IO is done.
*/
- if (flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) {
+ if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
if (io)
- io->flag = DIO_AIO_UNWRITTEN;
+ io->flag = EXT4_IO_UNWRITTEN;
else
- EXT4_I(inode)->i_state |=
- EXT4_STATE_DIO_UNWRITTEN;;
+ ext4_set_inode_state(inode,
+ EXT4_STATE_DIO_UNWRITTEN);
+ }
+ if (ext4_should_dioread_nolock(inode))
+ set_buffer_uninit(bh_result);
+ }
+
+ if (unlikely(EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL)) {
+ if (unlikely(!eh->eh_entries)) {
+ EXT4_ERROR_INODE(inode,
+ "eh->eh_entries == 0 ee_block %d",
+ ex->ee_block);
+ err = -EIO;
+ goto out2;
}
+ last_ex = EXT_LAST_EXTENT(eh);
+ if (iblock + ar.len > le32_to_cpu(last_ex->ee_block)
+ + ext4_ext_get_actual_len(last_ex))
+ EXT4_I(inode)->i_flags &= ~EXT4_EOFBLOCKS_FL;
}
err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
if (err) {
@@ -3499,6 +3619,13 @@ static void ext4_falloc_update_inode(struct inode *inode,
i_size_write(inode, new_size);
if (new_size > EXT4_I(inode)->i_disksize)
ext4_update_i_disksize(inode, new_size);
+ } else {
+ /*
+ * Mark that we allocate beyond EOF so the subsequent truncate
+ * can proceed even if the new size is the same as i_size.
+ */
+ if (new_size > i_size_read(inode))
+ EXT4_I(inode)->i_flags |= EXT4_EOFBLOCKS_FL;
}
}
@@ -3603,7 +3730,7 @@ retry:
* Returns 0 on success.
*/
int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
- loff_t len)
+ ssize_t len)
{
handle_t *handle;
ext4_lblk_t block;
@@ -3635,7 +3762,7 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
map_bh.b_state = 0;
ret = ext4_get_blocks(handle, inode, block,
max_blocks, &map_bh,
- EXT4_GET_BLOCKS_DIO_CONVERT_EXT);
+ EXT4_GET_BLOCKS_IO_CONVERT_EXT);
if (ret <= 0) {
WARN_ON(ret <= 0);
printk(KERN_ERR "%s: ext4_ext_get_blocks "
@@ -3739,7 +3866,7 @@ static int ext4_xattr_fiemap(struct inode *inode,
int error = 0;
/* in-inode? */
- if (EXT4_I(inode)->i_state & EXT4_STATE_XATTR) {
+ if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
struct ext4_iloc iloc;
int offset; /* offset of xattr in inode */
@@ -3752,6 +3879,7 @@ static int ext4_xattr_fiemap(struct inode *inode,
physical += offset;
length = EXT4_SB(inode->i_sb)->s_inode_size - offset;
flags |= FIEMAP_EXTENT_DATA_INLINE;
+ brelse(iloc.bh);
} else { /* external block */
physical = EXT4_I(inode)->i_file_acl << blockbits;
length = inode->i_sb->s_blocksize;
@@ -3767,7 +3895,6 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
__u64 start, __u64 len)
{
ext4_lblk_t start_blk;
- ext4_lblk_t len_blks;
int error = 0;
/* fallback to generic here if not in extents fmt */
@@ -3781,8 +3908,14 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) {
error = ext4_xattr_fiemap(inode, fieinfo);
} else {
+ ext4_lblk_t len_blks;
+ __u64 last_blk;
+
start_blk = start >> inode->i_sb->s_blocksize_bits;
- len_blks = len >> inode->i_sb->s_blocksize_bits;
+ last_blk = (start + len - 1) >> inode->i_sb->s_blocksize_bits;
+ if (last_blk >= EXT_MAX_BLOCK)
+ last_blk = EXT_MAX_BLOCK-1;
+ len_blks = ((ext4_lblk_t) last_blk) - start_blk + 1;
/*
* Walk the extent tree gathering extent information.
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 56eee3d796c..d0776e410f3 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -23,6 +23,7 @@
#include <linux/jbd2.h>
#include <linux/mount.h>
#include <linux/path.h>
+#include <linux/quotaops.h>
#include "ext4.h"
#include "ext4_jbd2.h"
#include "xattr.h"
@@ -35,9 +36,9 @@
*/
static int ext4_release_file(struct inode *inode, struct file *filp)
{
- if (EXT4_I(inode)->i_state & EXT4_STATE_DA_ALLOC_CLOSE) {
+ if (ext4_test_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE)) {
ext4_alloc_da_blocks(inode);
- EXT4_I(inode)->i_state &= ~EXT4_STATE_DA_ALLOC_CLOSE;
+ ext4_clear_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE);
}
/* if we are the last writer on the inode, drop the block reservation */
if ((filp->f_mode & FMODE_WRITE) &&
@@ -125,7 +126,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
sb->s_dirt = 1;
}
}
- return generic_file_open(inode, filp);
+ return dquot_file_open(inode, filp);
}
const struct file_operations ext4_file_operations = {
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 98bd140aad0..0d0c3239c1c 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -63,7 +63,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
if (inode->i_sb->s_flags & MS_RDONLY)
return 0;
- ret = flush_aio_dio_completed_IO(inode);
+ ret = flush_completed_IO(inode);
if (ret < 0)
return ret;
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index f3624ead4f6..57f6eef6ccd 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -76,8 +76,7 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
/* If checksum is bad mark all blocks and inodes use to prevent
* allocation, essentially implementing a per-group read-only flag. */
if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
- ext4_error(sb, __func__, "Checksum bad for group %u",
- block_group);
+ ext4_error(sb, "Checksum bad for group %u", block_group);
ext4_free_blks_set(sb, gdp, 0);
ext4_free_inodes_set(sb, gdp, 0);
ext4_itable_unused_set(sb, gdp, 0);
@@ -111,8 +110,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
bitmap_blk = ext4_inode_bitmap(sb, desc);
bh = sb_getblk(sb, bitmap_blk);
if (unlikely(!bh)) {
- ext4_error(sb, __func__,
- "Cannot read inode bitmap - "
+ ext4_error(sb, "Cannot read inode bitmap - "
"block_group = %u, inode_bitmap = %llu",
block_group, bitmap_blk);
return NULL;
@@ -153,8 +151,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
set_bitmap_uptodate(bh);
if (bh_submit_read(bh) < 0) {
put_bh(bh);
- ext4_error(sb, __func__,
- "Cannot read inode bitmap - "
+ ext4_error(sb, "Cannot read inode bitmap - "
"block_group = %u, inode_bitmap = %llu",
block_group, bitmap_blk);
return NULL;
@@ -217,10 +214,10 @@ void ext4_free_inode(handle_t *handle, 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.
*/
- vfs_dq_init(inode);
+ dquot_initialize(inode);
ext4_xattr_delete_inode(handle, inode);
- vfs_dq_free_inode(inode);
- vfs_dq_drop(inode);
+ dquot_free_inode(inode);
+ dquot_drop(inode);
is_directory = S_ISDIR(inode->i_mode);
@@ -229,8 +226,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
es = EXT4_SB(sb)->s_es;
if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
- ext4_error(sb, "ext4_free_inode",
- "reserved or nonexistent inode %lu", ino);
+ ext4_error(sb, "reserved or nonexistent inode %lu", ino);
goto error_return;
}
block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
@@ -248,8 +244,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
cleared = ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
bit, bitmap_bh->b_data);
if (!cleared)
- ext4_error(sb, "ext4_free_inode",
- "bit already cleared for inode %lu", ino);
+ ext4_error(sb, "bit already cleared for inode %lu", ino);
else {
gdp = ext4_get_group_desc(sb, block_group, &bh2);
@@ -268,7 +263,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
ext4_group_t f;
f = ext4_flex_group(sbi, block_group);
- atomic_dec(&sbi->s_flex_groups[f].free_inodes);
+ atomic_dec(&sbi->s_flex_groups[f].used_dirs);
}
}
@@ -736,8 +731,7 @@ static int ext4_claim_inode(struct super_block *sb,
if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
ino > EXT4_INODES_PER_GROUP(sb)) {
ext4_unlock_group(sb, group);
- ext4_error(sb, __func__,
- "reserved inode or inode > inodes count - "
+ ext4_error(sb, "reserved inode or inode > inodes count - "
"block_group = %u, inode=%lu", group,
ino + group * EXT4_INODES_PER_GROUP(sb));
return 1;
@@ -779,7 +773,7 @@ static int ext4_claim_inode(struct super_block *sb,
if (sbi->s_log_groups_per_flex) {
ext4_group_t f = ext4_flex_group(sbi, group);
- atomic_inc(&sbi->s_flex_groups[f].free_inodes);
+ atomic_inc(&sbi->s_flex_groups[f].used_dirs);
}
}
gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
@@ -904,7 +898,7 @@ repeat_in_this_group:
BUFFER_TRACE(inode_bitmap_bh,
"call ext4_handle_dirty_metadata");
err = ext4_handle_dirty_metadata(handle,
- inode,
+ NULL,
inode_bitmap_bh);
if (err)
goto fail;
@@ -1029,15 +1023,16 @@ got:
inode->i_generation = sbi->s_next_generation++;
spin_unlock(&sbi->s_next_gen_lock);
- ei->i_state = EXT4_STATE_NEW;
+ ei->i_state_flags = 0;
+ ext4_set_inode_state(inode, EXT4_STATE_NEW);
ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
ret = inode;
- if (vfs_dq_alloc_inode(inode)) {
- err = -EDQUOT;
+ dquot_initialize(inode);
+ err = dquot_alloc_inode(inode);
+ if (err)
goto fail_drop;
- }
err = ext4_init_acl(handle, inode, dir);
if (err)
@@ -1074,10 +1069,10 @@ really_out:
return ret;
fail_free_drop:
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
fail_drop:
- vfs_dq_drop(inode);
+ dquot_drop(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
unlock_new_inode(inode);
@@ -1098,8 +1093,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
/* Error cases - e2fsck has already cleaned up for us */
if (ino > max_ino) {
- ext4_warning(sb, __func__,
- "bad orphan ino %lu! e2fsck was run?", ino);
+ ext4_warning(sb, "bad orphan ino %lu! e2fsck was run?", ino);
goto error;
}
@@ -1107,8 +1101,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
if (!bitmap_bh) {
- ext4_warning(sb, __func__,
- "inode bitmap error for orphan %lu", ino);
+ ext4_warning(sb, "inode bitmap error for orphan %lu", ino);
goto error;
}
@@ -1140,8 +1133,7 @@ iget_failed:
err = PTR_ERR(inode);
inode = NULL;
bad_orphan:
- ext4_warning(sb, __func__,
- "bad orphan inode %lu! e2fsck was run?", ino);
+ ext4_warning(sb, "bad orphan inode %lu! e2fsck was run?", ino);
printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n",
bit, (unsigned long long)bitmap_bh->b_blocknr,
ext4_test_bit(bit, bitmap_bh->b_data));
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index e11952404e0..81d60541284 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -38,6 +38,8 @@
#include <linux/uio.h>
#include <linux/bio.h>
#include <linux/workqueue.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
#include "ext4_jbd2.h"
#include "xattr.h"
@@ -170,6 +172,9 @@ void ext4_delete_inode(struct inode *inode)
handle_t *handle;
int err;
+ if (!is_bad_inode(inode))
+ dquot_initialize(inode);
+
if (ext4_should_order_data(inode))
ext4_begin_ordered_truncate(inode, 0);
truncate_inode_pages(&inode->i_data, 0);
@@ -194,7 +199,7 @@ void ext4_delete_inode(struct inode *inode)
inode->i_size = 0;
err = ext4_mark_inode_dirty(handle, inode);
if (err) {
- ext4_warning(inode->i_sb, __func__,
+ ext4_warning(inode->i_sb,
"couldn't mark inode dirty (err %d)", err);
goto stop_handle;
}
@@ -212,7 +217,7 @@ void ext4_delete_inode(struct inode *inode)
if (err > 0)
err = ext4_journal_restart(handle, 3);
if (err != 0) {
- ext4_warning(inode->i_sb, __func__,
+ ext4_warning(inode->i_sb,
"couldn't extend journal (err %d)", err);
stop_handle:
ext4_journal_stop(handle);
@@ -323,8 +328,7 @@ static int ext4_block_to_path(struct inode *inode,
offsets[n++] = i_block & (ptrs - 1);
final = ptrs;
} else {
- ext4_warning(inode->i_sb, "ext4_block_to_path",
- "block %lu > max in inode %lu",
+ ext4_warning(inode->i_sb, "block %lu > max in inode %lu",
i_block + direct_blocks +
indirect_blocks + double_blocks, inode->i_ino);
}
@@ -344,7 +348,7 @@ static int __ext4_check_blockref(const char *function, struct inode *inode,
if (blk &&
unlikely(!ext4_data_block_valid(EXT4_SB(inode->i_sb),
blk, 1))) {
- ext4_error(inode->i_sb, function,
+ __ext4_error(inode->i_sb, function,
"invalid block reference %u "
"in inode #%lu", blk, inode->i_ino);
return -EIO;
@@ -607,7 +611,14 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
if (*err)
goto failed_out;
- BUG_ON(current_block + count > EXT4_MAX_BLOCK_FILE_PHYS);
+ if (unlikely(current_block + count > EXT4_MAX_BLOCK_FILE_PHYS)) {
+ EXT4_ERROR_INODE(inode,
+ "current_block %llu + count %lu > %d!",
+ current_block, count,
+ EXT4_MAX_BLOCK_FILE_PHYS);
+ *err = -EIO;
+ goto failed_out;
+ }
target -= count;
/* allocate blocks for indirect blocks */
@@ -643,7 +654,14 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
ar.flags = EXT4_MB_HINT_DATA;
current_block = ext4_mb_new_blocks(handle, &ar, err);
- BUG_ON(current_block + ar.len > EXT4_MAX_BLOCK_FILE_PHYS);
+ if (unlikely(current_block + ar.len > EXT4_MAX_BLOCK_FILE_PHYS)) {
+ EXT4_ERROR_INODE(inode,
+ "current_block %llu + ar.len %d > %d!",
+ current_block, ar.len,
+ EXT4_MAX_BLOCK_FILE_PHYS);
+ *err = -EIO;
+ goto failed_out;
+ }
if (*err && (target == blks)) {
/*
@@ -1018,7 +1036,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode,
sector_t lblock)
{
struct ext4_inode_info *ei = EXT4_I(inode);
- int dind_mask = EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1;
+ sector_t dind_mask = ~((sector_t)EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1);
int blk_bits;
if (lblock < EXT4_NDIR_BLOCKS)
@@ -1033,7 +1051,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode,
}
ei->i_da_metadata_calc_last_lblock = lblock & dind_mask;
ei->i_da_metadata_calc_len = 1;
- blk_bits = roundup_pow_of_two(lblock + 1);
+ blk_bits = order_base_2(lblock);
return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1;
}
@@ -1061,6 +1079,7 @@ void ext4_da_update_reserve_space(struct inode *inode,
int mdb_free = 0, allocated_meta_blocks = 0;
spin_lock(&ei->i_block_reservation_lock);
+ trace_ext4_da_update_reserve_space(inode, used);
if (unlikely(used > ei->i_reserved_data_blocks)) {
ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, used %d "
"with only %d reserved data blocks\n",
@@ -1093,9 +1112,9 @@ void ext4_da_update_reserve_space(struct inode *inode,
/* Update quota subsystem */
if (quota_claim) {
- vfs_dq_claim_block(inode, used);
+ dquot_claim_block(inode, used);
if (mdb_free)
- vfs_dq_release_reservation_block(inode, mdb_free);
+ dquot_release_reservation_block(inode, mdb_free);
} else {
/*
* We did fallocate with an offset that is already delayed
@@ -1106,8 +1125,8 @@ void ext4_da_update_reserve_space(struct inode *inode,
* that
*/
if (allocated_meta_blocks)
- vfs_dq_claim_block(inode, allocated_meta_blocks);
- vfs_dq_release_reservation_block(inode, mdb_free + used);
+ dquot_claim_block(inode, allocated_meta_blocks);
+ dquot_release_reservation_block(inode, mdb_free + used);
}
/*
@@ -1124,7 +1143,7 @@ static int check_block_validity(struct inode *inode, const char *msg,
sector_t logical, sector_t phys, int len)
{
if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), phys, len)) {
- ext4_error(inode->i_sb, msg,
+ __ext4_error(inode->i_sb, msg,
"inode #%lu logical block %llu mapped to %llu "
"(size %d)", inode->i_ino,
(unsigned long long) logical,
@@ -1306,7 +1325,7 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
* i_data's format changing. Force the migrate
* to fail by clearing migrate flags
*/
- EXT4_I(inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE;
+ ext4_clear_inode_state(inode, EXT4_STATE_EXT_MIGRATE);
}
/*
@@ -1534,6 +1553,8 @@ static void ext4_truncate_failed_write(struct inode *inode)
ext4_truncate(inode);
}
+static int ext4_get_block_write(struct inode *inode, sector_t iblock,
+ struct buffer_head *bh_result, int create);
static int ext4_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
@@ -1575,8 +1596,12 @@ retry:
}
*pagep = page;
- ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- ext4_get_block);
+ if (ext4_should_dioread_nolock(inode))
+ ret = block_write_begin(file, mapping, pos, len, flags, pagep,
+ fsdata, ext4_get_block_write);
+ else
+ ret = block_write_begin(file, mapping, pos, len, flags, pagep,
+ fsdata, ext4_get_block);
if (!ret && ext4_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
@@ -1793,7 +1818,7 @@ static int ext4_journalled_write_end(struct file *file,
new_i_size = pos + copied;
if (new_i_size > inode->i_size)
i_size_write(inode, pos+copied);
- EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
+ ext4_set_inode_state(inode, EXT4_STATE_JDATA);
if (new_i_size > EXT4_I(inode)->i_disksize) {
ext4_update_i_disksize(inode, new_i_size);
ret2 = ext4_mark_inode_dirty(handle, inode);
@@ -1836,6 +1861,7 @@ static int ext4_da_reserve_space(struct inode *inode, sector_t lblock)
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct ext4_inode_info *ei = EXT4_I(inode);
unsigned long md_needed, md_reserved;
+ int ret;
/*
* recalculate the amount of metadata blocks to reserve
@@ -1846,6 +1872,7 @@ repeat:
spin_lock(&ei->i_block_reservation_lock);
md_reserved = ei->i_reserved_meta_blocks;
md_needed = ext4_calc_metadata_amount(inode, lblock);
+ trace_ext4_da_reserve_space(inode, md_needed);
spin_unlock(&ei->i_block_reservation_lock);
/*
@@ -1853,11 +1880,12 @@ repeat:
* later. Real quota accounting is done at pages writeout
* time.
*/
- if (vfs_dq_reserve_block(inode, md_needed + 1))
- return -EDQUOT;
+ ret = dquot_reserve_block(inode, md_needed + 1);
+ if (ret)
+ return ret;
if (ext4_claim_free_blocks(sbi, md_needed + 1)) {
- vfs_dq_release_reservation_block(inode, md_needed + 1);
+ dquot_release_reservation_block(inode, md_needed + 1);
if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
yield();
goto repeat;
@@ -1914,7 +1942,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
- vfs_dq_release_reservation_block(inode, to_free);
+ dquot_release_reservation_block(inode, to_free);
}
static void ext4_da_page_release_reservation(struct page *page,
@@ -2091,6 +2119,8 @@ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical,
} else if (buffer_mapped(bh))
BUG_ON(bh->b_blocknr != pblock);
+ if (buffer_uninit(exbh))
+ set_buffer_uninit(bh);
cur_logical++;
pblock++;
} while ((bh = bh->b_this_page) != head);
@@ -2133,17 +2163,16 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd,
break;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
- index = page->index;
- if (index > end)
+ if (page->index > end)
break;
- index++;
-
BUG_ON(!PageLocked(page));
BUG_ON(PageWriteback(page));
block_invalidatepage(page, 0);
ClearPageUptodate(page);
unlock_page(page);
}
+ index = pvec.pages[nr_pages - 1]->index + 1;
+ pagevec_release(&pvec);
}
return;
}
@@ -2220,6 +2249,8 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
*/
new.b_state = 0;
get_blocks_flags = EXT4_GET_BLOCKS_CREATE;
+ if (ext4_should_dioread_nolock(mpd->inode))
+ get_blocks_flags |= EXT4_GET_BLOCKS_IO_CREATE_EXT;
if (mpd->b_state & (1 << BH_Delay))
get_blocks_flags |= EXT4_GET_BLOCKS_DELALLOC_RESERVE;
@@ -2630,11 +2661,14 @@ static int __ext4_journalled_writepage(struct page *page,
ret = err;
walk_page_buffers(handle, page_bufs, 0, len, NULL, bput_one);
- EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
+ ext4_set_inode_state(inode, EXT4_STATE_JDATA);
out:
return ret;
}
+static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode);
+static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
+
/*
* Note that we don't need to start a transaction unless we're journaling data
* because we should have holes filled from ext4_page_mkwrite(). We even don't
@@ -2682,7 +2716,7 @@ static int ext4_writepage(struct page *page,
int ret = 0;
loff_t size;
unsigned int len;
- struct buffer_head *page_bufs;
+ struct buffer_head *page_bufs = NULL;
struct inode *inode = page->mapping->host;
trace_ext4_writepage(inode, page);
@@ -2758,7 +2792,11 @@ static int ext4_writepage(struct page *page,
if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
ret = nobh_writepage(page, noalloc_get_block_write, wbc);
- else
+ else if (page_bufs && buffer_uninit(page_bufs)) {
+ ext4_set_bh_endio(page_bufs, inode);
+ ret = block_write_full_page_endio(page, noalloc_get_block_write,
+ wbc, ext4_end_io_buffer_write);
+ } else
ret = block_write_full_page(page, noalloc_get_block_write,
wbc);
@@ -3301,7 +3339,8 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
filemap_write_and_wait(mapping);
}
- if (EXT4_JOURNAL(inode) && EXT4_I(inode)->i_state & EXT4_STATE_JDATA) {
+ if (EXT4_JOURNAL(inode) &&
+ ext4_test_inode_state(inode, EXT4_STATE_JDATA)) {
/*
* This is a REALLY heavyweight approach, but the use of
* bmap on dirty files is expected to be extremely rare:
@@ -3320,7 +3359,7 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
* everything they get.
*/
- EXT4_I(inode)->i_state &= ~EXT4_STATE_JDATA;
+ ext4_clear_inode_state(inode, EXT4_STATE_JDATA);
journal = EXT4_JOURNAL(inode);
jbd2_journal_lock_updates(journal);
err = jbd2_journal_flush(journal);
@@ -3345,11 +3384,45 @@ ext4_readpages(struct file *file, struct address_space *mapping,
return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
}
+static void ext4_free_io_end(ext4_io_end_t *io)
+{
+ BUG_ON(!io);
+ if (io->page)
+ put_page(io->page);
+ iput(io->inode);
+ kfree(io);
+}
+
+static void ext4_invalidatepage_free_endio(struct page *page, unsigned long offset)
+{
+ struct buffer_head *head, *bh;
+ unsigned int curr_off = 0;
+
+ if (!page_has_buffers(page))
+ return;
+ head = bh = page_buffers(page);
+ do {
+ if (offset <= curr_off && test_clear_buffer_uninit(bh)
+ && bh->b_private) {
+ ext4_free_io_end(bh->b_private);
+ bh->b_private = NULL;
+ bh->b_end_io = NULL;
+ }
+ curr_off = curr_off + bh->b_size;
+ bh = bh->b_this_page;
+ } while (bh != head);
+}
+
static void ext4_invalidatepage(struct page *page, unsigned long offset)
{
journal_t *journal = EXT4_JOURNAL(page->mapping->host);
/*
+ * free any io_end structure allocated for buffers to be discarded
+ */
+ if (ext4_should_dioread_nolock(page->mapping->host))
+ ext4_invalidatepage_free_endio(page, offset);
+ /*
* If it's a full truncate we just forget about the pending dirtying
*/
if (offset == 0)
@@ -3420,7 +3493,14 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
}
retry:
- ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ if (rw == READ && ext4_should_dioread_nolock(inode))
+ ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
+ inode->i_sb->s_bdev, iov,
+ offset, nr_segs,
+ ext4_get_block, NULL);
+ else
+ ret = blockdev_direct_IO(rw, iocb, inode,
+ inode->i_sb->s_bdev, iov,
offset, nr_segs,
ext4_get_block, NULL);
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
@@ -3436,6 +3516,9 @@ retry:
* but cannot extend i_size. Bail out and pretend
* the write failed... */
ret = PTR_ERR(handle);
+ if (inode->i_nlink)
+ ext4_orphan_del(NULL, inode);
+
goto out;
}
if (inode->i_nlink)
@@ -3463,75 +3546,63 @@ out:
return ret;
}
-static int ext4_get_block_dio_write(struct inode *inode, sector_t iblock,
+static int ext4_get_block_write(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
- handle_t *handle = NULL;
+ handle_t *handle = ext4_journal_current_handle();
int ret = 0;
unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
int dio_credits;
+ int started = 0;
- ext4_debug("ext4_get_block_dio_write: inode %lu, create flag %d\n",
+ ext4_debug("ext4_get_block_write: inode %lu, create flag %d\n",
inode->i_ino, create);
/*
- * DIO VFS code passes create = 0 flag for write to
- * the middle of file. It does this to avoid block
- * allocation for holes, to prevent expose stale data
- * out when there is parallel buffered read (which does
- * not hold the i_mutex lock) while direct IO write has
- * not completed. DIO request on holes finally falls back
- * to buffered IO for this reason.
- *
- * For ext4 extent based file, since we support fallocate,
- * new allocated extent as uninitialized, for holes, we
- * could fallocate blocks for holes, thus parallel
- * buffered IO read will zero out the page when read on
- * a hole while parallel DIO write to the hole has not completed.
- *
- * when we come here, we know it's a direct IO write to
- * to the middle of file (<i_size)
- * so it's safe to override the create flag from VFS.
+ * ext4_get_block in prepare for a DIO write or buffer write.
+ * We allocate an uinitialized extent if blocks haven't been allocated.
+ * The extent will be converted to initialized after IO complete.
*/
- create = EXT4_GET_BLOCKS_DIO_CREATE_EXT;
+ create = EXT4_GET_BLOCKS_IO_CREATE_EXT;
- if (max_blocks > DIO_MAX_BLOCKS)
- max_blocks = DIO_MAX_BLOCKS;
- dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
- handle = ext4_journal_start(inode, dio_credits);
- if (IS_ERR(handle)) {
- ret = PTR_ERR(handle);
- goto out;
+ if (!handle) {
+ if (max_blocks > DIO_MAX_BLOCKS)
+ max_blocks = DIO_MAX_BLOCKS;
+ dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
+ handle = ext4_journal_start(inode, dio_credits);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ goto out;
+ }
+ started = 1;
}
+
ret = ext4_get_blocks(handle, inode, iblock, max_blocks, bh_result,
create);
if (ret > 0) {
bh_result->b_size = (ret << inode->i_blkbits);
ret = 0;
}
- ext4_journal_stop(handle);
+ if (started)
+ ext4_journal_stop(handle);
out:
return ret;
}
-static void ext4_free_io_end(ext4_io_end_t *io)
-{
- BUG_ON(!io);
- iput(io->inode);
- kfree(io);
-}
-static void dump_aio_dio_list(struct inode * inode)
+static void dump_completed_IO(struct inode * inode)
{
#ifdef EXT4_DEBUG
struct list_head *cur, *before, *after;
ext4_io_end_t *io, *io0, *io1;
+ unsigned long flags;
- if (list_empty(&EXT4_I(inode)->i_aio_dio_complete_list)){
- ext4_debug("inode %lu aio dio list is empty\n", inode->i_ino);
+ if (list_empty(&EXT4_I(inode)->i_completed_io_list)){
+ ext4_debug("inode %lu completed_io list is empty\n", inode->i_ino);
return;
}
- ext4_debug("Dump inode %lu aio_dio_completed_IO list \n", inode->i_ino);
- list_for_each_entry(io, &EXT4_I(inode)->i_aio_dio_complete_list, list){
+ ext4_debug("Dump inode %lu completed_io list \n", inode->i_ino);
+ spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
+ list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list){
cur = &io->list;
before = cur->prev;
io0 = container_of(before, ext4_io_end_t, list);
@@ -3541,32 +3612,31 @@ static void dump_aio_dio_list(struct inode * inode)
ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
io, inode->i_ino, io0, io1);
}
+ spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
#endif
}
/*
* check a range of space and convert unwritten extents to written.
*/
-static int ext4_end_aio_dio_nolock(ext4_io_end_t *io)
+static int ext4_end_io_nolock(ext4_io_end_t *io)
{
struct inode *inode = io->inode;
loff_t offset = io->offset;
- size_t size = io->size;
+ ssize_t size = io->size;
int ret = 0;
- ext4_debug("end_aio_dio_onlock: io 0x%p from inode %lu,list->next 0x%p,"
+ ext4_debug("ext4_end_io_nolock: io 0x%p from inode %lu,list->next 0x%p,"
"list->prev 0x%p\n",
io, inode->i_ino, io->list.next, io->list.prev);
if (list_empty(&io->list))
return ret;
- if (io->flag != DIO_AIO_UNWRITTEN)
+ if (io->flag != EXT4_IO_UNWRITTEN)
return ret;
- if (offset + size <= i_size_read(inode))
- ret = ext4_convert_unwritten_extents(inode, offset, size);
-
+ ret = ext4_convert_unwritten_extents(inode, offset, size);
if (ret < 0) {
printk(KERN_EMERG "%s: failed to convert unwritten"
"extents to written extents, error is %d"
@@ -3579,50 +3649,64 @@ static int ext4_end_aio_dio_nolock(ext4_io_end_t *io)
io->flag = 0;
return ret;
}
+
/*
* work on completed aio dio IO, to convert unwritten extents to extents
*/
-static void ext4_end_aio_dio_work(struct work_struct *work)
+static void ext4_end_io_work(struct work_struct *work)
{
- ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
- struct inode *inode = io->inode;
- int ret = 0;
+ ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
+ struct inode *inode = io->inode;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ unsigned long flags;
+ int ret;
mutex_lock(&inode->i_mutex);
- ret = ext4_end_aio_dio_nolock(io);
- if (ret >= 0) {
- if (!list_empty(&io->list))
- list_del_init(&io->list);
- ext4_free_io_end(io);
+ ret = ext4_end_io_nolock(io);
+ if (ret < 0) {
+ mutex_unlock(&inode->i_mutex);
+ return;
}
+
+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+ if (!list_empty(&io->list))
+ list_del_init(&io->list);
+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
mutex_unlock(&inode->i_mutex);
+ ext4_free_io_end(io);
}
+
/*
* This function is called from ext4_sync_file().
*
- * When AIO DIO IO is completed, the work to convert unwritten
- * extents to written is queued on workqueue but may not get immediately
+ * When IO is completed, the work to convert unwritten extents to
+ * written is queued on workqueue but may not get immediately
* scheduled. When fsync is called, we need to ensure the
* conversion is complete before fsync returns.
- * The inode keeps track of a list of completed AIO from DIO path
- * that might needs to do the conversion. This function walks through
- * the list and convert the related unwritten extents to written.
+ * The inode keeps track of a list of pending/completed IO that
+ * might needs to do the conversion. This function walks through
+ * the list and convert the related unwritten extents for completed IO
+ * to written.
+ * The function return the number of pending IOs on success.
*/
-int flush_aio_dio_completed_IO(struct inode *inode)
+int flush_completed_IO(struct inode *inode)
{
ext4_io_end_t *io;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ unsigned long flags;
int ret = 0;
int ret2 = 0;
- if (list_empty(&EXT4_I(inode)->i_aio_dio_complete_list))
+ if (list_empty(&ei->i_completed_io_list))
return ret;
- dump_aio_dio_list(inode);
- while (!list_empty(&EXT4_I(inode)->i_aio_dio_complete_list)){
- io = list_entry(EXT4_I(inode)->i_aio_dio_complete_list.next,
+ dump_completed_IO(inode);
+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+ while (!list_empty(&ei->i_completed_io_list)){
+ io = list_entry(ei->i_completed_io_list.next,
ext4_io_end_t, list);
/*
- * Calling ext4_end_aio_dio_nolock() to convert completed
+ * Calling ext4_end_io_nolock() to convert completed
* IO to written.
*
* When ext4_sync_file() is called, run_queue() may already
@@ -3635,20 +3719,23 @@ int flush_aio_dio_completed_IO(struct inode *inode)
* avoid double converting from both fsync and background work
* queue work.
*/
- ret = ext4_end_aio_dio_nolock(io);
+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
+ ret = ext4_end_io_nolock(io);
+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
if (ret < 0)
ret2 = ret;
else
list_del_init(&io->list);
}
+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
return (ret2 < 0) ? ret2 : 0;
}
-static ext4_io_end_t *ext4_init_io_end (struct inode *inode)
+static ext4_io_end_t *ext4_init_io_end (struct inode *inode, gfp_t flags)
{
ext4_io_end_t *io = NULL;
- io = kmalloc(sizeof(*io), GFP_NOFS);
+ io = kmalloc(sizeof(*io), flags);
if (io) {
igrab(inode);
@@ -3656,8 +3743,8 @@ static ext4_io_end_t *ext4_init_io_end (struct inode *inode)
io->flag = 0;
io->offset = 0;
io->size = 0;
- io->error = 0;
- INIT_WORK(&io->work, ext4_end_aio_dio_work);
+ io->page = NULL;
+ INIT_WORK(&io->work, ext4_end_io_work);
INIT_LIST_HEAD(&io->list);
}
@@ -3669,6 +3756,8 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
{
ext4_io_end_t *io_end = iocb->private;
struct workqueue_struct *wq;
+ unsigned long flags;
+ struct ext4_inode_info *ei;
/* if not async direct IO or dio with 0 bytes write, just return */
if (!io_end || !size)
@@ -3680,7 +3769,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
size);
/* if not aio dio with unwritten extents, just free io and return */
- if (io_end->flag != DIO_AIO_UNWRITTEN){
+ if (io_end->flag != EXT4_IO_UNWRITTEN){
ext4_free_io_end(io_end);
iocb->private = NULL;
return;
@@ -3688,16 +3777,85 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
io_end->offset = offset;
io_end->size = size;
+ io_end->flag = EXT4_IO_UNWRITTEN;
wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
/* queue the work to convert unwritten extents to written */
queue_work(wq, &io_end->work);
/* Add the io_end to per-inode completed aio dio list*/
- list_add_tail(&io_end->list,
- &EXT4_I(io_end->inode)->i_aio_dio_complete_list);
+ ei = EXT4_I(io_end->inode);
+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+ list_add_tail(&io_end->list, &ei->i_completed_io_list);
+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
iocb->private = NULL;
}
+
+static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
+{
+ ext4_io_end_t *io_end = bh->b_private;
+ struct workqueue_struct *wq;
+ struct inode *inode;
+ unsigned long flags;
+
+ if (!test_clear_buffer_uninit(bh) || !io_end)
+ goto out;
+
+ if (!(io_end->inode->i_sb->s_flags & MS_ACTIVE)) {
+ printk("sb umounted, discard end_io request for inode %lu\n",
+ io_end->inode->i_ino);
+ ext4_free_io_end(io_end);
+ goto out;
+ }
+
+ io_end->flag = EXT4_IO_UNWRITTEN;
+ inode = io_end->inode;
+
+ /* Add the io_end to per-inode completed io list*/
+ spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
+ list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
+ spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
+
+ wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
+ /* queue the work to convert unwritten extents to written */
+ queue_work(wq, &io_end->work);
+out:
+ bh->b_private = NULL;
+ bh->b_end_io = NULL;
+ clear_buffer_uninit(bh);
+ end_buffer_async_write(bh, uptodate);
+}
+
+static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode)
+{
+ ext4_io_end_t *io_end;
+ struct page *page = bh->b_page;
+ loff_t offset = (sector_t)page->index << PAGE_CACHE_SHIFT;
+ size_t size = bh->b_size;
+
+retry:
+ io_end = ext4_init_io_end(inode, GFP_ATOMIC);
+ if (!io_end) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING "%s: allocation fail\n", __func__);
+ schedule();
+ goto retry;
+ }
+ io_end->offset = offset;
+ io_end->size = size;
+ /*
+ * We need to hold a reference to the page to make sure it
+ * doesn't get evicted before ext4_end_io_work() has a chance
+ * to convert the extent from written to unwritten.
+ */
+ io_end->page = page;
+ get_page(io_end->page);
+
+ bh->b_private = io_end;
+ bh->b_end_io = ext4_end_io_buffer_write;
+ return 0;
+}
+
/*
* For ext4 extent files, ext4 will do direct-io write to holes,
* preallocated extents, and those write extend the file, no need to
@@ -3751,7 +3909,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
iocb->private = NULL;
EXT4_I(inode)->cur_aio_dio = NULL;
if (!is_sync_kiocb(iocb)) {
- iocb->private = ext4_init_io_end(inode);
+ iocb->private = ext4_init_io_end(inode, GFP_NOFS);
if (!iocb->private)
return -ENOMEM;
/*
@@ -3767,7 +3925,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
ret = blockdev_direct_IO(rw, iocb, inode,
inode->i_sb->s_bdev, iov,
offset, nr_segs,
- ext4_get_block_dio_write,
+ ext4_get_block_write,
ext4_end_io_dio);
if (iocb->private)
EXT4_I(inode)->cur_aio_dio = NULL;
@@ -3788,8 +3946,8 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) {
ext4_free_io_end(iocb->private);
iocb->private = NULL;
- } else if (ret > 0 && (EXT4_I(inode)->i_state &
- EXT4_STATE_DIO_UNWRITTEN)) {
+ } else if (ret > 0 && ext4_test_inode_state(inode,
+ EXT4_STATE_DIO_UNWRITTEN)) {
int err;
/*
* for non AIO case, since the IO is already
@@ -3799,7 +3957,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
offset, ret);
if (err < 0)
ret = err;
- EXT4_I(inode)->i_state &= ~EXT4_STATE_DIO_UNWRITTEN;
+ ext4_clear_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN);
}
return ret;
}
@@ -4130,18 +4288,27 @@ no_top:
* We release `count' blocks on disk, but (last - first) may be greater
* than `count' because there can be holes in there.
*/
-static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
- struct buffer_head *bh,
- ext4_fsblk_t block_to_free,
- unsigned long count, __le32 *first,
- __le32 *last)
+static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
+ struct buffer_head *bh,
+ ext4_fsblk_t block_to_free,
+ unsigned long count, __le32 *first,
+ __le32 *last)
{
__le32 *p;
- int flags = EXT4_FREE_BLOCKS_FORGET;
+ int flags = EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_VALIDATED;
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
flags |= EXT4_FREE_BLOCKS_METADATA;
+ if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), block_to_free,
+ count)) {
+ ext4_error(inode->i_sb, "inode #%lu: "
+ "attempt to clear blocks %llu len %lu, invalid",
+ inode->i_ino, (unsigned long long) block_to_free,
+ count);
+ return 1;
+ }
+
if (try_to_extend_transaction(handle, inode)) {
if (bh) {
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
@@ -4160,6 +4327,7 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
*p = 0;
ext4_free_blocks(handle, inode, 0, block_to_free, count, flags);
+ return 0;
}
/**
@@ -4215,9 +4383,10 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
} else if (nr == block_to_free + count) {
count++;
} else {
- ext4_clear_blocks(handle, inode, this_bh,
- block_to_free,
- count, block_to_free_p, p);
+ if (ext4_clear_blocks(handle, inode, this_bh,
+ block_to_free, count,
+ block_to_free_p, p))
+ break;
block_to_free = nr;
block_to_free_p = p;
count = 1;
@@ -4241,7 +4410,7 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
if ((EXT4_JOURNAL(inode) == NULL) || bh2jh(this_bh))
ext4_handle_dirty_metadata(handle, inode, this_bh);
else
- ext4_error(inode->i_sb, __func__,
+ ext4_error(inode->i_sb,
"circular indirect block detected, "
"inode=%lu, block=%llu",
inode->i_ino,
@@ -4281,6 +4450,16 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
if (!nr)
continue; /* A hole */
+ if (!ext4_data_block_valid(EXT4_SB(inode->i_sb),
+ nr, 1)) {
+ ext4_error(inode->i_sb,
+ "indirect mapped block in inode "
+ "#%lu invalid (level %d, blk #%lu)",
+ inode->i_ino, depth,
+ (unsigned long) nr);
+ break;
+ }
+
/* Go read the buffer for the next level down */
bh = sb_bread(inode->i_sb, nr);
@@ -4289,7 +4468,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
* (should be rare).
*/
if (!bh) {
- ext4_error(inode->i_sb, "ext4_free_branches",
+ ext4_error(inode->i_sb,
"Read failure, inode=%lu, block=%llu",
inode->i_ino, nr);
continue;
@@ -4433,8 +4612,10 @@ void ext4_truncate(struct inode *inode)
if (!ext4_can_truncate(inode))
return;
+ EXT4_I(inode)->i_flags &= ~EXT4_EOFBLOCKS_FL;
+
if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC))
- ei->i_state |= EXT4_STATE_DA_ALLOC_CLOSE;
+ ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE);
if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
ext4_ext_truncate(inode);
@@ -4604,9 +4785,8 @@ static int __ext4_get_inode_loc(struct inode *inode,
bh = sb_getblk(sb, block);
if (!bh) {
- ext4_error(sb, "ext4_get_inode_loc", "unable to read "
- "inode block - inode=%lu, block=%llu",
- inode->i_ino, block);
+ ext4_error(sb, "unable to read inode block - "
+ "inode=%lu, block=%llu", inode->i_ino, block);
return -EIO;
}
if (!buffer_uptodate(bh)) {
@@ -4704,9 +4884,8 @@ make_io:
submit_bh(READ_META, bh);
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
- ext4_error(sb, __func__,
- "unable to read inode block - inode=%lu, "
- "block=%llu", inode->i_ino, block);
+ ext4_error(sb, "unable to read inode block - inode=%lu,"
+ " block=%llu", inode->i_ino, block);
brelse(bh);
return -EIO;
}
@@ -4720,7 +4899,7 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
{
/* We have all inode data except xattrs in memory here. */
return __ext4_get_inode_loc(inode, iloc,
- !(EXT4_I(inode)->i_state & EXT4_STATE_XATTR));
+ !ext4_test_inode_state(inode, EXT4_STATE_XATTR));
}
void ext4_set_inode_flags(struct inode *inode)
@@ -4814,7 +4993,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
- ei->i_state = 0;
+ ei->i_state_flags = 0;
ei->i_dir_start_lookup = 0;
ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
/* We now have enough fields to check if the inode was active or not.
@@ -4897,7 +5076,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
EXT4_GOOD_OLD_INODE_SIZE +
ei->i_extra_isize;
if (*magic == cpu_to_le32(EXT4_XATTR_MAGIC))
- ei->i_state |= EXT4_STATE_XATTR;
+ ext4_set_inode_state(inode, EXT4_STATE_XATTR);
}
} else
ei->i_extra_isize = 0;
@@ -4917,8 +5096,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
ret = 0;
if (ei->i_file_acl &&
!ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
- ext4_error(sb, __func__,
- "bad extended attribute block %llu in inode #%lu",
+ ext4_error(sb, "bad extended attribute block %llu inode #%lu",
ei->i_file_acl, inode->i_ino);
ret = -EIO;
goto bad_inode;
@@ -4964,8 +5142,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
} else {
ret = -EIO;
- ext4_error(inode->i_sb, __func__,
- "bogus i_mode (%o) for inode=%lu",
+ ext4_error(inode->i_sb, "bogus i_mode (%o) for inode=%lu",
inode->i_mode, inode->i_ino);
goto bad_inode;
}
@@ -5037,7 +5214,7 @@ static int ext4_do_update_inode(handle_t *handle,
/* For fields not not tracking in the in-memory inode,
* initialise them to zero for new inodes. */
- if (ei->i_state & EXT4_STATE_NEW)
+ if (ext4_test_inode_state(inode, EXT4_STATE_NEW))
memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
ext4_get_inode_flags(ei);
@@ -5101,7 +5278,7 @@ static int ext4_do_update_inode(handle_t *handle,
EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
sb->s_dirt = 1;
ext4_handle_sync(handle);
- err = ext4_handle_dirty_metadata(handle, inode,
+ err = ext4_handle_dirty_metadata(handle, NULL,
EXT4_SB(sb)->s_sbh);
}
}
@@ -5130,10 +5307,10 @@ static int ext4_do_update_inode(handle_t *handle,
}
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
- rc = ext4_handle_dirty_metadata(handle, inode, bh);
+ rc = ext4_handle_dirty_metadata(handle, NULL, bh);
if (!err)
err = rc;
- ei->i_state &= ~EXT4_STATE_NEW;
+ ext4_clear_inode_state(inode, EXT4_STATE_NEW);
ext4_update_inode_fsync_trans(handle, inode, 0);
out_brelse:
@@ -5177,7 +5354,7 @@ out_brelse:
* `stuff()' is running, and the new i_size will be lost. Plus the inode
* will no longer be on the superblock's dirty inode list.
*/
-int ext4_write_inode(struct inode *inode, int wait)
+int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int err;
@@ -5191,26 +5368,25 @@ int ext4_write_inode(struct inode *inode, int wait)
return -EIO;
}
- if (!wait)
+ if (wbc->sync_mode != WB_SYNC_ALL)
return 0;
err = ext4_force_commit(inode->i_sb);
} else {
struct ext4_iloc iloc;
- err = ext4_get_inode_loc(inode, &iloc);
+ err = __ext4_get_inode_loc(inode, &iloc, 0);
if (err)
return err;
- if (wait)
+ if (wbc->sync_mode == WB_SYNC_ALL)
sync_dirty_buffer(iloc.bh);
if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) {
- ext4_error(inode->i_sb, __func__,
- "IO error syncing inode, "
- "inode=%lu, block=%llu",
- inode->i_ino,
+ ext4_error(inode->i_sb, "IO error syncing inode, "
+ "inode=%lu, block=%llu", inode->i_ino,
(unsigned long long)iloc.bh->b_blocknr);
err = -EIO;
}
+ brelse(iloc.bh);
}
return err;
}
@@ -5249,6 +5425,8 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
if (error)
return error;
+ if (ia_valid & ATTR_SIZE)
+ dquot_initialize(inode);
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
handle_t *handle;
@@ -5261,7 +5439,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
error = PTR_ERR(handle);
goto err_out;
}
- error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+ error = dquot_transfer(inode, attr);
if (error) {
ext4_journal_stop(handle);
return error;
@@ -5288,7 +5466,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
}
if (S_ISREG(inode->i_mode) &&
- attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
+ attr->ia_valid & ATTR_SIZE &&
+ (attr->ia_size < inode->i_size ||
+ (EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL))) {
handle_t *handle;
handle = ext4_journal_start(inode, 3);
@@ -5319,6 +5499,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
goto err_out;
}
}
+ /* ext4_truncate will clear the flag */
+ if ((EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL))
+ ext4_truncate(inode);
}
rc = inode_setattr(inode, attr);
@@ -5557,8 +5740,8 @@ static int ext4_expand_extra_isize(struct inode *inode,
entry = IFIRST(header);
/* No extended attributes present */
- if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR) ||
- header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
+ if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) ||
+ header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0,
new_extra_isize);
EXT4_I(inode)->i_extra_isize = new_extra_isize;
@@ -5602,7 +5785,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
err = ext4_reserve_inode_write(handle, inode, &iloc);
if (ext4_handle_valid(handle) &&
EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
- !(EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND)) {
+ !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
/*
* We need extra buffer credits since we may write into EA block
* with this same handle. If journal_extend fails, then it will
@@ -5616,10 +5799,11 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
sbi->s_want_extra_isize,
iloc, handle);
if (ret) {
- EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
+ ext4_set_inode_state(inode,
+ EXT4_STATE_NO_EXPAND);
if (mnt_count !=
le16_to_cpu(sbi->s_es->s_mnt_count)) {
- ext4_warning(inode->i_sb, __func__,
+ ext4_warning(inode->i_sb,
"Unable to expand inode %lu. Delete"
" some EAs or run e2fsck.",
inode->i_ino);
@@ -5641,7 +5825,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
* i_size has been changed by generic_commit_write() and we thus need
* to include the updated inode in the current transaction.
*
- * Also, vfs_dq_alloc_block() will always dirty the inode when blocks
+ * Also, dquot_alloc_block() will always dirty the inode when blocks
* are allocated to the file.
*
* If the inode is marked synchronous, we don't honour that here - doing
@@ -5683,7 +5867,7 @@ static int ext4_pin_inode(handle_t *handle, struct inode *inode)
err = jbd2_journal_get_write_access(handle, iloc.bh);
if (!err)
err = ext4_handle_dirty_metadata(handle,
- inode,
+ NULL,
iloc.bh);
brelse(iloc.bh);
}
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index b63d193126d..016d0249294 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -92,6 +92,15 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
flags &= ~EXT4_EXTENTS_FL;
}
+ if (flags & EXT4_EOFBLOCKS_FL) {
+ /* we don't support adding EOFBLOCKS flag */
+ if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
+ err = -EOPNOTSUPP;
+ goto flags_out;
+ }
+ } else if (oldflags & EXT4_EOFBLOCKS_FL)
+ ext4_truncate(inode);
+
handle = ext4_journal_start(inode, 1);
if (IS_ERR(handle)) {
err = PTR_ERR(handle);
@@ -249,7 +258,8 @@ setversion_out:
if (me.moved_len > 0)
file_remove_suid(donor_filp);
- if (copy_to_user((struct move_extent *)arg, &me, sizeof(me)))
+ if (copy_to_user((struct move_extent __user *)arg,
+ &me, sizeof(me)))
err = -EFAULT;
mext_out:
fput(donor_filp);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index d34afad3e13..b423a364dca 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -23,6 +23,7 @@
#include "mballoc.h"
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <trace/events/ext4.h>
/*
@@ -69,7 +70,7 @@
*
* pa_lstart -> the logical start block for this prealloc space
* pa_pstart -> the physical start block for this prealloc space
- * pa_len -> lenght for this prealloc space
+ * pa_len -> length for this prealloc space
* pa_free -> free space available in this prealloc space
*
* The inode preallocation space is used looking at the _logical_ start
@@ -441,10 +442,9 @@ static void mb_free_blocks_double(struct inode *inode, struct ext4_buddy *e4b,
for (i = 0; i < count; i++) {
if (!mb_test_bit(first + i, e4b->bd_info->bb_bitmap)) {
ext4_fsblk_t blocknr;
- blocknr = e4b->bd_group * EXT4_BLOCKS_PER_GROUP(sb);
+
+ blocknr = ext4_group_first_block_no(sb, e4b->bd_group);
blocknr += first + i;
- blocknr +=
- le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
ext4_grp_locked_error(sb, e4b->bd_group,
__func__, "double-free of inode"
" %lu's block %llu(bit %u in group %u)",
@@ -1255,10 +1255,9 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
if (!mb_test_bit(block, EXT4_MB_BITMAP(e4b))) {
ext4_fsblk_t blocknr;
- blocknr = e4b->bd_group * EXT4_BLOCKS_PER_GROUP(sb);
+
+ blocknr = ext4_group_first_block_no(sb, e4b->bd_group);
blocknr += block;
- blocknr +=
- le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
ext4_grp_locked_error(sb, e4b->bd_group,
__func__, "double-free of inode"
" %lu's block %llu(bit %u in group %u)",
@@ -1631,7 +1630,6 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
int max;
int err;
struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
- struct ext4_super_block *es = sbi->s_es;
struct ext4_free_extent ex;
if (!(ac->ac_flags & EXT4_MB_HINT_TRY_GOAL))
@@ -1648,8 +1646,8 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) {
ext4_fsblk_t start;
- start = (e4b->bd_group * EXT4_BLOCKS_PER_GROUP(ac->ac_sb)) +
- ex.fe_start + le32_to_cpu(es->s_first_data_block);
+ start = ext4_group_first_block_no(ac->ac_sb, e4b->bd_group) +
+ ex.fe_start;
/* use do_div to get remainder (would be 64-bit modulo) */
if (do_div(start, sbi->s_stripe) == 0) {
ac->ac_found++;
@@ -1803,8 +1801,8 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
BUG_ON(sbi->s_stripe == 0);
/* find first stripe-aligned block in group */
- first_group_block = e4b->bd_group * EXT4_BLOCKS_PER_GROUP(sb)
- + le32_to_cpu(sbi->s_es->s_first_data_block);
+ first_group_block = ext4_group_first_block_no(sb, e4b->bd_group);
+
a = first_group_block + sbi->s_stripe - 1;
do_div(a, sbi->s_stripe);
i = (a * sbi->s_stripe) - first_group_block;
@@ -2256,7 +2254,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list);
init_rwsem(&meta_group_info[i]->alloc_sem);
- meta_group_info[i]->bb_free_root.rb_node = NULL;
+ meta_group_info[i]->bb_free_root = RB_ROOT;
#ifdef DOUBLE_CHECK
{
@@ -2537,6 +2535,17 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
entry->count, entry->group, entry);
+ if (test_opt(sb, DISCARD)) {
+ ext4_fsblk_t discard_block;
+
+ discard_block = entry->start_blk +
+ ext4_group_first_block_no(sb, entry->group);
+ trace_ext4_discard_blocks(sb,
+ (unsigned long long)discard_block,
+ entry->count);
+ sb_issue_discard(sb, discard_block, entry->count);
+ }
+
err = ext4_mb_load_buddy(sb, entry->group, &e4b);
/* we expect to find existing buddy because it's pinned */
BUG_ON(err != 0);
@@ -2558,19 +2567,6 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
page_cache_release(e4b.bd_bitmap_page);
}
ext4_unlock_group(sb, entry->group);
- if (test_opt(sb, DISCARD)) {
- ext4_fsblk_t discard_block;
- struct ext4_super_block *es = EXT4_SB(sb)->s_es;
-
- discard_block = (ext4_fsblk_t)entry->group *
- EXT4_BLOCKS_PER_GROUP(sb)
- + entry->start_blk
- + le32_to_cpu(es->s_first_data_block);
- trace_ext4_discard_blocks(sb,
- (unsigned long long)discard_block,
- entry->count);
- sb_issue_discard(sb, discard_block, entry->count);
- }
kmem_cache_free(ext4_free_ext_cachep, entry);
ext4_mb_release_desc(&e4b);
}
@@ -2703,14 +2699,11 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
if (err)
goto out_err;
- block = ac->ac_b_ex.fe_group * EXT4_BLOCKS_PER_GROUP(sb)
- + ac->ac_b_ex.fe_start
- + le32_to_cpu(es->s_first_data_block);
+ block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
len = ac->ac_b_ex.fe_len;
if (!ext4_data_block_valid(sbi, block, len)) {
- ext4_error(sb, __func__,
- "Allocating blocks %llu-%llu which overlap "
+ ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
"fs metadata\n", block, block+len);
/* File system mounted not to panic on error
* Fix the bitmap and repeat the block allocation
@@ -3161,9 +3154,7 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
/* The max size of hash table is PREALLOC_TB_SIZE */
order = PREALLOC_TB_SIZE - 1;
- goal_block = ac->ac_g_ex.fe_group * EXT4_BLOCKS_PER_GROUP(ac->ac_sb) +
- ac->ac_g_ex.fe_start +
- le32_to_cpu(EXT4_SB(ac->ac_sb)->s_es->s_first_data_block);
+ goal_block = ext4_grp_offs_to_block(ac->ac_sb, &ac->ac_g_ex);
/*
* search for the prealloc space that is having
* minimal distance from the goal block.
@@ -3526,8 +3517,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
if (bit >= end)
break;
next = mb_find_next_bit(bitmap_bh->b_data, end, bit);
- start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit +
- le32_to_cpu(sbi->s_es->s_first_data_block);
+ start = ext4_group_first_block_no(sb, group) + bit;
mb_debug(1, " free preallocated %u/%u in group %u\n",
(unsigned) start, (unsigned) next - bit,
(unsigned) group);
@@ -3623,15 +3613,13 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
bitmap_bh = ext4_read_block_bitmap(sb, group);
if (bitmap_bh == NULL) {
- ext4_error(sb, __func__, "Error in reading block "
- "bitmap for %u", group);
+ ext4_error(sb, "Error reading block bitmap for %u", group);
return 0;
}
err = ext4_mb_load_buddy(sb, group, &e4b);
if (err) {
- ext4_error(sb, __func__, "Error in loading buddy "
- "information for %u", group);
+ ext4_error(sb, "Error loading buddy information for %u", group);
put_bh(bitmap_bh);
return 0;
}
@@ -3804,15 +3792,15 @@ repeat:
err = ext4_mb_load_buddy(sb, group, &e4b);
if (err) {
- ext4_error(sb, __func__, "Error in loading buddy "
- "information for %u", group);
+ ext4_error(sb, "Error loading buddy information for %u",
+ group);
continue;
}
bitmap_bh = ext4_read_block_bitmap(sb, group);
if (bitmap_bh == NULL) {
- ext4_error(sb, __func__, "Error in reading block "
- "bitmap for %u", group);
+ ext4_error(sb, "Error reading block bitmap for %u",
+ group);
ext4_mb_release_desc(&e4b);
continue;
}
@@ -3938,7 +3926,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
/* don't use group allocation for large files */
size = max(size, isize);
- if (size >= sbi->s_mb_stream_request) {
+ if (size > sbi->s_mb_stream_request) {
ac->ac_flags |= EXT4_MB_STREAM_ALLOC;
return;
}
@@ -4077,8 +4065,8 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, NULL);
if (ext4_mb_load_buddy(sb, group, &e4b)) {
- ext4_error(sb, __func__, "Error in loading buddy "
- "information for %u", group);
+ ext4_error(sb, "Error loading buddy information for %u",
+ group);
continue;
}
ext4_lock_group(sb, group);
@@ -4254,7 +4242,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
return 0;
}
reserv_blks = ar->len;
- while (ar->len && vfs_dq_alloc_block(ar->inode, ar->len)) {
+ while (ar->len && dquot_alloc_block(ar->inode, ar->len)) {
ar->flags |= EXT4_MB_HINT_NOPREALLOC;
ar->len--;
}
@@ -4331,7 +4319,7 @@ out2:
kmem_cache_free(ext4_ac_cachep, ac);
out1:
if (inquota && ar->len < inquota)
- vfs_dq_free_block(ar->inode, inquota - ar->len);
+ dquot_free_block(ar->inode, inquota - ar->len);
out3:
if (!ar->len) {
if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag)
@@ -4476,10 +4464,10 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
sbi = EXT4_SB(sb);
es = EXT4_SB(sb)->s_es;
- if (!ext4_data_block_valid(sbi, block, count)) {
- ext4_error(sb, __func__,
- "Freeing blocks not in datazone - "
- "block = %llu, count = %lu", block, count);
+ if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
+ !ext4_data_block_valid(sbi, block, count)) {
+ ext4_error(sb, "Freeing blocks not in datazone - "
+ "block = %llu, count = %lu", block, count);
goto error_return;
}
@@ -4547,8 +4535,7 @@ do_more:
in_range(block + count - 1, ext4_inode_table(sb, gdp),
EXT4_SB(sb)->s_itb_per_group)) {
- ext4_error(sb, __func__,
- "Freeing blocks in system zone - "
+ ext4_error(sb, "Freeing blocks in system zone - "
"Block = %llu, count = %lu", block, count);
/* err = 0. ext4_std_error should be a no op */
goto error_return;
@@ -4646,7 +4633,7 @@ do_more:
sb->s_dirt = 1;
error_return:
if (freed)
- vfs_dq_free_block(inode, freed);
+ dquot_free_block(inode, freed);
brelse(bitmap_bh);
ext4_std_error(sb, err);
if (ac)
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index 436521cae45..b619322c76f 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -220,16 +220,9 @@ struct ext4_buddy {
#define EXT4_MB_BITMAP(e4b) ((e4b)->bd_bitmap)
#define EXT4_MB_BUDDY(e4b) ((e4b)->bd_buddy)
-#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
-
static inline ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb,
struct ext4_free_extent *fex)
{
- ext4_fsblk_t block;
-
- block = (ext4_fsblk_t) fex->fe_group * EXT4_BLOCKS_PER_GROUP(sb)
- + fex->fe_start
- + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
- return block;
+ return ext4_group_first_block_no(sb, fex->fe_group) + fex->fe_start;
}
#endif
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 81415814b00..34dcfc52ef4 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -13,6 +13,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include "ext4_jbd2.h"
#include "ext4_extents.h"
@@ -365,12 +366,12 @@ static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode,
* happened after we started the migrate. We need to
* fail the migrate
*/
- if (!(EXT4_I(inode)->i_state & EXT4_STATE_EXT_MIGRATE)) {
+ if (!ext4_test_inode_state(inode, EXT4_STATE_EXT_MIGRATE)) {
retval = -EAGAIN;
up_write(&EXT4_I(inode)->i_data_sem);
goto err_out;
} else
- EXT4_I(inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE;
+ ext4_clear_inode_state(inode, EXT4_STATE_EXT_MIGRATE);
/*
* We have the extent map build with the tmp inode.
* Now copy the i_data across
@@ -503,14 +504,10 @@ int ext4_ext_migrate(struct inode *inode)
}
i_size_write(tmp_inode, i_size_read(inode));
/*
- * We don't want the inode to be reclaimed
- * if we got interrupted in between. We have
- * this tmp inode carrying reference to the
- * data blocks of the original file. We set
- * the i_nlink to zero at the last stage after
- * switching the original file to extent format
+ * Set the i_nlink to zero so it will be deleted later
+ * when we drop inode reference.
*/
- tmp_inode->i_nlink = 1;
+ tmp_inode->i_nlink = 0;
ext4_ext_tree_init(handle, tmp_inode);
ext4_orphan_add(handle, tmp_inode);
@@ -533,10 +530,20 @@ int ext4_ext_migrate(struct inode *inode)
* allocation.
*/
down_read((&EXT4_I(inode)->i_data_sem));
- EXT4_I(inode)->i_state |= EXT4_STATE_EXT_MIGRATE;
+ ext4_set_inode_state(inode, EXT4_STATE_EXT_MIGRATE);
up_read((&EXT4_I(inode)->i_data_sem));
handle = ext4_journal_start(inode, 1);
+ if (IS_ERR(handle)) {
+ /*
+ * It is impossible to update on-disk structures without
+ * a handle, so just rollback in-core changes and live other
+ * work to orphan_list_cleanup()
+ */
+ ext4_orphan_del(NULL, tmp_inode);
+ retval = PTR_ERR(handle);
+ goto out;
+ }
ei = EXT4_I(inode);
i_data = ei->i_data;
@@ -618,15 +625,8 @@ err_out:
/* Reset the extent details */
ext4_ext_tree_init(handle, tmp_inode);
-
- /*
- * Set the i_nlink to zero so that
- * generic_drop_inode really deletes the
- * inode
- */
- tmp_inode->i_nlink = 0;
-
ext4_journal_stop(handle);
+out:
unlock_new_inode(tmp_inode);
iput(tmp_inode);
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 82c415be87a..d1fc662cc31 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -15,6 +15,7 @@
#include <linux/fs.h>
#include <linux/quotaops.h>
+#include <linux/slab.h>
#include "ext4_jbd2.h"
#include "ext4_extents.h"
#include "ext4.h"
@@ -152,12 +153,12 @@ mext_check_null_inode(struct inode *inode1, struct inode *inode2,
int ret = 0;
if (inode1 == NULL) {
- ext4_error(inode2->i_sb, function,
+ __ext4_error(inode2->i_sb, function,
"Both inodes should not be NULL: "
"inode1 NULL inode2 %lu", inode2->i_ino);
ret = -EIO;
} else if (inode2 == NULL) {
- ext4_error(inode1->i_sb, function,
+ __ext4_error(inode1->i_sb, function,
"Both inodes should not be NULL: "
"inode1 %lu inode2 NULL", inode1->i_ino);
ret = -EIO;
@@ -252,6 +253,7 @@ mext_insert_across_blocks(handle_t *handle, struct inode *orig_inode,
}
o_start->ee_len = start_ext->ee_len;
+ eblock = le32_to_cpu(start_ext->ee_block);
new_flag = 1;
} else if (start_ext->ee_len && new_ext->ee_len &&
@@ -262,6 +264,7 @@ mext_insert_across_blocks(handle_t *handle, struct inode *orig_inode,
* orig |------------------------------|
*/
o_start->ee_len = start_ext->ee_len;
+ eblock = le32_to_cpu(start_ext->ee_block);
new_flag = 1;
} else if (!start_ext->ee_len && new_ext->ee_len &&
@@ -475,7 +478,6 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
struct ext4_extent *oext, *o_start, *o_end, *prev_ext;
struct ext4_extent new_ext, start_ext, end_ext;
ext4_lblk_t new_ext_end;
- ext4_fsblk_t new_phys_end;
int oext_alen, new_ext_alen, end_ext_alen;
int depth = ext_depth(orig_inode);
int ret;
@@ -489,7 +491,6 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
new_ext.ee_len = dext->ee_len;
new_ext_alen = ext4_ext_get_actual_len(&new_ext);
new_ext_end = le32_to_cpu(new_ext.ee_block) + new_ext_alen - 1;
- new_phys_end = ext_pblock(&new_ext) + new_ext_alen - 1;
/*
* Case: original extent is first
@@ -502,6 +503,7 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
le32_to_cpu(oext->ee_block) + oext_alen) {
start_ext.ee_len = cpu_to_le16(le32_to_cpu(new_ext.ee_block) -
le32_to_cpu(oext->ee_block));
+ start_ext.ee_block = oext->ee_block;
copy_extent_status(oext, &start_ext);
} else if (oext > EXT_FIRST_EXTENT(orig_path[depth].p_hdr)) {
prev_ext = oext - 1;
@@ -515,6 +517,7 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
start_ext.ee_len = cpu_to_le16(
ext4_ext_get_actual_len(prev_ext) +
new_ext_alen);
+ start_ext.ee_block = oext->ee_block;
copy_extent_status(prev_ext, &start_ext);
new_ext.ee_len = 0;
}
@@ -526,7 +529,7 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
* new_ext |-------|
*/
if (le32_to_cpu(oext->ee_block) + oext_alen - 1 < new_ext_end) {
- ext4_error(orig_inode->i_sb, __func__,
+ ext4_error(orig_inode->i_sb,
"new_ext_end(%u) should be less than or equal to "
"oext->ee_block(%u) + oext_alen(%d) - 1",
new_ext_end, le32_to_cpu(oext->ee_block),
@@ -689,12 +692,12 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
while (1) {
/* The extent for donor must be found. */
if (!dext) {
- ext4_error(donor_inode->i_sb, __func__,
+ ext4_error(donor_inode->i_sb,
"The extent for donor must be found");
*err = -EIO;
goto out;
} else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) {
- ext4_error(donor_inode->i_sb, __func__,
+ ext4_error(donor_inode->i_sb,
"Donor offset(%u) and the first block of donor "
"extent(%u) should be equal",
donor_off,
@@ -928,7 +931,7 @@ out2:
}
/**
- * mext_check_argumants - Check whether move extent can be done
+ * mext_check_arguments - Check whether move extent can be done
*
* @orig_inode: original inode
* @donor_inode: donor inode
@@ -949,14 +952,6 @@ mext_check_arguments(struct inode *orig_inode,
unsigned int blkbits = orig_inode->i_blkbits;
unsigned int blocksize = 1 << blkbits;
- /* Regular file check */
- if (!S_ISREG(orig_inode->i_mode) || !S_ISREG(donor_inode->i_mode)) {
- ext4_debug("ext4 move extent: The argument files should be "
- "regular file [ino:orig %lu, donor %lu]\n",
- orig_inode->i_ino, donor_inode->i_ino);
- return -EINVAL;
- }
-
if (donor_inode->i_mode & (S_ISUID|S_ISGID)) {
ext4_debug("ext4 move extent: suid or sgid is set"
" to donor file [ino:orig %lu, donor %lu]\n",
@@ -1204,6 +1199,14 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
return -EINVAL;
}
+ /* Regular file check */
+ if (!S_ISREG(orig_inode->i_mode) || !S_ISREG(donor_inode->i_mode)) {
+ ext4_debug("ext4 move extent: The argument files should be "
+ "regular file [ino:orig %lu, donor %lu]\n",
+ orig_inode->i_ino, donor_inode->i_ino);
+ return -EINVAL;
+ }
+
/* Protect orig and donor inodes against a truncate */
ret1 = mext_inode_double_lock(orig_inode, donor_inode);
if (ret1 < 0)
@@ -1351,7 +1354,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
if (ret1 < 0)
break;
if (*moved_len > len) {
- ext4_error(orig_inode->i_sb, __func__,
+ ext4_error(orig_inode->i_sb,
"We replaced blocks too much! "
"sum of replaced: %llu requested: %llu",
*moved_len, len);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 17a17e10dd6..0c070fabd10 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -383,8 +383,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
if (root->info.hash_version != DX_HASH_TEA &&
root->info.hash_version != DX_HASH_HALF_MD4 &&
root->info.hash_version != DX_HASH_LEGACY) {
- ext4_warning(dir->i_sb, __func__,
- "Unrecognised inode hash code %d",
+ ext4_warning(dir->i_sb, "Unrecognised inode hash code %d",
root->info.hash_version);
brelse(bh);
*err = ERR_BAD_DX_DIR;
@@ -399,8 +398,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
hash = hinfo->hash;
if (root->info.unused_flags & 1) {
- ext4_warning(dir->i_sb, __func__,
- "Unimplemented inode hash flags: %#06x",
+ ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x",
root->info.unused_flags);
brelse(bh);
*err = ERR_BAD_DX_DIR;
@@ -408,8 +406,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
}
if ((indirect = root->info.indirect_levels) > 1) {
- ext4_warning(dir->i_sb, __func__,
- "Unimplemented inode hash depth: %#06x",
+ ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
root->info.indirect_levels);
brelse(bh);
*err = ERR_BAD_DX_DIR;
@@ -421,8 +418,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
if (dx_get_limit(entries) != dx_root_limit(dir,
root->info.info_length)) {
- ext4_warning(dir->i_sb, __func__,
- "dx entry: limit != root limit");
+ ext4_warning(dir->i_sb, "dx entry: limit != root limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail;
@@ -433,7 +429,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
{
count = dx_get_count(entries);
if (!count || count > dx_get_limit(entries)) {
- ext4_warning(dir->i_sb, __func__,
+ ext4_warning(dir->i_sb,
"dx entry: no count or count > limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
@@ -478,7 +474,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
goto fail2;
at = entries = ((struct dx_node *) bh->b_data)->entries;
if (dx_get_limit(entries) != dx_node_limit (dir)) {
- ext4_warning(dir->i_sb, __func__,
+ ext4_warning(dir->i_sb,
"dx entry: limit != node limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
@@ -494,7 +490,7 @@ fail2:
}
fail:
if (*err == ERR_BAD_DX_DIR)
- ext4_warning(dir->i_sb, __func__,
+ ext4_warning(dir->i_sb,
"Corrupt dir inode %ld, running e2fsck is "
"recommended.", dir->i_ino);
return NULL;
@@ -947,9 +943,8 @@ restart:
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
/* read error, skip block & hope for the best */
- ext4_error(sb, __func__, "reading directory #%lu "
- "offset %lu", dir->i_ino,
- (unsigned long)block);
+ ext4_error(sb, "reading directory #%lu offset %lu",
+ dir->i_ino, (unsigned long)block);
brelse(bh);
goto next;
}
@@ -1041,7 +1036,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
retval = ext4_htree_next_block(dir, hash, frame,
frames, NULL);
if (retval < 0) {
- ext4_warning(sb, __func__,
+ ext4_warning(sb,
"error reading index page in directory #%lu",
dir->i_ino);
*err = retval;
@@ -1071,14 +1066,13 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru
__u32 ino = le32_to_cpu(de->inode);
brelse(bh);
if (!ext4_valid_inum(dir->i_sb, ino)) {
- ext4_error(dir->i_sb, "ext4_lookup",
- "bad inode number: %u", ino);
+ ext4_error(dir->i_sb, "bad inode number: %u", ino);
return ERR_PTR(-EIO);
}
inode = ext4_iget(dir->i_sb, ino);
if (unlikely(IS_ERR(inode))) {
if (PTR_ERR(inode) == -ESTALE) {
- ext4_error(dir->i_sb, __func__,
+ ext4_error(dir->i_sb,
"deleted inode referenced: %u",
ino);
return ERR_PTR(-EIO);
@@ -1110,7 +1104,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
brelse(bh);
if (!ext4_valid_inum(child->d_inode->i_sb, ino)) {
- ext4_error(child->d_inode->i_sb, "ext4_get_parent",
+ ext4_error(child->d_inode->i_sb,
"bad inode number: %u", ino);
return ERR_PTR(-EIO);
}
@@ -1410,7 +1404,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
de = (struct ext4_dir_entry_2 *)((char *)fde +
ext4_rec_len_from_disk(fde->rec_len, blocksize));
if ((char *) de >= (((char *) root) + blocksize)) {
- ext4_error(dir->i_sb, __func__,
+ ext4_error(dir->i_sb,
"invalid rec_len for '..' in inode %lu",
dir->i_ino);
brelse(bh);
@@ -1575,8 +1569,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
if (levels && (dx_get_count(frames->entries) ==
dx_get_limit(frames->entries))) {
- ext4_warning(sb, __func__,
- "Directory index full!");
+ ext4_warning(sb, "Directory index full!");
err = -ENOSPC;
goto cleanup;
}
@@ -1766,6 +1759,8 @@ static int ext4_create(struct inode *dir, struct dentry *dentry, int mode,
struct inode *inode;
int err, retries = 0;
+ dquot_initialize(dir);
+
retry:
handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -1800,6 +1795,8 @@ static int ext4_mknod(struct inode *dir, struct dentry *dentry,
if (!new_valid_dev(rdev))
return -EINVAL;
+ dquot_initialize(dir);
+
retry:
handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -1837,6 +1834,8 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (EXT4_DIR_LINK_MAX(dir))
return -EMLINK;
+ dquot_initialize(dir);
+
retry:
handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
@@ -1916,11 +1915,11 @@ static int empty_dir(struct inode *inode)
if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
!(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
if (err)
- ext4_error(inode->i_sb, __func__,
+ ext4_error(inode->i_sb,
"error %d reading directory #%lu offset 0",
err, inode->i_ino);
else
- ext4_warning(inode->i_sb, __func__,
+ ext4_warning(inode->i_sb,
"bad directory (dir #%lu) - no data block",
inode->i_ino);
return 1;
@@ -1931,7 +1930,7 @@ static int empty_dir(struct inode *inode)
!le32_to_cpu(de1->inode) ||
strcmp(".", de->name) ||
strcmp("..", de1->name)) {
- ext4_warning(inode->i_sb, "empty_dir",
+ ext4_warning(inode->i_sb,
"bad directory (dir #%lu) - no `.' or `..'",
inode->i_ino);
brelse(bh);
@@ -1949,7 +1948,7 @@ static int empty_dir(struct inode *inode)
offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err);
if (!bh) {
if (err)
- ext4_error(sb, __func__,
+ ext4_error(sb,
"error %d reading directory"
" #%lu offset %u",
err, inode->i_ino, offset);
@@ -2020,11 +2019,18 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
err = ext4_reserve_inode_write(handle, inode, &iloc);
if (err)
goto out_unlock;
+ /*
+ * Due to previous errors inode may be already a part of on-disk
+ * orphan list. If so skip on-disk list modification.
+ */
+ if (NEXT_ORPHAN(inode) && NEXT_ORPHAN(inode) <=
+ (le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)))
+ goto mem_insert;
/* Insert this inode at the head of the on-disk orphan list... */
NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan);
EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
- err = ext4_handle_dirty_metadata(handle, inode, EXT4_SB(sb)->s_sbh);
+ err = ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
if (!err)
err = rc;
@@ -2037,6 +2043,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
*
* This is safe: on error we're going to ignore the orphan list
* anyway on the next recovery. */
+mem_insert:
if (!err)
list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
@@ -2096,7 +2103,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
if (err)
goto out_brelse;
sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
- err = ext4_handle_dirty_metadata(handle, inode, sbi->s_sbh);
+ err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh);
} else {
struct ext4_iloc iloc2;
struct inode *i_prev =
@@ -2136,7 +2143,9 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
/* Initialize quotas before so that eventual writes go in
* separate transaction */
- vfs_dq_init(dentry->d_inode);
+ dquot_initialize(dir);
+ dquot_initialize(dentry->d_inode);
+
handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb));
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -2163,7 +2172,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
if (retval)
goto end_rmdir;
if (!EXT4_DIR_LINK_EMPTY(inode))
- ext4_warning(inode->i_sb, "ext4_rmdir",
+ ext4_warning(inode->i_sb,
"empty directory has too many links (%d)",
inode->i_nlink);
inode->i_version++;
@@ -2195,7 +2204,9 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
/* Initialize quotas before so that eventual writes go
* in separate transaction */
- vfs_dq_init(dentry->d_inode);
+ dquot_initialize(dir);
+ dquot_initialize(dentry->d_inode);
+
handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb));
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -2215,7 +2226,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
goto end_unlink;
if (!inode->i_nlink) {
- ext4_warning(inode->i_sb, "ext4_unlink",
+ ext4_warning(inode->i_sb,
"Deleting nonexistent file (%lu), %d",
inode->i_ino, inode->i_nlink);
inode->i_nlink = 1;
@@ -2250,6 +2261,8 @@ static int ext4_symlink(struct inode *dir,
if (l > dir->i_sb->s_blocksize)
return -ENAMETOOLONG;
+ dquot_initialize(dir);
+
retry:
handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 +
@@ -2308,6 +2321,8 @@ static int ext4_link(struct dentry *old_dentry,
if (inode->i_nlink >= EXT4_LINK_MAX)
return -EMLINK;
+ dquot_initialize(dir);
+
/*
* Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing
* otherwise has the potential to corrupt the orphan inode list.
@@ -2358,12 +2373,15 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
struct ext4_dir_entry_2 *old_de, *new_de;
int retval, force_da_alloc = 0;
+ dquot_initialize(old_dir);
+ dquot_initialize(new_dir);
+
old_bh = new_bh = dir_bh = NULL;
/* Initialize quotas before so that eventual writes go
* in separate transaction */
if (new_dentry->d_inode)
- vfs_dq_init(new_dentry->d_inode);
+ dquot_initialize(new_dentry->d_inode);
handle = ext4_journal_start(old_dir, 2 *
EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) +
EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2);
@@ -2462,7 +2480,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
}
}
if (retval) {
- ext4_warning(old_dir->i_sb, "ext4_rename",
+ ext4_warning(old_dir->i_sb,
"Deleting old file (%lu), %d, error=%d",
old_dir->i_ino, old_dir->i_nlink, retval);
}
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 3b2c5541d8a..5692c48754a 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -48,65 +48,54 @@ static int verify_group_input(struct super_block *sb,
ext4_get_group_no_and_offset(sb, start, NULL, &offset);
if (group != sbi->s_groups_count)
- ext4_warning(sb, __func__,
- "Cannot add at group %u (only %u groups)",
+ ext4_warning(sb, "Cannot add at group %u (only %u groups)",
input->group, sbi->s_groups_count);
else if (offset != 0)
- ext4_warning(sb, __func__, "Last group not full");
+ ext4_warning(sb, "Last group not full");
else if (input->reserved_blocks > input->blocks_count / 5)
- ext4_warning(sb, __func__, "Reserved blocks too high (%u)",
+ ext4_warning(sb, "Reserved blocks too high (%u)",
input->reserved_blocks);
else if (free_blocks_count < 0)
- ext4_warning(sb, __func__, "Bad blocks count %u",
+ ext4_warning(sb, "Bad blocks count %u",
input->blocks_count);
else if (!(bh = sb_bread(sb, end - 1)))
- ext4_warning(sb, __func__,
- "Cannot read last block (%llu)",
+ ext4_warning(sb, "Cannot read last block (%llu)",
end - 1);
else if (outside(input->block_bitmap, start, end))
- ext4_warning(sb, __func__,
- "Block bitmap not in group (block %llu)",
+ ext4_warning(sb, "Block bitmap not in group (block %llu)",
(unsigned long long)input->block_bitmap);
else if (outside(input->inode_bitmap, start, end))
- ext4_warning(sb, __func__,
- "Inode bitmap not in group (block %llu)",
+ ext4_warning(sb, "Inode bitmap not in group (block %llu)",
(unsigned long long)input->inode_bitmap);
else if (outside(input->inode_table, start, end) ||
outside(itend - 1, start, end))
- ext4_warning(sb, __func__,
- "Inode table not in group (blocks %llu-%llu)",
+ ext4_warning(sb, "Inode table not in group (blocks %llu-%llu)",
(unsigned long long)input->inode_table, itend - 1);
else if (input->inode_bitmap == input->block_bitmap)
- ext4_warning(sb, __func__,
- "Block bitmap same as inode bitmap (%llu)",
+ ext4_warning(sb, "Block bitmap same as inode bitmap (%llu)",
(unsigned long long)input->block_bitmap);
else if (inside(input->block_bitmap, input->inode_table, itend))
- ext4_warning(sb, __func__,
- "Block bitmap (%llu) in inode table (%llu-%llu)",
+ ext4_warning(sb, "Block bitmap (%llu) in inode table "
+ "(%llu-%llu)",
(unsigned long long)input->block_bitmap,
(unsigned long long)input->inode_table, itend - 1);
else if (inside(input->inode_bitmap, input->inode_table, itend))
- ext4_warning(sb, __func__,
- "Inode bitmap (%llu) in inode table (%llu-%llu)",
+ ext4_warning(sb, "Inode bitmap (%llu) in inode table "
+ "(%llu-%llu)",
(unsigned long long)input->inode_bitmap,
(unsigned long long)input->inode_table, itend - 1);
else if (inside(input->block_bitmap, start, metaend))
- ext4_warning(sb, __func__,
- "Block bitmap (%llu) in GDT table"
- " (%llu-%llu)",
+ ext4_warning(sb, "Block bitmap (%llu) in GDT table (%llu-%llu)",
(unsigned long long)input->block_bitmap,
start, metaend - 1);
else if (inside(input->inode_bitmap, start, metaend))
- ext4_warning(sb, __func__,
- "Inode bitmap (%llu) in GDT table"
- " (%llu-%llu)",
+ ext4_warning(sb, "Inode bitmap (%llu) in GDT table (%llu-%llu)",
(unsigned long long)input->inode_bitmap,
start, metaend - 1);
else if (inside(input->inode_table, start, metaend) ||
inside(itend - 1, start, metaend))
- ext4_warning(sb, __func__,
- "Inode table (%llu-%llu) overlaps"
- "GDT table (%llu-%llu)",
+ ext4_warning(sb, "Inode table (%llu-%llu) overlaps GDT table "
+ "(%llu-%llu)",
(unsigned long long)input->inode_table,
itend - 1, start, metaend - 1);
else
@@ -364,8 +353,7 @@ static int verify_reserved_gdb(struct super_block *sb,
while ((grp = ext4_list_backups(sb, &three, &five, &seven)) < end) {
if (le32_to_cpu(*p++) !=
grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){
- ext4_warning(sb, __func__,
- "reserved GDT %llu"
+ ext4_warning(sb, "reserved GDT %llu"
" missing grp %d (%llu)",
blk, grp,
grp *
@@ -420,8 +408,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
*/
if (EXT4_SB(sb)->s_sbh->b_blocknr !=
le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
- ext4_warning(sb, __func__,
- "won't resize using backup superblock at %llu",
+ ext4_warning(sb, "won't resize using backup superblock at %llu",
(unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
return -EPERM;
}
@@ -444,8 +431,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
data = (__le32 *)dind->b_data;
if (le32_to_cpu(data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)]) != gdblock) {
- ext4_warning(sb, __func__,
- "new group %u GDT block %llu not reserved",
+ ext4_warning(sb, "new group %u GDT block %llu not reserved",
input->group, gdblock);
err = -EINVAL;
goto exit_dind;
@@ -468,7 +454,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
GFP_NOFS);
if (!n_group_desc) {
err = -ENOMEM;
- ext4_warning(sb, __func__,
+ ext4_warning(sb,
"not enough memory for %lu groups", gdb_num + 1);
goto exit_inode;
}
@@ -567,8 +553,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
/* Get each reserved primary GDT block and verify it holds backups */
for (res = 0; res < reserved_gdb; res++, blk++) {
if (le32_to_cpu(*data) != blk) {
- ext4_warning(sb, __func__,
- "reserved block %llu"
+ ext4_warning(sb, "reserved block %llu"
" not at offset %ld",
blk,
(long)(data - (__le32 *)dind->b_data));
@@ -713,8 +698,7 @@ static void update_backups(struct super_block *sb,
*/
exit_err:
if (err) {
- ext4_warning(sb, __func__,
- "can't update backup for group %u (err %d), "
+ ext4_warning(sb, "can't update backup for group %u (err %d), "
"forcing fsck on next reboot", group, err);
sbi->s_mount_state &= ~EXT4_VALID_FS;
sbi->s_es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
@@ -753,20 +737,19 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
- ext4_warning(sb, __func__,
- "Can't resize non-sparse filesystem further");
+ ext4_warning(sb, "Can't resize non-sparse filesystem further");
return -EPERM;
}
if (ext4_blocks_count(es) + input->blocks_count <
ext4_blocks_count(es)) {
- ext4_warning(sb, __func__, "blocks_count overflow");
+ ext4_warning(sb, "blocks_count overflow");
return -EINVAL;
}
if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) <
le32_to_cpu(es->s_inodes_count)) {
- ext4_warning(sb, __func__, "inodes_count overflow");
+ ext4_warning(sb, "inodes_count overflow");
return -EINVAL;
}
@@ -774,14 +757,13 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
if (!EXT4_HAS_COMPAT_FEATURE(sb,
EXT4_FEATURE_COMPAT_RESIZE_INODE)
|| !le16_to_cpu(es->s_reserved_gdt_blocks)) {
- ext4_warning(sb, __func__,
+ ext4_warning(sb,
"No reserved GDT blocks, can't resize");
return -EPERM;
}
inode = ext4_iget(sb, EXT4_RESIZE_INO);
if (IS_ERR(inode)) {
- ext4_warning(sb, __func__,
- "Error opening resize inode");
+ ext4_warning(sb, "Error opening resize inode");
return PTR_ERR(inode);
}
}
@@ -810,8 +792,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
mutex_lock(&sbi->s_resize_lock);
if (input->group != sbi->s_groups_count) {
- ext4_warning(sb, __func__,
- "multiple resizers run on filesystem!");
+ ext4_warning(sb, "multiple resizers run on filesystem!");
err = -EBUSY;
goto exit_journal;
}
@@ -997,13 +978,12 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
" too large to resize to %llu blocks safely\n",
sb->s_id, n_blocks_count);
if (sizeof(sector_t) < 8)
- ext4_warning(sb, __func__, "CONFIG_LBDAF not enabled");
+ ext4_warning(sb, "CONFIG_LBDAF not enabled");
return -EINVAL;
}
if (n_blocks_count < o_blocks_count) {
- ext4_warning(sb, __func__,
- "can't shrink FS - resize aborted");
+ ext4_warning(sb, "can't shrink FS - resize aborted");
return -EBUSY;
}
@@ -1011,15 +991,14 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
ext4_get_group_no_and_offset(sb, o_blocks_count, &group, &last);
if (last == 0) {
- ext4_warning(sb, __func__,
- "need to use ext2online to resize further");
+ ext4_warning(sb, "need to use ext2online to resize further");
return -EPERM;
}
add = EXT4_BLOCKS_PER_GROUP(sb) - last;
if (o_blocks_count + add < o_blocks_count) {
- ext4_warning(sb, __func__, "blocks_count overflow");
+ ext4_warning(sb, "blocks_count overflow");
return -EINVAL;
}
@@ -1027,16 +1006,13 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
add = n_blocks_count - o_blocks_count;
if (o_blocks_count + add < n_blocks_count)
- ext4_warning(sb, __func__,
- "will only finish group (%llu"
- " blocks, %u new)",
+ ext4_warning(sb, "will only finish group (%llu blocks, %u new)",
o_blocks_count + add, add);
/* See if the device is actually as big as what was requested */
bh = sb_bread(sb, o_blocks_count + add - 1);
if (!bh) {
- ext4_warning(sb, __func__,
- "can't read last block, resize aborted");
+ ext4_warning(sb, "can't read last block, resize aborted");
return -ENOSPC;
}
brelse(bh);
@@ -1047,14 +1023,13 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
handle = ext4_journal_start_sb(sb, 3);
if (IS_ERR(handle)) {
err = PTR_ERR(handle);
- ext4_warning(sb, __func__, "error %d on journal start", err);
+ ext4_warning(sb, "error %d on journal start", err);
goto exit_put;
}
mutex_lock(&EXT4_SB(sb)->s_resize_lock);
if (o_blocks_count != ext4_blocks_count(es)) {
- ext4_warning(sb, __func__,
- "multiple resizers run on filesystem!");
+ ext4_warning(sb, "multiple resizers run on filesystem!");
mutex_unlock(&EXT4_SB(sb)->s_resize_lock);
ext4_journal_stop(handle);
err = -EBUSY;
@@ -1063,8 +1038,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
if ((err = ext4_journal_get_write_access(handle,
EXT4_SB(sb)->s_sbh))) {
- ext4_warning(sb, __func__,
- "error %d on journal write access", err);
+ ext4_warning(sb, "error %d on journal write access", err);
mutex_unlock(&EXT4_SB(sb)->s_resize_lock);
ext4_journal_stop(handle);
goto exit_put;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 735c20d5fd5..e14d22c170d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -68,7 +68,21 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
static int ext4_unfreeze(struct super_block *sb);
static void ext4_write_super(struct super_block *sb);
static int ext4_freeze(struct super_block *sb);
+static int ext4_get_sb(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data, struct vfsmount *mnt);
+#if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
+static struct file_system_type ext3_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "ext3",
+ .get_sb = ext4_get_sb,
+ .kill_sb = kill_block_super,
+ .fs_flags = FS_REQUIRES_DEV,
+};
+#define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
+#else
+#define IS_EXT3_SB(sb) (0)
+#endif
ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
struct ext4_group_desc *bg)
@@ -302,7 +316,7 @@ void ext4_journal_abort_handle(const char *caller, const char *err_fn,
* write out the superblock safely.
*
* We'll just use the jbd2_journal_abort() error code to record an error in
- * the journal instead. On recovery, the journal will compain about
+ * the journal instead. On recovery, the journal will complain about
* that error until we've noted it down and cleared it.
*/
@@ -333,7 +347,7 @@ static void ext4_handle_error(struct super_block *sb)
sb->s_id);
}
-void ext4_error(struct super_block *sb, const char *function,
+void __ext4_error(struct super_block *sb, const char *function,
const char *fmt, ...)
{
va_list args;
@@ -347,6 +361,42 @@ void ext4_error(struct super_block *sb, const char *function,
ext4_handle_error(sb);
}
+void ext4_error_inode(const char *function, struct inode *inode,
+ const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ printk(KERN_CRIT "EXT4-fs error (device %s): %s: inode #%lu: (comm %s) ",
+ inode->i_sb->s_id, function, inode->i_ino, current->comm);
+ vprintk(fmt, args);
+ printk("\n");
+ va_end(args);
+
+ ext4_handle_error(inode->i_sb);
+}
+
+void ext4_error_file(const char *function, struct file *file,
+ const char *fmt, ...)
+{
+ va_list args;
+ struct inode *inode = file->f_dentry->d_inode;
+ char pathname[80], *path;
+
+ va_start(args, fmt);
+ path = d_path(&(file->f_path), pathname, sizeof(pathname));
+ if (!path)
+ path = "(unknown)";
+ printk(KERN_CRIT
+ "EXT4-fs error (device %s): %s: inode #%lu (comm %s path %s): ",
+ inode->i_sb->s_id, function, inode->i_ino, current->comm, path);
+ vprintk(fmt, args);
+ printk("\n");
+ va_end(args);
+
+ ext4_handle_error(inode->i_sb);
+}
+
static const char *ext4_decode_error(struct super_block *sb, int errno,
char nbuf[16])
{
@@ -450,7 +500,7 @@ void ext4_msg (struct super_block * sb, const char *prefix,
va_end(args);
}
-void ext4_warning(struct super_block *sb, const char *function,
+void __ext4_warning(struct super_block *sb, const char *function,
const char *fmt, ...)
{
va_list args;
@@ -507,7 +557,7 @@ void ext4_update_dynamic_rev(struct super_block *sb)
if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV)
return;
- ext4_warning(sb, __func__,
+ ext4_warning(sb,
"updating to rev %d because of new feature flag, "
"running e2fsck is recommended",
EXT4_DYNAMIC_REV);
@@ -708,7 +758,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
#ifdef CONFIG_QUOTA
ei->i_reserved_quota = 0;
#endif
- INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
+ INIT_LIST_HEAD(&ei->i_completed_io_list);
+ spin_lock_init(&ei->i_completed_io_lock);
ei->cur_aio_dio = NULL;
ei->i_sync_tid = 0;
ei->i_datasync_tid = 0;
@@ -761,6 +812,7 @@ static void destroy_inodecache(void)
static void ext4_clear_inode(struct inode *inode)
{
+ dquot_drop(inode);
ext4_discard_preallocations(inode);
if (EXT4_JOURNAL(inode))
jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal,
@@ -796,10 +848,10 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
if (sbi->s_qf_names[GRPQUOTA])
seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
- if (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA)
+ if (test_opt(sb, USRQUOTA))
seq_puts(seq, ",usrquota");
- if (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)
+ if (test_opt(sb, GRPQUOTA))
seq_puts(seq, ",grpquota");
#endif
}
@@ -926,6 +978,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
if (test_opt(sb, NOLOAD))
seq_puts(seq, ",norecovery");
+ if (test_opt(sb, DIOREAD_NOLOCK))
+ seq_puts(seq, ",dioread_nolock");
+
ext4_show_quota_options(seq, sb);
return 0;
@@ -1012,19 +1067,9 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
const char *data, size_t len, loff_t off);
static const struct dquot_operations ext4_quota_operations = {
- .initialize = dquot_initialize,
- .drop = dquot_drop,
- .alloc_space = dquot_alloc_space,
- .reserve_space = dquot_reserve_space,
- .claim_space = dquot_claim_space,
- .release_rsv = dquot_release_reserved_space,
#ifdef CONFIG_QUOTA
.get_reserved_space = ext4_get_reserved_space,
#endif
- .alloc_inode = dquot_alloc_inode,
- .free_space = dquot_free_space,
- .free_inode = dquot_free_inode,
- .transfer = dquot_transfer,
.write_dquot = ext4_write_dquot,
.acquire_dquot = ext4_acquire_dquot,
.release_dquot = ext4_release_dquot,
@@ -1109,6 +1154,7 @@ enum {
Opt_stripe, Opt_delalloc, Opt_nodelalloc,
Opt_block_validity, Opt_noblock_validity,
Opt_inode_readahead_blks, Opt_journal_ioprio,
+ Opt_dioread_nolock, Opt_dioread_lock,
Opt_discard, Opt_nodiscard,
};
@@ -1176,6 +1222,8 @@ static const match_table_t tokens = {
{Opt_auto_da_alloc, "auto_da_alloc=%u"},
{Opt_auto_da_alloc, "auto_da_alloc"},
{Opt_noauto_da_alloc, "noauto_da_alloc"},
+ {Opt_dioread_nolock, "dioread_nolock"},
+ {Opt_dioread_lock, "dioread_lock"},
{Opt_discard, "discard"},
{Opt_nodiscard, "nodiscard"},
{Opt_err, NULL},
@@ -1205,6 +1253,66 @@ static ext4_fsblk_t get_sb_block(void **data)
}
#define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3))
+static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n"
+ "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n";
+
+#ifdef CONFIG_QUOTA
+static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
+{
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ char *qname;
+
+ if (sb_any_quota_loaded(sb) &&
+ !sbi->s_qf_names[qtype]) {
+ ext4_msg(sb, KERN_ERR,
+ "Cannot change journaled "
+ "quota options when quota turned on");
+ return 0;
+ }
+ qname = match_strdup(args);
+ if (!qname) {
+ ext4_msg(sb, KERN_ERR,
+ "Not enough memory for storing quotafile name");
+ return 0;
+ }
+ if (sbi->s_qf_names[qtype] &&
+ strcmp(sbi->s_qf_names[qtype], qname)) {
+ ext4_msg(sb, KERN_ERR,
+ "%s quota file already specified", QTYPE2NAME(qtype));
+ kfree(qname);
+ return 0;
+ }
+ sbi->s_qf_names[qtype] = qname;
+ if (strchr(sbi->s_qf_names[qtype], '/')) {
+ ext4_msg(sb, KERN_ERR,
+ "quotafile must be on filesystem root");
+ kfree(sbi->s_qf_names[qtype]);
+ sbi->s_qf_names[qtype] = NULL;
+ return 0;
+ }
+ set_opt(sbi->s_mount_opt, QUOTA);
+ return 1;
+}
+
+static int clear_qf_name(struct super_block *sb, int qtype)
+{
+
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+ if (sb_any_quota_loaded(sb) &&
+ sbi->s_qf_names[qtype]) {
+ ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options"
+ " when quota turned on");
+ return 0;
+ }
+ /*
+ * The space will be released later when all options are confirmed
+ * to be correct
+ */
+ sbi->s_qf_names[qtype] = NULL;
+ return 1;
+}
+#endif
static int parse_options(char *options, struct super_block *sb,
unsigned long *journal_devnum,
@@ -1217,8 +1325,7 @@ static int parse_options(char *options, struct super_block *sb,
int data_opt = 0;
int option;
#ifdef CONFIG_QUOTA
- int qtype, qfmt;
- char *qname;
+ int qfmt;
#endif
if (!options)
@@ -1229,19 +1336,31 @@ static int parse_options(char *options, struct super_block *sb,
if (!*p)
continue;
+ /*
+ * Initialize args struct so we know whether arg was
+ * found; some options take optional arguments.
+ */
+ args[0].to = args[0].from = 0;
token = match_token(p, tokens, args);
switch (token) {
case Opt_bsd_df:
+ ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
clear_opt(sbi->s_mount_opt, MINIX_DF);
break;
case Opt_minix_df:
+ ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
set_opt(sbi->s_mount_opt, MINIX_DF);
+
break;
case Opt_grpid:
+ ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
set_opt(sbi->s_mount_opt, GRPID);
+
break;
case Opt_nogrpid:
+ ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
clear_opt(sbi->s_mount_opt, GRPID);
+
break;
case Opt_resuid:
if (match_int(&args[0], &option))
@@ -1378,14 +1497,13 @@ static int parse_options(char *options, struct super_block *sb,
data_opt = EXT4_MOUNT_WRITEBACK_DATA;
datacheck:
if (is_remount) {
- if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS)
- != data_opt) {
+ if (test_opt(sb, DATA_FLAGS) != data_opt) {
ext4_msg(sb, KERN_ERR,
"Cannot change data mode on remount");
return 0;
}
} else {
- sbi->s_mount_opt &= ~EXT4_MOUNT_DATA_FLAGS;
+ clear_opt(sbi->s_mount_opt, DATA_FLAGS);
sbi->s_mount_opt |= data_opt;
}
break;
@@ -1397,63 +1515,22 @@ static int parse_options(char *options, struct super_block *sb,
break;
#ifdef CONFIG_QUOTA
case Opt_usrjquota:
- qtype = USRQUOTA;
- goto set_qf_name;
- case Opt_grpjquota:
- qtype = GRPQUOTA;
-set_qf_name:
- if (sb_any_quota_loaded(sb) &&
- !sbi->s_qf_names[qtype]) {
- ext4_msg(sb, KERN_ERR,
- "Cannot change journaled "
- "quota options when quota turned on");
+ if (!set_qf_name(sb, USRQUOTA, &args[0]))
return 0;
- }
- qname = match_strdup(&args[0]);
- if (!qname) {
- ext4_msg(sb, KERN_ERR,
- "Not enough memory for "
- "storing quotafile name");
- return 0;
- }
- if (sbi->s_qf_names[qtype] &&
- strcmp(sbi->s_qf_names[qtype], qname)) {
- ext4_msg(sb, KERN_ERR,
- "%s quota file already "
- "specified", QTYPE2NAME(qtype));
- kfree(qname);
- return 0;
- }
- sbi->s_qf_names[qtype] = qname;
- if (strchr(sbi->s_qf_names[qtype], '/')) {
- ext4_msg(sb, KERN_ERR,
- "quotafile must be on "
- "filesystem root");
- kfree(sbi->s_qf_names[qtype]);
- sbi->s_qf_names[qtype] = NULL;
+ break;
+ case Opt_grpjquota:
+ if (!set_qf_name(sb, GRPQUOTA, &args[0]))
return 0;
- }
- set_opt(sbi->s_mount_opt, QUOTA);
break;
case Opt_offusrjquota:
- qtype = USRQUOTA;
- goto clear_qf_name;
+ if (!clear_qf_name(sb, USRQUOTA))
+ return 0;
+ break;
case Opt_offgrpjquota:
- qtype = GRPQUOTA;
-clear_qf_name:
- if (sb_any_quota_loaded(sb) &&
- sbi->s_qf_names[qtype]) {
- ext4_msg(sb, KERN_ERR, "Cannot change "
- "journaled quota options when "
- "quota turned on");
+ if (!clear_qf_name(sb, GRPQUOTA))
return 0;
- }
- /*
- * The space will be released later when all options
- * are confirmed to be correct
- */
- sbi->s_qf_names[qtype] = NULL;
break;
+
case Opt_jqfmt_vfsold:
qfmt = QFMT_VFS_OLD;
goto set_qf_format;
@@ -1518,10 +1595,11 @@ set_qf_format:
clear_opt(sbi->s_mount_opt, BARRIER);
break;
case Opt_barrier:
- if (match_int(&args[0], &option)) {
- set_opt(sbi->s_mount_opt, BARRIER);
- break;
- }
+ if (args[0].from) {
+ if (match_int(&args[0], &option))
+ return 0;
+ } else
+ option = 1; /* No argument, default to 1 */
if (option)
set_opt(sbi->s_mount_opt, BARRIER);
else
@@ -1594,10 +1672,11 @@ set_qf_format:
set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
break;
case Opt_auto_da_alloc:
- if (match_int(&args[0], &option)) {
- clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC);
- break;
- }
+ if (args[0].from) {
+ if (match_int(&args[0], &option))
+ return 0;
+ } else
+ option = 1; /* No argument, default to 1 */
if (option)
clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC);
else
@@ -1609,6 +1688,12 @@ set_qf_format:
case Opt_nodiscard:
clear_opt(sbi->s_mount_opt, DISCARD);
break;
+ case Opt_dioread_nolock:
+ set_opt(sbi->s_mount_opt, DIOREAD_NOLOCK);
+ break;
+ case Opt_dioread_lock:
+ clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK);
+ break;
default:
ext4_msg(sb, KERN_ERR,
"Unrecognized mount option \"%s\" "
@@ -1618,18 +1703,13 @@ set_qf_format:
}
#ifdef CONFIG_QUOTA
if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
- if ((sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) &&
- sbi->s_qf_names[USRQUOTA])
+ if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
clear_opt(sbi->s_mount_opt, USRQUOTA);
- if ((sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) &&
- sbi->s_qf_names[GRPQUOTA])
+ if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
clear_opt(sbi->s_mount_opt, GRPQUOTA);
- if ((sbi->s_qf_names[USRQUOTA] &&
- (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) ||
- (sbi->s_qf_names[GRPQUOTA] &&
- (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) {
+ if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) {
ext4_msg(sb, KERN_ERR, "old and new quota "
"format mixing");
return 0;
@@ -1939,7 +2019,7 @@ static void ext4_orphan_cleanup(struct super_block *sb,
}
list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
- vfs_dq_init(inode);
+ dquot_initialize(inode);
if (inode->i_nlink) {
ext4_msg(sb, KERN_DEBUG,
"%s: truncating inode %lu to %lld bytes",
@@ -2292,7 +2372,7 @@ static void ext4_sb_release(struct kobject *kobj)
}
-static struct sysfs_ops ext4_attr_ops = {
+static const struct sysfs_ops ext4_attr_ops = {
.show = ext4_attr_show,
.store = ext4_attr_store,
};
@@ -2432,8 +2512,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
if (def_mount_opts & EXT4_DEFM_DEBUG)
set_opt(sbi->s_mount_opt, DEBUG);
- if (def_mount_opts & EXT4_DEFM_BSDGROUPS)
+ if (def_mount_opts & EXT4_DEFM_BSDGROUPS) {
+ ext4_msg(sb, KERN_WARNING, deprecated_msg, "bsdgroups",
+ "2.6.38");
set_opt(sbi->s_mount_opt, GRPID);
+ }
if (def_mount_opts & EXT4_DEFM_UID16)
set_opt(sbi->s_mount_opt, NO_UID32);
#ifdef CONFIG_EXT4_FS_XATTR
@@ -2445,11 +2528,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
set_opt(sbi->s_mount_opt, POSIX_ACL);
#endif
if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
- sbi->s_mount_opt |= EXT4_MOUNT_JOURNAL_DATA;
+ set_opt(sbi->s_mount_opt, JOURNAL_DATA);
else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED)
- sbi->s_mount_opt |= EXT4_MOUNT_ORDERED_DATA;
+ set_opt(sbi->s_mount_opt, ORDERED_DATA);
else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK)
- sbi->s_mount_opt |= EXT4_MOUNT_WRITEBACK_DATA;
+ set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC)
set_opt(sbi->s_mount_opt, ERRORS_PANIC);
@@ -2470,14 +2553,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
* enable delayed allocation by default
* Use -o nodelalloc to turn it off
*/
- set_opt(sbi->s_mount_opt, DELALLOC);
+ if (!IS_EXT3_SB(sb))
+ set_opt(sbi->s_mount_opt, DELALLOC);
if (!parse_options((char *) data, sb, &journal_devnum,
&journal_ioprio, NULL, 0))
goto failed_mount;
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
- ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+ (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
(EXT4_HAS_COMPAT_FEATURE(sb, ~0U) ||
@@ -2766,7 +2850,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
ext4_msg(sb, KERN_ERR, "required journal recovery "
"suppressed and not mounted read-only");
- goto failed_mount4;
+ goto failed_mount_wq;
} else {
clear_opt(sbi->s_mount_opt, DATA_FLAGS);
set_opt(sbi->s_mount_opt, WRITEBACK_DATA);
@@ -2779,7 +2863,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
!jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0,
JBD2_FEATURE_INCOMPAT_64BIT)) {
ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature");
- goto failed_mount4;
+ goto failed_mount_wq;
}
if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
@@ -2818,7 +2902,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
(sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) {
ext4_msg(sb, KERN_ERR, "Journal does not support "
"requested data journaling mode");
- goto failed_mount4;
+ goto failed_mount_wq;
}
default:
break;
@@ -2826,13 +2910,17 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
no_journal:
-
if (test_opt(sb, NOBH)) {
if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) {
ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - "
"its supported only with writeback mode");
clear_opt(sbi->s_mount_opt, NOBH);
}
+ if (test_opt(sb, DIOREAD_NOLOCK)) {
+ ext4_msg(sb, KERN_WARNING, "dioread_nolock option is "
+ "not supported with nobh mode");
+ goto failed_mount_wq;
+ }
}
EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten");
if (!EXT4_SB(sb)->dio_unwritten_wq) {
@@ -2897,6 +2985,18 @@ no_journal:
"requested data journaling mode");
clear_opt(sbi->s_mount_opt, DELALLOC);
}
+ if (test_opt(sb, DIOREAD_NOLOCK)) {
+ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
+ ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock "
+ "option - requested data journaling mode");
+ clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK);
+ }
+ if (sb->s_blocksize < PAGE_SIZE) {
+ ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock "
+ "option - block size is too small");
+ clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK);
+ }
+ }
err = ext4_setup_system_zone(sb);
if (err) {
@@ -3360,10 +3460,9 @@ static void ext4_clear_journal_err(struct super_block *sb,
char nbuf[16];
errstr = ext4_decode_error(sb, j_errno, nbuf);
- ext4_warning(sb, __func__, "Filesystem error recorded "
+ ext4_warning(sb, "Filesystem error recorded "
"from previous mount: %s", errstr);
- ext4_warning(sb, __func__, "Marking fs in need of "
- "filesystem check.");
+ ext4_warning(sb, "Marking fs in need of filesystem check.");
EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
@@ -3514,7 +3613,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
ext4_abort(sb, __func__, "Abort forced by user");
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
- ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+ (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
es = sbi->s_es;
@@ -3708,7 +3807,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
* Process 1 Process 2
* ext4_create() quota_sync()
* jbd2_journal_start() write_dquot()
- * vfs_dq_init() down(dqio_mutex)
+ * dquot_initialize() down(dqio_mutex)
* down(dqio_mutex) jbd2_journal_start()
*
*/
@@ -3917,9 +4016,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
int err = 0;
int offset = off & (sb->s_blocksize - 1);
- int tocopy;
int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL;
- size_t towrite = len;
struct buffer_head *bh;
handle_t *handle = journal_current_handle();
@@ -3929,52 +4026,53 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
(unsigned long long)off, (unsigned long long)len);
return -EIO;
}
+ /*
+ * Since we account only one data block in transaction credits,
+ * then it is impossible to cross a block boundary.
+ */
+ if (sb->s_blocksize - offset < len) {
+ ext4_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)"
+ " cancelled because not block aligned",
+ (unsigned long long)off, (unsigned long long)len);
+ return -EIO;
+ }
+
mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
- while (towrite > 0) {
- tocopy = sb->s_blocksize - offset < towrite ?
- sb->s_blocksize - offset : towrite;
- bh = ext4_bread(handle, inode, blk, 1, &err);
- if (!bh)
+ bh = ext4_bread(handle, inode, blk, 1, &err);
+ if (!bh)
+ goto out;
+ if (journal_quota) {
+ err = ext4_journal_get_write_access(handle, bh);
+ if (err) {
+ brelse(bh);
goto out;
- if (journal_quota) {
- err = ext4_journal_get_write_access(handle, bh);
- if (err) {
- brelse(bh);
- goto out;
- }
- }
- lock_buffer(bh);
- memcpy(bh->b_data+offset, data, tocopy);
- flush_dcache_page(bh->b_page);
- unlock_buffer(bh);
- if (journal_quota)
- err = ext4_handle_dirty_metadata(handle, NULL, bh);
- else {
- /* Always do at least ordered writes for quotas */
- err = ext4_jbd2_file_inode(handle, inode);
- mark_buffer_dirty(bh);
}
- brelse(bh);
- if (err)
- goto out;
- offset = 0;
- towrite -= tocopy;
- data += tocopy;
- blk++;
}
+ lock_buffer(bh);
+ memcpy(bh->b_data+offset, data, len);
+ flush_dcache_page(bh->b_page);
+ unlock_buffer(bh);
+ if (journal_quota)
+ err = ext4_handle_dirty_metadata(handle, NULL, bh);
+ else {
+ /* Always do at least ordered writes for quotas */
+ err = ext4_jbd2_file_inode(handle, inode);
+ mark_buffer_dirty(bh);
+ }
+ brelse(bh);
out:
- if (len == towrite) {
+ if (err) {
mutex_unlock(&inode->i_mutex);
return err;
}
- if (inode->i_size < off+len-towrite) {
- i_size_write(inode, off+len-towrite);
+ if (inode->i_size < off + len) {
+ i_size_write(inode, off + len);
EXT4_I(inode)->i_disksize = inode->i_size;
}
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
ext4_mark_inode_dirty(handle, inode);
mutex_unlock(&inode->i_mutex);
- return len - towrite;
+ return len;
}
#endif
@@ -3985,7 +4083,7 @@ static int ext4_get_sb(struct file_system_type *fs_type, int flags,
return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
}
-#if !defined(CONTIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
+#if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
static struct file_system_type ext2_fs_type = {
.owner = THIS_MODULE,
.name = "ext2",
@@ -4012,15 +4110,7 @@ static inline void register_as_ext2(void) { }
static inline void unregister_as_ext2(void) { }
#endif
-#if !defined(CONTIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
-static struct file_system_type ext3_fs_type = {
- .owner = THIS_MODULE,
- .name = "ext3",
- .get_sb = ext4_get_sb,
- .kill_sb = kill_block_super,
- .fs_flags = FS_REQUIRES_DEV,
-};
-
+#if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
static inline void register_as_ext3(void)
{
int err = register_filesystem(&ext3_fs_type);
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index f3a2f7ed45a..b4c5aa8489d 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -227,7 +227,8 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
ea_bdebug(bh, "b_count=%d, refcount=%d",
atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
if (ext4_xattr_check_block(bh)) {
-bad_block: ext4_error(inode->i_sb, __func__,
+bad_block:
+ ext4_error(inode->i_sb,
"inode %lu: bad block %llu", inode->i_ino,
EXT4_I(inode)->i_file_acl);
error = -EIO;
@@ -267,7 +268,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
void *end;
int error;
- if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR))
+ if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR))
return -ENODATA;
error = ext4_get_inode_loc(inode, &iloc);
if (error)
@@ -371,7 +372,7 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
ea_bdebug(bh, "b_count=%d, refcount=%d",
atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
if (ext4_xattr_check_block(bh)) {
- ext4_error(inode->i_sb, __func__,
+ ext4_error(inode->i_sb,
"inode %lu: bad block %llu", inode->i_ino,
EXT4_I(inode)->i_file_acl);
error = -EIO;
@@ -396,7 +397,7 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
void *end;
int error;
- if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR))
+ if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR))
return 0;
error = ext4_get_inode_loc(inode, &iloc);
if (error)
@@ -494,7 +495,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
error = ext4_handle_dirty_metadata(handle, inode, bh);
if (IS_SYNC(inode))
ext4_handle_sync(handle);
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
ea_bdebug(bh, "refcount now=%d; releasing",
le32_to_cpu(BHDR(bh)->h_refcount));
if (ce)
@@ -665,9 +666,8 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
atomic_read(&(bs->bh->b_count)),
le32_to_cpu(BHDR(bs->bh)->h_refcount));
if (ext4_xattr_check_block(bs->bh)) {
- ext4_error(sb, __func__,
- "inode %lu: bad block %llu", inode->i_ino,
- EXT4_I(inode)->i_file_acl);
+ ext4_error(sb, "inode %lu: bad block %llu",
+ inode->i_ino, EXT4_I(inode)->i_file_acl);
error = -EIO;
goto cleanup;
}
@@ -787,8 +787,8 @@ inserted:
else {
/* The old block is released after updating
the inode. */
- error = -EDQUOT;
- if (vfs_dq_alloc_block(inode, 1))
+ error = dquot_alloc_block(inode, 1);
+ if (error)
goto cleanup;
error = ext4_journal_get_write_access(handle,
new_bh);
@@ -876,13 +876,12 @@ cleanup:
return error;
cleanup_dquot:
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
goto cleanup;
bad_block:
- ext4_error(inode->i_sb, __func__,
- "inode %lu: bad block %llu", inode->i_ino,
- EXT4_I(inode)->i_file_acl);
+ ext4_error(inode->i_sb, "inode %lu: bad block %llu",
+ inode->i_ino, EXT4_I(inode)->i_file_acl);
goto cleanup;
#undef header
@@ -908,7 +907,7 @@ ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
is->s.base = is->s.first = IFIRST(header);
is->s.here = is->s.first;
is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
- if (EXT4_I(inode)->i_state & EXT4_STATE_XATTR) {
+ if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
error = ext4_xattr_check_names(IFIRST(header), is->s.end);
if (error)
return error;
@@ -940,10 +939,10 @@ ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
header = IHDR(inode, ext4_raw_inode(&is->iloc));
if (!IS_LAST_ENTRY(s->first)) {
header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
- EXT4_I(inode)->i_state |= EXT4_STATE_XATTR;
+ ext4_set_inode_state(inode, EXT4_STATE_XATTR);
} else {
header->h_magic = cpu_to_le32(0);
- EXT4_I(inode)->i_state &= ~EXT4_STATE_XATTR;
+ ext4_clear_inode_state(inode, EXT4_STATE_XATTR);
}
return 0;
}
@@ -986,8 +985,8 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
if (strlen(name) > 255)
return -ERANGE;
down_write(&EXT4_I(inode)->xattr_sem);
- no_expand = EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND;
- EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
+ no_expand = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND);
+ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
error = ext4_get_inode_loc(inode, &is.iloc);
if (error)
@@ -997,10 +996,10 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
if (error)
goto cleanup;
- if (EXT4_I(inode)->i_state & EXT4_STATE_NEW) {
+ if (ext4_test_inode_state(inode, EXT4_STATE_NEW)) {
struct ext4_inode *raw_inode = ext4_raw_inode(&is.iloc);
memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
- EXT4_I(inode)->i_state &= ~EXT4_STATE_NEW;
+ ext4_clear_inode_state(inode, EXT4_STATE_NEW);
}
error = ext4_xattr_ibody_find(inode, &i, &is);
@@ -1052,7 +1051,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
ext4_xattr_update_super_block(handle, inode->i_sb);
inode->i_ctime = ext4_current_time(inode);
if (!value)
- EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND;
+ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
/*
* The bh is consumed by ext4_mark_iloc_dirty, even with
@@ -1067,7 +1066,7 @@ cleanup:
brelse(is.iloc.bh);
brelse(bs.bh);
if (no_expand == 0)
- EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND;
+ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
up_write(&EXT4_I(inode)->xattr_sem);
return error;
}
@@ -1195,9 +1194,8 @@ retry:
if (!bh)
goto cleanup;
if (ext4_xattr_check_block(bh)) {
- ext4_error(inode->i_sb, __func__,
- "inode %lu: bad block %llu", inode->i_ino,
- EXT4_I(inode)->i_file_acl);
+ ext4_error(inode->i_sb, "inode %lu: bad block %llu",
+ inode->i_ino, EXT4_I(inode)->i_file_acl);
error = -EIO;
goto cleanup;
}
@@ -1302,6 +1300,8 @@ retry:
/* Remove the chosen entry from the inode */
error = ext4_xattr_ibody_set(handle, inode, &i, is);
+ if (error)
+ goto cleanup;
entry = IFIRST(header);
if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize)
@@ -1372,16 +1372,14 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode)
goto cleanup;
bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
if (!bh) {
- ext4_error(inode->i_sb, __func__,
- "inode %lu: block %llu read error", inode->i_ino,
- EXT4_I(inode)->i_file_acl);
+ ext4_error(inode->i_sb, "inode %lu: block %llu read error",
+ inode->i_ino, EXT4_I(inode)->i_file_acl);
goto cleanup;
}
if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
BHDR(bh)->h_blocks != cpu_to_le32(1)) {
- ext4_error(inode->i_sb, __func__,
- "inode %lu: bad block %llu", inode->i_ino,
- EXT4_I(inode)->i_file_acl);
+ ext4_error(inode->i_sb, "inode %lu: bad block %llu",
+ inode->i_ino, EXT4_I(inode)->i_file_acl);
goto cleanup;
}
ext4_xattr_release_block(handle, inode, bh);
@@ -1506,7 +1504,7 @@ again:
}
bh = sb_bread(inode->i_sb, ce->e_block);
if (!bh) {
- ext4_error(inode->i_sb, __func__,
+ ext4_error(inode->i_sb,
"inode %lu: block %lu read error",
inode->i_ino, (unsigned long) ce->e_block);
} else if (le32_to_cpu(BHDR(bh)->h_refcount) >=
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index 983c253999a..8b145e98df0 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -7,6 +7,7 @@
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/security.h>
+#include <linux/slab.h>
#include "ext4_jbd2.h"
#include "ext4.h"
#include "xattr.h"
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 923990e4f16..113f0a1e565 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -9,6 +9,7 @@
*/
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/buffer_head.h>
#include "fat.h"
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 14da530b05c..0ce143bd7d5 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -558,7 +558,7 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_bavail = sbi->free_clusters;
buf->f_fsid.val[0] = (u32)id;
buf->f_fsid.val[1] = (u32)(id >> 32);
- buf->f_namelen = sbi->options.isvfat ? 260 : 12;
+ buf->f_namelen = sbi->options.isvfat ? FAT_LFN_LEN : 12;
return 0;
}
@@ -577,7 +577,7 @@ static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi,
return i_pos;
}
-static int fat_write_inode(struct inode *inode, int wait)
+static int __fat_write_inode(struct inode *inode, int wait)
{
struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -634,9 +634,14 @@ retry:
return err;
}
+static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ return __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
+}
+
int fat_sync_inode(struct inode *inode)
{
- return fat_write_inode(inode, 1);
+ return __fat_write_inode(inode, 1);
}
EXPORT_SYMBOL_GPL(fat_sync_inode);
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index f565f24019b..6fcc7e71fba 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -309,7 +309,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
{
struct fat_mount_options *opts = &MSDOS_SB(dir->i_sb)->options;
wchar_t *ip, *ext_start, *end, *name_start;
- unsigned char base[9], ext[4], buf[8], *p;
+ unsigned char base[9], ext[4], buf[5], *p;
unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
int chl, chi;
int sz = 0, extlen, baselen, i, numtail_baselen, numtail2_baselen;
@@ -467,7 +467,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
return 0;
}
- i = jiffies & 0xffff;
+ i = jiffies;
sz = (jiffies >> 16) & 0x7;
if (baselen > 2) {
baselen = numtail2_baselen;
@@ -476,7 +476,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
name_res[baselen + 4] = '~';
name_res[baselen + 5] = '1' + sz;
while (1) {
- sprintf(buf, "%04X", i);
+ snprintf(buf, sizeof(buf), "%04X", i & 0xffff);
memcpy(&name_res[baselen], buf, 4);
if (vfat_find_form(dir, name_res) < 0)
break;
@@ -502,14 +502,14 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
*outlen = utf8s_to_utf16s(name, len, (wchar_t *)outname);
if (*outlen < 0)
return *outlen;
- else if (*outlen > 255)
+ else if (*outlen > FAT_LFN_LEN)
return -ENAMETOOLONG;
op = &outname[*outlen * sizeof(wchar_t)];
} else {
if (nls) {
for (i = 0, ip = name, op = outname, *outlen = 0;
- i < len && *outlen <= 255;
+ i < len && *outlen <= FAT_LFN_LEN;
*outlen += 1)
{
if (escape && (*ip == ':')) {
@@ -549,7 +549,7 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
return -ENAMETOOLONG;
} else {
for (i = 0, ip = name, op = outname, *outlen = 0;
- i < len && *outlen <= 255;
+ i < len && *outlen <= FAT_LFN_LEN;
i++, *outlen += 1)
{
*op++ = *ip++;
@@ -701,6 +701,15 @@ static int vfat_find(struct inode *dir, struct qstr *qname,
return fat_search_long(dir, qname->name, len, sinfo);
}
+/*
+ * (nfsd's) anonymous disconnected dentry?
+ * NOTE: !IS_ROOT() is not anonymous (I.e. d_splice_alias() did the job).
+ */
+static int vfat_d_anon_disconn(struct dentry *dentry)
+{
+ return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED);
+}
+
static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
@@ -729,11 +738,11 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
}
alias = d_find_alias(inode);
- if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
+ if (alias && !vfat_d_anon_disconn(alias)) {
/*
- * This inode has non DCACHE_DISCONNECTED dentry. This
- * means, the user did ->lookup() by an another name
- * (longname vs 8.3 alias of it) in past.
+ * This inode has non anonymous-DCACHE_DISCONNECTED
+ * dentry. This means, the user did ->lookup() by an
+ * another name (longname vs 8.3 alias of it) in past.
*
* Switch to new one for reason of locality if possible.
*/
@@ -743,7 +752,9 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
iput(inode);
unlock_super(sb);
return alias;
- }
+ } else
+ dput(alias);
+
out:
unlock_super(sb);
dentry->d_op = sb->s_root->d_op;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 97e01dc0d95..452d02f9075 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -344,7 +344,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
switch (cmd) {
case F_DUPFD:
case F_DUPFD_CLOEXEC:
- if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+ if (arg >= rlimit(RLIMIT_NOFILE))
break;
err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
if (err >= 0) {
diff --git a/fs/fifo.c b/fs/fifo.c
index f8f97b8b6d4..5d6606ffc2d 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -10,7 +10,6 @@
*/
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/pipe_fs_i.h>
diff --git a/fs/file.c b/fs/file.c
index 38039af6766..34bb7f71d99 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -257,7 +257,7 @@ int expand_files(struct files_struct *files, int nr)
* N.B. For clone tasks sharing a files structure, this test
* will limit the total number of files that can be opened.
*/
- if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+ if (nr >= rlimit(RLIMIT_NOFILE))
return -EMFILE;
/* Do we need to expand? */
diff --git a/fs/file_table.c b/fs/file_table.c
index b98404b5438..32d12b78bac 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -393,7 +393,9 @@ retry:
continue;
if (!(f->f_mode & FMODE_WRITE))
continue;
+ spin_lock(&f->f_lock);
f->f_mode &= ~FMODE_WRITE;
+ spin_unlock(&f->f_lock);
if (file_check_writeable(f) != 0)
continue;
file_release_write(f);
diff --git a/fs/filesystems.c b/fs/filesystems.c
index a24c58e181d..68ba492d8ee 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -10,10 +10,10 @@
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
/*
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
index ed8f0b0dd88..1429f3ae1e8 100644
--- a/fs/freevxfs/vxfs_subr.c
+++ b/fs/freevxfs/vxfs_subr.c
@@ -33,7 +33,6 @@
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/pagemap.h>
#include "vxfs_extern.h"
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 1a7c42c64ff..4b37f7cea4d 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h>
@@ -381,10 +382,10 @@ static void queue_io(struct bdi_writeback *wb, unsigned long *older_than_this)
move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this);
}
-static int write_inode(struct inode *inode, int sync)
+static int write_inode(struct inode *inode, struct writeback_control *wbc)
{
if (inode->i_sb->s_op->write_inode && !is_bad_inode(inode))
- return inode->i_sb->s_op->write_inode(inode, sync);
+ return inode->i_sb->s_op->write_inode(inode, wbc);
return 0;
}
@@ -421,7 +422,6 @@ static int
writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
{
struct address_space *mapping = inode->i_mapping;
- int wait = wbc->sync_mode == WB_SYNC_ALL;
unsigned dirty;
int ret;
@@ -439,7 +439,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
* We'll have another go at writing back this inode when we
* completed a full scan of b_io.
*/
- if (!wait) {
+ if (wbc->sync_mode != WB_SYNC_ALL) {
requeue_io(inode);
return 0;
}
@@ -461,15 +461,20 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
ret = do_writepages(mapping, wbc);
- /* Don't write the inode if only I_DIRTY_PAGES was set */
- if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
- int err = write_inode(inode, wait);
+ /*
+ * Make sure to wait on the data before writing out the metadata.
+ * This is important for filesystems that modify metadata on data
+ * I/O completion.
+ */
+ if (wbc->sync_mode == WB_SYNC_ALL) {
+ int err = filemap_fdatawait(mapping);
if (ret == 0)
ret = err;
}
- if (wait) {
- int err = filemap_fdatawait(mapping);
+ /* Don't write the inode if only I_DIRTY_PAGES was set */
+ if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
+ int err = write_inode(inode, wbc);
if (ret == 0)
ret = err;
}
@@ -549,108 +554,85 @@ select_queue:
return ret;
}
-static void unpin_sb_for_writeback(struct super_block **psb)
+static void unpin_sb_for_writeback(struct super_block *sb)
{
- struct super_block *sb = *psb;
-
- if (sb) {
- up_read(&sb->s_umount);
- put_super(sb);
- *psb = NULL;
- }
+ up_read(&sb->s_umount);
+ put_super(sb);
}
+enum sb_pin_state {
+ SB_PINNED,
+ SB_NOT_PINNED,
+ SB_PIN_FAILED
+};
+
/*
* For WB_SYNC_NONE writeback, the caller does not have the sb pinned
* before calling writeback. So make sure that we do pin it, so it doesn't
* go away while we are writing inodes from it.
- *
- * Returns 0 if the super was successfully pinned (or pinning wasn't needed),
- * 1 if we failed.
*/
-static int pin_sb_for_writeback(struct writeback_control *wbc,
- struct inode *inode, struct super_block **psb)
+static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc,
+ struct super_block *sb)
{
- struct super_block *sb = inode->i_sb;
-
- /*
- * If this sb is already pinned, nothing more to do. If not and
- * *psb is non-NULL, unpin the old one first
- */
- if (sb == *psb)
- return 0;
- else if (*psb)
- unpin_sb_for_writeback(psb);
-
/*
* Caller must already hold the ref for this
*/
if (wbc->sync_mode == WB_SYNC_ALL) {
WARN_ON(!rwsem_is_locked(&sb->s_umount));
- return 0;
+ return SB_NOT_PINNED;
}
-
spin_lock(&sb_lock);
sb->s_count++;
if (down_read_trylock(&sb->s_umount)) {
if (sb->s_root) {
spin_unlock(&sb_lock);
- goto pinned;
+ return SB_PINNED;
}
/*
* umounted, drop rwsem again and fall through to failure
*/
up_read(&sb->s_umount);
}
-
sb->s_count--;
spin_unlock(&sb_lock);
- return 1;
-pinned:
- *psb = sb;
- return 0;
+ return SB_PIN_FAILED;
}
-static void writeback_inodes_wb(struct bdi_writeback *wb,
- struct writeback_control *wbc)
+/*
+ * Write a portion of b_io inodes which belong to @sb.
+ * If @wbc->sb != NULL, then find and write all such
+ * inodes. Otherwise write only ones which go sequentially
+ * in reverse order.
+ * Return 1, if the caller writeback routine should be
+ * interrupted. Otherwise return 0.
+ */
+static int writeback_sb_inodes(struct super_block *sb,
+ struct bdi_writeback *wb,
+ struct writeback_control *wbc)
{
- struct super_block *sb = wbc->sb, *pin_sb = NULL;
- const unsigned long start = jiffies; /* livelock avoidance */
-
- spin_lock(&inode_lock);
-
- if (!wbc->for_kupdate || list_empty(&wb->b_io))
- queue_io(wb, wbc->older_than_this);
-
while (!list_empty(&wb->b_io)) {
- struct inode *inode = list_entry(wb->b_io.prev,
- struct inode, i_list);
long pages_skipped;
-
- /*
- * super block given and doesn't match, skip this inode
- */
- if (sb && sb != inode->i_sb) {
+ struct inode *inode = list_entry(wb->b_io.prev,
+ struct inode, i_list);
+ if (wbc->sb && sb != inode->i_sb) {
+ /* super block given and doesn't
+ match, skip this inode */
redirty_tail(inode);
continue;
}
-
+ if (sb != inode->i_sb)
+ /* finish with this superblock */
+ return 0;
if (inode->i_state & (I_NEW | I_WILL_FREE)) {
requeue_io(inode);
continue;
}
-
/*
* Was this inode dirtied after sync_sb_inodes was called?
* This keeps sync from extra jobs and livelock.
*/
- if (inode_dirtied_after(inode, start))
- break;
-
- if (pin_sb_for_writeback(wbc, inode, &pin_sb)) {
- requeue_io(inode);
- continue;
- }
+ if (inode_dirtied_after(inode, wbc->wb_start))
+ return 1;
BUG_ON(inode->i_state & (I_FREEING | I_CLEAR));
__iget(inode);
@@ -669,14 +651,50 @@ static void writeback_inodes_wb(struct bdi_writeback *wb,
spin_lock(&inode_lock);
if (wbc->nr_to_write <= 0) {
wbc->more_io = 1;
- break;
+ return 1;
}
if (!list_empty(&wb->b_more_io))
wbc->more_io = 1;
}
+ /* b_io is empty */
+ return 1;
+}
+
+static void writeback_inodes_wb(struct bdi_writeback *wb,
+ struct writeback_control *wbc)
+{
+ int ret = 0;
+
+ wbc->wb_start = jiffies; /* livelock avoidance */
+ spin_lock(&inode_lock);
+ if (!wbc->for_kupdate || list_empty(&wb->b_io))
+ queue_io(wb, wbc->older_than_this);
+
+ while (!list_empty(&wb->b_io)) {
+ struct inode *inode = list_entry(wb->b_io.prev,
+ struct inode, i_list);
+ struct super_block *sb = inode->i_sb;
+ enum sb_pin_state state;
- unpin_sb_for_writeback(&pin_sb);
+ if (wbc->sb && sb != wbc->sb) {
+ /* super block given and doesn't
+ match, skip this inode */
+ redirty_tail(inode);
+ continue;
+ }
+ state = pin_sb_for_writeback(wbc, sb);
+ if (state == SB_PIN_FAILED) {
+ requeue_io(inode);
+ continue;
+ }
+ ret = writeback_sb_inodes(sb, wb, wbc);
+
+ if (state == SB_PINNED)
+ unpin_sb_for_writeback(sb);
+ if (ret)
+ break;
+ }
spin_unlock(&inode_lock);
/* Leave any unwritten inodes on b_io */
}
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig
index 864dac20a24..cc94bb9563f 100644
--- a/fs/fscache/Kconfig
+++ b/fs/fscache/Kconfig
@@ -1,7 +1,6 @@
config FSCACHE
tristate "General filesystem local caching manager"
- depends on EXPERIMENTAL
select SLOW_WORK
help
This option enables a generic filesystem caching manager that can be
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
index 3221a0c7944..1e1f286dd70 100644
--- a/fs/fscache/object-list.c
+++ b/fs/fscache/object-list.c
@@ -12,6 +12,7 @@
#define FSCACHE_DEBUG_LEVEL COOKIE
#include <linux/module.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/key.h>
#include <keys/user-type.h>
#include "internal.h"
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index e513ac599c8..0b589a9b4ff 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -53,7 +53,7 @@ const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = {
static void fscache_object_slow_work_put_ref(struct slow_work *);
static int fscache_object_slow_work_get_ref(struct slow_work *);
static void fscache_object_slow_work_execute(struct slow_work *);
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *);
#endif
static void fscache_initialise_object(struct fscache_object *);
@@ -69,7 +69,7 @@ const struct slow_work_ops fscache_object_slow_work_ops = {
.get_ref = fscache_object_slow_work_get_ref,
.put_ref = fscache_object_slow_work_put_ref,
.execute = fscache_object_slow_work_execute,
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
.desc = fscache_object_slow_work_desc,
#endif
};
@@ -364,7 +364,7 @@ static void fscache_object_slow_work_execute(struct slow_work *work)
/*
* describe an object for slow-work debugging
*/
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
static void fscache_object_slow_work_desc(struct slow_work *work,
struct seq_file *m)
{
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index 313e79a1426..f17cecafae4 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
@@ -14,6 +14,7 @@
#define FSCACHE_DEBUG_LEVEL OPERATION
#include <linux/module.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "internal.h"
atomic_t fscache_op_debug_id;
@@ -500,7 +501,7 @@ static void fscache_op_execute(struct slow_work *work)
/*
* describe an operation for slow-work debugging
*/
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
static void fscache_op_desc(struct slow_work *work, struct seq_file *m)
{
struct fscache_operation *op =
@@ -517,7 +518,7 @@ const struct slow_work_ops fscache_op_slow_work_ops = {
.get_ref = fscache_op_get_ref,
.put_ref = fscache_op_put_ref,
.execute = fscache_op_execute,
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
.desc = fscache_op_desc,
#endif
};
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index c598ea4c4e7..47aefd376e5 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -14,6 +14,7 @@
#include <linux/fscache-cache.h>
#include <linux/buffer_head.h>
#include <linux/pagevec.h>
+#include <linux/slab.h>
#include "internal.h"
/*
@@ -881,6 +882,7 @@ submit_failed:
goto nobufs;
nobufs_unlock_obj:
+ spin_unlock(&cookie->stores_lock);
spin_unlock(&object->lock);
nobufs:
spin_unlock(&cookie->lock);
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
index 46435f3aae6..4765190d537 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
@@ -165,8 +165,8 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_object_lookups),
atomic_read(&fscache_n_object_lookups_negative),
atomic_read(&fscache_n_object_lookups_positive),
- atomic_read(&fscache_n_object_lookups_timed_out),
- atomic_read(&fscache_n_object_created));
+ atomic_read(&fscache_n_object_created),
+ atomic_read(&fscache_n_object_lookups_timed_out));
seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
atomic_read(&fscache_n_updates),
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index de792dcf327..e1f8171278b 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -44,6 +44,7 @@
#include <linux/magic.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stat.h>
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 1a822ce2b24..ec14d19ce50 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -850,7 +850,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
req->in.args[0].size = sizeof(*arg);
req->in.args[0].value = arg;
req->out.numargs = 1;
- /* Variable length arguement used for backward compatibility
+ /* Variable length argument used for backward compatibility
with interface version < 7.5. Rest of init_out is zeroed
by do_get_request(), so a short reply is not a problem */
req->out.argvar = 1;
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
index 55458031e50..fe5df545765 100644
--- a/fs/generic_acl.c
+++ b/fs/generic_acl.c
@@ -7,6 +7,7 @@
*/
#include <linux/sched.h>
+#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/generic_acl.h>
#include <linux/posix_acl.h>
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig
index 4dcddf83326..a47b4310711 100644
--- a/fs/gfs2/Kconfig
+++ b/fs/gfs2/Kconfig
@@ -8,7 +8,6 @@ config GFS2_FS
select FS_POSIX_ACL
select CRC32
select SLOW_WORK
- select QUOTA
select QUOTACTL
help
A cluster filesystem.
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 583e823307a..5e411d5f469 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c
index 91beddadd38..bb7907bde3d 100644
--- a/fs/gfs2/dentry.c
+++ b/fs/gfs2/dentry.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c
index d15876e9aa2..c22c2117483 100644
--- a/fs/gfs2/export.c
+++ b/fs/gfs2/export.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index a6abbae8a27..e6dd2aec6f8 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -640,7 +640,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
if (!(fl->fl_flags & FL_POSIX))
return -ENOLCK;
- if (__mandatory_lock(&ip->i_inode))
+ if (__mandatory_lock(&ip->i_inode) && fl->fl_type != F_UNLCK)
return -ENOLCK;
if (cmd == F_CANCELLK) {
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 38e3749d476..49f97d3bb69 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index b8025e51cab..3aac46f6853 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -616,7 +616,7 @@ struct gfs2_sbd {
unsigned int sd_log_blks_reserved;
unsigned int sd_log_commited_buf;
unsigned int sd_log_commited_databuf;
- unsigned int sd_log_commited_revoke;
+ int sd_log_commited_revoke;
unsigned int sd_log_num_buf;
unsigned int sd_log_num_revoke;
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index 569b46240f6..0e0470ed34c 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -9,6 +9,7 @@
#include <linux/fs.h>
#include <linux/dlm.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/gfs2_ondisk.h>
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 4511b08fc45..e5bf4b59d46 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -417,7 +417,7 @@ static unsigned int calc_reserved(struct gfs2_sbd *sdp)
databufhdrs_needed = (sdp->sd_log_commited_databuf +
(dbuf_limit - 1)) / dbuf_limit;
- if (sdp->sd_log_commited_revoke)
+ if (sdp->sd_log_commited_revoke > 0)
revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
sizeof(u64));
@@ -790,7 +790,6 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) ||
(((int)sdp->sd_log_commited_databuf) >= 0));
sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm;
- gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0);
reserved = calc_reserved(sdp);
gfs2_assert_withdraw(sdp, sdp->sd_log_blks_reserved + tr->tr_reserved >= reserved);
unused = sdp->sd_log_blks_reserved - reserved + tr->tr_reserved;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index a054b526dc0..c1309ed1c49 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1001,7 +1001,7 @@ static const struct lm_lockops nolock_ops = {
/**
* gfs2_lm_mount - mount a locking protocol
* @sdp: the filesystem
- * @args: mount arguements
+ * @args: mount arguments
* @silent: if 1, don't complain if the FS isn't a GFS2 fs
*
* Returns: errno
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index e3bf6eab875..6dbcbad6ab1 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1083,7 +1083,7 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
}
}
-int gfs2_quota_sync(struct super_block *sb, int type)
+int gfs2_quota_sync(struct super_block *sb, int type, int wait)
{
struct gfs2_sbd *sdp = sb->s_fs_info;
struct gfs2_quota_data **qda;
@@ -1127,6 +1127,11 @@ int gfs2_quota_sync(struct super_block *sb, int type)
return error;
}
+static int gfs2_quota_sync_timeo(struct super_block *sb, int type)
+{
+ return gfs2_quota_sync(sb, type, 0);
+}
+
int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
{
struct gfs2_quota_data *qd;
@@ -1382,7 +1387,7 @@ int gfs2_quotad(void *data)
&tune->gt_statfs_quantum);
/* Update quota file */
- quotad_check_timeo(sdp, "sync", gfs2_quota_sync, t,
+ quotad_check_timeo(sdp, "sync", gfs2_quota_sync_timeo, t,
&quotad_timeo, &tune->gt_quota_quantum);
/* Check for & recover partially truncated inodes */
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index e271fa07ad0..195f60c8bd1 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -25,7 +25,7 @@ extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid);
extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
u32 uid, u32 gid);
-extern int gfs2_quota_sync(struct super_block *sb, int type);
+extern int gfs2_quota_sync(struct super_block *sb, int type, int wait);
extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id);
extern int gfs2_quota_init(struct gfs2_sbd *sdp);
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index b4106ddaaa9..f07119d8955 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -10,6 +10,8 @@
#ifndef __RGRP_DOT_H__
#define __RGRP_DOT_H__
+#include <linux/slab.h>
+
struct gfs2_rgrpd;
struct gfs2_sbd;
struct gfs2_holder;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index e5e22629da6..50aac606b99 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -22,6 +22,7 @@
#include <linux/crc32.h>
#include <linux/time.h>
#include <linux/wait.h>
+#include <linux/writeback.h>
#include "gfs2.h"
#include "incore.h"
@@ -711,7 +712,7 @@ void gfs2_unfreeze_fs(struct gfs2_sbd *sdp)
* Returns: errno
*/
-static int gfs2_write_inode(struct inode *inode, int sync)
+static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -745,7 +746,7 @@ static int gfs2_write_inode(struct inode *inode, int sync)
do_unlock:
gfs2_glock_dq_uninit(&gh);
do_flush:
- if (sync != 0)
+ if (wbc->sync_mode == WB_SYNC_ALL)
gfs2_log_flush(GFS2_SB(inode), ip->i_gl);
return ret;
}
@@ -763,7 +764,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
int error;
flush_workqueue(gfs2_delete_workqueue);
- gfs2_quota_sync(sdp->sd_vfs, 0);
+ gfs2_quota_sync(sdp->sd_vfs, 0, 1);
gfs2_statfs_sync(sdp->sd_vfs, 0);
error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index a0db1c94317..54fd9842599 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -8,7 +8,6 @@
*/
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
@@ -49,7 +48,7 @@ static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr,
return a->store ? a->store(sdp, buf, len) : len;
}
-static struct sysfs_ops gfs2_attr_ops = {
+static const struct sysfs_ops gfs2_attr_ops = {
.show = gfs2_attr_show,
.store = gfs2_attr_store,
};
@@ -167,7 +166,7 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
if (simple_strtol(buf, NULL, 0) != 1)
return -EINVAL;
- gfs2_quota_sync(sdp->sd_vfs, 0);
+ gfs2_quota_sync(sdp->sd_vfs, 0, 1);
return len;
}
@@ -574,7 +573,7 @@ static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
return 0;
}
-static struct kset_uevent_ops gfs2_uevent_ops = {
+static const struct kset_uevent_ops gfs2_uevent_ops = {
.uevent = gfs2_uevent,
};
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 226f2bfbf16..53511291fe3 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c
index 0d200068d0a..cdb41a1f6a6 100644
--- a/fs/hfs/bnode.c
+++ b/fs/hfs/bnode.c
@@ -9,6 +9,7 @@
*/
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <linux/swap.h>
#include "btree.h"
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
index 052f214ea6f..38a0a9917d7 100644
--- a/fs/hfs/btree.c
+++ b/fs/hfs/btree.c
@@ -9,6 +9,7 @@
*/
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <linux/log2.h>
#include "btree.h"
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index 052387e1167..fe35e3b626c 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -188,7 +188,7 @@ extern const struct address_space_operations hfs_btree_aops;
extern struct inode *hfs_new_inode(struct inode *, struct qstr *, int);
extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *);
-extern int hfs_write_inode(struct inode *, int);
+extern int hfs_write_inode(struct inode *, struct writeback_control *);
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);
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index a1cbff2b4d9..14f5cb1b9fd 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -381,7 +381,7 @@ void hfs_inode_write_fork(struct inode *inode, struct hfs_extent *ext,
HFS_SB(inode->i_sb)->alloc_blksz);
}
-int hfs_write_inode(struct inode *inode, int unused)
+int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct inode *main_inode = inode;
struct hfs_find_data fd;
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c
index 8bbe03c3f6d..86428f5ac99 100644
--- a/fs/hfs/mdb.c
+++ b/fs/hfs/mdb.c
@@ -11,6 +11,7 @@
#include <linux/cdrom.h>
#include <linux/genhd.h>
#include <linux/nls.h>
+#include <linux/slab.h>
#include "hfs_fs.h"
#include "btree.h"
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 5ed7252b7b2..0a81eb7111f 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -19,6 +19,7 @@
#include <linux/nls.h>
#include <linux/parser.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/vfs.h>
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
index 3fcbb0e1f6f..572628b4b07 100644
--- a/fs/hfsplus/options.c
+++ b/fs/hfsplus/options.c
@@ -15,6 +15,7 @@
#include <linux/nls.h>
#include <linux/mount.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "hfsplus_fs.h"
enum {
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 43022f3d514..74b473a8ef9 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -87,7 +87,8 @@ bad_inode:
return ERR_PTR(err);
}
-static int hfsplus_write_inode(struct inode *inode, int unused)
+static int hfsplus_write_inode(struct inode *inode,
+ struct writeback_control *wbc)
{
struct hfsplus_vh *vhdr;
int ret = 0;
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 032604e5ef2..3a029d8f4cf 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -11,6 +11,7 @@
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/statfs.h>
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include "hostfs.h"
diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c
index b6fca543544..eac5f96323e 100644
--- a/fs/hpfs/buffer.c
+++ b/fs/hpfs/buffer.c
@@ -6,6 +6,7 @@
* general buffer i/o
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include "hpfs_fn.h"
void hpfs_lock_creation(struct super_block *s)
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c
index 26e3964a4b8..2338130cceb 100644
--- a/fs/hpfs/dir.c
+++ b/fs/hpfs/dir.c
@@ -7,6 +7,7 @@
*/
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include "hpfs_fn.h"
static int hpfs_dir_release(struct inode *inode, struct file *filp)
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
index ff90affb94e..1042a9bc97f 100644
--- a/fs/hpfs/inode.c
+++ b/fs/hpfs/inode.c
@@ -7,6 +7,7 @@
*/
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include "hpfs_fn.h"
void hpfs_init_inode(struct inode *i)
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index cadc4ce4865..aa53842c599 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -15,6 +15,7 @@
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/bitmap.h>
+#include <linux/slab.h>
/* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
diff --git a/fs/inode.c b/fs/inode.c
index 03dfeb2e392..407bf392e20 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -8,7 +8,6 @@
#include <linux/mm.h>
#include <linux/dcache.h>
#include <linux/init.h>
-#include <linux/quotaops.h>
#include <linux/slab.h>
#include <linux/writeback.h>
#include <linux/module.h>
@@ -314,7 +313,6 @@ void clear_inode(struct inode *inode)
BUG_ON(!(inode->i_state & I_FREEING));
BUG_ON(inode->i_state & I_CLEAR);
inode_sync_wait(inode);
- vfs_dq_drop(inode);
if (inode->i_sb->s_op->clear_inode)
inode->i_sb->s_op->clear_inode(inode);
if (S_ISBLK(inode->i_mode) && inode->i_bdev)
@@ -1211,8 +1209,6 @@ void generic_delete_inode(struct inode *inode)
if (op->delete_inode) {
void (*delete)(struct inode *) = op->delete_inode;
- if (!is_bad_inode(inode))
- vfs_dq_init(inode);
/* Filesystems implementing their own
* s_op->delete_inode are required to call
* truncate_inode_pages and clear_inode()
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 6c751106c2e..7faefb4da93 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -228,14 +228,23 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
#ifdef CONFIG_BLOCK
-#define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits)
-#define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits);
+static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
+{
+ return (offset >> inode->i_blkbits);
+}
+
+static inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
+{
+ return (blk << inode->i_blkbits);
+}
/**
* __generic_block_fiemap - FIEMAP for block based inodes (no locking)
- * @inode - the inode to map
- * @arg - the pointer to userspace where we copy everything to
- * @get_block - the fs's get_block function
+ * @inode: the inode to map
+ * @fieinfo: the fiemap info struct that will be passed back to userspace
+ * @start: where to start mapping in the inode
+ * @len: how much space to map
+ * @get_block: the fs's get_block function
*
* This does FIEMAP for block based inodes. Basically it will just loop
* through get_block until we hit the number of extents we want to map, or we
@@ -250,58 +259,63 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
*/
int __generic_block_fiemap(struct inode *inode,
- struct fiemap_extent_info *fieinfo, u64 start,
- u64 len, get_block_t *get_block)
+ struct fiemap_extent_info *fieinfo, loff_t start,
+ loff_t len, get_block_t *get_block)
{
- struct buffer_head tmp;
- unsigned long long start_blk;
- long long length = 0, map_len = 0;
+ struct buffer_head map_bh;
+ sector_t start_blk, last_blk;
+ loff_t isize = i_size_read(inode);
u64 logical = 0, phys = 0, size = 0;
u32 flags = FIEMAP_EXTENT_MERGED;
- int ret = 0, past_eof = 0, whole_file = 0;
+ bool past_eof = false, whole_file = false;
+ int ret = 0;
- if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC)))
+ ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
+ if (ret)
return ret;
- start_blk = logical_to_blk(inode, start);
-
- length = (long long)min_t(u64, len, i_size_read(inode));
- if (length < len)
- whole_file = 1;
+ /*
+ * Either the i_mutex or other appropriate locking needs to be held
+ * since we expect isize to not change at all through the duration of
+ * this call.
+ */
+ if (len >= isize) {
+ whole_file = true;
+ len = isize;
+ }
- map_len = length;
+ start_blk = logical_to_blk(inode, start);
+ last_blk = logical_to_blk(inode, start + len - 1);
do {
/*
* we set b_size to the total size we want so it will map as
* many contiguous blocks as possible at once
*/
- memset(&tmp, 0, sizeof(struct buffer_head));
- tmp.b_size = map_len;
+ memset(&map_bh, 0, sizeof(struct buffer_head));
+ map_bh.b_size = len;
- ret = get_block(inode, start_blk, &tmp, 0);
+ ret = get_block(inode, start_blk, &map_bh, 0);
if (ret)
break;
/* HOLE */
- if (!buffer_mapped(&tmp)) {
- length -= blk_to_logical(inode, 1);
+ if (!buffer_mapped(&map_bh)) {
start_blk++;
/*
- * we want to handle the case where there is an
+ * We want to handle the case where there is an
* allocated block at the front of the file, and then
* nothing but holes up to the end of the file properly,
* to make sure that extent at the front gets properly
* marked with FIEMAP_EXTENT_LAST
*/
if (!past_eof &&
- blk_to_logical(inode, start_blk) >=
- blk_to_logical(inode, 0)+i_size_read(inode))
+ blk_to_logical(inode, start_blk) >= isize)
past_eof = 1;
/*
- * first hole after going past the EOF, this is our
+ * First hole after going past the EOF, this is our
* last extent
*/
if (past_eof && size) {
@@ -309,15 +323,18 @@ int __generic_block_fiemap(struct inode *inode,
ret = fiemap_fill_next_extent(fieinfo, logical,
phys, size,
flags);
- break;
+ } else if (size) {
+ ret = fiemap_fill_next_extent(fieinfo, logical,
+ phys, size, flags);
+ size = 0;
}
/* if we have holes up to/past EOF then we're done */
- if (length <= 0 || past_eof)
+ if (start_blk > last_blk || past_eof || ret)
break;
} else {
/*
- * we have gone over the length of what we wanted to
+ * We have gone over the length of what we wanted to
* map, and it wasn't the entire file, so add the extent
* we got last time and exit.
*
@@ -331,7 +348,7 @@ int __generic_block_fiemap(struct inode *inode,
* are good to go, just add the extent to the fieinfo
* and break
*/
- if (length <= 0 && !whole_file) {
+ if (start_blk > last_blk && !whole_file) {
ret = fiemap_fill_next_extent(fieinfo, logical,
phys, size,
flags);
@@ -351,11 +368,10 @@ int __generic_block_fiemap(struct inode *inode,
}
logical = blk_to_logical(inode, start_blk);
- phys = blk_to_logical(inode, tmp.b_blocknr);
- size = tmp.b_size;
+ phys = blk_to_logical(inode, map_bh.b_blocknr);
+ size = map_bh.b_size;
flags = FIEMAP_EXTENT_MERGED;
- length -= tmp.b_size;
start_blk += logical_to_blk(inode, size);
/*
@@ -363,15 +379,13 @@ int __generic_block_fiemap(struct inode *inode,
* soon as we find a hole that the last extent we found
* is marked with FIEMAP_EXTENT_LAST
*/
- if (!past_eof &&
- logical+size >=
- blk_to_logical(inode, 0)+i_size_read(inode))
- past_eof = 1;
+ if (!past_eof && logical + size >= isize)
+ past_eof = true;
}
cond_resched();
} while (1);
- /* if ret is 1 then we just hit the end of the extent array */
+ /* If ret is 1 then we just hit the end of the extent array */
if (ret == 1)
ret = 0;
diff --git a/fs/ioprio.c b/fs/ioprio.c
index c7c0b28d7d2..748cfb92dcc 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -19,6 +19,7 @@
* See also Documentation/block/ioprio.txt
*
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/ioprio.h>
#include <linux/blkdev.h>
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
index 8ba5441063b..b9ab69b3a48 100644
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -11,6 +11,7 @@
* isofs directory handling functions
*/
#include <linux/smp_lock.h>
+#include <linux/gfp.h>
#include "isofs.h"
int isofs_name_translate(struct iso_directory_record *de, char *new, struct inode *inode)
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index eaa831311c9..ab438beb867 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -7,6 +7,7 @@
*/
#include <linux/smp_lock.h>
+#include <linux/gfp.h>
#include "isofs.h"
/*
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 4bd882548c4..ecb44c94ba8 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -17,7 +17,6 @@
#include <linux/fs.h>
#include <linux/jbd.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/bio.h>
@@ -862,12 +861,12 @@ restart_loop:
/* A buffer which has been freed while still being
* journaled by a previous transaction may end up still
* being dirty here, but we want to avoid writing back
- * that buffer in the future now that the last use has
- * been committed. That's not only a performance gain,
- * it also stops aliasing problems if the buffer is left
- * behind for writeback and gets reallocated for another
+ * that buffer in the future after the "add to orphan"
+ * operation been committed, That's not only a performance
+ * gain, it also stops aliasing problems if the buffer is
+ * left behind for writeback and gets reallocated for another
* use in a different page. */
- if (buffer_freed(bh)) {
+ if (buffer_freed(bh) && !jh->b_next_transaction) {
clear_buffer_freed(bh);
clear_buffer_jbddirty(bh);
}
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index cb1a49ae605..54c9bc9e1b1 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -20,7 +20,6 @@
#include <linux/fs.h>
#include <linux/jbd.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#endif
/*
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 006f9ad838a..5ae71e75a49 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -1398,7 +1398,7 @@ int journal_stop(handle_t *handle)
* the case where our storage is so fast that it is more optimal to go
* ahead and force a flush and wait for the transaction to be committed
* than it is to wait for an arbitrary amount of time for new writers to
- * join the transaction. We acheive this by measuring how long it takes
+ * join the transaction. We achieve this by measuring how long it takes
* to commit a transaction, and compare it with how long this
* transaction has been running, and if run time < commit time then we
* sleep for the delta and commit. This greatly helps super fast disks
@@ -1864,6 +1864,21 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
if (!jh)
goto zap_buffer_no_jh;
+ /*
+ * We cannot remove the buffer from checkpoint lists until the
+ * transaction adding inode to orphan list (let's call it T)
+ * is committed. Otherwise if the transaction changing the
+ * buffer would be cleaned from the journal before T is
+ * committed, a crash will cause that the correct contents of
+ * the buffer will be lost. On the other hand we have to
+ * clear the buffer dirty bit at latest at the moment when the
+ * transaction marking the buffer as freed in the filesystem
+ * structures is committed because from that moment on the
+ * buffer can be reallocated and used by a different page.
+ * Since the block hasn't been freed yet but the inode has
+ * already been added to orphan list, it is safe for us to add
+ * the buffer to BJ_Forget list of the newest transaction.
+ */
transaction = jh->b_transaction;
if (transaction == NULL) {
/* First case: not on any transaction. If it
@@ -1929,16 +1944,15 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
goto zap_buffer;
}
/*
- * If it is committing, we simply cannot touch it. We
- * can remove it's next_transaction pointer from the
- * running transaction if that is set, but nothing
- * else. */
+ * The buffer is committing, we simply cannot touch
+ * it. So we just set j_next_transaction to the
+ * running transaction (if there is one) and mark
+ * buffer as freed so that commit code knows it should
+ * clear dirty bits when it is done with the buffer.
+ */
set_buffer_freed(bh);
- if (jh->b_next_transaction) {
- J_ASSERT(jh->b_next_transaction ==
- journal->j_running_transaction);
- jh->b_next_transaction = NULL;
- }
+ if (journal->j_running_transaction && buffer_jbddirty(bh))
+ jh->b_next_transaction = journal->j_running_transaction;
journal_put_journal_head(jh);
spin_unlock(&journal->j_list_lock);
jbd_unlock_bh_state(bh);
@@ -2120,7 +2134,7 @@ void journal_file_buffer(struct journal_head *jh,
*/
void __journal_refile_buffer(struct journal_head *jh)
{
- int was_dirty;
+ int was_dirty, jlist;
struct buffer_head *bh = jh2bh(jh);
J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
@@ -2142,8 +2156,13 @@ void __journal_refile_buffer(struct journal_head *jh)
__journal_temp_unlink_buffer(jh);
jh->b_transaction = jh->b_next_transaction;
jh->b_next_transaction = NULL;
- __journal_file_buffer(jh, jh->b_transaction,
- jh->b_modified ? BJ_Metadata : BJ_Reserved);
+ if (buffer_freed(bh))
+ jlist = BJ_Forget;
+ else if (jh->b_modified)
+ jlist = BJ_Metadata;
+ else
+ jlist = BJ_Reserved;
+ __journal_file_buffer(jh, jh->b_transaction, jlist);
J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING);
if (was_dirty)
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 88684937095..30beb11ef92 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -507,6 +507,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal)
if (blocknr < journal->j_tail)
freed = freed + journal->j_last - journal->j_first;
+ trace_jbd2_cleanup_journal_tail(journal, first_tid, blocknr, freed);
jbd_debug(1,
"Cleaning journal tail from %d to %d (offset %lu), "
"freeing %lu\n",
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 1bc74b6f26d..671da7fb7ff 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -883,8 +883,7 @@ restart_loop:
spin_unlock(&journal->j_list_lock);
bh = jh2bh(jh);
jbd_lock_bh_state(bh);
- J_ASSERT_JH(jh, jh->b_transaction == commit_transaction ||
- jh->b_transaction == journal->j_running_transaction);
+ J_ASSERT_JH(jh, jh->b_transaction == commit_transaction);
/*
* If there is undo-protected committed data against
@@ -930,12 +929,12 @@ restart_loop:
/* A buffer which has been freed while still being
* journaled by a previous transaction may end up still
* being dirty here, but we want to avoid writing back
- * that buffer in the future now that the last use has
- * been committed. That's not only a performance gain,
- * it also stops aliasing problems if the buffer is left
- * behind for writeback and gets reallocated for another
+ * that buffer in the future after the "add to orphan"
+ * operation been committed, That's not only a performance
+ * gain, it also stops aliasing problems if the buffer is
+ * left behind for writeback and gets reallocated for another
* use in a different page. */
- if (buffer_freed(bh)) {
+ if (buffer_freed(bh) && !jh->b_next_transaction) {
clear_buffer_freed(bh);
clear_buffer_jbddirty(bh);
}
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index ac0d027595d..c03d4dce4d7 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -39,6 +39,8 @@
#include <linux/seq_file.h>
#include <linux/math64.h>
#include <linux/hash.h>
+#include <linux/log2.h>
+#include <linux/vmalloc.h>
#define CREATE_TRACE_POINTS
#include <trace/events/jbd2.h>
@@ -93,6 +95,7 @@ EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate);
static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
static void __journal_abort_soft (journal_t *journal, int errno);
+static int jbd2_journal_create_slab(size_t slab_size);
/*
* Helper function used to manage commit timeouts
@@ -1248,6 +1251,13 @@ int jbd2_journal_load(journal_t *journal)
}
}
+ /*
+ * Create a slab for this blocksize
+ */
+ err = jbd2_journal_create_slab(be32_to_cpu(sb->s_blocksize));
+ if (err)
+ return err;
+
/* Let the recovery code check whether it needs to recover any
* data from the journal. */
if (jbd2_journal_recover(journal))
@@ -1807,6 +1817,127 @@ size_t journal_tag_bytes(journal_t *journal)
}
/*
+ * JBD memory management
+ *
+ * These functions are used to allocate block-sized chunks of memory
+ * used for making copies of buffer_head data. Very often it will be
+ * page-sized chunks of data, but sometimes it will be in
+ * sub-page-size chunks. (For example, 16k pages on Power systems
+ * with a 4k block file system.) For blocks smaller than a page, we
+ * use a SLAB allocator. There are slab caches for each block size,
+ * which are allocated at mount time, if necessary, and we only free
+ * (all of) the slab caches when/if the jbd2 module is unloaded. For
+ * this reason we don't need to a mutex to protect access to
+ * jbd2_slab[] allocating or releasing memory; only in
+ * jbd2_journal_create_slab().
+ */
+#define JBD2_MAX_SLABS 8
+static struct kmem_cache *jbd2_slab[JBD2_MAX_SLABS];
+static DECLARE_MUTEX(jbd2_slab_create_sem);
+
+static const char *jbd2_slab_names[JBD2_MAX_SLABS] = {
+ "jbd2_1k", "jbd2_2k", "jbd2_4k", "jbd2_8k",
+ "jbd2_16k", "jbd2_32k", "jbd2_64k", "jbd2_128k"
+};
+
+
+static void jbd2_journal_destroy_slabs(void)
+{
+ int i;
+
+ for (i = 0; i < JBD2_MAX_SLABS; i++) {
+ if (jbd2_slab[i])
+ kmem_cache_destroy(jbd2_slab[i]);
+ jbd2_slab[i] = NULL;
+ }
+}
+
+static int jbd2_journal_create_slab(size_t size)
+{
+ int i = order_base_2(size) - 10;
+ size_t slab_size;
+
+ if (size == PAGE_SIZE)
+ return 0;
+
+ if (i >= JBD2_MAX_SLABS)
+ return -EINVAL;
+
+ if (unlikely(i < 0))
+ i = 0;
+ down(&jbd2_slab_create_sem);
+ if (jbd2_slab[i]) {
+ up(&jbd2_slab_create_sem);
+ return 0; /* Already created */
+ }
+
+ slab_size = 1 << (i+10);
+ jbd2_slab[i] = kmem_cache_create(jbd2_slab_names[i], slab_size,
+ slab_size, 0, NULL);
+ up(&jbd2_slab_create_sem);
+ if (!jbd2_slab[i]) {
+ printk(KERN_EMERG "JBD2: no memory for jbd2_slab cache\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static struct kmem_cache *get_slab(size_t size)
+{
+ int i = order_base_2(size) - 10;
+
+ BUG_ON(i >= JBD2_MAX_SLABS);
+ if (unlikely(i < 0))
+ i = 0;
+ BUG_ON(jbd2_slab[i] == 0);
+ return jbd2_slab[i];
+}
+
+void *jbd2_alloc(size_t size, gfp_t flags)
+{
+ void *ptr;
+
+ BUG_ON(size & (size-1)); /* Must be a power of 2 */
+
+ flags |= __GFP_REPEAT;
+ if (size == PAGE_SIZE)
+ ptr = (void *)__get_free_pages(flags, 0);
+ else if (size > PAGE_SIZE) {
+ int order = get_order(size);
+
+ if (order < 3)
+ ptr = (void *)__get_free_pages(flags, order);
+ else
+ ptr = vmalloc(size);
+ } else
+ ptr = kmem_cache_alloc(get_slab(size), flags);
+
+ /* Check alignment; SLUB has gotten this wrong in the past,
+ * and this can lead to user data corruption! */
+ BUG_ON(((unsigned long) ptr) & (size-1));
+
+ return ptr;
+}
+
+void jbd2_free(void *ptr, size_t size)
+{
+ if (size == PAGE_SIZE) {
+ free_pages((unsigned long)ptr, 0);
+ return;
+ }
+ if (size > PAGE_SIZE) {
+ int order = get_order(size);
+
+ if (order < 3)
+ free_pages((unsigned long)ptr, order);
+ else
+ vfree(ptr);
+ return;
+ }
+ kmem_cache_free(get_slab(size), ptr);
+};
+
+/*
* Journal_head storage management
*/
static struct kmem_cache *jbd2_journal_head_cache;
@@ -2204,6 +2335,7 @@ static void jbd2_journal_destroy_caches(void)
jbd2_journal_destroy_revoke_caches();
jbd2_journal_destroy_jbd2_journal_head_cache();
jbd2_journal_destroy_handle_cache();
+ jbd2_journal_destroy_slabs();
}
static int __init journal_init(void)
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index 73063285b13..049281b7cb8 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -20,7 +20,6 @@
#include <linux/fs.h>
#include <linux/jbd2.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/crc32.h>
#endif
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index a0512700542..bfc70f57900 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1727,6 +1727,21 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
if (!jh)
goto zap_buffer_no_jh;
+ /*
+ * We cannot remove the buffer from checkpoint lists until the
+ * transaction adding inode to orphan list (let's call it T)
+ * is committed. Otherwise if the transaction changing the
+ * buffer would be cleaned from the journal before T is
+ * committed, a crash will cause that the correct contents of
+ * the buffer will be lost. On the other hand we have to
+ * clear the buffer dirty bit at latest at the moment when the
+ * transaction marking the buffer as freed in the filesystem
+ * structures is committed because from that moment on the
+ * buffer can be reallocated and used by a different page.
+ * Since the block hasn't been freed yet but the inode has
+ * already been added to orphan list, it is safe for us to add
+ * the buffer to BJ_Forget list of the newest transaction.
+ */
transaction = jh->b_transaction;
if (transaction == NULL) {
/* First case: not on any transaction. If it
@@ -1783,16 +1798,15 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
} else if (transaction == journal->j_committing_transaction) {
JBUFFER_TRACE(jh, "on committing transaction");
/*
- * If it is committing, we simply cannot touch it. We
- * can remove it's next_transaction pointer from the
- * running transaction if that is set, but nothing
- * else. */
+ * The buffer is committing, we simply cannot touch
+ * it. So we just set j_next_transaction to the
+ * running transaction (if there is one) and mark
+ * buffer as freed so that commit code knows it should
+ * clear dirty bits when it is done with the buffer.
+ */
set_buffer_freed(bh);
- if (jh->b_next_transaction) {
- J_ASSERT(jh->b_next_transaction ==
- journal->j_running_transaction);
- jh->b_next_transaction = NULL;
- }
+ if (journal->j_running_transaction && buffer_jbddirty(bh))
+ jh->b_next_transaction = journal->j_running_transaction;
jbd2_journal_put_journal_head(jh);
spin_unlock(&journal->j_list_lock);
jbd_unlock_bh_state(bh);
@@ -1969,7 +1983,7 @@ void jbd2_journal_file_buffer(struct journal_head *jh,
*/
void __jbd2_journal_refile_buffer(struct journal_head *jh)
{
- int was_dirty;
+ int was_dirty, jlist;
struct buffer_head *bh = jh2bh(jh);
J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
@@ -1991,8 +2005,13 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh)
__jbd2_journal_temp_unlink_buffer(jh);
jh->b_transaction = jh->b_next_transaction;
jh->b_next_transaction = NULL;
- __jbd2_journal_file_buffer(jh, jh->b_transaction,
- jh->b_modified ? BJ_Metadata : BJ_Reserved);
+ if (buffer_freed(bh))
+ jlist = BJ_Forget;
+ else if (jh->b_modified)
+ jlist = BJ_Metadata;
+ else
+ jlist = BJ_Reserved;
+ __jbd2_journal_file_buffer(jh, jh->b_transaction, jlist);
J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING);
if (was_dirty)
diff --git a/fs/jffs2/compr_lzo.c b/fs/jffs2/compr_lzo.c
index 90cb60d0978..cd02acafde8 100644
--- a/fs/jffs2/compr_lzo.c
+++ b/fs/jffs2/compr_lzo.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/lzo.h>
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index cfd301a5edf..b46661a4275 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -14,7 +14,6 @@
#endif
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/zlib.h>
#include <linux/zutil.h>
#include "nodelist.h"
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c
index 5544d31c066..ec353841392 100644
--- a/fs/jffs2/debug.c
+++ b/fs/jffs2/debug.c
@@ -15,6 +15,7 @@
#include <linux/crc32.h>
#include <linux/jffs2.h>
#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
#include "nodelist.h"
#include "debug.h"
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index b7b74e29914..e7291c161a1 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -10,7 +10,6 @@
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/pagemap.h>
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index 87c6f555e1a..af02bd13846 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -15,7 +15,6 @@
#include <linux/mtd/mtd.h>
#include <linux/rbtree.h>
#include <linux/crc32.h>
-#include <linux/slab.h>
#include <linux/pagemap.h>
#include "nodelist.h"
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index 21a052915aa..191359dde4e 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -10,7 +10,6 @@
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/compiler.h>
#include <linux/sched.h> /* For cond_resched() */
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index e22de8397b7..d32ee9412cb 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -567,7 +567,7 @@ static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
else BUG();
}
}
- list->rb_node = NULL;
+ *list = RB_ROOT;
}
static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 4ec11e8bda8..b955626071c 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -10,7 +10,6 @@
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include "nodelist.h"
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index ca29440e943..c819eb0e982 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/crc32.h>
-#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/mtd/mtd.h>
#include "nodelist.h"
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index d66477c3430..1057a4998e4 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -19,8 +19,8 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/fs.h>
-#include <linux/quotaops.h>
#include <linux/posix_acl_xattr.h>
#include "jfs_incore.h"
#include "jfs_txnmgr.h"
@@ -174,7 +174,7 @@ cleanup:
return rc;
}
-static int jfs_acl_chmod(struct inode *inode)
+int jfs_acl_chmod(struct inode *inode)
{
struct posix_acl *acl, *clone;
int rc;
@@ -205,26 +205,3 @@ static int jfs_acl_chmod(struct inode *inode)
posix_acl_release(clone);
return rc;
}
-
-int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
-{
- struct inode *inode = dentry->d_inode;
- int rc;
-
- rc = inode_change_ok(inode, iattr);
- if (rc)
- return rc;
-
- if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
- if (vfs_dq_transfer(inode, iattr))
- return -EDQUOT;
- }
-
- rc = inode_setattr(inode, iattr);
-
- if (!rc && (iattr->ia_valid & ATTR_MODE))
- rc = jfs_acl_chmod(inode);
-
- return rc;
-}
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 2b70fa78e4a..14ba982b3f2 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -18,6 +18,7 @@
*/
#include <linux/fs.h>
+#include <linux/quotaops.h>
#include "jfs_incore.h"
#include "jfs_inode.h"
#include "jfs_dmap.h"
@@ -47,7 +48,7 @@ static int jfs_open(struct inode *inode, struct file *file)
{
int rc;
- if ((rc = generic_file_open(inode, file)))
+ if ((rc = dquot_file_open(inode, file)))
return rc;
/*
@@ -88,14 +89,40 @@ static int jfs_release(struct inode *inode, struct file *file)
return 0;
}
+int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+ struct inode *inode = dentry->d_inode;
+ int rc;
+
+ rc = inode_change_ok(inode, iattr);
+ if (rc)
+ return rc;
+
+ if (iattr->ia_valid & ATTR_SIZE)
+ dquot_initialize(inode);
+ if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
+ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
+ rc = dquot_transfer(inode, iattr);
+ if (rc)
+ return rc;
+ }
+
+ rc = inode_setattr(inode, iattr);
+
+ if (!rc && (iattr->ia_valid & ATTR_MODE))
+ rc = jfs_acl_chmod(inode);
+
+ return rc;
+}
+
const struct inode_operations jfs_file_inode_operations = {
.truncate = jfs_truncate,
.setxattr = jfs_setxattr,
.getxattr = jfs_getxattr,
.listxattr = jfs_listxattr,
.removexattr = jfs_removexattr,
-#ifdef CONFIG_JFS_POSIX_ACL
.setattr = jfs_setattr,
+#ifdef CONFIG_JFS_POSIX_ACL
.check_acl = jfs_check_acl,
#endif
};
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index b2ae190a77b..ed9ba6fe04f 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -22,6 +22,7 @@
#include <linux/buffer_head.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
+#include <linux/writeback.h>
#include "jfs_incore.h"
#include "jfs_inode.h"
#include "jfs_filsys.h"
@@ -60,7 +61,7 @@ struct inode *jfs_iget(struct super_block *sb, unsigned long ino)
inode->i_op = &page_symlink_inode_operations;
inode->i_mapping->a_ops = &jfs_aops;
} else {
- inode->i_op = &jfs_symlink_inode_operations;
+ inode->i_op = &jfs_fast_symlink_inode_operations;
/*
* The inline data should be null-terminated, but
* don't let on-disk corruption crash the kernel
@@ -120,8 +121,10 @@ int jfs_commit_inode(struct inode *inode, int wait)
return rc;
}
-int jfs_write_inode(struct inode *inode, int wait)
+int jfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
+ int wait = wbc->sync_mode == WB_SYNC_ALL;
+
if (test_cflag(COMMIT_Nolink, inode))
return 0;
/*
@@ -146,6 +149,9 @@ void jfs_delete_inode(struct inode *inode)
{
jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
+ if (!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);
@@ -158,9 +164,9 @@ void jfs_delete_inode(struct inode *inode)
/*
* Free the inode from the quota allocation.
*/
- vfs_dq_init(inode);
- vfs_dq_free_inode(inode);
- vfs_dq_drop(inode);
+ dquot_initialize(inode);
+ dquot_free_inode(inode);
+ dquot_drop(inode);
}
clear_inode(inode);
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
index b07bd417ef8..54e07559878 100644
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -22,7 +22,7 @@
int jfs_check_acl(struct inode *, int);
int jfs_init_acl(tid_t, struct inode *, struct inode *);
-int jfs_setattr(struct dentry *, struct iattr *);
+int jfs_acl_chmod(struct inode *inode);
#else
@@ -32,5 +32,10 @@ static inline int jfs_init_acl(tid_t tid, struct inode *inode,
return 0;
}
+static inline int jfs_acl_chmod(struct inode *inode)
+{
+ return 0;
+}
+
#endif
#endif /* _H_JFS_ACL */
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index d9b031cf69f..9e2f6a72166 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -17,6 +17,7 @@
*/
#include <linux/fs.h>
+#include <linux/slab.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
@@ -195,7 +196,7 @@ int dbMount(struct inode *ipbmap)
bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
- bmp->db_agheigth = le32_to_cpu(dbmp_le->dn_agheigth);
+ bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
@@ -287,7 +288,7 @@ int dbSync(struct inode *ipbmap)
dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag);
dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref);
dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel);
- dbmp_le->dn_agheigth = cpu_to_le32(bmp->db_agheigth);
+ dbmp_le->dn_agheight = cpu_to_le32(bmp->db_agheight);
dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth);
dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart);
dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size);
@@ -1440,7 +1441,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
* tree index of this allocation group within the control page.
*/
agperlev =
- (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
+ (1 << (L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth;
ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
/* dmap control page trees fan-out by 4 and a single allocation
@@ -1459,7 +1460,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
* the subtree to find the leftmost leaf that describes this
* free space.
*/
- for (k = bmp->db_agheigth; k > 0; k--) {
+ for (k = bmp->db_agheight; k > 0; k--) {
for (n = 0, m = (ti << 2) + 1; n < 4; n++) {
if (l2nb <= dcp->stree[m + n]) {
ti = m + n;
@@ -3606,7 +3607,7 @@ void dbFinalizeBmap(struct inode *ipbmap)
}
/*
- * compute db_aglevel, db_agheigth, db_width, db_agstart:
+ * compute db_aglevel, db_agheight, db_width, db_agstart:
* an ag is covered in aglevel dmapctl summary tree,
* at agheight level height (from leaf) with agwidth number of nodes
* each, which starts at agstart index node of the smmary tree node
@@ -3615,9 +3616,9 @@ void dbFinalizeBmap(struct inode *ipbmap)
bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
l2nl =
bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL);
- bmp->db_agheigth = l2nl >> 1;
- bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheigth << 1));
- for (i = 5 - bmp->db_agheigth, bmp->db_agstart = 0, n = 1; i > 0;
+ bmp->db_agheight = l2nl >> 1;
+ bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheight << 1));
+ for (i = 5 - bmp->db_agheight, bmp->db_agstart = 0, n = 1; i > 0;
i--) {
bmp->db_agstart += n;
n <<= 2;
diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h
index 1a6eb41569b..6dcb906c55d 100644
--- a/fs/jfs/jfs_dmap.h
+++ b/fs/jfs/jfs_dmap.h
@@ -210,7 +210,7 @@ struct dbmap_disk {
__le32 dn_maxag; /* 4: max active alloc group number */
__le32 dn_agpref; /* 4: preferred alloc group (hint) */
__le32 dn_aglevel; /* 4: dmapctl level holding the AG */
- __le32 dn_agheigth; /* 4: height in dmapctl of the AG */
+ __le32 dn_agheight; /* 4: height in dmapctl of the AG */
__le32 dn_agwidth; /* 4: width in dmapctl of the AG */
__le32 dn_agstart; /* 4: start tree index at AG height */
__le32 dn_agl2size; /* 4: l2 num of blks per alloc group */
@@ -229,7 +229,7 @@ struct dbmap {
int dn_maxag; /* max active alloc group number */
int dn_agpref; /* preferred alloc group (hint) */
int dn_aglevel; /* dmapctl level holding the AG */
- int dn_agheigth; /* height in dmapctl of the AG */
+ int dn_agheight; /* height in dmapctl of the AG */
int dn_agwidth; /* width in dmapctl of the AG */
int dn_agstart; /* start tree index at AG height */
int dn_agl2size; /* l2 num of blks per alloc group */
@@ -255,7 +255,7 @@ struct bmap {
#define db_agsize db_bmap.dn_agsize
#define db_agl2size db_bmap.dn_agl2size
#define db_agwidth db_bmap.dn_agwidth
-#define db_agheigth db_bmap.dn_agheigth
+#define db_agheight db_bmap.dn_agheight
#define db_agstart db_bmap.dn_agstart
#define db_numag db_bmap.dn_numag
#define db_maxlevel db_bmap.dn_maxlevel
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 925871e9887..9197a1b0d02 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -102,6 +102,7 @@
#include <linux/fs.h>
#include <linux/quotaops.h>
+#include <linux/slab.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_filsys.h"
@@ -381,10 +382,10 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
* It's time to move the inline table to an external
* page and begin to build the xtree
*/
- if (vfs_dq_alloc_block(ip, sbi->nbperpage))
+ if (dquot_alloc_block(ip, sbi->nbperpage))
goto clean_up;
if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
- vfs_dq_free_block(ip, sbi->nbperpage);
+ dquot_free_block(ip, sbi->nbperpage);
goto clean_up;
}
@@ -408,7 +409,7 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
memcpy(&jfs_ip->i_dirtable, temp_table,
sizeof (temp_table));
dbFree(ip, xaddr, sbi->nbperpage);
- vfs_dq_free_block(ip, sbi->nbperpage);
+ dquot_free_block(ip, sbi->nbperpage);
goto clean_up;
}
ip->i_size = PSIZE;
@@ -1027,10 +1028,9 @@ static int dtSplitUp(tid_t tid,
n = xlen;
/* Allocate blocks to quota. */
- if (vfs_dq_alloc_block(ip, n)) {
- rc = -EDQUOT;
+ rc = dquot_alloc_block(ip, n);
+ if (rc)
goto extendOut;
- }
quota_allocation += n;
if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
@@ -1308,7 +1308,7 @@ static int dtSplitUp(tid_t tid,
/* Rollback quota allocation */
if (rc && quota_allocation)
- vfs_dq_free_block(ip, quota_allocation);
+ dquot_free_block(ip, quota_allocation);
dtSplitUp_Exit:
@@ -1369,9 +1369,10 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
return -EIO;
/* Allocate blocks to quota. */
- if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) {
+ rc = dquot_alloc_block(ip, lengthPXD(pxd));
+ if (rc) {
release_metapage(rmp);
- return -EDQUOT;
+ return rc;
}
jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
@@ -1892,6 +1893,7 @@ static int dtSplitRoot(tid_t tid,
struct dt_lock *dtlck;
struct tlock *tlck;
struct lv *lv;
+ int rc;
/* get split root page */
smp = split->mp;
@@ -1916,9 +1918,10 @@ static int dtSplitRoot(tid_t tid,
rp = rmp->data;
/* Allocate blocks to quota. */
- if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) {
+ rc = dquot_alloc_block(ip, lengthPXD(pxd));
+ if (rc) {
release_metapage(rmp);
- return -EDQUOT;
+ return rc;
}
BT_MARK_DIRTY(rmp, ip);
@@ -2287,7 +2290,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
xlen = lengthPXD(&fp->header.self);
/* Free quota allocation. */
- vfs_dq_free_block(ip, xlen);
+ dquot_free_block(ip, xlen);
/* free/invalidate its buffer page */
discard_metapage(fmp);
@@ -2363,7 +2366,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
xlen = lengthPXD(&p->header.self);
/* Free quota allocation */
- vfs_dq_free_block(ip, xlen);
+ dquot_free_block(ip, xlen);
/* free/invalidate its buffer page */
discard_metapage(mp);
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
index 41d6045dbeb..5d3bbd10f8d 100644
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -141,10 +141,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
}
/* Allocate blocks to quota. */
- if (vfs_dq_alloc_block(ip, nxlen)) {
+ rc = dquot_alloc_block(ip, nxlen);
+ if (rc) {
dbFree(ip, nxaddr, (s64) nxlen);
mutex_unlock(&JFS_IP(ip)->commit_mutex);
- return -EDQUOT;
+ return rc;
}
/* determine the value of the extent flag */
@@ -164,7 +165,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
*/
if (rc) {
dbFree(ip, nxaddr, nxlen);
- vfs_dq_free_block(ip, nxlen);
+ dquot_free_block(ip, nxlen);
mutex_unlock(&JFS_IP(ip)->commit_mutex);
return (rc);
}
@@ -256,10 +257,11 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
goto exit;
/* Allocat blocks to quota. */
- if (vfs_dq_alloc_block(ip, nxlen)) {
+ rc = dquot_alloc_block(ip, nxlen);
+ if (rc) {
dbFree(ip, nxaddr, (s64) nxlen);
mutex_unlock(&JFS_IP(ip)->commit_mutex);
- return -EDQUOT;
+ return rc;
}
delta = nxlen - xlen;
@@ -297,7 +299,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
/* extend the extent */
if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
dbFree(ip, xaddr + xlen, delta);
- vfs_dq_free_block(ip, nxlen);
+ dquot_free_block(ip, nxlen);
goto exit;
}
} else {
@@ -308,7 +310,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
*/
if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
dbFree(ip, nxaddr, nxlen);
- vfs_dq_free_block(ip, nxlen);
+ dquot_free_block(ip, nxlen);
goto exit;
}
}
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 0fc30407f03..f8332dc8eeb 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -45,6 +45,7 @@
#include <linux/buffer_head.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
+#include <linux/slab.h>
#include "jfs_incore.h"
#include "jfs_inode.h"
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
index dc0e02159ac..829921b6776 100644
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -116,10 +116,10 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
/*
* Allocate inode to quota.
*/
- if (vfs_dq_alloc_inode(inode)) {
- rc = -EDQUOT;
+ dquot_initialize(inode);
+ rc = dquot_alloc_inode(inode);
+ if (rc)
goto fail_drop;
- }
inode->i_mode = mode;
/* inherit flags from parent */
@@ -162,7 +162,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
return inode;
fail_drop:
- vfs_dq_drop(inode);
+ dquot_drop(inode);
inode->i_flags |= S_NOQUOTA;
fail_unlock:
inode->i_nlink = 0;
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 1eff7db34d6..9e6bda30a6e 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -26,7 +26,7 @@ extern long jfs_ioctl(struct file *, unsigned int, unsigned long);
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*, int);
+extern int jfs_write_inode(struct inode *, struct writeback_control *);
extern void jfs_delete_inode(struct inode *);
extern void jfs_dirty_inode(struct inode *);
extern void jfs_truncate(struct inode *);
@@ -40,6 +40,7 @@ extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
int fh_len, int fh_type);
extern void jfs_set_inode_flags(struct inode *);
extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
+extern int jfs_setattr(struct dentry *, struct iattr *);
extern const struct address_space_operations jfs_aops;
extern const struct inode_operations jfs_dir_inode_operations;
@@ -47,5 +48,6 @@ extern const struct file_operations jfs_dir_operations;
extern const struct inode_operations jfs_file_inode_operations;
extern const struct file_operations jfs_file_operations;
extern const struct inode_operations jfs_symlink_inode_operations;
+extern const struct inode_operations jfs_fast_symlink_inode_operations;
extern const struct dentry_operations jfs_ci_dentry_operations;
#endif /* _H_JFS_INODE */
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 335c4de6552..c51af2a1451 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -70,6 +70,7 @@
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 07b6c5dfb4b..48b44bd8267 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -21,6 +21,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/bio.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/buffer_head.h>
#include <linux/mempool.h>
diff --git a/fs/jfs/jfs_unicode.h b/fs/jfs/jfs_unicode.h
index 3fbb3a22559..8f0f02cb6ca 100644
--- a/fs/jfs/jfs_unicode.h
+++ b/fs/jfs/jfs_unicode.h
@@ -19,6 +19,7 @@
#ifndef _H_JFS_UNICODE
#define _H_JFS_UNICODE
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "jfs_types.h"
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index d654a645864..6c50871e622 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -585,10 +585,10 @@ int xtInsert(tid_t tid, /* transaction id */
hint = addressXAD(xad) + lengthXAD(xad) - 1;
} else
hint = 0;
- if ((rc = vfs_dq_alloc_block(ip, xlen)))
+ if ((rc = dquot_alloc_block(ip, xlen)))
goto out;
if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
- vfs_dq_free_block(ip, xlen);
+ dquot_free_block(ip, xlen);
goto out;
}
}
@@ -617,7 +617,7 @@ int xtInsert(tid_t tid, /* transaction id */
/* undo data extent allocation */
if (*xaddrp == 0) {
dbFree(ip, xaddr, (s64) xlen);
- vfs_dq_free_block(ip, xlen);
+ dquot_free_block(ip, xlen);
}
return rc;
}
@@ -985,10 +985,9 @@ xtSplitPage(tid_t tid, struct inode *ip,
rbn = addressPXD(pxd);
/* Allocate blocks to quota. */
- if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) {
- rc = -EDQUOT;
+ rc = dquot_alloc_block(ip, lengthPXD(pxd));
+ if (rc)
goto clean_up;
- }
quota_allocation += lengthPXD(pxd);
@@ -1195,7 +1194,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
/* Rollback quota allocation. */
if (quota_allocation)
- vfs_dq_free_block(ip, quota_allocation);
+ dquot_free_block(ip, quota_allocation);
return (rc);
}
@@ -1235,6 +1234,7 @@ xtSplitRoot(tid_t tid,
struct pxdlist *pxdlist;
struct tlock *tlck;
struct xtlock *xtlck;
+ int rc;
sp = &JFS_IP(ip)->i_xtroot;
@@ -1252,9 +1252,10 @@ xtSplitRoot(tid_t tid,
return -EIO;
/* Allocate blocks to quota. */
- if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) {
+ rc = dquot_alloc_block(ip, lengthPXD(pxd));
+ if (rc) {
release_metapage(rmp);
- return -EDQUOT;
+ return rc;
}
jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
@@ -3680,7 +3681,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
ip->i_size = newsize;
/* update quota allocation to reflect freed blocks */
- vfs_dq_free_block(ip, nfreed);
+ dquot_free_block(ip, nfreed);
/*
* free tlock of invalidated pages
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index c79a4270f08..a9cf8e8675b 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -85,6 +85,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name);
+ dquot_initialize(dip);
+
/*
* search parent directory for entry/freespace
* (dtSearch() returns parent directory page pinned)
@@ -215,6 +217,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
jfs_info("jfs_mkdir: dip:0x%p name:%s", dip, dentry->d_name.name);
+ dquot_initialize(dip);
+
/* link count overflow on parent directory ? */
if (dip->i_nlink == JFS_LINK_MAX) {
rc = -EMLINK;
@@ -356,7 +360,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name);
/* Init inode for quota operations. */
- vfs_dq_init(ip);
+ dquot_initialize(dip);
+ dquot_initialize(ip);
/* directory must be empty to be removed */
if (!dtEmpty(ip)) {
@@ -483,7 +488,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name);
/* Init inode for quota operations. */
- vfs_dq_init(ip);
+ dquot_initialize(dip);
+ dquot_initialize(ip);
if ((rc = get_UCSname(&dname, dentry)))
goto out;
@@ -805,6 +811,8 @@ static int jfs_link(struct dentry *old_dentry,
if (ip->i_nlink == 0)
return -ENOENT;
+ dquot_initialize(dir);
+
tid = txBegin(ip->i_sb, 0);
mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
@@ -896,6 +904,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name);
+ dquot_initialize(dip);
+
ssize = strlen(name) + 1;
/*
@@ -946,7 +956,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
*/
if (ssize <= IDATASIZE) {
- ip->i_op = &jfs_symlink_inode_operations;
+ ip->i_op = &jfs_fast_symlink_inode_operations;
i_fastsymlink = JFS_IP(ip)->i_inline;
memcpy(i_fastsymlink, name, ssize);
@@ -968,7 +978,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
else {
jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
- ip->i_op = &page_symlink_inode_operations;
+ ip->i_op = &jfs_symlink_inode_operations;
ip->i_mapping->a_ops = &jfs_aops;
/*
@@ -1087,6 +1097,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
jfs_info("jfs_rename: %s %s", old_dentry->d_name.name,
new_dentry->d_name.name);
+ dquot_initialize(old_dir);
+ dquot_initialize(new_dir);
+
old_ip = old_dentry->d_inode;
new_ip = new_dentry->d_inode;
@@ -1136,7 +1149,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
} else if (new_ip) {
IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL);
/* Init inode for quota operations. */
- vfs_dq_init(new_ip);
+ dquot_initialize(new_ip);
}
/*
@@ -1360,6 +1373,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
jfs_info("jfs_mknod: %s", dentry->d_name.name);
+ dquot_initialize(dir);
+
if ((rc = get_UCSname(&dname, dentry)))
goto out;
@@ -1541,8 +1556,8 @@ const struct inode_operations jfs_dir_inode_operations = {
.getxattr = jfs_getxattr,
.listxattr = jfs_listxattr,
.removexattr = jfs_removexattr,
-#ifdef CONFIG_JFS_POSIX_ACL
.setattr = jfs_setattr,
+#ifdef CONFIG_JFS_POSIX_ACL
.check_acl = jfs_check_acl,
#endif
};
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c
index 7f24a0bb08c..1aba0039f1c 100644
--- a/fs/jfs/resize.c
+++ b/fs/jfs/resize.c
@@ -81,6 +81,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
struct inode *iplist[1];
struct jfs_superblock *j_sb, *j_sb2;
uint old_agsize;
+ int agsizechanged = 0;
struct buffer_head *bh, *bh2;
/* If the volume hasn't grown, get out now */
@@ -333,6 +334,9 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
*/
if ((rc = dbExtendFS(ipbmap, XAddress, nblocks)))
goto error_out;
+
+ agsizechanged |= (bmp->db_agsize != old_agsize);
+
/*
* the map now has extended to cover additional nblocks:
* dn_mapsize = oldMapsize + nblocks;
@@ -432,7 +436,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
* will correctly identify the new ag);
*/
/* if new AG size the same as old AG size, done! */
- if (bmp->db_agsize != old_agsize) {
+ if (agsizechanged) {
if ((rc = diExtendFS(ipimap, ipbmap)))
goto error_out;
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index d929a822a74..157382fa625 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -30,6 +30,7 @@
#include <linux/buffer_head.h>
#include <linux/exportfs.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
@@ -131,6 +132,11 @@ 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);
@@ -745,6 +751,7 @@ static const struct super_operations jfs_super_operations = {
.dirty_inode = jfs_dirty_inode,
.write_inode = jfs_write_inode,
.delete_inode = jfs_delete_inode,
+ .clear_inode = jfs_clear_inode,
.put_super = jfs_put_super,
.sync_fs = jfs_sync_fs,
.freeze_fs = jfs_freeze,
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index 4af1a05aad0..205b946d8e0 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -29,9 +29,21 @@ static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
return NULL;
}
-const struct inode_operations jfs_symlink_inode_operations = {
+const struct inode_operations jfs_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = jfs_follow_link,
+ .setattr = jfs_setattr,
+ .setxattr = jfs_setxattr,
+ .getxattr = jfs_getxattr,
+ .listxattr = jfs_listxattr,
+ .removexattr = jfs_removexattr,
+};
+
+const struct inode_operations jfs_symlink_inode_operations = {
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
+ .setattr = jfs_setattr,
.setxattr = jfs_setxattr,
.getxattr = jfs_getxattr,
.listxattr = jfs_listxattr,
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index fad364548bc..fa96bbb2634 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/xattr.h>
#include <linux/posix_acl_xattr.h>
+#include <linux/slab.h>
#include <linux/quotaops.h>
#include <linux/security.h>
#include "jfs_incore.h"
@@ -260,14 +261,14 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size,
nblocks = (size + (sb->s_blocksize - 1)) >> sb->s_blocksize_bits;
/* Allocate new blocks to quota. */
- if (vfs_dq_alloc_block(ip, nblocks)) {
- return -EDQUOT;
- }
+ rc = dquot_alloc_block(ip, nblocks);
+ if (rc)
+ return rc;
rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
if (rc) {
/*Rollback quota allocation. */
- vfs_dq_free_block(ip, nblocks);
+ dquot_free_block(ip, nblocks);
return rc;
}
@@ -332,7 +333,7 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size,
failed:
/* Rollback quota allocation. */
- vfs_dq_free_block(ip, nblocks);
+ dquot_free_block(ip, nblocks);
dbFree(ip, blkno, nblocks);
return rc;
@@ -538,7 +539,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
if (blocks_needed > current_blocks) {
/* Allocate new blocks to quota. */
- if (vfs_dq_alloc_block(inode, blocks_needed))
+ rc = dquot_alloc_block(inode, blocks_needed);
+ if (rc)
return -EDQUOT;
quota_allocation = blocks_needed;
@@ -602,7 +604,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
clean_up:
/* Rollback quota allocation */
if (quota_allocation)
- vfs_dq_free_block(inode, quota_allocation);
+ dquot_free_block(inode, quota_allocation);
return (rc);
}
@@ -677,7 +679,7 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf,
/* If old blocks exist, they must be removed from quota allocation. */
if (old_blocks)
- vfs_dq_free_block(inode, old_blocks);
+ dquot_free_block(inode, old_blocks);
inode->i_ctime = CURRENT_TIME;
diff --git a/fs/libfs.c b/fs/libfs.c
index 9e50bcf5585..ea9a6cc9b35 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -5,6 +5,7 @@
#include <linux/module.h>
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/mutex.h>
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index fc9032dc886..64fd427c993 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/time.h>
#include <linux/nfs_fs.h>
#include <linux/sunrpc/clnt.h>
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index c81249fef11..7932c399fab 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fs.h>
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 4600c2037b8..bb464d12104 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -479,8 +479,8 @@ again: mutex_lock(&nlm_host_mutex);
}
}
}
-
mutex_unlock(&nlm_host_mutex);
+ nsm_release(nsm);
}
/*
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index f956651d0f6..e3015464fba 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -10,6 +10,7 @@
#include <linux/utsname.h>
#include <linux/kernel.h>
#include <linux/ktime.h>
+#include <linux/slab.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/xprtsock.h>
@@ -349,9 +350,9 @@ retry:
* nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle
* @info: pointer to NLMPROC_SM_NOTIFY arguments
*
- * Returns a matching nsm_handle if found in the nsm cache; the returned
- * nsm_handle's reference count is bumped and sm_monitored is cleared.
- * Otherwise returns NULL if some error occurred.
+ * Returns a matching nsm_handle if found in the nsm cache. The returned
+ * nsm_handle's reference count is bumped. Otherwise returns NULL if some
+ * error occurred.
*/
struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
{
@@ -370,12 +371,6 @@ struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
atomic_inc(&cached->sm_count);
spin_unlock(&nsm_lock);
- /*
- * During subsequent lock activity, force a fresh
- * notification to be set up for this host.
- */
- cached->sm_monitored = 0;
-
dprintk("lockd: host %s (%s) rebooted, cnt %d\n",
cached->sm_name, cached->sm_addrbuf,
atomic_read(&cached->sm_count));
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index e50cfa3d965..f1bacf1a039 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -21,7 +21,6 @@
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/uio.h>
-#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/mutex.h>
@@ -243,11 +242,9 @@ static int make_socks(struct svc_serv *serv)
if (err < 0)
goto out_err;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
err = create_lockd_family(serv, PF_INET6);
if (err < 0 && err != -EAFNOSUPPORT)
goto out_err;
-#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */
warned = 0;
return 0;
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index a7966eed3c1..031c6569a13 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -9,7 +9,6 @@
#include <linux/types.h>
#include <linux/time.h>
-#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/share.h>
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index d1001790fa9..84055d31bfc 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -21,6 +21,7 @@
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 56c9519d900..0f2ab741ae7 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -9,7 +9,6 @@
#include <linux/types.h>
#include <linux/time.h>
-#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/share.h>
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index ad478da7ca6..d0ef94cfb3d 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -10,6 +10,7 @@
#include <linux/string.h>
#include <linux/time.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/clnt.h>
diff --git a/fs/locks.c b/fs/locks.c
index ae9ded026b7..ab24d49fc04 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1455,7 +1455,7 @@ EXPORT_SYMBOL(generic_setlease);
* leases held by processes on this node.
*
* There is also no break_lease method; filesystems that
- * handle their own leases shoud break leases themselves from the
+ * handle their own leases should break leases themselves from the
* filesystem's open, create, and (on truncate) setattr methods.
*
* Warning: the only current setlease methods exist only to disable
diff --git a/fs/logfs/Kconfig b/fs/logfs/Kconfig
new file mode 100644
index 00000000000..daf9a9b32dd
--- /dev/null
+++ b/fs/logfs/Kconfig
@@ -0,0 +1,17 @@
+config LOGFS
+ tristate "LogFS file system (EXPERIMENTAL)"
+ depends on (MTD || BLOCK) && EXPERIMENTAL
+ select ZLIB_INFLATE
+ select ZLIB_DEFLATE
+ select CRC32
+ select BTREE
+ help
+ Flash filesystem aimed to scale efficiently to large devices.
+ In comparison to JFFS2 it offers significantly faster mount
+ times and potentially less RAM usage, although the latter has
+ not been measured yet.
+
+ In its current state it is still very experimental and should
+ not be used for other than testing purposes.
+
+ If unsure, say N.
diff --git a/fs/logfs/Makefile b/fs/logfs/Makefile
new file mode 100644
index 00000000000..4820027787e
--- /dev/null
+++ b/fs/logfs/Makefile
@@ -0,0 +1,13 @@
+obj-$(CONFIG_LOGFS) += logfs.o
+
+logfs-y += compr.o
+logfs-y += dir.o
+logfs-y += file.o
+logfs-y += gc.o
+logfs-y += inode.o
+logfs-y += journal.o
+logfs-y += readwrite.o
+logfs-y += segment.o
+logfs-y += super.o
+logfs-$(CONFIG_BLOCK) += dev_bdev.o
+logfs-$(CONFIG_MTD) += dev_mtd.o
diff --git a/fs/logfs/compr.c b/fs/logfs/compr.c
new file mode 100644
index 00000000000..44bbfd249ab
--- /dev/null
+++ b/fs/logfs/compr.c
@@ -0,0 +1,95 @@
+/*
+ * fs/logfs/compr.c - compression routines
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ */
+#include "logfs.h"
+#include <linux/vmalloc.h>
+#include <linux/zlib.h>
+
+#define COMPR_LEVEL 3
+
+static DEFINE_MUTEX(compr_mutex);
+static struct z_stream_s stream;
+
+int logfs_compress(void *in, void *out, size_t inlen, size_t outlen)
+{
+ int err, ret;
+
+ ret = -EIO;
+ mutex_lock(&compr_mutex);
+ err = zlib_deflateInit(&stream, COMPR_LEVEL);
+ if (err != Z_OK)
+ goto error;
+
+ stream.next_in = in;
+ stream.avail_in = inlen;
+ stream.total_in = 0;
+ stream.next_out = out;
+ stream.avail_out = outlen;
+ stream.total_out = 0;
+
+ err = zlib_deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END)
+ goto error;
+
+ err = zlib_deflateEnd(&stream);
+ if (err != Z_OK)
+ goto error;
+
+ if (stream.total_out >= stream.total_in)
+ goto error;
+
+ ret = stream.total_out;
+error:
+ mutex_unlock(&compr_mutex);
+ return ret;
+}
+
+int logfs_uncompress(void *in, void *out, size_t inlen, size_t outlen)
+{
+ int err, ret;
+
+ ret = -EIO;
+ mutex_lock(&compr_mutex);
+ err = zlib_inflateInit(&stream);
+ if (err != Z_OK)
+ goto error;
+
+ stream.next_in = in;
+ stream.avail_in = inlen;
+ stream.total_in = 0;
+ stream.next_out = out;
+ stream.avail_out = outlen;
+ stream.total_out = 0;
+
+ err = zlib_inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END)
+ goto error;
+
+ err = zlib_inflateEnd(&stream);
+ if (err != Z_OK)
+ goto error;
+
+ ret = 0;
+error:
+ mutex_unlock(&compr_mutex);
+ return ret;
+}
+
+int __init logfs_compr_init(void)
+{
+ size_t size = max(zlib_deflate_workspacesize(),
+ zlib_inflate_workspacesize());
+ stream.workspace = vmalloc(size);
+ if (!stream.workspace)
+ return -ENOMEM;
+ return 0;
+}
+
+void logfs_compr_exit(void)
+{
+ vfree(stream.workspace);
+}
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c
new file mode 100644
index 00000000000..243c00071f7
--- /dev/null
+++ b/fs/logfs/dev_bdev.c
@@ -0,0 +1,333 @@
+/*
+ * fs/logfs/dev_bdev.c - Device access methods for block devices
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ */
+#include "logfs.h"
+#include <linux/bio.h>
+#include <linux/blkdev.h>
+#include <linux/buffer_head.h>
+#include <linux/gfp.h>
+
+#define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
+
+static void request_complete(struct bio *bio, int err)
+{
+ complete((struct completion *)bio->bi_private);
+}
+
+static int sync_request(struct page *page, struct block_device *bdev, int rw)
+{
+ struct bio bio;
+ struct bio_vec bio_vec;
+ struct completion complete;
+
+ bio_init(&bio);
+ bio.bi_io_vec = &bio_vec;
+ bio_vec.bv_page = page;
+ bio_vec.bv_len = PAGE_SIZE;
+ bio_vec.bv_offset = 0;
+ bio.bi_vcnt = 1;
+ bio.bi_idx = 0;
+ bio.bi_size = PAGE_SIZE;
+ bio.bi_bdev = bdev;
+ bio.bi_sector = page->index * (PAGE_SIZE >> 9);
+ init_completion(&complete);
+ bio.bi_private = &complete;
+ bio.bi_end_io = request_complete;
+
+ submit_bio(rw, &bio);
+ generic_unplug_device(bdev_get_queue(bdev));
+ wait_for_completion(&complete);
+ return test_bit(BIO_UPTODATE, &bio.bi_flags) ? 0 : -EIO;
+}
+
+static int bdev_readpage(void *_sb, struct page *page)
+{
+ struct super_block *sb = _sb;
+ struct block_device *bdev = logfs_super(sb)->s_bdev;
+ int err;
+
+ err = sync_request(page, bdev, READ);
+ if (err) {
+ ClearPageUptodate(page);
+ SetPageError(page);
+ } else {
+ SetPageUptodate(page);
+ ClearPageError(page);
+ }
+ unlock_page(page);
+ return err;
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+
+static void writeseg_end_io(struct bio *bio, int err)
+{
+ const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
+ struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+ struct super_block *sb = bio->bi_private;
+ struct logfs_super *super = logfs_super(sb);
+ struct page *page;
+
+ BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */
+ BUG_ON(err);
+ BUG_ON(bio->bi_vcnt == 0);
+ do {
+ page = bvec->bv_page;
+ if (--bvec >= bio->bi_io_vec)
+ prefetchw(&bvec->bv_page->flags);
+
+ end_page_writeback(page);
+ page_cache_release(page);
+ } while (bvec >= bio->bi_io_vec);
+ bio_put(bio);
+ if (atomic_dec_and_test(&super->s_pending_writes))
+ wake_up(&wq);
+}
+
+static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
+ size_t nr_pages)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ struct bio *bio;
+ struct page *page;
+ struct request_queue *q = bdev_get_queue(sb->s_bdev);
+ unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
+ int i;
+
+ if (max_pages > BIO_MAX_PAGES)
+ max_pages = BIO_MAX_PAGES;
+ bio = bio_alloc(GFP_NOFS, max_pages);
+ BUG_ON(!bio);
+
+ for (i = 0; i < nr_pages; i++) {
+ if (i >= max_pages) {
+ /* Block layer cannot split bios :( */
+ bio->bi_vcnt = i;
+ bio->bi_idx = 0;
+ bio->bi_size = i * PAGE_SIZE;
+ bio->bi_bdev = super->s_bdev;
+ bio->bi_sector = ofs >> 9;
+ bio->bi_private = sb;
+ bio->bi_end_io = writeseg_end_io;
+ atomic_inc(&super->s_pending_writes);
+ submit_bio(WRITE, bio);
+
+ ofs += i * PAGE_SIZE;
+ index += i;
+ nr_pages -= i;
+ i = 0;
+
+ bio = bio_alloc(GFP_NOFS, max_pages);
+ BUG_ON(!bio);
+ }
+ page = find_lock_page(mapping, index + i);
+ BUG_ON(!page);
+ bio->bi_io_vec[i].bv_page = page;
+ bio->bi_io_vec[i].bv_len = PAGE_SIZE;
+ bio->bi_io_vec[i].bv_offset = 0;
+
+ BUG_ON(PageWriteback(page));
+ set_page_writeback(page);
+ unlock_page(page);
+ }
+ bio->bi_vcnt = nr_pages;
+ bio->bi_idx = 0;
+ bio->bi_size = nr_pages * PAGE_SIZE;
+ bio->bi_bdev = super->s_bdev;
+ bio->bi_sector = ofs >> 9;
+ bio->bi_private = sb;
+ bio->bi_end_io = writeseg_end_io;
+ atomic_inc(&super->s_pending_writes);
+ submit_bio(WRITE, bio);
+ return 0;
+}
+
+static void bdev_writeseg(struct super_block *sb, u64 ofs, size_t len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int head;
+
+ BUG_ON(super->s_flags & LOGFS_SB_FLAG_RO);
+
+ if (len == 0) {
+ /* This can happen when the object fit perfectly into a
+ * segment, the segment gets written per sync and subsequently
+ * closed.
+ */
+ return;
+ }
+ head = ofs & (PAGE_SIZE - 1);
+ if (head) {
+ ofs -= head;
+ len += head;
+ }
+ len = PAGE_ALIGN(len);
+ __bdev_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT);
+ generic_unplug_device(bdev_get_queue(logfs_super(sb)->s_bdev));
+}
+
+
+static void erase_end_io(struct bio *bio, int err)
+{
+ const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
+ struct super_block *sb = bio->bi_private;
+ struct logfs_super *super = logfs_super(sb);
+
+ BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */
+ BUG_ON(err);
+ BUG_ON(bio->bi_vcnt == 0);
+ bio_put(bio);
+ if (atomic_dec_and_test(&super->s_pending_writes))
+ wake_up(&wq);
+}
+
+static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index,
+ size_t nr_pages)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct bio *bio;
+ struct request_queue *q = bdev_get_queue(sb->s_bdev);
+ unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
+ int i;
+
+ if (max_pages > BIO_MAX_PAGES)
+ max_pages = BIO_MAX_PAGES;
+ bio = bio_alloc(GFP_NOFS, max_pages);
+ BUG_ON(!bio);
+
+ for (i = 0; i < nr_pages; i++) {
+ if (i >= max_pages) {
+ /* Block layer cannot split bios :( */
+ bio->bi_vcnt = i;
+ bio->bi_idx = 0;
+ bio->bi_size = i * PAGE_SIZE;
+ bio->bi_bdev = super->s_bdev;
+ bio->bi_sector = ofs >> 9;
+ bio->bi_private = sb;
+ bio->bi_end_io = erase_end_io;
+ atomic_inc(&super->s_pending_writes);
+ submit_bio(WRITE, bio);
+
+ ofs += i * PAGE_SIZE;
+ index += i;
+ nr_pages -= i;
+ i = 0;
+
+ bio = bio_alloc(GFP_NOFS, max_pages);
+ BUG_ON(!bio);
+ }
+ bio->bi_io_vec[i].bv_page = super->s_erase_page;
+ bio->bi_io_vec[i].bv_len = PAGE_SIZE;
+ bio->bi_io_vec[i].bv_offset = 0;
+ }
+ bio->bi_vcnt = nr_pages;
+ bio->bi_idx = 0;
+ bio->bi_size = nr_pages * PAGE_SIZE;
+ bio->bi_bdev = super->s_bdev;
+ bio->bi_sector = ofs >> 9;
+ bio->bi_private = sb;
+ bio->bi_end_io = erase_end_io;
+ atomic_inc(&super->s_pending_writes);
+ submit_bio(WRITE, bio);
+ return 0;
+}
+
+static int bdev_erase(struct super_block *sb, loff_t to, size_t len,
+ int ensure_write)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ BUG_ON(to & (PAGE_SIZE - 1));
+ BUG_ON(len & (PAGE_SIZE - 1));
+
+ if (super->s_flags & LOGFS_SB_FLAG_RO)
+ return -EROFS;
+
+ if (ensure_write) {
+ /*
+ * Object store doesn't care whether erases happen or not.
+ * But for the journal they are required. Otherwise a scan
+ * can find an old commit entry and assume it is the current
+ * one, travelling back in time.
+ */
+ do_erase(sb, to, to >> PAGE_SHIFT, len >> PAGE_SHIFT);
+ }
+
+ return 0;
+}
+
+static void bdev_sync(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ wait_event(wq, atomic_read(&super->s_pending_writes) == 0);
+}
+
+static struct page *bdev_find_first_sb(struct super_block *sb, u64 *ofs)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ filler_t *filler = bdev_readpage;
+
+ *ofs = 0;
+ return read_cache_page(mapping, 0, filler, sb);
+}
+
+static struct page *bdev_find_last_sb(struct super_block *sb, u64 *ofs)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ filler_t *filler = bdev_readpage;
+ u64 pos = (super->s_bdev->bd_inode->i_size & ~0xfffULL) - 0x1000;
+ pgoff_t index = pos >> PAGE_SHIFT;
+
+ *ofs = pos;
+ return read_cache_page(mapping, index, filler, sb);
+}
+
+static int bdev_write_sb(struct super_block *sb, struct page *page)
+{
+ struct block_device *bdev = logfs_super(sb)->s_bdev;
+
+ /* Nothing special to do for block devices. */
+ return sync_request(page, bdev, WRITE);
+}
+
+static void bdev_put_device(struct super_block *sb)
+{
+ close_bdev_exclusive(logfs_super(sb)->s_bdev, FMODE_READ|FMODE_WRITE);
+}
+
+static const struct logfs_device_ops bd_devops = {
+ .find_first_sb = bdev_find_first_sb,
+ .find_last_sb = bdev_find_last_sb,
+ .write_sb = bdev_write_sb,
+ .readpage = bdev_readpage,
+ .writeseg = bdev_writeseg,
+ .erase = bdev_erase,
+ .sync = bdev_sync,
+ .put_device = bdev_put_device,
+};
+
+int logfs_get_sb_bdev(struct file_system_type *type, int flags,
+ const char *devname, struct vfsmount *mnt)
+{
+ struct block_device *bdev;
+
+ bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, type);
+ if (IS_ERR(bdev))
+ return PTR_ERR(bdev);
+
+ if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
+ int mtdnr = MINOR(bdev->bd_dev);
+ close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE);
+ return logfs_get_sb_mtd(type, flags, mtdnr, mnt);
+ }
+
+ return logfs_get_sb_device(type, flags, NULL, bdev, &bd_devops, mnt);
+}
diff --git a/fs/logfs/dev_mtd.c b/fs/logfs/dev_mtd.c
new file mode 100644
index 00000000000..cafb6ef2e05
--- /dev/null
+++ b/fs/logfs/dev_mtd.c
@@ -0,0 +1,254 @@
+/*
+ * fs/logfs/dev_mtd.c - Device access methods for MTD
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ */
+#include "logfs.h"
+#include <linux/completion.h>
+#include <linux/mount.h>
+#include <linux/sched.h>
+
+#define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
+
+static int mtd_read(struct super_block *sb, loff_t ofs, size_t len, void *buf)
+{
+ struct mtd_info *mtd = logfs_super(sb)->s_mtd;
+ size_t retlen;
+ int ret;
+
+ ret = mtd->read(mtd, ofs, len, &retlen, buf);
+ BUG_ON(ret == -EINVAL);
+ if (ret)
+ return ret;
+
+ /* Not sure if we should loop instead. */
+ if (retlen != len)
+ return -EIO;
+
+ return 0;
+}
+
+static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct mtd_info *mtd = super->s_mtd;
+ size_t retlen;
+ loff_t page_start, page_end;
+ int ret;
+
+ if (super->s_flags & LOGFS_SB_FLAG_RO)
+ return -EROFS;
+
+ BUG_ON((ofs >= mtd->size) || (len > mtd->size - ofs));
+ BUG_ON(ofs != (ofs >> super->s_writeshift) << super->s_writeshift);
+ BUG_ON(len > PAGE_CACHE_SIZE);
+ page_start = ofs & PAGE_CACHE_MASK;
+ page_end = PAGE_CACHE_ALIGN(ofs + len) - 1;
+ ret = mtd->write(mtd, ofs, len, &retlen, buf);
+ if (ret || (retlen != len))
+ return -EIO;
+
+ return 0;
+}
+
+/*
+ * For as long as I can remember (since about 2001) mtd->erase has been an
+ * asynchronous interface lacking the first driver to actually use the
+ * asynchronous properties. So just to prevent the first implementor of such
+ * a thing from breaking logfs in 2350, we do the usual pointless dance to
+ * declare a completion variable and wait for completion before returning
+ * from mtd_erase(). What an excercise in futility!
+ */
+static void logfs_erase_callback(struct erase_info *ei)
+{
+ complete((struct completion *)ei->priv);
+}
+
+static int mtd_erase_mapping(struct super_block *sb, loff_t ofs, size_t len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ struct page *page;
+ pgoff_t index = ofs >> PAGE_SHIFT;
+
+ for (index = ofs >> PAGE_SHIFT; index < (ofs + len) >> PAGE_SHIFT; index++) {
+ page = find_get_page(mapping, index);
+ if (!page)
+ continue;
+ memset(page_address(page), 0xFF, PAGE_SIZE);
+ page_cache_release(page);
+ }
+ return 0;
+}
+
+static int mtd_erase(struct super_block *sb, loff_t ofs, size_t len,
+ int ensure_write)
+{
+ struct mtd_info *mtd = logfs_super(sb)->s_mtd;
+ struct erase_info ei;
+ DECLARE_COMPLETION_ONSTACK(complete);
+ int ret;
+
+ BUG_ON(len % mtd->erasesize);
+ if (logfs_super(sb)->s_flags & LOGFS_SB_FLAG_RO)
+ return -EROFS;
+
+ memset(&ei, 0, sizeof(ei));
+ ei.mtd = mtd;
+ ei.addr = ofs;
+ ei.len = len;
+ ei.callback = logfs_erase_callback;
+ ei.priv = (long)&complete;
+ ret = mtd->erase(mtd, &ei);
+ if (ret)
+ return -EIO;
+
+ wait_for_completion(&complete);
+ if (ei.state != MTD_ERASE_DONE)
+ return -EIO;
+ return mtd_erase_mapping(sb, ofs, len);
+}
+
+static void mtd_sync(struct super_block *sb)
+{
+ struct mtd_info *mtd = logfs_super(sb)->s_mtd;
+
+ if (mtd->sync)
+ mtd->sync(mtd);
+}
+
+static int mtd_readpage(void *_sb, struct page *page)
+{
+ struct super_block *sb = _sb;
+ int err;
+
+ err = mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE,
+ page_address(page));
+ if (err == -EUCLEAN) {
+ err = 0;
+ /* FIXME: force GC this segment */
+ }
+ if (err) {
+ ClearPageUptodate(page);
+ SetPageError(page);
+ } else {
+ SetPageUptodate(page);
+ ClearPageError(page);
+ }
+ unlock_page(page);
+ return err;
+}
+
+static struct page *mtd_find_first_sb(struct super_block *sb, u64 *ofs)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ filler_t *filler = mtd_readpage;
+ struct mtd_info *mtd = super->s_mtd;
+
+ if (!mtd->block_isbad)
+ return NULL;
+
+ *ofs = 0;
+ while (mtd->block_isbad(mtd, *ofs)) {
+ *ofs += mtd->erasesize;
+ if (*ofs >= mtd->size)
+ return NULL;
+ }
+ BUG_ON(*ofs & ~PAGE_MASK);
+ return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb);
+}
+
+static struct page *mtd_find_last_sb(struct super_block *sb, u64 *ofs)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ filler_t *filler = mtd_readpage;
+ struct mtd_info *mtd = super->s_mtd;
+
+ if (!mtd->block_isbad)
+ return NULL;
+
+ *ofs = mtd->size - mtd->erasesize;
+ while (mtd->block_isbad(mtd, *ofs)) {
+ *ofs -= mtd->erasesize;
+ if (*ofs <= 0)
+ return NULL;
+ }
+ *ofs = *ofs + mtd->erasesize - 0x1000;
+ BUG_ON(*ofs & ~PAGE_MASK);
+ return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb);
+}
+
+static int __mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
+ size_t nr_pages)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ struct page *page;
+ int i, err;
+
+ for (i = 0; i < nr_pages; i++) {
+ page = find_lock_page(mapping, index + i);
+ BUG_ON(!page);
+
+ err = mtd_write(sb, page->index << PAGE_SHIFT, PAGE_SIZE,
+ page_address(page));
+ unlock_page(page);
+ page_cache_release(page);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static void mtd_writeseg(struct super_block *sb, u64 ofs, size_t len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int head;
+
+ if (super->s_flags & LOGFS_SB_FLAG_RO)
+ return;
+
+ if (len == 0) {
+ /* This can happen when the object fit perfectly into a
+ * segment, the segment gets written per sync and subsequently
+ * closed.
+ */
+ return;
+ }
+ head = ofs & (PAGE_SIZE - 1);
+ if (head) {
+ ofs -= head;
+ len += head;
+ }
+ len = PAGE_ALIGN(len);
+ __mtd_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT);
+}
+
+static void mtd_put_device(struct super_block *sb)
+{
+ put_mtd_device(logfs_super(sb)->s_mtd);
+}
+
+static const struct logfs_device_ops mtd_devops = {
+ .find_first_sb = mtd_find_first_sb,
+ .find_last_sb = mtd_find_last_sb,
+ .readpage = mtd_readpage,
+ .writeseg = mtd_writeseg,
+ .erase = mtd_erase,
+ .sync = mtd_sync,
+ .put_device = mtd_put_device,
+};
+
+int logfs_get_sb_mtd(struct file_system_type *type, int flags,
+ int mtdnr, struct vfsmount *mnt)
+{
+ struct mtd_info *mtd;
+ const struct logfs_device_ops *devops = &mtd_devops;
+
+ mtd = get_mtd_device(NULL, mtdnr);
+ return logfs_get_sb_device(type, flags, mtd, NULL, devops, mnt);
+}
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c
new file mode 100644
index 00000000000..2396a85c0f5
--- /dev/null
+++ b/fs/logfs/dir.c
@@ -0,0 +1,827 @@
+/*
+ * fs/logfs/dir.c - directory-related code
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ */
+#include "logfs.h"
+#include <linux/slab.h>
+
+/*
+ * Atomic dir operations
+ *
+ * Directory operations are by default not atomic. Dentries and Inodes are
+ * created/removed/altered in seperate operations. Therefore we need to do
+ * a small amount of journaling.
+ *
+ * Create, link, mkdir, mknod and symlink all share the same function to do
+ * the work: __logfs_create. This function works in two atomic steps:
+ * 1. allocate inode (remember in journal)
+ * 2. allocate dentry (clear journal)
+ *
+ * As we can only get interrupted between the two, when the inode we just
+ * created is simply stored in the anchor. On next mount, if we were
+ * interrupted, we delete the inode. From a users point of view the
+ * operation never happened.
+ *
+ * Unlink and rmdir also share the same function: unlink. Again, this
+ * function works in two atomic steps
+ * 1. remove dentry (remember inode in journal)
+ * 2. unlink inode (clear journal)
+ *
+ * And again, on the next mount, if we were interrupted, we delete the inode.
+ * From a users point of view the operation succeeded.
+ *
+ * Rename is the real pain to deal with, harder than all the other methods
+ * combined. Depending on the circumstances we can run into three cases.
+ * A "target rename" where the target dentry already existed, a "local
+ * rename" where both parent directories are identical or a "cross-directory
+ * rename" in the remaining case.
+ *
+ * Local rename is atomic, as the old dentry is simply rewritten with a new
+ * name.
+ *
+ * Cross-directory rename works in two steps, similar to __logfs_create and
+ * logfs_unlink:
+ * 1. Write new dentry (remember old dentry in journal)
+ * 2. Remove old dentry (clear journal)
+ *
+ * Here we remember a dentry instead of an inode. On next mount, if we were
+ * interrupted, we delete the dentry. From a users point of view, the
+ * operation succeeded.
+ *
+ * Target rename works in three atomic steps:
+ * 1. Attach old inode to new dentry (remember old dentry and new inode)
+ * 2. Remove old dentry (still remember the new inode)
+ * 3. Remove victim inode
+ *
+ * Here we remember both an inode an a dentry. If we get interrupted
+ * between steps 1 and 2, we delete both the dentry and the inode. If
+ * we get interrupted between steps 2 and 3, we delete just the inode.
+ * In either case, the remaining objects are deleted on next mount. From
+ * a users point of view, the operation succeeded.
+ */
+
+static int write_dir(struct inode *dir, struct logfs_disk_dentry *dd,
+ loff_t pos)
+{
+ return logfs_inode_write(dir, dd, sizeof(*dd), pos, WF_LOCK, NULL);
+}
+
+static int write_inode(struct inode *inode)
+{
+ return __logfs_write_inode(inode, WF_LOCK);
+}
+
+static s64 dir_seek_data(struct inode *inode, s64 pos)
+{
+ s64 new_pos = logfs_seek_data(inode, pos);
+
+ return max(pos, new_pos - 1);
+}
+
+static int beyond_eof(struct inode *inode, loff_t bix)
+{
+ loff_t pos = bix << inode->i_sb->s_blocksize_bits;
+ return pos >= i_size_read(inode);
+}
+
+/*
+ * Prime value was chosen to be roughly 256 + 26. r5 hash uses 11,
+ * so short names (len <= 9) don't even occupy the complete 32bit name
+ * space. A prime >256 ensures short names quickly spread the 32bit
+ * name space. Add about 26 for the estimated amount of information
+ * of each character and pick a prime nearby, preferrably a bit-sparse
+ * one.
+ */
+static u32 hash_32(const char *s, int len, u32 seed)
+{
+ u32 hash = seed;
+ int i;
+
+ for (i = 0; i < len; i++)
+ hash = hash * 293 + s[i];
+ return hash;
+}
+
+/*
+ * We have to satisfy several conflicting requirements here. Small
+ * directories should stay fairly compact and not require too many
+ * indirect blocks. The number of possible locations for a given hash
+ * should be small to make lookup() fast. And we should try hard not
+ * to overflow the 32bit name space or nfs and 32bit host systems will
+ * be unhappy.
+ *
+ * So we use the following scheme. First we reduce the hash to 0..15
+ * and try a direct block. If that is occupied we reduce the hash to
+ * 16..255 and try an indirect block. Same for 2x and 3x indirect
+ * blocks. Lastly we reduce the hash to 0x800_0000 .. 0xffff_ffff,
+ * but use buckets containing eight entries instead of a single one.
+ *
+ * Using 16 entries should allow for a reasonable amount of hash
+ * collisions, so the 32bit name space can be packed fairly tight
+ * before overflowing. Oh and currently we don't overflow but return
+ * and error.
+ *
+ * How likely are collisions? Doing the appropriate math is beyond me
+ * and the Bronstein textbook. But running a test program to brute
+ * force collisions for a couple of days showed that on average the
+ * first collision occurs after 598M entries, with 290M being the
+ * smallest result. Obviously 21 entries could already cause a
+ * collision if all entries are carefully chosen.
+ */
+static pgoff_t hash_index(u32 hash, int round)
+{
+ u32 i0_blocks = I0_BLOCKS;
+ u32 i1_blocks = I1_BLOCKS;
+ u32 i2_blocks = I2_BLOCKS;
+ u32 i3_blocks = I3_BLOCKS;
+
+ switch (round) {
+ case 0:
+ return hash % i0_blocks;
+ case 1:
+ return i0_blocks + hash % (i1_blocks - i0_blocks);
+ case 2:
+ return i1_blocks + hash % (i2_blocks - i1_blocks);
+ case 3:
+ return i2_blocks + hash % (i3_blocks - i2_blocks);
+ case 4 ... 19:
+ return i3_blocks + 16 * (hash % (((1<<31) - i3_blocks) / 16))
+ + round - 4;
+ }
+ BUG();
+}
+
+static struct page *logfs_get_dd_page(struct inode *dir, struct dentry *dentry)
+{
+ struct qstr *name = &dentry->d_name;
+ struct page *page;
+ struct logfs_disk_dentry *dd;
+ u32 hash = hash_32(name->name, name->len, 0);
+ pgoff_t index;
+ int round;
+
+ if (name->len > LOGFS_MAX_NAMELEN)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ for (round = 0; round < 20; round++) {
+ index = hash_index(hash, round);
+
+ if (beyond_eof(dir, index))
+ return NULL;
+ if (!logfs_exist_block(dir, index))
+ continue;
+ page = read_cache_page(dir->i_mapping, index,
+ (filler_t *)logfs_readpage, NULL);
+ if (IS_ERR(page))
+ return page;
+ dd = kmap_atomic(page, KM_USER0);
+ BUG_ON(dd->namelen == 0);
+
+ if (name->len != be16_to_cpu(dd->namelen) ||
+ memcmp(name->name, dd->name, name->len)) {
+ kunmap_atomic(dd, KM_USER0);
+ page_cache_release(page);
+ continue;
+ }
+
+ kunmap_atomic(dd, KM_USER0);
+ return page;
+ }
+ return NULL;
+}
+
+static int logfs_remove_inode(struct inode *inode)
+{
+ int ret;
+
+ inode->i_nlink--;
+ ret = write_inode(inode);
+ LOGFS_BUG_ON(ret, inode->i_sb);
+ return ret;
+}
+
+static void abort_transaction(struct inode *inode, struct logfs_transaction *ta)
+{
+ if (logfs_inode(inode)->li_block)
+ logfs_inode(inode)->li_block->ta = NULL;
+ kfree(ta);
+}
+
+static int logfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+ struct logfs_super *super = logfs_super(dir->i_sb);
+ struct inode *inode = dentry->d_inode;
+ struct logfs_transaction *ta;
+ struct page *page;
+ pgoff_t index;
+ int ret;
+
+ ta = kzalloc(sizeof(*ta), GFP_KERNEL);
+ if (!ta)
+ return -ENOMEM;
+
+ ta->state = UNLINK_1;
+ ta->ino = inode->i_ino;
+
+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+
+ page = logfs_get_dd_page(dir, dentry);
+ if (!page) {
+ kfree(ta);
+ return -ENOENT;
+ }
+ if (IS_ERR(page)) {
+ kfree(ta);
+ return PTR_ERR(page);
+ }
+ index = page->index;
+ page_cache_release(page);
+
+ mutex_lock(&super->s_dirop_mutex);
+ logfs_add_transaction(dir, ta);
+
+ ret = logfs_delete(dir, index, NULL);
+ if (!ret)
+ ret = write_inode(dir);
+
+ if (ret) {
+ abort_transaction(dir, ta);
+ printk(KERN_ERR"LOGFS: unable to delete inode\n");
+ goto out;
+ }
+
+ ta->state = UNLINK_2;
+ logfs_add_transaction(inode, ta);
+ ret = logfs_remove_inode(inode);
+out:
+ mutex_unlock(&super->s_dirop_mutex);
+ return ret;
+}
+
+static inline int logfs_empty_dir(struct inode *dir)
+{
+ u64 data;
+
+ data = logfs_seek_data(dir, 0) << dir->i_sb->s_blocksize_bits;
+ return data >= i_size_read(dir);
+}
+
+static int logfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+
+ if (!logfs_empty_dir(inode))
+ return -ENOTEMPTY;
+
+ return logfs_unlink(dir, dentry);
+}
+
+/* FIXME: readdir currently has it's own dir_walk code. I don't see a good
+ * way to combine the two copies */
+#define IMPLICIT_NODES 2
+static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir)
+{
+ struct inode *dir = file->f_dentry->d_inode;
+ loff_t pos = file->f_pos - IMPLICIT_NODES;
+ struct page *page;
+ struct logfs_disk_dentry *dd;
+ int full;
+
+ BUG_ON(pos < 0);
+ for (;; pos++) {
+ if (beyond_eof(dir, pos))
+ break;
+ if (!logfs_exist_block(dir, pos)) {
+ /* deleted dentry */
+ pos = dir_seek_data(dir, pos);
+ continue;
+ }
+ page = read_cache_page(dir->i_mapping, pos,
+ (filler_t *)logfs_readpage, NULL);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
+ dd = kmap(page);
+ BUG_ON(dd->namelen == 0);
+
+ full = filldir(buf, (char *)dd->name, be16_to_cpu(dd->namelen),
+ pos, be64_to_cpu(dd->ino), dd->type);
+ kunmap(page);
+ page_cache_release(page);
+ if (full)
+ break;
+ }
+
+ file->f_pos = pos + IMPLICIT_NODES;
+ return 0;
+}
+
+static int logfs_readdir(struct file *file, void *buf, filldir_t filldir)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ ino_t pino = parent_ino(file->f_dentry);
+ int err;
+
+ if (file->f_pos < 0)
+ return -EINVAL;
+
+ if (file->f_pos == 0) {
+ if (filldir(buf, ".", 1, 1, inode->i_ino, DT_DIR) < 0)
+ return 0;
+ file->f_pos++;
+ }
+ if (file->f_pos == 1) {
+ if (filldir(buf, "..", 2, 2, pino, DT_DIR) < 0)
+ return 0;
+ file->f_pos++;
+ }
+
+ err = __logfs_readdir(file, buf, filldir);
+ return err;
+}
+
+static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name)
+{
+ dd->namelen = cpu_to_be16(name->len);
+ memcpy(dd->name, name->name, name->len);
+}
+
+static struct dentry *logfs_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ struct page *page;
+ struct logfs_disk_dentry *dd;
+ pgoff_t index;
+ u64 ino = 0;
+ struct inode *inode;
+
+ page = logfs_get_dd_page(dir, dentry);
+ if (IS_ERR(page))
+ return ERR_CAST(page);
+ if (!page) {
+ d_add(dentry, NULL);
+ return NULL;
+ }
+ index = page->index;
+ dd = kmap_atomic(page, KM_USER0);
+ ino = be64_to_cpu(dd->ino);
+ kunmap_atomic(dd, KM_USER0);
+ page_cache_release(page);
+
+ inode = logfs_iget(dir->i_sb, ino);
+ if (IS_ERR(inode)) {
+ printk(KERN_ERR"LogFS: Cannot read inode #%llx for dentry (%lx, %lx)n",
+ ino, dir->i_ino, index);
+ return ERR_CAST(inode);
+ }
+ return d_splice_alias(inode, dentry);
+}
+
+static void grow_dir(struct inode *dir, loff_t index)
+{
+ index = (index + 1) << dir->i_sb->s_blocksize_bits;
+ if (i_size_read(dir) < index)
+ i_size_write(dir, index);
+}
+
+static int logfs_write_dir(struct inode *dir, struct dentry *dentry,
+ struct inode *inode)
+{
+ struct page *page;
+ struct logfs_disk_dentry *dd;
+ u32 hash = hash_32(dentry->d_name.name, dentry->d_name.len, 0);
+ pgoff_t index;
+ int round, err;
+
+ for (round = 0; round < 20; round++) {
+ index = hash_index(hash, round);
+
+ if (logfs_exist_block(dir, index))
+ continue;
+ page = find_or_create_page(dir->i_mapping, index, GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+
+ dd = kmap_atomic(page, KM_USER0);
+ memset(dd, 0, sizeof(*dd));
+ dd->ino = cpu_to_be64(inode->i_ino);
+ dd->type = logfs_type(inode);
+ logfs_set_name(dd, &dentry->d_name);
+ kunmap_atomic(dd, KM_USER0);
+
+ err = logfs_write_buf(dir, page, WF_LOCK);
+ unlock_page(page);
+ page_cache_release(page);
+ if (!err)
+ grow_dir(dir, index);
+ return err;
+ }
+ /* FIXME: Is there a better return value? In most cases neither
+ * the filesystem nor the directory are full. But we have had
+ * too many collisions for this particular hash and no fallback.
+ */
+ return -ENOSPC;
+}
+
+static int __logfs_create(struct inode *dir, struct dentry *dentry,
+ struct inode *inode, const char *dest, long destlen)
+{
+ struct logfs_super *super = logfs_super(dir->i_sb);
+ struct logfs_inode *li = logfs_inode(inode);
+ struct logfs_transaction *ta;
+ int ret;
+
+ ta = kzalloc(sizeof(*ta), GFP_KERNEL);
+ if (!ta)
+ return -ENOMEM;
+
+ ta->state = CREATE_1;
+ ta->ino = inode->i_ino;
+ mutex_lock(&super->s_dirop_mutex);
+ logfs_add_transaction(inode, ta);
+
+ if (dest) {
+ /* symlink */
+ ret = logfs_inode_write(inode, dest, destlen, 0, WF_LOCK, NULL);
+ if (!ret)
+ ret = write_inode(inode);
+ } else {
+ /* creat/mkdir/mknod */
+ ret = write_inode(inode);
+ }
+ if (ret) {
+ abort_transaction(inode, ta);
+ li->li_flags |= LOGFS_IF_STILLBORN;
+ /* FIXME: truncate symlink */
+ inode->i_nlink--;
+ iput(inode);
+ goto out;
+ }
+
+ ta->state = CREATE_2;
+ logfs_add_transaction(dir, ta);
+ ret = logfs_write_dir(dir, dentry, inode);
+ /* sync directory */
+ if (!ret)
+ ret = write_inode(dir);
+
+ if (ret) {
+ logfs_del_transaction(dir, ta);
+ ta->state = CREATE_2;
+ logfs_add_transaction(inode, ta);
+ logfs_remove_inode(inode);
+ iput(inode);
+ goto out;
+ }
+ d_instantiate(dentry, inode);
+out:
+ mutex_unlock(&super->s_dirop_mutex);
+ return ret;
+}
+
+static int logfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ struct inode *inode;
+
+ /*
+ * FIXME: why do we have to fill in S_IFDIR, while the mode is
+ * correct for mknod, creat, etc.? Smells like the vfs *should*
+ * do it for us but for some reason fails to do so.
+ */
+ inode = logfs_new_inode(dir, S_IFDIR | mode);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+ inode->i_op = &logfs_dir_iops;
+ inode->i_fop = &logfs_dir_fops;
+
+ return __logfs_create(dir, dentry, inode, NULL, 0);
+}
+
+static int logfs_create(struct inode *dir, struct dentry *dentry, int mode,
+ struct nameidata *nd)
+{
+ struct inode *inode;
+
+ inode = logfs_new_inode(dir, mode);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+ inode->i_op = &logfs_reg_iops;
+ inode->i_fop = &logfs_reg_fops;
+ inode->i_mapping->a_ops = &logfs_reg_aops;
+
+ return __logfs_create(dir, dentry, inode, NULL, 0);
+}
+
+static int logfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
+ dev_t rdev)
+{
+ struct inode *inode;
+
+ if (dentry->d_name.len > LOGFS_MAX_NAMELEN)
+ return -ENAMETOOLONG;
+
+ inode = logfs_new_inode(dir, mode);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+ init_special_inode(inode, mode, rdev);
+
+ return __logfs_create(dir, dentry, inode, NULL, 0);
+}
+
+static int logfs_symlink(struct inode *dir, struct dentry *dentry,
+ const char *target)
+{
+ struct inode *inode;
+ size_t destlen = strlen(target) + 1;
+
+ if (destlen > dir->i_sb->s_blocksize)
+ return -ENAMETOOLONG;
+
+ inode = logfs_new_inode(dir, S_IFLNK | 0777);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+ inode->i_op = &logfs_symlink_iops;
+ inode->i_mapping->a_ops = &logfs_reg_aops;
+
+ return __logfs_create(dir, dentry, inode, target, destlen);
+}
+
+static int logfs_permission(struct inode *inode, int mask)
+{
+ return generic_permission(inode, mask, NULL);
+}
+
+static int logfs_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+
+ if (inode->i_nlink >= LOGFS_LINK_MAX)
+ return -EMLINK;
+
+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ atomic_inc(&inode->i_count);
+ inode->i_nlink++;
+ mark_inode_dirty_sync(inode);
+
+ return __logfs_create(dir, dentry, inode, NULL, 0);
+}
+
+static int logfs_get_dd(struct inode *dir, struct dentry *dentry,
+ struct logfs_disk_dentry *dd, loff_t *pos)
+{
+ struct page *page;
+ void *map;
+
+ page = logfs_get_dd_page(dir, dentry);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
+ *pos = page->index;
+ map = kmap_atomic(page, KM_USER0);
+ memcpy(dd, map, sizeof(*dd));
+ kunmap_atomic(map, KM_USER0);
+ page_cache_release(page);
+ return 0;
+}
+
+static int logfs_delete_dd(struct inode *dir, loff_t pos)
+{
+ /*
+ * Getting called with pos somewhere beyond eof is either a goofup
+ * within this file or means someone maliciously edited the
+ * (crc-protected) journal.
+ */
+ BUG_ON(beyond_eof(dir, pos));
+ dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ log_dir(" Delete dentry (%lx, %llx)\n", dir->i_ino, pos);
+ return logfs_delete(dir, pos, NULL);
+}
+
+/*
+ * Cross-directory rename, target does not exist. Just a little nasty.
+ * Create a new dentry in the target dir, then remove the old dentry,
+ * all the while taking care to remember our operation in the journal.
+ */
+static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct logfs_super *super = logfs_super(old_dir->i_sb);
+ struct logfs_disk_dentry dd;
+ struct logfs_transaction *ta;
+ loff_t pos;
+ int err;
+
+ /* 1. locate source dd */
+ err = logfs_get_dd(old_dir, old_dentry, &dd, &pos);
+ if (err)
+ return err;
+
+ ta = kzalloc(sizeof(*ta), GFP_KERNEL);
+ if (!ta)
+ return -ENOMEM;
+
+ ta->state = CROSS_RENAME_1;
+ ta->dir = old_dir->i_ino;
+ ta->pos = pos;
+
+ /* 2. write target dd */
+ mutex_lock(&super->s_dirop_mutex);
+ logfs_add_transaction(new_dir, ta);
+ err = logfs_write_dir(new_dir, new_dentry, old_dentry->d_inode);
+ if (!err)
+ err = write_inode(new_dir);
+
+ if (err) {
+ super->s_rename_dir = 0;
+ super->s_rename_pos = 0;
+ abort_transaction(new_dir, ta);
+ goto out;
+ }
+
+ /* 3. remove source dd */
+ ta->state = CROSS_RENAME_2;
+ logfs_add_transaction(old_dir, ta);
+ err = logfs_delete_dd(old_dir, pos);
+ if (!err)
+ err = write_inode(old_dir);
+ LOGFS_BUG_ON(err, old_dir->i_sb);
+out:
+ mutex_unlock(&super->s_dirop_mutex);
+ return err;
+}
+
+static int logfs_replace_inode(struct inode *dir, struct dentry *dentry,
+ struct logfs_disk_dentry *dd, struct inode *inode)
+{
+ loff_t pos;
+ int err;
+
+ err = logfs_get_dd(dir, dentry, dd, &pos);
+ if (err)
+ return err;
+ dd->ino = cpu_to_be64(inode->i_ino);
+ dd->type = logfs_type(inode);
+
+ err = write_dir(dir, dd, pos);
+ if (err)
+ return err;
+ log_dir("Replace dentry (%lx, %llx) %s -> %llx\n", dir->i_ino, pos,
+ dd->name, be64_to_cpu(dd->ino));
+ return write_inode(dir);
+}
+
+/* Target dentry exists - the worst case. We need to attach the source
+ * inode to the target dentry, then remove the orphaned target inode and
+ * source dentry.
+ */
+static int logfs_rename_target(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct logfs_super *super = logfs_super(old_dir->i_sb);
+ struct inode *old_inode = old_dentry->d_inode;
+ struct inode *new_inode = new_dentry->d_inode;
+ int isdir = S_ISDIR(old_inode->i_mode);
+ struct logfs_disk_dentry dd;
+ struct logfs_transaction *ta;
+ loff_t pos;
+ int err;
+
+ BUG_ON(isdir != S_ISDIR(new_inode->i_mode));
+ if (isdir) {
+ if (!logfs_empty_dir(new_inode))
+ return -ENOTEMPTY;
+ }
+
+ /* 1. locate source dd */
+ err = logfs_get_dd(old_dir, old_dentry, &dd, &pos);
+ if (err)
+ return err;
+
+ ta = kzalloc(sizeof(*ta), GFP_KERNEL);
+ if (!ta)
+ return -ENOMEM;
+
+ ta->state = TARGET_RENAME_1;
+ ta->dir = old_dir->i_ino;
+ ta->pos = pos;
+ ta->ino = new_inode->i_ino;
+
+ /* 2. attach source inode to target dd */
+ mutex_lock(&super->s_dirop_mutex);
+ logfs_add_transaction(new_dir, ta);
+ err = logfs_replace_inode(new_dir, new_dentry, &dd, old_inode);
+ if (err) {
+ super->s_rename_dir = 0;
+ super->s_rename_pos = 0;
+ super->s_victim_ino = 0;
+ abort_transaction(new_dir, ta);
+ goto out;
+ }
+
+ /* 3. remove source dd */
+ ta->state = TARGET_RENAME_2;
+ logfs_add_transaction(old_dir, ta);
+ err = logfs_delete_dd(old_dir, pos);
+ if (!err)
+ err = write_inode(old_dir);
+ LOGFS_BUG_ON(err, old_dir->i_sb);
+
+ /* 4. remove target inode */
+ ta->state = TARGET_RENAME_3;
+ logfs_add_transaction(new_inode, ta);
+ err = logfs_remove_inode(new_inode);
+
+out:
+ mutex_unlock(&super->s_dirop_mutex);
+ return err;
+}
+
+static int logfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ if (new_dentry->d_inode)
+ return logfs_rename_target(old_dir, old_dentry,
+ new_dir, new_dentry);
+ return logfs_rename_cross(old_dir, old_dentry, new_dir, new_dentry);
+}
+
+/* No locking done here, as this is called before .get_sb() returns. */
+int logfs_replay_journal(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct inode *inode;
+ u64 ino, pos;
+ int err;
+
+ if (super->s_victim_ino) {
+ /* delete victim inode */
+ ino = super->s_victim_ino;
+ printk(KERN_INFO"LogFS: delete unmapped inode #%llx\n", ino);
+ inode = logfs_iget(sb, ino);
+ if (IS_ERR(inode))
+ goto fail;
+
+ LOGFS_BUG_ON(i_size_read(inode) > 0, sb);
+ super->s_victim_ino = 0;
+ err = logfs_remove_inode(inode);
+ iput(inode);
+ if (err) {
+ super->s_victim_ino = ino;
+ goto fail;
+ }
+ }
+ if (super->s_rename_dir) {
+ /* delete old dd from rename */
+ ino = super->s_rename_dir;
+ pos = super->s_rename_pos;
+ printk(KERN_INFO"LogFS: delete unbacked dentry (%llx, %llx)\n",
+ ino, pos);
+ inode = logfs_iget(sb, ino);
+ if (IS_ERR(inode))
+ goto fail;
+
+ super->s_rename_dir = 0;
+ super->s_rename_pos = 0;
+ err = logfs_delete_dd(inode, pos);
+ iput(inode);
+ if (err) {
+ super->s_rename_dir = ino;
+ super->s_rename_pos = pos;
+ goto fail;
+ }
+ }
+ return 0;
+fail:
+ LOGFS_BUG(sb);
+ return -EIO;
+}
+
+const struct inode_operations logfs_symlink_iops = {
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+};
+
+const struct inode_operations logfs_dir_iops = {
+ .create = logfs_create,
+ .link = logfs_link,
+ .lookup = logfs_lookup,
+ .mkdir = logfs_mkdir,
+ .mknod = logfs_mknod,
+ .rename = logfs_rename,
+ .rmdir = logfs_rmdir,
+ .permission = logfs_permission,
+ .symlink = logfs_symlink,
+ .unlink = logfs_unlink,
+};
+const struct file_operations logfs_dir_fops = {
+ .fsync = logfs_fsync,
+ .ioctl = logfs_ioctl,
+ .readdir = logfs_readdir,
+ .read = generic_read_dir,
+};
diff --git a/fs/logfs/file.c b/fs/logfs/file.c
new file mode 100644
index 00000000000..370f367a933
--- /dev/null
+++ b/fs/logfs/file.c
@@ -0,0 +1,263 @@
+/*
+ * fs/logfs/file.c - prepare_write, commit_write and friends
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ */
+#include "logfs.h"
+#include <linux/sched.h>
+#include <linux/writeback.h>
+
+static int logfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ struct inode *inode = mapping->host;
+ struct page *page;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+
+ page = grab_cache_page_write_begin(mapping, index, flags);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
+
+ if ((len == PAGE_CACHE_SIZE) || PageUptodate(page))
+ return 0;
+ if ((pos & PAGE_CACHE_MASK) >= i_size_read(inode)) {
+ unsigned start = pos & (PAGE_CACHE_SIZE - 1);
+ unsigned end = start + len;
+
+ /* Reading beyond i_size is simple: memset to zero */
+ zero_user_segments(page, 0, start, end, PAGE_CACHE_SIZE);
+ return 0;
+ }
+ return logfs_readpage_nolock(page);
+}
+
+static int logfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied, struct page *page,
+ void *fsdata)
+{
+ struct inode *inode = mapping->host;
+ pgoff_t index = page->index;
+ unsigned start = pos & (PAGE_CACHE_SIZE - 1);
+ unsigned end = start + copied;
+ int ret = 0;
+
+ BUG_ON(PAGE_CACHE_SIZE != inode->i_sb->s_blocksize);
+ BUG_ON(page->index > I3_BLOCKS);
+
+ if (copied < len) {
+ /*
+ * Short write of a non-initialized paged. Just tell userspace
+ * to retry the entire page.
+ */
+ if (!PageUptodate(page)) {
+ copied = 0;
+ goto out;
+ }
+ }
+ if (copied == 0)
+ goto out; /* FIXME: do we need to update inode? */
+
+ if (i_size_read(inode) < (index << PAGE_CACHE_SHIFT) + end) {
+ i_size_write(inode, (index << PAGE_CACHE_SHIFT) + end);
+ mark_inode_dirty_sync(inode);
+ }
+
+ SetPageUptodate(page);
+ if (!PageDirty(page)) {
+ if (!get_page_reserve(inode, page))
+ __set_page_dirty_nobuffers(page);
+ else
+ ret = logfs_write_buf(inode, page, WF_LOCK);
+ }
+out:
+ unlock_page(page);
+ page_cache_release(page);
+ return ret ? ret : copied;
+}
+
+int logfs_readpage(struct file *file, struct page *page)
+{
+ int ret;
+
+ ret = logfs_readpage_nolock(page);
+ unlock_page(page);
+ return ret;
+}
+
+/* Clear the page's dirty flag in the radix tree. */
+/* TODO: mucking with PageWriteback is silly. Add a generic function to clear
+ * the dirty bit from the radix tree for filesystems that don't have to wait
+ * for page writeback to finish (i.e. any compressing filesystem).
+ */
+static void clear_radix_tree_dirty(struct page *page)
+{
+ BUG_ON(PagePrivate(page) || page->private);
+ set_page_writeback(page);
+ end_page_writeback(page);
+}
+
+static int __logfs_writepage(struct page *page)
+{
+ struct inode *inode = page->mapping->host;
+ int err;
+
+ err = logfs_write_buf(inode, page, WF_LOCK);
+ if (err)
+ set_page_dirty(page);
+ else
+ clear_radix_tree_dirty(page);
+ unlock_page(page);
+ return err;
+}
+
+static int logfs_writepage(struct page *page, struct writeback_control *wbc)
+{
+ struct inode *inode = page->mapping->host;
+ loff_t i_size = i_size_read(inode);
+ pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
+ unsigned offset;
+ u64 bix;
+ level_t level;
+
+ log_file("logfs_writepage(%lx, %lx, %p)\n", inode->i_ino, page->index,
+ page);
+
+ logfs_unpack_index(page->index, &bix, &level);
+
+ /* Indirect blocks are never truncated */
+ if (level != 0)
+ return __logfs_writepage(page);
+
+ /*
+ * TODO: everything below is a near-verbatim copy of nobh_writepage().
+ * The relevant bits should be factored out after logfs is merged.
+ */
+
+ /* Is the page fully inside i_size? */
+ if (bix < end_index)
+ return __logfs_writepage(page);
+
+ /* Is the page fully outside i_size? (truncate in progress) */
+ offset = i_size & (PAGE_CACHE_SIZE-1);
+ if (bix > end_index || offset == 0) {
+ unlock_page(page);
+ return 0; /* don't care */
+ }
+
+ /*
+ * The page straddles i_size. It must be zeroed out on each and every
+ * writepage invokation because it may be mmapped. "A file is mapped
+ * in multiples of the page size. For a file that is not a multiple of
+ * the page size, the remaining memory is zeroed when mapped, and
+ * writes to that region are not written out to the file."
+ */
+ zero_user_segment(page, offset, PAGE_CACHE_SIZE);
+ return __logfs_writepage(page);
+}
+
+static void logfs_invalidatepage(struct page *page, unsigned long offset)
+{
+ move_page_to_btree(page);
+ BUG_ON(PagePrivate(page) || page->private);
+}
+
+static int logfs_releasepage(struct page *page, gfp_t only_xfs_uses_this)
+{
+ return 0; /* None of these are easy to release */
+}
+
+
+int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ unsigned int oldflags, flags;
+ int err;
+
+ switch (cmd) {
+ case FS_IOC_GETFLAGS:
+ flags = li->li_flags & LOGFS_FL_USER_VISIBLE;
+ return put_user(flags, (int __user *)arg);
+ case FS_IOC_SETFLAGS:
+ if (IS_RDONLY(inode))
+ return -EROFS;
+
+ if (!is_owner_or_cap(inode))
+ return -EACCES;
+
+ err = get_user(flags, (int __user *)arg);
+ if (err)
+ return err;
+
+ mutex_lock(&inode->i_mutex);
+ oldflags = li->li_flags;
+ flags &= LOGFS_FL_USER_MODIFIABLE;
+ flags |= oldflags & ~LOGFS_FL_USER_MODIFIABLE;
+ li->li_flags = flags;
+ mutex_unlock(&inode->i_mutex);
+
+ inode->i_ctime = CURRENT_TIME;
+ mark_inode_dirty_sync(inode);
+ return 0;
+
+ default:
+ return -ENOTTY;
+ }
+}
+
+int logfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+ struct super_block *sb = dentry->d_inode->i_sb;
+ struct logfs_super *super = logfs_super(sb);
+
+ /* FIXME: write anchor */
+ super->s_devops->sync(sb);
+ return 0;
+}
+
+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 = logfs_truncate(inode, attr->ia_size);
+ attr->ia_valid &= ~ATTR_SIZE;
+
+ if (!err)
+ err = inode_change_ok(inode, attr);
+ if (!err)
+ err = inode_setattr(inode, attr);
+ return err;
+}
+
+const struct inode_operations logfs_reg_iops = {
+ .setattr = logfs_setattr,
+};
+
+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,
+ .llseek = generic_file_llseek,
+ .mmap = generic_file_readonly_mmap,
+ .open = generic_file_open,
+ .read = do_sync_read,
+ .write = do_sync_write,
+};
+
+const struct address_space_operations logfs_reg_aops = {
+ .invalidatepage = logfs_invalidatepage,
+ .readpage = logfs_readpage,
+ .releasepage = logfs_releasepage,
+ .set_page_dirty = __set_page_dirty_nobuffers,
+ .writepage = logfs_writepage,
+ .writepages = generic_writepages,
+ .write_begin = logfs_write_begin,
+ .write_end = logfs_write_end,
+};
diff --git a/fs/logfs/gc.c b/fs/logfs/gc.c
new file mode 100644
index 00000000000..76c242fbe1b
--- /dev/null
+++ b/fs/logfs/gc.c
@@ -0,0 +1,739 @@
+/*
+ * fs/logfs/gc.c - garbage collection code
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ */
+#include "logfs.h"
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+/*
+ * Wear leveling needs to kick in when the difference between low erase
+ * counts and high erase counts gets too big. A good value for "too big"
+ * may be somewhat below 10% of maximum erase count for the device.
+ * Why not 397, to pick a nice round number with no specific meaning? :)
+ *
+ * WL_RATELIMIT is the minimum time between two wear level events. A huge
+ * number of segments may fulfil the requirements for wear leveling at the
+ * same time. If that happens we don't want to cause a latency from hell,
+ * but just gently pick one segment every so often and minimize overhead.
+ */
+#define WL_DELTA 397
+#define WL_RATELIMIT 100
+#define MAX_OBJ_ALIASES 2600
+#define SCAN_RATIO 512 /* number of scanned segments per gc'd segment */
+#define LIST_SIZE 64 /* base size of candidate lists */
+#define SCAN_ROUNDS 128 /* maximum number of complete medium scans */
+#define SCAN_ROUNDS_HIGH 4 /* maximum number of higher-level scans */
+
+static int no_free_segments(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ return super->s_free_list.count;
+}
+
+/* journal has distance -1, top-most ifile layer distance 0 */
+static u8 root_distance(struct super_block *sb, gc_level_t __gc_level)
+{
+ struct logfs_super *super = logfs_super(sb);
+ u8 gc_level = (__force u8)__gc_level;
+
+ switch (gc_level) {
+ case 0: /* fall through */
+ case 1: /* fall through */
+ case 2: /* fall through */
+ case 3:
+ /* file data or indirect blocks */
+ return super->s_ifile_levels + super->s_iblock_levels - gc_level;
+ case 6: /* fall through */
+ case 7: /* fall through */
+ case 8: /* fall through */
+ case 9:
+ /* inode file data or indirect blocks */
+ return super->s_ifile_levels - (gc_level - 6);
+ default:
+ printk(KERN_ERR"LOGFS: segment of unknown level %x found\n",
+ gc_level);
+ WARN_ON(1);
+ return super->s_ifile_levels + super->s_iblock_levels;
+ }
+}
+
+static int segment_is_reserved(struct super_block *sb, u32 segno)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_area *area;
+ void *reserved;
+ int i;
+
+ /* Some segments are reserved. Just pretend they were all valid */
+ reserved = btree_lookup32(&super->s_reserved_segments, segno);
+ if (reserved)
+ return 1;
+
+ /* Currently open segments */
+ for_each_area(i) {
+ area = super->s_area[i];
+ if (area->a_is_open && area->a_segno == segno)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void logfs_mark_segment_bad(struct super_block *sb, u32 segno)
+{
+ BUG();
+}
+
+/*
+ * Returns the bytes consumed by valid objects in this segment. Object headers
+ * are counted, the segment header is not.
+ */
+static u32 logfs_valid_bytes(struct super_block *sb, u32 segno, u32 *ec,
+ gc_level_t *gc_level)
+{
+ struct logfs_segment_entry se;
+ u32 ec_level;
+
+ logfs_get_segment_entry(sb, segno, &se);
+ if (se.ec_level == cpu_to_be32(BADSEG) ||
+ se.valid == cpu_to_be32(RESERVED))
+ return RESERVED;
+
+ ec_level = be32_to_cpu(se.ec_level);
+ *ec = ec_level >> 4;
+ *gc_level = GC_LEVEL(ec_level & 0xf);
+ return be32_to_cpu(se.valid);
+}
+
+static void logfs_cleanse_block(struct super_block *sb, u64 ofs, u64 ino,
+ u64 bix, gc_level_t gc_level)
+{
+ struct inode *inode;
+ int err, cookie;
+
+ inode = logfs_safe_iget(sb, ino, &cookie);
+ err = logfs_rewrite_block(inode, bix, ofs, gc_level, 0);
+ BUG_ON(err);
+ logfs_safe_iput(inode, cookie);
+}
+
+static u32 logfs_gc_segment(struct super_block *sb, u32 segno, u8 dist)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_segment_header sh;
+ struct logfs_object_header oh;
+ u64 ofs, ino, bix;
+ u32 seg_ofs, logical_segno, cleaned = 0;
+ int err, len, valid;
+ gc_level_t gc_level;
+
+ LOGFS_BUG_ON(segment_is_reserved(sb, segno), sb);
+
+ btree_insert32(&super->s_reserved_segments, segno, (void *)1, GFP_NOFS);
+ err = wbuf_read(sb, dev_ofs(sb, segno, 0), sizeof(sh), &sh);
+ BUG_ON(err);
+ gc_level = GC_LEVEL(sh.level);
+ logical_segno = be32_to_cpu(sh.segno);
+ if (sh.crc != logfs_crc32(&sh, sizeof(sh), 4)) {
+ logfs_mark_segment_bad(sb, segno);
+ cleaned = -1;
+ goto out;
+ }
+
+ for (seg_ofs = LOGFS_SEGMENT_HEADERSIZE;
+ seg_ofs + sizeof(oh) < super->s_segsize; ) {
+ ofs = dev_ofs(sb, logical_segno, seg_ofs);
+ err = wbuf_read(sb, dev_ofs(sb, segno, seg_ofs), sizeof(oh),
+ &oh);
+ BUG_ON(err);
+
+ if (!memchr_inv(&oh, 0xff, sizeof(oh)))
+ break;
+
+ if (oh.crc != logfs_crc32(&oh, sizeof(oh) - 4, 4)) {
+ logfs_mark_segment_bad(sb, segno);
+ cleaned = super->s_segsize - 1;
+ goto out;
+ }
+
+ ino = be64_to_cpu(oh.ino);
+ bix = be64_to_cpu(oh.bix);
+ len = sizeof(oh) + be16_to_cpu(oh.len);
+ valid = logfs_is_valid_block(sb, ofs, ino, bix, gc_level);
+ if (valid == 1) {
+ logfs_cleanse_block(sb, ofs, ino, bix, gc_level);
+ cleaned += len;
+ } else if (valid == 2) {
+ /* Will be invalid upon journal commit */
+ cleaned += len;
+ }
+ seg_ofs += len;
+ }
+out:
+ btree_remove32(&super->s_reserved_segments, segno);
+ return cleaned;
+}
+
+static struct gc_candidate *add_list(struct gc_candidate *cand,
+ struct candidate_list *list)
+{
+ struct rb_node **p = &list->rb_tree.rb_node;
+ struct rb_node *parent = NULL;
+ struct gc_candidate *cur;
+ int comp;
+
+ cand->list = list;
+ while (*p) {
+ parent = *p;
+ cur = rb_entry(parent, struct gc_candidate, rb_node);
+
+ if (list->sort_by_ec)
+ comp = cand->erase_count < cur->erase_count;
+ else
+ comp = cand->valid < cur->valid;
+
+ if (comp)
+ p = &parent->rb_left;
+ else
+ p = &parent->rb_right;
+ }
+ rb_link_node(&cand->rb_node, parent, p);
+ rb_insert_color(&cand->rb_node, &list->rb_tree);
+
+ if (list->count <= list->maxcount) {
+ list->count++;
+ return NULL;
+ }
+ cand = rb_entry(rb_last(&list->rb_tree), struct gc_candidate, rb_node);
+ rb_erase(&cand->rb_node, &list->rb_tree);
+ cand->list = NULL;
+ return cand;
+}
+
+static void remove_from_list(struct gc_candidate *cand)
+{
+ struct candidate_list *list = cand->list;
+
+ rb_erase(&cand->rb_node, &list->rb_tree);
+ list->count--;
+}
+
+static void free_candidate(struct super_block *sb, struct gc_candidate *cand)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ btree_remove32(&super->s_cand_tree, cand->segno);
+ kfree(cand);
+}
+
+u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec)
+{
+ struct gc_candidate *cand;
+ u32 segno;
+
+ BUG_ON(list->count == 0);
+
+ cand = rb_entry(rb_first(&list->rb_tree), struct gc_candidate, rb_node);
+ remove_from_list(cand);
+ segno = cand->segno;
+ if (ec)
+ *ec = cand->erase_count;
+ free_candidate(sb, cand);
+ return segno;
+}
+
+/*
+ * We have several lists to manage segments with. The reserve_list is used to
+ * deal with bad blocks. We try to keep the best (lowest ec) segments on this
+ * list.
+ * The free_list contains free segments for normal usage. It usually gets the
+ * second pick after the reserve_list. But when the free_list is running short
+ * it is more important to keep the free_list full than to keep a reserve.
+ *
+ * Segments that are not free are put onto a per-level low_list. If we have
+ * to run garbage collection, we pick a candidate from there. All segments on
+ * those lists should have at least some free space so GC will make progress.
+ *
+ * And last we have the ec_list, which is used to pick segments for wear
+ * leveling.
+ *
+ * If all appropriate lists are full, we simply free the candidate and forget
+ * about that segment for a while. We have better candidates for each purpose.
+ */
+static void __add_candidate(struct super_block *sb, struct gc_candidate *cand)
+{
+ struct logfs_super *super = logfs_super(sb);
+ u32 full = super->s_segsize - LOGFS_SEGMENT_RESERVE;
+
+ if (cand->valid == 0) {
+ /* 100% free segments */
+ log_gc_noisy("add reserve segment %x (ec %x) at %llx\n",
+ cand->segno, cand->erase_count,
+ dev_ofs(sb, cand->segno, 0));
+ cand = add_list(cand, &super->s_reserve_list);
+ if (cand) {
+ log_gc_noisy("add free segment %x (ec %x) at %llx\n",
+ cand->segno, cand->erase_count,
+ dev_ofs(sb, cand->segno, 0));
+ cand = add_list(cand, &super->s_free_list);
+ }
+ } else {
+ /* good candidates for Garbage Collection */
+ if (cand->valid < full)
+ cand = add_list(cand, &super->s_low_list[cand->dist]);
+ /* good candidates for wear leveling,
+ * segments that were recently written get ignored */
+ if (cand)
+ cand = add_list(cand, &super->s_ec_list);
+ }
+ if (cand)
+ free_candidate(sb, cand);
+}
+
+static int add_candidate(struct super_block *sb, u32 segno, u32 valid, u32 ec,
+ u8 dist)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct gc_candidate *cand;
+
+ cand = kmalloc(sizeof(*cand), GFP_NOFS);
+ if (!cand)
+ return -ENOMEM;
+
+ cand->segno = segno;
+ cand->valid = valid;
+ cand->erase_count = ec;
+ cand->dist = dist;
+
+ btree_insert32(&super->s_cand_tree, segno, cand, GFP_NOFS);
+ __add_candidate(sb, cand);
+ return 0;
+}
+
+static void remove_segment_from_lists(struct super_block *sb, u32 segno)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct gc_candidate *cand;
+
+ cand = btree_lookup32(&super->s_cand_tree, segno);
+ if (cand) {
+ remove_from_list(cand);
+ free_candidate(sb, cand);
+ }
+}
+
+static void scan_segment(struct super_block *sb, u32 segno)
+{
+ u32 valid, ec = 0;
+ gc_level_t gc_level = 0;
+ u8 dist;
+
+ if (segment_is_reserved(sb, segno))
+ return;
+
+ remove_segment_from_lists(sb, segno);
+ valid = logfs_valid_bytes(sb, segno, &ec, &gc_level);
+ if (valid == RESERVED)
+ return;
+
+ dist = root_distance(sb, gc_level);
+ add_candidate(sb, segno, valid, ec, dist);
+}
+
+static struct gc_candidate *first_in_list(struct candidate_list *list)
+{
+ if (list->count == 0)
+ return NULL;
+ return rb_entry(rb_first(&list->rb_tree), struct gc_candidate, rb_node);
+}
+
+/*
+ * Find the best segment for garbage collection. Main criterion is
+ * the segment requiring the least effort to clean. Secondary
+ * criterion is to GC on the lowest level available.
+ *
+ * So we search the least effort segment on the lowest level first,
+ * then move up and pick another segment iff is requires significantly
+ * less effort. Hence the LOGFS_MAX_OBJECTSIZE in the comparison.
+ */
+static struct gc_candidate *get_candidate(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int i, max_dist;
+ struct gc_candidate *cand = NULL, *this;
+
+ max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS);
+
+ for (i = max_dist; i >= 0; i--) {
+ this = first_in_list(&super->s_low_list[i]);
+ if (!this)
+ continue;
+ if (!cand)
+ cand = this;
+ if (this->valid + LOGFS_MAX_OBJECTSIZE <= cand->valid)
+ cand = this;
+ }
+ return cand;
+}
+
+static int __logfs_gc_once(struct super_block *sb, struct gc_candidate *cand)
+{
+ struct logfs_super *super = logfs_super(sb);
+ gc_level_t gc_level;
+ u32 cleaned, valid, segno, ec;
+ u8 dist;
+
+ if (!cand) {
+ log_gc("GC attempted, but no candidate found\n");
+ return 0;
+ }
+
+ segno = cand->segno;
+ dist = cand->dist;
+ valid = logfs_valid_bytes(sb, segno, &ec, &gc_level);
+ free_candidate(sb, cand);
+ log_gc("GC segment #%02x at %llx, %x required, %x free, %x valid, %llx free\n",
+ segno, (u64)segno << super->s_segshift,
+ dist, no_free_segments(sb), valid,
+ super->s_free_bytes);
+ cleaned = logfs_gc_segment(sb, segno, dist);
+ log_gc("GC segment #%02x complete - now %x valid\n", segno,
+ valid - cleaned);
+ BUG_ON(cleaned != valid);
+ return 1;
+}
+
+static int logfs_gc_once(struct super_block *sb)
+{
+ struct gc_candidate *cand;
+
+ cand = get_candidate(sb);
+ if (cand)
+ remove_from_list(cand);
+ return __logfs_gc_once(sb, cand);
+}
+
+/* returns 1 if a wrap occurs, 0 otherwise */
+static int logfs_scan_some(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ u32 segno;
+ int i, ret = 0;
+
+ segno = super->s_sweeper;
+ for (i = SCAN_RATIO; i > 0; i--) {
+ segno++;
+ if (segno >= super->s_no_segs) {
+ segno = 0;
+ ret = 1;
+ /* Break out of the loop. We want to read a single
+ * block from the segment size on next invocation if
+ * SCAN_RATIO is set to match block size
+ */
+ break;
+ }
+
+ scan_segment(sb, segno);
+ }
+ super->s_sweeper = segno;
+ return ret;
+}
+
+/*
+ * In principle, this function should loop forever, looking for GC candidates
+ * and moving data. LogFS is designed in such a way that this loop is
+ * guaranteed to terminate.
+ *
+ * Limiting the loop to some iterations serves purely to catch cases when
+ * these guarantees have failed. An actual endless loop is an obvious bug
+ * and should be reported as such.
+ */
+static void __logfs_gc_pass(struct super_block *sb, int target)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_block *block;
+ int round, progress, last_progress = 0;
+
+ /*
+ * Doing too many changes to the segfile at once would result
+ * in a large number of aliases. Write the journal before
+ * things get out of hand.
+ */
+ if (super->s_shadow_tree.no_shadowed_segments >= MAX_OBJ_ALIASES)
+ logfs_write_anchor(sb);
+
+ if (no_free_segments(sb) >= target &&
+ super->s_no_object_aliases < MAX_OBJ_ALIASES)
+ return;
+
+ log_gc("__logfs_gc_pass(%x)\n", target);
+ for (round = 0; round < SCAN_ROUNDS; ) {
+ if (no_free_segments(sb) >= target)
+ goto write_alias;
+
+ /* Sync in-memory state with on-medium state in case they
+ * diverged */
+ logfs_write_anchor(sb);
+ round += logfs_scan_some(sb);
+ if (no_free_segments(sb) >= target)
+ goto write_alias;
+ progress = logfs_gc_once(sb);
+ if (progress)
+ last_progress = round;
+ else if (round - last_progress > 2)
+ break;
+ continue;
+
+ /*
+ * The goto logic is nasty, I just don't know a better way to
+ * code it. GC is supposed to ensure two things:
+ * 1. Enough free segments are available.
+ * 2. The number of aliases is bounded.
+ * When 1. is achieved, we take a look at 2. and write back
+ * some alias-containing blocks, if necessary. However, after
+ * each such write we need to go back to 1., as writes can
+ * consume free segments.
+ */
+write_alias:
+ if (super->s_no_object_aliases < MAX_OBJ_ALIASES)
+ return;
+ if (list_empty(&super->s_object_alias)) {
+ /* All aliases are still in btree */
+ return;
+ }
+ log_gc("Write back one alias\n");
+ block = list_entry(super->s_object_alias.next,
+ struct logfs_block, alias_list);
+ block->ops->write_block(block);
+ /*
+ * To round off the nasty goto logic, we reset round here. It
+ * is a safety-net for GC not making any progress and limited
+ * to something reasonably small. If incremented it for every
+ * single alias, the loop could terminate rather quickly.
+ */
+ round = 0;
+ }
+ LOGFS_BUG(sb);
+}
+
+static int wl_ratelimit(struct super_block *sb, u64 *next_event)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ if (*next_event < super->s_gec) {
+ *next_event = super->s_gec + WL_RATELIMIT;
+ return 0;
+ }
+ return 1;
+}
+
+static void logfs_wl_pass(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct gc_candidate *wl_cand, *free_cand;
+
+ if (wl_ratelimit(sb, &super->s_wl_gec_ostore))
+ return;
+
+ wl_cand = first_in_list(&super->s_ec_list);
+ if (!wl_cand)
+ return;
+ free_cand = first_in_list(&super->s_free_list);
+ if (!free_cand)
+ return;
+
+ if (wl_cand->erase_count < free_cand->erase_count + WL_DELTA) {
+ remove_from_list(wl_cand);
+ __logfs_gc_once(sb, wl_cand);
+ }
+}
+
+/*
+ * The journal needs wear leveling as well. But moving the journal is an
+ * expensive operation so we try to avoid it as much as possible. And if we
+ * have to do it, we move the whole journal, not individual segments.
+ *
+ * Ratelimiting is not strictly necessary here, it mainly serves to avoid the
+ * calculations. First we check whether moving the journal would be a
+ * significant improvement. That means that a) the current journal segments
+ * have more wear than the future journal segments and b) the current journal
+ * segments have more wear than normal ostore segments.
+ * Rationale for b) is that we don't have to move the journal if it is aging
+ * less than the ostore, even if the reserve segments age even less (they are
+ * excluded from wear leveling, after all).
+ * Next we check that the superblocks have less wear than the journal. Since
+ * moving the journal requires writing the superblocks, we have to protect the
+ * superblocks even more than the journal.
+ *
+ * Also we double the acceptable wear difference, compared to ostore wear
+ * leveling. Journal data is read and rewritten rapidly, comparatively. So
+ * soft errors have much less time to accumulate and we allow the journal to
+ * be a bit worse than the ostore.
+ */
+static void logfs_journal_wl_pass(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct gc_candidate *cand;
+ u32 min_journal_ec = -1, max_reserve_ec = 0;
+ int i;
+
+ if (wl_ratelimit(sb, &super->s_wl_gec_journal))
+ return;
+
+ if (super->s_reserve_list.count < super->s_no_journal_segs) {
+ /* Reserve is not full enough to move complete journal */
+ return;
+ }
+
+ journal_for_each(i)
+ if (super->s_journal_seg[i])
+ min_journal_ec = min(min_journal_ec,
+ super->s_journal_ec[i]);
+ cand = rb_entry(rb_first(&super->s_free_list.rb_tree),
+ struct gc_candidate, rb_node);
+ max_reserve_ec = cand->erase_count;
+ for (i = 0; i < 2; i++) {
+ struct logfs_segment_entry se;
+ u32 segno = seg_no(sb, super->s_sb_ofs[i]);
+ u32 ec;
+
+ logfs_get_segment_entry(sb, segno, &se);
+ ec = be32_to_cpu(se.ec_level) >> 4;
+ max_reserve_ec = max(max_reserve_ec, ec);
+ }
+
+ if (min_journal_ec > max_reserve_ec + 2 * WL_DELTA) {
+ do_logfs_journal_wl_pass(sb);
+ }
+}
+
+void logfs_gc_pass(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ //BUG_ON(mutex_trylock(&logfs_super(sb)->s_w_mutex));
+ /* Write journal before free space is getting saturated with dirty
+ * objects.
+ */
+ if (super->s_dirty_used_bytes + super->s_dirty_free_bytes
+ + LOGFS_MAX_OBJECTSIZE >= super->s_free_bytes)
+ logfs_write_anchor(sb);
+ __logfs_gc_pass(sb, super->s_total_levels);
+ logfs_wl_pass(sb);
+ logfs_journal_wl_pass(sb);
+}
+
+static int check_area(struct super_block *sb, int i)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_area *area = super->s_area[i];
+ struct logfs_object_header oh;
+ u32 segno = area->a_segno;
+ u32 ofs = area->a_used_bytes;
+ __be32 crc;
+ int err;
+
+ if (!area->a_is_open)
+ return 0;
+
+ for (ofs = area->a_used_bytes;
+ ofs <= super->s_segsize - sizeof(oh);
+ ofs += (u32)be16_to_cpu(oh.len) + sizeof(oh)) {
+ err = wbuf_read(sb, dev_ofs(sb, segno, ofs), sizeof(oh), &oh);
+ if (err)
+ return err;
+
+ if (!memchr_inv(&oh, 0xff, sizeof(oh)))
+ break;
+
+ crc = logfs_crc32(&oh, sizeof(oh) - 4, 4);
+ if (crc != oh.crc) {
+ printk(KERN_INFO "interrupted header at %llx\n",
+ dev_ofs(sb, segno, ofs));
+ return 0;
+ }
+ }
+ if (ofs != area->a_used_bytes) {
+ printk(KERN_INFO "%x bytes unaccounted data found at %llx\n",
+ ofs - area->a_used_bytes,
+ dev_ofs(sb, segno, area->a_used_bytes));
+ area->a_used_bytes = ofs;
+ }
+ return 0;
+}
+
+int logfs_check_areas(struct super_block *sb)
+{
+ int i, err;
+
+ for_each_area(i) {
+ err = check_area(sb, i);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static void logfs_init_candlist(struct candidate_list *list, int maxcount,
+ int sort_by_ec)
+{
+ list->count = 0;
+ list->maxcount = maxcount;
+ list->sort_by_ec = sort_by_ec;
+ list->rb_tree = RB_ROOT;
+}
+
+int logfs_init_gc(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int i;
+
+ btree_init_mempool32(&super->s_cand_tree, super->s_btree_pool);
+ logfs_init_candlist(&super->s_free_list, LIST_SIZE + SCAN_RATIO, 1);
+ logfs_init_candlist(&super->s_reserve_list,
+ super->s_bad_seg_reserve, 1);
+ for_each_area(i)
+ logfs_init_candlist(&super->s_low_list[i], LIST_SIZE, 0);
+ logfs_init_candlist(&super->s_ec_list, LIST_SIZE, 1);
+ return 0;
+}
+
+static void logfs_cleanup_list(struct super_block *sb,
+ struct candidate_list *list)
+{
+ struct gc_candidate *cand;
+
+ while (list->count) {
+ cand = rb_entry(list->rb_tree.rb_node, struct gc_candidate,
+ rb_node);
+ remove_from_list(cand);
+ free_candidate(sb, cand);
+ }
+ BUG_ON(list->rb_tree.rb_node);
+}
+
+void logfs_cleanup_gc(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int i;
+
+ if (!super->s_free_list.count)
+ return;
+
+ /*
+ * FIXME: The btree may still contain a single empty node. So we
+ * call the grim visitor to clean up that mess. Btree code should
+ * do it for us, really.
+ */
+ btree_grim_visitor32(&super->s_cand_tree, 0, NULL);
+ logfs_cleanup_list(sb, &super->s_free_list);
+ logfs_cleanup_list(sb, &super->s_reserve_list);
+ for_each_area(i)
+ logfs_cleanup_list(sb, &super->s_low_list[i]);
+ logfs_cleanup_list(sb, &super->s_ec_list);
+}
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c
new file mode 100644
index 00000000000..14ed27274da
--- /dev/null
+++ b/fs/logfs/inode.c
@@ -0,0 +1,418 @@
+/*
+ * fs/logfs/inode.c - inode handling code
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ */
+#include "logfs.h"
+#include <linux/slab.h>
+#include <linux/writeback.h>
+#include <linux/backing-dev.h>
+
+/*
+ * How soon to reuse old inode numbers? LogFS doesn't store deleted inodes
+ * on the medium. It therefore also lacks a method to store the previous
+ * generation number for deleted inodes. Instead a single generation number
+ * is stored which will be used for new inodes. Being just a 32bit counter,
+ * this can obvious wrap relatively quickly. So we only reuse inodes if we
+ * know that a fair number of inodes can be created before we have to increment
+ * the generation again - effectively adding some bits to the counter.
+ * But being too aggressive here means we keep a very large and very sparse
+ * inode file, wasting space on indirect blocks.
+ * So what is a good value? Beats me. 64k seems moderately bad on both
+ * fronts, so let's use that for now...
+ *
+ * NFS sucks, as everyone already knows.
+ */
+#define INOS_PER_WRAP (0x10000)
+
+/*
+ * Logfs' requirement to read inodes for garbage collection makes life a bit
+ * harder. GC may have to read inodes that are in I_FREEING state, when they
+ * are being written out - and waiting for GC to make progress, naturally.
+ *
+ * So we cannot just call iget() or some variant of it, but first have to check
+ * wether the inode in question might be in I_FREEING state. Therefore we
+ * maintain our own per-sb list of "almost deleted" inodes and check against
+ * that list first. Normally this should be at most 1-2 entries long.
+ *
+ * Also, inodes have logfs-specific reference counting on top of what the vfs
+ * does. When .destroy_inode is called, normally the reference count will drop
+ * to zero and the inode gets deleted. But if GC accessed the inode, its
+ * refcount will remain nonzero and final deletion will have to wait.
+ *
+ * As a result we have two sets of functions to get/put inodes:
+ * logfs_safe_iget/logfs_safe_iput - safe to call from GC context
+ * logfs_iget/iput - normal version
+ */
+static struct kmem_cache *logfs_inode_cache;
+
+static DEFINE_SPINLOCK(logfs_inode_lock);
+
+static void logfs_inode_setops(struct inode *inode)
+{
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFDIR:
+ inode->i_op = &logfs_dir_iops;
+ inode->i_fop = &logfs_dir_fops;
+ inode->i_mapping->a_ops = &logfs_reg_aops;
+ break;
+ case S_IFREG:
+ inode->i_op = &logfs_reg_iops;
+ inode->i_fop = &logfs_reg_fops;
+ inode->i_mapping->a_ops = &logfs_reg_aops;
+ break;
+ case S_IFLNK:
+ inode->i_op = &logfs_symlink_iops;
+ inode->i_mapping->a_ops = &logfs_reg_aops;
+ break;
+ case S_IFSOCK: /* fall through */
+ case S_IFBLK: /* fall through */
+ case S_IFCHR: /* fall through */
+ case S_IFIFO:
+ init_special_inode(inode, inode->i_mode, inode->i_rdev);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static struct inode *__logfs_iget(struct super_block *sb, ino_t ino)
+{
+ struct inode *inode = iget_locked(sb, ino);
+ int err;
+
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+ if (!(inode->i_state & I_NEW))
+ return inode;
+
+ err = logfs_read_inode(inode);
+ if (err || inode->i_nlink == 0) {
+ /* inode->i_nlink == 0 can be true when called from
+ * block validator */
+ /* set i_nlink to 0 to prevent caching */
+ inode->i_nlink = 0;
+ logfs_inode(inode)->li_flags |= LOGFS_IF_ZOMBIE;
+ iget_failed(inode);
+ if (!err)
+ err = -ENOENT;
+ return ERR_PTR(err);
+ }
+
+ logfs_inode_setops(inode);
+ unlock_new_inode(inode);
+ return inode;
+}
+
+struct inode *logfs_iget(struct super_block *sb, ino_t ino)
+{
+ BUG_ON(ino == LOGFS_INO_MASTER);
+ BUG_ON(ino == LOGFS_INO_SEGFILE);
+ return __logfs_iget(sb, ino);
+}
+
+/*
+ * is_cached is set to 1 if we hand out a cached inode, 0 otherwise.
+ * this allows logfs_iput to do the right thing later
+ */
+struct inode *logfs_safe_iget(struct super_block *sb, ino_t ino, int *is_cached)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_inode *li;
+
+ if (ino == LOGFS_INO_MASTER)
+ return super->s_master_inode;
+ if (ino == LOGFS_INO_SEGFILE)
+ return super->s_segfile_inode;
+
+ spin_lock(&logfs_inode_lock);
+ list_for_each_entry(li, &super->s_freeing_list, li_freeing_list)
+ if (li->vfs_inode.i_ino == ino) {
+ li->li_refcount++;
+ spin_unlock(&logfs_inode_lock);
+ *is_cached = 1;
+ return &li->vfs_inode;
+ }
+ spin_unlock(&logfs_inode_lock);
+
+ *is_cached = 0;
+ return __logfs_iget(sb, ino);
+}
+
+static void __logfs_destroy_inode(struct inode *inode)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ BUG_ON(li->li_block);
+ list_del(&li->li_freeing_list);
+ kmem_cache_free(logfs_inode_cache, li);
+}
+
+static void logfs_destroy_inode(struct inode *inode)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ BUG_ON(list_empty(&li->li_freeing_list));
+ spin_lock(&logfs_inode_lock);
+ li->li_refcount--;
+ if (li->li_refcount == 0)
+ __logfs_destroy_inode(inode);
+ spin_unlock(&logfs_inode_lock);
+}
+
+void logfs_safe_iput(struct inode *inode, int is_cached)
+{
+ if (inode->i_ino == LOGFS_INO_MASTER)
+ return;
+ if (inode->i_ino == LOGFS_INO_SEGFILE)
+ return;
+
+ if (is_cached) {
+ logfs_destroy_inode(inode);
+ return;
+ }
+
+ iput(inode);
+}
+
+static void logfs_init_inode(struct super_block *sb, struct inode *inode)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ int i;
+
+ li->li_flags = 0;
+ li->li_height = 0;
+ li->li_used_bytes = 0;
+ li->li_block = NULL;
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+ inode->i_size = 0;
+ inode->i_blocks = 0;
+ inode->i_ctime = CURRENT_TIME;
+ inode->i_mtime = CURRENT_TIME;
+ inode->i_nlink = 1;
+ INIT_LIST_HEAD(&li->li_freeing_list);
+
+ for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
+ li->li_data[i] = 0;
+
+ return;
+}
+
+static struct inode *logfs_alloc_inode(struct super_block *sb)
+{
+ struct logfs_inode *li;
+
+ li = kmem_cache_alloc(logfs_inode_cache, GFP_NOFS);
+ if (!li)
+ return NULL;
+ logfs_init_inode(sb, &li->vfs_inode);
+ return &li->vfs_inode;
+}
+
+/*
+ * In logfs inodes are written to an inode file. The inode file, like any
+ * other file, is managed with a inode. The inode file's inode, aka master
+ * inode, requires special handling in several respects. First, it cannot be
+ * written to the inode file, so it is stored in the journal instead.
+ *
+ * Secondly, this inode cannot be written back and destroyed before all other
+ * inodes have been written. The ordering is important. Linux' VFS is happily
+ * unaware of the ordering constraint and would ordinarily destroy the master
+ * inode at umount time while other inodes are still in use and dirty. Not
+ * good.
+ *
+ * So logfs makes sure the master inode is not written until all other inodes
+ * have been destroyed. Sadly, this method has another side-effect. The VFS
+ * will notice one remaining inode and print a frightening warning message.
+ * Worse, it is impossible to judge whether such a warning was caused by the
+ * master inode or any other inodes have leaked as well.
+ *
+ * Our attempt of solving this is with logfs_new_meta_inode() below. Its
+ * 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.
+ */
+struct inode *logfs_new_meta_inode(struct super_block *sb, u64 ino)
+{
+ struct inode *inode;
+
+ inode = logfs_alloc_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;
+ }
+
+ return inode;
+}
+
+struct inode *logfs_read_meta_inode(struct super_block *sb, u64 ino)
+{
+ struct inode *inode;
+ int err;
+
+ inode = logfs_new_meta_inode(sb, ino);
+ if (IS_ERR(inode))
+ return inode;
+
+ err = logfs_read_inode(inode);
+ if (err) {
+ destroy_meta_inode(inode);
+ return ERR_PTR(err);
+ }
+ logfs_inode_setops(inode);
+ return inode;
+}
+
+static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ int ret;
+ long flags = WF_LOCK;
+
+ /* Can only happen if creat() failed. Safe to skip. */
+ if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN)
+ return 0;
+
+ ret = __logfs_write_inode(inode, flags);
+ LOGFS_BUG_ON(ret, inode->i_sb);
+ 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)
+{
+ struct logfs_super *super = logfs_super(inode->i_sb);
+ struct logfs_inode *li = logfs_inode(inode);
+
+ spin_lock(&logfs_inode_lock);
+ list_move(&li->li_freeing_list, &super->s_freeing_list);
+ spin_unlock(&logfs_inode_lock);
+ generic_drop_inode(inode);
+}
+
+static void logfs_set_ino_generation(struct super_block *sb,
+ struct inode *inode)
+{
+ struct logfs_super *super = logfs_super(sb);
+ u64 ino;
+
+ mutex_lock(&super->s_journal_mutex);
+ ino = logfs_seek_hole(super->s_master_inode, super->s_last_ino);
+ super->s_last_ino = ino;
+ super->s_inos_till_wrap--;
+ if (super->s_inos_till_wrap < 0) {
+ super->s_last_ino = LOGFS_RESERVED_INOS;
+ super->s_generation++;
+ super->s_inos_till_wrap = INOS_PER_WRAP;
+ }
+ inode->i_ino = ino;
+ inode->i_generation = super->s_generation;
+ mutex_unlock(&super->s_journal_mutex);
+}
+
+struct inode *logfs_new_inode(struct inode *dir, int mode)
+{
+ struct super_block *sb = dir->i_sb;
+ struct inode *inode;
+
+ inode = new_inode(sb);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ logfs_init_inode(sb, inode);
+
+ /* inherit parent flags */
+ logfs_inode(inode)->li_flags |=
+ logfs_inode(dir)->li_flags & LOGFS_FL_INHERITED;
+
+ inode->i_mode = mode;
+ logfs_set_ino_generation(sb, inode);
+
+ inode->i_uid = current_fsuid();
+ inode->i_gid = current_fsgid();
+ if (dir->i_mode & S_ISGID) {
+ inode->i_gid = dir->i_gid;
+ if (S_ISDIR(mode))
+ inode->i_mode |= S_ISGID;
+ }
+
+ logfs_inode_setops(inode);
+ insert_inode_hash(inode);
+
+ return inode;
+}
+
+static void logfs_init_once(void *_li)
+{
+ struct logfs_inode *li = _li;
+ int i;
+
+ li->li_flags = 0;
+ li->li_used_bytes = 0;
+ li->li_refcount = 1;
+ for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
+ li->li_data[i] = 0;
+ inode_init_once(&li->vfs_inode);
+}
+
+static int logfs_sync_fs(struct super_block *sb, int wait)
+{
+ /* FIXME: write anchor */
+ logfs_super(sb)->s_devops->sync(sb);
+ return 0;
+}
+
+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,
+ .drop_inode = logfs_drop_inode,
+ .write_inode = logfs_write_inode,
+ .statfs = logfs_statfs,
+ .sync_fs = logfs_sync_fs,
+};
+
+int logfs_init_inode_cache(void)
+{
+ logfs_inode_cache = kmem_cache_create("logfs_inode_cache",
+ sizeof(struct logfs_inode), 0, SLAB_RECLAIM_ACCOUNT,
+ logfs_init_once);
+ if (!logfs_inode_cache)
+ return -ENOMEM;
+ return 0;
+}
+
+void logfs_destroy_inode_cache(void)
+{
+ kmem_cache_destroy(logfs_inode_cache);
+}
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c
new file mode 100644
index 00000000000..fb0a613f885
--- /dev/null
+++ b/fs/logfs/journal.c
@@ -0,0 +1,898 @@
+/*
+ * fs/logfs/journal.c - journal handling code
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ */
+#include "logfs.h"
+#include <linux/slab.h>
+
+static void logfs_calc_free(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ u64 reserve, no_segs = super->s_no_segs;
+ s64 free;
+ int i;
+
+ /* superblock segments */
+ no_segs -= 2;
+ super->s_no_journal_segs = 0;
+ /* journal */
+ journal_for_each(i)
+ if (super->s_journal_seg[i]) {
+ no_segs--;
+ super->s_no_journal_segs++;
+ }
+
+ /* open segments plus one extra per level for GC */
+ no_segs -= 2 * super->s_total_levels;
+
+ free = no_segs * (super->s_segsize - LOGFS_SEGMENT_RESERVE);
+ free -= super->s_used_bytes;
+ /* just a bit extra */
+ free -= super->s_total_levels * 4096;
+
+ /* Bad blocks are 'paid' for with speed reserve - the filesystem
+ * simply gets slower as bad blocks accumulate. Until the bad blocks
+ * exceed the speed reserve - then the filesystem gets smaller.
+ */
+ reserve = super->s_bad_segments + super->s_bad_seg_reserve;
+ reserve *= super->s_segsize - LOGFS_SEGMENT_RESERVE;
+ reserve = max(reserve, super->s_speed_reserve);
+ free -= reserve;
+ if (free < 0)
+ free = 0;
+
+ super->s_free_bytes = free;
+}
+
+static void reserve_sb_and_journal(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct btree_head32 *head = &super->s_reserved_segments;
+ int i, err;
+
+ err = btree_insert32(head, seg_no(sb, super->s_sb_ofs[0]), (void *)1,
+ GFP_KERNEL);
+ BUG_ON(err);
+
+ err = btree_insert32(head, seg_no(sb, super->s_sb_ofs[1]), (void *)1,
+ GFP_KERNEL);
+ BUG_ON(err);
+
+ journal_for_each(i) {
+ if (!super->s_journal_seg[i])
+ continue;
+ err = btree_insert32(head, super->s_journal_seg[i], (void *)1,
+ GFP_KERNEL);
+ BUG_ON(err);
+ }
+}
+
+static void read_dynsb(struct super_block *sb,
+ struct logfs_je_dynsb *dynsb)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ super->s_gec = be64_to_cpu(dynsb->ds_gec);
+ super->s_sweeper = be64_to_cpu(dynsb->ds_sweeper);
+ super->s_victim_ino = be64_to_cpu(dynsb->ds_victim_ino);
+ super->s_rename_dir = be64_to_cpu(dynsb->ds_rename_dir);
+ super->s_rename_pos = be64_to_cpu(dynsb->ds_rename_pos);
+ super->s_used_bytes = be64_to_cpu(dynsb->ds_used_bytes);
+ super->s_generation = be32_to_cpu(dynsb->ds_generation);
+}
+
+static void read_anchor(struct super_block *sb,
+ struct logfs_je_anchor *da)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct inode *inode = super->s_master_inode;
+ struct logfs_inode *li = logfs_inode(inode);
+ int i;
+
+ super->s_last_ino = be64_to_cpu(da->da_last_ino);
+ li->li_flags = 0;
+ li->li_height = da->da_height;
+ i_size_write(inode, be64_to_cpu(da->da_size));
+ li->li_used_bytes = be64_to_cpu(da->da_used_bytes);
+
+ for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
+ li->li_data[i] = be64_to_cpu(da->da_data[i]);
+}
+
+static void read_erasecount(struct super_block *sb,
+ struct logfs_je_journal_ec *ec)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int i;
+
+ journal_for_each(i)
+ super->s_journal_ec[i] = be32_to_cpu(ec->ec[i]);
+}
+
+static int read_area(struct super_block *sb, struct logfs_je_area *a)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_area *area = super->s_area[a->gc_level];
+ u64 ofs;
+ u32 writemask = ~(super->s_writesize - 1);
+
+ if (a->gc_level >= LOGFS_NO_AREAS)
+ return -EIO;
+ if (a->vim != VIM_DEFAULT)
+ return -EIO; /* TODO: close area and continue */
+
+ area->a_used_bytes = be32_to_cpu(a->used_bytes);
+ area->a_written_bytes = area->a_used_bytes & writemask;
+ area->a_segno = be32_to_cpu(a->segno);
+ if (area->a_segno)
+ area->a_is_open = 1;
+
+ ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
+ if (super->s_writesize > 1)
+ logfs_buf_recover(area, ofs, a + 1, super->s_writesize);
+ else
+ logfs_buf_recover(area, ofs, NULL, 0);
+ return 0;
+}
+
+static void *unpack(void *from, void *to)
+{
+ struct logfs_journal_header *jh = from;
+ void *data = from + sizeof(struct logfs_journal_header);
+ int err;
+ size_t inlen, outlen;
+
+ inlen = be16_to_cpu(jh->h_len);
+ outlen = be16_to_cpu(jh->h_datalen);
+
+ if (jh->h_compr == COMPR_NONE)
+ memcpy(to, data, inlen);
+ else {
+ err = logfs_uncompress(data, to, inlen, outlen);
+ BUG_ON(err);
+ }
+ return to;
+}
+
+static int __read_je_header(struct super_block *sb, u64 ofs,
+ struct logfs_journal_header *jh)
+{
+ struct logfs_super *super = logfs_super(sb);
+ size_t bufsize = max_t(size_t, sb->s_blocksize, super->s_writesize)
+ + MAX_JOURNAL_HEADER;
+ u16 type, len, datalen;
+ int err;
+
+ /* read header only */
+ err = wbuf_read(sb, ofs, sizeof(*jh), jh);
+ if (err)
+ return err;
+ type = be16_to_cpu(jh->h_type);
+ len = be16_to_cpu(jh->h_len);
+ datalen = be16_to_cpu(jh->h_datalen);
+ if (len > sb->s_blocksize)
+ return -EIO;
+ if ((type < JE_FIRST) || (type > JE_LAST))
+ return -EIO;
+ if (datalen > bufsize)
+ return -EIO;
+ return 0;
+}
+
+static int __read_je_payload(struct super_block *sb, u64 ofs,
+ struct logfs_journal_header *jh)
+{
+ u16 len;
+ int err;
+
+ len = be16_to_cpu(jh->h_len);
+ err = wbuf_read(sb, ofs + sizeof(*jh), len, jh + 1);
+ if (err)
+ return err;
+ if (jh->h_crc != logfs_crc32(jh, len + sizeof(*jh), 4)) {
+ /* Old code was confused. It forgot about the header length
+ * and stopped calculating the crc 16 bytes before the end
+ * of data - ick!
+ * FIXME: Remove this hack once the old code is fixed.
+ */
+ if (jh->h_crc == logfs_crc32(jh, len, 4))
+ WARN_ON_ONCE(1);
+ else
+ return -EIO;
+ }
+ return 0;
+}
+
+/*
+ * jh needs to be large enough to hold the complete entry, not just the header
+ */
+static int __read_je(struct super_block *sb, u64 ofs,
+ struct logfs_journal_header *jh)
+{
+ int err;
+
+ err = __read_je_header(sb, ofs, jh);
+ if (err)
+ return err;
+ return __read_je_payload(sb, ofs, jh);
+}
+
+static int read_je(struct super_block *sb, u64 ofs)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_journal_header *jh = super->s_compressed_je;
+ void *scratch = super->s_je;
+ u16 type, datalen;
+ int err;
+
+ err = __read_je(sb, ofs, jh);
+ if (err)
+ return err;
+ type = be16_to_cpu(jh->h_type);
+ datalen = be16_to_cpu(jh->h_datalen);
+
+ switch (type) {
+ case JE_DYNSB:
+ read_dynsb(sb, unpack(jh, scratch));
+ break;
+ case JE_ANCHOR:
+ read_anchor(sb, unpack(jh, scratch));
+ break;
+ case JE_ERASECOUNT:
+ read_erasecount(sb, unpack(jh, scratch));
+ break;
+ case JE_AREA:
+ read_area(sb, unpack(jh, scratch));
+ break;
+ case JE_OBJ_ALIAS:
+ err = logfs_load_object_aliases(sb, unpack(jh, scratch),
+ datalen);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ return -EIO;
+ }
+ return err;
+}
+
+static int logfs_read_segment(struct super_block *sb, u32 segno)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_journal_header *jh = super->s_compressed_je;
+ u64 ofs, seg_ofs = dev_ofs(sb, segno, 0);
+ u32 h_ofs, last_ofs = 0;
+ u16 len, datalen, last_len = 0;
+ int i, err;
+
+ /* search for most recent commit */
+ for (h_ofs = 0; h_ofs < super->s_segsize; h_ofs += sizeof(*jh)) {
+ ofs = seg_ofs + h_ofs;
+ err = __read_je_header(sb, ofs, jh);
+ if (err)
+ continue;
+ if (jh->h_type != cpu_to_be16(JE_COMMIT))
+ continue;
+ err = __read_je_payload(sb, ofs, jh);
+ if (err)
+ continue;
+ len = be16_to_cpu(jh->h_len);
+ datalen = be16_to_cpu(jh->h_datalen);
+ if ((datalen > sizeof(super->s_je_array)) ||
+ (datalen % sizeof(__be64)))
+ continue;
+ last_ofs = h_ofs;
+ last_len = datalen;
+ h_ofs += ALIGN(len, sizeof(*jh)) - sizeof(*jh);
+ }
+ /* read commit */
+ if (last_ofs == 0)
+ return -ENOENT;
+ ofs = seg_ofs + last_ofs;
+ log_journal("Read commit from %llx\n", ofs);
+ err = __read_je(sb, ofs, jh);
+ BUG_ON(err); /* We should have caught it in the scan loop already */
+ if (err)
+ return err;
+ /* uncompress */
+ unpack(jh, super->s_je_array);
+ super->s_no_je = last_len / sizeof(__be64);
+ /* iterate over array */
+ for (i = 0; i < super->s_no_je; i++) {
+ err = read_je(sb, be64_to_cpu(super->s_je_array[i]));
+ if (err)
+ return err;
+ }
+ super->s_journal_area->a_segno = segno;
+ return 0;
+}
+
+static u64 read_gec(struct super_block *sb, u32 segno)
+{
+ struct logfs_segment_header sh;
+ __be32 crc;
+ int err;
+
+ if (!segno)
+ return 0;
+ err = wbuf_read(sb, dev_ofs(sb, segno, 0), sizeof(sh), &sh);
+ if (err)
+ return 0;
+ crc = logfs_crc32(&sh, sizeof(sh), 4);
+ if (crc != sh.crc) {
+ WARN_ON(sh.gec != cpu_to_be64(0xffffffffffffffffull));
+ /* Most likely it was just erased */
+ return 0;
+ }
+ return be64_to_cpu(sh.gec);
+}
+
+static int logfs_read_journal(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ u64 gec[LOGFS_JOURNAL_SEGS], max;
+ u32 segno;
+ int i, max_i;
+
+ max = 0;
+ max_i = -1;
+ journal_for_each(i) {
+ segno = super->s_journal_seg[i];
+ gec[i] = read_gec(sb, super->s_journal_seg[i]);
+ if (gec[i] > max) {
+ max = gec[i];
+ max_i = i;
+ }
+ }
+ if (max_i == -1)
+ return -EIO;
+ /* FIXME: Try older segments in case of error */
+ return logfs_read_segment(sb, super->s_journal_seg[max_i]);
+}
+
+/*
+ * First search the current segment (outer loop), then pick the next segment
+ * in the array, skipping any zero entries (inner loop).
+ */
+static void journal_get_free_segment(struct logfs_area *area)
+{
+ struct logfs_super *super = logfs_super(area->a_sb);
+ int i;
+
+ journal_for_each(i) {
+ if (area->a_segno != super->s_journal_seg[i])
+ continue;
+
+ do {
+ i++;
+ if (i == LOGFS_JOURNAL_SEGS)
+ i = 0;
+ } while (!super->s_journal_seg[i]);
+
+ area->a_segno = super->s_journal_seg[i];
+ area->a_erase_count = ++(super->s_journal_ec[i]);
+ log_journal("Journal now at %x (ec %x)\n", area->a_segno,
+ area->a_erase_count);
+ return;
+ }
+ BUG();
+}
+
+static void journal_get_erase_count(struct logfs_area *area)
+{
+ /* erase count is stored globally and incremented in
+ * journal_get_free_segment() - nothing to do here */
+}
+
+static int journal_erase_segment(struct logfs_area *area)
+{
+ struct super_block *sb = area->a_sb;
+ union {
+ struct logfs_segment_header sh;
+ unsigned char c[ALIGN(sizeof(struct logfs_segment_header), 16)];
+ } u;
+ u64 ofs;
+ int err;
+
+ err = logfs_erase_segment(sb, area->a_segno, 1);
+ if (err)
+ return err;
+
+ memset(&u, 0, sizeof(u));
+ u.sh.pad = 0;
+ u.sh.type = SEG_JOURNAL;
+ u.sh.level = 0;
+ u.sh.segno = cpu_to_be32(area->a_segno);
+ u.sh.ec = cpu_to_be32(area->a_erase_count);
+ u.sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
+ u.sh.crc = logfs_crc32(&u.sh, sizeof(u.sh), 4);
+
+ /* This causes a bug in segment.c. Not yet. */
+ //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0);
+
+ ofs = dev_ofs(sb, area->a_segno, 0);
+ area->a_used_bytes = sizeof(u);
+ logfs_buf_write(area, ofs, &u, sizeof(u));
+ return 0;
+}
+
+static size_t __logfs_write_header(struct logfs_super *super,
+ struct logfs_journal_header *jh, size_t len, size_t datalen,
+ u16 type, u8 compr)
+{
+ jh->h_len = cpu_to_be16(len);
+ jh->h_type = cpu_to_be16(type);
+ jh->h_datalen = cpu_to_be16(datalen);
+ jh->h_compr = compr;
+ jh->h_pad[0] = 'H';
+ jh->h_pad[1] = 'E';
+ jh->h_pad[2] = 'A';
+ jh->h_pad[3] = 'D';
+ jh->h_pad[4] = 'R';
+ jh->h_crc = logfs_crc32(jh, len + sizeof(*jh), 4);
+ return ALIGN(len, 16) + sizeof(*jh);
+}
+
+static size_t logfs_write_header(struct logfs_super *super,
+ struct logfs_journal_header *jh, size_t datalen, u16 type)
+{
+ size_t len = datalen;
+
+ return __logfs_write_header(super, jh, len, datalen, type, COMPR_NONE);
+}
+
+static inline size_t logfs_journal_erasecount_size(struct logfs_super *super)
+{
+ return LOGFS_JOURNAL_SEGS * sizeof(__be32);
+}
+
+static void *logfs_write_erasecount(struct super_block *sb, void *_ec,
+ u16 *type, size_t *len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_je_journal_ec *ec = _ec;
+ int i;
+
+ journal_for_each(i)
+ ec->ec[i] = cpu_to_be32(super->s_journal_ec[i]);
+ *type = JE_ERASECOUNT;
+ *len = logfs_journal_erasecount_size(super);
+ return ec;
+}
+
+static void account_shadow(void *_shadow, unsigned long _sb, u64 ignore,
+ size_t ignore2)
+{
+ struct logfs_shadow *shadow = _shadow;
+ struct super_block *sb = (void *)_sb;
+ struct logfs_super *super = logfs_super(sb);
+
+ /* consume new space */
+ super->s_free_bytes -= shadow->new_len;
+ super->s_used_bytes += shadow->new_len;
+ super->s_dirty_used_bytes -= shadow->new_len;
+
+ /* free up old space */
+ super->s_free_bytes += shadow->old_len;
+ super->s_used_bytes -= shadow->old_len;
+ super->s_dirty_free_bytes -= shadow->old_len;
+
+ logfs_set_segment_used(sb, shadow->old_ofs, -shadow->old_len);
+ logfs_set_segment_used(sb, shadow->new_ofs, shadow->new_len);
+
+ log_journal("account_shadow(%llx, %llx, %x) %llx->%llx %x->%x\n",
+ shadow->ino, shadow->bix, shadow->gc_level,
+ shadow->old_ofs, shadow->new_ofs,
+ shadow->old_len, shadow->new_len);
+ mempool_free(shadow, super->s_shadow_pool);
+}
+
+static void account_shadows(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct inode *inode = super->s_master_inode;
+ struct logfs_inode *li = logfs_inode(inode);
+ struct shadow_tree *tree = &super->s_shadow_tree;
+
+ btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow);
+ btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow);
+ btree_grim_visitor32(&tree->segment_map, 0, NULL);
+ tree->no_shadowed_segments = 0;
+
+ if (li->li_block) {
+ /*
+ * We never actually use the structure, when attached to the
+ * master inode. But it is easier to always free it here than
+ * to have checks in several places elsewhere when allocating
+ * it.
+ */
+ li->li_block->ops->free_block(sb, li->li_block);
+ }
+ BUG_ON((s64)li->li_used_bytes < 0);
+}
+
+static void *__logfs_write_anchor(struct super_block *sb, void *_da,
+ u16 *type, size_t *len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_je_anchor *da = _da;
+ struct inode *inode = super->s_master_inode;
+ struct logfs_inode *li = logfs_inode(inode);
+ int i;
+
+ da->da_height = li->li_height;
+ da->da_last_ino = cpu_to_be64(super->s_last_ino);
+ da->da_size = cpu_to_be64(i_size_read(inode));
+ da->da_used_bytes = cpu_to_be64(li->li_used_bytes);
+ for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
+ da->da_data[i] = cpu_to_be64(li->li_data[i]);
+ *type = JE_ANCHOR;
+ *len = sizeof(*da);
+ return da;
+}
+
+static void *logfs_write_dynsb(struct super_block *sb, void *_dynsb,
+ u16 *type, size_t *len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_je_dynsb *dynsb = _dynsb;
+
+ dynsb->ds_gec = cpu_to_be64(super->s_gec);
+ dynsb->ds_sweeper = cpu_to_be64(super->s_sweeper);
+ dynsb->ds_victim_ino = cpu_to_be64(super->s_victim_ino);
+ dynsb->ds_rename_dir = cpu_to_be64(super->s_rename_dir);
+ dynsb->ds_rename_pos = cpu_to_be64(super->s_rename_pos);
+ dynsb->ds_used_bytes = cpu_to_be64(super->s_used_bytes);
+ dynsb->ds_generation = cpu_to_be32(super->s_generation);
+ *type = JE_DYNSB;
+ *len = sizeof(*dynsb);
+ return dynsb;
+}
+
+static void write_wbuf(struct super_block *sb, struct logfs_area *area,
+ void *wbuf)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ u64 ofs;
+ pgoff_t index;
+ int page_ofs;
+ struct page *page;
+
+ ofs = dev_ofs(sb, area->a_segno,
+ area->a_used_bytes & ~(super->s_writesize - 1));
+ index = ofs >> PAGE_SHIFT;
+ page_ofs = ofs & (PAGE_SIZE - 1);
+
+ page = find_lock_page(mapping, index);
+ BUG_ON(!page);
+ memcpy(wbuf, page_address(page) + page_ofs, super->s_writesize);
+ unlock_page(page);
+}
+
+static void *logfs_write_area(struct super_block *sb, void *_a,
+ u16 *type, size_t *len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_area *area = super->s_area[super->s_sum_index];
+ struct logfs_je_area *a = _a;
+
+ a->vim = VIM_DEFAULT;
+ a->gc_level = super->s_sum_index;
+ a->used_bytes = cpu_to_be32(area->a_used_bytes);
+ a->segno = cpu_to_be32(area->a_segno);
+ if (super->s_writesize > 1)
+ write_wbuf(sb, area, a + 1);
+
+ *type = JE_AREA;
+ *len = sizeof(*a) + super->s_writesize;
+ return a;
+}
+
+static void *logfs_write_commit(struct super_block *sb, void *h,
+ u16 *type, size_t *len)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ *type = JE_COMMIT;
+ *len = super->s_no_je * sizeof(__be64);
+ return super->s_je_array;
+}
+
+static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type,
+ size_t len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ void *header = super->s_compressed_je;
+ void *data = header + sizeof(struct logfs_journal_header);
+ ssize_t compr_len, pad_len;
+ u8 compr = COMPR_ZLIB;
+
+ if (len == 0)
+ return logfs_write_header(super, header, 0, type);
+
+ BUG_ON(len > sb->s_blocksize);
+ compr_len = logfs_compress(buf, data, len, sb->s_blocksize);
+ if (compr_len < 0 || type == JE_ANCHOR) {
+ memcpy(data, buf, len);
+ compr_len = len;
+ compr = COMPR_NONE;
+ }
+
+ pad_len = ALIGN(compr_len, 16);
+ memset(data + compr_len, 0, pad_len - compr_len);
+
+ return __logfs_write_header(super, header, compr_len, len, type, compr);
+}
+
+static s64 logfs_get_free_bytes(struct logfs_area *area, size_t *bytes,
+ int must_pad)
+{
+ u32 writesize = logfs_super(area->a_sb)->s_writesize;
+ s32 ofs;
+ int ret;
+
+ ret = logfs_open_area(area, *bytes);
+ if (ret)
+ return -EAGAIN;
+
+ ofs = area->a_used_bytes;
+ area->a_used_bytes += *bytes;
+
+ if (must_pad) {
+ area->a_used_bytes = ALIGN(area->a_used_bytes, writesize);
+ *bytes = area->a_used_bytes - ofs;
+ }
+
+ return dev_ofs(area->a_sb, area->a_segno, ofs);
+}
+
+static int logfs_write_je_buf(struct super_block *sb, void *buf, u16 type,
+ size_t buf_len)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_area *area = super->s_journal_area;
+ struct logfs_journal_header *jh = super->s_compressed_je;
+ size_t len;
+ int must_pad = 0;
+ s64 ofs;
+
+ len = __logfs_write_je(sb, buf, type, buf_len);
+ if (jh->h_type == cpu_to_be16(JE_COMMIT))
+ must_pad = 1;
+
+ ofs = logfs_get_free_bytes(area, &len, must_pad);
+ if (ofs < 0)
+ return ofs;
+ logfs_buf_write(area, ofs, super->s_compressed_je, len);
+ BUG_ON(super->s_no_je >= MAX_JOURNAL_ENTRIES);
+ super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs);
+ return 0;
+}
+
+static int logfs_write_je(struct super_block *sb,
+ void* (*write)(struct super_block *sb, void *scratch,
+ u16 *type, size_t *len))
+{
+ void *buf;
+ size_t len;
+ u16 type;
+
+ buf = write(sb, logfs_super(sb)->s_je, &type, &len);
+ return logfs_write_je_buf(sb, buf, type, len);
+}
+
+int write_alias_journal(struct super_block *sb, u64 ino, u64 bix,
+ level_t level, int child_no, __be64 val)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_obj_alias *oa = super->s_je;
+ int err = 0, fill = super->s_je_fill;
+
+ log_aliases("logfs_write_obj_aliases #%x(%llx, %llx, %x, %x) %llx\n",
+ fill, ino, bix, level, child_no, be64_to_cpu(val));
+ oa[fill].ino = cpu_to_be64(ino);
+ oa[fill].bix = cpu_to_be64(bix);
+ oa[fill].val = val;
+ oa[fill].level = (__force u8)level;
+ oa[fill].child_no = cpu_to_be16(child_no);
+ fill++;
+ if (fill >= sb->s_blocksize / sizeof(*oa)) {
+ err = logfs_write_je_buf(sb, oa, JE_OBJ_ALIAS, sb->s_blocksize);
+ fill = 0;
+ }
+
+ super->s_je_fill = fill;
+ return err;
+}
+
+static int logfs_write_obj_aliases(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int err;
+
+ log_journal("logfs_write_obj_aliases: %d aliases to write\n",
+ super->s_no_object_aliases);
+ super->s_je_fill = 0;
+ err = logfs_write_obj_aliases_pagecache(sb);
+ if (err)
+ return err;
+
+ if (super->s_je_fill)
+ err = logfs_write_je_buf(sb, super->s_je, JE_OBJ_ALIAS,
+ super->s_je_fill
+ * sizeof(struct logfs_obj_alias));
+ return err;
+}
+
+/*
+ * Write all journal entries. The goto logic ensures that all journal entries
+ * are written whenever a new segment is used. It is ugly and potentially a
+ * bit wasteful, but robustness is more important. With this we can *always*
+ * erase all journal segments except the one containing the most recent commit.
+ */
+void logfs_write_anchor(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_area *area = super->s_journal_area;
+ int i, err;
+
+ if (!(super->s_flags & LOGFS_SB_FLAG_DIRTY))
+ return;
+ super->s_flags &= ~LOGFS_SB_FLAG_DIRTY;
+
+ BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
+ mutex_lock(&super->s_journal_mutex);
+
+ /* Do this first or suffer corruption */
+ logfs_sync_segments(sb);
+ account_shadows(sb);
+
+again:
+ super->s_no_je = 0;
+ for_each_area(i) {
+ if (!super->s_area[i]->a_is_open)
+ continue;
+ super->s_sum_index = i;
+ err = logfs_write_je(sb, logfs_write_area);
+ if (err)
+ goto again;
+ }
+ err = logfs_write_obj_aliases(sb);
+ if (err)
+ goto again;
+ err = logfs_write_je(sb, logfs_write_erasecount);
+ if (err)
+ goto again;
+ err = logfs_write_je(sb, __logfs_write_anchor);
+ if (err)
+ goto again;
+ err = logfs_write_je(sb, logfs_write_dynsb);
+ if (err)
+ goto again;
+ /*
+ * Order is imperative. First we sync all writes, including the
+ * non-committed journal writes. Then we write the final commit and
+ * sync the current journal segment.
+ * There is a theoretical bug here. Syncing the journal segment will
+ * write a number of journal entries and the final commit. All these
+ * are written in a single operation. If the device layer writes the
+ * data back-to-front, the commit will precede the other journal
+ * entries, leaving a race window.
+ * Two fixes are possible. Preferred is to fix the device layer to
+ * ensure writes happen front-to-back. Alternatively we can insert
+ * another logfs_sync_area() super->s_devops->sync() combo before
+ * writing the commit.
+ */
+ /*
+ * On another subject, super->s_devops->sync is usually not necessary.
+ * Unless called from sys_sync or friends, a barrier would suffice.
+ */
+ super->s_devops->sync(sb);
+ err = logfs_write_je(sb, logfs_write_commit);
+ if (err)
+ goto again;
+ log_journal("Write commit to %llx\n",
+ be64_to_cpu(super->s_je_array[super->s_no_je - 1]));
+ logfs_sync_area(area);
+ BUG_ON(area->a_used_bytes != area->a_written_bytes);
+ super->s_devops->sync(sb);
+
+ mutex_unlock(&super->s_journal_mutex);
+ return;
+}
+
+void do_logfs_journal_wl_pass(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_area *area = super->s_journal_area;
+ struct btree_head32 *head = &super->s_reserved_segments;
+ u32 segno, ec;
+ int i, err;
+
+ log_journal("Journal requires wear-leveling.\n");
+ /* Drop old segments */
+ journal_for_each(i)
+ if (super->s_journal_seg[i]) {
+ btree_remove32(head, super->s_journal_seg[i]);
+ logfs_set_segment_unreserved(sb,
+ super->s_journal_seg[i],
+ super->s_journal_ec[i]);
+ super->s_journal_seg[i] = 0;
+ super->s_journal_ec[i] = 0;
+ }
+ /* Get new segments */
+ for (i = 0; i < super->s_no_journal_segs; i++) {
+ segno = get_best_cand(sb, &super->s_reserve_list, &ec);
+ super->s_journal_seg[i] = segno;
+ super->s_journal_ec[i] = ec;
+ logfs_set_segment_reserved(sb, segno);
+ err = btree_insert32(head, segno, (void *)1, GFP_KERNEL);
+ BUG_ON(err); /* mempool should prevent this */
+ err = logfs_erase_segment(sb, segno, 1);
+ BUG_ON(err); /* FIXME: remount-ro would be nicer */
+ }
+ /* Manually move journal_area */
+ freeseg(sb, area->a_segno);
+ area->a_segno = super->s_journal_seg[0];
+ area->a_is_open = 0;
+ area->a_used_bytes = 0;
+ /* Write journal */
+ logfs_write_anchor(sb);
+ /* Write superblocks */
+ err = logfs_write_sb(sb);
+ BUG_ON(err);
+}
+
+static const struct logfs_area_ops journal_area_ops = {
+ .get_free_segment = journal_get_free_segment,
+ .get_erase_count = journal_get_erase_count,
+ .erase_segment = journal_erase_segment,
+};
+
+int logfs_init_journal(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ size_t bufsize = max_t(size_t, sb->s_blocksize, super->s_writesize)
+ + MAX_JOURNAL_HEADER;
+ int ret = -ENOMEM;
+
+ mutex_init(&super->s_journal_mutex);
+ btree_init_mempool32(&super->s_reserved_segments, super->s_btree_pool);
+
+ super->s_je = kzalloc(bufsize, GFP_KERNEL);
+ if (!super->s_je)
+ return ret;
+
+ super->s_compressed_je = kzalloc(bufsize, GFP_KERNEL);
+ if (!super->s_compressed_je)
+ return ret;
+
+ super->s_master_inode = logfs_new_meta_inode(sb, LOGFS_INO_MASTER);
+ if (IS_ERR(super->s_master_inode))
+ return PTR_ERR(super->s_master_inode);
+
+ ret = logfs_read_journal(sb);
+ if (ret)
+ return -EIO;
+
+ reserve_sb_and_journal(sb);
+ logfs_calc_free(sb);
+
+ super->s_journal_area->a_ops = &journal_area_ops;
+ return 0;
+}
+
+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
new file mode 100644
index 00000000000..0a3df1a0c93
--- /dev/null
+++ b/fs/logfs/logfs.h
@@ -0,0 +1,736 @@
+/*
+ * fs/logfs/logfs.h
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ *
+ * Private header for logfs.
+ */
+#ifndef FS_LOGFS_LOGFS_H
+#define FS_LOGFS_LOGFS_H
+
+#undef __CHECK_ENDIAN__
+#define __CHECK_ENDIAN__
+
+#include <linux/btree.h>
+#include <linux/crc32.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/mempool.h>
+#include <linux/pagemap.h>
+#include <linux/mtd/mtd.h>
+#include "logfs_abi.h"
+
+#define LOGFS_DEBUG_SUPER (0x0001)
+#define LOGFS_DEBUG_SEGMENT (0x0002)
+#define LOGFS_DEBUG_JOURNAL (0x0004)
+#define LOGFS_DEBUG_DIR (0x0008)
+#define LOGFS_DEBUG_FILE (0x0010)
+#define LOGFS_DEBUG_INODE (0x0020)
+#define LOGFS_DEBUG_READWRITE (0x0040)
+#define LOGFS_DEBUG_GC (0x0080)
+#define LOGFS_DEBUG_GC_NOISY (0x0100)
+#define LOGFS_DEBUG_ALIASES (0x0200)
+#define LOGFS_DEBUG_BLOCKMOVE (0x0400)
+#define LOGFS_DEBUG_ALL (0xffffffff)
+
+#define LOGFS_DEBUG (0x01)
+/*
+ * To enable specific log messages, simply define LOGFS_DEBUG to match any
+ * or all of the above.
+ */
+#ifndef LOGFS_DEBUG
+#define LOGFS_DEBUG (0)
+#endif
+
+#define log_cond(cond, fmt, arg...) do { \
+ if (cond) \
+ printk(KERN_DEBUG fmt, ##arg); \
+} while (0)
+
+#define log_super(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_SUPER, fmt, ##arg)
+#define log_segment(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_SEGMENT, fmt, ##arg)
+#define log_journal(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_JOURNAL, fmt, ##arg)
+#define log_dir(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_DIR, fmt, ##arg)
+#define log_file(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_FILE, fmt, ##arg)
+#define log_inode(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_INODE, fmt, ##arg)
+#define log_readwrite(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_READWRITE, fmt, ##arg)
+#define log_gc(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_GC, fmt, ##arg)
+#define log_gc_noisy(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_GC_NOISY, fmt, ##arg)
+#define log_aliases(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_ALIASES, fmt, ##arg)
+#define log_blockmove(fmt, arg...) \
+ log_cond(LOGFS_DEBUG & LOGFS_DEBUG_BLOCKMOVE, fmt, ##arg)
+
+#define PG_pre_locked PG_owner_priv_1
+#define PagePreLocked(page) test_bit(PG_pre_locked, &(page)->flags)
+#define SetPagePreLocked(page) set_bit(PG_pre_locked, &(page)->flags)
+#define ClearPagePreLocked(page) clear_bit(PG_pre_locked, &(page)->flags)
+
+/* FIXME: This should really be somewhere in the 64bit area. */
+#define LOGFS_LINK_MAX (1<<30)
+
+/* Read-only filesystem */
+#define LOGFS_SB_FLAG_RO 0x0001
+#define LOGFS_SB_FLAG_DIRTY 0x0002
+#define LOGFS_SB_FLAG_OBJ_ALIAS 0x0004
+#define LOGFS_SB_FLAG_SHUTDOWN 0x0008
+
+/* Write Control Flags */
+#define WF_LOCK 0x01 /* take write lock */
+#define WF_WRITE 0x02 /* write block */
+#define WF_DELETE 0x04 /* delete old block */
+
+typedef u8 __bitwise level_t;
+typedef u8 __bitwise gc_level_t;
+
+#define LEVEL(level) ((__force level_t)(level))
+#define GC_LEVEL(gc_level) ((__force gc_level_t)(gc_level))
+
+#define SUBLEVEL(level) ( (void)((level) == LEVEL(1)), \
+ (__force level_t)((__force u8)(level) - 1) )
+
+/**
+ * struct logfs_area - area management information
+ *
+ * @a_sb: the superblock this area belongs to
+ * @a_is_open: 1 if the area is currently open, else 0
+ * @a_segno: segment number of area
+ * @a_written_bytes: number of bytes already written back
+ * @a_used_bytes: number of used bytes
+ * @a_ops: area operations (either journal or ostore)
+ * @a_erase_count: erase count
+ * @a_level: GC level
+ */
+struct logfs_area { /* a segment open for writing */
+ struct super_block *a_sb;
+ int a_is_open;
+ u32 a_segno;
+ u32 a_written_bytes;
+ u32 a_used_bytes;
+ const struct logfs_area_ops *a_ops;
+ u32 a_erase_count;
+ gc_level_t a_level;
+};
+
+/**
+ * struct logfs_area_ops - area operations
+ *
+ * @get_free_segment: fill area->ofs with the offset of a free segment
+ * @get_erase_count: fill area->erase_count (needs area->ofs)
+ * @erase_segment: erase and setup segment
+ */
+struct logfs_area_ops {
+ void (*get_free_segment)(struct logfs_area *area);
+ void (*get_erase_count)(struct logfs_area *area);
+ int (*erase_segment)(struct logfs_area *area);
+};
+
+/**
+ * struct logfs_device_ops - device access operations
+ *
+ * @readpage: read one page (mm page)
+ * @writeseg: write one segment. may be a partial segment
+ * @erase: erase one segment
+ * @read: read from the device
+ * @erase: erase part of the device
+ */
+struct logfs_device_ops {
+ struct page *(*find_first_sb)(struct super_block *sb, u64 *ofs);
+ struct page *(*find_last_sb)(struct super_block *sb, u64 *ofs);
+ int (*write_sb)(struct super_block *sb, struct page *page);
+ int (*readpage)(void *_sb, struct page *page);
+ void (*writeseg)(struct super_block *sb, u64 ofs, size_t len);
+ int (*erase)(struct super_block *sb, loff_t ofs, size_t len,
+ int ensure_write);
+ void (*sync)(struct super_block *sb);
+ void (*put_device)(struct super_block *sb);
+};
+
+/**
+ * struct candidate_list - list of similar candidates
+ */
+struct candidate_list {
+ struct rb_root rb_tree;
+ int count;
+ int maxcount;
+ int sort_by_ec;
+};
+
+/**
+ * struct gc_candidate - "candidate" segment to be garbage collected next
+ *
+ * @list: list (either free of low)
+ * @segno: segment number
+ * @valid: number of valid bytes
+ * @erase_count: erase count of segment
+ * @dist: distance from tree root
+ *
+ * Candidates can be on two lists. The free list contains electees rather
+ * than candidates - segments that no longer contain any valid data. The
+ * low list contains candidates to be picked for GC. It should be kept
+ * short. It is not required to always pick a perfect candidate. In the
+ * worst case GC will have to move more data than absolutely necessary.
+ */
+struct gc_candidate {
+ struct rb_node rb_node;
+ struct candidate_list *list;
+ u32 segno;
+ u32 valid;
+ u32 erase_count;
+ u8 dist;
+};
+
+/**
+ * struct logfs_journal_entry - temporary structure used during journal scan
+ *
+ * @used:
+ * @version: normalized version
+ * @len: length
+ * @offset: offset
+ */
+struct logfs_journal_entry {
+ int used;
+ s16 version;
+ u16 len;
+ u16 datalen;
+ u64 offset;
+};
+
+enum transaction_state {
+ CREATE_1 = 1,
+ CREATE_2,
+ UNLINK_1,
+ UNLINK_2,
+ CROSS_RENAME_1,
+ CROSS_RENAME_2,
+ TARGET_RENAME_1,
+ TARGET_RENAME_2,
+ TARGET_RENAME_3
+};
+
+/**
+ * struct logfs_transaction - essential fields to support atomic dirops
+ *
+ * @ino: target inode
+ * @dir: inode of directory containing dentry
+ * @pos: pos of dentry in directory
+ */
+struct logfs_transaction {
+ enum transaction_state state;
+ u64 ino;
+ u64 dir;
+ u64 pos;
+};
+
+/**
+ * struct logfs_shadow - old block in the shadow of a not-yet-committed new one
+ * @old_ofs: offset of old block on medium
+ * @new_ofs: offset of new block on medium
+ * @ino: inode number
+ * @bix: block index
+ * @old_len: size of old block, including header
+ * @new_len: size of new block, including header
+ * @level: block level
+ */
+struct logfs_shadow {
+ u64 old_ofs;
+ u64 new_ofs;
+ u64 ino;
+ u64 bix;
+ int old_len;
+ int new_len;
+ gc_level_t gc_level;
+};
+
+/**
+ * struct shadow_tree
+ * @new: shadows where old_ofs==0, indexed by new_ofs
+ * @old: shadows where old_ofs!=0, indexed by old_ofs
+ * @segment_map: bitfield of segments containing shadows
+ * @no_shadowed_segment: number of segments containing shadows
+ */
+struct shadow_tree {
+ struct btree_head64 new;
+ struct btree_head64 old;
+ struct btree_head32 segment_map;
+ int no_shadowed_segments;
+};
+
+struct object_alias_item {
+ struct list_head list;
+ __be64 val;
+ int child_no;
+};
+
+/**
+ * struct logfs_block - contains any block state
+ * @type: indirect block or inode
+ * @full: number of fully populated children
+ * @partial: number of partially populated children
+ *
+ * Most blocks are directly represented by page cache pages. But when a block
+ * becomes dirty, is part of a transaction, contains aliases or is otherwise
+ * special, a struct logfs_block is allocated to track the additional state.
+ * Inodes are very similar to indirect blocks, so they can also get one of
+ * these structures added when appropriate.
+ */
+#define BLOCK_INDIRECT 1 /* Indirect block */
+#define BLOCK_INODE 2 /* Inode */
+struct logfs_block_ops;
+struct logfs_block {
+ struct list_head alias_list;
+ struct list_head item_list;
+ struct super_block *sb;
+ u64 ino;
+ u64 bix;
+ level_t level;
+ struct page *page;
+ struct inode *inode;
+ struct logfs_transaction *ta;
+ unsigned long alias_map[LOGFS_BLOCK_FACTOR / BITS_PER_LONG];
+ struct logfs_block_ops *ops;
+ int full;
+ int partial;
+ int reserved_bytes;
+};
+
+typedef int write_alias_t(struct super_block *sb, u64 ino, u64 bix,
+ level_t level, int child_no, __be64 val);
+struct logfs_block_ops {
+ void (*write_block)(struct logfs_block *block);
+ void (*free_block)(struct super_block *sb, struct logfs_block*block);
+ int (*write_alias)(struct super_block *sb,
+ struct logfs_block *block,
+ write_alias_t *write_one_alias);
+};
+
+#define MAX_JOURNAL_ENTRIES 256
+
+struct logfs_super {
+ struct mtd_info *s_mtd; /* underlying device */
+ struct block_device *s_bdev; /* underlying device */
+ const struct logfs_device_ops *s_devops;/* device access */
+ struct inode *s_master_inode; /* inode file */
+ struct inode *s_segfile_inode; /* segment file */
+ struct inode *s_mapping_inode; /* device mapping */
+ atomic_t s_pending_writes; /* outstanting bios */
+ long s_flags;
+ mempool_t *s_btree_pool; /* for btree nodes */
+ mempool_t *s_alias_pool; /* aliases in segment.c */
+ u64 s_feature_incompat;
+ u64 s_feature_ro_compat;
+ u64 s_feature_compat;
+ u64 s_feature_flags;
+ u64 s_sb_ofs[2];
+ struct page *s_erase_page; /* for dev_bdev.c */
+ /* alias.c fields */
+ struct btree_head32 s_segment_alias; /* remapped segments */
+ int s_no_object_aliases;
+ struct list_head s_object_alias; /* remapped objects */
+ struct btree_head128 s_object_alias_tree; /* remapped objects */
+ struct mutex s_object_alias_mutex;
+ /* dir.c fields */
+ struct mutex s_dirop_mutex; /* for creat/unlink/rename */
+ u64 s_victim_ino; /* used for atomic dir-ops */
+ u64 s_rename_dir; /* source directory ino */
+ u64 s_rename_pos; /* position of source dd */
+ /* gc.c fields */
+ long s_segsize; /* size of a segment */
+ int s_segshift; /* log2 of segment size */
+ long s_segmask; /* 1 << s_segshift - 1 */
+ long s_no_segs; /* segments on device */
+ long s_no_journal_segs; /* segments used for journal */
+ long s_no_blocks; /* blocks per segment */
+ long s_writesize; /* minimum write size */
+ int s_writeshift; /* log2 of write size */
+ u64 s_size; /* filesystem size */
+ struct logfs_area *s_area[LOGFS_NO_AREAS]; /* open segment array */
+ u64 s_gec; /* global erase count */
+ u64 s_wl_gec_ostore; /* time of last wl event */
+ u64 s_wl_gec_journal; /* time of last wl event */
+ u64 s_sweeper; /* current sweeper pos */
+ u8 s_ifile_levels; /* max level of ifile */
+ u8 s_iblock_levels; /* max level of regular files */
+ u8 s_data_levels; /* # of segments to leaf block*/
+ u8 s_total_levels; /* sum of above three */
+ struct btree_head32 s_cand_tree; /* all candidates */
+ struct candidate_list s_free_list; /* 100% free segments */
+ struct candidate_list s_reserve_list; /* Bad segment reserve */
+ struct candidate_list s_low_list[LOGFS_NO_AREAS];/* good candidates */
+ struct candidate_list s_ec_list; /* wear level candidates */
+ struct btree_head32 s_reserved_segments;/* sb, journal, bad, etc. */
+ /* inode.c fields */
+ u64 s_last_ino; /* highest ino used */
+ long s_inos_till_wrap;
+ u32 s_generation; /* i_generation for new files */
+ struct list_head s_freeing_list; /* inodes being freed */
+ /* journal.c fields */
+ struct mutex s_journal_mutex;
+ void *s_je; /* journal entry to compress */
+ void *s_compressed_je; /* block to write to journal */
+ u32 s_journal_seg[LOGFS_JOURNAL_SEGS]; /* journal segments */
+ u32 s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */
+ u64 s_last_version;
+ struct logfs_area *s_journal_area; /* open journal segment */
+ __be64 s_je_array[MAX_JOURNAL_ENTRIES];
+ int s_no_je;
+
+ int s_sum_index; /* for the 12 summaries */
+ struct shadow_tree s_shadow_tree;
+ int s_je_fill; /* index of current je */
+ /* readwrite.c fields */
+ struct mutex s_write_mutex;
+ int s_lock_count;
+ mempool_t *s_block_pool; /* struct logfs_block pool */
+ mempool_t *s_shadow_pool; /* struct logfs_shadow pool */
+ /*
+ * Space accounting:
+ * - s_used_bytes specifies space used to store valid data objects.
+ * - s_dirty_used_bytes is space used to store non-committed data
+ * objects. Those objects have already been written themselves,
+ * but they don't become valid until all indirect blocks up to the
+ * journal have been written as well.
+ * - s_dirty_free_bytes is space used to store the old copy of a
+ * replaced object, as long as the replacement is non-committed.
+ * In other words, it is the amount of space freed when all dirty
+ * blocks are written back.
+ * - s_free_bytes is the amount of free space available for any
+ * purpose.
+ * - s_root_reserve is the amount of free space available only to
+ * the root user. Non-privileged users can no longer write once
+ * this watermark has been reached.
+ * - s_speed_reserve is space which remains unused to speed up
+ * garbage collection performance.
+ * - s_dirty_pages is the space reserved for currently dirty pages.
+ * It is a pessimistic estimate, so some/most will get freed on
+ * page writeback.
+ *
+ * s_used_bytes + s_free_bytes + s_speed_reserve = total usable size
+ */
+ u64 s_free_bytes;
+ u64 s_used_bytes;
+ u64 s_dirty_free_bytes;
+ u64 s_dirty_used_bytes;
+ u64 s_root_reserve;
+ u64 s_speed_reserve;
+ u64 s_dirty_pages;
+ /* Bad block handling:
+ * - s_bad_seg_reserve is a number of segments usually kept
+ * free. When encountering bad blocks, the affected segment's data
+ * is _temporarily_ moved to a reserved segment.
+ * - s_bad_segments is the number of known bad segments.
+ */
+ u32 s_bad_seg_reserve;
+ u32 s_bad_segments;
+};
+
+/**
+ * struct logfs_inode - in-memory inode
+ *
+ * @vfs_inode: struct inode
+ * @li_data: data pointers
+ * @li_used_bytes: number of used bytes
+ * @li_freeing_list: used to track inodes currently being freed
+ * @li_flags: inode flags
+ * @li_refcount: number of internal (GC-induced) references
+ */
+struct logfs_inode {
+ struct inode vfs_inode;
+ u64 li_data[LOGFS_EMBEDDED_FIELDS];
+ u64 li_used_bytes;
+ struct list_head li_freeing_list;
+ struct logfs_block *li_block;
+ u32 li_flags;
+ u8 li_height;
+ int li_refcount;
+};
+
+#define journal_for_each(__i) for (__i = 0; __i < LOGFS_JOURNAL_SEGS; __i++)
+#define for_each_area(__i) for (__i = 0; __i < LOGFS_NO_AREAS; __i++)
+#define for_each_area_down(__i) for (__i = LOGFS_NO_AREAS - 1; __i >= 0; __i--)
+
+/* compr.c */
+int logfs_compress(void *in, void *out, size_t inlen, size_t outlen);
+int logfs_uncompress(void *in, void *out, size_t inlen, size_t outlen);
+int __init logfs_compr_init(void);
+void logfs_compr_exit(void);
+
+/* dev_bdev.c */
+#ifdef CONFIG_BLOCK
+int logfs_get_sb_bdev(struct file_system_type *type, int flags,
+ const char *devname, struct vfsmount *mnt);
+#else
+static inline int logfs_get_sb_bdev(struct file_system_type *type, int flags,
+ const char *devname, struct vfsmount *mnt)
+{
+ return -ENODEV;
+}
+#endif
+
+/* dev_mtd.c */
+#ifdef CONFIG_MTD
+int logfs_get_sb_mtd(struct file_system_type *type, int flags,
+ int mtdnr, struct vfsmount *mnt);
+#else
+static inline int logfs_get_sb_mtd(struct file_system_type *type, int flags,
+ int mtdnr, struct vfsmount *mnt)
+{
+ return -ENODEV;
+}
+#endif
+
+/* dir.c */
+extern const struct inode_operations logfs_symlink_iops;
+extern const struct inode_operations logfs_dir_iops;
+extern const struct file_operations logfs_dir_fops;
+int logfs_replay_journal(struct super_block *sb);
+
+/* file.c */
+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);
+int logfs_fsync(struct file *file, struct dentry *dentry, int datasync);
+
+/* gc.c */
+u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec);
+void logfs_gc_pass(struct super_block *sb);
+int logfs_check_areas(struct super_block *sb);
+int logfs_init_gc(struct super_block *sb);
+void logfs_cleanup_gc(struct super_block *sb);
+
+/* inode.c */
+extern const struct super_operations logfs_super_operations;
+struct inode *logfs_iget(struct super_block *sb, ino_t ino);
+struct inode *logfs_safe_iget(struct super_block *sb, ino_t ino, int *cookie);
+void logfs_safe_iput(struct inode *inode, int cookie);
+struct inode *logfs_new_inode(struct inode *dir, int mode);
+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);
+
+/* journal.c */
+void logfs_write_anchor(struct super_block *sb);
+int logfs_init_journal(struct super_block *sb);
+void logfs_cleanup_journal(struct super_block *sb);
+int write_alias_journal(struct super_block *sb, u64 ino, u64 bix,
+ level_t level, int child_no, __be64 val);
+void do_logfs_journal_wl_pass(struct super_block *sb);
+
+/* readwrite.c */
+pgoff_t logfs_pack_index(u64 bix, level_t level);
+void logfs_unpack_index(pgoff_t index, u64 *bix, level_t *level);
+int logfs_inode_write(struct inode *inode, const void *buf, size_t count,
+ loff_t bix, long flags, struct shadow_tree *shadow_tree);
+int logfs_readpage_nolock(struct page *page);
+int logfs_write_buf(struct inode *inode, struct page *page, long flags);
+int logfs_delete(struct inode *inode, pgoff_t index,
+ struct shadow_tree *shadow_tree);
+int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
+ gc_level_t gc_level, long flags);
+int logfs_is_valid_block(struct super_block *sb, u64 ofs, u64 ino, u64 bix,
+ gc_level_t gc_level);
+int logfs_truncate(struct inode *inode, u64 size);
+u64 logfs_seek_hole(struct inode *inode, u64 bix);
+u64 logfs_seek_data(struct inode *inode, u64 bix);
+int logfs_open_segfile(struct super_block *sb);
+int logfs_init_rw(struct super_block *sb);
+void logfs_cleanup_rw(struct super_block *sb);
+void logfs_add_transaction(struct inode *inode, struct logfs_transaction *ta);
+void logfs_del_transaction(struct inode *inode, struct logfs_transaction *ta);
+void logfs_write_block(struct logfs_block *block, long flags);
+int logfs_write_obj_aliases_pagecache(struct super_block *sb);
+void logfs_get_segment_entry(struct super_block *sb, u32 segno,
+ struct logfs_segment_entry *se);
+void logfs_set_segment_used(struct super_block *sb, u64 ofs, int increment);
+void logfs_set_segment_erased(struct super_block *sb, u32 segno, u32 ec,
+ gc_level_t gc_level);
+void logfs_set_segment_reserved(struct super_block *sb, u32 segno);
+void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec);
+struct logfs_block *__alloc_block(struct super_block *sb,
+ u64 ino, u64 bix, level_t level);
+void __free_block(struct super_block *sb, struct logfs_block *block);
+void btree_write_block(struct logfs_block *block);
+void initialize_block_counters(struct page *page, struct logfs_block *block,
+ __be64 *array, int page_is_empty);
+int logfs_exist_block(struct inode *inode, u64 bix);
+int get_page_reserve(struct inode *inode, struct page *page);
+extern struct logfs_block_ops indirect_block_ops;
+
+/* segment.c */
+int logfs_erase_segment(struct super_block *sb, u32 ofs, int ensure_erase);
+int wbuf_read(struct super_block *sb, u64 ofs, size_t len, void *buf);
+int logfs_segment_read(struct inode *inode, struct page *page, u64 ofs, u64 bix,
+ level_t level);
+int logfs_segment_write(struct inode *inode, struct page *page,
+ struct logfs_shadow *shadow);
+int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow);
+int logfs_load_object_aliases(struct super_block *sb,
+ struct logfs_obj_alias *oa, int count);
+void move_page_to_btree(struct page *page);
+int logfs_init_mapping(struct super_block *sb);
+void logfs_sync_area(struct logfs_area *area);
+void logfs_sync_segments(struct super_block *sb);
+void freeseg(struct super_block *sb, u32 segno);
+
+/* area handling */
+int logfs_init_areas(struct super_block *sb);
+void logfs_cleanup_areas(struct super_block *sb);
+int logfs_open_area(struct logfs_area *area, size_t bytes);
+void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
+ int use_filler);
+
+static inline void logfs_buf_write(struct logfs_area *area, u64 ofs,
+ void *buf, size_t len)
+{
+ __logfs_buf_write(area, ofs, buf, len, 0);
+}
+
+static inline void logfs_buf_recover(struct logfs_area *area, u64 ofs,
+ void *buf, size_t len)
+{
+ __logfs_buf_write(area, ofs, buf, len, 1);
+}
+
+/* super.c */
+struct page *emergency_read_begin(struct address_space *mapping, pgoff_t index);
+void emergency_read_end(struct page *page);
+void logfs_crash_dump(struct super_block *sb);
+void *memchr_inv(const void *s, int c, size_t n);
+int logfs_statfs(struct dentry *dentry, struct kstatfs *stats);
+int logfs_get_sb_device(struct file_system_type *type, int flags,
+ struct mtd_info *mtd, struct block_device *bdev,
+ const struct logfs_device_ops *devops, struct vfsmount *mnt);
+int logfs_check_ds(struct logfs_disk_super *ds);
+int logfs_write_sb(struct super_block *sb);
+
+static inline struct logfs_super *logfs_super(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+static inline struct logfs_inode *logfs_inode(struct inode *inode)
+{
+ return container_of(inode, struct logfs_inode, vfs_inode);
+}
+
+static inline void logfs_set_ro(struct super_block *sb)
+{
+ logfs_super(sb)->s_flags |= LOGFS_SB_FLAG_RO;
+}
+
+#define LOGFS_BUG(sb) do { \
+ struct super_block *__sb = sb; \
+ logfs_crash_dump(__sb); \
+ logfs_super(__sb)->s_flags |= LOGFS_SB_FLAG_RO; \
+ BUG(); \
+} while (0)
+
+#define LOGFS_BUG_ON(condition, sb) \
+ do { if (unlikely(condition)) LOGFS_BUG((sb)); } while (0)
+
+static inline __be32 logfs_crc32(void *data, size_t len, size_t skip)
+{
+ return cpu_to_be32(crc32(~0, data+skip, len-skip));
+}
+
+static inline u8 logfs_type(struct inode *inode)
+{
+ return (inode->i_mode >> 12) & 15;
+}
+
+static inline pgoff_t logfs_index(struct super_block *sb, u64 pos)
+{
+ return pos >> sb->s_blocksize_bits;
+}
+
+static inline u64 dev_ofs(struct super_block *sb, u32 segno, u32 ofs)
+{
+ return ((u64)segno << logfs_super(sb)->s_segshift) + ofs;
+}
+
+static inline u32 seg_no(struct super_block *sb, u64 ofs)
+{
+ return ofs >> logfs_super(sb)->s_segshift;
+}
+
+static inline u32 seg_ofs(struct super_block *sb, u64 ofs)
+{
+ return ofs & logfs_super(sb)->s_segmask;
+}
+
+static inline u64 seg_align(struct super_block *sb, u64 ofs)
+{
+ return ofs & ~logfs_super(sb)->s_segmask;
+}
+
+static inline struct logfs_block *logfs_block(struct page *page)
+{
+ return (void *)page->private;
+}
+
+static inline level_t shrink_level(gc_level_t __level)
+{
+ u8 level = (__force u8)__level;
+
+ if (level >= LOGFS_MAX_LEVELS)
+ level -= LOGFS_MAX_LEVELS;
+ return (__force level_t)level;
+}
+
+static inline gc_level_t expand_level(u64 ino, level_t __level)
+{
+ u8 level = (__force u8)__level;
+
+ if (ino == LOGFS_INO_MASTER) {
+ /* ifile has seperate areas */
+ level += LOGFS_MAX_LEVELS;
+ }
+ return (__force gc_level_t)level;
+}
+
+static inline int logfs_block_shift(struct super_block *sb, level_t level)
+{
+ level = shrink_level((__force gc_level_t)level);
+ return (__force int)level * (sb->s_blocksize_bits - 3);
+}
+
+static inline u64 logfs_block_mask(struct super_block *sb, level_t level)
+{
+ return ~0ull << logfs_block_shift(sb, level);
+}
+
+static inline struct logfs_area *get_area(struct super_block *sb,
+ gc_level_t gc_level)
+{
+ return logfs_super(sb)->s_area[(__force u8)gc_level];
+}
+
+static inline void logfs_mempool_destroy(mempool_t *pool)
+{
+ if (pool)
+ mempool_destroy(pool);
+}
+
+#endif
diff --git a/fs/logfs/logfs_abi.h b/fs/logfs/logfs_abi.h
new file mode 100644
index 00000000000..f674725663f
--- /dev/null
+++ b/fs/logfs/logfs_abi.h
@@ -0,0 +1,629 @@
+/*
+ * fs/logfs/logfs_abi.h
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ *
+ * Public header for logfs.
+ */
+#ifndef FS_LOGFS_LOGFS_ABI_H
+#define FS_LOGFS_LOGFS_ABI_H
+
+/* For out-of-kernel compiles */
+#ifndef BUILD_BUG_ON
+#define BUILD_BUG_ON(condition) /**/
+#endif
+
+#define SIZE_CHECK(type, size) \
+static inline void check_##type(void) \
+{ \
+ BUILD_BUG_ON(sizeof(struct type) != (size)); \
+}
+
+/*
+ * Throughout the logfs code, we're constantly dealing with blocks at
+ * various positions or offsets. To remove confusion, we stricly
+ * distinguish between a "position" - the logical position within a
+ * file and an "offset" - the physical location within the device.
+ *
+ * Any usage of the term offset for a logical location or position for
+ * a physical one is a bug and should get fixed.
+ */
+
+/*
+ * Block are allocated in one of several segments depending on their
+ * level. The following levels are used:
+ * 0 - regular data block
+ * 1 - i1 indirect blocks
+ * 2 - i2 indirect blocks
+ * 3 - i3 indirect blocks
+ * 4 - i4 indirect blocks
+ * 5 - i5 indirect blocks
+ * 6 - ifile data blocks
+ * 7 - ifile i1 indirect blocks
+ * 8 - ifile i2 indirect blocks
+ * 9 - ifile i3 indirect blocks
+ * 10 - ifile i4 indirect blocks
+ * 11 - ifile i5 indirect blocks
+ * Potential levels to be used in the future:
+ * 12 - gc recycled blocks, long-lived data
+ * 13 - replacement blocks, short-lived data
+ *
+ * Levels 1-11 are necessary for robust gc operations and help seperate
+ * short-lived metadata from longer-lived file data. In the future,
+ * file data should get seperated into several segments based on simple
+ * heuristics. Old data recycled during gc operation is expected to be
+ * long-lived. New data is of uncertain life expectancy. New data
+ * used to replace older blocks in existing files is expected to be
+ * short-lived.
+ */
+
+
+/* Magic numbers. 64bit for superblock, 32bit for statfs f_type */
+#define LOGFS_MAGIC 0x7a3a8e5cb9d5bf67ull
+#define LOGFS_MAGIC_U32 0xc97e8168u
+
+/*
+ * Various blocksize related macros. Blocksize is currently fixed at 4KiB.
+ * Sooner or later that should become configurable and the macros replaced
+ * by something superblock-dependent. Pointers in indirect blocks are and
+ * will remain 64bit.
+ *
+ * LOGFS_BLOCKSIZE - self-explaining
+ * LOGFS_BLOCK_FACTOR - number of pointers per indirect block
+ * LOGFS_BLOCK_BITS - log2 of LOGFS_BLOCK_FACTOR, used for shifts
+ */
+#define LOGFS_BLOCKSIZE (4096ull)
+#define LOGFS_BLOCK_FACTOR (LOGFS_BLOCKSIZE / sizeof(u64))
+#define LOGFS_BLOCK_BITS (9)
+
+/*
+ * Number of blocks at various levels of indirection. There are 16 direct
+ * block pointers plus a single indirect pointer.
+ */
+#define I0_BLOCKS (16)
+#define I1_BLOCKS LOGFS_BLOCK_FACTOR
+#define I2_BLOCKS (LOGFS_BLOCK_FACTOR * I1_BLOCKS)
+#define I3_BLOCKS (LOGFS_BLOCK_FACTOR * I2_BLOCKS)
+#define I4_BLOCKS (LOGFS_BLOCK_FACTOR * I3_BLOCKS)
+#define I5_BLOCKS (LOGFS_BLOCK_FACTOR * I4_BLOCKS)
+
+#define INDIRECT_INDEX I0_BLOCKS
+#define LOGFS_EMBEDDED_FIELDS (I0_BLOCKS + 1)
+
+/*
+ * Sizes at which files require another level of indirection. Files smaller
+ * than LOGFS_EMBEDDED_SIZE can be completely stored in the inode itself,
+ * similar like ext2 fast symlinks.
+ *
+ * Data at a position smaller than LOGFS_I0_SIZE is accessed through the
+ * direct pointers, else through the 1x indirect pointer and so forth.
+ */
+#define LOGFS_EMBEDDED_SIZE (LOGFS_EMBEDDED_FIELDS * sizeof(u64))
+#define LOGFS_I0_SIZE (I0_BLOCKS * LOGFS_BLOCKSIZE)
+#define LOGFS_I1_SIZE (I1_BLOCKS * LOGFS_BLOCKSIZE)
+#define LOGFS_I2_SIZE (I2_BLOCKS * LOGFS_BLOCKSIZE)
+#define LOGFS_I3_SIZE (I3_BLOCKS * LOGFS_BLOCKSIZE)
+#define LOGFS_I4_SIZE (I4_BLOCKS * LOGFS_BLOCKSIZE)
+#define LOGFS_I5_SIZE (I5_BLOCKS * LOGFS_BLOCKSIZE)
+
+/*
+ * Each indirect block pointer must have this flag set, if all block pointers
+ * behind it are set, i.e. there is no hole hidden in the shadow of this
+ * indirect block pointer.
+ */
+#define LOGFS_FULLY_POPULATED (1ULL << 63)
+#define pure_ofs(ofs) (ofs & ~LOGFS_FULLY_POPULATED)
+
+/*
+ * LogFS needs to seperate data into levels. Each level is defined as the
+ * maximal possible distance from the master inode (inode of the inode file).
+ * Data blocks reside on level 0, 1x indirect block on level 1, etc.
+ * Inodes reside on level 6, indirect blocks for the inode file on levels 7-11.
+ * This effort is necessary to guarantee garbage collection to always make
+ * progress.
+ *
+ * LOGFS_MAX_INDIRECT is the maximal indirection through indirect blocks,
+ * LOGFS_MAX_LEVELS is one more for the actual data level of a file. It is
+ * the maximal number of levels for one file.
+ * LOGFS_NO_AREAS is twice that, as the inode file and regular files are
+ * effectively stacked on top of each other.
+ */
+#define LOGFS_MAX_INDIRECT (5)
+#define LOGFS_MAX_LEVELS (LOGFS_MAX_INDIRECT + 1)
+#define LOGFS_NO_AREAS (2 * LOGFS_MAX_LEVELS)
+
+/* Maximum size of filenames */
+#define LOGFS_MAX_NAMELEN (255)
+
+/* Number of segments in the primary journal. */
+#define LOGFS_JOURNAL_SEGS (16)
+
+/* Maximum number of free/erased/etc. segments in journal entries */
+#define MAX_CACHED_SEGS (64)
+
+
+/*
+ * LOGFS_OBJECT_HEADERSIZE is the size of a single header in the object store,
+ * LOGFS_MAX_OBJECTSIZE the size of the largest possible object, including
+ * its header,
+ * LOGFS_SEGMENT_RESERVE is the amount of space reserved for each segment for
+ * its segment header and the padded space at the end when no further objects
+ * fit.
+ */
+#define LOGFS_OBJECT_HEADERSIZE (0x1c)
+#define LOGFS_SEGMENT_HEADERSIZE (0x18)
+#define LOGFS_MAX_OBJECTSIZE (LOGFS_OBJECT_HEADERSIZE + LOGFS_BLOCKSIZE)
+#define LOGFS_SEGMENT_RESERVE \
+ (LOGFS_SEGMENT_HEADERSIZE + LOGFS_MAX_OBJECTSIZE - 1)
+
+/*
+ * Segment types:
+ * SEG_SUPER - Data or indirect block
+ * SEG_JOURNAL - Inode
+ * SEG_OSTORE - Dentry
+ */
+enum {
+ SEG_SUPER = 0x01,
+ SEG_JOURNAL = 0x02,
+ SEG_OSTORE = 0x03,
+};
+
+/**
+ * struct logfs_segment_header - per-segment header in the ostore
+ *
+ * @crc: crc32 of header (there is no data)
+ * @pad: unused, must be 0
+ * @type: segment type, see above
+ * @level: GC level for all objects in this segment
+ * @segno: segment number
+ * @ec: erase count for this segment
+ * @gec: global erase count at time of writing
+ */
+struct logfs_segment_header {
+ __be32 crc;
+ __be16 pad;
+ __u8 type;
+ __u8 level;
+ __be32 segno;
+ __be32 ec;
+ __be64 gec;
+};
+
+SIZE_CHECK(logfs_segment_header, LOGFS_SEGMENT_HEADERSIZE);
+
+#define LOGFS_FEATURES_INCOMPAT (0ull)
+#define LOGFS_FEATURES_RO_COMPAT (0ull)
+#define LOGFS_FEATURES_COMPAT (0ull)
+
+/**
+ * struct logfs_disk_super - on-medium superblock
+ *
+ * @ds_magic: magic number, must equal LOGFS_MAGIC
+ * @ds_crc: crc32 of structure starting with the next field
+ * @ds_ifile_levels: maximum number of levels for ifile
+ * @ds_iblock_levels: maximum number of levels for regular files
+ * @ds_data_levels: number of seperate levels for data
+ * @pad0: reserved, must be 0
+ * @ds_feature_incompat: incompatible filesystem features
+ * @ds_feature_ro_compat: read-only compatible filesystem features
+ * @ds_feature_compat: compatible filesystem features
+ * @ds_flags: flags
+ * @ds_segment_shift: log2 of segment size
+ * @ds_block_shift: log2 of block size
+ * @ds_write_shift: log2 of write size
+ * @pad1: reserved, must be 0
+ * @ds_journal_seg: segments used by primary journal
+ * @ds_root_reserve: bytes reserved for the superuser
+ * @ds_speed_reserve: bytes reserved to speed up GC
+ * @ds_bad_seg_reserve: number of segments reserved to handle bad blocks
+ * @pad2: reserved, must be 0
+ * @pad3: reserved, must be 0
+ *
+ * Contains only read-only fields. Read-write fields like the amount of used
+ * space is tracked in the dynamic superblock, which is stored in the journal.
+ */
+struct logfs_disk_super {
+ struct logfs_segment_header ds_sh;
+ __be64 ds_magic;
+
+ __be32 ds_crc;
+ __u8 ds_ifile_levels;
+ __u8 ds_iblock_levels;
+ __u8 ds_data_levels;
+ __u8 ds_segment_shift;
+ __u8 ds_block_shift;
+ __u8 ds_write_shift;
+ __u8 pad0[6];
+
+ __be64 ds_filesystem_size;
+ __be32 ds_segment_size;
+ __be32 ds_bad_seg_reserve;
+
+ __be64 ds_feature_incompat;
+ __be64 ds_feature_ro_compat;
+
+ __be64 ds_feature_compat;
+ __be64 ds_feature_flags;
+
+ __be64 ds_root_reserve;
+ __be64 ds_speed_reserve;
+
+ __be32 ds_journal_seg[LOGFS_JOURNAL_SEGS];
+
+ __be64 ds_super_ofs[2];
+ __be64 pad3[8];
+};
+
+SIZE_CHECK(logfs_disk_super, 256);
+
+/*
+ * Object types:
+ * OBJ_BLOCK - Data or indirect block
+ * OBJ_INODE - Inode
+ * OBJ_DENTRY - Dentry
+ */
+enum {
+ OBJ_BLOCK = 0x04,
+ OBJ_INODE = 0x05,
+ OBJ_DENTRY = 0x06,
+};
+
+/**
+ * struct logfs_object_header - per-object header in the ostore
+ *
+ * @crc: crc32 of header, excluding data_crc
+ * @len: length of data
+ * @type: object type, see above
+ * @compr: compression type
+ * @ino: inode number
+ * @bix: block index
+ * @data_crc: crc32 of payload
+ */
+struct logfs_object_header {
+ __be32 crc;
+ __be16 len;
+ __u8 type;
+ __u8 compr;
+ __be64 ino;
+ __be64 bix;
+ __be32 data_crc;
+} __attribute__((packed));
+
+SIZE_CHECK(logfs_object_header, LOGFS_OBJECT_HEADERSIZE);
+
+/*
+ * Reserved inode numbers:
+ * LOGFS_INO_MASTER - master inode (for inode file)
+ * LOGFS_INO_ROOT - root directory
+ * LOGFS_INO_SEGFILE - per-segment used bytes and erase count
+ */
+enum {
+ LOGFS_INO_MAPPING = 0x00,
+ LOGFS_INO_MASTER = 0x01,
+ LOGFS_INO_ROOT = 0x02,
+ LOGFS_INO_SEGFILE = 0x03,
+ LOGFS_RESERVED_INOS = 0x10,
+};
+
+/*
+ * Inode flags. High bits should never be written to the medium. They are
+ * reserved for in-memory usage.
+ * Low bits should either remain in sync with the corresponding FS_*_FL or
+ * reuse slots that obviously don't make sense for logfs.
+ *
+ * LOGFS_IF_DIRTY Inode must be written back
+ * LOGFS_IF_ZOMBIE Inode has been deleted
+ * LOGFS_IF_STILLBORN -ENOSPC happened when creating inode
+ */
+#define LOGFS_IF_COMPRESSED 0x00000004 /* == FS_COMPR_FL */
+#define LOGFS_IF_DIRTY 0x20000000
+#define LOGFS_IF_ZOMBIE 0x40000000
+#define LOGFS_IF_STILLBORN 0x80000000
+
+/* Flags available to chattr */
+#define LOGFS_FL_USER_VISIBLE (LOGFS_IF_COMPRESSED)
+#define LOGFS_FL_USER_MODIFIABLE (LOGFS_IF_COMPRESSED)
+/* Flags inherited from parent directory on file/directory creation */
+#define LOGFS_FL_INHERITED (LOGFS_IF_COMPRESSED)
+
+/**
+ * struct logfs_disk_inode - on-medium inode
+ *
+ * @di_mode: file mode
+ * @di_pad: reserved, must be 0
+ * @di_flags: inode flags, see above
+ * @di_uid: user id
+ * @di_gid: group id
+ * @di_ctime: change time
+ * @di_mtime: modify time
+ * @di_refcount: reference count (aka nlink or link count)
+ * @di_generation: inode generation, for nfs
+ * @di_used_bytes: number of bytes used
+ * @di_size: file size
+ * @di_data: data pointers
+ */
+struct logfs_disk_inode {
+ __be16 di_mode;
+ __u8 di_height;
+ __u8 di_pad;
+ __be32 di_flags;
+ __be32 di_uid;
+ __be32 di_gid;
+
+ __be64 di_ctime;
+ __be64 di_mtime;
+
+ __be64 di_atime;
+ __be32 di_refcount;
+ __be32 di_generation;
+
+ __be64 di_used_bytes;
+ __be64 di_size;
+
+ __be64 di_data[LOGFS_EMBEDDED_FIELDS];
+};
+
+SIZE_CHECK(logfs_disk_inode, 200);
+
+#define INODE_POINTER_OFS \
+ (offsetof(struct logfs_disk_inode, di_data) / sizeof(__be64))
+#define INODE_USED_OFS \
+ (offsetof(struct logfs_disk_inode, di_used_bytes) / sizeof(__be64))
+#define INODE_SIZE_OFS \
+ (offsetof(struct logfs_disk_inode, di_size) / sizeof(__be64))
+#define INODE_HEIGHT_OFS (0)
+
+/**
+ * struct logfs_disk_dentry - on-medium dentry structure
+ *
+ * @ino: inode number
+ * @namelen: length of file name
+ * @type: file type, identical to bits 12..15 of mode
+ * @name: file name
+ */
+/* FIXME: add 6 bytes of padding to remove the __packed */
+struct logfs_disk_dentry {
+ __be64 ino;
+ __be16 namelen;
+ __u8 type;
+ __u8 name[LOGFS_MAX_NAMELEN];
+} __attribute__((packed));
+
+SIZE_CHECK(logfs_disk_dentry, 266);
+
+#define RESERVED 0xffffffff
+#define BADSEG 0xffffffff
+/**
+ * struct logfs_segment_entry - segment file entry
+ *
+ * @ec_level: erase count and level
+ * @valid: number of valid bytes
+ *
+ * Segment file contains one entry for every segment. ec_level contains the
+ * erasecount in the upper 28 bits and the level in the lower 4 bits. An
+ * ec_level of BADSEG (-1) identifies bad segments. valid contains the number
+ * of valid bytes or RESERVED (-1 again) if the segment is used for either the
+ * superblock or the journal, or when the segment is bad.
+ */
+struct logfs_segment_entry {
+ __be32 ec_level;
+ __be32 valid;
+};
+
+SIZE_CHECK(logfs_segment_entry, 8);
+
+/**
+ * struct logfs_journal_header - header for journal entries (JEs)
+ *
+ * @h_crc: crc32 of journal entry
+ * @h_len: length of compressed journal entry,
+ * not including header
+ * @h_datalen: length of uncompressed data
+ * @h_type: JE type
+ * @h_compr: compression type
+ * @h_pad: reserved
+ */
+struct logfs_journal_header {
+ __be32 h_crc;
+ __be16 h_len;
+ __be16 h_datalen;
+ __be16 h_type;
+ __u8 h_compr;
+ __u8 h_pad[5];
+};
+
+SIZE_CHECK(logfs_journal_header, 16);
+
+/*
+ * Life expectency of data.
+ * VIM_DEFAULT - default vim
+ * VIM_SEGFILE - for segment file only - very short-living
+ * VIM_GC - GC'd data - likely long-living
+ */
+enum logfs_vim {
+ VIM_DEFAULT = 0,
+ VIM_SEGFILE = 1,
+};
+
+/**
+ * struct logfs_je_area - wbuf header
+ *
+ * @segno: segment number of area
+ * @used_bytes: number of bytes already used
+ * @gc_level: GC level
+ * @vim: life expectancy of data
+ *
+ * "Areas" are segments currently being used for writing. There is at least
+ * one area per GC level. Several may be used to seperate long-living from
+ * short-living data. If an area with unknown vim is encountered, it can
+ * simply be closed.
+ * The write buffer immediately follow this header.
+ */
+struct logfs_je_area {
+ __be32 segno;
+ __be32 used_bytes;
+ __u8 gc_level;
+ __u8 vim;
+} __attribute__((packed));
+
+SIZE_CHECK(logfs_je_area, 10);
+
+#define MAX_JOURNAL_HEADER \
+ (sizeof(struct logfs_journal_header) + sizeof(struct logfs_je_area))
+
+/**
+ * struct logfs_je_dynsb - dynamic superblock
+ *
+ * @ds_gec: global erase count
+ * @ds_sweeper: current position of GC "sweeper"
+ * @ds_rename_dir: source directory ino (see dir.c documentation)
+ * @ds_rename_pos: position of source dd (see dir.c documentation)
+ * @ds_victim_ino: victims of incomplete dir operation (see dir.c)
+ * @ds_victim_ino: parent inode of victim (see dir.c)
+ * @ds_used_bytes: number of used bytes
+ */
+struct logfs_je_dynsb {
+ __be64 ds_gec;
+ __be64 ds_sweeper;
+
+ __be64 ds_rename_dir;
+ __be64 ds_rename_pos;
+
+ __be64 ds_victim_ino;
+ __be64 ds_victim_parent; /* XXX */
+
+ __be64 ds_used_bytes;
+ __be32 ds_generation;
+ __be32 pad;
+};
+
+SIZE_CHECK(logfs_je_dynsb, 64);
+
+/**
+ * struct logfs_je_anchor - anchor of filesystem tree, aka master inode
+ *
+ * @da_size: size of inode file
+ * @da_last_ino: last created inode
+ * @da_used_bytes: number of bytes used
+ * @da_data: data pointers
+ */
+struct logfs_je_anchor {
+ __be64 da_size;
+ __be64 da_last_ino;
+
+ __be64 da_used_bytes;
+ u8 da_height;
+ u8 pad[7];
+
+ __be64 da_data[LOGFS_EMBEDDED_FIELDS];
+};
+
+SIZE_CHECK(logfs_je_anchor, 168);
+
+/**
+ * struct logfs_je_spillout - spillout entry (from 1st to 2nd journal)
+ *
+ * @so_segment: segments used for 2nd journal
+ *
+ * Length of the array is given by h_len field in the header.
+ */
+struct logfs_je_spillout {
+ __be64 so_segment[0];
+};
+
+SIZE_CHECK(logfs_je_spillout, 0);
+
+/**
+ * struct logfs_je_journal_ec - erase counts for all journal segments
+ *
+ * @ec: erase count
+ *
+ * Length of the array is given by h_len field in the header.
+ */
+struct logfs_je_journal_ec {
+ __be32 ec[0];
+};
+
+SIZE_CHECK(logfs_je_journal_ec, 0);
+
+/**
+ * struct logfs_je_free_segments - list of free segmetns with erase count
+ */
+struct logfs_je_free_segments {
+ __be32 segno;
+ __be32 ec;
+};
+
+SIZE_CHECK(logfs_je_free_segments, 8);
+
+/**
+ * struct logfs_seg_alias - list of segment aliases
+ */
+struct logfs_seg_alias {
+ __be32 old_segno;
+ __be32 new_segno;
+};
+
+SIZE_CHECK(logfs_seg_alias, 8);
+
+/**
+ * struct logfs_obj_alias - list of object aliases
+ */
+struct logfs_obj_alias {
+ __be64 ino;
+ __be64 bix;
+ __be64 val;
+ u8 level;
+ u8 pad[5];
+ __be16 child_no;
+};
+
+SIZE_CHECK(logfs_obj_alias, 32);
+
+/**
+ * Compression types.
+ *
+ * COMPR_NONE - uncompressed
+ * COMPR_ZLIB - compressed with zlib
+ */
+enum {
+ COMPR_NONE = 0,
+ COMPR_ZLIB = 1,
+};
+
+/*
+ * Journal entries come in groups of 16. First group contains unique
+ * entries, next groups contain one entry per level
+ *
+ * JE_FIRST - smallest possible journal entry number
+ *
+ * JEG_BASE - base group, containing unique entries
+ * JE_COMMIT - commit entry, validates all previous entries
+ * JE_DYNSB - dynamic superblock, anything that ought to be in the
+ * superblock but cannot because it is read-write data
+ * JE_ANCHOR - anchor aka master inode aka inode file's inode
+ * JE_ERASECOUNT erasecounts for all journal segments
+ * JE_SPILLOUT - unused
+ * JE_SEG_ALIAS - aliases segments
+ * JE_AREA - area description
+ *
+ * JE_LAST - largest possible journal entry number
+ */
+enum {
+ JE_FIRST = 0x01,
+
+ JEG_BASE = 0x00,
+ JE_COMMIT = 0x02,
+ JE_DYNSB = 0x03,
+ JE_ANCHOR = 0x04,
+ JE_ERASECOUNT = 0x05,
+ JE_SPILLOUT = 0x06,
+ JE_OBJ_ALIAS = 0x0d,
+ JE_AREA = 0x0e,
+
+ JE_LAST = 0x0e,
+};
+
+#endif
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c
new file mode 100644
index 00000000000..3159db6958e
--- /dev/null
+++ b/fs/logfs/readwrite.c
@@ -0,0 +1,2267 @@
+/*
+ * fs/logfs/readwrite.c
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ *
+ *
+ * Actually contains five sets of very similar functions:
+ * read read blocks from a file
+ * seek_hole find next hole
+ * seek_data find next data block
+ * valid check whether a block still belongs to a file
+ * write write blocks to a file
+ * delete delete a block (for directories and ifile)
+ * rewrite move existing blocks of a file to a new location (gc helper)
+ * truncate truncate a file
+ */
+#include "logfs.h"
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+static u64 adjust_bix(u64 bix, level_t level)
+{
+ switch (level) {
+ case 0:
+ return bix;
+ case LEVEL(1):
+ return max_t(u64, bix, I0_BLOCKS);
+ case LEVEL(2):
+ return max_t(u64, bix, I1_BLOCKS);
+ case LEVEL(3):
+ return max_t(u64, bix, I2_BLOCKS);
+ case LEVEL(4):
+ return max_t(u64, bix, I3_BLOCKS);
+ case LEVEL(5):
+ return max_t(u64, bix, I4_BLOCKS);
+ default:
+ WARN_ON(1);
+ return bix;
+ }
+}
+
+static inline u64 maxbix(u8 height)
+{
+ return 1ULL << (LOGFS_BLOCK_BITS * height);
+}
+
+/**
+ * The inode address space is cut in two halves. Lower half belongs to data
+ * pages, upper half to indirect blocks. If the high bit (INDIRECT_BIT) is
+ * set, the actual block index (bix) and level can be derived from the page
+ * index.
+ *
+ * The lowest three bits of the block index are set to 0 after packing and
+ * unpacking. Since the lowest n bits (9 for 4KiB blocksize) are ignored
+ * anyway this is harmless.
+ */
+#define ARCH_SHIFT (BITS_PER_LONG - 32)
+#define INDIRECT_BIT (0x80000000UL << ARCH_SHIFT)
+#define LEVEL_SHIFT (28 + ARCH_SHIFT)
+static inline pgoff_t first_indirect_block(void)
+{
+ return INDIRECT_BIT | (1ULL << LEVEL_SHIFT);
+}
+
+pgoff_t logfs_pack_index(u64 bix, level_t level)
+{
+ pgoff_t index;
+
+ BUG_ON(bix >= INDIRECT_BIT);
+ if (level == 0)
+ return bix;
+
+ index = INDIRECT_BIT;
+ index |= (__force long)level << LEVEL_SHIFT;
+ index |= bix >> ((__force u8)level * LOGFS_BLOCK_BITS);
+ return index;
+}
+
+void logfs_unpack_index(pgoff_t index, u64 *bix, level_t *level)
+{
+ u8 __level;
+
+ if (!(index & INDIRECT_BIT)) {
+ *bix = index;
+ *level = 0;
+ return;
+ }
+
+ __level = (index & ~INDIRECT_BIT) >> LEVEL_SHIFT;
+ *level = LEVEL(__level);
+ *bix = (index << (__level * LOGFS_BLOCK_BITS)) & ~INDIRECT_BIT;
+ *bix = adjust_bix(*bix, *level);
+ return;
+}
+#undef ARCH_SHIFT
+#undef INDIRECT_BIT
+#undef LEVEL_SHIFT
+
+/*
+ * Time is stored as nanoseconds since the epoch.
+ */
+static struct timespec be64_to_timespec(__be64 betime)
+{
+ return ns_to_timespec(be64_to_cpu(betime));
+}
+
+static __be64 timespec_to_be64(struct timespec tsp)
+{
+ return cpu_to_be64((u64)tsp.tv_sec * NSEC_PER_SEC + tsp.tv_nsec);
+}
+
+static void logfs_disk_to_inode(struct logfs_disk_inode *di, struct inode*inode)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ int i;
+
+ inode->i_mode = be16_to_cpu(di->di_mode);
+ li->li_height = di->di_height;
+ li->li_flags = be32_to_cpu(di->di_flags);
+ inode->i_uid = be32_to_cpu(di->di_uid);
+ inode->i_gid = be32_to_cpu(di->di_gid);
+ inode->i_size = be64_to_cpu(di->di_size);
+ logfs_set_blocks(inode, be64_to_cpu(di->di_used_bytes));
+ inode->i_atime = be64_to_timespec(di->di_atime);
+ inode->i_ctime = be64_to_timespec(di->di_ctime);
+ inode->i_mtime = be64_to_timespec(di->di_mtime);
+ inode->i_nlink = be32_to_cpu(di->di_refcount);
+ inode->i_generation = be32_to_cpu(di->di_generation);
+
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFSOCK: /* fall through */
+ case S_IFBLK: /* fall through */
+ case S_IFCHR: /* fall through */
+ case S_IFIFO:
+ inode->i_rdev = be64_to_cpu(di->di_data[0]);
+ break;
+ case S_IFDIR: /* fall through */
+ case S_IFREG: /* fall through */
+ case S_IFLNK:
+ for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
+ li->li_data[i] = be64_to_cpu(di->di_data[i]);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static void logfs_inode_to_disk(struct inode *inode, struct logfs_disk_inode*di)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ int i;
+
+ di->di_mode = cpu_to_be16(inode->i_mode);
+ di->di_height = li->li_height;
+ di->di_pad = 0;
+ di->di_flags = cpu_to_be32(li->li_flags);
+ di->di_uid = cpu_to_be32(inode->i_uid);
+ di->di_gid = cpu_to_be32(inode->i_gid);
+ di->di_size = cpu_to_be64(i_size_read(inode));
+ di->di_used_bytes = cpu_to_be64(li->li_used_bytes);
+ di->di_atime = timespec_to_be64(inode->i_atime);
+ di->di_ctime = timespec_to_be64(inode->i_ctime);
+ di->di_mtime = timespec_to_be64(inode->i_mtime);
+ di->di_refcount = cpu_to_be32(inode->i_nlink);
+ di->di_generation = cpu_to_be32(inode->i_generation);
+
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFSOCK: /* fall through */
+ case S_IFBLK: /* fall through */
+ case S_IFCHR: /* fall through */
+ case S_IFIFO:
+ di->di_data[0] = cpu_to_be64(inode->i_rdev);
+ break;
+ case S_IFDIR: /* fall through */
+ case S_IFREG: /* fall through */
+ case S_IFLNK:
+ for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
+ di->di_data[i] = cpu_to_be64(li->li_data[i]);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static void __logfs_set_blocks(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ struct logfs_inode *li = logfs_inode(inode);
+
+ inode->i_blocks = ULONG_MAX;
+ if (li->li_used_bytes >> sb->s_blocksize_bits < ULONG_MAX)
+ inode->i_blocks = ALIGN(li->li_used_bytes, 512) >> 9;
+}
+
+void logfs_set_blocks(struct inode *inode, u64 bytes)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ li->li_used_bytes = bytes;
+ __logfs_set_blocks(inode);
+}
+
+static void prelock_page(struct super_block *sb, struct page *page, int lock)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ BUG_ON(!PageLocked(page));
+ if (lock) {
+ BUG_ON(PagePreLocked(page));
+ SetPagePreLocked(page);
+ } else {
+ /* We are in GC path. */
+ if (PagePreLocked(page))
+ super->s_lock_count++;
+ else
+ SetPagePreLocked(page);
+ }
+}
+
+static void preunlock_page(struct super_block *sb, struct page *page, int lock)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ BUG_ON(!PageLocked(page));
+ if (lock)
+ ClearPagePreLocked(page);
+ else {
+ /* We are in GC path. */
+ BUG_ON(!PagePreLocked(page));
+ if (super->s_lock_count)
+ super->s_lock_count--;
+ else
+ ClearPagePreLocked(page);
+ }
+}
+
+/*
+ * Logfs is prone to an AB-BA deadlock where one task tries to acquire
+ * s_write_mutex with a locked page and GC tries to get that page while holding
+ * s_write_mutex.
+ * To solve this issue logfs will ignore the page lock iff the page in question
+ * is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked
+ * in addition to PG_locked.
+ */
+static void logfs_get_wblocks(struct super_block *sb, struct page *page,
+ int lock)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ if (page)
+ prelock_page(sb, page, lock);
+
+ if (lock) {
+ mutex_lock(&super->s_write_mutex);
+ logfs_gc_pass(sb);
+ /* FIXME: We also have to check for shadowed space
+ * and mempool fill grade */
+ }
+}
+
+static void logfs_put_wblocks(struct super_block *sb, struct page *page,
+ int lock)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ if (page)
+ preunlock_page(sb, page, lock);
+ /* Order matters - we must clear PG_pre_locked before releasing
+ * s_write_mutex or we could race against another task. */
+ if (lock)
+ mutex_unlock(&super->s_write_mutex);
+}
+
+static struct page *logfs_get_read_page(struct inode *inode, u64 bix,
+ level_t level)
+{
+ return find_or_create_page(inode->i_mapping,
+ logfs_pack_index(bix, level), GFP_NOFS);
+}
+
+static void logfs_put_read_page(struct page *page)
+{
+ unlock_page(page);
+ page_cache_release(page);
+}
+
+static void logfs_lock_write_page(struct page *page)
+{
+ int loop = 0;
+
+ while (unlikely(!trylock_page(page))) {
+ if (loop++ > 0x1000) {
+ /* Has been observed once so far... */
+ printk(KERN_ERR "stack at %p\n", &loop);
+ BUG();
+ }
+ if (PagePreLocked(page)) {
+ /* Holder of page lock is waiting for us, it
+ * is safe to use this page. */
+ break;
+ }
+ /* Some other process has this page locked and has
+ * nothing to do with us. Wait for it to finish.
+ */
+ schedule();
+ }
+ BUG_ON(!PageLocked(page));
+}
+
+static struct page *logfs_get_write_page(struct inode *inode, u64 bix,
+ level_t level)
+{
+ struct address_space *mapping = inode->i_mapping;
+ pgoff_t index = logfs_pack_index(bix, level);
+ struct page *page;
+ int err;
+
+repeat:
+ page = find_get_page(mapping, index);
+ if (!page) {
+ page = __page_cache_alloc(GFP_NOFS);
+ if (!page)
+ return NULL;
+ err = add_to_page_cache_lru(page, mapping, index, GFP_NOFS);
+ if (unlikely(err)) {
+ page_cache_release(page);
+ if (err == -EEXIST)
+ goto repeat;
+ return NULL;
+ }
+ } else logfs_lock_write_page(page);
+ BUG_ON(!PageLocked(page));
+ return page;
+}
+
+static void logfs_unlock_write_page(struct page *page)
+{
+ if (!PagePreLocked(page))
+ unlock_page(page);
+}
+
+static void logfs_put_write_page(struct page *page)
+{
+ logfs_unlock_write_page(page);
+ page_cache_release(page);
+}
+
+static struct page *logfs_get_page(struct inode *inode, u64 bix, level_t level,
+ int rw)
+{
+ if (rw == READ)
+ return logfs_get_read_page(inode, bix, level);
+ else
+ return logfs_get_write_page(inode, bix, level);
+}
+
+static void logfs_put_page(struct page *page, int rw)
+{
+ if (rw == READ)
+ logfs_put_read_page(page);
+ else
+ logfs_put_write_page(page);
+}
+
+static unsigned long __get_bits(u64 val, int skip, int no)
+{
+ u64 ret = val;
+
+ ret >>= skip * no;
+ ret <<= 64 - no;
+ ret >>= 64 - no;
+ return ret;
+}
+
+static unsigned long get_bits(u64 val, level_t skip)
+{
+ return __get_bits(val, (__force int)skip, LOGFS_BLOCK_BITS);
+}
+
+static inline void init_shadow_tree(struct super_block *sb,
+ struct shadow_tree *tree)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ btree_init_mempool64(&tree->new, super->s_btree_pool);
+ btree_init_mempool64(&tree->old, super->s_btree_pool);
+}
+
+static void indirect_write_block(struct logfs_block *block)
+{
+ struct page *page;
+ struct inode *inode;
+ int ret;
+
+ page = block->page;
+ inode = page->mapping->host;
+ logfs_lock_write_page(page);
+ ret = logfs_write_buf(inode, page, 0);
+ logfs_unlock_write_page(page);
+ /*
+ * This needs some rework. Unless you want your filesystem to run
+ * completely synchronously (you don't), the filesystem will always
+ * report writes as 'successful' before the actual work has been
+ * done. The actual work gets done here and this is where any errors
+ * will show up. And there isn't much we can do about it, really.
+ *
+ * Some attempts to fix the errors (move from bad blocks, retry io,...)
+ * have already been done, so anything left should be either a broken
+ * device or a bug somewhere in logfs itself. Being relatively new,
+ * the odds currently favor a bug, so for now the line below isn't
+ * entirely tasteles.
+ */
+ BUG_ON(ret);
+}
+
+static void inode_write_block(struct logfs_block *block)
+{
+ struct inode *inode;
+ int ret;
+
+ inode = block->inode;
+ if (inode->i_ino == LOGFS_INO_MASTER)
+ logfs_write_anchor(inode->i_sb);
+ else {
+ ret = __logfs_write_inode(inode, 0);
+ /* see indirect_write_block comment */
+ BUG_ON(ret);
+ }
+}
+
+/*
+ * This silences a false, yet annoying gcc warning. I hate it when my editor
+ * jumps into bitops.h each time I recompile this file.
+ * TODO: Complain to gcc folks about this and upgrade compiler.
+ */
+static unsigned long fnb(const unsigned long *addr,
+ unsigned long size, unsigned long offset)
+{
+ return find_next_bit(addr, size, offset);
+}
+
+static __be64 inode_val0(struct inode *inode)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ u64 val;
+
+ /*
+ * Explicit shifting generates good code, but must match the format
+ * of the structure. Add some paranoia just in case.
+ */
+ BUILD_BUG_ON(offsetof(struct logfs_disk_inode, di_mode) != 0);
+ BUILD_BUG_ON(offsetof(struct logfs_disk_inode, di_height) != 2);
+ BUILD_BUG_ON(offsetof(struct logfs_disk_inode, di_flags) != 4);
+
+ val = (u64)inode->i_mode << 48 |
+ (u64)li->li_height << 40 |
+ (u64)li->li_flags;
+ return cpu_to_be64(val);
+}
+
+static int inode_write_alias(struct super_block *sb,
+ struct logfs_block *block, write_alias_t *write_one_alias)
+{
+ struct inode *inode = block->inode;
+ struct logfs_inode *li = logfs_inode(inode);
+ unsigned long pos;
+ u64 ino , bix;
+ __be64 val;
+ level_t level;
+ int err;
+
+ for (pos = 0; ; pos++) {
+ pos = fnb(block->alias_map, LOGFS_BLOCK_FACTOR, pos);
+ if (pos >= LOGFS_EMBEDDED_FIELDS + INODE_POINTER_OFS)
+ return 0;
+
+ switch (pos) {
+ case INODE_HEIGHT_OFS:
+ val = inode_val0(inode);
+ break;
+ case INODE_USED_OFS:
+ val = cpu_to_be64(li->li_used_bytes);;
+ break;
+ case INODE_SIZE_OFS:
+ val = cpu_to_be64(i_size_read(inode));
+ break;
+ case INODE_POINTER_OFS ... INODE_POINTER_OFS + LOGFS_EMBEDDED_FIELDS - 1:
+ val = cpu_to_be64(li->li_data[pos - INODE_POINTER_OFS]);
+ break;
+ default:
+ BUG();
+ }
+
+ ino = LOGFS_INO_MASTER;
+ bix = inode->i_ino;
+ level = LEVEL(0);
+ err = write_one_alias(sb, ino, bix, level, pos, val);
+ if (err)
+ return err;
+ }
+}
+
+static int indirect_write_alias(struct super_block *sb,
+ struct logfs_block *block, write_alias_t *write_one_alias)
+{
+ unsigned long pos;
+ struct page *page = block->page;
+ u64 ino , bix;
+ __be64 *child, val;
+ level_t level;
+ int err;
+
+ for (pos = 0; ; pos++) {
+ pos = fnb(block->alias_map, LOGFS_BLOCK_FACTOR, pos);
+ if (pos >= LOGFS_BLOCK_FACTOR)
+ return 0;
+
+ ino = page->mapping->host->i_ino;
+ logfs_unpack_index(page->index, &bix, &level);
+ child = kmap_atomic(page, KM_USER0);
+ val = child[pos];
+ kunmap_atomic(child, KM_USER0);
+ err = write_one_alias(sb, ino, bix, level, pos, val);
+ if (err)
+ return err;
+ }
+}
+
+int logfs_write_obj_aliases_pagecache(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_block *block;
+ int err;
+
+ list_for_each_entry(block, &super->s_object_alias, alias_list) {
+ err = block->ops->write_alias(sb, block, write_alias_journal);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+void __free_block(struct super_block *sb, struct logfs_block *block)
+{
+ BUG_ON(!list_empty(&block->item_list));
+ list_del(&block->alias_list);
+ mempool_free(block, logfs_super(sb)->s_block_pool);
+}
+
+static void inode_free_block(struct super_block *sb, struct logfs_block *block)
+{
+ struct inode *inode = block->inode;
+
+ logfs_inode(inode)->li_block = NULL;
+ __free_block(sb, block);
+}
+
+static void indirect_free_block(struct super_block *sb,
+ struct logfs_block *block)
+{
+ ClearPagePrivate(block->page);
+ block->page->private = 0;
+ __free_block(sb, block);
+}
+
+
+static struct logfs_block_ops inode_block_ops = {
+ .write_block = inode_write_block,
+ .free_block = inode_free_block,
+ .write_alias = inode_write_alias,
+};
+
+struct logfs_block_ops indirect_block_ops = {
+ .write_block = indirect_write_block,
+ .free_block = indirect_free_block,
+ .write_alias = indirect_write_alias,
+};
+
+struct logfs_block *__alloc_block(struct super_block *sb,
+ u64 ino, u64 bix, level_t level)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_block *block;
+
+ block = mempool_alloc(super->s_block_pool, GFP_NOFS);
+ memset(block, 0, sizeof(*block));
+ INIT_LIST_HEAD(&block->alias_list);
+ INIT_LIST_HEAD(&block->item_list);
+ block->sb = sb;
+ block->ino = ino;
+ block->bix = bix;
+ block->level = level;
+ return block;
+}
+
+static void alloc_inode_block(struct inode *inode)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ struct logfs_block *block;
+
+ if (li->li_block)
+ return;
+
+ block = __alloc_block(inode->i_sb, LOGFS_INO_MASTER, inode->i_ino, 0);
+ block->inode = inode;
+ li->li_block = block;
+ block->ops = &inode_block_ops;
+}
+
+void initialize_block_counters(struct page *page, struct logfs_block *block,
+ __be64 *array, int page_is_empty)
+{
+ u64 ptr;
+ int i, start;
+
+ block->partial = 0;
+ block->full = 0;
+ start = 0;
+ if (page->index < first_indirect_block()) {
+ /* Counters are pointless on level 0 */
+ return;
+ }
+ if (page->index == first_indirect_block()) {
+ /* Skip unused pointers */
+ start = I0_BLOCKS;
+ block->full = I0_BLOCKS;
+ }
+ if (!page_is_empty) {
+ for (i = start; i < LOGFS_BLOCK_FACTOR; i++) {
+ ptr = be64_to_cpu(array[i]);
+ if (ptr)
+ block->partial++;
+ if (ptr & LOGFS_FULLY_POPULATED)
+ block->full++;
+ }
+ }
+}
+
+static void alloc_data_block(struct inode *inode, struct page *page)
+{
+ struct logfs_block *block;
+ u64 bix;
+ level_t level;
+
+ if (PagePrivate(page))
+ return;
+
+ logfs_unpack_index(page->index, &bix, &level);
+ block = __alloc_block(inode->i_sb, inode->i_ino, bix, level);
+ block->page = page;
+ SetPagePrivate(page);
+ page->private = (unsigned long)block;
+ block->ops = &indirect_block_ops;
+}
+
+static void alloc_indirect_block(struct inode *inode, struct page *page,
+ int page_is_empty)
+{
+ struct logfs_block *block;
+ __be64 *array;
+
+ if (PagePrivate(page))
+ return;
+
+ alloc_data_block(inode, page);
+
+ block = logfs_block(page);
+ array = kmap_atomic(page, KM_USER0);
+ initialize_block_counters(page, block, array, page_is_empty);
+ kunmap_atomic(array, KM_USER0);
+}
+
+static void block_set_pointer(struct page *page, int index, u64 ptr)
+{
+ struct logfs_block *block = logfs_block(page);
+ __be64 *array;
+ u64 oldptr;
+
+ BUG_ON(!block);
+ array = kmap_atomic(page, KM_USER0);
+ oldptr = be64_to_cpu(array[index]);
+ array[index] = cpu_to_be64(ptr);
+ kunmap_atomic(array, KM_USER0);
+ SetPageUptodate(page);
+
+ block->full += !!(ptr & LOGFS_FULLY_POPULATED)
+ - !!(oldptr & LOGFS_FULLY_POPULATED);
+ block->partial += !!ptr - !!oldptr;
+}
+
+static u64 block_get_pointer(struct page *page, int index)
+{
+ __be64 *block;
+ u64 ptr;
+
+ block = kmap_atomic(page, KM_USER0);
+ ptr = be64_to_cpu(block[index]);
+ kunmap_atomic(block, KM_USER0);
+ return ptr;
+}
+
+static int logfs_read_empty(struct page *page)
+{
+ zero_user_segment(page, 0, PAGE_CACHE_SIZE);
+ return 0;
+}
+
+static int logfs_read_direct(struct inode *inode, struct page *page)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ pgoff_t index = page->index;
+ u64 block;
+
+ block = li->li_data[index];
+ if (!block)
+ return logfs_read_empty(page);
+
+ return logfs_segment_read(inode, page, block, index, 0);
+}
+
+static int logfs_read_loop(struct inode *inode, struct page *page,
+ int rw_context)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ u64 bix, bofs = li->li_data[INDIRECT_INDEX];
+ level_t level, target_level;
+ int ret;
+ struct page *ipage;
+
+ logfs_unpack_index(page->index, &bix, &target_level);
+ if (!bofs)
+ return logfs_read_empty(page);
+
+ if (bix >= maxbix(li->li_height))
+ return logfs_read_empty(page);
+
+ for (level = LEVEL(li->li_height);
+ (__force u8)level > (__force u8)target_level;
+ level = SUBLEVEL(level)){
+ ipage = logfs_get_page(inode, bix, level, rw_context);
+ if (!ipage)
+ return -ENOMEM;
+
+ ret = logfs_segment_read(inode, ipage, bofs, bix, level);
+ if (ret) {
+ logfs_put_read_page(ipage);
+ return ret;
+ }
+
+ bofs = block_get_pointer(ipage, get_bits(bix, SUBLEVEL(level)));
+ logfs_put_page(ipage, rw_context);
+ if (!bofs)
+ return logfs_read_empty(page);
+ }
+
+ return logfs_segment_read(inode, page, bofs, bix, 0);
+}
+
+static int logfs_read_block(struct inode *inode, struct page *page,
+ int rw_context)
+{
+ pgoff_t index = page->index;
+
+ if (index < I0_BLOCKS)
+ return logfs_read_direct(inode, page);
+ return logfs_read_loop(inode, page, rw_context);
+}
+
+static int logfs_exist_loop(struct inode *inode, u64 bix)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ u64 bofs = li->li_data[INDIRECT_INDEX];
+ level_t level;
+ int ret;
+ struct page *ipage;
+
+ if (!bofs)
+ return 0;
+ if (bix >= maxbix(li->li_height))
+ return 0;
+
+ for (level = LEVEL(li->li_height); level != 0; level = SUBLEVEL(level)) {
+ ipage = logfs_get_read_page(inode, bix, level);
+ if (!ipage)
+ return -ENOMEM;
+
+ ret = logfs_segment_read(inode, ipage, bofs, bix, level);
+ if (ret) {
+ logfs_put_read_page(ipage);
+ return ret;
+ }
+
+ bofs = block_get_pointer(ipage, get_bits(bix, SUBLEVEL(level)));
+ logfs_put_read_page(ipage);
+ if (!bofs)
+ return 0;
+ }
+
+ return 1;
+}
+
+int logfs_exist_block(struct inode *inode, u64 bix)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ if (bix < I0_BLOCKS)
+ return !!li->li_data[bix];
+ return logfs_exist_loop(inode, bix);
+}
+
+static u64 seek_holedata_direct(struct inode *inode, u64 bix, int data)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ for (; bix < I0_BLOCKS; bix++)
+ if (data ^ (li->li_data[bix] == 0))
+ return bix;
+ return I0_BLOCKS;
+}
+
+static u64 seek_holedata_loop(struct inode *inode, u64 bix, int data)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ __be64 *rblock;
+ u64 increment, bofs = li->li_data[INDIRECT_INDEX];
+ level_t level;
+ int ret, slot;
+ struct page *page;
+
+ BUG_ON(!bofs);
+
+ for (level = LEVEL(li->li_height); level != 0; level = SUBLEVEL(level)) {
+ increment = 1 << (LOGFS_BLOCK_BITS * ((__force u8)level-1));
+ page = logfs_get_read_page(inode, bix, level);
+ if (!page)
+ return bix;
+
+ ret = logfs_segment_read(inode, page, bofs, bix, level);
+ if (ret) {
+ logfs_put_read_page(page);
+ return bix;
+ }
+
+ slot = get_bits(bix, SUBLEVEL(level));
+ rblock = kmap_atomic(page, KM_USER0);
+ while (slot < LOGFS_BLOCK_FACTOR) {
+ if (data && (rblock[slot] != 0))
+ break;
+ if (!data && !(be64_to_cpu(rblock[slot]) & LOGFS_FULLY_POPULATED))
+ break;
+ slot++;
+ bix += increment;
+ bix &= ~(increment - 1);
+ }
+ if (slot >= LOGFS_BLOCK_FACTOR) {
+ kunmap_atomic(rblock, KM_USER0);
+ logfs_put_read_page(page);
+ return bix;
+ }
+ bofs = be64_to_cpu(rblock[slot]);
+ kunmap_atomic(rblock, KM_USER0);
+ logfs_put_read_page(page);
+ if (!bofs) {
+ BUG_ON(data);
+ return bix;
+ }
+ }
+ return bix;
+}
+
+/**
+ * logfs_seek_hole - find next hole starting at a given block index
+ * @inode: inode to search in
+ * @bix: block index to start searching
+ *
+ * Returns next hole. If the file doesn't contain any further holes, the
+ * block address next to eof is returned instead.
+ */
+u64 logfs_seek_hole(struct inode *inode, u64 bix)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ if (bix < I0_BLOCKS) {
+ bix = seek_holedata_direct(inode, bix, 0);
+ if (bix < I0_BLOCKS)
+ return bix;
+ }
+
+ if (!li->li_data[INDIRECT_INDEX])
+ return bix;
+ else if (li->li_data[INDIRECT_INDEX] & LOGFS_FULLY_POPULATED)
+ bix = maxbix(li->li_height);
+ else {
+ bix = seek_holedata_loop(inode, bix, 0);
+ if (bix < maxbix(li->li_height))
+ return bix;
+ /* Should not happen anymore. But if some port writes semi-
+ * corrupt images (as this one used to) we might run into it.
+ */
+ WARN_ON_ONCE(bix == maxbix(li->li_height));
+ }
+
+ return bix;
+}
+
+static u64 __logfs_seek_data(struct inode *inode, u64 bix)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ if (bix < I0_BLOCKS) {
+ bix = seek_holedata_direct(inode, bix, 1);
+ if (bix < I0_BLOCKS)
+ return bix;
+ }
+
+ if (bix < maxbix(li->li_height)) {
+ if (!li->li_data[INDIRECT_INDEX])
+ bix = maxbix(li->li_height);
+ else
+ return seek_holedata_loop(inode, bix, 1);
+ }
+
+ return bix;
+}
+
+/**
+ * logfs_seek_data - find next data block after a given block index
+ * @inode: inode to search in
+ * @bix: block index to start searching
+ *
+ * Returns next data block. If the file doesn't contain any further data
+ * blocks, the last block in the file is returned instead.
+ */
+u64 logfs_seek_data(struct inode *inode, u64 bix)
+{
+ struct super_block *sb = inode->i_sb;
+ u64 ret, end;
+
+ ret = __logfs_seek_data(inode, bix);
+ end = i_size_read(inode) >> sb->s_blocksize_bits;
+ if (ret >= end)
+ ret = max(bix, end);
+ return ret;
+}
+
+static int logfs_is_valid_direct(struct logfs_inode *li, u64 bix, u64 ofs)
+{
+ return pure_ofs(li->li_data[bix]) == ofs;
+}
+
+static int __logfs_is_valid_loop(struct inode *inode, u64 bix,
+ u64 ofs, u64 bofs)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ level_t level;
+ int ret;
+ struct page *page;
+
+ for (level = LEVEL(li->li_height); level != 0; level = SUBLEVEL(level)){
+ page = logfs_get_write_page(inode, bix, level);
+ BUG_ON(!page);
+
+ ret = logfs_segment_read(inode, page, bofs, bix, level);
+ if (ret) {
+ logfs_put_write_page(page);
+ return 0;
+ }
+
+ bofs = block_get_pointer(page, get_bits(bix, SUBLEVEL(level)));
+ logfs_put_write_page(page);
+ if (!bofs)
+ return 0;
+
+ if (pure_ofs(bofs) == ofs)
+ return 1;
+ }
+ return 0;
+}
+
+static int logfs_is_valid_loop(struct inode *inode, u64 bix, u64 ofs)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ u64 bofs = li->li_data[INDIRECT_INDEX];
+
+ if (!bofs)
+ return 0;
+
+ if (bix >= maxbix(li->li_height))
+ return 0;
+
+ if (pure_ofs(bofs) == ofs)
+ return 1;
+
+ return __logfs_is_valid_loop(inode, bix, ofs, bofs);
+}
+
+static int __logfs_is_valid_block(struct inode *inode, u64 bix, u64 ofs)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ if ((inode->i_nlink == 0) && atomic_read(&inode->i_count) == 1)
+ return 0;
+
+ if (bix < I0_BLOCKS)
+ return logfs_is_valid_direct(li, bix, ofs);
+ return logfs_is_valid_loop(inode, bix, ofs);
+}
+
+/**
+ * logfs_is_valid_block - check whether this block is still valid
+ *
+ * @sb - superblock
+ * @ofs - block physical offset
+ * @ino - block inode number
+ * @bix - block index
+ * @level - block level
+ *
+ * Returns 0 if the block is invalid, 1 if it is valid and 2 if it will
+ * become invalid once the journal is written.
+ */
+int logfs_is_valid_block(struct super_block *sb, u64 ofs, u64 ino, u64 bix,
+ gc_level_t gc_level)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct inode *inode;
+ int ret, cookie;
+
+ /* Umount closes a segment with free blocks remaining. Those
+ * blocks are by definition invalid. */
+ if (ino == -1)
+ return 0;
+
+ LOGFS_BUG_ON((u64)(u_long)ino != ino, sb);
+
+ inode = logfs_safe_iget(sb, ino, &cookie);
+ if (IS_ERR(inode))
+ goto invalid;
+
+ ret = __logfs_is_valid_block(inode, bix, ofs);
+ logfs_safe_iput(inode, cookie);
+ if (ret)
+ return ret;
+
+invalid:
+ /* Block is nominally invalid, but may still sit in the shadow tree,
+ * waiting for a journal commit.
+ */
+ if (btree_lookup64(&super->s_shadow_tree.old, ofs))
+ return 2;
+ return 0;
+}
+
+int logfs_readpage_nolock(struct page *page)
+{
+ struct inode *inode = page->mapping->host;
+ int ret = -EIO;
+
+ ret = logfs_read_block(inode, page, READ);
+
+ if (ret) {
+ ClearPageUptodate(page);
+ SetPageError(page);
+ } else {
+ SetPageUptodate(page);
+ ClearPageError(page);
+ }
+ flush_dcache_page(page);
+
+ return ret;
+}
+
+static int logfs_reserve_bytes(struct inode *inode, int bytes)
+{
+ struct logfs_super *super = logfs_super(inode->i_sb);
+ u64 available = super->s_free_bytes + super->s_dirty_free_bytes
+ - super->s_dirty_used_bytes - super->s_dirty_pages;
+
+ if (!bytes)
+ return 0;
+
+ if (available < bytes)
+ return -ENOSPC;
+
+ if (available < bytes + super->s_root_reserve &&
+ !capable(CAP_SYS_RESOURCE))
+ return -ENOSPC;
+
+ return 0;
+}
+
+int get_page_reserve(struct inode *inode, struct page *page)
+{
+ struct logfs_super *super = logfs_super(inode->i_sb);
+ int ret;
+
+ if (logfs_block(page) && logfs_block(page)->reserved_bytes)
+ return 0;
+
+ logfs_get_wblocks(inode->i_sb, page, WF_LOCK);
+ ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE);
+ if (!ret) {
+ alloc_data_block(inode, page);
+ logfs_block(page)->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE;
+ super->s_dirty_pages += 6 * LOGFS_MAX_OBJECTSIZE;
+ }
+ logfs_put_wblocks(inode->i_sb, page, WF_LOCK);
+ return ret;
+}
+
+/*
+ * We are protected by write lock. Push victims up to superblock level
+ * and release transaction when appropriate.
+ */
+/* FIXME: This is currently called from the wrong spots. */
+static void logfs_handle_transaction(struct inode *inode,
+ struct logfs_transaction *ta)
+{
+ struct logfs_super *super = logfs_super(inode->i_sb);
+
+ if (!ta)
+ return;
+ logfs_inode(inode)->li_block->ta = NULL;
+
+ if (inode->i_ino != LOGFS_INO_MASTER) {
+ BUG(); /* FIXME: Yes, this needs more thought */
+ /* just remember the transaction until inode is written */
+ //BUG_ON(logfs_inode(inode)->li_transaction);
+ //logfs_inode(inode)->li_transaction = ta;
+ return;
+ }
+
+ switch (ta->state) {
+ case CREATE_1: /* fall through */
+ case UNLINK_1:
+ BUG_ON(super->s_victim_ino);
+ super->s_victim_ino = ta->ino;
+ break;
+ case CREATE_2: /* fall through */
+ case UNLINK_2:
+ BUG_ON(super->s_victim_ino != ta->ino);
+ super->s_victim_ino = 0;
+ /* transaction ends here - free it */
+ kfree(ta);
+ break;
+ case CROSS_RENAME_1:
+ BUG_ON(super->s_rename_dir);
+ BUG_ON(super->s_rename_pos);
+ super->s_rename_dir = ta->dir;
+ super->s_rename_pos = ta->pos;
+ break;
+ case CROSS_RENAME_2:
+ BUG_ON(super->s_rename_dir != ta->dir);
+ BUG_ON(super->s_rename_pos != ta->pos);
+ super->s_rename_dir = 0;
+ super->s_rename_pos = 0;
+ kfree(ta);
+ break;
+ case TARGET_RENAME_1:
+ BUG_ON(super->s_rename_dir);
+ BUG_ON(super->s_rename_pos);
+ BUG_ON(super->s_victim_ino);
+ super->s_rename_dir = ta->dir;
+ super->s_rename_pos = ta->pos;
+ super->s_victim_ino = ta->ino;
+ break;
+ case TARGET_RENAME_2:
+ BUG_ON(super->s_rename_dir != ta->dir);
+ BUG_ON(super->s_rename_pos != ta->pos);
+ BUG_ON(super->s_victim_ino != ta->ino);
+ super->s_rename_dir = 0;
+ super->s_rename_pos = 0;
+ break;
+ case TARGET_RENAME_3:
+ BUG_ON(super->s_rename_dir);
+ BUG_ON(super->s_rename_pos);
+ BUG_ON(super->s_victim_ino != ta->ino);
+ super->s_victim_ino = 0;
+ kfree(ta);
+ break;
+ default:
+ BUG();
+ }
+}
+
+/*
+ * Not strictly a reservation, but rather a check that we still have enough
+ * space to satisfy the write.
+ */
+static int logfs_reserve_blocks(struct inode *inode, int blocks)
+{
+ return logfs_reserve_bytes(inode, blocks * LOGFS_MAX_OBJECTSIZE);
+}
+
+struct write_control {
+ u64 ofs;
+ long flags;
+};
+
+static struct logfs_shadow *alloc_shadow(struct inode *inode, u64 bix,
+ level_t level, u64 old_ofs)
+{
+ struct logfs_super *super = logfs_super(inode->i_sb);
+ struct logfs_shadow *shadow;
+
+ shadow = mempool_alloc(super->s_shadow_pool, GFP_NOFS);
+ memset(shadow, 0, sizeof(*shadow));
+ shadow->ino = inode->i_ino;
+ shadow->bix = bix;
+ shadow->gc_level = expand_level(inode->i_ino, level);
+ shadow->old_ofs = old_ofs & ~LOGFS_FULLY_POPULATED;
+ return shadow;
+}
+
+static void free_shadow(struct inode *inode, struct logfs_shadow *shadow)
+{
+ struct logfs_super *super = logfs_super(inode->i_sb);
+
+ mempool_free(shadow, super->s_shadow_pool);
+}
+
+static void mark_segment(struct shadow_tree *tree, u32 segno)
+{
+ int err;
+
+ if (!btree_lookup32(&tree->segment_map, segno)) {
+ err = btree_insert32(&tree->segment_map, segno, (void *)1,
+ GFP_NOFS);
+ BUG_ON(err);
+ tree->no_shadowed_segments++;
+ }
+}
+
+/**
+ * fill_shadow_tree - Propagate shadow tree changes due to a write
+ * @inode: Inode owning the page
+ * @page: Struct page that was written
+ * @shadow: Shadow for the current write
+ *
+ * Writes in logfs can result in two semi-valid objects. The old object
+ * is still valid as long as it can be reached by following pointers on
+ * the medium. Only when writes propagate all the way up to the journal
+ * has the new object safely replaced the old one.
+ *
+ * To handle this problem, a struct logfs_shadow is used to represent
+ * every single write. It is attached to the indirect block, which is
+ * marked dirty. When the indirect block is written, its shadows are
+ * handed up to the next indirect block (or inode). Untimately they
+ * will reach the master inode and be freed upon journal commit.
+ *
+ * This function handles a single step in the propagation. It adds the
+ * shadow for the current write to the tree, along with any shadows in
+ * the page's tree, in case it was an indirect block. If a page is
+ * written, the inode parameter is left NULL, if an inode is written,
+ * the page parameter is left NULL.
+ */
+static void fill_shadow_tree(struct inode *inode, struct page *page,
+ struct logfs_shadow *shadow)
+{
+ struct logfs_super *super = logfs_super(inode->i_sb);
+ struct logfs_block *block = logfs_block(page);
+ struct shadow_tree *tree = &super->s_shadow_tree;
+
+ if (PagePrivate(page)) {
+ if (block->alias_map)
+ super->s_no_object_aliases -= bitmap_weight(
+ block->alias_map, LOGFS_BLOCK_FACTOR);
+ logfs_handle_transaction(inode, block->ta);
+ block->ops->free_block(inode->i_sb, block);
+ }
+ if (shadow) {
+ if (shadow->old_ofs)
+ btree_insert64(&tree->old, shadow->old_ofs, shadow,
+ GFP_NOFS);
+ else
+ btree_insert64(&tree->new, shadow->new_ofs, shadow,
+ GFP_NOFS);
+
+ super->s_dirty_used_bytes += shadow->new_len;
+ super->s_dirty_free_bytes += shadow->old_len;
+ mark_segment(tree, shadow->old_ofs >> super->s_segshift);
+ mark_segment(tree, shadow->new_ofs >> super->s_segshift);
+ }
+}
+
+static void logfs_set_alias(struct super_block *sb, struct logfs_block *block,
+ long child_no)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ if (block->inode && block->inode->i_ino == LOGFS_INO_MASTER) {
+ /* Aliases in the master inode are pointless. */
+ return;
+ }
+
+ if (!test_bit(child_no, block->alias_map)) {
+ set_bit(child_no, block->alias_map);
+ super->s_no_object_aliases++;
+ }
+ list_move_tail(&block->alias_list, &super->s_object_alias);
+}
+
+/*
+ * Object aliases can and often do change the size and occupied space of a
+ * file. So not only do we have to change the pointers, we also have to
+ * change inode->i_size and li->li_used_bytes. Which is done by setting
+ * another two object aliases for the inode itself.
+ */
+static void set_iused(struct inode *inode, struct logfs_shadow *shadow)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ if (shadow->new_len == shadow->old_len)
+ return;
+
+ alloc_inode_block(inode);
+ li->li_used_bytes += shadow->new_len - shadow->old_len;
+ __logfs_set_blocks(inode);
+ logfs_set_alias(inode->i_sb, li->li_block, INODE_USED_OFS);
+ logfs_set_alias(inode->i_sb, li->li_block, INODE_SIZE_OFS);
+}
+
+static int logfs_write_i0(struct inode *inode, struct page *page,
+ struct write_control *wc)
+{
+ struct logfs_shadow *shadow;
+ u64 bix;
+ level_t level;
+ int full, err = 0;
+
+ logfs_unpack_index(page->index, &bix, &level);
+ if (wc->ofs == 0)
+ if (logfs_reserve_blocks(inode, 1))
+ return -ENOSPC;
+
+ shadow = alloc_shadow(inode, bix, level, wc->ofs);
+ if (wc->flags & WF_WRITE)
+ err = logfs_segment_write(inode, page, shadow);
+ if (wc->flags & WF_DELETE)
+ logfs_segment_delete(inode, shadow);
+ if (err) {
+ free_shadow(inode, shadow);
+ return err;
+ }
+
+ set_iused(inode, shadow);
+ full = 1;
+ if (level != 0) {
+ alloc_indirect_block(inode, page, 0);
+ full = logfs_block(page)->full == LOGFS_BLOCK_FACTOR;
+ }
+ fill_shadow_tree(inode, page, shadow);
+ wc->ofs = shadow->new_ofs;
+ if (wc->ofs && full)
+ wc->ofs |= LOGFS_FULLY_POPULATED;
+ return 0;
+}
+
+static int logfs_write_direct(struct inode *inode, struct page *page,
+ long flags)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ struct write_control wc = {
+ .ofs = li->li_data[page->index],
+ .flags = flags,
+ };
+ int err;
+
+ alloc_inode_block(inode);
+
+ err = logfs_write_i0(inode, page, &wc);
+ if (err)
+ return err;
+
+ li->li_data[page->index] = wc.ofs;
+ logfs_set_alias(inode->i_sb, li->li_block,
+ page->index + INODE_POINTER_OFS);
+ return 0;
+}
+
+static int ptr_change(u64 ofs, struct page *page)
+{
+ struct logfs_block *block = logfs_block(page);
+ int empty0, empty1, full0, full1;
+
+ empty0 = ofs == 0;
+ empty1 = block->partial == 0;
+ if (empty0 != empty1)
+ return 1;
+
+ /* The !! is necessary to shrink result to int */
+ full0 = !!(ofs & LOGFS_FULLY_POPULATED);
+ full1 = block->full == LOGFS_BLOCK_FACTOR;
+ if (full0 != full1)
+ return 1;
+ return 0;
+}
+
+static int __logfs_write_rec(struct inode *inode, struct page *page,
+ struct write_control *this_wc,
+ pgoff_t bix, level_t target_level, level_t level)
+{
+ int ret, page_empty = 0;
+ int child_no = get_bits(bix, SUBLEVEL(level));
+ struct page *ipage;
+ struct write_control child_wc = {
+ .flags = this_wc->flags,
+ };
+
+ ipage = logfs_get_write_page(inode, bix, level);
+ if (!ipage)
+ return -ENOMEM;
+
+ if (this_wc->ofs) {
+ ret = logfs_segment_read(inode, ipage, this_wc->ofs, bix, level);
+ if (ret)
+ goto out;
+ } else if (!PageUptodate(ipage)) {
+ page_empty = 1;
+ logfs_read_empty(ipage);
+ }
+
+ child_wc.ofs = block_get_pointer(ipage, child_no);
+
+ if ((__force u8)level-1 > (__force u8)target_level)
+ ret = __logfs_write_rec(inode, page, &child_wc, bix,
+ target_level, SUBLEVEL(level));
+ else
+ ret = logfs_write_i0(inode, page, &child_wc);
+
+ if (ret)
+ goto out;
+
+ alloc_indirect_block(inode, ipage, page_empty);
+ block_set_pointer(ipage, child_no, child_wc.ofs);
+ /* FIXME: first condition seems superfluous */
+ if (child_wc.ofs || logfs_block(ipage)->partial)
+ this_wc->flags |= WF_WRITE;
+ /* the condition on this_wc->ofs ensures that we won't consume extra
+ * space for indirect blocks in the future, which we cannot reserve */
+ if (!this_wc->ofs || ptr_change(this_wc->ofs, ipage))
+ ret = logfs_write_i0(inode, ipage, this_wc);
+ else
+ logfs_set_alias(inode->i_sb, logfs_block(ipage), child_no);
+out:
+ logfs_put_write_page(ipage);
+ return ret;
+}
+
+static int logfs_write_rec(struct inode *inode, struct page *page,
+ pgoff_t bix, level_t target_level, long flags)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ struct write_control wc = {
+ .ofs = li->li_data[INDIRECT_INDEX],
+ .flags = flags,
+ };
+ int ret;
+
+ alloc_inode_block(inode);
+
+ if (li->li_height > (__force u8)target_level)
+ ret = __logfs_write_rec(inode, page, &wc, bix, target_level,
+ LEVEL(li->li_height));
+ else
+ ret = logfs_write_i0(inode, page, &wc);
+ if (ret)
+ return ret;
+
+ if (li->li_data[INDIRECT_INDEX] != wc.ofs) {
+ li->li_data[INDIRECT_INDEX] = wc.ofs;
+ logfs_set_alias(inode->i_sb, li->li_block,
+ INDIRECT_INDEX + INODE_POINTER_OFS);
+ }
+ return ret;
+}
+
+void logfs_add_transaction(struct inode *inode, struct logfs_transaction *ta)
+{
+ alloc_inode_block(inode);
+ logfs_inode(inode)->li_block->ta = ta;
+}
+
+void logfs_del_transaction(struct inode *inode, struct logfs_transaction *ta)
+{
+ struct logfs_block *block = logfs_inode(inode)->li_block;
+
+ if (block && block->ta)
+ block->ta = NULL;
+}
+
+static int grow_inode(struct inode *inode, u64 bix, level_t level)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ u8 height = (__force u8)level;
+ struct page *page;
+ struct write_control wc = {
+ .flags = WF_WRITE,
+ };
+ int err;
+
+ BUG_ON(height > 5 || li->li_height > 5);
+ while (height > li->li_height || bix >= maxbix(li->li_height)) {
+ page = logfs_get_write_page(inode, I0_BLOCKS + 1,
+ LEVEL(li->li_height + 1));
+ if (!page)
+ return -ENOMEM;
+ logfs_read_empty(page);
+ alloc_indirect_block(inode, page, 1);
+ block_set_pointer(page, 0, li->li_data[INDIRECT_INDEX]);
+ err = logfs_write_i0(inode, page, &wc);
+ logfs_put_write_page(page);
+ if (err)
+ return err;
+ li->li_data[INDIRECT_INDEX] = wc.ofs;
+ wc.ofs = 0;
+ li->li_height++;
+ logfs_set_alias(inode->i_sb, li->li_block, INODE_HEIGHT_OFS);
+ }
+ return 0;
+}
+
+static int __logfs_write_buf(struct inode *inode, struct page *page, long flags)
+{
+ struct logfs_super *super = logfs_super(inode->i_sb);
+ pgoff_t index = page->index;
+ u64 bix;
+ level_t level;
+ int err;
+
+ flags |= WF_WRITE | WF_DELETE;
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
+ logfs_unpack_index(index, &bix, &level);
+ if (logfs_block(page) && logfs_block(page)->reserved_bytes)
+ super->s_dirty_pages -= logfs_block(page)->reserved_bytes;
+
+ if (index < I0_BLOCKS)
+ return logfs_write_direct(inode, page, flags);
+
+ bix = adjust_bix(bix, level);
+ err = grow_inode(inode, bix, level);
+ if (err)
+ return err;
+ return logfs_write_rec(inode, page, bix, level, flags);
+}
+
+int logfs_write_buf(struct inode *inode, struct page *page, long flags)
+{
+ struct super_block *sb = inode->i_sb;
+ int ret;
+
+ logfs_get_wblocks(sb, page, flags & WF_LOCK);
+ ret = __logfs_write_buf(inode, page, flags);
+ logfs_put_wblocks(sb, page, flags & WF_LOCK);
+ return ret;
+}
+
+static int __logfs_delete(struct inode *inode, struct page *page)
+{
+ long flags = WF_DELETE;
+
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
+ if (page->index < I0_BLOCKS)
+ return logfs_write_direct(inode, page, flags);
+ return logfs_write_rec(inode, page, page->index, 0, flags);
+}
+
+int logfs_delete(struct inode *inode, pgoff_t index,
+ struct shadow_tree *shadow_tree)
+{
+ struct super_block *sb = inode->i_sb;
+ struct page *page;
+ int ret;
+
+ page = logfs_get_read_page(inode, index, 0);
+ if (!page)
+ return -ENOMEM;
+
+ logfs_get_wblocks(sb, page, 1);
+ ret = __logfs_delete(inode, page);
+ logfs_put_wblocks(sb, page, 1);
+
+ logfs_put_read_page(page);
+
+ return ret;
+}
+
+int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
+ gc_level_t gc_level, long flags)
+{
+ level_t level = shrink_level(gc_level);
+ struct page *page;
+ int err;
+
+ page = logfs_get_write_page(inode, bix, level);
+ if (!page)
+ return -ENOMEM;
+
+ err = logfs_segment_read(inode, page, ofs, bix, level);
+ if (!err) {
+ if (level != 0)
+ alloc_indirect_block(inode, page, 0);
+ err = logfs_write_buf(inode, page, flags);
+ if (!err && shrink_level(gc_level) == 0) {
+ /* Rewrite cannot mark the inode dirty but has to
+ * write it immediatly.
+ * Q: Can't we just create an alias for the inode
+ * instead? And if not, why not?
+ */
+ if (inode->i_ino == LOGFS_INO_MASTER)
+ logfs_write_anchor(inode->i_sb);
+ else {
+ err = __logfs_write_inode(inode, flags);
+ }
+ }
+ }
+ logfs_put_write_page(page);
+ return err;
+}
+
+static int truncate_data_block(struct inode *inode, struct page *page,
+ u64 ofs, struct logfs_shadow *shadow, u64 size)
+{
+ loff_t pageofs = page->index << inode->i_sb->s_blocksize_bits;
+ u64 bix;
+ level_t level;
+ int err;
+
+ /* Does truncation happen within this page? */
+ if (size <= pageofs || size - pageofs >= PAGE_SIZE)
+ return 0;
+
+ logfs_unpack_index(page->index, &bix, &level);
+ BUG_ON(level != 0);
+
+ err = logfs_segment_read(inode, page, ofs, bix, level);
+ if (err)
+ return err;
+
+ zero_user_segment(page, size - pageofs, PAGE_CACHE_SIZE);
+ return logfs_segment_write(inode, page, shadow);
+}
+
+static int logfs_truncate_i0(struct inode *inode, struct page *page,
+ struct write_control *wc, u64 size)
+{
+ struct logfs_shadow *shadow;
+ u64 bix;
+ level_t level;
+ int err = 0;
+
+ logfs_unpack_index(page->index, &bix, &level);
+ BUG_ON(level != 0);
+ shadow = alloc_shadow(inode, bix, level, wc->ofs);
+
+ err = truncate_data_block(inode, page, wc->ofs, shadow, size);
+ if (err) {
+ free_shadow(inode, shadow);
+ return err;
+ }
+
+ logfs_segment_delete(inode, shadow);
+ set_iused(inode, shadow);
+ fill_shadow_tree(inode, page, shadow);
+ wc->ofs = shadow->new_ofs;
+ return 0;
+}
+
+static int logfs_truncate_direct(struct inode *inode, u64 size)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ struct write_control wc;
+ struct page *page;
+ int e;
+ int err;
+
+ alloc_inode_block(inode);
+
+ for (e = I0_BLOCKS - 1; e >= 0; e--) {
+ if (size > (e+1) * LOGFS_BLOCKSIZE)
+ break;
+
+ wc.ofs = li->li_data[e];
+ if (!wc.ofs)
+ continue;
+
+ page = logfs_get_write_page(inode, e, 0);
+ if (!page)
+ return -ENOMEM;
+ err = logfs_segment_read(inode, page, wc.ofs, e, 0);
+ if (err) {
+ logfs_put_write_page(page);
+ return err;
+ }
+ err = logfs_truncate_i0(inode, page, &wc, size);
+ logfs_put_write_page(page);
+ if (err)
+ return err;
+
+ li->li_data[e] = wc.ofs;
+ }
+ return 0;
+}
+
+/* FIXME: these need to become per-sb once we support different blocksizes */
+static u64 __logfs_step[] = {
+ 1,
+ I1_BLOCKS,
+ I2_BLOCKS,
+ I3_BLOCKS,
+};
+
+static u64 __logfs_start_index[] = {
+ I0_BLOCKS,
+ I1_BLOCKS,
+ I2_BLOCKS,
+ I3_BLOCKS
+};
+
+static inline u64 logfs_step(level_t level)
+{
+ return __logfs_step[(__force u8)level];
+}
+
+static inline u64 logfs_factor(u8 level)
+{
+ return __logfs_step[level] * LOGFS_BLOCKSIZE;
+}
+
+static inline u64 logfs_start_index(level_t level)
+{
+ return __logfs_start_index[(__force u8)level];
+}
+
+static void logfs_unpack_raw_index(pgoff_t index, u64 *bix, level_t *level)
+{
+ logfs_unpack_index(index, bix, level);
+ if (*bix <= logfs_start_index(SUBLEVEL(*level)))
+ *bix = 0;
+}
+
+static int __logfs_truncate_rec(struct inode *inode, struct page *ipage,
+ struct write_control *this_wc, u64 size)
+{
+ int truncate_happened = 0;
+ int e, err = 0;
+ u64 bix, child_bix, next_bix;
+ level_t level;
+ struct page *page;
+ struct write_control child_wc = { /* FIXME: flags */ };
+
+ logfs_unpack_raw_index(ipage->index, &bix, &level);
+ err = logfs_segment_read(inode, ipage, this_wc->ofs, bix, level);
+ if (err)
+ return err;
+
+ for (e = LOGFS_BLOCK_FACTOR - 1; e >= 0; e--) {
+ child_bix = bix + e * logfs_step(SUBLEVEL(level));
+ next_bix = child_bix + logfs_step(SUBLEVEL(level));
+ if (size > next_bix * LOGFS_BLOCKSIZE)
+ break;
+
+ child_wc.ofs = pure_ofs(block_get_pointer(ipage, e));
+ if (!child_wc.ofs)
+ continue;
+
+ page = logfs_get_write_page(inode, child_bix, SUBLEVEL(level));
+ if (!page)
+ return -ENOMEM;
+
+ if ((__force u8)level > 1)
+ err = __logfs_truncate_rec(inode, page, &child_wc, size);
+ else
+ err = logfs_truncate_i0(inode, page, &child_wc, size);
+ logfs_put_write_page(page);
+ if (err)
+ return err;
+
+ truncate_happened = 1;
+ alloc_indirect_block(inode, ipage, 0);
+ block_set_pointer(ipage, e, child_wc.ofs);
+ }
+
+ if (!truncate_happened) {
+ printk("ineffectual truncate (%lx, %lx, %llx)\n", inode->i_ino, ipage->index, size);
+ return 0;
+ }
+
+ this_wc->flags = WF_DELETE;
+ if (logfs_block(ipage)->partial)
+ this_wc->flags |= WF_WRITE;
+
+ return logfs_write_i0(inode, ipage, this_wc);
+}
+
+static int logfs_truncate_rec(struct inode *inode, u64 size)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ struct write_control wc = {
+ .ofs = li->li_data[INDIRECT_INDEX],
+ };
+ struct page *page;
+ int err;
+
+ alloc_inode_block(inode);
+
+ if (!wc.ofs)
+ return 0;
+
+ page = logfs_get_write_page(inode, 0, LEVEL(li->li_height));
+ if (!page)
+ return -ENOMEM;
+
+ err = __logfs_truncate_rec(inode, page, &wc, size);
+ logfs_put_write_page(page);
+ if (err)
+ return err;
+
+ if (li->li_data[INDIRECT_INDEX] != wc.ofs)
+ li->li_data[INDIRECT_INDEX] = wc.ofs;
+ return 0;
+}
+
+static int __logfs_truncate(struct inode *inode, u64 size)
+{
+ int ret;
+
+ if (size >= logfs_factor(logfs_inode(inode)->li_height))
+ return 0;
+
+ ret = logfs_truncate_rec(inode, size);
+ if (ret)
+ return ret;
+
+ return logfs_truncate_direct(inode, size);
+}
+
+/*
+ * Truncate, by changing the segment file, can consume a fair amount
+ * of resources. So back off from time to time and do some GC.
+ * 8 or 2048 blocks should be well within safety limits even if
+ * every single block resided in a different segment.
+ */
+#define TRUNCATE_STEP (8 * 1024 * 1024)
+int logfs_truncate(struct inode *inode, u64 target)
+{
+ struct super_block *sb = inode->i_sb;
+ u64 size = i_size_read(inode);
+ int err = 0;
+
+ size = ALIGN(size, TRUNCATE_STEP);
+ while (size > target) {
+ if (size > TRUNCATE_STEP)
+ size -= TRUNCATE_STEP;
+ else
+ size = 0;
+ if (size < target)
+ size = target;
+
+ logfs_get_wblocks(sb, NULL, 1);
+ err = __logfs_truncate(inode, target);
+ if (!err)
+ err = __logfs_write_inode(inode, 0);
+ logfs_put_wblocks(sb, NULL, 1);
+ }
+
+ if (!err)
+ err = vmtruncate(inode, target);
+
+ /* I don't trust error recovery yet. */
+ WARN_ON(err);
+ return err;
+}
+
+static void move_page_to_inode(struct inode *inode, struct page *page)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ struct logfs_block *block = logfs_block(page);
+
+ if (!block)
+ return;
+
+ log_blockmove("move_page_to_inode(%llx, %llx, %x)\n",
+ block->ino, block->bix, block->level);
+ BUG_ON(li->li_block);
+ block->ops = &inode_block_ops;
+ block->inode = inode;
+ li->li_block = block;
+
+ block->page = NULL;
+ page->private = 0;
+ ClearPagePrivate(page);
+}
+
+static void move_inode_to_page(struct page *page, struct inode *inode)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+ struct logfs_block *block = li->li_block;
+
+ if (!block)
+ return;
+
+ log_blockmove("move_inode_to_page(%llx, %llx, %x)\n",
+ block->ino, block->bix, block->level);
+ BUG_ON(PagePrivate(page));
+ block->ops = &indirect_block_ops;
+ block->page = page;
+ page->private = (unsigned long)block;
+ SetPagePrivate(page);
+
+ block->inode = NULL;
+ li->li_block = NULL;
+}
+
+int logfs_read_inode(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ struct logfs_super *super = logfs_super(sb);
+ struct inode *master_inode = super->s_master_inode;
+ struct page *page;
+ struct logfs_disk_inode *di;
+ u64 ino = inode->i_ino;
+
+ if (ino << sb->s_blocksize_bits > i_size_read(master_inode))
+ return -ENODATA;
+ if (!logfs_exist_block(master_inode, ino))
+ return -ENODATA;
+
+ page = read_cache_page(master_inode->i_mapping, ino,
+ (filler_t *)logfs_readpage, NULL);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
+
+ di = kmap_atomic(page, KM_USER0);
+ logfs_disk_to_inode(di, inode);
+ kunmap_atomic(di, KM_USER0);
+ move_page_to_inode(inode, page);
+ page_cache_release(page);
+ return 0;
+}
+
+/* Caller must logfs_put_write_page(page); */
+static struct page *inode_to_page(struct inode *inode)
+{
+ struct inode *master_inode = logfs_super(inode->i_sb)->s_master_inode;
+ struct logfs_disk_inode *di;
+ struct page *page;
+
+ BUG_ON(inode->i_ino == LOGFS_INO_MASTER);
+
+ page = logfs_get_write_page(master_inode, inode->i_ino, 0);
+ if (!page)
+ return NULL;
+
+ di = kmap_atomic(page, KM_USER0);
+ logfs_inode_to_disk(inode, di);
+ kunmap_atomic(di, KM_USER0);
+ move_inode_to_page(page, 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;
+ struct inode *master_inode = logfs_super(sb)->s_master_inode;
+ loff_t size = (inode->i_ino + 1) << inode->i_sb->s_blocksize_bits;
+ struct page *page;
+ int err;
+
+ BUG_ON(inode->i_ino == LOGFS_INO_MASTER);
+ /* FIXME: lock inode */
+
+ if (i_size_read(master_inode) < size)
+ i_size_write(master_inode, size);
+
+ /* TODO: Tell vfs this inode is clean now */
+
+ page = inode_to_page(inode);
+ if (!page)
+ return -ENOMEM;
+
+ /* FIXME: transaction is part of logfs_block now. Is that enough? */
+ err = logfs_write_buf(master_inode, page, 0);
+ logfs_put_write_page(page);
+ return err;
+}
+
+static void logfs_mod_segment_entry(struct super_block *sb, u32 segno,
+ int write,
+ void (*change_se)(struct logfs_segment_entry *, long),
+ long arg)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct inode *inode;
+ struct page *page;
+ struct logfs_segment_entry *se;
+ pgoff_t page_no;
+ int child_no;
+
+ page_no = segno >> (sb->s_blocksize_bits - 3);
+ child_no = segno & ((sb->s_blocksize >> 3) - 1);
+
+ inode = super->s_segfile_inode;
+ page = logfs_get_write_page(inode, page_no, 0);
+ BUG_ON(!page); /* FIXME: We need some reserve page for this case */
+ if (!PageUptodate(page))
+ logfs_read_block(inode, page, WRITE);
+
+ if (write)
+ alloc_indirect_block(inode, page, 0);
+ se = kmap_atomic(page, KM_USER0);
+ change_se(se + child_no, arg);
+ if (write) {
+ logfs_set_alias(sb, logfs_block(page), child_no);
+ BUG_ON((int)be32_to_cpu(se[child_no].valid) > super->s_segsize);
+ }
+ kunmap_atomic(se, KM_USER0);
+
+ logfs_put_write_page(page);
+}
+
+static void __get_segment_entry(struct logfs_segment_entry *se, long _target)
+{
+ struct logfs_segment_entry *target = (void *)_target;
+
+ *target = *se;
+}
+
+void logfs_get_segment_entry(struct super_block *sb, u32 segno,
+ struct logfs_segment_entry *se)
+{
+ logfs_mod_segment_entry(sb, segno, 0, __get_segment_entry, (long)se);
+}
+
+static void __set_segment_used(struct logfs_segment_entry *se, long increment)
+{
+ u32 valid;
+
+ valid = be32_to_cpu(se->valid);
+ valid += increment;
+ se->valid = cpu_to_be32(valid);
+}
+
+void logfs_set_segment_used(struct super_block *sb, u64 ofs, int increment)
+{
+ struct logfs_super *super = logfs_super(sb);
+ u32 segno = ofs >> super->s_segshift;
+
+ if (!increment)
+ return;
+
+ logfs_mod_segment_entry(sb, segno, 1, __set_segment_used, increment);
+}
+
+static void __set_segment_erased(struct logfs_segment_entry *se, long ec_level)
+{
+ se->ec_level = cpu_to_be32(ec_level);
+}
+
+void logfs_set_segment_erased(struct super_block *sb, u32 segno, u32 ec,
+ gc_level_t gc_level)
+{
+ u32 ec_level = ec << 4 | (__force u8)gc_level;
+
+ logfs_mod_segment_entry(sb, segno, 1, __set_segment_erased, ec_level);
+}
+
+static void __set_segment_reserved(struct logfs_segment_entry *se, long ignore)
+{
+ se->valid = cpu_to_be32(RESERVED);
+}
+
+void logfs_set_segment_reserved(struct super_block *sb, u32 segno)
+{
+ logfs_mod_segment_entry(sb, segno, 1, __set_segment_reserved, 0);
+}
+
+static void __set_segment_unreserved(struct logfs_segment_entry *se,
+ long ec_level)
+{
+ se->valid = 0;
+ se->ec_level = cpu_to_be32(ec_level);
+}
+
+void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec)
+{
+ u32 ec_level = ec << 4;
+
+ logfs_mod_segment_entry(sb, segno, 1, __set_segment_unreserved,
+ ec_level);
+}
+
+int __logfs_write_inode(struct inode *inode, long flags)
+{
+ struct super_block *sb = inode->i_sb;
+ int ret;
+
+ logfs_get_wblocks(sb, NULL, flags & WF_LOCK);
+ ret = do_write_inode(inode);
+ logfs_put_wblocks(sb, NULL, flags & WF_LOCK);
+ return ret;
+}
+
+static int do_delete_inode(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ struct inode *master_inode = logfs_super(sb)->s_master_inode;
+ struct page *page;
+ int ret;
+
+ page = logfs_get_write_page(master_inode, inode->i_ino, 0);
+ if (!page)
+ return -ENOMEM;
+
+ move_inode_to_page(page, inode);
+
+ logfs_get_wblocks(sb, page, 1);
+ ret = __logfs_delete(master_inode, page);
+ logfs_put_wblocks(sb, page, 1);
+
+ logfs_put_write_page(page);
+ return ret;
+}
+
+/*
+ * 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)
+{
+ struct logfs_inode *li = logfs_inode(inode);
+
+ 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);
+}
+
+void btree_write_block(struct logfs_block *block)
+{
+ struct inode *inode;
+ struct page *page;
+ int err, cookie;
+
+ inode = logfs_safe_iget(block->sb, block->ino, &cookie);
+ page = logfs_get_write_page(inode, block->bix, block->level);
+
+ err = logfs_readpage_nolock(page);
+ BUG_ON(err);
+ BUG_ON(!PagePrivate(page));
+ BUG_ON(logfs_block(page) != block);
+ err = __logfs_write_buf(inode, page, 0);
+ BUG_ON(err);
+ BUG_ON(PagePrivate(page) || page->private);
+
+ logfs_put_write_page(page);
+ logfs_safe_iput(inode, cookie);
+}
+
+/**
+ * logfs_inode_write - write inode or dentry objects
+ *
+ * @inode: parent inode (ifile or directory)
+ * @buf: object to write (inode or dentry)
+ * @n: object size
+ * @_pos: object number (file position in blocks/objects)
+ * @flags: write flags
+ * @lock: 0 if write lock is already taken, 1 otherwise
+ * @shadow_tree: shadow below this inode
+ *
+ * FIXME: All caller of this put a 200-300 byte variable on the stack,
+ * only to call here and do a memcpy from that stack variable. A good
+ * example of wasted performance and stack space.
+ */
+int logfs_inode_write(struct inode *inode, const void *buf, size_t count,
+ loff_t bix, long flags, struct shadow_tree *shadow_tree)
+{
+ loff_t pos = bix << inode->i_sb->s_blocksize_bits;
+ int err;
+ struct page *page;
+ void *pagebuf;
+
+ BUG_ON(pos & (LOGFS_BLOCKSIZE-1));
+ BUG_ON(count > LOGFS_BLOCKSIZE);
+ page = logfs_get_write_page(inode, bix, 0);
+ if (!page)
+ return -ENOMEM;
+
+ pagebuf = kmap_atomic(page, KM_USER0);
+ memcpy(pagebuf, buf, count);
+ flush_dcache_page(page);
+ kunmap_atomic(pagebuf, KM_USER0);
+
+ if (i_size_read(inode) < pos + LOGFS_BLOCKSIZE)
+ i_size_write(inode, pos + LOGFS_BLOCKSIZE);
+
+ err = logfs_write_buf(inode, page, flags);
+ logfs_put_write_page(page);
+ return err;
+}
+
+int logfs_open_segfile(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct inode *inode;
+
+ inode = logfs_read_meta_inode(sb, LOGFS_INO_SEGFILE);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+ super->s_segfile_inode = inode;
+ return 0;
+}
+
+int logfs_init_rw(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int min_fill = 3 * super->s_no_blocks;
+
+ INIT_LIST_HEAD(&super->s_object_alias);
+ mutex_init(&super->s_write_mutex);
+ super->s_block_pool = mempool_create_kmalloc_pool(min_fill,
+ sizeof(struct logfs_block));
+ super->s_shadow_pool = mempool_create_kmalloc_pool(min_fill,
+ sizeof(struct logfs_shadow));
+ return 0;
+}
+
+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
new file mode 100644
index 00000000000..f77ce2b470b
--- /dev/null
+++ b/fs/logfs/segment.c
@@ -0,0 +1,930 @@
+/*
+ * fs/logfs/segment.c - Handling the Object Store
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ *
+ * Object store or ostore makes up the complete device with exception of
+ * the superblock and journal areas. Apart from its own metadata it stores
+ * three kinds of objects: inodes, dentries and blocks, both data and indirect.
+ */
+#include "logfs.h"
+#include <linux/slab.h>
+
+static int logfs_mark_segment_bad(struct super_block *sb, u32 segno)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct btree_head32 *head = &super->s_reserved_segments;
+ int err;
+
+ err = btree_insert32(head, segno, (void *)1, GFP_NOFS);
+ if (err)
+ return err;
+ logfs_super(sb)->s_bad_segments++;
+ /* FIXME: write to journal */
+ return 0;
+}
+
+int logfs_erase_segment(struct super_block *sb, u32 segno, int ensure_erase)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ super->s_gec++;
+
+ return super->s_devops->erase(sb, (u64)segno << super->s_segshift,
+ super->s_segsize, ensure_erase);
+}
+
+static s64 logfs_get_free_bytes(struct logfs_area *area, size_t bytes)
+{
+ s32 ofs;
+
+ logfs_open_area(area, bytes);
+
+ ofs = area->a_used_bytes;
+ area->a_used_bytes += bytes;
+ BUG_ON(area->a_used_bytes >= logfs_super(area->a_sb)->s_segsize);
+
+ return dev_ofs(area->a_sb, area->a_segno, ofs);
+}
+
+static struct page *get_mapping_page(struct super_block *sb, pgoff_t index,
+ int use_filler)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ filler_t *filler = super->s_devops->readpage;
+ struct page *page;
+
+ BUG_ON(mapping_gfp_mask(mapping) & __GFP_FS);
+ if (use_filler)
+ page = read_cache_page(mapping, index, filler, sb);
+ else {
+ page = find_or_create_page(mapping, index, GFP_NOFS);
+ unlock_page(page);
+ }
+ return page;
+}
+
+void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
+ int use_filler)
+{
+ pgoff_t index = ofs >> PAGE_SHIFT;
+ struct page *page;
+ long offset = ofs & (PAGE_SIZE-1);
+ long copylen;
+
+ /* Only logfs_wbuf_recover may use len==0 */
+ BUG_ON(!len && !use_filler);
+ do {
+ copylen = min((ulong)len, PAGE_SIZE - offset);
+
+ page = get_mapping_page(area->a_sb, index, use_filler);
+ SetPageUptodate(page);
+ BUG_ON(!page); /* FIXME: reserve a pool */
+ memcpy(page_address(page) + offset, buf, copylen);
+ SetPagePrivate(page);
+ page_cache_release(page);
+
+ buf += copylen;
+ len -= copylen;
+ offset = 0;
+ index++;
+ } while (len);
+}
+
+static void pad_partial_page(struct logfs_area *area)
+{
+ struct super_block *sb = area->a_sb;
+ struct page *page;
+ u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
+ pgoff_t index = ofs >> PAGE_SHIFT;
+ long offset = ofs & (PAGE_SIZE-1);
+ u32 len = PAGE_SIZE - offset;
+
+ if (len % PAGE_SIZE) {
+ page = get_mapping_page(sb, index, 0);
+ BUG_ON(!page); /* FIXME: reserve a pool */
+ memset(page_address(page) + offset, 0xff, len);
+ SetPagePrivate(page);
+ page_cache_release(page);
+ }
+}
+
+static void pad_full_pages(struct logfs_area *area)
+{
+ struct super_block *sb = area->a_sb;
+ struct logfs_super *super = logfs_super(sb);
+ u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
+ u32 len = super->s_segsize - area->a_used_bytes;
+ pgoff_t index = PAGE_CACHE_ALIGN(ofs) >> PAGE_CACHE_SHIFT;
+ pgoff_t no_indizes = len >> PAGE_CACHE_SHIFT;
+ struct page *page;
+
+ while (no_indizes) {
+ page = get_mapping_page(sb, index, 0);
+ BUG_ON(!page); /* FIXME: reserve a pool */
+ SetPageUptodate(page);
+ memset(page_address(page), 0xff, PAGE_CACHE_SIZE);
+ SetPagePrivate(page);
+ page_cache_release(page);
+ index++;
+ no_indizes--;
+ }
+}
+
+/*
+ * bdev_writeseg will write full pages. Memset the tail to prevent data leaks.
+ * Also make sure we allocate (and memset) all pages for final writeout.
+ */
+static void pad_wbuf(struct logfs_area *area, int final)
+{
+ pad_partial_page(area);
+ if (final)
+ pad_full_pages(area);
+}
+
+/*
+ * We have to be careful with the alias tree. Since lookup is done by bix,
+ * it needs to be normalized, so 14, 15, 16, etc. all match when dealing with
+ * indirect blocks. So always use it through accessor functions.
+ */
+static void *alias_tree_lookup(struct super_block *sb, u64 ino, u64 bix,
+ level_t level)
+{
+ struct btree_head128 *head = &logfs_super(sb)->s_object_alias_tree;
+ pgoff_t index = logfs_pack_index(bix, level);
+
+ return btree_lookup128(head, ino, index);
+}
+
+static int alias_tree_insert(struct super_block *sb, u64 ino, u64 bix,
+ level_t level, void *val)
+{
+ struct btree_head128 *head = &logfs_super(sb)->s_object_alias_tree;
+ pgoff_t index = logfs_pack_index(bix, level);
+
+ return btree_insert128(head, ino, index, val, GFP_NOFS);
+}
+
+static int btree_write_alias(struct super_block *sb, struct logfs_block *block,
+ write_alias_t *write_one_alias)
+{
+ struct object_alias_item *item;
+ int err;
+
+ list_for_each_entry(item, &block->item_list, list) {
+ err = write_alias_journal(sb, block->ino, block->bix,
+ block->level, item->child_no, item->val);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static struct logfs_block_ops btree_block_ops = {
+ .write_block = btree_write_block,
+ .free_block = __free_block,
+ .write_alias = btree_write_alias,
+};
+
+int logfs_load_object_aliases(struct super_block *sb,
+ struct logfs_obj_alias *oa, int count)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_block *block;
+ struct object_alias_item *item;
+ u64 ino, bix;
+ level_t level;
+ int i, err;
+
+ super->s_flags |= LOGFS_SB_FLAG_OBJ_ALIAS;
+ count /= sizeof(*oa);
+ for (i = 0; i < count; i++) {
+ item = mempool_alloc(super->s_alias_pool, GFP_NOFS);
+ if (!item)
+ return -ENOMEM;
+ memset(item, 0, sizeof(*item));
+
+ super->s_no_object_aliases++;
+ item->val = oa[i].val;
+ item->child_no = be16_to_cpu(oa[i].child_no);
+
+ ino = be64_to_cpu(oa[i].ino);
+ bix = be64_to_cpu(oa[i].bix);
+ level = LEVEL(oa[i].level);
+
+ log_aliases("logfs_load_object_aliases(%llx, %llx, %x, %x) %llx\n",
+ ino, bix, level, item->child_no,
+ be64_to_cpu(item->val));
+ block = alias_tree_lookup(sb, ino, bix, level);
+ if (!block) {
+ block = __alloc_block(sb, ino, bix, level);
+ block->ops = &btree_block_ops;
+ err = alias_tree_insert(sb, ino, bix, level, block);
+ BUG_ON(err); /* mempool empty */
+ }
+ if (test_and_set_bit(item->child_no, block->alias_map)) {
+ printk(KERN_ERR"LogFS: Alias collision detected\n");
+ return -EIO;
+ }
+ list_move_tail(&block->alias_list, &super->s_object_alias);
+ list_add(&item->list, &block->item_list);
+ }
+ return 0;
+}
+
+static void kill_alias(void *_block, unsigned long ignore0,
+ u64 ignore1, u64 ignore2, size_t ignore3)
+{
+ struct logfs_block *block = _block;
+ struct super_block *sb = block->sb;
+ struct logfs_super *super = logfs_super(sb);
+ struct object_alias_item *item;
+
+ while (!list_empty(&block->item_list)) {
+ item = list_entry(block->item_list.next, typeof(*item), list);
+ list_del(&item->list);
+ mempool_free(item, super->s_alias_pool);
+ }
+ block->ops->free_block(sb, block);
+}
+
+static int obj_type(struct inode *inode, level_t level)
+{
+ if (level == 0) {
+ if (S_ISDIR(inode->i_mode))
+ return OBJ_DENTRY;
+ if (inode->i_ino == LOGFS_INO_MASTER)
+ return OBJ_INODE;
+ }
+ return OBJ_BLOCK;
+}
+
+static int obj_len(struct super_block *sb, int obj_type)
+{
+ switch (obj_type) {
+ case OBJ_DENTRY:
+ return sizeof(struct logfs_disk_dentry);
+ case OBJ_INODE:
+ return sizeof(struct logfs_disk_inode);
+ case OBJ_BLOCK:
+ return sb->s_blocksize;
+ default:
+ BUG();
+ }
+}
+
+static int __logfs_segment_write(struct inode *inode, void *buf,
+ struct logfs_shadow *shadow, int type, int len, int compr)
+{
+ struct logfs_area *area;
+ struct super_block *sb = inode->i_sb;
+ s64 ofs;
+ struct logfs_object_header h;
+ int acc_len;
+
+ if (shadow->gc_level == 0)
+ acc_len = len;
+ else
+ acc_len = obj_len(sb, type);
+
+ area = get_area(sb, shadow->gc_level);
+ ofs = logfs_get_free_bytes(area, len + LOGFS_OBJECT_HEADERSIZE);
+ LOGFS_BUG_ON(ofs <= 0, sb);
+ /*
+ * Order is important. logfs_get_free_bytes(), by modifying the
+ * segment file, may modify the content of the very page we're about
+ * to write now. Which is fine, as long as the calculated crc and
+ * written data still match. So do the modifications _before_
+ * calculating the crc.
+ */
+
+ h.len = cpu_to_be16(len);
+ h.type = type;
+ h.compr = compr;
+ h.ino = cpu_to_be64(inode->i_ino);
+ h.bix = cpu_to_be64(shadow->bix);
+ h.crc = logfs_crc32(&h, sizeof(h) - 4, 4);
+ h.data_crc = logfs_crc32(buf, len, 0);
+
+ logfs_buf_write(area, ofs, &h, sizeof(h));
+ logfs_buf_write(area, ofs + LOGFS_OBJECT_HEADERSIZE, buf, len);
+
+ shadow->new_ofs = ofs;
+ shadow->new_len = acc_len + LOGFS_OBJECT_HEADERSIZE;
+
+ return 0;
+}
+
+static s64 logfs_segment_write_compress(struct inode *inode, void *buf,
+ struct logfs_shadow *shadow, int type, int len)
+{
+ struct super_block *sb = inode->i_sb;
+ void *compressor_buf = logfs_super(sb)->s_compressed_je;
+ ssize_t compr_len;
+ int ret;
+
+ mutex_lock(&logfs_super(sb)->s_journal_mutex);
+ compr_len = logfs_compress(buf, compressor_buf, len, len);
+
+ if (compr_len >= 0) {
+ ret = __logfs_segment_write(inode, compressor_buf, shadow,
+ type, compr_len, COMPR_ZLIB);
+ } else {
+ ret = __logfs_segment_write(inode, buf, shadow, type, len,
+ COMPR_NONE);
+ }
+ mutex_unlock(&logfs_super(sb)->s_journal_mutex);
+ return ret;
+}
+
+/**
+ * logfs_segment_write - write data block to object store
+ * @inode: inode containing data
+ *
+ * Returns an errno or zero.
+ */
+int logfs_segment_write(struct inode *inode, struct page *page,
+ struct logfs_shadow *shadow)
+{
+ struct super_block *sb = inode->i_sb;
+ struct logfs_super *super = logfs_super(sb);
+ int do_compress, type, len;
+ int ret;
+ void *buf;
+
+ super->s_flags |= LOGFS_SB_FLAG_DIRTY;
+ BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
+ do_compress = logfs_inode(inode)->li_flags & LOGFS_IF_COMPRESSED;
+ if (shadow->gc_level != 0) {
+ /* temporarily disable compression for indirect blocks */
+ do_compress = 0;
+ }
+
+ type = obj_type(inode, shrink_level(shadow->gc_level));
+ len = obj_len(sb, type);
+ buf = kmap(page);
+ if (do_compress)
+ ret = logfs_segment_write_compress(inode, buf, shadow, type,
+ len);
+ else
+ ret = __logfs_segment_write(inode, buf, shadow, type, len,
+ COMPR_NONE);
+ kunmap(page);
+
+ log_segment("logfs_segment_write(%llx, %llx, %x) %llx->%llx %x->%x\n",
+ shadow->ino, shadow->bix, shadow->gc_level,
+ shadow->old_ofs, shadow->new_ofs,
+ shadow->old_len, shadow->new_len);
+ /* this BUG_ON did catch a locking bug. useful */
+ BUG_ON(!(shadow->new_ofs & (super->s_segsize - 1)));
+ return ret;
+}
+
+int wbuf_read(struct super_block *sb, u64 ofs, size_t len, void *buf)
+{
+ pgoff_t index = ofs >> PAGE_SHIFT;
+ struct page *page;
+ long offset = ofs & (PAGE_SIZE-1);
+ long copylen;
+
+ while (len) {
+ copylen = min((ulong)len, PAGE_SIZE - offset);
+
+ page = get_mapping_page(sb, index, 1);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
+ memcpy(buf, page_address(page) + offset, copylen);
+ page_cache_release(page);
+
+ buf += copylen;
+ len -= copylen;
+ offset = 0;
+ index++;
+ }
+ return 0;
+}
+
+/*
+ * The "position" of indirect blocks is ambiguous. It can be the position
+ * of any data block somewhere behind this indirect block. So we need to
+ * normalize the positions through logfs_block_mask() before comparing.
+ */
+static int check_pos(struct super_block *sb, u64 pos1, u64 pos2, level_t level)
+{
+ return (pos1 & logfs_block_mask(sb, level)) !=
+ (pos2 & logfs_block_mask(sb, level));
+}
+
+#if 0
+static int read_seg_header(struct super_block *sb, u64 ofs,
+ struct logfs_segment_header *sh)
+{
+ __be32 crc;
+ int err;
+
+ err = wbuf_read(sb, ofs, sizeof(*sh), sh);
+ if (err)
+ return err;
+ crc = logfs_crc32(sh, sizeof(*sh), 4);
+ if (crc != sh->crc) {
+ printk(KERN_ERR"LOGFS: header crc error at %llx: expected %x, "
+ "got %x\n", ofs, be32_to_cpu(sh->crc),
+ be32_to_cpu(crc));
+ return -EIO;
+ }
+ return 0;
+}
+#endif
+
+static int read_obj_header(struct super_block *sb, u64 ofs,
+ struct logfs_object_header *oh)
+{
+ __be32 crc;
+ int err;
+
+ err = wbuf_read(sb, ofs, sizeof(*oh), oh);
+ if (err)
+ return err;
+ crc = logfs_crc32(oh, sizeof(*oh) - 4, 4);
+ if (crc != oh->crc) {
+ printk(KERN_ERR"LOGFS: header crc error at %llx: expected %x, "
+ "got %x\n", ofs, be32_to_cpu(oh->crc),
+ be32_to_cpu(crc));
+ return -EIO;
+ }
+ return 0;
+}
+
+static void move_btree_to_page(struct inode *inode, struct page *page,
+ __be64 *data)
+{
+ struct super_block *sb = inode->i_sb;
+ struct logfs_super *super = logfs_super(sb);
+ struct btree_head128 *head = &super->s_object_alias_tree;
+ struct logfs_block *block;
+ struct object_alias_item *item, *next;
+
+ if (!(super->s_flags & LOGFS_SB_FLAG_OBJ_ALIAS))
+ return;
+
+ block = btree_remove128(head, inode->i_ino, page->index);
+ if (!block)
+ return;
+
+ log_blockmove("move_btree_to_page(%llx, %llx, %x)\n",
+ block->ino, block->bix, block->level);
+ list_for_each_entry_safe(item, next, &block->item_list, list) {
+ data[item->child_no] = item->val;
+ list_del(&item->list);
+ mempool_free(item, super->s_alias_pool);
+ }
+ block->page = page;
+ SetPagePrivate(page);
+ page->private = (unsigned long)block;
+ block->ops = &indirect_block_ops;
+ initialize_block_counters(page, block, data, 0);
+}
+
+/*
+ * This silences a false, yet annoying gcc warning. I hate it when my editor
+ * jumps into bitops.h each time I recompile this file.
+ * TODO: Complain to gcc folks about this and upgrade compiler.
+ */
+static unsigned long fnb(const unsigned long *addr,
+ unsigned long size, unsigned long offset)
+{
+ return find_next_bit(addr, size, offset);
+}
+
+void move_page_to_btree(struct page *page)
+{
+ struct logfs_block *block = logfs_block(page);
+ struct super_block *sb = block->sb;
+ struct logfs_super *super = logfs_super(sb);
+ struct object_alias_item *item;
+ unsigned long pos;
+ __be64 *child;
+ int err;
+
+ if (super->s_flags & LOGFS_SB_FLAG_SHUTDOWN) {
+ block->ops->free_block(sb, block);
+ return;
+ }
+ log_blockmove("move_page_to_btree(%llx, %llx, %x)\n",
+ block->ino, block->bix, block->level);
+ super->s_flags |= LOGFS_SB_FLAG_OBJ_ALIAS;
+
+ for (pos = 0; ; pos++) {
+ pos = fnb(block->alias_map, LOGFS_BLOCK_FACTOR, pos);
+ if (pos >= LOGFS_BLOCK_FACTOR)
+ break;
+
+ item = mempool_alloc(super->s_alias_pool, GFP_NOFS);
+ BUG_ON(!item); /* mempool empty */
+ memset(item, 0, sizeof(*item));
+
+ child = kmap_atomic(page, KM_USER0);
+ item->val = child[pos];
+ kunmap_atomic(child, KM_USER0);
+ item->child_no = pos;
+ list_add(&item->list, &block->item_list);
+ }
+ block->page = NULL;
+ ClearPagePrivate(page);
+ page->private = 0;
+ block->ops = &btree_block_ops;
+ err = alias_tree_insert(block->sb, block->ino, block->bix, block->level,
+ block);
+ BUG_ON(err); /* mempool empty */
+ ClearPageUptodate(page);
+}
+
+static int __logfs_segment_read(struct inode *inode, void *buf,
+ u64 ofs, u64 bix, level_t level)
+{
+ struct super_block *sb = inode->i_sb;
+ void *compressor_buf = logfs_super(sb)->s_compressed_je;
+ struct logfs_object_header oh;
+ __be32 crc;
+ u16 len;
+ int err, block_len;
+
+ block_len = obj_len(sb, obj_type(inode, level));
+ err = read_obj_header(sb, ofs, &oh);
+ if (err)
+ goto out_err;
+
+ err = -EIO;
+ if (be64_to_cpu(oh.ino) != inode->i_ino
+ || check_pos(sb, be64_to_cpu(oh.bix), bix, level)) {
+ printk(KERN_ERR"LOGFS: (ino, bix) don't match at %llx: "
+ "expected (%lx, %llx), got (%llx, %llx)\n",
+ ofs, inode->i_ino, bix,
+ be64_to_cpu(oh.ino), be64_to_cpu(oh.bix));
+ goto out_err;
+ }
+
+ len = be16_to_cpu(oh.len);
+
+ switch (oh.compr) {
+ case COMPR_NONE:
+ err = wbuf_read(sb, ofs + LOGFS_OBJECT_HEADERSIZE, len, buf);
+ if (err)
+ goto out_err;
+ crc = logfs_crc32(buf, len, 0);
+ if (crc != oh.data_crc) {
+ printk(KERN_ERR"LOGFS: uncompressed data crc error at "
+ "%llx: expected %x, got %x\n", ofs,
+ be32_to_cpu(oh.data_crc),
+ be32_to_cpu(crc));
+ goto out_err;
+ }
+ break;
+ case COMPR_ZLIB:
+ mutex_lock(&logfs_super(sb)->s_journal_mutex);
+ err = wbuf_read(sb, ofs + LOGFS_OBJECT_HEADERSIZE, len,
+ compressor_buf);
+ if (err) {
+ mutex_unlock(&logfs_super(sb)->s_journal_mutex);
+ goto out_err;
+ }
+ crc = logfs_crc32(compressor_buf, len, 0);
+ if (crc != oh.data_crc) {
+ printk(KERN_ERR"LOGFS: compressed data crc error at "
+ "%llx: expected %x, got %x\n", ofs,
+ be32_to_cpu(oh.data_crc),
+ be32_to_cpu(crc));
+ mutex_unlock(&logfs_super(sb)->s_journal_mutex);
+ goto out_err;
+ }
+ err = logfs_uncompress(compressor_buf, buf, len, block_len);
+ mutex_unlock(&logfs_super(sb)->s_journal_mutex);
+ if (err) {
+ printk(KERN_ERR"LOGFS: uncompress error at %llx\n", ofs);
+ goto out_err;
+ }
+ break;
+ default:
+ LOGFS_BUG(sb);
+ err = -EIO;
+ goto out_err;
+ }
+ return 0;
+
+out_err:
+ logfs_set_ro(sb);
+ printk(KERN_ERR"LOGFS: device is read-only now\n");
+ LOGFS_BUG(sb);
+ return err;
+}
+
+/**
+ * logfs_segment_read - read data block from object store
+ * @inode: inode containing data
+ * @buf: data buffer
+ * @ofs: physical data offset
+ * @bix: block index
+ * @level: block level
+ *
+ * Returns 0 on success or a negative errno.
+ */
+int logfs_segment_read(struct inode *inode, struct page *page,
+ u64 ofs, u64 bix, level_t level)
+{
+ int err;
+ void *buf;
+
+ if (PageUptodate(page))
+ return 0;
+
+ ofs &= ~LOGFS_FULLY_POPULATED;
+
+ buf = kmap(page);
+ err = __logfs_segment_read(inode, buf, ofs, bix, level);
+ if (!err) {
+ move_btree_to_page(inode, page, buf);
+ SetPageUptodate(page);
+ }
+ kunmap(page);
+ log_segment("logfs_segment_read(%lx, %llx, %x) %llx (%d)\n",
+ inode->i_ino, bix, level, ofs, err);
+ return err;
+}
+
+int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow)
+{
+ struct super_block *sb = inode->i_sb;
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_object_header h;
+ u16 len;
+ int err;
+
+ super->s_flags |= LOGFS_SB_FLAG_DIRTY;
+ BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
+ BUG_ON(shadow->old_ofs & LOGFS_FULLY_POPULATED);
+ if (!shadow->old_ofs)
+ return 0;
+
+ log_segment("logfs_segment_delete(%llx, %llx, %x) %llx->%llx %x->%x\n",
+ shadow->ino, shadow->bix, shadow->gc_level,
+ shadow->old_ofs, shadow->new_ofs,
+ shadow->old_len, shadow->new_len);
+ err = read_obj_header(sb, shadow->old_ofs, &h);
+ LOGFS_BUG_ON(err, sb);
+ LOGFS_BUG_ON(be64_to_cpu(h.ino) != inode->i_ino, sb);
+ LOGFS_BUG_ON(check_pos(sb, shadow->bix, be64_to_cpu(h.bix),
+ shrink_level(shadow->gc_level)), sb);
+
+ if (shadow->gc_level == 0)
+ len = be16_to_cpu(h.len);
+ else
+ len = obj_len(sb, h.type);
+ shadow->old_len = len + sizeof(h);
+ return 0;
+}
+
+void freeseg(struct super_block *sb, u32 segno)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping = super->s_mapping_inode->i_mapping;
+ struct page *page;
+ u64 ofs, start, end;
+
+ start = dev_ofs(sb, segno, 0);
+ end = dev_ofs(sb, segno + 1, 0);
+ for (ofs = start; ofs < end; ofs += PAGE_SIZE) {
+ page = find_get_page(mapping, ofs >> PAGE_SHIFT);
+ if (!page)
+ continue;
+ ClearPagePrivate(page);
+ page_cache_release(page);
+ }
+}
+
+int logfs_open_area(struct logfs_area *area, size_t bytes)
+{
+ struct super_block *sb = area->a_sb;
+ struct logfs_super *super = logfs_super(sb);
+ int err, closed = 0;
+
+ if (area->a_is_open && area->a_used_bytes + bytes <= super->s_segsize)
+ return 0;
+
+ if (area->a_is_open) {
+ u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
+ u32 len = super->s_segsize - area->a_written_bytes;
+
+ log_gc("logfs_close_area(%x)\n", area->a_segno);
+ pad_wbuf(area, 1);
+ super->s_devops->writeseg(area->a_sb, ofs, len);
+ freeseg(sb, area->a_segno);
+ closed = 1;
+ }
+
+ area->a_used_bytes = 0;
+ area->a_written_bytes = 0;
+again:
+ area->a_ops->get_free_segment(area);
+ area->a_ops->get_erase_count(area);
+
+ log_gc("logfs_open_area(%x, %x)\n", area->a_segno, area->a_level);
+ err = area->a_ops->erase_segment(area);
+ if (err) {
+ printk(KERN_WARNING "LogFS: Error erasing segment %x\n",
+ area->a_segno);
+ logfs_mark_segment_bad(sb, area->a_segno);
+ goto again;
+ }
+ area->a_is_open = 1;
+ return closed;
+}
+
+void logfs_sync_area(struct logfs_area *area)
+{
+ struct super_block *sb = area->a_sb;
+ struct logfs_super *super = logfs_super(sb);
+ u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
+ u32 len = (area->a_used_bytes - area->a_written_bytes);
+
+ if (super->s_writesize)
+ len &= ~(super->s_writesize - 1);
+ if (len == 0)
+ return;
+ pad_wbuf(area, 0);
+ super->s_devops->writeseg(sb, ofs, len);
+ area->a_written_bytes += len;
+}
+
+void logfs_sync_segments(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int i;
+
+ for_each_area(i)
+ logfs_sync_area(super->s_area[i]);
+}
+
+/*
+ * Pick a free segment to be used for this area. Effectively takes a
+ * candidate from the free list (not really a candidate anymore).
+ */
+static void ostore_get_free_segment(struct logfs_area *area)
+{
+ struct super_block *sb = area->a_sb;
+ struct logfs_super *super = logfs_super(sb);
+
+ if (super->s_free_list.count == 0) {
+ printk(KERN_ERR"LOGFS: ran out of free segments\n");
+ LOGFS_BUG(sb);
+ }
+
+ area->a_segno = get_best_cand(sb, &super->s_free_list, NULL);
+}
+
+static void ostore_get_erase_count(struct logfs_area *area)
+{
+ struct logfs_segment_entry se;
+ u32 ec_level;
+
+ logfs_get_segment_entry(area->a_sb, area->a_segno, &se);
+ BUG_ON(se.ec_level == cpu_to_be32(BADSEG) ||
+ se.valid == cpu_to_be32(RESERVED));
+
+ ec_level = be32_to_cpu(se.ec_level);
+ area->a_erase_count = (ec_level >> 4) + 1;
+}
+
+static int ostore_erase_segment(struct logfs_area *area)
+{
+ struct super_block *sb = area->a_sb;
+ struct logfs_segment_header sh;
+ u64 ofs;
+ int err;
+
+ err = logfs_erase_segment(sb, area->a_segno, 0);
+ if (err)
+ return err;
+
+ sh.pad = 0;
+ sh.type = SEG_OSTORE;
+ sh.level = (__force u8)area->a_level;
+ sh.segno = cpu_to_be32(area->a_segno);
+ sh.ec = cpu_to_be32(area->a_erase_count);
+ sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
+ sh.crc = logfs_crc32(&sh, sizeof(sh), 4);
+
+ logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count,
+ area->a_level);
+
+ ofs = dev_ofs(sb, area->a_segno, 0);
+ area->a_used_bytes = sizeof(sh);
+ logfs_buf_write(area, ofs, &sh, sizeof(sh));
+ return 0;
+}
+
+static const struct logfs_area_ops ostore_area_ops = {
+ .get_free_segment = ostore_get_free_segment,
+ .get_erase_count = ostore_get_erase_count,
+ .erase_segment = ostore_erase_segment,
+};
+
+static void free_area(struct logfs_area *area)
+{
+ if (area)
+ freeseg(area->a_sb, area->a_segno);
+ kfree(area);
+}
+
+static struct logfs_area *alloc_area(struct super_block *sb)
+{
+ struct logfs_area *area;
+
+ area = kzalloc(sizeof(*area), GFP_KERNEL);
+ if (!area)
+ return NULL;
+
+ area->a_sb = sb;
+ return area;
+}
+
+static void map_invalidatepage(struct page *page, unsigned long l)
+{
+ BUG();
+}
+
+static int map_releasepage(struct page *page, gfp_t g)
+{
+ /* Don't release these pages */
+ return 0;
+}
+
+static const struct address_space_operations mapping_aops = {
+ .invalidatepage = map_invalidatepage,
+ .releasepage = map_releasepage,
+ .set_page_dirty = __set_page_dirty_nobuffers,
+};
+
+int logfs_init_mapping(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct address_space *mapping;
+ struct inode *inode;
+
+ inode = logfs_new_meta_inode(sb, LOGFS_INO_MAPPING);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+ super->s_mapping_inode = inode;
+ mapping = inode->i_mapping;
+ mapping->a_ops = &mapping_aops;
+ /* Would it be possible to use __GFP_HIGHMEM as well? */
+ mapping_set_gfp_mask(mapping, GFP_NOFS);
+ return 0;
+}
+
+int logfs_init_areas(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int i = -1;
+
+ super->s_alias_pool = mempool_create_kmalloc_pool(600,
+ sizeof(struct object_alias_item));
+ if (!super->s_alias_pool)
+ return -ENOMEM;
+
+ super->s_journal_area = alloc_area(sb);
+ if (!super->s_journal_area)
+ goto err;
+
+ for_each_area(i) {
+ super->s_area[i] = alloc_area(sb);
+ if (!super->s_area[i])
+ goto err;
+ super->s_area[i]->a_level = GC_LEVEL(i);
+ super->s_area[i]->a_ops = &ostore_area_ops;
+ }
+ btree_init_mempool128(&super->s_object_alias_tree,
+ super->s_btree_pool);
+ return 0;
+
+err:
+ for (i--; i >= 0; i--)
+ free_area(super->s_area[i]);
+ free_area(super->s_journal_area);
+ logfs_mempool_destroy(super->s_alias_pool);
+ return -ENOMEM;
+}
+
+void logfs_cleanup_areas(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int i;
+
+ btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias);
+ 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
new file mode 100644
index 00000000000..5866ee6e132
--- /dev/null
+++ b/fs/logfs/super.c
@@ -0,0 +1,657 @@
+/*
+ * fs/logfs/super.c
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
+ *
+ * Generally contains mount/umount code and also serves as a dump area for
+ * any functions that don't fit elsewhere and neither justify a file of their
+ * own.
+ */
+#include "logfs.h"
+#include <linux/bio.h>
+#include <linux/slab.h>
+#include <linux/blkdev.h>
+#include <linux/mtd/mtd.h>
+#include <linux/statfs.h>
+#include <linux/buffer_head.h>
+
+static DEFINE_MUTEX(emergency_mutex);
+static struct page *emergency_page;
+
+struct page *emergency_read_begin(struct address_space *mapping, pgoff_t index)
+{
+ filler_t *filler = (filler_t *)mapping->a_ops->readpage;
+ struct page *page;
+ int err;
+
+ page = read_cache_page(mapping, index, filler, NULL);
+ if (page)
+ return page;
+
+ /* No more pages available, switch to emergency page */
+ printk(KERN_INFO"Logfs: Using emergency page\n");
+ mutex_lock(&emergency_mutex);
+ err = filler(NULL, emergency_page);
+ if (err) {
+ mutex_unlock(&emergency_mutex);
+ printk(KERN_EMERG"Logfs: Error reading emergency page\n");
+ return ERR_PTR(err);
+ }
+ return emergency_page;
+}
+
+void emergency_read_end(struct page *page)
+{
+ if (page == emergency_page)
+ mutex_unlock(&emergency_mutex);
+ else
+ page_cache_release(page);
+}
+
+static void dump_segfile(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_segment_entry se;
+ u32 segno;
+
+ for (segno = 0; segno < super->s_no_segs; segno++) {
+ logfs_get_segment_entry(sb, segno, &se);
+ printk("%3x: %6x %8x", segno, be32_to_cpu(se.ec_level),
+ be32_to_cpu(se.valid));
+ if (++segno < super->s_no_segs) {
+ logfs_get_segment_entry(sb, segno, &se);
+ printk(" %6x %8x", be32_to_cpu(se.ec_level),
+ be32_to_cpu(se.valid));
+ }
+ if (++segno < super->s_no_segs) {
+ logfs_get_segment_entry(sb, segno, &se);
+ printk(" %6x %8x", be32_to_cpu(se.ec_level),
+ be32_to_cpu(se.valid));
+ }
+ if (++segno < super->s_no_segs) {
+ logfs_get_segment_entry(sb, segno, &se);
+ printk(" %6x %8x", be32_to_cpu(se.ec_level),
+ be32_to_cpu(se.valid));
+ }
+ printk("\n");
+ }
+}
+
+/*
+ * logfs_crash_dump - dump debug information to device
+ *
+ * The LogFS superblock only occupies part of a segment. This function will
+ * write as much debug information as it can gather into the spare space.
+ */
+void logfs_crash_dump(struct super_block *sb)
+{
+ dump_segfile(sb);
+}
+
+/*
+ * TODO: move to lib/string.c
+ */
+/**
+ * memchr_inv - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first character other than @c, or %NULL
+ * if the whole buffer contains just @c.
+ */
+void *memchr_inv(const void *s, int c, size_t n)
+{
+ const unsigned char *p = s;
+ while (n-- != 0)
+ if ((unsigned char)c != *p++)
+ return (void *)(p - 1);
+
+ return NULL;
+}
+
+/*
+ * FIXME: There should be a reserve for root, similar to ext2.
+ */
+int logfs_statfs(struct dentry *dentry, struct kstatfs *stats)
+{
+ struct super_block *sb = dentry->d_sb;
+ struct logfs_super *super = logfs_super(sb);
+
+ stats->f_type = LOGFS_MAGIC_U32;
+ stats->f_bsize = sb->s_blocksize;
+ stats->f_blocks = super->s_size >> LOGFS_BLOCK_BITS >> 3;
+ stats->f_bfree = super->s_free_bytes >> sb->s_blocksize_bits;
+ stats->f_bavail = super->s_free_bytes >> sb->s_blocksize_bits;
+ stats->f_files = 0;
+ stats->f_ffree = 0;
+ stats->f_namelen = LOGFS_MAX_NAMELEN;
+ return 0;
+}
+
+static int logfs_sb_set(struct super_block *sb, void *_super)
+{
+ struct logfs_super *super = _super;
+
+ sb->s_fs_info = super;
+ sb->s_mtd = super->s_mtd;
+ sb->s_bdev = super->s_bdev;
+ if (sb->s_bdev)
+ sb->s_bdi = &bdev_get_queue(sb->s_bdev)->backing_dev_info;
+ if (sb->s_mtd)
+ sb->s_bdi = sb->s_mtd->backing_dev_info;
+ return 0;
+}
+
+static int logfs_sb_test(struct super_block *sb, void *_super)
+{
+ struct logfs_super *super = _super;
+ struct mtd_info *mtd = super->s_mtd;
+
+ if (mtd && sb->s_mtd == mtd)
+ return 1;
+ if (super->s_bdev && sb->s_bdev == super->s_bdev)
+ return 1;
+ return 0;
+}
+
+static void set_segment_header(struct logfs_segment_header *sh, u8 type,
+ u8 level, u32 segno, u32 ec)
+{
+ sh->pad = 0;
+ sh->type = type;
+ sh->level = level;
+ sh->segno = cpu_to_be32(segno);
+ sh->ec = cpu_to_be32(ec);
+ sh->gec = cpu_to_be64(segno);
+ sh->crc = logfs_crc32(sh, LOGFS_SEGMENT_HEADERSIZE, 4);
+}
+
+static void logfs_write_ds(struct super_block *sb, struct logfs_disk_super *ds,
+ u32 segno, u32 ec)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_segment_header *sh = &ds->ds_sh;
+ int i;
+
+ memset(ds, 0, sizeof(*ds));
+ set_segment_header(sh, SEG_SUPER, 0, segno, ec);
+
+ ds->ds_ifile_levels = super->s_ifile_levels;
+ ds->ds_iblock_levels = super->s_iblock_levels;
+ ds->ds_data_levels = super->s_data_levels; /* XXX: Remove */
+ ds->ds_segment_shift = super->s_segshift;
+ ds->ds_block_shift = sb->s_blocksize_bits;
+ ds->ds_write_shift = super->s_writeshift;
+ ds->ds_filesystem_size = cpu_to_be64(super->s_size);
+ ds->ds_segment_size = cpu_to_be32(super->s_segsize);
+ ds->ds_bad_seg_reserve = cpu_to_be32(super->s_bad_seg_reserve);
+ ds->ds_feature_incompat = cpu_to_be64(super->s_feature_incompat);
+ ds->ds_feature_ro_compat= cpu_to_be64(super->s_feature_ro_compat);
+ ds->ds_feature_compat = cpu_to_be64(super->s_feature_compat);
+ ds->ds_feature_flags = cpu_to_be64(super->s_feature_flags);
+ ds->ds_root_reserve = cpu_to_be64(super->s_root_reserve);
+ ds->ds_speed_reserve = cpu_to_be64(super->s_speed_reserve);
+ journal_for_each(i)
+ ds->ds_journal_seg[i] = cpu_to_be32(super->s_journal_seg[i]);
+ ds->ds_magic = cpu_to_be64(LOGFS_MAGIC);
+ ds->ds_crc = logfs_crc32(ds, sizeof(*ds),
+ LOGFS_SEGMENT_HEADERSIZE + 12);
+}
+
+static int write_one_sb(struct super_block *sb,
+ struct page *(*find_sb)(struct super_block *sb, u64 *ofs))
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_disk_super *ds;
+ struct logfs_segment_entry se;
+ struct page *page;
+ u64 ofs;
+ u32 ec, segno;
+ int err;
+
+ page = find_sb(sb, &ofs);
+ if (!page)
+ return -EIO;
+ ds = page_address(page);
+ segno = seg_no(sb, ofs);
+ logfs_get_segment_entry(sb, segno, &se);
+ ec = be32_to_cpu(se.ec_level) >> 4;
+ ec++;
+ logfs_set_segment_erased(sb, segno, ec, 0);
+ logfs_write_ds(sb, ds, segno, ec);
+ err = super->s_devops->write_sb(sb, page);
+ page_cache_release(page);
+ return err;
+}
+
+int logfs_write_sb(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int err;
+
+ /* First superblock */
+ err = write_one_sb(sb, super->s_devops->find_first_sb);
+ if (err)
+ return err;
+
+ /* Last superblock */
+ err = write_one_sb(sb, super->s_devops->find_last_sb);
+ if (err)
+ return err;
+ return 0;
+}
+
+static int ds_cmp(const void *ds0, const void *ds1)
+{
+ size_t len = sizeof(struct logfs_disk_super);
+
+ /* We know the segment headers differ, so ignore them */
+ len -= LOGFS_SEGMENT_HEADERSIZE;
+ ds0 += LOGFS_SEGMENT_HEADERSIZE;
+ ds1 += LOGFS_SEGMENT_HEADERSIZE;
+ return memcmp(ds0, ds1, len);
+}
+
+static int logfs_recover_sb(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct logfs_disk_super _ds0, *ds0 = &_ds0;
+ struct logfs_disk_super _ds1, *ds1 = &_ds1;
+ int err, valid0, valid1;
+
+ /* read first superblock */
+ err = wbuf_read(sb, super->s_sb_ofs[0], sizeof(*ds0), ds0);
+ if (err)
+ return err;
+ /* read last superblock */
+ err = wbuf_read(sb, super->s_sb_ofs[1], sizeof(*ds1), ds1);
+ if (err)
+ return err;
+ valid0 = logfs_check_ds(ds0) == 0;
+ valid1 = logfs_check_ds(ds1) == 0;
+
+ if (!valid0 && valid1) {
+ printk(KERN_INFO"First superblock is invalid - fixing.\n");
+ return write_one_sb(sb, super->s_devops->find_first_sb);
+ }
+ if (valid0 && !valid1) {
+ printk(KERN_INFO"Last superblock is invalid - fixing.\n");
+ return write_one_sb(sb, super->s_devops->find_last_sb);
+ }
+ if (valid0 && valid1 && ds_cmp(ds0, ds1)) {
+ printk(KERN_INFO"Superblocks don't match - fixing.\n");
+ return logfs_write_sb(sb);
+ }
+ /* If neither is valid now, something's wrong. Didn't we properly
+ * check them before?!? */
+ BUG_ON(!valid0 && !valid1);
+ return 0;
+}
+
+static int logfs_make_writeable(struct super_block *sb)
+{
+ int err;
+
+ err = logfs_open_segfile(sb);
+ if (err)
+ return err;
+
+ /* Repair any broken superblock copies */
+ err = logfs_recover_sb(sb);
+ if (err)
+ return err;
+
+ /* Check areas for trailing unaccounted data */
+ err = logfs_check_areas(sb);
+ if (err)
+ return err;
+
+ /* Do one GC pass before any data gets dirtied */
+ logfs_gc_pass(sb);
+
+ /* after all initializations are done, replay the journal
+ * for rw-mounts, if necessary */
+ err = logfs_replay_journal(sb);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct inode *rootdir;
+ int err;
+
+ /* root dir */
+ rootdir = logfs_iget(sb, LOGFS_INO_ROOT);
+ if (IS_ERR(rootdir))
+ goto fail;
+
+ sb->s_root = d_alloc_root(rootdir);
+ if (!sb->s_root)
+ goto fail2;
+
+ super->s_erase_page = alloc_pages(GFP_KERNEL, 0);
+ if (!super->s_erase_page)
+ goto fail2;
+ memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE);
+
+ /* FIXME: check for read-only mounts */
+ err = logfs_make_writeable(sb);
+ if (err)
+ goto fail3;
+
+ log_super("LogFS: Finished mounting\n");
+ simple_set_mnt(mnt, sb);
+ return 0;
+
+fail3:
+ __free_page(super->s_erase_page);
+fail2:
+ iput(rootdir);
+fail:
+ iput(logfs_super(sb)->s_master_inode);
+ return -EIO;
+}
+
+int logfs_check_ds(struct logfs_disk_super *ds)
+{
+ struct logfs_segment_header *sh = &ds->ds_sh;
+
+ if (ds->ds_magic != cpu_to_be64(LOGFS_MAGIC))
+ return -EINVAL;
+ if (sh->crc != logfs_crc32(sh, LOGFS_SEGMENT_HEADERSIZE, 4))
+ return -EINVAL;
+ if (ds->ds_crc != logfs_crc32(ds, sizeof(*ds),
+ LOGFS_SEGMENT_HEADERSIZE + 12))
+ return -EINVAL;
+ return 0;
+}
+
+static struct page *find_super_block(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct page *first, *last;
+
+ first = super->s_devops->find_first_sb(sb, &super->s_sb_ofs[0]);
+ if (!first || IS_ERR(first))
+ return NULL;
+ last = super->s_devops->find_last_sb(sb, &super->s_sb_ofs[1]);
+ if (!last || IS_ERR(first)) {
+ page_cache_release(first);
+ return NULL;
+ }
+
+ if (!logfs_check_ds(page_address(first))) {
+ page_cache_release(last);
+ return first;
+ }
+
+ /* First one didn't work, try the second superblock */
+ if (!logfs_check_ds(page_address(last))) {
+ page_cache_release(first);
+ return last;
+ }
+
+ /* Neither worked, sorry folks */
+ page_cache_release(first);
+ page_cache_release(last);
+ return NULL;
+}
+
+static int __logfs_read_sb(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ struct page *page;
+ struct logfs_disk_super *ds;
+ int i;
+
+ page = find_super_block(sb);
+ if (!page)
+ return -EIO;
+
+ ds = page_address(page);
+ super->s_size = be64_to_cpu(ds->ds_filesystem_size);
+ super->s_root_reserve = be64_to_cpu(ds->ds_root_reserve);
+ super->s_speed_reserve = be64_to_cpu(ds->ds_speed_reserve);
+ super->s_bad_seg_reserve = be32_to_cpu(ds->ds_bad_seg_reserve);
+ super->s_segsize = 1 << ds->ds_segment_shift;
+ super->s_segmask = (1 << ds->ds_segment_shift) - 1;
+ super->s_segshift = ds->ds_segment_shift;
+ sb->s_blocksize = 1 << ds->ds_block_shift;
+ sb->s_blocksize_bits = ds->ds_block_shift;
+ super->s_writesize = 1 << ds->ds_write_shift;
+ super->s_writeshift = ds->ds_write_shift;
+ super->s_no_segs = super->s_size >> super->s_segshift;
+ super->s_no_blocks = super->s_segsize >> sb->s_blocksize_bits;
+ super->s_feature_incompat = be64_to_cpu(ds->ds_feature_incompat);
+ super->s_feature_ro_compat = be64_to_cpu(ds->ds_feature_ro_compat);
+ super->s_feature_compat = be64_to_cpu(ds->ds_feature_compat);
+ super->s_feature_flags = be64_to_cpu(ds->ds_feature_flags);
+
+ journal_for_each(i)
+ super->s_journal_seg[i] = be32_to_cpu(ds->ds_journal_seg[i]);
+
+ super->s_ifile_levels = ds->ds_ifile_levels;
+ super->s_iblock_levels = ds->ds_iblock_levels;
+ super->s_data_levels = ds->ds_data_levels;
+ super->s_total_levels = super->s_ifile_levels + super->s_iblock_levels
+ + super->s_data_levels;
+ page_cache_release(page);
+ return 0;
+}
+
+static int logfs_read_sb(struct super_block *sb, int read_only)
+{
+ struct logfs_super *super = logfs_super(sb);
+ int ret;
+
+ super->s_btree_pool = mempool_create(32, btree_alloc, btree_free, NULL);
+ if (!super->s_btree_pool)
+ return -ENOMEM;
+
+ btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool);
+ btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool);
+ btree_init_mempool32(&super->s_shadow_tree.segment_map,
+ super->s_btree_pool);
+
+ ret = logfs_init_mapping(sb);
+ if (ret)
+ return ret;
+
+ ret = __logfs_read_sb(sb);
+ if (ret)
+ return ret;
+
+ if (super->s_feature_incompat & ~LOGFS_FEATURES_INCOMPAT)
+ return -EIO;
+ if ((super->s_feature_ro_compat & ~LOGFS_FEATURES_RO_COMPAT) &&
+ !read_only)
+ return -EIO;
+
+ mutex_init(&super->s_dirop_mutex);
+ mutex_init(&super->s_object_alias_mutex);
+ INIT_LIST_HEAD(&super->s_freeing_list);
+
+ ret = logfs_init_rw(sb);
+ if (ret)
+ return ret;
+
+ ret = logfs_init_areas(sb);
+ if (ret)
+ return ret;
+
+ ret = logfs_init_gc(sb);
+ if (ret)
+ return ret;
+
+ ret = logfs_init_journal(sb);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void logfs_kill_sb(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+
+ log_super("LogFS: Start unmounting\n");
+ /* Alias entries slow down mount, so evict as many as possible */
+ sync_filesystem(sb);
+ logfs_write_anchor(sb);
+
+ /*
+ * From this point on alias entries are simply dropped - and any
+ * writes to the object store are considered bugs.
+ */
+ super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN;
+ log_super("LogFS: Now in shutdown\n");
+ generic_shutdown_super(sb);
+
+ BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes);
+
+ logfs_cleanup_gc(sb);
+ logfs_cleanup_journal(sb);
+ logfs_cleanup_areas(sb);
+ logfs_cleanup_rw(sb);
+ if (super->s_erase_page)
+ __free_page(super->s_erase_page);
+ super->s_devops->put_device(sb);
+ logfs_mempool_destroy(super->s_btree_pool);
+ logfs_mempool_destroy(super->s_alias_pool);
+ kfree(super);
+ log_super("LogFS: Finished unmounting\n");
+}
+
+int logfs_get_sb_device(struct file_system_type *type, int flags,
+ struct mtd_info *mtd, struct block_device *bdev,
+ const struct logfs_device_ops *devops, struct vfsmount *mnt)
+{
+ struct logfs_super *super;
+ struct super_block *sb;
+ int err = -ENOMEM;
+ static int mount_count;
+
+ log_super("LogFS: Start mount %x\n", mount_count++);
+ super = kzalloc(sizeof(*super), GFP_KERNEL);
+ if (!super)
+ goto err0;
+
+ super->s_mtd = mtd;
+ super->s_bdev = bdev;
+ err = -EINVAL;
+ sb = sget(type, logfs_sb_test, logfs_sb_set, super);
+ if (IS_ERR(sb))
+ goto err0;
+
+ if (sb->s_root) {
+ /* Device is already in use */
+ err = 0;
+ simple_set_mnt(mnt, sb);
+ goto err0;
+ }
+
+ super->s_devops = devops;
+
+ /*
+ * sb->s_maxbytes is limited to 8TB. On 32bit systems, the page cache
+ * only covers 16TB and the upper 8TB are used for indirect blocks.
+ * On 64bit system we could bump up the limit, but that would make
+ * the filesystem incompatible with 32bit systems.
+ */
+ sb->s_maxbytes = (1ull << 43) - 1;
+ sb->s_op = &logfs_super_operations;
+ sb->s_flags = flags | MS_NOATIME;
+
+ err = logfs_read_sb(sb, sb->s_flags & MS_RDONLY);
+ if (err)
+ goto err1;
+
+ sb->s_flags |= MS_ACTIVE;
+ err = logfs_get_sb_final(sb, mnt);
+ if (err)
+ goto err1;
+ return 0;
+
+err1:
+ deactivate_locked_super(sb);
+ return err;
+err0:
+ kfree(super);
+ //devops->put_device(sb);
+ return err;
+}
+
+static int logfs_get_sb(struct file_system_type *type, int flags,
+ const char *devname, void *data, struct vfsmount *mnt)
+{
+ ulong mtdnr;
+
+ if (!devname)
+ return logfs_get_sb_bdev(type, flags, devname, mnt);
+ if (strncmp(devname, "mtd", 3))
+ return logfs_get_sb_bdev(type, flags, devname, mnt);
+
+ {
+ char *garbage;
+ mtdnr = simple_strtoul(devname+3, &garbage, 0);
+ if (*garbage)
+ return -EINVAL;
+ }
+
+ return logfs_get_sb_mtd(type, flags, mtdnr, mnt);
+}
+
+static struct file_system_type logfs_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "logfs",
+ .get_sb = logfs_get_sb,
+ .kill_sb = logfs_kill_sb,
+ .fs_flags = FS_REQUIRES_DEV,
+
+};
+
+static int __init logfs_init(void)
+{
+ int ret;
+
+ emergency_page = alloc_pages(GFP_KERNEL, 0);
+ if (!emergency_page)
+ return -ENOMEM;
+
+ ret = logfs_compr_init();
+ if (ret)
+ goto out1;
+
+ ret = logfs_init_inode_cache();
+ if (ret)
+ goto out2;
+
+ return register_filesystem(&logfs_fs_type);
+out2:
+ logfs_compr_exit();
+out1:
+ __free_pages(emergency_page, 0);
+ return ret;
+}
+
+static void __exit logfs_exit(void)
+{
+ unregister_filesystem(&logfs_fs_type);
+ logfs_destroy_inode_cache();
+ logfs_compr_exit();
+ __free_pages(emergency_page, 0);
+}
+
+module_init(logfs_init);
+module_exit(logfs_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Joern Engel <joern@logfs.org>");
+MODULE_DESCRIPTION("scalable flash filesystem");
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 74ea82d7216..756f8c93780 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -17,8 +17,10 @@
#include <linux/init.h>
#include <linux/highuid.h>
#include <linux/vfs.h>
+#include <linux/writeback.h>
-static int minix_write_inode(struct inode * inode, int wait);
+static int minix_write_inode(struct inode *inode,
+ struct writeback_control *wbc);
static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
static int minix_remount (struct super_block * sb, int * flags, char * data);
@@ -552,7 +554,7 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
return bh;
}
-static int minix_write_inode(struct inode *inode, int wait)
+static int minix_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int err = 0;
struct buffer_head *bh;
@@ -563,7 +565,7 @@ static int minix_write_inode(struct inode *inode, int wait)
bh = V2_minix_update_inode(inode);
if (!bh)
return -EIO;
- if (wait && buffer_dirty(bh)) {
+ if (wbc->sync_mode == WB_SYNC_ALL && buffer_dirty(bh)) {
sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh)) {
printk("IO error syncing minix inode [%s:%08lx]\n",
diff --git a/fs/minix/itree_v1.c b/fs/minix/itree_v1.c
index 82d6554b02f..282e15ad8cd 100644
--- a/fs/minix/itree_v1.c
+++ b/fs/minix/itree_v1.c
@@ -1,4 +1,5 @@
#include <linux/buffer_head.h>
+#include <linux/slab.h>
#include "minix.h"
enum {DEPTH = 3, DIRECT = 7}; /* Only double indirect */
diff --git a/fs/mpage.c b/fs/mpage.c
index 42381bd6543..fd56ca2ea55 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kdev_t.h>
+#include <linux/gfp.h>
#include <linux/bio.h>
#include <linux/fs.h>
#include <linux/buffer_head.h>
@@ -561,7 +562,7 @@ page_is_mapped:
if (page->index >= end_index) {
/*
* The page straddles i_size. It must be zeroed out on each
- * and every writepage invokation because it may be mmapped.
+ * and every writepage invocation because it may be mmapped.
* "A file is mapped in multiples of the page size. For a file
* that is not a multiple of the page size, the remaining memory
* is zeroed when mapped, and writes to that region are not
diff --git a/fs/namei.c b/fs/namei.c
index 0741c69b331..a7dce91a7e4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -19,7 +19,6 @@
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/namei.h>
-#include <linux/quotaops.h>
#include <linux/pagemap.h>
#include <linux/fsnotify.h>
#include <linux/personality.h>
@@ -498,8 +497,6 @@ static int link_path_walk(const char *, struct nameidata *);
static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
{
- int res = 0;
- char *name;
if (IS_ERR(link))
goto fail;
@@ -510,22 +507,7 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
path_get(&nd->root);
}
- res = link_path_walk(link, nd);
- if (nd->depth || res || nd->last_type!=LAST_NORM)
- return res;
- /*
- * If it is an iterative symlinks resolution in open_namei() we
- * have to copy the last component. And all that crap because of
- * bloody create() on broken symlinks. Furrfu...
- */
- name = __getname();
- if (unlikely(!name)) {
- path_put(&nd->path);
- return -ENOMEM;
- }
- strcpy(name, nd->last.name);
- nd->last.name = name;
- return 0;
+ return link_path_walk(link, nd);
fail:
path_put(&nd->path);
return PTR_ERR(link);
@@ -547,10 +529,10 @@ static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
nd->path.dentry = path->dentry;
}
-static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd)
+static __always_inline int
+__do_follow_link(struct path *path, struct nameidata *nd, void **p)
{
int error;
- void *cookie;
struct dentry *dentry = path->dentry;
touch_atime(path->mnt, dentry);
@@ -562,9 +544,9 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
}
mntget(path->mnt);
nd->last_type = LAST_BIND;
- cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
- error = PTR_ERR(cookie);
- if (!IS_ERR(cookie)) {
+ *p = dentry->d_inode->i_op->follow_link(dentry, nd);
+ error = PTR_ERR(*p);
+ if (!IS_ERR(*p)) {
char *s = nd_get_link(nd);
error = 0;
if (s)
@@ -574,8 +556,6 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
if (error)
path_put(&nd->path);
}
- if (dentry->d_inode->i_op->put_link)
- dentry->d_inode->i_op->put_link(dentry, nd, cookie);
}
return error;
}
@@ -589,6 +569,7 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata
*/
static inline int do_follow_link(struct path *path, struct nameidata *nd)
{
+ void *cookie;
int err = -ELOOP;
if (current->link_count >= MAX_NESTED_LINKS)
goto loop;
@@ -602,7 +583,9 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
current->link_count++;
current->total_link_count++;
nd->depth++;
- err = __do_follow_link(path, nd);
+ err = __do_follow_link(path, nd, &cookie);
+ if (!IS_ERR(cookie) && path->dentry->d_inode->i_op->put_link)
+ path->dentry->d_inode->i_op->put_link(path->dentry, nd, cookie);
path_put(path);
current->link_count--;
nd->depth--;
@@ -1375,22 +1358,6 @@ static inline int may_create(struct inode *dir, struct dentry *child)
return inode_permission(dir, MAY_WRITE | MAY_EXEC);
}
-/*
- * O_DIRECTORY translates into forcing a directory lookup.
- */
-static inline int lookup_flags(unsigned int f)
-{
- unsigned long retval = LOOKUP_FOLLOW;
-
- if (f & O_NOFOLLOW)
- retval &= ~LOOKUP_FOLLOW;
-
- if (f & O_DIRECTORY)
- retval |= LOOKUP_DIRECTORY;
-
- return retval;
-}
-
/*
* p1 and p2 should be directories on the same fs.
*/
@@ -1448,7 +1415,6 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
error = security_inode_create(dir, dentry, mode);
if (error)
return error;
- vfs_dq_init(dir);
error = dir->i_op->create(dir, dentry, mode, nd);
if (!error)
fsnotify_create(dir, dentry);
@@ -1590,129 +1556,133 @@ static int open_will_truncate(int flag, struct inode *inode)
return (flag & O_TRUNC);
}
-/*
- * Note that the low bits of the passed in "open_flag"
- * are not the same as in the local variable "flag". See
- * open_to_namei_flags() for more details.
- */
-struct file *do_filp_open(int dfd, const char *pathname,
- int open_flag, int mode, int acc_mode)
+static struct file *finish_open(struct nameidata *nd,
+ int open_flag, int acc_mode)
{
struct file *filp;
- struct nameidata nd;
- int error;
- struct path path;
- struct dentry *dir;
- int count = 0;
int will_truncate;
- int flag = open_to_namei_flags(open_flag);
- int force_reval = 0;
+ int error;
+ will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode);
+ if (will_truncate) {
+ error = mnt_want_write(nd->path.mnt);
+ if (error)
+ goto exit;
+ }
+ error = may_open(&nd->path, acc_mode, open_flag);
+ if (error) {
+ if (will_truncate)
+ mnt_drop_write(nd->path.mnt);
+ goto exit;
+ }
+ filp = nameidata_to_filp(nd);
+ if (!IS_ERR(filp)) {
+ error = ima_file_check(filp, acc_mode);
+ if (error) {
+ fput(filp);
+ filp = ERR_PTR(error);
+ }
+ }
+ if (!IS_ERR(filp)) {
+ if (will_truncate) {
+ error = handle_truncate(&nd->path);
+ if (error) {
+ fput(filp);
+ filp = ERR_PTR(error);
+ }
+ }
+ }
/*
- * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
- * check for O_DSYNC if the need any syncing at all we enforce it's
- * always set instead of having to deal with possibly weird behaviour
- * for malicious applications setting only __O_SYNC.
+ * It is now safe to drop the mnt write
+ * because the filp has had a write taken
+ * on its behalf.
*/
- if (open_flag & __O_SYNC)
- open_flag |= O_DSYNC;
-
- if (!acc_mode)
- acc_mode = MAY_OPEN | ACC_MODE(open_flag);
+ if (will_truncate)
+ mnt_drop_write(nd->path.mnt);
+ return filp;
- /* O_TRUNC implies we need access checks for write permissions */
- if (flag & O_TRUNC)
- acc_mode |= MAY_WRITE;
+exit:
+ if (!IS_ERR(nd->intent.open.file))
+ release_open_intent(nd);
+ path_put(&nd->path);
+ return ERR_PTR(error);
+}
- /* Allow the LSM permission hook to distinguish append
- access from general write access. */
- if (flag & O_APPEND)
- acc_mode |= MAY_APPEND;
+static struct file *do_last(struct nameidata *nd, struct path *path,
+ int open_flag, int acc_mode,
+ int mode, const char *pathname)
+{
+ struct dentry *dir = nd->path.dentry;
+ struct file *filp;
+ int error = -EISDIR;
- /*
- * The simplest case - just a plain lookup.
- */
- if (!(flag & O_CREAT)) {
- filp = get_empty_filp();
-
- if (filp == NULL)
- return ERR_PTR(-ENFILE);
- nd.intent.open.file = filp;
- filp->f_flags = open_flag;
- nd.intent.open.flags = flag;
- nd.intent.open.create_mode = 0;
- error = do_path_lookup(dfd, pathname,
- lookup_flags(flag)|LOOKUP_OPEN, &nd);
- if (IS_ERR(nd.intent.open.file)) {
- if (error == 0) {
- error = PTR_ERR(nd.intent.open.file);
- path_put(&nd.path);
+ switch (nd->last_type) {
+ case LAST_DOTDOT:
+ follow_dotdot(nd);
+ dir = nd->path.dentry;
+ if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) {
+ if (!dir->d_op->d_revalidate(dir, nd)) {
+ error = -ESTALE;
+ goto exit;
}
- } else if (error)
- release_open_intent(&nd);
- if (error)
- return ERR_PTR(error);
+ }
+ /* fallthrough */
+ case LAST_DOT:
+ case LAST_ROOT:
+ if (open_flag & O_CREAT)
+ goto exit;
+ /* fallthrough */
+ case LAST_BIND:
+ audit_inode(pathname, dir);
goto ok;
}
- /*
- * Create - we need to know the parent.
- */
-reval:
- error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
- if (error)
- return ERR_PTR(error);
- if (force_reval)
- nd.flags |= LOOKUP_REVAL;
- error = path_walk(pathname, &nd);
- if (error) {
- if (nd.root.mnt)
- path_put(&nd.root);
- return ERR_PTR(error);
+ /* trailing slashes? */
+ if (nd->last.name[nd->last.len]) {
+ if (open_flag & O_CREAT)
+ goto exit;
+ nd->flags |= LOOKUP_DIRECTORY;
}
- if (unlikely(!audit_dummy_context()))
- audit_inode(pathname, nd.path.dentry);
- /*
- * We have the parent and last component. First of all, check
- * that we are not asked to creat(2) an obvious directory - that
- * will not do.
- */
- error = -EISDIR;
- if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len])
- goto exit_parent;
+ /* just plain open? */
+ if (!(open_flag & O_CREAT)) {
+ error = do_lookup(nd, &nd->last, path);
+ if (error)
+ goto exit;
+ error = -ENOENT;
+ if (!path->dentry->d_inode)
+ goto exit_dput;
+ if (path->dentry->d_inode->i_op->follow_link)
+ return NULL;
+ error = -ENOTDIR;
+ if (nd->flags & LOOKUP_DIRECTORY) {
+ if (!path->dentry->d_inode->i_op->lookup)
+ goto exit_dput;
+ }
+ path_to_nameidata(path, nd);
+ audit_inode(pathname, nd->path.dentry);
+ goto ok;
+ }
- error = -ENFILE;
- filp = get_empty_filp();
- if (filp == NULL)
- goto exit_parent;
- nd.intent.open.file = filp;
- filp->f_flags = open_flag;
- nd.intent.open.flags = flag;
- nd.intent.open.create_mode = mode;
- dir = nd.path.dentry;
- nd.flags &= ~LOOKUP_PARENT;
- nd.flags |= LOOKUP_CREATE | LOOKUP_OPEN;
- if (flag & O_EXCL)
- nd.flags |= LOOKUP_EXCL;
+ /* OK, it's O_CREAT */
mutex_lock(&dir->d_inode->i_mutex);
- path.dentry = lookup_hash(&nd);
- path.mnt = nd.path.mnt;
-do_last:
- error = PTR_ERR(path.dentry);
- if (IS_ERR(path.dentry)) {
+ path->dentry = lookup_hash(nd);
+ path->mnt = nd->path.mnt;
+
+ error = PTR_ERR(path->dentry);
+ if (IS_ERR(path->dentry)) {
mutex_unlock(&dir->d_inode->i_mutex);
goto exit;
}
- if (IS_ERR(nd.intent.open.file)) {
- error = PTR_ERR(nd.intent.open.file);
+ if (IS_ERR(nd->intent.open.file)) {
+ error = PTR_ERR(nd->intent.open.file);
goto exit_mutex_unlock;
}
/* Negative dentry, just create the file */
- if (!path.dentry->d_inode) {
+ if (!path->dentry->d_inode) {
/*
* This write is needed to ensure that a
* ro->rw transition does not occur between
@@ -1720,18 +1690,16 @@ do_last:
* a permanent write count is taken through
* the 'struct file' in nameidata_to_filp().
*/
- error = mnt_want_write(nd.path.mnt);
+ error = mnt_want_write(nd->path.mnt);
if (error)
goto exit_mutex_unlock;
- error = __open_namei_create(&nd, &path, open_flag, mode);
+ error = __open_namei_create(nd, path, open_flag, mode);
if (error) {
- mnt_drop_write(nd.path.mnt);
+ mnt_drop_write(nd->path.mnt);
goto exit;
}
- filp = nameidata_to_filp(&nd);
- mnt_drop_write(nd.path.mnt);
- if (nd.root.mnt)
- path_put(&nd.root);
+ filp = nameidata_to_filp(nd);
+ mnt_drop_write(nd->path.mnt);
if (!IS_ERR(filp)) {
error = ima_file_check(filp, acc_mode);
if (error) {
@@ -1746,150 +1714,182 @@ do_last:
* It already exists.
*/
mutex_unlock(&dir->d_inode->i_mutex);
- audit_inode(pathname, path.dentry);
+ audit_inode(pathname, path->dentry);
error = -EEXIST;
- if (flag & O_EXCL)
+ if (open_flag & O_EXCL)
goto exit_dput;
- if (__follow_mount(&path)) {
+ if (__follow_mount(path)) {
error = -ELOOP;
- if (flag & O_NOFOLLOW)
+ if (open_flag & O_NOFOLLOW)
goto exit_dput;
}
error = -ENOENT;
- if (!path.dentry->d_inode)
+ if (!path->dentry->d_inode)
goto exit_dput;
- if (path.dentry->d_inode->i_op->follow_link)
- goto do_link;
- path_to_nameidata(&path, &nd);
+ if (path->dentry->d_inode->i_op->follow_link)
+ return NULL;
+
+ path_to_nameidata(path, nd);
error = -EISDIR;
- if (S_ISDIR(path.dentry->d_inode->i_mode))
+ if (S_ISDIR(path->dentry->d_inode->i_mode))
goto exit;
ok:
+ filp = finish_open(nd, open_flag, acc_mode);
+ return filp;
+
+exit_mutex_unlock:
+ mutex_unlock(&dir->d_inode->i_mutex);
+exit_dput:
+ path_put_conditional(path, nd);
+exit:
+ if (!IS_ERR(nd->intent.open.file))
+ release_open_intent(nd);
+ path_put(&nd->path);
+ return ERR_PTR(error);
+}
+
+/*
+ * Note that the low bits of the passed in "open_flag"
+ * are not the same as in the local variable "flag". See
+ * open_to_namei_flags() for more details.
+ */
+struct file *do_filp_open(int dfd, const char *pathname,
+ int open_flag, int mode, int acc_mode)
+{
+ struct file *filp;
+ struct nameidata nd;
+ int error;
+ struct path path;
+ int count = 0;
+ int flag = open_to_namei_flags(open_flag);
+ int force_reval = 0;
+
+ if (!(open_flag & O_CREAT))
+ mode = 0;
+
/*
- * Consider:
- * 1. may_open() truncates a file
- * 2. a rw->ro mount transition occurs
- * 3. nameidata_to_filp() fails due to
- * the ro mount.
- * That would be inconsistent, and should
- * be avoided. Taking this mnt write here
- * ensures that (2) can not occur.
+ * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
+ * check for O_DSYNC if the need any syncing at all we enforce it's
+ * always set instead of having to deal with possibly weird behaviour
+ * for malicious applications setting only __O_SYNC.
*/
- will_truncate = open_will_truncate(flag, nd.path.dentry->d_inode);
- if (will_truncate) {
- error = mnt_want_write(nd.path.mnt);
- if (error)
- goto exit;
- }
- error = may_open(&nd.path, acc_mode, open_flag);
+ if (open_flag & __O_SYNC)
+ open_flag |= O_DSYNC;
+
+ if (!acc_mode)
+ acc_mode = MAY_OPEN | ACC_MODE(open_flag);
+
+ /* O_TRUNC implies we need access checks for write permissions */
+ if (open_flag & O_TRUNC)
+ acc_mode |= MAY_WRITE;
+
+ /* Allow the LSM permission hook to distinguish append
+ access from general write access. */
+ if (open_flag & O_APPEND)
+ acc_mode |= MAY_APPEND;
+
+ /* find the parent */
+reval:
+ error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
+ if (error)
+ return ERR_PTR(error);
+ if (force_reval)
+ nd.flags |= LOOKUP_REVAL;
+
+ current->total_link_count = 0;
+ error = link_path_walk(pathname, &nd);
if (error) {
- if (will_truncate)
- mnt_drop_write(nd.path.mnt);
- goto exit;
- }
- filp = nameidata_to_filp(&nd);
- if (!IS_ERR(filp)) {
- error = ima_file_check(filp, acc_mode);
- if (error) {
- fput(filp);
- filp = ERR_PTR(error);
- }
+ filp = ERR_PTR(error);
+ goto out;
}
- if (!IS_ERR(filp)) {
- if (acc_mode & MAY_WRITE)
- vfs_dq_init(nd.path.dentry->d_inode);
+ if (unlikely(!audit_dummy_context()) && (open_flag & O_CREAT))
+ audit_inode(pathname, nd.path.dentry);
- if (will_truncate) {
- error = handle_truncate(&nd.path);
- if (error) {
- fput(filp);
- filp = ERR_PTR(error);
- }
- }
- }
/*
- * It is now safe to drop the mnt write
- * because the filp has had a write taken
- * on its behalf.
+ * We have the parent and last component.
*/
- if (will_truncate)
- mnt_drop_write(nd.path.mnt);
+
+ error = -ENFILE;
+ filp = get_empty_filp();
+ if (filp == NULL)
+ goto exit_parent;
+ nd.intent.open.file = filp;
+ filp->f_flags = open_flag;
+ nd.intent.open.flags = flag;
+ nd.intent.open.create_mode = mode;
+ nd.flags &= ~LOOKUP_PARENT;
+ nd.flags |= LOOKUP_OPEN;
+ if (open_flag & O_CREAT) {
+ nd.flags |= LOOKUP_CREATE;
+ if (open_flag & O_EXCL)
+ nd.flags |= LOOKUP_EXCL;
+ }
+ if (open_flag & O_DIRECTORY)
+ nd.flags |= LOOKUP_DIRECTORY;
+ filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
+ while (unlikely(!filp)) { /* trailing symlink */
+ struct path holder;
+ struct inode *inode = path.dentry->d_inode;
+ void *cookie;
+ error = -ELOOP;
+ /* S_ISDIR part is a temporary automount kludge */
+ if ((open_flag & O_NOFOLLOW) && !S_ISDIR(inode->i_mode))
+ goto exit_dput;
+ if (count++ == 32)
+ goto exit_dput;
+ /*
+ * This is subtle. Instead of calling do_follow_link() we do
+ * the thing by hands. The reason is that this way we have zero
+ * link_count and path_walk() (called from ->follow_link)
+ * honoring LOOKUP_PARENT. After that we have the parent and
+ * last component, i.e. we are in the same situation as after
+ * the first path_walk(). Well, almost - if the last component
+ * is normal we get its copy stored in nd->last.name and we will
+ * have to putname() it when we are done. Procfs-like symlinks
+ * just set LAST_BIND.
+ */
+ nd.flags |= LOOKUP_PARENT;
+ error = security_inode_follow_link(path.dentry, &nd);
+ if (error)
+ goto exit_dput;
+ error = __do_follow_link(&path, &nd, &cookie);
+ if (unlikely(error)) {
+ /* nd.path had been dropped */
+ if (!IS_ERR(cookie) && inode->i_op->put_link)
+ inode->i_op->put_link(path.dentry, &nd, cookie);
+ path_put(&path);
+ release_open_intent(&nd);
+ filp = ERR_PTR(error);
+ goto out;
+ }
+ holder = path;
+ nd.flags &= ~LOOKUP_PARENT;
+ filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
+ if (inode->i_op->put_link)
+ inode->i_op->put_link(holder.dentry, &nd, cookie);
+ path_put(&holder);
+ }
+out:
if (nd.root.mnt)
path_put(&nd.root);
+ if (filp == ERR_PTR(-ESTALE) && !force_reval) {
+ force_reval = 1;
+ goto reval;
+ }
return filp;
-exit_mutex_unlock:
- mutex_unlock(&dir->d_inode->i_mutex);
exit_dput:
path_put_conditional(&path, &nd);
-exit:
if (!IS_ERR(nd.intent.open.file))
release_open_intent(&nd);
exit_parent:
- if (nd.root.mnt)
- path_put(&nd.root);
path_put(&nd.path);
- return ERR_PTR(error);
-
-do_link:
- error = -ELOOP;
- if (flag & O_NOFOLLOW)
- goto exit_dput;
- /*
- * This is subtle. Instead of calling do_follow_link() we do the
- * thing by hands. The reason is that this way we have zero link_count
- * and path_walk() (called from ->follow_link) honoring LOOKUP_PARENT.
- * After that we have the parent and last component, i.e.
- * we are in the same situation as after the first path_walk().
- * Well, almost - if the last component is normal we get its copy
- * stored in nd->last.name and we will have to putname() it when we
- * are done. Procfs-like symlinks just set LAST_BIND.
- */
- nd.flags |= LOOKUP_PARENT;
- error = security_inode_follow_link(path.dentry, &nd);
- if (error)
- goto exit_dput;
- error = __do_follow_link(&path, &nd);
- path_put(&path);
- if (error) {
- /* Does someone understand code flow here? Or it is only
- * me so stupid? Anathema to whoever designed this non-sense
- * with "intent.open".
- */
- release_open_intent(&nd);
- if (nd.root.mnt)
- path_put(&nd.root);
- if (error == -ESTALE && !force_reval) {
- force_reval = 1;
- goto reval;
- }
- return ERR_PTR(error);
- }
- nd.flags &= ~LOOKUP_PARENT;
- if (nd.last_type == LAST_BIND)
- goto ok;
- error = -EISDIR;
- if (nd.last_type != LAST_NORM)
- goto exit;
- if (nd.last.name[nd.last.len]) {
- __putname(nd.last.name);
- goto exit;
- }
- error = -ELOOP;
- if (count++==32) {
- __putname(nd.last.name);
- goto exit;
- }
- dir = nd.path.dentry;
- mutex_lock(&dir->d_inode->i_mutex);
- path.dentry = lookup_hash(&nd);
- path.mnt = nd.path.mnt;
- __putname(nd.last.name);
- goto do_last;
+ filp = ERR_PTR(error);
+ goto out;
}
/**
@@ -1983,7 +1983,6 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
if (error)
return error;
- vfs_dq_init(dir);
error = dir->i_op->mknod(dir, dentry, mode, dev);
if (!error)
fsnotify_create(dir, dentry);
@@ -2082,7 +2081,6 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (error)
return error;
- vfs_dq_init(dir);
error = dir->i_op->mkdir(dir, dentry, mode);
if (!error)
fsnotify_mkdir(dir, dentry);
@@ -2168,8 +2166,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
if (!dir->i_op->rmdir)
return -EPERM;
- vfs_dq_init(dir);
-
mutex_lock(&dentry->d_inode->i_mutex);
dentry_unhash(dentry);
if (d_mountpoint(dentry))
@@ -2255,8 +2251,6 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
if (!dir->i_op->unlink)
return -EPERM;
- vfs_dq_init(dir);
-
mutex_lock(&dentry->d_inode->i_mutex);
if (d_mountpoint(dentry))
error = -EBUSY;
@@ -2369,7 +2363,6 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
if (error)
return error;
- vfs_dq_init(dir);
error = dir->i_op->symlink(dir, dentry, oldname);
if (!error)
fsnotify_create(dir, dentry);
@@ -2453,7 +2446,6 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
return error;
mutex_lock(&inode->i_mutex);
- vfs_dq_init(dir);
error = dir->i_op->link(old_dentry, dir, new_dentry);
mutex_unlock(&inode->i_mutex);
if (!error)
@@ -2554,7 +2546,7 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname
* e) conversion from fhandle to dentry may come in the wrong moment - when
* we are removing the target. Solution: we will have to grab ->i_mutex
* in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
- * ->i_mutex on parents, which works but leads to some truely excessive
+ * ->i_mutex on parents, which works but leads to some truly excessive
* locking].
*/
static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
@@ -2654,9 +2646,6 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (!old_dir->i_op->rename)
return -EPERM;
- vfs_dq_init(old_dir);
- vfs_dq_init(new_dir);
-
old_name = fsnotify_oldname_init(old_dentry->d_name.name);
if (is_dir)
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index b8b5b30d53f..7edfcd4d5e5 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -15,7 +15,6 @@
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 6a7d901f193..1daabb90e0a 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -15,7 +15,6 @@
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index cf98da1be23..fa338515402 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -526,10 +526,15 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
sb->s_blocksize_bits = 10;
sb->s_magic = NCP_SUPER_MAGIC;
sb->s_op = &ncp_sops;
+ sb->s_bdi = &server->bdi;
server = NCP_SBP(sb);
memset(server, 0, sizeof(*server));
+ error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
+ if (error)
+ goto out_bdi;
+
server->ncp_filp = ncp_filp;
server->ncp_sock = sock;
@@ -719,6 +724,8 @@ out_fput2:
if (server->info_filp)
fput(server->info_filp);
out_fput:
+ bdi_destroy(&server->bdi);
+out_bdi:
/* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
*
* The previously used put_filp(ncp_filp); was bogous, since
@@ -756,6 +763,7 @@ static void ncp_put_super(struct super_block *sb)
kill_pid(server->m.wdog_pid, SIGTERM, 1);
put_pid(server->m.wdog_pid);
+ bdi_destroy(&server->bdi);
kfree(server->priv.data);
kfree(server->auth.object_name);
vfree(server->rxbuf);
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index ec8f45f12e0..60a5e2864ea 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -15,6 +15,7 @@
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/mount.h>
+#include <linux/slab.h>
#include <linux/highuid.h>
#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 15458decdb8..56f5b3a0e1e 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -9,12 +9,12 @@
#include <linux/stat.h>
#include <linux/time.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/shm.h>
#include <linux/errno.h>
#include <linux/mman.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/ncp_fs.h>
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index e37df8d5fe7..c7ff6c700a6 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -21,6 +21,7 @@
#include <linux/mm.h>
#include <linux/netdevice.h>
#include <linux/signal.h>
+#include <linux/slab.h>
#include <net/scm.h>
#include <net/sock.h>
#include <linux/ipx.h>
diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c
index e3d26c1bd10..c634fd17b33 100644
--- a/fs/ncpfs/symlink.c
+++ b/fs/ncpfs/symlink.c
@@ -27,6 +27,7 @@
#include <linux/fs.h>
#include <linux/ncp_fs.h>
#include <linux/time.h>
+#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/stat.h>
#include "ncplib_kernel.h"
diff --git a/fs/nfs/cache_lib.c b/fs/nfs/cache_lib.c
index b4ffd0146ea..84690319e62 100644
--- a/fs/nfs/cache_lib.c
+++ b/fs/nfs/cache_lib.c
@@ -10,6 +10,7 @@
#include <linux/moduleparam.h>
#include <linux/mount.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#include <linux/sunrpc/cache.h>
#include <linux/sunrpc/rpc_pipe_fs.h>
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 73ab220354d..36dfdae9512 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -118,7 +118,6 @@ nfs4_callback_up(struct svc_serv *serv)
dprintk("NFS: Callback listener port = %u (af %u)\n",
nfs_callback_tcpport, PF_INET);
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
ret = svc_create_xprt(serv, "tcp", PF_INET6,
nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
if (ret > 0) {
@@ -129,7 +128,6 @@ nfs4_callback_up(struct svc_serv *serv)
ret = 0;
else
goto out_err;
-#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
return svc_prepare_thread(serv, &serv->sv_pools[0]);
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index d4036be0b58..85a7cfd1b8d 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -119,6 +119,14 @@ struct cb_recallanyargs {
};
extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy);
+
+struct cb_recallslotargs {
+ struct sockaddr *crsa_addr;
+ uint32_t crsa_target_max_slots;
+};
+extern unsigned nfs4_callback_recallslot(struct cb_recallslotargs *args,
+ void *dummy);
+
#endif /* CONFIG_NFS_V4_1 */
extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res);
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index defa9b4c470..a08770a7e85 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -7,6 +7,7 @@
*/
#include <linux/nfs4.h>
#include <linux/nfs_fs.h>
+#include <linux/slab.h>
#include "nfs4_fs.h"
#include "callback.h"
#include "delegation.h"
@@ -143,44 +144,49 @@ int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const n
* Return success if the sequenceID is one more than what we last saw on
* this slot, accounting for wraparound. Increments the slot's sequence.
*
- * We don't yet implement a duplicate request cache, so at this time
- * we will log replays, and process them as if we had not seen them before,
- * but we don't bump the sequence in the slot. Not too worried about it,
+ * We don't yet implement a duplicate request cache, instead we set the
+ * back channel ca_maxresponsesize_cached to zero. This is OK for now
* since we only currently implement idempotent callbacks anyway.
*
* We have a single slot backchannel at this time, so we don't bother
* checking the used_slots bit array on the table. The lower layer guarantees
* a single outstanding callback request at a time.
*/
-static int
-validate_seqid(struct nfs4_slot_table *tbl, u32 slotid, u32 seqid)
+static __be32
+validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
{
struct nfs4_slot *slot;
dprintk("%s enter. slotid %d seqid %d\n",
- __func__, slotid, seqid);
+ __func__, args->csa_slotid, args->csa_sequenceid);
- if (slotid > NFS41_BC_MAX_CALLBACKS)
+ if (args->csa_slotid > NFS41_BC_MAX_CALLBACKS)
return htonl(NFS4ERR_BADSLOT);
- slot = tbl->slots + slotid;
+ slot = tbl->slots + args->csa_slotid;
dprintk("%s slot table seqid: %d\n", __func__, slot->seq_nr);
/* Normal */
- if (likely(seqid == slot->seq_nr + 1)) {
+ if (likely(args->csa_sequenceid == slot->seq_nr + 1)) {
slot->seq_nr++;
return htonl(NFS4_OK);
}
/* Replay */
- if (seqid == slot->seq_nr) {
- dprintk("%s seqid %d is a replay - no DRC available\n",
- __func__, seqid);
- return htonl(NFS4_OK);
+ if (args->csa_sequenceid == slot->seq_nr) {
+ dprintk("%s seqid %d is a replay\n",
+ __func__, args->csa_sequenceid);
+ /* Signal process_op to set this error on next op */
+ if (args->csa_cachethis == 0)
+ return htonl(NFS4ERR_RETRY_UNCACHED_REP);
+
+ /* The ca_maxresponsesize_cached is 0 with no DRC */
+ else if (args->csa_cachethis == 1)
+ return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE);
}
/* Wraparound */
- if (seqid == 1 && (slot->seq_nr + 1) == 0) {
+ if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) {
slot->seq_nr = 1;
return htonl(NFS4_OK);
}
@@ -225,27 +231,87 @@ validate_seqid(struct nfs4_slot_table *tbl, u32 slotid, u32 seqid)
return NULL;
}
-/* FIXME: referring calls should be processed */
-unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
+/*
+ * For each referring call triple, check the session's slot table for
+ * a match. If the slot is in use and the sequence numbers match, the
+ * client is still waiting for a response to the original request.
+ */
+static bool referring_call_exists(struct nfs_client *clp,
+ uint32_t nrclists,
+ struct referring_call_list *rclists)
+{
+ bool status = 0;
+ int i, j;
+ struct nfs4_session *session;
+ struct nfs4_slot_table *tbl;
+ struct referring_call_list *rclist;
+ struct referring_call *ref;
+
+ /*
+ * XXX When client trunking is implemented, this becomes
+ * a session lookup from within the loop
+ */
+ session = clp->cl_session;
+ tbl = &session->fc_slot_table;
+
+ for (i = 0; i < nrclists; i++) {
+ rclist = &rclists[i];
+ if (memcmp(session->sess_id.data,
+ rclist->rcl_sessionid.data,
+ NFS4_MAX_SESSIONID_LEN) != 0)
+ continue;
+
+ for (j = 0; j < rclist->rcl_nrefcalls; j++) {
+ ref = &rclist->rcl_refcalls[j];
+
+ dprintk("%s: sessionid %x:%x:%x:%x sequenceid %u "
+ "slotid %u\n", __func__,
+ ((u32 *)&rclist->rcl_sessionid.data)[0],
+ ((u32 *)&rclist->rcl_sessionid.data)[1],
+ ((u32 *)&rclist->rcl_sessionid.data)[2],
+ ((u32 *)&rclist->rcl_sessionid.data)[3],
+ ref->rc_sequenceid, ref->rc_slotid);
+
+ spin_lock(&tbl->slot_tbl_lock);
+ status = (test_bit(ref->rc_slotid, tbl->used_slots) &&
+ tbl->slots[ref->rc_slotid].seq_nr ==
+ ref->rc_sequenceid);
+ spin_unlock(&tbl->slot_tbl_lock);
+ if (status)
+ goto out;
+ }
+ }
+
+out:
+ return status;
+}
+
+__be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
struct cb_sequenceres *res)
{
struct nfs_client *clp;
- int i, status;
-
- for (i = 0; i < args->csa_nrclists; i++)
- kfree(args->csa_rclists[i].rcl_refcalls);
- kfree(args->csa_rclists);
+ int i;
+ __be32 status;
status = htonl(NFS4ERR_BADSESSION);
clp = find_client_with_session(args->csa_addr, 4, &args->csa_sessionid);
if (clp == NULL)
goto out;
- status = validate_seqid(&clp->cl_session->bc_slot_table,
- args->csa_slotid, args->csa_sequenceid);
+ status = validate_seqid(&clp->cl_session->bc_slot_table, args);
if (status)
goto out_putclient;
+ /*
+ * Check for pending referring calls. If a match is found, a
+ * related callback was received before the response to the original
+ * call.
+ */
+ if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) {
+ status = htonl(NFS4ERR_DELAY);
+ goto out_putclient;
+ }
+
memcpy(&res->csr_sessionid, &args->csa_sessionid,
sizeof(res->csr_sessionid));
res->csr_sequenceid = args->csa_sequenceid;
@@ -256,15 +322,23 @@ unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
out_putclient:
nfs_put_client(clp);
out:
- dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
- res->csr_status = status;
- return res->csr_status;
+ for (i = 0; i < args->csa_nrclists; i++)
+ kfree(args->csa_rclists[i].rcl_refcalls);
+ kfree(args->csa_rclists);
+
+ if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP))
+ res->csr_status = 0;
+ else
+ res->csr_status = status;
+ dprintk("%s: exit with status = %d res->csr_status %d\n", __func__,
+ ntohl(status), ntohl(res->csr_status));
+ return status;
}
-unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy)
+__be32 nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy)
{
struct nfs_client *clp;
- int status;
+ __be32 status;
fmode_t flags = 0;
status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
@@ -289,4 +363,40 @@ out:
dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
return status;
}
+
+/* Reduce the fore channel's max_slots to the target value */
+__be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy)
+{
+ struct nfs_client *clp;
+ struct nfs4_slot_table *fc_tbl;
+ __be32 status;
+
+ status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
+ clp = nfs_find_client(args->crsa_addr, 4);
+ if (clp == NULL)
+ goto out;
+
+ dprintk("NFS: CB_RECALL_SLOT request from %s target max slots %d\n",
+ rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR),
+ args->crsa_target_max_slots);
+
+ fc_tbl = &clp->cl_session->fc_slot_table;
+
+ status = htonl(NFS4ERR_BAD_HIGH_SLOT);
+ if (args->crsa_target_max_slots > fc_tbl->max_slots ||
+ args->crsa_target_max_slots < 1)
+ goto out_putclient;
+
+ status = htonl(NFS4_OK);
+ if (args->crsa_target_max_slots == fc_tbl->max_slots)
+ goto out_putclient;
+
+ fc_tbl->target_max_slots = args->crsa_target_max_slots;
+ nfs41_handle_recall_slot(clp);
+out_putclient:
+ nfs_put_client(clp); /* balance nfs_find_client */
+out:
+ dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
+ return status;
+}
#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 8e1a2511c8b..05af212f0ed 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -9,6 +9,7 @@
#include <linux/sunrpc/svc.h>
#include <linux/nfs4.h>
#include <linux/nfs_fs.h>
+#include <linux/slab.h>
#include "nfs4_fs.h"
#include "callback.h"
@@ -24,10 +25,14 @@
#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
4 + 1 + 3)
#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
+#define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#endif /* CONFIG_NFS_V4_1 */
#define NFSDBG_FACILITY NFSDBG_CALLBACK
+/* Internal error code */
+#define NFS4ERR_RESOURCE_HDR 11050
+
typedef __be32 (*callback_process_op_t)(void *, void *);
typedef __be32 (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *);
typedef __be32 (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *);
@@ -173,7 +178,7 @@ static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op)
__be32 *p;
p = read_buf(xdr, 4);
if (unlikely(p == NULL))
- return htonl(NFS4ERR_RESOURCE);
+ return htonl(NFS4ERR_RESOURCE_HDR);
*op = ntohl(*p);
return 0;
}
@@ -215,10 +220,10 @@ out:
#if defined(CONFIG_NFS_V4_1)
-static unsigned decode_sessionid(struct xdr_stream *xdr,
+static __be32 decode_sessionid(struct xdr_stream *xdr,
struct nfs4_sessionid *sid)
{
- uint32_t *p;
+ __be32 *p;
int len = NFS4_MAX_SESSIONID_LEN;
p = read_buf(xdr, len);
@@ -229,12 +234,12 @@ static unsigned decode_sessionid(struct xdr_stream *xdr,
return 0;
}
-static unsigned decode_rc_list(struct xdr_stream *xdr,
+static __be32 decode_rc_list(struct xdr_stream *xdr,
struct referring_call_list *rc_list)
{
- uint32_t *p;
+ __be32 *p;
int i;
- unsigned status;
+ __be32 status;
status = decode_sessionid(xdr, &rc_list->rcl_sessionid);
if (status)
@@ -267,13 +272,13 @@ out:
return status;
}
-static unsigned decode_cb_sequence_args(struct svc_rqst *rqstp,
+static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp,
struct xdr_stream *xdr,
struct cb_sequenceargs *args)
{
- uint32_t *p;
+ __be32 *p;
int i;
- unsigned status;
+ __be32 status;
status = decode_sessionid(xdr, &args->csa_sessionid);
if (status)
@@ -327,11 +332,11 @@ out_free:
goto out;
}
-static unsigned decode_recallany_args(struct svc_rqst *rqstp,
+static __be32 decode_recallany_args(struct svc_rqst *rqstp,
struct xdr_stream *xdr,
struct cb_recallanyargs *args)
{
- uint32_t *p;
+ __be32 *p;
args->craa_addr = svc_addr(rqstp);
p = read_buf(xdr, 4);
@@ -346,6 +351,20 @@ static unsigned decode_recallany_args(struct svc_rqst *rqstp,
return 0;
}
+static __be32 decode_recallslot_args(struct svc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct cb_recallslotargs *args)
+{
+ __be32 *p;
+
+ args->crsa_addr = svc_addr(rqstp);
+ p = read_buf(xdr, 4);
+ if (unlikely(p == NULL))
+ return htonl(NFS4ERR_BADXDR);
+ args->crsa_target_max_slots = ntohl(*p++);
+ return 0;
+}
+
#endif /* CONFIG_NFS_V4_1 */
static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
@@ -465,7 +484,7 @@ static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res)
p = xdr_reserve_space(xdr, 8);
if (unlikely(p == NULL))
- return htonl(NFS4ERR_RESOURCE);
+ return htonl(NFS4ERR_RESOURCE_HDR);
*p++ = htonl(op);
*p = res;
return 0;
@@ -499,10 +518,10 @@ out:
#if defined(CONFIG_NFS_V4_1)
-static unsigned encode_sessionid(struct xdr_stream *xdr,
+static __be32 encode_sessionid(struct xdr_stream *xdr,
const struct nfs4_sessionid *sid)
{
- uint32_t *p;
+ __be32 *p;
int len = NFS4_MAX_SESSIONID_LEN;
p = xdr_reserve_space(xdr, len);
@@ -513,11 +532,11 @@ static unsigned encode_sessionid(struct xdr_stream *xdr,
return 0;
}
-static unsigned encode_cb_sequence_res(struct svc_rqst *rqstp,
+static __be32 encode_cb_sequence_res(struct svc_rqst *rqstp,
struct xdr_stream *xdr,
const struct cb_sequenceres *res)
{
- uint32_t *p;
+ __be32 *p;
unsigned status = res->csr_status;
if (unlikely(status != 0))
@@ -554,6 +573,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
case OP_CB_RECALL:
case OP_CB_SEQUENCE:
case OP_CB_RECALL_ANY:
+ case OP_CB_RECALL_SLOT:
*op = &callback_ops[op_nr];
break;
@@ -562,7 +582,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
case OP_CB_NOTIFY:
case OP_CB_PUSH_DELEG:
case OP_CB_RECALLABLE_OBJ_AVAIL:
- case OP_CB_RECALL_SLOT:
case OP_CB_WANTS_CANCELLED:
case OP_CB_NOTIFY_LOCK:
return htonl(NFS4ERR_NOTSUPP);
@@ -602,20 +621,18 @@ preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op)
static __be32 process_op(uint32_t minorversion, int nop,
struct svc_rqst *rqstp,
struct xdr_stream *xdr_in, void *argp,
- struct xdr_stream *xdr_out, void *resp)
+ struct xdr_stream *xdr_out, void *resp, int* drc_status)
{
struct callback_op *op = &callback_ops[0];
- unsigned int op_nr = OP_CB_ILLEGAL;
+ unsigned int op_nr;
__be32 status;
long maxlen;
__be32 res;
dprintk("%s: start\n", __func__);
status = decode_op_hdr(xdr_in, &op_nr);
- if (unlikely(status)) {
- status = htonl(NFS4ERR_OP_ILLEGAL);
- goto out;
- }
+ if (unlikely(status))
+ return status;
dprintk("%s: minorversion=%d nop=%d op_nr=%u\n",
__func__, minorversion, nop, op_nr);
@@ -624,19 +641,32 @@ static __be32 process_op(uint32_t minorversion, int nop,
preprocess_nfs4_op(op_nr, &op);
if (status == htonl(NFS4ERR_OP_ILLEGAL))
op_nr = OP_CB_ILLEGAL;
-out:
+ if (status)
+ goto encode_hdr;
+
+ if (*drc_status) {
+ status = *drc_status;
+ goto encode_hdr;
+ }
+
maxlen = xdr_out->end - xdr_out->p;
if (maxlen > 0 && maxlen < PAGE_SIZE) {
- if (likely(status == 0 && op->decode_args != NULL))
- status = op->decode_args(rqstp, xdr_in, argp);
- if (likely(status == 0 && op->process_op != NULL))
+ status = op->decode_args(rqstp, xdr_in, argp);
+ if (likely(status == 0))
status = op->process_op(argp, resp);
} else
status = htonl(NFS4ERR_RESOURCE);
+ /* Only set by OP_CB_SEQUENCE processing */
+ if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP)) {
+ *drc_status = status;
+ status = 0;
+ }
+
+encode_hdr:
res = encode_op_hdr(xdr_out, op_nr, status);
- if (status == 0)
- status = res;
+ if (unlikely(res))
+ return res;
if (op->encode_res != NULL && status == 0)
status = op->encode_res(rqstp, xdr_out, resp);
dprintk("%s: done, status = %d\n", __func__, ntohl(status));
@@ -652,7 +682,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
struct cb_compound_hdr_res hdr_res = { NULL };
struct xdr_stream xdr_in, xdr_out;
__be32 *p;
- __be32 status;
+ __be32 status, drc_status = 0;
unsigned int nops = 0;
dprintk("%s: start\n", __func__);
@@ -672,11 +702,18 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
return rpc_system_err;
while (status == 0 && nops != hdr_arg.nops) {
- status = process_op(hdr_arg.minorversion, nops,
- rqstp, &xdr_in, argp, &xdr_out, resp);
+ status = process_op(hdr_arg.minorversion, nops, rqstp,
+ &xdr_in, argp, &xdr_out, resp, &drc_status);
nops++;
}
+ /* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return
+ * resource error in cb_compound status without returning op */
+ if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
+ status = htonl(NFS4ERR_RESOURCE);
+ nops--;
+ }
+
*hdr_res.status = status;
*hdr_res.nops = htonl(nops);
dprintk("%s: done, status = %u\n", __func__, ntohl(status));
@@ -713,6 +750,11 @@ static struct callback_op callback_ops[] = {
.decode_args = (callback_decode_arg_t)decode_recallany_args,
.res_maxsize = CB_OP_RECALLANY_RES_MAXSZ,
},
+ [OP_CB_RECALL_SLOT] = {
+ .process_op = (callback_process_op_t)nfs4_callback_recallslot,
+ .decode_args = (callback_decode_arg_t)decode_recallslot_args,
+ .res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ,
+ },
#endif /* CONFIG_NFS_V4_1 */
};
@@ -741,6 +783,7 @@ struct svc_version nfs4_callback_version1 = {
.vs_proc = nfs4_callback_procedures1,
.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
.vs_dispatch = NULL,
+ .vs_hidden = 1,
};
struct svc_version nfs4_callback_version4 = {
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ee77713ce68..acc9c4943b8 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -35,6 +35,7 @@
#include <linux/vfs.h>
#include <linux/inet.h>
#include <linux/in6.h>
+#include <linux/slab.h>
#include <net/ipv6.h>
#include <linux/nfs_xdr.h>
#include <linux/sunrpc/bc_xprt.h>
@@ -164,30 +165,7 @@ error_0:
return ERR_PTR(err);
}
-static void nfs4_shutdown_client(struct nfs_client *clp)
-{
-#ifdef CONFIG_NFS_V4
- if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
- nfs4_kill_renewd(clp);
- BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners));
- if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
- nfs_idmap_delete(clp);
-
- rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
-#endif
-}
-
-/*
- * Destroy the NFS4 callback service
- */
-static void nfs4_destroy_callback(struct nfs_client *clp)
-{
#ifdef CONFIG_NFS_V4
- if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
- nfs_callback_down(clp->cl_minorversion);
-#endif /* CONFIG_NFS_V4 */
-}
-
/*
* Clears/puts all minor version specific parts from an nfs_client struct
* reverting it to minorversion 0.
@@ -202,9 +180,33 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
clp->cl_call_sync = _nfs4_call_sync;
#endif /* CONFIG_NFS_V4_1 */
+}
+
+/*
+ * Destroy the NFS4 callback service
+ */
+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);
+}
+static void nfs4_shutdown_client(struct nfs_client *clp)
+{
+ if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
+ nfs4_kill_renewd(clp);
+ nfs4_clear_client_minor_version(clp);
nfs4_destroy_callback(clp);
+ if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
+ nfs_idmap_delete(clp);
+
+ rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
+}
+#else
+static void nfs4_shutdown_client(struct nfs_client *clp)
+{
}
+#endif /* CONFIG_NFS_V4 */
/*
* Destroy a shared client record
@@ -213,7 +215,6 @@ static void nfs_free_client(struct nfs_client *clp)
{
dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
- nfs4_clear_client_minor_version(clp);
nfs4_shutdown_client(clp);
nfs_fscache_release_client_cookie(clp);
@@ -965,6 +966,8 @@ out_error:
static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
{
target->flags = source->flags;
+ target->rsize = source->rsize;
+ target->wsize = source->wsize;
target->acregmin = source->acregmin;
target->acregmax = source->acregmax;
target->acdirmin = source->acdirmin;
@@ -1293,7 +1296,8 @@ static int nfs4_init_server(struct nfs_server *server,
/* Initialise the client representation from the mount data */
server->flags = data->flags;
- server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
+ server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|
+ NFS_CAP_POSIX_LOCK;
server->options = data->options;
/* Get a client record */
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 2563bebc4c6..15671245c6e 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -10,6 +10,7 @@
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 944b627ec6e..69e7b814012 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -71,4 +71,10 @@ static inline int nfs_inode_return_delegation(struct inode *inode)
}
#endif
+static inline int nfs_have_delegated_attributes(struct inode *inode)
+{
+ return nfs_have_delegation(inode, FMODE_READ) &&
+ !(NFS_I(inode)->cache_validity & NFS_INO_REVAL_FORCED);
+}
+
#endif
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 3c7f03b669f..a7bb5c694aa 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -560,7 +560,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
desc->entry = &my_entry;
nfs_block_sillyrename(dentry);
- res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping);
+ res = nfs_revalidate_mapping(inode, filp->f_mapping);
if (res < 0)
goto out;
@@ -837,6 +837,8 @@ out_zap_parent:
/* If we have submounts, don't unhash ! */
if (have_submounts(dentry))
goto out_valid;
+ if (dentry->d_flags & DCACHE_DISCONNECTED)
+ goto out_valid;
shrink_dcache_parent(dentry);
}
d_drop(dentry);
@@ -1025,12 +1027,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
res = NULL;
goto out;
/* This turned out not to be a regular file */
+ case -EISDIR:
case -ENOTDIR:
goto no_open;
case -ELOOP:
if (!(nd->intent.open.flags & O_NOFOLLOW))
goto no_open;
- /* case -EISDIR: */
/* case -EINVAL: */
default:
goto out;
@@ -1050,7 +1052,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
struct inode *dir;
int openflags, ret = 0;
- if (!is_atomic_open(nd))
+ if (!is_atomic_open(nd) || d_mountpoint(dentry))
goto no_open;
parent = dget_parent(dentry);
dir = parent->d_inode;
@@ -1789,7 +1791,7 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
cache = nfs_access_search_rbtree(inode, cred);
if (cache == NULL)
goto out;
- if (!nfs_have_delegation(inode, FMODE_READ) &&
+ if (!nfs_have_delegated_attributes(inode) &&
!time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
goto out_stale;
res->jiffies = cache->jiffies;
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 0d289823e85..ad4cd31d605 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -44,6 +44,7 @@
#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/kref.h>
+#include <linux/slab.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index 95e1ca765d4..76fd235d002 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -9,6 +9,7 @@
#include <linux/hash.h>
#include <linux/string.h>
#include <linux/kmod.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/seq_file.h>
@@ -36,6 +37,19 @@ struct nfs_dns_ent {
};
+static void nfs_dns_ent_update(struct cache_head *cnew,
+ struct cache_head *ckey)
+{
+ struct nfs_dns_ent *new;
+ struct nfs_dns_ent *key;
+
+ new = container_of(cnew, struct nfs_dns_ent, h);
+ key = container_of(ckey, struct nfs_dns_ent, h);
+
+ memcpy(&new->addr, &key->addr, key->addrlen);
+ new->addrlen = key->addrlen;
+}
+
static void nfs_dns_ent_init(struct cache_head *cnew,
struct cache_head *ckey)
{
@@ -49,8 +63,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
if (new->hostname) {
new->namelen = key->namelen;
- memcpy(&new->addr, &key->addr, key->addrlen);
- new->addrlen = key->addrlen;
+ nfs_dns_ent_update(cnew, ckey);
} else {
new->namelen = 0;
new->addrlen = 0;
@@ -234,7 +247,7 @@ static struct cache_detail nfs_dns_resolve = {
.cache_show = nfs_dns_show,
.match = nfs_dns_match,
.init = nfs_dns_ent_init,
- .update = nfs_dns_ent_init,
+ .update = nfs_dns_ent_update,
.alloc = nfs_dns_ent_alloc,
};
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 63f2071d644..8d965bddb87 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -24,9 +24,9 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/aio.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -123,11 +123,11 @@ nfs_file_open(struct inode *inode, struct file *filp)
filp->f_path.dentry->d_parent->d_name.name,
filp->f_path.dentry->d_name.name);
+ nfs_inc_stats(inode, NFSIOS_VFSOPEN);
res = nfs_check_flags(filp->f_flags);
if (res)
return res;
- nfs_inc_stats(inode, NFSIOS_VFSOPEN);
res = nfs_open(inode, filp);
return res;
}
@@ -237,9 +237,9 @@ nfs_file_flush(struct file *file, fl_owner_t id)
dentry->d_parent->d_name.name,
dentry->d_name.name);
+ nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
if ((file->f_mode & FMODE_WRITE) == 0)
return 0;
- nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
/* Flush writes to the server and return any errors */
return nfs_do_fsync(ctx, inode);
@@ -262,9 +262,11 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
(unsigned long) count, (unsigned long) pos);
result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
- nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
- if (!result)
+ if (!result) {
result = generic_file_aio_read(iocb, iov, nr_segs, pos);
+ if (result > 0)
+ nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, result);
+ }
return result;
}
@@ -282,8 +284,11 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
(unsigned long) count, (unsigned long long) *ppos);
res = nfs_revalidate_mapping(inode, filp->f_mapping);
- if (!res)
+ if (!res) {
res = generic_file_splice_read(filp, ppos, pipe, count, flags);
+ if (res > 0)
+ nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, res);
+ }
return res;
}
@@ -486,7 +491,8 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
{
dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
- if (gfp & __GFP_WAIT)
+ /* Only do I/O if gfp is a superset of GFP_KERNEL */
+ if ((gfp & GFP_KERNEL) == GFP_KERNEL)
nfs_wb_page(page->mapping->host, page);
/* If PagePrivate() is set, then the page is not freeable */
if (PagePrivate(page))
@@ -596,6 +602,7 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
{
struct dentry * dentry = iocb->ki_filp->f_path.dentry;
struct inode * inode = dentry->d_inode;
+ unsigned long written = 0;
ssize_t result;
size_t count = iov_length(iov, nr_segs);
@@ -622,14 +629,18 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
if (!count)
goto out;
- nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
result = generic_file_aio_write(iocb, iov, nr_segs, pos);
+ if (result > 0)
+ written = result;
+
/* Return error values for O_DSYNC and IS_SYNC() */
if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
if (err < 0)
result = err;
}
+ if (result > 0)
+ nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
out:
return result;
@@ -644,6 +655,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
{
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
+ unsigned long written = 0;
ssize_t ret;
dprintk("NFS splice_write(%s/%s, %lu@%llu)\n",
@@ -654,14 +666,17 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
* The combination of splice and an O_APPEND destination is disallowed.
*/
- nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
-
ret = generic_file_splice_write(pipe, filp, ppos, count, flags);
+ if (ret > 0)
+ written = ret;
+
if (ret >= 0 && nfs_need_sync_write(filp, inode)) {
int err = nfs_do_fsync(nfs_file_open_context(filp), inode);
if (err < 0)
ret = err;
}
+ if (ret > 0)
+ nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
return ret;
}
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index 237874f1af2..a6b16ed9322 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -17,6 +17,7 @@
#include <linux/nfs_fs_sb.h>
#include <linux/in6.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include "internal.h"
#include "iostat.h"
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 7570573bdb3..50a56edca0b 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -36,6 +36,7 @@
#include <linux/vfs.h>
#include <linux/inet.h>
#include <linux/nfs_xdr.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -97,22 +98,6 @@ u64 nfs_compat_user_ino64(u64 fileid)
return ino;
}
-int nfs_write_inode(struct inode *inode, int sync)
-{
- int ret;
-
- if (sync) {
- ret = filemap_fdatawait(inode->i_mapping);
- if (ret == 0)
- ret = nfs_commit_inode(inode, FLUSH_SYNC);
- } else
- ret = nfs_commit_inode(inode, 0);
- if (ret >= 0)
- return 0;
- __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
- return ret;
-}
-
void nfs_clear_inode(struct inode *inode)
{
/*
@@ -130,16 +115,12 @@ void nfs_clear_inode(struct inode *inode)
*/
int nfs_sync_mapping(struct address_space *mapping)
{
- int ret;
+ int ret = 0;
- if (mapping->nrpages == 0)
- return 0;
- unmap_mapping_range(mapping, 0, 0, 0);
- ret = filemap_write_and_wait(mapping);
- if (ret != 0)
- goto out;
- ret = nfs_wb_all(mapping->host);
-out:
+ if (mapping->nrpages != 0) {
+ unmap_mapping_range(mapping, 0, 0, 0);
+ ret = nfs_wb_all(mapping->host);
+ }
return ret;
}
@@ -511,17 +492,11 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
int err;
- /*
- * Flush out writes to the server in order to update c/mtime.
- *
- * Hold the i_mutex to suspend application writes temporarily;
- * this prevents long-running writing applications from blocking
- * nfs_wb_nocommit.
- */
+ /* Flush out writes to the server in order to update c/mtime. */
if (S_ISREG(inode->i_mode)) {
- mutex_lock(&inode->i_mutex);
- nfs_wb_nocommit(inode);
- mutex_unlock(&inode->i_mutex);
+ err = filemap_write_and_wait(inode->i_mapping);
+ if (err)
+ goto out;
}
/*
@@ -545,6 +520,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
generic_fillattr(inode, stat);
stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
}
+out:
return err;
}
@@ -620,11 +596,6 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
__put_nfs_open_context(ctx, 0);
}
-static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
-{
- __put_nfs_open_context(ctx, 1);
-}
-
/*
* Ensure that mmap has a recent RPC credential for use when writing out
* shared pages
@@ -652,10 +623,10 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
list_for_each_entry(pos, &nfsi->open_files, list) {
if (cred != NULL && pos->cred != cred)
continue;
- if ((pos->mode & mode) == mode) {
- ctx = get_nfs_open_context(pos);
- break;
- }
+ if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode)
+ continue;
+ ctx = get_nfs_open_context(pos);
+ break;
}
spin_unlock(&inode->i_lock);
return ctx;
@@ -671,7 +642,7 @@ static void nfs_file_clear_open_context(struct file *filp)
spin_lock(&inode->i_lock);
list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
spin_unlock(&inode->i_lock);
- put_nfs_open_context_sync(ctx);
+ __put_nfs_open_context(ctx, filp->f_flags & O_DIRECT ? 0 : 1);
}
}
@@ -759,7 +730,7 @@ int nfs_attribute_timeout(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
- if (nfs_have_delegation(inode, FMODE_READ))
+ if (nfs_have_delegated_attributes(inode))
return 0;
return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
}
@@ -779,7 +750,7 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
return __nfs_revalidate_inode(server, inode);
}
-static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
+static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
{
struct nfs_inode *nfsi = NFS_I(inode);
@@ -800,49 +771,10 @@ static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_spa
return 0;
}
-static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
-{
- int ret = 0;
-
- mutex_lock(&inode->i_mutex);
- if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_DATA) {
- ret = nfs_sync_mapping(mapping);
- if (ret == 0)
- ret = nfs_invalidate_mapping_nolock(inode, mapping);
- }
- mutex_unlock(&inode->i_mutex);
- return ret;
-}
-
-/**
- * nfs_revalidate_mapping_nolock - Revalidate the pagecache
- * @inode - pointer to host inode
- * @mapping - pointer to mapping
- */
-int nfs_revalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
-{
- struct nfs_inode *nfsi = NFS_I(inode);
- int ret = 0;
-
- if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
- || nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
- ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
- if (ret < 0)
- goto out;
- }
- if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
- ret = nfs_invalidate_mapping_nolock(inode, mapping);
-out:
- return ret;
-}
-
/**
* nfs_revalidate_mapping - Revalidate the pagecache
* @inode - pointer to host inode
* @mapping - pointer to mapping
- *
- * This version of the function will take the inode->i_mutex and attempt to
- * flush out all dirty data if it needs to invalidate the page cache.
*/
int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
{
@@ -1420,6 +1352,7 @@ static void init_once(void *foo)
INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
nfsi->npages = 0;
+ nfsi->ncommit = 0;
atomic_set(&nfsi->silly_count, 1);
INIT_HLIST_HEAD(&nfsi->silly_list);
init_waitqueue_head(&nfsi->waitqueue);
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 29e464d23b3..11f82f03c5d 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -211,7 +211,7 @@ extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask);
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 *,int);
+extern int nfs_write_inode(struct inode *, struct writeback_control *);
extern void nfs_clear_inode(struct inode *);
#ifdef CONFIG_NFS_V4
extern void nfs4_clear_inode(struct inode *);
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 40c76678289..7888cf36022 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -8,6 +8,7 @@
*/
#include <linux/dcache.h>
+#include <linux/gfp.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/nfs_fs.h>
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 7bc2da8efd4..81cf1425791 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -12,7 +12,6 @@
#include <linux/param.h>
#include <linux/time.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/in.h>
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index bac60515a4b..d150ae0c5ec 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -1,4 +1,5 @@
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/nfs.h>
#include <linux/nfs3.h>
#include <linux/nfs_fs.h>
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 3f8881d1a05..e701002694e 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/sunrpc/clnt.h>
+#include <linux/slab.h>
#include <linux/nfs.h>
#include <linux/nfs3.h>
#include <linux/nfs_fs.h>
@@ -22,14 +23,14 @@
#define NFSDBG_FACILITY NFSDBG_PROC
-/* A wrapper to handle the EJUKEBOX error message */
+/* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */
static int
nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
{
int res;
do {
res = rpc_call_sync(clnt, msg, flags);
- if (res != -EJUKEBOX)
+ if (res != -EJUKEBOX && res != -EKEYEXPIRED)
break;
schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
res = -ERESTARTSYS;
@@ -42,9 +43,10 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
static int
nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
{
- if (task->tk_status != -EJUKEBOX)
+ if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED)
return 0;
- nfs_inc_stats(inode, NFSIOS_DELAY);
+ if (task->tk_status == -EJUKEBOX)
+ nfs_inc_stats(inode, NFSIOS_DELAY);
task->tk_status = 0;
rpc_restart_call(task);
rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 5fe5492fbd2..56a86f6ac8b 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -9,7 +9,6 @@
#include <linux/param.h>
#include <linux/time.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/in.h>
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 0c6fda33d66..a187200a7aa 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -46,6 +46,7 @@ enum nfs4_client_state {
NFS4CLNT_DELEGRETURN,
NFS4CLNT_SESSION_RESET,
NFS4CLNT_SESSION_DRAINING,
+ NFS4CLNT_RECALL_SLOT,
};
/*
@@ -280,6 +281,7 @@ extern void nfs4_schedule_state_manager(struct nfs_client *);
extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state);
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);
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index fa3408f2011..f071d12c613 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -11,6 +11,7 @@
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/nfs_fs.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sunrpc/clnt.h>
#include <linux/vfs.h>
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 84d83be25a9..071fcedd517 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -39,6 +39,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/sunrpc/clnt.h>
#include <linux/nfs.h>
#include <linux/nfs4.h>
@@ -281,6 +282,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
}
case -NFS4ERR_GRACE:
case -NFS4ERR_DELAY:
+ case -EKEYEXPIRED:
ret = nfs4_delay(server->client, &exception->timeout);
if (ret != 0)
break;
@@ -418,7 +420,8 @@ static void nfs41_sequence_done(struct nfs_client *clp,
clp->cl_last_renewal = timestamp;
spin_unlock(&clp->cl_lock);
/* Check sequence flags */
- nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
+ if (atomic_read(&clp->cl_count) > 1)
+ nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
}
out:
/* The session may be reset by one of the error handlers. */
@@ -1163,7 +1166,7 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
int err;
do {
err = _nfs4_do_open_reclaim(ctx, state);
- if (err != -NFS4ERR_DELAY)
+ if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED)
break;
nfs4_handle_exception(server, err, &exception);
} while (exception.retry);
@@ -1520,6 +1523,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
nfs_post_op_update_inode(dir, o_res->dir_attr);
} else
nfs_refresh_inode(dir, o_res->dir_attr);
+ if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
+ server->caps &= ~NFS_CAP_POSIX_LOCK;
if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
status = _nfs4_proc_open_confirm(data);
if (status != 0)
@@ -1582,6 +1587,7 @@ static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state
goto out;
case -NFS4ERR_GRACE:
case -NFS4ERR_DELAY:
+ case -EKEYEXPIRED:
nfs4_handle_exception(server, err, &exception);
err = 0;
}
@@ -1660,7 +1666,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
status = PTR_ERR(state);
if (IS_ERR(state))
goto err_opendata_put;
- if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0)
+ if (server->caps & NFS_CAP_POSIX_LOCK)
set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
nfs4_opendata_put(opendata);
nfs4_put_state_owner(sp);
@@ -2064,8 +2070,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
case -EDQUOT:
case -ENOSPC:
case -EROFS:
- lookup_instantiate_filp(nd, (struct dentry *)state, NULL);
- return 1;
+ return PTR_ERR(state);
default:
goto out_drop;
}
@@ -3145,10 +3150,19 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
* nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
* standalone procedure for queueing an asynchronous RENEW.
*/
+static void nfs4_renew_release(void *data)
+{
+ struct nfs_client *clp = data;
+
+ if (atomic_read(&clp->cl_count) > 1)
+ nfs4_schedule_state_renewal(clp);
+ nfs_put_client(clp);
+}
+
static void nfs4_renew_done(struct rpc_task *task, void *data)
{
- struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp;
- unsigned long timestamp = (unsigned long)data;
+ struct nfs_client *clp = data;
+ unsigned long timestamp = task->tk_start;
if (task->tk_status < 0) {
/* Unless we're shutting down, schedule state recovery! */
@@ -3164,6 +3178,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
static const struct rpc_call_ops nfs4_renew_ops = {
.rpc_call_done = nfs4_renew_done,
+ .rpc_release = nfs4_renew_release,
};
int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -3174,8 +3189,10 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
.rpc_cred = cred,
};
+ if (!atomic_inc_not_zero(&clp->cl_count))
+ return -EIO;
return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
- &nfs4_renew_ops, (void *)jiffies);
+ &nfs4_renew_ops, clp);
}
int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -3452,6 +3469,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
if (server)
nfs_inc_server_stats(server, NFSIOS_DELAY);
case -NFS4ERR_GRACE:
+ case -EKEYEXPIRED:
rpc_delay(task, NFS4_POLL_RETRY_MAX);
task->tk_status = 0;
return -EAGAIN;
@@ -3564,6 +3582,7 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
case -NFS4ERR_RESOURCE:
/* The IBM lawyers misread another document! */
case -NFS4ERR_DELAY:
+ case -EKEYEXPIRED:
err = nfs4_delay(clp->cl_rpcclient, &timeout);
}
} while (err == 0);
@@ -4179,7 +4198,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
return 0;
err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
- if (err != -NFS4ERR_DELAY)
+ if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED)
break;
nfs4_handle_exception(server, err, &exception);
} while (exception.retry);
@@ -4204,6 +4223,7 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
goto out;
case -NFS4ERR_GRACE:
case -NFS4ERR_DELAY:
+ case -EKEYEXPIRED:
nfs4_handle_exception(server, err, &exception);
err = 0;
}
@@ -4355,6 +4375,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
err = 0;
goto out;
case -NFS4ERR_DELAY:
+ case -EKEYEXPIRED:
break;
}
err = nfs4_handle_exception(server, err, &exception);
@@ -4500,7 +4521,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
- if (status != NFS4ERR_CLID_INUSE)
+ if (status != -NFS4ERR_CLID_INUSE)
break;
if (signalled())
@@ -4554,6 +4575,7 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
switch (task->tk_status) {
case -NFS4ERR_DELAY:
case -NFS4ERR_GRACE:
+ case -EKEYEXPIRED:
dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
rpc_delay(task, NFS4_POLL_RETRY_MIN);
task->tk_status = 0;
@@ -4611,26 +4633,32 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
/*
* Reset a slot table
*/
-static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, int max_slots,
- int old_max_slots, int ivalue)
+static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
+ int ivalue)
{
+ struct nfs4_slot *new = NULL;
int i;
int ret = 0;
- dprintk("--> %s: max_reqs=%u, tbl %p\n", __func__, max_slots, tbl);
+ dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
+ max_reqs, tbl->max_slots);
- /*
- * Until we have dynamic slot table adjustment, insist
- * upon the same slot table size
- */
- if (max_slots != old_max_slots) {
- dprintk("%s reset slot table does't match old\n",
- __func__);
- ret = -EINVAL; /*XXX NFS4ERR_REQ_TOO_BIG ? */
- goto out;
+ /* Does the newly negotiated max_reqs match the existing slot table? */
+ if (max_reqs != tbl->max_slots) {
+ ret = -ENOMEM;
+ new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
+ GFP_KERNEL);
+ if (!new)
+ goto out;
+ ret = 0;
+ kfree(tbl->slots);
}
spin_lock(&tbl->slot_tbl_lock);
- for (i = 0; i < max_slots; ++i)
+ if (new) {
+ tbl->slots = new;
+ tbl->max_slots = max_reqs;
+ }
+ for (i = 0; i < tbl->max_slots; ++i)
tbl->slots[i].seq_nr = ivalue;
spin_unlock(&tbl->slot_tbl_lock);
dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
@@ -4648,16 +4676,12 @@ static int nfs4_reset_slot_tables(struct nfs4_session *session)
int status;
status = nfs4_reset_slot_table(&session->fc_slot_table,
- session->fc_attrs.max_reqs,
- session->fc_slot_table.max_slots,
- 1);
+ session->fc_attrs.max_reqs, 1);
if (status)
return status;
status = nfs4_reset_slot_table(&session->bc_slot_table,
- session->bc_attrs.max_reqs,
- session->bc_slot_table.max_slots,
- 0);
+ session->bc_attrs.max_reqs, 0);
return status;
}
@@ -4798,16 +4822,14 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
args->fc_attrs.headerpadsz = 0;
args->fc_attrs.max_rqst_sz = mxrqst_sz;
args->fc_attrs.max_resp_sz = mxresp_sz;
- args->fc_attrs.max_resp_sz_cached = mxresp_sz;
args->fc_attrs.max_ops = NFS4_MAX_OPS;
args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs;
dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u "
- "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
+ "max_ops=%u max_reqs=%u\n",
__func__,
args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz,
- args->fc_attrs.max_resp_sz_cached, args->fc_attrs.max_ops,
- args->fc_attrs.max_reqs);
+ args->fc_attrs.max_ops, args->fc_attrs.max_reqs);
/* Back channel attributes */
args->bc_attrs.headerpadsz = 0;
@@ -5016,7 +5038,16 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
&res, args.sa_cache_this, 1);
}
-void nfs41_sequence_call_done(struct rpc_task *task, void *data)
+static void nfs41_sequence_release(void *data)
+{
+ struct nfs_client *clp = (struct nfs_client *)data;
+
+ if (atomic_read(&clp->cl_count) > 1)
+ nfs4_schedule_state_renewal(clp);
+ nfs_put_client(clp);
+}
+
+static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
{
struct nfs_client *clp = (struct nfs_client *)data;
@@ -5024,6 +5055,8 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
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) {
@@ -5032,7 +5065,7 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
}
}
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);
@@ -5057,6 +5090,7 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
static const struct rpc_call_ops nfs41_sequence_ops = {
.rpc_call_done = nfs41_sequence_call_done,
.rpc_call_prepare = nfs41_sequence_prepare,
+ .rpc_release = nfs41_sequence_release,
};
static int nfs41_proc_async_sequence(struct nfs_client *clp,
@@ -5069,12 +5103,14 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
.rpc_cred = cred,
};
+ if (!atomic_inc_not_zero(&clp->cl_count))
+ return -EIO;
args = kzalloc(sizeof(*args), GFP_KERNEL);
- if (!args)
- return -ENOMEM;
res = kzalloc(sizeof(*res), GFP_KERNEL);
- if (!res) {
+ if (!args || !res) {
kfree(args);
+ kfree(res);
+ nfs_put_client(clp);
return -ENOMEM;
}
res->sr_slotid = NFS4_MAX_SLOT_TABLE;
@@ -5182,9 +5218,12 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
msg.rpc_resp = &calldata->res;
task_setup_data.callback_data = calldata;
task = rpc_run_task(&task_setup_data);
- if (IS_ERR(task))
+ if (IS_ERR(task)) {
status = PTR_ERR(task);
+ goto out;
+ }
rpc_put_task(task);
+ return 0;
out:
dprintk("<-- %s status=%d\n", __func__, status);
return status;
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 0156c01c212..d87f10327b7 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -36,11 +36,6 @@
* as an rpc_task, not a real kernel thread, so it always runs in rpciod's
* context. There is one renewd per nfs_server.
*
- * TODO: If the send queue gets backlogged (e.g., if the server goes down),
- * we will keep filling the queue with periodic RENEW requests. We need a
- * mechanism for ensuring that if renewd successfully sends off a request,
- * then it only wakes up when the request is finished. Maybe use the
- * child task framework of the RPC layer?
*/
#include <linux/mm.h>
@@ -63,7 +58,7 @@ nfs4_renew_state(struct work_struct *work)
struct nfs_client *clp =
container_of(work, struct nfs_client, cl_renewd.work);
struct rpc_cred *cred;
- long lease, timeout;
+ long lease;
unsigned long last, now;
ops = nfs4_state_renewal_ops[clp->cl_minorversion];
@@ -75,7 +70,6 @@ nfs4_renew_state(struct work_struct *work)
lease = clp->cl_lease_time;
last = clp->cl_last_renewal;
now = jiffies;
- timeout = (2 * lease) / 3 + (long)last - (long)now;
/* Are we close to a lease timeout? */
if (time_after(now, last + lease/3)) {
cred = ops->get_state_renewal_cred_locked(clp);
@@ -90,19 +84,15 @@ nfs4_renew_state(struct work_struct *work)
/* Queue an asynchronous RENEW. */
ops->sched_state_renewal(clp, cred);
put_rpccred(cred);
+ goto out_exp;
}
- timeout = (2 * lease) / 3;
- spin_lock(&clp->cl_lock);
- } else
+ } else {
dprintk("%s: failed to call renewd. Reason: lease not expired \n",
__func__);
- if (timeout < 5 * HZ) /* safeguard */
- timeout = 5 * HZ;
- dprintk("%s: requeueing work. Lease period = %ld\n",
- __func__, (timeout + HZ - 1) / HZ);
- cancel_delayed_work(&clp->cl_renewd);
- schedule_delayed_work(&clp->cl_renewd, timeout);
- spin_unlock(&clp->cl_lock);
+ spin_unlock(&clp->cl_lock);
+ }
+ nfs4_schedule_state_renewal(clp);
+out_exp:
nfs_expire_unreferenced_delegations(clp);
out:
dprintk("%s: done\n", __func__);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index c1e2733f4fa..6c5ed51f105 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1249,26 +1249,65 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
}
#ifdef CONFIG_NFS_V4_1
+void nfs41_handle_recall_slot(struct nfs_client *clp)
+{
+ set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
+ nfs4_schedule_state_recovery(clp);
+}
+
+static void nfs4_reset_all_state(struct nfs_client *clp)
+{
+ if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
+ clp->cl_boot_time = CURRENT_TIME;
+ nfs4_state_start_reclaim_nograce(clp);
+ nfs4_schedule_state_recovery(clp);
+ }
+}
+
+static void nfs41_handle_server_reboot(struct nfs_client *clp)
+{
+ if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
+ nfs4_state_start_reclaim_reboot(clp);
+ nfs4_schedule_state_recovery(clp);
+ }
+}
+
+static void nfs41_handle_state_revoked(struct nfs_client *clp)
+{
+ /* Temporary */
+ nfs4_reset_all_state(clp);
+}
+
+static void nfs41_handle_recallable_state_revoked(struct nfs_client *clp)
+{
+ /* This will need to handle layouts too */
+ nfs_expire_all_delegations(clp);
+}
+
+static void nfs41_handle_cb_path_down(struct nfs_client *clp)
+{
+ nfs_expire_all_delegations(clp);
+ if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0)
+ nfs4_schedule_state_recovery(clp);
+}
+
void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
{
if (!flags)
return;
- else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) {
- set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
- nfs4_state_start_reclaim_reboot(clp);
- nfs4_schedule_state_recovery(clp);
- } else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
+ else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED)
+ nfs41_handle_server_reboot(clp);
+ else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED |
SEQ4_STATUS_ADMIN_STATE_REVOKED |
- SEQ4_STATUS_RECALLABLE_STATE_REVOKED |
- SEQ4_STATUS_LEASE_MOVED)) {
- set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
- nfs4_state_start_reclaim_nograce(clp);
- nfs4_schedule_state_recovery(clp);
- } else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
+ SEQ4_STATUS_LEASE_MOVED))
+ nfs41_handle_state_revoked(clp);
+ else if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED)
+ nfs41_handle_recallable_state_revoked(clp);
+ else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
SEQ4_STATUS_BACKCHANNEL_FAULT |
SEQ4_STATUS_CB_PATH_DOWN_SESSION))
- nfs_expire_all_delegations(clp);
+ nfs41_handle_cb_path_down(clp);
}
static int nfs4_reset_session(struct nfs_client *clp)
@@ -1285,23 +1324,52 @@ static int nfs4_reset_session(struct nfs_client *clp)
memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN);
status = nfs4_proc_create_session(clp);
- if (status)
+ if (status) {
status = nfs4_recovery_handle_error(clp, status);
+ goto out;
+ }
+ /* create_session negotiated new slot table */
+ clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
-out:
- /*
- * Let the state manager reestablish state
- */
- if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
- status == 0)
+ /* Let the state manager reestablish state */
+ if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
nfs41_setup_state_renewal(clp);
-
+out:
return status;
}
+static int nfs4_recall_slot(struct nfs_client *clp)
+{
+ struct nfs4_slot_table *fc_tbl = &clp->cl_session->fc_slot_table;
+ struct nfs4_channel_attrs *fc_attrs = &clp->cl_session->fc_attrs;
+ struct nfs4_slot *new, *old;
+ int i;
+
+ nfs4_begin_drain_session(clp);
+ new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot),
+ GFP_KERNEL);
+ if (!new)
+ return -ENOMEM;
+
+ spin_lock(&fc_tbl->slot_tbl_lock);
+ for (i = 0; i < fc_tbl->target_max_slots; i++)
+ new[i].seq_nr = fc_tbl->slots[i].seq_nr;
+ old = fc_tbl->slots;
+ fc_tbl->slots = new;
+ fc_tbl->max_slots = fc_tbl->target_max_slots;
+ fc_tbl->target_max_slots = 0;
+ fc_attrs->max_reqs = fc_tbl->max_slots;
+ spin_unlock(&fc_tbl->slot_tbl_lock);
+
+ kfree(old);
+ nfs4_end_drain_session(clp);
+ return 0;
+}
+
#else /* CONFIG_NFS_V4_1 */
static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; }
+static int nfs4_recall_slot(struct nfs_client *clp) { return 0; }
#endif /* CONFIG_NFS_V4_1 */
/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
@@ -1314,6 +1382,7 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
case -NFS4ERR_DELAY:
case -NFS4ERR_CLID_INUSE:
case -EAGAIN:
+ case -EKEYEXPIRED:
break;
case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
@@ -1397,6 +1466,15 @@ static void nfs4_state_manager(struct nfs_client *clp)
nfs_client_return_marked_delegations(clp);
continue;
}
+ /* Recall session slots */
+ if (test_and_clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state)
+ && nfs4_has_session(clp)) {
+ status = nfs4_recall_slot(clp);
+ if (status < 0)
+ goto out_error;
+ continue;
+ }
+
nfs4_clear_state_manager_bit(clp);
/* Did we race with an attempt to give us more work? */
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 5cd5184b56d..38f3b582e7c 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -38,7 +38,6 @@
#include <linux/param.h>
#include <linux/time.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/in.h>
@@ -1578,6 +1577,14 @@ static void encode_create_session(struct xdr_stream *xdr,
char machine_name[NFS4_MAX_MACHINE_NAME_LEN];
uint32_t len;
struct nfs_client *clp = args->client;
+ u32 max_resp_sz_cached;
+
+ /*
+ * Assumes OPEN is the biggest non-idempotent compound.
+ * 2 is the verifier.
+ */
+ max_resp_sz_cached = (NFS4_dec_open_sz + RPC_REPHDRSIZE +
+ RPC_MAX_AUTH_SIZE + 2) * XDR_UNIT;
len = scnprintf(machine_name, sizeof(machine_name), "%s",
clp->cl_ipaddr);
@@ -1592,7 +1599,7 @@ static void encode_create_session(struct xdr_stream *xdr,
*p++ = cpu_to_be32(args->fc_attrs.headerpadsz); /* header padding size */
*p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */
*p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */
- *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz_cached); /* Max resp sz cached */
+ *p++ = cpu_to_be32(max_resp_sz_cached); /* Max resp sz cached */
*p++ = cpu_to_be32(args->fc_attrs.max_ops); /* max operations */
*p++ = cpu_to_be32(args->fc_attrs.max_reqs); /* max requests */
*p++ = cpu_to_be32(0); /* rdmachannel_attrs */
@@ -5544,6 +5551,8 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf
if (status != 0)
goto out;
status = decode_delegreturn(&xdr);
+ if (status != 0)
+ goto out;
decode_getfattr(&xdr, res->fattr, res->server,
!RPC_IS_ASYNC(rqstp->rq_task));
out:
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index a12c45b65dd..29d9d36cd5f 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -112,12 +112,10 @@ void nfs_unlock_request(struct nfs_page *req)
*/
int nfs_set_page_tag_locked(struct nfs_page *req)
{
- struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode);
-
if (!nfs_lock_request_dontget(req))
return 0;
if (req->wb_page != NULL)
- radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
+ radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
return 1;
}
@@ -126,10 +124,10 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
*/
void nfs_clear_page_tag_locked(struct nfs_page *req)
{
- struct inode *inode = req->wb_context->path.dentry->d_inode;
- struct nfs_inode *nfsi = NFS_I(inode);
-
if (req->wb_page != NULL) {
+ struct inode *inode = req->wb_context->path.dentry->d_inode;
+ struct nfs_inode *nfsi = NFS_I(inode);
+
spin_lock(&inode->i_lock);
radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
nfs_unlock_request(req);
@@ -142,16 +140,22 @@ void nfs_clear_page_tag_locked(struct nfs_page *req)
* nfs_clear_request - Free up all resources allocated to the request
* @req:
*
- * Release page resources associated with a write request after it
- * has completed.
+ * Release page and open context resources associated with a read/write
+ * request after it has completed.
*/
void nfs_clear_request(struct nfs_page *req)
{
struct page *page = req->wb_page;
+ struct nfs_open_context *ctx = req->wb_context;
+
if (page != NULL) {
page_cache_release(page);
req->wb_page = NULL;
}
+ if (ctx != NULL) {
+ put_nfs_open_context(ctx);
+ req->wb_context = NULL;
+ }
}
@@ -165,9 +169,8 @@ static void nfs_free_request(struct kref *kref)
{
struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
- /* Release struct file or cached credential */
+ /* Release struct file and open context */
nfs_clear_request(req);
- put_nfs_open_context(req->wb_context);
nfs_page_free(req);
}
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index ef583854d8d..0288be80444 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -29,7 +29,6 @@
#include <linux/types.h>
#include <linux/param.h>
-#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/errno.h>
@@ -47,6 +46,39 @@
#define NFSDBG_FACILITY NFSDBG_PROC
/*
+ * wrapper to handle the -EKEYEXPIRED error message. This should generally
+ * only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't
+ * support the NFSERR_JUKEBOX error code, but we handle this situation in the
+ * same way that we handle that error with NFSv3.
+ */
+static int
+nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
+{
+ int res;
+ do {
+ res = rpc_call_sync(clnt, msg, flags);
+ if (res != -EKEYEXPIRED)
+ break;
+ schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
+ res = -ERESTARTSYS;
+ } while (!fatal_signal_pending(current));
+ return res;
+}
+
+#define rpc_call_sync(clnt, msg, flags) nfs_rpc_wrapper(clnt, msg, flags)
+
+static int
+nfs_async_handle_expired_key(struct rpc_task *task)
+{
+ if (task->tk_status != -EKEYEXPIRED)
+ return 0;
+ task->tk_status = 0;
+ rpc_restart_call(task);
+ rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
+ return 1;
+}
+
+/*
* Bare-bones access to getattr: this is for nfs_read_super.
*/
static int
@@ -307,6 +339,8 @@ nfs_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
{
+ if (nfs_async_handle_expired_key(task))
+ return 0;
nfs_mark_for_revalidate(dir);
return 1;
}
@@ -560,6 +594,9 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
{
+ if (nfs_async_handle_expired_key(task))
+ return -EAGAIN;
+
nfs_invalidate_atime(data->inode);
if (task->tk_status >= 0) {
nfs_refresh_inode(data->inode, data->res.fattr);
@@ -579,6 +616,9 @@ static void nfs_proc_read_setup(struct nfs_read_data *data, struct rpc_message *
static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
{
+ if (nfs_async_handle_expired_key(task))
+ return -EAGAIN;
+
if (task->tk_status >= 0)
nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr);
return 0;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f1afee4eea7..b4148fc00f9 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -48,6 +48,7 @@
#include <linux/vfs.h>
#include <linux/inet.h>
#include <linux/in6.h>
+#include <linux/slab.h>
#include <net/ipv6.h>
#include <linux/netdevice.h>
#include <linux/nfs_xdr.h>
@@ -2186,6 +2187,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
if (data->version == 4) {
error = nfs4_try_mount(flags, dev_name, data, mnt);
kfree(data->client_address);
+ kfree(data->nfs_server.export_path);
goto out;
}
#endif /* CONFIG_NFS_V4 */
@@ -2214,7 +2216,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
} else {
error = nfs_bdi_register(server);
if (error)
- goto error_splat_super;
+ goto error_splat_bdi;
}
if (!s->s_root) {
@@ -2256,6 +2258,9 @@ out_err_nosb:
error_splat_root:
dput(mntroot);
error_splat_super:
+ if (server && !s->s_root)
+ bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
deactivate_locked_super(s);
goto out;
}
@@ -2326,7 +2331,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
} else {
error = nfs_bdi_register(server);
if (error)
- goto error_splat_super;
+ goto error_splat_bdi;
}
if (!s->s_root) {
@@ -2363,6 +2368,9 @@ out_err_noserver:
return error;
error_splat_super:
+ if (server && !s->s_root)
+ bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
deactivate_locked_super(s);
dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
return error;
@@ -2578,7 +2586,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
} else {
error = nfs_bdi_register(server);
if (error)
- goto error_splat_super;
+ goto error_splat_bdi;
}
if (!s->s_root) {
@@ -2616,6 +2624,9 @@ out_free:
error_splat_root:
dput(mntroot);
error_splat_super:
+ if (server && !s->s_root)
+ bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
deactivate_locked_super(s);
goto out;
}
@@ -2647,7 +2658,7 @@ static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt)
devname = nfs_path(path->mnt->mnt_devname,
path->mnt->mnt_root, path->dentry,
page, PAGE_SIZE);
- if (devname == NULL)
+ if (IS_ERR(devname))
goto out_freepage;
tmp = kstrdup(devname, GFP_KERNEL);
if (tmp == NULL)
@@ -2811,7 +2822,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
} else {
error = nfs_bdi_register(server);
if (error)
- goto error_splat_super;
+ goto error_splat_bdi;
}
if (!s->s_root) {
@@ -2847,6 +2858,9 @@ out_err_noserver:
return error;
error_splat_super:
+ if (server && !s->s_root)
+ bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
deactivate_locked_super(s);
dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
return error;
@@ -2893,7 +2907,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
} else {
error = nfs_bdi_register(server);
if (error)
- goto error_splat_super;
+ goto error_splat_bdi;
}
if (!s->s_root) {
@@ -2929,6 +2943,9 @@ out_err_noserver:
return error;
error_splat_super:
+ if (server && !s->s_root)
+ bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
deactivate_locked_super(s);
dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
return error;
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index 412738dbfbc..05c9e02f415 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -19,7 +19,6 @@
#include <linux/pagemap.h>
#include <linux/stat.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/namei.h>
@@ -50,7 +49,7 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
struct page *page;
void *err;
- err = ERR_PTR(nfs_revalidate_mapping_nolock(inode, inode->i_mapping));
+ err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
if (err)
goto read_failed;
page = read_cache_page(&inode->i_data, 0,
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index d63d964a039..3aea3ca98ab 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -201,6 +201,7 @@ static int nfs_set_page_writeback(struct page *page)
struct inode *inode = page->mapping->host;
struct nfs_server *nfss = NFS_SERVER(inode);
+ page_cache_get(page);
if (atomic_long_inc_return(&nfss->writeback) >
NFS_CONGESTION_ON_THRESH) {
set_bdi_congested(&nfss->backing_dev_info,
@@ -216,6 +217,7 @@ static void nfs_end_page_writeback(struct page *page)
struct nfs_server *nfss = NFS_SERVER(inode);
end_page_writeback(page);
+ page_cache_release(page);
if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC);
}
@@ -421,6 +423,7 @@ static void
nfs_mark_request_dirty(struct nfs_page *req)
{
__set_page_dirty_nobuffers(req->wb_page);
+ __mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC);
}
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -438,6 +441,7 @@ nfs_mark_request_commit(struct nfs_page *req)
radix_tree_tag_set(&nfsi->nfs_page_tree,
req->wb_index,
NFS_PAGE_TAG_COMMIT);
+ nfsi->ncommit++;
spin_unlock(&inode->i_lock);
inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
inc_bdi_stat(req->wb_page->mapping->backing_dev_info, BDI_RECLAIMABLE);
@@ -501,57 +505,6 @@ int nfs_reschedule_unstable_write(struct nfs_page *req)
}
#endif
-/*
- * Wait for a request to complete.
- *
- * Interruptible by fatal signals only.
- */
-static int nfs_wait_on_requests_locked(struct inode *inode, pgoff_t idx_start, unsigned int npages)
-{
- struct nfs_inode *nfsi = NFS_I(inode);
- struct nfs_page *req;
- pgoff_t idx_end, next;
- unsigned int res = 0;
- int error;
-
- if (npages == 0)
- idx_end = ~0;
- else
- idx_end = idx_start + npages - 1;
-
- next = idx_start;
- while (radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, (void **)&req, next, 1, NFS_PAGE_TAG_LOCKED)) {
- if (req->wb_index > idx_end)
- break;
-
- next = req->wb_index + 1;
- BUG_ON(!NFS_WBACK_BUSY(req));
-
- kref_get(&req->wb_kref);
- spin_unlock(&inode->i_lock);
- error = nfs_wait_on_request(req);
- nfs_release_request(req);
- spin_lock(&inode->i_lock);
- if (error < 0)
- return error;
- res++;
- }
- return res;
-}
-
-static void nfs_cancel_commit_list(struct list_head *head)
-{
- struct nfs_page *req;
-
- while(!list_empty(head)) {
- req = nfs_list_entry(head->next);
- nfs_list_remove_request(req);
- nfs_clear_request_commit(req);
- nfs_inode_remove_request(req);
- nfs_unlock_request(req);
- }
-}
-
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
static int
nfs_need_commit(struct nfs_inode *nfsi)
@@ -573,11 +526,17 @@ static int
nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages)
{
struct nfs_inode *nfsi = NFS_I(inode);
+ int ret;
if (!nfs_need_commit(nfsi))
return 0;
- return nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT);
+ ret = nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT);
+ if (ret > 0)
+ nfsi->ncommit -= ret;
+ if (nfs_need_commit(NFS_I(inode)))
+ __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
+ return ret;
}
#else
static inline int nfs_need_commit(struct nfs_inode *nfsi)
@@ -642,9 +601,10 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode,
spin_lock(&inode->i_lock);
}
- if (nfs_clear_request_commit(req))
- radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree,
- req->wb_index, NFS_PAGE_TAG_COMMIT);
+ if (nfs_clear_request_commit(req) &&
+ radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree,
+ req->wb_index, NFS_PAGE_TAG_COMMIT) != NULL)
+ NFS_I(inode)->ncommit--;
/* Okay, the request matches. Update the region */
if (offset < req->wb_offset) {
@@ -703,9 +663,11 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
req = nfs_setup_write_request(ctx, page, offset, count);
if (IS_ERR(req))
return PTR_ERR(req);
+ nfs_mark_request_dirty(req);
/* Update file length */
nfs_grow_file(page, offset, count);
nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes);
+ nfs_mark_request_dirty(req);
nfs_clear_page_tag_locked(req);
return 0;
}
@@ -782,8 +744,6 @@ int nfs_updatepage(struct file *file, struct page *page,
status = nfs_writepage_setup(ctx, page, offset, count);
if (status < 0)
nfs_set_pageerror(page);
- else
- __set_page_dirty_nobuffers(page);
dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n",
status, (long long)i_size_read(inode));
@@ -792,13 +752,12 @@ int nfs_updatepage(struct file *file, struct page *page,
static void nfs_writepage_release(struct nfs_page *req)
{
+ struct page *page = req->wb_page;
- if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) {
- nfs_end_page_writeback(req->wb_page);
+ if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req))
nfs_inode_remove_request(req);
- } else
- nfs_end_page_writeback(req->wb_page);
nfs_clear_page_tag_locked(req);
+ nfs_end_page_writeback(page);
}
static int flush_task_priority(int how)
@@ -822,7 +781,6 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
int how)
{
struct inode *inode = req->wb_context->path.dentry->d_inode;
- int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
int priority = flush_task_priority(how);
struct rpc_task *task;
struct rpc_message msg = {
@@ -837,9 +795,10 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
.callback_ops = call_ops,
.callback_data = data,
.workqueue = nfsiod_workqueue,
- .flags = flags,
+ .flags = RPC_TASK_ASYNC,
.priority = priority,
};
+ int ret = 0;
/* Set up the RPC argument and reply structs
* NB: take care not to mess about with data->commit et al. */
@@ -878,10 +837,18 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
(unsigned long long)data->args.offset);
task = rpc_run_task(&task_setup_data);
- if (IS_ERR(task))
- return PTR_ERR(task);
+ if (IS_ERR(task)) {
+ ret = PTR_ERR(task);
+ goto out;
+ }
+ if (how & FLUSH_SYNC) {
+ ret = rpc_wait_for_completion_task(task);
+ if (ret == 0)
+ ret = task->tk_status;
+ }
rpc_put_task(task);
- return 0;
+out:
+ return ret;
}
/* If a nfs_flush_* function fails, it should remove reqs from @head and
@@ -890,9 +857,11 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
*/
static void nfs_redirty_request(struct nfs_page *req)
{
+ struct page *page = req->wb_page;
+
nfs_mark_request_dirty(req);
- nfs_end_page_writeback(req->wb_page);
nfs_clear_page_tag_locked(req);
+ nfs_end_page_writeback(page);
}
/*
@@ -1127,16 +1096,15 @@ static void nfs_writeback_release_full(void *calldata)
if (nfs_write_need_commit(data)) {
memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
nfs_mark_request_commit(req);
- nfs_end_page_writeback(page);
dprintk(" marked for commit\n");
goto next;
}
dprintk(" OK\n");
remove_request:
- nfs_end_page_writeback(page);
nfs_inode_remove_request(req);
next:
nfs_clear_page_tag_locked(req);
+ nfs_end_page_writeback(page);
}
nfs_writedata_release(calldata);
}
@@ -1233,6 +1201,25 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
+{
+ if (!test_and_set_bit(NFS_INO_COMMIT, &nfsi->flags))
+ return 1;
+ if (may_wait && !out_of_line_wait_on_bit_lock(&nfsi->flags,
+ NFS_INO_COMMIT, nfs_wait_bit_killable,
+ TASK_KILLABLE))
+ return 1;
+ return 0;
+}
+
+static void nfs_commit_clear_lock(struct nfs_inode *nfsi)
+{
+ clear_bit(NFS_INO_COMMIT, &nfsi->flags);
+ smp_mb__after_clear_bit();
+ wake_up_bit(&nfsi->flags, NFS_INO_COMMIT);
+}
+
+
static void nfs_commitdata_release(void *data)
{
struct nfs_write_data *wdata = data;
@@ -1250,7 +1237,6 @@ static int nfs_commit_rpcsetup(struct list_head *head,
{
struct nfs_page *first = nfs_list_entry(head->next);
struct inode *inode = first->wb_context->path.dentry->d_inode;
- int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
int priority = flush_task_priority(how);
struct rpc_task *task;
struct rpc_message msg = {
@@ -1265,7 +1251,7 @@ static int nfs_commit_rpcsetup(struct list_head *head,
.callback_ops = &nfs_commit_ops,
.callback_data = data,
.workqueue = nfsiod_workqueue,
- .flags = flags,
+ .flags = RPC_TASK_ASYNC,
.priority = priority,
};
@@ -1325,6 +1311,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
BDI_RECLAIMABLE);
nfs_clear_page_tag_locked(req);
}
+ nfs_commit_clear_lock(NFS_I(inode));
return -ENOMEM;
}
@@ -1380,6 +1367,7 @@ static void nfs_commit_release(void *calldata)
next:
nfs_clear_page_tag_locked(req);
}
+ nfs_commit_clear_lock(NFS_I(data->inode));
nfs_commitdata_release(calldata);
}
@@ -1391,11 +1379,14 @@ static const struct rpc_call_ops nfs_commit_ops = {
.rpc_release = nfs_commit_release,
};
-int nfs_commit_inode(struct inode *inode, int how)
+static int nfs_commit_inode(struct inode *inode, int how)
{
LIST_HEAD(head);
- int res;
+ int may_wait = how & FLUSH_SYNC;
+ int res = 0;
+ if (!nfs_commit_set_lock(NFS_I(inode), may_wait))
+ goto out;
spin_lock(&inode->i_lock);
res = nfs_scan_commit(inode, &head, 0, 0);
spin_unlock(&inode->i_lock);
@@ -1403,95 +1394,60 @@ int nfs_commit_inode(struct inode *inode, int how)
int error = nfs_commit_list(inode, &head, how);
if (error < 0)
return error;
- }
+ if (may_wait)
+ wait_on_bit(&NFS_I(inode)->flags, NFS_INO_COMMIT,
+ nfs_wait_bit_killable,
+ TASK_KILLABLE);
+ } else
+ nfs_commit_clear_lock(NFS_I(inode));
+out:
return res;
}
-#else
-static inline int nfs_commit_list(struct inode *inode, struct list_head *head, int how)
-{
- return 0;
-}
-#endif
-long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how)
+static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_control *wbc)
{
- struct inode *inode = mapping->host;
- pgoff_t idx_start, idx_end;
- unsigned int npages = 0;
- LIST_HEAD(head);
- int nocommit = how & FLUSH_NOCOMMIT;
- long pages, ret;
-
- /* FIXME */
- if (wbc->range_cyclic)
- idx_start = 0;
- else {
- idx_start = wbc->range_start >> PAGE_CACHE_SHIFT;
- idx_end = wbc->range_end >> PAGE_CACHE_SHIFT;
- if (idx_end > idx_start) {
- pgoff_t l_npages = 1 + idx_end - idx_start;
- npages = l_npages;
- if (sizeof(npages) != sizeof(l_npages) &&
- (pgoff_t)npages != l_npages)
- npages = 0;
+ struct nfs_inode *nfsi = NFS_I(inode);
+ int flags = FLUSH_SYNC;
+ int ret = 0;
+
+ /* Don't commit yet if this is a non-blocking flush and there are
+ * lots of outstanding writes for this mapping.
+ */
+ if (wbc->sync_mode == WB_SYNC_NONE &&
+ nfsi->ncommit <= (nfsi->npages >> 1))
+ goto out_mark_dirty;
+
+ if (wbc->nonblocking || wbc->for_background)
+ flags = 0;
+ ret = nfs_commit_inode(inode, flags);
+ if (ret >= 0) {
+ if (wbc->sync_mode == WB_SYNC_NONE) {
+ if (ret < wbc->nr_to_write)
+ wbc->nr_to_write -= ret;
+ else
+ wbc->nr_to_write = 0;
}
+ return 0;
}
- how &= ~FLUSH_NOCOMMIT;
- spin_lock(&inode->i_lock);
- do {
- ret = nfs_wait_on_requests_locked(inode, idx_start, npages);
- if (ret != 0)
- continue;
- if (nocommit)
- break;
- pages = nfs_scan_commit(inode, &head, idx_start, npages);
- if (pages == 0)
- break;
- if (how & FLUSH_INVALIDATE) {
- spin_unlock(&inode->i_lock);
- nfs_cancel_commit_list(&head);
- ret = pages;
- spin_lock(&inode->i_lock);
- continue;
- }
- pages += nfs_scan_commit(inode, &head, 0, 0);
- spin_unlock(&inode->i_lock);
- ret = nfs_commit_list(inode, &head, how);
- spin_lock(&inode->i_lock);
-
- } while (ret >= 0);
- spin_unlock(&inode->i_lock);
+out_mark_dirty:
+ __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
return ret;
}
-
-static int __nfs_write_mapping(struct address_space *mapping, struct writeback_control *wbc, int how)
+#else
+static int nfs_commit_inode(struct inode *inode, int how)
{
- int ret;
-
- ret = nfs_writepages(mapping, wbc);
- if (ret < 0)
- goto out;
- ret = nfs_sync_mapping_wait(mapping, wbc, how);
- if (ret < 0)
- goto out;
return 0;
-out:
- __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
- return ret;
}
-/* Two pass sync: first using WB_SYNC_NONE, then WB_SYNC_ALL */
-static int nfs_write_mapping(struct address_space *mapping, int how)
+static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_control *wbc)
{
- struct writeback_control wbc = {
- .bdi = mapping->backing_dev_info,
- .sync_mode = WB_SYNC_ALL,
- .nr_to_write = LONG_MAX,
- .range_start = 0,
- .range_end = LLONG_MAX,
- };
+ return 0;
+}
+#endif
- return __nfs_write_mapping(mapping, &wbc, how);
+int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ return nfs_commit_unstable_pages(inode, wbc);
}
/*
@@ -1499,37 +1455,27 @@ static int nfs_write_mapping(struct address_space *mapping, int how)
*/
int nfs_wb_all(struct inode *inode)
{
- return nfs_write_mapping(inode->i_mapping, 0);
-}
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_ALL,
+ .nr_to_write = LONG_MAX,
+ .range_start = 0,
+ .range_end = LLONG_MAX,
+ };
-int nfs_wb_nocommit(struct inode *inode)
-{
- return nfs_write_mapping(inode->i_mapping, FLUSH_NOCOMMIT);
+ return sync_inode(inode, &wbc);
}
int nfs_wb_page_cancel(struct inode *inode, struct page *page)
{
struct nfs_page *req;
- loff_t range_start = page_offset(page);
- loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1);
- struct writeback_control wbc = {
- .bdi = page->mapping->backing_dev_info,
- .sync_mode = WB_SYNC_ALL,
- .nr_to_write = LONG_MAX,
- .range_start = range_start,
- .range_end = range_end,
- };
int ret = 0;
BUG_ON(!PageLocked(page));
for (;;) {
+ wait_on_page_writeback(page);
req = nfs_page_find_request(page);
if (req == NULL)
- goto out;
- if (test_bit(PG_CLEAN, &req->wb_flags)) {
- nfs_release_request(req);
break;
- }
if (nfs_lock_request_dontget(req)) {
nfs_inode_remove_request(req);
/*
@@ -1543,54 +1489,42 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
ret = nfs_wait_on_request(req);
nfs_release_request(req);
if (ret < 0)
- goto out;
+ break;
}
- if (!PagePrivate(page))
- return 0;
- ret = nfs_sync_mapping_wait(page->mapping, &wbc, FLUSH_INVALIDATE);
-out:
return ret;
}
-static int nfs_wb_page_priority(struct inode *inode, struct page *page,
- int how)
+/*
+ * Write back all requests on one page - we do this before reading it.
+ */
+int nfs_wb_page(struct inode *inode, struct page *page)
{
loff_t range_start = page_offset(page);
loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1);
struct writeback_control wbc = {
- .bdi = page->mapping->backing_dev_info,
.sync_mode = WB_SYNC_ALL,
- .nr_to_write = LONG_MAX,
+ .nr_to_write = 0,
.range_start = range_start,
.range_end = range_end,
};
int ret;
- do {
+ while(PagePrivate(page)) {
+ wait_on_page_writeback(page);
if (clear_page_dirty_for_io(page)) {
ret = nfs_writepage_locked(page, &wbc);
if (ret < 0)
goto out_error;
- } else if (!PagePrivate(page))
- break;
- ret = nfs_sync_mapping_wait(page->mapping, &wbc, how);
+ }
+ ret = sync_inode(inode, &wbc);
if (ret < 0)
goto out_error;
- } while (PagePrivate(page));
+ }
return 0;
out_error:
- __mark_inode_dirty(inode, I_DIRTY_PAGES);
return ret;
}
-/*
- * Write back all requests on one page - we do this before reading it.
- */
-int nfs_wb_page(struct inode *inode, struct page* page)
-{
- return nfs_wb_page_priority(inode, page, FLUSH_STABLE);
-}
-
#ifdef CONFIG_MIGRATION
int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
struct page *page)
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
index 04133aacb1e..fc1c52571c0 100644
--- a/fs/nfs_common/nfsacl.c
+++ b/fs/nfs_common/nfsacl.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/sunrpc/xdr.h>
#include <linux/nfsacl.h>
#include <linux/nfs3.h>
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index a0c4016413f..872a5ef550c 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -12,6 +12,7 @@
* Copyright (C) 1995, 1996 Olaf Kirch, <okir@monad.swb.de>
*/
+#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/module.h>
#include <linux/exportfs.h>
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index f20589d2ae2..6aa5590c367 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -7,6 +7,7 @@
#include "nfsd.h"
/* FIXME: nfsacl.h is a broken header */
#include <linux/nfsacl.h>
+#include <linux/gfp.h>
#include "cache.h"
#include "xdr3.h"
#include "vfs.h"
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index e0c4846bad9..a596e9d987e 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -7,6 +7,7 @@
#include "nfsd.h"
/* FIXME: nfsacl.h is a broken header */
#include <linux/nfsacl.h>
+#include <linux/gfp.h>
#include "cache.h"
#include "xdr3.h"
#include "vfs.h"
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 88150685df3..e4805261515 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -34,6 +34,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/slab.h>
#include <linux/nfs_fs.h>
#include <linux/nfs4_acl.h>
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index c6eed2a3b09..7e32bd394e8 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -32,6 +32,7 @@
*/
#include <linux/sunrpc/clnt.h>
+#include <linux/slab.h>
#include "nfsd.h"
#include "state.h"
@@ -525,6 +526,8 @@ static struct rpc_cred *callback_cred;
int set_callback_cred(void)
{
+ if (callback_cred)
+ return 0;
callback_cred = rpc_lookup_machine_cred();
if (!callback_cred)
return -ENOMEM;
@@ -542,7 +545,8 @@ void do_probe_callback(struct nfs4_client *clp)
};
int status;
- status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_SOFT,
+ status = rpc_call_async(cb->cb_client, &msg,
+ RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
&nfsd4_cb_probe_ops, (void *)clp);
if (status) {
warn_no_callback_path(clp, status);
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 6e2983b27f3..c78dbf49342 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -36,6 +36,7 @@
#include <linux/nfsd_idmap.h>
#include <linux/seq_file.h>
#include <linux/sched.h>
+#include <linux/slab.h>
/*
* Cache entry
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 37514c46984..2ab9e8501bf 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -33,6 +33,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/file.h>
+#include <linux/slab.h>
#include "cache.h"
#include "xdr4.h"
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 5a754f7b71e..7a9ae3254a4 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -32,6 +32,7 @@
*/
#include <linux/file.h>
+#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/crypto.h>
#include <linux/sched.h>
@@ -119,9 +120,7 @@ out_no_tfm:
static void
nfsd4_sync_rec_dir(void)
{
- mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
- nfsd_sync_dir(rec_dir.dentry);
- mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+ vfs_fsync(NULL, rec_dir.dentry, 0);
}
int
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index f19ed866c95..6a8fedaa4f5 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -34,6 +34,7 @@
#include <linux/file.h>
#include <linux/smp_lock.h>
+#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/swap.h>
#include <linux/sunrpc/svcauth_gss.h>
@@ -1998,7 +1999,9 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access)
{
if (share_access & NFS4_SHARE_ACCESS_WRITE) {
drop_file_write_access(filp);
+ spin_lock(&filp->f_lock);
filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
+ spin_unlock(&filp->f_lock);
}
}
@@ -2480,8 +2483,10 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
}
memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
- if (nfsd4_has_session(&resp->cstate))
+ if (nfsd4_has_session(&resp->cstate)) {
open->op_stateowner->so_confirmed = 1;
+ nfsd4_create_clid_dir(open->op_stateowner->so_client);
+ }
/*
* Attempt to hand out a delegation. No error return, because the
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index bbf72d8f9fc..34ccf815ea8 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -40,6 +40,7 @@
* at the end of nfs4svc_decode_compoundargs.
*/
+#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/statfs.h>
#include <linux/utsname.h>
@@ -160,10 +161,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
argp->p = page_address(argp->pagelist[0]);
argp->pagelist++;
if (argp->pagelen < PAGE_SIZE) {
- argp->end = p + (argp->pagelen>>2);
+ argp->end = argp->p + (argp->pagelen>>2);
argp->pagelen = 0;
} else {
- argp->end = p + (PAGE_SIZE>>2);
+ argp->end = argp->p + (PAGE_SIZE>>2);
argp->pagelen -= PAGE_SIZE;
}
memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
@@ -1425,16 +1426,16 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
argp->p = page_address(argp->pagelist[0]);
argp->pagelist++;
if (argp->pagelen < PAGE_SIZE) {
- argp->end = p + (argp->pagelen>>2);
+ argp->end = argp->p + (argp->pagelen>>2);
argp->pagelen = 0;
} else {
- argp->end = p + (PAGE_SIZE>>2);
+ argp->end = argp->p + (PAGE_SIZE>>2);
argp->pagelen -= PAGE_SIZE;
}
}
op->opnum = ntohl(*argp->p++);
- if (op->opnum >= OP_ACCESS && op->opnum < ops->nops)
+ if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
op->status = ops->decoders[op->opnum](argp, &op->u);
else {
op->opnum = OP_ILLEGAL;
@@ -1528,7 +1529,7 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
} } while (0);
/* Encode as an array of strings the string given with components
- * seperated @sep.
+ * separated @sep.
*/
static __be32 nfsd4_encode_components(char sep, char *components,
__be32 **pp, int *buflen)
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index da08560c481..4666a209678 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -8,6 +8,8 @@
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
+#include <linux/slab.h>
+
#include "nfsd.h"
#include "cache.h"
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 2604c3e70ea..e3591073098 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -4,6 +4,7 @@
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
+#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/ctype.h>
@@ -988,6 +989,7 @@ static ssize_t __write_ports_delfd(char *buf)
static ssize_t __write_ports_addxprt(char *buf)
{
char transport[16];
+ struct svc_xprt *xprt;
int port, err;
if (sscanf(buf, "%15s %4u", transport, &port) != 2)
@@ -1002,13 +1004,24 @@ static ssize_t __write_ports_addxprt(char *buf)
err = svc_create_xprt(nfsd_serv, transport,
PF_INET, port, SVC_SOCK_ANONYMOUS);
- if (err < 0) {
- /* Give a reasonable perror msg for bad transport string */
- if (err == -ENOENT)
- err = -EPROTONOSUPPORT;
- return err;
- }
+ if (err < 0)
+ goto out_err;
+
+ err = svc_create_xprt(nfsd_serv, transport,
+ PF_INET6, port, SVC_SOCK_ANONYMOUS);
+ if (err < 0 && err != -EAFNOSUPPORT)
+ goto out_close;
return 0;
+out_close:
+ xprt = svc_find_xprt(nfsd_serv, transport, PF_INET, port);
+ if (xprt != NULL) {
+ svc_close_xprt(xprt);
+ svc_xprt_put(xprt);
+ }
+out_err:
+ /* Decrease the count, but don't shut down the service */
+ nfsd_serv->sv_nrthreads--;
+ return err;
}
/*
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 15dc2deaac5..6dd5f1970e0 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -20,13 +20,15 @@
#include <linux/fcntl.h>
#include <linux/namei.h>
#include <linux/delay.h>
-#include <linux/quotaops.h>
#include <linux/fsnotify.h>
#include <linux/posix_acl_xattr.h>
#include <linux/xattr.h>
#include <linux/jhash.h>
#include <linux/ima.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
+#include <linux/exportfs.h>
+#include <linux/writeback.h>
#ifdef CONFIG_NFSD_V3
#include "xdr3.h"
@@ -271,6 +273,32 @@ out:
return err;
}
+/*
+ * Commit metadata changes to stable storage.
+ */
+static int
+commit_metadata(struct svc_fh *fhp)
+{
+ struct inode *inode = fhp->fh_dentry->d_inode;
+ const struct export_operations *export_ops = inode->i_sb->s_export_op;
+ int error = 0;
+
+ if (!EX_ISSYNC(fhp->fh_export))
+ return 0;
+
+ if (export_ops->commit_metadata) {
+ error = export_ops->commit_metadata(inode);
+ } else {
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_ALL,
+ .nr_to_write = 0, /* metadata only */
+ };
+
+ error = sync_inode(inode, &wbc);
+ }
+
+ return error;
+}
/*
* Set various file attributes.
@@ -377,7 +405,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
put_write_access(inode);
goto out_nfserr;
}
- vfs_dq_init(inode);
}
/* sanitize the mode change */
@@ -745,8 +772,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
flags = O_RDWR|O_LARGEFILE;
else
flags = O_WRONLY|O_LARGEFILE;
-
- vfs_dq_init(inode);
}
*filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
flags, current_cred());
@@ -771,43 +796,6 @@ nfsd_close(struct file *filp)
}
/*
- * Sync a file
- * As this calls fsync (not fdatasync) there is no need for a write_inode
- * after it.
- */
-static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
- const struct file_operations *fop)
-{
- struct inode *inode = dp->d_inode;
- int (*fsync) (struct file *, struct dentry *, int);
- int err;
-
- err = filemap_write_and_wait(inode->i_mapping);
- if (err == 0 && fop && (fsync = fop->fsync))
- err = fsync(filp, dp, 0);
- return err;
-}
-
-static int
-nfsd_sync(struct file *filp)
-{
- int err;
- struct inode *inode = filp->f_path.dentry->d_inode;
- dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name);
- mutex_lock(&inode->i_mutex);
- err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op);
- mutex_unlock(&inode->i_mutex);
-
- return err;
-}
-
-int
-nfsd_sync_dir(struct dentry *dp)
-{
- return nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
-}
-
-/*
* Obtain the readahead parameters for the file
* specified by (dev, ino).
*/
@@ -1010,7 +998,7 @@ static int wait_for_concurrent_writes(struct file *file)
if (inode->i_state & I_DIRTY) {
dprintk("nfsd: write sync %d\n", task_pid_nr(current));
- err = nfsd_sync(file);
+ err = vfs_fsync(file, file->f_path.dentry, 0);
}
last_ino = inode->i_ino;
last_dev = inode->i_sb->s_dev;
@@ -1158,8 +1146,9 @@ out:
#ifdef CONFIG_NFSD_V3
/*
* Commit all pending writes to stable storage.
- * Strictly speaking, we could sync just the indicated file region here,
- * but there's currently no way we can ask the VFS to do so.
+ *
+ * Note: we only guarantee that data that lies within the range specified
+ * by the 'offset' and 'count' parameters will be synced.
*
* Unfortunately we cannot lock the file to make sure we return full WCC
* data to the client, as locking happens lower down in the filesystem.
@@ -1169,23 +1158,32 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
loff_t offset, unsigned long count)
{
struct file *file;
- __be32 err;
+ loff_t end = LLONG_MAX;
+ __be32 err = nfserr_inval;
- if ((u64)count > ~(u64)offset)
- return nfserr_inval;
+ if (offset < 0)
+ goto out;
+ if (count != 0) {
+ end = offset + (loff_t)count - 1;
+ if (end < offset)
+ goto out;
+ }
err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file);
if (err)
- return err;
+ goto out;
if (EX_ISSYNC(fhp->fh_export)) {
- if (file->f_op && file->f_op->fsync) {
- err = nfserrno(nfsd_sync(file));
- } else {
+ int err2 = vfs_fsync_range(file, file->f_path.dentry,
+ offset, end, 0);
+
+ if (err2 != -EINVAL)
+ err = nfserrno(err2);
+ else
err = nfserr_notsupp;
- }
}
nfsd_close(file);
+out:
return err;
}
#endif /* CONFIG_NFSD_V3 */
@@ -1338,12 +1336,14 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
goto out_nfserr;
}
- if (EX_ISSYNC(fhp->fh_export)) {
- err = nfserrno(nfsd_sync_dir(dentry));
- write_inode_now(dchild->d_inode, 1);
- }
+ err = nfsd_create_setattr(rqstp, resfhp, iap);
- err2 = nfsd_create_setattr(rqstp, resfhp, iap);
+ /*
+ * nfsd_setattr already committed the child. Transactional filesystems
+ * had a chance to commit changes for both parent and child
+ * simultaneously making the following commit_metadata a noop.
+ */
+ err2 = nfserrno(commit_metadata(fhp));
if (err2)
err = err2;
mnt_drop_write(fhp->fh_export->ex_path.mnt);
@@ -1375,7 +1375,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
struct dentry *dentry, *dchild = NULL;
struct inode *dirp;
__be32 err;
- __be32 err2;
int host_err;
__u32 v_mtime=0, v_atime=0;
@@ -1470,11 +1469,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (created)
*created = 1;
- if (EX_ISSYNC(fhp->fh_export)) {
- err = nfserrno(nfsd_sync_dir(dentry));
- /* setattr will sync the child (or not) */
- }
-
nfsd_check_ignore_resizing(iap);
if (createmode == NFS3_CREATE_EXCLUSIVE) {
@@ -1489,9 +1483,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
}
set_attr:
- err2 = nfsd_create_setattr(rqstp, resfhp, iap);
- if (err2)
- err = err2;
+ err = nfsd_create_setattr(rqstp, resfhp, iap);
+
+ /*
+ * nfsd_setattr already committed the child (and possibly also the parent).
+ */
+ if (!err)
+ err = nfserrno(commit_metadata(fhp));
mnt_drop_write(fhp->fh_export->ex_path.mnt);
/*
@@ -1606,12 +1604,9 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
}
} else
host_err = vfs_symlink(dentry->d_inode, dnew, path);
-
- if (!host_err) {
- if (EX_ISSYNC(fhp->fh_export))
- host_err = nfsd_sync_dir(dentry);
- }
err = nfserrno(host_err);
+ if (!err)
+ err = nfserrno(commit_metadata(fhp));
fh_unlock(fhp);
mnt_drop_write(fhp->fh_export->ex_path.mnt);
@@ -1673,11 +1668,9 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
}
host_err = vfs_link(dold, dirp, dnew);
if (!host_err) {
- if (EX_ISSYNC(ffhp->fh_export)) {
- err = nfserrno(nfsd_sync_dir(ddir));
- write_inode_now(dest, 1);
- }
- err = 0;
+ err = nfserrno(commit_metadata(ffhp));
+ if (!err)
+ err = nfserrno(commit_metadata(tfhp));
} else {
if (host_err == -EXDEV && rqstp->rq_vers == 2)
err = nfserr_acces;
@@ -1773,10 +1766,10 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
goto out_dput_new;
host_err = vfs_rename(fdir, odentry, tdir, ndentry);
- if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
- host_err = nfsd_sync_dir(tdentry);
+ if (!host_err) {
+ host_err = commit_metadata(tfhp);
if (!host_err)
- host_err = nfsd_sync_dir(fdentry);
+ host_err = commit_metadata(ffhp);
}
mnt_drop_write(ffhp->fh_export->ex_path.mnt);
@@ -1857,12 +1850,9 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
dput(rdentry);
- if (host_err)
- goto out_drop;
- if (EX_ISSYNC(fhp->fh_export))
- host_err = nfsd_sync_dir(dentry);
+ if (!host_err)
+ host_err = commit_metadata(fhp);
-out_drop:
mnt_drop_write(fhp->fh_export->ex_path.mnt);
out_nfserr:
err = nfserrno(host_err);
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
index 3f959f1879d..7cfb87e692d 100644
--- a/fs/nilfs2/alloc.c
+++ b/fs/nilfs2/alloc.c
@@ -26,6 +26,7 @@
#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include "mdt.h"
#include "alloc.h"
@@ -425,7 +426,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
group_offset, bitmap))
- printk(KERN_WARNING "%s: entry numer %llu already freed\n",
+ printk(KERN_WARNING "%s: entry number %llu already freed\n",
__func__, (unsigned long long)req->pr_entry_nr);
nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h
index f4543ac4f56..5cccf874d69 100644
--- a/fs/nilfs2/alloc.h
+++ b/fs/nilfs2/alloc.h
@@ -42,7 +42,7 @@ void *nilfs_palloc_block_get_entry(const struct inode *, __u64,
const struct buffer_head *, void *);
/**
- * nilfs_palloc_req - persistent alloctor request and reply
+ * nilfs_palloc_req - persistent allocator request and reply
* @pr_entry_nr: entry number (vblocknr or inode number)
* @pr_desc_bh: buffer head of the buffer containing block group descriptors
* @pr_bitmap_bh: buffer head of the buffer containing a block group bitmap
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 471e269536a..447ce47a330 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -27,6 +27,7 @@
#include <linux/buffer_head.h>
#include <linux/mm.h>
#include <linux/backing-dev.h>
+#include <linux/gfp.h>
#include "nilfs.h"
#include "mdt.h"
#include "dat.h"
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 7cdd98b8d51..76c38e3e19d 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -1879,7 +1879,7 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
struct nilfs_btree_path *path,
int level, struct buffer_head *bh)
{
- int maxlevel, ret;
+ int maxlevel = 0, ret;
struct nilfs_btree_node *parent;
struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
__u64 ptr;
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index 9d1e5de91af..01314675568 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -288,7 +288,7 @@ int nilfs_dat_mark_dirty(struct inode *dat, __u64 vblocknr)
* @vblocknrs and @nitems.
*
* Return Value: On success, 0 is returned. On error, one of the following
- * nagative error codes is returned.
+ * negative error codes is returned.
*
* %-EIO - I/O error.
*
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 0092840492e..85c89dfc71f 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -396,7 +396,7 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
/* next page is past the blocks we've got */
if (unlikely(n > (dir->i_blocks >> (PAGE_CACHE_SHIFT - 9)))) {
nilfs_error(dir->i_sb, __func__,
- "dir %lu size %lld exceeds block cout %llu",
+ "dir %lu size %lld exceeds block count %llu",
dir->i_ino, dir->i_size,
(unsigned long long)dir->i_blocks);
goto out;
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
index e16a6664dfa..145f03cd7d3 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -28,10 +28,10 @@
* gcinodes), and this file provides lookup function of the dummy
* inodes and their buffer read function.
*
- * Since NILFS2 keeps up multiple checkpoints/snapshots accross GC, it
+ * Since NILFS2 keeps up multiple checkpoints/snapshots across GC, it
* has to treat blocks that belong to a same file but have different
* checkpoint numbers. To avoid interference among generations, dummy
- * inodes are managed separatly from actual inodes, and their lookup
+ * inodes are managed separately from actual inodes, and their lookup
* function (nilfs_gc_iget) is designed to be specified with a
* checkpoint number argument as well as an inode number.
*
@@ -45,6 +45,7 @@
#include <linux/buffer_head.h>
#include <linux/mpage.h>
#include <linux/hash.h>
+#include <linux/slab.h>
#include <linux/swap.h>
#include "nilfs.h"
#include "page.h"
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 7868cc122ac..0957b58f909 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -22,6 +22,7 @@
*/
#include <linux/buffer_head.h>
+#include <linux/gfp.h>
#include <linux/mpage.h>
#include <linux/writeback.h>
#include <linux/uio.h>
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 313d0a21da4..f90a33d9a5b 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -23,6 +23,7 @@
#include <linux/fs.h>
#include <linux/wait.h>
#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */
+#include <linux/slab.h>
#include <linux/capability.h> /* capable() */
#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
#include <linux/vmalloc.h>
@@ -648,7 +649,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct inode *inode = filp->f_dentry->d_inode;
- void __user *argp = (void * __user *)arg;
+ void __user *argp = (void __user *)arg;
switch (cmd) {
case NILFS_IOCTL_CHANGE_CPMODE:
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 06713ffcc7f..024be8c35bb 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -26,6 +26,7 @@
#include <linux/writeback.h>
#include <linux/backing-dev.h>
#include <linux/swap.h>
+#include <linux/slab.h>
#include "nilfs.h"
#include "segment.h"
#include "page.h"
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index a2692bbc7b5..8de3e1e4813 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -29,6 +29,7 @@
#include <linux/list.h>
#include <linux/highmem.h>
#include <linux/pagevec.h>
+#include <linux/gfp.h>
#include "nilfs.h"
#include "page.h"
#include "mdt.h"
@@ -292,7 +293,7 @@ void nilfs_free_private_page(struct page *page)
* @src: source page
* @copy_dirty: flag whether to copy dirty states on the page's buffer heads.
*
- * This fuction is for both data pages and btnode pages. The dirty flag
+ * This function is for both data pages and btnode pages. The dirty flag
* should be treated by caller. The page must not be under i/o.
* Both src and dst page must be locked
*/
@@ -388,7 +389,7 @@ repeat:
}
/**
- * nilfs_copy_back_pages -- copy back pages to orignal cache from shadow cache
+ * nilfs_copy_back_pages -- copy back pages to original cache from shadow cache
* @dmap: destination page cache
* @smap: source page cache
*
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 017bedc761a..ba43146f3c3 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -23,6 +23,7 @@
#include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include <linux/swap.h>
+#include <linux/slab.h>
#include <linux/crc32.h>
#include "nilfs.h"
#include "segment.h"
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index ab56fe44e37..17851f77f73 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -25,6 +25,7 @@
#include <linux/writeback.h>
#include <linux/crc32.h>
#include <linux/backing-dev.h>
+#include <linux/slab.h>
#include "page.h"
#include "segbuf.h"
@@ -32,7 +33,7 @@
struct nilfs_write_info {
struct the_nilfs *nilfs;
struct bio *bio;
- int start, end; /* The region to be submitted */
+ int start, end; /* The region to be submitted */
int rest_blocks;
int max_pages;
int nr_vecs;
@@ -174,7 +175,7 @@ int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags,
}
/*
- * Setup segument summary
+ * Setup segment summary
*/
void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf)
{
@@ -323,14 +324,14 @@ int nilfs_write_logs(struct list_head *logs, struct the_nilfs *nilfs)
int nilfs_wait_on_logs(struct list_head *logs)
{
struct nilfs_segment_buffer *segbuf;
- int err;
+ int err, ret = 0;
list_for_each_entry(segbuf, logs, sb_list) {
err = nilfs_segbuf_wait(segbuf);
- if (err)
- return err;
+ if (err && !ret)
+ ret = err;
}
- return 0;
+ return ret;
}
/*
@@ -470,8 +471,8 @@ static int nilfs_segbuf_submit_bh(struct nilfs_segment_buffer *segbuf,
*
* %-ENOMEM - Insufficient memory available.
*/
-int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
- struct the_nilfs *nilfs)
+static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
+ struct the_nilfs *nilfs)
{
struct nilfs_write_info wi;
struct buffer_head *bh;
@@ -514,7 +515,7 @@ int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
*
* %-EIO - I/O error
*/
-int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf)
+static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf)
{
int err = 0;
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index ada2f1b947a..6a7dbd8451d 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -32,6 +32,7 @@
#include <linux/kthread.h>
#include <linux/crc32.h>
#include <linux/pagevec.h>
+#include <linux/slab.h>
#include "nilfs.h"
#include "btnode.h"
#include "page.h"
@@ -141,7 +142,7 @@ int nilfs_init_transaction_cache(void)
}
/**
- * nilfs_detroy_transaction_cache - destroy the cache for transaction info
+ * nilfs_destroy_transaction_cache - destroy the cache for transaction info
*
* nilfs_destroy_transaction_cache() frees the slab cache for the struct
* nilfs_transaction_info.
@@ -201,7 +202,7 @@ static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti)
* This function allocates a nilfs_transaction_info struct to keep context
* information on it. It is initialized and hooked onto the current task in
* the outermost call. If a pre-allocated struct is given to @ti, it is used
- * instead; othewise a new struct is assigned from a slab.
+ * instead; otherwise a new struct is assigned from a slab.
*
* When @vacancy_check flag is set, this function will check the amount of
* free space, and will wait for the GC to reclaim disk space if low capacity.
@@ -1510,6 +1511,12 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE)
break;
+ nilfs_clear_logs(&sci->sc_segbufs);
+
+ err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
+ if (unlikely(err))
+ return err;
+
if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
err = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
sci->sc_freesegs,
@@ -1517,12 +1524,6 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
NULL);
WARN_ON(err); /* do not happen */
}
- nilfs_clear_logs(&sci->sc_segbufs);
-
- err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
- if (unlikely(err))
- return err;
-
nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
sci->sc_stage = prev_stage;
}
@@ -1897,8 +1898,7 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
list_splice_tail_init(&sci->sc_write_logs, &logs);
ret = nilfs_wait_on_logs(&logs);
- if (ret)
- nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret);
+ nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret ? : err);
list_splice_tail_init(&sci->sc_segbufs, &logs);
nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
@@ -2214,7 +2214,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
}
/**
- * nilfs_secgtor_start_timer - set timer of background write
+ * nilfs_segctor_start_timer - set timer of background write
* @sci: nilfs_sc_info
*
* If the timer has already been set, it ignores the new request.
@@ -2854,7 +2854,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
* @sbi: nilfs_sb_info
*
* nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info,
- * initilizes it, and starts the segment constructor.
+ * initializes it, and starts the segment constructor.
*
* Return Value: On success, 0 is returned. On error, one of the following
* negative error code is returned.
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 3155e0c7f41..82dfd6a686b 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -30,7 +30,7 @@
#include "sb.h"
/**
- * struct nilfs_recovery_info - Recovery infomation
+ * struct nilfs_recovery_info - Recovery information
* @ri_need_recovery: Recovery status
* @ri_super_root: Block number of the last super root
* @ri_ri_cno: Number of the last checkpoint
@@ -71,7 +71,7 @@ struct nilfs_recovery_info {
*/
struct nilfs_cstage {
int scnt;
- unsigned flags;
+ unsigned flags;
struct nilfs_inode_info *dirty_file_ptr;
struct nilfs_inode_info *gc_inode_ptr;
};
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index b6c36d0cc33..3c6cc6005c2 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Written by Koji Sato <koji@osrg.net>.
- * Rivised by Ryusuke Konishi <ryusuke@osrg.net>.
+ * Revised by Ryusuke Konishi <ryusuke@osrg.net>.
*/
#include <linux/kernel.h>
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 92579cc4c93..0cdbc5e7655 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -436,7 +436,7 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
/*
* Compute the overhead
*
- * When distributing meta data blocks outside semgent structure,
+ * When distributing meta data blocks outside segment structure,
* We must count them as the overhead.
*/
overhead = 0;
@@ -866,7 +866,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
if ((*flags & MS_RDONLY) &&
sbi->s_snapshot_cno != old_opts.snapshot_cno) {
printk(KERN_WARNING "NILFS (device %s): couldn't "
- "remount to a different snapshot. \n",
+ "remount to a different snapshot.\n",
sb->s_id);
err = -EINVAL;
goto restore_opts;
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 92733d5651d..33871f7e4f0 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -386,7 +386,7 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
- printk(KERN_ERR "NILFS: too short segment. \n");
+ printk(KERN_ERR "NILFS: too short segment.\n");
return -EINVAL;
}
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index e9795f1724d..1ab97453369 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -29,6 +29,7 @@
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
+#include <linux/slab.h>
#include "sb.h"
/* the_nilfs struct */
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 037e878e03f..fcc2f064af8 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -18,6 +18,7 @@
#include <linux/dcache.h>
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/srcu.h>
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 3165d85aada..0399bcbe09c 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -87,7 +87,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/writeback.h> /* for inode_lock */
diff --git a/fs/notify/inotify/Kconfig b/fs/notify/inotify/Kconfig
index 3e56dbffe72..b3a159b21cf 100644
--- a/fs/notify/inotify/Kconfig
+++ b/fs/notify/inotify/Kconfig
@@ -15,6 +15,7 @@ config INOTIFY
config INOTIFY_USER
bool "Inotify support for userspace"
+ select ANON_INODES
select FSNOTIFY
default y
---help---
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
deleted file mode 100644
index 37c11e19437..00000000000
--- a/fs/ntfs/ChangeLog
+++ /dev/null
@@ -1,1702 +0,0 @@
-ToDo/Notes:
- - Find and fix bugs.
- - The only places in the kernel where a file is resized are
- ntfs_file_write*() and ntfs_truncate() for both of which i_mutex is
- held. Just have to be careful in read-/writepage and other helpers
- not running under i_mutex that we play nice. Also need to be careful
- with initialized_size extension in ntfs_file_write*() and writepage.
- UPDATE: The only things that need to be checked are the compressed
- write and the other attribute resize/write cases like index
- attributes, etc. For now none of these are implemented so are safe.
- - Implement filling in of holes in aops.c::ntfs_writepage() and its
- helpers.
- - Implement mft.c::sync_mft_mirror_umount(). We currently will just
- leave the volume dirty on umount if the final iput(vol->mft_ino)
- causes a write of any mirrored mft records due to the mft mirror
- inode having been discarded already. Whether this can actually ever
- happen is unclear however so it is worth waiting until someone hits
- the problem.
-
-2.1.29 - Fix a deadlock at mount time.
-
- - During mount the VFS holds s_umount lock on the superblock. So when
- we try to empty the journal $LogFile contents by calling
- ntfs_attr_set() when the machine does not have much memory and the
- journal is large ntfs_attr_set() results in the VM trying to balance
- dirty pages which in turn tries to that the s_umount lock and thus we
- get a deadlock. The solution is to not use ntfs_attr_set() and
- instead do the zeroing by hand at the block level rather than page
- cache level.
- - Fix sparse warnings.
-
-2.1.28 - Fix a deadlock.
-
- - Fix deadlock in fs/ntfs/inode.c::ntfs_put_inode(). Thanks to Sergey
- Vlasov for the report and detailed analysis of the deadlock. The fix
- involved getting rid of ntfs_put_inode() altogether and hence NTFS no
- longer has a ->put_inode super operation.
-
-2.1.27 - Various bug fixes and cleanups.
-
- - Fix two compiler warnings on Alpha. Thanks to Andrew Morton for
- reporting them.
- - Fix an (innocent) off-by-one error in the runlist code.
- - Fix a buggette in an "should be impossible" case handling where we
- continued the attribute lookup loop instead of aborting it.
- - Use buffer_migrate_page() for the ->migratepage function of all ntfs
- address space operations.
- - Fix comparison of $MFT and $MFTMirr to not bail out when there are
- unused, invalid mft records which are the same in both $MFT and
- $MFTMirr.
- - Add support for sparse files which have a compression unit of 0.
- - Remove all the make_bad_inode() calls. This should only be called
- from read inode and new inode code paths.
- - Limit name length in fs/ntfs/unistr.c::ntfs_nlstoucs() to maximum
- allowed by NTFS, i.e. 255 Unicode characters, not including the
- terminating NULL (which is not stored on disk).
- - Improve comments on file attribute flags in fs/ntfs/layout.h.
- - Fix a bug in fs/ntfs/inode.c::ntfs_read_locked_index_inode() where we
- forgot to update a temporary variable so loading index inodes which
- have an index allocation attribute failed.
- - Add a missing call to flush_dcache_mft_record_page() in
- fs/ntfs/inode.c::ntfs_write_inode().
- - Handle the recently introduced -ENAMETOOLONG return value from
- fs/ntfs/unistr.c::ntfs_nlstoucs() in fs/ntfs/namei.c::ntfs_lookup().
- - Semaphore to mutex conversion. (Ingo Molnar)
-
-2.1.26 - Minor bug fixes and updates.
-
- - Fix a potential overflow in file.c where a cast to s64 was missing in
- a left shift of a page index.
- - The struct inode has had its i_sem semaphore changed to a mutex named
- i_mutex.
- - We have struct kmem_cache now so use it instead of the typedef
- kmem_cache_t. (Pekka Enberg)
- - Implement support for sector sizes above 512 bytes (up to the maximum
- supported by NTFS which is 4096 bytes).
- - Do more detailed reporting of why we cannot mount read-write by
- special casing the VOLUME_MODIFIED_BY_CHKDSK flag.
- - Miscellaneous updates to layout.h.
- - Cope with attribute list attribute having invalid flags. Windows
- copes with this and even chkdsk does not detect or fix this so we
- have to cope with it, too. Thanks to Pawel Kot for reporting the
- problem.
-
-2.1.25 - (Almost) fully implement write(2) and truncate(2).
-
- - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and
- {__,}ntfs_cluster_free() to also take an optional attribute search
- context as argument. This allows calling these functions with the
- mft record mapped. Update all callers.
- - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock()
- error handling by passing in the active search context when calling
- ntfs_cluster_free().
- - Change ntfs_cluster_alloc() to take an extra boolean parameter
- specifying whether the cluster are being allocated to extend an
- attribute or to fill a hole.
- - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc()
- with @is_extension set to TRUE and remove the runlist terminator
- fixup code as this is now done by ntfs_cluster_alloc().
- - Change ntfs_attr_make_non_resident to take the attribute value size
- as an extra parameter. This is needed since we need to know the size
- before we can map the mft record and our callers always know it. The
- reason we cannot simply read the size from the vfs inode i_size is
- that this is not necessarily uptodate. This happens when
- ntfs_attr_make_non_resident() is called in the ->truncate call path.
- - Fix ntfs_attr_make_non_resident() to update the vfs inode i_blocks
- which is zero for a resident attribute but should no longer be zero
- once the attribute is non-resident as it then has real clusters
- allocated.
- - Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to
- extend the allocation of an attributes. Optionally, the data size,
- but not the initialized size can be extended, too.
- - Implement fs/ntfs/inode.[hc]::ntfs_truncate(). It only supports
- uncompressed and unencrypted files and it never creates sparse files
- at least for the moment (making a file sparse requires us to modify
- its directory entries and we do not support directory operations at
- the moment). Also, support for highly fragmented files, i.e. ones
- whose data attribute is split across multiple extents, is severly
- limited. When such a case is encountered, EOPNOTSUPP is returned.
- - Enable ATTR_SIZE attribute changes in ntfs_setattr(). This completes
- the initial implementation of file truncation. Now both open(2)ing
- a file with the O_TRUNC flag and the {,f}truncate(2) system calls
- will resize a file appropriately. The limitations are that only
- uncompressed and unencrypted files are supported. Also, there is
- only very limited support for highly fragmented files (the ones whose
- $DATA attribute is split into multiple attribute extents).
- - In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited()
- and cond_resched() in the main loop as we could be dirtying a lot of
- pages and this ensures we play nice with the VM and the system as a
- whole.
- - Implement file operations ->write, ->aio_write, ->writev for regular
- files. This replaces the old use of generic_file_write(), et al and
- the address space operations ->prepare_write and ->commit_write.
- This means that both sparse and non-sparse (unencrypted and
- uncompressed) files can now be extended using the normal write(2)
- code path. There are two limitations at present and these are that
- we never create sparse files and that we only have limited support
- for highly fragmented files, i.e. ones whose data attribute is split
- across multiple extents. When such a case is encountered,
- EOPNOTSUPP is returned.
- - $EA attributes can be both resident and non-resident.
- - Use %z for size_t to fix compilation warnings. (Andrew Morton)
- - Fix compilation warnings with gcc-4.0.2 on SUSE 10.0.
- - Document extended attribute ($EA) NEED_EA flag. (Based on libntfs
- patch by Yura Pakhuchiy.)
-
-2.1.24 - Lots of bug fixes and support more clean journal states.
-
- - Support journals ($LogFile) which have been modified by chkdsk. This
- means users can boot into Windows after we marked the volume dirty.
- The Windows boot will run chkdsk and then reboot. The user can then
- immediately boot into Linux rather than having to do a full Windows
- boot first before rebooting into Linux and we will recognize such a
- journal and empty it as it is clean by definition. Note, this only
- works if chkdsk left the journal in an obviously clean state.
- - Support journals ($LogFile) with only one restart page as well as
- journals with two different restart pages. We sanity check both and
- either use the only sane one or the more recent one of the two in the
- case that both are valid.
- - Add fs/ntfs/malloc.h::ntfs_malloc_nofs_nofail() which is analogous to
- ntfs_malloc_nofs() but it performs allocations with __GFP_NOFAIL and
- hence cannot fail.
- - Use ntfs_malloc_nofs_nofail() in the two critical regions in
- fs/ntfs/runlist.c::ntfs_runlists_merge(). This means we no longer
- need to panic() if the allocation fails as it now cannot fail.
- - Fix two nasty runlist merging bugs that had gone unnoticed so far.
- Thanks to Stefano Picerno for the bug report.
- - Remove two bogus BUG_ON()s from fs/ntfs/mft.c.
- - Fix handling of valid but empty mapping pairs array in
- fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress().
- - Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING
- messages and include the inode number. Thanks to Yura Pakhuchiy for
- pointing this out.
- - Change ntfs_rl_truncate_nolock() to throw away the runlist if the new
- length is zero.
- - Add runlist.[hc]::ntfs_rl_punch_nolock() which punches a caller
- specified hole into a runlist.
- - Fix a bug in fs/ntfs/index.c::ntfs_index_lookup(). When the returned
- index entry is in the index root, we forgot to set the @ir pointer in
- the index context. Thanks to Yura Pakhuchiy for finding this bug.
- - Remove bogus setting of PageError in ntfs_read_compressed_block().
- - Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
- - Fix a bug in ntfs_map_runlist_nolock() where we forgot to protect
- access to the allocated size in the ntfs inode with the size lock.
- - Fix ntfs_attr_vcn_to_lcn_nolock() and ntfs_attr_find_vcn_nolock() to
- return LCN_ENOENT when there is no runlist and the allocated size is
- zero.
- - Fix load_attribute_list() to handle the case of a NULL runlist.
- - Fix handling of sparse attributes in ntfs_attr_make_non_resident().
- - Add BUG() checks to ntfs_attr_make_non_resident() and ntfs_attr_set()
- to ensure that these functions are never called for compressed or
- encrypted attributes.
- - Fix cluster (de)allocators to work when the runlist is NULL and more
- importantly to take a locked runlist rather than them locking it
- which leads to lock reversal.
- - Truncate {a,c,m}time to the ntfs supported time granularity when
- updating the times in the inode in ntfs_setattr().
- - Fixup handling of sparse, compressed, and encrypted attributes in
- fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode(),
- fs/ntfs/aops.c::ntfs_{read,write}page().
- - Make ntfs_write_block() not instantiate sparse blocks if they contain
- only zeroes.
- - Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
- lock protection over the buffer submission for i/o which allows the
- removal of the get_bh()/put_bh() pairs for each buffer.
- - Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
- where a concurrent truncate has truncated the runlist under our feet.
- - Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c.
- - In fs/ntfs/aops.c::ntfs_end_buffer_async_read(), use a bit spin lock
- in the first buffer head instead of a driver global spin lock to
- improve scalability.
- - Minor fix to error handling and error message display in
- fs/ntfs/aops.c::ntfs_prepare_nonresident_write().
- - Change the mount options {u,f,d}mask to always parse the number as
- an octal number to conform to how chmod(1) works, too. Thanks to
- Giuseppe Bilotta and Horst von Brand for pointing out the errors of
- my ways.
- - Fix various bugs in the runlist merging code. (Based on libntfs
- changes by Richard Russon.)
- - Fix sparse warnings that have crept in over time.
- - Change ntfs_cluster_free() to require a write locked runlist on entry
- since we otherwise get into a lock reversal deadlock if a read locked
- runlist is passed in. In the process also change it to take an ntfs
- inode instead of a vfs inode as parameter.
- - Fix the definition of the CHKD ntfs record magic. It had an off by
- two error causing it to be CHKB instead of CHKD.
- - Fix a stupid bug in __ntfs_bitmap_set_bits_in_run() which caused the
- count to become negative and hence we had a wild memset() scribbling
- all over the system's ram.
-
-2.1.23 - Implement extension of resident files and make writing safe as well as
- many bug fixes, cleanups, and enhancements...
-
- - Add printk rate limiting for ntfs_warning() and ntfs_error() when
- compiled without debug. This avoids a possible denial of service
- attack. Thanks to Carl-Daniel Hailfinger from SuSE for pointing this
- out.
- - Fix compilation warnings on ia64. (Randy Dunlap)
- - Use i_size_{read,write}() instead of reading i_size by hand and cache
- the value where apropriate.
- - Add size_lock to the ntfs_inode structure. This is an rw spinlock
- and it locks against access to the inode sizes. Note, ->size_lock
- is also accessed from irq context so you must use the _irqsave and
- _irqrestore lock and unlock functions, respectively. Protect all
- accesses to allocated_size, initialized_size, and compressed_size.
- - Minor optimization to fs/ntfs/super.c::ntfs_statfs() and its helpers.
- - Implement extension of resident files in the regular file write code
- paths (fs/ntfs/aops.c::ntfs_{prepare,commit}_write()). At present
- this only works until the data attribute becomes too big for the mft
- record after which we abort the write returning -EOPNOTSUPP from
- ntfs_prepare_write().
- - Add disable_sparse mount option together with a per volume sparse
- enable bit which is set appropriately and a per inode sparse disable
- bit which is preset on some system file inodes as appropriate.
- - Enforce that sparse support is disabled on NTFS volumes pre 3.0.
- - Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in
- the creation of the unmapped runlist element for the base attribute
- extent.
- - Split ntfs_map_runlist() into ntfs_map_runlist() and a non-locking
- helper ntfs_map_runlist_nolock() which is used by ntfs_map_runlist().
- This allows us to map runlist fragments with the runlist lock already
- held without having to drop and reacquire it around the call. Adapt
- all callers.
- - Change ntfs_find_vcn() to ntfs_find_vcn_nolock() which takes a locked
- runlist. This allows us to find runlist elements with the runlist
- lock already held without having to drop and reacquire it around the
- call. Adapt all callers.
- - Change time to u64 in time.h::ntfs2utc() as it otherwise generates a
- warning in the do_div() call on sparc32. Thanks to Meelis Roos for
- the report and analysis of the warning.
- - Fix a nasty runlist merge bug when merging two holes.
- - Set the ntfs_inode->allocated_size to the real allocated size in the
- mft record for resident attributes (fs/ntfs/inode.c).
- - Small readability cleanup to use "a" instead of "ctx->attr"
- everywhere (fs/ntfs/inode.c).
- - Make fs/ntfs/namei.c::ntfs_get_{parent,dentry} static and move the
- definition of ntfs_export_ops from fs/ntfs/super.c to namei.c. Also,
- declare ntfs_export_ops in fs/ntfs/ntfs.h.
- - Correct sparse file handling. The compressed values need to be
- checked and set in the ntfs inode as done for compressed files and
- the compressed size needs to be used for vfs inode->i_blocks instead
- of the allocated size, again, as done for compressed files.
- - Add AT_EA in addition to AT_DATA to whitelist for being allowed to be
- non-resident in fs/ntfs/attrib.c::ntfs_attr_can_be_non_resident().
- - Add fs/ntfs/attrib.c::ntfs_attr_vcn_to_lcn_nolock() used by the new
- write code.
- - Fix bug in fs/ntfs/attrib.c::ntfs_find_vcn_nolock() where after
- dropping the read lock and taking the write lock we were not checking
- whether someone else did not already do the work we wanted to do.
- - Rename fs/ntfs/attrib.c::ntfs_find_vcn_nolock() to
- ntfs_attr_find_vcn_nolock() and update all callers.
- - Add fs/ntfs/attrib.[hc]::ntfs_attr_make_non_resident().
- - Fix sign of various error return values to be negative in
- fs/ntfs/lcnalloc.c.
- - Modify ->readpage and ->writepage (fs/ntfs/aops.c) so they detect and
- handle the case where an attribute is converted from resident to
- non-resident by a concurrent file write.
- - Remove checks for NULL before calling kfree() since kfree() does the
- checking itself. (Jesper Juhl)
- - Some utilities modify the boot sector but do not update the checksum.
- Thus, relax the checking in fs/ntfs/super.c::is_boot_sector_ntfs() to
- only emit a warning when the checksum is incorrect rather than
- refusing the mount. Thanks to Bernd Casimir for pointing this
- problem out.
- - Update attribute definition handling.
- - Add NTFS_MAX_CLUSTER_SIZE and NTFS_MAX_PAGES_PER_CLUSTER constants.
- - Use NTFS_MAX_CLUSTER_SIZE in super.c instead of hard coding 0x10000.
- - Use MAX_BUF_PER_PAGE instead of variable sized array allocation for
- better code generation and one less sparse warning in fs/ntfs/aops.c.
- - Remove spurious void pointer casts from fs/ntfs/. (Pekka Enberg)
- - Use C99 style structure initialization after memory allocation where
- possible (fs/ntfs/{attrib.c,index.c,super.c}). Thanks to Al Viro and
- Pekka Enberg.
- - Stamp the transaction log ($UsnJrnl), aka user space journal, if it
- is active on the volume and we are mounting read-write or remounting
- from read-only to read-write.
- - Fix a bug in address space operations error recovery code paths where
- if the runlist was not mapped at all and a mapping error occured we
- would leave the runlist locked on exit to the function so that the
- next access to the same file would try to take the lock and deadlock.
- - Detect the case when Windows has been suspended to disk on the volume
- to be mounted and if this is the case do not allow (re)mounting
- read-write. This is done by parsing hiberfil.sys if present.
- - Fix several occurences of a bug where we would perform 'var & ~const'
- with a 64-bit variable and a int, i.e. 32-bit, constant. This causes
- the higher order 32-bits of the 64-bit variable to be zeroed. To fix
- this cast the 'const' to the same 64-bit type as 'var'.
- - Change the runlist terminator of the newly allocated cluster(s) to
- LCN_ENOENT in ntfs_attr_make_non_resident(). Otherwise the runlist
- code gets confused.
- - Add an extra parameter @last_vcn to ntfs_get_size_for_mapping_pairs()
- and ntfs_mapping_pairs_build() to allow the runlist encoding to be
- partial which is desirable when filling holes in sparse attributes.
- Update all callers.
- - Change ntfs_map_runlist_nolock() to only decompress the mapping pairs
- if the requested vcn is inside it. Otherwise we get into problems
- when we try to map an out of bounds vcn because we then try to map
- the already mapped runlist fragment which causes
- ntfs_mapping_pairs_decompress() to fail and return error. Update
- ntfs_attr_find_vcn_nolock() accordingly.
- - Fix a nasty deadlock that appeared in recent kernels.
- The situation: VFS inode X on a mounted ntfs volume is dirty. For
- same inode X, the ntfs_inode is dirty and thus corresponding on-disk
- inode, i.e. mft record, which is in a dirty PAGE_CACHE_PAGE belonging
- to the table of inodes, i.e. $MFT, inode 0.
- What happens:
- Process 1: sys_sync()/umount()/whatever... calls
- __sync_single_inode() for $MFT -> do_writepages() -> write_page for
- the dirty page containing the on-disk inode X, the page is now locked
- -> ntfs_write_mst_block() which clears PageUptodate() on the page to
- prevent anyone else getting hold of it whilst it does the write out.
- This is necessary as the on-disk inode needs "fixups" applied before
- the write to disk which are removed again after the write and
- PageUptodate is then set again. It then analyses the page looking
- for dirty on-disk inodes and when it finds one it calls
- ntfs_may_write_mft_record() to see if it is safe to write this
- on-disk inode. This then calls ilookup5() to check if the
- corresponding VFS inode is in icache(). This in turn calls ifind()
- which waits on the inode lock via wait_on_inode whilst holding the
- global inode_lock.
- Process 2: pdflush results in a call to __sync_single_inode for the
- same VFS inode X on the ntfs volume. This locks the inode (I_LOCK)
- then calls write-inode -> ntfs_write_inode -> map_mft_record() ->
- read_cache_page() for the page (in page cache of table of inodes
- $MFT, inode 0) containing the on-disk inode. This page has
- PageUptodate() clear because of Process 1 (see above) so
- read_cache_page() blocks when it tries to take the page lock for the
- page so it can call ntfs_read_page().
- Thus Process 1 is holding the page lock on the page containing the
- on-disk inode X and it is waiting on the inode X to be unlocked in
- ifind() so it can write the page out and then unlock the page.
- And Process 2 is holding the inode lock on inode X and is waiting for
- the page to be unlocked so it can call ntfs_readpage() or discover
- that Process 1 set PageUptodate() again and use the page.
- Thus we have a deadlock due to ifind() waiting on the inode lock.
- The solution: The fix is to use the newly introduced
- ilookup5_nowait() which does not wait on the inode's lock and hence
- avoids the deadlock. This is safe as we do not care about the VFS
- inode and only use the fact that it is in the VFS inode cache and the
- fact that the vfs and ntfs inodes are one struct in memory to find
- the ntfs inode in memory if present. Also, the ntfs inode has its
- own locking so it does not matter if the vfs inode is locked.
- - Fix bug in mft record writing where we forgot to set the device in
- the buffers when mapping them after the VM had discarded them.
- Thanks to Martin MOKREJÃ… for the bug report.
-
-2.1.22 - Many bug and race fixes and error handling improvements.
-
- - Improve error handling in fs/ntfs/inode.c::ntfs_truncate().
- - Change fs/ntfs/inode.c::ntfs_truncate() to return an error code
- instead of void and provide a helper ntfs_truncate_vfs() for the
- vfs ->truncate method.
- - Add a new ntfs inode flag NInoTruncateFailed() and modify
- fs/ntfs/inode.c::ntfs_truncate() to set and clear it appropriately.
- - Fix min_size and max_size definitions in ATTR_DEF structure in
- fs/ntfs/layout.h to be signed.
- - Add attribute definition handling helpers to fs/ntfs/attrib.[hc]:
- ntfs_attr_size_bounds_check(), ntfs_attr_can_be_non_resident(), and
- ntfs_attr_can_be_resident(), which in turn use the new private helper
- ntfs_attr_find_in_attrdef().
- - In fs/ntfs/aops.c::mark_ntfs_record_dirty(), take the
- mapping->private_lock around the dirtying of the buffer heads
- analagous to the way it is done in __set_page_dirty_buffers().
- - Ensure the mft record size does not exceed the PAGE_CACHE_SIZE at
- mount time as this cannot work with the current implementation.
- - Check for location of attribute name and improve error handling in
- general in fs/ntfs/inode.c::ntfs_read_locked_inode() and friends.
- - In fs/ntfs/aops.c::ntfs_writepage(), if the page is fully outside
- i_size, i.e. race with truncate, invalidate the buffers on the page
- so that they become freeable and hence the page does not leak.
- - Remove unused function fs/ntfs/runlist.c::ntfs_rl_merge(). (Adrian
- Bunk)
- - Fix stupid bug in fs/ntfs/attrib.c::ntfs_attr_find() that resulted in
- a NULL pointer dereference in the error code path when a corrupt
- attribute was found. (Thanks to Domen Puncer for the bug report.)
- - Add MODULE_VERSION() to fs/ntfs/super.c.
- - Make several functions and variables static. (Adrian Bunk)
- - Modify fs/ntfs/aops.c::mark_ntfs_record_dirty() so it allocates
- buffers for the page if they are not present and then marks the
- buffers belonging to the ntfs record dirty. This causes the buffers
- to become busy and hence they are safe from removal until the page
- has been written out.
- - Fix stupid bug in fs/ntfs/attrib.c::ntfs_external_attr_find() in the
- error handling code path that resulted in a BUG() due to trying to
- unmap an extent mft record when the mapping of it had failed and it
- thus was not mapped. (Thanks to Ken MacFerrin for the bug report.)
- - Drop the runlist lock after the vcn has been read in
- fs/ntfs/lcnalloc.c::__ntfs_cluster_free().
- - Rewrite handling of multi sector transfer errors. We now do not set
- PageError() when such errors are detected in the async i/o handler
- fs/ntfs/aops.c::ntfs_end_buffer_async_read(). All users of mst
- protected attributes now check the magic of each ntfs record as they
- use it and act appropriately. This has the effect of making errors
- granular per ntfs record rather than per page which solves the case
- where we cannot access any of the ntfs records in a page when a
- single one of them had an mst error. (Thanks to Ken MacFerrin for
- the bug report.)
- - Fix error handling in fs/ntfs/quota.c::ntfs_mark_quotas_out_of_date()
- where we failed to release i_mutex on the $Quota/$Q attribute inode.
- - Fix bug in handling of bad inodes in fs/ntfs/namei.c::ntfs_lookup().
- - Add mapping of unmapped buffers to all remaining code paths, i.e.
- fs/ntfs/aops.c::ntfs_write_mst_block(), mft.c::ntfs_sync_mft_mirror(),
- and write_mft_record_nolock(). From now on we require that the
- complete runlist for the mft mirror is always mapped into memory.
- - Add creation of buffers to fs/ntfs/mft.c::ntfs_sync_mft_mirror().
- - Improve error handling in fs/ntfs/aops.c::ntfs_{read,write}_block().
- - Cleanup fs/ntfs/aops.c::ntfs_{read,write}page() since we know that a
- resident attribute will be smaller than a page which makes the code
- simpler. Also make the code more tolerant to concurrent ->truncate.
-
-2.1.21 - Fix some races and bugs, rewrite mft write code, add mft allocator.
-
- - Implement extent mft record deallocation
- fs/ntfs/mft.c::ntfs_extent_mft_record_free().
- - Splitt runlist related functions off from attrib.[hc] to runlist.[hc].
- - Add vol->mft_data_pos and initialize it at mount time.
- - Rename init_runlist() to ntfs_init_runlist(), ntfs_vcn_to_lcn() to
- ntfs_rl_vcn_to_lcn(), decompress_mapping_pairs() to
- ntfs_mapping_pairs_decompress(), ntfs_merge_runlists() to
- ntfs_runlists_merge() and adapt all callers.
- - Add fs/ntfs/runlist.[hc]::ntfs_get_nr_significant_bytes(),
- ntfs_get_size_for_mapping_pairs(), ntfs_write_significant_bytes(),
- and ntfs_mapping_pairs_build(), adapted from libntfs.
- - Make fs/ntfs/lcnalloc.c::ntfs_cluster_free_from_rl_nolock() not
- static and add a declaration for it to lcnalloc.h.
- - Add fs/ntfs/lcnalloc.h::ntfs_cluster_free_from_rl() which is a static
- inline wrapper for ntfs_cluster_free_from_rl_nolock() which takes the
- cluster bitmap lock for the duration of the call.
- - Add fs/ntfs/attrib.[hc]::ntfs_attr_record_resize().
- - Implement the equivalent of memset() for an ntfs attribute in
- fs/ntfs/attrib.[hc]::ntfs_attr_set() and switch
- fs/ntfs/logfile.c::ntfs_empty_logfile() to using it.
- - Remove unnecessary casts from LCN_* constants.
- - Implement fs/ntfs/runlist.c::ntfs_rl_truncate_nolock().
- - Add MFT_RECORD_OLD as a copy of MFT_RECORD in fs/ntfs/layout.h and
- change MFT_RECORD to contain the NTFS 3.1+ specific fields.
- - Add a helper function fs/ntfs/aops.c::mark_ntfs_record_dirty() which
- marks all buffers belonging to an ntfs record dirty, followed by
- marking the page the ntfs record is in dirty and also marking the vfs
- inode containing the ntfs record dirty (I_DIRTY_PAGES).
- - Switch fs/ntfs/index.h::ntfs_index_entry_mark_dirty() to using the
- new helper fs/ntfs/aops.c::mark_ntfs_record_dirty() and remove the no
- longer needed fs/ntfs/index.[hc]::__ntfs_index_entry_mark_dirty().
- - Move ntfs_{un,}map_page() from ntfs.h to aops.h and fix resulting
- include errors.
- - Move the typedefs for runlist_element and runlist from types.h to
- runlist.h and fix resulting include errors.
- - Remove unused {__,}format_mft_record() from fs/ntfs/mft.c.
- - Modify fs/ntfs/mft.c::__mark_mft_record_dirty() to use the helper
- mark_ntfs_record_dirty() which also changes the behaviour in that we
- now set the buffers belonging to the mft record dirty as well as the
- page itself.
- - Update fs/ntfs/mft.c::write_mft_record_nolock() and sync_mft_mirror()
- to cope with the fact that there now are dirty buffers in mft pages.
- - Update fs/ntfs/inode.c::ntfs_write_inode() to also use the helper
- mark_ntfs_record_dirty() and thus to set the buffers belonging to the
- mft record dirty as well as the page itself.
- - Fix compiler warnings on x86-64 in fs/ntfs/dir.c. (Randy Dunlap,
- slightly modified by me)
- - Add fs/ntfs/mft.c::try_map_mft_record() which fails with -EALREADY if
- the mft record is already locked and otherwise behaves the same way
- as fs/ntfs/mft.c::map_mft_record().
- - Modify fs/ntfs/mft.c::write_mft_record_nolock() so that it only
- writes the mft record if the buffers belonging to it are dirty.
- Otherwise we assume that it was written out by other means already.
- - Attempting to write outside initialized size is _not_ a bug so remove
- the bug check from fs/ntfs/aops.c::ntfs_write_mst_block(). It is in
- fact required to write outside initialized size when preparing to
- extend the initialized size.
- - Map the page instead of using page_address() before writing to it in
- fs/ntfs/aops.c::ntfs_mft_writepage().
- - Provide exclusion between opening an inode / mapping an mft record
- and accessing the mft record in fs/ntfs/mft.c::ntfs_mft_writepage()
- by setting the page not uptodate throughout ntfs_mft_writepage().
- - Clear the page uptodate flag in fs/ntfs/aops.c::ntfs_write_mst_block()
- to ensure noone can see the page whilst the mst fixups are applied.
- - Add the helper fs/ntfs/mft.c::ntfs_may_write_mft_record() which
- checks if an mft record may be written out safely obtaining any
- necessary locks in the process. This is used by
- fs/ntfs/aops.c::ntfs_write_mst_block().
- - Modify fs/ntfs/aops.c::ntfs_write_mst_block() to also work for
- writing mft records and improve its error handling in the process.
- Now if any of the records in the page fail to be written out, all
- other records will be written out instead of aborting completely.
- - Remove ntfs_mft_aops and update all users to use ntfs_mst_aops.
- - Modify fs/ntfs/inode.c::ntfs_read_locked_inode() to set the
- ntfs_mst_aops for all inodes which are NInoMstProtected() and
- ntfs_aops for all other inodes.
- - Rename fs/ntfs/mft.c::sync_mft_mirror{,_umount}() to
- ntfs_sync_mft_mirror{,_umount}() and change their parameters so they
- no longer require an ntfs inode to be present. Update all callers.
- - Cleanup the error handling in fs/ntfs/mft.c::ntfs_sync_mft_mirror().
- - Clear the page uptodate flag in fs/ntfs/mft.c::ntfs_sync_mft_mirror()
- to ensure noone can see the page whilst the mst fixups are applied.
- - Remove the no longer needed fs/ntfs/mft.c::ntfs_mft_writepage() and
- fs/ntfs/mft.c::try_map_mft_record().
- - Fix callers of fs/ntfs/aops.c::mark_ntfs_record_dirty() to call it
- with the ntfs inode which contains the page rather than the ntfs
- inode the mft record of which is in the page.
- - Fix race condition in fs/ntfs/inode.c::ntfs_put_inode() by moving the
- index inode bitmap inode release code from there to
- fs/ntfs/inode.c::ntfs_clear_big_inode(). (Thanks to Christoph
- Hellwig for spotting this.)
- - Fix race condition in fs/ntfs/inode.c::ntfs_put_inode() by taking the
- inode semaphore around the code that sets ni->itype.index.bmp_ino to
- NULL and reorganize the code to optimize it a bit. (Thanks to
- Christoph Hellwig for spotting this.)
- - Modify fs/ntfs/aops.c::mark_ntfs_record_dirty() to no longer take the
- ntfs inode as a parameter as this is confusing and misleading and the
- needed ntfs inode is available via NTFS_I(page->mapping->host).
- Adapt all callers to this change.
- - Modify fs/ntfs/mft.c::write_mft_record_nolock() and
- fs/ntfs/aops.c::ntfs_write_mst_block() to only check the dirty state
- of the first buffer in a record and to take this as the ntfs record
- dirty state. We cannot look at the dirty state for subsequent
- buffers because we might be racing with
- fs/ntfs/aops.c::mark_ntfs_record_dirty().
- - Move the static inline ntfs_init_big_inode() from fs/ntfs/inode.c to
- inode.h and make fs/ntfs/inode.c::__ntfs_init_inode() non-static and
- add a declaration for it to inode.h. Fix some compilation issues
- that resulted due to #includes and header file interdependencies.
- - Simplify setup of i_mode in fs/ntfs/inode.c::ntfs_read_locked_inode().
- - Add helpers fs/ntfs/layout.h::MK_MREF() and MK_LE_MREF().
- - Modify fs/ntfs/mft.c::map_extent_mft_record() to only verify the mft
- record sequence number if it is specified (i.e. not zero).
- - Add fs/ntfs/mft.[hc]::ntfs_mft_record_alloc() and various helper
- functions used by it.
- - Update Documentation/filesystems/ntfs.txt with instructions on how to
- use the Device-Mapper driver with NTFS ftdisk/LDM raid. This removes
- the linear raid problem with the Software RAID / MD driver when one
- or more of the devices has an odd number of sectors.
-
-2.1.20 - Fix two stupid bugs introduced in 2.1.18 release.
-
- - Fix stupid bug in fs/ntfs/attrib.c::ntfs_attr_reinit_search_ctx()
- where we did not clear ctx->al_entry but it was still set due to
- changes in ntfs_attr_lookup() and ntfs_external_attr_find() in
- particular.
- - Fix another stupid bug in fs/ntfs/attrib.c::ntfs_external_attr_find()
- where we forgot to unmap the extent mft record when we had finished
- enumerating an attribute which caused a bug check to trigger when the
- VFS calls ->clear_inode.
-
-2.1.19 - Many cleanups, improvements, and a minor bug fix.
-
- - Update ->setattr (fs/ntfs/inode.c::ntfs_setattr()) to refuse to
- change the uid, gid, and mode of an inode as we do not support NTFS
- ACLs yet.
- - Remove BKL use from ntfs_setattr() syncing up with the rest of the
- kernel.
- - Get rid of the ugly transparent union in fs/ntfs/dir.c::ntfs_readdir()
- and ntfs_filldir() as per suggestion from Al Viro.
- - Change '\0' and L'\0' to simply 0 as per advice from Linus Torvalds.
- - Update ->truncate (fs/ntfs/inode.c::ntfs_truncate()) to check if the
- inode size has changed and to only output an error if so.
- - Rename fs/ntfs/attrib.h::attribute_value_length() to ntfs_attr_size().
- - Add le{16,32,64} as well as sle{16,32,64} data types to
- fs/ntfs/types.h.
- - Change ntfschar to be le16 instead of u16 in fs/ntfs/types.h.
- - Add le versions of VCN, LCN, and LSN called leVCN, leLCN, and leLSN,
- respectively, to fs/ntfs/types.h.
- - Update endianness conversion macros in fs/ntfs/endian.h to use the
- new types as appropriate.
- - Do proper type casting when using sle64_to_cpup() in fs/ntfs/dir.c
- and index.c.
- - Add leMFT_REF data type to fs/ntfs/layout.h.
- - Update all NTFS header files with the new little endian data types.
- Affected files are fs/ntfs/layout.h, logfile.h, and time.h.
- - Do proper type casting when using ntfs_is_*_recordp() in
- fs/ntfs/logfile.c, mft.c, and super.c.
- - Fix all the sparse bitwise warnings. Had to change all the typedef
- enums storing little endian values to simple enums plus a typedef for
- the datatype to make sparse happy.
- - Fix a bug found by the new sparse bitwise warnings where the default
- upcase table was defined as a pointer to wchar_t rather than ntfschar
- in fs/ntfs/ntfs.h and super.c.
- - Change {const_,}cpu_to_le{16,32}(0) to just 0 as suggested by Al Viro.
-
-2.1.18 - Fix scheduling latencies at mount time as well as an endianness bug.
-
- - Remove vol->nr_mft_records as it was pretty meaningless and optimize
- the calculation of total/free inodes as used by statfs().
- - Fix scheduling latencies in ntfs_fill_super() by dropping the BKL
- because the code itself is using the ntfs_lock semaphore which
- provides safe locking. (Ingo Molnar)
- - Fix a potential bug in fs/ntfs/mft.c::map_extent_mft_record() that
- could occur in the future for when we start closing/freeing extent
- inodes if we don't set base_ni->ext.extent_ntfs_inos to NULL after
- we free it.
- - Rename {find,lookup}_attr() to ntfs_attr_{find,lookup}() as well as
- find_external_attr() to ntfs_external_attr_find() to cleanup the
- namespace a bit and to be more consistent with libntfs.
- - Rename {{re,}init,get,put}_attr_search_ctx() to
- ntfs_attr_{{re,}init,get,put}_search_ctx() as well as the type
- attr_search_context to ntfs_attr_search_ctx.
- - Force use of ntfs_attr_find() in ntfs_attr_lookup() when searching
- for the attribute list attribute itself.
- - Fix endianness bug in ntfs_external_attr_find().
- - Change ntfs_{external_,}attr_find() to return 0 on success, -ENOENT
- if the attribute is not found, and -EIO on real error. In the case
- of -ENOENT, the search context is updated to describe the attribute
- before which the attribute being searched for would need to be
- inserted if such an action were to be desired and in the case of
- ntfs_external_attr_find() the search context is also updated to
- indicate the attribute list entry before which the attribute list
- entry of the attribute being searched for would need to be inserted
- if such an action were to be desired. Also make ntfs_find_attr()
- static and remove its prototype from attrib.h as it is not used
- anywhere other than attrib.c. Update ntfs_attr_lookup() and all
- callers of ntfs_{external,}attr_{find,lookup}() for the new return
- values.
- - Minor cleanup of fs/ntfs/inode.c::ntfs_init_locked_inode().
-
-2.1.17 - Fix bugs in mount time error code paths and other updates.
-
- - Implement bitmap modification code (fs/ntfs/bitmap.[hc]). This
- includes functions to set/clear a single bit or a run of bits.
- - Add fs/ntfs/attrib.[hc]::ntfs_find_vcn() which returns the locked
- runlist element containing a particular vcn. It also takes care of
- mapping any needed runlist fragments.
- - Implement cluster (de-)allocation code (fs/ntfs/lcnalloc.[hc]).
- - Load attribute definition table from $AttrDef at mount time.
- - Fix bugs in mount time error code paths involving (de)allocation of
- the default and volume upcase tables.
- - Remove ntfs_nr_mounts as it is no longer used.
-
-2.1.16 - Implement access time updates, file sync, async io, and read/writev.
-
- - Add support for readv/writev and aio_read/aio_write (fs/ntfs/file.c).
- This is done by setting the appropriate file operations pointers to
- the generic helper functions provided by mm/filemap.c.
- - Implement fsync, fdatasync, and msync both for files (fs/ntfs/file.c)
- and directories (fs/ntfs/dir.c).
- - Add support for {a,m,c}time updates to inode.c::ntfs_write_inode().
- Note, except for the root directory and any other system files opened
- by the user, the system files will not have their access times
- updated as they are only accessed at the inode level an hence the
- file level functions which cause the times to be updated are never
- invoked.
-
-2.1.15 - Invalidate quotas when (re)mounting read-write.
-
- - Add new element itype.index.collation_rule to the ntfs inode
- structure and set it appropriately in ntfs_read_locked_inode().
- - Implement a new inode type "index" to allow efficient access to the
- indices found in various system files and adapt inode handling
- accordingly (fs/ntfs/inode.[hc]). An index inode is essentially an
- attribute inode (NInoAttr() is true) with an attribute type of
- AT_INDEX_ALLOCATION. As such, it is no longer allowed to call
- ntfs_attr_iget() with an attribute type of AT_INDEX_ALLOCATION as
- there would be no way to distinguish between normal attribute inodes
- and index inodes. The function to obtain an index inode is
- ntfs_index_iget() and it uses the helper function
- ntfs_read_locked_index_inode(). Note, we do not overload
- ntfs_attr_iget() as indices consist of multiple attributes so using
- ntfs_attr_iget() to obtain an index inode would be confusing.
- - Ensure that there is no overflow when doing page->index <<
- PAGE_CACHE_SHIFT by casting page->index to s64 in fs/ntfs/aops.c.
- - Use atomic kmap instead of kmap() in fs/ntfs/aops.c::ntfs_read_page()
- and ntfs_read_block().
- - Use case sensitive attribute lookups instead of case insensitive ones.
- - Lock all page cache pages belonging to mst protected attributes while
- accessing them to ensure we never see corrupt data while the page is
- under writeout.
- - Add framework for generic ntfs collation (fs/ntfs/collation.[hc]).
- We have ntfs_is_collation_rule_supported() to check if the collation
- rule you want to use is supported and ntfs_collation() which actually
- collates two data items. We currently only support COLLATION_BINARY
- and COLLATION_NTOFS_ULONG but support for other collation rules will
- be added as the need arises.
- - Add a new type, ntfs_index_context, to allow retrieval of an index
- entry using the corresponding index key. To get an index context,
- use ntfs_index_ctx_get() and to release it, use ntfs_index_ctx_put().
- This also adds a new slab cache for the index contexts. To lookup a
- key in an index inode, use ntfs_index_lookup(). After modifying an
- index entry, call ntfs_index_entry_flush_dcache_page() followed by
- ntfs_index_entry_mark_dirty() to ensure the changes are written out
- to disk. For details see fs/ntfs/index.[hc]. Note, at present, if
- an index entry is in the index allocation attribute rather than the
- index root attribute it will not be written out (you will get a
- warning message about discarded changes instead).
- - Load the quota file ($Quota) and check if quota tracking is enabled
- and if so, mark the quotas out of date. This causes windows to
- rescan the volume on boot and update all quota entries.
- - Add a set_page_dirty address space operation for ntfs_m[fs]t_aops.
- It is simply set to __set_page_dirty_nobuffers() to make sure that
- running set_page_dirty() on a page containing mft/ntfs records will
- not affect the dirty state of the page buffers.
- - Add fs/ntfs/index.c::__ntfs_index_entry_mark_dirty() which sets all
- buffers that are inside the ntfs record in the page dirty after which
- it sets the page dirty. This allows ->writepage to only write the
- dirty index records rather than having to write all the records in
- the page. Modify fs/ntfs/index.h::ntfs_index_entry_mark_dirty() to
- use this rather than __set_page_dirty_nobuffers().
- - Implement fs/ntfs/aops.c::ntfs_write_mst_block() which enables the
- writing of page cache pages belonging to mst protected attributes
- like the index allocation attribute in directory indices and other
- indices like $Quota/$Q, etc. This means that the quota is now marked
- out of date on all volumes rather than only on ones where the quota
- defaults entry is in the index root attribute of the $Quota/$Q index.
-
-2.1.14 - Fix an NFSd caused deadlock reported by several users.
-
- - Modify fs/ntfs/ntfs_readdir() to copy the index root attribute value
- to a buffer so that we can put the search context and unmap the mft
- record before calling the filldir() callback. We need to do this
- because of NFSd which calls ->lookup() from its filldir callback()
- and this causes NTFS to deadlock as ntfs_lookup() maps the mft record
- of the directory and since ntfs_readdir() has got it mapped already
- ntfs_lookup() deadlocks.
-
-2.1.13 - Enable overwriting of resident files and housekeeping of system files.
-
- - Implement writing of mft records (fs/ntfs/mft.[hc]), which includes
- keeping the mft mirror in sync with the mft when mirrored mft records
- are written. The functions are write_mft_record{,_nolock}(). The
- implementation is quite rudimentary for now with lots of things not
- implemented yet but I am not sure any of them can actually occur so
- I will wait for people to hit each one and only then implement it.
- - Commit open system inodes at umount time. This should make it
- virtually impossible for sync_mft_mirror_umount() to ever be needed.
- - Implement ->write_inode (fs/ntfs/inode.c::ntfs_write_inode()) for the
- ntfs super operations. This gives us inode writing via the VFS inode
- dirty code paths. Note: Access time updates are not implemented yet.
- - Implement fs/ntfs/mft.[hc]::{,__}mark_mft_record_dirty() and make
- fs/ntfs/aops.c::ntfs_writepage() and ntfs_commit_write() use it, thus
- finally enabling resident file overwrite! (-8 This also includes a
- placeholder for ->writepage (ntfs_mft_writepage()), which for now
- just redirties the page and returns. Also, at umount time, we for
- now throw away all mft data page cache pages after the last call to
- ntfs_commit_inode() in the hope that all inodes will have been
- written out by then and hence no dirty (meta)data will be lost. We
- also check for this case and emit an error message telling the user
- to run chkdsk.
- - Use set_page_writeback() and end_page_writeback() in the resident
- attribute code path of fs/ntfs/aops.c::ntfs_writepage() otherwise
- the radix-tree tag PAGECACHE_TAG_DIRTY remains set even though the
- page is clean.
- - Implement ntfs_mft_writepage() so it now checks if any of the mft
- records in the page are dirty and if so redirties the page and
- returns. Otherwise it just returns (after doing set_page_writeback(),
- unlock_page(), end_page_writeback() or the radix-tree tag
- PAGECACHE_TAG_DIRTY remains set even though the page is clean), thus
- alowing the VM to do with the page as it pleases. Also, at umount
- time, now only throw away dirty mft (meta)data pages if dirty inodes
- are present and ask the user to email us if they see this happening.
- - Add functions ntfs_{clear,set}_volume_flags(), to modify the volume
- information flags (fs/ntfs/super.c).
- - Mark the volume dirty when (re)mounting read-write and mark it clean
- when unmounting or remounting read-only. If any volume errors are
- found, the volume is left marked dirty to force chkdsk to run.
- - Add code to set the NT4 compatibility flag when (re)mounting
- read-write for newer NTFS versions but leave it commented out for now
- since we do not make any modifications that are NTFS 1.2 specific yet
- and since setting this flag breaks Captive-NTFS which is not nice.
- This code must be enabled once we start writing NTFS 1.2 specific
- changes otherwise Windows NTFS driver might crash / cause corruption.
-
-2.1.12 - Fix the second fix to the decompression engine and some cleanups.
-
- - Add a new address space operations struct, ntfs_mst_aops, for mst
- protected attributes. This is because the default ntfs_aops do not
- make sense with mst protected data and were they to write anything to
- such an attribute they would cause data corruption so we provide
- ntfs_mst_aops which does not have any write related operations set.
- - Cleanup dirty ntfs inode handling (fs/ntfs/inode.[hc]) which also
- includes an adapted ntfs_commit_inode() and an implementation of
- ntfs_write_inode() which for now just cleans dirty inodes without
- writing them (it does emit a warning that this is happening).
- - Undo the second decompression engine fix (see 2.1.9 release ChangeLog
- entry) as it was only fixing a theoretical bug but at the same time
- it badly broke the handling of sparse and uncompressed compression
- blocks.
-
-2.1.11 - Driver internal cleanups.
-
- - Only build logfile.o if building the driver with read-write support.
- - Really final white space cleanups.
- - Use generic_ffs() instead of ffs() in logfile.c which allows the
- log_page_size variable to be optimized by gcc into a constant.
- - Rename uchar_t to ntfschar everywhere as uchar_t is unsigned 1-byte
- char as defined by POSIX and as found on some systems.
-
-2.1.10 - Force read-only (re)mounting of volumes with unsupported volume flags.
-
- - Finish off the white space cleanups (remove trailing spaces, etc).
- - Clean up ntfs_fill_super() and ntfs_read_inode_mount() by removing
- the kludges around the first iget(). Instead of (re)setting ->s_op
- we have the $MFT inode set up by explicit new_inode() / set ->i_ino /
- insert_inode_hash() / call ntfs_read_inode_mount() directly. This
- kills the need for second super_operations and allows to return error
- from ntfs_read_inode_mount() without resorting to ugly "poisoning"
- tricks. (Al Viro)
- - Force read-only (re)mounting if any of the following bits are set in
- the volume information flags:
- VOLUME_IS_DIRTY, VOLUME_RESIZE_LOG_FILE,
- VOLUME_UPGRADE_ON_MOUNT, VOLUME_DELETE_USN_UNDERWAY,
- VOLUME_REPAIR_OBJECT_ID, VOLUME_MODIFIED_BY_CHKDSK
- To make this easier we define VOLUME_MUST_MOUNT_RO_MASK with all the
- above bits set so the test is made easy.
-
-2.1.9 - Fix two bugs in decompression engine.
-
- - Fix a bug where we would not always detect that we have reached the
- end of a compression block because we were ending at minus one byte
- which is effectively the same as being at the end. The fix is to
- check whether the uncompressed buffer has been fully filled and if so
- we assume we have reached the end of the compression block. A big
- thank you to Marcin Gibuła for the bug report, the assistance in
- tracking down the bug and testing the fix.
- - Fix a possible bug where when a compressed read is truncated to the
- end of the file, the offset inside the last page was not truncated.
-
-2.1.8 - Handle $MFT mirror and $LogFile, improve time handling, and cleanups.
-
- - Use get_bh() instead of manual atomic_inc() in fs/ntfs/compress.c.
- - Modify fs/ntfs/time.c::ntfs2utc(), get_current_ntfs_time(), and
- utc2ntfs() to work with struct timespec instead of time_t on the
- Linux UTC time side thus preserving the full precision of the NTFS
- time and only loosing up to 99 nano-seconds in the Linux UTC time.
- - Move fs/ntfs/time.c to fs/ntfs/time.h and make the time functions
- static inline.
- - Remove unused ntfs_dirty_inode().
- - Cleanup super operations declaration in fs/ntfs/super.c.
- - Wrap flush_dcache_mft_record_page() in #ifdef NTFS_RW.
- - Add NInoTestSetFoo() and NInoTestClearFoo() macro magic to
- fs/ntfs/inode.h and use it to declare NInoTest{Set,Clear}Dirty.
- - Move typedefs for ntfs_attr and test_t from fs/ntfs/inode.c to
- fs/ntfs/inode.h so they can be used elsewhere.
- - Determine the mft mirror size as the number of mirrored mft records
- and store it in ntfs_volume->mftmirr_size (fs/ntfs/super.c).
- - Load the mft mirror at mount time and compare the mft records stored
- in it to the ones in the mft. Force a read-only mount if the two do
- not match (fs/ntfs/super.c).
- - Fix type casting related warnings on 64-bit architectures. Thanks
- to Meelis Roos for reporting them.
- - Move %L to %ll as %L is floating point and %ll is integer which is
- what we want.
- - Read the journal ($LogFile) and determine if the volume has been
- shutdown cleanly and force a read-only mount if not (fs/ntfs/super.c
- and fs/ntfs/logfile.c). This is a little bit of a crude check in
- that we only look at the restart areas and not at the actual log
- records so that there will be a very small number of cases where we
- think that a volume is dirty when in fact it is clean. This should
- only affect volumes that have not been shutdown cleanly and did not
- have any pending, non-check-pointed i/o.
- - If the $LogFile indicates a clean shutdown and a read-write (re)mount
- is requested, empty $LogFile by overwriting it with 0xff bytes to
- ensure that Windows cannot cause data corruption by replaying a stale
- journal after Linux has written to the volume.
-
-2.1.7 - Enable NFS exporting of mounted NTFS volumes.
-
- - Set i_generation in the VFS inode from the seq_no of the NTFS inode.
- - Make ntfs_lookup() NFS export safe, i.e. use d_splice_alias(), etc.
- - Implement ->get_dentry() in fs/ntfs/namei.c::ntfs_get_dentry() as the
- default doesn't allow inode number 0 which is a valid inode on NTFS
- and even if it did allow that it uses iget() instead of ntfs_iget()
- which makes it useless for us.
- - Implement ->get_parent() in fs/ntfs/namei.c::ntfs_get_parent() as the
- default just returns -EACCES which is not very useful.
- - Define export operations (->s_export_op) for NTFS (ntfs_export_ops)
- and set them up in the super block at mount time (super.c) this
- allows mounted NTFS volumes to be exported via NFS.
- - Add missing return -EOPNOTSUPP; in
- fs/ntfs/aops.c::ntfs_commit_nonresident_write().
- - Enforce no atime and no dir atime updates at mount/remount time as
- they are not implemented yet anyway.
- - Move a few assignments in fs/ntfs/attrib.c::load_attribute_list() to
- after a NULL check. Thanks to Dave Jones for pointing this out.
-
-2.1.6 - Fix minor bug in handling of compressed directories.
-
- - Fix bug in handling of compressed directories. A compressed
- directory is not really compressed so when we set the ->i_blocks
- field of a compressed directory inode we were setting it from the
- non-existing field ni->itype.compressed.size which gave random
- results... For directories we now always use ni->allocated_size.
-
-2.1.5 - Fix minor bug in attribute list attribute handling.
-
- - Fix bug in attribute list handling. Actually it is not as much a bug
- as too much protection in that we were not allowing attribute lists
- which waste space on disk while Windows XP clearly allows it and in
- fact creates such attribute lists so our driver was failing.
- - Update NTFS documentation ready for 2.6 kernel release.
-
-2.1.4 - Reduce compiler requirements.
-
- - Remove all uses of unnamed structs and unions in the driver to make
- old and newer gcc versions happy. Makes it a bit uglier IMO but at
- least people will stop hassling me about it.
-
-2.1.3 - Important bug fixes in corner cases.
-
- - super.c::parse_ntfs_boot_sector(): Correct the check for 64-bit
- clusters. (Philipp Thomas)
- - attrib.c::load_attribute_list(): Fix bug when initialized_size is a
- multiple of the block_size but not the cluster size. (Szabolcs
- Szakacsits)
-
-2.1.2 - Important bug fixes aleviating the hangs in statfs.
-
- - Fix buggy free cluster and free inode determination logic.
-
-2.1.1 - Minor updates.
-
- - Add handling for initialized_size != data_size in compressed files.
- - Reduce function local stack usage from 0x3d4 bytes to just noise in
- fs/ntfs/upcase.c. (Randy Dunlap)
- - Remove compiler warnings for newer gcc.
- - Pages are no longer kmapped by mm/filemap.c::generic_file_write()
- around calls to ->{prepare,commit}_write. Adapt NTFS appropriately
- in fs/ntfs/aops.c::ntfs_prepare_nonresident_write() by using
- kmap_atomic(KM_USER0).
-
-2.1.0 - First steps towards write support: implement file overwrite.
-
- - Add configuration option for developmental write support with an
- appropriately scary configuration help text.
- - Initial implementation of fs/ntfs/aops.c::ntfs_writepage() and its
- helper fs/ntfs/aops.c::ntfs_write_block(). This enables mmap(2) based
- overwriting of existing files on ntfs. Note: Resident files are
- only written into memory, and not written out to disk at present, so
- avoid writing to files smaller than about 1kiB.
- - Initial implementation of fs/ntfs/aops.c::ntfs_prepare_write(), its
- helper fs/ntfs/aops.c::ntfs_prepare_nonresident_write() and their
- counterparts, fs/ntfs/aops.c::ntfs_commit_write(), and
- fs/ntfs/aops.c::ntfs_commit_nonresident_write(), respectively. Also,
- add generic_file_write() to the ntfs file operations (fs/ntfs/file.c).
- This enables write(2) based overwriting of existing files on ntfs.
- Note: As with mmap(2) based overwriting, resident files are only
- written into memory, and not written out to disk at present, so avoid
- writing to files smaller than about 1kiB.
- - Implement ->truncate (fs/ntfs/inode.c::ntfs_truncate()) and
- ->setattr() (fs/ntfs/inode.c::ntfs_setattr()) inode operations for
- files with the purpose of intercepting and aborting all i_size
- changes which we do not support yet. ntfs_truncate() actually only
- emits a warning message but AFAICS our interception of i_size changes
- elsewhere means ntfs_truncate() never gets called for i_size changes.
- It is only called from generic_file_write() when we fail in
- ntfs_prepare_{,nonresident_}write() in order to discard any
- instantiated buffers beyond i_size. Thus i_size is not actually
- changed so our warning message is enough. Unfortunately it is not
- possible to easily determine if i_size is being changed or not hence
- we just emit an appropriately worded error message.
-
-2.0.25 - Small bug fixes and cleanups.
-
- - Unlock the page in an out of memory error code path in
- fs/ntfs/aops.c::ntfs_read_block().
- - If fs/ntfs/aops.c::ntfs_read_page() is called on an uptodate page,
- just unlock the page and return. (This can happen due to ->writepage
- clearing PageUptodate() during write out of MstProtected()
- attributes.
- - Remove leaked write code again.
-
-2.0.24 - Cleanups.
-
- - Treat BUG_ON() as ASSERT() not VERIFY(), i.e. do not use side effects
- inside BUG_ON(). (Adam J. Richter)
- - Split logical OR expressions inside BUG_ON() into individual BUG_ON()
- calls for improved debugging. (Adam J. Richter)
- - Add errors flag to the ntfs volume state, accessed via
- NVol{,Set,Clear}Errors(vol).
- - Do not allow read-write remounts of read-only volumes with errors.
- - Clarify comment for ntfs file operation sendfile which was added by
- Christoph Hellwig a while ago (just using generic_file_sendfile())
- to say that ntfs ->sendfile is only used for the case where the
- source data is on the ntfs partition and the destination is
- somewhere else, i.e. nothing we need to concern ourselves with.
- - Add generic_file_write() as our ntfs file write operation.
-
-2.0.23 - Major bug fixes (races, deadlocks, non-i386 architectures).
-
- - Massive internal locking changes to mft record locking. Fixes lock
- recursion and replaces the mrec_lock read/write semaphore with a
- mutex. Also removes the now superfluous mft_count. This fixes several
- race conditions and deadlocks, especially in the future write code.
- - Fix ntfs over loopback for compressed files by adding an
- optimization barrier. (gcc was screwing up otherwise ?)
- - Miscellaneous cleanups all over the code and a fix or two in error
- handling code paths.
- Thanks go to Christoph Hellwig for pointing out the following two:
- - Remove now unused function fs/ntfs/malloc.h::vmalloc_nofs().
- - Fix ntfs_free() for ia64 and parisc by checking for VMALLOC_END, too.
-
-2.0.22 - Cleanups, mainly to ntfs_readdir(), and use C99 initializers.
-
- - Change fs/ntfs/dir.c::ntfs_reddir() to only read/write ->f_pos once
- at entry/exit respectively.
- - Use C99 initializers for structures.
- - Remove unused variable blocks from fs/ntfs/aops.c::ntfs_read_block().
-
-2.0.21 - Check for, and refuse to work with too large files/directories/volumes.
-
- - Limit volume size at mount time to 2TiB on architectures where
- unsigned long is 32-bits (fs/ntfs/super.c::parse_ntfs_boot_sector()).
- This is the most we can do without overflowing the 32-bit limit of
- the block device size imposed on us by sb_bread() and sb_getblk()
- for the time being.
- - Limit file/directory size at open() time to 16TiB on architectures
- where unsigned long is 32-bits (fs/ntfs/file.c::ntfs_file_open() and
- fs/ntfs/dir.c::ntfs_dir_open()). This is the most we can do without
- overflowing the page cache page index.
-
-2.0.20 - Support non-resident directory index bitmaps, fix page leak in readdir.
-
- - Move the directory index bitmap to use an attribute inode instead of
- having special fields for it inside the ntfs inode structure. This
- means that the index bitmaps now use the page cache for i/o, too,
- and also as a side effect we get support for non-resident index
- bitmaps for free.
- - Simplify/cleanup error handling in fs/ntfs/dir.c::ntfs_readdir() and
- fix a page leak that manifested itself in some cases.
- - Add fs/ntfs/inode.c::ntfs_put_inode(), which we need to release the
- index bitmap inode on the final iput().
-
-2.0.19 - Fix race condition, improvements, and optimizations in i/o interface.
-
- - Apply block optimization added to fs/ntfs/aops.c::ntfs_read_block()
- to fs/ntfs/compress.c::ntfs_file_read_compressed_block() as well.
- - Drop the "file" from ntfs_file_read_compressed_block().
- - Rename fs/ntfs/aops.c::ntfs_enb_buffer_read_async() to
- ntfs_end_buffer_async_read() (more like the fs/buffer.c counterpart).
- - Update ntfs_end_buffer_async_read() with the improved logic from
- its updated counterpart fs/buffer.c::end_buffer_async_read(). Apply
- further logic improvements to better determine when we set PageError.
- - Update submission of buffers in fs/ntfs/aops.c::ntfs_read_block() to
- check for the buffers being uptodate first in line with the updated
- fs/buffer.c::block_read_full_page(). This plugs a small race
- condition.
-
-2.0.18 - Fix race condition in reading of compressed files.
-
- - There was a narrow window between checking a buffer head for being
- uptodate and locking it in ntfs_file_read_compressed_block(). We now
- lock the buffer and then check whether it is uptodate or not.
-
-2.0.17 - Cleanups and optimizations - shrinking the ToDo list.
-
- - Modify fs/ntfs/inode.c::ntfs_read_locked_inode() to return an error
- code and update callers, i.e. ntfs_iget(), to pass that error code
- up instead of just using -EIO.
- - Modifications to super.c to ensure that both mount and remount
- cannot set any write related options when the driver is compiled
- read-only.
- - Optimize block resolution in fs/ntfs/aops.c::ntfs_read_block() to
- cache the current runlist element. This should improve performance
- when reading very large and/or very fragmented data.
-
-2.0.16 - Convert access to $MFT/$BITMAP to attribute inode API.
-
- - Fix a stupid bug introduced in 2.0.15 where we were unmapping the
- wrong inode in fs/ntfs/inode.c::ntfs_attr_iget().
- - Fix debugging check in fs/ntfs/aops.c::ntfs_read_block().
- - Convert $MFT/$BITMAP access to attribute inode API and remove all
- remnants of the ugly mftbmp address space and operations hack. This
- means we finally have only one readpage function as well as only one
- async io completion handler. Yey! The mft bitmap is now just an
- attribute inode and is accessed from vol->mftbmp_ino just as if it
- were a normal file. Fake inodes rule. (-:
-
-2.0.15 - Fake inodes based attribute i/o via the pagecache, fixes and cleanups.
-
- - Fix silly bug in fs/ntfs/super.c::parse_options() which was causing
- remounts to fail when the partition had an entry in /etc/fstab and
- the entry specified the nls= option.
- - Apply same macro magic used in fs/ntfs/inode.h to fs/ntfs/volume.h to
- expand all the helper functions NVolFoo(), NVolSetFoo(), and
- NVolClearFoo().
- - Move copyright statement from driver initialisation message to
- module description (fs/super.c). This makes the initialisation
- message fit on one line and fits in better with rest of kernel.
- - Update fs/ntfs/attrib.c::map_run_list() to work on both real and
- attribute inodes, and both for files and directories.
- - Implement fake attribute inodes allowing all attribute i/o to go via
- the page cache and to use all the normal vfs/mm functionality:
- - Add ntfs_attr_iget() and its helper ntfs_read_locked_attr_inode()
- to fs/ntfs/inode.c.
- - Add needed cleanup code to ntfs_clear_big_inode().
- - Merge address space operations for files and directories (aops.c),
- now just have ntfs_aops:
- - Rename:
- end_buffer_read_attr_async() -> ntfs_end_buffer_read_async(),
- ntfs_attr_read_block() -> ntfs_read_block(),
- ntfs_file_read_page() -> ntfs_readpage().
- - Rewrite fs/ntfs/aops.c::ntfs_readpage() to work on both real and
- attribute inodes, and both for files and directories.
- - Remove obsolete fs/ntfs/aops.c::ntfs_mst_readpage().
-
-2.0.14 - Run list merging code cleanup, minor locking changes, typo fixes.
-
- - Change fs/ntfs/super.c::ntfs_statfs() to not rely on BKL by moving
- the locking out of super.c::get_nr_free_mft_records() and taking and
- dropping the mftbmp_lock rw_semaphore in ntfs_statfs() itself.
- - Bring attribute runlist merging code (fs/ntfs/attrib.c) in sync with
- current userspace ntfs library code. This means that if a merge
- fails the original runlists are always left unmodified instead of
- being silently corrupted.
- - Misc typo fixes.
-
-2.0.13 - Use iget5_locked() in preparation for fake inodes and small cleanups.
-
- - Remove nr_mft_bits and the now superfluous union with nr_mft_records
- from ntfs_volume structure.
- - Remove nr_lcn_bits and the now superfluous union with nr_clusters
- from ntfs_volume structure.
- - Use iget5_locked() and friends instead of conventional iget(). Wrap
- the call in fs/ntfs/inode.c::ntfs_iget() and update callers of iget()
- to use ntfs_iget(). Leave only one iget() call at mount time so we
- don't need an ntfs_iget_mount().
- - Change fs/ntfs/inode.c::ntfs_new_extent_inode() to take mft_no as an
- additional argument.
-
-2.0.12 - Initial cleanup of address space operations following 2.0.11 changes.
-
- - Merge fs/ntfs/aops.c::end_buffer_read_mst_async() and
- fs/ntfs/aops.c::end_buffer_read_file_async() into one function
- fs/ntfs/aops.c::end_buffer_read_attr_async() using NInoMstProtected()
- to determine whether to apply mst fixups or not.
- - Above change allows merging fs/ntfs/aops.c::ntfs_file_read_block()
- and fs/ntfs/aops.c::ntfs_mst_readpage() into one function
- fs/ntfs/aops.c::ntfs_attr_read_block(). Also, create a tiny wrapper
- fs/ntfs/aops.c::ntfs_mst_readpage() to transform the parameters from
- the VFS readpage function prototype to the ntfs_attr_read_block()
- function prototype.
-
-2.0.11 - Initial preparations for fake inode based attribute i/o.
-
- - Move definition of ntfs_inode_state_bits to fs/ntfs/inode.h and
- do some macro magic (adapted from include/linux/buffer_head.h) to
- expand all the helper functions NInoFoo(), NInoSetFoo(), and
- NInoClearFoo().
- - Add new flag to ntfs_inode_state_bits: NI_Sparse.
- - Add new fields to ntfs_inode structure to allow use of fake inodes
- for attribute i/o: type, name, name_len. Also add new state bits:
- NI_Attr, which, if set, indicates the inode is a fake inode, and
- NI_MstProtected, which, if set, indicates the attribute uses multi
- sector transfer protection, i.e. fixups need to be applied after
- reads and before/after writes.
- - Rename fs/ntfs/inode.c::ntfs_{new,clear,destroy}_inode() to
- ntfs_{new,clear,destroy}_extent_inode() and update callers.
- - Use ntfs_clear_extent_inode() in fs/ntfs/inode.c::__ntfs_clear_inode()
- instead of ntfs_destroy_extent_inode().
- - Cleanup memory deallocations in {__,}ntfs_clear_{,big_}inode().
- - Make all operations on ntfs inode state bits use the NIno* functions.
- - Set up the new ntfs inode fields and state bits in
- fs/ntfs/inode.c::ntfs_read_inode() and add appropriate cleanup of
- allocated memory to __ntfs_clear_inode().
- - Cleanup ntfs_inode structure a bit for better ordering of elements
- w.r.t. their size to allow better packing of the structure in memory.
-
-2.0.10 - There can only be 2^32 - 1 inodes on an NTFS volume.
-
- - Add check at mount time to verify that the number of inodes on the
- volume does not exceed 2^32 - 1, which is the maximum allowed for
- NTFS according to Microsoft.
- - Change mft_no member of ntfs_inode structure to be unsigned long.
- Update all users. This makes ntfs_inode->mft_no just a copy of struct
- inode->i_ino. But we can't just always use struct inode->i_ino and
- remove mft_no because extent inodes do not have an attached struct
- inode.
-
-2.0.9 - Decompression engine now uses a single buffer and other cleanups.
-
- - Change decompression engine to use a single buffer protected by a
- spin lock instead of per-CPU buffers. (Rusty Russell)
- - Do not update cb_pos when handling a partial final page during
- decompression of a sparse compression block, as the value is later
- reset without being read/used. (Rusty Russell)
- - Switch to using the new KM_BIO_SRC_IRQ for atomic kmap()s. (Andrew
- Morton)
- - Change buffer size in ntfs_readdir()/ntfs_filldir() to use
- NLS_MAX_CHARSET_SIZE which makes the buffers almost 1kiB each but
- it also makes everything safer so it is a good thing.
- - Miscellaneous minor cleanups to comments.
-
-2.0.8 - Major updates for handling of case sensitivity and dcache aliasing.
-
- Big thanks go to Al Viro and other inhabitants of #kernel for investing
- their time to discuss the case sensitivity and dcache aliasing issues.
-
- - Remove unused source file fs/ntfs/attraops.c.
- - Remove show_inodes mount option(s), thus dropping support for
- displaying of short file names.
- - Remove deprecated mount option posix.
- - Restore show_sys_files mount option.
- - Add new mount option case_sensitive, to determine if the driver
- treats file names as case sensitive or not. If case sensitive, create
- file names in the POSIX namespace. Otherwise create file names in the
- LONG/WIN32 namespace. Note, files remain accessible via their short
- file name, if it exists.
- - Remove really dumb logic bug in boot sector recovery code.
- - Fix dcache aliasing issues wrt short/long file names via changes
- to fs/ntfs/dir.c::ntfs_lookup_inode_by_name() and
- fs/ntfs/namei.c::ntfs_lookup():
- - Add additional argument to ntfs_lookup_inode_by_name() in which we
- return information about the matching file name if the case is not
- matching or the match is a short file name. See comments above the
- function definition for details.
- - Change ntfs_lookup() to only create dcache entries for the correctly
- cased file name and only for the WIN32 namespace counterpart of DOS
- namespace file names. This ensures we have only one dentry per
- directory and also removes all dcache aliasing issues between short
- and long file names once we add write support. See comments above
- function for details.
- - Fix potential 1 byte overflow in fs/ntfs/unistr.c::ntfs_ucstonls().
-
-2.0.7 - Minor cleanups and updates for changes in core kernel code.
-
- - Remove much of the NULL struct element initializers.
- - Various updates to make compatible with recent kernels.
- - Remove defines of MAX_BUF_PER_PAGE and include linux/buffer_head.h
- in fs/ntfs/ntfs.h instead.
- - Remove no longer needed KERNEL_VERSION checks. We are now in the
- kernel proper so they are no longer needed.
-
-2.0.6 - Major bugfix to make compatible with other kernel changes.
-
- - Initialize the mftbmp address space properly now that there are more
- fields in the struct address_space. This was leading to hangs and
- oopses on umount since 2.5.12 because of changes to other parts of
- the kernel. We probably want a kernel generic init_address_space()
- function...
- - Drop BKL from ntfs_readdir() after consultation with Al Viro. The
- only caller of ->readdir() is vfs_readdir() which holds i_mutex
- during the call, and i_mutex is sufficient protection against changes
- in the directory inode (including ->i_size).
- - Use generic_file_llseek() for directories (as opposed to
- default_llseek()) as this downs i_mutex instead of the BKL which is
- what we now need for exclusion against ->f_pos changes considering we
- no longer take the BKL in ntfs_readdir().
-
-2.0.5 - Major bugfix. Buffer overflow in extent inode handling.
-
- - No need to set old blocksize in super.c::ntfs_fill_super() as the
- VFS does so via invocation of deactivate_super() calling
- fs->fill_super() calling block_kill_super() which does it.
- - BKL moved from VFS into dir.c::ntfs_readdir(). (Linus Torvalds)
- -> Do we really need it? I don't think so as we have exclusion on
- the directory ntfs_inode rw_semaphore mrec_lock. We mmight have to
- move the ->f_pos accesses under the mrec_lock though. Check this...
- - Fix really, really, really stupid buffer overflow in extent inode
- handling in mft.c::map_extent_mft_record().
-
-2.0.4 - Cleanups and updates for kernel 2.5.11.
-
- - Add documentation on how to use the MD driver to be able to use NTFS
- stripe and volume sets in Linux and generally cleanup documentation
- a bit.
- Remove all uses of kdev_t in favour of struct block_device *:
- - Change compress.c::ntfs_file_read_compressed_block() to use
- sb_getblk() instead of getblk().
- - Change super.c::ntfs_fill_super() to use bdev_hardsect_size() instead
- of get_hardsect_size().
- - No need to get old blocksize in super.c::ntfs_fill_super() as
- fs/super.c::get_sb_bdev() already does this.
- - Set bh->b_bdev instead of bh->b_dev throughout aops.c.
-
-2.0.3 - Small bug fixes, cleanups, and performance improvements.
-
- - Remove some dead code from mft.c.
- - Optimize readpage and read_block functions throughout aops.c so that
- only initialized blocks are read. Non-initialized ones have their
- buffer head mapped, zeroed, and set up to date, without scheduling
- any i/o. Thanks to Al Viro for advice on how to avoid the device i/o.
- Thanks go to Andrew Morton for spotting the below:
- - Fix buglet in allocate_compression_buffers() error code path.
- - Call flush_dcache_page() after modifying page cache page contents in
- ntfs_file_readpage().
- - Check for existence of page buffers throughout aops.c before calling
- create_empty_buffers(). This happens when an I/O error occurs and the
- read is retried. (It also happens once writing is implemented so that
- needed doing anyway but I had left it for later...)
- - Don't BUG_ON() uptodate and/or mapped buffers throughout aops.c in
- readpage and read_block functions. Reasoning same as above (i.e. I/O
- error retries and future write code paths.)
-
-2.0.2 - Minor updates and cleanups.
-
- - Cleanup: rename mst.c::__post_read_mst_fixup to post_write_mst_fixup
- and cleanup the code a bit, removing the unused size parameter.
- - Change default fmask to 0177 and update documentation.
- - Change attrib.c::get_attr_search_ctx() to return the search context
- directly instead of taking the address of a pointer. A return value
- of NULL means the allocation failed. Updated all callers
- appropriately.
- - Update to 2.5.9 kernel (preserving backwards compatibility) by
- replacing all occurences of page->buffers with page_buffers(page).
- - Fix minor bugs in runlist merging, also minor cleanup.
- - Updates to bootsector layout and mft mirror contents descriptions.
- - Small bug fix in error detection in unistr.c and some cleanups.
- - Grow name buffer allocations in unistr.c in aligned mutlipled of 64
- bytes.
-
-2.0.1 - Minor updates.
-
- - Make default umask correspond to documentation.
- - Improve documentation.
- - Set default mode to include execute bit. The {u,f,d}mask can be used
- to take it away if desired. This allows binaries to be executed from
- a mounted ntfs partition.
-
-2.0.0 - New version number. Remove TNG from the name. Now in the kernel.
-
- - Add kill_super, just keeping up with the vfs changes in the kernel.
- - Repeat some changes from tng-0.0.8 that somehow got lost on the way
- from the CVS import into BitKeeper.
- - Begin to implement proper handling of allocated_size vs
- initialized_size vs data_size (i.e. i_size). Done are
- mft.c::ntfs_mft_readpage(), aops.c::end_buffer_read_index_async(),
- and attrib.c::load_attribute_list().
- - Lock the runlist in attrib.c::load_attribute_list() while using it.
- - Fix memory leak in ntfs_file_read_compressed_block() and generally
- clean up compress.c a little, removing some uncommented/unused debug
- code.
- - Tidy up dir.c a little bit.
- - Don't bother getting the runlist in inode.c::ntfs_read_inode().
- - Merge mft.c::ntfs_mft_readpage() and aops.c::ntfs_index_readpage()
- creating aops.c::ntfs_mst_readpage(), improving the handling of
- holes and overflow in the process and implementing the correct
- equivalent of ntfs_file_get_block() in ntfs_mst_readpage() itself.
- I am aiming for correctness at the moment. Modularisation can come
- later.
- - Rename aops.c::end_buffer_read_index_async() to
- end_buffer_read_mst_async() and optimize the overflow checking and
- handling.
- - Use the host of the mftbmp address space mapping to hold the ntfs
- volume. This is needed so the async i/o completion handler can
- retrieve a pointer to the volume. Hopefully this will not cause
- problems elsewhere in the kernel... Otherwise will need to use a
- fake inode.
- - Complete implementation of proper handling of allocated_size vs
- initialized_size vs data_size (i.e. i_size) in whole driver.
- Basically aops.c is now completely rewritten.
- - Change NTFS driver name to just NTFS and set version number to 2.0.0
- to make a clear distinction from the old driver which is still on
- version 1.1.22.
-
-tng-0.0.8 - 08/03/2002 - Now using BitKeeper, http://linux-ntfs.bkbits.net/
-
- - Replace bdevname(sb->s_dev) with sb->s_id.
- - Remove now superfluous new-line characters in all callers of
- ntfs_debug().
- - Apply kludge in ntfs_read_inode(), setting i_nlink to 1 for
- directories. Without this the "find" utility gets very upset which is
- fair enough as Linux/Unix do not support directory hard links.
- - Further runlist merging work. (Richard Russon)
- - Backwards compatibility for gcc-2.95. (Richard Russon)
- - Update to kernel 2.5.5-pre1 and rediff the now tiny patch.
- - Convert to new filesystem declaration using ->ntfs_get_sb() and
- replacing ntfs_read_super() with ntfs_fill_super().
- - Set s_maxbytes to MAX_LFS_FILESIZE to avoid page cache page index
- overflow on 32-bit architectures.
- - Cleanup upcase loading code to use ntfs_(un)map_page().
- - Disable/reenable preemtion in critical sections of compession engine.
- - Replace device size determination in ntfs_fill_super() with
- sb->s_bdev->bd_inode->i_size (in bytes) and remove now superfluous
- function super.c::get_nr_blocks().
- - Implement a mount time option (show_inodes) allowing choice of which
- types of inode names readdir() returns and modify ntfs_filldir()
- accordingly. There are several parameters to show_inodes:
- system: system files
- win32: long file names (including POSIX file names) [DEFAULT]
- long: same as win32
- dos: short file names only (excluding POSIX file names)
- short: same as dos
- posix: same as both win32 and dos
- all: all file names
- Note that the options are additive, i.e. specifying:
- -o show_inodes=system,show_inodes=win32,show_inodes=dos
- is the same as specifying:
- -o show_inodes=all
- Note that the "posix" and "all" options will show all directory
- names, BUT the link count on each directory inode entry is set to 1,
- due to Linux not supporting directory hard links. This may well
- confuse some userspace applications, since the directory names will
- have the same inode numbers. Thus it is NOT advisable to use the
- "posix" or "all" options. We provide them only for completeness sake.
- - Add copies of allocated_size, initialized_size, and compressed_size to
- the ntfs inode structure and set them up in
- inode.c::ntfs_read_inode(). These reflect the unnamed data attribute
- for files and the index allocation attribute for directories.
- - Add copies of allocated_size and initialized_size to ntfs inode for
- $BITMAP attribute of large directories and set them up in
- inode.c::ntfs_read_inode().
- - Add copies of allocated_size and initialized_size to ntfs volume for
- $BITMAP attribute of $MFT and set them up in
- super.c::load_system_files().
- - Parse deprecated ntfs driver options (iocharset, show_sys_files,
- posix, and utf8) and tell user what the new options to use are. Note
- we still do support them but they will be removed with kernel 2.7.x.
- - Change all occurences of integer long long printf formatting to hex
- as printk() will not support long long integer format if/when the
- div64 patch goes into the kernel.
- - Make slab caches have stable names and change the names to what they
- were intended to be. These changes are required/made possible by the
- new slab cache name handling which removes the length limitation by
- requiring the caller of kmem_cache_create() to supply a stable name
- which is then referenced but not copied.
- - Rename run_list structure to run_list_element and create a new
- run_list structure containing a pointer to a run_list_element
- structure and a read/write semaphore. Adapt all users of runlists
- to new scheme and take and release the lock as needed. This fixes a
- nasty race as the run_list changes even when inodes are locked for
- reading and even when the inode isn't locked at all, so we really
- needed the serialization. We use a semaphore rather than a spinlock
- as memory allocations can sleep and doing everything GFP_ATOMIC
- would be silly.
- - Cleanup read_inode() removing all code checking for lowest_vcn != 0.
- This can never happen due to the nature of lookup_attr() and how we
- support attribute lists. If it did happen it would imply the inode
- being corrupt.
- - Check for lowest_vcn != 0 in ntfs_read_inode() and mark the inode as
- bad if found.
- - Update to 2.5.6-pre2 changes in struct address_space.
- - Use parent_ino() when accessing d_parent inode number in dir.c.
- - Import Sourceforge CVS repository into BitKeeper repository:
- http://linux-ntfs.bkbits.net/ntfs-tng-2.5
- - Update fs/Makefile, fs/Config.help, fs/Config.in, and
- Documentation/filesystems/ntfs.txt for NTFS TNG.
- - Create kernel configuration option controlling whether debugging
- is enabled or not.
- - Add the required export of end_buffer_io_sync() from the patches
- directory to the kernel code.
- - Update inode.c::ntfs_show_options() with show_inodes mount option.
- - Update errors mount option.
-
-tng-0.0.7 - 13/02/2002 - The driver is now feature complete for read-only!
-
- - Cleanup mft.c and it's debug/error output in particular. Fix a minor
- bug in mapping of extent inodes. Update all the comments to fit all
- the recent code changes.
- - Modify vcn_to_lcn() to cope with entirely unmapped runlists.
- - Cleanups in compress.c, mostly comments and folding help.
- - Implement attrib.c::map_run_list() as a generic helper.
- - Make compress.c::ntfs_file_read_compressed_block() use map_run_list()
- thus making code shorter and enabling attribute list support.
- - Cleanup incorrect use of [su]64 with %L printf format specifier in
- all source files. Type casts to [unsigned] long long added to correct
- the mismatches (important for architectures which have long long not
- being 64 bits).
- - Merge async io completion handlers for directory indexes and $MFT
- data into one by setting the index_block_size{_bits} of the ntfs
- inode for $MFT to the mft_record_size{_bits} of the ntfs_volume.
- - Cleanup aops.c, update comments.
- - Make ntfs_file_get_block() use map_run_list() so all files now
- support attribute lists.
- - Make ntfs_dir_readpage() almost verbatim copy of
- block_read_full_page() by using ntfs_file_get_block() with only real
- difference being the use of our own async io completion handler
- rather than the default one, thus reducing the amount of code and
- automatically enabling attribute list support for directory indices.
- - Fix bug in load_attribute_list() - forgot to call brelse in error
- code path.
- - Change parameters to find_attr() and lookup_attr(). We no longer
- pass in the upcase table and its length. These can be gotten from
- ctx->ntfs_ino->vol->upcase{_len}. Update all callers.
- - Cleanups in attrib.c.
- - Implement merging of runlists, attrib.c::merge_run_lists() and its
- helpers. (Richard Russon)
- - Attribute lists part 2, attribute extents and multi part runlists:
- enable proper support for LCN_RL_NOT_MAPPED and automatic mapping of
- further runlist parts via attrib.c::map_run_list().
- - Tiny endianness bug fix in decompress_mapping_pairs().
-
-tng-0.0.6 - Encrypted directories, bug fixes, cleanups, debugging enhancements.
-
- - Enable encrypted directories. (Their index root is marked encrypted
- to indicate that new files in that directory should be created
- encrypted.)
- - Fix bug in NInoBmpNonResident() macro. (Cut and paste error.)
- - Enable $Extend system directory. Most (if not all) extended system
- files do not have unnamed data attributes so ntfs_read_inode() had to
- special case them but that is ok, as the special casing recovery
- happens inside an error code path so there is zero slow down in the
- normal fast path. The special casing is done by introducing a new
- function inode.c::ntfs_is_extended_system_file() which checks if any
- of the hard links in the inode point to $Extend as being their parent
- directory and if they do we assume this is an extended system file.
- - Create a sysctl/proc interface to allow {dis,en}abling of debug output
- when compiled with -DDEBUG. Default is debug messages to be disabled.
- To enable them, one writes a non-zero value to /proc/sys/fs/ntfs-debug
- (if /proc is enabled) or uses sysctl(2) to effect the same (if sysctl
- interface is enabled). Inspired by old ntfs driver.
- - Add debug_msgs insmod/kernel boot parameter to set whether debug
- messages are {dis,en}abled. This is useful to enable debug messages
- during ntfs initialization and is the only way to activate debugging
- when the sysctl interface is not enabled.
- - Cleanup debug output in various places.
- - Remove all dollar signs ($) from the source (except comments) to
- enable compilation on architectures whose gcc compiler does not
- support dollar signs in the names of variables/constants. Attribute
- types now start with AT_ instead of $ and $I30 is now just I30.
- - Cleanup ntfs_lookup() and add consistency check of sequence numbers.
- - Load complete runlist for $MFT/$BITMAP during mount and cleanup
- access functions. This means we now cope with $MFT/$BITMAP being
- spread accross several mft records.
- - Disable modification of mft_zone_multiplier on remount. We can always
- reenable this later on if we really want to, but we will need to make
- sure we readjust the mft_zone size / layout accordingly.
-
-tng-0.0.5 - Modernize for 2.5.x and further in line-ing with Al Viro's comments.
-
- - Use sb_set_blocksize() instead of set_blocksize() and verify the
- return value.
- - Use sb_bread() instead of bread() throughout.
- - Add index_vcn_size{_bits} to ntfs_inode structure to store the size
- of a directory index block vcn. Apply resulting simplifications in
- dir.c everywhere.
- - Fix a small bug somewhere (but forgot what it was).
- - Change ntfs_{debug,error,warning} to enable gcc to do type checking
- on the printf-format parameter list and fix bugs reported by gcc
- as a result. (Richard Russon)
- - Move inode allocation strategy to Al's new stuff but maintain the
- divorce of ntfs_inode from struct inode. To achieve this we have two
- separate slab caches, one for big ntfs inodes containing a struct
- inode and pure ntfs inodes and at the same time fix some faulty
- error code paths in ntfs_read_inode().
- - Show mount options in proc (inode.c::ntfs_show_options()).
-
-tng-0.0.4 - Big changes, getting in line with Al Viro's comments.
-
- - Modified (un)map_mft_record functions to be common for read and write
- case. To specify which is which, added extra parameter at front of
- parameter list. Pass either READ or WRITE to this, each has the
- obvious meaning.
- - General cleanups to allow for easier folding in vi.
- - attrib.c::decompress_mapping_pairs() now accepts the old runlist
- argument, and invokes attrib.c::merge_run_lists() to merge the old
- and the new runlists.
- - Removed attrib.c::find_first_attr().
- - Implemented loading of attribute list and complete runlist for $MFT.
- This means we now cope with $MFT being spread across several mft
- records.
- - Adapt to 2.5.2-pre9 and the changed create_empty_buffers() syntax.
- - Adapt major/minor/kdev_t/[bk]devname stuff to new 2.5.x kernels.
- - Make ntfs_volume be allocated via kmalloc() instead of using a slab
- cache. There are too little ntfs_volume structures at any one time
- to justify a private slab cache.
- - Fix bogus kmap() use in async io completion. Now use kmap_atomic().
- Use KM_BIO_IRQ on advice from IRC/kernel...
- - Use ntfs_map_page() in map_mft_record() and create ->readpage method
- for reading $MFT (ntfs_mft_readpage). In the process create dedicated
- address space operations (ntfs_mft_aops) for $MFT inode mapping. Also
- removed the now superfluous exports from the kernel core patch.
- - Fix a bug where kfree() was used instead of ntfs_free().
- - Change map_mft_record() to take ntfs_inode as argument instead of
- vfs inode. Dito for unmap_mft_record(). Adapt all callers.
- - Add pointer to ntfs_volume to ntfs_inode.
- - Add mft record number and sequence number to ntfs_inode. Stop using
- i_ino and i_generation for in-driver purposes.
- - Implement attrib.c::merge_run_lists(). (Richard Russon)
- - Remove use of proper inodes by extent inodes. Move i_ino and
- i_generation to ntfs_inode to do this. Apply simplifications that
- result and remove iget_no_wait(), etc.
- - Pass ntfs_inode everywhere in the driver (used to be struct inode).
- - Add reference counting in ntfs_inode for the ntfs inode itself and
- for the mapped mft record.
- - Extend mft record mapping so we can (un)map extent mft records (new
- functions (un)map_extent_mft_record), and so mappings are reference
- counted and don't have to happen twice if already mapped - just ref
- count increases.
- - Add -o iocharset as alias to -o nls for backwards compatibility.
- - The latest core patch is now tiny. In fact just a single additional
- export is necessary over the base kernel.
-
-tng-0.0.3 - Cleanups, enhancements, bug fixes.
-
- - Work on attrib.c::decompress_mapping_pairs() to detect base extents
- and setup the runlist appropriately using knowledge provided by the
- sizes in the base attribute record.
- - Balance the get_/put_attr_search_ctx() calls so we don't leak memory
- any more.
- - Introduce ntfs_malloc_nofs() and ntfs_free() to allocate/free a single
- page or use vmalloc depending on the amount of memory requested.
- - Cleanup error output. The __FUNCTION__ "(): " is now added
- automatically. Introduced a new header file debug.h to support this
- and also moved ntfs_debug() function into it.
- - Make reading of compressed files more intelligent and especially get
- rid of the vmalloc_nofs() from readpage(). This now uses per CPU
- buffers (allocated at first mount with cluster size <= 4kiB and
- deallocated on last umount with cluster size <= 4kiB), and
- asynchronous io for the compressed data using a list of buffer heads.
- Er, we use synchronous io as async io only works on whole pages
- covered by buffers and not on individual buffer heads...
- - Bug fix for reading compressed files with sparse compression blocks.
-
-tng-0.0.2 - Now handles larger/fragmented/compressed volumes/files/dirs.
-
- - Fixed handling of directories when cluster size exceeds index block
- size.
- - Hide DOS only name space directory entries from readdir() but allow
- them in lookup(). This should fix the problem that Linux doesn't
- support directory hard links, while still allowing access to entries
- via their short file name. This also has the benefit of mimicking
- what Windows users are used to, so it is the ideal solution.
- - Implemented sync_page everywhere so no more hangs in D state when
- waiting for a page.
- - Stop using bforget() in favour of brelse().
- - Stop locking buffers unnecessarily.
- - Implemented compressed files (inode->mapping contains uncompressed
- data, raw compressed data is currently bread() into a vmalloc()ed
- memory buffer).
- - Enable compressed directories. (Their index root is marked compressed
- to indicate that new files in that directory should be created
- compressed.)
- - Use vsnprintf rather than vsprintf in the ntfs_error and ntfs_warning
- functions. (Thanks to Will Dyson for pointing this out.)
- - Moved the ntfs_inode and ntfs_volume (the former ntfs_inode_info and
- ntfs_sb_info) out of the common inode and super_block structures and
- started using the generic_ip and generic_sbp pointers instead. This
- makes ntfs entirely private with respect to the kernel tree.
- - Detect compiler version and abort with error message if gcc less than
- 2.96 is used.
- - Fix bug in name comparison function in unistr.c.
- - Implement attribute lists part 1, the infrastructure: search contexts
- and operations, find_external_attr(), lookup_attr()) and make the
- code use the infrastructure.
- - Fix stupid buffer overflow bug that became apparent on larger run
- list containing attributes.
- - Fix bugs in readdir() that became apparent on larger directories.
-
- The driver is now really useful and survives the test
- find . -type f -exec md5sum "{}" \;
- without any error messages on a over 1GiB sized partition with >16k
- files on it, including compressed files and directories and many files
- and directories with attribute lists.
-
-tng-0.0.1 - The first useful version.
-
- - Added ntfs_lookup().
- - Added default upcase generation and handling.
- - Added compile options to be shown on module init.
- - Many bug fixes that were "hidden" before.
- - Update to latest kernel.
- - Added ntfs_readdir().
- - Added file operations for mmap(), read(), open() and llseek(). We just
- use the generic ones. The whole point of going through implementing
- readpage() methods and where possible get_block() call backs is that
- this allows us to make use of the generic high level methods provided
- by the kernel.
-
- The driver is now actually useful! Yey. (-: It undoubtedly has got bugs
- though and it doesn't implement accesssing compressed files yet. Also,
- accessing files with attribute list attributes is not implemented yet
- either. But for small or simple filesystems it should work and allow
- you to list directories, use stat on directory entries and the file
- system, open, read, mmap and llseek around in files. A big mile stone
- has been reached!
-
-tng-0.0.0 - Initial version tag.
-
- Initial driver implementation. The driver can mount and umount simple
- NTFS filesystems (i.e. ones without attribute lists in the system
- files). If the mount fails there might be problems in the error handling
- code paths, so be warned. Otherwise it seems to be loading the system
- files nicely and the mft record read mapping/unmapping seems to be
- working nicely, too. Proof of inode metadata in the page cache and non-
- resident file unnamed stream data in the page cache concepts is thus
- complete.
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index cfce53cb65d..c3c2c7ac902 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -23,6 +23,7 @@
#include <linux/errno.h>
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 50d3b0c258e..f5094ee224c 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -22,6 +22,7 @@
#include <linux/buffer_head.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/writeback.h>
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index 08f7530e934..6551c7cbad9 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -25,6 +25,7 @@
#include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include "attrib.h"
#include "inode.h"
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 5a9e34475e3..fe44d3feee4 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -21,6 +21,7 @@
*/
#include <linux/buffer_head.h>
+#include <linux/slab.h>
#include "dir.h"
#include "aops.h"
@@ -1545,7 +1546,7 @@ static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry,
write_inode_now(bmp_vi, !datasync);
iput(bmp_vi);
}
- ret = ntfs_write_inode(vi, 1);
+ ret = __ntfs_write_inode(vi, 1);
write_inode_now(vi, !datasync);
err = sync_blockdev(vi->i_sb->s_bdev);
if (unlikely(err && !ret))
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 43179ddd336..8804f093ba7 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -20,6 +20,7 @@
*/
#include <linux/buffer_head.h>
+#include <linux/gfp.h>
#include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/sched.h>
@@ -2182,7 +2183,7 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry,
ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
BUG_ON(S_ISDIR(vi->i_mode));
if (!datasync || !NInoNonResident(NTFS_I(vi)))
- ret = ntfs_write_inode(vi, 1);
+ ret = __ntfs_write_inode(vi, 1);
write_inode_now(vi, !datasync);
/*
* NOTE: If we were to use mapping->private_list (see ext2 and
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
index 2194eff4974..096c135691a 100644
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -19,6 +19,8 @@
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/slab.h>
+
#include "aops.h"
#include "collate.h"
#include "debug.h"
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index dc2505abb6d..4b57fb1eac2 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2957,7 +2957,7 @@ out:
*
* Return 0 on success and -errno on error.
*/
-int ntfs_write_inode(struct inode *vi, int sync)
+int __ntfs_write_inode(struct inode *vi, int sync)
{
sle64 nt;
ntfs_inode *ni = NTFS_I(vi);
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h
index 117eaf8032a..9a113544605 100644
--- a/fs/ntfs/inode.h
+++ b/fs/ntfs/inode.h
@@ -307,12 +307,12 @@ extern void ntfs_truncate_vfs(struct inode *vi);
extern int ntfs_setattr(struct dentry *dentry, struct iattr *attr);
-extern int ntfs_write_inode(struct inode *vi, int sync);
+extern int __ntfs_write_inode(struct inode *vi, int sync);
static inline void ntfs_commit_inode(struct inode *vi)
{
if (!is_bad_inode(vi))
- ntfs_write_inode(vi, 1);
+ __ntfs_write_inode(vi, 1);
return;
}
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 1caa0ef0b2b..b572b672718 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -21,6 +21,7 @@
*/
#include <linux/buffer_head.h>
+#include <linux/slab.h>
#include <linux/swap.h>
#include "attrib.h"
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c
index 2ca00153b6e..358273e59ad 100644
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -23,6 +23,7 @@
#include <linux/dcache.h>
#include <linux/exportfs.h>
#include <linux/security.h>
+#include <linux/slab.h>
#include "attrib.h"
#include "debug.h"
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 80b04770e8e..0de1db6cddb 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -31,6 +31,7 @@
#include <linux/vfs.h>
#include <linux/moduleparam.h>
#include <linux/smp_lock.h>
+#include <linux/bitmap.h>
#include "sysctl.h"
#include "logfile.h"
@@ -39,6 +40,7 @@
#include "dir.h"
#include "debug.h"
#include "index.h"
+#include "inode.h"
#include "aops.h"
#include "layout.h"
#include "malloc.h"
@@ -2457,7 +2459,6 @@ static void ntfs_put_super(struct super_block *sb)
static s64 get_nr_free_clusters(ntfs_volume *vol)
{
s64 nr_free = vol->nr_clusters;
- u32 *kaddr;
struct address_space *mapping = vol->lcnbmp_ino->i_mapping;
struct page *page;
pgoff_t index, max_index;
@@ -2476,7 +2477,8 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.",
max_index, PAGE_CACHE_SIZE / 4);
for (index = 0; index < max_index; index++) {
- unsigned int i;
+ unsigned long *kaddr;
+
/*
* Read the page from page cache, getting it from backing store
* if necessary, and increment the use count.
@@ -2489,16 +2491,16 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
nr_free -= PAGE_CACHE_SIZE * 8;
continue;
}
- kaddr = (u32*)kmap_atomic(page, KM_USER0);
+ kaddr = kmap_atomic(page, KM_USER0);
/*
- * For each 4 bytes, subtract the number of set bits. If this
+ * Subtract the number of set bits. If this
* is the last page and it is partial we don't really care as
* it just means we do a little extra work but it won't affect
* the result as all out of range bytes are set to zero by
* ntfs_readpage().
*/
- for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
- nr_free -= (s64)hweight32(kaddr[i]);
+ nr_free -= bitmap_weight(kaddr,
+ PAGE_CACHE_SIZE * BITS_PER_BYTE);
kunmap_atomic(kaddr, KM_USER0);
page_cache_release(page);
}
@@ -2537,7 +2539,6 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
s64 nr_free, const pgoff_t max_index)
{
- u32 *kaddr;
struct address_space *mapping = vol->mftbmp_ino->i_mapping;
struct page *page;
pgoff_t index;
@@ -2547,7 +2548,8 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = "
"0x%lx.", max_index, PAGE_CACHE_SIZE / 4);
for (index = 0; index < max_index; index++) {
- unsigned int i;
+ unsigned long *kaddr;
+
/*
* Read the page from page cache, getting it from backing store
* if necessary, and increment the use count.
@@ -2560,16 +2562,16 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
nr_free -= PAGE_CACHE_SIZE * 8;
continue;
}
- kaddr = (u32*)kmap_atomic(page, KM_USER0);
+ kaddr = kmap_atomic(page, KM_USER0);
/*
- * For each 4 bytes, subtract the number of set bits. If this
+ * Subtract the number of set bits. If this
* is the last page and it is partial we don't really care as
* it just means we do a little extra work but it won't affect
* the result as all out of range bytes are set to zero by
* ntfs_readpage().
*/
- for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
- nr_free -= (s64)hweight32(kaddr[i]);
+ nr_free -= bitmap_weight(kaddr,
+ PAGE_CACHE_SIZE * BITS_PER_BYTE);
kunmap_atomic(kaddr, KM_USER0);
page_cache_release(page);
}
@@ -2662,6 +2664,13 @@ static int ntfs_statfs(struct dentry *dentry, struct kstatfs *sfs)
return 0;
}
+#ifdef NTFS_RW
+static int ntfs_write_inode(struct inode *vi, struct writeback_control *wbc)
+{
+ return __ntfs_write_inode(vi, wbc->sync_mode == WB_SYNC_ALL);
+}
+#endif
+
/**
* The complete super operations.
*/
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index 0501974bedd..e13fc9e8fcd 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/string.h>
#define MLOG_MASK_PREFIX ML_INODE
@@ -30,6 +31,8 @@
#include "alloc.h"
#include "dlmglue.h"
#include "file.h"
+#include "inode.h"
+#include "journal.h"
#include "ocfs2_fs.h"
#include "xattr.h"
@@ -166,6 +169,60 @@ static struct posix_acl *ocfs2_get_acl(struct inode *inode, int type)
}
/*
+ * Helper function to set i_mode in memory and disk. Some call paths
+ * will not have di_bh or a journal handle to pass, in which case it
+ * will create it's own.
+ */
+static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh,
+ handle_t *handle, umode_t new_mode)
+{
+ int ret, commit_handle = 0;
+ struct ocfs2_dinode *di;
+
+ if (di_bh == NULL) {
+ ret = ocfs2_read_inode_block(inode, &di_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ } else
+ get_bh(di_bh);
+
+ if (handle == NULL) {
+ handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb),
+ OCFS2_INODE_UPDATE_CREDITS);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ mlog_errno(ret);
+ goto out_brelse;
+ }
+
+ commit_handle = 1;
+ }
+
+ di = (struct ocfs2_dinode *)di_bh->b_data;
+ ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ inode->i_mode = new_mode;
+ di->i_mode = cpu_to_le16(inode->i_mode);
+
+ ocfs2_journal_dirty(handle, di_bh);
+
+out_commit:
+ if (commit_handle)
+ ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
+out_brelse:
+ brelse(di_bh);
+out:
+ return ret;
+}
+
+/*
* Set the access or default ACL of an inode.
*/
static int ocfs2_set_acl(handle_t *handle,
@@ -193,9 +250,14 @@ static int ocfs2_set_acl(handle_t *handle,
if (ret < 0)
return ret;
else {
- inode->i_mode = mode;
if (ret == 0)
acl = NULL;
+
+ ret = ocfs2_acl_set_mode(inode, di_bh,
+ handle, mode);
+ if (ret)
+ return ret;
+
}
}
break;
@@ -283,6 +345,7 @@ int ocfs2_init_acl(handle_t *handle,
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct posix_acl *acl = NULL;
int ret = 0;
+ mode_t mode;
if (!S_ISLNK(inode->i_mode)) {
if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
@@ -291,12 +354,17 @@ int ocfs2_init_acl(handle_t *handle,
if (IS_ERR(acl))
return PTR_ERR(acl);
}
- if (!acl)
- inode->i_mode &= ~current_umask();
+ if (!acl) {
+ mode = inode->i_mode & ~current_umask();
+ ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
+ if (ret) {
+ mlog_errno(ret);
+ goto cleanup;
+ }
+ }
}
if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
struct posix_acl *clone;
- mode_t mode;
if (S_ISDIR(inode->i_mode)) {
ret = ocfs2_set_acl(handle, inode, di_bh,
@@ -313,7 +381,7 @@ int ocfs2_init_acl(handle_t *handle,
mode = inode->i_mode;
ret = posix_acl_create_masq(clone, &mode);
if (ret >= 0) {
- inode->i_mode = mode;
+ ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
if (ret > 0) {
ret = ocfs2_set_acl(handle, inode,
di_bh, ACL_TYPE_ACCESS,
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 2bbe1ecc08c..9f8bd913c51 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -5713,7 +5713,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
goto out;
}
- vfs_dq_free_space_nodirty(inode,
+ dquot_free_space_nodirty(inode,
ocfs2_clusters_to_bytes(inode->i_sb, len));
ret = ocfs2_remove_extent(handle, et, cpos, len, meta_ac, dealloc);
@@ -6936,7 +6936,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
goto bail;
}
- vfs_dq_free_space_nodirty(inode,
+ dquot_free_space_nodirty(inode,
ocfs2_clusters_to_bytes(osb->sb, clusters_to_del));
spin_lock(&OCFS2_I(inode)->ip_lock);
OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters) -
@@ -7301,11 +7301,10 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
unsigned int page_end;
u64 phys;
- if (vfs_dq_alloc_space_nodirty(inode,
- ocfs2_clusters_to_bytes(osb->sb, 1))) {
- ret = -EDQUOT;
+ ret = dquot_alloc_space_nodirty(inode,
+ ocfs2_clusters_to_bytes(osb->sb, 1));
+ if (ret)
goto out_commit;
- }
did_quota = 1;
ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off,
@@ -7381,7 +7380,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
out_commit:
if (ret < 0 && did_quota)
- vfs_dq_free_space_nodirty(inode,
+ dquot_free_space_nodirty(inode,
ocfs2_clusters_to_bytes(osb->sb, 1));
ocfs2_commit_trans(osb, handle);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 4c2a6d282c4..21441ddb550 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1764,10 +1764,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
wc->w_handle = handle;
- if (clusters_to_alloc && vfs_dq_alloc_space_nodirty(inode,
- ocfs2_clusters_to_bytes(osb->sb, clusters_to_alloc))) {
- ret = -EDQUOT;
- goto out_commit;
+ if (clusters_to_alloc) {
+ ret = dquot_alloc_space_nodirty(inode,
+ ocfs2_clusters_to_bytes(osb->sb, clusters_to_alloc));
+ if (ret)
+ goto out_commit;
}
/*
* We don't want this to fail in ocfs2_write_end(), so do it
@@ -1810,7 +1811,7 @@ success:
return 0;
out_quota:
if (clusters_to_alloc)
- vfs_dq_free_space(inode,
+ dquot_free_space(inode,
ocfs2_clusters_to_bytes(osb->sb, clusters_to_alloc));
out_commit:
ocfs2_commit_trans(osb, handle);
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c
index 21c808f752d..ecebb227679 100644
--- a/fs/ocfs2/buffer_head_io.c
+++ b/fs/ocfs2/buffer_head_io.c
@@ -25,7 +25,6 @@
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#include <cluster/masklog.h>
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 5c989000670..41d5f1f92d5 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -34,6 +34,7 @@
#include <linux/crc32.h>
#include <linux/time.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include "heartbeat.h"
#include "tcp.h"
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index b39da877b12..3bb928a2bf7 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -136,7 +136,7 @@ static ssize_t mlog_store(struct kobject *obj, struct attribute *attr,
return mlog_mask_store(mlog_attr->mask, buf, count);
}
-static struct sysfs_ops mlog_attr_ops = {
+static const struct sysfs_ops mlog_attr_ops = {
.show = mlog_show,
.store = mlog_store,
};
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index c81142e3ef8..ed0c9f367fe 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -19,6 +19,7 @@
* Boston, MA 021110-1307, USA.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/configfs.h>
diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c
index 639024033fc..cf3e1669621 100644
--- a/fs/ocfs2/cluster/quorum.c
+++ b/fs/ocfs2/cluster/quorum.c
@@ -44,7 +44,6 @@
* and if they're the last, they fire off the decision.
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/reboot.h>
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index d8d0c65ac03..73e743eea2c 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -72,9 +72,9 @@
#include "tcp_internal.h"
-#define SC_NODEF_FMT "node %s (num %u) at %u.%u.%u.%u:%u"
+#define SC_NODEF_FMT "node %s (num %u) at %pI4:%u"
#define SC_NODEF_ARGS(sc) sc->sc_node->nd_name, sc->sc_node->nd_num, \
- NIPQUAD(sc->sc_node->nd_ipv4_address), \
+ &sc->sc_node->nd_ipv4_address, \
ntohs(sc->sc_node->nd_ipv4_port)
/*
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 765d66c7098..efd77d071c8 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -2964,12 +2964,10 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
goto out;
}
- if (vfs_dq_alloc_space_nodirty(dir,
- ocfs2_clusters_to_bytes(osb->sb,
- alloc + dx_alloc))) {
- ret = -EDQUOT;
+ ret = dquot_alloc_space_nodirty(dir,
+ ocfs2_clusters_to_bytes(osb->sb, alloc + dx_alloc));
+ if (ret)
goto out_commit;
- }
did_quota = 1;
if (ocfs2_supports_indexed_dirs(osb) && !dx_inline) {
@@ -3178,7 +3176,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
out_commit:
if (ret < 0 && did_quota)
- vfs_dq_free_space_nodirty(dir, bytes_allocated);
+ dquot_free_space_nodirty(dir, bytes_allocated);
ocfs2_commit_trans(osb, handle);
@@ -3221,11 +3219,10 @@ static int ocfs2_do_extend_dir(struct super_block *sb,
if (extend) {
u32 offset = OCFS2_I(dir)->ip_clusters;
- if (vfs_dq_alloc_space_nodirty(dir,
- ocfs2_clusters_to_bytes(sb, 1))) {
- status = -EDQUOT;
+ status = dquot_alloc_space_nodirty(dir,
+ ocfs2_clusters_to_bytes(sb, 1));
+ if (status)
goto bail;
- }
did_quota = 1;
status = ocfs2_add_inode_data(OCFS2_SB(sb), dir, &offset,
@@ -3254,7 +3251,7 @@ static int ocfs2_do_extend_dir(struct super_block *sb,
status = 0;
bail:
if (did_quota && status < 0)
- vfs_dq_free_space_nodirty(dir, ocfs2_clusters_to_bytes(sb, 1));
+ dquot_free_space_nodirty(dir, ocfs2_clusters_to_bytes(sb, 1));
mlog_exit(status);
return status;
}
@@ -3889,11 +3886,10 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir,
goto out;
}
- if (vfs_dq_alloc_space_nodirty(dir,
- ocfs2_clusters_to_bytes(dir->i_sb, 1))) {
- ret = -EDQUOT;
+ ret = dquot_alloc_space_nodirty(dir,
+ ocfs2_clusters_to_bytes(dir->i_sb, 1));
+ if (ret)
goto out_commit;
- }
did_quota = 1;
ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), dx_leaf_bh,
@@ -3983,7 +3979,7 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir,
out_commit:
if (ret < 0 && did_quota)
- vfs_dq_free_space_nodirty(dir,
+ dquot_free_space_nodirty(dir,
ocfs2_clusters_to_bytes(dir->i_sb, 1));
ocfs2_commit_trans(osb, handle);
@@ -4165,11 +4161,10 @@ static int ocfs2_expand_inline_dx_root(struct inode *dir,
goto out;
}
- if (vfs_dq_alloc_space_nodirty(dir,
- ocfs2_clusters_to_bytes(osb->sb, 1))) {
- ret = -EDQUOT;
+ ret = dquot_alloc_space_nodirty(dir,
+ ocfs2_clusters_to_bytes(osb->sb, 1));
+ if (ret)
goto out_commit;
- }
did_quota = 1;
/*
@@ -4229,7 +4224,7 @@ static int ocfs2_expand_inline_dx_root(struct inode *dir,
out_commit:
if (ret < 0 && did_quota)
- vfs_dq_free_space_nodirty(dir,
+ dquot_free_space_nodirty(dir,
ocfs2_clusters_to_bytes(dir->i_sb, 1));
ocfs2_commit_trans(osb, handle);
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c
index dccc439fa08..a795eb91f4e 100644
--- a/fs/ocfs2/dlm/dlmast.c
+++ b/fs/ocfs2/dlm/dlmast.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/sysctl.h>
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c
index f283bce776b..90803b47cd8 100644
--- a/fs/ocfs2/dlm/dlmconvert.c
+++ b/fs/ocfs2/dlm/dlmconvert.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/sysctl.h>
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index a659606dcb9..9289b4357d2 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -1875,7 +1875,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
ok:
spin_unlock(&res->spinlock);
}
- spin_unlock(&dlm->spinlock);
// mlog(0, "woo! got an assert_master from node %u!\n",
// assert->node_idx);
@@ -1926,7 +1925,6 @@ ok:
/* master is known, detach if not already detached.
* ensures that only one assert_master call will happen
* on this mle. */
- spin_lock(&dlm->spinlock);
spin_lock(&dlm->master_lock);
rr = atomic_read(&mle->mle_refs.refcount);
@@ -1959,7 +1957,6 @@ ok:
__dlm_put_mle(mle);
}
spin_unlock(&dlm->master_lock);
- spin_unlock(&dlm->spinlock);
} else if (res) {
if (res->owner != assert->node_idx) {
mlog(0, "assert_master from %u, but current "
@@ -1967,6 +1964,7 @@ ok:
res->owner, namelen, name);
}
}
+ spin_unlock(&dlm->spinlock);
done:
ret = 0;
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c
index 52ec020ea78..11a6d1fd1d3 100644
--- a/fs/ocfs2/dlm/dlmthread.c
+++ b/fs/ocfs2/dlm/dlmthread.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/sysctl.h>
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c
index 49e29ecd020..b47c1b92b82 100644
--- a/fs/ocfs2/dlm/dlmunlock.c
+++ b/fs/ocfs2/dlm/dlmunlock.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/sysctl.h>
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 8298608d416..50c4ee805da 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -1881,7 +1881,7 @@ out:
* ocfs2_file_lock() and ocfs2_file_unlock() map to a single pair of
* flock() calls. The locking approach this requires is sufficiently
* different from all other cluster lock types that we implement a
- * seperate path to the "low-level" dlm calls. In particular:
+ * separate path to the "low-level" dlm calls. In particular:
*
* - No optimization of lock levels is done - we take at exactly
* what's been requested.
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index 5328529e7fd..09e3fdfa6d3 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -24,6 +24,7 @@
#include <linux/fs.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/fiemap.h>
@@ -453,7 +454,7 @@ static int ocfs2_get_clusters_nocache(struct inode *inode,
if (i == -1) {
/*
* Holes can be larger than the maximum size of an
- * extent, so we return their lengths in a seperate
+ * extent, so we return their lengths in a separate
* field.
*/
if (hole_len) {
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 5b52547d629..17947dc8341 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -107,6 +107,9 @@ static int ocfs2_file_open(struct inode *inode, struct file *file)
mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file,
file->f_path.dentry->d_name.len, file->f_path.dentry->d_name.name);
+ if (file->f_mode & FMODE_WRITE)
+ dquot_initialize(inode);
+
spin_lock(&oi->ip_lock);
/* Check that the inode hasn't been wiped from disk by another
@@ -629,11 +632,10 @@ restart_all:
}
restarted_transaction:
- if (vfs_dq_alloc_space_nodirty(inode, ocfs2_clusters_to_bytes(osb->sb,
- clusters_to_add))) {
- status = -EDQUOT;
+ status = dquot_alloc_space_nodirty(inode,
+ ocfs2_clusters_to_bytes(osb->sb, clusters_to_add));
+ if (status)
goto leave;
- }
did_quota = 1;
/* reserve a write to the file entry early on - that we if we
@@ -674,7 +676,7 @@ restarted_transaction:
clusters_to_add -= (OCFS2_I(inode)->ip_clusters - prev_clusters);
spin_unlock(&OCFS2_I(inode)->ip_lock);
/* Release unused quota reservation */
- vfs_dq_free_space(inode,
+ dquot_free_space(inode,
ocfs2_clusters_to_bytes(osb->sb, clusters_to_add));
did_quota = 0;
@@ -710,7 +712,7 @@ restarted_transaction:
leave:
if (status < 0 && did_quota)
- vfs_dq_free_space(inode,
+ dquot_free_space(inode,
ocfs2_clusters_to_bytes(osb->sb, clusters_to_add));
if (handle) {
ocfs2_commit_trans(osb, handle);
@@ -978,6 +980,8 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE;
if (size_change) {
+ dquot_initialize(inode);
+
status = ocfs2_rw_lock(inode, 1);
if (status < 0) {
mlog_errno(status);
@@ -1020,7 +1024,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
/*
* Gather pointers to quota structures so that allocation /
* freeing of quota structures happens here and not inside
- * vfs_dq_transfer() where we have problems with lock ordering
+ * dquot_transfer() where we have problems with lock ordering
*/
if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid
&& OCFS2_HAS_RO_COMPAT_FEATURE(sb,
@@ -1053,7 +1057,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
mlog_errno(status);
goto bail_unlock;
}
- status = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+ status = dquot_transfer(inode, attr);
if (status < 0)
goto bail_commit;
} else {
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c
index c6e7213db86..1aa863dd901 100644
--- a/fs/ocfs2/heartbeat.c
+++ b/fs/ocfs2/heartbeat.c
@@ -26,7 +26,6 @@
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#define MLOG_MASK_PREFIX ML_SUPER
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 88459bdd1ff..07cc8bb68b6 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -25,7 +25,6 @@
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
@@ -665,7 +664,7 @@ static int ocfs2_remove_inode(struct inode *inode,
}
ocfs2_remove_from_cache(INODE_CACHE(inode), di_bh);
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
status = ocfs2_free_dinode(handle, inode_alloc_inode,
inode_alloc_bh, di);
@@ -891,6 +890,21 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
/* Do some basic inode verification... */
di = (struct ocfs2_dinode *) di_bh->b_data;
if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) {
+ /*
+ * Inodes in the orphan dir must have ORPHANED_FL. The only
+ * inodes that come back out of the orphan dir are reflink
+ * targets. A reflink target may be moved out of the orphan
+ * dir between the time we scan the directory and the time we
+ * process it. This would lead to HAS_REFCOUNT_FL being set but
+ * ORPHANED_FL not.
+ */
+ if (di->i_dyn_features & cpu_to_le16(OCFS2_HAS_REFCOUNT_FL)) {
+ mlog(0, "Reflinked inode %llu is no longer orphaned. "
+ "it shouldn't be deleted\n",
+ (unsigned long long)oi->ip_blkno);
+ goto bail;
+ }
+
/* for lack of a better error? */
status = -EEXIST;
mlog(ML_ERROR,
@@ -971,6 +985,8 @@ void ocfs2_delete_inode(struct inode *inode)
goto bail;
}
+ dquot_initialize(inode);
+
if (!ocfs2_inode_is_valid_to_delete(inode)) {
/* It's probably not necessary to truncate_inode_pages
* here but we do it for safety anyway (it will most
@@ -1087,6 +1103,8 @@ void ocfs2_clear_inode(struct inode *inode)
mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
"Inode=%lu\n", inode->i_ino);
+ dquot_drop(inode);
+
/* To preven remote deletes we hold open lock before, now it
* is time to unlock PR and EX open locks. */
ocfs2_open_unlock(inode);
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index ca992d91f51..c983715d8d8 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -872,8 +872,10 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
(unsigned long long)la_start_blk,
(unsigned long long)blkno);
- status = ocfs2_free_clusters(handle, main_bm_inode,
- main_bm_bh, blkno, count);
+ status = ocfs2_release_clusters(handle,
+ main_bm_inode,
+ main_bm_bh, blkno,
+ count);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -984,8 +986,7 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
}
retry_enospc:
- (*ac)->ac_bits_wanted = osb->local_alloc_bits;
-
+ (*ac)->ac_bits_wanted = osb->local_alloc_default_bits;
status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
if (status == -ENOSPC) {
if (ocfs2_recalc_la_window(osb, OCFS2_LA_EVENT_ENOSPC) ==
@@ -1061,6 +1062,7 @@ retry_enospc:
OCFS2_LA_DISABLED)
goto bail;
+ ac->ac_bits_wanted = osb->local_alloc_default_bits;
status = ocfs2_claim_clusters(osb, handle, ac,
osb->local_alloc_bits,
&cluster_off,
diff --git a/fs/ocfs2/locks.c b/fs/ocfs2/locks.c
index 544ac624517..b5cb3ede940 100644
--- a/fs/ocfs2/locks.c
+++ b/fs/ocfs2/locks.c
@@ -133,7 +133,7 @@ int ocfs2_lock(struct file *file, int cmd, struct file_lock *fl)
if (!(fl->fl_flags & FL_POSIX))
return -ENOLCK;
- if (__mandatory_lock(inode))
+ if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
return -ENOLCK;
return ocfs2_plock(osb->cconn, OCFS2_I(inode)->ip_blkno, file, cmd, fl);
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 39737613424..7898bd3a99f 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -25,7 +25,6 @@
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/uio.h>
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 50fb26a6a5f..b1eb50ae409 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -84,7 +84,7 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
static int ocfs2_orphan_add(struct ocfs2_super *osb,
handle_t *handle,
struct inode *inode,
- struct ocfs2_dinode *fe,
+ struct buffer_head *fe_bh,
char *name,
struct ocfs2_dir_lookup_result *lookup,
struct inode *orphan_dir_inode);
@@ -212,7 +212,7 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode)
} else
inode->i_gid = current_fsgid();
inode->i_mode = mode;
- vfs_dq_init(inode);
+ dquot_initialize(inode);
return inode;
}
@@ -244,6 +244,8 @@ static int ocfs2_mknod(struct inode *dir,
(unsigned long)dev, dentry->d_name.len,
dentry->d_name.name);
+ dquot_initialize(dir);
+
/* get our super block */
osb = OCFS2_SB(dir->i_sb);
@@ -348,13 +350,9 @@ static int ocfs2_mknod(struct inode *dir,
goto leave;
}
- /* We don't use standard VFS wrapper because we don't want vfs_dq_init
- * to be called. */
- if (sb_any_quota_active(osb->sb) &&
- osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) {
- status = -EDQUOT;
+ status = dquot_alloc_inode(inode);
+ if (status)
goto leave;
- }
did_quota_inode = 1;
mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
@@ -431,7 +429,7 @@ static int ocfs2_mknod(struct inode *dir,
status = 0;
leave:
if (status < 0 && did_quota_inode)
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
if (handle)
ocfs2_commit_trans(osb, handle);
@@ -636,6 +634,8 @@ static int ocfs2_link(struct dentry *old_dentry,
if (S_ISDIR(inode->i_mode))
return -EPERM;
+ dquot_initialize(dir);
+
err = ocfs2_inode_lock_nested(dir, &parent_fe_bh, 1, OI_LS_PARENT);
if (err < 0) {
if (err != -ENOENT)
@@ -791,6 +791,8 @@ static int ocfs2_unlink(struct inode *dir,
mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry,
dentry->d_name.len, dentry->d_name.name);
+ dquot_initialize(dir);
+
BUG_ON(dentry->d_parent->d_inode != dir);
mlog(0, "ino = %llu\n", (unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -877,7 +879,7 @@ static int ocfs2_unlink(struct inode *dir,
fe = (struct ocfs2_dinode *) fe_bh->b_data;
if (inode_is_unlinkable(inode)) {
- status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
+ status = ocfs2_orphan_add(osb, handle, inode, fe_bh, orphan_name,
&orphan_insert, orphan_dir);
if (status < 0) {
mlog_errno(status);
@@ -1051,6 +1053,9 @@ static int ocfs2_rename(struct inode *old_dir,
old_dentry->d_name.len, old_dentry->d_name.name,
new_dentry->d_name.len, new_dentry->d_name.name);
+ dquot_initialize(old_dir);
+ dquot_initialize(new_dir);
+
osb = OCFS2_SB(old_dir->i_sb);
if (new_inode) {
@@ -1295,7 +1300,7 @@ static int ocfs2_rename(struct inode *old_dir,
if (S_ISDIR(new_inode->i_mode) ||
(ocfs2_read_links_count(newfe) == 1)) {
status = ocfs2_orphan_add(osb, handle, new_inode,
- newfe, orphan_name,
+ newfe_bh, orphan_name,
&orphan_insert, orphan_dir);
if (status < 0) {
mlog_errno(status);
@@ -1599,6 +1604,8 @@ static int ocfs2_symlink(struct inode *dir,
mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir,
dentry, symname, dentry->d_name.len, dentry->d_name.name);
+ dquot_initialize(dir);
+
sb = dir->i_sb;
osb = OCFS2_SB(sb);
@@ -1688,13 +1695,9 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
}
- /* We don't use standard VFS wrapper because we don't want vfs_dq_init
- * to be called. */
- if (sb_any_quota_active(osb->sb) &&
- osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) {
- status = -EDQUOT;
+ status = dquot_alloc_inode(inode);
+ if (status)
goto bail;
- }
did_quota_inode = 1;
mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry,
@@ -1716,11 +1719,10 @@ static int ocfs2_symlink(struct inode *dir,
u32 offset = 0;
inode->i_op = &ocfs2_symlink_inode_operations;
- if (vfs_dq_alloc_space_nodirty(inode,
- ocfs2_clusters_to_bytes(osb->sb, 1))) {
- status = -EDQUOT;
+ status = dquot_alloc_space_nodirty(inode,
+ ocfs2_clusters_to_bytes(osb->sb, 1));
+ if (status)
goto bail;
- }
did_quota = 1;
status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0,
new_fe_bh,
@@ -1788,10 +1790,10 @@ static int ocfs2_symlink(struct inode *dir,
d_instantiate(dentry, inode);
bail:
if (status < 0 && did_quota)
- vfs_dq_free_space_nodirty(inode,
+ dquot_free_space_nodirty(inode,
ocfs2_clusters_to_bytes(osb->sb, 1));
if (status < 0 && did_quota_inode)
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
if (handle)
ocfs2_commit_trans(osb, handle);
@@ -1909,7 +1911,7 @@ leave:
static int ocfs2_orphan_add(struct ocfs2_super *osb,
handle_t *handle,
struct inode *inode,
- struct ocfs2_dinode *fe,
+ struct buffer_head *fe_bh,
char *name,
struct ocfs2_dir_lookup_result *lookup,
struct inode *orphan_dir_inode)
@@ -1917,6 +1919,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
struct buffer_head *orphan_dir_bh = NULL;
int status = 0;
struct ocfs2_dinode *orphan_fe;
+ struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
@@ -1957,6 +1960,21 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
goto leave;
}
+ /*
+ * We're going to journal the change of i_flags and i_orphaned_slot.
+ * It's safe anyway, though some callers may duplicate the journaling.
+ * Journaling within the func just make the logic look more
+ * straightforward.
+ */
+ status = ocfs2_journal_access_di(handle,
+ INODE_CACHE(inode),
+ fe_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (status < 0) {
+ mlog_errno(status);
+ goto leave;
+ }
+
le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL);
/* Record which orphan dir our inode now resides
@@ -1964,6 +1982,8 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
* dir to lock. */
fe->i_orphaned_slot = cpu_to_le16(osb->slot_num);
+ ocfs2_journal_dirty(handle, fe_bh);
+
mlog(0, "Inode %llu orphaned in slot %d\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num);
@@ -2099,13 +2119,9 @@ int ocfs2_create_inode_in_orphan(struct inode *dir,
goto leave;
}
- /* We don't use standard VFS wrapper because we don't want vfs_dq_init
- * to be called. */
- if (sb_any_quota_active(osb->sb) &&
- osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) {
- status = -EDQUOT;
+ status = dquot_alloc_inode(inode);
+ if (status)
goto leave;
- }
did_quota_inode = 1;
inode->i_nlink = 0;
@@ -2125,7 +2141,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir,
}
di = (struct ocfs2_dinode *)new_di_bh->b_data;
- status = ocfs2_orphan_add(osb, handle, inode, di, orphan_name,
+ status = ocfs2_orphan_add(osb, handle, inode, new_di_bh, orphan_name,
&orphan_insert, orphan_dir);
if (status < 0) {
mlog_errno(status);
@@ -2140,7 +2156,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir,
insert_inode_hash(inode);
leave:
if (status < 0 && did_quota_inode)
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
if (handle)
ocfs2_commit_trans(osb, handle);
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 1238b491db9..adf5e2ebc2c 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -763,8 +763,18 @@ static inline unsigned int ocfs2_megabytes_to_clusters(struct super_block *sb,
return megs << (20 - OCFS2_SB(sb)->s_clustersize_bits);
}
-#define ocfs2_set_bit ext2_set_bit
-#define ocfs2_clear_bit ext2_clear_bit
+static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap)
+{
+ ext2_set_bit(bit, bitmap);
+}
+#define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr))
+
+static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap)
+{
+ ext2_clear_bit(bit, bitmap);
+}
+#define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr))
+
#define ocfs2_test_bit ext2_test_bit
#define ocfs2_find_next_zero_bit ext2_find_next_zero_bit
#define ocfs2_find_next_bit ext2_find_next_bit
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index b437dc0c4ca..ab42a74c753 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -3,6 +3,7 @@
*/
#include <linux/spinlock.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/quota.h>
#include <linux/quotaops.h>
#include <linux/dqblk_qtree.h>
@@ -851,13 +852,6 @@ static void ocfs2_destroy_dquot(struct dquot *dquot)
}
const struct dquot_operations ocfs2_quota_operations = {
- .initialize = dquot_initialize,
- .drop = dquot_drop,
- .alloc_space = dquot_alloc_space,
- .alloc_inode = dquot_alloc_inode,
- .free_space = dquot_free_space,
- .free_inode = dquot_free_inode,
- .transfer = dquot_transfer,
.write_dquot = ocfs2_write_dquot,
.acquire_dquot = ocfs2_acquire_dquot,
.release_dquot = ocfs2_release_dquot,
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 21f9e71223c..9ad49305f45 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -3,6 +3,7 @@
*/
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/quota.h>
#include <linux/quotaops.h>
#include <linux/module.h>
@@ -457,7 +458,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
break;
}
dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
- for_each_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) {
+ for_each_set_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) {
qbh = NULL;
status = ocfs2_read_quota_block(lqinode,
ol_dqblk_block(sb, chunk, bit),
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index fb6aa7acf54..bd96f6c7877 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -37,7 +37,6 @@
#include <linux/bio.h>
#include <linux/blkdev.h>
-#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/writeback.h>
#include <linux/pagevec.h>
@@ -4075,6 +4074,7 @@ static int ocfs2_complete_reflink(struct inode *s_inode,
OCFS2_I(t_inode)->ip_dyn_features = OCFS2_I(s_inode)->ip_dyn_features;
spin_unlock(&OCFS2_I(t_inode)->ip_lock);
i_size_write(t_inode, size);
+ t_inode->i_blocks = s_inode->i_blocks;
di->i_xattr_inline_size = s_di->i_xattr_inline_size;
di->i_clusters = s_di->i_clusters;
@@ -4390,7 +4390,7 @@ static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir,
}
mutex_lock(&inode->i_mutex);
- vfs_dq_init(dir);
+ dquot_initialize(dir);
error = ocfs2_reflink(old_dentry, dir, new_dentry, preserve);
mutex_unlock(&inode->i_mutex);
if (!error)
diff --git a/fs/ocfs2/stack_o2cb.c b/fs/ocfs2/stack_o2cb.c
index 7020e1253ff..0d3049f696c 100644
--- a/fs/ocfs2/stack_o2cb.c
+++ b/fs/ocfs2/stack_o2cb.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include <linux/module.h>
/* Needed for AOP_TRUNCATED_PAGE in mlog_errno() */
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c
index 5ae8812b286..2dc57bca068 100644
--- a/fs/ocfs2/stack_user.c
+++ b/fs/ocfs2/stack_user.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/reboot.h>
#include <asm/uaccess.h>
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index c3c60bc3e07..19ba00f2854 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -95,13 +95,6 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle,
struct buffer_head *group_bh,
unsigned int bit_off,
unsigned int num_bits);
-static inline int ocfs2_block_group_clear_bits(handle_t *handle,
- struct inode *alloc_inode,
- struct ocfs2_group_desc *bg,
- struct buffer_head *group_bh,
- unsigned int bit_off,
- unsigned int num_bits);
-
static int ocfs2_relink_block_group(handle_t *handle,
struct inode *alloc_inode,
struct buffer_head *fe_bh,
@@ -152,7 +145,7 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl)
#define do_error(fmt, ...) \
do{ \
- if (clean_error) \
+ if (resize) \
mlog(ML_ERROR, fmt "\n", ##__VA_ARGS__); \
else \
ocfs2_error(sb, fmt, ##__VA_ARGS__); \
@@ -160,7 +153,7 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl)
static int ocfs2_validate_gd_self(struct super_block *sb,
struct buffer_head *bh,
- int clean_error)
+ int resize)
{
struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
@@ -211,7 +204,7 @@ static int ocfs2_validate_gd_self(struct super_block *sb,
static int ocfs2_validate_gd_parent(struct super_block *sb,
struct ocfs2_dinode *di,
struct buffer_head *bh,
- int clean_error)
+ int resize)
{
unsigned int max_bits;
struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
@@ -233,8 +226,11 @@ static int ocfs2_validate_gd_parent(struct super_block *sb,
return -EINVAL;
}
- if (le16_to_cpu(gd->bg_chain) >=
- le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) {
+ /* In resize, we may meet the case bg_chain == cl_next_free_rec. */
+ if ((le16_to_cpu(gd->bg_chain) >
+ le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) ||
+ ((le16_to_cpu(gd->bg_chain) ==
+ le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) && !resize)) {
do_error("Group descriptor #%llu has bad chain %u",
(unsigned long long)bh->b_blocknr,
le16_to_cpu(gd->bg_chain));
@@ -1975,18 +1971,18 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
bits_wanted, cluster_start, num_clusters);
}
-static inline int ocfs2_block_group_clear_bits(handle_t *handle,
- struct inode *alloc_inode,
- struct ocfs2_group_desc *bg,
- struct buffer_head *group_bh,
- unsigned int bit_off,
- unsigned int num_bits)
+static int ocfs2_block_group_clear_bits(handle_t *handle,
+ struct inode *alloc_inode,
+ struct ocfs2_group_desc *bg,
+ struct buffer_head *group_bh,
+ unsigned int bit_off,
+ unsigned int num_bits,
+ void (*undo_fn)(unsigned int bit,
+ unsigned long *bmap))
{
int status;
unsigned int tmp;
- int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;
struct ocfs2_group_desc *undo_bg = NULL;
- int cluster_bitmap = 0;
mlog_entry_void();
@@ -1996,20 +1992,18 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
mlog(0, "off = %u, num = %u\n", bit_off, num_bits);
- if (ocfs2_is_cluster_bitmap(alloc_inode))
- journal_type = OCFS2_JOURNAL_ACCESS_UNDO;
-
+ BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode));
status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode),
- group_bh, journal_type);
+ group_bh,
+ undo_fn ?
+ OCFS2_JOURNAL_ACCESS_UNDO :
+ OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto bail;
}
- if (ocfs2_is_cluster_bitmap(alloc_inode))
- cluster_bitmap = 1;
-
- if (cluster_bitmap) {
+ if (undo_fn) {
jbd_lock_bh_state(group_bh);
undo_bg = (struct ocfs2_group_desc *)
bh2jh(group_bh)->b_committed_data;
@@ -2020,13 +2014,13 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
while(tmp--) {
ocfs2_clear_bit((bit_off + tmp),
(unsigned long *) bg->bg_bitmap);
- if (cluster_bitmap)
- ocfs2_set_bit(bit_off + tmp,
- (unsigned long *) undo_bg->bg_bitmap);
+ if (undo_fn)
+ undo_fn(bit_off + tmp,
+ (unsigned long *) undo_bg->bg_bitmap);
}
le16_add_cpu(&bg->bg_free_bits_count, num_bits);
- if (cluster_bitmap)
+ if (undo_fn)
jbd_unlock_bh_state(group_bh);
status = ocfs2_journal_dirty(handle, group_bh);
@@ -2039,12 +2033,14 @@ bail:
/*
* expects the suballoc inode to already be locked.
*/
-int ocfs2_free_suballoc_bits(handle_t *handle,
- struct inode *alloc_inode,
- struct buffer_head *alloc_bh,
- unsigned int start_bit,
- u64 bg_blkno,
- unsigned int count)
+static int _ocfs2_free_suballoc_bits(handle_t *handle,
+ struct inode *alloc_inode,
+ struct buffer_head *alloc_bh,
+ unsigned int start_bit,
+ u64 bg_blkno,
+ unsigned int count,
+ void (*undo_fn)(unsigned int bit,
+ unsigned long *bitmap))
{
int status = 0;
u32 tmp_used;
@@ -2079,7 +2075,7 @@ int ocfs2_free_suballoc_bits(handle_t *handle,
status = ocfs2_block_group_clear_bits(handle, alloc_inode,
group, group_bh,
- start_bit, count);
+ start_bit, count, undo_fn);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -2110,6 +2106,17 @@ bail:
return status;
}
+int ocfs2_free_suballoc_bits(handle_t *handle,
+ struct inode *alloc_inode,
+ struct buffer_head *alloc_bh,
+ unsigned int start_bit,
+ u64 bg_blkno,
+ unsigned int count)
+{
+ return _ocfs2_free_suballoc_bits(handle, alloc_inode, alloc_bh,
+ start_bit, bg_blkno, count, NULL);
+}
+
int ocfs2_free_dinode(handle_t *handle,
struct inode *inode_alloc_inode,
struct buffer_head *inode_alloc_bh,
@@ -2123,11 +2130,13 @@ int ocfs2_free_dinode(handle_t *handle,
inode_alloc_bh, bit, bg_blkno, 1);
}
-int ocfs2_free_clusters(handle_t *handle,
- struct inode *bitmap_inode,
- struct buffer_head *bitmap_bh,
- u64 start_blk,
- unsigned int num_clusters)
+static int _ocfs2_free_clusters(handle_t *handle,
+ struct inode *bitmap_inode,
+ struct buffer_head *bitmap_bh,
+ u64 start_blk,
+ unsigned int num_clusters,
+ void (*undo_fn)(unsigned int bit,
+ unsigned long *bitmap))
{
int status;
u16 bg_start_bit;
@@ -2154,9 +2163,9 @@ int ocfs2_free_clusters(handle_t *handle,
mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n",
(unsigned long long)bg_blkno, bg_start_bit);
- status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,
- bg_start_bit, bg_blkno,
- num_clusters);
+ status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,
+ bg_start_bit, bg_blkno,
+ num_clusters, undo_fn);
if (status < 0) {
mlog_errno(status);
goto out;
@@ -2170,6 +2179,32 @@ out:
return status;
}
+int ocfs2_free_clusters(handle_t *handle,
+ struct inode *bitmap_inode,
+ struct buffer_head *bitmap_bh,
+ u64 start_blk,
+ unsigned int num_clusters)
+{
+ return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh,
+ start_blk, num_clusters,
+ _ocfs2_set_bit);
+}
+
+/*
+ * Give never-used clusters back to the global bitmap. We don't need
+ * to protect these bits in the undo buffer.
+ */
+int ocfs2_release_clusters(handle_t *handle,
+ struct inode *bitmap_inode,
+ struct buffer_head *bitmap_bh,
+ u64 start_blk,
+ unsigned int num_clusters)
+{
+ return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh,
+ start_blk, num_clusters,
+ _ocfs2_clear_bit);
+}
+
static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg)
{
printk("Block Group:\n");
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index fa60723c43e..e0f46df357e 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -127,6 +127,11 @@ int ocfs2_free_clusters(handle_t *handle,
struct buffer_head *bitmap_bh,
u64 start_blk,
unsigned int num_clusters);
+int ocfs2_release_clusters(handle_t *handle,
+ struct inode *bitmap_inode,
+ struct buffer_head *bitmap_bh,
+ u64 start_blk,
+ unsigned int num_clusters);
static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit)
{
diff --git a/fs/ocfs2/sysfile.c b/fs/ocfs2/sysfile.c
index 40e53702948..bfe7190cdbf 100644
--- a/fs/ocfs2/sysfile.c
+++ b/fs/ocfs2/sysfile.c
@@ -25,7 +25,6 @@
#include <linux/fs.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/highmem.h>
#define MLOG_MASK_PREFIX ML_INODE
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index d1b0d386f6d..3e7773089b9 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -1622,7 +1622,7 @@ static void ocfs2_xa_block_wipe_namevalue(struct ocfs2_xa_loc *loc)
/* Now tell xh->xh_entries about it */
for (i = 0; i < count; i++) {
offset = le16_to_cpu(xh->xh_entries[i].xe_name_offset);
- if (offset < namevalue_offset)
+ if (offset <= namevalue_offset)
le16_add_cpu(&xh->xh_entries[i].xe_name_offset,
namevalue_size);
}
@@ -6528,13 +6528,11 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
int indexed)
{
int ret;
- struct ocfs2_alloc_context *meta_ac;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- struct ocfs2_xattr_set_ctxt ctxt = {
- .meta_ac = meta_ac,
- };
+ struct ocfs2_xattr_set_ctxt ctxt;
- ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
+ memset(&ctxt, 0, sizeof(ctxt));
+ ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &ctxt.meta_ac);
if (ret < 0) {
mlog_errno(ret);
return ret;
@@ -6556,7 +6554,7 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
ocfs2_commit_trans(osb, ctxt.handle);
out:
- ocfs2_free_alloc_context(meta_ac);
+ ocfs2_free_alloc_context(ctxt.meta_ac);
return ret;
}
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c
index f3b7c1541f3..c82af6acc2e 100644
--- a/fs/omfs/inode.c
+++ b/fs/omfs/inode.c
@@ -6,11 +6,13 @@
#include <linux/version.h>
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/vfs.h>
#include <linux/parser.h>
#include <linux/buffer_head.h>
#include <linux/vmalloc.h>
+#include <linux/writeback.h>
#include <linux/crc-itu-t.h>
#include "omfs.h"
@@ -89,7 +91,7 @@ static void omfs_update_checksums(struct omfs_inode *oi)
oi->i_head.h_check_xor = xor;
}
-static int omfs_write_inode(struct inode *inode, int wait)
+static int __omfs_write_inode(struct inode *inode, int wait)
{
struct omfs_inode *oi;
struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
@@ -162,9 +164,14 @@ out:
return ret;
}
+static int omfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ return __omfs_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
+}
+
int omfs_sync_inode(struct inode *inode)
{
- return omfs_write_inode(inode, 1);
+ return __omfs_write_inode(inode, 1);
}
/*
diff --git a/fs/open.c b/fs/open.c
index e0b2d88b038..74e5cd9f718 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -8,10 +8,8 @@
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/fdtable.h>
-#include <linux/quotaops.h>
#include <linux/fsnotify.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/namei.h>
#include <linux/backing-dev.h>
@@ -21,6 +19,7 @@
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/fcntl.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/personality.h>
@@ -278,10 +277,8 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
error = locks_verify_truncate(inode, NULL, length);
if (!error)
error = security_path_truncate(&path, length, 0);
- if (!error) {
- vfs_dq_init(inode);
+ if (!error)
error = do_truncate(path.dentry, length, 0, NULL);
- }
put_write_and_out:
put_write_access(inode);
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index e8865c11777..e238ab23a9e 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/ctype.h>
#include <linux/genhd.h>
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c
index 49cfd5f5423..91babdae758 100644
--- a/fs/partitions/efi.c
+++ b/fs/partitions/efi.c
@@ -95,6 +95,7 @@
************************************************************/
#include <linux/crc32.h>
#include <linux/math64.h>
+#include <linux/slab.h>
#include "check.h"
#include "efi.h"
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index 0028d2ef066..90be97f1f5a 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -31,14 +31,17 @@
*/
#include <asm/unaligned.h>
-#define SYS_IND(p) (get_unaligned(&p->sys_ind))
-#define NR_SECTS(p) ({ __le32 __a = get_unaligned(&p->nr_sects); \
- le32_to_cpu(__a); \
- })
+#define SYS_IND(p) get_unaligned(&p->sys_ind)
-#define START_SECT(p) ({ __le32 __a = get_unaligned(&p->start_sect); \
- le32_to_cpu(__a); \
- })
+static inline sector_t nr_sects(struct partition *p)
+{
+ return (sector_t)get_unaligned_le32(&p->nr_sects);
+}
+
+static inline sector_t start_sect(struct partition *p)
+{
+ return (sector_t)get_unaligned_le32(&p->start_sect);
+}
static inline int is_extended_partition(struct partition *p)
{
@@ -104,13 +107,13 @@ static int aix_magic_present(unsigned char *p, struct block_device *bdev)
static void
parse_extended(struct parsed_partitions *state, struct block_device *bdev,
- u32 first_sector, u32 first_size)
+ sector_t first_sector, sector_t first_size)
{
struct partition *p;
Sector sect;
unsigned char *data;
- u32 this_sector, this_size;
- int sector_size = bdev_logical_block_size(bdev) / 512;
+ sector_t this_sector, this_size;
+ sector_t sector_size = bdev_logical_block_size(bdev) / 512;
int loopct = 0; /* number of links followed
without finding a data partition */
int i;
@@ -145,14 +148,14 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev,
* First process the data partition(s)
*/
for (i=0; i<4; i++, p++) {
- u32 offs, size, next;
- if (!NR_SECTS(p) || is_extended_partition(p))
+ sector_t offs, size, next;
+ if (!nr_sects(p) || is_extended_partition(p))
continue;
/* Check the 3rd and 4th entries -
these sometimes contain random garbage */
- offs = START_SECT(p)*sector_size;
- size = NR_SECTS(p)*sector_size;
+ offs = start_sect(p)*sector_size;
+ size = nr_sects(p)*sector_size;
next = this_sector + offs;
if (i >= 2) {
if (offs + size > this_size)
@@ -179,13 +182,13 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev,
*/
p -= 4;
for (i=0; i<4; i++, p++)
- if (NR_SECTS(p) && is_extended_partition(p))
+ if (nr_sects(p) && is_extended_partition(p))
break;
if (i == 4)
goto done; /* nothing left to do */
- this_sector = first_sector + START_SECT(p) * sector_size;
- this_size = NR_SECTS(p) * sector_size;
+ this_sector = first_sector + start_sect(p) * sector_size;
+ this_size = nr_sects(p) * sector_size;
put_dev_sector(sect);
}
done:
@@ -197,7 +200,7 @@ done:
static void
parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
- u32 offset, u32 size, int origin)
+ sector_t offset, sector_t size, int origin)
{
#ifdef CONFIG_SOLARIS_X86_PARTITION
Sector sect;
@@ -244,7 +247,7 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
*/
static void
parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
- u32 offset, u32 size, int origin, char *flavour,
+ sector_t offset, sector_t size, int origin, char *flavour,
int max_partitions)
{
Sector sect;
@@ -263,7 +266,7 @@ parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
if (le16_to_cpu(l->d_npartitions) < max_partitions)
max_partitions = le16_to_cpu(l->d_npartitions);
for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
- u32 bsd_start, bsd_size;
+ sector_t bsd_start, bsd_size;
if (state->next == state->limit)
break;
@@ -290,7 +293,7 @@ parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
static void
parse_freebsd(struct parsed_partitions *state, struct block_device *bdev,
- u32 offset, u32 size, int origin)
+ sector_t offset, sector_t size, int origin)
{
#ifdef CONFIG_BSD_DISKLABEL
parse_bsd(state, bdev, offset, size, origin,
@@ -300,7 +303,7 @@ parse_freebsd(struct parsed_partitions *state, struct block_device *bdev,
static void
parse_netbsd(struct parsed_partitions *state, struct block_device *bdev,
- u32 offset, u32 size, int origin)
+ sector_t offset, sector_t size, int origin)
{
#ifdef CONFIG_BSD_DISKLABEL
parse_bsd(state, bdev, offset, size, origin,
@@ -310,7 +313,7 @@ parse_netbsd(struct parsed_partitions *state, struct block_device *bdev,
static void
parse_openbsd(struct parsed_partitions *state, struct block_device *bdev,
- u32 offset, u32 size, int origin)
+ sector_t offset, sector_t size, int origin)
{
#ifdef CONFIG_BSD_DISKLABEL
parse_bsd(state, bdev, offset, size, origin,
@@ -324,7 +327,7 @@ parse_openbsd(struct parsed_partitions *state, struct block_device *bdev,
*/
static void
parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
- u32 offset, u32 size, int origin)
+ sector_t offset, sector_t size, int origin)
{
#ifdef CONFIG_UNIXWARE_DISKLABEL
Sector sect;
@@ -348,7 +351,8 @@ parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
if (p->s_label != UNIXWARE_FS_UNUSED)
put_partition(state, state->next++,
- START_SECT(p), NR_SECTS(p));
+ le32_to_cpu(p->start_sect),
+ le32_to_cpu(p->nr_sects));
p++;
}
put_dev_sector(sect);
@@ -363,7 +367,7 @@ parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
*/
static void
parse_minix(struct parsed_partitions *state, struct block_device *bdev,
- u32 offset, u32 size, int origin)
+ sector_t offset, sector_t size, int origin)
{
#ifdef CONFIG_MINIX_SUBPARTITION
Sector sect;
@@ -390,7 +394,7 @@ parse_minix(struct parsed_partitions *state, struct block_device *bdev,
/* add each partition in use */
if (SYS_IND(p) == MINIX_PARTITION)
put_partition(state, state->next++,
- START_SECT(p), NR_SECTS(p));
+ start_sect(p), nr_sects(p));
}
printk(" >\n");
}
@@ -401,7 +405,7 @@ parse_minix(struct parsed_partitions *state, struct block_device *bdev,
static struct {
unsigned char id;
void (*parse)(struct parsed_partitions *, struct block_device *,
- u32, u32, int);
+ sector_t, sector_t, int);
} subtypes[] = {
{FREEBSD_PARTITION, parse_freebsd},
{NETBSD_PARTITION, parse_netbsd},
@@ -415,7 +419,7 @@ static struct {
int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
{
- int sector_size = bdev_logical_block_size(bdev) / 512;
+ sector_t sector_size = bdev_logical_block_size(bdev) / 512;
Sector sect;
unsigned char *data;
struct partition *p;
@@ -483,14 +487,21 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
state->next = 5;
for (slot = 1 ; slot <= 4 ; slot++, p++) {
- u32 start = START_SECT(p)*sector_size;
- u32 size = NR_SECTS(p)*sector_size;
+ sector_t start = start_sect(p)*sector_size;
+ sector_t size = nr_sects(p)*sector_size;
if (!size)
continue;
if (is_extended_partition(p)) {
- /* prevent someone doing mkfs or mkswap on an
- extended partition, but leave room for LILO */
- put_partition(state, slot, start, size == 1 ? 1 : 2);
+ /*
+ * prevent someone doing mkfs or mkswap on an
+ * extended partition, but leave room for LILO
+ * FIXME: this uses one logical sector for > 512b
+ * sector, although it may not be enough/proper.
+ */
+ sector_t n = 2;
+ n = min(size, max(sector_size, n));
+ put_partition(state, slot, start, n);
+
printk(" <");
parse_extended(state, bdev, start, size);
printk(" >");
@@ -513,7 +524,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
unsigned char id = SYS_IND(p);
int n;
- if (!NR_SECTS(p))
+ if (!nr_sects(p))
continue;
for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++)
@@ -521,8 +532,8 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
if (!subtypes[n].parse)
continue;
- subtypes[n].parse(state, bdev, START_SECT(p)*sector_size,
- NR_SECTS(p)*sector_size, slot);
+ subtypes[n].parse(state, bdev, start_sect(p)*sector_size,
+ nr_sects(p)*sector_size, slot);
}
put_dev_sector(sect);
return 1;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 18e20feee25..e51f2ec2c5e 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -68,7 +68,6 @@
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
-#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/signal.h>
#include <linux/highmem.h>
@@ -273,7 +272,7 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
rcu_read_lock(); /* FIXME: is this correct? */
qsize = atomic_read(&__task_cred(p)->user->sigpending);
rcu_read_unlock();
- qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
+ qlim = task_rlimit(p, RLIMIT_SIGPENDING);
unlock_task_sighand(p, &flags);
}
@@ -420,7 +419,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
cutime = sig->cutime;
cstime = sig->cstime;
cgtime = sig->cgtime;
- rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
+ rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
/* add up live thread stats at the group level */
if (whole) {
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a7310841c83..8418fcc0a6a 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -81,6 +81,7 @@
#include <linux/elf.h>
#include <linux/pid_namespace.h>
#include <linux/fs_struct.h>
+#include <linux/slab.h>
#include "internal.h"
/* NOTE:
@@ -442,12 +443,13 @@ static const struct file_operations proc_lstats_operations = {
unsigned long badness(struct task_struct *p, unsigned long uptime);
static int proc_oom_score(struct task_struct *task, char *buffer)
{
- unsigned long points;
+ unsigned long points = 0;
struct timespec uptime;
do_posix_clock_monotonic_gettime(&uptime);
read_lock(&tasklist_lock);
- points = badness(task->group_leader, uptime.tv_sec);
+ if (pid_alive(task))
+ points = badness(task, uptime.tv_sec);
read_unlock(&tasklist_lock);
return sprintf(buffer, "%lu\n", points);
}
@@ -2907,7 +2909,7 @@ out_no_task:
*/
static const struct pid_entry tid_base_stuff[] = {
DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
- DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations),
+ DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
REG("environ", S_IRUSR, proc_environ_operations),
INF("auxv", S_IRUSR, proc_pid_auxv),
ONE("status", S_IRUGO, proc_pid_status),
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 9580abeadeb..43c12749060 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -13,6 +13,7 @@
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/init.h>
#include <linux/idr.h>
@@ -291,19 +292,17 @@ static const struct inode_operations proc_file_inode_operations = {
* returns the struct proc_dir_entry for "/proc/tty/driver", and
* returns "serial" in residual.
*/
-static int xlate_proc_name(const char *name,
- struct proc_dir_entry **ret, const char **residual)
+static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
+ const char **residual)
{
const char *cp = name, *next;
struct proc_dir_entry *de;
int len;
- int rtn = 0;
de = *ret;
if (!de)
de = &proc_root;
- spin_lock(&proc_subdir_lock);
while (1) {
next = strchr(cp, '/');
if (!next)
@@ -315,16 +314,25 @@ static int xlate_proc_name(const char *name,
break;
}
if (!de) {
- rtn = -ENOENT;
- goto out;
+ WARN(1, "name '%s'\n", name);
+ return -ENOENT;
}
cp += len + 1;
}
*residual = cp;
*ret = de;
-out:
+ return 0;
+}
+
+static int xlate_proc_name(const char *name, struct proc_dir_entry **ret,
+ const char **residual)
+{
+ int rv;
+
+ spin_lock(&proc_subdir_lock);
+ rv = __xlate_proc_name(name, ret, residual);
spin_unlock(&proc_subdir_lock);
- return rtn;
+ return rv;
}
static DEFINE_IDA(proc_inum_ida);
@@ -797,11 +805,13 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
const char *fn = name;
int len;
- if (xlate_proc_name(name, &parent, &fn) != 0)
+ spin_lock(&proc_subdir_lock);
+ if (__xlate_proc_name(name, &parent, &fn) != 0) {
+ spin_unlock(&proc_subdir_lock);
return;
+ }
len = strlen(fn);
- spin_lock(&proc_subdir_lock);
for (p = &parent->subdir; *p; p=&(*p)->next ) {
if (proc_match(len, fn, *p)) {
de = *p;
@@ -811,8 +821,10 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
}
}
spin_unlock(&proc_subdir_lock);
- if (!de)
+ if (!de) {
+ WARN(1, "name '%s'\n", name);
return;
+ }
spin_lock(&de->pde_unload_lock);
/*
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 445a02bcaab..d35b23238fb 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <linux/sysctl.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index a44a7897fd4..19979a2ce27 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -19,6 +19,7 @@
#include <linux/highmem.h>
#include <linux/bootmem.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/list.h>
@@ -490,7 +491,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
}
read_unlock(&kclist_lock);
- if (m == NULL) {
+ if (&m->list == &kclist_head) {
if (clear_user(buffer, tsz))
return -EFAULT;
} else if (is_vmalloc_or_module_addr((void *)start)) {
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
index 9fe7d7ebe11..b1822dde55c 100644
--- a/fs/proc/nommu.c
+++ b/fs/proc/nommu.c
@@ -21,7 +21,6 @@
#include <linux/mmzone.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
-#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/seq_file.h>
#include <linux/hugetlb.h>
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index f8650dce74f..ce94801f48c 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -12,6 +12,7 @@
#include <linux/string.h>
#include <linux/of.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/uaccess.h>
#include "internal.h"
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index 04d1270f1c3..9020ac15baa 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -14,6 +14,7 @@
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/module.h>
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
index b9b7aad2003..bf31b03fc27 100644
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -1,6 +1,5 @@
#include <linux/cpumask.h>
#include <linux/fs.h>
-#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index f277c4a111c..070553427dd 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -4,6 +4,7 @@
#include <linux/seq_file.h>
#include <linux/highmem.h>
#include <linux/ptrace.h>
+#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/mempolicy.h>
#include <linux/swap.h>
@@ -16,7 +17,7 @@
void task_mem(struct seq_file *m, struct mm_struct *mm)
{
- unsigned long data, text, lib;
+ unsigned long data, text, lib, swap;
unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
/*
@@ -36,6 +37,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
data = mm->total_vm - mm->shared_vm - mm->stack_vm;
text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
+ swap = get_mm_counter(mm, MM_SWAPENTS);
seq_printf(m,
"VmPeak:\t%8lu kB\n"
"VmSize:\t%8lu kB\n"
@@ -46,7 +48,8 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
"VmStk:\t%8lu kB\n"
"VmExe:\t%8lu kB\n"
"VmLib:\t%8lu kB\n"
- "VmPTE:\t%8lu kB\n",
+ "VmPTE:\t%8lu kB\n"
+ "VmSwap:\t%8lu kB\n",
hiwater_vm << (PAGE_SHIFT-10),
(total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
mm->locked_vm << (PAGE_SHIFT-10),
@@ -54,7 +57,8 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
total_rss << (PAGE_SHIFT-10),
data << (PAGE_SHIFT-10),
mm->stack_vm << (PAGE_SHIFT-10), text, lib,
- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
+ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
+ swap << (PAGE_SHIFT-10));
}
unsigned long task_vsize(struct mm_struct *mm)
@@ -65,11 +69,11 @@ unsigned long task_vsize(struct mm_struct *mm)
int task_statm(struct mm_struct *mm, int *shared, int *text,
int *data, int *resident)
{
- *shared = get_mm_counter(mm, file_rss);
+ *shared = get_mm_counter(mm, MM_FILEPAGES);
*text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
>> PAGE_SHIFT;
*data = mm->total_vm - mm->shared_vm;
- *resident = *shared + get_mm_counter(mm, anon_rss);
+ *resident = *shared + get_mm_counter(mm, MM_ANONPAGES);
return mm->total_vm;
}
@@ -403,6 +407,7 @@ static int show_smap(struct seq_file *m, void *v)
memset(&mss, 0, sizeof mss);
mss.vma = vma;
+ /* mmap_sem is held in m_start */
if (vma->vm_mm && !is_vm_hugetlb_page(vma))
walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
@@ -549,7 +554,8 @@ const struct file_operations proc_clear_refs_operations = {
};
struct pagemapread {
- u64 __user *out, *end;
+ int pos, len;
+ u64 *buffer;
};
#define PM_ENTRY_BYTES sizeof(u64)
@@ -572,10 +578,8 @@ struct pagemapread {
static int add_to_pagemap(unsigned long addr, u64 pfn,
struct pagemapread *pm)
{
- if (put_user(pfn, pm->out))
- return -EFAULT;
- pm->out++;
- if (pm->out >= pm->end)
+ pm->buffer[pm->pos++] = pfn;
+ if (pm->pos >= pm->len)
return PM_END_OF_BUFFER;
return 0;
}
@@ -658,31 +662,18 @@ static u64 huge_pte_to_pagemap_entry(pte_t pte, int offset)
return pme;
}
-static int pagemap_hugetlb_range(pte_t *pte, unsigned long addr,
- unsigned long end, struct mm_walk *walk)
+/* This function walks within one hugetlb entry in the single call */
+static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
+ unsigned long addr, unsigned long end,
+ struct mm_walk *walk)
{
- struct vm_area_struct *vma;
struct pagemapread *pm = walk->private;
- struct hstate *hs = NULL;
int err = 0;
+ u64 pfn;
- vma = find_vma(walk->mm, addr);
- if (vma)
- hs = hstate_vma(vma);
for (; addr != end; addr += PAGE_SIZE) {
- u64 pfn = PM_NOT_PRESENT;
-
- if (vma && (addr >= vma->vm_end)) {
- vma = find_vma(walk->mm, addr);
- if (vma)
- hs = hstate_vma(vma);
- }
-
- if (vma && (vma->vm_start <= addr) && is_vm_hugetlb_page(vma)) {
- /* calculate pfn of the "raw" page in the hugepage. */
- int offset = (addr & ~huge_page_mask(hs)) >> PAGE_SHIFT;
- pfn = huge_pte_to_pagemap_entry(*pte, offset);
- }
+ int offset = (addr & ~hmask) >> PAGE_SHIFT;
+ pfn = huge_pte_to_pagemap_entry(*pte, offset);
err = add_to_pagemap(addr, pfn, pm);
if (err)
return err;
@@ -717,21 +708,20 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long addr,
* determine which areas of memory are actually mapped and llseek to
* skip over unmapped regions.
*/
+#define PAGEMAP_WALK_SIZE (PMD_SIZE)
static ssize_t pagemap_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
- struct page **pages, *page;
- unsigned long uaddr, uend;
struct mm_struct *mm;
struct pagemapread pm;
- int pagecount;
int ret = -ESRCH;
struct mm_walk pagemap_walk = {};
unsigned long src;
unsigned long svpfn;
unsigned long start_vaddr;
unsigned long end_vaddr;
+ int copied = 0;
if (!task)
goto out;
@@ -754,35 +744,12 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
if (!mm)
goto out_task;
-
- uaddr = (unsigned long)buf & PAGE_MASK;
- uend = (unsigned long)(buf + count);
- pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE;
- ret = 0;
- if (pagecount == 0)
- goto out_mm;
- pages = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL);
+ pm.len = PM_ENTRY_BYTES * (PAGEMAP_WALK_SIZE >> PAGE_SHIFT);
+ pm.buffer = kmalloc(pm.len, GFP_TEMPORARY);
ret = -ENOMEM;
- if (!pages)
+ if (!pm.buffer)
goto out_mm;
- down_read(&current->mm->mmap_sem);
- ret = get_user_pages(current, current->mm, uaddr, pagecount,
- 1, 0, pages, NULL);
- up_read(&current->mm->mmap_sem);
-
- if (ret < 0)
- goto out_free;
-
- if (ret != pagecount) {
- pagecount = ret;
- ret = -EFAULT;
- goto out_pages;
- }
-
- pm.out = (u64 __user *)buf;
- pm.end = (u64 __user *)(buf + count);
-
pagemap_walk.pmd_entry = pagemap_pte_range;
pagemap_walk.pte_hole = pagemap_pte_hole;
pagemap_walk.hugetlb_entry = pagemap_hugetlb_range;
@@ -804,23 +771,36 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
* user buffer is tracked in "pm", and the walk
* will stop when we hit the end of the buffer.
*/
- ret = walk_page_range(start_vaddr, end_vaddr, &pagemap_walk);
- if (ret == PM_END_OF_BUFFER)
- ret = 0;
- /* don't need mmap_sem for these, but this looks cleaner */
- *ppos += (char __user *)pm.out - buf;
- if (!ret)
- ret = (char __user *)pm.out - buf;
-
-out_pages:
- for (; pagecount; pagecount--) {
- page = pages[pagecount-1];
- if (!PageReserved(page))
- SetPageDirty(page);
- page_cache_release(page);
+ ret = 0;
+ while (count && (start_vaddr < end_vaddr)) {
+ int len;
+ unsigned long end;
+
+ pm.pos = 0;
+ end = start_vaddr + PAGEMAP_WALK_SIZE;
+ /* overflow ? */
+ if (end < start_vaddr || end > end_vaddr)
+ end = end_vaddr;
+ down_read(&mm->mmap_sem);
+ ret = walk_page_range(start_vaddr, end, &pagemap_walk);
+ up_read(&mm->mmap_sem);
+ start_vaddr = end;
+
+ len = min(count, PM_ENTRY_BYTES * pm.pos);
+ if (copy_to_user(buf, pm.buffer, len)) {
+ ret = -EFAULT;
+ goto out_free;
+ }
+ copied += len;
+ buf += len;
+ count -= len;
}
+ *ppos += copied;
+ if (!ret || ret == PM_END_OF_BUFFER)
+ ret = copied;
+
out_free:
- kfree(pages);
+ kfree(pm.buffer);
out_mm:
mmput(mm);
out_task:
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 5d9fd64ef81..46d4b5d72bd 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -5,6 +5,7 @@
#include <linux/fs_struct.h>
#include <linux/mount.h>
#include <linux/ptrace.h>
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include "internal.h"
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 0872afa58d3..9fbc99ec799 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -12,6 +12,7 @@
#include <linux/user.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
+#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/bootmem.h>
#include <linux/init.h>
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index ebf3440d28c..277575ddc05 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -201,7 +201,8 @@ static const char *qnx4_checkroot(struct super_block *sb)
rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE);
if (rootdir->di_fname != NULL) {
QNX4DEBUG((KERN_INFO "rootdir entry found : [%s]\n", rootdir->di_fname));
- if (!strncmp(rootdir->di_fname, QNX4_BMNAME, sizeof QNX4_BMNAME)) {
+ if (!strcmp(rootdir->di_fname,
+ QNX4_BMNAME)) {
found = 1;
qnx4_sb(sb)->BitMap = kmalloc( sizeof( struct qnx4_inode_entry ), GFP_KERNEL );
if (!qnx4_sb(sb)->BitMap) {
diff --git a/fs/quota/Kconfig b/fs/quota/Kconfig
index efc02ebb8c7..3e21b1e2ad3 100644
--- a/fs/quota/Kconfig
+++ b/fs/quota/Kconfig
@@ -33,6 +33,14 @@ config PRINT_QUOTA_WARNING
Note that this behavior is currently deprecated and may go away in
future. Please use notification via netlink socket instead.
+config QUOTA_DEBUG
+ bool "Additional quota sanity checks"
+ depends on QUOTA
+ default n
+ help
+ If you say Y here, quota subsystem will perform some additional
+ sanity checks of quota internal structures. If unsure, say N.
+
# Generic support for tree structured quota files. Selected when needed.
config QUOTA_TREE
tristate
@@ -59,3 +67,8 @@ config QUOTACTL
bool
depends on XFS_QUOTA || QUOTA
default y
+
+config QUOTACTL_COMPAT
+ bool
+ depends on QUOTACTL && COMPAT_FOR_U64_ALIGNMENT
+ default y
diff --git a/fs/quota/Makefile b/fs/quota/Makefile
index 68d4f6dc057..5f9e9e276af 100644
--- a/fs/quota/Makefile
+++ b/fs/quota/Makefile
@@ -3,3 +3,5 @@ obj-$(CONFIG_QFMT_V1) += quota_v1.o
obj-$(CONFIG_QFMT_V2) += quota_v2.o
obj-$(CONFIG_QUOTA_TREE) += quota_tree.o
obj-$(CONFIG_QUOTACTL) += quota.o
+obj-$(CONFIG_QUOTACTL_COMPAT) += compat.o
+obj-$(CONFIG_QUOTA_NETLINK_INTERFACE) += netlink.o
diff --git a/fs/quota/compat.c b/fs/quota/compat.c
new file mode 100644
index 00000000000..fb1892fe3e5
--- /dev/null
+++ b/fs/quota/compat.c
@@ -0,0 +1,118 @@
+
+#include <linux/syscalls.h>
+#include <linux/compat.h>
+#include <linux/quotaops.h>
+
+/*
+ * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
+ * and is necessary due to alignment problems.
+ */
+struct compat_if_dqblk {
+ compat_u64 dqb_bhardlimit;
+ compat_u64 dqb_bsoftlimit;
+ compat_u64 dqb_curspace;
+ compat_u64 dqb_ihardlimit;
+ compat_u64 dqb_isoftlimit;
+ compat_u64 dqb_curinodes;
+ compat_u64 dqb_btime;
+ compat_u64 dqb_itime;
+ compat_uint_t dqb_valid;
+};
+
+/* XFS structures */
+struct compat_fs_qfilestat {
+ compat_u64 dqb_bhardlimit;
+ compat_u64 qfs_nblks;
+ compat_uint_t qfs_nextents;
+};
+
+struct compat_fs_quota_stat {
+ __s8 qs_version;
+ __u16 qs_flags;
+ __s8 qs_pad;
+ struct compat_fs_qfilestat qs_uquota;
+ struct compat_fs_qfilestat qs_gquota;
+ compat_uint_t qs_incoredqs;
+ compat_int_t qs_btimelimit;
+ compat_int_t qs_itimelimit;
+ compat_int_t qs_rtbtimelimit;
+ __u16 qs_bwarnlimit;
+ __u16 qs_iwarnlimit;
+};
+
+asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
+ qid_t id, void __user *addr)
+{
+ unsigned int cmds;
+ struct if_dqblk __user *dqblk;
+ struct compat_if_dqblk __user *compat_dqblk;
+ struct fs_quota_stat __user *fsqstat;
+ struct compat_fs_quota_stat __user *compat_fsqstat;
+ compat_uint_t data;
+ u16 xdata;
+ long ret;
+
+ cmds = cmd >> SUBCMDSHIFT;
+
+ switch (cmds) {
+ case Q_GETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ if (ret)
+ break;
+ if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &dqblk->dqb_valid) ||
+ put_user(data, &compat_dqblk->dqb_valid))
+ ret = -EFAULT;
+ break;
+ case Q_SETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = -EFAULT;
+ if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &compat_dqblk->dqb_valid) ||
+ put_user(data, &dqblk->dqb_valid))
+ break;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ break;
+ case Q_XGETQSTAT:
+ fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat));
+ compat_fsqstat = addr;
+ ret = sys_quotactl(cmd, special, id, fsqstat);
+ if (ret)
+ break;
+ ret = -EFAULT;
+ /* Copying qs_version, qs_flags, qs_pad */
+ if (copy_in_user(compat_fsqstat, fsqstat,
+ offsetof(struct compat_fs_quota_stat, qs_uquota)))
+ break;
+ /* Copying qs_uquota */
+ if (copy_in_user(&compat_fsqstat->qs_uquota,
+ &fsqstat->qs_uquota,
+ sizeof(compat_fsqstat->qs_uquota)) ||
+ get_user(data, &fsqstat->qs_uquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents))
+ break;
+ /* Copying qs_gquota */
+ if (copy_in_user(&compat_fsqstat->qs_gquota,
+ &fsqstat->qs_gquota,
+ sizeof(compat_fsqstat->qs_gquota)) ||
+ get_user(data, &fsqstat->qs_gquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents))
+ break;
+ /* Copying the rest */
+ if (copy_in_user(&compat_fsqstat->qs_incoredqs,
+ &fsqstat->qs_incoredqs,
+ sizeof(struct compat_fs_quota_stat) -
+ offsetof(struct compat_fs_quota_stat, qs_incoredqs)) ||
+ get_user(xdata, &fsqstat->qs_iwarnlimit) ||
+ put_user(xdata, &compat_fsqstat->qs_iwarnlimit))
+ break;
+ ret = 0;
+ break;
+ default:
+ ret = sys_quotactl(cmd, special, id, addr);
+ }
+ return ret;
+}
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 3fc62b097be..788b5802a7c 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -80,8 +80,6 @@
#include <asm/uaccess.h>
-#define __DQUOT_PARANOIA
-
/*
* There are three quota SMP locks. dq_list_lock protects all lists with quotas
* and quota formats, dqstats structure containing statistics about the lists
@@ -100,9 +98,13 @@
*
* Any operation working on dquots via inode pointers must hold dqptr_sem. If
* operation is just reading pointers from inode (or not using them at all) the
- * read lock is enough. If pointers are altered function must hold write lock
- * (these locking rules also apply for S_NOQUOTA flag in the inode - note that
- * for altering the flag i_mutex is also needed).
+ * read lock is enough. If pointers are altered function must hold write lock.
+ * Special care needs to be taken about S_NOQUOTA inode flag (marking that
+ * inode is a quota file). Functions adding pointers from inode to dquots have
+ * to check this flag under dqptr_sem and then (if S_NOQUOTA is not set) they
+ * have to do all pointer modifications before dropping dqptr_sem. This makes
+ * sure they cannot race with quotaon which first sets S_NOQUOTA flag and
+ * then drops all pointers to dquots from an inode.
*
* Each dquot has its dq_lock mutex. Locked dquots might not be referenced
* from inodes (dquot_alloc_space() and such don't check the dq_lock).
@@ -225,6 +227,9 @@ static struct hlist_head *dquot_hash;
struct dqstats dqstats;
EXPORT_SYMBOL(dqstats);
+static qsize_t inode_get_rsv_space(struct inode *inode);
+static void __dquot_initialize(struct inode *inode, int type);
+
static inline unsigned int
hashfn(const struct super_block *sb, unsigned int id, int type)
{
@@ -564,7 +569,7 @@ out:
}
EXPORT_SYMBOL(dquot_scan_active);
-int vfs_quota_sync(struct super_block *sb, int type)
+int vfs_quota_sync(struct super_block *sb, int type, int wait)
{
struct list_head *dirty;
struct dquot *dquot;
@@ -609,6 +614,33 @@ int vfs_quota_sync(struct super_block *sb, int type)
spin_unlock(&dq_list_lock);
mutex_unlock(&dqopt->dqonoff_mutex);
+ if (!wait || (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE))
+ return 0;
+
+ /* This is not very clever (and fast) but currently I don't know about
+ * any other simple way of getting quota data to disk and we must get
+ * them there for userspace to be visible... */
+ if (sb->s_op->sync_fs)
+ sb->s_op->sync_fs(sb, 1);
+ sync_blockdev(sb->s_bdev);
+
+ /*
+ * Now when everything is written we can discard the pagecache so
+ * that userspace sees the changes.
+ */
+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+ if (type != -1 && cnt != type)
+ continue;
+ if (!sb_has_quota_active(sb, cnt))
+ continue;
+ mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex,
+ I_MUTEX_QUOTA);
+ truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0);
+ mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex);
+ }
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
+
return 0;
}
EXPORT_SYMBOL(vfs_quota_sync);
@@ -661,7 +693,7 @@ void dqput(struct dquot *dquot)
if (!dquot)
return;
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
if (!atomic_read(&dquot->dq_count)) {
printk("VFS: dqput: trying to free free dquot\n");
printk("VFS: device %s, dquot of %s %d\n",
@@ -714,7 +746,7 @@ we_slept:
goto we_slept;
}
atomic_dec(&dquot->dq_count);
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
/* sanity check */
BUG_ON(!list_empty(&dquot->dq_free));
#endif
@@ -811,7 +843,7 @@ we_slept:
dquot = NULL;
goto out;
}
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */
#endif
out:
@@ -840,11 +872,18 @@ static int dqinit_needed(struct inode *inode, int type)
static void add_dquot_ref(struct super_block *sb, int type)
{
struct inode *inode, *old_inode = NULL;
+#ifdef CONFIG_QUOTA_DEBUG
+ int reserved = 0;
+#endif
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))
continue;
+#ifdef CONFIG_QUOTA_DEBUG
+ if (unlikely(inode_get_rsv_space(inode) > 0))
+ reserved = 1;
+#endif
if (!atomic_read(&inode->i_writecount))
continue;
if (!dqinit_needed(inode, type))
@@ -854,7 +893,7 @@ static void add_dquot_ref(struct super_block *sb, int type)
spin_unlock(&inode_lock);
iput(old_inode);
- sb->dq_op->initialize(inode, type);
+ __dquot_initialize(inode, type);
/* We hold a reference to 'inode' so it couldn't have been
* removed from s_inodes list while we dropped the inode_lock.
* We cannot iput the inode now as we can be holding the last
@@ -865,6 +904,14 @@ static void add_dquot_ref(struct super_block *sb, int type)
}
spin_unlock(&inode_lock);
iput(old_inode);
+
+#ifdef CONFIG_QUOTA_DEBUG
+ if (reserved) {
+ printk(KERN_WARNING "VFS (%s): Writes happened before quota"
+ " was turned on thus quota information is probably "
+ "inconsistent. Please run quotacheck(8).\n", sb->s_id);
+ }
+#endif
}
/*
@@ -891,7 +938,7 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
inode->i_dquot[type] = NULL;
if (dquot) {
if (dqput_blocks(dquot)) {
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
if (atomic_read(&dquot->dq_count) != 1)
printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count));
#endif
@@ -978,10 +1025,12 @@ static inline void dquot_resv_space(struct dquot *dquot, qsize_t number)
/*
* Claim reserved quota space
*/
-static void dquot_claim_reserved_space(struct dquot *dquot,
- qsize_t number)
+static void dquot_claim_reserved_space(struct dquot *dquot, qsize_t number)
{
- WARN_ON(dquot->dq_dqb.dqb_rsvspace < number);
+ if (dquot->dq_dqb.dqb_rsvspace < number) {
+ WARN_ON_ONCE(1);
+ number = dquot->dq_dqb.dqb_rsvspace;
+ }
dquot->dq_dqb.dqb_curspace += number;
dquot->dq_dqb.dqb_rsvspace -= number;
}
@@ -989,7 +1038,12 @@ static void dquot_claim_reserved_space(struct dquot *dquot,
static inline
void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
{
- dquot->dq_dqb.dqb_rsvspace -= number;
+ if (dquot->dq_dqb.dqb_rsvspace >= number)
+ dquot->dq_dqb.dqb_rsvspace -= number;
+ else {
+ WARN_ON_ONCE(1);
+ dquot->dq_dqb.dqb_rsvspace = 0;
+ }
}
static void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
@@ -1131,13 +1185,13 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
*warntype = QUOTA_NL_NOWARN;
if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
test_bit(DQ_FAKE_B, &dquot->dq_flags))
- return QUOTA_OK;
+ return 0;
if (dquot->dq_dqb.dqb_ihardlimit &&
newinodes > dquot->dq_dqb.dqb_ihardlimit &&
!ignore_hardlimit(dquot)) {
*warntype = QUOTA_NL_IHARDWARN;
- return NO_QUOTA;
+ return -EDQUOT;
}
if (dquot->dq_dqb.dqb_isoftlimit &&
@@ -1146,7 +1200,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
get_seconds() >= dquot->dq_dqb.dqb_itime &&
!ignore_hardlimit(dquot)) {
*warntype = QUOTA_NL_ISOFTLONGWARN;
- return NO_QUOTA;
+ return -EDQUOT;
}
if (dquot->dq_dqb.dqb_isoftlimit &&
@@ -1157,7 +1211,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
}
- return QUOTA_OK;
+ return 0;
}
/* needs dq_data_lock */
@@ -1169,7 +1223,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
*warntype = QUOTA_NL_NOWARN;
if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) ||
test_bit(DQ_FAKE_B, &dquot->dq_flags))
- return QUOTA_OK;
+ return 0;
tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace
+ space;
@@ -1179,7 +1233,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
!ignore_hardlimit(dquot)) {
if (!prealloc)
*warntype = QUOTA_NL_BHARDWARN;
- return NO_QUOTA;
+ return -EDQUOT;
}
if (dquot->dq_dqb.dqb_bsoftlimit &&
@@ -1189,7 +1243,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
!ignore_hardlimit(dquot)) {
if (!prealloc)
*warntype = QUOTA_NL_BSOFTLONGWARN;
- return NO_QUOTA;
+ return -EDQUOT;
}
if (dquot->dq_dqb.dqb_bsoftlimit &&
@@ -1205,10 +1259,10 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
* We don't allow preallocation to exceed softlimit so exceeding will
* be always printed
*/
- return NO_QUOTA;
+ return -EDQUOT;
}
- return QUOTA_OK;
+ return 0;
}
static int info_idq_free(struct dquot *dquot, qsize_t inodes)
@@ -1242,25 +1296,32 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space)
return QUOTA_NL_BHARDBELOW;
return QUOTA_NL_NOWARN;
}
+
/*
- * Initialize quota pointers in inode
- * We do things in a bit complicated way but by that we avoid calling
- * dqget() and thus filesystem callbacks under dqptr_sem.
+ * Initialize quota pointers in inode
+ *
+ * We do things in a bit complicated way but by that we avoid calling
+ * dqget() and thus filesystem callbacks under dqptr_sem.
+ *
+ * It is better to call this function outside of any transaction as it
+ * might need a lot of space in journal for dquot structure allocation.
*/
-int dquot_initialize(struct inode *inode, int type)
+static void __dquot_initialize(struct inode *inode, int type)
{
unsigned int id = 0;
- int cnt, ret = 0;
- struct dquot *got[MAXQUOTAS] = { NULL, NULL };
+ int cnt;
+ struct dquot *got[MAXQUOTAS];
struct super_block *sb = inode->i_sb;
+ qsize_t rsv;
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
- if (IS_NOQUOTA(inode))
- return 0;
+ if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode))
+ return;
/* First get references to structures we might need. */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+ got[cnt] = NULL;
if (type != -1 && cnt != type)
continue;
switch (cnt) {
@@ -1275,7 +1336,6 @@ int dquot_initialize(struct inode *inode, int type)
}
down_write(&sb_dqopt(sb)->dqptr_sem);
- /* Having dqptr_sem we know NOQUOTA flags can't be altered... */
if (IS_NOQUOTA(inode))
goto out_err;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1287,20 +1347,31 @@ int dquot_initialize(struct inode *inode, int type)
if (!inode->i_dquot[cnt]) {
inode->i_dquot[cnt] = got[cnt];
got[cnt] = NULL;
+ /*
+ * Make quota reservation system happy if someone
+ * did a write before quota was turned on
+ */
+ rsv = inode_get_rsv_space(inode);
+ if (unlikely(rsv))
+ dquot_resv_space(inode->i_dquot[cnt], rsv);
}
}
out_err:
up_write(&sb_dqopt(sb)->dqptr_sem);
/* Drop unused references */
dqput_all(got);
- return ret;
+}
+
+void dquot_initialize(struct inode *inode)
+{
+ __dquot_initialize(inode, -1);
}
EXPORT_SYMBOL(dquot_initialize);
/*
* Release all quotas referenced by inode
*/
-int dquot_drop(struct inode *inode)
+static void __dquot_drop(struct inode *inode)
{
int cnt;
struct dquot *put[MAXQUOTAS];
@@ -1312,32 +1383,31 @@ int dquot_drop(struct inode *inode)
}
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
dqput_all(put);
- return 0;
}
-EXPORT_SYMBOL(dquot_drop);
-/* Wrapper to remove references to quota structures from inode */
-void vfs_dq_drop(struct inode *inode)
-{
- /* Here we can get arbitrary inode from clear_inode() so we have
- * to be careful. OTOH we don't need locking as quota operations
- * are allowed to change only at mount time */
- if (!IS_NOQUOTA(inode) && inode->i_sb && inode->i_sb->dq_op
- && inode->i_sb->dq_op->drop) {
- int cnt;
- /* Test before calling to rule out calls from proc and such
- * where we are not allowed to block. Note that this is
- * actually reliable test even without the lock - the caller
- * must assure that nobody can come after the DQUOT_DROP and
- * add quota pointers back anyway */
- for (cnt = 0; cnt < MAXQUOTAS; cnt++)
- if (inode->i_dquot[cnt])
- break;
- if (cnt < MAXQUOTAS)
- inode->i_sb->dq_op->drop(inode);
- }
-}
-EXPORT_SYMBOL(vfs_dq_drop);
+void dquot_drop(struct inode *inode)
+{
+ int cnt;
+
+ if (IS_NOQUOTA(inode))
+ return;
+
+ /*
+ * Test before calling to rule out calls from proc and such
+ * where we are not allowed to block. Note that this is
+ * actually reliable test even without the lock - the caller
+ * must assure that nobody can come after the DQUOT_DROP and
+ * add quota pointers back anyway.
+ */
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+ if (inode->i_dquot[cnt])
+ break;
+ }
+
+ if (cnt < MAXQUOTAS)
+ __dquot_drop(inode);
+}
+EXPORT_SYMBOL(dquot_drop);
/*
* inode_reserved_space is managed internally by quota, and protected by
@@ -1351,28 +1421,30 @@ static qsize_t *inode_reserved_space(struct inode * inode)
return inode->i_sb->dq_op->get_reserved_space(inode);
}
-static void inode_add_rsv_space(struct inode *inode, qsize_t number)
+void inode_add_rsv_space(struct inode *inode, qsize_t number)
{
spin_lock(&inode->i_lock);
*inode_reserved_space(inode) += number;
spin_unlock(&inode->i_lock);
}
+EXPORT_SYMBOL(inode_add_rsv_space);
-
-static void inode_claim_rsv_space(struct inode *inode, qsize_t number)
+void inode_claim_rsv_space(struct inode *inode, qsize_t number)
{
spin_lock(&inode->i_lock);
*inode_reserved_space(inode) -= number;
__inode_add_bytes(inode, number);
spin_unlock(&inode->i_lock);
}
+EXPORT_SYMBOL(inode_claim_rsv_space);
-static void inode_sub_rsv_space(struct inode *inode, qsize_t number)
+void inode_sub_rsv_space(struct inode *inode, qsize_t number)
{
spin_lock(&inode->i_lock);
*inode_reserved_space(inode) -= number;
spin_unlock(&inode->i_lock);
}
+EXPORT_SYMBOL(inode_sub_rsv_space);
static qsize_t inode_get_rsv_space(struct inode *inode)
{
@@ -1404,38 +1476,34 @@ static void inode_decr_space(struct inode *inode, qsize_t number, int reserve)
}
/*
- * Following four functions update i_blocks+i_bytes fields and
- * quota information (together with appropriate checks)
- * NOTE: We absolutely rely on the fact that caller dirties
- * the inode (usually macros in quotaops.h care about this) and
- * holds a handle for the current transaction so that dquot write and
- * inode write go into the same transaction.
+ * This functions updates i_blocks+i_bytes fields and quota information
+ * (together with appropriate checks).
+ *
+ * NOTE: We absolutely rely on the fact that caller dirties the inode
+ * (usually helpers in quotaops.h care about this) and holds a handle for
+ * the current transaction so that dquot write and inode write go into the
+ * same transaction.
*/
/*
* This operation can block, but only after everything is updated
*/
int __dquot_alloc_space(struct inode *inode, qsize_t number,
- int warn, int reserve)
+ int warn, int reserve)
{
- int cnt, ret = QUOTA_OK;
+ int cnt, ret = 0;
char warntype[MAXQUOTAS];
/*
* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex
*/
- if (IS_NOQUOTA(inode)) {
+ if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) {
inode_incr_space(inode, number, reserve);
goto out;
}
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- if (IS_NOQUOTA(inode)) {
- inode_incr_space(inode, number, reserve);
- goto out_unlock;
- }
-
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warntype[cnt] = QUOTA_NL_NOWARN;
@@ -1443,9 +1511,9 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (!inode->i_dquot[cnt])
continue;
- if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt)
- == NO_QUOTA) {
- ret = NO_QUOTA;
+ ret = check_bdq(inode->i_dquot[cnt], number, !warn,
+ warntype+cnt);
+ if (ret) {
spin_unlock(&dq_data_lock);
goto out_flush_warn;
}
@@ -1466,61 +1534,45 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
mark_all_dquot_dirty(inode->i_dquot);
out_flush_warn:
flush_warnings(inode->i_dquot, warntype);
-out_unlock:
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
out:
return ret;
}
-
-int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
-{
- return __dquot_alloc_space(inode, number, warn, 0);
-}
-EXPORT_SYMBOL(dquot_alloc_space);
-
-int dquot_reserve_space(struct inode *inode, qsize_t number, int warn)
-{
- return __dquot_alloc_space(inode, number, warn, 1);
-}
-EXPORT_SYMBOL(dquot_reserve_space);
+EXPORT_SYMBOL(__dquot_alloc_space);
/*
* This operation can block, but only after everything is updated
*/
-int dquot_alloc_inode(const struct inode *inode, qsize_t number)
+int dquot_alloc_inode(const struct inode *inode)
{
- int cnt, ret = NO_QUOTA;
+ int cnt, ret = 0;
char warntype[MAXQUOTAS];
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
- if (IS_NOQUOTA(inode))
- return QUOTA_OK;
+ if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode))
+ return 0;
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warntype[cnt] = QUOTA_NL_NOWARN;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- if (IS_NOQUOTA(inode)) {
- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- return QUOTA_OK;
- }
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (!inode->i_dquot[cnt])
continue;
- if (check_idq(inode->i_dquot[cnt], number, warntype+cnt)
- == NO_QUOTA)
+ ret = check_idq(inode->i_dquot[cnt], 1, warntype + cnt);
+ if (ret)
goto warn_put_all;
}
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (!inode->i_dquot[cnt])
continue;
- dquot_incr_inodes(inode->i_dquot[cnt], number);
+ dquot_incr_inodes(inode->i_dquot[cnt], 1);
}
- ret = QUOTA_OK;
+
warn_put_all:
spin_unlock(&dq_data_lock);
- if (ret == QUOTA_OK)
+ if (ret == 0)
mark_all_dquot_dirty(inode->i_dquot);
flush_warnings(inode->i_dquot, warntype);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -1528,23 +1580,19 @@ warn_put_all:
}
EXPORT_SYMBOL(dquot_alloc_inode);
-int dquot_claim_space(struct inode *inode, qsize_t number)
+/*
+ * Convert in-memory reserved quotas to real consumed quotas
+ */
+int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
{
int cnt;
- int ret = QUOTA_OK;
- if (IS_NOQUOTA(inode)) {
+ if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) {
inode_claim_rsv_space(inode, number);
- goto out;
+ return 0;
}
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- if (IS_NOQUOTA(inode)) {
- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- inode_claim_rsv_space(inode, number);
- goto out;
- }
-
spin_lock(&dq_data_lock);
/* Claim reserved quotas to allocated quotas */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1557,33 +1605,26 @@ int dquot_claim_space(struct inode *inode, qsize_t number)
spin_unlock(&dq_data_lock);
mark_all_dquot_dirty(inode->i_dquot);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
-out:
- return ret;
+ return 0;
}
-EXPORT_SYMBOL(dquot_claim_space);
+EXPORT_SYMBOL(dquot_claim_space_nodirty);
/*
* This operation can block, but only after everything is updated
*/
-int __dquot_free_space(struct inode *inode, qsize_t number, int reserve)
+void __dquot_free_space(struct inode *inode, qsize_t number, int reserve)
{
unsigned int cnt;
char warntype[MAXQUOTAS];
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
- if (IS_NOQUOTA(inode)) {
-out_sub:
+ if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) {
inode_decr_space(inode, number, reserve);
- return QUOTA_OK;
+ return;
}
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- /* Now recheck reliably when holding dqptr_sem */
- if (IS_NOQUOTA(inode)) {
- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- goto out_sub;
- }
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (!inode->i_dquot[cnt])
@@ -1603,56 +1644,34 @@ out_sub:
out_unlock:
flush_warnings(inode->i_dquot, warntype);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- return QUOTA_OK;
-}
-
-int dquot_free_space(struct inode *inode, qsize_t number)
-{
- return __dquot_free_space(inode, number, 0);
}
-EXPORT_SYMBOL(dquot_free_space);
-
-/*
- * Release reserved quota space
- */
-void dquot_release_reserved_space(struct inode *inode, qsize_t number)
-{
- __dquot_free_space(inode, number, 1);
-
-}
-EXPORT_SYMBOL(dquot_release_reserved_space);
+EXPORT_SYMBOL(__dquot_free_space);
/*
* This operation can block, but only after everything is updated
*/
-int dquot_free_inode(const struct inode *inode, qsize_t number)
+void dquot_free_inode(const struct inode *inode)
{
unsigned int cnt;
char warntype[MAXQUOTAS];
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
- if (IS_NOQUOTA(inode))
- return QUOTA_OK;
+ if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode))
+ return;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- /* Now recheck reliably when holding dqptr_sem */
- if (IS_NOQUOTA(inode)) {
- up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- return QUOTA_OK;
- }
spin_lock(&dq_data_lock);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (!inode->i_dquot[cnt])
continue;
- warntype[cnt] = info_idq_free(inode->i_dquot[cnt], number);
- dquot_decr_inodes(inode->i_dquot[cnt], number);
+ warntype[cnt] = info_idq_free(inode->i_dquot[cnt], 1);
+ dquot_decr_inodes(inode->i_dquot[cnt], 1);
}
spin_unlock(&dq_data_lock);
mark_all_dquot_dirty(inode->i_dquot);
flush_warnings(inode->i_dquot, warntype);
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
- return QUOTA_OK;
}
EXPORT_SYMBOL(dquot_free_inode);
@@ -1662,37 +1681,31 @@ EXPORT_SYMBOL(dquot_free_inode);
* This operation can block, but only after everything is updated
* A transaction must be started when entering this function.
*/
-int dquot_transfer(struct inode *inode, struct iattr *iattr)
+static int __dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask)
{
qsize_t space, cur_space;
qsize_t rsv_space = 0;
struct dquot *transfer_from[MAXQUOTAS];
struct dquot *transfer_to[MAXQUOTAS];
- int cnt, ret = QUOTA_OK;
- int chuid = iattr->ia_valid & ATTR_UID && inode->i_uid != iattr->ia_uid,
- chgid = iattr->ia_valid & ATTR_GID && inode->i_gid != iattr->ia_gid;
+ int cnt, ret = 0;
char warntype_to[MAXQUOTAS];
char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS];
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
if (IS_NOQUOTA(inode))
- return QUOTA_OK;
+ return 0;
/* Initialize the arrays */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
transfer_from[cnt] = NULL;
transfer_to[cnt] = NULL;
warntype_to[cnt] = QUOTA_NL_NOWARN;
}
- if (chuid)
- transfer_to[USRQUOTA] = dqget(inode->i_sb, iattr->ia_uid,
- USRQUOTA);
- if (chgid)
- transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid,
- GRPQUOTA);
-
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+ if (mask & (1 << cnt))
+ transfer_to[cnt] = dqget(inode->i_sb, chid[cnt], cnt);
+ }
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
- /* Now recheck reliably when holding dqptr_sem */
if (IS_NOQUOTA(inode)) { /* File without quota accounting? */
up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
goto put_all;
@@ -1706,9 +1719,11 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
if (!transfer_to[cnt])
continue;
transfer_from[cnt] = inode->i_dquot[cnt];
- if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) ==
- NO_QUOTA || check_bdq(transfer_to[cnt], space, 0,
- warntype_to + cnt) == NO_QUOTA)
+ ret = check_idq(transfer_to[cnt], 1, warntype_to + cnt);
+ if (ret)
+ goto over_quota;
+ ret = check_bdq(transfer_to[cnt], space, 0, warntype_to + cnt);
+ if (ret)
goto over_quota;
}
@@ -1762,22 +1777,32 @@ over_quota:
/* Clear dquot pointers we don't want to dqput() */
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
transfer_from[cnt] = NULL;
- ret = NO_QUOTA;
goto warn_put_all;
}
-EXPORT_SYMBOL(dquot_transfer);
-/* Wrapper for transferring ownership of an inode */
-int vfs_dq_transfer(struct inode *inode, struct iattr *iattr)
+/* Wrapper for transferring ownership of an inode for uid/gid only
+ * Called from FSXXX_setattr()
+ */
+int dquot_transfer(struct inode *inode, struct iattr *iattr)
{
+ qid_t chid[MAXQUOTAS];
+ unsigned long mask = 0;
+
+ if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) {
+ mask |= 1 << USRQUOTA;
+ chid[USRQUOTA] = iattr->ia_uid;
+ }
+ if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) {
+ mask |= 1 << GRPQUOTA;
+ chid[GRPQUOTA] = iattr->ia_gid;
+ }
if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) {
- vfs_dq_init(inode);
- if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA)
- return 1;
+ dquot_initialize(inode);
+ return __dquot_transfer(inode, chid, mask);
}
return 0;
}
-EXPORT_SYMBOL(vfs_dq_transfer);
+EXPORT_SYMBOL(dquot_transfer);
/*
* Write info of quota file to disk
@@ -1798,13 +1823,6 @@ EXPORT_SYMBOL(dquot_commit_info);
* Definitions of diskquota operations.
*/
const struct dquot_operations dquot_operations = {
- .initialize = dquot_initialize,
- .drop = dquot_drop,
- .alloc_space = dquot_alloc_space,
- .alloc_inode = dquot_alloc_inode,
- .free_space = dquot_free_space,
- .free_inode = dquot_free_inode,
- .transfer = dquot_transfer,
.write_dquot = dquot_commit,
.acquire_dquot = dquot_acquire,
.release_dquot = dquot_release,
@@ -1815,6 +1833,20 @@ const struct dquot_operations dquot_operations = {
};
/*
+ * Generic helper for ->open on filesystems supporting disk quotas.
+ */
+int dquot_file_open(struct inode *inode, struct file *file)
+{
+ int error;
+
+ error = generic_file_open(inode, file);
+ if (!error && (file->f_mode & FMODE_WRITE))
+ dquot_initialize(inode);
+ return error;
+}
+EXPORT_SYMBOL(dquot_file_open);
+
+/*
* Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
*/
int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
@@ -1993,11 +2025,13 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
}
if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
- /* As we bypass the pagecache we must now flush the inode so
- * that we see all the changes from userspace... */
- write_inode_now(inode, 1);
- /* And now flush the block cache so that kernel sees the
- * changes */
+ /* As we bypass the pagecache we must now flush all the
+ * dirty data and invalidate caches so that kernel sees
+ * changes from userspace. It is not enough to just flush
+ * the quota file since if blocksize < pagesize, invalidation
+ * of the cache could fail because of other unrelated dirty
+ * data */
+ sync_filesystem(sb);
invalidate_bdev(sb->s_bdev);
}
mutex_lock(&dqopt->dqonoff_mutex);
@@ -2010,14 +2044,16 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
/* We don't want quota and atime on quota files (deadlocks
* possible) Also nobody should write to the file - we use
* special IO operations which ignore the immutable bit. */
- down_write(&dqopt->dqptr_sem);
mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE |
S_NOQUOTA);
inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
mutex_unlock(&inode->i_mutex);
- up_write(&dqopt->dqptr_sem);
- sb->dq_op->drop(inode);
+ /*
+ * When S_NOQUOTA is set, remove dquot references as no more
+ * references can be added
+ */
+ __dquot_drop(inode);
}
error = -EIO;
@@ -2053,14 +2089,12 @@ out_file_init:
iput(inode);
out_lock:
if (oldflags != -1) {
- down_write(&dqopt->dqptr_sem);
mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
/* Set the flags back (in the case of accidental quotaon()
* on a wrong file we don't want to mess up the flags) */
inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE);
inode->i_flags |= oldflags;
mutex_unlock(&inode->i_mutex);
- up_write(&dqopt->dqptr_sem);
}
mutex_unlock(&dqopt->dqonoff_mutex);
out_fmt:
@@ -2292,34 +2326,34 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
if (di->dqb_valid & QIF_SPACE) {
dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
check_blim = 1;
- __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
+ set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
}
if (di->dqb_valid & QIF_BLIMITS) {
dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
check_blim = 1;
- __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
+ set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
}
if (di->dqb_valid & QIF_INODES) {
dm->dqb_curinodes = di->dqb_curinodes;
check_ilim = 1;
- __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
+ set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
}
if (di->dqb_valid & QIF_ILIMITS) {
dm->dqb_isoftlimit = di->dqb_isoftlimit;
dm->dqb_ihardlimit = di->dqb_ihardlimit;
check_ilim = 1;
- __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
+ set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
}
if (di->dqb_valid & QIF_BTIME) {
dm->dqb_btime = di->dqb_btime;
check_blim = 1;
- __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
+ set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
}
if (di->dqb_valid & QIF_ITIME) {
dm->dqb_itime = di->dqb_itime;
check_ilim = 1;
- __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
+ set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
}
if (check_blim) {
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
new file mode 100644
index 00000000000..d67908b407d
--- /dev/null
+++ b/fs/quota/netlink.c
@@ -0,0 +1,96 @@
+
+#include <linux/cred.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/quotaops.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+/* Netlink family structure for quota */
+static struct genl_family quota_genl_family = {
+ .id = GENL_ID_GENERATE,
+ .hdrsize = 0,
+ .name = "VFS_DQUOT",
+ .version = 1,
+ .maxattr = QUOTA_NL_A_MAX,
+};
+
+/**
+ * quota_send_warning - Send warning to userspace about exceeded quota
+ * @type: The quota type: USRQQUOTA, GRPQUOTA,...
+ * @id: The user or group id of the quota that was exceeded
+ * @dev: The device on which the fs is mounted (sb->s_dev)
+ * @warntype: The type of the warning: QUOTA_NL_...
+ *
+ * This can be used by filesystems (including those which don't use
+ * dquot) to send a message to userspace relating to quota limits.
+ *
+ */
+
+void quota_send_warning(short type, unsigned int id, dev_t dev,
+ const char warntype)
+{
+ static atomic_t seq;
+ struct sk_buff *skb;
+ void *msg_head;
+ int ret;
+ int msg_size = 4 * nla_total_size(sizeof(u32)) +
+ 2 * nla_total_size(sizeof(u64));
+
+ /* We have to allocate using GFP_NOFS as we are called from a
+ * filesystem performing write and thus further recursion into
+ * the fs to free some data could cause deadlocks. */
+ skb = genlmsg_new(msg_size, GFP_NOFS);
+ if (!skb) {
+ printk(KERN_ERR
+ "VFS: Not enough memory to send quota warning.\n");
+ return;
+ }
+ msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
+ &quota_genl_family, 0, QUOTA_NL_C_WARNING);
+ if (!msg_head) {
+ printk(KERN_ERR
+ "VFS: Cannot store netlink header in quota warning.\n");
+ goto err_out;
+ }
+ ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, type);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, id);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR, MAJOR(dev));
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev));
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
+ if (ret)
+ goto attr_err_out;
+ genlmsg_end(skb, msg_head);
+
+ genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
+ return;
+attr_err_out:
+ printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
+err_out:
+ kfree_skb(skb);
+}
+EXPORT_SYMBOL(quota_send_warning);
+
+static int __init quota_init(void)
+{
+ if (genl_register_family(&quota_genl_family) != 0)
+ printk(KERN_ERR
+ "VFS: Failed to create quota netlink interface.\n");
+ return 0;
+};
+
+module_init(quota_init);
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index ee91e275695..95388f9b735 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -10,7 +10,6 @@
#include <linux/slab.h>
#include <asm/current.h>
#include <asm/uaccess.h>
-#include <linux/compat.h>
#include <linux/kernel.h>
#include <linux/security.h>
#include <linux/syscalls.h>
@@ -18,220 +17,205 @@
#include <linux/capability.h>
#include <linux/quotaops.h>
#include <linux/types.h>
-#include <net/netlink.h>
-#include <net/genetlink.h>
+#include <linux/writeback.h>
-/* Check validity of generic quotactl commands */
-static int generic_quotactl_valid(struct super_block *sb, int type, int cmd,
- qid_t id)
+static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
+ qid_t id)
{
- if (type >= MAXQUOTAS)
- return -EINVAL;
- if (!sb && cmd != Q_SYNC)
- return -ENODEV;
- /* Is operation supported? */
- if (sb && !sb->s_qcop)
- return -ENOSYS;
-
switch (cmd) {
- case Q_GETFMT:
- break;
- case Q_QUOTAON:
- if (!sb->s_qcop->quota_on)
- return -ENOSYS;
- break;
- case Q_QUOTAOFF:
- if (!sb->s_qcop->quota_off)
- return -ENOSYS;
- break;
- case Q_SETINFO:
- if (!sb->s_qcop->set_info)
- return -ENOSYS;
- break;
- case Q_GETINFO:
- if (!sb->s_qcop->get_info)
- return -ENOSYS;
- break;
- case Q_SETQUOTA:
- if (!sb->s_qcop->set_dqblk)
- return -ENOSYS;
- break;
- case Q_GETQUOTA:
- if (!sb->s_qcop->get_dqblk)
- return -ENOSYS;
- break;
- case Q_SYNC:
- if (sb && !sb->s_qcop->quota_sync)
- return -ENOSYS;
+ /* these commands do not require any special privilegues */
+ case Q_GETFMT:
+ case Q_SYNC:
+ case Q_GETINFO:
+ case Q_XGETQSTAT:
+ case Q_XQUOTASYNC:
+ break;
+ /* allow to query information for dquots we "own" */
+ case Q_GETQUOTA:
+ case Q_XGETQUOTA:
+ if ((type == USRQUOTA && current_euid() == id) ||
+ (type == GRPQUOTA && in_egroup_p(id)))
break;
- default:
- return -EINVAL;
+ /*FALLTHROUGH*/
+ default:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
}
- /* Is quota turned on for commands which need it? */
- switch (cmd) {
- case Q_GETFMT:
- case Q_GETINFO:
- case Q_SETINFO:
- case Q_SETQUOTA:
- case Q_GETQUOTA:
- /* This is just an informative test so we are satisfied
- * without the lock */
- if (!sb_has_quota_active(sb, type))
- return -ESRCH;
- }
+ return security_quotactl(cmd, type, id, sb);
+}
- /* Check privileges */
- if (cmd == Q_GETQUOTA) {
- if (((type == USRQUOTA && current_euid() != id) ||
- (type == GRPQUOTA && !in_egroup_p(id))) &&
- !capable(CAP_SYS_ADMIN))
- return -EPERM;
+static int quota_sync_all(int type)
+{
+ struct super_block *sb;
+ int ret;
+
+ if (type >= MAXQUOTAS)
+ return -EINVAL;
+ ret = security_quotactl(Q_SYNC, type, 0, NULL);
+ if (ret)
+ return ret;
+
+ spin_lock(&sb_lock);
+restart:
+ list_for_each_entry(sb, &super_blocks, s_list) {
+ if (!sb->s_qcop || !sb->s_qcop->quota_sync)
+ continue;
+
+ sb->s_count++;
+ spin_unlock(&sb_lock);
+ down_read(&sb->s_umount);
+ if (sb->s_root)
+ sb->s_qcop->quota_sync(sb, type, 1);
+ up_read(&sb->s_umount);
+ spin_lock(&sb_lock);
+ if (__put_super_and_need_restart(sb))
+ goto restart;
}
- else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO)
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ spin_unlock(&sb_lock);
return 0;
}
-/* Check validity of XFS Quota Manager commands */
-static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd,
- qid_t id)
+static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
+ void __user *addr)
{
- if (type >= XQM_MAXQUOTAS)
- return -EINVAL;
- if (!sb)
- return -ENODEV;
- if (!sb->s_qcop)
- return -ENOSYS;
+ char *pathname;
+ int ret = -ENOSYS;
+
+ pathname = getname(addr);
+ if (IS_ERR(pathname))
+ return PTR_ERR(pathname);
+ if (sb->s_qcop->quota_on)
+ ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0);
+ putname(pathname);
+ return ret;
+}
- switch (cmd) {
- case Q_XQUOTAON:
- case Q_XQUOTAOFF:
- case Q_XQUOTARM:
- if (!sb->s_qcop->set_xstate)
- return -ENOSYS;
- break;
- case Q_XGETQSTAT:
- if (!sb->s_qcop->get_xstate)
- return -ENOSYS;
- break;
- case Q_XSETQLIM:
- if (!sb->s_qcop->set_xquota)
- return -ENOSYS;
- break;
- case Q_XGETQUOTA:
- if (!sb->s_qcop->get_xquota)
- return -ENOSYS;
- break;
- case Q_XQUOTASYNC:
- if (!sb->s_qcop->quota_sync)
- return -ENOSYS;
- break;
- default:
- return -EINVAL;
- }
+static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
+{
+ __u32 fmt;
- /* Check privileges */
- if (cmd == Q_XGETQUOTA) {
- if (((type == XQM_USRQUOTA && current_euid() != id) ||
- (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
- !capable(CAP_SYS_ADMIN))
- return -EPERM;
- } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ down_read(&sb_dqopt(sb)->dqptr_sem);
+ if (!sb_has_quota_active(sb, type)) {
+ up_read(&sb_dqopt(sb)->dqptr_sem);
+ return -ESRCH;
}
+ fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
+ up_read(&sb_dqopt(sb)->dqptr_sem);
+ if (copy_to_user(addr, &fmt, sizeof(fmt)))
+ return -EFAULT;
+ return 0;
+}
+static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
+{
+ struct if_dqinfo info;
+ int ret;
+
+ if (!sb_has_quota_active(sb, type))
+ return -ESRCH;
+ if (!sb->s_qcop->get_info)
+ return -ENOSYS;
+ ret = sb->s_qcop->get_info(sb, type, &info);
+ if (!ret && copy_to_user(addr, &info, sizeof(info)))
+ return -EFAULT;
+ return ret;
+}
+
+static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
+{
+ struct if_dqinfo info;
+
+ if (copy_from_user(&info, addr, sizeof(info)))
+ return -EFAULT;
+ if (!sb_has_quota_active(sb, type))
+ return -ESRCH;
+ if (!sb->s_qcop->set_info)
+ return -ENOSYS;
+ return sb->s_qcop->set_info(sb, type, &info);
+}
+
+static int quota_getquota(struct super_block *sb, int type, qid_t id,
+ void __user *addr)
+{
+ struct if_dqblk idq;
+ int ret;
+
+ if (!sb_has_quota_active(sb, type))
+ return -ESRCH;
+ if (!sb->s_qcop->get_dqblk)
+ return -ENOSYS;
+ ret = sb->s_qcop->get_dqblk(sb, type, id, &idq);
+ if (ret)
+ return ret;
+ if (copy_to_user(addr, &idq, sizeof(idq)))
+ return -EFAULT;
return 0;
}
-static int check_quotactl_valid(struct super_block *sb, int type, int cmd,
- qid_t id)
+static int quota_setquota(struct super_block *sb, int type, qid_t id,
+ void __user *addr)
{
- int error;
-
- if (XQM_COMMAND(cmd))
- error = xqm_quotactl_valid(sb, type, cmd, id);
- else
- error = generic_quotactl_valid(sb, type, cmd, id);
- if (!error)
- error = security_quotactl(cmd, type, id, sb);
- return error;
+ struct if_dqblk idq;
+
+ if (copy_from_user(&idq, addr, sizeof(idq)))
+ return -EFAULT;
+ if (!sb_has_quota_active(sb, type))
+ return -ESRCH;
+ if (!sb->s_qcop->set_dqblk)
+ return -ENOSYS;
+ return sb->s_qcop->set_dqblk(sb, type, id, &idq);
}
-#ifdef CONFIG_QUOTA
-void sync_quota_sb(struct super_block *sb, int type)
+static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
{
- int cnt;
+ __u32 flags;
- if (!sb->s_qcop->quota_sync)
- return;
+ if (copy_from_user(&flags, addr, sizeof(flags)))
+ return -EFAULT;
+ if (!sb->s_qcop->set_xstate)
+ return -ENOSYS;
+ return sb->s_qcop->set_xstate(sb, flags, cmd);
+}
- sb->s_qcop->quota_sync(sb, type);
+static int quota_getxstate(struct super_block *sb, void __user *addr)
+{
+ struct fs_quota_stat fqs;
+ int ret;
- if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
- return;
- /* This is not very clever (and fast) but currently I don't know about
- * any other simple way of getting quota data to disk and we must get
- * them there for userspace to be visible... */
- if (sb->s_op->sync_fs)
- sb->s_op->sync_fs(sb, 1);
- sync_blockdev(sb->s_bdev);
+ if (!sb->s_qcop->get_xstate)
+ return -ENOSYS;
+ ret = sb->s_qcop->get_xstate(sb, &fqs);
+ if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
+ return -EFAULT;
+ return ret;
+}
- /*
- * Now when everything is written we can discard the pagecache so
- * that userspace sees the changes.
- */
- mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
- for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
- if (type != -1 && cnt != type)
- continue;
- if (!sb_has_quota_active(sb, cnt))
- continue;
- mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex,
- I_MUTEX_QUOTA);
- truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0);
- mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex);
- }
- mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
+static int quota_setxquota(struct super_block *sb, int type, qid_t id,
+ void __user *addr)
+{
+ struct fs_disk_quota fdq;
+
+ if (copy_from_user(&fdq, addr, sizeof(fdq)))
+ return -EFAULT;
+ if (!sb->s_qcop->set_xquota)
+ return -ENOSYS;
+ return sb->s_qcop->set_xquota(sb, type, id, &fdq);
}
-#endif
-static void sync_dquots(int type)
+static int quota_getxquota(struct super_block *sb, int type, qid_t id,
+ void __user *addr)
{
- struct super_block *sb;
- int cnt;
+ struct fs_disk_quota fdq;
+ int ret;
- spin_lock(&sb_lock);
-restart:
- list_for_each_entry(sb, &super_blocks, s_list) {
- /* This test just improves performance so it needn't be
- * reliable... */
- for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
- if (type != -1 && type != cnt)
- continue;
- if (!sb_has_quota_active(sb, cnt))
- continue;
- if (!info_dirty(&sb_dqopt(sb)->info[cnt]) &&
- list_empty(&sb_dqopt(sb)->info[cnt].dqi_dirty_list))
- continue;
- break;
- }
- if (cnt == MAXQUOTAS)
- continue;
- sb->s_count++;
- spin_unlock(&sb_lock);
- down_read(&sb->s_umount);
- if (sb->s_root)
- sync_quota_sb(sb, type);
- up_read(&sb->s_umount);
- spin_lock(&sb_lock);
- if (__put_super_and_need_restart(sb))
- goto restart;
- }
- spin_unlock(&sb_lock);
+ if (!sb->s_qcop->get_xquota)
+ return -ENOSYS;
+ ret = sb->s_qcop->get_xquota(sb, type, id, &fdq);
+ if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
+ return -EFAULT;
+ return ret;
}
/* Copy parameters and call proper function */
@@ -240,117 +224,55 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
{
int ret;
+ if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
+ return -EINVAL;
+ if (!sb->s_qcop)
+ return -ENOSYS;
+
+ ret = check_quotactl_permission(sb, type, cmd, id);
+ if (ret < 0)
+ return ret;
+
switch (cmd) {
- case Q_QUOTAON: {
- char *pathname;
-
- pathname = getname(addr);
- if (IS_ERR(pathname))
- return PTR_ERR(pathname);
- ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0);
- putname(pathname);
- return ret;
- }
- case Q_QUOTAOFF:
- return sb->s_qcop->quota_off(sb, type, 0);
-
- case Q_GETFMT: {
- __u32 fmt;
-
- down_read(&sb_dqopt(sb)->dqptr_sem);
- if (!sb_has_quota_active(sb, type)) {
- up_read(&sb_dqopt(sb)->dqptr_sem);
- return -ESRCH;
- }
- fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
- up_read(&sb_dqopt(sb)->dqptr_sem);
- if (copy_to_user(addr, &fmt, sizeof(fmt)))
- return -EFAULT;
- return 0;
- }
- case Q_GETINFO: {
- struct if_dqinfo info;
-
- ret = sb->s_qcop->get_info(sb, type, &info);
- if (ret)
- return ret;
- if (copy_to_user(addr, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- case Q_SETINFO: {
- struct if_dqinfo info;
-
- if (copy_from_user(&info, addr, sizeof(info)))
- return -EFAULT;
- return sb->s_qcop->set_info(sb, type, &info);
- }
- case Q_GETQUOTA: {
- struct if_dqblk idq;
-
- ret = sb->s_qcop->get_dqblk(sb, type, id, &idq);
- if (ret)
- return ret;
- if (copy_to_user(addr, &idq, sizeof(idq)))
- return -EFAULT;
- return 0;
- }
- case Q_SETQUOTA: {
- struct if_dqblk idq;
-
- if (copy_from_user(&idq, addr, sizeof(idq)))
- return -EFAULT;
- return sb->s_qcop->set_dqblk(sb, type, id, &idq);
- }
- case Q_SYNC:
- if (sb)
- sync_quota_sb(sb, type);
- else
- sync_dquots(type);
- return 0;
-
- case Q_XQUOTAON:
- case Q_XQUOTAOFF:
- case Q_XQUOTARM: {
- __u32 flags;
-
- if (copy_from_user(&flags, addr, sizeof(flags)))
- return -EFAULT;
- return sb->s_qcop->set_xstate(sb, flags, cmd);
- }
- case Q_XGETQSTAT: {
- struct fs_quota_stat fqs;
-
- if ((ret = sb->s_qcop->get_xstate(sb, &fqs)))
- return ret;
- if (copy_to_user(addr, &fqs, sizeof(fqs)))
- return -EFAULT;
- return 0;
- }
- case Q_XSETQLIM: {
- struct fs_disk_quota fdq;
-
- if (copy_from_user(&fdq, addr, sizeof(fdq)))
- return -EFAULT;
- return sb->s_qcop->set_xquota(sb, type, id, &fdq);
- }
- case Q_XGETQUOTA: {
- struct fs_disk_quota fdq;
-
- ret = sb->s_qcop->get_xquota(sb, type, id, &fdq);
- if (ret)
- return ret;
- if (copy_to_user(addr, &fdq, sizeof(fdq)))
- return -EFAULT;
- return 0;
- }
- case Q_XQUOTASYNC:
- return sb->s_qcop->quota_sync(sb, type);
- /* We never reach here unless validity check is broken */
- default:
- BUG();
+ case Q_QUOTAON:
+ return quota_quotaon(sb, type, cmd, id, addr);
+ case Q_QUOTAOFF:
+ if (!sb->s_qcop->quota_off)
+ return -ENOSYS;
+ return sb->s_qcop->quota_off(sb, type, 0);
+ case Q_GETFMT:
+ return quota_getfmt(sb, type, addr);
+ case Q_GETINFO:
+ return quota_getinfo(sb, type, addr);
+ case Q_SETINFO:
+ return quota_setinfo(sb, type, addr);
+ case Q_GETQUOTA:
+ return quota_getquota(sb, type, id, addr);
+ case Q_SETQUOTA:
+ return quota_setquota(sb, type, id, addr);
+ case Q_SYNC:
+ if (!sb->s_qcop->quota_sync)
+ return -ENOSYS;
+ return sb->s_qcop->quota_sync(sb, type, 1);
+ case Q_XQUOTAON:
+ case Q_XQUOTAOFF:
+ case Q_XQUOTARM:
+ return quota_setxstate(sb, cmd, addr);
+ case Q_XGETQSTAT:
+ return quota_getxstate(sb, addr);
+ case Q_XSETQLIM:
+ return quota_setxquota(sb, type, id, addr);
+ case Q_XGETQUOTA:
+ return quota_getxquota(sb, type, id, addr);
+ case Q_XQUOTASYNC:
+ /* caller already holds s_umount */
+ if (sb->s_flags & MS_RDONLY)
+ return -EROFS;
+ writeback_inodes_sb(sb);
+ return 0;
+ default:
+ return -EINVAL;
}
- return 0;
}
/*
@@ -397,224 +319,23 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
cmds = cmd >> SUBCMDSHIFT;
type = cmd & SUBCMDMASK;
- if (cmds != Q_SYNC || special) {
- sb = quotactl_block(special);
- if (IS_ERR(sb))
- return PTR_ERR(sb);
+ /*
+ * As a special case Q_SYNC can be called without a specific device.
+ * It will iterate all superblocks that have quota enabled and call
+ * the sync action on each of them.
+ */
+ if (!special) {
+ if (cmds == Q_SYNC)
+ return quota_sync_all(type);
+ return -ENODEV;
}
- ret = check_quotactl_valid(sb, type, cmds, id);
- if (ret >= 0)
- ret = do_quotactl(sb, type, cmds, id, addr);
- if (sb)
- drop_super(sb);
+ sb = quotactl_block(special);
+ if (IS_ERR(sb))
+ return PTR_ERR(sb);
- return ret;
-}
-
-#if defined(CONFIG_COMPAT_FOR_U64_ALIGNMENT)
-/*
- * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
- * and is necessary due to alignment problems.
- */
-struct compat_if_dqblk {
- compat_u64 dqb_bhardlimit;
- compat_u64 dqb_bsoftlimit;
- compat_u64 dqb_curspace;
- compat_u64 dqb_ihardlimit;
- compat_u64 dqb_isoftlimit;
- compat_u64 dqb_curinodes;
- compat_u64 dqb_btime;
- compat_u64 dqb_itime;
- compat_uint_t dqb_valid;
-};
-
-/* XFS structures */
-struct compat_fs_qfilestat {
- compat_u64 dqb_bhardlimit;
- compat_u64 qfs_nblks;
- compat_uint_t qfs_nextents;
-};
-
-struct compat_fs_quota_stat {
- __s8 qs_version;
- __u16 qs_flags;
- __s8 qs_pad;
- struct compat_fs_qfilestat qs_uquota;
- struct compat_fs_qfilestat qs_gquota;
- compat_uint_t qs_incoredqs;
- compat_int_t qs_btimelimit;
- compat_int_t qs_itimelimit;
- compat_int_t qs_rtbtimelimit;
- __u16 qs_bwarnlimit;
- __u16 qs_iwarnlimit;
-};
-
-asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
- qid_t id, void __user *addr)
-{
- unsigned int cmds;
- struct if_dqblk __user *dqblk;
- struct compat_if_dqblk __user *compat_dqblk;
- struct fs_quota_stat __user *fsqstat;
- struct compat_fs_quota_stat __user *compat_fsqstat;
- compat_uint_t data;
- u16 xdata;
- long ret;
+ ret = do_quotactl(sb, type, cmds, id, addr);
- cmds = cmd >> SUBCMDSHIFT;
-
- switch (cmds) {
- case Q_GETQUOTA:
- dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
- compat_dqblk = addr;
- ret = sys_quotactl(cmd, special, id, dqblk);
- if (ret)
- break;
- if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) ||
- get_user(data, &dqblk->dqb_valid) ||
- put_user(data, &compat_dqblk->dqb_valid))
- ret = -EFAULT;
- break;
- case Q_SETQUOTA:
- dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
- compat_dqblk = addr;
- ret = -EFAULT;
- if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) ||
- get_user(data, &compat_dqblk->dqb_valid) ||
- put_user(data, &dqblk->dqb_valid))
- break;
- ret = sys_quotactl(cmd, special, id, dqblk);
- break;
- case Q_XGETQSTAT:
- fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat));
- compat_fsqstat = addr;
- ret = sys_quotactl(cmd, special, id, fsqstat);
- if (ret)
- break;
- ret = -EFAULT;
- /* Copying qs_version, qs_flags, qs_pad */
- if (copy_in_user(compat_fsqstat, fsqstat,
- offsetof(struct compat_fs_quota_stat, qs_uquota)))
- break;
- /* Copying qs_uquota */
- if (copy_in_user(&compat_fsqstat->qs_uquota,
- &fsqstat->qs_uquota,
- sizeof(compat_fsqstat->qs_uquota)) ||
- get_user(data, &fsqstat->qs_uquota.qfs_nextents) ||
- put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents))
- break;
- /* Copying qs_gquota */
- if (copy_in_user(&compat_fsqstat->qs_gquota,
- &fsqstat->qs_gquota,
- sizeof(compat_fsqstat->qs_gquota)) ||
- get_user(data, &fsqstat->qs_gquota.qfs_nextents) ||
- put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents))
- break;
- /* Copying the rest */
- if (copy_in_user(&compat_fsqstat->qs_incoredqs,
- &fsqstat->qs_incoredqs,
- sizeof(struct compat_fs_quota_stat) -
- offsetof(struct compat_fs_quota_stat, qs_incoredqs)) ||
- get_user(xdata, &fsqstat->qs_iwarnlimit) ||
- put_user(xdata, &compat_fsqstat->qs_iwarnlimit))
- break;
- ret = 0;
- break;
- default:
- ret = sys_quotactl(cmd, special, id, addr);
- }
+ drop_super(sb);
return ret;
}
-#endif
-
-
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-
-/* Netlink family structure for quota */
-static struct genl_family quota_genl_family = {
- .id = GENL_ID_GENERATE,
- .hdrsize = 0,
- .name = "VFS_DQUOT",
- .version = 1,
- .maxattr = QUOTA_NL_A_MAX,
-};
-
-/**
- * quota_send_warning - Send warning to userspace about exceeded quota
- * @type: The quota type: USRQQUOTA, GRPQUOTA,...
- * @id: The user or group id of the quota that was exceeded
- * @dev: The device on which the fs is mounted (sb->s_dev)
- * @warntype: The type of the warning: QUOTA_NL_...
- *
- * This can be used by filesystems (including those which don't use
- * dquot) to send a message to userspace relating to quota limits.
- *
- */
-
-void quota_send_warning(short type, unsigned int id, dev_t dev,
- const char warntype)
-{
- static atomic_t seq;
- struct sk_buff *skb;
- void *msg_head;
- int ret;
- int msg_size = 4 * nla_total_size(sizeof(u32)) +
- 2 * nla_total_size(sizeof(u64));
-
- /* We have to allocate using GFP_NOFS as we are called from a
- * filesystem performing write and thus further recursion into
- * the fs to free some data could cause deadlocks. */
- skb = genlmsg_new(msg_size, GFP_NOFS);
- if (!skb) {
- printk(KERN_ERR
- "VFS: Not enough memory to send quota warning.\n");
- return;
- }
- msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
- &quota_genl_family, 0, QUOTA_NL_C_WARNING);
- if (!msg_head) {
- printk(KERN_ERR
- "VFS: Cannot store netlink header in quota warning.\n");
- goto err_out;
- }
- ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, type);
- if (ret)
- goto attr_err_out;
- ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, id);
- if (ret)
- goto attr_err_out;
- ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
- if (ret)
- goto attr_err_out;
- ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR, MAJOR(dev));
- if (ret)
- goto attr_err_out;
- ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev));
- if (ret)
- goto attr_err_out;
- ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
- if (ret)
- goto attr_err_out;
- genlmsg_end(skb, msg_head);
-
- genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
- return;
-attr_err_out:
- printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
-err_out:
- kfree_skb(skb);
-}
-EXPORT_SYMBOL(quota_send_warning);
-
-static int __init quota_init(void)
-{
- if (genl_register_family(&quota_genl_family) != 0)
- printk(KERN_ERR
- "VFS: Failed to create quota netlink interface.\n");
- return 0;
-};
-
-module_init(quota_init);
-#endif
-
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 1739a4aba25..5ea4ad81a42 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -21,6 +21,7 @@
#include <linux/pagevec.h>
#include <linux/mman.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include "internal.h"
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index a6090aa1a7c..c94853473ca 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -35,6 +35,7 @@
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/magic.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include "internal.h"
diff --git a/fs/read_write.c b/fs/read_write.c
index b7f4a1f94d4..113386d6fd2 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -258,6 +258,7 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
+ kiocb.ki_nbytes = len;
for (;;) {
ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
@@ -313,6 +314,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
+ kiocb.ki_nbytes = len;
for (;;) {
ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 65c87276117..483442e66ed 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -169,7 +169,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
return 0; // No free blocks in this bitmap
}
- /* search for a first zero bit -- beggining of a window */
+ /* search for a first zero bit -- beginning of a window */
*beg = reiserfs_find_next_zero_le_bit
((unsigned long *)(bh->b_data), boundary, *beg);
@@ -425,7 +425,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
journal_mark_dirty(th, s, sbh);
if (for_unformatted)
- vfs_dq_free_block_nodirty(inode, 1);
+ dquot_free_block_nodirty(inode, 1);
}
void reiserfs_free_block(struct reiserfs_transaction_handle *th,
@@ -1049,7 +1049,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
amount_needed, hint->inode->i_uid);
#endif
quota_ret =
- vfs_dq_alloc_block_nodirty(hint->inode, amount_needed);
+ dquot_alloc_block_nodirty(hint->inode, amount_needed);
if (quota_ret) /* Quota exceeded? */
return QUOTA_EXCEEDED;
if (hint->preallocate && hint->prealloc_size) {
@@ -1058,7 +1058,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
"reiserquota: allocating (prealloc) %d blocks id=%u",
hint->prealloc_size, hint->inode->i_uid);
#endif
- quota_ret = vfs_dq_prealloc_block_nodirty(hint->inode,
+ quota_ret = dquot_prealloc_block_nodirty(hint->inode,
hint->prealloc_size);
if (quota_ret)
hint->preallocate = hint->prealloc_size = 0;
@@ -1092,7 +1092,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
hint->inode->i_uid);
#endif
/* Free not allocated blocks */
- vfs_dq_free_block_nodirty(hint->inode,
+ dquot_free_block_nodirty(hint->inode,
amount_needed + hint->prealloc_size -
nr_allocated);
}
@@ -1125,7 +1125,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
REISERFS_I(hint->inode)->i_prealloc_count,
hint->inode->i_uid);
#endif
- vfs_dq_free_block_nodirty(hint->inode, amount_needed +
+ dquot_free_block_nodirty(hint->inode, amount_needed +
hint->prealloc_size - nr_allocated -
REISERFS_I(hint->inode)->
i_prealloc_count);
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index c094f58c744..07930449a95 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -8,6 +8,7 @@
#include <linux/reiserfs_fs.h>
#include <linux/stat.h>
#include <linux/buffer_head.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
extern const struct reiserfs_key MIN_KEY;
@@ -45,8 +46,6 @@ static inline bool is_privroot_deh(struct dentry *dir,
struct reiserfs_de_head *deh)
{
struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root;
- if (reiserfs_expose_privroot(dir->d_sb))
- return 0;
return (dir == dir->d_parent && privroot->d_inode &&
deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid);
}
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index da2dba082e2..1d9c12714c5 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -289,7 +289,7 @@ const struct file_operations reiserfs_file_operations = {
.compat_ioctl = reiserfs_compat_ioctl,
#endif
.mmap = reiserfs_file_mmap,
- .open = generic_file_open,
+ .open = dquot_file_open,
.release = reiserfs_file_release,
.fsync = reiserfs_sync_file,
.aio_read = generic_file_aio_read,
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 6591cb21edf..1e4250bc3a6 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -35,6 +35,7 @@
**/
#include <linux/time.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/reiserfs_fs.h>
#include <linux/buffer_head.h>
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 2df0f5c7c60..dc2c65e0485 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -11,6 +11,7 @@
#include <linux/smp_lock.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <linux/buffer_head.h>
@@ -34,6 +35,9 @@ void reiserfs_delete_inode(struct inode *inode)
int depth;
int err;
+ if (!is_bad_inode(inode))
+ dquot_initialize(inode);
+
truncate_inode_pages(&inode->i_data, 0);
depth = reiserfs_write_lock_once(inode->i_sb);
@@ -54,7 +58,7 @@ void reiserfs_delete_inode(struct inode *inode)
* after delete_object so that quota updates go into the same transaction as
* stat data deletion */
if (!err)
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
if (journal_end(&th, inode->i_sb, jbegin_count))
goto out;
@@ -1615,7 +1619,7 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
** to properly mark inodes for datasync and such, but only actually
** does something when called for a synchronous update.
*/
-int reiserfs_write_inode(struct inode *inode, int do_sync)
+int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct reiserfs_transaction_handle th;
int jbegin_count = 1;
@@ -1627,7 +1631,7 @@ int reiserfs_write_inode(struct inode *inode, int do_sync)
** inode needs to reach disk for safety, and they can safely be
** ignored because the altered inode has already been logged.
*/
- if (do_sync && !(current->flags & PF_MEMALLOC)) {
+ if (wbc->sync_mode == WB_SYNC_ALL && !(current->flags & PF_MEMALLOC)) {
reiserfs_write_lock(inode->i_sb);
if (!journal_begin(&th, inode->i_sb, jbegin_count)) {
reiserfs_update_sd(&th, inode);
@@ -1765,10 +1769,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
BUG_ON(!th->t_trans_id);
- if (vfs_dq_alloc_inode(inode)) {
- err = -EDQUOT;
+ dquot_initialize(inode);
+ err = dquot_alloc_inode(inode);
+ if (err)
goto out_end_trans;
- }
if (!dir->i_nlink) {
err = -EPERM;
goto out_bad_inode;
@@ -1959,12 +1963,12 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
INODE_PKEY(inode)->k_objectid = 0;
/* Quota change must be inside a transaction for journaling */
- vfs_dq_free_inode(inode);
+ dquot_free_inode(inode);
out_end_trans:
journal_end(th, th->t_super, th->t_blocks_allocated);
/* Drop can be outside and it needs more credits so it's better to have it outside */
- vfs_dq_drop(inode);
+ dquot_drop(inode);
inode->i_flags |= S_NOQUOTA;
make_bad_inode(inode);
@@ -3073,6 +3077,8 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
depth = reiserfs_write_lock_once(inode->i_sb);
if (attr->ia_valid & ATTR_SIZE) {
+ dquot_initialize(inode);
+
/* version 2 items will be caught by the s_maxbytes check
** done for us in vmtruncate
*/
@@ -3134,8 +3140,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
jbegin_count);
if (error)
goto out;
- error =
- vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+ error = dquot_transfer(inode, attr);
if (error) {
journal_end(&th, inode->i_sb,
jbegin_count);
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index ba98546fabb..19fbc810e8e 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -50,6 +50,7 @@
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <asm/system.h>
@@ -2217,6 +2218,15 @@ static int journal_read_transaction(struct super_block *sb,
brelse(d_bh);
return 1;
}
+
+ if (bdev_read_only(sb->s_bdev)) {
+ reiserfs_warning(sb, "clm-2076",
+ "device is readonly, unable to replay log");
+ brelse(c_bh);
+ brelse(d_bh);
+ return -EROFS;
+ }
+
trans_id = get_desc_trans_id(desc);
/* now we know we've got a good transaction, and it was inside the valid time ranges */
log_blocks = kmalloc(get_desc_trans_len(desc) *
@@ -2459,12 +2469,6 @@ static int journal_read(struct super_block *sb)
goto start_log_replay;
}
- if (continue_replay && bdev_read_only(sb->s_bdev)) {
- reiserfs_warning(sb, "clm-2076",
- "device is readonly, unable to replay log");
- return -1;
- }
-
/* ok, there are transactions that need to be replayed. start with the first log block, find
** all the valid transactions, and pick out the oldest.
*/
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 9d4dcf0b07c..d0c43cb99ff 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -13,6 +13,7 @@
#include <linux/time.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
@@ -546,7 +547,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
*/
static int drop_new_inode(struct inode *inode)
{
- vfs_dq_drop(inode);
+ dquot_drop(inode);
make_bad_inode(inode);
inode->i_flags |= S_NOQUOTA;
iput(inode);
@@ -554,7 +555,7 @@ static int drop_new_inode(struct inode *inode)
}
/* utility function that does setup for reiserfs_new_inode.
-** vfs_dq_init needs lots of credits so it's better to have it
+** dquot_initialize needs lots of credits so it's better to have it
** outside of a transaction, so we had to pull some bits of
** reiserfs_new_inode out into this func.
*/
@@ -577,7 +578,7 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode)
} else {
inode->i_gid = current_fsgid();
}
- vfs_dq_init(inode);
+ dquot_initialize(inode);
return 0;
}
@@ -594,6 +595,8 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode,
struct reiserfs_transaction_handle th;
struct reiserfs_security_handle security;
+ dquot_initialize(dir);
+
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM;
}
@@ -666,6 +669,8 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
if (!new_valid_dev(rdev))
return -EINVAL;
+ dquot_initialize(dir);
+
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM;
}
@@ -739,6 +744,8 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
+ dquot_initialize(dir);
+
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
/* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */
REISERFS_I(dir)->new_packing_locality = 1;
@@ -842,6 +849,8 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
JOURNAL_PER_BALANCE_CNT * 2 + 2 +
4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
+ dquot_initialize(dir);
+
reiserfs_write_lock(dir->i_sb);
retval = journal_begin(&th, dir->i_sb, jbegin_count);
if (retval)
@@ -923,6 +932,8 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry)
unsigned long savelink;
int depth;
+ dquot_initialize(dir);
+
inode = dentry->d_inode;
/* in this transaction we can be doing at max two balancings and update
@@ -1024,6 +1035,8 @@ static int reiserfs_symlink(struct inode *parent_dir,
2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) +
REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb));
+ dquot_initialize(parent_dir);
+
if (!(inode = new_inode(parent_dir->i_sb))) {
return -ENOMEM;
}
@@ -1111,6 +1124,8 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir,
JOURNAL_PER_BALANCE_CNT * 3 +
2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
+ dquot_initialize(dir);
+
reiserfs_write_lock(dir->i_sb);
if (inode->i_nlink >= REISERFS_LINK_MAX) {
//FIXME: sd_nlink is 32 bit for new files
@@ -1235,6 +1250,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
JOURNAL_PER_BALANCE_CNT * 3 + 5 +
4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb);
+ dquot_initialize(old_dir);
+ dquot_initialize(new_dir);
+
old_inode = old_dentry->d_inode;
new_dentry_inode = new_dentry->d_inode;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 5fa7118f04e..313d39d639e 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -1299,7 +1299,7 @@ int reiserfs_delete_item(struct reiserfs_transaction_handle *th,
"reiserquota delete_item(): freeing %u, id=%u type=%c",
quota_cut_bytes, inode->i_uid, head2type(&s_ih));
#endif
- vfs_dq_free_space_nodirty(inode, quota_cut_bytes);
+ dquot_free_space_nodirty(inode, quota_cut_bytes);
/* Return deleted body length */
return ret_value;
@@ -1383,7 +1383,7 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th,
quota_cut_bytes, inode->i_uid,
key2type(key));
#endif
- vfs_dq_free_space_nodirty(inode,
+ dquot_free_space_nodirty(inode,
quota_cut_bytes);
}
break;
@@ -1733,7 +1733,7 @@ int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th,
"reiserquota cut_from_item(): freeing %u id=%u type=%c",
quota_cut_bytes, inode->i_uid, '?');
#endif
- vfs_dq_free_space_nodirty(inode, quota_cut_bytes);
+ dquot_free_space_nodirty(inode, quota_cut_bytes);
return ret_value;
}
@@ -1968,9 +1968,10 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
key2type(&(key->on_disk_key)));
#endif
- if (vfs_dq_alloc_space_nodirty(inode, pasted_size)) {
+ retval = dquot_alloc_space_nodirty(inode, pasted_size);
+ if (retval) {
pathrelse(search_path);
- return -EDQUOT;
+ return retval;
}
init_tb_struct(th, &s_paste_balance, th->t_super, search_path,
pasted_size);
@@ -2024,7 +2025,7 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
pasted_size, inode->i_uid,
key2type(&(key->on_disk_key)));
#endif
- vfs_dq_free_space_nodirty(inode, pasted_size);
+ dquot_free_space_nodirty(inode, pasted_size);
return retval;
}
@@ -2062,9 +2063,10 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
#endif
/* We can't dirty inode here. It would be immediately written but
* appropriate stat item isn't inserted yet... */
- if (vfs_dq_alloc_space_nodirty(inode, quota_bytes)) {
+ retval = dquot_alloc_space_nodirty(inode, quota_bytes);
+ if (retval) {
pathrelse(path);
- return -EDQUOT;
+ return retval;
}
}
init_tb_struct(th, &s_ins_balance, th->t_super, path,
@@ -2113,6 +2115,6 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
quota_bytes, inode->i_uid, head2type(ih));
#endif
if (inode)
- vfs_dq_free_space_nodirty(inode, quota_bytes);
+ dquot_free_space_nodirty(inode, quota_bytes);
return retval;
}
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index b4a7dd03bdb..59125fb36d4 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -12,6 +12,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/time.h>
#include <asm/uaccess.h>
@@ -246,7 +247,7 @@ static int finish_unfinished(struct super_block *s)
retval = remove_save_link_only(s, &save_link_key, 0);
continue;
}
- vfs_dq_init(inode);
+ dquot_initialize(inode);
if (truncate && S_ISDIR(inode->i_mode)) {
/* We got a truncate request for a dir which is impossible.
@@ -578,6 +579,11 @@ 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);
@@ -590,6 +596,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,
.put_super = reiserfs_put_super,
.write_super = reiserfs_write_super,
@@ -616,13 +623,6 @@ static int reiserfs_write_info(struct super_block *, int);
static int reiserfs_quota_on(struct super_block *, int, int, char *, int);
static const struct dquot_operations reiserfs_quota_operations = {
- .initialize = dquot_initialize,
- .drop = dquot_drop,
- .alloc_space = dquot_alloc_space,
- .alloc_inode = dquot_alloc_inode,
- .free_space = dquot_free_space,
- .free_inode = dquot_free_inode,
- .transfer = dquot_transfer,
.write_dquot = reiserfs_write_dquot,
.acquire_dquot = reiserfs_acquire_dquot,
.release_dquot = reiserfs_release_dquot,
@@ -1619,10 +1619,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
save_mount_options(s, data);
sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
- if (!sbi) {
- errval = -ENOMEM;
- goto error_alloc;
- }
+ if (!sbi)
+ return -ENOMEM;
s->s_fs_info = sbi;
/* Set default values for options: non-aggressive tails, RO on errors */
REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
@@ -1879,12 +1877,12 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
return (0);
error:
- reiserfs_write_unlock(s);
-error_alloc:
if (jinit_done) { /* kill the commit thread, free journal ram */
journal_release_error(NULL, s);
}
+ reiserfs_write_unlock(s);
+
reiserfs_free_bitmap_cache(s);
if (SB_BUFFER_WITH_SB(s))
brelse(SB_BUFFER_WITH_SB(s));
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 81f09fab8ae..e7cc00e636d 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -38,6 +38,7 @@
#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/pagemap.h>
@@ -61,7 +62,6 @@
static int xattr_create(struct inode *dir, struct dentry *dentry, int mode)
{
BUG_ON(!mutex_is_locked(&dir->i_mutex));
- vfs_dq_init(dir);
return dir->i_op->create(dir, dentry, mode, NULL);
}
#endif
@@ -69,7 +69,6 @@ static int xattr_create(struct inode *dir, struct dentry *dentry, int mode)
static int xattr_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
BUG_ON(!mutex_is_locked(&dir->i_mutex));
- vfs_dq_init(dir);
return dir->i_op->mkdir(dir, dentry, mode);
}
@@ -81,7 +80,6 @@ static int xattr_unlink(struct inode *dir, struct dentry *dentry)
{
int error;
BUG_ON(!mutex_is_locked(&dir->i_mutex));
- vfs_dq_init(dir);
reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex,
I_MUTEX_CHILD, dir->i_sb);
@@ -97,7 +95,6 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry)
{
int error;
BUG_ON(!mutex_is_locked(&dir->i_mutex));
- vfs_dq_init(dir);
reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex,
I_MUTEX_CHILD, dir->i_sb);
@@ -557,7 +554,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
if (!err && new_size < i_size_read(dentry->d_inode)) {
struct iattr newattrs = {
.ia_ctime = current_fs_time(inode->i_sb),
- .ia_size = buffer_size,
+ .ia_size = new_size,
.ia_valid = ATTR_SIZE | ATTR_CTIME,
};
@@ -976,21 +973,13 @@ int reiserfs_permission(struct inode *inode, int mask)
return generic_permission(inode, mask, NULL);
}
-/* This will catch lookups from the fs root to .reiserfs_priv */
-static int
-xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
+static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd)
{
- struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
- if (container_of(q1, struct dentry, d_name) == priv_root)
- return -ENOENT;
- if (q1->len == name->len &&
- !memcmp(q1->name, name->name, name->len))
- return 0;
- return 1;
+ return -EPERM;
}
static const struct dentry_operations xattr_lookup_poison_ops = {
- .d_compare = xattr_lookup_poison,
+ .d_revalidate = xattr_hide_revalidate,
};
int reiserfs_lookup_privroot(struct super_block *s)
@@ -1004,8 +993,7 @@ int reiserfs_lookup_privroot(struct super_block *s)
strlen(PRIVROOT_NAME));
if (!IS_ERR(dentry)) {
REISERFS_SB(s)->priv_root = dentry;
- if (!reiserfs_expose_privroot(s))
- s->s_root->d_op = &xattr_lookup_poison_ops;
+ dentry->d_op = &xattr_lookup_poison_ops;
if (dentry->d_inode)
dentry->d_inode->i_flags |= S_PRIVATE;
} else
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index dd20a7883f0..9cdb759645a 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -5,6 +5,7 @@
#include <linux/errno.h>
#include <linux/pagemap.h>
#include <linux/xattr.h>
+#include <linux/slab.h>
#include <linux/posix_acl_xattr.h>
#include <linux/reiserfs_xattr.h>
#include <linux/reiserfs_acl.h>
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index d8b5bfcbdd3..7271a477c04 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -3,6 +3,7 @@
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/xattr.h>
+#include <linux/slab.h>
#include <linux/reiserfs_xattr.h>
#include <linux/security.h>
#include <asm/uaccess.h>
@@ -76,7 +77,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
return error;
}
- if (sec->length) {
+ if (sec->length && reiserfs_xattrs_initialized(inode->i_sb)) {
blocks = reiserfs_xattr_jcreate_nblocks(inode) +
reiserfs_xattr_nblocks(inode, sec->length);
/* We don't want to count the directories twice if we have
diff --git a/fs/select.c b/fs/select.c
index fd38ce2e32e..500a669f779 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -691,6 +691,23 @@ SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
}
#endif /* HAVE_SET_RESTORE_SIGMASK */
+#ifdef __ARCH_WANT_SYS_OLD_SELECT
+struct sel_arg_struct {
+ unsigned long n;
+ fd_set __user *inp, *outp, *exp;
+ struct timeval __user *tvp;
+};
+
+SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg)
+{
+ struct sel_arg_struct a;
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ return -EFAULT;
+ return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+#endif
+
struct poll_list {
struct poll_list *next;
int len;
@@ -821,7 +838,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
struct poll_list *walk = head;
unsigned long todo = nfds;
- if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
+ if (nfds > rlimit(RLIMIT_NOFILE))
return -EINVAL;
len = min_t(unsigned int, nfds, N_STACK_PPS);
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 5afd554efad..e1f437be6c3 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -734,7 +734,7 @@ EXPORT_SYMBOL(seq_hlist_start_head);
* seq_hlist_next - move to the next position of the hlist
* @v: the current iterator
* @head: the head of the hlist
- * @pos: the current posision
+ * @ppos: the current position
*
* Called at seq_file->op->next().
*/
@@ -800,7 +800,7 @@ EXPORT_SYMBOL(seq_hlist_start_head_rcu);
* seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
* @v: the current iterator
* @head: the head of the hlist
- * @pos: the current posision
+ * @ppos: the current position
*
* Called at seq_file->op->next().
*
diff --git a/fs/signalfd.c b/fs/signalfd.c
index 1dabe4ee02f..f329849ce3c 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/list.h>
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index 92d5e8ffb63..dbf6548bbf0 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -13,7 +13,6 @@
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
#include <linux/net.h>
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 1c4c8f08997..dfa1d67f8fc 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -479,6 +479,7 @@ smb_put_super(struct super_block *sb)
if (server->conn_pid)
kill_pid(server->conn_pid, SIGTERM, 1);
+ bdi_destroy(&server->bdi);
kfree(server->ops);
smb_unload_nls(server);
sb->s_fs_info = NULL;
@@ -525,6 +526,11 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
if (!server)
goto out_no_server;
sb->s_fs_info = server;
+
+ if (bdi_setup_and_register(&server->bdi, "smbfs", BDI_CAP_MAP_COPY))
+ goto out_bdi;
+
+ sb->s_bdi = &server->bdi;
server->super_block = sb;
server->mnt = NULL;
@@ -624,6 +630,8 @@ out_no_smbiod:
out_bad_option:
kfree(mem);
out_no_mem:
+ bdi_destroy(&server->bdi);
+out_bdi:
if (!server->mnt)
printk(KERN_ERR "smb_fill_super: allocation failure\n");
sb->s_fs_info = NULL;
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
index 6bd9b691a46..0e39a924f10 100644
--- a/fs/smbfs/smbiod.c
+++ b/fs/smbfs/smbiod.c
@@ -12,7 +12,6 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/file.h>
#include <linux/dcache.h>
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
index 00b2909bd46..54350b59046 100644
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -15,6 +15,7 @@
#include <linux/pagemap.h>
#include <linux/net.h>
#include <linux/namei.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/fs/splice.c b/fs/splice.c
index 39208663aaf..9313b6124a2 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -30,6 +30,7 @@
#include <linux/syscalls.h>
#include <linux/uio.h>
#include <linux/security.h>
+#include <linux/gfp.h>
/*
* Attempt to steal a page from a pipe buffer. This should perhaps go into
diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile
index 70e3244fa30..df8a19ef870 100644
--- a/fs/squashfs/Makefile
+++ b/fs/squashfs/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_SQUASHFS) += squashfs.o
squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
-squashfs-y += namei.o super.o symlink.o
+squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index 2a796031034..653c030eb84 100644
--- a/fs/squashfs/block.c
+++ b/fs/squashfs/block.c
@@ -29,15 +29,14 @@
#include <linux/fs.h>
#include <linux/vfs.h>
#include <linux/slab.h>
-#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/buffer_head.h>
-#include <linux/zlib.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
#include "squashfs_fs_i.h"
#include "squashfs.h"
+#include "decompressor.h"
/*
* Read the metadata block length, this is stored in the first two
@@ -88,9 +87,8 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
u64 cur_index = index >> msblk->devblksize_log2;
int bytes, compressed, b = 0, k = 0, page = 0, avail;
-
- bh = kcalloc((msblk->block_size >> msblk->devblksize_log2) + 1,
- sizeof(*bh), GFP_KERNEL);
+ bh = kcalloc(((srclength + msblk->devblksize - 1)
+ >> msblk->devblksize_log2) + 1, sizeof(*bh), GFP_KERNEL);
if (bh == NULL)
return -ENOMEM;
@@ -153,72 +151,10 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
}
if (compressed) {
- int zlib_err = 0, zlib_init = 0;
-
- /*
- * Uncompress block.
- */
-
- mutex_lock(&msblk->read_data_mutex);
-
- msblk->stream.avail_out = 0;
- msblk->stream.avail_in = 0;
-
- bytes = length;
- do {
- if (msblk->stream.avail_in == 0 && k < b) {
- avail = min(bytes, msblk->devblksize - offset);
- bytes -= avail;
- wait_on_buffer(bh[k]);
- if (!buffer_uptodate(bh[k]))
- goto release_mutex;
-
- if (avail == 0) {
- offset = 0;
- put_bh(bh[k++]);
- continue;
- }
-
- msblk->stream.next_in = bh[k]->b_data + offset;
- msblk->stream.avail_in = avail;
- offset = 0;
- }
-
- if (msblk->stream.avail_out == 0 && page < pages) {
- msblk->stream.next_out = buffer[page++];
- msblk->stream.avail_out = PAGE_CACHE_SIZE;
- }
-
- if (!zlib_init) {
- zlib_err = zlib_inflateInit(&msblk->stream);
- if (zlib_err != Z_OK) {
- ERROR("zlib_inflateInit returned"
- " unexpected result 0x%x,"
- " srclength %d\n", zlib_err,
- srclength);
- goto release_mutex;
- }
- zlib_init = 1;
- }
-
- zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH);
-
- if (msblk->stream.avail_in == 0 && k < b)
- put_bh(bh[k++]);
- } while (zlib_err == Z_OK);
-
- if (zlib_err != Z_STREAM_END) {
- ERROR("zlib_inflate error, data probably corrupt\n");
- goto release_mutex;
- }
-
- zlib_err = zlib_inflateEnd(&msblk->stream);
- if (zlib_err != Z_OK) {
- ERROR("zlib_inflate error, data probably corrupt\n");
- goto release_mutex;
- }
- length = msblk->stream.total_out;
- mutex_unlock(&msblk->read_data_mutex);
+ length = squashfs_decompress(msblk, buffer, bh, b, offset,
+ length, srclength, pages);
+ if (length < 0)
+ goto read_failure;
} else {
/*
* Block is uncompressed.
@@ -255,9 +191,6 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
kfree(bh);
return length;
-release_mutex:
- mutex_unlock(&msblk->read_data_mutex);
-
block_release:
for (; k < b; k++)
put_bh(bh[k]);
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index 40c98fa6b5d..57314bee905 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -51,7 +51,6 @@
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
-#include <linux/zlib.h>
#include <linux/pagemap.h>
#include "squashfs_fs.h"
diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c
new file mode 100644
index 00000000000..157478da6ac
--- /dev/null
+++ b/fs/squashfs/decompressor.c
@@ -0,0 +1,68 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; 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,
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * decompressor.c
+ */
+
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/buffer_head.h>
+
+#include "squashfs_fs.h"
+#include "squashfs_fs_sb.h"
+#include "squashfs_fs_i.h"
+#include "decompressor.h"
+#include "squashfs.h"
+
+/*
+ * This file (and decompressor.h) implements a decompressor framework for
+ * Squashfs, allowing multiple decompressors to be easily supported
+ */
+
+static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = {
+ NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0
+};
+
+static const struct squashfs_decompressor squashfs_lzo_unsupported_comp_ops = {
+ NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
+};
+
+static const struct squashfs_decompressor squashfs_unknown_comp_ops = {
+ NULL, NULL, NULL, 0, "unknown", 0
+};
+
+static const struct squashfs_decompressor *decompressor[] = {
+ &squashfs_zlib_comp_ops,
+ &squashfs_lzma_unsupported_comp_ops,
+ &squashfs_lzo_unsupported_comp_ops,
+ &squashfs_unknown_comp_ops
+};
+
+
+const struct squashfs_decompressor *squashfs_lookup_decompressor(int id)
+{
+ int i;
+
+ for (i = 0; decompressor[i]->id; i++)
+ if (id == decompressor[i]->id)
+ break;
+
+ return decompressor[i];
+}
diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h
new file mode 100644
index 00000000000..7425f80783f
--- /dev/null
+++ b/fs/squashfs/decompressor.h
@@ -0,0 +1,55 @@
+#ifndef DECOMPRESSOR_H
+#define DECOMPRESSOR_H
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; 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,
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * decompressor.h
+ */
+
+struct squashfs_decompressor {
+ void *(*init)(struct squashfs_sb_info *);
+ void (*free)(void *);
+ int (*decompress)(struct squashfs_sb_info *, void **,
+ struct buffer_head **, int, int, int, int, int);
+ int id;
+ char *name;
+ int supported;
+};
+
+static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk)
+{
+ return msblk->decompressor->init(msblk);
+}
+
+static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk,
+ void *s)
+{
+ if (msblk->decompressor)
+ msblk->decompressor->free(s);
+}
+
+static inline int squashfs_decompress(struct squashfs_sb_info *msblk,
+ void **buffer, struct buffer_head **bh, int b, int offset, int length,
+ int srclength, int pages)
+{
+ return msblk->decompressor->decompress(msblk, buffer, bh, b, offset,
+ length, srclength, pages);
+}
+#endif
diff --git a/fs/squashfs/dir.c b/fs/squashfs/dir.c
index 566b0eaed86..12b933ac658 100644
--- a/fs/squashfs/dir.c
+++ b/fs/squashfs/dir.c
@@ -30,7 +30,6 @@
#include <linux/fs.h>
#include <linux/vfs.h>
#include <linux/slab.h>
-#include <linux/zlib.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
diff --git a/fs/squashfs/export.c b/fs/squashfs/export.c
index 2b1b8fe5e03..7f93d5a9ee0 100644
--- a/fs/squashfs/export.c
+++ b/fs/squashfs/export.c
@@ -39,7 +39,6 @@
#include <linux/vfs.h>
#include <linux/dcache.h>
#include <linux/exportfs.h>
-#include <linux/zlib.h>
#include <linux/slab.h>
#include "squashfs_fs.h"
diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
index 717767d831d..a25c5060bdc 100644
--- a/fs/squashfs/file.c
+++ b/fs/squashfs/file.c
@@ -47,7 +47,6 @@
#include <linux/string.h>
#include <linux/pagemap.h>
#include <linux/mutex.h>
-#include <linux/zlib.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
index b5a2c15bbbc..7c90bbd6879 100644
--- a/fs/squashfs/fragment.c
+++ b/fs/squashfs/fragment.c
@@ -36,7 +36,6 @@
#include <linux/fs.h>
#include <linux/vfs.h>
#include <linux/slab.h>
-#include <linux/zlib.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
diff --git a/fs/squashfs/id.c b/fs/squashfs/id.c
index 3795b837ba2..b7f64bcd2b7 100644
--- a/fs/squashfs/id.c
+++ b/fs/squashfs/id.c
@@ -34,7 +34,6 @@
#include <linux/fs.h>
#include <linux/vfs.h>
#include <linux/slab.h>
-#include <linux/zlib.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c
index 9101dbde39e..49daaf669e4 100644
--- a/fs/squashfs/inode.c
+++ b/fs/squashfs/inode.c
@@ -40,7 +40,6 @@
#include <linux/fs.h>
#include <linux/vfs.h>
-#include <linux/zlib.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c
index 9e398653b22..5266bd8ad93 100644
--- a/fs/squashfs/namei.c
+++ b/fs/squashfs/namei.c
@@ -57,7 +57,6 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/dcache.h>
-#include <linux/zlib.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
index 0e9feb6adf7..fe2587af551 100644
--- a/fs/squashfs/squashfs.h
+++ b/fs/squashfs/squashfs.h
@@ -51,6 +51,9 @@ extern struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *,
u64, int);
extern int squashfs_read_table(struct super_block *, void *, u64, int);
+/* decompressor.c */
+extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);
+
/* export.c */
extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64,
unsigned int);
@@ -71,7 +74,7 @@ extern struct inode *squashfs_iget(struct super_block *, long long,
extern int squashfs_read_inode(struct inode *, long long);
/*
- * Inodes and files operations
+ * Inodes, files and decompressor operations
*/
/* dir.c */
@@ -88,3 +91,6 @@ extern const struct inode_operations squashfs_dir_inode_ops;
/* symlink.c */
extern const struct address_space_operations squashfs_symlink_aops;
+
+/* zlib_wrapper.c */
+extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
index 283daafc568..79024245ea0 100644
--- a/fs/squashfs/squashfs_fs.h
+++ b/fs/squashfs/squashfs_fs.h
@@ -183,8 +183,6 @@
#define SQUASHFS_MAX_FILE_SIZE (1LL << \
(SQUASHFS_MAX_FILE_SIZE_LOG - 2))
-#define SQUASHFS_MARKER_BYTE 0xff
-
/* meta index cache */
#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
#define SQUASHFS_META_ENTRIES 127
@@ -211,7 +209,9 @@ struct meta_index {
/*
* definitions for structures on disk
*/
-#define ZLIB_COMPRESSION 1
+#define ZLIB_COMPRESSION 1
+#define LZMA_COMPRESSION 2
+#define LZO_COMPRESSION 3
struct squashfs_super_block {
__le32 s_magic;
diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h
index c8c65614dd1..2e77dc547e2 100644
--- a/fs/squashfs/squashfs_fs_sb.h
+++ b/fs/squashfs/squashfs_fs_sb.h
@@ -52,25 +52,25 @@ struct squashfs_cache_entry {
};
struct squashfs_sb_info {
- int devblksize;
- int devblksize_log2;
- struct squashfs_cache *block_cache;
- struct squashfs_cache *fragment_cache;
- struct squashfs_cache *read_page;
- int next_meta_index;
- __le64 *id_table;
- __le64 *fragment_index;
- unsigned int *fragment_index_2;
- struct mutex read_data_mutex;
- struct mutex meta_index_mutex;
- struct meta_index *meta_index;
- z_stream stream;
- __le64 *inode_lookup_table;
- u64 inode_table;
- u64 directory_table;
- unsigned int block_size;
- unsigned short block_log;
- long long bytes_used;
- unsigned int inodes;
+ const struct squashfs_decompressor *decompressor;
+ int devblksize;
+ int devblksize_log2;
+ struct squashfs_cache *block_cache;
+ struct squashfs_cache *fragment_cache;
+ struct squashfs_cache *read_page;
+ int next_meta_index;
+ __le64 *id_table;
+ __le64 *fragment_index;
+ struct mutex read_data_mutex;
+ struct mutex meta_index_mutex;
+ struct meta_index *meta_index;
+ void *stream;
+ __le64 *inode_lookup_table;
+ u64 inode_table;
+ u64 directory_table;
+ unsigned int block_size;
+ unsigned short block_log;
+ long long bytes_used;
+ unsigned int inodes;
};
#endif
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 6c197ef53ad..48b6f4a385a 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -35,34 +35,41 @@
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/zlib.h>
#include <linux/magic.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
#include "squashfs_fs_i.h"
#include "squashfs.h"
+#include "decompressor.h"
static struct file_system_type squashfs_fs_type;
static const struct super_operations squashfs_super_ops;
-static int supported_squashfs_filesystem(short major, short minor, short comp)
+static const struct squashfs_decompressor *supported_squashfs_filesystem(short
+ major, short minor, short id)
{
+ const struct squashfs_decompressor *decompressor;
+
if (major < SQUASHFS_MAJOR) {
ERROR("Major/Minor mismatch, older Squashfs %d.%d "
"filesystems are unsupported\n", major, minor);
- return -EINVAL;
+ return NULL;
} else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
ERROR("Major/Minor mismatch, trying to mount newer "
"%d.%d filesystem\n", major, minor);
ERROR("Please update your kernel\n");
- return -EINVAL;
+ return NULL;
}
- if (comp != ZLIB_COMPRESSION)
- return -EINVAL;
+ decompressor = squashfs_lookup_decompressor(id);
+ if (!decompressor->supported) {
+ ERROR("Filesystem uses \"%s\" compression. This is not "
+ "supported\n", decompressor->name);
+ return NULL;
+ }
- return 0;
+ return decompressor;
}
@@ -87,13 +94,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
}
msblk = sb->s_fs_info;
- msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(),
- GFP_KERNEL);
- if (msblk->stream.workspace == NULL) {
- ERROR("Failed to allocate zlib workspace\n");
- goto failure;
- }
-
sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
if (sblk == NULL) {
ERROR("Failed to allocate squashfs_super_block\n");
@@ -120,25 +120,25 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount;
}
+ err = -EINVAL;
+
/* Check it is a SQUASHFS superblock */
sb->s_magic = le32_to_cpu(sblk->s_magic);
if (sb->s_magic != SQUASHFS_MAGIC) {
if (!silent)
ERROR("Can't find a SQUASHFS superblock on %s\n",
bdevname(sb->s_bdev, b));
- err = -EINVAL;
goto failed_mount;
}
- /* Check the MAJOR & MINOR versions and compression type */
- err = supported_squashfs_filesystem(le16_to_cpu(sblk->s_major),
+ /* Check the MAJOR & MINOR versions and lookup compression type */
+ msblk->decompressor = supported_squashfs_filesystem(
+ le16_to_cpu(sblk->s_major),
le16_to_cpu(sblk->s_minor),
le16_to_cpu(sblk->compression));
- if (err < 0)
+ if (msblk->decompressor == NULL)
goto failed_mount;
- err = -EINVAL;
-
/*
* Check if there's xattrs in the filesystem. These are not
* supported in this version, so warn that they will be ignored.
@@ -205,6 +205,10 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
err = -ENOMEM;
+ msblk->stream = squashfs_decompressor_init(msblk);
+ if (msblk->stream == NULL)
+ goto failed_mount;
+
msblk->block_cache = squashfs_cache_init("metadata",
SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
if (msblk->block_cache == NULL)
@@ -271,7 +275,8 @@ allocate_root:
err = squashfs_read_inode(root, root_inode);
if (err) {
- iget_failed(root);
+ make_bad_inode(root);
+ iput(root);
goto failed_mount;
}
insert_inode_hash(root);
@@ -292,17 +297,16 @@ failed_mount:
squashfs_cache_delete(msblk->block_cache);
squashfs_cache_delete(msblk->fragment_cache);
squashfs_cache_delete(msblk->read_page);
+ squashfs_decompressor_free(msblk, msblk->stream);
kfree(msblk->inode_lookup_table);
kfree(msblk->fragment_index);
kfree(msblk->id_table);
- kfree(msblk->stream.workspace);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
kfree(sblk);
return err;
failure:
- kfree(msblk->stream.workspace);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
return -ENOMEM;
@@ -346,10 +350,11 @@ static void squashfs_put_super(struct super_block *sb)
squashfs_cache_delete(sbi->block_cache);
squashfs_cache_delete(sbi->fragment_cache);
squashfs_cache_delete(sbi->read_page);
+ squashfs_decompressor_free(sbi, sbi->stream);
kfree(sbi->id_table);
kfree(sbi->fragment_index);
kfree(sbi->meta_index);
- kfree(sbi->stream.workspace);
+ kfree(sbi->inode_lookup_table);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
}
diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c
index 83d87880aac..32b911f4ee3 100644
--- a/fs/squashfs/symlink.c
+++ b/fs/squashfs/symlink.c
@@ -33,10 +33,8 @@
#include <linux/fs.h>
#include <linux/vfs.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/pagemap.h>
-#include <linux/zlib.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c
new file mode 100644
index 00000000000..7a603874e48
--- /dev/null
+++ b/fs/squashfs/zlib_wrapper.c
@@ -0,0 +1,152 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; 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,
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * zlib_wrapper.c
+ */
+
+
+#include <linux/mutex.h>
+#include <linux/buffer_head.h>
+#include <linux/slab.h>
+#include <linux/zlib.h>
+
+#include "squashfs_fs.h"
+#include "squashfs_fs_sb.h"
+#include "squashfs_fs_i.h"
+#include "squashfs.h"
+#include "decompressor.h"
+
+static void *zlib_init(struct squashfs_sb_info *dummy)
+{
+ z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
+ if (stream == NULL)
+ goto failed;
+ stream->workspace = kmalloc(zlib_inflate_workspacesize(),
+ GFP_KERNEL);
+ if (stream->workspace == NULL)
+ goto failed;
+
+ return stream;
+
+failed:
+ ERROR("Failed to allocate zlib workspace\n");
+ kfree(stream);
+ return NULL;
+}
+
+
+static void zlib_free(void *strm)
+{
+ z_stream *stream = strm;
+
+ if (stream)
+ kfree(stream->workspace);
+ kfree(stream);
+}
+
+
+static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
+ struct buffer_head **bh, int b, int offset, int length, int srclength,
+ int pages)
+{
+ int zlib_err = 0, zlib_init = 0;
+ int avail, bytes, k = 0, page = 0;
+ z_stream *stream = msblk->stream;
+
+ mutex_lock(&msblk->read_data_mutex);
+
+ stream->avail_out = 0;
+ stream->avail_in = 0;
+
+ bytes = length;
+ do {
+ if (stream->avail_in == 0 && k < b) {
+ avail = min(bytes, msblk->devblksize - offset);
+ bytes -= avail;
+ wait_on_buffer(bh[k]);
+ if (!buffer_uptodate(bh[k]))
+ goto release_mutex;
+
+ if (avail == 0) {
+ offset = 0;
+ put_bh(bh[k++]);
+ continue;
+ }
+
+ stream->next_in = bh[k]->b_data + offset;
+ stream->avail_in = avail;
+ offset = 0;
+ }
+
+ if (stream->avail_out == 0 && page < pages) {
+ stream->next_out = buffer[page++];
+ stream->avail_out = PAGE_CACHE_SIZE;
+ }
+
+ if (!zlib_init) {
+ zlib_err = zlib_inflateInit(stream);
+ if (zlib_err != Z_OK) {
+ ERROR("zlib_inflateInit returned unexpected "
+ "result 0x%x, srclength %d\n",
+ zlib_err, srclength);
+ goto release_mutex;
+ }
+ zlib_init = 1;
+ }
+
+ zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
+
+ if (stream->avail_in == 0 && k < b)
+ put_bh(bh[k++]);
+ } while (zlib_err == Z_OK);
+
+ if (zlib_err != Z_STREAM_END) {
+ ERROR("zlib_inflate error, data probably corrupt\n");
+ goto release_mutex;
+ }
+
+ zlib_err = zlib_inflateEnd(stream);
+ if (zlib_err != Z_OK) {
+ ERROR("zlib_inflate error, data probably corrupt\n");
+ goto release_mutex;
+ }
+
+ length = stream->total_out;
+ mutex_unlock(&msblk->read_data_mutex);
+ return length;
+
+release_mutex:
+ mutex_unlock(&msblk->read_data_mutex);
+
+ for (; k < b; k++)
+ put_bh(bh[k]);
+
+ return -EIO;
+}
+
+const struct squashfs_decompressor squashfs_zlib_comp_ops = {
+ .init = zlib_init,
+ .free = zlib_free,
+ .decompress = zlib_uncompress,
+ .id = ZLIB_COMPRESSION,
+ .name = "zlib",
+ .supported = 1
+};
+
diff --git a/fs/super.c b/fs/super.c
index f35ac602210..1527e6a0ee3 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -37,6 +37,7 @@
#include <linux/kobject.h>
#include <linux/mutex.h>
#include <linux/file.h>
+#include <linux/backing-dev.h>
#include <asm/uaccess.h>
#include "internal.h"
@@ -693,6 +694,7 @@ int set_anon_super(struct super_block *s, void *data)
return -EMFILE;
}
s->s_dev = MKDEV(0, dev & MINORMASK);
+ s->s_bdi = &noop_backing_dev_info;
return 0;
}
@@ -954,10 +956,11 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
if (error < 0)
goto out_free_secdata;
BUG_ON(!mnt->mnt_sb);
+ WARN_ON(!mnt->mnt_sb->s_bdi);
- error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
- if (error)
- goto out_sb;
+ error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
+ if (error)
+ goto out_sb;
/*
* filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE
diff --git a/fs/sync.c b/fs/sync.c
index 418727a2a23..92b228176f7 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/writeback.h>
@@ -13,6 +14,7 @@
#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
+#include <linux/backing-dev.h>
#include "internal.h"
#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
@@ -31,17 +33,17 @@ static int __sync_filesystem(struct super_block *sb, int wait)
* This should be safe, as we require bdi backing to actually
* write out data in the first place
*/
- if (!sb->s_bdi)
+ if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info)
return 0;
- /* Avoid doing twice syncing and cache pruning for quota sync */
- if (!wait) {
- writeout_quota_sb(sb, -1);
- writeback_inodes_sb(sb);
- } else {
- sync_quota_sb(sb, -1);
+ if (sb->s_qcop && sb->s_qcop->quota_sync)
+ sb->s_qcop->quota_sync(sb, -1, wait);
+
+ if (wait)
sync_inodes_sb(sb);
- }
+ else
+ writeback_inodes_sb(sb);
+
if (sb->s_op->sync_fs)
sb->s_op->sync_fs(sb, wait);
return __sync_blockdev(sb->s_bdev, wait);
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index a0a500af24a..e9d293593e5 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -54,14 +54,14 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
int rc;
/* need attr_sd for attr, its parent for kobj */
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return -ENODEV;
rc = -EIO;
if (attr->read)
rc = attr->read(kobj, attr, buffer, off, count);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return rc;
}
@@ -125,14 +125,14 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
int rc;
/* need attr_sd for attr, its parent for kobj */
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return -ENODEV;
rc = -EIO;
if (attr->write)
rc = attr->write(kobj, attr, buffer, offset, count);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return rc;
}
@@ -184,12 +184,12 @@ static void bin_vma_open(struct vm_area_struct *vma)
if (!bb->vm_ops || !bb->vm_ops->open)
return;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return;
bb->vm_ops->open(vma);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
}
static void bin_vma_close(struct vm_area_struct *vma)
@@ -201,12 +201,12 @@ static void bin_vma_close(struct vm_area_struct *vma)
if (!bb->vm_ops || !bb->vm_ops->close)
return;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return;
bb->vm_ops->close(vma);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
}
static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -219,12 +219,12 @@ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
if (!bb->vm_ops || !bb->vm_ops->fault)
return VM_FAULT_SIGBUS;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return VM_FAULT_SIGBUS;
ret = bb->vm_ops->fault(vma, vmf);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return ret;
}
@@ -241,12 +241,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
if (!bb->vm_ops->page_mkwrite)
return 0;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return VM_FAULT_SIGBUS;
ret = bb->vm_ops->page_mkwrite(vma, vmf);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return ret;
}
@@ -261,12 +261,12 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr,
if (!bb->vm_ops || !bb->vm_ops->access)
return -EINVAL;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return -EINVAL;
ret = bb->vm_ops->access(vma, addr, buf, len, write);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return ret;
}
@@ -281,12 +281,12 @@ static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
if (!bb->vm_ops || !bb->vm_ops->set_policy)
return 0;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return -EINVAL;
ret = bb->vm_ops->set_policy(vma, new);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return ret;
}
@@ -301,12 +301,12 @@ static struct mempolicy *bin_get_policy(struct vm_area_struct *vma,
if (!bb->vm_ops || !bb->vm_ops->get_policy)
return vma->vm_policy;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return vma->vm_policy;
pol = bb->vm_ops->get_policy(vma, addr);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return pol;
}
@@ -321,12 +321,12 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
if (!bb->vm_ops || !bb->vm_ops->migrate)
return 0;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return 0;
ret = bb->vm_ops->migrate(vma, from, to, flags);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return ret;
}
#endif
@@ -356,7 +356,7 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
/* need attr_sd for attr, its parent for kobj */
rc = -ENODEV;
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
goto out_unlock;
rc = -EINVAL;
@@ -384,7 +384,7 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
bb->vm_ops = vma->vm_ops;
vma->vm_ops = &bin_vm_ops;
out_put:
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
out_unlock:
mutex_unlock(&bb->mutex);
@@ -399,7 +399,7 @@ static int open(struct inode * inode, struct file * file)
int error;
/* binary file operations requires both @sd and its parent */
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return -ENODEV;
error = -EACCES;
@@ -426,11 +426,11 @@ static int open(struct inode * inode, struct file * file)
mutex_unlock(&sysfs_bin_lock);
/* open succeeded, put active references */
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return 0;
err_out:
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
kfree(bb);
return error;
}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 699f371b9f1..590717861c7 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -93,7 +93,7 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
* RETURNS:
* Pointer to @sd on success, NULL on failure.
*/
-static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
+struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
{
if (unlikely(!sd))
return NULL;
@@ -124,7 +124,7 @@ static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
* Put an active reference to @sd. This function is noop if @sd
* is NULL.
*/
-static void sysfs_put_active(struct sysfs_dirent *sd)
+void sysfs_put_active(struct sysfs_dirent *sd)
{
struct completion *cmpl;
int v;
@@ -145,45 +145,6 @@ static void sysfs_put_active(struct sysfs_dirent *sd)
}
/**
- * sysfs_get_active_two - get active references to sysfs_dirent and parent
- * @sd: sysfs_dirent of interest
- *
- * Get active reference to @sd and its parent. Parent's active
- * reference is grabbed first. This function is noop if @sd is
- * NULL.
- *
- * RETURNS:
- * Pointer to @sd on success, NULL on failure.
- */
-struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd)
-{
- if (sd) {
- if (sd->s_parent && unlikely(!sysfs_get_active(sd->s_parent)))
- return NULL;
- if (unlikely(!sysfs_get_active(sd))) {
- sysfs_put_active(sd->s_parent);
- return NULL;
- }
- }
- return sd;
-}
-
-/**
- * sysfs_put_active_two - put active references to sysfs_dirent and parent
- * @sd: sysfs_dirent of interest
- *
- * Put active references to @sd and its parent. This function is
- * noop if @sd is NULL.
- */
-void sysfs_put_active_two(struct sysfs_dirent *sd)
-{
- if (sd) {
- sysfs_put_active(sd);
- sysfs_put_active(sd->s_parent);
- }
-}
-
-/**
* sysfs_deactivate - deactivate sysfs_dirent
* @sd: sysfs_dirent to deactivate
*
@@ -195,6 +156,10 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
int v;
BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED));
+
+ if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF))
+ return;
+
sd->s_sibling = (void *)&wait;
rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_);
@@ -354,7 +319,6 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
atomic_set(&sd->s_count, 1);
atomic_set(&sd->s_active, 0);
- sysfs_dirent_init_lockdep(sd);
sd->s_name = name;
sd->s_mode = mode;
@@ -681,7 +645,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
}
/* attach dentry and inode */
- inode = sysfs_get_inode(sd);
+ inode = sysfs_get_inode(dir->i_sb, sd);
if (!inode) {
ret = ERR_PTR(-ENOMEM);
goto out_unlock;
@@ -837,11 +801,46 @@ static inline unsigned char dt_type(struct sysfs_dirent *sd)
return (sd->s_mode >> 12) & 15;
}
+static int sysfs_dir_release(struct inode *inode, struct file *filp)
+{
+ sysfs_put(filp->private_data);
+ return 0;
+}
+
+static struct sysfs_dirent *sysfs_dir_pos(struct sysfs_dirent *parent_sd,
+ ino_t ino, struct sysfs_dirent *pos)
+{
+ if (pos) {
+ int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) &&
+ pos->s_parent == parent_sd &&
+ ino == pos->s_ino;
+ sysfs_put(pos);
+ if (valid)
+ return pos;
+ }
+ pos = NULL;
+ if ((ino > 1) && (ino < INT_MAX)) {
+ pos = parent_sd->s_dir.children;
+ while (pos && (ino > pos->s_ino))
+ pos = pos->s_sibling;
+ }
+ return pos;
+}
+
+static struct sysfs_dirent *sysfs_dir_next_pos(struct sysfs_dirent *parent_sd,
+ ino_t ino, struct sysfs_dirent *pos)
+{
+ pos = sysfs_dir_pos(parent_sd, ino, pos);
+ if (pos)
+ pos = pos->s_sibling;
+ return pos;
+}
+
static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
struct dentry *dentry = filp->f_path.dentry;
struct sysfs_dirent * parent_sd = dentry->d_fsdata;
- struct sysfs_dirent *pos;
+ struct sysfs_dirent *pos = filp->private_data;
ino_t ino;
if (filp->f_pos == 0) {
@@ -857,29 +856,31 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
filp->f_pos++;
}
- if ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) {
- mutex_lock(&sysfs_mutex);
-
- /* Skip the dentries we have already reported */
- pos = parent_sd->s_dir.children;
- while (pos && (filp->f_pos > pos->s_ino))
- pos = pos->s_sibling;
-
- for ( ; pos; pos = pos->s_sibling) {
- const char * name;
- int len;
-
- name = pos->s_name;
- len = strlen(name);
- filp->f_pos = ino = pos->s_ino;
+ mutex_lock(&sysfs_mutex);
+ for (pos = sysfs_dir_pos(parent_sd, filp->f_pos, pos);
+ pos;
+ pos = sysfs_dir_next_pos(parent_sd, filp->f_pos, pos)) {
+ const char * name;
+ unsigned int type;
+ int len, ret;
+
+ name = pos->s_name;
+ len = strlen(name);
+ ino = pos->s_ino;
+ type = dt_type(pos);
+ filp->f_pos = ino;
+ filp->private_data = sysfs_get(pos);
- if (filldir(dirent, name, len, filp->f_pos, ino,
- dt_type(pos)) < 0)
- break;
- }
- if (!pos)
- filp->f_pos = INT_MAX;
mutex_unlock(&sysfs_mutex);
+ ret = filldir(dirent, name, len, filp->f_pos, ino, type);
+ mutex_lock(&sysfs_mutex);
+ if (ret < 0)
+ break;
+ }
+ mutex_unlock(&sysfs_mutex);
+ if ((filp->f_pos > 1) && !pos) { /* EOF */
+ filp->f_pos = INT_MAX;
+ filp->private_data = NULL;
}
return 0;
}
@@ -888,5 +889,6 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
const struct file_operations sysfs_dir_operations = {
.read = generic_read_dir,
.readdir = sysfs_readdir,
+ .release = sysfs_dir_release,
.llseek = generic_file_llseek,
};
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index dc30d9e3168..e222b258274 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -53,7 +53,7 @@ struct sysfs_buffer {
size_t count;
loff_t pos;
char * page;
- struct sysfs_ops * ops;
+ const struct sysfs_ops * ops;
struct mutex mutex;
int needs_read_fill;
int event;
@@ -75,7 +75,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
{
struct sysfs_dirent *attr_sd = dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
- struct sysfs_ops * ops = buffer->ops;
+ const struct sysfs_ops * ops = buffer->ops;
int ret = 0;
ssize_t count;
@@ -85,13 +85,13 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
return -ENOMEM;
/* need attr_sd for attr and ops, its parent for kobj */
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return -ENODEV;
buffer->event = atomic_read(&attr_sd->s_attr.open->event);
count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
/*
* The code works fine with PAGE_SIZE return but it's likely to
@@ -199,16 +199,16 @@ flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t
{
struct sysfs_dirent *attr_sd = dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
- struct sysfs_ops * ops = buffer->ops;
+ const struct sysfs_ops * ops = buffer->ops;
int rc;
/* need attr_sd for attr and ops, its parent for kobj */
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return -ENODEV;
rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return rc;
}
@@ -335,7 +335,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
struct sysfs_buffer *buffer;
- struct sysfs_ops *ops;
+ const struct sysfs_ops *ops;
int error = -EACCES;
char *p;
@@ -344,7 +344,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
memmove(last_sysfs_file, p, strlen(p) + 1);
/* need attr_sd for attr and ops, its parent for kobj */
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
return -ENODEV;
/* every kobject with an attribute needs a ktype assigned */
@@ -393,13 +393,13 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
goto err_free;
/* open succeeded, put active references */
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return 0;
err_free:
kfree(buffer);
err_out:
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
return error;
}
@@ -437,12 +437,12 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
struct sysfs_open_dirent *od = attr_sd->s_attr.open;
/* need parent for the kobj, grab both */
- if (!sysfs_get_active_two(attr_sd))
+ if (!sysfs_get_active(attr_sd))
goto trigger;
poll_wait(filp, &od->poll, wait);
- sysfs_put_active_two(attr_sd);
+ sysfs_put_active(attr_sd);
if (buffer->event != atomic_read(&od->event))
goto trigger;
@@ -509,6 +509,7 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
if (!sd)
return -ENOMEM;
sd->s_attr.attr = (void *)attr;
+ sysfs_dirent_init_lockdep(sd);
sysfs_addrm_start(&acxt, dir_sd);
rc = sysfs_add_one(&acxt, sd);
@@ -542,6 +543,18 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
}
+int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
+{
+ int err = 0;
+ int i;
+
+ for (i = 0; ptr[i] && !err; i++)
+ err = sysfs_create_file(kobj, ptr[i]);
+ if (err)
+ while (--i >= 0)
+ sysfs_remove_file(kobj, ptr[i]);
+ return err;
+}
/**
* sysfs_add_file_to_group - add an attribute file to a pre-existing group.
@@ -614,6 +627,12 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
sysfs_hash_and_remove(kobj->sd, attr->name);
}
+void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr)
+{
+ int i;
+ for (i = 0; ptr[i]; i++)
+ sysfs_remove_file(kobj, ptr[i]);
+}
/**
* sysfs_remove_file_from_group - remove an attribute file from a group.
@@ -732,3 +751,5 @@ EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
EXPORT_SYMBOL_GPL(sysfs_create_file);
EXPORT_SYMBOL_GPL(sysfs_remove_file);
+EXPORT_SYMBOL_GPL(sysfs_remove_files);
+EXPORT_SYMBOL_GPL(sysfs_create_files);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 6a06a1d1ea7..a4a0a941971 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -18,6 +18,7 @@
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/xattr.h>
#include <linux/security.h>
#include "sysfs.h"
@@ -111,20 +112,20 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
if (!sd)
return -EINVAL;
+ mutex_lock(&sysfs_mutex);
error = inode_change_ok(inode, iattr);
if (error)
- return error;
+ goto out;
iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
error = inode_setattr(inode, iattr);
if (error)
- return error;
+ goto out;
- mutex_lock(&sysfs_mutex);
error = sysfs_sd_setattr(sd, iattr);
+out:
mutex_unlock(&sysfs_mutex);
-
return error;
}
@@ -283,6 +284,7 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
/**
* sysfs_get_inode - get inode for sysfs_dirent
+ * @sb: super block
* @sd: sysfs_dirent to allocate inode for
*
* Get inode for @sd. If such inode doesn't exist, a new inode
@@ -295,11 +297,11 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
* RETURNS:
* Pointer to allocated inode on success, NULL on failure.
*/
-struct inode * sysfs_get_inode(struct sysfs_dirent *sd)
+struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
{
struct inode *inode;
- inode = iget_locked(sysfs_sb, sd->s_ino);
+ inode = iget_locked(sb, sd->s_ino);
if (inode && (inode->i_state & I_NEW))
sysfs_init_inode(sd, inode);
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 49749955cca..776137828dc 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -18,12 +18,12 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/magic.h>
+#include <linux/slab.h>
#include "sysfs.h"
static struct vfsmount *sysfs_mount;
-struct super_block * sysfs_sb = NULL;
struct kmem_cache *sysfs_dir_cachep;
static const struct super_operations sysfs_ops = {
@@ -50,11 +50,10 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_magic = SYSFS_MAGIC;
sb->s_op = &sysfs_ops;
sb->s_time_gran = 1;
- sysfs_sb = sb;
/* get root inode, initialize and unlock it */
mutex_lock(&sysfs_mutex);
- inode = sysfs_get_inode(&sysfs_root);
+ inode = sysfs_get_inode(sb, &sysfs_root);
mutex_unlock(&sysfs_mutex);
if (!inode) {
pr_debug("sysfs: could not get root inode\n");
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index c5eff49fa41..b93ec51fa7a 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -11,6 +11,7 @@
*/
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/mount.h>
#include <linux/module.h>
#include <linux/kobject.h>
@@ -123,6 +124,44 @@ void sysfs_remove_link(struct kobject * kobj, const char * name)
sysfs_hash_and_remove(parent_sd, name);
}
+/**
+ * sysfs_rename_link - rename symlink in object's directory.
+ * @kobj: object we're acting for.
+ * @targ: object we're pointing to.
+ * @old: previous name of the symlink.
+ * @new: new name of the symlink.
+ *
+ * A helper function for the common rename symlink idiom.
+ */
+int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
+ const char *old, const char *new)
+{
+ struct sysfs_dirent *parent_sd, *sd = NULL;
+ int result;
+
+ if (!kobj)
+ parent_sd = &sysfs_root;
+ else
+ parent_sd = kobj->sd;
+
+ result = -ENOENT;
+ sd = sysfs_get_dirent(parent_sd, old);
+ if (!sd)
+ goto out;
+
+ result = -EINVAL;
+ if (sysfs_type(sd) != SYSFS_KOBJ_LINK)
+ goto out;
+ if (sd->s_symlink.target_sd->s_dir.kobj != targ)
+ goto out;
+
+ result = sysfs_rename(sd, parent_sd, new);
+
+out:
+ sysfs_put(sd);
+ return result;
+}
+
static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
struct sysfs_dirent *target_sd, char *path)
{
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index cdd9377a6e0..30f5a44fb5d 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -66,8 +66,8 @@ struct sysfs_dirent {
};
unsigned int s_flags;
+ unsigned short s_mode;
ino_t s_ino;
- umode_t s_mode;
struct sysfs_inode_attrs *s_iattr;
};
@@ -79,6 +79,7 @@ struct sysfs_dirent {
#define SYSFS_KOBJ_BIN_ATTR 0x0004
#define SYSFS_KOBJ_LINK 0x0008
#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
+#define SYSFS_ACTIVE_REF (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR)
#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK
#define SYSFS_FLAG_REMOVED 0x0200
@@ -91,9 +92,12 @@ static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
#ifdef CONFIG_DEBUG_LOCK_ALLOC
#define sysfs_dirent_init_lockdep(sd) \
do { \
- static struct lock_class_key __key; \
+ struct attribute *attr = sd->s_attr.attr; \
+ struct lock_class_key *key = attr->key; \
+ if (!key) \
+ key = &attr->skey; \
\
- lockdep_init_map(&sd->dep_map, "s_active", &__key, 0); \
+ lockdep_init_map(&sd->dep_map, "s_active", key, 0); \
} while(0)
#else
#define sysfs_dirent_init_lockdep(sd) do {} while(0)
@@ -111,7 +115,6 @@ struct sysfs_addrm_cxt {
* mount.c
*/
extern struct sysfs_dirent sysfs_root;
-extern struct super_block *sysfs_sb;
extern struct kmem_cache *sysfs_dir_cachep;
/*
@@ -124,8 +127,8 @@ extern const struct file_operations sysfs_dir_operations;
extern const struct inode_operations sysfs_dir_inode_operations;
struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
-struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
-void sysfs_put_active_two(struct sysfs_dirent *sd);
+struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
+void sysfs_put_active(struct sysfs_dirent *sd);
void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
struct sysfs_dirent *parent_sd);
int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
@@ -168,7 +171,7 @@ static inline void __sysfs_put(struct sysfs_dirent *sd)
/*
* inode.c
*/
-struct inode *sysfs_get_inode(struct sysfs_dirent *sd);
+struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd);
void sysfs_delete_inode(struct inode *inode);
int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
int sysfs_permission(struct inode *inode, int mask);
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 9824743832a..4573734d723 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
+#include <linux/writeback.h>
#include <linux/namei.h>
#include <asm/byteorder.h>
#include "sysv.h"
@@ -246,7 +247,7 @@ bad_inode:
return ERR_PTR(-EIO);
}
-int sysv_write_inode(struct inode *inode, int wait)
+static int __sysv_write_inode(struct inode *inode, int wait)
{
struct super_block * sb = inode->i_sb;
struct sysv_sb_info * sbi = SYSV_SB(sb);
@@ -296,9 +297,14 @@ int sysv_write_inode(struct inode *inode, int wait)
return 0;
}
+int sysv_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ return __sysv_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
+}
+
int sysv_sync_inode(struct inode *inode)
{
- return sysv_write_inode(inode, 1);
+ return __sysv_write_inode(inode, 1);
}
static void sysv_delete_inode(struct inode *inode)
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 53786eb5cf6..94cb9b4d76c 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -142,7 +142,7 @@ extern int __sysv_write_begin(struct file *file, struct address_space *mapping,
/* inode.c */
extern struct inode *sysv_iget(struct super_block *, unsigned int);
-extern int sysv_write_inode(struct inode *, int);
+extern int sysv_write_inode(struct inode *, struct writeback_control *wbc);
extern int sysv_sync_inode(struct inode *);
extern void sysv_set_inode(struct inode *, dev_t);
extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *);
diff --git a/fs/timerfd.c b/fs/timerfd.c
index 1bfc95ad5f7..98158de91d2 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -14,6 +14,7 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/time.h>
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 4775af40116..37fa7ed062d 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -45,6 +45,7 @@
#include <linux/freezer.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include "ubifs.h"
/**
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 90492327b38..c2a68baa782 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -34,6 +34,7 @@
#include <linux/moduleparam.h>
#include <linux/debugfs.h>
#include <linux/math64.h>
+#include <linux/slab.h>
#ifdef CONFIG_UBIFS_FS_DEBUG
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 552fb0111ff..401e503d44a 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -1120,7 +1120,7 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (release)
ubifs_release_budget(c, &ino_req);
if (IS_SYNC(old_inode))
- err = old_inode->i_sb->s_op->write_inode(old_inode, 1);
+ err = old_inode->i_sb->s_op->write_inode(old_inode, NULL);
return err;
out_cancel:
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 16a6444330e..5692cf72b80 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -52,6 +52,7 @@
#include "ubifs.h"
#include <linux/mount.h>
#include <linux/namei.h>
+#include <linux/slab.h>
static int read_block(struct inode *inode, void *addr, unsigned int block,
struct ubifs_data_node *dn)
@@ -1011,7 +1012,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
/* Is the page fully inside @i_size? */
if (page->index < end_index) {
if (page->index >= synced_i_size >> PAGE_CACHE_SHIFT) {
- err = inode->i_sb->s_op->write_inode(inode, 1);
+ err = inode->i_sb->s_op->write_inode(inode, NULL);
if (err)
goto out_unlock;
/*
@@ -1039,7 +1040,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
kunmap_atomic(kaddr, KM_USER0);
if (i_size > synced_i_size) {
- err = inode->i_sb->s_op->write_inode(inode, 1);
+ err = inode->i_sb->s_op->write_inode(inode, NULL);
if (err)
goto out_unlock;
}
@@ -1242,7 +1243,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
if (release)
ubifs_release_budget(c, &req);
if (IS_SYNC(inode))
- err = inode->i_sb->s_op->write_inode(inode, 1);
+ err = inode->i_sb->s_op->write_inode(inode, NULL);
return err;
out:
@@ -1316,7 +1317,7 @@ int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync)
* the inode unless this is a 'datasync()' call.
*/
if (!datasync || (inode->i_state & I_DIRTY_DATASYNC)) {
- err = inode->i_sb->s_op->write_inode(inode, 1);
+ err = inode->i_sb->s_op->write_inode(inode, NULL);
if (err)
return err;
}
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index e5a3d8e96bb..918d1582ca0 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -53,6 +53,7 @@
* good, and GC takes extra care when moving them.
*/
+#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/list_sort.h>
#include "ubifs.h"
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index e589fedaf1e..77d5cf4a754 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -51,6 +51,7 @@
*/
#include <linux/crc32.h>
+#include <linux/slab.h>
#include "ubifs.h"
/**
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index b2792e84d24..ad7f67b827e 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -46,6 +46,7 @@
#include "ubifs.h"
#include <linux/crc16.h>
#include <linux/math64.h>
+#include <linux/slab.h>
/**
* do_calc_lpt_geom - calculate sizes for the LPT area.
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 8cbfb824802..13cb7a4237b 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -26,6 +26,7 @@
*/
#include <linux/crc16.h>
+#include <linux/slab.h>
#include "ubifs.h"
/**
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 868a55ee080..109c6ea03bb 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -31,6 +31,7 @@
*/
#include <linux/crc32.h>
+#include <linux/slab.h>
#include "ubifs.h"
/**
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index 57085e43320..96cb62c8a9d 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -27,6 +27,7 @@
*/
#include "ubifs.h"
+#include <linux/slab.h>
#include <linux/random.h>
#include <linux/math64.h>
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 43f9d19a6f3..4d2f2157dd3 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -283,7 +283,7 @@ static void ubifs_destroy_inode(struct inode *inode)
/*
* Note, Linux write-back code calls this without 'i_mutex'.
*/
-static int ubifs_write_inode(struct inode *inode, int wait)
+static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int err = 0;
struct ubifs_info *c = inode->i_sb->s_fs_info;
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index e5b1a7d00fa..2194915220e 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -31,6 +31,7 @@
*/
#include <linux/crc32.h>
+#include <linux/slab.h>
#include "ubifs.h"
/*
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index b2d976366a4..bd2542dad01 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -28,6 +28,7 @@
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index 195830f4756..c74400f88fe 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -56,6 +56,7 @@
*/
#include "ubifs.h"
+#include <linux/slab.h>
#include <linux/xattr.h>
#include <linux/posix_acl_xattr.h>
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index b2d96f45c12..9a9378b4eb5 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -31,55 +31,8 @@
#define udf_clear_bit(nr, addr) ext2_clear_bit(nr, addr)
#define udf_set_bit(nr, addr) ext2_set_bit(nr, addr)
#define udf_test_bit(nr, addr) ext2_test_bit(nr, addr)
-#define udf_find_first_one_bit(addr, size) find_first_one_bit(addr, size)
#define udf_find_next_one_bit(addr, size, offset) \
- find_next_one_bit(addr, size, offset)
-
-#define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
-#define leNUM_to_cpup(x, y) xleNUM_to_cpup(x, y)
-#define xleNUM_to_cpup(x, y) (le ## x ## _to_cpup(y))
-#define uintBPL_t uint(BITS_PER_LONG)
-#define uint(x) xuint(x)
-#define xuint(x) __le ## x
-
-static inline int find_next_one_bit(void *addr, int size, int offset)
-{
- uintBPL_t *p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG);
- int result = offset & ~(BITS_PER_LONG - 1);
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= (BITS_PER_LONG - 1);
- if (offset) {
- tmp = leBPL_to_cpup(p++);
- tmp &= ~0UL << offset;
- if (size < BITS_PER_LONG)
- goto found_first;
- if (tmp)
- goto found_middle;
- size -= BITS_PER_LONG;
- result += BITS_PER_LONG;
- }
- while (size & ~(BITS_PER_LONG - 1)) {
- tmp = leBPL_to_cpup(p++);
- if (tmp)
- goto found_middle;
- result += BITS_PER_LONG;
- size -= BITS_PER_LONG;
- }
- if (!size)
- return result;
- tmp = leBPL_to_cpup(p);
-found_first:
- tmp &= ~0UL >> (BITS_PER_LONG - size);
-found_middle:
- return result + ffz(~tmp);
-}
-
-#define find_first_one_bit(addr, size)\
- find_next_one_bit((addr), (size), 0)
+ ext2_find_next_bit(addr, size, offset)
static int read_block_bitmap(struct super_block *sb,
struct udf_bitmap *bitmap, unsigned int block,
@@ -172,9 +125,8 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
mutex_lock(&sbi->s_alloc_mutex);
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
- if (bloc->logicalBlockNum < 0 ||
- (bloc->logicalBlockNum + count) >
- partmap->s_partition_len) {
+ if (bloc->logicalBlockNum + count < count ||
+ (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
udf_debug("%d < %d || %d + %d > %d\n",
bloc->logicalBlockNum, 0, bloc->logicalBlockNum,
count, partmap->s_partition_len);
@@ -208,7 +160,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
((char *)bh->b_data)[(bit + i) >> 3]);
} else {
if (inode)
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
udf_add_free_space(sb, sbi->s_partition, 1);
}
}
@@ -260,11 +212,11 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
while (bit < (sb->s_blocksize << 3) && block_count > 0) {
if (!udf_test_bit(bit, bh->b_data))
goto out;
- else if (vfs_dq_prealloc_block(inode, 1))
+ else if (dquot_prealloc_block(inode, 1))
goto out;
else if (!udf_clear_bit(bit, bh->b_data)) {
udf_debug("bit already cleared for block %d\n", bit);
- vfs_dq_free_block(inode, 1);
+ dquot_free_block(inode, 1);
goto out;
}
block_count--;
@@ -390,10 +342,14 @@ got_block:
/*
* Check quota for allocation of this block.
*/
- if (inode && vfs_dq_alloc_block(inode, 1)) {
- mutex_unlock(&sbi->s_alloc_mutex);
- *err = -EDQUOT;
- return 0;
+ if (inode) {
+ int ret = dquot_alloc_block(inode, 1);
+
+ if (ret) {
+ mutex_unlock(&sbi->s_alloc_mutex);
+ *err = ret;
+ return 0;
+ }
}
newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
@@ -436,9 +392,8 @@ static void udf_table_free_blocks(struct super_block *sb,
mutex_lock(&sbi->s_alloc_mutex);
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
- if (bloc->logicalBlockNum < 0 ||
- (bloc->logicalBlockNum + count) >
- partmap->s_partition_len) {
+ if (bloc->logicalBlockNum + count < count ||
+ (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
udf_debug("%d < %d || %d + %d > %d\n",
bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count,
partmap->s_partition_len);
@@ -449,7 +404,7 @@ static void udf_table_free_blocks(struct super_block *sb,
/* We do this up front - There are some error conditions that
could occure, but.. oh well */
if (inode)
- vfs_dq_free_block(inode, count);
+ dquot_free_block(inode, count);
udf_add_free_space(sb, sbi->s_partition, count);
start = bloc->logicalBlockNum + offset;
@@ -694,7 +649,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
epos.offset -= adsize;
alloc_count = (elen >> sb->s_blocksize_bits);
- if (inode && vfs_dq_prealloc_block(inode,
+ if (inode && dquot_prealloc_block(inode,
alloc_count > block_count ? block_count : alloc_count))
alloc_count = 0;
else if (alloc_count > block_count) {
@@ -797,12 +752,13 @@ static int udf_table_new_block(struct super_block *sb,
newblock = goal_eloc.logicalBlockNum;
goal_eloc.logicalBlockNum++;
goal_elen -= sb->s_blocksize;
-
- if (inode && vfs_dq_alloc_block(inode, 1)) {
- brelse(goal_epos.bh);
- mutex_unlock(&sbi->s_alloc_mutex);
- *err = -EDQUOT;
- return 0;
+ if (inode) {
+ *err = dquot_alloc_block(inode, 1);
+ if (*err) {
+ brelse(goal_epos.bh);
+ mutex_unlock(&sbi->s_alloc_mutex);
+ return 0;
+ }
}
if (goal_elen)
diff --git a/fs/udf/file.c b/fs/udf/file.c
index f311d509b6a..4b6a46ccbf4 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -34,6 +34,7 @@
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <linux/pagemap.h>
+#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/aio.h>
@@ -207,7 +208,7 @@ const struct file_operations udf_file_operations = {
.read = do_sync_read,
.aio_read = generic_file_aio_read,
.ioctl = udf_ioctl,
- .open = generic_file_open,
+ .open = dquot_file_open,
.mmap = generic_file_mmap,
.write = do_sync_write,
.aio_write = udf_file_aio_write,
@@ -217,6 +218,29 @@ const struct file_operations udf_file_operations = {
.llseek = generic_file_llseek,
};
+int udf_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ error = inode_change_ok(inode, iattr);
+ if (error)
+ return error;
+
+ if (iattr->ia_valid & ATTR_SIZE)
+ dquot_initialize(inode);
+
+ if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
+ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
+ error = dquot_transfer(inode, iattr);
+ if (error)
+ return error;
+ }
+
+ return inode_setattr(inode, iattr);
+}
+
const struct inode_operations udf_file_inode_operations = {
- .truncate = udf_truncate,
+ .truncate = udf_truncate,
+ .setattr = udf_setattr,
};
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index c10fa39f97e..fb68c9cd0c3 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -36,8 +36,8 @@ void udf_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.
*/
- vfs_dq_free_inode(inode);
- vfs_dq_drop(inode);
+ dquot_free_inode(inode);
+ dquot_drop(inode);
clear_inode(inode);
@@ -61,7 +61,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
struct super_block *sb = dir->i_sb;
struct udf_sb_info *sbi = UDF_SB(sb);
struct inode *inode;
- int block;
+ int block, ret;
uint32_t start = UDF_I(dir)->i_location.logicalBlockNum;
struct udf_inode_info *iinfo;
struct udf_inode_info *dinfo = UDF_I(dir);
@@ -153,12 +153,14 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
insert_inode_hash(inode);
mark_inode_dirty(inode);
- if (vfs_dq_alloc_inode(inode)) {
- vfs_dq_drop(inode);
+ dquot_initialize(inode);
+ ret = dquot_alloc_inode(inode);
+ if (ret) {
+ dquot_drop(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
iput(inode);
- *err = -EDQUOT;
+ *err = ret;
return NULL;
}
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 378a7592257..8a3fbd177ca 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -36,6 +36,7 @@
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
+#include <linux/quotaops.h>
#include <linux/slab.h>
#include <linux/crc-itu-t.h>
@@ -70,6 +71,9 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
void udf_delete_inode(struct inode *inode)
{
+ if (!is_bad_inode(inode))
+ dquot_initialize(inode);
+
truncate_inode_pages(&inode->i_data, 0);
if (is_bad_inode(inode))
@@ -102,12 +106,14 @@ void udf_clear_inode(struct inode *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 "
- "inode size %llu different from extent lenght %llu. "
+ "inode size %llu different from extent length %llu. "
"Filesystem need not be standards compliant.\n",
inode->i_sb->s_id, inode->i_ino, inode->i_mode,
(unsigned long long)inode->i_size,
(unsigned long long)iinfo->i_lenExtents);
}
+
+ dquot_drop(inode);
kfree(iinfo->i_ext.i_data);
iinfo->i_ext.i_data = NULL;
}
@@ -1308,7 +1314,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
break;
case ICBTAG_FILE_TYPE_SYMLINK:
inode->i_data.a_ops = &udf_symlink_aops;
- inode->i_op = &page_symlink_inode_operations;
+ inode->i_op = &udf_symlink_inode_operations;
inode->i_mode = S_IFLNK | S_IRWXUGO;
break;
case ICBTAG_FILE_TYPE_MAIN:
@@ -1373,12 +1379,12 @@ static mode_t udf_convert_permissions(struct fileEntry *fe)
return mode;
}
-int udf_write_inode(struct inode *inode, int sync)
+int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int ret;
lock_kernel();
- ret = udf_update_inode(inode, sync);
+ ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
unlock_kernel();
return ret;
@@ -1402,20 +1408,19 @@ static int udf_update_inode(struct inode *inode, int do_sync)
unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
struct udf_inode_info *iinfo = UDF_I(inode);
- bh = udf_tread(inode->i_sb,
- udf_get_lb_pblock(inode->i_sb,
- &iinfo->i_location, 0));
+ bh = udf_tgetblk(inode->i_sb,
+ udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0));
if (!bh) {
- udf_debug("bread failure\n");
- return -EIO;
+ udf_debug("getblk failure\n");
+ return -ENOMEM;
}
- memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
-
+ lock_buffer(bh);
+ memset(bh->b_data, 0, inode->i_sb->s_blocksize);
fe = (struct fileEntry *)bh->b_data;
efe = (struct extendedFileEntry *)bh->b_data;
- if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) {
+ if (iinfo->i_use) {
struct unallocSpaceEntry *use =
(struct unallocSpaceEntry *)bh->b_data;
@@ -1423,20 +1428,18 @@ static int udf_update_inode(struct inode *inode, int do_sync)
memcpy(bh->b_data + sizeof(struct unallocSpaceEntry),
iinfo->i_ext.i_data, inode->i_sb->s_blocksize -
sizeof(struct unallocSpaceEntry));
+ use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE);
+ use->descTag.tagLocation =
+ cpu_to_le32(iinfo->i_location.logicalBlockNum);
crclen = sizeof(struct unallocSpaceEntry) +
iinfo->i_lenAlloc - sizeof(struct tag);
- use->descTag.tagLocation = cpu_to_le32(
- iinfo->i_location.
- logicalBlockNum);
use->descTag.descCRCLength = cpu_to_le16(crclen);
use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use +
sizeof(struct tag),
crclen));
use->descTag.tagChecksum = udf_tag_checksum(&use->descTag);
- mark_buffer_dirty(bh);
- brelse(bh);
- return err;
+ goto out;
}
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
@@ -1591,18 +1594,21 @@ static int udf_update_inode(struct inode *inode, int do_sync)
fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number);
fe->descTag.tagLocation = cpu_to_le32(
iinfo->i_location.logicalBlockNum);
- crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc -
- sizeof(struct tag);
+ crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag);
fe->descTag.descCRCLength = cpu_to_le16(crclen);
fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag),
crclen));
fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag);
+out:
+ set_buffer_uptodate(bh);
+ unlock_buffer(bh);
+
/* write the data blocks */
mark_buffer_dirty(bh);
if (do_sync) {
sync_dirty_buffer(bh);
- if (buffer_req(bh) && !buffer_uptodate(bh)) {
+ if (buffer_write_io_error(bh)) {
printk(KERN_WARNING "IO error syncing udf inode "
"[%s:%08lx]\n", inode->i_sb->s_id,
inode->i_ino);
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 7c56ff00cd5..75816025f95 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -563,6 +563,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
int err;
struct udf_inode_info *iinfo;
+ dquot_initialize(dir);
+
lock_kernel();
inode = udf_new_inode(dir, mode, &err);
if (!inode) {
@@ -616,6 +618,8 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
if (!old_valid_dev(rdev))
return -EINVAL;
+ dquot_initialize(dir);
+
lock_kernel();
err = -EIO;
inode = udf_new_inode(dir, mode, &err);
@@ -662,6 +666,8 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct udf_inode_info *dinfo = UDF_I(dir);
struct udf_inode_info *iinfo;
+ dquot_initialize(dir);
+
lock_kernel();
err = -EMLINK;
if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1)
@@ -799,6 +805,8 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
struct fileIdentDesc *fi, cfi;
struct kernel_lb_addr tloc;
+ dquot_initialize(dir);
+
retval = -ENOENT;
lock_kernel();
fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
@@ -845,6 +853,8 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
struct fileIdentDesc cfi;
struct kernel_lb_addr tloc;
+ dquot_initialize(dir);
+
retval = -ENOENT;
lock_kernel();
fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi);
@@ -899,6 +909,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
struct buffer_head *bh;
struct udf_inode_info *iinfo;
+ dquot_initialize(dir);
+
lock_kernel();
inode = udf_new_inode(dir, S_IFLNK, &err);
if (!inode)
@@ -913,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
iinfo = UDF_I(inode);
inode->i_mode = S_IFLNK | S_IRWXUGO;
inode->i_data.a_ops = &udf_symlink_aops;
- inode->i_op = &page_symlink_inode_operations;
+ inode->i_op = &udf_symlink_inode_operations;
if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
struct kernel_lb_addr eloc;
@@ -1069,6 +1081,8 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
int err;
struct buffer_head *bh;
+ dquot_initialize(dir);
+
lock_kernel();
if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) {
unlock_kernel();
@@ -1131,6 +1145,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
struct kernel_lb_addr tloc;
struct udf_inode_info *old_iinfo = UDF_I(old_inode);
+ dquot_initialize(old_dir);
+ dquot_initialize(new_dir);
+
lock_kernel();
ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
if (ofi) {
@@ -1376,6 +1393,7 @@ const struct export_operations udf_export_ops = {
const struct inode_operations udf_dir_inode_operations = {
.lookup = udf_lookup,
.create = udf_create,
+ .setattr = udf_setattr,
.link = udf_link,
.unlink = udf_unlink,
.symlink = udf_symlink,
@@ -1384,3 +1402,9 @@ const struct inode_operations udf_dir_inode_operations = {
.mknod = udf_mknod,
.rename = udf_rename,
};
+const struct inode_operations udf_symlink_inode_operations = {
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
+ .setattr = udf_setattr,
+};
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index 4b540ee632d..745eb209be0 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -24,7 +24,6 @@
#include <linux/fs.h>
#include <linux/string.h>
-#include <linux/slab.h>
#include <linux/buffer_head.h>
uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 852e9184568..16064787d2b 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -26,7 +26,6 @@
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/stat.h>
-#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 8d46f4294ee..702a1148e70 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -76,6 +76,7 @@ extern const struct inode_operations udf_dir_inode_operations;
extern const struct file_operations udf_dir_operations;
extern const struct inode_operations udf_file_inode_operations;
extern const struct file_operations udf_file_operations;
+extern const struct inode_operations udf_symlink_inode_operations;
extern const struct address_space_operations udf_aops;
extern const struct address_space_operations udf_adinicb_aops;
extern const struct address_space_operations udf_symlink_aops;
@@ -131,7 +132,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
/* file.c */
extern int udf_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
-
+extern int udf_setattr(struct dentry *dentry, struct iattr *iattr);
/* inode.c */
extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
extern int udf_sync_inode(struct inode *);
@@ -142,7 +143,7 @@ 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 int udf_write_inode(struct inode *, int);
+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 *,
struct kernel_long_ad *, sector_t);
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index cefa8c8913e..d03a90b6ad6 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -24,6 +24,7 @@
#include <linux/string.h> /* for memset */
#include <linux/nls.h>
#include <linux/crc-itu-t.h>
+#include <linux/slab.h>
#include "udf_sb.h"
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 54c16ec95df..5cfa4d85ccf 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -85,7 +85,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
"bit already cleared for fragment %u", i);
}
- vfs_dq_free_block(inode, count);
+ dquot_free_block(inode, count);
fs32_add(sb, &ucg->cg_cs.cs_nffree, count);
@@ -195,7 +195,7 @@ do_more:
ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
ufs_clusteracct (sb, ucpi, blkno, 1);
- vfs_dq_free_block(inode, uspi->s_fpb);
+ dquot_free_block(inode, uspi->s_fpb);
fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1);
uspi->cs_total.cs_nbfree++;
@@ -511,6 +511,7 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
unsigned cgno, fragno, fragoff, count, fragsize, i;
+ int ret;
UFSD("ENTER, fragment %llu, oldcount %u, newcount %u\n",
(unsigned long long)fragment, oldcount, newcount);
@@ -556,8 +557,9 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment,
fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1);
for (i = oldcount; i < newcount; i++)
ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i);
- if (vfs_dq_alloc_block(inode, count)) {
- *err = -EDQUOT;
+ ret = dquot_alloc_block(inode, count);
+ if (ret) {
+ *err = ret;
return 0;
}
@@ -596,6 +598,7 @@ static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno,
struct ufs_cylinder_group * ucg;
unsigned oldcg, i, j, k, allocsize;
u64 result;
+ int ret;
UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u\n",
inode->i_ino, cgno, (unsigned long long)goal, count);
@@ -664,7 +667,7 @@ cg_found:
for (i = count; i < uspi->s_fpb; i++)
ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i);
i = uspi->s_fpb - count;
- vfs_dq_free_block(inode, i);
+ dquot_free_block(inode, i);
fs32_add(sb, &ucg->cg_cs.cs_nffree, i);
uspi->cs_total.cs_nffree += i;
@@ -676,8 +679,9 @@ cg_found:
result = ufs_bitmap_search (sb, ucpi, goal, allocsize);
if (result == INVBLOCK)
return 0;
- if (vfs_dq_alloc_block(inode, count)) {
- *err = -EDQUOT;
+ ret = dquot_alloc_block(inode, count);
+ if (ret) {
+ *err = ret;
return 0;
}
for (i = 0; i < count; i++)
@@ -714,6 +718,7 @@ static u64 ufs_alloccg_block(struct inode *inode,
struct ufs_super_block_first * usb1;
struct ufs_cylinder_group * ucg;
u64 result, blkno;
+ int ret;
UFSD("ENTER, goal %llu\n", (unsigned long long)goal);
@@ -747,8 +752,9 @@ gotit:
ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno);
if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
ufs_clusteracct (sb, ucpi, blkno, -1);
- if (vfs_dq_alloc_block(inode, uspi->s_fpb)) {
- *err = -EDQUOT;
+ ret = dquot_alloc_block(inode, uspi->s_fpb);
+ if (ret) {
+ *err = ret;
return INVBLOCK;
}
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 73655c61240..a8962cecde5 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -24,6 +24,7 @@
*/
#include <linux/fs.h>
+#include <linux/quotaops.h>
#include "ufs_fs.h"
#include "ufs.h"
@@ -40,7 +41,7 @@ const struct file_operations ufs_file_operations = {
.write = do_sync_write,
.aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
- .open = generic_file_open,
+ .open = dquot_file_open,
.fsync = simple_fsync,
.splice_read = generic_file_splice_read,
};
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index 3527c00fef0..230ecf60802 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -95,8 +95,8 @@ void ufs_free_inode (struct inode * inode)
is_directory = S_ISDIR(inode->i_mode);
- vfs_dq_free_inode(inode);
- vfs_dq_drop(inode);
+ dquot_free_inode(inode);
+ dquot_drop(inode);
clear_inode (inode);
@@ -355,9 +355,10 @@ cg_found:
unlock_super (sb);
- if (vfs_dq_alloc_inode(inode)) {
- vfs_dq_drop(inode);
- err = -EDQUOT;
+ dquot_initialize(inode);
+ err = dquot_alloc_inode(inode);
+ if (err) {
+ dquot_drop(inode);
goto fail_without_unlock;
}
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 7cf33379fd4..80b68c3702d 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -36,6 +36,8 @@
#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
+#include <linux/writeback.h>
+#include <linux/quotaops.h>
#include "ufs_fs.h"
#include "ufs.h"
@@ -890,11 +892,11 @@ static int ufs_update_inode(struct inode * inode, int do_sync)
return 0;
}
-int ufs_write_inode (struct inode * inode, int wait)
+int ufs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int ret;
lock_kernel();
- ret = ufs_update_inode (inode, wait);
+ ret = ufs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
unlock_kernel();
return ret;
}
@@ -908,6 +910,9 @@ void ufs_delete_inode (struct inode * inode)
{
loff_t old_i_size;
+ if (!is_bad_inode(inode))
+ dquot_initialize(inode);
+
truncate_inode_pages(&inode->i_data, 0);
if (is_bad_inode(inode))
goto no_delete;
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 4c26d9e8bc9..118556243e7 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -30,6 +30,7 @@
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
+#include <linux/quotaops.h>
#include "ufs_fs.h"
#include "ufs.h"
@@ -84,6 +85,9 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode,
int err;
UFSD("BEGIN\n");
+
+ dquot_initialize(dir);
+
inode = ufs_new_inode(dir, mode);
err = PTR_ERR(inode);
@@ -107,6 +111,9 @@ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t
if (!old_valid_dev(rdev))
return -EINVAL;
+
+ dquot_initialize(dir);
+
inode = ufs_new_inode(dir, mode);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
@@ -131,6 +138,8 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry,
if (l > sb->s_blocksize)
goto out_notlocked;
+ dquot_initialize(dir);
+
lock_kernel();
inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO);
err = PTR_ERR(inode);
@@ -176,6 +185,8 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
return -EMLINK;
}
+ dquot_initialize(dir);
+
inode->i_ctime = CURRENT_TIME_SEC;
inode_inc_link_count(inode);
atomic_inc(&inode->i_count);
@@ -193,6 +204,8 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
if (dir->i_nlink >= UFS_LINK_MAX)
goto out;
+ dquot_initialize(dir);
+
lock_kernel();
inode_inc_link_count(dir);
@@ -237,6 +250,8 @@ static int ufs_unlink(struct inode *dir, struct dentry *dentry)
struct page *page;
int err = -ENOENT;
+ dquot_initialize(dir);
+
de = ufs_find_entry(dir, &dentry->d_name, &page);
if (!de)
goto out;
@@ -281,6 +296,9 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct ufs_dir_entry *old_de;
int err = -ENOENT;
+ dquot_initialize(old_dir);
+ dquot_initialize(new_dir);
+
old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page);
if (!old_de)
goto out;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 143c20bfb04..14743d935a9 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1016,6 +1016,9 @@ magic_found:
case UFS_FSSTABLE:
UFSD("fs is stable\n");
break;
+ case UFS_FSLOG:
+ UFSD("fs is logging fs\n");
+ break;
case UFS_FSOSF1:
UFSD("fs is DEC OSF/1\n");
break;
@@ -1432,6 +1435,11 @@ static void destroy_inodecache(void)
kmem_cache_destroy(ufs_inode_cachep);
}
+static void ufs_clear_inode(struct inode *inode)
+{
+ dquot_drop(inode);
+}
+
#ifdef CONFIG_QUOTA
static ssize_t ufs_quota_read(struct super_block *, int, char *,size_t, loff_t);
static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, loff_t);
@@ -1442,6 +1450,7 @@ static const struct super_operations ufs_super_ops = {
.destroy_inode = ufs_destroy_inode,
.write_inode = ufs_write_inode,
.delete_inode = ufs_delete_inode,
+ .clear_inode = ufs_clear_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 41dd431ce22..d3b6270cb37 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -44,6 +44,7 @@
#include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include <linux/sched.h>
+#include <linux/quotaops.h>
#include "ufs_fs.h"
#include "ufs.h"
@@ -517,9 +518,18 @@ static int ufs_setattr(struct dentry *dentry, struct iattr *attr)
if (error)
return error;
+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+ error = dquot_transfer(inode, attr);
+ if (error)
+ return error;
+ }
if (ia_valid & ATTR_SIZE &&
attr->ia_size != i_size_read(inode)) {
loff_t old_i_size = inode->i_size;
+
+ dquot_initialize(inode);
+
error = vmtruncate(inode, attr->ia_size);
if (error)
return error;
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 01d0e2a3b23..43f9f5d5670 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -106,7 +106,7 @@ extern struct inode * ufs_new_inode (struct inode *, int);
/* inode.c */
extern struct inode *ufs_iget(struct super_block *, unsigned long);
-extern int ufs_write_inode (struct inode *, int);
+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 struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *);
diff --git a/fs/ufs/ufs_fs.h b/fs/ufs/ufs_fs.h
index 54bde1895a8..6943ec677c0 100644
--- a/fs/ufs/ufs_fs.h
+++ b/fs/ufs/ufs_fs.h
@@ -138,6 +138,7 @@ typedef __u16 __bitwise __fs16;
#define UFS_USEEFT ((__u16)65535)
+/* fs_clean values */
#define UFS_FSOK 0x7c269d38
#define UFS_FSACTIVE ((__s8)0x00)
#define UFS_FSCLEAN ((__s8)0x01)
@@ -145,6 +146,11 @@ typedef __u16 __bitwise __fs16;
#define UFS_FSOSF1 ((__s8)0x03) /* is this correct for DEC OSF/1? */
#define UFS_FSBAD ((__s8)0xff)
+/* Solaris-specific fs_clean values */
+#define UFS_FSSUSPEND ((__s8)0xfe) /* temporarily suspended */
+#define UFS_FSLOG ((__s8)0xfd) /* logging fs */
+#define UFS_FSFIX ((__s8)0xfc) /* being repaired while mounted */
+
/* From here to next blank line, s_flags for ufs_sb_info */
/* directory entry encoding */
#define UFS_DE_MASK 0x00000010 /* mask for the following */
@@ -227,11 +233,16 @@ typedef __u16 __bitwise __fs16;
*/
#define ufs_cbtocylno(bno) \
((bno) * uspi->s_nspf / uspi->s_spc)
-#define ufs_cbtorpos(bno) \
+#define ufs_cbtorpos(bno) \
+ ((UFS_SB(sb)->s_flags & UFS_CG_SUN) ? \
+ (((((bno) * uspi->s_nspf % uspi->s_spc) % \
+ uspi->s_nsect) * \
+ uspi->s_nrpos) / uspi->s_nsect) \
+ : \
((((bno) * uspi->s_nspf % uspi->s_spc / uspi->s_nsect \
* uspi->s_trackskew + (bno) * uspi->s_nspf % uspi->s_spc \
% uspi->s_nsect * uspi->s_interleave) % uspi->s_nsect \
- * uspi->s_nrpos) / uspi->s_npsect)
+ * uspi->s_nrpos) / uspi->s_npsect))
/*
* The following macros optimize certain frequently calculated
diff --git a/fs/xattr_acl.c b/fs/xattr_acl.c
index 05ac0fe9c4d..8d5a506c82e 100644
--- a/fs/xattr_acl.c
+++ b/fs/xattr_acl.c
@@ -6,9 +6,9 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/posix_acl_xattr.h>
+#include <linux/gfp.h>
/*
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 5c5a366aa33..b4769e40e8b 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -105,7 +105,6 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
xfs_globals.o \
xfs_ioctl.o \
xfs_iops.o \
- xfs_lrw.o \
xfs_super.o \
xfs_sync.o \
xfs_xattr.o)
diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c
index bc7405585de..666c9db48eb 100644
--- a/fs/xfs/linux-2.6/kmem.c
+++ b/fs/xfs/linux-2.6/kmem.c
@@ -17,6 +17,7 @@
*/
#include <linux/mm.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c
index bf85bbe4a9a..a7bc925c4d6 100644
--- a/fs/xfs/linux-2.6/xfs_acl.c
+++ b/fs/xfs/linux-2.6/xfs_acl.c
@@ -22,6 +22,7 @@
#include "xfs_inode.h"
#include "xfs_vnodeops.h"
#include "xfs_trace.h"
+#include <linux/slab.h>
#include <linux/xattr.h>
#include <linux/posix_acl_xattr.h>
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 66abe36c121..0f8b9968a80 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -39,6 +39,8 @@
#include "xfs_iomap.h"
#include "xfs_vnodeops.h"
#include "xfs_trace.h"
+#include "xfs_bmap.h"
+#include <linux/gfp.h>
#include <linux/mpage.h>
#include <linux/pagevec.h>
#include <linux/writeback.h>
@@ -163,14 +165,17 @@ xfs_ioend_new_eof(
}
/*
- * Update on-disk file size now that data has been written to disk.
- * The current in-memory file size is i_size. If a write is beyond
- * eof i_new_size will be the intended file size until i_size is
- * updated. If this write does not extend all the way to the valid
- * file size then restrict this update to the end of the write.
+ * Update on-disk file size now that data has been written to disk. The
+ * current in-memory file size is i_size. If a write is beyond eof i_new_size
+ * will be the intended file size until i_size is updated. If this write does
+ * not extend all the way to the valid file size then restrict this update to
+ * the end of the write.
+ *
+ * This function does not block as blocking on the inode lock in IO completion
+ * can lead to IO completion order dependency deadlocks.. If it can't get the
+ * inode ilock it will return EAGAIN. Callers must handle this.
*/
-
-STATIC void
+STATIC int
xfs_setfilesize(
xfs_ioend_t *ioend)
{
@@ -181,16 +186,40 @@ xfs_setfilesize(
ASSERT(ioend->io_type != IOMAP_READ);
if (unlikely(ioend->io_error))
- return;
+ return 0;
+
+ if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL))
+ return EAGAIN;
- xfs_ilock(ip, XFS_ILOCK_EXCL);
isize = xfs_ioend_new_eof(ioend);
if (isize) {
ip->i_d.di_size = isize;
- xfs_mark_inode_dirty_sync(ip);
+ xfs_mark_inode_dirty(ip);
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ return 0;
+}
+
+/*
+ * Schedule IO completion handling on a xfsdatad if this was
+ * the final hold on this ioend. If we are asked to wait,
+ * flush the workqueue.
+ */
+STATIC void
+xfs_finish_ioend(
+ xfs_ioend_t *ioend,
+ int wait)
+{
+ if (atomic_dec_and_test(&ioend->io_remaining)) {
+ struct workqueue_struct *wq;
+
+ wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
+ xfsconvertd_workqueue : xfsdatad_workqueue;
+ queue_work(wq, &ioend->io_work);
+ if (wait)
+ flush_workqueue(wq);
+ }
}
/*
@@ -198,11 +227,11 @@ xfs_setfilesize(
*/
STATIC void
xfs_end_io(
- struct work_struct *work)
+ struct work_struct *work)
{
- xfs_ioend_t *ioend =
- container_of(work, xfs_ioend_t, io_work);
- struct xfs_inode *ip = XFS_I(ioend->io_inode);
+ xfs_ioend_t *ioend = container_of(work, xfs_ioend_t, io_work);
+ struct xfs_inode *ip = XFS_I(ioend->io_inode);
+ int error = 0;
/*
* For unwritten extents we need to issue transactions to convert a
@@ -210,7 +239,6 @@ xfs_end_io(
*/
if (ioend->io_type == IOMAP_UNWRITTEN &&
likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) {
- int error;
error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
ioend->io_size);
@@ -222,30 +250,23 @@ xfs_end_io(
* We might have to update the on-disk file size after extending
* writes.
*/
- if (ioend->io_type != IOMAP_READ)
- xfs_setfilesize(ioend);
- xfs_destroy_ioend(ioend);
-}
-
-/*
- * Schedule IO completion handling on a xfsdatad if this was
- * the final hold on this ioend. If we are asked to wait,
- * flush the workqueue.
- */
-STATIC void
-xfs_finish_ioend(
- xfs_ioend_t *ioend,
- int wait)
-{
- if (atomic_dec_and_test(&ioend->io_remaining)) {
- struct workqueue_struct *wq;
-
- wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
- xfsconvertd_workqueue : xfsdatad_workqueue;
- queue_work(wq, &ioend->io_work);
- if (wait)
- flush_workqueue(wq);
+ if (ioend->io_type != IOMAP_READ) {
+ error = xfs_setfilesize(ioend);
+ ASSERT(!error || error == EAGAIN);
}
+
+ /*
+ * If we didn't complete processing of the ioend, requeue it to the
+ * tail of the workqueue for another attempt later. Otherwise destroy
+ * it.
+ */
+ if (error == EAGAIN) {
+ atomic_inc(&ioend->io_remaining);
+ xfs_finish_ioend(ioend, 0);
+ /* ensure we don't spin on blocked ioends */
+ delay(1);
+ } else
+ xfs_destroy_ioend(ioend);
}
/*
@@ -341,7 +362,7 @@ xfs_submit_ioend_bio(
* but don't update the inode size until I/O completion.
*/
if (xfs_ioend_new_eof(ioend))
- xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode));
+ xfs_mark_inode_dirty(XFS_I(ioend->io_inode));
submit_bio(wbc->sync_mode == WB_SYNC_ALL ?
WRITE_SYNC_PLUG : WRITE, bio);
@@ -874,6 +895,125 @@ xfs_cluster_write(
}
}
+STATIC void
+xfs_vm_invalidatepage(
+ struct page *page,
+ unsigned long offset)
+{
+ trace_xfs_invalidatepage(page->mapping->host, page, offset);
+ block_invalidatepage(page, offset);
+}
+
+/*
+ * If the page has delalloc buffers on it, we need to punch them out before we
+ * invalidate the page. If we don't, we leave a stale delalloc mapping on the
+ * inode that can trip a BUG() in xfs_get_blocks() later on if a direct IO read
+ * is done on that same region - the delalloc extent is returned when none is
+ * supposed to be there.
+ *
+ * We prevent this by truncating away the delalloc regions on the page before
+ * invalidating it. Because they are delalloc, we can do this without needing a
+ * transaction. Indeed - if we get ENOSPC errors, we have to be able to do this
+ * truncation without a transaction as there is no space left for block
+ * reservation (typically why we see a ENOSPC in writeback).
+ *
+ * This is not a performance critical path, so for now just do the punching a
+ * buffer head at a time.
+ */
+STATIC void
+xfs_aops_discard_page(
+ struct page *page)
+{
+ struct inode *inode = page->mapping->host;
+ struct xfs_inode *ip = XFS_I(inode);
+ struct buffer_head *bh, *head;
+ loff_t offset = page_offset(page);
+ ssize_t len = 1 << inode->i_blkbits;
+
+ if (!xfs_is_delayed_page(page, IOMAP_DELAY))
+ goto out_invalidate;
+
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+ goto out_invalidate;
+
+ xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+ "page discard on page %p, inode 0x%llx, offset %llu.",
+ page, ip->i_ino, offset);
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ bh = head = page_buffers(page);
+ do {
+ int done;
+ xfs_fileoff_t offset_fsb;
+ xfs_bmbt_irec_t imap;
+ int nimaps = 1;
+ int error;
+ xfs_fsblock_t firstblock;
+ xfs_bmap_free_t flist;
+
+ if (!buffer_delay(bh))
+ goto next_buffer;
+
+ offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
+
+ /*
+ * Map the range first and check that it is a delalloc extent
+ * before trying to unmap the range. Otherwise we will be
+ * trying to remove a real extent (which requires a
+ * transaction) or a hole, which is probably a bad idea...
+ */
+ error = xfs_bmapi(NULL, ip, offset_fsb, 1,
+ XFS_BMAPI_ENTIRE, NULL, 0, &imap,
+ &nimaps, NULL, NULL);
+
+ if (error) {
+ /* something screwed, just bail */
+ if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+ xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+ "page discard failed delalloc mapping lookup.");
+ }
+ break;
+ }
+ if (!nimaps) {
+ /* nothing there */
+ goto next_buffer;
+ }
+ if (imap.br_startblock != DELAYSTARTBLOCK) {
+ /* been converted, ignore */
+ goto next_buffer;
+ }
+ WARN_ON(imap.br_blockcount == 0);
+
+ /*
+ * Note: while we initialise the firstblock/flist pair, they
+ * should never be used because blocks should never be
+ * allocated or freed for a delalloc extent and hence we need
+ * don't cancel or finish them after the xfs_bunmapi() call.
+ */
+ xfs_bmap_init(&flist, &firstblock);
+ error = xfs_bunmapi(NULL, ip, offset_fsb, 1, 0, 1, &firstblock,
+ &flist, NULL, &done);
+
+ ASSERT(!flist.xbf_count && !flist.xbf_first);
+ if (error) {
+ /* something screwed, just bail */
+ if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+ xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+ "page discard unable to remove delalloc mapping.");
+ }
+ break;
+ }
+next_buffer:
+ offset += len;
+
+ } while ((bh = bh->b_this_page) != head);
+
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+out_invalidate:
+ xfs_vm_invalidatepage(page, 0);
+ return;
+}
+
/*
* 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
@@ -1125,7 +1265,7 @@ error:
*/
if (err != -EAGAIN) {
if (!unmapped)
- block_invalidatepage(page, 0);
+ xfs_aops_discard_page(page);
ClearPageUptodate(page);
}
return err;
@@ -1535,15 +1675,6 @@ xfs_vm_readpages(
return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks);
}
-STATIC void
-xfs_vm_invalidatepage(
- struct page *page,
- unsigned long offset)
-{
- trace_xfs_invalidatepage(page->mapping->host, page, offset);
- block_invalidatepage(page, offset);
-}
-
const struct address_space_operations xfs_address_space_operations = {
.readpage = xfs_vm_readpage,
.readpages = xfs_vm_readpages,
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 6f76ba85f19..44c2b0ef9a4 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -18,7 +18,7 @@
#include "xfs.h"
#include <linux/stddef.h>
#include <linux/errno.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
@@ -168,75 +168,6 @@ test_page_region(
}
/*
- * Mapping of multi-page buffers into contiguous virtual space
- */
-
-typedef struct a_list {
- void *vm_addr;
- struct a_list *next;
-} a_list_t;
-
-static a_list_t *as_free_head;
-static int as_list_len;
-static DEFINE_SPINLOCK(as_lock);
-
-/*
- * Try to batch vunmaps because they are costly.
- */
-STATIC void
-free_address(
- void *addr)
-{
- a_list_t *aentry;
-
-#ifdef CONFIG_XEN
- /*
- * Xen needs to be able to make sure it can get an exclusive
- * RO mapping of pages it wants to turn into a pagetable. If
- * a newly allocated page is also still being vmap()ed by xfs,
- * it will cause pagetable construction to fail. This is a
- * quick workaround to always eagerly unmap pages so that Xen
- * is happy.
- */
- vunmap(addr);
- return;
-#endif
-
- aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT);
- if (likely(aentry)) {
- spin_lock(&as_lock);
- aentry->next = as_free_head;
- aentry->vm_addr = addr;
- as_free_head = aentry;
- as_list_len++;
- spin_unlock(&as_lock);
- } else {
- vunmap(addr);
- }
-}
-
-STATIC void
-purge_addresses(void)
-{
- a_list_t *aentry, *old;
-
- if (as_free_head == NULL)
- return;
-
- spin_lock(&as_lock);
- aentry = as_free_head;
- as_free_head = NULL;
- as_list_len = 0;
- spin_unlock(&as_lock);
-
- while ((old = aentry) != NULL) {
- vunmap(aentry->vm_addr);
- aentry = aentry->next;
- kfree(old);
- }
-}
-
-/*
* Internal xfs_buf_t object manipulation
*/
@@ -337,7 +268,8 @@ xfs_buf_free(
uint i;
if (xfs_buf_is_vmapped(bp))
- free_address(bp->b_addr - bp->b_offset);
+ vm_unmap_ram(bp->b_addr - bp->b_offset,
+ bp->b_page_count);
for (i = 0; i < bp->b_page_count; i++) {
struct page *page = bp->b_pages[i];
@@ -457,10 +389,8 @@ _xfs_buf_map_pages(
bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset;
bp->b_flags |= XBF_MAPPED;
} else if (flags & XBF_MAPPED) {
- if (as_list_len > 64)
- purge_addresses();
- bp->b_addr = vmap(bp->b_pages, bp->b_page_count,
- VM_MAP, PAGE_KERNEL);
+ bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count,
+ -1, PAGE_KERNEL);
if (unlikely(bp->b_addr == NULL))
return -ENOMEM;
bp->b_addr += bp->b_offset;
@@ -1955,9 +1885,6 @@ xfsbufd(
xfs_buf_iostrategy(bp);
count++;
}
-
- if (as_list_len > 0)
- purge_addresses();
if (count)
blk_run_address_space(target->bt_mapping);
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 87b8cbd23d4..846b75aeb2a 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -29,6 +29,7 @@
#include "xfs_vnodeops.h"
#include "xfs_bmap_btree.h"
#include "xfs_inode.h"
+#include "xfs_inode_item.h"
/*
* Note that we only accept fileids which are long enough rather than allow
@@ -215,9 +216,28 @@ xfs_fs_get_parent(
return d_obtain_alias(VFS_I(cip));
}
+STATIC int
+xfs_fs_nfs_commit_metadata(
+ struct inode *inode)
+{
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ int error = 0;
+
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+ if (xfs_ipincount(ip)) {
+ error = _xfs_log_force_lsn(mp, ip->i_itemp->ili_last_lsn,
+ XFS_LOG_SYNC, NULL);
+ }
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+
+ return error;
+}
+
const struct export_operations xfs_export_operations = {
.encode_fh = xfs_fs_encode_fh,
.fh_to_dentry = xfs_fs_fh_to_dentry,
.fh_to_parent = xfs_fs_fh_to_parent,
.get_parent = xfs_fs_get_parent,
+ .commit_metadata = xfs_fs_nfs_commit_metadata,
};
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index e4caeb28ce2..42dd3bcfba6 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -16,6 +16,7 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
+#include "xfs_fs.h"
#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_inum.h"
@@ -34,52 +35,279 @@
#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"
+#include "xfs_trace.h"
#include <linux/dcache.h>
static const struct vm_operations_struct xfs_file_vm_ops;
-STATIC ssize_t
-xfs_file_aio_read(
- struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs,
- loff_t pos)
+/*
+ * xfs_iozero
+ *
+ * xfs_iozero clears the specified range of buffer supplied,
+ * and marks all the affected blocks as valid and modified. If
+ * an affected block is not allocated, it will be allocated. If
+ * an affected block is not completely overwritten, and is not
+ * valid before the operation, it will be read from disk before
+ * being partially zeroed.
+ */
+STATIC int
+xfs_iozero(
+ struct xfs_inode *ip, /* inode */
+ loff_t pos, /* offset in file */
+ size_t count) /* size of data to zero */
{
- struct file *file = iocb->ki_filp;
- int ioflags = 0;
+ struct page *page;
+ struct address_space *mapping;
+ int status;
- BUG_ON(iocb->ki_pos != pos);
- if (unlikely(file->f_flags & O_DIRECT))
- ioflags |= IO_ISDIRECT;
- if (file->f_mode & FMODE_NOCMTIME)
- ioflags |= IO_INVIS;
- return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov,
- nr_segs, &iocb->ki_pos, ioflags);
+ mapping = VFS_I(ip)->i_mapping;
+ do {
+ unsigned offset, bytes;
+ void *fsdata;
+
+ offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
+ bytes = PAGE_CACHE_SIZE - offset;
+ if (bytes > count)
+ bytes = count;
+
+ status = pagecache_write_begin(NULL, mapping, pos, bytes,
+ AOP_FLAG_UNINTERRUPTIBLE,
+ &page, &fsdata);
+ if (status)
+ break;
+
+ zero_user(page, offset, bytes);
+
+ status = pagecache_write_end(NULL, mapping, pos, bytes, bytes,
+ page, fsdata);
+ WARN_ON(status <= 0); /* can't return less than zero! */
+ pos += bytes;
+ count -= bytes;
+ status = 0;
+ } while (count);
+
+ return (-status);
+}
+
+STATIC int
+xfs_file_fsync(
+ struct file *file,
+ struct dentry *dentry,
+ int datasync)
+{
+ struct xfs_inode *ip = XFS_I(dentry->d_inode);
+ struct xfs_trans *tp;
+ int error = 0;
+ int log_flushed = 0;
+
+ xfs_itrace_entry(ip);
+
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+ return -XFS_ERROR(EIO);
+
+ xfs_iflags_clear(ip, XFS_ITRUNCATED);
+
+ /*
+ * We always need to make sure that the required inode state is safe on
+ * disk. The inode might be clean but we still might need to force the
+ * log because of committed transactions that haven't hit the disk yet.
+ * Likewise, there could be unflushed non-transactional changes to the
+ * inode core that have to go to disk and this requires us to issue
+ * a synchronous transaction to capture these changes correctly.
+ *
+ * This code relies on the assumption that if the i_update_core field
+ * of the inode is clear and the inode is unpinned then it is clean
+ * and no action is required.
+ */
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+
+ /*
+ * First check if the VFS inode is marked dirty. All the dirtying
+ * of non-transactional updates no goes through mark_inode_dirty*,
+ * which allows us to distinguish beteeen pure timestamp updates
+ * and i_size updates which need to be caught for fdatasync.
+ * After that also theck for the dirty state in the XFS inode, which
+ * might gets cleared when the inode gets written out via the AIL
+ * or xfs_iflush_cluster.
+ */
+ if (((dentry->d_inode->i_state & I_DIRTY_DATASYNC) ||
+ ((dentry->d_inode->i_state & I_DIRTY_SYNC) && !datasync)) &&
+ ip->i_update_core) {
+ /*
+ * Kick off a transaction to log the inode core to get the
+ * updates. The sync transaction will also force the log.
+ */
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
+ error = xfs_trans_reserve(tp, 0,
+ XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0);
+ if (error) {
+ xfs_trans_cancel(tp, 0);
+ return -error;
+ }
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+
+ /*
+ * Note - it's possible that we might have pushed ourselves out
+ * of the way during trans_reserve which would flush the inode.
+ * But there's no guarantee that the inode buffer has actually
+ * gone out yet (it's delwri). Plus the buffer could be pinned
+ * anyway if it's part of 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_log_inode(tp, ip, XFS_ILOG_CORE);
+ xfs_trans_set_sync(tp);
+ error = _xfs_trans_commit(tp, 0, &log_flushed);
+
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ } else {
+ /*
+ * Timestamps/size haven't changed since last inode flush or
+ * inode transaction commit. That means either nothing got
+ * written or a transaction committed which caught the updates.
+ * If the latter happened and the transaction hasn't hit the
+ * disk yet, the inode will be still be pinned. If it is,
+ * force the log.
+ */
+ if (xfs_ipincount(ip)) {
+ error = _xfs_log_force_lsn(ip->i_mount,
+ ip->i_itemp->ili_last_lsn,
+ XFS_LOG_SYNC, &log_flushed);
+ }
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ }
+
+ if (ip->i_mount->m_flags & XFS_MOUNT_BARRIER) {
+ /*
+ * If the log write didn't issue an ordered tag we need
+ * to flush the disk cache for the data device now.
+ */
+ if (!log_flushed)
+ xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
+
+ /*
+ * If this inode is on the RT dev we need to flush that
+ * cache as well.
+ */
+ if (XFS_IS_REALTIME_INODE(ip))
+ xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
+ }
+
+ return -error;
}
STATIC ssize_t
-xfs_file_aio_write(
+xfs_file_aio_read(
struct kiocb *iocb,
- const struct iovec *iov,
+ const struct iovec *iovp,
unsigned long nr_segs,
loff_t pos)
{
struct file *file = iocb->ki_filp;
+ struct inode *inode = file->f_mapping->host;
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ size_t size = 0;
+ ssize_t ret = 0;
int ioflags = 0;
+ xfs_fsize_t n;
+ unsigned long seg;
+
+ XFS_STATS_INC(xs_read_calls);
BUG_ON(iocb->ki_pos != pos);
+
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
if (file->f_mode & FMODE_NOCMTIME)
ioflags |= IO_INVIS;
- return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs,
- &iocb->ki_pos, ioflags);
+
+ /* START copy & waste from filemap.c */
+ for (seg = 0; seg < nr_segs; seg++) {
+ const struct iovec *iv = &iovp[seg];
+
+ /*
+ * If any segment has a negative length, or the cumulative
+ * length ever wraps negative then return -EINVAL.
+ */
+ size += iv->iov_len;
+ if (unlikely((ssize_t)(size|iv->iov_len) < 0))
+ return XFS_ERROR(-EINVAL);
+ }
+ /* END copy & waste from filemap.c */
+
+ if (unlikely(ioflags & IO_ISDIRECT)) {
+ xfs_buftarg_t *target =
+ XFS_IS_REALTIME_INODE(ip) ?
+ mp->m_rtdev_targp : mp->m_ddev_targp;
+ if ((iocb->ki_pos & target->bt_smask) ||
+ (size & target->bt_smask)) {
+ if (iocb->ki_pos == ip->i_size)
+ return 0;
+ return -XFS_ERROR(EINVAL);
+ }
+ }
+
+ n = XFS_MAXIOFFSET(mp) - iocb->ki_pos;
+ if (n <= 0 || size == 0)
+ return 0;
+
+ if (n < size)
+ size = n;
+
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return -EIO;
+
+ if (unlikely(ioflags & IO_ISDIRECT))
+ 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,
+ (iocb->ki_pos & PAGE_CACHE_MASK),
+ -1, FI_REMAPF_LOCKED);
+ }
+ mutex_unlock(&inode->i_mutex);
+ if (ret) {
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+ return ret;
+ }
+ }
+
+ trace_xfs_file_read(ip, size, iocb->ki_pos, ioflags);
+
+ ret = generic_file_aio_read(iocb, iovp, nr_segs, iocb->ki_pos);
+ if (ret > 0)
+ XFS_STATS_ADD(xs_read_bytes, ret);
+
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+ return ret;
}
STATIC ssize_t
@@ -87,16 +315,44 @@ xfs_file_splice_read(
struct file *infilp,
loff_t *ppos,
struct pipe_inode_info *pipe,
- size_t len,
+ size_t count,
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;
+
+ XFS_STATS_INC(xs_read_calls);
if (infilp->f_mode & FMODE_NOCMTIME)
ioflags |= IO_INVIS;
- return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
- infilp, ppos, pipe, len, flags, ioflags);
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+ return -EIO;
+
+ 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);
+ if (ret > 0)
+ XFS_STATS_ADD(xs_read_bytes, ret);
+
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+ return ret;
}
STATIC ssize_t
@@ -104,16 +360,538 @@ xfs_file_splice_write(
struct pipe_inode_info *pipe,
struct file *outfilp,
loff_t *ppos,
- size_t len,
+ size_t count,
unsigned int flags)
{
+ 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;
+
+ XFS_STATS_INC(xs_write_calls);
if (outfilp->f_mode & FMODE_NOCMTIME)
ioflags |= IO_INVIS;
- return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
- pipe, outfilp, ppos, len, flags, ioflags);
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+ return -EIO;
+
+ 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);
+ if (new_size > ip->i_size)
+ ip->i_new_size = new_size;
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+
+ trace_xfs_file_splice_write(ip, count, *ppos, ioflags);
+
+ ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
+ if (ret > 0)
+ XFS_STATS_ADD(xs_write_bytes, ret);
+
+ isize = i_size_read(inode);
+ if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
+ *ppos = isize;
+
+ if (*ppos > ip->i_size) {
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ if (*ppos > ip->i_size)
+ ip->i_size = *ppos;
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ }
+
+ if (ip->i_new_size) {
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ ip->i_new_size = 0;
+ if (ip->i_d.di_size > ip->i_size)
+ ip->i_d.di_size = ip->i_size;
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ }
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+ return ret;
+}
+
+/*
+ * This routine is called to handle zeroing any space in the last
+ * block of the file that is beyond the EOF. We do this since the
+ * size is being increased without writing anything to that block
+ * and we don't want anyone to read the garbage on the disk.
+ */
+STATIC int /* error (positive) */
+xfs_zero_last_block(
+ xfs_inode_t *ip,
+ xfs_fsize_t offset,
+ xfs_fsize_t isize)
+{
+ xfs_fileoff_t last_fsb;
+ xfs_mount_t *mp = ip->i_mount;
+ int nimaps;
+ int zero_offset;
+ int zero_len;
+ int error = 0;
+ xfs_bmbt_irec_t imap;
+
+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+ zero_offset = XFS_B_FSB_OFFSET(mp, isize);
+ if (zero_offset == 0) {
+ /*
+ * There are no extra bytes in the last block on disk to
+ * zero, so return.
+ */
+ return 0;
+ }
+
+ 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);
+ if (error) {
+ return error;
+ }
+ ASSERT(nimaps > 0);
+ /*
+ * If the block underlying isize is just a hole, then there
+ * is nothing to zero.
+ */
+ if (imap.br_startblock == HOLESTARTBLOCK) {
+ return 0;
+ }
+ /*
+ * Zero the part of the last block beyond the EOF, and write it
+ * out sync. We need to drop the ilock while we do this so we
+ * don't deadlock when the buffer cache calls back to us.
+ */
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+
+ zero_len = mp->m_sb.sb_blocksize - zero_offset;
+ if (isize + zero_len > offset)
+ zero_len = offset - isize;
+ error = xfs_iozero(ip, isize, zero_len);
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ ASSERT(error >= 0);
+ return error;
+}
+
+/*
+ * Zero any on disk space between the current EOF and the new,
+ * larger EOF. This handles the normal case of zeroing the remainder
+ * of the last block in the file and the unusual case of zeroing blocks
+ * out beyond the size of the file. This second case only happens
+ * with fixed size extents and when the system crashes before the inode
+ * size was updated but after blocks were allocated. If fill is set,
+ * then any holes in the range are filled and zeroed. If not, the holes
+ * are left alone as holes.
+ */
+
+int /* error (positive) */
+xfs_zero_eof(
+ xfs_inode_t *ip,
+ xfs_off_t offset, /* starting I/O offset */
+ xfs_fsize_t isize) /* current inode size */
+{
+ xfs_mount_t *mp = ip->i_mount;
+ xfs_fileoff_t start_zero_fsb;
+ xfs_fileoff_t end_zero_fsb;
+ xfs_fileoff_t zero_count_fsb;
+ xfs_fileoff_t last_fsb;
+ xfs_fileoff_t zero_off;
+ xfs_fsize_t zero_len;
+ int nimaps;
+ int error = 0;
+ xfs_bmbt_irec_t imap;
+
+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
+ ASSERT(offset > isize);
+
+ /*
+ * First handle zeroing the block on which isize resides.
+ * We only zero a part of that block so it is handled specially.
+ */
+ error = xfs_zero_last_block(ip, offset, isize);
+ if (error) {
+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
+ return error;
+ }
+
+ /*
+ * Calculate the range between the new size and the old
+ * where blocks needing to be zeroed may exist. To get the
+ * block where the last byte in the file currently resides,
+ * we need to subtract one from the size and truncate back
+ * to a block boundary. We subtract 1 in case the size is
+ * exactly on a block boundary.
+ */
+ last_fsb = isize ? XFS_B_TO_FSBT(mp, isize - 1) : (xfs_fileoff_t)-1;
+ start_zero_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)isize);
+ end_zero_fsb = XFS_B_TO_FSBT(mp, offset - 1);
+ ASSERT((xfs_sfiloff_t)last_fsb < (xfs_sfiloff_t)start_zero_fsb);
+ if (last_fsb == end_zero_fsb) {
+ /*
+ * The size was only incremented on its last block.
+ * We took care of that above, so just return.
+ */
+ return 0;
+ }
+
+ ASSERT(start_zero_fsb <= end_zero_fsb);
+ while (start_zero_fsb <= end_zero_fsb) {
+ 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);
+ if (error) {
+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
+ return error;
+ }
+ ASSERT(nimaps > 0);
+
+ if (imap.br_state == XFS_EXT_UNWRITTEN ||
+ imap.br_startblock == HOLESTARTBLOCK) {
+ /*
+ * This loop handles initializing pages that were
+ * partially initialized by the code below this
+ * loop. It basically zeroes the part of the page
+ * that sits on a hole and sets the page as P_HOLE
+ * and calls remapf if it is a mapped file.
+ */
+ start_zero_fsb = imap.br_startoff + imap.br_blockcount;
+ ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
+ continue;
+ }
+
+ /*
+ * There are blocks we need to zero.
+ * Drop the inode lock while we're doing the I/O.
+ * We'll still have the iolock to protect us.
+ */
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+
+ zero_off = XFS_FSB_TO_B(mp, start_zero_fsb);
+ zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount);
+
+ if ((zero_off + zero_len) > offset)
+ zero_len = offset - zero_off;
+
+ error = xfs_iozero(ip, zero_off, zero_len);
+ if (error) {
+ goto out_lock;
+ }
+
+ start_zero_fsb = imap.br_startoff + imap.br_blockcount;
+ ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ }
+
+ return 0;
+
+out_lock:
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ ASSERT(error >= 0);
+ return error;
+}
+
+STATIC ssize_t
+xfs_file_aio_write(
+ struct kiocb *iocb,
+ const struct iovec *iovp,
+ unsigned long nr_segs,
+ loff_t pos)
+{
+ struct file *file = iocb->ki_filp;
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ ssize_t ret = 0, error = 0;
+ int ioflags = 0;
+ xfs_fsize_t isize, new_size;
+ int iolock;
+ int eventsent = 0;
+ size_t ocount = 0, count;
+ int need_i_mutex;
+
+ XFS_STATS_INC(xs_write_calls);
+
+ BUG_ON(iocb->ki_pos != pos);
+
+ if (unlikely(file->f_flags & O_DIRECT))
+ ioflags |= IO_ISDIRECT;
+ if (file->f_mode & FMODE_NOCMTIME)
+ ioflags |= IO_INVIS;
+
+ error = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ);
+ if (error)
+ return error;
+
+ count = ocount;
+ if (count == 0)
+ return 0;
+
+ xfs_wait_for_freeze(mp, SB_FREEZE_WRITE);
+
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return -EIO;
+
+relock:
+ if (ioflags & IO_ISDIRECT) {
+ iolock = XFS_IOLOCK_SHARED;
+ need_i_mutex = 0;
+ } else {
+ iolock = XFS_IOLOCK_EXCL;
+ need_i_mutex = 1;
+ mutex_lock(&inode->i_mutex);
+ }
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL|iolock);
+
+start:
+ error = -generic_write_checks(file, &pos, &count,
+ S_ISBLK(inode->i_mode));
+ if (error) {
+ xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock);
+ 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) ?
+ mp->m_rtdev_targp : mp->m_ddev_targp;
+
+ if ((pos & target->bt_smask) || (count & target->bt_smask)) {
+ xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock);
+ return XFS_ERROR(-EINVAL);
+ }
+
+ if (!need_i_mutex && (mapping->nrpages || pos > ip->i_size)) {
+ xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock);
+ iolock = XFS_IOLOCK_EXCL;
+ need_i_mutex = 1;
+ mutex_lock(&inode->i_mutex);
+ xfs_ilock(ip, XFS_ILOCK_EXCL|iolock);
+ goto start;
+ }
+ }
+
+ new_size = pos + count;
+ if (new_size > ip->i_size)
+ ip->i_new_size = new_size;
+
+ if (likely(!(ioflags & IO_INVIS)))
+ file_update_time(file);
+
+ /*
+ * If the offset is beyond the size of the file, we have a couple
+ * of things to do. First, if there is already space allocated
+ * we need to either create holes or zero the disk or ...
+ *
+ * If there is a page where the previous size lands, we need
+ * to zero it out up to the new size.
+ */
+
+ if (pos > ip->i_size) {
+ error = xfs_zero_eof(ip, pos, ip->i_size);
+ if (error) {
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ goto out_unlock_internal;
+ }
+ }
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+
+ /*
+ * If we're writing the file then make sure to clear the
+ * setuid and setgid bits if the process is not being run
+ * by root. This keeps people from modifying setuid and
+ * setgid binaries.
+ */
+ error = -file_remove_suid(file);
+ if (unlikely(error))
+ goto out_unlock_internal;
+
+ /* We can write back this queue in page reclaim */
+ current->backing_dev_info = mapping->backing_dev_info;
+
+ if ((ioflags & IO_ISDIRECT)) {
+ if (mapping->nrpages) {
+ WARN_ON(need_i_mutex == 0);
+ error = xfs_flushinval_pages(ip,
+ (pos & PAGE_CACHE_MASK),
+ -1, FI_REMAPF_LOCKED);
+ if (error)
+ goto out_unlock_internal;
+ }
+
+ if (need_i_mutex) {
+ /* demote the lock now the cached pages are gone */
+ xfs_ilock_demote(ip, XFS_IOLOCK_EXCL);
+ mutex_unlock(&inode->i_mutex);
+
+ iolock = XFS_IOLOCK_SHARED;
+ need_i_mutex = 0;
+ }
+
+ trace_xfs_file_direct_write(ip, count, iocb->ki_pos, ioflags);
+ ret = generic_file_direct_write(iocb, iovp,
+ &nr_segs, pos, &iocb->ki_pos, count, ocount);
+
+ /*
+ * direct-io write to a hole: fall through to buffered I/O
+ * for completing the rest of the request.
+ */
+ if (ret >= 0 && ret != count) {
+ XFS_STATS_ADD(xs_write_bytes, ret);
+
+ pos += ret;
+ count -= ret;
+
+ ioflags &= ~IO_ISDIRECT;
+ xfs_iunlock(ip, iolock);
+ goto relock;
+ }
+ } else {
+ int enospc = 0;
+ ssize_t ret2 = 0;
+
+write_retry:
+ trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, ioflags);
+ ret2 = generic_file_buffered_write(iocb, iovp, nr_segs,
+ pos, &iocb->ki_pos, count, ret);
+ /*
+ * if we just got an ENOSPC, flush the inode now we
+ * aren't holding any page locks and retry *once*
+ */
+ if (ret2 == -ENOSPC && !enospc) {
+ error = xfs_flush_pages(ip, 0, -1, 0, FI_NONE);
+ if (error)
+ goto out_unlock_internal;
+ enospc = 1;
+ goto write_retry;
+ }
+ ret = ret2;
+ }
+
+ current->backing_dev_info = NULL;
+
+ isize = i_size_read(inode);
+ if (unlikely(ret < 0 && ret != -EFAULT && iocb->ki_pos > isize))
+ iocb->ki_pos = isize;
+
+ if (iocb->ki_pos > ip->i_size) {
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ if (iocb->ki_pos > ip->i_size)
+ ip->i_size = iocb->ki_pos;
+ 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;
+
+ XFS_STATS_ADD(xs_write_bytes, ret);
+
+ /* Handle various SYNC-type writes */
+ if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
+ loff_t end = pos + ret - 1;
+ int error2;
+
+ xfs_iunlock(ip, iolock);
+ if (need_i_mutex)
+ mutex_unlock(&inode->i_mutex);
+
+ error2 = filemap_write_and_wait_range(mapping, pos, end);
+ if (!error)
+ error = error2;
+ if (need_i_mutex)
+ mutex_lock(&inode->i_mutex);
+ xfs_ilock(ip, iolock);
+
+ error2 = -xfs_file_fsync(file, file->f_path.dentry,
+ (file->f_flags & __O_SYNC) ? 0 : 1);
+ if (!error)
+ error = error2;
+ }
+
+ out_unlock_internal:
+ if (ip->i_new_size) {
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ ip->i_new_size = 0;
+ /*
+ * If this was a direct or synchronous I/O that failed (such
+ * as ENOSPC) then part of the I/O may have been written to
+ * disk before the error occured. In this case the on-disk
+ * file size may have been adjusted beyond the in-memory file
+ * size and now needs to be truncated back.
+ */
+ if (ip->i_d.di_size > ip->i_size)
+ ip->i_d.di_size = ip->i_size;
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ }
+ xfs_iunlock(ip, iolock);
+ out_unlock_mutex:
+ if (need_i_mutex)
+ mutex_unlock(&inode->i_mutex);
+ return -error;
}
STATIC int
@@ -160,28 +938,6 @@ xfs_file_release(
return -xfs_release(XFS_I(inode));
}
-/*
- * We ignore the datasync flag here because a datasync is effectively
- * identical to an fsync. That is, datasync implies that we need to write
- * only the metadata needed to be able to access the data that is written
- * if we crash after the call completes. Hence if we are writing beyond
- * EOF we have to log the inode size change as well, which makes it a
- * full fsync. If we don't write beyond EOF, the inode core will be
- * clean in memory and so we don't need to log the inode, just like
- * fsync.
- */
-STATIC int
-xfs_file_fsync(
- struct file *file,
- struct dentry *dentry,
- int datasync)
-{
- struct xfs_inode *ip = XFS_I(dentry->d_inode);
-
- xfs_iflags_clear(ip, XFS_ITRUNCATED);
- return -xfs_fsync(ip);
-}
-
STATIC int
xfs_file_readdir(
struct file *filp,
@@ -203,9 +959,9 @@ xfs_file_readdir(
*
* Try to give it an estimate that's good enough, maybe at some
* point we can change the ->readdir prototype to include the
- * buffer size.
+ * buffer size. For now we use the current glibc buffer size.
*/
- bufsize = (size_t)min_t(loff_t, PAGE_SIZE, ip->i_d.di_size);
+ bufsize = (size_t)min_t(loff_t, 32768, ip->i_d.di_size);
error = xfs_readdir(ip, dirent, bufsize,
(xfs_off_t *)&filp->f_pos, filldir);
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 4ea1ee18ade..7b26cc2fd28 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -58,6 +58,7 @@
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <linux/exportfs.h>
/*
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 0bf6d61f052..593c05b4df8 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -18,6 +18,7 @@
#include <linux/compat.h>
#include <linux/ioctl.h>
#include <linux/mount.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include "xfs.h"
#include "xfs_fs.h"
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index e8566bbf0f0..e65a7937f3a 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -56,6 +56,7 @@
#include <linux/security.h>
#include <linux/falloc.h>
#include <linux/fiemap.h>
+#include <linux/slab.h>
/*
* Bring the timestamps in the XFS inode uptodate.
@@ -91,6 +92,16 @@ xfs_mark_inode_dirty_sync(
mark_inode_dirty_sync(inode);
}
+void
+xfs_mark_inode_dirty(
+ xfs_inode_t *ip)
+{
+ struct inode *inode = VFS_I(ip);
+
+ if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR)))
+ mark_inode_dirty(inode);
+}
+
/*
* Change the requested timestamp in the given inode.
* We don't lock across timestamp updates, and we don't log them but
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 5af0c81ca1a..facfb323a70 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -88,7 +88,6 @@
#include <xfs_super.h>
#include <xfs_globals.h>
#include <xfs_fs_subr.h>
-#include <xfs_lrw.h>
#include <xfs_buf.h>
/*
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
deleted file mode 100644
index eac6f80d786..00000000000
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ /dev/null
@@ -1,796 +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_bit.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#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_inode_item.h"
-#include "xfs_buf_item.h"
-#include "xfs_utils.h"
-#include "xfs_iomap.h"
-#include "xfs_vnodeops.h"
-#include "xfs_trace.h"
-
-#include <linux/capability.h>
-#include <linux/writeback.h>
-
-
-/*
- * xfs_iozero
- *
- * xfs_iozero clears the specified range of buffer supplied,
- * and marks all the affected blocks as valid and modified. If
- * an affected block is not allocated, it will be allocated. If
- * an affected block is not completely overwritten, and is not
- * valid before the operation, it will be read from disk before
- * being partially zeroed.
- */
-STATIC int
-xfs_iozero(
- struct xfs_inode *ip, /* inode */
- loff_t pos, /* offset in file */
- size_t count) /* size of data to zero */
-{
- struct page *page;
- struct address_space *mapping;
- int status;
-
- mapping = VFS_I(ip)->i_mapping;
- do {
- unsigned offset, bytes;
- void *fsdata;
-
- offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
- bytes = PAGE_CACHE_SIZE - offset;
- if (bytes > count)
- bytes = count;
-
- status = pagecache_write_begin(NULL, mapping, pos, bytes,
- AOP_FLAG_UNINTERRUPTIBLE,
- &page, &fsdata);
- if (status)
- break;
-
- zero_user(page, offset, bytes);
-
- status = pagecache_write_end(NULL, mapping, pos, bytes, bytes,
- page, fsdata);
- WARN_ON(status <= 0); /* can't return less than zero! */
- pos += bytes;
- count -= bytes;
- status = 0;
- } while (count);
-
- return (-status);
-}
-
-ssize_t /* bytes read, or (-) error */
-xfs_read(
- xfs_inode_t *ip,
- struct kiocb *iocb,
- const struct iovec *iovp,
- unsigned int segs,
- loff_t *offset,
- int ioflags)
-{
- struct file *file = iocb->ki_filp;
- struct inode *inode = file->f_mapping->host;
- xfs_mount_t *mp = ip->i_mount;
- size_t size = 0;
- ssize_t ret = 0;
- xfs_fsize_t n;
- unsigned long seg;
-
-
- XFS_STATS_INC(xs_read_calls);
-
- /* START copy & waste from filemap.c */
- for (seg = 0; seg < segs; seg++) {
- const struct iovec *iv = &iovp[seg];
-
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- size += iv->iov_len;
- if (unlikely((ssize_t)(size|iv->iov_len) < 0))
- return XFS_ERROR(-EINVAL);
- }
- /* END copy & waste from filemap.c */
-
- if (unlikely(ioflags & IO_ISDIRECT)) {
- xfs_buftarg_t *target =
- XFS_IS_REALTIME_INODE(ip) ?
- mp->m_rtdev_targp : mp->m_ddev_targp;
- if ((*offset & target->bt_smask) ||
- (size & target->bt_smask)) {
- if (*offset == ip->i_size) {
- return (0);
- }
- return -XFS_ERROR(EINVAL);
- }
- }
-
- n = XFS_MAXIOFFSET(mp) - *offset;
- if ((n <= 0) || (size == 0))
- return 0;
-
- if (n < size)
- size = n;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return -EIO;
-
- if (unlikely(ioflags & IO_ISDIRECT))
- 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, *offset, 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, (*offset & PAGE_CACHE_MASK),
- -1, FI_REMAPF_LOCKED);
- mutex_unlock(&inode->i_mutex);
- if (ret) {
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- return ret;
- }
- }
-
- trace_xfs_file_read(ip, size, *offset, ioflags);
-
- iocb->ki_pos = *offset;
- ret = generic_file_aio_read(iocb, iovp, segs, *offset);
- if (ret > 0)
- XFS_STATS_ADD(xs_read_bytes, ret);
-
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- return ret;
-}
-
-ssize_t
-xfs_splice_read(
- xfs_inode_t *ip,
- struct file *infilp,
- loff_t *ppos,
- struct pipe_inode_info *pipe,
- size_t count,
- int flags,
- int ioflags)
-{
- xfs_mount_t *mp = ip->i_mount;
- ssize_t ret;
-
- XFS_STATS_INC(xs_read_calls);
- if (XFS_FORCED_SHUTDOWN(ip->i_mount))
- return -EIO;
-
- 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);
- if (ret > 0)
- XFS_STATS_ADD(xs_read_bytes, ret);
-
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- return ret;
-}
-
-ssize_t
-xfs_splice_write(
- xfs_inode_t *ip,
- struct pipe_inode_info *pipe,
- struct file *outfilp,
- loff_t *ppos,
- size_t count,
- int flags,
- int ioflags)
-{
- xfs_mount_t *mp = ip->i_mount;
- ssize_t ret;
- struct inode *inode = outfilp->f_mapping->host;
- xfs_fsize_t isize, new_size;
-
- XFS_STATS_INC(xs_write_calls);
- if (XFS_FORCED_SHUTDOWN(ip->i_mount))
- return -EIO;
-
- 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);
- if (new_size > ip->i_size)
- ip->i_new_size = new_size;
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
-
- trace_xfs_file_splice_write(ip, count, *ppos, ioflags);
-
- ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
- if (ret > 0)
- XFS_STATS_ADD(xs_write_bytes, ret);
-
- isize = i_size_read(inode);
- if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
- *ppos = isize;
-
- if (*ppos > ip->i_size) {
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- if (*ppos > ip->i_size)
- ip->i_size = *ppos;
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
-
- if (ip->i_new_size) {
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- ip->i_new_size = 0;
- if (ip->i_d.di_size > ip->i_size)
- ip->i_d.di_size = ip->i_size;
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return ret;
-}
-
-/*
- * This routine is called to handle zeroing any space in the last
- * block of the file that is beyond the EOF. We do this since the
- * size is being increased without writing anything to that block
- * and we don't want anyone to read the garbage on the disk.
- */
-STATIC int /* error (positive) */
-xfs_zero_last_block(
- xfs_inode_t *ip,
- xfs_fsize_t offset,
- xfs_fsize_t isize)
-{
- xfs_fileoff_t last_fsb;
- xfs_mount_t *mp = ip->i_mount;
- int nimaps;
- int zero_offset;
- int zero_len;
- int error = 0;
- xfs_bmbt_irec_t imap;
-
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-
- zero_offset = XFS_B_FSB_OFFSET(mp, isize);
- if (zero_offset == 0) {
- /*
- * There are no extra bytes in the last block on disk to
- * zero, so return.
- */
- return 0;
- }
-
- 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);
- if (error) {
- return error;
- }
- ASSERT(nimaps > 0);
- /*
- * If the block underlying isize is just a hole, then there
- * is nothing to zero.
- */
- if (imap.br_startblock == HOLESTARTBLOCK) {
- return 0;
- }
- /*
- * Zero the part of the last block beyond the EOF, and write it
- * out sync. We need to drop the ilock while we do this so we
- * don't deadlock when the buffer cache calls back to us.
- */
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
-
- zero_len = mp->m_sb.sb_blocksize - zero_offset;
- if (isize + zero_len > offset)
- zero_len = offset - isize;
- error = xfs_iozero(ip, isize, zero_len);
-
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- ASSERT(error >= 0);
- return error;
-}
-
-/*
- * Zero any on disk space between the current EOF and the new,
- * larger EOF. This handles the normal case of zeroing the remainder
- * of the last block in the file and the unusual case of zeroing blocks
- * out beyond the size of the file. This second case only happens
- * with fixed size extents and when the system crashes before the inode
- * size was updated but after blocks were allocated. If fill is set,
- * then any holes in the range are filled and zeroed. If not, the holes
- * are left alone as holes.
- */
-
-int /* error (positive) */
-xfs_zero_eof(
- xfs_inode_t *ip,
- xfs_off_t offset, /* starting I/O offset */
- xfs_fsize_t isize) /* current inode size */
-{
- xfs_mount_t *mp = ip->i_mount;
- xfs_fileoff_t start_zero_fsb;
- xfs_fileoff_t end_zero_fsb;
- xfs_fileoff_t zero_count_fsb;
- xfs_fileoff_t last_fsb;
- xfs_fileoff_t zero_off;
- xfs_fsize_t zero_len;
- int nimaps;
- int error = 0;
- xfs_bmbt_irec_t imap;
-
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
- ASSERT(offset > isize);
-
- /*
- * First handle zeroing the block on which isize resides.
- * We only zero a part of that block so it is handled specially.
- */
- error = xfs_zero_last_block(ip, offset, isize);
- if (error) {
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
- return error;
- }
-
- /*
- * Calculate the range between the new size and the old
- * where blocks needing to be zeroed may exist. To get the
- * block where the last byte in the file currently resides,
- * we need to subtract one from the size and truncate back
- * to a block boundary. We subtract 1 in case the size is
- * exactly on a block boundary.
- */
- last_fsb = isize ? XFS_B_TO_FSBT(mp, isize - 1) : (xfs_fileoff_t)-1;
- start_zero_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)isize);
- end_zero_fsb = XFS_B_TO_FSBT(mp, offset - 1);
- ASSERT((xfs_sfiloff_t)last_fsb < (xfs_sfiloff_t)start_zero_fsb);
- if (last_fsb == end_zero_fsb) {
- /*
- * The size was only incremented on its last block.
- * We took care of that above, so just return.
- */
- return 0;
- }
-
- ASSERT(start_zero_fsb <= end_zero_fsb);
- while (start_zero_fsb <= end_zero_fsb) {
- 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);
- if (error) {
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
- return error;
- }
- ASSERT(nimaps > 0);
-
- if (imap.br_state == XFS_EXT_UNWRITTEN ||
- imap.br_startblock == HOLESTARTBLOCK) {
- /*
- * This loop handles initializing pages that were
- * partially initialized by the code below this
- * loop. It basically zeroes the part of the page
- * that sits on a hole and sets the page as P_HOLE
- * and calls remapf if it is a mapped file.
- */
- start_zero_fsb = imap.br_startoff + imap.br_blockcount;
- ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
- continue;
- }
-
- /*
- * There are blocks we need to zero.
- * Drop the inode lock while we're doing the I/O.
- * We'll still have the iolock to protect us.
- */
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
-
- zero_off = XFS_FSB_TO_B(mp, start_zero_fsb);
- zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount);
-
- if ((zero_off + zero_len) > offset)
- zero_len = offset - zero_off;
-
- error = xfs_iozero(ip, zero_off, zero_len);
- if (error) {
- goto out_lock;
- }
-
- start_zero_fsb = imap.br_startoff + imap.br_blockcount;
- ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
-
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- }
-
- return 0;
-
-out_lock:
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- ASSERT(error >= 0);
- return error;
-}
-
-ssize_t /* bytes written, or (-) error */
-xfs_write(
- struct xfs_inode *xip,
- struct kiocb *iocb,
- const struct iovec *iovp,
- unsigned int nsegs,
- loff_t *offset,
- int ioflags)
-{
- struct file *file = iocb->ki_filp;
- struct address_space *mapping = file->f_mapping;
- struct inode *inode = mapping->host;
- unsigned long segs = nsegs;
- xfs_mount_t *mp;
- ssize_t ret = 0, error = 0;
- xfs_fsize_t isize, new_size;
- int iolock;
- int eventsent = 0;
- size_t ocount = 0, count;
- loff_t pos;
- int need_i_mutex;
-
- XFS_STATS_INC(xs_write_calls);
-
- error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ);
- if (error)
- return error;
-
- count = ocount;
- pos = *offset;
-
- if (count == 0)
- return 0;
-
- mp = xip->i_mount;
-
- xfs_wait_for_freeze(mp, SB_FREEZE_WRITE);
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return -EIO;
-
-relock:
- if (ioflags & IO_ISDIRECT) {
- iolock = XFS_IOLOCK_SHARED;
- need_i_mutex = 0;
- } else {
- iolock = XFS_IOLOCK_EXCL;
- need_i_mutex = 1;
- mutex_lock(&inode->i_mutex);
- }
-
- xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
-
-start:
- error = -generic_write_checks(file, &pos, &count,
- S_ISBLK(inode->i_mode));
- if (error) {
- xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
- goto out_unlock_mutex;
- }
-
- if ((DM_EVENT_ENABLED(xip, DM_EVENT_WRITE) &&
- !(ioflags & IO_INVIS) && !eventsent)) {
- int dmflags = FILP_DELAY_FLAG(file);
-
- if (need_i_mutex)
- dmflags |= DM_FLAGS_IMUX;
-
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
- error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, xip,
- pos, count, dmflags, &iolock);
- if (error) {
- goto out_unlock_internal;
- }
- xfs_ilock(xip, 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 != xip->i_size)
- goto start;
- }
-
- if (ioflags & IO_ISDIRECT) {
- xfs_buftarg_t *target =
- XFS_IS_REALTIME_INODE(xip) ?
- mp->m_rtdev_targp : mp->m_ddev_targp;
-
- if ((pos & target->bt_smask) || (count & target->bt_smask)) {
- xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
- return XFS_ERROR(-EINVAL);
- }
-
- if (!need_i_mutex && (mapping->nrpages || pos > xip->i_size)) {
- xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
- iolock = XFS_IOLOCK_EXCL;
- need_i_mutex = 1;
- mutex_lock(&inode->i_mutex);
- xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
- goto start;
- }
- }
-
- new_size = pos + count;
- if (new_size > xip->i_size)
- xip->i_new_size = new_size;
-
- if (likely(!(ioflags & IO_INVIS)))
- file_update_time(file);
-
- /*
- * If the offset is beyond the size of the file, we have a couple
- * of things to do. First, if there is already space allocated
- * we need to either create holes or zero the disk or ...
- *
- * If there is a page where the previous size lands, we need
- * to zero it out up to the new size.
- */
-
- if (pos > xip->i_size) {
- error = xfs_zero_eof(xip, pos, xip->i_size);
- if (error) {
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
- goto out_unlock_internal;
- }
- }
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
-
- /*
- * If we're writing the file then make sure to clear the
- * setuid and setgid bits if the process is not being run
- * by root. This keeps people from modifying setuid and
- * setgid binaries.
- */
- error = -file_remove_suid(file);
- if (unlikely(error))
- goto out_unlock_internal;
-
- /* We can write back this queue in page reclaim */
- current->backing_dev_info = mapping->backing_dev_info;
-
- if ((ioflags & IO_ISDIRECT)) {
- if (mapping->nrpages) {
- WARN_ON(need_i_mutex == 0);
- error = xfs_flushinval_pages(xip,
- (pos & PAGE_CACHE_MASK),
- -1, FI_REMAPF_LOCKED);
- if (error)
- goto out_unlock_internal;
- }
-
- if (need_i_mutex) {
- /* demote the lock now the cached pages are gone */
- xfs_ilock_demote(xip, XFS_IOLOCK_EXCL);
- mutex_unlock(&inode->i_mutex);
-
- iolock = XFS_IOLOCK_SHARED;
- need_i_mutex = 0;
- }
-
- trace_xfs_file_direct_write(xip, count, *offset, ioflags);
- ret = generic_file_direct_write(iocb, iovp,
- &segs, pos, offset, count, ocount);
-
- /*
- * direct-io write to a hole: fall through to buffered I/O
- * for completing the rest of the request.
- */
- if (ret >= 0 && ret != count) {
- XFS_STATS_ADD(xs_write_bytes, ret);
-
- pos += ret;
- count -= ret;
-
- ioflags &= ~IO_ISDIRECT;
- xfs_iunlock(xip, iolock);
- goto relock;
- }
- } else {
- int enospc = 0;
- ssize_t ret2 = 0;
-
-write_retry:
- trace_xfs_file_buffered_write(xip, count, *offset, ioflags);
- ret2 = generic_file_buffered_write(iocb, iovp, segs,
- pos, offset, count, ret);
- /*
- * if we just got an ENOSPC, flush the inode now we
- * aren't holding any page locks and retry *once*
- */
- if (ret2 == -ENOSPC && !enospc) {
- error = xfs_flush_pages(xip, 0, -1, 0, FI_NONE);
- if (error)
- goto out_unlock_internal;
- enospc = 1;
- goto write_retry;
- }
- ret = ret2;
- }
-
- current->backing_dev_info = NULL;
-
- isize = i_size_read(inode);
- if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize))
- *offset = isize;
-
- if (*offset > xip->i_size) {
- xfs_ilock(xip, XFS_ILOCK_EXCL);
- if (*offset > xip->i_size)
- xip->i_size = *offset;
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
- }
-
- if (ret == -ENOSPC &&
- DM_EVENT_ENABLED(xip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) {
- xfs_iunlock(xip, iolock);
- if (need_i_mutex)
- mutex_unlock(&inode->i_mutex);
- error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, xip,
- DM_RIGHT_NULL, xip, DM_RIGHT_NULL, NULL, NULL,
- 0, 0, 0); /* Delay flag intentionally unused */
- if (need_i_mutex)
- mutex_lock(&inode->i_mutex);
- xfs_ilock(xip, iolock);
- if (error)
- goto out_unlock_internal;
- goto start;
- }
-
- error = -ret;
- if (ret <= 0)
- goto out_unlock_internal;
-
- XFS_STATS_ADD(xs_write_bytes, ret);
-
- /* Handle various SYNC-type writes */
- if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
- loff_t end = pos + ret - 1;
- int error2;
-
- xfs_iunlock(xip, iolock);
- if (need_i_mutex)
- mutex_unlock(&inode->i_mutex);
-
- error2 = filemap_write_and_wait_range(mapping, pos, end);
- if (!error)
- error = error2;
- if (need_i_mutex)
- mutex_lock(&inode->i_mutex);
- xfs_ilock(xip, iolock);
-
- error2 = xfs_fsync(xip);
- if (!error)
- error = error2;
- }
-
- out_unlock_internal:
- if (xip->i_new_size) {
- xfs_ilock(xip, XFS_ILOCK_EXCL);
- xip->i_new_size = 0;
- /*
- * If this was a direct or synchronous I/O that failed (such
- * as ENOSPC) then part of the I/O may have been written to
- * disk before the error occured. In this case the on-disk
- * file size may have been adjusted beyond the in-memory file
- * size and now needs to be truncated back.
- */
- if (xip->i_d.di_size > xip->i_size)
- xip->i_d.di_size = xip->i_size;
- xfs_iunlock(xip, XFS_ILOCK_EXCL);
- }
- xfs_iunlock(xip, iolock);
- out_unlock_mutex:
- if (need_i_mutex)
- mutex_unlock(&inode->i_mutex);
- return -error;
-}
-
-/*
- * If the underlying (data/log/rt) device is readonly, there are some
- * operations that cannot proceed.
- */
-int
-xfs_dev_is_read_only(
- xfs_mount_t *mp,
- char *message)
-{
- if (xfs_readonly_buftarg(mp->m_ddev_targp) ||
- xfs_readonly_buftarg(mp->m_logdev_targp) ||
- (mp->m_rtdev_targp && xfs_readonly_buftarg(mp->m_rtdev_targp))) {
- cmn_err(CE_NOTE,
- "XFS: %s required on read-only device.", message);
- cmn_err(CE_NOTE,
- "XFS: write access unavailable, cannot proceed.");
- return EROFS;
- }
- return 0;
-}
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
deleted file mode 100644
index 342ae8c0d01..00000000000
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ /dev/null
@@ -1,29 +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
- */
-#ifndef __XFS_LRW_H__
-#define __XFS_LRW_H__
-
-struct xfs_mount;
-struct xfs_inode;
-struct xfs_buf;
-
-extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
-
-extern int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t);
-
-#endif /* __XFS_LRW_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c
index 3d4a0c84d63..1947514ce1a 100644
--- a/fs/xfs/linux-2.6/xfs_quotaops.c
+++ b/fs/xfs/linux-2.6/xfs_quotaops.c
@@ -44,20 +44,6 @@ xfs_quota_type(int type)
}
STATIC int
-xfs_fs_quota_sync(
- struct super_block *sb,
- int type)
-{
- struct xfs_mount *mp = XFS_M(sb);
-
- if (sb->s_flags & MS_RDONLY)
- return -EROFS;
- if (!XFS_IS_QUOTA_RUNNING(mp))
- return -ENOSYS;
- return -xfs_sync_data(mp, 0);
-}
-
-STATIC int
xfs_fs_get_xstate(
struct super_block *sb,
struct fs_quota_stat *fqs)
@@ -82,8 +68,6 @@ xfs_fs_set_xstate(
return -EROFS;
if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
return -ENOSYS;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
if (uflags & XFS_QUOTA_UDQ_ACCT)
flags |= XFS_UQUOTA_ACCT;
@@ -144,14 +128,11 @@ xfs_fs_set_xquota(
return -ENOSYS;
if (!XFS_IS_QUOTA_ON(mp))
return -ESRCH;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
return -xfs_qm_scall_setqlim(mp, id, xfs_quota_type(type), fdq);
}
const struct quotactl_ops xfs_quotactl_operations = {
- .quota_sync = xfs_fs_quota_sync,
.get_xstate = xfs_fs_get_xstate,
.set_xstate = xfs_fs_set_xstate,
.get_xquota = xfs_fs_get_xquota,
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 25ea2408118..29f1edca76d 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -61,6 +61,7 @@
#include <linux/namei.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/mempool.h>
#include <linux/writeback.h>
@@ -1063,7 +1064,7 @@ xfs_log_inode(
STATIC int
xfs_fs_write_inode(
struct inode *inode,
- int sync)
+ struct writeback_control *wbc)
{
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
@@ -1074,11 +1075,7 @@ xfs_fs_write_inode(
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
- if (sync) {
- error = xfs_wait_on_pages(ip, 0, -1);
- if (error)
- goto out;
-
+ 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
@@ -1212,6 +1209,7 @@ xfs_fs_put_super(
xfs_unmountfs(mp);
xfs_freesb(mp);
+ xfs_inode_shrinker_unregister(mp);
xfs_icsb_destroy_counters(mp);
xfs_close_devices(mp);
xfs_dmops_put(mp);
@@ -1625,6 +1623,8 @@ xfs_fs_fill_super(
if (error)
goto fail_vnrele;
+ xfs_inode_shrinker_register(mp);
+
kfree(mtpt);
return 0;
@@ -1870,6 +1870,7 @@ init_xfs_fs(void)
goto out_cleanup_procfs;
vfs_initquota();
+ xfs_inode_shrinker_init();
error = register_filesystem(&xfs_fs_type);
if (error)
@@ -1897,6 +1898,7 @@ exit_xfs_fs(void)
{
vfs_exitquota();
unregister_filesystem(&xfs_fs_type);
+ xfs_inode_shrinker_destroy();
xfs_sysctl_unregister();
xfs_cleanup_procfs();
xfs_buf_terminate();
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index a9f6d20aff4..a427c638d90 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -95,7 +95,8 @@ xfs_inode_ag_walk(
struct xfs_perag *pag, int flags),
int flags,
int tag,
- int exclusive)
+ int exclusive,
+ int *nr_to_scan)
{
uint32_t first_index;
int last_error = 0;
@@ -134,7 +135,7 @@ restart:
if (error == EFSCORRUPTED)
break;
- } while (1);
+ } while ((*nr_to_scan)--);
if (skipped) {
delay(1);
@@ -150,12 +151,15 @@ xfs_inode_ag_iterator(
struct xfs_perag *pag, int flags),
int flags,
int tag,
- int exclusive)
+ int exclusive,
+ int *nr_to_scan)
{
int error = 0;
int last_error = 0;
xfs_agnumber_t ag;
+ int nr;
+ nr = nr_to_scan ? *nr_to_scan : INT_MAX;
for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
struct xfs_perag *pag;
@@ -165,14 +169,18 @@ xfs_inode_ag_iterator(
continue;
}
error = xfs_inode_ag_walk(mp, pag, execute, flags, tag,
- exclusive);
+ exclusive, &nr);
xfs_perag_put(pag);
if (error) {
last_error = error;
if (error == EFSCORRUPTED)
break;
}
+ if (nr <= 0)
+ break;
}
+ if (nr_to_scan)
+ *nr_to_scan = nr;
return XFS_ERROR(last_error);
}
@@ -291,7 +299,7 @@ xfs_sync_data(
ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags,
- XFS_ICI_NO_TAG, 0);
+ XFS_ICI_NO_TAG, 0, NULL);
if (error)
return XFS_ERROR(error);
@@ -310,7 +318,7 @@ xfs_sync_attr(
ASSERT((flags & ~SYNC_WAIT) == 0);
return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags,
- XFS_ICI_NO_TAG, 0);
+ XFS_ICI_NO_TAG, 0, NULL);
}
STATIC int
@@ -607,7 +615,8 @@ xfssyncd(
set_freezable();
timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
for (;;) {
- timeleft = schedule_timeout_interruptible(timeleft);
+ if (list_empty(&mp->m_sync_list))
+ timeleft = schedule_timeout_interruptible(timeleft);
/* swsusp */
try_to_freeze();
if (kthread_should_stop() && list_empty(&mp->m_sync_list))
@@ -627,8 +636,7 @@ xfssyncd(
list_add_tail(&mp->m_sync_work.w_list,
&mp->m_sync_list);
}
- list_for_each_entry_safe(work, n, &mp->m_sync_list, w_list)
- list_move(&work->w_list, &tmp);
+ list_splice_init(&mp->m_sync_list, &tmp);
spin_unlock(&mp->m_sync_lock);
list_for_each_entry_safe(work, n, &tmp, w_list) {
@@ -673,6 +681,7 @@ __xfs_inode_set_reclaim_tag(
radix_tree_tag_set(&pag->pag_ici_root,
XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
XFS_ICI_RECLAIM_TAG);
+ pag->pag_ici_reclaimable++;
}
/*
@@ -688,12 +697,12 @@ xfs_inode_set_reclaim_tag(
struct xfs_perag *pag;
pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
- read_lock(&pag->pag_ici_lock);
+ write_lock(&pag->pag_ici_lock);
spin_lock(&ip->i_flags_lock);
__xfs_inode_set_reclaim_tag(pag, ip);
__xfs_iflags_set(ip, XFS_IRECLAIMABLE);
spin_unlock(&ip->i_flags_lock);
- read_unlock(&pag->pag_ici_lock);
+ write_unlock(&pag->pag_ici_lock);
xfs_perag_put(pag);
}
@@ -705,6 +714,7 @@ __xfs_inode_clear_reclaim_tag(
{
radix_tree_tag_clear(&pag->pag_ici_root,
XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
+ pag->pag_ici_reclaimable--;
}
/*
@@ -820,10 +830,10 @@ xfs_reclaim_inode(
* call into reclaim to find it in a clean state instead of waiting for
* it now. We also don't return errors here - if the error is transient
* then the next reclaim pass will flush the inode, and if the error
- * is permanent then the next sync reclaim will relcaim the inode and
+ * is permanent then the next sync reclaim will reclaim the inode and
* pass on the error.
*/
- if (error && !XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+ if (error && error != EAGAIN && !XFS_FORCED_SHUTDOWN(ip->i_mount)) {
xfs_fs_cmn_err(CE_WARN, ip->i_mount,
"inode 0x%llx background reclaim flush failed with %d",
(long long)ip->i_ino, error);
@@ -854,5 +864,93 @@ xfs_reclaim_inodes(
int mode)
{
return xfs_inode_ag_iterator(mp, xfs_reclaim_inode, mode,
- XFS_ICI_RECLAIM_TAG, 1);
+ XFS_ICI_RECLAIM_TAG, 1, NULL);
+}
+
+/*
+ * Shrinker infrastructure.
+ *
+ * This is all far more complex than it needs to be. It adds a global list of
+ * mounts because the shrinkers can only call a global context. We need to make
+ * the shrinkers pass a context to avoid the need for global state.
+ */
+static LIST_HEAD(xfs_mount_list);
+static struct rw_semaphore xfs_mount_list_lock;
+
+static int
+xfs_reclaim_inode_shrink(
+ int nr_to_scan,
+ gfp_t gfp_mask)
+{
+ struct xfs_mount *mp;
+ struct xfs_perag *pag;
+ xfs_agnumber_t ag;
+ int reclaimable = 0;
+
+ if (nr_to_scan) {
+ if (!(gfp_mask & __GFP_FS))
+ return -1;
+
+ down_read(&xfs_mount_list_lock);
+ list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
+ xfs_inode_ag_iterator(mp, xfs_reclaim_inode, 0,
+ XFS_ICI_RECLAIM_TAG, 1, &nr_to_scan);
+ if (nr_to_scan <= 0)
+ break;
+ }
+ up_read(&xfs_mount_list_lock);
+ }
+
+ down_read(&xfs_mount_list_lock);
+ list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
+ for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
+
+ pag = xfs_perag_get(mp, ag);
+ if (!pag->pag_ici_init) {
+ xfs_perag_put(pag);
+ continue;
+ }
+ reclaimable += pag->pag_ici_reclaimable;
+ xfs_perag_put(pag);
+ }
+ }
+ up_read(&xfs_mount_list_lock);
+ return reclaimable;
+}
+
+static struct shrinker xfs_inode_shrinker = {
+ .shrink = xfs_reclaim_inode_shrink,
+ .seeks = DEFAULT_SEEKS,
+};
+
+void __init
+xfs_inode_shrinker_init(void)
+{
+ init_rwsem(&xfs_mount_list_lock);
+ register_shrinker(&xfs_inode_shrinker);
+}
+
+void
+xfs_inode_shrinker_destroy(void)
+{
+ ASSERT(list_empty(&xfs_mount_list));
+ unregister_shrinker(&xfs_inode_shrinker);
+}
+
+void
+xfs_inode_shrinker_register(
+ struct xfs_mount *mp)
+{
+ down_write(&xfs_mount_list_lock);
+ list_add_tail(&mp->m_mplist, &xfs_mount_list);
+ up_write(&xfs_mount_list_lock);
+}
+
+void
+xfs_inode_shrinker_unregister(
+ struct xfs_mount *mp)
+{
+ down_write(&xfs_mount_list_lock);
+ list_del(&mp->m_mplist);
+ up_write(&xfs_mount_list_lock);
}
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index d480c346cab..cdcbaaca988 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -53,6 +53,11 @@ void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag);
int xfs_inode_ag_iterator(struct xfs_mount *mp,
int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
- int flags, int tag, int write_lock);
+ int flags, int tag, int write_lock, int *nr_to_scan);
+
+void xfs_inode_shrinker_init(void);
+void xfs_inode_shrinker_destroy(void);
+void xfs_inode_shrinker_register(struct xfs_mount *mp);
+void xfs_inode_shrinker_unregister(struct xfs_mount *mp);
#endif
diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/linux-2.6/xfs_trace.c
index 856eb3c8d60..5a107601e96 100644
--- a/fs/xfs/linux-2.6/xfs_trace.c
+++ b/fs/xfs/linux-2.6/xfs_trace.c
@@ -52,22 +52,6 @@
#include "quota/xfs_dquot.h"
/*
- * Format fsblock number into a static buffer & return it.
- */
-STATIC char *xfs_fmtfsblock(xfs_fsblock_t bno)
-{
- static char rval[50];
-
- if (bno == NULLFSBLOCK)
- sprintf(rval, "NULLFSBLOCK");
- else if (isnullstartblock(bno))
- sprintf(rval, "NULLSTARTBLOCK(%lld)", startblockval(bno));
- else
- sprintf(rval, "%lld", (xfs_dfsbno_t)bno);
- return rval;
-}
-
-/*
* We include this last to have the helpers above available for the trace
* event implementations.
*/
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index a4574dcf506..fcaa62f0799 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -197,13 +197,13 @@ TRACE_EVENT(xfs_iext_insert,
__entry->caller_ip = caller_ip;
),
TP_printk("dev %d:%d ino 0x%llx state %s idx %ld "
- "offset %lld block %s count %lld flag %d caller %pf",
+ "offset %lld block %lld count %lld flag %d caller %pf",
MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->ino,
__print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS),
(long)__entry->idx,
__entry->startoff,
- xfs_fmtfsblock(__entry->startblock),
+ (__int64_t)__entry->startblock,
__entry->blockcount,
__entry->state,
(char *)__entry->caller_ip)
@@ -241,13 +241,13 @@ DECLARE_EVENT_CLASS(xfs_bmap_class,
__entry->caller_ip = caller_ip;
),
TP_printk("dev %d:%d ino 0x%llx state %s idx %ld "
- "offset %lld block %s count %lld flag %d caller %pf",
+ "offset %lld block %lld count %lld flag %d caller %pf",
MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->ino,
__print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS),
(long)__entry->idx,
__entry->startoff,
- xfs_fmtfsblock(__entry->startblock),
+ (__int64_t)__entry->startblock,
__entry->blockcount,
__entry->state,
(char *)__entry->caller_ip)
@@ -593,7 +593,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
TP_ARGS(dqp),
TP_STRUCT__entry(
__field(dev_t, dev)
- __field(__be32, id)
+ __field(u32, id)
__field(unsigned, flags)
__field(unsigned, nrefs)
__field(unsigned long long, res_bcount)
@@ -606,7 +606,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
), \
TP_fast_assign(
__entry->dev = dqp->q_mount->m_super->s_dev;
- __entry->id = dqp->q_core.d_id;
+ __entry->id = be32_to_cpu(dqp->q_core.d_id);
__entry->flags = dqp->dq_flags;
__entry->nrefs = dqp->q_nrefs;
__entry->res_bcount = dqp->q_res_bcount;
@@ -622,10 +622,10 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
be64_to_cpu(dqp->q_core.d_ino_softlimit);
),
TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx "
- "bcnt 0x%llx [hard 0x%llx | soft 0x%llx] "
- "icnt 0x%llx [hard 0x%llx | soft 0x%llx]",
+ "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx "
+ "icnt 0x%llx ihardlimit 0x%llx isoftlimit 0x%llx]",
MAJOR(__entry->dev), MINOR(__entry->dev),
- be32_to_cpu(__entry->id),
+ __entry->id,
__print_flags(__entry->flags, "|", XFS_DQ_FLAGS),
__entry->nrefs,
__entry->res_bcount,
@@ -881,7 +881,7 @@ TRACE_EVENT(name, \
), \
TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \
"offset 0x%llx count %zd flags %s " \
- "startoff 0x%llx startblock %s blockcount 0x%llx", \
+ "startoff 0x%llx startblock %lld blockcount 0x%llx", \
MAJOR(__entry->dev), MINOR(__entry->dev), \
__entry->ino, \
__entry->size, \
@@ -890,7 +890,7 @@ TRACE_EVENT(name, \
__entry->count, \
__print_flags(__entry->flags, "|", BMAPI_FLAGS), \
__entry->startoff, \
- xfs_fmtfsblock(__entry->startblock), \
+ (__int64_t)__entry->startblock, \
__entry->blockcount) \
)
DEFINE_IOMAP_EVENT(xfs_iomap_enter);
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 5d0ee8d492d..50bee07d6b0 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -891,7 +891,8 @@ xfs_qm_dqrele_all_inodes(
uint flags)
{
ASSERT(mp->m_quotainfo);
- xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG, 0);
+ xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags,
+ XFS_ICI_NO_TAG, 0, NULL);
}
/*------------------------------------------------------------------------*/
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index b1a5a1ff88e..abb8222b88c 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -223,6 +223,7 @@ typedef struct xfs_perag {
int pag_ici_init; /* incore inode cache initialised */
rwlock_t pag_ici_lock; /* incore inode lock */
struct radix_tree_root pag_ici_root; /* incore inode cache root */
+ int pag_ici_reclaimable; /* reclaimable inodes */
#endif
int pagb_count; /* pagb slots in use */
xfs_perag_busy_t pagb_list[XFS_PAGB_NUM_SLOTS]; /* unstable blocks */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 1869fb97381..5c11e4d1701 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2550,22 +2550,134 @@ xfs_bmap_rtalloc(
}
STATIC int
+xfs_bmap_btalloc_nullfb(
+ struct xfs_bmalloca *ap,
+ struct xfs_alloc_arg *args,
+ xfs_extlen_t *blen)
+{
+ struct xfs_mount *mp = ap->ip->i_mount;
+ struct xfs_perag *pag;
+ xfs_agnumber_t ag, startag;
+ int notinit = 0;
+ int error;
+
+ if (ap->userdata && xfs_inode_is_filestream(ap->ip))
+ args->type = XFS_ALLOCTYPE_NEAR_BNO;
+ else
+ args->type = XFS_ALLOCTYPE_START_BNO;
+ args->total = ap->total;
+
+ /*
+ * Search for an allocation group with a single extent large enough
+ * for the request. If one isn't found, then adjust the minimum
+ * allocation size to the largest space found.
+ */
+ startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
+ if (startag == NULLAGNUMBER)
+ startag = ag = 0;
+
+ pag = xfs_perag_get(mp, ag);
+ while (*blen < ap->alen) {
+ if (!pag->pagf_init) {
+ error = xfs_alloc_pagf_init(mp, args->tp, ag,
+ XFS_ALLOC_FLAG_TRYLOCK);
+ if (error) {
+ xfs_perag_put(pag);
+ return error;
+ }
+ }
+
+ /*
+ * See xfs_alloc_fix_freelist...
+ */
+ if (pag->pagf_init) {
+ xfs_extlen_t longest;
+ longest = xfs_alloc_longest_free_extent(mp, pag);
+ if (*blen < longest)
+ *blen = longest;
+ } else
+ notinit = 1;
+
+ if (xfs_inode_is_filestream(ap->ip)) {
+ if (*blen >= ap->alen)
+ break;
+
+ if (ap->userdata) {
+ /*
+ * If startag is an invalid AG, we've
+ * come here once before and
+ * xfs_filestream_new_ag picked the
+ * best currently available.
+ *
+ * Don't continue looping, since we
+ * could loop forever.
+ */
+ if (startag == NULLAGNUMBER)
+ break;
+
+ error = xfs_filestream_new_ag(ap, &ag);
+ xfs_perag_put(pag);
+ if (error)
+ return error;
+
+ /* loop again to set 'blen'*/
+ startag = NULLAGNUMBER;
+ pag = xfs_perag_get(mp, ag);
+ continue;
+ }
+ }
+ if (++ag == mp->m_sb.sb_agcount)
+ ag = 0;
+ if (ag == startag)
+ break;
+ xfs_perag_put(pag);
+ pag = xfs_perag_get(mp, ag);
+ }
+ xfs_perag_put(pag);
+
+ /*
+ * Since the above loop did a BUF_TRYLOCK, it is
+ * possible that there is space for this request.
+ */
+ if (notinit || *blen < ap->minlen)
+ args->minlen = ap->minlen;
+ /*
+ * If the best seen length is less than the request
+ * length, use the best as the minimum.
+ */
+ else if (*blen < ap->alen)
+ args->minlen = *blen;
+ /*
+ * Otherwise we've seen an extent as big as alen,
+ * use that as the minimum.
+ */
+ else
+ args->minlen = ap->alen;
+
+ /*
+ * set the failure fallback case to look in the selected
+ * AG as the stream may have moved.
+ */
+ if (xfs_inode_is_filestream(ap->ip))
+ ap->rval = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
+
+ return 0;
+}
+
+STATIC int
xfs_bmap_btalloc(
xfs_bmalloca_t *ap) /* bmap alloc argument struct */
{
xfs_mount_t *mp; /* mount point structure */
xfs_alloctype_t atype = 0; /* type for allocation routines */
xfs_extlen_t align; /* minimum allocation alignment */
- xfs_agnumber_t ag;
xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
- xfs_agnumber_t startag;
+ xfs_agnumber_t ag;
xfs_alloc_arg_t args;
xfs_extlen_t blen;
xfs_extlen_t nextminlen = 0;
- xfs_perag_t *pag;
int nullfb; /* true if ap->firstblock isn't set */
int isaligned;
- int notinit;
int tryagain;
int error;
@@ -2612,103 +2724,9 @@ xfs_bmap_btalloc(
args.firstblock = ap->firstblock;
blen = 0;
if (nullfb) {
- if (ap->userdata && xfs_inode_is_filestream(ap->ip))
- args.type = XFS_ALLOCTYPE_NEAR_BNO;
- else
- args.type = XFS_ALLOCTYPE_START_BNO;
- args.total = ap->total;
-
- /*
- * Search for an allocation group with a single extent
- * large enough for the request.
- *
- * If one isn't found, then adjust the minimum allocation
- * size to the largest space found.
- */
- startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno);
- if (startag == NULLAGNUMBER)
- startag = ag = 0;
- notinit = 0;
- pag = xfs_perag_get(mp, ag);
- while (blen < ap->alen) {
- if (!pag->pagf_init &&
- (error = xfs_alloc_pagf_init(mp, args.tp,
- ag, XFS_ALLOC_FLAG_TRYLOCK))) {
- xfs_perag_put(pag);
- return error;
- }
- /*
- * See xfs_alloc_fix_freelist...
- */
- if (pag->pagf_init) {
- xfs_extlen_t longest;
- longest = xfs_alloc_longest_free_extent(mp, pag);
- if (blen < longest)
- blen = longest;
- } else
- notinit = 1;
-
- if (xfs_inode_is_filestream(ap->ip)) {
- if (blen >= ap->alen)
- break;
-
- if (ap->userdata) {
- /*
- * If startag is an invalid AG, we've
- * come here once before and
- * xfs_filestream_new_ag picked the
- * best currently available.
- *
- * Don't continue looping, since we
- * could loop forever.
- */
- if (startag == NULLAGNUMBER)
- break;
-
- error = xfs_filestream_new_ag(ap, &ag);
- xfs_perag_put(pag);
- if (error)
- return error;
-
- /* loop again to set 'blen'*/
- startag = NULLAGNUMBER;
- pag = xfs_perag_get(mp, ag);
- continue;
- }
- }
- if (++ag == mp->m_sb.sb_agcount)
- ag = 0;
- if (ag == startag)
- break;
- xfs_perag_put(pag);
- pag = xfs_perag_get(mp, ag);
- }
- xfs_perag_put(pag);
- /*
- * Since the above loop did a BUF_TRYLOCK, it is
- * possible that there is space for this request.
- */
- if (notinit || blen < ap->minlen)
- args.minlen = ap->minlen;
- /*
- * If the best seen length is less than the request
- * length, use the best as the minimum.
- */
- else if (blen < ap->alen)
- args.minlen = blen;
- /*
- * Otherwise we've seen an extent as big as alen,
- * use that as the minimum.
- */
- else
- args.minlen = ap->alen;
-
- /*
- * set the failure fallback case to look in the selected
- * AG as the stream may have moved.
- */
- if (xfs_inode_is_filestream(ap->ip))
- ap->rval = args.fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
+ error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
+ if (error)
+ return error;
} else if (ap->low) {
if (xfs_inode_is_filestream(ap->ip))
args.type = XFS_ALLOCTYPE_FIRST_AG;
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index cd27c9d6c71..5bba29a0781 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -177,16 +177,26 @@ xfs_swap_extents_check_format(
XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > tip->i_df.if_ext_max)
return EINVAL;
- /* Check root block of temp in btree form to max in target */
+ /*
+ * If we are in a btree format, check that the temp root block will fit
+ * in the target and that it has enough extents to be in btree format
+ * in the target.
+ *
+ * Note that we have to be careful to allow btree->extent conversions
+ * (a common defrag case) which will occur when the temp inode is in
+ * extent format...
+ */
if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_BOFF(ip) &&
- tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip))
+ ((XFS_IFORK_BOFF(ip) &&
+ tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip)) ||
+ XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= ip->i_df.if_ext_max))
return EINVAL;
- /* Check root block of target in btree form to max in temp */
+ /* Reciprocal target->temp btree format checks */
if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
- XFS_IFORK_BOFF(tip) &&
- ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip))
+ ((XFS_IFORK_BOFF(tip) &&
+ ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip)) ||
+ XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= tip->i_df.if_ext_max))
return EINVAL;
return 0;
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index f52ac276277..7cf7220e7d5 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -292,7 +292,8 @@ typedef struct xfs_bstat {
__s32 bs_extents; /* number of extents */
__u32 bs_gen; /* generation count */
__u16 bs_projid; /* project id */
- unsigned char bs_pad[14]; /* pad space, unused */
+ __u16 bs_forkoff; /* inode fork offset in bytes */
+ unsigned char bs_pad[12]; /* pad space, unused */
__u32 bs_dmevmask; /* DMIG event mask */
__u16 bs_dmstate; /* DMIG state info */
__u16 bs_aextents; /* attribute number of extents */
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index e281eb4a1c4..6845db90818 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -190,13 +190,12 @@ xfs_iget_cache_hit(
trace_xfs_iget_reclaim(ip);
/*
- * We need to set XFS_INEW atomically with clearing the
- * reclaimable tag so that we do have an indicator of the
- * inode still being initialized.
+ * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode
+ * from stomping over us while we recycle the inode. We can't
+ * clear the radix tree reclaimable tag yet as it requires
+ * pag_ici_lock to be held exclusive.
*/
- ip->i_flags |= XFS_INEW;
- ip->i_flags &= ~XFS_IRECLAIMABLE;
- __xfs_inode_clear_reclaim_tag(mp, pag, ip);
+ ip->i_flags |= XFS_IRECLAIM;
spin_unlock(&ip->i_flags_lock);
read_unlock(&pag->pag_ici_lock);
@@ -216,7 +215,15 @@ xfs_iget_cache_hit(
trace_xfs_iget_reclaim(ip);
goto out_error;
}
+
+ write_lock(&pag->pag_ici_lock);
+ spin_lock(&ip->i_flags_lock);
+ ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM);
+ ip->i_flags |= XFS_INEW;
+ __xfs_inode_clear_reclaim_tag(mp, pag, ip);
inode->i_state = I_NEW;
+ spin_unlock(&ip->i_flags_lock);
+ write_unlock(&pag->pag_ici_lock);
} else {
/* If the VFS inode is being torn down, pause and try again. */
if (!igrab(inode)) {
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index fa31360046d..0ffd5644704 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2439,75 +2439,31 @@ xfs_idestroy_fork(
}
/*
- * Increment the pin count of the given buffer.
- * This value is protected by ipinlock spinlock in the mount structure.
+ * This is called to unpin an inode. The caller must have the inode locked
+ * in at least shared mode so that the buffer cannot be subsequently pinned
+ * once someone is waiting for it to be unpinned.
*/
-void
-xfs_ipin(
- xfs_inode_t *ip)
-{
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-
- atomic_inc(&ip->i_pincount);
-}
-
-/*
- * Decrement the pin count of the given inode, and wake up
- * anyone in xfs_iwait_unpin() if the count goes to 0. The
- * inode must have been previously pinned with a call to xfs_ipin().
- */
-void
-xfs_iunpin(
- xfs_inode_t *ip)
-{
- ASSERT(atomic_read(&ip->i_pincount) > 0);
-
- if (atomic_dec_and_test(&ip->i_pincount))
- wake_up(&ip->i_ipin_wait);
-}
-
-/*
- * This is called to unpin an inode. It can be directed to wait or to return
- * immediately without waiting for the inode to be unpinned. The caller must
- * have the inode locked in at least shared mode so that the buffer cannot be
- * subsequently pinned once someone is waiting for it to be unpinned.
- */
-STATIC void
-__xfs_iunpin_wait(
- xfs_inode_t *ip,
- int wait)
+static void
+xfs_iunpin_nowait(
+ struct xfs_inode *ip)
{
- xfs_inode_log_item_t *iip = ip->i_itemp;
-
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
- if (atomic_read(&ip->i_pincount) == 0)
- return;
/* Give the log a push to start the unpinning I/O */
- if (iip && iip->ili_last_lsn)
- xfs_log_force_lsn(ip->i_mount, iip->ili_last_lsn, 0);
- else
- xfs_log_force(ip->i_mount, 0);
+ xfs_log_force_lsn(ip->i_mount, ip->i_itemp->ili_last_lsn, 0);
- if (wait)
- wait_event(ip->i_ipin_wait, (atomic_read(&ip->i_pincount) == 0));
}
void
xfs_iunpin_wait(
- xfs_inode_t *ip)
+ struct xfs_inode *ip)
{
- __xfs_iunpin_wait(ip, 1);
-}
-
-static inline void
-xfs_iunpin_nowait(
- xfs_inode_t *ip)
-{
- __xfs_iunpin_wait(ip, 0);
+ if (xfs_ipincount(ip)) {
+ xfs_iunpin_nowait(ip);
+ wait_event(ip->i_ipin_wait, (xfs_ipincount(ip) == 0));
+ }
}
-
/*
* xfs_iextents_copy()
*
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 6c912b02759..9965e40a461 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -471,8 +471,6 @@ int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *,
int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
void xfs_iext_realloc(xfs_inode_t *, int, int);
-void xfs_ipin(xfs_inode_t *);
-void xfs_iunpin(xfs_inode_t *);
void xfs_iunpin_wait(xfs_inode_t *);
int xfs_iflush(xfs_inode_t *, uint);
void xfs_ichgtime(xfs_inode_t *, int);
@@ -480,6 +478,7 @@ void xfs_lock_inodes(xfs_inode_t **, int, uint);
void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint);
void xfs_synchronize_times(xfs_inode_t *);
+void xfs_mark_inode_dirty(xfs_inode_t *);
void xfs_mark_inode_dirty_sync(xfs_inode_t *);
#define IHOLD(ip) \
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index d4dc063111f..7bfea854015 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -535,23 +535,23 @@ xfs_inode_item_format(
/*
* This is called to pin the inode associated with the inode log
- * item in memory so it cannot be written out. Do this by calling
- * xfs_ipin() to bump the pin count in the inode while holding the
- * inode pin lock.
+ * item in memory so it cannot be written out.
*/
STATIC void
xfs_inode_item_pin(
xfs_inode_log_item_t *iip)
{
ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL));
- xfs_ipin(iip->ili_inode);
+
+ atomic_inc(&iip->ili_inode->i_pincount);
}
/*
* This is called to unpin the inode associated with the inode log
* item which was previously pinned with a call to xfs_inode_item_pin().
- * Just call xfs_iunpin() on the inode to do this.
+ *
+ * Also wake up anyone in xfs_iunpin_wait() if the count goes to 0.
*/
/* ARGSUSED */
STATIC void
@@ -559,7 +559,11 @@ xfs_inode_item_unpin(
xfs_inode_log_item_t *iip,
int stale)
{
- xfs_iunpin(iip->ili_inode);
+ struct xfs_inode *ip = iip->ili_inode;
+
+ ASSERT(atomic_read(&ip->i_pincount) > 0);
+ if (atomic_dec_and_test(&ip->i_pincount))
+ wake_up(&ip->i_ipin_wait);
}
/* ARGSUSED */
@@ -568,7 +572,7 @@ xfs_inode_item_unpin_remove(
xfs_inode_log_item_t *iip,
xfs_trans_t *tp)
{
- xfs_iunpin(iip->ili_inode);
+ xfs_inode_item_unpin(iip, 0);
}
/*
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 3af02314c60..b1b801e4a28 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -106,6 +106,7 @@ xfs_bulkstat_one_iget(
buf->bs_dmevmask = dic->di_dmevmask;
buf->bs_dmstate = dic->di_dmstate;
buf->bs_aextents = dic->di_anextents;
+ buf->bs_forkoff = XFS_IFORK_BOFF(ip);
switch (dic->di_format) {
case XFS_DINODE_FMT_DEV:
@@ -176,6 +177,7 @@ xfs_bulkstat_one_dinode(
buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask);
buf->bs_dmstate = be16_to_cpu(dic->di_dmstate);
buf->bs_aextents = be16_to_cpu(dic->di_anextents);
+ buf->bs_forkoff = XFS_DFORK_BOFF(dic);
switch (dic->di_format) {
case XFS_DINODE_FMT_DEV:
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 4f16be4b6ee..2be01913628 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -60,7 +60,7 @@ STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes);
STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
STATIC void xlog_dealloc_log(xlog_t *log);
STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[],
- int nentries, xfs_log_ticket_t tic,
+ int nentries, struct xlog_ticket *tic,
xfs_lsn_t *start_lsn,
xlog_in_core_t **commit_iclog,
uint flags);
@@ -243,14 +243,14 @@ xlog_tic_add_region(xlog_ticket_t *tic, uint len, uint type)
* out when the next write occurs.
*/
xfs_lsn_t
-xfs_log_done(xfs_mount_t *mp,
- xfs_log_ticket_t xtic,
- void **iclog,
- uint flags)
+xfs_log_done(
+ struct xfs_mount *mp,
+ struct xlog_ticket *ticket,
+ struct xlog_in_core **iclog,
+ uint flags)
{
- xlog_t *log = mp->m_log;
- xlog_ticket_t *ticket = (xfs_log_ticket_t) xtic;
- xfs_lsn_t lsn = 0;
+ struct log *log = mp->m_log;
+ xfs_lsn_t lsn = 0;
if (XLOG_FORCED_SHUTDOWN(log) ||
/*
@@ -258,8 +258,7 @@ xfs_log_done(xfs_mount_t *mp,
* If we get an error, just continue and give back the log ticket.
*/
(((ticket->t_flags & XLOG_TIC_INITED) == 0) &&
- (xlog_commit_record(mp, ticket,
- (xlog_in_core_t **)iclog, &lsn)))) {
+ (xlog_commit_record(mp, ticket, iclog, &lsn)))) {
lsn = (xfs_lsn_t) -1;
if (ticket->t_flags & XLOG_TIC_PERM_RESERV) {
flags |= XFS_LOG_REL_PERM_RESERV;
@@ -289,7 +288,7 @@ xfs_log_done(xfs_mount_t *mp,
}
return lsn;
-} /* xfs_log_done */
+}
/*
* Attaches a new iclog I/O completion callback routine during
@@ -298,11 +297,11 @@ xfs_log_done(xfs_mount_t *mp,
* executing the callback at an appropriate time.
*/
int
-xfs_log_notify(xfs_mount_t *mp, /* mount of partition */
- void *iclog_hndl, /* iclog to hang callback off */
- xfs_log_callback_t *cb)
+xfs_log_notify(
+ struct xfs_mount *mp,
+ struct xlog_in_core *iclog,
+ xfs_log_callback_t *cb)
{
- xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
int abortflg;
spin_lock(&iclog->ic_callback_lock);
@@ -316,16 +315,14 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */
}
spin_unlock(&iclog->ic_callback_lock);
return abortflg;
-} /* xfs_log_notify */
+}
int
-xfs_log_release_iclog(xfs_mount_t *mp,
- void *iclog_hndl)
+xfs_log_release_iclog(
+ struct xfs_mount *mp,
+ struct xlog_in_core *iclog)
{
- xlog_t *log = mp->m_log;
- xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
-
- if (xlog_state_release_iclog(log, iclog)) {
+ if (xlog_state_release_iclog(mp->m_log, iclog)) {
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
return EIO;
}
@@ -344,17 +341,18 @@ xfs_log_release_iclog(xfs_mount_t *mp,
* reservation, we prevent over allocation problems.
*/
int
-xfs_log_reserve(xfs_mount_t *mp,
- int unit_bytes,
- int cnt,
- xfs_log_ticket_t *ticket,
- __uint8_t client,
- uint flags,
- uint t_type)
+xfs_log_reserve(
+ struct xfs_mount *mp,
+ int unit_bytes,
+ int cnt,
+ struct xlog_ticket **ticket,
+ __uint8_t client,
+ uint flags,
+ uint t_type)
{
- xlog_t *log = mp->m_log;
- xlog_ticket_t *internal_ticket;
- int retval = 0;
+ struct log *log = mp->m_log;
+ struct xlog_ticket *internal_ticket;
+ int retval = 0;
ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);
ASSERT((flags & XFS_LOG_NOSLEEP) == 0);
@@ -367,7 +365,7 @@ xfs_log_reserve(xfs_mount_t *mp,
if (*ticket != NULL) {
ASSERT(flags & XFS_LOG_PERM_RESERV);
- internal_ticket = (xlog_ticket_t *)*ticket;
+ internal_ticket = *ticket;
trace_xfs_log_reserve(log, internal_ticket);
@@ -519,7 +517,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
xlog_in_core_t *first_iclog;
#endif
xfs_log_iovec_t reg[1];
- xfs_log_ticket_t tic = NULL;
+ xlog_ticket_t *tic = NULL;
xfs_lsn_t lsn;
int error;
@@ -656,24 +654,24 @@ xfs_log_unmount(xfs_mount_t *mp)
* transaction occur with one call to xfs_log_write().
*/
int
-xfs_log_write(xfs_mount_t * mp,
- xfs_log_iovec_t reg[],
- int nentries,
- xfs_log_ticket_t tic,
- xfs_lsn_t *start_lsn)
+xfs_log_write(
+ struct xfs_mount *mp,
+ struct xfs_log_iovec reg[],
+ int nentries,
+ struct xlog_ticket *tic,
+ xfs_lsn_t *start_lsn)
{
- int error;
- xlog_t *log = mp->m_log;
+ struct log *log = mp->m_log;
+ int error;
if (XLOG_FORCED_SHUTDOWN(log))
return XFS_ERROR(EIO);
- if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
+ error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0);
+ if (error)
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
- }
return error;
-} /* xfs_log_write */
-
+}
void
xfs_log_move_tail(xfs_mount_t *mp,
@@ -747,9 +745,16 @@ xfs_log_move_tail(xfs_mount_t *mp,
/*
* Determine if we have a transaction that has gone to disk
- * that needs to be covered. Log activity needs to be idle (no AIL and
- * nothing in the iclogs). And, we need to be in the right state indicating
- * something has gone out.
+ * that needs to be covered. To begin the transition to the idle state
+ * firstly the log needs to be idle (no AIL and nothing in the iclogs).
+ * If we are then in a state where covering is needed, the caller is informed
+ * that dummy transactions are required to move the log into the idle state.
+ *
+ * Because this is called as part of the sync process, we should also indicate
+ * that dummy transactions should be issued in anything but the covered or
+ * idle states. This ensures that the log tail is accurately reflected in
+ * the log at the end of the sync, hence if a crash occurrs avoids replay
+ * of transactions where the metadata is already on disk.
*/
int
xfs_log_need_covered(xfs_mount_t *mp)
@@ -761,17 +766,24 @@ xfs_log_need_covered(xfs_mount_t *mp)
return 0;
spin_lock(&log->l_icloglock);
- if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
- (log->l_covered_state == XLOG_STATE_COVER_NEED2))
- && !xfs_trans_ail_tail(log->l_ailp)
- && xlog_iclogs_empty(log)) {
- if (log->l_covered_state == XLOG_STATE_COVER_NEED)
- log->l_covered_state = XLOG_STATE_COVER_DONE;
- else {
- ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2);
- log->l_covered_state = XLOG_STATE_COVER_DONE2;
+ switch (log->l_covered_state) {
+ case XLOG_STATE_COVER_DONE:
+ case XLOG_STATE_COVER_DONE2:
+ case XLOG_STATE_COVER_IDLE:
+ break;
+ case XLOG_STATE_COVER_NEED:
+ case XLOG_STATE_COVER_NEED2:
+ if (!xfs_trans_ail_tail(log->l_ailp) &&
+ xlog_iclogs_empty(log)) {
+ if (log->l_covered_state == XLOG_STATE_COVER_NEED)
+ log->l_covered_state = XLOG_STATE_COVER_DONE;
+ else
+ log->l_covered_state = XLOG_STATE_COVER_DONE2;
}
+ /* FALLTHRU */
+ default:
needed = 1;
+ break;
}
spin_unlock(&log->l_icloglock);
return needed;
@@ -1642,16 +1654,16 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket)
* bytes have been written out.
*/
STATIC int
-xlog_write(xfs_mount_t * mp,
- xfs_log_iovec_t reg[],
- int nentries,
- xfs_log_ticket_t tic,
- xfs_lsn_t *start_lsn,
- xlog_in_core_t **commit_iclog,
- uint flags)
+xlog_write(
+ struct xfs_mount *mp,
+ struct xfs_log_iovec reg[],
+ int nentries,
+ struct xlog_ticket *ticket,
+ xfs_lsn_t *start_lsn,
+ struct xlog_in_core **commit_iclog,
+ uint flags)
{
xlog_t *log = mp->m_log;
- xlog_ticket_t *ticket = (xlog_ticket_t *)tic;
xlog_in_core_t *iclog = NULL; /* ptr to current in-core log */
xlog_op_header_t *logop_head; /* ptr to log operation header */
__psint_t ptr; /* copy address into data region */
@@ -1765,7 +1777,7 @@ xlog_write(xfs_mount_t * mp,
default:
xfs_fs_cmn_err(CE_WARN, mp,
"Bad XFS transaction clientid 0x%x in ticket 0x%p",
- logop_head->oh_clientid, tic);
+ logop_head->oh_clientid, ticket);
return XFS_ERROR(EIO);
}
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 7074be9d13e..97a24c7795a 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -110,8 +110,6 @@ typedef struct xfs_log_iovec {
uint i_type; /* type of region */
} xfs_log_iovec_t;
-typedef void* xfs_log_ticket_t;
-
/*
* Structure used to pass callback function and the function's argument
* to the log manager.
@@ -126,10 +124,12 @@ typedef struct xfs_log_callback {
#ifdef __KERNEL__
/* Log manager interfaces */
struct xfs_mount;
+struct xlog_in_core;
struct xlog_ticket;
+
xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
- xfs_log_ticket_t ticket,
- void **iclog,
+ struct xlog_ticket *ticket,
+ struct xlog_in_core **iclog,
uint flags);
int _xfs_log_force(struct xfs_mount *mp,
uint flags,
@@ -151,21 +151,21 @@ int xfs_log_mount_finish(struct xfs_mount *mp);
void xfs_log_move_tail(struct xfs_mount *mp,
xfs_lsn_t tail_lsn);
int xfs_log_notify(struct xfs_mount *mp,
- void *iclog,
+ struct xlog_in_core *iclog,
xfs_log_callback_t *callback_entry);
int xfs_log_release_iclog(struct xfs_mount *mp,
- void *iclog_hndl);
+ struct xlog_in_core *iclog);
int xfs_log_reserve(struct xfs_mount *mp,
int length,
int count,
- xfs_log_ticket_t *ticket,
+ struct xlog_ticket **ticket,
__uint8_t clientid,
uint flags,
uint t_type);
int xfs_log_write(struct xfs_mount *mp,
xfs_log_iovec_t region[],
int nentries,
- xfs_log_ticket_t ticket,
+ struct xlog_ticket *ticket,
xfs_lsn_t *start_lsn);
int xfs_log_unmount_write(struct xfs_mount *mp);
void xfs_log_unmount(struct xfs_mount *mp);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 6afaaeb2950..e79b56b4bca 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1097,13 +1097,15 @@ xfs_default_resblks(xfs_mount_t *mp)
__uint64_t resblks;
/*
- * We default to 5% or 1024 fsbs of space reserved, whichever is smaller.
- * This may drive us straight to ENOSPC on mount, but that implies
- * we were already there on the last unmount. Warn if this occurs.
+ * We default to 5% or 8192 fsbs of space reserved, whichever is
+ * smaller. This is intended to cover concurrent allocation
+ * transactions when we initially hit enospc. These each require a 4
+ * block reservation. Hence by default we cover roughly 2000 concurrent
+ * allocation reservations.
*/
resblks = mp->m_sb.sb_dblocks;
do_div(resblks, 20);
- resblks = min_t(__uint64_t, resblks, 1024);
+ resblks = min_t(__uint64_t, resblks, 8192);
return resblks;
}
@@ -1417,6 +1419,9 @@ xfs_mountfs(
* when at ENOSPC. This is needed for operations like create with
* attr, unwritten extent conversion at ENOSPC, etc. Data allocations
* are not allowed to use this reserved space.
+ *
+ * This may drive us straight to ENOSPC on mount, but that implies
+ * we were already there on the last unmount. Warn if this occurs.
*/
if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
resblks = xfs_default_resblks(mp);
@@ -1725,26 +1730,30 @@ xfs_mod_incore_sb_unlocked(
lcounter += rem;
}
} else { /* Taking blocks away */
-
lcounter += delta;
+ if (lcounter >= 0) {
+ mp->m_sb.sb_fdblocks = lcounter +
+ XFS_ALLOC_SET_ASIDE(mp);
+ return 0;
+ }
- /*
- * If were out of blocks, use any available reserved blocks if
- * were allowed to.
- */
+ /*
+ * We are out of blocks, use any available reserved
+ * blocks if were allowed to.
+ */
+ if (!rsvd)
+ return XFS_ERROR(ENOSPC);
- if (lcounter < 0) {
- if (rsvd) {
- lcounter = (long long)mp->m_resblks_avail + delta;
- if (lcounter < 0) {
- return XFS_ERROR(ENOSPC);
- }
- mp->m_resblks_avail = lcounter;
- return 0;
- } else { /* not reserved */
- return XFS_ERROR(ENOSPC);
- }
+ lcounter = (long long)mp->m_resblks_avail + delta;
+ if (lcounter >= 0) {
+ mp->m_resblks_avail = lcounter;
+ return 0;
}
+ printk_once(KERN_WARNING
+ "Filesystem \"%s\": reserve blocks depleted! "
+ "Consider increasing reserve pool size.",
+ mp->m_fsname);
+ return XFS_ERROR(ENOSPC);
}
mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
@@ -2052,6 +2061,26 @@ xfs_mount_log_sb(
return error;
}
+/*
+ * If the underlying (data/log/rt) device is readonly, there are some
+ * operations that cannot proceed.
+ */
+int
+xfs_dev_is_read_only(
+ struct xfs_mount *mp,
+ char *message)
+{
+ if (xfs_readonly_buftarg(mp->m_ddev_targp) ||
+ xfs_readonly_buftarg(mp->m_logdev_targp) ||
+ (mp->m_rtdev_targp && xfs_readonly_buftarg(mp->m_rtdev_targp))) {
+ cmn_err(CE_NOTE,
+ "XFS: %s required on read-only device.", message);
+ cmn_err(CE_NOTE,
+ "XFS: write access unavailable, cannot proceed.");
+ return EROFS;
+ }
+ return 0;
+}
#ifdef HAVE_PERCPU_SB
/*
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 14dafd60823..9ff48a16a7e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -259,6 +259,7 @@ typedef struct xfs_mount {
wait_queue_head_t m_wait_single_sync_task;
__int64_t m_update_flags; /* sb flags we need to update
on the next remount,rw */
+ struct list_head m_mplist; /* inode shrinker mount list */
} xfs_mount_t;
/*
@@ -436,6 +437,8 @@ extern void xfs_freesb(xfs_mount_t *);
extern int xfs_fs_writable(xfs_mount_t *);
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 *);
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index be942d4e332..f73e358bae8 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -796,7 +796,7 @@ _xfs_trans_commit(
int sync;
#define XFS_TRANS_LOGVEC_COUNT 16
xfs_log_iovec_t log_vector_fast[XFS_TRANS_LOGVEC_COUNT];
- void *commit_iclog;
+ struct xlog_in_core *commit_iclog;
int shutdown;
commit_lsn = -1;
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index c93e3a10285..79c8bab9dff 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -910,7 +910,7 @@ typedef struct xfs_trans {
unsigned int t_blk_res_used; /* # of resvd blocks used */
unsigned int t_rtx_res; /* # of rt extents resvd */
unsigned int t_rtx_res_used; /* # of resvd rt extents used */
- xfs_log_ticket_t t_ticket; /* log mgr ticket */
+ struct xlog_ticket *t_ticket; /* log mgr ticket */
xfs_lsn_t t_lsn; /* log seq num of start of
* transaction. */
xfs_lsn_t t_commit_lsn; /* log seq num of end of
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 5ffd544434e..fb586360d1c 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -46,6 +46,65 @@ STATIC xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, xfs_buftarg_t *,
STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *,
xfs_daddr_t, int);
+/*
+ * Add the locked buffer to the transaction.
+ *
+ * The buffer must be locked, and it cannot be associated with any
+ * transaction.
+ *
+ * If the buffer does not yet have a buf log item associated with it,
+ * then allocate one for it. Then add the buf item to the transaction.
+ */
+STATIC void
+_xfs_trans_bjoin(
+ struct xfs_trans *tp,
+ struct xfs_buf *bp,
+ int reset_recur)
+{
+ struct xfs_buf_log_item *bip;
+
+ ASSERT(XFS_BUF_ISBUSY(bp));
+ ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
+
+ /*
+ * The xfs_buf_log_item pointer is stored in b_fsprivate. If
+ * it doesn't have one yet, then allocate one and initialize it.
+ * The checks to see if one is there are in xfs_buf_item_init().
+ */
+ xfs_buf_item_init(bp, tp->t_mountp);
+ bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
+ ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
+ ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
+ ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
+ if (reset_recur)
+ bip->bli_recur = 0;
+
+ /*
+ * Take a reference for this transaction on the buf item.
+ */
+ atomic_inc(&bip->bli_refcount);
+
+ /*
+ * Get a log_item_desc to point at the new item.
+ */
+ (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
+
+ /*
+ * Initialize b_fsprivate2 so we can find it with incore_match()
+ * in xfs_trans_get_buf() and friends above.
+ */
+ XFS_BUF_SET_FSPRIVATE2(bp, tp);
+
+}
+
+void
+xfs_trans_bjoin(
+ struct xfs_trans *tp,
+ struct xfs_buf *bp)
+{
+ _xfs_trans_bjoin(tp, bp, 0);
+ trace_xfs_trans_bjoin(bp->b_fspriv);
+}
/*
* Get and lock the buffer for the caller if it is not already
@@ -132,40 +191,8 @@ xfs_trans_get_buf(xfs_trans_t *tp,
ASSERT(!XFS_BUF_GETERROR(bp));
- /*
- * The xfs_buf_log_item pointer is stored in b_fsprivate. If
- * it doesn't have one yet, then allocate one and initialize it.
- * The checks to see if one is there are in xfs_buf_item_init().
- */
- xfs_buf_item_init(bp, tp->t_mountp);
-
- /*
- * Set the recursion count for the buffer within this transaction
- * to 0.
- */
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
- bip->bli_recur = 0;
-
- /*
- * Take a reference for this transaction on the buf item.
- */
- atomic_inc(&bip->bli_refcount);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
-
- /*
- * Initialize b_fsprivate2 so we can find it with incore_match()
- * above.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, tp);
-
- trace_xfs_trans_get_buf(bip);
+ _xfs_trans_bjoin(tp, bp, 1);
+ trace_xfs_trans_get_buf(bp->b_fspriv);
return (bp);
}
@@ -210,44 +237,11 @@ xfs_trans_getsb(xfs_trans_t *tp,
}
bp = xfs_getsb(mp, flags);
- if (bp == NULL) {
+ if (bp == NULL)
return NULL;
- }
-
- /*
- * The xfs_buf_log_item pointer is stored in b_fsprivate. If
- * it doesn't have one yet, then allocate one and initialize it.
- * The checks to see if one is there are in xfs_buf_item_init().
- */
- xfs_buf_item_init(bp, mp);
-
- /*
- * Set the recursion count for the buffer within this transaction
- * to 0.
- */
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
- bip->bli_recur = 0;
-
- /*
- * Take a reference for this transaction on the buf item.
- */
- atomic_inc(&bip->bli_refcount);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
-
- /*
- * Initialize b_fsprivate2 so we can find it with incore_match()
- * above.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, tp);
- trace_xfs_trans_getsb(bip);
+ _xfs_trans_bjoin(tp, bp, 1);
+ trace_xfs_trans_getsb(bp->b_fspriv);
return (bp);
}
@@ -425,40 +419,9 @@ xfs_trans_read_buf(
if (XFS_FORCED_SHUTDOWN(mp))
goto shutdown_abort;
- /*
- * The xfs_buf_log_item pointer is stored in b_fsprivate. If
- * it doesn't have one yet, then allocate one and initialize it.
- * The checks to see if one is there are in xfs_buf_item_init().
- */
- xfs_buf_item_init(bp, tp->t_mountp);
+ _xfs_trans_bjoin(tp, bp, 1);
+ trace_xfs_trans_read_buf(bp->b_fspriv);
- /*
- * Set the recursion count for the buffer within this transaction
- * to 0.
- */
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
- bip->bli_recur = 0;
-
- /*
- * Take a reference for this transaction on the buf item.
- */
- atomic_inc(&bip->bli_refcount);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
-
- /*
- * Initialize b_fsprivate2 so we can find it with incore_match()
- * above.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, tp);
-
- trace_xfs_trans_read_buf(bip);
*bpp = bp;
return 0;
@@ -623,53 +586,6 @@ xfs_trans_brelse(xfs_trans_t *tp,
}
/*
- * Add the locked buffer to the transaction.
- * The buffer must be locked, and it cannot be associated with any
- * transaction.
- *
- * If the buffer does not yet have a buf log item associated with it,
- * then allocate one for it. Then add the buf item to the transaction.
- */
-void
-xfs_trans_bjoin(xfs_trans_t *tp,
- xfs_buf_t *bp)
-{
- xfs_buf_log_item_t *bip;
-
- ASSERT(XFS_BUF_ISBUSY(bp));
- ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
-
- /*
- * The xfs_buf_log_item pointer is stored in b_fsprivate. If
- * it doesn't have one yet, then allocate one and initialize it.
- * The checks to see if one is there are in xfs_buf_item_init().
- */
- xfs_buf_item_init(bp, tp->t_mountp);
- bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
- ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
- ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
-
- /*
- * Take a reference for this transaction on the buf item.
- */
- atomic_inc(&bip->bli_refcount);
-
- /*
- * Get a log_item_desc to point at the new item.
- */
- (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
-
- /*
- * Initialize b_fsprivate2 so we can find it with incore_match()
- * in xfs_trans_get_buf() and friends above.
- */
- XFS_BUF_SET_FSPRIVATE2(bp, tp);
-
- trace_xfs_trans_bjoin(bip);
-}
-
-/*
* Mark the buffer as not needing to be unlocked when the buf item's
* IOP_UNLOCK() routine is called. The buffer must already be locked
* and associated with the given transaction.
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index ddd2c5d1b85..9d376be0ea3 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -584,113 +584,6 @@ xfs_readlink(
}
/*
- * xfs_fsync
- *
- * This is called to sync the inode and its data out to disk. We need to hold
- * the I/O lock while flushing the data, and the inode lock while flushing the
- * inode. The inode lock CANNOT be held while flushing the data, so acquire
- * after we're done with that.
- */
-int
-xfs_fsync(
- xfs_inode_t *ip)
-{
- xfs_trans_t *tp;
- int error = 0;
- int log_flushed = 0;
-
- xfs_itrace_entry(ip);
-
- if (XFS_FORCED_SHUTDOWN(ip->i_mount))
- return XFS_ERROR(EIO);
-
- /*
- * We always need to make sure that the required inode state is safe on
- * disk. The inode might be clean but we still might need to force the
- * log because of committed transactions that haven't hit the disk yet.
- * Likewise, there could be unflushed non-transactional changes to the
- * inode core that have to go to disk and this requires us to issue
- * a synchronous transaction to capture these changes correctly.
- *
- * This code relies on the assumption that if the update_* fields
- * of the inode are clear and the inode is unpinned then it is clean
- * and no action is required.
- */
- xfs_ilock(ip, XFS_ILOCK_SHARED);
-
- if (!ip->i_update_core) {
- /*
- * Timestamps/size haven't changed since last inode flush or
- * inode transaction commit. That means either nothing got
- * written or a transaction committed which caught the updates.
- * If the latter happened and the transaction hasn't hit the
- * disk yet, the inode will be still be pinned. If it is,
- * force the log.
- */
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- if (xfs_ipincount(ip)) {
- if (ip->i_itemp->ili_last_lsn) {
- error = _xfs_log_force_lsn(ip->i_mount,
- ip->i_itemp->ili_last_lsn,
- XFS_LOG_SYNC, &log_flushed);
- } else {
- error = _xfs_log_force(ip->i_mount,
- XFS_LOG_SYNC, &log_flushed);
- }
- }
- } else {
- /*
- * Kick off a transaction to log the inode core to get the
- * updates. The sync transaction will also force the log.
- */
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
- error = xfs_trans_reserve(tp, 0,
- XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0);
- if (error) {
- xfs_trans_cancel(tp, 0);
- return error;
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL);
-
- /*
- * Note - it's possible that we might have pushed ourselves out
- * of the way during trans_reserve which would flush the inode.
- * But there's no guarantee that the inode buffer has actually
- * gone out yet (it's delwri). Plus the buffer could be pinned
- * anyway if it's part of 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_log_inode(tp, ip, XFS_ILOG_CORE);
- xfs_trans_set_sync(tp);
- error = _xfs_trans_commit(tp, 0, &log_flushed);
-
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- }
-
- if (ip->i_mount->m_flags & XFS_MOUNT_BARRIER) {
- /*
- * If the log write didn't issue an ordered tag we need
- * to flush the disk cache for the data device now.
- */
- if (!log_flushed)
- xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
-
- /*
- * If this inode is on the RT dev we need to flush that
- * cache as well.
- */
- if (XFS_IS_REALTIME_INODE(ip))
- xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
- }
-
- return error;
-}
-
-/*
* Flags for xfs_free_eofblocks
*/
#define XFS_FREE_EOF_TRYLOCK (1<<0)
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 774f40729ca..d8dfa8d0dad 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -21,7 +21,6 @@ int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags);
#define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */
int xfs_readlink(struct xfs_inode *ip, char *link);
-int xfs_fsync(struct xfs_inode *ip);
int xfs_release(struct xfs_inode *ip);
int xfs_inactive(struct xfs_inode *ip);
int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,
@@ -50,18 +49,6 @@ int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,
int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags);
int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
int flags, struct attrlist_cursor_kern *cursor);
-ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb,
- const struct iovec *iovp, unsigned int segs,
- loff_t *offset, int ioflags);
-ssize_t xfs_splice_read(struct xfs_inode *ip, struct file *infilp,
- loff_t *ppos, struct pipe_inode_info *pipe, size_t count,
- int flags, int ioflags);
-ssize_t xfs_splice_write(struct xfs_inode *ip,
- struct pipe_inode_info *pipe, struct file *outfilp,
- loff_t *ppos, size_t count, int flags, int ioflags);
-ssize_t xfs_write(struct xfs_inode *xip, struct kiocb *iocb,
- const struct iovec *iovp, unsigned int nsegs,
- loff_t *offset, int ioflags);
int xfs_bmap(struct xfs_inode *ip, xfs_off_t offset, ssize_t count,
int flags, struct xfs_iomap *iomapp, int *niomaps);
void xfs_tosspages(struct xfs_inode *inode, xfs_off_t first,
@@ -72,4 +59,6 @@ int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first,
xfs_off_t last, uint64_t flags, int fiopt);
int xfs_wait_on_pages(struct xfs_inode *ip, xfs_off_t first, xfs_off_t last);
+int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t);
+
#endif /* _XFS_VNODEOPS_H */
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 3a4767c01c5..4f7b44866b7 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -65,6 +65,8 @@
#define ACPI_VIDEO_HID "LNXVIDEO"
#define ACPI_BAY_HID "LNXIOBAY"
#define ACPI_DOCK_HID "LNXDOCK"
+/* Quirk for broken IBM BIOSes */
+#define ACPI_SMBUS_IBM_HID "SMBUSIBM"
/*
* For fixed hardware buttons, we fabricate acpi_devices with HID
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 1172c27adad..86825ddbe14 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -320,8 +320,16 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
#endif /* CONFIG_CPU_FREQ */
-/* in processor_pdc.c */
+/* in processor_core.c */
void acpi_processor_set_pdc(acpi_handle handle);
+#ifdef CONFIG_SMP
+int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id);
+#else
+static inline int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
+{
+ return -1;
+}
+#endif
/* in processor_throttling.c */
int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 485eeb6c4ef..979c6a57f2f 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -136,6 +136,32 @@ extern int __gpio_cansleep(unsigned gpio);
extern int __gpio_to_irq(unsigned gpio);
+#define GPIOF_DIR_OUT (0 << 0)
+#define GPIOF_DIR_IN (1 << 0)
+
+#define GPIOF_INIT_LOW (0 << 1)
+#define GPIOF_INIT_HIGH (1 << 1)
+
+#define GPIOF_IN (GPIOF_DIR_IN)
+#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW)
+#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
+
+/**
+ * struct gpio - a structure describing a GPIO with configuration
+ * @gpio: the GPIO number
+ * @flags: GPIO configuration as specified by GPIOF_*
+ * @label: a literal description string of this GPIO
+ */
+struct gpio {
+ unsigned gpio;
+ unsigned long flags;
+ const char *label;
+};
+
+extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
+extern int gpio_request_array(struct gpio *array, size_t num);
+extern void gpio_free_array(struct gpio *array, size_t num);
+
#ifdef CONFIG_GPIO_SYSFS
/*
diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h
index 37b3706226e..1437b7da09b 100644
--- a/include/asm-generic/pci-dma-compat.h
+++ b/include/asm-generic/pci-dma-compat.h
@@ -6,9 +6,6 @@
#include <linux/dma-mapping.h>
-/* note pci_set_dma_mask isn't here, since it's a public function
- * exported from drivers/pci, use dma_supported instead */
-
static inline int
pci_dma_supported(struct pci_dev *hwdev, u64 mask)
{
@@ -104,4 +101,16 @@ pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr)
return dma_mapping_error(&pdev->dev, dma_addr);
}
+#ifdef CONFIG_PCI
+static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ return dma_set_mask(&dev->dev, mask);
+}
+
+static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ return dma_set_coherent_mask(&dev->dev, mask);
+}
+#endif
+
#endif
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 4a3c4e44102..2f3b3a00b7a 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -55,6 +55,7 @@
#include <linux/mm.h>
#include <linux/cdev.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#if defined(__alpha__) || defined(__powerpc__)
#include <asm/pgtable.h> /* For pte_wrprotect */
#endif
@@ -1545,39 +1546,7 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
{
}
-
-static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
-{
- if (size != 0 && nmemb > ULONG_MAX / size)
- return NULL;
-
- if (size * nmemb <= PAGE_SIZE)
- return kcalloc(nmemb, size, GFP_KERNEL);
-
- return __vmalloc(size * nmemb,
- GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
-}
-
-/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
-static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
-{
- if (size != 0 && nmemb > ULONG_MAX / size)
- return NULL;
-
- if (size * nmemb <= PAGE_SIZE)
- return kmalloc(nmemb * size, GFP_KERNEL);
-
- return __vmalloc(size * nmemb,
- GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
-static __inline void drm_free_large(void *ptr)
-{
- if (!is_vmalloc_addr(ptr))
- return kfree(ptr);
-
- vfree(ptr);
-}
+#include "drm_mem_util.h"
/*@}*/
#endif /* __KERNEL__ */
diff --git a/include/drm/drm_mem_util.h b/include/drm/drm_mem_util.h
new file mode 100644
index 00000000000..6bd325fedc8
--- /dev/null
+++ b/include/drm/drm_mem_util.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ */
+#ifndef _DRM_MEM_UTIL_H_
+#define _DRM_MEM_UTIL_H_
+
+#include <linux/vmalloc.h>
+
+static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
+{
+ if (size != 0 && nmemb > ULONG_MAX / size)
+ return NULL;
+
+ if (size * nmemb <= PAGE_SIZE)
+ return kcalloc(nmemb, size, GFP_KERNEL);
+
+ return __vmalloc(size * nmemb,
+ GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
+}
+
+/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
+static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
+{
+ if (size != 0 && nmemb > ULONG_MAX / size)
+ return NULL;
+
+ if (size * nmemb <= PAGE_SIZE)
+ return kmalloc(nmemb * size, GFP_KERNEL);
+
+ return __vmalloc(size * nmemb,
+ GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+}
+
+static __inline void drm_free_large(void *ptr)
+{
+ if (!is_vmalloc_addr(ptr))
+ return kfree(ptr);
+
+ vfree(ptr);
+}
+
+#endif
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index 676104b7818..2d428b088cc 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -6,6 +6,7 @@
{0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \
@@ -410,6 +411,7 @@
{0x1002, 0x9712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
{0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
{0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+ {0x1002, 0x9715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
{0, 0, 0}
#define r128_PCI_IDS \
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index e3f1b4a4b60..e929c27ede2 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -115,7 +115,6 @@ struct ttm_backend {
struct ttm_backend_func *func;
};
-#define TTM_PAGE_FLAG_VMALLOC (1 << 0)
#define TTM_PAGE_FLAG_USER (1 << 1)
#define TTM_PAGE_FLAG_USER_DIRTY (1 << 2)
#define TTM_PAGE_FLAG_WRITE (1 << 3)
diff --git a/include/linux/acct.h b/include/linux/acct.h
index 882dc724876..3e4737fa6cc 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -121,16 +121,15 @@ struct vfsmount;
struct super_block;
struct pacct_struct;
struct pid_namespace;
+extern int acct_parm[]; /* for sysctl */
extern void acct_auto_close_mnt(struct vfsmount *m);
extern void acct_auto_close(struct super_block *sb);
-extern void acct_init_pacct(struct pacct_struct *pacct);
extern void acct_collect(long exitcode, int group_dead);
extern void acct_process(void);
extern void acct_exit_ns(struct pid_namespace *);
#else
#define acct_auto_close_mnt(x) do { } while (0)
#define acct_auto_close(x) do { } while (0)
-#define acct_init_pacct(x) do { } while (0)
#define acct_collect(x,y) do { } while (0)
#define acct_process() do { } while (0)
#define acct_exit_ns(ns) do { } while (0)
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index 6816be6c3f7..8b103860783 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -14,6 +14,9 @@
#ifndef ASMARM_AMBA_H
#define ASMARM_AMBA_H
+#include <linux/device.h>
+#include <linux/resource.h>
+
#define AMBA_NR_IRQS 2
struct amba_device {
diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h
index 29c0448265c..ca16c3801a1 100644
--- a/include/linux/amba/clcd.h
+++ b/include/linux/amba/clcd.h
@@ -21,22 +21,21 @@
#define CLCD_UBAS 0x00000010
#define CLCD_LBAS 0x00000014
-#if !defined(CONFIG_ARCH_VERSATILE) && !defined(CONFIG_ARCH_REALVIEW)
-#define CLCD_IENB 0x00000018
-#define CLCD_CNTL 0x0000001c
-#else
-/*
- * Someone rearranged these two registers on the Versatile
- * platform...
- */
-#define CLCD_IENB 0x0000001c
-#define CLCD_CNTL 0x00000018
-#endif
-
-#define CLCD_STAT 0x00000020
-#define CLCD_INTR 0x00000024
-#define CLCD_UCUR 0x00000028
-#define CLCD_LCUR 0x0000002C
+#define CLCD_PL110_IENB 0x00000018
+#define CLCD_PL110_CNTL 0x0000001c
+#define CLCD_PL110_STAT 0x00000020
+#define CLCD_PL110_INTR 0x00000024
+#define CLCD_PL110_UCUR 0x00000028
+#define CLCD_PL110_LCUR 0x0000002C
+
+#define CLCD_PL111_CNTL 0x00000018
+#define CLCD_PL111_IENB 0x0000001c
+#define CLCD_PL111_RIS 0x00000020
+#define CLCD_PL111_MIS 0x00000024
+#define CLCD_PL111_ICR 0x00000028
+#define CLCD_PL111_UCUR 0x0000002c
+#define CLCD_PL111_LCUR 0x00000030
+
#define CLCD_PALL 0x00000200
#define CLCD_PALETTE 0x00000200
@@ -147,6 +146,8 @@ struct clcd_fb {
struct clcd_board *board;
void *board_data;
void __iomem *regs;
+ u16 off_ienb;
+ u16 off_cntl;
u32 clcd_cntl;
u32 cmap[16];
};
diff --git a/include/linux/amba/pl061.h b/include/linux/amba/pl061.h
index b4fbd986260..5ddd9ad4b19 100644
--- a/include/linux/amba/pl061.h
+++ b/include/linux/amba/pl061.h
@@ -1,3 +1,5 @@
+#include <linux/types.h>
+
/* platform data for the PL061 GPIO driver */
struct pl061_platform_data {
diff --git a/include/linux/ata.h b/include/linux/ata.h
index b4c85e2adef..700c5b9b358 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -1025,8 +1025,8 @@ static inline int ata_ok(u8 status)
static inline int lba_28_ok(u64 block, u32 n_block)
{
- /* check the ending block number */
- return ((block + n_block) < ((u64)1 << 28)) && (n_block <= 256);
+ /* check the ending block number: must be LESS THAN 0x0fffffff */
+ return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= 256);
}
static inline int lba_48_ok(u64 block, u32 n_block)
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index fcbc26af00e..bd0e3c6f323 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -101,6 +101,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
const char *fmt, ...);
int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
void bdi_unregister(struct backing_dev_info *bdi);
+int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
long nr_pages);
int bdi_writeback_task(struct bdi_writeback *wb);
@@ -246,6 +247,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
#endif
extern struct backing_dev_info default_backing_dev_info;
+extern struct backing_dev_info noop_backing_dev_info;
void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
int writeback_in_progress(struct backing_dev_info *bdi);
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index 8c4f884db6b..4a3d52e545e 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -36,18 +36,18 @@ struct backlight_device;
struct fb_info;
struct backlight_ops {
- const unsigned int options;
+ unsigned int options;
#define BL_CORE_SUSPENDRESUME (1 << 0)
/* Notify the backlight driver some property has changed */
- int (* const update_status)(struct backlight_device *);
+ int (*update_status)(struct backlight_device *);
/* Return the current backlight brightness (accounting for power,
fb_blank etc.) */
- int (* const get_brightness)(struct backlight_device *);
+ int (*get_brightness)(struct backlight_device *);
/* Check if given framebuffer device is the one bound to this backlight;
return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
- int (* const check_fb)(struct fb_info *);
+ int (*check_fb)(struct backlight_device *, struct fb_info *);
};
/* This structure defines all the properties of a backlight */
@@ -103,7 +103,8 @@ static inline void backlight_update_status(struct backlight_device *bd)
}
extern struct backlight_device *backlight_device_register(const char *name,
- struct device *dev, void *devdata, const struct backlight_ops *ops);
+ struct device *dev, void *devdata, const struct backlight_ops *ops,
+ const struct backlight_properties *props);
extern void backlight_device_unregister(struct backlight_device *bd);
extern void backlight_force_update(struct backlight_device *bd,
enum backlight_update_reason reason);
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 89c6249fc56..c809e286d21 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -74,6 +74,7 @@ struct coredump_params {
struct pt_regs *regs;
struct file *file;
unsigned long limit;
+ unsigned long mm_flags;
};
/*
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 25b8b2f33ae..b796eab5ca7 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -16,12 +16,11 @@
*/
#include <asm/bitops.h>
-#define for_each_bit(bit, addr, size) \
+#define for_each_set_bit(bit, addr, size) \
for ((bit) = find_first_bit((addr), (size)); \
(bit) < (size); \
(bit) = find_next_bit((addr), (size), (bit) + 1))
-
static __inline__ int get_bitmask_order(unsigned int count)
{
int order;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ebd22dbed86..6690e8bae7b 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -158,7 +158,6 @@ enum rq_flag_bits {
struct request {
struct list_head queuelist;
struct call_single_data csd;
- int cpu;
struct request_queue *q;
@@ -166,9 +165,11 @@ struct request {
enum rq_cmd_type_bits cmd_type;
unsigned long atomic_flags;
+ int cpu;
+
/* the following two fields are internal, NEVER access directly */
- sector_t __sector; /* sector cursor */
unsigned int __data_len; /* total data len */
+ sector_t __sector; /* sector cursor */
struct bio *bio;
struct bio *biotail;
@@ -201,20 +202,20 @@ struct request {
unsigned short ioprio;
+ int ref_count;
+
void *special; /* opaque pointer available for LLD use */
char *buffer; /* kaddr of the current segment if available */
int tag;
int errors;
- int ref_count;
-
/*
* when request is used as a packet command carrier
*/
- unsigned short cmd_len;
unsigned char __cmd[BLK_MAX_CDB];
unsigned char *cmd;
+ unsigned short cmd_len;
unsigned int extra_len; /* length of alignment and padding */
unsigned int sense_len;
@@ -921,26 +922,7 @@ extern void blk_cleanup_queue(struct request_queue *);
extern void blk_queue_make_request(struct request_queue *, make_request_fn *);
extern void blk_queue_bounce_limit(struct request_queue *, u64);
extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
-
-/* Temporary compatibility wrapper */
-static inline void blk_queue_max_sectors(struct request_queue *q, unsigned int max)
-{
- blk_queue_max_hw_sectors(q, max);
-}
-
extern void blk_queue_max_segments(struct request_queue *, unsigned short);
-
-static inline void blk_queue_max_phys_segments(struct request_queue *q, unsigned short max)
-{
- blk_queue_max_segments(q, max);
-}
-
-static inline void blk_queue_max_hw_segments(struct request_queue *q, unsigned short max)
-{
- blk_queue_max_segments(q, max);
-}
-
-
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
extern void blk_queue_max_discard_sectors(struct request_queue *q,
unsigned int max_discard_sectors);
@@ -1030,11 +1012,6 @@ static inline int sb_issue_discard(struct super_block *sb,
extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm);
-#define MAX_PHYS_SEGMENTS 128
-#define MAX_HW_SEGMENTS 128
-#define SAFE_MAX_SECTORS 255
-#define MAX_SEGMENT_SIZE 65536
-
enum blk_default_limits {
BLK_MAX_SEGMENTS = 128,
BLK_SAFE_MAX_SECTORS = 255,
diff --git a/include/linux/btree-128.h b/include/linux/btree-128.h
new file mode 100644
index 00000000000..0b3414c4c92
--- /dev/null
+++ b/include/linux/btree-128.h
@@ -0,0 +1,109 @@
+extern struct btree_geo btree_geo128;
+
+struct btree_head128 { struct btree_head h; };
+
+static inline void btree_init_mempool128(struct btree_head128 *head,
+ mempool_t *mempool)
+{
+ btree_init_mempool(&head->h, mempool);
+}
+
+static inline int btree_init128(struct btree_head128 *head)
+{
+ return btree_init(&head->h);
+}
+
+static inline void btree_destroy128(struct btree_head128 *head)
+{
+ btree_destroy(&head->h);
+}
+
+static inline void *btree_lookup128(struct btree_head128 *head, u64 k1, u64 k2)
+{
+ u64 key[2] = {k1, k2};
+ return btree_lookup(&head->h, &btree_geo128, (unsigned long *)&key);
+}
+
+static inline void *btree_get_prev128(struct btree_head128 *head,
+ u64 *k1, u64 *k2)
+{
+ u64 key[2] = {*k1, *k2};
+ void *val;
+
+ val = btree_get_prev(&head->h, &btree_geo128,
+ (unsigned long *)&key);
+ *k1 = key[0];
+ *k2 = key[1];
+ return val;
+}
+
+static inline int btree_insert128(struct btree_head128 *head, u64 k1, u64 k2,
+ void *val, gfp_t gfp)
+{
+ u64 key[2] = {k1, k2};
+ return btree_insert(&head->h, &btree_geo128,
+ (unsigned long *)&key, val, gfp);
+}
+
+static inline int btree_update128(struct btree_head128 *head, u64 k1, u64 k2,
+ void *val)
+{
+ u64 key[2] = {k1, k2};
+ return btree_update(&head->h, &btree_geo128,
+ (unsigned long *)&key, val);
+}
+
+static inline void *btree_remove128(struct btree_head128 *head, u64 k1, u64 k2)
+{
+ u64 key[2] = {k1, k2};
+ return btree_remove(&head->h, &btree_geo128, (unsigned long *)&key);
+}
+
+static inline void *btree_last128(struct btree_head128 *head, u64 *k1, u64 *k2)
+{
+ u64 key[2];
+ void *val;
+
+ val = btree_last(&head->h, &btree_geo128, (unsigned long *)&key[0]);
+ if (val) {
+ *k1 = key[0];
+ *k2 = key[1];
+ }
+
+ return val;
+}
+
+static inline int btree_merge128(struct btree_head128 *target,
+ struct btree_head128 *victim,
+ gfp_t gfp)
+{
+ return btree_merge(&target->h, &victim->h, &btree_geo128, gfp);
+}
+
+void visitor128(void *elem, unsigned long opaque, unsigned long *__key,
+ size_t index, void *__func);
+
+typedef void (*visitor128_t)(void *elem, unsigned long opaque,
+ u64 key1, u64 key2, size_t index);
+
+static inline size_t btree_visitor128(struct btree_head128 *head,
+ unsigned long opaque,
+ visitor128_t func2)
+{
+ return btree_visitor(&head->h, &btree_geo128, opaque,
+ visitor128, func2);
+}
+
+static inline size_t btree_grim_visitor128(struct btree_head128 *head,
+ unsigned long opaque,
+ visitor128_t func2)
+{
+ return btree_grim_visitor(&head->h, &btree_geo128, opaque,
+ visitor128, func2);
+}
+
+#define btree_for_each_safe128(head, k1, k2, val) \
+ for (val = btree_last128(head, &k1, &k2); \
+ val; \
+ val = btree_get_prev128(head, &k1, &k2))
+
diff --git a/include/linux/btree-type.h b/include/linux/btree-type.h
new file mode 100644
index 00000000000..9a1147ef856
--- /dev/null
+++ b/include/linux/btree-type.h
@@ -0,0 +1,147 @@
+#define __BTREE_TP(pfx, type, sfx) pfx ## type ## sfx
+#define _BTREE_TP(pfx, type, sfx) __BTREE_TP(pfx, type, sfx)
+#define BTREE_TP(pfx) _BTREE_TP(pfx, BTREE_TYPE_SUFFIX,)
+#define BTREE_FN(name) BTREE_TP(btree_ ## name)
+#define BTREE_TYPE_HEAD BTREE_TP(struct btree_head)
+#define VISITOR_FN BTREE_TP(visitor)
+#define VISITOR_FN_T _BTREE_TP(visitor, BTREE_TYPE_SUFFIX, _t)
+
+BTREE_TYPE_HEAD {
+ struct btree_head h;
+};
+
+static inline void BTREE_FN(init_mempool)(BTREE_TYPE_HEAD *head,
+ mempool_t *mempool)
+{
+ btree_init_mempool(&head->h, mempool);
+}
+
+static inline int BTREE_FN(init)(BTREE_TYPE_HEAD *head)
+{
+ return btree_init(&head->h);
+}
+
+static inline void BTREE_FN(destroy)(BTREE_TYPE_HEAD *head)
+{
+ btree_destroy(&head->h);
+}
+
+static inline int BTREE_FN(merge)(BTREE_TYPE_HEAD *target,
+ BTREE_TYPE_HEAD *victim,
+ gfp_t gfp)
+{
+ return btree_merge(&target->h, &victim->h, BTREE_TYPE_GEO, gfp);
+}
+
+#if (BITS_PER_LONG > BTREE_TYPE_BITS)
+static inline void *BTREE_FN(lookup)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key)
+{
+ unsigned long _key = key;
+ return btree_lookup(&head->h, BTREE_TYPE_GEO, &_key);
+}
+
+static inline int BTREE_FN(insert)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key,
+ void *val, gfp_t gfp)
+{
+ unsigned long _key = key;
+ return btree_insert(&head->h, BTREE_TYPE_GEO, &_key, val, gfp);
+}
+
+static inline int BTREE_FN(update)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key,
+ void *val)
+{
+ unsigned long _key = key;
+ return btree_update(&head->h, BTREE_TYPE_GEO, &_key, val);
+}
+
+static inline void *BTREE_FN(remove)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key)
+{
+ unsigned long _key = key;
+ return btree_remove(&head->h, BTREE_TYPE_GEO, &_key);
+}
+
+static inline void *BTREE_FN(last)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE *key)
+{
+ unsigned long _key;
+ void *val = btree_last(&head->h, BTREE_TYPE_GEO, &_key);
+ if (val)
+ *key = _key;
+ return val;
+}
+
+static inline void *BTREE_FN(get_prev)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE *key)
+{
+ unsigned long _key = *key;
+ void *val = btree_get_prev(&head->h, BTREE_TYPE_GEO, &_key);
+ if (val)
+ *key = _key;
+ return val;
+}
+#else
+static inline void *BTREE_FN(lookup)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key)
+{
+ return btree_lookup(&head->h, BTREE_TYPE_GEO, (unsigned long *)&key);
+}
+
+static inline int BTREE_FN(insert)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key,
+ void *val, gfp_t gfp)
+{
+ return btree_insert(&head->h, BTREE_TYPE_GEO, (unsigned long *)&key,
+ val, gfp);
+}
+
+static inline int BTREE_FN(update)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key,
+ void *val)
+{
+ return btree_update(&head->h, BTREE_TYPE_GEO, (unsigned long *)&key, val);
+}
+
+static inline void *BTREE_FN(remove)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key)
+{
+ return btree_remove(&head->h, BTREE_TYPE_GEO, (unsigned long *)&key);
+}
+
+static inline void *BTREE_FN(last)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE *key)
+{
+ return btree_last(&head->h, BTREE_TYPE_GEO, (unsigned long *)key);
+}
+
+static inline void *BTREE_FN(get_prev)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE *key)
+{
+ return btree_get_prev(&head->h, BTREE_TYPE_GEO, (unsigned long *)key);
+}
+#endif
+
+void VISITOR_FN(void *elem, unsigned long opaque, unsigned long *key,
+ size_t index, void *__func);
+
+typedef void (*VISITOR_FN_T)(void *elem, unsigned long opaque,
+ BTREE_KEYTYPE key, size_t index);
+
+static inline size_t BTREE_FN(visitor)(BTREE_TYPE_HEAD *head,
+ unsigned long opaque,
+ VISITOR_FN_T func2)
+{
+ return btree_visitor(&head->h, BTREE_TYPE_GEO, opaque,
+ visitorl, func2);
+}
+
+static inline size_t BTREE_FN(grim_visitor)(BTREE_TYPE_HEAD *head,
+ unsigned long opaque,
+ VISITOR_FN_T func2)
+{
+ return btree_grim_visitor(&head->h, BTREE_TYPE_GEO, opaque,
+ visitorl, func2);
+}
+
+#undef VISITOR_FN
+#undef VISITOR_FN_T
+#undef __BTREE_TP
+#undef _BTREE_TP
+#undef BTREE_TP
+#undef BTREE_FN
+#undef BTREE_TYPE_HEAD
+#undef BTREE_TYPE_SUFFIX
+#undef BTREE_TYPE_GEO
+#undef BTREE_KEYTYPE
+#undef BTREE_TYPE_BITS
diff --git a/include/linux/btree.h b/include/linux/btree.h
new file mode 100644
index 00000000000..65b5bb05832
--- /dev/null
+++ b/include/linux/btree.h
@@ -0,0 +1,243 @@
+#ifndef BTREE_H
+#define BTREE_H
+
+#include <linux/kernel.h>
+#include <linux/mempool.h>
+
+/**
+ * DOC: B+Tree basics
+ *
+ * A B+Tree is a data structure for looking up arbitrary (currently allowing
+ * unsigned long, u32, u64 and 2 * u64) keys into pointers. The data structure
+ * is described at http://en.wikipedia.org/wiki/B-tree, we currently do not
+ * use binary search to find the key on lookups.
+ *
+ * Each B+Tree consists of a head, that contains bookkeeping information and
+ * a variable number (starting with zero) nodes. Each node contains the keys
+ * and pointers to sub-nodes, or, for leaf nodes, the keys and values for the
+ * tree entries.
+ *
+ * Each node in this implementation has the following layout:
+ * [key1, key2, ..., keyN] [val1, val2, ..., valN]
+ *
+ * Each key here is an array of unsigned longs, geo->no_longs in total. The
+ * number of keys and values (N) is geo->no_pairs.
+ */
+
+/**
+ * struct btree_head - btree head
+ *
+ * @node: the first node in the tree
+ * @mempool: mempool used for node allocations
+ * @height: current of the tree
+ */
+struct btree_head {
+ unsigned long *node;
+ mempool_t *mempool;
+ int height;
+};
+
+/* btree geometry */
+struct btree_geo;
+
+/**
+ * btree_alloc - allocate function for the mempool
+ * @gfp_mask: gfp mask for the allocation
+ * @pool_data: unused
+ */
+void *btree_alloc(gfp_t gfp_mask, void *pool_data);
+
+/**
+ * btree_free - free function for the mempool
+ * @element: the element to free
+ * @pool_data: unused
+ */
+void btree_free(void *element, void *pool_data);
+
+/**
+ * btree_init_mempool - initialise a btree with given mempool
+ *
+ * @head: the btree head to initialise
+ * @mempool: the mempool to use
+ *
+ * When this function is used, there is no need to destroy
+ * the mempool.
+ */
+void btree_init_mempool(struct btree_head *head, mempool_t *mempool);
+
+/**
+ * btree_init - initialise a btree
+ *
+ * @head: the btree head to initialise
+ *
+ * This function allocates the memory pool that the
+ * btree needs. Returns zero or a negative error code
+ * (-%ENOMEM) when memory allocation fails.
+ *
+ */
+int __must_check btree_init(struct btree_head *head);
+
+/**
+ * btree_destroy - destroy mempool
+ *
+ * @head: the btree head to destroy
+ *
+ * This function destroys the internal memory pool, use only
+ * when using btree_init(), not with btree_init_mempool().
+ */
+void btree_destroy(struct btree_head *head);
+
+/**
+ * btree_lookup - look up a key in the btree
+ *
+ * @head: the btree to look in
+ * @geo: the btree geometry
+ * @key: the key to look up
+ *
+ * This function returns the value for the given key, or %NULL.
+ */
+void *btree_lookup(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key);
+
+/**
+ * btree_insert - insert an entry into the btree
+ *
+ * @head: the btree to add to
+ * @geo: the btree geometry
+ * @key: the key to add (must not already be present)
+ * @val: the value to add (must not be %NULL)
+ * @gfp: allocation flags for node allocations
+ *
+ * This function returns 0 if the item could be added, or an
+ * error code if it failed (may fail due to memory pressure).
+ */
+int __must_check btree_insert(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, void *val, gfp_t gfp);
+/**
+ * btree_update - update an entry in the btree
+ *
+ * @head: the btree to update
+ * @geo: the btree geometry
+ * @key: the key to update
+ * @val: the value to change it to (must not be %NULL)
+ *
+ * This function returns 0 if the update was successful, or
+ * -%ENOENT if the key could not be found.
+ */
+int btree_update(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, void *val);
+/**
+ * btree_remove - remove an entry from the btree
+ *
+ * @head: the btree to update
+ * @geo: the btree geometry
+ * @key: the key to remove
+ *
+ * This function returns the removed entry, or %NULL if the key
+ * could not be found.
+ */
+void *btree_remove(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key);
+
+/**
+ * btree_merge - merge two btrees
+ *
+ * @target: the tree that gets all the entries
+ * @victim: the tree that gets merged into @target
+ * @geo: the btree geometry
+ * @gfp: allocation flags
+ *
+ * The two trees @target and @victim may not contain the same keys,
+ * that is a bug and triggers a BUG(). This function returns zero
+ * if the trees were merged successfully, and may return a failure
+ * when memory allocation fails, in which case both trees might have
+ * been partially merged, i.e. some entries have been moved from
+ * @victim to @target.
+ */
+int btree_merge(struct btree_head *target, struct btree_head *victim,
+ struct btree_geo *geo, gfp_t gfp);
+
+/**
+ * btree_last - get last entry in btree
+ *
+ * @head: btree head
+ * @geo: btree geometry
+ * @key: last key
+ *
+ * Returns the last entry in the btree, and sets @key to the key
+ * of that entry; returns NULL if the tree is empty, in that case
+ * key is not changed.
+ */
+void *btree_last(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key);
+
+/**
+ * btree_get_prev - get previous entry
+ *
+ * @head: btree head
+ * @geo: btree geometry
+ * @key: pointer to key
+ *
+ * The function returns the next item right before the value pointed to by
+ * @key, and updates @key with its key, or returns %NULL when there is no
+ * entry with a key smaller than the given key.
+ */
+void *btree_get_prev(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key);
+
+
+/* internal use, use btree_visitor{l,32,64,128} */
+size_t btree_visitor(struct btree_head *head, struct btree_geo *geo,
+ unsigned long opaque,
+ void (*func)(void *elem, unsigned long opaque,
+ unsigned long *key, size_t index,
+ void *func2),
+ void *func2);
+
+/* internal use, use btree_grim_visitor{l,32,64,128} */
+size_t btree_grim_visitor(struct btree_head *head, struct btree_geo *geo,
+ unsigned long opaque,
+ void (*func)(void *elem, unsigned long opaque,
+ unsigned long *key,
+ size_t index, void *func2),
+ void *func2);
+
+
+#include <linux/btree-128.h>
+
+extern struct btree_geo btree_geo32;
+#define BTREE_TYPE_SUFFIX l
+#define BTREE_TYPE_BITS BITS_PER_LONG
+#define BTREE_TYPE_GEO &btree_geo32
+#define BTREE_KEYTYPE unsigned long
+#include <linux/btree-type.h>
+
+#define btree_for_each_safel(head, key, val) \
+ for (val = btree_lastl(head, &key); \
+ val; \
+ val = btree_get_prevl(head, &key))
+
+#define BTREE_TYPE_SUFFIX 32
+#define BTREE_TYPE_BITS 32
+#define BTREE_TYPE_GEO &btree_geo32
+#define BTREE_KEYTYPE u32
+#include <linux/btree-type.h>
+
+#define btree_for_each_safe32(head, key, val) \
+ for (val = btree_last32(head, &key); \
+ val; \
+ val = btree_get_prev32(head, &key))
+
+extern struct btree_geo btree_geo64;
+#define BTREE_TYPE_SUFFIX 64
+#define BTREE_TYPE_BITS 64
+#define BTREE_TYPE_GEO &btree_geo64
+#define BTREE_KEYTYPE u64
+#include <linux/btree-type.h>
+
+#define btree_for_each_safe64(head, key, val) \
+ for (val = btree_last64(head, &key); \
+ val; \
+ val = btree_get_prev64(head, &key))
+
+#endif
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index c9bbcb2a75a..b8ad1ea9958 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -37,16 +37,24 @@ extern void cgroup_post_fork(struct task_struct *p);
extern void cgroup_exit(struct task_struct *p, int run_callbacks);
extern int cgroupstats_build(struct cgroupstats *stats,
struct dentry *dentry);
+extern int cgroup_load_subsys(struct cgroup_subsys *ss);
+extern void cgroup_unload_subsys(struct cgroup_subsys *ss);
extern const struct file_operations proc_cgroup_operations;
-/* Define the enumeration of all cgroup subsystems */
+/* Define the enumeration of all builtin cgroup subsystems */
#define SUBSYS(_x) _x ## _subsys_id,
enum cgroup_subsys_id {
#include <linux/cgroup_subsys.h>
- CGROUP_SUBSYS_COUNT
+ CGROUP_BUILTIN_SUBSYS_COUNT
};
#undef SUBSYS
+/*
+ * This define indicates the maximum number of subsystems that can be loaded
+ * at once. We limit to this many since cgroupfs_root has subsys_bits to keep
+ * track of all of them.
+ */
+#define CGROUP_SUBSYS_COUNT (BITS_PER_BYTE*sizeof(unsigned long))
/* Per-subsystem/per-cgroup state maintained by the system. */
struct cgroup_subsys_state {
@@ -76,6 +84,12 @@ enum {
CSS_REMOVED, /* This CSS is dead */
};
+/* Caller must verify that the css is not for root cgroup */
+static inline void __css_get(struct cgroup_subsys_state *css, int count)
+{
+ atomic_add(count, &css->refcnt);
+}
+
/*
* Call css_get() to hold a reference on the css; it can be used
* for a reference obtained via:
@@ -87,7 +101,7 @@ static inline void css_get(struct cgroup_subsys_state *css)
{
/* We don't need to reference count the root state */
if (!test_bit(CSS_ROOT, &css->flags))
- atomic_inc(&css->refcnt);
+ __css_get(css, 1);
}
static inline bool css_is_removed(struct cgroup_subsys_state *css)
@@ -118,11 +132,11 @@ static inline bool css_tryget(struct cgroup_subsys_state *css)
* css_get() or css_tryget()
*/
-extern void __css_put(struct cgroup_subsys_state *css);
+extern void __css_put(struct cgroup_subsys_state *css, int count);
static inline void css_put(struct cgroup_subsys_state *css)
{
if (!test_bit(CSS_ROOT, &css->flags))
- __css_put(css);
+ __css_put(css, 1);
}
/* bits in struct cgroup flags field */
@@ -221,6 +235,10 @@ struct cgroup {
/* For RCU-protected deletion */
struct rcu_head rcu_head;
+
+ /* List of events which userspace want to recieve */
+ struct list_head event_list;
+ spinlock_t event_list_lock;
};
/*
@@ -258,7 +276,8 @@ struct css_set {
/*
* Set of subsystem states, one for each subsystem. This array
* is immutable after creation apart from the init_css_set
- * during subsystem registration (at boot time).
+ * during subsystem registration (at boot time) and modular subsystem
+ * loading/unloading.
*/
struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
@@ -363,6 +382,23 @@ struct cftype {
int (*trigger)(struct cgroup *cgrp, unsigned int event);
int (*release)(struct inode *inode, struct file *file);
+
+ /*
+ * register_event() callback will be used to add new userspace
+ * waiter for changes related to the cftype. Implement it if
+ * you want to provide this functionality. Use eventfd_signal()
+ * on eventfd to send notification to userspace.
+ */
+ int (*register_event)(struct cgroup *cgrp, struct cftype *cft,
+ struct eventfd_ctx *eventfd, const char *args);
+ /*
+ * unregister_event() callback will be called when userspace
+ * closes the eventfd or on cgroup removing.
+ * This callback must be implemented, if you want provide
+ * notification functionality.
+ */
+ int (*unregister_event)(struct cgroup *cgrp, struct cftype *cft,
+ struct eventfd_ctx *eventfd);
};
struct cgroup_scanner {
@@ -428,6 +464,8 @@ struct cgroup_subsys {
void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
int (*can_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
struct task_struct *tsk, bool threadgroup);
+ void (*cancel_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
+ struct task_struct *tsk, bool threadgroup);
void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
struct cgroup *old_cgrp, struct task_struct *tsk,
bool threadgroup);
@@ -472,6 +510,9 @@ struct cgroup_subsys {
/* used when use_id == true */
struct idr idr;
spinlock_t id_lock;
+
+ /* should be defined only by modular subsystems */
+ struct module *module;
};
#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
diff --git a/include/linux/circ_buf.h b/include/linux/circ_buf.h
index a2ed0591fb1..90f2471dc6f 100644
--- a/include/linux/circ_buf.h
+++ b/include/linux/circ_buf.h
@@ -1,3 +1,7 @@
+/*
+ * See Documentation/circular-buffers.txt for more information.
+ */
+
#ifndef _LINUX_CIRC_BUF_H
#define _LINUX_CIRC_BUF_H 1
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 0cf725bdd2a..fc53492b6ad 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -73,6 +73,7 @@ enum clock_event_nofitiers {
* @list: list head for the management code
* @mode: operating mode assigned by the management code
* @next_event: local storage for the next event in oneshot mode
+ * @retries: number of forced programming retries
*/
struct clock_event_device {
const char *name;
@@ -93,6 +94,7 @@ struct clock_event_device {
struct list_head list;
enum clock_event_mode mode;
ktime_t next_event;
+ unsigned long retries;
};
/*
diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h
index 5b5d4731f95..8859e2ede9f 100644
--- a/include/linux/coda_psdev.h
+++ b/include/linux/coda_psdev.h
@@ -7,6 +7,8 @@
#define MAX_CODADEVS 5 /* how many do we allow */
#ifdef __KERNEL__
+#include <linux/backing-dev.h>
+
struct kstatfs;
/* communication pending/processing queues */
@@ -17,6 +19,7 @@ struct venus_comm {
struct list_head vc_processing;
int vc_inuse;
struct super_block *vc_sb;
+ struct backing_dev_info bdi;
};
diff --git a/include/linux/compat.h b/include/linux/compat.h
index ef68119a4fd..717c691ecd8 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -23,6 +23,7 @@
typedef __compat_uid32_t compat_uid_t;
typedef __compat_gid32_t compat_gid_t;
+struct compat_sel_arg_struct;
struct rusage;
struct compat_itimerspec {
@@ -249,6 +250,8 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
struct compat_timeval __user *tvp);
+asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg);
+
asmlinkage long compat_sys_wait4(compat_pid_t pid,
compat_uint_t __user *stat_addr, int options,
struct compat_rusage __user *ru);
diff --git a/include/linux/coredump.h b/include/linux/coredump.h
new file mode 100644
index 00000000000..8ba66a9d902
--- /dev/null
+++ b/include/linux/coredump.h
@@ -0,0 +1,45 @@
+#ifndef _LINUX_COREDUMP_H
+#define _LINUX_COREDUMP_H
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+
+/*
+ * These are the only things you should do on a core-file: use only these
+ * functions to write out all the necessary info.
+ */
+static inline int dump_write(struct file *file, const void *addr, int nr)
+{
+ return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+}
+
+static inline int dump_seek(struct file *file, loff_t off)
+{
+ int ret = 1;
+
+ if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
+ if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
+ return 0;
+ } else {
+ char *buf = (char *)get_zeroed_page(GFP_KERNEL);
+
+ if (!buf)
+ return 0;
+ while (off > 0) {
+ unsigned long n = off;
+
+ if (n > PAGE_SIZE)
+ n = PAGE_SIZE;
+ if (!dump_write(file, buf, n)) {
+ ret = 0;
+ break;
+ }
+ off -= n;
+ }
+ free_page((unsigned long)buf);
+ }
+ return ret;
+}
+
+#endif /* _LINUX_COREDUMP_H */
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index dbcee7647d9..bae6fe24d1f 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -90,10 +90,10 @@ extern const struct cpumask *const cpu_active_mask;
#define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask)
#define cpu_active(cpu) cpumask_test_cpu((cpu), cpu_active_mask)
#else
-#define num_online_cpus() 1
-#define num_possible_cpus() 1
-#define num_present_cpus() 1
-#define num_active_cpus() 1
+#define num_online_cpus() 1U
+#define num_possible_cpus() 1U
+#define num_present_cpus() 1U
+#define num_active_cpus() 1U
#define cpu_online(cpu) ((cpu) == 0)
#define cpu_possible(cpu) ((cpu) == 0)
#define cpu_present(cpu) ((cpu) == 0)
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 4db09f89b63..52507c3e138 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -280,7 +280,7 @@ static inline void put_cred(const struct cred *_cred)
* task or by holding tasklist_lock to prevent it from being unlinked.
*/
#define __task_cred(task) \
- ((const struct cred *)(rcu_dereference_check((task)->real_cred, rcu_read_lock_held() || lockdep_is_held(&tasklist_lock))))
+ ((const struct cred *)(rcu_dereference_check((task)->real_cred, rcu_read_lock_held() || lockdep_tasklist_lock_is_held())))
/**
* get_task_cred - Get another task's objective credentials
diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h
index 5032b9a31ae..ad5ec1d0475 100644
--- a/include/linux/decompress/mm.h
+++ b/include/linux/decompress/mm.h
@@ -14,11 +14,21 @@
/* Code active when included from pre-boot environment: */
+/*
+ * Some architectures want to ensure there is no local data in their
+ * pre-boot environment, so that data can arbitarily relocated (via
+ * GOT references). This is achieved by defining STATIC_RW_DATA to
+ * be null.
+ */
+#ifndef STATIC_RW_DATA
+#define STATIC_RW_DATA static
+#endif
+
/* A trivial malloc implementation, adapted from
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*/
-static unsigned long malloc_ptr;
-static int malloc_count;
+STATIC_RW_DATA unsigned long malloc_ptr;
+STATIC_RW_DATA int malloc_count;
static void *malloc(int size)
{
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
index 5076fe0c8a9..6cee17c2231 100644
--- a/include/linux/delayacct.h
+++ b/include/linux/delayacct.h
@@ -18,6 +18,7 @@
#define _LINUX_DELAYACCT_H
#include <linux/sched.h>
+#include <linux/slab.h>
/*
* Per-task flags relevant to delay accounting
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index d4c9c0b88ad..1381cd97b4e 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -118,10 +118,9 @@ struct dm_dev {
/*
* Constructors should call these functions to ensure destination devices
* are opened/closed correctly.
- * FIXME: too many arguments.
*/
-int dm_get_device(struct dm_target *ti, const char *path, sector_t start,
- sector_t len, fmode_t mode, struct dm_dev **result);
+int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
+ struct dm_dev **result);
void dm_put_device(struct dm_target *ti, struct dm_dev *d);
/*
diff --git a/include/linux/device.h b/include/linux/device.h
index b30527db3ac..182192892d4 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -106,7 +106,7 @@ extern int bus_unregister_notifier(struct bus_type *bus,
/* All 4 notifers below get called with the target struct device *
* as an argument. Note that those functions are likely to be called
- * with the device semaphore held in the core, so be careful.
+ * with the device lock held in the core, so be careful.
*/
#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */
#define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */
@@ -251,8 +251,10 @@ extern struct device *class_find_device(struct class *class,
struct class_attribute {
struct attribute attr;
- ssize_t (*show)(struct class *class, char *buf);
- ssize_t (*store)(struct class *class, const char *buf, size_t count);
+ ssize_t (*show)(struct class *class, struct class_attribute *attr,
+ char *buf);
+ ssize_t (*store)(struct class *class, struct class_attribute *attr,
+ const char *buf, size_t count);
};
#define CLASS_ATTR(_name, _mode, _show, _store) \
@@ -263,6 +265,23 @@ extern int __must_check class_create_file(struct class *class,
extern void class_remove_file(struct class *class,
const struct class_attribute *attr);
+/* Simple class attribute that is just a static string */
+
+struct class_attribute_string {
+ struct class_attribute attr;
+ char *str;
+};
+
+/* Currently read-only only */
+#define _CLASS_ATTR_STRING(_name, _mode, _str) \
+ { __ATTR(_name, _mode, show_class_attr_string, NULL), _str }
+#define CLASS_ATTR_STRING(_name, _mode, _str) \
+ struct class_attribute_string class_attr_##_name = \
+ _CLASS_ATTR_STRING(_name, _mode, _str)
+
+extern ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr,
+ char *buf);
+
struct class_interface {
struct list_head node;
struct class *class;
@@ -489,6 +508,21 @@ static inline bool device_async_suspend_enabled(struct device *dev)
return !!dev->power.async_suspend;
}
+static inline void device_lock(struct device *dev)
+{
+ down(&dev->sem);
+}
+
+static inline int device_trylock(struct device *dev)
+{
+ return down_trylock(&dev->sem);
+}
+
+static inline void device_unlock(struct device *dev)
+{
+ up(&dev->sem);
+}
+
void driver_init(void);
/*
diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h
index b6bf17ee2f6..5c9186b93ff 100644
--- a/include/linux/dm-io.h
+++ b/include/linux/dm-io.h
@@ -37,14 +37,14 @@ enum dm_io_mem_type {
struct dm_io_memory {
enum dm_io_mem_type type;
+ unsigned offset;
+
union {
struct page_list *pl;
struct bio_vec *bvec;
void *vma;
void *addr;
} ptr;
-
- unsigned offset;
};
struct dm_io_notify {
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index aa95508d2f9..2c445e11379 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -266,9 +266,9 @@ enum {
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 16
+#define DM_VERSION_MINOR 17
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2009-11-05)"
+#define DM_VERSION_EXTRA "-ioctl (2010-03-05)"
/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
@@ -316,4 +316,9 @@ enum {
*/
#define DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) /* In */
+/*
+ * If set, a uevent was generated for which the caller may need to wait.
+ */
+#define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */
+
#endif /* _LINUX_DM_IOCTL_H */
diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h
index c30879cf93b..96e87693d93 100644
--- a/include/linux/dm9000.h
+++ b/include/linux/dm9000.h
@@ -23,7 +23,7 @@
#define DM9000_PLATF_NO_EEPROM (0x0010)
#define DM9000_PLATF_SIMPLE_PHY (0x0020) /* Use NSR to find LinkStatus */
-/* platfrom data for platfrom device structure's platfrom_data field */
+/* platform data for platform device structure's platform_data field */
struct dm9000_plat_data {
unsigned int flags;
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 91b76184606..ca32ed78b05 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -127,6 +127,14 @@ static inline u64 dma_get_mask(struct device *dev)
return DMA_BIT_MASK(32);
}
+static inline int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+ if (!dma_supported(dev, mask))
+ return -EIO;
+ dev->coherent_dma_mask = mask;
+ return 0;
+}
+
extern u64 dma_get_required_mask(struct device *dev);
static inline unsigned int dma_get_max_seg_size(struct device *dev)
@@ -232,4 +240,20 @@ struct dma_attrs;
#endif /* CONFIG_HAVE_DMA_ATTRS */
+#ifdef CONFIG_NEED_DMA_MAP_STATE
+#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME
+#define DEFINE_DMA_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME
+#define dma_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
+#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
+#define dma_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
+#define dma_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
+#else
+#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME)
+#define DEFINE_DMA_UNMAP_LEN(LEN_NAME)
+#define dma_unmap_addr(PTR, ADDR_NAME) (0)
+#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
+#define dma_unmap_len(PTR, LEN_NAME) (0)
+#define dma_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
+#endif
+
#endif
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index 78962272338..4341b1a97a3 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -56,7 +56,7 @@ extern const char *drbd_buildtag(void);
#define REL_VERSION "8.3.7"
#define API_VERSION 88
#define PRO_VERSION_MIN 86
-#define PRO_VERSION_MAX 91
+#define PRO_VERSION_MAX 92
enum drbd_io_error_p {
diff --git a/include/linux/drbd_nl.h b/include/linux/drbd_nl.h
index a4d82f89599..f7431a4ca60 100644
--- a/include/linux/drbd_nl.h
+++ b/include/linux/drbd_nl.h
@@ -12,7 +12,7 @@
#endif
NL_PACKET(primary, 1,
- NL_BIT( 1, T_MAY_IGNORE, overwrite_peer)
+ NL_BIT( 1, T_MAY_IGNORE, primary_force)
)
NL_PACKET(secondary, 2, )
@@ -63,6 +63,7 @@ NL_PACKET(net_conf, 5,
NL_BIT( 41, T_MAY_IGNORE, always_asbp)
NL_BIT( 61, T_MAY_IGNORE, no_cork)
NL_BIT( 62, T_MANDATORY, auto_sndbuf_size)
+ NL_BIT( 70, T_MANDATORY, dry_run)
)
NL_PACKET(disconnect, 6, )
diff --git a/include/linux/elf.h b/include/linux/elf.h
index ad990c5f63f..59785841805 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -50,6 +50,28 @@ typedef __s64 Elf64_Sxword;
#define PT_GNU_STACK (PT_LOOS + 0x474e551)
+/*
+ * Extended Numbering
+ *
+ * If the real number of program header table entries is larger than
+ * or equal to PN_XNUM(0xffff), it is set to sh_info field of the
+ * section header at index 0, and PN_XNUM is set to e_phnum
+ * field. Otherwise, the section header at index 0 is zero
+ * initialized, if it exists.
+ *
+ * Specifications are available in:
+ *
+ * - Sun microsystems: Linker and Libraries.
+ * Part No: 817-1984-17, September 2008.
+ * URL: http://docs.sun.com/app/docs/doc/817-1984
+ *
+ * - System V ABI AMD64 Architecture Processor Supplement
+ * Draft Version 0.99.,
+ * May 11, 2009.
+ * URL: http://www.x86-64.org/
+ */
+#define PN_XNUM 0xffff
+
/* These constants define the different elf file types */
#define ET_NONE 0
#define ET_REL 1
@@ -286,7 +308,7 @@ typedef struct elf64_phdr {
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
-typedef struct {
+typedef struct elf32_shdr {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
@@ -394,16 +416,20 @@ typedef struct elf64_note {
extern Elf32_Dyn _DYNAMIC [];
#define elfhdr elf32_hdr
#define elf_phdr elf32_phdr
+#define elf_shdr elf32_shdr
#define elf_note elf32_note
#define elf_addr_t Elf32_Off
+#define Elf_Half Elf32_Half
#else
extern Elf64_Dyn _DYNAMIC [];
#define elfhdr elf64_hdr
#define elf_phdr elf64_phdr
+#define elf_shdr elf64_shdr
#define elf_note elf64_note
#define elf_addr_t Elf64_Off
+#define Elf_Half Elf64_Half
#endif
diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
index 00d6a68d042..e687bc3ba4d 100644
--- a/include/linux/elfcore.h
+++ b/include/linux/elfcore.h
@@ -8,6 +8,8 @@
#include <linux/user.h>
#endif
#include <linux/ptrace.h>
+#include <linux/elf.h>
+#include <linux/fs.h>
struct elf_siginfo
{
@@ -150,5 +152,20 @@ static inline int elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregse
#endif /* __KERNEL__ */
+/*
+ * These functions parameterize elf_core_dump in fs/binfmt_elf.c to write out
+ * extra segments containing the gate DSO contents. Dumping its
+ * contents makes post-mortem fully interpretable later without matching up
+ * the same kernel and hardware config to see what PC values meant.
+ * Dumping its extra ELF program headers includes all the other information
+ * a debugger needs to easily find how the gate DSO was being used.
+ */
+extern Elf_Half elf_core_extra_phdrs(void);
+extern int
+elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+ unsigned long limit);
+extern int
+elf_core_write_extra_data(struct file *file, size_t *size, unsigned long limit);
+extern size_t elf_core_extra_data_size(void);
#endif /* _LINUX_ELFCORE_H */
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index cca1c3de140..b33f316bb92 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -61,6 +61,13 @@ struct ethtool_drvinfo {
/* For PCI devices, use pci_name(pci_dev). */
char reserved1[32];
char reserved2[12];
+ /*
+ * Some struct members below are filled in
+ * using ops->get_sset_count(). Obtaining
+ * this info from ethtool_drvinfo is now
+ * deprecated; Use ETHTOOL_GSSET_INFO
+ * instead.
+ */
__u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */
__u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
__u32 testinfo_len;
@@ -253,6 +260,17 @@ struct ethtool_gstrings {
__u8 data[0];
};
+struct ethtool_sset_info {
+ __u32 cmd; /* ETHTOOL_GSSET_INFO */
+ __u32 reserved;
+ __u64 sset_mask; /* input: each bit selects an sset to query */
+ /* output: each bit a returned sset */
+ __u32 data[0]; /* ETH_SS_xxx count, in order, based on bits
+ in sset_mask. One bit implies one
+ __u32, two bits implies two
+ __u32's, etc. */
+};
+
enum ethtool_test_flags {
ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */
ETH_TEST_FL_FAILED = (1 << 1), /* test passed / failed */
@@ -606,9 +624,9 @@ struct ethtool_ops {
#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
#define ETHTOOL_RESET 0x00000034 /* Reset hardware */
-
-#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
-#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */
+#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
+#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */
+#define ETHTOOL_GSSET_INFO 0x00000037 /* Get string set info */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index dc12f416a49..a9cd507f8cd 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -96,6 +96,7 @@ struct fid {
* @fh_to_parent: find the implied object's parent and get a dentry for it
* @get_name: find the name for a given inode in a given directory
* @get_parent: find the parent of a given directory
+ * @commit_metadata: commit metadata changes to stable storage
*
* See Documentation/filesystems/nfs/Exporting for details on how to use
* this interface correctly.
@@ -137,6 +138,9 @@ struct fid {
* is also a directory. In the event that it cannot be found, or storage
* space cannot be allocated, a %ERR_PTR should be returned.
*
+ * commit_metadata:
+ * @commit_metadata should commit metadata changes to stable storage.
+ *
* Locking rules:
* get_parent is called with child->d_inode->i_mutex down
* get_name is not (which is possibly inconsistent)
@@ -152,6 +156,7 @@ struct export_operations {
int (*get_name)(struct dentry *parent, char *name,
struct dentry *child);
struct dentry * (*get_parent)(struct dentry *child);
+ int (*commit_metadata)(struct inode *inode);
};
extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 6b049030fbe..5f494b46509 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -202,14 +202,6 @@ static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags)
return flags & EXT3_OTHER_FLMASK;
}
-/*
- * Inode dynamic state flags
- */
-#define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */
-#define EXT3_STATE_NEW 0x00000002 /* inode is newly created */
-#define EXT3_STATE_XATTR 0x00000004 /* has in-inode xattrs */
-#define EXT3_STATE_FLUSH_ON_CLOSE 0x00000008
-
/* Used to pass group descriptor data when online resize is done */
struct ext3_new_group_input {
__u32 group; /* Group number for this data */
@@ -560,6 +552,31 @@ static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino)
(ino >= EXT3_FIRST_INO(sb) &&
ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count));
}
+
+/*
+ * Inode dynamic state flags
+ */
+enum {
+ EXT3_STATE_JDATA, /* journaled data exists */
+ EXT3_STATE_NEW, /* inode is newly created */
+ EXT3_STATE_XATTR, /* has in-inode xattrs */
+ EXT3_STATE_FLUSH_ON_CLOSE, /* flush dirty pages on close */
+};
+
+static inline int ext3_test_inode_state(struct inode *inode, int bit)
+{
+ return test_bit(bit, &EXT3_I(inode)->i_state_flags);
+}
+
+static inline void ext3_set_inode_state(struct inode *inode, int bit)
+{
+ set_bit(bit, &EXT3_I(inode)->i_state_flags);
+}
+
+static inline void ext3_clear_inode_state(struct inode *inode, int bit)
+{
+ clear_bit(bit, &EXT3_I(inode)->i_state_flags);
+}
#else
/* Assume that user mode programs are passing in an ext3fs superblock, not
* a kernel struct super_block. This will allow us to call the feature-test
@@ -877,7 +894,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
int create);
extern struct inode *ext3_iget(struct super_block *, unsigned long);
-extern int ext3_write_inode (struct inode *, int);
+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 int ext3_sync_inode (handle_t *, struct inode *);
diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
index 93e7428156b..f42c098aed8 100644
--- a/include/linux/ext3_fs_i.h
+++ b/include/linux/ext3_fs_i.h
@@ -87,7 +87,7 @@ struct ext3_inode_info {
* near to their parent directory's inode.
*/
__u32 i_block_group;
- __u32 i_state; /* Dynamic state flags for ext3 */
+ unsigned long i_state_flags; /* Dynamic state flags for ext3 */
/* block reservation info */
struct ext3_block_alloc_info *i_block_alloc_info;
diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h
index 06ca9b21dad..7b64ad40e4c 100644
--- a/include/linux/fault-inject.h
+++ b/include/linux/fault-inject.h
@@ -82,9 +82,10 @@ static inline void cleanup_fault_attr_dentries(struct fault_attr *attr)
#endif /* CONFIG_FAULT_INJECTION */
#ifdef CONFIG_FAILSLAB
-extern bool should_failslab(size_t size, gfp_t gfpflags);
+extern bool should_failslab(size_t size, gfp_t gfpflags, unsigned long flags);
#else
-static inline bool should_failslab(size_t size, gfp_t gfpflags)
+static inline bool should_failslab(size_t size, gfp_t gfpflags,
+ unsigned long flags)
{
return false;
}
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index 40b11013408..68f883b30a5 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -1,21 +1,26 @@
/*
* Char device interface.
*
- * Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net>
- *
- * This program is free software; 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 (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*/
#ifndef _LINUX_FIREWIRE_CDEV_H
@@ -438,7 +443,7 @@ struct fw_cdev_remove_descriptor {
* @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE
* @header_size: Header size to strip for receive contexts
* @channel: Channel to bind to
- * @speed: Speed to transmit at
+ * @speed: Speed for transmit contexts
* @closure: To be returned in &fw_cdev_event_iso_interrupt
* @handle: Handle to context, written back by kernel
*
@@ -451,6 +456,9 @@ struct fw_cdev_remove_descriptor {
* If a context was successfully created, the kernel writes back a handle to the
* context, which must be passed in for subsequent operations on that context.
*
+ * For receive contexts, @header_size must be at least 4 and must be a multiple
+ * of 4.
+ *
* Note that the effect of a @header_size > 4 depends on
* &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt.
*/
@@ -481,10 +489,34 @@ struct fw_cdev_create_iso_context {
*
* &struct fw_cdev_iso_packet is used to describe isochronous packet queues.
*
- * Use the FW_CDEV_ISO_ macros to fill in @control. The sy and tag fields are
- * specified by IEEE 1394a and IEC 61883.
- *
- * FIXME - finish this documentation
+ * Use the FW_CDEV_ISO_ macros to fill in @control.
+ *
+ * For transmit packets, the header length must be a multiple of 4 and specifies
+ * the numbers of bytes in @header that will be prepended to the packet's
+ * payload; these bytes are copied into the kernel and will not be accessed
+ * after the ioctl has returned. The sy and tag fields are copied to the iso
+ * packet header (these fields are specified by IEEE 1394a and IEC 61883-1).
+ * The skip flag specifies that no packet is to be sent in a frame; when using
+ * this, all other fields except the interrupt flag must be zero.
+ *
+ * For receive packets, the header length must be a multiple of the context's
+ * header size; if the header length is larger than the context's header size,
+ * multiple packets are queued for this entry. The sy and tag fields are
+ * ignored. If the sync flag is set, the context drops all packets until
+ * a packet with a matching sy field is received (the sync value to wait for is
+ * specified in the &fw_cdev_start_iso structure). The payload length defines
+ * how many payload bytes can be received for one packet (in addition to payload
+ * quadlets that have been defined as headers and are stripped and returned in
+ * the &fw_cdev_event_iso_interrupt structure). If more bytes are received, the
+ * additional bytes are dropped. If less bytes are received, the remaining
+ * bytes in this part of the payload buffer will not be written to, not even by
+ * the next packet, i.e., packets received in consecutive frames will not
+ * necessarily be consecutive in memory. If an entry has queued multiple
+ * packets, the payload length is divided equally among them.
+ *
+ * When a packet with the interrupt flag set has been completed, the
+ * &fw_cdev_event_iso_interrupt event will be sent. An entry that has queued
+ * multiple receive packets is completed when its last packet is completed.
*/
struct fw_cdev_iso_packet {
__u32 control;
@@ -501,7 +533,7 @@ struct fw_cdev_iso_packet {
* Queue a number of isochronous packets for reception or transmission.
* This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs,
* which describe how to transmit from or receive into a contiguous region
- * of a mmap()'ed payload buffer. As part of the packet descriptors,
+ * of a mmap()'ed payload buffer. As part of transmit packet descriptors,
* a series of headers can be supplied, which will be prepended to the
* payload during DMA.
*
@@ -620,8 +652,8 @@ struct fw_cdev_get_cycle_timer2 {
* instead of allocated.
* An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation.
*
- * To summarize, %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE allocates iso resources
- * for the lifetime of the fd or handle.
+ * To summarize, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE allocates iso resources
+ * for the lifetime of the fd or @handle.
* In contrast, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE allocates iso resources
* for the duration of a bus generation.
*
diff --git a/include/linux/firewire-constants.h b/include/linux/firewire-constants.h
index b316770a43f..9b4bb5fbba4 100644
--- a/include/linux/firewire-constants.h
+++ b/include/linux/firewire-constants.h
@@ -1,3 +1,28 @@
+/*
+ * IEEE 1394 constants.
+ *
+ * Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
#ifndef _LINUX_FIREWIRE_CONSTANTS_H
#define _LINUX_FIREWIRE_CONSTANTS_H
@@ -21,7 +46,7 @@
#define EXTCODE_WRAP_ADD 0x6
#define EXTCODE_VENDOR_DEPENDENT 0x7
-/* Juju specific tcodes */
+/* Linux firewire-core (Juju) specific tcodes */
#define TCODE_LOCK_MASK_SWAP (0x10 | EXTCODE_MASK_SWAP)
#define TCODE_LOCK_COMPARE_SWAP (0x10 | EXTCODE_COMPARE_SWAP)
#define TCODE_LOCK_FETCH_ADD (0x10 | EXTCODE_FETCH_ADD)
@@ -36,7 +61,7 @@
#define RCODE_TYPE_ERROR 0x6
#define RCODE_ADDRESS_ERROR 0x7
-/* Juju specific rcodes */
+/* Linux firewire-core (Juju) specific rcodes */
#define RCODE_SEND_ERROR 0x10
#define RCODE_CANCELLED 0x11
#define RCODE_BUSY 0x12
diff --git a/include/linux/firmware-map.h b/include/linux/firmware-map.h
index 875451f1373..c6dcc1dfe78 100644
--- a/include/linux/firmware-map.h
+++ b/include/linux/firmware-map.h
@@ -24,17 +24,17 @@
*/
#ifdef CONFIG_FIRMWARE_MEMMAP
-int firmware_map_add(u64 start, u64 end, const char *type);
int firmware_map_add_early(u64 start, u64 end, const char *type);
+int firmware_map_add_hotplug(u64 start, u64 end, const char *type);
#else /* CONFIG_FIRMWARE_MEMMAP */
-static inline int firmware_map_add(u64 start, u64 end, const char *type)
+static inline int firmware_map_add_early(u64 start, u64 end, const char *type)
{
return 0;
}
-static inline int firmware_map_add_early(u64 start, u64 end, const char *type)
+static inline int firmware_map_add_hotplug(u64 start, u64 end, const char *type)
{
return 0;
}
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 5a361f85cfe..da7e52b099f 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -64,9 +64,12 @@ extern bool freeze_task(struct task_struct *p, bool sig_only);
extern void cancel_freezing(struct task_struct *p);
#ifdef CONFIG_CGROUP_FREEZER
-extern int cgroup_frozen(struct task_struct *task);
+extern int cgroup_freezing_or_frozen(struct task_struct *task);
#else /* !CONFIG_CGROUP_FREEZER */
-static inline int cgroup_frozen(struct task_struct *task) { return 0; }
+static inline int cgroup_freezing_or_frozen(struct task_struct *task)
+{
+ return 0;
+}
#endif /* !CONFIG_CGROUP_FREEZER */
/*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 5b3182c7eb5..44f35aea2f1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -60,24 +60,24 @@ struct inodes_stat_t {
*/
/* file is open for reading */
-#define FMODE_READ ((__force fmode_t)1)
+#define FMODE_READ ((__force fmode_t)0x1)
/* file is open for writing */
-#define FMODE_WRITE ((__force fmode_t)2)
+#define FMODE_WRITE ((__force fmode_t)0x2)
/* file is seekable */
-#define FMODE_LSEEK ((__force fmode_t)4)
+#define FMODE_LSEEK ((__force fmode_t)0x4)
/* file can be accessed using pread */
-#define FMODE_PREAD ((__force fmode_t)8)
+#define FMODE_PREAD ((__force fmode_t)0x8)
/* file can be accessed using pwrite */
-#define FMODE_PWRITE ((__force fmode_t)16)
+#define FMODE_PWRITE ((__force fmode_t)0x10)
/* File is opened for execution with sys_execve / sys_uselib */
-#define FMODE_EXEC ((__force fmode_t)32)
+#define FMODE_EXEC ((__force fmode_t)0x20)
/* File is opened with O_NDELAY (only set for block devices) */
-#define FMODE_NDELAY ((__force fmode_t)64)
+#define FMODE_NDELAY ((__force fmode_t)0x40)
/* File is opened with O_EXCL (only set for block devices) */
-#define FMODE_EXCL ((__force fmode_t)128)
+#define FMODE_EXCL ((__force fmode_t)0x80)
/* File is opened using open(.., 3, ..) and is writeable only for ioctls
(specialy hack for floppy.c) */
-#define FMODE_WRITE_IOCTL ((__force fmode_t)256)
+#define FMODE_WRITE_IOCTL ((__force fmode_t)0x100)
/*
* Don't update ctime and mtime.
@@ -85,7 +85,10 @@ struct inodes_stat_t {
* Currently a special hack for the XFS open_by_handle ioctl, but we'll
* hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
*/
-#define FMODE_NOCMTIME ((__force fmode_t)2048)
+#define FMODE_NOCMTIME ((__force fmode_t)0x800)
+
+/* Expect random access pattern */
+#define FMODE_RANDOM ((__force fmode_t)0x1000)
/*
* The below are the various read and write types that we support. Some of
@@ -1557,7 +1560,7 @@ struct super_operations {
void (*destroy_inode)(struct inode *);
void (*dirty_inode) (struct inode *);
- int (*write_inode) (struct inode *, int);
+ int (*write_inode) (struct inode *, struct writeback_control *wbc);
void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
@@ -2209,6 +2212,7 @@ extern int generic_segment_checks(const struct iovec *iov,
/* fs/block_dev.c */
extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos);
+extern int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync);
/* fs/splice.c */
extern ssize_t generic_file_splice_read(struct file *, loff_t *,
@@ -2311,8 +2315,9 @@ extern int vfs_fstatat(int , char __user *, struct kstat *, int);
extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
unsigned long arg);
extern int __generic_block_fiemap(struct inode *inode,
- struct fiemap_extent_info *fieinfo, u64 start,
- u64 len, get_block_t *get_block);
+ struct fiemap_extent_info *fieinfo,
+ loff_t start, loff_t len,
+ get_block_t *get_block);
extern int generic_block_fiemap(struct inode *inode,
struct fiemap_extent_info *fieinfo, u64 start,
u64 len, get_block_t *get_block);
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 7be0c6fbe88..c57db27ac86 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -105,7 +105,7 @@ struct fscache_operation {
/* operation releaser */
fscache_operation_release_t release;
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
const char *name; /* operation name */
const char *state; /* operation state */
#define fscache_set_op_name(OP, N) do { (OP)->name = (N); } while(0)
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index df8fd9a3b21..01755909ce8 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -15,6 +15,7 @@
#include <linux/inotify.h>
#include <linux/fsnotify_backend.h>
#include <linux/audit.h>
+#include <linux/slab.h>
/*
* fsnotify_d_instantiate - instantiate a dentry for inode
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 6b7c444ab8f..c0f4b364c71 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -131,12 +131,12 @@ struct ftrace_event_call {
void *mod;
void *data;
- int profile_count;
- int (*profile_enable)(struct ftrace_event_call *);
- void (*profile_disable)(struct ftrace_event_call *);
+ int perf_refcount;
+ int (*perf_event_enable)(struct ftrace_event_call *);
+ void (*perf_event_disable)(struct ftrace_event_call *);
};
-#define FTRACE_MAX_PROFILE_SIZE 2048
+#define PERF_MAX_TRACE_SIZE 2048
#define MAX_FILTER_PRED 32
#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
@@ -187,22 +187,25 @@ do { \
#ifdef CONFIG_PERF_EVENTS
struct perf_event;
-extern int ftrace_profile_enable(int event_id);
-extern void ftrace_profile_disable(int event_id);
+
+DECLARE_PER_CPU(struct pt_regs, perf_trace_regs);
+
+extern int perf_trace_enable(int event_id);
+extern void perf_trace_disable(int event_id);
extern int ftrace_profile_set_filter(struct perf_event *event, int event_id,
char *filter_str);
extern void ftrace_profile_free_filter(struct perf_event *event);
extern void *
-ftrace_perf_buf_prepare(int size, unsigned short type, int *rctxp,
+perf_trace_buf_prepare(int size, unsigned short type, int *rctxp,
unsigned long *irq_flags);
static inline void
-ftrace_perf_buf_submit(void *raw_data, int size, int rctx, u64 addr,
- u64 count, unsigned long irq_flags)
+perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr,
+ u64 count, unsigned long irq_flags, struct pt_regs *regs)
{
struct trace_entry *entry = raw_data;
- perf_tp_event(entry->type, addr, count, raw_data, size);
+ perf_tp_event(entry->type, addr, count, raw_data, size, regs);
perf_swevent_put_recursion_context(rctx);
local_irq_restore(irq_flags);
}
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index 48e68da097f..361d1cc288d 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -16,6 +16,7 @@
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/timer.h>
+#include <linux/slab.h>
struct gameport {
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 56b50514ab2..5f2f4c4d8fb 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -109,7 +109,7 @@ struct hd_struct {
};
#define GENHD_FL_REMOVABLE 1
-#define GENHD_FL_DRIVERFS 2
+/* 2 is unused */
#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4
#define GENHD_FL_CD 8
#define GENHD_FL_UP 16
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 557bdad320b..4c6d41333f9 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -30,7 +30,8 @@ struct vm_area_struct;
* _might_ fail. This depends upon the particular VM implementation.
*
* __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
- * cannot handle allocation failures.
+ * cannot handle allocation failures. This modifier is deprecated and no new
+ * users should be added.
*
* __GFP_NORETRY: The VM implementation must not retry indefinitely.
*
@@ -83,6 +84,7 @@ struct vm_area_struct;
#define GFP_HIGHUSER_MOVABLE (__GFP_WAIT | __GFP_IO | __GFP_FS | \
__GFP_HARDWALL | __GFP_HIGHMEM | \
__GFP_MOVABLE)
+#define GFP_IOFS (__GFP_IO | __GFP_FS)
#ifdef CONFIG_NUMA
#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
@@ -325,7 +327,7 @@ void free_pages_exact(void *virt, size_t size);
extern void __free_pages(struct page *page, unsigned int order);
extern void free_pages(unsigned long addr, unsigned int order);
-extern void free_hot_page(struct page *page);
+extern void free_hot_cold_page(struct page *page, int cold);
#define __free_page(page) __free_pages((page), 0)
#define free_page(addr) free_pages((addr),0)
@@ -337,9 +339,7 @@ void drain_local_pages(void *dummy);
extern gfp_t gfp_allowed_mask;
-static inline void set_gfp_allowed_mask(gfp_t mask)
-{
- gfp_allowed_mask = mask;
-}
+extern void set_gfp_allowed_mask(gfp_t mask);
+extern gfp_t clear_gfp_allowed_mask(gfp_t mask);
#endif /* __LINUX_GFP_H */
diff --git a/include/linux/hil.h b/include/linux/hil.h
index 13352d7d0ca..523785a9de7 100644
--- a/include/linux/hil.h
+++ b/include/linux/hil.h
@@ -168,14 +168,14 @@ enum hil_command {
HIL_CMD_PR6 = 0x45, /* Prompt6 */
HIL_CMD_PR7 = 0x46, /* Prompt7 */
HIL_CMD_PRM = 0x47, /* Prompt (General Purpose) */
- HIL_CMD_AK1 = 0x48, /* Acknowlege1 */
- HIL_CMD_AK2 = 0x49, /* Acknowlege2 */
- HIL_CMD_AK3 = 0x4a, /* Acknowlege3 */
- HIL_CMD_AK4 = 0x4b, /* Acknowlege4 */
- HIL_CMD_AK5 = 0x4c, /* Acknowlege5 */
- HIL_CMD_AK6 = 0x4d, /* Acknowlege6 */
- HIL_CMD_AK7 = 0x4e, /* Acknowlege7 */
- HIL_CMD_ACK = 0x4f, /* Acknowlege (General Purpose) */
+ HIL_CMD_AK1 = 0x48, /* Acknowledge1 */
+ HIL_CMD_AK2 = 0x49, /* Acknowledge2 */
+ HIL_CMD_AK3 = 0x4a, /* Acknowledge3 */
+ HIL_CMD_AK4 = 0x4b, /* Acknowledge4 */
+ HIL_CMD_AK5 = 0x4c, /* Acknowledge5 */
+ HIL_CMD_AK6 = 0x4d, /* Acknowledge6 */
+ HIL_CMD_AK7 = 0x4e, /* Acknowledge7 */
+ HIL_CMD_ACK = 0x4f, /* Acknowledge (General Purpose) */
/* 0x50 to 0x78 reserved for future use */
/* 0x80 to 0xEF device-specific commands */
diff --git a/include/linux/htcpld.h b/include/linux/htcpld.h
new file mode 100644
index 00000000000..ab3f6cb4ddd
--- /dev/null
+++ b/include/linux/htcpld.h
@@ -0,0 +1,24 @@
+#ifndef __LINUX_HTCPLD_H
+#define __LINUX_HTCPLD_H
+
+struct htcpld_chip_platform_data {
+ unsigned int addr;
+ unsigned int reset;
+ unsigned int num_gpios;
+ unsigned int gpio_out_base;
+ unsigned int gpio_in_base;
+ unsigned int irq_base;
+ unsigned int num_irqs;
+};
+
+struct htcpld_core_platform_data {
+ unsigned int int_reset_gpio_hi;
+ unsigned int int_reset_gpio_lo;
+ unsigned int i2c_adapter_id;
+
+ struct htcpld_chip_platform_data *chip;
+ unsigned int num_chip;
+};
+
+#endif /* __LINUX_HTCPLD_H */
+
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h
index 5977b724f7c..c70d27af03f 100644
--- a/include/linux/hw_breakpoint.h
+++ b/include/linux/hw_breakpoint.h
@@ -66,14 +66,14 @@ register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
perf_overflow_handler_t triggered,
int cpu);
-extern struct perf_event **
+extern struct perf_event * __percpu *
register_wide_hw_breakpoint(struct perf_event_attr *attr,
perf_overflow_handler_t triggered);
extern int register_perf_hw_breakpoint(struct perf_event *bp);
extern int __register_perf_hw_breakpoint(struct perf_event *bp);
extern void unregister_hw_breakpoint(struct perf_event *bp);
-extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events);
+extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events);
extern int dbg_reserve_bp_slot(struct perf_event *bp);
extern int dbg_release_bp_slot(struct perf_event *bp);
@@ -100,7 +100,7 @@ static inline struct perf_event *
register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
perf_overflow_handler_t triggered,
int cpu) { return NULL; }
-static inline struct perf_event **
+static inline struct perf_event * __percpu *
register_wide_hw_breakpoint(struct perf_event_attr *attr,
perf_overflow_handler_t triggered) { return NULL; }
static inline int
@@ -109,7 +109,7 @@ static inline int
__register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
static inline void unregister_hw_breakpoint(struct perf_event *bp) { }
static inline void
-unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { }
+unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) { }
static inline int
reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; }
static inline void release_bp_slot(struct perf_event *bp) { }
diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h
index 111334f5b92..4f98148c11c 100644
--- a/include/linux/i2c-algo-bit.h
+++ b/include/linux/i2c-algo-bit.h
@@ -36,6 +36,8 @@ struct i2c_algo_bit_data {
void (*setscl) (void *data, int state);
int (*getsda) (void *data);
int (*getscl) (void *data);
+ int (*pre_xfer) (struct i2c_adapter *);
+ void (*post_xfer) (struct i2c_adapter *);
/* local settings */
int udelay; /* half clock cycle time in us,
diff --git a/include/linux/i2c-xiic.h b/include/linux/i2c-xiic.h
new file mode 100644
index 00000000000..4f9f2256a97
--- /dev/null
+++ b/include/linux/i2c-xiic.h
@@ -0,0 +1,43 @@
+/*
+ * i2c-xiic.h
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in 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.
+ */
+
+/* Supports:
+ * Xilinx IIC
+ */
+
+#ifndef _LINUX_I2C_XIIC_H
+#define _LINUX_I2C_XIIC_H
+
+/**
+ * struct xiic_i2c_platform_data - Platform data of the Xilinx I2C driver
+ * @num_devices: Number of devices that shall be added when the driver
+ * is probed.
+ * @devices: The actuall devices to add.
+ *
+ * This purpose of this platform data struct is to be able to provide a number
+ * of devices that should be added to the I2C bus. The reason is that sometimes
+ * the I2C board info is not enough, a new PCI board can for instance be
+ * plugged into a standard PC, and the bus number might be unknown at
+ * early init time.
+ */
+struct xiic_i2c_platform_data {
+ u8 num_devices;
+ struct i2c_board_info const *devices;
+};
+
+#endif /* _LINUX_I2C_XIIC_H */
diff --git a/include/linux/i2c/pca953x.h b/include/linux/i2c/pca953x.h
index 81736d6a8db..d5c5a60c8a0 100644
--- a/include/linux/i2c/pca953x.h
+++ b/include/linux/i2c/pca953x.h
@@ -1,3 +1,9 @@
+#ifndef _LINUX_PCA953X_H
+#define _LINUX_PCA953X_H
+
+#include <linux/types.h>
+#include <linux/i2c.h>
+
/* platform data for the PCA9539 16-bit I/O expander driver */
struct pca953x_platform_data {
@@ -7,6 +13,9 @@ struct pca953x_platform_data {
/* initial polarity inversion setting */
uint16_t invert;
+ /* interrupt base */
+ int irq_base;
+
void *context; /* param to setup/teardown */
int (*setup)(struct i2c_client *client,
@@ -17,3 +26,5 @@ struct pca953x_platform_data {
void *context);
char **names;
};
+
+#endif /* _LINUX_PCA953X_H */
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 7897f309656..fb6784e86d5 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -80,6 +80,11 @@
#define TWL_MODULE_PM_MASTER TWL4030_MODULE_PM_MASTER
#define TWL_MODULE_PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
#define TWL_MODULE_RTC TWL4030_MODULE_RTC
+#define TWL_MODULE_PWM TWL4030_MODULE_PWM0
+
+#define TWL6030_MODULE_ID0 0x0D
+#define TWL6030_MODULE_ID1 0x0E
+#define TWL6030_MODULE_ID2 0x0F
#define GPIO_INTR_OFFSET 0
#define KEYPAD_INTR_OFFSET 1
@@ -239,6 +244,21 @@ int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
/*----------------------------------------------------------------------*/
+/*Interface Bit Register (INTBR) offsets
+ *(Use TWL_4030_MODULE_INTBR)
+ */
+
+#define REG_GPPUPDCTR1 0x0F
+
+/*I2C1 and I2C4(SR) SDA/SCL pull-up control bits */
+
+#define I2C_SCL_CTRL_PU BIT(0)
+#define I2C_SDA_CTRL_PU BIT(2)
+#define SR_I2C_SCL_CTRL_PU BIT(4)
+#define SR_I2C_SDA_CTRL_PU BIT(6)
+
+/*----------------------------------------------------------------------*/
+
/*
* Keypad register offsets (use TWL4030_MODULE_KEYPAD)
* ... SIH/interrupt only
@@ -530,6 +550,7 @@ struct twl4030_power_data {
};
extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
+extern int twl4030_remove_script(u8 flags);
struct twl4030_codec_audio_data {
unsigned int audio_mclk;
@@ -605,12 +626,7 @@ int twl4030_sih_setup(int module);
#define TWL4030_VAUX3_DEV_GRP 0x1F
#define TWL4030_VAUX3_DEDICATED 0x22
-#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
- defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
- extern int twl4030charger_usb_en(int enable);
-#else
- static inline int twl4030charger_usb_en(int enable) { return 0; }
-#endif
+static inline int twl4030charger_usb_en(int enable) { return 0; }
/*----------------------------------------------------------------------*/
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index 87018dc5527..9e7a12d6385 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -782,7 +782,6 @@ extern int i2o_exec_lct_get(struct i2o_controller *);
#define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
#define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
-#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj))
/**
* i2o_out_to_virt - Turn an I2O message to a virtual address
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 97e6ab43518..3239d1c10ac 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1169,6 +1169,7 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
extern void ide_timer_expiry(unsigned long);
extern irqreturn_t ide_intr(int irq, void *dev_id);
extern void do_ide_request(struct request_queue *);
+extern void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq);
void ide_init_disk(struct gendisk *, ide_drive_t *);
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
index 1822d635be6..16b92d008be 100644
--- a/include/linux/if_tunnel.h
+++ b/include/linux/if_tunnel.h
@@ -2,6 +2,7 @@
#define _IF_TUNNEL_H_
#include <linux/types.h>
+#include <asm/byteorder.h>
#ifdef __KERNEL__
#include <linux/ip.h>
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index abec69b63d7..b1ed1cd8e2a 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -32,14 +32,6 @@ extern struct fs_struct init_fs;
}
extern struct nsproxy init_nsproxy;
-#define INIT_NSPROXY(nsproxy) { \
- .pid_ns = &init_pid_ns, \
- .count = ATOMIC_INIT(1), \
- .uts_ns = &init_uts_ns, \
- .mnt_ns = NULL, \
- INIT_NET_NS(net_ns) \
- INIT_IPC_NS(ipc_ns) \
-}
#define INIT_SIGHAND(sighand) { \
.count = ATOMIC_INIT(1), \
diff --git a/include/linux/input.h b/include/linux/input.h
index dc24effb6d0..7ed2251b33f 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -58,10 +58,10 @@ struct input_absinfo {
#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, int[2]) /* get repeat settings */
-#define EVIOCSREP _IOW('E', 0x03, int[2]) /* set repeat settings */
-#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */
-#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */
+#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 EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
@@ -1142,8 +1142,10 @@ struct input_dev {
unsigned int keycodemax;
unsigned int keycodesize;
void *keycode;
- int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
- int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
+ int (*setkeycode)(struct input_dev *dev,
+ unsigned int scancode, unsigned int keycode);
+ int (*getkeycode)(struct input_dev *dev,
+ unsigned int scancode, unsigned int *keycode);
struct ff_device *ff;
@@ -1415,8 +1417,10 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
}
-int input_get_keycode(struct input_dev *dev, int scancode, int *keycode);
-int input_set_keycode(struct input_dev *dev, int scancode, int keycode);
+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);
extern struct class input_class;
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index 3bd018baae2..c964cd7f436 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -44,6 +44,7 @@ struct matrix_keymap_data {
* @active_low: gpio polarity
* @wakeup: controls whether the device should be set up as wakeup
* source
+ * @no_autorepeat: disable key autorepeat
*
* This structure represents platform-specific data that use used by
* matrix_keypad driver to perform proper initialization.
@@ -64,6 +65,7 @@ struct matrix_keypad_platform_data {
bool active_low;
bool wakeup;
+ bool no_autorepeat;
};
/**
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h
index 97eb928b492..25085ddd955 100644
--- a/include/linux/io-mapping.h
+++ b/include/linux/io-mapping.h
@@ -19,6 +19,7 @@
#define _LINUX_IO_MAPPING_H
#include <linux/types.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/iomap.h>
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
index 1195a806fe0..a0bb301afac 100644
--- a/include/linux/iocontext.h
+++ b/include/linux/iocontext.h
@@ -42,7 +42,7 @@ struct io_context {
unsigned short ioprio;
unsigned short ioprio_changed;
-#ifdef CONFIG_BLK_CGROUP
+#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
unsigned short cgroup_changed;
#endif
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index dda98410d58..26fad187d66 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -34,22 +34,24 @@ struct resource_list {
*/
#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
-#define IORESOURCE_TYPE_BITS 0x00000f00 /* Resource type */
+#define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */
#define IORESOURCE_IO 0x00000100
#define IORESOURCE_MEM 0x00000200
#define IORESOURCE_IRQ 0x00000400
#define IORESOURCE_DMA 0x00000800
+#define IORESOURCE_BUS 0x00001000
-#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */
-#define IORESOURCE_READONLY 0x00002000
-#define IORESOURCE_CACHEABLE 0x00004000
-#define IORESOURCE_RANGELENGTH 0x00008000
-#define IORESOURCE_SHADOWABLE 0x00010000
+#define IORESOURCE_PREFETCH 0x00002000 /* No side effects */
+#define IORESOURCE_READONLY 0x00004000
+#define IORESOURCE_CACHEABLE 0x00008000
+#define IORESOURCE_RANGELENGTH 0x00010000
+#define IORESOURCE_SHADOWABLE 0x00020000
-#define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */
-#define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */
+#define IORESOURCE_SIZEALIGN 0x00040000 /* size indicates alignment */
+#define IORESOURCE_STARTALIGN 0x00080000 /* start field is alignment */
#define IORESOURCE_MEM_64 0x00100000
+#define IORESOURCE_WINDOW 0x00200000 /* forwarded by bridge */
#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */
#define IORESOURCE_DISABLED 0x10000000
@@ -110,12 +112,14 @@ struct resource_list {
extern struct resource ioport_resource;
extern struct resource iomem_resource;
+extern struct resource *request_resource_conflict(struct resource *root, struct resource *new);
extern int request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
void release_child_resources(struct resource *new);
extern void reserve_region_with_split(struct resource *root,
resource_size_t start, resource_size_t end,
const char *name);
+extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new);
extern int insert_resource(struct resource *parent, struct resource *new);
extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
extern int allocate_resource(struct resource *root, struct resource *new,
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index 07baa38bce3..51952989ad4 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -62,11 +62,6 @@ extern struct ipc_namespace init_ipc_ns;
extern atomic_t nr_ipc_ns;
extern spinlock_t mq_lock;
-#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
-#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
-#else
-#define INIT_IPC_NS(ns)
-#endif
#ifdef CONFIG_SYSVIPC
extern int register_ipcns_notifier(struct ipc_namespace *);
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index f7c9c75a277..4b48318ac54 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -39,7 +39,6 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
-#include <linux/ipmi_smi.h>
/* This files describes the interface for IPMI system management interface
drivers to bind into the IPMI message handler. */
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index 6092487e295..d2e4042f8f5 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -42,9 +42,13 @@ extern struct ibft_table_header *ibft_addr;
* mapped address is set in the ibft_addr variable.
*/
#ifdef CONFIG_ISCSI_IBFT_FIND
-extern void __init reserve_ibft_region(void);
+unsigned long find_ibft_region(unsigned long *sizep);
#else
-static inline void reserve_ibft_region(void) { }
+static inline unsigned long find_ibft_region(unsigned long *sizep)
+{
+ *sizep = 0;
+ return 0;
+}
#endif
#endif /* ISCSI_IBFT_H */
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 331530cd3cc..516a2a27e87 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -31,6 +31,7 @@
#include <linux/mutex.h>
#include <linux/timer.h>
#include <linux/lockdep.h>
+#include <linux/slab.h>
#define journal_oom_retry 1
@@ -246,19 +247,8 @@ typedef struct journal_superblock_s
#define J_ASSERT(assert) BUG_ON(!(assert))
-#if defined(CONFIG_BUFFER_DEBUG)
-void buffer_assertion_failure(struct buffer_head *bh);
-#define J_ASSERT_BH(bh, expr) \
- do { \
- if (!(expr)) \
- buffer_assertion_failure(bh); \
- J_ASSERT(expr); \
- } while (0)
-#define J_ASSERT_JH(jh, expr) J_ASSERT_BH(jh2bh(jh), expr)
-#else
#define J_ASSERT_BH(bh, expr) J_ASSERT(expr)
#define J_ASSERT_JH(jh, expr) J_ASSERT(expr)
-#endif
#if defined(JBD_PARANOID_IOFAIL)
#define J_EXPECT(expr, why...) J_ASSERT(expr)
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 638ce4554c7..a4d2e9f7088 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -30,6 +30,7 @@
#include <linux/bit_spinlock.h>
#include <linux/mutex.h>
#include <linux/timer.h>
+#include <linux/slab.h>
#endif
#define journal_oom_retry 1
@@ -69,15 +70,8 @@ extern u8 jbd2_journal_enable_debug;
#define jbd_debug(f, a...) /**/
#endif
-static inline void *jbd2_alloc(size_t size, gfp_t flags)
-{
- return (void *)__get_free_pages(flags, get_order(size));
-}
-
-static inline void jbd2_free(void *ptr, size_t size)
-{
- free_pages((unsigned long)ptr, get_order(size));
-};
+extern void *jbd2_alloc(size_t size, gfp_t flags);
+extern void jbd2_free(void *ptr, size_t size);
#define JBD2_MIN_JOURNAL_BLOCKS 1024
@@ -284,19 +278,8 @@ typedef struct journal_superblock_s
#define J_ASSERT(assert) BUG_ON(!(assert))
-#if defined(CONFIG_BUFFER_DEBUG)
-void buffer_assertion_failure(struct buffer_head *bh);
-#define J_ASSERT_BH(bh, expr) \
- do { \
- if (!(expr)) \
- buffer_assertion_failure(bh); \
- J_ASSERT(expr); \
- } while (0)
-#define J_ASSERT_JH(jh, expr) J_ASSERT_BH(jh2bh(jh), expr)
-#else
#define J_ASSERT_BH(bh, expr) J_ASSERT(expr)
#define J_ASSERT_JH(jh, expr) J_ASSERT(expr)
-#endif
#if defined(JBD2_PARANOID_IOFAIL)
#define J_EXPECT(expr, why...) J_ASSERT(expr)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 7f070746336..9365227dbaf 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -426,7 +426,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
.burst = DEFAULT_RATELIMIT_BURST, \
}; \
\
- if (!__ratelimit(&_rs)) \
+ if (__ratelimit(&_rs)) \
printk(fmt, ##__VA_ARGS__); \
})
#else
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index bc0fc795bd3..e117b1aee69 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -86,7 +86,8 @@ union { \
*/
#define INIT_KFIFO(name) \
name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \
- sizeof(struct kfifo), name##kfifo_buffer)
+ sizeof(struct kfifo), \
+ name##kfifo_buffer + sizeof(struct kfifo))
/**
* DEFINE_KFIFO - macro to define and initialize a kfifo
@@ -102,8 +103,6 @@ union { \
unsigned char name##kfifo_buffer[size]; \
struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer)
-#undef __kfifo_initializer
-
extern void kfifo_init(struct kfifo *fifo, void *buffer,
unsigned int size);
extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 384ca8bbf1a..facb27fe7de 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -27,6 +27,7 @@
#define KMOD_PATH_LEN 256
#ifdef CONFIG_MODULES
+extern char modprobe_path[]; /* for sysctl */
/* modprobe exit status on success, -ve on error. Return value
* usually useless though. */
extern int __request_module(bool wait, const char *name, ...) \
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 58ae8e00fcd..3950d3c2850 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -106,7 +106,7 @@ extern char *kobject_get_path(struct kobject *kobj, gfp_t flag);
struct kobj_type {
void (*release)(struct kobject *kobj);
- struct sysfs_ops *sysfs_ops;
+ const struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
};
@@ -118,9 +118,9 @@ struct kobj_uevent_env {
};
struct kset_uevent_ops {
- int (*filter)(struct kset *kset, struct kobject *kobj);
- const char *(*name)(struct kset *kset, struct kobject *kobj);
- int (*uevent)(struct kset *kset, struct kobject *kobj,
+ int (* const filter)(struct kset *kset, struct kobject *kobj);
+ const char *(* const name)(struct kset *kset, struct kobject *kobj);
+ int (* const uevent)(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env);
};
@@ -132,7 +132,7 @@ struct kobj_attribute {
const char *buf, size_t count);
};
-extern struct sysfs_ops kobj_sysfs_ops;
+extern const struct sysfs_ops kobj_sysfs_ops;
/**
* struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
@@ -155,14 +155,14 @@ struct kset {
struct list_head list;
spinlock_t list_lock;
struct kobject kobj;
- struct kset_uevent_ops *uevent_ops;
+ const struct kset_uevent_ops *uevent_ops;
};
extern void kset_init(struct kset *kset);
extern int __must_check kset_register(struct kset *kset);
extern void kset_unregister(struct kset *kset);
extern struct kset * __must_check kset_create_and_add(const char *name,
- struct kset_uevent_ops *u,
+ const struct kset_uevent_ops *u,
struct kobject *parent_kobj);
static inline struct kset *to_kset(struct kobject *kobj)
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 1b672f74a32..e7d1b2e0070 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -122,6 +122,11 @@ struct kprobe {
/* Kprobe status flags */
#define KPROBE_FLAG_GONE 1 /* breakpoint has already gone */
#define KPROBE_FLAG_DISABLED 2 /* probe is temporarily disabled */
+#define KPROBE_FLAG_OPTIMIZED 4 /*
+ * probe is really optimized.
+ * NOTE:
+ * this flag is only for optimized_kprobe.
+ */
/* Has this kprobe gone ? */
static inline int kprobe_gone(struct kprobe *p)
@@ -134,6 +139,12 @@ static inline int kprobe_disabled(struct kprobe *p)
{
return p->flags & (KPROBE_FLAG_DISABLED | KPROBE_FLAG_GONE);
}
+
+/* Is this kprobe really running optimized path ? */
+static inline int kprobe_optimized(struct kprobe *p)
+{
+ return p->flags & KPROBE_FLAG_OPTIMIZED;
+}
/*
* Special probe type that uses setjmp-longjmp type tricks to resume
* execution at a specified entry with a matching prototype corresponding
@@ -249,6 +260,39 @@ extern kprobe_opcode_t *get_insn_slot(void);
extern void free_insn_slot(kprobe_opcode_t *slot, int dirty);
extern void kprobes_inc_nmissed_count(struct kprobe *p);
+#ifdef CONFIG_OPTPROBES
+/*
+ * Internal structure for direct jump optimized probe
+ */
+struct optimized_kprobe {
+ struct kprobe kp;
+ struct list_head list; /* list for optimizing queue */
+ struct arch_optimized_insn optinsn;
+};
+
+/* Architecture dependent functions for direct jump optimization */
+extern int arch_prepared_optinsn(struct arch_optimized_insn *optinsn);
+extern int arch_check_optimized_kprobe(struct optimized_kprobe *op);
+extern int arch_prepare_optimized_kprobe(struct optimized_kprobe *op);
+extern void arch_remove_optimized_kprobe(struct optimized_kprobe *op);
+extern int arch_optimize_kprobe(struct optimized_kprobe *op);
+extern void arch_unoptimize_kprobe(struct optimized_kprobe *op);
+extern kprobe_opcode_t *get_optinsn_slot(void);
+extern void free_optinsn_slot(kprobe_opcode_t *slot, int dirty);
+extern int arch_within_optimized_kprobe(struct optimized_kprobe *op,
+ unsigned long addr);
+
+extern void opt_pre_handler(struct kprobe *p, struct pt_regs *regs);
+
+#ifdef CONFIG_SYSCTL
+extern int sysctl_kprobes_optimization;
+extern int proc_kprobes_optimization_handler(struct ctl_table *table,
+ int write, void __user *buffer,
+ size_t *length, loff_t *ppos);
+#endif
+
+#endif /* CONFIG_OPTPROBES */
+
/* Get the kprobe at this addr (if any) - called with preemption disabled */
struct kprobe *get_kprobe(void *addr);
void kretprobe_hash_lock(struct task_struct *tsk,
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index a24de0b1858..60df9c84eca 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -103,7 +103,7 @@ struct kvm_userspace_memory_region {
/* for kvm_memory_region::flags */
#define KVM_MEM_LOG_DIRTY_PAGES 1UL
-
+#define KVM_MEMSLOT_INVALID (1UL << 1)
/* for KVM_IRQ_LINE */
struct kvm_irq_level {
@@ -497,6 +497,11 @@ struct kvm_ioeventfd {
#endif
#define KVM_CAP_S390_PSW 42
#define KVM_CAP_PPC_SEGSTATE 43
+#define KVM_CAP_HYPERV 44
+#define KVM_CAP_HYPERV_VAPIC 45
+#define KVM_CAP_HYPERV_SPIN 46
+#define KVM_CAP_PCI_SEGMENT 47
+#define KVM_CAP_X86_ROBUST_SINGLESTEP 51
#ifdef KVM_CAP_IRQ_ROUTING
@@ -691,8 +696,9 @@ struct kvm_assigned_pci_dev {
__u32 busnr;
__u32 devfn;
__u32 flags;
+ __u32 segnr;
union {
- __u32 reserved[12];
+ __u32 reserved[11];
};
};
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index bd5a616d937..169d07758ee 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -38,6 +38,7 @@
#define KVM_REQ_MMU_SYNC 7
#define KVM_REQ_KVMCLOCK_UPDATE 8
#define KVM_REQ_KICK 9
+#define KVM_REQ_DEACTIVATE_FPU 10
#define KVM_USERSPACE_IRQ_SOURCE_ID 0
@@ -53,24 +54,24 @@ extern struct kmem_cache *kvm_vcpu_cache;
*/
struct kvm_io_bus {
int dev_count;
-#define NR_IOBUS_DEVS 6
+#define NR_IOBUS_DEVS 200
struct kvm_io_device *devs[NR_IOBUS_DEVS];
};
-void kvm_io_bus_init(struct kvm_io_bus *bus);
-void kvm_io_bus_destroy(struct kvm_io_bus *bus);
-int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr, int len,
- const void *val);
-int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len,
+enum kvm_bus {
+ KVM_MMIO_BUS,
+ KVM_PIO_BUS,
+ KVM_NR_BUSES
+};
+
+int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
+ int len, const void *val);
+int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len,
void *val);
-int __kvm_io_bus_register_dev(struct kvm_io_bus *bus,
- struct kvm_io_device *dev);
-int kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus,
+int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx,
struct kvm_io_device *dev);
-void __kvm_io_bus_unregister_dev(struct kvm_io_bus *bus,
- struct kvm_io_device *dev);
-void kvm_io_bus_unregister_dev(struct kvm *kvm, struct kvm_io_bus *bus,
- struct kvm_io_device *dev);
+int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+ struct kvm_io_device *dev);
struct kvm_vcpu {
struct kvm *kvm;
@@ -83,6 +84,8 @@ struct kvm_vcpu {
struct kvm_run *run;
unsigned long requests;
unsigned long guest_debug;
+ int srcu_idx;
+
int fpu_active;
int guest_fpu_loaded;
wait_queue_head_t wq;
@@ -116,6 +119,11 @@ struct kvm_memory_slot {
int user_alloc;
};
+static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot)
+{
+ return ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+}
+
struct kvm_kernel_irq_routing_entry {
u32 gsi;
u32 type;
@@ -150,14 +158,19 @@ struct kvm_irq_routing_table {};
#endif
-struct kvm {
- spinlock_t mmu_lock;
- spinlock_t requests_lock;
- struct rw_semaphore slots_lock;
- struct mm_struct *mm; /* userspace tied to this vm */
+struct kvm_memslots {
int nmemslots;
struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS +
KVM_PRIVATE_MEM_SLOTS];
+};
+
+struct kvm {
+ spinlock_t mmu_lock;
+ raw_spinlock_t requests_lock;
+ struct mutex slots_lock;
+ struct mm_struct *mm; /* userspace tied to this vm */
+ struct kvm_memslots *memslots;
+ struct srcu_struct srcu;
#ifdef CONFIG_KVM_APIC_ARCHITECTURE
u32 bsp_vcpu_id;
struct kvm_vcpu *bsp_vcpu;
@@ -166,8 +179,7 @@ struct kvm {
atomic_t online_vcpus;
struct list_head vm_list;
struct mutex lock;
- struct kvm_io_bus mmio_bus;
- struct kvm_io_bus pio_bus;
+ struct kvm_io_bus *buses[KVM_NR_BUSES];
#ifdef CONFIG_HAVE_KVM_EVENTFD
struct {
spinlock_t lock;
@@ -249,13 +261,20 @@ int kvm_set_memory_region(struct kvm *kvm,
int __kvm_set_memory_region(struct kvm *kvm,
struct kvm_userspace_memory_region *mem,
int user_alloc);
-int kvm_arch_set_memory_region(struct kvm *kvm,
+int kvm_arch_prepare_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *memslot,
+ struct kvm_memory_slot old,
+ struct kvm_userspace_memory_region *mem,
+ int user_alloc);
+void kvm_arch_commit_memory_region(struct kvm *kvm,
struct kvm_userspace_memory_region *mem,
struct kvm_memory_slot old,
int user_alloc);
void kvm_disable_largepages(void);
void kvm_arch_flush_shadow(struct kvm *kvm);
gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn);
+gfn_t unalias_gfn_instantiation(struct kvm *kvm, gfn_t gfn);
+
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn);
void kvm_release_page_clean(struct page *page);
@@ -264,6 +283,9 @@ void kvm_set_page_dirty(struct page *page);
void kvm_set_page_accessed(struct page *page);
pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn);
+pfn_t gfn_to_pfn_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot, gfn_t gfn);
+int memslot_id(struct kvm *kvm, gfn_t gfn);
void kvm_release_pfn_dirty(pfn_t);
void kvm_release_pfn_clean(pfn_t pfn);
void kvm_set_pfn_dirty(pfn_t pfn);
@@ -283,6 +305,7 @@ int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len);
struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);
int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn);
+unsigned long kvm_host_page_size(struct kvm *kvm, gfn_t gfn);
void mark_page_dirty(struct kvm *kvm, gfn_t gfn);
void kvm_vcpu_block(struct kvm_vcpu *vcpu);
@@ -383,6 +406,7 @@ struct kvm_assigned_dev_kernel {
struct work_struct interrupt_work;
struct list_head list;
int assigned_dev_id;
+ int host_segnr;
int host_busnr;
int host_devfn;
unsigned int entries_nr;
@@ -429,8 +453,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
#define KVM_IOMMU_CACHE_COHERENCY 0x1
#ifdef CONFIG_IOMMU_API
-int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn,
- unsigned long npages);
+int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
int kvm_iommu_map_guest(struct kvm *kvm);
int kvm_iommu_unmap_guest(struct kvm *kvm);
int kvm_assign_device(struct kvm *kvm,
@@ -480,11 +503,6 @@ static inline void kvm_guest_exit(void)
current->flags &= ~PF_VCPU;
}
-static inline int memslot_id(struct kvm *kvm, struct kvm_memory_slot *slot)
-{
- return slot - kvm->memslots;
-}
-
static inline gpa_t gfn_to_gpa(gfn_t gfn)
{
return (gpa_t)gfn << PAGE_SHIFT;
@@ -532,6 +550,10 @@ static inline int mmu_notifier_retry(struct kvm_vcpu *vcpu, unsigned long mmu_se
}
#endif
+#ifndef KVM_ARCH_HAS_UNALIAS_INSTANTIATION
+#define unalias_gfn_instantiation unalias_gfn
+#endif
+
#ifdef CONFIG_HAVE_KVM_IRQCHIP
#define KVM_MAX_IRQ_ROUTES 1024
diff --git a/include/linux/lcm.h b/include/linux/lcm.h
new file mode 100644
index 00000000000..7bf01d779b4
--- /dev/null
+++ b/include/linux/lcm.h
@@ -0,0 +1,8 @@
+#ifndef _LCM_H
+#define _LCM_H
+
+#include <linux/compiler.h>
+
+unsigned long lcm(unsigned long a, unsigned long b) __attribute_const__;
+
+#endif /* _LCM_H */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index f8ea71e6d0e..b2f2003b92e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -146,6 +146,7 @@ enum {
ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */
ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */
ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */
+ ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
ATA_DFLAG_DETACH = (1 << 24),
diff --git a/include/linux/list.h b/include/linux/list.h
index 5d9c6558e8a..8392884a297 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -498,7 +498,7 @@ static inline void list_splice_tail_init(struct list_head *list,
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
- * list_for_each_entry_safe_continue
+ * list_for_each_entry_safe_continue - continue list iteration safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
@@ -514,7 +514,7 @@ static inline void list_splice_tail_init(struct list_head *list,
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
- * list_for_each_entry_safe_from
+ * list_for_each_entry_safe_from - iterate over list from current point safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
@@ -529,7 +529,7 @@ static inline void list_splice_tail_init(struct list_head *list,
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
- * list_for_each_entry_safe_reverse
+ * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 10206a87da1..a03977a96d7 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -12,6 +12,10 @@
struct task_struct;
struct lockdep_map;
+/* for sysctl */
+extern int prove_locking;
+extern int lock_stat;
+
#ifdef CONFIG_LOCKDEP
#include <linux/linkage.h>
diff --git a/include/linux/lru_cache.h b/include/linux/lru_cache.h
index 3a2b2d9b047..de48d167568 100644
--- a/include/linux/lru_cache.h
+++ b/include/linux/lru_cache.h
@@ -64,7 +64,7 @@ For crash recovery after replication node failure,
usually the condition is softened to regions that _may_ have been target of
in-flight WRITE IO, e.g. by only lazily clearing the on-disk write-intent
bitmap, trading frequency of meta data transactions against amount of
- (possibly unneccessary) resync traffic.
+ (possibly unnecessary) resync traffic.
If we set a hard limit on the area that may be "hot" at any given time, we
limit the amount of resync traffic needed for crash recovery.
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 1f9b119f4ac..44301c6affa 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -124,7 +124,6 @@ static inline bool mem_cgroup_disabled(void)
return false;
}
-extern bool mem_cgroup_oom_called(struct task_struct *task);
void mem_cgroup_update_file_mapped(struct page *page, int val);
unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
gfp_t gfp_mask, int nid,
@@ -258,11 +257,6 @@ static inline bool mem_cgroup_disabled(void)
return true;
}
-static inline bool mem_cgroup_oom_called(struct task_struct *task)
-{
- return false;
-}
-
static inline int
mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg)
{
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 1adfe779eb9..85582e1bcee 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -36,6 +36,8 @@ struct memory_block {
struct sys_device sysdev;
};
+int arch_get_memory_phys_device(unsigned long start_pfn);
+
/* These states are exposed to userspace as text strings in sysfs */
#define MEM_ONLINE (1<<0) /* exposed to userspace */
#define MEM_GOING_OFFLINE (1<<1) /* exposed to userspace */
diff --git a/include/linux/mfd/88pm8607.h b/include/linux/mfd/88pm8607.h
deleted file mode 100644
index f41b428d2ce..00000000000
--- a/include/linux/mfd/88pm8607.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Marvell 88PM8607 Interface
- *
- * Copyright (C) 2009 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __LINUX_MFD_88PM8607_H
-#define __LINUX_MFD_88PM8607_H
-
-enum {
- PM8607_ID_BUCK1 = 0,
- PM8607_ID_BUCK2,
- PM8607_ID_BUCK3,
-
- PM8607_ID_LDO1,
- PM8607_ID_LDO2,
- PM8607_ID_LDO3,
- PM8607_ID_LDO4,
- PM8607_ID_LDO5,
- PM8607_ID_LDO6,
- PM8607_ID_LDO7,
- PM8607_ID_LDO8,
- PM8607_ID_LDO9,
- PM8607_ID_LDO10,
- PM8607_ID_LDO12,
- PM8607_ID_LDO14,
-
- PM8607_ID_RG_MAX,
-};
-
-#define CHIP_ID (0x40)
-#define CHIP_ID_MASK (0xF8)
-
-/* Interrupt Registers */
-#define PM8607_STATUS_1 (0x01)
-#define PM8607_STATUS_2 (0x02)
-#define PM8607_INT_STATUS1 (0x03)
-#define PM8607_INT_STATUS2 (0x04)
-#define PM8607_INT_STATUS3 (0x05)
-#define PM8607_INT_MASK_1 (0x06)
-#define PM8607_INT_MASK_2 (0x07)
-#define PM8607_INT_MASK_3 (0x08)
-
-/* Regulator Control Registers */
-#define PM8607_LDO1 (0x10)
-#define PM8607_LDO2 (0x11)
-#define PM8607_LDO3 (0x12)
-#define PM8607_LDO4 (0x13)
-#define PM8607_LDO5 (0x14)
-#define PM8607_LDO6 (0x15)
-#define PM8607_LDO7 (0x16)
-#define PM8607_LDO8 (0x17)
-#define PM8607_LDO9 (0x18)
-#define PM8607_LDO10 (0x19)
-#define PM8607_LDO12 (0x1A)
-#define PM8607_LDO14 (0x1B)
-#define PM8607_SLEEP_MODE1 (0x1C)
-#define PM8607_SLEEP_MODE2 (0x1D)
-#define PM8607_SLEEP_MODE3 (0x1E)
-#define PM8607_SLEEP_MODE4 (0x1F)
-#define PM8607_GO (0x20)
-#define PM8607_SLEEP_BUCK1 (0x21)
-#define PM8607_SLEEP_BUCK2 (0x22)
-#define PM8607_SLEEP_BUCK3 (0x23)
-#define PM8607_BUCK1 (0x24)
-#define PM8607_BUCK2 (0x25)
-#define PM8607_BUCK3 (0x26)
-#define PM8607_BUCK_CONTROLS (0x27)
-#define PM8607_SUPPLIES_EN11 (0x2B)
-#define PM8607_SUPPLIES_EN12 (0x2C)
-#define PM8607_GROUP1 (0x2D)
-#define PM8607_GROUP2 (0x2E)
-#define PM8607_GROUP3 (0x2F)
-#define PM8607_GROUP4 (0x30)
-#define PM8607_GROUP5 (0x31)
-#define PM8607_GROUP6 (0x32)
-#define PM8607_SUPPLIES_EN21 (0x33)
-#define PM8607_SUPPLIES_EN22 (0x34)
-
-/* RTC Control Registers */
-#define PM8607_RTC1 (0xA0)
-#define PM8607_RTC_COUNTER1 (0xA1)
-#define PM8607_RTC_COUNTER2 (0xA2)
-#define PM8607_RTC_COUNTER3 (0xA3)
-#define PM8607_RTC_COUNTER4 (0xA4)
-#define PM8607_RTC_EXPIRE1 (0xA5)
-#define PM8607_RTC_EXPIRE2 (0xA6)
-#define PM8607_RTC_EXPIRE3 (0xA7)
-#define PM8607_RTC_EXPIRE4 (0xA8)
-#define PM8607_RTC_TRIM1 (0xA9)
-#define PM8607_RTC_TRIM2 (0xAA)
-#define PM8607_RTC_TRIM3 (0xAB)
-#define PM8607_RTC_TRIM4 (0xAC)
-#define PM8607_RTC_MISC1 (0xAD)
-#define PM8607_RTC_MISC2 (0xAE)
-#define PM8607_RTC_MISC3 (0xAF)
-
-/* Misc Registers */
-#define PM8607_CHIP_ID (0x00)
-#define PM8607_LDO1 (0x10)
-#define PM8607_DVC3 (0x26)
-#define PM8607_MISC1 (0x40)
-
-/* bit definitions for PM8607 events */
-#define PM8607_EVENT_ONKEY (1 << 0)
-#define PM8607_EVENT_EXTON (1 << 1)
-#define PM8607_EVENT_CHG (1 << 2)
-#define PM8607_EVENT_BAT (1 << 3)
-#define PM8607_EVENT_RTC (1 << 4)
-#define PM8607_EVENT_CC (1 << 5)
-#define PM8607_EVENT_VBAT (1 << 8)
-#define PM8607_EVENT_VCHG (1 << 9)
-#define PM8607_EVENT_VSYS (1 << 10)
-#define PM8607_EVENT_TINT (1 << 11)
-#define PM8607_EVENT_GPADC0 (1 << 12)
-#define PM8607_EVENT_GPADC1 (1 << 13)
-#define PM8607_EVENT_GPADC2 (1 << 14)
-#define PM8607_EVENT_GPADC3 (1 << 15)
-#define PM8607_EVENT_AUDIO_SHORT (1 << 16)
-#define PM8607_EVENT_PEN (1 << 17)
-#define PM8607_EVENT_HEADSET (1 << 18)
-#define PM8607_EVENT_HOOK (1 << 19)
-#define PM8607_EVENT_MICIN (1 << 20)
-#define PM8607_EVENT_CHG_TIMEOUT (1 << 21)
-#define PM8607_EVENT_CHG_DONE (1 << 22)
-#define PM8607_EVENT_CHG_FAULT (1 << 23)
-
-/* bit definitions of Status Query Interface */
-#define PM8607_STATUS_CC (1 << 3)
-#define PM8607_STATUS_PEN (1 << 4)
-#define PM8607_STATUS_HEADSET (1 << 5)
-#define PM8607_STATUS_HOOK (1 << 6)
-#define PM8607_STATUS_MICIN (1 << 7)
-#define PM8607_STATUS_ONKEY (1 << 8)
-#define PM8607_STATUS_EXTON (1 << 9)
-#define PM8607_STATUS_CHG (1 << 10)
-#define PM8607_STATUS_BAT (1 << 11)
-#define PM8607_STATUS_VBUS (1 << 12)
-#define PM8607_STATUS_OV (1 << 13)
-
-/* bit definitions of BUCK3 */
-#define PM8607_BUCK3_DOUBLE (1 << 6)
-
-/* bit definitions of Misc1 */
-#define PM8607_MISC1_PI2C (1 << 0)
-
-/* Interrupt Number in 88PM8607 */
-enum {
- PM8607_IRQ_ONKEY = 0,
- PM8607_IRQ_EXTON,
- PM8607_IRQ_CHG,
- PM8607_IRQ_BAT,
- PM8607_IRQ_RTC,
- PM8607_IRQ_VBAT = 8,
- PM8607_IRQ_VCHG,
- PM8607_IRQ_VSYS,
- PM8607_IRQ_TINT,
- PM8607_IRQ_GPADC0,
- PM8607_IRQ_GPADC1,
- PM8607_IRQ_GPADC2,
- PM8607_IRQ_GPADC3,
- PM8607_IRQ_AUDIO_SHORT = 16,
- PM8607_IRQ_PEN,
- PM8607_IRQ_HEADSET,
- PM8607_IRQ_HOOK,
- PM8607_IRQ_MICIN,
- PM8607_IRQ_CHG_FAIL,
- PM8607_IRQ_CHG_DONE,
- PM8607_IRQ_CHG_FAULT,
-};
-
-enum {
- PM8607_CHIP_A0 = 0x40,
- PM8607_CHIP_A1 = 0x41,
- PM8607_CHIP_B0 = 0x48,
-};
-
-
-struct pm8607_chip {
- struct device *dev;
- struct mutex io_lock;
- struct i2c_client *client;
-
- int (*read)(struct pm8607_chip *chip, int reg, int bytes, void *dest);
- int (*write)(struct pm8607_chip *chip, int reg, int bytes, void *src);
-
- int buck3_double; /* DVC ramp slope double */
- unsigned char chip_id;
-
-};
-
-#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */
-
-enum {
- GI2C_PORT = 0,
- PI2C_PORT,
-};
-
-struct pm8607_platform_data {
- int i2c_port; /* Controlled by GI2C or PI2C */
- struct regulator_init_data *regulator[PM8607_MAX_REGULATOR];
-};
-
-extern int pm8607_reg_read(struct pm8607_chip *, int);
-extern int pm8607_reg_write(struct pm8607_chip *, int, unsigned char);
-extern int pm8607_bulk_read(struct pm8607_chip *, int, int,
- unsigned char *);
-extern int pm8607_bulk_write(struct pm8607_chip *, int, int,
- unsigned char *);
-extern int pm8607_set_bits(struct pm8607_chip *, int, unsigned char,
- unsigned char);
-#endif /* __LINUX_MFD_88PM8607_H */
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
new file mode 100644
index 00000000000..73f92c5feea
--- /dev/null
+++ b/include/linux/mfd/88pm860x.h
@@ -0,0 +1,375 @@
+/*
+ * Marvell 88PM860x Interface
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_MFD_88PM860X_H
+#define __LINUX_MFD_88PM860X_H
+
+#include <linux/interrupt.h>
+
+#define MFD_NAME_SIZE (40)
+
+enum {
+ CHIP_INVALID = 0,
+ CHIP_PM8606,
+ CHIP_PM8607,
+ CHIP_MAX,
+};
+
+enum {
+ PM8606_ID_INVALID,
+ PM8606_ID_BACKLIGHT,
+ PM8606_ID_LED,
+ PM8606_ID_VIBRATOR,
+ PM8606_ID_TOUCH,
+ PM8606_ID_SOUND,
+ PM8606_ID_CHARGER,
+ PM8606_ID_MAX,
+};
+
+enum {
+ PM8606_BACKLIGHT1 = 0,
+ PM8606_BACKLIGHT2,
+ PM8606_BACKLIGHT3,
+};
+
+enum {
+ PM8606_LED1_RED = 0,
+ PM8606_LED1_GREEN,
+ PM8606_LED1_BLUE,
+ PM8606_LED2_RED,
+ PM8606_LED2_GREEN,
+ PM8606_LED2_BLUE,
+ PM8607_LED_VIBRATOR,
+};
+
+
+/* 8606 Registers */
+#define PM8606_DCM_BOOST (0x00)
+#define PM8606_PWM (0x01)
+
+/* Backlight Registers */
+#define PM8606_WLED1A (0x02)
+#define PM8606_WLED1B (0x03)
+#define PM8606_WLED2A (0x04)
+#define PM8606_WLED2B (0x05)
+#define PM8606_WLED3A (0x06)
+#define PM8606_WLED3B (0x07)
+
+/* LED Registers */
+#define PM8606_RGB2A (0x08)
+#define PM8606_RGB2B (0x09)
+#define PM8606_RGB2C (0x0A)
+#define PM8606_RGB2D (0x0B)
+#define PM8606_RGB1A (0x0C)
+#define PM8606_RGB1B (0x0D)
+#define PM8606_RGB1C (0x0E)
+#define PM8606_RGB1D (0x0F)
+
+#define PM8606_PREREGULATORA (0x10)
+#define PM8606_PREREGULATORB (0x11)
+#define PM8606_VIBRATORA (0x12)
+#define PM8606_VIBRATORB (0x13)
+#define PM8606_VCHG (0x14)
+#define PM8606_VSYS (0x15)
+#define PM8606_MISC (0x16)
+#define PM8606_CHIP_ID (0x17)
+#define PM8606_STATUS (0x18)
+#define PM8606_FLAGS (0x19)
+#define PM8606_PROTECTA (0x1A)
+#define PM8606_PROTECTB (0x1B)
+#define PM8606_PROTECTC (0x1C)
+
+/* Bit definitions of PM8606 registers */
+#define PM8606_DCM_500MA (0x0) /* current limit */
+#define PM8606_DCM_750MA (0x1)
+#define PM8606_DCM_1000MA (0x2)
+#define PM8606_DCM_1250MA (0x3)
+#define PM8606_DCM_250MV (0x0 << 2)
+#define PM8606_DCM_300MV (0x1 << 2)
+#define PM8606_DCM_350MV (0x2 << 2)
+#define PM8606_DCM_400MV (0x3 << 2)
+
+#define PM8606_PWM_31200HZ (0x0)
+#define PM8606_PWM_15600HZ (0x1)
+#define PM8606_PWM_7800HZ (0x2)
+#define PM8606_PWM_3900HZ (0x3)
+#define PM8606_PWM_1950HZ (0x4)
+#define PM8606_PWM_976HZ (0x5)
+#define PM8606_PWM_488HZ (0x6)
+#define PM8606_PWM_244HZ (0x7)
+#define PM8606_PWM_FREQ_MASK (0x7)
+
+#define PM8606_WLED_ON (1 << 0)
+#define PM8606_WLED_CURRENT(x) ((x & 0x1F) << 1)
+
+#define PM8606_LED_CURRENT(x) (((x >> 2) & 0x07) << 5)
+
+#define PM8606_VSYS_EN (1 << 1)
+
+#define PM8606_MISC_OSC_EN (1 << 4)
+
+enum {
+ PM8607_ID_BUCK1 = 0,
+ PM8607_ID_BUCK2,
+ PM8607_ID_BUCK3,
+
+ PM8607_ID_LDO1,
+ PM8607_ID_LDO2,
+ PM8607_ID_LDO3,
+ PM8607_ID_LDO4,
+ PM8607_ID_LDO5,
+ PM8607_ID_LDO6,
+ PM8607_ID_LDO7,
+ PM8607_ID_LDO8,
+ PM8607_ID_LDO9,
+ PM8607_ID_LDO10,
+ PM8607_ID_LDO12,
+ PM8607_ID_LDO14,
+
+ PM8607_ID_RG_MAX,
+};
+
+#define PM8607_VERSION (0x40) /* 8607 chip ID */
+#define PM8607_VERSION_MASK (0xF0) /* 8607 chip ID mask */
+
+/* Interrupt Registers */
+#define PM8607_STATUS_1 (0x01)
+#define PM8607_STATUS_2 (0x02)
+#define PM8607_INT_STATUS1 (0x03)
+#define PM8607_INT_STATUS2 (0x04)
+#define PM8607_INT_STATUS3 (0x05)
+#define PM8607_INT_MASK_1 (0x06)
+#define PM8607_INT_MASK_2 (0x07)
+#define PM8607_INT_MASK_3 (0x08)
+
+/* Regulator Control Registers */
+#define PM8607_LDO1 (0x10)
+#define PM8607_LDO2 (0x11)
+#define PM8607_LDO3 (0x12)
+#define PM8607_LDO4 (0x13)
+#define PM8607_LDO5 (0x14)
+#define PM8607_LDO6 (0x15)
+#define PM8607_LDO7 (0x16)
+#define PM8607_LDO8 (0x17)
+#define PM8607_LDO9 (0x18)
+#define PM8607_LDO10 (0x19)
+#define PM8607_LDO12 (0x1A)
+#define PM8607_LDO14 (0x1B)
+#define PM8607_SLEEP_MODE1 (0x1C)
+#define PM8607_SLEEP_MODE2 (0x1D)
+#define PM8607_SLEEP_MODE3 (0x1E)
+#define PM8607_SLEEP_MODE4 (0x1F)
+#define PM8607_GO (0x20)
+#define PM8607_SLEEP_BUCK1 (0x21)
+#define PM8607_SLEEP_BUCK2 (0x22)
+#define PM8607_SLEEP_BUCK3 (0x23)
+#define PM8607_BUCK1 (0x24)
+#define PM8607_BUCK2 (0x25)
+#define PM8607_BUCK3 (0x26)
+#define PM8607_BUCK_CONTROLS (0x27)
+#define PM8607_SUPPLIES_EN11 (0x2B)
+#define PM8607_SUPPLIES_EN12 (0x2C)
+#define PM8607_GROUP1 (0x2D)
+#define PM8607_GROUP2 (0x2E)
+#define PM8607_GROUP3 (0x2F)
+#define PM8607_GROUP4 (0x30)
+#define PM8607_GROUP5 (0x31)
+#define PM8607_GROUP6 (0x32)
+#define PM8607_SUPPLIES_EN21 (0x33)
+#define PM8607_SUPPLIES_EN22 (0x34)
+
+/* Vibrator Control Registers */
+#define PM8607_VIBRATOR_SET (0x28)
+#define PM8607_VIBRATOR_PWM (0x29)
+
+/* GPADC Registers */
+#define PM8607_GP_BIAS1 (0x4F)
+#define PM8607_MEAS_EN1 (0x50)
+#define PM8607_MEAS_EN2 (0x51)
+#define PM8607_MEAS_EN3 (0x52)
+#define PM8607_MEAS_OFF_TIME1 (0x53)
+#define PM8607_MEAS_OFF_TIME2 (0x54)
+#define PM8607_TSI_PREBIAS (0x55) /* prebias time */
+#define PM8607_PD_PREBIAS (0x56) /* prebias time */
+#define PM8607_GPADC_MISC1 (0x57)
+
+/* RTC Control Registers */
+#define PM8607_RTC1 (0xA0)
+#define PM8607_RTC_COUNTER1 (0xA1)
+#define PM8607_RTC_COUNTER2 (0xA2)
+#define PM8607_RTC_COUNTER3 (0xA3)
+#define PM8607_RTC_COUNTER4 (0xA4)
+#define PM8607_RTC_EXPIRE1 (0xA5)
+#define PM8607_RTC_EXPIRE2 (0xA6)
+#define PM8607_RTC_EXPIRE3 (0xA7)
+#define PM8607_RTC_EXPIRE4 (0xA8)
+#define PM8607_RTC_TRIM1 (0xA9)
+#define PM8607_RTC_TRIM2 (0xAA)
+#define PM8607_RTC_TRIM3 (0xAB)
+#define PM8607_RTC_TRIM4 (0xAC)
+#define PM8607_RTC_MISC1 (0xAD)
+#define PM8607_RTC_MISC2 (0xAE)
+#define PM8607_RTC_MISC3 (0xAF)
+
+/* Misc Registers */
+#define PM8607_CHIP_ID (0x00)
+#define PM8607_B0_MISC1 (0x0C)
+#define PM8607_LDO1 (0x10)
+#define PM8607_DVC3 (0x26)
+#define PM8607_A1_MISC1 (0x40)
+
+/* bit definitions of Status Query Interface */
+#define PM8607_STATUS_CC (1 << 3)
+#define PM8607_STATUS_PEN (1 << 4)
+#define PM8607_STATUS_HEADSET (1 << 5)
+#define PM8607_STATUS_HOOK (1 << 6)
+#define PM8607_STATUS_MICIN (1 << 7)
+#define PM8607_STATUS_ONKEY (1 << 8)
+#define PM8607_STATUS_EXTON (1 << 9)
+#define PM8607_STATUS_CHG (1 << 10)
+#define PM8607_STATUS_BAT (1 << 11)
+#define PM8607_STATUS_VBUS (1 << 12)
+#define PM8607_STATUS_OV (1 << 13)
+
+/* bit definitions of BUCK3 */
+#define PM8607_BUCK3_DOUBLE (1 << 6)
+
+/* bit definitions of Misc1 */
+#define PM8607_A1_MISC1_PI2C (1 << 0)
+#define PM8607_B0_MISC1_INV_INT (1 << 0)
+#define PM8607_B0_MISC1_INT_CLEAR (1 << 1)
+#define PM8607_B0_MISC1_INT_MASK (1 << 2)
+#define PM8607_B0_MISC1_PI2C (1 << 3)
+#define PM8607_B0_MISC1_RESET (1 << 6)
+
+/* bits definitions of GPADC */
+#define PM8607_GPADC_EN (1 << 0)
+#define PM8607_GPADC_PREBIAS_MASK (3 << 1)
+#define PM8607_GPADC_SLOT_CYCLE_MASK (3 << 3) /* slow mode */
+#define PM8607_GPADC_OFF_SCALE_MASK (3 << 5) /* GP sleep mode */
+#define PM8607_GPADC_SW_CAL_MASK (1 << 7)
+
+#define PM8607_PD_PREBIAS_MASK (0x1F << 0)
+#define PM8607_PD_PRECHG_MASK (7 << 5)
+
+/* Interrupt Number in 88PM8607 */
+enum {
+ PM8607_IRQ_ONKEY,
+ PM8607_IRQ_EXTON,
+ PM8607_IRQ_CHG,
+ PM8607_IRQ_BAT,
+ PM8607_IRQ_RTC,
+ PM8607_IRQ_CC,
+ PM8607_IRQ_VBAT,
+ PM8607_IRQ_VCHG,
+ PM8607_IRQ_VSYS,
+ PM8607_IRQ_TINT,
+ PM8607_IRQ_GPADC0,
+ PM8607_IRQ_GPADC1,
+ PM8607_IRQ_GPADC2,
+ PM8607_IRQ_GPADC3,
+ PM8607_IRQ_AUDIO_SHORT,
+ PM8607_IRQ_PEN,
+ PM8607_IRQ_HEADSET,
+ PM8607_IRQ_HOOK,
+ PM8607_IRQ_MICIN,
+ PM8607_IRQ_CHG_FAIL,
+ PM8607_IRQ_CHG_DONE,
+ PM8607_IRQ_CHG_FAULT,
+};
+
+enum {
+ PM8607_CHIP_A0 = 0x40,
+ PM8607_CHIP_A1 = 0x41,
+ PM8607_CHIP_B0 = 0x48,
+};
+
+struct pm860x_chip {
+ struct device *dev;
+ struct mutex io_lock;
+ struct mutex irq_lock;
+ struct i2c_client *client;
+ struct i2c_client *companion; /* companion chip client */
+
+ int buck3_double; /* DVC ramp slope double */
+ unsigned short companion_addr;
+ int id;
+ int irq_mode;
+ int irq_base;
+ int core_irq;
+ unsigned char chip_version;
+
+};
+
+#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */
+
+enum {
+ GI2C_PORT = 0,
+ PI2C_PORT,
+};
+
+struct pm860x_backlight_pdata {
+ int id;
+ int pwm;
+ int iset;
+ unsigned long flags;
+};
+
+struct pm860x_led_pdata {
+ int id;
+ int iset;
+ unsigned long flags;
+};
+
+struct pm860x_touch_pdata {
+ int gpadc_prebias;
+ int slot_cycle;
+ int off_scale;
+ int sw_cal;
+ int tsi_prebias; /* time, slot */
+ int pen_prebias; /* time, slot */
+ int pen_prechg; /* time, slot */
+ int res_x; /* resistor of Xplate */
+ unsigned long flags;
+};
+
+struct pm860x_power_pdata {
+ unsigned fast_charge; /* charge current */
+};
+
+struct pm860x_platform_data {
+ struct pm860x_backlight_pdata *backlight;
+ struct pm860x_led_pdata *led;
+ struct pm860x_touch_pdata *touch;
+ struct pm860x_power_pdata *power;
+
+ unsigned short companion_addr; /* I2C address of companion chip */
+ int i2c_port; /* Controlled by GI2C or PI2C */
+ int irq_mode; /* Clear interrupt by read/write(0/1) */
+ int irq_base; /* IRQ base number of 88pm860x */
+ struct regulator_init_data *regulator[PM8607_MAX_REGULATOR];
+};
+
+extern char pm860x_backlight_name[][MFD_NAME_SIZE];
+extern char pm860x_led_name[][MFD_NAME_SIZE];
+
+extern int pm860x_reg_read(struct i2c_client *, int);
+extern int pm860x_reg_write(struct i2c_client *, int, unsigned char);
+extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *);
+extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *);
+extern int pm860x_set_bits(struct i2c_client *, int, unsigned char,
+ unsigned char);
+
+extern int pm860x_device_init(struct pm860x_chip *chip,
+ struct pm860x_platform_data *pdata);
+extern void pm860x_device_exit(struct pm860x_chip *chip);
+
+#endif /* __LINUX_MFD_88PM860X_H */
diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h
index e9aa4c9d749..9a881c305a5 100644
--- a/include/linux/mfd/ab3100.h
+++ b/include/linux/mfd/ab3100.h
@@ -6,7 +6,6 @@
*/
#include <linux/device.h>
-#include <linux/workqueue.h>
#include <linux/regulator/machine.h>
#ifndef MFD_AB3100_H
@@ -74,7 +73,6 @@
* @testreg_client: secondary client for test registers
* @chip_name: name of this chip variant
* @chip_id: 8 bit chip ID for this chip variant
- * @work: an event handling worker
* @event_subscribers: event subscribers are listed here
* @startup_events: a copy of the first reading of the event registers
* @startup_events_read: whether the first events have been read
@@ -90,7 +88,6 @@ struct ab3100 {
struct i2c_client *testreg_client;
char chip_name[32];
u8 chip_id;
- struct work_struct work;
struct blocking_notifier_head event_subscribers;
u32 startup_events;
bool startup_events_read;
diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h
new file mode 100644
index 00000000000..5259dfe8c58
--- /dev/null
+++ b/include/linux/mfd/max8925.h
@@ -0,0 +1,253 @@
+/*
+ * Maxim8925 Interface
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_MFD_MAX8925_H
+#define __LINUX_MFD_MAX8925_H
+
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+
+/* Unified sub device IDs for MAX8925 */
+enum {
+ MAX8925_ID_SD1,
+ MAX8925_ID_SD2,
+ MAX8925_ID_SD3,
+ MAX8925_ID_LDO1,
+ MAX8925_ID_LDO2,
+ MAX8925_ID_LDO3,
+ MAX8925_ID_LDO4,
+ MAX8925_ID_LDO5,
+ MAX8925_ID_LDO6,
+ MAX8925_ID_LDO7,
+ MAX8925_ID_LDO8,
+ MAX8925_ID_LDO9,
+ MAX8925_ID_LDO10,
+ MAX8925_ID_LDO11,
+ MAX8925_ID_LDO12,
+ MAX8925_ID_LDO13,
+ MAX8925_ID_LDO14,
+ MAX8925_ID_LDO15,
+ MAX8925_ID_LDO16,
+ MAX8925_ID_LDO17,
+ MAX8925_ID_LDO18,
+ MAX8925_ID_LDO19,
+ MAX8925_ID_LDO20,
+ MAX8925_ID_MAX,
+};
+
+enum {
+ /*
+ * Charging current threshold trigger going from fast charge
+ * to TOPOFF charge. From 5% to 20% of fasting charging current.
+ */
+ MAX8925_TOPOFF_THR_5PER,
+ MAX8925_TOPOFF_THR_10PER,
+ MAX8925_TOPOFF_THR_15PER,
+ MAX8925_TOPOFF_THR_20PER,
+};
+
+enum {
+ /* Fast charging current */
+ MAX8925_FCHG_85MA,
+ MAX8925_FCHG_300MA,
+ MAX8925_FCHG_460MA,
+ MAX8925_FCHG_600MA,
+ MAX8925_FCHG_700MA,
+ MAX8925_FCHG_800MA,
+ MAX8925_FCHG_900MA,
+ MAX8925_FCHG_1000MA,
+};
+
+/* Charger registers */
+#define MAX8925_CHG_IRQ1 (0x7e)
+#define MAX8925_CHG_IRQ2 (0x7f)
+#define MAX8925_CHG_IRQ1_MASK (0x80)
+#define MAX8925_CHG_IRQ2_MASK (0x81)
+#define MAX8925_CHG_STATUS (0x82)
+
+/* GPM registers */
+#define MAX8925_SYSENSEL (0x00)
+#define MAX8925_ON_OFF_IRQ1 (0x01)
+#define MAX8925_ON_OFF_IRQ1_MASK (0x02)
+#define MAX8925_ON_OFF_STATUS (0x03)
+#define MAX8925_ON_OFF_IRQ2 (0x0d)
+#define MAX8925_ON_OFF_IRQ2_MASK (0x0e)
+#define MAX8925_RESET_CNFG (0x0f)
+
+/* Touch registers */
+#define MAX8925_TSC_IRQ (0x00)
+#define MAX8925_TSC_IRQ_MASK (0x01)
+#define MAX8925_TSC_CNFG1 (0x02)
+#define MAX8925_ADC_SCHED (0x10)
+#define MAX8925_ADC_RES_END (0x6f)
+
+#define MAX8925_NREF_OK (1 << 4)
+
+/* RTC registers */
+#define MAX8925_ALARM0_CNTL (0x18)
+#define MAX8925_ALARM1_CNTL (0x19)
+#define MAX8925_RTC_IRQ (0x1c)
+#define MAX8925_RTC_IRQ_MASK (0x1d)
+#define MAX8925_MPL_CNTL (0x1e)
+
+/* WLED registers */
+#define MAX8925_WLED_MODE_CNTL (0x84)
+#define MAX8925_WLED_CNTL (0x85)
+
+/* MAX8925 Registers */
+#define MAX8925_SDCTL1 (0x04)
+#define MAX8925_SDCTL2 (0x07)
+#define MAX8925_SDCTL3 (0x0A)
+#define MAX8925_SDV1 (0x06)
+#define MAX8925_SDV2 (0x09)
+#define MAX8925_SDV3 (0x0C)
+#define MAX8925_LDOCTL1 (0x18)
+#define MAX8925_LDOCTL2 (0x1C)
+#define MAX8925_LDOCTL3 (0x20)
+#define MAX8925_LDOCTL4 (0x24)
+#define MAX8925_LDOCTL5 (0x28)
+#define MAX8925_LDOCTL6 (0x2C)
+#define MAX8925_LDOCTL7 (0x30)
+#define MAX8925_LDOCTL8 (0x34)
+#define MAX8925_LDOCTL9 (0x38)
+#define MAX8925_LDOCTL10 (0x3C)
+#define MAX8925_LDOCTL11 (0x40)
+#define MAX8925_LDOCTL12 (0x44)
+#define MAX8925_LDOCTL13 (0x48)
+#define MAX8925_LDOCTL14 (0x4C)
+#define MAX8925_LDOCTL15 (0x50)
+#define MAX8925_LDOCTL16 (0x10)
+#define MAX8925_LDOCTL17 (0x14)
+#define MAX8925_LDOCTL18 (0x72)
+#define MAX8925_LDOCTL19 (0x5C)
+#define MAX8925_LDOCTL20 (0x9C)
+#define MAX8925_LDOVOUT1 (0x1A)
+#define MAX8925_LDOVOUT2 (0x1E)
+#define MAX8925_LDOVOUT3 (0x22)
+#define MAX8925_LDOVOUT4 (0x26)
+#define MAX8925_LDOVOUT5 (0x2A)
+#define MAX8925_LDOVOUT6 (0x2E)
+#define MAX8925_LDOVOUT7 (0x32)
+#define MAX8925_LDOVOUT8 (0x36)
+#define MAX8925_LDOVOUT9 (0x3A)
+#define MAX8925_LDOVOUT10 (0x3E)
+#define MAX8925_LDOVOUT11 (0x42)
+#define MAX8925_LDOVOUT12 (0x46)
+#define MAX8925_LDOVOUT13 (0x4A)
+#define MAX8925_LDOVOUT14 (0x4E)
+#define MAX8925_LDOVOUT15 (0x52)
+#define MAX8925_LDOVOUT16 (0x12)
+#define MAX8925_LDOVOUT17 (0x16)
+#define MAX8925_LDOVOUT18 (0x74)
+#define MAX8925_LDOVOUT19 (0x5E)
+#define MAX8925_LDOVOUT20 (0x9E)
+
+/* bit definitions */
+#define CHG_IRQ1_MASK (0x07)
+#define CHG_IRQ2_MASK (0xff)
+#define ON_OFF_IRQ1_MASK (0xff)
+#define ON_OFF_IRQ2_MASK (0x03)
+#define TSC_IRQ_MASK (0x03)
+#define RTC_IRQ_MASK (0x0c)
+
+#define MAX8925_MAX_REGULATOR (23)
+
+#define MAX8925_NAME_SIZE (32)
+
+/* IRQ definitions */
+enum {
+ MAX8925_IRQ_VCHG_DC_OVP,
+ MAX8925_IRQ_VCHG_DC_F,
+ MAX8925_IRQ_VCHG_DC_R,
+ MAX8925_IRQ_VCHG_USB_OVP,
+ MAX8925_IRQ_VCHG_USB_F,
+ MAX8925_IRQ_VCHG_USB_R,
+ MAX8925_IRQ_VCHG_THM_OK_R,
+ MAX8925_IRQ_VCHG_THM_OK_F,
+ MAX8925_IRQ_VCHG_SYSLOW_F,
+ MAX8925_IRQ_VCHG_SYSLOW_R,
+ MAX8925_IRQ_VCHG_RST,
+ MAX8925_IRQ_VCHG_DONE,
+ MAX8925_IRQ_VCHG_TOPOFF,
+ MAX8925_IRQ_VCHG_TMR_FAULT,
+ MAX8925_IRQ_GPM_RSTIN,
+ MAX8925_IRQ_GPM_MPL,
+ MAX8925_IRQ_GPM_SW_3SEC,
+ MAX8925_IRQ_GPM_EXTON_F,
+ MAX8925_IRQ_GPM_EXTON_R,
+ MAX8925_IRQ_GPM_SW_1SEC,
+ MAX8925_IRQ_GPM_SW_F,
+ MAX8925_IRQ_GPM_SW_R,
+ MAX8925_IRQ_GPM_SYSCKEN_F,
+ MAX8925_IRQ_GPM_SYSCKEN_R,
+ MAX8925_IRQ_RTC_ALARM1,
+ MAX8925_IRQ_RTC_ALARM0,
+ MAX8925_IRQ_TSC_STICK,
+ MAX8925_IRQ_TSC_NSTICK,
+ MAX8925_NR_IRQS,
+};
+
+struct max8925_chip {
+ struct device *dev;
+ struct i2c_client *i2c;
+ struct i2c_client *adc;
+ struct i2c_client *rtc;
+ struct mutex io_lock;
+ struct mutex irq_lock;
+
+ int irq_base;
+ int core_irq;
+ int tsc_irq;
+};
+
+struct max8925_backlight_pdata {
+ int lxw_scl; /* 0/1 -- 0.8Ohm/0.4Ohm */
+ int lxw_freq; /* 700KHz ~ 1400KHz */
+ int dual_string; /* 0/1 -- single/dual string */
+};
+
+struct max8925_touch_pdata {
+ unsigned int flags;
+};
+
+struct max8925_power_pdata {
+ int (*set_charger)(int);
+ unsigned batt_detect:1;
+ unsigned topoff_threshold:2;
+ unsigned fast_charge:3; /* charge current */
+};
+
+/*
+ * irq_base: stores IRQ base number of MAX8925 in platform
+ * tsc_irq: stores IRQ number of MAX8925 TSC
+ */
+struct max8925_platform_data {
+ struct max8925_backlight_pdata *backlight;
+ struct max8925_touch_pdata *touch;
+ struct max8925_power_pdata *power;
+ struct regulator_init_data *regulator[MAX8925_MAX_REGULATOR];
+
+ int irq_base;
+ int tsc_irq;
+};
+
+extern int max8925_reg_read(struct i2c_client *, int);
+extern int max8925_reg_write(struct i2c_client *, int, unsigned char);
+extern int max8925_bulk_read(struct i2c_client *, int, int, unsigned char *);
+extern int max8925_bulk_write(struct i2c_client *, int, int, unsigned char *);
+extern int max8925_set_bits(struct i2c_client *, int, unsigned char,
+ unsigned char);
+
+extern int max8925_device_init(struct max8925_chip *,
+ struct max8925_platform_data *);
+extern void max8925_device_exit(struct max8925_chip *);
+#endif /* __LINUX_MFD_MAX8925_H */
+
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
index 94cb51a6403..8895d9d8879 100644
--- a/include/linux/mfd/mc13783.h
+++ b/include/linux/mfd/mc13783.h
@@ -26,10 +26,30 @@ int mc13783_irq_request(struct mc13783 *mc13783, int irq,
int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
irq_handler_t handler, const char *name, void *dev);
int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev);
-int mc13783_ackirq(struct mc13783 *mc13783, int irq);
-int mc13783_mask(struct mc13783 *mc13783, int irq);
-int mc13783_unmask(struct mc13783 *mc13783, int irq);
+int mc13783_irq_mask(struct mc13783 *mc13783, int irq);
+int mc13783_irq_unmask(struct mc13783 *mc13783, int irq);
+int mc13783_irq_status(struct mc13783 *mc13783, int irq,
+ int *enabled, int *pending);
+int mc13783_irq_ack(struct mc13783 *mc13783, int irq);
+
+static inline int mc13783_mask(struct mc13783 *mc13783, int irq) __deprecated;
+static inline int mc13783_mask(struct mc13783 *mc13783, int irq)
+{
+ return mc13783_irq_mask(mc13783, irq);
+}
+
+static inline int mc13783_unmask(struct mc13783 *mc13783, int irq) __deprecated;
+static inline int mc13783_unmask(struct mc13783 *mc13783, int irq)
+{
+ return mc13783_irq_unmask(mc13783, irq);
+}
+
+static inline int mc13783_ackirq(struct mc13783 *mc13783, int irq) __deprecated;
+static inline int mc13783_ackirq(struct mc13783 *mc13783, int irq)
+{
+ return mc13783_irq_ack(mc13783, irq);
+}
#define MC13783_ADC0 43
#define MC13783_ADC0_ADREFEN (1 << 10)
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index 9cb1834deff..c3f7dff8eff 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -59,7 +59,8 @@ void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state);
* data for the MMC controller
*/
struct tmio_mmc_data {
- const unsigned int hclk;
+ unsigned int hclk;
+ unsigned long capabilities;
void (*set_pwr)(struct platform_device *host, int state);
void (*set_clk_div)(struct platform_device *host, int state);
};
diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h
index aa9c3789bed..4321f044d1e 100644
--- a/include/linux/mfd/ucb1x00.h
+++ b/include/linux/mfd/ucb1x00.h
@@ -12,6 +12,7 @@
#include <linux/mfd/mcp.h>
#include <linux/gpio.h>
+#include <linux/semaphore.h>
#define UCB_IO_DATA 0x00
#define UCB_IO_DIR 0x01
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 5184b79c700..5915f6e3d9a 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -15,6 +15,7 @@
#ifndef __MFD_WM831X_CORE_H__
#define __MFD_WM831X_CORE_H__
+#include <linux/completion.h>
#include <linux/interrupt.h>
/*
@@ -254,9 +255,14 @@ struct wm831x {
int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */
int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */
+ /* Chip revision based flags */
+ unsigned has_gpio_ena:1; /* Has GPIO enable bit */
+ unsigned has_cs_sts:1; /* Has current sink status bit */
+
int num_gpio;
struct mutex auxadc_lock;
+ struct completion auxadc_done;
/* The WM831x has a security key blocking access to certain
* registers. The mutex is taken by the accessors for locking
diff --git a/include/linux/mfd/wm831x/gpio.h b/include/linux/mfd/wm831x/gpio.h
index 2835614af0e..9b163c58865 100644
--- a/include/linux/mfd/wm831x/gpio.h
+++ b/include/linux/mfd/wm831x/gpio.h
@@ -41,6 +41,10 @@
#define WM831X_GPN_OD_MASK 0x0200 /* GPN_OD */
#define WM831X_GPN_OD_SHIFT 9 /* GPN_OD */
#define WM831X_GPN_OD_WIDTH 1 /* GPN_OD */
+#define WM831X_GPN_ENA 0x0080 /* GPN_ENA */
+#define WM831X_GPN_ENA_MASK 0x0080 /* GPN_ENA */
+#define WM831X_GPN_ENA_SHIFT 7 /* GPN_ENA */
+#define WM831X_GPN_ENA_WIDTH 1 /* GPN_ENA */
#define WM831X_GPN_TRI 0x0080 /* GPN_TRI */
#define WM831X_GPN_TRI_MASK 0x0080 /* GPN_TRI */
#define WM831X_GPN_TRI_SHIFT 7 /* GPN_TRI */
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h
index 43868899bf4..98fcc977e82 100644
--- a/include/linux/mfd/wm8350/core.h
+++ b/include/linux/mfd/wm8350/core.h
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
+#include <linux/completion.h>
#include <linux/mfd/wm8350/audio.h>
#include <linux/mfd/wm8350/gpio.h>
@@ -579,6 +580,8 @@
#define WM8350_NUM_IRQ 63
+#define WM8350_NUM_IRQ_REGS 7
+
struct wm8350_reg_access {
u16 readable; /* Mask of readable bits */
u16 writable; /* Mask of writable bits */
@@ -600,11 +603,6 @@ extern const u16 wm8352_mode3_defaults[];
struct wm8350;
-struct wm8350_irq {
- irq_handler_t handler;
- void *data;
-};
-
struct wm8350_hwmon {
struct platform_device *pdev;
struct device *classdev;
@@ -624,11 +622,13 @@ struct wm8350 {
u16 *reg_cache;
struct mutex auxadc_mutex;
+ struct completion auxadc_done;
/* Interrupt handling */
- struct mutex irq_mutex; /* IRQ table mutex */
- struct wm8350_irq irq[WM8350_NUM_IRQ];
+ struct mutex irq_lock;
int chip_irq;
+ int irq_base;
+ u16 irq_masks[WM8350_NUM_IRQ_REGS];
/* Client devices */
struct wm8350_codec codec;
@@ -647,11 +647,13 @@ struct wm8350 {
* used by the platform to configure GPIO functions and similar.
* @irq_high: Set if WM8350 IRQ is active high.
* @irq_base: Base IRQ for genirq (not currently used).
+ * @gpio_base: Base for gpiolib.
*/
struct wm8350_platform_data {
int (*init)(struct wm8350 *wm8350);
int irq_high;
int irq_base;
+ int gpio_base;
};
@@ -677,12 +679,33 @@ int wm8350_block_write(struct wm8350 *wm8350, int reg, int size, u16 *src);
/*
* WM8350 internal interrupts
*/
-int wm8350_register_irq(struct wm8350 *wm8350, int irq,
- irq_handler_t handler, unsigned long flags,
- const char *name, void *data);
-int wm8350_free_irq(struct wm8350 *wm8350, int irq);
-int wm8350_mask_irq(struct wm8350 *wm8350, int irq);
-int wm8350_unmask_irq(struct wm8350 *wm8350, int irq);
+static inline int wm8350_register_irq(struct wm8350 *wm8350, int irq,
+ irq_handler_t handler,
+ unsigned long flags,
+ const char *name, void *data)
+{
+ if (!wm8350->irq_base)
+ return -ENODEV;
+
+ return request_threaded_irq(irq + wm8350->irq_base, NULL,
+ handler, flags, name, data);
+}
+
+static inline void wm8350_free_irq(struct wm8350 *wm8350, int irq, void *data)
+{
+ free_irq(irq + wm8350->irq_base, data);
+}
+
+static inline void wm8350_mask_irq(struct wm8350 *wm8350, int irq)
+{
+ disable_irq(irq + wm8350->irq_base);
+}
+
+static inline void wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
+{
+ enable_irq(irq + wm8350->irq_base);
+}
+
int wm8350_irq_init(struct wm8350 *wm8350, int irq,
struct wm8350_platform_data *pdata);
int wm8350_irq_exit(struct wm8350 *wm8350);
diff --git a/include/linux/mfd/wm8350/gpio.h b/include/linux/mfd/wm8350/gpio.h
index 71af3d6ebe9..d657bcd6d95 100644
--- a/include/linux/mfd/wm8350/gpio.h
+++ b/include/linux/mfd/wm8350/gpio.h
@@ -29,6 +29,7 @@
#define WM8350_GPIO_FUNCTION_SELECT_2 0x8D
#define WM8350_GPIO_FUNCTION_SELECT_3 0x8E
#define WM8350_GPIO_FUNCTION_SELECT_4 0x8F
+#define WM8350_GPIO_LEVEL 0xE6
/*
* GPIO Functions
diff --git a/include/linux/mfd/wm8350/rtc.h b/include/linux/mfd/wm8350/rtc.h
index 24add2bef6c..ebd72ffc62d 100644
--- a/include/linux/mfd/wm8350/rtc.h
+++ b/include/linux/mfd/wm8350/rtc.h
@@ -263,6 +263,7 @@ struct wm8350_rtc {
struct platform_device *pdev;
struct rtc_device *rtc;
int alarm_enabled; /* used over suspend/resume */
+ int update_enabled;
};
#endif
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
new file mode 100644
index 00000000000..b06ff284674
--- /dev/null
+++ b/include/linux/mfd/wm8994/core.h
@@ -0,0 +1,54 @@
+/*
+ * include/linux/mfd/wm8994/core.h -- Core interface for WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MFD_WM8994_CORE_H__
+#define __MFD_WM8994_CORE_H__
+
+struct regulator_dev;
+struct regulator_bulk_data;
+
+#define WM8994_NUM_GPIO_REGS 11
+#define WM8994_NUM_LDO_REGS 2
+
+struct wm8994 {
+ struct mutex io_lock;
+
+ struct device *dev;
+ int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
+ int bytes, void *dest);
+ int (*write_dev)(struct wm8994 *wm8994, unsigned short reg,
+ int bytes, void *src);
+
+ void *control_data;
+
+ int gpio_base;
+
+ /* Used over suspend/resume */
+ u16 ldo_regs[WM8994_NUM_LDO_REGS];
+ u16 gpio_regs[WM8994_NUM_GPIO_REGS];
+
+ struct regulator_dev *dbvdd;
+ struct regulator_bulk_data *supplies;
+};
+
+/* Device I/O API */
+int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg);
+int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
+ unsigned short val);
+int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
+ unsigned short mask, unsigned short val);
+int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
+ int count, u16 *buf);
+
+#endif
diff --git a/include/linux/mfd/wm8994/gpio.h b/include/linux/mfd/wm8994/gpio.h
new file mode 100644
index 00000000000..b4d4c22991e
--- /dev/null
+++ b/include/linux/mfd/wm8994/gpio.h
@@ -0,0 +1,72 @@
+/*
+ * include/linux/mfd/wm8994/gpio.h - GPIO configuration for WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MFD_WM8994_GPIO_H__
+#define __MFD_WM8994_GPIO_H__
+
+#define WM8994_GPIO_MAX 11
+
+#define WM8994_GP_FN_PIN_SPECIFIC 0
+#define WM8994_GP_FN_GPIO 1
+#define WM8994_GP_FN_SDOUT 2
+#define WM8994_GP_FN_IRQ 3
+#define WM8994_GP_FN_TEMPERATURE 4
+#define WM8994_GP_FN_MICBIAS1_DET 5
+#define WM8994_GP_FN_MICBIAS1_SHORT 6
+#define WM8994_GP_FN_MICBIAS2_DET 7
+#define WM8994_GP_FN_MICBIAS2_SHORT 8
+#define WM8994_GP_FN_FLL1_LOCK 9
+#define WM8994_GP_FN_FLL2_LOCK 10
+#define WM8994_GP_FN_SRC1_LOCK 11
+#define WM8994_GP_FN_SRC2_LOCK 12
+#define WM8994_GP_FN_DRC1_ACT 13
+#define WM8994_GP_FN_DRC2_ACT 14
+#define WM8994_GP_FN_DRC3_ACT 15
+#define WM8994_GP_FN_WSEQ_STATUS 16
+#define WM8994_GP_FN_FIFO_ERROR 17
+#define WM8994_GP_FN_OPCLK 18
+
+#define WM8994_GPN_DIR 0x8000 /* GPN_DIR */
+#define WM8994_GPN_DIR_MASK 0x8000 /* GPN_DIR */
+#define WM8994_GPN_DIR_SHIFT 15 /* GPN_DIR */
+#define WM8994_GPN_DIR_WIDTH 1 /* GPN_DIR */
+#define WM8994_GPN_PU 0x4000 /* GPN_PU */
+#define WM8994_GPN_PU_MASK 0x4000 /* GPN_PU */
+#define WM8994_GPN_PU_SHIFT 14 /* GPN_PU */
+#define WM8994_GPN_PU_WIDTH 1 /* GPN_PU */
+#define WM8994_GPN_PD 0x2000 /* GPN_PD */
+#define WM8994_GPN_PD_MASK 0x2000 /* GPN_PD */
+#define WM8994_GPN_PD_SHIFT 13 /* GPN_PD */
+#define WM8994_GPN_PD_WIDTH 1 /* GPN_PD */
+#define WM8994_GPN_POL 0x0400 /* GPN_POL */
+#define WM8994_GPN_POL_MASK 0x0400 /* GPN_POL */
+#define WM8994_GPN_POL_SHIFT 10 /* GPN_POL */
+#define WM8994_GPN_POL_WIDTH 1 /* GPN_POL */
+#define WM8994_GPN_OP_CFG 0x0200 /* GPN_OP_CFG */
+#define WM8994_GPN_OP_CFG_MASK 0x0200 /* GPN_OP_CFG */
+#define WM8994_GPN_OP_CFG_SHIFT 9 /* GPN_OP_CFG */
+#define WM8994_GPN_OP_CFG_WIDTH 1 /* GPN_OP_CFG */
+#define WM8994_GPN_DB 0x0100 /* GPN_DB */
+#define WM8994_GPN_DB_MASK 0x0100 /* GPN_DB */
+#define WM8994_GPN_DB_SHIFT 8 /* GPN_DB */
+#define WM8994_GPN_DB_WIDTH 1 /* GPN_DB */
+#define WM8994_GPN_LVL 0x0040 /* GPN_LVL */
+#define WM8994_GPN_LVL_MASK 0x0040 /* GPN_LVL */
+#define WM8994_GPN_LVL_SHIFT 6 /* GPN_LVL */
+#define WM8994_GPN_LVL_WIDTH 1 /* GPN_LVL */
+#define WM8994_GPN_FN_MASK 0x001F /* GPN_FN - [4:0] */
+#define WM8994_GPN_FN_SHIFT 0 /* GPN_FN - [4:0] */
+#define WM8994_GPN_FN_WIDTH 5 /* GPN_FN - [4:0] */
+
+#endif
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
new file mode 100644
index 00000000000..70d6a8687dc
--- /dev/null
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -0,0 +1,97 @@
+/*
+ * include/linux/mfd/wm8994/pdata.h -- Platform data for WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MFD_WM8994_PDATA_H__
+#define __MFD_WM8994_PDATA_H__
+
+#define WM8994_NUM_LDO 2
+#define WM8994_NUM_GPIO 11
+
+struct wm8994_ldo_pdata {
+ /** GPIOs to enable regulator, 0 or less if not available */
+ int enable;
+
+ const char *supply;
+ struct regulator_init_data *init_data;
+};
+
+#define WM8994_CONFIGURE_GPIO 0x8000
+
+#define WM8994_DRC_REGS 5
+#define WM8994_EQ_REGS 19
+
+/**
+ * DRC configurations are specified with a label and a set of register
+ * values to write (the enable bits will be ignored). At runtime an
+ * enumerated control will be presented for each DRC block allowing
+ * the user to choose the configration to use.
+ *
+ * Configurations may be generated by hand or by using the DRC control
+ * panel provided by the WISCE - see http://www.wolfsonmicro.com/wisce/
+ * for details.
+ */
+struct wm8994_drc_cfg {
+ const char *name;
+ u16 regs[WM8994_DRC_REGS];
+};
+
+/**
+ * ReTune Mobile configurations are specified with a label, sample
+ * rate and set of values to write (the enable bits will be ignored).
+ *
+ * Configurations are expected to be generated using the ReTune Mobile
+ * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/
+ */
+struct wm8994_retune_mobile_cfg {
+ const char *name;
+ unsigned int rate;
+ u16 regs[WM8994_EQ_REGS];
+};
+
+struct wm8994_pdata {
+ int gpio_base;
+
+ /**
+ * Default values for GPIOs if non-zero, WM8994_CONFIGURE_GPIO
+ * can be used for all zero values.
+ */
+ int gpio_defaults[WM8994_NUM_GPIO];
+
+ struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO];
+
+
+ int num_drc_cfgs;
+ struct wm8994_drc_cfg *drc_cfgs;
+
+ int num_retune_mobile_cfgs;
+ struct wm8994_retune_mobile_cfg *retune_mobile_cfgs;
+
+ /* LINEOUT can be differential or single ended */
+ unsigned int lineout1_diff:1;
+ unsigned int lineout2_diff:1;
+
+ /* Common mode feedback */
+ unsigned int lineout1fb:1;
+ unsigned int lineout2fb:1;
+
+ /* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
+ unsigned int micbias1_lvl:1;
+ unsigned int micbias2_lvl:1;
+
+ /* Jack detect threashold levels, see datasheet for values */
+ unsigned int jd_scthr:2;
+ unsigned int jd_thr:2;
+};
+
+#endif
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
new file mode 100644
index 00000000000..967f62f5415
--- /dev/null
+++ b/include/linux/mfd/wm8994/registers.h
@@ -0,0 +1,4292 @@
+/*
+ * include/linux/mfd/wm8994/registers.h -- Register definitions for WM8994
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MFD_WM8994_REGISTERS_H__
+#define __MFD_WM8994_REGISTERS_H__
+
+/*
+ * Register values.
+ */
+#define WM8994_SOFTWARE_RESET 0x00
+#define WM8994_POWER_MANAGEMENT_1 0x01
+#define WM8994_POWER_MANAGEMENT_2 0x02
+#define WM8994_POWER_MANAGEMENT_3 0x03
+#define WM8994_POWER_MANAGEMENT_4 0x04
+#define WM8994_POWER_MANAGEMENT_5 0x05
+#define WM8994_POWER_MANAGEMENT_6 0x06
+#define WM8994_INPUT_MIXER_1 0x15
+#define WM8994_LEFT_LINE_INPUT_1_2_VOLUME 0x18
+#define WM8994_LEFT_LINE_INPUT_3_4_VOLUME 0x19
+#define WM8994_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
+#define WM8994_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
+#define WM8994_LEFT_OUTPUT_VOLUME 0x1C
+#define WM8994_RIGHT_OUTPUT_VOLUME 0x1D
+#define WM8994_LINE_OUTPUTS_VOLUME 0x1E
+#define WM8994_HPOUT2_VOLUME 0x1F
+#define WM8994_LEFT_OPGA_VOLUME 0x20
+#define WM8994_RIGHT_OPGA_VOLUME 0x21
+#define WM8994_SPKMIXL_ATTENUATION 0x22
+#define WM8994_SPKMIXR_ATTENUATION 0x23
+#define WM8994_SPKOUT_MIXERS 0x24
+#define WM8994_CLASSD 0x25
+#define WM8994_SPEAKER_VOLUME_LEFT 0x26
+#define WM8994_SPEAKER_VOLUME_RIGHT 0x27
+#define WM8994_INPUT_MIXER_2 0x28
+#define WM8994_INPUT_MIXER_3 0x29
+#define WM8994_INPUT_MIXER_4 0x2A
+#define WM8994_INPUT_MIXER_5 0x2B
+#define WM8994_INPUT_MIXER_6 0x2C
+#define WM8994_OUTPUT_MIXER_1 0x2D
+#define WM8994_OUTPUT_MIXER_2 0x2E
+#define WM8994_OUTPUT_MIXER_3 0x2F
+#define WM8994_OUTPUT_MIXER_4 0x30
+#define WM8994_OUTPUT_MIXER_5 0x31
+#define WM8994_OUTPUT_MIXER_6 0x32
+#define WM8994_HPOUT2_MIXER 0x33
+#define WM8994_LINE_MIXER_1 0x34
+#define WM8994_LINE_MIXER_2 0x35
+#define WM8994_SPEAKER_MIXER 0x36
+#define WM8994_ADDITIONAL_CONTROL 0x37
+#define WM8994_ANTIPOP_1 0x38
+#define WM8994_ANTIPOP_2 0x39
+#define WM8994_MICBIAS 0x3A
+#define WM8994_LDO_1 0x3B
+#define WM8994_LDO_2 0x3C
+#define WM8994_CHARGE_PUMP_1 0x4C
+#define WM8994_CLASS_W_1 0x51
+#define WM8994_DC_SERVO_1 0x54
+#define WM8994_DC_SERVO_2 0x55
+#define WM8994_DC_SERVO_4 0x57
+#define WM8994_DC_SERVO_READBACK 0x58
+#define WM8994_ANALOGUE_HP_1 0x60
+#define WM8994_CHIP_REVISION 0x100
+#define WM8994_CONTROL_INTERFACE 0x101
+#define WM8994_WRITE_SEQUENCER_CTRL_1 0x110
+#define WM8994_WRITE_SEQUENCER_CTRL_2 0x111
+#define WM8994_AIF1_CLOCKING_1 0x200
+#define WM8994_AIF1_CLOCKING_2 0x201
+#define WM8994_AIF2_CLOCKING_1 0x204
+#define WM8994_AIF2_CLOCKING_2 0x205
+#define WM8994_CLOCKING_1 0x208
+#define WM8994_CLOCKING_2 0x209
+#define WM8994_AIF1_RATE 0x210
+#define WM8994_AIF2_RATE 0x211
+#define WM8994_RATE_STATUS 0x212
+#define WM8994_FLL1_CONTROL_1 0x220
+#define WM8994_FLL1_CONTROL_2 0x221
+#define WM8994_FLL1_CONTROL_3 0x222
+#define WM8994_FLL1_CONTROL_4 0x223
+#define WM8994_FLL1_CONTROL_5 0x224
+#define WM8994_FLL2_CONTROL_1 0x240
+#define WM8994_FLL2_CONTROL_2 0x241
+#define WM8994_FLL2_CONTROL_3 0x242
+#define WM8994_FLL2_CONTROL_4 0x243
+#define WM8994_FLL2_CONTROL_5 0x244
+#define WM8994_AIF1_CONTROL_1 0x300
+#define WM8994_AIF1_CONTROL_2 0x301
+#define WM8994_AIF1_MASTER_SLAVE 0x302
+#define WM8994_AIF1_BCLK 0x303
+#define WM8994_AIF1ADC_LRCLK 0x304
+#define WM8994_AIF1DAC_LRCLK 0x305
+#define WM8994_AIF1DAC_DATA 0x306
+#define WM8994_AIF1ADC_DATA 0x307
+#define WM8994_AIF2_CONTROL_1 0x310
+#define WM8994_AIF2_CONTROL_2 0x311
+#define WM8994_AIF2_MASTER_SLAVE 0x312
+#define WM8994_AIF2_BCLK 0x313
+#define WM8994_AIF2ADC_LRCLK 0x314
+#define WM8994_AIF2DAC_LRCLK 0x315
+#define WM8994_AIF2DAC_DATA 0x316
+#define WM8994_AIF2ADC_DATA 0x317
+#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400
+#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401
+#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402
+#define WM8994_AIF1_DAC1_RIGHT_VOLUME 0x403
+#define WM8994_AIF1_ADC2_LEFT_VOLUME 0x404
+#define WM8994_AIF1_ADC2_RIGHT_VOLUME 0x405
+#define WM8994_AIF1_DAC2_LEFT_VOLUME 0x406
+#define WM8994_AIF1_DAC2_RIGHT_VOLUME 0x407
+#define WM8994_AIF1_ADC1_FILTERS 0x410
+#define WM8994_AIF1_ADC2_FILTERS 0x411
+#define WM8994_AIF1_DAC1_FILTERS_1 0x420
+#define WM8994_AIF1_DAC1_FILTERS_2 0x421
+#define WM8994_AIF1_DAC2_FILTERS_1 0x422
+#define WM8994_AIF1_DAC2_FILTERS_2 0x423
+#define WM8994_AIF1_DRC1_1 0x440
+#define WM8994_AIF1_DRC1_2 0x441
+#define WM8994_AIF1_DRC1_3 0x442
+#define WM8994_AIF1_DRC1_4 0x443
+#define WM8994_AIF1_DRC1_5 0x444
+#define WM8994_AIF1_DRC2_1 0x450
+#define WM8994_AIF1_DRC2_2 0x451
+#define WM8994_AIF1_DRC2_3 0x452
+#define WM8994_AIF1_DRC2_4 0x453
+#define WM8994_AIF1_DRC2_5 0x454
+#define WM8994_AIF1_DAC1_EQ_GAINS_1 0x480
+#define WM8994_AIF1_DAC1_EQ_GAINS_2 0x481
+#define WM8994_AIF1_DAC1_EQ_BAND_1_A 0x482
+#define WM8994_AIF1_DAC1_EQ_BAND_1_B 0x483
+#define WM8994_AIF1_DAC1_EQ_BAND_1_PG 0x484
+#define WM8994_AIF1_DAC1_EQ_BAND_2_A 0x485
+#define WM8994_AIF1_DAC1_EQ_BAND_2_B 0x486
+#define WM8994_AIF1_DAC1_EQ_BAND_2_C 0x487
+#define WM8994_AIF1_DAC1_EQ_BAND_2_PG 0x488
+#define WM8994_AIF1_DAC1_EQ_BAND_3_A 0x489
+#define WM8994_AIF1_DAC1_EQ_BAND_3_B 0x48A
+#define WM8994_AIF1_DAC1_EQ_BAND_3_C 0x48B
+#define WM8994_AIF1_DAC1_EQ_BAND_3_PG 0x48C
+#define WM8994_AIF1_DAC1_EQ_BAND_4_A 0x48D
+#define WM8994_AIF1_DAC1_EQ_BAND_4_B 0x48E
+#define WM8994_AIF1_DAC1_EQ_BAND_4_C 0x48F
+#define WM8994_AIF1_DAC1_EQ_BAND_4_PG 0x490
+#define WM8994_AIF1_DAC1_EQ_BAND_5_A 0x491
+#define WM8994_AIF1_DAC1_EQ_BAND_5_B 0x492
+#define WM8994_AIF1_DAC1_EQ_BAND_5_PG 0x493
+#define WM8994_AIF1_DAC2_EQ_GAINS_1 0x4A0
+#define WM8994_AIF1_DAC2_EQ_GAINS_2 0x4A1
+#define WM8994_AIF1_DAC2_EQ_BAND_1_A 0x4A2
+#define WM8994_AIF1_DAC2_EQ_BAND_1_B 0x4A3
+#define WM8994_AIF1_DAC2_EQ_BAND_1_PG 0x4A4
+#define WM8994_AIF1_DAC2_EQ_BAND_2_A 0x4A5
+#define WM8994_AIF1_DAC2_EQ_BAND_2_B 0x4A6
+#define WM8994_AIF1_DAC2_EQ_BAND_2_C 0x4A7
+#define WM8994_AIF1_DAC2_EQ_BAND_2_PG 0x4A8
+#define WM8994_AIF1_DAC2_EQ_BAND_3_A 0x4A9
+#define WM8994_AIF1_DAC2_EQ_BAND_3_B 0x4AA
+#define WM8994_AIF1_DAC2_EQ_BAND_3_C 0x4AB
+#define WM8994_AIF1_DAC2_EQ_BAND_3_PG 0x4AC
+#define WM8994_AIF1_DAC2_EQ_BAND_4_A 0x4AD
+#define WM8994_AIF1_DAC2_EQ_BAND_4_B 0x4AE
+#define WM8994_AIF1_DAC2_EQ_BAND_4_C 0x4AF
+#define WM8994_AIF1_DAC2_EQ_BAND_4_PG 0x4B0
+#define WM8994_AIF1_DAC2_EQ_BAND_5_A 0x4B1
+#define WM8994_AIF1_DAC2_EQ_BAND_5_B 0x4B2
+#define WM8994_AIF1_DAC2_EQ_BAND_5_PG 0x4B3
+#define WM8994_AIF2_ADC_LEFT_VOLUME 0x500
+#define WM8994_AIF2_ADC_RIGHT_VOLUME 0x501
+#define WM8994_AIF2_DAC_LEFT_VOLUME 0x502
+#define WM8994_AIF2_DAC_RIGHT_VOLUME 0x503
+#define WM8994_AIF2_ADC_FILTERS 0x510
+#define WM8994_AIF2_DAC_FILTERS_1 0x520
+#define WM8994_AIF2_DAC_FILTERS_2 0x521
+#define WM8994_AIF2_DRC_1 0x540
+#define WM8994_AIF2_DRC_2 0x541
+#define WM8994_AIF2_DRC_3 0x542
+#define WM8994_AIF2_DRC_4 0x543
+#define WM8994_AIF2_DRC_5 0x544
+#define WM8994_AIF2_EQ_GAINS_1 0x580
+#define WM8994_AIF2_EQ_GAINS_2 0x581
+#define WM8994_AIF2_EQ_BAND_1_A 0x582
+#define WM8994_AIF2_EQ_BAND_1_B 0x583
+#define WM8994_AIF2_EQ_BAND_1_PG 0x584
+#define WM8994_AIF2_EQ_BAND_2_A 0x585
+#define WM8994_AIF2_EQ_BAND_2_B 0x586
+#define WM8994_AIF2_EQ_BAND_2_C 0x587
+#define WM8994_AIF2_EQ_BAND_2_PG 0x588
+#define WM8994_AIF2_EQ_BAND_3_A 0x589
+#define WM8994_AIF2_EQ_BAND_3_B 0x58A
+#define WM8994_AIF2_EQ_BAND_3_C 0x58B
+#define WM8994_AIF2_EQ_BAND_3_PG 0x58C
+#define WM8994_AIF2_EQ_BAND_4_A 0x58D
+#define WM8994_AIF2_EQ_BAND_4_B 0x58E
+#define WM8994_AIF2_EQ_BAND_4_C 0x58F
+#define WM8994_AIF2_EQ_BAND_4_PG 0x590
+#define WM8994_AIF2_EQ_BAND_5_A 0x591
+#define WM8994_AIF2_EQ_BAND_5_B 0x592
+#define WM8994_AIF2_EQ_BAND_5_PG 0x593
+#define WM8994_DAC1_MIXER_VOLUMES 0x600
+#define WM8994_DAC1_LEFT_MIXER_ROUTING 0x601
+#define WM8994_DAC1_RIGHT_MIXER_ROUTING 0x602
+#define WM8994_DAC2_MIXER_VOLUMES 0x603
+#define WM8994_DAC2_LEFT_MIXER_ROUTING 0x604
+#define WM8994_DAC2_RIGHT_MIXER_ROUTING 0x605
+#define WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606
+#define WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607
+#define WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608
+#define WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609
+#define WM8994_DAC1_LEFT_VOLUME 0x610
+#define WM8994_DAC1_RIGHT_VOLUME 0x611
+#define WM8994_DAC2_LEFT_VOLUME 0x612
+#define WM8994_DAC2_RIGHT_VOLUME 0x613
+#define WM8994_DAC_SOFTMUTE 0x614
+#define WM8994_OVERSAMPLING 0x620
+#define WM8994_SIDETONE 0x621
+#define WM8994_GPIO_1 0x700
+#define WM8994_GPIO_2 0x701
+#define WM8994_GPIO_3 0x702
+#define WM8994_GPIO_4 0x703
+#define WM8994_GPIO_5 0x704
+#define WM8994_GPIO_6 0x705
+#define WM8994_GPIO_7 0x706
+#define WM8994_GPIO_8 0x707
+#define WM8994_GPIO_9 0x708
+#define WM8994_GPIO_10 0x709
+#define WM8994_GPIO_11 0x70A
+#define WM8994_PULL_CONTROL_1 0x720
+#define WM8994_PULL_CONTROL_2 0x721
+#define WM8994_INTERRUPT_STATUS_1 0x730
+#define WM8994_INTERRUPT_STATUS_2 0x731
+#define WM8994_INTERRUPT_RAW_STATUS_2 0x732
+#define WM8994_INTERRUPT_STATUS_1_MASK 0x738
+#define WM8994_INTERRUPT_STATUS_2_MASK 0x739
+#define WM8994_INTERRUPT_CONTROL 0x740
+#define WM8994_IRQ_DEBOUNCE 0x748
+#define WM8994_WRITE_SEQUENCER_0 0x3000
+#define WM8994_WRITE_SEQUENCER_1 0x3001
+#define WM8994_WRITE_SEQUENCER_2 0x3002
+#define WM8994_WRITE_SEQUENCER_3 0x3003
+#define WM8994_WRITE_SEQUENCER_4 0x3004
+#define WM8994_WRITE_SEQUENCER_5 0x3005
+#define WM8994_WRITE_SEQUENCER_6 0x3006
+#define WM8994_WRITE_SEQUENCER_7 0x3007
+#define WM8994_WRITE_SEQUENCER_8 0x3008
+#define WM8994_WRITE_SEQUENCER_9 0x3009
+#define WM8994_WRITE_SEQUENCER_10 0x300A
+#define WM8994_WRITE_SEQUENCER_11 0x300B
+#define WM8994_WRITE_SEQUENCER_12 0x300C
+#define WM8994_WRITE_SEQUENCER_13 0x300D
+#define WM8994_WRITE_SEQUENCER_14 0x300E
+#define WM8994_WRITE_SEQUENCER_15 0x300F
+#define WM8994_WRITE_SEQUENCER_16 0x3010
+#define WM8994_WRITE_SEQUENCER_17 0x3011
+#define WM8994_WRITE_SEQUENCER_18 0x3012
+#define WM8994_WRITE_SEQUENCER_19 0x3013
+#define WM8994_WRITE_SEQUENCER_20 0x3014
+#define WM8994_WRITE_SEQUENCER_21 0x3015
+#define WM8994_WRITE_SEQUENCER_22 0x3016
+#define WM8994_WRITE_SEQUENCER_23 0x3017
+#define WM8994_WRITE_SEQUENCER_24 0x3018
+#define WM8994_WRITE_SEQUENCER_25 0x3019
+#define WM8994_WRITE_SEQUENCER_26 0x301A
+#define WM8994_WRITE_SEQUENCER_27 0x301B
+#define WM8994_WRITE_SEQUENCER_28 0x301C
+#define WM8994_WRITE_SEQUENCER_29 0x301D
+#define WM8994_WRITE_SEQUENCER_30 0x301E
+#define WM8994_WRITE_SEQUENCER_31 0x301F
+#define WM8994_WRITE_SEQUENCER_32 0x3020
+#define WM8994_WRITE_SEQUENCER_33 0x3021
+#define WM8994_WRITE_SEQUENCER_34 0x3022
+#define WM8994_WRITE_SEQUENCER_35 0x3023
+#define WM8994_WRITE_SEQUENCER_36 0x3024
+#define WM8994_WRITE_SEQUENCER_37 0x3025
+#define WM8994_WRITE_SEQUENCER_38 0x3026
+#define WM8994_WRITE_SEQUENCER_39 0x3027
+#define WM8994_WRITE_SEQUENCER_40 0x3028
+#define WM8994_WRITE_SEQUENCER_41 0x3029
+#define WM8994_WRITE_SEQUENCER_42 0x302A
+#define WM8994_WRITE_SEQUENCER_43 0x302B
+#define WM8994_WRITE_SEQUENCER_44 0x302C
+#define WM8994_WRITE_SEQUENCER_45 0x302D
+#define WM8994_WRITE_SEQUENCER_46 0x302E
+#define WM8994_WRITE_SEQUENCER_47 0x302F
+#define WM8994_WRITE_SEQUENCER_48 0x3030
+#define WM8994_WRITE_SEQUENCER_49 0x3031
+#define WM8994_WRITE_SEQUENCER_50 0x3032
+#define WM8994_WRITE_SEQUENCER_51 0x3033
+#define WM8994_WRITE_SEQUENCER_52 0x3034
+#define WM8994_WRITE_SEQUENCER_53 0x3035
+#define WM8994_WRITE_SEQUENCER_54 0x3036
+#define WM8994_WRITE_SEQUENCER_55 0x3037
+#define WM8994_WRITE_SEQUENCER_56 0x3038
+#define WM8994_WRITE_SEQUENCER_57 0x3039
+#define WM8994_WRITE_SEQUENCER_58 0x303A
+#define WM8994_WRITE_SEQUENCER_59 0x303B
+#define WM8994_WRITE_SEQUENCER_60 0x303C
+#define WM8994_WRITE_SEQUENCER_61 0x303D
+#define WM8994_WRITE_SEQUENCER_62 0x303E
+#define WM8994_WRITE_SEQUENCER_63 0x303F
+#define WM8994_WRITE_SEQUENCER_64 0x3040
+#define WM8994_WRITE_SEQUENCER_65 0x3041
+#define WM8994_WRITE_SEQUENCER_66 0x3042
+#define WM8994_WRITE_SEQUENCER_67 0x3043
+#define WM8994_WRITE_SEQUENCER_68 0x3044
+#define WM8994_WRITE_SEQUENCER_69 0x3045
+#define WM8994_WRITE_SEQUENCER_70 0x3046
+#define WM8994_WRITE_SEQUENCER_71 0x3047
+#define WM8994_WRITE_SEQUENCER_72 0x3048
+#define WM8994_WRITE_SEQUENCER_73 0x3049
+#define WM8994_WRITE_SEQUENCER_74 0x304A
+#define WM8994_WRITE_SEQUENCER_75 0x304B
+#define WM8994_WRITE_SEQUENCER_76 0x304C
+#define WM8994_WRITE_SEQUENCER_77 0x304D
+#define WM8994_WRITE_SEQUENCER_78 0x304E
+#define WM8994_WRITE_SEQUENCER_79 0x304F
+#define WM8994_WRITE_SEQUENCER_80 0x3050
+#define WM8994_WRITE_SEQUENCER_81 0x3051
+#define WM8994_WRITE_SEQUENCER_82 0x3052
+#define WM8994_WRITE_SEQUENCER_83 0x3053
+#define WM8994_WRITE_SEQUENCER_84 0x3054
+#define WM8994_WRITE_SEQUENCER_85 0x3055
+#define WM8994_WRITE_SEQUENCER_86 0x3056
+#define WM8994_WRITE_SEQUENCER_87 0x3057
+#define WM8994_WRITE_SEQUENCER_88 0x3058
+#define WM8994_WRITE_SEQUENCER_89 0x3059
+#define WM8994_WRITE_SEQUENCER_90 0x305A
+#define WM8994_WRITE_SEQUENCER_91 0x305B
+#define WM8994_WRITE_SEQUENCER_92 0x305C
+#define WM8994_WRITE_SEQUENCER_93 0x305D
+#define WM8994_WRITE_SEQUENCER_94 0x305E
+#define WM8994_WRITE_SEQUENCER_95 0x305F
+#define WM8994_WRITE_SEQUENCER_96 0x3060
+#define WM8994_WRITE_SEQUENCER_97 0x3061
+#define WM8994_WRITE_SEQUENCER_98 0x3062
+#define WM8994_WRITE_SEQUENCER_99 0x3063
+#define WM8994_WRITE_SEQUENCER_100 0x3064
+#define WM8994_WRITE_SEQUENCER_101 0x3065
+#define WM8994_WRITE_SEQUENCER_102 0x3066
+#define WM8994_WRITE_SEQUENCER_103 0x3067
+#define WM8994_WRITE_SEQUENCER_104 0x3068
+#define WM8994_WRITE_SEQUENCER_105 0x3069
+#define WM8994_WRITE_SEQUENCER_106 0x306A
+#define WM8994_WRITE_SEQUENCER_107 0x306B
+#define WM8994_WRITE_SEQUENCER_108 0x306C
+#define WM8994_WRITE_SEQUENCER_109 0x306D
+#define WM8994_WRITE_SEQUENCER_110 0x306E
+#define WM8994_WRITE_SEQUENCER_111 0x306F
+#define WM8994_WRITE_SEQUENCER_112 0x3070
+#define WM8994_WRITE_SEQUENCER_113 0x3071
+#define WM8994_WRITE_SEQUENCER_114 0x3072
+#define WM8994_WRITE_SEQUENCER_115 0x3073
+#define WM8994_WRITE_SEQUENCER_116 0x3074
+#define WM8994_WRITE_SEQUENCER_117 0x3075
+#define WM8994_WRITE_SEQUENCER_118 0x3076
+#define WM8994_WRITE_SEQUENCER_119 0x3077
+#define WM8994_WRITE_SEQUENCER_120 0x3078
+#define WM8994_WRITE_SEQUENCER_121 0x3079
+#define WM8994_WRITE_SEQUENCER_122 0x307A
+#define WM8994_WRITE_SEQUENCER_123 0x307B
+#define WM8994_WRITE_SEQUENCER_124 0x307C
+#define WM8994_WRITE_SEQUENCER_125 0x307D
+#define WM8994_WRITE_SEQUENCER_126 0x307E
+#define WM8994_WRITE_SEQUENCER_127 0x307F
+#define WM8994_WRITE_SEQUENCER_128 0x3080
+#define WM8994_WRITE_SEQUENCER_129 0x3081
+#define WM8994_WRITE_SEQUENCER_130 0x3082
+#define WM8994_WRITE_SEQUENCER_131 0x3083
+#define WM8994_WRITE_SEQUENCER_132 0x3084
+#define WM8994_WRITE_SEQUENCER_133 0x3085
+#define WM8994_WRITE_SEQUENCER_134 0x3086
+#define WM8994_WRITE_SEQUENCER_135 0x3087
+#define WM8994_WRITE_SEQUENCER_136 0x3088
+#define WM8994_WRITE_SEQUENCER_137 0x3089
+#define WM8994_WRITE_SEQUENCER_138 0x308A
+#define WM8994_WRITE_SEQUENCER_139 0x308B
+#define WM8994_WRITE_SEQUENCER_140 0x308C
+#define WM8994_WRITE_SEQUENCER_141 0x308D
+#define WM8994_WRITE_SEQUENCER_142 0x308E
+#define WM8994_WRITE_SEQUENCER_143 0x308F
+#define WM8994_WRITE_SEQUENCER_144 0x3090
+#define WM8994_WRITE_SEQUENCER_145 0x3091
+#define WM8994_WRITE_SEQUENCER_146 0x3092
+#define WM8994_WRITE_SEQUENCER_147 0x3093
+#define WM8994_WRITE_SEQUENCER_148 0x3094
+#define WM8994_WRITE_SEQUENCER_149 0x3095
+#define WM8994_WRITE_SEQUENCER_150 0x3096
+#define WM8994_WRITE_SEQUENCER_151 0x3097
+#define WM8994_WRITE_SEQUENCER_152 0x3098
+#define WM8994_WRITE_SEQUENCER_153 0x3099
+#define WM8994_WRITE_SEQUENCER_154 0x309A
+#define WM8994_WRITE_SEQUENCER_155 0x309B
+#define WM8994_WRITE_SEQUENCER_156 0x309C
+#define WM8994_WRITE_SEQUENCER_157 0x309D
+#define WM8994_WRITE_SEQUENCER_158 0x309E
+#define WM8994_WRITE_SEQUENCER_159 0x309F
+#define WM8994_WRITE_SEQUENCER_160 0x30A0
+#define WM8994_WRITE_SEQUENCER_161 0x30A1
+#define WM8994_WRITE_SEQUENCER_162 0x30A2
+#define WM8994_WRITE_SEQUENCER_163 0x30A3
+#define WM8994_WRITE_SEQUENCER_164 0x30A4
+#define WM8994_WRITE_SEQUENCER_165 0x30A5
+#define WM8994_WRITE_SEQUENCER_166 0x30A6
+#define WM8994_WRITE_SEQUENCER_167 0x30A7
+#define WM8994_WRITE_SEQUENCER_168 0x30A8
+#define WM8994_WRITE_SEQUENCER_169 0x30A9
+#define WM8994_WRITE_SEQUENCER_170 0x30AA
+#define WM8994_WRITE_SEQUENCER_171 0x30AB
+#define WM8994_WRITE_SEQUENCER_172 0x30AC
+#define WM8994_WRITE_SEQUENCER_173 0x30AD
+#define WM8994_WRITE_SEQUENCER_174 0x30AE
+#define WM8994_WRITE_SEQUENCER_175 0x30AF
+#define WM8994_WRITE_SEQUENCER_176 0x30B0
+#define WM8994_WRITE_SEQUENCER_177 0x30B1
+#define WM8994_WRITE_SEQUENCER_178 0x30B2
+#define WM8994_WRITE_SEQUENCER_179 0x30B3
+#define WM8994_WRITE_SEQUENCER_180 0x30B4
+#define WM8994_WRITE_SEQUENCER_181 0x30B5
+#define WM8994_WRITE_SEQUENCER_182 0x30B6
+#define WM8994_WRITE_SEQUENCER_183 0x30B7
+#define WM8994_WRITE_SEQUENCER_184 0x30B8
+#define WM8994_WRITE_SEQUENCER_185 0x30B9
+#define WM8994_WRITE_SEQUENCER_186 0x30BA
+#define WM8994_WRITE_SEQUENCER_187 0x30BB
+#define WM8994_WRITE_SEQUENCER_188 0x30BC
+#define WM8994_WRITE_SEQUENCER_189 0x30BD
+#define WM8994_WRITE_SEQUENCER_190 0x30BE
+#define WM8994_WRITE_SEQUENCER_191 0x30BF
+#define WM8994_WRITE_SEQUENCER_192 0x30C0
+#define WM8994_WRITE_SEQUENCER_193 0x30C1
+#define WM8994_WRITE_SEQUENCER_194 0x30C2
+#define WM8994_WRITE_SEQUENCER_195 0x30C3
+#define WM8994_WRITE_SEQUENCER_196 0x30C4
+#define WM8994_WRITE_SEQUENCER_197 0x30C5
+#define WM8994_WRITE_SEQUENCER_198 0x30C6
+#define WM8994_WRITE_SEQUENCER_199 0x30C7
+#define WM8994_WRITE_SEQUENCER_200 0x30C8
+#define WM8994_WRITE_SEQUENCER_201 0x30C9
+#define WM8994_WRITE_SEQUENCER_202 0x30CA
+#define WM8994_WRITE_SEQUENCER_203 0x30CB
+#define WM8994_WRITE_SEQUENCER_204 0x30CC
+#define WM8994_WRITE_SEQUENCER_205 0x30CD
+#define WM8994_WRITE_SEQUENCER_206 0x30CE
+#define WM8994_WRITE_SEQUENCER_207 0x30CF
+#define WM8994_WRITE_SEQUENCER_208 0x30D0
+#define WM8994_WRITE_SEQUENCER_209 0x30D1
+#define WM8994_WRITE_SEQUENCER_210 0x30D2
+#define WM8994_WRITE_SEQUENCER_211 0x30D3
+#define WM8994_WRITE_SEQUENCER_212 0x30D4
+#define WM8994_WRITE_SEQUENCER_213 0x30D5
+#define WM8994_WRITE_SEQUENCER_214 0x30D6
+#define WM8994_WRITE_SEQUENCER_215 0x30D7
+#define WM8994_WRITE_SEQUENCER_216 0x30D8
+#define WM8994_WRITE_SEQUENCER_217 0x30D9
+#define WM8994_WRITE_SEQUENCER_218 0x30DA
+#define WM8994_WRITE_SEQUENCER_219 0x30DB
+#define WM8994_WRITE_SEQUENCER_220 0x30DC
+#define WM8994_WRITE_SEQUENCER_221 0x30DD
+#define WM8994_WRITE_SEQUENCER_222 0x30DE
+#define WM8994_WRITE_SEQUENCER_223 0x30DF
+#define WM8994_WRITE_SEQUENCER_224 0x30E0
+#define WM8994_WRITE_SEQUENCER_225 0x30E1
+#define WM8994_WRITE_SEQUENCER_226 0x30E2
+#define WM8994_WRITE_SEQUENCER_227 0x30E3
+#define WM8994_WRITE_SEQUENCER_228 0x30E4
+#define WM8994_WRITE_SEQUENCER_229 0x30E5
+#define WM8994_WRITE_SEQUENCER_230 0x30E6
+#define WM8994_WRITE_SEQUENCER_231 0x30E7
+#define WM8994_WRITE_SEQUENCER_232 0x30E8
+#define WM8994_WRITE_SEQUENCER_233 0x30E9
+#define WM8994_WRITE_SEQUENCER_234 0x30EA
+#define WM8994_WRITE_SEQUENCER_235 0x30EB
+#define WM8994_WRITE_SEQUENCER_236 0x30EC
+#define WM8994_WRITE_SEQUENCER_237 0x30ED
+#define WM8994_WRITE_SEQUENCER_238 0x30EE
+#define WM8994_WRITE_SEQUENCER_239 0x30EF
+#define WM8994_WRITE_SEQUENCER_240 0x30F0
+#define WM8994_WRITE_SEQUENCER_241 0x30F1
+#define WM8994_WRITE_SEQUENCER_242 0x30F2
+#define WM8994_WRITE_SEQUENCER_243 0x30F3
+#define WM8994_WRITE_SEQUENCER_244 0x30F4
+#define WM8994_WRITE_SEQUENCER_245 0x30F5
+#define WM8994_WRITE_SEQUENCER_246 0x30F6
+#define WM8994_WRITE_SEQUENCER_247 0x30F7
+#define WM8994_WRITE_SEQUENCER_248 0x30F8
+#define WM8994_WRITE_SEQUENCER_249 0x30F9
+#define WM8994_WRITE_SEQUENCER_250 0x30FA
+#define WM8994_WRITE_SEQUENCER_251 0x30FB
+#define WM8994_WRITE_SEQUENCER_252 0x30FC
+#define WM8994_WRITE_SEQUENCER_253 0x30FD
+#define WM8994_WRITE_SEQUENCER_254 0x30FE
+#define WM8994_WRITE_SEQUENCER_255 0x30FF
+#define WM8994_WRITE_SEQUENCER_256 0x3100
+#define WM8994_WRITE_SEQUENCER_257 0x3101
+#define WM8994_WRITE_SEQUENCER_258 0x3102
+#define WM8994_WRITE_SEQUENCER_259 0x3103
+#define WM8994_WRITE_SEQUENCER_260 0x3104
+#define WM8994_WRITE_SEQUENCER_261 0x3105
+#define WM8994_WRITE_SEQUENCER_262 0x3106
+#define WM8994_WRITE_SEQUENCER_263 0x3107
+#define WM8994_WRITE_SEQUENCER_264 0x3108
+#define WM8994_WRITE_SEQUENCER_265 0x3109
+#define WM8994_WRITE_SEQUENCER_266 0x310A
+#define WM8994_WRITE_SEQUENCER_267 0x310B
+#define WM8994_WRITE_SEQUENCER_268 0x310C
+#define WM8994_WRITE_SEQUENCER_269 0x310D
+#define WM8994_WRITE_SEQUENCER_270 0x310E
+#define WM8994_WRITE_SEQUENCER_271 0x310F
+#define WM8994_WRITE_SEQUENCER_272 0x3110
+#define WM8994_WRITE_SEQUENCER_273 0x3111
+#define WM8994_WRITE_SEQUENCER_274 0x3112
+#define WM8994_WRITE_SEQUENCER_275 0x3113
+#define WM8994_WRITE_SEQUENCER_276 0x3114
+#define WM8994_WRITE_SEQUENCER_277 0x3115
+#define WM8994_WRITE_SEQUENCER_278 0x3116
+#define WM8994_WRITE_SEQUENCER_279 0x3117
+#define WM8994_WRITE_SEQUENCER_280 0x3118
+#define WM8994_WRITE_SEQUENCER_281 0x3119
+#define WM8994_WRITE_SEQUENCER_282 0x311A
+#define WM8994_WRITE_SEQUENCER_283 0x311B
+#define WM8994_WRITE_SEQUENCER_284 0x311C
+#define WM8994_WRITE_SEQUENCER_285 0x311D
+#define WM8994_WRITE_SEQUENCER_286 0x311E
+#define WM8994_WRITE_SEQUENCER_287 0x311F
+#define WM8994_WRITE_SEQUENCER_288 0x3120
+#define WM8994_WRITE_SEQUENCER_289 0x3121
+#define WM8994_WRITE_SEQUENCER_290 0x3122
+#define WM8994_WRITE_SEQUENCER_291 0x3123
+#define WM8994_WRITE_SEQUENCER_292 0x3124
+#define WM8994_WRITE_SEQUENCER_293 0x3125
+#define WM8994_WRITE_SEQUENCER_294 0x3126
+#define WM8994_WRITE_SEQUENCER_295 0x3127
+#define WM8994_WRITE_SEQUENCER_296 0x3128
+#define WM8994_WRITE_SEQUENCER_297 0x3129
+#define WM8994_WRITE_SEQUENCER_298 0x312A
+#define WM8994_WRITE_SEQUENCER_299 0x312B
+#define WM8994_WRITE_SEQUENCER_300 0x312C
+#define WM8994_WRITE_SEQUENCER_301 0x312D
+#define WM8994_WRITE_SEQUENCER_302 0x312E
+#define WM8994_WRITE_SEQUENCER_303 0x312F
+#define WM8994_WRITE_SEQUENCER_304 0x3130
+#define WM8994_WRITE_SEQUENCER_305 0x3131
+#define WM8994_WRITE_SEQUENCER_306 0x3132
+#define WM8994_WRITE_SEQUENCER_307 0x3133
+#define WM8994_WRITE_SEQUENCER_308 0x3134
+#define WM8994_WRITE_SEQUENCER_309 0x3135
+#define WM8994_WRITE_SEQUENCER_310 0x3136
+#define WM8994_WRITE_SEQUENCER_311 0x3137
+#define WM8994_WRITE_SEQUENCER_312 0x3138
+#define WM8994_WRITE_SEQUENCER_313 0x3139
+#define WM8994_WRITE_SEQUENCER_314 0x313A
+#define WM8994_WRITE_SEQUENCER_315 0x313B
+#define WM8994_WRITE_SEQUENCER_316 0x313C
+#define WM8994_WRITE_SEQUENCER_317 0x313D
+#define WM8994_WRITE_SEQUENCER_318 0x313E
+#define WM8994_WRITE_SEQUENCER_319 0x313F
+#define WM8994_WRITE_SEQUENCER_320 0x3140
+#define WM8994_WRITE_SEQUENCER_321 0x3141
+#define WM8994_WRITE_SEQUENCER_322 0x3142
+#define WM8994_WRITE_SEQUENCER_323 0x3143
+#define WM8994_WRITE_SEQUENCER_324 0x3144
+#define WM8994_WRITE_SEQUENCER_325 0x3145
+#define WM8994_WRITE_SEQUENCER_326 0x3146
+#define WM8994_WRITE_SEQUENCER_327 0x3147
+#define WM8994_WRITE_SEQUENCER_328 0x3148
+#define WM8994_WRITE_SEQUENCER_329 0x3149
+#define WM8994_WRITE_SEQUENCER_330 0x314A
+#define WM8994_WRITE_SEQUENCER_331 0x314B
+#define WM8994_WRITE_SEQUENCER_332 0x314C
+#define WM8994_WRITE_SEQUENCER_333 0x314D
+#define WM8994_WRITE_SEQUENCER_334 0x314E
+#define WM8994_WRITE_SEQUENCER_335 0x314F
+#define WM8994_WRITE_SEQUENCER_336 0x3150
+#define WM8994_WRITE_SEQUENCER_337 0x3151
+#define WM8994_WRITE_SEQUENCER_338 0x3152
+#define WM8994_WRITE_SEQUENCER_339 0x3153
+#define WM8994_WRITE_SEQUENCER_340 0x3154
+#define WM8994_WRITE_SEQUENCER_341 0x3155
+#define WM8994_WRITE_SEQUENCER_342 0x3156
+#define WM8994_WRITE_SEQUENCER_343 0x3157
+#define WM8994_WRITE_SEQUENCER_344 0x3158
+#define WM8994_WRITE_SEQUENCER_345 0x3159
+#define WM8994_WRITE_SEQUENCER_346 0x315A
+#define WM8994_WRITE_SEQUENCER_347 0x315B
+#define WM8994_WRITE_SEQUENCER_348 0x315C
+#define WM8994_WRITE_SEQUENCER_349 0x315D
+#define WM8994_WRITE_SEQUENCER_350 0x315E
+#define WM8994_WRITE_SEQUENCER_351 0x315F
+#define WM8994_WRITE_SEQUENCER_352 0x3160
+#define WM8994_WRITE_SEQUENCER_353 0x3161
+#define WM8994_WRITE_SEQUENCER_354 0x3162
+#define WM8994_WRITE_SEQUENCER_355 0x3163
+#define WM8994_WRITE_SEQUENCER_356 0x3164
+#define WM8994_WRITE_SEQUENCER_357 0x3165
+#define WM8994_WRITE_SEQUENCER_358 0x3166
+#define WM8994_WRITE_SEQUENCER_359 0x3167
+#define WM8994_WRITE_SEQUENCER_360 0x3168
+#define WM8994_WRITE_SEQUENCER_361 0x3169
+#define WM8994_WRITE_SEQUENCER_362 0x316A
+#define WM8994_WRITE_SEQUENCER_363 0x316B
+#define WM8994_WRITE_SEQUENCER_364 0x316C
+#define WM8994_WRITE_SEQUENCER_365 0x316D
+#define WM8994_WRITE_SEQUENCER_366 0x316E
+#define WM8994_WRITE_SEQUENCER_367 0x316F
+#define WM8994_WRITE_SEQUENCER_368 0x3170
+#define WM8994_WRITE_SEQUENCER_369 0x3171
+#define WM8994_WRITE_SEQUENCER_370 0x3172
+#define WM8994_WRITE_SEQUENCER_371 0x3173
+#define WM8994_WRITE_SEQUENCER_372 0x3174
+#define WM8994_WRITE_SEQUENCER_373 0x3175
+#define WM8994_WRITE_SEQUENCER_374 0x3176
+#define WM8994_WRITE_SEQUENCER_375 0x3177
+#define WM8994_WRITE_SEQUENCER_376 0x3178
+#define WM8994_WRITE_SEQUENCER_377 0x3179
+#define WM8994_WRITE_SEQUENCER_378 0x317A
+#define WM8994_WRITE_SEQUENCER_379 0x317B
+#define WM8994_WRITE_SEQUENCER_380 0x317C
+#define WM8994_WRITE_SEQUENCER_381 0x317D
+#define WM8994_WRITE_SEQUENCER_382 0x317E
+#define WM8994_WRITE_SEQUENCER_383 0x317F
+#define WM8994_WRITE_SEQUENCER_384 0x3180
+#define WM8994_WRITE_SEQUENCER_385 0x3181
+#define WM8994_WRITE_SEQUENCER_386 0x3182
+#define WM8994_WRITE_SEQUENCER_387 0x3183
+#define WM8994_WRITE_SEQUENCER_388 0x3184
+#define WM8994_WRITE_SEQUENCER_389 0x3185
+#define WM8994_WRITE_SEQUENCER_390 0x3186
+#define WM8994_WRITE_SEQUENCER_391 0x3187
+#define WM8994_WRITE_SEQUENCER_392 0x3188
+#define WM8994_WRITE_SEQUENCER_393 0x3189
+#define WM8994_WRITE_SEQUENCER_394 0x318A
+#define WM8994_WRITE_SEQUENCER_395 0x318B
+#define WM8994_WRITE_SEQUENCER_396 0x318C
+#define WM8994_WRITE_SEQUENCER_397 0x318D
+#define WM8994_WRITE_SEQUENCER_398 0x318E
+#define WM8994_WRITE_SEQUENCER_399 0x318F
+#define WM8994_WRITE_SEQUENCER_400 0x3190
+#define WM8994_WRITE_SEQUENCER_401 0x3191
+#define WM8994_WRITE_SEQUENCER_402 0x3192
+#define WM8994_WRITE_SEQUENCER_403 0x3193
+#define WM8994_WRITE_SEQUENCER_404 0x3194
+#define WM8994_WRITE_SEQUENCER_405 0x3195
+#define WM8994_WRITE_SEQUENCER_406 0x3196
+#define WM8994_WRITE_SEQUENCER_407 0x3197
+#define WM8994_WRITE_SEQUENCER_408 0x3198
+#define WM8994_WRITE_SEQUENCER_409 0x3199
+#define WM8994_WRITE_SEQUENCER_410 0x319A
+#define WM8994_WRITE_SEQUENCER_411 0x319B
+#define WM8994_WRITE_SEQUENCER_412 0x319C
+#define WM8994_WRITE_SEQUENCER_413 0x319D
+#define WM8994_WRITE_SEQUENCER_414 0x319E
+#define WM8994_WRITE_SEQUENCER_415 0x319F
+#define WM8994_WRITE_SEQUENCER_416 0x31A0
+#define WM8994_WRITE_SEQUENCER_417 0x31A1
+#define WM8994_WRITE_SEQUENCER_418 0x31A2
+#define WM8994_WRITE_SEQUENCER_419 0x31A3
+#define WM8994_WRITE_SEQUENCER_420 0x31A4
+#define WM8994_WRITE_SEQUENCER_421 0x31A5
+#define WM8994_WRITE_SEQUENCER_422 0x31A6
+#define WM8994_WRITE_SEQUENCER_423 0x31A7
+#define WM8994_WRITE_SEQUENCER_424 0x31A8
+#define WM8994_WRITE_SEQUENCER_425 0x31A9
+#define WM8994_WRITE_SEQUENCER_426 0x31AA
+#define WM8994_WRITE_SEQUENCER_427 0x31AB
+#define WM8994_WRITE_SEQUENCER_428 0x31AC
+#define WM8994_WRITE_SEQUENCER_429 0x31AD
+#define WM8994_WRITE_SEQUENCER_430 0x31AE
+#define WM8994_WRITE_SEQUENCER_431 0x31AF
+#define WM8994_WRITE_SEQUENCER_432 0x31B0
+#define WM8994_WRITE_SEQUENCER_433 0x31B1
+#define WM8994_WRITE_SEQUENCER_434 0x31B2
+#define WM8994_WRITE_SEQUENCER_435 0x31B3
+#define WM8994_WRITE_SEQUENCER_436 0x31B4
+#define WM8994_WRITE_SEQUENCER_437 0x31B5
+#define WM8994_WRITE_SEQUENCER_438 0x31B6
+#define WM8994_WRITE_SEQUENCER_439 0x31B7
+#define WM8994_WRITE_SEQUENCER_440 0x31B8
+#define WM8994_WRITE_SEQUENCER_441 0x31B9
+#define WM8994_WRITE_SEQUENCER_442 0x31BA
+#define WM8994_WRITE_SEQUENCER_443 0x31BB
+#define WM8994_WRITE_SEQUENCER_444 0x31BC
+#define WM8994_WRITE_SEQUENCER_445 0x31BD
+#define WM8994_WRITE_SEQUENCER_446 0x31BE
+#define WM8994_WRITE_SEQUENCER_447 0x31BF
+#define WM8994_WRITE_SEQUENCER_448 0x31C0
+#define WM8994_WRITE_SEQUENCER_449 0x31C1
+#define WM8994_WRITE_SEQUENCER_450 0x31C2
+#define WM8994_WRITE_SEQUENCER_451 0x31C3
+#define WM8994_WRITE_SEQUENCER_452 0x31C4
+#define WM8994_WRITE_SEQUENCER_453 0x31C5
+#define WM8994_WRITE_SEQUENCER_454 0x31C6
+#define WM8994_WRITE_SEQUENCER_455 0x31C7
+#define WM8994_WRITE_SEQUENCER_456 0x31C8
+#define WM8994_WRITE_SEQUENCER_457 0x31C9
+#define WM8994_WRITE_SEQUENCER_458 0x31CA
+#define WM8994_WRITE_SEQUENCER_459 0x31CB
+#define WM8994_WRITE_SEQUENCER_460 0x31CC
+#define WM8994_WRITE_SEQUENCER_461 0x31CD
+#define WM8994_WRITE_SEQUENCER_462 0x31CE
+#define WM8994_WRITE_SEQUENCER_463 0x31CF
+#define WM8994_WRITE_SEQUENCER_464 0x31D0
+#define WM8994_WRITE_SEQUENCER_465 0x31D1
+#define WM8994_WRITE_SEQUENCER_466 0x31D2
+#define WM8994_WRITE_SEQUENCER_467 0x31D3
+#define WM8994_WRITE_SEQUENCER_468 0x31D4
+#define WM8994_WRITE_SEQUENCER_469 0x31D5
+#define WM8994_WRITE_SEQUENCER_470 0x31D6
+#define WM8994_WRITE_SEQUENCER_471 0x31D7
+#define WM8994_WRITE_SEQUENCER_472 0x31D8
+#define WM8994_WRITE_SEQUENCER_473 0x31D9
+#define WM8994_WRITE_SEQUENCER_474 0x31DA
+#define WM8994_WRITE_SEQUENCER_475 0x31DB
+#define WM8994_WRITE_SEQUENCER_476 0x31DC
+#define WM8994_WRITE_SEQUENCER_477 0x31DD
+#define WM8994_WRITE_SEQUENCER_478 0x31DE
+#define WM8994_WRITE_SEQUENCER_479 0x31DF
+#define WM8994_WRITE_SEQUENCER_480 0x31E0
+#define WM8994_WRITE_SEQUENCER_481 0x31E1
+#define WM8994_WRITE_SEQUENCER_482 0x31E2
+#define WM8994_WRITE_SEQUENCER_483 0x31E3
+#define WM8994_WRITE_SEQUENCER_484 0x31E4
+#define WM8994_WRITE_SEQUENCER_485 0x31E5
+#define WM8994_WRITE_SEQUENCER_486 0x31E6
+#define WM8994_WRITE_SEQUENCER_487 0x31E7
+#define WM8994_WRITE_SEQUENCER_488 0x31E8
+#define WM8994_WRITE_SEQUENCER_489 0x31E9
+#define WM8994_WRITE_SEQUENCER_490 0x31EA
+#define WM8994_WRITE_SEQUENCER_491 0x31EB
+#define WM8994_WRITE_SEQUENCER_492 0x31EC
+#define WM8994_WRITE_SEQUENCER_493 0x31ED
+#define WM8994_WRITE_SEQUENCER_494 0x31EE
+#define WM8994_WRITE_SEQUENCER_495 0x31EF
+#define WM8994_WRITE_SEQUENCER_496 0x31F0
+#define WM8994_WRITE_SEQUENCER_497 0x31F1
+#define WM8994_WRITE_SEQUENCER_498 0x31F2
+#define WM8994_WRITE_SEQUENCER_499 0x31F3
+#define WM8994_WRITE_SEQUENCER_500 0x31F4
+#define WM8994_WRITE_SEQUENCER_501 0x31F5
+#define WM8994_WRITE_SEQUENCER_502 0x31F6
+#define WM8994_WRITE_SEQUENCER_503 0x31F7
+#define WM8994_WRITE_SEQUENCER_504 0x31F8
+#define WM8994_WRITE_SEQUENCER_505 0x31F9
+#define WM8994_WRITE_SEQUENCER_506 0x31FA
+#define WM8994_WRITE_SEQUENCER_507 0x31FB
+#define WM8994_WRITE_SEQUENCER_508 0x31FC
+#define WM8994_WRITE_SEQUENCER_509 0x31FD
+#define WM8994_WRITE_SEQUENCER_510 0x31FE
+#define WM8994_WRITE_SEQUENCER_511 0x31FF
+
+#define WM8994_REGISTER_COUNT 736
+#define WM8994_MAX_REGISTER 0x31FF
+#define WM8994_MAX_CACHED_REGISTER 0x749
+
+/*
+ * Field Definitions.
+ */
+
+/*
+ * R0 (0x00) - Software Reset
+ */
+#define WM8994_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
+#define WM8994_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
+#define WM8994_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
+
+/*
+ * R1 (0x01) - Power Management (1)
+ */
+#define WM8994_SPKOUTR_ENA 0x2000 /* SPKOUTR_ENA */
+#define WM8994_SPKOUTR_ENA_MASK 0x2000 /* SPKOUTR_ENA */
+#define WM8994_SPKOUTR_ENA_SHIFT 13 /* SPKOUTR_ENA */
+#define WM8994_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */
+#define WM8994_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
+#define WM8994_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
+#define WM8994_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
+#define WM8994_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
+#define WM8994_HPOUT2_ENA 0x0800 /* HPOUT2_ENA */
+#define WM8994_HPOUT2_ENA_MASK 0x0800 /* HPOUT2_ENA */
+#define WM8994_HPOUT2_ENA_SHIFT 11 /* HPOUT2_ENA */
+#define WM8994_HPOUT2_ENA_WIDTH 1 /* HPOUT2_ENA */
+#define WM8994_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
+#define WM8994_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
+#define WM8994_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
+#define WM8994_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
+#define WM8994_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
+#define WM8994_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
+#define WM8994_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
+#define WM8994_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
+#define WM8994_MICB2_ENA 0x0020 /* MICB2_ENA */
+#define WM8994_MICB2_ENA_MASK 0x0020 /* MICB2_ENA */
+#define WM8994_MICB2_ENA_SHIFT 5 /* MICB2_ENA */
+#define WM8994_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
+#define WM8994_MICB1_ENA 0x0010 /* MICB1_ENA */
+#define WM8994_MICB1_ENA_MASK 0x0010 /* MICB1_ENA */
+#define WM8994_MICB1_ENA_SHIFT 4 /* MICB1_ENA */
+#define WM8994_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
+#define WM8994_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */
+#define WM8994_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */
+#define WM8994_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */
+#define WM8994_BIAS_ENA 0x0001 /* BIAS_ENA */
+#define WM8994_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
+#define WM8994_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
+#define WM8994_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
+
+/*
+ * R2 (0x02) - Power Management (2)
+ */
+#define WM8994_TSHUT_ENA 0x4000 /* TSHUT_ENA */
+#define WM8994_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
+#define WM8994_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
+#define WM8994_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
+#define WM8994_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
+#define WM8994_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
+#define WM8994_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
+#define WM8994_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
+#define WM8994_OPCLK_ENA 0x0800 /* OPCLK_ENA */
+#define WM8994_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
+#define WM8994_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
+#define WM8994_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
+#define WM8994_MIXINL_ENA 0x0200 /* MIXINL_ENA */
+#define WM8994_MIXINL_ENA_MASK 0x0200 /* MIXINL_ENA */
+#define WM8994_MIXINL_ENA_SHIFT 9 /* MIXINL_ENA */
+#define WM8994_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */
+#define WM8994_MIXINR_ENA 0x0100 /* MIXINR_ENA */
+#define WM8994_MIXINR_ENA_MASK 0x0100 /* MIXINR_ENA */
+#define WM8994_MIXINR_ENA_SHIFT 8 /* MIXINR_ENA */
+#define WM8994_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */
+#define WM8994_IN2L_ENA 0x0080 /* IN2L_ENA */
+#define WM8994_IN2L_ENA_MASK 0x0080 /* IN2L_ENA */
+#define WM8994_IN2L_ENA_SHIFT 7 /* IN2L_ENA */
+#define WM8994_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
+#define WM8994_IN1L_ENA 0x0040 /* IN1L_ENA */
+#define WM8994_IN1L_ENA_MASK 0x0040 /* IN1L_ENA */
+#define WM8994_IN1L_ENA_SHIFT 6 /* IN1L_ENA */
+#define WM8994_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
+#define WM8994_IN2R_ENA 0x0020 /* IN2R_ENA */
+#define WM8994_IN2R_ENA_MASK 0x0020 /* IN2R_ENA */
+#define WM8994_IN2R_ENA_SHIFT 5 /* IN2R_ENA */
+#define WM8994_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
+#define WM8994_IN1R_ENA 0x0010 /* IN1R_ENA */
+#define WM8994_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
+#define WM8994_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
+#define WM8994_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
+
+/*
+ * R3 (0x03) - Power Management (3)
+ */
+#define WM8994_LINEOUT1N_ENA 0x2000 /* LINEOUT1N_ENA */
+#define WM8994_LINEOUT1N_ENA_MASK 0x2000 /* LINEOUT1N_ENA */
+#define WM8994_LINEOUT1N_ENA_SHIFT 13 /* LINEOUT1N_ENA */
+#define WM8994_LINEOUT1N_ENA_WIDTH 1 /* LINEOUT1N_ENA */
+#define WM8994_LINEOUT1P_ENA 0x1000 /* LINEOUT1P_ENA */
+#define WM8994_LINEOUT1P_ENA_MASK 0x1000 /* LINEOUT1P_ENA */
+#define WM8994_LINEOUT1P_ENA_SHIFT 12 /* LINEOUT1P_ENA */
+#define WM8994_LINEOUT1P_ENA_WIDTH 1 /* LINEOUT1P_ENA */
+#define WM8994_LINEOUT2N_ENA 0x0800 /* LINEOUT2N_ENA */
+#define WM8994_LINEOUT2N_ENA_MASK 0x0800 /* LINEOUT2N_ENA */
+#define WM8994_LINEOUT2N_ENA_SHIFT 11 /* LINEOUT2N_ENA */
+#define WM8994_LINEOUT2N_ENA_WIDTH 1 /* LINEOUT2N_ENA */
+#define WM8994_LINEOUT2P_ENA 0x0400 /* LINEOUT2P_ENA */
+#define WM8994_LINEOUT2P_ENA_MASK 0x0400 /* LINEOUT2P_ENA */
+#define WM8994_LINEOUT2P_ENA_SHIFT 10 /* LINEOUT2P_ENA */
+#define WM8994_LINEOUT2P_ENA_WIDTH 1 /* LINEOUT2P_ENA */
+#define WM8994_SPKRVOL_ENA 0x0200 /* SPKRVOL_ENA */
+#define WM8994_SPKRVOL_ENA_MASK 0x0200 /* SPKRVOL_ENA */
+#define WM8994_SPKRVOL_ENA_SHIFT 9 /* SPKRVOL_ENA */
+#define WM8994_SPKRVOL_ENA_WIDTH 1 /* SPKRVOL_ENA */
+#define WM8994_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
+#define WM8994_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
+#define WM8994_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
+#define WM8994_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
+#define WM8994_MIXOUTLVOL_ENA 0x0080 /* MIXOUTLVOL_ENA */
+#define WM8994_MIXOUTLVOL_ENA_MASK 0x0080 /* MIXOUTLVOL_ENA */
+#define WM8994_MIXOUTLVOL_ENA_SHIFT 7 /* MIXOUTLVOL_ENA */
+#define WM8994_MIXOUTLVOL_ENA_WIDTH 1 /* MIXOUTLVOL_ENA */
+#define WM8994_MIXOUTRVOL_ENA 0x0040 /* MIXOUTRVOL_ENA */
+#define WM8994_MIXOUTRVOL_ENA_MASK 0x0040 /* MIXOUTRVOL_ENA */
+#define WM8994_MIXOUTRVOL_ENA_SHIFT 6 /* MIXOUTRVOL_ENA */
+#define WM8994_MIXOUTRVOL_ENA_WIDTH 1 /* MIXOUTRVOL_ENA */
+#define WM8994_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
+#define WM8994_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
+#define WM8994_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
+#define WM8994_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
+#define WM8994_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
+#define WM8994_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
+#define WM8994_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
+#define WM8994_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
+
+/*
+ * R4 (0x04) - Power Management (4)
+ */
+#define WM8994_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */
+#define WM8994_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */
+#define WM8994_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */
+#define WM8994_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */
+#define WM8994_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */
+#define WM8994_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */
+#define WM8994_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */
+#define WM8994_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */
+#define WM8994_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */
+#define WM8994_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */
+#define WM8994_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */
+#define WM8994_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */
+#define WM8994_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */
+#define WM8994_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */
+#define WM8994_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */
+#define WM8994_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */
+#define WM8994_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */
+#define WM8994_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */
+#define WM8994_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */
+#define WM8994_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */
+#define WM8994_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */
+#define WM8994_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */
+#define WM8994_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */
+#define WM8994_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */
+#define WM8994_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
+#define WM8994_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
+#define WM8994_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
+#define WM8994_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
+#define WM8994_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
+#define WM8994_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
+#define WM8994_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
+#define WM8994_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
+#define WM8994_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
+#define WM8994_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
+#define WM8994_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
+#define WM8994_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
+#define WM8994_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
+#define WM8994_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
+#define WM8994_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
+#define WM8994_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
+#define WM8994_ADCL_ENA 0x0002 /* ADCL_ENA */
+#define WM8994_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
+#define WM8994_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
+#define WM8994_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
+#define WM8994_ADCR_ENA 0x0001 /* ADCR_ENA */
+#define WM8994_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
+#define WM8994_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
+#define WM8994_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
+
+/*
+ * R5 (0x05) - Power Management (5)
+ */
+#define WM8994_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */
+#define WM8994_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */
+#define WM8994_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */
+#define WM8994_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */
+#define WM8994_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */
+#define WM8994_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */
+#define WM8994_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */
+#define WM8994_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */
+#define WM8994_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */
+#define WM8994_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */
+#define WM8994_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */
+#define WM8994_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */
+#define WM8994_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */
+#define WM8994_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */
+#define WM8994_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */
+#define WM8994_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */
+#define WM8994_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */
+#define WM8994_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */
+#define WM8994_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */
+#define WM8994_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */
+#define WM8994_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */
+#define WM8994_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */
+#define WM8994_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */
+#define WM8994_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */
+#define WM8994_DAC2L_ENA 0x0008 /* DAC2L_ENA */
+#define WM8994_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
+#define WM8994_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
+#define WM8994_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
+#define WM8994_DAC2R_ENA 0x0004 /* DAC2R_ENA */
+#define WM8994_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
+#define WM8994_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
+#define WM8994_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
+#define WM8994_DAC1L_ENA 0x0002 /* DAC1L_ENA */
+#define WM8994_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
+#define WM8994_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
+#define WM8994_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
+#define WM8994_DAC1R_ENA 0x0001 /* DAC1R_ENA */
+#define WM8994_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
+#define WM8994_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
+#define WM8994_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
+
+/*
+ * R6 (0x06) - Power Management (6)
+ */
+#define WM8994_AIF3_TRI 0x0020 /* AIF3_TRI */
+#define WM8994_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
+#define WM8994_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
+#define WM8994_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
+#define WM8994_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8994_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8994_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */
+#define WM8994_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */
+#define WM8994_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */
+#define WM8994_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */
+#define WM8994_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */
+#define WM8994_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */
+#define WM8994_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */
+#define WM8994_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */
+#define WM8994_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */
+#define WM8994_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */
+#define WM8994_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */
+#define WM8994_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */
+#define WM8994_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */
+
+/*
+ * R21 (0x15) - Input Mixer (1)
+ */
+#define WM8994_IN1RP_MIXINR_BOOST 0x0100 /* IN1RP_MIXINR_BOOST */
+#define WM8994_IN1RP_MIXINR_BOOST_MASK 0x0100 /* IN1RP_MIXINR_BOOST */
+#define WM8994_IN1RP_MIXINR_BOOST_SHIFT 8 /* IN1RP_MIXINR_BOOST */
+#define WM8994_IN1RP_MIXINR_BOOST_WIDTH 1 /* IN1RP_MIXINR_BOOST */
+#define WM8994_IN1LP_MIXINL_BOOST 0x0080 /* IN1LP_MIXINL_BOOST */
+#define WM8994_IN1LP_MIXINL_BOOST_MASK 0x0080 /* IN1LP_MIXINL_BOOST */
+#define WM8994_IN1LP_MIXINL_BOOST_SHIFT 7 /* IN1LP_MIXINL_BOOST */
+#define WM8994_IN1LP_MIXINL_BOOST_WIDTH 1 /* IN1LP_MIXINL_BOOST */
+#define WM8994_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */
+#define WM8994_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */
+#define WM8994_INPUTS_CLAMP_SHIFT 6 /* INPUTS_CLAMP */
+#define WM8994_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */
+
+/*
+ * R24 (0x18) - Left Line Input 1&2 Volume
+ */
+#define WM8994_IN1_VU 0x0100 /* IN1_VU */
+#define WM8994_IN1_VU_MASK 0x0100 /* IN1_VU */
+#define WM8994_IN1_VU_SHIFT 8 /* IN1_VU */
+#define WM8994_IN1_VU_WIDTH 1 /* IN1_VU */
+#define WM8994_IN1L_MUTE 0x0080 /* IN1L_MUTE */
+#define WM8994_IN1L_MUTE_MASK 0x0080 /* IN1L_MUTE */
+#define WM8994_IN1L_MUTE_SHIFT 7 /* IN1L_MUTE */
+#define WM8994_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
+#define WM8994_IN1L_ZC 0x0040 /* IN1L_ZC */
+#define WM8994_IN1L_ZC_MASK 0x0040 /* IN1L_ZC */
+#define WM8994_IN1L_ZC_SHIFT 6 /* IN1L_ZC */
+#define WM8994_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
+#define WM8994_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
+#define WM8994_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
+#define WM8994_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
+
+/*
+ * R25 (0x19) - Left Line Input 3&4 Volume
+ */
+#define WM8994_IN2_VU 0x0100 /* IN2_VU */
+#define WM8994_IN2_VU_MASK 0x0100 /* IN2_VU */
+#define WM8994_IN2_VU_SHIFT 8 /* IN2_VU */
+#define WM8994_IN2_VU_WIDTH 1 /* IN2_VU */
+#define WM8994_IN2L_MUTE 0x0080 /* IN2L_MUTE */
+#define WM8994_IN2L_MUTE_MASK 0x0080 /* IN2L_MUTE */
+#define WM8994_IN2L_MUTE_SHIFT 7 /* IN2L_MUTE */
+#define WM8994_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
+#define WM8994_IN2L_ZC 0x0040 /* IN2L_ZC */
+#define WM8994_IN2L_ZC_MASK 0x0040 /* IN2L_ZC */
+#define WM8994_IN2L_ZC_SHIFT 6 /* IN2L_ZC */
+#define WM8994_IN2L_ZC_WIDTH 1 /* IN2L_ZC */
+#define WM8994_IN2L_VOL_MASK 0x001F /* IN2L_VOL - [4:0] */
+#define WM8994_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [4:0] */
+#define WM8994_IN2L_VOL_WIDTH 5 /* IN2L_VOL - [4:0] */
+
+/*
+ * R26 (0x1A) - Right Line Input 1&2 Volume
+ */
+#define WM8994_IN1_VU 0x0100 /* IN1_VU */
+#define WM8994_IN1_VU_MASK 0x0100 /* IN1_VU */
+#define WM8994_IN1_VU_SHIFT 8 /* IN1_VU */
+#define WM8994_IN1_VU_WIDTH 1 /* IN1_VU */
+#define WM8994_IN1R_MUTE 0x0080 /* IN1R_MUTE */
+#define WM8994_IN1R_MUTE_MASK 0x0080 /* IN1R_MUTE */
+#define WM8994_IN1R_MUTE_SHIFT 7 /* IN1R_MUTE */
+#define WM8994_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
+#define WM8994_IN1R_ZC 0x0040 /* IN1R_ZC */
+#define WM8994_IN1R_ZC_MASK 0x0040 /* IN1R_ZC */
+#define WM8994_IN1R_ZC_SHIFT 6 /* IN1R_ZC */
+#define WM8994_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
+#define WM8994_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
+#define WM8994_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
+#define WM8994_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
+
+/*
+ * R27 (0x1B) - Right Line Input 3&4 Volume
+ */
+#define WM8994_IN2_VU 0x0100 /* IN2_VU */
+#define WM8994_IN2_VU_MASK 0x0100 /* IN2_VU */
+#define WM8994_IN2_VU_SHIFT 8 /* IN2_VU */
+#define WM8994_IN2_VU_WIDTH 1 /* IN2_VU */
+#define WM8994_IN2R_MUTE 0x0080 /* IN2R_MUTE */
+#define WM8994_IN2R_MUTE_MASK 0x0080 /* IN2R_MUTE */
+#define WM8994_IN2R_MUTE_SHIFT 7 /* IN2R_MUTE */
+#define WM8994_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
+#define WM8994_IN2R_ZC 0x0040 /* IN2R_ZC */
+#define WM8994_IN2R_ZC_MASK 0x0040 /* IN2R_ZC */
+#define WM8994_IN2R_ZC_SHIFT 6 /* IN2R_ZC */
+#define WM8994_IN2R_ZC_WIDTH 1 /* IN2R_ZC */
+#define WM8994_IN2R_VOL_MASK 0x001F /* IN2R_VOL - [4:0] */
+#define WM8994_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [4:0] */
+#define WM8994_IN2R_VOL_WIDTH 5 /* IN2R_VOL - [4:0] */
+
+/*
+ * R28 (0x1C) - Left Output Volume
+ */
+#define WM8994_HPOUT1_VU 0x0100 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
+#define WM8994_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
+#define WM8994_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
+#define WM8994_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
+#define WM8994_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
+#define WM8994_HPOUT1L_MUTE_N 0x0040 /* HPOUT1L_MUTE_N */
+#define WM8994_HPOUT1L_MUTE_N_MASK 0x0040 /* HPOUT1L_MUTE_N */
+#define WM8994_HPOUT1L_MUTE_N_SHIFT 6 /* HPOUT1L_MUTE_N */
+#define WM8994_HPOUT1L_MUTE_N_WIDTH 1 /* HPOUT1L_MUTE_N */
+#define WM8994_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
+#define WM8994_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
+#define WM8994_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
+
+/*
+ * R29 (0x1D) - Right Output Volume
+ */
+#define WM8994_HPOUT1_VU 0x0100 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
+#define WM8994_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
+#define WM8994_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
+#define WM8994_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
+#define WM8994_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
+#define WM8994_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
+#define WM8994_HPOUT1R_MUTE_N 0x0040 /* HPOUT1R_MUTE_N */
+#define WM8994_HPOUT1R_MUTE_N_MASK 0x0040 /* HPOUT1R_MUTE_N */
+#define WM8994_HPOUT1R_MUTE_N_SHIFT 6 /* HPOUT1R_MUTE_N */
+#define WM8994_HPOUT1R_MUTE_N_WIDTH 1 /* HPOUT1R_MUTE_N */
+#define WM8994_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
+#define WM8994_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
+#define WM8994_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
+
+/*
+ * R30 (0x1E) - Line Outputs Volume
+ */
+#define WM8994_LINEOUT1N_MUTE 0x0040 /* LINEOUT1N_MUTE */
+#define WM8994_LINEOUT1N_MUTE_MASK 0x0040 /* LINEOUT1N_MUTE */
+#define WM8994_LINEOUT1N_MUTE_SHIFT 6 /* LINEOUT1N_MUTE */
+#define WM8994_LINEOUT1N_MUTE_WIDTH 1 /* LINEOUT1N_MUTE */
+#define WM8994_LINEOUT1P_MUTE 0x0020 /* LINEOUT1P_MUTE */
+#define WM8994_LINEOUT1P_MUTE_MASK 0x0020 /* LINEOUT1P_MUTE */
+#define WM8994_LINEOUT1P_MUTE_SHIFT 5 /* LINEOUT1P_MUTE */
+#define WM8994_LINEOUT1P_MUTE_WIDTH 1 /* LINEOUT1P_MUTE */
+#define WM8994_LINEOUT1_VOL 0x0010 /* LINEOUT1_VOL */
+#define WM8994_LINEOUT1_VOL_MASK 0x0010 /* LINEOUT1_VOL */
+#define WM8994_LINEOUT1_VOL_SHIFT 4 /* LINEOUT1_VOL */
+#define WM8994_LINEOUT1_VOL_WIDTH 1 /* LINEOUT1_VOL */
+#define WM8994_LINEOUT2N_MUTE 0x0004 /* LINEOUT2N_MUTE */
+#define WM8994_LINEOUT2N_MUTE_MASK 0x0004 /* LINEOUT2N_MUTE */
+#define WM8994_LINEOUT2N_MUTE_SHIFT 2 /* LINEOUT2N_MUTE */
+#define WM8994_LINEOUT2N_MUTE_WIDTH 1 /* LINEOUT2N_MUTE */
+#define WM8994_LINEOUT2P_MUTE 0x0002 /* LINEOUT2P_MUTE */
+#define WM8994_LINEOUT2P_MUTE_MASK 0x0002 /* LINEOUT2P_MUTE */
+#define WM8994_LINEOUT2P_MUTE_SHIFT 1 /* LINEOUT2P_MUTE */
+#define WM8994_LINEOUT2P_MUTE_WIDTH 1 /* LINEOUT2P_MUTE */
+#define WM8994_LINEOUT2_VOL 0x0001 /* LINEOUT2_VOL */
+#define WM8994_LINEOUT2_VOL_MASK 0x0001 /* LINEOUT2_VOL */
+#define WM8994_LINEOUT2_VOL_SHIFT 0 /* LINEOUT2_VOL */
+#define WM8994_LINEOUT2_VOL_WIDTH 1 /* LINEOUT2_VOL */
+
+/*
+ * R31 (0x1F) - HPOUT2 Volume
+ */
+#define WM8994_HPOUT2_MUTE 0x0020 /* HPOUT2_MUTE */
+#define WM8994_HPOUT2_MUTE_MASK 0x0020 /* HPOUT2_MUTE */
+#define WM8994_HPOUT2_MUTE_SHIFT 5 /* HPOUT2_MUTE */
+#define WM8994_HPOUT2_MUTE_WIDTH 1 /* HPOUT2_MUTE */
+#define WM8994_HPOUT2_VOL 0x0010 /* HPOUT2_VOL */
+#define WM8994_HPOUT2_VOL_MASK 0x0010 /* HPOUT2_VOL */
+#define WM8994_HPOUT2_VOL_SHIFT 4 /* HPOUT2_VOL */
+#define WM8994_HPOUT2_VOL_WIDTH 1 /* HPOUT2_VOL */
+
+/*
+ * R32 (0x20) - Left OPGA Volume
+ */
+#define WM8994_MIXOUT_VU 0x0100 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
+#define WM8994_MIXOUTL_ZC 0x0080 /* MIXOUTL_ZC */
+#define WM8994_MIXOUTL_ZC_MASK 0x0080 /* MIXOUTL_ZC */
+#define WM8994_MIXOUTL_ZC_SHIFT 7 /* MIXOUTL_ZC */
+#define WM8994_MIXOUTL_ZC_WIDTH 1 /* MIXOUTL_ZC */
+#define WM8994_MIXOUTL_MUTE_N 0x0040 /* MIXOUTL_MUTE_N */
+#define WM8994_MIXOUTL_MUTE_N_MASK 0x0040 /* MIXOUTL_MUTE_N */
+#define WM8994_MIXOUTL_MUTE_N_SHIFT 6 /* MIXOUTL_MUTE_N */
+#define WM8994_MIXOUTL_MUTE_N_WIDTH 1 /* MIXOUTL_MUTE_N */
+#define WM8994_MIXOUTL_VOL_MASK 0x003F /* MIXOUTL_VOL - [5:0] */
+#define WM8994_MIXOUTL_VOL_SHIFT 0 /* MIXOUTL_VOL - [5:0] */
+#define WM8994_MIXOUTL_VOL_WIDTH 6 /* MIXOUTL_VOL - [5:0] */
+
+/*
+ * R33 (0x21) - Right OPGA Volume
+ */
+#define WM8994_MIXOUT_VU 0x0100 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
+#define WM8994_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
+#define WM8994_MIXOUTR_ZC 0x0080 /* MIXOUTR_ZC */
+#define WM8994_MIXOUTR_ZC_MASK 0x0080 /* MIXOUTR_ZC */
+#define WM8994_MIXOUTR_ZC_SHIFT 7 /* MIXOUTR_ZC */
+#define WM8994_MIXOUTR_ZC_WIDTH 1 /* MIXOUTR_ZC */
+#define WM8994_MIXOUTR_MUTE_N 0x0040 /* MIXOUTR_MUTE_N */
+#define WM8994_MIXOUTR_MUTE_N_MASK 0x0040 /* MIXOUTR_MUTE_N */
+#define WM8994_MIXOUTR_MUTE_N_SHIFT 6 /* MIXOUTR_MUTE_N */
+#define WM8994_MIXOUTR_MUTE_N_WIDTH 1 /* MIXOUTR_MUTE_N */
+#define WM8994_MIXOUTR_VOL_MASK 0x003F /* MIXOUTR_VOL - [5:0] */
+#define WM8994_MIXOUTR_VOL_SHIFT 0 /* MIXOUTR_VOL - [5:0] */
+#define WM8994_MIXOUTR_VOL_WIDTH 6 /* MIXOUTR_VOL - [5:0] */
+
+/*
+ * R34 (0x22) - SPKMIXL Attenuation
+ */
+#define WM8994_DAC2L_SPKMIXL_VOL 0x0040 /* DAC2L_SPKMIXL_VOL */
+#define WM8994_DAC2L_SPKMIXL_VOL_MASK 0x0040 /* DAC2L_SPKMIXL_VOL */
+#define WM8994_DAC2L_SPKMIXL_VOL_SHIFT 6 /* DAC2L_SPKMIXL_VOL */
+#define WM8994_DAC2L_SPKMIXL_VOL_WIDTH 1 /* DAC2L_SPKMIXL_VOL */
+#define WM8994_MIXINL_SPKMIXL_VOL 0x0020 /* MIXINL_SPKMIXL_VOL */
+#define WM8994_MIXINL_SPKMIXL_VOL_MASK 0x0020 /* MIXINL_SPKMIXL_VOL */
+#define WM8994_MIXINL_SPKMIXL_VOL_SHIFT 5 /* MIXINL_SPKMIXL_VOL */
+#define WM8994_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */
+#define WM8994_IN1LP_SPKMIXL_VOL 0x0010 /* IN1LP_SPKMIXL_VOL */
+#define WM8994_IN1LP_SPKMIXL_VOL_MASK 0x0010 /* IN1LP_SPKMIXL_VOL */
+#define WM8994_IN1LP_SPKMIXL_VOL_SHIFT 4 /* IN1LP_SPKMIXL_VOL */
+#define WM8994_IN1LP_SPKMIXL_VOL_WIDTH 1 /* IN1LP_SPKMIXL_VOL */
+#define WM8994_MIXOUTL_SPKMIXL_VOL 0x0008 /* MIXOUTL_SPKMIXL_VOL */
+#define WM8994_MIXOUTL_SPKMIXL_VOL_MASK 0x0008 /* MIXOUTL_SPKMIXL_VOL */
+#define WM8994_MIXOUTL_SPKMIXL_VOL_SHIFT 3 /* MIXOUTL_SPKMIXL_VOL */
+#define WM8994_MIXOUTL_SPKMIXL_VOL_WIDTH 1 /* MIXOUTL_SPKMIXL_VOL */
+#define WM8994_DAC1L_SPKMIXL_VOL 0x0004 /* DAC1L_SPKMIXL_VOL */
+#define WM8994_DAC1L_SPKMIXL_VOL_MASK 0x0004 /* DAC1L_SPKMIXL_VOL */
+#define WM8994_DAC1L_SPKMIXL_VOL_SHIFT 2 /* DAC1L_SPKMIXL_VOL */
+#define WM8994_DAC1L_SPKMIXL_VOL_WIDTH 1 /* DAC1L_SPKMIXL_VOL */
+#define WM8994_SPKMIXL_VOL_MASK 0x0003 /* SPKMIXL_VOL - [1:0] */
+#define WM8994_SPKMIXL_VOL_SHIFT 0 /* SPKMIXL_VOL - [1:0] */
+#define WM8994_SPKMIXL_VOL_WIDTH 2 /* SPKMIXL_VOL - [1:0] */
+
+/*
+ * R35 (0x23) - SPKMIXR Attenuation
+ */
+#define WM8994_SPKOUT_CLASSAB 0x0100 /* SPKOUT_CLASSAB */
+#define WM8994_SPKOUT_CLASSAB_MASK 0x0100 /* SPKOUT_CLASSAB */
+#define WM8994_SPKOUT_CLASSAB_SHIFT 8 /* SPKOUT_CLASSAB */
+#define WM8994_SPKOUT_CLASSAB_WIDTH 1 /* SPKOUT_CLASSAB */
+#define WM8994_DAC2R_SPKMIXR_VOL 0x0040 /* DAC2R_SPKMIXR_VOL */
+#define WM8994_DAC2R_SPKMIXR_VOL_MASK 0x0040 /* DAC2R_SPKMIXR_VOL */
+#define WM8994_DAC2R_SPKMIXR_VOL_SHIFT 6 /* DAC2R_SPKMIXR_VOL */
+#define WM8994_DAC2R_SPKMIXR_VOL_WIDTH 1 /* DAC2R_SPKMIXR_VOL */
+#define WM8994_MIXINR_SPKMIXR_VOL 0x0020 /* MIXINR_SPKMIXR_VOL */
+#define WM8994_MIXINR_SPKMIXR_VOL_MASK 0x0020 /* MIXINR_SPKMIXR_VOL */
+#define WM8994_MIXINR_SPKMIXR_VOL_SHIFT 5 /* MIXINR_SPKMIXR_VOL */
+#define WM8994_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */
+#define WM8994_IN1RP_SPKMIXR_VOL 0x0010 /* IN1RP_SPKMIXR_VOL */
+#define WM8994_IN1RP_SPKMIXR_VOL_MASK 0x0010 /* IN1RP_SPKMIXR_VOL */
+#define WM8994_IN1RP_SPKMIXR_VOL_SHIFT 4 /* IN1RP_SPKMIXR_VOL */
+#define WM8994_IN1RP_SPKMIXR_VOL_WIDTH 1 /* IN1RP_SPKMIXR_VOL */
+#define WM8994_MIXOUTR_SPKMIXR_VOL 0x0008 /* MIXOUTR_SPKMIXR_VOL */
+#define WM8994_MIXOUTR_SPKMIXR_VOL_MASK 0x0008 /* MIXOUTR_SPKMIXR_VOL */
+#define WM8994_MIXOUTR_SPKMIXR_VOL_SHIFT 3 /* MIXOUTR_SPKMIXR_VOL */
+#define WM8994_MIXOUTR_SPKMIXR_VOL_WIDTH 1 /* MIXOUTR_SPKMIXR_VOL */
+#define WM8994_DAC1R_SPKMIXR_VOL 0x0004 /* DAC1R_SPKMIXR_VOL */
+#define WM8994_DAC1R_SPKMIXR_VOL_MASK 0x0004 /* DAC1R_SPKMIXR_VOL */
+#define WM8994_DAC1R_SPKMIXR_VOL_SHIFT 2 /* DAC1R_SPKMIXR_VOL */
+#define WM8994_DAC1R_SPKMIXR_VOL_WIDTH 1 /* DAC1R_SPKMIXR_VOL */
+#define WM8994_SPKMIXR_VOL_MASK 0x0003 /* SPKMIXR_VOL - [1:0] */
+#define WM8994_SPKMIXR_VOL_SHIFT 0 /* SPKMIXR_VOL - [1:0] */
+#define WM8994_SPKMIXR_VOL_WIDTH 2 /* SPKMIXR_VOL - [1:0] */
+
+/*
+ * R36 (0x24) - SPKOUT Mixers
+ */
+#define WM8994_IN2LRP_TO_SPKOUTL 0x0020 /* IN2LRP_TO_SPKOUTL */
+#define WM8994_IN2LRP_TO_SPKOUTL_MASK 0x0020 /* IN2LRP_TO_SPKOUTL */
+#define WM8994_IN2LRP_TO_SPKOUTL_SHIFT 5 /* IN2LRP_TO_SPKOUTL */
+#define WM8994_IN2LRP_TO_SPKOUTL_WIDTH 1 /* IN2LRP_TO_SPKOUTL */
+#define WM8994_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
+#define WM8994_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
+#define WM8994_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
+#define WM8994_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
+#define WM8994_SPKMIXR_TO_SPKOUTL 0x0008 /* SPKMIXR_TO_SPKOUTL */
+#define WM8994_SPKMIXR_TO_SPKOUTL_MASK 0x0008 /* SPKMIXR_TO_SPKOUTL */
+#define WM8994_SPKMIXR_TO_SPKOUTL_SHIFT 3 /* SPKMIXR_TO_SPKOUTL */
+#define WM8994_SPKMIXR_TO_SPKOUTL_WIDTH 1 /* SPKMIXR_TO_SPKOUTL */
+#define WM8994_IN2LRP_TO_SPKOUTR 0x0004 /* IN2LRP_TO_SPKOUTR */
+#define WM8994_IN2LRP_TO_SPKOUTR_MASK 0x0004 /* IN2LRP_TO_SPKOUTR */
+#define WM8994_IN2LRP_TO_SPKOUTR_SHIFT 2 /* IN2LRP_TO_SPKOUTR */
+#define WM8994_IN2LRP_TO_SPKOUTR_WIDTH 1 /* IN2LRP_TO_SPKOUTR */
+#define WM8994_SPKMIXL_TO_SPKOUTR 0x0002 /* SPKMIXL_TO_SPKOUTR */
+#define WM8994_SPKMIXL_TO_SPKOUTR_MASK 0x0002 /* SPKMIXL_TO_SPKOUTR */
+#define WM8994_SPKMIXL_TO_SPKOUTR_SHIFT 1 /* SPKMIXL_TO_SPKOUTR */
+#define WM8994_SPKMIXL_TO_SPKOUTR_WIDTH 1 /* SPKMIXL_TO_SPKOUTR */
+#define WM8994_SPKMIXR_TO_SPKOUTR 0x0001 /* SPKMIXR_TO_SPKOUTR */
+#define WM8994_SPKMIXR_TO_SPKOUTR_MASK 0x0001 /* SPKMIXR_TO_SPKOUTR */
+#define WM8994_SPKMIXR_TO_SPKOUTR_SHIFT 0 /* SPKMIXR_TO_SPKOUTR */
+#define WM8994_SPKMIXR_TO_SPKOUTR_WIDTH 1 /* SPKMIXR_TO_SPKOUTR */
+
+/*
+ * R37 (0x25) - ClassD
+ */
+#define WM8994_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
+#define WM8994_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
+#define WM8994_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
+#define WM8994_SPKOUTR_BOOST_MASK 0x0007 /* SPKOUTR_BOOST - [2:0] */
+#define WM8994_SPKOUTR_BOOST_SHIFT 0 /* SPKOUTR_BOOST - [2:0] */
+#define WM8994_SPKOUTR_BOOST_WIDTH 3 /* SPKOUTR_BOOST - [2:0] */
+
+/*
+ * R38 (0x26) - Speaker Volume Left
+ */
+#define WM8994_SPKOUT_VU 0x0100 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
+#define WM8994_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
+#define WM8994_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
+#define WM8994_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
+#define WM8994_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
+#define WM8994_SPKOUTL_MUTE_N 0x0040 /* SPKOUTL_MUTE_N */
+#define WM8994_SPKOUTL_MUTE_N_MASK 0x0040 /* SPKOUTL_MUTE_N */
+#define WM8994_SPKOUTL_MUTE_N_SHIFT 6 /* SPKOUTL_MUTE_N */
+#define WM8994_SPKOUTL_MUTE_N_WIDTH 1 /* SPKOUTL_MUTE_N */
+#define WM8994_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
+#define WM8994_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
+#define WM8994_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
+
+/*
+ * R39 (0x27) - Speaker Volume Right
+ */
+#define WM8994_SPKOUT_VU 0x0100 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
+#define WM8994_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
+#define WM8994_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */
+#define WM8994_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */
+#define WM8994_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */
+#define WM8994_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */
+#define WM8994_SPKOUTR_MUTE_N 0x0040 /* SPKOUTR_MUTE_N */
+#define WM8994_SPKOUTR_MUTE_N_MASK 0x0040 /* SPKOUTR_MUTE_N */
+#define WM8994_SPKOUTR_MUTE_N_SHIFT 6 /* SPKOUTR_MUTE_N */
+#define WM8994_SPKOUTR_MUTE_N_WIDTH 1 /* SPKOUTR_MUTE_N */
+#define WM8994_SPKOUTR_VOL_MASK 0x003F /* SPKOUTR_VOL - [5:0] */
+#define WM8994_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [5:0] */
+#define WM8994_SPKOUTR_VOL_WIDTH 6 /* SPKOUTR_VOL - [5:0] */
+
+/*
+ * R40 (0x28) - Input Mixer (2)
+ */
+#define WM8994_IN2LP_TO_IN2L 0x0080 /* IN2LP_TO_IN2L */
+#define WM8994_IN2LP_TO_IN2L_MASK 0x0080 /* IN2LP_TO_IN2L */
+#define WM8994_IN2LP_TO_IN2L_SHIFT 7 /* IN2LP_TO_IN2L */
+#define WM8994_IN2LP_TO_IN2L_WIDTH 1 /* IN2LP_TO_IN2L */
+#define WM8994_IN2LN_TO_IN2L 0x0040 /* IN2LN_TO_IN2L */
+#define WM8994_IN2LN_TO_IN2L_MASK 0x0040 /* IN2LN_TO_IN2L */
+#define WM8994_IN2LN_TO_IN2L_SHIFT 6 /* IN2LN_TO_IN2L */
+#define WM8994_IN2LN_TO_IN2L_WIDTH 1 /* IN2LN_TO_IN2L */
+#define WM8994_IN1LP_TO_IN1L 0x0020 /* IN1LP_TO_IN1L */
+#define WM8994_IN1LP_TO_IN1L_MASK 0x0020 /* IN1LP_TO_IN1L */
+#define WM8994_IN1LP_TO_IN1L_SHIFT 5 /* IN1LP_TO_IN1L */
+#define WM8994_IN1LP_TO_IN1L_WIDTH 1 /* IN1LP_TO_IN1L */
+#define WM8994_IN1LN_TO_IN1L 0x0010 /* IN1LN_TO_IN1L */
+#define WM8994_IN1LN_TO_IN1L_MASK 0x0010 /* IN1LN_TO_IN1L */
+#define WM8994_IN1LN_TO_IN1L_SHIFT 4 /* IN1LN_TO_IN1L */
+#define WM8994_IN1LN_TO_IN1L_WIDTH 1 /* IN1LN_TO_IN1L */
+#define WM8994_IN2RP_TO_IN2R 0x0008 /* IN2RP_TO_IN2R */
+#define WM8994_IN2RP_TO_IN2R_MASK 0x0008 /* IN2RP_TO_IN2R */
+#define WM8994_IN2RP_TO_IN2R_SHIFT 3 /* IN2RP_TO_IN2R */
+#define WM8994_IN2RP_TO_IN2R_WIDTH 1 /* IN2RP_TO_IN2R */
+#define WM8994_IN2RN_TO_IN2R 0x0004 /* IN2RN_TO_IN2R */
+#define WM8994_IN2RN_TO_IN2R_MASK 0x0004 /* IN2RN_TO_IN2R */
+#define WM8994_IN2RN_TO_IN2R_SHIFT 2 /* IN2RN_TO_IN2R */
+#define WM8994_IN2RN_TO_IN2R_WIDTH 1 /* IN2RN_TO_IN2R */
+#define WM8994_IN1RP_TO_IN1R 0x0002 /* IN1RP_TO_IN1R */
+#define WM8994_IN1RP_TO_IN1R_MASK 0x0002 /* IN1RP_TO_IN1R */
+#define WM8994_IN1RP_TO_IN1R_SHIFT 1 /* IN1RP_TO_IN1R */
+#define WM8994_IN1RP_TO_IN1R_WIDTH 1 /* IN1RP_TO_IN1R */
+#define WM8994_IN1RN_TO_IN1R 0x0001 /* IN1RN_TO_IN1R */
+#define WM8994_IN1RN_TO_IN1R_MASK 0x0001 /* IN1RN_TO_IN1R */
+#define WM8994_IN1RN_TO_IN1R_SHIFT 0 /* IN1RN_TO_IN1R */
+#define WM8994_IN1RN_TO_IN1R_WIDTH 1 /* IN1RN_TO_IN1R */
+
+/*
+ * R41 (0x29) - Input Mixer (3)
+ */
+#define WM8994_IN2L_TO_MIXINL 0x0100 /* IN2L_TO_MIXINL */
+#define WM8994_IN2L_TO_MIXINL_MASK 0x0100 /* IN2L_TO_MIXINL */
+#define WM8994_IN2L_TO_MIXINL_SHIFT 8 /* IN2L_TO_MIXINL */
+#define WM8994_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */
+#define WM8994_IN2L_MIXINL_VOL 0x0080 /* IN2L_MIXINL_VOL */
+#define WM8994_IN2L_MIXINL_VOL_MASK 0x0080 /* IN2L_MIXINL_VOL */
+#define WM8994_IN2L_MIXINL_VOL_SHIFT 7 /* IN2L_MIXINL_VOL */
+#define WM8994_IN2L_MIXINL_VOL_WIDTH 1 /* IN2L_MIXINL_VOL */
+#define WM8994_IN1L_TO_MIXINL 0x0020 /* IN1L_TO_MIXINL */
+#define WM8994_IN1L_TO_MIXINL_MASK 0x0020 /* IN1L_TO_MIXINL */
+#define WM8994_IN1L_TO_MIXINL_SHIFT 5 /* IN1L_TO_MIXINL */
+#define WM8994_IN1L_TO_MIXINL_WIDTH 1 /* IN1L_TO_MIXINL */
+#define WM8994_IN1L_MIXINL_VOL 0x0010 /* IN1L_MIXINL_VOL */
+#define WM8994_IN1L_MIXINL_VOL_MASK 0x0010 /* IN1L_MIXINL_VOL */
+#define WM8994_IN1L_MIXINL_VOL_SHIFT 4 /* IN1L_MIXINL_VOL */
+#define WM8994_IN1L_MIXINL_VOL_WIDTH 1 /* IN1L_MIXINL_VOL */
+#define WM8994_MIXOUTL_MIXINL_VOL_MASK 0x0007 /* MIXOUTL_MIXINL_VOL - [2:0] */
+#define WM8994_MIXOUTL_MIXINL_VOL_SHIFT 0 /* MIXOUTL_MIXINL_VOL - [2:0] */
+#define WM8994_MIXOUTL_MIXINL_VOL_WIDTH 3 /* MIXOUTL_MIXINL_VOL - [2:0] */
+
+/*
+ * R42 (0x2A) - Input Mixer (4)
+ */
+#define WM8994_IN2R_TO_MIXINR 0x0100 /* IN2R_TO_MIXINR */
+#define WM8994_IN2R_TO_MIXINR_MASK 0x0100 /* IN2R_TO_MIXINR */
+#define WM8994_IN2R_TO_MIXINR_SHIFT 8 /* IN2R_TO_MIXINR */
+#define WM8994_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */
+#define WM8994_IN2R_MIXINR_VOL 0x0080 /* IN2R_MIXINR_VOL */
+#define WM8994_IN2R_MIXINR_VOL_MASK 0x0080 /* IN2R_MIXINR_VOL */
+#define WM8994_IN2R_MIXINR_VOL_SHIFT 7 /* IN2R_MIXINR_VOL */
+#define WM8994_IN2R_MIXINR_VOL_WIDTH 1 /* IN2R_MIXINR_VOL */
+#define WM8994_IN1R_TO_MIXINR 0x0020 /* IN1R_TO_MIXINR */
+#define WM8994_IN1R_TO_MIXINR_MASK 0x0020 /* IN1R_TO_MIXINR */
+#define WM8994_IN1R_TO_MIXINR_SHIFT 5 /* IN1R_TO_MIXINR */
+#define WM8994_IN1R_TO_MIXINR_WIDTH 1 /* IN1R_TO_MIXINR */
+#define WM8994_IN1R_MIXINR_VOL 0x0010 /* IN1R_MIXINR_VOL */
+#define WM8994_IN1R_MIXINR_VOL_MASK 0x0010 /* IN1R_MIXINR_VOL */
+#define WM8994_IN1R_MIXINR_VOL_SHIFT 4 /* IN1R_MIXINR_VOL */
+#define WM8994_IN1R_MIXINR_VOL_WIDTH 1 /* IN1R_MIXINR_VOL */
+#define WM8994_MIXOUTR_MIXINR_VOL_MASK 0x0007 /* MIXOUTR_MIXINR_VOL - [2:0] */
+#define WM8994_MIXOUTR_MIXINR_VOL_SHIFT 0 /* MIXOUTR_MIXINR_VOL - [2:0] */
+#define WM8994_MIXOUTR_MIXINR_VOL_WIDTH 3 /* MIXOUTR_MIXINR_VOL - [2:0] */
+
+/*
+ * R43 (0x2B) - Input Mixer (5)
+ */
+#define WM8994_IN1LP_MIXINL_VOL_MASK 0x01C0 /* IN1LP_MIXINL_VOL - [8:6] */
+#define WM8994_IN1LP_MIXINL_VOL_SHIFT 6 /* IN1LP_MIXINL_VOL - [8:6] */
+#define WM8994_IN1LP_MIXINL_VOL_WIDTH 3 /* IN1LP_MIXINL_VOL - [8:6] */
+#define WM8994_IN2LRP_MIXINL_VOL_MASK 0x0007 /* IN2LRP_MIXINL_VOL - [2:0] */
+#define WM8994_IN2LRP_MIXINL_VOL_SHIFT 0 /* IN2LRP_MIXINL_VOL - [2:0] */
+#define WM8994_IN2LRP_MIXINL_VOL_WIDTH 3 /* IN2LRP_MIXINL_VOL - [2:0] */
+
+/*
+ * R44 (0x2C) - Input Mixer (6)
+ */
+#define WM8994_IN1RP_MIXINR_VOL_MASK 0x01C0 /* IN1RP_MIXINR_VOL - [8:6] */
+#define WM8994_IN1RP_MIXINR_VOL_SHIFT 6 /* IN1RP_MIXINR_VOL - [8:6] */
+#define WM8994_IN1RP_MIXINR_VOL_WIDTH 3 /* IN1RP_MIXINR_VOL - [8:6] */
+#define WM8994_IN2LRP_MIXINR_VOL_MASK 0x0007 /* IN2LRP_MIXINR_VOL - [2:0] */
+#define WM8994_IN2LRP_MIXINR_VOL_SHIFT 0 /* IN2LRP_MIXINR_VOL - [2:0] */
+#define WM8994_IN2LRP_MIXINR_VOL_WIDTH 3 /* IN2LRP_MIXINR_VOL - [2:0] */
+
+/*
+ * R45 (0x2D) - Output Mixer (1)
+ */
+#define WM8994_DAC1L_TO_HPOUT1L 0x0100 /* DAC1L_TO_HPOUT1L */
+#define WM8994_DAC1L_TO_HPOUT1L_MASK 0x0100 /* DAC1L_TO_HPOUT1L */
+#define WM8994_DAC1L_TO_HPOUT1L_SHIFT 8 /* DAC1L_TO_HPOUT1L */
+#define WM8994_DAC1L_TO_HPOUT1L_WIDTH 1 /* DAC1L_TO_HPOUT1L */
+#define WM8994_MIXINR_TO_MIXOUTL 0x0080 /* MIXINR_TO_MIXOUTL */
+#define WM8994_MIXINR_TO_MIXOUTL_MASK 0x0080 /* MIXINR_TO_MIXOUTL */
+#define WM8994_MIXINR_TO_MIXOUTL_SHIFT 7 /* MIXINR_TO_MIXOUTL */
+#define WM8994_MIXINR_TO_MIXOUTL_WIDTH 1 /* MIXINR_TO_MIXOUTL */
+#define WM8994_MIXINL_TO_MIXOUTL 0x0040 /* MIXINL_TO_MIXOUTL */
+#define WM8994_MIXINL_TO_MIXOUTL_MASK 0x0040 /* MIXINL_TO_MIXOUTL */
+#define WM8994_MIXINL_TO_MIXOUTL_SHIFT 6 /* MIXINL_TO_MIXOUTL */
+#define WM8994_MIXINL_TO_MIXOUTL_WIDTH 1 /* MIXINL_TO_MIXOUTL */
+#define WM8994_IN2RN_TO_MIXOUTL 0x0020 /* IN2RN_TO_MIXOUTL */
+#define WM8994_IN2RN_TO_MIXOUTL_MASK 0x0020 /* IN2RN_TO_MIXOUTL */
+#define WM8994_IN2RN_TO_MIXOUTL_SHIFT 5 /* IN2RN_TO_MIXOUTL */
+#define WM8994_IN2RN_TO_MIXOUTL_WIDTH 1 /* IN2RN_TO_MIXOUTL */
+#define WM8994_IN2LN_TO_MIXOUTL 0x0010 /* IN2LN_TO_MIXOUTL */
+#define WM8994_IN2LN_TO_MIXOUTL_MASK 0x0010 /* IN2LN_TO_MIXOUTL */
+#define WM8994_IN2LN_TO_MIXOUTL_SHIFT 4 /* IN2LN_TO_MIXOUTL */
+#define WM8994_IN2LN_TO_MIXOUTL_WIDTH 1 /* IN2LN_TO_MIXOUTL */
+#define WM8994_IN1R_TO_MIXOUTL 0x0008 /* IN1R_TO_MIXOUTL */
+#define WM8994_IN1R_TO_MIXOUTL_MASK 0x0008 /* IN1R_TO_MIXOUTL */
+#define WM8994_IN1R_TO_MIXOUTL_SHIFT 3 /* IN1R_TO_MIXOUTL */
+#define WM8994_IN1R_TO_MIXOUTL_WIDTH 1 /* IN1R_TO_MIXOUTL */
+#define WM8994_IN1L_TO_MIXOUTL 0x0004 /* IN1L_TO_MIXOUTL */
+#define WM8994_IN1L_TO_MIXOUTL_MASK 0x0004 /* IN1L_TO_MIXOUTL */
+#define WM8994_IN1L_TO_MIXOUTL_SHIFT 2 /* IN1L_TO_MIXOUTL */
+#define WM8994_IN1L_TO_MIXOUTL_WIDTH 1 /* IN1L_TO_MIXOUTL */
+#define WM8994_IN2LP_TO_MIXOUTL 0x0002 /* IN2LP_TO_MIXOUTL */
+#define WM8994_IN2LP_TO_MIXOUTL_MASK 0x0002 /* IN2LP_TO_MIXOUTL */
+#define WM8994_IN2LP_TO_MIXOUTL_SHIFT 1 /* IN2LP_TO_MIXOUTL */
+#define WM8994_IN2LP_TO_MIXOUTL_WIDTH 1 /* IN2LP_TO_MIXOUTL */
+#define WM8994_DAC1L_TO_MIXOUTL 0x0001 /* DAC1L_TO_MIXOUTL */
+#define WM8994_DAC1L_TO_MIXOUTL_MASK 0x0001 /* DAC1L_TO_MIXOUTL */
+#define WM8994_DAC1L_TO_MIXOUTL_SHIFT 0 /* DAC1L_TO_MIXOUTL */
+#define WM8994_DAC1L_TO_MIXOUTL_WIDTH 1 /* DAC1L_TO_MIXOUTL */
+
+/*
+ * R46 (0x2E) - Output Mixer (2)
+ */
+#define WM8994_DAC1R_TO_HPOUT1R 0x0100 /* DAC1R_TO_HPOUT1R */
+#define WM8994_DAC1R_TO_HPOUT1R_MASK 0x0100 /* DAC1R_TO_HPOUT1R */
+#define WM8994_DAC1R_TO_HPOUT1R_SHIFT 8 /* DAC1R_TO_HPOUT1R */
+#define WM8994_DAC1R_TO_HPOUT1R_WIDTH 1 /* DAC1R_TO_HPOUT1R */
+#define WM8994_MIXINL_TO_MIXOUTR 0x0080 /* MIXINL_TO_MIXOUTR */
+#define WM8994_MIXINL_TO_MIXOUTR_MASK 0x0080 /* MIXINL_TO_MIXOUTR */
+#define WM8994_MIXINL_TO_MIXOUTR_SHIFT 7 /* MIXINL_TO_MIXOUTR */
+#define WM8994_MIXINL_TO_MIXOUTR_WIDTH 1 /* MIXINL_TO_MIXOUTR */
+#define WM8994_MIXINR_TO_MIXOUTR 0x0040 /* MIXINR_TO_MIXOUTR */
+#define WM8994_MIXINR_TO_MIXOUTR_MASK 0x0040 /* MIXINR_TO_MIXOUTR */
+#define WM8994_MIXINR_TO_MIXOUTR_SHIFT 6 /* MIXINR_TO_MIXOUTR */
+#define WM8994_MIXINR_TO_MIXOUTR_WIDTH 1 /* MIXINR_TO_MIXOUTR */
+#define WM8994_IN2LN_TO_MIXOUTR 0x0020 /* IN2LN_TO_MIXOUTR */
+#define WM8994_IN2LN_TO_MIXOUTR_MASK 0x0020 /* IN2LN_TO_MIXOUTR */
+#define WM8994_IN2LN_TO_MIXOUTR_SHIFT 5 /* IN2LN_TO_MIXOUTR */
+#define WM8994_IN2LN_TO_MIXOUTR_WIDTH 1 /* IN2LN_TO_MIXOUTR */
+#define WM8994_IN2RN_TO_MIXOUTR 0x0010 /* IN2RN_TO_MIXOUTR */
+#define WM8994_IN2RN_TO_MIXOUTR_MASK 0x0010 /* IN2RN_TO_MIXOUTR */
+#define WM8994_IN2RN_TO_MIXOUTR_SHIFT 4 /* IN2RN_TO_MIXOUTR */
+#define WM8994_IN2RN_TO_MIXOUTR_WIDTH 1 /* IN2RN_TO_MIXOUTR */
+#define WM8994_IN1L_TO_MIXOUTR 0x0008 /* IN1L_TO_MIXOUTR */
+#define WM8994_IN1L_TO_MIXOUTR_MASK 0x0008 /* IN1L_TO_MIXOUTR */
+#define WM8994_IN1L_TO_MIXOUTR_SHIFT 3 /* IN1L_TO_MIXOUTR */
+#define WM8994_IN1L_TO_MIXOUTR_WIDTH 1 /* IN1L_TO_MIXOUTR */
+#define WM8994_IN1R_TO_MIXOUTR 0x0004 /* IN1R_TO_MIXOUTR */
+#define WM8994_IN1R_TO_MIXOUTR_MASK 0x0004 /* IN1R_TO_MIXOUTR */
+#define WM8994_IN1R_TO_MIXOUTR_SHIFT 2 /* IN1R_TO_MIXOUTR */
+#define WM8994_IN1R_TO_MIXOUTR_WIDTH 1 /* IN1R_TO_MIXOUTR */
+#define WM8994_IN2RP_TO_MIXOUTR 0x0002 /* IN2RP_TO_MIXOUTR */
+#define WM8994_IN2RP_TO_MIXOUTR_MASK 0x0002 /* IN2RP_TO_MIXOUTR */
+#define WM8994_IN2RP_TO_MIXOUTR_SHIFT 1 /* IN2RP_TO_MIXOUTR */
+#define WM8994_IN2RP_TO_MIXOUTR_WIDTH 1 /* IN2RP_TO_MIXOUTR */
+#define WM8994_DAC1R_TO_MIXOUTR 0x0001 /* DAC1R_TO_MIXOUTR */
+#define WM8994_DAC1R_TO_MIXOUTR_MASK 0x0001 /* DAC1R_TO_MIXOUTR */
+#define WM8994_DAC1R_TO_MIXOUTR_SHIFT 0 /* DAC1R_TO_MIXOUTR */
+#define WM8994_DAC1R_TO_MIXOUTR_WIDTH 1 /* DAC1R_TO_MIXOUTR */
+
+/*
+ * R47 (0x2F) - Output Mixer (3)
+ */
+#define WM8994_IN2LP_MIXOUTL_VOL_MASK 0x0E00 /* IN2LP_MIXOUTL_VOL - [11:9] */
+#define WM8994_IN2LP_MIXOUTL_VOL_SHIFT 9 /* IN2LP_MIXOUTL_VOL - [11:9] */
+#define WM8994_IN2LP_MIXOUTL_VOL_WIDTH 3 /* IN2LP_MIXOUTL_VOL - [11:9] */
+#define WM8994_IN2LN_MIXOUTL_VOL_MASK 0x01C0 /* IN2LN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN2LN_MIXOUTL_VOL_SHIFT 6 /* IN2LN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN2LN_MIXOUTL_VOL_WIDTH 3 /* IN2LN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN1R_MIXOUTL_VOL_MASK 0x0038 /* IN1R_MIXOUTL_VOL - [5:3] */
+#define WM8994_IN1R_MIXOUTL_VOL_SHIFT 3 /* IN1R_MIXOUTL_VOL - [5:3] */
+#define WM8994_IN1R_MIXOUTL_VOL_WIDTH 3 /* IN1R_MIXOUTL_VOL - [5:3] */
+#define WM8994_IN1L_MIXOUTL_VOL_MASK 0x0007 /* IN1L_MIXOUTL_VOL - [2:0] */
+#define WM8994_IN1L_MIXOUTL_VOL_SHIFT 0 /* IN1L_MIXOUTL_VOL - [2:0] */
+#define WM8994_IN1L_MIXOUTL_VOL_WIDTH 3 /* IN1L_MIXOUTL_VOL - [2:0] */
+
+/*
+ * R48 (0x30) - Output Mixer (4)
+ */
+#define WM8994_IN2RP_MIXOUTR_VOL_MASK 0x0E00 /* IN2RP_MIXOUTR_VOL - [11:9] */
+#define WM8994_IN2RP_MIXOUTR_VOL_SHIFT 9 /* IN2RP_MIXOUTR_VOL - [11:9] */
+#define WM8994_IN2RP_MIXOUTR_VOL_WIDTH 3 /* IN2RP_MIXOUTR_VOL - [11:9] */
+#define WM8994_IN2RN_MIXOUTR_VOL_MASK 0x01C0 /* IN2RN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN2RN_MIXOUTR_VOL_SHIFT 6 /* IN2RN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN2RN_MIXOUTR_VOL_WIDTH 3 /* IN2RN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN1L_MIXOUTR_VOL_MASK 0x0038 /* IN1L_MIXOUTR_VOL - [5:3] */
+#define WM8994_IN1L_MIXOUTR_VOL_SHIFT 3 /* IN1L_MIXOUTR_VOL - [5:3] */
+#define WM8994_IN1L_MIXOUTR_VOL_WIDTH 3 /* IN1L_MIXOUTR_VOL - [5:3] */
+#define WM8994_IN1R_MIXOUTR_VOL_MASK 0x0007 /* IN1R_MIXOUTR_VOL - [2:0] */
+#define WM8994_IN1R_MIXOUTR_VOL_SHIFT 0 /* IN1R_MIXOUTR_VOL - [2:0] */
+#define WM8994_IN1R_MIXOUTR_VOL_WIDTH 3 /* IN1R_MIXOUTR_VOL - [2:0] */
+
+/*
+ * R49 (0x31) - Output Mixer (5)
+ */
+#define WM8994_DAC1L_MIXOUTL_VOL_MASK 0x0E00 /* DAC1L_MIXOUTL_VOL - [11:9] */
+#define WM8994_DAC1L_MIXOUTL_VOL_SHIFT 9 /* DAC1L_MIXOUTL_VOL - [11:9] */
+#define WM8994_DAC1L_MIXOUTL_VOL_WIDTH 3 /* DAC1L_MIXOUTL_VOL - [11:9] */
+#define WM8994_IN2RN_MIXOUTL_VOL_MASK 0x01C0 /* IN2RN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN2RN_MIXOUTL_VOL_SHIFT 6 /* IN2RN_MIXOUTL_VOL - [8:6] */
+#define WM8994_IN2RN_MIXOUTL_VOL_WIDTH 3 /* IN2RN_MIXOUTL_VOL - [8:6] */
+#define WM8994_MIXINR_MIXOUTL_VOL_MASK 0x0038 /* MIXINR_MIXOUTL_VOL - [5:3] */
+#define WM8994_MIXINR_MIXOUTL_VOL_SHIFT 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
+#define WM8994_MIXINR_MIXOUTL_VOL_WIDTH 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
+#define WM8994_MIXINL_MIXOUTL_VOL_MASK 0x0007 /* MIXINL_MIXOUTL_VOL - [2:0] */
+#define WM8994_MIXINL_MIXOUTL_VOL_SHIFT 0 /* MIXINL_MIXOUTL_VOL - [2:0] */
+#define WM8994_MIXINL_MIXOUTL_VOL_WIDTH 3 /* MIXINL_MIXOUTL_VOL - [2:0] */
+
+/*
+ * R50 (0x32) - Output Mixer (6)
+ */
+#define WM8994_DAC1R_MIXOUTR_VOL_MASK 0x0E00 /* DAC1R_MIXOUTR_VOL - [11:9] */
+#define WM8994_DAC1R_MIXOUTR_VOL_SHIFT 9 /* DAC1R_MIXOUTR_VOL - [11:9] */
+#define WM8994_DAC1R_MIXOUTR_VOL_WIDTH 3 /* DAC1R_MIXOUTR_VOL - [11:9] */
+#define WM8994_IN2LN_MIXOUTR_VOL_MASK 0x01C0 /* IN2LN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN2LN_MIXOUTR_VOL_SHIFT 6 /* IN2LN_MIXOUTR_VOL - [8:6] */
+#define WM8994_IN2LN_MIXOUTR_VOL_WIDTH 3 /* IN2LN_MIXOUTR_VOL - [8:6] */
+#define WM8994_MIXINL_MIXOUTR_VOL_MASK 0x0038 /* MIXINL_MIXOUTR_VOL - [5:3] */
+#define WM8994_MIXINL_MIXOUTR_VOL_SHIFT 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
+#define WM8994_MIXINL_MIXOUTR_VOL_WIDTH 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
+#define WM8994_MIXINR_MIXOUTR_VOL_MASK 0x0007 /* MIXINR_MIXOUTR_VOL - [2:0] */
+#define WM8994_MIXINR_MIXOUTR_VOL_SHIFT 0 /* MIXINR_MIXOUTR_VOL - [2:0] */
+#define WM8994_MIXINR_MIXOUTR_VOL_WIDTH 3 /* MIXINR_MIXOUTR_VOL - [2:0] */
+
+/*
+ * R51 (0x33) - HPOUT2 Mixer
+ */
+#define WM8994_IN2LRP_TO_HPOUT2 0x0020 /* IN2LRP_TO_HPOUT2 */
+#define WM8994_IN2LRP_TO_HPOUT2_MASK 0x0020 /* IN2LRP_TO_HPOUT2 */
+#define WM8994_IN2LRP_TO_HPOUT2_SHIFT 5 /* IN2LRP_TO_HPOUT2 */
+#define WM8994_IN2LRP_TO_HPOUT2_WIDTH 1 /* IN2LRP_TO_HPOUT2 */
+#define WM8994_MIXOUTLVOL_TO_HPOUT2 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTLVOL_TO_HPOUT2_MASK 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTLVOL_TO_HPOUT2_SHIFT 4 /* MIXOUTLVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTLVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTLVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTRVOL_TO_HPOUT2 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTRVOL_TO_HPOUT2_MASK 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTRVOL_TO_HPOUT2_SHIFT 3 /* MIXOUTRVOL_TO_HPOUT2 */
+#define WM8994_MIXOUTRVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTRVOL_TO_HPOUT2 */
+
+/*
+ * R52 (0x34) - Line Mixer (1)
+ */
+#define WM8994_MIXOUTL_TO_LINEOUT1N 0x0040 /* MIXOUTL_TO_LINEOUT1N */
+#define WM8994_MIXOUTL_TO_LINEOUT1N_MASK 0x0040 /* MIXOUTL_TO_LINEOUT1N */
+#define WM8994_MIXOUTL_TO_LINEOUT1N_SHIFT 6 /* MIXOUTL_TO_LINEOUT1N */
+#define WM8994_MIXOUTL_TO_LINEOUT1N_WIDTH 1 /* MIXOUTL_TO_LINEOUT1N */
+#define WM8994_MIXOUTR_TO_LINEOUT1N 0x0020 /* MIXOUTR_TO_LINEOUT1N */
+#define WM8994_MIXOUTR_TO_LINEOUT1N_MASK 0x0020 /* MIXOUTR_TO_LINEOUT1N */
+#define WM8994_MIXOUTR_TO_LINEOUT1N_SHIFT 5 /* MIXOUTR_TO_LINEOUT1N */
+#define WM8994_MIXOUTR_TO_LINEOUT1N_WIDTH 1 /* MIXOUTR_TO_LINEOUT1N */
+#define WM8994_LINEOUT1_MODE 0x0010 /* LINEOUT1_MODE */
+#define WM8994_LINEOUT1_MODE_MASK 0x0010 /* LINEOUT1_MODE */
+#define WM8994_LINEOUT1_MODE_SHIFT 4 /* LINEOUT1_MODE */
+#define WM8994_LINEOUT1_MODE_WIDTH 1 /* LINEOUT1_MODE */
+#define WM8994_IN1R_TO_LINEOUT1P 0x0004 /* IN1R_TO_LINEOUT1P */
+#define WM8994_IN1R_TO_LINEOUT1P_MASK 0x0004 /* IN1R_TO_LINEOUT1P */
+#define WM8994_IN1R_TO_LINEOUT1P_SHIFT 2 /* IN1R_TO_LINEOUT1P */
+#define WM8994_IN1R_TO_LINEOUT1P_WIDTH 1 /* IN1R_TO_LINEOUT1P */
+#define WM8994_IN1L_TO_LINEOUT1P 0x0002 /* IN1L_TO_LINEOUT1P */
+#define WM8994_IN1L_TO_LINEOUT1P_MASK 0x0002 /* IN1L_TO_LINEOUT1P */
+#define WM8994_IN1L_TO_LINEOUT1P_SHIFT 1 /* IN1L_TO_LINEOUT1P */
+#define WM8994_IN1L_TO_LINEOUT1P_WIDTH 1 /* IN1L_TO_LINEOUT1P */
+#define WM8994_MIXOUTL_TO_LINEOUT1P 0x0001 /* MIXOUTL_TO_LINEOUT1P */
+#define WM8994_MIXOUTL_TO_LINEOUT1P_MASK 0x0001 /* MIXOUTL_TO_LINEOUT1P */
+#define WM8994_MIXOUTL_TO_LINEOUT1P_SHIFT 0 /* MIXOUTL_TO_LINEOUT1P */
+#define WM8994_MIXOUTL_TO_LINEOUT1P_WIDTH 1 /* MIXOUTL_TO_LINEOUT1P */
+
+/*
+ * R53 (0x35) - Line Mixer (2)
+ */
+#define WM8994_MIXOUTR_TO_LINEOUT2N 0x0040 /* MIXOUTR_TO_LINEOUT2N */
+#define WM8994_MIXOUTR_TO_LINEOUT2N_MASK 0x0040 /* MIXOUTR_TO_LINEOUT2N */
+#define WM8994_MIXOUTR_TO_LINEOUT2N_SHIFT 6 /* MIXOUTR_TO_LINEOUT2N */
+#define WM8994_MIXOUTR_TO_LINEOUT2N_WIDTH 1 /* MIXOUTR_TO_LINEOUT2N */
+#define WM8994_MIXOUTL_TO_LINEOUT2N 0x0020 /* MIXOUTL_TO_LINEOUT2N */
+#define WM8994_MIXOUTL_TO_LINEOUT2N_MASK 0x0020 /* MIXOUTL_TO_LINEOUT2N */
+#define WM8994_MIXOUTL_TO_LINEOUT2N_SHIFT 5 /* MIXOUTL_TO_LINEOUT2N */
+#define WM8994_MIXOUTL_TO_LINEOUT2N_WIDTH 1 /* MIXOUTL_TO_LINEOUT2N */
+#define WM8994_LINEOUT2_MODE 0x0010 /* LINEOUT2_MODE */
+#define WM8994_LINEOUT2_MODE_MASK 0x0010 /* LINEOUT2_MODE */
+#define WM8994_LINEOUT2_MODE_SHIFT 4 /* LINEOUT2_MODE */
+#define WM8994_LINEOUT2_MODE_WIDTH 1 /* LINEOUT2_MODE */
+#define WM8994_IN1L_TO_LINEOUT2P 0x0004 /* IN1L_TO_LINEOUT2P */
+#define WM8994_IN1L_TO_LINEOUT2P_MASK 0x0004 /* IN1L_TO_LINEOUT2P */
+#define WM8994_IN1L_TO_LINEOUT2P_SHIFT 2 /* IN1L_TO_LINEOUT2P */
+#define WM8994_IN1L_TO_LINEOUT2P_WIDTH 1 /* IN1L_TO_LINEOUT2P */
+#define WM8994_IN1R_TO_LINEOUT2P 0x0002 /* IN1R_TO_LINEOUT2P */
+#define WM8994_IN1R_TO_LINEOUT2P_MASK 0x0002 /* IN1R_TO_LINEOUT2P */
+#define WM8994_IN1R_TO_LINEOUT2P_SHIFT 1 /* IN1R_TO_LINEOUT2P */
+#define WM8994_IN1R_TO_LINEOUT2P_WIDTH 1 /* IN1R_TO_LINEOUT2P */
+#define WM8994_MIXOUTR_TO_LINEOUT2P 0x0001 /* MIXOUTR_TO_LINEOUT2P */
+#define WM8994_MIXOUTR_TO_LINEOUT2P_MASK 0x0001 /* MIXOUTR_TO_LINEOUT2P */
+#define WM8994_MIXOUTR_TO_LINEOUT2P_SHIFT 0 /* MIXOUTR_TO_LINEOUT2P */
+#define WM8994_MIXOUTR_TO_LINEOUT2P_WIDTH 1 /* MIXOUTR_TO_LINEOUT2P */
+
+/*
+ * R54 (0x36) - Speaker Mixer
+ */
+#define WM8994_DAC2L_TO_SPKMIXL 0x0200 /* DAC2L_TO_SPKMIXL */
+#define WM8994_DAC2L_TO_SPKMIXL_MASK 0x0200 /* DAC2L_TO_SPKMIXL */
+#define WM8994_DAC2L_TO_SPKMIXL_SHIFT 9 /* DAC2L_TO_SPKMIXL */
+#define WM8994_DAC2L_TO_SPKMIXL_WIDTH 1 /* DAC2L_TO_SPKMIXL */
+#define WM8994_DAC2R_TO_SPKMIXR 0x0100 /* DAC2R_TO_SPKMIXR */
+#define WM8994_DAC2R_TO_SPKMIXR_MASK 0x0100 /* DAC2R_TO_SPKMIXR */
+#define WM8994_DAC2R_TO_SPKMIXR_SHIFT 8 /* DAC2R_TO_SPKMIXR */
+#define WM8994_DAC2R_TO_SPKMIXR_WIDTH 1 /* DAC2R_TO_SPKMIXR */
+#define WM8994_MIXINL_TO_SPKMIXL 0x0080 /* MIXINL_TO_SPKMIXL */
+#define WM8994_MIXINL_TO_SPKMIXL_MASK 0x0080 /* MIXINL_TO_SPKMIXL */
+#define WM8994_MIXINL_TO_SPKMIXL_SHIFT 7 /* MIXINL_TO_SPKMIXL */
+#define WM8994_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */
+#define WM8994_MIXINR_TO_SPKMIXR 0x0040 /* MIXINR_TO_SPKMIXR */
+#define WM8994_MIXINR_TO_SPKMIXR_MASK 0x0040 /* MIXINR_TO_SPKMIXR */
+#define WM8994_MIXINR_TO_SPKMIXR_SHIFT 6 /* MIXINR_TO_SPKMIXR */
+#define WM8994_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */
+#define WM8994_IN1LP_TO_SPKMIXL 0x0020 /* IN1LP_TO_SPKMIXL */
+#define WM8994_IN1LP_TO_SPKMIXL_MASK 0x0020 /* IN1LP_TO_SPKMIXL */
+#define WM8994_IN1LP_TO_SPKMIXL_SHIFT 5 /* IN1LP_TO_SPKMIXL */
+#define WM8994_IN1LP_TO_SPKMIXL_WIDTH 1 /* IN1LP_TO_SPKMIXL */
+#define WM8994_IN1RP_TO_SPKMIXR 0x0010 /* IN1RP_TO_SPKMIXR */
+#define WM8994_IN1RP_TO_SPKMIXR_MASK 0x0010 /* IN1RP_TO_SPKMIXR */
+#define WM8994_IN1RP_TO_SPKMIXR_SHIFT 4 /* IN1RP_TO_SPKMIXR */
+#define WM8994_IN1RP_TO_SPKMIXR_WIDTH 1 /* IN1RP_TO_SPKMIXR */
+#define WM8994_MIXOUTL_TO_SPKMIXL 0x0008 /* MIXOUTL_TO_SPKMIXL */
+#define WM8994_MIXOUTL_TO_SPKMIXL_MASK 0x0008 /* MIXOUTL_TO_SPKMIXL */
+#define WM8994_MIXOUTL_TO_SPKMIXL_SHIFT 3 /* MIXOUTL_TO_SPKMIXL */
+#define WM8994_MIXOUTL_TO_SPKMIXL_WIDTH 1 /* MIXOUTL_TO_SPKMIXL */
+#define WM8994_MIXOUTR_TO_SPKMIXR 0x0004 /* MIXOUTR_TO_SPKMIXR */
+#define WM8994_MIXOUTR_TO_SPKMIXR_MASK 0x0004 /* MIXOUTR_TO_SPKMIXR */
+#define WM8994_MIXOUTR_TO_SPKMIXR_SHIFT 2 /* MIXOUTR_TO_SPKMIXR */
+#define WM8994_MIXOUTR_TO_SPKMIXR_WIDTH 1 /* MIXOUTR_TO_SPKMIXR */
+#define WM8994_DAC1L_TO_SPKMIXL 0x0002 /* DAC1L_TO_SPKMIXL */
+#define WM8994_DAC1L_TO_SPKMIXL_MASK 0x0002 /* DAC1L_TO_SPKMIXL */
+#define WM8994_DAC1L_TO_SPKMIXL_SHIFT 1 /* DAC1L_TO_SPKMIXL */
+#define WM8994_DAC1L_TO_SPKMIXL_WIDTH 1 /* DAC1L_TO_SPKMIXL */
+#define WM8994_DAC1R_TO_SPKMIXR 0x0001 /* DAC1R_TO_SPKMIXR */
+#define WM8994_DAC1R_TO_SPKMIXR_MASK 0x0001 /* DAC1R_TO_SPKMIXR */
+#define WM8994_DAC1R_TO_SPKMIXR_SHIFT 0 /* DAC1R_TO_SPKMIXR */
+#define WM8994_DAC1R_TO_SPKMIXR_WIDTH 1 /* DAC1R_TO_SPKMIXR */
+
+/*
+ * R55 (0x37) - Additional Control
+ */
+#define WM8994_LINEOUT1_FB 0x0080 /* LINEOUT1_FB */
+#define WM8994_LINEOUT1_FB_MASK 0x0080 /* LINEOUT1_FB */
+#define WM8994_LINEOUT1_FB_SHIFT 7 /* LINEOUT1_FB */
+#define WM8994_LINEOUT1_FB_WIDTH 1 /* LINEOUT1_FB */
+#define WM8994_LINEOUT2_FB 0x0040 /* LINEOUT2_FB */
+#define WM8994_LINEOUT2_FB_MASK 0x0040 /* LINEOUT2_FB */
+#define WM8994_LINEOUT2_FB_SHIFT 6 /* LINEOUT2_FB */
+#define WM8994_LINEOUT2_FB_WIDTH 1 /* LINEOUT2_FB */
+#define WM8994_VROI 0x0001 /* VROI */
+#define WM8994_VROI_MASK 0x0001 /* VROI */
+#define WM8994_VROI_SHIFT 0 /* VROI */
+#define WM8994_VROI_WIDTH 1 /* VROI */
+
+/*
+ * R56 (0x38) - AntiPOP (1)
+ */
+#define WM8994_LINEOUT_VMID_BUF_ENA 0x0080 /* LINEOUT_VMID_BUF_ENA */
+#define WM8994_LINEOUT_VMID_BUF_ENA_MASK 0x0080 /* LINEOUT_VMID_BUF_ENA */
+#define WM8994_LINEOUT_VMID_BUF_ENA_SHIFT 7 /* LINEOUT_VMID_BUF_ENA */
+#define WM8994_LINEOUT_VMID_BUF_ENA_WIDTH 1 /* LINEOUT_VMID_BUF_ENA */
+#define WM8994_HPOUT2_IN_ENA 0x0040 /* HPOUT2_IN_ENA */
+#define WM8994_HPOUT2_IN_ENA_MASK 0x0040 /* HPOUT2_IN_ENA */
+#define WM8994_HPOUT2_IN_ENA_SHIFT 6 /* HPOUT2_IN_ENA */
+#define WM8994_HPOUT2_IN_ENA_WIDTH 1 /* HPOUT2_IN_ENA */
+#define WM8994_LINEOUT1_DISCH 0x0020 /* LINEOUT1_DISCH */
+#define WM8994_LINEOUT1_DISCH_MASK 0x0020 /* LINEOUT1_DISCH */
+#define WM8994_LINEOUT1_DISCH_SHIFT 5 /* LINEOUT1_DISCH */
+#define WM8994_LINEOUT1_DISCH_WIDTH 1 /* LINEOUT1_DISCH */
+#define WM8994_LINEOUT2_DISCH 0x0010 /* LINEOUT2_DISCH */
+#define WM8994_LINEOUT2_DISCH_MASK 0x0010 /* LINEOUT2_DISCH */
+#define WM8994_LINEOUT2_DISCH_SHIFT 4 /* LINEOUT2_DISCH */
+#define WM8994_LINEOUT2_DISCH_WIDTH 1 /* LINEOUT2_DISCH */
+
+/*
+ * R57 (0x39) - AntiPOP (2)
+ */
+#define WM8994_MICB2_DISCH 0x0100 /* MICB2_DISCH */
+#define WM8994_MICB2_DISCH_MASK 0x0100 /* MICB2_DISCH */
+#define WM8994_MICB2_DISCH_SHIFT 8 /* MICB2_DISCH */
+#define WM8994_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
+#define WM8994_MICB1_DISCH 0x0080 /* MICB1_DISCH */
+#define WM8994_MICB1_DISCH_MASK 0x0080 /* MICB1_DISCH */
+#define WM8994_MICB1_DISCH_SHIFT 7 /* MICB1_DISCH */
+#define WM8994_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
+#define WM8994_VMID_RAMP_MASK 0x0060 /* VMID_RAMP - [6:5] */
+#define WM8994_VMID_RAMP_SHIFT 5 /* VMID_RAMP - [6:5] */
+#define WM8994_VMID_RAMP_WIDTH 2 /* VMID_RAMP - [6:5] */
+#define WM8994_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
+#define WM8994_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
+#define WM8994_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
+#define WM8994_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
+#define WM8994_STARTUP_BIAS_ENA 0x0004 /* STARTUP_BIAS_ENA */
+#define WM8994_STARTUP_BIAS_ENA_MASK 0x0004 /* STARTUP_BIAS_ENA */
+#define WM8994_STARTUP_BIAS_ENA_SHIFT 2 /* STARTUP_BIAS_ENA */
+#define WM8994_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
+#define WM8994_BIAS_SRC 0x0002 /* BIAS_SRC */
+#define WM8994_BIAS_SRC_MASK 0x0002 /* BIAS_SRC */
+#define WM8994_BIAS_SRC_SHIFT 1 /* BIAS_SRC */
+#define WM8994_BIAS_SRC_WIDTH 1 /* BIAS_SRC */
+#define WM8994_VMID_DISCH 0x0001 /* VMID_DISCH */
+#define WM8994_VMID_DISCH_MASK 0x0001 /* VMID_DISCH */
+#define WM8994_VMID_DISCH_SHIFT 0 /* VMID_DISCH */
+#define WM8994_VMID_DISCH_WIDTH 1 /* VMID_DISCH */
+
+/*
+ * R58 (0x3A) - MICBIAS
+ */
+#define WM8994_MICD_SCTHR_MASK 0x00C0 /* MICD_SCTHR - [7:6] */
+#define WM8994_MICD_SCTHR_SHIFT 6 /* MICD_SCTHR - [7:6] */
+#define WM8994_MICD_SCTHR_WIDTH 2 /* MICD_SCTHR - [7:6] */
+#define WM8994_MICD_THR_MASK 0x0038 /* MICD_THR - [5:3] */
+#define WM8994_MICD_THR_SHIFT 3 /* MICD_THR - [5:3] */
+#define WM8994_MICD_THR_WIDTH 3 /* MICD_THR - [5:3] */
+#define WM8994_MICD_ENA 0x0004 /* MICD_ENA */
+#define WM8994_MICD_ENA_MASK 0x0004 /* MICD_ENA */
+#define WM8994_MICD_ENA_SHIFT 2 /* MICD_ENA */
+#define WM8994_MICD_ENA_WIDTH 1 /* MICD_ENA */
+#define WM8994_MICB2_LVL 0x0002 /* MICB2_LVL */
+#define WM8994_MICB2_LVL_MASK 0x0002 /* MICB2_LVL */
+#define WM8994_MICB2_LVL_SHIFT 1 /* MICB2_LVL */
+#define WM8994_MICB2_LVL_WIDTH 1 /* MICB2_LVL */
+#define WM8994_MICB1_LVL 0x0001 /* MICB1_LVL */
+#define WM8994_MICB1_LVL_MASK 0x0001 /* MICB1_LVL */
+#define WM8994_MICB1_LVL_SHIFT 0 /* MICB1_LVL */
+#define WM8994_MICB1_LVL_WIDTH 1 /* MICB1_LVL */
+
+/*
+ * R59 (0x3B) - LDO 1
+ */
+#define WM8994_LDO1_VSEL_MASK 0x000E /* LDO1_VSEL - [3:1] */
+#define WM8994_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [3:1] */
+#define WM8994_LDO1_VSEL_WIDTH 3 /* LDO1_VSEL - [3:1] */
+#define WM8994_LDO1_DISCH 0x0001 /* LDO1_DISCH */
+#define WM8994_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
+#define WM8994_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
+#define WM8994_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
+
+/*
+ * R60 (0x3C) - LDO 2
+ */
+#define WM8994_LDO2_VSEL_MASK 0x0006 /* LDO2_VSEL - [2:1] */
+#define WM8994_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [2:1] */
+#define WM8994_LDO2_VSEL_WIDTH 2 /* LDO2_VSEL - [2:1] */
+#define WM8994_LDO2_DISCH 0x0001 /* LDO2_DISCH */
+#define WM8994_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
+#define WM8994_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
+#define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
+
+/*
+ * R76 (0x4C) - Charge Pump (1)
+ */
+#define WM8994_CP_ENA 0x8000 /* CP_ENA */
+#define WM8994_CP_ENA_MASK 0x8000 /* CP_ENA */
+#define WM8994_CP_ENA_SHIFT 15 /* CP_ENA */
+#define WM8994_CP_ENA_WIDTH 1 /* CP_ENA */
+
+/*
+ * R81 (0x51) - Class W (1)
+ */
+#define WM8994_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8994_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8994_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */
+#define WM8994_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
+#define WM8994_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
+#define WM8994_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
+#define WM8994_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
+
+/*
+ * R84 (0x54) - DC Servo (1)
+ */
+#define WM8994_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
+#define WM8994_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
+#define WM8994_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
+#define WM8994_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
+#define WM8994_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
+#define WM8994_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
+#define WM8994_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
+#define WM8994_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
+#define WM8994_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
+#define WM8994_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
+#define WM8994_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
+#define WM8994_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
+#define WM8994_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
+#define WM8994_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
+#define WM8994_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
+#define WM8994_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
+#define WM8994_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
+#define WM8994_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
+#define WM8994_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
+#define WM8994_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
+#define WM8994_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
+#define WM8994_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
+#define WM8994_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
+#define WM8994_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
+#define WM8994_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
+#define WM8994_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
+#define WM8994_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
+#define WM8994_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
+#define WM8994_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
+#define WM8994_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
+#define WM8994_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
+#define WM8994_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
+#define WM8994_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
+#define WM8994_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
+#define WM8994_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
+#define WM8994_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
+#define WM8994_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
+#define WM8994_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
+#define WM8994_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
+#define WM8994_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
+
+/*
+ * R85 (0x55) - DC Servo (2)
+ */
+#define WM8994_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
+#define WM8994_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
+#define WM8994_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
+#define WM8994_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
+#define WM8994_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
+#define WM8994_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
+
+/*
+ * R87 (0x57) - DC Servo (4)
+ */
+#define WM8994_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8994_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8994_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
+#define WM8994_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
+#define WM8994_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
+#define WM8994_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
+
+/*
+ * R88 (0x58) - DC Servo Readback
+ */
+#define WM8994_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
+#define WM8994_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
+#define WM8994_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
+#define WM8994_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
+#define WM8994_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
+#define WM8994_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
+#define WM8994_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
+#define WM8994_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
+#define WM8994_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
+
+/*
+ * R96 (0x60) - Analogue HP (1)
+ */
+#define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
+#define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
+#define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
+#define WM8994_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
+#define WM8994_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
+#define WM8994_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
+#define WM8994_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
+#define WM8994_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
+#define WM8994_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
+#define WM8994_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
+#define WM8994_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
+#define WM8994_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
+#define WM8994_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
+#define WM8994_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
+#define WM8994_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
+#define WM8994_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
+#define WM8994_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
+#define WM8994_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
+#define WM8994_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
+#define WM8994_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
+#define WM8994_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
+#define WM8994_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
+#define WM8994_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
+#define WM8994_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
+
+/*
+ * R256 (0x100) - Chip Revision
+ */
+#define WM8994_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
+#define WM8994_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
+#define WM8994_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
+
+/*
+ * R257 (0x101) - Control Interface
+ */
+#define WM8994_SPI_CONTRD 0x0040 /* SPI_CONTRD */
+#define WM8994_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
+#define WM8994_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
+#define WM8994_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
+#define WM8994_SPI_4WIRE 0x0020 /* SPI_4WIRE */
+#define WM8994_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
+#define WM8994_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
+#define WM8994_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
+#define WM8994_SPI_CFG 0x0010 /* SPI_CFG */
+#define WM8994_SPI_CFG_MASK 0x0010 /* SPI_CFG */
+#define WM8994_SPI_CFG_SHIFT 4 /* SPI_CFG */
+#define WM8994_SPI_CFG_WIDTH 1 /* SPI_CFG */
+#define WM8994_AUTO_INC 0x0004 /* AUTO_INC */
+#define WM8994_AUTO_INC_MASK 0x0004 /* AUTO_INC */
+#define WM8994_AUTO_INC_SHIFT 2 /* AUTO_INC */
+#define WM8994_AUTO_INC_WIDTH 1 /* AUTO_INC */
+
+/*
+ * R272 (0x110) - Write Sequencer Ctrl (1)
+ */
+#define WM8994_WSEQ_ENA 0x8000 /* WSEQ_ENA */
+#define WM8994_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
+#define WM8994_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
+#define WM8994_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
+#define WM8994_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
+#define WM8994_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
+#define WM8994_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
+#define WM8994_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
+#define WM8994_WSEQ_START 0x0100 /* WSEQ_START */
+#define WM8994_WSEQ_START_MASK 0x0100 /* WSEQ_START */
+#define WM8994_WSEQ_START_SHIFT 8 /* WSEQ_START */
+#define WM8994_WSEQ_START_WIDTH 1 /* WSEQ_START */
+#define WM8994_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
+#define WM8994_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
+#define WM8994_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
+
+/*
+ * R273 (0x111) - Write Sequencer Ctrl (2)
+ */
+#define WM8994_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
+#define WM8994_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
+#define WM8994_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
+#define WM8994_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
+#define WM8994_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
+#define WM8994_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
+#define WM8994_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
+
+/*
+ * R512 (0x200) - AIF1 Clocking (1)
+ */
+#define WM8994_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */
+#define WM8994_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */
+#define WM8994_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */
+#define WM8994_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */
+#define WM8994_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */
+#define WM8994_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */
+#define WM8994_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */
+#define WM8994_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */
+#define WM8994_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */
+#define WM8994_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */
+#define WM8994_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */
+#define WM8994_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */
+#define WM8994_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */
+#define WM8994_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */
+#define WM8994_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */
+
+/*
+ * R513 (0x201) - AIF1 Clocking (2)
+ */
+#define WM8994_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */
+#define WM8994_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */
+#define WM8994_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */
+#define WM8994_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */
+#define WM8994_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */
+#define WM8994_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */
+
+/*
+ * R516 (0x204) - AIF2 Clocking (1)
+ */
+#define WM8994_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */
+#define WM8994_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */
+#define WM8994_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */
+#define WM8994_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */
+#define WM8994_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */
+#define WM8994_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */
+#define WM8994_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */
+#define WM8994_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */
+#define WM8994_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */
+#define WM8994_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */
+#define WM8994_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */
+#define WM8994_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */
+#define WM8994_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */
+#define WM8994_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */
+#define WM8994_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */
+
+/*
+ * R517 (0x205) - AIF2 Clocking (2)
+ */
+#define WM8994_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */
+#define WM8994_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */
+#define WM8994_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */
+#define WM8994_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */
+#define WM8994_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */
+#define WM8994_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */
+
+/*
+ * R520 (0x208) - Clocking (1)
+ */
+#define WM8994_TOCLK_ENA 0x0010 /* TOCLK_ENA */
+#define WM8994_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
+#define WM8994_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
+#define WM8994_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
+#define WM8994_AIF1DSPCLK_ENA 0x0008 /* AIF1DSPCLK_ENA */
+#define WM8994_AIF1DSPCLK_ENA_MASK 0x0008 /* AIF1DSPCLK_ENA */
+#define WM8994_AIF1DSPCLK_ENA_SHIFT 3 /* AIF1DSPCLK_ENA */
+#define WM8994_AIF1DSPCLK_ENA_WIDTH 1 /* AIF1DSPCLK_ENA */
+#define WM8994_AIF2DSPCLK_ENA 0x0004 /* AIF2DSPCLK_ENA */
+#define WM8994_AIF2DSPCLK_ENA_MASK 0x0004 /* AIF2DSPCLK_ENA */
+#define WM8994_AIF2DSPCLK_ENA_SHIFT 2 /* AIF2DSPCLK_ENA */
+#define WM8994_AIF2DSPCLK_ENA_WIDTH 1 /* AIF2DSPCLK_ENA */
+#define WM8994_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
+#define WM8994_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
+#define WM8994_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
+#define WM8994_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
+#define WM8994_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */
+#define WM8994_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */
+#define WM8994_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */
+#define WM8994_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
+
+/*
+ * R521 (0x209) - Clocking (2)
+ */
+#define WM8994_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
+#define WM8994_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
+#define WM8994_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
+#define WM8994_DBCLK_DIV_MASK 0x0070 /* DBCLK_DIV - [6:4] */
+#define WM8994_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [6:4] */
+#define WM8994_DBCLK_DIV_WIDTH 3 /* DBCLK_DIV - [6:4] */
+#define WM8994_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
+#define WM8994_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
+#define WM8994_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
+
+/*
+ * R528 (0x210) - AIF1 Rate
+ */
+#define WM8994_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */
+#define WM8994_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */
+#define WM8994_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */
+#define WM8994_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */
+#define WM8994_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */
+#define WM8994_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */
+
+/*
+ * R529 (0x211) - AIF2 Rate
+ */
+#define WM8994_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */
+#define WM8994_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */
+#define WM8994_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */
+#define WM8994_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */
+#define WM8994_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */
+#define WM8994_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */
+
+/*
+ * R530 (0x212) - Rate Status
+ */
+#define WM8994_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */
+#define WM8994_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */
+#define WM8994_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */
+
+/*
+ * R544 (0x220) - FLL1 Control (1)
+ */
+#define WM8994_FLL1_FRAC 0x0004 /* FLL1_FRAC */
+#define WM8994_FLL1_FRAC_MASK 0x0004 /* FLL1_FRAC */
+#define WM8994_FLL1_FRAC_SHIFT 2 /* FLL1_FRAC */
+#define WM8994_FLL1_FRAC_WIDTH 1 /* FLL1_FRAC */
+#define WM8994_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */
+#define WM8994_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */
+#define WM8994_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */
+#define WM8994_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */
+#define WM8994_FLL1_ENA 0x0001 /* FLL1_ENA */
+#define WM8994_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
+#define WM8994_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
+#define WM8994_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
+
+/*
+ * R545 (0x221) - FLL1 Control (2)
+ */
+#define WM8994_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
+#define WM8994_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
+#define WM8994_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
+#define WM8994_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8994_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8994_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */
+#define WM8994_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
+#define WM8994_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
+#define WM8994_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
+
+/*
+ * R546 (0x222) - FLL1 Control (3)
+ */
+#define WM8994_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */
+#define WM8994_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */
+#define WM8994_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */
+
+/*
+ * R547 (0x223) - FLL1 Control (4)
+ */
+#define WM8994_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */
+#define WM8994_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */
+#define WM8994_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */
+#define WM8994_FLL1_LOOP_GAIN_MASK 0x000F /* FLL1_LOOP_GAIN - [3:0] */
+#define WM8994_FLL1_LOOP_GAIN_SHIFT 0 /* FLL1_LOOP_GAIN - [3:0] */
+#define WM8994_FLL1_LOOP_GAIN_WIDTH 4 /* FLL1_LOOP_GAIN - [3:0] */
+
+/*
+ * R548 (0x224) - FLL1 Control (5)
+ */
+#define WM8994_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */
+#define WM8994_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */
+#define WM8994_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */
+#define WM8994_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */
+#define WM8994_FLL1_REFCLK_DIV_MASK 0x0018 /* FLL1_REFCLK_DIV - [4:3] */
+#define WM8994_FLL1_REFCLK_DIV_SHIFT 3 /* FLL1_REFCLK_DIV - [4:3] */
+#define WM8994_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [4:3] */
+#define WM8994_FLL1_REFCLK_SRC_MASK 0x0003 /* FLL1_REFCLK_SRC - [1:0] */
+#define WM8994_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [1:0] */
+#define WM8994_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */
+
+/*
+ * R576 (0x240) - FLL2 Control (1)
+ */
+#define WM8994_FLL2_FRAC 0x0004 /* FLL2_FRAC */
+#define WM8994_FLL2_FRAC_MASK 0x0004 /* FLL2_FRAC */
+#define WM8994_FLL2_FRAC_SHIFT 2 /* FLL2_FRAC */
+#define WM8994_FLL2_FRAC_WIDTH 1 /* FLL2_FRAC */
+#define WM8994_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */
+#define WM8994_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */
+#define WM8994_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */
+#define WM8994_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */
+#define WM8994_FLL2_ENA 0x0001 /* FLL2_ENA */
+#define WM8994_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
+#define WM8994_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
+#define WM8994_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
+
+/*
+ * R577 (0x241) - FLL2 Control (2)
+ */
+#define WM8994_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
+#define WM8994_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
+#define WM8994_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
+#define WM8994_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8994_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8994_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */
+#define WM8994_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
+#define WM8994_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
+#define WM8994_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
+
+/*
+ * R578 (0x242) - FLL2 Control (3)
+ */
+#define WM8994_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */
+#define WM8994_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */
+#define WM8994_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */
+
+/*
+ * R579 (0x243) - FLL2 Control (4)
+ */
+#define WM8994_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */
+#define WM8994_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */
+#define WM8994_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */
+#define WM8994_FLL2_LOOP_GAIN_MASK 0x000F /* FLL2_LOOP_GAIN - [3:0] */
+#define WM8994_FLL2_LOOP_GAIN_SHIFT 0 /* FLL2_LOOP_GAIN - [3:0] */
+#define WM8994_FLL2_LOOP_GAIN_WIDTH 4 /* FLL2_LOOP_GAIN - [3:0] */
+
+/*
+ * R580 (0x244) - FLL2 Control (5)
+ */
+#define WM8994_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */
+#define WM8994_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */
+#define WM8994_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */
+#define WM8994_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */
+#define WM8994_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */
+#define WM8994_FLL2_REFCLK_DIV_MASK 0x0018 /* FLL2_REFCLK_DIV - [4:3] */
+#define WM8994_FLL2_REFCLK_DIV_SHIFT 3 /* FLL2_REFCLK_DIV - [4:3] */
+#define WM8994_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [4:3] */
+#define WM8994_FLL2_REFCLK_SRC_MASK 0x0003 /* FLL2_REFCLK_SRC - [1:0] */
+#define WM8994_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [1:0] */
+#define WM8994_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */
+
+/*
+ * R768 (0x300) - AIF1 Control (1)
+ */
+#define WM8994_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */
+#define WM8994_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */
+#define WM8994_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */
+#define WM8994_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */
+#define WM8994_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */
+#define WM8994_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */
+#define WM8994_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */
+#define WM8994_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */
+#define WM8994_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */
+#define WM8994_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */
+#define WM8994_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */
+#define WM8994_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */
+#define WM8994_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */
+#define WM8994_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */
+#define WM8994_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */
+#define WM8994_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
+#define WM8994_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */
+#define WM8994_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */
+#define WM8994_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */
+#define WM8994_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
+#define WM8994_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */
+#define WM8994_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */
+#define WM8994_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */
+#define WM8994_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */
+#define WM8994_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */
+#define WM8994_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */
+
+/*
+ * R769 (0x301) - AIF1 Control (2)
+ */
+#define WM8994_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */
+#define WM8994_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */
+#define WM8994_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */
+#define WM8994_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */
+#define WM8994_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */
+#define WM8994_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */
+#define WM8994_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */
+#define WM8994_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */
+#define WM8994_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */
+#define WM8994_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */
+#define WM8994_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */
+#define WM8994_AIF1_MONO 0x0100 /* AIF1_MONO */
+#define WM8994_AIF1_MONO_MASK 0x0100 /* AIF1_MONO */
+#define WM8994_AIF1_MONO_SHIFT 8 /* AIF1_MONO */
+#define WM8994_AIF1_MONO_WIDTH 1 /* AIF1_MONO */
+#define WM8994_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */
+#define WM8994_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */
+#define WM8994_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */
+#define WM8994_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */
+#define WM8994_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */
+#define WM8994_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */
+#define WM8994_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */
+#define WM8994_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */
+#define WM8994_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */
+#define WM8994_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */
+#define WM8994_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */
+#define WM8994_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */
+#define WM8994_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */
+#define WM8994_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */
+#define WM8994_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */
+#define WM8994_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */
+#define WM8994_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */
+#define WM8994_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */
+#define WM8994_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */
+#define WM8994_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */
+
+/*
+ * R770 (0x302) - AIF1 Master/Slave
+ */
+#define WM8994_AIF1_TRI 0x8000 /* AIF1_TRI */
+#define WM8994_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */
+#define WM8994_AIF1_TRI_SHIFT 15 /* AIF1_TRI */
+#define WM8994_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
+#define WM8994_AIF1_MSTR 0x4000 /* AIF1_MSTR */
+#define WM8994_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */
+#define WM8994_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */
+#define WM8994_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */
+#define WM8994_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */
+#define WM8994_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */
+#define WM8994_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */
+#define WM8994_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */
+#define WM8994_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */
+#define WM8994_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */
+#define WM8994_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */
+#define WM8994_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */
+
+/*
+ * R771 (0x303) - AIF1 BCLK
+ */
+#define WM8994_AIF1_BCLK_DIV_MASK 0x01F0 /* AIF1_BCLK_DIV - [8:4] */
+#define WM8994_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [8:4] */
+#define WM8994_AIF1_BCLK_DIV_WIDTH 5 /* AIF1_BCLK_DIV - [8:4] */
+
+/*
+ * R772 (0x304) - AIF1ADC LRCLK
+ */
+#define WM8994_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */
+#define WM8994_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */
+#define WM8994_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */
+#define WM8994_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */
+#define WM8994_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */
+#define WM8994_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */
+#define WM8994_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */
+
+/*
+ * R773 (0x305) - AIF1DAC LRCLK
+ */
+#define WM8994_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */
+#define WM8994_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */
+#define WM8994_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
+#define WM8994_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */
+#define WM8994_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */
+#define WM8994_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */
+#define WM8994_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */
+
+/*
+ * R774 (0x306) - AIF1DAC Data
+ */
+#define WM8994_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */
+#define WM8994_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */
+#define WM8994_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */
+#define WM8994_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */
+#define WM8994_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */
+#define WM8994_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */
+#define WM8994_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */
+#define WM8994_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */
+
+/*
+ * R775 (0x307) - AIF1ADC Data
+ */
+#define WM8994_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */
+#define WM8994_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */
+#define WM8994_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */
+#define WM8994_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */
+#define WM8994_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */
+#define WM8994_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */
+#define WM8994_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */
+#define WM8994_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */
+
+/*
+ * R784 (0x310) - AIF2 Control (1)
+ */
+#define WM8994_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */
+#define WM8994_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */
+#define WM8994_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */
+#define WM8994_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */
+#define WM8994_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */
+#define WM8994_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */
+#define WM8994_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */
+#define WM8994_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */
+#define WM8994_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */
+#define WM8994_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */
+#define WM8994_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */
+#define WM8994_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */
+#define WM8994_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */
+#define WM8994_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */
+#define WM8994_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */
+#define WM8994_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */
+#define WM8994_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */
+#define WM8994_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */
+#define WM8994_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */
+#define WM8994_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
+#define WM8994_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */
+#define WM8994_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */
+#define WM8994_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */
+#define WM8994_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */
+#define WM8994_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */
+#define WM8994_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */
+#define WM8994_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */
+#define WM8994_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */
+#define WM8994_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */
+#define WM8994_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */
+
+/*
+ * R785 (0x311) - AIF2 Control (2)
+ */
+#define WM8994_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */
+#define WM8994_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */
+#define WM8994_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */
+#define WM8994_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */
+#define WM8994_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */
+#define WM8994_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */
+#define WM8994_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */
+#define WM8994_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */
+#define WM8994_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */
+#define WM8994_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */
+#define WM8994_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */
+#define WM8994_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */
+#define WM8994_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */
+#define WM8994_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */
+#define WM8994_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */
+#define WM8994_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */
+#define WM8994_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */
+#define WM8994_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */
+#define WM8994_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */
+#define WM8994_AIF2_MONO 0x0100 /* AIF2_MONO */
+#define WM8994_AIF2_MONO_MASK 0x0100 /* AIF2_MONO */
+#define WM8994_AIF2_MONO_SHIFT 8 /* AIF2_MONO */
+#define WM8994_AIF2_MONO_WIDTH 1 /* AIF2_MONO */
+#define WM8994_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */
+#define WM8994_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */
+#define WM8994_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */
+#define WM8994_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */
+#define WM8994_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */
+#define WM8994_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */
+#define WM8994_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */
+#define WM8994_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */
+#define WM8994_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */
+#define WM8994_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */
+#define WM8994_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */
+#define WM8994_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */
+#define WM8994_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */
+#define WM8994_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */
+#define WM8994_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */
+#define WM8994_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */
+#define WM8994_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */
+#define WM8994_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */
+#define WM8994_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */
+#define WM8994_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */
+
+/*
+ * R786 (0x312) - AIF2 Master/Slave
+ */
+#define WM8994_AIF2_TRI 0x8000 /* AIF2_TRI */
+#define WM8994_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */
+#define WM8994_AIF2_TRI_SHIFT 15 /* AIF2_TRI */
+#define WM8994_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
+#define WM8994_AIF2_MSTR 0x4000 /* AIF2_MSTR */
+#define WM8994_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */
+#define WM8994_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */
+#define WM8994_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */
+#define WM8994_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */
+#define WM8994_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */
+#define WM8994_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */
+#define WM8994_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */
+#define WM8994_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */
+#define WM8994_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */
+#define WM8994_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */
+#define WM8994_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */
+
+/*
+ * R787 (0x313) - AIF2 BCLK
+ */
+#define WM8994_AIF2_BCLK_DIV_MASK 0x01F0 /* AIF2_BCLK_DIV - [8:4] */
+#define WM8994_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [8:4] */
+#define WM8994_AIF2_BCLK_DIV_WIDTH 5 /* AIF2_BCLK_DIV - [8:4] */
+
+/*
+ * R788 (0x314) - AIF2ADC LRCLK
+ */
+#define WM8994_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */
+#define WM8994_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */
+#define WM8994_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */
+#define WM8994_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */
+#define WM8994_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */
+#define WM8994_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */
+#define WM8994_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */
+
+/*
+ * R789 (0x315) - AIF2DAC LRCLK
+ */
+#define WM8994_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */
+#define WM8994_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */
+#define WM8994_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */
+#define WM8994_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */
+#define WM8994_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */
+#define WM8994_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */
+#define WM8994_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */
+
+/*
+ * R790 (0x316) - AIF2DAC Data
+ */
+#define WM8994_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */
+#define WM8994_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */
+#define WM8994_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */
+#define WM8994_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */
+#define WM8994_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */
+#define WM8994_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */
+#define WM8994_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */
+#define WM8994_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */
+
+/*
+ * R791 (0x317) - AIF2ADC Data
+ */
+#define WM8994_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */
+#define WM8994_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */
+#define WM8994_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */
+#define WM8994_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */
+#define WM8994_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */
+#define WM8994_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */
+#define WM8994_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */
+#define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
+
+/*
+ * R1024 (0x400) - AIF1 ADC1 Left Volume
+ */
+#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */
+#define WM8994_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */
+#define WM8994_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */
+
+/*
+ * R1025 (0x401) - AIF1 ADC1 Right Volume
+ */
+#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
+#define WM8994_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */
+#define WM8994_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */
+#define WM8994_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */
+
+/*
+ * R1026 (0x402) - AIF1 DAC1 Left Volume
+ */
+#define WM8994_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */
+#define WM8994_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */
+#define WM8994_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */
+
+/*
+ * R1027 (0x403) - AIF1 DAC1 Right Volume
+ */
+#define WM8994_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
+#define WM8994_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */
+#define WM8994_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */
+#define WM8994_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */
+
+/*
+ * R1028 (0x404) - AIF1 ADC2 Left Volume
+ */
+#define WM8994_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */
+#define WM8994_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */
+#define WM8994_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */
+
+/*
+ * R1029 (0x405) - AIF1 ADC2 Right Volume
+ */
+#define WM8994_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
+#define WM8994_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */
+#define WM8994_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */
+#define WM8994_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */
+
+/*
+ * R1030 (0x406) - AIF1 DAC2 Left Volume
+ */
+#define WM8994_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */
+#define WM8994_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */
+#define WM8994_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */
+
+/*
+ * R1031 (0x407) - AIF1 DAC2 Right Volume
+ */
+#define WM8994_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
+#define WM8994_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */
+#define WM8994_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */
+#define WM8994_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */
+
+/*
+ * R1040 (0x410) - AIF1 ADC1 Filters
+ */
+#define WM8994_AIF1ADC_4FS 0x8000 /* AIF1ADC_4FS */
+#define WM8994_AIF1ADC_4FS_MASK 0x8000 /* AIF1ADC_4FS */
+#define WM8994_AIF1ADC_4FS_SHIFT 15 /* AIF1ADC_4FS */
+#define WM8994_AIF1ADC_4FS_WIDTH 1 /* AIF1ADC_4FS */
+#define WM8994_AIF1ADC1_HPF_CUT_MASK 0x6000 /* AIF1ADC1_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC1_HPF_CUT_SHIFT 13 /* AIF1ADC1_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC1_HPF_CUT_WIDTH 2 /* AIF1ADC1_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */
+#define WM8994_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */
+#define WM8994_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */
+#define WM8994_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */
+#define WM8994_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */
+#define WM8994_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */
+#define WM8994_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */
+#define WM8994_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */
+
+/*
+ * R1041 (0x411) - AIF1 ADC2 Filters
+ */
+#define WM8994_AIF1ADC2_HPF_CUT_MASK 0x6000 /* AIF1ADC2_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC2_HPF_CUT_SHIFT 13 /* AIF1ADC2_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC2_HPF_CUT_WIDTH 2 /* AIF1ADC2_HPF_CUT - [14:13] */
+#define WM8994_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */
+#define WM8994_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */
+#define WM8994_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */
+#define WM8994_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */
+#define WM8994_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */
+#define WM8994_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */
+#define WM8994_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */
+#define WM8994_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */
+
+/*
+ * R1056 (0x420) - AIF1 DAC1 Filters (1)
+ */
+#define WM8994_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */
+#define WM8994_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */
+#define WM8994_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */
+#define WM8994_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */
+#define WM8994_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */
+#define WM8994_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */
+#define WM8994_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */
+#define WM8994_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */
+#define WM8994_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */
+#define WM8994_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8994_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8994_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8994_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */
+#define WM8994_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */
+#define WM8994_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */
+#define WM8994_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */
+
+/*
+ * R1057 (0x421) - AIF1 DAC1 Filters (2)
+ */
+#define WM8994_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */
+#define WM8994_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */
+#define WM8994_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */
+#define WM8994_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */
+
+/*
+ * R1058 (0x422) - AIF1 DAC2 Filters (1)
+ */
+#define WM8994_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */
+#define WM8994_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */
+#define WM8994_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */
+#define WM8994_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */
+#define WM8994_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */
+#define WM8994_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */
+#define WM8994_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */
+#define WM8994_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */
+#define WM8994_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */
+#define WM8994_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8994_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8994_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8994_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */
+#define WM8994_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */
+#define WM8994_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */
+#define WM8994_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */
+
+/*
+ * R1059 (0x423) - AIF1 DAC2 Filters (2)
+ */
+#define WM8994_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */
+#define WM8994_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */
+#define WM8994_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */
+#define WM8994_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */
+#define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
+
+/*
+ * R1088 (0x440) - AIF1 DRC1 (1)
+ */
+#define WM8994_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */
+#define WM8994_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */
+#define WM8994_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */
+#define WM8994_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */
+#define WM8994_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8994_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8994_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8994_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */
+#define WM8994_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */
+#define WM8994_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */
+#define WM8994_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */
+#define WM8994_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */
+#define WM8994_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */
+#define WM8994_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */
+#define WM8994_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */
+#define WM8994_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */
+#define WM8994_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */
+#define WM8994_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */
+#define WM8994_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */
+#define WM8994_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */
+#define WM8994_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */
+#define WM8994_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */
+#define WM8994_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */
+#define WM8994_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */
+#define WM8994_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */
+#define WM8994_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */
+#define WM8994_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */
+#define WM8994_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */
+#define WM8994_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */
+#define WM8994_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */
+#define WM8994_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */
+#define WM8994_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */
+
+/*
+ * R1089 (0x441) - AIF1 DRC1 (2)
+ */
+#define WM8994_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */
+#define WM8994_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */
+#define WM8994_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */
+#define WM8994_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */
+#define WM8994_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */
+#define WM8994_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */
+#define WM8994_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */
+#define WM8994_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */
+#define WM8994_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */
+
+/*
+ * R1090 (0x442) - AIF1 DRC1 (3)
+ */
+#define WM8994_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8994_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8994_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */
+#define WM8994_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */
+#define WM8994_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */
+#define WM8994_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */
+
+/*
+ * R1091 (0x443) - AIF1 DRC1 (4)
+ */
+#define WM8994_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */
+#define WM8994_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */
+#define WM8994_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */
+
+/*
+ * R1092 (0x444) - AIF1 DRC1 (5)
+ */
+#define WM8994_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */
+#define WM8994_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */
+#define WM8994_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */
+
+/*
+ * R1104 (0x450) - AIF1 DRC2 (1)
+ */
+#define WM8994_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */
+#define WM8994_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */
+#define WM8994_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */
+#define WM8994_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */
+#define WM8994_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */
+#define WM8994_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8994_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8994_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8994_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */
+#define WM8994_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */
+#define WM8994_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */
+#define WM8994_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */
+#define WM8994_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */
+#define WM8994_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */
+#define WM8994_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */
+#define WM8994_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */
+#define WM8994_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */
+#define WM8994_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */
+#define WM8994_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */
+#define WM8994_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */
+#define WM8994_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */
+#define WM8994_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */
+#define WM8994_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */
+#define WM8994_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */
+#define WM8994_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */
+#define WM8994_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */
+#define WM8994_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */
+#define WM8994_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */
+#define WM8994_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */
+#define WM8994_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */
+#define WM8994_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */
+#define WM8994_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */
+#define WM8994_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */
+#define WM8994_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */
+
+/*
+ * R1105 (0x451) - AIF1 DRC2 (2)
+ */
+#define WM8994_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */
+#define WM8994_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */
+#define WM8994_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */
+#define WM8994_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */
+#define WM8994_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */
+#define WM8994_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */
+#define WM8994_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */
+#define WM8994_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */
+#define WM8994_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */
+#define WM8994_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */
+
+/*
+ * R1106 (0x452) - AIF1 DRC2 (3)
+ */
+#define WM8994_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */
+#define WM8994_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */
+#define WM8994_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8994_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8994_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */
+#define WM8994_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */
+#define WM8994_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */
+#define WM8994_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */
+#define WM8994_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */
+#define WM8994_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */
+
+/*
+ * R1107 (0x453) - AIF1 DRC2 (4)
+ */
+#define WM8994_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */
+#define WM8994_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */
+#define WM8994_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */
+#define WM8994_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */
+
+/*
+ * R1108 (0x454) - AIF1 DRC2 (5)
+ */
+#define WM8994_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
+#define WM8994_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */
+#define WM8994_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */
+#define WM8994_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */
+
+/*
+ * R1152 (0x480) - AIF1 DAC1 EQ Gains (1)
+ */
+#define WM8994_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */
+#define WM8994_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */
+#define WM8994_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */
+#define WM8994_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */
+
+/*
+ * R1153 (0x481) - AIF1 DAC1 EQ Gains (2)
+ */
+#define WM8994_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A
+ */
+#define WM8994_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */
+
+/*
+ * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B
+ */
+#define WM8994_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */
+
+/*
+ * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */
+
+/*
+ * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A
+ */
+#define WM8994_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */
+
+/*
+ * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B
+ */
+#define WM8994_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */
+
+/*
+ * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C
+ */
+#define WM8994_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */
+
+/*
+ * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */
+
+/*
+ * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A
+ */
+#define WM8994_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */
+
+/*
+ * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B
+ */
+#define WM8994_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */
+
+/*
+ * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C
+ */
+#define WM8994_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */
+
+/*
+ * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */
+
+/*
+ * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A
+ */
+#define WM8994_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */
+
+/*
+ * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B
+ */
+#define WM8994_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */
+
+/*
+ * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C
+ */
+#define WM8994_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */
+
+/*
+ * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */
+
+/*
+ * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A
+ */
+#define WM8994_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */
+
+/*
+ * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B
+ */
+#define WM8994_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */
+
+/*
+ * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG
+ */
+#define WM8994_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */
+#define WM8994_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */
+
+/*
+ * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1)
+ */
+#define WM8994_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */
+#define WM8994_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */
+#define WM8994_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */
+#define WM8994_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */
+
+/*
+ * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2)
+ */
+#define WM8994_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A
+ */
+#define WM8994_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */
+
+/*
+ * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B
+ */
+#define WM8994_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */
+
+/*
+ * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */
+
+/*
+ * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A
+ */
+#define WM8994_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */
+
+/*
+ * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B
+ */
+#define WM8994_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */
+
+/*
+ * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C
+ */
+#define WM8994_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */
+
+/*
+ * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */
+
+/*
+ * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A
+ */
+#define WM8994_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */
+
+/*
+ * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B
+ */
+#define WM8994_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */
+
+/*
+ * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C
+ */
+#define WM8994_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */
+
+/*
+ * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */
+
+/*
+ * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A
+ */
+#define WM8994_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */
+
+/*
+ * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B
+ */
+#define WM8994_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */
+
+/*
+ * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C
+ */
+#define WM8994_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */
+
+/*
+ * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */
+
+/*
+ * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A
+ */
+#define WM8994_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */
+
+/*
+ * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B
+ */
+#define WM8994_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */
+
+/*
+ * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG
+ */
+#define WM8994_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */
+#define WM8994_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */
+
+/*
+ * R1280 (0x500) - AIF2 ADC Left Volume
+ */
+#define WM8994_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
+#define WM8994_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */
+#define WM8994_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */
+#define WM8994_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */
+
+/*
+ * R1281 (0x501) - AIF2 ADC Right Volume
+ */
+#define WM8994_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
+#define WM8994_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
+#define WM8994_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */
+#define WM8994_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */
+#define WM8994_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */
+
+/*
+ * R1282 (0x502) - AIF2 DAC Left Volume
+ */
+#define WM8994_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
+#define WM8994_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */
+#define WM8994_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */
+#define WM8994_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */
+
+/*
+ * R1283 (0x503) - AIF2 DAC Right Volume
+ */
+#define WM8994_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
+#define WM8994_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
+#define WM8994_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */
+#define WM8994_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */
+#define WM8994_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */
+
+/*
+ * R1296 (0x510) - AIF2 ADC Filters
+ */
+#define WM8994_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */
+#define WM8994_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */
+#define WM8994_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */
+#define WM8994_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */
+#define WM8994_AIF2ADC_HPF_CUT_MASK 0x6000 /* AIF2ADC_HPF_CUT - [14:13] */
+#define WM8994_AIF2ADC_HPF_CUT_SHIFT 13 /* AIF2ADC_HPF_CUT - [14:13] */
+#define WM8994_AIF2ADC_HPF_CUT_WIDTH 2 /* AIF2ADC_HPF_CUT - [14:13] */
+#define WM8994_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */
+#define WM8994_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */
+#define WM8994_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */
+#define WM8994_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */
+#define WM8994_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */
+#define WM8994_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */
+#define WM8994_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */
+#define WM8994_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */
+
+/*
+ * R1312 (0x520) - AIF2 DAC Filters (1)
+ */
+#define WM8994_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */
+#define WM8994_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */
+#define WM8994_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */
+#define WM8994_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */
+#define WM8994_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */
+#define WM8994_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */
+#define WM8994_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */
+#define WM8994_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */
+#define WM8994_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */
+#define WM8994_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */
+#define WM8994_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */
+#define WM8994_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */
+#define WM8994_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8994_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8994_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8994_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */
+#define WM8994_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */
+#define WM8994_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */
+#define WM8994_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */
+
+/*
+ * R1313 (0x521) - AIF2 DAC Filters (2)
+ */
+#define WM8994_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8994_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8994_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */
+#define WM8994_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */
+#define WM8994_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */
+#define WM8994_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */
+#define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
+
+/*
+ * R1344 (0x540) - AIF2 DRC (1)
+ */
+#define WM8994_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */
+#define WM8994_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8994_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8994_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */
+#define WM8994_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */
+#define WM8994_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */
+#define WM8994_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */
+#define WM8994_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */
+#define WM8994_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */
+#define WM8994_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */
+#define WM8994_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */
+#define WM8994_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */
+#define WM8994_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */
+#define WM8994_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */
+#define WM8994_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */
+#define WM8994_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */
+#define WM8994_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8994_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8994_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8994_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */
+#define WM8994_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */
+#define WM8994_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */
+#define WM8994_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */
+#define WM8994_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */
+#define WM8994_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */
+#define WM8994_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */
+#define WM8994_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */
+#define WM8994_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */
+#define WM8994_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */
+#define WM8994_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */
+#define WM8994_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */
+#define WM8994_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */
+#define WM8994_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */
+#define WM8994_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */
+#define WM8994_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */
+#define WM8994_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */
+#define WM8994_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */
+#define WM8994_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */
+#define WM8994_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */
+#define WM8994_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */
+
+/*
+ * R1345 (0x541) - AIF2 DRC (2)
+ */
+#define WM8994_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */
+#define WM8994_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */
+#define WM8994_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */
+#define WM8994_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */
+#define WM8994_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */
+#define WM8994_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */
+#define WM8994_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8994_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8994_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */
+#define WM8994_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */
+#define WM8994_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */
+#define WM8994_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */
+
+/*
+ * R1346 (0x542) - AIF2 DRC (3)
+ */
+#define WM8994_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8994_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8994_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */
+#define WM8994_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8994_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8994_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */
+#define WM8994_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8994_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8994_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */
+#define WM8994_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8994_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8994_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */
+#define WM8994_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8994_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8994_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */
+#define WM8994_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */
+#define WM8994_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */
+#define WM8994_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */
+
+/*
+ * R1347 (0x543) - AIF2 DRC (4)
+ */
+#define WM8994_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8994_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8994_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */
+#define WM8994_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */
+#define WM8994_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */
+#define WM8994_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */
+
+/*
+ * R1348 (0x544) - AIF2 DRC (5)
+ */
+#define WM8994_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8994_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8994_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */
+#define WM8994_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */
+#define WM8994_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */
+#define WM8994_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */
+
+/*
+ * R1408 (0x580) - AIF2 EQ Gains (1)
+ */
+#define WM8994_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
+#define WM8994_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */
+#define WM8994_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */
+#define WM8994_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */
+#define WM8994_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */
+
+/*
+ * R1409 (0x581) - AIF2 EQ Gains (2)
+ */
+#define WM8994_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
+#define WM8994_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+#define WM8994_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
+
+/*
+ * R1410 (0x582) - AIF2 EQ Band 1 A
+ */
+#define WM8994_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */
+
+/*
+ * R1411 (0x583) - AIF2 EQ Band 1 B
+ */
+#define WM8994_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */
+
+/*
+ * R1412 (0x584) - AIF2 EQ Band 1 PG
+ */
+#define WM8994_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */
+
+/*
+ * R1413 (0x585) - AIF2 EQ Band 2 A
+ */
+#define WM8994_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */
+
+/*
+ * R1414 (0x586) - AIF2 EQ Band 2 B
+ */
+#define WM8994_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */
+
+/*
+ * R1415 (0x587) - AIF2 EQ Band 2 C
+ */
+#define WM8994_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */
+
+/*
+ * R1416 (0x588) - AIF2 EQ Band 2 PG
+ */
+#define WM8994_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */
+
+/*
+ * R1417 (0x589) - AIF2 EQ Band 3 A
+ */
+#define WM8994_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */
+
+/*
+ * R1418 (0x58A) - AIF2 EQ Band 3 B
+ */
+#define WM8994_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */
+
+/*
+ * R1419 (0x58B) - AIF2 EQ Band 3 C
+ */
+#define WM8994_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */
+
+/*
+ * R1420 (0x58C) - AIF2 EQ Band 3 PG
+ */
+#define WM8994_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */
+
+/*
+ * R1421 (0x58D) - AIF2 EQ Band 4 A
+ */
+#define WM8994_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */
+
+/*
+ * R1422 (0x58E) - AIF2 EQ Band 4 B
+ */
+#define WM8994_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */
+
+/*
+ * R1423 (0x58F) - AIF2 EQ Band 4 C
+ */
+#define WM8994_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */
+
+/*
+ * R1424 (0x590) - AIF2 EQ Band 4 PG
+ */
+#define WM8994_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */
+
+/*
+ * R1425 (0x591) - AIF2 EQ Band 5 A
+ */
+#define WM8994_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */
+
+/*
+ * R1426 (0x592) - AIF2 EQ Band 5 B
+ */
+#define WM8994_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */
+
+/*
+ * R1427 (0x593) - AIF2 EQ Band 5 PG
+ */
+#define WM8994_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */
+#define WM8994_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */
+
+/*
+ * R1536 (0x600) - DAC1 Mixer Volumes
+ */
+#define WM8994_ADCR_DAC1_VOL_MASK 0x01E0 /* ADCR_DAC1_VOL - [8:5] */
+#define WM8994_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [8:5] */
+#define WM8994_ADCR_DAC1_VOL_WIDTH 4 /* ADCR_DAC1_VOL - [8:5] */
+#define WM8994_ADCL_DAC1_VOL_MASK 0x000F /* ADCL_DAC1_VOL - [3:0] */
+#define WM8994_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [3:0] */
+#define WM8994_ADCL_DAC1_VOL_WIDTH 4 /* ADCL_DAC1_VOL - [3:0] */
+
+/*
+ * R1537 (0x601) - DAC1 Left Mixer Routing
+ */
+#define WM8994_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
+#define WM8994_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
+#define WM8994_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
+#define WM8994_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
+#define WM8994_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
+#define WM8994_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
+#define WM8994_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
+#define WM8994_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
+#define WM8994_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */
+#define WM8994_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */
+#define WM8994_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */
+#define WM8994_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */
+#define WM8994_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */
+#define WM8994_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */
+#define WM8994_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */
+#define WM8994_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */
+#define WM8994_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */
+
+/*
+ * R1538 (0x602) - DAC1 Right Mixer Routing
+ */
+#define WM8994_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
+#define WM8994_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
+#define WM8994_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
+#define WM8994_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
+#define WM8994_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
+#define WM8994_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
+#define WM8994_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
+#define WM8994_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
+#define WM8994_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */
+#define WM8994_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */
+#define WM8994_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */
+#define WM8994_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */
+#define WM8994_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */
+#define WM8994_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */
+#define WM8994_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */
+#define WM8994_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */
+#define WM8994_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */
+
+/*
+ * R1539 (0x603) - DAC2 Mixer Volumes
+ */
+#define WM8994_ADCR_DAC2_VOL_MASK 0x01E0 /* ADCR_DAC2_VOL - [8:5] */
+#define WM8994_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [8:5] */
+#define WM8994_ADCR_DAC2_VOL_WIDTH 4 /* ADCR_DAC2_VOL - [8:5] */
+#define WM8994_ADCL_DAC2_VOL_MASK 0x000F /* ADCL_DAC2_VOL - [3:0] */
+#define WM8994_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [3:0] */
+#define WM8994_ADCL_DAC2_VOL_WIDTH 4 /* ADCL_DAC2_VOL - [3:0] */
+
+/*
+ * R1540 (0x604) - DAC2 Left Mixer Routing
+ */
+#define WM8994_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
+#define WM8994_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
+#define WM8994_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
+#define WM8994_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
+#define WM8994_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
+#define WM8994_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
+#define WM8994_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
+#define WM8994_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
+#define WM8994_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */
+#define WM8994_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */
+#define WM8994_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */
+#define WM8994_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */
+#define WM8994_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */
+#define WM8994_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */
+#define WM8994_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */
+#define WM8994_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */
+#define WM8994_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */
+#define WM8994_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */
+#define WM8994_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */
+#define WM8994_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */
+
+/*
+ * R1541 (0x605) - DAC2 Right Mixer Routing
+ */
+#define WM8994_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
+#define WM8994_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
+#define WM8994_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
+#define WM8994_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
+#define WM8994_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
+#define WM8994_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
+#define WM8994_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
+#define WM8994_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
+#define WM8994_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */
+#define WM8994_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */
+#define WM8994_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */
+#define WM8994_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */
+#define WM8994_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */
+#define WM8994_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */
+#define WM8994_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */
+#define WM8994_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */
+#define WM8994_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */
+#define WM8994_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */
+#define WM8994_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */
+#define WM8994_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */
+
+/*
+ * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing
+ */
+#define WM8994_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */
+#define WM8994_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */
+#define WM8994_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */
+#define WM8994_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */
+#define WM8994_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8994_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8994_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */
+#define WM8994_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */
+
+/*
+ * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing
+ */
+#define WM8994_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */
+#define WM8994_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */
+#define WM8994_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */
+#define WM8994_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */
+#define WM8994_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8994_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8994_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */
+#define WM8994_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */
+
+/*
+ * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing
+ */
+#define WM8994_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */
+#define WM8994_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */
+#define WM8994_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */
+#define WM8994_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */
+#define WM8994_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8994_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8994_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */
+#define WM8994_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */
+
+/*
+ * R1545 (0x609) - AIF1 ADC2 Right mixer Routing
+ */
+#define WM8994_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */
+#define WM8994_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */
+#define WM8994_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */
+#define WM8994_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */
+#define WM8994_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8994_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8994_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */
+#define WM8994_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */
+
+/*
+ * R1552 (0x610) - DAC1 Left Volume
+ */
+#define WM8994_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
+#define WM8994_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
+#define WM8994_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
+#define WM8994_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
+#define WM8994_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8994_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8994_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8994_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8994_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
+#define WM8994_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
+#define WM8994_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
+
+/*
+ * R1553 (0x611) - DAC1 Right Volume
+ */
+#define WM8994_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
+#define WM8994_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
+#define WM8994_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
+#define WM8994_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
+#define WM8994_DAC1_VU 0x0100 /* DAC1_VU */
+#define WM8994_DAC1_VU_MASK 0x0100 /* DAC1_VU */
+#define WM8994_DAC1_VU_SHIFT 8 /* DAC1_VU */
+#define WM8994_DAC1_VU_WIDTH 1 /* DAC1_VU */
+#define WM8994_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
+#define WM8994_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
+#define WM8994_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
+
+/*
+ * R1554 (0x612) - DAC2 Left Volume
+ */
+#define WM8994_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
+#define WM8994_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
+#define WM8994_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
+#define WM8994_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
+#define WM8994_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8994_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8994_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8994_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8994_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
+#define WM8994_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
+#define WM8994_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
+
+/*
+ * R1555 (0x613) - DAC2 Right Volume
+ */
+#define WM8994_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
+#define WM8994_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
+#define WM8994_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
+#define WM8994_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
+#define WM8994_DAC2_VU 0x0100 /* DAC2_VU */
+#define WM8994_DAC2_VU_MASK 0x0100 /* DAC2_VU */
+#define WM8994_DAC2_VU_SHIFT 8 /* DAC2_VU */
+#define WM8994_DAC2_VU_WIDTH 1 /* DAC2_VU */
+#define WM8994_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
+#define WM8994_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
+#define WM8994_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
+
+/*
+ * R1556 (0x614) - DAC Softmute
+ */
+#define WM8994_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
+#define WM8994_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
+#define WM8994_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
+#define WM8994_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
+#define WM8994_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
+#define WM8994_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
+#define WM8994_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
+#define WM8994_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
+
+/*
+ * R1568 (0x620) - Oversampling
+ */
+#define WM8994_ADC_OSR128 0x0002 /* ADC_OSR128 */
+#define WM8994_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
+#define WM8994_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
+#define WM8994_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
+#define WM8994_DAC_OSR128 0x0001 /* DAC_OSR128 */
+#define WM8994_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
+#define WM8994_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
+#define WM8994_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
+
+/*
+ * R1569 (0x621) - Sidetone
+ */
+#define WM8994_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
+#define WM8994_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
+#define WM8994_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
+#define WM8994_ST_HPF 0x0040 /* ST_HPF */
+#define WM8994_ST_HPF_MASK 0x0040 /* ST_HPF */
+#define WM8994_ST_HPF_SHIFT 6 /* ST_HPF */
+#define WM8994_ST_HPF_WIDTH 1 /* ST_HPF */
+#define WM8994_STR_SEL 0x0002 /* STR_SEL */
+#define WM8994_STR_SEL_MASK 0x0002 /* STR_SEL */
+#define WM8994_STR_SEL_SHIFT 1 /* STR_SEL */
+#define WM8994_STR_SEL_WIDTH 1 /* STR_SEL */
+#define WM8994_STL_SEL 0x0001 /* STL_SEL */
+#define WM8994_STL_SEL_MASK 0x0001 /* STL_SEL */
+#define WM8994_STL_SEL_SHIFT 0 /* STL_SEL */
+#define WM8994_STL_SEL_WIDTH 1 /* STL_SEL */
+
+/*
+ * R1824 (0x720) - Pull Control (1)
+ */
+#define WM8994_DMICDAT2_PU 0x0800 /* DMICDAT2_PU */
+#define WM8994_DMICDAT2_PU_MASK 0x0800 /* DMICDAT2_PU */
+#define WM8994_DMICDAT2_PU_SHIFT 11 /* DMICDAT2_PU */
+#define WM8994_DMICDAT2_PU_WIDTH 1 /* DMICDAT2_PU */
+#define WM8994_DMICDAT2_PD 0x0400 /* DMICDAT2_PD */
+#define WM8994_DMICDAT2_PD_MASK 0x0400 /* DMICDAT2_PD */
+#define WM8994_DMICDAT2_PD_SHIFT 10 /* DMICDAT2_PD */
+#define WM8994_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
+#define WM8994_DMICDAT1_PU 0x0200 /* DMICDAT1_PU */
+#define WM8994_DMICDAT1_PU_MASK 0x0200 /* DMICDAT1_PU */
+#define WM8994_DMICDAT1_PU_SHIFT 9 /* DMICDAT1_PU */
+#define WM8994_DMICDAT1_PU_WIDTH 1 /* DMICDAT1_PU */
+#define WM8994_DMICDAT1_PD 0x0100 /* DMICDAT1_PD */
+#define WM8994_DMICDAT1_PD_MASK 0x0100 /* DMICDAT1_PD */
+#define WM8994_DMICDAT1_PD_SHIFT 8 /* DMICDAT1_PD */
+#define WM8994_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
+#define WM8994_MCLK1_PU 0x0080 /* MCLK1_PU */
+#define WM8994_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
+#define WM8994_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
+#define WM8994_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
+#define WM8994_MCLK1_PD 0x0040 /* MCLK1_PD */
+#define WM8994_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
+#define WM8994_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
+#define WM8994_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
+#define WM8994_DACDAT1_PU 0x0020 /* DACDAT1_PU */
+#define WM8994_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
+#define WM8994_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
+#define WM8994_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
+#define WM8994_DACDAT1_PD 0x0010 /* DACDAT1_PD */
+#define WM8994_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
+#define WM8994_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
+#define WM8994_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
+#define WM8994_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
+#define WM8994_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
+#define WM8994_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
+#define WM8994_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
+#define WM8994_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
+#define WM8994_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
+#define WM8994_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
+#define WM8994_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
+#define WM8994_BCLK1_PU 0x0002 /* BCLK1_PU */
+#define WM8994_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
+#define WM8994_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
+#define WM8994_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
+#define WM8994_BCLK1_PD 0x0001 /* BCLK1_PD */
+#define WM8994_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
+#define WM8994_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
+#define WM8994_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
+
+/*
+ * R1825 (0x721) - Pull Control (2)
+ */
+#define WM8994_CSNADDR_PD 0x0100 /* CSNADDR_PD */
+#define WM8994_CSNADDR_PD_MASK 0x0100 /* CSNADDR_PD */
+#define WM8994_CSNADDR_PD_SHIFT 8 /* CSNADDR_PD */
+#define WM8994_CSNADDR_PD_WIDTH 1 /* CSNADDR_PD */
+#define WM8994_LDO2ENA_PD 0x0040 /* LDO2ENA_PD */
+#define WM8994_LDO2ENA_PD_MASK 0x0040 /* LDO2ENA_PD */
+#define WM8994_LDO2ENA_PD_SHIFT 6 /* LDO2ENA_PD */
+#define WM8994_LDO2ENA_PD_WIDTH 1 /* LDO2ENA_PD */
+#define WM8994_LDO1ENA_PD 0x0010 /* LDO1ENA_PD */
+#define WM8994_LDO1ENA_PD_MASK 0x0010 /* LDO1ENA_PD */
+#define WM8994_LDO1ENA_PD_SHIFT 4 /* LDO1ENA_PD */
+#define WM8994_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
+#define WM8994_CIFMODE_PD 0x0004 /* CIFMODE_PD */
+#define WM8994_CIFMODE_PD_MASK 0x0004 /* CIFMODE_PD */
+#define WM8994_CIFMODE_PD_SHIFT 2 /* CIFMODE_PD */
+#define WM8994_CIFMODE_PD_WIDTH 1 /* CIFMODE_PD */
+#define WM8994_SPKMODE_PU 0x0002 /* SPKMODE_PU */
+#define WM8994_SPKMODE_PU_MASK 0x0002 /* SPKMODE_PU */
+#define WM8994_SPKMODE_PU_SHIFT 1 /* SPKMODE_PU */
+#define WM8994_SPKMODE_PU_WIDTH 1 /* SPKMODE_PU */
+
+/*
+ * R1840 (0x730) - Interrupt Status 1
+ */
+#define WM8994_GP11_EINT 0x0400 /* GP11_EINT */
+#define WM8994_GP11_EINT_MASK 0x0400 /* GP11_EINT */
+#define WM8994_GP11_EINT_SHIFT 10 /* GP11_EINT */
+#define WM8994_GP11_EINT_WIDTH 1 /* GP11_EINT */
+#define WM8994_GP10_EINT 0x0200 /* GP10_EINT */
+#define WM8994_GP10_EINT_MASK 0x0200 /* GP10_EINT */
+#define WM8994_GP10_EINT_SHIFT 9 /* GP10_EINT */
+#define WM8994_GP10_EINT_WIDTH 1 /* GP10_EINT */
+#define WM8994_GP9_EINT 0x0100 /* GP9_EINT */
+#define WM8994_GP9_EINT_MASK 0x0100 /* GP9_EINT */
+#define WM8994_GP9_EINT_SHIFT 8 /* GP9_EINT */
+#define WM8994_GP9_EINT_WIDTH 1 /* GP9_EINT */
+#define WM8994_GP8_EINT 0x0080 /* GP8_EINT */
+#define WM8994_GP8_EINT_MASK 0x0080 /* GP8_EINT */
+#define WM8994_GP8_EINT_SHIFT 7 /* GP8_EINT */
+#define WM8994_GP8_EINT_WIDTH 1 /* GP8_EINT */
+#define WM8994_GP7_EINT 0x0040 /* GP7_EINT */
+#define WM8994_GP7_EINT_MASK 0x0040 /* GP7_EINT */
+#define WM8994_GP7_EINT_SHIFT 6 /* GP7_EINT */
+#define WM8994_GP7_EINT_WIDTH 1 /* GP7_EINT */
+#define WM8994_GP6_EINT 0x0020 /* GP6_EINT */
+#define WM8994_GP6_EINT_MASK 0x0020 /* GP6_EINT */
+#define WM8994_GP6_EINT_SHIFT 5 /* GP6_EINT */
+#define WM8994_GP6_EINT_WIDTH 1 /* GP6_EINT */
+#define WM8994_GP5_EINT 0x0010 /* GP5_EINT */
+#define WM8994_GP5_EINT_MASK 0x0010 /* GP5_EINT */
+#define WM8994_GP5_EINT_SHIFT 4 /* GP5_EINT */
+#define WM8994_GP5_EINT_WIDTH 1 /* GP5_EINT */
+#define WM8994_GP4_EINT 0x0008 /* GP4_EINT */
+#define WM8994_GP4_EINT_MASK 0x0008 /* GP4_EINT */
+#define WM8994_GP4_EINT_SHIFT 3 /* GP4_EINT */
+#define WM8994_GP4_EINT_WIDTH 1 /* GP4_EINT */
+#define WM8994_GP3_EINT 0x0004 /* GP3_EINT */
+#define WM8994_GP3_EINT_MASK 0x0004 /* GP3_EINT */
+#define WM8994_GP3_EINT_SHIFT 2 /* GP3_EINT */
+#define WM8994_GP3_EINT_WIDTH 1 /* GP3_EINT */
+#define WM8994_GP2_EINT 0x0002 /* GP2_EINT */
+#define WM8994_GP2_EINT_MASK 0x0002 /* GP2_EINT */
+#define WM8994_GP2_EINT_SHIFT 1 /* GP2_EINT */
+#define WM8994_GP2_EINT_WIDTH 1 /* GP2_EINT */
+#define WM8994_GP1_EINT 0x0001 /* GP1_EINT */
+#define WM8994_GP1_EINT_MASK 0x0001 /* GP1_EINT */
+#define WM8994_GP1_EINT_SHIFT 0 /* GP1_EINT */
+#define WM8994_GP1_EINT_WIDTH 1 /* GP1_EINT */
+
+/*
+ * R1841 (0x731) - Interrupt Status 2
+ */
+#define WM8994_TEMP_WARN_EINT 0x8000 /* TEMP_WARN_EINT */
+#define WM8994_TEMP_WARN_EINT_MASK 0x8000 /* TEMP_WARN_EINT */
+#define WM8994_TEMP_WARN_EINT_SHIFT 15 /* TEMP_WARN_EINT */
+#define WM8994_TEMP_WARN_EINT_WIDTH 1 /* TEMP_WARN_EINT */
+#define WM8994_DCS_DONE_EINT 0x4000 /* DCS_DONE_EINT */
+#define WM8994_DCS_DONE_EINT_MASK 0x4000 /* DCS_DONE_EINT */
+#define WM8994_DCS_DONE_EINT_SHIFT 14 /* DCS_DONE_EINT */
+#define WM8994_DCS_DONE_EINT_WIDTH 1 /* DCS_DONE_EINT */
+#define WM8994_WSEQ_DONE_EINT 0x2000 /* WSEQ_DONE_EINT */
+#define WM8994_WSEQ_DONE_EINT_MASK 0x2000 /* WSEQ_DONE_EINT */
+#define WM8994_WSEQ_DONE_EINT_SHIFT 13 /* WSEQ_DONE_EINT */
+#define WM8994_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
+#define WM8994_FIFOS_ERR_EINT 0x1000 /* FIFOS_ERR_EINT */
+#define WM8994_FIFOS_ERR_EINT_MASK 0x1000 /* FIFOS_ERR_EINT */
+#define WM8994_FIFOS_ERR_EINT_SHIFT 12 /* FIFOS_ERR_EINT */
+#define WM8994_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
+#define WM8994_AIF2DRC_SIG_DET_EINT 0x0800 /* AIF2DRC_SIG_DET_EINT */
+#define WM8994_AIF2DRC_SIG_DET_EINT_MASK 0x0800 /* AIF2DRC_SIG_DET_EINT */
+#define WM8994_AIF2DRC_SIG_DET_EINT_SHIFT 11 /* AIF2DRC_SIG_DET_EINT */
+#define WM8994_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* AIF2DRC_SIG_DET_EINT */
+#define WM8994_AIF1DRC2_SIG_DET_EINT 0x0400 /* AIF1DRC2_SIG_DET_EINT */
+#define WM8994_AIF1DRC2_SIG_DET_EINT_MASK 0x0400 /* AIF1DRC2_SIG_DET_EINT */
+#define WM8994_AIF1DRC2_SIG_DET_EINT_SHIFT 10 /* AIF1DRC2_SIG_DET_EINT */
+#define WM8994_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* AIF1DRC2_SIG_DET_EINT */
+#define WM8994_AIF1DRC1_SIG_DET_EINT 0x0200 /* AIF1DRC1_SIG_DET_EINT */
+#define WM8994_AIF1DRC1_SIG_DET_EINT_MASK 0x0200 /* AIF1DRC1_SIG_DET_EINT */
+#define WM8994_AIF1DRC1_SIG_DET_EINT_SHIFT 9 /* AIF1DRC1_SIG_DET_EINT */
+#define WM8994_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* AIF1DRC1_SIG_DET_EINT */
+#define WM8994_SRC2_LOCK_EINT 0x0100 /* SRC2_LOCK_EINT */
+#define WM8994_SRC2_LOCK_EINT_MASK 0x0100 /* SRC2_LOCK_EINT */
+#define WM8994_SRC2_LOCK_EINT_SHIFT 8 /* SRC2_LOCK_EINT */
+#define WM8994_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */
+#define WM8994_SRC1_LOCK_EINT 0x0080 /* SRC1_LOCK_EINT */
+#define WM8994_SRC1_LOCK_EINT_MASK 0x0080 /* SRC1_LOCK_EINT */
+#define WM8994_SRC1_LOCK_EINT_SHIFT 7 /* SRC1_LOCK_EINT */
+#define WM8994_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */
+#define WM8994_FLL2_LOCK_EINT 0x0040 /* FLL2_LOCK_EINT */
+#define WM8994_FLL2_LOCK_EINT_MASK 0x0040 /* FLL2_LOCK_EINT */
+#define WM8994_FLL2_LOCK_EINT_SHIFT 6 /* FLL2_LOCK_EINT */
+#define WM8994_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
+#define WM8994_FLL1_LOCK_EINT 0x0020 /* FLL1_LOCK_EINT */
+#define WM8994_FLL1_LOCK_EINT_MASK 0x0020 /* FLL1_LOCK_EINT */
+#define WM8994_FLL1_LOCK_EINT_SHIFT 5 /* FLL1_LOCK_EINT */
+#define WM8994_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
+#define WM8994_MIC2_SHRT_EINT 0x0010 /* MIC2_SHRT_EINT */
+#define WM8994_MIC2_SHRT_EINT_MASK 0x0010 /* MIC2_SHRT_EINT */
+#define WM8994_MIC2_SHRT_EINT_SHIFT 4 /* MIC2_SHRT_EINT */
+#define WM8994_MIC2_SHRT_EINT_WIDTH 1 /* MIC2_SHRT_EINT */
+#define WM8994_MIC2_DET_EINT 0x0008 /* MIC2_DET_EINT */
+#define WM8994_MIC2_DET_EINT_MASK 0x0008 /* MIC2_DET_EINT */
+#define WM8994_MIC2_DET_EINT_SHIFT 3 /* MIC2_DET_EINT */
+#define WM8994_MIC2_DET_EINT_WIDTH 1 /* MIC2_DET_EINT */
+#define WM8994_MIC1_SHRT_EINT 0x0004 /* MIC1_SHRT_EINT */
+#define WM8994_MIC1_SHRT_EINT_MASK 0x0004 /* MIC1_SHRT_EINT */
+#define WM8994_MIC1_SHRT_EINT_SHIFT 2 /* MIC1_SHRT_EINT */
+#define WM8994_MIC1_SHRT_EINT_WIDTH 1 /* MIC1_SHRT_EINT */
+#define WM8994_MIC1_DET_EINT 0x0002 /* MIC1_DET_EINT */
+#define WM8994_MIC1_DET_EINT_MASK 0x0002 /* MIC1_DET_EINT */
+#define WM8994_MIC1_DET_EINT_SHIFT 1 /* MIC1_DET_EINT */
+#define WM8994_MIC1_DET_EINT_WIDTH 1 /* MIC1_DET_EINT */
+#define WM8994_TEMP_SHUT_EINT 0x0001 /* TEMP_SHUT_EINT */
+#define WM8994_TEMP_SHUT_EINT_MASK 0x0001 /* TEMP_SHUT_EINT */
+#define WM8994_TEMP_SHUT_EINT_SHIFT 0 /* TEMP_SHUT_EINT */
+#define WM8994_TEMP_SHUT_EINT_WIDTH 1 /* TEMP_SHUT_EINT */
+
+/*
+ * R1842 (0x732) - Interrupt Raw Status 2
+ */
+#define WM8994_TEMP_WARN_STS 0x8000 /* TEMP_WARN_STS */
+#define WM8994_TEMP_WARN_STS_MASK 0x8000 /* TEMP_WARN_STS */
+#define WM8994_TEMP_WARN_STS_SHIFT 15 /* TEMP_WARN_STS */
+#define WM8994_TEMP_WARN_STS_WIDTH 1 /* TEMP_WARN_STS */
+#define WM8994_DCS_DONE_STS 0x4000 /* DCS_DONE_STS */
+#define WM8994_DCS_DONE_STS_MASK 0x4000 /* DCS_DONE_STS */
+#define WM8994_DCS_DONE_STS_SHIFT 14 /* DCS_DONE_STS */
+#define WM8994_DCS_DONE_STS_WIDTH 1 /* DCS_DONE_STS */
+#define WM8994_WSEQ_DONE_STS 0x2000 /* WSEQ_DONE_STS */
+#define WM8994_WSEQ_DONE_STS_MASK 0x2000 /* WSEQ_DONE_STS */
+#define WM8994_WSEQ_DONE_STS_SHIFT 13 /* WSEQ_DONE_STS */
+#define WM8994_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
+#define WM8994_FIFOS_ERR_STS 0x1000 /* FIFOS_ERR_STS */
+#define WM8994_FIFOS_ERR_STS_MASK 0x1000 /* FIFOS_ERR_STS */
+#define WM8994_FIFOS_ERR_STS_SHIFT 12 /* FIFOS_ERR_STS */
+#define WM8994_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
+#define WM8994_AIF2DRC_SIG_DET_STS 0x0800 /* AIF2DRC_SIG_DET_STS */
+#define WM8994_AIF2DRC_SIG_DET_STS_MASK 0x0800 /* AIF2DRC_SIG_DET_STS */
+#define WM8994_AIF2DRC_SIG_DET_STS_SHIFT 11 /* AIF2DRC_SIG_DET_STS */
+#define WM8994_AIF2DRC_SIG_DET_STS_WIDTH 1 /* AIF2DRC_SIG_DET_STS */
+#define WM8994_AIF1DRC2_SIG_DET_STS 0x0400 /* AIF1DRC2_SIG_DET_STS */
+#define WM8994_AIF1DRC2_SIG_DET_STS_MASK 0x0400 /* AIF1DRC2_SIG_DET_STS */
+#define WM8994_AIF1DRC2_SIG_DET_STS_SHIFT 10 /* AIF1DRC2_SIG_DET_STS */
+#define WM8994_AIF1DRC2_SIG_DET_STS_WIDTH 1 /* AIF1DRC2_SIG_DET_STS */
+#define WM8994_AIF1DRC1_SIG_DET_STS 0x0200 /* AIF1DRC1_SIG_DET_STS */
+#define WM8994_AIF1DRC1_SIG_DET_STS_MASK 0x0200 /* AIF1DRC1_SIG_DET_STS */
+#define WM8994_AIF1DRC1_SIG_DET_STS_SHIFT 9 /* AIF1DRC1_SIG_DET_STS */
+#define WM8994_AIF1DRC1_SIG_DET_STS_WIDTH 1 /* AIF1DRC1_SIG_DET_STS */
+#define WM8994_SRC2_LOCK_STS 0x0100 /* SRC2_LOCK_STS */
+#define WM8994_SRC2_LOCK_STS_MASK 0x0100 /* SRC2_LOCK_STS */
+#define WM8994_SRC2_LOCK_STS_SHIFT 8 /* SRC2_LOCK_STS */
+#define WM8994_SRC2_LOCK_STS_WIDTH 1 /* SRC2_LOCK_STS */
+#define WM8994_SRC1_LOCK_STS 0x0080 /* SRC1_LOCK_STS */
+#define WM8994_SRC1_LOCK_STS_MASK 0x0080 /* SRC1_LOCK_STS */
+#define WM8994_SRC1_LOCK_STS_SHIFT 7 /* SRC1_LOCK_STS */
+#define WM8994_SRC1_LOCK_STS_WIDTH 1 /* SRC1_LOCK_STS */
+#define WM8994_FLL2_LOCK_STS 0x0040 /* FLL2_LOCK_STS */
+#define WM8994_FLL2_LOCK_STS_MASK 0x0040 /* FLL2_LOCK_STS */
+#define WM8994_FLL2_LOCK_STS_SHIFT 6 /* FLL2_LOCK_STS */
+#define WM8994_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
+#define WM8994_FLL1_LOCK_STS 0x0020 /* FLL1_LOCK_STS */
+#define WM8994_FLL1_LOCK_STS_MASK 0x0020 /* FLL1_LOCK_STS */
+#define WM8994_FLL1_LOCK_STS_SHIFT 5 /* FLL1_LOCK_STS */
+#define WM8994_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
+#define WM8994_MIC2_SHRT_STS 0x0010 /* MIC2_SHRT_STS */
+#define WM8994_MIC2_SHRT_STS_MASK 0x0010 /* MIC2_SHRT_STS */
+#define WM8994_MIC2_SHRT_STS_SHIFT 4 /* MIC2_SHRT_STS */
+#define WM8994_MIC2_SHRT_STS_WIDTH 1 /* MIC2_SHRT_STS */
+#define WM8994_MIC2_DET_STS 0x0008 /* MIC2_DET_STS */
+#define WM8994_MIC2_DET_STS_MASK 0x0008 /* MIC2_DET_STS */
+#define WM8994_MIC2_DET_STS_SHIFT 3 /* MIC2_DET_STS */
+#define WM8994_MIC2_DET_STS_WIDTH 1 /* MIC2_DET_STS */
+#define WM8994_MIC1_SHRT_STS 0x0004 /* MIC1_SHRT_STS */
+#define WM8994_MIC1_SHRT_STS_MASK 0x0004 /* MIC1_SHRT_STS */
+#define WM8994_MIC1_SHRT_STS_SHIFT 2 /* MIC1_SHRT_STS */
+#define WM8994_MIC1_SHRT_STS_WIDTH 1 /* MIC1_SHRT_STS */
+#define WM8994_MIC1_DET_STS 0x0002 /* MIC1_DET_STS */
+#define WM8994_MIC1_DET_STS_MASK 0x0002 /* MIC1_DET_STS */
+#define WM8994_MIC1_DET_STS_SHIFT 1 /* MIC1_DET_STS */
+#define WM8994_MIC1_DET_STS_WIDTH 1 /* MIC1_DET_STS */
+#define WM8994_TEMP_SHUT_STS 0x0001 /* TEMP_SHUT_STS */
+#define WM8994_TEMP_SHUT_STS_MASK 0x0001 /* TEMP_SHUT_STS */
+#define WM8994_TEMP_SHUT_STS_SHIFT 0 /* TEMP_SHUT_STS */
+#define WM8994_TEMP_SHUT_STS_WIDTH 1 /* TEMP_SHUT_STS */
+
+/*
+ * R1848 (0x738) - Interrupt Status 1 Mask
+ */
+#define WM8994_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */
+#define WM8994_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */
+#define WM8994_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */
+#define WM8994_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */
+#define WM8994_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */
+#define WM8994_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */
+#define WM8994_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */
+#define WM8994_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */
+#define WM8994_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */
+#define WM8994_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */
+#define WM8994_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */
+#define WM8994_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */
+#define WM8994_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */
+#define WM8994_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */
+#define WM8994_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */
+#define WM8994_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */
+#define WM8994_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */
+#define WM8994_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */
+#define WM8994_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */
+#define WM8994_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */
+#define WM8994_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
+#define WM8994_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
+#define WM8994_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
+#define WM8994_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
+#define WM8994_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
+#define WM8994_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
+#define WM8994_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
+#define WM8994_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
+#define WM8994_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
+#define WM8994_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
+#define WM8994_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
+#define WM8994_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
+#define WM8994_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
+#define WM8994_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
+#define WM8994_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
+#define WM8994_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
+#define WM8994_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
+#define WM8994_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
+#define WM8994_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
+#define WM8994_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
+#define WM8994_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
+#define WM8994_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
+#define WM8994_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
+#define WM8994_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
+
+/*
+ * R1849 (0x739) - Interrupt Status 2 Mask
+ */
+#define WM8994_IM_TEMP_WARN_EINT 0x8000 /* IM_TEMP_WARN_EINT */
+#define WM8994_IM_TEMP_WARN_EINT_MASK 0x8000 /* IM_TEMP_WARN_EINT */
+#define WM8994_IM_TEMP_WARN_EINT_SHIFT 15 /* IM_TEMP_WARN_EINT */
+#define WM8994_IM_TEMP_WARN_EINT_WIDTH 1 /* IM_TEMP_WARN_EINT */
+#define WM8994_IM_DCS_DONE_EINT 0x4000 /* IM_DCS_DONE_EINT */
+#define WM8994_IM_DCS_DONE_EINT_MASK 0x4000 /* IM_DCS_DONE_EINT */
+#define WM8994_IM_DCS_DONE_EINT_SHIFT 14 /* IM_DCS_DONE_EINT */
+#define WM8994_IM_DCS_DONE_EINT_WIDTH 1 /* IM_DCS_DONE_EINT */
+#define WM8994_IM_WSEQ_DONE_EINT 0x2000 /* IM_WSEQ_DONE_EINT */
+#define WM8994_IM_WSEQ_DONE_EINT_MASK 0x2000 /* IM_WSEQ_DONE_EINT */
+#define WM8994_IM_WSEQ_DONE_EINT_SHIFT 13 /* IM_WSEQ_DONE_EINT */
+#define WM8994_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
+#define WM8994_IM_FIFOS_ERR_EINT 0x1000 /* IM_FIFOS_ERR_EINT */
+#define WM8994_IM_FIFOS_ERR_EINT_MASK 0x1000 /* IM_FIFOS_ERR_EINT */
+#define WM8994_IM_FIFOS_ERR_EINT_SHIFT 12 /* IM_FIFOS_ERR_EINT */
+#define WM8994_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
+#define WM8994_IM_AIF2DRC_SIG_DET_EINT 0x0800 /* IM_AIF2DRC_SIG_DET_EINT */
+#define WM8994_IM_AIF2DRC_SIG_DET_EINT_MASK 0x0800 /* IM_AIF2DRC_SIG_DET_EINT */
+#define WM8994_IM_AIF2DRC_SIG_DET_EINT_SHIFT 11 /* IM_AIF2DRC_SIG_DET_EINT */
+#define WM8994_IM_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* IM_AIF2DRC_SIG_DET_EINT */
+#define WM8994_IM_AIF1DRC2_SIG_DET_EINT 0x0400 /* IM_AIF1DRC2_SIG_DET_EINT */
+#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_MASK 0x0400 /* IM_AIF1DRC2_SIG_DET_EINT */
+#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_SHIFT 10 /* IM_AIF1DRC2_SIG_DET_EINT */
+#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC2_SIG_DET_EINT */
+#define WM8994_IM_AIF1DRC1_SIG_DET_EINT 0x0200 /* IM_AIF1DRC1_SIG_DET_EINT */
+#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_MASK 0x0200 /* IM_AIF1DRC1_SIG_DET_EINT */
+#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_SHIFT 9 /* IM_AIF1DRC1_SIG_DET_EINT */
+#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC1_SIG_DET_EINT */
+#define WM8994_IM_SRC2_LOCK_EINT 0x0100 /* IM_SRC2_LOCK_EINT */
+#define WM8994_IM_SRC2_LOCK_EINT_MASK 0x0100 /* IM_SRC2_LOCK_EINT */
+#define WM8994_IM_SRC2_LOCK_EINT_SHIFT 8 /* IM_SRC2_LOCK_EINT */
+#define WM8994_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */
+#define WM8994_IM_SRC1_LOCK_EINT 0x0080 /* IM_SRC1_LOCK_EINT */
+#define WM8994_IM_SRC1_LOCK_EINT_MASK 0x0080 /* IM_SRC1_LOCK_EINT */
+#define WM8994_IM_SRC1_LOCK_EINT_SHIFT 7 /* IM_SRC1_LOCK_EINT */
+#define WM8994_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */
+#define WM8994_IM_FLL2_LOCK_EINT 0x0040 /* IM_FLL2_LOCK_EINT */
+#define WM8994_IM_FLL2_LOCK_EINT_MASK 0x0040 /* IM_FLL2_LOCK_EINT */
+#define WM8994_IM_FLL2_LOCK_EINT_SHIFT 6 /* IM_FLL2_LOCK_EINT */
+#define WM8994_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
+#define WM8994_IM_FLL1_LOCK_EINT 0x0020 /* IM_FLL1_LOCK_EINT */
+#define WM8994_IM_FLL1_LOCK_EINT_MASK 0x0020 /* IM_FLL1_LOCK_EINT */
+#define WM8994_IM_FLL1_LOCK_EINT_SHIFT 5 /* IM_FLL1_LOCK_EINT */
+#define WM8994_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
+#define WM8994_IM_MIC2_SHRT_EINT 0x0010 /* IM_MIC2_SHRT_EINT */
+#define WM8994_IM_MIC2_SHRT_EINT_MASK 0x0010 /* IM_MIC2_SHRT_EINT */
+#define WM8994_IM_MIC2_SHRT_EINT_SHIFT 4 /* IM_MIC2_SHRT_EINT */
+#define WM8994_IM_MIC2_SHRT_EINT_WIDTH 1 /* IM_MIC2_SHRT_EINT */
+#define WM8994_IM_MIC2_DET_EINT 0x0008 /* IM_MIC2_DET_EINT */
+#define WM8994_IM_MIC2_DET_EINT_MASK 0x0008 /* IM_MIC2_DET_EINT */
+#define WM8994_IM_MIC2_DET_EINT_SHIFT 3 /* IM_MIC2_DET_EINT */
+#define WM8994_IM_MIC2_DET_EINT_WIDTH 1 /* IM_MIC2_DET_EINT */
+#define WM8994_IM_MIC1_SHRT_EINT 0x0004 /* IM_MIC1_SHRT_EINT */
+#define WM8994_IM_MIC1_SHRT_EINT_MASK 0x0004 /* IM_MIC1_SHRT_EINT */
+#define WM8994_IM_MIC1_SHRT_EINT_SHIFT 2 /* IM_MIC1_SHRT_EINT */
+#define WM8994_IM_MIC1_SHRT_EINT_WIDTH 1 /* IM_MIC1_SHRT_EINT */
+#define WM8994_IM_MIC1_DET_EINT 0x0002 /* IM_MIC1_DET_EINT */
+#define WM8994_IM_MIC1_DET_EINT_MASK 0x0002 /* IM_MIC1_DET_EINT */
+#define WM8994_IM_MIC1_DET_EINT_SHIFT 1 /* IM_MIC1_DET_EINT */
+#define WM8994_IM_MIC1_DET_EINT_WIDTH 1 /* IM_MIC1_DET_EINT */
+#define WM8994_IM_TEMP_SHUT_EINT 0x0001 /* IM_TEMP_SHUT_EINT */
+#define WM8994_IM_TEMP_SHUT_EINT_MASK 0x0001 /* IM_TEMP_SHUT_EINT */
+#define WM8994_IM_TEMP_SHUT_EINT_SHIFT 0 /* IM_TEMP_SHUT_EINT */
+#define WM8994_IM_TEMP_SHUT_EINT_WIDTH 1 /* IM_TEMP_SHUT_EINT */
+
+/*
+ * R1856 (0x740) - Interrupt Control
+ */
+#define WM8994_IM_IRQ 0x0001 /* IM_IRQ */
+#define WM8994_IM_IRQ_MASK 0x0001 /* IM_IRQ */
+#define WM8994_IM_IRQ_SHIFT 0 /* IM_IRQ */
+#define WM8994_IM_IRQ_WIDTH 1 /* IM_IRQ */
+
+/*
+ * R1864 (0x748) - IRQ Debounce
+ */
+#define WM8994_TEMP_WARN_DB 0x0020 /* TEMP_WARN_DB */
+#define WM8994_TEMP_WARN_DB_MASK 0x0020 /* TEMP_WARN_DB */
+#define WM8994_TEMP_WARN_DB_SHIFT 5 /* TEMP_WARN_DB */
+#define WM8994_TEMP_WARN_DB_WIDTH 1 /* TEMP_WARN_DB */
+#define WM8994_MIC2_SHRT_DB 0x0010 /* MIC2_SHRT_DB */
+#define WM8994_MIC2_SHRT_DB_MASK 0x0010 /* MIC2_SHRT_DB */
+#define WM8994_MIC2_SHRT_DB_SHIFT 4 /* MIC2_SHRT_DB */
+#define WM8994_MIC2_SHRT_DB_WIDTH 1 /* MIC2_SHRT_DB */
+#define WM8994_MIC2_DET_DB 0x0008 /* MIC2_DET_DB */
+#define WM8994_MIC2_DET_DB_MASK 0x0008 /* MIC2_DET_DB */
+#define WM8994_MIC2_DET_DB_SHIFT 3 /* MIC2_DET_DB */
+#define WM8994_MIC2_DET_DB_WIDTH 1 /* MIC2_DET_DB */
+#define WM8994_MIC1_SHRT_DB 0x0004 /* MIC1_SHRT_DB */
+#define WM8994_MIC1_SHRT_DB_MASK 0x0004 /* MIC1_SHRT_DB */
+#define WM8994_MIC1_SHRT_DB_SHIFT 2 /* MIC1_SHRT_DB */
+#define WM8994_MIC1_SHRT_DB_WIDTH 1 /* MIC1_SHRT_DB */
+#define WM8994_MIC1_DET_DB 0x0002 /* MIC1_DET_DB */
+#define WM8994_MIC1_DET_DB_MASK 0x0002 /* MIC1_DET_DB */
+#define WM8994_MIC1_DET_DB_SHIFT 1 /* MIC1_DET_DB */
+#define WM8994_MIC1_DET_DB_WIDTH 1 /* MIC1_DET_DB */
+#define WM8994_TEMP_SHUT_DB 0x0001 /* TEMP_SHUT_DB */
+#define WM8994_TEMP_SHUT_DB_MASK 0x0001 /* TEMP_SHUT_DB */
+#define WM8994_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */
+#define WM8994_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */
+
+#endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 90957f14195..462acaf36f3 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -783,8 +783,8 @@ struct mm_walk {
int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, struct mm_walk *);
int (*pte_entry)(pte_t *, unsigned long, unsigned long, struct mm_walk *);
int (*pte_hole)(unsigned long, unsigned long, struct mm_walk *);
- int (*hugetlb_entry)(pte_t *, unsigned long, unsigned long,
- struct mm_walk *);
+ int (*hugetlb_entry)(pte_t *, unsigned long,
+ unsigned long, unsigned long, struct mm_walk *);
struct mm_struct *mm;
void *private;
};
@@ -870,6 +870,114 @@ extern int mprotect_fixup(struct vm_area_struct *vma,
*/
int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct page **pages);
+/*
+ * per-process(per-mm_struct) statistics.
+ */
+#if defined(SPLIT_RSS_COUNTING)
+/*
+ * The mm counters are not protected by its page_table_lock,
+ * so must be incremented atomically.
+ */
+static inline void set_mm_counter(struct mm_struct *mm, int member, long value)
+{
+ atomic_long_set(&mm->rss_stat.count[member], value);
+}
+
+unsigned long get_mm_counter(struct mm_struct *mm, int member);
+
+static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
+{
+ atomic_long_add(value, &mm->rss_stat.count[member]);
+}
+
+static inline void inc_mm_counter(struct mm_struct *mm, int member)
+{
+ atomic_long_inc(&mm->rss_stat.count[member]);
+}
+
+static inline void dec_mm_counter(struct mm_struct *mm, int member)
+{
+ atomic_long_dec(&mm->rss_stat.count[member]);
+}
+
+#else /* !USE_SPLIT_PTLOCKS */
+/*
+ * The mm counters are protected by its page_table_lock,
+ * so can be incremented directly.
+ */
+static inline void set_mm_counter(struct mm_struct *mm, int member, long value)
+{
+ mm->rss_stat.count[member] = value;
+}
+
+static inline unsigned long get_mm_counter(struct mm_struct *mm, int member)
+{
+ return mm->rss_stat.count[member];
+}
+
+static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
+{
+ mm->rss_stat.count[member] += value;
+}
+
+static inline void inc_mm_counter(struct mm_struct *mm, int member)
+{
+ mm->rss_stat.count[member]++;
+}
+
+static inline void dec_mm_counter(struct mm_struct *mm, int member)
+{
+ mm->rss_stat.count[member]--;
+}
+
+#endif /* !USE_SPLIT_PTLOCKS */
+
+static inline unsigned long get_mm_rss(struct mm_struct *mm)
+{
+ return get_mm_counter(mm, MM_FILEPAGES) +
+ get_mm_counter(mm, MM_ANONPAGES);
+}
+
+static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm)
+{
+ return max(mm->hiwater_rss, get_mm_rss(mm));
+}
+
+static inline unsigned long get_mm_hiwater_vm(struct mm_struct *mm)
+{
+ return max(mm->hiwater_vm, mm->total_vm);
+}
+
+static inline void update_hiwater_rss(struct mm_struct *mm)
+{
+ unsigned long _rss = get_mm_rss(mm);
+
+ if ((mm)->hiwater_rss < _rss)
+ (mm)->hiwater_rss = _rss;
+}
+
+static inline void update_hiwater_vm(struct mm_struct *mm)
+{
+ if (mm->hiwater_vm < mm->total_vm)
+ mm->hiwater_vm = mm->total_vm;
+}
+
+static inline void setmax_mm_hiwater_rss(unsigned long *maxrss,
+ struct mm_struct *mm)
+{
+ unsigned long hiwater_rss = get_mm_hiwater_rss(mm);
+
+ if (*maxrss < hiwater_rss)
+ *maxrss = hiwater_rss;
+}
+
+#if defined(SPLIT_RSS_COUNTING)
+void sync_mm_rss(struct task_struct *task, struct mm_struct *mm);
+#else
+static inline void sync_mm_rss(struct task_struct *task, struct mm_struct *mm)
+{
+}
+#endif
/*
* A callback you can register to apply pressure to ageable caches.
@@ -1114,7 +1222,7 @@ static inline void vma_nonlinear_insert(struct vm_area_struct *vma,
/* mmap.c */
extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin);
-extern void vma_adjust(struct vm_area_struct *vma, unsigned long start,
+extern int vma_adjust(struct vm_area_struct *vma, unsigned long start,
unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert);
extern struct vm_area_struct *vma_merge(struct mm_struct *,
struct vm_area_struct *prev, unsigned long addr, unsigned long end,
@@ -1357,5 +1465,7 @@ extern void shake_page(struct page *p, int access);
extern atomic_long_t mce_bad_pages;
extern int soft_offline_page(struct page *page, int flags);
+extern void dump_page(struct page *page);
+
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 36f96271306..b8bb9a6a1f3 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -24,12 +24,6 @@ struct address_space;
#define USE_SPLIT_PTLOCKS (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS)
-#if USE_SPLIT_PTLOCKS
-typedef atomic_long_t mm_counter_t;
-#else /* !USE_SPLIT_PTLOCKS */
-typedef unsigned long mm_counter_t;
-#endif /* !USE_SPLIT_PTLOCKS */
-
/*
* Each physical page in the system has a struct page associated with
* it to keep track of whatever it is we are using the page for at the
@@ -169,7 +163,8 @@ struct vm_area_struct {
* can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
* or brk vma (with NULL file) can only be in an anon_vma list.
*/
- struct list_head anon_vma_node; /* Serialized by anon_vma->lock */
+ struct list_head anon_vma_chain; /* Serialized by mmap_sem &
+ * page_table_lock */
struct anon_vma *anon_vma; /* Serialized by page_table_lock */
/* Function pointers to deal with this struct. */
@@ -201,6 +196,29 @@ struct core_state {
struct completion startup;
};
+enum {
+ MM_FILEPAGES,
+ MM_ANONPAGES,
+ MM_SWAPENTS,
+ NR_MM_COUNTERS
+};
+
+#if USE_SPLIT_PTLOCKS && defined(CONFIG_MMU)
+#define SPLIT_RSS_COUNTING
+struct mm_rss_stat {
+ atomic_long_t count[NR_MM_COUNTERS];
+};
+/* per-thread cached information, */
+struct task_rss_stat {
+ int events; /* for synchronization threshold */
+ int count[NR_MM_COUNTERS];
+};
+#else /* !USE_SPLIT_PTLOCKS */
+struct mm_rss_stat {
+ unsigned long count[NR_MM_COUNTERS];
+};
+#endif /* !USE_SPLIT_PTLOCKS */
+
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
struct rb_root mm_rb;
@@ -227,11 +245,6 @@ struct mm_struct {
* by mmlist_lock
*/
- /* Special counters, in some configurations protected by the
- * page_table_lock, in other configurations by being atomic.
- */
- mm_counter_t _file_rss;
- mm_counter_t _anon_rss;
unsigned long hiwater_rss; /* High-watermark of RSS usage */
unsigned long hiwater_vm; /* High-water virtual memory usage */
@@ -244,6 +257,12 @@ struct mm_struct {
unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
+ /*
+ * Special counters, in some configurations protected by the
+ * page_table_lock, in other configurations by being atomic.
+ */
+ struct mm_rss_stat rss_stat;
+
struct linux_binfmt *binfmt;
cpumask_t cpu_vm_mask;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 2ee22e8af11..d02d2c6e0cf 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -99,6 +99,8 @@ struct mmc_card {
#define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
+#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
+ /* for byte mode */
u32 raw_cid[4]; /* raw card CID */
u32 raw_csd[4]; /* raw card CSD */
@@ -139,6 +141,11 @@ static inline int mmc_card_lenient_fn0(const struct mmc_card *c)
return c->quirks & MMC_QUIRK_LENIENT_FN0;
}
+static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c)
+{
+ return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+}
+
#define mmc_card_name(c) ((c)->cid.prod_name)
#define mmc_card_id(c) (dev_name(&(c)->dev))
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index eaf36364b7d..43eaf5ca584 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/mmc/core.h>
+#include <linux/mmc/pm.h>
struct mmc_ios {
unsigned int clock; /* clock rate */
@@ -152,6 +153,8 @@ struct mmc_host {
#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */
#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */
+ mmc_pm_flag_t pm_caps; /* supported pm features */
+
/* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */
@@ -197,6 +200,8 @@ struct mmc_host {
struct task_struct *sdio_irq_thread;
atomic_t sdio_irq_thread_abort;
+ mmc_pm_flag_t pm_flags; /* requested pm features */
+
#ifdef CONFIG_LEDS_TRIGGERS
struct led_trigger *led; /* activity led */
#endif
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index c02c8db7370..8a49cbf0376 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -268,6 +268,7 @@ struct _mmc_csd {
#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_MASK 0x3 /* Mask out reserved and DDR bits */
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
diff --git a/include/linux/mmc/pm.h b/include/linux/mmc/pm.h
new file mode 100644
index 00000000000..d37aac49cf9
--- /dev/null
+++ b/include/linux/mmc/pm.h
@@ -0,0 +1,30 @@
+/*
+ * linux/include/linux/mmc/pm.h
+ *
+ * Author: Nicolas Pitre
+ * Copyright: (C) 2009 Marvell Technology Group 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.
+ */
+
+#ifndef LINUX_MMC_PM_H
+#define LINUX_MMC_PM_H
+
+/*
+ * These flags are used to describe power management features that
+ * some cards (typically SDIO cards) might wish to benefit from when
+ * the host system is being suspended. There are several layers of
+ * abstractions involved, from the host controller driver, to the MMC core
+ * code, to the SDIO core code, to finally get to the actual SDIO function
+ * driver. This file is therefore used for common definitions shared across
+ * all those layers.
+ */
+
+typedef unsigned int mmc_pm_flag_t;
+
+#define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */
+#define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */
+
+#endif
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 47ba464f517..0ebaef577ff 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -95,6 +95,8 @@
#define SDIO_BUS_WIDTH_1BIT 0x00
#define SDIO_BUS_WIDTH_4BIT 0x02
+#define SDIO_BUS_ASYNC_INT 0x20
+
#define SDIO_BUS_CD_DISABLE 0x80 /* disable pull-up on DAT3 (pin 1) */
#define SDIO_CCCR_CAPS 0x08
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index ac3ab683fec..c6c0cceba5f 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -15,6 +15,8 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
+#include <linux/mmc/pm.h>
+
struct mmc_card;
struct sdio_func;
@@ -153,5 +155,8 @@ extern unsigned char sdio_f0_readb(struct sdio_func *func,
extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,
unsigned int addr, int *err_ret);
+extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func);
+extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);
+
#endif
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index a01a103341b..cf9e458e96b 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -306,6 +306,7 @@ struct zone {
* free areas of different sizes
*/
spinlock_t lock;
+ int all_unreclaimable; /* All pages pinned */
#ifdef CONFIG_MEMORY_HOTPLUG
/* see spanned/present_pages for more description */
seqlock_t span_seqlock;
@@ -341,7 +342,7 @@ struct zone {
* prev_priority holds the scanning priority for this zone. It is
* defined as the scanning priority at which we achieved our reclaim
* target at the previous try_to_free_pages() or balance_pgdat()
- * invokation.
+ * invocation.
*
* We use prev_priority as a measure of how much stress page reclaim is
* under - it drives the swappiness decision: whether to unmap mapped
@@ -417,7 +418,6 @@ struct zone {
} ____cacheline_internodealigned_in_smp;
typedef enum {
- ZONE_ALL_UNRECLAIMABLE, /* all pages pinned */
ZONE_RECLAIM_LOCKED, /* prevents concurrent reclaim */
ZONE_OOM_LOCKED, /* zone is in OOM killer zonelist */
} zone_flags_t;
@@ -437,11 +437,6 @@ static inline void zone_clear_flag(struct zone *zone, zone_flags_t flag)
clear_bit(flag, &zone->flags);
}
-static inline int zone_is_all_unreclaimable(const struct zone *zone)
-{
- return test_bit(ZONE_ALL_UNRECLAIMABLE, &zone->flags);
-}
-
static inline int zone_is_reclaim_locked(const struct zone *zone)
{
return test_bit(ZONE_RECLAIM_LOCKED, &zone->flags);
diff --git a/include/linux/module.h b/include/linux/module.h
index dd618eb026a..515d53ae6a7 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -175,6 +175,7 @@ struct notifier_block;
#ifdef CONFIG_MODULES
+extern int modules_disabled; /* for sysctl */
/* Get/put a kernel symbol (calls must be symmetric) */
void *__symbol_get(const char *symbol);
void *__symbol_get_gpl(const char *symbol);
@@ -329,8 +330,11 @@ struct module
struct module_notes_attrs *notes_attrs;
#endif
+#ifdef CONFIG_SMP
/* Per-cpu data. */
- void *percpu;
+ void __percpu *percpu;
+ unsigned int percpu_size;
+#endif
/* The command line arguments (may be mangled). People like
keeping pointers to this stuff */
@@ -364,7 +368,8 @@ struct module
void (*exit)(void);
struct module_ref {
- int count;
+ unsigned int incs;
+ unsigned int decs;
} __percpu *refptr;
#endif
@@ -391,6 +396,7 @@ static inline int module_is_live(struct module *mod)
struct module *__module_text_address(unsigned long addr);
struct module *__module_address(unsigned long addr);
bool is_module_address(unsigned long addr);
+bool is_module_percpu_address(unsigned long addr);
bool is_module_text_address(unsigned long addr);
static inline int within_module_core(unsigned long addr, struct module *mod)
@@ -458,9 +464,9 @@ static inline void __module_get(struct module *module)
{
if (module) {
preempt_disable();
- __this_cpu_inc(module->refptr->count);
+ __this_cpu_inc(module->refptr->incs);
trace_module_get(module, _THIS_IP_,
- __this_cpu_read(module->refptr->count));
+ __this_cpu_read(module->refptr->incs));
preempt_enable();
}
}
@@ -473,11 +479,10 @@ static inline int try_module_get(struct module *module)
preempt_disable();
if (likely(module_is_live(module))) {
- __this_cpu_inc(module->refptr->count);
+ __this_cpu_inc(module->refptr->incs);
trace_module_get(module, _THIS_IP_,
- __this_cpu_read(module->refptr->count));
- }
- else
+ __this_cpu_read(module->refptr->incs));
+ } else
ret = 0;
preempt_enable();
@@ -562,6 +567,11 @@ static inline bool is_module_address(unsigned long addr)
return false;
}
+static inline bool is_module_percpu_address(unsigned long addr)
+{
+ return false;
+}
+
static inline bool is_module_text_address(unsigned long addr)
{
return false;
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index ce38f1caa5e..34066e65fde 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -15,6 +15,7 @@
#define MSDOS_DPB_BITS 4 /* log2(MSDOS_DPB) */
#define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
#define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */
+#define MSDOS_LONGNAME 256 /* maximum name length */
#define CF_LE_W(v) le16_to_cpu(v)
#define CF_LE_L(v) le32_to_cpu(v)
#define CT_LE_W(v) cpu_to_le16(v)
@@ -47,8 +48,8 @@
#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
+#define FAT_LFN_LEN 255 /* maximum long name length */
#define MSDOS_NAME 11 /* maximum name length */
-#define MSDOS_LONGNAME 256 /* maximum name length */
#define MSDOS_SLOTS 21 /* max # of slots for short and long names */
#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */
#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */
diff --git a/include/linux/ncp_fs_sb.h b/include/linux/ncp_fs_sb.h
index 6330fc76b00..5ec9ca67168 100644
--- a/include/linux/ncp_fs_sb.h
+++ b/include/linux/ncp_fs_sb.h
@@ -12,6 +12,7 @@
#include <linux/ncp_mount.h>
#include <linux/net.h>
#include <linux/mutex.h>
+#include <linux/backing-dev.h>
#ifdef __KERNEL__
@@ -127,6 +128,7 @@ struct ncp_server {
size_t len;
__u8 data[128];
} unexpected_packet;
+ struct backing_dev_info bdi;
};
extern void ncp_tcp_rcv_proc(struct work_struct *work);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c79a88be7c3..fa8b4763799 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2059,12 +2059,12 @@ static inline void skb_bond_set_mac_by_master(struct sk_buff *skb,
* duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
* ARP on active-backup slaves with arp_validate enabled.
*/
-static inline int skb_bond_should_drop(struct sk_buff *skb)
+static inline int skb_bond_should_drop(struct sk_buff *skb,
+ struct net_device *master)
{
- struct net_device *dev = skb->dev;
- struct net_device *master = dev->master;
-
if (master) {
+ struct net_device *dev = skb->dev;
+
if (master->priv_flags & IFF_MASTER_ARPMON)
dev->last_rx = jiffies;
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 53923868c9b..361d6b5630e 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -76,7 +76,7 @@ extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n);
extern int nfnetlink_has_listeners(struct net *net, unsigned int group);
extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group,
int echo, gfp_t flags);
-extern void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error);
+extern int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error);
extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags);
extern void nfnl_lock(void);
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index d654873aa25..1f7e300094c 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -59,6 +59,7 @@
enum nf_ip6_hook_priorities {
NF_IP6_PRI_FIRST = INT_MIN,
NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
+ NF_IP6_PRI_RAW = -300,
NF_IP6_PRI_SELINUX_FIRST = -225,
NF_IP6_PRI_CONNTRACK = -200,
NF_IP6_PRI_MANGLE = -150,
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index fde27c01732..6eaca5e1e8c 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -188,7 +188,7 @@ extern int netlink_has_listeners(struct sock *sk, unsigned int group);
extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
__u32 group, gfp_t allocation);
-extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
+extern int netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
extern int netlink_register_notifier(struct notifier_block *nb);
extern int netlink_unregister_notifier(struct notifier_block *nb);
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index d09db1bc908..07ce4609fe5 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -33,9 +33,6 @@
#define FLUSH_STABLE 4 /* commit to stable storage */
#define FLUSH_LOWPRI 8 /* low priority background flush */
#define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */
-#define FLUSH_NOCOMMIT 32 /* Don't send the NFSv3/v4 COMMIT */
-#define FLUSH_INVALIDATE 64 /* Invalidate the page cache */
-#define FLUSH_NOWRITEPAGE 128 /* Don't call writepage() */
#ifdef __KERNEL__
@@ -166,6 +163,7 @@ struct nfs_inode {
struct radix_tree_root nfs_page_tree;
unsigned long npages;
+ unsigned long ncommit;
/* Open contexts for shared mmap writes */
struct list_head open_files;
@@ -211,6 +209,7 @@ struct nfs_inode {
#define NFS_INO_FLUSHING (4) /* inode is flushing out data */
#define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */
#define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */
+#define NFS_INO_COMMIT (7) /* inode is committing unstable writes */
static inline struct nfs_inode *NFS_I(const struct inode *inode)
{
@@ -349,7 +348,6 @@ extern int nfs_attribute_timeout(struct inode *inode);
extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
-extern int nfs_revalidate_mapping_nolock(struct inode *inode, struct address_space *mapping);
extern int nfs_setattr(struct dentry *, struct iattr *);
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);
@@ -477,21 +475,12 @@ extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
* Try to write back everything synchronously (but check the
* return value!)
*/
-extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_control *, int);
extern int nfs_wb_all(struct inode *inode);
-extern int nfs_wb_nocommit(struct inode *inode);
extern int nfs_wb_page(struct inode *inode, struct page* page);
extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-extern int nfs_commit_inode(struct inode *, int);
extern struct nfs_write_data *nfs_commitdata_alloc(void);
extern void nfs_commit_free(struct nfs_write_data *wdata);
-#else
-static inline int
-nfs_commit_inode(struct inode *inode, int how)
-{
- return 0;
-}
#endif
static inline int
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 6a2e44fd75e..e82957acea5 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -176,6 +176,7 @@ struct nfs_server {
#define NFS_CAP_ATIME (1U << 11)
#define NFS_CAP_CTIME (1U << 12)
#define NFS_CAP_MTIME (1U << 13)
+#define NFS_CAP_POSIX_LOCK (1U << 14)
/* maximum number of slots to use */
@@ -193,6 +194,8 @@ struct nfs4_slot_table {
int max_slots; /* # slots in table */
int highest_used_slotid; /* sent to server on each SEQ.
* op for dynamic resizing */
+ int target_max_slots; /* Set by CB_RECALL_SLOT as
+ * the new max_slots */
};
static inline int slot_idx(struct nfs4_slot_table *tbl, struct nfs4_slot *sp)
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 454997cccbd..dba35e41337 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -69,8 +69,6 @@
* int node_online(node) Is some node online?
* int node_possible(node) Is some node possible?
*
- * int any_online_node(mask) First online node in mask
- *
* node_set_online(node) set bit 'node' in node_online_map
* node_set_offline(node) clear bit 'node' in node_online_map
*
@@ -467,15 +465,6 @@ static inline int num_node_state(enum node_states state)
#define node_online_map node_states[N_ONLINE]
#define node_possible_map node_states[N_POSSIBLE]
-#define any_online_node(mask) \
-({ \
- int node; \
- for_each_node_mask(node, (mask)) \
- if (node_online(node)) \
- break; \
- node; \
-})
-
#define num_online_nodes() num_node_state(N_ONLINE)
#define num_possible_nodes() num_node_state(N_POSSIBLE)
#define node_online(node) node_state((node), N_ONLINE)
@@ -494,7 +483,7 @@ static inline int num_node_state(enum node_states state)
type *name = kmalloc(sizeof(*name), gfp_flags)
#define NODEMASK_FREE(m) kfree(m)
#else
-#define NODEMASK_ALLOC(type, name, gfp_flags) type _name, *name = &_name
+#define NODEMASK_ALLOC(type, name, gfp_flags) type _##name, *name = &_##name
#define NODEMASK_FREE(m) do {} while (0)
#endif
diff --git a/include/linux/of.h b/include/linux/of.h
index f6d9cbc39c9..a367e19bb3a 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -127,7 +127,7 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
/* Default string compare functions, Allow arch asm/prom.h to override */
#if !defined(of_compat_cmp)
-#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
+#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
#endif
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h
index b0e4eb12623..aef22ae2af4 100644
--- a/include/linux/page_cgroup.h
+++ b/include/linux/page_cgroup.h
@@ -39,6 +39,7 @@ enum {
PCG_CACHE, /* charged as cache */
PCG_USED, /* this object is in use. */
PCG_ACCT_LRU, /* page has been accounted for */
+ PCG_FILE_MAPPED, /* page is accounted as "mapped" */
};
#define TESTPCGFLAG(uname, lname) \
@@ -73,6 +74,11 @@ CLEARPCGFLAG(AcctLRU, ACCT_LRU)
TESTPCGFLAG(AcctLRU, ACCT_LRU)
TESTCLEARPCGFLAG(AcctLRU, ACCT_LRU)
+
+SETPCGFLAG(FileMapped, FILE_MAPPED)
+CLEARPCGFLAG(FileMapped, FILE_MAPPED)
+TESTPCGFLAG(FileMapped, FILE_MAPPED)
+
static inline int page_cgroup_nid(struct page_cgroup *pc)
{
return page_to_nid(pc->page);
@@ -118,6 +124,8 @@ static inline void __init page_cgroup_init_flatmem(void)
#include <linux/swap.h>
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
+extern unsigned short swap_cgroup_cmpxchg(swp_entry_t ent,
+ unsigned short old, unsigned short new);
extern unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id);
extern unsigned short lookup_swap_cgroup(swp_entry_t ent);
extern int swap_cgroup_swapon(int type, unsigned long max_pages);
diff --git a/include/linux/pci-dma.h b/include/linux/pci-dma.h
new file mode 100644
index 00000000000..549a041f9c0
--- /dev/null
+++ b/include/linux/pci-dma.h
@@ -0,0 +1,11 @@
+#ifndef _LINUX_PCI_DMA_H
+#define _LINUX_PCI_DMA_H
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) DEFINE_DMA_UNMAP_ADDR(ADDR_NAME);
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) DEFINE_DMA_UNMAP_LEN(LEN_NAME);
+#define pci_unmap_addr dma_unmap_addr
+#define pci_unmap_addr_set dma_unmap_addr_set
+#define pci_unmap_len dma_unmap_len
+#define pci_unmap_len_set dma_unmap_len_set
+
+#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ec95ebe629f..a788fa12ff3 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -678,6 +678,8 @@ enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *dev);
int pci_find_capability(struct pci_dev *dev, int cap);
int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap);
int pci_find_ext_capability(struct pci_dev *dev, int cap);
+int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn,
+ int cap);
int pci_find_ht_capability(struct pci_dev *dev, int ht_cap);
int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
@@ -767,8 +769,6 @@ int pci_try_set_mwi(struct pci_dev *dev);
void pci_clear_mwi(struct pci_dev *dev);
void pci_intx(struct pci_dev *dev, int enable);
void pci_msi_off(struct pci_dev *dev);
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
-int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);
int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask);
int pcix_get_max_mmrbc(struct pci_dev *dev);
@@ -902,6 +902,7 @@ int pci_set_vga_state(struct pci_dev *pdev, bool decode,
unsigned int command_bits, bool change_bridge);
/* kmem_cache style wrapper around pci_alloc_consistent() */
+#include <linux/pci-dma.h>
#include <linux/dmapool.h>
#define pci_pool dma_pool
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 9f2ad0aa3c3..c8f302991b6 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -507,6 +507,7 @@
#define PCI_EXT_CAP_ID_VC 2
#define PCI_EXT_CAP_ID_DSN 3
#define PCI_EXT_CAP_ID_PWR 4
+#define PCI_EXT_CAP_ID_VNDR 11
#define PCI_EXT_CAP_ID_ACS 13
#define PCI_EXT_CAP_ID_ARI 14
#define PCI_EXT_CAP_ID_ATS 15
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index a93e5bfdccb..d3a38d68710 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -2,10 +2,10 @@
#define __LINUX_PERCPU_H
#include <linux/preempt.h>
-#include <linux/slab.h> /* For kmalloc() */
#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/pfn.h>
+#include <linux/init.h>
#include <asm/percpu.h>
@@ -135,9 +135,7 @@ extern int __init pcpu_page_first_chunk(size_t reserved_size,
#define per_cpu_ptr(ptr, cpu) SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)))
extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align);
-extern void __percpu *__alloc_percpu(size_t size, size_t align);
-extern void free_percpu(void __percpu *__pdata);
-extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
+extern bool is_kernel_percpu_address(unsigned long addr);
#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
extern void __init setup_per_cpu_areas(void);
@@ -147,25 +145,10 @@ extern void __init setup_per_cpu_areas(void);
#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
-static inline void __percpu *__alloc_percpu(size_t size, size_t align)
+/* can't distinguish from other static vars, always false */
+static inline bool is_kernel_percpu_address(unsigned long addr)
{
- /*
- * Can't easily make larger alignment work with kmalloc. WARN
- * on it. Larger alignment should only be used for module
- * percpu sections on SMP for which this path isn't used.
- */
- WARN_ON_ONCE(align > SMP_CACHE_BYTES);
- return kzalloc(size, GFP_KERNEL);
-}
-
-static inline void free_percpu(void __percpu *p)
-{
- kfree(p);
-}
-
-static inline phys_addr_t per_cpu_ptr_to_phys(void *addr)
-{
- return __pa(addr);
+ return false;
}
static inline void __init setup_per_cpu_areas(void) { }
@@ -177,6 +160,10 @@ static inline void *pcpu_lpage_remapped(void *kaddr)
#endif /* CONFIG_SMP */
+extern void __percpu *__alloc_percpu(size_t size, size_t align);
+extern void free_percpu(void __percpu *__pdata);
+extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
+
#define alloc_percpu(type) \
(typeof(type) __percpu *)__alloc_percpu(sizeof(type), __alignof__(type))
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 7b18b4fd5df..c8e37544040 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -452,6 +452,8 @@ enum perf_callchain_context {
#include <linux/fs.h>
#include <linux/pid_namespace.h>
#include <linux/workqueue.h>
+#include <linux/ftrace.h>
+#include <linux/cpu.h>
#include <asm/atomic.h>
#define PERF_MAX_STACK_DEPTH 255
@@ -487,9 +489,8 @@ struct hw_perf_event {
struct hrtimer hrtimer;
};
#ifdef CONFIG_HAVE_HW_BREAKPOINT
- union { /* breakpoint */
- struct arch_hw_breakpoint info;
- };
+ /* breakpoint */
+ struct arch_hw_breakpoint info;
#endif
};
atomic64_t prev_count;
@@ -802,6 +803,13 @@ struct perf_sample_data {
struct perf_raw_record *raw;
};
+static inline
+void perf_sample_data_init(struct perf_sample_data *data, u64 addr)
+{
+ data->addr = addr;
+ data->raw = NULL;
+}
+
extern void perf_output_sample(struct perf_output_handle *handle,
struct perf_event_header *header,
struct perf_sample_data *data,
@@ -834,11 +842,56 @@ extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX];
extern void __perf_sw_event(u32, u64, int, struct pt_regs *, u64);
+extern void
+perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip);
+
+/*
+ * Take a snapshot of the regs. Skip ip and frame pointer to
+ * the nth caller. We only need a few of the regs:
+ * - ip for PERF_SAMPLE_IP
+ * - cs for user_mode() tests
+ * - bp for callchains
+ * - eflags, for future purposes, just in case
+ */
+static inline void perf_fetch_caller_regs(struct pt_regs *regs, int skip)
+{
+ unsigned long ip;
+
+ memset(regs, 0, sizeof(*regs));
+
+ switch (skip) {
+ case 1 :
+ ip = CALLER_ADDR0;
+ break;
+ case 2 :
+ ip = CALLER_ADDR1;
+ break;
+ case 3 :
+ ip = CALLER_ADDR2;
+ break;
+ case 4:
+ ip = CALLER_ADDR3;
+ break;
+ /* No need to support further for now */
+ default:
+ ip = 0;
+ }
+
+ return perf_arch_fetch_caller_regs(regs, ip, skip);
+}
+
static inline void
perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr)
{
- if (atomic_read(&perf_swevent_enabled[event_id]))
+ if (atomic_read(&perf_swevent_enabled[event_id])) {
+ struct pt_regs hot_regs;
+
+ if (!regs) {
+ perf_fetch_caller_regs(&hot_regs, 1);
+ regs = &hot_regs;
+ }
__perf_sw_event(event_id, nr, nmi, regs, addr);
+ }
}
extern void __perf_event_mmap(struct vm_area_struct *vma);
@@ -858,8 +911,24 @@ extern int sysctl_perf_event_paranoid;
extern int sysctl_perf_event_mlock;
extern int sysctl_perf_event_sample_rate;
+static inline bool perf_paranoid_tracepoint_raw(void)
+{
+ return sysctl_perf_event_paranoid > -1;
+}
+
+static inline bool perf_paranoid_cpu(void)
+{
+ return sysctl_perf_event_paranoid > 0;
+}
+
+static inline bool perf_paranoid_kernel(void)
+{
+ return sysctl_perf_event_paranoid > 1;
+}
+
extern void perf_event_init(void);
-extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record, int entry_size);
+extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
+ int entry_size, struct pt_regs *regs);
extern void perf_bp_event(struct perf_event *event, void *data);
#ifndef perf_misc_flags
@@ -915,5 +984,21 @@ static inline void perf_event_disable(struct perf_event *event) { }
#define perf_output_put(handle, x) \
perf_output_copy((handle), &(x), sizeof(x))
+/*
+ * This has to have a higher priority than migration_notifier in sched.c.
+ */
+#define perf_cpu_notifier(fn) \
+do { \
+ static struct notifier_block fn##_nb __cpuinitdata = \
+ { .notifier_call = fn, .priority = 20 }; \
+ fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE, \
+ (void *)(unsigned long)smp_processor_id()); \
+ fn(&fn##_nb, (unsigned long)CPU_STARTING, \
+ (void *)(unsigned long)smp_processor_id()); \
+ fn(&fn##_nb, (unsigned long)CPU_ONLINE, \
+ (void *)(unsigned long)smp_processor_id()); \
+ register_cpu_notifier(&fn##_nb); \
+} while (0)
+
#endif /* __KERNEL__ */
#endif /* _LINUX_PERF_EVENT_H */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 71ff887ca44..212da17d06a 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -21,7 +21,7 @@ struct platform_device {
u32 num_resources;
struct resource * resource;
- struct platform_device_id *id_entry;
+ const struct platform_device_id *id_entry;
/* arch specific additions */
struct pdev_archdata archdata;
@@ -62,7 +62,7 @@ struct platform_driver {
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
- struct platform_device_id *id_table;
+ const struct platform_device_id *id_table;
};
extern int platform_driver_register(struct platform_driver *);
@@ -77,6 +77,11 @@ extern int platform_driver_probe(struct platform_driver *driver,
#define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
#define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data))
+extern struct platform_device *platform_create_bundle(struct platform_driver *driver,
+ int (*probe)(struct platform_device *),
+ struct resource *res, unsigned int n_res,
+ const void *data, size_t size);
+
/* early platform driver interface */
struct early_platform_driver {
const char *class_str;
diff --git a/include/linux/pm.h b/include/linux/pm.h
index e80df06ad22..8e258c72797 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -215,20 +215,59 @@ struct dev_pm_ops {
int (*runtime_idle)(struct device *dev);
};
+#ifdef CONFIG_PM_SLEEP
+#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
+ .suspend = suspend_fn, \
+ .resume = resume_fn, \
+ .freeze = suspend_fn, \
+ .thaw = resume_fn, \
+ .poweroff = suspend_fn, \
+ .restore = resume_fn,
+#else
+#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
+ .runtime_suspend = suspend_fn, \
+ .runtime_resume = resume_fn, \
+ .runtime_idle = idle_fn,
+#else
+#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn)
+#endif
+
/*
* Use this if you want to use the same suspend and resume callbacks for suspend
* to RAM and hibernation.
*/
#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
const struct dev_pm_ops name = { \
- .suspend = suspend_fn, \
- .resume = resume_fn, \
- .freeze = suspend_fn, \
- .thaw = resume_fn, \
- .poweroff = suspend_fn, \
- .restore = resume_fn, \
+ SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
+}
+
+/*
+ * Use this for defining a set of PM operations to be used in all situations
+ * (sustem suspend, hibernation or runtime PM).
+ */
+#define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
+const struct dev_pm_ops name = { \
+ SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
+ SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
}
+/*
+ * Use this for subsystems (bus types, device types, device classes) that don't
+ * need any special suspend/resume handling in addition to invoking the PM
+ * callbacks provided by device drivers supporting both the system sleep PM and
+ * runtime PM, make the pm member point to generic_subsys_pm_ops.
+ */
+#ifdef CONFIG_PM_OPS
+extern struct dev_pm_ops generic_subsys_pm_ops;
+#define GENERIC_SUBSYS_PM_OPS (&generic_subsys_pm_ops)
+#else
+#define GENERIC_SUBSYS_PM_OPS NULL
+#endif
+
/**
* PM_EVENT_ messages
*
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 7d773aac531..b776db73724 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -62,6 +62,11 @@ static inline void device_set_run_wake(struct device *dev, bool enable)
dev->power.run_wake = enable;
}
+static inline bool pm_runtime_suspended(struct device *dev)
+{
+ return dev->power.runtime_status == RPM_SUSPENDED;
+}
+
#else /* !CONFIG_PM_RUNTIME */
static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; }
@@ -89,6 +94,7 @@ static inline void pm_runtime_get_noresume(struct device *dev) {}
static inline void pm_runtime_put_noidle(struct device *dev) {}
static inline bool device_run_wake(struct device *dev) { return false; }
static inline void device_set_run_wake(struct device *dev, bool enable) {}
+static inline bool pm_runtime_suspended(struct device *dev) { return false; }
#endif /* !CONFIG_PM_RUNTIME */
diff --git a/include/linux/poison.h b/include/linux/poison.h
index 2110a81c5e2..34066ffd893 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -48,6 +48,15 @@
#define POISON_FREE 0x6b /* for use-after-free poisoning */
#define POISON_END 0xa5 /* end-byte of poisoning */
+/********** mm/hugetlb.c **********/
+/*
+ * Private mappings of hugetlb pages use this poisoned value for
+ * page->mapping. The core VM should not be doing anything with this mapping
+ * but futex requires the existence of some page->mapping value even though it
+ * is unused if PAGE_MAPPING_ANON is set.
+ */
+#define HUGETLB_POISON ((void *)(0x00300300 + POISON_POINTER_DELTA + PAGE_MAPPING_ANON))
+
/********** arch/$ARCH/mm/init.c **********/
#define POISON_FREE_INITMEM 0xcc
diff --git a/include/linux/poll.h b/include/linux/poll.h
index 6673743946f..600cc1fde64 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -10,8 +10,10 @@
#include <linux/wait.h>
#include <linux/string.h>
#include <linux/fs.h>
+#include <linux/sysctl.h>
#include <asm/uaccess.h>
+extern struct ctl_table epoll_table[]; /* for sysctl */
/* ~832 bytes of stack space used max in sys_select/sys_poll before allocating
additional memory. */
#define MAX_STACK_ALLOC 832
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index b5d096d3a9b..ebd2b8fb00d 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -82,6 +82,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MAX,
POWER_SUPPLY_PROP_VOLTAGE_MIN,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index c5eab89da51..e1fb6072997 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -264,6 +264,9 @@ static inline void user_enable_single_step(struct task_struct *task)
static inline void user_disable_single_step(struct task_struct *task)
{
}
+#else
+extern void user_enable_single_step(struct task_struct *);
+extern void user_disable_single_step(struct task_struct *);
#endif /* arch_has_single_step */
#ifndef arch_has_block_step
@@ -291,6 +294,8 @@ static inline void user_enable_block_step(struct task_struct *task)
{
BUG(); /* This can never be called. */
}
+#else
+extern void user_enable_block_step(struct task_struct *);
#endif /* arch_has_block_step */
#ifdef ARCH_HAS_USER_SINGLE_STEP_INFO
diff --git a/include/linux/quota.h b/include/linux/quota.h
index a6861f11748..b462916b2a0 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -279,9 +279,6 @@ struct dquot {
struct mem_dqblk dq_dqb; /* Diskquota usage */
};
-#define QUOTA_OK 0
-#define NO_QUOTA 1
-
/* Operations which must be implemented by each quota format */
struct quota_format_ops {
int (*check_quota_file)(struct super_block *sb, int type); /* Detect whether file is in our format */
@@ -295,13 +292,6 @@ struct quota_format_ops {
/* Operations working with dquots */
struct dquot_operations {
- int (*initialize) (struct inode *, int);
- int (*drop) (struct inode *);
- int (*alloc_space) (struct inode *, qsize_t, int);
- int (*alloc_inode) (const struct inode *, qsize_t);
- int (*free_space) (struct inode *, qsize_t);
- int (*free_inode) (const struct inode *, qsize_t);
- int (*transfer) (struct inode *, struct iattr *);
int (*write_dquot) (struct dquot *); /* Ordinary dquot write */
struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */
void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */
@@ -309,12 +299,6 @@ struct dquot_operations {
int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */
int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */
int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */
- /* reserve quota for delayed block allocation */
- int (*reserve_space) (struct inode *, qsize_t, int);
- /* claim reserved quota for delayed alloc */
- int (*claim_space) (struct inode *, qsize_t);
- /* release rsved quota for delayed alloc */
- void (*release_rsv) (struct inode *, qsize_t);
/* get reserved quota for delayed alloc, value returned is managed by
* quota code only */
qsize_t *(*get_reserved_space) (struct inode *);
@@ -324,7 +308,7 @@ struct dquot_operations {
struct quotactl_ops {
int (*quota_on)(struct super_block *, int, int, char *, int);
int (*quota_off)(struct super_block *, int, int);
- int (*quota_sync)(struct super_block *, int);
+ int (*quota_sync)(struct super_block *, int, int);
int (*get_info)(struct super_block *, int, struct if_dqinfo *);
int (*set_info)(struct super_block *, int, struct if_dqinfo *);
int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
@@ -357,26 +341,25 @@ enum {
#define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
DQUOT_SUSPENDED)
/* Other quota flags */
-#define DQUOT_QUOTA_SYS_FILE (1 << 6) /* Quota file is a special
+#define DQUOT_STATE_LAST (_DQUOT_STATE_FLAGS * MAXQUOTAS)
+#define DQUOT_QUOTA_SYS_FILE (1 << DQUOT_STATE_LAST)
+ /* Quota file is a special
* system file and user cannot
* touch it. Filesystem is
* responsible for setting
* S_NOQUOTA, S_NOATIME flags
*/
-#define DQUOT_NEGATIVE_USAGE (1 << 7) /* Allow negative quota usage */
+#define DQUOT_NEGATIVE_USAGE (1 << (DQUOT_STATE_LAST + 1))
+ /* Allow negative quota usage */
static inline unsigned int dquot_state_flag(unsigned int flags, int type)
{
- if (type == USRQUOTA)
- return flags;
- return flags << _DQUOT_STATE_FLAGS;
+ return flags << _DQUOT_STATE_FLAGS * type;
}
static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
{
- if (type == USRQUOTA)
- return flags;
- return flags >> _DQUOT_STATE_FLAGS;
+ return (flags >> _DQUOT_STATE_FLAGS * type) & DQUOT_STATE_FLAGS;
}
#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 3ebb2315364..e6fa7acce29 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -19,15 +19,12 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb)
/*
* declaration of quota_function calls in kernel.
*/
-void sync_quota_sb(struct super_block *sb, int type);
-static inline void writeout_quota_sb(struct super_block *sb, int type)
-{
- if (sb->s_qcop->quota_sync)
- sb->s_qcop->quota_sync(sb, type);
-}
+void inode_add_rsv_space(struct inode *inode, qsize_t number);
+void inode_claim_rsv_space(struct inode *inode, qsize_t number);
+void inode_sub_rsv_space(struct inode *inode, qsize_t number);
-int dquot_initialize(struct inode *inode, int type);
-int dquot_drop(struct inode *inode);
+void dquot_initialize(struct inode *inode);
+void dquot_drop(struct inode *inode);
struct dquot *dqget(struct super_block *sb, unsigned int id, int type);
void dqput(struct dquot *dquot);
int dquot_scan_active(struct super_block *sb,
@@ -36,24 +33,23 @@ int dquot_scan_active(struct super_block *sb,
struct dquot *dquot_alloc(struct super_block *sb, int type);
void dquot_destroy(struct dquot *dquot);
-int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
-int dquot_alloc_inode(const struct inode *inode, qsize_t number);
+int __dquot_alloc_space(struct inode *inode, qsize_t number,
+ int warn, int reserve);
+void __dquot_free_space(struct inode *inode, qsize_t number, int reserve);
-int dquot_reserve_space(struct inode *inode, qsize_t number, int prealloc);
-int dquot_claim_space(struct inode *inode, qsize_t number);
-void dquot_release_reserved_space(struct inode *inode, qsize_t number);
-qsize_t dquot_get_reserved_space(struct inode *inode);
+int dquot_alloc_inode(const struct inode *inode);
-int dquot_free_space(struct inode *inode, qsize_t number);
-int dquot_free_inode(const struct inode *inode, qsize_t number);
+int dquot_claim_space_nodirty(struct inode *inode, qsize_t number);
+void dquot_free_inode(const struct inode *inode);
-int dquot_transfer(struct inode *inode, struct iattr *iattr);
int dquot_commit(struct dquot *dquot);
int dquot_acquire(struct dquot *dquot);
int dquot_release(struct dquot *dquot);
int dquot_commit_info(struct super_block *sb, int type);
int dquot_mark_dquot_dirty(struct dquot *dquot);
+int dquot_file_open(struct inode *inode, struct file *file);
+
int vfs_quota_on(struct super_block *sb, int type, int format_id,
char *path, int remount);
int vfs_quota_enable(struct inode *inode, int type, int format_id,
@@ -64,14 +60,13 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
int format_id, int type);
int vfs_quota_off(struct super_block *sb, int type, int remount);
int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags);
-int vfs_quota_sync(struct super_block *sb, int type);
+int vfs_quota_sync(struct super_block *sb, int type, int wait);
int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
-void vfs_dq_drop(struct inode *inode);
-int vfs_dq_transfer(struct inode *inode, struct iattr *iattr);
+int dquot_transfer(struct inode *inode, struct iattr *iattr);
int vfs_dq_quota_on_remount(struct super_block *sb);
static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
@@ -83,53 +78,56 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
* Functions for checking status of quota
*/
-static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type)
+static inline bool sb_has_quota_usage_enabled(struct super_block *sb, int type)
{
return sb_dqopt(sb)->flags &
dquot_state_flag(DQUOT_USAGE_ENABLED, type);
}
-static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type)
+static inline bool sb_has_quota_limits_enabled(struct super_block *sb, int type)
{
return sb_dqopt(sb)->flags &
dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
}
-static inline int sb_has_quota_suspended(struct super_block *sb, int type)
+static inline bool sb_has_quota_suspended(struct super_block *sb, int type)
{
return sb_dqopt(sb)->flags &
dquot_state_flag(DQUOT_SUSPENDED, type);
}
-static inline int sb_any_quota_suspended(struct super_block *sb)
+static inline unsigned sb_any_quota_suspended(struct super_block *sb)
{
- return sb_has_quota_suspended(sb, USRQUOTA) ||
- sb_has_quota_suspended(sb, GRPQUOTA);
+ unsigned type, tmsk = 0;
+ for (type = 0; type < MAXQUOTAS; type++)
+ tmsk |= sb_has_quota_suspended(sb, type) << type;
+ return tmsk;
}
/* Does kernel know about any quota information for given sb + type? */
-static inline int sb_has_quota_loaded(struct super_block *sb, int type)
+static inline bool sb_has_quota_loaded(struct super_block *sb, int type)
{
/* Currently if anything is on, then quota usage is on as well */
return sb_has_quota_usage_enabled(sb, type);
}
-static inline int sb_any_quota_loaded(struct super_block *sb)
+static inline unsigned sb_any_quota_loaded(struct super_block *sb)
{
- return sb_has_quota_loaded(sb, USRQUOTA) ||
- sb_has_quota_loaded(sb, GRPQUOTA);
+ unsigned type, tmsk = 0;
+ for (type = 0; type < MAXQUOTAS; type++)
+ tmsk |= sb_has_quota_loaded(sb, type) << type;
+ return tmsk;
}
-static inline int sb_has_quota_active(struct super_block *sb, int type)
+static inline bool sb_has_quota_active(struct super_block *sb, int type)
{
return sb_has_quota_loaded(sb, type) &&
!sb_has_quota_suspended(sb, type);
}
-static inline int sb_any_quota_active(struct super_block *sb)
+static inline unsigned sb_any_quota_active(struct super_block *sb)
{
- return sb_has_quota_active(sb, USRQUOTA) ||
- sb_has_quota_active(sb, GRPQUOTA);
+ return sb_any_quota_loaded(sb) & ~sb_any_quota_suspended(sb);
}
/*
@@ -141,122 +139,6 @@ extern const struct quotactl_ops vfs_quotactl_ops;
#define sb_dquot_ops (&dquot_operations)
#define sb_quotactl_ops (&vfs_quotactl_ops)
-/* It is better to call this function outside of any transaction as it might
- * need a lot of space in journal for dquot structure allocation. */
-static inline void vfs_dq_init(struct inode *inode)
-{
- BUG_ON(!inode->i_sb);
- if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode))
- inode->i_sb->dq_op->initialize(inode, -1);
-}
-
-/* The following allocation/freeing/transfer functions *must* be called inside
- * a transaction (deadlocks possible otherwise) */
-static inline int vfs_dq_prealloc_space_nodirty(struct inode *inode, qsize_t nr)
-{
- if (sb_any_quota_active(inode->i_sb)) {
- /* Used space is updated in alloc_space() */
- if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA)
- return 1;
- }
- else
- inode_add_bytes(inode, nr);
- return 0;
-}
-
-static inline int vfs_dq_prealloc_space(struct inode *inode, qsize_t nr)
-{
- int ret;
- if (!(ret = vfs_dq_prealloc_space_nodirty(inode, nr)))
- mark_inode_dirty(inode);
- return ret;
-}
-
-static inline int vfs_dq_alloc_space_nodirty(struct inode *inode, qsize_t nr)
-{
- if (sb_any_quota_active(inode->i_sb)) {
- /* Used space is updated in alloc_space() */
- if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA)
- return 1;
- }
- else
- inode_add_bytes(inode, nr);
- return 0;
-}
-
-static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
-{
- int ret;
- if (!(ret = vfs_dq_alloc_space_nodirty(inode, nr)))
- mark_inode_dirty(inode);
- return ret;
-}
-
-static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
-{
- if (sb_any_quota_active(inode->i_sb)) {
- /* Used space is updated in alloc_space() */
- if (inode->i_sb->dq_op->reserve_space(inode, nr, 0) == NO_QUOTA)
- return 1;
- }
- return 0;
-}
-
-static inline int vfs_dq_alloc_inode(struct inode *inode)
-{
- if (sb_any_quota_active(inode->i_sb)) {
- vfs_dq_init(inode);
- if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA)
- return 1;
- }
- return 0;
-}
-
-/*
- * Convert in-memory reserved quotas to real consumed quotas
- */
-static inline int vfs_dq_claim_space(struct inode *inode, qsize_t nr)
-{
- if (sb_any_quota_active(inode->i_sb)) {
- if (inode->i_sb->dq_op->claim_space(inode, nr) == NO_QUOTA)
- return 1;
- } else
- inode_add_bytes(inode, nr);
-
- mark_inode_dirty(inode);
- return 0;
-}
-
-/*
- * Release reserved (in-memory) quotas
- */
-static inline
-void vfs_dq_release_reservation_space(struct inode *inode, qsize_t nr)
-{
- if (sb_any_quota_active(inode->i_sb))
- inode->i_sb->dq_op->release_rsv(inode, nr);
-}
-
-static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
-{
- if (sb_any_quota_active(inode->i_sb))
- inode->i_sb->dq_op->free_space(inode, nr);
- else
- inode_sub_bytes(inode, nr);
-}
-
-static inline void vfs_dq_free_space(struct inode *inode, qsize_t nr)
-{
- vfs_dq_free_space_nodirty(inode, nr);
- mark_inode_dirty(inode);
-}
-
-static inline void vfs_dq_free_inode(struct inode *inode)
-{
- if (sb_any_quota_active(inode->i_sb))
- inode->i_sb->dq_op->free_inode(inode, 1);
-}
-
/* Cannot be called inside a transaction */
static inline int vfs_dq_off(struct super_block *sb, int remount)
{
@@ -316,28 +198,20 @@ static inline int sb_any_quota_active(struct super_block *sb)
#define sb_dquot_ops (NULL)
#define sb_quotactl_ops (NULL)
-static inline void vfs_dq_init(struct inode *inode)
+static inline void dquot_initialize(struct inode *inode)
{
}
-static inline void vfs_dq_drop(struct inode *inode)
+static inline void dquot_drop(struct inode *inode)
{
}
-static inline int vfs_dq_alloc_inode(struct inode *inode)
+static inline int dquot_alloc_inode(const struct inode *inode)
{
return 0;
}
-static inline void vfs_dq_free_inode(struct inode *inode)
-{
-}
-
-static inline void sync_quota_sb(struct super_block *sb, int type)
-{
-}
-
-static inline void writeout_quota_sb(struct super_block *sb, int type)
+static inline void dquot_free_inode(const struct inode *inode)
{
}
@@ -351,110 +225,116 @@ static inline int vfs_dq_quota_on_remount(struct super_block *sb)
return 0;
}
-static inline int vfs_dq_transfer(struct inode *inode, struct iattr *iattr)
+static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
{
return 0;
}
-static inline int vfs_dq_prealloc_space_nodirty(struct inode *inode, qsize_t nr)
+static inline int __dquot_alloc_space(struct inode *inode, qsize_t number,
+ int warn, int reserve)
{
- inode_add_bytes(inode, nr);
+ if (!reserve)
+ inode_add_bytes(inode, number);
return 0;
}
-static inline int vfs_dq_prealloc_space(struct inode *inode, qsize_t nr)
+static inline void __dquot_free_space(struct inode *inode, qsize_t number,
+ int reserve)
{
- vfs_dq_prealloc_space_nodirty(inode, nr);
- mark_inode_dirty(inode);
- return 0;
+ if (!reserve)
+ inode_sub_bytes(inode, number);
}
-static inline int vfs_dq_alloc_space_nodirty(struct inode *inode, qsize_t nr)
+static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
{
- inode_add_bytes(inode, nr);
+ inode_add_bytes(inode, number);
return 0;
}
-static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
+#define dquot_file_open generic_file_open
+
+#endif /* CONFIG_QUOTA */
+
+static inline int dquot_alloc_space_nodirty(struct inode *inode, qsize_t nr)
{
- vfs_dq_alloc_space_nodirty(inode, nr);
- mark_inode_dirty(inode);
- return 0;
+ return __dquot_alloc_space(inode, nr, 1, 0);
}
-static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
+static inline int dquot_alloc_space(struct inode *inode, qsize_t nr)
{
- return 0;
+ int ret;
+
+ ret = dquot_alloc_space_nodirty(inode, nr);
+ if (!ret)
+ mark_inode_dirty(inode);
+ return ret;
}
-static inline int vfs_dq_claim_space(struct inode *inode, qsize_t nr)
+static inline int dquot_alloc_block_nodirty(struct inode *inode, qsize_t nr)
{
- return vfs_dq_alloc_space(inode, nr);
+ return dquot_alloc_space_nodirty(inode, nr << inode->i_blkbits);
}
-static inline
-int vfs_dq_release_reservation_space(struct inode *inode, qsize_t nr)
+static inline int dquot_alloc_block(struct inode *inode, qsize_t nr)
{
- return 0;
+ return dquot_alloc_space(inode, nr << inode->i_blkbits);
}
-static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
+static inline int dquot_prealloc_block_nodirty(struct inode *inode, qsize_t nr)
{
- inode_sub_bytes(inode, nr);
+ return __dquot_alloc_space(inode, nr << inode->i_blkbits, 0, 0);
}
-static inline void vfs_dq_free_space(struct inode *inode, qsize_t nr)
+static inline int dquot_prealloc_block(struct inode *inode, qsize_t nr)
{
- vfs_dq_free_space_nodirty(inode, nr);
- mark_inode_dirty(inode);
-}
-
-#endif /* CONFIG_QUOTA */
+ int ret;
-static inline int vfs_dq_prealloc_block_nodirty(struct inode *inode, qsize_t nr)
-{
- return vfs_dq_prealloc_space_nodirty(inode, nr << inode->i_blkbits);
+ ret = dquot_prealloc_block_nodirty(inode, nr);
+ if (!ret)
+ mark_inode_dirty(inode);
+ return ret;
}
-static inline int vfs_dq_prealloc_block(struct inode *inode, qsize_t nr)
+static inline int dquot_reserve_block(struct inode *inode, qsize_t nr)
{
- return vfs_dq_prealloc_space(inode, nr << inode->i_blkbits);
+ return __dquot_alloc_space(inode, nr << inode->i_blkbits, 1, 1);
}
-static inline int vfs_dq_alloc_block_nodirty(struct inode *inode, qsize_t nr)
+static inline int dquot_claim_block(struct inode *inode, qsize_t nr)
{
- return vfs_dq_alloc_space_nodirty(inode, nr << inode->i_blkbits);
-}
+ int ret;
-static inline int vfs_dq_alloc_block(struct inode *inode, qsize_t nr)
-{
- return vfs_dq_alloc_space(inode, nr << inode->i_blkbits);
+ ret = dquot_claim_space_nodirty(inode, nr << inode->i_blkbits);
+ if (!ret)
+ mark_inode_dirty(inode);
+ return ret;
}
-static inline int vfs_dq_reserve_block(struct inode *inode, qsize_t nr)
+static inline void dquot_free_space_nodirty(struct inode *inode, qsize_t nr)
{
- return vfs_dq_reserve_space(inode, nr << inode->i_blkbits);
+ __dquot_free_space(inode, nr, 0);
}
-static inline int vfs_dq_claim_block(struct inode *inode, qsize_t nr)
+static inline void dquot_free_space(struct inode *inode, qsize_t nr)
{
- return vfs_dq_claim_space(inode, nr << inode->i_blkbits);
+ dquot_free_space_nodirty(inode, nr);
+ mark_inode_dirty(inode);
}
-static inline
-void vfs_dq_release_reservation_block(struct inode *inode, qsize_t nr)
+static inline void dquot_free_block_nodirty(struct inode *inode, qsize_t nr)
{
- vfs_dq_release_reservation_space(inode, nr << inode->i_blkbits);
+ dquot_free_space_nodirty(inode, nr << inode->i_blkbits);
}
-static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr)
+static inline void dquot_free_block(struct inode *inode, qsize_t nr)
{
- vfs_dq_free_space_nodirty(inode, nr << inode->i_blkbits);
+ dquot_free_space(inode, nr << inode->i_blkbits);
}
-static inline void vfs_dq_free_block(struct inode *inode, qsize_t nr)
+static inline void dquot_release_reservation_block(struct inode *inode,
+ qsize_t nr)
{
- vfs_dq_free_space(inode, nr << inode->i_blkbits);
+ __dquot_free_space(inode, nr << inode->i_blkbits, 1);
}
#endif /* _LINUX_QUOTAOPS_ */
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index c5da7491809..55ca73cf25e 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -121,6 +121,13 @@ do { \
* (Note, rcu_assign_pointer and rcu_dereference are not needed to control
* access to data items when inserting into or looking up from the radix tree)
*
+ * Note that the value returned by radix_tree_tag_get() may not be relied upon
+ * if only the RCU read lock is held. Functions to set/clear tags and to
+ * delete nodes running concurrently with it may affect its result such that
+ * two consecutive reads in the same locked section may return different
+ * values. If reliability is required, modification functions must also be
+ * excluded from concurrency.
+ *
* radix_tree_tagged is able to be called without locking or RCU.
*/
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 9c295411d01..5210a5c6087 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -25,10 +25,10 @@
Some example of insert and search follows here. The search is a plain
normal search over an ordered tree. The insert instead must be implemented
- int two steps: as first thing the code must insert the element in
- order as a red leaf in the tree, then the support library function
- rb_insert_color() must be called. Such function will do the
- not trivial work to rebalance the rbtree if necessary.
+ in two steps: First, the code must insert the element in order as a red leaf
+ in the tree, and then the support library function rb_insert_color() must
+ be called. Such function will do the not trivial work to rebalance the
+ rbtree, if necessary.
-----------------------------------------------------------------------
static inline struct page * rb_search_page_cache(struct inode * inode,
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index c8437362633..07db2feb857 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -41,6 +41,10 @@
#include <linux/lockdep.h>
#include <linux/completion.h>
+#ifdef CONFIG_RCU_TORTURE_TEST
+extern int rcutorture_runnable; /* for sysctl */
+#endif /* #ifdef CONFIG_RCU_TORTURE_TEST */
+
/**
* struct rcu_head - callback structure for use with RCU
* @next: next update requests in a list
@@ -97,6 +101,8 @@ extern struct lockdep_map rcu_sched_lock_map;
# define rcu_read_release_sched() \
lock_release(&rcu_sched_lock_map, 1, _THIS_IP_)
+extern int debug_lockdep_rcu_enabled(void);
+
/**
* rcu_read_lock_held - might we be in RCU read-side critical section?
*
@@ -104,28 +110,21 @@ extern struct lockdep_map rcu_sched_lock_map;
* an RCU read-side critical section. In absence of CONFIG_PROVE_LOCKING,
* this assumes we are in an RCU read-side critical section unless it can
* prove otherwise.
+ *
+ * Check rcu_scheduler_active to prevent false positives during boot.
*/
static inline int rcu_read_lock_held(void)
{
- if (debug_locks)
- return lock_is_held(&rcu_lock_map);
- return 1;
+ if (!debug_lockdep_rcu_enabled())
+ return 1;
+ return lock_is_held(&rcu_lock_map);
}
-/**
- * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section?
- *
- * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in
- * an RCU-bh read-side critical section. In absence of CONFIG_PROVE_LOCKING,
- * this assumes we are in an RCU-bh read-side critical section unless it can
- * prove otherwise.
+/*
+ * rcu_read_lock_bh_held() is defined out of line to avoid #include-file
+ * hell.
*/
-static inline int rcu_read_lock_bh_held(void)
-{
- if (debug_locks)
- return lock_is_held(&rcu_bh_lock_map);
- return 1;
-}
+extern int rcu_read_lock_bh_held(void);
/**
* rcu_read_lock_sched_held - might we be in RCU-sched read-side critical section?
@@ -135,15 +134,26 @@ static inline int rcu_read_lock_bh_held(void)
* this assumes we are in an RCU-sched read-side critical section unless it
* can prove otherwise. Note that disabling of preemption (including
* disabling irqs) counts as an RCU-sched read-side critical section.
+ *
+ * Check rcu_scheduler_active to prevent false positives during boot.
*/
+#ifdef CONFIG_PREEMPT
static inline int rcu_read_lock_sched_held(void)
{
int lockdep_opinion = 0;
+ if (!debug_lockdep_rcu_enabled())
+ return 1;
if (debug_locks)
lockdep_opinion = lock_is_held(&rcu_sched_lock_map);
- return lockdep_opinion || preempt_count() != 0 || !rcu_scheduler_active;
+ return lockdep_opinion || preempt_count() != 0 || irqs_disabled();
+}
+#else /* #ifdef CONFIG_PREEMPT */
+static inline int rcu_read_lock_sched_held(void)
+{
+ return 1;
}
+#endif /* #else #ifdef CONFIG_PREEMPT */
#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
@@ -164,10 +174,17 @@ static inline int rcu_read_lock_bh_held(void)
return 1;
}
+#ifdef CONFIG_PREEMPT
static inline int rcu_read_lock_sched_held(void)
{
- return preempt_count() != 0 || !rcu_scheduler_active;
+ return !rcu_scheduler_active || preempt_count() != 0 || irqs_disabled();
}
+#else /* #ifdef CONFIG_PREEMPT */
+static inline int rcu_read_lock_sched_held(void)
+{
+ return 1;
+}
+#endif /* #else #ifdef CONFIG_PREEMPT */
#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
@@ -175,27 +192,77 @@ static inline int rcu_read_lock_sched_held(void)
/**
* rcu_dereference_check - rcu_dereference with debug checking
+ * @p: The pointer to read, prior to dereferencing
+ * @c: The conditions under which the dereference will take place
+ *
+ * Do an rcu_dereference(), but check that the conditions under which the
+ * dereference will take place are correct. Typically the conditions indicate
+ * the various locking conditions that should be held at that point. The check
+ * should return true if the conditions are satisfied.
*
- * Do an rcu_dereference(), but check that the context is correct.
- * For example, rcu_dereference_check(gp, rcu_read_lock_held()) to
- * ensure that the rcu_dereference_check() executes within an RCU
- * read-side critical section. It is also possible to check for
- * locks being held, for example, by using lockdep_is_held().
+ * For example:
+ *
+ * bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() ||
+ * lockdep_is_held(&foo->lock));
+ *
+ * could be used to indicate to lockdep that foo->bar may only be dereferenced
+ * if either the RCU read lock is held, or that the lock required to replace
+ * the bar struct at foo->bar is held.
+ *
+ * Note that the list of conditions may also include indications of when a lock
+ * need not be held, for example during initialisation or destruction of the
+ * target struct:
+ *
+ * bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() ||
+ * lockdep_is_held(&foo->lock) ||
+ * atomic_read(&foo->usage) == 0);
*/
#define rcu_dereference_check(p, c) \
({ \
- if (debug_locks && !(c)) \
+ if (debug_lockdep_rcu_enabled() && !(c)) \
lockdep_rcu_dereference(__FILE__, __LINE__); \
rcu_dereference_raw(p); \
})
+/**
+ * rcu_dereference_protected - fetch RCU pointer when updates prevented
+ *
+ * Return the value of the specified RCU-protected pointer, but omit
+ * both the smp_read_barrier_depends() and the ACCESS_ONCE(). This
+ * is useful in cases where update-side locks prevent the value of the
+ * pointer from changing. Please note that this primitive does -not-
+ * prevent the compiler from repeating this reference or combining it
+ * with other references, so it should not be used without protection
+ * of appropriate locks.
+ */
+#define rcu_dereference_protected(p, c) \
+ ({ \
+ if (debug_lockdep_rcu_enabled() && !(c)) \
+ lockdep_rcu_dereference(__FILE__, __LINE__); \
+ (p); \
+ })
+
#else /* #ifdef CONFIG_PROVE_RCU */
#define rcu_dereference_check(p, c) rcu_dereference_raw(p)
+#define rcu_dereference_protected(p, c) (p)
#endif /* #else #ifdef CONFIG_PROVE_RCU */
/**
+ * rcu_access_pointer - fetch RCU pointer with no dereferencing
+ *
+ * Return the value of the specified RCU-protected pointer, but omit the
+ * smp_read_barrier_depends() and keep the ACCESS_ONCE(). This is useful
+ * when the value of this pointer is accessed, but the pointer is not
+ * dereferenced, for example, when testing an RCU-protected pointer against
+ * NULL. This may also be used in cases where update-side locks prevent
+ * the value of the pointer from changing, but rcu_dereference_protected()
+ * is a lighter-weight primitive for this use case.
+ */
+#define rcu_access_pointer(p) ACCESS_ONCE(p)
+
+/**
* rcu_read_lock - mark the beginning of an RCU read-side critical section.
*
* When synchronize_rcu() is invoked on one CPU while other CPUs
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 988e55fe649..3005d5a7fce 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -64,6 +64,7 @@ extern void kernel_restart(char *cmd);
extern void kernel_halt(void);
extern void kernel_power_off(void);
+extern int C_A_D; /* for sysctl */
void ctrl_alt_del(void);
#define POWEROFF_CMD_PATH_LEN 256
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 28c9fd020d3..ebd74726529 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -183,9 +183,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev,
{
/* Nothing except the stubbed out regulator API should be
* looking at the value except to check if it is an error
- * value so the actual return value doesn't matter.
+ * value. Drivers are free to handle NULL specifically by
+ * skipping all regulator API calls, but they don't have to.
+ * Drivers which don't, should make sure they properly handle
+ * corner cases of the API, such as regulator_get_voltage()
+ * returning 0.
*/
- return (struct regulator *)id;
+ return NULL;
}
static inline void regulator_put(struct regulator *regulator)
{
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 1ba3cf6edfb..3b603f47418 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -2034,7 +2034,7 @@ void reiserfs_read_locked_inode(struct inode *inode,
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);
-int reiserfs_write_inode(struct inode *inode, int);
+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);
struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
index 99928dce37e..7fa02b4af83 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -70,6 +70,11 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th,
void reiserfs_security_free(struct reiserfs_security_handle *sec);
#endif
+static inline int reiserfs_xattrs_initialized(struct super_block *sb)
+{
+ return REISERFS_SB(sb)->priv_root != NULL;
+}
+
#define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header))
static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size)
{
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 97059d08a62..4f82326eb29 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -29,7 +29,7 @@
/**
* enum rfkill_type - type of rfkill switch.
*
- * @RFKILL_TYPE_ALL: toggles all switches (userspace only)
+ * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type)
* @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
* @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
* @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index b019ae64e2a..d25bd224d37 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -37,7 +37,27 @@ struct anon_vma {
* is serialized by a system wide lock only visible to
* mm_take_all_locks() (mm_all_locks_mutex).
*/
- struct list_head head; /* List of private "related" vmas */
+ struct list_head head; /* Chain of private "related" vmas */
+};
+
+/*
+ * The copy-on-write semantics of fork mean that an anon_vma
+ * can become associated with multiple processes. Furthermore,
+ * each child process will have its own anon_vma, where new
+ * pages for that process are instantiated.
+ *
+ * This structure allows us to find the anon_vmas associated
+ * with a VMA, or the VMAs associated with an anon_vma.
+ * The "same_vma" list contains the anon_vma_chains linking
+ * all the anon_vmas associated with this VMA.
+ * The "same_anon_vma" list contains the anon_vma_chains
+ * which link all the VMAs associated with this anon_vma.
+ */
+struct anon_vma_chain {
+ struct vm_area_struct *vma;
+ struct anon_vma *anon_vma;
+ struct list_head same_vma; /* locked by mmap_sem & page_table_lock */
+ struct list_head same_anon_vma; /* locked by anon_vma->lock */
};
#ifdef CONFIG_MMU
@@ -89,15 +109,23 @@ static inline void anon_vma_unlock(struct vm_area_struct *vma)
*/
void anon_vma_init(void); /* create anon_vma_cachep */
int anon_vma_prepare(struct vm_area_struct *);
-void __anon_vma_merge(struct vm_area_struct *, struct vm_area_struct *);
-void anon_vma_unlink(struct vm_area_struct *);
-void anon_vma_link(struct vm_area_struct *);
+void unlink_anon_vmas(struct vm_area_struct *);
+int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
+int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
void __anon_vma_link(struct vm_area_struct *);
void anon_vma_free(struct anon_vma *);
+static inline void anon_vma_merge(struct vm_area_struct *vma,
+ struct vm_area_struct *next)
+{
+ VM_BUG_ON(vma->anon_vma != next->anon_vma);
+ unlink_anon_vmas(next);
+}
+
/*
* rmap interfaces called when adding or removing pte of page
*/
+void page_move_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
void page_add_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
void page_add_new_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
void page_add_file_rmap(struct page *);
@@ -181,7 +209,7 @@ static inline int page_referenced(struct page *page, int is_locked,
unsigned long *vm_flags)
{
*vm_flags = 0;
- return TestClearPageReferenced(page);
+ return 0;
}
#define try_to_unmap(page, refs) SWAP_FAIL
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 60f88a7fb13..14dbc83ded2 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -238,6 +238,12 @@ static inline bool is_leap_year(unsigned int year)
return (!(year % 4) && (year % 100)) || !(year % 400);
}
+#ifdef CONFIG_RTC_HCTOSYS
+extern int rtc_hctosys_ret;
+#else
+#define rtc_hctosys_ret -ENODEV
+#endif
+
#endif /* __KERNEL__ */
#endif /* _LINUX_RTC_H_ */
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h
index 281d8fd775e..8d522ffeda3 100644
--- a/include/linux/rtmutex.h
+++ b/include/linux/rtmutex.h
@@ -16,6 +16,8 @@
#include <linux/plist.h>
#include <linux/spinlock_types.h>
+extern int max_lock_depth; /* for sysctl */
+
/**
* The rt_mutex structure
*
diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h
index 71e0b00b6f2..bc2994ed66e 100644
--- a/include/linux/rwlock.h
+++ b/include/linux/rwlock.h
@@ -29,25 +29,25 @@ do { \
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
- extern void do_raw_read_lock(rwlock_t *lock);
+ extern void do_raw_read_lock(rwlock_t *lock) __acquires(lock);
#define do_raw_read_lock_flags(lock, flags) do_raw_read_lock(lock)
extern int do_raw_read_trylock(rwlock_t *lock);
- extern void do_raw_read_unlock(rwlock_t *lock);
- extern void do_raw_write_lock(rwlock_t *lock);
+ extern void do_raw_read_unlock(rwlock_t *lock) __releases(lock);
+ extern void do_raw_write_lock(rwlock_t *lock) __acquires(lock);
#define do_raw_write_lock_flags(lock, flags) do_raw_write_lock(lock)
extern int do_raw_write_trylock(rwlock_t *lock);
- extern void do_raw_write_unlock(rwlock_t *lock);
+ extern void do_raw_write_unlock(rwlock_t *lock) __releases(lock);
#else
-# define do_raw_read_lock(rwlock) arch_read_lock(&(rwlock)->raw_lock)
+# define do_raw_read_lock(rwlock) do {__acquire(lock); arch_read_lock(&(rwlock)->raw_lock); } while (0)
# define do_raw_read_lock_flags(lock, flags) \
- arch_read_lock_flags(&(lock)->raw_lock, *(flags))
+ do {__acquire(lock); arch_read_lock_flags(&(lock)->raw_lock, *(flags)); } while (0)
# define do_raw_read_trylock(rwlock) arch_read_trylock(&(rwlock)->raw_lock)
-# define do_raw_read_unlock(rwlock) arch_read_unlock(&(rwlock)->raw_lock)
-# define do_raw_write_lock(rwlock) arch_write_lock(&(rwlock)->raw_lock)
+# define do_raw_read_unlock(rwlock) do {arch_read_unlock(&(rwlock)->raw_lock); __release(lock); } while (0)
+# define do_raw_write_lock(rwlock) do {__acquire(lock); arch_write_lock(&(rwlock)->raw_lock); } while (0)
# define do_raw_write_lock_flags(lock, flags) \
- arch_write_lock_flags(&(lock)->raw_lock, *(flags))
+ do {__acquire(lock); arch_write_lock_flags(&(lock)->raw_lock, *(flags)); } while (0)
# define do_raw_write_trylock(rwlock) arch_write_trylock(&(rwlock)->raw_lock)
-# define do_raw_write_unlock(rwlock) arch_write_unlock(&(rwlock)->raw_lock)
+# define do_raw_write_unlock(rwlock) do {arch_write_unlock(&(rwlock)->raw_lock); __release(lock); } while (0)
#endif
#define read_can_lock(rwlock) arch_read_can_lock(&(rwlock)->raw_lock)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4b1753f7e48..dad7f668ebf 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -258,6 +258,10 @@ extern spinlock_t mmlist_lock;
struct task_struct;
+#ifdef CONFIG_PROVE_RCU
+extern int lockdep_tasklist_lock_is_held(void);
+#endif /* #ifdef CONFIG_PROVE_RCU */
+
extern void sched_init(void);
extern void sched_init_smp(void);
extern asmlinkage void schedule_tail(struct task_struct *prev);
@@ -396,60 +400,6 @@ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
static inline void arch_pick_mmap_layout(struct mm_struct *mm) {}
#endif
-#if USE_SPLIT_PTLOCKS
-/*
- * The mm counters are not protected by its page_table_lock,
- * so must be incremented atomically.
- */
-#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
-#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
-#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
-#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
-#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
-
-#else /* !USE_SPLIT_PTLOCKS */
-/*
- * The mm counters are protected by its page_table_lock,
- * so can be incremented directly.
- */
-#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
-#define get_mm_counter(mm, member) ((mm)->_##member)
-#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
-#define inc_mm_counter(mm, member) (mm)->_##member++
-#define dec_mm_counter(mm, member) (mm)->_##member--
-
-#endif /* !USE_SPLIT_PTLOCKS */
-
-#define get_mm_rss(mm) \
- (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
-#define update_hiwater_rss(mm) do { \
- unsigned long _rss = get_mm_rss(mm); \
- if ((mm)->hiwater_rss < _rss) \
- (mm)->hiwater_rss = _rss; \
-} while (0)
-#define update_hiwater_vm(mm) do { \
- if ((mm)->hiwater_vm < (mm)->total_vm) \
- (mm)->hiwater_vm = (mm)->total_vm; \
-} while (0)
-
-static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm)
-{
- return max(mm->hiwater_rss, get_mm_rss(mm));
-}
-
-static inline void setmax_mm_hiwater_rss(unsigned long *maxrss,
- struct mm_struct *mm)
-{
- unsigned long hiwater_rss = get_mm_hiwater_rss(mm);
-
- if (*maxrss < hiwater_rss)
- *maxrss = hiwater_rss;
-}
-
-static inline unsigned long get_mm_hiwater_vm(struct mm_struct *mm)
-{
- return max(mm->hiwater_vm, mm->total_vm);
-}
extern void set_dumpable(struct mm_struct *mm, int value);
extern int get_dumpable(struct mm_struct *mm);
@@ -1274,7 +1224,9 @@ struct task_struct {
struct plist_node pushable_tasks;
struct mm_struct *mm, *active_mm;
-
+#if defined(SPLIT_RSS_COUNTING)
+ struct task_rss_stat rss_stat;
+#endif
/* task state */
int exit_state;
int exit_code, exit_signal;
@@ -1525,7 +1477,7 @@ struct task_struct {
struct list_head *scm_work_list;
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- /* Index of current stored adress in ret_stack */
+ /* Index of current stored address in ret_stack */
int curr_ret_stack;
/* Stack of return addresses for return function tracing */
struct ftrace_ret_stack *ret_stack;
@@ -2443,9 +2395,7 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times);
static inline void thread_group_cputime_init(struct signal_struct *sig)
{
- sig->cputimer.cputime = INIT_CPUTIME;
spin_lock_init(&sig->cputimer.lock);
- sig->cputimer.running = 0;
}
static inline void thread_group_cputime_free(struct signal_struct *sig)
diff --git a/include/linux/security.h b/include/linux/security.h
index 233d20b52c1..3158dd982d2 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -33,7 +33,7 @@
#include <linux/sched.h>
#include <linux/key.h>
#include <linux/xfrm.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
#include <net/flow.h>
/* Maximum number of letters for an LSM name string */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 8c3dd36fe91..78dd1e7120a 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -491,9 +491,13 @@ uart_handle_dcd_change(struct uart_port *uport, unsigned int status)
{
struct uart_state *state = uport->state;
struct tty_port *port = &state->port;
+ struct tty_ldisc *ld = tty_ldisc_ref(port->tty);
+ struct timespec ts;
- uport->icount.dcd++;
+ if (ld && ld->ops->dcd_change)
+ getnstimeofday(&ts);
+ uport->icount.dcd++;
#ifdef CONFIG_HARD_PPS
if ((uport->flags & UPF_HARDPPS_CD) && status)
hardpps();
@@ -505,6 +509,11 @@ uart_handle_dcd_change(struct uart_port *uport, unsigned int status)
else if (port->tty)
tty_hangup(port->tty);
}
+
+ if (ld && ld->ops->dcd_change)
+ ld->ops->dcd_change(port->tty, status, &ts);
+ if (ld)
+ tty_ldisc_deref(ld);
}
/**
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index 1c297ddc9d5..193d4bfe42f 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -2,6 +2,9 @@
#define __LINUX_SERIAL_SCI_H
#include <linux/serial_core.h>
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+#include <asm/dmaengine.h>
+#endif
/*
* Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts)
@@ -16,6 +19,8 @@ enum {
SCIx_NR_IRQS,
};
+struct device;
+
/*
* Platform device specific platform_data struct
*/
@@ -26,6 +31,11 @@ struct plat_sci_port {
unsigned int type; /* SCI / SCIF / IRDA */
upf_t flags; /* UPF_* flags */
char *clk; /* clock string */
+ struct device *dma_dev;
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+ enum sh_dmae_slave_chan_id dma_slave_tx;
+ enum sh_dmae_slave_chan_id dma_slave_rx;
+#endif
};
#endif /* __LINUX_SERIAL_SCI_H */
diff --git a/include/linux/signal.h b/include/linux/signal.h
index ab9272cc270..fcd2b14b193 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -7,6 +7,8 @@
#ifdef __KERNEL__
#include <linux/list.h>
+/* for sysctl */
+extern int print_fatal_signals;
/*
* Real Time signals may be queued.
*/
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 03f816a9b65..124f90cd5a3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -190,9 +190,6 @@ struct skb_shared_info {
atomic_t dataref;
unsigned short nr_frags;
unsigned short gso_size;
-#ifdef CONFIG_HAS_DMA
- dma_addr_t dma_head;
-#endif
/* Warning: this field is not always filled in (UFO)! */
unsigned short gso_segs;
unsigned short gso_type;
@@ -201,9 +198,6 @@ struct skb_shared_info {
struct sk_buff *frag_list;
struct skb_shared_hwtstamps hwtstamps;
skb_frag_t frags[MAX_SKB_FRAGS];
-#ifdef CONFIG_HAS_DMA
- dma_addr_t dma_maps[MAX_SKB_FRAGS];
-#endif
/* Intermediate layers must ensure that destructor_arg
* remains valid until skb destructor */
void * destructor_arg;
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 2da8372519f..49d1247cd6d 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -70,6 +70,11 @@
#else
# define SLAB_NOTRACK 0x00000000UL
#endif
+#ifdef CONFIG_FAILSLAB
+# define SLAB_FAILSLAB 0x02000000UL /* Fault injection mark */
+#else
+# define SLAB_FAILSLAB 0x00000000UL
+#endif
/* The following flags affect the page allocator grouping pages by mobility */
#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
@@ -101,6 +106,7 @@ int kmem_cache_shrink(struct kmem_cache *);
void kmem_cache_free(struct kmem_cache *, void *);
unsigned int kmem_cache_size(struct kmem_cache *);
const char *kmem_cache_name(struct kmem_cache *);
+int kern_ptr_validate(const void *ptr, unsigned long size);
int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
/*
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 1e14beb23f9..0249d4175ba 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -38,8 +38,6 @@ struct kmem_cache_cpu {
void **freelist; /* Pointer to first free per cpu object */
struct page *page; /* The slab from which we are allocating */
int node; /* The node of the page (or -1 for debug) */
- unsigned int offset; /* Freepointer offset (in word units) */
- unsigned int objsize; /* Size of an object (from kmem_cache) */
#ifdef CONFIG_SLUB_STATS
unsigned stat[NR_SLUB_STAT_ITEMS];
#endif
@@ -69,6 +67,7 @@ struct kmem_cache_order_objects {
* Slab cache management.
*/
struct kmem_cache {
+ struct kmem_cache_cpu *cpu_slab;
/* Used for retriving partial slabs etc */
unsigned long flags;
int size; /* The size of an object including meta data */
@@ -104,11 +103,6 @@ struct kmem_cache {
int remote_node_defrag_ratio;
struct kmem_cache_node *node[MAX_NUMNODES];
#endif
-#ifdef CONFIG_SMP
- struct kmem_cache_cpu *cpu_slab[NR_CPUS];
-#else
- struct kmem_cache_cpu cpu_slab;
-#endif
};
/*
@@ -135,11 +129,21 @@ struct kmem_cache {
#define SLUB_PAGE_SHIFT (PAGE_SHIFT + 2)
+#ifdef CONFIG_ZONE_DMA
+#define SLUB_DMA __GFP_DMA
+/* Reserve extra caches for potential DMA use */
+#define KMALLOC_CACHES (2 * SLUB_PAGE_SHIFT - 6)
+#else
+/* Disable DMA functionality */
+#define SLUB_DMA (__force gfp_t)0
+#define KMALLOC_CACHES SLUB_PAGE_SHIFT
+#endif
+
/*
* We keep the general caches in an array of slab caches that are used for
* 2^x bytes of allocations.
*/
-extern struct kmem_cache kmalloc_caches[SLUB_PAGE_SHIFT];
+extern struct kmem_cache kmalloc_caches[KMALLOC_CACHES];
/*
* Sorry that the following has to be that ugly but some versions of GCC
@@ -207,13 +211,6 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size)
return &kmalloc_caches[index];
}
-#ifdef CONFIG_ZONE_DMA
-#define SLUB_DMA __GFP_DMA
-#else
-/* Disable DMA functionality */
-#define SLUB_DMA (__force gfp_t)0
-#endif
-
void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
void *__kmalloc(size_t size, gfp_t flags);
diff --git a/include/linux/smb_fs_sb.h b/include/linux/smb_fs_sb.h
index 8a060a7040d..bb947dd1fba 100644
--- a/include/linux/smb_fs_sb.h
+++ b/include/linux/smb_fs_sb.h
@@ -10,6 +10,7 @@
#define _SMB_FS_SB
#include <linux/types.h>
+#include <linux/backing-dev.h>
#include <linux/smb.h>
/*
@@ -74,6 +75,8 @@ struct smb_sb_info {
struct smb_ops *ops;
struct super_block *super_block;
+
+ struct backing_dev_info bdi;
};
static inline int
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 7a0570e6a59..cfa2d20e35f 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -154,7 +154,7 @@ smp_call_function_any(const struct cpumask *mask, void (*func)(void *info),
/*
* smp_processor_id(): get the current CPU ID.
*
- * if DEBUG_PREEMPT is enabled the we check whether it is
+ * if DEBUG_PREEMPT is enabled then we check whether it is
* used in a preemption-safe way. (smp_processor_id() is safe
* if it's used in a preemption-off critical section, or in
* a thread that is bound to the current CPU.)
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index e28f5a0182e..4435d108475 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -225,6 +225,8 @@ enum
LINUX_MIB_SACKSHIFTED,
LINUX_MIB_SACKMERGED,
LINUX_MIB_SACKSHIFTFALLBACK,
+ LINUX_MIB_TCPBACKLOGDROP,
+ LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
__LINUX_MIB_MAX
};
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 7b3aae2052a..354cc5617f8 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -255,6 +255,7 @@ struct ucred {
#define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */
#define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */
#define MSG_MORE 0x8000 /* Sender will send more */
+#define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */
#define MSG_EOF MSG_FIN
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h
index 51948eb6927..b4ae570d3c9 100644
--- a/include/linux/spi/ads7846.h
+++ b/include/linux/spi/ads7846.h
@@ -12,7 +12,7 @@ enum ads7846_filter {
};
struct ads7846_platform_data {
- u16 model; /* 7843, 7845, 7846. */
+ u16 model; /* 7843, 7845, 7846, 7873. */
u16 vref_delay_usecs; /* 0 for external vref; etc */
u16 vref_mv; /* external vref value, milliVolts */
bool keep_vref_on; /* set to keep vref on for differential
@@ -53,5 +53,6 @@ struct ads7846_platform_data {
int (*filter) (void *filter_data, int data_idx, int *val);
void (*filter_cleanup)(void *filter_data);
void (*wait_for_sync)(void);
+ bool wakeup;
};
diff --git a/include/linux/spi/l4f00242t03.h b/include/linux/spi/l4f00242t03.h
new file mode 100644
index 00000000000..aee1dbda4ed
--- /dev/null
+++ b/include/linux/spi/l4f00242t03.h
@@ -0,0 +1,31 @@
+/*
+ * l4f00242t03.h -- Platform glue for Epson L4F00242T03 LCD
+ *
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Based on Marek Vasut work in lms283gf05.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in 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 _INCLUDE_LINUX_SPI_L4F00242T03_H_
+#define _INCLUDE_LINUX_SPI_L4F00242T03_H_
+
+struct l4f00242t03_pdata {
+ unsigned int reset_gpio;
+ unsigned int data_enable_gpio;
+ const char *io_supply; /* will be set to 1.8 V */
+ const char *core_supply; /* will be set to 2.8 V */
+};
+
+#endif /* _INCLUDE_LINUX_SPI_L4F00242T03_H_ */
diff --git a/include/linux/spi/max7301.h b/include/linux/spi/max7301.h
index 6dfd83f19b4..34af0a3477b 100644
--- a/include/linux/spi/max7301.h
+++ b/include/linux/spi/max7301.h
@@ -1,9 +1,27 @@
#ifndef LINUX_SPI_MAX7301_H
#define LINUX_SPI_MAX7301_H
+#include <linux/gpio.h>
+
+/*
+ * Some registers must be read back to modify.
+ * To save time we cache them here in memory
+ */
+struct max7301 {
+ struct mutex lock;
+ u8 port_config[8]; /* field 0 is unused */
+ u32 out_level; /* cached output levels */
+ struct gpio_chip chip;
+ struct device *dev;
+ int (*write)(struct device *dev, unsigned int reg, unsigned int val);
+ int (*read)(struct device *dev, unsigned int reg);
+};
+
struct max7301_platform_data {
/* number assigned to the first GPIO */
unsigned base;
};
+extern int __max730x_remove(struct device *dev);
+extern int __max730x_probe(struct max7301 *ts);
#endif
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 97b60b37f44..af56071b06f 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -21,6 +21,7 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
/*
* INTERFACES between SPI master-side drivers and SPI infrastructure.
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 86088213334..89fac6a3f78 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -128,19 +128,21 @@ static inline void smp_mb__after_lock(void) { smp_mb(); }
#define raw_spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock)
#ifdef CONFIG_DEBUG_SPINLOCK
- extern void do_raw_spin_lock(raw_spinlock_t *lock);
+ extern void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock);
#define do_raw_spin_lock_flags(lock, flags) do_raw_spin_lock(lock)
extern int do_raw_spin_trylock(raw_spinlock_t *lock);
- extern void do_raw_spin_unlock(raw_spinlock_t *lock);
+ extern void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock);
#else
-static inline void do_raw_spin_lock(raw_spinlock_t *lock)
+static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
{
+ __acquire(lock);
arch_spin_lock(&lock->raw_lock);
}
static inline void
-do_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags)
+do_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) __acquires(lock)
{
+ __acquire(lock);
arch_spin_lock_flags(&lock->raw_lock, *flags);
}
@@ -149,9 +151,10 @@ static inline int do_raw_spin_trylock(raw_spinlock_t *lock)
return arch_spin_trylock(&(lock)->raw_lock);
}
-static inline void do_raw_spin_unlock(raw_spinlock_t *lock)
+static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)
{
arch_spin_unlock(&lock->raw_lock);
+ __release(lock);
}
#endif
diff --git a/include/linux/sunrpc/bc_xprt.h b/include/linux/sunrpc/bc_xprt.h
index 6508f0dc0ef..7c91260c44a 100644
--- a/include/linux/sunrpc/bc_xprt.h
+++ b/include/linux/sunrpc/bc_xprt.h
@@ -36,14 +36,32 @@ struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt);
void xprt_free_bc_request(struct rpc_rqst *req);
int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);
void xprt_destroy_backchannel(struct rpc_xprt *, int max_reqs);
-void bc_release_request(struct rpc_task *);
int bc_send(struct rpc_rqst *req);
+
+/*
+ * Determine if a shared backchannel is in use
+ */
+static inline int svc_is_backchannel(const struct svc_rqst *rqstp)
+{
+ if (rqstp->rq_server->bc_xprt)
+ return 1;
+ return 0;
+}
#else /* CONFIG_NFS_V4_1 */
static inline int xprt_setup_backchannel(struct rpc_xprt *xprt,
unsigned int min_reqs)
{
return 0;
}
+
+static inline int svc_is_backchannel(const struct svc_rqst *rqstp)
+{
+ return 0;
+}
+
+static inline void xprt_free_bc_request(struct rpc_rqst *req)
+{
+}
#endif /* CONFIG_NFS_V4_1 */
#endif /* _LINUX_SUNRPC_BC_XPRT_H */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index a2602a8207a..1f59d9340c4 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -355,6 +355,7 @@ static inline void disable_swap_token(void)
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
extern void
mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout);
+extern int mem_cgroup_count_swap_user(swp_entry_t ent, struct page **pagep);
#else
static inline void
mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout)
@@ -485,6 +486,14 @@ mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent)
{
}
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
+static inline int
+mem_cgroup_count_swap_user(swp_entry_t ent, struct page **pagep)
+{
+ return 0;
+}
+#endif
+
#endif /* CONFIG_SWAP */
#endif /* __KERNEL__*/
#endif /* _LINUX_SWAP_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 8126f239edf..057929b0a65 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -23,6 +23,7 @@ struct kexec_segment;
struct linux_dirent;
struct linux_dirent64;
struct list_head;
+struct mmap_arg_struct;
struct msgbuf;
struct msghdr;
struct mmsghdr;
@@ -30,10 +31,13 @@ struct msqid_ds;
struct new_utsname;
struct nfsctl_arg;
struct __old_kernel_stat;
+struct oldold_utsname;
+struct old_utsname;
struct pollfd;
struct rlimit;
struct rusage;
struct sched_param;
+struct sel_arg_struct;
struct semaphore;
struct sembuf;
struct shmid_ds;
@@ -101,18 +105,18 @@ struct perf_event_attr;
#ifdef CONFIG_PERF_EVENTS
-#define TRACE_SYS_ENTER_PROFILE_INIT(sname) \
- .profile_enable = prof_sysenter_enable, \
- .profile_disable = prof_sysenter_disable,
+#define TRACE_SYS_ENTER_PERF_INIT(sname) \
+ .perf_event_enable = perf_sysenter_enable, \
+ .perf_event_disable = perf_sysenter_disable,
-#define TRACE_SYS_EXIT_PROFILE_INIT(sname) \
- .profile_enable = prof_sysexit_enable, \
- .profile_disable = prof_sysexit_disable,
+#define TRACE_SYS_EXIT_PERF_INIT(sname) \
+ .perf_event_enable = perf_sysexit_enable, \
+ .perf_event_disable = perf_sysexit_disable,
#else
-#define TRACE_SYS_ENTER_PROFILE(sname)
-#define TRACE_SYS_ENTER_PROFILE_INIT(sname)
-#define TRACE_SYS_EXIT_PROFILE(sname)
-#define TRACE_SYS_EXIT_PROFILE_INIT(sname)
+#define TRACE_SYS_ENTER_PERF(sname)
+#define TRACE_SYS_ENTER_PERF_INIT(sname)
+#define TRACE_SYS_EXIT_PERF(sname)
+#define TRACE_SYS_EXIT_PERF_INIT(sname)
#endif /* CONFIG_PERF_EVENTS */
#ifdef CONFIG_FTRACE_SYSCALLS
@@ -149,7 +153,7 @@ struct perf_event_attr;
.regfunc = reg_event_syscall_enter, \
.unregfunc = unreg_event_syscall_enter, \
.data = (void *)&__syscall_meta_##sname,\
- TRACE_SYS_ENTER_PROFILE_INIT(sname) \
+ TRACE_SYS_ENTER_PERF_INIT(sname) \
}
#define SYSCALL_TRACE_EXIT_EVENT(sname) \
@@ -171,7 +175,7 @@ struct perf_event_attr;
.regfunc = reg_event_syscall_exit, \
.unregfunc = unreg_event_syscall_exit, \
.data = (void *)&__syscall_meta_##sname,\
- TRACE_SYS_EXIT_PROFILE_INIT(sname) \
+ TRACE_SYS_EXIT_PERF_INIT(sname) \
}
#define SYSCALL_METADATA(sname, nb) \
@@ -638,6 +642,7 @@ asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
long timeout);
asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
fd_set __user *exp, struct timeval __user *tvp);
+asmlinkage long sys_old_select(struct sel_arg_struct __user *arg);
asmlinkage long sys_epoll_create(int size);
asmlinkage long sys_epoll_create1(int flags);
asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
@@ -652,6 +657,8 @@ asmlinkage long sys_gethostname(char __user *name, int len);
asmlinkage long sys_sethostname(char __user *name, int len);
asmlinkage long sys_setdomainname(char __user *name, int len);
asmlinkage long sys_newuname(struct new_utsname __user *name);
+asmlinkage long sys_uname(struct old_utsname __user *);
+asmlinkage long sys_olduname(struct oldold_utsname __user *);
asmlinkage long sys_getrlimit(unsigned int resource,
struct rlimit __user *rlim);
@@ -681,6 +688,8 @@ asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg);
asmlinkage long sys_shmget(key_t key, size_t size, int flag);
asmlinkage long sys_shmdt(char __user *shmaddr);
asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
+asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
+ unsigned long third, void __user *ptr, long fifth);
asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr);
asmlinkage long sys_mq_unlink(const char __user *name);
@@ -836,4 +845,6 @@ asmlinkage long sys_perf_event_open(
asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
+asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg);
+
#endif
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
index f395bb3fa2f..1154c29f410 100644
--- a/include/linux/sysdev.h
+++ b/include/linux/sysdev.h
@@ -27,10 +27,12 @@
struct sys_device;
+struct sysdev_class_attribute;
struct sysdev_class {
const char *name;
struct list_head drivers;
+ struct sysdev_class_attribute **attrs;
/* Default operations for these types of devices */
int (*shutdown)(struct sys_device *);
@@ -41,8 +43,10 @@ struct sysdev_class {
struct sysdev_class_attribute {
struct attribute attr;
- ssize_t (*show)(struct sysdev_class *, char *);
- ssize_t (*store)(struct sysdev_class *, const char *, size_t);
+ ssize_t (*show)(struct sysdev_class *, struct sysdev_class_attribute *,
+ char *);
+ ssize_t (*store)(struct sysdev_class *, struct sysdev_class_attribute *,
+ const char *, size_t);
};
#define _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \
@@ -119,6 +123,19 @@ struct sysdev_attribute {
extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
+/* Create/remove NULL terminated attribute list */
+static inline int
+sysdev_create_files(struct sys_device *d, struct sysdev_attribute **a)
+{
+ return sysfs_create_files(&d->kobj, (const struct attribute **)a);
+}
+
+static inline void
+sysdev_remove_files(struct sys_device *d, struct sysdev_attribute **a)
+{
+ return sysfs_remove_files(&d->kobj, (const struct attribute **)a);
+}
+
struct sysdev_ext_attribute {
struct sysdev_attribute attr;
void *var;
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index cfa83083a2d..f0496b3d181 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -15,6 +15,7 @@
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/list.h>
+#include <linux/lockdep.h>
#include <asm/atomic.h>
struct kobject;
@@ -29,8 +30,33 @@ struct attribute {
const char *name;
struct module *owner;
mode_t mode;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lock_class_key *key;
+ struct lock_class_key skey;
+#endif
};
+/**
+ * sysfs_attr_init - initialize a dynamically allocated sysfs attribute
+ * @attr: struct attribute to initialize
+ *
+ * Initialize a dynamically allocated struct attribute so we can
+ * make lockdep happy. This is a new requirement for attributes
+ * and initially this is only needed when lockdep is enabled.
+ * Lockdep gives a nice error when your attribute is added to
+ * sysfs if you don't have this.
+ */
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+#define sysfs_attr_init(attr) \
+do { \
+ static struct lock_class_key __key; \
+ \
+ (attr)->key = &__key; \
+} while(0)
+#else
+#define sysfs_attr_init(attr) do {} while(0)
+#endif
+
struct attribute_group {
const char *name;
mode_t (*is_visible)(struct kobject *,
@@ -74,6 +100,18 @@ struct bin_attribute {
struct vm_area_struct *vma);
};
+/**
+ * sysfs_bin_attr_init - initialize a dynamically allocated bin_attribute
+ * @attr: struct bin_attribute to initialize
+ *
+ * Initialize a dynamically allocated struct bin_attribute so we
+ * can make lockdep happy. This is a new requirement for
+ * attributes and initially this is only needed when lockdep is
+ * enabled. Lockdep gives a nice error when your attribute is
+ * added to sysfs if you don't have this.
+ */
+#define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr)
+
struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *,char *);
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
@@ -94,9 +132,12 @@ int __must_check sysfs_move_dir(struct kobject *kobj,
int __must_check sysfs_create_file(struct kobject *kobj,
const struct attribute *attr);
+int __must_check sysfs_create_files(struct kobject *kobj,
+ const struct attribute **attr);
int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr,
mode_t mode);
void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);
+void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr);
int __must_check sysfs_create_bin_file(struct kobject *kobj,
const struct bin_attribute *attr);
@@ -110,6 +151,9 @@ int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
const char *name);
void sysfs_remove_link(struct kobject *kobj, const char *name);
+int sysfs_rename_link(struct kobject *kobj, struct kobject *target,
+ const char *old_name, const char *new_name);
+
int __must_check sysfs_create_group(struct kobject *kobj,
const struct attribute_group *grp);
int sysfs_update_group(struct kobject *kobj,
@@ -164,6 +208,12 @@ static inline int sysfs_create_file(struct kobject *kobj,
return 0;
}
+static inline int sysfs_create_files(struct kobject *kobj,
+ const struct attribute **attr)
+{
+ return 0;
+}
+
static inline int sysfs_chmod_file(struct kobject *kobj,
struct attribute *attr, mode_t mode)
{
@@ -175,6 +225,11 @@ static inline void sysfs_remove_file(struct kobject *kobj,
{
}
+static inline void sysfs_remove_files(struct kobject *kobj,
+ const struct attribute **attr)
+{
+}
+
static inline int sysfs_create_bin_file(struct kobject *kobj,
const struct bin_attribute *attr)
{
@@ -203,6 +258,12 @@ static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
{
}
+static inline int sysfs_rename_link(struct kobject *k, struct kobject *t,
+ const char *old_name, const char *new_name)
+{
+ return 0;
+}
+
static inline int sysfs_create_group(struct kobject *kobj,
const struct attribute_group *grp)
{
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h
index 3398f455326..58de6edf751 100644
--- a/include/linux/taskstats_kern.h
+++ b/include/linux/taskstats_kern.h
@@ -9,16 +9,12 @@
#include <linux/taskstats.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#ifdef CONFIG_TASKSTATS
extern struct kmem_cache *taskstats_cache;
extern struct mutex taskstats_exit_mutex;
-static inline void taskstats_tgid_init(struct signal_struct *sig)
-{
- sig->stats = NULL;
-}
-
static inline void taskstats_tgid_free(struct signal_struct *sig)
{
if (sig->stats)
@@ -30,8 +26,6 @@ extern void taskstats_init_early(void);
#else
static inline void taskstats_exit(struct task_struct *tsk, int group_dead)
{}
-static inline void taskstats_tgid_init(struct signal_struct *sig)
-{}
static inline void taskstats_tgid_free(struct signal_struct *sig)
{}
static inline void taskstats_init_early(void)
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index f59604ed0ec..78b4bd3be49 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -49,7 +49,7 @@ struct tracepoint {
void **it_func; \
\
rcu_read_lock_sched_notrace(); \
- it_func = rcu_dereference((tp)->funcs); \
+ it_func = rcu_dereference_sched((tp)->funcs); \
if (it_func) { \
do { \
((void(*)(proto))(*it_func))(args); \
diff --git a/include/linux/tty.h b/include/linux/tty.h
index d96e5882f12..4409967db0c 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -70,12 +70,13 @@ struct tty_buffer {
/*
* We default to dicing tty buffer allocations to this many characters
- * in order to avoid multiple page allocations. We assume tty_buffer itself
- * is under 256 bytes. See tty_buffer_find for the allocation logic this
- * must match
+ * in order to avoid multiple page allocations. We know the size of
+ * tty_buffer itself but it must also be taken into account that the
+ * the buffer is 256 byte aligned. See tty_buffer_find for the allocation
+ * logic this must match
*/
-#define TTY_BUFFER_PAGE ((PAGE_SIZE - 256) / 2)
+#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
struct tty_bufhead {
@@ -223,6 +224,7 @@ struct tty_port {
wait_queue_head_t close_wait; /* Close waiters */
wait_queue_head_t delta_msr_wait; /* Modem status change */
unsigned long flags; /* TTY flags ASY_*/
+ unsigned char console:1; /* port is a console */
struct mutex mutex; /* Locking */
struct mutex buf_mutex; /* Buffer alloc lock */
unsigned char *xmit_buf; /* Optional buffer */
@@ -514,6 +516,7 @@ extern void tty_ldisc_enable(struct tty_struct *tty);
/* n_tty.c */
extern struct tty_ldisc_ops tty_ldisc_N_TTY;
+extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops);
/* tty_audit.c */
#ifdef CONFIG_AUDIT
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index 0c4ee9b88f8..526d66f066a 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -99,6 +99,12 @@
* cease I/O to the tty driver. Can sleep. The driver should
* seek to perform this action quickly but should wait until
* any pending driver I/O is completed.
+ *
+ * void (*dcd_change)(struct tty_struct *tty, unsigned int status,
+ * struct timespec *ts)
+ *
+ * Tells the discipline that the DCD pin has changed its status and
+ * the relative timestamp. Pointer ts can be NULL.
*/
#include <linux/fs.h>
@@ -136,6 +142,8 @@ struct tty_ldisc_ops {
void (*receive_buf)(struct tty_struct *, const unsigned char *cp,
char *fp, int count);
void (*write_wakeup)(struct tty_struct *);
+ void (*dcd_change)(struct tty_struct *, unsigned int,
+ struct timespec *);
struct module *owner;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 3492abf82e7..739f1fd1cc1 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -512,9 +512,9 @@ extern struct usb_device *usb_get_dev(struct usb_device *dev);
extern void usb_put_dev(struct usb_device *dev);
/* USB device locking */
-#define usb_lock_device(udev) down(&(udev)->dev.sem)
-#define usb_unlock_device(udev) up(&(udev)->dev.sem)
-#define usb_trylock_device(udev) down_trylock(&(udev)->dev.sem)
+#define usb_lock_device(udev) device_lock(&(udev)->dev)
+#define usb_unlock_device(udev) device_unlock(&(udev)->dev)
+#define usb_trylock_device(udev) device_trylock(&(udev)->dev)
extern int usb_lock_device_for_reset(struct usb_device *udev,
const struct usb_interface *iface);
@@ -1055,7 +1055,8 @@ typedef void (*usb_complete_t)(struct urb *);
* @number_of_packets: Lists the number of ISO transfer buffers.
* @interval: Specifies the polling interval for interrupt or isochronous
* transfers. The units are frames (milliseconds) for full and low
- * speed devices, and microframes (1/8 millisecond) for highspeed ones.
+ * speed devices, and microframes (1/8 millisecond) for highspeed
+ * and SuperSpeed devices.
* @error_count: Returns the number of ISO transfers that reported errors.
* @context: For use in completion functions. This normally points to
* request-specific driver context.
@@ -1084,7 +1085,7 @@ typedef void (*usb_complete_t)(struct urb *);
* Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
* which tell the host controller driver that no such mapping is needed since
* the device driver is DMA-aware. For example, a device driver might
- * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
+ * allocate a DMA buffer with usb_alloc_coherent() or call usb_buffer_map().
* When these transfer flags are provided, host controller drivers will
* attempt to use the dma addresses found in the transfer_dma and/or
* setup_dma fields rather than determining a dma address themselves.
@@ -1286,9 +1287,16 @@ static inline void usb_fill_bulk_urb(struct urb *urb,
*
* Initializes a interrupt urb with the proper information needed to submit
* it to a device.
- * Note that high speed interrupt endpoints use a logarithmic encoding of
- * the endpoint interval, and express polling intervals in microframes
- * (eight per millisecond) rather than in frames (one per millisecond).
+ *
+ * Note that High Speed and SuperSpeed interrupt endpoints use a logarithmic
+ * encoding of the endpoint interval, and express polling intervals in
+ * microframes (eight per millisecond) rather than in frames (one per
+ * millisecond).
+ *
+ * Wireless USB also uses the logarithmic encoding, but specifies it in units of
+ * 128us instead of 125us. For Wireless USB devices, the interval is passed
+ * through to the host controller, rather than being translated into microframe
+ * units.
*/
static inline void usb_fill_int_urb(struct urb *urb,
struct usb_device *dev,
@@ -1305,7 +1313,7 @@ static inline void usb_fill_int_urb(struct urb *urb,
urb->transfer_buffer_length = buffer_length;
urb->complete = complete_fn;
urb->context = context;
- if (dev->speed == USB_SPEED_HIGH)
+ if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER)
urb->interval = 1 << (interval - 1);
else
urb->interval = interval;
@@ -1358,11 +1366,23 @@ static inline int usb_urb_dir_out(struct urb *urb)
return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
}
-void *usb_buffer_alloc(struct usb_device *dev, size_t size,
+void *usb_alloc_coherent(struct usb_device *dev, size_t size,
gfp_t mem_flags, dma_addr_t *dma);
-void usb_buffer_free(struct usb_device *dev, size_t size,
+void usb_free_coherent(struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma);
+/* Compatible macros while we switch over */
+static inline void *usb_buffer_alloc(struct usb_device *dev, size_t size,
+ gfp_t mem_flags, dma_addr_t *dma)
+{
+ return usb_alloc_coherent(dev, size, mem_flags, dma);
+}
+static inline void usb_buffer_free(struct usb_device *dev, size_t size,
+ void *addr, dma_addr_t dma)
+{
+ return usb_free_coherent(dev, size, addr, dma);
+}
+
#if 0
struct urb *usb_buffer_map(struct urb *urb);
void usb_buffer_dmasync(struct urb *urb);
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h
index 6bb293684eb..4d3e450e2b0 100644
--- a/include/linux/usb/audio.h
+++ b/include/linux/usb/audio.h
@@ -269,8 +269,8 @@ struct uac_format_type_i_ext_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
- __u8 bSubslotSize;
__u8 bFormatType;
+ __u8 bSubslotSize;
__u8 bBitResolution;
__u8 bHeaderLength;
__u8 bControlSize;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index bbf45d500b6..f4b7ca516cd 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -15,6 +15,8 @@
#ifndef __LINUX_USB_GADGET_H
#define __LINUX_USB_GADGET_H
+#include <linux/slab.h>
+
struct usb_ep;
/**
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index f508c651e53..40d1709bdbf 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -98,6 +98,7 @@ struct virtio_device {
void *priv;
};
+#define dev_to_virtio(dev) container_of(dev, struct virtio_device, dev)
int register_virtio_device(struct virtio_device *dev);
void unregister_virtio_device(struct virtio_device *dev);
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h
index 095e10d148b..5cf11765146 100644
--- a/include/linux/virtio_9p.h
+++ b/include/linux/virtio_9p.h
@@ -5,7 +5,16 @@
#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
-/* Maximum number of virtio channels per partition (1 for now) */
-#define MAX_9P_CHAN 1
+/* The feature bitmap for virtio 9P */
+
+/* The mount point is specified in a config variable */
+#define VIRTIO_9P_MOUNT_TAG 0
+
+struct virtio_9p_config {
+ /* length of the tag name */
+ __u16 tag_len;
+ /* non-NULL terminated tag name */
+ __u8 tag[0];
+} __attribute__((packed));
#endif /* _LINUX_VIRTIO_9P_H */
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h
index ae4f039515b..92228a8fbcb 100644
--- a/include/linux/virtio_console.h
+++ b/include/linux/virtio_console.h
@@ -12,37 +12,14 @@
/* Feature bits */
#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */
-#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */
struct virtio_console_config {
/* colums of the screens */
__u16 cols;
/* rows of the screens */
__u16 rows;
- /* max. number of ports this device can hold */
- __u32 max_nr_ports;
- /* number of ports added so far */
- __u32 nr_ports;
} __attribute__((packed));
-/*
- * A message that's passed between the Host and the Guest for a
- * particular port.
- */
-struct virtio_console_control {
- __u32 id; /* Port number */
- __u16 event; /* The kind of control event (see below) */
- __u16 value; /* Extra information for the key */
-};
-
-/* Some events for control messages */
-#define VIRTIO_CONSOLE_PORT_READY 0
-#define VIRTIO_CONSOLE_CONSOLE_PORT 1
-#define VIRTIO_CONSOLE_RESIZE 2
-#define VIRTIO_CONSOLE_PORT_OPEN 3
-#define VIRTIO_CONSOLE_PORT_NAME 4
-#define VIRTIO_CONSOLE_PORT_REMOVE 5
-
#ifdef __KERNEL__
int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
#endif /* __KERNEL__ */
diff --git a/include/linux/vt.h b/include/linux/vt.h
index 778b7b2a47d..d5dd0bc408f 100644
--- a/include/linux/vt.h
+++ b/include/linux/vt.h
@@ -27,7 +27,7 @@ struct vt_mode {
#define VT_SETMODE 0x5602 /* set mode of active vt */
#define VT_AUTO 0x00 /* auto vt switching */
#define VT_PROCESS 0x01 /* process controls switching */
-#define VT_PROCESS_AUTO 0x02 /* process is notified of switching */
+#define VT_ACKACQ 0x02 /* acknowledge switch */
struct vt_stat {
unsigned short v_active; /* active vt */
@@ -38,7 +38,6 @@ struct vt_stat {
#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */
#define VT_RELDISP 0x5605 /* release display */
-#define VT_ACKACQ 0x02 /* acknowledge switch */
#define VT_ACTIVATE 0x5606 /* make vt active */
#define VT_WAITACTIVE 0x5607 /* wait for vt active */
diff --git a/include/linux/wimax/debug.h b/include/linux/wimax/debug.h
index db8096e8853..57031b4d12f 100644
--- a/include/linux/wimax/debug.h
+++ b/include/linux/wimax/debug.h
@@ -155,6 +155,7 @@
#include <linux/types.h>
#include <linux/device.h>
+#include <linux/slab.h>
/* Backend stuff */
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 76e8903cd20..36520ded3e0 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -34,6 +34,9 @@ struct writeback_control {
enum writeback_sync_modes sync_mode;
unsigned long *older_than_this; /* If !NULL, only write back inodes
older than this */
+ unsigned long wb_start; /* Time writeback_inodes_wb was
+ called. This is needed to avoid
+ extra jobs and livelock */
long nr_to_write; /* Write this many pages, and decrement
this for each page written */
long pages_skipped; /* Pages which were not written */
diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
index f456534dcaf..fd882261225 100644
--- a/include/math-emu/op-common.h
+++ b/include/math-emu/op-common.h
@@ -29,7 +29,7 @@
_FP_FRAC_DECL_##wc(X)
/*
- * Finish truely unpacking a native fp value by classifying the kind
+ * Finish truly unpacking a native fp value by classifying the kind
* of fp value and normalizing both the exponent and the fraction.
*/
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
index d863e5e8426..4314a5f6a08 100644
--- a/include/media/davinci/vpfe_capture.h
+++ b/include/media/davinci/vpfe_capture.h
@@ -165,7 +165,7 @@ struct vpfe_device {
u8 started;
/*
* offset where second field starts from the starting of the
- * buffer for field seperated YCbCr formats
+ * buffer for field separated YCbCr formats
*/
u32 field_off;
};
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index fb00b329f0d..4f3760afc20 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -29,6 +29,19 @@
/* Number of requests per row */
#define P9_ROW_MAXTAG 255
+/** enum p9_proto_versions - 9P protocol versions
+ * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u
+ * @p9_proto_2000u: 9P2000.u extension
+ * @p9_proto_2000L: 9P2000.L extension
+ */
+
+enum p9_proto_versions{
+ p9_proto_legacy = 0,
+ p9_proto_2000u = 1,
+ p9_proto_2000L = 2,
+};
+
+
/**
* enum p9_trans_status - different states of underlying transports
* @Connected: transport is connected and healthy
@@ -41,6 +54,7 @@
enum p9_trans_status {
Connected,
+ BeginDisconnect,
Disconnected,
Hung,
};
@@ -111,6 +125,7 @@ struct p9_req_t {
* @lock: protect @fidlist
* @msize: maximum data size negotiated by protocol
* @dotu: extension flags negotiated by protocol
+ * @proto_version: 9P protocol version to use
* @trans_mod: module API instantiated with this client
* @trans: tranport instance state and API
* @conn: connection state information used by trans_fd
@@ -137,7 +152,7 @@ struct p9_req_t {
struct p9_client {
spinlock_t lock; /* protect client structure */
int msize;
- unsigned char dotu;
+ unsigned char proto_version;
struct p9_trans_module *trans_mod;
enum p9_trans_status status;
void *trans;
@@ -184,6 +199,7 @@ int p9_client_version(struct p9_client *);
struct p9_client *p9_client_create(const char *dev_name, char *options);
void p9_client_destroy(struct p9_client *clnt);
void p9_client_disconnect(struct p9_client *clnt);
+void p9_client_begin_disconnect(struct p9_client *clnt);
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
char *uname, u32 n_uname, char *aname);
struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
@@ -209,5 +225,7 @@ int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int);
int p9stat_read(char *, int, struct p9_wstat *, int);
void p9stat_free(struct p9_wstat *);
+int p9_is_proto_dotu(struct p9_client *clnt);
+int p9_is_proto_dotl(struct p9_client *clnt);
#endif /* NET_9P_CLIENT_H */
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 717e2192d52..206d22297ac 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -10,6 +10,7 @@
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#define AX25_T1CLAMPLO 1
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 04a6908e38d..ff77e8f882f 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -176,6 +176,6 @@ extern void hci_sock_cleanup(void);
extern int bt_sysfs_init(void);
extern void bt_sysfs_cleanup(void);
-extern struct class *bt_class;
+extern struct dentry *bt_debugfs;
#endif /* __BLUETOOTH_H */
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index c07ac9650eb..c49086d2bc7 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -2,6 +2,7 @@
#define __NET_FIB_RULES_H
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/fib_rules.h>
#include <net/flow.h>
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 4a808de7c0f..68f67836e14 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -37,6 +37,24 @@ struct route_info {
#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010
#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020
+/*
+ * rt6_srcprefs2flags() and rt6_flags2srcprefs() translate
+ * between IPV6_ADDR_PREFERENCES socket option values
+ * IPV6_PREFER_SRC_TMP = 0x1
+ * IPV6_PREFER_SRC_PUBLIC = 0x2
+ * IPV6_PREFER_SRC_COA = 0x4
+ * and above RT6_LOOKUP_F_SRCPREF_xxx flags.
+ */
+static inline int rt6_srcprefs2flags(unsigned int srcprefs)
+{
+ /* No need to bitmask because srcprefs have only 3 bits. */
+ return srcprefs << 3;
+}
+
+static inline unsigned int rt6_flags2srcprefs(int flags)
+{
+ return (flags >> 3) & 7;
+}
extern void ip6_route_input(struct sk_buff *skb);
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index 83b4e008b16..fbf9d1cda27 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -15,7 +15,6 @@
struct ip6_tnl {
struct ip6_tnl *next; /* next tunnel in list */
struct net_device *dev; /* virtual device associated with tunnel */
- int recursion; /* depth of hard_start_xmit recursion */
struct ip6_tnl_parm parms; /* tunnel configuration parameters */
struct flowi fl; /* flowi template for xmit */
struct dst_entry *dst_cache; /* cached dst */
diff --git a/include/net/ipx.h b/include/net/ipx.h
index a14121dd193..ef51a668ba1 100644
--- a/include/net/ipx.h
+++ b/include/net/ipx.h
@@ -13,6 +13,7 @@
#include <net/datalink.h>
#include <linux/ipx.h>
#include <linux/list.h>
+#include <linux/slab.h>
struct ipx_address {
__be32 net;
diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h
index 0788c23d282..11aee7a2972 100644
--- a/include/net/irda/irttp.h
+++ b/include/net/irda/irttp.h
@@ -97,7 +97,7 @@
#define TTP_MAX_SDU_SIZE 0x01
/*
- * This structure contains all data assosiated with one instance of a TTP
+ * This structure contains all data associated with one instance of a TTP
* connection.
*/
struct tsap_cb {
diff --git a/include/net/iucv/iucv.h b/include/net/iucv/iucv.h
index 5e310c8d8e2..205a3360156 100644
--- a/include/net/iucv/iucv.h
+++ b/include/net/iucv/iucv.h
@@ -28,6 +28,7 @@
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <asm/debug.h>
/*
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 80eb7cc42ce..45d7d44d7cb 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2426,7 +2426,8 @@ struct rate_control_ops {
struct ieee80211_sta *sta, void *priv_sta);
void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta,
- void *priv_sta, u32 changed);
+ void *priv_sta, u32 changed,
+ enum nl80211_channel_type oper_chan_type);
void (*free_sta)(void *priv, struct ieee80211_sta *sta,
void *priv_sta);
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 82b7be4db89..bd10a790899 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -100,14 +100,9 @@ struct net {
extern struct net init_net;
#ifdef CONFIG_NET
-#define INIT_NET_NS(net_ns) .net_ns = &init_net,
-
extern struct net *copy_net_ns(unsigned long flags, struct net *net_ns);
#else /* CONFIG_NET */
-
-#define INIT_NET_NS(net_ns)
-
static inline struct net *copy_net_ns(unsigned long flags, struct net *net_ns)
{
/* There is nothing to copy so this is a noop */
diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
index 2d2a1f9a61d..32d15bd6efa 100644
--- a/include/net/netfilter/nf_conntrack_extend.h
+++ b/include/net/netfilter/nf_conntrack_extend.h
@@ -1,6 +1,8 @@
#ifndef _NF_CONNTRACK_EXTEND_H
#define _NF_CONNTRACK_EXTEND_H
+#include <linux/slab.h>
+
#include <net/netfilter/nf_conntrack.h>
enum nf_ct_ext_id {
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 60ebbc1fef4..9db401a8b4d 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -31,6 +31,7 @@
#define _NETLABEL_H
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/in.h>
diff --git a/include/net/netlink.h b/include/net/netlink.h
index f82e463c875..4fc05b58503 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -945,7 +945,11 @@ static inline u64 nla_get_u64(const struct nlattr *nla)
*/
static inline __be64 nla_get_be64(const struct nlattr *nla)
{
- return *(__be64 *) nla_data(nla);
+ __be64 tmp;
+
+ nla_memcpy(&tmp, nla, sizeof(tmp));
+
+ return tmp;
}
/**
diff --git a/include/net/netrom.h b/include/net/netrom.h
index ab170a60e7d..f0793c1cb5f 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -9,6 +9,7 @@
#include <linux/netrom.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/sock.h>
#define NR_NETWORK_LEN 15
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 8be5135ff7a..2c55a7ea20a 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -107,6 +107,7 @@ typedef enum {
SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */
SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
SCTP_CMD_SEND_MSG, /* Send the whole use message */
+ SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
SCTP_CMD_LAST
} sctp_verb_t;
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 78740ec57d5..fa6cde578a1 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -128,6 +128,7 @@ extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb);
int sctp_inet_listen(struct socket *sock, int backlog);
void sctp_write_space(struct sock *sk);
+void sctp_data_ready(struct sock *sk, int len);
unsigned int sctp_poll(struct file *file, struct socket *sock,
poll_table *wait);
void sctp_sock_rfree(struct sk_buff *skb);
diff --git a/include/net/sock.h b/include/net/sock.h
index 6cb1676e409..b4603cd54fc 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -51,6 +51,7 @@
#include <linux/skbuff.h> /* struct sk_buff */
#include <linux/mm.h>
#include <linux/security.h>
+#include <linux/slab.h>
#include <linux/filter.h>
#include <linux/rculist_nulls.h>
@@ -253,6 +254,8 @@ struct sock {
struct {
struct sk_buff *head;
struct sk_buff *tail;
+ int len;
+ int limit;
} sk_backlog;
wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache;
@@ -589,8 +592,8 @@ static inline int sk_stream_memory_free(struct sock *sk)
return sk->sk_wmem_queued < sk->sk_sndbuf;
}
-/* The per-socket spinlock must be held here. */
-static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
+/* OOB backlog add */
+static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
{
if (!sk->sk_backlog.tail) {
sk->sk_backlog.head = sk->sk_backlog.tail = skb;
@@ -601,6 +604,17 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
skb->next = NULL;
}
+/* The per-socket spinlock must be held here. */
+static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb)
+{
+ if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1))
+ return -ENOBUFS;
+
+ __sk_add_backlog(sk, skb);
+ sk->sk_backlog.len += skb->truesize;
+ return 0;
+}
+
static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
return sk->sk_backlog_rcv(sk, skb);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 56f0aec40ed..75be5a28815 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -939,7 +939,7 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
tp->ucopy.memory = 0;
} else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
- wake_up_interruptible_poll(sk->sk_sleep,
+ wake_up_interruptible_sync_poll(sk->sk_sleep,
POLLIN | POLLRDNORM | POLLRDBAND);
if (!inet_csk_ack_scheduled(sk))
inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
diff --git a/include/net/x25.h b/include/net/x25.h
index 9baa07dc7d1..468551ea4f1 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -10,6 +10,7 @@
#ifndef _X25_H
#define _X25_H
#include <linux/x25.h>
+#include <linux/slab.h>
#include <net/sock.h>
#define X25_ADDR_LEN 16
@@ -182,6 +183,10 @@ extern int sysctl_x25_clear_request_timeout;
extern int sysctl_x25_ack_holdback_timeout;
extern int sysctl_x25_forward;
+extern int x25_parse_address_block(struct sk_buff *skb,
+ struct x25_address *called_addr,
+ struct x25_address *calling_addr);
+
extern int x25_addr_ntoa(unsigned char *, struct x25_address *,
struct x25_address *);
extern int x25_addr_aton(unsigned char *, struct x25_address *,
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index a7df3275b86..ac52f33f3e4 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -12,6 +12,7 @@
#include <linux/in6.h>
#include <linux/mutex.h>
#include <linux/audit.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/dst.h>
@@ -275,7 +276,8 @@ struct xfrm_policy_afinfo {
struct dst_entry *dst,
int nfheader_len);
int (*fill_dst)(struct xfrm_dst *xdst,
- struct net_device *dev);
+ struct net_device *dev,
+ struct flowi *fl);
};
extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index d57847f2f6c..aab3c13dc31 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -26,6 +26,7 @@
#ifdef __KERNEL__
#include <linux/device.h>
#include <pcmcia/ss.h>
+#include <asm/atomic.h>
/*
* PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus
@@ -94,10 +95,8 @@ struct pcmcia_device {
config_req_t conf;
window_handle_t win;
- /* Is the device suspended, or in the process of
- * being removed? */
+ /* Is the device suspended? */
u16 suspended:1;
- u16 _removed:1;
/* Flags whether io, irq, win configurations were
* requested, and whether the configuration is "locked" */
@@ -115,7 +114,7 @@ struct pcmcia_device {
u16 has_card_id:1;
u16 has_func_id:1;
- u16 reserved:3;
+ u16 reserved:4;
u8 func_id;
u16 manf_id;
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 32896a77391..344705cb42f 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -224,18 +224,16 @@ struct pcmcia_socket {
/* 16-bit state: */
struct {
- /* PCMCIA card is present in socket */
- u8 present:1;
/* "master" ioctl is used */
u8 busy:1;
- /* pcmcia module is being unloaded */
- u8 dead:1;
/* the PCMCIA card consists of two pseudo devices */
u8 has_pfc:1;
- u8 reserved:4;
+ u8 reserved:6;
} pcmcia_state;
+ /* non-zero if PCMCIA card is present */
+ atomic_t present;
#ifdef CONFIG_PCMCIA_IOCTL
struct user_info_t *user;
@@ -277,12 +275,6 @@ extern struct pccard_resource_ops pccard_nonstatic_ops;
#endif
-/* socket drivers are expected to use these callbacks in their .drv struct */
-extern int pcmcia_socket_dev_suspend(struct device *dev);
-extern void pcmcia_socket_dev_early_resume(struct device *dev);
-extern void pcmcia_socket_dev_late_resume(struct device *dev);
-extern int pcmcia_socket_dev_resume(struct device *dev);
-
/* socket drivers use this callback in their IRQ handler */
extern void pcmcia_parse_events(struct pcmcia_socket *socket,
unsigned int events);
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index ff92b46f515..ae5196aae1a 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -338,7 +338,8 @@ struct iscsi_host {
extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth,
int reason);
extern int iscsi_eh_abort(struct scsi_cmnd *sc);
-extern int iscsi_eh_target_reset(struct scsi_cmnd *sc);
+extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
+extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
extern int iscsi_queuecommand(struct scsi_cmnd *sc,
void (*done)(struct scsi_cmnd *));
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 9eaa3f05f95..3b586859669 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -36,6 +36,7 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_transport_sas.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
struct block_device;
diff --git a/include/scsi/sg.h b/include/scsi/sg.h
index 934ae389671..a9f3c6fc3f5 100644
--- a/include/scsi/sg.h
+++ b/include/scsi/sg.h
@@ -70,6 +70,9 @@ Major new features in SG 3.x driver (cf SG 2.x drivers)
(for the lk 2.2 series).
*/
+#ifdef __KERNEL__
+extern int sg_big_buff; /* for sysctl */
+#endif
/* New interface introduced in the 3.x SG drivers follows */
diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h
index 8988edae160..2609048c1d4 100644
--- a/include/sound/ak4113.h
+++ b/include/sound/ak4113.h
@@ -307,7 +307,7 @@ struct ak4113 {
int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
ak4113_write_t *write,
- const unsigned char pgm[AK4113_WRITABLE_REGS],
+ const unsigned char *pgm,
void *private_data, struct ak4113 **r_ak4113);
void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg,
unsigned char mask, unsigned char val);
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 1f57bb92eb5..09859550063 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -544,7 +544,7 @@ struct snd_rawmidi_status {
* Timer section - /dev/snd/timer
*/
-#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 5)
+#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
enum {
SNDRV_TIMER_CLASS_NONE = -1,
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 061f16d4c87..0a0b019d41a 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -219,7 +219,6 @@ struct snd_soc_dai {
struct snd_soc_codec *codec;
unsigned int active;
unsigned char pop_wait:1;
- void *dma_data;
/* DAI private data */
void *private_data;
@@ -230,4 +229,21 @@ struct snd_soc_dai {
struct list_head list;
};
+static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
+ const struct snd_pcm_substream *ss)
+{
+ return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ dai->playback.dma_data : dai->capture.dma_data;
+}
+
+static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
+ const struct snd_pcm_substream *ss,
+ void *data)
+{
+ if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dai->playback.dma_data = data;
+ else
+ dai->capture.dma_data = data;
+}
+
#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 5d234a8c250..a57fbfcd4c8 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -375,6 +375,7 @@ struct snd_soc_pcm_stream {
unsigned int channels_min; /* min channels */
unsigned int channels_max; /* max channels */
unsigned int active:1; /* stream is in use */
+ void *dma_data; /* used by platform code */
};
/* SoC audio ops */
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index 5fb72733331..d870a918559 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -40,6 +40,16 @@ DECLARE_EVENT_CLASS(block_rq_with_error,
__entry->nr_sector, __entry->errors)
);
+/**
+ * block_rq_abort - abort block operation request
+ * @q: queue containing the block operation request
+ * @rq: block IO operation request
+ *
+ * Called immediately after pending block IO operation request @rq in
+ * queue @q is aborted. The fields in the operation request @rq
+ * can be examined to determine which device and sectors the pending
+ * operation would access.
+ */
DEFINE_EVENT(block_rq_with_error, block_rq_abort,
TP_PROTO(struct request_queue *q, struct request *rq),
@@ -47,6 +57,15 @@ DEFINE_EVENT(block_rq_with_error, block_rq_abort,
TP_ARGS(q, rq)
);
+/**
+ * block_rq_requeue - place block IO request back on a queue
+ * @q: queue holding operation
+ * @rq: block IO operation request
+ *
+ * The block operation request @rq is being placed back into queue
+ * @q. For some reason the request was not completed and needs to be
+ * put back in the queue.
+ */
DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
TP_PROTO(struct request_queue *q, struct request *rq),
@@ -54,6 +73,17 @@ DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
TP_ARGS(q, rq)
);
+/**
+ * block_rq_complete - block IO operation completed by device driver
+ * @q: queue containing the block operation request
+ * @rq: block operations request
+ *
+ * The block_rq_complete tracepoint event indicates that some portion
+ * of operation request has been completed by the device driver. If
+ * the @rq->bio is %NULL, then there is absolutely no additional work to
+ * do for the request. If @rq->bio is non-NULL then there is
+ * additional work required to complete the request.
+ */
DEFINE_EVENT(block_rq_with_error, block_rq_complete,
TP_PROTO(struct request_queue *q, struct request *rq),
@@ -95,6 +125,16 @@ DECLARE_EVENT_CLASS(block_rq,
__entry->nr_sector, __entry->comm)
);
+/**
+ * block_rq_insert - insert block operation request into queue
+ * @q: target queue
+ * @rq: block IO operation request
+ *
+ * Called immediately before block operation request @rq is inserted
+ * into queue @q. The fields in the operation request @rq struct can
+ * be examined to determine which device and sectors the pending
+ * operation would access.
+ */
DEFINE_EVENT(block_rq, block_rq_insert,
TP_PROTO(struct request_queue *q, struct request *rq),
@@ -102,6 +142,14 @@ DEFINE_EVENT(block_rq, block_rq_insert,
TP_ARGS(q, rq)
);
+/**
+ * block_rq_issue - issue pending block IO request operation to device driver
+ * @q: queue holding operation
+ * @rq: block IO operation operation request
+ *
+ * Called when block operation request @rq from queue @q is sent to a
+ * device driver for processing.
+ */
DEFINE_EVENT(block_rq, block_rq_issue,
TP_PROTO(struct request_queue *q, struct request *rq),
@@ -109,6 +157,17 @@ DEFINE_EVENT(block_rq, block_rq_issue,
TP_ARGS(q, rq)
);
+/**
+ * block_bio_bounce - used bounce buffer when processing block operation
+ * @q: queue holding the block operation
+ * @bio: block operation
+ *
+ * A bounce buffer was used to handle the block operation @bio in @q.
+ * This occurs when hardware limitations prevent a direct transfer of
+ * data between the @bio data memory area and the IO device. Use of a
+ * bounce buffer requires extra copying of data and decreases
+ * performance.
+ */
TRACE_EVENT(block_bio_bounce,
TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -138,6 +197,14 @@ TRACE_EVENT(block_bio_bounce,
__entry->nr_sector, __entry->comm)
);
+/**
+ * block_bio_complete - completed all work on the block operation
+ * @q: queue holding the block operation
+ * @bio: block operation completed
+ *
+ * This tracepoint indicates there is no further work to do on this
+ * block IO operation @bio.
+ */
TRACE_EVENT(block_bio_complete,
TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -193,6 +260,14 @@ DECLARE_EVENT_CLASS(block_bio,
__entry->nr_sector, __entry->comm)
);
+/**
+ * block_bio_backmerge - merging block operation to the end of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block request @bio to the end of an existing block request
+ * in queue @q.
+ */
DEFINE_EVENT(block_bio, block_bio_backmerge,
TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -200,6 +275,14 @@ DEFINE_EVENT(block_bio, block_bio_backmerge,
TP_ARGS(q, bio)
);
+/**
+ * block_bio_frontmerge - merging block operation to the beginning of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block IO operation @bio to the beginning of an existing block
+ * operation in queue @q.
+ */
DEFINE_EVENT(block_bio, block_bio_frontmerge,
TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -207,6 +290,13 @@ DEFINE_EVENT(block_bio, block_bio_frontmerge,
TP_ARGS(q, bio)
);
+/**
+ * block_bio_queue - putting new block IO operation in queue
+ * @q: queue holding operation
+ * @bio: new block operation
+ *
+ * About to place the block IO operation @bio into queue @q.
+ */
DEFINE_EVENT(block_bio, block_bio_queue,
TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -243,6 +333,15 @@ DECLARE_EVENT_CLASS(block_get_rq,
__entry->nr_sector, __entry->comm)
);
+/**
+ * block_getrq - get a free request entry in queue for block IO operations
+ * @q: queue for operations
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * A request struct for queue @q has been allocated to handle the
+ * block IO operation @bio.
+ */
DEFINE_EVENT(block_get_rq, block_getrq,
TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
@@ -250,6 +349,17 @@ DEFINE_EVENT(block_get_rq, block_getrq,
TP_ARGS(q, bio, rw)
);
+/**
+ * block_sleeprq - waiting to get a free request entry in queue for block IO operation
+ * @q: queue for operation
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * In the case where a request struct cannot be provided for queue @q
+ * the process needs to wait for an request struct to become
+ * available. This tracepoint event is generated each time the
+ * process goes to sleep waiting for request struct become available.
+ */
DEFINE_EVENT(block_get_rq, block_sleeprq,
TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
@@ -257,6 +367,14 @@ DEFINE_EVENT(block_get_rq, block_sleeprq,
TP_ARGS(q, bio, rw)
);
+/**
+ * block_plug - keep operations requests in request queue
+ * @q: request queue to plug
+ *
+ * Plug the request queue @q. Do not allow block operation requests
+ * to be sent to the device driver. Instead, accumulate requests in
+ * the queue to improve throughput performance of the block device.
+ */
TRACE_EVENT(block_plug,
TP_PROTO(struct request_queue *q),
@@ -293,6 +411,13 @@ DECLARE_EVENT_CLASS(block_unplug,
TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
);
+/**
+ * block_unplug_timer - timed release of operations requests in queue to device driver
+ * @q: request queue to unplug
+ *
+ * Unplug the request queue @q because a timer expired and allow block
+ * operation requests to be sent to the device driver.
+ */
DEFINE_EVENT(block_unplug, block_unplug_timer,
TP_PROTO(struct request_queue *q),
@@ -300,6 +425,13 @@ DEFINE_EVENT(block_unplug, block_unplug_timer,
TP_ARGS(q)
);
+/**
+ * block_unplug_io - release of operations requests in request queue
+ * @q: request queue to unplug
+ *
+ * Unplug request queue @q because device driver is scheduled to work
+ * on elements in the request queue.
+ */
DEFINE_EVENT(block_unplug, block_unplug_io,
TP_PROTO(struct request_queue *q),
@@ -307,6 +439,17 @@ DEFINE_EVENT(block_unplug, block_unplug_io,
TP_ARGS(q)
);
+/**
+ * block_split - split a single bio struct into two bio structs
+ * @q: queue containing the bio
+ * @bio: block operation being split
+ * @new_sector: The starting sector for the new bio
+ *
+ * The bio request @bio in request queue @q needs to be split into two
+ * bio requests. The newly created @bio request starts at
+ * @new_sector. This split may be required due to hardware limitation
+ * such as operation crossing device boundaries in a RAID system.
+ */
TRACE_EVENT(block_split,
TP_PROTO(struct request_queue *q, struct bio *bio,
@@ -337,6 +480,16 @@ TRACE_EVENT(block_split,
__entry->comm)
);
+/**
+ * block_remap - map request for a partition to the raw device
+ * @q: queue holding the operation
+ * @bio: revised operation
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * An operation for a partition on a block device has been mapped to the
+ * raw block device.
+ */
TRACE_EVENT(block_remap,
TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
@@ -370,6 +523,17 @@ TRACE_EVENT(block_remap,
(unsigned long long)__entry->old_sector)
);
+/**
+ * block_rq_remap - map request for a block operation request
+ * @q: queue holding the operation
+ * @rq: block IO operation request
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * The block operation request @rq in @q has been remapped. The block
+ * operation request @rq holds the current information and @from hold
+ * the original sector.
+ */
TRACE_EVENT(block_rq_remap,
TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index d0b6cd3afb2..2aa6aa3e8f6 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -874,6 +874,107 @@ TRACE_EVENT(ext4_forget,
__entry->mode, __entry->is_metadata, __entry->block)
);
+TRACE_EVENT(ext4_da_update_reserve_space,
+ TP_PROTO(struct inode *inode, int used_blocks),
+
+ TP_ARGS(inode, used_blocks),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( umode_t, mode )
+ __field( __u64, i_blocks )
+ __field( int, used_blocks )
+ __field( int, reserved_data_blocks )
+ __field( int, reserved_meta_blocks )
+ __field( int, allocated_meta_blocks )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->mode = inode->i_mode;
+ __entry->i_blocks = inode->i_blocks;
+ __entry->used_blocks = used_blocks;
+ __entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
+ __entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
+ __entry->allocated_meta_blocks = EXT4_I(inode)->i_allocated_meta_blocks;
+ ),
+
+ TP_printk("dev %s ino %lu mode 0%o i_blocks %llu used_blocks %d reserved_data_blocks %d reserved_meta_blocks %d allocated_meta_blocks %d",
+ jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+ __entry->mode, (unsigned long long) __entry->i_blocks,
+ __entry->used_blocks, __entry->reserved_data_blocks,
+ __entry->reserved_meta_blocks, __entry->allocated_meta_blocks)
+);
+
+TRACE_EVENT(ext4_da_reserve_space,
+ TP_PROTO(struct inode *inode, int md_needed),
+
+ TP_ARGS(inode, md_needed),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( umode_t, mode )
+ __field( __u64, i_blocks )
+ __field( int, md_needed )
+ __field( int, reserved_data_blocks )
+ __field( int, reserved_meta_blocks )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->mode = inode->i_mode;
+ __entry->i_blocks = inode->i_blocks;
+ __entry->md_needed = md_needed;
+ __entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
+ __entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
+ ),
+
+ TP_printk("dev %s ino %lu mode 0%o i_blocks %llu md_needed %d reserved_data_blocks %d reserved_meta_blocks %d",
+ jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+ __entry->mode, (unsigned long long) __entry->i_blocks,
+ __entry->md_needed, __entry->reserved_data_blocks,
+ __entry->reserved_meta_blocks)
+);
+
+TRACE_EVENT(ext4_da_release_space,
+ TP_PROTO(struct inode *inode, int freed_blocks),
+
+ TP_ARGS(inode, freed_blocks),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( umode_t, mode )
+ __field( __u64, i_blocks )
+ __field( int, freed_blocks )
+ __field( int, reserved_data_blocks )
+ __field( int, reserved_meta_blocks )
+ __field( int, allocated_meta_blocks )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->mode = inode->i_mode;
+ __entry->i_blocks = inode->i_blocks;
+ __entry->freed_blocks = freed_blocks;
+ __entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
+ __entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
+ __entry->allocated_meta_blocks = EXT4_I(inode)->i_allocated_meta_blocks;
+ ),
+
+ TP_printk("dev %s ino %lu mode 0%o i_blocks %llu freed_blocks %d reserved_data_blocks %d reserved_meta_blocks %d allocated_meta_blocks %d",
+ jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+ __entry->mode, (unsigned long long) __entry->i_blocks,
+ __entry->freed_blocks, __entry->reserved_data_blocks,
+ __entry->reserved_meta_blocks, __entry->allocated_meta_blocks)
+);
+
+
#endif /* _TRACE_EXT4_H */
/* This part must be outside protection */
diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
index 96b370a050d..bf16545cc97 100644
--- a/include/trace/events/jbd2.h
+++ b/include/trace/events/jbd2.h
@@ -199,6 +199,34 @@ TRACE_EVENT(jbd2_checkpoint_stats,
__entry->forced_to_close, __entry->written, __entry->dropped)
);
+TRACE_EVENT(jbd2_cleanup_journal_tail,
+
+ TP_PROTO(journal_t *journal, tid_t first_tid,
+ unsigned long block_nr, unsigned long freed),
+
+ TP_ARGS(journal, first_tid, block_nr, freed),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( tid_t, tail_sequence )
+ __field( tid_t, first_tid )
+ __field(unsigned long, block_nr )
+ __field(unsigned long, freed )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = journal->j_fs_dev->bd_dev;
+ __entry->tail_sequence = journal->j_tail_sequence;
+ __entry->first_tid = first_tid;
+ __entry->block_nr = block_nr;
+ __entry->freed = freed;
+ ),
+
+ TP_printk("dev %s from %u to %u offset %lu freed %lu",
+ jbd2_dev_to_name(__entry->dev), __entry->tail_sequence,
+ __entry->first_tid, __entry->block_nr, __entry->freed)
+);
+
#endif /* _TRACE_JBD2_H */
/* This part must be outside protection */
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index dbe10845527..b17d49dfc3e 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -145,6 +145,47 @@ TRACE_EVENT(kvm_mmio,
__entry->len, __entry->gpa, __entry->val)
);
+#define kvm_fpu_load_symbol \
+ {0, "unload"}, \
+ {1, "load"}
+
+TRACE_EVENT(kvm_fpu,
+ TP_PROTO(int load),
+ TP_ARGS(load),
+
+ TP_STRUCT__entry(
+ __field( u32, load )
+ ),
+
+ TP_fast_assign(
+ __entry->load = load;
+ ),
+
+ TP_printk("%s", __print_symbolic(__entry->load, kvm_fpu_load_symbol))
+);
+
+TRACE_EVENT(kvm_age_page,
+ TP_PROTO(ulong hva, struct kvm_memory_slot *slot, int ref),
+ TP_ARGS(hva, slot, ref),
+
+ TP_STRUCT__entry(
+ __field( u64, hva )
+ __field( u64, gfn )
+ __field( u8, referenced )
+ ),
+
+ TP_fast_assign(
+ __entry->hva = hva;
+ __entry->gfn =
+ slot->base_gfn + ((hva - slot->userspace_addr) >> PAGE_SHIFT);
+ __entry->referenced = ref;
+ ),
+
+ TP_printk("hva %llx gfn %llx %s",
+ __entry->hva, __entry->gfn,
+ __entry->referenced ? "YOUNG" : "OLD")
+);
+
#endif /* _TRACE_KVM_MAIN_H */
/* This part must be outside protection */
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 0804cd59480..ea6f9d4a20e 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -401,18 +401,18 @@ static inline notrace int ftrace_get_offsets_##call( \
#undef DEFINE_EVENT
#define DEFINE_EVENT(template, name, proto, args) \
\
-static void ftrace_profile_##name(proto); \
+static void perf_trace_##name(proto); \
\
static notrace int \
-ftrace_profile_enable_##name(struct ftrace_event_call *unused) \
+perf_trace_enable_##name(struct ftrace_event_call *unused) \
{ \
- return register_trace_##name(ftrace_profile_##name); \
+ return register_trace_##name(perf_trace_##name); \
} \
\
static notrace void \
-ftrace_profile_disable_##name(struct ftrace_event_call *unused) \
+perf_trace_disable_##name(struct ftrace_event_call *unused) \
{ \
- unregister_trace_##name(ftrace_profile_##name); \
+ unregister_trace_##name(perf_trace_##name); \
}
#undef DEFINE_EVENT_PRINT
@@ -507,12 +507,12 @@ ftrace_profile_disable_##name(struct ftrace_event_call *unused) \
#ifdef CONFIG_PERF_EVENTS
-#define _TRACE_PROFILE_INIT(call) \
- .profile_enable = ftrace_profile_enable_##call, \
- .profile_disable = ftrace_profile_disable_##call,
+#define _TRACE_PERF_INIT(call) \
+ .perf_event_enable = perf_trace_enable_##call, \
+ .perf_event_disable = perf_trace_disable_##call,
#else
-#define _TRACE_PROFILE_INIT(call)
+#define _TRACE_PERF_INIT(call)
#endif /* CONFIG_PERF_EVENTS */
#undef __entry
@@ -638,7 +638,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
.unregfunc = ftrace_raw_unreg_event_##call, \
.print_fmt = print_fmt_##template, \
.define_fields = ftrace_define_fields_##template, \
- _TRACE_PROFILE_INIT(call) \
+ _TRACE_PERF_INIT(call) \
}
#undef DEFINE_EVENT_PRINT
@@ -657,18 +657,18 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
.unregfunc = ftrace_raw_unreg_event_##call, \
.print_fmt = print_fmt_##call, \
.define_fields = ftrace_define_fields_##template, \
- _TRACE_PROFILE_INIT(call) \
+ _TRACE_PERF_INIT(call) \
}
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
/*
- * Define the insertion callback to profile events
+ * Define the insertion callback to perf events
*
* The job is very similar to ftrace_raw_event_<call> except that we don't
* insert in the ring buffer but in a perf counter.
*
- * static void ftrace_profile_<call>(proto)
+ * static void ftrace_perf_<call>(proto)
* {
* struct ftrace_data_offsets_<call> __maybe_unused __data_offsets;
* struct ftrace_event_call *event_call = &event_<call>;
@@ -699,9 +699,9 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
* __cpu = smp_processor_id();
*
* if (in_nmi())
- * trace_buf = rcu_dereference(perf_trace_buf_nmi);
+ * trace_buf = rcu_dereference_sched(perf_trace_buf_nmi);
* else
- * trace_buf = rcu_dereference(perf_trace_buf);
+ * trace_buf = rcu_dereference_sched(perf_trace_buf);
*
* if (!trace_buf)
* goto end;
@@ -757,13 +757,14 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
#undef DECLARE_EVENT_CLASS
#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
static notrace void \
-ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \
+perf_trace_templ_##call(struct ftrace_event_call *event_call, \
proto) \
{ \
struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
struct ftrace_raw_##call *entry; \
u64 __addr = 0, __count = 1; \
unsigned long irq_flags; \
+ struct pt_regs *__regs; \
int __entry_size; \
int __data_size; \
int rctx; \
@@ -773,10 +774,10 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \
sizeof(u64)); \
__entry_size -= sizeof(u32); \
\
- if (WARN_ONCE(__entry_size > FTRACE_MAX_PROFILE_SIZE, \
+ if (WARN_ONCE(__entry_size > PERF_MAX_TRACE_SIZE, \
"profile buffer not large enough")) \
return; \
- entry = (struct ftrace_raw_##call *)ftrace_perf_buf_prepare( \
+ entry = (struct ftrace_raw_##call *)perf_trace_buf_prepare( \
__entry_size, event_call->id, &rctx, &irq_flags); \
if (!entry) \
return; \
@@ -784,17 +785,20 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \
\
{ assign; } \
\
- ftrace_perf_buf_submit(entry, __entry_size, rctx, __addr, \
- __count, irq_flags); \
+ __regs = &__get_cpu_var(perf_trace_regs); \
+ perf_fetch_caller_regs(__regs, 2); \
+ \
+ perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \
+ __count, irq_flags, __regs); \
}
#undef DEFINE_EVENT
#define DEFINE_EVENT(template, call, proto, args) \
-static notrace void ftrace_profile_##call(proto) \
+static notrace void perf_trace_##call(proto) \
{ \
struct ftrace_event_call *event_call = &event_##call; \
\
- ftrace_profile_templ_##template(event_call, args); \
+ perf_trace_templ_##template(event_call, args); \
}
#undef DEFINE_EVENT_PRINT
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index 0387100752f..e5e5f48dbfb 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -47,10 +47,10 @@ enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags);
#endif
#ifdef CONFIG_PERF_EVENTS
-int prof_sysenter_enable(struct ftrace_event_call *call);
-void prof_sysenter_disable(struct ftrace_event_call *call);
-int prof_sysexit_enable(struct ftrace_event_call *call);
-void prof_sysexit_disable(struct ftrace_event_call *call);
+int perf_sysenter_enable(struct ftrace_event_call *call);
+void perf_sysenter_disable(struct ftrace_event_call *call);
+int perf_sysexit_enable(struct ftrace_event_call *call);
+void perf_sysexit_disable(struct ftrace_event_call *call);
#endif
#endif /* _TRACE_SYSCALL_H */
diff --git a/include/video/broadsheetfb.h b/include/video/broadsheetfb.h
index a758534c027..548d28f4ec6 100644
--- a/include/video/broadsheetfb.h
+++ b/include/video/broadsheetfb.h
@@ -29,11 +29,19 @@
#define BS_CMD_UPD_FULL 0x33
#define BS_CMD_UPD_GDRV_CLR 0x37
+/* Broadsheet register interface defines */
+#define BS_REG_REV 0x00
+#define BS_REG_PRC 0x02
+
/* Broadsheet pin interface specific defines */
#define BS_CS 0x01
#define BS_DC 0x02
#define BS_WR 0x03
+/* Broadsheet IO interface specific defines */
+#define BS_MMIO_CMD 0x01
+#define BS_MMIO_DATA 0x02
+
/* struct used by broadsheet. board specific stuff comes from *board */
struct broadsheetfb_par {
struct fb_info *info;
@@ -41,6 +49,8 @@ struct broadsheetfb_par {
void (*write_reg)(struct broadsheetfb_par *, u16 reg, u16 val);
u16 (*read_reg)(struct broadsheetfb_par *, u16 reg);
wait_queue_head_t waitq;
+ int panel_index;
+ struct mutex io_lock;
};
/* board specific routines */
@@ -48,12 +58,17 @@ struct broadsheet_board {
struct module *owner;
int (*init)(struct broadsheetfb_par *);
int (*wait_for_rdy)(struct broadsheetfb_par *);
- void (*set_ctl)(struct broadsheetfb_par *, unsigned char, u8);
- void (*set_hdb)(struct broadsheetfb_par *, u16);
- u16 (*get_hdb)(struct broadsheetfb_par *);
void (*cleanup)(struct broadsheetfb_par *);
int (*get_panel_type)(void);
int (*setup_irq)(struct fb_info *);
-};
+ /* Functions for boards that use GPIO */
+ void (*set_ctl)(struct broadsheetfb_par *, unsigned char, u8);
+ void (*set_hdb)(struct broadsheetfb_par *, u16);
+ u16 (*get_hdb)(struct broadsheetfb_par *);
+
+ /* Functions for boards that have specialized MMIO */
+ void (*mmio_write)(struct broadsheetfb_par *, int type, u16);
+ u16 (*mmio_read)(struct broadsheetfb_par *);
+};
#endif
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index b9763badbd7..43e2d7d3397 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -39,6 +39,7 @@
#include <linux/mutex.h>
#include <linux/completion.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <xen/interface/xen.h>
#include <xen/interface/grant_table.h>
#include <xen/interface/io/xenbus.h>
diff --git a/init/Kconfig b/init/Kconfig
index 089a230e565..eb77e8ccde1 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -463,6 +463,7 @@ config HAVE_UNSTABLE_SCHED_CLOCK
menuconfig CGROUPS
boolean "Control Group support"
+ depends on EVENTFD
help
This option adds support for grouping sets of processes together, for
use with process control subsystems such as Cpusets, CFS, memory
diff --git a/init/do_mounts.c b/init/do_mounts.c
index bb008d064c1..02e3ca4fc52 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -15,6 +15,7 @@
#include <linux/initrd.h>
#include <linux/async.h>
#include <linux/fs_struct.h>
+#include <linux/slab.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index 027a402708d..bf3ef667bf3 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -7,6 +7,7 @@
#include <linux/cramfs_fs.h>
#include <linux/initrd.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include "do_mounts.h"
#include "../fs/squashfs/squashfs_fs.h"
diff --git a/init/initramfs.c b/init/initramfs.c
index b37d34beb90..4b9c2020509 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -457,7 +457,8 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len)
compress_name);
message = msg_buf;
}
- }
+ } else
+ error("junk in compressed archive");
if (state != Reset)
error("junk in compressed archive");
this_header = saved_offset + my_inptr;
@@ -525,7 +526,7 @@ static void __init clean_rootfs(void)
int fd;
void *buf;
struct linux_dirent64 *dirp;
- int count;
+ int num;
fd = sys_open("/", O_RDONLY, 0);
WARN_ON(fd < 0);
@@ -539,9 +540,9 @@ static void __init clean_rootfs(void)
}
dirp = buf;
- count = sys_getdents64(fd, dirp, BUF_SIZE);
- while (count > 0) {
- while (count > 0) {
+ num = sys_getdents64(fd, dirp, BUF_SIZE);
+ while (num > 0) {
+ while (num > 0) {
struct stat st;
int ret;
@@ -554,12 +555,12 @@ static void __init clean_rootfs(void)
sys_unlink(dirp->d_name);
}
- count -= dirp->d_reclen;
+ num -= dirp->d_reclen;
dirp = (void *)dirp + dirp->d_reclen;
}
dirp = buf;
memset(buf, 0, BUF_SIZE);
- count = sys_getdents64(fd, dirp, BUF_SIZE);
+ num = sys_getdents64(fd, dirp, BUF_SIZE);
}
sys_close(fd);
diff --git a/init/main.c b/init/main.c
index 40aaa020cd6..5c854027152 100644
--- a/init/main.c
+++ b/init/main.c
@@ -25,7 +25,6 @@
#include <linux/bootmem.h>
#include <linux/acpi.h>
#include <linux/tty.h>
-#include <linux/gfp.h>
#include <linux/percpu.h>
#include <linux/kmod.h>
#include <linux/vmalloc.h>
@@ -69,6 +68,7 @@
#include <linux/kmemtrace.h>
#include <linux/sfi.h>
#include <linux/shmem_fs.h>
+#include <linux/slab.h>
#include <trace/boot.h>
#include <asm/io.h>
@@ -174,7 +174,7 @@ static int __init maxcpus(char *str)
early_param("maxcpus", maxcpus);
#else
-const unsigned int setup_max_cpus = NR_CPUS;
+static const unsigned int setup_max_cpus = NR_CPUS;
#endif
/*
@@ -618,7 +618,7 @@ asmlinkage void __init start_kernel(void)
local_irq_enable();
/* Interrupts are enabled now so all GFP allocations are safe. */
- set_gfp_allowed_mask(__GFP_BITS_MASK);
+ gfp_allowed_mask = __GFP_BITS_MASK;
kmem_cache_init_late();
@@ -847,7 +847,8 @@ static noinline int init_post(void)
run_init_process("/bin/init");
run_init_process("/bin/sh");
- panic("No init found. Try passing init= option to kernel.");
+ panic("No init found. Try passing init= option to kernel. "
+ "See Linux Documentation/init.txt for guidance.");
}
static int __init kernel_init(void * unused)
@@ -857,7 +858,7 @@ static int __init kernel_init(void * unused)
/*
* init can allocate pages on any node
*/
- set_mems_allowed(node_possible_map);
+ set_mems_allowed(node_states[N_HIGH_MEMORY]);
/*
* init can run on any cpu.
*/
diff --git a/ipc/Makefile b/ipc/Makefile
index 4e1955ea815..9075e172e52 100644
--- a/ipc/Makefile
+++ b/ipc/Makefile
@@ -3,7 +3,7 @@
#
obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
-obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o
+obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o syscall.o
obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
obj_mq-$(CONFIG_COMPAT) += compat_mq.o
obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
diff --git a/ipc/compat.c b/ipc/compat.c
index ab76fb0ef84..9dc2c7d3c9e 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -26,7 +26,6 @@
#include <linux/init.h>
#include <linux/msg.h>
#include <linux/shm.h>
-#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/mutex.h>
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index b6cb06451f4..722b0130aa9 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -32,6 +32,7 @@
#include <linux/nsproxy.h>
#include <linux/pid.h>
#include <linux/ipc_namespace.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include "util.h"
@@ -155,7 +156,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
spin_lock(&mq_lock);
if (u->mq_bytes + mq_bytes < u->mq_bytes ||
u->mq_bytes + mq_bytes >
- p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
+ task_rlimit(p, RLIMIT_MSGQUEUE)) {
spin_unlock(&mq_lock);
kfree(info->messages);
goto out_inode;
diff --git a/ipc/msg.c b/ipc/msg.c
index af42ef8900a..9547cb7ac31 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -23,7 +23,6 @@
*/
#include <linux/capability.h>
-#include <linux/slab.h>
#include <linux/msg.h>
#include <linux/spinlock.h>
#include <linux/init.h>
diff --git a/ipc/shm.c b/ipc/shm.c
index 23256b85581..1a314c89f93 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -764,8 +764,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
if (euid != shp->shm_perm.uid &&
euid != shp->shm_perm.cuid)
goto out_unlock;
- if (cmd == SHM_LOCK &&
- !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
+ if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK))
goto out_unlock;
}
diff --git a/ipc/syscall.c b/ipc/syscall.c
new file mode 100644
index 00000000000..1d6f53f6b56
--- /dev/null
+++ b/ipc/syscall.c
@@ -0,0 +1,99 @@
+/*
+ * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
+ *
+ * This is really horribly ugly, and new architectures should just wire up
+ * the individual syscalls instead.
+ */
+#include <linux/unistd.h>
+
+#ifdef __ARCH_WANT_SYS_IPC
+#include <linux/errno.h>
+#include <linux/ipc.h>
+#include <linux/shm.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
+ unsigned long, third, void __user *, ptr, long, fifth)
+{
+ int version, ret;
+
+ version = call >> 16; /* hack for backward compatibility */
+ call &= 0xffff;
+
+ switch (call) {
+ case SEMOP:
+ return sys_semtimedop(first, (struct sembuf __user *)ptr,
+ second, NULL);
+ case SEMTIMEDOP:
+ return sys_semtimedop(first, (struct sembuf __user *)ptr,
+ second,
+ (const struct timespec __user *)fifth);
+
+ case SEMGET:
+ return sys_semget(first, second, third);
+ case SEMCTL: {
+ union semun fourth;
+ if (!ptr)
+ return -EINVAL;
+ if (get_user(fourth.__pad, (void __user * __user *) ptr))
+ return -EFAULT;
+ return sys_semctl(first, second, third, fourth);
+ }
+
+ case MSGSND:
+ return sys_msgsnd(first, (struct msgbuf __user *) ptr,
+ second, third);
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
+ if (!ptr)
+ return -EINVAL;
+
+ if (copy_from_user(&tmp,
+ (struct ipc_kludge __user *) ptr,
+ sizeof(tmp)))
+ return -EFAULT;
+ return sys_msgrcv(first, tmp.msgp, second,
+ tmp.msgtyp, third);
+ }
+ default:
+ return sys_msgrcv(first,
+ (struct msgbuf __user *) ptr,
+ second, fifth, third);
+ }
+ case MSGGET:
+ return sys_msgget((key_t) first, second);
+ case MSGCTL:
+ return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
+
+ case SHMAT:
+ switch (version) {
+ default: {
+ unsigned long raddr;
+ ret = do_shmat(first, (char __user *)ptr,
+ second, &raddr);
+ if (ret)
+ return ret;
+ return put_user(raddr, (unsigned long __user *) third);
+ }
+ case 1:
+ /*
+ * This was the entry point for kernel-originating calls
+ * from iBCS2 in 2.2 days.
+ */
+ return -EINVAL;
+ }
+ case SHMDT:
+ return sys_shmdt((char __user *)ptr);
+ case SHMGET:
+ return sys_shmget(first, second, third);
+ case SHMCTL:
+ return sys_shmctl(first, second,
+ (struct shmid_ds __user *) ptr);
+ default:
+ return -ENOSYS;
+ }
+}
+#endif
diff --git a/kernel/Makefile b/kernel/Makefile
index 7b974699f8c..a987aa1676b 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -91,6 +91,9 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
obj-$(CONFIG_LATENCYTOP) += latencytop.o
+obj-$(CONFIG_BINFMT_ELF) += elfcore.o
+obj-$(CONFIG_COMPAT_BINFMT_ELF) += elfcore.o
+obj-$(CONFIG_BINFMT_ELF_FDPIC) += elfcore.o
obj-$(CONFIG_FUNCTION_TRACER) += trace/
obj-$(CONFIG_TRACING) += trace/
obj-$(CONFIG_X86_DS) += trace/
diff --git a/kernel/acct.c b/kernel/acct.c
index a6605ca921b..24f8c81fc48 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -588,16 +588,6 @@ out:
}
/**
- * acct_init_pacct - initialize a new pacct_struct
- * @pacct: per-process accounting info struct to initialize
- */
-void acct_init_pacct(struct pacct_struct *pacct)
-{
- memset(pacct, 0, sizeof(struct pacct_struct));
- pacct->ac_utime = pacct->ac_stime = cputime_zero;
-}
-
-/**
* acct_collect - collect accounting information into pacct_struct
* @exitcode: task exit code
* @group_dead: not 0, if this thread is the last one in the process.
diff --git a/kernel/async.c b/kernel/async.c
index 27235f5de19..15319d6c18f 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -56,6 +56,7 @@ asynchronous and synchronous parts of the kernel.
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
static async_cookie_t next_cookie = 1;
diff --git a/kernel/audit.c b/kernel/audit.c
index 5feed232be9..c71bd26631a 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -46,6 +46,7 @@
#include <asm/atomic.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/kthread.h>
@@ -398,7 +399,7 @@ static void kauditd_send_skb(struct sk_buff *skb)
skb_get(skb);
err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0);
if (err < 0) {
- BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */
+ BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */
printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
audit_log_lost("auditd dissapeared\n");
audit_pid = 0;
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 028e85663f2..46a57b57a33 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -3,6 +3,7 @@
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
struct audit_tree;
struct audit_chunk;
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index cc7e87936cb..8df43696f4b 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -27,6 +27,7 @@
#include <linux/namei.h>
#include <linux/netlink.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/inotify.h>
#include <linux/security.h>
#include "audit.h"
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index a70604047f3..ce08041f578 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -27,6 +27,7 @@
#include <linux/namei.h>
#include <linux/netlink.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/security.h>
#include "audit.h"
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index f3a461c0970..3828ad5fb8f 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -49,6 +49,7 @@
#include <linux/namei.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/mount.h>
#include <linux/socket.h>
#include <linux/mqueue.h>
@@ -1893,7 +1894,7 @@ static int audit_inc_name_count(struct audit_context *context,
{
if (context->name_count >= AUDIT_NAMES) {
if (inode)
- printk(KERN_DEBUG "name_count maxed, losing inode data: "
+ printk(KERN_DEBUG "audit: name_count maxed, losing inode data: "
"dev=%02x:%02x, inode=%lu\n",
MAJOR(inode->i_sb->s_dev),
MINOR(inode->i_sb->s_dev),
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 4fd90e12977..e2769e13980 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4,6 +4,10 @@
* Based originally on the cpuset system, extracted by Paul Menage
* Copyright (C) 2006 Google, Inc
*
+ * Notifications support
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Kirill A. Shutemov
+ *
* Copyright notices from the original cpuset code:
* --------------------------------------------------
* Copyright (C) 2003 BULL SA.
@@ -23,7 +27,6 @@
*/
#include <linux/cgroup.h>
-#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/errno.h>
#include <linux/fs.h>
@@ -44,6 +47,7 @@
#include <linux/string.h>
#include <linux/sort.h>
#include <linux/kmod.h>
+#include <linux/module.h>
#include <linux/delayacct.h>
#include <linux/cgroupstats.h>
#include <linux/hash.h>
@@ -52,15 +56,21 @@
#include <linux/pid_namespace.h>
#include <linux/idr.h>
#include <linux/vmalloc.h> /* TODO: replace with more sophisticated array */
+#include <linux/eventfd.h>
+#include <linux/poll.h>
#include <asm/atomic.h>
static DEFINE_MUTEX(cgroup_mutex);
-/* Generate an array of cgroup subsystem pointers */
+/*
+ * Generate an array of cgroup subsystem pointers. At boot time, this is
+ * populated up to CGROUP_BUILTIN_SUBSYS_COUNT, and modular subsystems are
+ * registered after that. The mutable section of this array is protected by
+ * cgroup_mutex.
+ */
#define SUBSYS(_x) &_x ## _subsys,
-
-static struct cgroup_subsys *subsys[] = {
+static struct cgroup_subsys *subsys[CGROUP_SUBSYS_COUNT] = {
#include <linux/cgroup_subsys.h>
};
@@ -147,6 +157,35 @@ struct css_id {
unsigned short stack[0]; /* Array of Length (depth+1) */
};
+/*
+ * cgroup_event represents events which userspace want to recieve.
+ */
+struct cgroup_event {
+ /*
+ * Cgroup which the event belongs to.
+ */
+ struct cgroup *cgrp;
+ /*
+ * Control file which the event associated.
+ */
+ struct cftype *cft;
+ /*
+ * eventfd to signal userspace about the event.
+ */
+ struct eventfd_ctx *eventfd;
+ /*
+ * Each of these stored in a list by the cgroup.
+ */
+ struct list_head list;
+ /*
+ * All fields below needed to unregister event when
+ * userspace closes eventfd.
+ */
+ poll_table pt;
+ wait_queue_head_t *wqh;
+ wait_queue_t wait;
+ struct work_struct remove;
+};
/* The list of hierarchy roots */
@@ -250,7 +289,8 @@ struct cg_cgroup_link {
static struct css_set init_css_set;
static struct cg_cgroup_link init_css_set_link;
-static int cgroup_subsys_init_idr(struct cgroup_subsys *ss);
+static int cgroup_init_idr(struct cgroup_subsys *ss,
+ struct cgroup_subsys_state *css);
/* css_set_lock protects the list of css_set objects, and the
* chain of tasks off each css_set. Nests outside task->alloc_lock
@@ -448,8 +488,11 @@ static struct css_set *find_existing_css_set(
struct hlist_node *node;
struct css_set *cg;
- /* Built the set of subsystem state objects that we want to
- * see in the new css_set */
+ /*
+ * Build the set of subsystem state objects that we want to see in the
+ * new css_set. while subsystems can change globally, the entries here
+ * won't change, so no need for locking.
+ */
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
if (root->subsys_bits & (1UL << i)) {
/* Subsystem is in this hierarchy. So we want
@@ -696,6 +739,7 @@ void cgroup_lock(void)
{
mutex_lock(&cgroup_mutex);
}
+EXPORT_SYMBOL_GPL(cgroup_lock);
/**
* cgroup_unlock - release lock on cgroup changes
@@ -706,6 +750,7 @@ void cgroup_unlock(void)
{
mutex_unlock(&cgroup_mutex);
}
+EXPORT_SYMBOL_GPL(cgroup_unlock);
/*
* A couple of forward declarations required, due to cyclic reference loop:
@@ -757,6 +802,7 @@ static int cgroup_call_pre_destroy(struct cgroup *cgrp)
if (ret)
break;
}
+
return ret;
}
@@ -884,7 +930,11 @@ void cgroup_release_and_wakeup_rmdir(struct cgroup_subsys_state *css)
css_put(css);
}
-
+/*
+ * Call with cgroup_mutex held. Drops reference counts on modules, including
+ * any duplicate ones that parse_cgroupfs_options took. If this function
+ * returns an error, no reference counts are touched.
+ */
static int rebind_subsystems(struct cgroupfs_root *root,
unsigned long final_bits)
{
@@ -892,6 +942,8 @@ static int rebind_subsystems(struct cgroupfs_root *root,
struct cgroup *cgrp = &root->top_cgroup;
int i;
+ BUG_ON(!mutex_is_locked(&cgroup_mutex));
+
removed_bits = root->actual_subsys_bits & ~final_bits;
added_bits = final_bits & ~root->actual_subsys_bits;
/* Check that any added subsystems are currently free */
@@ -900,6 +952,12 @@ static int rebind_subsystems(struct cgroupfs_root *root,
struct cgroup_subsys *ss = subsys[i];
if (!(bit & added_bits))
continue;
+ /*
+ * Nobody should tell us to do a subsys that doesn't exist:
+ * parse_cgroupfs_options should catch that case and refcounts
+ * ensure that subsystems won't disappear once selected.
+ */
+ BUG_ON(ss == NULL);
if (ss->root != &rootnode) {
/* Subsystem isn't free */
return -EBUSY;
@@ -919,6 +977,7 @@ static int rebind_subsystems(struct cgroupfs_root *root,
unsigned long bit = 1UL << i;
if (bit & added_bits) {
/* We're binding this subsystem to this hierarchy */
+ BUG_ON(ss == NULL);
BUG_ON(cgrp->subsys[i]);
BUG_ON(!dummytop->subsys[i]);
BUG_ON(dummytop->subsys[i]->cgroup != dummytop);
@@ -930,8 +989,10 @@ static int rebind_subsystems(struct cgroupfs_root *root,
if (ss->bind)
ss->bind(ss, cgrp);
mutex_unlock(&ss->hierarchy_mutex);
+ /* refcount was already taken, and we're keeping it */
} else if (bit & removed_bits) {
/* We're removing this subsystem */
+ BUG_ON(ss == NULL);
BUG_ON(cgrp->subsys[i] != dummytop->subsys[i]);
BUG_ON(cgrp->subsys[i]->cgroup != cgrp);
mutex_lock(&ss->hierarchy_mutex);
@@ -942,9 +1003,20 @@ static int rebind_subsystems(struct cgroupfs_root *root,
subsys[i]->root = &rootnode;
list_move(&ss->sibling, &rootnode.subsys_list);
mutex_unlock(&ss->hierarchy_mutex);
+ /* subsystem is now free - drop reference on module */
+ module_put(ss->module);
} else if (bit & final_bits) {
/* Subsystem state should already exist */
+ BUG_ON(ss == NULL);
BUG_ON(!cgrp->subsys[i]);
+ /*
+ * a refcount was taken, but we already had one, so
+ * drop the extra reference.
+ */
+ module_put(ss->module);
+#ifdef CONFIG_MODULE_UNLOAD
+ BUG_ON(ss->module && !module_refcount(ss->module));
+#endif
} else {
/* Subsystem state shouldn't exist */
BUG_ON(cgrp->subsys[i]);
@@ -986,13 +1058,20 @@ struct cgroup_sb_opts {
};
-/* Convert a hierarchy specifier into a bitmask of subsystems and
- * flags. */
-static int parse_cgroupfs_options(char *data,
- struct cgroup_sb_opts *opts)
+/*
+ * Convert a hierarchy specifier into a bitmask of subsystems and flags. Call
+ * with cgroup_mutex held to protect the subsys[] array. This function takes
+ * refcounts on subsystems to be used, unless it returns error, in which case
+ * no refcounts are taken.
+ */
+static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
{
char *token, *o = data ?: "all";
unsigned long mask = (unsigned long)-1;
+ int i;
+ bool module_pin_failed = false;
+
+ BUG_ON(!mutex_is_locked(&cgroup_mutex));
#ifdef CONFIG_CPUSETS
mask = ~(1UL << cpuset_subsys_id);
@@ -1005,10 +1084,11 @@ static int parse_cgroupfs_options(char *data,
return -EINVAL;
if (!strcmp(token, "all")) {
/* Add all non-disabled subsystems */
- int i;
opts->subsys_bits = 0;
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
+ if (ss == NULL)
+ continue;
if (!ss->disabled)
opts->subsys_bits |= 1ul << i;
}
@@ -1026,7 +1106,6 @@ static int parse_cgroupfs_options(char *data,
if (!opts->release_agent)
return -ENOMEM;
} else if (!strncmp(token, "name=", 5)) {
- int i;
const char *name = token + 5;
/* Can't specify an empty name */
if (!strlen(name))
@@ -1050,9 +1129,10 @@ static int parse_cgroupfs_options(char *data,
return -ENOMEM;
} else {
struct cgroup_subsys *ss;
- int i;
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
ss = subsys[i];
+ if (ss == NULL)
+ continue;
if (!strcmp(token, ss->name)) {
if (!ss->disabled)
set_bit(i, &opts->subsys_bits);
@@ -1087,9 +1167,54 @@ static int parse_cgroupfs_options(char *data,
if (!opts->subsys_bits && !opts->name)
return -EINVAL;
+ /*
+ * Grab references on all the modules we'll need, so the subsystems
+ * don't dance around before rebind_subsystems attaches them. This may
+ * take duplicate reference counts on a subsystem that's already used,
+ * but rebind_subsystems handles this case.
+ */
+ for (i = CGROUP_BUILTIN_SUBSYS_COUNT; i < CGROUP_SUBSYS_COUNT; i++) {
+ unsigned long bit = 1UL << i;
+
+ if (!(bit & opts->subsys_bits))
+ continue;
+ if (!try_module_get(subsys[i]->module)) {
+ module_pin_failed = true;
+ break;
+ }
+ }
+ if (module_pin_failed) {
+ /*
+ * oops, one of the modules was going away. this means that we
+ * raced with a module_delete call, and to the user this is
+ * essentially a "subsystem doesn't exist" case.
+ */
+ for (i--; i >= CGROUP_BUILTIN_SUBSYS_COUNT; i--) {
+ /* drop refcounts only on the ones we took */
+ unsigned long bit = 1UL << i;
+
+ if (!(bit & opts->subsys_bits))
+ continue;
+ module_put(subsys[i]->module);
+ }
+ return -ENOENT;
+ }
+
return 0;
}
+static void drop_parsed_module_refcounts(unsigned long subsys_bits)
+{
+ int i;
+ for (i = CGROUP_BUILTIN_SUBSYS_COUNT; i < CGROUP_SUBSYS_COUNT; i++) {
+ unsigned long bit = 1UL << i;
+
+ if (!(bit & subsys_bits))
+ continue;
+ module_put(subsys[i]->module);
+ }
+}
+
static int cgroup_remount(struct super_block *sb, int *flags, char *data)
{
int ret = 0;
@@ -1106,21 +1231,19 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data)
if (ret)
goto out_unlock;
- /* Don't allow flags to change at remount */
- if (opts.flags != root->flags) {
- ret = -EINVAL;
- goto out_unlock;
- }
-
- /* Don't allow name to change at remount */
- if (opts.name && strcmp(opts.name, root->name)) {
+ /* Don't allow flags or name to change at remount */
+ if (opts.flags != root->flags ||
+ (opts.name && strcmp(opts.name, root->name))) {
ret = -EINVAL;
+ drop_parsed_module_refcounts(opts.subsys_bits);
goto out_unlock;
}
ret = rebind_subsystems(root, opts.subsys_bits);
- if (ret)
+ if (ret) {
+ drop_parsed_module_refcounts(opts.subsys_bits);
goto out_unlock;
+ }
/* (re)populate subsystem files */
cgroup_populate_dir(cgrp);
@@ -1151,6 +1274,8 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp)
INIT_LIST_HEAD(&cgrp->release_list);
INIT_LIST_HEAD(&cgrp->pidlists);
mutex_init(&cgrp->pidlist_mutex);
+ INIT_LIST_HEAD(&cgrp->event_list);
+ spin_lock_init(&cgrp->event_list_lock);
}
static void init_cgroup_root(struct cgroupfs_root *root)
@@ -1306,7 +1431,9 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
struct cgroupfs_root *new_root;
/* First find the desired set of subsystems */
+ mutex_lock(&cgroup_mutex);
ret = parse_cgroupfs_options(data, &opts);
+ mutex_unlock(&cgroup_mutex);
if (ret)
goto out_err;
@@ -1317,7 +1444,7 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
new_root = cgroup_root_from_opts(&opts);
if (IS_ERR(new_root)) {
ret = PTR_ERR(new_root);
- goto out_err;
+ goto drop_modules;
}
opts.new_root = new_root;
@@ -1326,7 +1453,7 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
if (IS_ERR(sb)) {
ret = PTR_ERR(sb);
cgroup_drop_root(opts.new_root);
- goto out_err;
+ goto drop_modules;
}
root = sb->s_fs_info;
@@ -1382,6 +1509,11 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
free_cg_links(&tmp_cg_links);
goto drop_new_super;
}
+ /*
+ * There must be no failure case after here, since rebinding
+ * takes care of subsystems' refcounts, which are explicitly
+ * dropped in the failure exit path.
+ */
/* EBUSY should be the only error here */
BUG_ON(ret);
@@ -1420,6 +1552,8 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
* any) is not needed
*/
cgroup_drop_root(opts.new_root);
+ /* no subsys rebinding, so refcounts don't change */
+ drop_parsed_module_refcounts(opts.subsys_bits);
}
simple_set_mnt(mnt, sb);
@@ -1429,6 +1563,8 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
drop_new_super:
deactivate_locked_super(sb);
+ drop_modules:
+ drop_parsed_module_refcounts(opts.subsys_bits);
out_err:
kfree(opts.release_agent);
kfree(opts.name);
@@ -1542,6 +1678,7 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
memmove(buf, start, buf + buflen - start);
return 0;
}
+EXPORT_SYMBOL_GPL(cgroup_path);
/**
* cgroup_attach_task - attach task 'tsk' to cgroup 'cgrp'
@@ -1554,7 +1691,7 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
{
int retval = 0;
- struct cgroup_subsys *ss;
+ struct cgroup_subsys *ss, *failed_ss = NULL;
struct cgroup *oldcgrp;
struct css_set *cg;
struct css_set *newcg;
@@ -1568,8 +1705,16 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
for_each_subsys(root, ss) {
if (ss->can_attach) {
retval = ss->can_attach(ss, cgrp, tsk, false);
- if (retval)
- return retval;
+ if (retval) {
+ /*
+ * Remember on which subsystem the can_attach()
+ * failed, so that we only call cancel_attach()
+ * against the subsystems whose can_attach()
+ * succeeded. (See below)
+ */
+ failed_ss = ss;
+ goto out;
+ }
}
}
@@ -1583,14 +1728,17 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
*/
newcg = find_css_set(cg, cgrp);
put_css_set(cg);
- if (!newcg)
- return -ENOMEM;
+ if (!newcg) {
+ retval = -ENOMEM;
+ goto out;
+ }
task_lock(tsk);
if (tsk->flags & PF_EXITING) {
task_unlock(tsk);
put_css_set(newcg);
- return -ESRCH;
+ retval = -ESRCH;
+ goto out;
}
rcu_assign_pointer(tsk->cgroups, newcg);
task_unlock(tsk);
@@ -1616,7 +1764,22 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
* is no longer empty.
*/
cgroup_wakeup_rmdir_waiter(cgrp);
- return 0;
+out:
+ if (retval) {
+ for_each_subsys(root, ss) {
+ if (ss == failed_ss)
+ /*
+ * This subsystem was the one that failed the
+ * can_attach() check earlier, so we don't need
+ * to call cancel_attach() against it or any
+ * remaining subsystems.
+ */
+ break;
+ if (ss->cancel_attach)
+ ss->cancel_attach(ss, cgrp, tsk, false);
+ }
+ }
+ return retval;
}
/*
@@ -1682,6 +1845,7 @@ bool cgroup_lock_live_group(struct cgroup *cgrp)
}
return true;
}
+EXPORT_SYMBOL_GPL(cgroup_lock_live_group);
static int cgroup_release_agent_write(struct cgroup *cgrp, struct cftype *cft,
const char *buffer)
@@ -1950,6 +2114,16 @@ static const struct inode_operations cgroup_dir_inode_operations = {
.rename = cgroup_rename,
};
+/*
+ * Check if a file is a control file
+ */
+static inline struct cftype *__file_cft(struct file *file)
+{
+ if (file->f_dentry->d_inode->i_fop != &cgroup_file_operations)
+ return ERR_PTR(-EINVAL);
+ return __d_cft(file->f_dentry);
+}
+
static int cgroup_create_file(struct dentry *dentry, mode_t mode,
struct super_block *sb)
{
@@ -2069,6 +2243,7 @@ int cgroup_add_file(struct cgroup *cgrp,
error = PTR_ERR(dentry);
return error;
}
+EXPORT_SYMBOL_GPL(cgroup_add_file);
int cgroup_add_files(struct cgroup *cgrp,
struct cgroup_subsys *subsys,
@@ -2083,6 +2258,7 @@ int cgroup_add_files(struct cgroup *cgrp,
}
return 0;
}
+EXPORT_SYMBOL_GPL(cgroup_add_files);
/**
* cgroup_task_count - count the number of tasks in a cgroup.
@@ -2468,7 +2644,8 @@ static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp,
{
struct cgroup_pidlist *l;
/* don't need task_nsproxy() if we're looking at ourself */
- struct pid_namespace *ns = get_pid_ns(current->nsproxy->pid_ns);
+ struct pid_namespace *ns = current->nsproxy->pid_ns;
+
/*
* We can't drop the pidlist_mutex before taking the l->mutex in case
* the last ref-holder is trying to remove l from the list at the same
@@ -2478,8 +2655,6 @@ static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp,
mutex_lock(&cgrp->pidlist_mutex);
list_for_each_entry(l, &cgrp->pidlists, links) {
if (l->key.type == type && l->key.ns == ns) {
- /* found a matching list - drop the extra refcount */
- put_pid_ns(ns);
/* make sure l doesn't vanish out from under us */
down_write(&l->mutex);
mutex_unlock(&cgrp->pidlist_mutex);
@@ -2490,13 +2665,12 @@ static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp,
l = kmalloc(sizeof(struct cgroup_pidlist), GFP_KERNEL);
if (!l) {
mutex_unlock(&cgrp->pidlist_mutex);
- put_pid_ns(ns);
return l;
}
init_rwsem(&l->mutex);
down_write(&l->mutex);
l->key.type = type;
- l->key.ns = ns;
+ l->key.ns = get_pid_ns(ns);
l->use_count = 0; /* don't increment here */
l->list = NULL;
l->owner = cgrp;
@@ -2804,6 +2978,174 @@ static int cgroup_write_notify_on_release(struct cgroup *cgrp,
}
/*
+ * Unregister event and free resources.
+ *
+ * Gets called from workqueue.
+ */
+static void cgroup_event_remove(struct work_struct *work)
+{
+ struct cgroup_event *event = container_of(work, struct cgroup_event,
+ remove);
+ struct cgroup *cgrp = event->cgrp;
+
+ /* TODO: check return code */
+ event->cft->unregister_event(cgrp, event->cft, event->eventfd);
+
+ eventfd_ctx_put(event->eventfd);
+ kfree(event);
+ dput(cgrp->dentry);
+}
+
+/*
+ * Gets called on POLLHUP on eventfd when user closes it.
+ *
+ * Called with wqh->lock held and interrupts disabled.
+ */
+static int cgroup_event_wake(wait_queue_t *wait, unsigned mode,
+ int sync, void *key)
+{
+ struct cgroup_event *event = container_of(wait,
+ struct cgroup_event, wait);
+ struct cgroup *cgrp = event->cgrp;
+ unsigned long flags = (unsigned long)key;
+
+ if (flags & POLLHUP) {
+ remove_wait_queue_locked(event->wqh, &event->wait);
+ spin_lock(&cgrp->event_list_lock);
+ list_del(&event->list);
+ spin_unlock(&cgrp->event_list_lock);
+ /*
+ * We are in atomic context, but cgroup_event_remove() may
+ * sleep, so we have to call it in workqueue.
+ */
+ schedule_work(&event->remove);
+ }
+
+ return 0;
+}
+
+static void cgroup_event_ptable_queue_proc(struct file *file,
+ wait_queue_head_t *wqh, poll_table *pt)
+{
+ struct cgroup_event *event = container_of(pt,
+ struct cgroup_event, pt);
+
+ event->wqh = wqh;
+ add_wait_queue(wqh, &event->wait);
+}
+
+/*
+ * Parse input and register new cgroup event handler.
+ *
+ * Input must be in format '<event_fd> <control_fd> <args>'.
+ * Interpretation of args is defined by control file implementation.
+ */
+static int cgroup_write_event_control(struct cgroup *cgrp, struct cftype *cft,
+ const char *buffer)
+{
+ struct cgroup_event *event = NULL;
+ unsigned int efd, cfd;
+ struct file *efile = NULL;
+ struct file *cfile = NULL;
+ char *endp;
+ int ret;
+
+ efd = simple_strtoul(buffer, &endp, 10);
+ if (*endp != ' ')
+ return -EINVAL;
+ buffer = endp + 1;
+
+ cfd = simple_strtoul(buffer, &endp, 10);
+ if ((*endp != ' ') && (*endp != '\0'))
+ return -EINVAL;
+ buffer = endp + 1;
+
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
+ if (!event)
+ return -ENOMEM;
+ event->cgrp = cgrp;
+ INIT_LIST_HEAD(&event->list);
+ init_poll_funcptr(&event->pt, cgroup_event_ptable_queue_proc);
+ init_waitqueue_func_entry(&event->wait, cgroup_event_wake);
+ INIT_WORK(&event->remove, cgroup_event_remove);
+
+ efile = eventfd_fget(efd);
+ if (IS_ERR(efile)) {
+ ret = PTR_ERR(efile);
+ goto fail;
+ }
+
+ event->eventfd = eventfd_ctx_fileget(efile);
+ if (IS_ERR(event->eventfd)) {
+ ret = PTR_ERR(event->eventfd);
+ goto fail;
+ }
+
+ cfile = fget(cfd);
+ if (!cfile) {
+ ret = -EBADF;
+ goto fail;
+ }
+
+ /* the process need read permission on control file */
+ ret = file_permission(cfile, MAY_READ);
+ if (ret < 0)
+ goto fail;
+
+ event->cft = __file_cft(cfile);
+ if (IS_ERR(event->cft)) {
+ ret = PTR_ERR(event->cft);
+ goto fail;
+ }
+
+ if (!event->cft->register_event || !event->cft->unregister_event) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = event->cft->register_event(cgrp, event->cft,
+ event->eventfd, buffer);
+ if (ret)
+ goto fail;
+
+ if (efile->f_op->poll(efile, &event->pt) & POLLHUP) {
+ event->cft->unregister_event(cgrp, event->cft, event->eventfd);
+ ret = 0;
+ goto fail;
+ }
+
+ /*
+ * Events should be removed after rmdir of cgroup directory, but before
+ * destroying subsystem state objects. Let's take reference to cgroup
+ * directory dentry to do that.
+ */
+ dget(cgrp->dentry);
+
+ spin_lock(&cgrp->event_list_lock);
+ list_add(&event->list, &cgrp->event_list);
+ spin_unlock(&cgrp->event_list_lock);
+
+ fput(cfile);
+ fput(efile);
+
+ return 0;
+
+fail:
+ if (cfile)
+ fput(cfile);
+
+ if (event && event->eventfd && !IS_ERR(event->eventfd))
+ eventfd_ctx_put(event->eventfd);
+
+ if (!IS_ERR_OR_NULL(efile))
+ fput(efile);
+
+ kfree(event);
+
+ return ret;
+}
+
+/*
* for the common functions, 'private' gives the type of file
*/
/* for hysterical raisins, we can't put this on the older files */
@@ -2828,6 +3170,11 @@ static struct cftype files[] = {
.read_u64 = cgroup_read_notify_on_release,
.write_u64 = cgroup_write_notify_on_release,
},
+ {
+ .name = CGROUP_FILE_GENERIC_PREFIX "event_control",
+ .write_string = cgroup_write_event_control,
+ .mode = S_IWUGO,
+ },
};
static struct cftype cft_release_agent = {
@@ -2892,8 +3239,14 @@ static void cgroup_lock_hierarchy(struct cgroupfs_root *root)
/* We need to take each hierarchy_mutex in a consistent order */
int i;
+ /*
+ * No worry about a race with rebind_subsystems that might mess up the
+ * locking order, since both parties are under cgroup_mutex.
+ */
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
+ if (ss == NULL)
+ continue;
if (ss->root == root)
mutex_lock(&ss->hierarchy_mutex);
}
@@ -2905,6 +3258,8 @@ static void cgroup_unlock_hierarchy(struct cgroupfs_root *root)
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
+ if (ss == NULL)
+ continue;
if (ss->root == root)
mutex_unlock(&ss->hierarchy_mutex);
}
@@ -3028,11 +3383,16 @@ static int cgroup_has_css_refs(struct cgroup *cgrp)
* synchronization other than RCU, and the subsystem linked
* list isn't RCU-safe */
int i;
+ /*
+ * We won't need to lock the subsys array, because the subsystems
+ * we're concerned about aren't going anywhere since our cgroup root
+ * has a reference on them.
+ */
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
struct cgroup_subsys_state *css;
- /* Skip subsystems not in this hierarchy */
- if (ss->root != cgrp->root)
+ /* Skip subsystems not present or not in this hierarchy */
+ if (ss == NULL || ss->root != cgrp->root)
continue;
css = cgrp->subsys[ss->subsys_id];
/* When called from check_for_release() it's possible
@@ -3106,6 +3466,7 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
struct dentry *d;
struct cgroup *parent;
DEFINE_WAIT(wait);
+ struct cgroup_event *event, *tmp;
int ret;
/* the vfs holds both inode->i_mutex already */
@@ -3189,6 +3550,20 @@ again:
set_bit(CGRP_RELEASABLE, &parent->flags);
check_for_release(parent);
+ /*
+ * Unregister events and notify userspace.
+ * Notify userspace about cgroup removing only after rmdir of cgroup
+ * directory to avoid race between userspace and kernelspace
+ */
+ spin_lock(&cgrp->event_list_lock);
+ list_for_each_entry_safe(event, tmp, &cgrp->event_list, list) {
+ list_del(&event->list);
+ remove_wait_queue(event->wqh, &event->wait);
+ eventfd_signal(event->eventfd, 1);
+ schedule_work(&event->remove);
+ }
+ spin_unlock(&cgrp->event_list_lock);
+
mutex_unlock(&cgroup_mutex);
return 0;
}
@@ -3223,9 +3598,198 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
mutex_init(&ss->hierarchy_mutex);
lockdep_set_class(&ss->hierarchy_mutex, &ss->subsys_key);
ss->active = 1;
+
+ /* this function shouldn't be used with modular subsystems, since they
+ * need to register a subsys_id, among other things */
+ BUG_ON(ss->module);
}
/**
+ * cgroup_load_subsys: load and register a modular subsystem at runtime
+ * @ss: the subsystem to load
+ *
+ * This function should be called in a modular subsystem's initcall. If the
+ * subsytem is built as a module, it will be assigned a new subsys_id and set
+ * up for use. If the subsystem is built-in anyway, work is delegated to the
+ * simpler cgroup_init_subsys.
+ */
+int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
+{
+ int i;
+ struct cgroup_subsys_state *css;
+
+ /* check name and function validity */
+ if (ss->name == NULL || strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN ||
+ ss->create == NULL || ss->destroy == NULL)
+ return -EINVAL;
+
+ /*
+ * we don't support callbacks in modular subsystems. this check is
+ * before the ss->module check for consistency; a subsystem that could
+ * be a module should still have no callbacks even if the user isn't
+ * compiling it as one.
+ */
+ if (ss->fork || ss->exit)
+ return -EINVAL;
+
+ /*
+ * an optionally modular subsystem is built-in: we want to do nothing,
+ * since cgroup_init_subsys will have already taken care of it.
+ */
+ if (ss->module == NULL) {
+ /* a few sanity checks */
+ BUG_ON(ss->subsys_id >= CGROUP_BUILTIN_SUBSYS_COUNT);
+ BUG_ON(subsys[ss->subsys_id] != ss);
+ return 0;
+ }
+
+ /*
+ * need to register a subsys id before anything else - for example,
+ * init_cgroup_css needs it.
+ */
+ mutex_lock(&cgroup_mutex);
+ /* find the first empty slot in the array */
+ for (i = CGROUP_BUILTIN_SUBSYS_COUNT; i < CGROUP_SUBSYS_COUNT; i++) {
+ if (subsys[i] == NULL)
+ break;
+ }
+ if (i == CGROUP_SUBSYS_COUNT) {
+ /* maximum number of subsystems already registered! */
+ mutex_unlock(&cgroup_mutex);
+ return -EBUSY;
+ }
+ /* assign ourselves the subsys_id */
+ ss->subsys_id = i;
+ subsys[i] = ss;
+
+ /*
+ * no ss->create seems to need anything important in the ss struct, so
+ * this can happen first (i.e. before the rootnode attachment).
+ */
+ css = ss->create(ss, dummytop);
+ if (IS_ERR(css)) {
+ /* failure case - need to deassign the subsys[] slot. */
+ subsys[i] = NULL;
+ mutex_unlock(&cgroup_mutex);
+ return PTR_ERR(css);
+ }
+
+ list_add(&ss->sibling, &rootnode.subsys_list);
+ ss->root = &rootnode;
+
+ /* our new subsystem will be attached to the dummy hierarchy. */
+ init_cgroup_css(css, ss, dummytop);
+ /* init_idr must be after init_cgroup_css because it sets css->id. */
+ if (ss->use_id) {
+ int ret = cgroup_init_idr(ss, css);
+ if (ret) {
+ dummytop->subsys[ss->subsys_id] = NULL;
+ ss->destroy(ss, dummytop);
+ subsys[i] = NULL;
+ mutex_unlock(&cgroup_mutex);
+ return ret;
+ }
+ }
+
+ /*
+ * Now we need to entangle the css into the existing css_sets. unlike
+ * in cgroup_init_subsys, there are now multiple css_sets, so each one
+ * will need a new pointer to it; done by iterating the css_set_table.
+ * furthermore, modifying the existing css_sets will corrupt the hash
+ * table state, so each changed css_set will need its hash recomputed.
+ * this is all done under the css_set_lock.
+ */
+ write_lock(&css_set_lock);
+ for (i = 0; i < CSS_SET_TABLE_SIZE; i++) {
+ struct css_set *cg;
+ struct hlist_node *node, *tmp;
+ struct hlist_head *bucket = &css_set_table[i], *new_bucket;
+
+ hlist_for_each_entry_safe(cg, node, tmp, bucket, hlist) {
+ /* skip entries that we already rehashed */
+ if (cg->subsys[ss->subsys_id])
+ continue;
+ /* remove existing entry */
+ hlist_del(&cg->hlist);
+ /* set new value */
+ cg->subsys[ss->subsys_id] = css;
+ /* recompute hash and restore entry */
+ new_bucket = css_set_hash(cg->subsys);
+ hlist_add_head(&cg->hlist, new_bucket);
+ }
+ }
+ write_unlock(&css_set_lock);
+
+ mutex_init(&ss->hierarchy_mutex);
+ lockdep_set_class(&ss->hierarchy_mutex, &ss->subsys_key);
+ ss->active = 1;
+
+ /* success! */
+ mutex_unlock(&cgroup_mutex);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cgroup_load_subsys);
+
+/**
+ * cgroup_unload_subsys: unload a modular subsystem
+ * @ss: the subsystem to unload
+ *
+ * This function should be called in a modular subsystem's exitcall. When this
+ * function is invoked, the refcount on the subsystem's module will be 0, so
+ * the subsystem will not be attached to any hierarchy.
+ */
+void cgroup_unload_subsys(struct cgroup_subsys *ss)
+{
+ struct cg_cgroup_link *link;
+ struct hlist_head *hhead;
+
+ BUG_ON(ss->module == NULL);
+
+ /*
+ * we shouldn't be called if the subsystem is in use, and the use of
+ * try_module_get in parse_cgroupfs_options should ensure that it
+ * doesn't start being used while we're killing it off.
+ */
+ BUG_ON(ss->root != &rootnode);
+
+ mutex_lock(&cgroup_mutex);
+ /* deassign the subsys_id */
+ BUG_ON(ss->subsys_id < CGROUP_BUILTIN_SUBSYS_COUNT);
+ subsys[ss->subsys_id] = NULL;
+
+ /* remove subsystem from rootnode's list of subsystems */
+ list_del(&ss->sibling);
+
+ /*
+ * disentangle the css from all css_sets attached to the dummytop. as
+ * in loading, we need to pay our respects to the hashtable gods.
+ */
+ write_lock(&css_set_lock);
+ list_for_each_entry(link, &dummytop->css_sets, cgrp_link_list) {
+ struct css_set *cg = link->cg;
+
+ hlist_del(&cg->hlist);
+ BUG_ON(!cg->subsys[ss->subsys_id]);
+ cg->subsys[ss->subsys_id] = NULL;
+ hhead = css_set_hash(cg->subsys);
+ hlist_add_head(&cg->hlist, hhead);
+ }
+ write_unlock(&css_set_lock);
+
+ /*
+ * remove subsystem's css from the dummytop and free it - need to free
+ * before marking as null because ss->destroy needs the cgrp->subsys
+ * pointer to find their state. note that this also takes care of
+ * freeing the css_id.
+ */
+ ss->destroy(ss, dummytop);
+ dummytop->subsys[ss->subsys_id] = NULL;
+
+ mutex_unlock(&cgroup_mutex);
+}
+EXPORT_SYMBOL_GPL(cgroup_unload_subsys);
+
+/**
* cgroup_init_early - cgroup initialization at system boot
*
* Initialize cgroups at system boot, and initialize any
@@ -3253,7 +3817,8 @@ int __init cgroup_init_early(void)
for (i = 0; i < CSS_SET_TABLE_SIZE; i++)
INIT_HLIST_HEAD(&css_set_table[i]);
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ /* at bootup time, we don't worry about modular subsystems */
+ for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
BUG_ON(!ss->name);
@@ -3288,12 +3853,13 @@ int __init cgroup_init(void)
if (err)
return err;
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ /* at bootup time, we don't worry about modular subsystems */
+ for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
if (!ss->early_init)
cgroup_init_subsys(ss);
if (ss->use_id)
- cgroup_subsys_init_idr(ss);
+ cgroup_init_idr(ss, init_css_set.subsys[ss->subsys_id]);
}
/* Add init_css_set to the hash table */
@@ -3397,9 +3963,16 @@ static int proc_cgroupstats_show(struct seq_file *m, void *v)
int i;
seq_puts(m, "#subsys_name\thierarchy\tnum_cgroups\tenabled\n");
+ /*
+ * ideally we don't want subsystems moving around while we do this.
+ * cgroup_mutex is also necessary to guarantee an atomic snapshot of
+ * subsys/hierarchy state.
+ */
mutex_lock(&cgroup_mutex);
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
+ if (ss == NULL)
+ continue;
seq_printf(m, "%s\t%d\t%d\t%d\n",
ss->name, ss->root->hierarchy_id,
ss->root->number_of_cgroups, !ss->disabled);
@@ -3457,7 +4030,12 @@ void cgroup_fork_callbacks(struct task_struct *child)
{
if (need_forkexit_callback) {
int i;
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ /*
+ * forkexit callbacks are only supported for builtin
+ * subsystems, and the builtin section of the subsys array is
+ * immutable, so we don't need to lock the subsys array here.
+ */
+ for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
if (ss->fork)
ss->fork(ss, child);
@@ -3526,7 +4104,11 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
struct css_set *cg;
if (run_callbacks && need_forkexit_callback) {
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ /*
+ * modular subsystems can't use callbacks, so no need to lock
+ * the subsys array
+ */
+ for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
if (ss->exit)
ss->exit(ss, tsk);
@@ -3720,12 +4302,13 @@ static void check_for_release(struct cgroup *cgrp)
}
}
-void __css_put(struct cgroup_subsys_state *css)
+/* Caller must verify that the css is not for root cgroup */
+void __css_put(struct cgroup_subsys_state *css, int count)
{
struct cgroup *cgrp = css->cgroup;
int val;
rcu_read_lock();
- val = atomic_dec_return(&css->refcnt);
+ val = atomic_sub_return(count, &css->refcnt);
if (val == 1) {
if (notify_on_release(cgrp)) {
set_bit(CGRP_RELEASABLE, &cgrp->flags);
@@ -3736,6 +4319,7 @@ void __css_put(struct cgroup_subsys_state *css)
rcu_read_unlock();
WARN_ON_ONCE(val < 1);
}
+EXPORT_SYMBOL_GPL(__css_put);
/*
* Notify userspace when a cgroup is released, by running the
@@ -3817,8 +4401,11 @@ static int __init cgroup_disable(char *str)
while ((token = strsep(&str, ",")) != NULL) {
if (!*token)
continue;
-
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ /*
+ * cgroup_disable, being at boot time, can't know about module
+ * subsystems, so we don't worry about them.
+ */
+ for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
struct cgroup_subsys *ss = subsys[i];
if (!strcmp(token, ss->name)) {
@@ -3848,6 +4435,7 @@ unsigned short css_id(struct cgroup_subsys_state *css)
return cssid->id;
return 0;
}
+EXPORT_SYMBOL_GPL(css_id);
unsigned short css_depth(struct cgroup_subsys_state *css)
{
@@ -3857,6 +4445,7 @@ unsigned short css_depth(struct cgroup_subsys_state *css)
return cssid->depth;
return 0;
}
+EXPORT_SYMBOL_GPL(css_depth);
bool css_is_ancestor(struct cgroup_subsys_state *child,
const struct cgroup_subsys_state *root)
@@ -3893,6 +4482,7 @@ void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css)
spin_unlock(&ss->id_lock);
call_rcu(&id->rcu_head, __free_css_id_cb);
}
+EXPORT_SYMBOL_GPL(free_css_id);
/*
* This is called by init or create(). Then, calls to this function are
@@ -3942,15 +4532,14 @@ err_out:
}
-static int __init cgroup_subsys_init_idr(struct cgroup_subsys *ss)
+static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss,
+ struct cgroup_subsys_state *rootcss)
{
struct css_id *newid;
- struct cgroup_subsys_state *rootcss;
spin_lock_init(&ss->id_lock);
idr_init(&ss->idr);
- rootcss = init_css_set.subsys[ss->subsys_id];
newid = get_new_cssid(ss, 0);
if (IS_ERR(newid))
return PTR_ERR(newid);
@@ -4010,6 +4599,7 @@ struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id)
return rcu_dereference(cssid->css);
}
+EXPORT_SYMBOL_GPL(css_lookup);
/**
* css_get_next - lookup next cgroup under specified hierarchy.
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c
index 59e9ef6aab4..da5e1397553 100644
--- a/kernel/cgroup_freezer.c
+++ b/kernel/cgroup_freezer.c
@@ -15,6 +15,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/cgroup.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
@@ -47,17 +48,20 @@ static inline struct freezer *task_freezer(struct task_struct *task)
struct freezer, css);
}
-int cgroup_frozen(struct task_struct *task)
+int cgroup_freezing_or_frozen(struct task_struct *task)
{
struct freezer *freezer;
enum freezer_state state;
task_lock(task);
freezer = task_freezer(task);
- state = freezer->state;
+ if (!freezer->css.cgroup->parent)
+ state = CGROUP_THAWED; /* root cgroup can't be frozen */
+ else
+ state = freezer->state;
task_unlock(task);
- return state == CGROUP_FROZEN;
+ return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN);
}
/*
diff --git a/kernel/compat.c b/kernel/compat.c
index f6c204f07ea..7f40e9275fd 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -25,6 +25,7 @@
#include <linux/posix-timers.h>
#include <linux/times.h>
#include <linux/ptrace.h>
+#include <linux/gfp.h>
#include <asm/uaccess.h>
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 677f25376a3..25bba73b1be 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -14,6 +14,7 @@
#include <linux/kthread.h>
#include <linux/stop_machine.h>
#include <linux/mutex.h>
+#include <linux/gfp.h>
#ifdef CONFIG_SMP
/* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -338,7 +339,7 @@ int __cpuinit cpu_up(unsigned int cpu)
if (!cpu_possible(cpu)) {
printk(KERN_ERR "can't online cpu %d because it is not "
"configured as may-hotadd at boot time\n", cpu);
-#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
+#if defined(CONFIG_IA64)
printk(KERN_ERR "please check additional_cpus= boot "
"parameter\n");
#endif
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index ba401fab459..d10946748ec 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -920,9 +920,6 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
* call to guarantee_online_mems(), as we know no one is changing
* our task's cpuset.
*
- * Hold callback_mutex around the two modifications of our tasks
- * mems_allowed to synchronize with cpuset_mems_allowed().
- *
* While the mm_struct we are migrating is typically from some
* other task, the task_struct mems_allowed that we are hacking
* is for our current task, which must allocate new pages for that
@@ -973,15 +970,20 @@ static void cpuset_change_nodemask(struct task_struct *p,
struct cpuset *cs;
int migrate;
const nodemask_t *oldmem = scan->data;
- nodemask_t newmems;
+ NODEMASK_ALLOC(nodemask_t, newmems, GFP_KERNEL);
+
+ if (!newmems)
+ return;
cs = cgroup_cs(scan->cg);
- guarantee_online_mems(cs, &newmems);
+ guarantee_online_mems(cs, newmems);
task_lock(p);
- cpuset_change_task_nodemask(p, &newmems);
+ cpuset_change_task_nodemask(p, newmems);
task_unlock(p);
+ NODEMASK_FREE(newmems);
+
mm = get_task_mm(p);
if (!mm)
return;
@@ -1051,16 +1053,21 @@ static void update_tasks_nodemask(struct cpuset *cs, const nodemask_t *oldmem,
static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
const char *buf)
{
- nodemask_t oldmem;
+ NODEMASK_ALLOC(nodemask_t, oldmem, GFP_KERNEL);
int retval;
struct ptr_heap heap;
+ if (!oldmem)
+ return -ENOMEM;
+
/*
* top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
* it's read-only
*/
- if (cs == &top_cpuset)
- return -EACCES;
+ if (cs == &top_cpuset) {
+ retval = -EACCES;
+ goto done;
+ }
/*
* An empty mems_allowed is ok iff there are no tasks in the cpuset.
@@ -1076,11 +1083,13 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
goto done;
if (!nodes_subset(trialcs->mems_allowed,
- node_states[N_HIGH_MEMORY]))
- return -EINVAL;
+ node_states[N_HIGH_MEMORY])) {
+ retval = -EINVAL;
+ goto done;
+ }
}
- oldmem = cs->mems_allowed;
- if (nodes_equal(oldmem, trialcs->mems_allowed)) {
+ *oldmem = cs->mems_allowed;
+ if (nodes_equal(*oldmem, trialcs->mems_allowed)) {
retval = 0; /* Too easy - nothing to do */
goto done;
}
@@ -1096,10 +1105,11 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
cs->mems_allowed = trialcs->mems_allowed;
mutex_unlock(&callback_mutex);
- update_tasks_nodemask(cs, &oldmem, &heap);
+ update_tasks_nodemask(cs, oldmem, &heap);
heap_free(&heap);
done:
+ NODEMASK_FREE(oldmem);
return retval;
}
@@ -1384,40 +1394,47 @@ static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont,
struct cgroup *oldcont, struct task_struct *tsk,
bool threadgroup)
{
- nodemask_t from, to;
struct mm_struct *mm;
struct cpuset *cs = cgroup_cs(cont);
struct cpuset *oldcs = cgroup_cs(oldcont);
+ NODEMASK_ALLOC(nodemask_t, from, GFP_KERNEL);
+ NODEMASK_ALLOC(nodemask_t, to, GFP_KERNEL);
+
+ if (from == NULL || to == NULL)
+ goto alloc_fail;
if (cs == &top_cpuset) {
cpumask_copy(cpus_attach, cpu_possible_mask);
- to = node_possible_map;
} else {
guarantee_online_cpus(cs, cpus_attach);
- guarantee_online_mems(cs, &to);
}
+ guarantee_online_mems(cs, to);
/* do per-task migration stuff possibly for each in the threadgroup */
- cpuset_attach_task(tsk, &to, cs);
+ cpuset_attach_task(tsk, to, cs);
if (threadgroup) {
struct task_struct *c;
rcu_read_lock();
list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) {
- cpuset_attach_task(c, &to, cs);
+ cpuset_attach_task(c, to, cs);
}
rcu_read_unlock();
}
/* change mm; only needs to be done once even if threadgroup */
- from = oldcs->mems_allowed;
- to = cs->mems_allowed;
+ *from = oldcs->mems_allowed;
+ *to = cs->mems_allowed;
mm = get_task_mm(tsk);
if (mm) {
- mpol_rebind_mm(mm, &to);
+ mpol_rebind_mm(mm, to);
if (is_memory_migrate(cs))
- cpuset_migrate_mm(mm, &from, &to);
+ cpuset_migrate_mm(mm, from, to);
mmput(mm);
}
+
+alloc_fail:
+ NODEMASK_FREE(from);
+ NODEMASK_FREE(to);
}
/* The various types of files and directories in a cpuset file system */
@@ -1562,13 +1579,21 @@ static int cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
{
- nodemask_t mask;
+ NODEMASK_ALLOC(nodemask_t, mask, GFP_KERNEL);
+ int retval;
+
+ if (mask == NULL)
+ return -ENOMEM;
mutex_lock(&callback_mutex);
- mask = cs->mems_allowed;
+ *mask = cs->mems_allowed;
mutex_unlock(&callback_mutex);
- return nodelist_scnprintf(page, PAGE_SIZE, mask);
+ retval = nodelist_scnprintf(page, PAGE_SIZE, *mask);
+
+ NODEMASK_FREE(mask);
+
+ return retval;
}
static ssize_t cpuset_common_file_read(struct cgroup *cont,
@@ -1997,7 +2022,10 @@ static void scan_for_empty_cpusets(struct cpuset *root)
struct cpuset *cp; /* scans cpusets being updated */
struct cpuset *child; /* scans child cpusets of cp */
struct cgroup *cont;
- nodemask_t oldmems;
+ NODEMASK_ALLOC(nodemask_t, oldmems, GFP_KERNEL);
+
+ if (oldmems == NULL)
+ return;
list_add_tail((struct list_head *)&root->stack_list, &queue);
@@ -2014,7 +2042,7 @@ static void scan_for_empty_cpusets(struct cpuset *root)
nodes_subset(cp->mems_allowed, node_states[N_HIGH_MEMORY]))
continue;
- oldmems = cp->mems_allowed;
+ *oldmems = cp->mems_allowed;
/* Remove offline cpus and mems from this cpuset. */
mutex_lock(&callback_mutex);
@@ -2030,9 +2058,10 @@ static void scan_for_empty_cpusets(struct cpuset *root)
remove_tasks_in_empty_cpuset(cp);
else {
update_tasks_cpumask(cp, NULL);
- update_tasks_nodemask(cp, &oldmems, NULL);
+ update_tasks_nodemask(cp, oldmems, NULL);
}
}
+ NODEMASK_FREE(oldmems);
}
/*
@@ -2090,20 +2119,33 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
static int cpuset_track_online_nodes(struct notifier_block *self,
unsigned long action, void *arg)
{
+ NODEMASK_ALLOC(nodemask_t, oldmems, GFP_KERNEL);
+
+ if (oldmems == NULL)
+ return NOTIFY_DONE;
+
cgroup_lock();
switch (action) {
case MEM_ONLINE:
- case MEM_OFFLINE:
+ *oldmems = top_cpuset.mems_allowed;
mutex_lock(&callback_mutex);
top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
mutex_unlock(&callback_mutex);
- if (action == MEM_OFFLINE)
- scan_for_empty_cpusets(&top_cpuset);
+ update_tasks_nodemask(&top_cpuset, oldmems, NULL);
+ break;
+ case MEM_OFFLINE:
+ /*
+ * needn't update top_cpuset.mems_allowed explicitly because
+ * scan_for_empty_cpusets() will update it.
+ */
+ scan_for_empty_cpusets(&top_cpuset);
break;
default:
break;
}
cgroup_unlock();
+
+ NODEMASK_FREE(oldmems);
return NOTIFY_OK;
}
#endif
diff --git a/kernel/cred.c b/kernel/cred.c
index 1ed8ca18790..62af1816c23 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
#include <linux/cred.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/key.h>
#include <linux/keyctl.h>
@@ -364,7 +365,7 @@ struct cred *prepare_usermodehelper_creds(void)
new = kmem_cache_alloc(cred_jar, GFP_ATOMIC);
if (!new)
- return NULL;
+ goto free_tgcred;
kdebug("prepare_usermodehelper_creds() alloc %p", new);
@@ -398,6 +399,12 @@ struct cred *prepare_usermodehelper_creds(void)
error:
put_cred(new);
return NULL;
+
+free_tgcred:
+#ifdef CONFIG_KEYS
+ kfree(tgcred);
+#endif
+ return NULL;
}
/*
@@ -786,8 +793,6 @@ bool creds_are_invalid(const struct cred *cred)
{
if (cred->magic != CRED_MAGIC)
return true;
- if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers))
- return true;
#ifdef CONFIG_SECURITY_SELINUX
if (selinux_is_enabled()) {
if ((unsigned long) cred->security < PAGE_SIZE)
diff --git a/kernel/early_res.c b/kernel/early_res.c
index 3cb2c661bb7..31aa9332ef3 100644
--- a/kernel/early_res.c
+++ b/kernel/early_res.c
@@ -333,6 +333,12 @@ void __init free_early_partial(u64 start, u64 end)
struct early_res *r;
int i;
+ if (start == end)
+ return;
+
+ if (WARN_ONCE(start > end, " wrong range [%#llx, %#llx]\n", start, end))
+ return;
+
try_next:
i = find_overlapped_early(start, end);
if (i >= max_early_res)
diff --git a/kernel/elfcore.c b/kernel/elfcore.c
new file mode 100644
index 00000000000..ff915efef66
--- /dev/null
+++ b/kernel/elfcore.c
@@ -0,0 +1,28 @@
+#include <linux/elf.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf_Half __weak elf_core_extra_phdrs(void)
+{
+ return 0;
+}
+
+int __weak elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+ unsigned long limit)
+{
+ return 1;
+}
+
+int __weak elf_core_write_extra_data(struct file *file, size_t *size,
+ unsigned long limit)
+{
+ return 1;
+}
+
+size_t __weak elf_core_extra_data_size(void)
+{
+ return 0;
+}
diff --git a/kernel/exit.c b/kernel/exit.c
index 45ed043b8bf..7f2683a10ac 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -87,7 +87,7 @@ static void __exit_signal(struct task_struct *tsk)
sighand = rcu_dereference_check(tsk->sighand,
rcu_read_lock_held() ||
- lockdep_is_held(&tasklist_lock));
+ lockdep_tasklist_lock_is_held());
spin_lock(&sighand->siglock);
posix_cpu_timers_exit(tsk);
@@ -952,7 +952,9 @@ NORET_TYPE void do_exit(long code)
preempt_count());
acct_update_integrals(tsk);
-
+ /* sync mm's RSS info before statistics gathering */
+ if (tsk->mm)
+ sync_mm_rss(tsk, tsk->mm);
group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead) {
hrtimer_cancel(&tsk->signal->real_timer);
@@ -1188,7 +1190,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
if (unlikely(wo->wo_flags & WNOWAIT)) {
int exit_code = p->exit_code;
- int why, status;
+ int why;
get_task_struct(p);
read_unlock(&tasklist_lock);
diff --git a/kernel/fork.c b/kernel/fork.c
index 17bbf093356..44b0791b0a2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -86,7 +86,14 @@ int max_threads; /* tunable limit on nr_threads */
DEFINE_PER_CPU(unsigned long, process_counts) = 0;
__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
-EXPORT_SYMBOL_GPL(tasklist_lock);
+
+#ifdef CONFIG_PROVE_RCU
+int lockdep_tasklist_lock_is_held(void)
+{
+ return lockdep_is_held(&tasklist_lock);
+}
+EXPORT_SYMBOL_GPL(lockdep_tasklist_lock_is_held);
+#endif /* #ifdef CONFIG_PROVE_RCU */
int nr_processes(void)
{
@@ -329,15 +336,17 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
if (!tmp)
goto fail_nomem;
*tmp = *mpnt;
+ INIT_LIST_HEAD(&tmp->anon_vma_chain);
pol = mpol_dup(vma_policy(mpnt));
retval = PTR_ERR(pol);
if (IS_ERR(pol))
goto fail_nomem_policy;
vma_set_policy(tmp, pol);
+ if (anon_vma_fork(tmp, mpnt))
+ goto fail_nomem_anon_vma_fork;
tmp->vm_flags &= ~VM_LOCKED;
tmp->vm_mm = mm;
tmp->vm_next = NULL;
- anon_vma_link(tmp);
file = tmp->vm_file;
if (file) {
struct inode *inode = file->f_path.dentry->d_inode;
@@ -392,6 +401,8 @@ out:
flush_tlb_mm(oldmm);
up_write(&oldmm->mmap_sem);
return retval;
+fail_nomem_anon_vma_fork:
+ mpol_put(pol);
fail_nomem_policy:
kmem_cache_free(vm_area_cachep, tmp);
fail_nomem:
@@ -455,8 +466,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p)
(current->mm->flags & MMF_INIT_MASK) : default_dump_filter;
mm->core_state = NULL;
mm->nr_ptes = 0;
- set_mm_counter(mm, file_rss, 0);
- set_mm_counter(mm, anon_rss, 0);
+ memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
spin_lock_init(&mm->page_table_lock);
mm->free_area_cache = TASK_UNMAPPED_BASE;
mm->cached_hole_size = ~0UL;
@@ -825,23 +835,14 @@ void __cleanup_sighand(struct sighand_struct *sighand)
*/
static void posix_cpu_timers_init_group(struct signal_struct *sig)
{
+ unsigned long cpu_limit;
+
/* Thread group counters. */
thread_group_cputime_init(sig);
- /* Expiration times and increments. */
- sig->it[CPUCLOCK_PROF].expires = cputime_zero;
- sig->it[CPUCLOCK_PROF].incr = cputime_zero;
- sig->it[CPUCLOCK_VIRT].expires = cputime_zero;
- sig->it[CPUCLOCK_VIRT].incr = cputime_zero;
-
- /* Cached expiration times. */
- sig->cputime_expires.prof_exp = cputime_zero;
- sig->cputime_expires.virt_exp = cputime_zero;
- sig->cputime_expires.sched_exp = 0;
-
- if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
- sig->cputime_expires.prof_exp =
- secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
+ cpu_limit = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
+ if (cpu_limit != RLIM_INFINITY) {
+ sig->cputime_expires.prof_exp = secs_to_cputime(cpu_limit);
sig->cputimer.running = 1;
}
@@ -858,7 +859,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
if (clone_flags & CLONE_THREAD)
return 0;
- sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
+ sig = kmem_cache_zalloc(signal_cachep, GFP_KERNEL);
tsk->signal = sig;
if (!sig)
return -ENOMEM;
@@ -866,46 +867,21 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
atomic_set(&sig->count, 1);
atomic_set(&sig->live, 1);
init_waitqueue_head(&sig->wait_chldexit);
- sig->flags = 0;
if (clone_flags & CLONE_NEWPID)
sig->flags |= SIGNAL_UNKILLABLE;
- sig->group_exit_code = 0;
- sig->group_exit_task = NULL;
- sig->group_stop_count = 0;
sig->curr_target = tsk;
init_sigpending(&sig->shared_pending);
INIT_LIST_HEAD(&sig->posix_timers);
hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- sig->it_real_incr.tv64 = 0;
sig->real_timer.function = it_real_fn;
- sig->leader = 0; /* session leadership doesn't inherit */
- sig->tty_old_pgrp = NULL;
- sig->tty = NULL;
-
- sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
- sig->gtime = cputime_zero;
- sig->cgtime = cputime_zero;
-#ifndef CONFIG_VIRT_CPU_ACCOUNTING
- sig->prev_utime = sig->prev_stime = cputime_zero;
-#endif
- sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
- sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
- sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
- sig->maxrss = sig->cmaxrss = 0;
- task_io_accounting_init(&sig->ioac);
- sig->sum_sched_runtime = 0;
- taskstats_tgid_init(sig);
-
task_lock(current->group_leader);
memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
task_unlock(current->group_leader);
posix_cpu_timers_init_group(sig);
- acct_init_pacct(&sig->pacct);
-
tty_audit_fork(sig);
sig->oom_adj = current->signal->oom_adj;
@@ -1034,7 +1010,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
#endif
retval = -EAGAIN;
if (atomic_read(&p->real_cred->user->processes) >=
- p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
+ task_rlimit(p, RLIMIT_NPROC)) {
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
p->real_cred->user != INIT_USER)
goto bad_fork_free;
@@ -1076,6 +1052,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->prev_utime = cputime_zero;
p->prev_stime = cputime_zero;
#endif
+#if defined(SPLIT_RSS_COUNTING)
+ memset(&p->rss_stat, 0, sizeof(p->rss_stat));
+#endif
p->default_timer_slack_ns = current->timer_slack_ns;
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
index 967e66143e1..03808ed342a 100644
--- a/kernel/hw_breakpoint.c
+++ b/kernel/hw_breakpoint.c
@@ -413,17 +413,17 @@ EXPORT_SYMBOL_GPL(unregister_hw_breakpoint);
*
* @return a set of per_cpu pointers to perf events
*/
-struct perf_event **
+struct perf_event * __percpu *
register_wide_hw_breakpoint(struct perf_event_attr *attr,
perf_overflow_handler_t triggered)
{
- struct perf_event **cpu_events, **pevent, *bp;
+ struct perf_event * __percpu *cpu_events, **pevent, *bp;
long err;
int cpu;
cpu_events = alloc_percpu(typeof(*cpu_events));
if (!cpu_events)
- return ERR_PTR(-ENOMEM);
+ return (void __percpu __force *)ERR_PTR(-ENOMEM);
get_online_cpus();
for_each_online_cpu(cpu) {
@@ -451,7 +451,7 @@ fail:
put_online_cpus();
free_percpu(cpu_events);
- return ERR_PTR(err);
+ return (void __percpu __force *)ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint);
@@ -459,7 +459,7 @@ EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint);
* unregister_wide_hw_breakpoint - unregister a wide breakpoint in the kernel
* @cpu_events: the per cpu set of events to unregister
*/
-void unregister_wide_hw_breakpoint(struct perf_event **cpu_events)
+void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events)
{
int cpu;
struct perf_event **pevent;
@@ -489,5 +489,4 @@ struct pmu perf_ops_bp = {
.enable = arch_install_hw_breakpoint,
.disable = arch_uninstall_hw_breakpoint,
.read = hw_breakpoint_pmu_read,
- .unthrottle = hw_breakpoint_pmu_unthrottle
};
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index d70394f12ee..b7091d5ca2f 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -359,6 +359,23 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
if (desc->chip->ack)
desc->chip->ack(irq);
}
+ desc->status |= IRQ_MASKED;
+}
+
+static inline void mask_irq(struct irq_desc *desc, int irq)
+{
+ if (desc->chip->mask) {
+ desc->chip->mask(irq);
+ desc->status |= IRQ_MASKED;
+ }
+}
+
+static inline void unmask_irq(struct irq_desc *desc, int irq)
+{
+ if (desc->chip->unmask) {
+ desc->chip->unmask(irq);
+ desc->status &= ~IRQ_MASKED;
+ }
}
/*
@@ -484,10 +501,8 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
raw_spin_lock(&desc->lock);
desc->status &= ~IRQ_INPROGRESS;
- if (unlikely(desc->status & IRQ_ONESHOT))
- desc->status |= IRQ_MASKED;
- else if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
- desc->chip->unmask(irq);
+ if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT)))
+ unmask_irq(desc, irq);
out_unlock:
raw_spin_unlock(&desc->lock);
}
@@ -524,8 +539,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
action = desc->action;
if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
desc->status |= IRQ_PENDING;
- if (desc->chip->mask)
- desc->chip->mask(irq);
+ mask_irq(desc, irq);
goto out;
}
@@ -554,7 +568,7 @@ out:
* signal. The occurence is latched into the irq controller hardware
* and must be acked in order to be reenabled. After the ack another
* interrupt can happen on the same source even before the first one
- * is handled by the assosiacted event handler. If this happens it
+ * is handled by the associated event handler. If this happens it
* might be necessary to disable (mask) the interrupt depending on the
* controller hardware. This requires to reenable the interrupt inside
* of the loop which handles the interrupts which have arrived while
@@ -593,7 +607,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
irqreturn_t action_ret;
if (unlikely(!action)) {
- desc->chip->mask(irq);
+ mask_irq(desc, irq);
goto out_unlock;
}
@@ -605,8 +619,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
if (unlikely((desc->status &
(IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
(IRQ_PENDING | IRQ_MASKED))) {
- desc->chip->unmask(irq);
- desc->status &= ~IRQ_MASKED;
+ unmask_irq(desc, irq);
}
desc->status &= ~IRQ_PENDING;
@@ -716,7 +729,7 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
__set_irq_handler(irq, handle, 0, name);
}
-void __init set_irq_noprobe(unsigned int irq)
+void set_irq_noprobe(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
@@ -731,7 +744,7 @@ void __init set_irq_noprobe(unsigned int irq)
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
-void __init set_irq_probe(unsigned int irq)
+void set_irq_probe(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index d06df9c41cb..1ef4ffcdfa5 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -42,7 +42,7 @@ static int devm_irq_match(struct device *dev, void *res, void *data)
* automatically freed on driver detach.
*
* If an IRQ allocated with this function needs to be freed
- * separately, dev_free_irq() must be used.
+ * separately, devm_free_irq() must be used.
*/
int devm_request_threaded_irq(struct device *dev, unsigned int irq,
irq_handler_t handler, irq_handler_t thread_fn,
@@ -81,7 +81,7 @@ EXPORT_SYMBOL(devm_request_threaded_irq);
* Except for the extra @dev argument, this function takes the
* same arguments and performs the same function as free_irq().
* This function instead of free_irq() should be used to manually
- * free IRQs allocated with dev_request_irq().
+ * free IRQs allocated with devm_request_irq().
*/
void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id)
{
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index eb6078ca60c..704e488730a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -382,6 +382,7 @@ int can_request_irq(unsigned int irq, unsigned long irqflags)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
+ unsigned long flags;
if (!desc)
return 0;
@@ -389,11 +390,14 @@ int can_request_irq(unsigned int irq, unsigned long irqflags)
if (desc->status & IRQ_NOREQUEST)
return 0;
+ raw_spin_lock_irqsave(&desc->lock, flags);
action = desc->action;
if (action)
if (irqflags & action->flags & IRQF_SHARED)
action = NULL;
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+
return !action;
}
@@ -483,8 +487,26 @@ static int irq_wait_for_interrupt(struct irqaction *action)
*/
static void irq_finalize_oneshot(unsigned int irq, struct irq_desc *desc)
{
+again:
chip_bus_lock(irq, desc);
raw_spin_lock_irq(&desc->lock);
+
+ /*
+ * Implausible though it may be we need to protect us against
+ * the following scenario:
+ *
+ * The thread is faster done than the hard interrupt handler
+ * on the other CPU. If we unmask the irq line then the
+ * interrupt can come in again and masks the line, leaves due
+ * to IRQ_INPROGRESS and the irq line is masked forever.
+ */
+ if (unlikely(desc->status & IRQ_INPROGRESS)) {
+ raw_spin_unlock_irq(&desc->lock);
+ chip_bus_sync_unlock(irq, desc);
+ cpu_relax();
+ goto again;
+ }
+
if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) {
desc->status &= ~IRQ_MASKED;
desc->chip->unmask(irq);
@@ -735,6 +757,16 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
if (new->flags & IRQF_ONESHOT)
desc->status |= IRQ_ONESHOT;
+ /*
+ * Force MSI interrupts to run with interrupts
+ * disabled. The multi vector cards can cause stack
+ * overflows due to nested interrupts when enough of
+ * them are directed to a core and fire at the same
+ * time.
+ */
+ if (desc->msi_desc)
+ new->flags |= IRQF_DISABLED;
+
if (!(desc->status & IRQ_NOAUTOEN)) {
desc->depth = 0;
desc->status &= ~IRQ_DISABLED;
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index 963559dbd85..65d3845665a 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -6,6 +6,7 @@
*/
#include <linux/irq.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/interrupt.h>
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 6f50eccc79c..7a6eb04ef6b 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -7,6 +7,7 @@
*/
#include <linux/irq.h>
+#include <linux/gfp.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 8e5288a8a35..13aff293f4d 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -21,6 +21,7 @@
#include <linux/sched.h> /* for cond_resched */
#include <linux/mm.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <asm/sections.h>
diff --git a/kernel/kgdb.c b/kernel/kgdb.c
index 761fdd2b303..11f3515ca83 100644
--- a/kernel/kgdb.c
+++ b/kernel/kgdb.c
@@ -69,9 +69,16 @@ struct kgdb_state {
struct pt_regs *linux_regs;
};
+/* Exception state values */
+#define DCPU_WANT_MASTER 0x1 /* Waiting to become a master kgdb cpu */
+#define DCPU_NEXT_MASTER 0x2 /* Transition from one master cpu to another */
+#define DCPU_IS_SLAVE 0x4 /* Slave cpu enter exception */
+#define DCPU_SSTEP 0x8 /* CPU is single stepping */
+
static struct debuggerinfo_struct {
void *debuggerinfo;
struct task_struct *task;
+ int exception_state;
} kgdb_info[NR_CPUS];
/**
@@ -391,27 +398,22 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
/*
* Copy the binary array pointed to by buf into mem. Fix $, #, and
- * 0x7d escaped with 0x7d. Return a pointer to the character after
- * the last byte written.
+ * 0x7d escaped with 0x7d. Return -EFAULT on failure or 0 on success.
+ * The input buf is overwitten with the result to write to mem.
*/
static int kgdb_ebin2mem(char *buf, char *mem, int count)
{
- int err = 0;
- char c;
+ int size = 0;
+ char *c = buf;
while (count-- > 0) {
- c = *buf++;
- if (c == 0x7d)
- c = *buf++ ^ 0x20;
-
- err = probe_kernel_write(mem, &c, 1);
- if (err)
- break;
-
- mem++;
+ c[size] = *buf++;
+ if (c[size] == 0x7d)
+ c[size] = *buf++ ^ 0x20;
+ size++;
}
- return err;
+ return probe_kernel_write(mem, c, size);
}
/*
@@ -563,49 +565,6 @@ static struct task_struct *getthread(struct pt_regs *regs, int tid)
}
/*
- * CPU debug state control:
- */
-
-#ifdef CONFIG_SMP
-static void kgdb_wait(struct pt_regs *regs)
-{
- unsigned long flags;
- int cpu;
-
- local_irq_save(flags);
- cpu = raw_smp_processor_id();
- kgdb_info[cpu].debuggerinfo = regs;
- kgdb_info[cpu].task = current;
- /*
- * Make sure the above info reaches the primary CPU before
- * our cpu_in_kgdb[] flag setting does:
- */
- smp_wmb();
- atomic_set(&cpu_in_kgdb[cpu], 1);
-
- /* Disable any cpu specific hw breakpoints */
- kgdb_disable_hw_debug(regs);
-
- /* Wait till primary CPU is done with debugging */
- while (atomic_read(&passive_cpu_wait[cpu]))
- cpu_relax();
-
- kgdb_info[cpu].debuggerinfo = NULL;
- kgdb_info[cpu].task = NULL;
-
- /* fix up hardware debug registers on local cpu */
- if (arch_kgdb_ops.correct_hw_break)
- arch_kgdb_ops.correct_hw_break();
-
- /* Signal the primary CPU that we are done: */
- atomic_set(&cpu_in_kgdb[cpu], 0);
- touch_softlockup_watchdog_sync();
- clocksource_touch_watchdog();
- local_irq_restore(flags);
-}
-#endif
-
-/*
* Some architectures need cache flushes when we set/clear a
* breakpoint:
*/
@@ -1400,34 +1359,13 @@ static int kgdb_reenter_check(struct kgdb_state *ks)
return 1;
}
-/*
- * kgdb_handle_exception() - main entry point from a kernel exception
- *
- * Locking hierarchy:
- * interface locks, if any (begin_session)
- * kgdb lock (kgdb_active)
- */
-int
-kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
+static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs)
{
- struct kgdb_state kgdb_var;
- struct kgdb_state *ks = &kgdb_var;
unsigned long flags;
int sstep_tries = 100;
int error = 0;
int i, cpu;
-
- ks->cpu = raw_smp_processor_id();
- ks->ex_vector = evector;
- ks->signo = signo;
- ks->ex_vector = evector;
- ks->err_code = ecode;
- ks->kgdb_usethreadid = 0;
- ks->linux_regs = regs;
-
- if (kgdb_reenter_check(ks))
- return 0; /* Ouch, double exception ! */
-
+ int trace_on = 0;
acquirelock:
/*
* Interrupts will be restored by the 'trap return' code, except when
@@ -1435,13 +1373,43 @@ acquirelock:
*/
local_irq_save(flags);
- cpu = raw_smp_processor_id();
+ cpu = ks->cpu;
+ kgdb_info[cpu].debuggerinfo = regs;
+ kgdb_info[cpu].task = current;
+ /*
+ * Make sure the above info reaches the primary CPU before
+ * our cpu_in_kgdb[] flag setting does:
+ */
+ atomic_inc(&cpu_in_kgdb[cpu]);
/*
- * Acquire the kgdb_active lock:
+ * CPU will loop if it is a slave or request to become a kgdb
+ * master cpu and acquire the kgdb_active lock:
*/
- while (atomic_cmpxchg(&kgdb_active, -1, cpu) != -1)
+ while (1) {
+ if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) {
+ if (atomic_cmpxchg(&kgdb_active, -1, cpu) == cpu)
+ break;
+ } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) {
+ if (!atomic_read(&passive_cpu_wait[cpu]))
+ goto return_normal;
+ } else {
+return_normal:
+ /* Return to normal operation by executing any
+ * hw breakpoint fixup.
+ */
+ if (arch_kgdb_ops.correct_hw_break)
+ arch_kgdb_ops.correct_hw_break();
+ if (trace_on)
+ tracing_on();
+ atomic_dec(&cpu_in_kgdb[cpu]);
+ touch_softlockup_watchdog_sync();
+ clocksource_touch_watchdog();
+ local_irq_restore(flags);
+ return 0;
+ }
cpu_relax();
+ }
/*
* For single stepping, try to only enter on the processor
@@ -1475,9 +1443,6 @@ acquirelock:
if (kgdb_io_ops->pre_exception)
kgdb_io_ops->pre_exception();
- kgdb_info[ks->cpu].debuggerinfo = ks->linux_regs;
- kgdb_info[ks->cpu].task = current;
-
kgdb_disable_hw_debug(ks->linux_regs);
/*
@@ -1486,15 +1451,9 @@ acquirelock:
*/
if (!kgdb_single_step) {
for (i = 0; i < NR_CPUS; i++)
- atomic_set(&passive_cpu_wait[i], 1);
+ atomic_inc(&passive_cpu_wait[i]);
}
- /*
- * spin_lock code is good enough as a barrier so we don't
- * need one here:
- */
- atomic_set(&cpu_in_kgdb[ks->cpu], 1);
-
#ifdef CONFIG_SMP
/* Signal the other CPUs to enter kgdb_wait() */
if ((!kgdb_single_step) && kgdb_do_roundup)
@@ -1518,6 +1477,9 @@ acquirelock:
kgdb_single_step = 0;
kgdb_contthread = current;
exception_level = 0;
+ trace_on = tracing_is_on();
+ if (trace_on)
+ tracing_off();
/* Talk to debugger with gdbserial protocol */
error = gdb_serial_stub(ks);
@@ -1526,13 +1488,11 @@ acquirelock:
if (kgdb_io_ops->post_exception)
kgdb_io_ops->post_exception();
- kgdb_info[ks->cpu].debuggerinfo = NULL;
- kgdb_info[ks->cpu].task = NULL;
- atomic_set(&cpu_in_kgdb[ks->cpu], 0);
+ atomic_dec(&cpu_in_kgdb[ks->cpu]);
if (!kgdb_single_step) {
for (i = NR_CPUS-1; i >= 0; i--)
- atomic_set(&passive_cpu_wait[i], 0);
+ atomic_dec(&passive_cpu_wait[i]);
/*
* Wait till all the CPUs have quit
* from the debugger.
@@ -1551,6 +1511,8 @@ kgdb_restore:
else
kgdb_sstep_pid = 0;
}
+ if (trace_on)
+ tracing_on();
/* Free kgdb_active */
atomic_set(&kgdb_active, -1);
touch_softlockup_watchdog_sync();
@@ -1560,13 +1522,52 @@ kgdb_restore:
return error;
}
+/*
+ * kgdb_handle_exception() - main entry point from a kernel exception
+ *
+ * Locking hierarchy:
+ * interface locks, if any (begin_session)
+ * kgdb lock (kgdb_active)
+ */
+int
+kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
+{
+ struct kgdb_state kgdb_var;
+ struct kgdb_state *ks = &kgdb_var;
+ int ret;
+
+ ks->cpu = raw_smp_processor_id();
+ ks->ex_vector = evector;
+ ks->signo = signo;
+ ks->ex_vector = evector;
+ ks->err_code = ecode;
+ ks->kgdb_usethreadid = 0;
+ ks->linux_regs = regs;
+
+ if (kgdb_reenter_check(ks))
+ return 0; /* Ouch, double exception ! */
+ kgdb_info[ks->cpu].exception_state |= DCPU_WANT_MASTER;
+ ret = kgdb_cpu_enter(ks, regs);
+ kgdb_info[ks->cpu].exception_state &= ~DCPU_WANT_MASTER;
+ return ret;
+}
+
int kgdb_nmicallback(int cpu, void *regs)
{
#ifdef CONFIG_SMP
+ struct kgdb_state kgdb_var;
+ struct kgdb_state *ks = &kgdb_var;
+
+ memset(ks, 0, sizeof(struct kgdb_state));
+ ks->cpu = cpu;
+ ks->linux_regs = regs;
+
if (!atomic_read(&cpu_in_kgdb[cpu]) &&
- atomic_read(&kgdb_active) != cpu &&
- atomic_read(&cpu_in_kgdb[atomic_read(&kgdb_active)])) {
- kgdb_wait((struct pt_regs *)regs);
+ atomic_read(&kgdb_active) != -1 &&
+ atomic_read(&kgdb_active) != cpu) {
+ kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE;
+ kgdb_cpu_enter(ks, regs);
+ kgdb_info[cpu].exception_state &= ~DCPU_IS_SLAVE;
return 0;
}
#endif
@@ -1742,11 +1743,11 @@ EXPORT_SYMBOL_GPL(kgdb_unregister_io_module);
*/
void kgdb_breakpoint(void)
{
- atomic_set(&kgdb_setting_breakpoint, 1);
+ atomic_inc(&kgdb_setting_breakpoint);
wmb(); /* Sync point before breakpoint */
arch_kgdb_breakpoint();
wmb(); /* Sync point after breakpoint */
- atomic_set(&kgdb_setting_breakpoint, 0);
+ atomic_dec(&kgdb_setting_breakpoint);
}
EXPORT_SYMBOL_GPL(kgdb_breakpoint);
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index ccec774c716..0ed46f3e51e 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -42,9 +42,11 @@
#include <linux/freezer.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
+#include <linux/sysctl.h>
#include <linux/kdebug.h>
#include <linux/memory.h>
#include <linux/ftrace.h>
+#include <linux/cpu.h>
#include <asm-generic/sections.h>
#include <asm/cacheflush.h>
@@ -105,57 +107,74 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
* stepping on the instruction on a vmalloced/kmalloced/data page
* is a recipe for disaster
*/
-#define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
-
struct kprobe_insn_page {
struct list_head list;
kprobe_opcode_t *insns; /* Page of instruction slots */
- char slot_used[INSNS_PER_PAGE];
int nused;
int ngarbage;
+ char slot_used[];
+};
+
+#define KPROBE_INSN_PAGE_SIZE(slots) \
+ (offsetof(struct kprobe_insn_page, slot_used) + \
+ (sizeof(char) * (slots)))
+
+struct kprobe_insn_cache {
+ struct list_head pages; /* list of kprobe_insn_page */
+ size_t insn_size; /* size of instruction slot */
+ int nr_garbage;
};
+static int slots_per_page(struct kprobe_insn_cache *c)
+{
+ return PAGE_SIZE/(c->insn_size * sizeof(kprobe_opcode_t));
+}
+
enum kprobe_slot_state {
SLOT_CLEAN = 0,
SLOT_DIRTY = 1,
SLOT_USED = 2,
};
-static DEFINE_MUTEX(kprobe_insn_mutex); /* Protects kprobe_insn_pages */
-static LIST_HEAD(kprobe_insn_pages);
-static int kprobe_garbage_slots;
-static int collect_garbage_slots(void);
+static DEFINE_MUTEX(kprobe_insn_mutex); /* Protects kprobe_insn_slots */
+static struct kprobe_insn_cache kprobe_insn_slots = {
+ .pages = LIST_HEAD_INIT(kprobe_insn_slots.pages),
+ .insn_size = MAX_INSN_SIZE,
+ .nr_garbage = 0,
+};
+static int __kprobes collect_garbage_slots(struct kprobe_insn_cache *c);
/**
* __get_insn_slot() - Find a slot on an executable page for an instruction.
* We allocate an executable page if there's no room on existing ones.
*/
-static kprobe_opcode_t __kprobes *__get_insn_slot(void)
+static kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
{
struct kprobe_insn_page *kip;
retry:
- list_for_each_entry(kip, &kprobe_insn_pages, list) {
- if (kip->nused < INSNS_PER_PAGE) {
+ list_for_each_entry(kip, &c->pages, list) {
+ if (kip->nused < slots_per_page(c)) {
int i;
- for (i = 0; i < INSNS_PER_PAGE; i++) {
+ for (i = 0; i < slots_per_page(c); i++) {
if (kip->slot_used[i] == SLOT_CLEAN) {
kip->slot_used[i] = SLOT_USED;
kip->nused++;
- return kip->insns + (i * MAX_INSN_SIZE);
+ return kip->insns + (i * c->insn_size);
}
}
- /* Surprise! No unused slots. Fix kip->nused. */
- kip->nused = INSNS_PER_PAGE;
+ /* kip->nused is broken. Fix it. */
+ kip->nused = slots_per_page(c);
+ WARN_ON(1);
}
}
/* If there are any garbage slots, collect it and try again. */
- if (kprobe_garbage_slots && collect_garbage_slots() == 0) {
+ if (c->nr_garbage && collect_garbage_slots(c) == 0)
goto retry;
- }
- /* All out of space. Need to allocate a new page. Use slot 0. */
- kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL);
+
+ /* All out of space. Need to allocate a new page. */
+ kip = kmalloc(KPROBE_INSN_PAGE_SIZE(slots_per_page(c)), GFP_KERNEL);
if (!kip)
return NULL;
@@ -170,20 +189,23 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(void)
return NULL;
}
INIT_LIST_HEAD(&kip->list);
- list_add(&kip->list, &kprobe_insn_pages);
- memset(kip->slot_used, SLOT_CLEAN, INSNS_PER_PAGE);
+ memset(kip->slot_used, SLOT_CLEAN, slots_per_page(c));
kip->slot_used[0] = SLOT_USED;
kip->nused = 1;
kip->ngarbage = 0;
+ list_add(&kip->list, &c->pages);
return kip->insns;
}
+
kprobe_opcode_t __kprobes *get_insn_slot(void)
{
- kprobe_opcode_t *ret;
+ kprobe_opcode_t *ret = NULL;
+
mutex_lock(&kprobe_insn_mutex);
- ret = __get_insn_slot();
+ ret = __get_insn_slot(&kprobe_insn_slots);
mutex_unlock(&kprobe_insn_mutex);
+
return ret;
}
@@ -199,7 +221,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
* so as not to have to set it up again the
* next time somebody inserts a probe.
*/
- if (!list_is_singular(&kprobe_insn_pages)) {
+ if (!list_is_singular(&kip->list)) {
list_del(&kip->list);
module_free(NULL, kip->insns);
kfree(kip);
@@ -209,51 +231,85 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
return 0;
}
-static int __kprobes collect_garbage_slots(void)
+static int __kprobes collect_garbage_slots(struct kprobe_insn_cache *c)
{
struct kprobe_insn_page *kip, *next;
/* Ensure no-one is interrupted on the garbages */
synchronize_sched();
- list_for_each_entry_safe(kip, next, &kprobe_insn_pages, list) {
+ list_for_each_entry_safe(kip, next, &c->pages, list) {
int i;
if (kip->ngarbage == 0)
continue;
kip->ngarbage = 0; /* we will collect all garbages */
- for (i = 0; i < INSNS_PER_PAGE; i++) {
+ for (i = 0; i < slots_per_page(c); i++) {
if (kip->slot_used[i] == SLOT_DIRTY &&
collect_one_slot(kip, i))
break;
}
}
- kprobe_garbage_slots = 0;
+ c->nr_garbage = 0;
return 0;
}
-void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty)
+static void __kprobes __free_insn_slot(struct kprobe_insn_cache *c,
+ kprobe_opcode_t *slot, int dirty)
{
struct kprobe_insn_page *kip;
- mutex_lock(&kprobe_insn_mutex);
- list_for_each_entry(kip, &kprobe_insn_pages, list) {
- if (kip->insns <= slot &&
- slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) {
- int i = (slot - kip->insns) / MAX_INSN_SIZE;
+ list_for_each_entry(kip, &c->pages, list) {
+ long idx = ((long)slot - (long)kip->insns) /
+ (c->insn_size * sizeof(kprobe_opcode_t));
+ if (idx >= 0 && idx < slots_per_page(c)) {
+ WARN_ON(kip->slot_used[idx] != SLOT_USED);
if (dirty) {
- kip->slot_used[i] = SLOT_DIRTY;
+ kip->slot_used[idx] = SLOT_DIRTY;
kip->ngarbage++;
+ if (++c->nr_garbage > slots_per_page(c))
+ collect_garbage_slots(c);
} else
- collect_one_slot(kip, i);
- break;
+ collect_one_slot(kip, idx);
+ return;
}
}
+ /* Could not free this slot. */
+ WARN_ON(1);
+}
- if (dirty && ++kprobe_garbage_slots > INSNS_PER_PAGE)
- collect_garbage_slots();
-
+void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty)
+{
+ mutex_lock(&kprobe_insn_mutex);
+ __free_insn_slot(&kprobe_insn_slots, slot, dirty);
mutex_unlock(&kprobe_insn_mutex);
}
+#ifdef CONFIG_OPTPROBES
+/* For optimized_kprobe buffer */
+static DEFINE_MUTEX(kprobe_optinsn_mutex); /* Protects kprobe_optinsn_slots */
+static struct kprobe_insn_cache kprobe_optinsn_slots = {
+ .pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages),
+ /* .insn_size is initialized later */
+ .nr_garbage = 0,
+};
+/* Get a slot for optimized_kprobe buffer */
+kprobe_opcode_t __kprobes *get_optinsn_slot(void)
+{
+ kprobe_opcode_t *ret = NULL;
+
+ mutex_lock(&kprobe_optinsn_mutex);
+ ret = __get_insn_slot(&kprobe_optinsn_slots);
+ mutex_unlock(&kprobe_optinsn_mutex);
+
+ return ret;
+}
+
+void __kprobes free_optinsn_slot(kprobe_opcode_t * slot, int dirty)
+{
+ mutex_lock(&kprobe_optinsn_mutex);
+ __free_insn_slot(&kprobe_optinsn_slots, slot, dirty);
+ mutex_unlock(&kprobe_optinsn_mutex);
+}
+#endif
#endif
/* We have preemption disabled.. so it is safe to use __ versions */
@@ -284,23 +340,401 @@ struct kprobe __kprobes *get_kprobe(void *addr)
if (p->addr == addr)
return p;
}
+
+ return NULL;
+}
+
+static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs);
+
+/* Return true if the kprobe is an aggregator */
+static inline int kprobe_aggrprobe(struct kprobe *p)
+{
+ return p->pre_handler == aggr_pre_handler;
+}
+
+/*
+ * Keep all fields in the kprobe consistent
+ */
+static inline void copy_kprobe(struct kprobe *old_p, struct kprobe *p)
+{
+ memcpy(&p->opcode, &old_p->opcode, sizeof(kprobe_opcode_t));
+ memcpy(&p->ainsn, &old_p->ainsn, sizeof(struct arch_specific_insn));
+}
+
+#ifdef CONFIG_OPTPROBES
+/* NOTE: change this value only with kprobe_mutex held */
+static bool kprobes_allow_optimization;
+
+/*
+ * Call all pre_handler on the list, but ignores its return value.
+ * This must be called from arch-dep optimized caller.
+ */
+void __kprobes opt_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kprobe *kp;
+
+ list_for_each_entry_rcu(kp, &p->list, list) {
+ if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
+ set_kprobe_instance(kp);
+ kp->pre_handler(kp, regs);
+ }
+ reset_kprobe_instance();
+ }
+}
+
+/* Return true(!0) if the kprobe is ready for optimization. */
+static inline int kprobe_optready(struct kprobe *p)
+{
+ struct optimized_kprobe *op;
+
+ if (kprobe_aggrprobe(p)) {
+ op = container_of(p, struct optimized_kprobe, kp);
+ return arch_prepared_optinsn(&op->optinsn);
+ }
+
+ return 0;
+}
+
+/*
+ * Return an optimized kprobe whose optimizing code replaces
+ * instructions including addr (exclude breakpoint).
+ */
+struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr)
+{
+ int i;
+ struct kprobe *p = NULL;
+ struct optimized_kprobe *op;
+
+ /* Don't check i == 0, since that is a breakpoint case. */
+ for (i = 1; !p && i < MAX_OPTIMIZED_LENGTH; i++)
+ p = get_kprobe((void *)(addr - i));
+
+ if (p && kprobe_optready(p)) {
+ op = container_of(p, struct optimized_kprobe, kp);
+ if (arch_within_optimized_kprobe(op, addr))
+ return p;
+ }
+
return NULL;
}
+/* Optimization staging list, protected by kprobe_mutex */
+static LIST_HEAD(optimizing_list);
+
+static void kprobe_optimizer(struct work_struct *work);
+static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer);
+#define OPTIMIZE_DELAY 5
+
+/* Kprobe jump optimizer */
+static __kprobes void kprobe_optimizer(struct work_struct *work)
+{
+ struct optimized_kprobe *op, *tmp;
+
+ /* Lock modules while optimizing kprobes */
+ mutex_lock(&module_mutex);
+ mutex_lock(&kprobe_mutex);
+ if (kprobes_all_disarmed || !kprobes_allow_optimization)
+ goto end;
+
+ /*
+ * Wait for quiesence period to ensure all running interrupts
+ * are done. Because optprobe may modify multiple instructions
+ * there is a chance that Nth instruction is interrupted. In that
+ * case, running interrupt can return to 2nd-Nth byte of jump
+ * instruction. This wait is for avoiding it.
+ */
+ synchronize_sched();
+
+ /*
+ * The optimization/unoptimization refers online_cpus via
+ * stop_machine() and cpu-hotplug modifies online_cpus.
+ * And same time, text_mutex will be held in cpu-hotplug and here.
+ * This combination can cause a deadlock (cpu-hotplug try to lock
+ * text_mutex but stop_machine can not be done because online_cpus
+ * has been changed)
+ * To avoid this deadlock, we need to call get_online_cpus()
+ * for preventing cpu-hotplug outside of text_mutex locking.
+ */
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+ list_for_each_entry_safe(op, tmp, &optimizing_list, list) {
+ WARN_ON(kprobe_disabled(&op->kp));
+ if (arch_optimize_kprobe(op) < 0)
+ op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
+ list_del_init(&op->list);
+ }
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+end:
+ mutex_unlock(&kprobe_mutex);
+ mutex_unlock(&module_mutex);
+}
+
+/* Optimize kprobe if p is ready to be optimized */
+static __kprobes void optimize_kprobe(struct kprobe *p)
+{
+ struct optimized_kprobe *op;
+
+ /* Check if the kprobe is disabled or not ready for optimization. */
+ if (!kprobe_optready(p) || !kprobes_allow_optimization ||
+ (kprobe_disabled(p) || kprobes_all_disarmed))
+ return;
+
+ /* Both of break_handler and post_handler are not supported. */
+ if (p->break_handler || p->post_handler)
+ return;
+
+ op = container_of(p, struct optimized_kprobe, kp);
+
+ /* Check there is no other kprobes at the optimized instructions */
+ if (arch_check_optimized_kprobe(op) < 0)
+ return;
+
+ /* Check if it is already optimized. */
+ if (op->kp.flags & KPROBE_FLAG_OPTIMIZED)
+ return;
+
+ op->kp.flags |= KPROBE_FLAG_OPTIMIZED;
+ list_add(&op->list, &optimizing_list);
+ if (!delayed_work_pending(&optimizing_work))
+ schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY);
+}
+
+/* Unoptimize a kprobe if p is optimized */
+static __kprobes void unoptimize_kprobe(struct kprobe *p)
+{
+ struct optimized_kprobe *op;
+
+ if ((p->flags & KPROBE_FLAG_OPTIMIZED) && kprobe_aggrprobe(p)) {
+ op = container_of(p, struct optimized_kprobe, kp);
+ if (!list_empty(&op->list))
+ /* Dequeue from the optimization queue */
+ list_del_init(&op->list);
+ else
+ /* Replace jump with break */
+ arch_unoptimize_kprobe(op);
+ op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
+ }
+}
+
+/* Remove optimized instructions */
+static void __kprobes kill_optimized_kprobe(struct kprobe *p)
+{
+ struct optimized_kprobe *op;
+
+ op = container_of(p, struct optimized_kprobe, kp);
+ if (!list_empty(&op->list)) {
+ /* Dequeue from the optimization queue */
+ list_del_init(&op->list);
+ op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
+ }
+ /* Don't unoptimize, because the target code will be freed. */
+ arch_remove_optimized_kprobe(op);
+}
+
+/* Try to prepare optimized instructions */
+static __kprobes void prepare_optimized_kprobe(struct kprobe *p)
+{
+ struct optimized_kprobe *op;
+
+ op = container_of(p, struct optimized_kprobe, kp);
+ arch_prepare_optimized_kprobe(op);
+}
+
+/* Free optimized instructions and optimized_kprobe */
+static __kprobes void free_aggr_kprobe(struct kprobe *p)
+{
+ struct optimized_kprobe *op;
+
+ op = container_of(p, struct optimized_kprobe, kp);
+ arch_remove_optimized_kprobe(op);
+ kfree(op);
+}
+
+/* Allocate new optimized_kprobe and try to prepare optimized instructions */
+static __kprobes struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
+{
+ struct optimized_kprobe *op;
+
+ op = kzalloc(sizeof(struct optimized_kprobe), GFP_KERNEL);
+ if (!op)
+ return NULL;
+
+ INIT_LIST_HEAD(&op->list);
+ op->kp.addr = p->addr;
+ arch_prepare_optimized_kprobe(op);
+
+ return &op->kp;
+}
+
+static void __kprobes init_aggr_kprobe(struct kprobe *ap, struct kprobe *p);
+
+/*
+ * Prepare an optimized_kprobe and optimize it
+ * NOTE: p must be a normal registered kprobe
+ */
+static __kprobes void try_to_optimize_kprobe(struct kprobe *p)
+{
+ struct kprobe *ap;
+ struct optimized_kprobe *op;
+
+ ap = alloc_aggr_kprobe(p);
+ if (!ap)
+ return;
+
+ op = container_of(ap, struct optimized_kprobe, kp);
+ if (!arch_prepared_optinsn(&op->optinsn)) {
+ /* If failed to setup optimizing, fallback to kprobe */
+ free_aggr_kprobe(ap);
+ return;
+ }
+
+ init_aggr_kprobe(ap, p);
+ optimize_kprobe(ap);
+}
+
+#ifdef CONFIG_SYSCTL
+static void __kprobes optimize_all_kprobes(void)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct kprobe *p;
+ unsigned int i;
+
+ /* If optimization is already allowed, just return */
+ if (kprobes_allow_optimization)
+ return;
+
+ kprobes_allow_optimization = true;
+ mutex_lock(&text_mutex);
+ for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
+ head = &kprobe_table[i];
+ hlist_for_each_entry_rcu(p, node, head, hlist)
+ if (!kprobe_disabled(p))
+ optimize_kprobe(p);
+ }
+ mutex_unlock(&text_mutex);
+ printk(KERN_INFO "Kprobes globally optimized\n");
+}
+
+static void __kprobes unoptimize_all_kprobes(void)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct kprobe *p;
+ unsigned int i;
+
+ /* If optimization is already prohibited, just return */
+ if (!kprobes_allow_optimization)
+ return;
+
+ kprobes_allow_optimization = false;
+ printk(KERN_INFO "Kprobes globally unoptimized\n");
+ get_online_cpus(); /* For avoiding text_mutex deadlock */
+ mutex_lock(&text_mutex);
+ for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
+ head = &kprobe_table[i];
+ hlist_for_each_entry_rcu(p, node, head, hlist) {
+ if (!kprobe_disabled(p))
+ unoptimize_kprobe(p);
+ }
+ }
+
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+ /* Allow all currently running kprobes to complete */
+ synchronize_sched();
+}
+
+int sysctl_kprobes_optimization;
+int proc_kprobes_optimization_handler(struct ctl_table *table, int write,
+ void __user *buffer, size_t *length,
+ loff_t *ppos)
+{
+ int ret;
+
+ mutex_lock(&kprobe_mutex);
+ sysctl_kprobes_optimization = kprobes_allow_optimization ? 1 : 0;
+ ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
+
+ if (sysctl_kprobes_optimization)
+ optimize_all_kprobes();
+ else
+ unoptimize_all_kprobes();
+ mutex_unlock(&kprobe_mutex);
+
+ return ret;
+}
+#endif /* CONFIG_SYSCTL */
+
+static void __kprobes __arm_kprobe(struct kprobe *p)
+{
+ struct kprobe *old_p;
+
+ /* Check collision with other optimized kprobes */
+ old_p = get_optimized_kprobe((unsigned long)p->addr);
+ if (unlikely(old_p))
+ unoptimize_kprobe(old_p); /* Fallback to unoptimized kprobe */
+
+ arch_arm_kprobe(p);
+ optimize_kprobe(p); /* Try to optimize (add kprobe to a list) */
+}
+
+static void __kprobes __disarm_kprobe(struct kprobe *p)
+{
+ struct kprobe *old_p;
+
+ unoptimize_kprobe(p); /* Try to unoptimize */
+ arch_disarm_kprobe(p);
+
+ /* If another kprobe was blocked, optimize it. */
+ old_p = get_optimized_kprobe((unsigned long)p->addr);
+ if (unlikely(old_p))
+ optimize_kprobe(old_p);
+}
+
+#else /* !CONFIG_OPTPROBES */
+
+#define optimize_kprobe(p) do {} while (0)
+#define unoptimize_kprobe(p) do {} while (0)
+#define kill_optimized_kprobe(p) do {} while (0)
+#define prepare_optimized_kprobe(p) do {} while (0)
+#define try_to_optimize_kprobe(p) do {} while (0)
+#define __arm_kprobe(p) arch_arm_kprobe(p)
+#define __disarm_kprobe(p) arch_disarm_kprobe(p)
+
+static __kprobes void free_aggr_kprobe(struct kprobe *p)
+{
+ kfree(p);
+}
+
+static __kprobes struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
+{
+ return kzalloc(sizeof(struct kprobe), GFP_KERNEL);
+}
+#endif /* CONFIG_OPTPROBES */
+
/* Arm a kprobe with text_mutex */
static void __kprobes arm_kprobe(struct kprobe *kp)
{
+ /*
+ * Here, since __arm_kprobe() doesn't use stop_machine(),
+ * this doesn't cause deadlock on text_mutex. So, we don't
+ * need get_online_cpus().
+ */
mutex_lock(&text_mutex);
- arch_arm_kprobe(kp);
+ __arm_kprobe(kp);
mutex_unlock(&text_mutex);
}
/* Disarm a kprobe with text_mutex */
static void __kprobes disarm_kprobe(struct kprobe *kp)
{
+ get_online_cpus(); /* For avoiding text_mutex deadlock */
mutex_lock(&text_mutex);
- arch_disarm_kprobe(kp);
+ __disarm_kprobe(kp);
mutex_unlock(&text_mutex);
+ put_online_cpus();
}
/*
@@ -369,7 +803,7 @@ static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
void __kprobes kprobes_inc_nmissed_count(struct kprobe *p)
{
struct kprobe *kp;
- if (p->pre_handler != aggr_pre_handler) {
+ if (!kprobe_aggrprobe(p)) {
p->nmissed++;
} else {
list_for_each_entry_rcu(kp, &p->list, list)
@@ -493,21 +927,16 @@ static void __kprobes cleanup_rp_inst(struct kretprobe *rp)
}
/*
- * Keep all fields in the kprobe consistent
- */
-static inline void copy_kprobe(struct kprobe *old_p, struct kprobe *p)
-{
- memcpy(&p->opcode, &old_p->opcode, sizeof(kprobe_opcode_t));
- memcpy(&p->ainsn, &old_p->ainsn, sizeof(struct arch_specific_insn));
-}
-
-/*
* Add the new probe to ap->list. Fail if this is the
* second jprobe at the address - two jprobes can't coexist
*/
static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
{
BUG_ON(kprobe_gone(ap) || kprobe_gone(p));
+
+ if (p->break_handler || p->post_handler)
+ unoptimize_kprobe(ap); /* Fall back to normal kprobe */
+
if (p->break_handler) {
if (ap->break_handler)
return -EEXIST;
@@ -522,7 +951,7 @@ static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
ap->flags &= ~KPROBE_FLAG_DISABLED;
if (!kprobes_all_disarmed)
/* Arm the breakpoint again. */
- arm_kprobe(ap);
+ __arm_kprobe(ap);
}
return 0;
}
@@ -531,12 +960,13 @@ static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
* Fill in the required fields of the "manager kprobe". Replace the
* earlier kprobe in the hlist with the manager kprobe
*/
-static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
+static void __kprobes init_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
{
+ /* Copy p's insn slot to ap */
copy_kprobe(p, ap);
flush_insn_slot(ap);
ap->addr = p->addr;
- ap->flags = p->flags;
+ ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED;
ap->pre_handler = aggr_pre_handler;
ap->fault_handler = aggr_fault_handler;
/* We don't care the kprobe which has gone. */
@@ -546,8 +976,9 @@ static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
ap->break_handler = aggr_break_handler;
INIT_LIST_HEAD(&ap->list);
- list_add_rcu(&p->list, &ap->list);
+ INIT_HLIST_NODE(&ap->hlist);
+ list_add_rcu(&p->list, &ap->list);
hlist_replace_rcu(&p->hlist, &ap->hlist);
}
@@ -561,12 +992,12 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
int ret = 0;
struct kprobe *ap = old_p;
- if (old_p->pre_handler != aggr_pre_handler) {
- /* If old_p is not an aggr_probe, create new aggr_kprobe. */
- ap = kzalloc(sizeof(struct kprobe), GFP_KERNEL);
+ if (!kprobe_aggrprobe(old_p)) {
+ /* If old_p is not an aggr_kprobe, create new aggr_kprobe. */
+ ap = alloc_aggr_kprobe(old_p);
if (!ap)
return -ENOMEM;
- add_aggr_kprobe(ap, old_p);
+ init_aggr_kprobe(ap, old_p);
}
if (kprobe_gone(ap)) {
@@ -585,6 +1016,9 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
*/
return ret;
+ /* Prepare optimized instructions if possible. */
+ prepare_optimized_kprobe(ap);
+
/*
* Clear gone flag to prevent allocating new slot again, and
* set disabled flag because it is not armed yet.
@@ -593,6 +1027,7 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
| KPROBE_FLAG_DISABLED;
}
+ /* Copy ap's insn slot to p */
copy_kprobe(ap, p);
return add_new_kprobe(ap, p);
}
@@ -743,27 +1178,34 @@ int __kprobes register_kprobe(struct kprobe *p)
p->nmissed = 0;
INIT_LIST_HEAD(&p->list);
mutex_lock(&kprobe_mutex);
+
+ get_online_cpus(); /* For avoiding text_mutex deadlock. */
+ mutex_lock(&text_mutex);
+
old_p = get_kprobe(p->addr);
if (old_p) {
+ /* Since this may unoptimize old_p, locking text_mutex. */
ret = register_aggr_kprobe(old_p, p);
goto out;
}
- mutex_lock(&text_mutex);
ret = arch_prepare_kprobe(p);
if (ret)
- goto out_unlock_text;
+ goto out;
INIT_HLIST_NODE(&p->hlist);
hlist_add_head_rcu(&p->hlist,
&kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
if (!kprobes_all_disarmed && !kprobe_disabled(p))
- arch_arm_kprobe(p);
+ __arm_kprobe(p);
+
+ /* Try to optimize kprobe */
+ try_to_optimize_kprobe(p);
-out_unlock_text:
- mutex_unlock(&text_mutex);
out:
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
mutex_unlock(&kprobe_mutex);
if (probed_mod)
@@ -785,7 +1227,7 @@ static int __kprobes __unregister_kprobe_top(struct kprobe *p)
return -EINVAL;
if (old_p == p ||
- (old_p->pre_handler == aggr_pre_handler &&
+ (kprobe_aggrprobe(old_p) &&
list_is_singular(&old_p->list))) {
/*
* Only probe on the hash list. Disarm only if kprobes are
@@ -793,7 +1235,7 @@ static int __kprobes __unregister_kprobe_top(struct kprobe *p)
* already have been removed. We save on flushing icache.
*/
if (!kprobes_all_disarmed && !kprobe_disabled(old_p))
- disarm_kprobe(p);
+ disarm_kprobe(old_p);
hlist_del_rcu(&old_p->hlist);
} else {
if (p->break_handler && !kprobe_gone(p))
@@ -809,8 +1251,13 @@ noclean:
list_del_rcu(&p->list);
if (!kprobe_disabled(old_p)) {
try_to_disable_aggr_kprobe(old_p);
- if (!kprobes_all_disarmed && kprobe_disabled(old_p))
- disarm_kprobe(old_p);
+ if (!kprobes_all_disarmed) {
+ if (kprobe_disabled(old_p))
+ disarm_kprobe(old_p);
+ else
+ /* Try to optimize this probe again */
+ optimize_kprobe(old_p);
+ }
}
}
return 0;
@@ -827,7 +1274,7 @@ static void __kprobes __unregister_kprobe_bottom(struct kprobe *p)
old_p = list_entry(p->list.next, struct kprobe, list);
list_del(&p->list);
arch_remove_kprobe(old_p);
- kfree(old_p);
+ free_aggr_kprobe(old_p);
}
}
@@ -1123,7 +1570,7 @@ static void __kprobes kill_kprobe(struct kprobe *p)
struct kprobe *kp;
p->flags |= KPROBE_FLAG_GONE;
- if (p->pre_handler == aggr_pre_handler) {
+ if (kprobe_aggrprobe(p)) {
/*
* If this is an aggr_kprobe, we have to list all the
* chained probes and mark them GONE.
@@ -1132,6 +1579,7 @@ static void __kprobes kill_kprobe(struct kprobe *p)
kp->flags |= KPROBE_FLAG_GONE;
p->post_handler = NULL;
p->break_handler = NULL;
+ kill_optimized_kprobe(p);
}
/*
* Here, we can remove insn_slot safely, because no thread calls
@@ -1241,6 +1689,15 @@ static int __init init_kprobes(void)
}
}
+#if defined(CONFIG_OPTPROBES)
+#if defined(__ARCH_WANT_KPROBES_INSN_SLOT)
+ /* Init kprobe_optinsn_slots */
+ kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;
+#endif
+ /* By default, kprobes can be optimized */
+ kprobes_allow_optimization = true;
+#endif
+
/* By default, kprobes are armed */
kprobes_all_disarmed = false;
@@ -1259,7 +1716,7 @@ static int __init init_kprobes(void)
#ifdef CONFIG_DEBUG_FS
static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
- const char *sym, int offset,char *modname)
+ const char *sym, int offset, char *modname, struct kprobe *pp)
{
char *kprobe_type;
@@ -1269,19 +1726,21 @@ static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
kprobe_type = "j";
else
kprobe_type = "k";
+
if (sym)
- seq_printf(pi, "%p %s %s+0x%x %s %s%s\n",
+ seq_printf(pi, "%p %s %s+0x%x %s ",
p->addr, kprobe_type, sym, offset,
- (modname ? modname : " "),
- (kprobe_gone(p) ? "[GONE]" : ""),
- ((kprobe_disabled(p) && !kprobe_gone(p)) ?
- "[DISABLED]" : ""));
+ (modname ? modname : " "));
else
- seq_printf(pi, "%p %s %p %s%s\n",
- p->addr, kprobe_type, p->addr,
- (kprobe_gone(p) ? "[GONE]" : ""),
- ((kprobe_disabled(p) && !kprobe_gone(p)) ?
- "[DISABLED]" : ""));
+ seq_printf(pi, "%p %s %p ",
+ p->addr, kprobe_type, p->addr);
+
+ if (!pp)
+ pp = p;
+ seq_printf(pi, "%s%s%s\n",
+ (kprobe_gone(p) ? "[GONE]" : ""),
+ ((kprobe_disabled(p) && !kprobe_gone(p)) ? "[DISABLED]" : ""),
+ (kprobe_optimized(pp) ? "[OPTIMIZED]" : ""));
}
static void __kprobes *kprobe_seq_start(struct seq_file *f, loff_t *pos)
@@ -1317,11 +1776,11 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
hlist_for_each_entry_rcu(p, node, head, hlist) {
sym = kallsyms_lookup((unsigned long)p->addr, NULL,
&offset, &modname, namebuf);
- if (p->pre_handler == aggr_pre_handler) {
+ if (kprobe_aggrprobe(p)) {
list_for_each_entry_rcu(kp, &p->list, list)
- report_probe(pi, kp, sym, offset, modname);
+ report_probe(pi, kp, sym, offset, modname, p);
} else
- report_probe(pi, p, sym, offset, modname);
+ report_probe(pi, p, sym, offset, modname, NULL);
}
preempt_enable();
return 0;
@@ -1399,12 +1858,13 @@ int __kprobes enable_kprobe(struct kprobe *kp)
goto out;
}
- if (!kprobes_all_disarmed && kprobe_disabled(p))
- arm_kprobe(p);
-
- p->flags &= ~KPROBE_FLAG_DISABLED;
if (p != kp)
kp->flags &= ~KPROBE_FLAG_DISABLED;
+
+ if (!kprobes_all_disarmed && kprobe_disabled(p)) {
+ p->flags &= ~KPROBE_FLAG_DISABLED;
+ arm_kprobe(p);
+ }
out:
mutex_unlock(&kprobe_mutex);
return ret;
@@ -1424,12 +1884,13 @@ static void __kprobes arm_all_kprobes(void)
if (!kprobes_all_disarmed)
goto already_enabled;
+ /* Arming kprobes doesn't optimize kprobe itself */
mutex_lock(&text_mutex);
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
hlist_for_each_entry_rcu(p, node, head, hlist)
if (!kprobe_disabled(p))
- arch_arm_kprobe(p);
+ __arm_kprobe(p);
}
mutex_unlock(&text_mutex);
@@ -1456,16 +1917,23 @@ static void __kprobes disarm_all_kprobes(void)
kprobes_all_disarmed = true;
printk(KERN_INFO "Kprobes globally disabled\n");
+
+ /*
+ * Here we call get_online_cpus() for avoiding text_mutex deadlock,
+ * because disarming may also unoptimize kprobes.
+ */
+ get_online_cpus();
mutex_lock(&text_mutex);
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
hlist_for_each_entry_rcu(p, node, head, hlist) {
if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p))
- arch_disarm_kprobe(p);
+ __disarm_kprobe(p);
}
}
mutex_unlock(&text_mutex);
+ put_online_cpus();
mutex_unlock(&kprobe_mutex);
/* Allow all currently running kprobes to complete */
synchronize_sched();
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 6b1ccc3f020..21fe3c42694 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -33,7 +33,7 @@ static ssize_t uevent_seqnum_show(struct kobject *kobj,
}
KERNEL_ATTR_RO(uevent_seqnum);
-/* uevent helper program, used during early boo */
+/* uevent helper program, used during early boot */
static ssize_t uevent_helper_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 82ed0ea1519..83911c78017 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -219,7 +219,7 @@ int kthreadd(void *unused)
set_task_comm(tsk, "kthreadd");
ignore_signals(tsk);
set_cpus_allowed_ptr(tsk, cpu_all_mask);
- set_mems_allowed(node_possible_map);
+ set_mems_allowed(node_states[N_HIGH_MEMORY]);
current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
diff --git a/kernel/latencytop.c b/kernel/latencytop.c
index ca07c5c0c91..877fb306d41 100644
--- a/kernel/latencytop.c
+++ b/kernel/latencytop.c
@@ -56,7 +56,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/list.h>
-#include <linux/slab.h>
#include <linux/stacktrace.h>
static DEFINE_SPINLOCK(latency_lock);
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 0c30d0455de..2594e1ce41c 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -43,6 +43,7 @@
#include <linux/ftrace.h>
#include <linux/stringify.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
#include <asm/sections.h>
@@ -582,9 +583,6 @@ static int static_obj(void *obj)
unsigned long start = (unsigned long) &_stext,
end = (unsigned long) &_end,
addr = (unsigned long) obj;
-#ifdef CONFIG_SMP
- int i;
-#endif
/*
* static variable?
@@ -595,24 +593,16 @@ static int static_obj(void *obj)
if (arch_is_kernel_data(addr))
return 1;
-#ifdef CONFIG_SMP
/*
- * percpu var?
+ * in-kernel percpu var?
*/
- for_each_possible_cpu(i) {
- start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
- + per_cpu_offset(i);
-
- if ((addr >= start) && (addr < end))
- return 1;
- }
-#endif
+ if (is_kernel_percpu_address(addr))
+ return 1;
/*
- * module var?
+ * module static or percpu var?
*/
- return is_module_address(addr);
+ return is_module_address(addr) || is_module_percpu_address(addr);
}
/*
@@ -3211,8 +3201,6 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
{
unsigned long flags;
- trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
-
if (unlikely(current->lockdep_recursion))
return;
@@ -3220,6 +3208,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
check_flags(flags);
current->lockdep_recursion = 1;
+ trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
__lock_acquire(lock, subclass, trylock, read, check,
irqs_disabled_flags(flags), nest_lock, ip, 0);
current->lockdep_recursion = 0;
@@ -3232,14 +3221,13 @@ void lock_release(struct lockdep_map *lock, int nested,
{
unsigned long flags;
- trace_lock_release(lock, nested, ip);
-
if (unlikely(current->lockdep_recursion))
return;
raw_local_irq_save(flags);
check_flags(flags);
current->lockdep_recursion = 1;
+ trace_lock_release(lock, nested, ip);
__lock_release(lock, nested, ip);
current->lockdep_recursion = 0;
raw_local_irq_restore(flags);
@@ -3413,8 +3401,6 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
{
unsigned long flags;
- trace_lock_contended(lock, ip);
-
if (unlikely(!lock_stat))
return;
@@ -3424,6 +3410,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
raw_local_irq_save(flags);
check_flags(flags);
current->lockdep_recursion = 1;
+ trace_lock_contended(lock, ip);
__lock_contended(lock, ip);
current->lockdep_recursion = 0;
raw_local_irq_restore(flags);
@@ -3822,6 +3809,7 @@ void lockdep_rcu_dereference(const char *file, const int line)
printk("%s:%d invoked rcu_dereference_check() without protection!\n",
file, line);
printk("\nother info that might help us debug this:\n\n");
+ printk("\nrcu_scheduler_active = %d, debug_locks = %d\n", rcu_scheduler_active, debug_locks);
lockdep_print_held_locks(curr);
printk("\nstack backtrace:\n");
dump_stack();
diff --git a/kernel/module.c b/kernel/module.c
index e5538d5f00a..1016b75b026 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -370,27 +370,33 @@ EXPORT_SYMBOL_GPL(find_module);
#ifdef CONFIG_SMP
-static void *percpu_modalloc(unsigned long size, unsigned long align,
- const char *name)
+static inline void __percpu *mod_percpu(struct module *mod)
{
- void *ptr;
+ return mod->percpu;
+}
+static int percpu_modalloc(struct module *mod,
+ unsigned long size, unsigned long align)
+{
if (align > PAGE_SIZE) {
printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
- name, align, PAGE_SIZE);
+ mod->name, align, PAGE_SIZE);
align = PAGE_SIZE;
}
- ptr = __alloc_reserved_percpu(size, align);
- if (!ptr)
+ mod->percpu = __alloc_reserved_percpu(size, align);
+ if (!mod->percpu) {
printk(KERN_WARNING
"Could not allocate %lu bytes percpu data\n", size);
- return ptr;
+ return -ENOMEM;
+ }
+ mod->percpu_size = size;
+ return 0;
}
-static void percpu_modfree(void *freeme)
+static void percpu_modfree(struct module *mod)
{
- free_percpu(freeme);
+ free_percpu(mod->percpu);
}
static unsigned int find_pcpusec(Elf_Ehdr *hdr,
@@ -400,24 +406,62 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr,
return find_sec(hdr, sechdrs, secstrings, ".data.percpu");
}
-static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size)
+static void percpu_modcopy(struct module *mod,
+ const void *from, unsigned long size)
{
int cpu;
for_each_possible_cpu(cpu)
- memcpy(pcpudest + per_cpu_offset(cpu), from, size);
+ memcpy(per_cpu_ptr(mod->percpu, cpu), from, size);
+}
+
+/**
+ * is_module_percpu_address - test whether address is from module static percpu
+ * @addr: address to test
+ *
+ * Test whether @addr belongs to module static percpu area.
+ *
+ * RETURNS:
+ * %true if @addr is from module static percpu area
+ */
+bool is_module_percpu_address(unsigned long addr)
+{
+ struct module *mod;
+ unsigned int cpu;
+
+ preempt_disable();
+
+ list_for_each_entry_rcu(mod, &modules, list) {
+ if (!mod->percpu_size)
+ continue;
+ for_each_possible_cpu(cpu) {
+ void *start = per_cpu_ptr(mod->percpu, cpu);
+
+ if ((void *)addr >= start &&
+ (void *)addr < start + mod->percpu_size) {
+ preempt_enable();
+ return true;
+ }
+ }
+ }
+
+ preempt_enable();
+ return false;
}
#else /* ... !CONFIG_SMP */
-static inline void *percpu_modalloc(unsigned long size, unsigned long align,
- const char *name)
+static inline void __percpu *mod_percpu(struct module *mod)
{
return NULL;
}
-static inline void percpu_modfree(void *pcpuptr)
+static inline int percpu_modalloc(struct module *mod,
+ unsigned long size, unsigned long align)
+{
+ return -ENOMEM;
+}
+static inline void percpu_modfree(struct module *mod)
{
- BUG();
}
static inline unsigned int find_pcpusec(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs,
@@ -425,12 +469,16 @@ static inline unsigned int find_pcpusec(Elf_Ehdr *hdr,
{
return 0;
}
-static inline void percpu_modcopy(void *pcpudst, const void *src,
- unsigned long size)
+static inline void percpu_modcopy(struct module *mod,
+ const void *from, unsigned long size)
{
/* pcpusec should be 0, and size of that section should be 0. */
BUG_ON(size != 0);
}
+bool is_module_percpu_address(unsigned long addr)
+{
+ return false;
+}
#endif /* CONFIG_SMP */
@@ -473,11 +521,13 @@ static void module_unload_init(struct module *mod)
int cpu;
INIT_LIST_HEAD(&mod->modules_which_use_me);
- for_each_possible_cpu(cpu)
- per_cpu_ptr(mod->refptr, cpu)->count = 0;
+ for_each_possible_cpu(cpu) {
+ per_cpu_ptr(mod->refptr, cpu)->incs = 0;
+ per_cpu_ptr(mod->refptr, cpu)->decs = 0;
+ }
/* Hold reference count during initialization. */
- __this_cpu_write(mod->refptr->count, 1);
+ __this_cpu_write(mod->refptr->incs, 1);
/* Backwards compatibility macros put refcount during init. */
mod->waiter = current;
}
@@ -616,12 +666,28 @@ static int try_stop_module(struct module *mod, int flags, int *forced)
unsigned int module_refcount(struct module *mod)
{
- unsigned int total = 0;
+ unsigned int incs = 0, decs = 0;
int cpu;
for_each_possible_cpu(cpu)
- total += per_cpu_ptr(mod->refptr, cpu)->count;
- return total;
+ decs += per_cpu_ptr(mod->refptr, cpu)->decs;
+ /*
+ * ensure the incs are added up after the decs.
+ * module_put ensures incs are visible before decs with smp_wmb.
+ *
+ * This 2-count scheme avoids the situation where the refcount
+ * for CPU0 is read, then CPU0 increments the module refcount,
+ * then CPU1 drops that refcount, then the refcount for CPU1 is
+ * read. We would record a decrement but not its corresponding
+ * increment so we would see a low count (disaster).
+ *
+ * Rare situation? But module_refcount can be preempted, and we
+ * might be tallying up 4096+ CPUs. So it is not impossible.
+ */
+ smp_rmb();
+ for_each_possible_cpu(cpu)
+ incs += per_cpu_ptr(mod->refptr, cpu)->incs;
+ return incs - decs;
}
EXPORT_SYMBOL(module_refcount);
@@ -798,10 +864,11 @@ void module_put(struct module *module)
{
if (module) {
preempt_disable();
- __this_cpu_dec(module->refptr->count);
+ smp_wmb(); /* see comment in module_refcount */
+ __this_cpu_inc(module->refptr->decs);
trace_module_put(module, _RET_IP_,
- __this_cpu_read(module->refptr->count));
+ __this_cpu_read(module->refptr->decs));
/* Maybe they're waiting for us to drop reference? */
if (unlikely(!module_is_live(module)))
wake_up_process(module->waiter);
@@ -1085,6 +1152,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
if (sattr->name == NULL)
goto out;
sect_attrs->nsections++;
+ sysfs_attr_init(&sattr->mattr.attr);
sattr->mattr.show = module_sect_show;
sattr->mattr.store = NULL;
sattr->mattr.attr.name = sattr->name;
@@ -1180,6 +1248,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
if (sect_empty(&sechdrs[i]))
continue;
if (sechdrs[i].sh_type == SHT_NOTE) {
+ sysfs_bin_attr_init(nattr);
nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
nattr->attr.mode = S_IRUGO;
nattr->size = sechdrs[i].sh_size;
@@ -1252,6 +1321,7 @@ int module_add_modinfo_attrs(struct module *mod)
if (!attr->test ||
(attr->test && attr->test(mod))) {
memcpy(temp_attr, attr, sizeof(*temp_attr));
+ sysfs_attr_init(&temp_attr->attr);
error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr);
++temp_attr;
}
@@ -1397,8 +1467,7 @@ static void free_module(struct module *mod)
/* This may be NULL, but that's OK */
module_free(mod, mod->module_init);
kfree(mod->args);
- if (mod->percpu)
- percpu_modfree(mod->percpu);
+ percpu_modfree(mod);
#if defined(CONFIG_MODULE_UNLOAD)
if (mod->refptr)
free_percpu(mod->refptr);
@@ -1517,7 +1586,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
default:
/* Divert to percpu allocation if a percpu var. */
if (sym[i].st_shndx == pcpuindex)
- secbase = (unsigned long)mod->percpu;
+ secbase = (unsigned long)mod_percpu(mod);
else
secbase = sechdrs[sym[i].st_shndx].sh_addr;
sym[i].st_value += secbase;
@@ -1951,7 +2020,7 @@ static noinline struct module *load_module(void __user *umod,
unsigned int modindex, versindex, infoindex, pcpuindex;
struct module *mod;
long err = 0;
- void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
+ void *ptr = NULL; /* Stops spurious gcc warning */
unsigned long symoffs, stroffs, *strmap;
mm_segment_t old_fs;
@@ -2091,15 +2160,11 @@ static noinline struct module *load_module(void __user *umod,
if (pcpuindex) {
/* We have a special allocation for this section. */
- percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
- sechdrs[pcpuindex].sh_addralign,
- mod->name);
- if (!percpu) {
- err = -ENOMEM;
+ err = percpu_modalloc(mod, sechdrs[pcpuindex].sh_size,
+ sechdrs[pcpuindex].sh_addralign);
+ if (err)
goto free_mod;
- }
sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
- mod->percpu = percpu;
}
/* Determine total sizes, and put offsets in sh_entsize. For now
@@ -2314,7 +2379,7 @@ static noinline struct module *load_module(void __user *umod,
sort_extable(mod->extable, mod->extable + mod->num_exentries);
/* Finally, copy percpu area over. */
- percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
+ percpu_modcopy(mod, (void *)sechdrs[pcpuindex].sh_addr,
sechdrs[pcpuindex].sh_size);
add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex,
@@ -2406,8 +2471,7 @@ static noinline struct module *load_module(void __user *umod,
module_free(mod, mod->module_core);
/* mod will be freed with core. Don't access it beyond this line! */
free_percpu:
- if (percpu)
- percpu_modfree(percpu);
+ percpu_modfree(mod);
free_mod:
kfree(args);
kfree(strmap);
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 09b4ff9711b..f74e6c00e26 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -13,6 +13,7 @@
* Pavel Emelianov <xemul@openvz.org>
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/nsproxy.h>
#include <linux/init_task.h>
@@ -24,7 +25,18 @@
static struct kmem_cache *nsproxy_cachep;
-struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
+struct nsproxy init_nsproxy = {
+ .count = ATOMIC_INIT(1),
+ .uts_ns = &init_uts_ns,
+#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
+ .ipc_ns = &init_ipc_ns,
+#endif
+ .mnt_ns = NULL,
+ .pid_ns = &init_pid_ns,
+#ifdef CONFIG_NET
+ .net_ns = &init_net,
+#endif
+};
static inline struct nsproxy *create_nsproxy(void)
{
diff --git a/kernel/padata.c b/kernel/padata.c
index 5085046d83f..5b44d0fa358 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -25,6 +25,7 @@
#include <linux/padata.h>
#include <linux/mutex.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/rcupdate.h>
#define MAX_SEQ_NR INT_MAX - NR_CPUS
@@ -642,6 +643,9 @@ struct padata_instance *padata_alloc(const struct cpumask *cpumask,
if (!pd)
goto err_free_inst;
+ if (!alloc_cpumask_var(&pinst->cpumask, GFP_KERNEL))
+ goto err_free_pd;
+
rcu_assign_pointer(pinst->pd, pd);
pinst->wq = wq;
@@ -654,12 +658,14 @@ struct padata_instance *padata_alloc(const struct cpumask *cpumask,
pinst->cpu_notifier.priority = 0;
err = register_hotcpu_notifier(&pinst->cpu_notifier);
if (err)
- goto err_free_pd;
+ goto err_free_cpumask;
mutex_init(&pinst->lock);
return pinst;
+err_free_cpumask:
+ free_cpumask_var(pinst->cpumask);
err_free_pd:
padata_free_pd(pd);
err_free_inst:
@@ -685,6 +691,7 @@ void padata_free(struct padata_instance *pinst)
unregister_hotcpu_notifier(&pinst->cpu_notifier);
padata_free_pd(pinst->pd);
+ free_cpumask_var(pinst->cpumask);
kfree(pinst);
}
EXPORT_SYMBOL(padata_free);
diff --git a/kernel/panic.c b/kernel/panic.c
index c787333282b..13d966b4c14 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -36,15 +36,36 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
EXPORT_SYMBOL(panic_notifier_list);
-static long no_blink(long time)
-{
- return 0;
-}
-
/* Returns how long it waited in ms */
long (*panic_blink)(long time);
EXPORT_SYMBOL(panic_blink);
+static void panic_blink_one_second(void)
+{
+ static long i = 0, end;
+
+ if (panic_blink) {
+ end = i + MSEC_PER_SEC;
+
+ while (i < end) {
+ i += panic_blink(i);
+ mdelay(1);
+ i++;
+ }
+ } else {
+ /*
+ * When running under a hypervisor a small mdelay may get
+ * rounded up to the hypervisor timeslice. For example, with
+ * a 1ms in 10ms hypervisor timeslice we might inflate a
+ * mdelay(1) loop by 10x.
+ *
+ * If we have nothing to blink, spin on 1 second calls to
+ * mdelay to avoid this.
+ */
+ mdelay(MSEC_PER_SEC);
+ }
+}
+
/**
* panic - halt the system
* @fmt: The text string to print
@@ -95,9 +116,6 @@ NORET_TYPE void panic(const char * fmt, ...)
bust_spinlocks(0);
- if (!panic_blink)
- panic_blink = no_blink;
-
if (panic_timeout > 0) {
/*
* Delay timeout seconds before rebooting the machine.
@@ -105,11 +123,9 @@ NORET_TYPE void panic(const char * fmt, ...)
*/
printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout);
- for (i = 0; i < panic_timeout*1000; ) {
+ for (i = 0; i < panic_timeout; i++) {
touch_nmi_watchdog();
- i += panic_blink(i);
- mdelay(1);
- i++;
+ panic_blink_one_second();
}
/*
* This will not be a clean reboot, with everything
@@ -135,11 +151,9 @@ NORET_TYPE void panic(const char * fmt, ...)
}
#endif
local_irq_enable();
- for (i = 0; ; ) {
+ while (1) {
touch_softlockup_watchdog();
- i += panic_blink(i);
- mdelay(1);
- i++;
+ panic_blink_one_second();
}
}
diff --git a/kernel/params.c b/kernel/params.c
index cf1b6918312..0b30ecd53a5 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -24,7 +24,6 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/ctype.h>
-#include <linux/string.h>
#if 0
#define DEBUGP printk
@@ -402,8 +401,8 @@ int param_get_string(char *buffer, struct kernel_param *kp)
}
/* sysfs output in /sys/modules/XYZ/parameters/ */
-#define to_module_attr(n) container_of(n, struct module_attribute, attr);
-#define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
+#define to_module_attr(n) container_of(n, struct module_attribute, attr)
+#define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
extern struct kernel_param __start___param[], __stop___param[];
@@ -421,7 +420,7 @@ struct module_param_attrs
};
#ifdef CONFIG_SYSFS
-#define to_param_attr(n) container_of(n, struct param_attribute, mattr);
+#define to_param_attr(n) container_of(n, struct param_attribute, mattr)
static ssize_t param_attr_show(struct module_attribute *mattr,
struct module *mod, char *buf)
@@ -517,6 +516,7 @@ static __modinit int add_sysfs_param(struct module_kobject *mk,
new->grp.attrs = attrs;
/* Tack new one on the end. */
+ sysfs_attr_init(&new->attrs[num].mattr.attr);
new->attrs[num].param = kp;
new->attrs[num].mattr.show = param_attr_show;
new->attrs[num].mattr.store = param_attr_store;
@@ -723,7 +723,7 @@ static ssize_t module_attr_store(struct kobject *kobj,
return ret;
}
-static struct sysfs_ops module_sysfs_ops = {
+static const struct sysfs_ops module_sysfs_ops = {
.show = module_attr_show,
.store = module_attr_store,
};
@@ -737,7 +737,7 @@ static int uevent_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
-static struct kset_uevent_ops module_uevent_ops = {
+static const struct kset_uevent_ops module_uevent_ops = {
.filter = uevent_filter,
};
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index a661e799186..2f3fbf84215 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -15,6 +15,7 @@
#include <linux/smp.h>
#include <linux/file.h>
#include <linux/poll.h>
+#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/dcache.h>
#include <linux/percpu.h>
@@ -56,21 +57,6 @@ static atomic_t nr_task_events __read_mostly;
*/
int sysctl_perf_event_paranoid __read_mostly = 1;
-static inline bool perf_paranoid_tracepoint_raw(void)
-{
- return sysctl_perf_event_paranoid > -1;
-}
-
-static inline bool perf_paranoid_cpu(void)
-{
- return sysctl_perf_event_paranoid > 0;
-}
-
-static inline bool perf_paranoid_kernel(void)
-{
- return sysctl_perf_event_paranoid > 1;
-}
-
int sysctl_perf_event_mlock __read_mostly = 512; /* 'free' kb per user */
/*
@@ -96,10 +82,6 @@ extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event)
void __weak hw_perf_disable(void) { barrier(); }
void __weak hw_perf_enable(void) { barrier(); }
-void __weak hw_perf_event_setup(int cpu) { barrier(); }
-void __weak hw_perf_event_setup_online(int cpu) { barrier(); }
-void __weak hw_perf_event_setup_offline(int cpu) { barrier(); }
-
int __weak
hw_perf_group_sched_in(struct perf_event *group_leader,
struct perf_cpu_context *cpuctx,
@@ -112,25 +94,15 @@ void __weak perf_event_print_debug(void) { }
static DEFINE_PER_CPU(int, perf_disable_count);
-void __perf_disable(void)
-{
- __get_cpu_var(perf_disable_count)++;
-}
-
-bool __perf_enable(void)
-{
- return !--__get_cpu_var(perf_disable_count);
-}
-
void perf_disable(void)
{
- __perf_disable();
- hw_perf_disable();
+ if (!__get_cpu_var(perf_disable_count)++)
+ hw_perf_disable();
}
void perf_enable(void)
{
- if (__perf_enable())
+ if (!--__get_cpu_var(perf_disable_count))
hw_perf_enable();
}
@@ -1193,11 +1165,9 @@ void perf_event_task_sched_out(struct task_struct *task,
struct perf_event_context *ctx = task->perf_event_ctxp;
struct perf_event_context *next_ctx;
struct perf_event_context *parent;
- struct pt_regs *regs;
int do_switch = 1;
- regs = task_pt_regs(task);
- perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, regs, 0);
+ perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
if (likely(!ctx || !cpuctx->task_ctx))
return;
@@ -1553,12 +1523,15 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
*/
if (interrupts == MAX_INTERRUPTS) {
perf_log_throttle(event, 1);
+ perf_disable();
event->pmu->unthrottle(event);
+ perf_enable();
}
if (!event->attr.freq || !event->attr.sample_freq)
continue;
+ perf_disable();
event->pmu->read(event);
now = atomic64_read(&event->count);
delta = now - hwc->freq_count_stamp;
@@ -1566,6 +1539,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
if (delta > 0)
perf_adjust_period(event, TICK_NSEC, delta);
+ perf_enable();
}
raw_spin_unlock(&ctx->lock);
}
@@ -1575,9 +1549,6 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
*/
static void rotate_ctx(struct perf_event_context *ctx)
{
- if (!ctx->nr_events)
- return;
-
raw_spin_lock(&ctx->lock);
/* Rotate the first entry last of non-pinned groups */
@@ -1590,19 +1561,28 @@ void perf_event_task_tick(struct task_struct *curr)
{
struct perf_cpu_context *cpuctx;
struct perf_event_context *ctx;
+ int rotate = 0;
if (!atomic_read(&nr_events))
return;
cpuctx = &__get_cpu_var(perf_cpu_context);
- ctx = curr->perf_event_ctxp;
+ if (cpuctx->ctx.nr_events &&
+ cpuctx->ctx.nr_events != cpuctx->ctx.nr_active)
+ rotate = 1;
- perf_disable();
+ ctx = curr->perf_event_ctxp;
+ if (ctx && ctx->nr_events && ctx->nr_events != ctx->nr_active)
+ rotate = 1;
perf_ctx_adjust_freq(&cpuctx->ctx);
if (ctx)
perf_ctx_adjust_freq(ctx);
+ if (!rotate)
+ return;
+
+ perf_disable();
cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE);
if (ctx)
task_ctx_sched_out(ctx, EVENT_FLEXIBLE);
@@ -1614,7 +1594,6 @@ void perf_event_task_tick(struct task_struct *curr)
cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE);
if (ctx)
task_ctx_sched_in(curr, EVENT_FLEXIBLE);
-
perf_enable();
}
@@ -2610,7 +2589,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
if (user_locked > user_lock_limit)
extra = user_locked - user_lock_limit;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlimit(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
locked = vma->vm_mm->locked_vm + extra;
@@ -2806,6 +2785,12 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
return NULL;
}
+__weak
+void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
+{
+}
+
+
/*
* Output
*/
@@ -3391,15 +3376,23 @@ static void perf_event_task_output(struct perf_event *event,
struct perf_task_event *task_event)
{
struct perf_output_handle handle;
- int size;
struct task_struct *task = task_event->task;
- int ret;
+ unsigned long flags;
+ int size, ret;
+
+ /*
+ * If this CPU attempts to acquire an rq lock held by a CPU spinning
+ * in perf_output_lock() from interrupt context, it's game over.
+ */
+ local_irq_save(flags);
size = task_event->event_id.header.size;
ret = perf_output_begin(&handle, event, size, 0, 0);
- if (ret)
+ if (ret) {
+ local_irq_restore(flags);
return;
+ }
task_event->event_id.pid = perf_event_pid(event, task);
task_event->event_id.ppid = perf_event_pid(event, current);
@@ -3410,6 +3403,7 @@ static void perf_event_task_output(struct perf_event *event,
perf_output_put(&handle, task_event->event_id);
perf_output_end(&handle);
+ local_irq_restore(flags);
}
static int perf_event_task_match(struct perf_event *event)
@@ -4123,8 +4117,7 @@ void __perf_sw_event(u32 event_id, u64 nr, int nmi,
if (rctx < 0)
return;
- data.addr = addr;
- data.raw = NULL;
+ perf_sample_data_init(&data, addr);
do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi, &data, regs);
@@ -4169,11 +4162,10 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
struct perf_event *event;
u64 period;
- event = container_of(hrtimer, struct perf_event, hw.hrtimer);
+ event = container_of(hrtimer, struct perf_event, hw.hrtimer);
event->pmu->read(event);
- data.addr = 0;
- data.raw = NULL;
+ perf_sample_data_init(&data, 0);
data.period = event->hw.last_period;
regs = get_irq_regs();
/*
@@ -4335,26 +4327,20 @@ static const struct pmu perf_ops_task_clock = {
#ifdef CONFIG_EVENT_TRACING
void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
- int entry_size)
+ int entry_size, struct pt_regs *regs)
{
+ struct perf_sample_data data;
struct perf_raw_record raw = {
.size = entry_size,
.data = record,
};
- struct perf_sample_data data = {
- .addr = addr,
- .raw = &raw,
- };
-
- struct pt_regs *regs = get_irq_regs();
-
- if (!regs)
- regs = task_pt_regs(current);
+ perf_sample_data_init(&data, addr);
+ data.raw = &raw;
/* Trace events already protected against recursion */
do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1,
- &data, regs);
+ &data, regs);
}
EXPORT_SYMBOL_GPL(perf_tp_event);
@@ -4370,7 +4356,7 @@ static int perf_tp_event_match(struct perf_event *event,
static void tp_perf_event_destroy(struct perf_event *event)
{
- ftrace_profile_disable(event->attr.config);
+ perf_trace_disable(event->attr.config);
}
static const struct pmu *tp_perf_event_init(struct perf_event *event)
@@ -4384,7 +4370,7 @@ static const struct pmu *tp_perf_event_init(struct perf_event *event)
!capable(CAP_SYS_ADMIN))
return ERR_PTR(-EPERM);
- if (ftrace_profile_enable(event->attr.config))
+ if (perf_trace_enable(event->attr.config))
return NULL;
event->destroy = tp_perf_event_destroy;
@@ -4463,8 +4449,7 @@ void perf_bp_event(struct perf_event *bp, void *data)
struct perf_sample_data sample;
struct pt_regs *regs = data;
- sample.raw = NULL;
- sample.addr = bp->attr.bp_addr;
+ perf_sample_data_init(&sample, bp->attr.bp_addr);
if (!perf_exclude_event(bp, regs))
perf_swevent_add(bp, 1, 1, &sample, regs);
@@ -5392,18 +5377,26 @@ int perf_event_init_task(struct task_struct *child)
return ret;
}
+static void __init perf_event_init_all_cpus(void)
+{
+ int cpu;
+ struct perf_cpu_context *cpuctx;
+
+ for_each_possible_cpu(cpu) {
+ cpuctx = &per_cpu(perf_cpu_context, cpu);
+ __perf_event_init_context(&cpuctx->ctx, NULL);
+ }
+}
+
static void __cpuinit perf_event_init_cpu(int cpu)
{
struct perf_cpu_context *cpuctx;
cpuctx = &per_cpu(perf_cpu_context, cpu);
- __perf_event_init_context(&cpuctx->ctx, NULL);
spin_lock(&perf_resource_lock);
cpuctx->max_pertask = perf_max_events - perf_reserved_percpu;
spin_unlock(&perf_resource_lock);
-
- hw_perf_event_setup(cpu);
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -5443,20 +5436,11 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
perf_event_init_cpu(cpu);
break;
- case CPU_ONLINE:
- case CPU_ONLINE_FROZEN:
- hw_perf_event_setup_online(cpu);
- break;
-
case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN:
perf_event_exit_cpu(cpu);
break;
- case CPU_DEAD:
- hw_perf_event_setup_offline(cpu);
- break;
-
default:
break;
}
@@ -5474,6 +5458,7 @@ static struct notifier_block __cpuinitdata perf_cpu_nb = {
void __init perf_event_init(void)
{
+ perf_event_init_all_cpus();
perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
(void *)(long)smp_processor_id());
perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,
@@ -5481,13 +5466,16 @@ void __init perf_event_init(void)
register_cpu_notifier(&perf_cpu_nb);
}
-static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, char *buf)
+static ssize_t perf_show_reserve_percpu(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%d\n", perf_reserved_percpu);
}
static ssize_t
perf_set_reserve_percpu(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
const char *buf,
size_t count)
{
@@ -5516,13 +5504,17 @@ perf_set_reserve_percpu(struct sysdev_class *class,
return count;
}
-static ssize_t perf_show_overcommit(struct sysdev_class *class, char *buf)
+static ssize_t perf_show_overcommit(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%d\n", perf_overcommit);
}
static ssize_t
-perf_set_overcommit(struct sysdev_class *class, const char *buf, size_t count)
+perf_set_overcommit(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ const char *buf, size_t count)
{
unsigned long val;
int err;
diff --git a/kernel/pid.c b/kernel/pid.c
index b08e697cd83..aebb30d9c23 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -367,7 +367,9 @@ struct task_struct *pid_task(struct pid *pid, enum pid_type type)
struct task_struct *result = NULL;
if (pid) {
struct hlist_node *first;
- first = rcu_dereference_check(pid->tasks[type].first, rcu_read_lock_held() || lockdep_is_held(&tasklist_lock));
+ first = rcu_dereference_check(pid->tasks[type].first,
+ rcu_read_lock_held() ||
+ lockdep_tasklist_lock_is_held());
if (first)
result = hlist_entry(first, struct task_struct, pids[(type)].node);
}
@@ -376,7 +378,7 @@ struct task_struct *pid_task(struct pid *pid, enum pid_type type)
EXPORT_SYMBOL(pid_task);
/*
- * Must be called under rcu_read_lock() or with tasklist_lock read-held.
+ * Must be called under rcu_read_lock().
*/
struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
{
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index 86b3796b043..a5aff94e1f0 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -13,6 +13,7 @@
#include <linux/syscalls.h>
#include <linux/err.h>
#include <linux/acct.h>
+#include <linux/slab.h>
#define BITS_PER_PAGE (PAGE_SIZE*8)
@@ -161,13 +162,12 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
rcu_read_lock();
/*
- * Use force_sig() since it clears SIGNAL_UNKILLABLE ensuring
- * any nested-container's init processes don't ignore the
- * signal
+ * Any nested-container's init processes won't ignore the
+ * SEND_SIG_NOINFO signal, see send_signal()->si_fromuser().
*/
task = pid_task(find_vpid(nr), PIDTYPE_PID);
if (task)
- force_sig(SIGKILL, task);
+ send_sig_info(SIGKILL, SEND_SIG_NOINFO, task);
rcu_read_unlock();
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 438ff452351..bc7704b3a44 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -982,6 +982,7 @@ static void check_thread_timers(struct task_struct *tsk,
int maxfire;
struct list_head *timers = tsk->cpu_timers;
struct signal_struct *const sig = tsk->signal;
+ unsigned long soft;
maxfire = 20;
tsk->cputime_expires.prof_exp = cputime_zero;
@@ -1030,9 +1031,10 @@ static void check_thread_timers(struct task_struct *tsk,
/*
* Check for the special case thread timers.
*/
- if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) {
- unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max;
- unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur;
+ soft = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur);
+ if (soft != RLIM_INFINITY) {
+ unsigned long hard =
+ ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max);
if (hard != RLIM_INFINITY &&
tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
@@ -1043,14 +1045,13 @@ static void check_thread_timers(struct task_struct *tsk,
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
- if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) {
+ if (tsk->rt.timeout > DIV_ROUND_UP(soft, USEC_PER_SEC/HZ)) {
/*
* At the soft limit, send a SIGXCPU every second.
*/
- if (sig->rlim[RLIMIT_RTTIME].rlim_cur
- < sig->rlim[RLIMIT_RTTIME].rlim_max) {
- sig->rlim[RLIMIT_RTTIME].rlim_cur +=
- USEC_PER_SEC;
+ if (soft < hard) {
+ soft += USEC_PER_SEC;
+ sig->rlim[RLIMIT_RTTIME].rlim_cur = soft;
}
printk(KERN_INFO
"RT Watchdog Timeout: %s[%d]\n",
@@ -1060,9 +1061,9 @@ static void check_thread_timers(struct task_struct *tsk,
}
}
-static void stop_process_timers(struct task_struct *tsk)
+static void stop_process_timers(struct signal_struct *sig)
{
- struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
+ struct thread_group_cputimer *cputimer = &sig->cputimer;
unsigned long flags;
if (!cputimer->running)
@@ -1071,6 +1072,10 @@ static void stop_process_timers(struct task_struct *tsk)
spin_lock_irqsave(&cputimer->lock, flags);
cputimer->running = 0;
spin_unlock_irqrestore(&cputimer->lock, flags);
+
+ sig->cputime_expires.prof_exp = cputime_zero;
+ sig->cputime_expires.virt_exp = cputime_zero;
+ sig->cputime_expires.sched_exp = 0;
}
static u32 onecputick;
@@ -1121,6 +1126,7 @@ static void check_process_timers(struct task_struct *tsk,
unsigned long long sum_sched_runtime, sched_expires;
struct list_head *timers = sig->cpu_timers;
struct task_cputime cputime;
+ unsigned long soft;
/*
* Don't sample the current process CPU clocks if there are no timers.
@@ -1131,7 +1137,7 @@ static void check_process_timers(struct task_struct *tsk,
list_empty(&timers[CPUCLOCK_VIRT]) &&
cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) &&
list_empty(&timers[CPUCLOCK_SCHED])) {
- stop_process_timers(tsk);
+ stop_process_timers(sig);
return;
}
@@ -1193,11 +1199,13 @@ static void check_process_timers(struct task_struct *tsk,
SIGPROF);
check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime,
SIGVTALRM);
-
- if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
+ soft = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
+ if (soft != RLIM_INFINITY) {
unsigned long psecs = cputime_to_secs(ptime);
+ unsigned long hard =
+ ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max);
cputime_t x;
- if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) {
+ if (psecs >= hard) {
/*
* At the hard limit, we just die.
* No need to calculate anything else now.
@@ -1205,17 +1213,17 @@ static void check_process_timers(struct task_struct *tsk,
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
- if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
+ if (psecs >= soft) {
/*
* At the soft limit, send a SIGXCPU every second.
*/
__group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
- if (sig->rlim[RLIMIT_CPU].rlim_cur
- < sig->rlim[RLIMIT_CPU].rlim_max) {
- sig->rlim[RLIMIT_CPU].rlim_cur++;
+ if (soft < hard) {
+ soft++;
+ sig->rlim[RLIMIT_CPU].rlim_cur = soft;
}
}
- x = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
+ x = secs_to_cputime(soft);
if (cputime_eq(prof_expires, cputime_zero) ||
cputime_lt(x, prof_expires)) {
prof_expires = x;
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index bbfe472d752..aa9e916da4d 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -22,6 +22,7 @@
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/freezer.h>
+#include <linux/gfp.h>
#include <scsi/scsi_scan.h>
#include <asm/suspend.h>
@@ -323,6 +324,7 @@ static int create_image(int platform_mode)
int hibernation_snapshot(int platform_mode)
{
int error;
+ gfp_t saved_mask;
error = platform_begin(platform_mode);
if (error)
@@ -334,6 +336,7 @@ int hibernation_snapshot(int platform_mode)
goto Close;
suspend_console();
+ saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
error = dpm_suspend_start(PMSG_FREEZE);
if (error)
goto Recover_platform;
@@ -351,6 +354,7 @@ int hibernation_snapshot(int platform_mode)
dpm_resume_end(in_suspend ?
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
+ set_gfp_allowed_mask(saved_mask);
resume_console();
Close:
platform_end(platform_mode);
@@ -445,14 +449,17 @@ static int resume_target_kernel(bool platform_mode)
int hibernation_restore(int platform_mode)
{
int error;
+ gfp_t saved_mask;
pm_prepare_console();
suspend_console();
+ saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
error = dpm_suspend_start(PMSG_QUIESCE);
if (!error) {
error = resume_target_kernel(platform_mode);
dpm_resume_end(PMSG_RECOVER);
}
+ set_gfp_allowed_mask(saved_mask);
resume_console();
pm_restore_console();
return error;
@@ -466,6 +473,7 @@ int hibernation_restore(int platform_mode)
int hibernation_platform_enter(void)
{
int error;
+ gfp_t saved_mask;
if (!hibernation_ops)
return -ENOSYS;
@@ -481,6 +489,7 @@ int hibernation_platform_enter(void)
entering_platform_hibernation = true;
suspend_console();
+ saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
error = dpm_suspend_start(PMSG_HIBERNATE);
if (error) {
if (hibernation_ops->recover)
@@ -518,6 +527,7 @@ int hibernation_platform_enter(void)
Resume_devices:
entering_platform_hibernation = false;
dpm_resume_end(PMSG_RESTORE);
+ set_gfp_allowed_mask(saved_mask);
resume_console();
Close:
diff --git a/kernel/power/hibernate_nvs.c b/kernel/power/hibernate_nvs.c
index 39ac698ef83..fdcad9ed5a7 100644
--- a/kernel/power/hibernate_nvs.c
+++ b/kernel/power/hibernate_nvs.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/suspend.h>
/*
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 5ade1bdcf36..71ae29052ab 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -88,12 +88,11 @@ static int try_to_freeze_tasks(bool sig_only)
printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
"(%d tasks refusing to freeze):\n",
elapsed_csecs / 100, elapsed_csecs % 100, todo);
- show_state();
read_lock(&tasklist_lock);
do_each_thread(g, p) {
task_lock(p);
if (freezing(p) && !freezer_should_skip(p))
- printk(KERN_ERR " %s\n", p->comm);
+ sched_show_task(p);
cancel_freezing(p);
task_unlock(p);
} while_each_thread(g, p);
@@ -145,7 +144,7 @@ static void thaw_tasks(bool nosig_only)
if (nosig_only && should_send_signal(p))
continue;
- if (cgroup_frozen(p))
+ if (cgroup_freezing_or_frozen(p))
continue;
thaw_process(p);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 830cadecbdf..be861c26dda 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -26,6 +26,7 @@
#include <linux/console.h>
#include <linux/highmem.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 6f10dfc2d3e..56e7dbb8b99 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -15,6 +15,7 @@
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/syscalls.h>
+#include <linux/gfp.h>
#include "power.h"
@@ -189,6 +190,7 @@ static int suspend_enter(suspend_state_t state)
int suspend_devices_and_enter(suspend_state_t state)
{
int error;
+ gfp_t saved_mask;
if (!suspend_ops)
return -ENOSYS;
@@ -199,6 +201,7 @@ int suspend_devices_and_enter(suspend_state_t state)
goto Close;
}
suspend_console();
+ saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
suspend_test_start();
error = dpm_suspend_start(PMSG_SUSPEND);
if (error) {
@@ -215,6 +218,7 @@ int suspend_devices_and_enter(suspend_state_t state)
suspend_test_start();
dpm_resume_end(PMSG_RESUME);
suspend_test_finish("resume devices");
+ set_gfp_allowed_mask(saved_mask);
resume_console();
Close:
if (suspend_ops->end)
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 1d575733d4e..66824d71983 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -23,6 +23,7 @@
#include <linux/swap.h>
#include <linux/swapops.h>
#include <linux/pm.h>
+#include <linux/slab.h>
#include "power.h"
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 4d2289626a8..a8c96212bc1 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -420,7 +420,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
* User space encodes device types as two-byte values,
* so we need to recode them
*/
- swdev = old_decode_dev(swap_area.dev);
+ swdev = new_decode_dev(swap_area.dev);
if (swdev) {
offset = swap_area.offset;
data->swap = swap_type_of(swdev, offset, NULL);
diff --git a/kernel/printk.c b/kernel/printk.c
index 40674122ecf..75077ad0b53 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -70,8 +70,6 @@ int console_printk[4] = {
DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */
};
-static int saved_console_loglevel = -1;
-
/*
* Low level drivers may need that to know if they can schedule in
* their unblank() callback or not. So let's export it.
@@ -146,6 +144,7 @@ static char __log_buf[__LOG_BUF_LEN];
static char *log_buf = __log_buf;
static int log_buf_len = __LOG_BUF_LEN;
static unsigned logged_chars; /* Number of chars produced since last read+clear operation */
+static int saved_console_loglevel = -1;
#ifdef CONFIG_KEXEC
/*
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index f1125c1a632..03a7ea1579f 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -45,6 +45,7 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/kernel_stat.h>
+#include <linux/hardirq.h>
#ifdef CONFIG_DEBUG_LOCK_ALLOC
static struct lock_class_key rcu_lock_key;
@@ -66,6 +67,35 @@ EXPORT_SYMBOL_GPL(rcu_sched_lock_map);
int rcu_scheduler_active __read_mostly;
EXPORT_SYMBOL_GPL(rcu_scheduler_active);
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+int debug_lockdep_rcu_enabled(void)
+{
+ return rcu_scheduler_active && debug_locks &&
+ current->lockdep_recursion == 0;
+}
+EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled);
+
+/**
+ * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section?
+ *
+ * Check for bottom half being disabled, which covers both the
+ * CONFIG_PROVE_RCU and not cases. Note that if someone uses
+ * rcu_read_lock_bh(), but then later enables BH, lockdep (if enabled)
+ * will show the situation.
+ *
+ * Check debug_lockdep_rcu_enabled() to prevent false positives during boot.
+ */
+int rcu_read_lock_bh_held(void)
+{
+ if (!debug_lockdep_rcu_enabled())
+ return 1;
+ return in_softirq();
+}
+EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
+
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
/*
* This function is invoked towards the end of the scheduler's initialization
* process. Before this is called, the idle task might contain
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index 1439eb504c2..4a525a30e08 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -246,12 +246,21 @@ struct rcu_data {
#define RCU_JIFFIES_TILL_FORCE_QS 3 /* for rsp->jiffies_force_qs */
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
-#define RCU_SECONDS_TILL_STALL_CHECK (10 * HZ) /* for rsp->jiffies_stall */
-#define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ) /* for rsp->jiffies_stall */
-#define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */
- /* to take at least one */
- /* scheduling clock irq */
- /* before ratting on them. */
+
+#ifdef CONFIG_PROVE_RCU
+#define RCU_STALL_DELAY_DELTA (5 * HZ)
+#else
+#define RCU_STALL_DELAY_DELTA 0
+#endif
+
+#define RCU_SECONDS_TILL_STALL_CHECK (10 * HZ + RCU_STALL_DELAY_DELTA)
+ /* for rsp->jiffies_stall */
+#define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ + RCU_STALL_DELAY_DELTA)
+ /* for rsp->jiffies_stall */
+#define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */
+ /* to take at least one */
+ /* scheduling clock irq */
+ /* before ratting on them. */
#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index 464ad2cdee0..79b53bda894 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -1010,6 +1010,10 @@ int rcu_needs_cpu(int cpu)
int c = 0;
int thatcpu;
+ /* Check for being in the holdoff period. */
+ if (per_cpu(rcu_dyntick_holdoff, cpu) == jiffies)
+ return rcu_needs_cpu_quick_check(cpu);
+
/* Don't bother unless we are the last non-dyntick-idle CPU. */
for_each_cpu_not(thatcpu, nohz_cpu_mask)
if (thatcpu != cpu) {
@@ -1041,10 +1045,8 @@ int rcu_needs_cpu(int cpu)
}
/* If RCU callbacks are still pending, RCU still needs this CPU. */
- if (c) {
+ if (c)
raise_softirq(RCU_SOFTIRQ);
- per_cpu(rcu_dyntick_holdoff, cpu) = jiffies;
- }
return c;
}
diff --git a/kernel/relay.c b/kernel/relay.c
index c705a41b4ba..3d97f282161 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -1215,14 +1215,14 @@ static void relay_page_release(struct splice_pipe_desc *spd, unsigned int i)
/*
* subbuf_splice_actor - splice up to one subbuf's worth of data
*/
-static int subbuf_splice_actor(struct file *in,
+static ssize_t subbuf_splice_actor(struct file *in,
loff_t *ppos,
struct pipe_inode_info *pipe,
size_t len,
unsigned int flags,
int *nonpad_ret)
{
- unsigned int pidx, poff, total_len, subbuf_pages, nr_pages, ret;
+ unsigned int pidx, poff, total_len, subbuf_pages, nr_pages;
struct rchan_buf *rbuf = in->private_data;
unsigned int subbuf_size = rbuf->chan->subbuf_size;
uint64_t pos = (uint64_t) *ppos;
@@ -1241,6 +1241,7 @@ static int subbuf_splice_actor(struct file *in,
.ops = &relay_pipe_buf_ops,
.spd_release = relay_page_release,
};
+ ssize_t ret;
if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
return 0;
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index bcdabf37c40..c7eaa37a768 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -10,7 +10,6 @@
#include <linux/types.h>
#include <linux/parser.h>
#include <linux/fs.h>
-#include <linux/slab.h>
#include <linux/res_counter.h>
#include <linux/uaccess.h>
#include <linux/mm.h>
diff --git a/kernel/resource.c b/kernel/resource.c
index 2d5be5d9bf5..9c358e26353 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -219,19 +219,34 @@ void release_child_resources(struct resource *r)
}
/**
- * request_resource - request and reserve an I/O or memory resource
+ * request_resource_conflict - request and reserve an I/O or memory resource
* @root: root resource descriptor
* @new: resource descriptor desired by caller
*
- * Returns 0 for success, negative error code on error.
+ * Returns 0 for success, conflict resource on error.
*/
-int request_resource(struct resource *root, struct resource *new)
+struct resource *request_resource_conflict(struct resource *root, struct resource *new)
{
struct resource *conflict;
write_lock(&resource_lock);
conflict = __request_resource(root, new);
write_unlock(&resource_lock);
+ return conflict;
+}
+
+/**
+ * request_resource - request and reserve an I/O or memory resource
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ *
+ * Returns 0 for success, negative error code on error.
+ */
+int request_resource(struct resource *root, struct resource *new)
+{
+ struct resource *conflict;
+
+ conflict = request_resource_conflict(root, new);
return conflict ? -EBUSY : 0;
}
@@ -474,25 +489,40 @@ static struct resource * __insert_resource(struct resource *parent, struct resou
}
/**
- * insert_resource - Inserts a resource in the resource tree
+ * insert_resource_conflict - Inserts resource in the resource tree
* @parent: parent of the new resource
* @new: new resource to insert
*
- * Returns 0 on success, -EBUSY if the resource can't be inserted.
+ * Returns 0 on success, conflict resource if the resource can't be inserted.
*
- * This function is equivalent to request_resource when no conflict
+ * This function is equivalent to request_resource_conflict when no conflict
* happens. If a conflict happens, and the conflicting resources
* entirely fit within the range of the new resource, then the new
* resource is inserted and the conflicting resources become children of
* the new resource.
*/
-int insert_resource(struct resource *parent, struct resource *new)
+struct resource *insert_resource_conflict(struct resource *parent, struct resource *new)
{
struct resource *conflict;
write_lock(&resource_lock);
conflict = __insert_resource(parent, new);
write_unlock(&resource_lock);
+ return conflict;
+}
+
+/**
+ * insert_resource - Inserts a resource in the resource tree
+ * @parent: parent of the new resource
+ * @new: new resource to insert
+ *
+ * Returns 0 on success, -EBUSY if the resource can't be inserted.
+ */
+int insert_resource(struct resource *parent, struct resource *new)
+{
+ struct resource *conflict;
+
+ conflict = insert_resource_conflict(parent, new);
return conflict ? -EBUSY : 0;
}
diff --git a/kernel/sched.c b/kernel/sched.c
index abb36b16b93..6af210a7de7 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -71,6 +71,7 @@
#include <linux/debugfs.h>
#include <linux/ctype.h>
#include <linux/ftrace.h>
+#include <linux/slab.h>
#include <asm/tlb.h>
#include <asm/irq_regs.h>
@@ -2359,7 +2360,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
{
int cpu, orig_cpu, this_cpu, success = 0;
unsigned long flags;
- struct rq *rq, *orig_rq;
+ struct rq *rq;
if (!sched_feat(SYNC_WAKEUPS))
wake_flags &= ~WF_SYNC;
@@ -2367,7 +2368,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
this_cpu = get_cpu();
smp_wmb();
- rq = orig_rq = task_rq_lock(p, &flags);
+ rq = task_rq_lock(p, &flags);
update_rq_clock(rq);
if (!(p->state & state))
goto out;
@@ -2650,7 +2651,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
{
unsigned long flags;
struct rq *rq;
- int cpu = get_cpu();
+ int cpu __maybe_unused = get_cpu();
#ifdef CONFIG_SMP
/*
@@ -4353,7 +4354,7 @@ int can_nice(const struct task_struct *p, const int nice)
/* convert nice value [19,-20] to rlimit style value [1,40] */
int nice_rlim = 20 - nice;
- return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur ||
+ return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
capable(CAP_SYS_NICE));
}
@@ -4530,7 +4531,7 @@ recheck:
if (!lock_task_sighand(p, &flags))
return -ESRCH;
- rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur;
+ rlim_rtprio = task_rlimit(p, RLIMIT_RTPRIO);
unlock_task_sighand(p, &flags);
/* can't set/change the rt policy */
@@ -4902,7 +4903,9 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
int ret;
cpumask_var_t mask;
- if (len < cpumask_size())
+ if ((len * BITS_PER_BYTE) < nr_cpu_ids)
+ return -EINVAL;
+ if (len & (sizeof(unsigned long)-1))
return -EINVAL;
if (!alloc_cpumask_var(&mask, GFP_KERNEL))
@@ -4910,10 +4913,12 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
ret = sched_getaffinity(pid, mask);
if (ret == 0) {
- if (copy_to_user(user_mask_ptr, mask, cpumask_size()))
+ size_t retlen = min_t(size_t, len, cpumask_size());
+
+ if (copy_to_user(user_mask_ptr, mask, retlen))
ret = -EFAULT;
else
- ret = cpumask_size();
+ ret = retlen;
}
free_cpumask_var(mask);
@@ -5383,7 +5388,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
get_task_struct(mt);
task_rq_unlock(rq, &flags);
- wake_up_process(rq->migration_thread);
+ wake_up_process(mt);
put_task_struct(mt);
wait_for_completion(&req.done);
tlb_migrate_finish(p->mm);
@@ -7406,11 +7411,13 @@ static ssize_t sched_power_savings_store(const char *buf, size_t count, int smt)
#ifdef CONFIG_SCHED_MC
static ssize_t sched_mc_power_savings_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
char *page)
{
return sprintf(page, "%u\n", sched_mc_power_savings);
}
static ssize_t sched_mc_power_savings_store(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
const char *buf, size_t count)
{
return sched_power_savings_store(buf, count, 0);
@@ -7422,11 +7429,13 @@ static SYSDEV_CLASS_ATTR(sched_mc_power_savings, 0644,
#ifdef CONFIG_SCHED_SMT
static ssize_t sched_smt_power_savings_show(struct sysdev_class *dev,
+ struct sysdev_class_attribute *attr,
char *page)
{
return sprintf(page, "%u\n", sched_smt_power_savings);
}
static ssize_t sched_smt_power_savings_store(struct sysdev_class *dev,
+ struct sysdev_class_attribute *attr,
const char *buf, size_t count)
{
return sched_power_savings_store(buf, count, 1);
diff --git a/kernel/sched_cpupri.c b/kernel/sched_cpupri.c
index eeb3506c483..e6871cb3fc8 100644
--- a/kernel/sched_cpupri.c
+++ b/kernel/sched_cpupri.c
@@ -27,6 +27,7 @@
* of the License.
*/
+#include <linux/gfp.h>
#include "sched_cpupri.h"
/* Convert between a 140 based task->prio, and our 102 based cpupri */
@@ -47,7 +48,7 @@ static int convert_prio(int prio)
}
#define for_each_cpupri_active(array, idx) \
- for_each_bit(idx, array, CPUPRI_NR_PRIORITIES)
+ for_each_set_bit(idx, array, CPUPRI_NR_PRIORITIES)
/**
* cpupri_find - find the best (lowest-pri) CPU in the system
@@ -56,7 +57,7 @@ static int convert_prio(int prio)
* @lowest_mask: A mask to fill in with selected CPUs (or NULL)
*
* Note: This function returns the recommended CPUs as calculated during the
- * current invokation. By the time the call returns, the CPUs may have in
+ * current invocation. By the time the call returns, the CPUs may have in
* fact changed priorities any number of times. While not ideal, it is not
* an issue of correctness since the normal rebalancer logic will correct
* any discrepancies created by racing against the uncertainty of the current
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 67f95aada4b..9b49db14403 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -518,8 +518,4 @@ void proc_sched_set_task(struct task_struct *p)
p->se.nr_wakeups_idle = 0;
p->sched_info.bkl_count = 0;
#endif
- p->se.sum_exec_runtime = 0;
- p->se.prev_sum_exec_runtime = 0;
- p->nvcsw = 0;
- p->nivcsw = 0;
}
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 3e1fd96c6cf..5a5ea2cd924 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -3476,7 +3476,7 @@ static void run_rebalance_domains(struct softirq_action *h)
static inline int on_null_domain(int cpu)
{
- return !rcu_dereference(cpu_rq(cpu)->sd);
+ return !rcu_dereference_sched(cpu_rq(cpu)->sd);
}
/*
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index bf3e38fdbe6..b5b920ae2ea 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -1146,7 +1146,12 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu)
if (next && next->prio < idx)
continue;
list_for_each_entry(rt_se, array->queue + idx, run_list) {
- struct task_struct *p = rt_task_of(rt_se);
+ struct task_struct *p;
+
+ if (!rt_entity_is_task(rt_se))
+ continue;
+
+ p = rt_task_of(rt_se);
if (pick_rt_task(rq, p, cpu)) {
next = p;
break;
@@ -1662,8 +1667,9 @@ static void watchdog(struct rq *rq, struct task_struct *p)
if (!p->signal)
return;
- soft = p->signal->rlim[RLIMIT_RTTIME].rlim_cur;
- hard = p->signal->rlim[RLIMIT_RTTIME].rlim_max;
+ /* max may change after cur was read, this will be fixed next tick */
+ soft = task_rlimit(p, RLIMIT_RTTIME);
+ hard = task_rlimit_max(p, RLIMIT_RTTIME);
if (soft != RLIM_INFINITY) {
unsigned long next;
diff --git a/kernel/signal.c b/kernel/signal.c
index 5bb9baffa4f..dbd7fe073c5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -245,7 +245,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
if (override_rlimit ||
atomic_read(&user->sigpending) <=
- t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) {
+ task_rlimit(t, RLIMIT_SIGPENDING)) {
q = kmem_cache_alloc(sigqueue_cachep, flags);
} else {
print_dropped_signal(sig);
diff --git a/kernel/slow-work.c b/kernel/slow-work.c
index 7494bbf5a27..7d3f4fa9ef4 100644
--- a/kernel/slow-work.c
+++ b/kernel/slow-work.c
@@ -637,7 +637,7 @@ int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
goto cancelled;
/* the timer holds a reference whilst it is pending */
- ret = work->ops->get_ref(work);
+ ret = slow_work_get_ref(work);
if (ret < 0)
goto cant_get_ref;
diff --git a/kernel/slow-work.h b/kernel/slow-work.h
index 321f3c59d73..a29ebd1ef41 100644
--- a/kernel/slow-work.h
+++ b/kernel/slow-work.h
@@ -43,28 +43,28 @@ extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *);
*/
static inline void slow_work_set_thread_pid(int id, pid_t pid)
{
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
slow_work_pids[id] = pid;
#endif
}
static inline void slow_work_mark_time(struct slow_work *work)
{
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
work->mark = CURRENT_TIME;
#endif
}
static inline void slow_work_begin_exec(int id, struct slow_work *work)
{
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
slow_work_execs[id] = work;
#endif
}
static inline void slow_work_end_exec(int id, struct slow_work *work)
{
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
write_lock(&slow_work_execs_lock);
slow_work_execs[id] = NULL;
write_unlock(&slow_work_execs_lock);
diff --git a/kernel/smp.c b/kernel/smp.c
index 9867b6bfefc..3fc69733618 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/percpu.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/smp.h>
#include <linux/cpu.h>
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 0d4c7898ab8..4b493f67dcb 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -155,11 +155,11 @@ void softlockup_tick(void)
* Wake up the high-prio watchdog task twice per
* threshold timespan.
*/
- if (now > touch_ts + softlockup_thresh/2)
+ if (time_after(now - softlockup_thresh/2, touch_ts))
wake_up_process(per_cpu(softlockup_watchdog, this_cpu));
/* Warn about unreasonable delays: */
- if (now <= (touch_ts + softlockup_thresh))
+ if (time_before_eq(now - softlockup_thresh, touch_ts))
return;
per_cpu(softlockup_print_ts, this_cpu) = touch_ts;
diff --git a/kernel/srcu.c b/kernel/srcu.c
index bde4295774c..2980da3fd50 100644
--- a/kernel/srcu.c
+++ b/kernel/srcu.c
@@ -30,7 +30,6 @@
#include <linux/preempt.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/srcu.h>
diff --git a/kernel/sys.c b/kernel/sys.c
index 877fe4f8e05..7cb426a5896 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -33,8 +33,10 @@
#include <linux/task_io_accounting_ops.h>
#include <linux/seccomp.h>
#include <linux/cpu.h>
+#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/fs_struct.h>
+#include <linux/gfp.h>
#include <linux/compat.h>
#include <linux/syscalls.h>
@@ -571,8 +573,7 @@ static int set_user(struct cred *new)
if (!new_user)
return -EAGAIN;
- if (atomic_read(&new_user->processes) >=
- current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
+ if (atomic_read(&new_user->processes) >= rlimit(RLIMIT_NPROC) &&
new_user != INIT_USER) {
free_uid(new_user);
return -EAGAIN;
@@ -1115,6 +1116,15 @@ out:
DECLARE_RWSEM(uts_sem);
+#ifdef COMPAT_UTS_MACHINE
+#define override_architecture(name) \
+ (personality(current->personality) == PER_LINUX32 && \
+ copy_to_user(name->machine, COMPAT_UTS_MACHINE, \
+ sizeof(COMPAT_UTS_MACHINE)))
+#else
+#define override_architecture(name) 0
+#endif
+
SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
{
int errno = 0;
@@ -1123,9 +1133,66 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
if (copy_to_user(name, utsname(), sizeof *name))
errno = -EFAULT;
up_read(&uts_sem);
+
+ if (!errno && override_architecture(name))
+ errno = -EFAULT;
return errno;
}
+#ifdef __ARCH_WANT_SYS_OLD_UNAME
+/*
+ * Old cruft
+ */
+SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
+{
+ int error = 0;
+
+ if (!name)
+ return -EFAULT;
+
+ down_read(&uts_sem);
+ if (copy_to_user(name, utsname(), sizeof(*name)))
+ error = -EFAULT;
+ up_read(&uts_sem);
+
+ if (!error && override_architecture(name))
+ error = -EFAULT;
+ return error;
+}
+
+SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
+{
+ int error;
+
+ if (!name)
+ return -EFAULT;
+ if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
+ return -EFAULT;
+
+ down_read(&uts_sem);
+ error = __copy_to_user(&name->sysname, &utsname()->sysname,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename, &utsname()->nodename,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release, &utsname()->release,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->release + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version, &utsname()->version,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->version + __OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine, &utsname()->machine,
+ __OLD_UTS_LEN);
+ error |= __put_user(0, name->machine + __OLD_UTS_LEN);
+ up_read(&uts_sem);
+
+ if (!error && override_architecture(name))
+ error = -EFAULT;
+ return error ? -EFAULT : 0;
+}
+#endif
+
SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
{
int errno;
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 695384f12a7..70f2ea758ff 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -126,6 +126,7 @@ cond_syscall(sys_setreuid16);
cond_syscall(sys_setuid16);
cond_syscall(sys_vm86old);
cond_syscall(sys_vm86);
+cond_syscall(sys_ipc);
cond_syscall(compat_sys_ipc);
cond_syscall(compat_sys_sysctl);
cond_syscall(sys_flock);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 33e7a38b6eb..8686b0f5fc1 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -23,6 +23,7 @@
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
+#include <linux/signal.h>
#include <linux/proc_fs.h>
#include <linux/security.h>
#include <linux/ctype.h>
@@ -50,6 +51,7 @@
#include <linux/ftrace.h>
#include <linux/slow-work.h>
#include <linux/perf_event.h>
+#include <linux/kprobes.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
@@ -59,13 +61,23 @@
#include <asm/stacktrace.h>
#include <asm/io.h>
#endif
+#ifdef CONFIG_BSD_PROCESS_ACCT
+#include <linux/acct.h>
+#endif
+#ifdef CONFIG_RT_MUTEXES
+#include <linux/rtmutex.h>
+#endif
+#if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
+#include <linux/lockdep.h>
+#endif
+#ifdef CONFIG_CHR_DEV_SG
+#include <scsi/sg.h>
+#endif
#if defined(CONFIG_SYSCTL)
/* External variables not in a header file. */
-extern int C_A_D;
-extern int print_fatal_signals;
extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
extern int sysctl_panic_on_oom;
@@ -87,9 +99,6 @@ extern int sysctl_nr_open_min, sysctl_nr_open_max;
#ifndef CONFIG_MMU
extern int sysctl_nr_trim_pages;
#endif
-#ifdef CONFIG_RCU_TORTURE_TEST
-extern int rcutorture_runnable;
-#endif /* #ifdef CONFIG_RCU_TORTURE_TEST */
#ifdef CONFIG_BLOCK
extern int blk_iopoll_enabled;
#endif
@@ -119,14 +128,6 @@ static int min_percpu_pagelist_fract = 8;
static int ngroups_max = NGROUPS_MAX;
-#ifdef CONFIG_MODULES
-extern char modprobe_path[];
-extern int modules_disabled;
-#endif
-#ifdef CONFIG_CHR_DEV_SG
-extern int sg_big_buff;
-#endif
-
#ifdef CONFIG_SPARC
#include <asm/system.h>
#endif
@@ -148,10 +149,6 @@ extern int sysctl_userprocess_debug;
extern int spin_retry;
#endif
-#ifdef CONFIG_BSD_PROCESS_ACCT
-extern int acct_parm[];
-#endif
-
#ifdef CONFIG_IA64
extern int no_unaligned_warning;
extern int unaligned_dump_stack;
@@ -159,10 +156,6 @@ extern int unaligned_dump_stack;
extern struct ratelimit_state printk_ratelimit_state;
-#ifdef CONFIG_RT_MUTEXES
-extern int max_lock_depth;
-#endif
-
#ifdef CONFIG_PROC_SYSCTL
static int proc_do_cad_pid(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
@@ -201,9 +194,6 @@ extern struct ctl_table epoll_table[];
int sysctl_legacy_va_layout;
#endif
-extern int prove_locking;
-extern int lock_stat;
-
/* The default sysctl tables: */
static struct ctl_table root_table[] = {
@@ -1450,6 +1440,17 @@ static struct ctl_table debug_table[] = {
.proc_handler = proc_dointvec
},
#endif
+#if defined(CONFIG_OPTPROBES)
+ {
+ .procname = "kprobes-optimization",
+ .data = &sysctl_kprobes_optimization,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_kprobes_optimization_handler,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
+#endif
{ }
};
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
index 8cd50d8f9bd..59030570f5c 100644
--- a/kernel/sysctl_binary.c
+++ b/kernel/sysctl_binary.c
@@ -13,6 +13,7 @@
#include <linux/file.h>
#include <linux/ctype.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#ifdef CONFIG_SYSCTL_SYSCALL
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 899ca51be5e..11281d5792b 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -22,6 +22,7 @@
#include <linux/delayacct.h>
#include <linux/cpumask.h>
#include <linux/percpu.h>
+#include <linux/slab.h>
#include <linux/cgroupstats.h>
#include <linux/cgroup.h>
#include <linux/fs.h>
diff --git a/kernel/time.c b/kernel/time.c
index 804798005d1..656dccfe1cb 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -35,7 +35,6 @@
#include <linux/syscalls.h>
#include <linux/security.h>
#include <linux/fs.h>
-#include <linux/slab.h>
#include <linux/math64.h>
#include <linux/ptrace.h>
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 1f663d23e85..1f5dde63745 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -592,6 +592,10 @@ static inline void clocksource_select(void) { }
*/
static int __init clocksource_done_booting(void)
{
+ mutex_lock(&clocksource_mutex);
+ curr_clocksource = clocksource_default_clock();
+ mutex_unlock(&clocksource_mutex);
+
finished_booting = 1;
/*
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
index 0a8a213016f..aada0e52680 100644
--- a/kernel/time/tick-oneshot.c
+++ b/kernel/time/tick-oneshot.c
@@ -22,6 +22,29 @@
#include "tick-internal.h"
+/* Limit min_delta to a jiffie */
+#define MIN_DELTA_LIMIT (NSEC_PER_SEC / HZ)
+
+static int tick_increase_min_delta(struct clock_event_device *dev)
+{
+ /* Nothing to do if we already reached the limit */
+ if (dev->min_delta_ns >= MIN_DELTA_LIMIT)
+ return -ETIME;
+
+ if (dev->min_delta_ns < 5000)
+ dev->min_delta_ns = 5000;
+ else
+ dev->min_delta_ns += dev->min_delta_ns >> 1;
+
+ if (dev->min_delta_ns > MIN_DELTA_LIMIT)
+ dev->min_delta_ns = MIN_DELTA_LIMIT;
+
+ printk(KERN_WARNING "CE: %s increased min_delta_ns to %llu nsec\n",
+ dev->name ? dev->name : "?",
+ (unsigned long long) dev->min_delta_ns);
+ return 0;
+}
+
/**
* tick_program_event internal worker function
*/
@@ -37,23 +60,28 @@ int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires,
if (!ret || !force)
return ret;
+ dev->retries++;
/*
- * We tried 2 times to program the device with the given
- * min_delta_ns. If that's not working then we double it
+ * We tried 3 times to program the device with the given
+ * min_delta_ns. If that's not working then we increase it
* and emit a warning.
*/
if (++i > 2) {
/* Increase the min. delta and try again */
- if (!dev->min_delta_ns)
- dev->min_delta_ns = 5000;
- else
- dev->min_delta_ns += dev->min_delta_ns >> 1;
-
- printk(KERN_WARNING
- "CE: %s increasing min_delta_ns to %llu nsec\n",
- dev->name ? dev->name : "?",
- (unsigned long long) dev->min_delta_ns << 1);
-
+ if (tick_increase_min_delta(dev)) {
+ /*
+ * Get out of the loop if min_delta_ns
+ * hit the limit already. That's
+ * better than staying here forever.
+ *
+ * We clear next_event so we have a
+ * chance that the box survives.
+ */
+ printk(KERN_WARNING
+ "CE: Reprogramming failure. Giving up\n");
+ dev->next_event.tv64 = KTIME_MAX;
+ return -ETIME;
+ }
i = 0;
}
diff --git a/kernel/time/timecompare.c b/kernel/time/timecompare.c
index 12f5c55090b..ac38fbb176c 100644
--- a/kernel/time/timecompare.c
+++ b/kernel/time/timecompare.c
@@ -19,6 +19,7 @@
#include <linux/timecompare.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/math64.h>
/*
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 16736379a9c..39f6177fafa 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -818,7 +818,8 @@ void update_wall_time(void)
shift = min(shift, maxshift);
while (offset >= timekeeper.cycle_interval) {
offset = logarithmic_accumulation(offset, shift);
- shift--;
+ if(offset < timekeeper.cycle_interval<<shift)
+ shift--;
}
/* correct the clock when NTP error is too big */
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index bdfb8dd1050..1a4a7dd7877 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -228,6 +228,7 @@ print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
SEQ_printf(m, " event_handler: ");
print_name_offset(m, dev->event_handler);
SEQ_printf(m, "\n");
+ SEQ_printf(m, " retries: %lu\n", dev->retries);
}
static void timer_list_show_tickdevices(struct seq_file *m)
@@ -257,7 +258,7 @@ static int timer_list_show(struct seq_file *m, void *v)
u64 now = ktime_to_ns(ktime_get());
int cpu;
- SEQ_printf(m, "Timer List Version: v0.5\n");
+ SEQ_printf(m, "Timer List Version: v0.6\n");
SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES);
SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now);
diff --git a/kernel/timer.c b/kernel/timer.c
index c61a7949387..aeb6a54f277 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -39,6 +39,7 @@
#include <linux/kallsyms.h>
#include <linux/perf_event.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -880,6 +881,7 @@ int try_to_del_timer_sync(struct timer_list *timer)
if (base->running_timer == timer)
goto out;
+ timer_stats_timer_clear_start_info(timer);
ret = 0;
if (timer_pending(timer)) {
detach_timer(timer, 1);
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index d00c6fe23f5..78edc649003 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -52,7 +52,7 @@ obj-$(CONFIG_EVENT_TRACING) += trace_events.o
obj-$(CONFIG_EVENT_TRACING) += trace_export.o
obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
ifeq ($(CONFIG_PERF_EVENTS),y)
-obj-$(CONFIG_EVENT_TRACING) += trace_event_profile.o
+obj-$(CONFIG_EVENT_TRACING) += trace_event_perf.o
endif
obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 07f945a9943..b3bc91a3f51 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -21,6 +21,7 @@
#include <linux/percpu.h>
#include <linux/init.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/smp_lock.h>
#include <linux/time.h>
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 83783579378..2404b59b309 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -24,9 +24,11 @@
#include <linux/uaccess.h>
#include <linux/ftrace.h>
#include <linux/sysctl.h>
+#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/list.h>
#include <linux/hash.h>
+#include <linux/rcupdate.h>
#include <trace/events/sched.h>
@@ -84,22 +86,22 @@ ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-static int ftrace_set_func(unsigned long *array, int *idx, char *buffer);
-#endif
-
+/*
+ * Traverse the ftrace_list, invoking all entries. The reason that we
+ * can use rcu_dereference_raw() is that elements removed from this list
+ * are simply leaked, so there is no need to interact with a grace-period
+ * mechanism. The rcu_dereference_raw() calls are needed to handle
+ * concurrent insertions into the ftrace_list.
+ *
+ * Silly Alpha and silly pointer-speculation compiler optimizations!
+ */
static void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
{
- struct ftrace_ops *op = ftrace_list;
-
- /* in case someone actually ports this to alpha! */
- read_barrier_depends();
+ struct ftrace_ops *op = rcu_dereference_raw(ftrace_list); /*see above*/
while (op != &ftrace_list_end) {
- /* silly alpha */
- read_barrier_depends();
op->func(ip, parent_ip);
- op = op->next;
+ op = rcu_dereference_raw(op->next); /*see above*/
};
}
@@ -154,8 +156,7 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
* the ops->next pointer is valid before another CPU sees
* the ops pointer included into the ftrace_list.
*/
- smp_wmb();
- ftrace_list = ops;
+ rcu_assign_pointer(ftrace_list, ops);
if (ftrace_enabled) {
ftrace_func_t func;
@@ -2276,6 +2277,8 @@ __setup("ftrace_filter=", set_ftrace_filter);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
+static int ftrace_set_func(unsigned long *array, int *idx, char *buffer);
+
static int __init set_graph_function(char *str)
{
strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE);
@@ -3351,6 +3354,7 @@ void ftrace_graph_init_task(struct task_struct *t)
{
/* Make sure we do not use the parent ret_stack */
t->ret_stack = NULL;
+ t->curr_ret_stack = -1;
if (ftrace_graph_active) {
struct ftrace_ret_stack *ret_stack;
@@ -3360,7 +3364,6 @@ void ftrace_graph_init_task(struct task_struct *t)
GFP_KERNEL);
if (!ret_stack)
return;
- t->curr_ret_stack = -1;
atomic_set(&t->tracing_graph_pause, 0);
atomic_set(&t->trace_overrun, 0);
t->ftrace_timestamp = 0;
diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c
index 9f4f565b01e..a22582a0616 100644
--- a/kernel/trace/power-traces.c
+++ b/kernel/trace/power-traces.c
@@ -9,7 +9,6 @@
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/module.h>
-#include <linux/slab.h>
#define CREATE_TRACE_POINTS
#include <trace/events/power.h>
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 0287f9f52f5..41ca394feb2 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/percpu.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/hash.h>
#include <linux/list.h>
@@ -207,6 +208,14 @@ EXPORT_SYMBOL_GPL(tracing_is_on);
#define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX)
#define RB_EVNT_MIN_SIZE 8U /* two 32bit words */
+#if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+# define RB_FORCE_8BYTE_ALIGNMENT 0
+# define RB_ARCH_ALIGNMENT RB_ALIGNMENT
+#else
+# define RB_FORCE_8BYTE_ALIGNMENT 1
+# define RB_ARCH_ALIGNMENT 8U
+#endif
+
/* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */
#define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX
@@ -1201,18 +1210,19 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
for (i = 0; i < nr_pages; i++) {
if (RB_WARN_ON(cpu_buffer, list_empty(cpu_buffer->pages)))
- return;
+ goto out;
p = cpu_buffer->pages->next;
bpage = list_entry(p, struct buffer_page, list);
list_del_init(&bpage->list);
free_buffer_page(bpage);
}
if (RB_WARN_ON(cpu_buffer, list_empty(cpu_buffer->pages)))
- return;
+ goto out;
rb_reset_cpu(cpu_buffer);
rb_check_pages(cpu_buffer);
+out:
spin_unlock_irq(&cpu_buffer->reader_lock);
}
@@ -1229,7 +1239,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
for (i = 0; i < nr_pages; i++) {
if (RB_WARN_ON(cpu_buffer, list_empty(pages)))
- return;
+ goto out;
p = pages->next;
bpage = list_entry(p, struct buffer_page, list);
list_del_init(&bpage->list);
@@ -1238,6 +1248,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
rb_reset_cpu(cpu_buffer);
rb_check_pages(cpu_buffer);
+out:
spin_unlock_irq(&cpu_buffer->reader_lock);
}
@@ -1547,7 +1558,7 @@ rb_update_event(struct ring_buffer_event *event,
case 0:
length -= RB_EVNT_HDR_SIZE;
- if (length > RB_MAX_SMALL_DATA)
+ if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT)
event->array[0] = length;
else
event->type_len = DIV_ROUND_UP(length, RB_ALIGNMENT);
@@ -1722,11 +1733,11 @@ static unsigned rb_calculate_event_length(unsigned length)
if (!length)
length = 1;
- if (length > RB_MAX_SMALL_DATA)
+ if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT)
length += sizeof(event.array[0]);
length += RB_EVNT_HDR_SIZE;
- length = ALIGN(length, RB_ALIGNMENT);
+ length = ALIGN(length, RB_ARCH_ALIGNMENT);
return length;
}
@@ -2233,12 +2244,12 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
if (ring_buffer_flags != RB_BUFFERS_ON)
return NULL;
- if (atomic_read(&buffer->record_disabled))
- return NULL;
-
/* If we are tracing schedule, we don't want to recurse */
resched = ftrace_preempt_disable();
+ if (atomic_read(&buffer->record_disabled))
+ goto out_nocheck;
+
if (trace_recursive_lock())
goto out_nocheck;
@@ -2470,11 +2481,11 @@ int ring_buffer_write(struct ring_buffer *buffer,
if (ring_buffer_flags != RB_BUFFERS_ON)
return -EBUSY;
- if (atomic_read(&buffer->record_disabled))
- return -EBUSY;
-
resched = ftrace_preempt_disable();
+ if (atomic_read(&buffer->record_disabled))
+ goto out;
+
cpu = raw_smp_processor_id();
if (!cpumask_test_cpu(cpu, buffer->cpumask))
@@ -2542,7 +2553,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_disable);
* @buffer: The ring buffer to enable writes
*
* Note, multiple disables will need the same number of enables
- * to truely enable the writing (much like preempt_disable).
+ * to truly enable the writing (much like preempt_disable).
*/
void ring_buffer_record_enable(struct ring_buffer *buffer)
{
@@ -2578,7 +2589,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_disable_cpu);
* @cpu: The CPU to enable.
*
* Note, multiple disables will need the same number of enables
- * to truely enable the writing (much like preempt_disable).
+ * to truly enable the writing (much like preempt_disable).
*/
void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu)
{
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index ed01fdba4a5..44f916a0406 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -33,10 +33,10 @@
#include <linux/kdebug.h>
#include <linux/string.h>
#include <linux/rwsem.h>
+#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/gfp.h>
#include <linux/fs.h>
#include "trace.h"
@@ -374,6 +374,21 @@ static int __init set_buf_size(char *str)
}
__setup("trace_buf_size=", set_buf_size);
+static int __init set_tracing_thresh(char *str)
+{
+ unsigned long threshhold;
+ int ret;
+
+ if (!str)
+ return 0;
+ ret = strict_strtoul(str, 0, &threshhold);
+ if (ret < 0)
+ return 0;
+ tracing_thresh = threshhold * 1000;
+ return 1;
+}
+__setup("tracing_thresh=", set_tracing_thresh);
+
unsigned long nsecs_to_usecs(unsigned long nsecs)
{
return nsecs / 1000;
@@ -579,9 +594,10 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
static arch_spinlock_t ftrace_max_lock =
(arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
+unsigned long __read_mostly tracing_thresh;
+
#ifdef CONFIG_TRACER_MAX_TRACE
unsigned long __read_mostly tracing_max_latency;
-unsigned long __read_mostly tracing_thresh;
/*
* Copy the new maximum trace into the separate maximum-trace
@@ -592,7 +608,7 @@ static void
__update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
{
struct trace_array_cpu *data = tr->data[cpu];
- struct trace_array_cpu *max_data = tr->data[cpu];
+ struct trace_array_cpu *max_data;
max_tr.cpu = cpu;
max_tr.time_start = data->preempt_timestamp;
@@ -602,7 +618,7 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
max_data->critical_start = data->critical_start;
max_data->critical_end = data->critical_end;
- memcpy(data->comm, tsk->comm, TASK_COMM_LEN);
+ memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN);
max_data->pid = tsk->pid;
max_data->uid = task_uid(tsk);
max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO;
@@ -824,10 +840,10 @@ out:
mutex_unlock(&trace_types_lock);
}
-static void __tracing_reset(struct trace_array *tr, int cpu)
+static void __tracing_reset(struct ring_buffer *buffer, int cpu)
{
ftrace_disable_cpu();
- ring_buffer_reset_cpu(tr->buffer, cpu);
+ ring_buffer_reset_cpu(buffer, cpu);
ftrace_enable_cpu();
}
@@ -839,7 +855,7 @@ void tracing_reset(struct trace_array *tr, int cpu)
/* Make sure all commits have finished */
synchronize_sched();
- __tracing_reset(tr, cpu);
+ __tracing_reset(buffer, cpu);
ring_buffer_record_enable(buffer);
}
@@ -857,7 +873,7 @@ void tracing_reset_online_cpus(struct trace_array *tr)
tr->time_start = ftrace_now(tr->cpu);
for_each_online_cpu(cpu)
- __tracing_reset(tr, cpu);
+ __tracing_reset(buffer, cpu);
ring_buffer_record_enable(buffer);
}
@@ -934,6 +950,8 @@ void tracing_start(void)
goto out;
}
+ /* Prevent the buffers from switching */
+ arch_spin_lock(&ftrace_max_lock);
buffer = global_trace.buffer;
if (buffer)
@@ -943,6 +961,8 @@ void tracing_start(void)
if (buffer)
ring_buffer_record_enable(buffer);
+ arch_spin_unlock(&ftrace_max_lock);
+
ftrace_start();
out:
spin_unlock_irqrestore(&tracing_start_lock, flags);
@@ -964,6 +984,9 @@ void tracing_stop(void)
if (trace_stop_count++)
goto out;
+ /* Prevent the buffers from switching */
+ arch_spin_lock(&ftrace_max_lock);
+
buffer = global_trace.buffer;
if (buffer)
ring_buffer_record_disable(buffer);
@@ -972,6 +995,8 @@ void tracing_stop(void)
if (buffer)
ring_buffer_record_disable(buffer);
+ arch_spin_unlock(&ftrace_max_lock);
+
out:
spin_unlock_irqrestore(&tracing_start_lock, flags);
}
@@ -1259,6 +1284,13 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
if (!(trace_flags & TRACE_ITER_USERSTACKTRACE))
return;
+ /*
+ * NMIs can not handle page faults, even with fix ups.
+ * The save user stack can (and often does) fault.
+ */
+ if (unlikely(in_nmi()))
+ return;
+
event = trace_buffer_lock_reserve(buffer, TRACE_USER_STACK,
sizeof(*entry), flags, pc);
if (!event)
@@ -1703,6 +1735,7 @@ static void *s_start(struct seq_file *m, loff_t *pos)
ftrace_enable_cpu();
+ iter->leftover = 0;
for (p = iter; p && l < *pos; p = s_next(m, p, &l))
;
@@ -4248,10 +4281,10 @@ static __init int tracer_init_debugfs(void)
#ifdef CONFIG_TRACER_MAX_TRACE
trace_create_file("tracing_max_latency", 0644, d_tracer,
&tracing_max_latency, &tracing_max_lat_fops);
+#endif
trace_create_file("tracing_thresh", 0644, d_tracer,
&tracing_thresh, &tracing_max_lat_fops);
-#endif
trace_create_file("README", 0444, d_tracer,
NULL, &tracing_readme_fops);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index fd05bcaf91b..2825ef2c0b1 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -396,9 +396,10 @@ extern int process_new_ksym_entry(char *ksymname, int op, unsigned long addr);
extern unsigned long nsecs_to_usecs(unsigned long nsecs);
+extern unsigned long tracing_thresh;
+
#ifdef CONFIG_TRACER_MAX_TRACE
extern unsigned long tracing_max_latency;
-extern unsigned long tracing_thresh;
void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu);
void update_max_tr_single(struct trace_array *tr,
@@ -550,7 +551,7 @@ static inline int ftrace_trace_task(struct task_struct *task)
* struct trace_parser - servers for reading the user input separated by spaces
* @cont: set if the input is not complete - no final space char was found
* @buffer: holds the parsed user input
- * @idx: user input lenght
+ * @idx: user input length
* @size: buffer size
*/
struct trace_parser {
diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c
index 84a3a7ba072..9d589d8dcd1 100644
--- a/kernel/trace/trace_clock.c
+++ b/kernel/trace/trace_clock.c
@@ -13,6 +13,7 @@
* Tracer plugins will chose a default from these clocks.
*/
#include <linux/spinlock.h>
+#include <linux/irqflags.h>
#include <linux/hardirq.h>
#include <linux/module.h>
#include <linux/percpu.h>
@@ -83,7 +84,7 @@ u64 notrace trace_clock_global(void)
int this_cpu;
u64 now;
- raw_local_irq_save(flags);
+ local_irq_save(flags);
this_cpu = raw_smp_processor_id();
now = cpu_clock(this_cpu);
@@ -109,7 +110,7 @@ u64 notrace trace_clock_global(void)
arch_spin_unlock(&trace_clock_struct.lock);
out:
- raw_local_irq_restore(flags);
+ local_irq_restore(flags);
return now;
}
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
new file mode 100644
index 00000000000..0565bb42566
--- /dev/null
+++ b/kernel/trace/trace_event_perf.c
@@ -0,0 +1,175 @@
+/*
+ * trace event based perf event profiling/tracing
+ *
+ * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra <pzijlstr@redhat.com>
+ * Copyright (C) 2009-2010 Frederic Weisbecker <fweisbec@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include "trace.h"
+
+DEFINE_PER_CPU(struct pt_regs, perf_trace_regs);
+EXPORT_PER_CPU_SYMBOL_GPL(perf_trace_regs);
+
+EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs);
+
+static char *perf_trace_buf;
+static char *perf_trace_buf_nmi;
+
+/*
+ * Force it to be aligned to unsigned long to avoid misaligned accesses
+ * suprises
+ */
+typedef typeof(unsigned long [PERF_MAX_TRACE_SIZE / sizeof(unsigned long)])
+ perf_trace_t;
+
+/* Count the events in use (per event id, not per instance) */
+static int total_ref_count;
+
+static int perf_trace_event_enable(struct ftrace_event_call *event)
+{
+ char *buf;
+ int ret = -ENOMEM;
+
+ if (event->perf_refcount++ > 0)
+ return 0;
+
+ if (!total_ref_count) {
+ buf = (char *)alloc_percpu(perf_trace_t);
+ if (!buf)
+ goto fail_buf;
+
+ rcu_assign_pointer(perf_trace_buf, buf);
+
+ buf = (char *)alloc_percpu(perf_trace_t);
+ if (!buf)
+ goto fail_buf_nmi;
+
+ rcu_assign_pointer(perf_trace_buf_nmi, buf);
+ }
+
+ ret = event->perf_event_enable(event);
+ if (!ret) {
+ total_ref_count++;
+ return 0;
+ }
+
+fail_buf_nmi:
+ if (!total_ref_count) {
+ free_percpu(perf_trace_buf_nmi);
+ free_percpu(perf_trace_buf);
+ perf_trace_buf_nmi = NULL;
+ perf_trace_buf = NULL;
+ }
+fail_buf:
+ event->perf_refcount--;
+
+ return ret;
+}
+
+int perf_trace_enable(int event_id)
+{
+ struct ftrace_event_call *event;
+ int ret = -EINVAL;
+
+ mutex_lock(&event_mutex);
+ list_for_each_entry(event, &ftrace_events, list) {
+ if (event->id == event_id && event->perf_event_enable &&
+ try_module_get(event->mod)) {
+ ret = perf_trace_event_enable(event);
+ break;
+ }
+ }
+ mutex_unlock(&event_mutex);
+
+ return ret;
+}
+
+static void perf_trace_event_disable(struct ftrace_event_call *event)
+{
+ char *buf, *nmi_buf;
+
+ if (--event->perf_refcount > 0)
+ return;
+
+ event->perf_event_disable(event);
+
+ if (!--total_ref_count) {
+ buf = perf_trace_buf;
+ rcu_assign_pointer(perf_trace_buf, NULL);
+
+ nmi_buf = perf_trace_buf_nmi;
+ rcu_assign_pointer(perf_trace_buf_nmi, NULL);
+
+ /*
+ * Ensure every events in profiling have finished before
+ * releasing the buffers
+ */
+ synchronize_sched();
+
+ free_percpu(buf);
+ free_percpu(nmi_buf);
+ }
+}
+
+void perf_trace_disable(int event_id)
+{
+ struct ftrace_event_call *event;
+
+ mutex_lock(&event_mutex);
+ list_for_each_entry(event, &ftrace_events, list) {
+ if (event->id == event_id) {
+ perf_trace_event_disable(event);
+ module_put(event->mod);
+ break;
+ }
+ }
+ mutex_unlock(&event_mutex);
+}
+
+__kprobes void *perf_trace_buf_prepare(int size, unsigned short type,
+ int *rctxp, unsigned long *irq_flags)
+{
+ struct trace_entry *entry;
+ char *trace_buf, *raw_data;
+ int pc, cpu;
+
+ BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(unsigned long));
+
+ pc = preempt_count();
+
+ /* Protect the per cpu buffer, begin the rcu read side */
+ local_irq_save(*irq_flags);
+
+ *rctxp = perf_swevent_get_recursion_context();
+ if (*rctxp < 0)
+ goto err_recursion;
+
+ cpu = smp_processor_id();
+
+ if (in_nmi())
+ trace_buf = rcu_dereference_sched(perf_trace_buf_nmi);
+ else
+ trace_buf = rcu_dereference_sched(perf_trace_buf);
+
+ if (!trace_buf)
+ goto err;
+
+ raw_data = per_cpu_ptr(trace_buf, cpu);
+
+ /* zero the dead bytes from align to not leak stack to user */
+ memset(&raw_data[size - sizeof(u64)], 0, sizeof(u64));
+
+ entry = (struct trace_entry *)raw_data;
+ tracing_generic_entry_update(entry, *irq_flags, pc);
+ entry->type = type;
+
+ return raw_data;
+err:
+ perf_swevent_put_recursion_context(*rctxp);
+err_recursion:
+ local_irq_restore(*irq_flags);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(perf_trace_buf_prepare);
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c
deleted file mode 100644
index f0d69300507..00000000000
--- a/kernel/trace/trace_event_profile.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * trace event based perf counter profiling
- *
- * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra <pzijlstr@redhat.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/kprobes.h>
-#include "trace.h"
-
-
-static char *perf_trace_buf;
-static char *perf_trace_buf_nmi;
-
-typedef typeof(char [FTRACE_MAX_PROFILE_SIZE]) perf_trace_t ;
-
-/* Count the events in use (per event id, not per instance) */
-static int total_profile_count;
-
-static int ftrace_profile_enable_event(struct ftrace_event_call *event)
-{
- char *buf;
- int ret = -ENOMEM;
-
- if (event->profile_count++ > 0)
- return 0;
-
- if (!total_profile_count) {
- buf = (char *)alloc_percpu(perf_trace_t);
- if (!buf)
- goto fail_buf;
-
- rcu_assign_pointer(perf_trace_buf, buf);
-
- buf = (char *)alloc_percpu(perf_trace_t);
- if (!buf)
- goto fail_buf_nmi;
-
- rcu_assign_pointer(perf_trace_buf_nmi, buf);
- }
-
- ret = event->profile_enable(event);
- if (!ret) {
- total_profile_count++;
- return 0;
- }
-
-fail_buf_nmi:
- if (!total_profile_count) {
- free_percpu(perf_trace_buf_nmi);
- free_percpu(perf_trace_buf);
- perf_trace_buf_nmi = NULL;
- perf_trace_buf = NULL;
- }
-fail_buf:
- event->profile_count--;
-
- return ret;
-}
-
-int ftrace_profile_enable(int event_id)
-{
- struct ftrace_event_call *event;
- int ret = -EINVAL;
-
- mutex_lock(&event_mutex);
- list_for_each_entry(event, &ftrace_events, list) {
- if (event->id == event_id && event->profile_enable &&
- try_module_get(event->mod)) {
- ret = ftrace_profile_enable_event(event);
- break;
- }
- }
- mutex_unlock(&event_mutex);
-
- return ret;
-}
-
-static void ftrace_profile_disable_event(struct ftrace_event_call *event)
-{
- char *buf, *nmi_buf;
-
- if (--event->profile_count > 0)
- return;
-
- event->profile_disable(event);
-
- if (!--total_profile_count) {
- buf = perf_trace_buf;
- rcu_assign_pointer(perf_trace_buf, NULL);
-
- nmi_buf = perf_trace_buf_nmi;
- rcu_assign_pointer(perf_trace_buf_nmi, NULL);
-
- /*
- * Ensure every events in profiling have finished before
- * releasing the buffers
- */
- synchronize_sched();
-
- free_percpu(buf);
- free_percpu(nmi_buf);
- }
-}
-
-void ftrace_profile_disable(int event_id)
-{
- struct ftrace_event_call *event;
-
- mutex_lock(&event_mutex);
- list_for_each_entry(event, &ftrace_events, list) {
- if (event->id == event_id) {
- ftrace_profile_disable_event(event);
- module_put(event->mod);
- break;
- }
- }
- mutex_unlock(&event_mutex);
-}
-
-__kprobes void *ftrace_perf_buf_prepare(int size, unsigned short type,
- int *rctxp, unsigned long *irq_flags)
-{
- struct trace_entry *entry;
- char *trace_buf, *raw_data;
- int pc, cpu;
-
- pc = preempt_count();
-
- /* Protect the per cpu buffer, begin the rcu read side */
- local_irq_save(*irq_flags);
-
- *rctxp = perf_swevent_get_recursion_context();
- if (*rctxp < 0)
- goto err_recursion;
-
- cpu = smp_processor_id();
-
- if (in_nmi())
- trace_buf = rcu_dereference(perf_trace_buf_nmi);
- else
- trace_buf = rcu_dereference(perf_trace_buf);
-
- if (!trace_buf)
- goto err;
-
- raw_data = per_cpu_ptr(trace_buf, cpu);
-
- /* zero the dead bytes from align to not leak stack to user */
- *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
-
- entry = (struct trace_entry *)raw_data;
- tracing_generic_entry_update(entry, *irq_flags, pc);
- entry->type = type;
-
- return raw_data;
-err:
- perf_swevent_put_recursion_context(*rctxp);
-err_recursion:
- local_irq_restore(*irq_flags);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(ftrace_perf_buf_prepare);
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 3f972ad98d0..c697c704334 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -15,6 +15,7 @@
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/setup.h>
@@ -938,7 +939,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
trace_create_file("enable", 0644, call->dir, call,
enable);
- if (call->id && call->profile_enable)
+ if (call->id && call->perf_event_enable)
trace_create_file("id", 0444, call->dir, call,
id);
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 4615f62a04f..88c0b6dbd7f 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -22,6 +22,7 @@
#include <linux/ctype.h>
#include <linux/mutex.h>
#include <linux/perf_event.h>
+#include <linux/slab.h>
#include "trace.h"
#include "trace_output.h"
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 3fc2a575664..9aed1a5cf55 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -9,6 +9,7 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include "trace.h"
@@ -237,6 +238,14 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
return ret;
}
+int trace_graph_thresh_entry(struct ftrace_graph_ent *trace)
+{
+ if (tracing_thresh)
+ return 1;
+ else
+ return trace_graph_entry(trace);
+}
+
static void __trace_graph_return(struct trace_array *tr,
struct ftrace_graph_ret *trace,
unsigned long flags,
@@ -290,13 +299,26 @@ void set_graph_array(struct trace_array *tr)
smp_mb();
}
+void trace_graph_thresh_return(struct ftrace_graph_ret *trace)
+{
+ if (tracing_thresh &&
+ (trace->rettime - trace->calltime < tracing_thresh))
+ return;
+ else
+ trace_graph_return(trace);
+}
+
static int graph_trace_init(struct trace_array *tr)
{
int ret;
set_graph_array(tr);
- ret = register_ftrace_graph(&trace_graph_return,
- &trace_graph_entry);
+ if (tracing_thresh)
+ ret = register_ftrace_graph(&trace_graph_thresh_return,
+ &trace_graph_thresh_entry);
+ else
+ ret = register_ftrace_graph(&trace_graph_return,
+ &trace_graph_entry);
if (ret)
return ret;
tracing_start_cmdline_record();
@@ -920,7 +942,7 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
} else {
- ret = trace_seq_printf(s, "} (%ps)\n", (void *)trace->func);
+ ret = trace_seq_printf(s, "} /* %ps */\n", (void *)trace->func);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
}
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 505c92273b1..1251e367bae 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1214,7 +1214,7 @@ static int set_print_fmt(struct trace_probe *tp)
#ifdef CONFIG_PERF_EVENTS
/* Kprobe profile handler */
-static __kprobes void kprobe_profile_func(struct kprobe *kp,
+static __kprobes void kprobe_perf_func(struct kprobe *kp,
struct pt_regs *regs)
{
struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
@@ -1227,11 +1227,11 @@ static __kprobes void kprobe_profile_func(struct kprobe *kp,
__size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args);
size = ALIGN(__size + sizeof(u32), sizeof(u64));
size -= sizeof(u32);
- if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
+ if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
"profile buffer not large enough"))
return;
- entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags);
+ entry = perf_trace_buf_prepare(size, call->id, &rctx, &irq_flags);
if (!entry)
return;
@@ -1240,11 +1240,11 @@ static __kprobes void kprobe_profile_func(struct kprobe *kp,
for (i = 0; i < tp->nr_args; i++)
entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
- ftrace_perf_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags);
+ perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags, regs);
}
/* Kretprobe profile handler */
-static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri,
+static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
@@ -1257,11 +1257,11 @@ static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri,
__size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args);
size = ALIGN(__size + sizeof(u32), sizeof(u64));
size -= sizeof(u32);
- if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
+ if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
"profile buffer not large enough"))
return;
- entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags);
+ entry = perf_trace_buf_prepare(size, call->id, &rctx, &irq_flags);
if (!entry)
return;
@@ -1271,10 +1271,11 @@ static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri,
for (i = 0; i < tp->nr_args; i++)
entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
- ftrace_perf_buf_submit(entry, size, rctx, entry->ret_ip, 1, irq_flags);
+ perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1,
+ irq_flags, regs);
}
-static int probe_profile_enable(struct ftrace_event_call *call)
+static int probe_perf_enable(struct ftrace_event_call *call)
{
struct trace_probe *tp = (struct trace_probe *)call->data;
@@ -1286,7 +1287,7 @@ static int probe_profile_enable(struct ftrace_event_call *call)
return enable_kprobe(&tp->rp.kp);
}
-static void probe_profile_disable(struct ftrace_event_call *call)
+static void probe_perf_disable(struct ftrace_event_call *call)
{
struct trace_probe *tp = (struct trace_probe *)call->data;
@@ -1311,7 +1312,7 @@ int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
kprobe_trace_func(kp, regs);
#ifdef CONFIG_PERF_EVENTS
if (tp->flags & TP_FLAG_PROFILE)
- kprobe_profile_func(kp, regs);
+ kprobe_perf_func(kp, regs);
#endif
return 0; /* We don't tweek kernel, so just return 0 */
}
@@ -1325,7 +1326,7 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
kretprobe_trace_func(ri, regs);
#ifdef CONFIG_PERF_EVENTS
if (tp->flags & TP_FLAG_PROFILE)
- kretprobe_profile_func(ri, regs);
+ kretprobe_perf_func(ri, regs);
#endif
return 0; /* We don't tweek kernel, so just return 0 */
}
@@ -1358,8 +1359,8 @@ static int register_probe_event(struct trace_probe *tp)
call->unregfunc = probe_event_disable;
#ifdef CONFIG_PERF_EVENTS
- call->profile_enable = probe_profile_enable;
- call->profile_disable = probe_profile_disable;
+ call->perf_event_enable = probe_perf_enable;
+ call->perf_event_disable = probe_perf_disable;
#endif
call->data = tp;
ret = trace_add_event_call(call);
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
index 94103cdcf9d..d59cd687947 100644
--- a/kernel/trace/trace_ksym.c
+++ b/kernel/trace/trace_ksym.c
@@ -23,6 +23,7 @@
#include <linux/debugfs.h>
#include <linux/ftrace.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include "trace_output.h"
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 0acd834659e..017fa376505 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/mmiotrace.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/time.h>
#include <asm/atomic.h>
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index 280fea470d6..81003b4d617 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -3,6 +3,7 @@
#include <linux/stringify.h>
#include <linux/kthread.h>
#include <linux/delay.h>
+#include <linux/slab.h>
static inline int trace_valid_entry(struct trace_entry *entry)
{
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
index a4bb239eb98..96cffb269e7 100644
--- a/kernel/trace/trace_stat.c
+++ b/kernel/trace/trace_stat.c
@@ -10,6 +10,7 @@
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/rbtree.h>
#include <linux/debugfs.h>
#include "trace_stat.h"
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index cba47d7935c..4d6d711717f 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -1,5 +1,6 @@
#include <trace/syscall.h>
#include <trace/events/syscalls.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/ftrace.h>
#include <linux/perf_event.h>
@@ -428,12 +429,12 @@ core_initcall(init_ftrace_syscalls);
#ifdef CONFIG_PERF_EVENTS
-static DECLARE_BITMAP(enabled_prof_enter_syscalls, NR_syscalls);
-static DECLARE_BITMAP(enabled_prof_exit_syscalls, NR_syscalls);
-static int sys_prof_refcount_enter;
-static int sys_prof_refcount_exit;
+static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls);
+static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls);
+static int sys_perf_refcount_enter;
+static int sys_perf_refcount_exit;
-static void prof_syscall_enter(struct pt_regs *regs, long id)
+static void perf_syscall_enter(struct pt_regs *regs, long id)
{
struct syscall_metadata *sys_data;
struct syscall_trace_enter *rec;
@@ -443,7 +444,7 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
int size;
syscall_nr = syscall_get_nr(current, regs);
- if (!test_bit(syscall_nr, enabled_prof_enter_syscalls))
+ if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
return;
sys_data = syscall_nr_to_meta(syscall_nr);
@@ -455,11 +456,11 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
size = ALIGN(size + sizeof(u32), sizeof(u64));
size -= sizeof(u32);
- if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
- "profile buffer not large enough"))
+ if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
+ "perf buffer not large enough"))
return;
- rec = (struct syscall_trace_enter *)ftrace_perf_buf_prepare(size,
+ rec = (struct syscall_trace_enter *)perf_trace_buf_prepare(size,
sys_data->enter_event->id, &rctx, &flags);
if (!rec)
return;
@@ -467,10 +468,10 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
rec->nr = syscall_nr;
syscall_get_arguments(current, regs, 0, sys_data->nb_args,
(unsigned long *)&rec->args);
- ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags);
+ perf_trace_buf_submit(rec, size, rctx, 0, 1, flags, regs);
}
-int prof_sysenter_enable(struct ftrace_event_call *call)
+int perf_sysenter_enable(struct ftrace_event_call *call)
{
int ret = 0;
int num;
@@ -478,34 +479,34 @@ int prof_sysenter_enable(struct ftrace_event_call *call)
num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
- if (!sys_prof_refcount_enter)
- ret = register_trace_sys_enter(prof_syscall_enter);
+ if (!sys_perf_refcount_enter)
+ ret = register_trace_sys_enter(perf_syscall_enter);
if (ret) {
pr_info("event trace: Could not activate"
"syscall entry trace point");
} else {
- set_bit(num, enabled_prof_enter_syscalls);
- sys_prof_refcount_enter++;
+ set_bit(num, enabled_perf_enter_syscalls);
+ sys_perf_refcount_enter++;
}
mutex_unlock(&syscall_trace_lock);
return ret;
}
-void prof_sysenter_disable(struct ftrace_event_call *call)
+void perf_sysenter_disable(struct ftrace_event_call *call)
{
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
- sys_prof_refcount_enter--;
- clear_bit(num, enabled_prof_enter_syscalls);
- if (!sys_prof_refcount_enter)
- unregister_trace_sys_enter(prof_syscall_enter);
+ sys_perf_refcount_enter--;
+ clear_bit(num, enabled_perf_enter_syscalls);
+ if (!sys_perf_refcount_enter)
+ unregister_trace_sys_enter(perf_syscall_enter);
mutex_unlock(&syscall_trace_lock);
}
-static void prof_syscall_exit(struct pt_regs *regs, long ret)
+static void perf_syscall_exit(struct pt_regs *regs, long ret)
{
struct syscall_metadata *sys_data;
struct syscall_trace_exit *rec;
@@ -515,7 +516,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
int size;
syscall_nr = syscall_get_nr(current, regs);
- if (!test_bit(syscall_nr, enabled_prof_exit_syscalls))
+ if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
return;
sys_data = syscall_nr_to_meta(syscall_nr);
@@ -530,11 +531,11 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
* Impossible, but be paranoid with the future
* How to put this check outside runtime?
*/
- if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
- "exit event has grown above profile buffer size"))
+ if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
+ "exit event has grown above perf buffer size"))
return;
- rec = (struct syscall_trace_exit *)ftrace_perf_buf_prepare(size,
+ rec = (struct syscall_trace_exit *)perf_trace_buf_prepare(size,
sys_data->exit_event->id, &rctx, &flags);
if (!rec)
return;
@@ -542,10 +543,10 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
rec->nr = syscall_nr;
rec->ret = syscall_get_return_value(current, regs);
- ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags);
+ perf_trace_buf_submit(rec, size, rctx, 0, 1, flags, regs);
}
-int prof_sysexit_enable(struct ftrace_event_call *call)
+int perf_sysexit_enable(struct ftrace_event_call *call)
{
int ret = 0;
int num;
@@ -553,30 +554,30 @@ int prof_sysexit_enable(struct ftrace_event_call *call)
num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
- if (!sys_prof_refcount_exit)
- ret = register_trace_sys_exit(prof_syscall_exit);
+ if (!sys_perf_refcount_exit)
+ ret = register_trace_sys_exit(perf_syscall_exit);
if (ret) {
pr_info("event trace: Could not activate"
"syscall exit trace point");
} else {
- set_bit(num, enabled_prof_exit_syscalls);
- sys_prof_refcount_exit++;
+ set_bit(num, enabled_perf_exit_syscalls);
+ sys_perf_refcount_exit++;
}
mutex_unlock(&syscall_trace_lock);
return ret;
}
-void prof_sysexit_disable(struct ftrace_event_call *call)
+void perf_sysexit_disable(struct ftrace_event_call *call)
{
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
- sys_prof_refcount_exit--;
- clear_bit(num, enabled_prof_exit_syscalls);
- if (!sys_prof_refcount_exit)
- unregister_trace_sys_exit(prof_syscall_exit);
+ sys_perf_refcount_exit--;
+ clear_bit(num, enabled_perf_exit_syscalls);
+ if (!sys_perf_refcount_exit)
+ unregister_trace_sys_exit(perf_syscall_exit);
mutex_unlock(&syscall_trace_lock);
}
diff --git a/kernel/trace/trace_workqueue.c b/kernel/trace/trace_workqueue.c
index 40cafb07dff..cc2d2faa7d9 100644
--- a/kernel/trace/trace_workqueue.c
+++ b/kernel/trace/trace_workqueue.c
@@ -9,6 +9,7 @@
#include <trace/events/workqueue.h>
#include <linux/list.h>
#include <linux/percpu.h>
+#include <linux/slab.h>
#include <linux/kref.h>
#include "trace_stat.h"
#include "trace.h"
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index 00d59d048ed..0a67e041edf 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -21,6 +21,7 @@
#include <linux/tsacct_kern.h>
#include <linux/acct.h>
#include <linux/jiffies.h>
+#include <linux/mm.h>
/*
* fill in basic accounting fields
diff --git a/lib/Kconfig b/lib/Kconfig
index 97b136ff117..170d8ca901d 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -160,6 +160,9 @@ config TEXTSEARCH_BM
config TEXTSEARCH_FSM
tristate
+config BTREE
+ boolean
+
config HAS_IOMEM
boolean
depends on !NO_IOMEM
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 5e3407d997b..935248bdbc4 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -103,7 +103,8 @@ config HEADERS_CHECK
config DEBUG_SECTION_MISMATCH
bool "Enable full Section mismatch analysis"
- depends on UNDEFINED
+ depends on UNDEFINED || (BLACKFIN)
+ default y
# This option is on purpose disabled for now.
# It will be enabled when we are down to a reasonable number
# of section mismatch warnings (< 10 for an allyesconfig build)
@@ -355,7 +356,7 @@ config SLUB_STATS
config DEBUG_KMEMLEAK
bool "Kernel memory leak detector"
depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
- (X86 || ARM || PPC || S390 || SUPERH)
+ (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE)
select DEBUG_FS if SYSFS
select STACKTRACE if STACKTRACE_SUPPORT
@@ -532,6 +533,14 @@ config LOCK_STAT
For more details, see Documentation/lockstat.txt
+ This also enables lock events required by "perf lock",
+ subcommand of perf.
+ If you want to use "perf lock", you also need to turn on
+ CONFIG_EVENT_TRACING.
+
+ CONFIG_LOCK_STAT defines "contended" and "acquired" lock events.
+ (CONFIG_LOCKDEP defines "acquire" and "release" events.)
+
config DEBUG_LOCKDEP
bool "Lock dependency engine debugging"
depends on DEBUG_KERNEL && LOCKDEP
@@ -864,8 +873,7 @@ config DEBUG_FORCE_WEAK_PER_CPU
config LKDTM
tristate "Linux Kernel Dump Test Tool Module"
- depends on DEBUG_KERNEL
- depends on KPROBES
+ depends on DEBUG_FS
depends on BLOCK
default n
help
@@ -876,7 +884,7 @@ config LKDTM
called lkdtm.
Documentation on how to use the module can be found in
- drivers/misc/lkdtm.c
+ Documentation/fault-injection/provoke-crashes.txt
config FAULT_INJECTION
bool "Fault-injection framework"
diff --git a/lib/Makefile b/lib/Makefile
index 3b0b4a696db..0d4015205c6 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o
obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
- string_helpers.o gcd.o list_sort.o
+ string_helpers.o gcd.o lcm.o list_sort.o
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
@@ -41,6 +41,7 @@ lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o
obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
+obj-$(CONFIG_BTREE) += btree.o
obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
obj-$(CONFIG_DEBUG_LIST) += list_debug.o
obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 11bf4975058..ffb78c916cc 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -487,7 +487,7 @@ int __bitmap_parse(const char *buf, unsigned int buflen,
EXPORT_SYMBOL(__bitmap_parse);
/**
- * bitmap_parse_user()
+ * bitmap_parse_user - convert an ASCII hex string in a user buffer into a bitmap
*
* @ubuf: pointer to user buffer containing string.
* @ulen: buffer size in bytes. If string is smaller than this
@@ -619,7 +619,7 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
EXPORT_SYMBOL(bitmap_parselist);
/**
- * bitmap_pos_to_ord(buf, pos, bits)
+ * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
* @buf: pointer to a bitmap
* @pos: a bit position in @buf (0 <= @pos < @bits)
* @bits: number of valid bit positions in @buf
@@ -655,7 +655,7 @@ static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
}
/**
- * bitmap_ord_to_pos(buf, ord, bits)
+ * bitmap_ord_to_pos - find position of n-th set bit in bitmap
* @buf: pointer to bitmap
* @ord: ordinal bit position (n-th set bit, n >= 0)
* @bits: number of valid bit positions in @buf
@@ -733,10 +733,9 @@ void bitmap_remap(unsigned long *dst, const unsigned long *src,
bitmap_zero(dst, bits);
w = bitmap_weight(new, bits);
- for (oldbit = find_first_bit(src, bits);
- oldbit < bits;
- oldbit = find_next_bit(src, bits, oldbit + 1)) {
+ for_each_set_bit(oldbit, src, bits) {
int n = bitmap_pos_to_ord(old, oldbit, bits);
+
if (n < 0 || w == 0)
set_bit(oldbit, dst); /* identity map */
else
@@ -903,9 +902,7 @@ void bitmap_onto(unsigned long *dst, const unsigned long *orig,
*/
m = 0;
- for (n = find_first_bit(relmap, bits);
- n < bits;
- n = find_next_bit(relmap, bits, n + 1)) {
+ for_each_set_bit(n, relmap, bits) {
/* m == bitmap_pos_to_ord(relmap, n, bits) */
if (test_bit(m, orig))
set_bit(n, dst);
@@ -934,9 +931,7 @@ void bitmap_fold(unsigned long *dst, const unsigned long *orig,
return;
bitmap_zero(dst, bits);
- for (oldbit = find_first_bit(orig, bits);
- oldbit < bits;
- oldbit = find_next_bit(orig, bits, oldbit + 1))
+ for_each_set_bit(oldbit, orig, bits)
set_bit(oldbit % sz, dst);
}
EXPORT_SYMBOL(bitmap_fold);
diff --git a/lib/btree.c b/lib/btree.c
new file mode 100644
index 00000000000..41859a82021
--- /dev/null
+++ b/lib/btree.c
@@ -0,0 +1,797 @@
+/*
+ * lib/btree.c - Simple In-memory B+Tree
+ *
+ * As should be obvious for Linux kernel code, license is GPLv2
+ *
+ * Copyright (c) 2007-2008 Joern Engel <joern@logfs.org>
+ * Bits and pieces stolen from Peter Zijlstra's code, which is
+ * Copyright 2007, Red Hat Inc. Peter Zijlstra <pzijlstr@redhat.com>
+ * GPLv2
+ *
+ * see http://programming.kicks-ass.net/kernel-patches/vma_lookup/btree.patch
+ *
+ * A relatively simple B+Tree implementation. I have written it as a learning
+ * excercise to understand how B+Trees work. Turned out to be useful as well.
+ *
+ * B+Trees can be used similar to Linux radix trees (which don't have anything
+ * in common with textbook radix trees, beware). Prerequisite for them working
+ * well is that access to a random tree node is much faster than a large number
+ * of operations within each node.
+ *
+ * Disks have fulfilled the prerequisite for a long time. More recently DRAM
+ * has gained similar properties, as memory access times, when measured in cpu
+ * cycles, have increased. Cacheline sizes have increased as well, which also
+ * helps B+Trees.
+ *
+ * Compared to radix trees, B+Trees are more efficient when dealing with a
+ * sparsely populated address space. Between 25% and 50% of the memory is
+ * occupied with valid pointers. When densely populated, radix trees contain
+ * ~98% pointers - hard to beat. Very sparse radix trees contain only ~2%
+ * pointers.
+ *
+ * This particular implementation stores pointers identified by a long value.
+ * Storing NULL pointers is illegal, lookup will return NULL when no entry
+ * was found.
+ *
+ * A tricks was used that is not commonly found in textbooks. The lowest
+ * values are to the right, not to the left. All used slots within a node
+ * are on the left, all unused slots contain NUL values. Most operations
+ * simply loop once over all slots and terminate on the first NUL.
+ */
+
+#include <linux/btree.h>
+#include <linux/cache.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define NODESIZE MAX(L1_CACHE_BYTES, 128)
+
+struct btree_geo {
+ int keylen;
+ int no_pairs;
+ int no_longs;
+};
+
+struct btree_geo btree_geo32 = {
+ .keylen = 1,
+ .no_pairs = NODESIZE / sizeof(long) / 2,
+ .no_longs = NODESIZE / sizeof(long) / 2,
+};
+EXPORT_SYMBOL_GPL(btree_geo32);
+
+#define LONG_PER_U64 (64 / BITS_PER_LONG)
+struct btree_geo btree_geo64 = {
+ .keylen = LONG_PER_U64,
+ .no_pairs = NODESIZE / sizeof(long) / (1 + LONG_PER_U64),
+ .no_longs = LONG_PER_U64 * (NODESIZE / sizeof(long) / (1 + LONG_PER_U64)),
+};
+EXPORT_SYMBOL_GPL(btree_geo64);
+
+struct btree_geo btree_geo128 = {
+ .keylen = 2 * LONG_PER_U64,
+ .no_pairs = NODESIZE / sizeof(long) / (1 + 2 * LONG_PER_U64),
+ .no_longs = 2 * LONG_PER_U64 * (NODESIZE / sizeof(long) / (1 + 2 * LONG_PER_U64)),
+};
+EXPORT_SYMBOL_GPL(btree_geo128);
+
+static struct kmem_cache *btree_cachep;
+
+void *btree_alloc(gfp_t gfp_mask, void *pool_data)
+{
+ return kmem_cache_alloc(btree_cachep, gfp_mask);
+}
+EXPORT_SYMBOL_GPL(btree_alloc);
+
+void btree_free(void *element, void *pool_data)
+{
+ kmem_cache_free(btree_cachep, element);
+}
+EXPORT_SYMBOL_GPL(btree_free);
+
+static unsigned long *btree_node_alloc(struct btree_head *head, gfp_t gfp)
+{
+ unsigned long *node;
+
+ node = mempool_alloc(head->mempool, gfp);
+ memset(node, 0, NODESIZE);
+ return node;
+}
+
+static int longcmp(const unsigned long *l1, const unsigned long *l2, size_t n)
+{
+ size_t i;
+
+ for (i = 0; i < n; i++) {
+ if (l1[i] < l2[i])
+ return -1;
+ if (l1[i] > l2[i])
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned long *longcpy(unsigned long *dest, const unsigned long *src,
+ size_t n)
+{
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ dest[i] = src[i];
+ return dest;
+}
+
+static unsigned long *longset(unsigned long *s, unsigned long c, size_t n)
+{
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ s[i] = c;
+ return s;
+}
+
+static void dec_key(struct btree_geo *geo, unsigned long *key)
+{
+ unsigned long val;
+ int i;
+
+ for (i = geo->keylen - 1; i >= 0; i--) {
+ val = key[i];
+ key[i] = val - 1;
+ if (val)
+ break;
+ }
+}
+
+static unsigned long *bkey(struct btree_geo *geo, unsigned long *node, int n)
+{
+ return &node[n * geo->keylen];
+}
+
+static void *bval(struct btree_geo *geo, unsigned long *node, int n)
+{
+ return (void *)node[geo->no_longs + n];
+}
+
+static void setkey(struct btree_geo *geo, unsigned long *node, int n,
+ unsigned long *key)
+{
+ longcpy(bkey(geo, node, n), key, geo->keylen);
+}
+
+static void setval(struct btree_geo *geo, unsigned long *node, int n,
+ void *val)
+{
+ node[geo->no_longs + n] = (unsigned long) val;
+}
+
+static void clearpair(struct btree_geo *geo, unsigned long *node, int n)
+{
+ longset(bkey(geo, node, n), 0, geo->keylen);
+ node[geo->no_longs + n] = 0;
+}
+
+static inline void __btree_init(struct btree_head *head)
+{
+ head->node = NULL;
+ head->height = 0;
+}
+
+void btree_init_mempool(struct btree_head *head, mempool_t *mempool)
+{
+ __btree_init(head);
+ head->mempool = mempool;
+}
+EXPORT_SYMBOL_GPL(btree_init_mempool);
+
+int btree_init(struct btree_head *head)
+{
+ __btree_init(head);
+ head->mempool = mempool_create(0, btree_alloc, btree_free, NULL);
+ if (!head->mempool)
+ return -ENOMEM;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(btree_init);
+
+void btree_destroy(struct btree_head *head)
+{
+ mempool_destroy(head->mempool);
+ head->mempool = NULL;
+}
+EXPORT_SYMBOL_GPL(btree_destroy);
+
+void *btree_last(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key)
+{
+ int height = head->height;
+ unsigned long *node = head->node;
+
+ if (height == 0)
+ return NULL;
+
+ for ( ; height > 1; height--)
+ node = bval(geo, node, 0);
+
+ longcpy(key, bkey(geo, node, 0), geo->keylen);
+ return bval(geo, node, 0);
+}
+EXPORT_SYMBOL_GPL(btree_last);
+
+static int keycmp(struct btree_geo *geo, unsigned long *node, int pos,
+ unsigned long *key)
+{
+ return longcmp(bkey(geo, node, pos), key, geo->keylen);
+}
+
+static int keyzero(struct btree_geo *geo, unsigned long *key)
+{
+ int i;
+
+ for (i = 0; i < geo->keylen; i++)
+ if (key[i])
+ return 0;
+
+ return 1;
+}
+
+void *btree_lookup(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key)
+{
+ int i, height = head->height;
+ unsigned long *node = head->node;
+
+ if (height == 0)
+ return NULL;
+
+ for ( ; height > 1; height--) {
+ for (i = 0; i < geo->no_pairs; i++)
+ if (keycmp(geo, node, i, key) <= 0)
+ break;
+ if (i == geo->no_pairs)
+ return NULL;
+ node = bval(geo, node, i);
+ if (!node)
+ return NULL;
+ }
+
+ if (!node)
+ return NULL;
+
+ for (i = 0; i < geo->no_pairs; i++)
+ if (keycmp(geo, node, i, key) == 0)
+ return bval(geo, node, i);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(btree_lookup);
+
+int btree_update(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, void *val)
+{
+ int i, height = head->height;
+ unsigned long *node = head->node;
+
+ if (height == 0)
+ return -ENOENT;
+
+ for ( ; height > 1; height--) {
+ for (i = 0; i < geo->no_pairs; i++)
+ if (keycmp(geo, node, i, key) <= 0)
+ break;
+ if (i == geo->no_pairs)
+ return -ENOENT;
+ node = bval(geo, node, i);
+ if (!node)
+ return -ENOENT;
+ }
+
+ if (!node)
+ return -ENOENT;
+
+ for (i = 0; i < geo->no_pairs; i++)
+ if (keycmp(geo, node, i, key) == 0) {
+ setval(geo, node, i, val);
+ return 0;
+ }
+ return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(btree_update);
+
+/*
+ * Usually this function is quite similar to normal lookup. But the key of
+ * a parent node may be smaller than the smallest key of all its siblings.
+ * In such a case we cannot just return NULL, as we have only proven that no
+ * key smaller than __key, but larger than this parent key exists.
+ * So we set __key to the parent key and retry. We have to use the smallest
+ * such parent key, which is the last parent key we encountered.
+ */
+void *btree_get_prev(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *__key)
+{
+ int i, height;
+ unsigned long *node, *oldnode;
+ unsigned long *retry_key = NULL, key[geo->keylen];
+
+ if (keyzero(geo, __key))
+ return NULL;
+
+ if (head->height == 0)
+ return NULL;
+retry:
+ longcpy(key, __key, geo->keylen);
+ dec_key(geo, key);
+
+ node = head->node;
+ for (height = head->height ; height > 1; height--) {
+ for (i = 0; i < geo->no_pairs; i++)
+ if (keycmp(geo, node, i, key) <= 0)
+ break;
+ if (i == geo->no_pairs)
+ goto miss;
+ oldnode = node;
+ node = bval(geo, node, i);
+ if (!node)
+ goto miss;
+ retry_key = bkey(geo, oldnode, i);
+ }
+
+ if (!node)
+ goto miss;
+
+ for (i = 0; i < geo->no_pairs; i++) {
+ if (keycmp(geo, node, i, key) <= 0) {
+ if (bval(geo, node, i)) {
+ longcpy(__key, bkey(geo, node, i), geo->keylen);
+ return bval(geo, node, i);
+ } else
+ goto miss;
+ }
+ }
+miss:
+ if (retry_key) {
+ __key = retry_key;
+ retry_key = NULL;
+ goto retry;
+ }
+ return NULL;
+}
+
+static int getpos(struct btree_geo *geo, unsigned long *node,
+ unsigned long *key)
+{
+ int i;
+
+ for (i = 0; i < geo->no_pairs; i++) {
+ if (keycmp(geo, node, i, key) <= 0)
+ break;
+ }
+ return i;
+}
+
+static int getfill(struct btree_geo *geo, unsigned long *node, int start)
+{
+ int i;
+
+ for (i = start; i < geo->no_pairs; i++)
+ if (!bval(geo, node, i))
+ break;
+ return i;
+}
+
+/*
+ * locate the correct leaf node in the btree
+ */
+static unsigned long *find_level(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, int level)
+{
+ unsigned long *node = head->node;
+ int i, height;
+
+ for (height = head->height; height > level; height--) {
+ for (i = 0; i < geo->no_pairs; i++)
+ if (keycmp(geo, node, i, key) <= 0)
+ break;
+
+ if ((i == geo->no_pairs) || !bval(geo, node, i)) {
+ /* right-most key is too large, update it */
+ /* FIXME: If the right-most key on higher levels is
+ * always zero, this wouldn't be necessary. */
+ i--;
+ setkey(geo, node, i, key);
+ }
+ BUG_ON(i < 0);
+ node = bval(geo, node, i);
+ }
+ BUG_ON(!node);
+ return node;
+}
+
+static int btree_grow(struct btree_head *head, struct btree_geo *geo,
+ gfp_t gfp)
+{
+ unsigned long *node;
+ int fill;
+
+ node = btree_node_alloc(head, gfp);
+ if (!node)
+ return -ENOMEM;
+ if (head->node) {
+ fill = getfill(geo, head->node, 0);
+ setkey(geo, node, 0, bkey(geo, head->node, fill - 1));
+ setval(geo, node, 0, head->node);
+ }
+ head->node = node;
+ head->height++;
+ return 0;
+}
+
+static void btree_shrink(struct btree_head *head, struct btree_geo *geo)
+{
+ unsigned long *node;
+ int fill;
+
+ if (head->height <= 1)
+ return;
+
+ node = head->node;
+ fill = getfill(geo, node, 0);
+ BUG_ON(fill > 1);
+ head->node = bval(geo, node, 0);
+ head->height--;
+ mempool_free(node, head->mempool);
+}
+
+static int btree_insert_level(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, void *val, int level,
+ gfp_t gfp)
+{
+ unsigned long *node;
+ int i, pos, fill, err;
+
+ BUG_ON(!val);
+ if (head->height < level) {
+ err = btree_grow(head, geo, gfp);
+ if (err)
+ return err;
+ }
+
+retry:
+ node = find_level(head, geo, key, level);
+ pos = getpos(geo, node, key);
+ fill = getfill(geo, node, pos);
+ /* two identical keys are not allowed */
+ BUG_ON(pos < fill && keycmp(geo, node, pos, key) == 0);
+
+ if (fill == geo->no_pairs) {
+ /* need to split node */
+ unsigned long *new;
+
+ new = btree_node_alloc(head, gfp);
+ if (!new)
+ return -ENOMEM;
+ err = btree_insert_level(head, geo,
+ bkey(geo, node, fill / 2 - 1),
+ new, level + 1, gfp);
+ if (err) {
+ mempool_free(new, head->mempool);
+ return err;
+ }
+ for (i = 0; i < fill / 2; i++) {
+ setkey(geo, new, i, bkey(geo, node, i));
+ setval(geo, new, i, bval(geo, node, i));
+ setkey(geo, node, i, bkey(geo, node, i + fill / 2));
+ setval(geo, node, i, bval(geo, node, i + fill / 2));
+ clearpair(geo, node, i + fill / 2);
+ }
+ if (fill & 1) {
+ setkey(geo, node, i, bkey(geo, node, fill - 1));
+ setval(geo, node, i, bval(geo, node, fill - 1));
+ clearpair(geo, node, fill - 1);
+ }
+ goto retry;
+ }
+ BUG_ON(fill >= geo->no_pairs);
+
+ /* shift and insert */
+ for (i = fill; i > pos; i--) {
+ setkey(geo, node, i, bkey(geo, node, i - 1));
+ setval(geo, node, i, bval(geo, node, i - 1));
+ }
+ setkey(geo, node, pos, key);
+ setval(geo, node, pos, val);
+
+ return 0;
+}
+
+int btree_insert(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, void *val, gfp_t gfp)
+{
+ return btree_insert_level(head, geo, key, val, 1, gfp);
+}
+EXPORT_SYMBOL_GPL(btree_insert);
+
+static void *btree_remove_level(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, int level);
+static void merge(struct btree_head *head, struct btree_geo *geo, int level,
+ unsigned long *left, int lfill,
+ unsigned long *right, int rfill,
+ unsigned long *parent, int lpos)
+{
+ int i;
+
+ for (i = 0; i < rfill; i++) {
+ /* Move all keys to the left */
+ setkey(geo, left, lfill + i, bkey(geo, right, i));
+ setval(geo, left, lfill + i, bval(geo, right, i));
+ }
+ /* Exchange left and right child in parent */
+ setval(geo, parent, lpos, right);
+ setval(geo, parent, lpos + 1, left);
+ /* Remove left (formerly right) child from parent */
+ btree_remove_level(head, geo, bkey(geo, parent, lpos), level + 1);
+ mempool_free(right, head->mempool);
+}
+
+static void rebalance(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, int level, unsigned long *child, int fill)
+{
+ unsigned long *parent, *left = NULL, *right = NULL;
+ int i, no_left, no_right;
+
+ if (fill == 0) {
+ /* Because we don't steal entries from a neigbour, this case
+ * can happen. Parent node contains a single child, this
+ * node, so merging with a sibling never happens.
+ */
+ btree_remove_level(head, geo, key, level + 1);
+ mempool_free(child, head->mempool);
+ return;
+ }
+
+ parent = find_level(head, geo, key, level + 1);
+ i = getpos(geo, parent, key);
+ BUG_ON(bval(geo, parent, i) != child);
+
+ if (i > 0) {
+ left = bval(geo, parent, i - 1);
+ no_left = getfill(geo, left, 0);
+ if (fill + no_left <= geo->no_pairs) {
+ merge(head, geo, level,
+ left, no_left,
+ child, fill,
+ parent, i - 1);
+ return;
+ }
+ }
+ if (i + 1 < getfill(geo, parent, i)) {
+ right = bval(geo, parent, i + 1);
+ no_right = getfill(geo, right, 0);
+ if (fill + no_right <= geo->no_pairs) {
+ merge(head, geo, level,
+ child, fill,
+ right, no_right,
+ parent, i);
+ return;
+ }
+ }
+ /*
+ * We could also try to steal one entry from the left or right
+ * neighbor. By not doing so we changed the invariant from
+ * "all nodes are at least half full" to "no two neighboring
+ * nodes can be merged". Which means that the average fill of
+ * all nodes is still half or better.
+ */
+}
+
+static void *btree_remove_level(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key, int level)
+{
+ unsigned long *node;
+ int i, pos, fill;
+ void *ret;
+
+ if (level > head->height) {
+ /* we recursed all the way up */
+ head->height = 0;
+ head->node = NULL;
+ return NULL;
+ }
+
+ node = find_level(head, geo, key, level);
+ pos = getpos(geo, node, key);
+ fill = getfill(geo, node, pos);
+ if ((level == 1) && (keycmp(geo, node, pos, key) != 0))
+ return NULL;
+ ret = bval(geo, node, pos);
+
+ /* remove and shift */
+ for (i = pos; i < fill - 1; i++) {
+ setkey(geo, node, i, bkey(geo, node, i + 1));
+ setval(geo, node, i, bval(geo, node, i + 1));
+ }
+ clearpair(geo, node, fill - 1);
+
+ if (fill - 1 < geo->no_pairs / 2) {
+ if (level < head->height)
+ rebalance(head, geo, key, level, node, fill - 1);
+ else if (fill - 1 == 1)
+ btree_shrink(head, geo);
+ }
+
+ return ret;
+}
+
+void *btree_remove(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *key)
+{
+ if (head->height == 0)
+ return NULL;
+
+ return btree_remove_level(head, geo, key, 1);
+}
+EXPORT_SYMBOL_GPL(btree_remove);
+
+int btree_merge(struct btree_head *target, struct btree_head *victim,
+ struct btree_geo *geo, gfp_t gfp)
+{
+ unsigned long key[geo->keylen];
+ unsigned long dup[geo->keylen];
+ void *val;
+ int err;
+
+ BUG_ON(target == victim);
+
+ if (!(target->node)) {
+ /* target is empty, just copy fields over */
+ target->node = victim->node;
+ target->height = victim->height;
+ __btree_init(victim);
+ return 0;
+ }
+
+ /* TODO: This needs some optimizations. Currently we do three tree
+ * walks to remove a single object from the victim.
+ */
+ for (;;) {
+ if (!btree_last(victim, geo, key))
+ break;
+ val = btree_lookup(victim, geo, key);
+ err = btree_insert(target, geo, key, val, gfp);
+ if (err)
+ return err;
+ /* We must make a copy of the key, as the original will get
+ * mangled inside btree_remove. */
+ longcpy(dup, key, geo->keylen);
+ btree_remove(victim, geo, dup);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(btree_merge);
+
+static size_t __btree_for_each(struct btree_head *head, struct btree_geo *geo,
+ unsigned long *node, unsigned long opaque,
+ void (*func)(void *elem, unsigned long opaque,
+ unsigned long *key, size_t index,
+ void *func2),
+ void *func2, int reap, int height, size_t count)
+{
+ int i;
+ unsigned long *child;
+
+ for (i = 0; i < geo->no_pairs; i++) {
+ child = bval(geo, node, i);
+ if (!child)
+ break;
+ if (height > 1)
+ count = __btree_for_each(head, geo, child, opaque,
+ func, func2, reap, height - 1, count);
+ else
+ func(child, opaque, bkey(geo, node, i), count++,
+ func2);
+ }
+ if (reap)
+ mempool_free(node, head->mempool);
+ return count;
+}
+
+static void empty(void *elem, unsigned long opaque, unsigned long *key,
+ size_t index, void *func2)
+{
+}
+
+void visitorl(void *elem, unsigned long opaque, unsigned long *key,
+ size_t index, void *__func)
+{
+ visitorl_t func = __func;
+
+ func(elem, opaque, *key, index);
+}
+EXPORT_SYMBOL_GPL(visitorl);
+
+void visitor32(void *elem, unsigned long opaque, unsigned long *__key,
+ size_t index, void *__func)
+{
+ visitor32_t func = __func;
+ u32 *key = (void *)__key;
+
+ func(elem, opaque, *key, index);
+}
+EXPORT_SYMBOL_GPL(visitor32);
+
+void visitor64(void *elem, unsigned long opaque, unsigned long *__key,
+ size_t index, void *__func)
+{
+ visitor64_t func = __func;
+ u64 *key = (void *)__key;
+
+ func(elem, opaque, *key, index);
+}
+EXPORT_SYMBOL_GPL(visitor64);
+
+void visitor128(void *elem, unsigned long opaque, unsigned long *__key,
+ size_t index, void *__func)
+{
+ visitor128_t func = __func;
+ u64 *key = (void *)__key;
+
+ func(elem, opaque, key[0], key[1], index);
+}
+EXPORT_SYMBOL_GPL(visitor128);
+
+size_t btree_visitor(struct btree_head *head, struct btree_geo *geo,
+ unsigned long opaque,
+ void (*func)(void *elem, unsigned long opaque,
+ unsigned long *key,
+ size_t index, void *func2),
+ void *func2)
+{
+ size_t count = 0;
+
+ if (!func2)
+ func = empty;
+ if (head->node)
+ count = __btree_for_each(head, geo, head->node, opaque, func,
+ func2, 0, head->height, 0);
+ return count;
+}
+EXPORT_SYMBOL_GPL(btree_visitor);
+
+size_t btree_grim_visitor(struct btree_head *head, struct btree_geo *geo,
+ unsigned long opaque,
+ void (*func)(void *elem, unsigned long opaque,
+ unsigned long *key,
+ size_t index, void *func2),
+ void *func2)
+{
+ size_t count = 0;
+
+ if (!func2)
+ func = empty;
+ if (head->node)
+ count = __btree_for_each(head, geo, head->node, opaque, func,
+ func2, 1, head->height, 0);
+ __btree_init(head);
+ return count;
+}
+EXPORT_SYMBOL_GPL(btree_grim_visitor);
+
+static int __init btree_module_init(void)
+{
+ btree_cachep = kmem_cache_create("btree_node", NODESIZE, 0,
+ SLAB_HWCACHE_ALIGN, NULL);
+ return 0;
+}
+
+static void __exit btree_module_exit(void)
+{
+ kmem_cache_destroy(btree_cachep);
+}
+
+/* If core code starts using btree, initialization should happen even earlier */
+module_init(btree_module_init);
+module_exit(btree_module_exit);
+
+MODULE_AUTHOR("Joern Engel <joern@logfs.org>");
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_LICENSE("GPL");
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 7bb4142a502..05d6aca7fc1 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -1,3 +1,4 @@
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/cpumask.h>
diff --git a/lib/crc32.c b/lib/crc32.c
index 02e3b31b3a7..bc5b936e914 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -25,16 +25,19 @@
#include <linux/module.h>
#include <linux/compiler.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <asm/atomic.h>
#include "crc32defs.h"
#if CRC_LE_BITS == 8
-#define tole(x) __constant_cpu_to_le32(x)
-#define tobe(x) __constant_cpu_to_be32(x)
+# define tole(x) __constant_cpu_to_le32(x)
#else
-#define tole(x) (x)
-#define tobe(x) (x)
+# define tole(x) (x)
+#endif
+
+#if CRC_BE_BITS == 8
+# define tobe(x) __constant_cpu_to_be32(x)
+#else
+# define tobe(x) (x)
#endif
#include "crc32table.h"
@@ -52,20 +55,19 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab)
# else
# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
# endif
- const u32 *b = (const u32 *)buf;
+ const u32 *b;
size_t rem_len;
/* Align it */
- if (unlikely((long)b & 3 && len)) {
- u8 *p = (u8 *)b;
+ if (unlikely((long)buf & 3 && len)) {
do {
- DO_CRC(*p++);
- } while ((--len) && ((long)p)&3);
- b = (u32 *)p;
+ DO_CRC(*buf++);
+ } while ((--len) && ((long)buf)&3);
}
rem_len = len & 3;
/* load data 32 bits wide, xor data 32 bits wide. */
len = len >> 2;
+ b = (const u32 *)buf;
for (--b; len; --len) {
crc ^= *++b; /* use pre increment for speed */
DO_CRC(0);
@@ -82,6 +84,7 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab)
} while (--len);
}
return crc;
+#undef DO_CRC
}
#endif
/**
@@ -119,9 +122,6 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
crc = __cpu_to_le32(crc);
crc = crc32_body(crc, p, len, tab);
return __le32_to_cpu(crc);
-#undef ENDIAN_SHIFT
-#undef DO_CRC
-
# elif CRC_LE_BITS == 4
while (len--) {
crc ^= *p++;
@@ -179,9 +179,6 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
crc = __cpu_to_be32(crc);
crc = crc32_body(crc, p, len, tab);
return __be32_to_cpu(crc);
-#undef ENDIAN_SHIFT
-#undef DO_CRC
-
# elif CRC_BE_BITS == 4
while (len--) {
crc ^= *p++ << 24;
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index a9a8996d286..b862b30369f 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <linux/hash.h>
#define ODEBUG_HASH_BITS 14
diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c
index db521f45626..bcb3a4bd68f 100644
--- a/lib/decompress_unlzo.c
+++ b/lib/decompress_unlzo.c
@@ -97,7 +97,7 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
u32 src_len, dst_len;
size_t tmp;
u8 *in_buf, *in_buf_save, *out_buf;
- int obytes_processed = 0;
+ int ret = -1;
set_error_fn(error_fn);
@@ -174,15 +174,22 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
/* decompress */
tmp = dst_len;
- r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
+
+ /* When the input data is not compressed at all,
+ * lzo1x_decompress_safe will fail, so call memcpy()
+ * instead */
+ if (unlikely(dst_len == src_len))
+ memcpy(out_buf, in_buf, src_len);
+ else {
+ r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
out_buf, &tmp);
- if (r != LZO_E_OK || dst_len != tmp) {
- error("Compressed data violation");
- goto exit_2;
+ if (r != LZO_E_OK || dst_len != tmp) {
+ error("Compressed data violation");
+ goto exit_2;
+ }
}
- obytes_processed += dst_len;
if (flush)
flush(out_buf, dst_len);
if (output)
@@ -196,6 +203,7 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
in_buf += src_len;
}
+ ret = 0;
exit_2:
if (!input)
free(in_buf);
@@ -203,7 +211,7 @@ exit_1:
if (!output)
free(out_buf);
exit:
- return obytes_processed;
+ return ret;
}
#define decompress unlzo
diff --git a/lib/devres.c b/lib/devres.c
index 72c8909006d..49368608f98 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -1,5 +1,6 @@
#include <linux/pci.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <linux/module.h>
void devm_ioremap_release(struct device *dev, void *res)
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index ba8b67039d1..01e64270e24 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -570,7 +570,7 @@ static ssize_t filter_write(struct file *file, const char __user *userbuf,
* Now parse out the first token and use it as the name for the
* driver to filter for.
*/
- for (i = 0; i < NAME_MAX_LEN; ++i) {
+ for (i = 0; i < NAME_MAX_LEN - 1; ++i) {
current_driver_name[i] = buf[i];
if (isspace(buf[i]) || buf[i] == ' ' || buf[i] == 0)
break;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index f9350291598..d6b8b9b1abf 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -25,6 +25,7 @@
#include <linux/uaccess.h>
#include <linux/dynamic_debug.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[];
diff --git a/lib/flex_array.c b/lib/flex_array.c
index 66eef2e4483..41b1804fa72 100644
--- a/lib/flex_array.c
+++ b/lib/flex_array.c
@@ -99,7 +99,7 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
ret->element_size = element_size;
ret->total_nr_elements = total;
if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO))
- memset(ret->parts[0], FLEX_ARRAY_FREE,
+ memset(&ret->parts[0], FLEX_ARRAY_FREE,
FLEX_ARRAY_BASE_BYTES_LEFT);
return ret;
}
diff --git a/lib/genalloc.c b/lib/genalloc.c
index e67f97495dd..736c3b06398 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -10,6 +10,7 @@
* Version 2. See the file COPYING for more details.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/bitmap.h>
#include <linux/genalloc.h>
diff --git a/lib/inflate.c b/lib/inflate.c
index d10255973a9..677b738c220 100644
--- a/lib/inflate.c
+++ b/lib/inflate.c
@@ -103,6 +103,7 @@
the two sets of lengths.
*/
#include <linux/compiler.h>
+#include <linux/slab.h>
#ifdef RCSID
static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #";
diff --git a/lib/kasprintf.c b/lib/kasprintf.c
index c5ff1fd1003..9c4233b2378 100644
--- a/lib/kasprintf.c
+++ b/lib/kasprintf.c
@@ -6,6 +6,7 @@
#include <stdarg.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/string.h>
diff --git a/lib/kobject.c b/lib/kobject.c
index b512b746d2a..8115eb1bbf4 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -700,7 +700,7 @@ static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-struct sysfs_ops kobj_sysfs_ops = {
+const struct sysfs_ops kobj_sysfs_ops = {
.show = kobj_attr_show,
.store = kobj_attr_store,
};
@@ -789,7 +789,7 @@ static struct kobj_type kset_ktype = {
* If the kset was not able to be created, NULL will be returned.
*/
static struct kset *kset_create(const char *name,
- struct kset_uevent_ops *uevent_ops,
+ const struct kset_uevent_ops *uevent_ops,
struct kobject *parent_kobj)
{
struct kset *kset;
@@ -832,7 +832,7 @@ static struct kset *kset_create(const char *name,
* If the kset was not able to be created, NULL will be returned.
*/
struct kset *kset_create_and_add(const char *name,
- struct kset_uevent_ops *uevent_ops,
+ const struct kset_uevent_ops *uevent_ops,
struct kobject *parent_kobj)
{
struct kset *kset;
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 920a3ca6e25..7b48d44ced6 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/kobject.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
@@ -95,7 +96,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
const char *subsystem;
struct kobject *top_kobj;
struct kset *kset;
- struct kset_uevent_ops *uevent_ops;
+ const struct kset_uevent_ops *uevent_ops;
u64 seq;
int i = 0;
int retval = 0;
diff --git a/lib/kref.c b/lib/kref.c
index 9ecd6e86561..6d19f690380 100644
--- a/lib/kref.c
+++ b/lib/kref.c
@@ -13,6 +13,7 @@
#include <linux/kref.h>
#include <linux/module.h>
+#include <linux/slab.h>
/**
* kref_set - initialize object and set refcount to requested number.
diff --git a/lib/lcm.c b/lib/lcm.c
new file mode 100644
index 00000000000..157cd88a6ff
--- /dev/null
+++ b/lib/lcm.c
@@ -0,0 +1,15 @@
+#include <linux/kernel.h>
+#include <linux/gcd.h>
+#include <linux/module.h>
+
+/* Lowest common multiple */
+unsigned long lcm(unsigned long a, unsigned long b)
+{
+ if (a && b)
+ return (a * b) / gcd(a, b);
+ else if (b)
+ return b;
+
+ return a;
+}
+EXPORT_SYMBOL_GPL(lcm);
diff --git a/lib/list_sort.c b/lib/list_sort.c
index 19d11e0bb95..4b5cb794c38 100644
--- a/lib/list_sort.c
+++ b/lib/list_sort.c
@@ -4,99 +4,214 @@
#include <linux/slab.h>
#include <linux/list.h>
+#define MAX_LIST_LENGTH_BITS 20
+
+/*
+ * Returns a list organized in an intermediate format suited
+ * to chaining of merge() calls: null-terminated, no reserved or
+ * sentinel head node, "prev" links not maintained.
+ */
+static struct list_head *merge(void *priv,
+ int (*cmp)(void *priv, struct list_head *a,
+ struct list_head *b),
+ struct list_head *a, struct list_head *b)
+{
+ struct list_head head, *tail = &head;
+
+ while (a && b) {
+ /* if equal, take 'a' -- important for sort stability */
+ if ((*cmp)(priv, a, b) <= 0) {
+ tail->next = a;
+ a = a->next;
+ } else {
+ tail->next = b;
+ b = b->next;
+ }
+ tail = tail->next;
+ }
+ tail->next = a?:b;
+ return head.next;
+}
+
+/*
+ * Combine final list merge with restoration of standard doubly-linked
+ * list structure. This approach duplicates code from merge(), but
+ * runs faster than the tidier alternatives of either a separate final
+ * prev-link restoration pass, or maintaining the prev links
+ * throughout.
+ */
+static void merge_and_restore_back_links(void *priv,
+ int (*cmp)(void *priv, struct list_head *a,
+ struct list_head *b),
+ struct list_head *head,
+ struct list_head *a, struct list_head *b)
+{
+ struct list_head *tail = head;
+
+ while (a && b) {
+ /* if equal, take 'a' -- important for sort stability */
+ if ((*cmp)(priv, a, b) <= 0) {
+ tail->next = a;
+ a->prev = tail;
+ a = a->next;
+ } else {
+ tail->next = b;
+ b->prev = tail;
+ b = b->next;
+ }
+ tail = tail->next;
+ }
+ tail->next = a ? : b;
+
+ do {
+ /*
+ * In worst cases this loop may run many iterations.
+ * Continue callbacks to the client even though no
+ * element comparison is needed, so the client's cmp()
+ * routine can invoke cond_resched() periodically.
+ */
+ (*cmp)(priv, tail, tail);
+
+ tail->next->prev = tail;
+ tail = tail->next;
+ } while (tail->next);
+
+ tail->next = head;
+ head->prev = tail;
+}
+
/**
- * list_sort - sort a list.
- * @priv: private data, passed to @cmp
+ * list_sort - sort a list
+ * @priv: private data, opaque to list_sort(), passed to @cmp
* @head: the list to sort
* @cmp: the elements comparison function
*
- * This function has been implemented by Mark J Roberts <mjr@znex.org>. It
- * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted
- * in ascending order.
+ * This function implements "merge sort", which has O(nlog(n))
+ * complexity.
*
- * The comparison function @cmp is supposed to return a negative value if @a is
- * less than @b, and a positive value if @a is greater than @b. If @a and @b
- * are equivalent, then it does not matter what this function returns.
+ * The comparison function @cmp must return a negative value if @a
+ * should sort before @b, and a positive value if @a should sort after
+ * @b. If @a and @b are equivalent, and their original relative
+ * ordering is to be preserved, @cmp must return 0.
*/
void list_sort(void *priv, struct list_head *head,
- int (*cmp)(void *priv, struct list_head *a,
- struct list_head *b))
+ int (*cmp)(void *priv, struct list_head *a,
+ struct list_head *b))
{
- struct list_head *p, *q, *e, *list, *tail, *oldhead;
- int insize, nmerges, psize, qsize, i;
+ struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
+ -- last slot is a sentinel */
+ int lev; /* index into part[] */
+ int max_lev = 0;
+ struct list_head *list;
if (list_empty(head))
return;
+ memset(part, 0, sizeof(part));
+
+ head->prev->next = NULL;
list = head->next;
- list_del(head);
- insize = 1;
- for (;;) {
- p = oldhead = list;
- list = tail = NULL;
- nmerges = 0;
-
- while (p) {
- nmerges++;
- q = p;
- psize = 0;
- for (i = 0; i < insize; i++) {
- psize++;
- q = q->next == oldhead ? NULL : q->next;
- if (!q)
- break;
- }
- qsize = insize;
- while (psize > 0 || (qsize > 0 && q)) {
- if (!psize) {
- e = q;
- q = q->next;
- qsize--;
- if (q == oldhead)
- q = NULL;
- } else if (!qsize || !q) {
- e = p;
- p = p->next;
- psize--;
- if (p == oldhead)
- p = NULL;
- } else if (cmp(priv, p, q) <= 0) {
- e = p;
- p = p->next;
- psize--;
- if (p == oldhead)
- p = NULL;
- } else {
- e = q;
- q = q->next;
- qsize--;
- if (q == oldhead)
- q = NULL;
- }
- if (tail)
- tail->next = e;
- else
- list = e;
- e->prev = tail;
- tail = e;
+ while (list) {
+ struct list_head *cur = list;
+ list = list->next;
+ cur->next = NULL;
+
+ for (lev = 0; part[lev]; lev++) {
+ cur = merge(priv, cmp, part[lev], cur);
+ part[lev] = NULL;
+ }
+ if (lev > max_lev) {
+ if (unlikely(lev >= ARRAY_SIZE(part)-1)) {
+ printk_once(KERN_DEBUG "list passed to"
+ " list_sort() too long for"
+ " efficiency\n");
+ lev--;
}
- p = q;
+ max_lev = lev;
}
+ part[lev] = cur;
+ }
- tail->next = list;
- list->prev = tail;
+ for (lev = 0; lev < max_lev; lev++)
+ if (part[lev])
+ list = merge(priv, cmp, part[lev], list);
- if (nmerges <= 1)
- break;
+ merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
+}
+EXPORT_SYMBOL(list_sort);
- insize *= 2;
- }
+#ifdef DEBUG_LIST_SORT
+struct debug_el {
+ struct list_head l_h;
+ int value;
+ unsigned serial;
+};
- head->next = list;
- head->prev = list->prev;
- list->prev->next = head;
- list->prev = head;
+static int cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+ return container_of(a, struct debug_el, l_h)->value
+ - container_of(b, struct debug_el, l_h)->value;
}
-EXPORT_SYMBOL(list_sort);
+/*
+ * The pattern of set bits in the list length determines which cases
+ * are hit in list_sort().
+ */
+#define LIST_SORT_TEST_LENGTH (512+128+2) /* not including head */
+
+static int __init list_sort_test(void)
+{
+ int i, r = 1, count;
+ struct list_head *head = kmalloc(sizeof(*head), GFP_KERNEL);
+ struct list_head *cur;
+
+ printk(KERN_WARNING "testing list_sort()\n");
+
+ cur = head;
+ for (i = 0; i < LIST_SORT_TEST_LENGTH; i++) {
+ struct debug_el *el = kmalloc(sizeof(*el), GFP_KERNEL);
+ BUG_ON(!el);
+ /* force some equivalencies */
+ el->value = (r = (r * 725861) % 6599) % (LIST_SORT_TEST_LENGTH/3);
+ el->serial = i;
+
+ el->l_h.prev = cur;
+ cur->next = &el->l_h;
+ cur = cur->next;
+ }
+ head->prev = cur;
+
+ list_sort(NULL, head, cmp);
+
+ count = 1;
+ for (cur = head->next; cur->next != head; cur = cur->next) {
+ struct debug_el *el = container_of(cur, struct debug_el, l_h);
+ int cmp_result = cmp(NULL, cur, cur->next);
+ if (cur->next->prev != cur) {
+ printk(KERN_EMERG "list_sort() returned "
+ "a corrupted list!\n");
+ return 1;
+ } else if (cmp_result > 0) {
+ printk(KERN_EMERG "list_sort() failed to sort!\n");
+ return 1;
+ } else if (cmp_result == 0 &&
+ el->serial >= container_of(cur->next,
+ struct debug_el, l_h)->serial) {
+ printk(KERN_EMERG "list_sort() failed to preserve order"
+ " of equivalent elements!\n");
+ return 1;
+ }
+ kfree(cur->prev);
+ count++;
+ }
+ kfree(cur);
+ if (count != LIST_SORT_TEST_LENGTH) {
+ printk(KERN_EMERG "list_sort() returned list of"
+ "different length!\n");
+ return 1;
+ }
+ return 0;
+}
+module_init(list_sort_test);
+#endif
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 6b9670d6bbf..2a087e0f986 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
-#include <linux/gfp.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/rcupdate.h>
@@ -556,6 +555,10 @@ EXPORT_SYMBOL(radix_tree_tag_clear);
*
* 0: tag not present or not set
* 1: tag set
+ *
+ * Note that the return value of this function may not be relied on, even if
+ * the RCU lock is held, unless tag modification and node deletion are excluded
+ * from concurrency.
*/
int radix_tree_tag_get(struct radix_tree_root *root,
unsigned long index, unsigned int tag)
@@ -596,12 +599,8 @@ int radix_tree_tag_get(struct radix_tree_root *root,
*/
if (!tag_get(node, tag, offset))
saw_unset_tag = 1;
- if (height == 1) {
- int ret = tag_get(node, tag, offset);
-
- BUG_ON(ret && saw_unset_tag);
- return !!ret;
- }
+ if (height == 1)
+ return !!tag_get(node, tag, offset);
node = rcu_dereference_raw(node->slots[offset]);
shift -= RADIX_TREE_MAP_SHIFT;
height--;
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
index 09f5ce1810d..027a03f4c56 100644
--- a/lib/ratelimit.c
+++ b/lib/ratelimit.c
@@ -16,9 +16,14 @@
/*
* __ratelimit - rate limiting
* @rs: ratelimit_state data
+ * @func: name of calling function
*
- * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks
- * in every @rs->ratelimit_jiffies
+ * This enforces a rate limit: not more than @rs->burst callbacks
+ * in every @rs->interval
+ *
+ * RETURNS:
+ * 0 means callbacks will be suppressed.
+ * 1 means go ahead and do it.
*/
int ___ratelimit(struct ratelimit_state *rs, const char *func)
{
@@ -35,7 +40,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
* the entity that is holding the lock already:
*/
if (!spin_trylock_irqsave(&rs->lock, flags))
- return 1;
+ return 0;
if (!rs->begin)
rs->begin = jiffies;
diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c
index ccf95bff798..ffc9fc7f3b0 100644
--- a/lib/rwsem-spinlock.c
+++ b/lib/rwsem-spinlock.c
@@ -143,13 +143,14 @@ void __sched __down_read(struct rw_semaphore *sem)
{
struct rwsem_waiter waiter;
struct task_struct *tsk;
+ unsigned long flags;
- spin_lock_irq(&sem->wait_lock);
+ spin_lock_irqsave(&sem->wait_lock, flags);
if (sem->activity >= 0 && list_empty(&sem->wait_list)) {
/* granted */
sem->activity++;
- spin_unlock_irq(&sem->wait_lock);
+ spin_unlock_irqrestore(&sem->wait_lock, flags);
goto out;
}
@@ -164,7 +165,7 @@ void __sched __down_read(struct rw_semaphore *sem)
list_add_tail(&waiter.list, &sem->wait_list);
/* we don't need to touch the semaphore struct anymore */
- spin_unlock_irq(&sem->wait_lock);
+ spin_unlock_irqrestore(&sem->wait_lock, flags);
/* wait to be given the lock */
for (;;) {
@@ -209,13 +210,14 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
{
struct rwsem_waiter waiter;
struct task_struct *tsk;
+ unsigned long flags;
- spin_lock_irq(&sem->wait_lock);
+ spin_lock_irqsave(&sem->wait_lock, flags);
if (sem->activity == 0 && list_empty(&sem->wait_list)) {
/* granted */
sem->activity = -1;
- spin_unlock_irq(&sem->wait_lock);
+ spin_unlock_irqrestore(&sem->wait_lock, flags);
goto out;
}
@@ -230,7 +232,7 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
list_add_tail(&waiter.list, &sem->wait_list);
/* we don't need to touch the semaphore struct anymore */
- spin_unlock_irq(&sem->wait_lock);
+ spin_unlock_irqrestore(&sem->wait_lock, flags);
/* wait to be given the lock */
for (;;) {
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 0d475d8167b..9afa25b52a8 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -7,6 +7,7 @@
* Version 2. See the file COPYING for more details.
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/highmem.h>
diff --git a/lib/show_mem.c b/lib/show_mem.c
index 238e72a18ce..fdc77c82f92 100644
--- a/lib/show_mem.c
+++ b/lib/show_mem.c
@@ -15,7 +15,7 @@ void show_mem(void)
unsigned long total = 0, reserved = 0, shared = 0,
nonshared = 0, highmem = 0;
- printk(KERN_INFO "Mem-Info:\n");
+ printk("Mem-Info:\n");
show_free_areas();
for_each_online_pgdat(pgdat) {
@@ -49,15 +49,15 @@ void show_mem(void)
pgdat_resize_unlock(pgdat, &flags);
}
- printk(KERN_INFO "%lu pages RAM\n", total);
+ printk("%lu pages RAM\n", total);
#ifdef CONFIG_HIGHMEM
- printk(KERN_INFO "%lu pages HighMem\n", highmem);
+ printk("%lu pages HighMem\n", highmem);
#endif
- printk(KERN_INFO "%lu pages reserved\n", reserved);
- printk(KERN_INFO "%lu pages shared\n", shared);
- printk(KERN_INFO "%lu pages non-shared\n", nonshared);
+ printk("%lu pages reserved\n", reserved);
+ printk("%lu pages shared\n", shared);
+ printk("%lu pages non-shared\n", nonshared);
#ifdef CONFIG_QUICKLIST
- printk(KERN_INFO "%lu pages in pagetable cache\n",
+ printk("%lu pages in pagetable cache\n",
quicklist_total_size());
#endif
}
diff --git a/lib/string.c b/lib/string.c
index a1cdcfcc42d..f71bead1be3 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -36,25 +36,21 @@ int strnicmp(const char *s1, const char *s2, size_t len)
/* Yes, Virginia, it had better be unsigned */
unsigned char c1, c2;
- c1 = c2 = 0;
- if (len) {
- do {
- c1 = *s1;
- c2 = *s2;
- s1++;
- s2++;
- if (!c1)
- break;
- if (!c2)
- break;
- if (c1 == c2)
- continue;
- c1 = tolower(c1);
- c2 = tolower(c2);
- if (c1 != c2)
- break;
- } while (--len);
- }
+ if (!len)
+ return 0;
+
+ do {
+ c1 = *s1++;
+ c2 = *s2++;
+ if (!c1 || !c2)
+ break;
+ if (c1 == c2)
+ continue;
+ c1 = tolower(c1);
+ c2 = tolower(c2);
+ if (c1 != c2)
+ break;
+ } while (--len);
return (int)c1 - (int)c2;
}
EXPORT_SYMBOL(strnicmp);
@@ -693,13 +689,13 @@ EXPORT_SYMBOL(strstr);
*/
char *strnstr(const char *s1, const char *s2, size_t len)
{
- size_t l1 = len, l2;
+ size_t l2;
l2 = strlen(s2);
if (!l2)
return (char *)s1;
- while (l1 >= l2) {
- l1--;
+ while (len >= l2) {
+ len--;
if (!memcmp(s1, s2, l2))
return (char *)s1;
s1++;
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 437eedb5a53..5fddf720da7 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -28,6 +28,7 @@
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/highmem.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/dma.h>
diff --git a/lib/textsearch.c b/lib/textsearch.c
index 9fbcb44c554..d608331b3e4 100644
--- a/lib/textsearch.c
+++ b/lib/textsearch.c
@@ -103,6 +103,7 @@
#include <linux/rcupdate.h>
#include <linux/err.h>
#include <linux/textsearch.h>
+#include <linux/slab.h>
static LIST_HEAD(ts_ops);
static DEFINE_SPINLOCK(ts_mod_lock);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index af4aaa6c36f..46d34b0b74a 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -118,6 +118,7 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base)
return simple_strtoull(cp, endp, base);
}
+EXPORT_SYMBOL(simple_strtoll);
/**
* strict_strtoul - convert a string to an unsigned long strictly
@@ -381,8 +382,8 @@ static noinline char *put_dec(char *buf, unsigned long long num)
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
-#define SMALL 32 /* Must be 32 == 0x20 */
-#define SPECIAL 64 /* 0x */
+#define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */
+#define SPECIAL 64 /* prefix hex with "0x", octal with "0" */
enum format_type {
FORMAT_TYPE_NONE, /* Just a string part */
@@ -408,12 +409,12 @@ enum format_type {
};
struct printf_spec {
- enum format_type type;
- int flags; /* flags to number() */
- int field_width; /* width of output field */
- int base;
- int precision; /* # of digits/chars */
- int qualifier;
+ u8 type; /* format_type enum */
+ u8 flags; /* flags to number() */
+ u8 base; /* number base, 8, 10 or 16 only */
+ u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */
+ s16 field_width; /* width of output field */
+ s16 precision; /* # of digits/chars */
};
static char *number(char *buf, char *end, unsigned long long num,
@@ -597,22 +598,35 @@ static char *resource_string(char *buf, char *end, struct resource *res,
#ifndef MEM_RSRC_PRINTK_SIZE
#define MEM_RSRC_PRINTK_SIZE 10
#endif
- struct printf_spec hex_spec = {
+ static const struct printf_spec io_spec = {
.base = 16,
+ .field_width = IO_RSRC_PRINTK_SIZE,
.precision = -1,
.flags = SPECIAL | SMALL | ZEROPAD,
};
- struct printf_spec dec_spec = {
+ static const struct printf_spec mem_spec = {
+ .base = 16,
+ .field_width = MEM_RSRC_PRINTK_SIZE,
+ .precision = -1,
+ .flags = SPECIAL | SMALL | ZEROPAD,
+ };
+ static const struct printf_spec bus_spec = {
+ .base = 16,
+ .field_width = 2,
+ .precision = -1,
+ .flags = SMALL | ZEROPAD,
+ };
+ static const struct printf_spec dec_spec = {
.base = 10,
.precision = -1,
.flags = 0,
};
- struct printf_spec str_spec = {
+ static const struct printf_spec str_spec = {
.field_width = -1,
.precision = 10,
.flags = LEFT,
};
- struct printf_spec flag_spec = {
+ static const struct printf_spec flag_spec = {
.base = 16,
.precision = -1,
.flags = SPECIAL | SMALL,
@@ -622,47 +636,48 @@ static char *resource_string(char *buf, char *end, struct resource *res,
* 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
#define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4)
#define FLAG_BUF_SIZE (2 * sizeof(res->flags))
-#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref disabled]")
+#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]")
#define RAW_BUF_SIZE sizeof("[mem - flags 0x]")
char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
char *p = sym, *pend = sym + sizeof(sym);
- int size = -1, addr = 0;
int decode = (fmt[0] == 'R') ? 1 : 0;
-
- if (res->flags & IORESOURCE_IO) {
- size = IO_RSRC_PRINTK_SIZE;
- addr = 1;
- } else if (res->flags & IORESOURCE_MEM) {
- size = MEM_RSRC_PRINTK_SIZE;
- addr = 1;
- }
+ const struct printf_spec *specp;
*p++ = '[';
- if (res->flags & IORESOURCE_IO)
+ if (res->flags & IORESOURCE_IO) {
p = string(p, pend, "io ", str_spec);
- else if (res->flags & IORESOURCE_MEM)
+ specp = &io_spec;
+ } else if (res->flags & IORESOURCE_MEM) {
p = string(p, pend, "mem ", str_spec);
- else if (res->flags & IORESOURCE_IRQ)
+ specp = &mem_spec;
+ } else if (res->flags & IORESOURCE_IRQ) {
p = string(p, pend, "irq ", str_spec);
- else if (res->flags & IORESOURCE_DMA)
+ specp = &dec_spec;
+ } else if (res->flags & IORESOURCE_DMA) {
p = string(p, pend, "dma ", str_spec);
- else {
+ specp = &dec_spec;
+ } else if (res->flags & IORESOURCE_BUS) {
+ p = string(p, pend, "bus ", str_spec);
+ specp = &bus_spec;
+ } else {
p = string(p, pend, "??? ", str_spec);
+ specp = &mem_spec;
decode = 0;
}
- hex_spec.field_width = size;
- p = number(p, pend, res->start, addr ? hex_spec : dec_spec);
+ p = number(p, pend, res->start, *specp);
if (res->start != res->end) {
*p++ = '-';
- p = number(p, pend, res->end, addr ? hex_spec : dec_spec);
+ p = number(p, pend, res->end, *specp);
}
if (decode) {
if (res->flags & IORESOURCE_MEM_64)
p = string(p, pend, " 64bit", str_spec);
if (res->flags & IORESOURCE_PREFETCH)
p = string(p, pend, " pref", str_spec);
+ if (res->flags & IORESOURCE_WINDOW)
+ p = string(p, pend, " window", str_spec);
if (res->flags & IORESOURCE_DISABLED)
p = string(p, pend, " disabled", str_spec);
} else {
@@ -1333,7 +1348,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
break;
case FORMAT_TYPE_NRCHARS: {
- int qualifier = spec.qualifier;
+ u8 qualifier = spec.qualifier;
if (qualifier == 'l') {
long *ip = va_arg(args, long *);
@@ -1619,7 +1634,7 @@ do { \
case FORMAT_TYPE_NRCHARS: {
/* skip %n 's argument */
- int qualifier = spec.qualifier;
+ u8 qualifier = spec.qualifier;
void *skip_arg;
if (qualifier == 'l')
skip_arg = va_arg(args, long *);
@@ -1885,7 +1900,9 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
char *next;
char digit;
int num = 0;
- int qualifier, base, field_width;
+ u8 qualifier;
+ u8 base;
+ s16 field_width;
bool is_sign;
while (*fmt && *str) {
@@ -1963,7 +1980,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
{
char *s = (char *)va_arg(args, char *);
if (field_width == -1)
- field_width = INT_MAX;
+ field_width = SHORT_MAX;
/* first, skip leading white space in buffer */
str = skip_spaces(str);
diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c
index 215447c5526..2c13ecc5bb2 100644
--- a/lib/zlib_inflate/inffast.c
+++ b/lib/zlib_inflate/inffast.c
@@ -8,21 +8,6 @@
#include "inflate.h"
#include "inffast.h"
-/* Only do the unaligned "Faster" variant when
- * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is set
- *
- * On powerpc, it won't be as we don't include autoconf.h
- * automatically for the boot wrapper, which is intended as
- * we run in an environment where we may not be able to deal
- * with (even rare) alignment faults. In addition, we do not
- * define __KERNEL__ for arch/powerpc/boot unlike x86
- */
-
-#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-#include <asm/unaligned.h>
-#include <asm/byteorder.h>
-#endif
-
#ifndef ASMINF
/* Allow machine dependent optimization for post-increment or pre-increment.
@@ -36,14 +21,31 @@
- Pentium III (Anderson)
- M68060 (Nikl)
*/
+union uu {
+ unsigned short us;
+ unsigned char b[2];
+};
+
+/* Endian independed version */
+static inline unsigned short
+get_unaligned16(const unsigned short *p)
+{
+ union uu mm;
+ unsigned char *b = (unsigned char *)p;
+
+ mm.b[0] = b[0];
+ mm.b[1] = b[1];
+ return mm.us;
+}
+
#ifdef POSTINC
# define OFF 0
# define PUP(a) *(a)++
-# define UP_UNALIGNED(a) get_unaligned((a)++)
+# define UP_UNALIGNED(a) get_unaligned16((a)++)
#else
# define OFF 1
# define PUP(a) *++(a)
-# define UP_UNALIGNED(a) get_unaligned(++(a))
+# define UP_UNALIGNED(a) get_unaligned16(++(a))
#endif
/*
@@ -256,7 +258,6 @@ void inflate_fast(z_streamp strm, unsigned start)
}
}
else {
-#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
unsigned short *sout;
unsigned long loops;
@@ -274,22 +275,25 @@ void inflate_fast(z_streamp strm, unsigned start)
sfrom = (unsigned short *)(from - OFF);
loops = len >> 1;
do
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ PUP(sout) = PUP(sfrom);
+#else
PUP(sout) = UP_UNALIGNED(sfrom);
+#endif
while (--loops);
out = (unsigned char *)sout + OFF;
from = (unsigned char *)sfrom + OFF;
} else { /* dist == 1 or dist == 2 */
unsigned short pat16;
- pat16 = *(sout-2+2*OFF);
- if (dist == 1)
-#if defined(__BIG_ENDIAN)
- pat16 = (pat16 & 0xff) | ((pat16 & 0xff) << 8);
-#elif defined(__LITTLE_ENDIAN)
- pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00) >> 8);
-#else
-#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
-#endif
+ pat16 = *(sout-1+OFF);
+ if (dist == 1) {
+ union uu mm;
+ /* copy one char pattern to both bytes */
+ mm.us = pat16;
+ mm.b[0] = mm.b[1];
+ pat16 = mm.us;
+ }
loops = len >> 1;
do
PUP(sout) = pat16;
@@ -298,20 +302,6 @@ void inflate_fast(z_streamp strm, unsigned start)
}
if (len & 1)
PUP(out) = PUP(from);
-#else /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
- from = out - dist; /* copy direct from output */
- do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- } while (len > 2);
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
-#endif /* !CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
diff --git a/mm/Makefile b/mm/Makefile
index 7a68d2ab556..6c2a73a54a4 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -33,7 +33,11 @@ obj-$(CONFIG_FAILSLAB) += failslab.o
obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
obj-$(CONFIG_FS_XIP) += filemap_xip.o
obj-$(CONFIG_MIGRATION) += migrate.o
-obj-$(CONFIG_SMP) += percpu.o
+ifdef CONFIG_SMP
+obj-y += percpu.o
+else
+obj-y += percpu_up.o
+endif
obj-$(CONFIG_QUICKLIST) += quicklist.o
obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 0e8ca034770..707d0dc6da0 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -11,6 +11,8 @@
#include <linux/writeback.h>
#include <linux/device.h>
+static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
+
void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
{
}
@@ -25,6 +27,11 @@ struct backing_dev_info default_backing_dev_info = {
};
EXPORT_SYMBOL_GPL(default_backing_dev_info);
+struct backing_dev_info noop_backing_dev_info = {
+ .name = "noop",
+};
+EXPORT_SYMBOL_GPL(noop_backing_dev_info);
+
static struct class *bdi_class;
/*
@@ -227,6 +234,9 @@ static struct device_attribute bdi_dev_attrs[] = {
static __init int bdi_class_init(void)
{
bdi_class = class_create(THIS_MODULE, "bdi");
+ if (IS_ERR(bdi_class))
+ return PTR_ERR(bdi_class);
+
bdi_class->dev_attrs = bdi_dev_attrs;
bdi_debug_init();
return 0;
@@ -712,6 +722,33 @@ void bdi_destroy(struct backing_dev_info *bdi)
}
EXPORT_SYMBOL(bdi_destroy);
+/*
+ * For use from filesystems to quickly init and register a bdi associated
+ * with dirty writeback
+ */
+int bdi_setup_and_register(struct backing_dev_info *bdi, char *name,
+ unsigned int cap)
+{
+ char tmp[32];
+ int err;
+
+ bdi->name = name;
+ bdi->capabilities = cap;
+ err = bdi_init(bdi);
+ if (err)
+ return err;
+
+ sprintf(tmp, "%.28s%s", name, "-%d");
+ err = bdi_register(bdi, NULL, tmp, atomic_long_inc_return(&bdi_seq));
+ if (err) {
+ bdi_destroy(bdi);
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(bdi_setup_and_register);
+
static wait_queue_head_t congestion_wqh[2] = {
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
diff --git a/mm/bootmem.c b/mm/bootmem.c
index d7c791ef003..58c66cc5056 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -10,6 +10,7 @@
*/
#include <linux/init.h>
#include <linux/pfn.h>
+#include <linux/slab.h>
#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/kmemleak.h>
@@ -180,19 +181,12 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end)
end_aligned = end & ~(BITS_PER_LONG - 1);
if (end_aligned <= start_aligned) {
-#if 1
- printk(KERN_DEBUG " %lx - %lx\n", start, end);
-#endif
for (i = start; i < end; i++)
__free_pages_bootmem(pfn_to_page(i), 0);
return;
}
-#if 1
- printk(KERN_DEBUG " %lx %lx - %lx %lx\n",
- start, start_aligned, end_aligned, end);
-#endif
for (i = start; i < start_aligned; i++)
__free_pages_bootmem(pfn_to_page(i), 0);
@@ -310,9 +304,22 @@ unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
unsigned long __init free_all_bootmem(void)
{
#ifdef CONFIG_NO_BOOTMEM
- return free_all_memory_core_early(NODE_DATA(0)->node_id);
+ /*
+ * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
+ * because in some case like Node0 doesnt have RAM installed
+ * low ram will be on Node1
+ * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
+ * will be used instead of only Node0 related
+ */
+ return free_all_memory_core_early(MAX_NUMNODES);
#else
- return free_all_bootmem_core(NODE_DATA(0)->bdata);
+ unsigned long total_pages = 0;
+ bootmem_data_t *bdata;
+
+ list_for_each_entry(bdata, &bdata_list, list)
+ total_pages += free_all_bootmem_core(bdata);
+
+ return total_pages;
#endif
}
@@ -428,9 +435,6 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
{
#ifdef CONFIG_NO_BOOTMEM
free_early(physaddr, physaddr + size);
-#if 0
- printk(KERN_DEBUG "free %lx %lx\n", physaddr, size);
-#endif
#else
unsigned long start, end;
@@ -456,9 +460,6 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
{
#ifdef CONFIG_NO_BOOTMEM
free_early(addr, addr + size);
-#if 0
- printk(KERN_DEBUG "free %lx %lx\n", addr, size);
-#endif
#else
unsigned long start, end;
diff --git a/mm/bounce.c b/mm/bounce.c
index a2b76a588e3..13b6dad1eed 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -6,6 +6,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/swap.h>
+#include <linux/gfp.h>
#include <linux/bio.h>
#include <linux/pagemap.h>
#include <linux/mempool.h>
diff --git a/mm/fadvise.c b/mm/fadvise.c
index e43359214f6..8d723c9e8b7 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -77,12 +77,20 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
switch (advice) {
case POSIX_FADV_NORMAL:
file->f_ra.ra_pages = bdi->ra_pages;
+ spin_lock(&file->f_lock);
+ file->f_mode &= ~FMODE_RANDOM;
+ spin_unlock(&file->f_lock);
break;
case POSIX_FADV_RANDOM:
- file->f_ra.ra_pages = 0;
+ spin_lock(&file->f_lock);
+ file->f_mode |= FMODE_RANDOM;
+ spin_unlock(&file->f_lock);
break;
case POSIX_FADV_SEQUENTIAL:
file->f_ra.ra_pages = bdi->ra_pages * 2;
+ spin_lock(&file->f_lock);
+ file->f_mode &= ~FMODE_RANDOM;
+ spin_unlock(&file->f_lock);
break;
case POSIX_FADV_WILLNEED:
if (!mapping->a_ops->readpage) {
diff --git a/mm/failslab.c b/mm/failslab.c
index 9339de5f0a9..c5f88f240dd 100644
--- a/mm/failslab.c
+++ b/mm/failslab.c
@@ -1,18 +1,21 @@
#include <linux/fault-inject.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
static struct {
struct fault_attr attr;
u32 ignore_gfp_wait;
+ int cache_filter;
#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
struct dentry *ignore_gfp_wait_file;
+ struct dentry *cache_filter_file;
#endif
} failslab = {
.attr = FAULT_ATTR_INITIALIZER,
.ignore_gfp_wait = 1,
+ .cache_filter = 0,
};
-bool should_failslab(size_t size, gfp_t gfpflags)
+bool should_failslab(size_t size, gfp_t gfpflags, unsigned long cache_flags)
{
if (gfpflags & __GFP_NOFAIL)
return false;
@@ -20,6 +23,9 @@ bool should_failslab(size_t size, gfp_t gfpflags)
if (failslab.ignore_gfp_wait && (gfpflags & __GFP_WAIT))
return false;
+ if (failslab.cache_filter && !(cache_flags & SLAB_FAILSLAB))
+ return false;
+
return should_fail(&failslab.attr, size);
}
@@ -30,7 +36,6 @@ static int __init setup_failslab(char *str)
__setup("failslab=", setup_failslab);
#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
-
static int __init failslab_debugfs_init(void)
{
mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
@@ -46,8 +51,14 @@ static int __init failslab_debugfs_init(void)
debugfs_create_bool("ignore-gfp-wait", mode, dir,
&failslab.ignore_gfp_wait);
- if (!failslab.ignore_gfp_wait_file) {
+ failslab.cache_filter_file =
+ debugfs_create_bool("cache-filter", mode, dir,
+ &failslab.cache_filter);
+
+ if (!failslab.ignore_gfp_wait_file ||
+ !failslab.cache_filter_file) {
err = -ENOMEM;
+ debugfs_remove(failslab.cache_filter_file);
debugfs_remove(failslab.ignore_gfp_wait_file);
cleanup_fault_attr_dentries(&failslab.attr);
}
diff --git a/mm/filemap.c b/mm/filemap.c
index 148b52a5bb7..140ebda9640 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -10,13 +10,13 @@
* the NFS filesystem used to do this differently, for example)
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/compiler.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/aio.h>
#include <linux/capability.h>
#include <linux/kernel_stat.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/mman.h>
@@ -1986,7 +1986,7 @@ EXPORT_SYMBOL(iov_iter_single_seg_count);
inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk)
{
struct inode *inode = file->f_mapping->host;
- unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+ unsigned long limit = rlimit(RLIMIT_FSIZE);
if (unlikely(*pos < 0))
return -EINVAL;
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 1888b2d71bb..83364df74a3 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -17,6 +17,7 @@
#include <linux/sched.h>
#include <linux/seqlock.h>
#include <linux/mutex.h>
+#include <linux/gfp.h>
#include <asm/tlbflush.h>
#include <asm/io.h>
@@ -194,7 +195,7 @@ retry:
flush_cache_page(vma, address, pte_pfn(*pte));
pteval = ptep_clear_flush_notify(vma, address, pte);
page_remove_rmap(page);
- dec_mm_counter(mm, file_rss);
+ dec_mm_counter(mm, MM_FILEPAGES);
BUG_ON(pte_dirty(pteval));
pte_unmap_unlock(pte, ptl);
page_cache_release(page);
diff --git a/mm/fremap.c b/mm/fremap.c
index b6ec85abbb3..46f5dacf90a 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -40,7 +40,7 @@ static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
page_remove_rmap(page);
page_cache_release(page);
update_hiwater_rss(mm);
- dec_mm_counter(mm, file_rss);
+ dec_mm_counter(mm, MM_FILEPAGES);
}
} else {
if (!pte_file(pte))
diff --git a/mm/highmem.c b/mm/highmem.c
index 9c1e627f282..bed8a8bfd01 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -220,7 +220,7 @@ EXPORT_SYMBOL(kmap_high);
* @page: &struct page to pin
*
* Returns the page's current virtual memory address, or NULL if no mapping
- * exists. When and only when a non null address is returned then a
+ * exists. If and only if a non null address is returned then a
* matching call to kunmap_high() is necessary.
*
* This can be called from any context.
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 3a5aeb37c11..ffbdfc86aed 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2,7 +2,6 @@
* Generic hugetlb support.
* (C) William Irwin, April 2004
*/
-#include <linux/gfp.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -18,6 +17,7 @@
#include <linux/mutex.h>
#include <linux/bootmem.h>
#include <linux/sysfs.h>
+#include <linux/slab.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -546,6 +546,7 @@ static void free_huge_page(struct page *page)
mapping = (struct address_space *) page_private(page);
set_page_private(page, 0);
+ page->mapping = NULL;
BUG_ON(page_count(page));
INIT_LIST_HEAD(&page->lru);
@@ -2447,8 +2448,10 @@ retry:
spin_lock(&inode->i_lock);
inode->i_blocks += blocks_per_huge_page(h);
spin_unlock(&inode->i_lock);
- } else
+ } else {
lock_page(page);
+ page->mapping = HUGETLB_POISON;
+ }
}
/*
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 5b069e4f5e4..2c0d032ac89 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -72,7 +72,6 @@
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/prio_tree.h>
-#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
diff --git a/mm/ksm.c b/mm/ksm.c
index 56a0da1f997..956880f2ff4 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -365,7 +365,7 @@ static int break_ksm(struct vm_area_struct *vma, unsigned long addr)
do {
cond_resched();
page = follow_page(vma, addr, FOLL_GET);
- if (!page)
+ if (IS_ERR_OR_NULL(page))
break;
if (PageKsm(page))
ret = handle_mm_fault(vma->vm_mm, vma, addr,
@@ -447,7 +447,7 @@ static struct page *get_mergeable_page(struct rmap_item *rmap_item)
goto out;
page = follow_page(vma, addr, FOLL_GET);
- if (!page)
+ if (IS_ERR_OR_NULL(page))
goto out;
if (PageAnon(page)) {
flush_anon_page(vma, page, addr);
@@ -751,7 +751,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
* page
*/
if (page_mapcount(page) + 1 + swapped != page_count(page)) {
- set_pte_at_notify(mm, addr, ptep, entry);
+ set_pte_at(mm, addr, ptep, entry);
goto out_unlock;
}
entry = pte_wrprotect(entry);
@@ -1086,7 +1086,7 @@ struct rmap_item *unstable_tree_search_insert(struct rmap_item *rmap_item,
cond_resched();
tree_rmap_item = rb_entry(*new, struct rmap_item, node);
tree_page = get_mergeable_page(tree_rmap_item);
- if (!tree_page)
+ if (IS_ERR_OR_NULL(tree_page))
return NULL;
/*
@@ -1294,7 +1294,7 @@ next_mm:
if (ksm_test_exit(mm))
break;
*page = follow_page(vma, ksm_scan.address, FOLL_GET);
- if (*page && PageAnon(*page)) {
+ if (!IS_ERR_OR_NULL(*page) && PageAnon(*page)) {
flush_anon_page(vma, *page, ksm_scan.address);
flush_dcache_page(*page);
rmap_item = get_next_rmap_item(slot,
@@ -1308,7 +1308,7 @@ next_mm:
up_read(&mm->mmap_sem);
return rmap_item;
}
- if (*page)
+ if (!IS_ERR_OR_NULL(*page))
put_page(*page);
ksm_scan.address += PAGE_SIZE;
cond_resched();
@@ -1367,7 +1367,7 @@ next_mm:
static void ksm_do_scan(unsigned int scan_npages)
{
struct rmap_item *rmap_item;
- struct page *page;
+ struct page *uninitialized_var(page);
while (scan_npages--) {
cond_resched();
@@ -1563,10 +1563,12 @@ int page_referenced_ksm(struct page *page, struct mem_cgroup *memcg,
again:
hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {
struct anon_vma *anon_vma = rmap_item->anon_vma;
+ struct anon_vma_chain *vmac;
struct vm_area_struct *vma;
spin_lock(&anon_vma->lock);
- list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+ list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+ vma = vmac->vma;
if (rmap_item->address < vma->vm_start ||
rmap_item->address >= vma->vm_end)
continue;
@@ -1614,10 +1616,12 @@ int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
again:
hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {
struct anon_vma *anon_vma = rmap_item->anon_vma;
+ struct anon_vma_chain *vmac;
struct vm_area_struct *vma;
spin_lock(&anon_vma->lock);
- list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+ list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+ vma = vmac->vma;
if (rmap_item->address < vma->vm_start ||
rmap_item->address >= vma->vm_end)
continue;
@@ -1664,10 +1668,12 @@ int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page *,
again:
hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {
struct anon_vma *anon_vma = rmap_item->anon_vma;
+ struct anon_vma_chain *vmac;
struct vm_area_struct *vma;
spin_lock(&anon_vma->lock);
- list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+ list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+ vma = vmac->vma;
if (rmap_item->address < vma->vm_start ||
rmap_item->address >= vma->vm_end)
continue;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 954032b80be..6c755de385f 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6,6 +6,10 @@
* Copyright 2007 OpenVZ SWsoft Inc
* Author: Pavel Emelianov <xemul@openvz.org>
*
+ * Memory thresholds
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Kirill A. Shutemov
+ *
* This program is free software; 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
@@ -21,6 +25,7 @@
#include <linux/memcontrol.h>
#include <linux/cgroup.h>
#include <linux/mm.h>
+#include <linux/hugetlb.h>
#include <linux/pagemap.h>
#include <linux/smp.h>
#include <linux/page-flags.h>
@@ -32,7 +37,10 @@
#include <linux/rbtree.h>
#include <linux/slab.h>
#include <linux/swap.h>
+#include <linux/swapops.h>
#include <linux/spinlock.h>
+#include <linux/eventfd.h>
+#include <linux/sort.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
@@ -55,7 +63,15 @@ static int really_do_swap_account __initdata = 1; /* for remember boot option*/
#define do_swap_account (0)
#endif
-#define SOFTLIMIT_EVENTS_THRESH (1000)
+/*
+ * Per memcg event counter is incremented at every pagein/pageout. This counter
+ * is used for trigger some periodic events. This is straightforward and better
+ * than using jiffies etc. to handle periodic memcg event.
+ *
+ * These values will be used as !((event) & ((1 <<(thresh)) - 1))
+ */
+#define THRESHOLDS_EVENTS_THRESH (7) /* once in 128 */
+#define SOFTLIMIT_EVENTS_THRESH (10) /* once in 1024 */
/*
* Statistics for memory cgroup.
@@ -69,62 +85,16 @@ enum mem_cgroup_stat_index {
MEM_CGROUP_STAT_FILE_MAPPED, /* # of pages charged as file rss */
MEM_CGROUP_STAT_PGPGIN_COUNT, /* # of pages paged in */
MEM_CGROUP_STAT_PGPGOUT_COUNT, /* # of pages paged out */
- MEM_CGROUP_STAT_EVENTS, /* sum of pagein + pageout for internal use */
MEM_CGROUP_STAT_SWAPOUT, /* # of pages, swapped out */
+ MEM_CGROUP_EVENTS, /* incremented at every pagein/pageout */
MEM_CGROUP_STAT_NSTATS,
};
struct mem_cgroup_stat_cpu {
s64 count[MEM_CGROUP_STAT_NSTATS];
-} ____cacheline_aligned_in_smp;
-
-struct mem_cgroup_stat {
- struct mem_cgroup_stat_cpu cpustat[0];
};
-static inline void
-__mem_cgroup_stat_reset_safe(struct mem_cgroup_stat_cpu *stat,
- enum mem_cgroup_stat_index idx)
-{
- stat->count[idx] = 0;
-}
-
-static inline s64
-__mem_cgroup_stat_read_local(struct mem_cgroup_stat_cpu *stat,
- enum mem_cgroup_stat_index idx)
-{
- return stat->count[idx];
-}
-
-/*
- * For accounting under irq disable, no need for increment preempt count.
- */
-static inline void __mem_cgroup_stat_add_safe(struct mem_cgroup_stat_cpu *stat,
- enum mem_cgroup_stat_index idx, int val)
-{
- stat->count[idx] += val;
-}
-
-static s64 mem_cgroup_read_stat(struct mem_cgroup_stat *stat,
- enum mem_cgroup_stat_index idx)
-{
- int cpu;
- s64 ret = 0;
- for_each_possible_cpu(cpu)
- ret += stat->cpustat[cpu].count[idx];
- return ret;
-}
-
-static s64 mem_cgroup_local_usage(struct mem_cgroup_stat *stat)
-{
- s64 ret;
-
- ret = mem_cgroup_read_stat(stat, MEM_CGROUP_STAT_CACHE);
- ret += mem_cgroup_read_stat(stat, MEM_CGROUP_STAT_RSS);
- return ret;
-}
-
/*
* per-zone information in memory controller.
*/
@@ -174,6 +144,22 @@ struct mem_cgroup_tree {
static struct mem_cgroup_tree soft_limit_tree __read_mostly;
+struct mem_cgroup_threshold {
+ struct eventfd_ctx *eventfd;
+ u64 threshold;
+};
+
+struct mem_cgroup_threshold_ary {
+ /* An array index points to threshold just below usage. */
+ atomic_t current_threshold;
+ /* Size of entries[] */
+ unsigned int size;
+ /* Array of thresholds */
+ struct mem_cgroup_threshold entries[0];
+};
+
+static void mem_cgroup_threshold(struct mem_cgroup *mem);
+
/*
* The memory controller data structure. The memory controller controls both
* page cache and RSS per cgroup. We would eventually like to provide
@@ -217,7 +203,7 @@ struct mem_cgroup {
* Should the accounting and control be hierarchical, per subtree?
*/
bool use_hierarchy;
- unsigned long last_oom_jiffies;
+ atomic_t oom_lock;
atomic_t refcnt;
unsigned int swappiness;
@@ -225,10 +211,48 @@ struct mem_cgroup {
/* set when res.limit == memsw.limit */
bool memsw_is_minimum;
+ /* protect arrays of thresholds */
+ struct mutex thresholds_lock;
+
+ /* thresholds for memory usage. RCU-protected */
+ struct mem_cgroup_threshold_ary *thresholds;
+
+ /* thresholds for mem+swap usage. RCU-protected */
+ struct mem_cgroup_threshold_ary *memsw_thresholds;
+
/*
- * statistics. This must be placed at the end of memcg.
+ * Should we move charges of a task when a task is moved into this
+ * mem_cgroup ? And what type of charges should we move ?
*/
- struct mem_cgroup_stat stat;
+ unsigned long move_charge_at_immigrate;
+
+ /*
+ * percpu counter.
+ */
+ struct mem_cgroup_stat_cpu *stat;
+};
+
+/* Stuffs for move charges at task migration. */
+/*
+ * Types of charges to be moved. "move_charge_at_immitgrate" is treated as a
+ * left-shifted bitmap of these types.
+ */
+enum move_type {
+ MOVE_CHARGE_TYPE_ANON, /* private anonymous page and swap of it */
+ NR_MOVE_TYPE,
+};
+
+/* "mc" and its members are protected by cgroup_mutex */
+static struct move_charge_struct {
+ struct mem_cgroup *from;
+ struct mem_cgroup *to;
+ unsigned long precharge;
+ unsigned long moved_charge;
+ unsigned long moved_swap;
+ struct task_struct *moving_task; /* a task moving charges */
+ wait_queue_head_t waitq; /* a waitq for other context */
+} mc = {
+ .waitq = __WAIT_QUEUE_HEAD_INITIALIZER(mc.waitq),
};
/*
@@ -371,23 +395,6 @@ mem_cgroup_remove_exceeded(struct mem_cgroup *mem,
spin_unlock(&mctz->lock);
}
-static bool mem_cgroup_soft_limit_check(struct mem_cgroup *mem)
-{
- bool ret = false;
- int cpu;
- s64 val;
- struct mem_cgroup_stat_cpu *cpustat;
-
- cpu = get_cpu();
- cpustat = &mem->stat.cpustat[cpu];
- val = __mem_cgroup_stat_read_local(cpustat, MEM_CGROUP_STAT_EVENTS);
- if (unlikely(val > SOFTLIMIT_EVENTS_THRESH)) {
- __mem_cgroup_stat_reset_safe(cpustat, MEM_CGROUP_STAT_EVENTS);
- ret = true;
- }
- put_cpu();
- return ret;
-}
static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page)
{
@@ -481,17 +488,31 @@ mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz)
return mz;
}
+static s64 mem_cgroup_read_stat(struct mem_cgroup *mem,
+ enum mem_cgroup_stat_index idx)
+{
+ int cpu;
+ s64 val = 0;
+
+ for_each_possible_cpu(cpu)
+ val += per_cpu(mem->stat->count[idx], cpu);
+ return val;
+}
+
+static s64 mem_cgroup_local_usage(struct mem_cgroup *mem)
+{
+ s64 ret;
+
+ ret = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_RSS);
+ ret += mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_CACHE);
+ return ret;
+}
+
static void mem_cgroup_swap_statistics(struct mem_cgroup *mem,
bool charge)
{
int val = (charge) ? 1 : -1;
- struct mem_cgroup_stat *stat = &mem->stat;
- struct mem_cgroup_stat_cpu *cpustat;
- int cpu = get_cpu();
-
- cpustat = &stat->cpustat[cpu];
- __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_SWAPOUT, val);
- put_cpu();
+ this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_SWAPOUT], val);
}
static void mem_cgroup_charge_statistics(struct mem_cgroup *mem,
@@ -499,24 +520,21 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem,
bool charge)
{
int val = (charge) ? 1 : -1;
- struct mem_cgroup_stat *stat = &mem->stat;
- struct mem_cgroup_stat_cpu *cpustat;
- int cpu = get_cpu();
- cpustat = &stat->cpustat[cpu];
+ preempt_disable();
+
if (PageCgroupCache(pc))
- __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_CACHE, val);
+ __this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_CACHE], val);
else
- __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_RSS, val);
+ __this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_RSS], val);
if (charge)
- __mem_cgroup_stat_add_safe(cpustat,
- MEM_CGROUP_STAT_PGPGIN_COUNT, 1);
+ __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_PGPGIN_COUNT]);
else
- __mem_cgroup_stat_add_safe(cpustat,
- MEM_CGROUP_STAT_PGPGOUT_COUNT, 1);
- __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_EVENTS, 1);
- put_cpu();
+ __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_PGPGOUT_COUNT]);
+ __this_cpu_inc(mem->stat->count[MEM_CGROUP_EVENTS]);
+
+ preempt_enable();
}
static unsigned long mem_cgroup_get_local_zonestat(struct mem_cgroup *mem,
@@ -534,6 +552,29 @@ static unsigned long mem_cgroup_get_local_zonestat(struct mem_cgroup *mem,
return total;
}
+static bool __memcg_event_check(struct mem_cgroup *mem, int event_mask_shift)
+{
+ s64 val;
+
+ val = this_cpu_read(mem->stat->count[MEM_CGROUP_EVENTS]);
+
+ return !(val & ((1 << event_mask_shift) - 1));
+}
+
+/*
+ * Check events in order.
+ *
+ */
+static void memcg_check_events(struct mem_cgroup *mem, struct page *page)
+{
+ /* threshold event is triggered in finer grain than soft limit */
+ if (unlikely(__memcg_event_check(mem, THRESHOLDS_EVENTS_THRESH))) {
+ mem_cgroup_threshold(mem);
+ if (unlikely(__memcg_event_check(mem, SOFTLIMIT_EVENTS_THRESH)))
+ mem_cgroup_update_tree(mem, page);
+ }
+}
+
static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
{
return container_of(cgroup_subsys_state(cont,
@@ -1000,7 +1041,7 @@ static int mem_cgroup_count_children_cb(struct mem_cgroup *mem, void *data)
}
/**
- * mem_cgroup_print_mem_info: Called from OOM with tasklist_lock held in read mode.
+ * mem_cgroup_print_oom_info: Called from OOM with tasklist_lock held in read mode.
* @memcg: The memory cgroup that went over limit
* @p: Task that is going to be killed
*
@@ -1174,7 +1215,7 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem,
}
}
}
- if (!mem_cgroup_local_usage(&victim->stat)) {
+ if (!mem_cgroup_local_usage(victim)) {
/* this cgroup's local usage == 0 */
css_put(&victim->css);
continue;
@@ -1205,32 +1246,102 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem,
return total;
}
-bool mem_cgroup_oom_called(struct task_struct *task)
+static int mem_cgroup_oom_lock_cb(struct mem_cgroup *mem, void *data)
{
- bool ret = false;
- struct mem_cgroup *mem;
- struct mm_struct *mm;
+ int *val = (int *)data;
+ int x;
+ /*
+ * Logically, we can stop scanning immediately when we find
+ * a memcg is already locked. But condidering unlock ops and
+ * creation/removal of memcg, scan-all is simple operation.
+ */
+ x = atomic_inc_return(&mem->oom_lock);
+ *val = max(x, *val);
+ return 0;
+}
+/*
+ * Check OOM-Killer is already running under our hierarchy.
+ * If someone is running, return false.
+ */
+static bool mem_cgroup_oom_lock(struct mem_cgroup *mem)
+{
+ int lock_count = 0;
- rcu_read_lock();
- mm = task->mm;
- if (!mm)
- mm = &init_mm;
- mem = mem_cgroup_from_task(rcu_dereference(mm->owner));
- if (mem && time_before(jiffies, mem->last_oom_jiffies + HZ/10))
- ret = true;
- rcu_read_unlock();
- return ret;
+ mem_cgroup_walk_tree(mem, &lock_count, mem_cgroup_oom_lock_cb);
+
+ if (lock_count == 1)
+ return true;
+ return false;
}
-static int record_last_oom_cb(struct mem_cgroup *mem, void *data)
+static int mem_cgroup_oom_unlock_cb(struct mem_cgroup *mem, void *data)
{
- mem->last_oom_jiffies = jiffies;
+ /*
+ * When a new child is created while the hierarchy is under oom,
+ * mem_cgroup_oom_lock() may not be called. We have to use
+ * atomic_add_unless() here.
+ */
+ atomic_add_unless(&mem->oom_lock, -1, 0);
return 0;
}
-static void record_last_oom(struct mem_cgroup *mem)
+static void mem_cgroup_oom_unlock(struct mem_cgroup *mem)
+{
+ mem_cgroup_walk_tree(mem, NULL, mem_cgroup_oom_unlock_cb);
+}
+
+static DEFINE_MUTEX(memcg_oom_mutex);
+static DECLARE_WAIT_QUEUE_HEAD(memcg_oom_waitq);
+
+/*
+ * try to call OOM killer. returns false if we should exit memory-reclaim loop.
+ */
+bool mem_cgroup_handle_oom(struct mem_cgroup *mem, gfp_t mask)
{
- mem_cgroup_walk_tree(mem, NULL, record_last_oom_cb);
+ DEFINE_WAIT(wait);
+ bool locked;
+
+ /* At first, try to OOM lock hierarchy under mem.*/
+ mutex_lock(&memcg_oom_mutex);
+ locked = mem_cgroup_oom_lock(mem);
+ /*
+ * Even if signal_pending(), we can't quit charge() loop without
+ * accounting. So, UNINTERRUPTIBLE is appropriate. But SIGKILL
+ * under OOM is always welcomed, use TASK_KILLABLE here.
+ */
+ if (!locked)
+ prepare_to_wait(&memcg_oom_waitq, &wait, TASK_KILLABLE);
+ mutex_unlock(&memcg_oom_mutex);
+
+ if (locked)
+ mem_cgroup_out_of_memory(mem, mask);
+ else {
+ schedule();
+ finish_wait(&memcg_oom_waitq, &wait);
+ }
+ mutex_lock(&memcg_oom_mutex);
+ mem_cgroup_oom_unlock(mem);
+ /*
+ * Here, we use global waitq .....more fine grained waitq ?
+ * Assume following hierarchy.
+ * A/
+ * 01
+ * 02
+ * assume OOM happens both in A and 01 at the same time. Tthey are
+ * mutually exclusive by lock. (kill in 01 helps A.)
+ * When we use per memcg waitq, we have to wake up waiters on A and 02
+ * in addtion to waiters on 01. We use global waitq for avoiding mess.
+ * It will not be a big problem.
+ * (And a task may be moved to other groups while it's waiting for OOM.)
+ */
+ wake_up_all(&memcg_oom_waitq);
+ mutex_unlock(&memcg_oom_mutex);
+
+ if (test_thread_flag(TIF_MEMDIE) || fatal_signal_pending(current))
+ return false;
+ /* Give chance to dying process */
+ schedule_timeout(1);
+ return true;
}
/*
@@ -1240,9 +1351,6 @@ static void record_last_oom(struct mem_cgroup *mem)
void mem_cgroup_update_file_mapped(struct page *page, int val)
{
struct mem_cgroup *mem;
- struct mem_cgroup_stat *stat;
- struct mem_cgroup_stat_cpu *cpustat;
- int cpu;
struct page_cgroup *pc;
pc = lookup_page_cgroup(page);
@@ -1251,20 +1359,20 @@ void mem_cgroup_update_file_mapped(struct page *page, int val)
lock_page_cgroup(pc);
mem = pc->mem_cgroup;
- if (!mem)
- goto done;
-
- if (!PageCgroupUsed(pc))
+ if (!mem || !PageCgroupUsed(pc))
goto done;
/*
- * Preemption is already disabled, we don't need get_cpu()
+ * Preemption is already disabled. We can use __this_cpu_xxx
*/
- cpu = smp_processor_id();
- stat = &mem->stat;
- cpustat = &stat->cpustat[cpu];
+ if (val > 0) {
+ __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
+ SetPageCgroupFileMapped(pc);
+ } else {
+ __this_cpu_dec(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
+ ClearPageCgroupFileMapped(pc);
+ }
- __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_FILE_MAPPED, val);
done:
unlock_page_cgroup(pc);
}
@@ -1401,19 +1509,21 @@ static int __cpuinit memcg_stock_cpu_callback(struct notifier_block *nb,
* oom-killer can be invoked.
*/
static int __mem_cgroup_try_charge(struct mm_struct *mm,
- gfp_t gfp_mask, struct mem_cgroup **memcg,
- bool oom, struct page *page)
+ gfp_t gfp_mask, struct mem_cgroup **memcg, bool oom)
{
struct mem_cgroup *mem, *mem_over_limit;
int nr_retries = MEM_CGROUP_RECLAIM_RETRIES;
struct res_counter *fail_res;
int csize = CHARGE_SIZE;
- if (unlikely(test_thread_flag(TIF_MEMDIE))) {
- /* Don't account this! */
- *memcg = NULL;
- return 0;
- }
+ /*
+ * Unlike gloval-vm's OOM-kill, we're not in memory shortage
+ * in system level. So, allow to go ahead dying process in addition to
+ * MEMDIE process.
+ */
+ if (unlikely(test_thread_flag(TIF_MEMDIE)
+ || fatal_signal_pending(current)))
+ goto bypass;
/*
* We always charge the cgroup the mm_struct belongs to.
@@ -1440,7 +1550,7 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
unsigned long flags = 0;
if (consume_stock(mem))
- goto charged;
+ goto done;
ret = res_counter_charge(&mem->res, csize, &fail_res);
if (likely(!ret)) {
@@ -1483,28 +1593,70 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
if (mem_cgroup_check_under_limit(mem_over_limit))
continue;
+ /* try to avoid oom while someone is moving charge */
+ if (mc.moving_task && current != mc.moving_task) {
+ struct mem_cgroup *from, *to;
+ bool do_continue = false;
+ /*
+ * There is a small race that "from" or "to" can be
+ * freed by rmdir, so we use css_tryget().
+ */
+ rcu_read_lock();
+ from = mc.from;
+ to = mc.to;
+ if (from && css_tryget(&from->css)) {
+ if (mem_over_limit->use_hierarchy)
+ do_continue = css_is_ancestor(
+ &from->css,
+ &mem_over_limit->css);
+ else
+ do_continue = (from == mem_over_limit);
+ css_put(&from->css);
+ }
+ if (!do_continue && to && css_tryget(&to->css)) {
+ if (mem_over_limit->use_hierarchy)
+ do_continue = css_is_ancestor(
+ &to->css,
+ &mem_over_limit->css);
+ else
+ do_continue = (to == mem_over_limit);
+ css_put(&to->css);
+ }
+ rcu_read_unlock();
+ if (do_continue) {
+ DEFINE_WAIT(wait);
+ prepare_to_wait(&mc.waitq, &wait,
+ TASK_INTERRUPTIBLE);
+ /* moving charge context might have finished. */
+ if (mc.moving_task)
+ schedule();
+ finish_wait(&mc.waitq, &wait);
+ continue;
+ }
+ }
+
if (!nr_retries--) {
- if (oom) {
- mem_cgroup_out_of_memory(mem_over_limit, gfp_mask);
- record_last_oom(mem_over_limit);
+ if (!oom)
+ goto nomem;
+ if (mem_cgroup_handle_oom(mem_over_limit, gfp_mask)) {
+ nr_retries = MEM_CGROUP_RECLAIM_RETRIES;
+ continue;
}
- goto nomem;
+ /* When we reach here, current task is dying .*/
+ css_put(&mem->css);
+ goto bypass;
}
}
if (csize > PAGE_SIZE)
refill_stock(mem, csize - PAGE_SIZE);
-charged:
- /*
- * Insert ancestor (and ancestor's ancestors), to softlimit RB-tree.
- * if they exceeds softlimit.
- */
- if (mem_cgroup_soft_limit_check(mem))
- mem_cgroup_update_tree(mem, page);
done:
return 0;
nomem:
css_put(&mem->css);
return -ENOMEM;
+bypass:
+ *memcg = NULL;
+ return 0;
}
/*
@@ -1512,14 +1664,23 @@ nomem:
* This function is for that and do uncharge, put css's refcnt.
* gotten by try_charge().
*/
-static void mem_cgroup_cancel_charge(struct mem_cgroup *mem)
+static void __mem_cgroup_cancel_charge(struct mem_cgroup *mem,
+ unsigned long count)
{
if (!mem_cgroup_is_root(mem)) {
- res_counter_uncharge(&mem->res, PAGE_SIZE);
+ res_counter_uncharge(&mem->res, PAGE_SIZE * count);
if (do_swap_account)
- res_counter_uncharge(&mem->memsw, PAGE_SIZE);
+ res_counter_uncharge(&mem->memsw, PAGE_SIZE * count);
+ VM_BUG_ON(test_bit(CSS_ROOT, &mem->css.flags));
+ WARN_ON_ONCE(count > INT_MAX);
+ __css_put(&mem->css, (int)count);
}
- css_put(&mem->css);
+ /* we don't need css_put for root */
+}
+
+static void mem_cgroup_cancel_charge(struct mem_cgroup *mem)
+{
+ __mem_cgroup_cancel_charge(mem, 1);
}
/*
@@ -1615,6 +1776,12 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *mem,
mem_cgroup_charge_statistics(mem, pc, true);
unlock_page_cgroup(pc);
+ /*
+ * "charge_statistics" updated event counter. Then, check it.
+ * Insert ancestor (and ancestor's ancestors), to softlimit RB-tree.
+ * if they exceeds softlimit.
+ */
+ memcg_check_events(mem, pc->page);
}
/**
@@ -1622,61 +1789,48 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *mem,
* @pc: page_cgroup of the page.
* @from: mem_cgroup which the page is moved from.
* @to: mem_cgroup which the page is moved to. @from != @to.
+ * @uncharge: whether we should call uncharge and css_put against @from.
*
* The caller must confirm following.
* - page is not on LRU (isolate_page() is useful.)
* - the pc is locked, used, and ->mem_cgroup points to @from.
*
- * This function does "uncharge" from old cgroup but doesn't do "charge" to
- * new cgroup. It should be done by a caller.
+ * This function doesn't do "charge" nor css_get to new cgroup. It should be
+ * done by a caller(__mem_cgroup_try_charge would be usefull). If @uncharge is
+ * true, this function does "uncharge" from old cgroup, but it doesn't if
+ * @uncharge is false, so a caller should do "uncharge".
*/
static void __mem_cgroup_move_account(struct page_cgroup *pc,
- struct mem_cgroup *from, struct mem_cgroup *to)
+ struct mem_cgroup *from, struct mem_cgroup *to, bool uncharge)
{
- struct page *page;
- int cpu;
- struct mem_cgroup_stat *stat;
- struct mem_cgroup_stat_cpu *cpustat;
-
VM_BUG_ON(from == to);
VM_BUG_ON(PageLRU(pc->page));
VM_BUG_ON(!PageCgroupLocked(pc));
VM_BUG_ON(!PageCgroupUsed(pc));
VM_BUG_ON(pc->mem_cgroup != from);
- if (!mem_cgroup_is_root(from))
- res_counter_uncharge(&from->res, PAGE_SIZE);
- mem_cgroup_charge_statistics(from, pc, false);
-
- page = pc->page;
- if (page_mapped(page) && !PageAnon(page)) {
- cpu = smp_processor_id();
- /* Update mapped_file data for mem_cgroup "from" */
- stat = &from->stat;
- cpustat = &stat->cpustat[cpu];
- __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_FILE_MAPPED,
- -1);
-
- /* Update mapped_file data for mem_cgroup "to" */
- stat = &to->stat;
- cpustat = &stat->cpustat[cpu];
- __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_FILE_MAPPED,
- 1);
+ if (PageCgroupFileMapped(pc)) {
+ /* Update mapped_file data for mem_cgroup */
+ preempt_disable();
+ __this_cpu_dec(from->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
+ __this_cpu_inc(to->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
+ preempt_enable();
}
+ mem_cgroup_charge_statistics(from, pc, false);
+ if (uncharge)
+ /* This is not "cancel", but cancel_charge does all we need. */
+ mem_cgroup_cancel_charge(from);
- if (do_swap_account && !mem_cgroup_is_root(from))
- res_counter_uncharge(&from->memsw, PAGE_SIZE);
- css_put(&from->css);
-
- css_get(&to->css);
+ /* caller should have done css_get */
pc->mem_cgroup = to;
mem_cgroup_charge_statistics(to, pc, true);
/*
* We charges against "to" which may not have any tasks. Then, "to"
* can be under rmdir(). But in current implementation, caller of
- * this function is just force_empty() and it's garanteed that
- * "to" is never removed. So, we don't check rmdir status here.
+ * this function is just force_empty() and move charge, so it's
+ * garanteed that "to" is never removed. So, we don't check rmdir
+ * status here.
*/
}
@@ -1685,15 +1839,20 @@ static void __mem_cgroup_move_account(struct page_cgroup *pc,
* __mem_cgroup_move_account()
*/
static int mem_cgroup_move_account(struct page_cgroup *pc,
- struct mem_cgroup *from, struct mem_cgroup *to)
+ struct mem_cgroup *from, struct mem_cgroup *to, bool uncharge)
{
int ret = -EINVAL;
lock_page_cgroup(pc);
if (PageCgroupUsed(pc) && pc->mem_cgroup == from) {
- __mem_cgroup_move_account(pc, from, to);
+ __mem_cgroup_move_account(pc, from, to, uncharge);
ret = 0;
}
unlock_page_cgroup(pc);
+ /*
+ * check events
+ */
+ memcg_check_events(to, pc->page);
+ memcg_check_events(from, pc->page);
return ret;
}
@@ -1722,15 +1881,13 @@ static int mem_cgroup_move_parent(struct page_cgroup *pc,
goto put;
parent = mem_cgroup_from_cont(pcg);
- ret = __mem_cgroup_try_charge(NULL, gfp_mask, &parent, false, page);
+ ret = __mem_cgroup_try_charge(NULL, gfp_mask, &parent, false);
if (ret || !parent)
goto put_back;
- ret = mem_cgroup_move_account(pc, child, parent);
- if (!ret)
- css_put(&parent->css); /* drop extra refcnt by try_charge() */
- else
- mem_cgroup_cancel_charge(parent); /* does css_put */
+ ret = mem_cgroup_move_account(pc, child, parent, true);
+ if (ret)
+ mem_cgroup_cancel_charge(parent);
put_back:
putback_lru_page(page);
put:
@@ -1760,7 +1917,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
prefetchw(pc);
mem = memcg;
- ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, true, page);
+ ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, true);
if (ret || !mem)
return ret;
@@ -1880,14 +2037,14 @@ int mem_cgroup_try_charge_swapin(struct mm_struct *mm,
if (!mem)
goto charge_cur_mm;
*ptr = mem;
- ret = __mem_cgroup_try_charge(NULL, mask, ptr, true, page);
+ ret = __mem_cgroup_try_charge(NULL, mask, ptr, true);
/* drop extra refcnt from tryget */
css_put(&mem->css);
return ret;
charge_cur_mm:
if (unlikely(!mm))
mm = &init_mm;
- return __mem_cgroup_try_charge(mm, mask, ptr, true, page);
+ return __mem_cgroup_try_charge(mm, mask, ptr, true);
}
static void
@@ -2064,8 +2221,7 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
mz = page_cgroup_zoneinfo(pc);
unlock_page_cgroup(pc);
- if (mem_cgroup_soft_limit_check(mem))
- mem_cgroup_update_tree(mem, page);
+ memcg_check_events(mem, page);
/* at swapout, this memcg will be accessed to record to swap */
if (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT)
css_put(&mem->css);
@@ -2192,6 +2348,64 @@ void mem_cgroup_uncharge_swap(swp_entry_t ent)
}
rcu_read_unlock();
}
+
+/**
+ * mem_cgroup_move_swap_account - move swap charge and swap_cgroup's record.
+ * @entry: swap entry to be moved
+ * @from: mem_cgroup which the entry is moved from
+ * @to: mem_cgroup which the entry is moved to
+ * @need_fixup: whether we should fixup res_counters and refcounts.
+ *
+ * It succeeds only when the swap_cgroup's record for this entry is the same
+ * as the mem_cgroup's id of @from.
+ *
+ * Returns 0 on success, -EINVAL on failure.
+ *
+ * The caller must have charged to @to, IOW, called res_counter_charge() about
+ * both res and memsw, and called css_get().
+ */
+static int mem_cgroup_move_swap_account(swp_entry_t entry,
+ struct mem_cgroup *from, struct mem_cgroup *to, bool need_fixup)
+{
+ unsigned short old_id, new_id;
+
+ old_id = css_id(&from->css);
+ new_id = css_id(&to->css);
+
+ if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) {
+ mem_cgroup_swap_statistics(from, false);
+ mem_cgroup_swap_statistics(to, true);
+ /*
+ * This function is only called from task migration context now.
+ * It postpones res_counter and refcount handling till the end
+ * of task migration(mem_cgroup_clear_mc()) for performance
+ * improvement. But we cannot postpone mem_cgroup_get(to)
+ * because if the process that has been moved to @to does
+ * swap-in, the refcount of @to might be decreased to 0.
+ */
+ mem_cgroup_get(to);
+ if (need_fixup) {
+ if (!mem_cgroup_is_root(from))
+ res_counter_uncharge(&from->memsw, PAGE_SIZE);
+ mem_cgroup_put(from);
+ /*
+ * we charged both to->res and to->memsw, so we should
+ * uncharge to->res.
+ */
+ if (!mem_cgroup_is_root(to))
+ res_counter_uncharge(&to->res, PAGE_SIZE);
+ css_put(&to->css);
+ }
+ return 0;
+ }
+ return -EINVAL;
+}
+#else
+static inline int mem_cgroup_move_swap_account(swp_entry_t entry,
+ struct mem_cgroup *from, struct mem_cgroup *to, bool need_fixup)
+{
+ return -EINVAL;
+}
#endif
/*
@@ -2215,12 +2429,11 @@ int mem_cgroup_prepare_migration(struct page *page, struct mem_cgroup **ptr)
}
unlock_page_cgroup(pc);
+ *ptr = mem;
if (mem) {
- ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, &mem, false,
- page);
+ ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, ptr, false);
css_put(&mem->css);
}
- *ptr = mem;
return ret;
}
@@ -2545,7 +2758,7 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *mem,
pc = list_entry(list->prev, struct page_cgroup, lru);
if (busy == pc) {
list_move(&pc->lru, list);
- busy = 0;
+ busy = NULL;
spin_unlock_irqrestore(&zone->lru_lock, flags);
continue;
}
@@ -2704,7 +2917,7 @@ static int
mem_cgroup_get_idx_stat(struct mem_cgroup *mem, void *data)
{
struct mem_cgroup_idx_data *d = data;
- d->val += mem_cgroup_read_stat(&mem->stat, d->idx);
+ d->val += mem_cgroup_read_stat(mem, d->idx);
return 0;
}
@@ -2719,40 +2932,50 @@ mem_cgroup_get_recursive_idx_stat(struct mem_cgroup *mem,
*val = d.val;
}
+static inline u64 mem_cgroup_usage(struct mem_cgroup *mem, bool swap)
+{
+ u64 idx_val, val;
+
+ if (!mem_cgroup_is_root(mem)) {
+ if (!swap)
+ return res_counter_read_u64(&mem->res, RES_USAGE);
+ else
+ return res_counter_read_u64(&mem->memsw, RES_USAGE);
+ }
+
+ mem_cgroup_get_recursive_idx_stat(mem, MEM_CGROUP_STAT_CACHE, &idx_val);
+ val = idx_val;
+ mem_cgroup_get_recursive_idx_stat(mem, MEM_CGROUP_STAT_RSS, &idx_val);
+ val += idx_val;
+
+ if (swap) {
+ mem_cgroup_get_recursive_idx_stat(mem,
+ MEM_CGROUP_STAT_SWAPOUT, &idx_val);
+ val += idx_val;
+ }
+
+ return val << PAGE_SHIFT;
+}
+
static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft)
{
struct mem_cgroup *mem = mem_cgroup_from_cont(cont);
- u64 idx_val, val;
+ u64 val;
int type, name;
type = MEMFILE_TYPE(cft->private);
name = MEMFILE_ATTR(cft->private);
switch (type) {
case _MEM:
- if (name == RES_USAGE && mem_cgroup_is_root(mem)) {
- mem_cgroup_get_recursive_idx_stat(mem,
- MEM_CGROUP_STAT_CACHE, &idx_val);
- val = idx_val;
- mem_cgroup_get_recursive_idx_stat(mem,
- MEM_CGROUP_STAT_RSS, &idx_val);
- val += idx_val;
- val <<= PAGE_SHIFT;
- } else
+ if (name == RES_USAGE)
+ val = mem_cgroup_usage(mem, false);
+ else
val = res_counter_read_u64(&mem->res, name);
break;
case _MEMSWAP:
- if (name == RES_USAGE && mem_cgroup_is_root(mem)) {
- mem_cgroup_get_recursive_idx_stat(mem,
- MEM_CGROUP_STAT_CACHE, &idx_val);
- val = idx_val;
- mem_cgroup_get_recursive_idx_stat(mem,
- MEM_CGROUP_STAT_RSS, &idx_val);
- val += idx_val;
- mem_cgroup_get_recursive_idx_stat(mem,
- MEM_CGROUP_STAT_SWAPOUT, &idx_val);
- val += idx_val;
- val <<= PAGE_SHIFT;
- } else
+ if (name == RES_USAGE)
+ val = mem_cgroup_usage(mem, true);
+ else
val = res_counter_read_u64(&mem->memsw, name);
break;
default:
@@ -2865,6 +3088,39 @@ static int mem_cgroup_reset(struct cgroup *cont, unsigned int event)
return 0;
}
+static u64 mem_cgroup_move_charge_read(struct cgroup *cgrp,
+ struct cftype *cft)
+{
+ return mem_cgroup_from_cont(cgrp)->move_charge_at_immigrate;
+}
+
+#ifdef CONFIG_MMU
+static int mem_cgroup_move_charge_write(struct cgroup *cgrp,
+ struct cftype *cft, u64 val)
+{
+ struct mem_cgroup *mem = mem_cgroup_from_cont(cgrp);
+
+ if (val >= (1 << NR_MOVE_TYPE))
+ return -EINVAL;
+ /*
+ * We check this value several times in both in can_attach() and
+ * attach(), so we need cgroup lock to prevent this value from being
+ * inconsistent.
+ */
+ cgroup_lock();
+ mem->move_charge_at_immigrate = val;
+ cgroup_unlock();
+
+ return 0;
+}
+#else
+static int mem_cgroup_move_charge_write(struct cgroup *cgrp,
+ struct cftype *cft, u64 val)
+{
+ return -ENOSYS;
+}
+#endif
+
/* For read statistics */
enum {
@@ -2910,18 +3166,18 @@ static int mem_cgroup_get_local_stat(struct mem_cgroup *mem, void *data)
s64 val;
/* per cpu stat */
- val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_CACHE);
+ val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_CACHE);
s->stat[MCS_CACHE] += val * PAGE_SIZE;
- val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS);
+ val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_RSS);
s->stat[MCS_RSS] += val * PAGE_SIZE;
- val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_FILE_MAPPED);
+ val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_FILE_MAPPED);
s->stat[MCS_FILE_MAPPED] += val * PAGE_SIZE;
- val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGIN_COUNT);
+ val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_PGPGIN_COUNT);
s->stat[MCS_PGPGIN] += val;
- val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGOUT_COUNT);
+ val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_PGPGOUT_COUNT);
s->stat[MCS_PGPGOUT] += val;
if (do_swap_account) {
- val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_SWAPOUT);
+ val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_SWAPOUT);
s->stat[MCS_SWAP] += val * PAGE_SIZE;
}
@@ -3049,12 +3305,249 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft,
return 0;
}
+static void __mem_cgroup_threshold(struct mem_cgroup *memcg, bool swap)
+{
+ struct mem_cgroup_threshold_ary *t;
+ u64 usage;
+ int i;
+
+ rcu_read_lock();
+ if (!swap)
+ t = rcu_dereference(memcg->thresholds);
+ else
+ t = rcu_dereference(memcg->memsw_thresholds);
+
+ if (!t)
+ goto unlock;
+
+ usage = mem_cgroup_usage(memcg, swap);
+
+ /*
+ * current_threshold points to threshold just below usage.
+ * If it's not true, a threshold was crossed after last
+ * call of __mem_cgroup_threshold().
+ */
+ i = atomic_read(&t->current_threshold);
+
+ /*
+ * Iterate backward over array of thresholds starting from
+ * current_threshold and check if a threshold is crossed.
+ * If none of thresholds below usage is crossed, we read
+ * only one element of the array here.
+ */
+ for (; i >= 0 && unlikely(t->entries[i].threshold > usage); i--)
+ eventfd_signal(t->entries[i].eventfd, 1);
+
+ /* i = current_threshold + 1 */
+ i++;
+
+ /*
+ * Iterate forward over array of thresholds starting from
+ * current_threshold+1 and check if a threshold is crossed.
+ * If none of thresholds above usage is crossed, we read
+ * only one element of the array here.
+ */
+ for (; i < t->size && unlikely(t->entries[i].threshold <= usage); i++)
+ eventfd_signal(t->entries[i].eventfd, 1);
+
+ /* Update current_threshold */
+ atomic_set(&t->current_threshold, i - 1);
+unlock:
+ rcu_read_unlock();
+}
+
+static void mem_cgroup_threshold(struct mem_cgroup *memcg)
+{
+ __mem_cgroup_threshold(memcg, false);
+ if (do_swap_account)
+ __mem_cgroup_threshold(memcg, true);
+}
+
+static int compare_thresholds(const void *a, const void *b)
+{
+ const struct mem_cgroup_threshold *_a = a;
+ const struct mem_cgroup_threshold *_b = b;
+
+ return _a->threshold - _b->threshold;
+}
+
+static int mem_cgroup_register_event(struct cgroup *cgrp, struct cftype *cft,
+ struct eventfd_ctx *eventfd, const char *args)
+{
+ struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
+ struct mem_cgroup_threshold_ary *thresholds, *thresholds_new;
+ int type = MEMFILE_TYPE(cft->private);
+ u64 threshold, usage;
+ int size;
+ int i, ret;
+
+ ret = res_counter_memparse_write_strategy(args, &threshold);
+ if (ret)
+ return ret;
+
+ mutex_lock(&memcg->thresholds_lock);
+ if (type == _MEM)
+ thresholds = memcg->thresholds;
+ else if (type == _MEMSWAP)
+ thresholds = memcg->memsw_thresholds;
+ else
+ BUG();
+
+ usage = mem_cgroup_usage(memcg, type == _MEMSWAP);
+
+ /* Check if a threshold crossed before adding a new one */
+ if (thresholds)
+ __mem_cgroup_threshold(memcg, type == _MEMSWAP);
+
+ if (thresholds)
+ size = thresholds->size + 1;
+ else
+ size = 1;
+
+ /* Allocate memory for new array of thresholds */
+ thresholds_new = kmalloc(sizeof(*thresholds_new) +
+ size * sizeof(struct mem_cgroup_threshold),
+ GFP_KERNEL);
+ if (!thresholds_new) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+ thresholds_new->size = size;
+
+ /* Copy thresholds (if any) to new array */
+ if (thresholds)
+ memcpy(thresholds_new->entries, thresholds->entries,
+ thresholds->size *
+ sizeof(struct mem_cgroup_threshold));
+ /* Add new threshold */
+ thresholds_new->entries[size - 1].eventfd = eventfd;
+ thresholds_new->entries[size - 1].threshold = threshold;
+
+ /* Sort thresholds. Registering of new threshold isn't time-critical */
+ sort(thresholds_new->entries, size,
+ sizeof(struct mem_cgroup_threshold),
+ compare_thresholds, NULL);
+
+ /* Find current threshold */
+ atomic_set(&thresholds_new->current_threshold, -1);
+ for (i = 0; i < size; i++) {
+ if (thresholds_new->entries[i].threshold < usage) {
+ /*
+ * thresholds_new->current_threshold will not be used
+ * until rcu_assign_pointer(), so it's safe to increment
+ * it here.
+ */
+ atomic_inc(&thresholds_new->current_threshold);
+ }
+ }
+
+ if (type == _MEM)
+ rcu_assign_pointer(memcg->thresholds, thresholds_new);
+ else
+ rcu_assign_pointer(memcg->memsw_thresholds, thresholds_new);
+
+ /* To be sure that nobody uses thresholds before freeing it */
+ synchronize_rcu();
+
+ kfree(thresholds);
+unlock:
+ mutex_unlock(&memcg->thresholds_lock);
+
+ return ret;
+}
+
+static int mem_cgroup_unregister_event(struct cgroup *cgrp, struct cftype *cft,
+ struct eventfd_ctx *eventfd)
+{
+ struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
+ struct mem_cgroup_threshold_ary *thresholds, *thresholds_new;
+ int type = MEMFILE_TYPE(cft->private);
+ u64 usage;
+ int size = 0;
+ int i, j, ret;
+
+ mutex_lock(&memcg->thresholds_lock);
+ if (type == _MEM)
+ thresholds = memcg->thresholds;
+ else if (type == _MEMSWAP)
+ thresholds = memcg->memsw_thresholds;
+ else
+ BUG();
+
+ /*
+ * Something went wrong if we trying to unregister a threshold
+ * if we don't have thresholds
+ */
+ BUG_ON(!thresholds);
+
+ usage = mem_cgroup_usage(memcg, type == _MEMSWAP);
+
+ /* Check if a threshold crossed before removing */
+ __mem_cgroup_threshold(memcg, type == _MEMSWAP);
+
+ /* Calculate new number of threshold */
+ for (i = 0; i < thresholds->size; i++) {
+ if (thresholds->entries[i].eventfd != eventfd)
+ size++;
+ }
+
+ /* Set thresholds array to NULL if we don't have thresholds */
+ if (!size) {
+ thresholds_new = NULL;
+ goto assign;
+ }
+
+ /* Allocate memory for new array of thresholds */
+ thresholds_new = kmalloc(sizeof(*thresholds_new) +
+ size * sizeof(struct mem_cgroup_threshold),
+ GFP_KERNEL);
+ if (!thresholds_new) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+ thresholds_new->size = size;
+
+ /* Copy thresholds and find current threshold */
+ atomic_set(&thresholds_new->current_threshold, -1);
+ for (i = 0, j = 0; i < thresholds->size; i++) {
+ if (thresholds->entries[i].eventfd == eventfd)
+ continue;
+
+ thresholds_new->entries[j] = thresholds->entries[i];
+ if (thresholds_new->entries[j].threshold < usage) {
+ /*
+ * thresholds_new->current_threshold will not be used
+ * until rcu_assign_pointer(), so it's safe to increment
+ * it here.
+ */
+ atomic_inc(&thresholds_new->current_threshold);
+ }
+ j++;
+ }
+
+assign:
+ if (type == _MEM)
+ rcu_assign_pointer(memcg->thresholds, thresholds_new);
+ else
+ rcu_assign_pointer(memcg->memsw_thresholds, thresholds_new);
+
+ /* To be sure that nobody uses thresholds before freeing it */
+ synchronize_rcu();
+
+ kfree(thresholds);
+unlock:
+ mutex_unlock(&memcg->thresholds_lock);
+
+ return ret;
+}
static struct cftype mem_cgroup_files[] = {
{
.name = "usage_in_bytes",
.private = MEMFILE_PRIVATE(_MEM, RES_USAGE),
.read_u64 = mem_cgroup_read,
+ .register_event = mem_cgroup_register_event,
+ .unregister_event = mem_cgroup_unregister_event,
},
{
.name = "max_usage_in_bytes",
@@ -3098,6 +3591,11 @@ static struct cftype mem_cgroup_files[] = {
.read_u64 = mem_cgroup_swappiness_read,
.write_u64 = mem_cgroup_swappiness_write,
},
+ {
+ .name = "move_charge_at_immigrate",
+ .read_u64 = mem_cgroup_move_charge_read,
+ .write_u64 = mem_cgroup_move_charge_write,
+ },
};
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
@@ -3106,6 +3604,8 @@ static struct cftype memsw_cgroup_files[] = {
.name = "memsw.usage_in_bytes",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_USAGE),
.read_u64 = mem_cgroup_read,
+ .register_event = mem_cgroup_register_event,
+ .unregister_event = mem_cgroup_unregister_event,
},
{
.name = "memsw.max_usage_in_bytes",
@@ -3180,24 +3680,29 @@ static void free_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node)
kfree(mem->info.nodeinfo[node]);
}
-static int mem_cgroup_size(void)
-{
- int cpustat_size = nr_cpu_ids * sizeof(struct mem_cgroup_stat_cpu);
- return sizeof(struct mem_cgroup) + cpustat_size;
-}
-
static struct mem_cgroup *mem_cgroup_alloc(void)
{
struct mem_cgroup *mem;
- int size = mem_cgroup_size();
+ int size = sizeof(struct mem_cgroup);
+ /* Can be very big if MAX_NUMNODES is very big */
if (size < PAGE_SIZE)
mem = kmalloc(size, GFP_KERNEL);
else
mem = vmalloc(size);
- if (mem)
- memset(mem, 0, size);
+ if (!mem)
+ return NULL;
+
+ memset(mem, 0, size);
+ mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu);
+ if (!mem->stat) {
+ if (size < PAGE_SIZE)
+ kfree(mem);
+ else
+ vfree(mem);
+ mem = NULL;
+ }
return mem;
}
@@ -3222,7 +3727,8 @@ static void __mem_cgroup_free(struct mem_cgroup *mem)
for_each_node_state(node, N_POSSIBLE)
free_mem_cgroup_per_zone_info(mem, node);
- if (mem_cgroup_size() < PAGE_SIZE)
+ free_percpu(mem->stat);
+ if (sizeof(struct mem_cgroup) < PAGE_SIZE)
kfree(mem);
else
vfree(mem);
@@ -3233,9 +3739,9 @@ static void mem_cgroup_get(struct mem_cgroup *mem)
atomic_inc(&mem->refcnt);
}
-static void mem_cgroup_put(struct mem_cgroup *mem)
+static void __mem_cgroup_put(struct mem_cgroup *mem, int count)
{
- if (atomic_dec_and_test(&mem->refcnt)) {
+ if (atomic_sub_and_test(count, &mem->refcnt)) {
struct mem_cgroup *parent = parent_mem_cgroup(mem);
__mem_cgroup_free(mem);
if (parent)
@@ -3243,6 +3749,11 @@ static void mem_cgroup_put(struct mem_cgroup *mem)
}
}
+static void mem_cgroup_put(struct mem_cgroup *mem)
+{
+ __mem_cgroup_put(mem, 1);
+}
+
/*
* Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled.
*/
@@ -3319,7 +3830,6 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
INIT_WORK(&stock->work, drain_local_stock);
}
hotcpu_notifier(memcg_stock_cpu_callback, 0);
-
} else {
parent = mem_cgroup_from_cont(cont->parent);
mem->use_hierarchy = parent->use_hierarchy;
@@ -3345,6 +3855,8 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
if (parent)
mem->swappiness = get_swappiness(parent);
atomic_set(&mem->refcnt, 1);
+ mem->move_charge_at_immigrate = 0;
+ mutex_init(&mem->thresholds_lock);
return &mem->css;
free_out:
__mem_cgroup_free(mem);
@@ -3381,17 +3893,445 @@ static int mem_cgroup_populate(struct cgroup_subsys *ss,
return ret;
}
+#ifdef CONFIG_MMU
+/* Handlers for move charge at task migration. */
+#define PRECHARGE_COUNT_AT_ONCE 256
+static int mem_cgroup_do_precharge(unsigned long count)
+{
+ int ret = 0;
+ int batch_count = PRECHARGE_COUNT_AT_ONCE;
+ struct mem_cgroup *mem = mc.to;
+
+ if (mem_cgroup_is_root(mem)) {
+ mc.precharge += count;
+ /* we don't need css_get for root */
+ return ret;
+ }
+ /* try to charge at once */
+ if (count > 1) {
+ struct res_counter *dummy;
+ /*
+ * "mem" cannot be under rmdir() because we've already checked
+ * by cgroup_lock_live_cgroup() that it is not removed and we
+ * are still under the same cgroup_mutex. So we can postpone
+ * css_get().
+ */
+ if (res_counter_charge(&mem->res, PAGE_SIZE * count, &dummy))
+ goto one_by_one;
+ if (do_swap_account && res_counter_charge(&mem->memsw,
+ PAGE_SIZE * count, &dummy)) {
+ res_counter_uncharge(&mem->res, PAGE_SIZE * count);
+ goto one_by_one;
+ }
+ mc.precharge += count;
+ VM_BUG_ON(test_bit(CSS_ROOT, &mem->css.flags));
+ WARN_ON_ONCE(count > INT_MAX);
+ __css_get(&mem->css, (int)count);
+ return ret;
+ }
+one_by_one:
+ /* fall back to one by one charge */
+ while (count--) {
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
+ if (!batch_count--) {
+ batch_count = PRECHARGE_COUNT_AT_ONCE;
+ cond_resched();
+ }
+ ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, &mem, false);
+ if (ret || !mem)
+ /* mem_cgroup_clear_mc() will do uncharge later */
+ return -ENOMEM;
+ mc.precharge++;
+ }
+ return ret;
+}
+
+/**
+ * is_target_pte_for_mc - check a pte whether it is valid for move charge
+ * @vma: the vma the pte to be checked belongs
+ * @addr: the address corresponding to the pte to be checked
+ * @ptent: the pte to be checked
+ * @target: the pointer the target page or swap ent will be stored(can be NULL)
+ *
+ * Returns
+ * 0(MC_TARGET_NONE): if the pte is not a target for move charge.
+ * 1(MC_TARGET_PAGE): if the page corresponding to this pte is a target for
+ * move charge. if @target is not NULL, the page is stored in target->page
+ * with extra refcnt got(Callers should handle it).
+ * 2(MC_TARGET_SWAP): if the swap entry corresponding to this pte is a
+ * target for charge migration. if @target is not NULL, the entry is stored
+ * in target->ent.
+ *
+ * Called with pte lock held.
+ */
+union mc_target {
+ struct page *page;
+ swp_entry_t ent;
+};
+
+enum mc_target_type {
+ MC_TARGET_NONE, /* not used */
+ MC_TARGET_PAGE,
+ MC_TARGET_SWAP,
+};
+
+static int is_target_pte_for_mc(struct vm_area_struct *vma,
+ unsigned long addr, pte_t ptent, union mc_target *target)
+{
+ struct page *page = NULL;
+ struct page_cgroup *pc;
+ int ret = 0;
+ swp_entry_t ent = { .val = 0 };
+ int usage_count = 0;
+ bool move_anon = test_bit(MOVE_CHARGE_TYPE_ANON,
+ &mc.to->move_charge_at_immigrate);
+
+ if (!pte_present(ptent)) {
+ /* TODO: handle swap of shmes/tmpfs */
+ if (pte_none(ptent) || pte_file(ptent))
+ return 0;
+ else if (is_swap_pte(ptent)) {
+ ent = pte_to_swp_entry(ptent);
+ if (!move_anon || non_swap_entry(ent))
+ return 0;
+ usage_count = mem_cgroup_count_swap_user(ent, &page);
+ }
+ } else {
+ page = vm_normal_page(vma, addr, ptent);
+ if (!page || !page_mapped(page))
+ return 0;
+ /*
+ * TODO: We don't move charges of file(including shmem/tmpfs)
+ * pages for now.
+ */
+ if (!move_anon || !PageAnon(page))
+ return 0;
+ if (!get_page_unless_zero(page))
+ return 0;
+ usage_count = page_mapcount(page);
+ }
+ if (usage_count > 1) {
+ /*
+ * TODO: We don't move charges of shared(used by multiple
+ * processes) pages for now.
+ */
+ if (page)
+ put_page(page);
+ return 0;
+ }
+ if (page) {
+ pc = lookup_page_cgroup(page);
+ /*
+ * Do only loose check w/o page_cgroup lock.
+ * mem_cgroup_move_account() checks the pc is valid or not under
+ * the lock.
+ */
+ if (PageCgroupUsed(pc) && pc->mem_cgroup == mc.from) {
+ ret = MC_TARGET_PAGE;
+ if (target)
+ target->page = page;
+ }
+ if (!ret || !target)
+ put_page(page);
+ }
+ /* throught */
+ if (ent.val && do_swap_account && !ret &&
+ css_id(&mc.from->css) == lookup_swap_cgroup(ent)) {
+ ret = MC_TARGET_SWAP;
+ if (target)
+ target->ent = ent;
+ }
+ return ret;
+}
+
+static int mem_cgroup_count_precharge_pte_range(pmd_t *pmd,
+ unsigned long addr, unsigned long end,
+ struct mm_walk *walk)
+{
+ struct vm_area_struct *vma = walk->private;
+ pte_t *pte;
+ spinlock_t *ptl;
+
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+ for (; addr != end; pte++, addr += PAGE_SIZE)
+ if (is_target_pte_for_mc(vma, addr, *pte, NULL))
+ mc.precharge++; /* increment precharge temporarily */
+ pte_unmap_unlock(pte - 1, ptl);
+ cond_resched();
+
+ return 0;
+}
+
+static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm)
+{
+ unsigned long precharge;
+ struct vm_area_struct *vma;
+
+ down_read(&mm->mmap_sem);
+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
+ struct mm_walk mem_cgroup_count_precharge_walk = {
+ .pmd_entry = mem_cgroup_count_precharge_pte_range,
+ .mm = mm,
+ .private = vma,
+ };
+ if (is_vm_hugetlb_page(vma))
+ continue;
+ /* TODO: We don't move charges of shmem/tmpfs pages for now. */
+ if (vma->vm_flags & VM_SHARED)
+ continue;
+ walk_page_range(vma->vm_start, vma->vm_end,
+ &mem_cgroup_count_precharge_walk);
+ }
+ up_read(&mm->mmap_sem);
+
+ precharge = mc.precharge;
+ mc.precharge = 0;
+
+ return precharge;
+}
+
+static int mem_cgroup_precharge_mc(struct mm_struct *mm)
+{
+ return mem_cgroup_do_precharge(mem_cgroup_count_precharge(mm));
+}
+
+static void mem_cgroup_clear_mc(void)
+{
+ /* we must uncharge all the leftover precharges from mc.to */
+ if (mc.precharge) {
+ __mem_cgroup_cancel_charge(mc.to, mc.precharge);
+ mc.precharge = 0;
+ }
+ /*
+ * we didn't uncharge from mc.from at mem_cgroup_move_account(), so
+ * we must uncharge here.
+ */
+ if (mc.moved_charge) {
+ __mem_cgroup_cancel_charge(mc.from, mc.moved_charge);
+ mc.moved_charge = 0;
+ }
+ /* we must fixup refcnts and charges */
+ if (mc.moved_swap) {
+ WARN_ON_ONCE(mc.moved_swap > INT_MAX);
+ /* uncharge swap account from the old cgroup */
+ if (!mem_cgroup_is_root(mc.from))
+ res_counter_uncharge(&mc.from->memsw,
+ PAGE_SIZE * mc.moved_swap);
+ __mem_cgroup_put(mc.from, mc.moved_swap);
+
+ if (!mem_cgroup_is_root(mc.to)) {
+ /*
+ * we charged both to->res and to->memsw, so we should
+ * uncharge to->res.
+ */
+ res_counter_uncharge(&mc.to->res,
+ PAGE_SIZE * mc.moved_swap);
+ VM_BUG_ON(test_bit(CSS_ROOT, &mc.to->css.flags));
+ __css_put(&mc.to->css, mc.moved_swap);
+ }
+ /* we've already done mem_cgroup_get(mc.to) */
+
+ mc.moved_swap = 0;
+ }
+ mc.from = NULL;
+ mc.to = NULL;
+ mc.moving_task = NULL;
+ wake_up_all(&mc.waitq);
+}
+
+static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
+ struct cgroup *cgroup,
+ struct task_struct *p,
+ bool threadgroup)
+{
+ int ret = 0;
+ struct mem_cgroup *mem = mem_cgroup_from_cont(cgroup);
+
+ if (mem->move_charge_at_immigrate) {
+ struct mm_struct *mm;
+ struct mem_cgroup *from = mem_cgroup_from_task(p);
+
+ VM_BUG_ON(from == mem);
+
+ mm = get_task_mm(p);
+ if (!mm)
+ return 0;
+ /* We move charges only when we move a owner of the mm */
+ if (mm->owner == p) {
+ VM_BUG_ON(mc.from);
+ VM_BUG_ON(mc.to);
+ VM_BUG_ON(mc.precharge);
+ VM_BUG_ON(mc.moved_charge);
+ VM_BUG_ON(mc.moved_swap);
+ VM_BUG_ON(mc.moving_task);
+ mc.from = from;
+ mc.to = mem;
+ mc.precharge = 0;
+ mc.moved_charge = 0;
+ mc.moved_swap = 0;
+ mc.moving_task = current;
+
+ ret = mem_cgroup_precharge_mc(mm);
+ if (ret)
+ mem_cgroup_clear_mc();
+ }
+ mmput(mm);
+ }
+ return ret;
+}
+
+static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss,
+ struct cgroup *cgroup,
+ struct task_struct *p,
+ bool threadgroup)
+{
+ mem_cgroup_clear_mc();
+}
+
+static int mem_cgroup_move_charge_pte_range(pmd_t *pmd,
+ unsigned long addr, unsigned long end,
+ struct mm_walk *walk)
+{
+ int ret = 0;
+ struct vm_area_struct *vma = walk->private;
+ pte_t *pte;
+ spinlock_t *ptl;
+
+retry:
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+ for (; addr != end; addr += PAGE_SIZE) {
+ pte_t ptent = *(pte++);
+ union mc_target target;
+ int type;
+ struct page *page;
+ struct page_cgroup *pc;
+ swp_entry_t ent;
+
+ if (!mc.precharge)
+ break;
+
+ type = is_target_pte_for_mc(vma, addr, ptent, &target);
+ switch (type) {
+ case MC_TARGET_PAGE:
+ page = target.page;
+ if (isolate_lru_page(page))
+ goto put;
+ pc = lookup_page_cgroup(page);
+ if (!mem_cgroup_move_account(pc,
+ mc.from, mc.to, false)) {
+ mc.precharge--;
+ /* we uncharge from mc.from later. */
+ mc.moved_charge++;
+ }
+ putback_lru_page(page);
+put: /* is_target_pte_for_mc() gets the page */
+ put_page(page);
+ break;
+ case MC_TARGET_SWAP:
+ ent = target.ent;
+ if (!mem_cgroup_move_swap_account(ent,
+ mc.from, mc.to, false)) {
+ mc.precharge--;
+ /* we fixup refcnts and charges later. */
+ mc.moved_swap++;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ pte_unmap_unlock(pte - 1, ptl);
+ cond_resched();
+
+ if (addr != end) {
+ /*
+ * We have consumed all precharges we got in can_attach().
+ * We try charge one by one, but don't do any additional
+ * charges to mc.to if we have failed in charge once in attach()
+ * phase.
+ */
+ ret = mem_cgroup_do_precharge(1);
+ if (!ret)
+ goto retry;
+ }
+
+ return ret;
+}
+
+static void mem_cgroup_move_charge(struct mm_struct *mm)
+{
+ struct vm_area_struct *vma;
+
+ lru_add_drain_all();
+ down_read(&mm->mmap_sem);
+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
+ int ret;
+ struct mm_walk mem_cgroup_move_charge_walk = {
+ .pmd_entry = mem_cgroup_move_charge_pte_range,
+ .mm = mm,
+ .private = vma,
+ };
+ if (is_vm_hugetlb_page(vma))
+ continue;
+ /* TODO: We don't move charges of shmem/tmpfs pages for now. */
+ if (vma->vm_flags & VM_SHARED)
+ continue;
+ ret = walk_page_range(vma->vm_start, vma->vm_end,
+ &mem_cgroup_move_charge_walk);
+ if (ret)
+ /*
+ * means we have consumed all precharges and failed in
+ * doing additional charge. Just abandon here.
+ */
+ break;
+ }
+ up_read(&mm->mmap_sem);
+}
+
static void mem_cgroup_move_task(struct cgroup_subsys *ss,
struct cgroup *cont,
struct cgroup *old_cont,
struct task_struct *p,
bool threadgroup)
{
- /*
- * FIXME: It's better to move charges of this process from old
- * memcg to new memcg. But it's just on TODO-List now.
- */
+ struct mm_struct *mm;
+
+ if (!mc.to)
+ /* no need to move charge */
+ return;
+
+ mm = get_task_mm(p);
+ if (mm) {
+ mem_cgroup_move_charge(mm);
+ mmput(mm);
+ }
+ mem_cgroup_clear_mc();
}
+#else /* !CONFIG_MMU */
+static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
+ struct cgroup *cgroup,
+ struct task_struct *p,
+ bool threadgroup)
+{
+ return 0;
+}
+static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss,
+ struct cgroup *cgroup,
+ struct task_struct *p,
+ bool threadgroup)
+{
+}
+static void mem_cgroup_move_task(struct cgroup_subsys *ss,
+ struct cgroup *cont,
+ struct cgroup *old_cont,
+ struct task_struct *p,
+ bool threadgroup)
+{
+}
+#endif
struct cgroup_subsys mem_cgroup_subsys = {
.name = "memory",
@@ -3400,6 +4340,8 @@ struct cgroup_subsys mem_cgroup_subsys = {
.pre_destroy = mem_cgroup_pre_destroy,
.destroy = mem_cgroup_destroy,
.populate = mem_cgroup_populate,
+ .can_attach = mem_cgroup_can_attach,
+ .cancel_attach = mem_cgroup_cancel_attach,
.attach = mem_cgroup_move_task,
.early_init = 0,
.use_id = 1,
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 17299fd4577..620b0b46159 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -44,6 +44,7 @@
#include <linux/migrate.h>
#include <linux/page-isolation.h>
#include <linux/suspend.h>
+#include <linux/slab.h>
#include "internal.h"
int sysctl_memory_failure_early_kill __read_mostly = 0;
@@ -383,9 +384,12 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
if (av == NULL) /* Not actually mapped anymore */
goto out;
for_each_process (tsk) {
+ struct anon_vma_chain *vmac;
+
if (!task_early_kill(tsk))
continue;
- list_for_each_entry (vma, &av->head, anon_vma_node) {
+ list_for_each_entry(vmac, &av->head, same_anon_vma) {
+ vma = vmac->vma;
if (!page_mapped_in_vma(page, vma))
continue;
if (vma->vm_mm == tsk->mm)
diff --git a/mm/memory.c b/mm/memory.c
index 72fb5f39bcc..833952d8b74 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -56,6 +56,7 @@
#include <linux/kallsyms.h>
#include <linux/swapops.h>
#include <linux/elf.h>
+#include <linux/gfp.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
@@ -121,6 +122,77 @@ static int __init init_zero_pfn(void)
}
core_initcall(init_zero_pfn);
+
+#if defined(SPLIT_RSS_COUNTING)
+
+static void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm)
+{
+ int i;
+
+ for (i = 0; i < NR_MM_COUNTERS; i++) {
+ if (task->rss_stat.count[i]) {
+ add_mm_counter(mm, i, task->rss_stat.count[i]);
+ task->rss_stat.count[i] = 0;
+ }
+ }
+ task->rss_stat.events = 0;
+}
+
+static void add_mm_counter_fast(struct mm_struct *mm, int member, int val)
+{
+ struct task_struct *task = current;
+
+ if (likely(task->mm == mm))
+ task->rss_stat.count[member] += val;
+ else
+ add_mm_counter(mm, member, val);
+}
+#define inc_mm_counter_fast(mm, member) add_mm_counter_fast(mm, member, 1)
+#define dec_mm_counter_fast(mm, member) add_mm_counter_fast(mm, member, -1)
+
+/* sync counter once per 64 page faults */
+#define TASK_RSS_EVENTS_THRESH (64)
+static void check_sync_rss_stat(struct task_struct *task)
+{
+ if (unlikely(task != current))
+ return;
+ if (unlikely(task->rss_stat.events++ > TASK_RSS_EVENTS_THRESH))
+ __sync_task_rss_stat(task, task->mm);
+}
+
+unsigned long get_mm_counter(struct mm_struct *mm, int member)
+{
+ long val = 0;
+
+ /*
+ * Don't use task->mm here...for avoiding to use task_get_mm()..
+ * The caller must guarantee task->mm is not invalid.
+ */
+ val = atomic_long_read(&mm->rss_stat.count[member]);
+ /*
+ * counter is updated in asynchronous manner and may go to minus.
+ * But it's never be expected number for users.
+ */
+ if (val < 0)
+ return 0;
+ return (unsigned long)val;
+}
+
+void sync_mm_rss(struct task_struct *task, struct mm_struct *mm)
+{
+ __sync_task_rss_stat(task, mm);
+}
+#else
+
+#define inc_mm_counter_fast(mm, member) inc_mm_counter(mm, member)
+#define dec_mm_counter_fast(mm, member) dec_mm_counter(mm, member)
+
+static void check_sync_rss_stat(struct task_struct *task)
+{
+}
+
+#endif
+
/*
* If a p?d_bad entry is found while walking page tables, report
* the error, before resetting entry to p?d_none. Usually (but
@@ -300,7 +372,7 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *vma,
* Hide vma from rmap and truncate_pagecache before freeing
* pgtables
*/
- anon_vma_unlink(vma);
+ unlink_anon_vmas(vma);
unlink_file_vma(vma);
if (is_vm_hugetlb_page(vma)) {
@@ -314,7 +386,7 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *vma,
&& !is_vm_hugetlb_page(next)) {
vma = next;
next = vma->vm_next;
- anon_vma_unlink(vma);
+ unlink_anon_vmas(vma);
unlink_file_vma(vma);
}
free_pgd_range(tlb, addr, vma->vm_end,
@@ -376,12 +448,20 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
return 0;
}
-static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss)
+static inline void init_rss_vec(int *rss)
{
- if (file_rss)
- add_mm_counter(mm, file_rss, file_rss);
- if (anon_rss)
- add_mm_counter(mm, anon_rss, anon_rss);
+ memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
+}
+
+static inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
+{
+ int i;
+
+ if (current->mm == mm)
+ sync_mm_rss(current, mm);
+ for (i = 0; i < NR_MM_COUNTERS; i++)
+ if (rss[i])
+ add_mm_counter(mm, i, rss[i]);
}
/*
@@ -430,12 +510,8 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
"BUG: Bad page map in process %s pte:%08llx pmd:%08llx\n",
current->comm,
(long long)pte_val(pte), (long long)pmd_val(*pmd));
- if (page) {
- printk(KERN_ALERT
- "page:%p flags:%p count:%d mapcount:%d mapping:%p index:%lx\n",
- page, (void *)page->flags, page_count(page),
- page_mapcount(page), page->mapping, page->index);
- }
+ if (page)
+ dump_page(page);
printk(KERN_ALERT
"addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n",
(void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
@@ -597,7 +673,9 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
&src_mm->mmlist);
spin_unlock(&mmlist_lock);
}
- if (is_write_migration_entry(entry) &&
+ if (likely(!non_swap_entry(entry)))
+ rss[MM_SWAPENTS]++;
+ else if (is_write_migration_entry(entry) &&
is_cow_mapping(vm_flags)) {
/*
* COW mappings require pages in both parent
@@ -632,7 +710,10 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
if (page) {
get_page(page);
page_dup_rmap(page);
- rss[PageAnon(page)]++;
+ if (PageAnon(page))
+ rss[MM_ANONPAGES]++;
+ else
+ rss[MM_FILEPAGES]++;
}
out_set_pte:
@@ -648,11 +729,12 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pte_t *src_pte, *dst_pte;
spinlock_t *src_ptl, *dst_ptl;
int progress = 0;
- int rss[2];
+ int rss[NR_MM_COUNTERS];
swp_entry_t entry = (swp_entry_t){0};
again:
- rss[1] = rss[0] = 0;
+ init_rss_vec(rss);
+
dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
if (!dst_pte)
return -ENOMEM;
@@ -688,7 +770,7 @@ again:
arch_leave_lazy_mmu_mode();
spin_unlock(src_ptl);
pte_unmap_nested(orig_src_pte);
- add_mm_rss(dst_mm, rss[0], rss[1]);
+ add_mm_rss_vec(dst_mm, rss);
pte_unmap_unlock(orig_dst_pte, dst_ptl);
cond_resched();
@@ -816,8 +898,9 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
struct mm_struct *mm = tlb->mm;
pte_t *pte;
spinlock_t *ptl;
- int file_rss = 0;
- int anon_rss = 0;
+ int rss[NR_MM_COUNTERS];
+
+ init_rss_vec(rss);
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
arch_enter_lazy_mmu_mode();
@@ -863,14 +946,14 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
set_pte_at(mm, addr, pte,
pgoff_to_pte(page->index));
if (PageAnon(page))
- anon_rss--;
+ rss[MM_ANONPAGES]--;
else {
if (pte_dirty(ptent))
set_page_dirty(page);
if (pte_young(ptent) &&
likely(!VM_SequentialReadHint(vma)))
mark_page_accessed(page);
- file_rss--;
+ rss[MM_FILEPAGES]--;
}
page_remove_rmap(page);
if (unlikely(page_mapcount(page) < 0))
@@ -887,13 +970,18 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
if (pte_file(ptent)) {
if (unlikely(!(vma->vm_flags & VM_NONLINEAR)))
print_bad_pte(vma, addr, ptent, NULL);
- } else if
- (unlikely(!free_swap_and_cache(pte_to_swp_entry(ptent))))
- print_bad_pte(vma, addr, ptent, NULL);
+ } else {
+ swp_entry_t entry = pte_to_swp_entry(ptent);
+
+ if (!non_swap_entry(entry))
+ rss[MM_SWAPENTS]--;
+ if (unlikely(!free_swap_and_cache(entry)))
+ print_bad_pte(vma, addr, ptent, NULL);
+ }
pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
} while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0));
- add_mm_rss(mm, file_rss, anon_rss);
+ add_mm_rss_vec(mm, rss);
arch_leave_lazy_mmu_mode();
pte_unmap_unlock(pte - 1, ptl);
@@ -1527,7 +1615,7 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
/* Ok, finally just insert the thing.. */
get_page(page);
- inc_mm_counter(mm, file_rss);
+ inc_mm_counter_fast(mm, MM_FILEPAGES);
page_add_file_rmap(page);
set_pte_at(mm, addr, pte, mk_pte(page, prot));
@@ -2044,6 +2132,13 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
page_cache_release(old_page);
}
reuse = reuse_swap_page(old_page);
+ if (reuse)
+ /*
+ * The page is all ours. Move it to our anon_vma so
+ * the rmap code will not search our parent or siblings.
+ * Protected against the rmap code by the page lock.
+ */
+ page_move_anon_rmap(old_page, vma, address);
unlock_page(old_page);
} else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
(VM_WRITE|VM_SHARED))) {
@@ -2163,11 +2258,11 @@ gotten:
if (likely(pte_same(*page_table, orig_pte))) {
if (old_page) {
if (!PageAnon(old_page)) {
- dec_mm_counter(mm, file_rss);
- inc_mm_counter(mm, anon_rss);
+ dec_mm_counter_fast(mm, MM_FILEPAGES);
+ inc_mm_counter_fast(mm, MM_ANONPAGES);
}
} else
- inc_mm_counter(mm, anon_rss);
+ inc_mm_counter_fast(mm, MM_ANONPAGES);
flush_cache_page(vma, address, pte_pfn(orig_pte));
entry = mk_pte(new_page, vma->vm_page_prot);
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
@@ -2604,7 +2699,8 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
* discarded at swap_free().
*/
- inc_mm_counter(mm, anon_rss);
+ inc_mm_counter_fast(mm, MM_ANONPAGES);
+ dec_mm_counter_fast(mm, MM_SWAPENTS);
pte = mk_pte(page, vma->vm_page_prot);
if ((flags & FAULT_FLAG_WRITE) && reuse_swap_page(page)) {
pte = maybe_mkwrite(pte_mkdirty(pte), vma);
@@ -2688,7 +2784,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
if (!pte_none(*page_table))
goto release;
- inc_mm_counter(mm, anon_rss);
+ inc_mm_counter_fast(mm, MM_ANONPAGES);
page_add_new_anon_rmap(page, vma, address);
setpte:
set_pte_at(mm, address, page_table, entry);
@@ -2842,10 +2938,10 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
if (flags & FAULT_FLAG_WRITE)
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
if (anon) {
- inc_mm_counter(mm, anon_rss);
+ inc_mm_counter_fast(mm, MM_ANONPAGES);
page_add_new_anon_rmap(page, vma, address);
} else {
- inc_mm_counter(mm, file_rss);
+ inc_mm_counter_fast(mm, MM_FILEPAGES);
page_add_file_rmap(page);
if (flags & FAULT_FLAG_WRITE) {
dirty_page = page;
@@ -3023,6 +3119,9 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
count_vm_event(PGFAULT);
+ /* do counter updates before entering really critical section. */
+ check_sync_rss_stat(current);
+
if (unlikely(is_vm_hugetlb_page(vma)))
return hugetlb_fault(mm, vma, address, flags);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 030ce8a5bb0..be211a58293 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -28,6 +28,7 @@
#include <linux/pfn.h>
#include <linux/suspend.h>
#include <linux/mm_inline.h>
+#include <linux/firmware-map.h>
#include <asm/tlbflush.h>
@@ -523,6 +524,9 @@ int __ref add_memory(int nid, u64 start, u64 size)
BUG_ON(ret);
}
+ /* create new memmap entry */
+ firmware_map_add_hotplug(start, start + size, "System RAM");
+
goto out;
error:
@@ -684,9 +688,9 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
if (page_count(page))
not_managed++;
#ifdef CONFIG_DEBUG_VM
- printk(KERN_INFO "removing from LRU failed"
- " %lx/%d/%lx\n",
- pfn, page_count(page), page->flags);
+ printk(KERN_ALERT "removing pfn %lx from LRU failed\n",
+ pfn);
+ dump_page(page);
#endif
}
}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 290fb5bf044..08f40a2f3fe 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -73,7 +73,6 @@
#include <linux/sched.h>
#include <linux/nodemask.h>
#include <linux/cpuset.h>
-#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/module.h>
@@ -563,24 +562,50 @@ static int policy_vma(struct vm_area_struct *vma, struct mempolicy *new)
}
/* Step 2: apply policy to a range and do splits. */
-static int mbind_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end, struct mempolicy *new)
+static int mbind_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end, struct mempolicy *new_pol)
{
struct vm_area_struct *next;
- int err;
+ struct vm_area_struct *prev;
+ struct vm_area_struct *vma;
+ int err = 0;
+ pgoff_t pgoff;
+ unsigned long vmstart;
+ unsigned long vmend;
- err = 0;
- for (; vma && vma->vm_start < end; vma = next) {
+ vma = find_vma_prev(mm, start, &prev);
+ if (!vma || vma->vm_start > start)
+ return -EFAULT;
+
+ for (; vma && vma->vm_start < end; prev = vma, vma = next) {
next = vma->vm_next;
- if (vma->vm_start < start)
- err = split_vma(vma->vm_mm, vma, start, 1);
- if (!err && vma->vm_end > end)
- err = split_vma(vma->vm_mm, vma, end, 0);
- if (!err)
- err = policy_vma(vma, new);
+ vmstart = max(start, vma->vm_start);
+ vmend = min(end, vma->vm_end);
+
+ pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
+ prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
+ vma->anon_vma, vma->vm_file, pgoff, new_pol);
+ if (prev) {
+ vma = prev;
+ next = vma->vm_next;
+ continue;
+ }
+ if (vma->vm_start != vmstart) {
+ err = split_vma(vma->vm_mm, vma, vmstart, 1);
+ if (err)
+ goto out;
+ }
+ if (vma->vm_end != vmend) {
+ err = split_vma(vma->vm_mm, vma, vmend, 0);
+ if (err)
+ goto out;
+ }
+ err = policy_vma(vma, new_pol);
if (err)
- break;
+ goto out;
}
+
+ out:
return err;
}
@@ -780,9 +805,13 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
err = 0;
if (nmask) {
- task_lock(current);
- get_policy_nodemask(pol, nmask);
- task_unlock(current);
+ if (mpol_store_user_nodemask(pol)) {
+ *nmask = pol->w.user_nodemask;
+ } else {
+ task_lock(current);
+ get_policy_nodemask(pol, nmask);
+ task_unlock(current);
+ }
}
out:
@@ -862,36 +891,36 @@ int do_migrate_pages(struct mm_struct *mm,
if (err)
goto out;
-/*
- * Find a 'source' bit set in 'tmp' whose corresponding 'dest'
- * bit in 'to' is not also set in 'tmp'. Clear the found 'source'
- * bit in 'tmp', and return that <source, dest> pair for migration.
- * The pair of nodemasks 'to' and 'from' define the map.
- *
- * If no pair of bits is found that way, fallback to picking some
- * pair of 'source' and 'dest' bits that are not the same. If the
- * 'source' and 'dest' bits are the same, this represents a node
- * that will be migrating to itself, so no pages need move.
- *
- * If no bits are left in 'tmp', or if all remaining bits left
- * in 'tmp' correspond to the same bit in 'to', return false
- * (nothing left to migrate).
- *
- * This lets us pick a pair of nodes to migrate between, such that
- * if possible the dest node is not already occupied by some other
- * source node, minimizing the risk of overloading the memory on a
- * node that would happen if we migrated incoming memory to a node
- * before migrating outgoing memory source that same node.
- *
- * A single scan of tmp is sufficient. As we go, we remember the
- * most recent <s, d> pair that moved (s != d). If we find a pair
- * that not only moved, but what's better, moved to an empty slot
- * (d is not set in tmp), then we break out then, with that pair.
- * Otherwise when we finish scannng from_tmp, we at least have the
- * most recent <s, d> pair that moved. If we get all the way through
- * the scan of tmp without finding any node that moved, much less
- * moved to an empty node, then there is nothing left worth migrating.
- */
+ /*
+ * Find a 'source' bit set in 'tmp' whose corresponding 'dest'
+ * bit in 'to' is not also set in 'tmp'. Clear the found 'source'
+ * bit in 'tmp', and return that <source, dest> pair for migration.
+ * The pair of nodemasks 'to' and 'from' define the map.
+ *
+ * If no pair of bits is found that way, fallback to picking some
+ * pair of 'source' and 'dest' bits that are not the same. If the
+ * 'source' and 'dest' bits are the same, this represents a node
+ * that will be migrating to itself, so no pages need move.
+ *
+ * If no bits are left in 'tmp', or if all remaining bits left
+ * in 'tmp' correspond to the same bit in 'to', return false
+ * (nothing left to migrate).
+ *
+ * This lets us pick a pair of nodes to migrate between, such that
+ * if possible the dest node is not already occupied by some other
+ * source node, minimizing the risk of overloading the memory on a
+ * node that would happen if we migrated incoming memory to a node
+ * before migrating outgoing memory source that same node.
+ *
+ * A single scan of tmp is sufficient. As we go, we remember the
+ * most recent <s, d> pair that moved (s != d). If we find a pair
+ * that not only moved, but what's better, moved to an empty slot
+ * (d is not set in tmp), then we break out then, with that pair.
+ * Otherwise when we finish scannng from_tmp, we at least have the
+ * most recent <s, d> pair that moved. If we get all the way through
+ * the scan of tmp without finding any node that moved, much less
+ * moved to an empty node, then there is nothing left worth migrating.
+ */
tmp = *from_nodes;
while (!nodes_empty(tmp)) {
@@ -1047,7 +1076,7 @@ static long do_mbind(unsigned long start, unsigned long len,
if (!IS_ERR(vma)) {
int nr_failed = 0;
- err = mbind_range(vma, start, end, new);
+ err = mbind_range(mm, start, end, new);
if (!list_empty(&pagelist))
nr_failed = migrate_pages(&pagelist, new_vma_page,
@@ -1730,10 +1759,12 @@ struct mempolicy *__mpol_dup(struct mempolicy *old)
if (!new)
return ERR_PTR(-ENOMEM);
+ rcu_read_lock();
if (current_cpuset_is_being_rebound()) {
nodemask_t mems = cpuset_mems_allowed(current);
mpol_rebind_policy(old, &mems);
}
+ rcu_read_unlock();
*new = *old;
atomic_set(&new->refcnt, 1);
return new;
@@ -2167,8 +2198,8 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
char *rest = nodelist;
while (isdigit(*rest))
rest++;
- if (!*rest)
- err = 0;
+ if (*rest)
+ goto out;
}
break;
case MPOL_INTERLEAVE:
@@ -2177,7 +2208,6 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
*/
if (!nodelist)
nodes = node_states[N_HIGH_MEMORY];
- err = 0;
break;
case MPOL_LOCAL:
/*
@@ -2187,11 +2217,19 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
goto out;
mode = MPOL_PREFERRED;
break;
-
- /*
- * case MPOL_BIND: mpol_new() enforces non-empty nodemask.
- * case MPOL_DEFAULT: mpol_new() enforces empty nodemask, ignores flags.
- */
+ case MPOL_DEFAULT:
+ /*
+ * Insist on a empty nodelist
+ */
+ if (!nodelist)
+ err = 0;
+ goto out;
+ case MPOL_BIND:
+ /*
+ * Insist on a nodelist
+ */
+ if (!nodelist)
+ goto out;
}
mode_flags = 0;
@@ -2205,13 +2243,14 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
else if (!strcmp(flags, "relative"))
mode_flags |= MPOL_F_RELATIVE_NODES;
else
- err = 1;
+ goto out;
}
new = mpol_new(mode, mode_flags, &nodes);
if (IS_ERR(new))
- err = 1;
- else {
+ goto out;
+
+ {
int ret;
NODEMASK_SCRATCH(scratch);
if (scratch) {
@@ -2222,13 +2261,15 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
ret = -ENOMEM;
NODEMASK_SCRATCH_FREE(scratch);
if (ret) {
- err = 1;
mpol_put(new);
- } else if (no_context) {
- /* save for contextualization */
- new->w.user_nodemask = nodes;
+ goto out;
}
}
+ err = 0;
+ if (no_context) {
+ /* save for contextualization */
+ new->w.user_nodemask = nodes;
+ }
out:
/* Restore string for error message */
diff --git a/mm/migrate.c b/mm/migrate.c
index edb6101ed77..d3f3f7f8107 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -32,6 +32,7 @@
#include <linux/security.h>
#include <linux/memcontrol.h>
#include <linux/syscalls.h>
+#include <linux/gfp.h>
#include "internal.h"
@@ -275,8 +276,6 @@ static int migrate_page_move_mapping(struct address_space *mapping,
*/
static void migrate_page_copy(struct page *newpage, struct page *page)
{
- int anon;
-
copy_highpage(newpage, page);
if (PageError(page))
@@ -313,8 +312,6 @@ static void migrate_page_copy(struct page *newpage, struct page *page)
ClearPageSwapCache(page);
ClearPagePrivate(page);
set_page_private(page, 0);
- /* page->mapping contains a flag for PageAnon() */
- anon = PageAnon(page);
page->mapping = NULL;
/*
diff --git a/mm/mincore.c b/mm/mincore.c
index 7a3436ef39e..f77433c2027 100644
--- a/mm/mincore.c
+++ b/mm/mincore.c
@@ -7,8 +7,8 @@
/*
* The mincore() system call.
*/
-#include <linux/slab.h>
#include <linux/pagemap.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/syscalls.h>
diff --git a/mm/mlock.c b/mm/mlock.c
index 2b8335a8940..8f4e2dfceec 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -25,7 +25,7 @@ int can_do_mlock(void)
{
if (capable(CAP_IPC_LOCK))
return 1;
- if (current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur != 0)
+ if (rlimit(RLIMIT_MEMLOCK) != 0)
return 1;
return 0;
}
@@ -487,7 +487,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
locked = len >> PAGE_SHIFT;
locked += current->mm->locked_vm;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlimit(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
/* check against resource limits */
@@ -550,7 +550,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
down_write(&current->mm->mmap_sem);
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlimit(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
ret = -ENOMEM;
@@ -584,7 +584,7 @@ int user_shm_lock(size_t size, struct user_struct *user)
int allowed = 0;
locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlimit(RLIMIT_MEMLOCK);
if (lock_limit == RLIM_INFINITY)
allowed = 1;
lock_limit >>= PAGE_SHIFT;
@@ -618,12 +618,12 @@ int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
down_write(&mm->mmap_sem);
- lim = rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
+ lim = ACCESS_ONCE(rlim[RLIMIT_AS].rlim_cur) >> PAGE_SHIFT;
vm = mm->total_vm + pgsz;
if (lim < vm)
goto out;
- lim = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+ lim = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur) >> PAGE_SHIFT;
vm = mm->locked_vm + pgsz;
if (lim < vm)
goto out;
diff --git a/mm/mmap.c b/mm/mmap.c
index ee2298936fe..456ec6f2788 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -265,7 +265,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
* segment grow beyond its set limit the in case where the limit is
* not page aligned -Ram Gupta
*/
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+ rlim = rlimit(RLIMIT_DATA);
if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
(mm->end_data - mm->start_data) > rlim)
goto out;
@@ -437,7 +437,6 @@ __vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
{
__vma_link_list(mm, vma, prev, rb_parent);
__vma_link_rb(mm, vma, rb_link, rb_parent);
- __anon_vma_link(vma);
}
static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -499,7 +498,7 @@ __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma,
* are necessary. The "insert" vma (if any) is to be inserted
* before we drop the necessary locks.
*/
-void vma_adjust(struct vm_area_struct *vma, unsigned long start,
+int vma_adjust(struct vm_area_struct *vma, unsigned long start,
unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert)
{
struct mm_struct *mm = vma->vm_mm;
@@ -508,11 +507,12 @@ void vma_adjust(struct vm_area_struct *vma, unsigned long start,
struct address_space *mapping = NULL;
struct prio_tree_root *root = NULL;
struct file *file = vma->vm_file;
- struct anon_vma *anon_vma = NULL;
long adjust_next = 0;
int remove_next = 0;
if (next && !insert) {
+ struct vm_area_struct *exporter = NULL;
+
if (end >= next->vm_end) {
/*
* vma expands, overlapping all the next, and
@@ -520,7 +520,7 @@ void vma_adjust(struct vm_area_struct *vma, unsigned long start,
*/
again: remove_next = 1 + (end > next->vm_end);
end = next->vm_end;
- anon_vma = next->anon_vma;
+ exporter = next;
importer = vma;
} else if (end > next->vm_start) {
/*
@@ -528,7 +528,7 @@ again: remove_next = 1 + (end > next->vm_end);
* mprotect case 5 shifting the boundary up.
*/
adjust_next = (end - next->vm_start) >> PAGE_SHIFT;
- anon_vma = next->anon_vma;
+ exporter = next;
importer = vma;
} else if (end < vma->vm_end) {
/*
@@ -537,9 +537,20 @@ again: remove_next = 1 + (end > next->vm_end);
* mprotect case 4 shifting the boundary down.
*/
adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT);
- anon_vma = next->anon_vma;
+ exporter = vma;
importer = next;
}
+
+ /*
+ * Easily overlooked: when mprotect shifts the boundary,
+ * make sure the expanding vma has anon_vma set if the
+ * shrinking vma had, to cover any anon pages imported.
+ */
+ if (exporter && exporter->anon_vma && !importer->anon_vma) {
+ if (anon_vma_clone(importer, exporter))
+ return -ENOMEM;
+ importer->anon_vma = exporter->anon_vma;
+ }
}
if (file) {
@@ -567,25 +578,6 @@ again: remove_next = 1 + (end > next->vm_end);
}
}
- /*
- * When changing only vma->vm_end, we don't really need
- * anon_vma lock.
- */
- if (vma->anon_vma && (insert || importer || start != vma->vm_start))
- anon_vma = vma->anon_vma;
- if (anon_vma) {
- spin_lock(&anon_vma->lock);
- /*
- * Easily overlooked: when mprotect shifts the boundary,
- * make sure the expanding vma has anon_vma set if the
- * shrinking vma had, to cover any anon pages imported.
- */
- if (importer && !importer->anon_vma) {
- importer->anon_vma = anon_vma;
- __anon_vma_link(importer);
- }
- }
-
if (root) {
flush_dcache_mmap_lock(mapping);
vma_prio_tree_remove(vma, root);
@@ -616,8 +608,6 @@ again: remove_next = 1 + (end > next->vm_end);
__vma_unlink(mm, next, vma);
if (file)
__remove_shared_vm_struct(next, file, mapping);
- if (next->anon_vma)
- __anon_vma_merge(vma, next);
} else if (insert) {
/*
* split_vma has split insert from vma, and needs
@@ -627,8 +617,6 @@ again: remove_next = 1 + (end > next->vm_end);
__insert_vm_struct(mm, insert);
}
- if (anon_vma)
- spin_unlock(&anon_vma->lock);
if (mapping)
spin_unlock(&mapping->i_mmap_lock);
@@ -638,6 +626,8 @@ again: remove_next = 1 + (end > next->vm_end);
if (next->vm_flags & VM_EXECUTABLE)
removed_exe_file_vma(mm);
}
+ if (next->anon_vma)
+ anon_vma_merge(vma, next);
mm->map_count--;
mpol_put(vma_policy(next));
kmem_cache_free(vm_area_cachep, next);
@@ -653,6 +643,8 @@ again: remove_next = 1 + (end > next->vm_end);
}
validate_mm(mm);
+
+ return 0;
}
/*
@@ -759,6 +751,7 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
{
pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
struct vm_area_struct *area, *next;
+ int err;
/*
* We later require that vma->vm_flags == vm_flags,
@@ -792,11 +785,13 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
is_mergeable_anon_vma(prev->anon_vma,
next->anon_vma)) {
/* cases 1, 6 */
- vma_adjust(prev, prev->vm_start,
+ err = vma_adjust(prev, prev->vm_start,
next->vm_end, prev->vm_pgoff, NULL);
} else /* cases 2, 5, 7 */
- vma_adjust(prev, prev->vm_start,
+ err = vma_adjust(prev, prev->vm_start,
end, prev->vm_pgoff, NULL);
+ if (err)
+ return NULL;
return prev;
}
@@ -808,11 +803,13 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
can_vma_merge_before(next, vm_flags,
anon_vma, file, pgoff+pglen)) {
if (prev && addr < prev->vm_end) /* case 4 */
- vma_adjust(prev, prev->vm_start,
+ err = vma_adjust(prev, prev->vm_start,
addr, prev->vm_pgoff, NULL);
else /* cases 3, 8 */
- vma_adjust(area, addr, next->vm_end,
+ err = vma_adjust(area, addr, next->vm_end,
next->vm_pgoff - pglen, NULL);
+ if (err)
+ return NULL;
return area;
}
@@ -820,6 +817,61 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
}
/*
+ * Rough compatbility check to quickly see if it's even worth looking
+ * at sharing an anon_vma.
+ *
+ * They need to have the same vm_file, and the flags can only differ
+ * in things that mprotect may change.
+ *
+ * NOTE! The fact that we share an anon_vma doesn't _have_ to mean that
+ * we can merge the two vma's. For example, we refuse to merge a vma if
+ * there is a vm_ops->close() function, because that indicates that the
+ * driver is doing some kind of reference counting. But that doesn't
+ * really matter for the anon_vma sharing case.
+ */
+static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *b)
+{
+ return a->vm_end == b->vm_start &&
+ mpol_equal(vma_policy(a), vma_policy(b)) &&
+ a->vm_file == b->vm_file &&
+ !((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC)) &&
+ b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT);
+}
+
+/*
+ * Do some basic sanity checking to see if we can re-use the anon_vma
+ * from 'old'. The 'a'/'b' vma's are in VM order - one of them will be
+ * the same as 'old', the other will be the new one that is trying
+ * to share the anon_vma.
+ *
+ * NOTE! This runs with mm_sem held for reading, so it is possible that
+ * the anon_vma of 'old' is concurrently in the process of being set up
+ * by another page fault trying to merge _that_. But that's ok: if it
+ * is being set up, that automatically means that it will be a singleton
+ * acceptable for merging, so we can do all of this optimistically. But
+ * we do that ACCESS_ONCE() to make sure that we never re-load the pointer.
+ *
+ * IOW: that the "list_is_singular()" test on the anon_vma_chain only
+ * matters for the 'stable anon_vma' case (ie the thing we want to avoid
+ * is to return an anon_vma that is "complex" due to having gone through
+ * a fork).
+ *
+ * We also make sure that the two vma's are compatible (adjacent,
+ * and with the same memory policies). That's all stable, even with just
+ * a read lock on the mm_sem.
+ */
+static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_area_struct *a, struct vm_area_struct *b)
+{
+ if (anon_vma_compatible(a, b)) {
+ struct anon_vma *anon_vma = ACCESS_ONCE(old->anon_vma);
+
+ if (anon_vma && list_is_singular(&old->anon_vma_chain))
+ return anon_vma;
+ }
+ return NULL;
+}
+
+/*
* find_mergeable_anon_vma is used by anon_vma_prepare, to check
* neighbouring vmas for a suitable anon_vma, before it goes off
* to allocate a new anon_vma. It checks because a repetitive
@@ -829,28 +881,16 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
*/
struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma)
{
+ struct anon_vma *anon_vma;
struct vm_area_struct *near;
- unsigned long vm_flags;
near = vma->vm_next;
if (!near)
goto try_prev;
- /*
- * Since only mprotect tries to remerge vmas, match flags
- * which might be mprotected into each other later on.
- * Neither mlock nor madvise tries to remerge at present,
- * so leave their flags as obstructing a merge.
- */
- vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC);
- vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC);
-
- if (near->anon_vma && vma->vm_end == near->vm_start &&
- mpol_equal(vma_policy(vma), vma_policy(near)) &&
- can_vma_merge_before(near, vm_flags,
- NULL, vma->vm_file, vma->vm_pgoff +
- ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)))
- return near->anon_vma;
+ anon_vma = reusable_anon_vma(near, vma, near);
+ if (anon_vma)
+ return anon_vma;
try_prev:
/*
* It is potentially slow to have to call find_vma_prev here.
@@ -863,14 +903,9 @@ try_prev:
if (!near)
goto none;
- vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC);
- vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC);
-
- if (near->anon_vma && near->vm_end == vma->vm_start &&
- mpol_equal(vma_policy(near), vma_policy(vma)) &&
- can_vma_merge_after(near, vm_flags,
- NULL, vma->vm_file, vma->vm_pgoff))
- return near->anon_vma;
+ anon_vma = reusable_anon_vma(near, near, vma);
+ if (anon_vma)
+ return anon_vma;
none:
/*
* There's no absolute need to look only at touching neighbours:
@@ -967,7 +1002,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long locked, lock_limit;
locked = len >> PAGE_SHIFT;
locked += mm->locked_vm;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlimit(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
return -EAGAIN;
@@ -1083,6 +1118,30 @@ out:
return retval;
}
+#ifdef __ARCH_WANT_SYS_OLD_MMAP
+struct mmap_arg_struct {
+ unsigned long addr;
+ unsigned long len;
+ unsigned long prot;
+ unsigned long flags;
+ unsigned long fd;
+ unsigned long offset;
+};
+
+SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
+{
+ struct mmap_arg_struct a;
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ return -EFAULT;
+ if (a.offset & ~PAGE_MASK)
+ return -EINVAL;
+
+ return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+ a.offset >> PAGE_SHIFT);
+}
+#endif /* __ARCH_WANT_SYS_OLD_MMAP */
+
/*
* Some shared mappigns will want the pages marked read-only
* to track write events. If so, we'll downgrade vm_page_prot
@@ -1205,6 +1264,7 @@ munmap_back:
vma->vm_flags = vm_flags;
vma->vm_page_prot = vm_get_page_prot(vm_flags);
vma->vm_pgoff = pgoff;
+ INIT_LIST_HEAD(&vma->anon_vma_chain);
if (file) {
error = -EINVAL;
@@ -1265,13 +1325,8 @@ out:
mm->total_vm += len >> PAGE_SHIFT;
vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
if (vm_flags & VM_LOCKED) {
- /*
- * makes pages present; downgrades, drops, reacquires mmap_sem
- */
- long nr_pages = mlock_vma_pages_range(vma, addr, addr + len);
- if (nr_pages < 0)
- return nr_pages; /* vma gone! */
- mm->locked_vm += (len >> PAGE_SHIFT) - nr_pages;
+ if (!mlock_vma_pages_range(vma, addr, addr + len))
+ mm->locked_vm += (len >> PAGE_SHIFT);
} else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
make_pages_present(addr, addr + len);
return addr;
@@ -1599,7 +1654,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
return -ENOMEM;
/* Stack limit test */
- if (size > rlim[RLIMIT_STACK].rlim_cur)
+ if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
return -ENOMEM;
/* mlock limit tests */
@@ -1607,7 +1662,8 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
unsigned long locked;
unsigned long limit;
locked = mm->locked_vm + grow;
- limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+ limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur);
+ limit >>= PAGE_SHIFT;
if (locked > limit && !capable(CAP_IPC_LOCK))
return -ENOMEM;
}
@@ -1754,8 +1810,7 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
if (!prev || expand_stack(prev, addr))
return NULL;
if (prev->vm_flags & VM_LOCKED) {
- if (mlock_vma_pages_range(prev, addr, prev->vm_end) < 0)
- return NULL; /* vma gone! */
+ mlock_vma_pages_range(prev, addr, prev->vm_end);
}
return prev;
}
@@ -1783,8 +1838,7 @@ find_extend_vma(struct mm_struct * mm, unsigned long addr)
if (expand_stack(vma, addr))
return NULL;
if (vma->vm_flags & VM_LOCKED) {
- if (mlock_vma_pages_range(vma, addr, start) < 0)
- return NULL; /* vma gone! */
+ mlock_vma_pages_range(vma, addr, start);
}
return vma;
}
@@ -1871,6 +1925,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
{
struct mempolicy *pol;
struct vm_area_struct *new;
+ int err = -ENOMEM;
if (is_vm_hugetlb_page(vma) && (addr &
~(huge_page_mask(hstate_vma(vma)))))
@@ -1878,11 +1933,13 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
if (!new)
- return -ENOMEM;
+ goto out_err;
/* most fields are the same, copy all, and then fixup */
*new = *vma;
+ INIT_LIST_HEAD(&new->anon_vma_chain);
+
if (new_below)
new->vm_end = addr;
else {
@@ -1892,11 +1949,14 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
pol = mpol_dup(vma_policy(vma));
if (IS_ERR(pol)) {
- kmem_cache_free(vm_area_cachep, new);
- return PTR_ERR(pol);
+ err = PTR_ERR(pol);
+ goto out_free_vma;
}
vma_set_policy(new, pol);
+ if (anon_vma_clone(new, vma))
+ goto out_free_mpol;
+
if (new->vm_file) {
get_file(new->vm_file);
if (vma->vm_flags & VM_EXECUTABLE)
@@ -1907,12 +1967,29 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
new->vm_ops->open(new);
if (new_below)
- vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
+ err = vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
((addr - new->vm_start) >> PAGE_SHIFT), new);
else
- vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
+ err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
- return 0;
+ /* Success. */
+ if (!err)
+ return 0;
+
+ /* Clean everything up if vma_adjust failed. */
+ if (new->vm_ops && new->vm_ops->close)
+ new->vm_ops->close(new);
+ if (new->vm_file) {
+ if (vma->vm_flags & VM_EXECUTABLE)
+ removed_exe_file_vma(mm);
+ fput(new->vm_file);
+ }
+ out_free_mpol:
+ mpol_put(pol);
+ out_free_vma:
+ kmem_cache_free(vm_area_cachep, new);
+ out_err:
+ return err;
}
/*
@@ -2074,7 +2151,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
unsigned long locked, lock_limit;
locked = len >> PAGE_SHIFT;
locked += mm->locked_vm;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlimit(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
return -EAGAIN;
@@ -2122,6 +2199,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
return -ENOMEM;
}
+ INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_mm = mm;
vma->vm_start = addr;
vma->vm_end = addr + len;
@@ -2258,10 +2336,11 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
if (new_vma) {
*new_vma = *vma;
pol = mpol_dup(vma_policy(vma));
- if (IS_ERR(pol)) {
- kmem_cache_free(vm_area_cachep, new_vma);
- return NULL;
- }
+ if (IS_ERR(pol))
+ goto out_free_vma;
+ INIT_LIST_HEAD(&new_vma->anon_vma_chain);
+ if (anon_vma_clone(new_vma, vma))
+ goto out_free_mempol;
vma_set_policy(new_vma, pol);
new_vma->vm_start = addr;
new_vma->vm_end = addr + len;
@@ -2277,6 +2356,12 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
}
}
return new_vma;
+
+ out_free_mempol:
+ mpol_put(pol);
+ out_free_vma:
+ kmem_cache_free(vm_area_cachep, new_vma);
+ return NULL;
}
/*
@@ -2288,7 +2373,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
unsigned long cur = mm->total_vm; /* pages */
unsigned long lim;
- lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
+ lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT;
if (cur + npages > lim)
return 0;
@@ -2354,6 +2439,7 @@ int install_special_mapping(struct mm_struct *mm,
if (unlikely(vma == NULL))
return -ENOMEM;
+ INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_mm = mm;
vma->vm_start = addr;
vma->vm_end = addr + len;
@@ -2454,6 +2540,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping)
int mm_take_all_locks(struct mm_struct *mm)
{
struct vm_area_struct *vma;
+ struct anon_vma_chain *avc;
int ret = -EINTR;
BUG_ON(down_read_trylock(&mm->mmap_sem));
@@ -2471,7 +2558,8 @@ int mm_take_all_locks(struct mm_struct *mm)
if (signal_pending(current))
goto out_unlock;
if (vma->anon_vma)
- vm_lock_anon_vma(mm, vma->anon_vma);
+ list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+ vm_lock_anon_vma(mm, avc->anon_vma);
}
ret = 0;
@@ -2526,13 +2614,15 @@ static void vm_unlock_mapping(struct address_space *mapping)
void mm_drop_all_locks(struct mm_struct *mm)
{
struct vm_area_struct *vma;
+ struct anon_vma_chain *avc;
BUG_ON(down_read_trylock(&mm->mmap_sem));
BUG_ON(!mutex_is_locked(&mm_all_locks_mutex));
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (vma->anon_vma)
- vm_unlock_anon_vma(vma->anon_vma);
+ list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+ vm_unlock_anon_vma(avc->anon_vma);
if (vma->vm_file && vma->vm_file->f_mapping)
vm_unlock_mapping(vma->vm_file->f_mapping);
}
diff --git a/mm/mmu_context.c b/mm/mmu_context.c
index 0777654147c..9e82e937000 100644
--- a/mm/mmu_context.c
+++ b/mm/mmu_context.c
@@ -53,6 +53,7 @@ void unuse_mm(struct mm_struct *mm)
struct task_struct *tsk = current;
task_lock(tsk);
+ sync_mm_rss(tsk, mm);
tsk->mm = NULL;
/* active_mm is still 'mm' */
enter_lazy_tlb(mm, tsk);
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index 7e33f2cb3c7..438951d366f 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
+#include <linux/slab.h>
/*
* This function can't run concurrently against mmu_notifier_register
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 8bc969d8112..2d1bf7cf885 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -10,7 +10,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
-#include <linux/slab.h>
#include <linux/shm.h>
#include <linux/mman.h>
#include <linux/fs.h>
diff --git a/mm/mremap.c b/mm/mremap.c
index 845190898d5..cde56ee51ef 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -9,7 +9,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
-#include <linux/slab.h>
#include <linux/shm.h>
#include <linux/ksm.h>
#include <linux/mman.h>
@@ -285,7 +284,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
if (vma->vm_flags & VM_LOCKED) {
unsigned long locked, lock_limit;
locked = mm->locked_vm << PAGE_SHIFT;
- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ lock_limit = rlimit(RLIMIT_MEMLOCK);
locked += new_len - old_len;
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
goto Eagain;
@@ -460,8 +459,11 @@ unsigned long do_mremap(unsigned long addr,
if (vma_expandable(vma, new_len - old_len)) {
int pages = (new_len - old_len) >> PAGE_SHIFT;
- vma_adjust(vma, vma->vm_start,
- addr + new_len, vma->vm_pgoff, NULL);
+ if (vma_adjust(vma, vma->vm_start, addr + new_len,
+ vma->vm_pgoff, NULL)) {
+ ret = -ENOMEM;
+ goto out;
+ }
mm->total_vm += pages;
vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
diff --git a/mm/nommu.c b/mm/nommu.c
index 48a2ecfaf05..63fa17d121f 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -162,7 +162,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
}
if (vmas)
vmas[i] = vma;
- start += PAGE_SIZE;
+ start = (start + PAGE_SIZE) & PAGE_MASK;
}
return i;
@@ -1040,10 +1040,9 @@ static int do_mmap_shared_file(struct vm_area_struct *vma)
if (ret != -ENOSYS)
return ret;
- /* getting an ENOSYS error indicates that direct mmap isn't
- * possible (as opposed to tried but failed) so we'll fall
- * through to making a private copy of the data and mapping
- * that if we can */
+ /* getting -ENOSYS indicates that direct mmap isn't possible (as
+ * opposed to tried but failed) so we can only give a suitable error as
+ * it's not possible to make a private copy if MAP_SHARED was given */
return -ENODEV;
}
@@ -1209,7 +1208,7 @@ unsigned long do_mmap_pgoff(struct file *file,
region->vm_flags = vm_flags;
region->vm_pgoff = pgoff;
- INIT_LIST_HEAD(&vma->anon_vma_node);
+ INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_flags = vm_flags;
vma->vm_pgoff = pgoff;
@@ -1428,6 +1427,30 @@ out:
return retval;
}
+#ifdef __ARCH_WANT_SYS_OLD_MMAP
+struct mmap_arg_struct {
+ unsigned long addr;
+ unsigned long len;
+ unsigned long prot;
+ unsigned long flags;
+ unsigned long fd;
+ unsigned long offset;
+};
+
+SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
+{
+ struct mmap_arg_struct a;
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ return -EFAULT;
+ if (a.offset & ~PAGE_MASK)
+ return -EINVAL;
+
+ return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
+ a.offset >> PAGE_SHIFT);
+}
+#endif /* __ARCH_WANT_SYS_OLD_MMAP */
+
/*
* split a vma into two pieces at address 'addr', a new vma is allocated either
* for the first part or the tail.
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 237050478f2..b68e802a7a7 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -18,6 +18,7 @@
#include <linux/oom.h>
#include <linux/mm.h>
#include <linux/err.h>
+#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/swap.h>
#include <linux/timex.h>
@@ -401,8 +402,8 @@ static void __oom_kill_task(struct task_struct *p, int verbose)
"vsz:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
task_pid_nr(p), p->comm,
K(p->mm->total_vm),
- K(get_mm_counter(p->mm, anon_rss)),
- K(get_mm_counter(p->mm, file_rss)));
+ K(get_mm_counter(p->mm, MM_ANONPAGES)),
+ K(get_mm_counter(p->mm, MM_FILEPAGES)));
task_unlock(p);
/*
@@ -473,6 +474,8 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask)
unsigned long points = 0;
struct task_struct *p;
+ if (sysctl_panic_on_oom == 2)
+ panic("out of memory(memcg). panic_on_oom is selected.\n");
read_lock(&tasklist_lock);
retry:
p = select_bad_process(&points, mem);
@@ -601,13 +604,6 @@ void pagefault_out_of_memory(void)
/* Got some memory back in the last second. */
return;
- /*
- * If this is from memcg, oom-killer is already invoked.
- * and not worth to go system-wide-oom.
- */
- if (mem_cgroup_oom_called(current))
- goto rest_and_return;
-
if (sysctl_panic_on_oom)
panic("out of memory from page fault. panic_on_oom is selected.\n");
@@ -619,7 +615,6 @@ void pagefault_out_of_memory(void)
* Give "p" a good chance of killing itself before we
* retry to allocate memory.
*/
-rest_and_return:
if (!test_thread_flag(TIF_MEMDIE))
schedule_timeout_uninterruptible(1);
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a6b17aa4740..d03c946d556 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -50,6 +50,7 @@
#include <linux/kmemleak.h>
#include <linux/memory.h>
#include <trace/events/kmem.h>
+#include <linux/ftrace_event.h>
#include <asm/tlbflush.h>
#include <asm/div64.h>
@@ -76,6 +77,31 @@ unsigned long totalreserve_pages __read_mostly;
int percpu_pagelist_fraction;
gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
+#ifdef CONFIG_PM_SLEEP
+/*
+ * The following functions are used by the suspend/hibernate code to temporarily
+ * change gfp_allowed_mask in order to avoid using I/O during memory allocations
+ * while devices are suspended. To avoid races with the suspend/hibernate code,
+ * they should always be called with pm_mutex held (gfp_allowed_mask also should
+ * only be modified with pm_mutex held, unless the suspend/hibernate code is
+ * guaranteed not to run in parallel with that modification).
+ */
+void set_gfp_allowed_mask(gfp_t mask)
+{
+ WARN_ON(!mutex_is_locked(&pm_mutex));
+ gfp_allowed_mask = mask;
+}
+
+gfp_t clear_gfp_allowed_mask(gfp_t mask)
+{
+ gfp_t ret = gfp_allowed_mask;
+
+ WARN_ON(!mutex_is_locked(&pm_mutex));
+ gfp_allowed_mask &= ~mask;
+ return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
int pageblock_order __read_mostly;
#endif
@@ -263,10 +289,7 @@ static void bad_page(struct page *page)
printk(KERN_ALERT "BUG: Bad page state in process %s pfn:%05lx\n",
current->comm, page_to_pfn(page));
- printk(KERN_ALERT
- "page:%p flags:%p count:%d mapcount:%d mapping:%p index:%lx\n",
- page, (void *)page->flags, page_count(page),
- page_mapcount(page), page->mapping, page->index);
+ dump_page(page);
dump_stack();
out:
@@ -530,7 +553,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
int batch_free = 0;
spin_lock(&zone->lock);
- zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
+ zone->all_unreclaimable = 0;
zone->pages_scanned = 0;
__mod_zone_page_state(zone, NR_FREE_PAGES, count);
@@ -568,7 +591,7 @@ static void free_one_page(struct zone *zone, struct page *page, int order,
int migratetype)
{
spin_lock(&zone->lock);
- zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
+ zone->all_unreclaimable = 0;
zone->pages_scanned = 0;
__mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
@@ -583,6 +606,7 @@ static void __free_pages_ok(struct page *page, unsigned int order)
int bad = 0;
int wasMlocked = __TestClearPageMlocked(page);
+ trace_mm_page_free_direct(page, order);
kmemcheck_free_shadow(page, order);
for (i = 0 ; i < (1 << order) ; ++i)
@@ -1073,8 +1097,9 @@ void mark_free_pages(struct zone *zone)
/*
* Free a 0-order page
+ * cold == 1 ? free a cold page : free a hot page
*/
-static void free_hot_cold_page(struct page *page, int cold)
+void free_hot_cold_page(struct page *page, int cold)
{
struct zone *zone = page_zone(page);
struct per_cpu_pages *pcp;
@@ -1082,6 +1107,7 @@ static void free_hot_cold_page(struct page *page, int cold)
int migratetype;
int wasMlocked = __TestClearPageMlocked(page);
+ trace_mm_page_free_direct(page, 0);
kmemcheck_free_shadow(page, 0);
if (PageAnon(page))
@@ -1133,12 +1159,6 @@ out:
local_irq_restore(flags);
}
-void free_hot_page(struct page *page)
-{
- trace_mm_page_free_direct(page, 0);
- free_hot_cold_page(page, 0);
-}
-
/*
* split_page takes a non-compound higher-order page, and splits it into
* n (1<<order) sub-pages: page[0..n]
@@ -2008,9 +2028,8 @@ void __pagevec_free(struct pagevec *pvec)
void __free_pages(struct page *page, unsigned int order)
{
if (put_page_testzero(page)) {
- trace_mm_page_free_direct(page, order);
if (order == 0)
- free_hot_page(page);
+ free_hot_cold_page(page, 0);
else
__free_pages_ok(page, order);
}
@@ -2266,7 +2285,7 @@ void show_free_areas(void)
K(zone_page_state(zone, NR_BOUNCE)),
K(zone_page_state(zone, NR_WRITEBACK_TEMP)),
zone->pages_scanned,
- (zone_is_all_unreclaimable(zone) ? "yes" : "no")
+ (zone->all_unreclaimable ? "yes" : "no")
);
printk("lowmem_reserve[]:");
for (i = 0; i < MAX_NR_ZONES; i++)
@@ -3203,7 +3222,7 @@ static int __zone_pcp_update(void *data)
int cpu;
unsigned long batch = zone_batchsize(zone), flags;
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ for_each_possible_cpu(cpu) {
struct per_cpu_pageset *pset;
struct per_cpu_pages *pcp;
@@ -4371,8 +4390,12 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
for (i = 0; i < MAX_NR_ZONES; i++) {
if (i == ZONE_MOVABLE)
continue;
- printk(" %-8s %0#10lx -> %0#10lx\n",
- zone_names[i],
+ printk(" %-8s ", zone_names[i]);
+ if (arch_zone_lowest_possible_pfn[i] ==
+ arch_zone_highest_possible_pfn[i])
+ printk("empty\n");
+ else
+ printk("%0#10lx -> %0#10lx\n",
arch_zone_lowest_possible_pfn[i],
arch_zone_highest_possible_pfn[i]);
}
@@ -5158,3 +5181,80 @@ bool is_free_buddy_page(struct page *page)
return order < MAX_ORDER;
}
#endif
+
+static struct trace_print_flags pageflag_names[] = {
+ {1UL << PG_locked, "locked" },
+ {1UL << PG_error, "error" },
+ {1UL << PG_referenced, "referenced" },
+ {1UL << PG_uptodate, "uptodate" },
+ {1UL << PG_dirty, "dirty" },
+ {1UL << PG_lru, "lru" },
+ {1UL << PG_active, "active" },
+ {1UL << PG_slab, "slab" },
+ {1UL << PG_owner_priv_1, "owner_priv_1" },
+ {1UL << PG_arch_1, "arch_1" },
+ {1UL << PG_reserved, "reserved" },
+ {1UL << PG_private, "private" },
+ {1UL << PG_private_2, "private_2" },
+ {1UL << PG_writeback, "writeback" },
+#ifdef CONFIG_PAGEFLAGS_EXTENDED
+ {1UL << PG_head, "head" },
+ {1UL << PG_tail, "tail" },
+#else
+ {1UL << PG_compound, "compound" },
+#endif
+ {1UL << PG_swapcache, "swapcache" },
+ {1UL << PG_mappedtodisk, "mappedtodisk" },
+ {1UL << PG_reclaim, "reclaim" },
+ {1UL << PG_buddy, "buddy" },
+ {1UL << PG_swapbacked, "swapbacked" },
+ {1UL << PG_unevictable, "unevictable" },
+#ifdef CONFIG_MMU
+ {1UL << PG_mlocked, "mlocked" },
+#endif
+#ifdef CONFIG_ARCH_USES_PG_UNCACHED
+ {1UL << PG_uncached, "uncached" },
+#endif
+#ifdef CONFIG_MEMORY_FAILURE
+ {1UL << PG_hwpoison, "hwpoison" },
+#endif
+ {-1UL, NULL },
+};
+
+static void dump_page_flags(unsigned long flags)
+{
+ const char *delim = "";
+ unsigned long mask;
+ int i;
+
+ printk(KERN_ALERT "page flags: %#lx(", flags);
+
+ /* remove zone id */
+ flags &= (1UL << NR_PAGEFLAGS) - 1;
+
+ for (i = 0; pageflag_names[i].name && flags; i++) {
+
+ mask = pageflag_names[i].mask;
+ if ((flags & mask) != mask)
+ continue;
+
+ flags &= ~mask;
+ printk("%s%s", delim, pageflag_names[i].name);
+ delim = "|";
+ }
+
+ /* check for left over flags */
+ if (flags)
+ printk("%s%#lx", delim, flags);
+
+ printk(")\n");
+}
+
+void dump_page(struct page *page)
+{
+ printk(KERN_ALERT
+ "page:%p count:%d mapcount:%d mapping:%p index:%#lx\n",
+ page, page_count(page), page_mapcount(page),
+ page->mapping, page->index);
+ dump_page_flags(page->flags);
+}
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c
index 3d535d59482..6c0081441a3 100644
--- a/mm/page_cgroup.c
+++ b/mm/page_cgroup.c
@@ -284,6 +284,7 @@ static DEFINE_MUTEX(swap_cgroup_mutex);
struct swap_cgroup_ctrl {
struct page **map;
unsigned long length;
+ spinlock_t lock;
};
struct swap_cgroup_ctrl swap_cgroup_ctrl[MAX_SWAPFILES];
@@ -335,6 +336,43 @@ not_enough_page:
}
/**
+ * swap_cgroup_cmpxchg - cmpxchg mem_cgroup's id for this swp_entry.
+ * @end: swap entry to be cmpxchged
+ * @old: old id
+ * @new: new id
+ *
+ * Returns old id at success, 0 at failure.
+ * (There is no mem_cgroup useing 0 as its id)
+ */
+unsigned short swap_cgroup_cmpxchg(swp_entry_t ent,
+ unsigned short old, unsigned short new)
+{
+ int type = swp_type(ent);
+ unsigned long offset = swp_offset(ent);
+ unsigned long idx = offset / SC_PER_PAGE;
+ unsigned long pos = offset & SC_POS_MASK;
+ struct swap_cgroup_ctrl *ctrl;
+ struct page *mappage;
+ struct swap_cgroup *sc;
+ unsigned long flags;
+ unsigned short retval;
+
+ ctrl = &swap_cgroup_ctrl[type];
+
+ mappage = ctrl->map[idx];
+ sc = page_address(mappage);
+ sc += pos;
+ spin_lock_irqsave(&ctrl->lock, flags);
+ retval = sc->id;
+ if (retval == old)
+ sc->id = new;
+ else
+ retval = 0;
+ spin_unlock_irqrestore(&ctrl->lock, flags);
+ return retval;
+}
+
+/**
* swap_cgroup_record - record mem_cgroup for this swp_entry.
* @ent: swap entry to be recorded into
* @mem: mem_cgroup to be recorded
@@ -352,14 +390,17 @@ unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id)
struct page *mappage;
struct swap_cgroup *sc;
unsigned short old;
+ unsigned long flags;
ctrl = &swap_cgroup_ctrl[type];
mappage = ctrl->map[idx];
sc = page_address(mappage);
sc += pos;
+ spin_lock_irqsave(&ctrl->lock, flags);
old = sc->id;
sc->id = id;
+ spin_unlock_irqrestore(&ctrl->lock, flags);
return old;
}
@@ -411,6 +452,7 @@ int swap_cgroup_swapon(int type, unsigned long max_pages)
mutex_lock(&swap_cgroup_mutex);
ctrl->length = length;
ctrl->map = array;
+ spin_lock_init(&ctrl->lock);
if (swap_cgroup_prepare(type)) {
/* memory shortage */
ctrl->map = NULL;
diff --git a/mm/page_io.c b/mm/page_io.c
index a19af956ee1..31a3b962230 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/kernel_stat.h>
+#include <linux/gfp.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
#include <linux/bio.h>
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 7b47a57b664..8b1a2ce21ee 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -80,6 +80,37 @@ static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end,
return err;
}
+#ifdef CONFIG_HUGETLB_PAGE
+static unsigned long hugetlb_entry_end(struct hstate *h, unsigned long addr,
+ unsigned long end)
+{
+ unsigned long boundary = (addr & huge_page_mask(h)) + huge_page_size(h);
+ return boundary < end ? boundary : end;
+}
+
+static int walk_hugetlb_range(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long end,
+ struct mm_walk *walk)
+{
+ struct hstate *h = hstate_vma(vma);
+ unsigned long next;
+ unsigned long hmask = huge_page_mask(h);
+ pte_t *pte;
+ int err = 0;
+
+ do {
+ next = hugetlb_entry_end(h, addr, end);
+ pte = huge_pte_offset(walk->mm, addr & hmask);
+ if (pte && walk->hugetlb_entry)
+ err = walk->hugetlb_entry(pte, hmask, addr, next, walk);
+ if (err)
+ return err;
+ } while (addr = next, addr != end);
+
+ return 0;
+}
+#endif
+
/**
* walk_page_range - walk a memory map's page tables with a callback
* @mm: memory map to walk
@@ -128,20 +159,16 @@ int walk_page_range(unsigned long addr, unsigned long end,
vma = find_vma(walk->mm, addr);
#ifdef CONFIG_HUGETLB_PAGE
if (vma && is_vm_hugetlb_page(vma)) {
- pte_t *pte;
- struct hstate *hs;
-
if (vma->vm_end < next)
next = vma->vm_end;
- hs = hstate_vma(vma);
- pte = huge_pte_offset(walk->mm,
- addr & huge_page_mask(hs));
- if (pte && !huge_pte_none(huge_ptep_get(pte))
- && walk->hugetlb_entry)
- err = walk->hugetlb_entry(pte, addr,
- next, walk);
+ /*
+ * Hugepage is very tightly coupled with vma, so
+ * walk through hugetlb entries within a given vma.
+ */
+ err = walk_hugetlb_range(vma, addr, next, walk);
if (err)
break;
+ pgd = pgd_offset(walk->mm, next);
continue;
}
#endif
diff --git a/mm/percpu.c b/mm/percpu.c
index 768419d44ad..6e09741ddc6 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1304,6 +1304,32 @@ void free_percpu(void __percpu *ptr)
EXPORT_SYMBOL_GPL(free_percpu);
/**
+ * is_kernel_percpu_address - test whether address is from static percpu area
+ * @addr: address to test
+ *
+ * Test whether @addr belongs to in-kernel static percpu area. Module
+ * static percpu areas are not considered. For those, use
+ * is_module_percpu_address().
+ *
+ * RETURNS:
+ * %true if @addr is from in-kernel static percpu area, %false otherwise.
+ */
+bool is_kernel_percpu_address(unsigned long addr)
+{
+ const size_t static_size = __per_cpu_end - __per_cpu_start;
+ void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr);
+ unsigned int cpu;
+
+ for_each_possible_cpu(cpu) {
+ void *start = per_cpu_ptr(base, cpu);
+
+ if ((void *)addr >= start && (void *)addr < start + static_size)
+ return true;
+ }
+ return false;
+}
+
+/**
* per_cpu_ptr_to_phys - convert translated percpu address to physical address
* @addr: the address to be converted to physical address
*
diff --git a/mm/percpu_up.c b/mm/percpu_up.c
new file mode 100644
index 00000000000..c4351c7f57d
--- /dev/null
+++ b/mm/percpu_up.c
@@ -0,0 +1,30 @@
+/*
+ * mm/percpu_up.c - dummy percpu memory allocator implementation for UP
+ */
+
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+
+void __percpu *__alloc_percpu(size_t size, size_t align)
+{
+ /*
+ * Can't easily make larger alignment work with kmalloc. WARN
+ * on it. Larger alignment should only be used for module
+ * percpu sections on SMP for which this path isn't used.
+ */
+ WARN_ON_ONCE(align > SMP_CACHE_BYTES);
+ return kzalloc(size, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(__alloc_percpu);
+
+void free_percpu(void __percpu *p)
+{
+ kfree(p);
+}
+EXPORT_SYMBOL_GPL(free_percpu);
+
+phys_addr_t per_cpu_ptr_to_phys(void *addr)
+{
+ return __pa(addr);
+}
diff --git a/mm/quicklist.c b/mm/quicklist.c
index 6633965bb27..2876349339a 100644
--- a/mm/quicklist.c
+++ b/mm/quicklist.c
@@ -14,6 +14,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
#include <linux/module.h>
diff --git a/mm/readahead.c b/mm/readahead.c
index 033bc135a41..dfa9a1a03a1 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/blkdev.h>
@@ -501,6 +502,12 @@ void page_cache_sync_readahead(struct address_space *mapping,
if (!ra->ra_pages)
return;
+ /* be dumb */
+ if (filp && (filp->f_mode & FMODE_RANDOM)) {
+ force_page_cache_readahead(mapping, filp, offset, req_size);
+ return;
+ }
+
/* do read-ahead */
ondemand_readahead(mapping, ra, filp, false, offset, req_size);
}
diff --git a/mm/rmap.c b/mm/rmap.c
index 278cd277bde..07fc9475879 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -62,6 +62,7 @@
#include "internal.h"
static struct kmem_cache *anon_vma_cachep;
+static struct kmem_cache *anon_vma_chain_cachep;
static inline struct anon_vma *anon_vma_alloc(void)
{
@@ -73,6 +74,16 @@ void anon_vma_free(struct anon_vma *anon_vma)
kmem_cache_free(anon_vma_cachep, anon_vma);
}
+static inline struct anon_vma_chain *anon_vma_chain_alloc(void)
+{
+ return kmem_cache_alloc(anon_vma_chain_cachep, GFP_KERNEL);
+}
+
+void anon_vma_chain_free(struct anon_vma_chain *anon_vma_chain)
+{
+ kmem_cache_free(anon_vma_chain_cachep, anon_vma_chain);
+}
+
/**
* anon_vma_prepare - attach an anon_vma to a memory region
* @vma: the memory region in question
@@ -103,73 +114,140 @@ void anon_vma_free(struct anon_vma *anon_vma)
int anon_vma_prepare(struct vm_area_struct *vma)
{
struct anon_vma *anon_vma = vma->anon_vma;
+ struct anon_vma_chain *avc;
might_sleep();
if (unlikely(!anon_vma)) {
struct mm_struct *mm = vma->vm_mm;
struct anon_vma *allocated;
+ avc = anon_vma_chain_alloc();
+ if (!avc)
+ goto out_enomem;
+
anon_vma = find_mergeable_anon_vma(vma);
allocated = NULL;
if (!anon_vma) {
anon_vma = anon_vma_alloc();
if (unlikely(!anon_vma))
- return -ENOMEM;
+ goto out_enomem_free_avc;
allocated = anon_vma;
}
- spin_lock(&anon_vma->lock);
+ spin_lock(&anon_vma->lock);
/* page_table_lock to protect against threads */
spin_lock(&mm->page_table_lock);
if (likely(!vma->anon_vma)) {
vma->anon_vma = anon_vma;
- list_add_tail(&vma->anon_vma_node, &anon_vma->head);
+ avc->anon_vma = anon_vma;
+ avc->vma = vma;
+ list_add(&avc->same_vma, &vma->anon_vma_chain);
+ list_add(&avc->same_anon_vma, &anon_vma->head);
allocated = NULL;
+ avc = NULL;
}
spin_unlock(&mm->page_table_lock);
-
spin_unlock(&anon_vma->lock);
+
if (unlikely(allocated))
anon_vma_free(allocated);
+ if (unlikely(avc))
+ anon_vma_chain_free(avc);
}
return 0;
+
+ out_enomem_free_avc:
+ anon_vma_chain_free(avc);
+ out_enomem:
+ return -ENOMEM;
}
-void __anon_vma_merge(struct vm_area_struct *vma, struct vm_area_struct *next)
+static void anon_vma_chain_link(struct vm_area_struct *vma,
+ struct anon_vma_chain *avc,
+ struct anon_vma *anon_vma)
{
- BUG_ON(vma->anon_vma != next->anon_vma);
- list_del(&next->anon_vma_node);
+ avc->vma = vma;
+ avc->anon_vma = anon_vma;
+ list_add(&avc->same_vma, &vma->anon_vma_chain);
+
+ spin_lock(&anon_vma->lock);
+ list_add_tail(&avc->same_anon_vma, &anon_vma->head);
+ spin_unlock(&anon_vma->lock);
}
-void __anon_vma_link(struct vm_area_struct *vma)
+/*
+ * Attach the anon_vmas from src to dst.
+ * Returns 0 on success, -ENOMEM on failure.
+ */
+int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
{
- struct anon_vma *anon_vma = vma->anon_vma;
+ struct anon_vma_chain *avc, *pavc;
- if (anon_vma)
- list_add_tail(&vma->anon_vma_node, &anon_vma->head);
+ list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) {
+ avc = anon_vma_chain_alloc();
+ if (!avc)
+ goto enomem_failure;
+ anon_vma_chain_link(dst, avc, pavc->anon_vma);
+ }
+ return 0;
+
+ enomem_failure:
+ unlink_anon_vmas(dst);
+ return -ENOMEM;
}
-void anon_vma_link(struct vm_area_struct *vma)
+/*
+ * Attach vma to its own anon_vma, as well as to the anon_vmas that
+ * the corresponding VMA in the parent process is attached to.
+ * Returns 0 on success, non-zero on failure.
+ */
+int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
{
- struct anon_vma *anon_vma = vma->anon_vma;
+ struct anon_vma_chain *avc;
+ struct anon_vma *anon_vma;
- if (anon_vma) {
- spin_lock(&anon_vma->lock);
- list_add_tail(&vma->anon_vma_node, &anon_vma->head);
- spin_unlock(&anon_vma->lock);
- }
+ /* Don't bother if the parent process has no anon_vma here. */
+ if (!pvma->anon_vma)
+ return 0;
+
+ /*
+ * First, attach the new VMA to the parent VMA's anon_vmas,
+ * so rmap can find non-COWed pages in child processes.
+ */
+ if (anon_vma_clone(vma, pvma))
+ return -ENOMEM;
+
+ /* Then add our own anon_vma. */
+ anon_vma = anon_vma_alloc();
+ if (!anon_vma)
+ goto out_error;
+ avc = anon_vma_chain_alloc();
+ if (!avc)
+ goto out_error_free_anon_vma;
+ anon_vma_chain_link(vma, avc, anon_vma);
+ /* Mark this anon_vma as the one where our new (COWed) pages go. */
+ vma->anon_vma = anon_vma;
+
+ return 0;
+
+ out_error_free_anon_vma:
+ anon_vma_free(anon_vma);
+ out_error:
+ unlink_anon_vmas(vma);
+ return -ENOMEM;
}
-void anon_vma_unlink(struct vm_area_struct *vma)
+static void anon_vma_unlink(struct anon_vma_chain *anon_vma_chain)
{
- struct anon_vma *anon_vma = vma->anon_vma;
+ struct anon_vma *anon_vma = anon_vma_chain->anon_vma;
int empty;
+ /* If anon_vma_fork fails, we can get an empty anon_vma_chain. */
if (!anon_vma)
return;
spin_lock(&anon_vma->lock);
- list_del(&vma->anon_vma_node);
+ list_del(&anon_vma_chain->same_anon_vma);
/* We must garbage collect the anon_vma if it's empty */
empty = list_empty(&anon_vma->head) && !ksm_refcount(anon_vma);
@@ -179,6 +257,18 @@ void anon_vma_unlink(struct vm_area_struct *vma)
anon_vma_free(anon_vma);
}
+void unlink_anon_vmas(struct vm_area_struct *vma)
+{
+ struct anon_vma_chain *avc, *next;
+
+ /* Unlink each anon_vma chained to the VMA. */
+ list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) {
+ anon_vma_unlink(avc);
+ list_del(&avc->same_vma);
+ anon_vma_chain_free(avc);
+ }
+}
+
static void anon_vma_ctor(void *data)
{
struct anon_vma *anon_vma = data;
@@ -192,6 +282,7 @@ void __init anon_vma_init(void)
{
anon_vma_cachep = kmem_cache_create("anon_vma", sizeof(struct anon_vma),
0, SLAB_DESTROY_BY_RCU|SLAB_PANIC, anon_vma_ctor);
+ anon_vma_chain_cachep = KMEM_CACHE(anon_vma_chain, SLAB_PANIC);
}
/*
@@ -396,7 +487,7 @@ static int page_referenced_anon(struct page *page,
{
unsigned int mapcount;
struct anon_vma *anon_vma;
- struct vm_area_struct *vma;
+ struct anon_vma_chain *avc;
int referenced = 0;
anon_vma = page_lock_anon_vma(page);
@@ -404,7 +495,8 @@ static int page_referenced_anon(struct page *page,
return referenced;
mapcount = page_mapcount(page);
- list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+ list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+ struct vm_area_struct *vma = avc->vma;
unsigned long address = vma_address(page, vma);
if (address == -EFAULT)
continue;
@@ -511,9 +603,6 @@ int page_referenced(struct page *page,
int referenced = 0;
int we_locked = 0;
- if (TestClearPageReferenced(page))
- referenced++;
-
*vm_flags = 0;
if (page_mapped(page) && page_rmapping(page)) {
if (!is_locked && (!PageAnon(page) || PageKsm(page))) {
@@ -614,17 +703,57 @@ int page_mkclean(struct page *page)
EXPORT_SYMBOL_GPL(page_mkclean);
/**
+ * page_move_anon_rmap - move a page to our anon_vma
+ * @page: the page to move to our anon_vma
+ * @vma: the vma the page belongs to
+ * @address: the user virtual address mapped
+ *
+ * When a page belongs exclusively to one process after a COW event,
+ * that page can be moved into the anon_vma that belongs to just that
+ * process, so the rmap code will not search the parent or sibling
+ * processes.
+ */
+void page_move_anon_rmap(struct page *page,
+ struct vm_area_struct *vma, unsigned long address)
+{
+ struct anon_vma *anon_vma = vma->anon_vma;
+
+ VM_BUG_ON(!PageLocked(page));
+ VM_BUG_ON(!anon_vma);
+ VM_BUG_ON(page->index != linear_page_index(vma, address));
+
+ anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
+ page->mapping = (struct address_space *) anon_vma;
+}
+
+/**
* __page_set_anon_rmap - setup new anonymous rmap
* @page: the page to add the mapping to
* @vma: the vm area in which the mapping is added
* @address: the user virtual address mapped
+ * @exclusive: the page is exclusively owned by the current process
*/
static void __page_set_anon_rmap(struct page *page,
- struct vm_area_struct *vma, unsigned long address)
+ struct vm_area_struct *vma, unsigned long address, int exclusive)
{
struct anon_vma *anon_vma = vma->anon_vma;
BUG_ON(!anon_vma);
+
+ /*
+ * If the page isn't exclusively mapped into this vma,
+ * we must use the _oldest_ possible anon_vma for the
+ * page mapping!
+ *
+ * So take the last AVC chain entry in the vma, which is
+ * the deepest ancestor, and use the anon_vma from that.
+ */
+ if (!exclusive) {
+ struct anon_vma_chain *avc;
+ avc = list_entry(vma->anon_vma_chain.prev, struct anon_vma_chain, same_vma);
+ anon_vma = avc->anon_vma;
+ }
+
anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
page->mapping = (struct address_space *) anon_vma;
page->index = linear_page_index(vma, address);
@@ -652,9 +781,6 @@ static void __page_check_anon_rmap(struct page *page,
* are initially only visible via the pagetables, and the pte is locked
* over the call to page_add_new_anon_rmap.
*/
- struct anon_vma *anon_vma = vma->anon_vma;
- anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
- BUG_ON(page->mapping != (struct address_space *)anon_vma);
BUG_ON(page->index != linear_page_index(vma, address));
#endif
}
@@ -682,7 +808,7 @@ void page_add_anon_rmap(struct page *page,
VM_BUG_ON(!PageLocked(page));
VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end);
if (first)
- __page_set_anon_rmap(page, vma, address);
+ __page_set_anon_rmap(page, vma, address, 0);
else
__page_check_anon_rmap(page, vma, address);
}
@@ -704,7 +830,7 @@ void page_add_new_anon_rmap(struct page *page,
SetPageSwapBacked(page);
atomic_set(&page->_mapcount, 0); /* increment count (starts at -1) */
__inc_zone_page_state(page, NR_ANON_PAGES);
- __page_set_anon_rmap(page, vma, address);
+ __page_set_anon_rmap(page, vma, address, 1);
if (page_evictable(page, vma))
lru_cache_add_lru(page, LRU_ACTIVE_ANON);
else
@@ -815,9 +941,9 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
if (PageAnon(page))
- dec_mm_counter(mm, anon_rss);
+ dec_mm_counter(mm, MM_ANONPAGES);
else
- dec_mm_counter(mm, file_rss);
+ dec_mm_counter(mm, MM_FILEPAGES);
set_pte_at(mm, address, pte,
swp_entry_to_pte(make_hwpoison_entry(page)));
} else if (PageAnon(page)) {
@@ -839,7 +965,8 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
list_add(&mm->mmlist, &init_mm.mmlist);
spin_unlock(&mmlist_lock);
}
- dec_mm_counter(mm, anon_rss);
+ dec_mm_counter(mm, MM_ANONPAGES);
+ inc_mm_counter(mm, MM_SWAPENTS);
} else if (PAGE_MIGRATION) {
/*
* Store the pfn of the page in a special migration
@@ -857,7 +984,7 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
entry = make_migration_entry(page, pte_write(pteval));
set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
} else
- dec_mm_counter(mm, file_rss);
+ dec_mm_counter(mm, MM_FILEPAGES);
page_remove_rmap(page);
page_cache_release(page);
@@ -996,7 +1123,7 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
page_remove_rmap(page);
page_cache_release(page);
- dec_mm_counter(mm, file_rss);
+ dec_mm_counter(mm, MM_FILEPAGES);
(*mapcount)--;
}
pte_unmap_unlock(pte - 1, ptl);
@@ -1024,14 +1151,15 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
{
struct anon_vma *anon_vma;
- struct vm_area_struct *vma;
+ struct anon_vma_chain *avc;
int ret = SWAP_AGAIN;
anon_vma = page_lock_anon_vma(page);
if (!anon_vma)
return ret;
- list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+ list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+ struct vm_area_struct *vma = avc->vma;
unsigned long address = vma_address(page, vma);
if (address == -EFAULT)
continue;
@@ -1222,7 +1350,7 @@ static int rmap_walk_anon(struct page *page, int (*rmap_one)(struct page *,
struct vm_area_struct *, unsigned long, void *), void *arg)
{
struct anon_vma *anon_vma;
- struct vm_area_struct *vma;
+ struct anon_vma_chain *avc;
int ret = SWAP_AGAIN;
/*
@@ -1237,7 +1365,8 @@ static int rmap_walk_anon(struct page *page, int (*rmap_one)(struct page *,
if (!anon_vma)
return ret;
spin_lock(&anon_vma->lock);
- list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+ list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+ struct vm_area_struct *vma = avc->vma;
unsigned long address = vma_address(page, vma);
if (address == -EFAULT)
continue;
diff --git a/mm/slab.c b/mm/slab.c
index 7451bdacaf1..bac0f4fcc21 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -935,7 +935,6 @@ static int transfer_objects(struct array_cache *to,
from->avail -= nr;
to->avail += nr;
- to->touched = 1;
return nr;
}
@@ -983,13 +982,11 @@ static struct array_cache **alloc_alien_cache(int node, int limit, gfp_t gfp)
if (limit > 1)
limit = 12;
- ac_ptr = kmalloc_node(memsize, gfp, node);
+ ac_ptr = kzalloc_node(memsize, gfp, node);
if (ac_ptr) {
for_each_node(i) {
- if (i == node || !node_online(i)) {
- ac_ptr[i] = NULL;
+ if (i == node || !node_online(i))
continue;
- }
ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d, gfp);
if (!ac_ptr[i]) {
for (i--; i >= 0; i--)
@@ -2963,8 +2960,10 @@ retry:
spin_lock(&l3->list_lock);
/* See if we can refill from the shared array */
- if (l3->shared && transfer_objects(ac, l3->shared, batchcount))
+ if (l3->shared && transfer_objects(ac, l3->shared, batchcount)) {
+ l3->shared->touched = 1;
goto alloc_done;
+ }
while (batchcount > 0) {
struct list_head *entry;
@@ -3101,7 +3100,7 @@ static bool slab_should_failslab(struct kmem_cache *cachep, gfp_t flags)
if (cachep == &cache_cache)
return false;
- return should_failslab(obj_size(cachep), flags);
+ return should_failslab(obj_size(cachep), flags, cachep->flags);
}
static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
@@ -3603,21 +3602,10 @@ EXPORT_SYMBOL(kmem_cache_alloc_notrace);
*/
int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
{
- unsigned long addr = (unsigned long)ptr;
- unsigned long min_addr = PAGE_OFFSET;
- unsigned long align_mask = BYTES_PER_WORD - 1;
unsigned long size = cachep->buffer_size;
struct page *page;
- if (unlikely(addr < min_addr))
- goto out;
- if (unlikely(addr > (unsigned long)high_memory - size))
- goto out;
- if (unlikely(addr & align_mask))
- goto out;
- if (unlikely(!kern_addr_valid(addr)))
- goto out;
- if (unlikely(!kern_addr_valid(addr + size - 1)))
+ if (unlikely(!kern_ptr_validate(ptr, size)))
goto out;
page = virt_to_page(ptr);
if (unlikely(!PageSlab(page)))
diff --git a/mm/slub.c b/mm/slub.c
index 8d71aaf888d..7d6c8b1ccf6 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -151,7 +151,8 @@
* Set of flags that will prevent slab merging
*/
#define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
- SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE)
+ SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \
+ SLAB_FAILSLAB)
#define SLUB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \
SLAB_CACHE_DMA | SLAB_NOTRACK)
@@ -217,10 +218,10 @@ static inline void sysfs_slab_remove(struct kmem_cache *s)
#endif
-static inline void stat(struct kmem_cache_cpu *c, enum stat_item si)
+static inline void stat(struct kmem_cache *s, enum stat_item si)
{
#ifdef CONFIG_SLUB_STATS
- c->stat[si]++;
+ __this_cpu_inc(s->cpu_slab->stat[si]);
#endif
}
@@ -242,15 +243,6 @@ static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node)
#endif
}
-static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu)
-{
-#ifdef CONFIG_SMP
- return s->cpu_slab[cpu];
-#else
- return &s->cpu_slab;
-#endif
-}
-
/* Verify that a pointer has an address that is valid within a slab page */
static inline int check_valid_pointer(struct kmem_cache *s,
struct page *page, const void *object)
@@ -269,13 +261,6 @@ static inline int check_valid_pointer(struct kmem_cache *s,
return 1;
}
-/*
- * Slow version of get and set free pointer.
- *
- * This version requires touching the cache lines of kmem_cache which
- * we avoid to do in the fast alloc free paths. There we obtain the offset
- * from the page struct.
- */
static inline void *get_freepointer(struct kmem_cache *s, void *object)
{
return *(void **)(object + s->offset);
@@ -1020,6 +1005,9 @@ static int __init setup_slub_debug(char *str)
case 't':
slub_debug |= SLAB_TRACE;
break;
+ case 'a':
+ slub_debug |= SLAB_FAILSLAB;
+ break;
default:
printk(KERN_ERR "slub_debug option '%c' "
"unknown. skipped\n", *str);
@@ -1124,7 +1112,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
if (!page)
return NULL;
- stat(get_cpu_slab(s, raw_smp_processor_id()), ORDER_FALLBACK);
+ stat(s, ORDER_FALLBACK);
}
if (kmemcheck_enabled
@@ -1422,23 +1410,22 @@ static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node)
static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
{
struct kmem_cache_node *n = get_node(s, page_to_nid(page));
- struct kmem_cache_cpu *c = get_cpu_slab(s, smp_processor_id());
__ClearPageSlubFrozen(page);
if (page->inuse) {
if (page->freelist) {
add_partial(n, page, tail);
- stat(c, tail ? DEACTIVATE_TO_TAIL : DEACTIVATE_TO_HEAD);
+ stat(s, tail ? DEACTIVATE_TO_TAIL : DEACTIVATE_TO_HEAD);
} else {
- stat(c, DEACTIVATE_FULL);
+ stat(s, DEACTIVATE_FULL);
if (SLABDEBUG && PageSlubDebug(page) &&
(s->flags & SLAB_STORE_USER))
add_full(n, page);
}
slab_unlock(page);
} else {
- stat(c, DEACTIVATE_EMPTY);
+ stat(s, DEACTIVATE_EMPTY);
if (n->nr_partial < s->min_partial) {
/*
* Adding an empty slab to the partial slabs in order
@@ -1454,7 +1441,7 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
slab_unlock(page);
} else {
slab_unlock(page);
- stat(get_cpu_slab(s, raw_smp_processor_id()), FREE_SLAB);
+ stat(s, FREE_SLAB);
discard_slab(s, page);
}
}
@@ -1469,7 +1456,7 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
int tail = 1;
if (page->freelist)
- stat(c, DEACTIVATE_REMOTE_FREES);
+ stat(s, DEACTIVATE_REMOTE_FREES);
/*
* Merge cpu freelist into slab freelist. Typically we get here
* because both freelists are empty. So this is unlikely
@@ -1482,10 +1469,10 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
/* Retrieve object from cpu_freelist */
object = c->freelist;
- c->freelist = c->freelist[c->offset];
+ c->freelist = get_freepointer(s, c->freelist);
/* And put onto the regular freelist */
- object[c->offset] = page->freelist;
+ set_freepointer(s, object, page->freelist);
page->freelist = object;
page->inuse--;
}
@@ -1495,7 +1482,7 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
{
- stat(c, CPUSLAB_FLUSH);
+ stat(s, CPUSLAB_FLUSH);
slab_lock(c->page);
deactivate_slab(s, c);
}
@@ -1507,7 +1494,7 @@ static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
*/
static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
{
- struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
if (likely(c && c->page))
flush_slab(s, c);
@@ -1635,7 +1622,7 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
if (unlikely(!node_match(c, node)))
goto another_slab;
- stat(c, ALLOC_REFILL);
+ stat(s, ALLOC_REFILL);
load_freelist:
object = c->page->freelist;
@@ -1644,13 +1631,13 @@ load_freelist:
if (unlikely(SLABDEBUG && PageSlubDebug(c->page)))
goto debug;
- c->freelist = object[c->offset];
+ c->freelist = get_freepointer(s, object);
c->page->inuse = c->page->objects;
c->page->freelist = NULL;
c->node = page_to_nid(c->page);
unlock_out:
slab_unlock(c->page);
- stat(c, ALLOC_SLOWPATH);
+ stat(s, ALLOC_SLOWPATH);
return object;
another_slab:
@@ -1660,7 +1647,7 @@ new_slab:
new = get_partial(s, gfpflags, node);
if (new) {
c->page = new;
- stat(c, ALLOC_FROM_PARTIAL);
+ stat(s, ALLOC_FROM_PARTIAL);
goto load_freelist;
}
@@ -1673,8 +1660,8 @@ new_slab:
local_irq_disable();
if (new) {
- c = get_cpu_slab(s, smp_processor_id());
- stat(c, ALLOC_SLAB);
+ c = __this_cpu_ptr(s->cpu_slab);
+ stat(s, ALLOC_SLAB);
if (c->page)
flush_slab(s, c);
slab_lock(new);
@@ -1690,7 +1677,7 @@ debug:
goto another_slab;
c->page->inuse++;
- c->page->freelist = object[c->offset];
+ c->page->freelist = get_freepointer(s, object);
c->node = -1;
goto unlock_out;
}
@@ -1711,35 +1698,33 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
void **object;
struct kmem_cache_cpu *c;
unsigned long flags;
- unsigned int objsize;
gfpflags &= gfp_allowed_mask;
lockdep_trace_alloc(gfpflags);
might_sleep_if(gfpflags & __GFP_WAIT);
- if (should_failslab(s->objsize, gfpflags))
+ if (should_failslab(s->objsize, gfpflags, s->flags))
return NULL;
local_irq_save(flags);
- c = get_cpu_slab(s, smp_processor_id());
- objsize = c->objsize;
- if (unlikely(!c->freelist || !node_match(c, node)))
+ c = __this_cpu_ptr(s->cpu_slab);
+ object = c->freelist;
+ if (unlikely(!object || !node_match(c, node)))
object = __slab_alloc(s, gfpflags, node, addr, c);
else {
- object = c->freelist;
- c->freelist = object[c->offset];
- stat(c, ALLOC_FASTPATH);
+ c->freelist = get_freepointer(s, object);
+ stat(s, ALLOC_FASTPATH);
}
local_irq_restore(flags);
if (unlikely(gfpflags & __GFP_ZERO) && object)
- memset(object, 0, objsize);
+ memset(object, 0, s->objsize);
- kmemcheck_slab_alloc(s, gfpflags, object, c->objsize);
- kmemleak_alloc_recursive(object, objsize, 1, s->flags, gfpflags);
+ kmemcheck_slab_alloc(s, gfpflags, object, s->objsize);
+ kmemleak_alloc_recursive(object, s->objsize, 1, s->flags, gfpflags);
return object;
}
@@ -1794,26 +1779,25 @@ EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
* handling required then we can return immediately.
*/
static void __slab_free(struct kmem_cache *s, struct page *page,
- void *x, unsigned long addr, unsigned int offset)
+ void *x, unsigned long addr)
{
void *prior;
void **object = (void *)x;
- struct kmem_cache_cpu *c;
- c = get_cpu_slab(s, raw_smp_processor_id());
- stat(c, FREE_SLOWPATH);
+ stat(s, FREE_SLOWPATH);
slab_lock(page);
if (unlikely(SLABDEBUG && PageSlubDebug(page)))
goto debug;
checks_ok:
- prior = object[offset] = page->freelist;
+ prior = page->freelist;
+ set_freepointer(s, object, prior);
page->freelist = object;
page->inuse--;
if (unlikely(PageSlubFrozen(page))) {
- stat(c, FREE_FROZEN);
+ stat(s, FREE_FROZEN);
goto out_unlock;
}
@@ -1826,7 +1810,7 @@ checks_ok:
*/
if (unlikely(!prior)) {
add_partial(get_node(s, page_to_nid(page)), page, 1);
- stat(c, FREE_ADD_PARTIAL);
+ stat(s, FREE_ADD_PARTIAL);
}
out_unlock:
@@ -1839,10 +1823,10 @@ slab_empty:
* Slab still on the partial list.
*/
remove_partial(s, page);
- stat(c, FREE_REMOVE_PARTIAL);
+ stat(s, FREE_REMOVE_PARTIAL);
}
slab_unlock(page);
- stat(c, FREE_SLAB);
+ stat(s, FREE_SLAB);
discard_slab(s, page);
return;
@@ -1872,17 +1856,17 @@ static __always_inline void slab_free(struct kmem_cache *s,
kmemleak_free_recursive(x, s->flags);
local_irq_save(flags);
- c = get_cpu_slab(s, smp_processor_id());
- kmemcheck_slab_free(s, object, c->objsize);
- debug_check_no_locks_freed(object, c->objsize);
+ c = __this_cpu_ptr(s->cpu_slab);
+ kmemcheck_slab_free(s, object, s->objsize);
+ debug_check_no_locks_freed(object, s->objsize);
if (!(s->flags & SLAB_DEBUG_OBJECTS))
- debug_check_no_obj_freed(object, c->objsize);
+ debug_check_no_obj_freed(object, s->objsize);
if (likely(page == c->page && c->node >= 0)) {
- object[c->offset] = c->freelist;
+ set_freepointer(s, object, c->freelist);
c->freelist = object;
- stat(c, FREE_FASTPATH);
+ stat(s, FREE_FASTPATH);
} else
- __slab_free(s, page, x, addr, c->offset);
+ __slab_free(s, page, x, addr);
local_irq_restore(flags);
}
@@ -2069,19 +2053,6 @@ static unsigned long calculate_alignment(unsigned long flags,
return ALIGN(align, sizeof(void *));
}
-static void init_kmem_cache_cpu(struct kmem_cache *s,
- struct kmem_cache_cpu *c)
-{
- c->page = NULL;
- c->freelist = NULL;
- c->node = 0;
- c->offset = s->offset / sizeof(void *);
- c->objsize = s->objsize;
-#ifdef CONFIG_SLUB_STATS
- memset(c->stat, 0, NR_SLUB_STAT_ITEMS * sizeof(unsigned));
-#endif
-}
-
static void
init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s)
{
@@ -2095,130 +2066,24 @@ init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s)
#endif
}
-#ifdef CONFIG_SMP
-/*
- * Per cpu array for per cpu structures.
- *
- * The per cpu array places all kmem_cache_cpu structures from one processor
- * close together meaning that it becomes possible that multiple per cpu
- * structures are contained in one cacheline. This may be particularly
- * beneficial for the kmalloc caches.
- *
- * A desktop system typically has around 60-80 slabs. With 100 here we are
- * likely able to get per cpu structures for all caches from the array defined
- * here. We must be able to cover all kmalloc caches during bootstrap.
- *
- * If the per cpu array is exhausted then fall back to kmalloc
- * of individual cachelines. No sharing is possible then.
- */
-#define NR_KMEM_CACHE_CPU 100
-
-static DEFINE_PER_CPU(struct kmem_cache_cpu [NR_KMEM_CACHE_CPU],
- kmem_cache_cpu);
-
-static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free);
-static DECLARE_BITMAP(kmem_cach_cpu_free_init_once, CONFIG_NR_CPUS);
-
-static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
- int cpu, gfp_t flags)
-{
- struct kmem_cache_cpu *c = per_cpu(kmem_cache_cpu_free, cpu);
-
- if (c)
- per_cpu(kmem_cache_cpu_free, cpu) =
- (void *)c->freelist;
- else {
- /* Table overflow: So allocate ourselves */
- c = kmalloc_node(
- ALIGN(sizeof(struct kmem_cache_cpu), cache_line_size()),
- flags, cpu_to_node(cpu));
- if (!c)
- return NULL;
- }
-
- init_kmem_cache_cpu(s, c);
- return c;
-}
-
-static void free_kmem_cache_cpu(struct kmem_cache_cpu *c, int cpu)
-{
- if (c < per_cpu(kmem_cache_cpu, cpu) ||
- c >= per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) {
- kfree(c);
- return;
- }
- c->freelist = (void *)per_cpu(kmem_cache_cpu_free, cpu);
- per_cpu(kmem_cache_cpu_free, cpu) = c;
-}
-
-static void free_kmem_cache_cpus(struct kmem_cache *s)
-{
- int cpu;
-
- for_each_online_cpu(cpu) {
- struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
-
- if (c) {
- s->cpu_slab[cpu] = NULL;
- free_kmem_cache_cpu(c, cpu);
- }
- }
-}
-
-static int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
-{
- int cpu;
-
- for_each_online_cpu(cpu) {
- struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
-
- if (c)
- continue;
-
- c = alloc_kmem_cache_cpu(s, cpu, flags);
- if (!c) {
- free_kmem_cache_cpus(s);
- return 0;
- }
- s->cpu_slab[cpu] = c;
- }
- return 1;
-}
-
-/*
- * Initialize the per cpu array.
- */
-static void init_alloc_cpu_cpu(int cpu)
-{
- int i;
+static DEFINE_PER_CPU(struct kmem_cache_cpu, kmalloc_percpu[KMALLOC_CACHES]);
- if (cpumask_test_cpu(cpu, to_cpumask(kmem_cach_cpu_free_init_once)))
- return;
-
- for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--)
- free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu);
-
- cpumask_set_cpu(cpu, to_cpumask(kmem_cach_cpu_free_init_once));
-}
-
-static void __init init_alloc_cpu(void)
+static inline int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
{
- int cpu;
-
- for_each_online_cpu(cpu)
- init_alloc_cpu_cpu(cpu);
- }
+ if (s < kmalloc_caches + KMALLOC_CACHES && s >= kmalloc_caches)
+ /*
+ * Boot time creation of the kmalloc array. Use static per cpu data
+ * since the per cpu allocator is not available yet.
+ */
+ s->cpu_slab = kmalloc_percpu + (s - kmalloc_caches);
+ else
+ s->cpu_slab = alloc_percpu(struct kmem_cache_cpu);
-#else
-static inline void free_kmem_cache_cpus(struct kmem_cache *s) {}
-static inline void init_alloc_cpu(void) {}
+ if (!s->cpu_slab)
+ return 0;
-static inline int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
-{
- init_kmem_cache_cpu(s, &s->cpu_slab);
return 1;
}
-#endif
#ifdef CONFIG_NUMA
/*
@@ -2287,7 +2152,8 @@ static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
int node;
int local_node;
- if (slab_state >= UP)
+ if (slab_state >= UP && (s < kmalloc_caches ||
+ s > kmalloc_caches + KMALLOC_CACHES))
local_node = page_to_nid(virt_to_page(s));
else
local_node = 0;
@@ -2502,6 +2368,7 @@ static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
if (alloc_kmem_cache_cpus(s, gfpflags & ~SLUB_DMA))
return 1;
+
free_kmem_cache_nodes(s);
error:
if (flags & SLAB_PANIC)
@@ -2519,6 +2386,9 @@ int kmem_ptr_validate(struct kmem_cache *s, const void *object)
{
struct page *page;
+ if (!kern_ptr_validate(object, s->size))
+ return 0;
+
page = get_object_page(object);
if (!page || s != page->slab)
@@ -2609,9 +2479,8 @@ static inline int kmem_cache_close(struct kmem_cache *s)
int node;
flush_all(s);
-
+ free_percpu(s->cpu_slab);
/* Attempt to free all objects */
- free_kmem_cache_cpus(s);
for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n = get_node(s, node);
@@ -2651,7 +2520,7 @@ EXPORT_SYMBOL(kmem_cache_destroy);
* Kmalloc subsystem
*******************************************************************/
-struct kmem_cache kmalloc_caches[SLUB_PAGE_SHIFT] __cacheline_aligned;
+struct kmem_cache kmalloc_caches[KMALLOC_CACHES] __cacheline_aligned;
EXPORT_SYMBOL(kmalloc_caches);
static int __init setup_slub_min_order(char *str)
@@ -2741,6 +2610,7 @@ static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags)
char *text;
size_t realsize;
unsigned long slabflags;
+ int i;
s = kmalloc_caches_dma[index];
if (s)
@@ -2760,7 +2630,14 @@ static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags)
realsize = kmalloc_caches[index].objsize;
text = kasprintf(flags & ~SLUB_DMA, "kmalloc_dma-%d",
(unsigned int)realsize);
- s = kmalloc(kmem_size, flags & ~SLUB_DMA);
+
+ s = NULL;
+ for (i = 0; i < KMALLOC_CACHES; i++)
+ if (!kmalloc_caches[i].size)
+ break;
+
+ BUG_ON(i >= KMALLOC_CACHES);
+ s = kmalloc_caches + i;
/*
* Must defer sysfs creation to a workqueue because we don't know
@@ -2772,9 +2649,9 @@ static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags)
if (slab_state >= SYSFS)
slabflags |= __SYSFS_ADD_DEFERRED;
- if (!s || !text || !kmem_cache_open(s, flags, text,
+ if (!text || !kmem_cache_open(s, flags, text,
realsize, ARCH_KMALLOC_MINALIGN, slabflags, NULL)) {
- kfree(s);
+ s->size = 0;
kfree(text);
goto unlock_out;
}
@@ -3086,7 +2963,7 @@ static void slab_mem_offline_callback(void *arg)
/*
* if n->nr_slabs > 0, slabs still exist on the node
* that is going down. We were unable to free them,
- * and offline_pages() function shoudn't call this
+ * and offline_pages() function shouldn't call this
* callback. So, we must fail.
*/
BUG_ON(slabs_node(s, offline_node));
@@ -3176,8 +3053,6 @@ void __init kmem_cache_init(void)
int i;
int caches = 0;
- init_alloc_cpu();
-
#ifdef CONFIG_NUMA
/*
* Must first have the slab cache available for the allocations of the
@@ -3261,8 +3136,10 @@ void __init kmem_cache_init(void)
#ifdef CONFIG_SMP
register_cpu_notifier(&slab_notifier);
- kmem_size = offsetof(struct kmem_cache, cpu_slab) +
- nr_cpu_ids * sizeof(struct kmem_cache_cpu *);
+#endif
+#ifdef CONFIG_NUMA
+ kmem_size = offsetof(struct kmem_cache, node) +
+ nr_node_ids * sizeof(struct kmem_cache_node *);
#else
kmem_size = sizeof(struct kmem_cache);
#endif
@@ -3351,22 +3228,12 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
down_write(&slub_lock);
s = find_mergeable(size, align, flags, name, ctor);
if (s) {
- int cpu;
-
s->refcount++;
/*
* Adjust the object sizes so that we clear
* the complete object on kzalloc.
*/
s->objsize = max(s->objsize, (int)size);
-
- /*
- * And then we need to update the object size in the
- * per cpu structures
- */
- for_each_online_cpu(cpu)
- get_cpu_slab(s, cpu)->objsize = s->objsize;
-
s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
up_write(&slub_lock);
@@ -3420,29 +3287,15 @@ static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
unsigned long flags;
switch (action) {
- case CPU_UP_PREPARE:
- case CPU_UP_PREPARE_FROZEN:
- init_alloc_cpu_cpu(cpu);
- down_read(&slub_lock);
- list_for_each_entry(s, &slab_caches, list)
- s->cpu_slab[cpu] = alloc_kmem_cache_cpu(s, cpu,
- GFP_KERNEL);
- up_read(&slub_lock);
- break;
-
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
down_read(&slub_lock);
list_for_each_entry(s, &slab_caches, list) {
- struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
-
local_irq_save(flags);
__flush_cpu_slab(s, cpu);
local_irq_restore(flags);
- free_kmem_cache_cpu(c, cpu);
- s->cpu_slab[cpu] = NULL;
}
up_read(&slub_lock);
break;
@@ -3928,7 +3781,7 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
int cpu;
for_each_possible_cpu(cpu) {
- struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
if (!c || c->node < 0)
continue;
@@ -4171,6 +4024,23 @@ static ssize_t trace_store(struct kmem_cache *s, const char *buf,
}
SLAB_ATTR(trace);
+#ifdef CONFIG_FAILSLAB
+static ssize_t failslab_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_FAILSLAB));
+}
+
+static ssize_t failslab_store(struct kmem_cache *s, const char *buf,
+ size_t length)
+{
+ s->flags &= ~SLAB_FAILSLAB;
+ if (buf[0] == '1')
+ s->flags |= SLAB_FAILSLAB;
+ return length;
+}
+SLAB_ATTR(failslab);
+#endif
+
static ssize_t reclaim_account_show(struct kmem_cache *s, char *buf)
{
return sprintf(buf, "%d\n", !!(s->flags & SLAB_RECLAIM_ACCOUNT));
@@ -4353,7 +4223,7 @@ static int show_stat(struct kmem_cache *s, char *buf, enum stat_item si)
return -ENOMEM;
for_each_online_cpu(cpu) {
- unsigned x = get_cpu_slab(s, cpu)->stat[si];
+ unsigned x = per_cpu_ptr(s->cpu_slab, cpu)->stat[si];
data[cpu] = x;
sum += x;
@@ -4376,7 +4246,7 @@ static void clear_stat(struct kmem_cache *s, enum stat_item si)
int cpu;
for_each_online_cpu(cpu)
- get_cpu_slab(s, cpu)->stat[si] = 0;
+ per_cpu_ptr(s->cpu_slab, cpu)->stat[si] = 0;
}
#define STAT_ATTR(si, text) \
@@ -4467,6 +4337,10 @@ static struct attribute *slab_attrs[] = {
&deactivate_remote_frees_attr.attr,
&order_fallback_attr.attr,
#endif
+#ifdef CONFIG_FAILSLAB
+ &failslab_attr.attr,
+#endif
+
NULL
};
@@ -4519,7 +4393,7 @@ static void kmem_cache_release(struct kobject *kobj)
kfree(s);
}
-static struct sysfs_ops slab_sysfs_ops = {
+static const struct sysfs_ops slab_sysfs_ops = {
.show = slab_attr_show,
.store = slab_attr_store,
};
@@ -4538,7 +4412,7 @@ static int uevent_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
-static struct kset_uevent_ops slab_uevent_ops = {
+static const struct kset_uevent_ops slab_uevent_ops = {
.filter = uevent_filter,
};
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 392b9bb5bc0..aa33fd67fa4 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -22,6 +22,7 @@
#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
diff --git a/mm/sparse.c b/mm/sparse.c
index 22896d58913..dc0cc4d43ff 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -2,6 +2,7 @@
* sparse memory mappings.
*/
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/mmzone.h>
#include <linux/bootmem.h>
#include <linux/highmem.h>
diff --git a/mm/swap.c b/mm/swap.c
index 308e57d8d7e..7cd60bf0a97 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -30,6 +30,7 @@
#include <linux/notifier.h>
#include <linux/backing-dev.h>
#include <linux/memcontrol.h>
+#include <linux/gfp.h>
#include "internal.h"
@@ -55,7 +56,7 @@ static void __page_cache_release(struct page *page)
del_page_from_lru(zone, page);
spin_unlock_irqrestore(&zone->lru_lock, flags);
}
- free_hot_page(page);
+ free_hot_cold_page(page, 0);
}
static void put_compound_page(struct page *page)
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 6d1daeb1cb4..e10f5833167 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -8,6 +8,7 @@
*/
#include <linux/module.h>
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/kernel_stat.h>
#include <linux/swap.h>
#include <linux/swapops.h>
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 6c0585b1641..6cd0a8f90dc 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -723,6 +723,37 @@ int free_swap_and_cache(swp_entry_t entry)
return p != NULL;
}
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
+/**
+ * mem_cgroup_count_swap_user - count the user of a swap entry
+ * @ent: the swap entry to be checked
+ * @pagep: the pointer for the swap cache page of the entry to be stored
+ *
+ * Returns the number of the user of the swap entry. The number is valid only
+ * for swaps of anonymous pages.
+ * If the entry is found on swap cache, the page is stored to pagep with
+ * refcount of it being incremented.
+ */
+int mem_cgroup_count_swap_user(swp_entry_t ent, struct page **pagep)
+{
+ struct page *page;
+ struct swap_info_struct *p;
+ int count = 0;
+
+ page = find_get_page(&swapper_space, ent.val);
+ if (page)
+ count += page_mapcount(page);
+ p = swap_info_get(ent);
+ if (p) {
+ count += swap_count(p->swap_map[swp_offset(ent)]);
+ spin_unlock(&swap_lock);
+ }
+
+ *pagep = page;
+ return count;
+}
+#endif
+
#ifdef CONFIG_HIBERNATION
/*
* Find the swap type that corresponds to given device (if any).
@@ -840,7 +871,8 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
goto out;
}
- inc_mm_counter(vma->vm_mm, anon_rss);
+ dec_mm_counter(vma->vm_mm, MM_SWAPENTS);
+ inc_mm_counter(vma->vm_mm, MM_ANONPAGES);
get_page(page);
set_pte_at(vma->vm_mm, addr, pte,
pte_mkold(mk_pte(page, vma->vm_page_prot)));
@@ -1759,11 +1791,11 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
unsigned int type;
int i, prev;
int error;
- union swap_header *swap_header = NULL;
- unsigned int nr_good_pages = 0;
+ union swap_header *swap_header;
+ unsigned int nr_good_pages;
int nr_extents = 0;
sector_t span;
- unsigned long maxpages = 1;
+ unsigned long maxpages;
unsigned long swapfilepages;
unsigned char *swap_map = NULL;
struct page *page = NULL;
@@ -1922,9 +1954,13 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
* swap pte.
*/
maxpages = swp_offset(pte_to_swp_entry(
- swp_entry_to_pte(swp_entry(0, ~0UL)))) - 1;
- if (maxpages > swap_header->info.last_page)
- maxpages = swap_header->info.last_page;
+ swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1;
+ if (maxpages > swap_header->info.last_page) {
+ maxpages = swap_header->info.last_page + 1;
+ /* p->max is an unsigned int: don't overflow it */
+ if ((unsigned int)maxpages == 0)
+ maxpages = UINT_MAX;
+ }
p->highest_bit = maxpages - 1;
error = -EINVAL;
@@ -1948,23 +1984,24 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
}
memset(swap_map, 0, maxpages);
+ nr_good_pages = maxpages - 1; /* omit header page */
+
for (i = 0; i < swap_header->info.nr_badpages; i++) {
- int page_nr = swap_header->info.badpages[i];
- if (page_nr <= 0 || page_nr >= swap_header->info.last_page) {
+ unsigned int page_nr = swap_header->info.badpages[i];
+ if (page_nr == 0 || page_nr > swap_header->info.last_page) {
error = -EINVAL;
goto bad_swap;
}
- swap_map[page_nr] = SWAP_MAP_BAD;
+ if (page_nr < maxpages) {
+ swap_map[page_nr] = SWAP_MAP_BAD;
+ nr_good_pages--;
+ }
}
error = swap_cgroup_swapon(type, maxpages);
if (error)
goto bad_swap;
- nr_good_pages = swap_header->info.last_page -
- swap_header->info.nr_badpages -
- 1 /* header page */;
-
if (nr_good_pages) {
swap_map[0] = SWAP_MAP_BAD;
p->max = maxpages;
@@ -2155,7 +2192,11 @@ void swap_shmem_alloc(swp_entry_t entry)
}
/*
- * increase reference count of swap entry by 1.
+ * Increase reference count of swap entry by 1.
+ * Returns 0 for success, or -ENOMEM if a swap_count_continuation is required
+ * but could not be atomically allocated. Returns 0, just as if it succeeded,
+ * if __swap_duplicate() fails for another reason (-EINVAL or -ENOENT), which
+ * might occur if a page table entry has got corrupted.
*/
int swap_duplicate(swp_entry_t entry)
{
diff --git a/mm/truncate.c b/mm/truncate.c
index e87e3724482..f42675a3615 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/backing-dev.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/module.h>
diff --git a/mm/util.c b/mm/util.c
index 834db7be240..f5712e8964b 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -186,6 +186,27 @@ void kzfree(const void *p)
}
EXPORT_SYMBOL(kzfree);
+int kern_ptr_validate(const void *ptr, unsigned long size)
+{
+ unsigned long addr = (unsigned long)ptr;
+ unsigned long min_addr = PAGE_OFFSET;
+ unsigned long align_mask = sizeof(void *) - 1;
+
+ if (unlikely(addr < min_addr))
+ goto out;
+ if (unlikely(addr > (unsigned long)high_memory - size))
+ goto out;
+ if (unlikely(addr & align_mask))
+ goto out;
+ if (unlikely(!kern_addr_valid(addr)))
+ goto out;
+ if (unlikely(!kern_addr_valid(addr + size - 1)))
+ goto out;
+ return 1;
+out:
+ return 0;
+}
+
/*
* strndup_user - duplicate an existing string from user space
* @s: The string to duplicate
diff --git a/mm/vmscan.c b/mm/vmscan.c
index c26986c85ce..3ff3311447f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -13,7 +13,7 @@
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/kernel_stat.h>
#include <linux/swap.h>
#include <linux/pagemap.h>
@@ -262,27 +262,6 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
return ret;
}
-/* Called without lock on whether page is mapped, so answer is unstable */
-static inline int page_mapping_inuse(struct page *page)
-{
- struct address_space *mapping;
-
- /* Page is in somebody's page tables. */
- if (page_mapped(page))
- return 1;
-
- /* Be more reluctant to reclaim swapcache than pagecache */
- if (PageSwapCache(page))
- return 1;
-
- mapping = page_mapping(page);
- if (!mapping)
- return 0;
-
- /* File is mmap'd by somebody? */
- return mapping_mapped(mapping);
-}
-
static inline int is_page_cache_freeable(struct page *page)
{
/*
@@ -579,6 +558,65 @@ redo:
put_page(page); /* drop ref from isolate */
}
+enum page_references {
+ PAGEREF_RECLAIM,
+ PAGEREF_RECLAIM_CLEAN,
+ PAGEREF_KEEP,
+ PAGEREF_ACTIVATE,
+};
+
+static enum page_references page_check_references(struct page *page,
+ struct scan_control *sc)
+{
+ int referenced_ptes, referenced_page;
+ unsigned long vm_flags;
+
+ referenced_ptes = page_referenced(page, 1, sc->mem_cgroup, &vm_flags);
+ referenced_page = TestClearPageReferenced(page);
+
+ /* Lumpy reclaim - ignore references */
+ if (sc->order > PAGE_ALLOC_COSTLY_ORDER)
+ return PAGEREF_RECLAIM;
+
+ /*
+ * Mlock lost the isolation race with us. Let try_to_unmap()
+ * move the page to the unevictable list.
+ */
+ if (vm_flags & VM_LOCKED)
+ return PAGEREF_RECLAIM;
+
+ if (referenced_ptes) {
+ if (PageAnon(page))
+ return PAGEREF_ACTIVATE;
+ /*
+ * All mapped pages start out with page table
+ * references from the instantiating fault, so we need
+ * to look twice if a mapped file page is used more
+ * than once.
+ *
+ * Mark it and spare it for another trip around the
+ * inactive list. Another page table reference will
+ * lead to its activation.
+ *
+ * Note: the mark is set for activated pages as well
+ * so that recently deactivated but used pages are
+ * quickly recovered.
+ */
+ SetPageReferenced(page);
+
+ if (referenced_page)
+ return PAGEREF_ACTIVATE;
+
+ return PAGEREF_KEEP;
+ }
+
+ /* Reclaim if clean, defer dirty pages to writeback */
+ if (referenced_page)
+ return PAGEREF_RECLAIM_CLEAN;
+
+ return PAGEREF_RECLAIM;
+}
+
/*
* shrink_page_list() returns the number of reclaimed pages
*/
@@ -590,16 +628,15 @@ static unsigned long shrink_page_list(struct list_head *page_list,
struct pagevec freed_pvec;
int pgactivate = 0;
unsigned long nr_reclaimed = 0;
- unsigned long vm_flags;
cond_resched();
pagevec_init(&freed_pvec, 1);
while (!list_empty(page_list)) {
+ enum page_references references;
struct address_space *mapping;
struct page *page;
int may_enter_fs;
- int referenced;
cond_resched();
@@ -641,17 +678,16 @@ static unsigned long shrink_page_list(struct list_head *page_list,
goto keep_locked;
}
- referenced = page_referenced(page, 1,
- sc->mem_cgroup, &vm_flags);
- /*
- * In active use or really unfreeable? Activate it.
- * If page which have PG_mlocked lost isoltation race,
- * try_to_unmap moves it to unevictable list
- */
- if (sc->order <= PAGE_ALLOC_COSTLY_ORDER &&
- referenced && page_mapping_inuse(page)
- && !(vm_flags & VM_LOCKED))
+ references = page_check_references(page, sc);
+ switch (references) {
+ case PAGEREF_ACTIVATE:
goto activate_locked;
+ case PAGEREF_KEEP:
+ goto keep_locked;
+ case PAGEREF_RECLAIM:
+ case PAGEREF_RECLAIM_CLEAN:
+ ; /* try to reclaim the page below */
+ }
/*
* Anonymous process memory has backing store?
@@ -685,7 +721,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
}
if (PageDirty(page)) {
- if (sc->order <= PAGE_ALLOC_COSTLY_ORDER && referenced)
+ if (references == PAGEREF_RECLAIM_CLEAN)
goto keep_locked;
if (!may_enter_fs)
goto keep_locked;
@@ -1350,9 +1386,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
continue;
}
- /* page_referenced clears PageReferenced */
- if (page_mapping_inuse(page) &&
- page_referenced(page, 0, sc->mem_cgroup, &vm_flags)) {
+ if (page_referenced(page, 0, sc->mem_cgroup, &vm_flags)) {
nr_rotated++;
/*
* Identify referenced, file-backed active pages and
@@ -1694,8 +1728,7 @@ static void shrink_zones(int priority, struct zonelist *zonelist,
continue;
note_zone_scanning_priority(zone, priority);
- if (zone_is_all_unreclaimable(zone) &&
- priority != DEF_PRIORITY)
+ if (zone->all_unreclaimable && priority != DEF_PRIORITY)
continue; /* Let kswapd poll it */
sc->all_unreclaimable = 0;
} else {
@@ -1922,7 +1955,7 @@ static int sleeping_prematurely(pg_data_t *pgdat, int order, long remaining)
if (!populated_zone(zone))
continue;
- if (zone_is_all_unreclaimable(zone))
+ if (zone->all_unreclaimable)
continue;
if (!zone_watermark_ok(zone, order, high_wmark_pages(zone),
@@ -2012,8 +2045,7 @@ loop_again:
if (!populated_zone(zone))
continue;
- if (zone_is_all_unreclaimable(zone) &&
- priority != DEF_PRIORITY)
+ if (zone->all_unreclaimable && priority != DEF_PRIORITY)
continue;
/*
@@ -2056,13 +2088,9 @@ loop_again:
if (!populated_zone(zone))
continue;
- if (zone_is_all_unreclaimable(zone) &&
- priority != DEF_PRIORITY)
+ if (zone->all_unreclaimable && priority != DEF_PRIORITY)
continue;
- if (!zone_watermark_ok(zone, order,
- high_wmark_pages(zone), end_zone, 0))
- all_zones_ok = 0;
temp_priority[i] = priority;
sc.nr_scanned = 0;
note_zone_scanning_priority(zone, priority);
@@ -2087,12 +2115,11 @@ loop_again:
lru_pages);
sc.nr_reclaimed += reclaim_state->reclaimed_slab;
total_scanned += sc.nr_scanned;
- if (zone_is_all_unreclaimable(zone))
+ if (zone->all_unreclaimable)
continue;
- if (nr_slab == 0 && zone->pages_scanned >=
- (zone_reclaimable_pages(zone) * 6))
- zone_set_flag(zone,
- ZONE_ALL_UNRECLAIMABLE);
+ if (nr_slab == 0 &&
+ zone->pages_scanned >= (zone_reclaimable_pages(zone) * 6))
+ zone->all_unreclaimable = 1;
/*
* If we've done a decent amount of scanning and
* the reclaim ratio is low, start doing writepage
@@ -2102,13 +2129,18 @@ loop_again:
total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
sc.may_writepage = 1;
- /*
- * We are still under min water mark. it mean we have
- * GFP_ATOMIC allocation failure risk. Hurry up!
- */
- if (!zone_watermark_ok(zone, order, min_wmark_pages(zone),
- end_zone, 0))
- has_under_min_watermark_zone = 1;
+ if (!zone_watermark_ok(zone, order,
+ high_wmark_pages(zone), end_zone, 0)) {
+ all_zones_ok = 0;
+ /*
+ * We are still under min water mark. This
+ * means that we have a GFP_ATOMIC allocation
+ * failure risk. Hurry up!
+ */
+ if (!zone_watermark_ok(zone, order,
+ min_wmark_pages(zone), end_zone, 0))
+ has_under_min_watermark_zone = 1;
+ }
}
if (all_zones_ok)
@@ -2550,6 +2582,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
* and RECLAIM_SWAP.
*/
p->flags |= PF_MEMALLOC | PF_SWAPWRITE;
+ lockdep_set_current_reclaim_state(gfp_mask);
reclaim_state.reclaimed_slab = 0;
p->reclaim_state = &reclaim_state;
@@ -2593,6 +2626,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
p->reclaim_state = NULL;
current->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE);
+ lockdep_clear_current_reclaim_state();
return sc.nr_reclaimed >= nr_pages;
}
@@ -2615,7 +2649,7 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages)
return ZONE_RECLAIM_FULL;
- if (zone_is_all_unreclaimable(zone))
+ if (zone->all_unreclaimable)
return ZONE_RECLAIM_FULL;
/*
diff --git a/mm/vmstat.c b/mm/vmstat.c
index fc5aa183bc4..fa12ea3051f 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/vmstat.h>
#include <linux/sched.h>
@@ -763,7 +764,7 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
"\n prev_priority: %i"
"\n start_pfn: %lu"
"\n inactive_ratio: %u",
- zone_is_all_unreclaimable(zone),
+ zone->all_unreclaimable,
zone->prev_priority,
zone->zone_start_pfn,
zone->inactive_ratio);
diff --git a/net/802/garp.c b/net/802/garp.c
index 1dcb0660c49..9ed7c0e7dc1 100644
--- a/net/802/garp.c
+++ b/net/802/garp.c
@@ -14,6 +14,7 @@
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <linux/llc.h>
+#include <linux/slab.h>
#include <net/llc.h>
#include <net/llc_pdu.h>
#include <net/garp.h>
diff --git a/net/802/p8022.c b/net/802/p8022.c
index 2530f35241c..7f353c4f437 100644
--- a/net/802/p8022.c
+++ b/net/802/p8022.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/datalink.h>
#include <linux/mm.h>
#include <linux/in.h>
diff --git a/net/802/p8023.c b/net/802/p8023.c
index 6ab1835041a..1256a40da43 100644
--- a/net/802/p8023.c
+++ b/net/802/p8023.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/datalink.h>
#include <net/p8022.h>
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 6fea0750662..21cde8fd579 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/datalink.h>
#include <net/llc.h>
#include <net/psnap.h>
diff --git a/net/802/stp.c b/net/802/stp.c
index 0b7a24452d1..53c8f77f0cc 100644
--- a/net/802/stp.c
+++ b/net/802/stp.c
@@ -11,6 +11,7 @@
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/llc.h>
+#include <linux/slab.h>
#include <net/llc.h>
#include <net/llc_pdu.h>
#include <net/stp.h>
diff --git a/net/802/tr.c b/net/802/tr.c
index 44acce47fcd..1c6e596074d 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -36,6 +36,7 @@
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/sysctl.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <net/net_namespace.h>
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 453512266ea..97da977c2a2 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rculist.h>
#include <net/p8022.h>
@@ -378,6 +379,8 @@ static void vlan_transfer_features(struct net_device *dev,
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
#endif
+ vlandev->real_num_tx_queues = dev->real_num_tx_queues;
+ BUG_ON(vlandev->real_num_tx_queues > vlandev->num_tx_queues);
if (old_features != vlandev->features)
netdev_features_change(vlandev);
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index c0316e0ca6e..c584a0af77d 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -11,7 +11,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
if (netpoll_rx(skb))
return NET_RX_DROP;
- if (skb_bond_should_drop(skb))
+ if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
goto drop;
skb->skb_iif = skb->dev->ifindex;
@@ -83,7 +83,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
{
struct sk_buff *p;
- if (skb_bond_should_drop(skb))
+ if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
goto drop;
skb->skb_iif = skb->dev->ifindex;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 9e83272fc5b..29b6348c8d4 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -21,6 +21,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -361,6 +362,14 @@ static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
return ret;
}
+static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+ struct net_device *rdev = vlan_dev_info(dev)->real_dev;
+ const struct net_device_ops *ops = rdev->netdev_ops;
+
+ return ops->ndo_select_queue(rdev, skb);
+}
+
static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
{
/* TODO: gotta make sure the underlying layer can handle it,
@@ -688,7 +697,8 @@ static const struct header_ops vlan_header_ops = {
.parse = eth_header_parse,
};
-static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops;
+static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops,
+ vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq;
static int vlan_dev_init(struct net_device *dev)
{
@@ -722,11 +732,17 @@ static int vlan_dev_init(struct net_device *dev)
if (real_dev->features & NETIF_F_HW_VLAN_TX) {
dev->header_ops = real_dev->header_ops;
dev->hard_header_len = real_dev->hard_header_len;
- dev->netdev_ops = &vlan_netdev_accel_ops;
+ if (real_dev->netdev_ops->ndo_select_queue)
+ dev->netdev_ops = &vlan_netdev_accel_ops_sq;
+ else
+ dev->netdev_ops = &vlan_netdev_accel_ops;
} else {
dev->header_ops = &vlan_header_ops;
dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
- dev->netdev_ops = &vlan_netdev_ops;
+ if (real_dev->netdev_ops->ndo_select_queue)
+ dev->netdev_ops = &vlan_netdev_ops_sq;
+ else
+ dev->netdev_ops = &vlan_netdev_ops;
}
if (is_vlan_dev(real_dev))
@@ -865,6 +881,56 @@ static const struct net_device_ops vlan_netdev_accel_ops = {
#endif
};
+static const struct net_device_ops vlan_netdev_ops_sq = {
+ .ndo_select_queue = vlan_dev_select_queue,
+ .ndo_change_mtu = vlan_dev_change_mtu,
+ .ndo_init = vlan_dev_init,
+ .ndo_uninit = vlan_dev_uninit,
+ .ndo_open = vlan_dev_open,
+ .ndo_stop = vlan_dev_stop,
+ .ndo_start_xmit = vlan_dev_hard_start_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = vlan_dev_set_mac_address,
+ .ndo_set_rx_mode = vlan_dev_set_rx_mode,
+ .ndo_set_multicast_list = vlan_dev_set_rx_mode,
+ .ndo_change_rx_flags = vlan_dev_change_rx_flags,
+ .ndo_do_ioctl = vlan_dev_ioctl,
+ .ndo_neigh_setup = vlan_dev_neigh_setup,
+ .ndo_get_stats = vlan_dev_get_stats,
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+ .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup,
+ .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done,
+ .ndo_fcoe_enable = vlan_dev_fcoe_enable,
+ .ndo_fcoe_disable = vlan_dev_fcoe_disable,
+ .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
+#endif
+};
+
+static const struct net_device_ops vlan_netdev_accel_ops_sq = {
+ .ndo_select_queue = vlan_dev_select_queue,
+ .ndo_change_mtu = vlan_dev_change_mtu,
+ .ndo_init = vlan_dev_init,
+ .ndo_uninit = vlan_dev_uninit,
+ .ndo_open = vlan_dev_open,
+ .ndo_stop = vlan_dev_stop,
+ .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = vlan_dev_set_mac_address,
+ .ndo_set_rx_mode = vlan_dev_set_rx_mode,
+ .ndo_set_multicast_list = vlan_dev_set_rx_mode,
+ .ndo_change_rx_flags = vlan_dev_change_rx_flags,
+ .ndo_do_ioctl = vlan_dev_ioctl,
+ .ndo_neigh_setup = vlan_dev_neigh_setup,
+ .ndo_get_stats = vlan_dev_get_stats,
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+ .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup,
+ .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done,
+ .ndo_fcoe_enable = vlan_dev_fcoe_enable,
+ .ndo_fcoe_disable = vlan_dev_fcoe_disable,
+ .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
+#endif
+};
+
void vlan_setup(struct net_device *dev)
{
ether_setup(dev);
diff --git a/net/9p/client.c b/net/9p/client.c
index 09d4f1e2e4a..0aa79faa985 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -29,6 +29,7 @@
#include <linux/poll.h>
#include <linux/idr.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <net/9p/9p.h>
@@ -46,6 +47,7 @@ enum {
Opt_msize,
Opt_trans,
Opt_legacy,
+ Opt_version,
Opt_err,
};
@@ -53,9 +55,43 @@ static const match_table_t tokens = {
{Opt_msize, "msize=%u"},
{Opt_legacy, "noextend"},
{Opt_trans, "trans=%s"},
+ {Opt_version, "version=%s"},
{Opt_err, NULL},
};
+inline int p9_is_proto_dotl(struct p9_client *clnt)
+{
+ return (clnt->proto_version == p9_proto_2000L);
+}
+EXPORT_SYMBOL(p9_is_proto_dotl);
+
+inline int p9_is_proto_dotu(struct p9_client *clnt)
+{
+ return (clnt->proto_version == p9_proto_2000u);
+}
+EXPORT_SYMBOL(p9_is_proto_dotu);
+
+/* Interpret mount option for protocol version */
+static int get_protocol_version(const substring_t *name)
+{
+ int version = -EINVAL;
+
+ if (!strncmp("9p2000", name->from, name->to-name->from)) {
+ version = p9_proto_legacy;
+ P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");
+ } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) {
+ version = p9_proto_2000u;
+ P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
+ } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) {
+ version = p9_proto_2000L;
+ P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
+ } else {
+ P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ",
+ name->from);
+ }
+ return version;
+}
+
static struct p9_req_t *
p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
@@ -75,7 +111,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
int option;
int ret = 0;
- clnt->dotu = 1;
+ clnt->proto_version = p9_proto_2000u;
clnt->msize = 8192;
if (!opts)
@@ -118,7 +154,13 @@ static int parse_opts(char *opts, struct p9_client *clnt)
}
break;
case Opt_legacy:
- clnt->dotu = 0;
+ clnt->proto_version = p9_proto_legacy;
+ break;
+ case Opt_version:
+ ret = get_protocol_version(&args[0]);
+ if (ret == -EINVAL)
+ goto free_and_return;
+ clnt->proto_version = ret;
break;
default:
continue;
@@ -410,14 +452,15 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
int ecode;
char *ename;
- err = p9pdu_readf(req->rc, c->dotu, "s?d", &ename, &ecode);
+ err = p9pdu_readf(req->rc, c->proto_version, "s?d",
+ &ename, &ecode);
if (err) {
P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n",
err);
return err;
}
- if (c->dotu)
+ if (p9_is_proto_dotu(c))
err = -ecode;
if (!err || !IS_ERR_VALUE(err))
@@ -492,7 +535,12 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
- if (c->status != Connected)
+ /* we allow for any status other than disconnected */
+ if (c->status == Disconnected)
+ return ERR_PTR(-EIO);
+
+ /* if status is begin_disconnected we allow only clunk request */
+ if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
return ERR_PTR(-EIO);
if (signal_pending(current)) {
@@ -515,7 +563,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
/* marshall the data */
p9pdu_prepare(req->tc, tag, type);
va_start(ap, fmt);
- err = p9pdu_vwritef(req->tc, c->dotu, fmt, ap);
+ err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
va_end(ap);
p9pdu_finalize(req->tc);
@@ -627,14 +675,31 @@ int p9_client_version(struct p9_client *c)
char *version;
int msize;
- P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d extended %d\n",
- c->msize, c->dotu);
- req = p9_client_rpc(c, P9_TVERSION, "ds", c->msize,
- c->dotu ? "9P2000.u" : "9P2000");
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d protocol %d\n",
+ c->msize, c->proto_version);
+
+ switch (c->proto_version) {
+ case p9_proto_2000L:
+ req = p9_client_rpc(c, P9_TVERSION, "ds",
+ c->msize, "9P2000.L");
+ break;
+ case p9_proto_2000u:
+ req = p9_client_rpc(c, P9_TVERSION, "ds",
+ c->msize, "9P2000.u");
+ break;
+ case p9_proto_legacy:
+ req = p9_client_rpc(c, P9_TVERSION, "ds",
+ c->msize, "9P2000");
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
if (IS_ERR(req))
return PTR_ERR(req);
- err = p9pdu_readf(req->rc, c->dotu, "ds", &msize, &version);
+ err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version);
if (err) {
P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
p9pdu_dump(1, req->rc);
@@ -642,10 +707,12 @@ int p9_client_version(struct p9_client *c)
}
P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
- if (!memcmp(version, "9P2000.u", 8))
- c->dotu = 1;
- else if (!memcmp(version, "9P2000", 6))
- c->dotu = 0;
+ if (!strncmp(version, "9P2000.L", 8))
+ c->proto_version = p9_proto_2000L;
+ else if (!strncmp(version, "9P2000.u", 8))
+ c->proto_version = p9_proto_2000u;
+ else if (!strncmp(version, "9P2000", 6))
+ c->proto_version = p9_proto_legacy;
else {
err = -EREMOTEIO;
goto error;
@@ -700,8 +767,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
goto put_trans;
}
- P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n",
- clnt, clnt->trans_mod, clnt->msize, clnt->dotu);
+ P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
+ clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
err = clnt->trans_mod->create(clnt, dev_name, options);
if (err)
@@ -739,8 +806,10 @@ void p9_client_destroy(struct p9_client *clnt)
v9fs_put_trans(clnt->trans_mod);
- list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
+ list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) {
+ printk(KERN_INFO "Found fid %d not clunked\n", fid->fid);
p9_fid_destroy(fid);
+ }
if (clnt->fidpool)
p9_idpool_destroy(clnt->fidpool);
@@ -758,6 +827,13 @@ void p9_client_disconnect(struct p9_client *clnt)
}
EXPORT_SYMBOL(p9_client_disconnect);
+void p9_client_begin_disconnect(struct p9_client *clnt)
+{
+ P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
+ clnt->status = BeginDisconnect;
+}
+EXPORT_SYMBOL(p9_client_begin_disconnect);
+
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
char *uname, u32 n_uname, char *aname)
{
@@ -784,7 +860,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
goto error;
}
- err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
+ err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
if (err) {
p9pdu_dump(1, req->rc);
p9_free_req(clnt, req);
@@ -833,7 +909,7 @@ p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname)
goto error;
}
- err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
+ err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
if (err) {
p9pdu_dump(1, req->rc);
p9_free_req(clnt, req);
@@ -891,7 +967,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
goto error;
}
- err = p9pdu_readf(req->rc, clnt->dotu, "R", &nwqids, &wqids);
+ err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids);
if (err) {
p9pdu_dump(1, req->rc);
p9_free_req(clnt, req);
@@ -952,7 +1028,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
goto error;
}
- err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
+ err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
if (err) {
p9pdu_dump(1, req->rc);
goto free_and_error;
@@ -997,7 +1073,7 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
goto error;
}
- err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
+ err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
if (err) {
p9pdu_dump(1, req->rc);
goto free_and_error;
@@ -1098,7 +1174,7 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
goto error;
}
- err = p9pdu_readf(req->rc, clnt->dotu, "D", &count, &dataptr);
+ err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
if (err) {
p9pdu_dump(1, req->rc);
goto free_and_error;
@@ -1159,7 +1235,7 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
goto error;
}
- err = p9pdu_readf(req->rc, clnt->dotu, "d", &count);
+ err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
if (err) {
p9pdu_dump(1, req->rc);
goto free_and_error;
@@ -1199,7 +1275,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
goto error;
}
- err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret);
+ err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret);
if (err) {
p9pdu_dump(1, req->rc);
p9_free_req(clnt, req);
@@ -1226,7 +1302,7 @@ error:
}
EXPORT_SYMBOL(p9_client_stat);
-static int p9_client_statsize(struct p9_wstat *wst, int optional)
+static int p9_client_statsize(struct p9_wstat *wst, int proto_version)
{
int ret;
@@ -1245,7 +1321,7 @@ static int p9_client_statsize(struct p9_wstat *wst, int optional)
if (wst->muid)
ret += strlen(wst->muid);
- if (optional) {
+ if (proto_version == p9_proto_2000u) {
ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */
if (wst->extension)
ret += strlen(wst->extension);
@@ -1262,7 +1338,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
err = 0;
clnt = fid->clnt;
- wst->size = p9_client_statsize(wst, clnt->dotu);
+ wst->size = p9_client_statsize(wst, clnt->proto_version);
P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
P9_DPRINTK(P9_DEBUG_9P,
" sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index fc70147c771..e7541d5b011 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <net/9p/9p.h>
@@ -52,7 +53,7 @@
#endif
static int
-p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...);
+p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
#ifdef CONFIG_NET_9P_DEBUG
void
@@ -144,7 +145,8 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
*/
static int
-p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
+p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
+ va_list ap)
{
const char *ptr;
int errcode = 0;
@@ -194,7 +196,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
int16_t len;
int size;
- errcode = p9pdu_readf(pdu, optional, "w", &len);
+ errcode = p9pdu_readf(pdu, proto_version,
+ "w", &len);
if (errcode)
break;
@@ -217,7 +220,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
struct p9_qid *qid =
va_arg(ap, struct p9_qid *);
- errcode = p9pdu_readf(pdu, optional, "bdq",
+ errcode = p9pdu_readf(pdu, proto_version, "bdq",
&qid->type, &qid->version,
&qid->path);
}
@@ -230,7 +233,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
stbuf->n_uid = stbuf->n_gid = stbuf->n_muid =
-1;
errcode =
- p9pdu_readf(pdu, optional,
+ p9pdu_readf(pdu, proto_version,
"wwdQdddqssss?sddd",
&stbuf->size, &stbuf->type,
&stbuf->dev, &stbuf->qid,
@@ -250,7 +253,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
void **data = va_arg(ap, void **);
errcode =
- p9pdu_readf(pdu, optional, "d", count);
+ p9pdu_readf(pdu, proto_version, "d", count);
if (!errcode) {
*count =
MIN(*count,
@@ -263,8 +266,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
int16_t *nwname = va_arg(ap, int16_t *);
char ***wnames = va_arg(ap, char ***);
- errcode =
- p9pdu_readf(pdu, optional, "w", nwname);
+ errcode = p9pdu_readf(pdu, proto_version,
+ "w", nwname);
if (!errcode) {
*wnames =
kmalloc(sizeof(char *) * *nwname,
@@ -278,7 +281,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
for (i = 0; i < *nwname; i++) {
errcode =
- p9pdu_readf(pdu, optional,
+ p9pdu_readf(pdu,
+ proto_version,
"s",
&(*wnames)[i]);
if (errcode)
@@ -306,7 +310,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
*wqids = NULL;
errcode =
- p9pdu_readf(pdu, optional, "w", nwqid);
+ p9pdu_readf(pdu, proto_version, "w", nwqid);
if (!errcode) {
*wqids =
kmalloc(*nwqid *
@@ -321,7 +325,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
for (i = 0; i < *nwqid; i++) {
errcode =
- p9pdu_readf(pdu, optional,
+ p9pdu_readf(pdu,
+ proto_version,
"Q",
&(*wqids)[i]);
if (errcode)
@@ -336,7 +341,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
}
break;
case '?':
- if (!optional)
+ if (proto_version != p9_proto_2000u)
return 0;
break;
default:
@@ -352,7 +357,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
}
int
-p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
+p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
+ va_list ap)
{
const char *ptr;
int errcode = 0;
@@ -389,7 +395,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
if (sptr)
len = MIN(strlen(sptr), USHORT_MAX);
- errcode = p9pdu_writef(pdu, optional, "w", len);
+ errcode = p9pdu_writef(pdu, proto_version,
+ "w", len);
if (!errcode && pdu_write(pdu, sptr, len))
errcode = -EFAULT;
}
@@ -398,7 +405,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
const struct p9_qid *qid =
va_arg(ap, const struct p9_qid *);
errcode =
- p9pdu_writef(pdu, optional, "bdq",
+ p9pdu_writef(pdu, proto_version, "bdq",
qid->type, qid->version,
qid->path);
} break;
@@ -406,7 +413,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
const struct p9_wstat *stbuf =
va_arg(ap, const struct p9_wstat *);
errcode =
- p9pdu_writef(pdu, optional,
+ p9pdu_writef(pdu, proto_version,
"wwdQdddqssss?sddd",
stbuf->size, stbuf->type,
stbuf->dev, &stbuf->qid,
@@ -421,8 +428,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
int32_t count = va_arg(ap, int32_t);
const void *data = va_arg(ap, const void *);
- errcode =
- p9pdu_writef(pdu, optional, "d", count);
+ errcode = p9pdu_writef(pdu, proto_version, "d",
+ count);
if (!errcode && pdu_write(pdu, data, count))
errcode = -EFAULT;
}
@@ -431,8 +438,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
int32_t count = va_arg(ap, int32_t);
const char __user *udata =
va_arg(ap, const void __user *);
- errcode =
- p9pdu_writef(pdu, optional, "d", count);
+ errcode = p9pdu_writef(pdu, proto_version, "d",
+ count);
if (!errcode && pdu_write_u(pdu, udata, count))
errcode = -EFAULT;
}
@@ -441,14 +448,15 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
int16_t nwname = va_arg(ap, int);
const char **wnames = va_arg(ap, const char **);
- errcode =
- p9pdu_writef(pdu, optional, "w", nwname);
+ errcode = p9pdu_writef(pdu, proto_version, "w",
+ nwname);
if (!errcode) {
int i;
for (i = 0; i < nwname; i++) {
errcode =
- p9pdu_writef(pdu, optional,
+ p9pdu_writef(pdu,
+ proto_version,
"s",
wnames[i]);
if (errcode)
@@ -462,14 +470,15 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
struct p9_qid *wqids =
va_arg(ap, struct p9_qid *);
- errcode =
- p9pdu_writef(pdu, optional, "w", nwqid);
+ errcode = p9pdu_writef(pdu, proto_version, "w",
+ nwqid);
if (!errcode) {
int i;
for (i = 0; i < nwqid; i++) {
errcode =
- p9pdu_writef(pdu, optional,
+ p9pdu_writef(pdu,
+ proto_version,
"Q",
&wqids[i]);
if (errcode)
@@ -479,7 +488,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
}
break;
case '?':
- if (!optional)
+ if (proto_version != p9_proto_2000u)
return 0;
break;
default:
@@ -494,32 +503,32 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
return errcode;
}
-int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...)
+int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
- ret = p9pdu_vreadf(pdu, optional, fmt, ap);
+ ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
va_end(ap);
return ret;
}
static int
-p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...)
+p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
- ret = p9pdu_vwritef(pdu, optional, fmt, ap);
+ ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
va_end(ap);
return ret;
}
-int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu)
+int p9stat_read(char *buf, int len, struct p9_wstat *st, int proto_version)
{
struct p9_fcall fake_pdu;
int ret;
@@ -529,7 +538,7 @@ int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu)
fake_pdu.sdata = buf;
fake_pdu.offset = 0;
- ret = p9pdu_readf(&fake_pdu, dotu, "S", st);
+ ret = p9pdu_readf(&fake_pdu, proto_version, "S", st);
if (ret) {
P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
p9pdu_dump(1, &fake_pdu);
diff --git a/net/9p/protocol.h b/net/9p/protocol.h
index ccde462e7ac..2431c0f38d5 100644
--- a/net/9p/protocol.h
+++ b/net/9p/protocol.h
@@ -25,9 +25,9 @@
*
*/
-int
-p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap);
-int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...);
+int p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
+ va_list ap);
+int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
int p9pdu_finalize(struct p9_fcall *pdu);
void p9pdu_dump(int, struct p9_fcall *);
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 31d0b05582a..98ce9bcb0e1 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -38,6 +38,7 @@
#include <linux/idr.h>
#include <linux/file.h>
#include <linux/parser.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
index 2c95a89c0f4..041101ab4aa 100644
--- a/net/9p/trans_rdma.c
+++ b/net/9p/trans_rdma.c
@@ -40,6 +40,7 @@
#include <linux/file.h>
#include <linux/parser.h>
#include <linux/semaphore.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index cb50f4ae5ee..7eb78ecc161 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -37,6 +37,7 @@
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/file.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
#include <linux/parser.h>
#include <net/9p/client.h>
@@ -49,8 +50,6 @@
/* a single mutex to manage channel initialization and attachment */
static DEFINE_MUTEX(virtio_9p_lock);
-/* global which tracks highest initialized channel */
-static int chan_index;
/**
* struct virtio_chan - per-instance transport information
@@ -68,8 +67,7 @@ static int chan_index;
*
*/
-static struct virtio_chan {
- bool initialized;
+struct virtio_chan {
bool inuse;
spinlock_t lock;
@@ -80,7 +78,17 @@ static struct virtio_chan {
/* Scatterlist: can be too big for stack. */
struct scatterlist sg[VIRTQUEUE_NUM];
-} channels[MAX_9P_CHAN];
+
+ int tag_len;
+ /*
+ * tag name to identify a mount Non-null terminated
+ */
+ char *tag;
+
+ struct list_head chan_list;
+};
+
+static struct list_head virtio_chan_list;
/* How many bytes left in this page. */
static unsigned int rest_of_page(void *data)
@@ -213,30 +221,38 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
return 0;
}
+static ssize_t p9_mount_tag_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtio_chan *chan;
+ struct virtio_device *vdev;
+
+ vdev = dev_to_virtio(dev);
+ chan = vdev->priv;
+
+ return snprintf(buf, chan->tag_len + 1, "%s", chan->tag);
+}
+
+static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL);
+
/**
* p9_virtio_probe - probe for existence of 9P virtio channels
* @vdev: virtio device to probe
*
- * This probes for existing virtio channels. At present only
- * a single channel is in use, so in the future more work may need
- * to be done here.
+ * This probes for existing virtio channels.
*
*/
static int p9_virtio_probe(struct virtio_device *vdev)
{
+ __u16 tag_len;
+ char *tag;
int err;
struct virtio_chan *chan;
- int index;
- mutex_lock(&virtio_9p_lock);
- index = chan_index++;
- chan = &channels[index];
- mutex_unlock(&virtio_9p_lock);
-
- if (chan_index > MAX_9P_CHAN) {
- printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n");
- BUG();
+ chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL);
+ if (!chan) {
+ printk(KERN_ERR "9p: Failed to allocate virtio 9P channel\n");
err = -ENOMEM;
goto fail;
}
@@ -255,15 +271,37 @@ static int p9_virtio_probe(struct virtio_device *vdev)
sg_init_table(chan->sg, VIRTQUEUE_NUM);
chan->inuse = false;
- chan->initialized = true;
+ if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
+ vdev->config->get(vdev,
+ offsetof(struct virtio_9p_config, tag_len),
+ &tag_len, sizeof(tag_len));
+ } else {
+ err = -EINVAL;
+ goto out_free_vq;
+ }
+ tag = kmalloc(tag_len, GFP_KERNEL);
+ if (!tag) {
+ err = -ENOMEM;
+ goto out_free_vq;
+ }
+ vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag),
+ tag, tag_len);
+ chan->tag = tag;
+ chan->tag_len = tag_len;
+ err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
+ if (err) {
+ kfree(tag);
+ goto out_free_vq;
+ }
+ mutex_lock(&virtio_9p_lock);
+ list_add_tail(&chan->chan_list, &virtio_chan_list);
+ mutex_unlock(&virtio_9p_lock);
return 0;
out_free_vq:
vdev->config->del_vqs(vdev);
+ kfree(chan);
fail:
- mutex_lock(&virtio_9p_lock);
- chan_index--;
- mutex_unlock(&virtio_9p_lock);
return err;
}
@@ -280,35 +318,31 @@ fail:
* We use a simple reference count mechanism to ensure that only a single
* mount has a channel open at a time.
*
- * Bugs: doesn't allow identification of a specific channel
- * to allocate, channels are allocated sequentially. This was
- * a pragmatic decision to get things rolling, but ideally some
- * way of identifying the channel to attach to would be nice
- * if we are going to support multiple channels.
- *
*/
static int
p9_virtio_create(struct p9_client *client, const char *devname, char *args)
{
- struct virtio_chan *chan = channels;
- int index = 0;
+ struct virtio_chan *chan;
+ int ret = -ENOENT;
+ int found = 0;
mutex_lock(&virtio_9p_lock);
- while (index < MAX_9P_CHAN) {
- if (chan->initialized && !chan->inuse) {
- chan->inuse = true;
- break;
- } else {
- index++;
- chan = &channels[index];
+ list_for_each_entry(chan, &virtio_chan_list, chan_list) {
+ if (!strncmp(devname, chan->tag, chan->tag_len)) {
+ if (!chan->inuse) {
+ chan->inuse = true;
+ found = 1;
+ break;
+ }
+ ret = -EBUSY;
}
}
mutex_unlock(&virtio_9p_lock);
- if (index >= MAX_9P_CHAN) {
+ if (!found) {
printk(KERN_ERR "9p: no channels available\n");
- return -ENODEV;
+ return ret;
}
client->trans = (void *)chan;
@@ -329,11 +363,15 @@ static void p9_virtio_remove(struct virtio_device *vdev)
struct virtio_chan *chan = vdev->priv;
BUG_ON(chan->inuse);
+ vdev->config->del_vqs(vdev);
+
+ mutex_lock(&virtio_9p_lock);
+ list_del(&chan->chan_list);
+ mutex_unlock(&virtio_9p_lock);
+ sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
+ kfree(chan->tag);
+ kfree(chan);
- if (chan->initialized) {
- vdev->config->del_vqs(vdev);
- chan->initialized = false;
- }
}
static struct virtio_device_id id_table[] = {
@@ -341,13 +379,19 @@ static struct virtio_device_id id_table[] = {
{ 0 },
};
+static unsigned int features[] = {
+ VIRTIO_9P_MOUNT_TAG,
+};
+
/* The standard "struct lguest_driver": */
static struct virtio_driver p9_virtio_drv = {
- .driver.name = KBUILD_MODNAME,
- .driver.owner = THIS_MODULE,
- .id_table = id_table,
- .probe = p9_virtio_probe,
- .remove = p9_virtio_remove,
+ .feature_table = features,
+ .feature_table_size = ARRAY_SIZE(features),
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = id_table,
+ .probe = p9_virtio_probe,
+ .remove = p9_virtio_remove,
};
static struct p9_trans_module p9_virtio_trans = {
@@ -364,10 +408,7 @@ static struct p9_trans_module p9_virtio_trans = {
/* The standard init function */
static int __init p9_virtio_init(void)
{
- int count;
-
- for (count = 0; count < MAX_9P_CHAN; count++)
- channels[count].initialized = false;
+ INIT_LIST_HEAD(&virtio_chan_list);
v9fs_register_trans(&p9_virtio_trans);
return register_virtio_driver(&p9_virtio_drv);
diff --git a/net/9p/util.c b/net/9p/util.c
index dc4ec05ad93..e048701a72d 100644
--- a/net/9p/util.c
+++ b/net/9p/util.c
@@ -30,6 +30,7 @@
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/idr.h>
+#include <linux/slab.h>
#include <net/9p/9p.h>
/**
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
index f2b3b56aa77..50dce798132 100644
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -30,6 +30,7 @@
*/
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/datalink.h>
#include <net/psnap.h>
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 9fc4da56fb1..7b02967fbbe 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -57,6 +57,7 @@
#include <linux/smp_lock.h>
#include <linux/termios.h> /* For TIOCOUTQ/INQ */
#include <linux/compat.h>
+#include <linux/slab.h>
#include <net/datalink.h>
#include <net/psnap.h>
#include <net/sock.h>
diff --git a/net/atm/addr.c b/net/atm/addr.c
index cf3ae8b4757..dcda35c66f1 100644
--- a/net/atm/addr.c
+++ b/net/atm/addr.c
@@ -4,6 +4,7 @@
#include <linux/atm.h>
#include <linux/atmdev.h>
+#include <linux/slab.h>
#include <linux/uaccess.h>
#include "signaling.h"
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c
index f693b78eb46..799c631f0fe 100644
--- a/net/atm/atm_sysfs.c
+++ b/net/atm/atm_sysfs.c
@@ -1,6 +1,7 @@
/* ATM driver model support. */
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/atmdev.h>
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 4d64d87e757..d6c7ceaf13e 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -18,6 +18,7 @@
#include <linux/rtnetlink.h>
#include <linux/ip.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
diff --git a/net/atm/clip.c b/net/atm/clip.c
index ebfa022008f..313aba11316 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -30,6 +30,7 @@
#include <linux/seq_file.h>
#include <linux/rcupdate.h>
#include <linux/jhash.h>
+#include <linux/slab.h>
#include <net/route.h> /* for struct rtable and routing */
#include <net/icmp.h> /* icmp_send */
#include <linux/param.h> /* for HZ */
diff --git a/net/atm/common.c b/net/atm/common.c
index 74d095a081e..97ed94aa0cb 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -18,6 +18,7 @@
#include <linux/skbuff.h>
#include <linux/bitops.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/sock.h> /* struct sock */
#include <linux/uaccess.h>
#include <linux/poll.h>
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 5da5753157f..feeaf571847 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/capability.h>
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index a6521c8aa88..436f2e17765 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -2,6 +2,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/bitops.h>
diff --git a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c
index 4c141810eb6..e773d833691 100644
--- a/net/atm/mpoa_caches.c
+++ b/net/atm/mpoa_caches.c
@@ -1,5 +1,6 @@
#include <linux/types.h>
#include <linux/atmmpc.h>
+#include <linux/slab.h>
#include <linux/time.h>
#include "mpoa_caches.h"
diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
index b9bdb98427e..53e50029227 100644
--- a/net/atm/mpoa_proc.c
+++ b/net/atm/mpoa_proc.c
@@ -12,6 +12,7 @@
#include <linux/uaccess.h>
#include <linux/atmmpc.h>
#include <linux/atm.h>
+#include <linux/gfp.h>
#include "mpc.h"
#include "mpoa_caches.h"
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index 400839273c6..e49bb6d948a 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -38,6 +38,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/capability.h>
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 7a96b2376bd..696e218436e 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -22,6 +22,7 @@
#include <linux/netdevice.h>
#include <linux/atmclip.h>
#include <linux/init.h> /* for __init */
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/atmclip.h>
#include <linux/uaccess.h>
diff --git a/net/atm/raw.c b/net/atm/raw.c
index d0c4bd047dc..b4f7b9ff3c7 100644
--- a/net/atm/raw.c
+++ b/net/atm/raw.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include "common.h"
#include "protocols.h"
diff --git a/net/atm/resources.c b/net/atm/resources.c
index 90082904f20..d29e5826151 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -19,6 +19,7 @@
#include <linux/capability.h>
#include <linux/delay.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <net/sock.h> /* for struct sock */
diff --git a/net/atm/signaling.c b/net/atm/signaling.c
index ad1d28ae512..6ba6e466ee5 100644
--- a/net/atm/signaling.c
+++ b/net/atm/signaling.c
@@ -14,6 +14,7 @@
#include <linux/atmsvc.h>
#include <linux/atmdev.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include "resources.h"
#include "signaling.h"
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index a5beedf43e2..65c5801261f 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -25,6 +25,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
index a7a0e0c9698..c1cb982f6e8 100644
--- a/net/ax25/ax25_dev.c
+++ b/net/ax25/ax25_dev.c
@@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
+#include <linux/slab.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/timer.h>
diff --git a/net/ax25/ax25_ds_subr.c b/net/ax25/ax25_ds_subr.c
index b5e59787be2..85816e612dc 100644
--- a/net/ax25/ax25_ds_subr.c
+++ b/net/ax25/ax25_ds_subr.c
@@ -17,6 +17,7 @@
#include <linux/sockios.h>
#include <linux/spinlock.h>
#include <linux/net.h>
+#include <linux/gfp.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 71338f11210..5a0dda8df49 100644
--- a/net/ax25/ax25_iface.c
+++ b/net/ax25/ax25_iface.c
@@ -17,6 +17,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index de56d3983de..9bb77654120 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c
index f047a57aa95..cf0c47a2653 100644
--- a/net/ax25/ax25_ip.c
+++ b/net/ax25/ax25_ip.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
index 14912600ec5..37507d806f6 100644
--- a/net/ax25/ax25_out.c
+++ b/net/ax25/ax25_out.c
@@ -19,6 +19,7 @@
#include <linux/sockios.h>
#include <linux/spinlock.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index c833ba4c45a..7805945a5fd 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -23,6 +23,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c
index 034aa10a519..c6715ee4ab8 100644
--- a/net/ax25/ax25_subr.c
+++ b/net/ax25/ax25_subr.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
index 9f13f6eefcb..d349be9578f 100644
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -18,6 +18,7 @@
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c
index 5159be6b262..ebe0ef3f1d8 100644
--- a/net/ax25/sysctl_net_ax25.c
+++ b/net/ax25/sysctl_net_ax25.c
@@ -7,6 +7,7 @@
* Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com)
*/
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/spinlock.h>
#include <net/ax25.h>
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 087cc51f592..404a8500fd0 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -31,7 +31,6 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index ef09c7b3a85..8062dad6d10 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -35,6 +35,7 @@
#include <linux/freezer.h>
#include <linux/errno.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/socket.h>
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index b6234b73c4c..5643a2391e7 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -26,6 +26,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/netdevice.h>
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 2ff6ac7b2ed..2862f53b66b 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -30,7 +30,6 @@
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/skbuff.h>
@@ -39,6 +38,7 @@
#include <linux/file.h>
#include <linux/init.h>
#include <linux/compat.h>
+#include <linux/gfp.h>
#include <net/sock.h>
#include <asm/system.h>
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index 978cc3a718a..7ea1979a8e4 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -26,7 +26,6 @@
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/skbuff.h>
@@ -34,6 +33,7 @@
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/compat.h>
+#include <linux/gfp.h>
#include <net/sock.h>
#include <linux/isdn/capilli.h>
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 1a79a6c7e30..0e8e1a59856 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -1,14 +1,15 @@
/* Bluetooth HCI driver model support. */
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
-struct class *bt_class = NULL;
-EXPORT_SYMBOL_GPL(bt_class);
+static struct class *bt_class;
struct dentry *bt_debugfs = NULL;
EXPORT_SYMBOL_GPL(bt_debugfs);
@@ -405,20 +406,11 @@ static struct device_type bt_host = {
.release = bt_host_release,
};
-static int inquiry_cache_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
+static int inquiry_cache_show(struct seq_file *f, void *p)
{
- struct hci_dev *hdev = file->private_data;
+ struct hci_dev *hdev = f->private;
struct inquiry_cache *cache = &hdev->inq_cache;
struct inquiry_entry *e;
- char buf[4096];
- int n = 0;
hci_dev_lock_bh(hdev);
@@ -426,23 +418,30 @@ static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf,
struct inquiry_data *data = &e->data;
bdaddr_t bdaddr;
baswap(&bdaddr, &data->bdaddr);
- n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
- batostr(&bdaddr),
- data->pscan_rep_mode, data->pscan_period_mode,
- data->pscan_mode, data->dev_class[2],
- data->dev_class[1], data->dev_class[0],
- __le16_to_cpu(data->clock_offset),
- data->rssi, data->ssp_mode, e->timestamp);
+ seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
+ batostr(&bdaddr),
+ data->pscan_rep_mode, data->pscan_period_mode,
+ data->pscan_mode, data->dev_class[2],
+ data->dev_class[1], data->dev_class[0],
+ __le16_to_cpu(data->clock_offset),
+ data->rssi, data->ssp_mode, e->timestamp);
}
hci_dev_unlock_bh(hdev);
- return simple_read_from_buffer(userbuf, count, ppos, buf, n);
+ return 0;
+}
+
+static int inquiry_cache_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, inquiry_cache_show, inode->i_private);
}
static const struct file_operations inquiry_cache_fops = {
- .open = inquiry_cache_open,
- .read = inquiry_cache_read,
+ .open = inquiry_cache_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
int hci_register_sysfs(struct hci_dev *hdev)
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index 9cfef68b9fe..250dfd46237 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -26,7 +26,6 @@
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/skbuff.h>
@@ -35,6 +34,7 @@
#include <linux/file.h>
#include <linux/init.h>
#include <linux/compat.h>
+#include <linux/gfp.h>
#include <net/sock.h>
#include "hidp.h"
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 400efa26ddb..9753b690a8b 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -40,6 +40,8 @@
#include <linux/skbuff.h>
#include <linux/list.h>
#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/crc16.h>
#include <net/sock.h>
@@ -1000,7 +1002,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
BT_DBG("sk %p", sk);
- if (!addr || addr->sa_family != AF_BLUETOOTH)
+ if (!addr || alen < sizeof(addr->sa_family) ||
+ addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
memset(&la, 0, sizeof(la));
@@ -1623,7 +1626,10 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
/* Connectionless channel */
if (sk->sk_type == SOCK_DGRAM) {
skb = l2cap_create_connless_pdu(sk, msg, len);
- err = l2cap_do_send(sk, skb);
+ if (IS_ERR(skb))
+ err = PTR_ERR(skb);
+ else
+ err = l2cap_do_send(sk, skb);
goto done;
}
@@ -2830,6 +2836,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
int len = cmd->len - sizeof(*rsp);
char req[64];
+ if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
+ l2cap_send_disconn_req(conn, sk);
+ goto done;
+ }
+
/* throw out any old stored conf requests */
result = L2CAP_CONF_SUCCESS;
len = l2cap_parse_conf_rsp(sk, rsp->data,
@@ -3937,29 +3948,42 @@ drop:
return 0;
}
-static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
+static int l2cap_debugfs_show(struct seq_file *f, void *p)
{
struct sock *sk;
struct hlist_node *node;
- char *str = buf;
read_lock_bh(&l2cap_sk_list.lock);
sk_for_each(sk, node, &l2cap_sk_list.head) {
struct l2cap_pinfo *pi = l2cap_pi(sk);
- str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
- batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
- sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
- pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
+ seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
+ batostr(&bt_sk(sk)->src),
+ batostr(&bt_sk(sk)->dst),
+ sk->sk_state, __le16_to_cpu(pi->psm),
+ pi->scid, pi->dcid,
+ pi->imtu, pi->omtu, pi->sec_level);
}
read_unlock_bh(&l2cap_sk_list.lock);
- return str - buf;
+ return 0;
}
-static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
+static int l2cap_debugfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, l2cap_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations l2cap_debugfs_fops = {
+ .open = l2cap_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *l2cap_debugfs;
static const struct proto_ops l2cap_sock_ops = {
.family = PF_BLUETOOTH,
@@ -4019,8 +4043,12 @@ static int __init l2cap_init(void)
goto error;
}
- if (class_create_file(bt_class, &class_attr_l2cap) < 0)
- BT_ERR("Failed to create L2CAP info file");
+ if (bt_debugfs) {
+ l2cap_debugfs = debugfs_create_file("l2cap", 0444,
+ bt_debugfs, NULL, &l2cap_debugfs_fops);
+ if (!l2cap_debugfs)
+ BT_ERR("Failed to create L2CAP debug file");
+ }
BT_INFO("L2CAP ver %s", VERSION);
BT_INFO("L2CAP socket layer initialized");
@@ -4034,7 +4062,7 @@ error:
static void __exit l2cap_exit(void)
{
- class_remove_file(bt_class, &class_attr_l2cap);
+ debugfs_remove(l2cap_debugfs);
if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
BT_ERR("L2CAP socket unregistration failed");
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 89f4a59eb82..7dca91bb8c5 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -33,9 +33,12 @@
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
@@ -2098,11 +2101,10 @@ static struct hci_cb rfcomm_cb = {
.security_cfm = rfcomm_security_cfm
};
-static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
+static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
{
struct rfcomm_session *s;
struct list_head *pp, *p;
- char *str = buf;
rfcomm_lock();
@@ -2112,18 +2114,32 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
struct sock *sk = s->sock->sk;
struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
- str += sprintf(str, "%s %s %ld %d %d %d %d\n",
- batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
- d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
+ seq_printf(f, "%s %s %ld %d %d %d %d\n",
+ batostr(&bt_sk(sk)->src),
+ batostr(&bt_sk(sk)->dst),
+ d->state, d->dlci, d->mtu,
+ d->rx_credits, d->tx_credits);
}
}
rfcomm_unlock();
- return (str - buf);
+ return 0;
}
-static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
+static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations rfcomm_dlc_debugfs_fops = {
+ .open = rfcomm_dlc_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *rfcomm_dlc_debugfs;
/* ---- Initialization ---- */
static int __init rfcomm_init(void)
@@ -2140,8 +2156,12 @@ static int __init rfcomm_init(void)
goto unregister;
}
- if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
- BT_ERR("Failed to create RFCOMM info file");
+ if (bt_debugfs) {
+ rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
+ bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops);
+ if (!rfcomm_dlc_debugfs)
+ BT_ERR("Failed to create RFCOMM debug file");
+ }
err = rfcomm_init_ttys();
if (err < 0)
@@ -2169,7 +2189,7 @@ unregister:
static void __exit rfcomm_exit(void)
{
- class_remove_file(bt_class, &class_attr_rfcomm_dlc);
+ debugfs_remove(rfcomm_dlc_debugfs);
hci_unregister_cb(&rfcomm_cb);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 4b5968dda67..8ed3c37684f 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -40,6 +40,8 @@
#include <linux/skbuff.h>
#include <linux/list.h>
#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <net/sock.h>
#include <asm/system.h>
@@ -395,7 +397,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
BT_DBG("sk %p", sk);
- if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
+ if (alen < sizeof(struct sockaddr_rc) ||
+ addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
lock_sock(sk);
@@ -1061,26 +1064,38 @@ done:
return result;
}
-static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf)
+static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
{
struct sock *sk;
struct hlist_node *node;
- char *str = buf;
read_lock_bh(&rfcomm_sk_list.lock);
sk_for_each(sk, node, &rfcomm_sk_list.head) {
- str += sprintf(str, "%s %s %d %d\n",
- batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
+ seq_printf(f, "%s %s %d %d\n",
+ batostr(&bt_sk(sk)->src),
+ batostr(&bt_sk(sk)->dst),
sk->sk_state, rfcomm_pi(sk)->channel);
}
read_unlock_bh(&rfcomm_sk_list.lock);
- return (str - buf);
+ return 0;
}
-static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
+static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rfcomm_sock_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations rfcomm_sock_debugfs_fops = {
+ .open = rfcomm_sock_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *rfcomm_sock_debugfs;
static const struct proto_ops rfcomm_sock_ops = {
.family = PF_BLUETOOTH,
@@ -1120,8 +1135,12 @@ int __init rfcomm_init_sockets(void)
if (err < 0)
goto error;
- if (class_create_file(bt_class, &class_attr_rfcomm) < 0)
- BT_ERR("Failed to create RFCOMM info file");
+ if (bt_debugfs) {
+ rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
+ bt_debugfs, NULL, &rfcomm_sock_debugfs_fops);
+ if (!rfcomm_sock_debugfs)
+ BT_ERR("Failed to create RFCOMM debug file");
+ }
BT_INFO("RFCOMM socket layer initialized");
@@ -1135,7 +1154,7 @@ error:
void rfcomm_cleanup_sockets(void)
{
- class_remove_file(bt_class, &class_attr_rfcomm);
+ debugfs_remove(rfcomm_sock_debugfs);
if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
BT_ERR("RFCOMM socket layer unregistration failed");
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index dd8f6ec57dc..ca6b2ad1c3f 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -38,6 +38,8 @@
#include <linux/socket.h>
#include <linux/skbuff.h>
#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <linux/list.h>
#include <net/sock.h>
@@ -497,7 +499,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
BT_DBG("sk %p", sk);
- if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
+ if (alen < sizeof(struct sockaddr_sco) ||
+ addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
@@ -953,26 +956,36 @@ drop:
return 0;
}
-static ssize_t sco_sysfs_show(struct class *dev, char *buf)
+static int sco_debugfs_show(struct seq_file *f, void *p)
{
struct sock *sk;
struct hlist_node *node;
- char *str = buf;
read_lock_bh(&sco_sk_list.lock);
sk_for_each(sk, node, &sco_sk_list.head) {
- str += sprintf(str, "%s %s %d\n",
- batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
- sk->sk_state);
+ seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
+ batostr(&bt_sk(sk)->dst), sk->sk_state);
}
read_unlock_bh(&sco_sk_list.lock);
- return (str - buf);
+ return 0;
}
-static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
+static int sco_debugfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, sco_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations sco_debugfs_fops = {
+ .open = sco_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *sco_debugfs;
static const struct proto_ops sco_sock_ops = {
.family = PF_BLUETOOTH,
@@ -1030,8 +1043,12 @@ static int __init sco_init(void)
goto error;
}
- if (class_create_file(bt_class, &class_attr_sco) < 0)
- BT_ERR("Failed to create SCO info file");
+ if (bt_debugfs) {
+ sco_debugfs = debugfs_create_file("sco", 0444,
+ bt_debugfs, NULL, &sco_debugfs_fops);
+ if (!sco_debugfs)
+ BT_ERR("Failed to create SCO debug file");
+ }
BT_INFO("SCO (Voice Link) ver %s", VERSION);
BT_INFO("SCO socket layer initialized");
@@ -1045,7 +1062,7 @@ error:
static void __exit sco_exit(void)
{
- class_remove_file(bt_class, &class_attr_sco);
+ debugfs_remove(sco_debugfs);
if (bt_sock_unregister(BTPROTO_SCO) < 0)
BT_ERR("SCO socket unregistration failed");
diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig
index 19a6b9629c5..d115d5cea5b 100644
--- a/net/bridge/Kconfig
+++ b/net/bridge/Kconfig
@@ -35,6 +35,7 @@ config BRIDGE
config BRIDGE_IGMP_SNOOPING
bool "IGMP snooping"
depends on BRIDGE
+ depends on INET
default y
---help---
If you say Y here, then the Ethernet bridge will be able selectively
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index eb7062d2e9e..90a9024e5c1 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -40,7 +40,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
mdst = br_mdb_get(br, skb);
- if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only)
+ if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb))
br_multicast_deliver(mdst, skb);
else
br_flood_deliver(br, skb);
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 3b8e038ab32..9101a4e5620 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -20,6 +20,7 @@
#include <linux/etherdevice.h>
#include <linux/jhash.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include "br_private.h"
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index d61e6f74112..7a241c39698 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -12,6 +12,7 @@
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
@@ -19,6 +20,11 @@
#include <linux/netfilter_bridge.h>
#include "br_private.h"
+static int deliver_clone(const struct net_bridge_port *prev,
+ struct sk_buff *skb,
+ void (*__packet_hook)(const struct net_bridge_port *p,
+ struct sk_buff *skb));
+
/* Don't forward packets to originating port or forwarding diasabled */
static inline int should_deliver(const struct net_bridge_port *p,
const struct sk_buff *skb)
@@ -94,17 +100,22 @@ void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
}
/* called with rcu_read_lock */
-void br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
+void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0)
{
if (should_deliver(to, skb)) {
- __br_forward(to, skb);
+ if (skb0)
+ deliver_clone(to, skb, __br_forward);
+ else
+ __br_forward(to, skb);
return;
}
- kfree_skb(skb);
+ if (!skb0)
+ kfree_skb(skb);
}
-static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb,
+static int deliver_clone(const struct net_bridge_port *prev,
+ struct sk_buff *skb,
void (*__packet_hook)(const struct net_bridge_port *p,
struct sk_buff *skb))
{
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index b6a3872f568..0b6b1f2ff7a 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/if_ether.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include "br_private.h"
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 53b39851d87..a82dde2d2ea 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -11,6 +11,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -70,7 +71,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
if (is_multicast_ether_addr(dest)) {
mdst = br_mdb_get(br, skb);
- if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) {
+ if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
if ((mdst && !hlist_unhashed(&mdst->mglist)) ||
br_multicast_is_router(br))
skb2 = skb;
@@ -90,7 +91,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
if (skb) {
if (dst)
- br_forward(dst->dst, skb);
+ br_forward(dst->dst, skb, skb2);
else
br_flood_forward(br, skb, skb2);
}
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index 2af6e4a9026..995afc4b04d 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/if_bridge.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <linux/times.h>
#include <net/net_namespace.h>
#include <asm/uaccess.h>
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 2559fb53983..eaa0e1bae49 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -38,7 +38,7 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
struct net_bridge_mdb_entry *mp;
struct hlist_node *p;
- hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
+ hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
if (dst == mp->addr)
return mp;
}
@@ -49,22 +49,23 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
static struct net_bridge_mdb_entry *br_mdb_ip_get(
struct net_bridge_mdb_htable *mdb, __be32 dst)
{
+ if (!mdb)
+ return NULL;
+
return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst));
}
struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
struct sk_buff *skb)
{
- struct net_bridge_mdb_htable *mdb = br->mdb;
-
- if (!mdb || br->multicast_disabled)
+ if (br->multicast_disabled)
return NULL;
switch (skb->protocol) {
case htons(ETH_P_IP):
if (BR_INPUT_SKB_CB(skb)->igmp)
break;
- return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr);
+ return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr);
}
return NULL;
@@ -627,8 +628,8 @@ static void br_multicast_port_query_expired(unsigned long data)
struct net_bridge *br = port->br;
spin_lock(&br->multicast_lock);
- if (port && (port->state == BR_STATE_DISABLED ||
- port->state == BR_STATE_BLOCKING))
+ if (port->state == BR_STATE_DISABLED ||
+ port->state == BR_STATE_BLOCKING)
goto out;
if (port->multicast_startup_queries_sent <
@@ -722,11 +723,11 @@ static int br_multicast_igmp3_report(struct net_bridge *br,
if (!pskb_may_pull(skb, len))
return -EINVAL;
- grec = (void *)(skb->data + len);
+ grec = (void *)(skb->data + len - sizeof(*grec));
group = grec->grec_mca;
type = grec->grec_type;
- len += grec->grec_nsrcs * 4;
+ len += ntohs(grec->grec_nsrcs) * 4;
if (!pskb_may_pull(skb, len))
return -EINVAL;
@@ -823,6 +824,7 @@ static int br_multicast_query(struct net_bridge *br,
unsigned long max_delay;
unsigned long now = jiffies;
__be32 group;
+ int err = 0;
spin_lock(&br->multicast_lock);
if (!netif_running(br->dev) ||
@@ -841,15 +843,17 @@ static int br_multicast_query(struct net_bridge *br,
group = 0;
}
} else {
- if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
- return -EINVAL;
+ if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) {
+ err = -EINVAL;
+ goto out;
+ }
ih3 = igmpv3_query_hdr(skb);
if (ih3->nsrcs)
- return 0;
+ goto out;
- max_delay = ih3->code ? 1 :
- IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE);
+ max_delay = ih3->code ?
+ IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
}
if (!group)
@@ -876,7 +880,7 @@ static int br_multicast_query(struct net_bridge *br,
out:
spin_unlock(&br->multicast_lock);
- return 0;
+ return err;
}
static void br_multicast_leave_group(struct net_bridge *br,
@@ -953,9 +957,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
unsigned offset;
int err;
- BR_INPUT_SKB_CB(skb)->igmp = 0;
- BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
-
/* We treat OOM as packet loss for now. */
if (!pskb_may_pull(skb, sizeof(*iph)))
return -EINVAL;
@@ -987,7 +988,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
err = pskb_trim_rcsum(skb2, len);
if (err)
- return err;
+ goto err_out;
}
len -= ip_hdrlen(skb2);
@@ -1009,7 +1010,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
case CHECKSUM_NONE:
skb2->csum = 0;
if (skb_checksum_complete(skb2))
- return -EINVAL;
+ goto out;
}
err = 0;
@@ -1036,6 +1037,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
out:
__skb_push(skb2, offset);
+err_out:
if (skb2 != skb)
kfree_skb(skb2);
return err;
@@ -1044,6 +1046,9 @@ out:
int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
struct sk_buff *skb)
{
+ BR_INPUT_SKB_CB(skb)->igmp = 0;
+ BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
+
if (br->multicast_disabled)
return 0;
@@ -1135,7 +1140,7 @@ void br_multicast_stop(struct net_bridge *br)
if (mdb->old) {
spin_unlock_bh(&br->multicast_lock);
- synchronize_rcu_bh();
+ rcu_barrier_bh();
spin_lock_bh(&br->multicast_lock);
WARN_ON(mdb->old);
}
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 268e2e72588..4c4977d12fd 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/ip.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index fcffb3fb117..aa56ac2c882 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -11,6 +11,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <net/rtnetlink.h>
#include <net/net_namespace.h>
#include <net/sock.h>
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 1cf2cef7858..846d7d1e207 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -206,12 +206,20 @@ struct net_bridge
struct br_input_skb_cb {
struct net_device *brdev;
+#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
int igmp;
int mrouters_only;
+#endif
};
#define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb)
+#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
+# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (BR_INPUT_SKB_CB(__skb)->mrouters_only)
+#else
+# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (0)
+#endif
+
extern struct notifier_block br_device_notifier;
extern const u8 br_group_address[ETH_ALEN];
@@ -252,7 +260,7 @@ extern void br_deliver(const struct net_bridge_port *to,
struct sk_buff *skb);
extern int br_dev_queue_push_xmit(struct sk_buff *skb);
extern void br_forward(const struct net_bridge_port *to,
- struct sk_buff *skb);
+ struct sk_buff *skb, struct sk_buff *skb0);
extern int br_forward_finish(struct sk_buff *skb);
extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb);
extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
@@ -423,7 +431,7 @@ extern void br_ifinfo_notify(int event, struct net_bridge_port *port);
#ifdef CONFIG_SYSFS
/* br_sysfs_if.c */
-extern struct sysfs_ops brport_sysfs_ops;
+extern const struct sysfs_ops brport_sysfs_ops;
extern int br_sysfs_addif(struct net_bridge_port *p);
/* br_sysfs_br.c */
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 81ae40b3f65..d66cce11f3b 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -15,6 +15,7 @@
#include <linux/netfilter_bridge.h>
#include <linux/etherdevice.h>
#include <linux/llc.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/llc.h>
#include <net/llc_pdu.h>
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index 696596cd338..0b9916489d6 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -238,7 +238,7 @@ static ssize_t brport_store(struct kobject * kobj,
return ret;
}
-struct sysfs_ops brport_sysfs_ops = {
+const struct sysfs_ops brport_sysfs_ops = {
.show = brport_show,
.store = brport_store,
};
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index c6ac657074a..f9560f3dbdc 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -29,6 +29,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index dfb58056a89..f0865fd1e3e 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -23,6 +23,7 @@
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/smp.h>
#include <linux/cpumask.h>
diff --git a/net/can/bcm.c b/net/can/bcm.c
index e32af52238a..907dc871fac 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -56,6 +56,7 @@
#include <linux/can.h>
#include <linux/can/core.h>
#include <linux/can/bcm.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/net_namespace.h>
@@ -1478,6 +1479,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
struct sock *sk = sock->sk;
struct bcm_sock *bo = bcm_sk(sk);
+ if (len < sizeof(*addr))
+ return -EINVAL;
+
if (bo->bound)
return -EISCONN;
diff --git a/net/can/raw.c b/net/can/raw.c
index abca920440b..da99cf153b3 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -45,6 +45,7 @@
#include <linux/init.h>
#include <linux/uio.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/socket.h>
#include <linux/if_arp.h>
@@ -444,7 +445,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
return -EFAULT;
}
} else if (count == 1) {
- if (copy_from_user(&sfilter, optval, optlen))
+ if (copy_from_user(&sfilter, optval, sizeof(sfilter)))
return -EFAULT;
}
diff --git a/net/compat.c b/net/compat.c
index a1fb1b079a8..ec24d9edb02 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -12,6 +12,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/file.h>
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 95c2e0840d0..2dccd4ee591 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -48,6 +48,7 @@
#include <linux/poll.h>
#include <linux/highmem.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <net/protocol.h>
#include <linux/skbuff.h>
diff --git a/net/core/dev.c b/net/core/dev.c
index bcc490cc945..f769098774b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -80,6 +80,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/hash.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/mutex.h>
#include <linux/string.h>
@@ -1988,8 +1989,12 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
if (dev->real_num_tx_queues > 1)
queue_index = skb_tx_hash(dev, skb);
- if (sk && sk->sk_dst_cache)
- sk_tx_queue_set(sk, queue_index);
+ if (sk) {
+ struct dst_entry *dst = rcu_dereference_bh(sk->sk_dst_cache);
+
+ if (dst && skb_dst(skb) == dst)
+ sk_tx_queue_set(sk, queue_index);
+ }
}
}
@@ -2483,6 +2488,7 @@ int netif_receive_skb(struct sk_buff *skb)
{
struct packet_type *ptype, *pt_prev;
struct net_device *orig_dev;
+ struct net_device *master;
struct net_device *null_or_orig;
struct net_device *null_or_bond;
int ret = NET_RX_DROP;
@@ -2503,11 +2509,12 @@ int netif_receive_skb(struct sk_buff *skb)
null_or_orig = NULL;
orig_dev = skb->dev;
- if (orig_dev->master) {
- if (skb_bond_should_drop(skb))
+ master = ACCESS_ONCE(orig_dev->master);
+ if (master) {
+ if (skb_bond_should_drop(skb, master))
null_or_orig = orig_dev; /* deliver only exact match */
else
- skb->dev = orig_dev->master;
+ skb->dev = master;
}
__get_cpu_var(netdev_rx_stat).total++;
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index fd91569e239..3dc295beb48 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -97,8 +97,9 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
netif_addr_lock_bh(dev);
if (alen != dev->addr_len)
- return -EINVAL;
- err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
+ err = -EINVAL;
+ else
+ err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
if (!err)
__dev_set_rx_mode(dev);
netif_addr_unlock_bh(dev);
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index f8c87497535..cf208d8042b 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -21,6 +21,7 @@
#include <linux/percpu.h>
#include <linux/timer.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <net/genetlink.h>
#include <net/netevent.h>
diff --git a/net/core/dst.c b/net/core/dst.c
index cb1b3488b73..f307bc18f6a 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -12,6 +12,7 @@
#include <linux/workqueue.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/string.h>
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 0f2f82185ec..9d55c57f318 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -17,6 +17,8 @@
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
/*
@@ -199,10 +201,7 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
return dev->ethtool_ops->set_settings(dev, &cmd);
}
-/*
- * noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
- */
-static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
+static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
{
struct ethtool_drvinfo info;
const struct ethtool_ops *ops = dev->ethtool_ops;
@@ -214,6 +213,10 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use
info.cmd = ETHTOOL_GDRVINFO;
ops->get_drvinfo(dev, &info);
+ /*
+ * this method of obtaining string set info is deprecated;
+ * Use ETHTOOL_GSSET_INFO instead.
+ */
if (ops->get_sset_count) {
int rc;
@@ -237,10 +240,67 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use
return 0;
}
-/*
- * noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
- */
-static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
+static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev,
+ void __user *useraddr)
+{
+ struct ethtool_sset_info info;
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+ u64 sset_mask;
+ int i, idx = 0, n_bits = 0, ret, rc;
+ u32 *info_buf = NULL;
+
+ if (!ops->get_sset_count)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&info, useraddr, sizeof(info)))
+ return -EFAULT;
+
+ /* store copy of mask, because we zero struct later on */
+ sset_mask = info.sset_mask;
+ if (!sset_mask)
+ return 0;
+
+ /* calculate size of return buffer */
+ n_bits = hweight64(sset_mask);
+
+ memset(&info, 0, sizeof(info));
+ info.cmd = ETHTOOL_GSSET_INFO;
+
+ info_buf = kzalloc(n_bits * sizeof(u32), GFP_USER);
+ if (!info_buf)
+ return -ENOMEM;
+
+ /*
+ * fill return buffer based on input bitmask and successful
+ * get_sset_count return
+ */
+ for (i = 0; i < 64; i++) {
+ if (!(sset_mask & (1ULL << i)))
+ continue;
+
+ rc = ops->get_sset_count(dev, i);
+ if (rc >= 0) {
+ info.sset_mask |= (1ULL << i);
+ info_buf[idx++] = rc;
+ }
+ }
+
+ ret = -EFAULT;
+ if (copy_to_user(useraddr, &info, sizeof(info)))
+ goto out;
+
+ useraddr += offsetof(struct ethtool_sset_info, data);
+ if (copy_to_user(useraddr, info_buf, idx * sizeof(u32)))
+ goto out;
+
+ ret = 0;
+
+out:
+ kfree(info_buf);
+ return ret;
+}
+
+static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr)
{
struct ethtool_rxnfc cmd;
@@ -253,10 +313,7 @@ static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *usera
return dev->ethtool_ops->set_rxnfc(dev, &cmd);
}
-/*
- * noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
- */
-static noinline int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
+static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr)
{
struct ethtool_rxnfc info;
const struct ethtool_ops *ops = dev->ethtool_ops;
@@ -328,10 +385,7 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
list->count++;
}
-/*
- * noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
- */
-static noinline int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
+static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
{
struct ethtool_rx_ntuple cmd;
const struct ethtool_ops *ops = dev->ethtool_ops;
@@ -799,10 +853,7 @@ static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
return ret;
}
-/*
- * noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
- */
-static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr)
+static noinline_for_stack int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr)
{
struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
@@ -816,10 +867,7 @@ static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *us
return 0;
}
-/*
- * noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
- */
-static noinline int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
+static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr)
{
struct ethtool_coalesce coalesce;
@@ -1229,10 +1277,7 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
return actor(dev, edata.data);
}
-/*
- * noinline attribute so that gcc doesnt use too much stack in dev_ethtool()
- */
-static noinline int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
+static noinline_for_stack int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
{
struct ethtool_flash efl;
@@ -1471,6 +1516,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GRXNTUPLE:
rc = ethtool_get_rx_ntuple(dev, useraddr);
break;
+ case ETHTOOL_GSSET_INFO:
+ rc = ethtool_get_sset_info(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 9a24377146b..d2c3e7dc2e5 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <net/net_namespace.h>
#include <net/sock.h>
diff --git a/net/core/filter.c b/net/core/filter.c
index d38ef7fd50f..ff943bed21a 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -25,6 +25,7 @@
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/if_packet.h>
+#include <linux/gfp.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/netlink.h>
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 493775f4f2f..cf8e70392fe 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -32,6 +32,7 @@
#include <linux/rtnetlink.h>
#include <linux/init.h>
#include <linux/rbtree.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/gen_stats.h>
diff --git a/net/core/iovec.c b/net/core/iovec.c
index 16ad45d4882..1e7f4e91a93 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -20,7 +20,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/net.h>
#include <linux/in6.h>
#include <asm/uaccess.h>
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index 5910b555a54..bdbce2f5875 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -19,7 +19,6 @@
#include <linux/rtnetlink.h>
#include <linux/jiffies.h>
#include <linux/spinlock.h>
-#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
#include <asm/types.h>
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d102f6d9abd..bff37908bd5 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -15,6 +15,7 @@
* Harald Welte Add neighbour cache statistics like rtstat
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -771,6 +772,8 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
}
static void neigh_invalidate(struct neighbour *neigh)
+ __releases(neigh->lock)
+ __acquires(neigh->lock)
{
struct sk_buff *skb;
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 099c753c421..59cfc7d8fc4 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/rtnetlink.h>
#include <linux/wireless.h>
diff --git a/net/core/net-traces.c b/net/core/net-traces.c
index f1e982c508b..afa6380ed88 100644
--- a/net/core/net-traces.c
+++ b/net/core/net-traces.c
@@ -19,6 +19,7 @@
#include <linux/workqueue.h>
#include <linux/netlink.h>
#include <linux/net_dropmon.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include <asm/bitops.h>
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 7aa69725376..a58f59b9759 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/rcupdate.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <asm/unaligned.h>
@@ -614,7 +615,7 @@ void netpoll_print_options(struct netpoll *np)
np->name, np->local_port);
printk(KERN_INFO "%s: local IP %pI4\n",
np->name, &np->local_ip);
- printk(KERN_INFO "%s: interface %s\n",
+ printk(KERN_INFO "%s: interface '%s'\n",
np->name, np->dev_name);
printk(KERN_INFO "%s: remote port %d\n",
np->name, np->remote_port);
@@ -661,6 +662,9 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
if ((delim = strchr(cur, '@')) == NULL)
goto parse_failed;
*delim = 0;
+ if (*cur == ' ' || *cur == '\t')
+ printk(KERN_INFO "%s: warning: whitespace"
+ "is not allowed\n", np->name);
np->remote_port = simple_strtol(cur, NULL, 10);
cur = delim;
}
@@ -708,7 +712,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
return 0;
parse_failed:
- printk(KERN_INFO "%s: couldn't parse config at %s!\n",
+ printk(KERN_INFO "%s: couldn't parse config at '%s'!\n",
np->name, cur);
return -1;
}
@@ -735,7 +739,7 @@ int netpoll_setup(struct netpoll *np)
npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
if (!npinfo) {
err = -ENOMEM;
- goto release;
+ goto put;
}
npinfo->rx_flags = 0;
@@ -845,7 +849,7 @@ int netpoll_setup(struct netpoll *np)
kfree(npinfo);
}
-
+put:
dev_put(ndev);
return err;
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4568120d853..fe776c9ddec 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1270,10 +1270,11 @@ replay:
err = ops->newlink(net, dev, tb, data);
else
err = register_netdevice(dev);
- if (err < 0 && !IS_ERR(dev)) {
+
+ if (err < 0 && !IS_ERR(dev))
free_netdev(dev);
+ if (err < 0)
goto out;
- }
err = rtnl_configure_link(dev, ifm);
if (err < 0)
diff --git a/net/core/scm.c b/net/core/scm.c
index 9b264634acf..b88f6f9d0b9 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -26,6 +26,7 @@
#include <linux/security.h>
#include <linux/pid.h>
#include <linux/nsproxy.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/net/core/sock.c b/net/core/sock.c
index fcd397a762f..c5812bbc2cc 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -340,8 +340,12 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
rc = sk_backlog_rcv(sk, skb);
mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
- } else
- sk_add_backlog(sk, skb);
+ } else if (sk_add_backlog(sk, skb)) {
+ bh_unlock_sock(sk);
+ atomic_inc(&sk->sk_drops);
+ goto discard_and_relse;
+ }
+
bh_unlock_sock(sk);
out:
sock_put(sk);
@@ -1139,6 +1143,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
sock_lock_init(newsk);
bh_lock_sock(newsk);
newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
+ newsk->sk_backlog.len = 0;
atomic_set(&newsk->sk_rmem_alloc, 0);
/*
@@ -1542,6 +1547,12 @@ static void __release_sock(struct sock *sk)
bh_lock_sock(sk);
} while ((skb = sk->sk_backlog.head) != NULL);
+
+ /*
+ * Doing the zeroing here guarantee we can not loop forever
+ * while a wild producer attempts to flood us.
+ */
+ sk->sk_backlog.len = 0;
}
/**
@@ -1874,6 +1885,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_allocation = GFP_KERNEL;
sk->sk_rcvbuf = sysctl_rmem_default;
sk->sk_sndbuf = sysctl_wmem_default;
+ sk->sk_backlog.limit = sk->sk_rcvbuf << 1;
sk->sk_state = TCP_CLOSE;
sk_set_socket(sk, sock);
@@ -2276,7 +2288,8 @@ out_free_request_sock_slab:
prot->rsk_prot->slab = NULL;
}
out_free_request_sock_slab_name:
- kfree(prot->rsk_prot->slab_name);
+ if (prot->rsk_prot)
+ kfree(prot->rsk_prot->slab_name);
out_free_sock_slab:
kmem_cache_destroy(prot->slab);
prot->slab = NULL;
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 06124872af5..b7b6b8208f7 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <linux/ratelimit.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/sock.h>
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 813e399220a..19ac2b98548 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -19,6 +19,7 @@
#include <linux/netdevice.h>
#include <linux/netlink.h>
+#include <linux/slab.h>
#include <net/netlink.h>
#include <net/rtnetlink.h>
#include <linux/dcbnl.h>
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index 49d27c556be..36479ca61e0 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -11,6 +11,8 @@
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
+
#include "ccid.h"
#include "ccids/lib/tfrc.h"
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index a47a8c918ee..9b3ae9922be 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -23,6 +23,7 @@
/*
* This implementation should follow RFC 4341
*/
+#include <linux/slab.h>
#include "../feat.h"
#include "../ccid.h"
#include "../dccp.h"
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 972b8dc918d..df7dd26cf07 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -22,6 +22,7 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include "ccid.h"
#include "feat.h"
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 7648f316310..9ec71742602 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -12,6 +12,7 @@
#include <linux/dccp.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index b195c4feaa0..52ffa1cde15 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -12,6 +12,7 @@
#include <linux/dccp.h>
#include <linux/icmp.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/random.h>
@@ -998,11 +999,11 @@ static struct inet_protosw dccp_v4_protosw = {
static int __net_init dccp_v4_init_net(struct net *net)
{
- int err;
+ if (dccp_hashinfo.bhash == NULL)
+ return -ESOCKTNOSUPPORT;
- err = inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET,
- SOCK_DCCP, IPPROTO_DCCP, net);
- return err;
+ return inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET,
+ SOCK_DCCP, IPPROTO_DCCP, net);
}
static void __net_exit dccp_v4_exit_net(struct net *net)
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 1aec6349e85..3b11e41a292 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/xfrm.h>
#include <net/addrconf.h>
@@ -1191,11 +1192,11 @@ static struct inet_protosw dccp_v6_protosw = {
static int __net_init dccp_v6_init_net(struct net *net)
{
- int err;
+ if (dccp_hashinfo.bhash == NULL)
+ return -ESOCKTNOSUPPORT;
- err = inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6,
- SOCK_DCCP, IPPROTO_DCCP, net);
- return err;
+ return inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6,
+ SOCK_DCCP, IPPROTO_DCCP, net);
}
static void __net_exit dccp_v6_exit_net(struct net *net)
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index af226a06314..128b089d3ae 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -11,6 +11,7 @@
*/
#include <linux/dccp.h>
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/timer.h>
@@ -254,7 +255,7 @@ int dccp_child_process(struct sock *parent, struct sock *child,
* in main socket hash table and lock on listening
* socket does not protect us more.
*/
- sk_add_backlog(child, skb);
+ __sk_add_backlog(child, skb);
}
bh_unlock_sock(child);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index d6bb753bf6a..fc3f436440b 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -13,6 +13,7 @@
#include <linux/dccp.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/inet_sock.h>
#include <net/sock.h>
diff --git a/net/dccp/probe.c b/net/dccp/probe.c
index f5b3464f124..078e48d442f 100644
--- a/net/dccp/probe.c
+++ b/net/dccp/probe.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/kfifo.h>
#include <linux/vmalloc.h>
+#include <linux/gfp.h>
#include <net/net_namespace.h>
#include "dccp.h"
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 0ef7061920c..a0e38d8018f 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -20,6 +20,7 @@
#include <linux/if_arp.h>
#include <linux/init.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/inet_sock.h>
@@ -1036,7 +1037,7 @@ static int __init dccp_init(void)
FIELD_SIZEOF(struct sk_buff, cb));
rc = percpu_counter_init(&dccp_orphan_count, 0);
if (rc)
- goto out;
+ goto out_fail;
rc = -ENOBUFS;
inet_hashinfo_init(&dccp_hashinfo);
dccp_hashinfo.bind_bucket_cachep =
@@ -1125,8 +1126,9 @@ static int __init dccp_init(void)
goto out_sysctl_exit;
dccp_timestamping_init();
-out:
- return rc;
+
+ return 0;
+
out_sysctl_exit:
dccp_sysctl_exit();
out_ackvec_exit:
@@ -1135,18 +1137,19 @@ out_free_dccp_mib:
dccp_mib_exit();
out_free_dccp_bhash:
free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
- dccp_hashinfo.bhash = NULL;
out_free_dccp_locks:
inet_ehash_locks_free(&dccp_hashinfo);
out_free_dccp_ehash:
free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
- dccp_hashinfo.ehash = NULL;
out_free_bind_bucket_cachep:
kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
- dccp_hashinfo.bind_bucket_cachep = NULL;
out_free_percpu:
percpu_counter_destroy(&dccp_orphan_count);
- goto out;
+out_fail:
+ dccp_hashinfo.bhash = NULL;
+ dccp_hashinfo.ehash = NULL;
+ dccp_hashinfo.bind_bucket_cachep = NULL;
+ return rc;
}
static void __exit dccp_fini(void)
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 238af093495..cead68eb254 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -40,6 +40,7 @@
#include <linux/skbuff.h>
#include <linux/sysctl.h>
#include <linux/notifier.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <net/net_namespace.h>
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index e9d48700e83..4ab96c15166 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -20,6 +20,7 @@
#include <linux/string.h>
#include <linux/net.h>
#include <linux/socket.h>
+#include <linux/slab.h>
#include <linux/sockios.h>
#include <linux/init.h>
#include <linux/skbuff.h>
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 794b5bf95af..deb723dba44 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
index 932408dca86..25a37299bc6 100644
--- a/net/decnet/dn_nsp_in.c
+++ b/net/decnet/dn_nsp_in.c
@@ -57,6 +57,7 @@
#include <linux/netdevice.h>
#include <linux/inet.h>
#include <linux/route.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/system.h>
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index a65e929ce76..baeb1eaf011 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -50,6 +50,7 @@
#include <linux/netdevice.h>
#include <linux/inet.h>
#include <linux/route.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <asm/system.h>
#include <linux/fcntl.h>
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index a7bf03ca0a3..70ebe74027d 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -66,6 +66,7 @@
#include <linux/inet.h>
#include <linux/route.h>
#include <linux/in_route.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index b9a33bb5e9c..f2abd375569 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/net.h>
#include <linux/socket.h>
+#include <linux/slab.h>
#include <linux/sockios.h>
#include <linux/init.h>
#include <linux/skbuff.h>
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index 6d2bd320204..64a7f39e069 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -14,6 +14,7 @@
*/
#include <linux/module.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 71489f69a42..6112a12578b 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -11,6 +11,7 @@
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <net/dsa.h>
#include "dsa_priv.h"
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index cdf2d28a029..98dfe80b453 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -11,6 +11,7 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include "dsa_priv.h"
#define DSA_HLEN 4
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
index 8f53948cff4..6f383322ad2 100644
--- a/net/dsa/tag_edsa.c
+++ b/net/dsa/tag_edsa.c
@@ -11,6 +11,7 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include "dsa_priv.h"
#define DSA_HLEN 4
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
index a85c829853c..d6d7d0add3c 100644
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -11,6 +11,7 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include "dsa_priv.h"
netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev)
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 29b4931aae5..2a5a8053e00 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -30,6 +30,7 @@
#include <linux/wireless.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/inet_common.h>
#include <linux/stat.h>
diff --git a/net/ethernet/pe2.c b/net/ethernet/pe2.c
index d60e15d9365..eb00796758c 100644
--- a/net/ethernet/pe2.c
+++ b/net/ethernet/pe2.c
@@ -3,6 +3,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/datalink.h>
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
index bad1c49fd96..93c91b633a5 100644
--- a/net/ieee802154/af_ieee802154.c
+++ b/net/ieee802154/af_ieee802154.c
@@ -28,6 +28,7 @@
#include <linux/if.h>
#include <linux/termios.h> /* For TIOCOUTQ/INQ */
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/datalink.h>
#include <net/psnap.h>
#include <net/sock.h>
@@ -126,6 +127,9 @@ static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
{
struct sock *sk = sock->sk;
+ if (addr_len < sizeof(uaddr->sa_family))
+ return -EINVAL;
+
if (uaddr->sa_family == AF_UNSPEC)
return sk->sk_prot->disconnect(sk, flags);
@@ -147,6 +151,9 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
dev_load(sock_net(sk), ifr.ifr_name);
dev = dev_get_by_name(sock_net(sk), ifr.ifr_name);
+ if (!dev)
+ return -ENODEV;
+
if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl)
ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd);
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
index 9aac5aee157..1a3334c2609 100644
--- a/net/ieee802154/dgram.c
+++ b/net/ieee802154/dgram.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/if_arp.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_ieee802154.h>
#include <net/ieee802154.h>
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 33137b99e47..c8097ae2482 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -23,6 +23,7 @@
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <net/genetlink.h>
#include <linux/nl802154.h>
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index 135c1678fb1..71ee1108d4f 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -22,6 +22,7 @@
* Maxim Osipov <maxim.osipov@siemens.com>
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 199a2d9d12f..ed0eab39f53 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -23,6 +23,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <net/netlink.h>
#include <net/genetlink.h>
#include <net/wpan-phy.h>
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c
index 9c9b85c0003..10970ca8574 100644
--- a/net/ieee802154/raw.c
+++ b/net/ieee802154/raw.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/if_arp.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_ieee802154.h>
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 268691256a6..3d803a1b9fb 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -16,6 +16,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 33b7dffa773..f7135742238 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -86,6 +86,7 @@
#include <linux/poll.h>
#include <linux/netfilter_ipv4.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -530,6 +531,8 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
{
struct sock *sk = sock->sk;
+ if (addr_len < sizeof(uaddr->sa_family))
+ return -EINVAL;
if (uaddr->sa_family == AF_UNSPEC)
return sk->sk_prot->disconnect(sk, flags);
@@ -573,6 +576,9 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int err;
long timeo;
+ if (addr_len < sizeof(uaddr->sa_family))
+ return -EINVAL;
+
lock_sock(sk);
if (uaddr->sa_family == AF_UNSPEC) {
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 987b47dc69a..880a5ec6dce 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -1,6 +1,7 @@
#include <crypto/hash.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/ah.h>
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index c4dd1354280..6e747065c20 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -98,6 +98,7 @@
#include <linux/net.h>
#include <linux/rcupdate.h>
#include <linux/jhash.h>
+#include <linux/slab.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 1e029dc7545..c97cd9ff697 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -44,6 +44,7 @@
#include <linux/string.h>
#include <linux/jhash.h>
#include <linux/audit.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/tcp.h>
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 51ca946e339..90e3d6379a4 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -50,6 +50,7 @@
#include <linux/notifier.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
+#include <linux/slab.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
@@ -1194,7 +1195,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
if (idx < s_idx)
goto cont;
- if (idx > s_idx)
+ if (h > s_h || idx > s_idx)
s_ip_idx = 0;
in_dev = __in_dev_get_rcu(dev);
if (!in_dev)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 9b3e28ed524..4f0ed458c88 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -34,6 +34,7 @@
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/protocol.h>
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 14972017b9c..4ed7e0dea1b 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -32,6 +32,7 @@
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/ip.h>
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 1af0ea0fb6a..20f09c5b31e 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -32,6 +32,7 @@
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/arp.h>
#include <net/ip.h>
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index af5d8979286..c98f115fb0f 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -71,6 +71,7 @@
#include <linux/netlink.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/ip.h>
#include <net/protocol.h>
@@ -208,7 +209,9 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i)
{
struct node *ret = tnode_get_child(tn, i);
- return rcu_dereference(ret);
+ return rcu_dereference_check(ret,
+ rcu_read_lock_held() ||
+ lockdep_rtnl_is_held());
}
static inline int tnode_child_length(const struct tnode *tn)
@@ -961,7 +964,9 @@ fib_find_node(struct trie *t, u32 key)
struct node *n;
pos = 0;
- n = rcu_dereference(t->trie);
+ n = rcu_dereference_check(t->trie,
+ rcu_read_lock_held() ||
+ lockdep_rtnl_is_held());
while (n != NULL && NODE_TYPE(n) == T_TNODE) {
tn = (struct tnode *) n;
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 4b4c2bcd15d..ac4dec13273 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -74,6 +74,7 @@
#include <linux/netdevice.h>
#include <linux/string.h>
#include <linux/netfilter_ipv4.h>
+#include <linux/slab.h>
#include <net/snmp.h>
#include <net/ip.h>
#include <net/route.h>
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 63bf298ca10..15d3eeda92f 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -71,6 +71,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/types.h>
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 1aaa8110d84..e5fa2ddce32 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/cache.h>
#include <linux/init.h>
#include <linux/time.h>
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index eaf3e2c8646..a2ca6aed763 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -19,6 +19,7 @@
#include <linux/random.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <net/inet_frag.h>
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index cc94cc2d8b2..c5af909cf70 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/kmemcheck.h>
+#include <linux/slab.h>
#include <net/inet_hashtables.h>
#include <net/inet_timewait_sock.h>
#include <net/ip.h>
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index a2991bc8e32..af10942b326 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -25,6 +25,7 @@
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/tcp.h>
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index b59430bc041..75347ea70ea 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -32,6 +32,7 @@
#include <linux/netdevice.h>
#include <linux/jhash.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <net/route.h>
#include <net/dst.h>
#include <net/sock.h>
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index c0c5274d027..fe381d12ecd 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
@@ -810,11 +811,13 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
tunnel->err_count = 0;
}
- max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
+ max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + rt->u.dst.header_len;
if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
(skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
+ if (max_headroom > dev->needed_headroom)
+ dev->needed_headroom = max_headroom;
if (!new_skb) {
ip_rt_put(rt);
txq->tx_dropped++;
@@ -1144,12 +1147,9 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
if (saddr)
memcpy(&iph->saddr, saddr, 4);
-
- if (daddr) {
+ if (daddr)
memcpy(&iph->daddr, daddr, 4);
- return t->hlen;
- }
- if (iph->daddr && !ipv4_is_multicast(iph->daddr))
+ if (iph->daddr)
return t->hlen;
return -t->hlen;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index c29de9879fd..f8ab7a380d4 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -119,6 +119,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/net.h>
#include <linux/socket.h>
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 94bf105ef3c..4c09a31fd14 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -11,6 +11,7 @@
#include <linux/capability.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <linux/skbuff.h>
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3451799e3db..d1bcc9f21d4 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -51,6 +51,7 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/highmem.h>
+#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/sockios.h>
@@ -119,7 +120,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
newskb->pkt_type = PACKET_LOOPBACK;
newskb->ip_summed = CHECKSUM_UNNECESSARY;
WARN_ON(!skb_dst(newskb));
- netif_rx(newskb);
+ netif_rx_ni(newskb);
return 0;
}
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 644dc43a55d..1e64dabbd23 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -23,6 +23,7 @@
#include <linux/icmp.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/icmp.h>
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 10a6a604bf3..067ce9e043d 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -53,6 +53,7 @@
#include <linux/root_dev.h>
#include <linux/delay.h>
#include <linux/nfs_fs.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/arp.h>
#include <net/ip.h>
@@ -187,6 +188,16 @@ struct ic_device {
static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
static struct net_device *ic_dev __initdata = NULL; /* Selected device */
+static bool __init ic_device_match(struct net_device *dev)
+{
+ if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
+ (!(dev->flags & IFF_LOOPBACK) &&
+ (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
+ strncmp(dev->name, "dummy", 5)))
+ return true;
+ return false;
+}
+
static int __init ic_open_devs(void)
{
struct ic_device *d, **last;
@@ -207,10 +218,7 @@ static int __init ic_open_devs(void)
for_each_netdev(&init_net, dev) {
if (dev->flags & IFF_LOOPBACK)
continue;
- if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
- (!(dev->flags & IFF_LOOPBACK) &&
- (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
- strncmp(dev->name, "dummy", 5))) {
+ if (ic_device_match(dev)) {
int able = 0;
if (dev->mtu >= 364)
able |= IC_BOOTP;
@@ -228,7 +236,7 @@ static int __init ic_open_devs(void)
}
if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
rtnl_unlock();
- return -1;
+ return -ENOMEM;
}
d->dev = dev;
*last = d;
@@ -253,7 +261,7 @@ static int __init ic_open_devs(void)
printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
else
printk(KERN_ERR "IP-Config: No network devices available.\n");
- return -1;
+ return -ENODEV;
}
return 0;
}
@@ -1303,6 +1311,32 @@ __be32 __init root_nfs_parse_addr(char *name)
return addr;
}
+#define DEVICE_WAIT_MAX 12 /* 12 seconds */
+
+static int __init wait_for_devices(void)
+{
+ int i;
+
+ msleep(CONF_PRE_OPEN);
+ for (i = 0; i < DEVICE_WAIT_MAX; i++) {
+ struct net_device *dev;
+ int found = 0;
+
+ rtnl_lock();
+ for_each_netdev(&init_net, dev) {
+ if (ic_device_match(dev)) {
+ found = 1;
+ break;
+ }
+ }
+ rtnl_unlock();
+ if (found)
+ return 0;
+ ssleep(1);
+ }
+ return -ENODEV;
+}
+
/*
* IP Autoconfig dispatcher.
*/
@@ -1313,6 +1347,7 @@ static int __init ip_auto_config(void)
#ifdef IPCONFIG_DYNAMIC
int retries = CONF_OPEN_RETRIES;
#endif
+ int err;
#ifdef CONFIG_PROC_FS
proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops);
@@ -1325,12 +1360,15 @@ static int __init ip_auto_config(void)
#ifdef IPCONFIG_DYNAMIC
try_try_again:
#endif
- /* Give hardware a chance to settle */
- msleep(CONF_PRE_OPEN);
+ /* Wait for devices to appear */
+ err = wait_for_devices();
+ if (err)
+ return err;
/* Setup all network devices */
- if (ic_open_devs() < 0)
- return -1;
+ err = ic_open_devs();
+ if (err)
+ return err;
/* Give drivers a chance to settle */
ssleep(CONF_POST_OPEN);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 2f302d3ac9a..0b27b14dcc9 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -95,6 +95,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 8582e12e4a6..9d4f6d1340a 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -47,6 +47,7 @@
#include <linux/mroute.h>
#include <linux/init.h>
#include <linux/if_ether.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/ip.h>
#include <net/protocol.h>
@@ -802,6 +803,9 @@ static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock)
int line;
struct mfc_cache *uc, *c, **cp;
+ if (mfc->mfcc_parent >= MAXVIFS)
+ return -ENFILE;
+
line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
for (cp = &net->ipv4.mfc_cache_array[line];
@@ -1613,17 +1617,20 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm)
int ct;
struct rtnexthop *nhp;
struct net *net = mfc_net(c);
- struct net_device *dev = net->ipv4.vif_table[c->mfc_parent].dev;
u8 *b = skb_tail_pointer(skb);
struct rtattr *mp_head;
- if (dev)
- RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex);
+ /* If cache is unresolved, don't try to parse IIF and OIF */
+ if (c->mfc_parent > MAXVIFS)
+ return -ENOENT;
+
+ if (VIF_EXISTS(net, c->mfc_parent))
+ RTA_PUT(skb, RTA_IIF, 4, &net->ipv4.vif_table[c->mfc_parent].dev->ifindex);
mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0));
for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
- if (c->mfc_un.res.ttls[ct] < 255) {
+ if (VIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) {
if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
goto rtattr_failure;
nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index c14623fc4d5..82fb43c5c59 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -4,6 +4,7 @@
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
+#include <linux/gfp.h>
#include <net/route.h>
#include <net/xfrm.h>
#include <net/ip.h>
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index bfe26f32b93..79ca5e70d49 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_arp/arp_tables.h>
+#include <linux/slab.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 2855f1f38cb..e2787048aa0 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -26,6 +26,7 @@
#include <linux/security.h>
#include <linux/net.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/route.h>
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 0886f96c736..ab828400ed7 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -14,6 +14,7 @@
#include <linux/jhash.h>
#include <linux/bitops.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 5113b8f1a37..a0e8bcf0415 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/icmp.h>
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 09a5d3f7cc4..0dbe697f164 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/socket.h>
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/kernel.h>
#include <linux/timer.h>
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index c8dc9800d62..55392466daa 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/slab.h>
#include <net/ip.h>
MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index b9b83464cbf..294a2a32f29 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -12,6 +12,7 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/route.h>
#include <linux/ip.h>
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 06fb9d11953..07fb710cd72 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -5,6 +5,7 @@
*/
#include <linux/module.h>
#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/slab.h>
#include <net/ip.h>
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
index cce2f64e6f2..be45bdc4c60 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -17,6 +17,7 @@
*/
#include <linux/module.h>
#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/slab.h>
#include <net/ip.h>
MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 4595281c286..4f8bddb760c 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/skbuff.h>
+#include <linux/gfp.h>
#include <net/checksum.h>
#include <net/icmp.h>
#include <net/ip.h>
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 4b6af4bb1f5..4a0c6b548ee 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/kmod.h>
#include <linux/types.h>
#include <linux/timer.h>
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index ab74cc0535e..26de2c1f7fa 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -15,6 +15,7 @@
#include <linux/kmod.h>
#include <linux/skbuff.h>
#include <linux/proc_fs.h>
+#include <linux/slab.h>
#include <net/checksum.h>
#include <net/route.h>
#include <linux/bitops.h>
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 0b9c7ce3d6c..4d85b6e55f2 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -43,6 +43,7 @@
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/udp.h>
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 5678e9562c1..c39c9cf6bee 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -7,6 +7,7 @@
*/
#include <linux/types.h>
#include <linux/icmp.h>
+#include <linux/gfp.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 242ed230737..4f1f337f433 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -249,6 +249,8 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TCPSackShifted", LINUX_MIB_SACKSHIFTED),
SNMP_MIB_ITEM("TCPSackMerged", LINUX_MIB_SACKMERGED),
SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK),
+ SNMP_MIB_ITEM("TCPBacklogDrop", LINUX_MIB_TCPBACKLOGDROP),
+ SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index ce154b47f1d..cc6f097fbd5 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -60,7 +60,6 @@
#include <net/net_namespace.h>
#include <net/dst.h>
#include <net/sock.h>
-#include <linux/gfp.h>
#include <linux/ip.h>
#include <linux/net.h>
#include <net/ip.h>
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index b2ba5581d2a..cb562fdd9b9 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -90,6 +90,7 @@
#include <linux/jhash.h>
#include <linux/rcupdate.h>
#include <linux/times.h>
+#include <linux/slab.h>
#include <net/dst.h>
#include <net/net_namespace.h>
#include <net/protocol.h>
@@ -146,7 +147,6 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
static int rt_garbage_collect(struct dst_ops *ops);
-static void rt_emergency_hash_rebuild(struct net *net);
static struct dst_ops ipv4_dst_ops = {
@@ -780,11 +780,30 @@ static void rt_do_flush(int process_context)
#define FRACT_BITS 3
#define ONE (1UL << FRACT_BITS)
+/*
+ * Given a hash chain and an item in this hash chain,
+ * find if a previous entry has the same hash_inputs
+ * (but differs on tos, mark or oif)
+ * Returns 0 if an alias is found.
+ * Returns ONE if rth has no alias before itself.
+ */
+static int has_noalias(const struct rtable *head, const struct rtable *rth)
+{
+ const struct rtable *aux = head;
+
+ while (aux != rth) {
+ if (compare_hash_inputs(&aux->fl, &rth->fl))
+ return 0;
+ aux = aux->u.dst.rt_next;
+ }
+ return ONE;
+}
+
static void rt_check_expire(void)
{
static unsigned int rover;
unsigned int i = rover, goal;
- struct rtable *rth, *aux, **rthp;
+ struct rtable *rth, **rthp;
unsigned long samples = 0;
unsigned long sum = 0, sum2 = 0;
unsigned long delta;
@@ -835,15 +854,7 @@ nofree:
* attributes don't unfairly skew
* the length computation
*/
- for (aux = rt_hash_table[i].chain;;) {
- if (aux == rth) {
- length += ONE;
- break;
- }
- if (compare_hash_inputs(&aux->fl, &rth->fl))
- break;
- aux = aux->u.dst.rt_next;
- }
+ length += has_noalias(rt_hash_table[i].chain, rth);
continue;
}
} else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
@@ -922,10 +933,8 @@ static void rt_secret_rebuild_oneshot(struct net *net)
{
del_timer_sync(&net->ipv4.rt_secret_timer);
rt_cache_invalidate(net);
- if (ip_rt_secret_interval) {
- net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval;
- add_timer(&net->ipv4.rt_secret_timer);
- }
+ if (ip_rt_secret_interval)
+ mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval);
}
static void rt_emergency_hash_rebuild(struct net *net)
@@ -1073,8 +1082,23 @@ work_done:
out: return 0;
}
+/*
+ * Returns number of entries in a hash chain that have different hash_inputs
+ */
+static int slow_chain_length(const struct rtable *head)
+{
+ int length = 0;
+ const struct rtable *rth = head;
+
+ while (rth) {
+ length += has_noalias(head, rth);
+ rth = rth->u.dst.rt_next;
+ }
+ return length >> FRACT_BITS;
+}
+
static int rt_intern_hash(unsigned hash, struct rtable *rt,
- struct rtable **rp, struct sk_buff *skb)
+ struct rtable **rp, struct sk_buff *skb, int ifindex)
{
struct rtable *rth, **rthp;
unsigned long now;
@@ -1185,14 +1209,20 @@ restart:
rt_free(cand);
}
} else {
- if (chain_length > rt_chain_length_max) {
+ if (chain_length > rt_chain_length_max &&
+ slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) {
struct net *net = dev_net(rt->u.dst.dev);
int num = ++net->ipv4.current_rt_cache_rebuild_count;
- if (!rt_caching(dev_net(rt->u.dst.dev))) {
+ if (!rt_caching(net)) {
printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n",
rt->u.dst.dev->name, num);
}
- rt_emergency_hash_rebuild(dev_net(rt->u.dst.dev));
+ rt_emergency_hash_rebuild(net);
+ spin_unlock_bh(rt_hash_lock_addr(hash));
+
+ hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
+ ifindex, rt_genid(net));
+ goto restart;
}
}
@@ -1417,7 +1447,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
dev_hold(rt->u.dst.dev);
if (rt->idev)
in_dev_hold(rt->idev);
- rt->u.dst.obsolete = 0;
+ rt->u.dst.obsolete = -1;
rt->u.dst.lastuse = jiffies;
rt->u.dst.path = &rt->u.dst;
rt->u.dst.neighbour = NULL;
@@ -1453,7 +1483,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
&netevent);
rt_del(hash, rth);
- if (!rt_intern_hash(hash, rt, &rt, NULL))
+ if (!rt_intern_hash(hash, rt, &rt, NULL, rt->fl.oif))
ip_rt_put(rt);
goto do_next;
}
@@ -1482,11 +1512,12 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
struct dst_entry *ret = dst;
if (rt) {
- if (dst->obsolete) {
+ if (dst->obsolete > 0) {
ip_rt_put(rt);
ret = NULL;
} else if ((rt->rt_flags & RTCF_REDIRECTED) ||
- rt->u.dst.expires) {
+ (rt->u.dst.expires &&
+ time_after_eq(jiffies, rt->u.dst.expires))) {
unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
rt->fl.oif,
rt_genid(dev_net(dst->dev)));
@@ -1702,7 +1733,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
{
- return NULL;
+ if (rt_is_expired((struct rtable *)dst))
+ return NULL;
+ return dst;
}
static void ipv4_dst_destroy(struct dst_entry *dst)
@@ -1864,7 +1897,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
if (!rth)
goto e_nobufs;
- rth->u.dst.output= ip_rt_bug;
+ rth->u.dst.output = ip_rt_bug;
+ rth->u.dst.obsolete = -1;
atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
@@ -1903,7 +1937,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
in_dev_put(in_dev);
hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
- return rt_intern_hash(hash, rth, NULL, skb);
+ return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex);
e_nobufs:
in_dev_put(in_dev);
@@ -2030,6 +2064,7 @@ static int __mkroute_input(struct sk_buff *skb,
rth->fl.oif = 0;
rth->rt_spec_dst= spec_dst;
+ rth->u.dst.obsolete = -1;
rth->u.dst.input = ip_forward;
rth->u.dst.output = ip_output;
rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev));
@@ -2069,7 +2104,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
/* put it into the cache */
hash = rt_hash(daddr, saddr, fl->iif,
rt_genid(dev_net(rth->u.dst.dev)));
- return rt_intern_hash(hash, rth, NULL, skb);
+ return rt_intern_hash(hash, rth, NULL, skb, fl->iif);
}
/*
@@ -2194,6 +2229,7 @@ local_input:
goto e_nobufs;
rth->u.dst.output= ip_rt_bug;
+ rth->u.dst.obsolete = -1;
rth->rt_genid = rt_genid(net);
atomic_set(&rth->u.dst.__refcnt, 1);
@@ -2225,7 +2261,7 @@ local_input:
}
rth->rt_type = res.type;
hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
- err = rt_intern_hash(hash, rth, NULL, skb);
+ err = rt_intern_hash(hash, rth, NULL, skb, fl.iif);
goto done;
no_route:
@@ -2420,6 +2456,7 @@ static int __mkroute_output(struct rtable **result,
rth->rt_spec_dst= fl->fl4_src;
rth->u.dst.output=ip_output;
+ rth->u.dst.obsolete = -1;
rth->rt_genid = rt_genid(dev_net(dev_out));
RT_CACHE_STAT_INC(out_slow_tot);
@@ -2471,7 +2508,7 @@ static int ip_mkroute_output(struct rtable **rp,
if (err == 0) {
hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
rt_genid(dev_net(dev_out)));
- err = rt_intern_hash(hash, rth, rp, NULL);
+ err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif);
}
return err;
@@ -3077,22 +3114,20 @@ static void rt_secret_reschedule(int old)
rtnl_lock();
for_each_net(net) {
int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
+ long time;
if (!new)
continue;
if (deleted) {
- long time = net->ipv4.rt_secret_timer.expires - jiffies;
+ time = net->ipv4.rt_secret_timer.expires - jiffies;
if (time <= 0 || (time += diff) <= 0)
time = 0;
-
- net->ipv4.rt_secret_timer.expires = time;
} else
- net->ipv4.rt_secret_timer.expires = new;
+ time = new;
- net->ipv4.rt_secret_timer.expires += jiffies;
- add_timer(&net->ipv4.rt_secret_timer);
+ mod_timer(&net->ipv4.rt_secret_timer, jiffies + time);
}
rtnl_unlock();
}
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index c1bc074f61b..1cd5c15174b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -12,6 +12,7 @@
#include <linux/inetdevice.h>
#include <linux/seqlock.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/snmp.h>
#include <net/icmp.h>
#include <net/ip.h>
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5901010fad5..0f8caf64caa 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -265,6 +265,7 @@
#include <linux/err.h>
#include <linux/crypto.h>
#include <linux/time.h>
+#include <linux/slab.h>
#include <net/icmp.h>
#include <net/tcp.h>
@@ -429,7 +430,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
if (tp->urg_seq == tp->copied_seq &&
!sock_flag(sk, SOCK_URGINLINE) &&
tp->urg_data)
- target--;
+ target++;
/* Potential race condition. If read of tp below will
* escape above sk->sk_state, we can be illegally awaken
@@ -1254,6 +1255,39 @@ static void tcp_prequeue_process(struct sock *sk)
tp->ucopy.memory = 0;
}
+#ifdef CONFIG_NET_DMA
+static void tcp_service_net_dma(struct sock *sk, bool wait)
+{
+ dma_cookie_t done, used;
+ dma_cookie_t last_issued;
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ if (!tp->ucopy.dma_chan)
+ return;
+
+ last_issued = tp->ucopy.dma_cookie;
+ dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+
+ do {
+ if (dma_async_memcpy_complete(tp->ucopy.dma_chan,
+ last_issued, &done,
+ &used) == DMA_SUCCESS) {
+ /* Safe to free early-copied skbs now */
+ __skb_queue_purge(&sk->sk_async_wait_queue);
+ break;
+ } else {
+ struct sk_buff *skb;
+ while ((skb = skb_peek(&sk->sk_async_wait_queue)) &&
+ (dma_async_is_complete(skb->dma_cookie, done,
+ used) == DMA_SUCCESS)) {
+ __skb_dequeue(&sk->sk_async_wait_queue);
+ kfree_skb(skb);
+ }
+ }
+ } while (wait);
+}
+#endif
+
static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
{
struct sk_buff *skb;
@@ -1335,6 +1369,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
sk_eat_skb(sk, skb, 0);
if (!desc->count)
break;
+ tp->copied_seq = seq;
}
tp->copied_seq = seq;
@@ -1546,6 +1581,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
/* __ Set realtime policy in scheduler __ */
}
+#ifdef CONFIG_NET_DMA
+ if (tp->ucopy.dma_chan)
+ dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+#endif
if (copied >= target) {
/* Do not sleep, just process backlog. */
release_sock(sk);
@@ -1554,6 +1593,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
sk_wait_data(sk, &timeo);
#ifdef CONFIG_NET_DMA
+ tcp_service_net_dma(sk, false); /* Don't block */
tp->ucopy.wakeup = 0;
#endif
@@ -1633,6 +1673,9 @@ do_prequeue:
copied = -EFAULT;
break;
}
+
+ dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+
if ((offset + used) == skb->len)
copied_early = 1;
@@ -1702,27 +1745,9 @@ skip_copy:
}
#ifdef CONFIG_NET_DMA
- if (tp->ucopy.dma_chan) {
- dma_cookie_t done, used;
-
- dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
-
- while (dma_async_memcpy_complete(tp->ucopy.dma_chan,
- tp->ucopy.dma_cookie, &done,
- &used) == DMA_IN_PROGRESS) {
- /* do partial cleanup of sk_async_wait_queue */
- while ((skb = skb_peek(&sk->sk_async_wait_queue)) &&
- (dma_async_is_complete(skb->dma_cookie, done,
- used) == DMA_SUCCESS)) {
- __skb_dequeue(&sk->sk_async_wait_queue);
- kfree_skb(skb);
- }
- }
+ tcp_service_net_dma(sk, true); /* Wait for queue to drain */
+ tp->ucopy.dma_chan = NULL;
- /* Safe to free early-copied skbs now */
- __skb_queue_purge(&sk->sk_async_wait_queue);
- tp->ucopy.dma_chan = NULL;
- }
if (tp->ucopy.pinned_list) {
dma_unpin_iovec_pages(tp->ucopy.pinned_list);
tp->ucopy.pinned_list = NULL;
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 6428b342b16..0ec9bd0ae94 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -10,6 +10,7 @@
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/list.h>
+#include <linux/gfp.h>
#include <net/tcp.h>
int sysctl_tcp_max_ssthresh = 0;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 788851ca8c5..f240f57b219 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -62,6 +62,7 @@
*/
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/sysctl.h>
#include <linux/kernel.h>
@@ -2511,6 +2512,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
int err;
unsigned int mss;
+ if (packets == 0)
+ return;
+
WARN_ON(packets > tp->packets_out);
if (tp->lost_skb_hint) {
skb = tp->lost_skb_hint;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index c3588b4fd97..3c23e70885f 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -60,6 +60,7 @@
#include <linux/jhash.h>
#include <linux/init.h>
#include <linux/times.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/icmp.h>
@@ -370,6 +371,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
if (sk->sk_state == TCP_CLOSE)
goto out;
+ if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
+ NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
+ goto out;
+ }
+
icsk = inet_csk(sk);
tp = tcp_sk(sk);
seq = ntohl(th->seq);
@@ -1651,13 +1657,15 @@ int tcp_v4_rcv(struct sk_buff *skb)
if (!sk)
goto no_tcp_socket;
- if (iph->ttl < inet_sk(sk)->min_ttl)
- goto discard_and_relse;
-
process:
if (sk->sk_state == TCP_TIME_WAIT)
goto do_time_wait;
+ if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
+ NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
+ goto discard_and_relse;
+ }
+
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_and_relse;
nf_reset(skb);
@@ -1682,8 +1690,11 @@ process:
if (!tcp_prequeue(sk, skb))
ret = tcp_v4_do_rcv(sk, skb);
}
- } else
- sk_add_backlog(sk, skb);
+ } else if (unlikely(sk_add_backlog(sk, skb))) {
+ bh_unlock_sock(sk);
+ NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
+ goto discard_and_relse;
+ }
bh_unlock_sock(sk);
sock_put(sk);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index f206ee5dda8..5fabff9ac6d 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -20,6 +20,7 @@
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/workqueue.h>
#include <net/tcp.h>
@@ -728,7 +729,7 @@ int tcp_child_process(struct sock *parent, struct sock *child,
* in main socket hash table and lock on listening
* socket does not protect us more.
*/
- sk_add_backlog(child, skb);
+ __sk_add_backlog(child, skb);
}
bh_unlock_sock(child);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 4a1605d3f90..0dda86e72ad 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -37,6 +37,7 @@
#include <net/tcp.h>
#include <linux/compiler.h>
+#include <linux/gfp.h>
#include <linux/module.h>
/* People can turn this off for buggy TCP's found in printers etc. */
@@ -2395,13 +2396,17 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
struct tcp_extend_values *xvp = tcp_xv(rvp);
struct inet_request_sock *ireq = inet_rsk(req);
struct tcp_sock *tp = tcp_sk(sk);
+ const struct tcp_cookie_values *cvp = tp->cookie_values;
struct tcphdr *th;
struct sk_buff *skb;
struct tcp_md5sig_key *md5;
int tcp_header_size;
int mss;
+ int s_data_desired = 0;
- skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
+ if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired)
+ s_data_desired = cvp->s_data_desired;
+ skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC);
if (skb == NULL)
return NULL;
@@ -2457,16 +2462,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
if (OPTION_COOKIE_EXTENSION & opts.options) {
- const struct tcp_cookie_values *cvp = tp->cookie_values;
-
- if (cvp != NULL &&
- cvp->s_data_constant &&
- cvp->s_data_desired > 0) {
- u8 *buf = skb_put(skb, cvp->s_data_desired);
+ if (s_data_desired) {
+ u8 *buf = skb_put(skb, s_data_desired);
/* copy data directly from the listening socket. */
- memcpy(buf, cvp->s_data_payload, cvp->s_data_desired);
- TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired;
+ memcpy(buf, cvp->s_data_payload, s_data_desired);
+ TCP_SKB_CB(skb)->end_seq += s_data_desired;
}
if (opts.hash_size > 0) {
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index 9bc805df95d..f8efada580e 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -22,6 +22,7 @@
#include <linux/kprobes.h>
#include <linux/socket.h>
#include <linux/tcp.h>
+#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/ktime.h>
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index a17629b8912..8a0ab2977f1 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -19,6 +19,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <net/tcp.h>
int sysctl_tcp_syn_retries __read_mostly = TCP_SYN_RETRIES;
@@ -134,7 +135,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
}
/* This function calculates a "timeout" which is equivalent to the timeout of a
- * TCP connection after "boundary" unsucessful, exponentially backed-off
+ * TCP connection after "boundary" unsuccessful, exponentially backed-off
* retransmissions with an initial RTO of TCP_RTO_MIN.
*/
static bool retransmits_timed_out(struct sock *sk,
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c
index 3959e0ca456..3b3813cc80b 100644
--- a/net/ipv4/tunnel4.c
+++ b/net/ipv4/tunnel4.c
@@ -8,6 +8,7 @@
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/icmp.h>
#include <net/ip.h>
#include <net/protocol.h>
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 608a5446d05..8fef859db35 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -95,6 +95,7 @@
#include <linux/mm.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <net/tcp_states.h>
#include <linux/skbuff.h>
#include <linux/proc_fs.h>
@@ -471,8 +472,8 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
if (hslot->count < hslot2->count)
goto begin;
- result = udp4_lib_lookup2(net, INADDR_ANY, sport,
- daddr, hnum, dif,
+ result = udp4_lib_lookup2(net, saddr, sport,
+ INADDR_ANY, hnum, dif,
hslot2, slot2);
}
rcu_read_unlock();
@@ -1371,8 +1372,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
rc = __udp_queue_rcv_skb(sk, skb);
- else
- sk_add_backlog(sk, skb);
+ else if (sk_add_backlog(sk, skb)) {
+ bh_unlock_sock(sk);
+ goto drop;
+ }
bh_unlock_sock(sk);
return rc;
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index f9f922a0ba8..c791bb63203 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -9,6 +9,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/netfilter.h>
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 3444f3b34ec..6f368413eb0 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -4,6 +4,7 @@
* Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 67107d63c1c..e4a1483fba7 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -91,11 +91,12 @@ static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
return 0;
}
-static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+ struct flowi *fl)
{
struct rtable *rt = (struct rtable *)xdst->route;
- xdst->u.rt.fl = rt->fl;
+ xdst->u.rt.fl = *fl;
xdst->u.dst.dev = dev;
dev_hold(dev);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 88fd8c5877e..413054f02aa 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -53,6 +53,7 @@
#include <linux/route.h>
#include <linux/inetdevice.h>
#include <linux/init.h>
+#include <linux/slab.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
@@ -1380,6 +1381,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
if (dad_failed)
ifp->flags |= IFA_F_DADFAILED;
spin_unlock_bh(&ifp->lock);
+ if (dad_failed)
+ ipv6_ifa_notify(0, ifp);
in6_ifa_put(ifp);
#ifdef CONFIG_IPV6_PRIVACY
} else if (ifp->flags&IFA_F_TEMPORARY) {
@@ -2615,7 +2618,7 @@ static void addrconf_bonding_change(struct net_device *dev, unsigned long event)
static int addrconf_ifdown(struct net_device *dev, int how)
{
struct inet6_dev *idev;
- struct inet6_ifaddr *ifa, **bifa;
+ struct inet6_ifaddr *ifa, *keep_list, **bifa;
struct net *net = dev_net(dev);
int i;
@@ -2649,11 +2652,11 @@ static int addrconf_ifdown(struct net_device *dev, int how)
write_lock_bh(&addrconf_hash_lock);
while ((ifa = *bifa) != NULL) {
if (ifa->idev == idev &&
- (how || !(ifa->flags&IFA_F_PERMANENT))) {
+ (how || !(ifa->flags&IFA_F_PERMANENT) ||
+ ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
*bifa = ifa->lst_next;
ifa->lst_next = NULL;
- addrconf_del_timer(ifa);
- in6_ifa_put(ifa);
+ __in6_ifa_put(ifa);
continue;
}
bifa = &ifa->lst_next;
@@ -2689,31 +2692,51 @@ static int addrconf_ifdown(struct net_device *dev, int how)
write_lock_bh(&idev->lock);
}
#endif
- bifa = &idev->addr_list;
- while ((ifa = *bifa) != NULL) {
- if (how == 0 && (ifa->flags&IFA_F_PERMANENT)) {
- /* Retain permanent address on admin down */
+ keep_list = NULL;
+ bifa = &keep_list;
+ while ((ifa = idev->addr_list) != NULL) {
+ idev->addr_list = ifa->if_next;
+ ifa->if_next = NULL;
+
+ addrconf_del_timer(ifa);
+
+ /* If just doing link down, and address is permanent
+ and not link-local, then retain it. */
+ if (how == 0 &&
+ (ifa->flags&IFA_F_PERMANENT) &&
+ !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
+
+ /* Move to holding list */
+ *bifa = ifa;
bifa = &ifa->if_next;
- /* Restart DAD if needed when link comes back up */
- if ( !((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
- idev->cnf.accept_dad <= 0 ||
- (ifa->flags & IFA_F_NODAD)))
- ifa->flags |= IFA_F_TENTATIVE;
- } else {
- *bifa = ifa->if_next;
- ifa->if_next = NULL;
+ /* If not doing DAD on this address, just keep it. */
+ if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
+ idev->cnf.accept_dad <= 0 ||
+ (ifa->flags & IFA_F_NODAD))
+ continue;
+ /* If it was tentative already, no need to notify */
+ if (ifa->flags & IFA_F_TENTATIVE)
+ continue;
+
+ /* Flag it for later restoration when link comes up */
+ ifa->flags |= IFA_F_TENTATIVE;
+ in6_ifa_hold(ifa);
+ } else {
ifa->dead = 1;
- write_unlock_bh(&idev->lock);
+ }
+ write_unlock_bh(&idev->lock);
- __ipv6_ifa_notify(RTM_DELADDR, ifa);
- atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
- in6_ifa_put(ifa);
+ __ipv6_ifa_notify(RTM_DELADDR, ifa);
+ atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
+ in6_ifa_put(ifa);
- write_lock_bh(&idev->lock);
- }
+ write_lock_bh(&idev->lock);
}
+
+ idev->addr_list = keep_list;
+
write_unlock_bh(&idev->lock);
/* Step 5: Discard multicast list */
@@ -2739,28 +2762,29 @@ static int addrconf_ifdown(struct net_device *dev, int how)
static void addrconf_rs_timer(unsigned long data)
{
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
+ struct inet6_dev *idev = ifp->idev;
- if (ifp->idev->cnf.forwarding)
+ read_lock(&idev->lock);
+ if (idev->dead || !(idev->if_flags & IF_READY))
goto out;
- if (ifp->idev->if_flags & IF_RA_RCVD) {
- /*
- * Announcement received after solicitation
- * was sent
- */
+ if (idev->cnf.forwarding)
+ goto out;
+
+ /* Announcement received after solicitation was sent */
+ if (idev->if_flags & IF_RA_RCVD)
goto out;
- }
spin_lock(&ifp->lock);
- if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) {
+ if (ifp->probes++ < idev->cnf.rtr_solicits) {
/* The wait after the last probe can be shorter */
addrconf_mod_timer(ifp, AC_RS,
- (ifp->probes == ifp->idev->cnf.rtr_solicits) ?
- ifp->idev->cnf.rtr_solicit_delay :
- ifp->idev->cnf.rtr_solicit_interval);
+ (ifp->probes == idev->cnf.rtr_solicits) ?
+ idev->cnf.rtr_solicit_delay :
+ idev->cnf.rtr_solicit_interval);
spin_unlock(&ifp->lock);
- ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
+ ndisc_send_rs(idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
} else {
spin_unlock(&ifp->lock);
/*
@@ -2768,10 +2792,11 @@ static void addrconf_rs_timer(unsigned long data)
* assumption any longer.
*/
printk(KERN_DEBUG "%s: no IPv6 routers present\n",
- ifp->idev->dev->name);
+ idev->dev->name);
}
out:
+ read_unlock(&idev->lock);
in6_ifa_put(ifp);
}
@@ -2850,9 +2875,9 @@ static void addrconf_dad_timer(unsigned long data)
struct inet6_dev *idev = ifp->idev;
struct in6_addr mcaddr;
- read_lock_bh(&idev->lock);
- if (idev->dead) {
- read_unlock_bh(&idev->lock);
+ read_lock(&idev->lock);
+ if (idev->dead || !(idev->if_flags & IF_READY)) {
+ read_unlock(&idev->lock);
goto out;
}
@@ -2864,7 +2889,7 @@ static void addrconf_dad_timer(unsigned long data)
ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
spin_unlock(&ifp->lock);
- read_unlock_bh(&idev->lock);
+ read_unlock(&idev->lock);
addrconf_dad_completed(ifp);
@@ -2874,7 +2899,7 @@ static void addrconf_dad_timer(unsigned long data)
ifp->probes--;
addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
spin_unlock(&ifp->lock);
- read_unlock_bh(&idev->lock);
+ read_unlock(&idev->lock);
/* send a neighbour solicitation for our addr */
addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
@@ -3586,7 +3611,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
if (idx < s_idx)
goto cont;
- if (idx > s_idx)
+ if (h > s_h || idx > s_idx)
s_ip_idx = 0;
ip_idx = 0;
if ((idev = __in6_dev_get(dev)) == NULL)
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 6ff73c4c126..ae404c9a746 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -13,6 +13,7 @@
#include <linux/list.h>
#include <linux/rcupdate.h>
#include <linux/in6.h>
+#include <linux/slab.h>
#include <net/addrconf.h>
#include <linux/if_addrlabel.h>
#include <linux/netlink.h>
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 37d14e735c2..3192aa02ba5 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -36,6 +36,7 @@
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 5ac89025f9d..ee82d4ef26c 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -26,6 +26,7 @@
#include <crypto/hash.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/ah.h>
#include <linux/crypto.h>
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index c4f6ca32fa7..b5b07054508 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -29,6 +29,7 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/sock.h>
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index e6f9cdf780f..622dc7939a1 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -21,6 +21,7 @@
#include <linux/in6.h>
#include <linux/ipv6.h>
#include <linux/route.h>
+#include <linux/slab.h>
#include <net/ipv6.h>
#include <net/ndisc.h>
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 074f2c084f9..8a659f92d17 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -29,6 +29,7 @@
#include <linux/netdevice.h>
#include <linux/in6.h>
#include <linux/icmpv6.h>
+#include <linux/slab.h>
#include <net/dst.h>
#include <net/sock.h>
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 551882b9dfd..5e463c43fcc 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
if ((rule->flags & FIB_RULE_FIND_SADDR) &&
r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
struct in6_addr saddr;
- unsigned int srcprefs = 0;
-
- if (flags & RT6_LOOKUP_F_SRCPREF_TMP)
- srcprefs |= IPV6_PREFER_SRC_TMP;
- if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC)
- srcprefs |= IPV6_PREFER_SRC_PUBLIC;
- if (flags & RT6_LOOKUP_F_SRCPREF_COA)
- srcprefs |= IPV6_PREFER_SRC_COA;
if (ipv6_dev_get_saddr(net,
ip6_dst_idev(&rt->u.dst)->dev,
- &flp->fl6_dst, srcprefs,
+ &flp->fl6_dst,
+ rt6_flags2srcprefs(flags),
&saddr))
goto again;
if (!ipv6_prefix_equal(&saddr, &r->src.addr,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index eb9abe24bdf..3330a4bd615 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -40,6 +40,7 @@
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/netfilter.h>
+#include <linux/slab.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 3516e6fe2e5..628db24bcf2 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -17,6 +17,7 @@
#include <linux/in6.h>
#include <linux/ipv6.h>
#include <linux/jhash.h>
+#include <linux/slab.h>
#include <net/addrconf.h>
#include <net/inet_connection_sock.h>
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 2f9847924fa..6b82e02158c 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -26,6 +26,7 @@
#include <linux/in6.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/slab.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index e41eba8aacf..14e23216eb2 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -20,6 +20,7 @@
#include <linux/route.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/sock.h>
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index e28f9203dec..6aa7ee1295c 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -28,6 +28,7 @@
#include <linux/in6.h>
#include <linux/icmpv6.h>
#include <linux/mroute6.h>
+#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index dabf108ad81..75d5ef83009 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -37,6 +37,7 @@
#include <linux/tcp.h>
#include <linux/route.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
@@ -107,7 +108,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
newskb->ip_summed = CHECKSUM_UNNECESSARY;
WARN_ON(!skb_dst(newskb));
- netif_rx(newskb);
+ netif_rx_ni(newskb);
return 0;
}
@@ -628,7 +629,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
/* We must not fragment if the socket is set to force MTU discovery
* or if the skb it not generated by a local socket.
*/
- if (!skb->local_df) {
+ if (!skb->local_df && skb->len > mtu) {
skb->dev = skb_dst(skb)->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 138980eec21..2599870747e 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -37,6 +37,7 @@
#include <linux/route.h>
#include <linux/rtnetlink.h>
#include <linux/netfilter_ipv6.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 52e0f74fdfe..3e333268db8 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -33,6 +33,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/protocol.h>
#include <linux/skbuff.h>
#include <net/sock.h>
@@ -1113,6 +1114,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)
unsigned char ttls[MAXMIFS];
int i;
+ if (mfc->mf6cc_parent >= MAXMIFS)
+ return -ENFILE;
+
memset(ttls, 255, MAXMIFS);
for (i = 0; i < MAXMIFS; i++) {
if (IF_ISSET(i, &mfc->mf6cc_ifset))
@@ -1692,17 +1696,20 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm)
int ct;
struct rtnexthop *nhp;
struct net *net = mfc6_net(c);
- struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev;
u8 *b = skb_tail_pointer(skb);
struct rtattr *mp_head;
- if (dev)
- RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex);
+ /* If cache is unresolved, don't try to parse IIF and OIF */
+ if (c->mf6c_parent > MAXMIFS)
+ return -ENOENT;
+
+ if (MIF_EXISTS(net, c->mf6c_parent))
+ RTA_PUT(skb, RTA_IIF, 4, &net->ipv6.vif6_table[c->mf6c_parent].dev->ifindex);
mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0));
for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
- if (c->mfc_un.res.ttls[ct] < 255) {
+ if (MIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) {
if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
goto rtattr_failure;
nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 430454ee5ea..33f60fca7aa 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -36,6 +36,7 @@
#include <linux/init.h>
#include <linux/sysctl.h>
#include <linux/netfilter.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/snmp.h>
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index bcd97191596..c483ab9fd67 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -43,6 +43,7 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 8bcc4b7db3b..da0a4d2adc6 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -59,6 +59,7 @@
#include <linux/route.h>
#include <linux/init.h>
#include <linux/rcupdate.h>
+#include <linux/slab.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 7854052be60..6a68a74d14a 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -25,6 +25,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/ipv6.h>
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index dd8afbaf00a..39b50c3768e 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -15,6 +15,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/icmpv6.h>
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 36b72cafc22..d6fc9aff316 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/slab.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 7844e557c0e..6a102b57f35 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/slab.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index aef31a29de9..5b9926a011b 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -5,6 +5,7 @@
*/
#include <linux/module.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/slab.h>
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
@@ -13,7 +14,7 @@ static const struct xt_table packet_raw = {
.valid_hooks = RAW_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV6,
- .priority = NF_IP6_PRI_FIRST,
+ .priority = NF_IP6_PRI_RAW,
};
/* The work comes in here from netfilter.c. */
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 0824d865aa9..91aa2b4d83c 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -17,6 +17,7 @@
*/
#include <linux/module.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/slab.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>");
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index f1171b74465..dd5b9bd61c6 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -27,6 +27,7 @@
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/snmp.h>
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ed31c37c6e3..8763b1a0814 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
+#include <linux/slab.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/in6.h>
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index a555156e977..6d4292ff585 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -41,6 +41,7 @@
#include <linux/random.h>
#include <linux/jhash.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/snmp.h>
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b08879e97f2..05ebd783304 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -40,6 +40,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/nsproxy.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/snmp.h>
#include <net/ipv6.h>
@@ -814,20 +815,13 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
{
int flags = 0;
- if (rt6_need_strict(&fl->fl6_dst))
+ if (fl->oif || rt6_need_strict(&fl->fl6_dst))
flags |= RT6_LOOKUP_F_IFACE;
if (!ipv6_addr_any(&fl->fl6_src))
flags |= RT6_LOOKUP_F_HAS_SADDR;
- else if (sk) {
- unsigned int prefs = inet6_sk(sk)->srcprefs;
- if (prefs & IPV6_PREFER_SRC_TMP)
- flags |= RT6_LOOKUP_F_SRCPREF_TMP;
- if (prefs & IPV6_PREFER_SRC_PUBLIC)
- flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC;
- if (prefs & IPV6_PREFER_SRC_COA)
- flags |= RT6_LOOKUP_F_SRCPREF_COA;
- }
+ else if (sk)
+ flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
}
@@ -886,7 +880,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
rt = (struct rt6_info *) dst;
- if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
+ if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
return dst;
return NULL;
@@ -897,12 +891,17 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
struct rt6_info *rt = (struct rt6_info *) dst;
if (rt) {
- if (rt->rt6i_flags & RTF_CACHE)
- ip6_del_rt(rt);
- else
+ if (rt->rt6i_flags & RTF_CACHE) {
+ if (rt6_check_expired(rt)) {
+ ip6_del_rt(rt);
+ dst = NULL;
+ }
+ } else {
dst_release(dst);
+ dst = NULL;
+ }
}
- return NULL;
+ return dst;
}
static void ip6_link_failure(struct sk_buff *skb)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b1eea811be4..5abae10cd88 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -28,6 +28,7 @@
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/icmp.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/netfilter_ipv4.h>
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index f841d93bf98..fa1d8f4e005 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -9,6 +9,7 @@
#include <linux/sysctl.h>
#include <linux/in6.h>
#include <linux/ipv6.h>
+#include <linux/slab.h>
#include <net/ndisc.h>
#include <net/ipv6.h>
#include <net/addrconf.h>
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 6963a6b6763..075f540ec19 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -38,6 +38,7 @@
#include <linux/jhash.h>
#include <linux/ipsec.h>
#include <linux/times.h>
+#include <linux/slab.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
@@ -1014,7 +1015,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
t1 = (struct tcphdr *) skb_push(buff, tot_len);
- skb_reset_transport_header(skb);
+ skb_reset_transport_header(buff);
/* Swap the send and the receive. */
memset(t1, 0, sizeof(*t1));
@@ -1740,8 +1741,11 @@ process:
if (!tcp_prequeue(sk, skb))
ret = tcp_v6_do_rcv(sk, skb);
}
- } else
- sk_add_backlog(sk, skb);
+ } else if (unlikely(sk_add_backlog(sk, skb))) {
+ bh_unlock_sock(sk);
+ NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
+ goto discard_and_relse;
+ }
bh_unlock_sock(sk);
sock_put(sk);
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index e17bc1dfc1a..fc3c86a4745 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -25,6 +25,7 @@
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/ipv6.h>
#include <net/protocol.h>
#include <net/xfrm.h>
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 52b8347ae3b..90824852f59 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <net/ndisc.h>
@@ -258,8 +259,8 @@ static struct sock *__udp6_lib_lookup(struct net *net,
if (hslot->count < hslot2->count)
goto begin;
- result = udp6_lib_lookup2(net, &in6addr_any, sport,
- daddr, hnum, dif,
+ result = udp6_lib_lookup2(net, saddr, sport,
+ &in6addr_any, hnum, dif,
hslot2, slot2);
}
rcu_read_unlock();
@@ -583,16 +584,20 @@ static void flush_stack(struct sock **stack, unsigned int count,
bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
udpv6_queue_rcv_skb(sk, skb1);
- else
- sk_add_backlog(sk, skb1);
+ else if (sk_add_backlog(sk, skb1)) {
+ kfree_skb(skb1);
+ bh_unlock_sock(sk);
+ goto drop;
+ }
bh_unlock_sock(sk);
- } else {
- atomic_inc(&sk->sk_drops);
- UDP6_INC_STATS_BH(sock_net(sk),
- UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
- UDP6_INC_STATS_BH(sock_net(sk),
- UDP_MIB_INERRORS, IS_UDPLITE(sk));
+ continue;
}
+drop:
+ atomic_inc(&sk->sk_drops);
+ UDP6_INC_STATS_BH(sock_net(sk),
+ UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
+ UDP6_INC_STATS_BH(sock_net(sk),
+ UDP_MIB_INERRORS, IS_UDPLITE(sk));
}
}
/*
@@ -754,8 +759,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
udpv6_queue_rcv_skb(sk, skb);
- else
- sk_add_backlog(sk, skb);
+ else if (sk_add_backlog(sk, skb)) {
+ atomic_inc(&sk->sk_drops);
+ bh_unlock_sock(sk);
+ sock_put(sk);
+ goto discard;
+ }
bh_unlock_sock(sk);
sock_put(sk);
return 0;
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 3927832227b..b809812c8d3 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -5,6 +5,7 @@
* Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index dbdc696f5fc..00bf7c962b7 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -116,14 +116,15 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
return 0;
}
-static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+ struct flowi *fl)
{
struct rt6_info *rt = (struct rt6_info*)xdst->route;
xdst->u.dst.dev = dev;
dev_hold(dev);
- xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev);
+ xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
if (!xdst->u.rt6.rt6i_idev)
return -ENODEV;
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index fa85a7d22dc..2ce3a8278f2 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -23,6 +23,7 @@
*/
#include <linux/module.h>
#include <linux/xfrm.h>
+#include <linux/slab.h>
#include <linux/rculist.h>
#include <net/ip.h>
#include <net/xfrm.h>
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index f9759b54a6d..da3d21c41d9 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -40,6 +40,7 @@
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/uio.h>
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/smp_lock.h>
#include <linux/socket.h>
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c
index e16c1142352..30f4519b092 100644
--- a/net/ipx/ipx_route.c
+++ b/net/ipx/ipx_route.c
@@ -9,6 +9,7 @@
#include <linux/list.h>
#include <linux/route.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <net/ipx.h>
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 10093aab617..2a4efcea342 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -48,6 +48,7 @@
#include <linux/smp_lock.h>
#include <linux/socket.h>
#include <linux/sockios.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/net.h>
#include <linux/irda.h>
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index a6f99b5a149..c1c8ae93912 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -34,6 +34,7 @@
#include <linux/socket.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <net/irda/irda.h>
#include <net/irda/irlmp.h>
diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
index 018c92941ab..e97082017f4 100644
--- a/net/irda/ircomm/ircomm_core.c
+++ b/net/irda/ircomm/ircomm_core.c
@@ -33,6 +33,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/irda/irda.h>
#include <net/irda/irmod.h>
diff --git a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c
index 7ba96618660..08fb54dc8c4 100644
--- a/net/irda/ircomm/ircomm_lmp.c
+++ b/net/irda/ircomm/ircomm_lmp.c
@@ -31,6 +31,7 @@
********************************************************************/
#include <linux/init.h>
+#include <linux/gfp.h>
#include <net/irda/irda.h>
#include <net/irda/irlmp.h>
diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c
index d57aefd9fe7..e2e893b474e 100644
--- a/net/irda/ircomm/ircomm_param.c
+++ b/net/irda/ircomm/ircomm_param.c
@@ -28,6 +28,7 @@
*
********************************************************************/
+#include <linux/gfp.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 8b85d774e47..faa82ca2dfd 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -33,6 +33,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/termios.h>
diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c
index bf92e147344..25cc2e69515 100644
--- a/net/irda/irda_device.c
+++ b/net/irda/irda_device.c
@@ -41,6 +41,7 @@
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <asm/ioctls.h>
#include <asm/uaccess.h>
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 294e34d3517..79a1e5a23e1 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -31,6 +31,7 @@
#include <linux/string.h>
#include <linux/init.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
diff --git a/net/irda/iriap_event.c b/net/irda/iriap_event.c
index a301cbd9378..703774e29e3 100644
--- a/net/irda/iriap_event.c
+++ b/net/irda/iriap_event.c
@@ -24,6 +24,8 @@
*
********************************************************************/
+#include <linux/slab.h>
+
#include <net/irda/irda.h>
#include <net/irda/irlmp.h>
#include <net/irda/iriap.h>
diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c
index 99ebb96f138..f07ed9fd579 100644
--- a/net/irda/irias_object.c
+++ b/net/irda/irias_object.c
@@ -22,6 +22,7 @@
*
********************************************************************/
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/module.h>
diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
index 42f7d960d05..7ed3af95793 100644
--- a/net/irda/irlan/irlan_client.c
+++ b/net/irda/irlan/irlan_client.c
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netdevice.h>
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index e486dc89ea5..a788f9e9427 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
index 3f81f81b2df..5cf5e6c872b 100644
--- a/net/irda/irlan/irlan_provider.c
+++ b/net/irda/irlan/irlan_provider.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/random.h>
#include <linux/bitops.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/byteorder.h>
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
index 94a9884d714..d434c888074 100644
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/irda/irda.h>
#include <net/irda/irlap_event.h>
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
index 7af2e74deda..688222cbf55 100644
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -29,6 +29,7 @@
#include <linux/if_ether.h>
#include <linux/netdevice.h>
#include <linux/irda.h>
+#include <linux/slab.h>
#include <net/pkt_sched.h>
#include <net/sock.h>
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index b26dee784ab..df18ab4b6c5 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -11,6 +11,7 @@
#include "irnet_irda.h" /* Private header */
#include <linux/sched.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
/*
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index 6b3602de359..6a1a202710c 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -14,6 +14,7 @@
*/
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include "irnet_ppp.h" /* Private header */
/* Please put other headers in irnet.h - Thanks */
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index 69b5b75f543..6c7c4b92e4f 100644
--- a/net/irda/irnetlink.c
+++ b/net/irda/irnetlink.c
@@ -15,6 +15,7 @@
#include <linux/socket.h>
#include <linux/irda.h>
+#include <linux/gfp.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/irda/irda.h>
diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c
index ba01938becb..849aaf0dabb 100644
--- a/net/irda/irqueue.c
+++ b/net/irda/irqueue.c
@@ -192,6 +192,7 @@
* Jean II
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <net/irda/irda.h>
#include <net/irda/irqueue.h>
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 9cb79f95bf6..47db1d8a0d9 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 36870788264..ba9a3fcc2fe 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -26,6 +26,7 @@
#include <linux/in6.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/xfrm.h>
@@ -2129,10 +2130,9 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c
int err;
out_skb = pfkey_xfrm_policy2msg_prep(xp);
- if (IS_ERR(out_skb)) {
- err = PTR_ERR(out_skb);
- goto out;
- }
+ if (IS_ERR(out_skb))
+ return PTR_ERR(out_skb);
+
err = pfkey_xfrm_policy2msg(out_skb, xp, dir);
if (err < 0)
return err;
@@ -2148,7 +2148,6 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c
out_hdr->sadb_msg_seq = c->seq;
out_hdr->sadb_msg_pid = c->pid;
pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp));
-out:
return 0;
}
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index bda96d18fd9..d5d8d555c41 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -29,6 +29,7 @@
#include <linux/inet.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/net/lapb/lapb_in.c b/net/lapb/lapb_in.c
index 6762e7c751e..21904a00244 100644
--- a/net/lapb/lapb_in.c
+++ b/net/lapb/lapb_in.c
@@ -27,6 +27,7 @@
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/net/lapb/lapb_out.c b/net/lapb/lapb_out.c
index 339cc5f2684..c75a79540f9 100644
--- a/net/lapb/lapb_out.c
+++ b/net/lapb/lapb_out.c
@@ -25,6 +25,7 @@
#include <linux/net.h>
#include <linux/inet.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/net/lapb/lapb_subr.c b/net/lapb/lapb_subr.c
index b827f47ac13..43a2a7fb327 100644
--- a/net/lapb/lapb_subr.c
+++ b/net/lapb/lapb_subr.c
@@ -24,6 +24,7 @@
#include <linux/net.h>
#include <linux/inet.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index e35d907fba2..2db6a9f7591 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/rtnetlink.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/llc.h>
#include <net/llc_sap.h>
#include <net/llc_pdu.h>
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 019c780512e..ea225bd2672 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -18,6 +18,7 @@
* See the GNU General Public License for more details.
*/
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <net/llc_conn.h>
#include <net/llc_sap.h>
#include <net/sock.h>
@@ -1437,7 +1438,7 @@ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
llc_conn_state_process(sk, skb);
else {
llc_set_backlog_type(skb, LLC_EVENT);
- sk_add_backlog(sk, skb);
+ __sk_add_backlog(sk, skb);
}
}
}
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index a8dde9b010d..ba137a6a224 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -13,6 +13,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/llc_sap.h>
#include <net/llc_conn.h>
#include <net/sock.h>
@@ -827,7 +828,8 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
else {
dprintk("%s: adding to backlog...\n", __func__);
llc_set_backlog_type(skb, LLC_PACKET);
- sk_add_backlog(sk, skb);
+ if (sk_add_backlog(sk, skb))
+ goto drop_unlock;
}
out:
bh_unlock_sock(sk);
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c
index a89917130a7..25c31c0a3fd 100644
--- a/net/llc/llc_if.c
+++ b/net/llc/llc_if.c
@@ -11,6 +11,7 @@
*
* See the GNU General Public License for more details.
*/
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
index 57ad974e4d9..f9968743913 100644
--- a/net/llc/llc_input.c
+++ b/net/llc/llc_input.c
@@ -12,6 +12,7 @@
* See the GNU General Public License for more details.
*/
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/llc.h>
#include <net/llc_pdu.h>
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index ad6e6e1cf22..a432f0ec051 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -23,6 +23,7 @@
#include <net/sock.h>
#include <net/tcp_states.h>
#include <linux/llc.h>
+#include <linux/slab.h>
static int llc_mac_header_len(unsigned short devtype)
{
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c
index 83da1333949..e4dae0244d7 100644
--- a/net/llc/llc_station.c
+++ b/net/llc/llc_station.c
@@ -13,6 +13,7 @@
*/
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <net/llc.h>
#include <net/llc_sap.h>
#include <net/llc_conn.h>
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index a978e666ed6..f9516a27e23 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -14,6 +14,7 @@
*/
#include <linux/ieee80211.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 5538e1b4a69..87782a4bb54 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -14,6 +14,7 @@
*/
#include <linux/ieee80211.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
@@ -183,7 +184,6 @@ static void sta_addba_resp_timer_expired(unsigned long data)
HT_AGG_STATE_REQ_STOP_BA_MSK)) !=
HT_ADDBA_REQUESTED_MSK) {
spin_unlock_bh(&sta->lock);
- *state = HT_AGG_STATE_IDLE;
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "timer expired on tid %d but we are not "
"(or no longer) expecting addBA response there",
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b7116ef84a3..edc872e22c9 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -9,6 +9,7 @@
#include <linux/ieee80211.h>
#include <linux/nl80211.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <linux/rcupdate.h>
#include <net/cfg80211.h>
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index d12e743cb4e..97c9e46e859 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -9,6 +9,7 @@
*/
#include <linux/kobject.h>
+#include <linux/slab.h>
#include "ieee80211_i.h"
#include "key.h"
#include "debugfs.h"
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 9affe2cd185..83d4289d954 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -13,6 +13,7 @@
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <linux/notifier.h>
#include <net/mac80211.h>
#include <net/cfg80211.h>
@@ -48,20 +49,24 @@ static ssize_t ieee80211_if_write(
ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
{
u8 *buf;
- ssize_t ret = -ENODEV;
+ ssize_t ret;
- buf = kzalloc(count, GFP_KERNEL);
+ buf = kmalloc(count, GFP_KERNEL);
if (!buf)
return -ENOMEM;
+ ret = -EFAULT;
if (copy_from_user(buf, userbuf, count))
- return -EFAULT;
+ goto freebuf;
+ ret = -ENODEV;
rtnl_lock();
if (sdata->dev->reg_state == NETREG_REGISTERED)
ret = (*write)(sdata, buf, count);
rtnl_unlock();
+freebuf:
+ kfree(buf);
return ret;
}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f3e94248674..e2976da4e0d 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -13,6 +13,7 @@
*/
#include <linux/delay.h>
+#include <linux/slab.h>
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0793d7a8d74..e08fa8eda1b 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -10,6 +10,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 8160d9c5372..e8f6e3b252d 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -14,6 +14,7 @@
#include <linux/list.h>
#include <linux/rcupdate.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 162a643f16b..063aad94424 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -8,6 +8,7 @@
/* just for IFNAMSIZ */
#include <linux/if.h>
+#include <linux/slab.h>
#include "led.h"
void ieee80211_led_rx(struct ieee80211_local *local)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 06c33b68d8e..b887e484ae0 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP:
sdata->vif.bss_conf.enable_beacon =
- !!rcu_dereference(sdata->u.ap.beacon);
+ !!sdata->u.ap.beacon;
break;
case NL80211_IFTYPE_ADHOC:
sdata->vif.bss_conf.enable_beacon =
- !!rcu_dereference(sdata->u.ibss.presp);
+ !!sdata->u.ibss.presp;
break;
case NL80211_IFTYPE_MESH_POINT:
sdata->vif.bss_conf.enable_beacon = true;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 61080c5fad5..859ee5f3d94 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include "ieee80211_i.h"
#include "mesh.h"
@@ -749,9 +750,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
switch (fc & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_ACTION:
- if (skb->len < IEEE80211_MIN_ACTION_SIZE)
- return RX_DROP_MONITOR;
- /* fall through */
case IEEE80211_STYPE_PROBE_RESP:
case IEEE80211_STYPE_BEACON:
skb_queue_tail(&ifmsh->skb_queue, skb);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index ce84237ebad..fefc45c4b4e 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -7,6 +7,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
#include "mesh.h"
#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG
@@ -391,7 +392,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
if (SN_GT(mpath->sn, orig_sn) ||
(mpath->sn == orig_sn &&
action == MPATH_PREQ &&
- new_metric > mpath->metric)) {
+ new_metric >= mpath->metric)) {
process = false;
fresh_info = false;
}
@@ -611,7 +612,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
cpu_to_le32(orig_sn), 0, target_addr,
- cpu_to_le32(target_sn), mpath->next_hop->sta.addr, hopcount,
+ cpu_to_le32(target_sn), next_hop, hopcount,
ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
0, sdata);
rcu_read_unlock();
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 2312efe04c6..181ffd6efd8 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -10,6 +10,7 @@
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <net/mac80211.h>
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index bc4e20e57ff..7b7080e2b49 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -6,6 +6,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/random.h>
#include "ieee80211_i.h"
@@ -744,7 +745,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
break;
default:
/* should not get here, PLINK_BLOCKED is dealt with at the
- * beggining of the function
+ * beginning of the function
*/
spin_unlock_bh(&sta->lock);
break;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 41812a15eea..4aefa6dc309 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -19,6 +19,7 @@
#include <linux/rtnetlink.h>
#include <linux/pm_qos_params.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include <asm/unaligned.h>
@@ -167,6 +168,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
channel_type != local->hw.conf.channel_type;
+ if (local->tmp_channel)
+ local->tmp_channel_type = channel_type;
local->oper_channel_type = channel_type;
if (ht_changed) {
@@ -177,7 +180,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
sta = sta_info_get(sdata, bssid);
if (sta)
rate_control_rate_update(local, sband, sta,
- IEEE80211_RC_HT_CHANGED);
+ IEEE80211_RC_HT_CHANGED,
+ local->oper_channel_type);
rcu_read_unlock();
}
@@ -435,10 +439,12 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
ieee80211_send_nullfunc(local, sdata, 1);
- if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
- conf->flags |= IEEE80211_CONF_PS;
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
- }
+ if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
+ (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
+ return;
+
+ conf->flags |= IEEE80211_CONF_PS;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
}
}
@@ -557,7 +563,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
(!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
ieee80211_send_nullfunc(local, sdata, 1);
- if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) ||
+ if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
+ (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ||
(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
local->hw.conf.flags |= IEEE80211_CONF_PS;
@@ -1893,8 +1900,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
mutex_lock(&ifmgd->mtx);
if (ifmgd->associated) {
- mutex_unlock(&ifmgd->mtx);
- return -EALREADY;
+ if (!req->prev_bssid ||
+ memcmp(req->prev_bssid, ifmgd->associated->bssid,
+ ETH_ALEN)) {
+ /*
+ * We are already associated and the request was not a
+ * reassociation request from the current BSS, so
+ * reject it.
+ */
+ mutex_unlock(&ifmgd->mtx);
+ return -EALREADY;
+ }
+
+ /* Trying to reassociate - clear previous association state */
+ ieee80211_set_disassoc(sdata);
}
mutex_unlock(&ifmgd->mtx);
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 0b299d236fa..6d0bd198af1 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include "rate.h"
#include "ieee80211_i.h"
#include "debugfs.h"
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index b6108bca96d..065a96190e3 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -66,7 +66,8 @@ static inline void rate_control_rate_init(struct sta_info *sta)
static inline void rate_control_rate_update(struct ieee80211_local *local,
struct ieee80211_supported_band *sband,
- struct sta_info *sta, u32 changed)
+ struct sta_info *sta, u32 changed,
+ enum nl80211_channel_type oper_chan_type)
{
struct rate_control_ref *ref = local->rate_ctrl;
struct ieee80211_sta *ista = &sta->sta;
@@ -74,7 +75,7 @@ static inline void rate_control_rate_update(struct ieee80211_local *local,
if (ref && ref->ops->rate_update)
ref->ops->rate_update(ref->priv, sband, ista,
- priv_sta, changed);
+ priv_sta, changed, oper_chan_type);
}
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 6e5d68b4e42..818abfae900 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -50,6 +50,7 @@
#include <linux/debugfs.h>
#include <linux/random.h>
#include <linux/ieee80211.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "rate.h"
#include "rc80211_minstrel.h"
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index a715d9454f6..0e1f12b1b6d 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -49,6 +49,7 @@
#include <linux/skbuff.h>
#include <linux/debugfs.h>
#include <linux/ieee80211.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "rc80211_minstrel.h"
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 2652a374974..aeda65466f3 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "rate.h"
#include "mesh.h"
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index 45667054a5f..47438b4a9af 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "rate.h"
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b5c48de81d8..04ea07f0e78 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -10,6 +10,7 @@
*/
#include <linux/jiffies.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
@@ -1973,6 +1974,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto handled;
}
break;
+ case MESH_PLINK_CATEGORY:
+ case MESH_PATH_SEL_CATEGORY:
+ if (ieee80211_vif_is_mesh(&sdata->vif))
+ return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
+ break;
}
/*
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index b822dce9786..85507bd9e34 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -14,6 +14,7 @@
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 211c475f73c..fb12cec4d33 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
- sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+ sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+ rcu_read_lock_held() ||
+ lockdep_is_held(&local->sta_lock) ||
+ lockdep_is_held(&local->sta_mtx));
while (sta) {
if (sta->sdata == sdata &&
memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
break;
- sta = rcu_dereference(sta->hnext);
+ sta = rcu_dereference_check(sta->hnext,
+ rcu_read_lock_held() ||
+ lockdep_is_held(&local->sta_lock) ||
+ lockdep_is_held(&local->sta_mtx));
}
return sta;
}
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
- sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+ sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+ rcu_read_lock_held() ||
+ lockdep_is_held(&local->sta_lock) ||
+ lockdep_is_held(&local->sta_mtx));
while (sta) {
if ((sta->sdata == sdata ||
sta->sdata->bss == sdata->bss) &&
memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
break;
- sta = rcu_dereference(sta->hnext);
+ sta = rcu_dereference_check(sta->hnext,
+ rcu_read_lock_held() ||
+ lockdep_is_held(&local->sta_lock) ||
+ lockdep_is_held(&local->sta_mtx));
}
return sta;
}
@@ -434,6 +446,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
/* check if STA exists already */
if (sta_info_get_bss(sdata, sta->sta.addr)) {
spin_unlock_irqrestore(&local->sta_lock, flags);
+ mutex_unlock(&local->sta_mtx);
rcu_read_lock();
err = -EEXIST;
goto out_free;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cbe53ed4fb0..cfc473e1b05 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1991,6 +1991,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
void ieee80211_tx_pending(unsigned long data)
{
struct ieee80211_local *local = (struct ieee80211_local *)data;
+ struct ieee80211_sub_if_data *sdata;
unsigned long flags;
int i;
bool txok;
@@ -2029,6 +2030,11 @@ void ieee80211_tx_pending(unsigned long data)
if (!txok)
break;
}
+
+ if (skb_queue_empty(&local->pending[i]))
+ list_for_each_entry_rcu(sdata, &local->interfaces, list)
+ netif_tx_wake_queue(
+ netdev_get_tx_queue(sdata->dev, i));
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index c453226f06b..53af5704743 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -279,13 +279,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
/* someone still has this queue stopped */
return;
- if (!skb_queue_empty(&local->pending[queue]))
+ if (skb_queue_empty(&local->pending[queue])) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(sdata, &local->interfaces, list)
+ netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
+ rcu_read_unlock();
+ } else
tasklet_schedule(&local->tx_pending_tasklet);
-
- rcu_read_lock();
- list_for_each_entry_rcu(sdata, &local->interfaces, list)
- netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
- rcu_read_unlock();
}
void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -1097,9 +1097,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
*/
res = drv_start(local);
if (res) {
- WARN(local->suspended, "Harware became unavailable "
- "upon resume. This is could be a software issue"
- "prior to suspend or a hardware issue\n");
+ WARN(local->suspended, "Hardware became unavailable "
+ "upon resume. This could be a software issue "
+ "prior to suspend or a hardware issue.\n");
return res;
}
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5d745f2d723..5f3a4113bda 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -17,6 +17,7 @@
#include <linux/err.h>
#include <linux/mm.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include <net/mac80211.h>
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 1e1ea3007b0..15e1ba931b8 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -19,6 +19,7 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/crc32.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include <asm/unaligned.h>
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index f4971cd45c6..0adbcc941ac 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -9,10 +9,10 @@
#include <linux/netdevice.h>
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/compiler.h>
#include <linux/ieee80211.h>
+#include <linux/gfp.h>
#include <asm/unaligned.h>
#include <net/mac80211.h>
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 60ec4e4bada..78b505d33bf 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -19,6 +19,7 @@
#include <linux/inetdevice.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/sock.h>
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index 3c7e42735b6..1cb0e834f8f 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -27,6 +27,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/protocol.h>
#include <net/tcp.h>
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 60bb41a8d8d..d8f7e8ef67b 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/proc_fs.h> /* for proc_net_* */
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/jhash.h>
#include <linux/random.h>
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 44590887a92..1cd6e3fd058 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -33,6 +33,7 @@
#include <linux/tcp.h>
#include <linux/sctp.h>
#include <linux/icmp.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/tcp.h>
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 7ee9c3426f4..36dc1d88c2f 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -31,6 +31,7 @@
#include <linux/workqueue.h>
#include <linux/swap.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
diff --git a/net/netfilter/ipvs/ip_vs_dh.c b/net/netfilter/ipvs/ip_vs_dh.c
index fe3e18834b9..95fd0d14200 100644
--- a/net/netfilter/ipvs/ip_vs_dh.c
+++ b/net/netfilter/ipvs/ip_vs_dh.c
@@ -39,6 +39,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/ip.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
index 702b53ca937..ff28801962e 100644
--- a/net/netfilter/ipvs/ip_vs_est.c
+++ b/net/netfilter/ipvs/ip_vs_est.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/jiffies.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/sysctl.h>
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index 73f38ea98f2..2c7f185dfae 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -32,6 +32,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
+#include <linux/gfp.h>
#include <net/protocol.h>
#include <net/tcp.h>
#include <asm/unaligned.h>
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 1b9370db230..94a45213faa 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -43,6 +43,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/ip.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index caa58fa1438..535dc2b419d 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -46,6 +46,7 @@
#include <linux/skbuff.h>
#include <linux/jiffies.h>
#include <linux/list.h>
+#include <linux/slab.h>
/* for sysctl */
#include <linux/fs.h>
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 0e584553819..7fc49f4cf5a 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
+#include <linux/gfp.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <net/protocol.h>
diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c
index 8e6cfd36e6f..e6cc174fbc0 100644
--- a/net/netfilter/ipvs/ip_vs_sh.c
+++ b/net/netfilter/ipvs/ip_vs_sh.c
@@ -36,6 +36,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/ip.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c
index 3c115fc1978..30db633f88f 100644
--- a/net/netfilter/ipvs/ip_vs_wrr.c
+++ b/net/netfilter/ipvs/ip_vs_wrr.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/net.h>
#include <linux/gcd.h>
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 223b5018c7d..e450cd6f4eb 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -17,6 +17,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/tcp.h> /* for tcphdr */
#include <net/ip.h>
#include <net/tcp.h> /* for csum_tcpudp_magic */
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
index 018f90db511..ab81b380eae 100644
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -9,6 +9,7 @@
*/
#include <linux/netfilter.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index 07d9d8857e5..372e80f07a8 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -16,6 +16,7 @@
#include <linux/in.h>
#include <linux/udp.h>
#include <linux/netfilter.h>
+#include <linux/gfp.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_expect.h>
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index d5a9bcd7d61..f516961a83b 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -18,6 +18,7 @@
#include <linux/percpu.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index f0732aa18e4..2ae3169e763 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -13,6 +13,7 @@
#include <linux/moduleparam.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
+#include <linux/slab.h>
#include <linux/ipv6.h>
#include <linux/ctype.h>
#include <linux/inet.h>
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index a1c8dd917e1..a487c803804 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -17,6 +17,7 @@
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/ip.h>
+#include <linux/slab.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/skbuff.h>
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 4509fa6726f..59e1a4cd4e8 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -15,7 +15,6 @@
#include <linux/skbuff.h>
#include <linux/vmalloc.h>
#include <linux/stddef.h>
-#include <linux/slab.h>
#include <linux/random.h>
#include <linux/err.h>
#include <linux/kernel.h>
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 8bd98c84f77..7673930ca34 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -15,6 +15,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/netfilter.h>
+#include <linux/slab.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_expect.h>
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 2b2af631d2b..afc52f2ee4a 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -27,6 +27,7 @@
#include <linux/netlink.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/netfilter.h>
#include <net/netlink.h>
@@ -582,7 +583,9 @@ nla_put_failure:
nlmsg_failure:
kfree_skb(skb);
errout:
- nfnetlink_set_err(net, 0, group, -ENOBUFS);
+ if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0)
+ return -ENOBUFS;
+
return 0;
}
#endif /* CONFIG_NF_CONNTRACK_EVENTS */
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 1a4568bf7ea..a44fa75b517 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/netfilter.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/skbuff.h>
#include <linux/vmalloc.h>
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 9a281554937..5292560d6d4 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -15,6 +15,7 @@
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <linux/dccp.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index d899b1a6994..cf616e55ca4 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -31,6 +31,7 @@
#include <linux/in.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/dst.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index dcfecbb81c4..d9e27734b2a 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netfilter.h>
+#include <linux/slab.h>
#include <linux/in.h>
#include <linux/tcp.h>
#include <net/netfilter/nf_conntrack.h>
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 8dd75d90efc..c6cd1b84edd 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -284,7 +284,7 @@ EXPORT_SYMBOL_GPL(ct_sip_parse_request);
* tabs, spaces and continuation lines, which are treated as a single whitespace
* character.
*
- * Some headers may appear multiple times. A comma seperated list of values is
+ * Some headers may appear multiple times. A comma separated list of values is
* equivalent to multiple headers.
*/
static const struct sip_header ct_sip_hdrs[] = {
@@ -421,7 +421,7 @@ int ct_sip_get_header(const struct nf_conn *ct, const char *dptr,
}
EXPORT_SYMBOL_GPL(ct_sip_get_header);
-/* Get next header field in a list of comma seperated values */
+/* Get next header field in a list of comma separated values */
static int ct_sip_next_header(const struct nf_conn *ct, const char *dptr,
unsigned int dataoff, unsigned int datalen,
enum sip_header_types type,
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 24a42efe62e..faa8eb3722b 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/netfilter.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/proc_fs.h>
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index ba095fd014e..c49ef219899 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -1,4 +1,5 @@
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 8eb0cc23ada..6afa3d52ea5 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -113,9 +113,9 @@ int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid,
}
EXPORT_SYMBOL_GPL(nfnetlink_send);
-void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error)
+int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error)
{
- netlink_set_err(net->nfnl, pid, group, error);
+ return netlink_set_err(net->nfnl, pid, group, error);
}
EXPORT_SYMBOL_GPL(nfnetlink_set_err);
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index d9b8fb8ab34..203643fb2c5 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -28,6 +28,7 @@
#include <linux/list.h>
#include <linux/jhash.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/netfilter/nf_log.h>
#include <net/netfilter/nfnetlink_log.h>
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 7ba4abc405c..e70a6ef1f4f 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -18,6 +18,7 @@
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/notifier.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 0a12cedfe9e..665f5beef6a 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -22,6 +22,7 @@
#include <linux/vmalloc.h>
#include <linux/mutex.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <linux/netfilter/x_tables.h>
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 61c50fa8470..ee18b231b95 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -7,6 +7,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/skbuff.h>
#include <linux/selinux.h>
#include <linux/netfilter_ipv4/ip_tables.h>
diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c
index 8ff7843bb92..3271c8e5215 100644
--- a/net/netfilter/xt_LED.c
+++ b/net/netfilter/xt_LED.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h>
+#include <linux/slab.h>
#include <linux/leds.h>
#include <linux/mutex.h>
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
index 87ae97e5516..d16d55df4f6 100644
--- a/net/netfilter/xt_RATEEST.c
+++ b/net/netfilter/xt_RATEEST.c
@@ -11,6 +11,7 @@
#include <linux/jhash.h>
#include <linux/rtnetlink.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <net/gen_stats.h>
#include <net/netlink.h>
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 0e357ac9a2a..c5f4b9919e9 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
+#include <linux/gfp.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>
#include <net/dst.h>
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 26997ce90e4..388ca459609 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -17,6 +17,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/jhash.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/random.h>
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c
index 0989f29ade2..395af5943ff 100644
--- a/net/netfilter/xt_dccp.c
+++ b/net/netfilter/xt_dccp.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <net/ip.h>
#include <linux/dccp.h>
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index d952806b646..215a64835de 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -1,6 +1,6 @@
/*
* xt_hashlimit - Netfilter module to limit the number of packets per time
- * seperately for each hashbucket (sourceip/sourceport/dstip/dstport)
+ * separately for each hashbucket (sourceip/sourceport/dstip/dstport)
*
* (C) 2003-2004 by Harald Welte <laforge@netfilter.org>
* Copyright © CC Computer Consultants GmbH, 2007 - 2008
@@ -493,6 +493,7 @@ static void hashlimit_ipv6_mask(__be32 *i, unsigned int p)
case 64 ... 95:
i[2] = maskl(i[2], p - 64);
i[3] = 0;
+ break;
case 96 ... 127:
i[3] = maskl(i[3], p - 96);
break;
@@ -879,7 +880,8 @@ static void dl_seq_stop(struct seq_file *s, void *v)
struct xt_hashlimit_htable *htable = s->private;
unsigned int *bucket = (unsigned int *)v;
- kfree(bucket);
+ if (!IS_ERR(bucket))
+ kfree(bucket);
spin_unlock_bh(&htable->lock);
}
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index a0ca5339af4..e5d7e1ffb1a 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -6,6 +6,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c
index 390b7d09fe5..2d5562498c4 100644
--- a/net/netfilter/xt_quota.c
+++ b/net/netfilter/xt_quota.c
@@ -4,6 +4,7 @@
* Sam Johnston <samj@samj.net>
*/
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/netfilter/x_tables.h>
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 7073dbb8100..834b736857c 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -27,6 +27,7 @@
#include <linux/bitops.h>
#include <linux/skbuff.h>
#include <linux/inet.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
@@ -267,7 +268,7 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
for (i = 0; i < e->nstamps; i++) {
if (info->seconds && time_after(time, e->stamps[i]))
continue;
- if (info->hit_count && ++hits >= info->hit_count) {
+ if (!info->hit_count || ++hits >= info->hit_count) {
ret = !ret;
break;
}
diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c
index d8c0f8f1a78..937ce0633e9 100644
--- a/net/netfilter/xt_statistic.c
+++ b/net/netfilter/xt_statistic.c
@@ -12,6 +12,7 @@
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <linux/netfilter/xt_statistic.h>
#include <linux/netfilter/x_tables.h>
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c
index b4d77411131..96801ffd8af 100644
--- a/net/netfilter/xt_string.c
+++ b/net/netfilter/xt_string.c
@@ -7,6 +7,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index e639298bc9c..5f14c8462e3 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -33,6 +33,7 @@
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/audit.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 0bfeaab88ef..d37b7f80fa3 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/audit.h>
+#include <linux/slab.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <asm/bug.h>
@@ -50,9 +51,12 @@ struct netlbl_domhsh_tbl {
};
/* Domain hash table */
-/* XXX - updates should be so rare that having one spinlock for the entire
- * hash table should be okay */
+/* updates should be so rare that having one spinlock for the entire hash table
+ * should be okay */
static DEFINE_SPINLOCK(netlbl_domhsh_lock);
+#define netlbl_domhsh_rcu_deref(p) \
+ rcu_dereference_check(p, rcu_read_lock_held() || \
+ lockdep_is_held(&netlbl_domhsh_lock))
static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
@@ -106,7 +110,8 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry)
* Description:
* This is the hashing function for the domain hash table, it returns the
* correct bucket number for the domain. The caller is responsibile for
- * calling the rcu_read_[un]lock() functions.
+ * ensuring that the hash table is protected with either a RCU read lock or the
+ * hash table lock.
*
*/
static u32 netlbl_domhsh_hash(const char *key)
@@ -120,7 +125,7 @@ static u32 netlbl_domhsh_hash(const char *key)
for (iter = 0, val = 0, len = strlen(key); iter < len; iter++)
val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter];
- return val & (rcu_dereference(netlbl_domhsh)->size - 1);
+ return val & (netlbl_domhsh_rcu_deref(netlbl_domhsh)->size - 1);
}
/**
@@ -130,7 +135,8 @@ static u32 netlbl_domhsh_hash(const char *key)
* Description:
* Searches the domain hash table and returns a pointer to the hash table
* entry if found, otherwise NULL is returned. The caller is responsibile for
- * the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()).
+ * ensuring that the hash table is protected with either a RCU read lock or the
+ * hash table lock.
*
*/
static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
@@ -141,7 +147,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
if (domain != NULL) {
bkt = netlbl_domhsh_hash(domain);
- bkt_list = &rcu_dereference(netlbl_domhsh)->tbl[bkt];
+ bkt_list = &netlbl_domhsh_rcu_deref(netlbl_domhsh)->tbl[bkt];
list_for_each_entry_rcu(iter, bkt_list, list)
if (iter->valid && strcmp(iter->domain, domain) == 0)
return iter;
@@ -159,8 +165,8 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
* Searches the domain hash table and returns a pointer to the hash table
* entry if an exact match is found, if an exact match is not present in the
* hash table then the default entry is returned if valid otherwise NULL is
- * returned. The caller is responsibile for the rcu hash table locks
- * (i.e. the caller much call rcu_read_[un]lock()).
+ * returned. The caller is responsibile ensuring that the hash table is
+ * protected with either a RCU read lock or the hash table lock.
*
*/
static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
@@ -169,7 +175,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
entry = netlbl_domhsh_search(domain);
if (entry == NULL) {
- entry = rcu_dereference(netlbl_domhsh_def);
+ entry = netlbl_domhsh_rcu_deref(netlbl_domhsh_def);
if (entry != NULL && !entry->valid)
entry = NULL;
}
@@ -306,8 +312,11 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
struct netlbl_af6list *tmp6;
#endif /* IPv6 */
+ /* XXX - we can remove this RCU read lock as the spinlock protects the
+ * entire function, but before we do we need to fixup the
+ * netlbl_af[4,6]list RCU functions to do "the right thing" with
+ * respect to rcu_dereference() when only a spinlock is held. */
rcu_read_lock();
-
spin_lock(&netlbl_domhsh_lock);
if (entry->domain != NULL)
entry_old = netlbl_domhsh_search(entry->domain);
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 6ce00205f34..1b83e0009d8 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/audit.h>
#include <linux/in.h>
#include <linux/in6.h>
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 8203623e65a..998e85e895d 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -34,6 +34,7 @@
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/in6.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 852d9d7976b..a3d64aabe2f 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -43,6 +43,7 @@
#include <linux/notifier.h>
#include <linux/netdevice.h>
#include <linux/security.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
@@ -114,6 +115,9 @@ struct netlbl_unlhsh_walk_arg {
/* updates should be so rare that having one spinlock for the entire
* hash table should be okay */
static DEFINE_SPINLOCK(netlbl_unlhsh_lock);
+#define netlbl_unlhsh_rcu_deref(p) \
+ rcu_dereference_check(p, rcu_read_lock_held() || \
+ lockdep_is_held(&netlbl_unlhsh_lock))
static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL;
static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL;
@@ -235,15 +239,13 @@ static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
* Description:
* This is the hashing function for the unlabeled hash table, it returns the
* bucket number for the given device/interface. The caller is responsible for
- * calling the rcu_read_[un]lock() functions.
+ * ensuring that the hash table is protected with either a RCU read lock or
+ * the hash table lock.
*
*/
static u32 netlbl_unlhsh_hash(int ifindex)
{
- /* this is taken _almost_ directly from
- * security/selinux/netif.c:sel_netif_hasfn() as they do pretty much
- * the same thing */
- return ifindex & (rcu_dereference(netlbl_unlhsh)->size - 1);
+ return ifindex & (netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->size - 1);
}
/**
@@ -253,7 +255,8 @@ static u32 netlbl_unlhsh_hash(int ifindex)
* Description:
* Searches the unlabeled connection hash table and returns a pointer to the
* interface entry which matches @ifindex, otherwise NULL is returned. The
- * caller is responsible for calling the rcu_read_[un]lock() functions.
+ * caller is responsible for ensuring that the hash table is protected with
+ * either a RCU read lock or the hash table lock.
*
*/
static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
@@ -263,7 +266,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
struct netlbl_unlhsh_iface *iter;
bkt = netlbl_unlhsh_hash(ifindex);
- bkt_list = &rcu_dereference(netlbl_unlhsh)->tbl[bkt];
+ bkt_list = &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt];
list_for_each_entry_rcu(iter, bkt_list, list)
if (iter->valid && iter->ifindex == ifindex)
return iter;
@@ -272,33 +275,6 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
}
/**
- * netlbl_unlhsh_search_iface_def - Search for a matching interface entry
- * @ifindex: the network interface
- *
- * Description:
- * Searches the unlabeled connection hash table and returns a pointer to the
- * interface entry which matches @ifindex. If an exact match can not be found
- * and there is a valid default entry, the default entry is returned, otherwise
- * NULL is returned. The caller is responsible for calling the
- * rcu_read_[un]lock() functions.
- *
- */
-static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
-{
- struct netlbl_unlhsh_iface *entry;
-
- entry = netlbl_unlhsh_search_iface(ifindex);
- if (entry != NULL)
- return entry;
-
- entry = rcu_dereference(netlbl_unlhsh_def);
- if (entry != NULL && entry->valid)
- return entry;
-
- return NULL;
-}
-
-/**
* netlbl_unlhsh_add_addr4 - Add a new IPv4 address entry to the hash table
* @iface: the associated interface entry
* @addr: IPv4 address in network byte order
@@ -308,8 +284,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
* Description:
* Add a new address entry into the unlabeled connection hash table using the
* interface entry specified by @iface. On success zero is returned, otherwise
- * a negative value is returned. The caller is responsible for calling the
- * rcu_read_[un]lock() functions.
+ * a negative value is returned.
*
*/
static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
@@ -349,8 +324,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
* Description:
* Add a new address entry into the unlabeled connection hash table using the
* interface entry specified by @iface. On success zero is returned, otherwise
- * a negative value is returned. The caller is responsible for calling the
- * rcu_read_[un]lock() functions.
+ * a negative value is returned.
*
*/
static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
@@ -391,8 +365,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
* Description:
* Add a new, empty, interface entry into the unlabeled connection hash table.
* On success a pointer to the new interface entry is returned, on failure NULL
- * is returned. The caller is responsible for calling the rcu_read_[un]lock()
- * functions.
+ * is returned.
*
*/
static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
@@ -415,10 +388,10 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
if (netlbl_unlhsh_search_iface(ifindex) != NULL)
goto add_iface_failure;
list_add_tail_rcu(&iface->list,
- &rcu_dereference(netlbl_unlhsh)->tbl[bkt]);
+ &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]);
} else {
INIT_LIST_HEAD(&iface->list);
- if (rcu_dereference(netlbl_unlhsh_def) != NULL)
+ if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL)
goto add_iface_failure;
rcu_assign_pointer(netlbl_unlhsh_def, iface);
}
@@ -548,8 +521,7 @@ unlhsh_add_return:
*
* Description:
* Remove an IP address entry from the unlabeled connection hash table.
- * Returns zero on success, negative values on failure. The caller is
- * responsible for calling the rcu_read_[un]lock() functions.
+ * Returns zero on success, negative values on failure.
*
*/
static int netlbl_unlhsh_remove_addr4(struct net *net,
@@ -611,8 +583,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
*
* Description:
* Remove an IP address entry from the unlabeled connection hash table.
- * Returns zero on success, negative values on failure. The caller is
- * responsible for calling the rcu_read_[un]lock() functions.
+ * Returns zero on success, negative values on failure.
*
*/
static int netlbl_unlhsh_remove_addr6(struct net *net,
@@ -1547,8 +1518,10 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
struct netlbl_unlhsh_iface *iface;
rcu_read_lock();
- iface = netlbl_unlhsh_search_iface_def(skb->skb_iif);
+ iface = netlbl_unlhsh_search_iface(skb->skb_iif);
if (iface == NULL)
+ iface = rcu_dereference(netlbl_unlhsh_def);
+ if (iface == NULL || !iface->valid)
goto unlabel_getattr_nolabel;
switch (family) {
case PF_INET: {
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 68706b4e3bf..a3fd75ac3fa 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -35,6 +35,7 @@
#include <linux/audit.h>
#include <linux/tty.h>
#include <linux/security.h>
+#include <linux/gfp.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 320d0423a24..795424396af 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -683,6 +683,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
struct netlink_sock *nlk = nlk_sk(sk);
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
+ if (alen < sizeof(addr->sa_family))
+ return -EINVAL;
+
if (addr->sa_family == AF_UNSPEC) {
sk->sk_state = NETLINK_UNCONNECTED;
nlk->dst_pid = 0;
@@ -1093,6 +1096,7 @@ static inline int do_one_set_err(struct sock *sk,
struct netlink_set_err_data *p)
{
struct netlink_sock *nlk = nlk_sk(sk);
+ int ret = 0;
if (sk == p->exclude_sk)
goto out;
@@ -1104,10 +1108,15 @@ static inline int do_one_set_err(struct sock *sk,
!test_bit(p->group - 1, nlk->groups))
goto out;
+ if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) {
+ ret = 1;
+ goto out;
+ }
+
sk->sk_err = p->code;
sk->sk_error_report(sk);
out:
- return 0;
+ return ret;
}
/**
@@ -1116,12 +1125,16 @@ out:
* @pid: the PID of a process that we want to skip (if any)
* @groups: the broadcast group that will notice the error
* @code: error code, must be negative (as usual in kernelspace)
+ *
+ * This function returns the number of broadcast listeners that have set the
+ * NETLINK_RECV_NO_ENOBUFS socket option.
*/
-void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
+int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
{
struct netlink_set_err_data info;
struct hlist_node *node;
struct sock *sk;
+ int ret = 0;
info.exclude_sk = ssk;
info.pid = pid;
@@ -1132,9 +1145,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
read_lock(&nl_table_lock);
sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list)
- do_one_set_err(sk, &info);
+ ret += do_one_set_err(sk, &info);
read_unlock(&nl_table_lock);
+ return ret;
}
EXPORT_SYMBOL(netlink_set_err);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index a4b6e148c5d..06438fa2b1e 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index a249127020a..fa07f044b59 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/timer.h>
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 7aa11b01b2e..64e6dde9749 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -19,6 +19,7 @@
#include <linux/fcntl.h>
#include <linux/in.h>
#include <linux/if_ether.h> /* For the statistics structure. */
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index 68176483617..6d4ef6d65b3 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/netrom/nr_loopback.c b/net/netrom/nr_loopback.c
index f324d5df418..94d4e922af5 100644
--- a/net/netrom/nr_loopback.c
+++ b/net/netrom/nr_loopback.c
@@ -7,6 +7,7 @@
* Copyright Tomi Manninen OH2BNS (oh2bns@sral.fi)
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/timer.h>
#include <net/ax25.h>
diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
index e3e6c44e189..607fddb4fdb 100644
--- a/net/netrom/nr_out.c
+++ b/net/netrom/nr_out.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 5cc648012f5..44059d0c8dd 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -17,6 +17,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/netrom/nr_subr.c b/net/netrom/nr_subr.c
index 04e7d0d2fd8..6a947ae50db 100644
--- a/net/netrom/nr_subr.c
+++ b/net/netrom/nr_subr.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 031a5e6fb4a..243946d4809 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -60,6 +60,7 @@
#include <linux/wireless.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/ip.h>
#include <net/protocol.h>
@@ -1688,6 +1689,8 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
{
switch (i->type) {
case PACKET_MR_MULTICAST:
+ if (i->alen != dev->addr_len)
+ return -EINVAL;
if (what > 0)
return dev_mc_add(dev, i->addr, i->alen, 0);
else
@@ -1700,6 +1703,8 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
return dev_set_allmulti(dev, what);
break;
case PACKET_MR_UNICAST:
+ if (i->alen != dev->addr_len)
+ return -EINVAL;
if (what > 0)
return dev_unicast_add(dev, i->addr);
else
@@ -1734,7 +1739,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
goto done;
err = -EINVAL;
- if (mreq->mr_alen != dev->addr_len)
+ if (mreq->mr_alen > dev->addr_len)
goto done;
err = -ENOBUFS;
@@ -2164,8 +2169,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
case SIOCGIFDSTADDR:
case SIOCSIFDSTADDR:
case SIOCSIFFLAGS:
- if (!net_eq(sock_net(sk), &init_net))
- return -ENOIOCTLCMD;
return inet_dgram_ops.ioctl(sock, cmd, arg);
#endif
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 526d0273991..73aee7f2fcd 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/unaligned.h>
#include <net/sock.h>
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
index 387197b579b..1bd38db4fe1 100644
--- a/net/phonet/datagram.c
+++ b/net/phonet/datagram.c
@@ -24,6 +24,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/socket.h>
#include <asm/ioctls.h>
#include <net/sock.h>
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 360cf377693..e2a95762abd 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -23,6 +23,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/socket.h>
#include <net/sock.h>
#include <net/tcp_states.h>
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index c597cc53a6f..9b4ced6e096 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/phonet.h>
#include <linux/proc_fs.h>
@@ -107,8 +108,7 @@ static void phonet_device_destroy(struct net_device *dev)
if (pnd) {
u8 addr;
- for (addr = find_first_bit(pnd->addrs, 64); addr < 64;
- addr = find_next_bit(pnd->addrs, 64, 1+addr))
+ for_each_set_bit(addr, pnd->addrs, 64)
phonet_address_notify(RTM_DELADDR, dev, addr);
kfree(pnd);
}
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index 2e6c7eb8e76..58b3b1f991e 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/netlink.h>
#include <linux/phonet.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/phonet/pn_dev.h>
@@ -141,8 +142,7 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
continue;
addr_idx = 0;
- for (addr = find_first_bit(pnd->addrs, 64); addr < 64;
- addr = find_next_bit(pnd->addrs, 64, 1+addr)) {
+ for_each_set_bit(addr, pnd->addrs, 64) {
if (addr_idx++ < addr_start_idx)
continue;
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 69c8b826a0c..c785bfd0744 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -23,6 +23,7 @@
* 02110-1301 USA
*/
+#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/poll.h>
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 853c52be781..f81862baf4d 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/in.h>
#include <linux/poll.h>
#include <net/sock.h>
diff --git a/net/rds/cong.c b/net/rds/cong.c
index 6d06cac2649..f1da27ceb06 100644
--- a/net/rds/cong.c
+++ b/net/rds/cong.c
@@ -30,6 +30,7 @@
* SOFTWARE.
*
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/rbtree.h>
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 278f607ab60..7619b671ca2 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -32,6 +32,7 @@
*/
#include <linux/kernel.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/inet_hashtables.h>
#include "rds.h"
diff --git a/net/rds/ib.c b/net/rds/ib.c
index 3b899236104..8f2d6dd7700 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -37,6 +37,7 @@
#include <linux/inetdevice.h>
#include <linux/if_arp.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "rds.h"
#include "ib.h"
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index 647cb8ffc39..88d0856cb79 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -32,6 +32,7 @@
*/
#include <linux/kernel.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "rds.h"
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index 4b0da865a72..059989fdb7d 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "rds.h"
#include "rdma.h"
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index 04dc0d3f3c9..c7dd11b835f 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <rdma/rdma_cm.h>
diff --git a/net/rds/info.c b/net/rds/info.c
index 814a91a6f4a..c45c4173a44 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -32,6 +32,7 @@
*/
#include <linux/percpu.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/proc_fs.h>
#include "rds.h"
diff --git a/net/rds/iw.c b/net/rds/iw.c
index b28fa8525b2..c8f3d3525cb 100644
--- a/net/rds/iw.c
+++ b/net/rds/iw.c
@@ -37,6 +37,7 @@
#include <linux/inetdevice.h>
#include <linux/if_arp.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include "rds.h"
#include "iw.h"
diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c
index 394cf6b4d0a..3e9460f935d 100644
--- a/net/rds/iw_cm.c
+++ b/net/rds/iw_cm.c
@@ -32,6 +32,7 @@
*/
#include <linux/kernel.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "rds.h"
diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c
index 9eda11cca95..13dc1862d86 100644
--- a/net/rds/iw_rdma.c
+++ b/net/rds/iw_rdma.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "rds.h"
#include "rdma.h"
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index 54af7d6b92d..da43ee840ca 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <rdma/rdma_cm.h>
diff --git a/net/rds/loop.c b/net/rds/loop.c
index 4a61997f554..0d7a159158b 100644
--- a/net/rds/loop.c
+++ b/net/rds/loop.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/in.h>
#include "rds.h"
diff --git a/net/rds/message.c b/net/rds/message.c
index 73e600ffd87..9a1d67e001b 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "rds.h"
#include "rdma.h"
diff --git a/net/rds/page.c b/net/rds/page.c
index 36790122dfd..595a952d4b1 100644
--- a/net/rds/page.c
+++ b/net/rds/page.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/highmem.h>
+#include <linux/gfp.h>
#include "rds.h"
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 4c64daa1f5d..5ce9437cad6 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/pagemap.h>
+#include <linux/slab.h>
#include <linux/rbtree.h>
#include <linux/dma-mapping.h> /* for DMA_*_DEVICE */
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index 9ece910ea39..7b155081b4d 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -134,7 +134,7 @@ static int __init rds_rdma_listen_init(void)
ret = PTR_ERR(cm_id);
printk(KERN_ERR "RDS/RDMA: failed to setup listener, "
"rdma_create_id() returned %d\n", ret);
- goto out;
+ return ret;
}
sin.sin_family = AF_INET,
diff --git a/net/rds/recv.c b/net/rds/recv.c
index b426d67f760..e2a2b9344f7 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/in.h>
diff --git a/net/rds/send.c b/net/rds/send.c
index b2fccfc2076..f04b929ded9 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <net/sock.h>
#include <linux/in.h>
#include <linux/list.h>
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index b5198aee45d..babf4577ff7 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/in.h>
#include <net/tcp.h>
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 53cb1b54165..975183fe695 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/in.h>
#include <net/tcp.h>
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index c00dafffbb5..e08ec912d8b 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -31,6 +31,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <net/tcp.h>
#include "rds.h"
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index c218e07e5ca..a9fa86f6598 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -33,6 +33,7 @@
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#include "rfkill.h"
diff --git a/net/rfkill/input.c b/net/rfkill/input.c
index a7295ad5f9c..3713d7ecab9 100644
--- a/net/rfkill/input.c
+++ b/net/rfkill/input.c
@@ -212,6 +212,9 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
case KEY_WIMAX:
rfkill_schedule_toggle(RFKILL_TYPE_WIMAX);
break;
+ case KEY_RFKILL:
+ rfkill_schedule_toggle(RFKILL_TYPE_ALL);
+ break;
}
} else if (type == EV_SW && code == SW_RFKILL_ALL)
rfkill_schedule_evsw_rfkillall(data);
@@ -295,6 +298,11 @@ static const struct input_device_id rfkill_ids[] = {
.keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
},
{
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(KEY_RFKILL)] = BIT_MASK(KEY_RFKILL) },
+ },
+ {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
.evbit = { BIT(EV_SW) },
.swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index e90b9b6c16a..4fb711a035f 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/in.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
index 424b893d145..178ff4f73c8 100644
--- a/net/rose/rose_dev.c
+++ b/net/rose/rose_dev.c
@@ -19,6 +19,7 @@
#include <linux/fcntl.h>
#include <linux/in.h>
#include <linux/if_ether.h>
+#include <linux/slab.h>
#include <asm/system.h>
#include <asm/io.h>
diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
index 5ef5f6988a2..a750a28e022 100644
--- a/net/rose/rose_link.c
+++ b/net/rose/rose_link.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c
index 968e8bac1b5..ae4a9d99aec 100644
--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -7,6 +7,7 @@
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/timer.h>
#include <net/ax25.h>
diff --git a/net/rose/rose_out.c b/net/rose/rose_out.c
index 69820f93414..4ebf33afbe4 100644
--- a/net/rose/rose_out.c
+++ b/net/rose/rose_out.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/gfp.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 70a0b3b4b4d..cbc244a128b 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index b05108f382d..1734abba26a 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 287b1415cee..c060095b27c 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/net.h>
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c
index 77228f28fa3..6d79310fcaa 100644
--- a/net/rxrpc/ar-accept.c
+++ b/net/rxrpc/ar-accept.c
@@ -17,6 +17,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/icmp.h>
+#include <linux/gfp.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <net/ip.h>
@@ -88,6 +89,11 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
/* get a notification message to send to the server app */
notification = alloc_skb(0, GFP_NOFS);
+ if (!notification) {
+ _debug("no memory");
+ ret = -ENOMEM;
+ goto error_nofree;
+ }
rxrpc_new_skb(notification);
notification->mark = RXRPC_SKB_MARK_NEW_CALL;
@@ -189,6 +195,7 @@ invalid_service:
ret = -ECONNREFUSED;
error:
rxrpc_free_skb(notification);
+error_nofree:
_leave(" = %d", ret);
return ret;
}
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c
index b4a22097703..2714da167fb 100644
--- a/net/rxrpc/ar-ack.c
+++ b/net/rxrpc/ar-ack.c
@@ -13,6 +13,7 @@
#include <linux/circ_buf.h>
#include <linux/net.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/udp.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c
index bc0019f704f..909d092de9f 100644
--- a/net/rxrpc/ar-call.c
+++ b/net/rxrpc/ar-call.c
@@ -9,6 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/circ_buf.h>
#include <net/sock.h>
diff --git a/net/rxrpc/ar-connection.c b/net/rxrpc/ar-connection.c
index 9f1ce841a0b..4106ca95ec8 100644
--- a/net/rxrpc/ar-connection.c
+++ b/net/rxrpc/ar-connection.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/crypto.h>
diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c
index f98c8027e5c..89315009bab 100644
--- a/net/rxrpc/ar-input.c
+++ b/net/rxrpc/ar-input.c
@@ -17,6 +17,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/icmp.h>
+#include <linux/gfp.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <net/ip.h>
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 74697b20049..5ee16f0353f 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -18,6 +18,7 @@
#include <linux/key-type.h>
#include <linux/crypto.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <keys/rxrpc-type.h>
diff --git a/net/rxrpc/ar-local.c b/net/rxrpc/ar-local.c
index 807535ff29b..87f7135d238 100644
--- a/net/rxrpc/ar-local.c
+++ b/net/rxrpc/ar-local.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include "ar-internal.h"
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c
index cc9102c5b58..5f22e263eda 100644
--- a/net/rxrpc/ar-output.c
+++ b/net/rxrpc/ar-output.c
@@ -10,6 +10,7 @@
*/
#include <linux/net.h>
+#include <linux/gfp.h>
#include <linux/skbuff.h>
#include <linux/circ_buf.h>
#include <net/sock.h>
diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c
index edc026c1eb7..f0f85b0123f 100644
--- a/net/rxrpc/ar-peer.c
+++ b/net/rxrpc/ar-peer.c
@@ -16,6 +16,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/icmp.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <net/ip.h>
diff --git a/net/rxrpc/ar-transport.c b/net/rxrpc/ar-transport.c
index 0936e1acc30..5e0226fe587 100644
--- a/net/rxrpc/ar-transport.c
+++ b/net/rxrpc/ar-transport.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include "ar-internal.h"
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index 713ac593e2e..7635107726c 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -16,6 +16,7 @@
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <keys/rxrpc-type.h>
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 21f9c7678aa..2f691fb180d 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -328,13 +328,16 @@ config NET_CLS_FLOW
module will be called cls_flow.
config NET_CLS_CGROUP
- bool "Control Group Classifier"
+ tristate "Control Group Classifier"
select NET_CLS
depends on CGROUPS
---help---
Say Y here if you want to classify packets based on the control
cgroup of their process.
+ To compile this code as a module, choose M here: the
+ module will be called cls_cgroup.
+
config NET_EMATCH
bool "Extended Matches"
select NET_CLS
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 64f5e328cee..d8e0171d9a4 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/kmod.h>
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 082c520b0de..da27a170b6b 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -19,6 +19,7 @@
#include <linux/rtnetlink.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <linux/tc_act/tc_ipt.h>
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index d329170243c..c046682054e 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -20,6 +20,7 @@
#include <linux/rtnetlink.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <net/net_namespace.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 6b0359a500e..b7dcfedc802 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -17,6 +17,7 @@
#include <linux/rtnetlink.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <linux/tc_act/tc_pedit.h>
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 723964c3ee4..654f73dff7c 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -18,6 +18,7 @@
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/act_api.h>
#include <net/netlink.h>
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 8daa1ebc741..622ca809c15 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 3725d8fa29d..f082b27ff46 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -24,6 +24,7 @@
#include <linux/kmod.h>
#include <linux/netlink.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/netlink.h>
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 4e2bda85411..efd4f95fd05 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index e4877ca6727..221180384fd 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/errno.h>
@@ -24,6 +25,25 @@ struct cgroup_cls_state
u32 classid;
};
+static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
+ struct cgroup *cgrp);
+static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
+static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp);
+
+struct cgroup_subsys net_cls_subsys = {
+ .name = "net_cls",
+ .create = cgrp_create,
+ .destroy = cgrp_destroy,
+ .populate = cgrp_populate,
+#ifdef CONFIG_NET_CLS_CGROUP
+ .subsys_id = net_cls_subsys_id,
+#else
+#define net_cls_subsys_id net_cls_subsys.subsys_id
+#endif
+ .module = THIS_MODULE,
+};
+
+
static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp)
{
return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id),
@@ -79,14 +99,6 @@ static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files));
}
-struct cgroup_subsys net_cls_subsys = {
- .name = "net_cls",
- .create = cgrp_create,
- .destroy = cgrp_destroy,
- .populate = cgrp_populate,
- .subsys_id = net_cls_subsys_id,
-};
-
struct cls_cgroup_head
{
u32 handle;
@@ -277,12 +289,19 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = {
static int __init init_cgroup_cls(void)
{
- return register_tcf_proto_ops(&cls_cgroup_ops);
+ int ret = register_tcf_proto_ops(&cls_cgroup_ops);
+ if (ret)
+ return ret;
+ ret = cgroup_load_subsys(&net_cls_subsys);
+ if (ret)
+ unregister_tcf_proto_ops(&cls_cgroup_ops);
+ return ret;
}
static void __exit exit_cgroup_cls(void)
{
unregister_tcf_proto_ops(&cls_cgroup_ops);
+ cgroup_unload_subsys(&net_cls_subsys);
}
module_init(init_cgroup_cls);
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index e054c62857e..6ed61b10e00 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -20,6 +20,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/if_vlan.h>
+#include <linux/slab.h>
#include <net/pkt_cls.h>
#include <net/ip.h>
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 6d6e87585fb..93b0a7b6f9b 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -19,6 +19,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index dd872d5383e..694dcd85dec 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index e806f2314b5..20ef330bb91 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/errno.h>
+#include <linux/slab.h>
#include <net/act_api.h>
#include <net/netlink.h>
#include <net/pkt_cls.h>
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 07372f60bee..17c5dfc6732 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -31,6 +31,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 24dce8b648a..3bcac8aa333 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -58,6 +58,7 @@
* only available if that subsystem is enabled in the kernel.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/sched/em_nbyte.c b/net/sched/em_nbyte.c
index 370a1b2ea31..1a4176aee6e 100644
--- a/net/sched/em_nbyte.c
+++ b/net/sched/em_nbyte.c
@@ -9,6 +9,7 @@
* Authors: Thomas Graf <tgraf@suug.ch>
*/
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
index 853c5ead87f..76325325741 100644
--- a/net/sched/em_text.c
+++ b/net/sched/em_text.c
@@ -9,6 +9,7 @@
* Authors: Thomas Graf <tgraf@suug.ch>
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index aab59409728..e782bdeedc5 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -82,6 +82,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 6cd491013b5..145268ca57c 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -28,6 +28,7 @@
#include <linux/list.h>
#include <linux/hrtimer.h>
#include <linux/lockdep.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/sock.h>
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index ab82f145f68..fcbb86a486a 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -3,6 +3,7 @@
/* Written 1998-2000 by Werner Almesberger, EPFL ICA */
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 3846d65bc03..28c01ef5abc 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index a65604f8f2b..b74046a9539 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -9,6 +9,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index d303daa45d4..63d41f86679 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -5,6 +5,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 4b0a6cc44c7..5948bafa8ce 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 5173c1e1b19..ff4dd53eeff 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <net/pkt_sched.h>
/* Main transmission queue. */
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 40408d595c0..51dcc2aa5c9 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -18,6 +18,7 @@
* For all the glorious comments look at include/net/red.h
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 508cf5f3a6d..0b52b8de562 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -36,6 +36,7 @@
#include <linux/compiler.h>
#include <linux/rbtree.h>
#include <linux/workqueue.h>
+#include <linux/slab.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index d1dea3d5dc9..b2aba3f5e6f 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -9,6 +9,7 @@
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 7db2c88ce58..c50876cd870 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -18,6 +18,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index d8b10e05462..4714ff162bb 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -14,6 +14,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 93285cecb24..81672e0c1b2 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -12,6 +12,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index cb21380c060..c5a9ac56600 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -20,6 +20,7 @@
#include <linux/ipv6.h>
#include <linux/skbuff.h>
#include <linux/jhash.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index db69637069c..3415b6ce1c0 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index df5abbff63e..99c93ee98ad 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1194,8 +1194,10 @@ void sctp_assoc_update(struct sctp_association *asoc,
/* Remove any peer addresses not present in the new association. */
list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
trans = list_entry(pos, struct sctp_transport, transports);
- if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr))
- sctp_assoc_del_peer(asoc, &trans->ipaddr);
+ if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) {
+ sctp_assoc_rm_peer(asoc, trans);
+ continue;
+ }
if (asoc->state >= SCTP_STATE_ESTABLISHED)
sctp_transport_reset(trans);
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 56935bbc149..86366390038 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -34,6 +34,7 @@
* be incorporated into the next SCTP release.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index bef13373168..faf71d179e4 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -43,6 +43,7 @@
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/in.h>
#include <net/sock.h>
#include <net/ipv6.h>
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 8e4320040f0..3eab6db59a3 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -42,6 +42,7 @@
#include <linux/net.h>
#include <linux/inet.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 905fda582b9..7ec09ba03a1 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -144,6 +144,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
/* Use SCTP specific send buffer space queues. */
ep->sndbuf_policy = sctp_sndbuf_policy;
+ sk->sk_data_ready = sctp_data_ready;
sk->sk_write_space = sctp_write_space;
sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
diff --git a/net/sctp/input.c b/net/sctp/input.c
index c0c973e67ad..2a570184e5a 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -53,6 +53,7 @@
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/time.h> /* For struct timeval */
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/snmp.h>
@@ -75,7 +76,7 @@ static struct sctp_association *__sctp_lookup_association(
const union sctp_addr *peer,
struct sctp_transport **pt);
-static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
+static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
/* Calculate the SCTP checksum of an SCTP packet. */
@@ -265,8 +266,13 @@ int sctp_rcv(struct sk_buff *skb)
}
if (sock_owned_by_user(sk)) {
+ if (sctp_add_backlog(sk, skb)) {
+ sctp_bh_unlock_sock(sk);
+ sctp_chunk_free(chunk);
+ skb = NULL; /* sctp_chunk_free already freed the skb */
+ goto discard_release;
+ }
SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG);
- sctp_add_backlog(sk, skb);
} else {
SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ);
sctp_inq_push(&chunk->rcvr->inqueue, chunk);
@@ -336,8 +342,10 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
sctp_bh_lock_sock(sk);
if (sock_owned_by_user(sk)) {
- sk_add_backlog(sk, skb);
- backloged = 1;
+ if (sk_add_backlog(sk, skb))
+ sctp_chunk_free(chunk);
+ else
+ backloged = 1;
} else
sctp_inq_push(inqueue, chunk);
@@ -362,22 +370,27 @@ done:
return 0;
}
-static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
+static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
{
struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
struct sctp_ep_common *rcvr = chunk->rcvr;
+ int ret;
- /* Hold the assoc/ep while hanging on the backlog queue.
- * This way, we know structures we need will not disappear from us
- */
- if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
- sctp_association_hold(sctp_assoc(rcvr));
- else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
- sctp_endpoint_hold(sctp_ep(rcvr));
- else
- BUG();
+ ret = sk_add_backlog(sk, skb);
+ if (!ret) {
+ /* Hold the assoc/ep while hanging on the backlog queue.
+ * This way, we know structures we need will not disappear
+ * from us
+ */
+ if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
+ sctp_association_hold(sctp_assoc(rcvr));
+ else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
+ sctp_endpoint_hold(sctp_ep(rcvr));
+ else
+ BUG();
+ }
+ return ret;
- sk_add_backlog(sk, skb);
}
/* Handle icmp frag needed error. */
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index bbf5dd2a97c..ccb6dc48d15 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -46,6 +46,7 @@
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
/* Initialize an SCTP inqueue. */
void sctp_inq_init(struct sctp_inq *queue)
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 1d7ac70ba39..9fb5d37c37a 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -58,6 +58,7 @@
#include <linux/netdevice.h>
#include <linux/init.h>
#include <linux/ipsec.h>
+#include <linux/slab.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 7c558936343..fad261d41ec 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -48,6 +48,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/inet_ecn.h>
#include <net/ip.h>
#include <net/icmp.h>
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 229690f02a1..abfc0b8dee7 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -50,6 +50,7 @@
#include <linux/list.h> /* For struct list_head */
#include <linux/socket.h>
#include <linux/ip.h>
+#include <linux/slab.h>
#include <net/sock.h> /* For skb_set_owner_w */
#include <net/sctp/sctp.h>
diff --git a/net/sctp/primitive.c b/net/sctp/primitive.c
index 8cb4f060bce..534c7eae9d1 100644
--- a/net/sctp/primitive.c
+++ b/net/sctp/primitive.c
@@ -50,6 +50,7 @@
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/time.h> /* For struct timeval */
+#include <linux/gfp.h>
#include <net/sock.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index e771690f6d5..a56f98e82f9 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -54,6 +54,7 @@
#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/swap.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/protocol.h>
#include <net/ip.h>
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 9e732916b67..0fd5b4c8835 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -58,6 +58,7 @@
#include <linux/inet.h>
#include <linux/scatterlist.h>
#include <linux/crypto.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/skbuff.h>
@@ -207,7 +208,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
sp = sctp_sk(asoc->base.sk);
num_types = sp->pf->supported_addrs(sp, types);
- chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types);
+ chunksize = sizeof(init) + addrs_len;
+ chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types));
chunksize += sizeof(ecap_param);
if (sctp_prsctp_enable)
@@ -237,14 +239,14 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
/* Add HMACS parameter length if any were defined */
auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
if (auth_hmacs->length)
- chunksize += ntohs(auth_hmacs->length);
+ chunksize += WORD_ROUND(ntohs(auth_hmacs->length));
else
auth_hmacs = NULL;
/* Add CHUNKS parameter length */
auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
if (auth_chunks->length)
- chunksize += ntohs(auth_chunks->length);
+ chunksize += WORD_ROUND(ntohs(auth_chunks->length));
else
auth_chunks = NULL;
@@ -254,7 +256,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
/* If we have any extensions to report, account for that */
if (num_ext)
- chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
+ chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) +
+ num_ext);
/* RFC 2960 3.3.2 Initiation (INIT) (1)
*
@@ -396,13 +399,13 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
if (auth_hmacs->length)
- chunksize += ntohs(auth_hmacs->length);
+ chunksize += WORD_ROUND(ntohs(auth_hmacs->length));
else
auth_hmacs = NULL;
auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
if (auth_chunks->length)
- chunksize += ntohs(auth_chunks->length);
+ chunksize += WORD_ROUND(ntohs(auth_chunks->length));
else
auth_chunks = NULL;
@@ -411,7 +414,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
}
if (num_ext)
- chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
+ chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) +
+ num_ext);
/* Now allocate and fill out the chunk. */
retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
@@ -3314,21 +3318,6 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
sctp_chunk_free(asconf);
asoc->addip_last_asconf = NULL;
- /* Send the next asconf chunk from the addip chunk queue. */
- if (!list_empty(&asoc->addip_chunk_list)) {
- struct list_head *entry = asoc->addip_chunk_list.next;
- asconf = list_entry(entry, struct sctp_chunk, list);
-
- list_del_init(entry);
-
- /* Hold the chunk until an ASCONF_ACK is received. */
- sctp_chunk_hold(asconf);
- if (sctp_primitive_ASCONF(asoc, asconf))
- sctp_chunk_free(asconf);
- else
- asoc->addip_last_asconf = asconf;
- }
-
return retval;
}
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 4e4ca65cd32..d5ae450b6f0 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -51,6 +51,7 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/ip.h>
+#include <linux/gfp.h>
#include <net/sock.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
@@ -475,7 +476,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
* used to provide an upper bound to this doubling operation.
*
* Special Case: the first HB doesn't trigger exponential backoff.
- * The first unacknowleged HB triggers it. We do this with a flag
+ * The first unacknowledged HB triggers it. We do this with a flag
* that indicates that we have an outstanding HB.
*/
if (!is_hb || transport->hb_sent) {
@@ -961,6 +962,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc,
}
+/* Sent the next ASCONF packet currently stored in the association.
+ * This happens after the ASCONF_ACK was succeffully processed.
+ */
+static void sctp_cmd_send_asconf(struct sctp_association *asoc)
+{
+ /* Send the next asconf chunk from the addip chunk
+ * queue.
+ */
+ if (!list_empty(&asoc->addip_chunk_list)) {
+ struct list_head *entry = asoc->addip_chunk_list.next;
+ struct sctp_chunk *asconf = list_entry(entry,
+ struct sctp_chunk, list);
+ list_del_init(entry);
+
+ /* Hold the chunk until an ASCONF_ACK is received. */
+ sctp_chunk_hold(asconf);
+ if (sctp_primitive_ASCONF(asoc, asconf))
+ sctp_chunk_free(asconf);
+ else
+ asoc->addip_last_asconf = asconf;
+ }
+}
+
/* These three macros allow us to pull the debugging code out of the
* main flow of sctp_do_sm() to keep attention focused on the real
@@ -1616,6 +1640,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
}
error = sctp_cmd_send_msg(asoc, cmd->obj.msg);
break;
+ case SCTP_CMD_SEND_NEXT_ASCONF:
+ sctp_cmd_send_asconf(asoc);
+ break;
default:
printk(KERN_WARNING "Impossible command: %u, %p\n",
cmd->verb, cmd->obj.ptr);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 47bc20d3a85..24b2cd55563 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -56,6 +56,7 @@
#include <linux/ipv6.h>
#include <linux/net.h>
#include <linux/inet.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/inet_ecn.h>
#include <linux/skbuff.h>
@@ -3675,8 +3676,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
- asconf_ack))
+ asconf_ack)) {
+ /* Successfully processed ASCONF_ACK. We can
+ * release the next asconf if we have one.
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF,
+ SCTP_NULL());
return SCTP_DISPOSITION_CONSUME;
+ }
abort = sctp_make_abort(asoc, asconf_ack,
sizeof(sctp_errhdr_t));
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index f6d1e59c415..44a1ab03a3f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -67,6 +67,7 @@
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/crypto.h>
+#include <linux/slab.h>
#include <net/ip.h>
#include <net/icmp.h>
@@ -3718,9 +3719,12 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
sp->hmac = NULL;
SCTP_DBG_OBJCNT_INC(sock);
- percpu_counter_inc(&sctp_sockets_allocated);
+
+ /* Set socket backlog limit. */
+ sk->sk_backlog.limit = sysctl_sctp_rmem[1];
local_bh_disable();
+ percpu_counter_inc(&sctp_sockets_allocated);
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
local_bh_enable();
@@ -3737,8 +3741,8 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
/* Release our hold on the endpoint. */
ep = sctp_sk(sk)->ep;
sctp_endpoint_free(ep);
- percpu_counter_dec(&sctp_sockets_allocated);
local_bh_disable();
+ percpu_counter_dec(&sctp_sockets_allocated);
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
local_bh_enable();
}
@@ -6185,6 +6189,16 @@ do_nonblock:
goto out;
}
+void sctp_data_ready(struct sock *sk, int len)
+{
+ read_lock_bh(&sk->sk_callback_lock);
+ if (sk_has_sleeper(sk))
+ wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN |
+ POLLRDNORM | POLLRDBAND);
+ sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
+ read_unlock_bh(&sk->sk_callback_lock);
+}
+
/* If socket sndbuf has changed, wake up all per association waiters. */
void sctp_write_space(struct sock *sk)
{
diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
index 737d330e5ff..442ad4ed631 100644
--- a/net/sctp/ssnmap.c
+++ b/net/sctp/ssnmap.c
@@ -37,6 +37,7 @@
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index b827d21dbe5..be4d63d5a5c 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -48,6 +48,7 @@
* be incorporated into the next SCTP release.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/random.h>
#include <net/sctp/sctp.h>
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
index 9bd64565021..747d5412c46 100644
--- a/net/sctp/tsnmap.c
+++ b/net/sctp/tsnmap.c
@@ -42,6 +42,7 @@
* be incorporated into the next SCTP release.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/bitmap.h>
#include <net/sctp/sctp.h>
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 8b3560fd876..aa72e89c3ee 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -43,6 +43,7 @@
* be incorporated into the next SCTP release.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <net/sctp/structs.h>
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 7b23803343c..3a448536f0b 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -41,6 +41,7 @@
* be incorporated into the next SCTP release.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <net/sock.h>
diff --git a/net/socket.c b/net/socket.c
index 769c386bd42..5e8d0af3c0e 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -87,6 +87,7 @@
#include <linux/wireless.h>
#include <linux/nsproxy.h>
#include <linux/magic.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -2135,6 +2136,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
break;
++datagrams;
+ /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
+ if (flags & MSG_WAITFORONE)
+ flags |= MSG_DONTWAIT;
+
if (timeout) {
ktime_get_ts(timeout);
*timeout = timespec_sub(end_time, *timeout);
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
index 6dcdd251781..1419d0cdbba 100644
--- a/net/sunrpc/addr.c
+++ b/net/sunrpc/addr.c
@@ -18,6 +18,7 @@
#include <net/ipv6.h>
#include <linux/sunrpc/clnt.h>
+#include <linux/slab.h>
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -71,8 +72,9 @@ static size_t rpc_ntop6(const struct sockaddr *sap,
if (unlikely(len == 0))
return len;
- if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
- !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL))
+ if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
+ return len;
+ if (sin6->sin6_scope_id == 0)
return len;
rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u",
@@ -165,8 +167,7 @@ static int rpc_parse_scope_id(const char *buf, const size_t buflen,
if (*delim != IPV6_SCOPE_DELIMITER)
return 0;
- if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
- !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL))
+ if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
return 0;
len = (buf + buflen) - delim - 1;
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index f394fc190a4..95afe79dd9d 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -237,7 +237,7 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) {
/* Enforce a 60 second garbage collection moratorium */
- if (time_in_range_open(cred->cr_expire, expired, jiffies) &&
+ if (time_in_range(cred->cr_expire, expired, jiffies) &&
test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
continue;
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index bf88bf8e936..8f623b0f03d 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -5,6 +5,7 @@
*/
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/sched.h>
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index f7a7f8380e3..c389ccf6437 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -206,8 +206,14 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
ctx->gc_win = window_size;
/* gssd signals an error by passing ctx->gc_win = 0: */
if (ctx->gc_win == 0) {
- /* in which case, p points to an error code which we ignore */
- p = ERR_PTR(-EACCES);
+ /*
+ * in which case, p points to an error code. Anything other
+ * than -EKEYEXPIRED gets converted to -EACCES.
+ */
+ p = simple_get_bytes(p, end, &ret, sizeof(ret));
+ if (!IS_ERR(p))
+ p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) :
+ ERR_PTR(-EACCES);
goto err;
}
/* copy the opaque wire context */
@@ -646,6 +652,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
err = PTR_ERR(p);
switch (err) {
case -EACCES:
+ case -EKEYEXPIRED:
gss_msg->msg.errno = err;
err = mlen;
break;
@@ -1273,9 +1280,8 @@ alloc_enc_pages(struct rpc_rqst *rqstp)
rqstp->rq_release_snd_buf = priv_release_snd_buf;
return 0;
out_free:
- for (i--; i >= 0; i--) {
- __free_page(rqstp->rq_enc_pages[i]);
- }
+ rqstp->rq_enc_pages_num = i;
+ priv_release_snd_buf(rqstp);
out:
return -EAGAIN;
}
diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c
index c0ba39c4f5f..310b78e9945 100644
--- a/net/sunrpc/auth_gss/gss_generic_token.c
+++ b/net/sunrpc/auth_gss/gss_generic_token.c
@@ -33,7 +33,6 @@
#include <linux/types.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/gss_asn1.h>
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index c93fca20455..e9b63617668 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -37,7 +37,6 @@
#include <linux/err.h>
#include <linux/types.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index b8f42ef7178..88fe6e75ed7 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -59,7 +59,6 @@
*/
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/random.h>
diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
index 17562b4c35f..6331cd6866e 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
@@ -32,7 +32,6 @@
*/
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/crypto.h>
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 066ec73c84d..ce6c247edad 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -58,7 +58,6 @@
*/
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/crypto.h>
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index ae8e69b59c4..a6e905637e0 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -1,5 +1,4 @@
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/random.h>
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c
index c832712f8d5..5a3a65a0e2b 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_seal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c
@@ -34,7 +34,6 @@
*/
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/sunrpc/gss_spkm3.h>
#include <linux/random.h>
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index e34bc531fcb..b81e790ef9f 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -37,6 +37,7 @@
*
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pagemap.h>
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 46b2647c5bd..aac2f8b4ee2 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -6,6 +6,7 @@
* Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/module.h>
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
index 553621fb2c4..cf06af3b63c 100644
--- a/net/sunrpc/backchannel_rqst.c
+++ b/net/sunrpc/backchannel_rqst.c
@@ -22,6 +22,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#include <linux/tcp.h>
+#include <linux/slab.h>
#include <linux/sunrpc/xprt.h>
#ifdef RPC_DEBUG
diff --git a/net/sunrpc/bc_svc.c b/net/sunrpc/bc_svc.c
index 13f214f5312..f0c05d3311c 100644
--- a/net/sunrpc/bc_svc.c
+++ b/net/sunrpc/bc_svc.c
@@ -37,21 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define RPCDBG_FACILITY RPCDBG_SVCDSP
-void bc_release_request(struct rpc_task *task)
-{
- struct rpc_rqst *req = task->tk_rqstp;
-
- dprintk("RPC: bc_release_request: task= %p\n", task);
-
- /*
- * Release this request only if it's a backchannel
- * preallocated request
- */
- if (!bc_prealloc(req))
- return;
- xprt_free_bc_request(req);
-}
-
/* Empty callback ops */
static const struct rpc_call_ops nfs41_callback_ops = {
};
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 154034b675b..19c9983d536 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -659,6 +659,7 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
task = rpc_new_task(&task_setup_data);
if (!task) {
xprt_free_bc_request(req);
+ task = ERR_PTR(-ENOMEM);
goto out;
}
task->tk_rqstp = req;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 8d63f8fd29b..20e30c6f835 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -587,6 +587,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
struct dentry *dentry;
dentry = __rpc_lookup_create(parent, name);
+ if (IS_ERR(dentry))
+ return dentry;
if (dentry->d_inode == NULL)
return dentry;
dput(dentry);
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 3e3772d8eb9..121105355f6 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <net/ipv6.h>
#include <linux/sunrpc/clnt.h>
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index a661a3acb37..10b4319ebbc 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -8,6 +8,7 @@
#include <linux/compiler.h>
#include <linux/netdevice.h>
+#include <linux/gfp.h>
#include <linux/skbuff.h>
#include <linux/types.h>
#include <linux/pagemap.h>
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 1b4e6791ecf..5785d2037f4 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -13,6 +13,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kernel.h>
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 538ca433a56..d9017d64597 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/xdr.h>
@@ -133,7 +134,7 @@ svc_pool_map_choose_mode(void)
return SVC_POOL_PERNODE;
}
- node = any_online_node(node_online_map);
+ node = first_online_node;
if (nr_cpus_node(node) > 2) {
/*
* Non-trivial SMP, or CONFIG_NUMA on
@@ -506,6 +507,10 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
{
unsigned int pages, arghi;
+ /* bc_xprt uses fore channel allocated buffers */
+ if (svc_is_backchannel(rqstp))
+ return 1;
+
pages = size / PAGE_SIZE + 1; /* extra page as we hold both request and reply.
* We assume one is at most one page
*/
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 7d1f9e928f6..061b2e0f911 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/svc_xprt.h>
@@ -173,11 +174,13 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
.sin_addr.s_addr = htonl(INADDR_ANY),
.sin_port = htons(port),
};
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct sockaddr_in6 sin6 = {
.sin6_family = AF_INET6,
.sin6_addr = IN6ADDR_ANY_INIT,
.sin6_port = htons(port),
};
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
struct sockaddr *sap;
size_t len;
@@ -186,10 +189,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
sap = (struct sockaddr *)&sin;
len = sizeof(sin);
break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case PF_INET6:
sap = (struct sockaddr *)&sin6;
len = sizeof(sin6);
break;
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
default:
return ERR_PTR(-EAFNOSUPPORT);
}
@@ -231,7 +236,10 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
err:
spin_unlock(&svc_xprt_class_lock);
dprintk("svc: transport %s not found\n", xprt_name);
- return -ENOENT;
+
+ /* This errno is exposed to user space. Provide a reasonable
+ * perror msg for a bad transport. */
+ return -EPROTONOSUPPORT;
}
EXPORT_SYMBOL_GPL(svc_create_xprt);
@@ -699,8 +707,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
spin_unlock_bh(&pool->sp_lock);
len = 0;
- if (test_bit(XPT_LISTENER, &xprt->xpt_flags) &&
- !test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
+ if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
+ dprintk("svc_recv: found XPT_CLOSE\n");
+ svc_delete_xprt(xprt);
+ } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
struct svc_xprt *newxpt;
newxpt = xprt->xpt_ops->xpo_accept(xprt);
if (newxpt) {
@@ -726,7 +736,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
svc_xprt_received(newxpt);
}
svc_xprt_received(xprt);
- } else if (!test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
+ } else {
dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
rqstp, pool->sp_id, xprt,
atomic_read(&xprt->xpt_ref.refcount));
@@ -739,11 +749,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
dprintk("svc: got len=%d\n", len);
}
- if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
- dprintk("svc_recv: found XPT_CLOSE\n");
- svc_delete_xprt(xprt);
- }
-
/* No data, incomplete (TCP) read, or accept() */
if (len == 0 || len == -EAGAIN) {
rqstp->rq_res.len = 0;
@@ -889,11 +894,8 @@ void svc_delete_xprt(struct svc_xprt *xprt)
if (test_bit(XPT_TEMP, &xprt->xpt_flags))
serv->sv_tmpcnt--;
- for (dr = svc_deferred_dequeue(xprt); dr;
- dr = svc_deferred_dequeue(xprt)) {
- svc_xprt_put(xprt);
+ while ((dr = svc_deferred_dequeue(xprt)) != NULL)
kfree(dr);
- }
svc_xprt_put(xprt);
spin_unlock_bh(&serv->sv_lock);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index d8c04111449..20731161098 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -10,11 +10,13 @@
#include <linux/seq_file.h>
#include <linux/hash.h>
#include <linux/string.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/ipv6.h>
#include <linux/kernel.h>
#define RPCDBG_FACILITY RPCDBG_AUTH
+#include <linux/sunrpc/clnt.h>
/*
* AUTHUNIX and AUTHNULL credentials are both handled here.
@@ -187,10 +189,13 @@ static int ip_map_parse(struct cache_detail *cd,
* for scratch: */
char *buf = mesg;
int len;
- int b1, b2, b3, b4, b5, b6, b7, b8;
- char c;
char class[8];
- struct in6_addr addr;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in s4;
+ struct sockaddr_in6 s6;
+ } address;
+ struct sockaddr_in6 sin6;
int err;
struct ip_map *ipmp;
@@ -209,24 +214,24 @@ static int ip_map_parse(struct cache_detail *cd,
len = qword_get(&mesg, buf, mlen);
if (len <= 0) return -EINVAL;
- if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) == 4) {
- addr.s6_addr32[0] = 0;
- addr.s6_addr32[1] = 0;
- addr.s6_addr32[2] = htonl(0xffff);
- addr.s6_addr32[3] =
- htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
- } else if (sscanf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x%c",
- &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
- addr.s6_addr16[0] = htons(b1);
- addr.s6_addr16[1] = htons(b2);
- addr.s6_addr16[2] = htons(b3);
- addr.s6_addr16[3] = htons(b4);
- addr.s6_addr16[4] = htons(b5);
- addr.s6_addr16[5] = htons(b6);
- addr.s6_addr16[6] = htons(b7);
- addr.s6_addr16[7] = htons(b8);
- } else
+ if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0)
return -EINVAL;
+ switch (address.sa.sa_family) {
+ case AF_INET:
+ /* Form a mapped IPv4 address in sin6 */
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
+ sin6.sin6_addr.s6_addr32[3] = address.s4.sin_addr.s_addr;
+ break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ case AF_INET6:
+ memcpy(&sin6, &address.s6, sizeof(sin6));
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
expiry = get_expiry(&mesg);
if (expiry ==0)
@@ -243,7 +248,8 @@ static int ip_map_parse(struct cache_detail *cd,
} else
dom = NULL;
- ipmp = ip_map_lookup(class, &addr);
+ /* IPv6 scope IDs are ignored for now */
+ ipmp = ip_map_lookup(class, &sin6.sin6_addr);
if (ipmp) {
err = ip_map_update(ipmp,
container_of(dom, struct unix_domain, h),
@@ -619,7 +625,7 @@ static int unix_gid_show(struct seq_file *m,
else
glen = 0;
- seq_printf(m, "%d %d:", ug->uid, glen);
+ seq_printf(m, "%u %d:", ug->uid, glen);
for (i = 0; i < glen; i++)
seq_printf(m, " %d", GROUP_AT(ug->gi, i));
seq_printf(m, "\n");
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 870929e08e5..a29f259204e 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -968,6 +968,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
return len;
err_delete:
set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
+ svc_xprt_received(&svsk->sk_xprt);
err_again:
return -EAGAIN;
}
@@ -1357,7 +1358,7 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
if (!so)
return err;
- if (so->sk->sk_family != AF_INET)
+ if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6))
err = -EAFNOSUPPORT;
else if (so->sk->sk_protocol != IPPROTO_TCP &&
so->sk->sk_protocol != IPPROTO_UDP)
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 8bd690c48b6..2763fde8849 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -7,6 +7,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 469de292c23..42f09ade004 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -46,6 +46,7 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/metrics.h>
+#include <linux/sunrpc/bc_xprt.h>
#include "sunrpc.h"
@@ -1032,21 +1033,16 @@ void xprt_release(struct rpc_task *task)
if (req->rq_release_snd_buf)
req->rq_release_snd_buf(req);
- /*
- * Early exit if this is a backchannel preallocated request.
- * There is no need to have it added to the RPC slot list.
- */
- if (is_bc_request)
- return;
-
- memset(req, 0, sizeof(*req)); /* mark unused */
-
dprintk("RPC: %5u release request %p\n", task->tk_pid, req);
+ if (likely(!is_bc_request)) {
+ memset(req, 0, sizeof(*req)); /* mark unused */
- spin_lock(&xprt->reserve_lock);
- list_add(&req->rq_list, &xprt->free);
- rpc_wake_up_next(&xprt->backlog);
- spin_unlock(&xprt->reserve_lock);
+ spin_lock(&xprt->reserve_lock);
+ list_add(&req->rq_list, &xprt->free);
+ rpc_wake_up_next(&xprt->backlog);
+ spin_unlock(&xprt->reserve_lock);
+ } else
+ xprt_free_bc_request(req);
}
/**
diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
index 5b8a8ff93a2..d718b8fa952 100644
--- a/net/sunrpc/xprtrdma/svc_rdma.c
+++ b/net/sunrpc/xprtrdma/svc_rdma.c
@@ -40,6 +40,7 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/sysctl.h>
#include <linux/sunrpc/clnt.h>
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 3fa5751af0e..edea15a54e5 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -43,6 +43,7 @@
#include <linux/sunrpc/debug.h>
#include <linux/sunrpc/rpc_rdma.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <rdma/ib_verbs.h>
#include <rdma/rdma_cm.h>
@@ -678,7 +679,10 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
int ret;
dprintk("svcrdma: Creating RDMA socket\n");
-
+ if (sa->sa_family != AF_INET) {
+ dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family);
+ return ERR_PTR(-EAFNOSUPPORT);
+ }
cma_xprt = rdma_create_xprt(serv, 1);
if (!cma_xprt)
return ERR_PTR(-ENOMEM);
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 7018eef1dcd..187257b1d88 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -49,6 +49,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/seq_file.h>
#include "xprt_rdma.h"
@@ -160,16 +161,15 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt)
(void)rpc_ntop(sap, buf, sizeof(buf));
xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL);
- (void)snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap));
+ snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap));
xprt->address_strings[RPC_DISPLAY_PORT] = kstrdup(buf, GFP_KERNEL);
xprt->address_strings[RPC_DISPLAY_PROTO] = "rdma";
- (void)snprintf(buf, sizeof(buf), "%02x%02x%02x%02x",
- NIPQUAD(sin->sin_addr.s_addr));
+ snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr));
xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL);
- (void)snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap));
+ snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap));
xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);
/* netid */
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 2209aa87d89..27015c6d8eb 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -48,6 +48,7 @@
*/
#include <linux/pci.h> /* for Tavor hack below */
+#include <linux/slab.h>
#include "xprt_rdma.h"
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 3d739e5d15d..9847c30b500 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -297,12 +297,11 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt)
switch (sap->sa_family) {
case AF_INET:
sin = xs_addr_in(xprt);
- (void)snprintf(buf, sizeof(buf), "%02x%02x%02x%02x",
- NIPQUAD(sin->sin_addr.s_addr));
+ snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr));
break;
case AF_INET6:
sin6 = xs_addr_in6(xprt);
- (void)snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr);
+ snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr);
break;
default:
BUG();
@@ -315,10 +314,10 @@ static void xs_format_common_peer_ports(struct rpc_xprt *xprt)
struct sockaddr *sap = xs_addr(xprt);
char buf[128];
- (void)snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap));
+ snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap));
xprt->address_strings[RPC_DISPLAY_PORT] = kstrdup(buf, GFP_KERNEL);
- (void)snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap));
+ snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap));
xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);
}
@@ -549,8 +548,6 @@ static int xs_udp_send_request(struct rpc_task *task)
/* Still some bytes left; set up for a retry later. */
status = -EAGAIN;
}
- if (!transport->sock)
- goto out;
switch (status) {
case -ENOTSOCK:
@@ -570,7 +567,7 @@ static int xs_udp_send_request(struct rpc_task *task)
* prompts ECONNREFUSED. */
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
}
-out:
+
return status;
}
@@ -652,8 +649,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
status = -EAGAIN;
break;
}
- if (!transport->sock)
- goto out;
switch (status) {
case -ENOTSOCK:
@@ -673,7 +668,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
case -ENOTCONN:
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
}
-out:
+
return status;
}
@@ -1912,6 +1907,11 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt,
case -EALREADY:
xprt_clear_connecting(xprt);
return;
+ case -EINVAL:
+ /* Happens, for instance, if the user specified a link
+ * local IPv6 address without a scope-id.
+ */
+ goto out;
}
out_eagain:
status = -EAGAIN;
@@ -2100,7 +2100,7 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
* we allocate pages instead doing a kmalloc like rpc_malloc is because we want
* to use the server side send routines.
*/
-void *bc_malloc(struct rpc_task *task, size_t size)
+static void *bc_malloc(struct rpc_task *task, size_t size)
{
struct page *page;
struct rpc_buffer *buf;
@@ -2120,7 +2120,7 @@ void *bc_malloc(struct rpc_task *task, size_t size)
/*
* Free the space allocated in the bc_alloc routine
*/
-void bc_free(void *buffer)
+static void bc_free(void *buffer)
{
struct rpc_buffer *buf;
@@ -2251,9 +2251,6 @@ static struct rpc_xprt_ops xs_tcp_ops = {
.buf_free = rpc_free,
.send_request = xs_tcp_send_request,
.set_retrans_timeout = xprt_set_retrans_timeout_def,
-#if defined(CONFIG_NFS_V4_1)
- .release_request = bc_release_request,
-#endif /* CONFIG_NFS_V4_1 */
.close = xs_tcp_close,
.destroy = xs_destroy,
.print_stats = xs_tcp_print_stats,
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 327011fcc40..78091375ca1 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -45,10 +45,10 @@
#define MAX_ADDR_STR 32
-static struct media *media_list = NULL;
+static struct media media_list[MAX_MEDIA];
static u32 media_count = 0;
-struct bearer *tipc_bearers = NULL;
+struct bearer tipc_bearers[MAX_BEARERS];
/**
* media_name_valid - validate media name
@@ -108,9 +108,11 @@ int tipc_register_media(u32 media_type,
int res = -EINVAL;
write_lock_bh(&tipc_net_lock);
- if (!media_list)
- goto exit;
+ if (tipc_mode != TIPC_NET_MODE) {
+ warn("Media <%s> rejected, not in networked mode yet\n", name);
+ goto exit;
+ }
if (!media_name_valid(name)) {
warn("Media <%s> rejected, illegal name\n", name);
goto exit;
@@ -660,33 +662,10 @@ int tipc_disable_bearer(const char *name)
-int tipc_bearer_init(void)
-{
- int res;
-
- write_lock_bh(&tipc_net_lock);
- tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC);
- media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC);
- if (tipc_bearers && media_list) {
- res = 0;
- } else {
- kfree(tipc_bearers);
- kfree(media_list);
- tipc_bearers = NULL;
- media_list = NULL;
- res = -ENOMEM;
- }
- write_unlock_bh(&tipc_net_lock);
- return res;
-}
-
void tipc_bearer_stop(void)
{
u32 i;
- if (!tipc_bearers)
- return;
-
for (i = 0; i < MAX_BEARERS; i++) {
if (tipc_bearers[i].active)
tipc_bearers[i].publ.blocked = 1;
@@ -695,10 +674,6 @@ void tipc_bearer_stop(void)
if (tipc_bearers[i].active)
bearer_disable(tipc_bearers[i].publ.name);
}
- kfree(tipc_bearers);
- kfree(media_list);
- tipc_bearers = NULL;
- media_list = NULL;
media_count = 0;
}
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index ca573489271..000228e93f9 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -114,7 +114,7 @@ struct bearer_name {
struct link;
-extern struct bearer *tipc_bearers;
+extern struct bearer tipc_bearers[];
void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
struct sk_buff *tipc_media_get_names(void);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index a881f92a853..c58a1d16563 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -56,6 +56,7 @@
#include <linux/netdevice.h>
#include <linux/in.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
/*
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 524ba5696d4..6230d16020c 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -38,6 +38,7 @@
#include <net/tipc/tipc_bearer.h>
#include <net/tipc/tipc_msg.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#define MAX_ETH_BEARERS 2
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 6f50f6423f6..1a7e4665af8 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1882,6 +1882,15 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
(msg_destnode(msg) != tipc_own_addr)))
goto cont;
+ /* Discard non-routeable messages destined for another node */
+
+ if (unlikely(!msg_isdata(msg) &&
+ (msg_destnode(msg) != tipc_own_addr))) {
+ if ((msg_user(msg) != CONN_MANAGER) &&
+ (msg_user(msg) != MSG_FRAGMENTER))
+ goto cont;
+ }
+
/* Locate unicast link endpoint that should handle message */
n_ptr = tipc_node_find(msg_prevnode(msg));
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 7906608bf51..f25b1cdb64e 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -116,7 +116,8 @@
*/
DEFINE_RWLOCK(tipc_net_lock);
-struct network tipc_net = { NULL };
+struct _zone *tipc_zones[256] = { NULL, };
+struct network tipc_net = { tipc_zones };
struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref)
{
@@ -158,28 +159,12 @@ void tipc_net_send_external_routes(u32 dest)
}
}
-static int net_init(void)
-{
- memset(&tipc_net, 0, sizeof(tipc_net));
- tipc_net.zones = kcalloc(tipc_max_zones + 1, sizeof(struct _zone *), GFP_ATOMIC);
- if (!tipc_net.zones) {
- return -ENOMEM;
- }
- return 0;
-}
-
static void net_stop(void)
{
u32 z_num;
- if (!tipc_net.zones)
- return;
-
- for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
+ for (z_num = 1; z_num <= tipc_max_zones; z_num++)
tipc_zone_delete(tipc_net.zones[z_num]);
- }
- kfree(tipc_net.zones);
- tipc_net.zones = NULL;
}
static void net_route_named_msg(struct sk_buff *buf)
@@ -282,9 +267,7 @@ int tipc_net_start(u32 addr)
tipc_named_reinit();
tipc_port_reinit();
- if ((res = tipc_bearer_init()) ||
- (res = net_init()) ||
- (res = tipc_cltr_init()) ||
+ if ((res = tipc_cltr_init()) ||
(res = tipc_bclink_init())) {
return res;
}
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 414fc34b8be..8dea66500cf 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -153,11 +153,11 @@ void tipc_ref_table_stop(void)
u32 tipc_ref_acquire(void *object, spinlock_t **lock)
{
- struct reference *entry;
u32 index;
u32 index_mask;
u32 next_plus_upper;
u32 ref;
+ struct reference *entry = NULL;
if (!object) {
err("Attempt to acquire reference to non-existent object\n");
@@ -175,30 +175,36 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
index = tipc_ref_table.first_free;
entry = &(tipc_ref_table.entries[index]);
index_mask = tipc_ref_table.index_mask;
- /* take lock in case a previous user of entry still holds it */
- spin_lock_bh(&entry->lock);
next_plus_upper = entry->ref;
tipc_ref_table.first_free = next_plus_upper & index_mask;
ref = (next_plus_upper & ~index_mask) + index;
- entry->ref = ref;
- entry->object = object;
- *lock = &entry->lock;
}
else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
index = tipc_ref_table.init_point++;
entry = &(tipc_ref_table.entries[index]);
spin_lock_init(&entry->lock);
- spin_lock_bh(&entry->lock);
ref = tipc_ref_table.start_mask + index;
- entry->ref = ref;
- entry->object = object;
- *lock = &entry->lock;
}
else {
ref = 0;
}
write_unlock_bh(&ref_table_lock);
+ /*
+ * Grab the lock so no one else can modify this entry
+ * While we assign its ref value & object pointer
+ */
+ if (entry) {
+ spin_lock_bh(&entry->lock);
+ entry->ref = ref;
+ entry->object = object;
+ *lock = &entry->lock;
+ /*
+ * keep it locked, the caller is responsible
+ * for unlocking this when they're done with it
+ */
+ }
+
return ref;
}
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 1ea64f09cc4..cfb20b80b3a 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -40,9 +40,9 @@
#include <linux/socket.h>
#include <linux/errno.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
+#include <linux/gfp.h>
#include <asm/string.h>
#include <asm/atomic.h>
#include <net/sock.h>
@@ -1322,8 +1322,10 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
if (!sock_owned_by_user(sk)) {
res = filter_rcv(sk, buf);
} else {
- sk_add_backlog(sk, buf);
- res = TIPC_OK;
+ if (sk_add_backlog(sk, buf))
+ res = TIPC_ERR_OVERLOAD;
+ else
+ res = TIPC_OK;
}
bh_unlock_sock(sk);
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index ac91f0dfa14..ff123e56114 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -76,19 +76,6 @@ struct top_srv {
static struct top_srv topsrv = { 0 };
/**
- * htohl - convert value to endianness used by destination
- * @in: value to convert
- * @swap: non-zero if endianness must be reversed
- *
- * Returns converted value
- */
-
-static u32 htohl(u32 in, int swap)
-{
- return swap ? swab32(in) : in;
-}
-
-/**
* subscr_send_event - send a message containing a tipc_event to the subscriber
*
* Note: Must not hold subscriber's server port lock, since tipc_send() will
@@ -107,11 +94,11 @@ static void subscr_send_event(struct subscription *sub,
msg_sect.iov_base = (void *)&sub->evt;
msg_sect.iov_len = sizeof(struct tipc_event);
- sub->evt.event = htohl(event, sub->swap);
- sub->evt.found_lower = htohl(found_lower, sub->swap);
- sub->evt.found_upper = htohl(found_upper, sub->swap);
- sub->evt.port.ref = htohl(port_ref, sub->swap);
- sub->evt.port.node = htohl(node, sub->swap);
+ sub->evt.event = htonl(event);
+ sub->evt.found_lower = htonl(found_lower);
+ sub->evt.found_upper = htonl(found_upper);
+ sub->evt.port.ref = htonl(port_ref);
+ sub->evt.port.node = htonl(node);
tipc_send(sub->server_ref, 1, &msg_sect);
}
@@ -287,16 +274,23 @@ static void subscr_cancel(struct tipc_subscr *s,
{
struct subscription *sub;
struct subscription *sub_temp;
+ __u32 type, lower, upper;
int found = 0;
/* Find first matching subscription, exit if not found */
+ type = ntohl(s->seq.type);
+ lower = ntohl(s->seq.lower);
+ upper = ntohl(s->seq.upper);
+
list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
subscription_list) {
- if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
- found = 1;
- break;
- }
+ if ((type == sub->seq.type) &&
+ (lower == sub->seq.lower) &&
+ (upper == sub->seq.upper)) {
+ found = 1;
+ break;
+ }
}
if (!found)
return;
@@ -325,16 +319,10 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
struct subscriber *subscriber)
{
struct subscription *sub;
- int swap;
-
- /* Determine subscriber's endianness */
-
- swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
/* Detect & process a subscription cancellation request */
- if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
- s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
+ if (ntohl(s->filter) & TIPC_SUB_CANCEL) {
subscr_cancel(s, subscriber);
return NULL;
}
@@ -359,11 +347,11 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
/* Initialize subscription object */
- sub->seq.type = htohl(s->seq.type, swap);
- sub->seq.lower = htohl(s->seq.lower, swap);
- sub->seq.upper = htohl(s->seq.upper, swap);
- sub->timeout = htohl(s->timeout, swap);
- sub->filter = htohl(s->filter, swap);
+ sub->seq.type = ntohl(s->seq.type);
+ sub->seq.lower = ntohl(s->seq.lower);
+ sub->seq.upper = ntohl(s->seq.upper);
+ sub->timeout = ntohl(s->timeout);
+ sub->filter = ntohl(s->filter);
if ((!(sub->filter & TIPC_SUB_PORTS) ==
!(sub->filter & TIPC_SUB_SERVICE)) ||
(sub->seq.lower > sub->seq.upper)) {
@@ -376,7 +364,6 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
INIT_LIST_HEAD(&sub->nameseq_list);
list_add(&sub->subscription_list, &subscriber->subscription_list);
sub->server_ref = subscriber->port_ref;
- sub->swap = swap;
memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
atomic_inc(&topsrv.subscription_count);
if (sub->timeout != TIPC_WAIT_FOREVER) {
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 45d89bf4d20..c20f496d95b 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -53,7 +53,6 @@ typedef void (*tipc_subscr_event) (struct subscription *sub,
* @nameseq_list: adjacent subscriptions in name sequence's subscription list
* @subscription_list: adjacent subscriptions in subscriber's subscription list
* @server_ref: object reference of server port associated with subscription
- * @swap: indicates if subscriber uses opposite endianness in its messages
* @evt: template for events generated by subscription
*/
@@ -66,7 +65,6 @@ struct subscription {
struct list_head nameseq_list;
struct list_head subscription_list;
u32 server_ref;
- int swap;
struct tipc_event evt;
};
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 19c17e4a0c8..14c22c3768d 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -74,7 +74,6 @@
#include <linux/un.h>
#include <linux/net.h>
#include <linux/fs.h>
-#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/file.h>
diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
index d095c7be10d..397cffebb3b 100644
--- a/net/unix/sysctl_net_unix.c
+++ b/net/unix/sysctl_net_unix.c
@@ -10,6 +10,7 @@
*/
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/sysctl.h>
#include <net/af_unix.h>
diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index 7718657e93d..d5b7c3779c4 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -72,6 +72,7 @@
* wimax_msg_send()
*/
#include <linux/device.h>
+#include <linux/slab.h>
#include <net/genetlink.h>
#include <linux/netdevice.h>
#include <linux/wimax.h>
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 813e1eaea29..1ed65dbdab0 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -51,6 +51,7 @@
* wimax_rfkill_rm()
*/
#include <linux/device.h>
+#include <linux/gfp.h>
#include <net/genetlink.h>
#include <linux/netdevice.h>
#include <linux/wimax.h>
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 7fdb9409ad2..6ac70c10152 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/nl80211.h>
#include <linux/debugfs.h>
#include <linux/notifier.h>
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 2e489561503..a4991a3efec 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
#include "core.h"
#include "debugfs.h"
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 6ef5a491fb4..6a5acf75017 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -6,6 +6,7 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/cfg80211.h>
#include "wext-compat.h"
#include "nl80211.h"
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 62bc8855e12..22139fa4611 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/nl80211.h>
+#include <linux/slab.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <net/iw_handler.h>
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e447db04cf7..030cf153bea 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7,6 +7,7 @@
#include <linux/if.h>
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/if_ether.h>
#include <linux/ieee80211.h>
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ed89c59bb43..422da20d1e5 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -33,6 +33,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/random.h>
#include <linux/nl80211.h>
@@ -324,7 +325,7 @@ struct reg_regdb_search_request {
};
static LIST_HEAD(reg_regdb_search_list);
-static DEFINE_SPINLOCK(reg_regdb_search_lock);
+static DEFINE_MUTEX(reg_regdb_search_mutex);
static void reg_regdb_search(struct work_struct *work)
{
@@ -332,7 +333,7 @@ static void reg_regdb_search(struct work_struct *work)
const struct ieee80211_regdomain *curdom, *regdom;
int i, r;
- spin_lock(&reg_regdb_search_lock);
+ mutex_lock(&reg_regdb_search_mutex);
while (!list_empty(&reg_regdb_search_list)) {
request = list_first_entry(&reg_regdb_search_list,
struct reg_regdb_search_request,
@@ -346,18 +347,16 @@ static void reg_regdb_search(struct work_struct *work)
r = reg_copy_regd(&regdom, curdom);
if (r)
break;
- spin_unlock(&reg_regdb_search_lock);
mutex_lock(&cfg80211_mutex);
set_regdom(regdom);
mutex_unlock(&cfg80211_mutex);
- spin_lock(&reg_regdb_search_lock);
break;
}
}
kfree(request);
}
- spin_unlock(&reg_regdb_search_lock);
+ mutex_unlock(&reg_regdb_search_mutex);
}
static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
@@ -375,9 +374,9 @@ static void reg_regdb_query(const char *alpha2)
memcpy(request->alpha2, alpha2, 2);
- spin_lock(&reg_regdb_search_lock);
+ mutex_lock(&reg_regdb_search_mutex);
list_add_tail(&request->list, &reg_regdb_search_list);
- spin_unlock(&reg_regdb_search_lock);
+ mutex_unlock(&reg_regdb_search_mutex);
schedule_work(&reg_regdb_work);
}
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 978cac3414b..a026c6d56bd 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -4,6 +4,7 @@
* Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 17fde0da1b0..f4dfd5f5f2e 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -7,6 +7,7 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
diff --git a/net/wireless/util.c b/net/wireless/util.c
index be2ab8c59e3..d3574a4eb3b 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -5,6 +5,7 @@
*/
#include <linux/bitops.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <net/cfg80211.h>
#include <net/ip.h>
#include "core.h"
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 9ab51838849..a60a2773b49 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -12,6 +12,7 @@
#include <linux/nl80211.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
#include <net/cfg80211.h>
#include "wext-compat.h"
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 5e1656bdf23..4f5a47091fd 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/uaccess.h>
#include <net/cfg80211.h>
diff --git a/net/wireless/wext-priv.c b/net/wireless/wext-priv.c
index a3c2277de9e..3feb28e41c5 100644
--- a/net/wireless/wext-priv.c
+++ b/net/wireless/wext-priv.c
@@ -7,6 +7,7 @@
*
* (As all part of the Linux kernel, this file is GPL)
*/
+#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <net/iw_handler.h>
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 5615a880253..d5c6140f4cb 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -7,6 +7,7 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/cfg80211.h>
#include "wext-compat.h"
#include "nl80211.h"
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 9796f3ed1ed..36e84e13c6a 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -47,6 +47,7 @@
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/uaccess.h>
@@ -82,6 +83,41 @@ struct compat_x25_subscrip_struct {
};
#endif
+
+int x25_parse_address_block(struct sk_buff *skb,
+ struct x25_address *called_addr,
+ struct x25_address *calling_addr)
+{
+ unsigned char len;
+ int needed;
+ int rc;
+
+ if (skb->len < 1) {
+ /* packet has no address block */
+ rc = 0;
+ goto empty;
+ }
+
+ len = *skb->data;
+ needed = 1 + (len >> 4) + (len & 0x0f);
+
+ if (skb->len < needed) {
+ /* packet is too short to hold the addresses it claims
+ to hold */
+ rc = -1;
+ goto empty;
+ }
+
+ return x25_addr_ntoa(skb->data, called_addr, calling_addr);
+
+empty:
+ *called_addr->x25_addr = 0;
+ *calling_addr->x25_addr = 0;
+
+ return rc;
+}
+
+
int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
struct x25_address *calling_addr)
{
@@ -366,6 +402,7 @@ static void __x25_destroy_socket(struct sock *sk)
/*
* Queue the unaccepted socket for death
*/
+ skb->sk->sk_state = TCP_LISTEN;
sock_set_flag(skb->sk, SOCK_DEAD);
x25_start_heartbeat(skb->sk);
x25_sk(skb->sk)->state = X25_STATE_0;
@@ -553,7 +590,8 @@ static int x25_create(struct net *net, struct socket *sock, int protocol,
x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE;
x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
- x25->facilities.throughput = X25_DEFAULT_THROUGHPUT;
+ x25->facilities.throughput = 0; /* by default don't negotiate
+ throughput */
x25->facilities.reverse = X25_DEFAULT_REVERSE;
x25->dte_facilities.calling_len = 0;
x25->dte_facilities.called_len = 0;
@@ -921,16 +959,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
/*
* Extract the X.25 addresses and convert them to ASCII strings,
* and remove them.
+ *
+ * Address block is mandatory in call request packets
*/
- addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr);
+ addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
+ if (addr_len <= 0)
+ goto out_clear_request;
skb_pull(skb, addr_len);
/*
* Get the length of the facilities, skip past them for the moment
* get the call user data because this is needed to determine
* the correct listener
+ *
+ * Facilities length is mandatory in call request packets
*/
+ if (skb->len < 1)
+ goto out_clear_request;
len = skb->data[0] + 1;
+ if (skb->len < len)
+ goto out_clear_request;
skb_pull(skb,len);
/*
@@ -1414,9 +1462,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
if (facilities.winsize_in < 1 ||
facilities.winsize_in > 127)
break;
- if (facilities.throughput < 0x03 ||
- facilities.throughput > 0xDD)
- break;
+ if (facilities.throughput) {
+ int out = facilities.throughput & 0xf0;
+ int in = facilities.throughput & 0x0f;
+ if (!out)
+ facilities.throughput |=
+ X25_DEFAULT_THROUGHPUT << 4;
+ else if (out < 0x30 || out > 0xD0)
+ break;
+ if (!in)
+ facilities.throughput |=
+ X25_DEFAULT_THROUGHPUT;
+ else if (in < 0x03 || in > 0x0D)
+ break;
+ }
if (facilities.reverse &&
(facilities.reverse & 0x81) != 0x81)
break;
diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c
index 3e1efe53464..b9ef682230a 100644
--- a/net/x25/x25_dev.c
+++ b/net/x25/x25_dev.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <net/sock.h>
#include <linux/if_arp.h>
#include <net/x25.h>
@@ -53,7 +54,7 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb)
if (!sock_owned_by_user(sk)) {
queued = x25_process_rx_frame(sk, skb);
} else {
- sk_add_backlog(sk, skb);
+ queued = !sk_add_backlog(sk, skb);
}
bh_unlock_sock(sk);
sock_put(sk);
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index a21f6646eb3..771bab00754 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -35,7 +35,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
{
unsigned char *p = skb->data;
- unsigned int len = *p++;
+ unsigned int len;
*vc_fac_mask = 0;
@@ -50,6 +50,14 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
+ if (skb->len < 1)
+ return 0;
+
+ len = *p++;
+
+ if (len >= skb->len)
+ return -1;
+
while (len > 0) {
switch (*p & X25_FAC_CLASS_MASK) {
case X25_FAC_CLASS_A:
@@ -247,6 +255,8 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
memcpy(new, ours, sizeof(*new));
len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
+ if (len < 0)
+ return len;
/*
* They want reverse charging, we won't accept it.
@@ -259,9 +269,18 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
new->reverse = theirs.reverse;
if (theirs.throughput) {
- if (theirs.throughput < ours->throughput) {
- SOCK_DEBUG(sk, "X.25: throughput negotiated down\n");
- new->throughput = theirs.throughput;
+ int theirs_in = theirs.throughput & 0x0f;
+ int theirs_out = theirs.throughput & 0xf0;
+ int ours_in = ours->throughput & 0x0f;
+ int ours_out = ours->throughput & 0xf0;
+ if (!ours_in || theirs_in < ours_in) {
+ SOCK_DEBUG(sk, "X.25: inbound throughput negotiated\n");
+ new->throughput = (new->throughput & 0xf0) | theirs_in;
+ }
+ if (!ours_out || theirs_out < ours_out) {
+ SOCK_DEBUG(sk,
+ "X.25: outbound throughput negotiated\n");
+ new->throughput = (new->throughput & 0x0f) | theirs_out;
}
}
diff --git a/net/x25/x25_forward.c b/net/x25/x25_forward.c
index 056a55f3a87..25a81079396 100644
--- a/net/x25/x25_forward.c
+++ b/net/x25/x25_forward.c
@@ -10,6 +10,7 @@
*/
#include <linux/if_arp.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/x25.h>
LIST_HEAD(x25_forward_list);
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c
index 96d92278354..372ac226e64 100644
--- a/net/x25/x25_in.c
+++ b/net/x25/x25_in.c
@@ -23,6 +23,7 @@
* i-frames.
*/
+#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -89,6 +90,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{
struct x25_address source_addr, dest_addr;
+ int len;
switch (frametype) {
case X25_CALL_ACCEPTED: {
@@ -106,11 +108,17 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
* Parse the data in the frame.
*/
skb_pull(skb, X25_STD_MIN_LEN);
- skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
- skb_pull(skb,
- x25_parse_facilities(skb, &x25->facilities,
+
+ len = x25_parse_address_block(skb, &source_addr,
+ &dest_addr);
+ if (len > 0)
+ skb_pull(skb, len);
+
+ len = x25_parse_facilities(skb, &x25->facilities,
&x25->dte_facilities,
- &x25->vc_facil_mask));
+ &x25->vc_facil_mask);
+ if (len > 0)
+ skb_pull(skb, len);
/*
* Copy any Call User Data.
*/
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index e4e1b6e4953..73e7b954ad2 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <asm/uaccess.h>
diff --git a/net/x25/x25_out.c b/net/x25/x25_out.c
index 2b96b52114d..52351a26b6f 100644
--- a/net/x25/x25_out.c
+++ b/net/x25/x25_out.c
@@ -22,6 +22,7 @@
* needed cleaned seq-number fields.
*/
+#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/net/x25/x25_route.c b/net/x25/x25_route.c
index b95fae9ab39..97d77c532d8 100644
--- a/net/x25/x25_route.c
+++ b/net/x25/x25_route.c
@@ -19,6 +19,7 @@
#include <linux/if_arp.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <net/x25.h>
LIST_HEAD(x25_route_list);
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
index 352b32d216f..dc20cf12f39 100644
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -23,6 +23,7 @@
* restriction on response.
*/
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/skbuff.h>
diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
index 0fc5ff66d1f..fc91ad7ee26 100644
--- a/net/xfrm/xfrm_ipcomp.c
+++ b/net/xfrm/xfrm_ipcomp.c
@@ -17,11 +17,11 @@
#include <linux/crypto.h>
#include <linux/err.h>
-#include <linux/gfp.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/percpu.h>
+#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/vmalloc.h>
#include <net/ip.h>
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index b9fe13138c0..6a329158bdf 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -14,6 +14,7 @@
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <net/dst.h>
#include <net/xfrm.h>
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 34a5ef8316e..843e066649c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1372,7 +1372,8 @@ static inline int xfrm_init_path(struct xfrm_dst *path, struct dst_entry *dst,
return err;
}
-static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
+ struct flowi *fl)
{
struct xfrm_policy_afinfo *afinfo =
xfrm_policy_get_afinfo(xdst->u.dst.ops->family);
@@ -1381,7 +1382,7 @@ static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
if (!afinfo)
return -EINVAL;
- err = afinfo->fill_dst(xdst, dev);
+ err = afinfo->fill_dst(xdst, dev, fl);
xfrm_policy_put_afinfo(afinfo);
@@ -1486,7 +1487,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) {
struct xfrm_dst *xdst = (struct xfrm_dst *)dst_prev;
- err = xfrm_fill_dst(xdst, dev);
+ err = xfrm_fill_dst(xdst, dev, fl);
if (err)
goto free_dst;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 17d5b96f2fc..add77ecb8ac 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -22,6 +22,7 @@
#include <linux/audit.h>
#include <asm/uaccess.h>
#include <linux/ktime.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c
index 2c4d6cdcba4..05640bc9594 100644
--- a/net/xfrm/xfrm_sysctl.c
+++ b/net/xfrm/xfrm_sysctl.c
@@ -1,4 +1,5 @@
#include <linux/sysctl.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/xfrm.h>
diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c
index c69cbe9b242..bd0f337afca 100644
--- a/samples/hw_breakpoint/data_breakpoint.c
+++ b/samples/hw_breakpoint/data_breakpoint.c
@@ -34,7 +34,7 @@
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
-struct perf_event **sample_hbp;
+struct perf_event * __percpu *sample_hbp;
static char ksym_name[KSYM_NAME_LEN] = "pid_max";
module_param_string(ksym, ksym_name, KSYM_NAME_LEN, S_IRUGO);
@@ -61,8 +61,8 @@ static int __init hw_break_module_init(void)
attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
sample_hbp = register_wide_hw_breakpoint(&attr, sample_hbp_handler);
- if (IS_ERR(sample_hbp)) {
- ret = PTR_ERR(sample_hbp);
+ if (IS_ERR((void __force *)sample_hbp)) {
+ ret = PTR_ERR((void __force *)sample_hbp);
goto fail;
}
diff --git a/samples/kobject/kobject-example.c b/samples/kobject/kobject-example.c
index 8d9b55a1202..86ea0c3ad97 100644
--- a/samples/kobject/kobject-example.c
+++ b/samples/kobject/kobject-example.c
@@ -44,7 +44,7 @@ static struct kobj_attribute foo_attribute =
__ATTR(foo, 0666, foo_show, foo_store);
/*
- * More complex function where we determine which varible is being accessed by
+ * More complex function where we determine which variable is being accessed by
* looking at the attribute for the "baz" and "bar" files.
*/
static ssize_t b_show(struct kobject *kobj, struct kobj_attribute *attr,
@@ -79,7 +79,7 @@ static struct kobj_attribute bar_attribute =
/*
- * Create a group of attributes so that we can create and destory them all
+ * Create a group of attributes so that we can create and destroy them all
* at once.
*/
static struct attribute *attrs[] = {
diff --git a/samples/kobject/kset-example.c b/samples/kobject/kset-example.c
index 45b7d56fb54..d0c687fd980 100644
--- a/samples/kobject/kset-example.c
+++ b/samples/kobject/kset-example.c
@@ -10,6 +10,7 @@
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/sysfs.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -87,7 +88,7 @@ static ssize_t foo_attr_store(struct kobject *kobj,
}
/* Our custom sysfs_ops that we will associate with our ktype later on */
-static struct sysfs_ops foo_sysfs_ops = {
+static const struct sysfs_ops foo_sysfs_ops = {
.show = foo_attr_show,
.store = foo_attr_store,
};
@@ -127,7 +128,7 @@ static struct foo_attribute foo_attribute =
__ATTR(foo, 0666, foo_show, foo_store);
/*
- * More complex function where we determine which varible is being accessed by
+ * More complex function where we determine which variable is being accessed by
* looking at the attribute for the "baz" and "bar" files.
*/
static ssize_t b_show(struct foo_obj *foo_obj, struct foo_attribute *attr,
@@ -161,7 +162,7 @@ static struct foo_attribute bar_attribute =
__ATTR(bar, 0666, b_show, b_store);
/*
- * Create a group of attributes so that we can create and destory them all
+ * Create a group of attributes so that we can create and destroy them all
* at once.
*/
static struct attribute *foo_default_attrs[] = {
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 3257d3d9676..a4d74344d80 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -145,11 +145,14 @@ our $Sparse = qr{
__kprobes|
__ref
}x;
+
+# Notes to $Attribute:
+# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
our $Attribute = qr{
const|
__read_mostly|
__kprobes|
- __(?:mem|cpu|dev|)(?:initdata|init)|
+ __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
____cacheline_aligned|
____cacheline_aligned_in_smp|
____cacheline_internodealigned_in_smp|
@@ -189,6 +192,14 @@ our $typeTypedefs = qr{(?x:
atomic_t
)};
+our $logFunctions = qr{(?x:
+ printk|
+ pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)|
+ dev_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
+ WARN|
+ panic
+)};
+
our @typeList = (
qr{void},
qr{(?:unsigned\s+)?char},
@@ -1377,12 +1388,17 @@ sub process {
#80 column limit
if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
$rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
- $line !~ /^\+\s*printk\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ &&
+ $line !~ /^\+\s*$logFunctions\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ &&
$length > 80)
{
WARN("line over 80 characters\n" . $herecurr);
}
+# check for spaces before a quoted newline
+ if ($rawline =~ /^.*\".*\s\\n/) {
+ WARN("unnecessary whitespace before a quoted newline\n" . $herecurr);
+ }
+
# check for adding lines without a newline.
if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
WARN("adding a line without newline at end of file\n" . $herecurr);
@@ -1411,6 +1427,12 @@ sub process {
ERROR("code indent should use tabs where possible\n" . $herevet);
}
+# check for space before tabs.
+ if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
+ my $herevet = "$here\n" . cat_vet($rawline) . "\n";
+ WARN("please, no space before tabs\n" . $herevet);
+ }
+
# check we are in a valid C source file if not then ignore this hunk
next if ($realfile !~ /\.(h|c)$/);
@@ -2182,8 +2204,10 @@ sub process {
# Find out how long the conditional actually is.
my @newlines = ($c =~ /\n/gs);
my $cond_lines = 1 + $#newlines;
+ my $stat_real = '';
- my $stat_real = raw_line($linenr, $cond_lines);
+ $stat_real = raw_line($linenr, $cond_lines)
+ . "\n" if ($cond_lines);
if (defined($stat_real) && $cond_lines > 1) {
$stat_real = "[...]\n$stat_real";
}
@@ -2348,6 +2372,8 @@ sub process {
DECLARE_PER_CPU|
DEFINE_PER_CPU|
__typeof__\(|
+ union|
+ struct|
\.$Ident\s*=\s*|
^\"|\"$
}x;
@@ -2572,6 +2598,11 @@ sub process {
WARN("plain inline is preferred over $1\n" . $herecurr);
}
+# check for sizeof(&)
+ if ($line =~ /\bsizeof\s*\(\s*\&/) {
+ WARN("sizeof(& should be avoided\n" . $herecurr);
+ }
+
# check for new externs in .c files.
if ($realfile =~ /\.c$/ && defined $stat &&
$stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
@@ -2634,9 +2665,46 @@ sub process {
if ($line =~ /^.\s*__initcall\s*\(/) {
WARN("please use device_initcall() instead of __initcall()\n" . $herecurr);
}
-# check for struct file_operations, ensure they are const.
+# check for various ops structs, ensure they are const.
+ my $struct_ops = qr{acpi_dock_ops|
+ address_space_operations|
+ backlight_ops|
+ block_device_operations|
+ dentry_operations|
+ dev_pm_ops|
+ dma_map_ops|
+ extent_io_ops|
+ file_lock_operations|
+ file_operations|
+ hv_ops|
+ ide_dma_ops|
+ intel_dvo_dev_ops|
+ item_operations|
+ iwl_ops|
+ kgdb_arch|
+ kgdb_io|
+ kset_uevent_ops|
+ lock_manager_operations|
+ microcode_ops|
+ mtrr_ops|
+ neigh_ops|
+ nlmsvc_binding|
+ pci_raw_ops|
+ pipe_buf_operations|
+ platform_hibernation_ops|
+ platform_suspend_ops|
+ proto_ops|
+ rpc_pipe_ops|
+ seq_operations|
+ snd_ac97_build_ops|
+ soc_pcmcia_socket_ops|
+ stacktrace_ops|
+ sysfs_ops|
+ tty_operations|
+ usb_mon_operations|
+ wd_ops}x;
if ($line !~ /\bconst\b/ &&
- $line =~ /\bstruct\s+(file_operations|seq_operations)\b/) {
+ $line =~ /\bstruct\s+($struct_ops)\b/) {
WARN("struct $1 should normally be const\n" .
$herecurr);
}
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 2f3230db7ff..6f97a13bcee 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -41,6 +41,8 @@ my $web = 0;
my $subsystem = 0;
my $status = 0;
my $keywords = 1;
+my $sections = 0;
+my $file_emails = 0;
my $from_filename = 0;
my $pattern_depth = 0;
my $version = 0;
@@ -120,9 +122,11 @@ if (!GetOptions(
'web!' => \$web,
'pattern-depth=i' => \$pattern_depth,
'k|keywords!' => \$keywords,
+ 'sections!' => \$sections,
+ 'fe|file-emails!' => \$file_emails,
'f|file' => \$from_filename,
'v|version' => \$version,
- 'h|help' => \$help,
+ 'h|help|usage' => \$help,
)) {
die "$P: invalid argument - use --help if necessary\n";
}
@@ -137,9 +141,9 @@ if ($version != 0) {
exit 0;
}
-if ($#ARGV < 0) {
- usage();
- die "$P: argument missing: patchfile or -f file please\n";
+if (-t STDIN && !@ARGV) {
+ # We're talking to a terminal, but have no command line arguments.
+ die "$P: missing patchfile or -f file - use --help if necessary\n";
}
if ($output_separator ne ", ") {
@@ -150,16 +154,24 @@ if ($output_rolestats) {
$output_roles = 1;
}
-my $selections = $email + $scm + $status + $subsystem + $web;
-if ($selections == 0) {
- usage();
- die "$P: Missing required option: email, scm, status, subsystem or web\n";
+if ($sections) {
+ $email = 0;
+ $email_list = 0;
+ $scm = 0;
+ $status = 0;
+ $subsystem = 0;
+ $web = 0;
+ $keywords = 0;
+} else {
+ my $selections = $email + $scm + $status + $subsystem + $web;
+ if ($selections == 0) {
+ die "$P: Missing required option: email, scm, status, subsystem or web\n";
+ }
}
if ($email &&
($email_maintainer + $email_list + $email_subscriber_list +
$email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) {
- usage();
die "$P: Please select at least 1 email option\n";
}
@@ -173,8 +185,9 @@ if (!top_of_kernel_tree($lk_path)) {
my @typevalue = ();
my %keyword_hash;
-open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n";
-while (<MAINT>) {
+open (my $maint, '<', "${lk_path}MAINTAINERS")
+ or die "$P: Can't open MAINTAINERS: $!\n";
+while (<$maint>) {
my $line = $_;
if ($line =~ m/^(\C):\s*(.*)/) {
@@ -199,13 +212,14 @@ while (<MAINT>) {
push(@typevalue, $line);
}
}
-close(MAINT);
+close($maint);
my %mailmap;
if ($email_remove_duplicates) {
- open(MAILMAP, "<${lk_path}.mailmap") || warn "$P: Can't open .mailmap\n";
- while (<MAILMAP>) {
+ open(my $mailmap, '<', "${lk_path}.mailmap")
+ or warn "$P: Can't open .mailmap: $!\n";
+ while (<$mailmap>) {
my $line = $_;
next if ($line =~ m/^\s*#/);
@@ -224,7 +238,7 @@ if ($email_remove_duplicates) {
$mailmap{$name} = \@arr;
}
}
- close(MAILMAP);
+ close($mailmap);
}
## use the filenames on the command line or find the filenames in the patchfiles
@@ -232,31 +246,47 @@ if ($email_remove_duplicates) {
my @files = ();
my @range = ();
my @keyword_tvi = ();
+my @file_emails = ();
+
+if (!@ARGV) {
+ push(@ARGV, "&STDIN");
+}
foreach my $file (@ARGV) {
- ##if $file is a directory and it lacks a trailing slash, add one
- if ((-d $file)) {
- $file =~ s@([^/])$@$1/@;
- } elsif (!(-f $file)) {
- die "$P: file '${file}' not found\n";
+ if ($file ne "&STDIN") {
+ ##if $file is a directory and it lacks a trailing slash, add one
+ if ((-d $file)) {
+ $file =~ s@([^/])$@$1/@;
+ } elsif (!(-f $file)) {
+ die "$P: file '${file}' not found\n";
+ }
}
if ($from_filename) {
push(@files, $file);
- if (-f $file && $keywords) {
- open(FILE, "<$file") or die "$P: Can't open ${file}\n";
- my $text = do { local($/) ; <FILE> };
- foreach my $line (keys %keyword_hash) {
- if ($text =~ m/$keyword_hash{$line}/x) {
- push(@keyword_tvi, $line);
+ if (-f $file && ($keywords || $file_emails)) {
+ open(my $f, '<', $file)
+ or die "$P: Can't open $file: $!\n";
+ my $text = do { local($/) ; <$f> };
+ close($f);
+ if ($keywords) {
+ foreach my $line (keys %keyword_hash) {
+ if ($text =~ m/$keyword_hash{$line}/x) {
+ push(@keyword_tvi, $line);
+ }
}
}
- close(FILE);
+ if ($file_emails) {
+ my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
+ push(@file_emails, clean_file_emails(@poss_addr));
+ }
}
} else {
my $file_cnt = @files;
my $lastfile;
- open(PATCH, "<$file") or die "$P: Can't open ${file}\n";
- while (<PATCH>) {
+
+ open(my $patch, "< $file")
+ or die "$P: Can't open $file: $!\n";
+ while (<$patch>) {
my $patch_line = $_;
if (m/^\+\+\+\s+(\S+)/) {
my $filename = $1;
@@ -276,7 +306,8 @@ foreach my $file (@ARGV) {
}
}
}
- close(PATCH);
+ close($patch);
+
if ($file_cnt == @files) {
warn "$P: file '${file}' doesn't appear to be a patch. "
. "Add -f to options?\n";
@@ -285,6 +316,8 @@ foreach my $file (@ARGV) {
}
}
+@file_emails = uniq(@file_emails);
+
my @email_to = ();
my @list_to = ();
my @scm = ();
@@ -314,6 +347,7 @@ foreach my $file (@files) {
if ($type eq 'X') {
if (file_match_pattern($file, $value)) {
$exclude = 1;
+ last;
}
}
}
@@ -340,12 +374,28 @@ foreach my $file (@files) {
}
}
- $tvi += ($end - $start);
-
+ $tvi = $end + 1;
}
foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
add_categories($line);
+ if ($sections) {
+ my $i;
+ my $start = find_starting_index($line);
+ my $end = find_ending_index($line);
+ for ($i = $start; $i < $end; $i++) {
+ my $line = $typevalue[$i];
+ if ($line =~ /^[FX]:/) { ##Restore file patterns
+ $line =~ s/([^\\])\.([^\*])/$1\?$2/g;
+ $line =~ s/([^\\])\.$/$1\?/g; ##Convert . back to ?
+ $line =~ s/\\\./\./g; ##Convert \. to .
+ $line =~ s/\.\*/\*/g; ##Convert .* to *
+ }
+ $line =~ s/^([A-Z]):/$1:\t/g;
+ print("$line\n");
+ }
+ print("\n");
+ }
}
if ($email && $email_git) {
@@ -377,6 +427,14 @@ if ($email) {
}
}
}
+
+ foreach my $email (@file_emails) {
+ my ($name, $address) = parse_email($email);
+
+ my $tmp_email = format_email($name, $address, $email_usename);
+ push_email_address($tmp_email, '');
+ add_role($tmp_email, 'in file');
+ }
}
if ($email || $email_list) {
@@ -453,6 +511,7 @@ MAINTAINER field selection options:
--remove-duplicates => minimize duplicate email names/addresses
--roles => show roles (status:subsystem, git-signer, list, etc...)
--rolestats => show roles and statistics (commits/total_commits, %)
+ --file-emails => add email addresses found in -f file (default: 0 (off))
--scm => print SCM tree(s) if any
--status => print status if any
--subsystem => print subsystem name if any
@@ -466,6 +525,7 @@ Output type options:
Other options:
--pattern-depth => Number of pattern directory traversals (default: 0 (all))
--keywords => scan patch for keywords (default: 1 (on))
+ --sections => print the entire subsystem sections with pattern matches
--version => show version
--help => show this help information
@@ -545,7 +605,7 @@ sub parse_email {
$name =~ s/^\"|\"$//g;
$address =~ s/^\s+|\s+$//g;
- if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars
+ if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
$name = "\"$name\"";
}
@@ -562,7 +622,7 @@ sub format_email {
$name =~ s/^\"|\"$//g;
$address =~ s/^\s+|\s+$//g;
- if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars
+ if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
$name = "\"$name\"";
}
@@ -811,7 +871,9 @@ sub add_role {
foreach my $entry (@email_to) {
if ($email_remove_duplicates) {
my ($entry_name, $entry_address) = parse_email($entry->[0]);
- if ($name eq $entry_name || $address eq $entry_address) {
+ if (($name eq $entry_name || $address eq $entry_address)
+ && ($role eq "" || !($entry->[1] =~ m/$role/))
+ ) {
if ($entry->[1] eq "") {
$entry->[1] = "$role";
} else {
@@ -819,7 +881,9 @@ sub add_role {
}
}
} else {
- if ($email eq $entry->[0]) {
+ if ($email eq $entry->[0]
+ && ($role eq "" || !($entry->[1] =~ m/$role/))
+ ) {
if ($entry->[1] eq "") {
$entry->[1] = "$role";
} else {
@@ -1099,6 +1163,51 @@ sub sort_and_uniq {
return @parms;
}
+sub clean_file_emails {
+ my (@file_emails) = @_;
+ my @fmt_emails = ();
+
+ foreach my $email (@file_emails) {
+ $email =~ s/[\(\<\{]{0,1}([A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+)[\)\>\}]{0,1}/\<$1\>/g;
+ my ($name, $address) = parse_email($email);
+ if ($name eq '"[,\.]"') {
+ $name = "";
+ }
+
+ my @nw = split(/[^A-Za-zÀ-ÿ\'\,\.\+-]/, $name);
+ if (@nw > 2) {
+ my $first = $nw[@nw - 3];
+ my $middle = $nw[@nw - 2];
+ my $last = $nw[@nw - 1];
+
+ if (((length($first) == 1 && $first =~ m/[A-Za-z]/) ||
+ (length($first) == 2 && substr($first, -1) eq ".")) ||
+ (length($middle) == 1 ||
+ (length($middle) == 2 && substr($middle, -1) eq "."))) {
+ $name = "$first $middle $last";
+ } else {
+ $name = "$middle $last";
+ }
+ }
+
+ if (substr($name, -1) =~ /[,\.]/) {
+ $name = substr($name, 0, length($name) - 1);
+ } elsif (substr($name, -2) =~ /[,\.]"/) {
+ $name = substr($name, 0, length($name) - 2) . '"';
+ }
+
+ if (substr($name, 0, 1) =~ /[,\.]/) {
+ $name = substr($name, 1, length($name) - 1);
+ } elsif (substr($name, 0, 2) =~ /"[,\.]/) {
+ $name = '"' . substr($name, 2, length($name) - 2);
+ }
+
+ my $fmt_email = format_email($name, $address, $email_usename);
+ push(@fmt_emails, $fmt_email);
+ }
+ return @fmt_emails;
+}
+
sub merge_email {
my @lines;
my %saw;
@@ -1183,7 +1292,7 @@ sub rfc822_strip_comments {
# valid: returns true if the parameter is an RFC822 valid address
#
-sub rfc822_valid ($) {
+sub rfc822_valid {
my $s = rfc822_strip_comments(shift);
if (!$rfc822re) {
@@ -1203,7 +1312,7 @@ sub rfc822_valid ($) {
# from success with no addresses found, because an empty string is
# a valid list.
-sub rfc822_validlist ($) {
+sub rfc822_validlist {
my $s = rfc822_strip_comments(shift);
if (!$rfc822re) {
diff --git a/scripts/gfp-translate b/scripts/gfp-translate
index 073cb6d152a..d81b968d864 100644
--- a/scripts/gfp-translate
+++ b/scripts/gfp-translate
@@ -19,7 +19,7 @@ usage() {
exit 0
}
-# Parse command-line arguements
+# Parse command-line arguments
while [ $# -gt 0 ]; do
case $1 in
--source)
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 208ad3b0ca5..fcdfb245a57 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1424,6 +1424,8 @@ sub dump_struct($$) {
$nested =~ s/\/\*.*?\*\///gos;
# strip kmemcheck_bitfield_{begin,end}.*;
$members =~ s/kmemcheck_bitfield_.*?;//gos;
+ # strip attributes
+ $members =~ s/__aligned\s*\(\d+\)//gos;
create_parameterlist($members, ';', $file);
check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
@@ -1728,6 +1730,7 @@ sub dump_function($$) {
$prototype =~ s/^noinline +//;
$prototype =~ s/__devinit +//;
$prototype =~ s/__init +//;
+ $prototype =~ s/__init_or_module +//;
$prototype =~ s/^#\s*define\s+//; #ak added
$prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//;
@@ -2103,7 +2106,7 @@ sub process_file($) {
$section = $newsection;
} elsif (/$doc_end/) {
- if ($contents ne "") {
+ if (($contents ne "") && ($contents ne "\n")) {
dump_section($file, $section, xml_escape($contents));
$section = $section_default;
$contents = "";
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 6cf8fd2b79e..f77c6042399 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -10,6 +10,7 @@
#include <linux/list.h>
#include <linux/uaccess.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <linux/rcupdate.h>
#include <linux/mutex.h>
diff --git a/security/inode.c b/security/inode.c
index c3a793881d0..1c812e87450 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -161,13 +161,13 @@ static int create_by_name(const char *name, mode_t mode,
mutex_lock(&parent->d_inode->i_mutex);
*dentry = lookup_one_len(name, parent, strlen(name));
- if (!IS_ERR(dentry)) {
+ if (!IS_ERR(*dentry)) {
if ((mode & S_IFMT) == S_IFDIR)
error = mkdir(parent->d_inode, *dentry, mode);
else
error = create(parent->d_inode, *dentry, mode);
} else
- error = PTR_ERR(dentry);
+ error = PTR_ERR(*dentry);
mutex_unlock(&parent->d_inode->i_mutex);
return error;
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 2a5e0bcf388..52015d098fd 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -13,6 +13,7 @@
* and store_template.
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include "ima.h"
static const char *IMA_TEMPLATE_NAME = "ima";
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index ff513ff737f..5af76340470 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -11,6 +11,7 @@
*/
#include <linux/fs.h>
+#include <linux/gfp.h>
#include <linux/audit.h>
#include "ima.h"
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 46642a19bc7..952e51373f5 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -18,6 +18,7 @@
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include "ima.h"
static int init_desc(struct hash_desc *desc)
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 0c72c9c3895..07cb9c338cc 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -16,6 +16,7 @@
* current measurement list and IMA statistics
*/
#include <linux/fcntl.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/rculist.h>
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index 2d4d05d92fd..2c744d48801 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -14,6 +14,7 @@
* - cache integrity information associated with an inode
* using a radix tree.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/radix-tree.h>
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index a40da7ae590..b1bcb702a27 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -16,6 +16,7 @@
*/
#include <linux/module.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include "ima.h"
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 294b005d652..b2c89d9de2a 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -21,6 +21,7 @@
#include <linux/binfmts.h>
#include <linux/mount.h>
#include <linux/mman.h>
+#include <linux/slab.h>
#include "ima.h"
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 4759d0f9933..8643a93c596 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -15,6 +15,7 @@
#include <linux/security.h>
#include <linux/magic.h>
#include <linux/parser.h>
+#include <linux/slab.h>
#include "ima.h"
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index a0880e9c8e0..46ba62b1adf 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -20,6 +20,7 @@
*/
#include <linux/module.h>
#include <linux/rculist.h>
+#include <linux/slab.h>
#include "ima.h"
LIST_HEAD(ima_measurements); /* list of all measurements */
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index e814d2109f8..dd7cd0f8e13 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -201,7 +201,7 @@ static long keyring_read(const struct key *keyring,
int loop, ret;
ret = 0;
- klist = rcu_dereference(keyring->payload.subscriptions);
+ klist = keyring->payload.subscriptions;
if (klist) {
/* calculate how much data we could return */
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 9d01021ca0c..706d63f4f18 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 5c23afb31ec..06c2ccf26ed 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/keyctl.h>
#include <linux/fs.h>
#include <linux/err.h>
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 03fe63ed55b..d737cea5347 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -68,7 +68,8 @@ static int call_sbin_request_key(struct key_construction *cons,
{
const struct cred *cred = current_cred();
key_serial_t prkey, sskey;
- struct key *key = cons->key, *authkey = cons->authkey, *keyring;
+ struct key *key = cons->key, *authkey = cons->authkey, *keyring,
+ *session;
char *argv[9], *envp[3], uid_str[12], gid_str[12];
char key_str[12], keyring_str[3][12];
char desc[20];
@@ -112,10 +113,12 @@ static int call_sbin_request_key(struct key_construction *cons,
if (cred->tgcred->process_keyring)
prkey = cred->tgcred->process_keyring->serial;
- if (cred->tgcred->session_keyring)
- sskey = rcu_dereference(cred->tgcred->session_keyring)->serial;
- else
- sskey = cred->user->session_keyring->serial;
+ rcu_read_lock();
+ session = rcu_dereference(cred->tgcred->session_keyring);
+ if (!session)
+ session = cred->user->session_keyring;
+ sskey = session->serial;
+ rcu_read_unlock();
sprintf(keyring_str[2], "%d", sskey);
@@ -336,8 +339,10 @@ static int construct_alloc_key(struct key_type *type,
key_already_present:
mutex_unlock(&key_construction_mutex);
- if (dest_keyring)
+ if (dest_keyring) {
+ __key_link(dest_keyring, key_ref_to_ptr(key_ref));
up_write(&dest_keyring->sem);
+ }
mutex_unlock(&user->cons_lock);
key_put(key);
*_key = key = key_ref_to_ptr(key_ref);
@@ -428,6 +433,11 @@ struct key *request_key_and_link(struct key_type *type,
if (!IS_ERR(key_ref)) {
key = key_ref_to_ptr(key_ref);
+ if (dest_keyring) {
+ construct_get_dest_keyring(&dest_keyring);
+ key_link(dest_keyring, key);
+ key_put(dest_keyring);
+ }
} else if (PTR_ERR(key_ref) != -EAGAIN) {
key = ERR_CAST(key_ref);
} else {
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index acba3dfc8d2..893365b79a2 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <net/sock.h>
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index db0fd9f3349..989fef82563 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -337,7 +337,7 @@ static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
* Look up an AVC entry that is valid for the
* (@ssid, @tsid), interpreting the permissions
* based on @tclass. If a valid AVC entry exists,
- * then this function return the avc_node.
+ * then this function returns the avc_node.
* Otherwise, this function returns NULL.
*/
static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
@@ -523,7 +523,7 @@ void avc_audit(u32 ssid, u32 tsid,
* @perms: permissions
*
* Register a callback function for events in the set @events
- * related to the SID pair (@ssid, @tsid) and
+ * related to the SID pair (@ssid, @tsid)
* and the permissions @perms, interpreting
* @perms based on @tclass. Returns %0 on success or
* -%ENOMEM if insufficient memory exists to add the callback.
@@ -568,7 +568,7 @@ static inline int avc_sidcmp(u32 x, u32 y)
*
* if a valid AVC entry doesn't exist,this function returns -ENOENT.
* if kmalloc() called internal returns NULL, this function returns -ENOMEM.
- * otherwise, this function update the AVC entry. The original AVC-entry object
+ * otherwise, this function updates the AVC entry. The original AVC-entry object
* will release later by RCU.
*/
static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index b4e14bc0bf3..d6095d63d83 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -16,6 +16,7 @@
*/
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/list.h>
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 2534400317c..628da72ee76 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -29,6 +29,7 @@
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
+#include <linux/gfp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <net/sock.h>
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 1ae556446e6..0e147b6914a 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/list.h>
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 7100072bb1b..dc92792271f 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -31,6 +31,7 @@
#include <linux/types.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/in.h>
#include <linux/in6.h>
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index fe7fba67f19..cfe2d72d3fb 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -30,6 +30,7 @@
#include <linux/types.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/in.h>
#include <linux/in6.h>
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 8da6a842808..cd4f734e274 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
void avtab_cache_init(void);
void avtab_cache_destroy(void);
-#define MAX_AVTAB_HASH_BITS 13
+#define MAX_AVTAB_HASH_BITS 11
#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
diff --git a/security/selinux/ss/symtab.c b/security/selinux/ss/symtab.c
index 837658a98a5..bcf9f620426 100644
--- a/security/selinux/ss/symtab.c
+++ b/security/selinux/ss/symtab.c
@@ -4,7 +4,6 @@
* Author : Stephen Smalley, <sds@epoch.ncsc.mil>
*/
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include "symtab.h"
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index f3cb9ed731a..fff78d3b51a 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -38,6 +38,7 @@
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv6.h>
+#include <linux/slab.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/skbuff.h>
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 0f9ac814690..f4fac64c4da 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -11,6 +11,7 @@
*/
#include <linux/types.h>
+#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include "smack.h"
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 5225e668dbf..fdfeaa2f28e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -25,6 +25,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
+#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/pipe_fs_i.h>
#include <net/netlabel.h>
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index aeead758509..a2b72d77f92 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -20,6 +20,7 @@
#include <linux/vmalloc.h>
#include <linux/security.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index ff51f1026b5..975c45d88ba 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -10,6 +10,7 @@
*/
#include <linux/uaccess.h>
+#include <linux/slab.h>
#include <linux/security.h>
#include <linux/hardirq.h>
#include "common.h"
@@ -886,6 +887,7 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
ptr = kmalloc(sizeof(*ptr), GFP_KERNEL);
if (!tomoyo_memory_ok(ptr)) {
kfree(ptr);
+ ptr = NULL;
goto ok;
}
for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 66caaa1b842..acb8c397d5c 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -11,6 +11,7 @@
#include "common.h"
#include <linux/binfmts.h>
+#include <linux/slab.h>
/* Variables definitions.*/
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 1b24304edb7..6f3fe76a1fd 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -10,6 +10,7 @@
*/
#include "common.h"
+#include <linux/slab.h>
/* Keyword array for single path operations. */
static const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index 9645525ccdd..d9ad35bc7fa 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -9,6 +9,7 @@
#include "common.h"
#include <linux/kthread.h>
+#include <linux/slab.h>
enum tomoyo_gc_id {
TOMOYO_ID_DOMAIN_INITIALIZER,
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index cf7d61f781b..c225c65ce42 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -15,6 +15,7 @@
#include <linux/fs_struct.h>
#include <linux/hash.h>
#include <linux/magic.h>
+#include <linux/slab.h>
#include "common.h"
/**
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 84bb07d39a7..91852e49910 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -33,6 +33,7 @@
*/
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 1dd66ddffca..fd2188c3df2 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -66,6 +66,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_LICENSE("GPL");
diff --git a/sound/aoa/codecs/toonie.c b/sound/aoa/codecs/toonie.c
index f13827e1756..69d2cb601f2 100644
--- a/sound/aoa/codecs/toonie.c
+++ b/sound/aoa/codecs/toonie.c
@@ -11,6 +11,7 @@
*/
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/slab.h>
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 1dd0c28d1fb..6776d1c12b6 100644
--- a/sound/aoa/core/gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
@@ -6,6 +6,7 @@
* GPL v2, can be found in COPYING.
*/
+#include <linux/slab.h>
#include <asm/pmac_feature.h>
#include <asm/pmac_pfunc.h>
#include "../aoa.h"
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index 7a437da0564..1cd9b301df0 100644
--- a/sound/aoa/fabrics/layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -12,6 +12,7 @@
#include <asm/prom.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "../aoa.h"
#include "../soundbus/soundbus.h"
diff --git a/sound/aoa/soundbus/i2sbus/control.c b/sound/aoa/soundbus/i2sbus/control.c
index 87beb4ad4d6..47f854c2001 100644
--- a/sound/aoa/soundbus/i2sbus/control.c
+++ b/sound/aoa/soundbus/i2sbus/control.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/prom.h>
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
index 4e3b819d499..9d6f3b176ed 100644
--- a/sound/aoa/soundbus/i2sbus/core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -7,6 +7,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c
index 59bacd36573..be838993926 100644
--- a/sound/aoa/soundbus/i2sbus/pcm.c
+++ b/sound/aoa/soundbus/i2sbus/pcm.c
@@ -8,6 +8,7 @@
#include <asm/io.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <asm/macio.h>
#include <linux/pci.h>
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 656e474dca4..91acc9a243e 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
struct snd_ac97 *ac97;
int ret;
- writel(0, aaci->base + AC97_POWERDOWN);
/*
* Assert AACIRESET for 2us
*/
@@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
writel(0x1fff, aaci->base + AACI_INTCLR);
writel(aaci->maincr, aaci->base + AACI_MAINCR);
-
+ /*
+ * Fix: ac97 read back fail errors by reading
+ * from any arbitrary aaci register.
+ */
+ readl(aaci->base + AACI_CSCH1);
ret = aaci_probe_ac97(aaci);
if (ret)
goto out;
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 6fdca97186e..88eec3847df 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -22,7 +22,6 @@
#include <asm/irq.h>
#include <mach/regs-ac97.h>
-#include <mach/pxa2xx-gpio.h>
#include <mach/audio.h>
static DEFINE_MUTEX(car_mutex);
@@ -32,6 +31,8 @@ static struct clk *ac97_clk;
static struct clk *ac97conf_clk;
static int reset_gpio;
+extern void pxa27x_assert_ac97reset(int reset_gpio, int on);
+
/*
* Beware PXA27x bugs:
*
@@ -42,45 +43,6 @@ static int reset_gpio;
* 1 jiffy timeout if interrupt never comes).
*/
-enum {
- RESETGPIO_FORCE_HIGH,
- RESETGPIO_FORCE_LOW,
- RESETGPIO_NORMAL_ALTFUNC
-};
-
-/**
- * set_resetgpio_mode - computes and sets the AC97_RESET gpio mode on PXA
- * @mode: chosen action
- *
- * As the PXA27x CPUs suffer from a AC97 bug, a manual control of the reset line
- * must be done to insure proper work of AC97 reset line. This function
- * computes the correct gpio_mode for further use by reset functions, and
- * applied the change through pxa_gpio_mode.
- */
-static void set_resetgpio_mode(int resetgpio_action)
-{
- int mode = 0;
-
- if (reset_gpio)
- switch (resetgpio_action) {
- case RESETGPIO_NORMAL_ALTFUNC:
- if (reset_gpio == 113)
- mode = 113 | GPIO_ALT_FN_2_OUT;
- if (reset_gpio == 95)
- mode = 95 | GPIO_ALT_FN_1_OUT;
- break;
- case RESETGPIO_FORCE_LOW:
- mode = reset_gpio | GPIO_OUT | GPIO_DFLT_LOW;
- break;
- case RESETGPIO_FORCE_HIGH:
- mode = reset_gpio | GPIO_OUT | GPIO_DFLT_HIGH;
- break;
- };
-
- if (mode)
- pxa_gpio_mode(mode);
-}
-
unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
unsigned short val = -1;
@@ -174,12 +136,11 @@ static inline void pxa_ac97_warm_pxa27x(void)
{
gsr_bits = 0;
- /* warm reset broken on Bulverde,
- so manually keep AC97 reset high */
- set_resetgpio_mode(RESETGPIO_FORCE_HIGH);
+ /* warm reset broken on Bulverde, so manually keep AC97 reset high */
+ pxa27x_assert_ac97reset(reset_gpio, 1);
udelay(10);
GCR |= GCR_WARM_RST;
- set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
+ pxa27x_assert_ac97reset(reset_gpio, 0);
udelay(500);
}
@@ -345,16 +306,6 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
int pxa2xx_ac97_hw_resume(void)
{
- if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
- pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
- pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
- pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
- pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
- }
- if (cpu_is_pxa27x()) {
- /* Use GPIO 113 or 95 as AC97 Reset on Bulverde */
- set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
- }
clk_enable(ac97_clk);
return 0;
}
@@ -386,16 +337,9 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
reset_gpio = 113;
}
- if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
- pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
- pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
- pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
- pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
- }
-
if (cpu_is_pxa27x()) {
/* Use GPIO 113 as AC97 Reset on Bulverde */
- set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
+ pxa27x_assert_ac97reset(reset_gpio, 0);
ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
if (IS_ERR(ac97conf_clk)) {
ret = PTR_ERR(ac97conf_clk);
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index 743ac6a2906..8808b82311b 100644
--- a/sound/arm/pxa2xx-pcm-lib.c
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -4,6 +4,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
@@ -205,6 +206,7 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
if (!rtd->dma_desc_array)
goto err1;
+ rtd->dma_ch = -1;
runtime->private_data = rtd;
return 0;
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 368dc9c4aef..426874429a5 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -21,6 +21,7 @@
/* this file included from control.c */
#include <linux/compat.h>
+#include <linux/slab.h>
struct snd_ctl_elem_list32 {
u32 offset;
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index 7f4d744ae40..7730575bfad 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -19,6 +19,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/hrtimer.h>
diff --git a/sound/core/info.c b/sound/core/info.c
index d749a0d394a..cc4a53d4b7f 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/time.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
#include <sound/core.h>
diff --git a/sound/core/jack.c b/sound/core/jack.c
index f705eec7372..14b8a4ee690 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -20,6 +20,7 @@
*/
#include <linux/input.h>
+#include <linux/slab.h>
#include <sound/jack.h>
#include <sound/core.h>
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 3da4f92427d..2c41825c836 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/time.h>
+#include <linux/slab.h>
#include <linux/ioport.h>
#include <sound/core.h>
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index 0dcc2870d53..bbe25d8c450 100644
--- a/sound/core/oss/route.c
+++ b/sound/core/oss/route.c
@@ -19,7 +19,6 @@
*
*/
-#include <linux/slab.h>
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 08bfed594a8..5fb2e28e796 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -21,6 +21,7 @@
/* This file included from pcm_native.c */
#include <linux/compat.h>
+#include <linux/slab.h>
static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
s32 __user *src)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b546ac2660f..a2ff86189d2 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -148,6 +148,9 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
#define xrun_debug(substream, mask) \
((substream)->pstr->xrun_debug & (mask))
+#else
+#define xrun_debug(substream, mask) 0
+#endif
#define dump_stack_on_xrun(substream) do { \
if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
@@ -169,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream)
}
}
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
#define hw_ptr_error(substream, fmt, args...) \
do { \
if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
@@ -255,8 +259,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
-#define xrun_debug(substream, mask) 0
-#define xrun(substream) do { } while (0)
#define hw_ptr_error(substream, fmt, args...) do { } while (0)
#define xrun_log(substream, pos) do { } while (0)
#define xrun_log_show(substream) do { } while (0)
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index d6d49d6651f..917e4055ee3 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -22,6 +22,7 @@
#include <asm/io.h>
#include <linux/time.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <sound/core.h>
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index d0d721c22ea..685712276ac 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -29,6 +29,7 @@
#include "seq_oss_event.h"
#include <linux/init.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
/*
* common variables
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 9dfb2f77be6..677dc84590c 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -28,6 +28,7 @@
#include <sound/seq_midi_event.h>
#include "../seq_lock.h"
#include <linux/init.h>
+#include <linux/slab.h>
/*
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index f5de79f29f1..73661c4ab82 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -25,6 +25,7 @@
#include <sound/seq_oss_legacy.h>
#include "../seq_lock.h"
#include <linux/wait.h>
+#include <linux/slab.h>
/*
* constants
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index 945a27c34a9..ee44ab9593c 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -24,6 +24,7 @@
#include "seq_oss_midi.h"
#include "../seq_lock.h"
#include <linux/init.h>
+#include <linux/slab.h>
/*
* constants
diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
index c440fdacec9..ab59cbfbcaf 100644
--- a/sound/core/seq/oss/seq_oss_timer.c
+++ b/sound/core/seq/oss/seq_oss_timer.c
@@ -23,6 +23,7 @@
#include "seq_oss_timer.h"
#include "seq_oss_event.h"
#include <sound/seq_oss_legacy.h>
+#include <linux/slab.h>
/*
*/
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index 21742485819..d50338bbc21 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -27,6 +27,7 @@
#include "../seq_lock.h"
#include "../seq_clientmgr.h"
#include <linux/wait.h>
+#include <linux/slab.h>
/*
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c
index c956fe46256..81f7c109dc4 100644
--- a/sound/core/seq/seq_compat.c
+++ b/sound/core/seq/seq_compat.c
@@ -21,6 +21,7 @@
/* This file included from seq.c */
#include <linux/compat.h>
+#include <linux/slab.h>
struct snd_seq_port_info32 {
struct snd_seq_addr addr; /* client/port numbers */
diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c
index 77884e62b64..c38b90cf3cb 100644
--- a/sound/core/seq/seq_system.c
+++ b/sound/core/seq/seq_system.c
@@ -20,6 +20,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include "seq_system.h"
#include "seq_timer.h"
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 8f8b17ac074..73943651cae 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -393,7 +393,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
event == SNDRV_TIMER_EVENT_CONTINUE)
resolution = snd_timer_resolution(ti);
if (ti->ccallback)
- ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution);
+ ti->ccallback(ti, event, &tstamp, resolution);
if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
return;
timer = ti->timer;
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index 1950ffce2b5..a1282c1c059 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -39,6 +39,7 @@
#include <linux/platform_device.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
#include <linux/io.h>
#include <linux/interrupt.h>
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 2f8f295d6b0..da03597fc89 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -54,7 +54,6 @@
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 9284829bf92..8539ab0a089 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -23,6 +23,7 @@
#include <linux/parport.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/rawmidi.h>
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index a54b1dc5cc7..ade3ca52422 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -19,7 +19,6 @@
*/
#include "opl3_voice.h"
-#include <linux/slab.h>
static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg);
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c
index 6d57b6441de..301acb6b9cf 100644
--- a/sound/drivers/opl3/opl3_synth.c
+++ b/sound/drivers/opl3/opl3_synth.c
@@ -19,6 +19,7 @@
*
*/
+#include <linux/slab.h>
#include <sound/opl3.h>
#include <sound/asound_fm.h>
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 01997f24c89..f07e38da59b 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -20,6 +20,7 @@
#include "opl4_local.h"
#include <sound/initval.h>
#include <linux/ioport.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index e1145ac6e90..d77ffa9a938 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -7,6 +7,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <sound/pcm.h>
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 60158e2e0ea..f2b0ba22d9c 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -42,6 +42,7 @@
#include <linux/parport.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/rawmidi.h>
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 46df8817c18..f7a6fbd313e 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -22,6 +22,7 @@
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <sound/core.h>
#include <sound/hwdep.h>
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index fff62cc8607..971a84a4fa7 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device)
}
int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
- ak4113_write_t *write, const unsigned char pgm[5],
+ ak4113_write_t *write, const unsigned char *pgm,
void *private_data, struct ak4113 **r_ak4113)
{
struct ak4113 *chip;
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index c4c6ef73f9b..ee538f1ae84 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include <sound/core.h>
#include <sound/tea575x-tuner.h>
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 8246aae32ab..fe79a169acb 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -46,7 +46,6 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/isa.h>
-#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index cc15d1d65a2..999dc1e0fdb 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/isa.h>
-#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 9a43baae725..fb4d6b34bbc 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -80,7 +80,6 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/isa.h>
-#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/isapnp.h>
#include <linux/moduleparam.h>
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 534a6eced2b..c7b80e4730f 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -26,7 +26,6 @@
#include <linux/err.h>
#include <linux/isa.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
#include <asm/dma.h>
diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c
index 4be562b2cf2..78749567423 100644
--- a/sound/isa/msnd/msnd_midi.c
+++ b/sound/isa/msnd/msnd_midi.c
@@ -25,6 +25,7 @@
*/
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/errno.h>
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 0481a55334b..265abcce9db 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -24,7 +24,6 @@
#include <linux/isa.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
-#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index b865e45a8f9..8c24102d0d9 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -27,7 +27,6 @@
#include <linux/isa.h>
#include <linux/pnp.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/moduleparam.h>
#include <asm/io.h>
@@ -1558,7 +1557,7 @@ static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
err = pnp_activate_dev(devmc);
if (err < 0) {
- snd_printk(KERN_ERR "OPL syntg pnp configure failure: %d\n",
+ snd_printk(KERN_ERR "MC pnp configure failure: %d\n",
err);
return err;
}
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index a4af53b5c1c..c35dc68930d 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -27,7 +27,6 @@
#include <linux/err.h>
#include <linux/isa.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
#include <asm/io.h>
@@ -144,12 +143,8 @@ struct snd_opti9xx {
spinlock_t lock;
+ long wss_base;
int irq;
-
-#ifdef CONFIG_PNP
- struct pnp_dev *dev;
- struct pnp_dev *devmpu;
-#endif /* CONFIG_PNP */
};
static int snd_opti9xx_pnp_is_probed;
@@ -159,12 +154,17 @@ static int snd_opti9xx_pnp_is_probed;
static struct pnp_card_device_id snd_opti9xx_pnpids[] = {
#ifndef OPTi93X
/* OPTi 82C924 */
- { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 },
+ { .id = "OPT0924",
+ .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
+ .driver_data = 0x0924 },
/* OPTi 82C925 */
- { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 },
+ { .id = "OPT0925",
+ .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
+ .driver_data = 0x0925 },
#else
/* OPTi 82C931/3 */
- { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 },
+ { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
+ .driver_data = 0x0931 },
#endif /* OPTi93X */
{ .id = "" }
};
@@ -207,24 +207,35 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
chip->hardware = hardware;
strcpy(chip->name, snd_opti9xx_names[hardware]);
- chip->mc_base_size = opti9xx_mc_size[hardware];
-
spin_lock_init(&chip->lock);
chip->irq = -1;
+#ifndef OPTi93X
+#ifdef CONFIG_PNP
+ if (isapnp && chip->mc_base)
+ /* PnP resource gives the least 10 bits */
+ chip->mc_base |= 0xc00;
+ else
+#endif /* CONFIG_PNP */
+ {
+ chip->mc_base = 0xf8c;
+ chip->mc_base_size = opti9xx_mc_size[hardware];
+ }
+#else
+ chip->mc_base_size = opti9xx_mc_size[hardware];
+#endif
+
switch (hardware) {
#ifndef OPTi93X
case OPTi9XX_HW_82C928:
case OPTi9XX_HW_82C929:
- chip->mc_base = 0xf8c;
chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
chip->pwd_reg = 3;
break;
case OPTi9XX_HW_82C924:
case OPTi9XX_HW_82C925:
- chip->mc_base = 0xf8c;
chip->password = 0xe5;
chip->pwd_reg = 3;
break;
@@ -292,7 +303,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
spin_unlock_irqrestore(&chip->lock, flags);
return retval;
}
-
+
static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
unsigned char value)
{
@@ -341,7 +352,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
- long wss_base,
+ long port,
int irq, int dma1, int dma2,
long mpu_port, int mpu_irq)
{
@@ -354,16 +365,23 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
switch (chip->hardware) {
#ifndef OPTi93X
case OPTi9XX_HW_82C924:
+ /* opti 929 mode (?), OPL3 clock output, audio enable */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
+ /* enable wave audio */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
case OPTi9XX_HW_82C925:
+ /* enable WSS mode */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
+ /* OPL3 FM synthesis */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
+ /* disable Sound Blaster IRQ and DMA */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
#ifdef CS4231
+ /* cs4231/4248 fix enabled */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
#else
+ /* cs4231/4248 fix disabled */
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
#endif /* CS4231 */
break;
@@ -411,21 +429,26 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
return -EINVAL;
}
- switch (wss_base) {
- case 0x530:
+ /* PnP resource says it decodes only 10 bits of address */
+ switch (port & 0x3ff) {
+ case 0x130:
+ chip->wss_base = 0x530;
wss_base_bits = 0x00;
break;
- case 0x604:
+ case 0x204:
+ chip->wss_base = 0x604;
wss_base_bits = 0x03;
break;
- case 0xe80:
+ case 0x280:
+ chip->wss_base = 0xe80;
wss_base_bits = 0x01;
break;
- case 0xf40:
+ case 0x340:
+ chip->wss_base = 0xf40;
wss_base_bits = 0x02;
break;
default:
- snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base);
+ snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port);
goto __skip_base;
}
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
@@ -487,7 +510,7 @@ __skip_base:
#endif /* CS4231 || OPTi93X */
#ifndef OPTi93X
- outb(irq_bits << 3 | dma_bits, wss_base);
+ outb(irq_bits << 3 | dma_bits, chip->wss_base);
#else /* OPTi93X */
snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
#endif /* OPTi93X */
@@ -729,15 +752,15 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
{
struct pnp_dev *pdev;
int err;
+ struct pnp_dev *devmpu;
+#ifndef OPTi93X
+ struct pnp_dev *devmc;
+#endif
- chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
- if (chip->dev == NULL)
+ pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
+ if (pdev == NULL)
return -EBUSY;
- chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
-
- pdev = chip->dev;
-
err = pnp_activate_dev(pdev);
if (err < 0) {
snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
@@ -750,9 +773,24 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
#else
- if (pid->driver_data != 0x0924)
- port = pnp_port_start(pdev, 1);
+ devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
+ if (devmc == NULL)
+ return -EBUSY;
+
+ err = pnp_activate_dev(devmc);
+ if (err < 0) {
+ snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
+ return err;
+ }
+
+ port = pnp_port_start(pdev, 1);
fm_port = pnp_port_start(pdev, 2) + 8;
+ /*
+ * The MC(0) is never accessed and card does not
+ * include it in the PnP resource range. OPTI93x include it.
+ */
+ chip->mc_base = pnp_port_start(devmc, 0) - 1;
+ chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
#endif /* OPTi93X */
irq = pnp_irq(pdev, 0);
dma1 = pnp_dma(pdev, 0);
@@ -760,16 +798,16 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
dma2 = pnp_dma(pdev, 1);
#endif /* CS4231 || OPTi93X */
- pdev = chip->devmpu;
- if (pdev && mpu_port > 0) {
- err = pnp_activate_dev(pdev);
+ devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
+
+ if (devmpu && mpu_port > 0) {
+ err = pnp_activate_dev(devmpu);
if (err < 0) {
- snd_printk(KERN_ERR "AUDIO pnp configure failure\n");
+ snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
mpu_port = -1;
- chip->devmpu = NULL;
} else {
- mpu_port = pnp_port_start(pdev, 0);
- mpu_irq = pnp_irq(pdev, 0);
+ mpu_port = pnp_port_start(devmpu, 0);
+ mpu_irq = pnp_irq(devmpu, 0);
}
}
return pid->driver_data;
@@ -824,7 +862,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
if (error)
return error;
- error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2,
+ error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
#ifdef OPTi93X
WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
#else
@@ -865,10 +903,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
sprintf(card->shortname, "OPTi %s", card->driver);
#if defined(CS4231) || defined(OPTi93X)
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
- card->shortname, pcm->name, port + 4, irq, dma1, xdma2);
+ card->shortname, pcm->name,
+ chip->wss_base + 4, irq, dma1, xdma2);
#else
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
- card->shortname, pcm->name, port + 4, irq, dma1);
+ card->shortname, pcm->name, chip->wss_base + 4, irq, dma1);
#endif /* CS4231 || OPTi93X */
if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
@@ -1062,9 +1101,6 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
snd_card_free(card);
return error;
}
- if (hw <= OPTi9XX_HW_82C930)
- chip->mc_base -= 0x80;
-
error = snd_opti9xx_read_check(chip);
if (error) {
snd_printk(KERN_ERR "OPTI chip not found\n");
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 91dc3d83e2c..ccedbfed061 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -20,6 +20,7 @@
#include "emu8000_local.h"
#include <linux/init.h>
+#include <linux/slab.h>
#include <sound/initval.h>
#include <sound/pcm.h>
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 8d21a3feda3..8ccbcddf08e 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/delay.h>
#include <asm/dma.h>
#include <linux/isa.h>
#include <sound/core.h>
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 519c36346de..4d1c5a300ff 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -21,7 +21,6 @@
#include <asm/dma.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/err.h>
#include <linux/isa.h>
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 3cd57ee5466..81284a8fa0c 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/isa.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index a34ae7b1f7d..711670e4a42 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -21,7 +21,6 @@
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/err.h>
#include <linux/isa.h>
#include <linux/pnp.h>
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
index 2bb1cee0925..657e2d6c01a 100644
--- a/sound/isa/wavefront/wavefront_fx.c
+++ b/sound/isa/wavefront/wavefront_fx.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/time.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <sound/core.h>
#include <sound/snd_wavefront.h>
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 5d4ff48c434..4fb7b19ff39 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -28,6 +28,7 @@
#include <linux/wait.h>
#include <linux/firmware.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/snd_wavefront.h>
#include <sound/initval.h>
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index 9a88cdfd952..453d343550a 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -25,6 +25,7 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index 6aff217379d..717604c00f0 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -25,11 +25,11 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/gfp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/ip32/ip32_ints.h>
#include <asm/ip32/mace.h>
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index d12bd98a37b..24793c5b65a 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -45,6 +45,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/stddef.h>
+#include <linux/slab.h>
#include <linux/isapnp.h>
#include <linux/pnp.h>
#include <linux/spinlock.h>
diff --git a/sound/oss/coproc.h b/sound/oss/coproc.h
index 7306346e9ac..7bec21bbdd8 100644
--- a/sound/oss/coproc.h
+++ b/sound/oss/coproc.h
@@ -4,7 +4,7 @@
*/
/*
- * Coprocessor access types
+ * Coprocessor access types
*/
#define COPR_CUSTOM 0x0001 /* Custom applications */
#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */
diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c
index 1bfcf7e8854..bcc3e8e0712 100644
--- a/sound/oss/dmabuf.c
+++ b/sound/oss/dmabuf.c
@@ -26,6 +26,7 @@
#define SAMPLE_ROUNDUP 0
#include <linux/mm.h>
+#include <linux/gfp.h>
#include "sound_config.h"
#define DMAP_FREE_ON_CLOSE 0
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index 24d152ccf80..52d06a334e8 100644
--- a/sound/oss/kahlua.c
+++ b/sound/oss/kahlua.c
@@ -31,6 +31,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include "sound_config.h"
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index 0af9d24feb8..25e4609f833 100644
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -19,6 +19,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c
index 21eb6dce46d..c0cc951ba97 100644
--- a/sound/oss/msnd.c
+++ b/sound/oss/msnd.c
@@ -24,7 +24,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/types.h>
#include <linux/delay.h>
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
index bf27e008f46..a1e3f9671be 100644
--- a/sound/oss/msnd_pinnacle.c
+++ b/sound/oss/msnd_pinnacle.c
@@ -35,12 +35,12 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/smp_lock.h>
+#include <linux/gfp.h>
#include <asm/irq.h>
#include <asm/io.h>
#include "sound_config.h"
diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c
index 7781c13c147..938c48c4358 100644
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -24,6 +24,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/delay.h>
diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c
index 7de18b58f2c..84ef4d06c1c 100644
--- a/sound/oss/sb_card.c
+++ b/sound/oss/sb_card.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include "sound_config.h"
#include "sb_mixer.h"
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c
index ce4db49291f..7d42c5418d1 100644
--- a/sound/oss/sb_common.c
+++ b/sound/oss/sb_common.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include "sound_config.h"
#include "sound_firmware.h"
diff --git a/sound/oss/sb_midi.c b/sound/oss/sb_midi.c
index 8b796704e11..f139028e85c 100644
--- a/sound/oss/sb_midi.c
+++ b/sound/oss/sb_midi.c
@@ -12,6 +12,7 @@
*/
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include "sound_config.h"
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c
index fad1a4f25ad..2039d31b7e2 100644
--- a/sound/oss/sb_mixer.c
+++ b/sound/oss/sb_mixer.c
@@ -16,6 +16,8 @@
* Stanislav Voronyi <stas@esc.kharkov.com> : Support for AWE 3DSE device (Jun 7 1999)
*/
+#include <linux/slab.h>
+
#include "sound_config.h"
#define __SB_MIXER_C__
diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c
index c79874696be..e85789e5381 100644
--- a/sound/oss/sequencer.c
+++ b/sound/oss/sequencer.c
@@ -1631,8 +1631,6 @@ unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
}
semitones = bend / 100;
- if (semitones > 99)
- semitones = 99;
cents = bend % 100;
amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000;
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index fde7c12fe5d..2d9c5131262 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -36,7 +36,6 @@
#include <asm/dma.h>
#include <asm/io.h>
#include <linux/wait.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/major.h>
#include <linux/delay.h>
diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c
index a446b826d5f..8e514a676a0 100644
--- a/sound/oss/uart401.c
+++ b/sound/oss/uart401.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include "sound_config.h"
diff --git a/sound/oss/v_midi.c b/sound/oss/v_midi.c
index 103940fd5b4..f0b4151d9b1 100644
--- a/sound/oss/v_midi.c
+++ b/sound/oss/v_midi.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include "sound_config.h"
diff --git a/sound/oss/v_midi.h b/sound/oss/v_midi.h
index 1b86cb45c60..08e2185ee81 100644
--- a/sound/oss/v_midi.h
+++ b/sound/oss/v_midi.h
@@ -2,9 +2,9 @@ typedef struct vmidi_devc {
int dev;
/* State variables */
- int opened;
+ int opened;
spinlock_t lock;
-
+
/* MIDI fields */
int my_mididev;
int pair_mididev;
@@ -12,4 +12,3 @@ typedef struct vmidi_devc {
int intr_active;
void (*midi_input_intr) (int dev, unsigned char data);
} vmidi_devc;
-
diff --git a/sound/oss/vidc.c b/sound/oss/vidc.c
index 725fef0f59a..ac39a531df1 100644
--- a/sound/oss/vidc.c
+++ b/sound/oss/vidc.c
@@ -17,6 +17,7 @@
* We currently support a mixer device, but it is currently non-functional.
*/
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -363,13 +364,13 @@ static void vidc_audio_trigger(int dev, int enable_bits)
struct audio_operations *adev = audio_devs[dev];
if (enable_bits & PCM_ENABLE_OUTPUT) {
- if (!(adev->flags & DMA_ACTIVE)) {
+ if (!(adev->dmap_out->flags & DMA_ACTIVE)) {
unsigned long flags;
local_irq_save(flags);
/* prevent recusion */
- adev->flags |= DMA_ACTIVE;
+ adev->dmap_out->flags |= DMA_ACTIVE;
dma_interrupt = vidc_audio_dma_interrupt;
vidc_sound_dma_irq(0, NULL);
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 6713110bdc7..20b3b325aa8 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -149,6 +149,7 @@
#include <linux/wait.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <asm/visws/cobalt.h>
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index 2c63bb9da74..e688dde6bbd 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 1caf5e3c1f6..e68c98ef404 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1852,12 +1852,14 @@ static unsigned int ad1981_jacks_blacklist[] = {
0x10140523, /* Thinkpad R40 */
0x10140534, /* Thinkpad X31 */
0x10140537, /* Thinkpad T41p */
+ 0x1014053e, /* Thinkpad R40e */
0x10140554, /* Thinkpad T42p/R50p */
0x10140567, /* Thinkpad T43p 2668-G7U */
0x10140581, /* Thinkpad X41-2527 */
0x10280160, /* Dell Dimension 2400 */
0x104380b0, /* Asus A7V8X-MX */
0x11790241, /* Toshiba Satellite A-15 S127 */
+ 0x1179ff10, /* Toshiba P500 */
0x144dc01a, /* Samsung NP-X20C004/SEG */
0 /* end */
};
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
index 73b17d526c8..6320bf084e4 100644
--- a/sound/pci/ac97/ac97_proc.c
+++ b/sound/pci/ac97/ac97_proc.c
@@ -22,7 +22,6 @@
*
*/
-#include <linux/slab.h>
#include <linux/mutex.h>
#include <sound/core.h>
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index d75cf7b0642..6cf1de8042e 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -68,7 +68,6 @@
#include <asm/io.h>
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
diff --git a/sound/pci/aw2/aw2-saa7146.c b/sound/pci/aw2/aw2-saa7146.c
index 296123ab74f..8afd8b5d1ac 100644
--- a/sound/pci/aw2/aw2-saa7146.c
+++ b/sound/pci/aw2/aw2-saa7146.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <asm/system.h>
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 8f443a9d61e..85fd315d999 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -63,7 +63,6 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/initval.h>
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index 0470461cc03..ba96428c9f4 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -63,7 +63,6 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/initval.h>
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 1ded64e0564..329968edca9 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci
struct snd_pcm_substream *substream)
{
size_t ptr;
- unsigned int reg;
+ unsigned int reg, rem, tries;
+
if (!rec->running)
return 0;
#if 1 // this seems better..
reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
- ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1);
- ptr >>= rec->shift;
+ for (tries = 0; tries < 3; tries++) {
+ rem = snd_cmipci_read_w(cm, reg);
+ if (rem < rec->dma_size)
+ goto ok;
+ }
+ printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem);
+ return SNDRV_PCM_POS_XRUN;
+ok:
+ ptr = (rec->dma_size - (rem + 1)) >> rec->shift;
#else
reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
ptr = snd_cmipci_read(cm, reg) - rec->offset;
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index 207479a641c..bc07e275d4d 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -39,6 +39,7 @@
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/sb.h>
#include <sound/initval.h>
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 0f48a871f17..f16bc8aad6e 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -23,7 +23,6 @@
*/
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/pci.h>
#include <sound/core.h>
#include <sound/control.h>
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index 564c33b6095..a3301cc4ab8 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -19,7 +19,6 @@
*/
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <sound/core.h>
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 480cb1e905b..1bff80cde0a 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -24,6 +24,7 @@
#include "ctdaio.h"
#include "cttimer.h"
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/control.h>
#include <sound/asoundef.h>
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index d0dc227fbdd..85ab43e8921 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -17,6 +17,7 @@
#include "ctpcm.h"
#include "cttimer.h"
+#include <linux/slab.h>
#include <sound/pcm.h>
/* Hardware descriptions for playback */
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
index a65bafe0800..fe7ad64dccd 100644
--- a/sound/pci/echoaudio/darla20.c
+++ b/sound/pci/echoaudio/darla20.c
@@ -40,9 +40,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
index 0a6c50bcd75..d1fd34b1a8e 100644
--- a/sound/pci/echoaudio/darla24.c
+++ b/sound/pci/echoaudio/darla24.c
@@ -44,9 +44,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
index f5142796989..1dffdc54416 100644
--- a/sound/pci/echoaudio/echo3g.c
+++ b/sound/pci/echoaudio/echo3g.c
@@ -51,9 +51,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 8dab82d7d19..668a5ec0449 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
goto ctl_error;
#endif
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
+ err = snd_card_register(card);
+ if (err < 0)
goto ctl_error;
- }
snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
pci_set_drvdata(pci, chip);
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
index 2364f8a1bc2..050e54aa693 100644
--- a/sound/pci/echoaudio/gina20.c
+++ b/sound/pci/echoaudio/gina20.c
@@ -44,9 +44,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
index 616b55825a1..5748fc6d29d 100644
--- a/sound/pci/echoaudio/gina24.c
+++ b/sound/pci/echoaudio/gina24.c
@@ -50,9 +50,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
index 776175c0bda..4ae5e35cb5f 100644
--- a/sound/pci/echoaudio/indigo.c
+++ b/sound/pci/echoaudio/indigo.c
@@ -42,9 +42,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
index 8816b0bd2ba..3550715bab1 100644
--- a/sound/pci/echoaudio/indigodj.c
+++ b/sound/pci/echoaudio/indigodj.c
@@ -42,9 +42,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c
index b1e3652f2f4..19b191fd012 100644
--- a/sound/pci/echoaudio/indigodjx.c
+++ b/sound/pci/echoaudio/indigodjx.c
@@ -42,10 +42,10 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
index 1035125336d..a9fcedf317a 100644
--- a/sound/pci/echoaudio/indigoio.c
+++ b/sound/pci/echoaudio/indigoio.c
@@ -43,9 +43,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c
index 60b7cb2753c..bcdfac63212 100644
--- a/sound/pci/echoaudio/indigoiox.c
+++ b/sound/pci/echoaudio/indigoiox.c
@@ -43,10 +43,10 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
index 8c3f5c5b530..d3a98c5dac8 100644
--- a/sound/pci/echoaudio/layla20.c
+++ b/sound/pci/echoaudio/layla20.c
@@ -49,9 +49,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
index ed1cc0abc2b..2a1dca6dce1 100644
--- a/sound/pci/echoaudio/layla24.c
+++ b/sound/pci/echoaudio/layla24.c
@@ -51,9 +51,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index cc2bbfc6532..9cdf14cfdd7 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -50,9 +50,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
index 3e7e01824b4..1047be405eb 100644
--- a/sound/pci/echoaudio/mona.c
+++ b/sound/pci/echoaudio/mona.c
@@ -48,9 +48,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 6a47672f930..ffb1ddb8dc2 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -22,6 +22,7 @@
*/
#include <linux/pci.h>
+#include <linux/gfp.h>
#include <linux/time.h>
#include <linux/mutex.h>
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 556cff937be..567348b05b5 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -157,7 +157,7 @@ config SND_HDA_CODEC_INTELHDMI
config SND_HDA_ELD
def_bool y
- depends on SND_HDA_CODEC_INTELHDMI
+ depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
config SND_HDA_CODEC_CIRRUS
bool "Build Cirrus Logic codec support"
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 315a1c4f899..24bc195b02d 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -3,7 +3,7 @@ snd-hda-intel-objs := hda_intel.o
snd-hda-codec-y := hda_codec.o
snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
-# snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
+snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
@@ -18,7 +18,7 @@ snd-hda-codec-ca0110-objs := patch_ca0110.o
snd-hda-codec-conexant-objs := patch_conexant.o
snd-hda-codec-via-objs := patch_via.o
snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
-snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o hda_eld.o
+snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o
# common driver
obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index e4581a42ace..29714c818b5 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -21,6 +21,7 @@
#include <linux/input.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <sound/core.h>
#include "hda_beep.h"
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 76d3c4c049d..0e76ac2b2ac 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -978,8 +978,9 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
*
* Returns 0 if successful, or a negative error code.
*/
-int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
- struct hda_codec **codecp)
+int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
+ unsigned int codec_addr,
+ struct hda_codec **codecp)
{
struct hda_codec *codec;
char component[31];
@@ -1186,7 +1187,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
*/
/* FIXME: more better hash key? */
-#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
+#define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
@@ -1356,7 +1357,8 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
if (!codec->no_trigger_sense) {
pincap = snd_hda_query_pin_caps(codec, nid);
if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
- snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
+ snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_SET_PIN_SENSE, 0);
}
return snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_SENSE, 0);
@@ -1372,8 +1374,8 @@ EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
*/
int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
{
- u32 sense = snd_hda_pin_sense(codec, nid);
- return !!(sense & AC_PINSENSE_PRESENCE);
+ u32 sense = snd_hda_pin_sense(codec, nid);
+ return !!(sense & AC_PINSENSE_PRESENCE);
}
EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
@@ -1804,6 +1806,8 @@ int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
item->nid = nid;
return 0;
}
+ printk(KERN_ERR "hda-codec: no NID for mapping control %s:%d:%d\n",
+ kctl->id.name, kctl->id.index, index);
return -EINVAL;
}
EXPORT_SYMBOL_HDA(snd_hda_add_nid);
@@ -1952,7 +1956,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
err = snd_hda_ctl_add(codec, 0, kctl);
if (err < 0)
return err;
-
+
for (s = slaves; *s; s++) {
struct snd_kcontrol *sctl;
int i = 0;
@@ -2439,27 +2443,27 @@ static struct snd_kcontrol_new dig_mixes[] = {
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
.info = snd_hda_spdif_mask_info,
.get = snd_hda_spdif_cmask_get,
},
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
.info = snd_hda_spdif_mask_info,
.get = snd_hda_spdif_pmask_get,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
.info = snd_hda_spdif_mask_info,
.get = snd_hda_spdif_default_get,
.put = snd_hda_spdif_default_put,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
.info = snd_hda_spdif_out_switch_info,
.get = snd_hda_spdif_out_switch_get,
.put = snd_hda_spdif_out_switch_put,
@@ -2610,7 +2614,7 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
static struct snd_kcontrol_new dig_in_ctls[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
.info = snd_hda_spdif_in_switch_info,
.get = snd_hda_spdif_in_switch_get,
.put = snd_hda_spdif_in_switch_put,
@@ -2618,7 +2622,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
.info = snd_hda_spdif_mask_info,
.get = snd_hda_spdif_in_status_get,
},
@@ -2882,8 +2886,8 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
list_for_each_entry(codec, &bus->codec_list, list) {
int err = snd_hda_codec_build_controls(codec);
if (err < 0) {
- printk(KERN_ERR "hda_codec: cannot build controls"
- "for #%d (error %d)\n", codec->addr, err);
+ printk(KERN_ERR "hda_codec: cannot build controls "
+ "for #%d (error %d)\n", codec->addr, err);
err = snd_hda_codec_reset(codec);
if (err < 0) {
printk(KERN_ERR
@@ -2979,8 +2983,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
val |= channels - 1;
switch (snd_pcm_format_width(format)) {
- case 8: val |= 0x00; break;
- case 16: val |= 0x10; break;
+ case 8:
+ val |= 0x00;
+ break;
+ case 16:
+ val |= 0x10;
+ break;
case 20:
case 24:
case 32:
@@ -3298,7 +3306,8 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type)
if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
return audio_idx[type][i];
- snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]);
+ snd_printk(KERN_WARNING "Too many %s devices\n",
+ snd_hda_pcm_type_name[type]);
return -EAGAIN;
}
@@ -3336,7 +3345,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
err = codec->patch_ops.build_pcms(codec);
if (err < 0) {
printk(KERN_ERR "hda_codec: cannot build PCMs"
- "for #%d (error %d)\n", codec->addr, err);
+ "for #%d (error %d)\n", codec->addr, err);
err = snd_hda_codec_reset(codec);
if (err < 0) {
printk(KERN_ERR
@@ -3466,8 +3475,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
/**
* snd_hda_check_board_codec_sid_config - compare the current codec
- subsystem ID with the
- config table
+ subsystem ID with the
+ config table
This is important for Gateway notebooks with SB450 HDA Audio
where the vendor ID of the PCI device is:
@@ -3607,7 +3616,7 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
*
* Increment the power-up counter and power up the hardware really when
* not turned on yet.
- */
+ */
void snd_hda_power_up(struct hda_codec *codec)
{
struct hda_bus *bus = codec->bus;
@@ -3636,7 +3645,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up);
*
* Decrement the power-up counter and schedules the power-off work if
* the counter rearches to zero.
- */
+ */
void snd_hda_power_down(struct hda_codec *codec)
{
--codec->power_count;
@@ -3662,7 +3671,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_down);
*
* This function is supposed to be set or called from the check_power_status
* patch ops.
- */
+ */
int snd_hda_check_amp_list_power(struct hda_codec *codec,
struct hda_loopback_check *check,
hda_nid_t nid)
@@ -3830,7 +3839,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
{
/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
- set_dig_out_convert(codec, nid,
+ set_dig_out_convert(codec, nid,
codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
-1);
snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
@@ -4089,13 +4098,13 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
/*
* Sort an associated group of pins according to their sequence numbers.
*/
-static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
+static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
int num_pins)
{
int i, j;
short seq;
hda_nid_t nid;
-
+
for (i = 0; i < num_pins; i++) {
for (j = i + 1; j < num_pins; j++) {
if (sequences[i] > sequences[j]) {
@@ -4123,7 +4132,7 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
* is detected, one of speaker of HP pins is assigned as the primary
* output, i.e. to line_out_pins[0]. So, line_outs is always positive
* if any analog output exists.
- *
+ *
* The analog input pins are assigned to input_pins array.
* The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
* respectively.
@@ -4186,9 +4195,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
case AC_JACK_SPEAKER:
seq = get_defcfg_sequence(def_conf);
assoc = get_defcfg_association(def_conf);
- if (! assoc)
+ if (!assoc)
continue;
- if (! assoc_speaker)
+ if (!assoc_speaker)
assoc_speaker = assoc;
else if (assoc_speaker != assoc)
continue;
@@ -4286,7 +4295,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
cfg->speaker_outs);
sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
cfg->hp_outs);
-
+
/* if we have only one mic, make it AUTO_PIN_MIC */
if (!cfg->input_pins[AUTO_PIN_MIC] &&
cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
@@ -4436,7 +4445,7 @@ EXPORT_SYMBOL_HDA(snd_hda_resume);
/**
* snd_array_new - get a new element from the given array
* @array: the array object
- *
+ *
* Get a new element from the given array. If it exceeds the
* pre-allocated array size, re-allocate the array.
*
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 4228f2fe595..d8da18a9e98 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -22,6 +22,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <asm/unaligned.h>
#include "hda_codec.h"
@@ -331,6 +332,7 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
AC_DIPSIZE_ELD_BUF);
}
+EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
int snd_hdmi_get_eld(struct hdmi_eld *eld,
struct hda_codec *codec, hda_nid_t nid)
@@ -366,6 +368,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
kfree(buf);
return ret;
}
+EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
static void hdmi_show_short_audio_desc(struct cea_sad *a)
{
@@ -404,6 +407,7 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
}
buf[j] = '\0'; /* necessary when j == 0 */
}
+EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
void snd_hdmi_show_eld(struct hdmi_eld *e)
{
@@ -422,6 +426,7 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
for (i = 0; i < e->sad_count; i++)
hdmi_show_short_audio_desc(e->sad + i);
}
+EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
#ifdef CONFIG_PROC_FS
@@ -580,6 +585,7 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
return 0;
}
+EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
{
@@ -588,5 +594,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
eld->proc_entry = NULL;
}
}
+EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index d5c93ad852e..cec68152dcb 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -267,7 +267,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define RIRB_INT_MASK 0x05
/* STATESTS int mask: S3,SD2,SD1,SD0 */
-#define AZX_MAX_CODECS 4
+#define AZX_MAX_CODECS 8
+#define AZX_DEFAULT_CODECS 4
#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
/* SD_CTL bits */
@@ -1367,6 +1368,7 @@ static void azx_bus_reset(struct hda_bus *bus)
/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
+ [AZX_DRIVER_NVIDIA] = 8,
[AZX_DRIVER_TERA] = 1,
};
@@ -1399,7 +1401,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
codecs = 0;
max_slots = azx_max_codecs[chip->driver_type];
if (!max_slots)
- max_slots = AZX_MAX_CODECS;
+ max_slots = AZX_DEFAULT_CODECS;
/* First try to probe all given codec slots */
for (c = 0; c < max_slots; c++) {
@@ -2263,10 +2265,16 @@ static int azx_dev_free(struct snd_device *device)
static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
{}
};
@@ -2354,6 +2362,9 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
static struct snd_pci_quirk msi_black_list[] __devinitdata = {
SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
+ SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
+ SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
+ SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
{}
};
@@ -2372,6 +2383,13 @@ static void __devinit check_msi(struct azx *chip)
"hda_intel: msi for device %04x:%04x set to %d\n",
q->subvendor, q->subdevice, q->value);
chip->msi = q->value;
+ return;
+ }
+
+ /* NVidia chipsets seem to cause troubles with MSI */
+ if (chip->driver_type == AZX_DRIVER_NVIDIA) {
+ printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n");
+ chip->msi = 0;
}
}
@@ -2700,6 +2718,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{ PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
/* PCH */
{ PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
+ { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH },
/* CPT */
{ PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
/* SCH */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index e6d1bdff1b6..e9fdfc4b1c5 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -519,14 +519,6 @@ static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
ad198x_power_eapd(codec);
return 0;
}
-
-static int ad198x_resume(struct hda_codec *codec)
-{
- ad198x_init(codec);
- snd_hda_codec_resume_amp(codec);
- snd_hda_codec_resume_cache(codec);
- return 0;
-}
#endif
static struct hda_codec_ops ad198x_patch_ops = {
@@ -539,7 +531,6 @@ static struct hda_codec_ops ad198x_patch_ops = {
#endif
#ifdef SND_HDA_NEEDS_RESUME
.suspend = ad198x_suspend,
- .resume = ad198x_resume,
#endif
.reboot_notify = ad198x_shutup,
};
@@ -1896,6 +1887,14 @@ static int patch_ad1981(struct hda_codec *codec)
case AD1981_THINKPAD:
spec->mixers[0] = ad1981_thinkpad_mixers;
spec->input_mux = &ad1981_thinkpad_capture_source;
+ /* set the upper-limit for mixer amp to 0dB for avoiding the
+ * possible damage by overloading
+ */
+ snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
+ (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (1 << AC_AMPCAP_MUTE_SHIFT));
break;
case AD1981_TOSHIBA:
spec->mixers[0] = ad1981_hp_mixers;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 194a28c5499..61682e1d09d 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1591,6 +1591,21 @@ static int patch_cxt5047(struct hda_codec *codec)
#endif
}
spec->vmaster_nid = 0x13;
+
+ switch (codec->subsystem_id >> 16) {
+ case 0x103c:
+ /* HP laptops have really bad sound over 0 dB on NID 0x10.
+ * Fix max PCM level to 0 dB (originally it has 0x1e steps
+ * with 0 dB offset 0x17)
+ */
+ snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
+ (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (1 << AC_AMPCAP_MUTE_SHIFT));
+ break;
+ }
+
return 0;
}
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
new file mode 100644
index 00000000000..2c2bafbf025
--- /dev/null
+++ b/sound/pci/hda/patch_hdmi.c
@@ -0,0 +1,849 @@
+/*
+ *
+ * patch_hdmi.c - routines for HDMI/DisplayPort codecs
+ *
+ * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
+ *
+ * Authors:
+ * Wu Fengguang <wfg@linux.intel.com>
+ *
+ * Maintained by:
+ * Wu Fengguang <wfg@linux.intel.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.
+ */
+
+
+struct hdmi_spec {
+ int num_cvts;
+ int num_pins;
+ hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */
+ hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */
+
+ /*
+ * source connection for each pin
+ */
+ hda_nid_t pin_cvt[MAX_HDMI_PINS+1];
+
+ /*
+ * HDMI sink attached to each pin
+ */
+ struct hdmi_eld sink_eld[MAX_HDMI_PINS];
+
+ /*
+ * export one pcm per pipe
+ */
+ struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
+
+ /*
+ * nvhdmi specific
+ */
+ struct hda_multi_out multiout;
+ unsigned int codec_type;
+};
+
+
+struct hdmi_audio_infoframe {
+ u8 type; /* 0x84 */
+ u8 ver; /* 0x01 */
+ u8 len; /* 0x0a */
+
+ u8 checksum; /* PB0 */
+ u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
+ u8 SS01_SF24;
+ u8 CXT04;
+ u8 CA;
+ u8 LFEPBL01_LSV36_DM_INH7;
+ u8 reserved[5]; /* PB6 - PB10 */
+};
+
+/*
+ * CEA speaker placement:
+ *
+ * FLH FCH FRH
+ * FLW FL FLC FC FRC FR FRW
+ *
+ * LFE
+ * TC
+ *
+ * RL RLC RC RRC RR
+ *
+ * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
+ * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
+ */
+enum cea_speaker_placement {
+ FL = (1 << 0), /* Front Left */
+ FC = (1 << 1), /* Front Center */
+ FR = (1 << 2), /* Front Right */
+ FLC = (1 << 3), /* Front Left Center */
+ FRC = (1 << 4), /* Front Right Center */
+ RL = (1 << 5), /* Rear Left */
+ RC = (1 << 6), /* Rear Center */
+ RR = (1 << 7), /* Rear Right */
+ RLC = (1 << 8), /* Rear Left Center */
+ RRC = (1 << 9), /* Rear Right Center */
+ LFE = (1 << 10), /* Low Frequency Effect */
+ FLW = (1 << 11), /* Front Left Wide */
+ FRW = (1 << 12), /* Front Right Wide */
+ FLH = (1 << 13), /* Front Left High */
+ FCH = (1 << 14), /* Front Center High */
+ FRH = (1 << 15), /* Front Right High */
+ TC = (1 << 16), /* Top Center */
+};
+
+/*
+ * ELD SA bits in the CEA Speaker Allocation data block
+ */
+static int eld_speaker_allocation_bits[] = {
+ [0] = FL | FR,
+ [1] = LFE,
+ [2] = FC,
+ [3] = RL | RR,
+ [4] = RC,
+ [5] = FLC | FRC,
+ [6] = RLC | RRC,
+ /* the following are not defined in ELD yet */
+ [7] = FLW | FRW,
+ [8] = FLH | FRH,
+ [9] = TC,
+ [10] = FCH,
+};
+
+struct cea_channel_speaker_allocation {
+ int ca_index;
+ int speakers[8];
+
+ /* derived values, just for convenience */
+ int channels;
+ int spk_mask;
+};
+
+/*
+ * ALSA sequence is:
+ *
+ * surround40 surround41 surround50 surround51 surround71
+ * ch0 front left = = = =
+ * ch1 front right = = = =
+ * ch2 rear left = = = =
+ * ch3 rear right = = = =
+ * ch4 LFE center center center
+ * ch5 LFE LFE
+ * ch6 side left
+ * ch7 side right
+ *
+ * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
+ */
+static int hdmi_channel_mapping[0x32][8] = {
+ /* stereo */
+ [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
+ /* 2.1 */
+ [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
+ /* Dolby Surround */
+ [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
+ /* surround40 */
+ [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
+ /* 4ch */
+ [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
+ /* surround41 */
+ [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
+ /* surround50 */
+ [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
+ /* surround51 */
+ [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
+ /* 7.1 */
+ [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
+};
+
+/*
+ * This is an ordered list!
+ *
+ * The preceding ones have better chances to be selected by
+ * hdmi_setup_channel_allocation().
+ */
+static struct cea_channel_speaker_allocation channel_allocations[] = {
+/* channel: 7 6 5 4 3 2 1 0 */
+{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
+ /* 2.1 */
+{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
+ /* Dolby Surround */
+{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
+ /* surround40 */
+{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
+ /* surround41 */
+{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
+ /* surround50 */
+{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
+ /* surround51 */
+{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
+ /* 6.1 */
+{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
+ /* surround71 */
+{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
+
+{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
+{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
+{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
+{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
+{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
+{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
+{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
+{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
+{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
+{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
+{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
+{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
+{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
+{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
+{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
+{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
+{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
+{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
+{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
+{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
+{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
+{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
+{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
+{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
+{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
+{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
+{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
+{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
+{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
+{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
+{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
+{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
+};
+
+
+/*
+ * HDMI routines
+ */
+
+static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
+{
+ int i;
+
+ for (i = 0; nids[i]; i++)
+ if (nids[i] == nid)
+ return i;
+
+ snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
+ return -EINVAL;
+}
+
+static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
+ struct hdmi_eld *eld)
+{
+ if (!snd_hdmi_get_eld(eld, codec, pin_nid))
+ snd_hdmi_show_eld(eld);
+}
+
+#ifdef BE_PARANOID
+static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
+ int *packet_index, int *byte_index)
+{
+ int val;
+
+ val = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_HDMI_DIP_INDEX, 0);
+
+ *packet_index = val >> 5;
+ *byte_index = val & 0x1f;
+}
+#endif
+
+static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
+ int packet_index, int byte_index)
+{
+ int val;
+
+ val = (packet_index << 5) | (byte_index & 0x1f);
+
+ snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
+}
+
+static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
+ unsigned char val)
+{
+ snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
+}
+
+static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
+{
+ /* Unmute */
+ if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
+ snd_hda_codec_write(codec, pin_nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+ /* Enable pin out */
+ snd_hda_codec_write(codec, pin_nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+}
+
+static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
+{
+ return 1 + snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CVT_CHAN_COUNT, 0);
+}
+
+static void hdmi_set_channel_count(struct hda_codec *codec,
+ hda_nid_t nid, int chs)
+{
+ if (chs != hdmi_get_channel_count(codec, nid))
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
+}
+
+
+/*
+ * Channel mapping routines
+ */
+
+/*
+ * Compute derived values in channel_allocations[].
+ */
+static void init_channel_allocations(void)
+{
+ int i, j;
+ struct cea_channel_speaker_allocation *p;
+
+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+ p = channel_allocations + i;
+ p->channels = 0;
+ p->spk_mask = 0;
+ for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
+ if (p->speakers[j]) {
+ p->channels++;
+ p->spk_mask |= p->speakers[j];
+ }
+ }
+}
+
+/*
+ * The transformation takes two steps:
+ *
+ * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
+ * spk_mask => (channel_allocations[]) => ai->CA
+ *
+ * TODO: it could select the wrong CA from multiple candidates.
+*/
+static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
+ struct hdmi_audio_infoframe *ai)
+{
+ struct hdmi_spec *spec = codec->spec;
+ struct hdmi_eld *eld;
+ int i;
+ int spk_mask = 0;
+ int channels = 1 + (ai->CC02_CT47 & 0x7);
+ char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
+
+ /*
+ * CA defaults to 0 for basic stereo audio
+ */
+ if (channels <= 2)
+ return 0;
+
+ i = hda_node_index(spec->pin_cvt, nid);
+ if (i < 0)
+ return 0;
+ eld = &spec->sink_eld[i];
+
+ /*
+ * HDMI sink's ELD info cannot always be retrieved for now, e.g.
+ * in console or for audio devices. Assume the highest speakers
+ * configuration, to _not_ prohibit multi-channel audio playback.
+ */
+ if (!eld->spk_alloc)
+ eld->spk_alloc = 0xffff;
+
+ /*
+ * expand ELD's speaker allocation mask
+ *
+ * ELD tells the speaker mask in a compact(paired) form,
+ * expand ELD's notions to match the ones used by Audio InfoFrame.
+ */
+ for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
+ if (eld->spk_alloc & (1 << i))
+ spk_mask |= eld_speaker_allocation_bits[i];
+ }
+
+ /* search for the first working match in the CA table */
+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+ if (channels == channel_allocations[i].channels &&
+ (spk_mask & channel_allocations[i].spk_mask) ==
+ channel_allocations[i].spk_mask) {
+ ai->CA = channel_allocations[i].ca_index;
+ break;
+ }
+ }
+
+ snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
+ snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
+ ai->CA, channels, buf);
+
+ return ai->CA;
+}
+
+static void hdmi_debug_channel_mapping(struct hda_codec *codec,
+ hda_nid_t pin_nid)
+{
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ int i;
+ int slot;
+
+ for (i = 0; i < 8; i++) {
+ slot = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_HDMI_CHAN_SLOT, i);
+ printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
+ slot >> 4, slot & 0xf);
+ }
+#endif
+}
+
+
+static void hdmi_setup_channel_mapping(struct hda_codec *codec,
+ hda_nid_t pin_nid,
+ struct hdmi_audio_infoframe *ai)
+{
+ int i;
+ int ca = ai->CA;
+ int err;
+
+ if (hdmi_channel_mapping[ca][1] == 0) {
+ for (i = 0; i < channel_allocations[ca].channels; i++)
+ hdmi_channel_mapping[ca][i] = i | (i << 4);
+ for (; i < 8; i++)
+ hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
+ }
+
+ for (i = 0; i < 8; i++) {
+ err = snd_hda_codec_write(codec, pin_nid, 0,
+ AC_VERB_SET_HDMI_CHAN_SLOT,
+ hdmi_channel_mapping[ca][i]);
+ if (err) {
+ snd_printdd(KERN_NOTICE
+ "HDMI: channel mapping failed\n");
+ break;
+ }
+ }
+
+ hdmi_debug_channel_mapping(codec, pin_nid);
+}
+
+
+/*
+ * Audio InfoFrame routines
+ */
+
+/*
+ * Enable Audio InfoFrame Transmission
+ */
+static void hdmi_start_infoframe_trans(struct hda_codec *codec,
+ hda_nid_t pin_nid)
+{
+ hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
+ snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
+ AC_DIPXMIT_BEST);
+}
+
+/*
+ * Disable Audio InfoFrame Transmission
+ */
+static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
+ hda_nid_t pin_nid)
+{
+ hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
+ snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
+ AC_DIPXMIT_DISABLE);
+}
+
+static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
+{
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ int i;
+ int size;
+
+ size = snd_hdmi_get_eld_size(codec, pin_nid);
+ printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
+
+ for (i = 0; i < 8; i++) {
+ size = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_HDMI_DIP_SIZE, i);
+ printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
+ }
+#endif
+}
+
+static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
+{
+#ifdef BE_PARANOID
+ int i, j;
+ int size;
+ int pi, bi;
+ for (i = 0; i < 8; i++) {
+ size = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_HDMI_DIP_SIZE, i);
+ if (size == 0)
+ continue;
+
+ hdmi_set_dip_index(codec, pin_nid, i, 0x0);
+ for (j = 1; j < 1000; j++) {
+ hdmi_write_dip_byte(codec, pin_nid, 0x0);
+ hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
+ if (pi != i)
+ snd_printd(KERN_INFO "dip index %d: %d != %d\n",
+ bi, pi, i);
+ if (bi == 0) /* byte index wrapped around */
+ break;
+ }
+ snd_printd(KERN_INFO
+ "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
+ i, size, j);
+ }
+#endif
+}
+
+static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
+{
+ u8 *bytes = (u8 *)ai;
+ u8 sum = 0;
+ int i;
+
+ ai->checksum = 0;
+
+ for (i = 0; i < sizeof(*ai); i++)
+ sum += bytes[i];
+
+ ai->checksum = -sum;
+}
+
+static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
+ hda_nid_t pin_nid,
+ struct hdmi_audio_infoframe *ai)
+{
+ u8 *bytes = (u8 *)ai;
+ int i;
+
+ hdmi_debug_dip_size(codec, pin_nid);
+ hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
+
+ hdmi_checksum_audio_infoframe(ai);
+
+ hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
+ for (i = 0; i < sizeof(*ai); i++)
+ hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
+}
+
+static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
+ struct hdmi_audio_infoframe *ai)
+{
+ u8 *bytes = (u8 *)ai;
+ u8 val;
+ int i;
+
+ if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
+ != AC_DIPXMIT_BEST)
+ return false;
+
+ hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
+ for (i = 0; i < sizeof(*ai); i++) {
+ val = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_HDMI_DIP_DATA, 0);
+ if (val != bytes[i])
+ return false;
+ }
+
+ return true;
+}
+
+static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
+ struct snd_pcm_substream *substream)
+{
+ struct hdmi_spec *spec = codec->spec;
+ hda_nid_t pin_nid;
+ int i;
+ struct hdmi_audio_infoframe ai = {
+ .type = 0x84,
+ .ver = 0x01,
+ .len = 0x0a,
+ .CC02_CT47 = substream->runtime->channels - 1,
+ };
+
+ hdmi_setup_channel_allocation(codec, nid, &ai);
+
+ for (i = 0; i < spec->num_pins; i++) {
+ if (spec->pin_cvt[i] != nid)
+ continue;
+ if (!spec->sink_eld[i].monitor_present)
+ continue;
+
+ pin_nid = spec->pin[i];
+ if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
+ snd_printdd("hdmi_setup_audio_infoframe: "
+ "cvt=%d pin=%d channels=%d\n",
+ nid, pin_nid,
+ substream->runtime->channels);
+ hdmi_setup_channel_mapping(codec, pin_nid, &ai);
+ hdmi_stop_infoframe_trans(codec, pin_nid);
+ hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
+ hdmi_start_infoframe_trans(codec, pin_nid);
+ }
+ }
+}
+
+
+/*
+ * Unsolicited events
+ */
+
+static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
+{
+ struct hdmi_spec *spec = codec->spec;
+ int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
+ int pind = !!(res & AC_UNSOL_RES_PD);
+ int eldv = !!(res & AC_UNSOL_RES_ELDV);
+ int index;
+
+ printk(KERN_INFO
+ "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
+ tag, pind, eldv);
+
+ index = hda_node_index(spec->pin, tag);
+ if (index < 0)
+ return;
+
+ spec->sink_eld[index].monitor_present = pind;
+ spec->sink_eld[index].eld_valid = eldv;
+
+ if (pind && eldv) {
+ hdmi_get_show_eld(codec, spec->pin[index],
+ &spec->sink_eld[index]);
+ /* TODO: do real things about ELD */
+ }
+}
+
+static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
+{
+ int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
+ int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
+ int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
+ int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
+
+ printk(KERN_INFO
+ "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
+ tag,
+ subtag,
+ cp_state,
+ cp_ready);
+
+ /* TODO */
+ if (cp_state)
+ ;
+ if (cp_ready)
+ ;
+}
+
+
+static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ struct hdmi_spec *spec = codec->spec;
+ int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
+ int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
+
+ if (hda_node_index(spec->pin, tag) < 0) {
+ snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
+ return;
+ }
+
+ if (subtag == 0)
+ hdmi_intrinsic_event(codec, res);
+ else
+ hdmi_non_intrinsic_event(codec, res);
+}
+
+/*
+ * Callbacks
+ */
+
+static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
+ u32 stream_tag, int format)
+{
+ int tag;
+ int fmt;
+
+ tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
+ fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
+
+ snd_printdd("hdmi_setup_stream: "
+ "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
+ nid,
+ tag == stream_tag ? "" : "new-",
+ stream_tag,
+ fmt == format ? "" : "new-",
+ format);
+
+ if (tag != stream_tag)
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_CHANNEL_STREAMID,
+ stream_tag << 4);
+ if (fmt != format)
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_STREAM_FORMAT, format);
+}
+
+/*
+ * HDA/HDMI auto parsing
+ */
+
+static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
+{
+ struct hdmi_spec *spec = codec->spec;
+ hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
+ int conn_len, curr;
+ int index;
+
+ if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
+ snd_printk(KERN_WARNING
+ "HDMI: pin %d wcaps %#x "
+ "does not support connection list\n",
+ pin_nid, get_wcaps(codec, pin_nid));
+ return -EINVAL;
+ }
+
+ conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
+ HDA_MAX_CONNECTIONS);
+ if (conn_len > 1)
+ curr = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_CONNECT_SEL, 0);
+ else
+ curr = 0;
+
+ index = hda_node_index(spec->pin, pin_nid);
+ if (index < 0)
+ return -EINVAL;
+
+ spec->pin_cvt[index] = conn_list[curr];
+
+ return 0;
+}
+
+static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
+ struct hdmi_eld *eld)
+{
+ int present = snd_hda_pin_sense(codec, pin_nid);
+
+ eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
+ eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
+
+ if (present & AC_PINSENSE_ELDV)
+ hdmi_get_show_eld(codec, pin_nid, eld);
+}
+
+static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
+{
+ struct hdmi_spec *spec = codec->spec;
+
+ if (spec->num_pins >= MAX_HDMI_PINS) {
+ snd_printk(KERN_WARNING
+ "HDMI: no space for pin %d\n", pin_nid);
+ return -EINVAL;
+ }
+
+ hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
+
+ spec->pin[spec->num_pins] = pin_nid;
+ spec->num_pins++;
+
+ /*
+ * It is assumed that converter nodes come first in the node list and
+ * hence have been registered and usable now.
+ */
+ return hdmi_read_pin_conn(codec, pin_nid);
+}
+
+static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct hdmi_spec *spec = codec->spec;
+
+ if (spec->num_cvts >= MAX_HDMI_CVTS) {
+ snd_printk(KERN_WARNING
+ "HDMI: no space for converter %d\n", nid);
+ return -EINVAL;
+ }
+
+ spec->cvt[spec->num_cvts] = nid;
+ spec->num_cvts++;
+
+ return 0;
+}
+
+static int hdmi_parse_codec(struct hda_codec *codec)
+{
+ hda_nid_t nid;
+ int i, nodes;
+
+ nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
+ if (!nid || nodes < 0) {
+ snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < nodes; i++, nid++) {
+ unsigned int caps;
+ unsigned int type;
+
+ caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
+ type = get_wcaps_type(caps);
+
+ if (!(caps & AC_WCAP_DIGITAL))
+ continue;
+
+ switch (type) {
+ case AC_WID_AUD_OUT:
+ if (hdmi_add_cvt(codec, nid) < 0)
+ return -EINVAL;
+ break;
+ case AC_WID_PIN:
+ caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
+ if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
+ continue;
+ if (hdmi_add_pin(codec, nid) < 0)
+ return -EINVAL;
+ break;
+ }
+ }
+
+ /*
+ * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
+ * can be lost and presence sense verb will become inaccurate if the
+ * HDA link is powered off at hot plug or hw initialization time.
+ */
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
+ AC_PWRST_EPSS))
+ codec->bus->power_keep_link_on = 1;
+#endif
+
+ return 0;
+}
+
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 918f40378d5..88d035104cc 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -40,815 +40,20 @@
*
* The HDA correspondence of pipes/ports are converter/pin nodes.
*/
-#define INTEL_HDMI_CVTS 2
-#define INTEL_HDMI_PINS 3
+#define MAX_HDMI_CVTS 2
+#define MAX_HDMI_PINS 3
-static char *intel_hdmi_pcm_names[INTEL_HDMI_CVTS] = {
+#include "patch_hdmi.c"
+
+static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
"INTEL HDMI 0",
"INTEL HDMI 1",
};
-struct intel_hdmi_spec {
- int num_cvts;
- int num_pins;
- hda_nid_t cvt[INTEL_HDMI_CVTS+1]; /* audio sources */
- hda_nid_t pin[INTEL_HDMI_PINS+1]; /* audio sinks */
-
- /*
- * source connection for each pin
- */
- hda_nid_t pin_cvt[INTEL_HDMI_PINS+1];
-
- /*
- * HDMI sink attached to each pin
- */
- struct hdmi_eld sink_eld[INTEL_HDMI_PINS];
-
- /*
- * export one pcm per pipe
- */
- struct hda_pcm pcm_rec[INTEL_HDMI_CVTS];
-};
-
-struct hdmi_audio_infoframe {
- u8 type; /* 0x84 */
- u8 ver; /* 0x01 */
- u8 len; /* 0x0a */
-
- u8 checksum; /* PB0 */
- u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
- u8 SS01_SF24;
- u8 CXT04;
- u8 CA;
- u8 LFEPBL01_LSV36_DM_INH7;
- u8 reserved[5]; /* PB6 - PB10 */
-};
-
-/*
- * CEA speaker placement:
- *
- * FLH FCH FRH
- * FLW FL FLC FC FRC FR FRW
- *
- * LFE
- * TC
- *
- * RL RLC RC RRC RR
- *
- * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
- * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
- */
-enum cea_speaker_placement {
- FL = (1 << 0), /* Front Left */
- FC = (1 << 1), /* Front Center */
- FR = (1 << 2), /* Front Right */
- FLC = (1 << 3), /* Front Left Center */
- FRC = (1 << 4), /* Front Right Center */
- RL = (1 << 5), /* Rear Left */
- RC = (1 << 6), /* Rear Center */
- RR = (1 << 7), /* Rear Right */
- RLC = (1 << 8), /* Rear Left Center */
- RRC = (1 << 9), /* Rear Right Center */
- LFE = (1 << 10), /* Low Frequency Effect */
- FLW = (1 << 11), /* Front Left Wide */
- FRW = (1 << 12), /* Front Right Wide */
- FLH = (1 << 13), /* Front Left High */
- FCH = (1 << 14), /* Front Center High */
- FRH = (1 << 15), /* Front Right High */
- TC = (1 << 16), /* Top Center */
-};
-
-/*
- * ELD SA bits in the CEA Speaker Allocation data block
- */
-static int eld_speaker_allocation_bits[] = {
- [0] = FL | FR,
- [1] = LFE,
- [2] = FC,
- [3] = RL | RR,
- [4] = RC,
- [5] = FLC | FRC,
- [6] = RLC | RRC,
- /* the following are not defined in ELD yet */
- [7] = FLW | FRW,
- [8] = FLH | FRH,
- [9] = TC,
- [10] = FCH,
-};
-
-struct cea_channel_speaker_allocation {
- int ca_index;
- int speakers[8];
-
- /* derived values, just for convenience */
- int channels;
- int spk_mask;
-};
-
-/*
- * ALSA sequence is:
- *
- * surround40 surround41 surround50 surround51 surround71
- * ch0 front left = = = =
- * ch1 front right = = = =
- * ch2 rear left = = = =
- * ch3 rear right = = = =
- * ch4 LFE center center center
- * ch5 LFE LFE
- * ch6 side left
- * ch7 side right
- *
- * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
- */
-static int hdmi_channel_mapping[0x32][8] = {
- /* stereo */
- [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
- /* 2.1 */
- [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
- /* Dolby Surround */
- [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
- /* surround40 */
- [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
- /* 4ch */
- [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
- /* surround41 */
- [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
- /* surround50 */
- [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
- /* surround51 */
- [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
- /* 7.1 */
- [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
-};
-
-/*
- * This is an ordered list!
- *
- * The preceding ones have better chances to be selected by
- * hdmi_setup_channel_allocation().
- */
-static struct cea_channel_speaker_allocation channel_allocations[] = {
-/* channel: 7 6 5 4 3 2 1 0 */
-{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
- /* 2.1 */
-{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
- /* Dolby Surround */
-{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
- /* surround40 */
-{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
- /* surround41 */
-{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
- /* surround50 */
-{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
- /* surround51 */
-{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
- /* 6.1 */
-{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
- /* surround71 */
-{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
-
-{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
-{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
-{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
-{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
-{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
-{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
-{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
-{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
-{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
-{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
-{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
-{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
-{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
-{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
-{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
-{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
-{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
-{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
-};
-
-/*
- * HDA/HDMI auto parsing
- */
-
-static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
-{
- int i;
-
- for (i = 0; nids[i]; i++)
- if (nids[i] == nid)
- return i;
-
- snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
- return -EINVAL;
-}
-
-static int intel_hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
-{
- struct intel_hdmi_spec *spec = codec->spec;
- hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
- int conn_len, curr;
- int index;
-
- if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
- snd_printk(KERN_WARNING
- "HDMI: pin %d wcaps %#x "
- "does not support connection list\n",
- pin_nid, get_wcaps(codec, pin_nid));
- return -EINVAL;
- }
-
- conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
- HDA_MAX_CONNECTIONS);
- if (conn_len > 1)
- curr = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_CONNECT_SEL, 0);
- else
- curr = 0;
-
- index = hda_node_index(spec->pin, pin_nid);
- if (index < 0)
- return -EINVAL;
-
- spec->pin_cvt[index] = conn_list[curr];
-
- return 0;
-}
-
-static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
- struct hdmi_eld *eld)
-{
- if (!snd_hdmi_get_eld(eld, codec, pin_nid))
- snd_hdmi_show_eld(eld);
-}
-
-static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
- struct hdmi_eld *eld)
-{
- int present = snd_hda_pin_sense(codec, pin_nid);
-
- eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
- eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
-
- if (present & AC_PINSENSE_ELDV)
- hdmi_get_show_eld(codec, pin_nid, eld);
-}
-
-static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
-{
- struct intel_hdmi_spec *spec = codec->spec;
-
- if (spec->num_pins >= INTEL_HDMI_PINS) {
- snd_printk(KERN_WARNING
- "HDMI: no space for pin %d \n", pin_nid);
- return -EINVAL;
- }
-
- hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
-
- spec->pin[spec->num_pins] = pin_nid;
- spec->num_pins++;
-
- /*
- * It is assumed that converter nodes come first in the node list and
- * hence have been registered and usable now.
- */
- return intel_hdmi_read_pin_conn(codec, pin_nid);
-}
-
-static int intel_hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
-{
- struct intel_hdmi_spec *spec = codec->spec;
-
- if (spec->num_cvts >= INTEL_HDMI_CVTS) {
- snd_printk(KERN_WARNING
- "HDMI: no space for converter %d \n", nid);
- return -EINVAL;
- }
-
- spec->cvt[spec->num_cvts] = nid;
- spec->num_cvts++;
-
- return 0;
-}
-
-static int intel_hdmi_parse_codec(struct hda_codec *codec)
-{
- hda_nid_t nid;
- int i, nodes;
-
- nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
- if (!nid || nodes < 0) {
- snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
- return -EINVAL;
- }
-
- for (i = 0; i < nodes; i++, nid++) {
- unsigned int caps;
- unsigned int type;
-
- caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
- type = get_wcaps_type(caps);
-
- if (!(caps & AC_WCAP_DIGITAL))
- continue;
-
- switch (type) {
- case AC_WID_AUD_OUT:
- if (intel_hdmi_add_cvt(codec, nid) < 0)
- return -EINVAL;
- break;
- case AC_WID_PIN:
- caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
- if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
- continue;
- if (intel_hdmi_add_pin(codec, nid) < 0)
- return -EINVAL;
- break;
- }
- }
-
- /*
- * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
- * can be lost and presence sense verb will become inaccurate if the
- * HDA link is powered off at hot plug or hw initialization time.
- */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
- AC_PWRST_EPSS))
- codec->bus->power_keep_link_on = 1;
-#endif
-
- return 0;
-}
-
-/*
- * HDMI routines
- */
-
-#ifdef BE_PARANOID
-static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
- int *packet_index, int *byte_index)
-{
- int val;
-
- val = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_DIP_INDEX, 0);
-
- *packet_index = val >> 5;
- *byte_index = val & 0x1f;
-}
-#endif
-
-static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
- int packet_index, int byte_index)
-{
- int val;
-
- val = (packet_index << 5) | (byte_index & 0x1f);
-
- snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
-}
-
-static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
- unsigned char val)
-{
- snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
-}
-
-static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
-{
- /* Unmute */
- if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
- /* Enable pin out */
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
-}
-
-/*
- * Enable Audio InfoFrame Transmission
- */
-static void hdmi_start_infoframe_trans(struct hda_codec *codec,
- hda_nid_t pin_nid)
-{
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
- snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
- AC_DIPXMIT_BEST);
-}
-
-/*
- * Disable Audio InfoFrame Transmission
- */
-static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
- hda_nid_t pin_nid)
-{
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
- snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
- AC_DIPXMIT_DISABLE);
-}
-
-static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
-{
- return 1 + snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_CVT_CHAN_COUNT, 0);
-}
-
-static void hdmi_set_channel_count(struct hda_codec *codec,
- hda_nid_t nid, int chs)
-{
- if (chs != hdmi_get_channel_count(codec, nid))
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
-}
-
-static void hdmi_debug_channel_mapping(struct hda_codec *codec,
- hda_nid_t pin_nid)
-{
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- int i;
- int slot;
-
- for (i = 0; i < 8; i++) {
- slot = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_CHAN_SLOT, i);
- printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
- slot >> 4, slot & 0xf);
- }
-#endif
-}
-
-
-/*
- * Audio InfoFrame routines
- */
-
-static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
-{
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- int i;
- int size;
-
- size = snd_hdmi_get_eld_size(codec, pin_nid);
- printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
-
- for (i = 0; i < 8; i++) {
- size = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_DIP_SIZE, i);
- printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
- }
-#endif
-}
-
-static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
-{
-#ifdef BE_PARANOID
- int i, j;
- int size;
- int pi, bi;
- for (i = 0; i < 8; i++) {
- size = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_DIP_SIZE, i);
- if (size == 0)
- continue;
-
- hdmi_set_dip_index(codec, pin_nid, i, 0x0);
- for (j = 1; j < 1000; j++) {
- hdmi_write_dip_byte(codec, pin_nid, 0x0);
- hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
- if (pi != i)
- snd_printd(KERN_INFO "dip index %d: %d != %d\n",
- bi, pi, i);
- if (bi == 0) /* byte index wrapped around */
- break;
- }
- snd_printd(KERN_INFO
- "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
- i, size, j);
- }
-#endif
-}
-
-static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
-{
- u8 *bytes = (u8 *)ai;
- u8 sum = 0;
- int i;
-
- ai->checksum = 0;
-
- for (i = 0; i < sizeof(*ai); i++)
- sum += bytes[i];
-
- ai->checksum = - sum;
-}
-
-static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
- hda_nid_t pin_nid,
- struct hdmi_audio_infoframe *ai)
-{
- u8 *bytes = (u8 *)ai;
- int i;
-
- hdmi_debug_dip_size(codec, pin_nid);
- hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
-
- hdmi_checksum_audio_infoframe(ai);
-
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
- for (i = 0; i < sizeof(*ai); i++)
- hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
-}
-
-/*
- * Compute derived values in channel_allocations[].
- */
-static void init_channel_allocations(void)
-{
- int i, j;
- struct cea_channel_speaker_allocation *p;
-
- for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
- p = channel_allocations + i;
- p->channels = 0;
- p->spk_mask = 0;
- for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
- if (p->speakers[j]) {
- p->channels++;
- p->spk_mask |= p->speakers[j];
- }
- }
-}
-
-/*
- * The transformation takes two steps:
- *
- * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
- * spk_mask => (channel_allocations[]) => ai->CA
- *
- * TODO: it could select the wrong CA from multiple candidates.
-*/
-static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
- struct hdmi_audio_infoframe *ai)
-{
- struct intel_hdmi_spec *spec = codec->spec;
- struct hdmi_eld *eld;
- int i;
- int spk_mask = 0;
- int channels = 1 + (ai->CC02_CT47 & 0x7);
- char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
-
- /*
- * CA defaults to 0 for basic stereo audio
- */
- if (channels <= 2)
- return 0;
-
- i = hda_node_index(spec->pin_cvt, nid);
- if (i < 0)
- return 0;
- eld = &spec->sink_eld[i];
-
- /*
- * HDMI sink's ELD info cannot always be retrieved for now, e.g.
- * in console or for audio devices. Assume the highest speakers
- * configuration, to _not_ prohibit multi-channel audio playback.
- */
- if (!eld->spk_alloc)
- eld->spk_alloc = 0xffff;
-
- /*
- * expand ELD's speaker allocation mask
- *
- * ELD tells the speaker mask in a compact(paired) form,
- * expand ELD's notions to match the ones used by Audio InfoFrame.
- */
- for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
- if (eld->spk_alloc & (1 << i))
- spk_mask |= eld_speaker_allocation_bits[i];
- }
-
- /* search for the first working match in the CA table */
- for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
- if (channels == channel_allocations[i].channels &&
- (spk_mask & channel_allocations[i].spk_mask) ==
- channel_allocations[i].spk_mask) {
- ai->CA = channel_allocations[i].ca_index;
- break;
- }
- }
-
- snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
- snd_printdd(KERN_INFO
- "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
- ai->CA, channels, buf);
-
- return ai->CA;
-}
-
-static void hdmi_setup_channel_mapping(struct hda_codec *codec,
- hda_nid_t pin_nid,
- struct hdmi_audio_infoframe *ai)
-{
- int i;
- int ca = ai->CA;
- int err;
-
- if (hdmi_channel_mapping[ca][1] == 0) {
- for (i = 0; i < channel_allocations[ca].channels; i++)
- hdmi_channel_mapping[ca][i] = i | (i << 4);
- for (; i < 8; i++)
- hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
- }
-
- for (i = 0; i < 8; i++) {
- err = snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_HDMI_CHAN_SLOT,
- hdmi_channel_mapping[ca][i]);
- if (err) {
- snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
- break;
- }
- }
-
- hdmi_debug_channel_mapping(codec, pin_nid);
-}
-
-static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
- struct hdmi_audio_infoframe *ai)
-{
- u8 *bytes = (u8 *)ai;
- u8 val;
- int i;
-
- if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
- != AC_DIPXMIT_BEST)
- return false;
-
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
- for (i = 0; i < sizeof(*ai); i++) {
- val = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_DIP_DATA, 0);
- if (val != bytes[i])
- return false;
- }
-
- return true;
-}
-
-static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
- struct snd_pcm_substream *substream)
-{
- struct intel_hdmi_spec *spec = codec->spec;
- hda_nid_t pin_nid;
- int i;
- struct hdmi_audio_infoframe ai = {
- .type = 0x84,
- .ver = 0x01,
- .len = 0x0a,
- .CC02_CT47 = substream->runtime->channels - 1,
- };
-
- hdmi_setup_channel_allocation(codec, nid, &ai);
-
- for (i = 0; i < spec->num_pins; i++) {
- if (spec->pin_cvt[i] != nid)
- continue;
- if (!spec->sink_eld[i].monitor_present)
- continue;
-
- pin_nid = spec->pin[i];
- if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
- hdmi_setup_channel_mapping(codec, pin_nid, &ai);
- hdmi_stop_infoframe_trans(codec, pin_nid);
- hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
- hdmi_start_infoframe_trans(codec, pin_nid);
- }
- }
-}
-
-
/*
- * Unsolicited events
+ * HDMI callbacks
*/
-static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
-{
- struct intel_hdmi_spec *spec = codec->spec;
- int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
- int pind = !!(res & AC_UNSOL_RES_PD);
- int eldv = !!(res & AC_UNSOL_RES_ELDV);
- int index;
-
- printk(KERN_INFO
- "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
- tag, pind, eldv);
-
- index = hda_node_index(spec->pin, tag);
- if (index < 0)
- return;
-
- spec->sink_eld[index].monitor_present = pind;
- spec->sink_eld[index].eld_valid = eldv;
-
- if (pind && eldv) {
- hdmi_get_show_eld(codec, spec->pin[index], &spec->sink_eld[index]);
- /* TODO: do real things about ELD */
- }
-}
-
-static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
-{
- int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
- int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
- int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
- int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
-
- printk(KERN_INFO
- "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
- tag,
- subtag,
- cp_state,
- cp_ready);
-
- /* TODO */
- if (cp_state)
- ;
- if (cp_ready)
- ;
-}
-
-
-static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- struct intel_hdmi_spec *spec = codec->spec;
- int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
- int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
-
- if (hda_node_index(spec->pin, tag) < 0) {
- snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
- return;
- }
-
- if (subtag == 0)
- hdmi_intrinsic_event(codec, res);
- else
- hdmi_non_intrinsic_event(codec, res);
-}
-
-/*
- * Callbacks
- */
-
-static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
- u32 stream_tag, int format)
-{
- int tag;
- int fmt;
-
- tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
- fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
-
- snd_printdd("hdmi_setup_stream: "
- "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
- nid,
- tag == stream_tag ? "" : "new-",
- stream_tag,
- fmt == format ? "" : "new-",
- format);
-
- if (tag != stream_tag)
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CHANNEL_STREAMID, stream_tag << 4);
- if (fmt != format)
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_STREAM_FORMAT, format);
-}
-
static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
@@ -882,7 +87,7 @@ static struct hda_pcm_stream intel_hdmi_pcm_playback = {
static int intel_hdmi_build_pcms(struct hda_codec *codec)
{
- struct intel_hdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
struct hda_pcm *info = spec->pcm_rec;
int i;
@@ -908,7 +113,7 @@ static int intel_hdmi_build_pcms(struct hda_codec *codec)
static int intel_hdmi_build_controls(struct hda_codec *codec)
{
- struct intel_hdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
int err;
int i;
@@ -923,7 +128,7 @@ static int intel_hdmi_build_controls(struct hda_codec *codec)
static int intel_hdmi_init(struct hda_codec *codec)
{
- struct intel_hdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
int i;
for (i = 0; spec->pin[i]; i++) {
@@ -937,7 +142,7 @@ static int intel_hdmi_init(struct hda_codec *codec)
static void intel_hdmi_free(struct hda_codec *codec)
{
- struct intel_hdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
int i;
for (i = 0; i < spec->num_pins; i++)
@@ -951,12 +156,12 @@ static struct hda_codec_ops intel_hdmi_patch_ops = {
.free = intel_hdmi_free,
.build_pcms = intel_hdmi_build_pcms,
.build_controls = intel_hdmi_build_controls,
- .unsol_event = intel_hdmi_unsol_event,
+ .unsol_event = hdmi_unsol_event,
};
static int patch_intel_hdmi(struct hda_codec *codec)
{
- struct intel_hdmi_spec *spec;
+ struct hdmi_spec *spec;
int i;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -964,7 +169,7 @@ static int patch_intel_hdmi(struct hda_codec *codec)
return -ENOMEM;
codec->spec = spec;
- if (intel_hdmi_parse_codec(codec) < 0) {
+ if (hdmi_parse_codec(codec) < 0) {
codec->spec = NULL;
kfree(spec);
return -EINVAL;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 6afdab09bab..3c10c0b149f 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -29,13 +29,23 @@
#include "hda_codec.h"
#include "hda_local.h"
+#define MAX_HDMI_CVTS 1
+#define MAX_HDMI_PINS 1
+
+#include "patch_hdmi.c"
+
+static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
+ "NVIDIA HDMI",
+};
+
/* define below to restrict the supported rates and formats */
/* #define LIMITED_RATE_FMT_SUPPORT */
-struct nvhdmi_spec {
- struct hda_multi_out multiout;
-
- struct hda_pcm pcm_rec;
+enum HDACodec {
+ HDA_CODEC_NVIDIA_MCP7X,
+ HDA_CODEC_NVIDIA_MCP89,
+ HDA_CODEC_NVIDIA_GT21X,
+ HDA_CODEC_INVALID
};
#define Nv_VERB_SET_Channel_Allocation 0xF79
@@ -43,15 +53,18 @@ struct nvhdmi_spec {
#define Nv_VERB_SET_Audio_Protection_On 0xF98
#define Nv_VERB_SET_Audio_Protection_Off 0xF99
-#define Nv_Master_Convert_nid 0x04
-#define Nv_Master_Pin_nid 0x05
+#define nvhdmi_master_con_nid_7x 0x04
+#define nvhdmi_master_pin_nid_7x 0x05
-static hda_nid_t nvhdmi_convert_nids[4] = {
+#define nvhdmi_master_con_nid_89 0x04
+#define nvhdmi_master_pin_nid_89 0x05
+
+static hda_nid_t nvhdmi_con_nids_7x[4] = {
/*front, rear, clfe, rear_surr */
0x6, 0x8, 0xa, 0xc,
};
-static struct hda_verb nvhdmi_basic_init[] = {
+static struct hda_verb nvhdmi_basic_init_7x[] = {
/* set audio protect on */
{ 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
/* enable digital output on pin widget */
@@ -84,22 +97,60 @@ static struct hda_verb nvhdmi_basic_init[] = {
*/
static int nvhdmi_build_controls(struct hda_codec *codec)
{
- struct nvhdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
int err;
+ int i;
- err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
- if (err < 0)
- return err;
+ if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
+ || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
+ for (i = 0; i < codec->num_pcms; i++) {
+ err = snd_hda_create_spdif_out_ctls(codec,
+ spec->cvt[i]);
+ if (err < 0)
+ return err;
+ }
+ } else {
+ err = snd_hda_create_spdif_out_ctls(codec,
+ spec->multiout.dig_out_nid);
+ if (err < 0)
+ return err;
+ }
return 0;
}
static int nvhdmi_init(struct hda_codec *codec)
{
- snd_hda_sequence_write(codec, nvhdmi_basic_init);
+ struct hdmi_spec *spec = codec->spec;
+ int i;
+ if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
+ || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
+ for (i = 0; spec->pin[i]; i++) {
+ hdmi_enable_output(codec, spec->pin[i]);
+ snd_hda_codec_write(codec, spec->pin[i], 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | spec->pin[i]);
+ }
+ } else {
+ snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
+ }
return 0;
}
+static void nvhdmi_free(struct hda_codec *codec)
+{
+ struct hdmi_spec *spec = codec->spec;
+ int i;
+
+ if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
+ || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
+ for (i = 0; i < spec->num_pins; i++)
+ snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
+ }
+
+ kfree(spec);
+}
+
/*
* Digital out
*/
@@ -107,25 +158,25 @@ static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
- struct nvhdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
return snd_hda_multi_out_dig_open(codec, &spec->multiout);
}
-static int nvhdmi_dig_playback_pcm_close_8ch(struct hda_pcm_stream *hinfo,
+static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
- struct nvhdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
int i;
- snd_hda_codec_write(codec, Nv_Master_Convert_nid,
+ snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
0, AC_VERB_SET_CHANNEL_STREAMID, 0);
for (i = 0; i < 4; i++) {
/* set the stream id */
- snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0,
+ snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
AC_VERB_SET_CHANNEL_STREAMID, 0);
/* set the stream format */
- snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0,
+ snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
AC_VERB_SET_STREAM_FORMAT, 0);
}
@@ -136,10 +187,25 @@ static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
- struct nvhdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
+static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ hdmi_set_channel_count(codec, hinfo->nid,
+ substream->runtime->channels);
+
+ hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
+
+ hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
+ return 0;
+}
+
static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
@@ -181,29 +247,29 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
snd_hda_codec_write(codec,
- Nv_Master_Convert_nid,
+ nvhdmi_master_con_nid_7x,
0,
AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
/* set the stream id */
- snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0,
+ snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
/* set the stream format */
- snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0,
+ snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
AC_VERB_SET_STREAM_FORMAT, format);
/* turn on again (if needed) */
/* enable and set the channel status audio/data flag */
if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
snd_hda_codec_write(codec,
- Nv_Master_Convert_nid,
+ nvhdmi_master_con_nid_7x,
0,
AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & 0xff);
snd_hda_codec_write(codec,
- Nv_Master_Convert_nid,
+ nvhdmi_master_con_nid_7x,
0,
AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
}
@@ -220,19 +286,19 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
if (codec->spdif_status_reset &&
(codec->spdif_ctls & AC_DIG1_ENABLE))
snd_hda_codec_write(codec,
- nvhdmi_convert_nids[i],
+ nvhdmi_con_nids_7x[i],
0,
AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
/* set the stream id */
snd_hda_codec_write(codec,
- nvhdmi_convert_nids[i],
+ nvhdmi_con_nids_7x[i],
0,
AC_VERB_SET_CHANNEL_STREAMID,
(stream_tag << 4) | channel_id);
/* set the stream format */
snd_hda_codec_write(codec,
- nvhdmi_convert_nids[i],
+ nvhdmi_con_nids_7x[i],
0,
AC_VERB_SET_STREAM_FORMAT,
format);
@@ -241,12 +307,12 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
if (codec->spdif_status_reset &&
(codec->spdif_ctls & AC_DIG1_ENABLE)) {
snd_hda_codec_write(codec,
- nvhdmi_convert_nids[i],
+ nvhdmi_con_nids_7x[i],
0,
AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & 0xff);
snd_hda_codec_write(codec,
- nvhdmi_convert_nids[i],
+ nvhdmi_con_nids_7x[i],
0,
AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
}
@@ -261,28 +327,47 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
return 0;
}
+static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
{
- struct nvhdmi_spec *spec = codec->spec;
+ struct hdmi_spec *spec = codec->spec;
return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
format, substream);
}
-static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = {
+static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
+ .substreams = 1,
+ .channels_min = 2,
+ .rates = SUPPORTED_RATES,
+ .maxbps = SUPPORTED_MAXBPS,
+ .formats = SUPPORTED_FORMATS,
+ .ops = {
+ .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
+ .cleanup = nvhdmi_playback_pcm_cleanup,
+ },
+};
+
+static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
.substreams = 1,
.channels_min = 2,
.channels_max = 8,
- .nid = Nv_Master_Convert_nid,
+ .nid = nvhdmi_master_con_nid_7x,
.rates = SUPPORTED_RATES,
.maxbps = SUPPORTED_MAXBPS,
.formats = SUPPORTED_FORMATS,
.ops = {
.open = nvhdmi_dig_playback_pcm_open,
- .close = nvhdmi_dig_playback_pcm_close_8ch,
+ .close = nvhdmi_dig_playback_pcm_close_8ch_7x,
.prepare = nvhdmi_dig_playback_pcm_prepare_8ch
},
};
@@ -291,7 +376,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
- .nid = Nv_Master_Convert_nid,
+ .nid = nvhdmi_master_con_nid_7x,
.rates = SUPPORTED_RATES,
.maxbps = SUPPORTED_MAXBPS,
.formats = SUPPORTED_FORMATS,
@@ -302,10 +387,36 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
},
};
-static int nvhdmi_build_pcms_8ch(struct hda_codec *codec)
+static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
+{
+ struct hdmi_spec *spec = codec->spec;
+ struct hda_pcm *info = spec->pcm_rec;
+ int i;
+
+ codec->num_pcms = spec->num_cvts;
+ codec->pcm_info = info;
+
+ for (i = 0; i < codec->num_pcms; i++, info++) {
+ unsigned int chans;
+
+ chans = get_wcaps(codec, spec->cvt[i]);
+ chans = get_wcaps_channels(chans);
+
+ info->name = nvhdmi_pcm_names[i];
+ info->pcm_type = HDA_PCM_TYPE_HDMI;
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK]
+ = nvhdmi_pcm_digital_playback_8ch_89;
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
+ }
+
+ return 0;
+}
+
+static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
{
- struct nvhdmi_spec *spec = codec->spec;
- struct hda_pcm *info = &spec->pcm_rec;
+ struct hdmi_spec *spec = codec->spec;
+ struct hda_pcm *info = spec->pcm_rec;
codec->num_pcms = 1;
codec->pcm_info = info;
@@ -313,15 +424,15 @@ static int nvhdmi_build_pcms_8ch(struct hda_codec *codec)
info->name = "NVIDIA HDMI";
info->pcm_type = HDA_PCM_TYPE_HDMI;
info->stream[SNDRV_PCM_STREAM_PLAYBACK]
- = nvhdmi_pcm_digital_playback_8ch;
+ = nvhdmi_pcm_digital_playback_8ch_7x;
return 0;
}
static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
{
- struct nvhdmi_spec *spec = codec->spec;
- struct hda_pcm *info = &spec->pcm_rec;
+ struct hdmi_spec *spec = codec->spec;
+ struct hda_pcm *info = spec->pcm_rec;
codec->num_pcms = 1;
codec->pcm_info = info;
@@ -334,14 +445,17 @@ static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
return 0;
}
-static void nvhdmi_free(struct hda_codec *codec)
-{
- kfree(codec->spec);
-}
+static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
+ .build_controls = nvhdmi_build_controls,
+ .build_pcms = nvhdmi_build_pcms_8ch_89,
+ .init = nvhdmi_init,
+ .free = nvhdmi_free,
+ .unsol_event = hdmi_unsol_event,
+};
-static struct hda_codec_ops nvhdmi_patch_ops_8ch = {
+static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
.build_controls = nvhdmi_build_controls,
- .build_pcms = nvhdmi_build_pcms_8ch,
+ .build_pcms = nvhdmi_build_pcms_8ch_7x,
.init = nvhdmi_init,
.free = nvhdmi_free,
};
@@ -353,9 +467,36 @@ static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
.free = nvhdmi_free,
};
-static int patch_nvhdmi_8ch(struct hda_codec *codec)
+static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
+{
+ struct hdmi_spec *spec;
+ int i;
+
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (spec == NULL)
+ return -ENOMEM;
+
+ codec->spec = spec;
+ spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
+
+ if (hdmi_parse_codec(codec) < 0) {
+ codec->spec = NULL;
+ kfree(spec);
+ return -EINVAL;
+ }
+ codec->patch_ops = nvhdmi_patch_ops_8ch_89;
+
+ for (i = 0; i < spec->num_pins; i++)
+ snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
+
+ init_channel_allocations();
+
+ return 0;
+}
+
+static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
{
- struct nvhdmi_spec *spec;
+ struct hdmi_spec *spec;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
@@ -365,16 +506,17 @@ static int patch_nvhdmi_8ch(struct hda_codec *codec)
spec->multiout.num_dacs = 0; /* no analog */
spec->multiout.max_channels = 8;
- spec->multiout.dig_out_nid = Nv_Master_Convert_nid;
+ spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
+ spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
- codec->patch_ops = nvhdmi_patch_ops_8ch;
+ codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
return 0;
}
static int patch_nvhdmi_2ch(struct hda_codec *codec)
{
- struct nvhdmi_spec *spec;
+ struct hdmi_spec *spec;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
@@ -384,7 +526,8 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
spec->multiout.num_dacs = 0; /* no analog */
spec->multiout.max_channels = 2;
- spec->multiout.dig_out_nid = Nv_Master_Convert_nid;
+ spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
+ spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
codec->patch_ops = nvhdmi_patch_ops_2ch;
@@ -395,11 +538,24 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
* patch entries
*/
static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
- { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
- { .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
- { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
- { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
- { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
+ { .id = 0x10de0002, .name = "MCP77/78 HDMI",
+ .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de0003, .name = "MCP77/78 HDMI",
+ .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de0005, .name = "MCP77/78 HDMI",
+ .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de0006, .name = "MCP77/78 HDMI",
+ .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de0007, .name = "MCP79/7A HDMI",
+ .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de000a, .name = "GT220 HDMI",
+ .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de000b, .name = "GT21x HDMI",
+ .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de000c, .name = "MCP89 HDMI",
+ .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de000d, .name = "GT240 HDMI",
+ .patch = patch_nvhdmi_8ch_89 },
{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
{} /* terminator */
@@ -410,11 +566,15 @@ MODULE_ALIAS("snd-hda-codec-id:10de0003");
MODULE_ALIAS("snd-hda-codec-id:10de0005");
MODULE_ALIAS("snd-hda-codec-id:10de0006");
MODULE_ALIAS("snd-hda-codec-id:10de0007");
+MODULE_ALIAS("snd-hda-codec-id:10de000a");
+MODULE_ALIAS("snd-hda-codec-id:10de000b");
+MODULE_ALIAS("snd-hda-codec-id:10de000c");
+MODULE_ALIAS("snd-hda-codec-id:10de000d");
MODULE_ALIAS("snd-hda-codec-id:10de0067");
MODULE_ALIAS("snd-hda-codec-id:10de8001");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec");
+MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
static struct hda_codec_preset_list nvhdmi_list = {
.preset = snd_hda_preset_nvhdmi,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e8cbe216e91..7404dba16f8 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -230,6 +230,7 @@ enum {
ALC888_ACER_ASPIRE_7730G,
ALC883_MEDION,
ALC883_MEDION_MD2,
+ ALC883_MEDION_WIM2160,
ALC883_LAPTOP_EAPD,
ALC883_LENOVO_101E_2ch,
ALC883_LENOVO_NB0763,
@@ -411,6 +412,8 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
if (mux_idx >= spec->num_mux_defs)
mux_idx = 0;
+ if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
+ mux_idx = 0;
return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
}
@@ -439,6 +442,8 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
imux = &spec->input_mux[mux_idx];
+ if (!imux->num_items && mux_idx > 0)
+ imux = &spec->input_mux[0];
type = get_wcaps_type(get_wcaps(codec, nid));
if (type == AC_WID_AUD_MIX) {
@@ -1385,22 +1390,31 @@ struct alc_fixup {
static void alc_pick_fixup(struct hda_codec *codec,
const struct snd_pci_quirk *quirk,
- const struct alc_fixup *fix)
+ const struct alc_fixup *fix,
+ int pre_init)
{
const struct alc_pincfg *cfg;
quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
if (!quirk)
return;
-
fix += quirk->value;
cfg = fix->pins;
- if (cfg) {
+ if (pre_init && cfg) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
+ codec->chip_name, quirk->name);
+#endif
for (; cfg->nid; cfg++)
snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
}
- if (fix->verbs)
+ if (!pre_init && fix->verbs) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
+ codec->chip_name, quirk->name);
+#endif
add_verb(codec->spec, fix->verbs);
+ }
}
static int alc_read_coef_idx(struct hda_codec *codec,
@@ -1617,6 +1631,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
*/
static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
+/* Route to built-in subwoofer as well as speakers */
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
/* Bias voltage on for external mic port */
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
/* Front Mic: set to PIN_IN (empty by default) */
@@ -1628,10 +1647,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
/* Enable speaker output */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
/* Enable headphone output */
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
{ }
};
@@ -2528,8 +2549,6 @@ static int alc_build_controls(struct hda_codec *codec)
return err;
}
- alc_free_kctls(codec); /* no longer needed */
-
/* assign Capture Source enums to NID */
kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
if (!kctl)
@@ -2598,6 +2617,9 @@ static int alc_build_controls(struct hda_codec *codec)
}
}
}
+
+ alc_free_kctls(codec); /* no longer needed */
+
return 0;
}
@@ -4121,7 +4143,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
- SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
+ SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
@@ -4796,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
}
}
+static void alc880_auto_init_input_src(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ int c;
+
+ for (c = 0; c < spec->num_adc_nids; c++) {
+ unsigned int mux_idx;
+ const struct hda_input_mux *imux;
+ mux_idx = c >= spec->num_mux_defs ? 0 : c;
+ imux = &spec->input_mux[mux_idx];
+ if (!imux->num_items && mux_idx > 0)
+ imux = &spec->input_mux[0];
+ if (imux)
+ snd_hda_codec_write(codec, spec->adc_nids[c], 0,
+ AC_VERB_SET_CONNECT_SEL,
+ imux->items[0].index);
+ }
+}
+
/* parse the BIOS configuration and set up the alc_spec */
/* return 1 if successful, 0 if the proper config is not found,
* or a negative error code
@@ -4874,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec)
alc880_auto_init_multi_out(codec);
alc880_auto_init_extra_out(codec);
alc880_auto_init_analog_input(codec);
+ alc880_auto_init_input_src(codec);
if (spec->unsol_event)
alc_inithook(codec);
}
@@ -4915,7 +4957,7 @@ static void fixup_automic_adc(struct hda_codec *codec)
static void fixup_single_adc(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- hda_nid_t pin;
+ hda_nid_t pin = 0;
int i;
/* search for the input pin; there must be only one */
@@ -4979,6 +5021,70 @@ static void set_capture_mixer(struct hda_codec *codec)
}
}
+/* fill adc_nids (and capsrc_nids) containing all active input pins */
+static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
+ int num_nids)
+{
+ struct alc_spec *spec = codec->spec;
+ int n;
+ hda_nid_t fallback_adc = 0, fallback_cap = 0;
+
+ for (n = 0; n < num_nids; n++) {
+ hda_nid_t adc, cap;
+ hda_nid_t conn[HDA_MAX_NUM_INPUTS];
+ int nconns, i, j;
+
+ adc = nids[n];
+ if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
+ continue;
+ cap = adc;
+ nconns = snd_hda_get_connections(codec, cap, conn,
+ ARRAY_SIZE(conn));
+ if (nconns == 1) {
+ cap = conn[0];
+ nconns = snd_hda_get_connections(codec, cap, conn,
+ ARRAY_SIZE(conn));
+ }
+ if (nconns <= 0)
+ continue;
+ if (!fallback_adc) {
+ fallback_adc = adc;
+ fallback_cap = cap;
+ }
+ for (i = 0; i < AUTO_PIN_LAST; i++) {
+ hda_nid_t nid = spec->autocfg.input_pins[i];
+ if (!nid)
+ continue;
+ for (j = 0; j < nconns; j++) {
+ if (conn[j] == nid)
+ break;
+ }
+ if (j >= nconns)
+ break;
+ }
+ if (i >= AUTO_PIN_LAST) {
+ int num_adcs = spec->num_adc_nids;
+ spec->private_adc_nids[num_adcs] = adc;
+ spec->private_capsrc_nids[num_adcs] = cap;
+ spec->num_adc_nids++;
+ spec->adc_nids = spec->private_adc_nids;
+ if (adc != cap)
+ spec->capsrc_nids = spec->private_capsrc_nids;
+ }
+ }
+ if (!spec->num_adc_nids) {
+ printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
+ " using fallback 0x%x\n",
+ codec->chip_name, fallback_adc);
+ spec->private_adc_nids[0] = fallback_adc;
+ spec->adc_nids = spec->private_adc_nids;
+ if (fallback_adc != fallback_cap) {
+ spec->private_capsrc_nids[0] = fallback_cap;
+ spec->capsrc_nids = spec->private_adc_nids;
+ }
+ }
+}
+
#ifdef CONFIG_SND_HDA_INPUT_BEEP
#define set_beep_amp(spec, nid, idx, dir) \
((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -6321,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc260_auto_init_input_src alc880_auto_init_input_src
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -6407,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
alc260_auto_init_multi_out(codec);
alc260_auto_init_analog_input(codec);
+ alc260_auto_init_input_src(codec);
if (spec->unsol_event)
alc_inithook(codec);
}
@@ -6473,7 +6582,7 @@ static struct alc_config_preset alc260_presets[] = {
.num_dacs = ARRAY_SIZE(alc260_dac_nids),
.dac_nids = alc260_dac_nids,
.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
- .adc_nids = alc260_adc_nids,
+ .adc_nids = alc260_dual_adc_nids,
.num_channel_mode = ARRAY_SIZE(alc260_modes),
.channel_mode = alc260_modes,
.input_mux = &alc260_capture_source,
@@ -8379,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
+static struct hda_verb alc883_medion_wim2160_verbs[] = {
+ /* Unmute front mixer */
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+ /* Set speaker pin to front mixer */
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+ /* Init headphone pin */
+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+
+ { } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_medion_wim2160_setup(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ spec->autocfg.hp_pins[0] = 0x1a;
+ spec->autocfg.speaker_pins[0] = 0x15;
+}
+
static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -8393,9 +8538,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -9090,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
[ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
[ALC883_MEDION] = "medion",
[ALC883_MEDION_MD2] = "medion-md2",
+ [ALC883_MEDION_WIM2160] = "medion-wim2160",
[ALC883_LAPTOP_EAPD] = "laptop-eapd",
[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
[ALC883_LENOVO_NB0763] = "lenovo-nb0763",
@@ -9191,6 +9335,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
+ SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
@@ -9200,10 +9345,12 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
+ SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
+ SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
@@ -9231,7 +9378,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
- SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
+ SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
{}
};
@@ -9742,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = {
.setup = alc883_medion_md2_setup,
.init_hook = alc_automute_amp,
},
+ [ALC883_MEDION_WIM2160] = {
+ .mixers = { alc883_medion_wim2160_mixer },
+ .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
+ .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+ .dac_nids = alc883_dac_nids,
+ .dig_out_nid = ALC883_DIGOUT_NID,
+ .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+ .adc_nids = alc883_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+ .channel_mode = alc883_3ST_2ch_modes,
+ .input_mux = &alc883_capture_source,
+ .unsol_event = alc_automute_amp_unsol_event,
+ .setup = alc883_medion_wim2160_setup,
+ .init_hook = alc_automute_amp,
+ },
[ALC883_LAPTOP_EAPD] = {
.mixers = { alc883_base_mixer },
.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
@@ -10034,6 +10196,8 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
int idx;
alc_set_pin_output(codec, nid, pin_type);
+ if (dac_idx >= spec->multiout.num_dacs)
+ return;
if (spec->multiout.dac_nids[dac_idx] == 0x25)
idx = 4;
else
@@ -10105,6 +10269,8 @@ static void alc882_auto_init_input_src(struct hda_codec *codec)
continue;
mux_idx = c >= spec->num_mux_defs ? 0 : c;
imux = &spec->input_mux[mux_idx];
+ if (!imux->num_items && mux_idx > 0)
+ imux = &spec->input_mux[0];
for (idx = 0; idx < conns; idx++) {
/* if the current connection is the selected one,
* unmute it as default - otherwise mute it
@@ -10283,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec)
board_config = ALC882_AUTO;
}
- alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
+ if (board_config == ALC882_AUTO)
+ alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
if (board_config == ALC882_AUTO) {
/* automatic parse from the BIOS config */
@@ -10356,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec)
set_capture_mixer(codec);
set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
+ if (board_config == ALC882_AUTO)
+ alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
+
spec->vmaster_nid = 0x0c;
codec->patch_ops = alc_patch_ops;
@@ -12447,11 +12617,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
unsigned char bits;
present = snd_hda_jack_detect(codec, 0x15);
- bits = present ? AMP_IN_MUTE(0) : 0;
+ bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
@@ -12736,6 +12906,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
dac = 0x02;
break;
case 0x15:
+ case 0x21: /* ALC269vb has this pin, too */
dac = 0x03;
break;
default:
@@ -13201,7 +13372,7 @@ static int patch_alc268(struct hda_codec *codec)
if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
board_config = snd_hda_check_board_codec_sid_config(codec,
- ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
+ ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
@@ -13321,9 +13492,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = {
0x22,
};
-/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
- * not a mux!
- */
+static hda_nid_t alc269_adc_candidates[] = {
+ 0x08, 0x09, 0x07,
+};
#define alc269_modes alc260_modes
#define alc269_capture_source alc880_lg_lw_capture_source
@@ -13470,11 +13641,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
unsigned char bits;
present = snd_hda_jack_detect(codec, 0x15);
- bits = present ? AMP_IN_MUTE(0) : 0;
+ bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_write(codec, 0x20, 0,
AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13499,11 +13670,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
/* Check port replicator headphone socket */
present |= snd_hda_jack_detect(codec, 0x1a);
- bits = present ? AMP_IN_MUTE(0) : 0;
+ bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_write(codec, 0x20, 0,
AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13561,6 +13732,8 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec,
static void alc269_quanta_fl1_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
spec->ext_mic.pin = 0x18;
spec->ext_mic.mux_idx = 0;
spec->int_mic.pin = 0x19;
@@ -13632,11 +13805,11 @@ static void alc269_speaker_automute(struct hda_codec *codec)
unsigned char bits;
present = snd_hda_jack_detect(codec, nid);
- bits = present ? AMP_IN_MUTE(0) : 0;
+ bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
/* unsolicited event for HP jack sensing */
@@ -13653,29 +13826,35 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,
}
}
-static void alc269_laptop_dmic_setup(struct hda_codec *codec)
+static void alc269_laptop_amic_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
spec->ext_mic.pin = 0x18;
spec->ext_mic.mux_idx = 0;
- spec->int_mic.pin = 0x12;
- spec->int_mic.mux_idx = 5;
+ spec->int_mic.pin = 0x19;
+ spec->int_mic.mux_idx = 1;
spec->auto_mic = 1;
}
-static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
+static void alc269_laptop_dmic_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ spec->autocfg.hp_pins[0] = 0x15;
+ spec->autocfg.speaker_pins[0] = 0x14;
spec->ext_mic.pin = 0x18;
spec->ext_mic.mux_idx = 0;
spec->int_mic.pin = 0x12;
- spec->int_mic.mux_idx = 6;
+ spec->int_mic.mux_idx = 5;
spec->auto_mic = 1;
}
-static void alc269_laptop_amic_setup(struct hda_codec *codec)
+static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ spec->autocfg.hp_pins[0] = 0x21;
+ spec->autocfg.speaker_pins[0] = 0x14;
spec->ext_mic.pin = 0x18;
spec->ext_mic.mux_idx = 0;
spec->int_mic.pin = 0x19;
@@ -13683,6 +13862,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec)
spec->auto_mic = 1;
}
+static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ spec->autocfg.hp_pins[0] = 0x21;
+ spec->autocfg.speaker_pins[0] = 0x14;
+ spec->ext_mic.pin = 0x18;
+ spec->ext_mic.mux_idx = 0;
+ spec->int_mic.pin = 0x12;
+ spec->int_mic.mux_idx = 6;
+ spec->auto_mic = 1;
+}
+
static void alc269_laptop_inithook(struct hda_codec *codec)
{
alc269_speaker_automute(codec);
@@ -13822,7 +14013,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int err;
static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
- hda_nid_t real_capsrc_nids;
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
alc269_ignore);
@@ -13846,18 +14036,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
add_verb(spec, alc269vb_init_verbs);
- real_capsrc_nids = alc269vb_capsrc_nids[0];
alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
} else {
add_verb(spec, alc269_init_verbs);
- real_capsrc_nids = alc269_capsrc_nids[0];
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
}
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux[0];
+ fillup_priv_adc_nids(codec, alc269_adc_candidates,
+ sizeof(alc269_adc_candidates));
+
/* set default input source */
- snd_hda_codec_write_cache(codec, real_capsrc_nids,
+ snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
0, AC_VERB_SET_CONNECT_SEL,
spec->input_mux->items[0].index);
@@ -13887,6 +14078,27 @@ static void alc269_auto_init(struct hda_codec *codec)
alc_inithook(codec);
}
+enum {
+ ALC269_FIXUP_SONY_VAIO,
+};
+
+const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
+ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
+ {}
+};
+
+static const struct alc_fixup alc269_fixups[] = {
+ [ALC269_FIXUP_SONY_VAIO] = {
+ .verbs = alc269_sony_vaio_fixup_verbs
+ },
+};
+
+static struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
+ {}
+};
+
+
/*
* configuration and preset
*/
@@ -13946,7 +14158,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
ALC269_DMIC),
SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
- SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
+ SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
@@ -14020,7 +14232,7 @@ static struct alc_config_preset alc269_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc269_modes),
.channel_mode = alc269_modes,
.unsol_event = alc269_laptop_unsol_event,
- .setup = alc269_laptop_amic_setup,
+ .setup = alc269vb_laptop_amic_setup,
.init_hook = alc269_laptop_inithook,
},
[ALC269VB_DMIC] = {
@@ -14100,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec)
board_config = ALC269_AUTO;
}
+ if (board_config == ALC269_AUTO)
+ alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
+
if (board_config == ALC269_AUTO) {
/* automatic parse from the BIOS config */
err = alc269_parse_auto_config(codec);
@@ -14136,20 +14351,25 @@ static int patch_alc269(struct hda_codec *codec)
spec->stream_digital_playback = &alc269_pcm_digital_playback;
spec->stream_digital_capture = &alc269_pcm_digital_capture;
- if (!is_alc269vb) {
- spec->adc_nids = alc269_adc_nids;
- spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
- spec->capsrc_nids = alc269_capsrc_nids;
- } else {
- spec->adc_nids = alc269vb_adc_nids;
- spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
- spec->capsrc_nids = alc269vb_capsrc_nids;
+ if (!spec->adc_nids) { /* wasn't filled automatically? use default */
+ if (!is_alc269vb) {
+ spec->adc_nids = alc269_adc_nids;
+ spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
+ spec->capsrc_nids = alc269_capsrc_nids;
+ } else {
+ spec->adc_nids = alc269vb_adc_nids;
+ spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
+ spec->capsrc_nids = alc269vb_capsrc_nids;
+ }
}
if (!spec->cap_mixer)
set_capture_mixer(codec);
set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
+ if (board_config == ALC269_AUTO)
+ alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
+
spec->vmaster_nid = 0x02;
codec->patch_ops = alc_patch_ops;
@@ -15238,7 +15458,8 @@ static int patch_alc861(struct hda_codec *codec)
board_config = ALC861_AUTO;
}
- alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
+ if (board_config == ALC861_AUTO)
+ alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
if (board_config == ALC861_AUTO) {
/* automatic parse from the BIOS config */
@@ -15275,6 +15496,9 @@ static int patch_alc861(struct hda_codec *codec)
spec->vmaster_nid = 0x03;
+ if (board_config == ALC861_AUTO)
+ alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
+
codec->patch_ops = alc_patch_ops;
if (board_config == ALC861_AUTO) {
spec->init_hook = alc861_auto_init;
@@ -16209,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec)
board_config = ALC861VD_AUTO;
}
- alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
+ if (board_config == ALC861VD_AUTO)
+ alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
if (board_config == ALC861VD_AUTO) {
/* automatic parse from the BIOS config */
@@ -16257,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec)
spec->vmaster_nid = 0x02;
+ if (board_config == ALC861VD_AUTO)
+ alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
+
codec->patch_ops = alc_patch_ops;
if (board_config == ALC861VD_AUTO)
@@ -17095,9 +17323,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec)
present = snd_hda_jack_detect(codec, 0x21);
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
@@ -17108,13 +17336,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
present = snd_hda_jack_detect(codec, 0x21);
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
@@ -17125,13 +17353,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
present = snd_hda_jack_detect(codec, 0x15);
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
static void alc662_f5z_speaker_automute(struct hda_codec *codec)
@@ -17170,14 +17398,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
if (present1 || present2) {
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), AMP_IN_MUTE(0));
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), AMP_IN_MUTE(0));
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
} else {
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), 0);
+ HDA_AMP_MUTE, 0);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), 0);
+ HDA_AMP_MUTE, 0);
}
}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 8c416bb18a5..7fb7d017a34 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1607,6 +1607,10 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
"Dell Studio 1555", STAC_DELL_M6_DMIC),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
"Dell Studio 1557", STAC_DELL_M6_DMIC),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
+ "Dell Studio XPS 1645", STAC_DELL_M6_BOTH),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
+ "Dell Studio 1558", STAC_DELL_M6_BOTH),
{} /* terminator */
};
@@ -1730,6 +1734,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
"HP HDX", STAC_HP_HDX), /* HDX16 */
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
"HP dv6", STAC_HP_DV5),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
+ "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
"HP", STAC_HP_DV5),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 9ddc37300f6..73453814e09 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
knew->name = kstrdup(tmpl->name, GFP_KERNEL);
if (!knew->name)
return NULL;
- return 0;
+ return knew;
}
static void via_free_kctls(struct hda_codec *codec)
@@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = {
},
};
-static int via_hp_build(struct via_spec *spec)
+static int via_hp_build(struct hda_codec *codec)
{
+ struct via_spec *spec = codec->spec;
struct snd_kcontrol_new *knew;
hda_nid_t nid;
-
- knew = via_clone_control(spec, &via_hp_mixer[0]);
- if (knew == NULL)
- return -ENOMEM;
+ int nums;
+ hda_nid_t conn[HDA_MAX_CONNECTIONS];
switch (spec->codec_type) {
case VT1718S:
@@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec)
break;
}
+ nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
+ if (nums <= 1)
+ return 0;
+
+ knew = via_clone_control(spec, &via_hp_mixer[0]);
+ if (knew == NULL)
+ return -ENOMEM;
+
knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
knew->private_value = nid;
@@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
via_smart51_build(spec);
return 1;
@@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
via_smart51_build(spec);
return 1;
@@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
via_smart51_build(spec);
return 1;
@@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
via_smart51_build(spec);
return 1;
@@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
return 1;
}
@@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
via_smart51_build(spec);
@@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
via_smart51_build(spec);
@@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
return 1;
}
@@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
/* Line-Out: PortE */
err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
- "Master Front Playback Volume",
+ "Front Playback Volume",
HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
if (err < 0)
return err;
err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
- "Master Front Playback Switch",
+ "Front Playback Switch",
HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
if (err < 0)
return err;
@@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux[0];
if (spec->hp_mux)
- via_hp_build(spec);
+ via_hp_build(codec);
return 1;
}
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
index 03391da8c8c..90d560c3df1 100644
--- a/sound/pci/ice1712/ak4xxx.c
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -24,6 +24,7 @@
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <sound/core.h>
#include <sound/initval.h>
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index 6da21a2bcad..e328cfb7620 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -25,7 +25,6 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <sound/core.h>
#include "ice1712.h"
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index 7f9674b641c..4c551e147c0 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -25,7 +25,6 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <sound/core.h>
#include "ice1712.h"
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index 5af9e84456d..e618f789026 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -29,7 +29,6 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <sound/core.h>
#include "ice1712.h"
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 0cca56038cd..ef9af3f4ace 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/initval.h>
#include <sound/control.h>
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index b64e78139d6..b56e3367678 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -849,6 +849,7 @@ struct snd_m3 {
struct snd_kcontrol *master_switch;
struct snd_kcontrol *master_volume;
struct tasklet_struct hwvol_tq;
+ unsigned int in_suspend;
#ifdef CONFIG_PM
u16 *suspend_mem;
@@ -884,6 +885,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = {
MODULE_DEVICE_TABLE(pci, snd_m3_ids);
static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = {
+ SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c),
SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d),
SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d),
SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03),
@@ -1613,6 +1615,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER);
+ /* Ignore spurious HV interrupts during suspend / resume, this avoids
+ mistaking them for a mute button press. */
+ if (chip->in_suspend)
+ return;
+
if (!chip->master_switch || !chip->master_volume)
return;
@@ -2424,6 +2431,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
if (chip->suspend_mem == NULL)
return 0;
+ chip->in_suspend = 1;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm);
snd_ac97_suspend(chip->ac97);
@@ -2497,6 +2505,7 @@ static int m3_resume(struct pci_dev *pci)
snd_m3_hv_init(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ chip->in_suspend = 0;
return 0;
}
#endif /* CONFIG_PM */
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 7e8e7da592a..3be8f97c8bc 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -27,6 +27,7 @@
#include <linux/dma-mapping.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -1161,13 +1162,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
unsigned long count, unsigned long pos)
{
struct mixart_mgr *mgr = entry->private_data;
+ unsigned long maxsize;
- count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
- if(count <= 0)
+ if (pos >= MIXART_BA0_SIZE)
return 0;
- if(pos + count > MIXART_BA0_SIZE)
- count = (long)(MIXART_BA0_SIZE - pos);
- if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count))
+ maxsize = MIXART_BA0_SIZE - pos;
+ if (count > maxsize)
+ count = maxsize;
+ count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+ if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
return -EFAULT;
return count;
}
@@ -1180,13 +1183,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
unsigned long count, unsigned long pos)
{
struct mixart_mgr *mgr = entry->private_data;
+ unsigned long maxsize;
- count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
- if(count <= 0)
+ if (pos > MIXART_BA1_SIZE)
return 0;
- if(pos + count > MIXART_BA1_SIZE)
- count = (long)(MIXART_BA1_SIZE - pos);
- if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count))
+ maxsize = MIXART_BA1_SIZE - pos;
+ if (count > maxsize)
+ count = maxsize;
+ count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+ if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
return -EFAULT;
return count;
}
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index 4cf4cd8c939..bf2696aa5d4 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -24,6 +24,7 @@
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/vmalloc.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <sound/core.h>
#include "mixart.h"
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 9c5e6450eeb..fad03d64e3a 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/pci.h>
+#include <linux/slab.h>
#include <sound/ac97_codec.h>
#include <sound/asoundef.h>
#include <sound/core.h>
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 7754db166d9..dbc4b89d74e 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -68,7 +68,7 @@ static void wm8776_write(struct oxygen *chip,
OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
(reg << 9) | value);
if (reg < ARRAY_SIZE(data->wm8776_regs)) {
- if (reg >= WM8776_HPLVOL || reg <= WM8776_DACMASTER)
+ if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
value &= ~WM8776_UPDATE;
data->wm8776_regs[reg] = value;
}
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 960a227eb65..ad446267761 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1974,9 +1974,9 @@ snd_riptide_proc_read(struct snd_info_entry *entry,
}
snd_iprintf(buffer, "Paths:\n");
i = getpaths(cif, p);
- while (i--) {
- snd_iprintf(buffer, "%x->%x ", p[i - 1], p[i]);
- i--;
+ while (i >= 2) {
+ i -= 2;
+ snd_iprintf(buffer, "%x->%x ", p[i], p[i + 1]);
}
snd_iprintf(buffer, "\n");
}
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index d5e1c6eb7b7..3c04524de37 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -70,10 +70,10 @@
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 9d5252bc870..d19dc052c39 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -27,7 +27,6 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 52c6eb57cc3..b92adef8e81 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -24,7 +24,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/moduleparam.h>
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 3d72c1effee..547b713d720 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -2479,7 +2479,7 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
on MADICARD
- playback mixer matrix: [channelout+64] [output] [value]
- input(thru) mixer matrix: [channelin] [output] [value]
- (better do 2 kontrols for seperation ?)
+ (better do 2 kontrols for separation ?)
*/
#define HDSPM_MIXER(xname, xindex) \
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 44a3e2d8c55..c492af5b25f 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -24,7 +24,6 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 7e3e8fbc90f..9cc1b5aa014 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/time.h>
+#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index 5d2afa0b0ce..9dce0bde5c0 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -19,6 +19,7 @@
*/
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/info.h>
#include "pdaudiocf.h"
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 0d668f47162..43f995a3f96 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -20,7 +20,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/slab.h>
#include <linux/delay.h>
#include <sound/core.h>
#include <sound/asoundef.h>
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 7be3b335704..cfd1438bcc6 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include "vxpocket.h"
#include <pcmcia/ciscode.h>
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c
index 1f72e1c786b..00e2d5166d0 100644
--- a/sound/ppc/burgundy.c
+++ b/sound/ppc/burgundy.c
@@ -21,7 +21,6 @@
#include <asm/io.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <sound/core.h>
#include "pmac.h"
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index d06f780bd7e..8f064c7ce74 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <sound/core.h>
#include "pmac.h"
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 53c81a54761..2f12da4da56 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -20,10 +20,10 @@
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
-#include <linux/slab.h>
#include <sound/asound.h>
#include <sound/control.h>
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index 76d9ad27d91..68e0dee4ff0 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 9ef6b96373f..3e6628c8e66 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = params_buffer_bytes(params);
- prtd->params = rtd->dai->cpu_dai->dma_data;
+ prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
prtd->dma_buffer = runtime->dma_addr;
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index e588e63f18d..0b59806905d 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
ssc_p->dma_params[dir] = dma_params;
/*
- * The cpu_dai->dma_data field is only used to communicate the
- * appropriate DMA parameters to the pcm driver hw_params()
+ * The snd_soc_pcm_stream->dma_data field is only used to communicate
+ * the appropriate DMA parameters to the pcm driver hw_params()
* function. It should not be used for other purposes
* as it is common to all substreams.
*/
- rtd->dai->cpu_dai->dma_data = dma_params;
+ snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params);
channels = params_channels(params);
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 340311d7fed..a61ccd2d505 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/mutex.h>
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 0cf2ca61c77..495be6e7193 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/suspend.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 67cbfe7283d..5e7aacf3bb5 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -29,8 +29,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index e6932297873..523b7fc33f4 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index c6c6a4a7d94..1d2a1adf257 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -29,8 +29,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index 5e03bb2f3cd..6bac1ac1a31 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -29,8 +29,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index a1bbe16b7f9..1f5e57a4bb7 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -13,6 +13,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <sound/core.h>
@@ -80,9 +81,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
static int ac97_soc_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_card *card = socdev->card;
struct snd_soc_codec *codec;
struct snd_ac97_bus *ac97_bus;
struct snd_ac97_template ac97_template;
+ int i;
int ret = 0;
printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
@@ -102,12 +105,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
- ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
- if (ret < 0) {
- printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
- goto err;
- }
-
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0)
@@ -123,6 +120,13 @@ static int ac97_soc_probe(struct platform_device *pdev)
if (ret < 0)
goto bus_err;
+ for (i = 0; i < card->num_links; i++) {
+ if (card->dai_link[i].codec_dai->ac97_control) {
+ snd_ac97_dev_add_pdata(codec->ac97,
+ card->dai_link[i].cpu_dai->ac97_pdata);
+ }
+ }
+
return 0;
bus_err:
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 3c80137d593..11b62dee842 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -17,6 +17,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index c233810d463..240cd155b31 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -27,6 +27,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 39c0f7584e6..042072738cd 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -12,6 +12,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index d2fcc601722..475807bea2c 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index cc96411ca3e..f8e75edb27b 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -11,6 +11,7 @@
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/device.h>
#include <sound/core.h>
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index b9ef7e45891..bdeb10dfd88 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/initval.h>
@@ -90,12 +91,10 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
if (reg >= codec->reg_cache_size)
return -EINVAL;
- reg &= AK4104_REG_MASK;
- reg |= AK4104_WRITE;
-
/* only write to the hardware if value has changed */
if (cache[reg] != value) {
- u8 tmp[2] = { reg, value };
+ u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
+
if (spi_write(spi, tmp, sizeof(tmp))) {
dev_err(&spi->dev, "SPI write failed\n");
return -EIO;
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index ff966567e2b..352d1d08dbd 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -19,6 +19,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 3ef16bbc8c8..729859cf6ca 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -29,6 +29,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 82fca284d00..926797a014c 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index dfbeb2db61b..81a62d198b7 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/initval.h>
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index e000cdfec1e..9f169c47710 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -14,6 +14,7 @@
*/
#include <linux/tty.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index cf2975a7294..366daf1d044 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -23,6 +23,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 2afcd0a8669..5a5f187a265 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/initval.h>
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index d2ff1cde688..29d0906a924 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -33,6 +33,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 81b8c9dfe7f..3293629dcb3 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -15,6 +15,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/device.h>
#include <sound/core.h>
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index da589d8664d..776b79cde90 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -25,6 +25,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 357b609196e..b5b7d6a0384 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/sysfs.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index e4b946a19ea..4a6d56c3fed 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -39,6 +39,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index f9f367d29a9..d1e0e81ef30 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -778,7 +779,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
if (dac33->fifo_mode) {
/* Generic for all FIFO modes */
/* 50-51 : ASRC Control registers */
- dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
+ dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
/* Write registers 0x34 and 0x35 (MSB, LSB) */
@@ -1038,11 +1039,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
case SND_SOC_DAIFMT_DSP_A:
aictrl_a |= DAC33_AFMT_DSP;
aictrl_b &= ~DAC33_DATA_DELAY_MASK;
- aictrl_b |= DAC33_DATA_DELAY(1); /* 1 bit delay */
- break;
- case SND_SOC_DAIFMT_DSP_B:
- aictrl_a |= DAC33_AFMT_DSP;
- aictrl_b &= ~DAC33_DATA_DELAY_MASK; /* No delay */
+ aictrl_b |= DAC33_DATA_DELAY(0);
break;
case SND_SOC_DAIFMT_RIGHT_J:
aictrl_a |= DAC33_AFMT_RIGHT_J;
@@ -1066,7 +1063,7 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
{
/* 44-46: DAC Control Registers */
/* A : DAC sample rate Fsref/1.5 */
- dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(1));
+ dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
/* B : DAC src=normal, not muted */
dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
DAC33_DACSRCL_LEFT);
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 958d49c969a..569ad8758a8 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <sound/tpa6130a2-plat.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 6f5d4af2005..520ffd6536c 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -27,6 +27,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/i2c/twl.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 3e99fe5131d..a8dcd5a5bbc 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index a2763c2e734..9cd0a66b766 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -137,7 +137,7 @@ static void uda1380_flush_work(struct work_struct *work)
{
int bit, reg;
- for_each_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
+ for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
reg = 0x10 + bit;
pr_debug("uda1380: flush reg %x val %x:\n", reg,
uda1380_read_reg_cache(uda1380_codec, reg));
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 217b0268059..002e289d125 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/firmware.h>
@@ -32,6 +31,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 718ef912e75..2e0772f9c45 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
@@ -1349,7 +1350,7 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
int mask;
struct wm8350_jack_data *jack = NULL;
- switch (irq) {
+ switch (irq - wm8350->irq_base) {
case WM8350_IRQ_CODEC_JCK_DET_L:
jack = &priv->hpl;
mask = WM8350_JACK_L_LVL;
@@ -1424,7 +1425,7 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
/* Sync status */
- wm8350_hp_jack_handler(irq, priv);
+ wm8350_hp_jack_handler(irq + wm8350->irq_base, priv);
return 0;
}
@@ -1521,8 +1522,8 @@ static int wm8350_remove(struct platform_device *pdev)
WM8350_JDL_ENA | WM8350_JDR_ENA);
wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
- wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
priv->hpl.jack = NULL;
priv->hpr.jack = NULL;
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index b432f4d4a32..6acc885cf9b 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index af8cb6995a1..9000b1d19af 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index d3a61d7ea0c..19cd4729342 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index d077df6f5e7..8cc9042965e 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -25,6 +25,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 24a35603bcf..8ca3812f2f2 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index 63a254e293c..1072621e93f 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -13,6 +13,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 3fb653ba363..07adc375a70 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -18,6 +18,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 5a2619dbf28..e7c6bf16318 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 475c67ac781..2916ed4d384 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index c2444e7c848..613199a0f79 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -40,6 +40,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 44e7d9d82f8..60b1b3e1094 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index dbc368c0826..b7fd96adac6 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -24,6 +24,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 3595bd57c4e..fa5f99fde68 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -23,6 +23,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 593e47d0e0e..c6f0abcc571 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 31e39ffd1d8..0c04b476487 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -30,6 +30,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 615dab2b62e..c8d7a809af4 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -18,6 +18,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index d07bcc1e1c6..f1e63e01b04 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -15,6 +15,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index d2342c5e042..50634ab76a5 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -18,6 +18,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index d9540d55fc8..a65b781af51 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -20,6 +20,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index ee637af4737..69708c4cc00 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -18,6 +18,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 28bb59ea6ea..526f56b0906 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -19,6 +19,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 2862e4dced2..bb18c3ecfeb 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index a54dc77b7f3..831f4730bfd 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -18,6 +18,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -990,7 +991,7 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
reg = snd_soc_read(codec, WM8990_CLOCKING_2);
snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC);
- /* set up N , fractional mode and pre-divisor if neccessary */
+ /* set up N , fractional mode and pre-divisor if necessary */
snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
(pll_div.div2?WM8990_PRESCALE:0));
snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index bf022f68b84..03e8b1a6a56 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -18,6 +18,7 @@
#include <linux/i2c.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 29f3771c33a..9da0724cd47 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -3007,34 +3008,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_OFF:
- /* Switch over to startup biases */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- WM8994_VMID_RAMP_MASK,
- WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- (1 << WM8994_VMID_RAMP_SHIFT));
-
- /* Disable main biases */
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
- WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
+ if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+ /* Switch over to startup biases */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM8994_BIAS_SRC |
+ WM8994_STARTUP_BIAS_ENA |
+ WM8994_VMID_BUF_ENA |
+ WM8994_VMID_RAMP_MASK,
+ WM8994_BIAS_SRC |
+ WM8994_STARTUP_BIAS_ENA |
+ WM8994_VMID_BUF_ENA |
+ (1 << WM8994_VMID_RAMP_SHIFT));
- /* Discharge line */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH);
+ /* Disable main biases */
+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_BIAS_ENA |
+ WM8994_VMID_SEL_MASK, 0);
- msleep(5);
+ /* Discharge line */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+ WM8994_LINEOUT1_DISCH |
+ WM8994_LINEOUT2_DISCH,
+ WM8994_LINEOUT1_DISCH |
+ WM8994_LINEOUT2_DISCH);
- /* Switch off startup biases */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- WM8994_VMID_RAMP_MASK, 0);
+ msleep(5);
+ /* Switch off startup biases */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM8994_BIAS_SRC |
+ WM8994_STARTUP_BIAS_ENA |
+ WM8994_VMID_BUF_ENA |
+ WM8994_VMID_RAMP_MASK, 0);
+ }
break;
}
codec->bias_level = level;
@@ -3401,7 +3407,7 @@ struct snd_soc_dai wm8994_dai[] = {
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
- .playback = {
+ .capture = {
.stream_name = "AIF3 Capture",
.channels_min = 2,
.channels_max = 2,
@@ -3730,11 +3736,12 @@ static int wm8994_codec_probe(struct platform_device *pdev)
case 3:
wm8994->hubs.dcs_codes = -5;
wm8994->hubs.hp_startup_mode = 1;
+ wm8994->hubs.dcs_readback_mode = 1;
break;
default:
+ wm8994->hubs.dcs_readback_mode = 1;
break;
}
-
/* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index c468497314b..3a184fcb702 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -18,6 +18,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index ec54c6da985..8793341849d 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -10,6 +10,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index e237bf61512..2f48a8aae22 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index ceb86b4ddb2..2fca514fde5 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -16,6 +16,7 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/device.h>
#include <sound/core.h>
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 0ad9f5d536c..e1f225a3ac4 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -62,21 +62,27 @@ static const char *speaker_mode_text[] = {
static const struct soc_enum speaker_mode =
SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
-static void wait_for_dc_servo(struct snd_soc_codec *codec)
+static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
{
unsigned int reg;
int count = 0;
+ unsigned int val;
+
+ val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
+
+ /* Trigger the command */
+ snd_soc_write(codec, WM8993_DC_SERVO_0, val);
dev_dbg(codec->dev, "Waiting for DC servo...\n");
do {
count++;
msleep(1);
- reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
+ reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
dev_dbg(codec->dev, "DC servo: %x\n", reg);
- } while (reg & WM8993_DCS_DATAPATH_BUSY);
+ } while (reg & op && count < 400);
- if (reg & WM8993_DCS_DATAPATH_BUSY)
+ if (reg & op)
dev_err(codec->dev, "Timed out waiting for DC Servo\n");
}
@@ -86,51 +92,58 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
static void calibrate_dc_servo(struct snd_soc_codec *codec)
{
struct wm_hubs_data *hubs = codec->private_data;
- u16 reg, dcs_cfg;
+ u16 reg, reg_l, reg_r, dcs_cfg;
/* Set for 32 series updates */
snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
WM8993_DCS_SERIES_NO_01_MASK,
32 << WM8993_DCS_SERIES_NO_01_SHIFT);
-
- /* Enable the DC servo. Write all bits to avoid triggering startup
- * or write calibration.
- */
- snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
- 0xFFFF,
- WM8993_DCS_ENA_CHAN_0 |
- WM8993_DCS_ENA_CHAN_1 |
- WM8993_DCS_TRIG_SERIES_1 |
- WM8993_DCS_TRIG_SERIES_0);
-
- wait_for_dc_servo(codec);
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
/* Apply correction to DC servo result */
if (hubs->dcs_codes) {
dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
hubs->dcs_codes);
+ /* Different chips in the family support different
+ * readback methods.
+ */
+ switch (hubs->dcs_readback_mode) {
+ case 0:
+ reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+ & WM8993_DCS_INTEG_CHAN_0_MASK;;
+ reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+ & WM8993_DCS_INTEG_CHAN_1_MASK;
+ break;
+ case 1:
+ reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
+ reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
+ >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
+ break;
+ default:
+ WARN(1, "Unknown DCS readback method");
+ break;
+ }
+
/* HPOUT1L */
- reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) &
- WM8993_DCS_INTEG_CHAN_0_MASK;;
- reg += hubs->dcs_codes;
- dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ if (reg_l + hubs->dcs_codes > 0 &&
+ reg_l + hubs->dcs_codes < 0xff)
+ reg_l += hubs->dcs_codes;
+ dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
/* HPOUT1R */
- reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) &
- WM8993_DCS_INTEG_CHAN_1_MASK;
- reg += hubs->dcs_codes;
- dcs_cfg |= reg;
+ if (reg_r + hubs->dcs_codes > 0 &&
+ reg_r + hubs->dcs_codes < 0xff)
+ reg_r += hubs->dcs_codes;
+ dcs_cfg |= reg_r;
/* Do it */
snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
- snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
- WM8993_DCS_TRIG_DAC_WR_0 |
- WM8993_DCS_TRIG_DAC_WR_1,
- WM8993_DCS_TRIG_DAC_WR_0 |
- WM8993_DCS_TRIG_DAC_WR_1);
-
- wait_for_dc_servo(codec);
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_DAC_WR_0 |
+ WM8993_DCS_TRIG_DAC_WR_1);
}
}
@@ -141,10 +154,16 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm_hubs_data *hubs = codec->private_data;
int ret;
ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
+ /* If we're applying an offset correction then updating the
+ * callibration would be likely to introduce further offsets. */
+ if (hubs->dcs_codes)
+ return ret;
+
/* Only need to do this if the outputs are active */
if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
& (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 420104fe9c9..e51c1668358 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
/* This *must* be the first element of the codec->private_data struct */
struct wm_hubs_data {
int dcs_codes;
+ int dcs_readback_mode;
int hp_startup_mode;
};
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 6362ca05506..adadcd3aa1b 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/clk.h>
@@ -585,7 +586,8 @@ static int davinci_i2s_probe(struct platform_device *pdev)
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
davinci_i2s_dai.private_data = dev;
- davinci_i2s_dai.dma_data = dev->dma_params;
+ davinci_i2s_dai.capture.dma_data = dev->dma_params;
+ davinci_i2s_dai.playback.dma_data = dev->dma_params;
ret = snd_soc_register_dai(&davinci_i2s_dai);
if (ret != 0)
goto err_free_mem;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index ab6518d86f1..79f0f4ad242 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/clk.h>
@@ -917,7 +918,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dma_data->channel = res->start;
davinci_mcasp_dai[pdata->op_mode].private_data = dev;
- davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params;
+ davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params;
+ davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params;
davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 80c7fdf2f52..2dc406f42fe 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -649,8 +649,10 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_hardware *ppcm;
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->dma_data;
+ struct davinci_pcm_dma_params *pa;
struct davinci_pcm_dma_params *params;
+
+ pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
if (!pa)
return -ENODEV;
params = &pa[substream->stream];
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index b1a3a278819..410c7496a18 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -19,6 +19,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/gfp.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 93f0f38a32c..762c1b8e8e4 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/delay.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 30ed568afb2..d639e55c512 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/of_device.h>
+#include <linux/slab.h>
#include <sound/soc.h>
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index ef67d1cdffe..83de1c81c8c 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -9,6 +9,7 @@
* express or implied.
*/
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c
index 8bc5cd9e972..3bc13fd8909 100644
--- a/sound/soc/fsl/soc-of-simple.c
+++ b/sound/soc/fsl/soc-of-simple.c
@@ -12,6 +12,7 @@
#include <linux/bitops.h>
#include <linux/platform_device.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index c7d0fd9b7de..7174b4c710d 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -1,6 +1,6 @@
config SND_IMX_SOC
tristate "SoC Audio for Freescale i.MX CPUs"
- depends on ARCH_MXC && BROKEN
+ depends on ARCH_MXC
select SND_PCM
select FIQ
select SND_SOC_AC97_BUS
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 19452e44afd..2b31ac673ea 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -70,7 +71,12 @@ static void imx_ssi_dma_callback(int channel, void *data)
static void snd_imx_dma_err_callback(int channel, void *data, int err)
{
- pr_err("DMA error callback called\n");
+ struct snd_pcm_substream *substream = data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+ int ret;
pr_err("DMA timeout on channel %d -%s%s%s%s\n",
channel,
@@ -78,16 +84,26 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)
err & IMX_DMA_ERR_REQUEST ? " request" : "",
err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
err & IMX_DMA_ERR_BUFFER ? " buffer" : "");
+
+ imx_dma_disable(iprtd->dma);
+ ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
+ IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ DMA_MODE_WRITE : DMA_MODE_READ);
+ if (!ret)
+ imx_dma_enable(iprtd->dma);
}
static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+ struct imx_pcm_dma_params *dma_params;
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int ret;
+ dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
+
iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
if (iprtd->dma < 0) {
pr_err("Failed to claim the audio DMA\n");
@@ -192,10 +208,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+ struct imx_pcm_dma_params *dma_params;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int err;
+ dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
+
iprtd->substream = substream;
iprtd->buf = (unsigned int *)substream->dma_buffer.area;
iprtd->period_cnt = 0;
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index d9cb9849b03..6b518e07eea 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -38,23 +39,24 @@ struct imx_pcm_runtime_data {
unsigned long offset;
unsigned long last_offset;
unsigned long size;
- struct timer_list timer;
- int poll_time;
+ struct hrtimer hrt;
+ int poll_time_ns;
+ struct snd_pcm_substream *substream;
+ atomic_t running;
};
-static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd)
+static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
{
- iprtd->timer.expires = jiffies + iprtd->poll_time;
-}
-
-static void imx_ssi_timer_callback(unsigned long data)
-{
- struct snd_pcm_substream *substream = (void *)data;
+ struct imx_pcm_runtime_data *iprtd =
+ container_of(hrt, struct imx_pcm_runtime_data, hrt);
+ struct snd_pcm_substream *substream = iprtd->substream;
struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_pcm_runtime_data *iprtd = runtime->private_data;
struct pt_regs regs;
unsigned long delta;
+ if (!atomic_read(&iprtd->running))
+ return HRTIMER_NORESTART;
+
get_fiq_regs(&regs);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -71,16 +73,14 @@ static void imx_ssi_timer_callback(unsigned long data)
/* If we've transferred at least a period then report it and
* reset our poll time */
- if (delta >= runtime->period_size) {
+ if (delta >= iprtd->period) {
snd_pcm_period_elapsed(substream);
iprtd->last_offset = iprtd->offset;
-
- imx_ssi_set_next_poll(iprtd);
}
- /* Restart the timer; if we didn't report we'll run on the next tick */
- add_timer(&iprtd->timer);
+ hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns));
+ return HRTIMER_RESTART;
}
static struct fiq_handler fh = {
@@ -98,8 +98,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
iprtd->period = params_period_bytes(params) ;
iprtd->offset = 0;
iprtd->last_offset = 0;
- iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params));
-
+ iprtd->poll_time_ns = 1000000000 / params_rate(params) *
+ params_period_size(params);
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
return 0;
@@ -134,8 +134,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- imx_ssi_set_next_poll(iprtd);
- add_timer(&iprtd->timer);
+ atomic_set(&iprtd->running, 1);
+ hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns),
+ HRTIMER_MODE_REL);
if (++fiq_enable == 1)
enable_fiq(imx_pcm_fiq);
@@ -144,11 +145,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- del_timer(&iprtd->timer);
+ atomic_set(&iprtd->running, 0);
+
if (--fiq_enable == 0)
disable_fiq(imx_pcm_fiq);
-
break;
default:
return -EINVAL;
@@ -179,7 +180,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
.buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
.period_bytes_min = 128,
.period_bytes_max = 16 * 1024,
- .periods_min = 2,
+ .periods_min = 4,
.periods_max = 255,
.fifo_size = 0,
};
@@ -193,9 +194,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
runtime->private_data = iprtd;
- init_timer(&iprtd->timer);
- iprtd->timer.data = (unsigned long)substream;
- iprtd->timer.function = imx_ssi_timer_callback;
+ iprtd->substream = substream;
+
+ atomic_set(&iprtd->running, 0);
+ hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ iprtd->hrt.function = snd_hrtimer_callback;
ret = snd_pcm_hw_constraint_integer(substream->runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
@@ -211,7 +214,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
- del_timer_sync(&iprtd->timer);
+ hrtimer_cancel(&iprtd->hrt);
+
kfree(iprtd);
return 0;
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 56f46a75d29..80b4fee2442 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -39,6 +39,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -234,17 +235,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct imx_ssi *ssi = cpu_dai->private_data;
+ struct imx_pcm_dma_params *dma_data;
u32 reg, sccr;
/* Tx/Rx config */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
reg = SSI_STCCR;
- cpu_dai->dma_data = &ssi->dma_params_tx;
+ dma_data = &ssi->dma_params_tx;
} else {
reg = SSI_SRCCR;
- cpu_dai->dma_data = &ssi->dma_params_rx;
+ dma_data = &ssi->dma_params_rx;
}
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
+
sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
/* DAI data (word) size */
@@ -652,7 +656,8 @@ static int imx_ssi_probe(struct platform_device *pdev)
dai->private_data = ssi;
if ((cpu_is_mx27() || cpu_is_mx21()) &&
- !(ssi->flags & IMX_SSI_USE_AC97)) {
+ !(ssi->flags & IMX_SSI_USE_AC97) &&
+ (ssi->flags & IMX_SSI_DMA)) {
ssi->flags |= IMX_SSI_DMA;
platform = imx_ssi_dma_mx2_init(pdev, ssi);
} else
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
index ad8df6cfae8..1dab4c14874 100644
--- a/sound/soc/omap/mcpdm.c
+++ b/sound/soc/omap/mcpdm.c
@@ -25,6 +25,7 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/wait.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/clk.h>
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index e814a9591f7..8ad9dc90100 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -297,7 +297,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
OMAP_DMA_DATA_TYPE_S16;
- cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream,
+ &omap_mcbsp_dai_dma_params[id][substream->stream]);
if (mcbsp_data->configured) {
/* McBSP already configured by another stream */
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 25f19e4728b..b7f4f7e015f 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -150,7 +150,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
int stream = substream->stream;
int channels, err, link_mask = 0;
- cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream];
+ snd_soc_dai_set_dma_data(cpu_dai, substream,
+ &omap_mcpdm_dai_dma_params[stream]);
channels = params_channels(params);
switch (channels) {
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 825db385f01..1e521904ea6 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -23,6 +23,7 @@
*/
#include <linux/dma-mapping.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -60,12 +61,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
struct omap_runtime_data *prtd = runtime->private_data;
unsigned long flags;
- if ((cpu_is_omap1510()) &&
- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
+ if ((cpu_is_omap1510())) {
/*
* OMAP1510 doesn't fully support DMA progress counter
* and there is no software emulation implemented yet,
- * so have to maintain our own playback progress counter
+ * so have to maintain our own progress counters
* that can be used by omap_pcm_pointer() instead.
*/
spin_lock_irqsave(&prtd->lock, flags);
@@ -100,9 +100,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct omap_runtime_data *prtd = runtime->private_data;
- struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data;
+ struct omap_pcm_dma_data *dma_data;
int err = 0;
+ dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+
/* return if this is a bufferless transfer e.g.
* codec <--> BT codec or GSM modem -- lg FIXME */
if (!dma_data)
@@ -189,8 +191,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
dma_params.frame_count = runtime->periods;
omap_set_dma_params(prtd->dma_ch, &dma_params);
- if ((cpu_is_omap1510()) &&
- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
+ if ((cpu_is_omap1510()))
omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
else
@@ -248,14 +249,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
dma_addr_t ptr;
snd_pcm_uframes_t offset;
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (cpu_is_omap1510()) {
+ offset = prtd->period_index * runtime->period_size;
+ } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
ptr = omap_get_dma_dst_pos(prtd->dma_ch);
offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- } else if (!(cpu_is_omap1510())) {
+ } else {
ptr = omap_get_dma_src_pos(prtd->dma_ch);
offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- } else
- offset = prtd->period_index * runtime->period_size;
+ }
if (offset >= runtime->buffer_size)
offset = 0;
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index e69397f40f7..544fd9566f4 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
@@ -42,11 +43,14 @@
* SSP audio private data
*/
struct ssp_priv {
- struct ssp_dev dev;
+ struct ssp_device *ssp;
unsigned int sysclk;
int dai_fmt;
#ifdef CONFIG_PM
- struct ssp_state state;
+ uint32_t cr0;
+ uint32_t cr1;
+ uint32_t to;
+ uint32_t psp;
#endif
};
@@ -61,6 +65,22 @@ static void dump_registers(struct ssp_device *ssp)
ssp_read_reg(ssp, SSACD));
}
+static void ssp_enable(struct ssp_device *ssp)
+{
+ uint32_t sscr0;
+
+ sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE;
+ __raw_writel(sscr0, ssp->mmio_base + SSCR0);
+}
+
+static void ssp_disable(struct ssp_device *ssp)
+{
+ uint32_t sscr0;
+
+ sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE;
+ __raw_writel(sscr0, ssp->mmio_base + SSCR0);
+}
+
struct pxa2xx_pcm_dma_data {
struct pxa2xx_pcm_dma_params params;
char name[20];
@@ -94,19 +114,17 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
int ret = 0;
if (!cpu_dai->active) {
- priv->dev.port = cpu_dai->id + 1;
- priv->dev.irq = NO_IRQ;
- clk_enable(priv->dev.ssp->clk);
- ssp_disable(&priv->dev);
+ clk_enable(ssp->clk);
+ ssp_disable(ssp);
}
- if (cpu_dai->dma_data) {
- kfree(cpu_dai->dma_data);
- cpu_dai->dma_data = NULL;
- }
+ kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+ snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
+
return ret;
}
@@ -116,16 +134,15 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
if (!cpu_dai->active) {
- ssp_disable(&priv->dev);
- clk_disable(priv->dev.ssp->clk);
+ ssp_disable(ssp);
+ clk_disable(ssp->clk);
}
- if (cpu_dai->dma_data) {
- kfree(cpu_dai->dma_data);
- cpu_dai->dma_data = NULL;
- }
+ kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+ snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
}
#ifdef CONFIG_PM
@@ -133,27 +150,39 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
{
struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
if (!cpu_dai->active)
- clk_enable(priv->dev.ssp->clk);
+ clk_enable(ssp->clk);
- ssp_save_state(&priv->dev, &priv->state);
- clk_disable(priv->dev.ssp->clk);
+ priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
+ priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
+ priv->to = __raw_readl(ssp->mmio_base + SSTO);
+ priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
+ ssp_disable(ssp);
+ clk_disable(ssp->clk);
return 0;
}
static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
{
struct ssp_priv *priv = cpu_dai->private_data;
+ struct ssp_device *ssp = priv->ssp;
+ uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
- clk_enable(priv->dev.ssp->clk);
- ssp_restore_state(&priv->dev, &priv->state);
+ clk_enable(ssp->clk);
+
+ __raw_writel(sssr, ssp->mmio_base + SSSR);
+ __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
+ __raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
+ __raw_writel(priv->to, ssp->mmio_base + SSTO);
+ __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
if (cpu_dai->active)
- ssp_enable(&priv->dev);
+ ssp_enable(ssp);
else
- clk_disable(priv->dev.ssp->clk);
+ clk_disable(ssp->clk);
return 0;
}
@@ -203,7 +232,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
int clk_id, unsigned int freq, int dir)
{
struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->dev.ssp;
+ struct ssp_device *ssp = priv->ssp;
int val;
u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
@@ -244,11 +273,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
/* The SSP clock must be disabled when changing SSP clock mode
* on PXA2xx. On PXA3xx it must be enabled when doing so. */
if (!cpu_is_pxa3xx())
- clk_disable(priv->dev.ssp->clk);
+ clk_disable(ssp->clk);
val = ssp_read_reg(ssp, SSCR0) | sscr0;
ssp_write_reg(ssp, SSCR0, val);
if (!cpu_is_pxa3xx())
- clk_enable(priv->dev.ssp->clk);
+ clk_enable(ssp->clk);
return 0;
}
@@ -260,7 +289,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
int div_id, int div)
{
struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->dev.ssp;
+ struct ssp_device *ssp = priv->ssp;
int val;
switch (div_id) {
@@ -311,7 +340,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
int source, unsigned int freq_in, unsigned int freq_out)
{
struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->dev.ssp;
+ struct ssp_device *ssp = priv->ssp;
u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
#if defined(CONFIG_PXA3xx)
@@ -380,7 +409,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
{
struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->dev.ssp;
+ struct ssp_device *ssp = priv->ssp;
u32 sscr0;
sscr0 = ssp_read_reg(ssp, SSCR0);
@@ -415,7 +444,7 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
int tristate)
{
struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->dev.ssp;
+ struct ssp_device *ssp = priv->ssp;
u32 sscr1;
sscr1 = ssp_read_reg(ssp, SSCR1);
@@ -437,7 +466,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
{
struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->dev.ssp;
+ struct ssp_device *ssp = priv->ssp;
u32 sscr0;
u32 sscr1;
u32 sspsp;
@@ -532,25 +561,29 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->dev.ssp;
+ struct ssp_device *ssp = priv->ssp;
int chn = params_channels(params);
u32 sscr0;
u32 sspsp;
int width = snd_pcm_format_physical_width(params_format(params));
int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+ struct pxa2xx_pcm_dma_params *dma_data;
+
+ dma_data = snd_soc_dai_get_dma_data(dai, substream);
/* generate correct DMA params */
- if (cpu_dai->dma_data)
- kfree(cpu_dai->dma_data);
+ kfree(dma_data);
/* Network mode with one active slot (ttsa == 1) can be used
* to force 16-bit frame width on the wire (for S16_LE), even
* with two channels. Use 16-bit DMA transfers for this case.
*/
- cpu_dai->dma_data = ssp_get_dma_params(ssp,
+ dma_data = ssp_get_dma_params(ssp,
((chn == 2) && (ttsa != 1)) || (width == 32),
substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+ snd_soc_dai_set_dma_data(dai, substream, dma_data);
+
/* we can only change the settings if the port is not in use */
if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
return 0;
@@ -642,12 +675,12 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
int ret = 0;
struct ssp_priv *priv = cpu_dai->private_data;
- struct ssp_device *ssp = priv->dev.ssp;
+ struct ssp_device *ssp = priv->ssp;
int val;
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
- ssp_enable(&priv->dev);
+ ssp_enable(ssp);
break;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
val = ssp_read_reg(ssp, SSCR1);
@@ -666,7 +699,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
else
val |= SSCR1_RSRE;
ssp_write_reg(ssp, SSCR1, val);
- ssp_enable(&priv->dev);
+ ssp_enable(ssp);
break;
case SNDRV_PCM_TRIGGER_STOP:
val = ssp_read_reg(ssp, SSCR1);
@@ -677,7 +710,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
ssp_write_reg(ssp, SSCR1, val);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
- ssp_disable(&priv->dev);
+ ssp_disable(ssp);
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
val = ssp_read_reg(ssp, SSCR1);
@@ -707,8 +740,8 @@ static int pxa_ssp_probe(struct platform_device *pdev,
if (!priv)
return -ENOMEM;
- priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio");
- if (priv->dev.ssp == NULL) {
+ priv->ssp = ssp_request(dai->id + 1, "SoC audio");
+ if (priv->ssp == NULL) {
ret = -ENODEV;
goto err_priv;
}
@@ -727,7 +760,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
struct snd_soc_dai *dai)
{
struct ssp_priv *priv = dai->private_data;
- ssp_free(priv->dev.ssp);
+ ssp_free(priv->ssp);
}
#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index e9ae7b3a7e0..d314115e3dd 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct pxa2xx_pcm_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out;
+ dma_data = &pxa2xx_ac97_pcm_stereo_out;
else
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in;
+ dma_data = &pxa2xx_ac97_pcm_stereo_in;
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0;
}
@@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct pxa2xx_pcm_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
+ dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
else
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
+ dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0;
}
@@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return -ENODEV;
else
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in;
+ snd_soc_dai_set_dma_data(cpu_dai, substream,
+ &pxa2xx_ac97_pcm_mic_mono_in);
return 0;
}
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 6b8f655d1ad..c1a5275721e 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct pxa2xx_pcm_dma_params *dma_data;
BUG_ON(IS_ERR(clk_i2s));
clk_enable(clk_i2s);
@@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
pxa_i2s_wait();
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out;
+ dma_data = &pxa2xx_i2s_pcm_stereo_out;
else
- cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in;
+ dma_data = &pxa2xx_i2s_pcm_stereo_in;
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
/* is port used by another stream */
if (!(SACR0 & SACR0_ENB)) {
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index d38e39575f5..adc7e6f15f9 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
struct pxa2xx_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
+ struct pxa2xx_pcm_dma_params *dma;
int ret;
+ dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+
/* return if this is a bufferless transfer e.g.
* codec <--> BT codec or GSM modem -- lg FIXME */
if (!dma)
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c
index ee8ed9d7e70..ecf4fd04ae9 100644
--- a/sound/soc/s3c24xx/s3c-ac97.c
+++ b/sound/soc/s3c24xx/s3c-ac97.c
@@ -224,11 +224,14 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct s3c_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cpu_dai->dma_data = &s3c_ac97_pcm_out;
+ dma_data = &s3c_ac97_pcm_out;
else
- cpu_dai->dma_data = &s3c_ac97_pcm_in;
+ dma_data = &s3c_ac97_pcm_in;
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0;
}
@@ -238,8 +241,8 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
{
u32 ac_glbctrl;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int channel = ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->channel;
+ struct s3c_dma_params *dma_data =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -265,7 +268,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+ s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
return 0;
}
@@ -280,7 +283,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return -ENODEV;
else
- cpu_dai->dma_data = &s3c_ac97_mic_in;
+ snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in);
return 0;
}
@@ -290,8 +293,8 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
{
u32 ac_glbctrl;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int channel = ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->channel;
+ struct s3c_dma_params *dma_data =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
@@ -311,7 +314,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+ s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
return 0;
}
diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c
index 7725e26d6c9..1b61c23ff30 100644
--- a/sound/soc/s3c24xx/s3c-dma.c
+++ b/sound/soc/s3c24xx/s3c-dma.c
@@ -145,10 +145,12 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
struct s3c24xx_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data;
unsigned long totbytes = params_buffer_bytes(params);
+ struct s3c_dma_params *dma =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
int ret = 0;
+
pr_debug("Entered %s\n", __func__);
/* return if this is a bufferless transfer e.g.
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index e994d8374fe..88515946b6c 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -339,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai_link *dai = rtd->dai;
struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
+ struct s3c_dma_params *dma_data;
u32 iismod;
pr_debug("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dai->cpu_dai->dma_data = i2s->dma_playback;
+ dma_data = i2s->dma_playback;
else
- dai->cpu_dai->dma_data = i2s->dma_capture;
+ dma_data = i2s->dma_capture;
+
+ snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
/* Working copies of register */
iismod = readl(i2s->regs + S3C2412_IISMOD);
@@ -394,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
unsigned long irqs;
int ret = 0;
- int channel = ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->channel;
+ struct s3c_dma_params *dma_data =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
pr_debug("Entered %s\n", __func__);
@@ -431,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
* of the auto reload mechanism of S3C24XX.
* This call won't bother S3C64XX.
*/
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+ s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break;
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c
index a98f40c3cd2..326f0a9e7e3 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/s3c24xx/s3c-pcm.c
@@ -178,6 +178,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai_link *dai = rtd->dai;
struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
+ struct s3c_dma_params *dma_data;
void __iomem *regs = pcm->regs;
struct clk *clk;
int sclk_div, sync_div;
@@ -187,9 +188,11 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
dev_dbg(pcm->dev, "Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dai->cpu_dai->dma_data = pcm->dma_playback;
+ dma_data = pcm->dma_playback;
else
- dai->cpu_dai->dma_data = pcm->dma_capture;
+ dma_data = pcm->dma_capture;
+
+ snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
/* Strictly check for sample size */
switch (params_format(params)) {
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 0bc5950b9f0..c3ac890a398 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct s3c_dma_params *dma_data;
u32 iismod;
pr_debug("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
+ dma_data = &s3c24xx_i2s_pcm_stereo_out;
else
- rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in;
+ dma_data = &s3c24xx_i2s_pcm_stereo_in;
+
+ snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data);
/* Working copies of register */
iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
iismod &= ~S3C2410_IISMOD_16BIT;
- ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->dma_size = 1;
+ dma_data->dma_size = 1;
break;
case SNDRV_PCM_FORMAT_S16_LE:
iismod |= S3C2410_IISMOD_16BIT;
- ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->dma_size = 2;
+ dma_data->dma_size = 2;
break;
default:
return -EINVAL;
@@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
{
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int channel = ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->channel;
+ struct s3c_dma_params *dma_data =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
pr_debug("Entered %s\n", __func__);
@@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
else
s3c24xx_snd_txctrl(1);
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+ s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 93ed3aad163..a72c251401a 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -22,8 +22,8 @@
#include <sound/soc.h>
#include <plat/regs-s3c2412-iis.h>
-#include <plat/gpio-bank-d.h>
-#include <plat/gpio-bank-e.h>
+#include <mach/gpio-bank-d.h>
+#include <mach/gpio-bank-e.h>
#include <plat/gpio-cfg.h>
#include <mach/map.h>
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index c5cda187eca..5b9ac1759bd 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -16,6 +16,7 @@
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -518,7 +519,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
s6000_i2s_dai.dev = &pdev->dev;
s6000_i2s_dai.private_data = dev;
- s6000_i2s_dai.dma_data = &dev->dma_params;
+ s6000_i2s_dai.capture.dma_data = &dev->dma_params;
+ s6000_i2s_dai.playback.dma_data = &dev->dma_params;
dev->sifbase = sifmem->start;
dev->scbbase = mmio;
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 1d61109e09f..9c7f7f00ceb 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
int channel;
unsigned int period_size;
unsigned int dma_offset;
dma_addr_t dma_pos;
dma_addr_t src, dst;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
period_size = snd_pcm_lib_period_bytes(substream);
dma_offset = prtd->period * period_size;
dma_pos = runtime->dma_addr + dma_offset;
@@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
{
struct snd_pcm *pcm = data;
struct snd_soc_pcm_runtime *runtime = pcm->private_data;
- struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *params =
+ snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
struct s6000_runtime_data *prtd;
unsigned int has_xrun;
int i, ret = IRQ_NONE;
@@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
{
struct s6000_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
unsigned long flags;
int srcinc;
u32 dma;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
spin_lock_irqsave(&prtd->lock, flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
{
struct s6000_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
unsigned long flags;
u32 channel;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
channel = par->dma_out;
else
@@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
int ret;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
ret = par->trigger(substream, cmd, 0);
if (ret < 0)
return ret;
@@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd = runtime->private_data;
unsigned long flags;
unsigned int offset;
dma_addr_t count;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
spin_lock_irqsave(&prtd->lock, flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -305,11 +316,12 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
static int s6000_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd;
int ret;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
ret = snd_pcm_hw_constraint_step(runtime, 0,
@@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
int ret;
ret = snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params));
@@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
return ret;
}
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
if (par->same_rate) {
spin_lock(&par->lock);
if (par->rate == -1 ||
@@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par =
+ snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
spin_lock(&par->lock);
par->in_use &= ~(1 << substream->stream);
@@ -417,7 +432,8 @@ static struct snd_pcm_ops s6000_pcm_ops = {
static void s6000_pcm_free(struct snd_pcm *pcm)
{
struct snd_soc_pcm_runtime *runtime = pcm->private_data;
- struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *params =
+ snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
free_irq(params->irq, pcm);
snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -429,9 +445,11 @@ static int s6000_pcm_new(struct snd_card *card,
struct snd_soc_dai *dai, struct snd_pcm *pcm)
{
struct snd_soc_pcm_runtime *runtime = pcm->private_data;
- struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *params;
int res;
+ params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
if (!card->dev->dma_mask)
card->dev->dma_mask = &s6000_pcm_dmamask;
if (!card->dev->coherent_dma_mask)
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 106674979b5..f07f6d8b93e 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -32,6 +32,7 @@ config SND_SOC_SH4_SIU
select DMA_ENGINE
select DMADEVICES
select SH_DMAE
+ select FW_LOADER
##
## Boards
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index baddb1242c7..0d8bdf07729 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -13,6 +13,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 993abb730df..8dc966f45c3 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -19,6 +19,7 @@
#include <linux/list.h>
#include <linux/pm_runtime.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/initval.h>
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 9cc04ab2bce..c0bfab8fed3 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -72,7 +72,7 @@ struct siu_firmware {
#include <linux/interrupt.h>
#include <linux/io.h>
-#include <asm/dma-sh.h>
+#include <asm/dmaengine.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index 5452d19607e..d86ee1bfc03 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/pm_runtime.h>
+#include <linux/slab.h>
#include <asm/clock.h>
#include <asm/siu.h>
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index c5efc30f013..8f85719212f 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -24,7 +24,6 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <sound/control.h>
#include <sound/core.h>
@@ -32,7 +31,7 @@
#include <sound/pcm_params.h>
#include <sound/soc-dai.h>
-#include <asm/dma-sh.h>
+#include <asm/dmaengine.h>
#include <asm/siu.h>
#include "siu.h"
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a03bac943aa..ad7f9528d75 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -28,6 +28,7 @@
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <sound/ac97_codec.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -427,24 +428,24 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
if (!runtime->hw.rates) {
printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
codec_dai->name, cpu_dai->name);
- goto machine_err;
+ goto config_err;
}
if (!runtime->hw.formats) {
printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
codec_dai->name, cpu_dai->name);
- goto machine_err;
+ goto config_err;
}
if (!runtime->hw.channels_min || !runtime->hw.channels_max) {
printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
codec_dai->name, cpu_dai->name);
- goto machine_err;
+ goto config_err;
}
/* Symmetry only applies if we've already got an active stream. */
if (cpu_dai->active || codec_dai->active) {
ret = soc_pcm_apply_symmetry(substream);
if (ret != 0)
- goto machine_err;
+ goto config_err;
}
pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
@@ -464,10 +465,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
mutex_unlock(&pcm_mutex);
return 0;
-machine_err:
+config_err:
if (machine->ops && machine->ops->shutdown)
machine->ops->shutdown(substream);
+machine_err:
+ if (codec_dai->ops->shutdown)
+ codec_dai->ops->shutdown(substream, codec_dai);
+
codec_dai_err:
if (platform->pcm_ops->close)
platform->pcm_ops->close(substream);
@@ -1544,7 +1549,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
mutex_unlock(&codec->mutex);
return ret;
}
- if (card->dai_link[i].codec_dai->ac97_control) {
+ /* Check for codec->ac97 to handle the ac97.c fun */
+ if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
snd_ac97_dev_add_pdata(codec->ac97,
card->dai_link[i].cpu_dai->ac97_pdata);
}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 6c335109578..7c28f401f43 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -38,6 +38,7 @@
#include <linux/platform_device.h>
#include <linux/jiffies.h>
#include <linux/debugfs.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 0f83bdb9b16..612e18b4bf4 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/gfp.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index efed64b8b02..49cc7ea9a51 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/sound_firmware.c b/sound/sound_firmware.c
index 96deaefaa89..340a0bc5303 100644
--- a/sound/sound_firmware.c
+++ b/sound/sound_firmware.c
@@ -2,7 +2,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include "oss/sound_firmware.h"
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 8d13d933087..7dcc06512e8 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -10,7 +10,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 1d2e51b3f91..2eab6ce4885 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -58,6 +58,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c
index 687e6a13689..58a32a10d11 100644
--- a/sound/synth/emux/emux_proc.c
+++ b/sound/synth/emux/emux_proc.c
@@ -19,7 +19,6 @@
*/
#include <linux/wait.h>
-#include <linux/slab.h>
#include <sound/core.h>
#include <sound/emux_synth.h>
#include <sound/info.h>
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 8c2925814ce..c570ae3e6d5 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -22,13 +22,13 @@ config SND_USB_AUDIO
will be called snd-usb-audio.
config SND_USB_UA101
- tristate "Edirol UA-101 driver (EXPERIMENTAL)"
+ tristate "Edirol UA-101/UA-1000 driver (EXPERIMENTAL)"
depends on EXPERIMENTAL
select SND_PCM
select SND_RAWMIDI
help
- Say Y here to include support for the Edirol UA-101 audio/MIDI
- interface.
+ Say Y here to include support for the Edirol UA-101 and UA-1000
+ audio/MIDI interfaces.
To compile this driver as a module, choose M here: the module
will be called snd-ua101.
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 86b2c3b92df..4328cad6c3a 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -17,6 +17,7 @@
*/
#include <linux/spinlock.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <sound/core.h>
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index a3f02dd9744..afc5aeb6800 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/usb.h>
#include <sound/initval.h>
#include <sound/core.h>
diff --git a/sound/usb/caiaq/midi.c b/sound/usb/caiaq/midi.c
index 538e8c00d31..2f218c77fff 100644
--- a/sound/usb/caiaq/midi.c
+++ b/sound/usb/caiaq/midi.c
@@ -17,6 +17,7 @@
*/
#include <linux/usb.h>
+#include <linux/gfp.h>
#include <sound/rawmidi.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/usb/caiaq/midi.h b/sound/usb/caiaq/midi.h
index 9d16db027fc..380f984babc 100644
--- a/sound/usb/caiaq/midi.h
+++ b/sound/usb/caiaq/midi.h
@@ -3,6 +3,6 @@
int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
-void snd_usb_caiaq_midi_output_done(struct urb* urb);
+void snd_usb_caiaq_midi_output_done(struct urb *urb);
#endif /* CAIAQ_MIDI_H */
diff --git a/sound/usb/ua101.c b/sound/usb/ua101.c
index 4f4ccdf70dd..3d458d3b996 100644
--- a/sound/usb/ua101.c
+++ b/sound/usb/ua101.c
@@ -1,5 +1,5 @@
/*
- * Edirol UA-101 driver
+ * Edirol UA-101/UA-1000 driver
* Copyright (c) Clemens Ladisch <clemens@ladisch.de>
*
* This driver is free software: you can redistribute it and/or modify
@@ -25,13 +25,10 @@
#include <sound/pcm_params.h>
#include "usbaudio.h"
-MODULE_DESCRIPTION("Edirol UA-101 driver");
+MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101}}");
-
-/* I use my UA-1A for testing because I don't have a UA-101 ... */
-#define UA1A_HACK
+MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
/*
* Should not be lower than the minimum scheduling delay of the host
@@ -132,9 +129,6 @@ struct ua101 {
dma_addr_t dma;
} buffers[MAX_MEMORY_BUFFERS];
} capture, playback;
-
- unsigned int fps[10];
- unsigned int frame_counter;
};
static DEFINE_MUTEX(devices_mutex);
@@ -424,16 +418,6 @@ static void capture_urb_complete(struct urb *urb)
if (do_period_elapsed)
snd_pcm_period_elapsed(stream->substream);
- /* for debugging: measure the sample rate relative to the USB clock */
- ua->fps[ua->frame_counter++ / ua->packets_per_second] += frames;
- if (ua->frame_counter >= ARRAY_SIZE(ua->fps) * ua->packets_per_second) {
- printk(KERN_DEBUG "capture rate:");
- for (frames = 0; frames < ARRAY_SIZE(ua->fps); ++frames)
- printk(KERN_CONT " %u", ua->fps[frames]);
- printk(KERN_CONT "\n");
- memset(ua->fps, 0, sizeof(ua->fps));
- ua->frame_counter = 0;
- }
return;
stream_stopped:
@@ -1200,13 +1184,30 @@ static int ua101_probe(struct usb_interface *interface,
.type = QUIRK_MIDI_FIXED_ENDPOINT,
.data = &midi_ep
};
+ static const int intf_numbers[2][3] = {
+ { /* UA-101 */
+ [INTF_PLAYBACK] = 0,
+ [INTF_CAPTURE] = 1,
+ [INTF_MIDI] = 2,
+ },
+ { /* UA-1000 */
+ [INTF_CAPTURE] = 1,
+ [INTF_PLAYBACK] = 2,
+ [INTF_MIDI] = 3,
+ },
+ };
struct snd_card *card;
struct ua101 *ua;
unsigned int card_index, i;
+ int is_ua1000;
+ const char *name;
char usb_path[32];
int err;
- if (interface->altsetting->desc.bInterfaceNumber != 0)
+ is_ua1000 = usb_id->idProduct == 0x0044;
+
+ if (interface->altsetting->desc.bInterfaceNumber !=
+ intf_numbers[is_ua1000][0])
return -ENODEV;
mutex_lock(&devices_mutex);
@@ -1239,20 +1240,13 @@ static int ua101_probe(struct usb_interface *interface,
init_waitqueue_head(&ua->rate_feedback_wait);
init_waitqueue_head(&ua->alsa_playback_wait);
-#ifdef UA1A_HACK
- if (ua->dev->descriptor.idProduct == cpu_to_le16(0x0018)) {
- ua->intf[2] = interface;
- ua->intf[0] = usb_ifnum_to_if(ua->dev, 1);
- ua->intf[1] = usb_ifnum_to_if(ua->dev, 2);
- usb_driver_claim_interface(&ua101_driver, ua->intf[0], ua);
- usb_driver_claim_interface(&ua101_driver, ua->intf[1], ua);
- } else {
-#endif
ua->intf[0] = interface;
for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) {
- ua->intf[i] = usb_ifnum_to_if(ua->dev, i);
+ ua->intf[i] = usb_ifnum_to_if(ua->dev,
+ intf_numbers[is_ua1000][i]);
if (!ua->intf[i]) {
- dev_err(&ua->dev->dev, "interface %u not found\n", i);
+ dev_err(&ua->dev->dev, "interface %u not found\n",
+ intf_numbers[is_ua1000][i]);
err = -ENXIO;
goto probe_error;
}
@@ -1264,39 +1258,19 @@ static int ua101_probe(struct usb_interface *interface,
goto probe_error;
}
}
-#ifdef UA1A_HACK
- }
-#endif
snd_card_set_dev(card, &interface->dev);
-#ifdef UA1A_HACK
- if (ua->dev->descriptor.idProduct == cpu_to_le16(0x0018)) {
- ua->format_bit = SNDRV_PCM_FMTBIT_S16_LE;
- ua->rate = 44100;
- ua->packets_per_second = 1000;
- ua->capture.channels = 2;
- ua->playback.channels = 2;
- ua->capture.frame_bytes = 4;
- ua->playback.frame_bytes = 4;
- ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, 2);
- ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, 1);
- ua->capture.max_packet_bytes = 192;
- ua->playback.max_packet_bytes = 192;
- } else {
-#endif
err = detect_usb_format(ua);
if (err < 0)
goto probe_error;
-#ifdef UA1A_HACK
- }
-#endif
+ name = usb_id->idProduct == 0x0044 ? "UA-1000" : "UA-101";
strcpy(card->driver, "UA-101");
- strcpy(card->shortname, "UA-101");
+ strcpy(card->shortname, name);
usb_make_path(ua->dev, usb_path, sizeof(usb_path));
snprintf(ua->card->longname, sizeof(ua->card->longname),
- "EDIROL UA-101 (serial %s), %u Hz at %s, %s speed",
+ "EDIROL %s (serial %s), %u Hz at %s, %s speed", name,
ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path,
ua->dev->speed == USB_SPEED_HIGH ? "high" : "full");
@@ -1314,24 +1288,18 @@ static int ua101_probe(struct usb_interface *interface,
if (err < 0)
goto probe_error;
- err = snd_pcm_new(card, "UA-101", 0, 1, 1, &ua->pcm);
+ err = snd_pcm_new(card, name, 0, 1, 1, &ua->pcm);
if (err < 0)
goto probe_error;
ua->pcm->private_data = ua;
- strcpy(ua->pcm->name, "UA-101");
+ strcpy(ua->pcm->name, name);
snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops);
snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops);
-#ifdef UA1A_HACK
- if (ua->dev->descriptor.idProduct != cpu_to_le16(0x0018)) {
-#endif
err = snd_usbmidi_create(card, ua->intf[INTF_MIDI],
&ua->midi_list, &midi_quirk);
if (err < 0)
goto probe_error;
-#ifdef UA1A_HACK
- }
-#endif
err = snd_card_register(card);
if (err < 0)
@@ -1386,11 +1354,9 @@ static void ua101_disconnect(struct usb_interface *interface)
}
static struct usb_device_id ua101_ids[] = {
-#ifdef UA1A_HACK
- { USB_DEVICE(0x0582, 0x0018) },
-#endif
- { USB_DEVICE(0x0582, 0x007d) },
- { USB_DEVICE(0x0582, 0x008d) },
+ { USB_DEVICE(0x0582, 0x0044) }, /* UA-1000 high speed */
+ { USB_DEVICE(0x0582, 0x007d) }, /* UA-101 high speed */
+ { USB_DEVICE(0x0582, 0x008d) }, /* UA-101 full speed */
{ }
};
MODULE_DEVICE_TABLE(usb, ua101_ids);
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c539f7fe292..11b0826b8fe 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2483,7 +2483,6 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip,
sample_width, sample_bytes);
}
/* check the format byte size */
- printk(" XXXXX SAMPLE BYTES %d\n", sample_bytes);
switch (sample_bytes) {
case 1:
pcm_format = SNDRV_PCM_FORMAT_S8;
@@ -2581,6 +2580,9 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
fp->altsetting == 5 && fp->maxpacksize == 392)
rate = 96000;
+ /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
+ if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
+ rate = 8000;
fp->rate_table[fp->nr_rates] = rate;
if (!fp->rate_min || rate < fp->rate_min)
fp->rate_min = rate;
@@ -3386,58 +3388,6 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
return 0;
}
-/*
- * Create a stream for an Edirol UA-1000 interface.
- */
-static int create_ua1000_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- const struct snd_usb_audio_quirk *quirk)
-{
- static const struct audioformat ua1000_format = {
- .format = SNDRV_PCM_FORMAT_S32_LE,
- .fmt_type = UAC_FORMAT_TYPE_I,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- };
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- struct audioformat *fp;
- int stream, err;
-
- if (iface->num_altsetting != 2)
- return -ENXIO;
- alts = &iface->altsetting[1];
- altsd = get_iface_desc(alts);
- if (alts->extralen != 11 || alts->extra[1] != USB_DT_CS_INTERFACE ||
- altsd->bNumEndpoints != 1)
- return -ENXIO;
-
- fp = kmemdup(&ua1000_format, sizeof(*fp), GFP_KERNEL);
- if (!fp)
- return -ENOMEM;
-
- fp->channels = alts->extra[4];
- fp->iface = altsd->bInterfaceNumber;
- fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
- fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
- fp->datainterval = parse_datainterval(chip, alts);
- fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
- fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
-
- stream = (fp->endpoint & USB_DIR_IN)
- ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- err = add_audio_endpoint(chip, stream, fp);
- if (err < 0) {
- kfree(fp);
- return err;
- }
- /* FIXME: playback must be synchronized to capture */
- usb_set_interface(chip->dev, fp->iface, 0);
- return 0;
-}
-
static int snd_usb_create_quirk(struct snd_usb_audio *chip,
struct usb_interface *iface,
const struct snd_usb_audio_quirk *quirk);
@@ -3686,7 +3636,6 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
[QUIRK_MIDI_CME] = create_any_midi_quirk,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
- [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
[QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
};
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 6b016d4aac6..42c299cbf63 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -75,7 +75,6 @@ enum quirk_type {
QUIRK_MIDI_US122L,
QUIRK_AUDIO_STANDARD_INTERFACE,
QUIRK_AUDIO_FIXED_ENDPOINT,
- QUIRK_AUDIO_EDIROL_UA1000,
QUIRK_AUDIO_EDIROL_UAXX,
QUIRK_AUDIO_ALIGN_TRANSFER,
@@ -112,7 +111,7 @@ struct snd_usb_midi_endpoint_info {
/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
-/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */
+/* for QUIRK_AUDIO_EDIROL_UAXX, data is NULL */
/* for QUIRK_IGNORE_INTERFACE, data is NULL */
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 2c59afd9961..9e28b20cb2c 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
DEFINE_WAIT(wait);
long timeout = msecs_to_jiffies(50);
+ if (ep->umidi->disconnected)
+ return;
/*
* The substream buffer is empty, but some data might still be in the
* currently active URBs, so we have to wait for those to complete.
@@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
* Frees an output endpoint.
* May be called when ep hasn't been initialized completely.
*/
-static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep)
+static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
{
unsigned int i;
for (i = 0; i < OUTPUT_URBS; ++i)
- if (ep->urbs[i].urb)
+ if (ep->urbs[i].urb) {
free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
ep->max_transfer);
+ ep->urbs[i].urb = NULL;
+ }
+}
+
+static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
+{
+ snd_usbmidi_out_endpoint_clear(ep);
kfree(ep);
}
@@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
usb_kill_urb(ep->out->urbs[j].urb);
if (umidi->usb_protocol_ops->finish_out_endpoint)
umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
+ ep->out->active_urbs = 0;
+ if (ep->out->drain_urbs) {
+ ep->out->drain_urbs = 0;
+ wake_up(&ep->out->drain_wait);
+ }
}
if (ep->in)
for (j = 0; j < INPUT_URBS; ++j)
usb_kill_urb(ep->in->urbs[j]);
/* free endpoints here; later call can result in Oops */
- if (ep->out) {
- snd_usbmidi_out_endpoint_delete(ep->out);
- ep->out = NULL;
- }
+ if (ep->out)
+ snd_usbmidi_out_endpoint_clear(ep->out);
if (ep->in) {
snd_usbmidi_in_endpoint_delete(ep->in);
ep->in = NULL;
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index f06faf7917b..2b426c1fd0e 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1016,36 +1016,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
- USB_DEVICE(0x0582, 0x0044),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "UA-1000",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UA1000
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UA1000
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
/* has ID 0x0049 when not in "Advanced Driver" mode */
USB_DEVICE(0x0582, 0x0047),
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 44deb21b177..9ca9a13a78d 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -16,6 +16,7 @@
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/audio.h>
#include <sound/core.h>
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 1879b72c40f..04aafb43a13 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -21,6 +21,7 @@
*/
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <sound/core.h>
#include <sound/memalloc.h>
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index 12ae0340adc..c400ade3ff0 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -17,6 +17,7 @@
*/
#include <linux/usb.h>
+#include <linux/gfp.h>
#include "usb_stream.h"
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index c42350eed2e..cbd37f2c76d 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -133,6 +133,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <sound/core.h>
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 74a67a85aa8..5d37d1ccf81 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/usb.h>
#include <sound/core.h>
#include <sound/info.h>
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 9ed6c3956ca..2a528e56afd 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -51,6 +51,7 @@
*/
#include <linux/delay.h>
+#include <linux/gfp.h>
#include "usbusx2yaudio.c"
#if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1)
diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile
index bdd3b7ecad0..bd498d49695 100644
--- a/tools/perf/Documentation/Makefile
+++ b/tools/perf/Documentation/Makefile
@@ -24,7 +24,10 @@ DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT))
DOC_MAN5=$(patsubst %.txt,%.5,$(MAN5_TXT))
DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
+# Make the path relative to DESTDIR, not prefix
+ifndef DESTDIR
prefix?=$(HOME)
+endif
bindir?=$(prefix)/bin
htmldir?=$(prefix)/share/doc/perf-doc
pdfdir?=$(prefix)/share/doc/perf-doc
@@ -32,7 +35,6 @@ mandir?=$(prefix)/share/man
man1dir=$(mandir)/man1
man5dir=$(mandir)/man5
man7dir=$(mandir)/man7
-# DESTDIR=
ASCIIDOC=asciidoc
ASCIIDOC_EXTRA = --unsafe
diff --git a/tools/perf/Documentation/perf-lock.txt b/tools/perf/Documentation/perf-lock.txt
new file mode 100644
index 00000000000..b317102138c
--- /dev/null
+++ b/tools/perf/Documentation/perf-lock.txt
@@ -0,0 +1,29 @@
+perf-lock(1)
+============
+
+NAME
+----
+perf-lock - Analyze lock events
+
+SYNOPSIS
+--------
+[verse]
+'perf lock' {record|report|trace}
+
+DESCRIPTION
+-----------
+You can analyze various lock behaviours
+and statistics with this 'perf lock' command.
+
+ 'perf lock record <command>' records lock events
+ between start and end <command>. And this command
+ produces the file "perf.data" which contains tracing
+ results of lock events.
+
+ 'perf lock trace' shows raw lock events.
+
+ 'perf lock report' reports statistical data.
+
+SEE ALSO
+--------
+linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 2de34075f6a..34202b1be0b 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -41,7 +41,8 @@ OPTIONS
-d::
--del=::
- Delete a probe event.
+ Delete probe events. This accepts glob wildcards('*', '?') and character
+ classes(e.g. [a-z], [!A-Z]).
-l::
--list::
@@ -50,17 +51,29 @@ OPTIONS
-L::
--line=::
Show source code lines which can be probed. This needs an argument
- which specifies a range of the source code.
+ which specifies a range of the source code. (see LINE SYNTAX for detail)
+
+-f::
+--force::
+ Forcibly add events with existing name.
PROBE SYNTAX
------------
Probe points are defined by following syntax.
- "[EVENT=]FUNC[+OFFS|:RLN|%return][@SRC]|SRC:ALN [ARG ...]"
+ 1) Define event based on function name
+ [EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]
+
+ 2) Define event based on source file with line number
+ [EVENT=]SRC:ALN [ARG ...]
+
+ 3) Define event based on source file with lazy pattern
+ [EVENT=]SRC;PTN [ARG ...]
+
'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'.
-'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, 'RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. In addition, 'SRC' specifies a source file which has that function.
-It is also possible to specify a probe point by the source line number by using 'SRC:ALN' syntax, where 'SRC' is the source file path and 'ALN' is the line number.
+'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function.
+It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
'ARG' specifies the arguments of this probe point. You can use the name of local variable, or kprobe-tracer argument format (e.g. $retval, %ax, etc).
LINE SYNTAX
@@ -76,6 +89,41 @@ and 'ALN2' is end line number in the file. It is also possible to specify how
many lines to show by using 'NUM'.
So, "source.c:100-120" shows lines between 100th to l20th in source.c file. And "func:10+20" shows 20 lines from 10th line of func function.
+LAZY MATCHING
+-------------
+ The lazy line matching is similar to glob matching but ignoring spaces in both of pattern and target. So this accepts wildcards('*', '?') and character classes(e.g. [a-z], [!A-Z]).
+
+e.g.
+ 'a=*' can matches 'a=b', 'a = b', 'a == b' and so on.
+
+This provides some sort of flexibility and robustness to probe point definitions against minor code changes. For example, actual 10th line of schedule() can be moved easily by modifying schedule(), but the same line matching 'rq=cpu_rq*' may still exist in the function.)
+
+
+EXAMPLES
+--------
+Display which lines in schedule() can be probed:
+
+ ./perf probe --line schedule
+
+Add a probe on schedule() function 12th line with recording cpu local variable:
+
+ ./perf probe schedule:12 cpu
+ or
+ ./perf probe --add='schedule:12 cpu'
+
+ this will add one or more probes which has the name start with "schedule".
+
+ Add probes on lines in schedule() function which calls update_rq_clock().
+
+ ./perf probe 'schedule;update_rq_clock*'
+ or
+ ./perf probe --add='schedule;update_rq_clock*'
+
+Delete all probes on schedule().
+
+ ./perf probe --del='schedule*'
+
+
SEE ALSO
--------
linkperf:perf-trace[1], linkperf:perf-record[1]
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 54a5b50ff31..bc0f670a833 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -200,7 +200,7 @@ endif
CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
EXTLIBS = -lpthread -lrt -lelf -lm
-ALL_CFLAGS = $(CFLAGS)
+ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
ALL_LDFLAGS = $(LDFLAGS)
STRIP ?= strip
@@ -216,7 +216,10 @@ STRIP ?= strip
# runtime figures out where they are based on the path to the executable.
# This can help installing the suite in a relocatable way.
+# Make the path relative to DESTDIR, not to prefix
+ifndef DESTDIR
prefix = $(HOME)
+endif
bindir_relative = bin
bindir = $(prefix)/$(bindir_relative)
mandir = share/man
@@ -233,7 +236,6 @@ sysconfdir = $(prefix)/etc
ETC_PERFCONFIG = etc/perfconfig
endif
lib = lib
-# DESTDIR=
export prefix bindir sharedir sysconfdir
@@ -387,6 +389,7 @@ LIB_H += util/thread.h
LIB_H += util/trace-event.h
LIB_H += util/probe-finder.h
LIB_H += util/probe-event.h
+LIB_H += util/cpumap.h
LIB_OBJS += util/abspath.o
LIB_OBJS += util/alias.o
@@ -433,6 +436,7 @@ LIB_OBJS += util/sort.o
LIB_OBJS += util/hist.o
LIB_OBJS += util/probe-event.o
LIB_OBJS += util/util.o
+LIB_OBJS += util/cpumap.o
BUILTIN_OBJS += builtin-annotate.o
@@ -488,24 +492,24 @@ ifeq ($(uname_S),Darwin)
PTHREAD_LIBS =
endif
-ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
-ifneq ($(shell sh -c "(echo '\#include <gnu/libc-version.h>'; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ifneq ($(shell sh -c "(echo '\#include <gnu/libc-version.h>'; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
endif
- ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
BASIC_CFLAGS += -DLIBELF_NO_MMAP
endif
else
msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
endif
-ifneq ($(shell sh -c "(echo '\#ifndef _MIPS_SZLONG'; echo '\#define _MIPS_SZLONG 0'; echo '\#endif'; echo '\#include <dwarf.h>'; echo '\#include <libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/libdwarf -ldwarf -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
- msg := $(warning No libdwarf.h found or old libdwarf.h found, disables dwarf support. Please install libdwarf-dev/libdwarf-devel >= 20081231);
- BASIC_CFLAGS += -DNO_LIBDWARF
+ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
+ BASIC_CFLAGS += -DNO_DWARF_SUPPORT
else
- BASIC_CFLAGS += -I/usr/include/libdwarf
- EXTLIBS += -lelf -ldwarf
+ BASIC_CFLAGS += -I/usr/include/elfutils
+ EXTLIBS += -lelf -ldw
LIB_OBJS += util/probe-finder.o
endif
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 5ec5de99587..6ad7148451c 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -116,7 +116,7 @@ static int perf_session__add_hist_entry(struct perf_session *self,
return 0;
}
- he = __perf_session__add_hist_entry(self, al, NULL, count, &hit);
+ he = __perf_session__add_hist_entry(&self->hists, al, NULL, count, &hit);
if (he == NULL)
return -ENOMEM;
@@ -564,8 +564,8 @@ static int __cmd_annotate(void)
if (verbose > 2)
dsos__fprintf(stdout);
- perf_session__collapse_resort(session);
- perf_session__output_resort(session, session->event_total[0]);
+ perf_session__collapse_resort(&session->hists);
+ perf_session__output_resort(&session->hists, session->event_total[0]);
perf_session__find_annotations(session);
out_delete:
perf_session__delete(session);
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 18b3f505f9d..1ea15d8aeed 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -26,7 +26,8 @@ static int perf_session__add_hist_entry(struct perf_session *self,
struct addr_location *al, u64 count)
{
bool hit;
- struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL,
+ struct hist_entry *he = __perf_session__add_hist_entry(&self->hists,
+ al, NULL,
count, &hit);
if (he == NULL)
return -ENOMEM;
@@ -114,7 +115,7 @@ static void perf_session__resort_hist_entries(struct perf_session *self)
static void perf_session__set_hist_entries_positions(struct perf_session *self)
{
- perf_session__output_resort(self, self->events_stats.total);
+ perf_session__output_resort(&self->hists, self->events_stats.total);
perf_session__resort_hist_entries(self);
}
@@ -166,13 +167,15 @@ static int __cmd_diff(void)
goto out_delete;
}
- perf_session__output_resort(session[1], session[1]->events_stats.total);
+ perf_session__output_resort(&session[1]->hists,
+ session[1]->events_stats.total);
if (show_displacement)
perf_session__set_hist_entries_positions(session[0]);
perf_session__match_hists(session[0], session[1]);
- perf_session__fprintf_hists(session[1], session[0],
- show_displacement, stdout);
+ perf_session__fprintf_hists(&session[1]->hists, session[0],
+ show_displacement, stdout,
+ session[1]->events_stats.total);
out_delete:
for (i = 0; i < 2; ++i)
perf_session__delete(session[i]);
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index fb9ab2ad3f9..e12c844df1e 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -460,6 +460,150 @@ process_raw_event(void *data, int cpu,
process_lock_release_event(data, event, cpu, timestamp, thread);
}
+struct raw_event_queue {
+ u64 timestamp;
+ int cpu;
+ void *data;
+ struct thread *thread;
+ struct list_head list;
+};
+
+static LIST_HEAD(raw_event_head);
+
+#define FLUSH_PERIOD (5 * NSEC_PER_SEC)
+
+static u64 flush_limit = ULLONG_MAX;
+static u64 last_flush = 0;
+struct raw_event_queue *last_inserted;
+
+static void flush_raw_event_queue(u64 limit)
+{
+ struct raw_event_queue *tmp, *iter;
+
+ list_for_each_entry_safe(iter, tmp, &raw_event_head, list) {
+ if (iter->timestamp > limit)
+ return;
+
+ if (iter == last_inserted)
+ last_inserted = NULL;
+
+ process_raw_event(iter->data, iter->cpu, iter->timestamp,
+ iter->thread);
+
+ last_flush = iter->timestamp;
+ list_del(&iter->list);
+ free(iter->data);
+ free(iter);
+ }
+}
+
+static void __queue_raw_event_end(struct raw_event_queue *new)
+{
+ struct raw_event_queue *iter;
+
+ list_for_each_entry_reverse(iter, &raw_event_head, list) {
+ if (iter->timestamp < new->timestamp) {
+ list_add(&new->list, &iter->list);
+ return;
+ }
+ }
+
+ list_add(&new->list, &raw_event_head);
+}
+
+static void __queue_raw_event_before(struct raw_event_queue *new,
+ struct raw_event_queue *iter)
+{
+ list_for_each_entry_continue_reverse(iter, &raw_event_head, list) {
+ if (iter->timestamp < new->timestamp) {
+ list_add(&new->list, &iter->list);
+ return;
+ }
+ }
+
+ list_add(&new->list, &raw_event_head);
+}
+
+static void __queue_raw_event_after(struct raw_event_queue *new,
+ struct raw_event_queue *iter)
+{
+ list_for_each_entry_continue(iter, &raw_event_head, list) {
+ if (iter->timestamp > new->timestamp) {
+ list_add_tail(&new->list, &iter->list);
+ return;
+ }
+ }
+ list_add_tail(&new->list, &raw_event_head);
+}
+
+/* The queue is ordered by time */
+static void __queue_raw_event(struct raw_event_queue *new)
+{
+ if (!last_inserted) {
+ __queue_raw_event_end(new);
+ return;
+ }
+
+ /*
+ * Most of the time the current event has a timestamp
+ * very close to the last event inserted, unless we just switched
+ * to another event buffer. Having a sorting based on a list and
+ * on the last inserted event that is close to the current one is
+ * probably more efficient than an rbtree based sorting.
+ */
+ if (last_inserted->timestamp >= new->timestamp)
+ __queue_raw_event_before(new, last_inserted);
+ else
+ __queue_raw_event_after(new, last_inserted);
+}
+
+static void queue_raw_event(void *data, int raw_size, int cpu,
+ u64 timestamp, struct thread *thread)
+{
+ struct raw_event_queue *new;
+
+ if (flush_limit == ULLONG_MAX)
+ flush_limit = timestamp + FLUSH_PERIOD;
+
+ if (timestamp < last_flush) {
+ printf("Warning: Timestamp below last timeslice flush\n");
+ return;
+ }
+
+ new = malloc(sizeof(*new));
+ if (!new)
+ die("Not enough memory\n");
+
+ new->timestamp = timestamp;
+ new->cpu = cpu;
+ new->thread = thread;
+
+ new->data = malloc(raw_size);
+ if (!new->data)
+ die("Not enough memory\n");
+
+ memcpy(new->data, data, raw_size);
+
+ __queue_raw_event(new);
+ last_inserted = new;
+
+ /*
+ * We want to have a slice of events covering 2 * FLUSH_PERIOD
+ * If FLUSH_PERIOD is big enough, it ensures every events that occured
+ * in the first half of the timeslice have all been buffered and there
+ * are none remaining (we need that because of the weakly ordered
+ * event recording we have). Then once we reach the 2 * FLUSH_PERIOD
+ * timeslice, we flush the first half to be gentle with the memory
+ * (the second half can still get new events in the middle, so wait
+ * another period to flush it)
+ */
+ if (new->timestamp > flush_limit &&
+ new->timestamp - flush_limit > FLUSH_PERIOD) {
+ flush_limit += FLUSH_PERIOD;
+ flush_raw_event_queue(flush_limit);
+ }
+}
+
static int process_sample_event(event_t *event, struct perf_session *session)
{
struct thread *thread;
@@ -480,7 +624,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
if (profile_cpu != -1 && profile_cpu != (int) data.cpu)
return 0;
- process_raw_event(data.raw_data, data.cpu, data.time, thread);
+ queue_raw_event(data.raw_data, data.raw_size, data.cpu, data.time, thread);
return 0;
}
@@ -576,6 +720,7 @@ static void __cmd_report(void)
setup_pager();
select_key();
read_events();
+ flush_raw_event_queue(ULLONG_MAX);
sort_result();
print_result();
}
@@ -608,7 +753,6 @@ static const char *record_args[] = {
"record",
"-a",
"-R",
- "-M",
"-f",
"-m", "1024",
"-c", "1",
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index ad47bd4c50e..152d6c9b1fa 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -47,7 +47,6 @@
#include "util/probe-event.h"
#define MAX_PATH_LEN 256
-#define MAX_PROBES 128
/* Session management structure */
static struct {
@@ -128,7 +127,7 @@ static void evaluate_probe_point(struct probe_point *pp)
pp->function);
}
-#ifndef NO_LIBDWARF
+#ifndef NO_DWARF_SUPPORT
static int open_vmlinux(void)
{
if (map__load(session.kmaps[MAP__FUNCTION], NULL) < 0) {
@@ -156,14 +155,16 @@ static const char * const probe_usage[] = {
"perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
"perf probe [<options>] --del '[GROUP:]EVENT' ...",
"perf probe --list",
+#ifndef NO_DWARF_SUPPORT
"perf probe --line 'LINEDESC'",
+#endif
NULL
};
static const struct option options[] = {
OPT_BOOLEAN('v', "verbose", &verbose,
"be more verbose (show parsed arguments, etc)"),
-#ifndef NO_LIBDWARF
+#ifndef NO_DWARF_SUPPORT
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
"file", "vmlinux pathname"),
#endif
@@ -172,30 +173,32 @@ static const struct option options[] = {
OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
opt_del_probe_event),
OPT_CALLBACK('a', "add", NULL,
-#ifdef NO_LIBDWARF
- "[EVENT=]FUNC[+OFFS|%return] [ARG ...]",
+#ifdef NO_DWARF_SUPPORT
+ "[EVENT=]FUNC[+OFF|%return] [ARG ...]",
#else
- "[EVENT=]FUNC[+OFFS|%return|:RLN][@SRC]|SRC:ALN [ARG ...]",
+ "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
+ " [ARG ...]",
#endif
"probe point definition, where\n"
"\t\tGROUP:\tGroup name (optional)\n"
"\t\tEVENT:\tEvent name\n"
"\t\tFUNC:\tFunction name\n"
- "\t\tOFFS:\tOffset from function entry (in byte)\n"
+ "\t\tOFF:\tOffset from function entry (in byte)\n"
"\t\t%return:\tPut the probe at function return\n"
-#ifdef NO_LIBDWARF
+#ifdef NO_DWARF_SUPPORT
"\t\tARG:\tProbe argument (only \n"
#else
"\t\tSRC:\tSource code path\n"
- "\t\tRLN:\tRelative line number from function entry.\n"
- "\t\tALN:\tAbsolute line number in file.\n"
+ "\t\tRL:\tRelative line number from function entry.\n"
+ "\t\tAL:\tAbsolute line number in file.\n"
+ "\t\tPT:\tLazy expression of line code.\n"
"\t\tARG:\tProbe argument (local variable name or\n"
#endif
"\t\t\tkprobe-tracer argument format.)\n",
opt_add_probe_event),
OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events"
" with existing name"),
-#ifndef NO_LIBDWARF
+#ifndef NO_DWARF_SUPPORT
OPT_CALLBACK('L', "line", NULL,
"FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]",
"Show source code lines.", opt_show_lines),
@@ -223,7 +226,7 @@ static void init_vmlinux(void)
int cmd_probe(int argc, const char **argv, const char *prefix __used)
{
int i, ret;
-#ifndef NO_LIBDWARF
+#ifndef NO_DWARF_SUPPORT
int fd;
#endif
struct probe_point *pp;
@@ -259,7 +262,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
return 0;
}
-#ifndef NO_LIBDWARF
+#ifndef NO_DWARF_SUPPORT
if (session.show_lines) {
if (session.nr_probe != 0 || session.dellist) {
pr_warning(" Error: Don't use --line with"
@@ -290,9 +293,9 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
init_vmlinux();
if (session.need_dwarf)
-#ifdef NO_LIBDWARF
+#ifdef NO_DWARF_SUPPORT
die("Debuginfo-analysis is not supported");
-#else /* !NO_LIBDWARF */
+#else /* !NO_DWARF_SUPPORT */
pr_debug("Some probes require debuginfo.\n");
fd = open_vmlinux();
@@ -312,7 +315,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
continue;
lseek(fd, SEEK_SET, 0);
- ret = find_probepoint(fd, pp);
+ ret = find_probe_point(fd, pp);
if (ret > 0)
continue;
if (ret == 0) { /* No error but failed to find probe point. */
@@ -333,7 +336,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
close(fd);
end_dwarf:
-#endif /* !NO_LIBDWARF */
+#endif /* !NO_DWARF_SUPPORT */
/* Synthesize probes without dwarf */
for (i = 0; i < session.nr_probe; i++) {
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 771533ced6a..3b8b6387c47 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -22,6 +22,7 @@
#include "util/debug.h"
#include "util/session.h"
#include "util/symbol.h"
+#include "util/cpumap.h"
#include <unistd.h>
#include <sched.h>
@@ -244,6 +245,9 @@ static void create_counter(int counter, int cpu, pid_t pid)
attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
+ if (nr_counters > 1)
+ attr->sample_type |= PERF_SAMPLE_ID;
+
if (freq) {
attr->sample_type |= PERF_SAMPLE_PERIOD;
attr->freq = 1;
@@ -391,6 +395,9 @@ static int process_buildids(void)
{
u64 size = lseek(output, 0, SEEK_CUR);
+ if (size == 0)
+ return 0;
+
session->fd = output;
return __perf_session__process_events(session, post_processing_offset,
size - post_processing_offset,
@@ -418,9 +425,6 @@ static int __cmd_record(int argc, const char **argv)
char buf;
page_size = sysconf(_SC_PAGE_SIZE);
- nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
- assert(nr_cpus <= MAX_NR_CPUS);
- assert(nr_cpus >= 0);
atexit(sig_atexit);
signal(SIGCHLD, sig_handler);
@@ -544,8 +548,9 @@ static int __cmd_record(int argc, const char **argv)
if ((!system_wide && !inherit) || profile_cpu != -1) {
open_counters(profile_cpu, target_pid);
} else {
+ nr_cpus = read_cpu_map();
for (i = 0; i < nr_cpus; i++)
- open_counters(i, target_pid);
+ open_counters(cpumap[i], target_pid);
}
if (file_new) {
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index cfc655d40bb..f815de25d0f 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -45,28 +45,71 @@ static char *pretty_printing_style = default_pretty_printing_style;
static char callchain_default_opt[] = "fractal,0.5";
+static struct event_stat_id *get_stats(struct perf_session *self,
+ u64 event_stream, u32 type, u64 config)
+{
+ struct rb_node **p = &self->stats_by_id.rb_node;
+ struct rb_node *parent = NULL;
+ struct event_stat_id *iter, *new;
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct event_stat_id, rb_node);
+ if (iter->config == config)
+ return iter;
+
+
+ if (config > iter->config)
+ p = &(*p)->rb_right;
+ else
+ p = &(*p)->rb_left;
+ }
+
+ new = malloc(sizeof(struct event_stat_id));
+ if (new == NULL)
+ return NULL;
+ memset(new, 0, sizeof(struct event_stat_id));
+ new->event_stream = event_stream;
+ new->config = config;
+ new->type = type;
+ rb_link_node(&new->rb_node, parent, p);
+ rb_insert_color(&new->rb_node, &self->stats_by_id);
+ return new;
+}
+
static int perf_session__add_hist_entry(struct perf_session *self,
struct addr_location *al,
- struct ip_callchain *chain, u64 count)
+ struct sample_data *data)
{
struct symbol **syms = NULL, *parent = NULL;
bool hit;
struct hist_entry *he;
+ struct event_stat_id *stats;
+ struct perf_event_attr *attr;
- if ((sort__has_parent || symbol_conf.use_callchain) && chain)
+ if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain)
syms = perf_session__resolve_callchain(self, al->thread,
- chain, &parent);
- he = __perf_session__add_hist_entry(self, al, parent, count, &hit);
+ data->callchain, &parent);
+
+ attr = perf_header__find_attr(data->id, &self->header);
+ if (attr)
+ stats = get_stats(self, data->id, attr->type, attr->config);
+ else
+ stats = get_stats(self, data->id, 0, 0);
+ if (stats == NULL)
+ return -ENOMEM;
+ he = __perf_session__add_hist_entry(&stats->hists, al, parent,
+ data->period, &hit);
if (he == NULL)
return -ENOMEM;
if (hit)
- he->count += count;
+ he->count += data->period;
if (symbol_conf.use_callchain) {
if (!hit)
callchain_init(&he->callchain);
- append_chain(&he->callchain, chain, syms);
+ append_chain(&he->callchain, data->callchain, syms);
free(syms);
}
@@ -86,10 +129,30 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
return 0;
}
+static int add_event_total(struct perf_session *session,
+ struct sample_data *data,
+ struct perf_event_attr *attr)
+{
+ struct event_stat_id *stats;
+
+ if (attr)
+ stats = get_stats(session, data->id, attr->type, attr->config);
+ else
+ stats = get_stats(session, data->id, 0, 0);
+
+ if (!stats)
+ return -ENOMEM;
+
+ stats->stats.total += data->period;
+ session->events_stats.total += data->period;
+ return 0;
+}
+
static int process_sample_event(event_t *event, struct perf_session *session)
{
struct sample_data data = { .period = 1, };
struct addr_location al;
+ struct perf_event_attr *attr;
event__parse_sample(event, session->sample_type, &data);
@@ -123,12 +186,18 @@ static int process_sample_event(event_t *event, struct perf_session *session)
if (al.filtered || (hide_unresolved && al.sym == NULL))
return 0;
- if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) {
+ if (perf_session__add_hist_entry(session, &al, &data)) {
pr_debug("problem incrementing symbol count, skipping event\n");
return -1;
}
- session->events_stats.total += data.period;
+ attr = perf_header__find_attr(data.id, &session->header);
+
+ if (add_event_total(session, &data, attr)) {
+ pr_debug("problem adding event count\n");
+ return -1;
+ }
+
return 0;
}
@@ -197,6 +266,7 @@ static int __cmd_report(void)
{
int ret = -EINVAL;
struct perf_session *session;
+ struct rb_node *next;
session = perf_session__new(input_name, O_RDONLY, force);
if (session == NULL)
@@ -224,10 +294,28 @@ static int __cmd_report(void)
if (verbose > 2)
dsos__fprintf(stdout);
- perf_session__collapse_resort(session);
- perf_session__output_resort(session, session->events_stats.total);
- fprintf(stdout, "# Samples: %Ld\n#\n", session->events_stats.total);
- perf_session__fprintf_hists(session, NULL, false, stdout);
+ next = rb_first(&session->stats_by_id);
+ while (next) {
+ struct event_stat_id *stats;
+
+ stats = rb_entry(next, struct event_stat_id, rb_node);
+ perf_session__collapse_resort(&stats->hists);
+ perf_session__output_resort(&stats->hists, stats->stats.total);
+ if (rb_first(&session->stats_by_id) ==
+ rb_last(&session->stats_by_id))
+ fprintf(stdout, "# Samples: %Ld\n#\n",
+ stats->stats.total);
+ else
+ fprintf(stdout, "# Samples: %Ld %s\n#\n",
+ stats->stats.total,
+ __event_name(stats->type, stats->config));
+
+ perf_session__fprintf_hists(&stats->hists, NULL, false, stdout,
+ stats->stats.total);
+ fprintf(stdout, "\n\n");
+ next = rb_next(&stats->rb_node);
+ }
+
if (sort_order == default_sort_order &&
parent_pattern == default_parent_pattern)
fprintf(stdout, "#\n# (For a higher level overview, try: perf report --sort comm,dso)\n#\n");
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e8c85d5aec4..95db31cff6f 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -45,6 +45,7 @@
#include "util/event.h"
#include "util/debug.h"
#include "util/header.h"
+#include "util/cpumap.h"
#include <sys/prctl.h>
#include <math.h>
@@ -151,7 +152,7 @@ static void create_perf_stat_counter(int counter, int pid)
unsigned int cpu;
for (cpu = 0; cpu < nr_cpus; cpu++) {
- fd[cpu][counter] = sys_perf_event_open(attr, -1, cpu, -1, 0);
+ fd[cpu][counter] = sys_perf_event_open(attr, -1, cpumap[cpu], -1, 0);
if (fd[cpu][counter] < 0 && verbose)
fprintf(stderr, ERR_PERF_OPEN, counter,
fd[cpu][counter], strerror(errno));
@@ -519,9 +520,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
nr_counters = ARRAY_SIZE(default_attrs);
}
- nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
- assert(nr_cpus <= MAX_NR_CPUS);
- assert((int)nr_cpus >= 0);
+ if (system_wide)
+ nr_cpus = read_cpu_map();
+ else
+ nr_cpus = 1;
/*
* We dont want to block the signals - that would cause
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 31f2e597800..1f529321607 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -28,6 +28,7 @@
#include <linux/rbtree.h>
#include "util/parse-options.h"
#include "util/parse-events.h"
+#include "util/cpumap.h"
#include "util/debug.h"
@@ -454,7 +455,7 @@ static void print_sym_table(void)
struct sym_entry *syme, *n;
struct rb_root tmp = RB_ROOT;
struct rb_node *nd;
- int sym_width = 0, dso_width = 0, max_dso_width;
+ int sym_width = 0, dso_width = 0, dso_short_width = 0;
const int win_width = winsize.ws_col - 1;
samples = userspace_samples = 0;
@@ -544,15 +545,20 @@ static void print_sym_table(void)
if (syme->map->dso->long_name_len > dso_width)
dso_width = syme->map->dso->long_name_len;
+ if (syme->map->dso->short_name_len > dso_short_width)
+ dso_short_width = syme->map->dso->short_name_len;
+
if (syme->name_len > sym_width)
sym_width = syme->name_len;
}
printed = 0;
- max_dso_width = winsize.ws_col - sym_width - 29;
- if (dso_width > max_dso_width)
- dso_width = max_dso_width;
+ if (sym_width + dso_width > winsize.ws_col - 29) {
+ dso_width = dso_short_width;
+ if (sym_width + dso_width > winsize.ws_col - 29)
+ sym_width = winsize.ws_col - dso_width - 29;
+ }
putchar('\n');
if (nr_counters == 1)
printf(" samples pcnt");
@@ -1123,7 +1129,7 @@ static void start_counter(int i, int counter)
cpu = profile_cpu;
if (target_pid == -1 && profile_cpu == -1)
- cpu = i;
+ cpu = cpumap[i];
attr = attrs + counter;
@@ -1347,12 +1353,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
attrs[counter].sample_period = default_interval;
}
- nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
- assert(nr_cpus <= MAX_NR_CPUS);
- assert(nr_cpus >= 0);
-
if (target_pid != -1 || profile_cpu != -1)
nr_cpus = 1;
+ else
+ nr_cpus = read_cpu_map();
get_term_dimensions(&winsize);
if (print_entries == 0) {
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 5db687fc13d..407041d20de 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -573,7 +573,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
if (symbol__init() < 0)
return -1;
- setup_pager();
+ if (!script_name)
+ setup_pager();
session = perf_session__new(input_name, O_RDONLY, 0);
if (session == NULL)
@@ -608,7 +609,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
return -1;
}
- perf_header__read(&session->header, input);
err = scripting_ops->generate_script("perf-trace");
goto out;
}
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 9afcff2e3ae..db6ee94d4a8 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -18,3 +18,4 @@ perf-top mainporcelain common
perf-trace mainporcelain common
perf-probe mainporcelain common
perf-kmem mainporcelain common
+perf-lock mainporcelain common
diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh
index 45fbe2f07b1..910468e6e01 100644
--- a/tools/perf/perf-archive.sh
+++ b/tools/perf/perf-archive.sh
@@ -9,8 +9,9 @@ fi
DEBUGDIR=~/.debug/
BUILDIDS=$(mktemp /tmp/perf-archive-buildids.XXXXXX)
+NOBUILDID=0000000000000000000000000000000000000000
-perf buildid-list -i $PERF_DATA --with-hits > $BUILDIDS
+perf buildid-list -i $PERF_DATA --with-hits | grep -v "^$NOBUILDID " > $BUILDIDS
if [ ! -s $BUILDIDS ] ; then
echo "perf archive: no build-ids found"
rm -f $BUILDIDS
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 57cb107c1f1..cd32c200cdb 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -445,7 +445,7 @@ int main(int argc, const char **argv)
/*
* We use PATH to find perf commands, but we prepend some higher
- * precidence paths: the "--exec-path" option, the PERF_EXEC_PATH
+ * precedence paths: the "--exec-path" option, the PERF_EXEC_PATH
* environment, and the $(perfexecdir) from the Makefile at build
* time.
*/
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 75f941bfba9..6fb379bc1d1 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -65,9 +65,7 @@
* Use the __kuser_memory_barrier helper in the CPU helper page. See
* arch/arm/kernel/entry-armv.S in the kernel source for details.
*/
-#define rmb() asm volatile("mov r0, #0xffff0fff; mov lr, pc;" \
- "sub pc, r0, #95" ::: "r0", "lr", "cc", \
- "memory")
+#define rmb() ((void(*)(void))0xffff0fa0)()
#define cpu_relax() asm volatile("":::"memory")
#endif
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
new file mode 100644
index 00000000000..4e01490e51e
--- /dev/null
+++ b/tools/perf/util/cpumap.c
@@ -0,0 +1,59 @@
+#include "util.h"
+#include "../perf.h"
+#include "cpumap.h"
+#include <assert.h>
+#include <stdio.h>
+
+int cpumap[MAX_NR_CPUS];
+
+static int default_cpu_map(void)
+{
+ int nr_cpus, i;
+
+ nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ assert(nr_cpus <= MAX_NR_CPUS);
+ assert((int)nr_cpus >= 0);
+
+ for (i = 0; i < nr_cpus; ++i)
+ cpumap[i] = i;
+
+ return nr_cpus;
+}
+
+int read_cpu_map(void)
+{
+ FILE *onlnf;
+ int nr_cpus = 0;
+ int n, cpu, prev;
+ char sep;
+
+ onlnf = fopen("/sys/devices/system/cpu/online", "r");
+ if (!onlnf)
+ return default_cpu_map();
+
+ sep = 0;
+ prev = -1;
+ for (;;) {
+ n = fscanf(onlnf, "%u%c", &cpu, &sep);
+ if (n <= 0)
+ break;
+ if (prev >= 0) {
+ assert(nr_cpus + cpu - prev - 1 < MAX_NR_CPUS);
+ while (++prev < cpu)
+ cpumap[nr_cpus++] = prev;
+ }
+ assert (nr_cpus < MAX_NR_CPUS);
+ cpumap[nr_cpus++] = cpu;
+ if (n == 2 && sep == '-')
+ prev = cpu;
+ else
+ prev = -1;
+ if (n == 1 || sep == '\n')
+ break;
+ }
+ fclose(onlnf);
+ if (nr_cpus > 0)
+ return nr_cpus;
+
+ return default_cpu_map();
+}
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
new file mode 100644
index 00000000000..86c78bb3309
--- /dev/null
+++ b/tools/perf/util/cpumap.h
@@ -0,0 +1,7 @@
+#ifndef __PERF_CPUMAP_H
+#define __PERF_CPUMAP_H
+
+extern int read_cpu_map(void);
+extern int cpumap[];
+
+#endif /* __PERF_CPUMAP_H */
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 50a7132887f..a33b94952e3 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -99,6 +99,15 @@ struct events_stats {
u64 lost;
};
+struct event_stat_id {
+ struct rb_node rb_node;
+ struct rb_root hists;
+ struct events_stats stats;
+ u64 config;
+ u64 event_stream;
+ u32 type;
+};
+
void event__print_totals(void);
struct perf_session;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index e8daf5ca6fd..2be33c7dbf0 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -12,12 +12,12 @@ struct callchain_param callchain_param = {
* histogram, sorted on item, collects counts
*/
-struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
+struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
struct addr_location *al,
struct symbol *sym_parent,
u64 count, bool *hit)
{
- struct rb_node **p = &self->hists.rb_node;
+ struct rb_node **p = &hists->rb_node;
struct rb_node *parent = NULL;
struct hist_entry *he;
struct hist_entry entry = {
@@ -53,7 +53,7 @@ struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
return NULL;
*he = entry;
rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, &self->hists);
+ rb_insert_color(&he->rb_node, hists);
*hit = false;
return he;
}
@@ -130,7 +130,7 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
rb_insert_color(&he->rb_node, root);
}
-void perf_session__collapse_resort(struct perf_session *self)
+void perf_session__collapse_resort(struct rb_root *hists)
{
struct rb_root tmp;
struct rb_node *next;
@@ -140,17 +140,17 @@ void perf_session__collapse_resort(struct perf_session *self)
return;
tmp = RB_ROOT;
- next = rb_first(&self->hists);
+ next = rb_first(hists);
while (next) {
n = rb_entry(next, struct hist_entry, rb_node);
next = rb_next(&n->rb_node);
- rb_erase(&n->rb_node, &self->hists);
+ rb_erase(&n->rb_node, hists);
collapse__insert_entry(&tmp, n);
}
- self->hists = tmp;
+ *hists = tmp;
}
/*
@@ -183,7 +183,7 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
rb_insert_color(&he->rb_node, root);
}
-void perf_session__output_resort(struct perf_session *self, u64 total_samples)
+void perf_session__output_resort(struct rb_root *hists, u64 total_samples)
{
struct rb_root tmp;
struct rb_node *next;
@@ -194,18 +194,18 @@ void perf_session__output_resort(struct perf_session *self, u64 total_samples)
total_samples * (callchain_param.min_percent / 100);
tmp = RB_ROOT;
- next = rb_first(&self->hists);
+ next = rb_first(hists);
while (next) {
n = rb_entry(next, struct hist_entry, rb_node);
next = rb_next(&n->rb_node);
- rb_erase(&n->rb_node, &self->hists);
+ rb_erase(&n->rb_node, hists);
perf_session__insert_output_hist_entry(&tmp, n,
min_callchain_hits);
}
- self->hists = tmp;
+ *hists = tmp;
}
static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
@@ -321,7 +321,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
new_depth_mask &= ~(1 << (depth - 1));
/*
- * But we keep the older depth mask for the line seperator
+ * But we keep the older depth mask for the line separator
* to keep the level link until we reach the last child
*/
ret += ipchain__fprintf_graph_line(fp, depth, depth_mask,
@@ -456,10 +456,10 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
}
static size_t hist_entry__fprintf(struct hist_entry *self,
- struct perf_session *session,
struct perf_session *pair_session,
bool show_displacement,
- long displacement, FILE *fp)
+ long displacement, FILE *fp,
+ u64 session_total)
{
struct sort_entry *se;
u64 count, total;
@@ -474,7 +474,7 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
total = pair_session->events_stats.total;
} else {
count = self->count;
- total = session->events_stats.total;
+ total = session_total;
}
if (total)
@@ -496,8 +496,8 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
if (total > 0)
old_percent = (count * 100.0) / total;
- if (session->events_stats.total > 0)
- new_percent = (self->count * 100.0) / session->events_stats.total;
+ if (session_total > 0)
+ new_percent = (self->count * 100.0) / session_total;
diff = new_percent - old_percent;
@@ -544,16 +544,17 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
left_margin -= thread__comm_len(self->thread);
}
- hist_entry_callchain__fprintf(fp, self, session->events_stats.total,
+ hist_entry_callchain__fprintf(fp, self, session_total,
left_margin);
}
return ret;
}
-size_t perf_session__fprintf_hists(struct perf_session *self,
+size_t perf_session__fprintf_hists(struct rb_root *hists,
struct perf_session *pair,
- bool show_displacement, FILE *fp)
+ bool show_displacement, FILE *fp,
+ u64 session_total)
{
struct sort_entry *se;
struct rb_node *nd;
@@ -641,7 +642,7 @@ size_t perf_session__fprintf_hists(struct perf_session *self,
fprintf(fp, "\n#\n");
print_entries:
- for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
+ for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
if (show_displacement) {
@@ -652,8 +653,13 @@ print_entries:
displacement = 0;
++position;
}
- ret += hist_entry__fprintf(h, self, pair, show_displacement,
- displacement, fp);
+ ret += hist_entry__fprintf(h, pair, show_displacement,
+ displacement, fp, session_total);
+ if (h->map == NULL && verbose > 1) {
+ __map_groups__fprintf_maps(&h->thread->mg,
+ MAP__FUNCTION, fp);
+ fprintf(fp, "%.10s end\n", graph_dotted_line);
+ }
}
free(rem_sq_bracket);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index e5f99b24048..16f360cce5b 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -10,8 +10,9 @@ struct perf_session;
struct hist_entry;
struct addr_location;
struct symbol;
+struct rb_root;
-struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
+struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
struct addr_location *al,
struct symbol *parent,
u64 count, bool *hit);
@@ -19,9 +20,10 @@ extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
void hist_entry__free(struct hist_entry *);
-void perf_session__output_resort(struct perf_session *self, u64 total_samples);
-void perf_session__collapse_resort(struct perf_session *self);
-size_t perf_session__fprintf_hists(struct perf_session *self,
+void perf_session__output_resort(struct rb_root *hists, u64 total_samples);
+void perf_session__collapse_resort(struct rb_root *hists);
+size_t perf_session__fprintf_hists(struct rb_root *hists,
struct perf_session *pair,
- bool show_displacement, FILE *fp);
+ bool show_displacement, FILE *fp,
+ u64 session_total);
#endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 8f056884969..7c004b6ef24 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -119,14 +119,14 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
char c, nc = 0;
/*
* <Syntax>
- * perf probe [EVENT=]SRC:LN
- * perf probe [EVENT=]FUNC[+OFFS|%return][@SRC]
+ * perf probe [EVENT=]SRC[:LN|;PTN]
+ * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
*
* TODO:Group name support
*/
- ptr = strchr(arg, '=');
- if (ptr) { /* Event name */
+ ptr = strpbrk(arg, ";=@+%");
+ if (ptr && *ptr == '=') { /* Event name */
*ptr = '\0';
tmp = ptr + 1;
ptr = strchr(arg, ':');
@@ -139,7 +139,7 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
arg = tmp;
}
- ptr = strpbrk(arg, ":+@%");
+ ptr = strpbrk(arg, ";:+@%");
if (ptr) {
nc = *ptr;
*ptr++ = '\0';
@@ -156,7 +156,11 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
while (ptr) {
arg = ptr;
c = nc;
- ptr = strpbrk(arg, ":+@%");
+ if (c == ';') { /* Lazy pattern must be the last part */
+ pp->lazy_line = strdup(arg);
+ break;
+ }
+ ptr = strpbrk(arg, ";:+@%");
if (ptr) {
nc = *ptr;
*ptr++ = '\0';
@@ -165,13 +169,13 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
case ':': /* Line number */
pp->line = strtoul(arg, &tmp, 0);
if (*tmp != '\0')
- semantic_error("There is non-digit charactor"
- " in line number.");
+ semantic_error("There is non-digit char"
+ " in line number.");
break;
case '+': /* Byte offset from a symbol */
pp->offset = strtoul(arg, &tmp, 0);
if (*tmp != '\0')
- semantic_error("There is non-digit charactor"
+ semantic_error("There is non-digit character"
" in offset.");
break;
case '@': /* File name */
@@ -179,9 +183,6 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
semantic_error("SRC@SRC is not allowed.");
pp->file = strdup(arg);
DIE_IF(pp->file == NULL);
- if (ptr)
- semantic_error("@SRC must be the last "
- "option.");
break;
case '%': /* Probe places */
if (strcmp(arg, "return") == 0) {
@@ -196,11 +197,18 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
}
/* Exclusion check */
+ if (pp->lazy_line && pp->line)
+ semantic_error("Lazy pattern can't be used with line number.");
+
+ if (pp->lazy_line && pp->offset)
+ semantic_error("Lazy pattern can't be used with offset.");
+
if (pp->line && pp->offset)
semantic_error("Offset can't be used with line number.");
- if (!pp->line && pp->file && !pp->function)
- semantic_error("File always requires line number.");
+ if (!pp->line && !pp->lazy_line && pp->file && !pp->function)
+ semantic_error("File always requires line number or "
+ "lazy pattern.");
if (pp->offset && !pp->function)
semantic_error("Offset requires an entry function.");
@@ -208,11 +216,13 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
if (pp->retprobe && !pp->function)
semantic_error("Return probe requires an entry function.");
- if ((pp->offset || pp->line) && pp->retprobe)
- semantic_error("Offset/Line can't be used with return probe.");
+ if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe)
+ semantic_error("Offset/Line/Lazy pattern can't be used with "
+ "return probe.");
- pr_debug("symbol:%s file:%s line:%d offset:%d, return:%d\n",
- pp->function, pp->file, pp->line, pp->offset, pp->retprobe);
+ pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n",
+ pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
+ pp->lazy_line);
}
/* Parse perf-probe event definition */
@@ -232,7 +242,7 @@ void parse_perf_probe_event(const char *str, struct probe_point *pp,
/* Parse probe point */
parse_perf_probe_probepoint(argv[0], pp);
- if (pp->file || pp->line)
+ if (pp->file || pp->line || pp->lazy_line)
*need_dwarf = true;
/* Copy arguments and ensure return probe has no C argument */
@@ -458,6 +468,8 @@ static void clear_probe_point(struct probe_point *pp)
free(pp->function);
if (pp->file)
free(pp->file);
+ if (pp->lazy_line)
+ free(pp->lazy_line);
for (i = 0; i < pp->nr_args; i++)
free(pp->args[i]);
if (pp->args)
@@ -496,8 +508,8 @@ void show_perf_probe_events(void)
struct str_node *ent;
setup_pager();
-
memset(&pp, 0, sizeof(pp));
+
fd = open_kprobe_events(O_RDONLY, 0);
rawlist = get_trace_kprobe_event_rawlist(fd);
close(fd);
@@ -719,6 +731,7 @@ void del_trace_kprobe_events(struct strlist *dellist)
}
#define LINEBUF_SIZE 256
+#define NR_ADDITIONAL_LINES 2
static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
{
@@ -779,5 +792,11 @@ void show_line_range(struct line_range *lr)
show_one_line(fp, (l++) - lr->offset, false, false);
show_one_line(fp, (l++) - lr->offset, false, true);
}
+
+ if (lr->end == INT_MAX)
+ lr->end = l + NR_ADDITIONAL_LINES;
+ while (l < lr->end && !feof(fp))
+ show_one_line(fp, (l++) - lr->offset, false, false);
+
fclose(fp);
}
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 1b2124d12f6..c171a243d05 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -32,21 +32,13 @@
#include <stdarg.h>
#include <ctype.h>
+#include "string.h"
#include "event.h"
#include "debug.h"
#include "util.h"
#include "probe-finder.h"
-/* Dwarf_Die Linkage to parent Die */
-struct die_link {
- struct die_link *parent; /* Parent die */
- Dwarf_Die die; /* Current die */
-};
-
-static Dwarf_Debug __dw_debug;
-static Dwarf_Error __dw_error;
-
/*
* Generic dwarf analysis helpers
*/
@@ -113,281 +105,190 @@ static int strtailcmp(const char *s1, const char *s2)
return 0;
}
-/* Find the fileno of the target file. */
-static Dwarf_Unsigned cu_find_fileno(Dwarf_Die cu_die, const char *fname)
-{
- Dwarf_Signed cnt, i;
- Dwarf_Unsigned found = 0;
- char **srcs;
- int ret;
+/* Line number list operations */
- if (!fname)
- return 0;
+/* Add a line to line number list */
+static void line_list__add_line(struct list_head *head, unsigned int line)
+{
+ struct line_node *ln;
+ struct list_head *p;
- ret = dwarf_srcfiles(cu_die, &srcs, &cnt, &__dw_error);
- if (ret == DW_DLV_OK) {
- for (i = 0; i < cnt && !found; i++) {
- if (strtailcmp(srcs[i], fname) == 0)
- found = i + 1;
- dwarf_dealloc(__dw_debug, srcs[i], DW_DLA_STRING);
- }
- for (; i < cnt; i++)
- dwarf_dealloc(__dw_debug, srcs[i], DW_DLA_STRING);
- dwarf_dealloc(__dw_debug, srcs, DW_DLA_LIST);
+ /* Reverse search, because new line will be the last one */
+ list_for_each_entry_reverse(ln, head, list) {
+ if (ln->line < line) {
+ p = &ln->list;
+ goto found;
+ } else if (ln->line == line) /* Already exist */
+ return ;
}
- if (found)
- pr_debug("found fno: %d\n", (int)found);
- return found;
+ /* List is empty, or the smallest entry */
+ p = head;
+found:
+ pr_debug("line list: add a line %u\n", line);
+ ln = zalloc(sizeof(struct line_node));
+ DIE_IF(ln == NULL);
+ ln->line = line;
+ INIT_LIST_HEAD(&ln->list);
+ list_add(&ln->list, p);
}
-static int cu_get_filename(Dwarf_Die cu_die, Dwarf_Unsigned fno, char **buf)
+/* Check if the line in line number list */
+static int line_list__has_line(struct list_head *head, unsigned int line)
{
- Dwarf_Signed cnt, i;
- char **srcs;
- int ret = 0;
-
- if (!buf || !fno)
- return -EINVAL;
-
- ret = dwarf_srcfiles(cu_die, &srcs, &cnt, &__dw_error);
- if (ret == DW_DLV_OK) {
- if ((Dwarf_Unsigned)cnt > fno - 1) {
- *buf = strdup(srcs[fno - 1]);
- ret = 0;
- pr_debug("found filename: %s\n", *buf);
- } else
- ret = -ENOENT;
- for (i = 0; i < cnt; i++)
- dwarf_dealloc(__dw_debug, srcs[i], DW_DLA_STRING);
- dwarf_dealloc(__dw_debug, srcs, DW_DLA_LIST);
- } else
- ret = -EINVAL;
- return ret;
+ struct line_node *ln;
+
+ /* Reverse search, because new line will be the last one */
+ list_for_each_entry(ln, head, list)
+ if (ln->line == line)
+ return 1;
+
+ return 0;
}
-/* Compare diename and tname */
-static int die_compare_name(Dwarf_Die dw_die, const char *tname)
+/* Init line number list */
+static void line_list__init(struct list_head *head)
{
- char *name;
- int ret;
- ret = dwarf_diename(dw_die, &name, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_OK) {
- ret = strcmp(tname, name);
- dwarf_dealloc(__dw_debug, name, DW_DLA_STRING);
- } else
- ret = -1;
- return ret;
+ INIT_LIST_HEAD(head);
}
-/* Check the address is in the subprogram(function). */
-static int die_within_subprogram(Dwarf_Die sp_die, Dwarf_Addr addr,
- Dwarf_Signed *offs)
+/* Free line number list */
+static void line_list__free(struct list_head *head)
{
- Dwarf_Addr lopc, hipc;
- int ret;
-
- /* TODO: check ranges */
- ret = dwarf_lowpc(sp_die, &lopc, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_NO_ENTRY)
- return 0;
- ret = dwarf_highpc(sp_die, &hipc, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- if (lopc <= addr && addr < hipc) {
- *offs = addr - lopc;
- return 1;
- } else
- return 0;
+ struct line_node *ln;
+ while (!list_empty(head)) {
+ ln = list_first_entry(head, struct line_node, list);
+ list_del(&ln->list);
+ free(ln);
+ }
}
-/* Check the die is inlined function */
-static Dwarf_Bool die_inlined_subprogram(Dwarf_Die dw_die)
+/* Dwarf wrappers */
+
+/* Find the realpath of the target file. */
+static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
{
- /* TODO: check strictly */
- Dwarf_Bool inl;
+ Dwarf_Files *files;
+ size_t nfiles, i;
+ const char *src = NULL;
int ret;
- ret = dwarf_hasattr(dw_die, DW_AT_inline, &inl, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- return inl;
-}
+ if (!fname)
+ return NULL;
-/* Get the offset of abstruct_origin */
-static Dwarf_Off die_get_abstract_origin(Dwarf_Die dw_die)
-{
- Dwarf_Attribute attr;
- Dwarf_Off cu_offs;
- int ret;
+ ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
+ if (ret != 0)
+ return NULL;
- ret = dwarf_attr(dw_die, DW_AT_abstract_origin, &attr, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- ret = dwarf_formref(attr, &cu_offs, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
- return cu_offs;
+ for (i = 0; i < nfiles; i++) {
+ src = dwarf_filesrc(files, i, NULL, NULL);
+ if (strtailcmp(src, fname) == 0)
+ break;
+ }
+ return src;
}
-/* Get entry pc(or low pc, 1st entry of ranges) of the die */
-static Dwarf_Addr die_get_entrypc(Dwarf_Die dw_die)
+struct __addr_die_search_param {
+ Dwarf_Addr addr;
+ Dwarf_Die *die_mem;
+};
+
+static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
{
- Dwarf_Attribute attr;
- Dwarf_Addr addr;
- Dwarf_Off offs;
- Dwarf_Ranges *ranges;
- Dwarf_Signed cnt;
- int ret;
+ struct __addr_die_search_param *ad = data;
- /* Try to get entry pc */
- ret = dwarf_attr(dw_die, DW_AT_entry_pc, &attr, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_OK) {
- ret = dwarf_formaddr(attr, &addr, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
- return addr;
+ if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
+ dwarf_haspc(fn_die, ad->addr)) {
+ memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
+ return DWARF_CB_ABORT;
}
+ return DWARF_CB_OK;
+}
- /* Try to get low pc */
- ret = dwarf_lowpc(dw_die, &addr, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_OK)
- return addr;
-
- /* Try to get ranges */
- ret = dwarf_attr(dw_die, DW_AT_ranges, &attr, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- ret = dwarf_formref(attr, &offs, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- ret = dwarf_get_ranges(__dw_debug, offs, &ranges, &cnt, NULL,
- &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- addr = ranges[0].dwr_addr1;
- dwarf_ranges_dealloc(__dw_debug, ranges, cnt);
- return addr;
+/* Search a real subprogram including this line, */
+static Dwarf_Die *die_get_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
+ Dwarf_Die *die_mem)
+{
+ struct __addr_die_search_param ad;
+ ad.addr = addr;
+ ad.die_mem = die_mem;
+ /* dwarf_getscopes can't find subprogram. */
+ if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
+ return NULL;
+ else
+ return die_mem;
}
-/*
- * Search a Die from Die tree.
- * Note: cur_link->die should be deallocated in this function.
- */
-static int __search_die_tree(struct die_link *cur_link,
- int (*die_cb)(struct die_link *, void *),
- void *data)
+/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */
+static Dwarf_Die *die_get_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
+ Dwarf_Die *die_mem)
{
- Dwarf_Die new_die;
- struct die_link new_link;
+ Dwarf_Die child_die;
int ret;
- if (!die_cb)
- return 0;
-
- /* Check current die */
- while (!(ret = die_cb(cur_link, data))) {
- /* Check child die */
- ret = dwarf_child(cur_link->die, &new_die, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_OK) {
- new_link.parent = cur_link;
- new_link.die = new_die;
- ret = __search_die_tree(&new_link, die_cb, data);
- if (ret)
- break;
- }
+ ret = dwarf_child(sp_die, die_mem);
+ if (ret != 0)
+ return NULL;
- /* Move to next sibling */
- ret = dwarf_siblingof(__dw_debug, cur_link->die, &new_die,
- &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- dwarf_dealloc(__dw_debug, cur_link->die, DW_DLA_DIE);
- cur_link->die = new_die;
- if (ret == DW_DLV_NO_ENTRY)
- return 0;
- }
- dwarf_dealloc(__dw_debug, cur_link->die, DW_DLA_DIE);
- return ret;
-}
+ do {
+ if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
+ dwarf_haspc(die_mem, addr))
+ return die_mem;
-/* Search a die in its children's die tree */
-static int search_die_from_children(Dwarf_Die parent_die,
- int (*die_cb)(struct die_link *, void *),
- void *data)
-{
- struct die_link new_link;
- int ret;
+ if (die_get_inlinefunc(die_mem, addr, &child_die)) {
+ memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
+ return die_mem;
+ }
+ } while (dwarf_siblingof(die_mem, die_mem) == 0);
- new_link.parent = NULL;
- ret = dwarf_child(parent_die, &new_link.die, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_OK)
- return __search_die_tree(&new_link, die_cb, data);
- else
- return 0;
+ return NULL;
}
-/* Find a locdesc corresponding to the address */
-static int attr_get_locdesc(Dwarf_Attribute attr, Dwarf_Locdesc *desc,
- Dwarf_Addr addr)
+/* Compare diename and tname */
+static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
{
- Dwarf_Signed lcnt;
- Dwarf_Locdesc **llbuf;
- int ret, i;
-
- ret = dwarf_loclist_n(attr, &llbuf, &lcnt, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- ret = DW_DLV_NO_ENTRY;
- for (i = 0; i < lcnt; ++i) {
- if (llbuf[i]->ld_lopc <= addr &&
- llbuf[i]->ld_hipc > addr) {
- memcpy(desc, llbuf[i], sizeof(Dwarf_Locdesc));
- desc->ld_s =
- malloc(sizeof(Dwarf_Loc) * llbuf[i]->ld_cents);
- DIE_IF(desc->ld_s == NULL);
- memcpy(desc->ld_s, llbuf[i]->ld_s,
- sizeof(Dwarf_Loc) * llbuf[i]->ld_cents);
- ret = DW_DLV_OK;
- break;
- }
- dwarf_dealloc(__dw_debug, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
- dwarf_dealloc(__dw_debug, llbuf[i], DW_DLA_LOCDESC);
- }
- /* Releasing loop */
- for (; i < lcnt; ++i) {
- dwarf_dealloc(__dw_debug, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
- dwarf_dealloc(__dw_debug, llbuf[i], DW_DLA_LOCDESC);
- }
- dwarf_dealloc(__dw_debug, llbuf, DW_DLA_LIST);
- return ret;
+ const char *name;
+ name = dwarf_diename(dw_die);
+ DIE_IF(name == NULL);
+ return strcmp(tname, name);
}
-/* Get decl_file attribute value (file number) */
-static Dwarf_Unsigned die_get_decl_file(Dwarf_Die sp_die)
+/* Get entry pc(or low pc, 1st entry of ranges) of the die */
+static Dwarf_Addr die_get_entrypc(Dwarf_Die *dw_die)
{
- Dwarf_Attribute attr;
- Dwarf_Unsigned fno;
+ Dwarf_Addr epc;
int ret;
- ret = dwarf_attr(sp_die, DW_AT_decl_file, &attr, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- dwarf_formudata(attr, &fno, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
- return fno;
+ ret = dwarf_entrypc(dw_die, &epc);
+ DIE_IF(ret == -1);
+ return epc;
}
-/* Get decl_line attribute value (line number) */
-static Dwarf_Unsigned die_get_decl_line(Dwarf_Die sp_die)
+/* Get a variable die */
+static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name,
+ Dwarf_Die *die_mem)
{
- Dwarf_Attribute attr;
- Dwarf_Unsigned lno;
+ Dwarf_Die child_die;
+ int tag;
int ret;
- ret = dwarf_attr(sp_die, DW_AT_decl_line, &attr, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- dwarf_formudata(attr, &lno, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
- return lno;
+ ret = dwarf_child(sp_die, die_mem);
+ if (ret != 0)
+ return NULL;
+
+ do {
+ tag = dwarf_tag(die_mem);
+ if ((tag == DW_TAG_formal_parameter ||
+ tag == DW_TAG_variable) &&
+ (die_compare_name(die_mem, name) == 0))
+ return die_mem;
+
+ if (die_find_variable(die_mem, name, &child_die)) {
+ memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
+ return die_mem;
+ }
+ } while (dwarf_siblingof(die_mem, die_mem) == 0);
+
+ return NULL;
}
/*
@@ -395,47 +296,45 @@ static Dwarf_Unsigned die_get_decl_line(Dwarf_Die sp_die)
*/
/* Show a location */
-static void show_location(Dwarf_Loc *loc, struct probe_finder *pf)
+static void show_location(Dwarf_Op *op, struct probe_finder *pf)
{
- Dwarf_Small op;
- Dwarf_Unsigned regn;
- Dwarf_Signed offs;
+ unsigned int regn;
+ Dwarf_Word offs = 0;
int deref = 0, ret;
const char *regs;
- op = loc->lr_atom;
-
+ /* TODO: support CFA */
/* If this is based on frame buffer, set the offset */
- if (op == DW_OP_fbreg) {
+ if (op->atom == DW_OP_fbreg) {
+ if (pf->fb_ops == NULL)
+ die("The attribute of frame base is not supported.\n");
deref = 1;
- offs = (Dwarf_Signed)loc->lr_number;
- op = pf->fbloc.ld_s[0].lr_atom;
- loc = &pf->fbloc.ld_s[0];
- } else
- offs = 0;
+ offs = op->number;
+ op = &pf->fb_ops[0];
+ }
- if (op >= DW_OP_breg0 && op <= DW_OP_breg31) {
- regn = op - DW_OP_breg0;
- offs += (Dwarf_Signed)loc->lr_number;
+ if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
+ regn = op->atom - DW_OP_breg0;
+ offs += op->number;
deref = 1;
- } else if (op >= DW_OP_reg0 && op <= DW_OP_reg31) {
- regn = op - DW_OP_reg0;
- } else if (op == DW_OP_bregx) {
- regn = loc->lr_number;
- offs += (Dwarf_Signed)loc->lr_number2;
+ } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) {
+ regn = op->atom - DW_OP_reg0;
+ } else if (op->atom == DW_OP_bregx) {
+ regn = op->number;
+ offs += op->number2;
deref = 1;
- } else if (op == DW_OP_regx) {
- regn = loc->lr_number;
+ } else if (op->atom == DW_OP_regx) {
+ regn = op->number;
} else
- die("Dwarf_OP %d is not supported.", op);
+ die("DW_OP %d is not supported.", op->atom);
regs = get_arch_regstr(regn);
if (!regs)
- die("%lld exceeds max register number.", regn);
+ die("%u exceeds max register number.", regn);
if (deref)
- ret = snprintf(pf->buf, pf->len,
- " %s=%+lld(%s)", pf->var, offs, regs);
+ ret = snprintf(pf->buf, pf->len, " %s=%+jd(%s)",
+ pf->var, (intmax_t)offs, regs);
else
ret = snprintf(pf->buf, pf->len, " %s=%s", pf->var, regs);
DIE_IF(ret < 0);
@@ -443,52 +342,36 @@ static void show_location(Dwarf_Loc *loc, struct probe_finder *pf)
}
/* Show a variables in kprobe event format */
-static void show_variable(Dwarf_Die vr_die, struct probe_finder *pf)
+static void show_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
{
Dwarf_Attribute attr;
- Dwarf_Locdesc ld;
+ Dwarf_Op *expr;
+ size_t nexpr;
int ret;
- ret = dwarf_attr(vr_die, DW_AT_location, &attr, &__dw_error);
- if (ret != DW_DLV_OK)
+ if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
goto error;
- ret = attr_get_locdesc(attr, &ld, (pf->addr - pf->cu_base));
- if (ret != DW_DLV_OK)
+ /* TODO: handle more than 1 exprs */
+ ret = dwarf_getlocation_addr(&attr, pf->addr, &expr, &nexpr, 1);
+ if (ret <= 0 || nexpr == 0)
goto error;
- /* TODO? */
- DIE_IF(ld.ld_cents != 1);
- show_location(&ld.ld_s[0], pf);
- free(ld.ld_s);
- dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+
+ show_location(expr, pf);
+ /* *expr will be cached in libdw. Don't free it. */
return ;
error:
+ /* TODO: Support const_value */
die("Failed to find the location of %s at this address.\n"
" Perhaps, it has been optimized out.", pf->var);
}
-static int variable_callback(struct die_link *dlink, void *data)
-{
- struct probe_finder *pf = (struct probe_finder *)data;
- Dwarf_Half tag;
- int ret;
-
- ret = dwarf_tag(dlink->die, &tag, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if ((tag == DW_TAG_formal_parameter ||
- tag == DW_TAG_variable) &&
- (die_compare_name(dlink->die, pf->var) == 0)) {
- show_variable(dlink->die, pf);
- return 1;
- }
- /* TODO: Support struct members and arrays */
- return 0;
-}
-
/* Find a variable in a subprogram die */
-static void find_variable(Dwarf_Die sp_die, struct probe_finder *pf)
+static void find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
{
int ret;
+ Dwarf_Die vr_die;
+ /* TODO: Support struct members and arrays */
if (!is_c_varname(pf->var)) {
/* Output raw parameters */
ret = snprintf(pf->buf, pf->len, " %s", pf->var);
@@ -499,58 +382,51 @@ static void find_variable(Dwarf_Die sp_die, struct probe_finder *pf)
pr_debug("Searching '%s' variable in context.\n", pf->var);
/* Search child die for local variables and parameters. */
- ret = search_die_from_children(sp_die, variable_callback, pf);
- if (!ret)
+ if (!die_find_variable(sp_die, pf->var, &vr_die))
die("Failed to find '%s' in this function.", pf->var);
-}
-
-/* Get a frame base on the address */
-static void get_current_frame_base(Dwarf_Die sp_die, struct probe_finder *pf)
-{
- Dwarf_Attribute attr;
- int ret;
-
- ret = dwarf_attr(sp_die, DW_AT_frame_base, &attr, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- ret = attr_get_locdesc(attr, &pf->fbloc, (pf->addr - pf->cu_base));
- DIE_IF(ret != DW_DLV_OK);
- dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
-}
-static void free_current_frame_base(struct probe_finder *pf)
-{
- free(pf->fbloc.ld_s);
- memset(&pf->fbloc, 0, sizeof(Dwarf_Locdesc));
+ show_variable(&vr_die, pf);
}
/* Show a probe point to output buffer */
-static void show_probepoint(Dwarf_Die sp_die, Dwarf_Signed offs,
- struct probe_finder *pf)
+static void show_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
{
struct probe_point *pp = pf->pp;
- char *name;
+ Dwarf_Addr eaddr;
+ Dwarf_Die die_mem;
+ const char *name;
char tmp[MAX_PROBE_BUFFER];
int ret, i, len;
+ Dwarf_Attribute fb_attr;
+ size_t nops;
+
+ /* If no real subprogram, find a real one */
+ if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
+ sp_die = die_get_real_subprogram(&pf->cu_die,
+ pf->addr, &die_mem);
+ if (!sp_die)
+ die("Probe point is not found in subprograms.");
+ }
/* Output name of probe point */
- ret = dwarf_diename(sp_die, &name, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_OK) {
- ret = snprintf(tmp, MAX_PROBE_BUFFER, "%s+%u", name,
- (unsigned int)offs);
+ name = dwarf_diename(sp_die);
+ if (name) {
+ dwarf_entrypc(sp_die, &eaddr);
+ ret = snprintf(tmp, MAX_PROBE_BUFFER, "%s+%lu", name,
+ (unsigned long)(pf->addr - eaddr));
/* Copy the function name if possible */
if (!pp->function) {
pp->function = strdup(name);
- pp->offset = offs;
+ pp->offset = (size_t)(pf->addr - eaddr);
}
- dwarf_dealloc(__dw_debug, name, DW_DLA_STRING);
} else {
/* This function has no name. */
- ret = snprintf(tmp, MAX_PROBE_BUFFER, "0x%llx", pf->addr);
+ ret = snprintf(tmp, MAX_PROBE_BUFFER, "0x%jx",
+ (uintmax_t)pf->addr);
if (!pp->function) {
/* TODO: Use _stext */
pp->function = strdup("");
- pp->offset = (int)pf->addr;
+ pp->offset = (size_t)pf->addr;
}
}
DIE_IF(ret < 0);
@@ -558,8 +434,14 @@ static void show_probepoint(Dwarf_Die sp_die, Dwarf_Signed offs,
len = ret;
pr_debug("Probe point found: %s\n", tmp);
+ /* Get the frame base attribute/ops */
+ dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
+ ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
+ if (ret <= 0 || nops == 0)
+ pf->fb_ops = NULL;
+
/* Find each argument */
- get_current_frame_base(sp_die, pf);
+ /* TODO: use dwarf_cfi_addrframe */
for (i = 0; i < pp->nr_args; i++) {
pf->var = pp->args[i];
pf->buf = &tmp[len];
@@ -567,289 +449,325 @@ static void show_probepoint(Dwarf_Die sp_die, Dwarf_Signed offs,
find_variable(sp_die, pf);
len += strlen(pf->buf);
}
- free_current_frame_base(pf);
+
+ /* *pf->fb_ops will be cached in libdw. Don't free it. */
+ pf->fb_ops = NULL;
+
+ if (pp->found == MAX_PROBES)
+ die("Too many( > %d) probe point found.\n", MAX_PROBES);
pp->probes[pp->found] = strdup(tmp);
pp->found++;
}
-static int probeaddr_callback(struct die_link *dlink, void *data)
+/* Find probe point from its line number */
+static void find_probe_point_by_line(struct probe_finder *pf)
{
- struct probe_finder *pf = (struct probe_finder *)data;
- Dwarf_Half tag;
- Dwarf_Signed offs;
+ Dwarf_Lines *lines;
+ Dwarf_Line *line;
+ size_t nlines, i;
+ Dwarf_Addr addr;
+ int lineno;
int ret;
- ret = dwarf_tag(dlink->die, &tag, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- /* Check the address is in this subprogram */
- if (tag == DW_TAG_subprogram &&
- die_within_subprogram(dlink->die, pf->addr, &offs)) {
- show_probepoint(dlink->die, offs, pf);
- return 1;
+ ret = dwarf_getsrclines(&pf->cu_die, &lines, &nlines);
+ DIE_IF(ret != 0);
+
+ for (i = 0; i < nlines; i++) {
+ line = dwarf_onesrcline(lines, i);
+ dwarf_lineno(line, &lineno);
+ if (lineno != pf->lno)
+ continue;
+
+ /* TODO: Get fileno from line, but how? */
+ if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
+ continue;
+
+ ret = dwarf_lineaddr(line, &addr);
+ DIE_IF(ret != 0);
+ pr_debug("Probe line found: line[%d]:%d addr:0x%jx\n",
+ (int)i, lineno, (uintmax_t)addr);
+ pf->addr = addr;
+
+ show_probe_point(NULL, pf);
+ /* Continuing, because target line might be inlined. */
}
- return 0;
}
-/* Find probe point from its line number */
-static void find_probe_point_by_line(struct probe_finder *pf)
+/* Find lines which match lazy pattern */
+static int find_lazy_match_lines(struct list_head *head,
+ const char *fname, const char *pat)
+{
+ char *fbuf, *p1, *p2;
+ int fd, line, nlines = 0;
+ struct stat st;
+
+ fd = open(fname, O_RDONLY);
+ if (fd < 0)
+ die("failed to open %s", fname);
+ DIE_IF(fstat(fd, &st) < 0);
+ fbuf = malloc(st.st_size + 2);
+ DIE_IF(fbuf == NULL);
+ DIE_IF(read(fd, fbuf, st.st_size) < 0);
+ close(fd);
+ fbuf[st.st_size] = '\n'; /* Dummy line */
+ fbuf[st.st_size + 1] = '\0';
+ p1 = fbuf;
+ line = 1;
+ while ((p2 = strchr(p1, '\n')) != NULL) {
+ *p2 = '\0';
+ if (strlazymatch(p1, pat)) {
+ line_list__add_line(head, line);
+ nlines++;
+ }
+ line++;
+ p1 = p2 + 1;
+ }
+ free(fbuf);
+ return nlines;
+}
+
+/* Find probe points from lazy pattern */
+static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
{
- Dwarf_Signed cnt, i, clm;
- Dwarf_Line *lines;
- Dwarf_Unsigned lineno = 0;
+ Dwarf_Lines *lines;
+ Dwarf_Line *line;
+ size_t nlines, i;
Dwarf_Addr addr;
- Dwarf_Unsigned fno;
+ Dwarf_Die die_mem;
+ int lineno;
int ret;
- ret = dwarf_srclines(pf->cu_die, &lines, &cnt, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
+ if (list_empty(&pf->lcache)) {
+ /* Matching lazy line pattern */
+ ret = find_lazy_match_lines(&pf->lcache, pf->fname,
+ pf->pp->lazy_line);
+ if (ret <= 0)
+ die("No matched lines found in %s.", pf->fname);
+ }
- for (i = 0; i < cnt; i++) {
- ret = dwarf_line_srcfileno(lines[i], &fno, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- if (fno != pf->fno)
+ ret = dwarf_getsrclines(&pf->cu_die, &lines, &nlines);
+ DIE_IF(ret != 0);
+ for (i = 0; i < nlines; i++) {
+ line = dwarf_onesrcline(lines, i);
+
+ dwarf_lineno(line, &lineno);
+ if (!line_list__has_line(&pf->lcache, lineno))
continue;
- ret = dwarf_lineno(lines[i], &lineno, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- if (lineno != pf->lno)
+ /* TODO: Get fileno from line, but how? */
+ if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
continue;
- ret = dwarf_lineoff(lines[i], &clm, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
+ ret = dwarf_lineaddr(line, &addr);
+ DIE_IF(ret != 0);
+ if (sp_die) {
+ /* Address filtering 1: does sp_die include addr? */
+ if (!dwarf_haspc(sp_die, addr))
+ continue;
+ /* Address filtering 2: No child include addr? */
+ if (die_get_inlinefunc(sp_die, addr, &die_mem))
+ continue;
+ }
- ret = dwarf_lineaddr(lines[i], &addr, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- pr_debug("Probe line found: line[%d]:%u,%d addr:0x%llx\n",
- (int)i, (unsigned)lineno, (int)clm, addr);
+ pr_debug("Probe line found: line[%d]:%d addr:0x%llx\n",
+ (int)i, lineno, (unsigned long long)addr);
pf->addr = addr;
- /* Search a real subprogram including this line, */
- ret = search_die_from_children(pf->cu_die,
- probeaddr_callback, pf);
- if (ret == 0)
- die("Probe point is not found in subprograms.");
+
+ show_probe_point(sp_die, pf);
/* Continuing, because target line might be inlined. */
}
- dwarf_srclines_dealloc(__dw_debug, lines, cnt);
+ /* TODO: deallocate lines, but how? */
+}
+
+static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
+{
+ struct probe_finder *pf = (struct probe_finder *)data;
+ struct probe_point *pp = pf->pp;
+
+ if (pp->lazy_line)
+ find_probe_point_lazy(in_die, pf);
+ else {
+ /* Get probe address */
+ pf->addr = die_get_entrypc(in_die);
+ pf->addr += pp->offset;
+ pr_debug("found inline addr: 0x%jx\n",
+ (uintmax_t)pf->addr);
+
+ show_probe_point(in_die, pf);
+ }
+
+ return DWARF_CB_OK;
}
/* Search function from function name */
-static int probefunc_callback(struct die_link *dlink, void *data)
+static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
{
struct probe_finder *pf = (struct probe_finder *)data;
struct probe_point *pp = pf->pp;
- struct die_link *lk;
- Dwarf_Signed offs;
- Dwarf_Half tag;
- int ret;
- ret = dwarf_tag(dlink->die, &tag, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (tag == DW_TAG_subprogram) {
- if (die_compare_name(dlink->die, pp->function) == 0) {
- if (pp->line) { /* Function relative line */
- pf->fno = die_get_decl_file(dlink->die);
- pf->lno = die_get_decl_line(dlink->die)
- + pp->line;
- find_probe_point_by_line(pf);
- return 1;
- }
- if (die_inlined_subprogram(dlink->die)) {
- /* Inlined function, save it. */
- ret = dwarf_die_CU_offset(dlink->die,
- &pf->inl_offs,
- &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- pr_debug("inline definition offset %lld\n",
- pf->inl_offs);
- return 0; /* Continue to search */
- }
- /* Get probe address */
- pf->addr = die_get_entrypc(dlink->die);
+ /* Check tag and diename */
+ if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
+ die_compare_name(sp_die, pp->function) != 0)
+ return 0;
+
+ pf->fname = dwarf_decl_file(sp_die);
+ if (pp->line) { /* Function relative line */
+ dwarf_decl_line(sp_die, &pf->lno);
+ pf->lno += pp->line;
+ find_probe_point_by_line(pf);
+ } else if (!dwarf_func_inline(sp_die)) {
+ /* Real function */
+ if (pp->lazy_line)
+ find_probe_point_lazy(sp_die, pf);
+ else {
+ pf->addr = die_get_entrypc(sp_die);
pf->addr += pp->offset;
/* TODO: Check the address in this function */
- show_probepoint(dlink->die, pp->offset, pf);
- return 1; /* Exit; no same symbol in this CU. */
+ show_probe_point(sp_die, pf);
}
- } else if (tag == DW_TAG_inlined_subroutine && pf->inl_offs) {
- if (die_get_abstract_origin(dlink->die) == pf->inl_offs) {
- /* Get probe address */
- pf->addr = die_get_entrypc(dlink->die);
- pf->addr += pp->offset;
- pr_debug("found inline addr: 0x%llx\n", pf->addr);
- /* Inlined function. Get a real subprogram */
- for (lk = dlink->parent; lk != NULL; lk = lk->parent) {
- tag = 0;
- dwarf_tag(lk->die, &tag, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (tag == DW_TAG_subprogram &&
- !die_inlined_subprogram(lk->die))
- goto found;
- }
- die("Failed to find real subprogram.");
-found:
- /* Get offset from subprogram */
- ret = die_within_subprogram(lk->die, pf->addr, &offs);
- DIE_IF(!ret);
- show_probepoint(lk->die, offs, pf);
- /* Continue to search */
- }
- }
- return 0;
+ } else
+ /* Inlined function: search instances */
+ dwarf_func_inline_instances(sp_die, probe_point_inline_cb, pf);
+
+ return 1; /* Exit; no same symbol in this CU. */
}
static void find_probe_point_by_func(struct probe_finder *pf)
{
- search_die_from_children(pf->cu_die, probefunc_callback, pf);
+ dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, pf, 0);
}
/* Find a probe point */
-int find_probepoint(int fd, struct probe_point *pp)
+int find_probe_point(int fd, struct probe_point *pp)
{
- Dwarf_Half addr_size = 0;
- Dwarf_Unsigned next_cuh = 0;
- int cu_number = 0, ret;
struct probe_finder pf = {.pp = pp};
+ Dwarf_Off off, noff;
+ size_t cuhl;
+ Dwarf_Die *diep;
+ Dwarf *dbg;
- ret = dwarf_init(fd, DW_DLC_READ, 0, 0, &__dw_debug, &__dw_error);
- if (ret != DW_DLV_OK)
+ dbg = dwarf_begin(fd, DWARF_C_READ);
+ if (!dbg)
return -ENOENT;
pp->found = 0;
- while (++cu_number) {
- /* Search CU (Compilation Unit) */
- ret = dwarf_next_cu_header(__dw_debug, NULL, NULL, NULL,
- &addr_size, &next_cuh, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_NO_ENTRY)
- break;
-
+ off = 0;
+ line_list__init(&pf.lcache);
+ /* Loop on CUs (Compilation Unit) */
+ while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
/* Get the DIE(Debugging Information Entry) of this CU */
- ret = dwarf_siblingof(__dw_debug, 0, &pf.cu_die, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
+ diep = dwarf_offdie(dbg, off + cuhl, &pf.cu_die);
+ if (!diep)
+ continue;
/* Check if target file is included. */
if (pp->file)
- pf.fno = cu_find_fileno(pf.cu_die, pp->file);
-
- if (!pp->file || pf.fno) {
- /* Save CU base address (for frame_base) */
- ret = dwarf_lowpc(pf.cu_die, &pf.cu_base, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_NO_ENTRY)
- pf.cu_base = 0;
+ pf.fname = cu_find_realpath(&pf.cu_die, pp->file);
+ else
+ pf.fname = NULL;
+
+ if (!pp->file || pf.fname) {
if (pp->function)
find_probe_point_by_func(&pf);
+ else if (pp->lazy_line)
+ find_probe_point_lazy(NULL, &pf);
else {
pf.lno = pp->line;
find_probe_point_by_line(&pf);
}
}
- dwarf_dealloc(__dw_debug, pf.cu_die, DW_DLA_DIE);
+ off = noff;
}
- ret = dwarf_finish(__dw_debug, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
+ line_list__free(&pf.lcache);
+ dwarf_end(dbg);
return pp->found;
}
-
-static void line_range_add_line(struct line_range *lr, unsigned int line)
-{
- struct line_node *ln;
- struct list_head *p;
-
- /* Reverse search, because new line will be the last one */
- list_for_each_entry_reverse(ln, &lr->line_list, list) {
- if (ln->line < line) {
- p = &ln->list;
- goto found;
- } else if (ln->line == line) /* Already exist */
- return ;
- }
- /* List is empty, or the smallest entry */
- p = &lr->line_list;
-found:
- pr_debug("Debug: add a line %u\n", line);
- ln = zalloc(sizeof(struct line_node));
- DIE_IF(ln == NULL);
- ln->line = line;
- INIT_LIST_HEAD(&ln->list);
- list_add(&ln->list, p);
-}
-
/* Find line range from its line number */
-static void find_line_range_by_line(struct line_finder *lf)
+static void find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
{
- Dwarf_Signed cnt, i;
- Dwarf_Line *lines;
- Dwarf_Unsigned lineno = 0;
- Dwarf_Unsigned fno;
+ Dwarf_Lines *lines;
+ Dwarf_Line *line;
+ size_t nlines, i;
Dwarf_Addr addr;
+ int lineno;
int ret;
+ const char *src;
+ Dwarf_Die die_mem;
- ret = dwarf_srclines(lf->cu_die, &lines, &cnt, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
+ line_list__init(&lf->lr->line_list);
+ ret = dwarf_getsrclines(&lf->cu_die, &lines, &nlines);
+ DIE_IF(ret != 0);
- for (i = 0; i < cnt; i++) {
- ret = dwarf_line_srcfileno(lines[i], &fno, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- if (fno != lf->fno)
- continue;
-
- ret = dwarf_lineno(lines[i], &lineno, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
+ for (i = 0; i < nlines; i++) {
+ line = dwarf_onesrcline(lines, i);
+ ret = dwarf_lineno(line, &lineno);
+ DIE_IF(ret != 0);
if (lf->lno_s > lineno || lf->lno_e < lineno)
continue;
- /* Filter line in the function address range */
- if (lf->addr_s && lf->addr_e) {
- ret = dwarf_lineaddr(lines[i], &addr, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
- if (lf->addr_s > addr || lf->addr_e <= addr)
+ if (sp_die) {
+ /* Address filtering 1: does sp_die include addr? */
+ ret = dwarf_lineaddr(line, &addr);
+ DIE_IF(ret != 0);
+ if (!dwarf_haspc(sp_die, addr))
+ continue;
+
+ /* Address filtering 2: No child include addr? */
+ if (die_get_inlinefunc(sp_die, addr, &die_mem))
continue;
}
- line_range_add_line(lf->lr, (unsigned int)lineno);
+
+ /* TODO: Get fileno from line, but how? */
+ src = dwarf_linesrc(line, NULL, NULL);
+ if (strtailcmp(src, lf->fname) != 0)
+ continue;
+
+ /* Copy real path */
+ if (!lf->lr->path)
+ lf->lr->path = strdup(src);
+ line_list__add_line(&lf->lr->line_list, (unsigned int)lineno);
}
- dwarf_srclines_dealloc(__dw_debug, lines, cnt);
+ /* Update status */
if (!list_empty(&lf->lr->line_list))
lf->found = 1;
+ else {
+ free(lf->lr->path);
+ lf->lr->path = NULL;
+ }
+}
+
+static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
+{
+ find_line_range_by_line(in_die, (struct line_finder *)data);
+ return DWARF_CB_ABORT; /* No need to find other instances */
}
/* Search function from function name */
-static int linefunc_callback(struct die_link *dlink, void *data)
+static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
{
struct line_finder *lf = (struct line_finder *)data;
struct line_range *lr = lf->lr;
- Dwarf_Half tag;
- int ret;
- ret = dwarf_tag(dlink->die, &tag, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (tag == DW_TAG_subprogram &&
- die_compare_name(dlink->die, lr->function) == 0) {
- /* Get the address range of this function */
- ret = dwarf_highpc(dlink->die, &lf->addr_e, &__dw_error);
- if (ret == DW_DLV_OK)
- ret = dwarf_lowpc(dlink->die, &lf->addr_s, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_NO_ENTRY) {
- lf->addr_s = 0;
- lf->addr_e = 0;
- }
-
- lf->fno = die_get_decl_file(dlink->die);
- lr->offset = die_get_decl_line(dlink->die);;
+ if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
+ die_compare_name(sp_die, lr->function) == 0) {
+ lf->fname = dwarf_decl_file(sp_die);
+ dwarf_decl_line(sp_die, &lr->offset);
+ pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
lf->lno_s = lr->offset + lr->start;
if (!lr->end)
- lf->lno_e = (Dwarf_Unsigned)-1;
+ lf->lno_e = INT_MAX;
else
lf->lno_e = lr->offset + lr->end;
lr->start = lf->lno_s;
lr->end = lf->lno_e;
- find_line_range_by_line(lf);
- /* If we find a target function, this should be end. */
- lf->found = 1;
+ if (dwarf_func_inline(sp_die))
+ dwarf_func_inline_instances(sp_die,
+ line_range_inline_cb, lf);
+ else
+ find_line_range_by_line(sp_die, lf);
return 1;
}
return 0;
@@ -857,55 +775,55 @@ static int linefunc_callback(struct die_link *dlink, void *data)
static void find_line_range_by_func(struct line_finder *lf)
{
- search_die_from_children(lf->cu_die, linefunc_callback, lf);
+ dwarf_getfuncs(&lf->cu_die, line_range_search_cb, lf, 0);
}
int find_line_range(int fd, struct line_range *lr)
{
- Dwarf_Half addr_size = 0;
- Dwarf_Unsigned next_cuh = 0;
+ struct line_finder lf = {.lr = lr, .found = 0};
int ret;
- struct line_finder lf = {.lr = lr};
+ Dwarf_Off off = 0, noff;
+ size_t cuhl;
+ Dwarf_Die *diep;
+ Dwarf *dbg;
- ret = dwarf_init(fd, DW_DLC_READ, 0, 0, &__dw_debug, &__dw_error);
- if (ret != DW_DLV_OK)
+ dbg = dwarf_begin(fd, DWARF_C_READ);
+ if (!dbg)
return -ENOENT;
+ /* Loop on CUs (Compilation Unit) */
while (!lf.found) {
- /* Search CU (Compilation Unit) */
- ret = dwarf_next_cu_header(__dw_debug, NULL, NULL, NULL,
- &addr_size, &next_cuh, &__dw_error);
- DIE_IF(ret == DW_DLV_ERROR);
- if (ret == DW_DLV_NO_ENTRY)
+ ret = dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL);
+ if (ret != 0)
break;
/* Get the DIE(Debugging Information Entry) of this CU */
- ret = dwarf_siblingof(__dw_debug, 0, &lf.cu_die, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
+ diep = dwarf_offdie(dbg, off + cuhl, &lf.cu_die);
+ if (!diep)
+ continue;
/* Check if target file is included. */
if (lr->file)
- lf.fno = cu_find_fileno(lf.cu_die, lr->file);
+ lf.fname = cu_find_realpath(&lf.cu_die, lr->file);
+ else
+ lf.fname = 0;
- if (!lr->file || lf.fno) {
+ if (!lr->file || lf.fname) {
if (lr->function)
find_line_range_by_func(&lf);
else {
lf.lno_s = lr->start;
if (!lr->end)
- lf.lno_e = (Dwarf_Unsigned)-1;
+ lf.lno_e = INT_MAX;
else
lf.lno_e = lr->end;
- find_line_range_by_line(&lf);
+ find_line_range_by_line(NULL, &lf);
}
- /* Get the real file path */
- if (lf.found)
- cu_get_filename(lf.cu_die, lf.fno, &lr->path);
}
- dwarf_dealloc(__dw_debug, lf.cu_die, DW_DLA_DIE);
+ off = noff;
}
- ret = dwarf_finish(__dw_debug, &__dw_error);
- DIE_IF(ret != DW_DLV_OK);
+ pr_debug("path: %lx\n", (unsigned long)lr->path);
+ dwarf_end(dbg);
return lf.found;
}
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 972b386116f..21f7354397b 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -1,6 +1,7 @@
#ifndef _PROBE_FINDER_H
#define _PROBE_FINDER_H
+#include <stdbool.h>
#include "util.h"
#define MAX_PATH_LEN 256
@@ -20,6 +21,7 @@ struct probe_point {
/* Inputs */
char *file; /* File name */
int line; /* Line number */
+ char *lazy_line; /* Lazy line pattern */
char *function; /* Function name */
int offset; /* Offset bytes */
@@ -46,53 +48,45 @@ struct line_range {
char *function; /* Function name */
unsigned int start; /* Start line number */
unsigned int end; /* End line number */
- unsigned int offset; /* Start line offset */
+ int offset; /* Start line offset */
char *path; /* Real path name */
struct list_head line_list; /* Visible lines */
};
-#ifndef NO_LIBDWARF
-extern int find_probepoint(int fd, struct probe_point *pp);
+#ifndef NO_DWARF_SUPPORT
+extern int find_probe_point(int fd, struct probe_point *pp);
extern int find_line_range(int fd, struct line_range *lr);
-/* Workaround for undefined _MIPS_SZLONG bug in libdwarf.h: */
-#ifndef _MIPS_SZLONG
-# define _MIPS_SZLONG 0
-#endif
-
#include <dwarf.h>
-#include <libdwarf.h>
+#include <libdw.h>
struct probe_finder {
- struct probe_point *pp; /* Target probe point */
+ struct probe_point *pp; /* Target probe point */
/* For function searching */
- Dwarf_Addr addr; /* Address */
- Dwarf_Unsigned fno; /* File number */
- Dwarf_Unsigned lno; /* Line number */
- Dwarf_Off inl_offs; /* Inline offset */
- Dwarf_Die cu_die; /* Current CU */
+ Dwarf_Addr addr; /* Address */
+ const char *fname; /* File name */
+ int lno; /* Line number */
+ Dwarf_Die cu_die; /* Current CU */
/* For variable searching */
- Dwarf_Addr cu_base; /* Current CU base address */
- Dwarf_Locdesc fbloc; /* Location of Current Frame Base */
- const char *var; /* Current variable name */
- char *buf; /* Current output buffer */
- int len; /* Length of output buffer */
+ Dwarf_Op *fb_ops; /* Frame base attribute */
+ const char *var; /* Current variable name */
+ char *buf; /* Current output buffer */
+ int len; /* Length of output buffer */
+ struct list_head lcache; /* Line cache for lazy match */
};
struct line_finder {
- struct line_range *lr; /* Target line range */
-
- Dwarf_Unsigned fno; /* File number */
- Dwarf_Unsigned lno_s; /* Start line number */
- Dwarf_Unsigned lno_e; /* End line number */
- Dwarf_Addr addr_s; /* Start address */
- Dwarf_Addr addr_e; /* End address */
- Dwarf_Die cu_die; /* Current CU */
+ struct line_range *lr; /* Target line range */
+
+ const char *fname; /* File name */
+ int lno_s; /* Start line number */
+ int lno_e; /* End line number */
+ Dwarf_Die cu_die; /* Current CU */
int found;
};
-#endif /* NO_LIBDWARF */
+#endif /* NO_DWARF_SUPPORT */
#endif /*_PROBE_FINDER_H */
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 33a414bbba3..6a72f14c598 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -208,7 +208,7 @@ static void python_process_event(int cpu, void *data,
int size __unused,
unsigned long long nsecs, char *comm)
{
- PyObject *handler, *retval, *context, *t;
+ PyObject *handler, *retval, *context, *t, *obj;
static char handler_name[256];
struct format_field *field;
unsigned long long val;
@@ -256,16 +256,23 @@ static void python_process_event(int cpu, void *data,
offset &= 0xffff;
} else
offset = field->offset;
- PyTuple_SetItem(t, n++,
- PyString_FromString((char *)data + offset));
+ obj = PyString_FromString((char *)data + offset);
} else { /* FIELD_IS_NUMERIC */
val = read_size(data + field->offset, field->size);
if (field->flags & FIELD_IS_SIGNED) {
- PyTuple_SetItem(t, n++, PyInt_FromLong(val));
+ if ((long long)val >= LONG_MIN &&
+ (long long)val <= LONG_MAX)
+ obj = PyInt_FromLong(val);
+ else
+ obj = PyLong_FromLongLong(val);
} else {
- PyTuple_SetItem(t, n++, PyInt_FromLong(val));
+ if (val <= LONG_MAX)
+ obj = PyInt_FromLong(val);
+ else
+ obj = PyLong_FromUnsignedLongLong(val);
}
}
+ PyTuple_SetItem(t, n++, obj);
}
if (_PyTuple_Resize(&t, n) == -1)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 0de7258e70a..eed1cb88900 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -70,6 +70,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
memcpy(self->filename, filename, len);
self->threads = RB_ROOT;
+ self->stats_by_id = RB_ROOT;
self->last_match = NULL;
self->mmap_window = 32;
self->cwd = NULL;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 31950fcd8a4..5c33417eebb 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -20,6 +20,7 @@ struct perf_session {
struct thread *last_match;
struct map *vmlinux_maps[MAP__NR_TYPES];
struct events_stats events_stats;
+ struct rb_root stats_by_id;
unsigned long event_total[PERF_RECORD_MAX];
unsigned long unknown_events;
struct rb_root hists;
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index c397d4f6f74..a175949ed21 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -265,21 +265,21 @@ error:
return false;
}
-/**
- * strglobmatch - glob expression pattern matching
- * @str: the target string to match
- * @pat: the pattern string to match
- *
- * This returns true if the @str matches @pat. @pat can includes wildcards
- * ('*','?') and character classes ([CHARS], complementation and ranges are
- * also supported). Also, this supports escape character ('\') to use special
- * characters as normal character.
- *
- * Note: if @pat syntax is broken, this always returns false.
- */
-bool strglobmatch(const char *str, const char *pat)
+/* Glob/lazy pattern matching */
+static bool __match_glob(const char *str, const char *pat, bool ignore_space)
{
while (*str && *pat && *pat != '*') {
+ if (ignore_space) {
+ /* Ignore spaces for lazy matching */
+ if (isspace(*str)) {
+ str++;
+ continue;
+ }
+ if (isspace(*pat)) {
+ pat++;
+ continue;
+ }
+ }
if (*pat == '?') { /* Matches any single character */
str++;
pat++;
@@ -308,3 +308,32 @@ bool strglobmatch(const char *str, const char *pat)
return !*str && !*pat;
}
+/**
+ * strglobmatch - glob expression pattern matching
+ * @str: the target string to match
+ * @pat: the pattern string to match
+ *
+ * This returns true if the @str matches @pat. @pat can includes wildcards
+ * ('*','?') and character classes ([CHARS], complementation and ranges are
+ * also supported). Also, this supports escape character ('\') to use special
+ * characters as normal character.
+ *
+ * Note: if @pat syntax is broken, this always returns false.
+ */
+bool strglobmatch(const char *str, const char *pat)
+{
+ return __match_glob(str, pat, false);
+}
+
+/**
+ * strlazymatch - matching pattern strings lazily with glob pattern
+ * @str: the target string to match
+ * @pat: the pattern string to match
+ *
+ * This is similar to strglobmatch, except this ignores spaces in
+ * the target string.
+ */
+bool strlazymatch(const char *str, const char *pat)
+{
+ return __match_glob(str, pat, true);
+}
diff --git a/tools/perf/util/string.h b/tools/perf/util/string.h
index 02ede58c54b..542e44de371 100644
--- a/tools/perf/util/string.h
+++ b/tools/perf/util/string.h
@@ -10,6 +10,7 @@ s64 perf_atoll(const char *str);
char **argv_split(const char *str, int *argcp);
void argv_free(char **argv);
bool strglobmatch(const char *str, const char *pat);
+bool strlazymatch(const char *str, const char *pat);
#define _STR(x) #x
#define STR(x) _STR(x)
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 323c0aea0a9..c458c4a371d 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -163,9 +163,17 @@ void dso__set_long_name(struct dso *self, char *name)
self->long_name_len = strlen(name);
}
+static void dso__set_short_name(struct dso *self, const char *name)
+{
+ if (name == NULL)
+ return;
+ self->short_name = name;
+ self->short_name_len = strlen(name);
+}
+
static void dso__set_basename(struct dso *self)
{
- self->short_name = basename(self->long_name);
+ dso__set_short_name(self, basename(self->long_name));
}
struct dso *dso__new(const char *name)
@@ -176,7 +184,7 @@ struct dso *dso__new(const char *name)
int i;
strcpy(self->name, name);
dso__set_long_name(self, self->name);
- self->short_name = self->name;
+ dso__set_short_name(self, self->name);
for (i = 0; i < MAP__NR_TYPES; ++i)
self->symbols[i] = self->symbol_names[i] = RB_ROOT;
self->slen_calculated = 0;
@@ -897,7 +905,6 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
struct map *curr_map = map;
struct dso *curr_dso = self;
- size_t dso_name_len = strlen(self->short_name);
Elf_Data *symstrs, *secstrs;
uint32_t nr_syms;
int err = -1;
@@ -987,7 +994,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
char dso_name[PATH_MAX];
if (strcmp(section_name,
- curr_dso->short_name + dso_name_len) == 0)
+ (curr_dso->short_name +
+ self->short_name_len)) == 0)
goto new_symbol;
if (strcmp(section_name, ".text") == 0) {
@@ -1782,7 +1790,7 @@ struct dso *dso__new_kernel(const char *name)
struct dso *self = dso__new(name ?: "[kernel.kallsyms]");
if (self != NULL) {
- self->short_name = "[kernel]";
+ dso__set_short_name(self, "[kernel]");
self->kernel = 1;
}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 280dadd32a0..f30a3742891 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -110,9 +110,10 @@ struct dso {
u8 sorted_by_name;
u8 loaded;
u8 build_id[BUILD_ID_SIZE];
- u16 long_name_len;
const char *short_name;
char *long_name;
+ u16 long_name_len;
+ u16 short_name_len;
char name[0];
};
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 21b92162282..fa968312ee7 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -79,8 +79,8 @@ int thread__comm_len(struct thread *self)
return self->comm_len;
}
-static size_t __map_groups__fprintf_maps(struct map_groups *self,
- enum map_type type, FILE *fp)
+size_t __map_groups__fprintf_maps(struct map_groups *self,
+ enum map_type type, FILE *fp)
{
size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
struct rb_node *nd;
@@ -89,7 +89,7 @@ static size_t __map_groups__fprintf_maps(struct map_groups *self,
struct map *pos = rb_entry(nd, struct map, rb_node);
printed += fprintf(fp, "Map:");
printed += map__fprintf(pos, fp);
- if (verbose > 1) {
+ if (verbose > 2) {
printed += dso__fprintf(pos->dso, type, fp);
printed += fprintf(fp, "--\n");
}
@@ -183,8 +183,8 @@ struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
return th;
}
-static void map_groups__remove_overlappings(struct map_groups *self,
- struct map *map)
+static int map_groups__fixup_overlappings(struct map_groups *self,
+ struct map *map)
{
struct rb_root *root = &self->maps[map->type];
struct rb_node *next = rb_first(root);
@@ -209,7 +209,36 @@ static void map_groups__remove_overlappings(struct map_groups *self,
* list.
*/
list_add_tail(&pos->node, &self->removed_maps[map->type]);
+ /*
+ * Now check if we need to create new maps for areas not
+ * overlapped by the new map:
+ */
+ if (map->start > pos->start) {
+ struct map *before = map__clone(pos);
+
+ if (before == NULL)
+ return -ENOMEM;
+
+ before->end = map->start - 1;
+ map_groups__insert(self, before);
+ if (verbose >= 2)
+ map__fprintf(before, stderr);
+ }
+
+ if (map->end < pos->end) {
+ struct map *after = map__clone(pos);
+
+ if (after == NULL)
+ return -ENOMEM;
+
+ after->start = map->end + 1;
+ map_groups__insert(self, after);
+ if (verbose >= 2)
+ map__fprintf(after, stderr);
+ }
}
+
+ return 0;
}
void maps__insert(struct rb_root *maps, struct map *map)
@@ -254,7 +283,7 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
void thread__insert_map(struct thread *self, struct map *map)
{
- map_groups__remove_overlappings(&self->mg, map);
+ map_groups__fixup_overlappings(&self->mg, map);
map_groups__insert(&self->mg, map);
}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 0a28f39de54..dcf70303e58 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -10,6 +10,9 @@ struct map_groups {
struct list_head removed_maps[MAP__NR_TYPES];
};
+size_t __map_groups__fprintf_maps(struct map_groups *self,
+ enum map_type type, FILE *fp);
+
struct thread {
struct rb_node rb_node;
struct map_groups mg;
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index daece36c0a5..7f1178f6b83 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -12,3 +12,6 @@ config HAVE_KVM_EVENTFD
config KVM_APIC_ARCHITECTURE
bool
+
+config KVM_MMIO
+ bool
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
index f73de631e3e..02ff2b19dbe 100644
--- a/virt/kvm/assigned-dev.c
+++ b/virt/kvm/assigned-dev.c
@@ -16,6 +16,7 @@
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "irq.h"
static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
@@ -504,12 +505,12 @@ out:
static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
struct kvm_assigned_pci_dev *assigned_dev)
{
- int r = 0;
+ int r = 0, idx;
struct kvm_assigned_dev_kernel *match;
struct pci_dev *dev;
mutex_lock(&kvm->lock);
- down_read(&kvm->slots_lock);
+ idx = srcu_read_lock(&kvm->srcu);
match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
assigned_dev->assigned_dev_id);
@@ -526,7 +527,8 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
r = -ENOMEM;
goto out;
}
- dev = pci_get_bus_and_slot(assigned_dev->busnr,
+ dev = pci_get_domain_bus_and_slot(assigned_dev->segnr,
+ assigned_dev->busnr,
assigned_dev->devfn);
if (!dev) {
printk(KERN_INFO "%s: host device not found\n", __func__);
@@ -548,6 +550,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
pci_reset_function(dev);
match->assigned_dev_id = assigned_dev->assigned_dev_id;
+ match->host_segnr = assigned_dev->segnr;
match->host_busnr = assigned_dev->busnr;
match->host_devfn = assigned_dev->devfn;
match->flags = assigned_dev->flags;
@@ -573,7 +576,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
}
out:
- up_read(&kvm->slots_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
mutex_unlock(&kvm->lock);
return r;
out_list_del:
@@ -585,7 +588,7 @@ out_put:
pci_dev_put(dev);
out_free:
kfree(match);
- up_read(&kvm->slots_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
mutex_unlock(&kvm->lock);
return r;
}
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index 04d69cd7049..36e25802964 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -10,6 +10,7 @@
#include "iodev.h"
#include <linux/kvm_host.h>
+#include <linux/slab.h>
#include <linux/kvm.h>
#include "coalesced_mmio.h"
@@ -92,41 +93,64 @@ static const struct kvm_io_device_ops coalesced_mmio_ops = {
int kvm_coalesced_mmio_init(struct kvm *kvm)
{
struct kvm_coalesced_mmio_dev *dev;
+ struct page *page;
int ret;
+ ret = -ENOMEM;
+ page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ if (!page)
+ goto out_err;
+ kvm->coalesced_mmio_ring = page_address(page);
+
+ ret = -ENOMEM;
dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL);
if (!dev)
- return -ENOMEM;
+ goto out_free_page;
spin_lock_init(&dev->lock);
kvm_iodevice_init(&dev->dev, &coalesced_mmio_ops);
dev->kvm = kvm;
kvm->coalesced_mmio_dev = dev;
- ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &dev->dev);
+ mutex_lock(&kvm->slots_lock);
+ ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, &dev->dev);
+ mutex_unlock(&kvm->slots_lock);
if (ret < 0)
- kfree(dev);
+ goto out_free_dev;
+
+ return ret;
+out_free_dev:
+ kfree(dev);
+out_free_page:
+ __free_page(page);
+out_err:
return ret;
}
+void kvm_coalesced_mmio_free(struct kvm *kvm)
+{
+ if (kvm->coalesced_mmio_ring)
+ free_page((unsigned long)kvm->coalesced_mmio_ring);
+}
+
int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm,
- struct kvm_coalesced_mmio_zone *zone)
+ struct kvm_coalesced_mmio_zone *zone)
{
struct kvm_coalesced_mmio_dev *dev = kvm->coalesced_mmio_dev;
if (dev == NULL)
return -EINVAL;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
if (dev->nb_zones >= KVM_COALESCED_MMIO_ZONE_MAX) {
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return -ENOBUFS;
}
dev->zone[dev->nb_zones] = *zone;
dev->nb_zones++;
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return 0;
}
@@ -140,10 +164,10 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
if (dev == NULL)
return -EINVAL;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
i = dev->nb_zones;
- while(i) {
+ while (i) {
z = &dev->zone[i - 1];
/* unregister all zones
@@ -158,7 +182,7 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
i--;
}
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return 0;
}
diff --git a/virt/kvm/coalesced_mmio.h b/virt/kvm/coalesced_mmio.h
index 4b49f27fa31..8a5959e3535 100644
--- a/virt/kvm/coalesced_mmio.h
+++ b/virt/kvm/coalesced_mmio.h
@@ -1,3 +1,6 @@
+#ifndef __KVM_COALESCED_MMIO_H__
+#define __KVM_COALESCED_MMIO_H__
+
/*
* KVM coalesced MMIO
*
@@ -7,6 +10,8 @@
*
*/
+#ifdef CONFIG_KVM_MMIO
+
#define KVM_COALESCED_MMIO_ZONE_MAX 100
struct kvm_coalesced_mmio_dev {
@@ -18,7 +23,17 @@ struct kvm_coalesced_mmio_dev {
};
int kvm_coalesced_mmio_init(struct kvm *kvm);
+void kvm_coalesced_mmio_free(struct kvm *kvm);
int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm,
struct kvm_coalesced_mmio_zone *zone);
int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
struct kvm_coalesced_mmio_zone *zone);
+
+#else
+
+static inline int kvm_coalesced_mmio_init(struct kvm *kvm) { return 0; }
+static inline void kvm_coalesced_mmio_free(struct kvm *kvm) { }
+
+#endif
+
+#endif
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index a9d3fc6c681..b81f0ebbaaa 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -30,6 +30,7 @@
#include <linux/list.h>
#include <linux/eventfd.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include "iodev.h"
@@ -47,7 +48,6 @@ struct _irqfd {
int gsi;
struct list_head list;
poll_table pt;
- wait_queue_head_t *wqh;
wait_queue_t wait;
struct work_struct inject;
struct work_struct shutdown;
@@ -159,8 +159,6 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
poll_table *pt)
{
struct _irqfd *irqfd = container_of(pt, struct _irqfd, pt);
-
- irqfd->wqh = wqh;
add_wait_queue(wqh, &irqfd->wait);
}
@@ -463,7 +461,7 @@ static int
kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
{
int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
- struct kvm_io_bus *bus = pio ? &kvm->pio_bus : &kvm->mmio_bus;
+ enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
struct _ioeventfd *p;
struct eventfd_ctx *eventfd;
int ret;
@@ -508,7 +506,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
else
p->wildcard = true;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
/* Verify that there isnt a match already */
if (ioeventfd_check_collision(kvm, p)) {
@@ -518,18 +516,18 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
kvm_iodevice_init(&p->dev, &ioeventfd_ops);
- ret = __kvm_io_bus_register_dev(bus, &p->dev);
+ ret = kvm_io_bus_register_dev(kvm, bus_idx, &p->dev);
if (ret < 0)
goto unlock_fail;
list_add_tail(&p->list, &kvm->ioeventfds);
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return 0;
unlock_fail:
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
fail:
kfree(p);
@@ -542,7 +540,7 @@ static int
kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
{
int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
- struct kvm_io_bus *bus = pio ? &kvm->pio_bus : &kvm->mmio_bus;
+ enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
struct _ioeventfd *p, *tmp;
struct eventfd_ctx *eventfd;
int ret = -ENOENT;
@@ -551,7 +549,7 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
if (IS_ERR(eventfd))
return PTR_ERR(eventfd);
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) {
bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH);
@@ -565,13 +563,13 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
if (!p->wildcard && p->datamatch != args->datamatch)
continue;
- __kvm_io_bus_unregister_dev(bus, &p->dev);
+ kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
ioeventfd_release(p);
ret = 0;
break;
}
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
eventfd_ctx_put(eventfd);
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 38a2d20b89d..03a5eb22da2 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -33,6 +33,7 @@
#include <linux/smp.h>
#include <linux/hrtimer.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/current.h>
@@ -100,6 +101,19 @@ static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
return injected;
}
+static void update_handled_vectors(struct kvm_ioapic *ioapic)
+{
+ DECLARE_BITMAP(handled_vectors, 256);
+ int i;
+
+ memset(handled_vectors, 0, sizeof(handled_vectors));
+ for (i = 0; i < IOAPIC_NUM_PINS; ++i)
+ __set_bit(ioapic->redirtbl[i].fields.vector, handled_vectors);
+ memcpy(ioapic->handled_vectors, handled_vectors,
+ sizeof(handled_vectors));
+ smp_wmb();
+}
+
static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
{
unsigned index;
@@ -134,6 +148,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
e->bits |= (u32) val;
e->fields.remote_irr = 0;
}
+ update_handled_vectors(ioapic);
mask_after = e->fields.mask;
if (mask_before != mask_after)
kvm_fire_mask_notifiers(ioapic->kvm, index, mask_after);
@@ -241,6 +256,9 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode)
{
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
+ smp_rmb();
+ if (!test_bit(vector, ioapic->handled_vectors))
+ return;
mutex_lock(&ioapic->lock);
__kvm_ioapic_update_eoi(ioapic, vector, trigger_mode);
mutex_unlock(&ioapic->lock);
@@ -352,6 +370,7 @@ void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
ioapic->ioregsel = 0;
ioapic->irr = 0;
ioapic->id = 0;
+ update_handled_vectors(ioapic);
}
static const struct kvm_io_device_ops ioapic_mmio_ops = {
@@ -372,13 +391,28 @@ int kvm_ioapic_init(struct kvm *kvm)
kvm_ioapic_reset(ioapic);
kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops);
ioapic->kvm = kvm;
- ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &ioapic->dev);
- if (ret < 0)
+ mutex_lock(&kvm->slots_lock);
+ ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, &ioapic->dev);
+ mutex_unlock(&kvm->slots_lock);
+ if (ret < 0) {
+ kvm->arch.vioapic = NULL;
kfree(ioapic);
+ }
return ret;
}
+void kvm_ioapic_destroy(struct kvm *kvm)
+{
+ struct kvm_ioapic *ioapic = kvm->arch.vioapic;
+
+ if (ioapic) {
+ kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &ioapic->dev);
+ kvm->arch.vioapic = NULL;
+ kfree(ioapic);
+ }
+}
+
int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
{
struct kvm_ioapic *ioapic = ioapic_irqchip(kvm);
@@ -399,6 +433,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
mutex_lock(&ioapic->lock);
memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
+ update_handled_vectors(ioapic);
mutex_unlock(&ioapic->lock);
return 0;
}
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index 419c43b667a..8a751b78a43 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -46,6 +46,7 @@ struct kvm_ioapic {
struct kvm *kvm;
void (*ack_notifier)(void *opaque, int irq);
struct mutex lock;
+ DECLARE_BITMAP(handled_vectors, 256);
};
#ifdef DEBUG
@@ -71,6 +72,7 @@ int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
int kvm_ioapic_init(struct kvm *kvm);
+void kvm_ioapic_destroy(struct kvm *kvm);
int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
void kvm_ioapic_reset(struct kvm_ioapic *ioapic);
int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
index 15147583abd..80fd3ad3b2d 100644
--- a/virt/kvm/iommu.c
+++ b/virt/kvm/iommu.c
@@ -32,10 +32,10 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm);
static void kvm_iommu_put_pages(struct kvm *kvm,
gfn_t base_gfn, unsigned long npages);
-int kvm_iommu_map_pages(struct kvm *kvm,
- gfn_t base_gfn, unsigned long npages)
+int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
{
- gfn_t gfn = base_gfn;
+ gfn_t gfn = slot->base_gfn;
+ unsigned long npages = slot->npages;
pfn_t pfn;
int i, r = 0;
struct iommu_domain *domain = kvm->arch.iommu_domain;
@@ -54,7 +54,7 @@ int kvm_iommu_map_pages(struct kvm *kvm,
if (iommu_iova_to_phys(domain, gfn_to_gpa(gfn)))
continue;
- pfn = gfn_to_pfn(kvm, gfn);
+ pfn = gfn_to_pfn_memslot(kvm, slot, gfn);
r = iommu_map_range(domain,
gfn_to_gpa(gfn),
pfn_to_hpa(pfn),
@@ -69,17 +69,19 @@ int kvm_iommu_map_pages(struct kvm *kvm,
return 0;
unmap_pages:
- kvm_iommu_put_pages(kvm, base_gfn, i);
+ kvm_iommu_put_pages(kvm, slot->base_gfn, i);
return r;
}
static int kvm_iommu_map_memslots(struct kvm *kvm)
{
int i, r = 0;
+ struct kvm_memslots *slots;
+
+ slots = rcu_dereference(kvm->memslots);
- for (i = 0; i < kvm->nmemslots; i++) {
- r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn,
- kvm->memslots[i].npages);
+ for (i = 0; i < slots->nmemslots; i++) {
+ r = kvm_iommu_map_pages(kvm, &slots->memslots[i]);
if (r)
break;
}
@@ -104,7 +106,8 @@ int kvm_assign_device(struct kvm *kvm,
r = iommu_attach_device(domain, &pdev->dev);
if (r) {
- printk(KERN_ERR "assign device %x:%x.%x failed",
+ printk(KERN_ERR "assign device %x:%x:%x.%x failed",
+ pci_domain_nr(pdev->bus),
pdev->bus->number,
PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn));
@@ -125,7 +128,8 @@ int kvm_assign_device(struct kvm *kvm,
goto out_unmap;
}
- printk(KERN_DEBUG "assign device: host bdf = %x:%x:%x\n",
+ printk(KERN_DEBUG "assign device %x:%x:%x.%x\n",
+ assigned_dev->host_segnr,
assigned_dev->host_busnr,
PCI_SLOT(assigned_dev->host_devfn),
PCI_FUNC(assigned_dev->host_devfn));
@@ -152,7 +156,8 @@ int kvm_deassign_device(struct kvm *kvm,
iommu_detach_device(domain, &pdev->dev);
- printk(KERN_DEBUG "deassign device: host bdf = %x:%x:%x\n",
+ printk(KERN_DEBUG "deassign device %x:%x:%x.%x\n",
+ assigned_dev->host_segnr,
assigned_dev->host_busnr,
PCI_SLOT(assigned_dev->host_devfn),
PCI_FUNC(assigned_dev->host_devfn));
@@ -210,10 +215,13 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
static int kvm_iommu_unmap_memslots(struct kvm *kvm)
{
int i;
+ struct kvm_memslots *slots;
+
+ slots = rcu_dereference(kvm->memslots);
- for (i = 0; i < kvm->nmemslots; i++) {
- kvm_iommu_put_pages(kvm, kvm->memslots[i].base_gfn,
- kvm->memslots[i].npages);
+ for (i = 0; i < slots->nmemslots; i++) {
+ kvm_iommu_put_pages(kvm, slots->memslots[i].base_gfn,
+ slots->memslots[i].npages);
}
return 0;
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 9fd5b3ebc51..a0e88809e45 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -20,6 +20,7 @@
*/
#include <linux/kvm_host.h>
+#include <linux/slab.h>
#include <trace/events/kvm.h>
#include <asm/msidef.h>
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index a944be392d6..c82ae249263 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/percpu.h>
-#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/vmalloc.h>
@@ -44,6 +43,9 @@
#include <linux/bitops.h>
#include <linux/spinlock.h>
#include <linux/compat.h>
+#include <linux/srcu.h>
+#include <linux/hugetlb.h>
+#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -51,9 +53,7 @@
#include <asm/pgtable.h>
#include <asm-generic/bitops/le.h>
-#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
#include "coalesced_mmio.h"
-#endif
#define CREATE_TRACE_POINTS
#include <trace/events/kvm.h>
@@ -86,6 +86,8 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
static int hardware_enable_all(void);
static void hardware_disable_all(void);
+static void kvm_io_bus_destroy(struct kvm_io_bus *bus);
+
static bool kvm_rebooting;
static bool largepages_enabled = true;
@@ -136,7 +138,7 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
zalloc_cpumask_var(&cpus, GFP_ATOMIC);
- spin_lock(&kvm->requests_lock);
+ raw_spin_lock(&kvm->requests_lock);
me = smp_processor_id();
kvm_for_each_vcpu(i, vcpu, kvm) {
if (test_and_set_bit(req, &vcpu->requests))
@@ -151,7 +153,7 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
smp_call_function_many(cpus, ack_flush, NULL, 1);
else
called = false;
- spin_unlock(&kvm->requests_lock);
+ raw_spin_unlock(&kvm->requests_lock);
free_cpumask_var(cpus);
return called;
}
@@ -215,7 +217,7 @@ static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
unsigned long address)
{
struct kvm *kvm = mmu_notifier_to_kvm(mn);
- int need_tlb_flush;
+ int need_tlb_flush, idx;
/*
* When ->invalidate_page runs, the linux pte has been zapped
@@ -235,10 +237,12 @@ static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
* pte after kvm_unmap_hva returned, without noticing the page
* is going to be freed.
*/
+ idx = srcu_read_lock(&kvm->srcu);
spin_lock(&kvm->mmu_lock);
kvm->mmu_notifier_seq++;
need_tlb_flush = kvm_unmap_hva(kvm, address);
spin_unlock(&kvm->mmu_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
/* we've to flush the tlb before the pages can be freed */
if (need_tlb_flush)
@@ -252,11 +256,14 @@ static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
pte_t pte)
{
struct kvm *kvm = mmu_notifier_to_kvm(mn);
+ int idx;
+ idx = srcu_read_lock(&kvm->srcu);
spin_lock(&kvm->mmu_lock);
kvm->mmu_notifier_seq++;
kvm_set_spte_hva(kvm, address, pte);
spin_unlock(&kvm->mmu_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
}
static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
@@ -265,8 +272,9 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
unsigned long end)
{
struct kvm *kvm = mmu_notifier_to_kvm(mn);
- int need_tlb_flush = 0;
+ int need_tlb_flush = 0, idx;
+ idx = srcu_read_lock(&kvm->srcu);
spin_lock(&kvm->mmu_lock);
/*
* The count increase must become visible at unlock time as no
@@ -277,6 +285,7 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
for (; start < end; start += PAGE_SIZE)
need_tlb_flush |= kvm_unmap_hva(kvm, start);
spin_unlock(&kvm->mmu_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
/* we've to flush the tlb before the pages can be freed */
if (need_tlb_flush)
@@ -314,11 +323,13 @@ static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn,
unsigned long address)
{
struct kvm *kvm = mmu_notifier_to_kvm(mn);
- int young;
+ int young, idx;
+ idx = srcu_read_lock(&kvm->srcu);
spin_lock(&kvm->mmu_lock);
young = kvm_age_hva(kvm, address);
spin_unlock(&kvm->mmu_lock);
+ srcu_read_unlock(&kvm->srcu, idx);
if (young)
kvm_flush_remote_tlbs(kvm);
@@ -330,7 +341,11 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
struct mm_struct *mm)
{
struct kvm *kvm = mmu_notifier_to_kvm(mn);
+ int idx;
+
+ idx = srcu_read_lock(&kvm->srcu);
kvm_arch_flush_shadow(kvm);
+ srcu_read_unlock(&kvm->srcu, idx);
}
static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
@@ -341,15 +356,26 @@ static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
.change_pte = kvm_mmu_notifier_change_pte,
.release = kvm_mmu_notifier_release,
};
+
+static int kvm_init_mmu_notifier(struct kvm *kvm)
+{
+ kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops;
+ return mmu_notifier_register(&kvm->mmu_notifier, current->mm);
+}
+
+#else /* !(CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER) */
+
+static int kvm_init_mmu_notifier(struct kvm *kvm)
+{
+ return 0;
+}
+
#endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */
static struct kvm *kvm_create_vm(void)
{
- int r = 0;
+ int r = 0, i;
struct kvm *kvm = kvm_arch_create_vm();
-#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
- struct page *page;
-#endif
if (IS_ERR(kvm))
goto out;
@@ -363,39 +389,35 @@ static struct kvm *kvm_create_vm(void)
INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list);
#endif
-#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
- page = alloc_page(GFP_KERNEL | __GFP_ZERO);
- if (!page) {
- r = -ENOMEM;
+ r = -ENOMEM;
+ kvm->memslots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
+ if (!kvm->memslots)
goto out_err;
- }
- kvm->coalesced_mmio_ring =
- (struct kvm_coalesced_mmio_ring *)page_address(page);
-#endif
-
-#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
- {
- kvm->mmu_notifier.ops = &kvm_mmu_notifier_ops;
- r = mmu_notifier_register(&kvm->mmu_notifier, current->mm);
- if (r) {
-#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
- put_page(page);
-#endif
+ if (init_srcu_struct(&kvm->srcu))
+ goto out_err;
+ for (i = 0; i < KVM_NR_BUSES; i++) {
+ kvm->buses[i] = kzalloc(sizeof(struct kvm_io_bus),
+ GFP_KERNEL);
+ if (!kvm->buses[i]) {
+ cleanup_srcu_struct(&kvm->srcu);
goto out_err;
}
}
-#endif
+
+ r = kvm_init_mmu_notifier(kvm);
+ if (r) {
+ cleanup_srcu_struct(&kvm->srcu);
+ goto out_err;
+ }
kvm->mm = current->mm;
atomic_inc(&kvm->mm->mm_count);
spin_lock_init(&kvm->mmu_lock);
- spin_lock_init(&kvm->requests_lock);
- kvm_io_bus_init(&kvm->pio_bus);
+ raw_spin_lock_init(&kvm->requests_lock);
kvm_eventfd_init(kvm);
mutex_init(&kvm->lock);
mutex_init(&kvm->irq_lock);
- kvm_io_bus_init(&kvm->mmio_bus);
- init_rwsem(&kvm->slots_lock);
+ mutex_init(&kvm->slots_lock);
atomic_set(&kvm->users_count, 1);
spin_lock(&kvm_lock);
list_add(&kvm->vm_list, &vm_list);
@@ -406,12 +428,12 @@ static struct kvm *kvm_create_vm(void)
out:
return kvm;
-#if defined(KVM_COALESCED_MMIO_PAGE_OFFSET) || \
- (defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER))
out_err:
hardware_disable_all();
-#endif
out_err_nodisable:
+ for (i = 0; i < KVM_NR_BUSES; i++)
+ kfree(kvm->buses[i]);
+ kfree(kvm->memslots);
kfree(kvm);
return ERR_PTR(r);
}
@@ -446,13 +468,17 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
void kvm_free_physmem(struct kvm *kvm)
{
int i;
+ struct kvm_memslots *slots = kvm->memslots;
- for (i = 0; i < kvm->nmemslots; ++i)
- kvm_free_physmem_slot(&kvm->memslots[i], NULL);
+ for (i = 0; i < slots->nmemslots; ++i)
+ kvm_free_physmem_slot(&slots->memslots[i], NULL);
+
+ kfree(kvm->memslots);
}
static void kvm_destroy_vm(struct kvm *kvm)
{
+ int i;
struct mm_struct *mm = kvm->mm;
kvm_arch_sync_events(kvm);
@@ -460,12 +486,9 @@ static void kvm_destroy_vm(struct kvm *kvm)
list_del(&kvm->vm_list);
spin_unlock(&kvm_lock);
kvm_free_irq_routing(kvm);
- kvm_io_bus_destroy(&kvm->pio_bus);
- kvm_io_bus_destroy(&kvm->mmio_bus);
-#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
- if (kvm->coalesced_mmio_ring != NULL)
- free_page((unsigned long)kvm->coalesced_mmio_ring);
-#endif
+ for (i = 0; i < KVM_NR_BUSES; i++)
+ kvm_io_bus_destroy(kvm->buses[i]);
+ kvm_coalesced_mmio_free(kvm);
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
#else
@@ -512,12 +535,13 @@ int __kvm_set_memory_region(struct kvm *kvm,
struct kvm_userspace_memory_region *mem,
int user_alloc)
{
- int r;
+ int r, flush_shadow = 0;
gfn_t base_gfn;
unsigned long npages;
unsigned long i;
struct kvm_memory_slot *memslot;
struct kvm_memory_slot old, new;
+ struct kvm_memslots *slots, *old_memslots;
r = -EINVAL;
/* General sanity checks */
@@ -532,7 +556,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr)
goto out;
- memslot = &kvm->memslots[mem->slot];
+ memslot = &kvm->memslots->memslots[mem->slot];
base_gfn = mem->guest_phys_addr >> PAGE_SHIFT;
npages = mem->memory_size >> PAGE_SHIFT;
@@ -553,7 +577,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
/* Check for overlaps */
r = -EEXIST;
for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
- struct kvm_memory_slot *s = &kvm->memslots[i];
+ struct kvm_memory_slot *s = &kvm->memslots->memslots[i];
if (s == memslot || !s->npages)
continue;
@@ -579,15 +603,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
memset(new.rmap, 0, npages * sizeof(*new.rmap));
new.user_alloc = user_alloc;
- /*
- * hva_to_rmmap() serialzies with the mmu_lock and to be
- * safe it has to ignore memslots with !user_alloc &&
- * !userspace_addr.
- */
- if (user_alloc)
- new.userspace_addr = mem->userspace_addr;
- else
- new.userspace_addr = 0;
+ new.userspace_addr = mem->userspace_addr;
}
if (!npages)
goto skip_lpage;
@@ -636,14 +652,15 @@ skip_lpage:
/* Allocate page dirty bitmap if needed */
if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
- unsigned dirty_bytes = ALIGN(npages, BITS_PER_LONG) / 8;
+ unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new);
new.dirty_bitmap = vmalloc(dirty_bytes);
if (!new.dirty_bitmap)
goto out_free;
memset(new.dirty_bitmap, 0, dirty_bytes);
+ /* destroy any largepage mappings for dirty tracking */
if (old.npages)
- kvm_arch_flush_shadow(kvm);
+ flush_shadow = 1;
}
#else /* not defined CONFIG_S390 */
new.user_alloc = user_alloc;
@@ -651,36 +668,72 @@ skip_lpage:
new.userspace_addr = mem->userspace_addr;
#endif /* not defined CONFIG_S390 */
- if (!npages)
+ if (!npages) {
+ r = -ENOMEM;
+ slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
+ if (!slots)
+ goto out_free;
+ memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
+ if (mem->slot >= slots->nmemslots)
+ slots->nmemslots = mem->slot + 1;
+ slots->memslots[mem->slot].flags |= KVM_MEMSLOT_INVALID;
+
+ old_memslots = kvm->memslots;
+ rcu_assign_pointer(kvm->memslots, slots);
+ synchronize_srcu_expedited(&kvm->srcu);
+ /* From this point no new shadow pages pointing to a deleted
+ * memslot will be created.
+ *
+ * validation of sp->gfn happens in:
+ * - gfn_to_hva (kvm_read_guest, gfn_to_pfn)
+ * - kvm_is_visible_gfn (mmu_check_roots)
+ */
kvm_arch_flush_shadow(kvm);
+ kfree(old_memslots);
+ }
- spin_lock(&kvm->mmu_lock);
- if (mem->slot >= kvm->nmemslots)
- kvm->nmemslots = mem->slot + 1;
-
- *memslot = new;
- spin_unlock(&kvm->mmu_lock);
-
- r = kvm_arch_set_memory_region(kvm, mem, old, user_alloc);
- if (r) {
- spin_lock(&kvm->mmu_lock);
- *memslot = old;
- spin_unlock(&kvm->mmu_lock);
+ r = kvm_arch_prepare_memory_region(kvm, &new, old, mem, user_alloc);
+ if (r)
goto out_free;
- }
- kvm_free_physmem_slot(&old, npages ? &new : NULL);
- /* Slot deletion case: we have to update the current slot */
- spin_lock(&kvm->mmu_lock);
- if (!npages)
- *memslot = old;
- spin_unlock(&kvm->mmu_lock);
#ifdef CONFIG_DMAR
/* map the pages in iommu page table */
- r = kvm_iommu_map_pages(kvm, base_gfn, npages);
- if (r)
- goto out;
+ if (npages) {
+ r = kvm_iommu_map_pages(kvm, &new);
+ if (r)
+ goto out_free;
+ }
#endif
+
+ r = -ENOMEM;
+ slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
+ if (!slots)
+ goto out_free;
+ memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
+ if (mem->slot >= slots->nmemslots)
+ slots->nmemslots = mem->slot + 1;
+
+ /* actual memory is freed via old in kvm_free_physmem_slot below */
+ if (!npages) {
+ new.rmap = NULL;
+ new.dirty_bitmap = NULL;
+ for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i)
+ new.lpage_info[i] = NULL;
+ }
+
+ slots->memslots[mem->slot] = new;
+ old_memslots = kvm->memslots;
+ rcu_assign_pointer(kvm->memslots, slots);
+ synchronize_srcu_expedited(&kvm->srcu);
+
+ kvm_arch_commit_memory_region(kvm, mem, old, user_alloc);
+
+ kvm_free_physmem_slot(&old, &new);
+ kfree(old_memslots);
+
+ if (flush_shadow)
+ kvm_arch_flush_shadow(kvm);
+
return 0;
out_free:
@@ -697,9 +750,9 @@ int kvm_set_memory_region(struct kvm *kvm,
{
int r;
- down_write(&kvm->slots_lock);
+ mutex_lock(&kvm->slots_lock);
r = __kvm_set_memory_region(kvm, mem, user_alloc);
- up_write(&kvm->slots_lock);
+ mutex_unlock(&kvm->slots_lock);
return r;
}
EXPORT_SYMBOL_GPL(kvm_set_memory_region);
@@ -719,19 +772,19 @@ int kvm_get_dirty_log(struct kvm *kvm,
{
struct kvm_memory_slot *memslot;
int r, i;
- int n;
+ unsigned long n;
unsigned long any = 0;
r = -EINVAL;
if (log->slot >= KVM_MEMORY_SLOTS)
goto out;
- memslot = &kvm->memslots[log->slot];
+ memslot = &kvm->memslots->memslots[log->slot];
r = -ENOENT;
if (!memslot->dirty_bitmap)
goto out;
- n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+ n = kvm_dirty_bitmap_bytes(memslot);
for (i = 0; !any && i < n/sizeof(long); ++i)
any = memslot->dirty_bitmap[i];
@@ -780,9 +833,10 @@ EXPORT_SYMBOL_GPL(kvm_is_error_hva);
struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn)
{
int i;
+ struct kvm_memslots *slots = rcu_dereference(kvm->memslots);
- for (i = 0; i < kvm->nmemslots; ++i) {
- struct kvm_memory_slot *memslot = &kvm->memslots[i];
+ for (i = 0; i < slots->nmemslots; ++i) {
+ struct kvm_memory_slot *memslot = &slots->memslots[i];
if (gfn >= memslot->base_gfn
&& gfn < memslot->base_gfn + memslot->npages)
@@ -801,10 +855,14 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
{
int i;
+ struct kvm_memslots *slots = rcu_dereference(kvm->memslots);
- gfn = unalias_gfn(kvm, gfn);
+ gfn = unalias_gfn_instantiation(kvm, gfn);
for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
- struct kvm_memory_slot *memslot = &kvm->memslots[i];
+ struct kvm_memory_slot *memslot = &slots->memslots[i];
+
+ if (memslot->flags & KVM_MEMSLOT_INVALID)
+ continue;
if (gfn >= memslot->base_gfn
&& gfn < memslot->base_gfn + memslot->npages)
@@ -814,33 +872,68 @@ int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
}
EXPORT_SYMBOL_GPL(kvm_is_visible_gfn);
+unsigned long kvm_host_page_size(struct kvm *kvm, gfn_t gfn)
+{
+ struct vm_area_struct *vma;
+ unsigned long addr, size;
+
+ size = PAGE_SIZE;
+
+ addr = gfn_to_hva(kvm, gfn);
+ if (kvm_is_error_hva(addr))
+ return PAGE_SIZE;
+
+ down_read(&current->mm->mmap_sem);
+ vma = find_vma(current->mm, addr);
+ if (!vma)
+ goto out;
+
+ size = vma_kernel_pagesize(vma);
+
+out:
+ up_read(&current->mm->mmap_sem);
+
+ return size;
+}
+
+int memslot_id(struct kvm *kvm, gfn_t gfn)
+{
+ int i;
+ struct kvm_memslots *slots = rcu_dereference(kvm->memslots);
+ struct kvm_memory_slot *memslot = NULL;
+
+ gfn = unalias_gfn(kvm, gfn);
+ for (i = 0; i < slots->nmemslots; ++i) {
+ memslot = &slots->memslots[i];
+
+ if (gfn >= memslot->base_gfn
+ && gfn < memslot->base_gfn + memslot->npages)
+ break;
+ }
+
+ return memslot - slots->memslots;
+}
+
unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
{
struct kvm_memory_slot *slot;
- gfn = unalias_gfn(kvm, gfn);
+ gfn = unalias_gfn_instantiation(kvm, gfn);
slot = gfn_to_memslot_unaliased(kvm, gfn);
- if (!slot)
+ if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
return bad_hva();
return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE);
}
EXPORT_SYMBOL_GPL(gfn_to_hva);
-pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
+static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr)
{
struct page *page[1];
- unsigned long addr;
int npages;
pfn_t pfn;
might_sleep();
- addr = gfn_to_hva(kvm, gfn);
- if (kvm_is_error_hva(addr)) {
- get_page(bad_page);
- return page_to_pfn(bad_page);
- }
-
npages = get_user_pages_fast(addr, 1, 1, page);
if (unlikely(npages != 1)) {
@@ -865,8 +958,32 @@ pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
return pfn;
}
+pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
+{
+ unsigned long addr;
+
+ addr = gfn_to_hva(kvm, gfn);
+ if (kvm_is_error_hva(addr)) {
+ get_page(bad_page);
+ return page_to_pfn(bad_page);
+ }
+
+ return hva_to_pfn(kvm, addr);
+}
EXPORT_SYMBOL_GPL(gfn_to_pfn);
+static unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
+{
+ return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE);
+}
+
+pfn_t gfn_to_pfn_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot, gfn_t gfn)
+{
+ unsigned long addr = gfn_to_hva_memslot(slot, gfn);
+ return hva_to_pfn(kvm, addr);
+}
+
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
{
pfn_t pfn;
@@ -1073,10 +1190,13 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
memslot = gfn_to_memslot_unaliased(kvm, gfn);
if (memslot && memslot->dirty_bitmap) {
unsigned long rel_gfn = gfn - memslot->base_gfn;
+ unsigned long *p = memslot->dirty_bitmap +
+ rel_gfn / BITS_PER_LONG;
+ int offset = rel_gfn % BITS_PER_LONG;
/* avoid RMW */
- if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap))
- generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
+ if (!generic_test_le_bit(offset, p))
+ generic___set_le_bit(offset, p);
}
}
@@ -1854,12 +1974,7 @@ static struct notifier_block kvm_reboot_notifier = {
.priority = 0,
};
-void kvm_io_bus_init(struct kvm_io_bus *bus)
-{
- memset(bus, 0, sizeof(*bus));
-}
-
-void kvm_io_bus_destroy(struct kvm_io_bus *bus)
+static void kvm_io_bus_destroy(struct kvm_io_bus *bus)
{
int i;
@@ -1868,13 +1983,15 @@ void kvm_io_bus_destroy(struct kvm_io_bus *bus)
kvm_iodevice_destructor(pos);
}
+ kfree(bus);
}
/* kvm_io_bus_write - called under kvm->slots_lock */
-int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr,
+int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
int len, const void *val)
{
int i;
+ struct kvm_io_bus *bus = rcu_dereference(kvm->buses[bus_idx]);
for (i = 0; i < bus->dev_count; i++)
if (!kvm_iodevice_write(bus->devs[i], addr, len, val))
return 0;
@@ -1882,59 +1999,71 @@ int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr,
}
/* kvm_io_bus_read - called under kvm->slots_lock */
-int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len, void *val)
+int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
+ int len, void *val)
{
int i;
+ struct kvm_io_bus *bus = rcu_dereference(kvm->buses[bus_idx]);
+
for (i = 0; i < bus->dev_count; i++)
if (!kvm_iodevice_read(bus->devs[i], addr, len, val))
return 0;
return -EOPNOTSUPP;
}
-int kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus,
- struct kvm_io_device *dev)
+/* Caller must hold slots_lock. */
+int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+ struct kvm_io_device *dev)
{
- int ret;
-
- down_write(&kvm->slots_lock);
- ret = __kvm_io_bus_register_dev(bus, dev);
- up_write(&kvm->slots_lock);
+ struct kvm_io_bus *new_bus, *bus;
- return ret;
-}
-
-/* An unlocked version. Caller must have write lock on slots_lock. */
-int __kvm_io_bus_register_dev(struct kvm_io_bus *bus,
- struct kvm_io_device *dev)
-{
+ bus = kvm->buses[bus_idx];
if (bus->dev_count > NR_IOBUS_DEVS-1)
return -ENOSPC;
- bus->devs[bus->dev_count++] = dev;
+ new_bus = kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL);
+ if (!new_bus)
+ return -ENOMEM;
+ memcpy(new_bus, bus, sizeof(struct kvm_io_bus));
+ new_bus->devs[new_bus->dev_count++] = dev;
+ rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
+ synchronize_srcu_expedited(&kvm->srcu);
+ kfree(bus);
return 0;
}
-void kvm_io_bus_unregister_dev(struct kvm *kvm,
- struct kvm_io_bus *bus,
- struct kvm_io_device *dev)
+/* Caller must hold slots_lock. */
+int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+ struct kvm_io_device *dev)
{
- down_write(&kvm->slots_lock);
- __kvm_io_bus_unregister_dev(bus, dev);
- up_write(&kvm->slots_lock);
-}
+ int i, r;
+ struct kvm_io_bus *new_bus, *bus;
-/* An unlocked version. Caller must have write lock on slots_lock. */
-void __kvm_io_bus_unregister_dev(struct kvm_io_bus *bus,
- struct kvm_io_device *dev)
-{
- int i;
+ new_bus = kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL);
+ if (!new_bus)
+ return -ENOMEM;
- for (i = 0; i < bus->dev_count; i++)
- if (bus->devs[i] == dev) {
- bus->devs[i] = bus->devs[--bus->dev_count];
+ bus = kvm->buses[bus_idx];
+ memcpy(new_bus, bus, sizeof(struct kvm_io_bus));
+
+ r = -ENOENT;
+ for (i = 0; i < new_bus->dev_count; i++)
+ if (new_bus->devs[i] == dev) {
+ r = 0;
+ new_bus->devs[i] = new_bus->devs[--new_bus->dev_count];
break;
}
+
+ if (r) {
+ kfree(new_bus);
+ return r;
+ }
+
+ rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
+ synchronize_srcu_expedited(&kvm->srcu);
+ kfree(bus);
+ return r;
}
static struct notifier_block kvm_cpu_notifier = {